--- linux-oracle-5.4.0.orig/Documentation/ABI/stable/sysfs-driver-mlxreg-io +++ linux-oracle-5.4.0/Documentation/ABI/stable/sysfs-driver-mlxreg-io @@ -29,13 +29,13 @@ The files are read only. -What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/jtag_enable +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld3_version Date: November 2018 KernelVersion: 5.0 Contact: Vadim Pasternak Description: These files show with which CPLD versions have been burned - on LED board. + on LED or Gearbox board. The files are read only. @@ -121,6 +121,15 @@ The files are read only. +What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/cpld4_version +Date: November 2018 +KernelVersion: 5.0 +Contact: Vadim Pasternak +Description: These files show with which CPLD versions have been burned + on LED board. + + The files are read only. + Date: June 2019 KernelVersion: 5.3 Contact: Vadim Pasternak --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/debugfs-aufs +++ linux-oracle-5.4.0/Documentation/ABI/testing/debugfs-aufs @@ -0,0 +1,55 @@ +What: /debug/aufs/si_/ +Date: March 2009 +Contact: J. R. Okajima +Description: + Under /debug/aufs, a directory named si_ is created + per aufs mount, where is a unique id generated + internally. + +What: /debug/aufs/si_/plink +Date: Apr 2013 +Contact: J. R. Okajima +Description: + It has three lines and shows the information about the + pseudo-link. The first line is a single number + representing a number of buckets. The second line is a + number of pseudo-links per buckets (separated by a + blank). The last line is a single number representing a + total number of psedo-links. + When the aufs mount option 'noplink' is specified, it + will show "1\n0\n0\n". + +What: /debug/aufs/si_/xib +Date: March 2009 +Contact: J. R. Okajima +Description: + It shows the consumed blocks by xib (External Inode Number + Bitmap), its block size and file size. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. + +What: /debug/aufs/si_/xi0, xi1 ... xiN and xiN-N +Date: March 2009 +Contact: J. R. Okajima +Description: + It shows the consumed blocks by xino (External Inode Number + Translation Table), its link count, block size and file + size. + Due to the file size limit, there may exist multiple + xino files per branch. In this case, "-N" is added to + the filename and it corresponds to the index of the + internal xino array. "-0" is omitted. + When the aufs mount option 'noxino' is specified, Those + entries won't exist. About XINO files, see the aufs + manual. + +What: /debug/aufs/si_/xigen +Date: March 2009 +Contact: J. R. Okajima +Description: + It shows the consumed blocks by xigen (External Inode + Generation Table), its block size and file size. + If CONFIG_AUFS_EXPORT is disabled, this entry will not + be created. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/debugfs-hisi-hpre +++ linux-oracle-5.4.0/Documentation/ABI/testing/debugfs-hisi-hpre @@ -0,0 +1,57 @@ +What: /sys/kernel/debug/hisi_hpre//cluster[0-3]/regs +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: Dump debug registers from the HPRE cluster. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//cluster[0-3]/cluster_ctrl +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: Write the HPRE core selection in the cluster into this file, + and then we can read the debug information of the core. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//rdclr_en +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: HPRE cores debug registers read clear control. 1 means enable + register read clear, otherwise 0. Writing to this file has no + functional effect, only enable or disable counters clear after + reading of these registers. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//current_qm +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: One HPRE controller has one PF and multiple VFs, each function + has a QM. Select the QM which below qm refers to. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//regs +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: Dump debug registers from the HPRE. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//qm/qm_regs +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: Dump debug registers from the QM. + Available for PF and VF in host. VF in guest currently only + has one debug register. + +What: /sys/kernel/debug/hisi_hpre//qm/current_q +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: One QM may contain multiple queues. Select specific queue to + show its debug registers in above qm_regs. + Only available for PF. + +What: /sys/kernel/debug/hisi_hpre//qm/clear_enable +Date: Sep 2019 +Contact: linux-crypto@vger.kernel.org +Description: QM debug registers(qm_regs) read clear control. 1 means enable + register read clear, otherwise 0. + Writing to this file has no functional effect, only enable or + disable counters clear after reading of these registers. + Only available for PF. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/debugfs-hisi-sec +++ linux-oracle-5.4.0/Documentation/ABI/testing/debugfs-hisi-sec @@ -0,0 +1,43 @@ +What: /sys/kernel/debug/hisi_sec//sec_dfx +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: Dump the debug registers of SEC cores. + Only available for PF. + +What: /sys/kernel/debug/hisi_sec//clear_enable +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: Enabling/disabling of clear action after reading + the SEC debug registers. + 0: disable, 1: enable. + Only available for PF, and take no other effect on SEC. + +What: /sys/kernel/debug/hisi_sec//current_qm +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: One SEC controller has one PF and multiple VFs, each function + has a QM. This file can be used to select the QM which below + qm refers to. + Only available for PF. + +What: /sys/kernel/debug/hisi_sec//qm/qm_regs +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: Dump of QM related debug registers. + Available for PF and VF in host. VF in guest currently only + has one debug register. + +What: /sys/kernel/debug/hisi_sec//qm/current_q +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: One QM of SEC may contain multiple queues. Select specific + queue to show its debug registers in above 'qm_regs'. + Only available for PF. + +What: /sys/kernel/debug/hisi_sec//qm/clear_enable +Date: Oct 2019 +Contact: linux-crypto@vger.kernel.org +Description: Enabling/disabling of clear action after reading + the SEC's QM debug registers. + 0: disable, 1: enable. + Only available for PF, and take no other effect on SEC. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/evm +++ linux-oracle-5.4.0/Documentation/ABI/testing/evm @@ -42,8 +42,30 @@ modification of EVM-protected metadata and disable all further modification of policy - Note that once a key has been loaded, it will no longer be - possible to enable metadata modification. + Echoing a value is additive, the new value is added to the + existing initialization flags. + + For example, after:: + + echo 2 >/evm + + another echo can be performed:: + + echo 1 >/evm + + and the resulting value will be 3. + + Note that once an HMAC key has been loaded, it will no longer + be possible to enable metadata modification. Signaling that an + HMAC key has been loaded will clear the corresponding flag. + For example, if the current value is 6 (2 and 4 set):: + + echo 1 >/evm + + will set the new value to 3 (4 cleared). + + Loading an HMAC key is the only way to disable metadata + modification. Until key loading has been signaled EVM can not create or validate the 'security.evm' xattr, but returns --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/ima_policy +++ linux-oracle-5.4.0/Documentation/ABI/testing/ima_policy @@ -25,6 +25,7 @@ lsm: [[subj_user=] [subj_role=] [subj_type=] [obj_user=] [obj_role=] [obj_type=]] option: [[appraise_type=]] [template=] [permit_directio] + [appraise_flag=] base: func:= [BPRM_CHECK][MMAP_CHECK][CREDS_CHECK][FILE_CHECK][MODULE_CHECK] [FIRMWARE_CHECK] [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] @@ -38,6 +39,9 @@ fowner:= decimal value lsm: are LSM specific option: appraise_type:= [imasig] [imasig|modsig] + appraise_flag:= [check_blacklist] + Currently, blacklist check is only for files signed with appended + signature. template:= name of a defined IMA template type (eg, ima-ng). Only valid when action is "measure". pcr:= decimal value --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-ata +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-ata @@ -107,13 +107,14 @@ described in ATA8 7.16 and 7.17. Only valid if the device is not a PM. - pio_mode: (RO) Transfer modes supported by the device when - in PIO mode. Mostly used by PATA device. + pio_mode: (RO) PIO transfer mode used by the device. + Mostly used by PATA devices. - xfer_mode: (RO) Current transfer mode + xfer_mode: (RO) Current transfer mode. Mostly used by + PATA devices. - dma_mode: (RO) Transfer modes supported by the device when - in DMA mode. Mostly used by PATA device. + dma_mode: (RO) DMA transfer mode used by the device. + Mostly used by PATA devices. class: (RO) Device class. Can be "ata" for disk, "atapi" for packet device, "pmp" for PM, or --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-aufs +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-aufs @@ -0,0 +1,31 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 +Contact: J. R. Okajima +Description: + Under /sys/fs/aufs, a directory named si_ is created + per aufs mount, where is a unique id generated + internally. + +What: /sys/fs/aufs/si_/br0, br1 ... brN +Date: March 2009 +Contact: J. R. Okajima +Description: + It shows the abolute path of a member directory (which + is called branch) in aufs, and its permission. + +What: /sys/fs/aufs/si_/brid0, brid1 ... bridN +Date: July 2013 +Contact: J. R. Okajima +Description: + It shows the id of a member directory (which is called + branch) in aufs. + +What: /sys/fs/aufs/si_/xi_path +Date: March 2009 +Contact: J. R. Okajima +Description: + It shows the abolute path of XINO (External Inode Number + Bitmap, Translation Table and Generation Table) file + even if it is the default path. + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-bus-iio +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-bus-iio @@ -138,7 +138,7 @@ Raw capacitance measurement from channel Y. Units after application of scale and offset are nanofarads. -What: /sys/.../iio:deviceX/in_capacitanceY-in_capacitanceZ_raw +What: /sys/.../iio:deviceX/in_capacitanceY-capacitanceZ_raw KernelVersion: 3.2 Contact: linux-iio@vger.kernel.org Description: @@ -1566,7 +1566,8 @@ KernelVersion: 4.3 Contact: linux-iio@vger.kernel.org Description: - Raw (unscaled no offset etc.) percentage reading of a substance. + Raw (unscaled no offset etc.) reading of a substance. Units + after application of scale and offset are percents. What: /sys/bus/iio/devices/iio:deviceX/in_resistance_raw What: /sys/bus/iio/devices/iio:deviceX/in_resistanceX_raw --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-bus-iio-vf610 +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-bus-iio-vf610 @@ -1,4 +1,4 @@ -What: /sys/bus/iio/devices/iio:deviceX/conversion_mode +What: /sys/bus/iio/devices/iio:deviceX/in_conversion_mode KernelVersion: 4.2 Contact: linux-iio@vger.kernel.org Description: --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-bus-mei +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-bus-mei @@ -4,7 +4,7 @@ Contact: Samuel Ortiz linux-mei@linux.intel.com Description: Stores the same MODALIAS value emitted by uevent - Format: mei::: + Format: mei::: What: /sys/bus/mei/devices/.../name Date: May 2015 --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-bus-pci +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-bus-pci @@ -125,6 +125,17 @@ will be present in sysfs. Writing 1 to this file will perform reset. +What: /sys/bus/pci/devices/.../reset_subordinate +Date: October 2024 +Contact: linux-pci@vger.kernel.org +Description: + This is visible only for bridge devices. If you want to reset + all devices attached through the subordinate bus of a specific + bridge device, writing 1 to this will try to do it. This will + affect all devices attached to the system through this bridge + similiar to writing 1 to their individual "reset" file, so use + with caution. + What: /sys/bus/pci/devices/.../vpd Date: February 2008 Contact: Ben Hutchings @@ -347,3 +358,16 @@ If the device has any Peer-to-Peer memory registered, this file contains a '1' if the memory has been published for use outside the driver that owns the device. + +What: /sys/bus/pci/devices/.../link/clkpm + /sys/bus/pci/devices/.../link/l0s_aspm + /sys/bus/pci/devices/.../link/l1_aspm + /sys/bus/pci/devices/.../link/l1_1_aspm + /sys/bus/pci/devices/.../link/l1_2_aspm + /sys/bus/pci/devices/.../link/l1_1_pcipm + /sys/bus/pci/devices/.../link/l1_2_pcipm +Date: October 2019 +Contact: Heiner Kallweit +Description: If ASPM is supported for an endpoint, these files can be + used to disable or enable the individual power management + states. Write y/1/on to enable, n/0/off to disable. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-class-devfreq +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-class-devfreq @@ -7,6 +7,13 @@ The name of devfreq object denoted as ... is same as the name of device using devfreq. +What: /sys/class/devfreq/.../name +Date: November 2019 +Contact: Chanwoo Choi +Description: + The /sys/class/devfreq/.../name shows the name of device + of the corresponding devfreq object. + What: /sys/class/devfreq/.../governor Date: September 2011 Contact: MyungJoo Ham @@ -54,6 +61,8 @@ In order to activate this ABI, the devfreq target device driver should provide the list of available frequencies with its profile. + If the transition table is bigger than PAGE_SIZE, reading + this will return an -EFBIG error. What: /sys/class/devfreq/.../userspace/set_freq Date: September 2011 --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-class-net-queues +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-class-net-queues @@ -1,4 +1,4 @@ -What: /sys/class//queues/rx-/rps_cpus +What: /sys/class/net//queues/rx-/rps_cpus Date: March 2010 KernelVersion: 2.6.35 Contact: netdev@vger.kernel.org @@ -8,7 +8,7 @@ network device queue. Possible values depend on the number of available CPU(s) in the system. -What: /sys/class//queues/rx-/rps_flow_cnt +What: /sys/class/net//queues/rx-/rps_flow_cnt Date: April 2010 KernelVersion: 2.6.35 Contact: netdev@vger.kernel.org @@ -16,7 +16,7 @@ Number of Receive Packet Steering flows being currently processed by this particular network device receive queue. -What: /sys/class//queues/tx-/tx_timeout +What: /sys/class/net//queues/tx-/tx_timeout Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -24,7 +24,7 @@ Indicates the number of transmit timeout events seen by this network interface transmit queue. -What: /sys/class//queues/tx-/tx_maxrate +What: /sys/class/net//queues/tx-/tx_maxrate Date: March 2015 KernelVersion: 4.1 Contact: netdev@vger.kernel.org @@ -32,7 +32,7 @@ A Mbps max-rate set for the queue, a value of zero means disabled, default is disabled. -What: /sys/class//queues/tx-/xps_cpus +What: /sys/class/net//queues/tx-/xps_cpus Date: November 2010 KernelVersion: 2.6.38 Contact: netdev@vger.kernel.org @@ -42,7 +42,7 @@ network device transmit queue. Possible vaules depend on the number of available CPU(s) in the system. -What: /sys/class//queues/tx-/xps_rxqs +What: /sys/class/net//queues/tx-/xps_rxqs Date: June 2018 KernelVersion: 4.18.0 Contact: netdev@vger.kernel.org @@ -53,7 +53,7 @@ number of available receive queue(s) in the network device. Default is disabled. -What: /sys/class//queues/tx-/byte_queue_limits/hold_time +What: /sys/class/net//queues/tx-/byte_queue_limits/hold_time Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -62,7 +62,7 @@ of this particular network device transmit queue. Default value is 1000. -What: /sys/class//queues/tx-/byte_queue_limits/inflight +What: /sys/class/net//queues/tx-/byte_queue_limits/inflight Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -70,7 +70,7 @@ Indicates the number of bytes (objects) in flight on this network device transmit queue. -What: /sys/class//queues/tx-/byte_queue_limits/limit +What: /sys/class/net//queues/tx-/byte_queue_limits/limit Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -79,7 +79,7 @@ on this network device transmit queue. This value is clamped to be within the bounds defined by limit_max and limit_min. -What: /sys/class//queues/tx-/byte_queue_limits/limit_max +What: /sys/class/net//queues/tx-/byte_queue_limits/limit_max Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -88,7 +88,7 @@ queued on this network device transmit queue. See include/linux/dynamic_queue_limits.h for the default value. -What: /sys/class//queues/tx-/byte_queue_limits/limit_min +What: /sys/class/net//queues/tx-/byte_queue_limits/limit_min Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-devices-system-cpu +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -480,14 +480,17 @@ cpu_capacity: capacity of cpu#. What: /sys/devices/system/cpu/vulnerabilities + /sys/devices/system/cpu/vulnerabilities/gather_data_sampling + /sys/devices/system/cpu/vulnerabilities/itlb_multihit + /sys/devices/system/cpu/vulnerabilities/l1tf + /sys/devices/system/cpu/vulnerabilities/mds /sys/devices/system/cpu/vulnerabilities/meltdown + /sys/devices/system/cpu/vulnerabilities/mmio_stale_data + /sys/devices/system/cpu/vulnerabilities/spec_store_bypass /sys/devices/system/cpu/vulnerabilities/spectre_v1 /sys/devices/system/cpu/vulnerabilities/spectre_v2 - /sys/devices/system/cpu/vulnerabilities/spec_store_bypass - /sys/devices/system/cpu/vulnerabilities/l1tf - /sys/devices/system/cpu/vulnerabilities/mds + /sys/devices/system/cpu/vulnerabilities/srbds /sys/devices/system/cpu/vulnerabilities/tsx_async_abort - /sys/devices/system/cpu/vulnerabilities/itlb_multihit Date: January 2018 Contact: Linux kernel mailing list Description: Information about CPU vulnerabilities --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-kernel-oops_count +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-kernel-oops_count @@ -0,0 +1,6 @@ +What: /sys/kernel/oops_count +Date: November 2022 +KernelVersion: 6.2.0 +Contact: Linux Kernel Hardening List +Description: + Shows how many times the system has Oopsed since last boot. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-kernel-warn_count +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-kernel-warn_count @@ -0,0 +1,6 @@ +What: /sys/kernel/warn_count +Date: November 2022 +KernelVersion: 6.2.0 +Contact: Linux Kernel Hardening List +Description: + Shows how many times the system has Warned since last boot. --- linux-oracle-5.4.0.orig/Documentation/ABI/testing/sysfs-secvar +++ linux-oracle-5.4.0/Documentation/ABI/testing/sysfs-secvar @@ -0,0 +1,46 @@ +What: /sys/firmware/secvar +Date: August 2019 +Contact: Nayna Jain +Description: This directory is created if the POWER firmware supports OS + secureboot, thereby secure variables. It exposes interface + for reading/writing the secure variables + +What: /sys/firmware/secvar/vars +Date: August 2019 +Contact: Nayna Jain +Description: This directory lists all the secure variables that are supported + by the firmware. + +What: /sys/firmware/secvar/format +Date: August 2019 +Contact: Nayna Jain +Description: A string indicating which backend is in use by the firmware. + This determines the format of the variable and the accepted + format of variable updates. + +What: /sys/firmware/secvar/vars/ +Date: August 2019 +Contact: Nayna Jain +Description: Each secure variable is represented as a directory named as + . The variable name is unique and is in ASCII + representation. The data and size can be determined by reading + their respective attribute files. + +What: /sys/firmware/secvar/vars//size +Date: August 2019 +Contact: Nayna Jain +Description: An integer representation of the size of the content of the + variable. In other words, it represents the size of the data. + +What: /sys/firmware/secvar/vars//data +Date: August 2019 +Contact: Nayna Jain h +Description: A read-only file containing the value of the variable. The size + of the file represents the maximum size of the variable data. + +What: /sys/firmware/secvar/vars//update +Date: August 2019 +Contact: Nayna Jain +Description: A write-only file that is used to submit the new value for the + variable. The size of the file represents the maximum size of + the variable data that can be written. --- linux-oracle-5.4.0.orig/Documentation/DMA-attributes.txt +++ linux-oracle-5.4.0/Documentation/DMA-attributes.txt @@ -5,24 +5,6 @@ This document describes the semantics of the DMA attributes that are defined in linux/dma-mapping.h. -DMA_ATTR_WRITE_BARRIER ----------------------- - -DMA_ATTR_WRITE_BARRIER is a (write) barrier attribute for DMA. DMA -to a memory region with the DMA_ATTR_WRITE_BARRIER attribute forces -all pending DMA writes to complete, and thus provides a mechanism to -strictly order DMA from a device across all intervening busses and -bridges. This barrier is not specific to a particular type of -interconnect, it applies to the system as a whole, and so its -implementation must account for the idiosyncrasies of the system all -the way from the DMA device to memory. - -As an example of a situation where DMA_ATTR_WRITE_BARRIER would be -useful, suppose that a device does a DMA write to indicate that data is -ready and available in memory. The DMA of the "completion indication" -could race with data DMA. Mapping the memory used for completion -indications with DMA_ATTR_WRITE_BARRIER would prevent the race. - DMA_ATTR_WEAK_ORDERING ---------------------- --- linux-oracle-5.4.0.orig/Documentation/IPMI.txt +++ linux-oracle-5.4.0/Documentation/IPMI.txt @@ -518,7 +518,7 @@ [dbg_probe=1] The addresses are normal I2C addresses. The adapter is the string -name of the adapter, as shown in /sys/class/i2c-adapter/i2c-/name. +name of the adapter, as shown in /sys/bus/i2c/devices/i2c-/name. It is *NOT* i2c- itself. Also, the comparison is done ignoring spaces, so if the name is "This is an I2C chip" you can say adapter_name=ThisisanI2cchip. This is because it's hard to pass in --- linux-oracle-5.4.0.orig/Documentation/RCU/Design/Requirements/Requirements.html +++ linux-oracle-5.4.0/Documentation/RCU/Design/Requirements/Requirements.html @@ -2342,7 +2342,7 @@ The module-unload functions must therefore cancel any delayed calls to loadable-module functions, for example, any outstanding mod_timer() must be dealt with -via del_timer_sync() or similar. +via timer_shutdown_sync() or similar.

Unfortunately, there is no way to cancel an RCU callback; --- linux-oracle-5.4.0.orig/Documentation/accounting/psi.rst +++ linux-oracle-5.4.0/Documentation/accounting/psi.rst @@ -90,7 +90,8 @@ for the same psi metric can be specified. However for each trigger a separate file descriptor is required to be able to poll it separately from others, therefore for each trigger a separate open() syscall should be made even -when opening the same psi interface file. +when opening the same psi interface file. Write operations to a file descriptor +with an already existing psi trigger will fail with EBUSY. Monitors activate only when system enters stall state for the monitored psi metric and deactivates upon exit from the stall state. While system is --- linux-oracle-5.4.0.orig/Documentation/admin-guide/cgroup-v1/memory.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/cgroup-v1/memory.rst @@ -82,6 +82,8 @@ memory.swappiness set/show swappiness parameter of vmscan (See sysctl's vm.swappiness) memory.move_charge_at_immigrate set/show controls of moving charges + This knob is deprecated and shouldn't be + used. memory.oom_control set/show oom controls. memory.numa_stat show the number of memory usage per numa node @@ -745,8 +747,15 @@ It is recommended to set the soft limit always below the hard limit, otherwise the hard limit will take precedence. -8. Move charges at task migration -================================= +8. Move charges at task migration (DEPRECATED!) +=============================================== + +THIS IS DEPRECATED! + +It's expensive and unreliable! It's better practice to launch workload +tasks directly from inside their target cgroup. Use dedicated workload +cgroups to allow fine-grained policy adjustments without having to +move physical pages between control domains. Users can move charges associated with a task along with task migration, that is, uncharge task's pages from the old cgroup and charge them to the new cgroup. --- linux-oracle-5.4.0.orig/Documentation/admin-guide/device-mapper/dm-integrity.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/device-mapper/dm-integrity.rst @@ -177,6 +177,12 @@ The bitmap flush interval in milliseconds. The metadata buffers are synchronized when this interval expires. +legacy_recalculate + Allow recalculating of volumes with HMAC keys. This is disabled by + default for security reasons - an attacker could modify the volume, + set recalc_sector to zero, and the kernel would not detect the + modification. + The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can be changed when reloading the target (load an inactive table and swap the --- linux-oracle-5.4.0.orig/Documentation/admin-guide/device-mapper/index.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/device-mapper/index.rst @@ -8,6 +8,7 @@ cache-policies cache delay + dm-clone dm-crypt dm-flakey dm-init --- linux-oracle-5.4.0.orig/Documentation/admin-guide/devices.txt +++ linux-oracle-5.4.0/Documentation/admin-guide/devices.txt @@ -3002,10 +3002,10 @@ 65 = /dev/infiniband/issm1 Second InfiniBand IsSM device ... 127 = /dev/infiniband/issm63 63rd InfiniBand IsSM device - 128 = /dev/infiniband/uverbs0 First InfiniBand verbs device - 129 = /dev/infiniband/uverbs1 Second InfiniBand verbs device + 192 = /dev/infiniband/uverbs0 First InfiniBand verbs device + 193 = /dev/infiniband/uverbs1 Second InfiniBand verbs device ... - 159 = /dev/infiniband/uverbs31 31st InfiniBand verbs device + 223 = /dev/infiniband/uverbs31 31st InfiniBand verbs device 232 char Biometric Devices 0 = /dev/biometric/sensor0/fingerprint first fingerprint sensor on first device --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/cross-thread-rsb.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/cross-thread-rsb.rst @@ -0,0 +1,92 @@ + +.. SPDX-License-Identifier: GPL-2.0 + +Cross-Thread Return Address Predictions +======================================= + +Certain AMD and Hygon processors are subject to a cross-thread return address +predictions vulnerability. When running in SMT mode and one sibling thread +transitions out of C0 state, the other sibling thread could use return target +predictions from the sibling thread that transitioned out of C0. + +The Spectre v2 mitigations protect the Linux kernel, as it fills the return +address prediction entries with safe targets when context switching to the idle +thread. However, KVM does allow a VMM to prevent exiting guest mode when +transitioning out of C0. This could result in a guest-controlled return target +being consumed by the sibling thread. + +Affected processors +------------------- + +The following CPUs are vulnerable: + + - AMD Family 17h processors + - Hygon Family 18h processors + +Related CVEs +------------ + +The following CVE entry is related to this issue: + + ============== ======================================= + CVE-2022-27672 Cross-Thread Return Address Predictions + ============== ======================================= + +Problem +------- + +Affected SMT-capable processors support 1T and 2T modes of execution when SMT +is enabled. In 2T mode, both threads in a core are executing code. For the +processor core to enter 1T mode, it is required that one of the threads +requests to transition out of the C0 state. This can be communicated with the +HLT instruction or with an MWAIT instruction that requests non-C0. +When the thread re-enters the C0 state, the processor transitions back +to 2T mode, assuming the other thread is also still in C0 state. + +In affected processors, the return address predictor (RAP) is partitioned +depending on the SMT mode. For instance, in 2T mode each thread uses a private +16-entry RAP, but in 1T mode, the active thread uses a 32-entry RAP. Upon +transition between 1T/2T mode, the RAP contents are not modified but the RAP +pointers (which control the next return target to use for predictions) may +change. This behavior may result in return targets from one SMT thread being +used by RET predictions in the sibling thread following a 1T/2T switch. In +particular, a RET instruction executed immediately after a transition to 1T may +use a return target from the thread that just became idle. In theory, this +could lead to information disclosure if the return targets used do not come +from trustworthy code. + +Attack scenarios +---------------- + +An attack can be mounted on affected processors by performing a series of CALL +instructions with targeted return locations and then transitioning out of C0 +state. + +Mitigation mechanism +-------------------- + +Before entering idle state, the kernel context switches to the idle thread. The +context switch fills the RAP entries (referred to as the RSB in Linux) with safe +targets by performing a sequence of CALL instructions. + +Prevent a guest VM from directly putting the processor into an idle state by +intercepting HLT and MWAIT instructions. + +Both mitigations are required to fully address this issue. + +Mitigation control on the kernel command line +--------------------------------------------- + +Use existing Spectre v2 mitigations that will fill the RSB on context switch. + +Mitigation control for KVM - module parameter +--------------------------------------------- + +By default, the KVM hypervisor mitigates this issue by intercepting guest +attempts to transition out of C0. A VMM can use the KVM_CAP_X86_DISABLE_EXITS +capability to override those interceptions, but since this is not common, the +mitigation that covers this path is not enabled by default. + +The mitigation for the KVM_CAP_X86_DISABLE_EXITS capability can be turned on +using the boolean module parameter mitigate_smt_rsb, e.g.: + kvm.mitigate_smt_rsb=1 --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst @@ -0,0 +1,109 @@ +.. SPDX-License-Identifier: GPL-2.0 + +GDS - Gather Data Sampling +========================== + +Gather Data Sampling is a hardware vulnerability which allows unprivileged +speculative access to data which was previously stored in vector registers. + +Problem +------- +When a gather instruction performs loads from memory, different data elements +are merged into the destination vector register. However, when a gather +instruction that is transiently executed encounters a fault, stale data from +architectural or internal vector registers may get transiently forwarded to the +destination vector register instead. This will allow a malicious attacker to +infer stale data using typical side channel techniques like cache timing +attacks. GDS is a purely sampling-based attack. + +The attacker uses gather instructions to infer the stale vector register data. +The victim does not need to do anything special other than use the vector +registers. The victim does not need to use gather instructions to be +vulnerable. + +Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks +are possible. + +Attack scenarios +---------------- +Without mitigation, GDS can infer stale data across virtually all +permission boundaries: + + Non-enclaves can infer SGX enclave data + Userspace can infer kernel data + Guests can infer data from hosts + Guest can infer guest from other guests + Users can infer data from other users + +Because of this, it is important to ensure that the mitigation stays enabled in +lower-privilege contexts like guests and when running outside SGX enclaves. + +The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure +that guests are not allowed to disable the GDS mitigation. If a host erred and +allowed this, a guest could theoretically disable GDS mitigation, mount an +attack, and re-enable it. + +Mitigation mechanism +-------------------- +This issue is mitigated in microcode. The microcode defines the following new +bits: + + ================================ === ============================ + IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability + and mitigation support. + IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable. + IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation + 0 by default. + IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes + to GDS_MITG_DIS are ignored + Can't be cleared once set. + ================================ === ============================ + +GDS can also be mitigated on systems that don't have updated microcode by +disabling AVX. This can be done by setting gather_data_sampling="force" or +"clearcpuid=avx" on the kernel command-line. + +If used, these options will disable AVX use by turning off XSAVE YMM support. +However, the processor will still enumerate AVX support. Userspace that +does not follow proper AVX enumeration to check both AVX *and* XSAVE YMM +support will break. + +Mitigation control on the kernel command line +--------------------------------------------- +The mitigation can be disabled by setting "gather_data_sampling=off" or +"mitigations=off" on the kernel command line. Not specifying either will default +to the mitigation being enabled. Specifying "gather_data_sampling=force" will +use the microcode mitigation when available or disable AVX on affected systems +where the microcode hasn't been updated to include the mitigation. + +GDS System Information +------------------------ +The kernel provides vulnerability status information through sysfs. For +GDS this can be accessed by the following sysfs file: + +/sys/devices/system/cpu/vulnerabilities/gather_data_sampling + +The possible values contained in this file are: + + ============================== ============================================= + Not affected Processor not vulnerable. + Vulnerable Processor vulnerable and mitigation disabled. + Vulnerable: No microcode Processor vulnerable and microcode is missing + mitigation. + Mitigation: AVX disabled, + no microcode Processor is vulnerable and microcode is missing + mitigation. AVX disabled as mitigation. + Mitigation: Microcode Processor is vulnerable and mitigation is in + effect. + Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in + effect and cannot be disabled. + Unknown: Dependent on + hypervisor status Running on a virtual guest processor that is + affected but with no way to know if host + processor is mitigated or vulnerable. + ============================== ============================================= + +GDS Default mitigation +---------------------- +The updated microcode will enable the mitigation by default. The kernel's +default action is to leave the mitigation enabled. --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/index.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/index.rst @@ -14,3 +14,7 @@ mds tsx_async_abort multihit.rst + special-register-buffer-data-sampling.rst + processor_mmio_stale_data.rst + cross-thread-rsb.rst + gather_data_sampling.rst --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/mds.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/mds.rst @@ -265,8 +265,11 @@ ============ ============================================================= -Not specifying this option is equivalent to "mds=full". - +Not specifying this option is equivalent to "mds=full". For processors +that are affected by both TAA (TSX Asynchronous Abort) and MDS, +specifying just "mds=off" without an accompanying "tsx_async_abort=off" +will have no effect as the same mitigation is used for both +vulnerabilities. Mitigation selection guide -------------------------- --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst @@ -0,0 +1,260 @@ +========================================= +Processor MMIO Stale Data Vulnerabilities +========================================= + +Processor MMIO Stale Data Vulnerabilities are a class of memory-mapped I/O +(MMIO) vulnerabilities that can expose data. The sequences of operations for +exposing data range from simple to very complex. Because most of the +vulnerabilities require the attacker to have access to MMIO, many environments +are not affected. System environments using virtualization where MMIO access is +provided to untrusted guests may need mitigation. These vulnerabilities are +not transient execution attacks. However, these vulnerabilities may propagate +stale data into core fill buffers where the data can subsequently be inferred +by an unmitigated transient execution attack. Mitigation for these +vulnerabilities includes a combination of microcode update and software +changes, depending on the platform and usage model. Some of these mitigations +are similar to those used to mitigate Microarchitectural Data Sampling (MDS) or +those used to mitigate Special Register Buffer Data Sampling (SRBDS). + +Data Propagators +================ +Propagators are operations that result in stale data being copied or moved from +one microarchitectural buffer or register to another. Processor MMIO Stale Data +Vulnerabilities are operations that may result in stale data being directly +read into an architectural, software-visible state or sampled from a buffer or +register. + +Fill Buffer Stale Data Propagator (FBSDP) +----------------------------------------- +Stale data may propagate from fill buffers (FB) into the non-coherent portion +of the uncore on some non-coherent writes. Fill buffer propagation by itself +does not make stale data architecturally visible. Stale data must be propagated +to a location where it is subject to reading or sampling. + +Sideband Stale Data Propagator (SSDP) +------------------------------------- +The sideband stale data propagator (SSDP) is limited to the client (including +Intel Xeon server E3) uncore implementation. The sideband response buffer is +shared by all client cores. For non-coherent reads that go to sideband +destinations, the uncore logic returns 64 bytes of data to the core, including +both requested data and unrequested stale data, from a transaction buffer and +the sideband response buffer. As a result, stale data from the sideband +response and transaction buffers may now reside in a core fill buffer. + +Primary Stale Data Propagator (PSDP) +------------------------------------ +The primary stale data propagator (PSDP) is limited to the client (including +Intel Xeon server E3) uncore implementation. Similar to the sideband response +buffer, the primary response buffer is shared by all client cores. For some +processors, MMIO primary reads will return 64 bytes of data to the core fill +buffer including both requested data and unrequested stale data. This is +similar to the sideband stale data propagator. + +Vulnerabilities +=============== +Device Register Partial Write (DRPW) (CVE-2022-21166) +----------------------------------------------------- +Some endpoint MMIO registers incorrectly handle writes that are smaller than +the register size. Instead of aborting the write or only copying the correct +subset of bytes (for example, 2 bytes for a 2-byte write), more bytes than +specified by the write transaction may be written to the register. On +processors affected by FBSDP, this may expose stale data from the fill buffers +of the core that created the write transaction. + +Shared Buffers Data Sampling (SBDS) (CVE-2022-21125) +---------------------------------------------------- +After propagators may have moved data around the uncore and copied stale data +into client core fill buffers, processors affected by MFBDS can leak data from +the fill buffer. It is limited to the client (including Intel Xeon server E3) +uncore implementation. + +Shared Buffers Data Read (SBDR) (CVE-2022-21123) +------------------------------------------------ +It is similar to Shared Buffer Data Sampling (SBDS) except that the data is +directly read into the architectural software-visible state. It is limited to +the client (including Intel Xeon server E3) uncore implementation. + +Affected Processors +=================== +Not all the CPUs are affected by all the variants. For instance, most +processors for the server market (excluding Intel Xeon E3 processors) are +impacted by only Device Register Partial Write (DRPW). + +Below is the list of affected Intel processors [#f1]_: + + =================== ============ ========= + Common name Family_Model Steppings + =================== ============ ========= + HASWELL_X 06_3FH 2,4 + SKYLAKE_L 06_4EH 3 + BROADWELL_X 06_4FH All + SKYLAKE_X 06_55H 3,4,6,7,11 + BROADWELL_D 06_56H 3,4,5 + SKYLAKE 06_5EH 3 + ICELAKE_X 06_6AH 4,5,6 + ICELAKE_D 06_6CH 1 + ICELAKE_L 06_7EH 5 + ATOM_TREMONT_D 06_86H All + LAKEFIELD 06_8AH 1 + KABYLAKE_L 06_8EH 9 to 12 + ATOM_TREMONT 06_96H 1 + ATOM_TREMONT_L 06_9CH 0 + KABYLAKE 06_9EH 9 to 13 + COMETLAKE 06_A5H 2,3,5 + COMETLAKE_L 06_A6H 0,1 + ROCKETLAKE 06_A7H 1 + =================== ============ ========= + +If a CPU is in the affected processor list, but not affected by a variant, it +is indicated by new bits in MSR IA32_ARCH_CAPABILITIES. As described in a later +section, mitigation largely remains the same for all the variants, i.e. to +clear the CPU fill buffers via VERW instruction. + +New bits in MSRs +================ +Newer processors and microcode update on existing affected processors added new +bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate +specific variants of Processor MMIO Stale Data vulnerabilities and mitigation +capability. + +MSR IA32_ARCH_CAPABILITIES +-------------------------- +Bit 13 - SBDR_SSDP_NO - When set, processor is not affected by either the + Shared Buffers Data Read (SBDR) vulnerability or the sideband stale + data propagator (SSDP). +Bit 14 - FBSDP_NO - When set, processor is not affected by the Fill Buffer + Stale Data Propagator (FBSDP). +Bit 15 - PSDP_NO - When set, processor is not affected by Primary Stale Data + Propagator (PSDP). +Bit 17 - FB_CLEAR - When set, VERW instruction will overwrite CPU fill buffer + values as part of MD_CLEAR operations. Processors that do not + enumerate MDS_NO (meaning they are affected by MDS) but that do + enumerate support for both L1D_FLUSH and MD_CLEAR implicitly enumerate + FB_CLEAR as part of their MD_CLEAR support. +Bit 18 - FB_CLEAR_CTRL - Processor supports read and write to MSR + IA32_MCU_OPT_CTRL[FB_CLEAR_DIS]. On such processors, the FB_CLEAR_DIS + bit can be set to cause the VERW instruction to not perform the + FB_CLEAR action. Not all processors that support FB_CLEAR will support + FB_CLEAR_CTRL. + +MSR IA32_MCU_OPT_CTRL +--------------------- +Bit 3 - FB_CLEAR_DIS - When set, VERW instruction does not perform the FB_CLEAR +action. This may be useful to reduce the performance impact of FB_CLEAR in +cases where system software deems it warranted (for example, when performance +is more critical, or the untrusted software has no MMIO access). Note that +FB_CLEAR_DIS has no impact on enumeration (for example, it does not change +FB_CLEAR or MD_CLEAR enumeration) and it may not be supported on all processors +that enumerate FB_CLEAR. + +Mitigation +========== +Like MDS, all variants of Processor MMIO Stale Data vulnerabilities have the +same mitigation strategy to force the CPU to clear the affected buffers before +an attacker can extract the secrets. + +This is achieved by using the otherwise unused and obsolete VERW instruction in +combination with a microcode update. The microcode clears the affected CPU +buffers when the VERW instruction is executed. + +Kernel reuses the MDS function to invoke the buffer clearing: + + mds_clear_cpu_buffers() + +On MDS affected CPUs, the kernel already invokes CPU buffer clear on +kernel/userspace, hypervisor/guest and C-state (idle) transitions. No +additional mitigation is needed on such CPUs. + +For CPUs not affected by MDS or TAA, mitigation is needed only for the attacker +with MMIO capability. Therefore, VERW is not required for kernel/userspace. For +virtualization case, VERW is only needed at VMENTER for a guest with MMIO +capability. + +Mitigation points +----------------- +Return to user space +^^^^^^^^^^^^^^^^^^^^ +Same mitigation as MDS when affected by MDS/TAA, otherwise no mitigation +needed. + +C-State transition +^^^^^^^^^^^^^^^^^^ +Control register writes by CPU during C-state transition can propagate data +from fill buffer to uncore buffers. Execute VERW before C-state transition to +clear CPU fill buffers. + +Guest entry point +^^^^^^^^^^^^^^^^^ +Same mitigation as MDS when processor is also affected by MDS/TAA, otherwise +execute VERW at VMENTER only for MMIO capable guests. On CPUs not affected by +MDS/TAA, guest without MMIO access cannot extract secrets using Processor MMIO +Stale Data vulnerabilities, so there is no need to execute VERW for such guests. + +Mitigation control on the kernel command line +--------------------------------------------- +The kernel command line allows to control the Processor MMIO Stale Data +mitigations at boot time with the option "mmio_stale_data=". The valid +arguments for this option are: + + ========== ================================================================= + full If the CPU is vulnerable, enable mitigation; CPU buffer clearing + on exit to userspace and when entering a VM. Idle transitions are + protected as well. It does not automatically disable SMT. + full,nosmt Same as full, with SMT disabled on vulnerable CPUs. This is the + complete mitigation. + off Disables mitigation completely. + ========== ================================================================= + +If the CPU is affected and mmio_stale_data=off is not supplied on the kernel +command line, then the kernel selects the appropriate mitigation. + +Mitigation status information +----------------------------- +The Linux kernel provides a sysfs interface to enumerate the current +vulnerability status of the system: whether the system is vulnerable, and +which mitigations are active. The relevant sysfs file is: + + /sys/devices/system/cpu/vulnerabilities/mmio_stale_data + +The possible values in this file are: + + .. list-table:: + + * - 'Not affected' + - The processor is not vulnerable + * - 'Vulnerable' + - The processor is vulnerable, but no mitigation enabled + * - 'Vulnerable: Clear CPU buffers attempted, no microcode' + - The processor is vulnerable, but microcode is not updated. The + mitigation is enabled on a best effort basis. + * - 'Mitigation: Clear CPU buffers' + - The processor is vulnerable and the CPU buffer clearing mitigation is + enabled. + * - 'Unknown: No mitigations' + - The processor vulnerability status is unknown because it is + out of Servicing period. Mitigation is not attempted. + +Definitions: +------------ + +Servicing period: The process of providing functional and security updates to +Intel processors or platforms, utilizing the Intel Platform Update (IPU) +process or other similar mechanisms. + +End of Servicing Updates (ESU): ESU is the date at which Intel will no +longer provide Servicing, such as through IPU or other similar update +processes. ESU dates will typically be aligned to end of quarter. + +If the processor is vulnerable then the following information is appended to +the above information: + + ======================== =========================================== + 'SMT vulnerable' SMT is enabled + 'SMT disabled' SMT is disabled + 'SMT Host state unknown' Kernel runs in a VM, Host SMT state unknown + ======================== =========================================== + +References +---------- +.. [#f1] Affected Processors + https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/special-register-buffer-data-sampling.rst @@ -0,0 +1,149 @@ +.. SPDX-License-Identifier: GPL-2.0 + +SRBDS - Special Register Buffer Data Sampling +============================================= + +SRBDS is a hardware vulnerability that allows MDS :doc:`mds` techniques to +infer values returned from special register accesses. Special register +accesses are accesses to off core registers. According to Intel's evaluation, +the special register reads that have a security expectation of privacy are +RDRAND, RDSEED and SGX EGETKEY. + +When RDRAND, RDSEED and EGETKEY instructions are used, the data is moved +to the core through the special register mechanism that is susceptible +to MDS attacks. + +Affected processors +-------------------- +Core models (desktop, mobile, Xeon-E3) that implement RDRAND and/or RDSEED may +be affected. + +A processor is affected by SRBDS if its Family_Model and stepping is +in the following list, with the exception of the listed processors +exporting MDS_NO while Intel TSX is available yet not enabled. The +latter class of processors are only affected when Intel TSX is enabled +by software using TSX_CTRL_MSR otherwise they are not affected. + + ============= ============ ======== + common name Family_Model Stepping + ============= ============ ======== + IvyBridge 06_3AH All + + Haswell 06_3CH All + Haswell_L 06_45H All + Haswell_G 06_46H All + + Broadwell_G 06_47H All + Broadwell 06_3DH All + + Skylake_L 06_4EH All + Skylake 06_5EH All + + Kabylake_L 06_8EH <= 0xC + Kabylake 06_9EH <= 0xD + ============= ============ ======== + +Related CVEs +------------ + +The following CVE entry is related to this SRBDS issue: + + ============== ===== ===================================== + CVE-2020-0543 SRBDS Special Register Buffer Data Sampling + ============== ===== ===================================== + +Attack scenarios +---------------- +An unprivileged user can extract values returned from RDRAND and RDSEED +executed on another core or sibling thread using MDS techniques. + + +Mitigation mechanism +------------------- +Intel will release microcode updates that modify the RDRAND, RDSEED, and +EGETKEY instructions to overwrite secret special register data in the shared +staging buffer before the secret data can be accessed by another logical +processor. + +During execution of the RDRAND, RDSEED, or EGETKEY instructions, off-core +accesses from other logical processors will be delayed until the special +register read is complete and the secret data in the shared staging buffer is +overwritten. + +This has three effects on performance: + +#. RDRAND, RDSEED, or EGETKEY instructions have higher latency. + +#. Executing RDRAND at the same time on multiple logical processors will be + serialized, resulting in an overall reduction in the maximum RDRAND + bandwidth. + +#. Executing RDRAND, RDSEED or EGETKEY will delay memory accesses from other + logical processors that miss their core caches, with an impact similar to + legacy locked cache-line-split accesses. + +The microcode updates provide an opt-out mechanism (RNGDS_MITG_DIS) to disable +the mitigation for RDRAND and RDSEED instructions executed outside of Intel +Software Guard Extensions (Intel SGX) enclaves. On logical processors that +disable the mitigation using this opt-out mechanism, RDRAND and RDSEED do not +take longer to execute and do not impact performance of sibling logical +processors memory accesses. The opt-out mechanism does not affect Intel SGX +enclaves (including execution of RDRAND or RDSEED inside an enclave, as well +as EGETKEY execution). + +IA32_MCU_OPT_CTRL MSR Definition +-------------------------------- +Along with the mitigation for this issue, Intel added a new thread-scope +IA32_MCU_OPT_CTRL MSR, (address 0x123). The presence of this MSR and +RNGDS_MITG_DIS (bit 0) is enumerated by CPUID.(EAX=07H,ECX=0).EDX[SRBDS_CTRL = +9]==1. This MSR is introduced through the microcode update. + +Setting IA32_MCU_OPT_CTRL[0] (RNGDS_MITG_DIS) to 1 for a logical processor +disables the mitigation for RDRAND and RDSEED executed outside of an Intel SGX +enclave on that logical processor. Opting out of the mitigation for a +particular logical processor does not affect the RDRAND and RDSEED mitigations +for other logical processors. + +Note that inside of an Intel SGX enclave, the mitigation is applied regardless +of the value of RNGDS_MITG_DS. + +Mitigation control on the kernel command line +--------------------------------------------- +The kernel command line allows control over the SRBDS mitigation at boot time +with the option "srbds=". The option for this is: + + ============= ============================================================= + off This option disables SRBDS mitigation for RDRAND and RDSEED on + affected platforms. + ============= ============================================================= + +SRBDS System Information +----------------------- +The Linux kernel provides vulnerability status information through sysfs. For +SRBDS this can be accessed by the following sysfs file: +/sys/devices/system/cpu/vulnerabilities/srbds + +The possible values contained in this file are: + + ============================== ============================================= + Not affected Processor not vulnerable + Vulnerable Processor vulnerable and mitigation disabled + Vulnerable: No microcode Processor vulnerable and microcode is missing + mitigation + Mitigation: Microcode Processor is vulnerable and mitigation is in + effect. + Mitigation: TSX disabled Processor is only vulnerable when TSX is + enabled while this system was booted with TSX + disabled. + Unknown: Dependent on + hypervisor status Running on virtual guest processor that is + affected but with no way to know if host + processor is mitigated or vulnerable. + ============================== ============================================= + +SRBDS Default mitigation +------------------------ +This new microcode serializes processor access during execution of RDRAND, +RDSEED ensures that the shared buffer is overwritten before it is released for +reuse. Use the "srbds=off" kernel command line to disable the mitigation for +RDRAND and RDSEED. --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/spectre.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/spectre.rst @@ -60,8 +60,8 @@ Spectre variant 1 attacks take advantage of speculative execution of conditional branches, while Spectre variant 2 attacks use speculative execution of indirect branches to leak privileged memory. -See :ref:`[1] ` :ref:`[5] ` :ref:`[7] ` -:ref:`[10] ` :ref:`[11] `. +See :ref:`[1] ` :ref:`[5] ` :ref:`[6] ` +:ref:`[7] ` :ref:`[10] ` :ref:`[11] `. Spectre variant 1 (Bounds Check Bypass) --------------------------------------- @@ -131,6 +131,18 @@ speculative execution's side effects left in level 1 cache to infer the victim's data. +Yet another variant 2 attack vector is for the attacker to poison the +Branch History Buffer (BHB) to speculatively steer an indirect branch +to a specific Branch Target Buffer (BTB) entry, even if the entry isn't +associated with the source address of the indirect branch. Specifically, +the BHB might be shared across privilege levels even in the presence of +Enhanced IBRS. + +Previously the only known real-world BHB attack vector was via unprivileged +eBPF. Further research has found attacks that don't require unprivileged eBPF. +For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or +use the BHB clearing sequence. + Attack scenarios ---------------- @@ -364,13 +376,15 @@ - Kernel status: - ==================================== ================================= - 'Not affected' The processor is not vulnerable - 'Vulnerable' Vulnerable, no mitigation - 'Mitigation: Full generic retpoline' Software-focused mitigation - 'Mitigation: Full AMD retpoline' AMD-specific software mitigation - 'Mitigation: Enhanced IBRS' Hardware-focused mitigation - ==================================== ================================= + ======================================== ================================= + 'Not affected' The processor is not vulnerable + 'Mitigation: None' Vulnerable, no mitigation + 'Mitigation: Retpolines' Use Retpoline thunks + 'Mitigation: LFENCE' Use LFENCE instructions + 'Mitigation: Enhanced IBRS' Hardware-focused mitigation + 'Mitigation: Enhanced IBRS + Retpolines' Hardware-focused + Retpolines + 'Mitigation: Enhanced IBRS + LFENCE' Hardware-focused + LFENCE + ======================================== ================================= - Firmware status: Show if Indirect Branch Restricted Speculation (IBRS) is used to protect against Spectre variant 2 attacks when calling firmware (x86 only). @@ -407,6 +421,31 @@ 'RSB filling' Protection of RSB on context switch enabled ============= =========================================== + - EIBRS Post-barrier Return Stack Buffer (PBRSB) protection status: + + =========================== ======================================================= + 'PBRSB-eIBRS: SW sequence' CPU is affected and protection of RSB on VMEXIT enabled + 'PBRSB-eIBRS: Vulnerable' CPU is vulnerable + 'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB + =========================== ======================================================= + + - Branch History Injection (BHI) protection status: + +.. list-table:: + + * - BHI: Not affected + - System is not affected + * - BHI: Retpoline + - System is protected by retpoline + * - BHI: BHI_DIS_S + - System is protected by BHI_DIS_S + * - BHI: SW loop, KVM SW loop + - System is protected by software clearing sequence + * - BHI: Vulnerable + - System is vulnerable to BHI + * - BHI: Vulnerable, KVM: SW loop + - System is vulnerable; KVM is protected by software clearing sequence + Full mitigation might require a microcode update from the CPU vendor. When the necessary microcode is not available, the kernel will report vulnerability. @@ -456,8 +495,19 @@ On Intel Skylake-era systems the mitigation covers most, but not all, cases. See :ref:`[3] ` for more details. - On CPUs with hardware mitigation for Spectre variant 2 (e.g. Enhanced - IBRS on x86), retpoline is automatically disabled at run time. + On CPUs with hardware mitigation for Spectre variant 2 (e.g. IBRS + or enhanced IBRS on x86), retpoline is automatically disabled at run time. + + Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at + boot, by setting the IBRS bit, and they're automatically protected against + Spectre v2 variant attacks. + + On Intel's enhanced IBRS systems, this includes cross-thread branch target + injections on SMT systems (STIBP). In other words, Intel eIBRS enables + STIBP, too. + + AMD Automatic IBRS does not protect userspace, and Legacy IBRS systems clear + the IBRS bit on exit to userspace, therefore both explicitly enable STIBP. The retpoline mitigation is turned on by default on vulnerable CPUs. It can be forced on or off by the administrator @@ -468,7 +518,7 @@ before invoking any firmware code to prevent Spectre variant 2 exploits using the firmware. - Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=y + Using kernel address space randomization (CONFIG_RANDOMIZE_BASE=y and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes attacks on the kernel generally more difficult. @@ -481,9 +531,12 @@ For Spectre variant 2 mitigation, individual user programs can be compiled with return trampolines for indirect branches. This protects them from consuming poisoned entries in the branch - target buffer left by malicious software. Alternatively, the - programs can disable their indirect branch speculation via prctl() - (See :ref:`Documentation/userspace-api/spec_ctrl.rst `). + target buffer left by malicious software. + + On legacy IBRS systems, at return to userspace, implicit STIBP is disabled + because the kernel clears the IBRS bit. In this case, the userspace programs + can disable indirect branch speculation via prctl() (See + :ref:`Documentation/userspace-api/spec_ctrl.rst `). On x86, this will turn on STIBP to guard against attacks from the sibling thread when the user program is running, and use IBPB to flush the branch target buffer when switching to/from the program. @@ -584,12 +637,14 @@ Specific mitigations can also be selected manually: - retpoline - replace indirect branches - retpoline,generic - google's original retpoline - retpoline,amd - AMD-specific minimal thunk + retpoline auto pick between generic,lfence + retpoline,generic Retpolines + retpoline,lfence LFENCE; indirect branch + retpoline,amd alias for retpoline,lfence + eibrs Enhanced/Auto IBRS + eibrs,retpoline Enhanced/Auto IBRS + Retpolines + eibrs,lfence Enhanced/Auto IBRS + LFENCE + ibrs use IBRS to protect kernel Not specifying this option is equivalent to spectre_v2=auto. @@ -649,6 +704,24 @@ spectre_v2=off. Spectre variant 1 mitigations cannot be disabled. + spectre_bhi= + + [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. This setting affects the deployment + of the HW BHI control and the SW BHB clearing sequence. + + on + (default) Enable the HW or SW mitigation as + needed. + off + Disable the mitigation. + auto + Enable the HW mitigation if needed, but + *don't* enable the SW mitigation except for KVM. + The system may be vulnerable. + +For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt + Mitigation selection guide -------------------------- @@ -730,7 +803,7 @@ .. _spec_ref6: -[6] `Software techniques for managing speculation on AMD processors `_. +[6] `Software techniques for managing speculation on AMD processors `_. ARM white papers: --- linux-oracle-5.4.0.orig/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/hw-vuln/tsx_async_abort.rst @@ -174,7 +174,10 @@ CPU is not vulnerable to cross-thread TAA attacks. ============ ============================================================= -Not specifying this option is equivalent to "tsx_async_abort=full". +Not specifying this option is equivalent to "tsx_async_abort=full". For +processors that are affected by both TAA and MDS, specifying just +"tsx_async_abort=off" without an accompanying "mds=off" will have no +effect as the same mitigation is used for both vulnerabilities. The kernel command line also allows to control the TSX feature using the parameter "tsx=" on CPUs which support TSX control. MSR_IA32_TSX_CTRL is used --- linux-oracle-5.4.0.orig/Documentation/admin-guide/iostats.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/iostats.rst @@ -99,7 +99,7 @@ Since 5.0 this field counts jiffies when at least one request was started or completed. If request runs more than 2 jiffies then some - I/O time will not be accounted unless there are other requests. + I/O time might be not accounted in case of concurrent requests. Field 11 -- weighted # of milliseconds spent doing I/Os This field is incremented at each I/O start, I/O completion, I/O @@ -133,6 +133,9 @@ summed to) and the result given to the user. There is no convenient user interface for accessing the per-CPU counters themselves. +Since 4.19 request times are measured with nanoseconds precision and +truncated to milliseconds before showing in this interface. + Disks vs Partitions ------------------- --- linux-oracle-5.4.0.orig/Documentation/admin-guide/kdump/vmcoreinfo.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/kdump/vmcoreinfo.rst @@ -393,6 +393,17 @@ The kernel randomization offset. Used to compute the page offset. If KASLR is disabled, this value is zero. +TCR_EL1.T1SZ +------------ + +Indicates the size offset of the memory region addressed by TTBR1_EL1. +The region size is 2^(64-T1SZ) bytes. + +TTBR1_EL1 is the table base address register specified by ARMv8-A +architecture which is used to lookup the page-tables for the Virtual +addresses in the higher VA range (refer to ARMv8 ARM document for +more details). + arm === --- linux-oracle-5.4.0.orig/Documentation/admin-guide/kernel-parameters.txt +++ linux-oracle-5.4.0/Documentation/admin-guide/kernel-parameters.txt @@ -113,7 +113,7 @@ the GPE dispatcher. This facility can be used to prevent such uncontrolled GPE floodings. - Format: + Format: acpi_no_auto_serialize [HW,ACPI] Disable auto-serialization of AML methods @@ -136,6 +136,10 @@ dynamic table installation which will install SSDT tables to /sys/firmware/acpi/tables/dynamic. + acpi_no_watchdog [HW,ACPI,WDT] + Ignore the ACPI-based watchdog interface (WDAT) and let + a native driver control the watchdog device instead. + acpi_rsdp= [ACPI,EFI,KEXEC] Pass the RSDP address to the kernel, mostly used on machines running EFI runtime service to boot the @@ -563,7 +567,13 @@ loops can be debugged more effectively on production systems. - clearcpuid=BITNUM [X86] + clocksource.max_cswd_read_retries= [KNL] + Number of clocksource_watchdog() retries due to + external delays before the clock will be marked + unstable. Defaults to three retries, that is, + four attempts to read the clock under test. + + clearcpuid=BITNUM[,BITNUM...] [X86] Disable CPUID feature X for the kernel. See arch/x86/include/asm/cpufeatures.h for the valid bit numbers. Note the Linux specific bits are not necessarily @@ -680,6 +690,10 @@ 0: default value, disable debugging 1: enable debugging at boot time + cpufreq_driver= [X86] Allow only the named cpu frequency scaling driver + to register. Example: cpufreq_driver=powernow-k8 + Format: { none | STRING } + cpuidle.off=1 [CPU_IDLE] disable the cpuidle sub-system @@ -815,10 +829,6 @@ debugpat [X86] Enable PAT debugging - decnet.addr= [HW,NET] - Format: [,] - See also Documentation/networking/decnet.txt. - default_hugepagesz= [same as hugepagesz=] The size of the default HugeTLB page size. This is the size represented by @@ -836,6 +846,18 @@ dump out devices still on the deferred probe list after retrying. + dfltcc= [HW,S390] + Format: { on | off | def_only | inf_only | always } + on: s390 zlib hardware support for compression on + level 1 and decompression (default) + off: No s390 zlib hardware support + def_only: s390 zlib hardware support for deflate + only (compression on level 1) + inf_only: s390 zlib hardware support for inflate + only (decompression) + always: Same as 'on' but ignores the selected compression + level always using hardware support (used for debugging) + dhash_entries= [KNL] Set number of hash buckets for dentry cache. @@ -1330,6 +1352,26 @@ Format: off | on default: on + gather_data_sampling= + [X86,INTEL] Control the Gather Data Sampling (GDS) + mitigation. + + Gather Data Sampling is a hardware vulnerability which + allows unprivileged speculative access to data which was + previously stored in vector registers. + + This issue is mitigated by default in updated microcode. + The mitigation may have a performance impact but can be + disabled. On systems without the microcode mitigation + disabling AVX serves as a mitigation. + + force: Disable AVX to mitigate systems without + microcode mitigation. No effect if the microcode + mitigation is present. Known to cause crashes in + userspace with buggy AVX enumeration. + + off: Disable GDS mitigation. + gcov_persist= [GCOV] When non-zero (default), profiling data for kernel modules is saved and remains accessible via debugfs, even when the module is unloaded/reloaded. @@ -1477,6 +1519,8 @@ architectures force reset to be always executed i8042.unlock [HW] Unlock (ignore) the keylock i8042.kbdreset [HW] Reset device connected to KBD port + i8042.probe_defer + [HW] Allow deferred probing upon i8042 probe errors i810= [HW,DRM] @@ -1932,24 +1976,57 @@ ivrs_ioapic [HW,X86_64] Provide an override to the IOAPIC-ID<->DEVICE-ID - mapping provided in the IVRS ACPI table. For - example, to map IOAPIC-ID decimal 10 to - PCI device 00:14.0 write the parameter as: + mapping provided in the IVRS ACPI table. + By default, PCI segment is 0, and can be omitted. + + For example, to map IOAPIC-ID decimal 10 to + PCI segment 0x1 and PCI device 00:14.0, + write the parameter as: + ivrs_ioapic=10@0001:00:14.0 + + Deprecated formats: + * To map IOAPIC-ID decimal 10 to PCI device 00:14.0 + write the parameter as: ivrs_ioapic[10]=00:14.0 + * To map IOAPIC-ID decimal 10 to PCI segment 0x1 and + PCI device 00:14.0 write the parameter as: + ivrs_ioapic[10]=0001:00:14.0 ivrs_hpet [HW,X86_64] Provide an override to the HPET-ID<->DEVICE-ID - mapping provided in the IVRS ACPI table. For - example, to map HPET-ID decimal 0 to - PCI device 00:14.0 write the parameter as: + mapping provided in the IVRS ACPI table. + By default, PCI segment is 0, and can be omitted. + + For example, to map HPET-ID decimal 10 to + PCI segment 0x1 and PCI device 00:14.0, + write the parameter as: + ivrs_hpet=10@0001:00:14.0 + + Deprecated formats: + * To map HPET-ID decimal 0 to PCI device 00:14.0 + write the parameter as: ivrs_hpet[0]=00:14.0 + * To map HPET-ID decimal 10 to PCI segment 0x1 and + PCI device 00:14.0 write the parameter as: + ivrs_ioapic[10]=0001:00:14.0 ivrs_acpihid [HW,X86_64] Provide an override to the ACPI-HID:UID<->DEVICE-ID - mapping provided in the IVRS ACPI table. For - example, to map UART-HID:UID AMD0020:0 to - PCI device 00:14.5 write the parameter as: + mapping provided in the IVRS ACPI table. + By default, PCI segment is 0, and can be omitted. + + For example, to map UART-HID:UID AMD0020:0 to + PCI segment 0x1 and PCI device ID 00:14.5, + write the parameter as: + ivrs_acpihid=AMD0020:0@0001:00:14.5 + + Deprecated formats: + * To map UART-HID:UID AMD0020:0 to PCI segment is 0, + PCI device ID 00:14.5, write the parameter as: ivrs_acpihid[00:14.5]=AMD0020:0 + * To map UART-HID:UID AMD0020:0 to PCI segment 0x1 and + PCI device ID 00:14.5, write the parameter as: + ivrs_acpihid[0001:00:14.5]=AMD0020:0 js= [HW,JOY] Analog joystick See Documentation/input/joydev/joystick.rst. @@ -2102,8 +2179,12 @@ Default is 1 (enabled) kvm-intel.emulate_invalid_guest_state= - [KVM,Intel] Enable emulation of invalid guest states - Default is 0 (disabled) + [KVM,Intel] Disable emulation of invalid guest state. + Ignored if kvm-intel.enable_unrestricted_guest=1, as + guest state is never invalid for unrestricted guests. + This param doesn't apply to nested guests (L2), as KVM + never emulates invalid L2 guest state. + Default is 1 (enabled) kvm-intel.flexpriority= [KVM,Intel] Disable FlexPriority feature (TPR shadow). @@ -2473,6 +2554,12 @@ SMT on vulnerable CPUs off - Unconditionally disable MDS mitigation + On TAA-affected machines, mds=off can be prevented by + an active TAA mitigation as both vulnerabilities are + mitigated with the same mechanism so in order to disable + this mitigation, you need to specify tsx_async_abort=off + too. + Not specifying this option is equivalent to mds=full. @@ -2645,18 +2732,27 @@ Disable all optional CPU mitigations. This improves system performance, but it may also expose users to several CPU vulnerabilities. - Equivalent to: nopti [X86,PPC] - kpti=0 [ARM64] - nospectre_v1 [X86,PPC] + Equivalent to: if nokaslr then kpti=0 [ARM64] + gather_data_sampling=off [X86] + kvm.nx_huge_pages=off [X86] + l1tf=off [X86] + mds=off [X86] + mmio_stale_data=off [X86] + no_entry_flush [PPC] + no_uaccess_flush [PPC] + mmio_stale_data=off [X86] nobp=0 [S390] + nopti [X86,PPC] + nospectre_bhb [ARM64] + nospectre_v1 [X86,PPC] nospectre_v2 [X86,PPC,S390,ARM64] - spectre_v2_user=off [X86] + retbleed=off [X86] spec_store_bypass_disable=off [X86,PPC] + spectre_bhi=off [X86] + spectre_v2_user=off [X86] + srbds=off [X86,INTEL] ssbd=force-off [ARM64] - l1tf=off [X86] - mds=off [X86] tsx_async_abort=off [X86] - kvm.nx_huge_pages=off [X86] Exceptions: This does not have any effect on @@ -2678,6 +2774,7 @@ Equivalent to: l1tf=flush,nosmt [X86] mds=full,nosmt [X86] tsx_async_abort=full,nosmt [X86] + mmio_stale_data=full,nosmt [X86] mminit_loglevel= [KNL] When CONFIG_DEBUG_MEMORY_INIT is set, this @@ -2687,6 +2784,40 @@ log everything. Information is printed at KERN_DEBUG so loglevel=8 may also need to be specified. + mmio_stale_data= + [X86,INTEL] Control mitigation for the Processor + MMIO Stale Data vulnerabilities. + + Processor MMIO Stale Data is a class of + vulnerabilities that may expose data after an MMIO + operation. Exposed data could originate or end in + the same CPU buffers as affected by MDS and TAA. + Therefore, similar to MDS and TAA, the mitigation + is to clear the affected CPU buffers. + + This parameter controls the mitigation. The + options are: + + full - Enable mitigation on vulnerable CPUs + + full,nosmt - Enable mitigation and disable SMT on + vulnerable CPUs. + + off - Unconditionally disable mitigation + + On MDS or TAA affected machines, + mmio_stale_data=off can be prevented by an active + MDS or TAA mitigation as these vulnerabilities are + mitigated with the same mechanism so in order to + disable this mitigation, you need to specify + mds=off and tsx_async_abort=off too. + + Not specifying this option is equivalent to + mmio_stale_data=full. + + For details see: + Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst + module.sig_enforce [KNL] When CONFIG_MODULE_SIG is set, this means that modules without (valid) signatures will fail to load. @@ -2731,7 +2862,7 @@ ,[,,,,] mtdparts= [MTD] - See drivers/mtd/cmdlinepart.c. + See drivers/mtd/parsers/cmdlinepart.c multitce=off [PPC] This parameter disables the use of the pSeries firmware feature for updating multiple TCE entries @@ -2979,6 +3110,8 @@ noefi Disable EFI runtime services support. + no_entry_flush [PPC] Don't flush the L1-D cache when entering the kernel. + noexec [IA-64] noexec [X86] @@ -3028,6 +3161,9 @@ nospec_store_bypass_disable [HW] Disable all mitigations for the Speculative Store Bypass vulnerability + no_uaccess_flush + [PPC] Don't flush the L1-D cache after accessing user data. + noxsave [BUGS=X86] Disables x86 extended register state save and restore using xsave. The kernel will fallback to enabling legacy floating-point and sse state. @@ -3402,6 +3538,12 @@ nomsi [MSI] If the PCI_MSI kernel config parameter is enabled, this kernel boot option can be used to disable the use of MSI interrupts system-wide. + clearmsi [X86] Clears MSI/MSI-X enable bits early in boot + time in order to avoid issues like adapters + screaming irqs and preventing boot progress. + Also, it enforces the PCI Local Bus spec + rule that those bits should be 0 in system reset + events (useful for kexec/kdump cases). noioapicquirk [APIC] Disable all boot interrupt quirks. Safety option to keep boot IRQs enabled. This should never be necessary. @@ -3555,6 +3697,8 @@ may put more devices in an IOMMU group. force_floating [S390] Force usage of floating interrupts. nomio [S390] Do not use MIO instructions. + norid [S390] ignore the RID field and force use of + one PCI domain per PCI function pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power Management. @@ -3567,6 +3711,8 @@ even if the platform doesn't give the OS permission to use them. This may cause conflicts if the platform also tries to use these services. + dpc-native Use native PCIe service for DPC only. May + cause conflicts if firmware uses AER or DPC. compat Disable native PCIe services (PME, AER, DPC, PCIe hotplug). @@ -3697,6 +3843,16 @@ printk.time= Show timing data prefixed to each printk message line Format: (1/Y/y=enable, 0/N/n=disable) + proc_mem.force_override= [KNL] + Format: {always | ptrace | never} + Traditionally /proc/pid/mem allows memory permissions to be + overridden without restrictions. This option may be set to + restrict that. Can be one of: + - 'always': traditional behavior always allows mem overrides. + - 'ptrace': only allow mem overrides for active ptracers. + - 'never': never allow mem overrides. + If not specified, default is the CONFIG_PROC_MEM_* choice. + processor.max_cstate= [HW,ACPI] Limit processor to maximum C-state max_cstate=9 overrides any DMI blacklist limit. @@ -3720,6 +3876,11 @@ before loading. See Documentation/admin-guide/blockdev/ramdisk.rst. + prot_virt= [S390] enable hosting protected virtual machines + isolated from the hypervisor (if hardware supports + that). + Format: + psi= [KNL] Enable or disable pressure stall information tracking. Format: @@ -3777,6 +3938,12 @@ fully seed the kernel's CRNG. Default is controlled by CONFIG_RANDOM_TRUST_CPU. + random.trust_bootloader={on,off} + [KNL] Enable or disable trusting the use of a + seed passed by the bootloader (if available) to + fully seed the kernel's CRNG. Default is controlled + by CONFIG_RANDOM_TRUST_BOOTLOADER. + ras=option[,option,...] [KNL] RAS-specific options cec_disable [X86] @@ -4227,6 +4394,18 @@ retain_initrd [RAM] Keep initrd memory after extraction + retbleed= [X86] Control mitigation of RETBleed (Arbitrary + Speculative Code Execution with Return Instructions) + vulnerability. + + off - unconditionally disable + auto - automatically select a migitation + + Selecting 'auto' will choose a mitigation method at run + time according to the CPU. + + Not specifying this option is equivalent to retbleed=auto. + rfkill.default_state= 0 "airplane mode". All wifi, bluetooth, wimax, gps, fm, etc. communication is blocked by default. @@ -4437,6 +4616,18 @@ sonypi.*= [HW] Sony Programmable I/O Control Device driver See Documentation/admin-guide/laptops/sonypi.rst + spectre_bhi= [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. This setting affects the + deployment of the HW BHI control and the SW BHB + clearing sequence. + + on - (default) Enable the HW or SW mitigation + as needed. + off - Disable the mitigation. + auto - Enable the HW mitigation if needed, but + *don't* enable the SW mitigation except + for KVM. The system may be vulnerable. + spectre_v2= [X86] Control mitigation of Spectre variant 2 (indirect branch speculation) vulnerability. The default operation protects the kernel from @@ -4464,8 +4655,13 @@ Specific mitigations can also be selected manually: retpoline - replace indirect branches - retpoline,generic - google's original retpoline - retpoline,amd - AMD-specific minimal thunk + retpoline,generic - Retpolines + retpoline,lfence - LFENCE; indirect branch + retpoline,amd - alias for retpoline,lfence + eibrs - Enhanced/Auto IBRS + eibrs,retpoline - Enhanced/Auto IBRS + Retpolines + eibrs,lfence - Enhanced/Auto IBRS + LFENCE + ibrs - use IBRS to protect kernel Not specifying this option is equivalent to spectre_v2=auto. @@ -4569,6 +4765,26 @@ spia_pedr= spia_peddr= + srbds= [X86,INTEL] + Control the Special Register Buffer Data Sampling + (SRBDS) mitigation. + + Certain CPUs are vulnerable to an MDS-like + exploit which can leak bits from the random + number generator. + + By default, this issue is mitigated by + microcode. However, the microcode fix can cause + the RDRAND and RDSEED instructions to become + much slower. Among other effects, this will + result in reduced throughput from /dev/urandom. + + The microcode mitigation can be disabled with + the following option: + + off: Disable mitigation and remove + performance impact to RDRAND and RDSEED + srcutree.counter_wrap_check [KNL] Specifies how frequently to check for grace-period sequence counter wrap for the @@ -4931,6 +5147,11 @@ vulnerable to cross-thread TAA attacks. off - Unconditionally disable TAA mitigation + On MDS-affected machines, tsx_async_abort=off can be + prevented by an active MDS mitigation as both vulnerabilities + are mitigated with the same mechanism so in order to disable + this mitigation, you need to specify mds=off too. + Not specifying this option is equivalent to tsx_async_abort=full. On CPUs which are MDS affected and deploy MDS mitigation, TAA mitigation is not @@ -4990,8 +5211,7 @@ usbcore.old_scheme_first= [USB] Start with the old device initialization - scheme, applies only to low and full-speed devices - (default 0 = off). + scheme (default 0 = off). usbcore.usbfs_memory_mb= [USB] Memory limit (in MB) for buffers allocated by @@ -5090,13 +5310,13 @@ Flags is a set of characters, each corresponding to a common usb-storage quirk flag as follows: a = SANE_SENSE (collect more than 18 bytes - of sense data); + of sense data, not on uas); b = BAD_SENSE (don't collect more than 18 - bytes of sense data); + bytes of sense data, not on uas); c = FIX_CAPACITY (decrease the reported device capacity by one sector); d = NO_READ_DISC_INFO (don't use - READ_DISC_INFO command); + READ_DISC_INFO command, not on uas); e = NO_READ_CAPACITY_16 (don't use READ_CAPACITY_16 command); f = NO_REPORT_OPCODES (don't use report opcodes @@ -5110,18 +5330,20 @@ device); j = NO_REPORT_LUNS (don't use report luns command, uas only); + k = NO_SAME (do not use WRITE_SAME, uas only) l = NOT_LOCKABLE (don't try to lock and - unlock ejectable media); + unlock ejectable media, not on uas); m = MAX_SECTORS_64 (don't transfer more - than 64 sectors = 32 KB at a time); + than 64 sectors = 32 KB at a time, + not on uas); n = INITIAL_READ10 (force a retry of the - initial READ(10) command); + initial READ(10) command, not on uas); o = CAPACITY_OK (accept the capacity - reported by the device); + reported by the device, not on uas); p = WRITE_CACHE (the device cache is ON - by default); + by default, not on uas); r = IGNORE_RESIDUE (the device reports - bogus residue values); + bogus residue values, not on uas); s = SINGLE_LUN (the device has only one Logical Unit); t = NO_ATA_1X (don't allow ATA(12) and ATA(16) @@ -5130,7 +5352,8 @@ w = NO_WP_DETECT (don't test whether the medium is write-protected). y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE - even if the device claims no cache) + even if the device claims no cache, + not on uas) Example: quirks=0419:aaf5:rl,0421:0433:rc user_debug= [KNL,ARM] @@ -5408,6 +5631,10 @@ This option is obsoleted by the "nopv" option, which has equivalent effect for XEN platform. + xen_no_vector_callback + [KNL,X86,XEN] Disable the vector callback for Xen + event channel interrupts. + xen_scrub_pages= [XEN] Boolean option to control scrubbing pages before giving them back to Xen, for use by other domains. Can be also changed at runtime @@ -5426,6 +5653,21 @@ as generic guest with no PV drivers. Currently support XEN HVM, KVM, HYPER_V and VMWARE guest. + xen.balloon_boot_timeout= [XEN] + The time (in seconds) to wait before giving up to boot + in case initial ballooning fails to free enough memory. + Applies only when running as HVM or PVH guest and + started with less memory configured than allowed at + max. Default is 180. + + xen.event_eoi_delay= [XEN] + How long to delay EOI handling in case of event + storms (jiffies). Default is 10. + + xen.event_loop_timeout= [XEN] + After which time (jiffies) the event handling loop + should start to delay EOI handling. Default is 2. + xirc2ps_cs= [NET,PCMCIA] Format: ,,,,,[,[,[,]]] --- linux-oracle-5.4.0.orig/Documentation/admin-guide/perf/arm-cmn.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/perf/arm-cmn.rst @@ -0,0 +1,65 @@ +============================= +Arm Coherent Mesh Network PMU +============================= + +CMN-600 is a configurable mesh interconnect consisting of a rectangular +grid of crosspoints (XPs), with each crosspoint supporting up to two +device ports to which various AMBA CHI agents are attached. + +CMN implements a distributed PMU design as part of its debug and trace +functionality. This consists of a local monitor (DTM) at every XP, which +counts up to 4 event signals from the connected device nodes and/or the +XP itself. Overflow from these local counters is accumulated in up to 8 +global counters implemented by the main controller (DTC), which provides +overall PMU control and interrupts for global counter overflow. + +PMU events +---------- + +The PMU driver registers a single PMU device for the whole interconnect, +see /sys/bus/event_source/devices/arm_cmn_0. Multi-chip systems may link +more than one CMN together via external CCIX links - in this situation, +each mesh counts its own events entirely independently, and additional +PMU devices will be named arm_cmn_{1..n}. + +Most events are specified in a format based directly on the TRM +definitions - "type" selects the respective node type, and "eventid" the +event number. Some events require an additional occupancy ID, which is +specified by "occupid". + +* Since RN-D nodes do not have any distinct events from RN-I nodes, they + are treated as the same type (0xa), and the common event templates are + named "rnid_*". + +* The cycle counter is treated as a synthetic event belonging to the DTC + node ("type" == 0x3, "eventid" is ignored). + +* XP events also encode the port and channel in the "eventid" field, to + match the underlying pmu_event0_id encoding for the pmu_event_sel + register. The event templates are named with prefixes to cover all + permutations. + +By default each event provides an aggregate count over all nodes of the +given type. To target a specific node, "bynodeid" must be set to 1 and +"nodeid" to the appropriate value derived from the CMN configuration +(as defined in the "Node ID Mapping" section of the TRM). + +Watchpoints +----------- + +The PMU can also count watchpoint events to monitor specific flit +traffic. Watchpoints are treated as a synthetic event type, and like PMU +events can be global or targeted with a particular XP's "nodeid" value. +Since the watchpoint direction is otherwise implicit in the underlying +register selection, separate events are provided for flit uploads and +downloads. + +The flit match value and mask are passed in config1 and config2 ("val" +and "mask" respectively). "wp_dev_sel", "wp_chn_sel", "wp_grp" and +"wp_exclusive" are specified per the TRM definitions for dtm_wp_config0. +Where a watchpoint needs to match fields from both match groups on the +REQ or SNP channel, it can be specified as two events - one for each +group - with the same nonzero "combine" value. The count for such a +pair of combined events will be attributed to the primary match. +Watchpoint events with a "combine" value of 0 are considered independent +and will count individually. --- linux-oracle-5.4.0.orig/Documentation/admin-guide/perf/index.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/perf/index.rst @@ -11,6 +11,7 @@ qcom_l2_pmu qcom_l3_pmu arm-ccn + arm-cmn xgene-pmu arm_dsu_pmu thunderx2-pmu --- linux-oracle-5.4.0.orig/Documentation/admin-guide/pm/cpuidle.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/pm/cpuidle.rst @@ -676,8 +676,8 @@ by default this way, for example. The other kernel command line parameters controlling CPU idle time management -described below are only relevant for the *x86* architecture and some of -them affect Intel processors only. +described below are only relevant for the *x86* architecture and references +to ``intel_idle`` affect Intel processors only. The *x86* architecture support code recognizes three kernel command line options related to CPU idle time management: ``idle=poll``, ``idle=halt``, @@ -699,10 +699,13 @@ energy-efficiency. Thus using it for performance reasons may not be a good idea at all.] -The ``idle=nomwait`` option disables the ``intel_idle`` driver and causes -``acpi_idle`` to be used (as long as all of the information needed by it is -there in the system's ACPI tables), but it is not allowed to use the -``MWAIT`` instruction of the CPUs to ask the hardware to enter idle states. +The ``idle=nomwait`` option prevents the use of ``MWAIT`` instruction of +the CPU to enter idle states. When this option is used, the ``acpi_idle`` +driver will use the ``HLT`` instruction instead of ``MWAIT``. On systems +running Intel processors, this option disables the ``intel_idle`` driver +and forces the use of the ``acpi_idle`` driver instead. Note that in either +case, ``acpi_idle`` driver will function only if all the information needed +by it is in the system's ACPI tables. In addition to the architecture-level kernel command line options affecting CPU idle time management, there are parameters affecting individual ``CPUIdle`` --- linux-oracle-5.4.0.orig/Documentation/admin-guide/security-bugs.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/security-bugs.rst @@ -56,31 +56,28 @@ of the report are treated confidentially even after the embargo has been lifted, in perpetuity. -Coordination ------------- +Coordination with other groups +------------------------------ -Fixes for sensitive bugs, such as those that might lead to privilege -escalations, may need to be coordinated with the private - mailing list so that distribution vendors -are well prepared to issue a fixed kernel upon public disclosure of the -upstream fix. Distros will need some time to test the proposed patch and -will generally request at least a few days of embargo, and vendor update -publication prefers to happen Tuesday through Thursday. When appropriate, -the security team can assist with this coordination, or the reporter can -include linux-distros from the start. In this case, remember to prefix -the email Subject line with "[vs]" as described in the linux-distros wiki: - +The kernel security team strongly recommends that reporters of potential +security issues NEVER contact the "linux-distros" mailing list until +AFTER discussing it with the kernel security team. Do not Cc: both +lists at once. You may contact the linux-distros mailing list after a +fix has been agreed on and you fully understand the requirements that +doing so will impose on you and the kernel community. + +The different lists have different goals and the linux-distros rules do +not contribute to actually fixing any potential security problems. CVE assignment -------------- -The security team does not normally assign CVEs, nor do we require them -for reports or fixes, as this can needlessly complicate the process and -may delay the bug handling. If a reporter wishes to have a CVE identifier -assigned ahead of public disclosure, they will need to contact the private -linux-distros list, described above. When such a CVE identifier is known -before a patch is provided, it is desirable to mention it in the commit -message if the reporter agrees. +The security team does not assign CVEs, nor do we require them for +reports or fixes, as this can needlessly complicate the process and may +delay the bug handling. If a reporter wishes to have a CVE identifier +assigned, they should find one by themselves, for example by contacting +MITRE directly. However under no circumstances will a patch inclusion +be delayed to wait for a CVE identifier to arrive. Non-disclosure agreements ------------------------- --- linux-oracle-5.4.0.orig/Documentation/admin-guide/sysctl/kernel.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/sysctl/kernel.rst @@ -48,6 +48,8 @@ - hyperv_record_panic_msg - kexec_load_disabled - kptr_restrict +- io_uring_disabled +- io_uring_group - l2cr [ PPC only ] - modprobe ==> Documentation/debugging-modules.txt - modules_disabled @@ -415,7 +417,6 @@ kptr_restrict: ============== - This toggle indicates whether restrictions are placed on exposing kernel addresses via /proc and other interfaces. @@ -438,6 +439,35 @@ %pK will be replaced with 0's regardless of privileges. +io_uring_disabled: +================== + +Prevents all processes from creating new io_uring instances. Enabling this +shrinks the kernel's attack surface. + += ====================================================================== +0 All processes can create io_uring instances as normal. This is the + default setting. +1 io_uring creation is disabled (io_uring_setup() will fail with + -EPERM) for unprivileged processes not in the io_uring_group group. + Existing io_uring instances can still be used. See the + documentation for io_uring_group for more information. +2 io_uring creation is disabled for all processes. io_uring_setup() + always fails with -EPERM. Existing io_uring instances can still be + used. += ====================================================================== + + +io_uring_group: +=============== + +When io_uring_disabled is set to 1, a process must either be +privileged (CAP_SYS_ADMIN) or be in the io_uring_group group in order +to create an io_uring instance. If io_uring_group is set to -1 (the +default), only processes with the CAP_SYS_ADMIN capability may create +io_uring instances. + + l2cr: (PPC only) ================ @@ -557,6 +587,15 @@ scanned for a given scan. +oops_limit +========== + +Number of kernel oopses after which the kernel should panic when +``panic_on_oops`` is not set. Setting this to 0 disables checking +the count. Setting this to 1 has the same effect as setting +``panic_on_oops=1``. The default value is 10000. + + osrelease, ostype & version: ============================ @@ -862,9 +901,40 @@ a one-time setting until next reboot: once set, it cannot be changed by this sysctl interface anymore. +pty +=== -randomize_va_space: -=================== +See Documentation/filesystems/devpts.rst. + + +random +====== + +This is a directory, with the following entries: + +* ``boot_id``: a UUID generated the first time this is retrieved, and + unvarying after that; + +* ``uuid``: a UUID generated every time this is retrieved (this can + thus be used to generate UUIDs at will); + +* ``entropy_avail``: the pool's entropy count, in bits; + +* ``poolsize``: the entropy pool size, in bits; + +* ``urandom_min_reseed_secs``: obsolete (used to determine the minimum + number of seconds between urandom pool reseeding). This file is + writable for compatibility purposes, but writing to it has no effect + on any RNG behavior; + +* ``write_wakeup_threshold``: when the entropy count drops below this + (as a number of bits), processes waiting to write to ``/dev/random`` + are woken up. This file is writable for compatibility purposes, but + writing to it has no effect on any RNG behavior. + + +randomize_va_space +================== This option can be used to select the type of process address space randomization that is used in the system, for architectures @@ -1125,6 +1195,37 @@ example. If a system hangs up, try pressing the NMI switch. +unprivileged_bpf_disabled: +========================== + +Writing 1 to this entry will disable unprivileged calls to ``bpf()``; +once disabled, calling ``bpf()`` without ``CAP_SYS_ADMIN`` will return +``-EPERM``. Once set to 1, this can't be cleared from the running kernel +anymore. + +Writing 2 to this entry will also disable unprivileged calls to ``bpf()``, +however, an admin can still change this setting later on, if needed, by +writing 0 or 1 to this entry. + +If ``BPF_UNPRIV_DEFAULT_OFF`` is enabled in the kernel config, then this +entry will default to 2 instead of 0. + += ============================================================= +0 Unprivileged calls to ``bpf()`` are enabled +1 Unprivileged calls to ``bpf()`` are disabled without recovery +2 Unprivileged calls to ``bpf()`` are disabled += ============================================================= + + +warn_limit +========== + +Number of kernel warnings after which the kernel should panic when +``panic_on_warn`` is not set. Setting this to 0 disables checking +the warning count. Setting this to 1 has the same effect as setting +``panic_on_warn=1``. The default value is 0. + + watchdog: ========= --- linux-oracle-5.4.0.orig/Documentation/admin-guide/sysctl/net.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/sysctl/net.rst @@ -31,17 +31,18 @@ Table : Subdirectories in /proc/sys/net - ========= =================== = ========== ================== + ========= =================== = ========== =================== Directory Content Directory Content - ========= =================== = ========== ================== - core General parameter appletalk Appletalk protocol - unix Unix domain sockets netrom NET/ROM - 802 E802 protocol ax25 AX25 - ethernet Ethernet protocol rose X.25 PLP layer + ========= =================== = ========== =================== + 802 E802 protocol mptcp Multipath TCP + appletalk Appletalk protocol netfilter Network Filter + ax25 AX25 netrom NET/ROM + bridge Bridging rose X.25 PLP layer + core General parameter tipc TIPC + ethernet Ethernet protocol unix Unix domain sockets ipv4 IP version 4 x25 X.25 protocol - bridge Bridging decnet DEC net - ipv6 IP version 6 tipc TIPC - ========= =================== = ========== ================== + ipv6 IP version 6 + ========= =================== = ========== =================== 1. /proc/sys/net/core - Network core options ============================================ --- linux-oracle-5.4.0.orig/Documentation/admin-guide/sysctl/vm.rst +++ linux-oracle-5.4.0/Documentation/admin-guide/sysctl/vm.rst @@ -61,6 +61,7 @@ - overcommit_memory - overcommit_ratio - page-cluster +- page_lock_unfairness - panic_on_oom - percpu_pagelist_fraction - stat_interval @@ -741,6 +742,14 @@ that consecutive pages readahead would have brought in. +page_lock_unfairness +==================== + +This value determines the number of times that the page lock can be +stolen from under a waiter. After the lock is stolen the number of times +specified in this file (default is 5), the "fair lock handoff" semantics +will apply, and the waiter will only be awakened if the lock can be taken. + panic_on_oom ============ --- linux-oracle-5.4.0.orig/Documentation/arm/memory.rst +++ linux-oracle-5.4.0/Documentation/arm/memory.rst @@ -45,9 +45,14 @@ fffe0000 fffe7fff ITCM mapping area for platforms with ITCM mounted inside the CPU. -ffc00000 ffefffff Fixmap mapping region. Addresses provided +ffc80000 ffefffff Fixmap mapping region. Addresses provided by fix_to_virt() will be located here. +ffc00000 ffc7ffff Guard region + +ff800000 ffbfffff Permanent, fixed read-only mapping of the + firmware provided DT blob + fee00000 feffffff Mapping of PCI I/O space. This is a static mapping within the vmalloc space. --- linux-oracle-5.4.0.orig/Documentation/arm64/cpu-feature-registers.rst +++ linux-oracle-5.4.0/Documentation/arm64/cpu-feature-registers.rst @@ -92,7 +92,7 @@ The infrastructure emulates only the following system register space:: - Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7 + Op0=3, Op1=0, CRn=0, CRm=0,2,3,4,5,6,7 (See Table C5-6 'System instruction encodings for non-Debug System register accesses' in ARMv8 ARM DDI 0487A.h, for the list of @@ -167,6 +167,42 @@ | EL0 | [3-0] | n | +------------------------------+---------+---------+ + 10) MVFR0_EL1 - AArch32 Media and VFP Feature Register 0 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | FPDP | [11-8] | y | + +------------------------------+---------+---------+ + + 11) MVFR1_EL1 - AArch32 Media and VFP Feature Register 1 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | SIMDFMAC | [31-28] | y | + +------------------------------+---------+---------+ + | SIMDSP | [19-16] | y | + +------------------------------+---------+---------+ + | SIMDInt | [15-12] | y | + +------------------------------+---------+---------+ + | SIMDLS | [11-8] | y | + +------------------------------+---------+---------+ + + 12) ID_ISAR5_EL1 - AArch32 Instruction Set Attribute Register 5 + + +------------------------------+---------+---------+ + | Name | bits | visible | + +------------------------------+---------+---------+ + | CRC32 | [19-16] | y | + +------------------------------+---------+---------+ + | SHA2 | [15-12] | y | + +------------------------------+---------+---------+ + | SHA1 | [11-8] | y | + +------------------------------+---------+---------+ + | AES | [7-4] | y | + +------------------------------+---------+---------+ + 3) MIDR_EL1 - Main ID Register --- linux-oracle-5.4.0.orig/Documentation/arm64/silicon-errata.rst +++ linux-oracle-5.4.0/Documentation/arm64/silicon-errata.rst @@ -70,8 +70,12 @@ +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A57 | #1742098 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A72 | #853709 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A72 | #1655431 | ARM64_ERRATUM_1742098 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 | @@ -84,10 +88,52 @@ +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A76 | #1463225 | ARM64_ERRATUM_1463225 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A76 | #3324349 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A77 | #3324348 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78 | #3324344 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A78C | #3324346,3324347| ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A710 | #3324338 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A715 | #3456084 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A720 | #3456091 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A725 | #3456106 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1 | #3324344 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X1C | #3324346 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X2 | #3324338 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X3 | #3324335 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X4 | #3194386 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-X925 | #3324334 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N1 | #3324349 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N2 | #3324339 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N3 | #3456111 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V1 | #3324341 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V2 | #3324336 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-V3 | #3312417 | ARM64_ERRATUM_3194386 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ @@ -128,6 +174,9 @@ +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | +| | Hip09 SMMU PMCG | | | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ --- linux-oracle-5.4.0.orig/Documentation/arm64/tagged-address-abi.rst +++ linux-oracle-5.4.0/Documentation/arm64/tagged-address-abi.rst @@ -44,8 +44,25 @@ how the user addresses are used by the kernel: 1. User addresses not accessed by the kernel but used for address space - management (e.g. ``mmap()``, ``mprotect()``, ``madvise()``). The use - of valid tagged pointers in this context is always allowed. + management (e.g. ``mprotect()``, ``madvise()``). The use of valid + tagged pointers in this context is allowed with these exceptions: + + - ``brk()``, ``mmap()`` and the ``new_address`` argument to + ``mremap()`` as these have the potential to alias with existing + user addresses. + + NOTE: This behaviour changed in v5.6 and so some earlier kernels may + incorrectly accept valid tagged pointers for the ``brk()``, + ``mmap()`` and ``mremap()`` system calls. + + - The ``range.start``, ``start`` and ``dst`` arguments to the + ``UFFDIO_*`` ``ioctl()``s used on a file descriptor obtained from + ``userfaultfd()``, as fault addresses subsequently obtained by reading + the file descriptor will be untagged, which may otherwise confuse + tag-unaware programs. + + NOTE: This behaviour changed in v5.14 and so some earlier kernels may + incorrectly accept valid tagged pointers for this system call. 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI relaxation is disabled by default and the application thread needs to --- linux-oracle-5.4.0.orig/Documentation/asm-annotations.rst +++ linux-oracle-5.4.0/Documentation/asm-annotations.rst @@ -0,0 +1,216 @@ +Assembler Annotations +===================== + +Copyright (c) 2017-2019 Jiri Slaby + +This document describes the new macros for annotation of data and code in +assembly. In particular, it contains information about ``SYM_FUNC_START``, +``SYM_FUNC_END``, ``SYM_CODE_START``, and similar. + +Rationale +--------- +Some code like entries, trampolines, or boot code needs to be written in +assembly. The same as in C, such code is grouped into functions and +accompanied with data. Standard assemblers do not force users into precisely +marking these pieces as code, data, or even specifying their length. +Nevertheless, assemblers provide developers with such annotations to aid +debuggers throughout assembly. On top of that, developers also want to mark +some functions as *global* in order to be visible outside of their translation +units. + +Over time, the Linux kernel has adopted macros from various projects (like +``binutils``) to facilitate such annotations. So for historic reasons, +developers have been using ``ENTRY``, ``END``, ``ENDPROC``, and other +annotations in assembly. Due to the lack of their documentation, the macros +are used in rather wrong contexts at some locations. Clearly, ``ENTRY`` was +intended to denote the beginning of global symbols (be it data or code). +``END`` used to mark the end of data or end of special functions with +*non-standard* calling convention. In contrast, ``ENDPROC`` should annotate +only ends of *standard* functions. + +When these macros are used correctly, they help assemblers generate a nice +object with both sizes and types set correctly. For example, the result of +``arch/x86/lib/putuser.S``:: + + Num: Value Size Type Bind Vis Ndx Name + 25: 0000000000000000 33 FUNC GLOBAL DEFAULT 1 __put_user_1 + 29: 0000000000000030 37 FUNC GLOBAL DEFAULT 1 __put_user_2 + 32: 0000000000000060 36 FUNC GLOBAL DEFAULT 1 __put_user_4 + 35: 0000000000000090 37 FUNC GLOBAL DEFAULT 1 __put_user_8 + +This is not only important for debugging purposes. When there are properly +annotated objects like this, tools can be run on them to generate more useful +information. In particular, on properly annotated objects, ``objtool`` can be +run to check and fix the object if needed. Currently, ``objtool`` can report +missing frame pointer setup/destruction in functions. It can also +automatically generate annotations for :doc:`ORC unwinder ` +for most code. Both of these are especially important to support reliable +stack traces which are in turn necessary for :doc:`Kernel live patching +`. + +Caveat and Discussion +--------------------- +As one might realize, there were only three macros previously. That is indeed +insufficient to cover all the combinations of cases: + +* standard/non-standard function +* code/data +* global/local symbol + +There was a discussion_ and instead of extending the current ``ENTRY/END*`` +macros, it was decided that brand new macros should be introduced instead:: + + So how about using macro names that actually show the purpose, instead + of importing all the crappy, historic, essentially randomly chosen + debug symbol macro names from the binutils and older kernels? + +.. _discussion: https://lkml.kernel.org/r/20170217104757.28588-1-jslaby@suse.cz + +Macros Description +------------------ + +The new macros are prefixed with the ``SYM_`` prefix and can be divided into +three main groups: + +1. ``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with + standard C calling conventions, i.e. the stack contains a return address at + the predefined place and a return from the function can happen in a + standard way. When frame pointers are enabled, save/restore of frame + pointer shall happen at the start/end of a function, respectively, too. + + Checking tools like ``objtool`` should ensure such marked functions conform + to these rules. The tools can also easily annotate these functions with + debugging information (like *ORC data*) automatically. + +2. ``SYM_CODE_*`` -- special functions called with special stack. Be it + interrupt handlers with special stack content, trampolines, or startup + functions. + + Checking tools mostly ignore checking of these functions. But some debug + information still can be generated automatically. For correct debug data, + this code needs hints like ``UNWIND_HINT_REGS`` provided by developers. + +3. ``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to + ``.text``. Data do not contain instructions, so they have to be treated + specially by the tools: they should not treat the bytes as instructions, + nor assign any debug information to them. + +Instruction Macros +~~~~~~~~~~~~~~~~~~ +This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above. + +* ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the + most frequent markings**. They are used for functions with standard calling + conventions -- global and local. Like in C, they both align the functions to + architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants + for special cases where developers do not want this implicit alignment. + + ``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are + also offered as an assembler counterpart to the *weak* attribute known from + C. + + All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks + the sequence of instructions as a function and computes its size to the + generated object file. Second, it also eases checking and processing such + object files as the tools can trivially find exact function boundaries. + + So in most cases, developers should write something like in the following + example, having some asm instructions in between the macros, of course:: + + SYM_FUNC_START(function_hook) + ... asm insns ... + SYM_FUNC_END(function_hook) + + In fact, this kind of annotation corresponds to the now deprecated ``ENTRY`` + and ``ENDPROC`` macros. + +* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` serve for those + who decided to have two or more names for one function. The typical use is:: + + SYM_FUNC_START_ALIAS(__memset) + SYM_FUNC_START(memset) + ... asm insns ... + SYM_FUNC_END(memset) + SYM_FUNC_END_ALIAS(__memset) + + In this example, one can call ``__memset`` or ``memset`` with the same + result, except the debug information for the instructions is generated to + the object file only once -- for the non-``ALIAS`` case. + +* ``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in + special cases -- if you know what you are doing. This is used exclusively + for interrupt handlers and similar where the calling convention is not the C + one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC`` + category above:: + + SYM_CODE_START_LOCAL(bad_put_user) + ... asm insns ... + SYM_CODE_END(bad_put_user) + + Again, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``. + + To some extent, this category corresponds to deprecated ``ENTRY`` and + ``END``. Except ``END`` had several other meanings too. + +* ``SYM_INNER_LABEL*`` is used to denote a label inside some + ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``. They are very similar + to C labels, except they can be made global. An example of use:: + + SYM_CODE_START(ftrace_caller) + /* save_mcount_regs fills in first two parameters */ + ... + + SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) + /* Load the ftrace_ops into the 3rd parameter */ + ... + + SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) + call ftrace_stub + ... + retq + SYM_CODE_END(ftrace_caller) + +Data Macros +~~~~~~~~~~~ +Similar to instructions, there is a couple of macros to describe data in the +assembly. + +* ``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data + and shall be used in conjunction with either ``SYM_DATA_END``, or + ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that + people can use ``lstack`` and (local) ``lstack_end`` in the following + example:: + + SYM_DATA_START_LOCAL(lstack) + .skip 4096 + SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end) + +* ``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line + data:: + + SYM_DATA(HEAP, .long rm_heap) + SYM_DATA(heap_end, .long rm_stack) + + In the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END`` + internally. + +Support Macros +~~~~~~~~~~~~~~ +All the above reduce themselves to some invocation of ``SYM_START``, +``SYM_END``, or ``SYM_ENTRY`` at last. Normally, developers should avoid using +these. + +Further, in the above examples, one could see ``SYM_L_LOCAL``. There are also +``SYM_L_GLOBAL`` and ``SYM_L_WEAK``. All are intended to denote linkage of a +symbol marked by them. They are used either in ``_LABEL`` variants of the +earlier macros, or in ``SYM_START``. + + +Overriding Macros +~~~~~~~~~~~~~~~~~ +Architecture can also override any of the macros in their own +``asm/linkage.h``, including macros specifying the type of a symbol +(``SYM_T_FUNC``, ``SYM_T_OBJECT``, and ``SYM_T_NONE``). As every macro +described in this file is surrounded by ``#ifdef`` + ``#endif``, it is enough +to define the macros differently in the aforementioned architecture-dependent +header. --- linux-oracle-5.4.0.orig/Documentation/atomic_bitops.txt +++ linux-oracle-5.4.0/Documentation/atomic_bitops.txt @@ -59,7 +59,7 @@ - RMW operations that have a return value are fully ordered. - RMW operations that are conditional are unordered on FAILURE, - otherwise the above rules apply. In the case of test_and_{}_bit() operations, + otherwise the above rules apply. In the case of test_and_set_bit_lock(), if the bit in memory is unchanged by the operation then it is deemed to have failed. --- linux-oracle-5.4.0.orig/Documentation/cgroups/namespace.txt +++ linux-oracle-5.4.0/Documentation/cgroups/namespace.txt @@ -0,0 +1,142 @@ + CGroup Namespaces + +CGroup Namespace provides a mechanism to virtualize the view of the +/proc//cgroup file. The CLONE_NEWCGROUP clone-flag can be used with +clone() and unshare() syscalls to create a new cgroup namespace. +The process running inside the cgroup namespace will have its /proc//cgroup +output restricted to cgroupns-root. cgroupns-root is the cgroup of the process +at the time of creation of the cgroup namespace. + +Prior to CGroup Namespace, the /proc//cgroup file used to show complete +path of the cgroup of a process. In a container setup (where a set of cgroups +and namespaces are intended to isolate processes), the /proc//cgroup file +may leak potential system level information to the isolated processes. + +For Example: + $ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + +The path '/batchjobs/container_id1' can generally be considered as system-data +and its desirable to not expose it to the isolated process. + +CGroup Namespaces can be used to restrict visibility of this path. +For Example: + # Before creating cgroup namespace + $ ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:37 /proc/self/ns/cgroup -> cgroup:[4026531835] + $ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + + # unshare(CLONE_NEWCGROUP) and exec /bin/bash + $ ~/unshare -c + [ns]$ ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:35 /proc/self/ns/cgroup -> cgroup:[4026532183] + # From within new cgroupns, process sees that its in the root cgroup + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/ + + # From global cgroupns: + $ cat /proc//cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1 + + # Unshare cgroupns along with userns and mountns + # Following calls unshare(CLONE_NEWCGROUP|CLONE_NEWUSER|CLONE_NEWNS), then + # sets up uid/gid map and execs /bin/bash + $ ~/unshare -c -u -m + # Originally, we were in /batchjobs/container_id1 cgroup. Mount our own cgroup + # hierarchy. + [ns]$ mount -t cgroup cgroup /tmp/cgroup + [ns]$ ls -l /tmp/cgroup + total 0 + -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.controllers + -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.populated + -rw-r--r-- 1 root root 0 2014-10-13 09:25 cgroup.procs + -rw-r--r-- 1 root root 0 2014-10-13 09:32 cgroup.subtree_control + +The cgroupns-root (/batchjobs/container_id1 in above example) becomes the +filesystem root for the namespace specific cgroupfs mount. + +The virtualization of /proc/self/cgroup file combined with restricting +the view of cgroup hierarchy by namespace-private cgroupfs mount +should provide a completely isolated cgroup view inside the container. + +In its current form, the cgroup namespaces patcheset provides following +behavior: + +(1) The 'cgroupns-root' for a cgroup namespace is the cgroup in which + the process calling unshare is running. + For ex. if a process in /batchjobs/container_id1 cgroup calls unshare, + cgroup /batchjobs/container_id1 becomes the cgroupns-root. + For the init_cgroup_ns, this is the real root ('/') cgroup + (identified in code as cgrp_dfl_root.cgrp). + +(2) The cgroupns-root cgroup does not change even if the namespace + creator process later moves to a different cgroup. + $ ~/unshare -c # unshare cgroupns in some cgroup + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/ + [ns]$ mkdir sub_cgrp_1 + [ns]$ echo 0 > sub_cgrp_1/cgroup.procs + [ns]$ cat /proc/self/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + +(3) Each process gets its CGROUPNS specific view of /proc//cgroup +(a) Processes running inside the cgroup namespace will be able to see + cgroup paths (in /proc/self/cgroup) only inside their root cgroup + [ns]$ sleep 100000 & # From within unshared cgroupns + [1] 7353 + [ns]$ echo 7353 > sub_cgrp_1/cgroup.procs + [ns]$ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + +(b) From global cgroupns, the real cgroup path will be visible: + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1/sub_cgrp_1 + +(c) From a sibling cgroupns (cgroupns root-ed at a different cgroup), cgroup + path relative to its own cgroupns-root will be shown: + # ns2's cgroupns-root is at '/batchjobs/container_id2' + [ns2]$ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2/sub_cgrp_1 + + Note that the relative path always starts with '/' to indicate that its + relative to the cgroupns-root of the caller. + +(4) Processes inside a cgroupns can move in-and-out of the cgroupns-root + (if they have proper access to external cgroups). + # From inside cgroupns (with cgroupns-root at /batchjobs/container_id1), and + # assuming that the global hierarchy is still accessible inside cgroupns: + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1 + $ echo 7353 > batchjobs/container_id2/cgroup.procs + $ cat /proc/7353/cgroup + 0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2 + + Note that this kind of setup is not encouraged. A task inside cgroupns + should only be exposed to its own cgroupns hierarchy. Otherwise it makes + the virtualization of /proc//cgroup less useful. + +(5) Setns to another cgroup namespace is allowed when: + (a) the process has CAP_SYS_ADMIN in its current userns + (b) the process has CAP_SYS_ADMIN in the target cgroupns' userns + No implicit cgroup changes happen with attaching to another cgroupns. It + is expected that the somone moves the attaching process under the target + cgroupns-root. + +(6) When some thread from a multi-threaded process unshares its + cgroup-namespace, the new cgroupns gets applied to the entire process (all + the threads). For the unified-hierarchy this is expected as it only allows + process-level containerization. For the legacy hierarchies this may be + unexpected. So all the threads in the process will have the same cgroup. + +(7) The cgroup namespace is alive as long as there is atleast 1 + process inside it. When the last process exits, the cgroup + namespace is destroyed. The cgroupns-root and the actual cgroups + remain though. + +(8) Namespace specific cgroup hierarchy can be mounted by a process running + inside cgroupns: + $ mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT + + This will mount the unified cgroup hierarchy with cgroupns-root as the + filesystem root. The process needs CAP_SYS_ADMIN in its userns and mntns. --- linux-oracle-5.4.0.orig/Documentation/conf.py +++ linux-oracle-5.4.0/Documentation/conf.py @@ -98,7 +98,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: --- linux-oracle-5.4.0.orig/Documentation/core-api/local_ops.rst +++ linux-oracle-5.4.0/Documentation/core-api/local_ops.rst @@ -191,7 +191,7 @@ static void __exit test_exit(void) { - del_timer_sync(&test_timer); + timer_shutdown_sync(&test_timer); } module_init(test_init); --- linux-oracle-5.4.0.orig/Documentation/core-api/printk-formats.rst +++ linux-oracle-5.4.0/Documentation/core-api/printk-formats.rst @@ -508,6 +508,12 @@ Thanks ====== +Kernel messages: + + %pj 123456 + + For generating the jhash of a string truncated to six digits + If you add other %p extensions, please extend with one or more test cases, if at all feasible. --- linux-oracle-5.4.0.orig/Documentation/core-api/xarray.rst +++ linux-oracle-5.4.0/Documentation/core-api/xarray.rst @@ -461,13 +461,15 @@ Each entry will only be returned once, no matter how many indices it occupies. -Using xas_next() or xas_prev() with a multi-index xa_state -is not supported. Using either of these functions on a multi-index entry -will reveal sibling entries; these should be skipped over by the caller. +Using xas_next() or xas_prev() with a multi-index xa_state is not +supported. Using either of these functions on a multi-index entry will +reveal sibling entries; these should be skipped over by the caller. -Storing ``NULL`` into any index of a multi-index entry will set the entry -at every index to ``NULL`` and dissolve the tie. Splitting a multi-index -entry into entries occupying smaller ranges is not yet supported. +Storing ``NULL`` into any index of a multi-index entry will set the +entry at every index to ``NULL`` and dissolve the tie. A multi-index +entry can be split into entries occupying smaller ranges by calling +xas_split_alloc() without the xa_lock held, followed by taking the lock +and calling xas_split(). Functions and structures ======================== --- linux-oracle-5.4.0.orig/Documentation/dev-tools/gdb-kernel-debugging.rst +++ linux-oracle-5.4.0/Documentation/dev-tools/gdb-kernel-debugging.rst @@ -39,6 +39,10 @@ this mode. In this case, you should build the kernel with CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR. +- Build the gdb scripts (required on kernels v5.1 and above):: + + make scripts_gdb + - Enable the gdb stub of QEMU/KVM, either - at VM startup time by appending "-s" to the QEMU command line --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/Makefile +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/Makefile @@ -12,7 +12,6 @@ $(call if_changed,chk_binding) DT_TMP_SCHEMA := processed-schema.yaml -extra-y += $(DT_TMP_SCHEMA) quiet_cmd_mk_schema = SCHEMA $@ cmd_mk_schema = $(DT_MK_SCHEMA) $(DT_MK_SCHEMA_FLAGS) -o $@ $(real-prereqs) @@ -26,8 +25,12 @@ DT_SCHEMA_FILES ?= $(addprefix $(src)/,$(DT_DOCS)) +ifeq ($(CHECK_DTBS),) extra-y += $(patsubst $(src)/%.yaml,%.example.dts, $(DT_SCHEMA_FILES)) extra-y += $(patsubst $(src)/%.yaml,%.example.dt.yaml, $(DT_SCHEMA_FILES)) +endif $(obj)/$(DT_TMP_SCHEMA): $(DT_SCHEMA_FILES) FORCE $(call if_changed,mk_schema) + +extra-y += $(DT_TMP_SCHEMA) --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/arm/qcom.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/arm/qcom.yaml @@ -112,8 +112,8 @@ - const: qcom,msm8974 - items: - - const: qcom,msm8916-mtp/1 - const: qcom,msm8916-mtp + - const: qcom,msm8916-mtp/1 - const: qcom,msm8916 - items: --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/arm/tegra.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/arm/tegra.yaml @@ -49,7 +49,7 @@ - const: toradex,apalis_t30 - const: nvidia,tegra30 - items: - - const: toradex,apalis_t30-eval-v1.1 + - const: toradex,apalis_t30-v1.1-eval - const: toradex,apalis_t30-eval - const: toradex,apalis_t30-v1.1 - const: toradex,apalis_t30 --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/adi,axi-clkgen.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Binding for Analog Devices AXI clkgen pcore clock generator + +maintainers: + - Lars-Peter Clausen + - Michael Hennerich + +description: | + The axi_clkgen IP core is a software programmable clock generator, + that can be synthesized on various FPGA platforms. + + Link: https://wiki.analog.com/resources/fpga/docs/axi_clkgen + +properties: + compatible: + enum: + - adi,axi-clkgen-2.00.a + + clocks: + description: + Specifies the reference clock(s) from which the output frequency is + derived. This must either reference one clock if only the first clock + input is connected or two if both clock inputs are connected. The last + clock is the AXI bus clock that needs to be enabled so we can access the + core registers. + minItems: 2 + maxItems: 3 + + clock-names: + oneOf: + - items: + - const: clkin1 + - const: s_axi_aclk + - items: + - const: clkin1 + - const: clkin2 + - const: s_axi_aclk + + '#clock-cells': + const: 0 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + clock-controller@ff000000 { + compatible = "adi,axi-clkgen-2.00.a"; + #clock-cells = <0>; + reg = <0xff000000 0x1000>; + clocks = <&osc 1>, <&clkc 15>; + clock-names = "clkin1", "s_axi_aclk"; + }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt @@ -46,7 +46,7 @@ Example (R-Car H3): usb2_clksel: clock-controller@e6590630 { - compatible = "renesas,r8a77950-rcar-usb2-clock-sel", + compatible = "renesas,r8a7795-rcar-usb2-clock-sel", "renesas,rcar-gen3-usb2-clock-sel"; reg = <0 0xe6590630 0 0x02>; clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml @@ -10,6 +10,9 @@ maintainers: - Neil Armstrong +allOf: + - $ref: /schemas/sound/name-prefix.yaml# + description: | The Amlogic Meson Synopsys Designware Integration is composed of - A Synopsys DesignWare HDMI Controller IP @@ -101,6 +104,8 @@ "#sound-dai-cells": const: 0 + sound-name-prefix: true + required: - compatible - reg --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml @@ -78,6 +78,10 @@ interrupts: maxItems: 1 + amlogic,canvas: + description: should point to a canvas provider node + $ref: /schemas/types.yaml#/definitions/phandle + power-domains: maxItems: 1 description: phandle to the associated power domain @@ -106,6 +110,7 @@ - port@1 - "#address-cells" - "#size-cells" + - amlogic,canvas examples: - | @@ -116,6 +121,7 @@ interrupts = <3>; #address-cells = <1>; #size-cells = <0>; + amlogic,canvas = <&canvas>; /* CVBS VDAC output port */ port@0 { --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.txt @@ -16,6 +16,9 @@ Documentation/devicetree/bindings/graph.txt. This port should be connected to the input port of an attached HDMI or LVDS encoder chip. +Optional properties: +- pinctrl-names: Contain "default" and "sleep". + Example: dpi0: dpi@1401d000 { @@ -26,6 +29,9 @@ <&mmsys CLK_MM_DPI_ENGINE>, <&apmixedsys CLK_APMIXED_TVDPLL>; clock-names = "pixel", "engine", "pll"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&dpi_pin_func>; + pinctrl-1 = <&dpi_pin_idle>; port { dpi0_out: endpoint { --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml @@ -58,7 +58,7 @@ then: properties: clocks: - maxItems: 2 + minItems: 2 required: - clock-names --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/dma/moxa,moxart-dma.txt @@ -34,8 +34,8 @@ Use specific request line passing from dma For example, MMC request line is 5 - sdhci: sdhci@98e00000 { - compatible = "moxa,moxart-sdhci"; + mmc: mmc@98e00000 { + compatible = "moxa,moxart-mmc"; reg = <0x98e00000 0x5C>; interrupts = <5 0>; clocks = <&clk_apb>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/gpio/gpio-altera.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/gpio/gpio-altera.txt @@ -9,8 +9,9 @@ - The second cell is reserved and is currently unused. - gpio-controller : Marks the device node as a GPIO controller. - interrupt-controller: Mark the device node as an interrupt controller -- #interrupt-cells : Should be 1. The interrupt type is fixed in the hardware. +- #interrupt-cells : Should be 2. The interrupt type is fixed in the hardware. - The first cell is the GPIO offset number within the GPIO controller. + - The second cell is the interrupt trigger type and level flags. - interrupts: Specify the interrupt. - altr,interrupt-type: Specifies the interrupt trigger type the GPIO hardware is synthesized. This field is required if the Altera GPIO controller @@ -38,6 +39,6 @@ altr,interrupt-type = ; #gpio-cells = <2>; gpio-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; interrupt-controller; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt @@ -20,8 +20,9 @@ - gpio-controller : Marks the device node as a GPIO controller - interrupts : Interrupt specifier, see interrupt-controller/interrupts.txt - interrupt-controller : Mark the GPIO controller as an interrupt-controller -- ngpios : number of GPIO lines, see gpio.txt - (should be multiple of 8, up to 80 pins) +- ngpios : number of *hardware* GPIO lines, see gpio.txt. This will expose + 2 software GPIOs per hardware GPIO: one for hardware input, one for hardware + output. Up to 80 pins, must be a multiple of 8. - clocks : A phandle to the APB clock for SGPM clock division - bus-frequency : SGPM CLK frequency --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/gpu/samsung-rotator.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/gpu/samsung-rotator.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpu/samsung-rotator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung SoC Image Rotator + +maintainers: + - Inki Dae + +properties: + compatible: + enum: + - "samsung,s5pv210-rotator" + - "samsung,exynos4210-rotator" + - "samsung,exynos4212-rotator" + - "samsung,exynos5250-rotator" + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: rotator + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +examples: + - | + rotator@12810000 { + compatible = "samsung,exynos4210-rotator"; + reg = <0x12810000 0x1000>; + interrupts = <0 83 0>; + clocks = <&clock 278>; + clock-names = "rotator"; + }; + --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml @@ -85,7 +85,7 @@ Must be the device tree identifier of the over-sampling mode pins. As the line is active high, it should be marked GPIO_ACTIVE_HIGH. - maxItems: 1 + maxItems: 3 adi,sw-mode: description: @@ -128,9 +128,9 @@ adi,conversion-start-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio 27 GPIO_ACTIVE_HIGH>; adi,first-data-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>; - adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH - &gpio 23 GPIO_ACTIVE_HIGH - &gpio 26 GPIO_ACTIVE_HIGH>; + adi,oversampling-ratio-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>, + <&gpio 23 GPIO_ACTIVE_HIGH>, + <&gpio 26 GPIO_ACTIVE_HIGH>; standby-gpios = <&gpio 24 GPIO_ACTIVE_LOW>; adi,sw-mode; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/iio/multiplexer/io-channel-mux.txt @@ -21,7 +21,7 @@ Example: mux: mux-controller { - compatible = "mux-gpio"; + compatible = "gpio-mux"; #mux-control-cells = <0>; mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>, --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt @@ -55,7 +55,7 @@ corresponds to a range of host irqs. For more details on TISCI IRQ resource management refer: -http://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html +https://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html Example: -------- --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.txt @@ -87,7 +87,7 @@ ranges; /* APU<->RPU0 IPI mailbox controller */ - ipi_mailbox_rpu0: mailbox@ff90400 { + ipi_mailbox_rpu0: mailbox@ff990400 { reg = <0xff990400 0x20>, <0xff990420 0x20>, <0xff990080 0x20>, --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mfd/ahc1ec0.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mfd/ahc1ec0.yaml @@ -0,0 +1,69 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ahc1ec0.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Advantech Embedded Controller (AHC1EC0) + +maintainers: + - Campion Kang + +description: | + AHC1EC0 is one of the embedded controllers used by Advantech to provide several + functions such as watchdog, hwmon, brightness, etc. Advantech related applications + can control the whole system via these functions. + +properties: + compatible: + const: advantech,ahc1ec0 + + advantech,sub-dev-nb: + description: + The number of sub-devices specified in the platform. + $ref: /schemas/types.yaml#/definitions/uint32 + maxItems: 1 + + advantech,sub-dev: + description: + A list of the sub-devices supported in the platform. Defines for the + appropriate values can found in dt-bindings/mfd/ahc1ec0-dt.h. + $ref: "/schemas/types.yaml#/definitions/uint32-array" + minItems: 1 + maxItems: 6 + + advantech,hwmon-profile: + description: + The number of sub-devices specified in the platform. Defines for the + hwmon profiles can found in dt-bindings/mfd/ahc1ec0-dt. + $ref: /schemas/types.yaml#/definitions/uint32 + maxItems: 1 + +required: + - compatible + - advantech,sub-dev-nb + - advantech,sub-dev + +if: + properties: + advantech,sub-dev: + contains: + const: 0x3 +then: + required: + - advantech,hwmon-profile + +additionalProperties: false + +examples: + - | + #include + ahc1ec0 { + compatible = "advantech,ahc1ec0"; + + advantech,sub-dev-nb = <2>; + advantech,sub-dev = ; + + advantech,hwmon-profile = ; + }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mmc/mmc-controller.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mmc/mmc-controller.yaml @@ -21,7 +21,7 @@ "#address-cells": const: 1 description: | - The cell is the slot ID if a function subnode is used. + The cell is the SDIO function number if a function subnode is used. "#size-cells": const: 0 --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mmc/mtk-sd.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mmc/mtk-sd.txt @@ -49,6 +49,8 @@ error caused by stop clock(fifo full) Valid range = [0:0x7]. if not present, default value is 0. applied to compatible "mediatek,mt2701-mmc". +- resets: Phandle and reset specifier pair to softreset line of MSDC IP. +- reset-names: Should be "hrst". Examples: mmc0: mmc@11230000 { --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt @@ -15,8 +15,15 @@ - "nvidia,tegra210-sdhci": for Tegra210 - "nvidia,tegra186-sdhci": for Tegra186 - "nvidia,tegra194-sdhci": for Tegra194 -- clocks : Must contain one entry, for the module clock. - See ../clocks/clock-bindings.txt for details. +- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries. + One for the module clock and one for the timeout clock. + For all other Tegra devices, must contain a single entry for + the module clock. See ../clocks/clock-bindings.txt for details. +- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the + strings 'sdhci' and 'tmclk' to represent the module and + the timeout clocks, respectively. + For all other Tegra devices must contain the string 'sdhci' + to represent the module clock. - resets : Must contain an entry for each entry in reset-names. See ../reset/reset.txt for details. - reset-names : Must include the following entries: @@ -99,7 +106,7 @@ Example: sdhci@700b0000 { - compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; + compatible = "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0000 0x0 0x200>; interrupts = ; clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; @@ -107,6 +114,25 @@ resets = <&tegra_car 14>; reset-names = "sdhci"; pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; + pinctrl-0 = <&sdmmc1_3v3>; + pinctrl-1 = <&sdmmc1_1v8>; + nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>; + nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>; + nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>; + nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>; + status = "disabled"; +}; + +sdhci@700b0000 { + compatible = "nvidia,tegra210-sdhci"; + reg = <0x0 0x700b0000 0x0 0x200>; + interrupts = ; + clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; + clock-names = "sdhci", "tmclk"; + resets = <&tegra_car 14>; + reset-names = "sdhci"; + pinctrl-names = "sdmmc-3v3", "sdmmc-1v8"; pinctrl-0 = <&sdmmc1_3v3>; pinctrl-1 = <&sdmmc1_1v8>; nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -122,7 +122,7 @@ so the device should have enough free bytes available its OOB/Spare area to accommodate ECC for entire page. In general following expression helps in determining if given device can accommodate ECC syndrome: - "2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE" + "2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE" where OOBSIZE number of bytes in OOB/spare area PAGESIZE number of bytes in main-area of device page --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/mtd/nand-controller.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/mtd/nand-controller.yaml @@ -44,7 +44,7 @@ properties: reg: description: - Contains the native Ready/Busy IDs. + Contains the chip-select IDs. nand-ecc-mode: allOf: @@ -139,6 +139,6 @@ nand-ecc-mode = "soft"; nand-ecc-algo = "bch"; - /* controller specific properties */ + /* NAND chip specific properties */ }; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/btusb.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/btusb.txt @@ -38,7 +38,7 @@ compatible = "usb1286,204e"; reg = <1>; interrupt-parent = <&gpio0>; - interrupt-name = "wakeup"; + interrupt-names = "wakeup"; interrupts = <3 IRQ_TYPE_LEVEL_LOW>; }; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/can/tcan4x5x.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/can/tcan4x5x.txt @@ -31,9 +31,9 @@ #address-cells = <1>; #size-cells = <1>; spi-max-frequency = <10000000>; - bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; + bosch,mram-cfg = <0x0 0 0 16 0 0 1 1>; interrupt-parent = <&gpio1>; - interrupts = <14 GPIO_ACTIVE_LOW>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; device-state-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; device-wake-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/ethernet-controller.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/ethernet-controller.yaml @@ -51,7 +51,7 @@ description: Reference to an nvmem node for the MAC address - nvmem-cells-names: + nvmem-cell-names: const: mac-address phy-connection-type: @@ -190,6 +190,11 @@ Indicates that full-duplex is used. When absent, half duplex is assumed. + pause: + $ref: /schemas/types.yaml#definitions/flag + description: + Indicates that pause should be enabled. + asym-pause: $ref: /schemas/types.yaml#definitions/flag description: --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/ethernet-phy.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/ethernet-phy.yaml @@ -87,6 +87,14 @@ compensate for the board being designed with the lanes swapped. + enet-phy-lane-no-swap: + $ref: /schemas/types.yaml#/definitions/flag + description: + If set, indicates that PHY will disable swap of the + TX/RX lanes. This property allows the PHY to work correcly after + e.g. wrong bootstrap configuration caused by issues in PCB + layout design. + eee-broken-100tx: $ref: /schemas/types.yaml#definitions/flag description: --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/fsl-fman.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/fsl-fman.txt @@ -110,6 +110,13 @@ Usage: required Definition: See soc/fsl/qman.txt and soc/fsl/bman.txt +- fsl,erratum-a050385 + Usage: optional + Value type: boolean + Definition: A boolean property. Indicates the presence of the + erratum A050385 which indicates that DMA transactions that are + split can result in a FMan lock. + ============================================================================= FMan MURAM Node --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt @@ -25,7 +25,7 @@ clock-frequency = <100000>; interrupt-parent = <&gpio1>; - interrupts = <29 GPIO_ACTIVE_HIGH>; + interrupts = <29 IRQ_TYPE_LEVEL_HIGH>; enable-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; firmware-gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/nfc/pn544.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/nfc/pn544.txt @@ -25,7 +25,7 @@ clock-frequency = <400000>; interrupt-parent = <&gpio1>; - interrupts = <17 GPIO_ACTIVE_HIGH>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; enable-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; firmware-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -347,6 +347,7 @@ - st,spear600-gmac then: + properties: snps,tso: $ref: /schemas/types.yaml#definitions/flag description: --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt @@ -81,6 +81,12 @@ Definition: Name of external front end module used. Some valid FEM names for example: "microsemi-lx5586", "sky85703-11" and "sky85803" etc. +- qcom,snoc-host-cap-8bit-quirk: + Usage: Optional + Value type: + Definition: Quirk specifying that the firmware expects the 8bit version + of the host capability QMI request + Example (to supply PCI based wifi block details): --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/pci/nvidia,tegra194-pcie.txt @@ -118,7 +118,7 @@ -------- pcie@14180000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */ --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/perf/arm,cmn.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/perf/arm,cmn.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2020 Arm Ltd. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/perf/arm,cmn.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Arm CMN (Coherent Mesh Network) Performance Monitors + +maintainers: + - Robin Murphy + +properties: + compatible: + const: arm,cmn-600 + + reg: + items: + - description: Physical address of the base (PERIPHBASE) and + size (up to 64MB) of the configuration address space. + + interrupts: + minItems: 1 + maxItems: 4 + items: + - description: Overflow interrupt for DTC0 + - description: Overflow interrupt for DTC1 + - description: Overflow interrupt for DTC2 + - description: Overflow interrupt for DTC3 + description: One interrupt for each DTC domain implemented must + be specified, in order. DTC0 is always present. + + arm,root-node: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Offset from PERIPHBASE of the configuration + discovery node (see TRM definition of ROOTNODEBASE). + +required: + - compatible + - reg + - interrupts + - arm,root-node + +additionalProperties: false + +examples: + - | + #include + #include + pmu@50000000 { + compatible = "arm,cmn-600"; + reg = <0x50000000 0x4000000>; + /* 4x2 mesh with one DTC, and CFG node at 0,1,1,0 */ + interrupts = ; + arm,root-node = <0x104000>; + }; +... --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2019 BayLibre, SAS +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb3-pcie-phy.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Amlogic G12A USB3 + PCIE Combo PHY + +maintainers: + - Neil Armstrong + +properties: + compatible: + enum: + - amlogic,g12a-usb3-pcie-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: ref_clk + + resets: + maxItems: 1 + + reset-names: + items: + - const: phy + + "#phy-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - "#phy-cells" + +examples: + - | + phy@46000 { + compatible = "amlogic,g12a-usb3-pcie-phy"; + reg = <0x46000 0x2000>; + clocks = <&ref_clk>; + clock-names = "ref_clk"; + resets = <&phy_reset>; + reset-names = "phy"; + #phy-cells = <1>; + }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt @@ -43,19 +43,19 @@ group pwm0 - pin 11 (GPIO1-11) - - functions pwm, gpio + - functions pwm, led, gpio group pwm1 - pin 12 - - functions pwm, gpio + - functions pwm, led, gpio group pwm2 - pin 13 - - functions pwm, gpio + - functions pwm, led, gpio group pwm3 - pin 14 - - functions pwm, gpio + - functions pwm, led, gpio group pmic1 - pin 7 --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/regulator/samsung,s5m8767.txt @@ -13,6 +13,14 @@ Required properties of the main device node (the parent!): + - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used + for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. + + [1] If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional + property is specified, then all the eight voltage values for the + 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. + +Optional properties of the main device node (the parent!): - s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV) units for buck2 when changing voltage using gpio dvs. Refer to [1] below for additional information. @@ -25,26 +33,13 @@ units for buck4 when changing voltage using gpio dvs. Refer to [1] below for additional information. - - s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used - for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines. - - [1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage' - property should specify atleast one voltage level (which would be a - safe operating voltage). - - If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional - property is specified, then all the eight voltage values for the - 's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified. - -Optional properties of the main device node (the parent!): - s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs. - s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs. - s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs. Additional properties required if either of the optional properties are used: - - s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from + - s5m8767,pmic-buck-default-dvs-idx: Default voltage setting selected from the possible 8 options selectable by the dvs gpios. The value of this property should be between 0 and 7. If not specified or if out of range, the default value of this property is set to 0. --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/reset/brcm,brcmstb-reset.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/reset/brcm,brcmstb-reset.txt @@ -22,6 +22,6 @@ }; ðernet_switch { - resets = <&reset>; + resets = <&reset 26>; reset-names = "switch"; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/rng/omap3_rom_rng.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/rng/omap3_rom_rng.txt @@ -0,0 +1,27 @@ +OMAP ROM RNG driver binding + +Secure SoCs may provide RNG via secure ROM calls like Nokia N900 does. The +implementation can depend on the SoC secure ROM used. + +- compatible: + Usage: required + Value type: + Definition: must be "nokia,n900-rom-rng" + +- clocks: + Usage: required + Value type: + Definition: reference to the the RNG interface clock + +- clock-names: + Usage: required + Value type: + Definition: must be "ick" + +Example: + + rom_rng: rng { + compatible = "nokia,n900-rom-rng"; + clocks = <&rng_ick>; + clock-names = "ick"; + }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml @@ -128,7 +128,6 @@ - compatible - reg - interrupts - - clocks - clock-output-names additionalProperties: false --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt @@ -2,9 +2,11 @@ Required properties: - compatible : "mediatek,mt8183_mt6358_ts3a227_max98357" -- mediatek,headset-codec: the phandles of ts3a227 codecs - mediatek,platform: the phandle of MT8183 ASoC platform +Optional properties: +- mediatek,headset-codec: the phandles of ts3a227 codecs + Example: sound { --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/sound/qcom,wcd9335.txt @@ -109,7 +109,7 @@ reg = <1 0>; interrupts = <&msmgpio 54 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "intr2" - reset-gpios = <&msmgpio 64 0>; + reset-gpios = <&msmgpio 64 GPIO_ACTIVE_LOW>; slim-ifc-dev = <&wc9335_ifd>; clock-names = "mclk", "native"; clocks = <&rpmcc RPM_SMD_DIV_CLK1>, --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/sound/rt5645.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/sound/rt5645.txt @@ -16,6 +16,11 @@ a GPIO spec for the external headphone detect pin. If jd-mode = 0, we will get the JD status by getting the value of hp-detect-gpios. +- cbj-sleeve-gpios: + a GPIO spec to control the external combo jack circuit to tie the sleeve/ring2 + contacts to the ground or floating. It could avoid some electric noise from the + active speaker jacks. + - realtek,in2-differential Boolean. Indicate MIC2 input are differential, rather than single-ended. @@ -64,6 +69,7 @@ compatible = "realtek,rt5650"; reg = <0x1a>; hp-detect-gpios = <&gpio 19 0>; + cbj-sleeve-gpios = <&gpio 20 0>; interrupt-parent = <&gpio>; interrupts = <7 IRQ_TYPE_EDGE_FALLING>; realtek,dmic-en = "true"; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/sound/wm8994.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/sound/wm8994.txt @@ -14,9 +14,15 @@ - #gpio-cells : Must be 2. The first cell is the pin number and the second cell is used to specify optional parameters (currently unused). - - AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply, - SPKVDD1-supply, SPKVDD2-supply : power supplies for the device, as covered - in Documentation/devicetree/bindings/regulator/regulator.txt + - power supplies for the device, as covered in + Documentation/devicetree/bindings/regulator/regulator.txt, depending + on compatible: + - for wlf,wm1811 and wlf,wm8958: + AVDD1-supply, AVDD2-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, + DCVDD-supply, CPVDD-supply, SPKVDD1-supply, SPKVDD2-supply + - for wlf,wm8994: + AVDD1-supply, AVDD2-supply, DBVDD-supply, DCVDD-supply, CPVDD-supply, + SPKVDD1-supply, SPKVDD2-supply Optional properties: @@ -73,11 +79,11 @@ lineout1-se; + AVDD1-supply = <®ulator>; AVDD2-supply = <®ulator>; CPVDD-supply = <®ulator>; - DBVDD1-supply = <®ulator>; - DBVDD2-supply = <®ulator>; - DBVDD3-supply = <®ulator>; + DBVDD-supply = <®ulator>; + DCVDD-supply = <®ulator>; SPKVDD1-supply = <®ulator>; SPKVDD2-supply = <®ulator>; }; --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/spi/spi-mxic.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/spi/spi-mxic.txt @@ -8,11 +8,13 @@ - reg: should contain 2 entries, one for the registers and one for the direct mapping area - reg-names: should contain "regs" and "dirmap" -- interrupts: interrupt line connected to the SPI controller - clock-names: should contain "ps_clk", "send_clk" and "send_dly_clk" - clocks: should contain 3 entries for the "ps_clk", "send_clk" and "send_dly_clk" clocks +Optional properties: +- interrupts: interrupt line connected to the SPI controller + Example: spi@43c30000 { --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/usb/dwc3.txt +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/usb/dwc3.txt @@ -75,6 +75,8 @@ from P0 to P1/P2/P3 without delay. - snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check during HS transmit. + - snps,parkmode-disable-ss-quirk: when set, all SuperSpeed bus instances in + park mode are disabled. - snps,dis_metastability_quirk: when set, disable metastability workaround. CAUTION: use only if you are absolutely sure of it. - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal --- linux-oracle-5.4.0.orig/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ linux-oracle-5.4.0/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -633,6 +633,8 @@ description: National Semiconductor "^nec,.*": description: NEC LCD Technologies, Ltd. + "^neofidelity,.*": + description: Neofidelity Inc. "^neonode,.*": description: Neonode Inc. "^netgear,.*": --- linux-oracle-5.4.0.orig/Documentation/devicetree/writing-schema.rst +++ linux-oracle-5.4.0/Documentation/devicetree/writing-schema.rst @@ -130,11 +130,13 @@ make dt_binding_check -In order to perform validation of DT source files, use the `dtbs_check` target:: +In order to perform validation of DT source files, use the ``dtbs_check`` target:: make dtbs_check -This will first run the `dt_binding_check` which generates the processed schema. +Note that ``dtbs_check`` will skip any binding schema files with errors. It is +necessary to use ``dt_binding_check`` to get all the validation errors in the +binding schema files. It is also possible to run checks with a single schema file by setting the ``DT_SCHEMA_FILES`` variable to a specific schema file. --- linux-oracle-5.4.0.orig/Documentation/driver-api/dmaengine/dmatest.rst +++ linux-oracle-5.4.0/Documentation/driver-api/dmaengine/dmatest.rst @@ -143,13 +143,14 @@ Allocating Channels ------------------- -Channels are required to be configured prior to starting the test run. -Attempting to run the test without configuring the channels will fail. +Channels do not need to be configured prior to starting a test run. Attempting +to run the test without configuring the channels will result in testing any +channels that are available. Example:: % echo 1 > /sys/module/dmatest/parameters/run - dmatest: Could not start test, no channels configured + dmatest: No channels configured, continue with any Channels are registered using the "channel" parameter. Channels can be requested by their name, once requested, the channel is registered and a pending thread is added to the test list. --- linux-oracle-5.4.0.orig/Documentation/driver-api/firewire.rst +++ linux-oracle-5.4.0/Documentation/driver-api/firewire.rst @@ -19,7 +19,7 @@ Firewire char device data structures ==================================== -.. include:: /ABI/stable/firewire-cdev +.. include:: ../ABI/stable/firewire-cdev :literal: .. kernel-doc:: include/uapi/linux/firewire-cdev.h @@ -28,7 +28,7 @@ Firewire device probing and sysfs interfaces ============================================ -.. include:: /ABI/stable/sysfs-bus-firewire +.. include:: ../ABI/stable/sysfs-bus-firewire :literal: .. kernel-doc:: drivers/firewire/core-device.c --- linux-oracle-5.4.0.orig/Documentation/driver-api/libata.rst +++ linux-oracle-5.4.0/Documentation/driver-api/libata.rst @@ -250,7 +250,7 @@ :: - void (*qc_prep) (struct ata_queued_cmd *qc); + enum ata_completion_errors (*qc_prep) (struct ata_queued_cmd *qc); int (*qc_issue) (struct ata_queued_cmd *qc); --- linux-oracle-5.4.0.orig/Documentation/driver-api/spi.rst +++ linux-oracle-5.4.0/Documentation/driver-api/spi.rst @@ -25,8 +25,8 @@ a pair of FIFOs connected to dual DMA engines on the other side of the SPI shift register (maximizing throughput). Such drivers bridge between whatever bus they sit on (often the platform bus) and SPI, and expose -the SPI side of their device as a :c:type:`struct spi_master -`. SPI devices are children of that master, +the SPI side of their device as a :c:type:`struct spi_controller +`. SPI devices are children of that master, represented as a :c:type:`struct spi_device ` and manufactured from :c:type:`struct spi_board_info ` descriptors which are usually provided by --- linux-oracle-5.4.0.orig/Documentation/fault-injection/fault-injection.rst +++ linux-oracle-5.4.0/Documentation/fault-injection/fault-injection.rst @@ -74,8 +74,8 @@ - /sys/kernel/debug/fail*/times: - specifies how many times failures may happen at most. - A value of -1 means "no limit". + specifies how many times failures may happen at most. A value of -1 + means "no limit". - /sys/kernel/debug/fail*/space: @@ -163,11 +163,13 @@ - ERRNO: retval must be -1 to -MAX_ERRNO (-4096). - ERR_NULL: retval must be 0 or -1 to -MAX_ERRNO (-4096). -- /sys/kernel/debug/fail_function//retval: +- /sys/kernel/debug/fail_function//retval: - specifies the "error" return value to inject to the given - function for given function. This will be created when - user specifies new injection entry. + specifies the "error" return value to inject to the given function. + This will be created when the user specifies a new injection entry. + Note that this file only accepts unsigned values. So, if you want to + use a negative errno, you better use 'printf' instead of 'echo', e.g.: + $ printf %#x -12 > retval Boot option ^^^^^^^^^^^ @@ -331,7 +333,7 @@ FAILTYPE=fail_function FAILFUNC=open_ctree echo $FAILFUNC > /sys/kernel/debug/$FAILTYPE/inject - echo -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval + printf %#x -12 > /sys/kernel/debug/$FAILTYPE/$FAILFUNC/retval echo N > /sys/kernel/debug/$FAILTYPE/task-filter echo 100 > /sys/kernel/debug/$FAILTYPE/probability echo 0 > /sys/kernel/debug/$FAILTYPE/interval --- linux-oracle-5.4.0.orig/Documentation/fb/fbcon.rst +++ linux-oracle-5.4.0/Documentation/fb/fbcon.rst @@ -127,7 +127,7 @@ is typically located on the same video card. Thus, the consoles that are controlled by the VGA console will be garbled. -4. fbcon=rotate: +5. fbcon=rotate: This option changes the orientation angle of the console display. The value 'n' accepts the following: @@ -152,21 +152,21 @@ Actually, the underlying fb driver is totally ignorant of console rotation. -5. fbcon=margin: +6. fbcon=margin: This option specifies the color of the margins. The margins are the leftover area at the right and the bottom of the screen that are not used by text. By default, this area will be black. The 'color' value is an integer number that depends on the framebuffer driver being used. -6. fbcon=nodefer +7. fbcon=nodefer If the kernel is compiled with deferred fbcon takeover support, normally the framebuffer contents, left in place by the firmware/bootloader, will be preserved until there actually is some text is output to the console. This option causes fbcon to bind immediately to the fbdev device. -7. fbcon=logo-pos: +8. fbcon=logo-pos: The only possible 'location' is 'center' (without quotes), and when given, the bootup logo is moved from the default top-left corner --- linux-oracle-5.4.0.orig/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt +++ linux-oracle-5.4.0/Documentation/features/debug/kprobes-on-ftrace/arch-support.txt @@ -24,7 +24,7 @@ | parisc: | ok | | powerpc: | ok | | riscv: | TODO | - | s390: | TODO | + | s390: | ok | | sh: | TODO | | sparc: | TODO | | um: | TODO | --- linux-oracle-5.4.0.orig/Documentation/filesystems/affs.txt +++ linux-oracle-5.4.0/Documentation/filesystems/affs.txt @@ -93,13 +93,15 @@ - R maps to r for user, group and others. On directories, R implies x. - - If both W and D are allowed, w will be set. + - W maps to w. - E maps to x. - - H and P are always retained and ignored under Linux. + - D is ignored. - - A is always reset when a file is written to. + - H, S and P are always retained and ignored under Linux. + + - A is cleared when a file is written to. User id and group id will be used unless set[gu]id are given as mount options. Since most of the Amiga file systems are single user systems @@ -111,11 +113,13 @@ The Linux rwxrwxrwx file mode is handled as follows: - - r permission will set R for user, group and others. + - r permission will allow R for user, group and others. + + - w permission will allow W for user, group and others. - - w permission will set W and D for user, group and others. + - x permission of the user will allow E for plain files. - - x permission of the user will set E for plain files. + - D will be allowed for user, group and others. - All other flags (suid, sgid, ...) are ignored and will not be retained. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/README +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/README @@ -0,0 +1,401 @@ + +Aufs5 -- advanced multi layered unification filesystem version 5.x +http://aufs.sf.net +Junjiro R. Okajima + + +0. Introduction +---------------------------------------- +In the early days, aufs was entirely re-designed and re-implemented +Unionfs Version 1.x series. Adding many original ideas, approaches, +improvements and implementations, it became totally different from +Unionfs while keeping the basic features. +Later, Unionfs Version 2.x series began taking some of the same +approaches to aufs1's. +Unionfs was being developed by Professor Erez Zadok at Stony Brook +University and his team. + +Aufs5 supports linux-v5.0 and later, If you want older kernel version +support, +- for linux-v4.x series, try aufs4-linux.git or aufs4-standalone.git +- for linux-v3.x series, try aufs3-linux.git or aufs3-standalone.git +- for linux-v2.6.16 and later, try aufs2-2.6.git, aufs2-standalone.git + or aufs1 from CVS on SourceForge. + +Note: it becomes clear that "Aufs was rejected. Let's give it up." + According to Christoph Hellwig, linux rejects all union-type + filesystems but UnionMount. + + +PS. Al Viro seems have a plan to merge aufs as well as overlayfs and + UnionMount, and he pointed out an issue around a directory mutex + lock and aufs addressed it. But it is still unsure whether aufs will + be merged (or any other union solution). + + + +1. Features +---------------------------------------- +- unite several directories into a single virtual filesystem. The member + directory is called as a branch. +- you can specify the permission flags to the branch, which are 'readonly', + 'readwrite' and 'whiteout-able.' +- by upper writable branch, internal copyup and whiteout, files/dirs on + readonly branch are modifiable logically. +- dynamic branch manipulation, add, del. +- etc... + +Also there are many enhancements in aufs, such as: +- test only the highest one for the directory permission (dirperm1) +- copyup on open (coo=) +- 'move' policy for copy-up between two writable branches, after + checking free space. +- xattr, acl +- readdir(3) in userspace. +- keep inode number by external inode number table +- keep the timestamps of file/dir in internal copyup operation +- seekable directory, supporting NFS readdir. +- whiteout is hardlinked in order to reduce the consumption of inodes + on branch +- do not copyup, nor create a whiteout when it is unnecessary +- revert a single systemcall when an error occurs in aufs +- remount interface instead of ioctl +- maintain /etc/mtab by an external command, /sbin/mount.aufs. +- loopback mounted filesystem as a branch +- kernel thread for removing the dir who has a plenty of whiteouts +- support copyup sparse file (a file which has a 'hole' in it) +- default permission flags for branches +- selectable permission flags for ro branch, whether whiteout can + exist or not +- export via NFS. +- support /fs/aufs and /aufs. +- support multiple writable branches, some policies to select one + among multiple writable branches. +- a new semantics for link(2) and rename(2) to support multiple + writable branches. +- no glibc changes are required. +- pseudo hardlink (hardlink over branches) +- allow a direct access manually to a file on branch, e.g. bypassing aufs. + including NFS or remote filesystem branch. +- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. +- and more... + +Currently these features are dropped temporary from aufs5. +See design/08plan.txt in detail. +- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs + (robr) +- statistics of aufs thread (/sys/fs/aufs/stat) + +Features or just an idea in the future (see also design/*.txt), +- reorder the branch index without del/re-add. +- permanent xino files for NFSD +- an option for refreshing the opened files after add/del branches +- light version, without branch manipulation. (unnecessary?) +- copyup in userspace +- inotify in userspace +- readv/writev + + +2. Download +---------------------------------------- +There are three GIT trees for aufs5, aufs5-linux.git, +aufs5-standalone.git, and aufs-util.git. Note that there is no "5" in +"aufs-util.git." +While the aufs-util is always necessary, you need either of aufs5-linux +or aufs5-standalone. + +The aufs5-linux tree includes the whole linux mainline GIT tree, +git://git.kernel.org/.../torvalds/linux.git. +And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot +build aufs5 as an external kernel module. +Several extra patches are not included in this tree. Only +aufs5-standalone tree contains them. They are described in the later +section "Configuration and Compilation." + +On the other hand, the aufs5-standalone tree has only aufs source files +and necessary patches, and you can select CONFIG_AUFS_FS=m. +But you need to apply all aufs patches manually. + +You will find GIT branches whose name is in form of "aufs5.x" where "x" +represents the linux kernel version, "linux-5.x". For instance, +"aufs5.0" is for linux-5.0. For latest "linux-5.x-rcN", use +"aufs5.x-rcN" branch. + +o aufs5-linux tree +$ git clone --reference /your/linux/git/tree \ + git://github.com/sfjro/aufs5-linux.git aufs5-linux.git +- if you don't have linux GIT tree, then remove "--reference ..." +$ cd aufs5-linux.git +$ git checkout origin/aufs5.0 + +Or You may want to directly git-pull aufs into your linux GIT tree, and +leave the patch-work to GIT. +$ cd /your/linux/git/tree +$ git remote add aufs5 git://github.com/sfjro/aufs5-linux.git +$ git fetch aufs5 +$ git checkout -b my5.0 v5.0 +$ (add your local change...) +$ git pull aufs5 aufs5.0 +- now you have v5.0 + your_changes + aufs5.0 in you my5.0 branch. +- you may need to solve some conflicts between your_changes and + aufs5.0. in this case, git-rerere is recommended so that you can + solve the similar conflicts automatically when you upgrade to 5.1 or + later in the future. + +o aufs5-standalone tree +$ git clone git://github.com/sfjro/aufs5-standalone.git aufs5-standalone.git +$ cd aufs5-standalone.git +$ git checkout origin/aufs5.0 + +o aufs-util tree +$ git clone git://git.code.sf.net/p/aufs/aufs-util aufs-util.git +- note that the public aufs-util.git is on SourceForge instead of + GitHUB. +$ cd aufs-util.git +$ git checkout origin/aufs5.0 + +Note: The 5.x-rcN branch is to be used with `rc' kernel versions ONLY. +The minor version number, 'x' in '5.x', of aufs may not always +follow the minor version number of the kernel. +Because changes in the kernel that cause the use of a new +minor version number do not always require changes to aufs-util. + +Since aufs-util has its own minor version number, you may not be +able to find a GIT branch in aufs-util for your kernel's +exact minor version number. +In this case, you should git-checkout the branch for the +nearest lower number. + +For (an unreleased) example: +If you are using "linux-5.10" and the "aufs5.10" branch +does not exist in aufs-util repository, then "aufs5.9", "aufs5.8" +or something numerically smaller is the branch for your kernel. + +Also you can view all branches by + $ git branch -a + + +3. Configuration and Compilation +---------------------------------------- +Make sure you have git-checkout'ed the correct branch. + +For aufs5-linux tree, +- enable CONFIG_AUFS_FS. +- set other aufs configurations if necessary. + +For aufs5-standalone tree, +There are several ways to build. + +1. +- apply ./aufs5-kbuild.patch to your kernel source files. +- apply ./aufs5-base.patch too. +- apply ./aufs5-mmap.patch too. +- apply ./aufs5-standalone.patch too, if you have a plan to set + CONFIG_AUFS_FS=m. otherwise you don't need ./aufs5-standalone.patch. +- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your + kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. +- enable CONFIG_AUFS_FS, you can select either + =m or =y. +- and build your kernel as usual. +- install the built kernel. +- install the header files too by "make headers_install" to the + directory where you specify. By default, it is $PWD/usr. + "make help" shows a brief note for headers_install. +- and reboot your system. + +2. +- module only (CONFIG_AUFS_FS=m). +- apply ./aufs5-base.patch to your kernel source files. +- apply ./aufs5-mmap.patch too. +- apply ./aufs5-standalone.patch too. +- build your kernel, don't forget "make headers_install", and reboot. +- edit ./config.mk and set other aufs configurations if necessary. + Note: You should read $PWD/fs/aufs/Kconfig carefully which describes + every aufs configurations. +- build the module by simple "make". +- you can specify ${KDIR} make variable which points to your kernel + source tree. +- install the files + + run "make install" to install the aufs module, or copy the built + $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). + + run "make install_headers" (instead of headers_install) to install + the modified aufs header file (you can specify DESTDIR which is + available in aufs standalone version's Makefile only), or copy + $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever + you like manually. By default, the target directory is $PWD/usr. +- no need to apply aufs5-kbuild.patch, nor copying source files to your + kernel source tree. + +Note: The header file aufs_type.h is necessary to build aufs-util + as well as "make headers_install" in the kernel source tree. + headers_install is subject to be forgotten, but it is essentially + necessary, not only for building aufs-util. + You may not meet problems without headers_install in some older + version though. + +And then, +- read README in aufs-util, build and install it +- note that your distribution may contain an obsoleted version of + aufs_type.h in /usr/include/linux or something. When you build aufs + utilities, make sure that your compiler refers the correct aufs header + file which is built by "make headers_install." +- if you want to use readdir(3) in userspace or pathconf(3) wrapper, + then run "make install_ulib" too. And refer to the aufs manual in + detail. + +There several other patches in aufs5-standalone.git. They are all +optional. When you meet some problems, they will help you. +- aufs5-loopback.patch + Supports a nested loopback mount in a branch-fs. This patch is + unnecessary until aufs produces a message like "you may want to try + another patch for loopback file". +- proc_mounts.patch + When there are many mountpoints and many mount(2)/umount(2) are + running, then /proc/mounts may not show the all mountpoints. This + patch makes /proc/mounts always show the full mountpoints list. + If you don't want to apply this patch and meet such problem, then you + need to increase the value of 'ProcMounts_Times' make-variable in + aufs-util.git as a second best solution. +- vfs-ino.patch + Modifies a system global kernel internal function get_next_ino() in + order to stop assigning 0 for an inode-number. Not directly related to + aufs, but recommended generally. +- tmpfs-idr.patch + Keeps the tmpfs inode number as the lowest value. Effective to reduce + the size of aufs XINO files for tmpfs branch. Also it prevents the + duplication of inode number, which is important for backup tools and + other utilities. When you find aufs XINO files for tmpfs branch + growing too much, try this patch. +- lockdep-debug.patch + Because aufs is not only an ordinary filesystem (callee of VFS), but + also a caller of VFS functions for branch filesystems, subclassing of + the internal locks for LOCKDEP is necessary. LOCKDEP is a debugging + feature of linux kernel. If you enable CONFIG_LOCKDEP, then you will + need to apply this debug patch to expand several constant values. + If you don't know what LOCKDEP is, then you don't have apply this + patch. + + +4. Usage +---------------------------------------- +At first, make sure aufs-util are installed, and please read the aufs +manual, aufs.5 in aufs-util.git tree. +$ man -l aufs.5 + +And then, +$ mkdir /tmp/rw /tmp/aufs +# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs + +Here is another example. The result is equivalent. +# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs + Or +# mount -t aufs -o br:/tmp/rw none /tmp/aufs +# mount -o remount,append:${HOME} /tmp/aufs + +Then, you can see whole tree of your home dir through /tmp/aufs. If +you modify a file under /tmp/aufs, the one on your home directory is +not affected, instead the same named file will be newly created under +/tmp/rw. And all of your modification to a file will be applied to +the one under /tmp/rw. This is called the file based Copy on Write +(COW) method. +Aufs mount options are described in aufs.5. +If you run chroot or something and make your aufs as a root directory, +then you need to customize the shutdown script. See the aufs manual in +detail. + +Additionally, there are some sample usages of aufs which are a +diskless system with network booting, and LiveCD over NFS. +See sample dir in CVS tree on SourceForge. + + +5. Contact +---------------------------------------- +When you have any problems or strange behaviour in aufs, please let me +know with: +- /proc/mounts (instead of the output of mount(8)) +- /sys/module/aufs/* +- /sys/fs/aufs/* (if you have them) +- /debug/aufs/* (if you have them) +- linux kernel version + if your kernel is not plain, for example modified by distributor, + the url where i can download its source is necessary too. +- aufs version which was printed at loading the module or booting the + system, instead of the date you downloaded. +- configuration (define/undefine CONFIG_AUFS_xxx) +- kernel configuration or /proc/config.gz (if you have it) +- LSM (linux security module, if you are using) +- behaviour which you think to be incorrect +- actual operation, reproducible one is better +- mailto: aufs-users at lists.sourceforge.net + +Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, +and Feature Requests) on SourceForge. Please join and write to +aufs-users ML. + + +6. Acknowledgements +---------------------------------------- +Thanks to everyone who have tried and are using aufs, whoever +have reported a bug or any feedback. + +Especially donators: +Tomas Matejicek(slax.org) made a donation (much more than once). + Since Apr 2010, Tomas M (the author of Slax and Linux Live + scripts) is making "doubling" donations. + Unfortunately I cannot list all of the donators, but I really + appreciate. + It ends Aug 2010, but the ordinary donation URL is still available. + +Dai Itasaka made a donation (2007/8). +Chuck Smith made a donation (2008/4, 10 and 12). +Henk Schoneveld made a donation (2008/9). +Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). +Francois Dupoux made a donation (2008/11). +Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public + aufs2 GIT tree (2009/2). +William Grant made a donation (2009/3). +Patrick Lane made a donation (2009/4). +The Mail Archive (mail-archive.com) made donations (2009/5). +Nippy Networks (Ed Wildgoose) made a donation (2009/7). +New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). +Pavel Pronskiy made a donation (2011/2). +Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy + Networks (Ed Wildgoose) made a donation for hardware (2011/3). +Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and +11). +Sam Liddicott made a donation (2011/9). +Era Scarecrow made a donation (2013/4). +Bor Ratajc made a donation (2013/4). +Alessandro Gorreta made a donation (2013/4). +POIRETTE Marc made a donation (2013/4). +Alessandro Gorreta made a donation (2013/4). +lauri kasvandik made a donation (2013/5). +"pemasu from Finland" made a donation (2013/7). +The Parted Magic Project made a donation (2013/9 and 11). +Pavel Barta made a donation (2013/10). +Nikolay Pertsev made a donation (2014/5). +James B made a donation (2014/7 and 2015/7). +Stefano Di Biase made a donation (2014/8). +Daniel Epellei made a donation (2015/1). +OmegaPhil made a donation (2016/1, 2018/4). +Tomasz Szewczyk made a donation (2016/4). +James Burry made a donation (2016/12). +Carsten Rose made a donation (2018/9). +Porteus Kiosk made a donation (2018/10). + +Thank you very much. +Donations are always, including future donations, very important and +helpful for me to keep on developing aufs. + + +7. +---------------------------------------- +If you are an experienced user, no explanation is needed. Aufs is +just a linux filesystem. + + +Enjoy! + +# Local variables: ; +# mode: text; +# End: ; --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/01intro.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/01intro.txt @@ -0,0 +1,171 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Introduction +---------------------------------------- + +aufs [ei ju: ef es] | /ey-yoo-ef-es/ | [a u f s] +1. abbrev. for "advanced multi-layered unification filesystem". +2. abbrev. for "another unionfs". +3. abbrev. for "auf das" in German which means "on the" in English. + Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). + But "Filesystem aufs Filesystem" is hard to understand. +4. abbrev. for "African Urban Fashion Show". + +AUFS is a filesystem with features: +- multi layered stackable unification filesystem, the member directory + is called as a branch. +- branch permission and attribute, 'readonly', 'real-readonly', + 'readwrite', 'whiteout-able', 'link-able whiteout', etc. and their + combination. +- internal "file copy-on-write". +- logical deletion, whiteout. +- dynamic branch manipulation, adding, deleting and changing permission. +- allow bypassing aufs, user's direct branch access. +- external inode number translation table and bitmap which maintains the + persistent aufs inode number. +- seekable directory, including NFS readdir. +- file mapping, mmap and sharing pages. +- pseudo-link, hardlink over branches. +- loopback mounted filesystem as a branch. +- several policies to select one among multiple writable branches. +- revert a single systemcall when an error occurs in aufs. +- and more... + + +Multi Layered Stackable Unification Filesystem +---------------------------------------------------------------------- +Most people already knows what it is. +It is a filesystem which unifies several directories and provides a +merged single directory. When users access a file, the access will be +passed/re-directed/converted (sorry, I am not sure which English word is +correct) to the real file on the member filesystem. The member +filesystem is called 'lower filesystem' or 'branch' and has a mode +'readonly' and 'readwrite.' And the deletion for a file on the lower +readonly branch is handled by creating 'whiteout' on the upper writable +branch. + +On LKML, there have been discussions about UnionMount (Jan Blunck, +Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took +different approaches to implement the merged-view. +The former tries putting it into VFS, and the latter implements as a +separate filesystem. +(If I misunderstand about these implementations, please let me know and +I shall correct it. Because it is a long time ago when I read their +source files last time). + +UnionMount's approach will be able to small, but may be hard to share +branches between several UnionMount since the whiteout in it is +implemented in the inode on branch filesystem and always +shared. According to Bharata's post, readdir does not seems to be +finished yet. +There are several missing features known in this implementations such as +- for users, the inode number may change silently. eg. copy-up. +- link(2) may break by copy-up. +- read(2) may get an obsoleted filedata (fstat(2) too). +- fcntl(F_SETLK) may be broken by copy-up. +- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after + open(O_RDWR). + +In linux-3.18, "overlay" filesystem (formerly known as "overlayfs") was +merged into mainline. This is another implementation of UnionMount as a +separated filesystem. All the limitations and known problems which +UnionMount are equally inherited to "overlay" filesystem. + +Unionfs has a longer history. When I started implementing a stackable +filesystem (Aug 2005), it already existed. It has virtual super_block, +inode, dentry and file objects and they have an array pointing lower +same kind objects. After contributing many patches for Unionfs, I +re-started my project AUFS (Jun 2006). + +In AUFS, the structure of filesystem resembles to Unionfs, but I +implemented my own ideas, approaches and enhancements and it became +totally different one. + +Comparing DM snapshot and fs based implementation +- the number of bytes to be copied between devices is much smaller. +- the type of filesystem must be one and only. +- the fs must be writable, no readonly fs, even for the lower original + device. so the compression fs will not be usable. but if we use + loopback mount, we may address this issue. + for instance, + mount /cdrom/squashfs.img /sq + losetup /sq/ext2.img + losetup /somewhere/cow + dmsetup "snapshot /dev/loop0 /dev/loop1 ..." +- it will be difficult (or needs more operations) to extract the + difference between the original device and COW. +- DM snapshot-merge may help a lot when users try merging. in the + fs-layer union, users will use rsync(1). + +You may want to read my old paper "Filesystems in LiveCD" +(http://aufs.sourceforge.net/aufs2/report/sq/sq.pdf). + + +Several characters/aspects/persona of aufs +---------------------------------------------------------------------- + +Aufs has several characters, aspects or persona. +1. a filesystem, callee of VFS helper +2. sub-VFS, caller of VFS helper for branches +3. a virtual filesystem which maintains persistent inode number +4. reader/writer of files on branches such like an application + +1. Callee of VFS Helper +As an ordinary linux filesystem, aufs is a callee of VFS. For instance, +unlink(2) from an application reaches sys_unlink() kernel function and +then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it +calls filesystem specific unlink operation. Actually aufs implements the +unlink operation but it behaves like a redirector. + +2. Caller of VFS Helper for Branches +aufs_unlink() passes the unlink request to the branch filesystem as if +it were called from VFS. So the called unlink operation of the branch +filesystem acts as usual. As a caller of VFS helper, aufs should handle +every necessary pre/post operation for the branch filesystem. +- acquire the lock for the parent dir on a branch +- lookup in a branch +- revalidate dentry on a branch +- mnt_want_write() for a branch +- vfs_unlink() for a branch +- mnt_drop_write() for a branch +- release the lock on a branch + +3. Persistent Inode Number +One of the most important issue for a filesystem is to maintain inode +numbers. This is particularly important to support exporting a +filesystem via NFS. Aufs is a virtual filesystem which doesn't have a +backend block device for its own. But some storage is necessary to +keep and maintain the inode numbers. It may be a large space and may not +suit to keep in memory. Aufs rents some space from its first writable +branch filesystem (by default) and creates file(s) on it. These files +are created by aufs internally and removed soon (currently) keeping +opened. +Note: Because these files are removed, they are totally gone after + unmounting aufs. It means the inode numbers are not persistent + across unmount or reboot. I have a plan to make them really + persistent which will be important for aufs on NFS server. + +4. Read/Write Files Internally (copy-on-write) +Because a branch can be readonly, when you write a file on it, aufs will +"copy-up" it to the upper writable branch internally. And then write the +originally requested thing to the file. Generally kernel doesn't +open/read/write file actively. In aufs, even a single write may cause a +internal "file copy". This behaviour is very similar to cp(1) command. + +Some people may think it is better to pass such work to user space +helper, instead of doing in kernel space. Actually I am still thinking +about it. But currently I have implemented it in kernel space. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/02struct.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/02struct.txt @@ -0,0 +1,258 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Basic Aufs Internal Structure + +Superblock/Inode/Dentry/File Objects +---------------------------------------------------------------------- +As like an ordinary filesystem, aufs has its own +superblock/inode/dentry/file objects. All these objects have a +dynamically allocated array and store the same kind of pointers to the +lower filesystem, branch. +For example, when you build a union with one readwrite branch and one +readonly, mounted /au, /rw and /ro respectively. +- /au = /rw + /ro +- /ro/fileA exists but /rw/fileA + +Aufs lookup operation finds /ro/fileA and gets dentry for that. These +pointers are stored in a aufs dentry. The array in aufs dentry will be, +- [0] = NULL (because /rw/fileA doesn't exist) +- [1] = /ro/fileA + +This style of an array is essentially same to the aufs +superblock/inode/dentry/file objects. + +Because aufs supports manipulating branches, ie. add/delete/change +branches dynamically, these objects has its own generation. When +branches are changed, the generation in aufs superblock is +incremented. And a generation in other object are compared when it is +accessed. When a generation in other objects are obsoleted, aufs +refreshes the internal array. + + +Superblock +---------------------------------------------------------------------- +Additionally aufs superblock has some data for policies to select one +among multiple writable branches, XIB files, pseudo-links and kobject. +See below in detail. +About the policies which supports copy-down a directory, see +wbr_policy.txt too. + + +Branch and XINO(External Inode Number Translation Table) +---------------------------------------------------------------------- +Every branch has its own xino (external inode number translation table) +file. The xino file is created and unlinked by aufs internally. When two +members of a union exist on the same filesystem, they share the single +xino file. +The struct of a xino file is simple, just a sequence of aufs inode +numbers which is indexed by the lower inode number. +In the above sample, assume the inode number of /ro/fileA is i111 and +aufs assigns the inode number i999 for fileA. Then aufs writes 999 as +4(8) bytes at 111 * 4(8) bytes offset in the xino file. + +When the inode numbers are not contiguous, the xino file will be sparse +which has a hole in it and doesn't consume as much disk space as it +might appear. If your branch filesystem consumes disk space for such +holes, then you should specify 'xino=' option at mounting aufs. + +Aufs has a mount option to free the disk blocks for such holes in XINO +files on tmpfs or ramdisk. But it is not so effective actually. If you +meet a problem of disk shortage due to XINO files, then you should try +"tmpfs-ino.patch" (and "vfs-ino.patch" too) in aufs4-standalone.git. +The patch localizes the assignment inumbers per tmpfs-mount and avoid +the holes in XINO files. + +Also a writable branch has three kinds of "whiteout bases". All these +are existed when the branch is joined to aufs, and their names are +whiteout-ed doubly, so that users will never see their names in aufs +hierarchy. +1. a regular file which will be hardlinked to all whiteouts. +2. a directory to store a pseudo-link. +3. a directory to store an "orphan"-ed file temporary. + +1. Whiteout Base + When you remove a file on a readonly branch, aufs handles it as a + logical deletion and creates a whiteout on the upper writable branch + as a hardlink of this file in order not to consume inode on the + writable branch. +2. Pseudo-link Dir + See below, Pseudo-link. +3. Step-Parent Dir + When "fileC" exists on the lower readonly branch only and it is + opened and removed with its parent dir, and then user writes + something into it, then aufs copies-up fileC to this + directory. Because there is no other dir to store fileC. After + creating a file under this dir, the file is unlinked. + +Because aufs supports manipulating branches, ie. add/delete/change +dynamically, a branch has its own id. When the branch order changes, +aufs finds the new index by searching the branch id. + + +Pseudo-link +---------------------------------------------------------------------- +Assume "fileA" exists on the lower readonly branch only and it is +hardlinked to "fileB" on the branch. When you write something to fileA, +aufs copies-up it to the upper writable branch. Additionally aufs +creates a hardlink under the Pseudo-link Directory of the writable +branch. The inode of a pseudo-link is kept in aufs super_block as a +simple list. If fileB is read after unlinking fileA, aufs returns +filedata from the pseudo-link instead of the lower readonly +branch. Because the pseudo-link is based upon the inode, to keep the +inode number by xino (see above) is essentially necessary. + +All the hardlinks under the Pseudo-link Directory of the writable branch +should be restored in a proper location later. Aufs provides a utility +to do this. The userspace helpers executed at remounting and unmounting +aufs by default. +During this utility is running, it puts aufs into the pseudo-link +maintenance mode. In this mode, only the process which began the +maintenance mode (and its child processes) is allowed to operate in +aufs. Some other processes which are not related to the pseudo-link will +be allowed to run too, but the rest have to return an error or wait +until the maintenance mode ends. If a process already acquires an inode +mutex (in VFS), it has to return an error. + + +XIB(external inode number bitmap) +---------------------------------------------------------------------- +Addition to the xino file per a branch, aufs has an external inode number +bitmap in a superblock object. It is also an internal file such like a +xino file. +It is a simple bitmap to mark whether the aufs inode number is in-use or +not. +To reduce the file I/O, aufs prepares a single memory page to cache xib. + +As well as XINO files, aufs has a feature to truncate/refresh XIB to +reduce the number of consumed disk blocks for these files. + + +Virtual or Vertical Dir, and Readdir in Userspace +---------------------------------------------------------------------- +In order to support multiple layers (branches), aufs readdir operation +constructs a virtual dir block on memory. For readdir, aufs calls +vfs_readdir() internally for each dir on branches, merges their entries +with eliminating the whiteout-ed ones, and sets it to file (dir) +object. So the file object has its entry list until it is closed. The +entry list will be updated when the file position is zero and becomes +obsoleted. This decision is made in aufs automatically. + +The dynamically allocated memory block for the name of entries has a +unit of 512 bytes (by default) and stores the names contiguously (no +padding). Another block for each entry is handled by kmem_cache too. +During building dir blocks, aufs creates hash list and judging whether +the entry is whiteouted by its upper branch or already listed. +The merged result is cached in the corresponding inode object and +maintained by a customizable life-time option. + +Some people may call it can be a security hole or invite DoS attack +since the opened and once readdir-ed dir (file object) holds its entry +list and becomes a pressure for system memory. But I'd say it is similar +to files under /proc or /sys. The virtual files in them also holds a +memory page (generally) while they are opened. When an idea to reduce +memory for them is introduced, it will be applied to aufs too. +For those who really hate this situation, I've developed readdir(3) +library which operates this merging in userspace. You just need to set +LD_PRELOAD environment variable, and aufs will not consume no memory in +kernel space for readdir(3). + + +Workqueue +---------------------------------------------------------------------- +Aufs sometimes requires privilege access to a branch. For instance, +in copy-up/down operation. When a user process is going to make changes +to a file which exists in the lower readonly branch only, and the mode +of one of ancestor directories may not be writable by a user +process. Here aufs copy-up the file with its ancestors and they may +require privilege to set its owner/group/mode/etc. +This is a typical case of a application character of aufs (see +Introduction). + +Aufs uses workqueue synchronously for this case. It creates its own +workqueue. The workqueue is a kernel thread and has privilege. Aufs +passes the request to call mkdir or write (for example), and wait for +its completion. This approach solves a problem of a signal handler +simply. +If aufs didn't adopt the workqueue and changed the privilege of the +process, then the process may receive the unexpected SIGXFSZ or other +signals. + +Also aufs uses the system global workqueue ("events" kernel thread) too +for asynchronous tasks, such like handling inotify/fsnotify, re-creating a +whiteout base and etc. This is unrelated to a privilege. +Most of aufs operation tries acquiring a rw_semaphore for aufs +superblock at the beginning, at the same time waits for the completion +of all queued asynchronous tasks. + + +Whiteout +---------------------------------------------------------------------- +The whiteout in aufs is very similar to Unionfs's. That is represented +by its filename. UnionMount takes an approach of a file mode, but I am +afraid several utilities (find(1) or something) will have to support it. + +Basically the whiteout represents "logical deletion" which stops aufs to +lookup further, but also it represents "dir is opaque" which also stop +further lookup. + +In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively. +In order to make several functions in a single systemcall to be +revertible, aufs adopts an approach to rename a directory to a temporary +unique whiteouted name. +For example, in rename(2) dir where the target dir already existed, aufs +renames the target dir to a temporary unique whiteouted name before the +actual rename on a branch, and then handles other actions (make it opaque, +update the attributes, etc). If an error happens in these actions, aufs +simply renames the whiteouted name back and returns an error. If all are +succeeded, aufs registers a function to remove the whiteouted unique +temporary name completely and asynchronously to the system global +workqueue. + + +Copy-up +---------------------------------------------------------------------- +It is a well-known feature or concept. +When user modifies a file on a readonly branch, aufs operate "copy-up" +internally and makes change to the new file on the upper writable branch. +When the trigger systemcall does not update the timestamps of the parent +dir, aufs reverts it after copy-up. + + +Move-down (aufs3.9 and later) +---------------------------------------------------------------------- +"Copy-up" is one of the essential feature in aufs. It copies a file from +the lower readonly branch to the upper writable branch when a user +changes something about the file. +"Move-down" is an opposite action of copy-up. Basically this action is +ran manually instead of automatically and internally. +For desgin and implementation, aufs has to consider these issues. +- whiteout for the file may exist on the lower branch. +- ancestor directories may not exist on the lower branch. +- diropq for the ancestor directories may exist on the upper branch. +- free space on the lower branch will reduce. +- another access to the file may happen during moving-down, including + UDBA (see "Revalidate Dentry and UDBA"). +- the file should not be hard-linked nor pseudo-linked. they should be + handled by auplink utility later. + +Sometimes users want to move-down a file from the upper writable branch +to the lower readonly or writable branch. For instance, +- the free space of the upper writable branch is going to run out. +- create a new intermediate branch between the upper and lower branch. +- etc. + +For this purpose, use "aumvdown" command in aufs-util.git. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/03atomic_open.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/03atomic_open.txt @@ -0,0 +1,85 @@ + +# Copyright (C) 2015-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Support for a branch who has its ->atomic_open() +---------------------------------------------------------------------- +The filesystems who implement its ->atomic_open() are not majority. For +example NFSv4 does, and aufs should call NFSv4 ->atomic_open, +particularly for open(O_CREAT|O_EXCL, 0400) case. Other than +->atomic_open(), NFSv4 returns an error for this open(2). While I am not +sure whether all filesystems who have ->atomic_open() behave like this, +but NFSv4 surely returns the error. + +In order to support ->atomic_open() for aufs, there are a few +approaches. + +A. Introduce aufs_atomic_open() + - calls one of VFS:do_last(), lookup_open() or atomic_open() for + branch fs. +B. Introduce aufs_atomic_open() calling create, open and chmod. this is + an aufs user Pip Cet's approach + - calls aufs_create(), VFS finish_open() and notify_change(). + - pass fake-mode to finish_open(), and then correct the mode by + notify_change(). +C. Extend aufs_open() to call branch fs's ->atomic_open() + - no aufs_atomic_open(). + - aufs_lookup() registers the TID to an aufs internal object. + - aufs_create() does nothing when the matching TID is registered, but + registers the mode. + - aufs_open() calls branch fs's ->atomic_open() when the matching + TID is registered. +D. Extend aufs_open() to re-try branch fs's ->open() with superuser's + credential + - no aufs_atomic_open(). + - aufs_create() registers the TID to an internal object. this info + represents "this process created this file just now." + - when aufs gets EACCES from branch fs's ->open(), then confirm the + registered TID and re-try open() with superuser's credential. + +Pros and cons for each approach. + +A. + - straightforward but highly depends upon VFS internal. + - the atomic behavaiour is kept. + - some of parameters such as nameidata are hard to reproduce for + branch fs. + - large overhead. +B. + - easy to implement. + - the atomic behavaiour is lost. +C. + - the atomic behavaiour is kept. + - dirty and tricky. + - VFS checks whether the file is created correctly after calling + ->create(), which means this approach doesn't work. +D. + - easy to implement. + - the atomic behavaiour is lost. + - to open a file with superuser's credential and give it to a user + process is a bad idea, since the file object keeps the credential + in it. It may affect LSM or something. This approach doesn't work + either. + +The approach A is ideal, but it hard to implement. So here is a +variation of A, which is to be implemented. + +A-1. Introduce aufs_atomic_open() + - calls branch fs ->atomic_open() if exists. otherwise calls + vfs_create() and finish_open(). + - the demerit is that the several checks after branch fs + ->atomic_open() are lost. in the ordinary case, the checks are + done by VFS:do_last(), lookup_open() and atomic_open(). some can + be implemented in aufs, but not all I am afraid. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/03lookup.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/03lookup.txt @@ -0,0 +1,113 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Lookup in a Branch +---------------------------------------------------------------------- +Since aufs has a character of sub-VFS (see Introduction), it operates +lookup for branches as VFS does. It may be a heavy work. But almost all +lookup operation in aufs is the simplest case, ie. lookup only an entry +directly connected to its parent. Digging down the directory hierarchy +is unnecessary. VFS has a function lookup_one_len() for that use, and +aufs calls it. + +When a branch is a remote filesystem, aufs basically relies upon its +->d_revalidate(), also aufs forces the hardest revalidate tests for +them. +For d_revalidate, aufs implements three levels of revalidate tests. See +"Revalidate Dentry and UDBA" in detail. + + +Test Only the Highest One for the Directory Permission (dirperm1 option) +---------------------------------------------------------------------- +Let's try case study. +- aufs has two branches, upper readwrite and lower readonly. + /au = /rw + /ro +- "dirA" exists under /ro, but /rw. and its mode is 0700. +- user invoked "chmod a+rx /au/dirA" +- the internal copy-up is activated and "/rw/dirA" is created and its + permission bits are set to world readable. +- then "/au/dirA" becomes world readable? + +In this case, /ro/dirA is still 0700 since it exists in readonly branch, +or it may be a natively readonly filesystem. If aufs respects the lower +branch, it should not respond readdir request from other users. But user +allowed it by chmod. Should really aufs rejects showing the entries +under /ro/dirA? + +To be honest, I don't have a good solution for this case. So aufs +implements 'dirperm1' and 'nodirperm1' mount options, and leave it to +users. +When dirperm1 is specified, aufs checks only the highest one for the +directory permission, and shows the entries. Otherwise, as usual, checks +every dir existing on all branches and rejects the request. + +As a side effect, dirperm1 option improves the performance of aufs +because the number of permission check is reduced when the number of +branch is many. + + +Revalidate Dentry and UDBA (User's Direct Branch Access) +---------------------------------------------------------------------- +Generally VFS helpers re-validate a dentry as a part of lookup. +0. digging down the directory hierarchy. +1. lock the parent dir by its i_mutex. +2. lookup the final (child) entry. +3. revalidate it. +4. call the actual operation (create, unlink, etc.) +5. unlock the parent dir + +If the filesystem implements its ->d_revalidate() (step 3), then it is +called. Actually aufs implements it and checks the dentry on a branch is +still valid. +But it is not enough. Because aufs has to release the lock for the +parent dir on a branch at the end of ->lookup() (step 2) and +->d_revalidate() (step 3) while the i_mutex of the aufs dir is still +held by VFS. +If the file on a branch is changed directly, eg. bypassing aufs, after +aufs released the lock, then the subsequent operation may cause +something unpleasant result. + +This situation is a result of VFS architecture, ->lookup() and +->d_revalidate() is separated. But I never say it is wrong. It is a good +design from VFS's point of view. It is just not suitable for sub-VFS +character in aufs. + +Aufs supports such case by three level of revalidation which is +selectable by user. +1. Simple Revalidate + Addition to the native flow in VFS's, confirm the child-parent + relationship on the branch just after locking the parent dir on the + branch in the "actual operation" (step 4). When this validation + fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still + checks the validation of the dentry on branches. +2. Monitor Changes Internally by Inotify/Fsnotify + Addition to above, in the "actual operation" (step 4) aufs re-lookup + the dentry on the branch, and returns EBUSY if it finds different + dentry. + Additionally, aufs sets the inotify/fsnotify watch for every dir on branches + during it is in cache. When the event is notified, aufs registers a + function to kernel 'events' thread by schedule_work(). And the + function sets some special status to the cached aufs dentry and inode + private data. If they are not cached, then aufs has nothing to + do. When the same file is accessed through aufs (step 0-3) later, + aufs will detect the status and refresh all necessary data. + In this mode, aufs has to ignore the event which is fired by aufs + itself. +3. No Extra Validation + This is the simplest test and doesn't add any additional revalidation + test, and skip the revalidation in step 4. It is useful and improves + aufs performance when system surely hide the aufs branches from user, + by over-mounting something (or another method). --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/04branch.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/04branch.txt @@ -0,0 +1,74 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Branch Manipulation + +Since aufs supports dynamic branch manipulation, ie. add/remove a branch +and changing its permission/attribute, there are a lot of works to do. + + +Add a Branch +---------------------------------------------------------------------- +o Confirm the adding dir exists outside of aufs, including loopback + mount, and its various attributes. +o Initialize the xino file and whiteout bases if necessary. + See struct.txt. + +o Check the owner/group/mode of the directory + When the owner/group/mode of the adding directory differs from the + existing branch, aufs issues a warning because it may impose a + security risk. + For example, when a upper writable branch has a world writable empty + top directory, a malicious user can create any files on the writable + branch directly, like copy-up and modify manually. If something like + /etc/{passwd,shadow} exists on the lower readonly branch but the upper + writable branch, and the writable branch is world-writable, then a + malicious guy may create /etc/passwd on the writable branch directly + and the infected file will be valid in aufs. + I am afraid it can be a security issue, but aufs can do nothing except + producing a warning. + + +Delete a Branch +---------------------------------------------------------------------- +o Confirm the deleting branch is not busy + To be general, there is one merit to adopt "remount" interface to + manipulate branches. It is to discard caches. At deleting a branch, + aufs checks the still cached (and connected) dentries and inodes. If + there are any, then they are all in-use. An inode without its + corresponding dentry can be alive alone (for example, inotify/fsnotify case). + + For the cached one, aufs checks whether the same named entry exists on + other branches. + If the cached one is a directory, because aufs provides a merged view + to users, as long as one dir is left on any branch aufs can show the + dir to users. In this case, the branch can be removed from aufs. + Otherwise aufs rejects deleting the branch. + + If any file on the deleting branch is opened by aufs, then aufs + rejects deleting. + + +Modify the Permission of a Branch +---------------------------------------------------------------------- +o Re-initialize or remove the xino file and whiteout bases if necessary. + See struct.txt. + +o rw --> ro: Confirm the modifying branch is not busy + Aufs rejects the request if any of these conditions are true. + - a file on the branch is mmap-ed. + - a regular file on the branch is opened for write and there is no + same named entry on the upper branch. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/05wbr_policy.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/05wbr_policy.txt @@ -0,0 +1,64 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Policies to Select One among Multiple Writable Branches +---------------------------------------------------------------------- +When the number of writable branch is more than one, aufs has to decide +the target branch for file creation or copy-up. By default, the highest +writable branch which has the parent (or ancestor) dir of the target +file is chosen (top-down-parent policy). +By user's request, aufs implements some other policies to select the +writable branch, for file creation several policies, round-robin, +most-free-space, and other policies. For copy-up, top-down-parent, +bottom-up-parent, bottom-up and others. + +As expected, the round-robin policy selects the branch in circular. When +you have two writable branches and creates 10 new files, 5 files will be +created for each branch. mkdir(2) systemcall is an exception. When you +create 10 new directories, all will be created on the same branch. +And the most-free-space policy selects the one which has most free +space among the writable branches. The amount of free space will be +checked by aufs internally, and users can specify its time interval. + +The policies for copy-up is more simple, +top-down-parent is equivalent to the same named on in create policy, +bottom-up-parent selects the writable branch where the parent dir +exists and the nearest upper one from the copyup-source, +bottom-up selects the nearest upper writable branch from the +copyup-source, regardless the existence of the parent dir. + +There are some rules or exceptions to apply these policies. +- If there is a readonly branch above the policy-selected branch and + the parent dir is marked as opaque (a variation of whiteout), or the + target (creating) file is whiteout-ed on the upper readonly branch, + then the result of the policy is ignored and the target file will be + created on the nearest upper writable branch than the readonly branch. +- If there is a writable branch above the policy-selected branch and + the parent dir is marked as opaque or the target file is whiteouted + on the branch, then the result of the policy is ignored and the target + file will be created on the highest one among the upper writable + branches who has diropq or whiteout. In case of whiteout, aufs removes + it as usual. +- link(2) and rename(2) systemcalls are exceptions in every policy. + They try selecting the branch where the source exists as possible + since copyup a large file will take long time. If it can't be, + ie. the branch where the source exists is readonly, then they will + follow the copyup policy. +- There is an exception for rename(2) when the target exists. + If the rename target exists, aufs compares the index of the branches + where the source and the target exists and selects the higher + one. If the selected branch is readonly, then aufs follows the + copyup policy. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/06dirren.dot +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/06dirren.dot @@ -0,0 +1,31 @@ + +// to view this graph, run dot(1) command in GRAPHVIZ. + +digraph G { +node [shape=box]; +whinfo [label="detailed info file\n(lower_brid_root-hinum, h_inum, namelen, old name)"]; + +node [shape=oval]; + +aufs_rename -> whinfo [label="store/remove"]; + +node [shape=oval]; +inode_list [label="h_inum list in branch\ncache"]; + +node [shape=box]; +whinode [label="h_inum list file"]; + +node [shape=oval]; +brmgmt [label="br_add/del/mod/umount"]; + +brmgmt -> inode_list [label="create/remove"]; +brmgmt -> whinode [label="load/store"]; + +inode_list -> whinode [style=dashed,dir=both]; + +aufs_rename -> inode_list [label="add/del"]; + +aufs_lookup -> inode_list [label="search"]; + +aufs_lookup -> whinfo [label="load/remove"]; +} --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/06dirren.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/06dirren.txt @@ -0,0 +1,102 @@ + +# Copyright (C) 2017-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Special handling for renaming a directory (DIRREN) +---------------------------------------------------------------------- +First, let's assume we have a simple usecase. + +- /u = /rw + /ro +- /rw/dirA exists +- /ro/dirA and /ro/dirA/file exist too +- there is no dirB on both branches +- a user issues rename("dirA", "dirB") + +Now, what should aufs behave against this rename(2)? +There are a few possible cases. + +A. returns EROFS. + since dirA exists on a readonly branch which cannot be renamed. +B. returns EXDEV. + it is possible to copy-up dirA (only the dir itself), but the child + entries ("file" in this case) should not be. it must be a bad + approach to copy-up recursively. +C. returns a success. + even the branch /ro is readonly, aufs tries renaming it. Obviously it + is a violation of aufs' policy. +D. construct an extra information which indicates that /ro/dirA should + be handled as the name of dirB. + overlayfs has a similar feature called REDIRECT. + +Until now, aufs implements the case B only which returns EXDEV, and +expects the userspace application behaves like mv(1) which tries +issueing rename(2) recursively. + +A new aufs feature called DIRREN is introduced which implements the case +D. There are several "extra information" added. + +1. detailed info per renamed directory + path: /rw/dirB/$AUFS_WH_DR_INFO_PFX. +2. the inode-number list of directories on a branch + path: /rw/dirB/$AUFS_WH_DR_BRHINO + +The filename of "detailed info per directory" represents the lower +branch, and its format is +- a type of the branch id + one of these. + + uuid (not implemented yet) + + fsid + + dev +- the inode-number of the branch root dir + +And it contains these info in a single regular file. +- magic number +- branch's inode-number of the logically renamed dir +- the name of the before-renamed dir + +The "detailed info per directory" file is created in aufs rename(2), and +loaded in any lookup. +The info is considered in lookup for the matching case only. Here +"matching" means that the root of branch (in the info filename) is same +to the current looking-up branch. After looking-up the before-renamed +name, the inode-number is compared. And the matched dentry is used. + +The "inode-number list of directories" is a regular file which contains +simply the inode-numbers on the branch. The file is created or updated +in removing the branch, and loaded in adding the branch. Its lifetime is +equal to the branch. +The list is refered in lookup, and when the current target inode is +found in the list, the aufs tries loading the "detailed info per +directory" and get the changed and valid name of the dir. + +Theoretically these "extra informaiton" may be able to be put into XATTR +in the dir inode. But aufs doesn't choose this way because +1. XATTR may not be supported by the branch (or its configuration) +2. XATTR may have its size limit. +3. XATTR may be less easy to convert than a regular file, when the + format of the info is changed in the future. +At the same time, I agree that the regular file approach is much slower +than XATTR approach. So, in the future, aufs may take the XATTR or other +better approach. + +This DIRREN feature is enabled by aufs configuration, and is activated +by a new mount option. + +For the more complicated case, there is a work with UDBA option, which +is to dected the direct access to the branches (by-passing aufs) and to +maintain the cashes in aufs. Since a single cached aufs dentry may +contains two names, before- and after-rename, the name comparision in +UDBA handler may not work correctly. In this case, the behaviour will be +equivalen to udba=reval case. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/06fhsm.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/06fhsm.txt @@ -0,0 +1,120 @@ + +# Copyright (C) 2011-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +File-based Hierarchical Storage Management (FHSM) +---------------------------------------------------------------------- +Hierarchical Storage Management (or HSM) is a well-known feature in the +storage world. Aufs provides this feature as file-based with multiple +writable branches, based upon the principle of "Colder, the Lower". +Here the word "colder" means that the less used files, and "lower" means +that the position in the order of the stacked branches vertically. +These multiple writable branches are prioritized, ie. the topmost one +should be the fastest drive and be used heavily. + +o Characters in aufs FHSM story +- aufs itself and a new branch attribute. +- a new ioctl interface to move-down and to establish a connection with + the daemon ("move-down" is a converse of "copy-up"). +- userspace tool and daemon. + +The userspace daemon establishes a connection with aufs and waits for +the notification. The notified information is very similar to struct +statfs containing the number of consumed blocks and inodes. +When the consumed blocks/inodes of a branch exceeds the user-specified +upper watermark, the daemon activates its move-down process until the +consumed blocks/inodes reaches the user-specified lower watermark. + +The actual move-down is done by aufs based upon the request from +user-space since we need to maintain the inode number and the internal +pointer arrays in aufs. + +Currently aufs FHSM handles the regular files only. Additionally they +must not be hard-linked nor pseudo-linked. + + +o Cowork of aufs and the user-space daemon + During the userspace daemon established the connection, aufs sends a + small notification to it whenever aufs writes something into the + writable branch. But it may cost high since aufs issues statfs(2) + internally. So user can specify a new option to cache the + info. Actually the notification is controlled by these factors. + + the specified cache time. + + classified as "force" by aufs internally. + Until the specified time expires, aufs doesn't send the info + except the forced cases. When aufs decide forcing, the info is always + notified to userspace. + For example, the number of free inodes is generally large enough and + the shortage of it happens rarely. So aufs doesn't force the + notification when creating a new file, directory and others. This is + the typical case which aufs doesn't force. + When aufs writes the actual filedata and the files consumes any of new + blocks, the aufs forces notifying. + + +o Interfaces in aufs +- New branch attribute. + + fhsm + Specifies that the branch is managed by FHSM feature. In other word, + participant in the FHSM. + When nofhsm is set to the branch, it will not be the source/target + branch of the move-down operation. This attribute is set + independently from coo and moo attributes, and if you want full + FHSM, you should specify them as well. +- New mount option. + + fhsm_sec + Specifies a second to suppress many less important info to be + notified. +- New ioctl. + + AUFS_CTL_FHSM_FD + create a new file descriptor which userspace can read the notification + (a subset of struct statfs) from aufs. +- Module parameter 'brs' + It has to be set to 1. Otherwise the new mount option 'fhsm' will not + be set. +- mount helpers /sbin/mount.aufs and /sbin/umount.aufs + When there are two or more branches with fhsm attributes, + /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs + terminates it. As a result of remounting and branch-manipulation, the + number of branches with fhsm attribute can be one. In this case, + /sbin/mount.aufs will terminate the user-space daemon. + + +Finally the operation is done as these steps in kernel-space. +- make sure that, + + no one else is using the file. + + the file is not hard-linked. + + the file is not pseudo-linked. + + the file is a regular file. + + the parent dir is not opaqued. +- find the target writable branch. +- make sure the file is not whiteout-ed by the upper (than the target) + branch. +- make the parent dir on the target branch. +- mutex lock the inode on the branch. +- unlink the whiteout on the target branch (if exists). +- lookup and create the whiteout-ed temporary name on the target branch. +- copy the file as the whiteout-ed temporary name on the target branch. +- rename the whiteout-ed temporary name to the original name. +- unlink the file on the source branch. +- maintain the internal pointer array and the external inode number + table (XINO). +- maintain the timestamps and other attributes of the parent dir and the + file. + +And of course, in every step, an error may happen. So the operation +should restore the original file state after an error happens. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/06mmap.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/06mmap.txt @@ -0,0 +1,72 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +mmap(2) -- File Memory Mapping +---------------------------------------------------------------------- +In aufs, the file-mapped pages are handled by a branch fs directly, no +interaction with aufs. It means aufs_mmap() calls the branch fs's +->mmap(). +This approach is simple and good, but there is one problem. +Under /proc, several entries show the mmapped files by its path (with +device and inode number), and the printed path will be the path on the +branch fs's instead of virtual aufs's. +This is not a problem in most cases, but some utilities lsof(1) (and its +user) may expect the path on aufs. + +To address this issue, aufs adds a new member called vm_prfile in struct +vm_area_struct (and struct vm_region). The original vm_file points to +the file on the branch fs in order to handle everything correctly as +usual. The new vm_prfile points to a virtual file in aufs, and the +show-functions in procfs refers to vm_prfile if it is set. +Also we need to maintain several other places where touching vm_file +such like +- fork()/clone() copies vma and the reference count of vm_file is + incremented. +- merging vma maintains the ref count too. + +This is not a good approach. It just fakes the printed path. But it +leaves all behaviour around f_mapping unchanged. This is surely an +advantage. +Actually aufs had adopted another complicated approach which calls +generic_file_mmap() and handles struct vm_operations_struct. In this +approach, aufs met a hard problem and I could not solve it without +switching the approach. + +There may be one more another approach which is +- bind-mount the branch-root onto the aufs-root internally +- grab the new vfsmount (ie. struct mount) +- lazy-umount the branch-root internally +- in open(2) the aufs-file, open the branch-file with the hidden + vfsmount (instead of the original branch's vfsmount) +- ideally this "bind-mount and lazy-umount" should be done atomically, + but it may be possible from userspace by the mount helper. + +Adding the internal hidden vfsmount and using it in opening a file, the +file path under /proc will be printed correctly. This approach looks +smarter, but is not possible I am afraid. +- aufs-root may be bind-mount later. when it happens, another hidden + vfsmount will be required. +- it is hard to get the chance to bind-mount and lazy-umount + + in kernel-space, FS can have vfsmount in open(2) via + file->f_path, and aufs can know its vfsmount. But several locks are + already acquired, and if aufs tries to bind-mount and lazy-umount + here, then it may cause a deadlock. + + in user-space, bind-mount doesn't invoke the mount helper. +- since /proc shows dev and ino, aufs has to give vma these info. it + means a new member vm_prinode will be necessary. this is essentially + equivalent to vm_prfile described above. + +I have to give up this "looks-smater" approach. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/06xattr.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/06xattr.txt @@ -0,0 +1,96 @@ + +# Copyright (C) 2014-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Listing XATTR/EA and getting the value +---------------------------------------------------------------------- +For the inode standard attributes (owner, group, timestamps, etc.), aufs +shows the values from the topmost existing file. This behaviour is good +for the non-dir entries since the bahaviour exactly matches the shown +information. But for the directories, aufs considers all the same named +entries on the lower branches. Which means, if one of the lower entry +rejects readdir call, then aufs returns an error even if the topmost +entry allows it. This behaviour is necessary to respect the branch fs's +security, but can make users confused since the user-visible standard +attributes don't match the behaviour. +To address this issue, aufs has a mount option called dirperm1 which +checks the permission for the topmost entry only, and ignores the lower +entry's permission. + +A similar issue can happen around XATTR. +getxattr(2) and listxattr(2) families behave as if dirperm1 option is +always set. Otherwise these very unpleasant situation would happen. +- listxattr(2) may return the duplicated entries. +- users may not be able to remove or reset the XATTR forever, + + +XATTR/EA support in the internal (copy,move)-(up,down) +---------------------------------------------------------------------- +Generally the extended attributes of inode are categorized as these. +- "security" for LSM and capability. +- "system" for posix ACL, 'acl' mount option is required for the branch + fs generally. +- "trusted" for userspace, CAP_SYS_ADMIN is required. +- "user" for userspace, 'user_xattr' mount option is required for the + branch fs generally. + +Moreover there are some other categories. Aufs handles these rather +unpopular categories as the ordinary ones, ie. there is no special +condition nor exception. + +In copy-up, the support for XATTR on the dst branch may differ from the +src branch. In this case, the copy-up operation will get an error and +the original user operation which triggered the copy-up will fail. It +can happen that even all copy-up will fail. +When both of src and dst branches support XATTR and if an error occurs +during copying XATTR, then the copy-up should fail obviously. That is a +good reason and aufs should return an error to userspace. But when only +the src branch support that XATTR, aufs should not return an error. +For example, the src branch supports ACL but the dst branch doesn't +because the dst branch may natively un-support it or temporary +un-support it due to "noacl" mount option. Of course, the dst branch fs +may NOT return an error even if the XATTR is not supported. It is +totally up to the branch fs. + +Anyway when the aufs internal copy-up gets an error from the dst branch +fs, then aufs tries removing the just copied entry and returns the error +to the userspace. The worst case of this situation will be all copy-up +will fail. + +For the copy-up operation, there two basic approaches. +- copy the specified XATTR only (by category above), and return the + error unconditionally if it happens. +- copy all XATTR, and ignore the error on the specified category only. + +In order to support XATTR and to implement the correct behaviour, aufs +chooses the latter approach and introduces some new branch attributes, +"icexsec", "icexsys", "icextr", "icexusr", and "icexoth". +They correspond to the XATTR namespaces (see above). Additionally, to be +convenient, "icex" is also provided which means all "icex*" attributes +are set (here the word "icex" stands for "ignore copy-error on XATTR"). + +The meaning of these attributes is to ignore the error from setting +XATTR on that branch. +Note that aufs tries copying all XATTR unconditionally, and ignores the +error from the dst branch according to the specified attributes. + +Some XATTR may have its default value. The default value may come from +the parent dir or the environment. If the default value is set at the +file creating-time, it will be overwritten by copy-up. +Some contradiction may happen I am afraid. +Do we need another attribute to stop copying XATTR? I am unsure. For +now, aufs implements the branch attributes to ignore the error. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/07export.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/07export.txt @@ -0,0 +1,58 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Export Aufs via NFS +---------------------------------------------------------------------- +Here is an approach. +- like xino/xib, add a new file 'xigen' which stores aufs inode + generation. +- iget_locked(): initialize aufs inode generation for a new inode, and + store it in xigen file. +- destroy_inode(): increment aufs inode generation and store it in xigen + file. it is necessary even if it is not unlinked, because any data of + inode may be changed by UDBA. +- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise + build file handle by + + branch id (4 bytes) + + superblock generation (4 bytes) + + inode number (4 or 8 bytes) + + parent dir inode number (4 or 8 bytes) + + inode generation (4 bytes)) + + return value of exportfs_encode_fh() for the parent on a branch (4 + bytes) + + file handle for a branch (by exportfs_encode_fh()) +- fh_to_dentry(): + + find the index of a branch from its id in handle, and check it is + still exist in aufs. + + 1st level: get the inode number from handle and search it in cache. + + 2nd level: if not found in cache, get the parent inode number from + the handle and search it in cache. and then open the found parent + dir, find the matching inode number by vfs_readdir() and get its + name, and call lookup_one_len() for the target dentry. + + 3rd level: if the parent dir is not cached, call + exportfs_decode_fh() for a branch and get the parent on a branch, + build a pathname of it, convert it a pathname in aufs, call + path_lookup(). now aufs gets a parent dir dentry, then handle it as + the 2nd level. + + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount + for every branch, but not itself. to get this, (currently) aufs + searches in current->nsproxy->mnt_ns list. it may not be a good + idea, but I didn't get other approach. + + test the generation of the gotten inode. +- every inode operation: they may get EBUSY due to UDBA. in this case, + convert it into ESTALE for NFSD. +- readdir(): call lockdep_on/off() because filldir in NFSD calls + lookup_one_len(), vfs_getattr(), encode_fh() and others. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/08shwh.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/08shwh.txt @@ -0,0 +1,52 @@ + +# Copyright (C) 2005-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Show Whiteout Mode (shwh) +---------------------------------------------------------------------- +Generally aufs hides the name of whiteouts. But in some cases, to show +them is very useful for users. For instance, creating a new middle layer +(branch) by merging existing layers. + +(borrowing aufs1 HOW-TO from a user, Michael Towers) +When you have three branches, +- Bottom: 'system', squashfs (underlying base system), read-only +- Middle: 'mods', squashfs, read-only +- Top: 'overlay', ram (tmpfs), read-write + +The top layer is loaded at boot time and saved at shutdown, to preserve +the changes made to the system during the session. +When larger changes have been made, or smaller changes have accumulated, +the size of the saved top layer data grows. At this point, it would be +nice to be able to merge the two overlay branches ('mods' and 'overlay') +and rewrite the 'mods' squashfs, clearing the top layer and thus +restoring save and load speed. + +This merging is simplified by the use of another aufs mount, of just the +two overlay branches using the 'shwh' option. +# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ + aufs /livesys/merge_union + +A merged view of these two branches is then available at +/livesys/merge_union, and the new feature is that the whiteouts are +visible! +Note that in 'shwh' mode the aufs mount must be 'ro', which will disable +writing to all branches. Also the default mode for all branches is 'ro'. +It is now possible to save the combined contents of the two overlay +branches to a new squashfs, e.g.: +# mksquashfs /livesys/merge_union /path/to/newmods.squash + +This new squashfs archive can be stored on the boot device and the +initramfs will use it to replace the old one at the next boot. --- linux-oracle-5.4.0.orig/Documentation/filesystems/aufs/design/10dynop.txt +++ linux-oracle-5.4.0/Documentation/filesystems/aufs/design/10dynop.txt @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2020 Junjiro R. Okajima +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +Dynamically customizable FS operations +---------------------------------------------------------------------- +Generally FS operations (struct inode_operations, struct +address_space_operations, struct file_operations, etc.) are defined as +"static const", but it never means that FS have only one set of +operation. Some FS have multiple sets of them. For instance, ext2 has +three sets, one for XIP, for NOBH, and for normal. +Since aufs overrides and redirects these operations, sometimes aufs has +to change its behaviour according to the branch FS type. More importantly +VFS acts differently if a function (member in the struct) is set or +not. It means aufs should have several sets of operations and select one +among them according to the branch FS definition. + +In order to solve this problem and not to affect the behaviour of VFS, +aufs defines these operations dynamically. For instance, aufs defines +dummy direct_IO function for struct address_space_operations, but it may +not be set to the address_space_operations actually. When the branch FS +doesn't have it, aufs doesn't set it to its address_space_operations +while the function definition itself is still alive. So the behaviour +itself will not change, and it will return an error when direct_IO is +not set. + +The lifetime of these dynamically generated operation object is +maintained by aufs branch object. When the branch is removed from aufs, +the reference counter of the object is decremented. When it reaches +zero, the dynamically generated operation object will be freed. + +This approach is designed to support AIO (io_submit), Direct I/O and +XIP (DAX) mainly. +Currently this approach is applied to address_space_operations for +regular files only. --- linux-oracle-5.4.0.orig/Documentation/filesystems/directory-locking.rst +++ linux-oracle-5.4.0/Documentation/filesystems/directory-locking.rst @@ -23,13 +23,15 @@ locks victim and calls the method. Locks are exclusive. 4) rename() that is _not_ cross-directory. Locking rules: caller locks -the parent and finds source and target. In case of exchange (with -RENAME_EXCHANGE in flags argument) lock both. In any case, -if the target already exists, lock it. If the source is a non-directory, -lock it. If we need to lock both, lock them in inode pointer order. -Then call the method. All locks are exclusive. -NB: we might get away with locking the the source (and target in exchange -case) shared. +the parent and finds source and target. Then we decide which of the +source and target need to be locked. Source needs to be locked if it's a +non-directory; target - if it's a non-directory or about to be removed. +Take the locks that need to be taken, in inode pointer order if need +to take both (that can happen only when both source and target are +non-directories - the source because it wouldn't be locked otherwise +and the target because mixing directory and non-directory is allowed +only with RENAME_EXCHANGE, and that won't be removing the target). +After the locks had been taken, call the method. All locks are exclusive. 5) link creation. Locking rules: @@ -44,19 +46,22 @@ rules: * lock the filesystem - * lock parents in "ancestors first" order. + * lock parents in "ancestors first" order. If one is not ancestor of + the other, lock the parent of source first. * find source and target. * if old parent is equal to or is a descendent of target fail with -ENOTEMPTY * if new parent is equal to or is a descendent of source fail with -ELOOP - * If it's an exchange, lock both the source and the target. - * If the target exists, lock it. If the source is a non-directory, - lock it. If we need to lock both, do so in inode pointer order. + * Lock both the source and the target provided they exist. If we + need to lock two inodes of different type (dir vs non-dir), we lock + the directory first. If we need to lock two inodes of the same type, + lock them in inode pointer order. + * Lock subdirectories involved (source before target). + * Lock non-directories involved, in inode pointer order. * call the method. -All ->i_rwsem are taken exclusive. Again, we might get away with locking -the the source (and target in exchange case) shared. +All ->i_rwsem are taken exclusive. The rules above obviously guarantee that all directories that are going to be read, modified or removed by method will be locked by caller. @@ -66,8 +71,10 @@ Proof: - First of all, at any moment we have a partial ordering of the - objects - A < B iff A is an ancestor of B. +[XXX: will be updated once we are done massaging the lock_rename()] + First of all, at any moment we have a linear ordering of the + objects - A < B iff (A is an ancestor of B) or (B is not an ancestor + of A and ptr(A) < ptr(B)). That ordering can change. However, the following is true: --- linux-oracle-5.4.0.orig/Documentation/filesystems/ext4/attributes.rst +++ linux-oracle-5.4.0/Documentation/filesystems/ext4/attributes.rst @@ -76,7 +76,7 @@ - Checksum of the extended attribute block. * - 0x14 - \_\_u32 - - h\_reserved[2] + - h\_reserved[3] - Zero. The checksum is calculated against the FS UUID, the 64-bit block number --- linux-oracle-5.4.0.orig/Documentation/filesystems/locking.rst +++ linux-oracle-5.4.0/Documentation/filesystems/locking.rst @@ -95,7 +95,7 @@ mkdir: exclusive unlink: exclusive (both) rmdir: exclusive (both)(see below) -rename: exclusive (all) (see below) +rename: exclusive (both parents, some children) (see below) readlink: no get_link: no setattr: exclusive @@ -113,6 +113,9 @@ Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem exclusive on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. + ->unlink() and ->rename() have ->i_rwsem exclusive on all non-directories + involved. + ->rename() has ->i_rwsem exclusive on any subdirectory that changes parent. See Documentation/filesystems/directory-locking.rst for more detailed discussion of the locking scheme for directory operations. --- linux-oracle-5.4.0.orig/Documentation/filesystems/porting.rst +++ linux-oracle-5.4.0/Documentation/filesystems/porting.rst @@ -850,3 +850,29 @@ d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are very suspect (and won't work in modules). Such uses are very likely to be misspelled d_alloc_anon(). + +--- + +**mandatory** + +[should've been added in 2016] stale comment in finish_open() nonwithstanding, +failure exits in ->atomic_open() instances should *NOT* fput() the file, +no matter what. Everything is handled by the caller. + +--- + +**mandatory** + +If ->rename() update of .. on cross-directory move needs an exclusion with +directory modifications, do *not* lock the subdirectory in question in your +->rename() - it's done by the caller now [that item should've been added in +28eceeda130f "fs: Lock moved directories"]. + +--- + +**mandatory** + +On same-directory ->rename() the (tautological) update of .. is not protected +by any locks; just don't do it if the old parent is the same as the new one. +We really can't lock two subdirectories in same-directory rename - not without +deadlocks. --- linux-oracle-5.4.0.orig/Documentation/filesystems/seq_file.txt +++ linux-oracle-5.4.0/Documentation/filesystems/seq_file.txt @@ -192,6 +192,12 @@ is a reasonable thing to do. The seq_file code will also avoid taking any other locks while the iterator is active. +The iterater value returned by start() or next() is guaranteed to be +passed to a subsequent next() or stop() call. This allows resources +such as locks that were taken to be reliably released. There is *no* +guarantee that the iterator will be passed to show(), though in practice +it often will be. + Formatted output --- linux-oracle-5.4.0.orig/Documentation/filesystems/sysfs.txt +++ linux-oracle-5.4.0/Documentation/filesystems/sysfs.txt @@ -232,12 +232,10 @@ is 4096. - show() methods should return the number of bytes printed into the - buffer. This is the return value of scnprintf(). + buffer. -- show() must not use snprintf() when formatting the value to be - returned to user space. If you can guarantee that an overflow - will never happen you can use sprintf() otherwise you must use - scnprintf(). +- show() should only use sysfs_emit() or sysfs_emit_at() when formatting + the value to be returned to user space. - store() should return the number of bytes used from the buffer. If the entire buffer has been used, just return the count argument. --- linux-oracle-5.4.0.orig/Documentation/filesystems/vfs.rst +++ linux-oracle-5.4.0/Documentation/filesystems/vfs.rst @@ -1173,7 +1173,7 @@ return -ECHILD and it will be called again in ref-walk mode. -``_weak_revalidate`` +``d_weak_revalidate`` called when the VFS needs to revalidate a "jumped" dentry. This is called when a path-walk ends at dentry that was not acquired by doing a lookup in the parent directory. This includes "/", --- linux-oracle-5.4.0.orig/Documentation/firmware-guide/acpi/apei/einj.rst +++ linux-oracle-5.4.0/Documentation/firmware-guide/acpi/apei/einj.rst @@ -168,7 +168,7 @@ 0x00000008 Memory Correctable 0x00000010 Memory Uncorrectable non-fatal # echo 0x12345000 > param1 # Set memory address for injection - # echo $((-1 << 12)) > param2 # Mask 0xfffffffffffff000 - anywhere in this page + # echo 0xfffffffffffff000 > param2 # Mask - anywhere in this page # echo 0x8 > error_type # Choose correctable memory error # echo 1 > error_inject # Inject now --- linux-oracle-5.4.0.orig/Documentation/firmware-guide/acpi/dsd/data-node-references.rst +++ linux-oracle-5.4.0/Documentation/firmware-guide/acpi/dsd/data-node-references.rst @@ -5,7 +5,7 @@ Referencing hierarchical data nodes =================================== -:Copyright: |copy| 2018 Intel Corporation +:Copyright: |copy| 2018, 2021 Intel Corporation :Author: Sakari Ailus ACPI in general allows referring to device objects in the tree only. @@ -52,12 +52,14 @@ Name (NOD0, Package() { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { + Package () { "reg", 0 }, Package () { "random-property", 3 }, } }) Name (NOD1, Package() { ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), Package () { + Package () { "reg", 1 }, Package () { "anothernode", "ANOD" }, } }) @@ -74,7 +76,11 @@ Name (_DSD, Package () { ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { - Package () { "reference", ^DEV0, "node@1", "anothernode" }, + Package () { + "reference", Package () { + ^DEV0, "node@1", "anothernode" + } + }, } }) } --- linux-oracle-5.4.0.orig/Documentation/hwmon/lm90.rst +++ linux-oracle-5.4.0/Documentation/hwmon/lm90.rst @@ -123,6 +123,18 @@ http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497 + * Maxim MAX6654 + + Prefix: 'max6654' + + Addresses scanned: I2C 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, + + 0x4c, 0x4d and 0x4e + + Datasheet: Publicly available at the Maxim website + + https://www.maximintegrated.com/en/products/sensors/MAX6654.html + * Maxim MAX6657 Prefix: 'max6657' @@ -253,6 +265,16 @@ http://www.ti.com/litv/pdf/sbos686 + * Texas Instruments TMP461 + + Prefix: 'tmp461' + + Addresses scanned: I2C 0x48 through 0x4F + + Datasheet: Publicly available at TI website + + https://www.ti.com/lit/gpn/tmp461 + Author: Jean Delvare @@ -301,6 +323,13 @@ * Extended temperature range (breaks compatibility) * Lower resolution for remote temperature +MAX6654: + * Better local resolution + * Selectable address + * Remote sensor type selection + * Extended temperature range + * Extended resolution only available when conversion rate <= 1 Hz + MAX6657 and MAX6658: * Better local resolution * Remote sensor type selection @@ -336,8 +365,8 @@ All temperature values are given in degrees Celsius. Resolution is 1.0 degree for the local temperature, 0.125 degree for the remote -temperature, except for the MAX6657, MAX6658 and MAX6659 which have a -resolution of 0.125 degree for both temperatures. +temperature, except for the MAX6654, MAX6657, MAX6658 and MAX6659 which have +a resolution of 0.125 degree for both temperatures. Each sensor has its own high and low limits, plus a critical limit. Additionally, there is a relative hysteresis value common to both critical --- linux-oracle-5.4.0.orig/Documentation/hwmon/max31790.rst +++ linux-oracle-5.4.0/Documentation/hwmon/max31790.rst @@ -38,6 +38,7 @@ fan[1-12]_input RO fan tachometer speed in RPM fan[1-12]_fault RO fan experienced fault fan[1-6]_target RW desired fan speed in RPM -pwm[1-6]_enable RW regulator mode, 0=disabled, 1=manual mode, 2=rpm mode -pwm[1-6] RW fan target duty cycle (0-255) +pwm[1-6]_enable RW regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode +pwm[1-6] RW read: current pwm duty cycle, + write: target pwm duty cycle (0-255) ================== === ======================================================= --- linux-oracle-5.4.0.orig/Documentation/index.rst +++ linux-oracle-5.4.0/Documentation/index.rst @@ -135,6 +135,14 @@ mic/index scheduler/index +Architecture-agnostic documentation +----------------------------------- + +.. toctree:: + :maxdepth: 2 + + asm-annotations + Architecture-specific documentation ----------------------------------- --- linux-oracle-5.4.0.orig/Documentation/input/joydev/joystick.rst +++ linux-oracle-5.4.0/Documentation/input/joydev/joystick.rst @@ -517,6 +517,7 @@ * AVB Mag Turbo Force * AVB Top Shot Pegasus * AVB Top Shot Force Feedback Racing Wheel +* Boeder Force Feedback Wheel * Logitech WingMan Force * Logitech WingMan Force Wheel * Guillemot Race Leader Force Feedback --- linux-oracle-5.4.0.orig/Documentation/ioctl/ioctl-number.rst +++ linux-oracle-5.4.0/Documentation/ioctl/ioctl-number.rst @@ -301,7 +301,6 @@ 0x89 00-06 arch/x86/include/asm/sockios.h 0x89 0B-DF linux/sockios.h 0x89 E0-EF linux/sockios.h SIOCPROTOPRIVATE range -0x89 E0-EF linux/dn.h PROTOPRIVATE range 0x89 F0-FF linux/sockios.h SIOCDEVPRIVATE range 0x8B all linux/wireless.h 0x8C 00-3F WiNRADiO driver --- linux-oracle-5.4.0.orig/Documentation/kbuild/index.rst +++ linux-oracle-5.4.0/Documentation/kbuild/index.rst @@ -19,6 +19,7 @@ issues reproducible-builds + llvm .. only:: subproject and html --- linux-oracle-5.4.0.orig/Documentation/kbuild/kbuild.rst +++ linux-oracle-5.4.0/Documentation/kbuild/kbuild.rst @@ -262,3 +262,8 @@ These two variables allow to override the user@host string displayed during boot and in /proc/version. The default value is the output of the commands whoami and host, respectively. + +LLVM +---- +If this variable is set to 1, Kbuild will use Clang and LLVM utilities instead +of GCC and GNU binutils to build the kernel. --- linux-oracle-5.4.0.orig/Documentation/kbuild/llvm.rst +++ linux-oracle-5.4.0/Documentation/kbuild/llvm.rst @@ -0,0 +1,87 @@ +============================== +Building Linux with Clang/LLVM +============================== + +This document covers how to build the Linux kernel with Clang and LLVM +utilities. + +About +----- + +The Linux kernel has always traditionally been compiled with GNU toolchains +such as GCC and binutils. Ongoing work has allowed for `Clang +`_ and `LLVM `_ utilities to be +used as viable substitutes. Distributions such as `Android +`_, `ChromeOS +`_, and `OpenMandriva +`_ use Clang built kernels. `LLVM is a +collection of toolchain components implemented in terms of C++ objects +`_. Clang is a front-end to LLVM that +supports C and the GNU C extensions required by the kernel, and is pronounced +"klang," not "see-lang." + +Clang +----- + +The compiler used can be swapped out via `CC=` command line argument to `make`. +`CC=` should be set when selecting a config and during a build. + + make CC=clang defconfig + + make CC=clang + +Cross Compiling +--------------- + +A single Clang compiler binary will typically contain all supported backends, +which can help simplify cross compiling. + + ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make CC=clang + +`CROSS_COMPILE` is not used to prefix the Clang compiler binary, instead +`CROSS_COMPILE` is used to set a command line flag: `--target `. For +example: + + clang --target aarch64-linux-gnu foo.c + +LLVM Utilities +-------------- + +LLVM has substitutes for GNU binutils utilities. Kbuild supports `LLVM=1` +to enable them. + + make LLVM=1 + +They can be enabled individually. The full list of the parameters: + + make CC=clang LD=ld.lld AR=llvm-ar NM=llvm-nm STRIP=llvm-strip \\ + OBJCOPY=llvm-objcopy OBJDUMP=llvm-objdump OBJSIZE=llvm-size \\ + READELF=llvm-readelf HOSTCC=clang HOSTCXX=clang++ HOSTAR=llvm-ar \\ + HOSTLD=ld.lld + +Currently, the integrated assembler is disabled by default. You can pass +`LLVM_IAS=1` to enable it. + +Getting Help +------------ + +- `Website `_ +- `Mailing List `_: +- `Issue Tracker `_ +- IRC: #clangbuiltlinux on chat.freenode.net +- `Telegram `_: @ClangBuiltLinux +- `Wiki `_ +- `Beginner Bugs `_ + +Getting LLVM +------------- + +- http://releases.llvm.org/download.html +- https://github.com/llvm/llvm-project +- https://llvm.org/docs/GettingStarted.html +- https://llvm.org/docs/CMake.html +- https://apt.llvm.org/ +- https://www.archlinux.org/packages/extra/x86_64/llvm/ +- https://github.com/ClangBuiltLinux/tc-build +- https://github.com/ClangBuiltLinux/linux/wiki/Building-Clang-from-source +- https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/ --- linux-oracle-5.4.0.orig/Documentation/kbuild/makefiles.rst +++ linux-oracle-5.4.0/Documentation/kbuild/makefiles.rst @@ -1115,23 +1115,6 @@ In this example, extra-y is used to list object files that shall be built, but shall not be linked as part of built-in.a. - header-test-y - - header-test-y specifies headers (`*.h`) in the current directory that - should be compile tested to ensure they are self-contained, - i.e. compilable as standalone units. If CONFIG_HEADER_TEST is enabled, - this builds them as part of extra-y. - - header-test-pattern-y - - This works as a weaker version of header-test-y, and accepts wildcard - patterns. The typical usage is:: - - header-test-pattern-y += *.h - - This specifies all the files that matches to `*.h` in the current - directory, but the files in 'header-test-' are excluded. - 6.7 Commands useful for building a boot image --------------------------------------------- --- linux-oracle-5.4.0.orig/Documentation/kbuild/modules.rst +++ linux-oracle-5.4.0/Documentation/kbuild/modules.rst @@ -470,9 +470,9 @@ The syntax of the Module.symvers file is:: - + - 0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL + 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE The fields are separated by tabs and values may be empty (e.g. if no namespace is defined for an exported symbol). --- linux-oracle-5.4.0.orig/Documentation/kernel-hacking/locking.rst +++ linux-oracle-5.4.0/Documentation/kernel-hacking/locking.rst @@ -976,7 +976,7 @@ while (list) { struct foo *next = list->next; - del_timer(&list->timer); + timer_delete(&list->timer); kfree(list); list = next; } @@ -990,7 +990,7 @@ the element (which has already been freed!). This can be avoided by checking the result of -:c:func:`del_timer()`: if it returns 1, the timer has been deleted. +:c:func:`timer_delete()`: if it returns 1, the timer has been deleted. If 0, it means (in this case) that it is currently running, so we can do:: @@ -999,7 +999,7 @@ while (list) { struct foo *next = list->next; - if (!del_timer(&list->timer)) { + if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; @@ -1014,9 +1014,13 @@ Another common problem is deleting timers which restart themselves (by calling :c:func:`add_timer()` at the end of their timer function). Because this is a fairly common case which is prone to races, you should -use :c:func:`del_timer_sync()` (``include/linux/timer.h``) to -handle this case. It returns the number of times the timer had to be -deleted before we finally stopped it from adding itself back in. +use :c:func:`timer_delete_sync()` (``include/linux/timer.h``) to +handle this case. + +Before freeing a timer, timer_shutdown() or timer_shutdown_sync() should be +called which will keep it from being rearmed. Any subsequent attempt to +rearm the timer will be silently ignored by the core code. + Locking Speed ============= @@ -1344,7 +1348,7 @@ - :c:func:`kfree()` -- :c:func:`add_timer()` and :c:func:`del_timer()` +- :c:func:`add_timer()` and :c:func:`timer_delete()` Mutex API reference =================== --- linux-oracle-5.4.0.orig/Documentation/kmsg/IPVS +++ linux-oracle-5.4.0/Documentation/kmsg/IPVS @@ -0,0 +1,81 @@ +/*? Text: "%s(): NULL arg\n" */ +/*? Text: "%s(): NULL scheduler_name\n" */ +/*? Text: "%s(): [%s] pe already existed in the system\n" */ +/*? Text: "%s(): [%s] pe already linked\n" */ +/*? Text: "%s(): [%s] pe is not in the list. failed\n" */ +/*? Text: "%s(): [%s] scheduler already existed in the system\n" */ +/*? Text: "%s(): [%s] scheduler already linked\n" */ +/*? Text: "%s(): [%s] scheduler is not in the list. failed\n" */ +/*? Text: "%s(): done error\n" */ +/*? Text: "%s(): init error\n" */ +/*? Text: "%s(): lower threshold is higher than upper threshold\n" */ +/*? Text: "%s(): no memory\n" */ +/*? Text: "%s(): request for already hashed, called from %pF\n" */ +/*? Text: "%s(): request for unhash flagged, called from %pF\n" */ +/*? Text: "%s(): server weight less than zero\n" */ +/*? Text: "%s: %s %pI4:%d - %s\n" */ +/*? Text: "%s: %s [%pI6]:%d - %s\n" */ +/*? Text: "%s: %s [%pI6c]:%d - %s\n" */ +/*? Text: "%s: FWM %u 0x%08X - %s\n" */ +/*? Text: "%s: enter\n" */ +/*? Text: "%s: loaded support on port[%d] = %d\n" */ +/*? Text: "BACKUP v0, Dropping buffer bogus conn options\n" */ +/*? Text: "BACKUP v0, bogus conn\n" */ +/*? Text: "BACKUP, Dropping buffer, Err: %d in decoding\n" */ +/*? Text: "BACKUP, Dropping buffer, Unknown version %d\n" */ +/*? Text: "BACKUP, Dropping buffer, msg > buffer\n" */ +/*? Text: "BACKUP, Dropping buffer, to small\n" */ +/*? Text: "BACKUP, Invalid PE parameters\n" */ +/*? Text: "BUG control DEL with n=0 : %s:%d to %s:%d\n" */ +/*? Text: "Connection hash table configured (size=%d, memory=%ldKbytes)\n" */ +/*? Text: "Error binding address of the mcast interface\n" */ +/*? Text: "Error binding to the multicast addr\n" */ +/*? Text: "Error connecting to the multicast addr\n" */ +/*? Text: "Error during creation of socket; terminating\n" */ +/*? Text: "Error joining to the multicast group\n" */ +/*? Text: "Error setting outbound mcast interface\n" */ +/*? Text: "Failed to stop Backup Daemon\n" */ +/*? Text: "Failed to stop Master Daemon\n" */ +/*? Text: "Registered protocols (%s)\n" */ +/*? Text: "SYNC, connection pe_data invalid\n" */ +/*? Text: "Schedule: port zero only supported in persistent services, check your ipvs configuration\n" */ +/*? Text: "Scheduler module ip_vs_%s not found\n" */ +/*? Text: "There is no net ptr to find in the skb in %s() line:%d\n" */ +/*? Text: "UDP no ns data\n" */ +/*? Text: "You probably need to specify IP address on multicast interface.\n" */ +/*? Text: "[%s] pe registered.\n" */ +/*? Text: "[%s] pe unregistered.\n" */ +/*? Text: "[%s] scheduler registered.\n" */ +/*? Text: "[%s] scheduler unregistered.\n" */ +/*? Text: "can't register hooks.\n" */ +/*? Text: "can't register netlink/ioctl.\n" */ +/*? Text: "can't setup connection table.\n" */ +/*? Text: "can't setup control.\n" */ +/*? Text: "cannot register Generic Netlink interface.\n" */ +/*? Text: "cannot register sockopt.\n" */ +/*? Text: "get_ctl: len %u < %u\n" */ +/*? Text: "ip_vs_send_async error %d\n" */ +/*? Text: "ip_vs_sync_buff_create failed.\n" */ +/*? Text: "ipvs loaded.\n" */ +/*? Text: "ipvs unloaded.\n" */ +/*? Text: "length: %u != %u\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "not enough space in Netlink message\n" */ +/*? Text: "persistence engine module ip_vs_pe_%s not found\n" */ +/*? Text: "receiving message error\n" */ +/*? Text: "request control ADD for already controlled: %s:%d to %s:%d\n" */ +/*? Text: "request control DEL for uncontrolled: %s:%d to %s:%d\n" */ +/*? Text: "set_ctl: invalid protocol: %d %pI4:%d %s\n" */ +/*? Text: "set_ctl: len %u != %u\n" */ +/*? Text: "shouldn't reach here, because the box is on the half connection in the tun/dr module.\n" */ +/*? Text: "stopping backup sync thread %d ...\n" */ +/*? Text: "stopping master sync thread %d ...\n" */ +/*? Text: "sync thread started: state = BACKUP, mcast_ifn = %s, syncid = %d\n" */ +/*? Text: "sync thread started: state = MASTER, mcast_ifn = %s, syncid = %d\n" */ +/*? Text: "unknown Generic Netlink command\n" */ +/*? Text: "sync thread started: state = MASTER, mcast_ifn = %s, syncid = %d, id = %d\n" */ +/*? Text: "sync thread started: state = BACKUP, mcast_ifn = %s, syncid = %d, id = %d\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "Unknown mcast interface: %s\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/aes_s390 +++ linux-oracle-5.4.0/Documentation/kmsg/s390/aes_s390 @@ -0,0 +1,45 @@ +/*? + * Text: "Allocating XTS fallback algorithm %s failed\n" + * Severity: Error + * Parameter: + * @1: algorithm name + * Description: + * The aes_s390 module failed to allocate a software fallback for the AES + * modes that are not supported by the hardware. A possible reason for this + * problem is that the aes_generic module that provides the fallback + * algorithms is not available. + * User action: + * Ensure that the aes_generic module is available and loaded and reload + * the aes_s390 module. + */ + +/*? + * Text: "Allocating AES fallback algorithm %s failed\n" + * Severity: Error + * Parameter: + * @1: algorithm name + * Description: + * The advanced encryption standard (AES) algorithm includes three modes with + * 128-bit, 192-bit, and 256-bit keys. Your hardware system only provides + * hardware acceleration for the 128-bit mode. The aes_s390 module failed to + * allocate a software fallback for the AES modes that are not supported by the + * hardware. A possible reason for this problem is that the aes_generic module + * that provides the fallback algorithms is not available. + * User action: + * Use the 128-bit mode only or ensure that the aes_generic module is available + * and loaded and reload the aes_s390 module. + */ + +/*? + * Text: "AES hardware acceleration is only available for 128-bit keys\n" + * Severity: Informational + * Description: + * The advanced encryption standard (AES) algorithm includes three modes with + * 128-bit, 192-bit, and 256-bit keys. Your hardware system only provides + * hardware acceleration for the 128-bit key mode. The aes_s390 module + * will use the less performant software fallback algorithm for the 192-bit + * and 256-bit key modes. + * User action: + * None. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/af_iucv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/af_iucv @@ -0,0 +1,23 @@ +/*? + * Text: "Application %s on z/VM guest %s exceeds message limit\n" + * Severity: Error + * Parameter: + * @1: application name + * @2: z/VM user ID + * Description: + * Messages or packets destined for the application have accumulated and + * reached the maximum value. The default for the message limit is 65535. + * You can specify a different limit as the value for MSGLIMIT within + * the IUCV statement of the z/VM virtual machine on which the application + * runs. + * User action: + * Ensure that you do not send data faster than the application retrieves + * them. Ensure that the message limit on the z/VM guest virtual machine + * on which the application runs is high enough. + */ + +/*? Text: "Attempt to release alive iucv socket %p\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/ap +++ linux-oracle-5.4.0/Documentation/kmsg/s390/ap @@ -0,0 +1,49 @@ +/*? + * Text: "%d is not a valid cryptographic domain\n" + * Severity: Warning + * Parameter: + * @1: AP domain index + * Description: + * The cryptographic domain specified for the 'domain=' module or kernel + * parameter must be an integer in the range 0 to 15. + * User action: + * Reload the cryptographic device driver with a correct module parameter. + * If the device driver has been compiled into the kernel, correct the value + * in the kernel parameter line and reboot Linux. + */ + +/*? + * Text: "The hardware system does not support AP instructions\n" + * Severity: Warning + * Description: + * The ap module addresses AP adapters through AP instructions. The hardware + * system on which the Linux instance runs does not support AP instructions. + * The ap module cannot detect any AP adapters. + * User action: + * Load the ap module only if your Linux instance runs on hardware that + * supports AP instructions. If the ap module has been compiled into the kernel, + * ignore this message. + */ + +/*? + * Text: "Registering adapter interrupts for AP device %02x.%04x failed\n" + * Severity: Error + * Parameter: + * @1: AP device ID + * @2: AP queue + * Description: + * The hardware system supports AP adapter interrupts but failed to enable + * an adapter for interrupts. Possible causes for this error are: + * i) The AP adapter firmware does not support AP interrupts. + * ii) An AP adapter firmware update to a firmware level that supports AP + * adapter interrupts failed. + * iii) The AP adapter firmware has been successfully updated to a level that + * supports AP interrupts but the new firmware has not been activated. + * User action: + * Ensure that the firmware on your AP adapters support AP interrupts and that + * any firmware updates have completed successfully. If necessary, deconfigure + * your cryptographic adapters and reconfigure them to ensure that any firmware + * updates become active, then reload the ap module. If the ap module has been + * compiled into the kernel, reboot Linux. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/appldata +++ linux-oracle-5.4.0/Documentation/kmsg/s390/appldata @@ -0,0 +1,91 @@ +/*? + * Text: "Starting the data collection for %s failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: appldata module + * @2: return code + * Description: + * The specified data collection module used the z/VM diagnose call + * DIAG 0xDC to start writing data. z/VM returned an error and the data + * collection could not start. If the return code is 5, your z/VM guest + * virtual machine is not authorized to write data records. + * User action: + * If the return code is 5, ensure that your z/VM guest virtual machine's + * entry in the z/VM directory includes the OPTION APPLMON statement. + * For other return codes see the section about DIAGNOSE Code X'DC' + * in "z/VM CP Programming Services". + */ + +/*? + * Text: "Stopping the data collection for %s failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: appldata module + * @2: return code + * Description: + * The specified data collection module used the z/VM diagnose call DIAG 0xDC + * to stop writing data. z/VM returned an error and the data collection + * continues. + * User action: + * See the section about DIAGNOSE Code X'DC' in "z/VM CP Programming Services". + */ + +/*? + * Text: "Starting a new OS data collection failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * After a CPU hotplug event, the record size for the running operating + * system data collection is no longer correct. The appldata_os module tried + * to start a new data collection with the correct record size but received + * an error from the z/VM diagnose call DIAG 0xDC. Any data collected with + * the current record size might be faulty. + * User action: + * Start a new data collection with the cappldata_os module. For information + * about starting data collections see "Device Drivers, Features, and + * Commands". For information about the return codes see the section about + * DIAGNOSE Code X'DC' in "z/VM CP Programming Services". + */ + +/*? + * Text: "Stopping a faulty OS data collection failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * After a CPU hotplug event, the record size for the running operating + * system data collection is no longer correct. The appldata_os module tried + * to stop the faulty data collection but received an error from the z/VM + * diagnose call DIAG 0xDC. Any data collected with the current record size + * might be faulty. + * User action: + * Try to restart appldata_os monitoring. For information about stopping + * and starting data collections see "Device Drivers, Features, and + * Commands". For information about the return codes see the section about + * DIAGNOSE Code X'DC' in "z/VM CP Programming Services". + */ + +/*? + * Text: "Maximum OS record size %i exceeds the maximum record size %i\n" + * Severity: Error + * Parameter: + * @1: no of bytes + * @2: no of bytes + * Description: + * The OS record size grows with the number of CPUs and is adjusted by the + * appldata_os module in response to CPU hotplug events. For more than 110 + * CPUs the record size would exceed the maximum record size of 4024 bytes + * that is supported by the z/VM hypervisor. To prevent the maximum supported + * record size from being exceeded while data collection is in progress, + * you cannot load the appldata_os module on Linux instances that are + * configured for a maximum of more than 110 CPUs. + * User action: + * If you do not want to collect operating system data, you can ignore this + * message. If you want to collect operating system data, reconfigure your + * Linux instance to support less than 110 CPUs. + */ + +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/bpf_jit +++ linux-oracle-5.4.0/Documentation/kmsg/s390/bpf_jit @@ -0,0 +1,16 @@ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ + +/*? + * Text: "Unknown opcode %02x\n" + * Severity: Error + * Parameter: + * @1: Instruction opcode + * Description: + * The BPF JIT compiler has found an unknown instruction in the BPF program + * and therefore stops the compilation. As a fallback, the interpreter is used. + * User action: + * Report this problem and the error message to your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/cio +++ linux-oracle-5.4.0/Documentation/kmsg/s390/cio @@ -0,0 +1,247 @@ +/*? + * Text: "%s is not a valid device for the cio_ignore kernel parameter\n" + * Severity: Warning + * Parameter: + * @1: device bus-ID + * Description: + * The device specification for the cio_ignore kernel parameter is + * syntactically incorrect or specifies an unknown device. This device is not + * excluded from being sensed and analyzed. + * User action: + * Correct your device specification in the kernel parameter line to have the + * device excluded when you next reboot Linux. You can write the correct + * device specification to /proc/cio_ignore to add the device to the list of + * devices to be excluded. This does not immediately make the device + * inaccessible but the device is ignored if it disappears and later reappears. + */ + +/*? + * Text: "0.%x.%04x to 0.%x.%04x is not a valid range for cio_ignore\n" + * Severity: Warning + * Parameter: + * @1: from subchannel set ID + * @2: from device number + * @3: to subchannel set ID + * @4: to device number + * Description: + * The device range specified for the cio_ignore kernel parameter is + * syntactically incorrect. No devices specified with this range are + * excluded from being sensed and analyzed. + * User action: + * Correct your range specification in the kernel parameter line to have the + * range of devices excluded when you next reboot Linux. You can write the + * correct range specification to /proc/cio_ignore to add the range of devices + * to the list of devices to be excluded. This does not immediately make the + * devices in the range inaccessible but any of these devices are ignored if + * they disappear and later reappear. + */ + +/*? + * Text: "Processing %s for channel path %x.%02x\n" + * Severity: Notice + * Parameter: + * @1: configuration change + * @2: channel subsystem ID + * @3: CHPID + * Description: + * A configuration change is in progress for the given channel path. + * User action: + * None. + */ + +/*? + * Text: "No CCW console was found\n" + * Severity: Warning + * Description: + * Linux did not find the expected CCW console and tries to use an alternative + * console. A possible reason why the console was not found is that the console + * has been specified in the cio_ignore list. + * User action: + * None, if an appropriate alternative console has been found, and you want + * to use this alternative console. If you want to use the CCW console, ensure + * that is not specified in the cio_ignore list, explicitly specify the console + * with the 'condev=' kernel parameter, and reboot Linux. + */ + +/*? + * Text: "Channel measurement facility initialized using format %s (mode %s)\n" + * Severity: Informational + * Parameter: + * @1: format + * @2: mode + * Description: + * The channel measurement facility has been initialized successfully. + * Format 'extended' should be used for z990 and later mainframe systems. + * Format 'basic' is intended for earlier mainframes. Mode 'autodetected' means + * that the format has been set automatically. Mode 'parameter' means that the + * format has been set according to the 'format=' kernel parameter. + * User action: + * None. + */ + +/*? + * Text: "The CSS device driver initialization failed with errno=%d\n" + * Severity: Alert + * Parameter: + * @1: Return code + * Description: + * The channel subsystem bus could not be established. + * User action: + * See the errno man page to find out what caused the problem. + */ + /*? Text: "%s: Got subchannel machine check but no sch_event handler provided.\n" */ + +/*? + * Text: "%s: Setting the device online failed because it is boxed\n" + * Severity: Warning + * Parameter: + * @1: Device bus-ID + * Description: + * Initialization of a device did not complete because it did not respond in + * time or it was reserved by another operating system. + * User action: + * Make sure that the device is working correctly, then try again to set it + * online. For devices that support the reserve/release mechanism (for example + * DASDs), you can try to override the reservation of the other system by + * writing 'force' to the 'online' sysfs attribute of the affected device. + */ + +/*? + * Text: "%s: Setting the device online failed because it is not operational\n" + * Severity: Warning + * Parameter: + * @1: Device bus-ID + * Description: + * Initialization of a device did not complete because it is not present or + * not operational. + * User action: + * Make sure that the device is present and working correctly, then try again + * to set it online. + */ + +/*? + * Text: "%s: The device stopped operating while being set offline\n" + * Severity: Warning + * Parameter: + * @1: Device bus-ID + * Description: + * While the device was set offline, it was not present or not operational. + * The device is now inactive, but setting it online again might fail. + * User action: + * None. + */ + +/*? + * Text: "%s: The device entered boxed state while being set offline\n" + * Severity: Warning + * Parameter: + * @1: Device bus-ID + * Description: + * While the device was set offline, it did not respond in time or it was + * reserved by another operating system. The device is now inactive, but + * setting it online again might fail. + * User action: + * None. + */ + +/*? + * Text: "Logging for subchannel 0.%x.%04x failed with errno=%d\n" + * Severity: Warning + * Parameter: + * @1: subchannel set ID + * @2: subchannel number + * @3: errno + * Description: + * Capturing model-dependent logs and traces could not be triggered for the + * specified subchannel. + * User action: + * See the errno man page to find out what caused the problem. + */ + +/*? + * Text: "Logging for subchannel 0.%x.%04x was triggered\n" + * Severity: Notice + * Parameter: + * @1: subchannel set ID + * @2: subchannel number + * Description: + * Model-dependent logs and traces may be captured for the specified + * subchannel. + * User action: + * None. + */ + +/*? + * Text: "%s: No interrupt was received within %lus (CS=%02x, DS=%02x, CHPID=%x.%02x)\n" + * Severity: Warning + * Parameter: + * @1: device number + * @2: timeout value + * @3: channel status + * @4: device status + * @5: channel subsystem ID + * @6: CHPID + * Description: + * Internal I/Os are used by the common I/O layer to ensure that devices are + * operational and accessible. + * The common I/O layer did not receive an interrupt for an internal I/O + * during the specified timeout period. + * As a result, the device might assume a state that makes the device + * unusable to Linux until the problem is resolved. + * User action: + * Make sure that the device is working correctly and try the action again. + */ + +/*? + * Text: "Link stopped: RS=%02x RSID=%04x IC=%02x IUPARAMS=%s IUNODEID=%s AUPARAMS=%s AUNODEID=%s\n" + * Severity: Error + * Parameter: + * @1: reporting source + * @2: reporting source ID + * @3: incident code + * @4: incident unit parameters + * @5: incident unit node ID + * @6: attached unit parameters + * @7: attached unit node ID + * + * Description: + * A hardware error has occurred. A unit at one end of an interface + * link has detected a failure in the link or in one of the units attached to + * the link. As a result, data transfer across the link has stopped. In the + * message text, the node IDs of involved units are represented in the + * following format: TTTTTT/MDL,MMM.PPSSSSSSSSSSSS,XXXX where TTTTTT refers to + * the machine type, MDL the model number, MMM the manufacturer, PP the + * manufacturing plant, SSSSSSSSSSSS the unit sequence number and XXXX the + * machine type-dependent physical interface number. If no data is available + * for the unit parameters or node ID field, "n/a" is used instead. + * + * User action: + * Report the problem to your support organization. + */ + +/*? + * Text: "Link degraded: RS=%02x RSID=%04x IC=%02x IUPARAMS=%s IUNODEID=%s AUPARAMS=%s AUNODEID=%s\n" + * Severity: Warning + * Parameter: + * @1: reporting source + * @2: reporting source ID + * @3: incident code + * @4: incident unit parameters + * @5: incident unit node ID + * @6: attached unit parameters + * @7: attached unit node ID + * Description: + * A hardware error has occurred. A unit at one end of an interface + * link has detected a failure in the link or in one of the units attached to + * the link. As a result, data transfer across the link is degraded. In the + * message text, the node IDs of involved units are represented in the + * following format: TTTTTT/MDL,MMM.PPSSSSSSSSSSSS,XXXX where TTTTTT refers to + * the machine type, MDL the model number, MMM the manufacturer, PP the + * manufacturing plant, SSSSSSSSSSSS the unit sequence number and XXXX the + * machine type-dependent physical interface number. If no data is available + * for the unit parameters or node ID field, "n/a" is used instead. + * + * User action: + * Report the problem to your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/cpcmd +++ linux-oracle-5.4.0/Documentation/kmsg/s390/cpcmd @@ -0,0 +1,16 @@ +/*? + * Text: "The cpcmd kernel function failed to allocate a response buffer\n" + * Severity: Warning + * Description: + * IPL code, console detection, and device drivers like vmcp or vmlogrdr use + * the cpcmd kernel function to send commands to the z/VM control program (CP). + * If a program that uses the cpcmd function does not allocate a contiguous + * response buffer below 2 GB guest real storage, cpcmd creates a bounce buffer + * to be used as the response buffer. Because of low memory or memory + * fragmentation, cpcmd could not create the bounce buffer. + * User action: + * Look for related page allocation failure messages and at the stack trace to + * find out which program or operation failed. Free some memory and retry the + * failed operation. Consider allocating more memory to your z/VM guest virtual + * machine. + */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/cpu +++ linux-oracle-5.4.0/Documentation/kmsg/s390/cpu @@ -0,0 +1,46 @@ +/*? + * Text: "%d configured CPUs, %d standby CPUs\n" + * Severity: Informational + * Parameter: + * @1: number of configured CPUs + * @2: number of standby CPUs + * Description: + * The kernel detected the given number of configured and standby CPUs. + * User action: + * None. + */ + +/*? + * Text: "The CPU configuration topology of the machine is:" + * Severity: Informational + * Description: + * The first six values of the topology information represent fields Mag6 to + * Mag1 of system-information block (SYSIB) 15.1.2. These fields specify the + * maximum numbers of topology-list entries (TLE) at successive topology nesting + * levels. The last value represents the MNest value of SYSIB 15.1.2 which + * specifies the maximum possible nesting that can be configured through + * dynamic changes. For details see the SYSIB 15.1.2 information in the + * "Principles of Operation." + * User action: + * None. + */ + +/*? + * Text: "CPU %i exceeds the maximum %i and is excluded from the dump\n" + * Severity: Warning + * Parameter: + * @1: CPU number + * @2: maximum CPU number + * Description: + * The Linux kernel is used as a system dumper but it runs on more CPUs than + * it has been compiled for with the CONFIG_NR_CPUS kernel configuration + * option. The system dump will be created but information on one or more + * CPUs will be missing. + * User action: + * Update the system dump kernel to a newer version that supports more + * CPUs or reduce the number of installed CPUs and reproduce the problem + * that should be analyzed. If you send the system dump that prompted this + * message to a support organization, be sure to communicate that the dump + * does not include all CPU information. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/cpum_cf +++ linux-oracle-5.4.0/Documentation/kmsg/s390/cpum_cf @@ -0,0 +1,68 @@ +/*? + * Text: "Enabling the performance measuring unit failed with rc=%x\n" + * Severity: Error + * Parameter: + * @1: error condition + * Description: + * The device driver failed to enable CPU counter sets with the + * load counter controls (lcctl) instruction. + * See the section about lcctl in "The Load-Program-Parameter and the CPU-Measurement + * Facilities", SA23-2260, for an explanation of the error conditions. + * User action: + * Stop the performance measurement programs and try again. + */ + +/*? + * Text: "Disabling the performance measuring unit failed with rc=%x\n" + * Severity: Error + * Parameter: + * @1: error condition + * Description: + * The device driver failed to disable CPU counter sets with the + * load counter controls (lcctl) instruction. + * See the section about lcctl in "The Load-Program-Parameter and the CPU-Measurement + * Facilities", SA23-2260, for an explanation of the error conditions. + * User action: + * Stop the performance measurement programs and try again. + */ + +/*? + * Text: "Registering the cpum_cf PMU failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: error code + * Description: + * The device driver could not register the Performance Measurement Unit (PMU) + * for the CPU-measurement counter facility. + * A possible cause of this problem is memory constraints. + * User action: + * If the error code is -12 (ENOMEM), consider assigning more memory + * to your Linux instance. + */ + +/*? + * Text: "CPU[%i] Counter data was lost\n" + * Severity: Error + * Parameter: + * @1: cpu number + * Description: + * CPU counter data was lost because of machine internal + * high-priority activities. + * User action: + * None. + */ + +/*? + * Text: "Registering for CPU-measurement alerts failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: error code + * Description: + * The device driver could not register to receive CPU-measurement alerts. + * Alerts make you aware of measurement errors. + * A possible cause of this problem is memory constraints. + * User action: + * If the error code is -12 (ENOMEM), consider assigning more memory + * to your Linux instance. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/cpum_sf +++ linux-oracle-5.4.0/Documentation/kmsg/s390/cpum_sf @@ -0,0 +1,104 @@ +/*? + * Text: "The sampling buffer limits have changed to: min=%lu max=%lu (diag=x%lu)\n" + * Severity: Informational + * Parameter: + * @1: minimum size in sample-data-blocks + * @2: maximum size in sample-data-blocks + * @3: size factor for buffering diagnostic-sampling data entries + * Description: + * The minimum or maximum size limit for the sampling facility buffer was + * changed. The change is effective immediately. + * User action: + * None. + */ + +/*? + * Text: "Switching off the sampling facility failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: error condition + * Description: + * The CPU-measurement sampling facility could not be switched off and continues + * to run. For details, see LOAD SAMPLING CONTROLS in + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * If this problem persists, reboot your Linux instance. + */ + +/*? + * Text: "Sample data was lost\n" + * Severity: Error + * Description: + * Sample data was lost because of machine-internal high-priority activities. + * The sampling facility is stopped. + * User action: + * End all performance measurement sessions. Discard the measurement data, + * which are likely to be flawed. Repeat your measurements. + * If the problem persists, contact your hardware administrator. + */ + +/*? + * Text: "Sampling facility support for perf is not available: reason=%04x\n" + * Severity: Error + * Parameter: + * @1: reason code + * Description: + * The device driver could not initialize the sampling facility support. + * Possible reason codes are: + * 0001: The device driver failed to query CPU-measurement sampling facility + * information. + * + * 0002: The device driver does not support the basic-sampling function that + * is available on the LPAR within which the Linux instance runs. + * + * 0003: The device driver could not register to receive CPU-measurement alerts. + * A possible cause of this problem is memory constraints. + * + * 0004: The device driver could not register the Performance Measurement Unit + * (PMU) for the CPU-measurement sampling facility. + * A possible cause of this problem is memory constraints. + * User action: + * Consider assigning more memory to your Linux instance. + */ + +/*? + * Text: "Loading sampling controls failed: op=%i err=%i\n" + * Severity: Error + * Parameter: + * @1: Type of operation + * @2: Error condition + * Description: + * The sampling facility support could not load sampling controls to enable + * (operation type 1) or disable (operation type 2) the CPU-measurement sampling + * facility. For details of the error condition, see LOAD SAMPLING CONTROLS in + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * If the problem persists, reboot your Linux instance. + */ + +/*? + * Text: "A sampling buffer entry is incorrect (alert=0x%x)\n" + * Severity: Error + * Parameter: + * @1: Alert code + * Description: + * An incorrect sampling facility buffer entry was detected. The alert code + * indicates the root cause, for example, an incorrect entry address or an + * incorrect sample-data-block-table entry. + * User action: + * End active performance measurement sessions, for example, perf processes. If + * the problem persists, reboot your Linux instance. + */ + +/*? + * Text: "Registering for s390dbf failed\n" + * Severity: Error + * Description: + * The device driver failed to register for the s390 debug feature. You will + * not receive any debug information. A possible cause of this problem is + * memory constraints. + * User action: + * Consider assigning more memory + * to your Linux instance. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/crc32-vx +++ linux-oracle-5.4.0/Documentation/kmsg/s390/crc32-vx @@ -0,0 +1 @@ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/ctcm +++ linux-oracle-5.4.0/Documentation/kmsg/s390/ctcm @@ -0,0 +1,202 @@ +/*? + * Text: "%s: An I/O-error occurred on the CTCM device\n" + * Severity: Error + * Parameter: + * @1: bus ID of the CTCM device + * Description: + * An I/O error was detected on one of the subchannels of the CTCM device. + * Depending on the error, the CTCM device driver might attempt an automatic + * recovery. + * User action: + * Check the status of the CTCM device, for example, with ifconfig. If the + * device is not operational, perform a manual recovery. See "Device Drivers, + * Features, and Commands" for details about how to recover a CTCM device. + */ + +/*? + * Text: "%s: An adapter hardware operation timed out\n" + * Severity: Error + * Parameter: + * @1: bus ID of the CTCM device + * Description: + * The CTCM device uses an adapter to physically connect to its communication + * peer. An operation on this adapter timed out. + * User action: + * Check the status of the CTCM device, for example, with ifconfig. If the + * device is not operational, perform a manual recovery. See "Device Drivers, + * Features, and Commands" for details about how to recover a CTCM device. + */ + +/*? + * Text: "%s: An error occurred on the adapter hardware\n" + * Severity: Error + * Parameter: + * @1: bus ID of the CTCM device + * Description: + * The CTCM device uses an adapter to physically connect to its communication + * peer. An operation on this adapter returned an error. + * User action: + * Check the status of the CTCM device, for example, with ifconfig. If the + * device is not operational, perform a manual recovery. See "Device Drivers, + * Features, and Commands" for details about how to recover a CTCM device. + */ + +/*? + * Text: "%s: The communication peer has disconnected\n" + * Severity: Notice + * Parameter: + * @1: channel ID + * Description: + * The remote device has disconnected. Possible reasons are that the remote + * interface has been closed or that the operating system instance with the + * communication peer has been rebooted or shut down. + * User action: + * Check the status of the peer device. Ensure that the peer operating system + * instance is running and that the peer interface is operational. + */ + +/*? + * Text: "%s: The remote operating system is not available\n" + * Severity: Notice + * Parameter: + * @1: channel ID + * Description: + * The operating system instance with the communication peer has disconnected. + * Possible reasons are that the operating system instance has been rebooted + * or shut down. + * User action: + * Ensure that the peer operating system instance is running and that the peer + * interface is operational. + */ + +/*? + * Text: "%s: The adapter received a non-specific IRQ\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the CTCM device + * Description: + * The adapter hardware used by the CTCM device received an IRQ that cannot + * be mapped to a particular device. This is a hardware problem. + * User action: + * Check the status of the CTCM device, for example, with ifconfig. Check if + * the connection to the remote device still works. If the CTCM device is not + * operational, set it offline and back online. If this does not resolve the + * problem, perform a manual recovery. See "Device Drivers, Features, and + * Commands" for details about how to recover a CTCM device. If this problem + * persists, gather Linux debug data, collect the hardware logs, and report the + * problem to your support organization. + */ + +/*? + * Text: "%s: A check occurred on the subchannel\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the CTCM device + * Description: + * A check condition has been detected on the subchannel. + * User action: + * Check if the connection to the remote device still works. If the CTCM device + * is not operational, set it offline and back online. If this does not resolve + * the problem, perform a manual recovery. See "Device Drivers, Features, and + * Commands" for details about how to recover a CTCM device. If this problem + * persists, gather Linux debug data and report the problem to your support + * organization. + */ + +/*? + * Text: "%s: The communication peer is busy\n" + * Severity: Informational + * Parameter: + * @1: channel ID + * Description: + * A busy target device was reported. This might be a temporary problem. + * User action: + * If this problem persists or is reported frequently ensure that the target + * device is working properly. + */ + +/*? + * Text: "%s: The specified target device is not valid\n" + * Severity: Error + * Parameter: + * @1: channel ID + * Description: + * A target device was called with a faulty device specification. This is an + * adapter hardware problem. + * User action: + * Gather Linux debug data, collect the hardware logs, and contact IBM support. + */ + +/*? + * Text: "An I/O operation resulted in error %04x\n" + * Severity: Error + * Parameter: + * @1: channel ID + * @2: error information + * Description: + * A hardware operation ended with an error. + * User action: + * Check the status of the CTCM device, for example, with ifconfig. If the + * device is not operational, perform a manual recovery. See "Device Drivers, + * Features, and Commands" for details about how to recover a CTCM device. + * If this problem persists, gather Linux debug data, collect the hardware logs, + * and report the problem to your support organization. + */ + +/*? + * Text: "%s: Initialization failed with RX/TX init handshake error %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the CTCM device + * @2: error information + * Description: + * A problem occurred during the initialization of the connection. If the + * connection can be established after an automatic recovery, a success message + * is issued. + * User action: + * If the problem is not resolved by the automatic recovery process, check the + * local and remote device. If this problem persists, gather Linux debug data + * and report the problem to your support organization. + */ + +/*? + * Text: "%s: The network backlog for %s is exceeded, package dropped\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the CTCM device + * @2: calling function + * Description: + * There is more network traffic than can be handled by the device. The device + * is closed and some data has not been transmitted. The device might be + * recovered automatically. + * User action: + * Investigate and resolve the congestion. If necessary, set the device + * online to make it operational. + */ + +/*? + * Text: "%s: The XID used in the MPC protocol is not valid, rc = %d\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the CTCM device + * @2: return code + * Description: + * The exchange identification (XID) used by the CTCM device driver when + * in MPC mode is not valid. + * User action: + * Note the error information provided with this message and contact your + * support organization. + */ + +/*? Text: "CTCM driver unloaded\n" */ +/*? Text: "%s: %s Internal error: net_device is NULL, ch = 0x%p\n" */ +/*? Text: "%s / Initializing the ctcm device driver failed, ret = %d\n" */ +/*? Text: "%s: %s: Internal error: Can't determine channel for interrupt device %s\n" */ +/*? Text: "CTCM driver initialized\n" */ +/*? Text: "%s: setup OK : r/w = %s/%s, protocol : %d\n" */ +/*? Text: "%s: Connected with remote side\n" */ +/*? Text: "%s: Restarting device\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/dasd +++ linux-oracle-5.4.0/Documentation/kmsg/s390/dasd @@ -0,0 +1,704 @@ +/* dasd_ioctl */ + +/*? + * Text: "%s: The DASD has been put in the quiesce state\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * No I/O operation is possible on this device. + * User action: + * Resume the DASD to enable I/O operations. + */ + +/*? + * Text: "%s: I/O operations have been resumed on the DASD\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD is no longer in state quiesce and I/O operations can be performed + * on the device. + * User action: + * None. + */ + +/*? + * Text: "%s: The DASD cannot be formatted while it is enabled\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD you try to format is enabled. Enabled devices cannot be formatted. + * User action: + * Contact the owner of the formatting tool. + */ + +/*? + * Text: "%s: The specified DASD is a partition and cannot be formatted\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD you try to format is a partition. Partitions cannot be formatted + * separately. You can only format a complete DASD including all its partitions. + * User action: + * Format the complete DASD. + * ATTENTION: Formatting irreversibly destroys all data on all partitions + * of the DASD. + */ + +/*? + * Text: "%s: The specified DASD is a partition and cannot be checked\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD you try to check is a partition. Partitions cannot be checked + * separately. You can only check a complete DASD including all its partitions. + * User action: + * Check the complete DASD. + */ + +/*? + * Text: "%s: Formatting unit %d failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: start track + * @3: return code + * Description: + * The formatting process might have been interrupted by a signal, for example, + * CTRL+C. If the process was not interrupted intentionally, an I/O error + * might have occurred. + * User action: + * Retry to format the device. If the error persists, check the log file for + * related error messages. If you cannot resolve the error, note the return + * code and contact your support organization. + */ + + +/* dasd */ + +/*? + * Text: "%s: Cancelling request %p failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to request + * @3: return code of previous function + * Description: + * In response to a user action, the DASD device driver tried but failed to + * cancel a previously started I/O operation. + * User action: + * Try the action again. + */ + +/*? + * Text: "%s: Flushing the DASD request queue failed for request %p\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to request + * Description: + * As part of the unloading process, the DASD device driver flushes the + * request queue. This failed because a previously started I/O operation + * could not be canceled. + * User action: + * Try again to unload the DASD device driver or to shut down Linux. + */ + +/*? + * Text: "The DASD device driver could not be initialized\n" + * Severity: Informational + * Description: + * The initialization of the DASD device driver failed because of previous + * errors. + * User action: + * Check for related previous error messages. + */ + +/*? + * Text: "%s: Accessing the DASD failed because it is in probeonly mode\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * The dasd= module or kernel parameter specified the probeonly attribute for + * the DASD you are trying to access. The DASD device driver cannot access + * DASDs that are in probeonly mode. + * User action: + * Change the dasd= parameter as to omit probeonly for the DASD and reload + * the DASD device driver. If the DASD device driver has been compiled into + * the kernel, reboot Linux. + */ + +/*? + * Text: "%s: cqr %p timed out (%lus), %i retries remaining\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: request + * @3: timeout value + * @4: number of retries left + * Description: + * A try of the error recovery procedure (ERP) for the channel queued request + * (cqr) timed out and failed to recover the error. ERP continues for the DASD. + * User action: + * Ignore this message if it occurs infrequently and if the recovery succeeds + * during one of the retries. If this error persists, check for related + * previous error messages and report the problem to your support organization. + * + * The timeout can be changed by writing a new value to the sysfs 'expires' attribute of the DASD. The value specifies the timeout in seconds. + */ + +/*? + * Text: "%s: cqr %p timed out (%lus) but cannot be ended, retrying in 5 s\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: request + * @3: timeout value + * Description: + * A try of the error recovery procedure (ERP) for the channel queued request + * (cqr) timed out and failed to recover the error. The I/O request submitted + * during the try could not be canceled. The ERP waits for 5 seconds before + * trying again. + * User action: + * Ignore this message if it occurs infrequently and if the recovery succeeds + * during one of the retries. If this error persists, check for related + * previous error messages and report the problem to your support organization. + * + * The timeout can be changed by writing a new value to the sysfs 'expires' attribute of the DASD. The value specifies the timeout in seconds. + */ + +/*? + * Text: "%s: The DASD cannot be set offline while it is in use\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD cannot be set offline because it is in use by an internal process. + * An action to free the DASD might not have completed yet. + * User action: + * Wait some time and set the DASD offline later. + */ + +/*? + * Text: "%s: The DASD cannot be set offline with open count %i\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: count + * Description: + * The DASD is being used by one or more processes and cannot be set offline. + * User action: + * Ensure that the DASD is not in use anymore, for example, unmount all + * partitions. Then try again to set the DASD offline. + */ + +/*? + * Text: "%s: Setting the DASD online failed with rc=%d\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * Description: + * The DASD could not be set online because of previous errors. + * User action: + * Look for previous error messages. If you cannot resolve the error, note + * the return code and contact your support organization. + */ + +/*? + * Text: "%s Setting the DASD online with discipline %s failed with rc=%i\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: discipline + * @3: return code + * Description: + * The DASD could not be set online because of previous errors. + * User action: + * Look for previous error messages. If you cannot resolve the error, note the + * return code and contact your support organization. + */ + +/*? + * Text: "%s Setting the DASD online failed because of missing DIAG discipline\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD was to be set online with discipline DIAG but this discipline of + * the DASD device driver is not available. + * User action: + * Ensure that the dasd_diag_mod module is loaded. If your Linux system does + * not include this module, you cannot set DASDs online with the DIAG + * discipline. + */ + +/*? + * Text: "%s Setting the DASD online failed because of a missing discipline\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD was to be set online with a DASD device driver discipline that + * is not available. + * User action: + * Ensure that all DASD modules are loaded correctly. + */ + +--------------------------- + +/*? + * Text: "The statistics feature has been switched off\n" + * Severity: Informational + * Description: + * The statistics feature of the DASD device driver has been switched off. + * User action: + * None. + */ + +/*? + * Text: "The statistics feature has been switched on\n" + * Severity: Informational + * Description: + * The statistics feature of the DASD device driver has been switched on. + * User action: + * None. + */ + +/*? + * Text: "The statistics have been reset\n" + * Severity: Informational + * Description: + * The DASD statistics data have been reset. + * User action: + * None. + */ + +/*? + * Text: "%s is not a supported value for /proc/dasd/statistics\n" + * Severity: Warning + * Parameter: + * @1: value + * Description: + * An incorrect value has been written to /proc/dasd/statistics. + * The supported values are: 'set on', 'set off', and 'reset'. + * User action: + * Write a supported value to /proc/dasd/statistics. + */ + +/*? + * Text: "%s is not a valid device range\n" + * Severity: Error + * Parameter: + * @1: range + * Description: + * A device range specified with the dasd= parameter is not valid. + * User action: + * Examine the dasd= parameter and correct the device range. + */ + +/*? + * Text: "The probeonly mode has been activated\n" + * Severity: Informational + * Description: + * The probeonly mode of the DASD device driver has been activated. In this + * mode the device driver rejects any 'open' syscalls with EPERM. + * User action: + * None. + */ + +/*? + * Text: "The IPL device is not a CCW device\n" + * Severity: Error + * Description: + * The value for the dasd= parameter contains the 'ipldev' keyword. During + * the boot process this keyword is replaced with the device from which the + * IPL was performed. The 'ipldev' keyword is not valid if the IPL device is + * not a CCW device. + * User action: + * Do not specify the 'ipldev' keyword when performing an IPL from a device + * other than a CCW device. + */ + +/*? + * Text: "A closing parenthesis ')' is missing in the dasd= parameter\n" + * Severity: Warning + * Description: + * The specification for the dasd= kernel or module parameter has an opening + * parenthesis '(' * without a matching closing parenthesis ')'. + * User action: + * Correct the parameter value. + */ + +/*? + * Text: "The autodetection mode has been activated\n" + * Severity: Informational + * Description: + * The autodetection mode of the DASD device driver has been activated. In + * this mode the DASD device driver sets all detected DASDs online. + * User action: + * None. + */ + +/*? + * Text: "%*s is not a supported device option\n" + * Severity: Warning + * Parameter: + * @1: length of option code + * @2: option code + * Description: + * The dasd= parameter includes an unknown option for a DASD or a device range. + * Options are specified in parenthesis and immediately follow a device or + * device range. + * User action: + * Check the dasd= syntax and remove any unsupported options from the dasd= + * parameter specification. + */ + +/*? + * Text: "PAV support has be deactivated\n" + * Severity: Informational + * Description: + * The 'nopav' keyword has been specified with the dasd= kernel or module + * parameter. The Parallel Access Volume (PAV) support of the DASD device + * driver has been deactivated. + * User action: + * None. + */ + +/*? + * Text: "'nopav' is not supported on z/VM\n" + * Severity: Informational + * Description: + * For Linux instances that run as guest operating systems of the z/VM + * hypervisor Parallel Access Volume (PAV) support is controlled by z/VM not + * by Linux. + * User action: + * Remove 'nopav' from the dasd= module or kernel parameter specification. + */ + +/*? + * Text: "High Performance FICON support has been deactivated\n" + * Severity: Informational + * Description: + * The 'nofcx' keyword has been specified with the dasd= kernel or module + * parameter. The High Performance FICON (transport mode) support of the DASD + * device driver has been deactivated. + * User action: + * None. + */ + +/*? + * Text: "The dasd= parameter value %s has an invalid ending\n" + * Severity: Warning + * Parameter: + * @1: parameter value + * Description: + * The specified value for the dasd= kernel or module parameter is not correct. + * User action: + * Check the module or the kernel parameter. + */ + +/*? + * Text: "Registering the device driver with major number %d failed\n" + * Severity: Warning + * Parameter: + * @1: DASD major + * Description: + * Major number 94 is reserved for the DASD device driver. The DASD device + * driver failed to register with this major number. Another device driver + * might have used major number 94. + * User action: + * Determine which device driver uses major number 94 instead of the DASD + * device driver and unload this device driver. Then try again to load the + * DASD device driver. + */ + +/*? + * Text: "%s: default ERP has run out of retries and failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The error recovery procedure (ERP) tried to recover an error but the number + * of retries for the I/O was exceeded before the error could be resolved. + * User action: + * Check for related previous error messages. + */ + +/*? + * Text: "%s: Unable to terminate request %p on suspend\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to request + * Description: + * As part of the suspend process, the DASD device driver terminates requests + * on the request queue. This failed because a previously started I/O operation + * could not be canceled. The suspend process will be stopped. + * User action: + * Try again to suspend the system. + */ + +/*? + * Text: "%s: ERP failed for the DASD\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * An error recovery procedure (ERP) was performed for the DASD but failed. + * User action: + * Check the message log for previous related error messages. + */ + +/*? + * Text: "%s: An error occurred in the DASD device driver, reason=%s\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: reason code + * Description: + * This problem indicates a program error in the DASD device driver. + * User action: + * Note the reason code and contact your support organization. +*/ + +/*? + * Text: "%s: No operational channel path is left for the device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * All channel paths to the device have become non-operational. The DASD + * device driver suspends I/O operations and queues I/O requests for this + * device until at least one channel path becomes operational again. + * User action: + * Ensure that each channel path to the device has been set up correctly + * and that the related physical cable connections are in place. + */ + +/*? + * Text: "%s: No verified channel paths remain for the device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * All verified channel paths to the device have become non-operational. + * Any other paths to the device have previously been identified as not usable. + * The DASD device driver suspends I/O operations and queues I/O requests + * for this device until at least one channel path becomes operational + * again. + * User action: + * Ensure that each channel path to the device has been set up correctly + * and that the related physical cable connections are in place. + * Set all paths to the device offline and online again to repeat the path + * verification. Alternatively, set the device offline and online again to + * verify all available paths for this device. + * If this problem persists, gather Linux debug data and report the problem + * to your support organization. + */ + +/*? + * Text: "%s: A channel path to the device has become operational\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * At least one channel path of this device has become operational again. + * The DASD device driver resumes I/O operations to the device and processes + * the I/O requests that were queued while there was no operational channel path. + * User action: + * None. + */ + +------------------------------------------------------------------------------------ +/* dasd_diag */ + +/*? + * Text: "%s: A 64-bit DIAG call failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * 64-bit DIAG calls require a 64-bit z/VM version. + * User action: + * Use z/VM 5.2 or later or set the sysfs 'use_diag' attribute of the DASD to 0 + * to switch off DIAG. + */ + +/*? + * Text: "%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * Description: + * The format of the DASD is not correct. + * User action: + * Check the device format. For details about the return code see the + * section about the INITIALIZE function for DIAGNOSE Code X'250' + * in "z/VM CP Programming Services". If you cannot resolve the error, note + * the return code and contact your support organization. + */ + +/*? + * Text: "%s: New DASD with %ld byte/block, total size %ld KB%s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * @2: bytes per block + * @3: size + * @4: access mode + * Description: + * A DASD with the indicated block size and total size has been set online. + * If the DASD is configured as read-only to the real or virtual hardware, + * the message includes an indication of this hardware access mode. The + * hardware access mode is independent from the 'readonly' attribute of + * the device in sysfs. + * User action: + * None. + */ + +/*? + * Text: "%s: DIAG ERP failed with rc=%d\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * Description: + * An error in the DIAG processing could not be recovered by the error + * recovery procedure (ERP) of the DIAG discipline. + * User action: + * Note the return code, check for related I/O errors, and report this problem + * to your support organization. + */ + +/*? + * Text: "%s: DIAG initialization failed with rc=%d\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * Description: + * Initializing the DASD with the DIAG discipline failed. Possible reasons for + * this problem are that the device has a device type other than FBA or ECKD, + * or has a block size other than one of the supported sizes: + * 512 byte, 1024 byte, 2048 byte, or 4096 byte. + * User action: + * Ensure that the device can be written to and has a supported device type + * and block size. For details about the return code see the section about + * the INITIALIZE function for DIAGNOSE Code X'250' in "z/VM CP Programming + * Services". If you cannot resolve the error, note the error code and contact + * your support organization. + */ + +/*? + * Text: "%s: Device type %d is not supported in DIAG mode\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: device type + * Description: + * Only DASD of type FBA and ECKD are supported in DIAG mode. + * User action: + * Set the sysfs 'use_diag' attribute of the DASD to 0 and try again to access + * the DASD. + */ + +/*? + * Text: "Discipline %s cannot be used without z/VM\n" + * Severity: Informational + * Parameter: + * @1: discipline name + * Description: + * The discipline that is specified with the dasd= kernel or module parameter + * is only available for Linux instances that run as guest operating + * systems of the z/VM hypervisor. + * User action: + * Remove the unsupported discipline from the parameter string. + */ + +/*? + * Text: "%s: The access mode of a DIAG device changed to read-only\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A device changed its access mode from writeable to + * read-only while in use. + * User action: + * Set the device offline, ensure that the device is configured correctly in + * z/VM, then set the device online again. + */ + +------------------------------------------------------------------------------------ +/* dasd_erp */ + +/*? + * Text: "%s: A timeout error occurred for cqr %p\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to request + * Description: + * A channel queued request (cqr) failed because it timed out. + * One possible reason for this error is that a request did not + * complete within the timeout interval specified for the DASD. + * The timeout interval is set as the value of the 'timeout' sysfs + * attribute of a DASD. A value of 0 disables the timeout function. + * The timeout function can be used; for example, by mirroring setups; + * to quickly process a request queue for a DASD that has become unavailable. + * User action: + * Check the message log for previous related error messages. Verify + * that the storage server and the connection from host to storage + * server are operational. If the 'timeout' sysfs attribute of the + * DASD has been set to a value other than 0, verify that this + * setting is intentional and change it if required. + */ + +/*? + * Text: "%s: A transport error occurred for cqr %p\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to request + * Description: + * A channel queued request (cqr) failed because the connection to the + * device was lost and the 'failfast' flag is set for the request. + * This flag can result from, for example: + * + * - A software layer above the DASD device driver; + * for example, in a host based mirroring setup. + * + * - Value 1 for the 'failfast' sysfs attribute of the DASD. + * This setting applies to all requests on the DASD. + * + * User action: + * Ensure that each channel path to the device has been set up + * correctly and that the related physical cable connections are in + * place. If the 'failfast' attribute of the DASD is set to 1, + * verify that this setting is intentional and change it to 0 if required. + */ + +/*? + * Text: "%s Setting the DASD online failed because the required module %s could not be loaded (rc=%d)\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: kernel module name + * @3: return code + * Description: + * The DASD was to be set online with discipline DIAG but this discipline of + * the DASD device driver is not available and an attempt to load the + * corresponding kernel module failed with the specified return code. + * + * User action: + * Ensure that the kernel module with the specified name is correctly installed + * or set the sysfs 'use_diag' attribute of the DASD to 0 to switch off DIAG. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/dasd-eckd +++ linux-oracle-5.4.0/Documentation/kmsg/s390/dasd-eckd @@ -0,0 +1,2154 @@ +/* dasd_eckd */ + +/*? + * Text: "%s: ERP failed for the DASD\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * An error recovery procedure (ERP) was performed for the DASD but failed. + * User action: + * Check the message log for previous related error messages. + */ + +/*? + * Text: "%s: An error occurred in the DASD device driver, reason=%s\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: reason code + * Description: + * This problem indicates a program error in the DASD device driver. + * User action: + * Note the reason code and contact your support organization. +*/ + +/*? + * Text: "%s: Allocating memory for private DASD data failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD device driver maintains data structures for each DASD it manages. + * There is not enough memory to allocate these data structures for one or + * more DASD. + * User action: + * Free some memory and try the operation again. + */ + +/*? + * Text: "%s: DASD with %d KB/block, %d KB total size, %d KB/track, %s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * @2: block size + * @3: DASD size + * @4: track size + * @5: disc layout + * Description: + * A DASD with the shown characteristics has been set online. + * User action: + * None. + */ + +/*? + * Text: "%s: Start track number %u used in formatting is too big\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: track number + * Description: + * The DASD format I/O control was used incorrectly by a formatting tool. + * User action: + * Contact the owner of the formatting tool. + */ + +/*? + * Text: "%s: Stop track number %u used in formatting is too big\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: track number + * Description: + * The DASD format I/O control was used incorrectly by a formatting tool. + * User action: + * Contact the owner of the formatting tool. + */ + +/*? + * Text: "%s: The DASD is not formatted\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A DASD has been set online but it has not been formatted yet. You must + * format the DASD before you can use it. + * User action: + * Format the DASD, for example, with dasdfmt. + */ + +/*? + * Text: "%s: 0x%x is not a known command\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: command + * Description: + * This problem is likely to be caused by a programming error. + * User action: + * Contact your support organization. + */ + +/*? + * Text: "%s: Track 0 has no records following the VTOC\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * Linux has identified a volume table of contents (VTOC) on the DASD but + * cannot read any data records following the VTOC. A possible cause of this + * problem is that the DASD has been used with another System z operating + * system. + * User action: + * Format the DASD for usage with Linux, for example, with dasdfmt. + * ATTENTION: Formatting irreversibly destroys all data on the DASD. + */ + +/*? + * Text: "%s: An I/O control call used incorrect flags 0x%x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: flags + * Description: + * The DASD format I/O control was used incorrectly. + * User action: + * Contact the owner of the formatting tool. + */ + +/*? + * Text: "%s: New DASD %04X/%02X (CU %04X/%02X) with %d cylinders, %d heads, %d sectors%s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * @2: device type + * @3: device model + * @4: control unit type + * @5: control unit model + * @6: number of cylinders + * @7: tracks per cylinder + * @8: sectors per track + * @9: access mode + * Description: + * A DASD with the shown characteristics has been set online. + * If the DASD is configured as read-only to the real or virtual hardware, + * the message includes an indication of this hardware access mode. The + * hardware access mode is independent from the 'readonly' attribute of + * the device in sysfs. + * User action: + * None. + */ + +/*? + * Text: "%s: The disk layout of the DASD is not supported\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD device driver only supports the following disk layouts: CDL, LDL, + * FBA, CMS, and CMS RESERVED. + * User action: + * None. + */ + +/*? + * Text: "%s: Start track %u used in formatting exceeds end track\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: track number + * Description: + * The DASD format I/O control was used incorrectly by a formatting tool. + * User action: + * Contact the owner of the formatting tool. + */ + +/*? + * Text: "%s: The DASD cache mode was set to %x (%i cylinder prestage)\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * @2: operation mode + * @3: number of cylinders + * Description: + * The DASD cache mode has been changed. See the storage system documentation + * for information about the different cache operation modes. + * User action: + * None. + */ + +/*? + * Text: "%s: The DASD cannot be formatted with block size %u\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: block size + * Description: + * The block size specified for a format instruction is not valid. The block + * size must be between 512 and 4096 byte and must be a power of 2. + * User action: + * Call the format command with a supported block size. + */ + +/*? + * Text: "%s: The UID of the DASD has changed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The Unique Identifier (UID) of a DASD that is currently in use has changed. + * This indicates that the physical disk has been replaced. + * User action: + * None if the replacement was intentional. + * If the disk change is not expected, stop using the disk to prevent possible + * data loss. +*/ + + +/* dasd_3990_erp */ + +/*? + * Text: "%s: is offline or not installed - INTERVENTION REQUIRED!!\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD to be accessed is not in an accessible state. The I/O operation + * will wait until the device is operational again. This is an operating system + * independent message that is issued by the storage system. + * User action: + * Make the DASD accessible again. For details see the storage system + * documentation. + */ + +/*? + * Text: "%s: The DASD cannot be reached on any path (lpum=%x/opm=%x)\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: last path used mask + * @3: online path mask + * Description: + * After a path to the DASD failed, the error recovery procedure of the DASD + * device driver tried but failed to reconnect the DASD through an alternative + * path. + * User action: + * Ensure that the cabling between the storage server and the mainframe + * system is securely in place. Check the file systems on the DASD when it is + * accessible again. + */ + +/*? + * Text: "%s: Unable to allocate DCTL-CQR\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an internal error. + * User action: + * Contact your support organization. + */ + +/*? + * Text: "%s: FORMAT 0 - Invalid Parameter\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A data argument of a command is not valid. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - DPS Installation Check\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This operating system independent message is issued by the storage system + * for one of the following reasons: + * - A 3380 Model D or E DASD does not have the Dynamic Path Selection (DPS) + * feature in the DASD A-unit. + * - The device type of an attached DASD is not supported by the firmware. + * - A type 3390 DASD is attached to a 3 MB channel. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 2 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Drive motor switch is off\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - CCW Count less than required\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The CCW count of a command is less than required. This is an operating + * system independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Channel requested ... %02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: reason code + * Description: + * This is an operating system independent message that is issued by the + * storage system. The possible reason codes indicate the following problems: + * 00 No Message. + * 01 The channel has requested unit check sense data. + * 02 The channel has requested retry and retry is exhausted. + * 03 A SA Check-2 error has occurred. This sense is presented with + * Equipment Check. + * 04 The channel has requested retry and retry is not possible. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Status Not As Required: reason %02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: reason code + * Description: + * This is an operating system independent message that is issued by the + * storage system. There are several potential reasons for this message; + * byte 8 contains the reason code. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Device status 1 not valid\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Storage Path Restart\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * An operation for an active channel program was queued in a Storage Control + * when a warm start was received by the path. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Reset Notification\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A system reset or its equivalent was received on an interface. The Unit + * Check that generates this sense is posted to the next channel initiated + * selection following the resetting event. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Invalid Command Sequence\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * An incorrect sequence of commands has occurred. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Missing device address bit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Subsystem Processing Error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A firmware logic error has been detected. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Seek incomplete\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Invalid Command\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A command was issued that is not in the 2107/1750 command set. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Command Invalid on Secondary Address\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A command or order not allowed on a PPRC secondary device has been received + * by the secondary device. This is an operating system independent message + * that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Invalid Defective/Alternate Track Pointer\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A defective track has been accessed. The subsystem generates an invalid + * Defective/Alternate Track Pointer as a part of RAID Recovery. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Channel Returned with Incorrect retry CCW\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A command portion of the CCW returned after a command retry sequence does + * not match the command for which retry was signaled. This is an operating + * system independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Diagnostic of Special Command Violates File Mask\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A command is not allowed under the Access Authorization specified by the + * File Mask. This is an operating system independent message that is issued + * by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Head address does not compare\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Device did not respond to selection\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Device check-2 error or Set Sector is not complete\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Device Error Source\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The device has completed soft error logging. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Data Pinned for Device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * Modified data in cache or in persistent storage exists for the DASD. The + * data cannot be destaged to the device. This track is the first track pinned + * for this device. This is an operating system independent message that is + * issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel C\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Device Status 1 not as expected\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 0 - Device Fenced - device = %02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: sense data byte 4 + * Description: + * The device shown in sense byte 4 has been fenced. This is an operating + * system independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Interruption cannot be reset\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Index missing\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - DASD Fast Write inhibited\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * DASD Fast Write is not allowed because of a nonvolatile storage battery + * check condition. This is an operating system independent message that is + * issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Invalid tag-in for an extended command sequence\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Key area error; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Count area error; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Track physical address did not compare\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 2 - 3990 check-2 error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Offset active cannot be reset\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - RCC 1 and RCC 2 sequences not successful\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in count address area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Data area error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel A\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in count address area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the key area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Caching status reset to default\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The storage director has assigned two new subsystem status devices and + * resets the status to its default value. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the data area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Device not ready\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in key area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - DASD controller failed to set or reset the long busy latch\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 1 - Cylinder address did not compare\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 3 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in data area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 2 - Support facility errors\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Key area error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - End operation with transfer count not zero\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 2 - Microcode detected error %02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: error code + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the count area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 3 - Allegiance terminated\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * Allegiance terminated because of a Reset Allegiance or an Unconditional + * Reserve command on another channel. This is an operating system independent + * message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Home address area error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Count area error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Invalid tag-in during selection sequence\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in data area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in home address area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Home address area error; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - Data area error; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in home address area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the home address area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the home address area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the count area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 4 - No sync byte in key area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Invalid DCC selection response or timeout\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the data area\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Operation Terminated\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The storage system ends an operation related to an active channel program + * when termination and redrive are required and logging is not desired. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel B\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 5 - Data Check in the key area; offset active\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Volume is suspended duplex\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The duplex pair volume has entered the suspended duplex state because of a + * failure. This is an operating system independent message that is issued by + * the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel D\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - RCC 1 sequence not successful\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel E\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - 3990 microcode time out when stopping selection\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel F\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - RCC initiated by a connection check alert\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel G\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - extra RCC required\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 6 - Overrun on channel H\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - Unexpected end operation response code\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Permanent path error (DASD controller not available)\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Missing end operation; device transfer incomplete\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Cache or nonvolatile storage equipment failure\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * An equipment failure has occurred in the cache storage or nonvolatile + * storage of the storage system. This is an operating system independent + * message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - DPS cannot be filled\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - Error correction code hardware fault\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Missing end operation; device transfer complete\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - DASD controller not available on disconnected command chain\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - No interruption from device during a command chain\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - No response to selection after a poll interruption\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 9 - Track physical address did not compare while oriented\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 9 - Head address did not compare\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Invalid tag-in for an immediate command sequence\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 9 - Cylinder address did not compare\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - DPS checks after a system reset or selective reset\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Caching reinitiated\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * Caching has been automatically reinitiated following an error. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - End operation with transfer count zero\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 7 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 9 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - Short busy time-out during device selection\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Caching terminated\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The storage system was unable to initiate caching or had to suspend caching + * for a 3990 control unit. If this problem is caused by a failure condition, + * an additional message will provide more information about the failure. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * Check for additional messages that point out possible failures. For more + * information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Subsystem status cannot be determined\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The status of a DASD Fast Write or PPRC volume cannot be determined. + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Nonvolatile storage terminated\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The storage director has stopped using nonvolatile storage or cannot + * initiate nonvolatile storage. If this problem is caused by a failure, an + * additional message will provide more information about the failure. This is + * an operating system independent message that is issued by the storage system. + * User action: + * Check for additional messages that point out possible failures. For more + * information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT 8 - Reserved\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: Write inhibited path encountered\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an informational message. + * User action: + * None. + */ + +/*? + * Text: "%s: FORMAT 9 - Device check-2 error\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * This is an operating system independent message that is issued by the + * storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Track format incorrect\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A track format error occurred while data was being written to the DASD or + * while a duplex pair was being established. This is an operating system + * independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: FORMAT F - Cache fast write access not authorized\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * A request for Cache Fast Write Data access cannot be satisfied because + * of missing access authorization for the storage system. This is an operating + * system independent message that is issued by the storage system. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: Data recovered during retry with PCI fetch mode active\n" + * Severity: Emerg + * Parameter: + * @1: bus ID of the DASD + * Description: + * A data error has been recovered on the storages system but the Linux file + * system cannot be informed about the data mismatch. To prevent Linux from + * running with incorrect data, the DASD device driver will trigger a kernel + * panic. + * User action: + * Reset your real or virtual hardware and reboot Linux. + */ + +/*? + * Text: "%s: The specified record was not found\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The record to be accessed does not exist. The DASD might be unformatted + * or defect. + * User action: + * Try to format the DASD or replace it. + * ATTENTION: Formatting irreversibly destroys all data on the DASD. + */ + +/*? + * Text: "%s: ERP %p (%02x) refers to %p\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: pointer to ERP + * @3: ERP status + * @4: cqr + * Description: + * This message provides debug information for the enhanced error recovery + * procedure (ERP). + * User action: + * If you do not need this information, you can suppress this message by + * switching off ERP logging, for example, by writing '1' to the 'erplog' + * sysfs attribute of the DASD. + */ + +/*? + * Text: "%s: ERP chain at END of ERP-ACTION\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * This message provides debug information for the enhanced error recovery + * procedure (ERP). + * User action: + * If you do not need this information, you can suppress this message by + * switching off ERP logging, for example, by writing '1' to the 'erplog' + * sysfs attribute of the DASD. + */ + +/*? + * Text: "%s: The cylinder data for accessing the DASD is inconsistent\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * An error occurred in the storage system hardware. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: Accessing the DASD failed because of a hardware error\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * An error occurred in the storage system hardware. + * User action: + * For more information see the documentation of your storage system. + */ + +/*? + * Text: "%s: ERP chain at BEGINNING of ERP-ACTION\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * This message provides debug information for the enhanced error recovery + * procedure (ERP). + * User action: + * If you do not need this information, you can suppress this message by + * switching off ERP logging, for example, by writing '1' to the 'erplog' + * sysfs attribute of the DASD. + */ + +/*? + * Text: "%s: ERP %p has run out of retries and failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: ERP pointer + * Description: + * The error recovery procedure (ERP) tried to recover an error but the number + * of retries for the I/O was exceeded before the error could be resolved. + * User action: + * Check for related previous error messages. + */ + +/*? + * Text: "%s: SIM - SRC: %02x%02x%02x%02x\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: sense byte + * @3: sense byte + * @4: sense byte + * @5: sense byte + * Description: + * This error message is a System Information Message (SIM) generated by the + * storage system. The System Reference Code (SRC) defines the error in detail. + * User action: + * Look up the SRC in the storage server documentation. + */ + +/*? + * Text: "%s: log SIM - SRC: %02x%02x%02x%02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: sense byte + * @3: sense byte + * @4: sense byte + * @5: sense byte + * Description: + * This System Information Message (SIM) is generated by the storage system. + * The System Reference Code (SRC) defines the error in detail. + * User action: + * Look up the SRC in the storage server documentation. + */ + +/*? + * Text: "%s: Reading device feature codes failed with rc=%d\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * Description: + * The device feature codes state which advanced features are supported by a + * device. + * Examples for advanced features are PAV or high performance FICON. + * Some early devices do not provide feature codes and no advanced features are + * available on these devices. + * User action: + * None, if the DASD does not provide feature codes. If the DASD provides + * feature codes, make sure that it is working correctly, then set it offline + * and back online. + */ + +/*? + * Text: "%s: A channel path group could not be established\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * Initialization of a DASD did not complete because a channel path group + * could not be established. + * User action: + * Make sure that the DASD is working correctly, then try again to set it + * online. If initialization still fails, reboot. + */ + +/*? + * Text: "%s: The DASD is not operating in multipath mode\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD channel path group could not be configured to use multipath mode. + * This might negatively affect I/O performance on this DASD. + * User action: + * Make sure that the DASD is working correctly, then try again to set it + * online. If initialization still fails, reboot. + */ + +/*? + * Text: "%s: Detecting the DASD disk layout failed because of an I/O error\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The disk layout of the DASD could not be detected because of an unexpected + * I/O error. The DASD device driver treats the device like an unformatted DASD, + * and partitions on the device are not accessible. + * User action: + * If the DASD is formatted, make sure that the DASD is working correctly, + * then set it offline and back online. If the DASD is unformatted, format the + * DASD, for example, with dasdfmt. + * ATTENTION: Formatting irreversibly destroys all data on the DASD. + */ + +/*? + * Text: "%s: An I/O request was rejected because writing is inhibited\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * An I/O request was returned with an error indication of 'command reject' + * and 'write inhibited'. The most likely reason for this error is a + * failed write request to a device that was attached as read-only in z/VM. + * User action: + * Set the device offline, ensure that the device is configured correctly in + * z/VM, then set the device online again. + */ + +/*? + * Text: "%s: An Alias device was reassigned to a new base device with UID: %s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the alias + * @2: UID of new base device + * Description: + * The alias device with the indicated bus ID has been reassigned. The UID of the new base device is shown in the message. + * User action: + * None. + */ + +/*? + * Text: "%s: Detecting the maximum supported data size for zHPF requests failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * High Performance FICON (zHPF) requests are limited to a hardware-dependent + * maximum data size. The DASD device driver failed to detect this size and zHPF + * is not available for this device. + * User action: + * Set the device offline and online again. If this problem persists, gather + * Linux debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Reading device feature codes failed (rc=%d) for new path %x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * @3: path mask + * Description: + * A new path has been made available to the a device. + * A command to read the device feature codes on this device returned an error. + * The new path will not be used for I/O. + * User action: + * Set the new path offline and online again to repeat the path verification. + * Alternatively, set the device offline and online again to + * verify all available paths for this device. + * If this problem persists, gather Linux debug data and report the problem + * to your support organization. + */ + +/*? + * Text: "%s: Detecting the maximum data size for zHPF requests failed (rc=%d) for a new path %x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: return code + * @3: path mask + * Description: + * High Performance FICON (zHPF) requests are limited to a hardware-dependent + * maximum data size. A command to detect this size for + * a new path returned an error. The new path will not be used for I/O. + * User action: + * Set the new path offline and online again to repeat the path verification. + * Alternatively, set the device offline and online again to + * verify all available paths for this device. + * If this problem persists, gather Linux debug data and report the problem + * to your support organization. + */ + +/*? + * Text: "%s: The maximum data size for zHPF requests %u on a new path %x is below the active maximum %u\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * @2: size in bytes + * @3: path mask + * @4: size in bytes + * Description: + * High Performance FICON (zHPF) requests are limited to a hardware-dependent + * maximum data size. The maximum of the new path is below + * the previously established common maximum for the + * existing paths for this device. This could cause requests on the new + * path to fail. The new path will not be used for I/O. + * User action: + * Set the device offline and online again to establish a new common maximum + * data size for the device. + */ + +/*? + * Text: "%s: The device reservation was lost\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * This Linux instance has lost its reservation of the device to another + * operating system instance. Depending on the reservation policy for the + * device, I/O might be blocked until the other operating system instance + * surrenders the reservation or all I/O requests might fail until the + * device is reset. + * User action: + * None, if this situation is handled by system automation software. + * If this situation is not handled by automation, check the + * last_known_reservation_state attribute of the device in sysfs. + * If the value is 'lost', verify that the device is no longer reserved + * by another operating system instance, then set the device offline and + * online again. For any other value of the last_known_reservation_state + * no action is required. I/O will resume when the device reservation is + * surrendered by the other operating system instance. + */ + +/*? + * Text: "%s: The storage server does not support raw-track access\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD cannot be accessed in raw-track access mode because the storage + * server does not have all required features for this access mode. + * In raw-track access mode, the DASD device driver accesses complete ECKD + * tracks. + * By default, the DASD device driver accesses only the data fields of ECKD + * devices and omits the count and key data fields. + * User action: + * Ensure that the raw_track_access sysfs attribute of the DASD has the value + * 0 to access the device in default ECKD mode. + */ + +/*? + * Text: "%s: The newly added channel path %02X will not be used because it leads to a different device %s\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: logical path mask + * @3: UID + * Description: + * The newly added channel path has a different UID than the DASD device. This indicates + * an incorrect cabling. This path is not going to be used. + * User action: + * Check the cabling of the DASD device. Disconnect and reconnect the cable. + */ + +/*? + * Text: "%s: Not all channel paths lead to the same device, path %02X leads to device %s instead of %s\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: logical path mask + * @3: UID + * @4: UID + * Description: + * Some channel paths have a different UID than others. This indicates + * an incorrect cabling. The DASD device is not enabled. + * User action: + * Check cabling of the DASD device and retry to enable the device. + */ + +/*? + * Text: "Service on the storage server caused path %x.%02x to go offline" + * Severity: Warning + * Parameter: + * @1: channel subsystem ID + * @2: CHPID + * Description: + * A channel path to the DASD has been set offline because of + * a service action on the storage server. The path will be set back + * online automatically when the service action is completed. + * User action: + * None. + */ + +/*? + * Text: "Path %x.%02x is back online after service on the storage server" + * Severity: Informational + * Parameter: + * @1: channel subsystem ID + * @2: CHPID + * Description: + * A path had been set offline temporarily because of a service + * action on the storage server. + * The service action has completed, and the channel path is available + * again. + * User action: + * None. + */ + +/*? + * Text: "%s: High Performance FICON disabled\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * Description: + * High Performance FICON (HPF) has been disabled. Either the device + * lost HPF functionality, or none of the remaining channel paths are + * HPF capable. + * User action: + * Report the problem to your support organization. + * Ensure that the cabling between the storage server and the mainframe + * system is securely in place. + * Reset the device and channel paths by writing "all" or a logical path mask + * to the path_reset sysfs attribute of the device. + */ + +/*? + * Text: "%s: Channel path %02X lost HPF functionality and is disabled\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: logical path mask + * Description: + * A channel path has lost High Performance FICON (HPF) functionality + * and was removed from regular operations. + * User action: + * Report the problem to your support organization. + * Ensure that the cabling between the storage server and the mainframe + * system is securely in place. + * Reset the device and channel paths by writing "all" or a logical path mask + * to the path_reset sysfs attribute of the device. + */ + +/*? + * Text: "%s: Path %x.%02x (pathmask %02x) is disabled - IFCC threshold exceeded\n" + * Severity: Error + * Parameter: + * @1: bus ID of the DASD + * @2: cssid + * @3: chpid + * @4: logical path mask + * Description: + * Due to numerous interface or channel control checks (IFCCs), a channel path + * was removed from regular operations to retain good I/O performance. + * User action: + * Ensure that the cabling between the storage server and the mainframe + * system is securely in place. + * Reset the device and channel paths by writing "all" or a logical path mask + * to the path_reset sysfs attribute of the device. + * If the problem persists, report it to your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/dasd-fba +++ linux-oracle-5.4.0/Documentation/kmsg/s390/dasd-fba @@ -0,0 +1,36 @@ + +/*? + * Text: "%s: New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB and %d B/blk%s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the DASD + * @2: device type + * @3: device model + * @4: control unit type + * @5: control unit model + * @6: size + * @7: bytes per block + * @8: access mode + * Description: + * A DASD with the shown characteristics has been set online. + * If the DASD is configured as read-only to the real or virtual hardware, + * the message includes an indication of this hardware access mode. The + * hardware access mode is independent from the 'readonly' attribute of + * the device in sysfs. + * User action: + * None. + */ + +/*? + * Text: "%s: Allocating memory for private DASD data failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the DASD + * Description: + * The DASD device driver maintains data structures for each DASD it manages. + * There is not enough memory to allocate these data structures for one or + * more DASD. + * User action: + * Free some memory and try the operation again. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/dcssblk +++ linux-oracle-5.4.0/Documentation/kmsg/s390/dcssblk @@ -0,0 +1,206 @@ +/*? + * Text: "Adjacent DCSSs %s and %s are not contiguous\n" + * Severity: Error + * Parameter: + * @1: name 1 + * @2: name 2 + * Description: + * You can only map a set of two or more DCSSs to a single DCSS device if the + * DCSSs in the set form a contiguous memory space. The DCSS device cannot be + * created because there is a memory gap between two adjacent DCSSs. + * User action: + * Ensure that you have specified all DCSSs that belong to the set. Check the + * definitions of the DCSSs on the z/VM hypervisor to verify that they form + * a contiguous memory space. + */ + +/*? + * Text: "DCSS %s and DCSS %s have incompatible types\n" + * Severity: Error + * Parameter: + * @1: name 1 + * @2: name 2 + * Description: + * You can only map a set of two or more DCSSs to a single DCSS device if + * either all DCSSs in the set have the same type or if the set contains DCSSs + * of the two types EW and EN but no other type. The DCSS device cannot be + * created because at least two of the specified DCSSs are not compatible. + * User action: + * Check the definitions of the DCSSs on the z/VM hypervisor to verify that + * their types are compatible. + */ + +/*? + * Text: "DCSS %s is of type SC and cannot be loaded as exclusive-writable\n" + * Severity: Error + * Parameter: + * @1: device name + * Description: + * You cannot load a DCSS device in exclusive-writable access mode if the DCSS + * devise maps to one or more DCSSs of type SC. + * User action: + * Load the DCSS in shared access mode. + */ + +/*? + * Text: "DCSS device %s is removed after a failed access mode change\n" + * Severity: Error + * Parameter: + * @1: device name + * Description: + * To change the access mode of a DCSS device, all DCSSs that map to the device + * were unloaded. Reloading the DCSSs for the new access mode failed and the + * device is removed. + * User action: + * Look for related messages to find out why the DCSSs could not be reloaded. + * If necessary, add the device again. + */ + +/*? + * Text: "All DCSSs that map to device %s are saved\n" + * Severity: Informational + * Parameter: + * @1: device name + * Description: + * A save request has been submitted for the DCSS device. Changes to all DCSSs + * that map to the device are saved permanently. + * User action: + * None. + */ + +/*? + * Text: "Device %s is in use, its DCSSs will be saved when it becomes idle\n" + * Severity: Informational + * Parameter: + * @1: device name + * Description: + * A save request for the device has been deferred until the device becomes + * idle. Then changes to all DCSSs that the device maps to will be saved + * permanently. + * User action: + * None. + */ + +/*? + * Text: "A pending save request for device %s has been canceled\n" + * Severity: Informational + * Parameter: + * @1: device name + * Description: + * A save request for the DCSSs that map to a DCSS device has been pending + * while the device was in use. This save request has been canceled. Changes to + * the DCSSs will not be saved permanently. + * User action: + * None. + */ + +/*? + * Text: "Loaded %s with total size %lu bytes and capacity %lu sectors\n" + * Severity: Informational + * Parameter: + * @1: DCSS names + * @2: total size in bytes + * @3: total size in 512 byte sectors + * Description: + * The listed DCSSs have been verified as contiguous and successfully loaded. + * The displayed sizes are the sums of all DCSSs. + * User action: + * None. + */ + +/*? + * Text: "Device %s cannot be removed because it is not a known device\n" + * Severity: Warning + * Parameter: + * @1: device name + * Description: + * The DCSS device you are trying to remove is not known to the DCSS device + * driver. + * User action: + * List the entries under /sys/devices/dcssblk/ to see the names of the + * existing DCSS devices. + */ + +/*? + * Text: "Device %s cannot be removed while it is in use\n" + * Severity: Warning + * Parameter: + * @1: device name + * Description: + * You are trying to remove a device that is in use. + * User action: + * Make sure that all users of the device close the device before you try to + * remove it. + */ + +/*? + * Text: "Device %s has become idle and is being saved now\n" + * Severity: Informational + * Parameter: + * @1: device name + * Description: + * A save request for the DCSSs that map to a DCSS device has been pending + * while the device was in use. The device has become idle and all changes + * to the DCSSs are now saved permanently. + * User action: + * None. + */ + +/*? + * Text: "Writing to %s failed because it is a read-only device\n" + * Severity: Warning + * Parameter: + * @1: device name + * Description: + * The DCSS device is in shared access mode and cannot be written to. Depending + * on the type of the DCSSs that the device maps to, you might be able to + * change the access mode to exclusive-writable. + * User action: + * If the DCSSs of the device are of type SC, do not attempt to write to the + * device. If the DCSSs of the device are of type ER or SR, change the access + * mode to exclusive-writable before writing to the device. + */ + +/*? + * Text: "The address range of DCSS %s changed while the system was suspended\n" + * Severity: Error + * Parameter: + * @1: device name + * Description: + * After resuming the system, the start address or end address of a DCSS does + * not match the address when the system was suspended. DCSSs must not be + * changed after the system was suspended. + * This error cannot be recovered. The system is stopped with a kernel panic. + * User action: + * Reboot Linux. + */ + +/*? + * Text: "Suspending the system failed because DCSS device %s is writable\n" + * Severity: Error + * Parameter: + * @1: device name + * Description: + * A system cannot be suspended if one or more DCSSs are accessed in exclusive- + * writable mode. DCSS segment types EW, SW, and EN are always writable and + * must be removed before a system is suspended. + * User action: + * Remove all DCSSs of segment types EW, SW, and EN by writing the DCSS name to + * the sysfs 'remove' attribute. Set the access mode for all DCSSs of segment + * types SR and ER to read-only by writing 1 to the sysfs 'shared' attribute of + * the DCSS. Then try again to suspend the system. + */ + +/*? + * Text: "DCSS %s is of type SN or EN and cannot be saved\n" + * Severity: Warning + * Parameter: + * @1: DCSS name + * Description: + * DCSSs of type SN or EN cannot be saved. + * User action: + * If the DCSS was set up with the intention to prevent the content from being saved, + * no action is necessary. + * To be able to save the content, you must define the DCSS with a type other than SN or EN. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/diag288_wdt +++ linux-oracle-5.4.0/Documentation/kmsg/s390/diag288_wdt @@ -0,0 +1,66 @@ +/*? + * Text: "The watchdog cannot be activated\n" + * Severity: Error + * Description: + * Diagnose instruction 0x288 was called to activate the diag288 watchdog. + * The diagnose call returned an error that cannot be handled by the device driver. + * The watchdog stays inactive. + * User action: + * Contact your support organization. + */ + +/*? + * Text: "The watchdog cannot be initialized\n" + * Severity: Error + * Description: + * Diagnose instruction 0x288 was called to initialize the diag288 watchdog. + * The diagnose call returned an error that cannot be handled by the device driver. + * The watchdog stays inactive. + * A possible reason for this error is that your real or virtual hardware does not support + * the diag288 watchdog. + * User action: + * Confirm that the diag288 watchdog is supported in your environment. + * Use a watchdog that is supported in your environment. + */ + +/*? + * Text: "The watchdog cannot be deactivated\n" + * Severity: Error + * Description: + * Diagnose instruction 0x288 was called to deactivate the diag288 watchdog. + * The diagnose call returned an error that cannot be handled by the device driver. + * The watchdog stays active and a watchdog timeout will trigger the configured timeout action. + * The diag288 watchdog device driver might intentionally be configured to prevent deactivation. + * User action: + * You can configure the diag288 watchdog device driver such that it can be deactivated. + * If the diag288 device driver has been compiled as a separate module, diag288_wdt, reload the module + * without specifying the 'nowayout' module parameter. + * If the diag288 device driver has been compiled into your kernel, + * reboot Linux without specifying the 'diag288.nowayout' kernel parameter'. + */ + +/*? + * Text: "The watchdog timer cannot be started or reset\n" + * Severity: Error + * Description: + * Diagnose instruction 0x288 was called to start the diag288 watchdog or to set timer back to zero. + * The diagnose call returned an error that cannot be handled by the device driver. + * The watchdog stays inactive or becomes inactive. + * User action: + * Contact your support organization. + */ + +/*? + * Text: "Linux cannot be suspended while the watchdog is in use\n" + * Severity: Error + * Description: + * The watchdog must not time out while Linux is suspended. + * Therefore, the diag288 watchdog device driver prevents Linux from being suspended + * while the watchdog is in use. + * User action: + * i) Stop the watchdog application. ii) If the problem persists, close the watchdog + * device node by issuing 'echo V > /dev/watchdog'. + * iii) If the device driver still prevents Linux from being suspended, + * contact your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/extmem +++ linux-oracle-5.4.0/Documentation/kmsg/s390/extmem @@ -0,0 +1,293 @@ +/*? + * Text: "Querying a DCSS type failed with rc=%ld\n" + * Severity: Warning + * Parameter: + * @1: return code + * Description: + * The DCSS kernel interface used z/VM diagnose call X'64' to query the + * type of a DCSS. z/VM failed to determine the type and returned an error. + * User action: + * Look for related messages to find out which DCSS is affected. + * For details about the return codes see the section about DIAGNOSE Code + * X'64' in "z/VM CP Programming Services". + */ + +/*? + * Text: "Loading DCSS %s failed with rc=%ld\n" + * Severity: Warning + * Parameter: + * @1: DCSS name + * @2: return code + * Description: + * The DCSS kernel interface used diagnose call X'64' to load a DCSS. z/VM + * failed to load the DCSS and returned an error. + * User action: + * For details about the return codes see the section about DIAGNOSE Code + * X'64' in "z/VM CP Programming Services". + */ + +/*? + * Text: "DCSS %s of range %p to %p and type %s loaded as exclusive-writable\n" + * Severity: Informational + * Parameter: + * @1: DCSS name + * @2: starting page address + * @3: ending page address + * @4: DCSS type + * Description: + * The DCSS was loaded successfully in exclusive-writable access mode. + * User action: + * None. + */ + +/*? + * Text: "DCSS %s of range %p to %p and type %s loaded in shared access mode\n" + * Severity: Informational + * Parameter: + * @1: DCSS name + * @2: starting page address + * @3: ending page address + * @4: DCSS type + * Description: + * The DCSS was loaded successfully in shared access mode. + * User action: + * None. + */ + +/*? + * Text: "DCSS %s is already in the requested access mode\n" + * Severity: Informational + * Parameter: + * @1: DCSS name + * Description: + * A request to reload a DCSS with a new access mode has been rejected + * because the new access mode is the same as the current access mode. + * User action: + * None. + */ + +/*? + * Text: "DCSS %s is in use and cannot be reloaded\n" + * Severity: Warning + * Parameter: + * @1: DCSS name + * Description: + * Reloading a DCSS in a different access mode has failed because the DCSS is + * being used by one or more device drivers. The DCSS remains loaded with the + * current access mode. + * User action: + * Ensure that the DCSS is not used by any device driver then try again to + * load the DCSS with the new access mode. + */ + +/*? + * Text: "DCSS %s overlaps with used memory resources and cannot be reloaded\n" + * Severity: Warning + * Parameter: + * @1: DCSS name + * Description: + * The DCSS has been unloaded and cannot be reloaded because it overlaps with + * another loaded DCSS or with the memory of the z/VM guest virtual machine + * (guest storage). + * User action: + * Ensure that no DCSS is loaded that has overlapping memory resources + * with the DCSS you want to reload. If the DCSS overlaps with guest storage, + * use the DEF STORE CONFIG z/VM CP command to create a sufficient storage gap + * for the DCSS. For details, see the section about the DCSS device driver in + * "Device Drivers, Features, and Commands". + */ + +/*? + * Text: "Reloading DCSS %s failed with rc=%ld\n" + * Severity: Warning + * Parameter: + * @1: DCSS name + * @2: return code + * Description: + * The DCSS kernel interface used z/VM diagnose call X'64' to reload a DCSS + * in a different access mode. The DCSS was unloaded but z/VM failed to reload + * the DCSS. + * User action: + * For details about the return codes see the section about DIAGNOSE Code + * X'64' in "z/VM CP Programming Services". + */ + +/*? + * Text: "Unloading unknown DCSS %s failed\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * The specified DCSS cannot be unloaded. The DCSS is known to the DCSS device + * driver but not to the DCSS kernel interface. This problem indicates a + * program error in extmem.c. + * User action: + * Report this problem to your support organization. + */ + +/*? + * Text: "Saving unknown DCSS %s failed\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * The specified DCSS cannot be saved. The DCSS is known to the DCSS device + * driver but not to the DCSS kernel interface. This problem indicates a + * program error in extmem.c. + * User action: + * Report this problem to your support organization. + */ + +/*? + * Text: "Saving a DCSS failed with DEFSEG response code %i\n" + * Severity: Error + * Parameter: + * @1: response-code + * Description: + * The DEFSEG z/VM CP command failed to permanently save changes to a DCSS. + * User action: + * Ensure that the z/VM guest virtual machine is authorized to issue + * the CP DEFSEG command (typically privilege class E). + * Look for related messages to find the cause of this error. See also message + * HCPE in the DEFSEG section of the "z/VM CP Command and + * Utility Reference". + */ + +/*? + * Text: "Saving a DCSS failed with SAVESEG response code %i\n" + * Severity: Error + * Parameter: + * @1: response-code + * Description: + * The SAVESEG z/VM CP command failed to permanently save changes to a DCSS. + * User action: + * Ensure that the z/VM guest virtual machine is authorized to issue + * the CP SAVESEG command (typically privilege class E). + * Look for related messages to find the cause of this error. See also message + * HCPE in the SAVESEG section of the "z/VM CP Command and + * Utility Reference". + */ + +/*? + * Text: "DCSS %s cannot be loaded or queried\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * You cannot load or query the specified DCSS because it either is not defined + * in the z/VM hypervisor, or it is a class S DCSS, or it is above 2047 MB + * and the Linux system is a 31-bit system. + * User action: + * Use the CP command "QUERY NSS" to find out if the DCSS is a valid + * DCSS that can be loaded. + */ + +/*? + * Text: "DCSS %s cannot be loaded or queried without z/VM\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * A DCSS is a z/VM resource. Your Linux instance is not running as a z/VM + * guest operating system and, therefore, cannot load DCSSs. + * User action: + * Load DCSSs only on Linux instances that run as z/VM guest operating systems. + */ + +/*? + * Text: "Loading or querying DCSS %s resulted in a hardware error\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * Either the z/VM DIAGNOSE X'64' query or load call issued for the DCSS + * returned with an error. + * User action: + * Look for previous extmem message to find the return code from the + * DIAGNOSE X'64' query or load call. For details about the return codes see + * the section about DIAGNOSE Code X'64' in "z/VM CP Programming Services". + */ + +/*? + * Text: "DCSS %s has multiple page ranges and cannot be loaded or queried\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * You can only load or query a DCSS with multiple page ranges if: + * - The DCSS has 6 or fewer page ranges + * - The page ranges form a contiguous address space + * - The page ranges are of type EW or EN + * User action: + * Check the definition of the DCSS to make sure that the conditions for + * DCSSs with multiple page ranges are met. + */ + +/*? + * Text: "%s needs used memory resources and cannot be loaded or queried\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * You cannot load or query the DCSS because it overlaps with an already + * loaded DCSS or with the memory of the z/VM guest virtual machine + * (guest storage). + * User action: + * Ensure that no DCSS is loaded that has overlapping memory resources + * with the DCSS you want to load or query. If the DCSS overlaps with guest + * storage, use the DEF STORE CONFIG z/VM CP command to create a sufficient + * storage gap for the DCSS. For details, see the section about the DCSS + * device driver in "Device Drivers, Features, and Commands". + */ + +/*? + * Text: "DCSS %s is already loaded in a different access mode\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * The DCSS you are trying to load has already been loaded in a different + * access mode. You cannot simultaneously load the DCSS in different modes. + * User action: + * Reload the DCSS in a different mode or load it with the same mode in which + * it has already been loaded. + */ + +/*? + * Text: "There is not enough memory to load or query DCSS %s\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * The available memory is not enough to load or query the DCSS. + * User action: + * Free some memory and repeat the failed operation. + */ + +/*? + * Text: "DCSS %s overlaps with used storage and cannot be loaded\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * You cannot load the DCSS because it overlaps with an already loaded DCSS + * or with the memory of the z/VM guest virtual machine (guest storage). + * User action: + * Ensure that no DCSS is loaded that has overlapping memory resources + * with the DCSS you want to load. If the DCSS overlaps with guest storage, + * use the DEF STORE CONFIG z/VM CP command to create a sufficient storage gap + * for the DCSS. For details, see the section about the DCSS device driver in + * "Device Drivers, Features, and Commands". + */ + +/*? + * Text: "DCSS %s exceeds the kernel mapping range (%lu) and cannot be loaded\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * @2: kernel mapping range in bytes + * Description: + * You cannot load the DCSS because it exceeds the kernel mapping range limit. + * User action: + * Ensure that the DCSS range is defined below the kernel mapping range. + */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/hmcdrv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/hmcdrv @@ -0,0 +1,22 @@ +/*? + * Text: "Allocating the requested cache size of %zu bytes failed\n" + * Severity: Error + * Parameter: + * @1: size + * Description: + * You cannot use the 'hmcdrv' module. + * Either the cache size that was specified for the 'hmcdrv' module exceeded + * the maximum of 1048576 (1 megabyte), or not enough free memory was + * available. + * If the 'hmcdrv' module was compiled into the kernel, the cache size was + * specified with the 'hmcdrv.cachesize' kernel parameter. + * For a separate 'hmcdrv' module, the cache size was specified with the + * 'cachesize=' module parameter. + * User action: + * Specify a smaller cache size and try again to load the module. + * Do not exceed the maximum specification of 1048576 (1 megabyte). + * If necessary, free some memory and try again. + * If the module is compiled into the kernel, you must reboot Linux to change + * the cache size specification. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/hugetlb +++ linux-oracle-5.4.0/Documentation/kmsg/s390/hugetlb @@ -0,0 +1,13 @@ +/*? + * Text: "hugepagesz= specifies an unsupported page size %s\n" + * Severity: Error + * Parameter: + * @1: size + * Description: + * The hugepagesz= kernel parameter specifies a huge page size + * that is not supported. + * User action: + * Specify "1M" for 1 MB huge pages. These are supported as of z10. + * Specify "2G" for 2 GB huge pages. These are supported as of zEC12 + * and zBC12 machines. + */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/hvc_iucv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/hvc_iucv @@ -0,0 +1,123 @@ +/*? + * Text: "The z/VM IUCV HVC device driver cannot be used without z/VM\n" + * Severity: Notice + * Description: + * The z/VM IUCV hypervisor console (HVC) device driver requires the + * z/VM inter-user communication vehicle (IUCV). + * User action: + * Set "hvc_iucv=" to zero in the kernel parameter line and reboot Linux. + */ + +/*? + * Text: "%lu is not a valid value for the hvc_iucv= kernel parameter\n" + * Severity: Error + * Parameter: + * @1: hvc_iucv_devices + * Description: + * The "hvc_iucv=" kernel parameter specifies the number of z/VM IUCV + * hypervisor console (HVC) terminal devices. + * The parameter value ranges from 0 to 8. + * If zero is specified, the z/VM IUCV HVC device driver is disabled + * and no IUCV-based terminal access is available. + * User action: + * Correct the "hvc_iucv=" setting in the kernel parameter line and + * reboot Linux. + */ + +/*? + * Text: "Creating a new HVC terminal device failed with error code=%d\n" + * Severity: Error + * Parameter: + * @1: errno + * Description: + * The device driver initialization failed to allocate a new + * HVC terminal device. + * A possible cause of this problem is memory constraints. + * User action: + * If the error code is -12 (ENOMEM), consider assigning more memory + * to your z/VM guest virtual machine. + */ + +/*? + * Text: "Registering HVC terminal device as Linux console failed\n" + * Severity: Error + * Description: + * The device driver initialization failed to set up the first HVC terminal + * device for use as Linux console. + * User action: + * If the error code is -12 (ENOMEM), consider assigning more memory + * to your z/VM guest virtual machine. + */ + +/*? + * Text: "Registering IUCV handlers failed with error code=%d\n" + * Severity: Error + * Parameter: + * @1: errno + * Description: + * The device driver initialization failed to register with z/VM IUCV to + * handle IUCV connections, as well as sending and receiving of IUCV messages. + * User action: + * Check for related IUCV error messages and see the errno manual page + * to find out what caused the problem. + */ + +/*? + * Text: "Allocating memory failed with reason code=%d\n" + * Severity: Error + * Parameter: + * @1: reason + * Description: + * The z/VM IUCV hypervisor console (HVC) device driver initialization failed, + * because of a general memory allocation failure. The reason code indicates + * the memory operation that has failed: + * kmem_cache (reason code=1), + * mempool (reason code=2), or + * hvc_iucv_allow= (reason code=3) + * User action: + * Consider assigning more memory to your z/VM guest virtual machine. + */ + +/*? + * Text: "hvc_iucv_allow= does not specify a valid z/VM user ID list\n" + * Severity: Error + * Description: + * The "hvc_iucv_allow=" kernel parameter specifies a comma-separated list + * of z/VM user IDs that are permitted to connect to the z/VM IUCV hypervisor + * device driver. + * The z/VM user IDs in the list must not exceed eight characters and must + * not contain spaces. + * User action: + * Correct the "hvc_iucv_allow=" setting in the kernel parameter line and reboot + * Linux. + */ + +/*? + * Text: "hvc_iucv_allow= specifies too many z/VM user IDs\n" + * Severity: Error + * Description: + * The "hvc_iucv_allow=" kernel parameter specifies a comma-separated list + * of z/VM user IDs that are permitted to connect to the z/VM IUCV hypervisor + * device driver. + * The number of z/VM user IDs that are specified with the "hvc_iucv_allow=" + * kernel parameter exceeds the maximum of 500. + * User action: + * Correct the "hvc_iucv_allow=" setting by reducing the z/VM user IDs in + * the list and reboot Linux. + */ + +/*? + * Text: "A connection request from z/VM user ID %s was refused\n" + * Severity: Informational + * Parameter: + * @1: ID + * Description: + * An IUCV connection request from another z/VM guest virtual machine has been + * refused. The request was from a z/VM guest virtual machine that is not + * listed by the "hvc_iucv_allow=" kernel parameter. + * User action: + * Check the "hvc_iucv_allow=" kernel parameter setting. + * Consider adding the z/VM user ID to the "hvc_iucv_allow=" list in the kernel + * parameter line and reboot Linux. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/hypfs +++ linux-oracle-5.4.0/Documentation/kmsg/s390/hypfs @@ -0,0 +1,56 @@ +/*? + * Text: "The hardware system does not support hypfs\n" + * Severity: Error + * Description: + * hypfs requires DIAGNOSE Code X'204' but this diagnose code is not available + * on your hardware. You need more recent hardware to use hypfs. + * User action: + * None. + */ + +/*? + * Text: "The hardware system does not provide all functions required by hypfs\n" + * Severity: Error + * Description: + * hypfs requires DIAGNOSE Code X'224' but this diagnode code is not available + * on your hardware. You need more recent hardware to use hypfs. + * User action: + * None. + */ + +/*? + * Text: "Updating the hypfs tree failed\n" + * Severity: Error + * Description: + * There was not enough memory available to update the hypfs tree. + * User action: + * Free some memory and try again to update the hypfs tree. Consider assigning + * more memory to your LPAR or z/VM guest virtual machine. + */ + +/*? + * Text: "%s is not a valid mount option\n" + * Severity: Error + * Parameter: + * @1: mount option + * Description: + * hypfs has detected mount options that are not valid. + * User action: + * See "Device Drivers Features and Commands" for information about valid + * mount options for hypfs. + */ + +/*? + * Text: "Initialization of hypfs failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: error code + * Description: + * Initialization of hypfs failed because of resource or hardware constraints. + * Possible reasons for this problem are insufficient free memory or missing + * hardware interfaces. + * User action: + * See errno.h for information about the error codes. + */ + +/*? Text: "Hypervisor filesystem mounted\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/iucv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/iucv @@ -0,0 +1,33 @@ +/*? + * Text: "Defining an interrupt buffer on CPU %i failed with 0x%02x (%s)\n" + * Severity: Warning + * Parameter: + * @1: CPU number + * @2: hexadecimal error value + * @3: short error code explanation + * Description: + * Defining an interrupt buffer for external interrupts failed. Error + * value 0x03 indicates a problem with the z/VM directory entry of the + * z/VM guest virtual machine. This problem can also be caused by a + * program error. + * User action: + * If the error value is 0x03, examine the z/VM directory entry of your + * z/VM guest virtual machine. If the directory entry is correct or if the + * error value is not 0x03, report this problem to your support organization. + */ + +/*? + * Text: "Suspending Linux did not completely close all IUCV connections\n" + * Severity: Warning + * Description: + * When resuming a suspended Linux instance, the IUCV base code found + * data structures from one or more IUCV connections that existed before the + * Linux instance was suspended. Modules that use IUCV connections must close + * these connections when a Linux instance is suspended. This problem + * indicates an error in a program that used an IUCV connection. + * User action: + * Report this problem to your support organization. + */ + +/*? Text: "iucv_external_interrupt: out of memory\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/lcs +++ linux-oracle-5.4.0/Documentation/kmsg/s390/lcs @@ -0,0 +1,169 @@ +/*? + * Text: "%s: Allocating a socket buffer to interface %s failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the LCS device + * @2: network interface + * Description: + * LAN channel station (LCS) devices require a socket buffer (SKB) structure + * for storing incoming data. The LCS device driver failed to allocate an SKB + * structure to the LCS device. A likely cause of this problem is memory + * constraints. + * User action: + * Free some memory and repeat the failed operation. + */ + +/*? + * Text: "%s: Shutting down the LCS device failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the LCS device + * Description: + * A request to shut down a LAN channel station (LCS) device resulted in an + * error. The error is logged in the LCS trace at trace level 4. + * User action: + * Try again to shut down the device. If the error persists, see the LCS trace + * to find out what causes the error. + */ + +/*? + * Text: "%s: Detecting a network adapter for LCS devices failed with rc=%d (0x%x)\n" + * Severity: Error + * Parameter: + * @1: bus ID of the LCS device + * @2: lcs_detect return code in decimal notation + * @3: lcs_detect return code in hexadecimal notation + * Description: + * The LCS device driver could not initialize a network adapter. + * User action: + * Ensure that the physical connection from the port to the network is + * in place. If the error persists, note the return code from the error + * message and contact IBM support. + */ + +/*? + * Text: "%s: A recovery process has been started for the LCS device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the LCS device + * Description: + * The LAN channel station (LCS) device is shut down and restarted. The recovery + * process might have been initiated by a user or started automatically as a + * response to a device problem. + * User action: + * Wait until a message indicates the completion of the recovery process. + */ + +/*? + * Text: "%s: An I/O-error occurred on the LCS device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the LCS device + * Description: + * The LAN channel station (LCS) device reported a problem that can be recovered + * by the LCS device driver. Repeated occurrences of this problem indicate a + * malfunctioning device. + * User action: + * If this problem occurs frequently, initiate a recovery process for the + * device, for example, by writing '1' to the 'recover' sysfs attribute of the + * device. + */ + +/*? + * Text: "%s: A command timed out on the LCS device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the LCS device + * Description: + * The LAN channel station (LCS) device reported a problem that can be recovered + * by the LCS device driver. Repeated occurrences of this problem indicate a + * malfunctioning device. + * User action: + * If this problem occurs frequently, initiate a recovery process for the + * device, for example, by writing '1' to the 'recover' sysfs attribute of the + * device. + */ + +/*? + * Text: "%s: An error occurred on the LCS device, rc=%ld\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the LCS device + * @2: return code + * Description: + * The LAN channel station (LCS) device reported a problem that can be recovered + * by the LCS device driver. Repeated occurrences of this problem indicate a + * malfunctioning device. + * User action: + * If this problem occurs frequently, initiate a recovery process for the + * device, for example, by writing '1' to the 'recover' sysfs attribute of the + * device. + */ + +/*? + * Text: "%s: The LCS device stopped because of an error, dstat=0x%X, cstat=0x%X \n" + * Severity: Warning + * Parameter: + * @1: bus ID of the LCS device + * @2: device status + * @3: subchannel status + * Description: + * The LAN channel station (LCS) device reported an error. The LCS device driver + * might start a device recovery process. + * User action: + * If the device driver does not start a recovery process, initiate a recovery + * process, for example, by writing '1' to the 'recover' sysfs attribute of the + * device. If the problem persists, note the status information provided with + * the message and contact IBM support. + */ + +/*? + * Text: "%s: Starting an LCS device resulted in an error, rc=%d!\n" + * Severity: Error + * Parameter: + * @1: bus ID of the LCS device + * @2: ccw_device_start return code in decimal notation + * Description: + * The LAN channel station (LCS) device driver failed to initialize an LCS + * device. The device is not operational. + * User action: + * Initiate a recovery process, for example, by writing '1' to the 'recover' + * sysfs attribute of the device. If the problem persists, contact IBM support. + */ + +/*? + * Text: "%s: Sending data from the LCS device to the LAN failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: bus ID of the LCS device + * @2: ccw_device_resume return code in decimal notation + * Description: + * The LAN channel station (LCS) device driver could not send data to the LAN + * using the LCS device. This might be a temporary problem. Operations continue + * on the LCS device. + * User action: + * If this problem occurs frequently, initiate a recovery process, for example, + * by writing '1' to the 'recover' sysfs attribute of the device. If the + * problem persists, contact IBM support. + */ + +/*? Text: "Query IPAssist failed. Assuming unsupported!\n" */ +/*? Text: "Stoplan for %s initiated by LGW\n" */ +/*? Text: "Not enough memory to add new multicast entry!\n" */ +/*? Text: "Not enough memory for debug facility.\n" */ +/*? Text: "Adding multicast address failed. Table possibly full!\n" */ +/*? Text: "Error in opening device!\n" */ +/*? Text: "LCS device %s %s IPv6 support\n" */ +/*? Text: "Device %s successfully recovered!\n" */ +/*? Text: "LCS device %s %s Multicast support\n" */ +/*? Text: " Initialization failed\n" */ +/*? Text: "Loading %s\n" */ +/*? Text: "Initialization failed\n" */ +/*? Text: "Terminating lcs module.\n" */ +/*? Text: "Device %s could not be recovered!\n" */ +/*? Text: "Initializing the lcs device driver failed\n" */ +/*? Text: "%s: The lcs device driver failed to recover the device\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/monreader +++ linux-oracle-5.4.0/Documentation/kmsg/s390/monreader @@ -0,0 +1,128 @@ +/*? + * Text: "Reading monitor data failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * The z/VM *MONITOR record device driver failed to read monitor data + * because the IUCV REPLY function failed. The read function against + * the monitor record device returns EIO. All monitor data that has been read + * since the last read with 0 size is incorrect. + * User action: + * Disregard all monitor data that has been read since the last read with + * 0 size. If the device driver has been compiled as a separate module, unload + * and reload the monreader module. If the device driver has been compiled + * into the kernel, reboot Linux. For more information about possible causes + * of the error see the IUCV section in "z/VM CP Programming Services" and + * the *MONITOR section in "z/VM Performance". + */ + +/*? + * Text: "z/VM *MONITOR system service disconnected with rc=%i\n" + * Severity: Error + * Parameter: + * @1: IPUSER SEVER return code + * Description: + * The z/VM *MONITOR record device driver receives monitor records through + * an IUCV connection to the z/VM *MONITOR system service. This connection + * has been severed and the read function of the z/VM *MONITOR device driver + * returns EIO. All data received since the last read with 0 size is incorrect. + * User action: + * Disregard all monitor data read since the last read with 0 size. Close and + * reopen the monitor record device. For information about the IPUSER SEVER + * return codes see "z/VM Performance". + */ + +/*? + * Text: "The read queue for monitor data is full\n" + * Severity: Warning + * Description: + * The read function of the z/VM *MONITOR device driver returns EOVERFLOW + * because not enough monitor data has been read since the monitor device + * has been opened. Monitor data already read are valid and subsequent reads + * return valid data but some intermediate data might be missing. + * User action: + * Be aware that monitor data might be missing. Assure that you regularly + * read monitor data after opening the monitor record device. + */ + +/*? + * Text: "Connecting to the z/VM *MONITOR system service failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: IUCV CONNECT return code + * Description: + * The z/VM *MONITOR record device driver receives monitor records through + * an IUCV connection to the z/VM *MONITOR system service. This connection + * could not be established when the monitor record device was opened. If + * the return code is 15, your z/VM guest virtual machine is not authorized + * to connect to the *MONITOR system service. + * User action: + * If the return code is 15, ensure that the IUCV *MONITOR statement is + * included in the z/VM directory entry for your z/VM guest virtual machine. + * For other IUCV CONNECT return codes see the IUCV section in "CP Programming + * Services" and the *MONITOR section in "z/VM Performance". + */ + +/*? + * Text: "Disconnecting the z/VM *MONITOR system service failed with rc=%i\n" + * Severity: Warning + * Parameter: + * @1: IUCV SEVER return code + * Description: + * The z/VM *MONITOR record device driver receives monitor data through an + * IUCV connection to the z/VM *MONITOR system service. This connection + * could not be closed when the monitor record device was closed. You might + * not be able to resume monitoring. + * User action: + * No immediate action is necessary. If you cannot open the monitor record + * device in the future, reboot Linux. For information about the IUCV SEVER + * return codes see the IUCV section in "CP Programming Services" and the + * *MONITOR section in "z/VM Performance". + */ + +/*? + * Text: "The z/VM *MONITOR record device driver cannot be loaded without z/VM\n" + * Severity: Error + * Description: + * The z/VM *MONITOR record device driver uses z/VM system services to provide + * monitor data about z/VM guest operating systems to applications on Linux. + * On Linux instances that run in environments other than the z/VM hypervisor, + * the z/VM *MONITOR record device driver does not provide any useful + * function and the corresponding monreader module cannot be loaded. + * User action: + * Load the z/VM *MONITOR record device driver only on Linux instances that run + * as guest operating systems of the z/VM hypervisor. If the z/VM *MONITOR + * record device driver has been compiled into the kernel, ignore this message. + */ + +/*? + * Text: "The z/VM *MONITOR record device driver failed to register with IUCV\n" + * Severity: Error + * Description: + * The z/VM *MONITOR record device driver receives monitor data through an IUCV + * connection and needs to register with the IUCV device driver. This + * registration failed and the z/VM *MONITOR record device driver was not + * loaded. A possible cause of this problem is insufficient memory. + * User action: + * Free some memory and try again to load the module. If the z/VM *MONITOR + * record device driver has been compiled into the kernel, you might have to + * configure more memory and reboot Linux. If you do not want to read monitor + * data, ignore this message. + */ + +/*? + * Text: "The specified *MONITOR DCSS %s does not have the required type SC\n" + * Severity: Error + * Parameter: + * @1: DCSS name + * Description: + * The DCSS that was specified with the monreader.mondcss kernel parameter or + * with the mondcss module parameter cannot be a *MONITOR DCSS because it is + * not of type SC. + * User action: + * Confirm that you are using the name of the DCSS that has been configured as + * the *MONITOR DCSS on the z/VM hypervisor. If the default name, MONDCSS, is + * used, omit the monreader.mondcss or mondcss parameter. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/monwriter +++ linux-oracle-5.4.0/Documentation/kmsg/s390/monwriter @@ -0,0 +1,17 @@ +/*? + * Text: "Writing monitor data failed with rc=%i\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * The monitor stream application device driver used the z/VM diagnose call + * DIAG X'DC' to start writing monitor data. z/VM returned an error and the + * monitor data cannot be written. If the return code is 5, your z/VM guest + * virtual machine is not authorized to write monitor data. + * User action: + * If the return code is 5, ensure that your z/VM guest virtual machine's + * entry in the z/VM directory includes the OPTION APPLMON statement. + * For other return codes see the section about DIAGNOSE Code X'DC' + * in "z/VM CP Programming Services". + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/netiucv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/netiucv @@ -0,0 +1,156 @@ +/*? + * Text: "%s: The peer interface of the IUCV device has closed the connection\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the IUCV device + * Description: + * The peer interface on the remote z/VM guest virtual machine has closed the + * connection. Do not expect further packets on this interface. Any packets + * you send to this interface will be dropped. + * User action: + * None. + */ + +/*? + * Text: "%s: The IUCV device failed to connect to z/VM guest %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the IUCV device + * @2: z/VM user ID + * Description: + * The connection cannot be established because the z/VM guest virtual + * machine with the peer interface is not running. + * User action: + * Ensure that the z/VM guest virtual machine with the peer interface is + * running; then try again to establish the connection. + */ + +/*? + * Text: "%s: The IUCV device failed to connect to the peer on z/VM guest %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the IUCV device + * @2: z/VM user ID + * Description: + * The connection cannot be established because the z/VM guest virtual machine + * with the peer interface is not configured for IUCV connections. + * User action: + * Configure the z/VM guest virtual machine with the peer interface for IUCV + * connections; then try again to establish the connection. + */ + +/*? + * Text: "%s: Connecting the IUCV device would exceed the maximum number of IUCV connections\n" + * Severity: Error + * Parameter: + * @1: bus ID of the IUCV device + * Description: + * The connection cannot be established because the maximum number of IUCV + * connections has been reached on the local z/VM guest virtual machine. + * User action: + * Close some of the established IUCV connections on the local z/VM guest + * virtual machine; then try again to establish the connection. + */ + +/*? + * Text: "%s: z/VM guest %s has too many IUCV connections to connect with the IUCV device\n" + * Severity: Error + * Parameter: + * @1: bus ID of the IUCV device + * @2: remote z/VM user ID + * Description: + * Connecting to the remote z/VM guest virtual machine failed because the + * maximum number of IUCV connections for the remote z/VM guest virtual + * machine has been reached. + * User action: + * Close some of the established IUCV connections on the remote z/VM guest + * virtual machine; then try again to establish the connection. + */ + +/*? + * Text: "%s: The IUCV device cannot connect to a z/VM guest with no IUCV authorization\n" + * Severity: Error + * Parameter: + * @1: bus ID of the IUCV device + * Description: + * Because the remote z/VM guest virtual machine is not authorized for IUCV + * connections, the connection cannot be established. + * User action: + * Add the statements 'IUCV ALLOW' and 'IUCV ANY' to the z/VM directory + * entry of the remote z/VM guest virtual machine; then try again to + * establish the connection. See "z/VM CP Planning and Administration" + * for details about the IUCV statements. + */ + +/*? + * Text: "%s: Connecting the IUCV device failed with error %d\n" + * Severity: Error + * Parameter: + * @1: bus ID of the IUCV device + * @2: error code + * Description: + * The connection cannot be established because of an IUCV CONNECT error. + * User action: + * Report this problem to your support organization. + */ + +/*? + * Text: "%s: The IUCV device has been connected successfully to %s\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the IUCV device + * @2: remote z/VM user ID + * Description: + * The connection has been established and the interface is ready to + * transmit communication packages. + * User action: + * None. + */ + +/*? + * Text: "%s: The IUCV interface to %s has been established successfully\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the IUCV device + * @2: remote z/VM user ID + * Description: + * The IUCV interface to the remote z/VM guest virtual machine has been + * established and can be activated with "ifconfig up" or an equivalent + * command. + * User action: + * None. + */ + +/*? + * Text: "%s: The IUCV device is connected to %s and cannot be removed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the IUCV device + * @2: remote z/VM user ID + * Description: + * Removing a connection failed because the interface is active with a peer + * interface on a remote z/VM guest virtual machine. + * User action: + * Deactivate the interface with "ifconfig down" or an equivalent command; + * then try again to remove the interface. + */ + +/*? + * Text: "%s: The peer z/VM guest %s has closed the connection\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the IUCV device + * @2: remote z/VM user ID + * Description: + * The peer interface is no longer available. + * User action: + * Either deactivate and remove the interface, or wait for the peer + * z/VM guest to re-establish the interface. + */ + +/*? Text: "driver unloaded\n" */ +/*? Text: "driver initialized\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/numa +++ linux-oracle-5.4.0/Documentation/kmsg/s390/numa @@ -0,0 +1,11 @@ +/*? + * Text: "NUMA mode: %s\n" + * Severity: Informational + * Parameter: + * @1: mode + * Description: + * Linux started with the specified NUMA mode. + * User action: + * None. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/numa_emu +++ linux-oracle-5.4.0/Documentation/kmsg/s390/numa_emu @@ -0,0 +1,50 @@ +/*? + * Text: "Not enough memory for %d nodes, reducing node count\n" + * Severity: Warning + * Parameter: + * @1: requested number of nodes + * Description: + * Using the requested memory stripe size for emulating the requested number of + * NUMA nodes requires more than the available memory. The number of nodes is + * specified with the emu_nodes= kernel parameter. The memory stripe size to + * be used for distributing the available memory among the nodes is specified + * with the emu_size= kernel parameter. Fewer nodes were created than the + * requested number; each node has one memory stripe of the requested size. + * User action: + * Specify fewer nodes, reduce the memory stripe size, or make more memory + * available to your Linux instance. + */ + +/*? + * Text: "Creating %d nodes with memory stripe size %ld MB\n" + * Severity: Informational + * Parameter: + * @1: number of nodes + * @2: stripe size + * Description: + * NUMA emulation is activated with the reported number of NUMA nodes. + * The specified memory stripe size is used to distribute, in round-robin + * fashion, the available memory among the nodes. + * User action: + * None. + */ + +/*? + * Text: "Increasing memory stripe size from %ld MB to %ld MB\n" + * Severity: Warning + * Parameter: + * @1: requested memory stripe size + * @2: adjusted memory stripe size + * Description: + * NUMA emulation could not use the requested memory stripe size and + * therefore has increased it to the next possible value. + * The requested memory stripe size is a default value or it was specified + * with the emu_size= kernel parameter. + * The memory stripe size must be a multiple of the memory block size that + * can be read in hexadecimal notation from + * /sys/devices/system/memory/block_size_bytes. + * User action: + * To avoid this message in the future, specify a valid memory stripe size + * with the emu_size= kernel parameter. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/os_info +++ linux-oracle-5.4.0/Documentation/kmsg/s390/os_info @@ -0,0 +1,36 @@ +/*? + * Text: "entry %i: %s (addr=0x%lx size=%lu)\n" + * Severity: Informational + * Parameter: + * @1: entry ID + * @2: entry state + * @3: entry address + * @4: entry size + * Description: + * Linux is running in kdump mode and reports information defined by the + * previously running production kernel. Possible values for + * "entry state" are: + * + * - copied: The entry has been found, verified, and copied + * + * - not available: The entry has not been defined + * + * - checksum failed: The entry has been found, but it is not valid + * User action: + * If kdump fails, contact your service organization and include this message + * in the error report. + */ + +/*? + * Text: "crashkernel: addr=0x%lx size=%lu\n" + * Severity: Informational + * Parameter: + * @1: address + * @2: size + * Description: + * Linux is running in kdump mode and reports the address and size of + * the memory area that was reserved for kdump by the previously running + * production kernel. + * User action: + * None. + */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/perf +++ linux-oracle-5.4.0/Documentation/kmsg/s390/perf @@ -0,0 +1,90 @@ +/*? + * Text: "CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n" + * Severity: Informational + * Parameter: + * @1: cpu number + * @2: first version number + * @3: second version number + * @4: counter set authorization + * @5: counter set enable controls + * @6: counter set activation controls + * Description: + * This message displays information about the CPU-measurement counter facility + * (CPUM_CF) on a particular CPU. For details, see + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * None. + */ + +/*? + * Text: "CPU[%i] CPUM_SF: basic=%i diag=%i min=%lu max=%lu cpu_speed=%u\n" + * Severity: Informational + * Parameter: + * @1: cpu number + * @2: authorization status for the basic-sampling function + * @3: authorization status for the diagnostic-sampling function + * @4: minimum sampling interval + * @5: maximum sampling interval + * @6: cpu speed + * Description: + * This message displays generic information about the CPU-measurement sampling + * facility (CPUM_SF) on a particular CPU. For details, see + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * None. + */ + +/*? + * Text: "CPU[%i] CPUM_SF: Basic-sampling: a=%i e=%i c=%i bsdes=%i tear=%016lx dear=%016lx\n" + * Severity: Informational + * Parameter: + * @1: cpu number + * @2: authorization control + * @3: enable control + * @4: activation control + * @5: basic-sampling-data-entry size + * @6: tear register contents + * @7: dear register contents + * Description: + * This message displays information about the basic-sampling function of the + * CPU-measurement sampling facility (CPUM_SF) on a particular CPU. + * For details, see + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * None. + */ + +/*? + * Text: "CPU[%i] CPUM_SF: Diagnostic-sampling: a=%i e=%i c=%i dsdes=%i tear=%016lx dear=%016lx\n" + * Severity: Informational + * Parameter: + * @1: cpu number + * @2: authorization control + * @3: enable control + * @4: activation control + * @5: diagnostic-sampling-data-entry size + * @6: tear register contents + * @7: dear register contents + * Description: + * This message displays information about the diagnostic-sampling function of the + * CPU-measurement sampling facility (CPUM_SF) on a particular CPU. + * For details, see + * "The Load-Program-Parameter and the CPU-Measurement Facilities", SA23-2260. + * User action: + * None. + */ + +/*? + * Text: "The sampling facility is already reserved by %p\n" + * Severity: Warning + * Parameter: + * @1: address of perf sampling support owner + * Description: + * A process tried to reserve the sampling facility support, but it was already + * reserved by another process. + * User action: + * Check whether another process, for example, the perf program or OProfile is + * currently active. Retry activating the sampling facility after the other + * process has ended. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/prng +++ linux-oracle-5.4.0/Documentation/kmsg/s390/prng @@ -0,0 +1,103 @@ +/* prng */ + +/*? + * Text: "prng runs in TDES mode with chunksize=%d and reseed_limit=%u\n" + * Severity: Informational + * Parameter: + * @1: read chunk size in bytes + * @2: reseed limit + * Description: + * The pseudo-random number device driver started in triple DES mode. + * For IBM mainframes earlier than IBM zEnterprise EC12 (zEC12), + * triple DES is the only available mode. + * As of zEC12, the preferred mode is SHA-512. + * User action: + * If triple DES is the expected mode, no action is required. + * Otherwise, verify that the prng started with the mode= module or + * prng.mode= kernel parameter set to a value other than 1. + * The value 1 forces triple DES mode. Also ensure that the mainframe + * runs with the latest firmware level. + */ + +/*? + * Text: "The prng module stopped after running in triple DES mode\n" + * Severity: Informational + * Description: + * The pseudo-random number device driver was running in triple DES mode. + * The device driver module, prng, was unloaded, or it stopped + * because Linux shut down. + * User action: + * None. + */ + +/*? + * Text: "The prng module cannot start in SHA-512 mode\n" + * Severity: Error + * Description: + * The pseudo-random number device driver was loaded with the mode= module parameter + * or the prng.mode= kernel parameter set to 2. This setting forces SHA-512 mode, + * but the required support for MSA 5 is not available. This support requires an IBM + * zEnterprise EC12 (zEC12) or later mainframe. + * User action: + * If your mainframe is earlier than zEC12, set the mode= module or + * prng.mode= kernel parameter to 0 or 1 to run the + * pseudo-random number device driver in triple DES mode. + * Otherwise, ensure that MSA 5 support available. + */ + +/*? + * Text: "prng runs in SHA-512 mode with chunksize=%d and reseed_limit=%u\n" + * Severity: Informational + * Parameter: + * @1: read chunk size in bytes + * @2: reseed limit + * Description: + * The pseudo-random number device driver started in SHA-512 mode. + * As of IBM zEnterprise EC12, this is the preferred mode. + * User action: + * None. + */ + +/*? + * Text: "The prng module stopped after running in SHA-512 mode\n" + * Severity: Informational + * Description: + * The pseudo-random number device driver was running in SHA-512 mode. + * The device driver module, prng, was unloaded, or stopped + * because Linux shut down. + * User action: + * None. + */ + +/*? + * Text: "The prng self test state test for the SHA-512 mode failed\n" + * Severity: Error + * Description: + * The pseudo-random number device driver is not operational because the self test failed. + * After processing a published National Institute of Standards and Technology (NIST) test vector for the + * Deterministic Random Bit Generator (DRBG) algorithm, the device driver + * was not in the expected working state. This failure might indicate + * that the cryptographic software or hardware is not working correctly. + * The processed NIST test vector was: Hash Drbg, Sha-512, Count #0. + * User action: + * Unload and reload the prng module, or + * if prng was compiled into the kernel, restart Linux. + * If the error persists, contact your support organization. + */ + +/*? + * Text: "The prng self test data test for the SHA-512 mode failed\n" + * Severity: Error + * Description: + * The pseudo-random number device driver is not operational because the self test failed. + * After processing a published National Institute of Standards and Technology (NIST) test vector for the + * Deterministic Random Bit Generator (DRBG) algorithm, the device driver + * did not produce the expected pseudo-random data. This failure might indicate + * that the cryptographic software or hardware is not working correctly. + * The processed NIST test vector was: Hash Drbg, Sha-512, Count #0. + * User action: + * Unload and reload the prng module, or + * if prng was compiled into the kernel, restart Linux. + * If the error persists, contact your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/qeth +++ linux-oracle-5.4.0/Documentation/kmsg/s390/qeth @@ -0,0 +1,929 @@ +/*? + * Text: "%s: The LAN is offline\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A start LAN command was sent by the qeth device driver but the physical or + * virtual adapter has not started the LAN. The LAN might take a few seconds + * to become available. + * User action: + * Check the status of the qeth device, for example, with the lsqeth command. + * If the device does not become operational within a few seconds, initiate a + * recovery process, for example, by writing '1' to the 'recover' sysfs + * attribute of the device. + */ + +/*? + * Text: "%s: A recovery process has been started for the device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A recovery process was started either by the qeth device driver or through + * a user command. + * User action: + * Wait until a message indicates the completion of the recovery process. + */ + +/*? + * Text: "%s: The qeth device driver failed to recover an error on the device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth device driver performed an automatic recovery operation to recover + * an error on a qeth device. The recovery operation failed. + * User action: + * Try the following actions in the given order: i) Check the status of the + * qeth device, for example, with the lsqeth command. ii) Initiate a recovery + * process by writing '1' to the 'recover' sysfs attribute of the device. + * iii) Ungroup and regroup the subchannel triplet of the device. vi) Reboot + * Linux. v) If the problem persists, gather Linux debug data and report the + * problem to your support organization. + */ + +/*? + * Text: "%s: Device recovery failed to restore all offload features\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth device driver performed a recovery operation on a qeth device. Part + * of the recovery is to restore the offload features that were enabled before + * the recovery. At least one of those offload features could not be restored. + * User action: + * Check which offload features are enabled on the device, for example with + * the "ethtool -k" command. Try to explicitly re-enable the missing offload + * features for the device, for example with the "ethtool -K" command. + */ + +/*? + * Text: "%s: The link for interface %s on CHPID 0x%X failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * @3: CHPID + * Description: + * A network link failed. A possible reason for this error is that a physical + * network cable has been disconnected. + * User action: + * Ensure that the network cable on the adapter hardware is connected properly. + * If the connection is to a guest LAN, ensure that the device is still coupled + * to the guest LAN. + */ + +/*? + * Text: "%s: The link for %s on CHPID 0x%X has been restored\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * @3: CHPID + * Description: + * A failed network link has been re-established. A device recovery is in + * progress. + * User action: + * Wait until a message indicates the completion of the recovery process. + */ + +/*? + * Text: "%s: A hardware operation timed out on the device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A hardware operation timed out on the qeth device. + * User action: + * Check the status of the qeth device, for example, with the lsqeth command. + * If the device is not operational, initiate a recovery process, for example, + * by writing '1' to the 'recover' sysfs attribute of the device. + */ + +/*? + * Text: "%s: The adapter hardware is of an unknown type\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth device driver does not recognize the adapter hardware. The cause + * of this problem could be a hardware error or a Linux level that does not + * support your adapter hardware. + * User action: + * i) Investigate if your adapter hardware is supported by your Linux level. + * Consider using hardware that is supported by your Linux level or upgrading + * to a Linux level that supports your hardware. ii) Install the latest + * firmware on your adapter hardware. iii) If the problem persists and is not + * caused by a version mismatch, contact IBM support. + */ + +/*? + * Text: "%s: The adapter is used exclusively by another host\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth adapter is exclusively used by another host. + * User action: + * Use another qeth adapter or configure this one not exclusively to a + * particular host. + */ + +/*? + * Text: "%s: QDIO reported an error, rc=%i\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: return code + * Description: + * The QDIO subsystem reported an error. + * User action: + * Check for related QDIO errors. Check the status of the qeth device, for + * example, with the lsqeth command. If the device is not operational, initiate + * a recovery process, for example, by writing '1' to the 'recover' sysfs + * attribute of the device. + */ + +/*? + * Text: "%s: There is no kernel module to support discipline %d\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * @2: discipline + * Description: + * The qeth device driver or a user command requested a kernel module for a + * particular qeth discipline. Either the discipline is not supported by the + * qeth device driver or the requested module is not available to your Linux + * system. + * User action: + * Check if the requested discipline module has been compiled into the kernel + * or is present in /lib/modules//kernel/drivers/s390/net. + */ + +/*? + * Text: "Initializing the qeth device driver failed\n" + * Severity: Error + * Parameter: + * Description: + * The base module of the qeth device driver could not be initialized. + * User action: + * See errno.h to determine the reason for the error. + * i) Reboot Linux. ii) If the problem persists, gather Linux debug data and + * report the problem to your support organization. + */ + +/*? + * Text: "%s: Registering IP address %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: IP address + * Description: + * An IP address could not be registered with the network adapter. + * User action: + * Check if another operating system instance has already registered the + * IP address with the same network adapter or at the same logical IP subnet. + */ + +/*? + * Text: "%s: Reading the adapter MAC address failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth device driver could not read the MAC address from the network + * adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Starting ARP processing support for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not start ARP support on the network adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Starting IP fragmentation support for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not start IP fragmentation support on the + * network adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Starting VLAN support for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not start VLAN support on the network adapter. + * User action: + * None if you do not require VLAN support. If you need VLAN support, + * ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Starting multicast support for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not start multicast support on the network + * adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Activating IPv6 support for %s failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not activate IPv6 support on the network + * adapter. + * User action: + * None if you do not require IPv6 communication. If you need IPv6 support, + * ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Enabling the passthrough mode for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not enable the passthrough mode on the + * network adapter. The passthrough mode is required for all network traffic + * other than IPv4. In particular, the passthrough mode is required for IPv6 + * traffic. + * User action: + * None if all you want to support is IPv4 communication. If you want to support + * IPv6 or other network traffic apart from IPv4, ungroup and regroup the + * subchannel triplet of the device. If this does not resolve the problem, + * reboot Linux. If the problem persists, gather Linux debug data and report + * the problem to your support organization. + */ + +/*? + * Text: "%s: Enabling broadcast filtering for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not enable broadcast filtering on the network + * adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Setting up broadcast filtering for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not set up broadcast filtering on the network + * adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Setting up broadcast echo filtering for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not set up broadcast echo filtering on the + * network adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: Starting HW checksumming for %s failed, using SW checksumming\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The network adapter supports hardware checksumming for IP packages + * but the qeth device driver could not start hardware checksumming on the + * adapter. The qeth device driver continues to use software checksumming for + * IP packages. + * User action: + * None if you do not require hardware checksumming for network + * traffic. If you want to enable hardware checksumming, ungroup and regroup + * the subchannel triplet of the device. If this does not resolve the problem, + * reboot Linux. If the problem persists, gather Linux debug data and report + * the problem to your support organization. + */ + +/*? + * Text: "%s: Enabling HW checksumming for %s failed, using SW checksumming\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The network adapter supports hardware checksumming for IP packages + * but the qeth device driver could not enable hardware checksumming on the + * adapter. The qeth device driver continues to use software checksumming for + * IP packages. + * User action: + * None if you do not require hardware checksumming for network + * traffic. If you want to enable hardware checksumming, ungroup and regroup + * the subchannel triplet of the device. If this does not resolve the problem, + * reboot Linux. If the problem persists, gather Linux debug data and report + * the problem to your support organization. + */ + +/*? + * Text: "%s: Starting outbound TCP segmentation offload for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The network adapter supports TCP segmentation offload, but the qeth device + * driver could not start this support on the adapter. + * User action: + * None if you do not require TCP segmentation offload. If you want to + * enable TCP segmentation offload, ungroup and regroup the subchannel triplet + * of the device. If this does not resolve the problem, reboot Linux. If the + * problem persists, gather Linux debug data and report the problem to your + * support organization. + */ + +/*? + * Text: "%s: The network adapter failed to generate a unique ID\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * In IBM mainframe environments, network interfaces are not identified by + * a specific MAC address. Therefore, the network adapters provide the network + * interfaces with unique IDs to be used in their IPv6 link local addresses. + * Without such a unique ID, duplicate addresses might be assigned in other + * LPARs. + * User action: + * Install the latest firmware on the adapter hardware. Manually, configure + * an IPv6 link local address for this device. + */ + +/*? + * Text: "There is no IPv6 support for the layer 3 discipline\n" + * Severity: Warning + * Description: + * If you want to use IPv6 with the layer 3 discipline, you need a Linux kernel + * with IPv6 support. Because your Linux kernel has not been compiled with + * IPv6 support, you cannot use IPv6 with the layer 3 discipline, even if your + * adapter supports IPv6. + * User action: + * Use a Linux kernel that has been complied to include IPv6 support if you + * want to use IPv6 with layer 3 qeth devices. + */ + +/*? + * Text: "%s: The qeth device is not configured for the OSI layer required by z/VM\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A qeth device that connects to a virtual network on z/VM must be configured for the + * same Open Systems Interconnection (OSI) layer as the virtual network. An ETHERNET + * guest LAN or VSWITCH uses the data link layer (layer 2) while an IP guest LAN + * or VSWITCH uses the network layer (layer 3). + * User action: + * If you are connecting to an ETHERNET guest LAN or VSWITCH, set the layer2 sysfs + * attribute of the qeth device to 1. If you are connecting to an IP guest LAN or + * VSWITCH, set the layer2 sysfs attribute of the qeth device to 0. + */ + +/*? + * Text: "%s: Starting source MAC-address support for %s failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The qeth device driver could not enable source MAC-address on the network + * adapter. + * User action: + * Ungroup and regroup the subchannel triplet of the device. If this does not + * resolve the problem, reboot Linux. If the problem persists, gather Linux + * debug data and report the problem to your support organization. + */ + +/*? + * Text: "%s: MAC address %pM already exists\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: MAC-address + * Description: + * Setting the MAC address for the qeth device fails, because this + * MAC address is already defined on the OSA CHPID. + * User action: + * Use a different MAC address for this qeth device. + */ + +/*? + * Text: "%s: MAC address %pM is not authorized\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: MAC-address + * Description: + * This qeth device is a virtual network interface card (NIC), to which z/VM + * has already assigned a MAC address. z/VM MAC address verification does + * not allow you to change this predefined address. + * User action: + * None; use the MAC address that has been assigned by z/VM. + */ + +/*? + * Text: "%s: The HiperSockets network traffic analyzer is activated\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The sysfs 'sniffer' attribute of the HiperSockets device has the value '1'. + * The corresponding HiperSockets interface has been switched into promiscuous mode. + * As a result, the HiperSockets network traffic analyzer is started on the device. + * User action: + * None. + */ + + /*? + * Text: "%s: The HiperSockets network traffic analyzer is deactivated\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The sysfs 'sniffer' attribute of the HiperSockets device has the value '1'. + * Promiscuous mode has been switched off for the corresponding HiperSockets interface + * As a result, the HiperSockets network traffic analyzer is stopped on the device. + * User action: + * None. + */ + +/*? + * Text: "%s: The device is not authorized to run as a HiperSockets network traffic analyzer\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The sysfs 'sniffer' attribute of the HiperSockets device has the value '1'. + * The corresponding HiperSockets interface is switched into promiscuous mode + * but the network traffic analyzer (NTA) rules configured at the Support Element (SE) + * do not allow tracing. Possible reasons are: + * - Tracing is not authorized for all HiperSockets LANs in the mainframe system + * - Tracing is not authorized for this HiperSockets LAN + * - LPAR is not authorized to enable an NTA + * User action: + * Configure appropriate HiperSockets NTA rules at the SE. + */ + +/*? + * Text: "%s: A HiperSockets network traffic analyzer is already active in the HiperSockets LAN\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The sysfs 'sniffer' attribute of the HiperSockets device has the value '1'. + * The HiperSockets interface is switched into promiscuous mode but another + * HiperSockets device on the same HiperSockets LAN is already running as + * a network traffic analyzer. + * A HiperSockets LAN can only have one active network traffic analyzer. + * User action: + * Do not configure multiple HiperSockets devices in the same HiperSockets LAN as + * tracing devices. + */ + +/*? + * Text: "%s: Enabling HW TX checksumming for %s failed, using SW TX checksumming\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * Description: + * The network adapter supports hardware checksumming for outgoing IP packages + * but the qeth device driver could not enable hardware TX checksumming on the + * adapter. The qeth device driver continues to use software checksumming for + * outgoing IP packages. + * User action: + * None if you do not require hardware checksumming for outgoing network + * traffic. If you want to enable hardware checksumming, ungroup and regroup + * the subchannel triplet of the device. If this does not resolve the problem, + * reboot Linux. If the problem persists, gather Linux debug data and report + * the problem to your support organization. + */ + +/*? + * Text: "%s: A connection could not be established because of an OLM limit\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * z/OS has activated Optimized Latency Mode (OLM) for a connection through an OSA Express3 adapter. + * This reduces the maximum number of concurrent connections per physical port for shared adapters. + * The new connection would exceed the maximum. Linux cannot establish further connections using + * this adapter. + * User action: + * If possible, deactivate an existing connection that uses this adapter and try again to establish + * the new connection. If you cannot free an existing connection, use a different adapter for the + * new connection. + */ + +/*? + * Text: "%s: Setting the device online failed because of insufficient authorization\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The qeth device is configured with OSX CHPIDs. An OSX CHPID cannot be activated unless the LPAR is explicitly authorized to access it. + * For z/VM guest operating systems, the z/VM user ID must be explicitly authorized in addition to the LPAR. + * You grant these authorizations through the Service Element. + * User action: + * At the Service Element, authorize the LPAR and, if applicable, the z/VM user ID for using the OSX CHPIDs with which the qeth device has been configured. + * Then try again to set the device online. + */ + +/*? + * Text: "%s: portname is deprecated and is ignored\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * An OSA-Express port name was required to identify a shared OSA port. + * All operating system instances that shared the port had to use the same port name. + * This requirement no longer applies, and the specified portname attribute is ignored. + * User action: + * For future upgrades, remove OSA port name specifications from your + * network configuration. + */ + +/*? Text: "core functions removed\n" */ +/*? Text: "%s: Device is a%s card%s%s%s\nwith link type %s.\n" */ +/*? Text: "%s: issue_next_read failed: no iob available!\n" */ +/*? Text: "%s: Priority Queueing not supported\n" */ +/*? Text: "%s: sense data available. cstat 0x%X dstat 0x%X\n" */ +/*? Text: "loading core functions\n" */ +/*? Text: "%s: MAC address %pM successfully registered on device %s\n" */ +/*? Text: "%s: Device successfully recovered!\n" */ +/*? Text: "register layer 2 discipline\n" */ +/*? Text: "unregister layer 2 discipline\n" */ +/*? Text: "%s: Hardware IP fragmentation not supported on %s\n" */ +/*? Text: "%s: IPv6 not supported on %s\n" */ +/*? Text: "%s: VLAN not supported on %s\n" */ +/*? Text: "%s: Inbound source MAC-address not supported on %s\n" */ +/*? Text: "%s: IPV6 enabled\n" */ +/*? Text: "%s: ARP processing not supported on %s!\n" */ +/*? Text: "%s: Hardware IP fragmentation enabled \n" */ +/*? Text: "%s: set adapter parameters not supported.\n" */ +/*? Text: "%s: VLAN enabled\n" */ +/*? Text: "register layer 3 discipline\n" */ +/*? Text: "%s: Outbound TSO enabled\n" */ +/*? Text: "%s: Broadcast not supported on %s\n" */ +/*? Text: "%s: Outbound TSO not supported on %s\n" */ +/*? Text: "%s: Inbound HW Checksumming not supported on %s,\ncontinuing using Inbound SW Checksumming\n" */ +/*? Text: "%s: Using no checksumming on %s.\n" */ +/*? Text: "%s: Broadcast enabled\n" */ +/*? Text: "%s: Multicast not supported on %s\n" */ +/*? Text: "%s: Using SW checksumming on %s.\n" */ +/*? Text: "%s: HW Checksumming (%sbound) enabled\n" */ +/*? Text: "unregister layer 3 discipline\n" */ +/*? Text: "%s: Multicast enabled\n" */ +/*? Text: "%s: QDIO data connection isolation is deactivated\n" */ +/*? Text: "%s: QDIO data connection isolation is activated\n" */ +/*? Text: "%s: Adapter does not support QDIO data connection isolation\n" */ +/*? Text: "%s: Adapter is dedicated. QDIO data connection isolation not supported\n" */ +/*? Text: "%s: TSO does not permit QDIO data connection isolation\n" */ +/*? Text: "%s: HW TX Checksumming enabled\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "qeth_l3: ignoring TR device\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ + +/*? + * Text: "%s: Turning off reflective relay mode at the adjacent switch failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The policy for the QDIO data connection isolation was + * changed successfully, and communications are now handled according to the + * new policy. The ISOLATION_FORWARD policy is no longer used, but the qeth + * device driver could not turn off the reflective relay mode on the adjacent + * switch port. + * User action: + * Check the adjacent switch for errors and correct the problem. + */ + +/*? + * Text: "%s: The adjacent switch port does not support reflective relay mode\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The 'isolation' sysfs attribute of the qeth device could not be set to 'forward'. + * This setting selects the ISOLATION_FORWARD policy for the QDIO data connection + * isolation. The ISOLATION_FORWARD policy requires a network adapter in Virtual + * Ethernet Port Aggregator (VEPA) mode with an adjacent switch port in reflective + * relay mode. + * User action: + * Use a switch port that supports reflective relay mode if you want to use the + * ISOLATION_FORWARD policy for the qeth device. + */ + +/*? + * Text: "%s: The reflective relay mode cannot be enabled at the adjacent switch port" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The 'isolation' sysfs attribute of the qeth device could not be set to 'forward'. + * This setting selects the ISOLATION_FORWARD policy for the QDIO data connection + * isolation. The ISOLATION_FORWARD policy requires a network adapter in Virtual + * Ethernet Port Aggregator (VEPA) mode with an adjacent switch port in reflective relay + * mode. The qeth device driver failed to enable the required reflective relay mode on + * the adjacent switch port although the switch port supports this mode. + * User action: + * Enable reflective relay mode on the switch for the adjacent port and try again. + */ + +/*? + * Text: "%s: Interface %s is down because the adjacent port is no longer in reflective relay mode\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * @2: interface name + * Description: + * The ISOLATION_FORWARD policy is active for the QDIO data connection isolation + * of the qeth device. This policy requires a network adapter in Virtual Ethernet + * Port Aggregator (VEPA) mode with an adjacent switch port in reflective relay mode. + * The reflective relay mode on the adjacent switch port was disabled. The qeth device + * was set offline and the interface was deactivated to prevent any unintended network traffic. + * User action: + * Enable the reflective relay mode again on the adjacent port or use the 'isolation' + * sysfs attribute of the qeth device to set a different policy for the QDIO data connection + * isolation. You can then resume operations by setting the qeth device back + * online and activating the interface. + */ + +/*? + * Text: "%s: Failed to create completion queue\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The HiperSockets device could not be configured with a completion queue. + * A completion queue is required to operate AF_IUCV communication in an LPAR. + * User action: + * i) Investigate if you have the latest firmware level in place. + * ii) If the problem persists and is not caused by a version mismatch, contact IBM + * support. + */ + +/*? + * Text: "%s: Completion Queueing supported\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The HiperSockets device supports completion queueing. This is required to + * set up AF_IUCV communication in an LPAR. + */ + +/*? + * Text: "%s: Completion Queue support enabled" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The HiperSockets device is enabled for completion queueing. This is part of + * the process to set up AF_IUCV communication in an LPAR. + */ + +/*? + * Text: "%s: Completion Queue support disabled" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The HiperSockets device is disabled for completion queueing. This device + * cannot or no longer be used to set up AF_IUCV communication in an LPAR. + */ + +/*? + * Text: "%s: The device represents a Bridge Capable Port\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * Description: + * You can configure this device as a Bridge Port. + * User action: + * None. + */ + +/*? + * Text: "%s: The device is not configured as a Bridge Port\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The Bridge Port role cannot be withdrawn from a device + * that is not configured as a Bridge Port. + * User action: + * None. + */ + +/*? + * Text: "%s: The LAN already has a primary Bridge Port\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A LAN can have multiple secondary Bridge Ports, but only + * one primary Bridge Port. Configuring the device as a + * primary Bridge Port failed because another port on the + * LAN has been configured as the primary Bridge Port. + * User action: + * Find out which operating system instance has configured the primary + * Bridge Port. Assure that the primary role for this port is withdrawn + * before trying again to configure your device as the primary Bridge + * Port. Alternatively, consider configuring your device as a secondary + * Bridge Port. + */ + +/*? + * Text: "%s: The device is already a secondary Bridge Port\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A device cannot be configured as a primary or secondary + * Bridge Port if it is already configured as a secondary Bridge Port. + * User action: + * None, if you want the device to be a secondary Bridge Port. + * If you want to configure the device as the primary Bridge Port, + * withdraw the secondary role by writing 'none' to the 'bridgeport_role' + * sysfs attribute of the device. Then try again to configure the + * device as the primary Bridge Port. + */ + +/*? + * Text: "%s: The LAN cannot have more secondary Bridge Ports\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A LAN can have up to five secondary Bridge Ports. + * You cannot configure a further device as a secondary + * Bridge Port unless the Bridge Ports role is withdrawn from one of + * the existing secondary Bridge Ports. + * User action: + * Assure that the Bridge Port role is withdrawn from one of the + * existing secondary Bridge Ports before trying again to configure your + * device as a secondary Bridge Port. + */ + +/*? + * Text: "%s: The device is already a primary Bridge Port\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * A device cannot be configured as a primary or secondary + * Bridge Port if it is already configured as a primary Bridge Port. + * User action: + * None, if you want the device to be a primary Bridge Port. + * If you want to configure the device as a secondary Bridge Port, + * withdraw the primary role by writing 'none' to the 'bridgeport_role' + * sysfs attribute of the device. Then try again to configure the + * device as the secondary Bridge Port. + */ + +/*? + * Text: "%s: The device is not authorized to be a Bridge Port\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * The device cannot be configured as a Bridge Port because + * the required authorizations in the hardware are not in place. + * User action: + * See your hardware documentation about how to authorize + * ports for becoming a Bridge Port. + */ + +/*? + * Text: "%s: A Bridge Port is already configured by a different operating system\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * Linux instances cannot configure the target port as a Bridge Port. + * Another operating system already uses a Bridge Port on the HiperSockets + * or on the OSA adapter. For example, a z/VM instance might be using + * a port in a VSWITCH configuration. Multiple Bridge Ports on the same + * HiperSockets or OSA adapter must be configured by instances of the same + * operating system, for example, all Linux or all z/VM. + * User action: + * Reconsider your network topology. Configure Bridge Ports only for ports + * on adapters where any other Bridge Ports are configured by other Linux + * instances. + */ + +/*? + * Text: "%s: Setting address notification failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the qeth device + * Description: + * Enabling or disabling the address notification feature of a + * HiperSockets device failed. The device might not be configured as a + * Bridge Port. + * User action: + * None, unless you need address notifications for this device. + * If you need notifications, confirm that your device is attached to a + * HiperSockets LAN that supports Bridge Capable Ports and that your + * device is configured as a Bridge Port. If the 'bridgeport_role' + * sysfs attribute of the device contains, one of the values 'primary' + * or 'secondary' and you cannot set the address notification, contact + * your support organization. + */ + +/*? + * Text: "%s: Address notification from the Bridge Port stopped %s (%s)\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the qeth device + * @2: network interface name + * @3: error reported by the hardware + * Description: + * A Bridge Port no longer provides address notifications. + * Possible reasons include traffic overflow and that the device is no + * longer configured as a Bridge Port. A udev event with + * BRIDGEDHOST=abort was emitted to alert applications that rely on the + * address notifications. + * User action: + * None. + */ + +/*? + * Text: "%s: The qeth driver ran out of channel command buffers\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the qeth device + * Description: + * Command buffers can temporarily run out during periods of + * intense network configuration activities. + * The device driver recovers from this condition as outstanding + * commands are completed. + * User action: + * Wait for a short time. If the problem persists, + * initiate a recovery process by writing '1' to the 'recover' + * sysfs attribute of the device. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/s390dbf +++ linux-oracle-5.4.0/Documentation/kmsg/s390/s390dbf @@ -0,0 +1,83 @@ +/*? + * Text: "Root becomes the owner of all s390dbf files in sysfs\n" + * Severity: Warning + * Description: + * The S/390 debug feature you are using only supports uid/gid = 0. + * User action: + * None. + */ + +/*? + * Text: "Registering debug feature %s failed\n" + * Severity: Error + * Parameter: + * @1: feature name + * Description: + * The initialization of an S/390 debug feature failed. A likely cause of this + * problem is memory constraints. The system keeps running, but the debug + * data for this feature will not be available in sysfs. + * User action: + * Consider assigning more memory to your LPAR or z/VM guest virtual machine. + */ + +/*? + * Text: "Registering view %s/%s would exceed the maximum number of views %i\n" + * Severity: Error + * Parameter: + * @1: feature name + * @2: view name + * @3: maximum + * Description: + * The maximum number of allowed debug feature views has been reached. The + * view has not been registered. The system keeps running but the new view + * will not be available in sysfs. This is a program error. + * User action: + * Report this problem to your support partner. + */ + +/*? + * Text: "%s is not a valid level for a debug feature\n" + * Severity: Warning + * Parameter: + * @1: level + * Description: + * Setting a new level for a debug feature by using the 'level' sysfs attribute + * failed. Valid levels are the minus sign (-) and the integers in the + * range 0 to 6. The minus sign switches off the feature. The numbers switch + * the feature on, where higher numbers produce more debug output. + * User action: + * Write a valid value to the 'level' sysfs attribute. + */ + +/*? + * Text: "Flushing debug data failed because %c is not a valid area\n" + * Severity: Informational + * Parameter: + * @1: debug area number + * Description: + * Flushing a debug area by using the 'flush' sysfs attribute failed. Valid + * values are the minus sign (-) for flushing all areas, or the number of the + * respective area for flushing a single area. + * User action: + * Write a valid area number or the minus sign (-) to the 'flush' sysfs + * attribute. + */ + +/*? + * Text: "Allocating memory for %i pages failed\n" + * Severity: Informational + * Parameter: + * @1: number of pages + * Description: + * Setting the debug feature size by using the 'page' sysfs attribute failed. + * Linux did not have enough memory for expanding the debug feature to the + * requested size. + * User action: + * Use a smaller number of pages for the debug feature or allocate more + * memory to your LPAR or z/VM guest virtual machine. + */ + +/*? Text: "%s: set new size (%i pages)\n" */ +/*? Text: "%s: switched off\n" */ +/*? Text: "%s: level %i is out of range (%i - %i)\n" */ +/*? Text: "Registering view %s/%s failed due to out of memory\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/sclp_cmd +++ linux-oracle-5.4.0/Documentation/kmsg/s390/sclp_cmd @@ -0,0 +1,44 @@ +/*? Text: "sync request failed (cmd=0x%08x, status=0x%02x)\n" */ +/*? Text: "readcpuinfo failed (response=0x%04x)\n" */ +/*? Text: "configure cpu failed (cmd=0x%08x, response=0x%04x)\n" */ +/*? Text: "configure channel-path failed (cmd=0x%08x, response=0x%04x)\n" */ +/*? Text: "read channel-path info failed (response=0x%04x)\n" */ +/*? Text: "assign storage failed (cmd=0x%08x, response=0x%04x, rn=0x%04x)\n" */ +/*? Text: "configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n" */ +/*? Text: "request failed (status=0x%02x)\n" */ +/*? Text: "request failed with response code 0x%x\n" */ + +/*? + * Text: "Memory hotplug state changed, suspend refused.\n" + * Severity: Error + * Description: + * Suspend is refused after a memory hotplug operation was performed. + * User action: + * The system needs to be restarted and no memory hotplug operation must be + * performed in order to allow suspend. + */ + +/*? + * Text: "Standby memory at 0x%llx (%lluM of %lluM usable)\n" + * Severity: Informational + * Parameter: + * @1: start address of standby memory + * @2: usable memory in MB + * @3: total detected memory in MB + * Description: + * Standby memory was detected. It can be used for memory hotplug only + * if it is aligned to the Linux hotplug memory block size. + * If the aligned amount of memory matches the total amount, + * all detected standby memory can be used. Otherwise, some of the detected + * memory is unaligned and cannot be used. + * User action: + * None, if the usable and the total amount of detected standby memory match. + * If the amounts of memory do not match, + * check the memory setup of your guest virtual machine and ensure that + * the standby memory start and end + * address is aligned to the Linux hotplug memory block size. + * On Linux, issue "cat /sys/devices/system/memory/block_size_bytes" + * to find the hotplug memory block size value in hexadecimal notation. + * On z/VM, query your memory setup with "vmcp q v store". + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/sclp_config +++ linux-oracle-5.4.0/Documentation/kmsg/s390/sclp_config @@ -0,0 +1,15 @@ +/*? + * Text: "CPU capability may have changed\n" + * Severity: Informational + * Description: + * The capability of the CPUs in the configuration may have been upgraded + * or downgraded. This message may also appear if the capability of the + * CPUs in the configuration did not change. + * For details see the STORE SYSTEM INFORMATION description in the + * "Principles of Operation." + * User action: + * The user can examine /proc/sysinfo for CPU capability values. + */ +/*? Text: "Open for Business request failed with response code 0x%04x\n" */ +/*? Text: "SCLP receiver did not register to receive Configuration Management Data Events.\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/sclp_cpi +++ linux-oracle-5.4.0/Documentation/kmsg/s390/sclp_cpi @@ -0,0 +1,3 @@ +/*? Text: "request failed (status=0x%02x)\n" */ +/*? Text: "request failed with response code 0x%x\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/sclp_ocf +++ linux-oracle-5.4.0/Documentation/kmsg/s390/sclp_ocf @@ -0,0 +1 @@ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/sclp_sdias +++ linux-oracle-5.4.0/Documentation/kmsg/s390/sclp_sdias @@ -0,0 +1,4 @@ +/*? Text: "sclp_send failed for get_nr_blocks\n" */ +/*? Text: "SCLP error: %x\n" */ +/*? Text: "sclp_send failed: %x\n" */ +/*? Text: "Error from SCLP while copying hsa. Event status = %x\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/scm_block +++ linux-oracle-5.4.0/Documentation/kmsg/s390/scm_block @@ -0,0 +1,51 @@ +/*? + * Text: "%lx: The capabilities of the SCM increment changed\n" + * Severity: Informational + * Parameter: + * @1: start address of the SCM increment + * Description: + * A configuration change is in progress for the storage class memory (SCM) + * increment. + * User action: + * Verify that the capability of the SCM increment is as intended; for + * example, with lsscm. + */ + +/*? + * Text: "An I/O operation to SCM failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * An error occurred during I/O to storage class memory (SCM). The operation + * was repeated, but the maximum number of retries was exceeded before the + * request could be fulfilled. + * User action: + * Contact your support organization. + */ + +/*? + * Text: "%lx: Write access to the SCM increment is suspended\n" + * Severity: Informational + * Parameter: + * @1: start address of the SCM increment + * Description: + * A concurrent firmware upgrade is in progress. For the duration of the + * upgrade, write access to the storage class memory (SCM) increment has been + * suspended. + * User action: + * None. + */ + +/*? + * Text: "%lx: Write access to the SCM increment is restored\n" + * Severity: Informational + * Parameter: + * @1: start address of the SCM increment + * Description: + * Write access to the storage class memory (SCM) increment was restored + * after a temporary suspension during a concurrent firmware upgrade. + * User action: + * None. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/setup +++ linux-oracle-5.4.0/Documentation/kmsg/s390/setup @@ -0,0 +1,165 @@ +/*? + * Text: "The initial RAM disk does not fit into the memory\n" + * Severity: Error + * Description: + * The load address and the size of the initial RAM disk specify a memory + * area that is not available. + * User action: + * Lower the load address of the initial RAM disk, reduce the size of the + * initial RAM disk, or increase the size of the system memory to make the + * initial RAM disk fit into the memory. + */ + +/*? + * Text: "The maximum memory size is %luMB\n" + * Severity: Notice + * Parameter: + * @1: size in MB + * Description: + * The system memory size cannot exceed the amount of memory that is + * provided by the real or virtual hardware. It can be further reduced + * through an upper memory address limit that is specified with the + * mem= kernel parameter. + * User action: + * None. + */ + +/*? + * Text: "Linux is running as a z/VM guest operating system in 31-bit mode\n" + * Severity: Informational + * Description: + * The 31-bit Linux kernel detected that it is running as a guest operating + * system of the z/VM hypervisor. + * User action: + * None. + */ + +/*? + * Text: "Linux is running natively in 31-bit mode\n" + * Severity: Informational + * Description: + * The 31-bit Linux kernel detected that it is running on an IBM mainframe, + * either as the sole operating system in an LPAR or as the sole operating + * system on the entire mainframe. The Linux kernel is not running as a + * guest operating system of the z/VM hypervisor. + * User action: + * None. + */ + +/*? + * Text: "The hardware system has IEEE compatible floating point units\n" + * Severity: Informational + * Description: + * The Linux kernel detected that it is running on a hardware system with + * CPUs that have IEEE compatible floating point units. + * User action: + * None. + */ + +/*? + * Text: "The hardware system has no IEEE compatible floating point units\n" + * Severity: Informational + * Description: + * The Linux kernel detected that it is running on a hardware system with + * CPUs that do not have IEEE compatible floating point units. + * User action: + * None. + */ + +/*? + * Text: "Linux is running as a z/VM guest operating system in 64-bit mode\n" + * Severity: Informational + * Description: + * The 64-bit Linux kernel detected that it is running as a guest operating + * system of the z/VM hypervisor. + * User action: + * None. + */ + +/*? + * Text: "Linux is running under KVM in 64-bit mode\n" + * Severity: Informational + * Description: + * The 64-bit Linux kernel detected that it is running as a guest operating + * system of the KVM hypervisor. + * User action: + * None. + */ + +/*? + * Text: "Linux is running natively in 64-bit mode\n" + * Severity: Informational + * Description: + * The 64-bit Linux kernel detected that it is running on an IBM mainframe, + * either as the sole operating system in an LPAR or as the sole operating + * system on the entire mainframe. The Linux kernel is not running as a + * guest operating system of the z/VM hypervisor. + * User action: + * None. + */ + +/*? + * Text: "Defining the Linux kernel NSS failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * The Linux kernel could not define the named saved system (NSS) with + * the z/VM CP DEFSYS command. The return code represents the numeric + * portion of the CP DEFSYS error message. + * User action: + * For return code 1, the z/VM guest virtual machine is not authorized + * to define named saved systems. + * Ensure that the z/VM guest virtual machine is authorized to issue + * the CP DEFSYS command (typically privilege class E). + * For other return codes, see the help and message documentation for + * the CP DEFSYS command. + */ + +/*? + * Text: "Saving the Linux kernel NSS failed with rc=%d\n" + * Severity: Error + * Parameter: + * @1: return code + * Description: + * The Linux kernel could not save the named saved system (NSS) with + * the z/VM CP SAVESYS command. The return code represents the numeric + * portion of the CP SAVESYS error message. + * User action: + * For return code 1, the z/VM guest virtual machine is not authorized + * to save named saved systems. + * Ensure that the z/VM guest virtual machine is authorized to issue + * the CP SAVESYS command (typically privilege class E). + * For other return codes, see the help and message documentation for + * the CP SAVESYS command. + */ + +/*? + * Text: "crashkernel reservation failed: %s\n" + * Severity: Informational + * Parameter: + * @1: reason string + * Description: + * The memory reservation for the kdump "crashkernel" parameter was not + * successful. The Linux kernel was either not able to find a free memory + * area or an invalid area has been defined. The reason string describes the + * cause of the failure in more detail. + * User action: + * Increase the memory footprint of your virtual machine or adjust the values + * for the "crashkernel" kernel parameter. Then boot your Linux system again. + */ + +/*? + * Text: "Reserving %lluMB of memory at %lluMB for crashkernel (System RAM: %luMB)\n" + * Severity: Informational + * Parameter: + * @1: amount of reserved memory + * @2: storage location of reserved memory + * @3: amount of system RAM + * Description: + * The memory reservation for the kdump "crashkernel" parameter was successful + * and a kdump kernel can now be loaded with the kexec tool. + * User action: + * None. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/smsgiucv +++ linux-oracle-5.4.0/Documentation/kmsg/s390/smsgiucv @@ -0,0 +1 @@ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/smsgiucv_app +++ linux-oracle-5.4.0/Documentation/kmsg/s390/smsgiucv_app @@ -0,0 +1 @@ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/tape +++ linux-oracle-5.4.0/Documentation/kmsg/s390/tape @@ -0,0 +1,63 @@ +/*? + * Text: "%s: A tape unit was detached while in use\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A tape unit has been detached from the I/O configuration while a tape + * was being accessed. This typically results in I/O error messages and + * potentially in damaged data on the tape. + * User action: + * Check the output of the application that accesses the tape device. + * If this problem occurred during a write-type operation, consider repeating + * the operation after bringing the tape device back online. + */ + +/*? + * Text: "%s: A tape cartridge has been mounted\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the tape device + * Description: + * A tape cartridge has been inserted into the tape unit. The tape in the + * tape unit is ready to be accessed. + * User action: + * None. + */ + +/*? + * Text: "%s: The tape cartridge has been successfully unloaded\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape cartridge has been unloaded from the tape unit. Insert a tape + * cartridge before accessing the tape device. + * User action: + * None. + */ + +/*? + * Text: "A cartridge is loaded in tape device %s, refusing to suspend\n" + * Severity: Error + * Parameter: + * @1: bus ID of the tape device + * Description: + * A request to suspend a tape device currently loaded with a cartridge is + * rejected. + * User action: + * Unload the tape device. Then try to suspend the system again. + */ + +/*? + * Text: "Tape device %s is busy, refusing to suspend\n" + * Severity: Error + * Parameter: + * @1: bus ID of the tape device + * Description: + * A request to suspend a tape device being currently in use is rejected. + * User action: + * Terminate applications performing tape operations + * and then try to suspend the system again. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/tape_34xx +++ linux-oracle-5.4.0/Documentation/kmsg/s390/tape_34xx @@ -0,0 +1,418 @@ +/*? + * Text: "%s: An unexpected condition %d occurred in tape error recovery\n" + * Severity: Error + * Parameter: + * @1: bus ID of the tape device + * @2: number + * Description: + * The control unit has reported an error condition that is not recognized by + * the error recovery process of the tape device driver. + * User action: + * Report this problem and the condition number from the message to your + * support organization. + */ + +/*? + * Text: "%s: A data overrun occurred between the control unit and tape unit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A data overrun error has occurred on the connection between the control + * unit and the tape unit. If this problem occurred during a write-type + * operation, the integrity of the data on the tape might be compromised. + * User action: + * Use a faster connection. If this problem occurred during a write-type + * operation, consider repositioning the tape and repeating the operation. + */ + +/*? + * Text: "%s: The block ID sequence on the tape is incorrect\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The control unit has detected an incorrect block ID sequence on the tape. + * This problem typically indicates that the data on the tape is damaged. + * User action: + * If this problem occurred during a write-type operation reposition the tape + * and repeat the operation. + */ + +/*? + * Text: "%s: A read error occurred that cannot be recovered\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A read error has occurred that cannot be recovered. The current tape might + * be damaged. + * User action: + * None. + */ + +/*? + * Text: "%s: A write error on the tape cannot be recovered\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A write error has occurred that could not be recovered by the automatic + * error recovery process. + * User action: + * Use a different tape cartridge. + */ + +/*? + * Text: "%s: Writing the ID-mark failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The ID-mark at the beginning of tape could not be written. The tape medium + * might be write-protected. + * User action: + * Try a different tape cartridge. Ensure that the write-protection on the + * cartridge is switched off. + */ + +/*? + * Text: "%s: Reading the tape beyond the end of the recorded area failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A read-type operation failed because it extended beyond the end of the + * recorded area on the tape medium. + * User action: + * None. + */ + +/*? + * Text: "%s: The tape contains an incorrect block ID sequence\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The control unit has detected an incorrect block ID sequence on the tape. + * This problem typically indicates that the data on the tape is damaged. + * User action: + * If this problem occurred during a write-type operation reposition the tape + * and repeat the operation. + */ + +/*? + * Text: "%s: A path equipment check occurred for the tape device\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A path equipment check has occurred. This check indicates problems with the + * connection between the mainframe system and the tape control unit. + * User action: + * Ensure that the cable connections between the mainframe system and the + * control unit are securely in place and not damaged. + */ + +/*? + * Text: "%s: The tape unit cannot process the tape format\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * Either the tape unit is not able to read the format ID mark, or the + * specified format is not supported by the tape unit. + * User action: + * If you do not need the data recorded on the current tape, use a different + * tape or write a new format ID mark at the beginning of the tape. Be aware + * that writing a new ID mark leads to a loss of all data that has been + * recorded on the tape. If you need the data on the current tape, use a tape + * unit that supports the tape format. + */ + +/*? + * Text: "%s: The tape medium is write-protected\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A write-type operation failed because the tape medium is write-protected. + * User action: + * Eject the tape cartridge, switch off the write protection on the cartridge, + * insert the cartridge, and try the operation again. + */ + +/*? + * Text: "%s: The tape does not have the required tape tension\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape does not have the required tape tension. + * User action: + * Rewind and reposition the tape, then repeat the operation. + */ + +/*? + * Text: "%s: The tape unit failed to load the cartridge\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * An error has occurred while loading the tape cartridge. + * User action: + * Unload the cartridge and load it again. + */ + +/*? + * Text: "%s: Automatic unloading of the tape cartridge failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit failed to unload the cartridge. + * User action: + * Unload the cartridge manually by using the eject button on the tape unit. + */ + +/*? + * Text: "%s: An equipment check has occurred on the tape unit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * Possible reasons for the check condition are a unit adapter error, a buffer + * error on the lower interface, an unusable internal path, or an error that + * has occurred while loading the cartridge. + * User action: + * Examine the tape unit and the cartridge loader. Consult the tape unit + * documentation for details. + */ + +/*? + * Text: "%s: The tape information states an incorrect length\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape is shorter than stated at the beginning of the tape data. A + * possible reason for this problem is that the tape might have been physically + * truncated. Data written to the tape might be incomplete or damaged. + * User action: + * If this problem occurred during a write-type operation, consider repeating + * the operation with a different tape cartridge. + */ + +/*? + * Text: "%s: The tape unit is not ready\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit is online but not ready. + * User action: + * Turn the ready switch on the tape unit to the ready position and try the + * operation again. + */ + +/*? + * Text: "%s: The tape medium has been rewound or unloaded manually\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit rewind button, unload button, or both have been used to + * rewind or unload the tape cartridge. A tape cartridge other than the + * intended cartridge might have been inserted or the tape medium might not + * be at the expected position. + * User action: + * Verify that the correct tape cartridge has been inserted and that the tape + * medium is at the required position before continuing to work with the tape. + */ + +/*? + * Text: "%s: The tape subsystem is running in degraded mode\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape subsystem is not operating at its maximum performance. + * User action: + * Contact your service representative for the tape unit and report this + * problem. + */ + +/*? + * Text: "%s: The tape unit is already assigned\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit is already assigned to another channel path. + * User action: + * Free the tape unit from the operating system instance to which it is + * currently assigned then try again. + */ + +/*? + * Text: "%s: The tape unit is not online\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit is not online to the tape device driver. + * User action: + * Ensure that the tape unit is operational and that the cable connections + * between the control unit and the tape unit are securely in place and not + * damaged. + */ + +/*? + * Text: "%s: The control unit has fenced access to the tape volume\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The control unit fences further access to the current tape volume. The data + * integrity on the tape volume might have been compromised. + * User action: + * Rewind and unload the tape cartridge. + */ + +/*? + * Text: "%s: A parity error occurred on the tape bus\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * A data parity check error occurred on the bus. Data that was read or written + * while the error occurred is not valid. + * User action: + * Reposition the tape and repeat the read-type or write-type operation. + */ + +/*? + * Text: "%s: I/O error recovery failed on the tape control unit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * An I/O error occurred that cannot be recovered by the automatic error + * recovery process of the tape control unit. The application that operates + * the tape unit will receive a return value of -EIO which indicates an + * I/O error. The data on the tape might be damaged. + * User action: + * If this problem occurred during a write-type operation, consider + * repositioning the tape and repeating the operation. + */ + +/*? + * Text: "%s: The tape unit requires a firmware update\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit requires firmware patches from the tape control unit but the + * required patches are not available on the control unit. + * User action: + * Make the require patches available on the control unit then reposition the + * tape and retry the operation. For details about obtaining and installing + * firmware updates see the control unit documentation. + */ + +/*? + * Text: "%s: The maximum block size for buffered mode is exceeded\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The block to be written is larger than allowed for the buffered mode. + * User action: + * Use a smaller block size. + */ + +/*? + * Text: "%s: A channel interface error cannot be recovered\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * An error has occurred on the channel interface. This error cannot + * be recovered by the control unit error recovery process. + * User action: + * See the documentation of the control unit. + */ + +/*? + * Text: "%s: A channel protocol error occurred\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * An error was detected in the channel protocol. + * User action: + * Reposition the tape and try the operation again. + */ + +/*? + * Text: "%s: The tape unit does not support the compaction algorithm\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit cannot read the current tape. The data on the tape has been + * compressed with an algorithm that is not supported by the tape unit. + * User action: + * Use a tape unit that supports the compaction algorithm used for the + * current tape. + */ + +/*? + * Text: "%s: The tape unit does not support tape format 3480-2 XF\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit does not support tapes recorded in the 3480-2 XF format. + * User action: + * If you do not need the data recorded on the current tape, rewind the tape + * and overwrite it with a supported format. If you need the data on the + * current tape, use a tape unit that supports the tape format. + */ + +/*? + * Text: "%s: The tape unit does not support format 3480 XF\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit does not support tapes recorded in the 3480 XF format. + * User action: + * If you do not need the data recorded on the current tape, rewind the tape + * and overwrite it with a supported format. If you need the data on the + * current tape, use a tape unit that supports the tape format. + */ + +/*? + * Text: "%s: The tape unit does not support the current tape length\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The length of the tape in the cartridge is incompatible with the tape unit. + * User action: + * Either use a different tape unit or use a tape with a supported length. + */ + +/*? + * Text: "%s: The tape unit does not support the tape length\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The length of the tape in the cartridge is incompatible with the tape + * unit. + * User action: + * Either use a different tape unit or use a tape with a supported length. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/tape_3590 +++ linux-oracle-5.4.0/Documentation/kmsg/s390/tape_3590 @@ -0,0 +1,183 @@ +/*? + * Text: "%s: The tape medium must be loaded into a different tape unit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape device has indicated an error condition that requires loading + * the tape cartridge into a different tape unit to recover. + * User action: + * Unload the cartridge and use a different tape unit to retry the operation. + */ + +/*? + * Text: "%s: Tape media information: exception %s, service %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: exception + * @3: service + * Description: + * This is an operating system independent tape medium information message + * that was issued by the tape unit. The information in the message is + * intended for the IBM customer engineer. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: Device subsystem information: exception %s, service %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: exception + * @3: required service action + * Description: + * This is an operating system independent device subsystem information message + * that was issued by the tape unit. The information in the message is + * intended for the IBM customer engineer. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: I/O subsystem information: exception %s, service %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: exception + * @3: required service action + * Description: + * This is an operating system independent I/O subsystem information message + * that was issued by the tape unit. The information in the message is + * intended for the IBM customer engineer. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: The tape unit has issued sense message %s\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: sense message code + * Description: + * The tape unit has issued an operating system independent sense message. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: The tape unit has issued an unknown sense message code 0x%x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: code + * Description: + * The tape device driver has received an unknown sense message from the + * tape unit. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: MIM SEV=%i, MC=%02x, ES=%x/%x, RC=%02x-%04x-%02x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: SEV + * @3: message code + * @4: exception + * @5: required service action + * @6: refcode + * @7: mid + * @8: fid + * Description: + * This is an operating system independent information message that was + * issued by the tape unit. The information in the message is intended for + * the IBM customer engineer. + * User action: + * See to the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: IOSIM SEV=%i, DEVTYPE=3590/%02x, MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: SEV + * @3: model + * @4: message code + * @5: exception + * @6: required service action + * @7: refcode1 + * @8: refcode2 + * @9: refcode3 + * Description: + * This is an operating system independent I/O subsystem information message + * that was issued by the tape unit. The information in the message is + * intended for the IBM customer engineer. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: DEVSIM SEV=%i, DEVTYPE=3590/%02x, MC=%02x, ES=%x/%x, REF=0x%04x-0x%04x-0x%04x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: SEV + * @3: model + * @4: message code + * @5: exception + * @6: required service action + * @7: refcode1 + * @8: refcode2 + * @9: refcode3 + * Description: + * This is an operating system independent device subsystem information message + * issued by the tape unit. The information in the message is intended for + * the IBM customer engineer. + * User action: + * See the documentation for the tape unit for further information. + */ + +/*? + * Text: "%s: The tape unit has issued an unknown sense message code %x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * @2: code + * Description: + * The tape device has issued a sense message, that is unknown to the device + * driver. + * User action: + * Use the message code printed as hexadecimal value and see the documentation + * for the tape unit for further information. + */ + +/*? + * Text: "%s: The tape unit failed to obtain the encryption key from EKM\n" + * Severity: Error + * Parameter: + * @1: bus ID of the tape device + * Description: + * The tape unit was unable to retrieve the encryption key required to decode + * the data on the tape from the enterprise key manager (EKM). + * User action: + * See the EKM and tape unit documentation for information about how to enable + * the tape unit to retrieve the encryption key. + */ + +/*? + * Text: "%s: A different host has privileged access to the tape unit\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the tape device + * Description: + * You cannot access the tape unit because a different operating system + * instance has privileged access to the unit. + * User action: + * Unload the current cartridge to solve this problem. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/time +++ linux-oracle-5.4.0/Documentation/kmsg/s390/time @@ -0,0 +1,36 @@ +/*? + * Text: "The ETR interface has adjusted the clock by %li microseconds\n" + * Severity: Notice + * Parameter: + * @1: number of microseconds + * Description: + * The external time reference (ETR) interface has synchronized the system + * clock with the external reference and set it to a new value. The time + * difference between the old and new clock value has been passed to the + * network time protocol (NTP) as a single shot adjustment. + * User action: + * None. + */ + +/*? + * Text: "The real or virtual hardware system does not provide an ETR interface\n" + * Severity: Warning + * Description: + * The 'etr=' parameter has been passed on the kernel parameter line for + * a Linux instance that does not have access to the external time reference + * (ETR) facility. + * User action: + * To avoid this warning remove the 'etr=' kernel parameter. + */ + +/*? + * Text: "The real or virtual hardware system does not provide an STP interface\n" + * Severity: Warning + * Description: + * The 'stp=' parameter has been passed on the kernel parameter line for + * a Linux instance that does not have access to the server time protocol + * (STP) facility. + * User action: + * To avoid this warning remove the 'stp=' kernel parameter. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/vmlogrdr +++ linux-oracle-5.4.0/Documentation/kmsg/s390/vmlogrdr @@ -0,0 +1,19 @@ +/*? Text: "vmlogrdr: failed to start recording automatically\n" */ +/*? Text: "vmlogrdr: connection severed with reason %i\n" */ +/*? Text: "vmlogrdr: iucv connection to %s failed with rc %i \n" */ +/*? Text: "vmlogrdr: failed to stop recording automatically\n" */ +/*? Text: "not running under VM, driver not loaded.\n" */ + +/*? + * Text: "vmlogrdr: device %s is busy. Refuse to suspend.\n" + * Severity: Error + * Parameter: + * @1: device name + * Description: + * Suspending vmlogrdr devices that are in uses is not supported. + * A request to suspend such a device is refused. + * User action: + * Close all applications that use any of the vmlogrdr devices + * and then try to suspend the system again. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/vmur +++ linux-oracle-5.4.0/Documentation/kmsg/s390/vmur @@ -0,0 +1,48 @@ +/*? + * Text: "The %s cannot be loaded without z/VM\n" + * Severity: Error + * Parameter: + * @1: z/VM virtual unit record device driver + * Description: + * The z/VM virtual unit record device driver provides Linux with access to + * z/VM virtual unit record devices like punch card readers, card punches, and + * line printers. On Linux instances that run in environments other than the + * z/VM hypervisor, the device driver does not provide any useful function and + * the corresponding vmur module cannot be loaded. + * User action: + * Load the vmur module only on Linux instances that run as guest operating + * systems of the z/VM hypervisor. If the z/VM virtual unit record device + * has been compiled into the kernel, ignore this message. + */ + +/*? + * Text: "Kernel function alloc_chrdev_region failed with error code %d\n" + * Severity: Error + * Parameter: + * @1: error code according to errno definitions + * Description: + * The z/VM virtual unit record device driver (vmur) needs to register a range + * of character device minor numbers from 0x0000 to 0xffff. + * This registration failed, probably because of memory constraints. + * User action: + * Free some memory and reload the vmur module. If the z/VM virtual unit + * record device driver has been compiled into the kernel reboot Linux. + * Consider assigning more memory to your LPAR or z/VM guest virtual machine. + */ + +/*? + * Text: "Unit record device %s is busy, %s refusing to suspend.\n" + * Severity: Error + * Parameter: + * @1: bus ID of the unit record device + * @1: z/VM virtual unit record device driver + * Description: + * Linux cannot be suspended while a unit record device is in use. + * User action: + * Stop all applications that work on z/VM spool file queues, for example, the + * vmur tool. Then try again to suspend Linux. + */ + +/*? Text: "%s loaded.\n" */ +/*? Text: "%s unloaded.\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/xpram +++ linux-oracle-5.4.0/Documentation/kmsg/s390/xpram @@ -0,0 +1,74 @@ +/*? + * Text: "%d is not a valid number of XPRAM devices\n" + * Severity: Error + * Parameter: + * @1: number of partitions + * Description: + * The number of XPRAM partitions specified for the 'devs' module parameter + * or with the 'xpram.parts' kernel parameter must be an integer in the + * range 1 to 32. The XPRAM device driver created a maximum of 32 partitions + * that are probably not configured as intended. + * User action: + * If the XPRAM device driver has been compiled as a separate module, + * unload the module and load it again with a correct value for the 'devs' + * module parameter. If the XPRAM device driver has been compiled + * into the kernel, correct the 'xpram.parts' parameter in the kernel + * command line and restart Linux. + */ + +/*? + * Text: "Not enough expanded memory available\n" + * Severity: Error + * Description: + * The amount of expanded memory required to set up your XPRAM partitions + * depends on the 'sizes' parameter specified for the xpram module or on + * the specifications for the 'xpram.parts' parameter if the XPRAM device + * driver has been compiled into the kernel. Your + * current specification exceed the amount of available expanded memory. + * Your XPRAM partitions are probably not configured as intended. + * User action: + * If the XPRAM device driver has been compiled as a separate module, + * unload the xpram module and load it again with an appropriate value + * for the 'sizes' module parameter. If the XPRAM device driver has been + * compiled into the kernel, adjust the 'xpram.parts' parameter in the + * kernel command line and restart Linux. If you need more than the + * available expanded memory, increase the expanded memory allocation for + * your virtual hardware or LPAR. + */ + +/*? + * Text: "No expanded memory available\n" + * Severity: Error + * Description: + * The XPRAM device driver has been loaded in a Linux instance that runs + * in an LPAR or virtual hardware without expanded memory. + * No XPRAM partitions are created. + * User action: + * Allocate expanded memory for your LPAR or virtual hardware or do not + * load the xpram module. You can ignore this message, if you do not want + * to create XPRAM partitions. + */ + +/*? + * Text: "Resuming the system failed: %s\n" + * Severity: Error + * Parameter: + * @1: cause of the failure + * Description: + * A system cannot be resumed if the expanded memory setup changes + * after hibernation. Possible reasons for the failure are: + * - Expanded memory was removed after hibernation. + * - Size of the expanded memory changed after hibernation. + * The system is stopped with a kernel panic. + * User action: + * Reboot Linux. + */ + +/*? Text: " number of devices (partitions): %d \n" */ +/*? Text: " size of partition %d: %u kB\n" */ +/*? Text: " size of partition %d to be set automatically\n" */ +/*? Text: " memory needed (for sized partitions): %lu kB\n" */ +/*? Text: " partitions to be sized automatically: %d\n" */ +/*? Text: " automatically determined partition size: %lu kB\n" */ +/*? Text: " %u pages expanded memory found (%lu KB).\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/zcrypt +++ linux-oracle-5.4.0/Documentation/kmsg/s390/zcrypt @@ -0,0 +1,22 @@ +/*? + * Text: "Cryptographic device %02x.%04x failed and was set offline\n" + * Severity: Error + * Parameter: + * @1: AP device ID + * @2: AP queue + * Description: + * A cryptographic device failed to process a cryptographic request. + * The cryptographic device driver could not correct the error and + * set the device offline. The application that issued the + * request received an indication that the request has failed. + * User action: + * Use the lszcrypt command to confirm that the cryptographic + * hardware is still configured to your LPAR or z/VM guest virtual + * machine. If the device is available to your Linux instance the + * command output contains a line that begins with 'card', + * where is the two-digit decimal number in the message text. + * After ensuring that the device is available, use the chzcrypt command to + * set it online again. + * If the error persists, contact your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/zdump +++ linux-oracle-5.4.0/Documentation/kmsg/s390/zdump @@ -0,0 +1,27 @@ +/*? + * Text: "The 32-bit dump tool cannot be used for a 64-bit system\n" + * Severity: Alert + * Description: + * The dump process ends without creating a system dump. + * User action: + * Use a 64-bit dump tool to obtain a system dump for 64-bit Linux instance. + */ +/*? + * Text: "The 64-bit dump tool cannot be used for a 32-bit system\n" + * Severity: Alert + * Description: + * The dump process ends without creating a system dump. + * User action: + * Use a 32-bit dump tool to obtain a system dump for 32-bit Linux instance. + */ +/*? + * Text: "The dump process started for a 64-bit operating system\n" + * Severity: Alert + * Description: + * The SCSI dump process started to create a dump for a 64-bit operating + * system instance. + * User action: + * None. + */ +/*? Text: "0x%x is an unknown architecture.\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/zfcp +++ linux-oracle-5.4.0/Documentation/kmsg/s390/zfcp @@ -0,0 +1,709 @@ +/*? + * Text: "%s is not a valid SCSI device\n" + * Severity: Error + * Parameter: + * @1: device specification + * Description: + * The specification for an initial SCSI device provided with the 'zfcp.device' + * kernel parameter or with the 'device' module parameter is syntactically + * incorrect. The specified SCSI device could not be attached to the Linux + * system. + * User action: + * Correct the value for the 'zfcp.device' or 'device' parameter and reboot + * Linux. See "Device Drivers, Features, and Commands" for information about + * the syntax. + */ + +/*? + * Text: "The zfcp device driver could not register with the common I/O layer\n" + * Severity: Error + * Description: + * The device driver initialization failed. A possible cause of this problem is + * memory constraints. + * User action: + * Free some memory and try again to load the zfcp device driver. If the zfcp + * device driver has been compiled into the kernel, reboot Linux. Consider + * assigning more memory to your LPAR or z/VM guest virtual machine. If the + * problem persists, contact your support organization. + */ + +/*? + * Text: "%s: Setting up data structures for the FCP adapter failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The zfcp device driver could not allocate data structures for an FCP adapter. + * A possible reason for this problem is memory constraints. + * User action: + * Set the FCP adapter offline or detach it from the Linux system, free some + * memory and set the FCP adapter online again or attach it again. If this + * problem persists, gather Linux debug data, collect the FCP adapter + * hardware logs, and report the problem to your support organization. + */ + +/*? + * Text: "%s: The FCP device is operational again\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * An FCP device has been unavailable because it had been detached from the + * Linux system or because the corresponding CHPID was offline. The FCP device + * is now available again and the zfcp device driver resumes all operations to + * the FCP device. + * User action: + * None. + */ + +/*? + * Text: "%s: The CHPID for the FCP device is offline\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The CHPID for an FCP device has been set offline, either logically in Linux + * or on the hardware. + * User action: + * Find out which CHPID corresponds to the FCP device, for example, with the + * lscss command. Check if the CHPID has been set logically offline in sysfs. + * Write 'on' to the CHPID's status attribute to set it online. If the CHPID is + * online in sysfs, find out if it has been varied offline through a hardware + * management interface, for example the service element (SE). + */ + +/*? + * Text: "%s: The FCP device has been detached\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * An FCP device is no longer available to Linux. + * User action: + * Ensure that the FCP adapter is operational and attached to the LPAR or z/VM + * virtual machine. + */ + +/*? + * Text: "%s: The FCP device did not respond within the specified time\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The common I/O layer waited for a response from the FCP adapter but + * no response was received within the specified time limit. This might + * indicate a hardware problem. + * User action: + * Consult your hardware administrator. If this problem persists, + * gather Linux debug data, collect the FCP adapter hardware logs, and + * report the problem to your support organization. + */ + +/*? + * Text: "%s: Registering the FCP device with the SCSI stack failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter could not be registered with the Linux SCSI + * stack. A possible reason for this problem is memory constraints. + * User action: + * Set the FCP adapter offline or detach it from the Linux system, free some + * memory and set the FCP adapter online again or attach it again. If this + * problem persists, gather Linux debug data, collect the FCP adapter + * hardware logs, and report the problem to your support organization. + */ + +/*? + * Text: "%s: ERP cannot recover an error on the FCP device\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * An error occurred on an FCP device. The error recovery procedure (ERP) + * could not resolve the error. The FCP device driver cannot use the FCP device. + * User action: + * Check for previous error messages for the same FCP device to find the + * cause of the problem. + */ + +/*? + * Text: "%s: Creating an ERP thread for the FCP device failed.\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The zfcp device driver could not set up error recovery procedure (ERP) + * processing for the FCP device. The FCP device is not available for use + * in Linux. + * User action: + * Free some memory and try again to load the zfcp device driver. If the zfcp + * device driver has been compiled into the kernel, reboot Linux. Consider + * assigning more memory to your LPAR or z/VM guest virtual machine. If the + * problem persists, contact your support organization. + */ + +/*? + * Text: "%s: ERP failed for LUN 0x%016Lx on port 0x%016Lx\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: LUN + * @3: WWPN + * Description: + * An error occurred on the SCSI device at the specified LUN. The error recovery + * procedure (ERP) could not resolve the error. The SCSI device is not + * available. + * User action: + * Verify that the LUN is correct. Check the fibre channel fabric for errors + * related to the specified WWPN and LUN, the storage server, and Linux. + */ + +/*? + * Text: "%s: ERP failed for remote port 0x%016Lx\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: WWPN + * Description: + * An error occurred on a remote port. The error recovery procedure (ERP) + * could not resolve the error. The port is not available. + * User action: + * Verify that the WWPN is correct and check the fibre channel fabric for + * errors related to the WWPN. + */ + +/*? + * Text: "%s: Registering port 0x%016Lx failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: WWPN + * Description: + * The Linux kernel could not allocate enough memory to register the + * remote port with the indicated WWPN with the SCSI stack. The remote + * port is not available. + * User action: + * Free some memory and trigger the rescan for ports. + */ + +/*? + * Text: "%s: A QDIO problem occurred\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * QDIO reported a problem to the zfcp device driver. The zfcp device driver + * tries to recover this problem. + * User action: + * Check for related error messages. If this problem occurs frequently, gather + * Linux debug data and contact your support organization. + */ + +/*? + * Text: "%s: Setting up the QDIO connection to the FCP adapter failed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The zfcp device driver failed to establish a QDIO connection with the FCP + * adapter. + * User action: + * Set the FCP adapter offline or detach it from the Linux system, free some + * memory and set the FCP adapter online again or attach it again. If this + * problem persists, gather Linux debug data, collect the FCP adapter + * hardware logs, and report the problem to your support organization. + */ + +/*? + * Text: "%s: The FCP adapter reported a problem that cannot be recovered\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter has a problem that cannot be recovered by the zfcp device + * driver. The zfcp device driver stopped using the FCP device. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to your support organization. + */ + +/*? + * Text: "%s: There is a wrap plug instead of a fibre channel cable\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter is not physically connected to the fibre channel fabric. + * User action: + * Remove the wrap plug from the FCP adapter and connect the adapter with the + * fibre channel fabric. + */ + +/*? + * Text: "%s: FCP device not operational because of an unsupported FC class\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter hardware does not support the fibre channel service class + * requested by the zfcp device driver. This problem indicates a program error + * in the zfcp device driver. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to your support organization. + */ + +/*? + * Text: "%s: 0x%Lx is an ambiguous request identifier\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: request ID + * Description: + * The FCP adapter reported that it received the same request ID twice. This is + * an error. The zfcp device driver stopped using the FCP device. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to your support organization. + */ + +/*? + * Text: "%s: QTCB version 0x%x not supported by FCP adapter (0x%x to 0x%x)\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: requested version + * @3: lowest supported version + * @4: highest supported version + * Description: + * See message text. + * The queue transfer control block (QTCB) version requested by the zfcp device + * driver is not supported by the FCP adapter hardware. + * User action: + * If the requested version is higher than the highest version supported by the + * hardware, install more recent firmware on the FCP adapter. If the requested + * version is lower then the lowest version supported by the hardware, upgrade + * to a Linux level with a more recent zfcp device driver. + */ + +/*? + * Text: "%s: The FCP adapter could not log in to the fibre channel fabric\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The fibre channel switch rejected the login request from the FCP adapter. + * User action: + * Check the fibre channel fabric or switch logs for possible errors. + */ + +/*? + * Text: "%s: The FCP device is suspended because of a firmware update\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP device is not available while a firmware update is in progress. This + * problem is temporary. The FCP device will resume operations when the + * firmware update is completed. + * User action: + * Wait 10 seconds and try the operation again. + */ + +/*? + * Text: "%s: All NPIV ports on the FCP adapter have been assigned\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The number of N_Port ID Virtualization (NPIV) ports that can be assigned + * on an FCP adapter is limited. Once assigned, NPIV ports are not released + * automatically but have to be released explicitly through the support + * element (SE). + * User action: + * Identify NPIV ports that have been assigned but are no longer in use and + * release them from the SE. + */ + +/*? + * Text: "%s: The link between the FCP adapter and the FC fabric is down\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter is not usable. Specific error information is not available. + * User action: + * Check the cabling and the fibre channel fabric configuration. If this + * problem persists, gather Linux debug data, collect the FCP adapter + * hardware logs, and report the problem to your support organization. + */ + +/*? + * Text: "%s: The QTCB type is not supported by the FCP adapter\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The queue transfer control block (QTCB) type requested by the zfcp device + * driver is not supported by the FCP adapter hardware. + * User action: + * Install the latest firmware on your FCP adapter hardware. If this does not + * resolve the problem, upgrade to a Linux level with a more recent zfcp device + * driver. If the problem persists, contact your support organization. + */ + +/*? + * Text: "%s: The error threshold for checksum statistics has been exceeded\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter has reported a large number of bit errors. This might + * indicate a problem with the physical components of the fibre channel fabric. + * Details about the errors have been written to the HBA trace for the FCP + * adapter. + * User action: + * Check for problems in the fibre channel fabric and ensure that all cables + * are properly plugged. + */ + +/*? + * Text: "%s: The local link has been restored\n" + * Severity: Informational + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * A problem with the connection between the FCP adapter and the adjacent node + * on the fibre channel fabric has been resolved. The FCP adapter is now + * available again. + * User action: + * None. + */ + +/*? + * Text: "%s: The mode table on the FCP adapter has been damaged\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * This is an FCP adapter hardware problem. + * User action: + * Report this problem with FCP hardware logs to IBM support. + */ + +/*? + * Text: "%s: The adjacent fibre channel node does not support FCP\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The fibre channel switch or storage system that is connected to the FCP + * channel does not support the fibre channel protocol (FCP). The zfcp + * device driver stopped using the FCP device. + * User action: + * Check the adjacent fibre channel node. + */ + +/*? + * Text: "%s: The FCP adapter does not recognize the command 0x%x\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: command + * Description: + * A command code that was sent from the zfcp device driver to the FCP adapter + * is not valid. The zfcp device driver stopped using the FCP device. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to your support organization. + */ + +/*? + * Text: "%s: There is no light signal from the local fibre channel cable\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * There is no signal on the fibre channel cable that connects the FCP adapter + * to the fibre channel fabric. + * User action: + * Ensure that the cable is in place and connected properly to the FCP adapter + * and to the adjacent fibre channel switch or storage system. + */ + +/*? + * Text: "%s: The WWPN assignment file on the FCP adapter has been damaged\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * This is an FCP adapter hardware problem. + * User action: + * Report this problem with FCP hardware logs to IBM support. + */ + +/*? + * Text: "%s: The FCP device detected a WWPN that is duplicate or not valid\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * This condition indicates an error in the FCP adapter hardware or in the z/VM + * hypervisor. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to IBM support. + */ + +/*? + * Text: "%s: The fibre channel fabric does not support NPIV\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP adapter requires N_Port ID Virtualization (NPIV) from the adjacent + * fibre channel node. Either the FCP adapter is connected to a fibre channel + * switch that does not support NPIV or the FCP adapter tries to use NPIV in a + * point-to-point setup. The connection is not operational. + * User action: + * Verify that NPIV is correctly used for this connection. Check the FCP adapter + * configuration and the fibre channel switch configuration. If necessary, + * update the fibre channel switch firmware. + */ + +/*? + * Text: "%s: The FCP adapter cannot support more NPIV ports\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * N_Port ID Virtualization (NPIV) ports consume physical resources on the FCP + * adapter. The FCP adapter resources are exhausted. The connection is not + * operational. + * User action: + * Analyze the number of available NPIV ports and which operating system + * instances use them. If necessary, reconfigure your setup to move some + * NPIV ports to an FCP adapter with free resources. + */ + +/*? + * Text: "%s: The adjacent switch cannot support more NPIV ports\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * N_Port ID Virtualization (NPIV) ports consume physical resources. The + * resources of the fibre channel switch that is connected to the FCP adapter + * are exhausted. The connection is not operational. + * User action: + * Analyze the number of available NPIV ports on the adjacent fibre channel + * switch and how they are used. If necessary, reconfigure your fibre channel + * fabric to accommodate the required NPIV ports. + */ + +/*? + * Text: "%s: 0x%x is not a valid transfer protocol status\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: status information + * Description: + * The transfer protocol status information reported by the FCP adapter is not + * a valid status for the zfcp device driver. The zfcp device driver stopped + * using the FCP device. + * User action: + * Gather Linux debug data, collect the FCP adapter hardware logs, and report + * this problem to your support organization. + */ + +/*? + * Text: "%s: Unknown or unsupported arbitrated loop fibre channel topology detected\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The FCP device is connected to a fibre channel arbitrated loop or the FCP adapter + * reported an unknown fibre channel topology. The zfcp device driver supports + * point-to-point connections and switched fibre channel fabrics but not arbitrated + * loop topologies. The FCP device cannot be used. + * User action: + * Check the fibre channel setup and ensure that only supported topologies are + * connected to the FCP adapter. + */ + +/*? + * Text: "%s: FCP adapter maximum QTCB size (%d bytes) is too small\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: maximum supported size + * @3: requested QTCB size + * Description: + * The queue transfer control block (QTCB) size requested by the zfcp + * device driver is not supported by the FCP adapter hardware. + * User action: + * Update the firmware on your FCP adapter hardware to the latest + * available level and update the Linux kernel to the latest supported + * level. If the problem persists, contact your support organization. + */ + +/*? + * Text: "%s: The FCP adapter only supports newer control block versions\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The protocol supported by the FCP adapter is not compatible with the zfcp + * device driver. + * User action: + * Upgrade your Linux kernel to a level that includes a zfcp device driver + * with support for the control block version required by your FCP adapter. + */ + +/*? + * Text: "%s: The FCP adapter only supports older control block versions\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * Description: + * The protocol supported by the FCP adapter is not compatible with the zfcp + * device driver. + * User action: + * Install the latest firmware on your FCP adapter. + */ + +/*? + * Text: "%s: Not enough FCP adapter resources to open remote port 0x%016Lx\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: WWPN + * Description: + * Each port that is opened consumes physical resources of the FCP adapter to + * which it is attached. These resources are exhausted and the specified port + * cannot be opened. + * User action: + * Reduce the total number of remote ports that are attached to the + * FCP adapter. + */ + +/*? + * Text: "%s: LUN 0x%Lx on port 0x%Lx is already in use by CSS%d, MIF Image ID %x\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: LUN + * @3: remote port WWPN + * @4: channel subsystem ID + * @5: MIF Image ID of the LPAR + * Description: + * The SCSI device at the indicated LUN is already in use by another system. + * Only one system at a time can use the SCSI device. + * User action: + * Ensure that the other system stops using the device before trying to use it. + */ + +/*? + * Text: "%s: No handle is available for LUN 0x%016Lx on port 0x%016Lx\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: LUN + * @3: WWPN + * Description: + * The FCP adapter can only open a limited number of SCSI devices. This limit + * has been reached and the SCSI device at the indicated LUN cannot be opened. + * User action: + * For FCP subchannels running in non-NPIV mode, check all SCSI + * devices opened through the FCP adapter and close some of them. For + * FCP subchannels running in NPIV mode, verify the SAN zoning and + * host connections on the storage systems. Ensure that the zoning and + * host connections only allow access to the required LUNs. As a + * workaround, disable the automatic LUN scanning by setting the + * zfcp.allow_lun_scan kernel parameter or the allow_lun_scan module + * parameter to 0. + */ + +/*? + * Text: "%s: Incorrect direction %d, LUN 0x%016Lx on port 0x%016Lx closed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: value in direction field + * @3: LUN + * @4: WWPN + * Description: + * The direction field in a SCSI request contains an incorrect value. The zfcp + * device driver closed down the SCSI device at the indicated LUN. + * User action: + * Gather Linux debug data and report this problem to your support organization. + */ + +/*? + * Text: "%s: Incorrect CDB length %d, LUN 0x%016Lx on port 0x%016Lx closed\n" + * Severity: Error + * Parameter: + * @1: bus ID of the zfcp device + * @2: value in length field + * @3: LUN + * @4: WWPN + * Description: + * The control-data-block (CDB) length field in a SCSI request is not valid or + * too large for the FCP adapter. The zfcp device driver closed down the SCSI + * device at the indicated LUN. + * User action: + * Gather Linux debug data and report this problem to your support organization. + */ + +/*? + * Text: "%s: Opening WKA port 0x%x failed\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: destination ID of the WKA port + * Description: + * The FCP adapter rejected a request to open the specified + * well-known address (WKA) port. No retry is possible. + * User action: + * Verify the setup and check if the maximum number of remote ports + * used through this adapter is below the maximum allowed. If the + * problem persists, gather Linux debug data, collect the FCP adapter + * hardware logs, and report the problem to your support organization. + */ + +/*? + * Text: "%s: The name server reported %d words residual data\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: number of words in residual data + * Description: + * The fibre channel name server sent too much information about remote ports. + * The zfcp device driver did not receive sufficient information to attach all + * available remote ports in the SAN. + * User action: + * Verify that you are running the latest firmware level on the FCP + * adapter. Check your SAN setup and consider reducing the number of ports + * visible to the FCP adapter by using more restrictive zoning in the SAN. + */ + +/*? + * Text: "%s: A port opened with WWPN 0x%016Lx returned data that identifies it as WWPN 0x%016Lx\n" + * Severity: Warning + * Parameter: + * @1: bus ID of the zfcp device + * @2: expected WWPN + * @3: reported WWPN + * Description: + * A remote port was opened successfully, but it reported an + * unexpected WWPN in the returned port login (PLOGI) data. This + * condition might have been caused by a change applied to the SAN + * configuration while the port was being opened. + * User action: + * If this condition is only temporary and access to the remote port + * is possible, no action is required. If the condition persists, + * identify the storage system with the specified WWPN and contact the + * support organization of the storage system. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/s390/zpci +++ linux-oracle-5.4.0/Documentation/kmsg/s390/zpci @@ -0,0 +1,42 @@ +/*? + * Text: "%s: Event 0x%x reconfigured PCI function 0x%x\n" + * Severity: Informational + * Parameter: + * @1: device name of the function + * @2: PCI event code + * @3: function ID + * Description: + * The availability of a PCI function has changed. + * Possible reasons for the change include PCI configuration actions on the + * Hardware Management Console or hypervisor. + * For shared PCI functions, the function might also have been reserved or + * released by another system. + * If the device name of a function is shown as 'n/a', the device registration + * with the PCI device driver has not completed. + * The function ID identifies the function to the I/O configuration (IOCDS). + * The PCI event code can be useful diagnostic information for your support + * organization. + * User action: + * None. + */ + +/*? + * Text: "%s: Event 0x%x reports an error for PCI function 0x%x\n" + * Severity: Error + * Parameter: + * @1: device name of the function + * @2: PCI event code + * @3: function ID + * Description: + * A PCI function entered an error state from which it cannot recover + * automatically. + * User action: + * Trigger a recovery action by writing '1' to the 'recover' sysfs attribute + * of the PCI function. + * In sysfs, PCI functions are represented as /sys/bus/pci/devices/, + * where is the device name of the function. + * If the device name of a function is shown as 'n/a', the device + * registration with the PCI device driver has not completed. + * If the problem persists, contact your support organization. + */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ --- linux-oracle-5.4.0.orig/Documentation/kmsg/sbp_target +++ linux-oracle-5.4.0/Documentation/kmsg/sbp_target @@ -0,0 +1,49 @@ +/*? Text: "ABORT TASK SET not implemented\n" */ +/*? Text: "ABORT TASK not implemented\n" */ +/*? Text: "Cannot change the directory_id on an active target.\n" */ +/*? Text: "Cannot enable a target with no LUNs!\n" */ +/*? Text: "Could not update Config ROM\n" */ +/*? Text: "Ignoring ORB_POINTER write while active.\n" */ +/*? Text: "LOGICAL UNIT RESET not implemented\n" */ +/*? Text: "Node ACL not found for %s\n" */ +/*? Text: "Only one TPG per Unit is possible.\n" */ +/*? Text: "QUERY LOGINS not implemented\n" */ +/*? Text: "Reconnect timer expired for node: %016llx\n" */ +/*? Text: "SET PASSWORD not implemented\n" */ +/*? Text: "TARGET RESET not implemented\n" */ +/*? Text: "Unable to allocate struct sbp_nacl\n" */ +/*? Text: "Unable to allocate struct sbp_tpg\n" */ +/*? Text: "Unable to allocate struct sbp_tport\n" */ +/*? Text: "Waiting for reconnect from node: %016llx\n" */ +/*? Text: "cannot find login: %d\n" */ +/*? Text: "failed to allocate login descriptor\n" */ +/*? Text: "failed to allocate login response block\n" */ +/*? Text: "failed to allocate session descriptor\n" */ +/*? Text: "failed to init se_session\n" */ +/*? Text: "failed to map command block handler: %d\n" */ +/*? Text: "failed to read peer GUID: %d\n" */ +/*? Text: "ignoring management request while busy\n" */ +/*? Text: "ignoring request from foreign node (%x != %x)\n" */ +/*? Text: "ignoring request with wrong generation\n" */ +/*? Text: "initiator already logged-in\n" */ +/*? Text: "login to unknown LUN: %d\n" */ +/*? Text: "logout from different node ID\n" */ +/*? Text: "max number of logins reached\n" */ +/*? Text: "mgt_agent LOGIN to LUN %d from %016llx\n" */ +/*? Text: "mgt_agent LOGOUT from LUN %d session %d\n" */ +/*? Text: "mgt_agent RECONNECT from %016llx\n" */ +/*? Text: "mgt_agent RECONNECT login GUID doesn't match\n" */ +/*? Text: "mgt_agent RECONNECT unknown login ID\n" */ +/*? Text: "mgt_orb bad request\n" */ +/*? Text: "netif_stop_queue() cannot be called before register_netdev()\n" */ +/*? Text: "refusing exclusive login with other active logins\n" */ +/*? Text: "refusing login while another exclusive login present\n" */ +/*? Text: "sbp_run_transaction: page size ignored\n" */ +/*? Text: "sbp_send_sense: unknown sense format: 0x%x\n" */ +/*? Text: "target_fabric_configfs_init() failed\n" */ +/*? Text: "target_fabric_configfs_register() failed for SBP\n" */ +/*? Text: "unknown management function 0x%x\n" */ +/*? Text: "unlink LUN: failed to update unit directory\n" */ +/*? Text: "flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n" */ +/*? Text: "%s selects TX queue %d, but real number of TX queues is %d\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ \ No newline at end of file --- linux-oracle-5.4.0.orig/Documentation/kmsg/zram +++ linux-oracle-5.4.0/Documentation/kmsg/zram @@ -0,0 +1,34 @@ +/*? Text: "Error allocating compressor buffer space\n" */ +/*? Text: "Error allocating memory for compressed page: %u, size=%zu\n" */ +/*? Text: "Error creating memory pool\n" */ +/*? Text: "num_devices not specified. Using default: 1\n" */ +/*? Text: "Error allocating compressor working memory!\n" */ +/*? Text: "Error allocating zram address table\n" */ +/*? Text: "Unable to get major number\n" */ +/*? Text: "Compression failed! err=%d\n" */ +/*? Text: "Decompression failed! err=%d, page=%u\n" */ +/*? Text: "There is little point creating a zram of greater than twice the size of memory since we expect a 2:1 compression ratio. Note that zram uses about 0.1%% of the size of the disk when not in use so a huge zram is wasteful.\n\tMemory Size: %zu kB\n\tSize you selected: %llu kB\nContinuing anyway ...\n" */ +/*? Text: "disk size not provided. You can use disksize_kb module param to specify size.\nUsing default: (%u%% of RAM).\n" */ +/*? Text: "Error creating sysfs group" */ +/*? Text: "Error allocating memory for incompressible page: %u\n" */ +/*? Text: "Creating %u devices ...\n" */ +/*? Text: "Initialization failed: err=%d\n" */ +/*? Text: "Error allocating disk queue for device %d\n" */ +/*? Text: "Error allocating disk structure for device %d\n" */ +/*? Text: "Invalid value for num_devices: %u\n" */ +/*? Text: "Error allocating temp memory!\n" */ +/*? Text: "Unable to allocate temp memory\n" */ +/*? Text: "Created %u device(s) ...\n" */ +/*? Text: "There is little point creating a zram of greater than twice the size of memory since we expect a 2:1 compression ratio. Note that zram uses about 0.1%% of the size of the disk when not in use so a huge zram is wasteful.\n\tMemory Size: %lu kB\n\tSize you selected: %llu kB\nContinuing anyway ...\n" */ +/*? Text: "Cannot change disksize for initialized device\n" */ +/*? Text: "Can't change algorithm for initialized device\n" */ +/*? Text: "Cannot initialise %s compressing backend\n" */ +/*? Text: "Cannot change max compression streams\n" */ +/*? Text: "Destroyed %u device(s)\n" */ +/*? Text: "Created %u device(s)\n" */ +/*? Text: "Unable to register zram-control class\n" */ +/*? Text: "Removed device: %s\n" */ +/*? Text: "Added device: %s\n" */ +/*? Text: "Error creating sysfs group for device %d\n" */ +/*? Text: "Error allocating memory for compressed page: %u, size=%u\n" */ +/*? Text: "%s: %d output lines suppressed due to ratelimiting\n" */ \ No newline at end of file --- linux-oracle-5.4.0.orig/Documentation/lzo.txt +++ linux-oracle-5.4.0/Documentation/lzo.txt @@ -159,11 +159,15 @@ distance = 16384 + (H << 14) + D state = S (copy S literals after this block) End of stream is reached if distance == 16384 + In version 1 only, to prevent ambiguity with the RLE case when + ((distance & 0x803f) == 0x803f) && (261 <= length <= 264), the + compressor must not emit block copies where distance and length + meet these conditions. In version 1 only, this instruction is also used to encode a run of - zeros if distance = 0xbfff, i.e. H = 1 and the D bits are all 1. + zeros if distance = 0xbfff, i.e. H = 1 and the D bits are all 1. In this case, it is followed by a fourth byte, X. - run length = ((X << 3) | (0 0 0 0 0 L L L)) + 4. + run length = ((X << 3) | (0 0 0 0 0 L L L)) + 4 0 0 1 L L L L L (32..63) Copy of small block within 16kB distance (preferably less than 34B) --- linux-oracle-5.4.0.orig/Documentation/media/kapi/v4l2-dev.rst +++ linux-oracle-5.4.0/Documentation/media/kapi/v4l2-dev.rst @@ -185,7 +185,7 @@ .. code-block:: c - err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + err = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (err) { video_device_release(vdev); /* or kfree(my_vdev); */ return err; @@ -201,7 +201,7 @@ ========================== ==================== ============================== :c:type:`vfl_devnode_type` Device name Usage ========================== ==================== ============================== -``VFL_TYPE_GRABBER`` ``/dev/videoX`` for video input/output devices +``VFL_TYPE_VIDEO`` ``/dev/videoX`` for video input/output devices ``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e. closed captions, teletext) ``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners --- linux-oracle-5.4.0.orig/Documentation/media/uapi/v4l/colorspaces-defs.rst +++ linux-oracle-5.4.0/Documentation/media/uapi/v4l/colorspaces-defs.rst @@ -36,8 +36,7 @@ :c:type:`v4l2_hsv_encoding` specifies which encoding is used. .. note:: The default R'G'B' quantization is full range for all - colorspaces except for BT.2020 which uses limited range R'G'B' - quantization. + colorspaces. HSV formats are always full range. .. tabularcolumns:: |p{6.7cm}|p{10.8cm}| @@ -169,8 +168,8 @@ - Details * - ``V4L2_QUANTIZATION_DEFAULT`` - Use the default quantization encoding as defined by the - colorspace. This is always full range for R'G'B' (except for the - BT.2020 colorspace) and HSV. It is usually limited range for Y'CbCr. + colorspace. This is always full range for R'G'B' and HSV. + It is usually limited range for Y'CbCr. * - ``V4L2_QUANTIZATION_FULL_RANGE`` - Use the full range quantization encoding. I.e. the range [0…1] is mapped to [0…255] (with possible clipping to [1…254] to avoid the @@ -180,4 +179,4 @@ * - ``V4L2_QUANTIZATION_LIM_RANGE`` - Use the limited range quantization encoding. I.e. the range [0…1] is mapped to [16…235]. Cb and Cr are mapped from [-0.5…0.5] to - [16…240]. + [16…240]. Limited Range cannot be used with HSV. --- linux-oracle-5.4.0.orig/Documentation/media/uapi/v4l/colorspaces-details.rst +++ linux-oracle-5.4.0/Documentation/media/uapi/v4l/colorspaces-details.rst @@ -377,9 +377,8 @@ The :ref:`itu2020` standard defines the colorspace used by Ultra-high definition television (UHDTV). The default transfer function is ``V4L2_XFER_FUNC_709``. The default Y'CbCr encoding is -``V4L2_YCBCR_ENC_BT2020``. The default R'G'B' quantization is limited -range (!), and so is the default Y'CbCr quantization. The chromaticities -of the primary colors and the white reference are: +``V4L2_YCBCR_ENC_BT2020``. The default Y'CbCr quantization is limited range. +The chromaticities of the primary colors and the white reference are: --- linux-oracle-5.4.0.orig/Documentation/media/uapi/v4l/subdev-formats.rst +++ linux-oracle-5.4.0/Documentation/media/uapi/v4l/subdev-formats.rst @@ -7794,3 +7794,30 @@ - 0x5001 - Interleaved raw UYVY and JPEG image format with embedded meta-data used by Samsung S3C73MX camera sensors. + +.. _v4l2-mbus-metadata-fmts: + +Metadata Formats +^^^^^^^^^^^^^^^^ + +This section lists all metadata formats. + +The following table lists the existing metadata formats. + +.. tabularcolumns:: |p{8.0cm}|p{1.4cm}|p{7.7cm}| + +.. flat-table:: Metadata formats + :header-rows: 1 + :stub-columns: 0 + + * - Identifier + - Code + - Comments + * .. _MEDIA-BUS-FMT-METADATA-FIXED: + + - MEDIA_BUS_FMT_METADATA_FIXED + - 0x7001 + - This format should be used when the same driver handles + both sides of the link and the bus format is a fixed + metadata format that is not configurable from userspace. + Width and height will be set to 0 for this format. --- linux-oracle-5.4.0.orig/Documentation/networking/af_xdp.rst +++ linux-oracle-5.4.0/Documentation/networking/af_xdp.rst @@ -40,13 +40,13 @@ appropriate (malloc, mmap, huge pages, etc). This memory area is then registered with the kernel using the new setsockopt XDP_UMEM_REG. The UMEM also has two rings: the FILL ring and the COMPLETION ring. The -fill ring is used by the application to send down addr for the kernel +FILL ring is used by the application to send down addr for the kernel to fill in with RX packet data. References to these frames will then appear in the RX ring once each packet has been received. The -completion ring, on the other hand, contains frame addr that the +COMPLETION ring, on the other hand, contains frame addr that the kernel has transmitted completely and can now be used again by user space, for either TX or RX. Thus, the frame addrs appearing in the -completion ring are addrs that were previously transmitted using the +COMPLETION ring are addrs that were previously transmitted using the TX ring. In summary, the RX and FILL rings are used for the RX path and the TX and COMPLETION rings are used for the TX path. @@ -91,11 +91,16 @@ ======== In order to use an AF_XDP socket, a number of associated objects need -to be setup. +to be setup. These objects and their options are explained in the +following sections. -Jonathan Corbet has also written an excellent article on LWN, -"Accelerating networking with AF_XDP". It can be found at -https://lwn.net/Articles/750845/. +For an overview on how AF_XDP works, you can also take a look at the +Linux Plumbers paper from 2018 on the subject: +http://vger.kernel.org/lpc_net2018_talks/lpc18_paper_af_xdp_perf-v2.pdf. Do +NOT consult the paper from 2017 on "AF_PACKET v4", the first attempt +at AF_XDP. Nearly everything changed since then. Jonathan Corbet has +also written an excellent article on LWN, "Accelerating networking +with AF_XDP". It can be found at https://lwn.net/Articles/750845/. UMEM ---- @@ -113,22 +118,22 @@ struct sockaddr_xdp member sxdp_flags, and passing the file descriptor of A to struct sockaddr_xdp member sxdp_shared_umem_fd. -The UMEM has two single-producer/single-consumer rings, that are used +The UMEM has two single-producer/single-consumer rings that are used to transfer ownership of UMEM frames between the kernel and the user-space application. Rings ----- -There are a four different kind of rings: Fill, Completion, RX and +There are a four different kind of rings: FILL, COMPLETION, RX and TX. All rings are single-producer/single-consumer, so the user-space application need explicit synchronization of multiple processes/threads are reading/writing to them. -The UMEM uses two rings: Fill and Completion. Each socket associated +The UMEM uses two rings: FILL and COMPLETION. Each socket associated with the UMEM must have an RX queue, TX queue or both. Say, that there is a setup with four sockets (all doing TX and RX). Then there will be -one Fill ring, one Completion ring, four TX rings and four RX rings. +one FILL ring, one COMPLETION ring, four TX rings and four RX rings. The rings are head(producer)/tail(consumer) based rings. A producer writes the data ring at the index pointed out by struct xdp_ring @@ -146,7 +151,7 @@ UMEM Fill Ring ~~~~~~~~~~~~~~ -The Fill ring is used to transfer ownership of UMEM frames from +The FILL ring is used to transfer ownership of UMEM frames from user-space to kernel-space. The UMEM addrs are passed in the ring. As an example, if the UMEM is 64k and each chunk is 4k, then the UMEM has 16 chunks and can pass addrs between 0 and 64k. @@ -164,8 +169,8 @@ UMEM Completion Ring ~~~~~~~~~~~~~~~~~~~~ -The Completion Ring is used transfer ownership of UMEM frames from -kernel-space to user-space. Just like the Fill ring, UMEM indicies are +The COMPLETION Ring is used transfer ownership of UMEM frames from +kernel-space to user-space. Just like the FILL ring, UMEM indices are used. Frames passed from the kernel to user-space are frames that has been @@ -181,7 +186,7 @@ is a struct xdp_desc descriptor. The descriptor contains UMEM offset (addr) and the length of the data (len). -If no frames have been passed to kernel via the Fill ring, no +If no frames have been passed to kernel via the FILL ring, no descriptors will (or can) appear on the RX ring. The user application consumes struct xdp_desc descriptors from this @@ -199,8 +204,24 @@ The user application produces struct xdp_desc descriptors to this ring. +Libbpf +====== + +Libbpf is a helper library for eBPF and XDP that makes using these +technologies a lot simpler. It also contains specific helper functions +in tools/lib/bpf/xsk.h for facilitating the use of AF_XDP. It +contains two types of functions: those that can be used to make the +setup of AF_XDP socket easier and ones that can be used in the data +plane to access the rings safely and quickly. To see an example on how +to use this API, please take a look at the sample application in +samples/bpf/xdpsock_usr.c which uses libbpf for both setup and data +plane operations. + +We recommend that you use this library unless you have become a power +user. It will make your program a lot simpler. + XSKMAP / BPF_MAP_TYPE_XSKMAP ----------------------------- +============================ On XDP side there is a BPF map type BPF_MAP_TYPE_XSKMAP (XSKMAP) that is used in conjunction with bpf_redirect_map() to pass the ingress @@ -216,21 +237,193 @@ successfully pass data to the socket. Please refer to the sample application (samples/bpf/) in for an example. +Configuration Flags and Socket Options +====================================== + +These are the various configuration flags that can be used to control +and monitor the behavior of AF_XDP sockets. + +XDP_COPY and XDP_ZERO_COPY bind flags +------------------------------------- + +When you bind to a socket, the kernel will first try to use zero-copy +copy. If zero-copy is not supported, it will fall back on using copy +mode, i.e. copying all packets out to user space. But if you would +like to force a certain mode, you can use the following flags. If you +pass the XDP_COPY flag to the bind call, the kernel will force the +socket into copy mode. If it cannot use copy mode, the bind call will +fail with an error. Conversely, the XDP_ZERO_COPY flag will force the +socket into zero-copy mode or fail. + +XDP_SHARED_UMEM bind flag +------------------------- + +This flag enables you to bind multiple sockets to the same UMEM, but +only if they share the same queue id. In this mode, each socket has +their own RX and TX rings, but the UMEM (tied to the fist socket +created) only has a single FILL ring and a single COMPLETION +ring. To use this mode, create the first socket and bind it in the normal +way. Create a second socket and create an RX and a TX ring, or at +least one of them, but no FILL or COMPLETION rings as the ones from +the first socket will be used. In the bind call, set he +XDP_SHARED_UMEM option and provide the initial socket's fd in the +sxdp_shared_umem_fd field. You can attach an arbitrary number of extra +sockets this way. + +What socket will then a packet arrive on? This is decided by the XDP +program. Put all the sockets in the XSK_MAP and just indicate which +index in the array you would like to send each packet to. A simple +round-robin example of distributing packets is shown below: + +.. code-block:: c + + #include + #include "bpf_helpers.h" + + #define MAX_SOCKS 16 + + struct { + __uint(type, BPF_MAP_TYPE_XSKMAP); + __uint(max_entries, MAX_SOCKS); + __uint(key_size, sizeof(int)); + __uint(value_size, sizeof(int)); + } xsks_map SEC(".maps"); + + static unsigned int rr; + + SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx) + { + rr = (rr + 1) & (MAX_SOCKS - 1); + + return bpf_redirect_map(&xsks_map, rr, 0); + } + +Note, that since there is only a single set of FILL and COMPLETION +rings, and they are single producer, single consumer rings, you need +to make sure that multiple processes or threads do not use these rings +concurrently. There are no synchronization primitives in the +libbpf code that protects multiple users at this point in time. + +XDP_USE_NEED_WAKEUP bind flag +----------------------------- + +This option adds support for a new flag called need_wakeup that is +present in the FILL ring and the TX ring, the rings for which user +space is a producer. When this option is set in the bind call, the +need_wakeup flag will be set if the kernel needs to be explicitly +woken up by a syscall to continue processing packets. If the flag is +zero, no syscall is needed. + +If the flag is set on the FILL ring, the application needs to call +poll() to be able to continue to receive packets on the RX ring. This +can happen, for example, when the kernel has detected that there are no +more buffers on the FILL ring and no buffers left on the RX HW ring of +the NIC. In this case, interrupts are turned off as the NIC cannot +receive any packets (as there are no buffers to put them in), and the +need_wakeup flag is set so that user space can put buffers on the +FILL ring and then call poll() so that the kernel driver can put these +buffers on the HW ring and start to receive packets. + +If the flag is set for the TX ring, it means that the application +needs to explicitly notify the kernel to send any packets put on the +TX ring. This can be accomplished either by a poll() call, as in the +RX path, or by calling sendto(). + +An example of how to use this flag can be found in +samples/bpf/xdpsock_user.c. An example with the use of libbpf helpers +would look like this for the TX path: + +.. code-block:: c + + if (xsk_ring_prod__needs_wakeup(&my_tx_ring)) + sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0); + +I.e., only use the syscall if the flag is set. + +We recommend that you always enable this mode as it usually leads to +better performance especially if you run the application and the +driver on the same core, but also if you use different cores for the +application and the kernel driver, as it reduces the number of +syscalls needed for the TX path. + +XDP_{RX|TX|UMEM_FILL|UMEM_COMPLETION}_RING setsockopts +------------------------------------------------------ + +These setsockopts sets the number of descriptors that the RX, TX, +FILL, and COMPLETION rings respectively should have. It is mandatory +to set the size of at least one of the RX and TX rings. If you set +both, you will be able to both receive and send traffic from your +application, but if you only want to do one of them, you can save +resources by only setting up one of them. Both the FILL ring and the +COMPLETION ring are mandatory if you have a UMEM tied to your socket, +which is the normal case. But if the XDP_SHARED_UMEM flag is used, any +socket after the first one does not have a UMEM and should in that +case not have any FILL or COMPLETION rings created. + +XDP_UMEM_REG setsockopt +----------------------- + +This setsockopt registers a UMEM to a socket. This is the area that +contain all the buffers that packet can recide in. The call takes a +pointer to the beginning of this area and the size of it. Moreover, it +also has parameter called chunk_size that is the size that the UMEM is +divided into. It can only be 2K or 4K at the moment. If you have an +UMEM area that is 128K and a chunk size of 2K, this means that you +will be able to hold a maximum of 128K / 2K = 64 packets in your UMEM +area and that your largest packet size can be 2K. + +There is also an option to set the headroom of each single buffer in +the UMEM. If you set this to N bytes, it means that the packet will +start N bytes into the buffer leaving the first N bytes for the +application to use. The final option is the flags field, but it will +be dealt with in separate sections for each UMEM flag. + +SO_BINDTODEVICE setsockopt +-------------------------- + +This is a generic SOL_SOCKET option that can be used to tie AF_XDP +socket to a particular network interface. It is useful when a socket +is created by a privileged process and passed to a non-privileged one. +Once the option is set, kernel will refuse attempts to bind that socket +to a different interface. Updating the value requires CAP_NET_RAW. + +XDP_STATISTICS getsockopt +------------------------- + +Gets drop statistics of a socket that can be useful for debug +purposes. The supported statistics are shown below: + +.. code-block:: c + + struct xdp_statistics { + __u64 rx_dropped; /* Dropped for reasons other than invalid desc */ + __u64 rx_invalid_descs; /* Dropped due to invalid descriptor */ + __u64 tx_invalid_descs; /* Dropped due to invalid descriptor */ + }; + +XDP_OPTIONS getsockopt +---------------------- + +Gets options from an XDP socket. The only one supported so far is +XDP_OPTIONS_ZEROCOPY which tells you if zero-copy is on or not. + Usage ===== -In order to use AF_XDP sockets there are two parts needed. The +In order to use AF_XDP sockets two parts are needed. The user-space application and the XDP program. For a complete setup and usage example, please refer to the sample application. The user-space side is xdpsock_user.c and the XDP side is part of libbpf. -The XDP code sample included in tools/lib/bpf/xsk.c is the following:: +The XDP code sample included in tools/lib/bpf/xsk.c is the following: + +.. code-block:: c SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx) { int index = ctx->rx_queue_index; - // A set entry here means that the correspnding queue_id + // A set entry here means that the corresponding queue_id // has an active AF_XDP socket bound to it. if (bpf_map_lookup_elem(&xsks_map, &index)) return bpf_redirect_map(&xsks_map, index, 0); @@ -238,7 +431,10 @@ return XDP_PASS; } -Naive ring dequeue and enqueue could look like this:: +A simple but not so performance ring dequeue and enqueue could look +like this: + +.. code-block:: c // struct xdp_rxtx_ring { // __u32 *producer; @@ -287,17 +483,16 @@ return 0; } - -For a more optimized version, please refer to the sample application. +But please use the libbpf functions as they are optimized and ready to +use. Will make your life easier. Sample application ================== There is a xdpsock benchmarking/test application included that -demonstrates how to use AF_XDP sockets with both private and shared -UMEMs. Say that you would like your UDP traffic from port 4242 to end -up in queue 16, that we will enable AF_XDP on. Here, we use ethtool -for this:: +demonstrates how to use AF_XDP sockets with private UMEMs. Say that +you would like your UDP traffic from port 4242 to end up in queue 16, +that we will enable AF_XDP on. Here, we use ethtool for this:: ethtool -N p3p2 rx-flow-hash udp4 fn ethtool -N p3p2 flow-type udp4 src-port 4242 dst-port 4242 \ @@ -311,13 +506,18 @@ For XDP_SKB mode, use the switch "-S" instead of "-N" and all options can be displayed with "-h", as usual. +This sample application uses libbpf to make the setup and usage of +AF_XDP simpler. If you want to know how the raw uapi of AF_XDP is +really used to make something more advanced, take a look at the libbpf +code in tools/lib/bpf/xsk.[ch]. + FAQ ======= Q: I am not seeing any traffic on the socket. What am I doing wrong? A: When a netdev of a physical NIC is initialized, Linux usually - allocates one Rx and Tx queue pair per core. So on a 8 core system, + allocates one RX and TX queue pair per core. So on a 8 core system, queue ids 0 to 7 will be allocated, one per core. In the AF_XDP bind call or the xsk_socket__create libbpf function call, you specify a specific queue id to bind to and it is only the traffic @@ -343,9 +543,21 @@ sudo ethtool -N flow-type udp4 src-port 4242 dst-port \ 4242 action 2 - A number of other ways are possible all up to the capabilitites of + A number of other ways are possible all up to the capabilities of the NIC you have. +Q: Can I use the XSKMAP to implement a switch betwen different umems + in copy mode? + +A: The short answer is no, that is not supported at the moment. The + XSKMAP can only be used to switch traffic coming in on queue id X + to sockets bound to the same queue id X. The XSKMAP can contain + sockets bound to different queue ids, for example X and Y, but only + traffic goming in from queue id Y can be directed to sockets bound + to the same queue id Y. In zero-copy mode, you should use the + switch, or other distribution mechanism, in your NIC to direct + traffic to the correct queue id and socket. + Credits ======= --- linux-oracle-5.4.0.orig/Documentation/networking/bonding.txt +++ linux-oracle-5.4.0/Documentation/networking/bonding.txt @@ -191,11 +191,12 @@ ad_actor_system In an AD system, this specifies the mac-address for the actor in - protocol packet exchanges (LACPDUs). The value cannot be NULL or - multicast. It is preferred to have the local-admin bit set for this - mac but driver does not enforce it. If the value is not given then - system defaults to using the masters' mac address as actors' system - address. + protocol packet exchanges (LACPDUs). The value cannot be a multicast + address. If the all-zeroes MAC is specified, bonding will internally + use the MAC of the bond itself. It is preferred to have the + local-admin bit set for this mac but driver does not enforce it. If + the value is not given then system defaults to using the masters' + mac address as actors' system address. This parameter has effect only in 802.3ad mode and is available through SysFs interface. --- linux-oracle-5.4.0.orig/Documentation/networking/device_drivers/amazon/ena.txt +++ linux-oracle-5.4.0/Documentation/networking/device_drivers/amazon/ena.txt @@ -248,7 +248,7 @@ inputs for hash functions. - The driver configures RSS settings using the AQ SetFeature command (ENA_ADMIN_RSS_HASH_FUNCTION, ENA_ADMIN_RSS_HASH_INPUT and - ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG properties). + ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG properties). - If the NETIF_F_RXHASH flag is set, the 32-bit result of the hash function delivered in the Rx CQ descriptor is set in the received SKB. --- linux-oracle-5.4.0.orig/Documentation/networking/device_drivers/mellanox/mlx5.rst +++ linux-oracle-5.4.0/Documentation/networking/device_drivers/mellanox/mlx5.rst @@ -154,6 +154,27 @@ values: cmode runtime value smfs +enable_roce: RoCE enablement state +---------------------------------- +RoCE enablement state controls driver support for RoCE traffic. +When RoCE is disabled, there is no gid table, only raw ethernet QPs are supported and traffic on the well known UDP RoCE port is handled as raw ethernet traffic. + +To change RoCE enablement state a user must change the driverinit cmode value and run devlink reload. + +User command examples: + +- Disable RoCE:: + + $ devlink dev param set pci/0000:06:00.0 name enable_roce value false cmode driverinit + $ devlink dev reload pci/0000:06:00.0 + +- Read RoCE enablement state:: + + $ devlink dev param show pci/0000:06:00.0 name enable_roce + pci/0000:06:00.0: + name enable_roce type generic + values: + cmode driverinit value true Devlink health reporters ======================== --- linux-oracle-5.4.0.orig/Documentation/networking/devlink-params-mlx5.txt +++ linux-oracle-5.4.0/Documentation/networking/devlink-params-mlx5.txt @@ -0,0 +1,17 @@ +flow_steering_mode [DEVICE, DRIVER-SPECIFIC] + Controls the flow steering mode of the driver. + Two modes are supported: + 1. 'dmfs' - Device managed flow steering. + 2. 'smfs - Software/Driver managed flow steering. + In DMFS mode, the HW steering entities are created and + managed through the Firmware. + In SMFS mode, the HW steering entities are created and + managed though by the driver directly into Hardware + without firmware intervention. + Type: String + Configuration mode: runtime + +enable_roce [DEVICE, GENERIC] + Enable handling of RoCE traffic in the device. + Defaultly enabled. + Configuration mode: driverinit --- linux-oracle-5.4.0.orig/Documentation/networking/devlink-params.txt +++ linux-oracle-5.4.0/Documentation/networking/devlink-params.txt @@ -65,3 +65,7 @@ Reset only if device firmware can be found in the filesystem. Type: u8 + +enable_roce [DEVICE, GENERIC] + Enable handling of RoCE traffic in the device. + Type: Boolean --- linux-oracle-5.4.0.orig/Documentation/networking/ip-sysctl.txt +++ linux-oracle-5.4.0/Documentation/networking/ip-sysctl.txt @@ -876,7 +876,7 @@ cipso_cache_bucket_size - INTEGER The CIPSO label cache consists of a fixed size hash table with each hash bucket containing a number of cache entries. This variable limits - the number of entries in each hash bucket; the larger the value the + the number of entries in each hash bucket; the larger the value is, the more CIPSO label mappings that can be cached. When the number of entries in a given hash bucket reaches this limit adding new entries causes the oldest entry in the bucket to be removed to make room. @@ -953,7 +953,7 @@ which can be quite useful - but may break some applications. Default: 0 -ip_dynaddr - BOOLEAN +ip_dynaddr - INTEGER If set non-zero, enables support for dynamic addresses. If set to a non-zero value larger than 1, a kernel log message will be printed when dynamic address rewriting @@ -1000,12 +1000,14 @@ icmp_msgs_per_sec - INTEGER Limit maximal number of ICMP packets sent per second from this host. Only messages whose type matches icmp_ratemask (see below) are - controlled by this limit. + controlled by this limit. For security reasons, the precise count + of messages per second is randomized. Default: 1000 icmp_msgs_burst - INTEGER icmp_msgs_per_sec controls number of ICMP packets sent per second, while icmp_msgs_burst controls the burst size of these packets. + For security reasons, the precise burst size is randomized. Default: 50 icmp_ratemask - INTEGER @@ -2282,7 +2284,14 @@ Default: 4K sctp_wmem - vector of 3 INTEGERs: min, default, max - Currently this tunable has no effect. + Only the first value ("min") is used, "default" and "max" are + ignored. + + min: Minimum size of send buffer that can be used by SCTP sockets. + It is guaranteed to each SCTP socket (but not association) even + under moderate memory pressure. + + Default: 4K addr_scope_policy - INTEGER Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00 --- linux-oracle-5.4.0.orig/Documentation/networking/ipvs-sysctl.txt +++ linux-oracle-5.4.0/Documentation/networking/ipvs-sysctl.txt @@ -30,8 +30,7 @@ 0: disable any special handling on port reuse. The new connection will be delivered to the same real server that was - servicing the previous connection. This will effectively - disable expire_nodest_conn. + servicing the previous connection. bit 1: enable rescheduling of new connections when it is safe. That is, whenever expire_nodest_conn and for TCP sockets, when --- linux-oracle-5.4.0.orig/Documentation/networking/j1939.rst +++ linux-oracle-5.4.0/Documentation/networking/j1939.rst @@ -339,7 +339,7 @@ .pgn = J1939_PGN_ADDRESS_CLAIMED, .pgn_mask = J1939_PGN_PDU1_MAX, }, { - .pgn = J1939_PGN_ADDRESS_REQUEST, + .pgn = J1939_PGN_REQUEST, .pgn_mask = J1939_PGN_PDU1_MAX, }, { .pgn = J1939_PGN_ADDRESS_COMMANDED, @@ -414,8 +414,8 @@ .can_family = AF_CAN, .can_addr.j1939 = { .name = J1939_NO_NAME; - .pgn = 0x30, - .addr = 0x12300, + .addr = 0x30, + .pgn = 0x12300, }, }; --- linux-oracle-5.4.0.orig/Documentation/networking/nf_flowtable.txt +++ linux-oracle-5.4.0/Documentation/networking/nf_flowtable.txt @@ -76,7 +76,7 @@ table inet x { flowtable f { - hook ingress priority 0 devices = { eth0, eth1 }; + hook ingress priority 0; devices = { eth0, eth1 }; } chain y { type filter hook forward priority 0; policy accept; --- linux-oracle-5.4.0.orig/Documentation/power/runtime_pm.rst +++ linux-oracle-5.4.0/Documentation/power/runtime_pm.rst @@ -382,6 +382,12 @@ nonzero, increment the counter and return 1; otherwise return 0 without changing the counter + `int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);` + - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the + runtime PM status is RPM_ACTIVE, and either ign_usage_count is true + or the device's usage_count is non-zero, increment the counter and + return 1; otherwise return 0 without changing the counter + `void pm_runtime_put_noidle(struct device *dev);` - decrement the device's usage counter --- linux-oracle-5.4.0.orig/Documentation/process/code-of-conduct-interpretation.rst +++ linux-oracle-5.4.0/Documentation/process/code-of-conduct-interpretation.rst @@ -51,7 +51,7 @@ uncertain how to handle situations that come up. It will not be considered a violation report unless you want it to be. If you are uncertain about approaching the TAB or any other maintainers, please -reach out to our conflict mediator, Mishi Choudhary . +reach out to our conflict mediator, Joanna Lee . In the end, "be kind to each other" is really what the end goal is for everybody. We know everyone is human and we all fail at times, but the --- linux-oracle-5.4.0.orig/Documentation/process/deprecated.rst +++ linux-oracle-5.4.0/Documentation/process/deprecated.rst @@ -48,6 +48,9 @@ foo = kmalloc_array(count, size, GFP_KERNEL); +Specifically, kmalloc() can be replaced with kmalloc_array(), and +kzalloc() can be replaced with kcalloc(). + If no 2-factor form is available, the saturate-on-overflow helpers should be used:: @@ -63,9 +66,20 @@ header = kzalloc(struct_size(header, item, count), GFP_KERNEL); -See :c:func:`array_size`, :c:func:`array3_size`, and :c:func:`struct_size`, -for more details as well as the related :c:func:`check_add_overflow` and -:c:func:`check_mul_overflow` family of functions. +For other calculations, please compose the use of the size_mul(), +size_add(), and size_sub() helpers. For example, in the case of:: + + foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL); + +Instead, use the helpers:: + + foo = krealloc(size_add(current_size, + size_mul(chunk_size, + size_sub(count, 3))), GFP_KERNEL); + +For more details, also see array3_size() and flex_array_size(), +as well as the related check_mul_overflow(), check_add_overflow(), +check_sub_overflow(), and check_shl_overflow() family of functions. simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull() ---------------------------------------------------------------------- --- linux-oracle-5.4.0.orig/Documentation/process/stable-kernel-rules.rst +++ linux-oracle-5.4.0/Documentation/process/stable-kernel-rules.rst @@ -174,7 +174,16 @@ - The finalized and tagged releases of all stable kernels can be found in separate branches per version at: - https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git + + - The release candidate of all stable kernel versions can be found at: + + https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/ + + .. warning:: + The -stable-rc tree is a snapshot in time of the stable-queue tree and + will change frequently, hence will be rebased often. It should only be + used for testing purposes (e.g. to be consumed by CI systems). Review committee --- linux-oracle-5.4.0.orig/Documentation/process/submitting-patches.rst +++ linux-oracle-5.4.0/Documentation/process/submitting-patches.rst @@ -133,7 +133,7 @@ The maintainer will thank you if you write your patch description in a form which can be easily pulled into Linux's source code management -system, ``git``, as a "commit log". See :ref:`explicit_in_reply_to`. +system, ``git``, as a "commit log". See :ref:`the_canonical_patch_format`. Solve only one problem per patch. If your description starts to get long, that's a sign that you probably need to split up your patch. --- linux-oracle-5.4.0.orig/Documentation/s390/index.rst +++ linux-oracle-5.4.0/Documentation/s390/index.rst @@ -15,6 +15,7 @@ vfio-ccw zfcpdump common_io + pci text_files --- linux-oracle-5.4.0.orig/Documentation/s390/pci.rst +++ linux-oracle-5.4.0/Documentation/s390/pci.rst @@ -0,0 +1,126 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========= +S/390 PCI +========= + +Authors: + - Pierre Morel + +Copyright, IBM Corp. 2020 + + +command line parameters and debugfs entries +=========================================== + +Command line parameters +----------------------- + +* nomio + + Do not use MIO instructions. + +* norid + + Ignore the RID field and force use of one PCI domain per PCI function. + +debugfs entries +--------------- + +* /sys/kernel/debug/s390dbf/pci_*/ (S/390 debug feature) + + Some views generated by the debug feature to hold various debug outputs. + + - /sys/kernel/debug/s390dbf/pci_msg/sprintf + Messages from the processing of PCI events like machine check handling + and setting of global functionality like UID checking. + + The level of logging can be changed to be more or less verbose by piping to + /sys/kernel/debug/s390dbf/pci_*/level a number between 0 and 6; see the + documentation on the S/390 debug feature (Documentation/s390/s390dbf.rst) + for details. + +Sysfs entries +============= + +Specific entries, or entries specificities for zPCI functions. + +* /sys/bus/pci/slots/XXXXXXXX + + The slot entries are setup using the FID (Function Identifier) of the + PCI function. + + - /sys/bus/pci/slots/XXXXXXXX/power + + A physical function currently supporting virtual function can not be + powered-off until all virtual-function have been removed with + echo 0 > /sys/bus/pci/devices/XXXX:XX:XX.X/sriov_numvf + +* /sys/bus/pci/devices/XXXX:XX:XX.X/ + + - function_id + zPCI function identifier unique for the complete Z System. + It define uniquely a function in the system. + + - function_handle + Low level identifier used for a configured PCI function. + It may be useful for debuging. + + - pchid + Model dependent location of the I/O adapter. + + - pfgid + PCI Function Group ID, functions sharing identical functionality + are using a common identifier. + A PCI group defines interrupts, IOMMU, IOTLB and DMA specifics. + + - vfn + The Virtual Function Number, from 1 to N for virtual functions. + 0 for physical functions. + + - pft + PCI function type specifies the type of the PCI function. + + - port + The port correspond to the physical port the function is attached to. + It also gives an indication on the physical function a virtual function + is attached to. + + - uid + The UID, Unique Identifier is defined when configuring a LPAR and is + unique inside an LPAR. + + - pfip/segmentX + The segments are used to determine the isolation of a function. + They corresponds to the physical path to the function. + The more the segment are different the more the functions are isolated. + +Enumeration and hotplug +======================= + +The PCI address is made of 4 parts: domain, bus, device and function, +like in DDDD:BB:dd.f + +* When not using multi-functions (norid is set or firmware does not support + multi-functions) + + - There is only one function per domain. + + - the domain is set from the zPCI function's UID as defined during the + LPAR creation. + + - Addresses look like DDDD:00:00.0 + +* When using multi-functions (norid parameter is not set), there are some + change in the way zPCI functions are addressed: + + - There is still only one bus per domain. + + - There can be up to 256 functions per bus. + + - The domain part of the address of all functions of all functions for + a multi-Function device is set from the zPCI function's UID as defined + in the LPAR creation for the function zero. + + - New functions will only be ready to be used after the function zero + (the function with devfn 0) has been enumerated. --- linux-oracle-5.4.0.orig/Documentation/scsi/smartpqi.txt +++ linux-oracle-5.4.0/Documentation/scsi/smartpqi.txt @@ -29,7 +29,7 @@ smartpqi host attributes: ------------------------- /sys/class/scsi_host/host*/rescan - /sys/class/scsi_host/host*/version + /sys/class/scsi_host/host*/driver_version The host rescan attribute is a write only attribute. Writing to this attribute will trigger the driver to scan for new, changed, or removed --- linux-oracle-5.4.0.orig/Documentation/sound/hd-audio/index.rst +++ linux-oracle-5.4.0/Documentation/sound/hd-audio/index.rst @@ -8,3 +8,4 @@ models controls dp-mst + realtek-pc-beep --- linux-oracle-5.4.0.orig/Documentation/sound/hd-audio/models.rst +++ linux-oracle-5.4.0/Documentation/sound/hd-audio/models.rst @@ -216,8 +216,6 @@ ALC298 fixups on Dell AIO machines alc275-dell-xps ALC275 fixups on Dell XPS models -alc256-dell-xps13 - ALC256 fixups on Dell XPS13 lenovo-spk-noise Workaround for speaker noise on Lenovo machines lenovo-hotkey @@ -263,6 +261,10 @@ huawei-mbx-stereo Enable initialization verbs for Huawei MBX stereo speakers; might be risky, try this at your own risk +alc298-samsung-headphone + Samsung laptops with ALC298 +alc256-samsung-headphone + Samsung laptops with ALC256 ALC66x/67x/892 ============== @@ -700,7 +702,7 @@ no-jd BIOS setup but without jack-detection intel - Intel DG45* mobos + Intel D*45* mobos dell-m6-amic Dell desktops/laptops with analog mics dell-m6-dmic --- linux-oracle-5.4.0.orig/Documentation/sound/hd-audio/realtek-pc-beep.rst +++ linux-oracle-5.4.0/Documentation/sound/hd-audio/realtek-pc-beep.rst @@ -0,0 +1,129 @@ +=============================== +Realtek PC Beep Hidden Register +=============================== + +This file documents the "PC Beep Hidden Register", which is present in certain +Realtek HDA codecs and controls a muxer and pair of passthrough mixers that can +route audio between pins but aren't themselves exposed as HDA widgets. As far +as I can tell, these hidden routes are designed to allow flexible PC Beep output +for codecs that don't have mixer widgets in their output paths. Why it's easier +to hide a mixer behind an undocumented vendor register than to just expose it +as a widget, I have no idea. + +Register Description +==================== + +The register is accessed via processing coefficient 0x36 on NID 20h. Bits not +identified below have no discernible effect on my machine, a Dell XPS 13 9350:: + + MSB LSB + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | |h|S|L| | B |R| | Known bits + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + |0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +1Ah input select (B): 2 bits + When zero, expose the PC Beep line (from the internal beep generator, when + enabled with the Set Beep Generation verb on NID 01h, or else from the + external PCBEEP pin) on the 1Ah pin node. When nonzero, expose the headphone + jack (or possibly Line In on some machines) input instead. If PC Beep is + selected, the 1Ah boost control has no effect. + +Amplify 1Ah loopback, left (L): 1 bit + Amplify the left channel of 1Ah before mixing it into outputs as specified + by h and S bits. Does not affect the level of 1Ah exposed to other widgets. + +Amplify 1Ah loopback, right (R): 1 bit + Amplify the right channel of 1Ah before mixing it into outputs as specified + by h and S bits. Does not affect the level of 1Ah exposed to other widgets. + +Loopback 1Ah to 21h [active low] (h): 1 bit + When zero, mix 1Ah (possibly with amplification, depending on L and R bits) + into 21h (headphone jack on my machine). Mixed signal respects the mute + setting on 21h. + +Loopback 1Ah to 14h (S): 1 bit + When one, mix 1Ah (possibly with amplification, depending on L and R bits) + into 14h (internal speaker on my machine). Mixed signal **ignores** the mute + setting on 14h and is present whenever 14h is configured as an output. + +Path diagrams +============= + +1Ah input selection (DIV is the PC Beep divider set on NID 01h):: + + + | | | + +--DIV--+--!DIV--+ {1Ah boost control} + | | + +--(b == 0)--+--(b != 0)--+ + | + >1Ah (Beep/Headphone Mic/Line In)< + +Loopback of 1Ah to 21h/14h:: + + <1Ah (Beep/Headphone Mic/Line In)> + | + {amplify if L/R} + | + +-----!h-----+-----S-----+ + | | + {21h mute control} | + | | + >21h (Headphone)< >14h (Internal Speaker)< + +Background +========== + +All Realtek HDA codecs have a vendor-defined widget with node ID 20h which +provides access to a bank of registers that control various codec functions. +Registers are read and written via the standard HDA processing coefficient +verbs (Set/Get Coefficient Index, Set/Get Processing Coefficient). The node is +named "Realtek Vendor Registers" in public datasheets' verb listings and, +apart from that, is entirely undocumented. + +This particular register, exposed at coefficient 0x36 and named in commits from +Realtek, is of note: unlike most registers, which seem to control detailed +amplifier parameters not in scope of the HDA specification, it controls audio +routing which could just as easily have been defined using standard HDA mixer +and selector widgets. + +Specifically, it selects between two sources for the input pin widget with Node +ID (NID) 1Ah: the widget's signal can come either from an audio jack (on my +laptop, a Dell XPS 13 9350, it's the headphone jack, but comments in Realtek +commits indicate that it might be a Line In on some machines) or from the PC +Beep line (which is itself multiplexed between the codec's internal beep +generator and external PCBEEP pin, depending on if the beep generator is +enabled via verbs on NID 01h). Additionally, it can mix (with optional +amplification) that signal onto the 21h and/or 14h output pins. + +The register's reset value is 0x3717, corresponding to PC Beep on 1Ah that is +then amplified and mixed into both the headphones and the speakers. Not only +does this violate the HDA specification, which says that "[a vendor defined +beep input pin] connection may be maintained *only* while the Link reset +(**RST#**) is asserted", it means that we cannot ignore the register if we care +about the input that 1Ah would otherwise expose or if the PCBEEP trace is +poorly shielded and picks up chassis noise (both of which are the case on my +machine). + +Unfortunately, there are lots of ways to get this register configuration wrong. +Linux, it seems, has gone through most of them. For one, the register resets +after S3 suspend: judging by existing code, this isn't the case for all vendor +registers, and it's led to some fixes that improve behavior on cold boot but +don't last after suspend. Other fixes have successfully switched the 1Ah input +away from PC Beep but have failed to disable both loopback paths. On my +machine, this means that the headphone input is amplified and looped back to +the headphone output, which uses the exact same pins! As you might expect, this +causes terrible headphone noise, the character of which is controlled by the +1Ah boost control. (If you've seen instructions online to fix XPS 13 headphone +noise by changing "Headphone Mic Boost" in ALSA, now you know why.) + +The information here has been obtained through black-box reverse engineering of +the ALC256 codec's behavior and is not guaranteed to be correct. It likely +also applies for the ALC255, ALC257, ALC235, and ALC236, since those codecs +seem to be close relatives of the ALC256. (They all share one initialization +function.) Additionally, other codecs like the ALC225 and ALC285 also have this +register, judging by existing fixups in ``patch_realtek.c``, but specific +data (e.g. node IDs, bit positions, pin mappings) for those codecs may differ +from what I've described here. --- linux-oracle-5.4.0.orig/Documentation/sound/soc/dapm.rst +++ linux-oracle-5.4.0/Documentation/sound/soc/dapm.rst @@ -234,7 +234,7 @@ a virtual widget - a widget with no control bits e.g. :: - SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), This can be used to merge to signal paths together in software. --- linux-oracle-5.4.0.orig/Documentation/sphinx/kernel_include.py +++ linux-oracle-5.4.0/Documentation/sphinx/kernel_include.py @@ -94,7 +94,6 @@ # HINT: this is the only line I had to change / commented out: #path = utils.relative_path(None, path) - path = nodes.reprunicode(path) encoding = self.options.get( 'encoding', self.state.document.settings.input_encoding) e_handler=self.state.document.settings.input_encoding_error_handler --- linux-oracle-5.4.0.orig/Documentation/sphinx/load_config.py +++ linux-oracle-5.4.0/Documentation/sphinx/load_config.py @@ -3,7 +3,7 @@ import os import sys -from sphinx.util.pycompat import execfile_ +from sphinx.util.osutil import fs_encoding # ------------------------------------------------------------------------------ def loadConfig(namespace): @@ -48,7 +48,9 @@ sys.stdout.write("load additional sphinx-config: %s\n" % config_file) config = namespace.copy() config['__file__'] = config_file - execfile_(config_file, config) + with open(config_file, 'rb') as f: + code = compile(f.read(), fs_encoding, 'exec') + exec(code, config) del config['__file__'] namespace.update(config) else: --- linux-oracle-5.4.0.orig/Documentation/sphinx/parse-headers.pl +++ linux-oracle-5.4.0/Documentation/sphinx/parse-headers.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use strict; use Text::Tabs; use Getopt::Long; --- linux-oracle-5.4.0.orig/Documentation/target/tcm_mod_builder.py +++ linux-oracle-5.4.0/Documentation/target/tcm_mod_builder.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD # # Copyright (c) 2010 Rising Tide Systems --- linux-oracle-5.4.0.orig/Documentation/timers/hrtimers.rst +++ linux-oracle-5.4.0/Documentation/timers/hrtimers.rst @@ -118,7 +118,7 @@ was not really a win, due to the different data structures. Also, the hrtimer functions now have clearer behavior and clearer names - such as hrtimer_try_to_cancel() and hrtimer_cancel() [which are roughly -equivalent to del_timer() and del_timer_sync()] - so there's no direct +equivalent to timer_delete() and timer_delete_sync()] - so there's no direct 1:1 mapping between them on the algorithmic level, and thus no real potential for code sharing either. --- linux-oracle-5.4.0.orig/Documentation/trace/histogram.rst +++ linux-oracle-5.4.0/Documentation/trace/histogram.rst @@ -39,7 +39,7 @@ will use the event's kernel stacktrace as the key. The keywords 'keys' or 'key' can be used to specify keys, and the keywords 'values', 'vals', or 'val' can be used to specify values. Compound - keys consisting of up to two fields can be specified by the 'keys' + keys consisting of up to three fields can be specified by the 'keys' keyword. Hashing a compound key produces a unique entry in the table for each unique combination of component keys, and can be useful for providing more fine-grained summaries of event data. @@ -191,7 +191,7 @@ with the event, in nanoseconds. May be modified by .usecs to have timestamps interpreted as microseconds. - cpu int the cpu on which the event occurred. + common_cpu int the cpu on which the event occurred. ====================== ==== ======================================= Extended error information --- linux-oracle-5.4.0.orig/Documentation/trace/postprocess/decode_msr.py +++ linux-oracle-5.4.0/Documentation/trace/postprocess/decode_msr.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # add symbolic names to read_msr / write_msr in trace # decode_msr msr-index.h < trace import sys --- linux-oracle-5.4.0.orig/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl +++ linux-oracle-5.4.0/Documentation/trace/postprocess/trace-pagealloc-postprocess.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # This is a POC (proof of concept or piece of crap, take your pick) for reading the # text representation of trace output related to page allocation. It makes an attempt # to extract some high-level information on what is going on. The accuracy of the parser --- linux-oracle-5.4.0.orig/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ linux-oracle-5.4.0/Documentation/trace/postprocess/trace-vmscan-postprocess.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # This is a POC for reading the text representation of trace output related to # page reclaim. It makes an attempt to extract some high-level information on # what is going on. The accuracy of the parser may vary --- linux-oracle-5.4.0.orig/Documentation/translations/it_IT/kernel-hacking/locking.rst +++ linux-oracle-5.4.0/Documentation/translations/it_IT/kernel-hacking/locking.rst @@ -998,7 +998,7 @@ while (list) { struct foo *next = list->next; - del_timer(&list->timer); + timer_delete(&list->timer); kfree(list); list = next; } @@ -1011,7 +1011,7 @@ di eliminare il suo oggetto (che però è già stato eliminato). Questo può essere evitato controllando il valore di ritorno di -:c:func:`del_timer()`: se ritorna 1, il temporizzatore è stato già +:c:func:`timer_delete()`: se ritorna 1, il temporizzatore è stato già rimosso. Se 0, significa (in questo caso) che il temporizzatore è in esecuzione, quindi possiamo fare come segue:: @@ -1020,7 +1020,7 @@ while (list) { struct foo *next = list->next; - if (!del_timer(&list->timer)) { + if (!timer_delete(&list->timer)) { /* Give timer a chance to delete this */ spin_unlock_bh(&list_lock); goto retry; @@ -1034,10 +1034,8 @@ Un altro problema è l'eliminazione dei temporizzatori che si riavviano da soli (chiamando :c:func:`add_timer()` alla fine della loro esecuzione). Dato che questo è un problema abbastanza comune con una propensione -alle corse critiche, dovreste usare :c:func:`del_timer_sync()` -(``include/linux/timer.h``) per gestire questo caso. Questa ritorna il -numero di volte che il temporizzatore è stato interrotto prima che -fosse in grado di fermarlo senza che si riavviasse. +alle corse critiche, dovreste usare :c:func:`timer_delete_sync()` +(``include/linux/timer.h``) per gestire questo caso. Velocità della sincronizzazione =============================== @@ -1384,7 +1382,7 @@ - :c:func:`kfree()` -- :c:func:`add_timer()` e :c:func:`del_timer()` +- :c:func:`add_timer()` e :c:func:`timer_delete()` Riferimento per l'API dei Mutex =============================== --- linux-oracle-5.4.0.orig/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt +++ linux-oracle-5.4.0/Documentation/translations/zh_CN/video4linux/v4l2-framework.txt @@ -649,7 +649,7 @@ 接下来你需要注册视频设备:这会为你创建一个字符设备。 - err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + err = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (err) { video_device_release(vdev); /* or kfree(my_vdev); */ return err; @@ -660,7 +660,7 @@ 注册哪种设备是根据类型(type)参数。存在以下类型: -VFL_TYPE_GRABBER: 用于视频输入/输出设备的 videoX +VFL_TYPE_VIDEO: 用于视频输入/输出设备的 videoX VFL_TYPE_VBI: 用于垂直消隐数据的 vbiX (例如,隐藏式字幕,图文电视) VFL_TYPE_RADIO: 用于广播调谐器的 radioX --- linux-oracle-5.4.0.orig/Documentation/userspace-api/seccomp_filter.rst +++ linux-oracle-5.4.0/Documentation/userspace-api/seccomp_filter.rst @@ -250,14 +250,14 @@ seccomp notification fd to receive a ``struct seccomp_notif``, which contains five members: the input length of the structure, a unique-per-filter ``id``, the ``pid`` of the task which triggered this request (which may be 0 if the -task is in a pid ns not visible from the listener's pid namespace), a ``flags`` -member which for now only has ``SECCOMP_NOTIF_FLAG_SIGNALED``, representing -whether or not the notification is a result of a non-fatal signal, and the -``data`` passed to seccomp. Userspace can then make a decision based on this -information about what to do, and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a -response, indicating what should be returned to userspace. The ``id`` member of -``struct seccomp_notif_resp`` should be the same ``id`` as in ``struct -seccomp_notif``. +task is in a pid ns not visible from the listener's pid namespace). The +notification also contains the ``data`` passed to seccomp, and a filters flag. +The structure should be zeroed out prior to calling the ioctl. + +Userspace can then make a decision based on this information about what to do, +and ``ioctl(SECCOMP_IOCTL_NOTIF_SEND)`` a response, indicating what should be +returned to userspace. The ``id`` member of ``struct seccomp_notif_resp`` should +be the same ``id`` as in ``struct seccomp_notif``. It is worth noting that ``struct seccomp_data`` contains the values of register arguments to the syscall, but does not contain pointers to memory. The task's --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/api.txt +++ linux-oracle-5.4.0/Documentation/virt/kvm/api.txt @@ -172,6 +172,9 @@ be retrieved using KVM_CAP_ARM_VM_IPA_SIZE of the KVM_CHECK_EXTENSION ioctl() at run-time. +Creation of the VM will fail if the requested IPA size (whether it is +implicit or explicit) is unsupported on the host. + Please note that configuring the IPA size does not affect the capability exposed by the guest CPUs in ID_AA64MMFR0_EL1[PARange]. It only affects size of the address translated by the stage2 level (guest physical to @@ -1132,6 +1135,9 @@ the entire memory slot size. Any object may back this memory, including anonymous memory, ordinary files, and hugetlbfs. +On architectures that support a form of address tagging, userspace_addr must +be an untagged address. + It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr be identical. This allows large pages in the guest to be backed by large pages in the host. @@ -1897,9 +1903,11 @@ Parameters: struct kvm_one_reg (in) Returns: 0 on success, negative value on failure Errors: -  ENOENT:   no such register -  EINVAL:   invalid register ID, or no such register -  EPERM:    (arm64) register access not allowed before vcpu finalization +  ENOENT   no such register +  EINVAL   invalid register ID, or no such register or used with VMs in + protected virtualization mode on s390 +  EPERM    (arm64) register access not allowed before vcpu finalization + (These error codes are indicative only: do not rely on a specific error code being returned in a specific situation.) @@ -2290,9 +2298,11 @@ Parameters: struct kvm_one_reg (in and out) Returns: 0 on success, negative value on failure Errors include: -  ENOENT:   no such register -  EINVAL:   invalid register ID, or no such register -  EPERM:    (arm64) register access not allowed before vcpu finalization +  ENOENT   no such register +  EINVAL   invalid register ID, or no such register or used with VMs in + protected virtualization mode on s390 +  EPERM    (arm64) register access not allowed before vcpu finalization + (These error codes are indicative only: do not rely on a specific error code being returned in a specific situation.) @@ -3058,51 +3068,116 @@ 4.89 KVM_S390_MEM_OP -Capability: KVM_CAP_S390_MEM_OP -Architectures: s390 -Type: vcpu ioctl -Parameters: struct kvm_s390_mem_op (in) -Returns: = 0 on success, - < 0 on generic error (e.g. -EFAULT or -ENOMEM), - > 0 if an exception occurred while walking the page tables - -Read or write data from/to the logical (virtual) memory of a VCPU. +:Capability: KVM_CAP_S390_MEM_OP, KVM_CAP_S390_PROTECTED, KVM_CAP_S390_MEM_OP_EXTENSION +:Architectures: s390 +:Type: vm ioctl, vcpu ioctl +:Parameters: struct kvm_s390_mem_op (in) +:Returns: = 0 on success, + < 0 on generic error (e.g. -EFAULT or -ENOMEM), + > 0 if an exception occurred while walking the page tables + +Read or write data from/to the VM's memory. +The KVM_CAP_S390_MEM_OP_EXTENSION capability specifies what functionality is +supported. -Parameters are specified via the following structure: +Parameters are specified via the following structure:: -struct kvm_s390_mem_op { + struct kvm_s390_mem_op { __u64 gaddr; /* the guest address */ __u64 flags; /* flags */ __u32 size; /* amount of bytes */ __u32 op; /* type of operation */ __u64 buf; /* buffer in userspace */ - __u8 ar; /* the access register number */ - __u8 reserved[31]; /* should be set to 0 */ -}; - -The type of operation is specified in the "op" field. It is either -KVM_S390_MEMOP_LOGICAL_READ for reading from logical memory space or -KVM_S390_MEMOP_LOGICAL_WRITE for writing to logical memory space. The -KVM_S390_MEMOP_F_CHECK_ONLY flag can be set in the "flags" field to check -whether the corresponding memory access would create an access exception -(without touching the data in the memory at the destination). In case an -access exception occurred while walking the MMU tables of the guest, the -ioctl returns a positive error number to indicate the type of exception. -This exception is also raised directly at the corresponding VCPU if the -flag KVM_S390_MEMOP_F_INJECT_EXCEPTION is set in the "flags" field. + union { + struct { + __u8 ar; /* the access register number */ + __u8 key; /* access key, ignored if flag unset */ + }; + __u32 sida_offset; /* offset into the sida */ + __u8 reserved[32]; /* ignored */ + }; + }; The start address of the memory region has to be specified in the "gaddr" field, and the length of the region in the "size" field (which must not be 0). The maximum value for "size" can be obtained by checking the KVM_CAP_S390_MEM_OP capability. "buf" is the buffer supplied by the userspace application where the read data should be written to for -KVM_S390_MEMOP_LOGICAL_READ, or where the data that should be written is -stored for a KVM_S390_MEMOP_LOGICAL_WRITE. When KVM_S390_MEMOP_F_CHECK_ONLY -is specified, "buf" is unused and can be NULL. "ar" designates the access -register number to be used; the valid range is 0..15. +a read access, or where the data that should be written is stored for +a write access. The "reserved" field is meant for future extensions. +Reserved and unused values are ignored. Future extension that add members must +introduce new flags. + +The type of operation is specified in the "op" field. Flags modifying +their behavior can be set in the "flags" field. Undefined flag bits must +be set to 0. + +Possible operations are: + * ``KVM_S390_MEMOP_LOGICAL_READ`` + * ``KVM_S390_MEMOP_LOGICAL_WRITE`` + * ``KVM_S390_MEMOP_ABSOLUTE_READ`` + * ``KVM_S390_MEMOP_ABSOLUTE_WRITE`` + * ``KVM_S390_MEMOP_SIDA_READ`` + * ``KVM_S390_MEMOP_SIDA_WRITE`` + +Logical read/write: + +Access logical memory, i.e. translate the given guest address to an absolute +address given the state of the VCPU and use the absolute address as target of +the access. "ar" designates the access register number to be used; the valid +range is 0..15. +Logical accesses are permitted for the VCPU ioctl only. +Logical accesses are permitted for non-protected guests only. + +Supported flags: + * ``KVM_S390_MEMOP_F_CHECK_ONLY`` + * ``KVM_S390_MEMOP_F_INJECT_EXCEPTION`` + * ``KVM_S390_MEMOP_F_SKEY_PROTECTION`` + +The KVM_S390_MEMOP_F_CHECK_ONLY flag can be set to check whether the +corresponding memory access would cause an access exception; however, +no actual access to the data in memory at the destination is performed. +In this case, "buf" is unused and can be NULL. + +In case an access exception occurred during the access (or would occur +in case of KVM_S390_MEMOP_F_CHECK_ONLY), the ioctl returns a positive +error number indicating the type of exception. This exception is also +raised directly at the corresponding VCPU if the flag +KVM_S390_MEMOP_F_INJECT_EXCEPTION is set. + +If the KVM_S390_MEMOP_F_SKEY_PROTECTION flag is set, storage key +protection is also in effect and may cause exceptions if accesses are +prohibited given the access key designated by "key"; the valid range is 0..15. +KVM_S390_MEMOP_F_SKEY_PROTECTION is available if KVM_CAP_S390_MEM_OP_EXTENSION +is > 0. + +Absolute read/write: + +Access absolute memory. This operation is intended to be used with the +KVM_S390_MEMOP_F_SKEY_PROTECTION flag, to allow accessing memory and performing +the checks required for storage key protection as one operation (as opposed to +user space getting the storage keys, performing the checks, and accessing +memory thereafter, which could lead to a delay between check and access). +Absolute accesses are permitted for the VM ioctl if KVM_CAP_S390_MEM_OP_EXTENSION +is > 0. +Currently absolute accesses are not permitted for VCPU ioctls. +Absolute accesses are permitted for non-protected guests only. + +Supported flags: + * ``KVM_S390_MEMOP_F_CHECK_ONLY`` + * ``KVM_S390_MEMOP_F_SKEY_PROTECTION`` + +The semantics of the flags are as for logical accesses. + +SIDA read/write: + +Access the secure instruction data area which contains memory operands necessary +for instruction emulation for protected guests. +SIDA accesses are available if the KVM_CAP_S390_PROTECTED capability is available. +SIDA accesses are permitted for the VCPU ioctl only. +SIDA accesses are permitted for protected guests only. -The "reserved" field is meant for future extensions. It is not used by -KVM with the currently defined set of flags. +No flags are supported. 4.90 KVM_S390_GET_SKEYS @@ -3609,6 +3684,18 @@ Parameters: struct kvm_s390_cmma_log (in, out) Returns: 0 on success, a negative value on error +Errors: + + ====== ============================================================= + ENOMEM not enough memory can be allocated to complete the task + ENXIO if CMMA is not enabled + EINVAL if KVM_S390_CMMA_PEEK is not set but migration mode was not enabled + EINVAL if KVM_S390_CMMA_PEEK is not set but dirty tracking has been + disabled (and thus migration mode was automatically disabled) + EFAULT if the userspace address is invalid or if no page table is + present for the addresses (e.g. when using hugepages). + ====== ============================================================= + This ioctl is used to get the values of the CMMA bits on the s390 architecture. It is meant to be used in two scenarios: - During live migration to save the CMMA values. Live migration needs @@ -3685,12 +3772,6 @@ values points to the userspace buffer where the result will be stored. -This ioctl can fail with -ENOMEM if not enough memory can be allocated to -complete the task, with -ENXIO if CMMA is not enabled, with -EINVAL if -KVM_S390_CMMA_PEEK is not set but migration mode was not enabled, with --EFAULT if the userspace address is invalid or if no page table is -present for the addresses (e.g. when using hugepages). - 4.108 KVM_S390_SET_CMMA_BITS Capability: KVM_CAP_S390_CMMA_MIGRATION @@ -4127,6 +4208,90 @@ #define KVM_PMU_EVENT_DENY 1 +4.122 KVM_S390_NORMAL_RESET + +Capability: KVM_CAP_S390_VCPU_RESETS +Architectures: s390 +Type: vcpu ioctl +Parameters: none +Returns: 0 + +This ioctl resets VCPU registers and control structures according to +the cpu reset definition in the POP (Principles Of Operation). + +4.123 KVM_S390_INITIAL_RESET + +Capability: none +Architectures: s390 +Type: vcpu ioctl +Parameters: none +Returns: 0 + +This ioctl resets VCPU registers and control structures according to +the initial cpu reset definition in the POP. However, the cpu is not +put into ESA mode. This reset is a superset of the normal reset. + +4.124 KVM_S390_CLEAR_RESET + +Capability: KVM_CAP_S390_VCPU_RESETS +Architectures: s390 +Type: vcpu ioctl +Parameters: none +Returns: 0 + +This ioctl resets VCPU registers and control structures according to +the clear cpu reset definition in the POP. However, the cpu is not put +into ESA mode. This reset is a superset of the initial reset. + + +4.125 KVM_S390_PV_COMMAND +------------------------- + +:Capability: KVM_CAP_S390_PROTECTED +:Architectures: s390 +:Type: vm ioctl +:Parameters: struct kvm_pv_cmd +:Returns: 0 on success, < 0 on error + +:: + + struct kvm_pv_cmd { + __u32 cmd; /* Command to be executed */ + __u16 rc; /* Ultravisor return code */ + __u16 rrc; /* Ultravisor return reason code */ + __u64 data; /* Data or address */ + __u32 flags; /* flags for future extensions. Must be 0 for now */ + __u32 reserved[3]; + }; + +cmd values: + +KVM_PV_ENABLE + Allocate memory and register the VM with the Ultravisor, thereby + donating memory to the Ultravisor that will become inaccessible to + KVM. All existing CPUs are converted to protected ones. After this + command has succeeded, any CPU added via hotplug will become + protected during its creation as well. + +KVM_PV_DISABLE + + Deregister the VM from the Ultravisor and reclaim the memory that + had been donated to the Ultravisor, making it usable by the kernel + again. All registered VCPUs are converted back to non-protected + ones. + +KVM_PV_VM_SET_SEC_PARMS + Pass the image header from VM memory to the Ultravisor in + preparation of image unpacking and verification. + +KVM_PV_VM_UNPACK + Unpack (protect and decrypt) a page of the encrypted boot image. + +KVM_PV_VM_VERIFY + Verify the integrity of the unpacked image. Only if this succeeds, + KVM is allowed to start protected VCPUs. + + 5. The kvm_run structure ------------------------ @@ -4444,9 +4609,11 @@ #define KVM_EXIT_HYPERV_SYNIC 1 #define KVM_EXIT_HYPERV_HCALL 2 __u32 type; + __u32 pad1; union { struct { __u32 msr; + __u32 pad2; __u64 control; __u64 evt_page; __u64 msg_page; @@ -5322,3 +5489,21 @@ flush hypercalls by Hyper-V) so userspace should disable KVM identification in CPUID and only exposes Hyper-V identification. In this case, guest thinks it's running on Hyper-V and only use Hyper-V hypercalls. + +8.22 KVM_CAP_S390_VCPU_RESETS + +Architectures: s390 + +This capability indicates that the KVM_S390_NORMAL_RESET and +KVM_S390_CLEAR_RESET ioctls are available. + +8.23 KVM_CAP_S390_PROTECTED + +Architecture: s390 + + +This capability indicates that the Ultravisor has been initialized and +KVM can therefore start protected VMs. +This capability governs the KVM_S390_PV_COMMAND ioctl and the +KVM_MP_STATE_LOAD MP_STATE. KVM_SET_MP_STATE can fail for protected +guests when the state change is invalid. --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/devices/s390_flic.txt +++ linux-oracle-5.4.0/Documentation/virt/kvm/devices/s390_flic.txt @@ -100,15 +100,9 @@ mask or unmask the adapter, as specified in mask KVM_S390_IO_ADAPTER_MAP - perform a gmap translation for the guest address provided in addr, - pin a userspace page for the translated address and add it to the - list of mappings - Note: A new mapping will be created unconditionally; therefore, - the calling code should avoid making duplicate mappings. - + This is now a no-op. The mapping is purely done by the irq route. KVM_S390_IO_ADAPTER_UNMAP - release a userspace page for the translated address specified in addr - from the list of mappings + This is now a no-op. The mapping is purely done by the irq route. KVM_DEV_FLIC_AISM modify the adapter-interruption-suppression mode for a given isc if the --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/devices/vm.txt +++ linux-oracle-5.4.0/Documentation/virt/kvm/devices/vm.txt @@ -183,6 +183,7 @@ Parameters: address of a buffer in user space to store the data (u8) to Returns: -EFAULT if the given address is not accessible from kernel space -EINVAL if setting the TOD clock extension to != 0 is not supported + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) 3.2. ATTRIBUTE: KVM_S390_VM_TOD_LOW @@ -191,6 +192,8 @@ Parameters: address of a buffer in user space to store the data (u64) to Returns: -EFAULT if the given address is not accessible from kernel space + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) + 3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT Allows user space to set/get bits 0-63 of the TOD clock register as defined in @@ -202,6 +205,7 @@ (kvm_s390_vm_tod_clock) to Returns: -EFAULT if the given address is not accessible from kernel space -EINVAL if setting the TOD clock extension to != 0 is not supported + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) 4. GROUP: KVM_S390_VM_CRYPTO Architectures: s390 @@ -254,6 +258,10 @@ Setting this attribute when migration mode is already active will have no effects. +Dirty tracking must be enabled on all memslots, else -EINVAL is returned. When +dirty tracking is disabled on any memslot, migration mode is automatically +stopped. + Parameters: none Returns: -ENOMEM if there is not enough free memory to start migration mode -EINVAL if the state of the VM is invalid (e.g. no memory defined) --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/index.rst +++ linux-oracle-5.4.0/Documentation/virt/kvm/index.rst @@ -9,4 +9,6 @@ amd-memory-encryption cpuid + s390-pv + s390-pv-boot vcpu-requests --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/mmu.txt +++ linux-oracle-5.4.0/Documentation/virt/kvm/mmu.txt @@ -152,8 +152,8 @@ shadow pages) so role.quadrant takes values in the range 0..3. Each quadrant maps 1GB virtual address space. role.access: - Inherited guest access permissions in the form uwx. Note execute - permission is positive, not negative. + Inherited guest access permissions from the parent ptes in the form uwx. + Note execute permission is positive, not negative. role.invalid: The page is invalid and should not be used. It is a root page that is currently pinned (by a cpu hardware register pointing to it); once it is @@ -420,7 +420,7 @@ number, it will ignore the cached MMIO information and handle the page fault through the slow path. -Since only 19 bits are used to store generation-number on mmio spte, all +Since only 18 bits are used to store generation-number on mmio spte, all pages are zapped when there is an overflow. Unfortunately, a single memory access might access kvm_memslots(kvm) multiple --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/s390-pv-boot.rst +++ linux-oracle-5.4.0/Documentation/virt/kvm/s390-pv-boot.rst @@ -0,0 +1,84 @@ +.. SPDX-License-Identifier: GPL-2.0 + +====================================== +s390 (IBM Z) Boot/IPL of Protected VMs +====================================== + +Summary +------- +The memory of Protected Virtual Machines (PVMs) is not accessible to +I/O or the hypervisor. In those cases where the hypervisor needs to +access the memory of a PVM, that memory must be made accessible. +Memory made accessible to the hypervisor will be encrypted. See +:doc:`s390-pv` for details." + +On IPL (boot) a small plaintext bootloader is started, which provides +information about the encrypted components and necessary metadata to +KVM to decrypt the protected virtual machine. + +Based on this data, KVM will make the protected virtual machine known +to the Ultravisor (UV) and instruct it to secure the memory of the +PVM, decrypt the components and verify the data and address list +hashes, to ensure integrity. Afterwards KVM can run the PVM via the +SIE instruction which the UV will intercept and execute on KVM's +behalf. + +As the guest image is just like an opaque kernel image that does the +switch into PV mode itself, the user can load encrypted guest +executables and data via every available method (network, dasd, scsi, +direct kernel, ...) without the need to change the boot process. + + +Diag308 +------- +This diagnose instruction is the basic mechanism to handle IPL and +related operations for virtual machines. The VM can set and retrieve +IPL information blocks, that specify the IPL method/devices and +request VM memory and subsystem resets, as well as IPLs. + +For PVMs this concept has been extended with new subcodes: + +Subcode 8: Set an IPL Information Block of type 5 (information block +for PVMs) +Subcode 9: Store the saved block in guest memory +Subcode 10: Move into Protected Virtualization mode + +The new PV load-device-specific-parameters field specifies all data +that is necessary to move into PV mode. + +* PV Header origin +* PV Header length +* List of Components composed of + * AES-XTS Tweak prefix + * Origin + * Size + +The PV header contains the keys and hashes, which the UV will use to +decrypt and verify the PV, as well as control flags and a start PSW. + +The components are for instance an encrypted kernel, kernel parameters +and initrd. The components are decrypted by the UV. + +After the initial import of the encrypted data, all defined pages will +contain the guest content. All non-specified pages will start out as +zero pages on first access. + + +When running in protected virtualization mode, some subcodes will result in +exceptions or return error codes. + +Subcodes 4 and 7, which specify operations that do not clear the guest +memory, will result in specification exceptions. This is because the +UV will clear all memory when a secure VM is removed, and therefore +non-clearing IPL subcodes are not allowed. + +Subcodes 8, 9, 10 will result in specification exceptions. +Re-IPL into a protected mode is only possible via a detour into non +protected mode. + +Keys +---- +Every CEC will have a unique public key to enable tooling to build +encrypted images. +See `s390-tools `_ +for the tooling. --- linux-oracle-5.4.0.orig/Documentation/virt/kvm/s390-pv.rst +++ linux-oracle-5.4.0/Documentation/virt/kvm/s390-pv.rst @@ -0,0 +1,116 @@ +.. SPDX-License-Identifier: GPL-2.0 + +========================================= +s390 (IBM Z) Ultravisor and Protected VMs +========================================= + +Summary +------- +Protected virtual machines (PVM) are KVM VMs that do not allow KVM to +access VM state like guest memory or guest registers. Instead, the +PVMs are mostly managed by a new entity called Ultravisor (UV). The UV +provides an API that can be used by PVMs and KVM to request management +actions. + +Each guest starts in non-protected mode and then may make a request to +transition into protected mode. On transition, KVM registers the guest +and its VCPUs with the Ultravisor and prepares everything for running +it. + +The Ultravisor will secure and decrypt the guest's boot memory +(i.e. kernel/initrd). It will safeguard state changes like VCPU +starts/stops and injected interrupts while the guest is running. + +As access to the guest's state, such as the SIE state description, is +normally needed to be able to run a VM, some changes have been made in +the behavior of the SIE instruction. A new format 4 state description +has been introduced, where some fields have different meanings for a +PVM. SIE exits are minimized as much as possible to improve speed and +reduce exposed guest state. + + +Interrupt injection +------------------- +Interrupt injection is safeguarded by the Ultravisor. As KVM doesn't +have access to the VCPUs' lowcores, injection is handled via the +format 4 state description. + +Machine check, external, IO and restart interruptions each can be +injected on SIE entry via a bit in the interrupt injection control +field (offset 0x54). If the guest cpu is not enabled for the interrupt +at the time of injection, a validity interception is recognized. The +format 4 state description contains fields in the interception data +block where data associated with the interrupt can be transported. + +Program and Service Call exceptions have another layer of +safeguarding; they can only be injected for instructions that have +been intercepted into KVM. The exceptions need to be a valid outcome +of an instruction emulation by KVM, e.g. we can never inject a +addressing exception as they are reported by SIE since KVM has no +access to the guest memory. + + +Mask notification interceptions +------------------------------- +KVM cannot intercept lctl(g) and lpsw(e) anymore in order to be +notified when a PVM enables a certain class of interrupt. As a +replacement, two new interception codes have been introduced: One +indicating that the contents of CRs 0, 6, or 14 have been changed, +indicating different interruption subclasses; and one indicating that +PSW bit 13 has been changed, indicating that a machine check +intervention was requested and those are now enabled. + +Instruction emulation +--------------------- +With the format 4 state description for PVMs, the SIE instruction already +interprets more instructions than it does with format 2. It is not able +to interpret every instruction, but needs to hand some tasks to KVM; +therefore, the SIE and the ultravisor safeguard emulation inputs and outputs. + +The control structures associated with SIE provide the Secure +Instruction Data Area (SIDA), the Interception Parameters (IP) and the +Secure Interception General Register Save Area. Guest GRs and most of +the instruction data, such as I/O data structures, are filtered. +Instruction data is copied to and from the SIDA when needed. Guest +GRs are put into / retrieved from the Secure Interception General +Register Save Area. + +Only GR values needed to emulate an instruction will be copied into this +save area and the real register numbers will be hidden. + +The Interception Parameters state description field still contains the +the bytes of the instruction text, but with pre-set register values +instead of the actual ones. I.e. each instruction always uses the same +instruction text, in order not to leak guest instruction text. +This also implies that the register content that a guest had in r +may be in r from the hypervisor's point of view. + +The Secure Instruction Data Area contains instruction storage +data. Instruction data, i.e. data being referenced by an instruction +like the SCCB for sclp, is moved via the SIDA. When an instruction is +intercepted, the SIE will only allow data and program interrupts for +this instruction to be moved to the guest via the two data areas +discussed before. Other data is either ignored or results in validity +interceptions. + + +Instruction emulation interceptions +----------------------------------- +There are two types of SIE secure instruction intercepts: the normal +and the notification type. Normal secure instruction intercepts will +make the guest pending for instruction completion of the intercepted +instruction type, i.e. on SIE entry it is attempted to complete +emulation of the instruction with the data provided by KVM. That might +be a program exception or instruction completion. + +The notification type intercepts inform KVM about guest environment +changes due to guest instruction interpretation. Such an interception +is recognized, for example, for the store prefix instruction to provide +the new lowcore location. On SIE reentry, any KVM data in the data areas +is ignored and execution continues as if the guest instruction had +completed. For that reason KVM is not allowed to inject a program +interrupt. + +Links +----- +`KVM Forum 2019 presentation `_ --- linux-oracle-5.4.0.orig/Documentation/vm/memory-model.rst +++ linux-oracle-5.4.0/Documentation/vm/memory-model.rst @@ -46,14 +46,12 @@ have entries in the `mem_map` array. The `struct page` objects corresponding to the holes are never fully initialized. -To allocate the `mem_map` array, architecture specific setup code -should call :c:func:`free_area_init_node` function or its convenience -wrapper :c:func:`free_area_init`. Yet, the mappings array is not -usable until the call to :c:func:`memblock_free_all` that hands all -the memory to the page allocator. +To allocate the `mem_map` array, architecture specific setup code should +call :c:func:`free_area_init` function. Yet, the mappings array is not +usable until the call to :c:func:`memblock_free_all` that hands all the +memory to the page allocator. -If an architecture enables `CONFIG_ARCH_HAS_HOLES_MEMORYMODEL` option, -it may free parts of the `mem_map` array that do not cover the +An architecture may free parts of the `mem_map` array that do not cover the actual physical pages. In such case, the architecture specific :c:func:`pfn_valid` implementation should take the holes in the `mem_map` into account. --- linux-oracle-5.4.0.orig/Documentation/vm/slub.rst +++ linux-oracle-5.4.0/Documentation/vm/slub.rst @@ -160,7 +160,7 @@ Here is a sample of slub debug output:: ==================================================================== - BUG kmalloc-8: Redzone overwritten + BUG kmalloc-8: Right Redzone overwritten -------------------------------------------------------------------- INFO: 0xc90f6d28-0xc90f6d2b. First byte 0x00 instead of 0xcc @@ -168,10 +168,10 @@ INFO: Object 0xc90f6d20 @offset=3360 fp=0xc90f6d58 INFO: Allocated in get_modalias+0x61/0xf5 age=53 cpu=1 pid=554 - Bytes b4 0xc90f6d10: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ - Object 0xc90f6d20: 31 30 31 39 2e 30 30 35 1019.005 - Redzone 0xc90f6d28: 00 cc cc cc . - Padding 0xc90f6d50: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ + Bytes b4 (0xc90f6d10): 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ + Object (0xc90f6d20): 31 30 31 39 2e 30 30 35 1019.005 + Redzone (0xc90f6d28): 00 cc cc cc . + Padding (0xc90f6d50): 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ [] dump_trace+0x63/0x1eb [] show_trace_log_lvl+0x1a/0x2f --- linux-oracle-5.4.0.orig/Documentation/x86/topology.rst +++ linux-oracle-5.4.0/Documentation/x86/topology.rst @@ -41,6 +41,8 @@ Packages contain a number of cores plus shared resources, e.g. DRAM controller, shared caches etc. +Modern systems may also use the term 'Die' for package. + AMD nomenclature for package is 'Node'. Package-related topology information in the kernel: @@ -53,11 +55,18 @@ The number of dies in a package. This information is retrieved via CPUID. + - cpuinfo_x86.cpu_die_id: + + The physical ID of the die. This information is retrieved via CPUID. + - cpuinfo_x86.phys_proc_id: The physical ID of the package. This information is retrieved via CPUID and deduced from the APIC IDs of the cores in the package. + Modern systems use this value for the socket. There may be multiple + packages within a socket. This value may differ from cpu_die_id. + - cpuinfo_x86.logical_proc_id: The logical ID of the package. As we do not trust BIOSes to enumerate the --- linux-oracle-5.4.0.orig/Documentation/xtensa/mmu.rst +++ linux-oracle-5.4.0/Documentation/xtensa/mmu.rst @@ -82,7 +82,8 @@ +------------------+ | VMALLOC area | VMALLOC_START 0xc0000000 128MB - 64KB +------------------+ VMALLOC_END - | Cache aliasing | TLBTEMP_BASE_1 0xc7ff0000 DCACHE_WAY_SIZE + +------------------+ + | Cache aliasing | TLBTEMP_BASE_1 0xc8000000 DCACHE_WAY_SIZE | remap area 1 | +------------------+ | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE @@ -124,7 +125,8 @@ +------------------+ | VMALLOC area | VMALLOC_START 0xa0000000 128MB - 64KB +------------------+ VMALLOC_END - | Cache aliasing | TLBTEMP_BASE_1 0xa7ff0000 DCACHE_WAY_SIZE + +------------------+ + | Cache aliasing | TLBTEMP_BASE_1 0xa8000000 DCACHE_WAY_SIZE | remap area 1 | +------------------+ | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE @@ -167,7 +169,8 @@ +------------------+ | VMALLOC area | VMALLOC_START 0x90000000 128MB - 64KB +------------------+ VMALLOC_END - | Cache aliasing | TLBTEMP_BASE_1 0x97ff0000 DCACHE_WAY_SIZE + +------------------+ + | Cache aliasing | TLBTEMP_BASE_1 0x98000000 DCACHE_WAY_SIZE | remap area 1 | +------------------+ | Cache aliasing | TLBTEMP_BASE_2 DCACHE_WAY_SIZE --- linux-oracle-5.4.0.orig/Kconfig +++ linux-oracle-5.4.0/Kconfig @@ -21,6 +21,8 @@ source "drivers/Kconfig" +source "ubuntu/Kconfig" + source "fs/Kconfig" source "security/Kconfig" --- linux-oracle-5.4.0.orig/MAINTAINERS +++ linux-oracle-5.4.0/MAINTAINERS @@ -537,6 +537,17 @@ F: Documentation/scsi/advansys.txt F: drivers/scsi/advansys.c +ADVANTECH AHC1EC0 EMBEDDED CONTROLLER DRIVER +M: Campion Kang +L: linux-kernel@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/mfd/ahc1ec0.yaml +F: drivers/hwmon/ahc1ec0-hwmon.c +F: drivers/mfd/ahc1ec0.c +F: drivers/watchdog/ahc1ec0-wdt.c +F: include/dt-bindings/mfd/ahc1ec0-dt.h +F: include/linux/mfd/ahc1ec0.h + ADXL34X THREE-AXIS DIGITAL ACCELEROMETER DRIVER (ADXL345/ADXL346) M: Michael Hennerich W: http://wiki.analog.com/ADXL345 @@ -1101,7 +1112,7 @@ M: William Breathitt Gray L: linux-iio@vger.kernel.org S: Maintained -F: drivers/iio/adc/stx104.c +F: drivers/iio/addac/stx104.c APM DRIVER M: Jiri Kosina @@ -2832,6 +2843,19 @@ F: include/uapi/linux/audit.h F: kernel/audit* +AUFS (advanced multi layered unification filesystem) FILESYSTEM +M: "J. R. Okajima" +L: aufs-users@lists.sourceforge.net (members only) +L: linux-unionfs@vger.kernel.org +W: http://aufs.sourceforge.net +T: git://github.com/sfjro/aufs4-linux.git +S: Supported +F: Documentation/filesystems/aufs/ +F: Documentation/ABI/testing/debugfs-aufs +F: Documentation/ABI/testing/sysfs-aufs +F: fs/aufs/ +F: include/uapi/linux/aufs_type.h + AUXILIARY DISPLAY DRIVERS M: Miguel Ojeda Sandonis S: Maintained @@ -4028,6 +4052,7 @@ C: irc://chat.freenode.net/clangbuiltlinux S: Supported K: \b(?i:clang|llvm)\b +F: Documentation/kbuild/llvm.rst CLEANCACHE API M: Konrad Rzeszutek Wilk @@ -4616,13 +4641,6 @@ F: include/linux/tfrc.h F: net/dccp/ -DECnet NETWORK LAYER -W: http://linux-decnet.sourceforge.net -L: linux-decnet-user@lists.sourceforge.net -S: Orphan -F: Documentation/networking/decnet.txt -F: net/decnet/ - DECSTATION PLATFORM SUPPORT M: "Maciej W. Rozycki" L: linux-mips@vger.kernel.org @@ -6973,6 +6991,7 @@ S: Maintained F: Documentation/firmware-guide/acpi/gpio-properties.rst F: drivers/gpio/gpiolib-acpi.c +F: drivers/gpio/gpiolib-acpi.h GPIO IR Transmitter M: Sean Young @@ -7364,6 +7383,25 @@ F: net/802/hippi.c F: drivers/net/hippi/ +HISILICON SECURITY ENGINE V2 DRIVER (SEC2) +M: Zaibo Xu +L: linux-crypto@vger.kernel.org +S: Maintained +F: drivers/crypto/hisilicon/sec2/sec_crypto.c +F: drivers/crypto/hisilicon/sec2/sec_main.c +F: drivers/crypto/hisilicon/sec2/sec_crypto.h +F: drivers/crypto/hisilicon/sec2/sec.h +F: Documentation/ABI/testing/debugfs-hisi-sec + +HISILICON HIGH PERFORMANCE RSA ENGINE DRIVER (HPRE) +M: Zaibo Xu +L: linux-crypto@vger.kernel.org +S: Maintained +F: drivers/crypto/hisilicon/hpre/hpre_crypto.c +F: drivers/crypto/hisilicon/hpre/hpre_main.c +F: drivers/crypto/hisilicon/hpre/hpre.h +F: Documentation/ABI/testing/debugfs-hisi-hpre + HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) M: Yisen Zhuang M: Salil Mehta @@ -7372,6 +7410,11 @@ S: Maintained F: drivers/net/ethernet/hisilicon/hns3/ +HISILICON TRUE RANDOM NUMBER GENERATOR V2 SUPPORT +M: Zaibo Xu +S: Maintained +F: drivers/char/hw_random/hisi-trng-v2.c + HISILICON LPC BUS DRIVER M: john.garry@huawei.com W: http://www.hisilicon.com @@ -7410,6 +7453,12 @@ F: drivers/scsi/hisi_sas/ F: Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +HISILICON V3XX SPI NOR FLASH Controller Driver +M: John Garry +W: http://www.hisilicon.com +S: Maintained +F: drivers/spi/spi-hisi-sfc-v3xx.c + HISILICON QM AND ZIP Controller DRIVER M: Zhou Wang L: linux-crypto@vger.kernel.org @@ -7417,7 +7466,6 @@ F: drivers/crypto/hisilicon/qm.c F: drivers/crypto/hisilicon/qm.h F: drivers/crypto/hisilicon/sgl.c -F: drivers/crypto/hisilicon/sgl.h F: drivers/crypto/hisilicon/zip/ F: Documentation/ABI/testing/debugfs-hisi-zip @@ -8200,7 +8248,7 @@ M: Rodrigo Vivi L: intel-gfx@lists.freedesktop.org W: https://01.org/linuxgraphics/ -B: https://01.org/linuxgraphics/documentation/how-report-bugs +B: https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs C: irc://chat.freenode.net/intel-gfx Q: http://patchwork.freedesktop.org/project/intel-gfx/ T: git git://anongit.freedesktop.org/drm-intel @@ -8703,8 +8751,10 @@ L: netdev@vger.kernel.org W: http://www.isdn4linux.de S: Maintained -F: drivers/isdn/mISDN -F: drivers/isdn/hardware +F: drivers/isdn/mISDN/ +F: drivers/isdn/hardware/ +F: drivers/isdn/Kconfig +F: drivers/isdn/Makefile ISDN/CAPI SUBSYSTEM M: Karsten Keil @@ -8991,6 +9041,7 @@ W: http://www.ibm.com/developerworks/linux/linux390/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux.git S: Supported +F: Documentation/virt/kvm/s390* F: arch/s390/include/uapi/asm/kvm* F: arch/s390/include/asm/gmap.h F: arch/s390/include/asm/kvm* @@ -13636,6 +13687,7 @@ RANDOM NUMBER DRIVER M: "Theodore Ts'o" +M: Jason A. Donenfeld S: Maintained F: drivers/char/random.c @@ -14131,6 +14183,7 @@ S: Supported F: arch/s390/pci/ F: drivers/pci/hotplug/s390_pci_hpc.c +F: Documentation/s390/pci.rst S390 VFIO-CCW DRIVER M: Cornelia Huck @@ -14656,6 +14709,7 @@ S: Maintained F: drivers/net/phy/phylink.c F: drivers/net/phy/sfp* +F: include/linux/mdio/mdio-i2c.h F: include/linux/phylink.h F: include/linux/sfp.h K: phylink @@ -17859,7 +17913,8 @@ F: sound/xen/* XFS FILESYSTEM -M: Darrick J. Wong +M: Chandan Babu R +M: Darrick J. Wong M: linux-xfs@vger.kernel.org L: linux-xfs@vger.kernel.org W: http://xfs.org/ --- linux-oracle-5.4.0.orig/Makefile +++ linux-oracle-5.4.0/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 0 +SUBLEVEL = 291 EXTRAVERSION = NAME = Kleptomaniac Octopus @@ -89,9 +89,16 @@ # If the user is running make -s (silent mode), suppress echoing of # commands +# make-4.0 (and later) keep single letter options in the 1st word of MAKEFLAGS. -ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) - quiet=silent_ +ifeq ($(filter 3.%,$(MAKE_VERSION)),) +silence:=$(findstring s,$(firstword -$(MAKEFLAGS))) +else +silence:=$(findstring s,$(filter-out --%,$(MAKEFLAGS))) +endif + +ifeq ($(silence),s) +quiet=silent_ endif export quiet Q KBUILD_VERBOSE @@ -206,6 +213,20 @@ KBUILD_CHECKSRC = 0 endif +# Call message checker as part of the C compilation +# +# Use 'make D=1' to enable checking +# Use 'make D=2' to create the message catalog + +ifdef D + ifeq ("$(origin D)", "command line") + KBUILD_KMSG_CHECK = $(D) + endif +endif +ifndef KBUILD_KMSG_CHECK + KBUILD_KMSG_CHECK = 0 +endif + # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the # directory of external module to build. Setting M= takes precedence. ifeq ("$(origin M)", "command line") @@ -394,8 +415,13 @@ HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null) -HOSTCC = gcc -HOSTCXX = g++ +ifneq ($(LLVM),) +HOSTCC = clang +HOSTCXX = clang++ +else +HOSTCC = gcc +HOSTCXX = g++ +endif KBUILD_HOSTCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 \ -fomit-frame-pointer -std=gnu89 $(HOST_LFS_CFLAGS) \ $(HOSTCFLAGS) @@ -404,31 +430,49 @@ KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) # Make variables (CC, etc...) -AS = $(CROSS_COMPILE)as -LD = $(CROSS_COMPILE)ld -CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E +ifneq ($(LLVM),) +CC = clang +LD = ld.lld +AR = llvm-ar +NM = llvm-nm +OBJCOPY = llvm-objcopy +OBJDUMP = llvm-objdump +READELF = llvm-readelf +OBJSIZE = llvm-size +STRIP = llvm-strip +else +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld AR = $(CROSS_COMPILE)ar NM = $(CROSS_COMPILE)nm -STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump +READELF = $(CROSS_COMPILE)readelf OBJSIZE = $(CROSS_COMPILE)size +STRIP = $(CROSS_COMPILE)strip +endif PAHOLE = pahole LEX = flex YACC = bison AWK = awk INSTALLKERNEL := installkernel -DEPMOD = /sbin/depmod +DEPMOD = depmod PERL = perl PYTHON = python -PYTHON2 = python2 PYTHON3 = python3 CHECK = sparse BASH = bash +KGZIP = gzip +KBZIP2 = bzip2 +KLZOP = lzop +LZMA = lzma +LZ4 = lz4c +XZ = xz CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void -Wno-unknown-attribute $(CF) +KMSG_CHECK = $(srctree)/scripts/kmsg-doc NOSTDINC_FLAGS := CFLAGS_MODULE = AFLAGS_MODULE = @@ -437,6 +481,13 @@ AFLAGS_KERNEL = LDFLAGS_vmlinux = +# Prefer linux-backports-modules +ifneq ($(KBUILD_SRC),) +ifneq ($(shell if test -e $(KBUILD_OUTPUT)/ubuntu-build; then echo yes; fi),yes) +UBUNTUINCLUDE := -I/usr/src/linux-headers-lbm-$(KERNELRELEASE) +endif +endif + # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE := \ -I$(srctree)/arch/$(SRCARCH)/include/uapi \ @@ -448,17 +499,21 @@ # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option LINUXINCLUDE := \ + $(UBUNTUINCLUDE) \ -I$(srctree)/arch/$(SRCARCH)/include \ -I$(objtree)/arch/$(SRCARCH)/include/generated \ $(if $(building_out_of_srctree),-I$(srctree)/include) \ -I$(objtree)/include \ $(USERINCLUDE) +# UBUNTU: Include our third party driver stuff too +LINUXINCLUDE += -Iubuntu/include $(if $(KBUILD_SRC),-I$(srctree)/ubuntu/include) + KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ -Werror=implicit-function-declaration -Werror=implicit-int \ - -Wno-format-security \ + -Werror=return-type -Wno-format-security \ -std=gnu89 KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_AFLAGS_KERNEL := @@ -471,15 +526,17 @@ GCC_PLUGINS_CFLAGS := CLANG_FLAGS := -export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC -export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE PAHOLE LEX YACC AWK INSTALLKERNEL -export PERL PYTHON PYTHON2 PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX +export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC +export CPP AR NM STRIP OBJCOPY OBJDUMP OBJSIZE READELF PAHOLE LEX YACC AWK INSTALLKERNEL +export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX +export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ export KBUILD_HOSTCXXFLAGS KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS LDFLAGS_MODULE export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE +export KBUILD_KMSG_CHECK KMSG_CHECK export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL @@ -528,13 +585,13 @@ ifneq ($(CROSS_COMPILE),) CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%)) GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) -CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) +CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) endif ifneq ($(GCC_TOOLCHAIN),) CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) endif -ifeq ($(shell $(AS) --version 2>&1 | head -n 1 | grep clang),) +ifneq ($(LLVM_IAS),1) CLANG_FLAGS += -no-integrated-as endif CLANG_FLAGS += -Werror=unknown-warning-option @@ -587,12 +644,8 @@ KBUILD_BUILTIN := 1 # If we have only "make modules", don't compile built-in objects. -# When we're building modules with modversions, we need to consider -# the built-in objects during the descend as well, in order to -# make sure the checksums are up to date before we record them. - ifeq ($(MAKECMDGOALS),modules) - KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) + KBUILD_BUILTIN := endif # If we have "make modules", compile modules @@ -616,9 +669,8 @@ ifeq ($(KBUILD_EXTMOD),) # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ -drivers-y := drivers/ sound/ +drivers-y := drivers/ sound/ ubuntu/ drivers-$(CONFIG_SAMPLES) += samples/ -drivers-$(CONFIG_KERNEL_HEADER_TEST) += include/ net-y := net/ libs-y := lib/ core-y := usr/ @@ -708,12 +760,9 @@ KBUILD_CFLAGS += -Os endif -ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED -KBUILD_CFLAGS += -Wno-maybe-uninitialized -endif - # Tell gcc to never replace conditional load with a non-conditional one KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races) include scripts/Makefile.kcov include scripts/Makefile.gcc-plugins @@ -750,17 +799,21 @@ KBUILD_CFLAGS += -mno-global-merge else -# These warnings generated too much noise in a regular build. -# Use make W=1 to enable them (see scripts/Makefile.extrawarn) -KBUILD_CFLAGS += -Wno-unused-but-set-variable - # Warn about unmarked fall-throughs in switch statement. # Disabled for clang while comment to attribute conversion happens and # https://github.com/ClangBuiltLinux/linux/issues/636 is discussed. KBUILD_CFLAGS += $(call cc-option,-Wimplicit-fallthrough,) endif +# These warnings generated too much noise in a regular build. +# Use make W=1 to enable them (see scripts/Makefile.extrawarn) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) + KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable) + +# These result in bogus false positives +KBUILD_CFLAGS += $(call cc-disable-warning, dangling-pointer) + ifdef CONFIG_FRAME_POINTER KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls else @@ -787,8 +840,13 @@ else DEBUG_CFLAGS += -g endif +ifeq ($(LLVM_IAS),1) +KBUILD_AFLAGS += -g +else KBUILD_AFLAGS += -Wa,-gdwarf-2 endif +endif + ifdef CONFIG_DEBUG_INFO_DWARF4 DEBUG_CFLAGS += -gdwarf-4 endif @@ -861,6 +919,17 @@ # disable stringop warnings in gcc 8+ KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) +# We'll want to enable this eventually, but it's not going away for 5.7 at least +KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) +KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) + +# Another good warning that we'll want to enable eventually +KBUILD_CFLAGS += $(call cc-disable-warning, restrict) + +# Enabled with W=2, disabled by default as noisy +KBUILD_CFLAGS += $(call cc-disable-warning, maybe-uninitialized) + # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) @@ -891,12 +960,6 @@ # change __FILE__ to the relative path from the srctree KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=) -# ensure -fcf-protection is disabled when using retpoline as it is -# incompatible with -mindirect-branch=thunk-extern -ifdef CONFIG_RETPOLINE -KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) -endif - include scripts/Makefile.kasan include scripts/Makefile.extrawarn include scripts/Makefile.ubsan @@ -909,12 +972,20 @@ KBUILD_LDFLAGS_MODULE += --build-id LDFLAGS_vmlinux += --build-id +KBUILD_LDFLAGS += -z noexecstack +KBUILD_LDFLAGS += $(call ld-option,--no-warn-rwx-segments) + ifeq ($(CONFIG_STRIP_ASM_SYMS),y) LDFLAGS_vmlinux += $(call ld-option, -X,) endif ifeq ($(CONFIG_RELR),y) -LDFLAGS_vmlinux += --pack-dyn-relocs=relr +LDFLAGS_vmlinux += --pack-dyn-relocs=relr --use-android-relr-tags +endif + +# userspace programs are linked via the compiler, use the correct linker +ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_LD_IS_LLD),yy) +KBUILD_USERLDFLAGS += $(call cc-option, --ld-path=$(LD)) endif # make the checker run with the right architecture @@ -978,10 +1049,10 @@ mod_compress_cmd = true ifdef CONFIG_MODULE_COMPRESS ifdef CONFIG_MODULE_COMPRESS_GZIP - mod_compress_cmd = gzip -n -f + mod_compress_cmd = $(KGZIP) -n -f endif # CONFIG_MODULE_COMPRESS_GZIP ifdef CONFIG_MODULE_COMPRESS_XZ - mod_compress_cmd = xz -f + mod_compress_cmd = $(XZ) -f endif # CONFIG_MODULE_COMPRESS_XZ endif # CONFIG_MODULE_COMPRESS export mod_compress_cmd @@ -999,7 +1070,7 @@ ifdef CONFIG_STACK_VALIDATION has_libelf := $(call try-run,\ - echo "int main() {}" | $(HOSTCC) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0) + echo "int main() {}" | $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0) ifeq ($(has_libelf),1) objtool_target := tools/objtool FORCE else @@ -1050,7 +1121,7 @@ ifdef CONFIG_TRIM_UNUSED_KSYMS autoksyms_recursive: descend modules.order $(Q)$(CONFIG_SHELL) $(srctree)/scripts/adjust_autoksyms.sh \ - "$(MAKE) -f $(srctree)/Makefile vmlinux" + "$(MAKE) -f $(srctree)/Makefile autoksyms_recursive" endif # For the kernel to actually contain only the needed exported symbols, @@ -1152,11 +1223,19 @@ endef define filechk_version.h - echo \#define LINUX_VERSION_CODE $(shell \ - expr $(VERSION) \* 65536 + 0$(PATCHLEVEL) \* 256 + 0$(SUBLEVEL)); \ - echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' + if [ $(SUBLEVEL) -gt 255 ]; then \ + echo \#define LINUX_VERSION_CODE $(shell \ + expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + 255); \ + else \ + echo \#define LINUX_VERSION_CODE $(shell \ + expr $(VERSION) \* 65536 + $(PATCHLEVEL) \* 256 + $(SUBLEVEL)); \ + fi; \ + echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + \ + ((c) > 255 ? 255 : (c)))' endef +$(version_h): PATCHLEVEL := $(if $(PATCHLEVEL), $(PATCHLEVEL), 0) +$(version_h): SUBLEVEL := $(if $(SUBLEVEL), $(SUBLEVEL), 0) $(version_h): FORCE $(call filechk,version.h) $(Q)rm -f $(old_version_h) @@ -1195,20 +1274,17 @@ $(error Headers not exportable for the $(SRCARCH) architecture)) $(Q)$(MAKE) $(hdr-inst)=include/uapi $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi + $(Q)$(MAKE) $(hdr-inst)=ubuntu/include dst=include oldheaders= +# Deprecated. It is no-op now. PHONY += headers_check -headers_check: headers - $(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1 - $(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi HDRCHECK=1 +headers_check: + @: ifdef CONFIG_HEADERS_INSTALL prepare: headers endif -ifdef CONFIG_HEADERS_CHECK -all: headers_check -endif - PHONY += scripts_unifdef scripts_unifdef: scripts_basic $(Q)$(MAKE) $(build)=scripts scripts/unifdef @@ -1242,12 +1318,16 @@ %.dtb: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ -PHONY += dtbs dtbs_install dt_binding_check -dtbs dtbs_check: include/config/kernel.release scripts_dtc +PHONY += dtbs dtbs_install dtbs_check +dtbs: include/config/kernel.release scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) +ifneq ($(filter dtbs_check, $(MAKECMDGOALS)),) +dtbs: dt_binding_check +endif + dtbs_check: export CHECK_DTBS=1 -dtbs_check: dt_binding_check +dtbs_check: dtbs dtbs_install: $(Q)$(MAKE) $(dtbinst)=$(dtstree) @@ -1262,6 +1342,7 @@ scripts_dtc: scripts_basic $(Q)$(MAKE) $(build)=scripts/dtc +PHONY += dt_binding_check dt_binding_check: scripts_dtc $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings @@ -1274,6 +1355,13 @@ all: modules +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are up to date before we record them. +ifdef CONFIG_MODVERSIONS + KBUILD_BUILTIN := 1 +endif + # Build modules # # A module can be listed more than once in obj-m resulting in @@ -1476,7 +1564,6 @@ @echo ' versioncheck - Sanity check on version.h usage' @echo ' includecheck - Check for duplicate included header files' @echo ' export_report - List the usages of all exported symbols' - @echo ' headers_check - Sanity check on exported headers' @echo ' headerdep - Detect inclusion cycles in headers' @echo ' coccicheck - Check with Coccinelle' @echo '' @@ -1641,6 +1728,50 @@ PHONY += prepare endif # KBUILD_EXTMOD +# Single targets +# --------------------------------------------------------------------------- +# To build individual files in subdirectories, you can do like this: +# +# make foo/bar/baz.s +# +# The supported suffixes for single-target are listed in 'single-targets' +# +# To build only under specific subdirectories, you can do like this: +# +# make foo/bar/baz/ + +ifdef single-build + +# .ko is special because modpost is needed +single-ko := $(sort $(filter %.ko, $(MAKECMDGOALS))) +single-no-ko := $(sort $(patsubst %.ko,%.mod, $(MAKECMDGOALS))) + +$(single-ko): single_modpost + @: +$(single-no-ko): descend + @: + +ifeq ($(KBUILD_EXTMOD),) +# For the single build of in-tree modules, use a temporary file to avoid +# the situation of modules_install installing an invalid modules.order. +MODORDER := .modules.tmp +endif + +PHONY += single_modpost +single_modpost: $(single-no-ko) + $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost + +KBUILD_MODULES := 1 + +export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko)) + +# trim unrelated directories +build-dirs := $(foreach d, $(build-dirs), \ + $(if $(filter $(d)/%, $(KBUILD_SINGLE_TARGETS)), $(d))) + +endif + # Handle descending into subdirectories listed in $(build-dirs) # Preset locale variables to speed up the build process. Limit locale # tweaks to this spot to avoid wrong language settings when running @@ -1649,7 +1780,9 @@ PHONY += descend $(build-dirs) descend: $(build-dirs) $(build-dirs): prepare - $(Q)$(MAKE) $(build)=$@ single-build=$(single-build) need-builtin=1 need-modorder=1 + $(Q)$(MAKE) $(build)=$@ \ + single-build=$(if $(filter-out $@/, $(single-no-ko)),1) \ + need-builtin=1 need-modorder=1 clean-dirs := $(addprefix _clean_, $(clean-dirs)) PHONY += $(clean-dirs) clean @@ -1753,50 +1886,6 @@ $(Q)mkdir -p $(objtree)/tools $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ $* -# Single targets -# --------------------------------------------------------------------------- -# To build individual files in subdirectories, you can do like this: -# -# make foo/bar/baz.s -# -# The supported suffixes for single-target are listed in 'single-targets' -# -# To build only under specific subdirectories, you can do like this: -# -# make foo/bar/baz/ - -ifdef single-build - -single-all := $(filter $(single-targets), $(MAKECMDGOALS)) - -# .ko is special because modpost is needed -single-ko := $(sort $(filter %.ko, $(single-all))) -single-no-ko := $(sort $(patsubst %.ko,%.mod, $(single-all))) - -$(single-ko): single_modpost - @: -$(single-no-ko): descend - @: - -ifeq ($(KBUILD_EXTMOD),) -# For the single build of in-tree modules, use a temporary file to avoid -# the situation of modules_install installing an invalid modules.order. -MODORDER := .modules.tmp -endif - -PHONY += single_modpost -single_modpost: $(single-no-ko) - $(Q){ $(foreach m, $(single-ko), echo $(extmod-prefix)$m;) } > $(MODORDER) - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost - -KBUILD_MODULES := 1 - -export KBUILD_SINGLE_TARGETS := $(addprefix $(extmod-prefix), $(single-no-ko)) - -single-build = $(if $(filter-out $@/, $(single-no-ko)),1) - -endif - # FIXME Should go into a make.lib or something # =========================================================================== --- linux-oracle-5.4.0.orig/Ubuntu.md +++ linux-oracle-5.4.0/Ubuntu.md @@ -0,0 +1,8 @@ +Name: linux-oracle +Version: 5.4.0 +Series: 20.04 (focal) +Description: + This is the source code for the Ubuntu linux kernel for the 20.04 series. This + source tree is used to produce the flavours: oracle. + This kernel is configured to support the widest range of desktop, laptop and + server configurations. --- linux-oracle-5.4.0.orig/arch/Kconfig +++ linux-oracle-5.4.0/arch/Kconfig @@ -131,6 +131,22 @@ managed by the kernel and kept transparent to the probed application. ) +config HAVE_64BIT_ALIGNED_ACCESS + def_bool 64BIT && !HAVE_EFFICIENT_UNALIGNED_ACCESS + help + Some architectures require 64 bit accesses to be 64 bit + aligned, which also requires structs containing 64 bit values + to be 64 bit aligned too. This includes some 32 bit + architectures which can do 64 bit accesses, as well as 64 bit + architectures without unaligned access. + + This symbol should be selected by an architecture if 64 bit + accesses are required to be 64 bit aligned in this way even + though it is not a 64 bit architecture. + + See Documentation/unaligned-memory-access.txt for more + information on the topic of unaligned memory accesses. + config HAVE_EFFICIENT_UNALIGNED_ACCESS bool help @@ -255,6 +271,9 @@ select ARCH_HAS_DMA_PREP_COHERENT bool +config ARCH_HAS_CPU_FINALIZE_INIT + bool + # Select if arch init_task must go in the __init_task_data section config ARCH_TASK_STRUCT_ON_STACK bool @@ -396,15 +415,22 @@ config HAVE_RCU_TABLE_FREE bool -config HAVE_RCU_TABLE_NO_INVALIDATE +config HAVE_MMU_GATHER_PAGE_SIZE bool -config HAVE_MMU_GATHER_PAGE_SIZE +config MMU_GATHER_NO_RANGE bool config HAVE_MMU_GATHER_NO_GATHER bool +config ARCH_WANT_IRQS_OFF_ACTIVATE_MM + bool + help + Temporary select until all architectures can be converted to have + irqs disabled over activate_mm. Architectures that do IPI based TLB + shootdowns should enable this. + config ARCH_HAVE_NMI_SAFE_CMPXCHG bool @@ -892,27 +918,6 @@ config ARCH_HAS_PHYS_TO_DMA bool -config ARCH_HAS_REFCOUNT - bool - help - An architecture selects this when it has implemented refcount_t - using open coded assembly primitives that provide an optimized - refcount_t implementation, possibly at the expense of some full - refcount state checks of CONFIG_REFCOUNT_FULL=y. - - The refcount overflow check behavior, however, must be retained. - Catching overflows is the primary security concern for protecting - against bugs in reference counts. - -config REFCOUNT_FULL - bool "Perform full reference count validation at the expense of speed" - help - Enabling this switches the refcounting infrastructure from a fast - unchecked atomic_t implementation to a fully state checked - implementation, which can be (slightly) slower but provides protections - against various use-after-free conditions that can be used in - security flaw exploits. - config HAVE_ARCH_COMPILER_H bool help --- linux-oracle-5.4.0.orig/arch/alpha/configs/defconfig +++ linux-oracle-5.4.0/arch/alpha/configs/defconfig @@ -36,7 +36,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_AIC7XXX=m CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 # CONFIG_AIC7XXX_DEBUG_ENABLE is not set --- linux-oracle-5.4.0.orig/arch/alpha/include/asm/io.h +++ linux-oracle-5.4.0/arch/alpha/include/asm/io.h @@ -61,7 +61,7 @@ * Change virtual addresses to physical addresses and vv. */ #ifdef USE_48_BIT_KSEG -static inline unsigned long virt_to_phys(void *address) +static inline unsigned long virt_to_phys(volatile void *address) { return (unsigned long)address - IDENT_ADDR; } @@ -71,7 +71,7 @@ return (void *) (address + IDENT_ADDR); } #else -static inline unsigned long virt_to_phys(void *address) +static inline unsigned long virt_to_phys(volatile void *address) { unsigned long phys = (unsigned long)address; @@ -107,7 +107,7 @@ extern unsigned long __direct_map_base; extern unsigned long __direct_map_size; -static inline unsigned long __deprecated virt_to_bus(void *address) +static inline unsigned long __deprecated virt_to_bus(volatile void *address) { unsigned long phys = virt_to_phys(address); unsigned long bus = phys + __direct_map_base; @@ -322,14 +322,18 @@ #if IO_CONCAT(__IO_PREFIX,trivial_io_bw) extern inline unsigned int ioread8(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr); mb(); return ret; } extern inline unsigned int ioread16(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr); mb(); return ret; } @@ -370,7 +374,9 @@ #if IO_CONCAT(__IO_PREFIX,trivial_io_lq) extern inline unsigned int ioread32(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr); mb(); return ret; } @@ -415,14 +421,18 @@ extern inline u8 readb(const volatile void __iomem *addr) { - u8 ret = __raw_readb(addr); + u8 ret; + mb(); + ret = __raw_readb(addr); mb(); return ret; } extern inline u16 readw(const volatile void __iomem *addr) { - u16 ret = __raw_readw(addr); + u16 ret; + mb(); + ret = __raw_readw(addr); mb(); return ret; } @@ -463,14 +473,18 @@ extern inline u32 readl(const volatile void __iomem *addr) { - u32 ret = __raw_readl(addr); + u32 ret; + mb(); + ret = __raw_readl(addr); mb(); return ret; } extern inline u64 readq(const volatile void __iomem *addr) { - u64 ret = __raw_readq(addr); + u64 ret; + mb(); + ret = __raw_readq(addr); mb(); return ret; } @@ -488,10 +502,10 @@ } #endif -#define ioread16be(p) be16_to_cpu(ioread16(p)) -#define ioread32be(p) be32_to_cpu(ioread32(p)) -#define iowrite16be(v,p) iowrite16(cpu_to_be16(v), (p)) -#define iowrite32be(v,p) iowrite32(cpu_to_be32(v), (p)) +#define ioread16be(p) swab16(ioread16(p)) +#define ioread32be(p) swab32(ioread32(p)) +#define iowrite16be(v,p) iowrite16(swab16(v), (p)) +#define iowrite32be(v,p) iowrite32(swab32(v), (p)) #define inb_p inb #define inw_p inw @@ -499,14 +513,44 @@ #define outb_p outb #define outw_p outw #define outl_p outl -#define readb_relaxed(addr) __raw_readb(addr) -#define readw_relaxed(addr) __raw_readw(addr) -#define readl_relaxed(addr) __raw_readl(addr) -#define readq_relaxed(addr) __raw_readq(addr) -#define writeb_relaxed(b, addr) __raw_writeb(b, addr) -#define writew_relaxed(b, addr) __raw_writew(b, addr) -#define writel_relaxed(b, addr) __raw_writel(b, addr) -#define writeq_relaxed(b, addr) __raw_writeq(b, addr) + +extern u8 readb_relaxed(const volatile void __iomem *addr); +extern u16 readw_relaxed(const volatile void __iomem *addr); +extern u32 readl_relaxed(const volatile void __iomem *addr); +extern u64 readq_relaxed(const volatile void __iomem *addr); + +#if IO_CONCAT(__IO_PREFIX,trivial_io_bw) +extern inline u8 readb_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readb(addr); +} + +extern inline u16 readw_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readw(addr); +} +#endif + +#if IO_CONCAT(__IO_PREFIX,trivial_io_lq) +extern inline u32 readl_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readl(addr); +} + +extern inline u64 readq_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readq(addr); +} +#endif + +#define writeb_relaxed writeb +#define writew_relaxed writew +#define writel_relaxed writel +#define writeq_relaxed writeq /* * String version of IO memory access ops: --- linux-oracle-5.4.0.orig/arch/alpha/include/asm/timex.h +++ linux-oracle-5.4.0/arch/alpha/include/asm/timex.h @@ -28,5 +28,6 @@ __asm__ __volatile__ ("rpcc %0" : "=r"(ret)); return ret; } +#define get_cycles get_cycles #endif --- linux-oracle-5.4.0.orig/arch/alpha/include/uapi/asm/ptrace.h +++ linux-oracle-5.4.0/arch/alpha/include/uapi/asm/ptrace.h @@ -42,6 +42,8 @@ unsigned long trap_a0; unsigned long trap_a1; unsigned long trap_a2; +/* This makes the stack 16-byte aligned as GCC expects */ + unsigned long __pad0; /* These are saved by PAL-code: */ unsigned long ps; unsigned long pc; --- linux-oracle-5.4.0.orig/arch/alpha/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/alpha/kernel/asm-offsets.c @@ -32,7 +32,9 @@ DEFINE(CRED_EGID, offsetof(struct cred, egid)); BLANK(); + DEFINE(SP_OFF, offsetof(struct pt_regs, ps)); DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs)); + DEFINE(SWITCH_STACK_SIZE, sizeof(struct switch_stack)); DEFINE(PT_PTRACED, PT_PTRACED); DEFINE(CLONE_VM, CLONE_VM); DEFINE(CLONE_UNTRACED, CLONE_UNTRACED); --- linux-oracle-5.4.0.orig/arch/alpha/kernel/entry.S +++ linux-oracle-5.4.0/arch/alpha/kernel/entry.S @@ -15,10 +15,6 @@ .set noat .cfi_sections .debug_frame -/* Stack offsets. */ -#define SP_OFF 184 -#define SWITCH_STACK_SIZE 320 - .macro CFI_START_OSF_FRAME func .align 4 .globl \func @@ -199,8 +195,8 @@ CFI_START_OSF_FRAME entMM SAVE_ALL /* save $9 - $15 so the inline exception code can manipulate them. */ - subq $sp, 56, $sp - .cfi_adjust_cfa_offset 56 + subq $sp, 64, $sp + .cfi_adjust_cfa_offset 64 stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp) @@ -215,7 +211,7 @@ .cfi_rel_offset $13, 32 .cfi_rel_offset $14, 40 .cfi_rel_offset $15, 48 - addq $sp, 56, $19 + addq $sp, 64, $19 /* handle the fault */ lda $8, 0x3fff bic $sp, $8, $8 @@ -228,7 +224,7 @@ ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) - addq $sp, 56, $sp + addq $sp, 64, $sp .cfi_restore $9 .cfi_restore $10 .cfi_restore $11 @@ -236,7 +232,7 @@ .cfi_restore $13 .cfi_restore $14 .cfi_restore $15 - .cfi_adjust_cfa_offset -56 + .cfi_adjust_cfa_offset -64 /* finish up the syscall as normal. */ br ret_from_sys_call CFI_END_OSF_FRAME entMM @@ -383,8 +379,8 @@ .cfi_restore $0 .cfi_adjust_cfa_offset -256 SAVE_ALL /* setup normal kernel stack */ - lda $sp, -56($sp) - .cfi_adjust_cfa_offset 56 + lda $sp, -64($sp) + .cfi_adjust_cfa_offset 64 stq $9, 0($sp) stq $10, 8($sp) stq $11, 16($sp) @@ -400,7 +396,7 @@ .cfi_rel_offset $14, 40 .cfi_rel_offset $15, 48 lda $8, 0x3fff - addq $sp, 56, $19 + addq $sp, 64, $19 bic $sp, $8, $8 jsr $26, do_entUnaUser ldq $9, 0($sp) @@ -410,7 +406,7 @@ ldq $13, 32($sp) ldq $14, 40($sp) ldq $15, 48($sp) - lda $sp, 56($sp) + lda $sp, 64($sp) .cfi_restore $9 .cfi_restore $10 .cfi_restore $11 @@ -418,7 +414,7 @@ .cfi_restore $13 .cfi_restore $14 .cfi_restore $15 - .cfi_adjust_cfa_offset -56 + .cfi_adjust_cfa_offset -64 br ret_from_sys_call CFI_END_OSF_FRAME entUna @@ -469,8 +465,10 @@ #ifdef CONFIG_AUDITSYSCALL lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT and $3, $6, $3 -#endif bne $3, strace +#else + blbs $3, strace /* check for SYSCALL_TRACE in disguise */ +#endif beq $4, 1f ldq $27, 0($5) 1: jsr $26, ($27), sys_ni_syscall --- linux-oracle-5.4.0.orig/arch/alpha/kernel/io.c +++ linux-oracle-5.4.0/arch/alpha/kernel/io.c @@ -16,21 +16,27 @@ unsigned int ioread8(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr); mb(); return ret; } unsigned int ioread16(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr); mb(); return ret; } unsigned int ioread32(void __iomem *addr) { - unsigned int ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr); + unsigned int ret; + mb(); + ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr); mb(); return ret; } @@ -148,28 +154,36 @@ u8 readb(const volatile void __iomem *addr) { - u8 ret = __raw_readb(addr); + u8 ret; + mb(); + ret = __raw_readb(addr); mb(); return ret; } u16 readw(const volatile void __iomem *addr) { - u16 ret = __raw_readw(addr); + u16 ret; + mb(); + ret = __raw_readw(addr); mb(); return ret; } u32 readl(const volatile void __iomem *addr) { - u32 ret = __raw_readl(addr); + u32 ret; + mb(); + ret = __raw_readl(addr); mb(); return ret; } u64 readq(const volatile void __iomem *addr) { - u64 ret = __raw_readq(addr); + u64 ret; + mb(); + ret = __raw_readq(addr); mb(); return ret; } @@ -207,6 +221,38 @@ EXPORT_SYMBOL(writel); EXPORT_SYMBOL(writeq); +/* + * The _relaxed functions must be ordered w.r.t. each other, but they don't + * have to be ordered w.r.t. other memory accesses. + */ +u8 readb_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readb(addr); +} + +u16 readw_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readw(addr); +} + +u32 readl_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readl(addr); +} + +u64 readq_relaxed(const volatile void __iomem *addr) +{ + mb(); + return __raw_readq(addr); +} + +EXPORT_SYMBOL(readb_relaxed); +EXPORT_SYMBOL(readw_relaxed); +EXPORT_SYMBOL(readl_relaxed); +EXPORT_SYMBOL(readq_relaxed); /* * Read COUNT 8-bit bytes from port PORT into memory starting at SRC. --- linux-oracle-5.4.0.orig/arch/alpha/kernel/module.c +++ linux-oracle-5.4.0/arch/alpha/kernel/module.c @@ -146,10 +146,8 @@ base = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr; symtab = (Elf64_Sym *)sechdrs[symindex].sh_addr; - /* The small sections were sorted to the end of the segment. - The following should definitely cover them. */ - gp = (u64)me->core_layout.base + me->core_layout.size - 0x8000; got = sechdrs[me->arch.gotsecindex].sh_addr; + gp = got + 0x8000; for (i = 0; i < n; i++) { unsigned long r_sym = ELF64_R_SYM (rela[i].r_info); --- linux-oracle-5.4.0.orig/arch/alpha/kernel/osf_sys.c +++ linux-oracle-5.4.0/arch/alpha/kernel/osf_sys.c @@ -963,7 +963,7 @@ } static inline long -put_tv_to_tv32(struct timeval32 __user *o, struct timeval *i) +put_tv_to_tv32(struct timeval32 __user *o, struct __kernel_old_timeval *i) { return copy_to_user(o, &(struct timeval32){ .tv_sec = i->tv_sec, --- linux-oracle-5.4.0.orig/arch/alpha/kernel/setup.c +++ linux-oracle-5.4.0/arch/alpha/kernel/setup.c @@ -394,8 +394,7 @@ extern void setup_memory(void *); #endif /* !CONFIG_DISCONTIGMEM */ -int __init -page_is_ram(unsigned long pfn) +int page_is_ram(unsigned long pfn) { struct memclust_struct * cluster; struct memdesc_struct * memdesc; --- linux-oracle-5.4.0.orig/arch/alpha/kernel/smp.c +++ linux-oracle-5.4.0/arch/alpha/kernel/smp.c @@ -585,7 +585,7 @@ smp_send_stop(void) { cpumask_t to_whom; - cpumask_copy(&to_whom, cpu_possible_mask); + cpumask_copy(&to_whom, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &to_whom); #ifdef DEBUG_IPI_MSG if (hard_smp_processor_id() != boot_cpu_id) --- linux-oracle-5.4.0.orig/arch/alpha/kernel/srmcons.c +++ linux-oracle-5.4.0/arch/alpha/kernel/srmcons.c @@ -59,7 +59,7 @@ } while((result.bits.status & 1) && (++loops < 10)); if (count) - tty_schedule_flip(port); + tty_flip_buffer_push(port); return count; } --- linux-oracle-5.4.0.orig/arch/alpha/kernel/traps.c +++ linux-oracle-5.4.0/arch/alpha/kernel/traps.c @@ -192,7 +192,7 @@ local_irq_enable(); while (1); } - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } #ifndef CONFIG_MATHEMU @@ -235,7 +235,21 @@ { int signo, code; - if ((regs->ps & ~IPL_MAX) == 0) { + if (type == 3) { /* FEN fault */ + /* Irritating users can call PAL_clrfen to disable the + FPU for the process. The kernel will then trap in + do_switch_stack and undo_switch_stack when we try + to save and restore the FP registers. + + Given that GCC by default generates code that uses the + FP registers, PAL_clrfen is not useful except for DoS + attacks. So turn the bleeding FPU back on and be done + with it. */ + current_thread_info()->pcb.flags |= 1; + __reload_thread(¤t_thread_info()->pcb); + return; + } + if (!user_mode(regs)) { if (type == 1) { const unsigned int *data = (const unsigned int *) regs->pc; @@ -368,20 +382,6 @@ } break; - case 3: /* FEN fault */ - /* Irritating users can call PAL_clrfen to disable the - FPU for the process. The kernel will then trap in - do_switch_stack and undo_switch_stack when we try - to save and restore the FP registers. - - Given that GCC by default generates code that uses the - FP registers, PAL_clrfen is not useful except for DoS - attacks. So turn the bleeding FPU back on and be done - with it. */ - current_thread_info()->pcb.flags |= 1; - __reload_thread(¤t_thread_info()->pcb); - return; - case 5: /* illoc */ default: /* unexpected instruction-fault type */ ; @@ -577,7 +577,7 @@ printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", pc, va, opcode, reg); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); got_exception: /* Ok, we caught the exception, but we don't want it. Is there @@ -632,7 +632,7 @@ local_irq_enable(); while (1); } - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } /* @@ -709,7 +709,7 @@ static int unauser_reg_offsets[32] = { R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8), /* r9 ... r15 are stored in front of regs. */ - -56, -48, -40, -32, -24, -16, -8, + -64, -56, -48, -40, -32, -24, -16, /* padding at -8 */ R(r16), R(r17), R(r18), R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26), R(r27), R(r28), R(gp), --- linux-oracle-5.4.0.orig/arch/alpha/mm/fault.c +++ linux-oracle-5.4.0/arch/alpha/mm/fault.c @@ -77,8 +77,8 @@ /* Macro for exception fixup code to access integer registers. */ #define dpf_reg(r) \ - (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ - (r) <= 18 ? (r)+10 : (r)-10]) + (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-17 : \ + (r) <= 18 ? (r)+11 : (r)-10]) asmlinkage void do_page_fault(unsigned long address, unsigned long mmcsr, @@ -206,7 +206,7 @@ printk(KERN_ALERT "Unable to handle kernel paging request at " "virtual address %016lx\n", address); die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16); - do_exit(SIGKILL); + make_task_dead(SIGKILL); /* We ran out of memory, or some other thing happened to us that made us unable to handle the page fault gracefully. */ --- linux-oracle-5.4.0.orig/arch/alpha/mm/init.c +++ linux-oracle-5.4.0/arch/alpha/mm/init.c @@ -239,21 +239,17 @@ */ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES] = {0, }; - unsigned long dma_pfn, high_pfn; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; + unsigned long dma_pfn; dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - high_pfn = max_pfn = max_low_pfn; + max_pfn = max_low_pfn; - if (dma_pfn >= high_pfn) - zones_size[ZONE_DMA] = high_pfn; - else { - zones_size[ZONE_DMA] = dma_pfn; - zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; - } + max_zone_pfn[ZONE_DMA] = dma_pfn; + max_zone_pfn[ZONE_NORMAL] = max_pfn; /* Initialize mem_map[]. */ - free_area_init(zones_size); + free_area_init(max_zone_pfn); /* Initialize the kernel's ZERO_PGE. */ memset((void *)ZERO_PGE, 0, PAGE_SIZE); --- linux-oracle-5.4.0.orig/arch/alpha/mm/numa.c +++ linux-oracle-5.4.0/arch/alpha/mm/numa.c @@ -144,8 +144,8 @@ if (!nid && (node_max_pfn < end_kernel_pfn || node_min_pfn > start_kernel_pfn)) panic("kernel loaded out of ram"); - memblock_add(PFN_PHYS(node_min_pfn), - (node_max_pfn - node_min_pfn) << PAGE_SHIFT); + memblock_add_node(PFN_PHYS(node_min_pfn), + (node_max_pfn - node_min_pfn) << PAGE_SHIFT, nid); /* Zone start phys-addr must be 2^(MAX_ORDER-1) aligned. Note that we round this down, not up - node memory @@ -202,8 +202,7 @@ void __init paging_init(void) { - unsigned int nid; - unsigned long zones_size[MAX_NR_ZONES] = {0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; unsigned long dma_local_pfn; /* @@ -215,19 +214,10 @@ */ dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - for_each_online_node(nid) { - unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; - unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_present_pages; - - if (dma_local_pfn >= end_pfn - start_pfn) - zones_size[ZONE_DMA] = end_pfn - start_pfn; - else { - zones_size[ZONE_DMA] = dma_local_pfn; - zones_size[ZONE_NORMAL] = (end_pfn - start_pfn) - dma_local_pfn; - } - node_set_state(nid, N_NORMAL_MEMORY); - free_area_init_node(nid, zones_size, start_pfn, NULL); - } + max_zone_pfn[ZONE_DMA] = dma_local_pfn; + max_zone_pfn[ZONE_NORMAL] = max_pfn; + + free_area_init(max_zone_pfn); /* Initialize the kernel's ZERO_PGE. */ memset((void *)ZERO_PGE, 0, PAGE_SIZE); --- linux-oracle-5.4.0.orig/arch/arc/Kconfig +++ linux-oracle-5.4.0/arch/arc/Kconfig @@ -29,6 +29,7 @@ select GENERIC_SMP_IDLE_THREAD select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK + select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_STACKOVERFLOW select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_IOREMAP_PROT --- linux-oracle-5.4.0.orig/arch/arc/Makefile +++ linux-oracle-5.4.0/arch/arc/Makefile @@ -6,7 +6,7 @@ KBUILD_DEFCONFIG := nsim_hs_defconfig ifeq ($(CROSS_COMPILE),) -CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux-) +CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux- arc-linux-gnu-) endif cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__ @@ -90,16 +90,22 @@ boot := arch/arc/boot -#default target for make without any arguments. -KBUILD_IMAGE := $(boot)/bootpImage - -all: bootpImage -bootpImage: vmlinux - -boot_targets += uImage uImage.bin uImage.gz +boot_targets := uImage.bin uImage.gz uImage.lzma +PHONY += $(boot_targets) $(boot_targets): vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +uimage-default-y := uImage.bin +uimage-default-$(CONFIG_KERNEL_GZIP) := uImage.gz +uimage-default-$(CONFIG_KERNEL_LZMA) := uImage.lzma + +PHONY += uImage +uImage: $(uimage-default-y) + @ln -sf $< $(boot)/uImage + @$(kecho) ' Image $(boot)/uImage is ready' + +CLEAN_FILES += $(boot)/uImage + archclean: $(Q)$(MAKE) $(clean)=$(boot) --- linux-oracle-5.4.0.orig/arch/arc/boot/Makefile +++ linux-oracle-5.4.0/arch/arc/boot/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -targets := vmlinux.bin vmlinux.bin.gz uImage +targets := vmlinux.bin vmlinux.bin.gz # uImage build relies on mkimage being availble on your host for ARC target # You will need to build u-boot for ARC, rename mkimage to arc-elf32-mkimage @@ -13,11 +13,6 @@ UIMAGE_LOADADDR = $(CONFIG_LINUX_LINK_BASE) UIMAGE_ENTRYADDR = $(LINUX_START_TEXT) -suffix-y := bin -suffix-$(CONFIG_KERNEL_GZIP) := gz -suffix-$(CONFIG_KERNEL_LZMA) := lzma - -targets += uImage targets += uImage.bin targets += uImage.gz targets += uImage.lzma @@ -42,7 +37,3 @@ $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma FORCE $(call if_changed,uimage,lzma) - -$(obj)/uImage: $(obj)/uImage.$(suffix-y) - @ln -sf $(notdir $<) $@ - @echo ' Image $@ is ready' --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/axc001.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/axc001.dtsi @@ -85,7 +85,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/axc003.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/axc003.dtsi @@ -129,7 +129,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/axc003_idu.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/axc003_idu.dtsi @@ -135,7 +135,7 @@ * avoid duplicating the MB dtsi file given that IRQ from * this intc to cpu intc are different for axs101 and axs103 */ - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0x0 0xe0012000 0x0 0x200 >; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/axs10x_mb.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/axs10x_mb.dtsi @@ -77,6 +77,7 @@ interrupt-names = "macirq"; phy-mode = "rgmii"; snps,pbl = < 32 >; + snps,multicast-filter-bins = <256>; clocks = <&apbclk>; clock-names = "stmmaceth"; max-speed = <100>; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/hsdk.dts +++ linux-oracle-5.4.0/arch/arc/boot/dts/hsdk.dts @@ -88,6 +88,8 @@ arcpct: pct { compatible = "snps,archs-pct"; + interrupt-parent = <&cpu_intc>; + interrupts = <20>; }; /* TIMER0 with interrupt for clockevent */ @@ -203,12 +205,11 @@ }; gmac: ethernet@8000 { - #interrupt-cells = <1>; compatible = "snps,dwmac"; reg = <0x8000 0x2000>; interrupts = <10>; interrupt-names = "macirq"; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; snps,pbl = <32>; snps,multicast-filter-bins = <256>; clocks = <&gmacclk>; @@ -226,7 +227,7 @@ #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; - phy0: ethernet-phy@0 { + phy0: ethernet-phy@0 { /* Micrel KSZ9031 */ reg = <0>; }; }; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/vdk_axc003.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/vdk_axc003.dtsi @@ -46,7 +46,7 @@ }; - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0xe0012000 0x200 >; --- linux-oracle-5.4.0.orig/arch/arc/boot/dts/vdk_axc003_idu.dtsi +++ linux-oracle-5.4.0/arch/arc/boot/dts/vdk_axc003_idu.dtsi @@ -54,7 +54,7 @@ }; - mb_intc: dw-apb-ictl@e0012000 { + mb_intc: interrupt-controller@e0012000 { #interrupt-cells = <1>; compatible = "snps,dw-apb-ictl"; reg = < 0xe0012000 0x200 >; --- linux-oracle-5.4.0.orig/arch/arc/include/asm/elf.h +++ linux-oracle-5.4.0/arch/arc/include/asm/elf.h @@ -19,7 +19,7 @@ #define R_ARC_32_PCREL 0x31 /*to set parameters in the core dumps */ -#define ELF_ARCH EM_ARCOMPACT +#define ELF_ARCH EM_ARC_INUSE #define ELF_CLASS ELFCLASS32 #ifdef CONFIG_CPU_BIG_ENDIAN --- linux-oracle-5.4.0.orig/arch/arc/include/asm/io.h +++ linux-oracle-5.4.0/arch/arc/include/asm/io.h @@ -32,7 +32,7 @@ { } -extern void iounmap(const void __iomem *addr); +extern void iounmap(const volatile void __iomem *addr); #define ioremap_nocache(phy, sz) ioremap(phy, sz) #define ioremap_wc(phy, sz) ioremap(phy, sz) --- linux-oracle-5.4.0.orig/arch/arc/include/asm/linkage.h +++ linux-oracle-5.4.0/arch/arc/include/asm/linkage.h @@ -8,6 +8,10 @@ #include +#define ASM_NL ` /* use '`' to mark new line in macro */ +#define __ALIGN .align 4 +#define __ALIGN_STR __stringify(__ALIGN) + #ifdef __ASSEMBLY__ .macro ST2 e, o, off @@ -28,8 +32,6 @@ #endif .endm -#define ASM_NL ` /* use '`' to mark new line in macro */ - /* annotation for data we want in DCCM - if enabled in .config */ .macro ARCFP_DATA nm #ifdef CONFIG_ARC_HAS_DCCM --- linux-oracle-5.4.0.orig/arch/arc/include/asm/page.h +++ linux-oracle-5.4.0/arch/arc/include/asm/page.h @@ -7,9 +7,22 @@ #include +#ifdef CONFIG_ARC_HAS_PAE40 + +#define MAX_POSSIBLE_PHYSMEM_BITS 40 +#define PAGE_MASK_PHYS (0xff00000000ull | PAGE_MASK) + +#else /* CONFIG_ARC_HAS_PAE40 */ + +#define MAX_POSSIBLE_PHYSMEM_BITS 32 +#define PAGE_MASK_PHYS PAGE_MASK + +#endif /* CONFIG_ARC_HAS_PAE40 */ + #ifndef __ASSEMBLY__ #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) +#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) struct vm_area_struct; --- linux-oracle-5.4.0.orig/arch/arc/include/asm/pgtable.h +++ linux-oracle-5.4.0/arch/arc/include/asm/pgtable.h @@ -108,8 +108,8 @@ #define ___DEF (_PAGE_PRESENT | _PAGE_CACHEABLE) /* Set of bits not changed in pte_modify */ -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_SPECIAL) - +#define _PAGE_CHG_MASK (PAGE_MASK_PHYS | _PAGE_ACCESSED | _PAGE_DIRTY | \ + _PAGE_SPECIAL) /* More Abbrevaited helpers */ #define PAGE_U_NONE __pgprot(___DEF) #define PAGE_U_R __pgprot(___DEF | _PAGE_READ) @@ -133,11 +133,7 @@ #define PTE_BITS_IN_PD0 (_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_HW_SZ) #define PTE_BITS_RWX (_PAGE_EXECUTE | _PAGE_WRITE | _PAGE_READ) -#ifdef CONFIG_ARC_HAS_PAE40 -#define PTE_BITS_NON_RWX_IN_PD1 (0xff00000000 | PAGE_MASK | _PAGE_CACHEABLE) -#else -#define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK | _PAGE_CACHEABLE) -#endif +#define PTE_BITS_NON_RWX_IN_PD1 (PAGE_MASK_PHYS | _PAGE_CACHEABLE) /************************************************************************** * Mapping of vm_flags (Generic VM) to PTE flags (arch specific) --- linux-oracle-5.4.0.orig/arch/arc/include/asm/syscalls.h +++ linux-oracle-5.4.0/arch/arc/include/asm/syscalls.h @@ -11,6 +11,7 @@ #include int sys_clone_wrapper(int, int, int, int, int); +int sys_clone3_wrapper(void *, size_t); int sys_cacheflush(uint32_t, uint32_t uint32_t); int sys_arc_settls(void *); int sys_arc_gettls(void); --- linux-oracle-5.4.0.orig/arch/arc/include/uapi/asm/page.h +++ linux-oracle-5.4.0/arch/arc/include/uapi/asm/page.h @@ -33,5 +33,4 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) - #endif /* _UAPI__ASM_ARC_PAGE_H */ --- linux-oracle-5.4.0.orig/arch/arc/include/uapi/asm/sigcontext.h +++ linux-oracle-5.4.0/arch/arc/include/uapi/asm/sigcontext.h @@ -18,6 +18,7 @@ */ struct sigcontext { struct user_regs_struct regs; + struct user_regs_arcv2 v2abi; }; #endif /* _ASM_ARC_SIGCONTEXT_H */ --- linux-oracle-5.4.0.orig/arch/arc/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/arc/include/uapi/asm/unistd.h @@ -21,6 +21,7 @@ #define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_SYS_CLONE3 #define __ARCH_WANT_SYS_VFORK #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_TIME32_SYSCALLS --- linux-oracle-5.4.0.orig/arch/arc/kernel/entry.S +++ linux-oracle-5.4.0/arch/arc/kernel/entry.S @@ -35,6 +35,18 @@ b .Lret_from_system_call END(sys_clone_wrapper) +ENTRY(sys_clone3_wrapper) + SAVE_CALLEE_SAVED_USER + bl @sys_clone3 + DISCARD_CALLEE_SAVED_USER + + GET_CURR_THR_INFO_FLAGS r10 + btst r10, TIF_SYSCALL_TRACE + bnz tracesys_exit + + b .Lret_from_system_call +END(sys_clone3_wrapper) + ENTRY(ret_from_fork) ; when the forked child comes here from the __switch_to function ; r0 has the last task pointer. @@ -153,7 +165,6 @@ tracesys: ; save EFA in case tracer wants the PC of traced task ; using ERET won't work since next-PC has already committed - lr r12, [efa] GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11 st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address @@ -166,7 +177,7 @@ ; Do the Sys Call as we normally would. ; Validate the Sys Call number - cmp r8, NR_syscalls + cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi tracesys_exit @@ -188,6 +199,7 @@ st r0, [sp, PT_r0] ; sys call return value in pt_regs ;POST Sys Call Ptrace Hook + mov r0, sp ; pt_regs needed bl @syscall_trace_exit b ret_from_exception ; NOT ret_from_system_call at is saves r0 which ; we'd done before calling post hook above @@ -196,15 +208,9 @@ ; Breakpoint TRAP ; --------------------------------------------- trap_with_param: - - ; stop_pc info by gdb needs this info - lr r0, [efa] + mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc mov r1, sp - ; Now that we have read EFA, it is safe to do "fake" rtie - ; and get out of CPU exception mode - FAKE_RET_FROM_EXCPN - ; Save callee regs in case gdb wants to have a look ; SP will grow up by size of CALLEE Reg-File ; NOTE: clobbers r12 @@ -231,6 +237,10 @@ EXCEPTION_PROLOGUE + lr r12, [efa] + + FAKE_RET_FROM_EXCPN + ;============ TRAP 1 :breakpoints ; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR) bmsk.f 0, r10, 7 @@ -238,9 +248,6 @@ ;============ TRAP (no param): syscall top level - ; First return from Exception to pure K mode (Exception/IRQs renabled) - FAKE_RET_FROM_EXCPN - ; If syscall tracing ongoing, invoke pre-post-hooks GET_CURR_THR_INFO_FLAGS r10 btst r10, TIF_SYSCALL_TRACE @@ -249,7 +256,7 @@ ;============ Normal syscall case ; syscall num shd not exceed the total system calls avail - cmp r8, NR_syscalls + cmp r8, NR_syscalls - 1 mov.hi r0, -ENOSYS bhi .Lret_from_system_call --- linux-oracle-5.4.0.orig/arch/arc/kernel/perf_event.c +++ linux-oracle-5.4.0/arch/arc/kernel/perf_event.c @@ -562,7 +562,7 @@ { struct arc_reg_pct_build pct_bcr; struct arc_reg_cc_build cc_bcr; - int i, has_interrupts; + int i, has_interrupts, irq = -1; int counter_size; /* in bits */ union cc_name { @@ -638,22 +638,25 @@ }; if (has_interrupts) { - int irq = platform_get_irq(pdev, 0); - - if (irq < 0) { - pr_err("Cannot get IRQ number for the platform\n"); - return -ENODEV; + irq = platform_get_irq(pdev, 0); + if (irq >= 0) { + int ret; + + arc_pmu->irq = irq; + + /* intc map function ensures irq_set_percpu_devid() called */ + ret = request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters", + this_cpu_ptr(&arc_pmu_cpu)); + + if (!ret) + on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1); + else + irq = -1; } - arc_pmu->irq = irq; - - /* intc map function ensures irq_set_percpu_devid() called */ - request_percpu_irq(irq, arc_pmu_intr, "ARC perf counters", - this_cpu_ptr(&arc_pmu_cpu)); - - on_each_cpu(arc_cpu_pmu_irq_init, &irq, 1); + } - } else + if (irq == -1) arc_pmu->pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; /* --- linux-oracle-5.4.0.orig/arch/arc/kernel/process.c +++ linux-oracle-5.4.0/arch/arc/kernel/process.c @@ -171,9 +171,8 @@ * | user_r25 | * ------------------ <===== END of PAGE */ -int copy_thread(unsigned long clone_flags, - unsigned long usp, unsigned long kthread_arg, - struct task_struct *p) +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, + unsigned long kthread_arg, struct task_struct *p, unsigned long tls) { struct pt_regs *c_regs; /* child's pt_regs */ unsigned long *childksp; /* to unwind out of __switch_to() */ @@ -231,7 +230,7 @@ * set task's userland tls data ptr from 4th arg * clone C-lib call is difft from clone sys-call */ - task_thread_info(p)->thr_ptr = regs->r3; + task_thread_info(p)->thr_ptr = tls; } else { /* Normal fork case: set parent's TLS ptr in child */ task_thread_info(p)->thr_ptr = --- linux-oracle-5.4.0.orig/arch/arc/kernel/setup.c +++ linux-oracle-5.4.0/arch/arc/kernel/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -409,12 +410,12 @@ if ((unsigned int)__arc_dccm_base != cpu->dccm.base_addr) panic("Linux built with incorrect DCCM Base address\n"); - if (CONFIG_ARC_DCCM_SZ != cpu->dccm.sz) + if (CONFIG_ARC_DCCM_SZ * SZ_1K != cpu->dccm.sz) panic("Linux built with incorrect DCCM Size\n"); #endif #ifdef CONFIG_ARC_HAS_ICCM - if (CONFIG_ARC_ICCM_SZ != cpu->iccm.sz) + if (CONFIG_ARC_ICCM_SZ * SZ_1K != cpu->iccm.sz) panic("Linux built with incorrect ICCM Size\n"); #endif --- linux-oracle-5.4.0.orig/arch/arc/kernel/signal.c +++ linux-oracle-5.4.0/arch/arc/kernel/signal.c @@ -61,6 +61,41 @@ unsigned int sigret_magic; }; +static int save_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) +{ + int err = 0; +#ifndef CONFIG_ISA_ARCOMPACT + struct user_regs_arcv2 v2abi; + + v2abi.r30 = regs->r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + v2abi.r58 = regs->r58; + v2abi.r59 = regs->r59; +#else + v2abi.r58 = v2abi.r59 = 0; +#endif + err = __copy_to_user(&mctx->v2abi, (void const *)&v2abi, sizeof(v2abi)); +#endif + return err; +} + +static int restore_arcv2_regs(struct sigcontext __user *mctx, struct pt_regs *regs) +{ + int err = 0; +#ifndef CONFIG_ISA_ARCOMPACT + struct user_regs_arcv2 v2abi; + + err = __copy_from_user(&v2abi, &mctx->v2abi, sizeof(v2abi)); + + regs->r30 = v2abi.r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + regs->r58 = v2abi.r58; + regs->r59 = v2abi.r59; +#endif +#endif + return err; +} + static int stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs, sigset_t *set) @@ -94,9 +129,13 @@ err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch, sizeof(sf->uc.uc_mcontext.regs.scratch)); + + if (is_isa_arcv2()) + err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs); + err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); - return err; + return err ? -EFAULT : 0; } static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) @@ -109,8 +148,12 @@ err |= __copy_from_user(&uregs.scratch, &(sf->uc.uc_mcontext.regs.scratch), sizeof(sf->uc.uc_mcontext.regs.scratch)); + + if (is_isa_arcv2()) + err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs); + if (err) - return err; + return -EFAULT; set_current_blocked(&set); regs->bta = uregs.scratch.bta; --- linux-oracle-5.4.0.orig/arch/arc/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/arc/kernel/stacktrace.c @@ -38,15 +38,15 @@ #ifdef CONFIG_ARC_DW2_UNWIND -static void seed_unwind_frame_info(struct task_struct *tsk, - struct pt_regs *regs, - struct unwind_frame_info *frame_info) +static int +seed_unwind_frame_info(struct task_struct *tsk, struct pt_regs *regs, + struct unwind_frame_info *frame_info) { /* * synchronous unwinding (e.g. dump_stack) * - uses current values of SP and friends */ - if (tsk == NULL && regs == NULL) { + if (regs == NULL && (tsk == NULL || tsk == current)) { unsigned long fp, sp, blink, ret; frame_info->task = current; @@ -65,11 +65,15 @@ frame_info->call_frame = 0; } else if (regs == NULL) { /* - * Asynchronous unwinding of sleeping task - * - Gets SP etc from task's pt_regs (saved bottom of kernel - * mode stack of task) + * Asynchronous unwinding of a likely sleeping task + * - first ensure it is actually sleeping + * - if so, it will be in __switch_to, kernel mode SP of task + * is safe-kept and BLINK at a well known location in there */ + if (tsk->state == TASK_RUNNING) + return -1; + frame_info->task = tsk; frame_info->regs.r27 = TSK_K_FP(tsk); @@ -103,6 +107,8 @@ frame_info->regs.r63 = regs->ret; frame_info->call_frame = 0; } + + return 0; } #endif @@ -112,11 +118,12 @@ int (*consumer_fn) (unsigned int, void *), void *arg) { #ifdef CONFIG_ARC_DW2_UNWIND - int ret = 0; + int ret = 0, cnt = 0; unsigned int address; struct unwind_frame_info frame_info; - seed_unwind_frame_info(tsk, regs, &frame_info); + if (seed_unwind_frame_info(tsk, regs, &frame_info)) + return 0; while (1) { address = UNW_PC(&frame_info); @@ -132,6 +139,11 @@ break; frame_info.regs.r63 = frame_info.regs.r31; + + if (cnt++ > 128) { + printk("unwinder looping too long, aborting !\n"); + return 0; + } } return address; /* return the last address it saw */ --- linux-oracle-5.4.0.orig/arch/arc/kernel/sys.c +++ linux-oracle-5.4.0/arch/arc/kernel/sys.c @@ -7,6 +7,7 @@ #include #define sys_clone sys_clone_wrapper +#define sys_clone3 sys_clone3_wrapper #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), --- linux-oracle-5.4.0.orig/arch/arc/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/arc/kernel/vmlinux.lds.S @@ -88,6 +88,8 @@ CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.gnu.warning) } --- linux-oracle-5.4.0.orig/arch/arc/mm/cache.c +++ linux-oracle-5.4.0/arch/arc/mm/cache.c @@ -1123,7 +1123,7 @@ clear_page(to); clear_bit(PG_dc_clean, &page->flags); } - +EXPORT_SYMBOL(clear_user_page); /********************************************************************** * Explicit Cache flush request from user space via syscall --- linux-oracle-5.4.0.orig/arch/arc/mm/dma.c +++ linux-oracle-5.4.0/arch/arc/mm/dma.c @@ -48,8 +48,8 @@ * upper layer functions (in include/linux/dma-mapping.h) */ -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: @@ -69,8 +69,8 @@ } } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: --- linux-oracle-5.4.0.orig/arch/arc/mm/init.c +++ linux-oracle-5.4.0/arch/arc/mm/init.c @@ -27,8 +27,8 @@ #ifdef CONFIG_HIGHMEM static unsigned long min_high_pfn, max_high_pfn; -static u64 high_mem_start; -static u64 high_mem_sz; +static phys_addr_t high_mem_start; +static phys_addr_t high_mem_sz; #endif #ifdef CONFIG_DISCONTIGMEM @@ -63,11 +63,14 @@ low_mem_sz = size; in_use = 1; + memblock_add_node(base, size, 0); } else { #ifdef CONFIG_HIGHMEM high_mem_start = base; high_mem_sz = size; in_use = 1; + memblock_add_node(base, size, 1); + memblock_reserve(base, size); #endif } @@ -75,6 +78,11 @@ base, TO_MB(size), !in_use ? "Not used":""); } +bool arch_has_descending_max_zone_pfns(void) +{ + return !IS_ENABLED(CONFIG_ARC_HAS_PAE40); +} + /* * First memory setup routine called from setup_arch() * 1. setup swapper's mm @init_mm @@ -83,8 +91,7 @@ */ void __init setup_arch_memory(void) { - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zones_holes[MAX_NR_ZONES]; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; init_mm.start_code = (unsigned long)_text; init_mm.end_code = (unsigned long)_etext; @@ -115,7 +122,6 @@ * the crash */ - memblock_add_node(low_mem_start, low_mem_sz, 0); memblock_reserve(CONFIG_LINUX_LINK_BASE, __pa(_end) - CONFIG_LINUX_LINK_BASE); @@ -133,22 +139,7 @@ memblock_dump_all(); /*----------------- node/zones setup --------------------------*/ - memset(zones_size, 0, sizeof(zones_size)); - memset(zones_holes, 0, sizeof(zones_holes)); - - zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn; - zones_holes[ZONE_NORMAL] = 0; - - /* - * We can't use the helper free_area_init(zones[]) because it uses - * PAGE_OFFSET to compute the @min_low_pfn which would be wrong - * when our kernel doesn't start at PAGE_OFFSET, i.e. - * PAGE_OFFSET != CONFIG_LINUX_RAM_BASE - */ - free_area_init_node(0, /* node-id */ - zones_size, /* num pages per zone */ - min_low_pfn, /* first pfn of node */ - zones_holes); /* holes */ + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM /* @@ -168,38 +159,35 @@ min_high_pfn = PFN_DOWN(high_mem_start); max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz); - zones_size[ZONE_NORMAL] = 0; - zones_holes[ZONE_NORMAL] = 0; - - zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn; - zones_holes[ZONE_HIGHMEM] = 0; - - free_area_init_node(1, /* node-id */ - zones_size, /* num pages per zone */ - min_high_pfn, /* first pfn of node */ - zones_holes); /* holes */ + max_zone_pfn[ZONE_HIGHMEM] = min_low_pfn; high_memory = (void *)(min_high_pfn << PAGE_SHIFT); kmap_init(); #endif + + free_area_init(max_zone_pfn); } -/* - * mem_init - initializes memory - * - * Frees up bootmem - * Calculates and displays memory available/used - */ -void __init mem_init(void) +static void __init highmem_init(void) { #ifdef CONFIG_HIGHMEM unsigned long tmp; - reset_all_zones_managed_pages(); + memblock_free(high_mem_start, high_mem_sz); for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++) free_highmem_page(pfn_to_page(tmp)); #endif +} +/* + * mem_init - initializes memory + * + * Frees up bootmem + * Calculates and displays memory available/used + */ +void __init mem_init(void) +{ memblock_free_all(); + highmem_init(); mem_init_print_info(NULL); } --- linux-oracle-5.4.0.orig/arch/arc/mm/ioremap.c +++ linux-oracle-5.4.0/arch/arc/mm/ioremap.c @@ -53,9 +53,10 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags) { + unsigned int off; unsigned long vaddr; struct vm_struct *area; - phys_addr_t off, end; + phys_addr_t end; pgprot_t prot = __pgprot(flags); /* Don't allow wraparound, zero size */ @@ -72,7 +73,7 @@ /* Mappings have to be page-aligned */ off = paddr & ~PAGE_MASK; - paddr &= PAGE_MASK; + paddr &= PAGE_MASK_PHYS; size = PAGE_ALIGN(end + 1) - paddr; /* @@ -92,7 +93,7 @@ EXPORT_SYMBOL(ioremap_prot); -void iounmap(const void __iomem *addr) +void iounmap(const volatile void __iomem *addr) { /* weird double cast to handle phys_addr_t > 32 bits */ if (arc_uncached_addr_space((phys_addr_t)(u32)addr)) --- linux-oracle-5.4.0.orig/arch/arc/mm/tlb.c +++ linux-oracle-5.4.0/arch/arc/mm/tlb.c @@ -597,7 +597,7 @@ pte_t *ptep) { unsigned long vaddr = vaddr_unaligned & PAGE_MASK; - phys_addr_t paddr = pte_val(*ptep) & PAGE_MASK; + phys_addr_t paddr = pte_val(*ptep) & PAGE_MASK_PHYS; struct page *page = pfn_to_page(pte_pfn(*ptep)); create_tlb(vma, vaddr, ptep); --- linux-oracle-5.4.0.orig/arch/arc/plat-eznps/Kconfig +++ linux-oracle-5.4.0/arch/arc/plat-eznps/Kconfig @@ -6,8 +6,9 @@ menuconfig ARC_PLAT_EZNPS bool "\"EZchip\" ARC dev platform" + depends on ISA_ARCOMPACT select CPU_BIG_ENDIAN - select CLKSRC_NPS + select CLKSRC_NPS if !PHYS_ADDR_T_64BIT select EZNPS_GIC select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET help --- linux-oracle-5.4.0.orig/arch/arc/plat-eznps/include/plat/ctop.h +++ linux-oracle-5.4.0/arch/arc/plat-eznps/include/plat/ctop.h @@ -33,7 +33,6 @@ #define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C) #define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030) #define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080) -#define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088) #define CTOP_AUX_GPA1 (CTOP_AUX_BASE + 0x08C) #define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300) --- linux-oracle-5.4.0.orig/arch/arc/plat-hsdk/Kconfig +++ linux-oracle-5.4.0/arch/arc/plat-hsdk/Kconfig @@ -8,5 +8,6 @@ select ARC_HAS_ACCL_REGS select ARC_IRQ_NO_AUTOSAVE select CLK_HSDK + select RESET_CONTROLLER select RESET_HSDK select HAVE_PCI --- linux-oracle-5.4.0.orig/arch/arm/Kconfig +++ linux-oracle-5.4.0/arch/arm/Kconfig @@ -5,6 +5,7 @@ select ARCH_32BIT_OFF_T select ARCH_CLOCKSOURCE_DATA select ARCH_HAS_BINFMT_FLAT + select ARCH_HAS_CPU_FINALIZE_INIT if MMU select ARCH_HAS_DEBUG_VIRTUAL if MMU select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB @@ -26,7 +27,7 @@ select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAS_GCOV_PROFILE_ALL - select ARCH_KEEP_MEMBLOCK if HAVE_ARCH_PFN_VALID || KEXEC + select ARCH_KEEP_MEMBLOCK select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_NO_SG_CHAIN if !ARM_HAS_SG_CHAIN select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX @@ -73,8 +74,9 @@ select HAVE_ARM_SMCCC if CPU_V7 select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32 select HAVE_CONTEXT_TRACKING + select HAVE_COPY_THREAD_TLS select HAVE_C_RECORDMCOUNT - select HAVE_DEBUG_KMEMLEAK + select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL select HAVE_DMA_CONTIGUOUS if MMU select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE @@ -84,6 +86,7 @@ select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG select HAVE_FUNCTION_TRACER if !XIP_KERNEL && (CC_IS_GCC || CLANG_VERSION >= 100000) + select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) select HAVE_IDE if PCI || ISA || PCMCIA @@ -117,7 +120,6 @@ select OLD_SIGSUSPEND3 select PCI_SYSCALL if PCI select PERF_USE_VMALLOC - select REFCOUNT_FULL select RTC_LIB select SYS_SUPPORTS_APM_EMULATION # Above selects are sorted alphabetically; please add new ones @@ -506,8 +508,10 @@ select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select NEED_MACH_IO_H + select S3C2410_WATCHDOG select SAMSUNG_ATAGS select USE_OF + select WATCHDOG help Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443 and S3C2450 SoCs based systems, such as the Simtec Electronics BAST @@ -517,7 +521,6 @@ config ARCH_OMAP1 bool "TI OMAP1" depends on MMU - select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_OMAP select CLKDEV_LOOKUP select CLKSRC_MMIO @@ -1514,9 +1517,6 @@ UNPREDICTABLE (in fact it can be predicted that it won't work at all). If in doubt say N. -config ARCH_HAS_HOLES_MEMORYMODEL - bool - config ARCH_SPARSEMEM_ENABLE bool @@ -1524,7 +1524,7 @@ def_bool ARCH_SPARSEMEM_ENABLE config HAVE_ARCH_PFN_VALID - def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM + def_bool y config HIGHMEM bool "High Memory Support" @@ -1838,7 +1838,6 @@ choice prompt "Kernel command line type" if CMDLINE != "" default CMDLINE_FROM_BOOTLOADER - depends on ATAGS config CMDLINE_FROM_BOOTLOADER bool "Use bootloader kernel arguments if available" @@ -1906,7 +1905,7 @@ config KEXEC bool "Kexec system call (EXPERIMENTAL)" depends on (!SMP || PM_SLEEP_SMP) - depends on !CPU_V7M + depends on MMU select KEXEC_CORE help kexec is a system call that implements the ability to shutdown your --- linux-oracle-5.4.0.orig/arch/arm/Makefile +++ linux-oracle-5.4.0/arch/arm/Makefile @@ -66,15 +66,15 @@ # Note that GCC does not numerically define an architecture version # macro, but instead defines a whole series of macros which makes # testing for a specific architecture or later rather impossible. -arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m -arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) -arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) +arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m +arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7-a +arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 -march=armv6 # Only override the compiler option if ARMv6. The ARMv6K extensions are # always available in ARMv7 ifeq ($(CONFIG_CPU_32v6),y) -arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) +arch-$(CONFIG_CPU_32v6K) =-D__LINUX_ARM_ARCH__=6 -march=armv6k endif -arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) +arch-$(CONFIG_CPU_32v5) =-D__LINUX_ARM_ARCH__=5 -march=armv5te arch-$(CONFIG_CPU_32v4T) =-D__LINUX_ARM_ARCH__=4 -march=armv4t arch-$(CONFIG_CPU_32v4) =-D__LINUX_ARM_ARCH__=4 -march=armv4 arch-$(CONFIG_CPU_32v3) =-D__LINUX_ARM_ARCH__=3 -march=armv3m @@ -88,7 +88,7 @@ tune-$(CONFIG_CPU_ARM740T) =-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM9TDMI) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM940T) =-mtune=arm9tdmi -tune-$(CONFIG_CPU_ARM946E) =$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) +tune-$(CONFIG_CPU_ARM946E) =-mtune=arm9e tune-$(CONFIG_CPU_ARM920T) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) =-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) =-mtune=arm9tdmi @@ -96,11 +96,11 @@ tune-$(CONFIG_CPU_FA526) =-mtune=arm9tdmi tune-$(CONFIG_CPU_SA110) =-mtune=strongarm110 tune-$(CONFIG_CPU_SA1100) =-mtune=strongarm1100 -tune-$(CONFIG_CPU_XSCALE) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale -tune-$(CONFIG_CPU_XSC3) =$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale -tune-$(CONFIG_CPU_FEROCEON) =$(call cc-option,-mtune=marvell-f,-mtune=xscale) -tune-$(CONFIG_CPU_V6) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) -tune-$(CONFIG_CPU_V6K) =$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) +tune-$(CONFIG_CPU_XSCALE) =-mtune=xscale +tune-$(CONFIG_CPU_XSC3) =-mtune=xscale +tune-$(CONFIG_CPU_FEROCEON) =-mtune=xscale +tune-$(CONFIG_CPU_V6) =-mtune=arm1136j-s +tune-$(CONFIG_CPU_V6K) =-mtune=arm1136j-s # Evaluate tune cc-option calls now tune-y := $(tune-y) @@ -307,13 +307,15 @@ ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) prepare: stack_protector_prepare stack_protector_prepare: prepare0 - $(eval KBUILD_CFLAGS += \ + $(eval SSP_PLUGIN_CFLAGS := \ -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ include/generated/asm-offsets.h) \ -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ include/generated/asm-offsets.h)) + $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) + $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) endif all: $(notdir $(KBUILD_IMAGE)) --- linux-oracle-5.4.0.orig/arch/arm/boot/bootp/init.S +++ linux-oracle-5.4.0/arch/arm/boot/bootp/init.S @@ -13,7 +13,7 @@ * size immediately following the kernel, we could build this into * a binary blob, and concatenate the zImage using the cat command. */ - .section .start,#alloc,#execinstr + .section .start, "ax" .type _start, #function .globl _start --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/Makefile +++ linux-oracle-5.4.0/arch/arm/boot/compressed/Makefile @@ -90,6 +90,8 @@ $(addprefix $(obj)/,$(libfdt_hdrs)) ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) +CFLAGS_REMOVE_atags_to_fdt.o += -Wframe-larger-than=${CONFIG_FRAME_WARN} +CFLAGS_atags_to_fdt.o += -Wframe-larger-than=1280 OBJS += $(libfdt_objs) atags_to_fdt.o endif @@ -101,7 +103,6 @@ $(libfdt) $(libfdt_hdrs) hyp-stub.S KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING -KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -117,13 +118,14 @@ CFLAGS_fdt_rw.o := $(nossp_flags) CFLAGS_fdt_wip.o := $(nossp_flags) -ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) +ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ + -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) asflags-y := -DZIMAGE # Supply kernel BSS size to the decompressor via a linker symbol. -KBSS_SZ = $(shell echo $$(($$($(CROSS_COMPILE)nm $(obj)/../../../../vmlinux | \ - sed -n -e 's/^\([^ ]*\) [AB] __bss_start$$/-0x\1/p' \ - -e 's/^\([^ ]*\) [AB] __bss_stop$$/+0x\1/p') )) ) +KBSS_SZ = $(shell echo $$(($$($(NM) $(obj)/../../../../vmlinux | \ + sed -n -e 's/^\([^ ]*\) [ABD] __bss_start$$/-0x\1/p' \ + -e 's/^\([^ ]*\) [ABD] __bss_stop$$/+0x\1/p') )) ) LDFLAGS_vmlinux = --defsym _kernel_bss_size=$(KBSS_SZ) # Supply ZRELADDR to the decompressor via a linker symbol. ifneq ($(CONFIG_AUTO_ZRELADDR),y) @@ -165,7 +167,7 @@ # The .data section is already discarded by the linker script so no need # to bother about it here. check_for_bad_syms = \ -bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \ +bad_syms=$$($(NM) $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \ [ -z "$$bad_syms" ] || \ ( echo "following symbols must have non local/private scope:" >&2; \ echo "$$bad_syms" >&2; false ) --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/big-endian.S +++ linux-oracle-5.4.0/arch/arm/boot/compressed/big-endian.S @@ -6,7 +6,7 @@ * Author: Nicolas Pitre */ - .section ".start", #alloc, #execinstr + .section ".start", "ax" mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #(1 << 7) @ enable big endian mode --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/decompress.c +++ linux-oracle-5.4.0/arch/arm/boot/compressed/decompress.c @@ -47,7 +47,10 @@ #endif #ifdef CONFIG_KERNEL_XZ +/* Prevent KASAN override of string helpers in decompressor */ +#undef memmove #define memmove memmove +#undef memcpy #define memcpy memcpy #include "../../../../lib/decompress_unxz.c" #endif --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/efi-header.S +++ linux-oracle-5.4.0/arch/arm/boot/compressed/efi-header.S @@ -9,16 +9,22 @@ #include .macro __nop -#ifdef CONFIG_EFI_STUB - @ This is almost but not quite a NOP, since it does clobber the - @ condition flags. But it is the best we can do for EFI, since - @ PE/COFF expects the magic string "MZ" at offset 0, while the - @ ARM/Linux boot protocol expects an executable instruction - @ there. - .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 -#else AR_CLASS( mov r0, r0 ) M_CLASS( nop.w ) + .endm + + .macro __initial_nops +#ifdef CONFIG_EFI_STUB + @ This is a two-instruction NOP, which happens to bear the + @ PE/COFF signature "MZ" in the first two bytes, so the kernel + @ is accepted as an EFI binary. Booting via the UEFI stub + @ will not execute those instructions, but the ARM/Linux + @ boot protocol does, so we need some NOPs here. + .inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000 + eor r5, r5, 0x4d000 @ undo previous insn +#else + __nop + __nop #endif .endm --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/head.S +++ linux-oracle-5.4.0/arch/arm/boot/compressed/head.S @@ -140,7 +140,7 @@ #endif .endm - .section ".start", #alloc, #execinstr + .section ".start", "ax" /* * sort out different calling conventions */ @@ -165,7 +165,8 @@ * were patching the initial instructions of the kernel, i.e * had started to exploit this "patch area". */ - .rept 7 + __initial_nops + .rept 5 __nop .endr #ifndef CONFIG_THUMB2_KERNEL @@ -1142,9 +1143,9 @@ __armv7_mmu_cache_off: mrc p15, 0, r0, c1, c0 #ifdef CONFIG_MMU - bic r0, r0, #0x000d + bic r0, r0, #0x0005 #else - bic r0, r0, #0x000c + bic r0, r0, #0x0004 #endif mcr p15, 0, r0, c1, c0 @ turn MMU and cache off mov r12, lr @@ -1273,7 +1274,7 @@ __armv5tej_mmu_cache_flush: tst r4, #1 movne pc, lr -1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache +1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate D cache bne 1b mcr p15, 0, r0, c7, c5, 0 @ flush I cache mcr p15, 0, r0, c7, c10, 4 @ drain WB --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/libfdt_env.h +++ linux-oracle-5.4.0/arch/arm/boot/compressed/libfdt_env.h @@ -2,11 +2,13 @@ #ifndef _ARM_LIBFDT_ENV_H #define _ARM_LIBFDT_ENV_H +#include #include #include #include -#define INT_MAX ((int)(~0U>>1)) +#define INT32_MAX S32_MAX +#define UINT32_MAX U32_MAX typedef __be16 fdt16_t; typedef __be32 fdt32_t; --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/piggy.S +++ linux-oracle-5.4.0/arch/arm/boot/compressed/piggy.S @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ - .section .piggydata,#alloc + .section .piggydata, "a" .globl input_data input_data: .incbin "arch/arm/boot/compressed/piggy_data" --- linux-oracle-5.4.0.orig/arch/arm/boot/compressed/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/arm/boot/compressed/vmlinux.lds.S @@ -43,7 +43,7 @@ } .table : ALIGN(4) { _table_start = .; - LONG(ZIMAGE_MAGIC(2)) + LONG(ZIMAGE_MAGIC(4)) LONG(ZIMAGE_MAGIC(0x5a534c4b)) LONG(ZIMAGE_MAGIC(__piggy_size_addr - _start)) LONG(ZIMAGE_MAGIC(_kernel_bss_size)) --- linux-oracle-5.4.0.orig/arch/arm/boot/deflate_xip_data.sh +++ linux-oracle-5.4.0/arch/arm/boot/deflate_xip_data.sh @@ -56,7 +56,7 @@ # substitute the data section by a compressed version $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp" $DD if="$XIPIMAGE" skip=$data_start iflag=skip_bytes | -gzip -9 >> "$XIPIMAGE.tmp" +$KGZIP -9 >> "$XIPIMAGE.tmp" # replace kernel binary mv -f "$XIPIMAGE.tmp" "$XIPIMAGE" --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am335x-boneblack-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am335x-boneblack-common.dtsi @@ -131,6 +131,11 @@ }; / { + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; + clk_mcasp0_fixed: clk_mcasp0_fixed { #clock-cells = <0>; compatible = "fixed-clock"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am335x-cm-t335.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am335x-cm-t335.dts @@ -516,7 +516,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; - ti,pindir-d0-out-d1-in = <1>; + ti,pindir-d0-out-d1-in; /* WLS1271 WiFi */ wlcore: wlcore@1 { compatible = "ti,wl1271"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am335x-pcm-953.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am335x-pcm-953.dtsi @@ -12,22 +12,20 @@ compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; /* Power */ - regulators { - vcc3v3: fixedregulator@1 { - compatible = "regulator-fixed"; - regulator-name = "vcc3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; + vcc3v3: fixedregulator1 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; - vcc1v8: fixedregulator@2 { - compatible = "regulator-fixed"; - regulator-name = "vcc1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-boot-on; - }; + vcc1v8: fixedregulator2 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; }; /* User IO */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am335x-pocketbeagle.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am335x-pocketbeagle.dts @@ -88,7 +88,6 @@ AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0) AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0) - AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKR, PIN_INPUT, MUX_MODE4) /* (B12) mcasp0_aclkr.mmc0_sdwp */ >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am335x-sancloud-bbe.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am335x-sancloud-bbe.dts @@ -108,7 +108,7 @@ &cpsw_emac0 { phy-handle = <ðphy0>; - phy-mode = "rgmii-txid"; + phy-mode = "rgmii-id"; }; &i2c0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am33xx-l4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am33xx-l4.dtsi @@ -1337,8 +1337,7 @@ ti,dual-volt; ti,needs-special-reset; ti,needs-special-hs-handling; - dmas = <&edma_xbar 24 0 0 - &edma_xbar 25 0 0>; + dmas = <&edma 24 0>, <&edma 25 0>; dma-names = "tx", "rx"; interrupts = <64>; reg = <0x0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am33xx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am33xx.dtsi @@ -40,6 +40,9 @@ ethernet1 = &cpsw_emac1; spi0 = &spi0; spi1 = &spi1; + mmc0 = &mmc1; + mmc1 = &mmc2; + mmc2 = &mmc3; }; cpus { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am3517-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am3517-evm.dts @@ -160,6 +160,8 @@ /* HS USB Host PHY on PORT 1 */ hsusb1_phy: hsusb1_phy { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb1_rst_pins>; compatible = "usb-nop-xceiv"; reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; /* gpio_57 */ #phy-cells = <0>; @@ -167,7 +169,9 @@ }; &davinci_emac { - status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <ðernet_pins>; + status = "okay"; }; &davinci_mdio { @@ -192,6 +196,8 @@ }; &i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; clock-frequency = <400000>; /* User DIP swithes [1:8] / User LEDS [1:2] */ tca6416: gpio@21 { @@ -204,6 +210,8 @@ }; &i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; clock-frequency = <400000>; }; @@ -222,6 +230,8 @@ }; &usbhshost { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb1_pins>; port1-mode = "ehci-phy"; }; @@ -230,8 +240,35 @@ }; &omap3_pmx_core { - pinctrl-names = "default"; - pinctrl-0 = <&hsusb1_rst_pins>; + + ethernet_pins: pinmux_ethernet_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21fe, PIN_INPUT | MUX_MODE0) /* rmii_mdio_data */ + OMAP3_CORE1_IOPAD(0x2200, MUX_MODE0) /* rmii_mdio_clk */ + OMAP3_CORE1_IOPAD(0x2202, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_rxd0 */ + OMAP3_CORE1_IOPAD(0x2204, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_rxd1 */ + OMAP3_CORE1_IOPAD(0x2206, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_crs_dv */ + OMAP3_CORE1_IOPAD(0x2208, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_rxer */ + OMAP3_CORE1_IOPAD(0x220a, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_txd0 */ + OMAP3_CORE1_IOPAD(0x220c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_txd1 */ + OMAP3_CORE1_IOPAD(0x220e, PIN_OUTPUT_PULLDOWN |MUX_MODE0) /* rmii_txen */ + OMAP3_CORE1_IOPAD(0x2210, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_50mhz_clk */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ + OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ + OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ + >; + }; leds_pins: pinmux_leds_pins { pinctrl-single,pins = < @@ -299,8 +336,6 @@ }; &omap3_pmx_core2 { - pinctrl-names = "default"; - pinctrl-0 = <&hsusb1_pins>; hsusb1_pins: pinmux_hsusb1_pins { pinctrl-single,pins = < --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am3517-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am3517-som.dtsi @@ -69,6 +69,8 @@ }; &i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; clock-frequency = <400000>; s35390a: s35390a@30 { @@ -179,6 +181,13 @@ &omap3_pmx_core { + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ + OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ + >; + }; + wl12xx_buffer_pins: pinmux_wl12xx_buffer_pins { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4) /* mmc1_dat7.gpio_129 */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am437x-gp-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am437x-gp-evm.dts @@ -86,7 +86,7 @@ }; lcd0: display { - compatible = "osddisplays,osd057T0559-34ts", "panel-dpi"; + compatible = "osddisplays,osd070t1718-19ts", "panel-dpi"; label = "lcd"; backlight = <&lcd_bl>; @@ -829,11 +829,14 @@ status = "okay"; }; +&gpio5_target { + ti,no-reset-on-init; +}; + &gpio5 { pinctrl-names = "default"; pinctrl-0 = <&display_mux_pins>; status = "okay"; - ti,no-reset-on-init; p8 { /* --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am437x-idk-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am437x-idk-evm.dts @@ -526,11 +526,11 @@ * Supply voltage supervisor on board will not allow opp50 so * disable it and set opp100 as suspend OPP. */ - opp50@300000000 { + opp50-300000000 { status = "disabled"; }; - opp100@600000000 { + opp100-600000000 { opp-suspend; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am437x-l4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am437x-l4.dtsi @@ -1576,8 +1576,9 @@ reg-names = "rev"; ti,hwmods = "d_can0"; /* Domains (P, C): per_pwrdm, l4ls_clkdm */ - clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>; - clock-names = "fck"; + clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>, + <&dcan0_fck>; + clock-names = "fck", "osc"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xcc000 0x2000>; @@ -1585,6 +1586,8 @@ dcan0: can@0 { compatible = "ti,am4372-d_can", "ti,am3352-d_can"; reg = <0x0 0x2000>; + clocks = <&dcan0_fck>; + clock-names = "fck"; syscon-raminit = <&scm_conf 0x644 0>; interrupts = ; status = "disabled"; @@ -1597,8 +1600,9 @@ reg-names = "rev"; ti,hwmods = "d_can1"; /* Domains (P, C): per_pwrdm, l4ls_clkdm */ - clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>; - clock-names = "fck"; + clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>, + <&dcan1_fck>; + clock-names = "fck", "osc"; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xd0000 0x2000>; @@ -1606,6 +1610,8 @@ dcan1: can@0 { compatible = "ti,am4372-d_can", "ti,am3352-d_can"; reg = <0x0 0x2000>; + clocks = <&dcan1_fck>; + clock-names = "fck"; syscon-raminit = <&scm_conf 0x644 1>; interrupts = ; status = "disabled"; @@ -2071,7 +2077,7 @@ }; }; - target-module@22000 { /* 0x48322000, ap 116 64.0 */ + gpio5_target: target-module@22000 { /* 0x48322000, ap 116 64.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; ti,hwmods = "gpio6"; reg = <0x22000 0x4>, --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am43x-epos-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am43x-epos-evm.dts @@ -42,7 +42,7 @@ }; lcd0: display { - compatible = "osddisplays,osd057T0559-34ts", "panel-dpi"; + compatible = "osddisplays,osd070t1718-19ts", "panel-dpi"; label = "lcd"; backlight = <&lcd_bl>; @@ -589,7 +589,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; - clock-frequency = <400000>; + clock-frequency = <100000>; tps65218: tps65218@24 { reg = <0x24>; @@ -848,6 +848,7 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&spi0_pins_default>; pinctrl-1 = <&spi0_pins_sleep>; + ti,pindir-d0-out-d1-in; }; &spi1 { @@ -855,6 +856,7 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&spi1_pins_default>; pinctrl-1 = <&spi1_pins_sleep>; + ti,pindir-d0-out-d1-in; }; &usb2_phy1 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am43xx-clocks.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am43xx-clocks.dtsi @@ -704,6 +704,60 @@ ti,bit-shift = <8>; reg = <0x2a48>; }; + + clkout1_osc_div_ck: clkout1-osc-div-ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&sys_clkin_ck>; + ti,bit-shift = <20>; + ti,max-div = <4>; + reg = <0x4100>; + }; + + clkout1_src2_mux_ck: clkout1-src2-mux-ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clk_rc32k_ck>, <&sysclk_div>, <&dpll_ddr_m2_ck>, + <&dpll_per_m2_ck>, <&dpll_disp_m2_ck>, + <&dpll_mpu_m2_ck>; + reg = <0x4100>; + }; + + clkout1_src2_pre_div_ck: clkout1-src2-pre-div-ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout1_src2_mux_ck>; + ti,bit-shift = <4>; + ti,max-div = <8>; + reg = <0x4100>; + }; + + clkout1_src2_post_div_ck: clkout1-src2-post-div-ck { + #clock-cells = <0>; + compatible = "ti,divider-clock"; + clocks = <&clkout1_src2_pre_div_ck>; + ti,bit-shift = <8>; + ti,max-div = <32>; + ti,index-power-of-two; + reg = <0x4100>; + }; + + clkout1_mux_ck: clkout1-mux-ck { + #clock-cells = <0>; + compatible = "ti,mux-clock"; + clocks = <&clkout1_osc_div_ck>, <&clk_rc32k_ck>, + <&clkout1_src2_post_div_ck>, <&dpll_extdev_m2_ck>; + ti,bit-shift = <16>; + reg = <0x4100>; + }; + + clkout1_ck: clkout1-ck { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&clkout1_mux_ck>; + ti,bit-shift = <23>; + reg = <0x4100>; + }; }; &prcm { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am571x-idk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am571x-idk.dts @@ -167,11 +167,7 @@ &pcie1_rc { status = "okay"; - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; -}; - -&pcie1_ep { - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; + gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>; }; &mmc1 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am572x-idk-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am572x-idk-common.dtsi @@ -147,10 +147,6 @@ gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; }; -&pcie1_ep { - gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; -}; - &mailbox5 { status = "okay"; mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi @@ -29,6 +29,27 @@ reg = <0x0 0x80000000 0x0 0x80000000>; }; + main_12v0: fixedregulator-main_12v0 { + /* main supply */ + compatible = "regulator-fixed"; + regulator-name = "main_12v0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + regulator-always-on; + regulator-boot-on; + }; + + evm_5v0: fixedregulator-evm_5v0 { + /* Output of TPS54531D */ + compatible = "regulator-fixed"; + regulator-name = "evm_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&main_12v0>; + regulator-always-on; + regulator-boot-on; + }; + vdd_3v3: fixedregulator-vdd_3v3 { compatible = "regulator-fixed"; regulator-name = "vdd_3v3"; @@ -547,10 +568,6 @@ gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; }; -&pcie1_ep { - gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; -}; - &mcasp3 { #sound-dai-cells = <0>; assigned-clocks = <&l4per2_clkctrl DRA7_L4PER2_MCASP3_CLKCTRL 24>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -527,7 +527,7 @@ interrupt-parent = <&gpio1>; interrupts = <31 0>; - pendown-gpio = <&gpio1 31 0>; + pendown-gpio = <&gpio1 31 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; @@ -611,12 +611,11 @@ >; }; -&gpio3 { - status = "okay"; +&gpio3_target { ti,no-reset-on-init; }; -&gpio2 { +&gpio2_target { status = "okay"; ti,no-reset-on-init; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/arm-realview-pb1176.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/arm-realview-pb1176.dts @@ -435,7 +435,7 @@ /* Direct-mapped development chip ROM */ pb1176_rom@10200000 { - compatible = "direct-mapped"; + compatible = "mtd-rom"; reg = <0x10200000 0x4000>; bank-width = <1>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-370.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-370.dtsi @@ -74,7 +74,7 @@ pcie2: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-375.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-375.dtsi @@ -584,7 +584,7 @@ pcie1: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-380.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-380.dtsi @@ -79,7 +79,7 @@ /* x1 port */ pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -98,7 +98,7 @@ /* x1 port */ pcie@3,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; reg = <0x1800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-385-turris-omnia.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-385-turris-omnia.dts @@ -22,6 +22,12 @@ stdout-path = &uart0; }; + aliases { + ethernet0 = ð0; + ethernet1 = ð1; + ethernet2 = ð2; + }; + memory { device_type = "memory"; reg = <0x00000000 0x40000000>; /* 1024 MB */ @@ -236,6 +242,7 @@ status = "okay"; compatible = "ethernet-phy-id0141.0DD1", "ethernet-phy-ieee802.3-c22"; reg = <1>; + marvell,reg-init = <3 18 0 0x4985>; /* irq is connected to &pcawan pin 7 */ }; @@ -290,7 +297,17 @@ }; }; - /* port 6 is connected to eth0 */ + ports@6 { + reg = <6>; + label = "cpu"; + ethernet = <ð0>; + phy-mode = "rgmii-id"; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; }; }; }; @@ -306,7 +323,7 @@ marvell,function = "spi0"; }; - spi0cs1_pins: spi0cs1-pins { + spi0cs2_pins: spi0cs2-pins { marvell,pins = "mpp26"; marvell,function = "spi0"; }; @@ -341,7 +358,7 @@ }; }; - /* MISO, MOSI, SCLK and CS1 are routed to pin header CN11 */ + /* MISO, MOSI, SCLK and CS2 are routed to pin header CN11 */ }; &uart0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-385.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-385.dtsi @@ -84,7 +84,7 @@ /* x1 port */ pcie2: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -103,7 +103,7 @@ /* x1 port */ pcie3: pcie@3,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; reg = <0x1800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -125,7 +125,7 @@ */ pcie4: pcie@4,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; reg = <0x2000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-388-helios4.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-388-helios4.dts @@ -70,6 +70,9 @@ system-leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&helios_system_led_pins>; + status-led { label = "helios4:green:status"; gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; @@ -86,6 +89,9 @@ io-leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&helios_io_led_pins>; + sata1-led { label = "helios4:green:ata1"; gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; @@ -121,11 +127,15 @@ fan1: j10-pwm { compatible = "pwm-fan"; pwms = <&gpio1 9 40000>; /* Target freq:25 kHz */ + pinctrl-names = "default"; + pinctrl-0 = <&helios_fan1_pins>; }; fan2: j17-pwm { compatible = "pwm-fan"; pwms = <&gpio1 23 40000>; /* Target freq:25 kHz */ + pinctrl-names = "default"; + pinctrl-0 = <&helios_fan2_pins>; }; usb2_phy: usb2-phy { @@ -291,16 +301,22 @@ "mpp39", "mpp40"; marvell,function = "sd0"; }; - helios_led_pins: helios-led-pins { - marvell,pins = "mpp24", "mpp25", - "mpp49", "mpp50", + helios_system_led_pins: helios-system-led-pins { + marvell,pins = "mpp24", "mpp25"; + marvell,function = "gpio"; + }; + helios_io_led_pins: helios-io-led-pins { + marvell,pins = "mpp49", "mpp50", "mpp52", "mpp53", "mpp54"; marvell,function = "gpio"; }; - helios_fan_pins: helios-fan-pins { - marvell,pins = "mpp41", "mpp43", - "mpp48", "mpp55"; + helios_fan1_pins: helios_fan1_pins { + marvell,pins = "mpp41", "mpp43"; + marvell,function = "gpio"; + }; + helios_fan2_pins: helios_fan2_pins { + marvell,pins = "mpp48", "mpp55"; marvell,function = "gpio"; }; microsom_spi1_cs_pins: spi1-cs-pins { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-38x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-38x.dtsi @@ -165,7 +165,7 @@ }; uart0: serial@12000 { - compatible = "marvell,armada-38x-uart"; + compatible = "marvell,armada-38x-uart", "ns16550a"; reg = <0x12000 0x100>; reg-shift = <2>; interrupts = ; @@ -175,7 +175,7 @@ }; uart1: serial@12100 { - compatible = "marvell,armada-38x-uart"; + compatible = "marvell,armada-38x-uart", "ns16550a"; reg = <0x12100 0x100>; reg-shift = <2>; interrupts = ; @@ -339,7 +339,8 @@ comphy: phy@18300 { compatible = "marvell,armada-380-comphy"; - reg = <0x18300 0x100>; + reg-names = "comphy", "conf"; + reg = <0x18300 0x100>, <0x18460 4>; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-39x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-39x.dtsi @@ -457,7 +457,7 @@ /* x1 port */ pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x40000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x40000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -476,7 +476,7 @@ /* x1 port */ pcie@3,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001800 0 0x44000 0 0x2000>; reg = <0x1800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -498,7 +498,7 @@ */ pcie@4,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + assigned-addresses = <0x82002000 0 0x48000 0 0x2000>; reg = <0x2000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-xp-98dx3236.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-xp-98dx3236.dtsi @@ -266,11 +266,6 @@ reg = <0x11000 0x100>; }; -&i2c1 { - compatible = "marvell,mv78230-i2c", "marvell,mv64xxx-i2c"; - reg = <0x11100 0x100>; -}; - &mpic { reg = <0x20a00 0x2d0>, <0x21070 0x58>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-xp-mv78230.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-xp-mv78230.dtsi @@ -97,7 +97,7 @@ pcie2: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -115,7 +115,7 @@ pcie3: pcie@3,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; reg = <0x1800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -133,7 +133,7 @@ pcie4: pcie@4,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; + assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; reg = <0x2000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -151,7 +151,7 @@ pcie5: pcie@5,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; + assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; reg = <0x2800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/armada-xp-mv78260.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/armada-xp-mv78260.dtsi @@ -112,7 +112,7 @@ pcie2: pcie@2,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x44000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x44000 0 0x2000>; reg = <0x1000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -130,7 +130,7 @@ pcie3: pcie@3,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x48000 0 0x2000>; + assigned-addresses = <0x82001800 0 0x48000 0 0x2000>; reg = <0x1800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -148,7 +148,7 @@ pcie4: pcie@4,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x4c000 0 0x2000>; + assigned-addresses = <0x82002000 0 0x4c000 0 0x2000>; reg = <0x2000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -166,7 +166,7 @@ pcie5: pcie@5,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x80000 0 0x2000>; + assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; reg = <0x2800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -184,7 +184,7 @@ pcie6: pcie@6,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x84000 0 0x2000>; + assigned-addresses = <0x82003000 0 0x84000 0 0x2000>; reg = <0x3000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -202,7 +202,7 @@ pcie7: pcie@7,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x88000 0 0x2000>; + assigned-addresses = <0x82003800 0 0x88000 0 0x2000>; reg = <0x3800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -220,7 +220,7 @@ pcie8: pcie@8,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>; + assigned-addresses = <0x82004000 0 0x8c000 0 0x2000>; reg = <0x4000 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; @@ -238,7 +238,7 @@ pcie9: pcie@9,0 { device_type = "pci"; - assigned-addresses = <0x82000800 0 0x42000 0 0x2000>; + assigned-addresses = <0x82004800 0 0x42000 0 0x2000>; reg = <0x4800 0 0 0 0>; #address-cells = <3>; #size-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-ast2500-evb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-ast2500-evb.dts @@ -5,7 +5,7 @@ / { model = "AST2500 EVB"; - compatible = "aspeed,ast2500"; + compatible = "aspeed,ast2500-evb", "aspeed,ast2500"; aliases { serial4 = &uart5; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-ast2600-evb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-ast2600-evb.dts @@ -7,7 +7,7 @@ / { model = "AST2600 EVB"; - compatible = "aspeed,ast2600"; + compatible = "aspeed,ast2600-evb-a1", "aspeed,ast2600"; aliases { serial4 = &uart5; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts @@ -81,11 +81,6 @@ status = "okay"; }; -&vuart { - // VUART Host Console - status = "okay"; -}; - &uart1 { // Host Console status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-bmc-intel-s2600wf.dts @@ -22,9 +22,9 @@ #size-cells = <1>; ranges; - vga_memory: framebuffer@7f000000 { + vga_memory: framebuffer@9f000000 { no-map; - reg = <0x7f000000 0x01000000>; + reg = <0x9f000000 0x01000000>; /* 16M */ }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-g4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-g4.dtsi @@ -371,6 +371,7 @@ compatible = "aspeed,ast2400-ibt-bmc"; reg = <0xc0 0x18>; interrupts = <8>; + clocks = <&syscon ASPEED_CLK_GATE_LCLK>; status = "disabled"; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-g5.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-g5.dtsi @@ -464,6 +464,7 @@ compatible = "aspeed,ast2500-ibt-bmc"; reg = <0xc0 0x18>; interrupts = <8>; + clocks = <&syscon ASPEED_CLK_GATE_LCLK>; status = "disabled"; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/aspeed-g6-pinctrl.dtsi @@ -117,11 +117,6 @@ groups = "FWSPID"; }; - pinctrl_fwqspid_default: fwqspid_default { - function = "FWQSPID"; - groups = "FWQSPID"; - }; - pinctrl_fwspiwp_default: fwspiwp_default { function = "FWSPIWP"; groups = "FWSPIWP"; @@ -208,12 +203,12 @@ }; pinctrl_hvi3c3_default: hvi3c3_default { - function = "HVI3C3"; + function = "I3C3"; groups = "HVI3C3"; }; pinctrl_hvi3c4_default: hvi3c4_default { - function = "HVI3C4"; + function = "I3C4"; groups = "HVI3C4"; }; @@ -653,12 +648,12 @@ }; pinctrl_qspi1_default: qspi1_default { - function = "QSPI1"; + function = "SPI1"; groups = "QSPI1"; }; pinctrl_qspi2_default: qspi2_default { - function = "QSPI2"; + function = "SPI2"; groups = "QSPI2"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-sama5d27_som1.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-sama5d27_som1.dtsi @@ -44,8 +44,8 @@ pinctrl-0 = <&pinctrl_macb0_default>; phy-mode = "rmii"; - ethernet-phy@0 { - reg = <0x0>; + ethernet-phy@7 { + reg = <0x7>; interrupt-parent = <&pioA>; interrupts = ; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-sama5d27_som1_ek.dts @@ -69,7 +69,6 @@ isc: isc@f0008000 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_isc_base &pinctrl_isc_data_8bit &pinctrl_isc_data_9_10 &pinctrl_isc_data_11_12>; - status = "okay"; }; qspi1: spi@f0024000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-sama5d2_ptc_ek.dts @@ -40,7 +40,7 @@ ahb { usb0: gadget@300000 { - atmel,vbus-gpio = <&pioA PIN_PA27 GPIO_ACTIVE_HIGH>; + atmel,vbus-gpio = <&pioA PIN_PB11 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usba_vbus>; status = "okay"; @@ -125,8 +125,6 @@ bus-width = <8>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sdmmc0_default>; - non-removable; - mmc-ddr-1_8v; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -242,6 +242,11 @@ atmel,pins = ; /* PE9, conflicts with A9 */ }; + pinctrl_usb_default: usb_default { + atmel,pins = + ; + }; }; }; }; @@ -259,6 +264,8 @@ &pioE 3 GPIO_ACTIVE_LOW &pioE 4 GPIO_ACTIVE_LOW >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -133,6 +133,11 @@ atmel,pins = ; }; + pinctrl_usb_default: usb_default { + atmel,pins = + ; + }; pinctrl_key_gpio: key_gpio_0 { atmel,pins = ; @@ -158,6 +163,8 @@ &pioE 11 GPIO_ACTIVE_HIGH &pioE 14 GPIO_ACTIVE_HIGH >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91-tse850-3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91-tse850-3.dts @@ -262,7 +262,7 @@ &macb1 { status = "okay"; - phy-mode = "rgmii"; + phy-mode = "rmii"; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9260.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9260.dtsi @@ -187,7 +187,7 @@ usart0 { pinctrl_usart0: usart0-0 { atmel,pins = - ; }; @@ -221,7 +221,7 @@ usart1 { pinctrl_usart1: usart1-0 { atmel,pins = - ; }; @@ -239,7 +239,7 @@ usart2 { pinctrl_usart2: usart2-0 { atmel,pins = - ; }; @@ -257,7 +257,7 @@ usart3 { pinctrl_usart3: usart3-0 { atmel,pins = - ; }; @@ -275,7 +275,7 @@ uart0 { pinctrl_uart0: uart0-0 { atmel,pins = - ; }; }; @@ -283,7 +283,7 @@ uart1 { pinctrl_uart1: uart1-0 { atmel,pins = - ; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9261.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9261.dtsi @@ -329,7 +329,7 @@ usart0 { pinctrl_usart0: usart0-0 { atmel,pins = - , + , ; }; @@ -347,7 +347,7 @@ usart1 { pinctrl_usart1: usart1-0 { atmel,pins = - , + , ; }; @@ -365,7 +365,7 @@ usart2 { pinctrl_usart2: usart2-0 { atmel,pins = - , + , ; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9261ek.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9261ek.dts @@ -156,7 +156,7 @@ compatible = "ti,ads7843"; interrupts-extended = <&pioC 2 IRQ_TYPE_EDGE_BOTH>; spi-max-frequency = <3000000>; - pendown-gpio = <&pioC 2 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&pioC 2 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <150>; ti,x-max = /bits/ 16 <3830>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9263.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9263.dtsi @@ -183,7 +183,7 @@ usart0 { pinctrl_usart0: usart0-0 { atmel,pins = - ; }; @@ -201,7 +201,7 @@ usart1 { pinctrl_usart1: usart1-0 { atmel,pins = - ; }; @@ -219,7 +219,7 @@ usart2 { pinctrl_usart2: usart2-0 { atmel,pins = - ; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9g20ek_common.dtsi @@ -38,6 +38,13 @@ }; + usb1 { + pinctrl_usb1_vbus_gpio: usb1_vbus_gpio { + atmel,pins = + ; /* PC5 GPIO */ + }; + }; + mmc0_slot1 { pinctrl_board_mmc0_slot1: mmc0_slot1-board { atmel,pins = @@ -83,6 +90,8 @@ }; usb1: gadget@fffa4000 { + pinctrl-0 = <&pinctrl_usb1_vbus_gpio>; + pinctrl-names = "default"; atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; @@ -217,6 +226,12 @@ wm8731: wm8731@1b { compatible = "wm8731"; reg = <0x1b>; + + /* PCK0 at 12MHz */ + clocks = <&pmc PMC_TYPE_SYSTEM 8>; + clock-names = "mclk"; + assigned-clocks = <&pmc PMC_TYPE_SYSTEM 8>; + assigned-clock-rates = <12000000>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9g45.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9g45.dtsi @@ -556,7 +556,7 @@ usart0 { pinctrl_usart0: usart0-0 { atmel,pins = - ; }; @@ -574,7 +574,7 @@ usart1 { pinctrl_usart1: usart1-0 { atmel,pins = - ; }; @@ -592,7 +592,7 @@ usart2 { pinctrl_usart2: usart2-0 { atmel,pins = - ; }; @@ -610,7 +610,7 @@ usart3 { pinctrl_usart3: usart3-0 { atmel,pins = - ; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/at91sam9rl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/at91sam9rl.dtsi @@ -278,23 +278,26 @@ atmel,adc-use-res = "highres"; trigger0 { - trigger-name = "timer-counter-0"; + trigger-name = "external-rising"; trigger-value = <0x1>; + trigger-external; }; + trigger1 { - trigger-name = "timer-counter-1"; - trigger-value = <0x3>; + trigger-name = "external-falling"; + trigger-value = <0x2>; + trigger-external; }; trigger2 { - trigger-name = "timer-counter-2"; - trigger-value = <0x5>; + trigger-name = "external-any"; + trigger-value = <0x3>; + trigger-external; }; trigger3 { - trigger-name = "external"; - trigger-value = <0x13>; - trigger-external; + trigger-name = "continuous"; + trigger-value = <0x6>; }; }; @@ -682,7 +685,7 @@ usart0 { pinctrl_usart0: usart0-0 { atmel,pins = - , + , ; }; @@ -721,7 +724,7 @@ usart1 { pinctrl_usart1: usart1-0 { atmel,pins = - , + , ; }; @@ -744,7 +747,7 @@ usart2 { pinctrl_usart2: usart2-0 { atmel,pins = - , + , ; }; @@ -767,7 +770,7 @@ usart3 { pinctrl_usart3: usart3-0 { atmel,pins = - , + , ; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm-cygnus.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -174,8 +174,8 @@ mdio: mdio@18002000 { compatible = "brcm,iproc-mdio"; reg = <0x18002000 0x8>; - #size-cells = <1>; - #address-cells = <0>; + #size-cells = <0>; + #address-cells = <1>; status = "disabled"; gphy0: ethernet-phy@0 { @@ -460,7 +460,7 @@ status = "disabled"; }; - nand: nand@18046000 { + nand_controller: nand-controller@18046000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x18046000 0x600>, <0xf8105408 0x600>, <0x18046f00 0x20>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm-hr2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm-hr2.dtsi @@ -75,7 +75,7 @@ timer@20200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x20200 0x100>; - interrupts = ; + interrupts = ; clocks = <&periph_clk>; }; @@ -83,7 +83,7 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x20600 0x20>; interrupts = ; + IRQ_TYPE_EDGE_RISING)>; clocks = <&periph_clk>; }; @@ -91,7 +91,7 @@ compatible = "arm,cortex-a9-twd-wdt"; reg = <0x20620 0x20>; interrupts = ; + IRQ_TYPE_EDGE_RISING)>; clocks = <&periph_clk>; }; @@ -179,7 +179,7 @@ status = "disabled"; }; - nand: nand@26000 { + nand_controller: nand-controller@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x26000 0x600>, <0x11b408 0x600>, @@ -217,7 +217,7 @@ }; qspi: spi@27200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x027200 0x184>, <0x027000 0x124>, <0x11c408 0x004>, --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm-nsp.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm-nsp.dtsi @@ -77,7 +77,7 @@ interrupt-affinity = <&cpu0>, <&cpu1>; }; - mpcore@19000000 { + mpcore-bus@19000000 { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x00023000>; #address-cells = <1>; @@ -217,7 +217,7 @@ #dma-cells = <1>; }; - sdio: sdhci@21000 { + sdio: mmc@21000 { compatible = "brcm,sdhci-iproc-cygnus"; reg = <0x21000 0x100>; interrupts = ; @@ -257,17 +257,17 @@ status = "disabled"; }; - mailbox: mailbox@25000 { + mailbox: mailbox@25c00 { compatible = "brcm,iproc-fa2-mbox"; - reg = <0x25000 0x445>; - interrupts = ; + reg = <0x25c00 0x400>; + interrupts = ; #mbox-cells = <1>; brcm,rx-status-len = <32>; brcm,use-bcm-hdr; dma-coherent; }; - nand: nand@26000 { + nand_controller: nand-controller@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x026000 0x600>, <0x11b408 0x600>, @@ -282,7 +282,7 @@ }; qspi: spi@27200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x027200 0x184>, <0x027000 0x124>, <0x11c408 0x004>, --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -53,18 +53,17 @@ "GPIO18", "NC", /* GPIO19 */ "NC", /* GPIO20 */ - "GPIO21", + "CAM_GPIO0", "GPIO22", "GPIO23", "GPIO24", "GPIO25", "NC", /* GPIO26 */ - "CAM_GPIO0", - /* Binary number representing build/revision */ - "CONFIG0", - "CONFIG1", - "CONFIG2", - "CONFIG3", + "GPIO27", + "GPIO28", + "GPIO29", + "GPIO30", + "GPIO31", "NC", /* GPIO32 */ "NC", /* GPIO33 */ "NC", /* GPIO34 */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -24,7 +24,7 @@ leds { act { - gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; + gpios = <&gpio 47 GPIO_ACTIVE_LOW>; }; }; @@ -74,16 +74,18 @@ "GPIO27", "SDA0", "SCL0", - "NC", /* GPIO30 */ - "NC", /* GPIO31 */ - "NC", /* GPIO32 */ - "NC", /* GPIO33 */ - "NC", /* GPIO34 */ - "NC", /* GPIO35 */ - "NC", /* GPIO36 */ - "NC", /* GPIO37 */ - "NC", /* GPIO38 */ - "NC", /* GPIO39 */ + /* Used by BT module */ + "CTS0", + "RTS0", + "TXD0", + "RXD0", + /* Used by Wifi */ + "SD1_CLK", + "SD1_CMD", + "SD1_DATA0", + "SD1_DATA1", + "SD1_DATA2", + "SD1_DATA3", "CAM_GPIO1", /* GPIO40 */ "WL_ON", /* GPIO41 */ "NC", /* GPIO42 */ @@ -112,6 +114,7 @@ &sdhci { #address-cells = <1>; #size-cells = <0>; + pinctrl-names = "default"; pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>; bus-width = <4>; mmc-pwrseq = <&wifi_pwrseq>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts @@ -43,7 +43,7 @@ #gpio-cells = <2>; gpio-line-names = "BT_ON", "WL_ON", - "STATUS_LED_R", + "PWR_LED_R", "LAN_RUN", "", "CAM_GPIO0", --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts @@ -63,8 +63,8 @@ "GPIO43", "GPIO44", "GPIO45", - "GPIO46", - "GPIO47", + "SMPS_SCL", + "SMPS_SDA", /* Used by eMMC */ "SD_CLK_R", "SD_CMD_R", @@ -77,7 +77,7 @@ }; &hdmi { - hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; + hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; power-domains = <&power RPI_POWER_DOMAIN_HDMI>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm2837.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm2837.dtsi @@ -38,12 +38,26 @@ #size-cells = <0>; enable-method = "brcm,bcm2836-smp"; // for ARM 32-bit + /* Source for d/i-cache-line-size and d/i-cache-sets + * https://developer.arm.com/documentation/ddi0500/e/level-1-memory-system + * /about-the-l1-memory-system?lang=en + * + * Source for d/i-cache-size + * https://magpi.raspberrypi.com/articles/raspberry-pi-3-specs-benchmarks + */ cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a53"; reg = <0>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000d8>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set + next-level-cache = <&l2>; }; cpu1: cpu@1 { @@ -52,6 +66,13 @@ reg = <1>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000e0>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set + next-level-cache = <&l2>; }; cpu2: cpu@2 { @@ -60,6 +81,13 @@ reg = <2>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000e8>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set + next-level-cache = <&l2>; }; cpu3: cpu@3 { @@ -68,6 +96,27 @@ reg = <3>; enable-method = "spin-table"; cpu-release-addr = <0x0 0x000000f0>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <128>; // 32KiB(size)/64(line-size)=512ways/4-way set + i-cache-size = <0x8000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; // 32KiB(size)/64(line-size)=512ways/2-way set + next-level-cache = <&l2>; + }; + + /* Source for cache-line-size + cache-sets + * https://developer.arm.com/documentation/ddi0500 + * /e/level-2-memory-system/about-the-l2-memory-system?lang=en + * Source for cache-size + * https://datasheets.raspberrypi.com/cm/cm1-and-cm3-datasheet.pdf + */ + l2: l2-cache0 { + compatible = "cache"; + cache-size = <0x80000>; + cache-line-size = <64>; + cache-sets = <512>; // 512KiB(size)/64(line-size)=8192ways/16-way set + cache-level = <2>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm283x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm283x.dtsi @@ -40,7 +40,7 @@ trips { cpu-crit { - temperature = <80000>; + temperature = <90000>; hysteresis = <0>; type = "critical"; }; @@ -183,6 +183,7 @@ interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&gpio 0 0 54>; /* Defines pin muxing groups according to * BCM2835-ARM-Peripherals.pdf page 102. @@ -488,6 +489,7 @@ "dsi0_ddr2", "dsi0_ddr"; + status = "disabled"; }; thermal: thermal@7e212000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts @@ -19,7 +19,8 @@ memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; }; gpio-keys { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts @@ -26,7 +26,6 @@ wlan { label = "bcm53xx:blue:wlan"; gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>; - linux,default-trigger = "default-off"; }; system { @@ -46,3 +45,16 @@ }; }; }; + +&gmac0 { + phy-mode = "rgmii"; + phy-handle = <&bcm54210e>; + + mdio { + /delete-node/ switch@1e; + + bcm54210e: ethernet-phy@0 { + reg = <0>; + }; + }; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts @@ -26,7 +26,6 @@ 5ghz { label = "bcm53xx:blue:5ghz"; gpios = <&chipcommon 11 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; system { @@ -42,7 +41,6 @@ 2ghz { label = "bcm53xx:blue:2ghz"; gpios = <&pcie0_chipcommon 3 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-off"; }; }; @@ -83,3 +81,16 @@ }; }; }; + +&gmac0 { + phy-mode = "rgmii"; + phy-handle = <&bcm54210e>; + + mdio { + /delete-node/ switch@1e; + + bcm54210e: ethernet-phy@0 { + reg = <0>; + }; + }; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm5301x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm5301x.dtsi @@ -242,6 +242,8 @@ gpio-controller; #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; }; pcie0: pcie@12000 { @@ -353,8 +355,8 @@ mdio: mdio@18003000 { compatible = "brcm,iproc-mdio"; reg = <0x18003000 0x8>; - #size-cells = <1>; - #address-cells = <0>; + #size-cells = <0>; + #address-cells = <1>; }; mdio-bus-mux@18003000 { @@ -387,7 +389,7 @@ i2c0: i2c@18009000 { compatible = "brcm,iproc-i2c"; reg = <0x18009000 0x50>; - interrupts = ; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clock-frequency = <100000>; @@ -488,33 +490,32 @@ }; spi@18029200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-nsp-qspi"; + compatible = "brcm,spi-nsp-qspi", "brcm,spi-bcm-qspi"; reg = <0x18029200 0x184>, <0x18029000 0x124>, <0x1811b408 0x004>, <0x180293a0 0x01c>; reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; - interrupts = , + interrupts = , + , + , , , , - , - , - ; - interrupt-names = "spi_lr_fullness_reached", + ; + interrupt-names = "mspi_done", + "mspi_halted", + "spi_lr_fullness_reached", "spi_lr_session_aborted", "spi_lr_impatient", "spi_lr_session_done", - "spi_lr_overhead", - "mspi_done", - "mspi_halted"; + "spi_lr_overread"; clocks = <&iprocmed>; - clock-names = "iprocmed"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>; - spi_nor: spi-nor@0 { + spi_nor: flash@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm53573.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm53573.dtsi @@ -127,6 +127,9 @@ pcie0: pcie@2000 { reg = <0x00002000 0x1000>; + + #address-cells = <3>; + #size-cells = <2>; }; usb2: usb2@4000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm63138.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm63138.dtsi @@ -203,7 +203,7 @@ status = "disabled"; }; - nand: nand@2000 { + nand_controller: nand-controller@2000 { #address-cells = <1>; #size-cells = <0>; compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.0", "brcm,brcmnand"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts @@ -14,10 +14,10 @@ }; }; -&nand { +&nand_controller { status = "okay"; - nandcs@1 { + nand@1 { compatible = "brcm,nandcs"; reg = <1>; nand-ecc-step-size = <512>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm7445.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm7445.dtsi @@ -148,7 +148,7 @@ reg-names = "aon-ctrl", "aon-sram"; }; - nand: nand@3e2800 { + nand_controller: nand-controller@3e2800 { status = "disabled"; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm911360_entphn.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm911360_entphn.dts @@ -82,8 +82,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm947189acdbmr.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm947189acdbmr.dts @@ -60,9 +60,9 @@ spi { compatible = "spi-gpio"; num-chipselects = <1>; - gpio-sck = <&chipcommon 21 0>; - gpio-miso = <&chipcommon 22 0>; - gpio-mosi = <&chipcommon 23 0>; + sck-gpios = <&chipcommon 21 0>; + miso-gpios = <&chipcommon 22 0>; + mosi-gpios = <&chipcommon 23 0>; cs-gpios = <&chipcommon 24 0>; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958300k.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958300k.dts @@ -60,8 +60,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958305k.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958305k.dts @@ -68,8 +68,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958522er.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958522er.dts @@ -70,8 +70,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958525er.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958525er.dts @@ -70,8 +70,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958525xmc.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958525xmc.dts @@ -86,8 +86,8 @@ }; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958622hr.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958622hr.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958623hr.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958623hr.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958625hr.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958625hr.dts @@ -90,8 +90,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm958625k.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm958625k.dts @@ -64,8 +64,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm963138dvt.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm963138dvt.dts @@ -31,10 +31,10 @@ status = "okay"; }; -&nand { +&nand_controller { status = "okay"; - nandcs@0 { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-ecc-strength = <4>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/bcm988312hr.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/bcm988312hr.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dm8148-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/dm8148-evm.dts @@ -24,12 +24,12 @@ &cpsw_emac0 { phy-handle = <ðphy0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &cpsw_emac1 { phy-handle = <ðphy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &davinci_mdio { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dm8148-t410.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/dm8148-t410.dts @@ -33,12 +33,12 @@ &cpsw_emac0 { phy-handle = <ðphy0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &cpsw_emac1 { phy-handle = <ðphy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &davinci_mdio { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dove.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/dove.dtsi @@ -129,7 +129,7 @@ pcie1: pcie@2 { device_type = "pci"; status = "disabled"; - assigned-addresses = <0x82002800 0 0x80000 0 0x2000>; + assigned-addresses = <0x82001000 0 0x80000 0 0x2000>; reg = <0x1000 0 0 0 0>; clocks = <&gate_clk 5>; marvell,pcie-port = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dra62x-j5eco-evm.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/dra62x-j5eco-evm.dts @@ -24,12 +24,12 @@ &cpsw_emac0 { phy-handle = <ðphy0>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &cpsw_emac1 { phy-handle = <ðphy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; }; &davinci_mdio { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dra7-l4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/dra7-l4.dtsi @@ -1176,7 +1176,7 @@ }; }; - target-module@34000 { /* 0x48034000, ap 7 46.0 */ + timer3_target: target-module@34000 { /* 0x48034000, ap 7 46.0 */ compatible = "ti,sysc-omap4-timer", "ti,sysc"; ti,hwmods = "timer3"; reg = <0x34000 0x4>, @@ -1204,7 +1204,7 @@ }; }; - target-module@36000 { /* 0x48036000, ap 9 4e.0 */ + timer4_target: target-module@36000 { /* 0x48036000, ap 9 4e.0 */ compatible = "ti,sysc-omap4-timer", "ti,sysc"; ti,hwmods = "timer4"; reg = <0x36000 0x4>, @@ -1326,7 +1326,7 @@ }; }; - target-module@55000 { /* 0x48055000, ap 13 0e.0 */ + gpio2_target: target-module@55000 { /* 0x48055000, ap 13 0e.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0x55000 0x4>, <0x55010 0x4>, @@ -1359,7 +1359,7 @@ }; }; - target-module@57000 { /* 0x48057000, ap 15 06.0 */ + gpio3_target: target-module@57000 { /* 0x48057000, ap 15 06.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0x57000 0x4>, <0x57010 0x4>, @@ -3059,7 +3059,7 @@ davinci_mdio: mdio@1000 { compatible = "ti,cpsw-mdio","ti,davinci_mdio"; - clocks = <&gmac_clkctrl DRA7_GMAC_GMAC_CLKCTRL 0>; + clocks = <&gmac_main_clk>; clock-names = "fck"; #address-cells = <1>; #size-cells = <0>; @@ -3413,6 +3413,7 @@ clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER13_CLKCTRL 24>; clock-names = "fck"; interrupts = ; + ti,timer-pwm; }; }; @@ -3441,6 +3442,7 @@ clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER14_CLKCTRL 24>; clock-names = "fck"; interrupts = ; + ti,timer-pwm; }; }; @@ -3469,6 +3471,7 @@ clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>; clock-names = "fck"; interrupts = ; + ti,timer-pwm; }; }; @@ -3497,6 +3500,7 @@ clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>; clock-names = "fck"; interrupts = ; + ti,timer-pwm; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dra7.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/dra7.dtsi @@ -46,6 +46,7 @@ timer { compatible = "arm,armv7-timer"; + status = "disabled"; /* See ARM architected timer wrap erratum i940 */ interrupts = , , , @@ -148,6 +149,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x0 0x0 0xc0000000>; + dma-ranges = <0x80000000 0x0 0x80000000 0x80000000>; ti,hwmods = "l3_main_1", "l3_main_2"; reg = <0x0 0x44000000 0x0 0x1000000>, <0x0 0x45000000 0x0 0x1000>; @@ -171,6 +173,7 @@ #address-cells = <1>; ranges = <0x51000000 0x51000000 0x3000 0x0 0x20000000 0x10000000>; + dma-ranges; /** * To enable PCI endpoint mode, disable the pcie1_rc * node and enable pcie1_ep mode. @@ -228,6 +231,7 @@ #address-cells = <1>; ranges = <0x51800000 0x51800000 0x3000 0x0 0x30000000 0x10000000>; + dma-ranges; status = "disabled"; pcie2_rc: pcie@51800000 { reg = <0x51800000 0x2000>, <0x51802000 0x14c>, <0x1000 0x2000>; @@ -763,3 +767,22 @@ #include "dra7-l4.dtsi" #include "dra7xx-clocks.dtsi" + +/* Local timers, see ARM architected timer wrap erratum i940 */ +&timer3_target { + ti,no-reset-on-init; + ti,no-idle; + timer@0 { + assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>; + assigned-clock-parents = <&timer_sys_clk_div>; + }; +}; + +&timer4_target { + ti,no-reset-on-init; + ti,no-idle; + timer@0 { + assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>; + assigned-clock-parents = <&timer_sys_clk_div>; + }; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dra76x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/dra76x.dtsi @@ -32,8 +32,8 @@ interrupts = , ; interrupt-names = "int0", "int1"; - clocks = <&mcan_clk>, <&l3_iclk_div>; - clock-names = "cclk", "hclk"; + clocks = <&l3_iclk_div>, <&mcan_clk>; + clock-names = "hclk", "cclk"; bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>; }; }; @@ -86,3 +86,8 @@ &usb4_tm { status = "disabled"; }; + +&mmc3 { + /* dra76x is not affected by i887 */ + max-frequency = <96000000>; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -796,16 +796,6 @@ clock-div = <1>; }; - ipu1_gfclk_mux: ipu1_gfclk_mux@520 { - #clock-cells = <0>; - compatible = "ti,mux-clock"; - clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; - ti,bit-shift = <24>; - reg = <0x0520>; - assigned-clocks = <&ipu1_gfclk_mux>; - assigned-clock-parents = <&dpll_core_h22x2_ck>; - }; - dummy_ck: dummy_ck { #clock-cells = <0>; compatible = "fixed-clock"; @@ -1564,6 +1554,8 @@ compatible = "ti,clkctrl"; reg = <0x20 0x4>; #clock-cells = <2>; + assigned-clocks = <&ipu1_clkctrl DRA7_IPU1_MMU_IPU1_CLKCTRL 24>; + assigned-clock-parents = <&dpll_core_h22x2_ck>; }; ipu_clkctrl: ipu-clkctrl@50 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos3250-artik5.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos3250-artik5.dtsi @@ -75,7 +75,7 @@ s2mps14_pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx3>; - interrupts = <5 IRQ_TYPE_NONE>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&s2mps14_irq>; reg = <0x66>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos3250-monk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos3250-monk.dts @@ -195,7 +195,7 @@ s2mps14_pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; - interrupts = <7 IRQ_TYPE_NONE>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; reg = <0x66>; wakeup-source; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos3250-rinato.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos3250-rinato.dts @@ -239,7 +239,7 @@ i80-if-timings { cs-setup = <0>; wr-setup = <0>; - wr-act = <1>; + wr-active = <1>; wr-hold = <0>; }; }; @@ -260,7 +260,7 @@ s2mps14_pmic@66 { compatible = "samsung,s2mps14-pmic"; interrupt-parent = <&gpx0>; - interrupts = <7 IRQ_TYPE_NONE>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; reg = <0x66>; wakeup-source; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4-cpu-thermal.dtsi @@ -10,7 +10,7 @@ / { thermal-zones { cpu_thermal: cpu-thermal { - thermal-sensors = <&tmu 0>; + thermal-sensors = <&tmu>; polling-delay-passive = <0>; polling-delay = <0>; trips { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4.dtsi @@ -605,7 +605,7 @@ status = "disabled"; hdmi_i2c_phy: hdmiphy@38 { - compatible = "exynos4210-hdmiphy"; + compatible = "samsung,exynos4210-hdmiphy"; reg = <0x38>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -64,7 +64,7 @@ &keypad { samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&keypad_rows &keypad_cols>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -115,7 +115,7 @@ gpio-sck = <&gpy3 1 GPIO_ACTIVE_HIGH>; gpio-mosi = <&gpy3 3 GPIO_ACTIVE_HIGH>; num-chipselects = <1>; - cs-gpios = <&gpy4 3 GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpy4 3 GPIO_ACTIVE_LOW>; lcd@0 { compatible = "samsung,ld9040"; @@ -124,8 +124,6 @@ vci-supply = <&ldo17_reg>; reset-gpios = <&gpy4 5 GPIO_ACTIVE_HIGH>; spi-max-frequency = <1200000>; - spi-cpol; - spi-cpha; power-on-delay = <10>; reset-delay = <10>; panel-width-mm = <90>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi @@ -68,7 +68,7 @@ i2c_cm36651: i2c-gpio-2 { compatible = "i2c-gpio"; - gpios = <&gpf0 0 GPIO_ACTIVE_LOW>, <&gpf0 1 GPIO_ACTIVE_LOW>; + gpios = <&gpf0 0 GPIO_ACTIVE_HIGH>, <&gpf0 1 GPIO_ACTIVE_HIGH>; i2c-gpio,delay-us = <2>; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-itop-elite.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-itop-elite.dts @@ -179,7 +179,7 @@ compatible = "wlf,wm8960"; reg = <0x1a>; clocks = <&pmu_system_controller 0>; - clock-names = "MCLK1"; + clock-names = "mclk"; wlf,shared-lrclk; #sound-dai-cells = <0>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-midas.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-midas.dtsi @@ -139,7 +139,7 @@ max77693@66 { compatible = "maxim,max77693"; interrupt-parent = <&gpx1>; - interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&max77693_irq>; reg = <0x66>; @@ -187,7 +187,7 @@ max77693-fuel-gauge@36 { compatible = "maxim,max17047"; interrupt-parent = <&gpx2>; - interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&max77693_fuel_irq>; reg = <0x36>; @@ -534,7 +534,7 @@ clocks = <&camera 1>; clock-names = "extclk"; samsung,camclk-out = <1>; - gpios = <&gpm1 6 GPIO_ACTIVE_HIGH>; + gpios = <&gpm1 6 GPIO_ACTIVE_LOW>; port { is_s5k6a3_ep: endpoint { @@ -588,7 +588,7 @@ max77686: max77686_pmic@9 { compatible = "maxim,max77686"; interrupt-parent = <&gpx0>; - interrupts = <7 IRQ_TYPE_NONE>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&max77686_irq>; pinctrl-names = "default"; reg = <0x09>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -274,7 +274,7 @@ max77686: pmic@9 { compatible = "maxim,max77686"; interrupt-parent = <&gpx3>; - interrupts = <2 IRQ_TYPE_NONE>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&max77686_irq>; reg = <0x09>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-origen.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-origen.dts @@ -86,7 +86,7 @@ }; &ehci { - samsung,vbus-gpio = <&gpx3 5 1>; + samsung,vbus-gpio = <&gpx3 5 GPIO_ACTIVE_HIGH>; status = "okay"; phys = <&exynos_usbphy 2>, <&exynos_usbphy 3>; phy-names = "hsic0", "hsic1"; @@ -431,7 +431,7 @@ &keypad { samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <2>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -43,7 +43,7 @@ &keypad { samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <8>; - linux,keypad-no-autorepeat; + linux,input-no-autorepeat; wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5250-pinctrl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5250-pinctrl.dtsi @@ -260,7 +260,7 @@ }; uart3_data: uart3-data { - samsung,pins = "gpa1-4", "gpa1-4"; + samsung,pins = "gpa1-4", "gpa1-5"; samsung,pin-function = ; samsung,pin-pud = ; samsung,pin-drv = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -117,6 +117,9 @@ status = "okay"; ddc = <&i2c_2>; hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>; + vdd-supply = <&ldo8_reg>; + vdd_osc-supply = <&ldo10_reg>; + vdd_pll-supply = <&ldo8_reg>; }; &i2c_0 { @@ -125,7 +128,7 @@ samsung,i2c-max-bus-freq = <20000>; eeprom@50 { - compatible = "samsung,s524ad0xd1"; + compatible = "samsung,s524ad0xd1", "atmel,24c128"; reg = <0x50>; }; @@ -133,7 +136,7 @@ compatible = "maxim,max77686"; reg = <0x09>; interrupt-parent = <&gpx3>; - interrupts = <2 IRQ_TYPE_NONE>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&max77686_irq>; wakeup-source; @@ -284,7 +287,7 @@ samsung,i2c-max-bus-freq = <20000>; eeprom@51 { - compatible = "samsung,s524ad0xd1"; + compatible = "samsung,s524ad0xd1", "atmel,24c128"; reg = <0x51>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -292,7 +292,7 @@ max77686: max77686@9 { compatible = "maxim,max77686"; interrupt-parent = <&gpx3>; - interrupts = <2 IRQ_TYPE_NONE>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&max77686_irq>; wakeup-source; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5250-spring.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5250-spring.dts @@ -108,7 +108,7 @@ compatible = "samsung,s5m8767-pmic"; reg = <0x66>; interrupt-parent = <&gpx3>; - interrupts = <2 IRQ_TYPE_NONE>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&s5m8767_irq &s5m8767_dvs &s5m8767_ds>; wakeup-source; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5410-odroidxu.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5410-odroidxu.dts @@ -116,7 +116,6 @@ }; &cpu0_thermal { - thermal-sensors = <&tmu_cpu0 0>; polling-delay-passive = <0>; polling-delay = <0>; @@ -327,6 +326,8 @@ regulator-name = "vddq_lcd"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + /* Supplies also GPK and GPJ */ + regulator-always-on; }; ldo8_reg: LDO8 { @@ -637,11 +638,11 @@ }; &usbdrd_dwc3_0 { - dr_mode = "host"; + dr_mode = "peripheral"; }; &usbdrd_dwc3_1 { - dr_mode = "peripheral"; + dr_mode = "host"; }; &usbdrd3_0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5410-pinctrl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5410-pinctrl.dtsi @@ -560,6 +560,34 @@ interrupt-controller; #interrupt-cells = <2>; }; + + usb3_1_oc: usb3-1-oc { + samsung,pins = "gpk2-4", "gpk2-5"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; + + usb3_1_vbusctrl: usb3-1-vbusctrl { + samsung,pins = "gpk2-6", "gpk2-7"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; + + usb3_0_oc: usb3-0-oc { + samsung,pins = "gpk3-0", "gpk3-1"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; + + usb3_0_vbusctrl: usb3-0-vbusctrl { + samsung,pins = "gpk3-2", "gpk3-3"; + samsung,pin-function = ; + samsung,pin-pud = ; + samsung,pin-drv = ; + }; }; &pinctrl_2 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5410.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5410.dtsi @@ -398,6 +398,8 @@ &usbdrd3_0 { clocks = <&clock CLK_USBD300>; clock-names = "usbdrd30"; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_0_oc>, <&usb3_0_vbusctrl>; }; &usbdrd_phy0 { @@ -409,6 +411,8 @@ &usbdrd3_1 { clocks = <&clock CLK_USBD301>; clock-names = "usbdrd30"; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_1_oc>, <&usb3_1_vbusctrl>; }; &usbdrd_dwc3_1 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -349,7 +349,7 @@ reg = <0x66>; interrupt-parent = <&gpx3>; - interrupts = <2 IRQ_TYPE_EDGE_FALLING>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&s2mps11_irq>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -132,6 +132,9 @@ hpd-gpios = <&gpx3 7 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&hdmi_hpd_irq>; + vdd-supply = <&ldo6_reg>; + vdd_osc-supply = <&ldo7_reg>; + vdd_pll-supply = <&ldo6_reg>; }; &hsi2c_4 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5420.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5420.dtsi @@ -539,7 +539,7 @@ }; mipi_phy: mipi-video-phy { - compatible = "samsung,s5pv210-mipi-video-phy"; + compatible = "samsung,exynos5420-mipi-video-phy"; syscon = <&pmu_system_controller>; #phy-cells = <1>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5422-odroid-core.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5422-odroid-core.dtsi @@ -141,7 +141,7 @@ samsung,s2mps11-acokb-ground; interrupt-parent = <&gpx0>; - interrupts = <4 IRQ_TYPE_EDGE_FALLING>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; pinctrl-0 = <&s2mps11_irq>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5422-odroidhc1.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5422-odroidhc1.dts @@ -22,7 +22,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -24,7 +24,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi @@ -22,7 +22,7 @@ * Green LED is much brighter than the others * so limit its max brightness */ - max_brightness = <127>; + max-brightness = <127>; linux,default-trigger = "mmc0"; }; @@ -30,7 +30,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini-dlink-dns-313.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini-dlink-dns-313.dts @@ -140,7 +140,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; /* Uses MDC and MDIO */ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini-nas4220b.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini-nas4220b.dts @@ -62,7 +62,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ @@ -84,7 +84,7 @@ partitions { compatible = "redboot-fis"; /* Eraseblock at 0xfe0000 */ - fis-index-block = <0x1fc>; + fis-index-block = <0x7f>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini-rut1xx.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini-rut1xx.dts @@ -56,7 +56,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ @@ -114,18 +114,6 @@ }; ethernet@60000000 { - status = "okay"; - - ethernet-port@0 { - phy-mode = "rgmii"; - phy-handle = <&phy0>; - }; - ethernet-port@1 { - /* Not used in this platform */ - }; - }; - - ethernet@60000000 { status = "okay"; ethernet-port@0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini-wbd111.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini-wbd111.dts @@ -68,7 +68,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini-wbd222.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini-wbd222.dts @@ -67,7 +67,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/gemini.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/gemini.dtsi @@ -286,6 +286,7 @@ clock-names = "PCLK", "PCICLK"; pinctrl-names = "default"; pinctrl-0 = <&pci_default_pins>; + device_type = "pci"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx1-ads.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx1-ads.dts @@ -65,7 +65,7 @@ pinctrl-0 = <&pinctrl_weim>; status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <4>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx1-apf9328.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx1-apf9328.dts @@ -45,7 +45,7 @@ pinctrl-0 = <&pinctrl_weim>; status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx1.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx1.dtsi @@ -268,9 +268,12 @@ status = "disabled"; }; - esram: esram@300000 { + esram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x20000>; + ranges = <0 0x00300000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx23-evk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx23-evk.dts @@ -79,7 +79,6 @@ MX23_PAD_LCD_RESET__GPIO_1_18 MX23_PAD_PWM3__GPIO_1_29 MX23_PAD_PWM4__GPIO_1_30 - MX23_PAD_SSP1_DETECT__SSP1_DETECT >; fsl,drive-strength = ; fsl,voltage = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx23-sansa.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx23-sansa.dts @@ -175,10 +175,8 @@ #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - gpios = < - &gpio1 24 0 /* SDA */ - &gpio1 22 0 /* SCL */ - >; + sda-gpios = <&gpio1 24 0>; + scl-gpios = <&gpio1 22 0>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ }; @@ -186,10 +184,8 @@ #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - gpios = < - &gpio0 31 0 /* SDA */ - &gpio0 30 0 /* SCL */ - >; + sda-gpios = <&gpio0 31 0>; + scl-gpios = <&gpio0 30 0>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ touch: touch@20 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx23.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx23.dtsi @@ -59,7 +59,7 @@ reg = <0x80000000 0x2000>; }; - dma_apbh: dma-apbh@80004000 { + dma_apbh: dma-controller@80004000 { compatible = "fsl,imx23-dma-apbh"; reg = <0x80004000 0x2000>; interrupts = <0 14 20 0 @@ -406,7 +406,7 @@ status = "disabled"; }; - dma_apbx: dma-apbx@80024000 { + dma_apbx: dma-controller@80024000 { compatible = "fsl,imx23-dma-apbx"; reg = <0x80024000 0x2000>; interrupts = <7 5 9 26 --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx25-eukrea-cpuimx25.dtsi @@ -27,7 +27,7 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - pcf8563@51 { + rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&qvga_timings>; - qvga_timings: 320x240 { + qvga_timings: timing0 { clock-frequency = <6500000>; hactive = <320>; vactive = <240>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&dvi_svga_timings>; - dvi_svga_timings: 800x600 { + dvi_svga_timings: timing0 { clock-frequency = <40000000>; hactive = <800>; vactive = <600>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&dvi_vga_timings>; - dvi_vga_timings: 640x480 { + dvi_vga_timings: timing0 { clock-frequency = <31250000>; hactive = <640>; vactive = <480>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx25-pdk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx25-pdk.dts @@ -78,7 +78,7 @@ bus-width = <18>; display-timings { native-mode = <&wvga_timings>; - wvga_timings: 640x480 { + wvga_timings: timing0 { hactive = <640>; vactive = <480>; hback-porch = <45>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-apf27dev.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-apf27dev.dts @@ -16,7 +16,7 @@ fsl,pcr = <0xfae80083>; /* non-standard but required */ display-timings { native-mode = <&timing0>; - timing0: 800x480 { + timing0: timing0 { clock-frequency = <33000033>; hactive = <800>; vactive = <480>; @@ -47,7 +47,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_leds>; - user { + led-user { label = "Heartbeat"; gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-eukrea-cpuimx27.dtsi @@ -33,7 +33,7 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - pcf8563@51 { + rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; @@ -90,7 +90,7 @@ &weim { status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { #address-cells = <1>; #size-cells = <1>; compatible = "cfi-flash"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts @@ -16,7 +16,7 @@ display-timings { native-mode = <&timing0>; - timing0: 320x240 { + timing0: timing0 { clock-frequency = <6500000>; hactive = <320>; vactive = <240>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts @@ -19,7 +19,7 @@ fsl,pcr = <0xf0c88080>; /* non-standard but required */ display-timings { native-mode = <&timing0>; - timing0: 640x480 { + timing0: timing0 { hactive = <640>; vactive = <480>; hback-porch = <112>; @@ -75,8 +75,8 @@ imx27-phycard-s-rdk { pinctrl_i2c1: i2c1grp { fsl,pins = < - MX27_PAD_I2C2_SDA__I2C2_SDA 0x0 - MX27_PAD_I2C2_SCL__I2C2_SCL 0x0 + MX27_PAD_I2C_DATA__I2C_DATA 0x0 + MX27_PAD_I2C_CLK__I2C_CLK 0x0 >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts @@ -19,7 +19,7 @@ display-timings { native-mode = <&timing0>; - timing0: 240x320 { + timing0: timing0 { clock-frequency = <5500000>; hactive = <240>; vactive = <320>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27-phytec-phycore-som.dtsi @@ -322,7 +322,7 @@ &weim { status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx27.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx27.dtsi @@ -588,6 +588,9 @@ iram: iram@ffff4c00 { compatible = "mmio-sram"; reg = <0xffff4c00 0xb400>; + ranges = <0 0xffff4c00 0xb400>; + #address-cells = <1>; + #size-cells = <1>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx28.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx28.dtsi @@ -78,7 +78,7 @@ status = "disabled"; }; - dma_apbh: dma-apbh@80004000 { + dma_apbh: dma-controller@80004000 { compatible = "fsl,imx28-dma-apbh"; reg = <0x80004000 0x2000>; interrupts = <82 83 84 85 @@ -982,7 +982,7 @@ status = "disabled"; }; - dma_apbx: dma-apbx@80024000 { + dma_apbx: dma-controller@80024000 { compatible = "fsl,imx28-dma-apbx"; reg = <0x80024000 0x2000>; interrupts = <78 79 66 0 --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx35.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx35.dtsi @@ -59,7 +59,7 @@ interrupt-parent = <&avic>; ranges; - L2: l2-cache@30000000 { + L2: cache-controller@30000000 { compatible = "arm,l210-cache"; reg = <0x30000000 0x1000>; cache-unified; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx50-evk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx50-evk.dts @@ -59,7 +59,7 @@ MX50_PAD_CSPI_MISO__CSPI_MISO 0x00 MX50_PAD_CSPI_MOSI__CSPI_MOSI 0x00 MX50_PAD_CSPI_SS0__GPIO4_11 0xc4 - MX50_PAD_ECSPI1_MOSI__CSPI_SS1 0xf4 + MX50_PAD_ECSPI1_MOSI__GPIO4_13 0x84 >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx53-m53menlo.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx53-m53menlo.dts @@ -53,14 +53,40 @@ }; }; + lvds-decoder { + compatible = "ti,ds90cf364a", "lvds-decoder"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lvds_decoder_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + + port@1 { + reg = <1>; + + lvds_decoder_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; + panel { compatible = "edt,etm0700g0dh6"; pinctrl-0 = <&pinctrl_display_gpio>; + pinctrl-names = "default"; enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; port { panel_in: endpoint { - remote-endpoint = <&lvds0_out>; + remote-endpoint = <&lvds_decoder_out>; }; }; }; @@ -76,8 +102,7 @@ regulator-name = "vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>; - enable-active-high; + gpio = <&gpio1 2 0>; }; }; @@ -388,13 +413,13 @@ pinctrl_power_button: powerbutgrp { fsl,pins = < - MX53_PAD_SD2_DATA2__GPIO1_13 0x1e4 + MX53_PAD_SD2_DATA0__GPIO1_15 0x1e4 >; }; pinctrl_power_out: poweroutgrp { fsl,pins = < - MX53_PAD_SD2_DATA0__GPIO1_15 0x1e4 + MX53_PAD_SD2_DATA2__GPIO1_13 0x1e4 >; }; @@ -450,7 +475,7 @@ reg = <2>; lvds0_out: endpoint { - remote-endpoint = <&panel_in>; + remote-endpoint = <&lvds_decoder_in>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx53-ppd.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx53-ppd.dts @@ -70,6 +70,12 @@ clock-frequency = <11289600>; }; + achc_24M: achc-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + sgtlsound: sound { compatible = "fsl,imx53-cpuvo-sgtl5000", "fsl,imx-audio-sgtl5000"; @@ -287,16 +293,13 @@ &gpio4 12 GPIO_ACTIVE_LOW>; status = "okay"; - spidev0: spi@0 { - compatible = "ge,achc"; - reg = <0>; - spi-max-frequency = <1000000>; - }; - - spidev1: spi@1 { - compatible = "ge,achc"; - reg = <1>; - spi-max-frequency = <1000000>; + spidev0: spi@1 { + compatible = "ge,achc", "nxp,kinetis-k20"; + reg = <1>, <0>; + vdd-supply = <®_3v3>; + vdda-supply = <®_3v3>; + clocks = <&achc_24M>; + reset-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; }; gpioxra0: gpio@2 { @@ -458,7 +461,7 @@ scl-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; status = "okay"; - i2c-switch@70 { + i2c-mux@70 { compatible = "nxp,pca9547"; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6dl-icore-mipi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6dl-icore-mipi.dts @@ -8,7 +8,7 @@ /dts-v1/; #include "imx6dl.dtsi" -#include "imx6qdl-icore.dtsi" +#include "imx6qdl-icore-1.5.dtsi" / { model = "Engicam i.CoreM6 DualLite/Solo MIPI Starter Kit"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi @@ -96,27 +96,22 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; phy-mode = "rgmii-id"; - phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; - phy-reset-duration = <20>; phy-supply = <&sw2_reg>; - phy-handle = <ðphy0>; status = "okay"; + fixed-link { + speed = <1000>; + full-duplex; + }; + mdio { #address-cells = <1>; #size-cells = <0>; - phy_port2: phy@1 { - reg = <1>; - }; - - phy_port3: phy@2 { - reg = <2>; - }; - switch@10 { compatible = "qca,qca8334"; - reg = <10>; + reg = <0x10>; + reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; switch_ports: ports { #address-cells = <1>; @@ -137,15 +132,30 @@ port@2 { reg = <2>; label = "eth2"; + phy-mode = "internal"; phy-handle = <&phy_port2>; }; port@3 { reg = <3>; label = "eth1"; + phy-mode = "internal"; phy-handle = <&phy_port3>; }; }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy_port2: ethernet-phy@1 { + reg = <1>; + }; + + phy_port3: ethernet-phy@2 { + reg = <2>; + }; + }; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6dl-yapp4-ursa.dts @@ -38,7 +38,7 @@ }; &switch_ports { - /delete-node/ port@2; + /delete-node/ port@3; }; &touchscreen { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6dl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6dl.dtsi @@ -81,6 +81,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-b450v3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-b450v3.dts @@ -65,13 +65,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, - <&clks IMX6QDL_CLK_PLL3_USB_OTG>; -}; - &ldb { status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-b650v3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-b650v3.dts @@ -65,13 +65,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, - <&clks IMX6QDL_CLK_PLL3_USB_OTG>; -}; - &ldb { status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-b850v3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-b850v3.dts @@ -53,17 +53,6 @@ }; }; -&clks { - assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>, - <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, - <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>; - assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, - <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, - <&clks IMX6QDL_CLK_PLL2_PFD2_396M>, - <&clks IMX6QDL_CLK_PLL2_PFD2_396M>; -}; - &ldb { fsl,dual-channel; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-bx50v3.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -377,3 +377,18 @@ #interrupt-cells = <1>; }; }; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>, + <&clks IMX6QDL_CLK_IPU1_DI0_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU1_DI1_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU2_DI0_PRE_SEL>, + <&clks IMX6QDL_CLK_IPU2_DI1_PRE_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, + <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>, + <&clks IMX6QDL_CLK_PLL2_PFD0_352M>; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-dhcom-pdk2.dts @@ -55,7 +55,7 @@ #sound-dai-cells = <0>; clocks = <&clk_ext_audio_codec>; VDDA-supply = <®_3p3v>; - VDDIO-supply = <®_3p3v>; + VDDIO-supply = <&sw2_reg>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q-dhcom-som.dtsi @@ -98,30 +98,40 @@ reg = <0>; max-speed = <100>; reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; - reset-delay-us = <1000>; - reset-post-delay-us = <1000>; + reset-assert-us = <1000>; + reset-deassert-us = <1000>; + smsc,disable-energy-detect; /* Make plugin detection reliable */ }; }; }; &i2c1 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio3 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio3 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; &i2c2 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; &i2c3 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + scl-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; ltc3676: pmic@3c { @@ -206,7 +216,7 @@ }; rtc@56 { - compatible = "rv3029c2"; + compatible = "microcrystal,rv3029"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rtc_hw300>; reg = <0x56>; @@ -287,6 +297,13 @@ >; }; + pinctrl_i2c1_gpio: i2c1-gpio-grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x4001b8b1 + MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x4001b8b1 + >; + }; + pinctrl_i2c2: i2c2-grp { fsl,pins = < MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 @@ -294,6 +311,13 @@ >; }; + pinctrl_i2c2_gpio: i2c2-gpio-grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x4001b8b1 + >; + }; + pinctrl_i2c3: i2c3-grp { fsl,pins = < MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 @@ -301,6 +325,13 @@ >; }; + pinctrl_i2c3_gpio: i2c3-gpio-grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x4001b8b1 + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x4001b8b1 + >; + }; + pinctrl_pmic_hw300: pmic-hw300-grp { fsl,pins = < MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1B0B0 @@ -408,6 +439,18 @@ vin-supply = <&sw1_reg>; }; +®_pu { + vin-supply = <&sw1_reg>; +}; + +®_vdd1p1 { + vin-supply = <&sw2_reg>; +}; + +®_vdd2p5 { + vin-supply = <&sw2_reg>; +}; + &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6q.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6q.dtsi @@ -158,6 +158,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x40000>; + ranges = <0 0x00900000 0x40000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-apalis.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -314,6 +314,8 @@ codec: sgtl5000@a { compatible = "fsl,sgtl5000"; reg = <0x0a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sgtl5000>; clocks = <&clks IMX6QDL_CLK_CKO>; VDDA-supply = <®_module_3v3_audio>; VDDIO-supply = <®_module_3v3>; @@ -543,8 +545,6 @@ MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x130b0 MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 - /* SGTL5000 sys_mclk */ - MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0 >; }; @@ -810,6 +810,12 @@ >; }; + pinctrl_sgtl5000: sgtl5000grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0 + >; + }; + pinctrl_spdif: spdifgrp { fsl,pins = < MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-emcon-avari.dtsi @@ -126,7 +126,7 @@ compatible = "nxp,pca8574"; reg = <0x3a>; gpio-controller; - #gpio-cells = <1>; + #gpio-cells = <2>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -273,7 +273,7 @@ /* VDD_AUD_1P8: Audio codec */ reg_aud_1p8v: ldo3 { - regulator-name = "vdd1p8"; + regulator-name = "vdd1p8a"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-boot-on; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-gw551x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-gw551x.dtsi @@ -105,19 +105,16 @@ sound-digital { compatible = "simple-audio-card"; simple-audio-card,name = "tda1997x-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_codec>; + simple-audio-card,frame-master = <&sound_codec>; - simple-audio-card,dai-link@0 { - format = "i2s"; - - cpu { - sound-dai = <&ssi2>; - }; + sound_cpu: simple-audio-card,cpu { + sound-dai = <&ssi1>; + }; - codec { - bitclock-master; - frame-master; - sound-dai = <&hdmi_receiver>; - }; + sound_codec: simple-audio-card,codec { + sound-dai = <&hdmi_receiver>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-gw560x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-gw560x.dtsi @@ -464,7 +464,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-icore.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-icore.dtsi @@ -384,7 +384,7 @@ pinctrl_usbotg: usbotggrp { fsl,pins = < - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 >; }; @@ -396,6 +396,7 @@ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17070 MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17070 MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17070 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1b0b0 >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi @@ -51,16 +51,6 @@ vin-supply = <®_3p3v_s5>; }; - reg_3p3v_s0: regulator-3p3v-s0 { - compatible = "regulator-fixed"; - regulator-name = "V_3V3_S0"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; - vin-supply = <®_3p3v_s5>; - }; - reg_3p3v_s5: regulator-3p3v-s5 { compatible = "regulator-fixed"; regulator-name = "V_3V3_S5"; @@ -167,7 +157,7 @@ i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; - status = "disabld"; + status = "disabled"; }; i2c_cam: i2c-gpio-cam { @@ -179,7 +169,7 @@ i2c-gpio,delay-us = <2>; /* ~100 kHz */ #address-cells = <1>; #size-cells = <0>; - status = "disabld"; + status = "disabled"; }; }; @@ -269,8 +259,20 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; - phy-mode = "rgmii"; - phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + phy-connection-type = "rgmii-id"; + phy-handle = <ðphy>; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>; + reset-assert-us = <1000>; + }; + }; }; &i2c_intern { @@ -510,7 +512,7 @@ MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 - MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0 /* RST_GBE0_PHY# */ + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 /* RST_GBE0_PHY# */ >; }; @@ -551,7 +553,7 @@ pinctrl_i2c3: i2c3grp { fsl,pins = < - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1 >; }; @@ -723,7 +725,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie>; wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>; - reset-gpio = <&gpio3 13 GPIO_ACTIVE_HIGH>; + reset-gpio = <&gpio3 13 GPIO_ACTIVE_LOW>; }; /* LCD_BKLT_PWM */ @@ -811,5 +813,6 @@ /* CPLD is feeded by watchdog (hardwired) */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_wdog1>; + fsl,ext-reset-output; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -315,8 +315,8 @@ fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 - MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1 - MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1 >; }; @@ -403,6 +403,7 @@ &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; status = "disabled"; }; @@ -432,6 +433,7 @@ pinctrl-0 = <&pinctrl_usdhc2>; cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&vdd_sd1_reg>; status = "disabled"; }; @@ -441,5 +443,6 @@ &pinctrl_usdhc3_cdwp>; cd-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio1 29 GPIO_ACTIVE_HIGH>; + vmmc-supply = <&vdd_sd0_reg>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi @@ -107,14 +107,14 @@ regulators { vdd_arm: buck1 { regulator-name = "vdd_arm"; - regulator-min-microvolt = <730000>; + regulator-min-microvolt = <925000>; regulator-max-microvolt = <1380000>; regulator-always-on; }; vdd_soc: buck2 { regulator-name = "vdd_soc"; - regulator-min-microvolt = <730000>; + regulator-min-microvolt = <1150000>; regulator-max-microvolt = <1380000>; regulator-always-on; }; @@ -183,7 +183,6 @@ pinctrl-0 = <&pinctrl_usdhc4>; bus-width = <8>; non-removable; - vmmc-supply = <&vdd_emmc_1p8>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -749,10 +749,6 @@ vin-supply = <&vgen5_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen5_reg>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-sr-som-ti.dtsi @@ -153,6 +153,7 @@ bus-width = <4>; keep-power-in-suspend; mmc-pwrseq = <&pwrseq_ti_wifi>; + cap-power-off-card; non-removable; vmmc-supply = <&vcc_3v3>; /* vqmmc-supply = <&nvcc_sd1>; - MMC layer doesn't like it! */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-sr-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-sr-som.dtsi @@ -54,7 +54,13 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_microsom_enet_ar8035>; phy-mode = "rgmii-id"; - phy-reset-duration = <2>; + + /* + * The PHY seems to require a long-enough reset duration to avoid + * some rare issues where the PHY gets stuck in an inconsistent and + * non-functional state at boot-up. 10ms proved to be fine . + */ + phy-reset-duration = <10>; phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-ts7970.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-ts7970.dtsi @@ -226,7 +226,7 @@ reg = <0x28>; #gpio-cells = <2>; gpio-controller; - ngpio = <32>; + ngpios = <62>; }; sgtl5000: codec@a { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-udoo.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-udoo.dtsi @@ -5,6 +5,8 @@ * Author: Fabio Estevam */ +#include + / { aliases { backlight = &backlight; @@ -98,7 +100,7 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; @@ -218,6 +220,7 @@ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 >; }; @@ -290,7 +293,7 @@ &usdhc3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc3>; - non-removable; + cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-wandboard-revd1.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-wandboard-revd1.dtsi @@ -166,7 +166,6 @@ MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b030 - MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1 >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi @@ -627,7 +627,7 @@ pinctrl-0 = <&pinctrl_usdhc2>; bus-width = <4>; cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>; + disable-wp; vmmc-supply = <®_3p3v_sd>; vqmmc-supply = <®_3p3v>; no-1-8-v; @@ -640,7 +640,7 @@ pinctrl-0 = <&pinctrl_usdhc3>; bus-width = <4>; cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; - wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + disable-wp; vmmc-supply = <®_3p3v_sd>; vqmmc-supply = <®_3p3v>; no-1-8-v; @@ -774,6 +774,7 @@ &usbh1 { vbus-supply = <®_5p0v_main>; disable-over-current; + maximum-speed = "full-speed"; status = "okay"; }; @@ -1055,7 +1056,6 @@ MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 - MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x40010040 MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x40010040 >; }; @@ -1068,7 +1068,6 @@ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 - MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x40010040 MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x40010040 >; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qdl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qdl.dtsi @@ -45,6 +45,10 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg; + usb1 = &usbh1; + usb2 = &usbh2; + usb3 = &usbh3; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -156,7 +160,7 @@ interrupt-parent = <&gpc>; ranges; - dma_apbh: dma-apbh@110000 { + dma_apbh: dma-controller@110000 { compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; reg = <0x00110000 0x2000>; interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>, @@ -255,7 +259,7 @@ interrupt-parent = <&intc>; }; - L2: l2-cache@a02000 { + L2: cache-controller@a02000 { compatible = "arm,pl310-cache"; reg = <0x00a02000 0x1000>; interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; @@ -574,7 +578,7 @@ status = "disabled"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt"; reg = <0x02098000 0x4000>; interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; @@ -766,7 +770,7 @@ regulator-name = "vddpu"; regulator-min-microvolt = <725000>; regulator-max-microvolt = <1450000>; - regulator-enable-ramp-delay = <150>; + regulator-enable-ramp-delay = <380>; anatop-reg-offset = <0x140>; anatop-vol-bit-shift = <9>; anatop-vol-bit-width = <5>; @@ -1039,9 +1043,8 @@ compatible = "fsl,imx6q-fec"; reg = <0x02188000 0x4000>; interrupt-names = "int0", "pps"; - interrupts-extended = - <&intc 0 118 IRQ_TYPE_LEVEL_HIGH>, - <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, + <0 119 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET_REF>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6qp.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6qp.dtsi @@ -9,12 +9,18 @@ ocram2: sram@940000 { compatible = "mmio-sram"; reg = <0x00940000 0x20000>; + ranges = <0 0x00940000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; ocram3: sram@960000 { compatible = "mmio-sram"; reg = <0x00960000 0x20000>; + ranges = <0 0x00960000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6QDL_CLK_OCRAM>; }; @@ -77,7 +83,6 @@ }; &fec { - /delete-property/interrupts-extended; interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>, <0 119 IRQ_TYPE_LEVEL_HIGH>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sl-evk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sl-evk.dts @@ -584,10 +584,6 @@ vin-supply = <&sw2_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&sw2_reg>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sl.dtsi @@ -39,6 +39,9 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -121,6 +124,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SL_CLK_OCRAM>; }; @@ -133,7 +139,7 @@ interrupt-parent = <&intc>; }; - L2: l2-cache@a02000 { + L2: cache-controller@a02000 { compatible = "arm,pl310-cache"; reg = <0x00a02000 0x1000>; interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; @@ -380,7 +386,7 @@ clock-names = "ipg", "per"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6sl-gpt"; reg = <0x02098000 0x4000>; interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>; @@ -936,8 +942,10 @@ }; rngb: rngb@21b4000 { + compatible = "fsl,imx6sl-rngb", "fsl,imx25-rngb"; reg = <0x021b4000 0x4000>; interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks IMX6SL_CLK_DUMMY>; }; weim: weim@21b8000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sll-evk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sll-evk.dts @@ -265,10 +265,6 @@ status = "okay"; }; -®_3p0 { - vin-supply = <&sw2_reg>; -}; - &snvs_poweroff { status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sll.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sll.dtsi @@ -36,6 +36,8 @@ spi1 = &ecspi2; spi3 = &ecspi3; spi4 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -49,20 +51,18 @@ device_type = "cpu"; reg = <0>; next-level-cache = <&L2>; - operating-points = < + operating-points = /* kHz uV */ - 996000 1275000 - 792000 1175000 - 396000 1075000 - 198000 975000 - >; - fsl,soc-operating-points = < + <996000 1275000>, + <792000 1175000>, + <396000 1075000>, + <198000 975000>; + fsl,soc-operating-points = /* ARM kHz SOC-PU uV */ - 996000 1175000 - 792000 1175000 - 396000 1175000 - 198000 1175000 - >; + <996000 1175000>, + <792000 1175000>, + <396000 1175000>, + <198000 1175000>; clock-latency = <61036>; /* two CLK32 periods */ #cooling-cells = <2>; clocks = <&clks IMX6SLL_CLK_ARM>, @@ -123,6 +123,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; }; intc: interrupt-controller@a01000 { @@ -134,7 +137,7 @@ interrupt-parent = <&intc>; }; - L2: l2-cache@a02000 { + L2: cache-controller@a02000 { compatible = "arm,pl310-cache"; reg = <0x00a02000 0x1000>; interrupts = ; @@ -269,7 +272,7 @@ status = "disabled"; }; - ssi1: ssi-controller@2028000 { + ssi1: ssi@2028000 { compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; reg = <0x02028000 0x4000>; interrupts = ; @@ -282,7 +285,7 @@ status = "disabled"; }; - ssi2: ssi-controller@202c000 { + ssi2: ssi@202c000 { compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; reg = <0x0202c000 0x4000>; interrupts = ; @@ -295,7 +298,7 @@ status = "disabled"; }; - ssi3: ssi-controller@2030000 { + ssi3: ssi@2030000 { compatible = "fsl,imx6sl-ssi", "fsl,imx51-ssi"; reg = <0x02030000 0x4000>; interrupts = ; @@ -547,7 +550,7 @@ reg = <0x020ca000 0x1000>; interrupts = ; clocks = <&clks IMX6SLL_CLK_USBPHY2>; - phy-reg_3p0-supply = <®_3p0>; + phy-3p0-supply = <®_3p0>; fsl,anatop = <&anatop>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sx-sabreauto.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sx-sabreauto.dts @@ -99,7 +99,7 @@ &fec2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <ðphy0>; fsl,magic-packet; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sx-sdb-reva.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sx-sdb-reva.dts @@ -159,10 +159,6 @@ vin-supply = <&vgen6_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen6_reg>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sx-sdb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sx-sdb.dts @@ -141,10 +141,6 @@ vin-supply = <&vgen6_reg>; }; -®_vdd3p0 { - vin-supply = <&sw2_reg>; -}; - ®_vdd2p5 { vin-supply = <&vgen6_reg>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sx-sdb.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sx-sdb.dtsi @@ -213,7 +213,7 @@ &fec2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet2>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <ðphy2>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6sx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6sx.dtsi @@ -49,6 +49,9 @@ spi2 = &ecspi3; spi3 = &ecspi4; spi4 = &ecspi5; + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -163,12 +166,18 @@ ocram_s: sram@8f8000 { compatible = "mmio-sram"; reg = <0x008f8000 0x4000>; + ranges = <0 0x008f8000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SX_CLK_OCRAM_S>; }; ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; clocks = <&clks IMX6SX_CLK_OCRAM>; }; @@ -181,7 +190,7 @@ interrupt-parent = <&intc>; }; - L2: l2-cache@a02000 { + L2: cache-controller@a02000 { compatible = "arm,pl310-cache"; reg = <0x00a02000 0x1000>; interrupts = ; @@ -202,7 +211,7 @@ power-domains = <&pd_pu>; }; - dma_apbh: dma-apbh@1804000 { + dma_apbh: dma-controller@1804000 { compatible = "fsl,imx6sx-dma-apbh", "fsl,imx28-dma-apbh"; reg = <0x01804000 0x2000>; interrupts = , @@ -466,7 +475,7 @@ status = "disabled"; }; - gpt: gpt@2098000 { + gpt: timer@2098000 { compatible = "fsl,imx6sx-gpt", "fsl,imx6dl-gpt"; reg = <0x02098000 0x4000>; interrupts = ; @@ -949,6 +958,8 @@ <&clks IMX6SX_CLK_USDHC1>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; status = "disabled"; }; @@ -961,6 +972,8 @@ <&clks IMX6SX_CLK_USDHC2>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; status = "disabled"; }; @@ -973,6 +986,8 @@ <&clks IMX6SX_CLK_USDHC3>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step= <2>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ul-14x14-evk.dtsi @@ -215,7 +215,7 @@ flash0: n25q256a@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q256a"; + compatible = "micron,n25q256a", "jedec,spi-nor"; spi-max-frequency = <29000000>; spi-rx-bus-width = <4>; spi-tx-bus-width = <4>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts @@ -157,10 +157,6 @@ status = "okay"; }; -&snvs_poweroff { - status = "okay"; -}; - &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ul.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ul.dtsi @@ -47,6 +47,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbotg2; usbphy0 = &usbphy1; usbphy1 = &usbphy2; }; @@ -62,20 +64,18 @@ clock-frequency = <696000000>; clock-latency = <61036>; /* two CLK32 periods */ #cooling-cells = <2>; - operating-points = < + operating-points = /* kHz uV */ - 696000 1275000 - 528000 1175000 - 396000 1025000 - 198000 950000 - >; - fsl,soc-operating-points = < + <696000 1275000>, + <528000 1175000>, + <396000 1025000>, + <198000 950000>; + fsl,soc-operating-points = /* KHz uV */ - 696000 1275000 - 528000 1175000 - 396000 1175000 - 198000 1175000 - >; + <696000 1275000>, + <528000 1175000>, + <396000 1175000>, + <198000 1175000>; clocks = <&clks IMX6UL_CLK_ARM>, <&clks IMX6UL_CLK_PLL2_BUS>, <&clks IMX6UL_CLK_PLL2_PFD2>, @@ -157,6 +157,9 @@ ocram: sram@900000 { compatible = "mmio-sram"; reg = <0x00900000 0x20000>; + ranges = <0 0x00900000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; }; intc: interrupt-controller@a01000 { @@ -171,7 +174,7 @@ <0x00a06000 0x2000>; }; - dma_apbh: dma-apbh@1804000 { + dma_apbh: dma-controller@1804000 { compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; reg = <0x01804000 0x2000>; interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>, @@ -430,7 +433,7 @@ status = "disabled"; }; - gpt1: gpt@2098000 { + gpt1: timer@2098000 { compatible = "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"; reg = <0x02098000 0x4000>; interrupts = ; @@ -704,7 +707,7 @@ reg = <0x020e4000 0x4000>; }; - gpt2: gpt@20e8000 { + gpt2: timer@20e8000 { compatible = "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"; reg = <0x020e8000 0x4000>; interrupts = ; @@ -966,7 +969,7 @@ }; csi: csi@21c4000 { - compatible = "fsl,imx6ul-csi", "fsl,imx7-csi"; + compatible = "fsl,imx6ul-csi"; reg = <0x021c4000 0x4000>; interrupts = ; clocks = <&clks IMX6UL_CLK_CSI>; @@ -975,7 +978,7 @@ }; lcdif: lcdif@21c8000 { - compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif"; + compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif"; reg = <0x021c8000 0x4000>; interrupts = ; clocks = <&clks IMX6UL_CLK_LCDIF_PIX>, @@ -996,7 +999,7 @@ qspi: spi@21e0000 { #address-cells = <1>; #size-cells = <0>; - compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi"; + compatible = "fsl,imx6ul-qspi"; reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>; reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi @@ -43,6 +43,7 @@ assigned-clock-rates = <0>, <198000000>; cap-power-off-card; keep-power-in-suspend; + max-frequency = <25000000>; mmc-pwrseq = <&wifi_pwrseq>; no-1-8-v; non-removable; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ull-colibri.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ull-colibri.dtsi @@ -37,7 +37,7 @@ reg_sd1_vmmc: regulator-sd1-vmmc { compatible = "regulator-gpio"; - gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>; + gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_snvs_reg_sd>; regulator-always-on; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx6ull-pinfunc.h +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx6ull-pinfunc.h @@ -82,6 +82,6 @@ #define MX6ULL_PAD_CSI_DATA04__ESAI_TX_FS 0x01F4 0x0480 0x0000 0x9 0x0 #define MX6ULL_PAD_CSI_DATA05__ESAI_TX_CLK 0x01F8 0x0484 0x0000 0x9 0x0 #define MX6ULL_PAD_CSI_DATA06__ESAI_TX5_RX0 0x01FC 0x0488 0x0000 0x9 0x0 -#define MX6ULL_PAD_CSI_DATA07__ESAI_T0 0x0200 0x048C 0x0000 0x9 0x0 +#define MX6ULL_PAD_CSI_DATA07__ESAI_TX0 0x0200 0x048C 0x0000 0x9 0x0 #endif /* __DTS_IMX6ULL_PINFUNC_H */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7-colibri.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7-colibri.dtsi @@ -77,7 +77,7 @@ dailink_master: simple-audio-card,codec { sound-dai = <&codec>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; }; }; }; @@ -152,7 +152,7 @@ compatible = "fsl,sgtl5000"; #sound-dai-cells = <0>; reg = <0x0a>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai1_mclk>; VDDA-supply = <®_module_3v3_avdd>; @@ -337,7 +337,6 @@ assigned-clock-rates = <400000000>; bus-width = <8>; fsl,tuning-step = <2>; - max-frequency = <100000000>; vmmc-supply = <®_module_3v3>; vqmmc-supply = <®_DCDC3>; non-removable; @@ -347,7 +346,7 @@ &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4 - &pinctrl_gpio7>; + &pinctrl_gpio7 &pinctrl_usbc_det>; pinctrl_gpio1: gpio1-grp { fsl,pins = < @@ -452,7 +451,6 @@ pinctrl_enet1: enet1grp { fsl,pins = < - MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14 MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x73 MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x73 MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x73 @@ -650,6 +648,12 @@ >; }; + pinctrl_usbc_det: gpio-usbc-det { + fsl,pins = < + MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x14 + >; + }; + pinctrl_usbh_reg: gpio-usbh-vbus { fsl,pins = < MX7D_PAD_UART3_CTS_B__GPIO4_IO7 0x14 /* SODIMM 129 USBH PEN */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7-mba7.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7-mba7.dtsi @@ -250,7 +250,7 @@ tlv320aic32x4: audio-codec@18 { compatible = "ti,tlv320aic32x4"; reg = <0x18>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; clock-names = "mclk"; ldoin-supply = <®_audio_3v3>; iov-supply = <®_audio_3v3>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-meerkat96.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-meerkat96.dts @@ -193,7 +193,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc1>; keep-power-in-suspend; - tuning-step = <2>; + fsl,tuning-step = <2>; vmmc-supply = <®_3p3v>; no-1-8-v; broken-cd; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-nitrogen7.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-nitrogen7.dts @@ -284,7 +284,7 @@ codec: wm8960@1a { compatible = "wlf,wm8960"; reg = <0x1a>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; clock-names = "mclk"; wlf,shared-lrclk; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-pico-hobbit.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-pico-hobbit.dts @@ -31,7 +31,7 @@ dailink_master: simple-audio-card,codec { sound-dai = <&sgtl5000>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; }; }; }; @@ -41,7 +41,7 @@ #sound-dai-cells = <0>; reg = <0x0a>; compatible = "fsl,sgtl5000"; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_vref_1v8>; }; @@ -64,7 +64,7 @@ interrupt-parent = <&gpio2>; interrupts = <7 0>; spi-max-frequency = <1000000>; - pendown-gpio = <&gpio2 7 0>; + pendown-gpio = <&gpio2 7 GPIO_ACTIVE_LOW>; vcc-supply = <®_3p3v>; ti,x-min = /bits/ 16 <0>; ti,x-max = /bits/ 16 <4095>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-pico-pi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-pico-pi.dts @@ -31,7 +31,7 @@ dailink_master: simple-audio-card,codec { sound-dai = <&sgtl5000>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; }; }; }; @@ -41,7 +41,7 @@ #sound-dai-cells = <0>; reg = <0x0a>; compatible = "fsl,sgtl5000"; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_vref_1v8>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-pico.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-pico.dtsi @@ -307,7 +307,7 @@ pinctrl-2 = <&pinctrl_usdhc1_200mhz>; cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; bus-width = <4>; - tuning-step = <2>; + fsl,tuning-step = <2>; vmmc-supply = <®_3p3v>; wakeup-source; no-1-8-v; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-sdb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-sdb.dts @@ -176,13 +176,8 @@ pinctrl-0 = <&pinctrl_tsc2046_pendown>; interrupt-parent = <&gpio2>; interrupts = <29 0>; - pendown-gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; - ti,x-min = /bits/ 16 <0>; - ti,x-max = /bits/ 16 <0>; - ti,y-min = /bits/ 16 <0>; - ti,y-max = /bits/ 16 <0>; - ti,pressure-max = /bits/ 16 <0>; - ti,x-plate-ohms = /bits/ 16 <400>; + pendown-gpio = <&gpio2 29 GPIO_ACTIVE_LOW>; + touchscreen-max-pressure = <255>; wakeup-source; }; }; @@ -356,7 +351,7 @@ codec: wm8960@1a { compatible = "wlf,wm8960"; reg = <0x1a>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; clock-names = "mclk"; wlf,shared-lrclk; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d-zii-rmu2.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d-zii-rmu2.dts @@ -350,7 +350,7 @@ &iomuxc_lpsr { pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp { - fsl,phy = < + fsl,pins = < MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2 0x08 >; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7d.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7d.dtsi @@ -7,6 +7,12 @@ #include / { + aliases { + usb0 = &usbotg1; + usb1 = &usbotg2; + usb2 = &usbh; + }; + cpus { cpu0: cpu@0 { clock-frequency = <996000000>; @@ -198,9 +204,6 @@ }; &ca_funnel_in_ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { reg = <1>; ca_funnel_in_port1: endpoint { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7s-colibri.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7s-colibri.dtsi @@ -49,3 +49,7 @@ reg = <0x80000000 0x10000000>; }; }; + +&gpmi { + status = "okay"; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7s-warp.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7s-warp.dts @@ -75,7 +75,7 @@ dailink_master: simple-audio-card,codec { sound-dai = <&codec>; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; }; }; }; @@ -232,7 +232,7 @@ #sound-dai-cells = <0>; reg = <0x0a>; compatible = "fsl,sgtl5000"; - clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai1_mclk>; VDDA-supply = <&vgen4_reg>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7s.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7s.dtsi @@ -47,6 +47,8 @@ spi1 = &ecspi2; spi2 = &ecspi3; spi3 = &ecspi4; + usb0 = &usbotg1; + usb1 = &usbh; }; cpus { @@ -181,7 +183,11 @@ clock-names = "apb_pclk"; ca_funnel_in_ports: in-ports { - port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; ca_funnel_in_port0: endpoint { remote-endpoint = <&etm0_out_port>; }; @@ -444,8 +450,8 @@ fsl,input-sel = <&iomuxc>; }; - gpt1: gpt@302d0000 { - compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; + gpt1: timer@302d0000 { + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; reg = <0x302d0000 0x10000>; interrupts = ; clocks = <&clks IMX7D_GPT1_ROOT_CLK>, @@ -453,8 +459,8 @@ clock-names = "ipg", "per"; }; - gpt2: gpt@302e0000 { - compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; + gpt2: timer@302e0000 { + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; reg = <0x302e0000 0x10000>; interrupts = ; clocks = <&clks IMX7D_GPT2_ROOT_CLK>, @@ -463,8 +469,8 @@ status = "disabled"; }; - gpt3: gpt@302f0000 { - compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; + gpt3: timer@302f0000 { + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; reg = <0x302f0000 0x10000>; interrupts = ; clocks = <&clks IMX7D_GPT3_ROOT_CLK>, @@ -473,8 +479,8 @@ status = "disabled"; }; - gpt4: gpt@30300000 { - compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; + gpt4: timer@30300000 { + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; reg = <0x30300000 0x10000>; interrupts = ; clocks = <&clks IMX7D_GPT4_ROOT_CLK>, @@ -504,7 +510,7 @@ mux: mux-controller { compatible = "mmio-mux"; - #mux-control-cells = <0>; + #mux-control-cells = <1>; mux-reg-masks = <0x14 0x00000010>; }; @@ -763,7 +769,7 @@ }; lcdif: lcdif@30730000 { - compatible = "fsl,imx7d-lcdif", "fsl,imx28-lcdif"; + compatible = "fsl,imx7d-lcdif", "fsl,imx6sx-lcdif"; reg = <0x30730000 0x10000>; interrupts = ; clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>, @@ -1131,6 +1137,8 @@ <&clks IMX7D_USDHC1_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-step = <2>; + fsl,tuning-start-tap = <20>; status = "disabled"; }; @@ -1143,6 +1151,8 @@ <&clks IMX7D_USDHC2_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-step = <2>; + fsl,tuning-start-tap = <20>; status = "disabled"; }; @@ -1155,6 +1165,8 @@ <&clks IMX7D_USDHC3_ROOT_CLK>; clock-names = "ipg", "ahb", "per"; bus-width = <4>; + fsl,tuning-step = <2>; + fsl,tuning-start-tap = <20>; status = "disabled"; }; @@ -1190,14 +1202,13 @@ }; }; - dma_apbh: dma-apbh@33000000 { + dma_apbh: dma-controller@33000000 { compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh"; reg = <0x33000000 0x2000>; interrupts = , , , ; - interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; #dma-cells = <1>; dma-channels = <4>; clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; @@ -1206,7 +1217,7 @@ gpmi: gpmi-nand@33002000{ compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/imx7ulp.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/imx7ulp.dtsi @@ -37,10 +37,10 @@ #address-cells = <1>; #size-cells = <0>; - cpu0: cpu@0 { + cpu0: cpu@f00 { compatible = "arm,cortex-a7"; device_type = "cpu"; - reg = <0>; + reg = <0xf00>; }; }; @@ -397,7 +397,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLC>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 0 32>; + gpio-ranges = <&iomuxc1 0 0 20>; }; gpio_ptd: gpio@40af0000 { @@ -411,7 +411,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLD>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 32 32>; + gpio-ranges = <&iomuxc1 0 32 12>; }; gpio_pte: gpio@40b00000 { @@ -425,7 +425,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLE>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 64 32>; + gpio-ranges = <&iomuxc1 0 64 16>; }; gpio_ptf: gpio@40b10000 { @@ -439,7 +439,7 @@ clocks = <&pcc2 IMX7ULP_CLK_RGPIO2P1>, <&pcc3 IMX7ULP_CLK_PCTLF>; clock-names = "gpio", "port"; - gpio-ranges = <&iomuxc1 0 96 32>; + gpio-ranges = <&iomuxc1 0 96 20>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/integratorap.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/integratorap.dts @@ -155,6 +155,7 @@ pci: pciv3@62000000 { compatible = "arm,integrator-ap-pci", "v3,v360epc-pci"; + device_type = "pci"; #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/kirkwood-lsxl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/kirkwood-lsxl.dtsi @@ -10,6 +10,11 @@ ocp@f1000000 { pinctrl: pin-controller@10000 { + /* Non-default UART pins */ + pmx_uart0: pmx-uart0 { + marvell,pins = "mpp4", "mpp5"; + }; + pmx_power_hdd: pmx-power-hdd { marvell,pins = "mpp10"; marvell,function = "gpo"; @@ -213,22 +218,11 @@ &mdio { status = "okay"; - ethphy0: ethernet-phy@0 { - reg = <0>; - }; - ethphy1: ethernet-phy@8 { reg = <8>; }; }; -ð0 { - status = "okay"; - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; - ð1 { status = "okay"; ethernet1-port@0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-som-lv-35xx-devkit.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-som-lv-35xx-devkit.dts @@ -11,3 +11,18 @@ model = "LogicPD Zoom OMAP35xx SOM-LV Development Kit"; compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3"; }; + +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_2_pins>; + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-som-lv-37xx-devkit.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-som-lv-37xx-devkit.dts @@ -11,3 +11,18 @@ model = "LogicPD Zoom DM3730 SOM-LV Development Kit"; compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3630", "ti,omap3"; }; + +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_2_pins>; + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi @@ -51,6 +51,8 @@ &mcbsp2 { status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mcbsp2_pins>; }; &charger { @@ -102,35 +104,18 @@ regulator-max-microvolt = <3300000>; }; - lcd0: display@0 { - compatible = "panel-dpi"; - label = "28"; - status = "okay"; - /* default-on; */ + lcd0: display { + /* This isn't the exact LCD, but the timings meet spec */ + compatible = "logicpd,type28"; pinctrl-names = "default"; pinctrl-0 = <&lcd_enable_pin>; - enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */ + backlight = <&bl>; + enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; port { lcd_in: endpoint { remote-endpoint = <&dpi_out>; }; }; - - panel-timing { - clock-frequency = <9000000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <3>; - hback-porch = <2>; - hsync-len = <42>; - vback-porch = <3>; - vfront-porch = <2>; - vsync-len = <11>; - hsync-active = <1>; - vsync-active = <1>; - de-active = <1>; - pixelclk-active = <0>; - }; }; bl: backlight { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-som-lv.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-som-lv.dtsi @@ -265,21 +265,6 @@ }; }; -&omap3_pmx_core2 { - pinctrl-names = "default"; - pinctrl-0 = <&hsusb2_2_pins>; - hsusb2_2_pins: pinmux_hsusb2_2_pins { - pinctrl-single,pins = < - OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ - OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ - OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ - OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ - OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ - OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ - >; - }; -}; - &uart2 { interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit-28.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit-28.dts @@ -11,22 +11,6 @@ #include "logicpd-torpedo-37xx-devkit.dts" &lcd0 { - - label = "28"; - - panel-timing { - clock-frequency = <9000000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <3>; - hback-porch = <2>; - hsync-len = <42>; - vback-porch = <3>; - vfront-porch = <2>; - vsync-len = <11>; - hsync-active = <1>; - vsync-active = <1>; - de-active = <1>; - pixelclk-active = <0>; - }; + /* To make it work, set CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=4 */ + compatible = "logicpd,type28"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi @@ -80,6 +80,8 @@ }; &mcbsp2 { + pinctrl-names = "default"; + pinctrl-0 = <&mcbsp2_pins>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/lpc32xx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/lpc32xx.dtsi @@ -329,9 +329,6 @@ clocks = <&xtal_32k>, <&xtal>; clock-names = "xtal_32k", "xtal"; - - assigned-clocks = <&clk LPC32XX_CLK_HCLK_PLL>; - assigned-clock-rates = <208000000>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/ls1021a-tsn.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/ls1021a-tsn.dts @@ -247,7 +247,7 @@ flash@0 { /* Rev. A uses 64MB flash, Rev. B & C use 32MB flash */ - compatible = "jedec,spi-nor", "s25fl256s1", "s25fl512s"; + compatible = "jedec,spi-nor"; spi-max-frequency = <20000000>; #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/ls1021a.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/ls1021a.dtsi @@ -181,7 +181,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x0 0x1550000 0x0 0x10000>, - <0x0 0x40000000 0x0 0x40000000>; + <0x0 0x40000000 0x0 0x20000000>; reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = ; clock-names = "qspi_en", "qspi"; @@ -311,39 +311,6 @@ #thermal-sensor-cells = <1>; }; - thermal-zones { - cpu_thermal: cpu-thermal { - polling-delay-passive = <1000>; - polling-delay = <5000>; - - thermal-sensors = <&tmu 0>; - - trips { - cpu_alert: cpu-alert { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - cpu_crit: cpu-crit { - temperature = <95000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu_alert>; - cooling-device = - <&cpu0 THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>, - <&cpu1 THERMAL_NO_LIMIT - THERMAL_NO_LIMIT>; - }; - }; - }; - }; - dspi0: spi@2100000 { compatible = "fsl,ls1021a-v1.0-dspi"; #address-cells = <1>; @@ -728,7 +695,7 @@ }; mdio0: mdio@2d24000 { - compatible = "fsl,etsec2-mdio"; + compatible = "gianfar"; device_type = "mdio"; #address-cells = <1>; #size-cells = <0>; @@ -737,7 +704,7 @@ }; mdio1: mdio@2d64000 { - compatible = "fsl,etsec2-mdio"; + compatible = "gianfar"; device_type = "mdio"; #address-cells = <1>; #size-cells = <0>; @@ -753,7 +720,7 @@ fsl,tmr-prsc = <2>; fsl,tmr-add = <0xaaaaaaab>; fsl,tmr-fiper1 = <999999995>; - fsl,tmr-fiper2 = <99990>; + fsl,tmr-fiper2 = <999999995>; fsl,max-adj = <499999999>; fsl,extts-fifo; }; @@ -984,4 +951,37 @@ }; }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <5000>; + + thermal-sensors = <&tmu 0>; + + trips { + cpu_alert: cpu-alert { + temperature = <85000>; + hysteresis = <2000>; + type = "passive"; + }; + cpu_crit: cpu-crit { + temperature = <95000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT + THERMAL_NO_LIMIT>; + }; + }; + }; + }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson.dtsi @@ -49,14 +49,14 @@ }; uart_A: serial@84c0 { - compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart"; reg = <0x84c0 0x18>; interrupts = ; status = "disabled"; }; uart_B: serial@84dc { - compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart"; reg = <0x84dc 0x18>; interrupts = ; status = "disabled"; @@ -94,7 +94,7 @@ }; uart_C: serial@8700 { - compatible = "amlogic,meson6-uart", "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart"; reg = <0x8700 0x18>; interrupts = ; status = "disabled"; @@ -196,7 +196,7 @@ }; uart_AO: serial@4c0 { - compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart", "amlogic,meson-uart"; + compatible = "amlogic,meson6-uart", "amlogic,meson-ao-uart"; reg = <0x4c0 0x18>; interrupts = ; status = "disabled"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8.dtsi @@ -129,8 +129,8 @@ gpu_opp_table: gpu-opp-table { compatible = "operating-points-v2"; - opp-182150000 { - opp-hz = /bits/ 64 <182150000>; + opp-182142857 { + opp-hz = /bits/ 64 <182142857>; opp-microvolt = <1150000>; }; opp-318750000 { @@ -230,8 +230,6 @@ , , , - , - , , , , @@ -243,8 +241,13 @@ "pp2", "ppmmu2", "pp4", "ppmmu4", "pp5", "ppmmu5", "pp6", "ppmmu6"; resets = <&reset RESET_MALI>; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; clock-names = "bus", "core"; + + assigned-clocks = <&clkc CLKID_MALI>; + assigned-clock-rates = <318750000>; + operating-points-v2 = <&gpu_opp_table>; }; }; @@ -253,7 +256,7 @@ &aobus { pmu: pmu@e0 { compatible = "amlogic,meson8-pmu", "syscon"; - reg = <0xe0 0x8>; + reg = <0xe0 0x18>; }; pinctrl_aobus: pinctrl@84 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8b-ec100.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8b-ec100.dts @@ -148,7 +148,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 0 1148 0>; pwm-dutycycle-range = <100 0>; @@ -232,7 +232,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 1 1148 0>; pwm-dutycycle-range = <100 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8b-mxq.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8b-mxq.dts @@ -39,6 +39,8 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; + pwm-supply = <&vcc_5v>; + pwms = <&pwm_cd 0 1148 0>; pwm-dutycycle-range = <100 0>; @@ -84,7 +86,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&vcc_5v>; + pwm-supply = <&vcc_5v>; pwms = <&pwm_cd 1 1148 0>; pwm-dutycycle-range = <100 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8b-odroidc1.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8b-odroidc1.dts @@ -130,7 +130,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&p5v0>; + pwm-supply = <&p5v0>; pwms = <&pwm_cd 0 12218 0>; pwm-dutycycle-range = <91 0>; @@ -162,7 +162,7 @@ regulator-min-microvolt = <860000>; regulator-max-microvolt = <1140000>; - vin-supply = <&p5v0>; + pwm-supply = <&p5v0>; pwms = <&pwm_cd 1 12218 0>; pwm-dutycycle-range = <91 0>; @@ -219,7 +219,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8b.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8b.dtsi @@ -125,8 +125,8 @@ opp-hz = /bits/ 64 <255000000>; opp-microvolt = <1100000>; }; - opp-364300000 { - opp-hz = /bits/ 64 <364300000>; + opp-364285714 { + opp-hz = /bits/ 64 <364285714>; opp-microvolt = <1100000>; }; opp-425000000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/meson8m2-mxiii-plus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/meson8m2-mxiii-plus.dts @@ -83,7 +83,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOH_4 GPIO_ACTIVE_LOW>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/mmp2-brownstone.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/mmp2-brownstone.dts @@ -19,176 +19,174 @@ device_type = "memory"; reg = <0x00000000 0x08000000>; }; +}; + +&uart3 { + status = "okay"; +}; - soc { - apb@d4000000 { - uart3: uart@d4018000 { - status = "okay"; - }; - twsi1: i2c@d4011000 { - status = "okay"; - pmic: max8925@3c { - compatible = "maxium,max8925"; - reg = <0x3c>; - interrupts = <1>; - interrupt-parent = <&intcmux4>; - interrupt-controller; - #interrupt-cells = <1>; - maxim,tsc-irq = <0>; +&twsi1 { + status = "okay"; + pmic: max8925@3c { + compatible = "maxim,max8925"; + reg = <0x3c>; + interrupts = <1>; + interrupt-parent = <&intcmux4>; + interrupt-controller; + #interrupt-cells = <1>; + maxim,tsc-irq = <0>; - regulators { - SDV1 { - regulator-min-microvolt = <637500>; - regulator-max-microvolt = <1425000>; - regulator-boot-on; - regulator-always-on; - }; - SDV2 { - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <2225000>; - regulator-boot-on; - regulator-always-on; - }; - SDV3 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO1 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO2 { - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <2250000>; - regulator-boot-on; - regulator-always-on; - }; - LDO3 { - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <2250000>; - regulator-boot-on; - regulator-always-on; - }; - LDO4 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO5 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO6 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO7 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO8 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO9 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO10 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - }; - LDO11 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO12 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO13 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO14 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO15 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO16 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO17 { - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <2250000>; - regulator-boot-on; - regulator-always-on; - }; - LDO18 { - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <2250000>; - regulator-boot-on; - regulator-always-on; - }; - LDO19 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - LDO20 { - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <3900000>; - regulator-boot-on; - regulator-always-on; - }; - }; - backlight { - maxim,max8925-dual-string = <0>; - }; - charger { - batt-detect = <0>; - topoff-threshold = <1>; - fast-charge = <7>; - no-temp-support = <0>; - no-insert-detect = <0>; - }; - }; + regulators { + SDV1 { + regulator-min-microvolt = <637500>; + regulator-max-microvolt = <1425000>; + regulator-boot-on; + regulator-always-on; + }; + SDV2 { + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2225000>; + regulator-boot-on; + regulator-always-on; + }; + SDV3 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO1 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO2 { + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2250000>; + regulator-boot-on; + regulator-always-on; + }; + LDO3 { + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2250000>; + regulator-boot-on; + regulator-always-on; + }; + LDO4 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO5 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO6 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO7 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO8 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO9 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; }; - rtc: rtc@d4010000 { - status = "okay"; + LDO10 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; }; + LDO11 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO12 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO13 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO14 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO15 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO16 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO17 { + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2250000>; + regulator-boot-on; + regulator-always-on; + }; + LDO18 { + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <2250000>; + regulator-boot-on; + regulator-always-on; + }; + LDO19 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + LDO20 { + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <3900000>; + regulator-boot-on; + regulator-always-on; + }; + }; + backlight { + maxim,max8925-dual-string = <0>; + }; + charger { + batt-detect = <0>; + topoff-threshold = <1>; + fast-charge = <7>; + no-temp-support = <0>; + no-insert-detect = <0>; }; }; }; + +&rtc { + status = "okay"; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi @@ -13,8 +13,10 @@ #interrupt-cells = <2>; #address-cells = <1>; #size-cells = <0>; - spi-max-frequency = <3000000>; + spi-max-frequency = <9600000>; spi-cs-high; + spi-cpol; + spi-cpha; cpcap_adc: adc { compatible = "motorola,mapphone-cpcap-adc"; @@ -160,12 +162,12 @@ regulator-enable-ramp-delay = <1000>; }; - /* Used by DSS */ + /* Used by DSS and is the "zerov_regulator" trigger for SoC off mode */ vcsi: VCSI { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-enable-ramp-delay = <1000>; - regulator-boot-on; + regulator-always-on; }; vdac: VDAC { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/moxart-uc7112lx.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/moxart-uc7112lx.dts @@ -79,7 +79,7 @@ clocks = <&ref12>; }; -&sdhci { +&mmc { status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/moxart.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/moxart.dtsi @@ -93,8 +93,8 @@ clock-names = "PCLK"; }; - sdhci: sdhci@98e00000 { - compatible = "moxa,moxart-sdhci"; + mmc: mmc@98e00000 { + compatible = "moxa,moxart-mmc"; reg = <0x98e00000 0x5C>; interrupts = <5 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk_apb>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/mt7623.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/mt7623.dtsi @@ -320,7 +320,7 @@ clock-names = "spi", "wrap"; }; - cir: cir@10013000 { + cir: ir-receiver@10013000 { compatible = "mediatek,mt7623-cir"; reg = <0 0x10013000 0 0x1000>; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts @@ -192,6 +192,7 @@ fixed-link { speed = <1000>; full-duplex; + pause; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/mt7623n-rfb-emmc.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/mt7623n-rfb-emmc.dts @@ -138,6 +138,7 @@ mac@1 { compatible = "mediatek,eth-mac"; reg = <1>; + phy-mode = "rgmii"; phy-handle = <&phy5>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi @@ -29,7 +29,7 @@ compatible = "smsc,lan9221","smsc,lan9115"; bank-width = <2>; - gpmc,mux-add-data; + gpmc,mux-add-data = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <42>; gpmc,cs-wr-off-ns = <36>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-cm-t3x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-cm-t3x.dtsi @@ -227,7 +227,7 @@ interrupt-parent = <&gpio2>; interrupts = <25 0>; /* gpio_57 */ - pendown-gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio2 25 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; ti,x-max = /bits/ 16 <0x0fff>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-devkit8000-lcd-common.dtsi @@ -54,7 +54,7 @@ interrupt-parent = <&gpio1>; interrupts = <27 0>; /* gpio_27 */ - pendown-gpio = <&gpio1 27 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio1 27 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; ti,x-max = /bits/ 16 <0x0fff>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-gta04.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-gta04.dtsi @@ -31,6 +31,8 @@ aliases { display0 = &lcd; display1 = &tv0; + /delete-property/ mmc2; + /delete-property/ mmc3; }; ldo_3v3: fixedregulator { @@ -515,7 +517,7 @@ compatible = "bosch,bma180"; reg = <0x41>; pinctrl-names = "default"; - pintcrl-0 = <&bma180_pins>; + pinctrl-0 = <&bma180_pins>; interrupt-parent = <&gpio4>; interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_115 */ }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-gta04a5one.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-gta04a5one.dts @@ -5,9 +5,11 @@ #include "omap3-gta04a5.dts" -&omap3_pmx_core { +/ { model = "Goldelico GTA04A5/Letux 2804 with OneNAND"; +}; +&omap3_pmx_core { gpmc_pins: pinmux_gpmc_pins { pinctrl-single,pins = < --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-lilly-a83x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-lilly-a83x.dtsi @@ -311,7 +311,7 @@ interrupt-parent = <&gpio1>; interrupts = <8 0>; /* boot6 / gpio_8 */ spi-max-frequency = <1000000>; - pendown-gpio = <&gpio1 8 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>; vcc-supply = <®_vcc3>; pinctrl-names = "default"; pinctrl-0 = <&tsc2048_pins>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-n900.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-n900.dts @@ -105,6 +105,14 @@ linux,code = ; linux,can-disable; }; + + machine_cover { + label = "Machine Cover"; + gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */ + linux,input-type = ; + linux,code = ; + linux,can-disable; + }; }; isp1707: isp1707 { @@ -155,6 +163,12 @@ pwms = <&pwm9 0 26316 0>; /* 38000 Hz */ }; + rom_rng: rng { + compatible = "nokia,n900-rom-rng"; + clocks = <&rng_ick>; + clock-names = "ick"; + }; + /* controlled (enabled/disabled) directly by bcm2048 and wl1251 */ vctcxo: vctcxo { compatible = "fixed-clock"; @@ -808,10 +822,6 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; bus-width = <4>; - /* For debugging, it is often good idea to remove this GPIO. - It means you can remove back cover (to reboot by removing - battery) and still use the MMC card. */ - cd-gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* 160 */ }; /* most boards use vaux3, only some old versions use vmmc2 instead */ @@ -843,34 +853,46 @@ compatible = "ti,omap2-onenand"; reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */ + /* + * These timings are based on CONFIG_OMAP_GPMC_DEBUG=y reported + * bootloader set values when booted with v5.1 + * (OneNAND Manufacturer: Samsung): + * + * cs0 GPMC_CS_CONFIG1: 0xfb001202 + * cs0 GPMC_CS_CONFIG2: 0x00111100 + * cs0 GPMC_CS_CONFIG3: 0x00020200 + * cs0 GPMC_CS_CONFIG4: 0x11001102 + * cs0 GPMC_CS_CONFIG5: 0x03101616 + * cs0 GPMC_CS_CONFIG6: 0x90060000 + */ gpmc,sync-read; gpmc,sync-write; gpmc,burst-length = <16>; gpmc,burst-read; gpmc,burst-wrap; gpmc,burst-write; - gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */ - gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */ + gpmc,device-width = <2>; + gpmc,mux-add-data = <2>; gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <87>; - gpmc,cs-wr-off-ns = <87>; + gpmc,cs-rd-off-ns = <102>; + gpmc,cs-wr-off-ns = <102>; gpmc,adv-on-ns = <0>; - gpmc,adv-rd-off-ns = <10>; - gpmc,adv-wr-off-ns = <10>; - gpmc,oe-on-ns = <15>; - gpmc,oe-off-ns = <87>; + gpmc,adv-rd-off-ns = <12>; + gpmc,adv-wr-off-ns = <12>; + gpmc,oe-on-ns = <12>; + gpmc,oe-off-ns = <102>; gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <87>; - gpmc,rd-cycle-ns = <112>; - gpmc,wr-cycle-ns = <112>; - gpmc,access-ns = <81>; - gpmc,page-burst-access-ns = <15>; + gpmc,we-off-ns = <102>; + gpmc,rd-cycle-ns = <132>; + gpmc,wr-cycle-ns = <132>; + gpmc,access-ns = <96>; + gpmc,page-burst-access-ns = <18>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,wait-monitoring-ns = <0>; - gpmc,clk-activation-ns = <5>; - gpmc,wr-data-mux-bus-ns = <30>; - gpmc,wr-access-ns = <81>; + gpmc,clk-activation-ns = <6>; + gpmc,wr-data-mux-bus-ns = <36>; + gpmc,wr-access-ns = <96>; gpmc,sync-clk-ps = <15000>; /* --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi @@ -149,7 +149,7 @@ interrupt-parent = <&gpio4>; interrupts = <18 0>; /* gpio_114 */ - pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; ti,x-max = /bits/ 16 <0x0fff>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-overo-common-lcd43.dtsi @@ -160,7 +160,7 @@ interrupt-parent = <&gpio4>; interrupts = <18 0>; /* gpio_114 */ - pendown-gpio = <&gpio4 18 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio4 18 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; ti,x-max = /bits/ 16 <0x0fff>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi @@ -22,7 +22,7 @@ compatible = "smsc,lan9221","smsc,lan9115"; bank-width = <2>; - gpmc,mux-add-data; + gpmc,mux-add-data = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <42>; gpmc,cs-wr-off-ns = <36>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-pandora-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-pandora-common.dtsi @@ -226,6 +226,17 @@ gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>; /* GPIO_164 */ }; + /* wl1251 wifi+bt module */ + wlan_en: fixed-regulator-wg7210_en { + compatible = "regulator-fixed"; + regulator-name = "vwlan"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <50000>; + enable-active-high; + gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>; + }; + /* wg7210 (wifi+bt module) 32k clock buffer */ wg7210_32k: fixed-regulator-wg7210_32k { compatible = "regulator-fixed"; @@ -522,9 +533,30 @@ /*wp-gpios = <&gpio4 31 GPIO_ACTIVE_HIGH>;*/ /* GPIO_127 */ }; -/* mmc3 is probed using pdata-quirks to pass wl1251 card data */ &mmc3 { - status = "disabled"; + vmmc-supply = <&wlan_en>; + + bus-width = <4>; + non-removable; + ti,non-removable; + cap-power-off-card; + + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_pins>; + + #address-cells = <1>; + #size-cells = <0>; + + wlan: wifi@1 { + compatible = "ti,wl1251"; + + reg = <1>; + + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* GPIO_21 */ + + ti,wl1251-has-eeprom; + }; }; /* bluetooth*/ @@ -619,7 +651,7 @@ pinctrl-0 = <&penirq_pins>; interrupt-parent = <&gpio3>; interrupts = <30 IRQ_TYPE_NONE>; /* GPIO_94 */ - pendown-gpio = <&gpio3 30 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio3 30 GPIO_ACTIVE_LOW>; vcc-supply = <&vaux4>; ti,x-min = /bits/ 16 <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3-tao3530.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -222,7 +222,7 @@ pinctrl-0 = <&mmc1_pins>; vmmc-supply = <&vmmc1>; vqmmc-supply = <&vsim>; - cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_HIGH>; + cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>; bus-width = <8>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3.dtsi @@ -23,6 +23,9 @@ i2c0 = &i2c1; i2c1 = &i2c2; i2c2 = &i2c3; + mmc0 = &mmc1; + mmc1 = &mmc2; + mmc2 = &mmc3; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap3430-sdp.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap3430-sdp.dts @@ -101,7 +101,7 @@ nand@1,0 { compatible = "ti,omap2-nand"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + reg = <1 0 4>; /* CS1, offset 0, IO size 4 */ interrupt-parent = <&gpmc>; interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ <1 IRQ_TYPE_NONE>; /* termcount */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap4-droid4-xt894.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap4-droid4-xt894.dts @@ -656,12 +656,12 @@ /* Configure pwm clock source for timers 8 & 9 */ &timer8 { assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; - assigned-clock-parents = <&sys_clkin_ck>; + assigned-clock-parents = <&sys_32k_ck>; }; &timer9 { assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; - assigned-clock-parents = <&sys_clkin_ck>; + assigned-clock-parents = <&sys_32k_ck>; }; /* @@ -678,6 +678,7 @@ &uart3 { interrupts-extended = <&wakeupgen GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH &omap4_pmx_core 0x17c>; + overrun-throttle-ms = <500>; }; &uart4 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap4-duovero-parlor.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap4-duovero-parlor.dts @@ -139,7 +139,7 @@ ethernet@gpmc { reg = <5 0 0xff>; interrupt-parent = <&gpio2>; - interrupts = <12 IRQ_TYPE_EDGE_FALLING>; /* gpio_44 */ + interrupts = <12 IRQ_TYPE_LEVEL_LOW>; /* gpio_44 */ phy-mode = "mii"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap4-panda-es.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap4-panda-es.dts @@ -46,7 +46,7 @@ button_pins: pinmux_button_pins { pinctrl-single,pins = < - OMAP4_IOPAD(0x11b, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ + OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ >; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap4.dtsi @@ -22,6 +22,11 @@ i2c1 = &i2c2; i2c2 = &i2c3; i2c3 = &i2c4; + mmc0 = &mmc1; + mmc1 = &mmc2; + mmc2 = &mmc3; + mmc3 = &mmc4; + mmc4 = &mmc5; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; @@ -328,10 +333,10 @@ status = "disabled"; }; - target-module@56000000 { + sgx_module: target-module@56000000 { compatible = "ti,sysc-omap4", "ti,sysc"; - reg = <0x5601fc00 0x4>, - <0x5601fc10 0x4>; + reg = <0x5600fe00 0x4>, + <0x5600fe10 0x4>; reg-names = "rev", "sysc"; ti,sysc-midle = , , --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap443x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap443x.dtsi @@ -33,10 +33,12 @@ }; ocp { + /* 4430 has only gpio_86 tshut and no talert interrupt */ bandgap: bandgap@4a002260 { reg = <0x4a002260 0x4 0x4a00232C 0x4>; compatible = "ti,omap4430-bandgap"; + gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; #thermal-sensor-cells = <0>; }; @@ -74,3 +76,13 @@ }; /include/ "omap443x-clocks.dtsi" + +/* + * Use dpll_per for sgx at 153.6MHz like droid4 stock v3.0.8 Android kernel + */ +&sgx_module { + assigned-clocks = <&l3_gfx_clkctrl OMAP4_GPU_CLKCTRL 24>, + <&dpll_per_m7x2_ck>; + assigned-clock-rates = <0>, <153600000>; + assigned-clock-parents = <&dpll_per_m7x2_ck>; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap44xx-clocks.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap44xx-clocks.dtsi @@ -770,14 +770,6 @@ ti,max-div = <2>; }; - sha2md5_fck: sha2md5_fck@15c8 { - #clock-cells = <0>; - compatible = "ti,gate-clock"; - clocks = <&l3_div_ck>; - ti,bit-shift = <1>; - reg = <0x15c8>; - }; - usb_phy_cm_clk32k: usb_phy_cm_clk32k@640 { #clock-cells = <0>; compatible = "ti,gate-clock"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap5-board-common.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap5-board-common.dtsi @@ -30,14 +30,6 @@ regulator-max-microvolt = <5000000>; }; - vdds_1v8_main: fixedregulator-vdds_1v8_main { - compatible = "regulator-fixed"; - regulator-name = "vdds_1v8_main"; - vin-supply = <&smps7_reg>; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vmmcsd_fixed: fixedregulator-mmcsd { compatible = "regulator-fixed"; regulator-name = "vmmcsd_fixed"; @@ -487,6 +479,7 @@ regulator-boot-on; }; + vdds_1v8_main: smps7_reg: smps7 { /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */ regulator-name = "smps7"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap5-cm-t54.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap5-cm-t54.dts @@ -354,7 +354,7 @@ interrupt-parent = <&gpio1>; interrupts = <15 0>; /* gpio1_wk15 */ - pendown-gpio = <&gpio1 15 GPIO_ACTIVE_HIGH>; + pendown-gpio = <&gpio1 15 GPIO_ACTIVE_LOW>; ti,x-min = /bits/ 16 <0x0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/omap5.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/omap5.dtsi @@ -25,6 +25,11 @@ i2c2 = &i2c3; i2c3 = &i2c4; i2c4 = &i2c5; + mmc0 = &mmc1; + mmc1 = &mmc2; + mmc2 = &mmc3; + mmc3 = &mmc4; + mmc4 = &mmc5; serial0 = &uart1; serial1 = &uart2; serial2 = &uart3; @@ -143,6 +148,7 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0 0 0 0xc0000000>; + dma-ranges = <0x80000000 0x0 0x80000000 0x80000000>; ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3"; reg = <0 0x44000000 0 0x2000>, <0 0x44800000 0 0x3000>, --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/owl-s500.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/owl-s500.dtsi @@ -84,21 +84,21 @@ global_timer: timer@b0020200 { compatible = "arm,cortex-a9-global-timer"; reg = <0xb0020200 0x100>; - interrupts = ; + interrupts = ; status = "disabled"; }; twd_timer: timer@b0020600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xb0020600 0x20>; - interrupts = ; + interrupts = ; status = "disabled"; }; twd_wdt: wdt@b0020620 { compatible = "arm,cortex-a9-twd-wdt"; reg = <0xb0020620 0xe0>; - interrupts = ; + interrupts = ; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/ox810se.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/ox810se.dtsi @@ -323,8 +323,8 @@ interrupt-controller; reg = <0 0x200>; #interrupt-cells = <1>; - valid-mask = <0xFFFFFFFF>; - clear-mask = <0>; + valid-mask = <0xffffffff>; + clear-mask = <0xffffffff>; }; timer0: timer@200 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/ox820.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/ox820.dtsi @@ -240,8 +240,8 @@ reg = <0 0x200>; interrupts = ; #interrupt-cells = <1>; - valid-mask = <0xFFFFFFFF>; - clear-mask = <0>; + valid-mask = <0xffffffff>; + clear-mask = <0xffffffff>; }; timer0: timer@200 { @@ -287,7 +287,7 @@ clocks = <&armclk>; }; - gic: gic@1000 { + gic: interrupt-controller@1000 { compatible = "arm,arm11mp-gic"; interrupt-controller; #interrupt-cells = <3>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/picoxcell-pc3x2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/picoxcell-pc3x2.dtsi @@ -45,18 +45,21 @@ emac: gem@30000 { compatible = "cadence,gem"; reg = <0x30000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <31>; }; dmac1: dmac@40000 { compatible = "snps,dw-dmac"; reg = <0x40000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <25>; }; dmac2: dmac@50000 { compatible = "snps,dw-dmac"; reg = <0x50000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <26>; }; @@ -234,6 +237,7 @@ axi2pico@c0000000 { compatible = "picochip,axi2pico-pc3x2"; reg = <0xc0000000 0x10000>; + interrupt-parent = <&vic0>; interrupts = <13 14 15 16 17 18 19 20 21>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-apq8064.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -198,7 +198,7 @@ clock-frequency = <19200000>; }; - pxo_board { + pxo_board: pxo_board { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; @@ -759,7 +759,7 @@ xoadc: xoadc@197 { compatible = "qcom,pm8921-adc"; - reg = <197>; + reg = <0x197>; interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>; #address-cells = <2>; #size-cells = <0>; @@ -1147,7 +1147,7 @@ }; gpu: adreno-3xx@4300000 { - compatible = "qcom,adreno-3xx"; + compatible = "qcom,adreno-320.2", "qcom,adreno"; reg = <0x04300000 0x20000>; reg-names = "kgsl_3d0_reg_memory"; interrupts = ; @@ -1162,7 +1162,6 @@ <&mmcc GFX3D_AHB_CLK>, <&mmcc GFX3D_AXI_CLK>, <&mmcc MMSS_IMEM_AHB_CLK>; - qcom,chipid = <0x03020002>; iommus = <&gfx3d 0 &gfx3d 1 @@ -1261,9 +1260,9 @@ <&mmcc DSI1_BYTE_CLK>, <&mmcc DSI_PIXEL_CLK>, <&mmcc DSI1_ESC_CLK>; - clock-names = "iface_clk", "bus_clk", "core_mmss_clk", - "src_clk", "byte_clk", "pixel_clk", - "core_clk"; + clock-names = "iface", "bus", "core_mmss", + "src", "byte", "pixel", + "core"; assigned-clocks = <&mmcc DSI1_BYTE_SRC>, <&mmcc DSI1_ESC_SRC>, @@ -1305,7 +1304,7 @@ reg-names = "dsi_pll", "dsi_phy", "dsi_phy_regulator"; clock-names = "iface_clk", "ref"; clocks = <&mmcc DSI_M_AHB_CLK>, - <&cxo_board>; + <&pxo_board>; }; @@ -1571,7 +1570,7 @@ }; etb@1a01000 { - compatible = "coresight-etb10", "arm,primecell"; + compatible = "arm,coresight-etb10", "arm,primecell"; reg = <0x1a01000 0x1000>; clocks = <&rpmcc RPM_QDSS_CLK>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -141,7 +141,8 @@ clocks { sleep_clk: sleep_clk { compatible = "fixed-clock"; - clock-frequency = <32768>; + clock-frequency = <32000>; + clock-output-names = "gcc_sleep_clk_src"; #clock-cells = <0>; }; @@ -392,8 +393,8 @@ #address-cells = <3>; #size-cells = <2>; - ranges = <0x81000000 0 0x40200000 0x40200000 0 0x00100000>, - <0x82000000 0 0x40300000 0x40300000 0 0x00d00000>; + ranges = <0x81000000 0x0 0x00000000 0x40200000 0x0 0x00100000>, + <0x82000000 0x0 0x40300000 0x40300000 0x0 0x00d00000>; interrupts = ; interrupt-names = "msi"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -451,8 +451,8 @@ #address-cells = <3>; #size-cells = <2>; - ranges = <0x81000000 0 0x0fe00000 0x0fe00000 0 0x00100000 /* downstream I/O */ - 0x82000000 0 0x08000000 0x08000000 0 0x07e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x0fe00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x08000000 0x08000000 0x0 0x07e00000>; /* MEM */ interrupts = ; interrupt-names = "msi"; @@ -502,8 +502,8 @@ #address-cells = <3>; #size-cells = <2>; - ranges = <0x81000000 0 0x31e00000 0x31e00000 0 0x00100000 /* downstream I/O */ - 0x82000000 0 0x2e000000 0x2e000000 0 0x03e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x31e00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x2e000000 0x2e000000 0x0 0x03e00000>; /* MEM */ interrupts = ; interrupt-names = "msi"; @@ -553,8 +553,8 @@ #address-cells = <3>; #size-cells = <2>; - ranges = <0x81000000 0 0x35e00000 0x35e00000 0 0x00100000 /* downstream I/O */ - 0x82000000 0 0x32000000 0x32000000 0 0x03e00000>; /* non-prefetchable memory */ + ranges = <0x81000000 0x0 0x00000000 0x35e00000 0x0 0x00010000 /* I/O */ + 0x82000000 0x0 0x32000000 0x32000000 0x0 0x03e00000>; /* MEM */ interrupts = ; interrupt-names = "msi"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-mdm9615.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-mdm9615.dtsi @@ -82,14 +82,12 @@ }; }; - regulators { - vsdcc_fixed: vsdcc-regulator { - compatible = "regulator-fixed"; - regulator-name = "SDCC Power"; - regulator-min-microvolt = <2700000>; - regulator-max-microvolt = <2700000>; - regulator-always-on; - }; + vsdcc_fixed: vsdcc-regulator { + compatible = "regulator-fixed"; + regulator-name = "SDCC Power"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2700000>; + regulator-always-on; }; soc: soc { @@ -323,6 +321,7 @@ pmicgpio: gpio@150 { compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio"; + reg = <0x150>; interrupt-controller; #interrupt-cells = <2>; gpio-controller; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-msm8960.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-msm8960.dtsi @@ -145,7 +145,9 @@ reg = <0x108000 0x1000>; qcom,ipc = <&l2cc 0x8 2>; - interrupts = <0 19 0>, <0 21 0>, <0 22 0>; + interrupts = , + , + ; interrupt-names = "ack", "err", "wakeup"; regulators { @@ -191,7 +193,7 @@ compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; reg = <0x16440000 0x1000>, <0x16400000 0x1000>; - interrupts = <0 154 0x0>; + interrupts = ; clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>; clock-names = "core", "iface"; status = "disabled"; @@ -317,7 +319,7 @@ #address-cells = <1>; #size-cells = <0>; reg = <0x16080000 0x1000>; - interrupts = <0 147 0>; + interrupts = ; spi-max-frequency = <24000000>; cs-gpios = <&msmgpio 8 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-msm8974.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1213,8 +1213,8 @@ #phy-cells = <0>; qcom,dsi-phy-index = <0>; - clocks = <&mmcc MDSS_AHB_CLK>; - clock-names = "iface"; + clocks = <&mmcc MDSS_AHB_CLK>, <&xo_board>; + clock-names = "iface", "ref"; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/qcom-pm8841.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/qcom-pm8841.dtsi @@ -25,6 +25,7 @@ compatible = "qcom,spmi-temp-alarm"; reg = <0x2400>; interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a73a4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a73a4.dtsi @@ -131,7 +131,14 @@ cmt1: timer@e6130000 { compatible = "renesas,r8a73a4-cmt1", "renesas,rcar-gen2-cmt1"; reg = <0 0xe6130000 0 0x1004>; - interrupts = ; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7740.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7740.dtsi @@ -479,7 +479,7 @@ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7740-cpg-clocks"; reg = <0xe6150000 0x10000>; - clocks = <&extal1_clk>, <&extalr_clk>; + clocks = <&extal1_clk>, <&extal2_clk>, <&extalr_clk>; #clock-cells = <1>; clock-output-names = "system", "pllc0", "pllc1", "pllc2", "r", --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7743.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7743.dtsi @@ -338,7 +338,7 @@ #thermal-sensor-cells = <0>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -348,7 +348,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -357,7 +357,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -367,7 +367,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -376,7 +376,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -386,7 +386,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7743", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7744.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7744.dtsi @@ -338,7 +338,7 @@ #thermal-sensor-cells = <0>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -348,7 +348,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -357,7 +357,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -367,7 +367,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -376,7 +376,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -386,7 +386,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7744", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7745.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7745.dtsi @@ -302,7 +302,7 @@ resets = <&cpg 407>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -312,7 +312,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -321,7 +321,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -331,7 +331,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -340,7 +340,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -350,7 +350,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7745", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7779-marzen.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7779-marzen.dts @@ -146,7 +146,7 @@ status = "okay"; clocks = <&mstp1_clks R8A7779_CLK_DU>, <&x3_clk>; - clock-names = "du", "dclkin.0"; + clock-names = "du.0", "dclkin.0"; ports { port@0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7779.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7779.dtsi @@ -68,6 +68,14 @@ <0xf0000100 0x100>; }; + timer@f0000200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xf0000200 0x100>; + interrupts = ; + clocks = <&cpg_clocks R8A7779_CLK_ZS>; + }; + timer@f0000600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xf0000600 0x20>; @@ -455,6 +463,7 @@ reg = <0xfff80000 0x40000>; interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; + clock-names = "du.0"; power-domains = <&sysc R8A7779_PD_ALWAYS_ON>; status = "disabled"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7790.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7790.dtsi @@ -427,7 +427,7 @@ #thermal-sensor-cells = <0>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -437,7 +437,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -446,7 +446,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -456,7 +456,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -465,7 +465,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -475,7 +475,7 @@ status = "disabled"; }; - ipmmu_rt: mmu@ffc80000 { + ipmmu_rt: iommu@ffc80000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7791.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7791.dtsi @@ -350,7 +350,7 @@ #thermal-sensor-cells = <0>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -360,7 +360,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -369,7 +369,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -379,7 +379,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -388,7 +388,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -398,7 +398,7 @@ status = "disabled"; }; - ipmmu_rt: mmu@ffc80000 { + ipmmu_rt: iommu@ffc80000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; @@ -407,7 +407,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7793-gose.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7793-gose.dts @@ -339,7 +339,7 @@ reg = <0x20>; remote = <&vin1>; - port { + ports { #address-cells = <1>; #size-cells = <0>; @@ -399,7 +399,7 @@ interrupts = <2 IRQ_TYPE_LEVEL_LOW>; default-input = <0>; - port { + ports { #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7793.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7793.dtsi @@ -336,7 +336,7 @@ #thermal-sensor-cells = <0>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -346,7 +346,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -355,7 +355,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -365,7 +365,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -374,7 +374,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -384,7 +384,7 @@ status = "disabled"; }; - ipmmu_rt: mmu@ffc80000 { + ipmmu_rt: iommu@ffc80000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; @@ -393,7 +393,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/r8a7794.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/r8a7794.dtsi @@ -290,7 +290,7 @@ resets = <&cpg 407>; }; - ipmmu_sy0: mmu@e6280000 { + ipmmu_sy0: iommu@e6280000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; @@ -300,7 +300,7 @@ status = "disabled"; }; - ipmmu_sy1: mmu@e6290000 { + ipmmu_sy1: iommu@e6290000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; @@ -309,7 +309,7 @@ status = "disabled"; }; - ipmmu_ds: mmu@e6740000 { + ipmmu_ds: iommu@e6740000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; @@ -319,7 +319,7 @@ status = "disabled"; }; - ipmmu_mp: mmu@ec680000 { + ipmmu_mp: iommu@ec680000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; @@ -328,7 +328,7 @@ status = "disabled"; }; - ipmmu_mx: mmu@fe951000 { + ipmmu_mx: iommu@fe951000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; @@ -338,7 +338,7 @@ status = "disabled"; }; - ipmmu_gp: mmu@e62a0000 { + ipmmu_gp: iommu@e62a0000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3036-evb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3036-evb.dts @@ -31,7 +31,7 @@ &i2c1 { status = "okay"; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3036-kylin.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3036-kylin.dts @@ -300,8 +300,8 @@ &i2c2 { status = "okay"; - rt5616: rt5616@1b { - compatible = "rt5616"; + rt5616: audio-codec@1b { + compatible = "realtek,rt5616"; reg = <0x1b>; clocks = <&cru SCLK_I2S_OUT>; clock-names = "mclk"; @@ -390,7 +390,7 @@ }; }; - sleep { + suspend { global_pwroff: global-pwroff { rockchip,pins = <2 RK_PA7 1 &pcfg_pull_none>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3036.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3036.dtsi @@ -128,7 +128,7 @@ assigned-clocks = <&cru SCLK_GPU>; assigned-clock-rates = <100000000>; clocks = <&cru SCLK_GPU>, <&cru SCLK_GPU>; - clock-names = "core", "bus"; + clock-names = "bus", "core"; resets = <&cru SRST_GPU>; status = "disabled"; }; @@ -317,12 +317,13 @@ }; }; - acodec: acodec-ana@20030000 { - compatible = "rk3036-codec"; + acodec: audio-codec@20030000 { + compatible = "rockchip,rk3036-codec"; reg = <0x20030000 0x4000>; - rockchip,grf = <&grf>; clock-names = "acodec_pclk"; clocks = <&cru PCLK_ACODEC>; + rockchip,grf = <&grf>; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -332,17 +333,24 @@ interrupts = ; clocks = <&cru PCLK_HDMI>; clock-names = "pclk"; - rockchip,grf = <&grf>; pinctrl-names = "default"; pinctrl-0 = <&hdmi_ctl>; status = "disabled"; - hdmi_in: port { + ports { #address-cells = <1>; #size-cells = <0>; - hdmi_in_vop: endpoint@0 { + + hdmi_in: port@0 { reg = <0>; - remote-endpoint = <&vop_out_hdmi>; + + hdmi_in_vop: endpoint { + remote-endpoint = <&vop_out_hdmi>; + }; + }; + + hdmi_out: port@1 { + reg = <1>; }; }; }; @@ -481,11 +489,11 @@ }; spi: spi@20074000 { - compatible = "rockchip,rockchip-spi"; + compatible = "rockchip,rk3036-spi"; reg = <0x20074000 0x1000>; interrupts = ; - clocks = <&cru PCLK_SPI>, <&cru SCLK_SPI>; - clock-names = "apb-pclk","spi_pclk"; + clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>; + clock-names = "spiclk", "apb_pclk"; dmas = <&pdma 8>, <&pdma 9>; dma-names = "tx", "rx"; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3066a.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3066a.dtsi @@ -124,6 +124,7 @@ pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>; power-domains = <&power RK3066_PD_VIO>; rockchip,grf = <&grf>; + #sound-dai-cells = <0>; status = "disabled"; ports { @@ -761,7 +762,7 @@ #address-cells = <1>; #size-cells = <0>; - pd_vio@RK3066_PD_VIO { + power-domain@RK3066_PD_VIO { reg = ; clocks = <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>, @@ -788,7 +789,7 @@ <&qos_rga>; }; - pd_video@RK3066_PD_VIDEO { + power-domain@RK3066_PD_VIDEO { reg = ; clocks = <&cru ACLK_VDPU>, <&cru ACLK_VEPU>, @@ -797,7 +798,7 @@ pm_qos = <&qos_vpu>; }; - pd_gpu@RK3066_PD_GPU { + power-domain@RK3066_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3188-bqedison2qc.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3188-bqedison2qc.dts @@ -58,20 +58,25 @@ lvds-encoder { compatible = "ti,sn75lvds83", "lvds-encoder"; - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - lvds_in_vop0: endpoint { - remote-endpoint = <&vop0_out_lvds>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lvds_in_vop0: endpoint { + remote-endpoint = <&vop0_out_lvds>; + }; }; - }; - port@1 { - reg = <1>; - lvds_out_panel: endpoint { - remote-endpoint = <&panel_in_lvds>; + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; }; }; }; @@ -465,10 +470,13 @@ non-removable; pinctrl-names = "default"; pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>; - vmmcq-supply = <&vccio_wl>; + vqmmc-supply = <&vccio_wl>; + #address-cells = <1>; + #size-cells = <0>; status = "okay"; brcmf: wifi@1 { + reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio3>; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3188-radxarock.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3188-radxarock.dts @@ -67,7 +67,7 @@ #sound-dai-cells = <0>; }; - ir_recv: gpio-ir-receiver { + ir_recv: ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3188.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3188.dtsi @@ -150,16 +150,16 @@ compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; reg = <0x2000e000 0x20>; interrupts = ; - clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER3>, <&cru SCLK_TIMER3>; + clock-names = "pclk", "timer"; }; timer6: timer@200380a0 { compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; reg = <0x200380a0 0x20>; interrupts = ; - clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER6>; + clock-names = "pclk", "timer"; }; i2s0: i2s@1011a000 { @@ -404,7 +404,7 @@ rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>; }; - lcdc1_rgb24: ldcd1-rgb24 { + lcdc1_rgb24: lcdc1-rgb24 { rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, <2 RK_PA1 1 &pcfg_pull_none>, <2 RK_PA2 1 &pcfg_pull_none>, @@ -632,7 +632,6 @@ &global_timer { interrupts = ; - status = "disabled"; }; &local_timer { @@ -701,7 +700,7 @@ #address-cells = <1>; #size-cells = <0>; - pd_vio@RK3188_PD_VIO { + power-domain@RK3188_PD_VIO { reg = ; clocks = <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>, @@ -723,7 +722,7 @@ <&qos_rga>; }; - pd_video@RK3188_PD_VIDEO { + power-domain@RK3188_PD_VIDEO { reg = ; clocks = <&cru ACLK_VDPU>, <&cru ACLK_VEPU>, @@ -732,7 +731,7 @@ pm_qos = <&qos_vpu>; }; - pd_gpu@RK3188_PD_GPU { + power-domain@RK3188_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3228-evb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3228-evb.dts @@ -46,7 +46,7 @@ #address-cells = <1>; #size-cells = <0>; - phy: phy@0 { + phy: ethernet-phy@0 { compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; reg = <0>; clocks = <&cru SCLK_MAC_PHY>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3229-xms6.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3229-xms6.dts @@ -150,7 +150,7 @@ #address-cells = <1>; #size-cells = <0>; - phy: phy@0 { + phy: ethernet-phy@0 { compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22"; reg = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk322x.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk322x.dtsi @@ -561,7 +561,7 @@ "pp1", "ppmmu1"; clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; - clock-names = "core", "bus"; + clock-names = "bus", "core"; resets = <&cru SRST_GPU_A>; status = "disabled"; }; @@ -570,10 +570,9 @@ compatible = "rockchip,iommu"; reg = <0x20020800 0x100>; interrupts = ; - interrupt-names = "vpu_mmu"; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; @@ -581,10 +580,9 @@ compatible = "rockchip,iommu"; reg = <0x20030480 0x40>, <0x200304c0 0x40>; interrupts = ; - interrupt-names = "vdec_mmu"; clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; @@ -614,7 +612,6 @@ compatible = "rockchip,iommu"; reg = <0x20053f00 0x100>; interrupts = ; - interrupt-names = "vop_mmu"; clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; clock-names = "aclk", "iface"; #iommu-cells = <0>; @@ -625,10 +622,9 @@ compatible = "rockchip,iommu"; reg = <0x20070800 0x100>; interrupts = ; - interrupt-names = "iep_mmu"; clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; @@ -639,8 +635,8 @@ interrupts = ; assigned-clocks = <&cru SCLK_HDMI_PHY>; assigned-clock-parents = <&hdmi_phy>; - clocks = <&cru SCLK_HDMI_HDCP>, <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_CEC>; - clock-names = "isfr", "iahb", "cec"; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>; + clock-names = "iahb", "isfr", "cec"; pinctrl-names = "default"; pinctrl-0 = <&hdmii2c_xfer &hdmi_hpd &hdmi_cec>; resets = <&cru SRST_HDMI_P>; @@ -1033,7 +1029,7 @@ }; }; - spi-0 { + spi0 { spi0_clk: spi0-clk { rockchip,pins = <0 RK_PB1 2 &pcfg_pull_up>; }; @@ -1051,7 +1047,7 @@ }; }; - spi-1 { + spi1 { spi1_clk: spi1-clk { rockchip,pins = <0 RK_PC7 2 &pcfg_pull_up>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-evb-act8846.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-evb-act8846.dts @@ -53,7 +53,7 @@ vin-supply = <&vcc_sys>; }; - hym8563@51 { + rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-firefly.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -233,7 +233,7 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-miqi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-miqi.dts @@ -145,7 +145,7 @@ vin-supply = <&vcc_sys>; }; - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -218,7 +218,7 @@ flash0-supply = <&vcc_flash>; flash1-supply = <&vccio_pmu>; gpio30-supply = <&vccio_pmu>; - gpio1830 = <&vcc_io>; + gpio1830-supply = <&vcc_io>; lcdc-supply = <&vcc_io>; sdcard-supply = <&vccio_sd>; wifi-supply = <&vcc_18>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-rock2-square.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -165,7 +165,7 @@ }; &i2c0 { - hym8563: hym8563@51 { + hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288-vyasa.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288-vyasa.dts @@ -357,10 +357,10 @@ audio-supply = <&vcc_18>; bb-supply = <&vcc_io>; dvp-supply = <&vcc_io>; - flash0-suuply = <&vcc_18>; + flash0-supply = <&vcc_18>; flash1-supply = <&vcc_lan>; gpio30-supply = <&vcc_io>; - gpio1830 = <&vcc_io>; + gpio1830-supply = <&vcc_io>; lcdc-supply = <&vcc_io>; sdcard-supply = <&vccio_sd>; wifi-supply = <&vcc_18>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3288.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3288.dtsi @@ -238,8 +238,8 @@ compatible = "rockchip,rk3288-timer"; reg = <0x0 0xff810000 0x0 0x20>; interrupts = ; - clocks = <&xin24m>, <&cru PCLK_TIMER>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER>, <&xin24m>; + clock-names = "pclk", "timer"; }; display-subsystem { @@ -771,7 +771,7 @@ * *_HDMI HDMI * *_MIPI_* MIPI */ - pd_vio@RK3288_PD_VIO { + power-domain@RK3288_PD_VIO { reg = ; clocks = <&cru ACLK_IEP>, <&cru ACLK_ISP>, @@ -813,7 +813,7 @@ * Note: The following 3 are HEVC(H.265) clocks, * and on the ACLK_HEVC_NIU (NOC). */ - pd_hevc@RK3288_PD_HEVC { + power-domain@RK3288_PD_HEVC { reg = ; clocks = <&cru ACLK_HEVC>, <&cru SCLK_HEVC_CABAC>, @@ -827,7 +827,7 @@ * (video endecoder & decoder) clocks that on the * ACLK_VCODEC_NIU and HCLK_VCODEC_NIU (NOC). */ - pd_video@RK3288_PD_VIDEO { + power-domain@RK3288_PD_VIDEO { reg = ; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; @@ -838,7 +838,7 @@ * Note: ACLK_GPU is the GPU clock, * and on the ACLK_GPU_NIU (NOC). */ - pd_gpu@RK3288_PD_GPU { + power-domain@RK3288_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu_r>, @@ -942,7 +942,7 @@ status = "disabled"; }; - spdif: sound@ff88b0000 { + spdif: sound@ff8b0000 { compatible = "rockchip,rk3288-spdif", "rockchip,rk3066-spdif"; reg = <0x0 0xff8b0000 0x0 0x10000>; #sound-dai-cells = <0>; @@ -975,7 +975,7 @@ status = "disabled"; }; - crypto: cypto-controller@ff8a0000 { + crypto: crypto@ff8a0000 { compatible = "rockchip,rk3288-crypto"; reg = <0x0 0xff8a0000 0x0 0x4000>; interrupts = ; @@ -1188,6 +1188,7 @@ clock-names = "dp", "pclk"; phys = <&edp_phy>; phy-names = "dp"; + power-domains = <&power RK3288_PD_VIO>; resets = <&cru SRST_EDP>; reset-names = "dp"; rockchip,grf = <&grf>; @@ -1575,7 +1576,7 @@ drive-strength = <12>; }; - sleep { + suspend { global_pwroff: global-pwroff { rockchip,pins = <0 RK_PA0 1 &pcfg_pull_none>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/rk3xxx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/rk3xxx.dtsi @@ -84,7 +84,7 @@ compatible = "arm,mali-400"; reg = <0x10090000 0x10000>; clocks = <&cru ACLK_GPU>, <&cru ACLK_GPU>; - clock-names = "core", "bus"; + clock-names = "bus", "core"; assigned-clocks = <&cru ACLK_GPU>; assigned-clock-rates = <100000000>; resets = <&cru SRST_GPU>; @@ -108,6 +108,13 @@ reg = <0x1013c200 0x20>; interrupts = ; clocks = <&cru CORE_PERI>; + status = "disabled"; + /* The clock source and the sched_clock provided by the arm_global_timer + * on Rockchip rk3066a/rk3188 are quite unstable because their rates + * depend on the CPU frequency. + * Keep the arm_global_timer disabled in order to have the + * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default. + */ }; local_timer: local-timer@1013c600 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s3c6410-mini6410.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/s3c6410-mini6410.dts @@ -28,29 +28,21 @@ bootargs = "console=ttySAC0,115200n8 earlyprintk rootwait root=/dev/mmcblk0p1"; }; - clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - fin_pll: oscillator@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <12000000>; - clock-output-names = "fin_pll"; - #clock-cells = <0>; - }; + fin_pll: oscillator-0 { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; - xusbxti: oscillator@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-output-names = "xusbxti"; - clock-frequency = <48000000>; - #clock-cells = <0>; - }; + xusbxti: oscillator-1 { + compatible = "fixed-clock"; + clock-output-names = "xusbxti"; + clock-frequency = <48000000>; + #clock-cells = <0>; }; - srom-cs1@18000000 { + srom-cs1-bus@18000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -59,7 +51,7 @@ ethernet@18000000 { compatible = "davicom,dm9000"; - reg = <0x18000000 0x2 0x18000004 0x2>; + reg = <0x18000000 0x2>, <0x18000004 0x2>; interrupt-parent = <&gpn>; interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; davicom,no-eeprom; @@ -165,6 +157,10 @@ }; }; +&clocks { + clocks = <&fin_pll>; +}; + &sdhci0 { pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; @@ -197,12 +193,12 @@ }; &pinctrl0 { - gpio_leds: gpio-leds { + gpio_leds: gpio-leds-pins { samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7"; samsung,pin-pud = ; }; - gpio_keys: gpio-keys { + gpio_keys: gpio-keys-pins { samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3", "gpn-4", "gpn-5", "gpl-11", "gpl-12"; samsung,pin-pud = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s3c6410-smdk6410.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/s3c6410-smdk6410.dts @@ -69,6 +69,10 @@ }; }; +&clocks { + clocks = <&fin_pll>; +}; + &sdhci0 { pinctrl-names = "default"; pinctrl-0 = <&sd0_clk>, <&sd0_cmd>, <&sd0_cd>, <&sd0_bus4>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi @@ -16,111 +16,111 @@ * Pin banks */ - gpa: gpa { + gpa: gpa-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpb: gpb { + gpb: gpb-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpc: gpc { + gpc: gpc-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpd: gpd { + gpd: gpd-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpe: gpe { + gpe: gpe-gpio-bank { gpio-controller; #gpio-cells = <2>; }; - gpf: gpf { + gpf: gpf-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpg: gpg { + gpg: gpg-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gph: gph { + gph: gph-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpi: gpi { + gpi: gpi-gpio-bank { gpio-controller; #gpio-cells = <2>; }; - gpj: gpj { + gpj: gpj-gpio-bank { gpio-controller; #gpio-cells = <2>; }; - gpk: gpk { + gpk: gpk-gpio-bank { gpio-controller; #gpio-cells = <2>; }; - gpl: gpl { + gpl: gpl-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpm: gpm { + gpm: gpm-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpn: gpn { + gpn: gpn-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpo: gpo { + gpo: gpo-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpp: gpp { + gpp: gpp-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; }; - gpq: gpq { + gpq: gpq-gpio-bank { gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -131,225 +131,225 @@ * Pin groups */ - uart0_data: uart0-data { + uart0_data: uart0-data-pins { samsung,pins = "gpa-0", "gpa-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - uart0_fctl: uart0-fctl { + uart0_fctl: uart0-fctl-pins { samsung,pins = "gpa-2", "gpa-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - uart1_data: uart1-data { + uart1_data: uart1-data-pins { samsung,pins = "gpa-4", "gpa-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - uart1_fctl: uart1-fctl { + uart1_fctl: uart1-fctl-pins { samsung,pins = "gpa-6", "gpa-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - uart2_data: uart2-data { + uart2_data: uart2-data-pins { samsung,pins = "gpb-0", "gpb-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - uart3_data: uart3-data { + uart3_data: uart3-data-pins { samsung,pins = "gpb-2", "gpb-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - ext_dma_0: ext-dma-0 { + ext_dma_0: ext-dma-0-pins { samsung,pins = "gpb-0", "gpb-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - ext_dma_1: ext-dma-1 { + ext_dma_1: ext-dma-1-pins { samsung,pins = "gpb-2", "gpb-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - irda_data_0: irda-data-0 { + irda_data_0: irda-data-0-pins { samsung,pins = "gpb-0", "gpb-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - irda_data_1: irda-data-1 { + irda_data_1: irda-data-1-pins { samsung,pins = "gpb-2", "gpb-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - irda_sdbw: irda-sdbw { + irda_sdbw: irda-sdbw-pins { samsung,pins = "gpb-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2c0_bus: i2c0-bus { + i2c0_bus: i2c0-bus-pins { samsung,pins = "gpb-5", "gpb-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2c1_bus: i2c1-bus { + i2c1_bus: i2c1-bus-pins { /* S3C6410-only */ samsung,pins = "gpb-2", "gpb-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - spi0_bus: spi0-bus { + spi0_bus: spi0-bus-pins { samsung,pins = "gpc-0", "gpc-1", "gpc-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - spi0_cs: spi0-cs { + spi0_cs: spi0-cs-pins { samsung,pins = "gpc-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - spi1_bus: spi1-bus { + spi1_bus: spi1-bus-pins { samsung,pins = "gpc-4", "gpc-5", "gpc-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - spi1_cs: spi1-cs { + spi1_cs: spi1-cs-pins { samsung,pins = "gpc-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd0_cmd: sd0-cmd { + sd0_cmd: sd0-cmd-pins { samsung,pins = "gpg-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd0_clk: sd0-clk { + sd0_clk: sd0-clk-pins { samsung,pins = "gpg-0"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd0_bus1: sd0-bus1 { + sd0_bus1: sd0-bus1-pins { samsung,pins = "gpg-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd0_bus4: sd0-bus4 { + sd0_bus4: sd0-bus4-pins { samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd0_cd: sd0-cd { + sd0_cd: sd0-cd-pins { samsung,pins = "gpg-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_cmd: sd1-cmd { + sd1_cmd: sd1-cmd-pins { samsung,pins = "gph-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_clk: sd1-clk { + sd1_clk: sd1-clk-pins { samsung,pins = "gph-0"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_bus1: sd1-bus1 { + sd1_bus1: sd1-bus1-pins { samsung,pins = "gph-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_bus4: sd1-bus4 { + sd1_bus4: sd1-bus4-pins { samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_bus8: sd1-bus8 { + sd1_bus8: sd1-bus8-pins { samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5", "gph-6", "gph-7", "gph-8", "gph-9"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd1_cd: sd1-cd { + sd1_cd: sd1-cd-pins { samsung,pins = "gpg-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd2_cmd: sd2-cmd { + sd2_cmd: sd2-cmd-pins { samsung,pins = "gpc-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd2_clk: sd2-clk { + sd2_clk: sd2-clk-pins { samsung,pins = "gpc-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd2_bus1: sd2-bus1 { + sd2_bus1: sd2-bus1-pins { samsung,pins = "gph-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - sd2_bus4: sd2-bus4 { + sd2_bus4: sd2-bus4-pins { samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2s0_bus: i2s0-bus { + i2s0_bus: i2s0-bus-pins { samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2s0_cdclk: i2s0-cdclk { + i2s0_cdclk: i2s0-cdclk-pins { samsung,pins = "gpd-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2s1_bus: i2s1-bus { + i2s1_bus: i2s1-bus-pins { samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2s1_cdclk: i2s1-cdclk { + i2s1_cdclk: i2s1-cdclk-pins { samsung,pins = "gpe-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - i2s2_bus: i2s2-bus { + i2s2_bus: i2s2-bus-pins { /* S3C6410-only */ samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6", "gph-8", "gph-9"; @@ -357,50 +357,50 @@ samsung,pin-pud = ; }; - i2s2_cdclk: i2s2-cdclk { + i2s2_cdclk: i2s2-cdclk-pins { /* S3C6410-only */ samsung,pins = "gph-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - pcm0_bus: pcm0-bus { + pcm0_bus: pcm0-bus-pins { samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - pcm0_extclk: pcm0-extclk { + pcm0_extclk: pcm0-extclk-pins { samsung,pins = "gpd-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - pcm1_bus: pcm1-bus { + pcm1_bus: pcm1-bus-pins { samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - pcm1_extclk: pcm1-extclk { + pcm1_extclk: pcm1-extclk-pins { samsung,pins = "gpe-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - ac97_bus_0: ac97-bus-0 { + ac97_bus_0: ac97-bus-0-pins { samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - ac97_bus_1: ac97-bus-1 { + ac97_bus_1: ac97-bus-1-pins { samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - cam_port: cam-port { + cam_port: cam-port-pins { samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4", "gpf-5", "gpf-6", "gpf-7", "gpf-8", "gpf-9", "gpf-10", "gpf-11", "gpf-12"; @@ -408,242 +408,242 @@ samsung,pin-pud = ; }; - cam_rst: cam-rst { + cam_rst: cam-rst-pins { samsung,pins = "gpf-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - cam_field: cam-field { + cam_field: cam-field-pins { /* S3C6410-only */ samsung,pins = "gpb-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - pwm_extclk: pwm-extclk { + pwm_extclk: pwm-extclk-pins { samsung,pins = "gpf-13"; samsung,pin-function = ; samsung,pin-pud = ; }; - pwm0_out: pwm0-out { + pwm0_out: pwm0-out-pins { samsung,pins = "gpf-14"; samsung,pin-function = ; samsung,pin-pud = ; }; - pwm1_out: pwm1-out { + pwm1_out: pwm1-out-pins { samsung,pins = "gpf-15"; samsung,pin-function = ; samsung,pin-pud = ; }; - clkout0: clkout-0 { + clkout0: clkout-0-pins { samsung,pins = "gpf-14"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col0_0: keypad-col0-0 { + keypad_col0_0: keypad-col0-0-pins { samsung,pins = "gph-0"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col1_0: keypad-col1-0 { + keypad_col1_0: keypad-col1-0-pins { samsung,pins = "gph-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col2_0: keypad-col2-0 { + keypad_col2_0: keypad-col2-0-pins { samsung,pins = "gph-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col3_0: keypad-col3-0 { + keypad_col3_0: keypad-col3-0-pins { samsung,pins = "gph-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col4_0: keypad-col4-0 { + keypad_col4_0: keypad-col4-0-pins { samsung,pins = "gph-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col5_0: keypad-col5-0 { + keypad_col5_0: keypad-col5-0-pins { samsung,pins = "gph-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col6_0: keypad-col6-0 { + keypad_col6_0: keypad-col6-0-pins { samsung,pins = "gph-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col7_0: keypad-col7-0 { + keypad_col7_0: keypad-col7-0-pins { samsung,pins = "gph-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col0_1: keypad-col0-1 { + keypad_col0_1: keypad-col0-1-pins { samsung,pins = "gpl-0"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col1_1: keypad-col1-1 { + keypad_col1_1: keypad-col1-1-pins { samsung,pins = "gpl-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col2_1: keypad-col2-1 { + keypad_col2_1: keypad-col2-1-pins { samsung,pins = "gpl-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col3_1: keypad-col3-1 { + keypad_col3_1: keypad-col3-1-pins { samsung,pins = "gpl-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col4_1: keypad-col4-1 { + keypad_col4_1: keypad-col4-1-pins { samsung,pins = "gpl-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col5_1: keypad-col5-1 { + keypad_col5_1: keypad-col5-1-pins { samsung,pins = "gpl-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col6_1: keypad-col6-1 { + keypad_col6_1: keypad-col6-1-pins { samsung,pins = "gpl-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_col7_1: keypad-col7-1 { + keypad_col7_1: keypad-col7-1-pins { samsung,pins = "gpl-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row0_0: keypad-row0-0 { + keypad_row0_0: keypad-row0-0-pins { samsung,pins = "gpk-8"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row1_0: keypad-row1-0 { + keypad_row1_0: keypad-row1-0-pins { samsung,pins = "gpk-9"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row2_0: keypad-row2-0 { + keypad_row2_0: keypad-row2-0-pins { samsung,pins = "gpk-10"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row3_0: keypad-row3-0 { + keypad_row3_0: keypad-row3-0-pins { samsung,pins = "gpk-11"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row4_0: keypad-row4-0 { + keypad_row4_0: keypad-row4-0-pins { samsung,pins = "gpk-12"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row5_0: keypad-row5-0 { + keypad_row5_0: keypad-row5-0-pins { samsung,pins = "gpk-13"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row6_0: keypad-row6-0 { + keypad_row6_0: keypad-row6-0-pins { samsung,pins = "gpk-14"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row7_0: keypad-row7-0 { + keypad_row7_0: keypad-row7-0-pins { samsung,pins = "gpk-15"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row0_1: keypad-row0-1 { + keypad_row0_1: keypad-row0-1-pins { samsung,pins = "gpn-0"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row1_1: keypad-row1-1 { + keypad_row1_1: keypad-row1-1-pins { samsung,pins = "gpn-1"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row2_1: keypad-row2-1 { + keypad_row2_1: keypad-row2-1-pins { samsung,pins = "gpn-2"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row3_1: keypad-row3-1 { + keypad_row3_1: keypad-row3-1-pins { samsung,pins = "gpn-3"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row4_1: keypad-row4-1 { + keypad_row4_1: keypad-row4-1-pins { samsung,pins = "gpn-4"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row5_1: keypad-row5-1 { + keypad_row5_1: keypad-row5-1-pins { samsung,pins = "gpn-5"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row6_1: keypad-row6-1 { + keypad_row6_1: keypad-row6-1-pins { samsung,pins = "gpn-6"; samsung,pin-function = ; samsung,pin-pud = ; }; - keypad_row7_1: keypad-row7-1 { + keypad_row7_1: keypad-row7-1-pins { samsung,pins = "gpn-7"; samsung,pin-function = ; samsung,pin-pud = ; }; - lcd_ctrl: lcd-ctrl { + lcd_ctrl: lcd-ctrl-pins { samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11"; samsung,pin-function = ; samsung,pin-pud = ; }; - lcd_data16: lcd-data-width16 { + lcd_data16: lcd-data-width16-pins { samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6", "gpi-7", "gpi-10", "gpi-11", "gpi-12", "gpi-13", "gpi-14", "gpi-15", "gpj-3", @@ -652,7 +652,7 @@ samsung,pin-pud = ; }; - lcd_data18: lcd-data-width18 { + lcd_data18: lcd-data-width18-pins { samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5", "gpi-6", "gpi-7", "gpi-10", "gpi-11", "gpi-12", "gpi-13", "gpi-14", "gpi-15", @@ -662,7 +662,7 @@ samsung,pin-pud = ; }; - lcd_data24: lcd-data-width24 { + lcd_data24: lcd-data-width24-pins { samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3", "gpi-4", "gpi-5", "gpi-6", "gpi-7", "gpi-8", "gpi-9", "gpi-10", "gpi-11", @@ -673,7 +673,7 @@ samsung,pin-pud = ; }; - hsi_bus: hsi-bus { + hsi_bus: hsi-bus-pins { samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3", "gpk-4", "gpk-5", "gpk-6", "gpk-7"; samsung,pin-function = ; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s5pv210-aries.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/s5pv210-aries.dtsi @@ -454,6 +454,7 @@ pinctrl-names = "default"; cap-sd-highspeed; cap-mmc-highspeed; + keep-power-in-suspend; mmc-pwrseq = <&wifi_pwrseq>; non-removable; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -15,6 +15,7 @@ */ /dts-v1/; +#include #include #include "s5pv210.dtsi" @@ -31,11 +32,18 @@ reg = <0x20000000 0x40000000>; }; - ethernet@18000000 { + pmic_ap_clk: clock-0 { + /* Workaround for missing PMIC and its clock */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + ethernet@a8000000 { compatible = "davicom,dm9000"; - reg = <0xA8000000 0x2 0xA8000002 0x2>; + reg = <0xa8000000 0x2>, <0xa8000002 0x2>; interrupt-parent = <&gph1>; - interrupts = <1 4>; + interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; local-mac-address = [00 00 de ad be ef]; davicom,no-eeprom; }; @@ -47,6 +55,14 @@ default-brightness-level = <6>; pinctrl-names = "default"; pinctrl-0 = <&pwm3_out>; + power-supply = <&dc5v_reg>; + }; + + dc5v_reg: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "DC5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; }; }; @@ -147,6 +163,8 @@ &rtc { status = "okay"; + clocks = <&clocks CLK_RTC>, <&pmic_ap_clk>; + clock-names = "rtc", "rtc_src"; }; &sdhci0 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/s5pv210.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/s5pv210.dtsi @@ -52,34 +52,26 @@ }; }; + xxti: oscillator-0 { + compatible = "fixed-clock"; + clock-frequency = <0>; + clock-output-names = "xxti"; + #clock-cells = <0>; + }; + + xusbxti: oscillator-1 { + compatible = "fixed-clock"; + clock-frequency = <0>; + clock-output-names = "xusbxti"; + #clock-cells = <0>; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; - external-clocks { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - xxti: oscillator@0 { - compatible = "fixed-clock"; - reg = <0>; - clock-frequency = <0>; - clock-output-names = "xxti"; - #clock-cells = <0>; - }; - - xusbxti: oscillator@1 { - compatible = "fixed-clock"; - reg = <1>; - clock-frequency = <0>; - clock-output-names = "xusbxti"; - #clock-cells = <0>; - }; - }; - onenand: onenand@b0600000 { compatible = "samsung,s5pv210-onenand"; reg = <0xb0600000 0x2000>, @@ -100,19 +92,16 @@ }; clocks: clock-controller@e0100000 { - compatible = "samsung,s5pv210-clock", "simple-bus"; + compatible = "samsung,s5pv210-clock"; reg = <0xe0100000 0x10000>; clock-names = "xxti", "xusbxti"; clocks = <&xxti>, <&xusbxti>; #clock-cells = <1>; - #address-cells = <1>; - #size-cells = <1>; - ranges; + }; - pmu_syscon: syscon@e0108000 { - compatible = "samsung-s5pv210-pmu", "syscon"; - reg = <0xe0108000 0x8000>; - }; + pmu_syscon: syscon@e0108000 { + compatible = "samsung-s5pv210-pmu", "syscon"; + reg = <0xe0108000 0x8000>; }; pinctrl0: pinctrl@e0200000 { @@ -128,35 +117,28 @@ }; }; - amba { - #address-cells = <1>; - #size-cells = <1>; - compatible = "simple-bus"; - ranges; - - pdma0: dma@e0900000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0xe0900000 0x1000>; - interrupt-parent = <&vic0>; - interrupts = <19>; - clocks = <&clocks CLK_PDMA0>; - clock-names = "apb_pclk"; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; - }; + pdma0: dma@e0900000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xe0900000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <19>; + clocks = <&clocks CLK_PDMA0>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; + }; - pdma1: dma@e0a00000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0xe0a00000 0x1000>; - interrupt-parent = <&vic0>; - interrupts = <20>; - clocks = <&clocks CLK_PDMA1>; - clock-names = "apb_pclk"; - #dma-cells = <1>; - #dma-channels = <8>; - #dma-requests = <32>; - }; + pdma1: dma@e0a00000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0xe0a00000 0x1000>; + interrupt-parent = <&vic0>; + interrupts = <20>; + clocks = <&clocks CLK_PDMA1>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + #dma-channels = <8>; + #dma-requests = <32>; }; spi0: spi@e1300000 { @@ -229,43 +211,36 @@ status = "disabled"; }; - audio-subsystem { - compatible = "samsung,s5pv210-audss", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - clk_audss: clock-controller@eee10000 { - compatible = "samsung,s5pv210-audss-clock"; - reg = <0xeee10000 0x1000>; - clock-names = "hclk", "xxti", - "fout_epll", - "sclk_audio0"; - clocks = <&clocks DOUT_HCLKP>, <&xxti>, - <&clocks FOUT_EPLL>, - <&clocks SCLK_AUDIO0>; - #clock-cells = <1>; - }; + clk_audss: clock-controller@eee10000 { + compatible = "samsung,s5pv210-audss-clock"; + reg = <0xeee10000 0x1000>; + clock-names = "hclk", "xxti", + "fout_epll", + "sclk_audio0"; + clocks = <&clocks DOUT_HCLKP>, <&xxti>, + <&clocks FOUT_EPLL>, + <&clocks SCLK_AUDIO0>; + #clock-cells = <1>; + }; - i2s0: i2s@eee30000 { - compatible = "samsung,s5pv210-i2s"; - reg = <0xeee30000 0x1000>; - interrupt-parent = <&vic2>; - interrupts = <16>; - dma-names = "rx", "tx", "tx-sec"; - dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>; - clock-names = "iis", - "i2s_opclk0", - "i2s_opclk1"; - clocks = <&clk_audss CLK_I2S>, - <&clk_audss CLK_I2S>, - <&clk_audss CLK_DOUT_AUD_BUS>; - samsung,idma-addr = <0xc0010000>; - pinctrl-names = "default"; - pinctrl-0 = <&i2s0_bus>; - #sound-dai-cells = <0>; - status = "disabled"; - }; + i2s0: i2s@eee30000 { + compatible = "samsung,s5pv210-i2s"; + reg = <0xeee30000 0x1000>; + interrupt-parent = <&vic2>; + interrupts = <16>; + dma-names = "rx", "tx", "tx-sec"; + dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>; + clock-names = "iis", + "i2s_opclk0", + "i2s_opclk1"; + clocks = <&clk_audss CLK_I2S>, + <&clk_audss CLK_I2S>, + <&clk_audss CLK_DOUT_AUD_BUS>; + samsung,idma-addr = <0xc0010000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_bus>; + #sound-dai-cells = <0>; + status = "disabled"; }; i2s1: i2s@e2100000 { @@ -596,7 +571,7 @@ interrupts = <29>; clocks = <&clocks CLK_CSIS>, <&clocks SCLK_CSIS>; - clock-names = "clk_csis", + clock-names = "csis", "sclk_csis"; bus-width = <4>; status = "disabled"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d2.dtsi @@ -526,7 +526,7 @@ pmecc: ecc-engine@f8014070 { compatible = "atmel,sama5d2-pmecc"; reg = <0xf8014070 0x490>, - <0xf8014500 0x100>; + <0xf8014500 0x200>; }; }; @@ -648,6 +648,7 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 51>; #address-cells = <1>; #size-cells = <1>; + no-memory-wc; ranges = <0 0xf8044000 0x1420>; }; @@ -716,7 +717,7 @@ can0: can@f8054000 { compatible = "bosch,m_can"; - reg = <0xf8054000 0x4000>, <0x210000 0x4000>; + reg = <0xf8054000 0x4000>, <0x210000 0x1c00>; reg-names = "m_can", "message_ram"; interrupts = <56 IRQ_TYPE_LEVEL_HIGH 7>, <64 IRQ_TYPE_LEVEL_HIGH 7>; @@ -932,13 +933,13 @@ clocks = <&pmc PMC_TYPE_PERIPHERAL 55>, <&pmc PMC_TYPE_GCK 55>; clock-names = "pclk", "gclk"; assigned-clocks = <&pmc PMC_TYPE_CORE PMC_I2S1_MUX>; - assigned-parrents = <&pmc PMC_TYPE_GCK 55>; + assigned-clock-parents = <&pmc PMC_TYPE_GCK 55>; status = "disabled"; }; can1: can@fc050000 { compatible = "bosch,m_can"; - reg = <0xfc050000 0x4000>, <0x210000 0x4000>; + reg = <0xfc050000 0x4000>, <0x210000 0x3800>; reg-names = "m_can", "message_ram"; interrupts = <57 IRQ_TYPE_LEVEL_HIGH 7>, <65 IRQ_TYPE_LEVEL_HIGH 7>; @@ -948,7 +949,7 @@ assigned-clocks = <&pmc PMC_TYPE_GCK 57>; assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_UTMI>; assigned-clock-rates = <40000000>; - bosch,mram-cfg = <0x1100 0 0 64 0 0 32 32>; + bosch,mram-cfg = <0x1c00 0 0 64 0 0 32 32>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d3.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d3.dtsi @@ -1188,49 +1188,49 @@ usart0_clk: usart0_clk { #clock-cells = <0>; reg = <12>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; usart1_clk: usart1_clk { #clock-cells = <0>; reg = <13>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; usart2_clk: usart2_clk { #clock-cells = <0>; reg = <14>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; usart3_clk: usart3_clk { #clock-cells = <0>; reg = <15>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; uart0_clk: uart0_clk { #clock-cells = <0>; reg = <16>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; twi0_clk: twi0_clk { reg = <18>; #clock-cells = <0>; - atmel,clk-output-range = <0 16625000>; + atmel,clk-output-range = <0 41500000>; }; twi1_clk: twi1_clk { #clock-cells = <0>; reg = <19>; - atmel,clk-output-range = <0 16625000>; + atmel,clk-output-range = <0 41500000>; }; twi2_clk: twi2_clk { #clock-cells = <0>; reg = <20>; - atmel,clk-output-range = <0 16625000>; + atmel,clk-output-range = <0 41500000>; }; mci0_clk: mci0_clk { @@ -1246,19 +1246,19 @@ spi0_clk: spi0_clk { #clock-cells = <0>; reg = <24>; - atmel,clk-output-range = <0 133000000>; + atmel,clk-output-range = <0 166000000>; }; spi1_clk: spi1_clk { #clock-cells = <0>; reg = <25>; - atmel,clk-output-range = <0 133000000>; + atmel,clk-output-range = <0 166000000>; }; tcb0_clk: tcb0_clk { #clock-cells = <0>; reg = <26>; - atmel,clk-output-range = <0 133000000>; + atmel,clk-output-range = <0 166000000>; }; pwm_clk: pwm_clk { @@ -1269,7 +1269,7 @@ adc_clk: adc_clk { #clock-cells = <0>; reg = <29>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; dma0_clk: dma0_clk { @@ -1300,13 +1300,13 @@ ssc0_clk: ssc0_clk { #clock-cells = <0>; reg = <38>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; ssc1_clk: ssc1_clk { #clock-cells = <0>; reg = <39>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; sha_clk: sha_clk { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d3_can.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d3_can.dtsi @@ -36,13 +36,13 @@ can0_clk: can0_clk { #clock-cells = <0>; reg = <40>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; can1_clk: can1_clk { #clock-cells = <0>; reg = <41>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d3_tcb1.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d3_tcb1.dtsi @@ -22,6 +22,7 @@ tcb1_clk: tcb1_clk { #clock-cells = <0>; reg = <27>; + atmel,clk-output-range = <0 166000000>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d3_uart.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d3_uart.dtsi @@ -41,13 +41,13 @@ uart0_clk: uart0_clk { #clock-cells = <0>; reg = <16>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; uart1_clk: uart1_clk { #clock-cells = <0>; reg = <17>; - atmel,clk-output-range = <0 66000000>; + atmel,clk-output-range = <0 83000000>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sama5d4.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sama5d4.dtsi @@ -914,7 +914,7 @@ 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */ 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */ 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */ - 0x0003ff00 0x8002a800 0x00000000 /* pioD */ + 0xb003ff00 0x8002a800 0x00000000 /* pioD */ 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */ >; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga.dtsi @@ -710,7 +710,7 @@ }; }; - L2: l2-cache@fffef000 { + L2: cache-controller@fffef000 { compatible = "arm,pl310-cache"; reg = <0xfffef000 0x1000>; interrupts = <0 38 0x04>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_arria10.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -636,7 +636,7 @@ reg = <0xffcfb100 0x80>; }; - L2: l2-cache@fffff000 { + L2: cache-controller@fffff000 { compatible = "arm,pl310-cache"; reg = <0xfffff000 0x1000>; interrupts = <0 18 IRQ_TYPE_LEVEL_HIGH>; @@ -819,7 +819,7 @@ timer3: timer3@ffd00100 { compatible = "snps,dw-apb-timer"; interrupts = <0 118 IRQ_TYPE_LEVEL_HIGH>; - reg = <0xffd01000 0x100>; + reg = <0xffd00100 0x100>; clocks = <&l4_sys_free_clk>; clock-names = "timer"; resets = <&rst L4SYSTIMER1_RESET>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_arria10_socdk_qspi.dts @@ -12,7 +12,7 @@ flash0: n25q00@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00aa"; + compatible = "micron,mt25qu02g", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <100000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_arria5_socdk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_arria5_socdk.dts @@ -119,7 +119,7 @@ flash: flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q256a"; + compatible = "micron,n25q256a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <100000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_cyclone5_socdk.dts @@ -124,7 +124,7 @@ flash0: n25q00@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00"; + compatible = "micron,mt25qu02g", "jedec,spi-nor"; reg = <0>; /* chip select */ spi-max-frequency = <100000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_cyclone5_sockit.dts @@ -169,7 +169,7 @@ flash: flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00"; + compatible = "micron,mt25qu02g", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <100000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_cyclone5_socrates.dts @@ -80,7 +80,7 @@ flash: flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q256a"; + compatible = "micron,n25q256a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <100000000>; m25p,fast-read; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_cyclone5_sodia.dts @@ -116,7 +116,7 @@ flash0: n25q512a@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q512a"; + compatible = "micron,n25q512a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <100000000>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts @@ -224,7 +224,7 @@ n25q128@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q128"; + compatible = "micron,n25q128", "jedec,spi-nor"; reg = <0>; /* chip select */ spi-max-frequency = <100000000>; m25p,fast-read; @@ -241,7 +241,7 @@ n25q00@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "n25q00"; + compatible = "micron,mt25qu02g", "jedec,spi-nor"; reg = <1>; /* chip select */ spi-max-frequency = <100000000>; m25p,fast-read; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/spear1340.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/spear1340.dtsi @@ -136,9 +136,9 @@ reg = <0xb4100000 0x1000>; interrupts = <0 105 0x4>; status = "disabled"; - dmas = <&dwdma0 12 0 1>, - <&dwdma0 13 1 0>; - dma-names = "tx", "rx"; + dmas = <&dwdma0 13 0 1>, + <&dwdma0 12 1 0>; + dma-names = "rx", "tx"; }; thermal@e07008c4 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/spear13xx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/spear13xx.dtsi @@ -284,9 +284,9 @@ #size-cells = <0>; interrupts = <0 31 0x4>; status = "disabled"; - dmas = <&dwdma0 4 0 0>, - <&dwdma0 5 0 0>; - dma-names = "tx", "rx"; + dmas = <&dwdma0 5 0 0>, + <&dwdma0 4 0 0>; + dma-names = "rx", "tx"; }; rtc@e0580000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/spear320-hmi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/spear320-hmi.dts @@ -242,7 +242,7 @@ irq-trigger = <0x1>; stmpegpio: stmpe-gpio { - compatible = "stmpe,gpio"; + compatible = "st,stmpe-gpio"; reg = <0>; gpio-controller; #gpio-cells = <2>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/spear3xx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/spear3xx.dtsi @@ -47,7 +47,7 @@ }; gmac: eth@e0800000 { - compatible = "st,spear600-gmac"; + compatible = "snps,dwmac-3.40a"; reg = <0xe0800000 0x8000>; interrupts = <23 22>; interrupt-names = "macirq", "eth_wake_irq"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/spear600.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/spear600.dtsi @@ -47,7 +47,7 @@ compatible = "arm,pl110", "arm,primecell"; reg = <0xfc200000 0x1000>; interrupt-parent = <&vic1>; - interrupts = <12>; + interrupts = <13>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -755,14 +755,14 @@ status = "disabled"; }; - vica: intc@10140000 { + vica: interrupt-controller@10140000 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; reg = <0x10140000 0x20>; }; - vicb: intc@10140020 { + vicb: interrupt-controller@10140020 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stihxxx-b2120.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stihxxx-b2120.dtsi @@ -46,7 +46,7 @@ /* DAC */ format = "i2s"; mclk-fs = <256>; - frame-inversion = <1>; + frame-inversion; cpu { sound-dai = <&sti_uni_player2>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32429i-eval.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32429i-eval.dts @@ -112,17 +112,15 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioa 0 0>; }; - button@1 { + button-1 { label = "Tamper"; linux,code = ; gpios = <&gpioc 13 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32746g-eval.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32746g-eval.dts @@ -81,12 +81,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioc 13 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f429-disco.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f429-disco.dts @@ -79,12 +79,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 0>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f429.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f429.dtsi @@ -283,8 +283,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM13)>; @@ -299,8 +297,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM14)>; @@ -623,8 +619,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM10)>; @@ -639,8 +633,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM11)>; @@ -696,7 +688,7 @@ status = "disabled"; }; - rcc: rcc@40023810 { + rcc: rcc@40023800 { #reset-cells = <1>; #clock-cells = <2>; compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f469-disco.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f469-disco.dts @@ -76,6 +76,13 @@ regulator-max-microvolt = <3300000>; }; + vdd_dsi: vdd-dsi { + compatible = "regulator-fixed"; + regulator-name = "vdd_dsi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + soc { dma-ranges = <0xc0000000 0x0 0x10000000>; }; @@ -97,12 +104,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; @@ -155,6 +160,7 @@ compatible = "orisetech,otm8009a"; reg = <0>; /* dsi virtual channel (0..3) */ reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>; + power-supply = <&vdd_dsi>; status = "okay"; port { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f7-pinctrl.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f7-pinctrl.dtsi @@ -284,6 +284,88 @@ slew-rate = <2>; }; }; + + can1_pins_a: can1-0 { + pins1 { + pinmux = ; /* CAN1_TX */ + }; + pins2 { + pinmux = ; /* CAN1_RX */ + bias-pull-up; + }; + }; + + can1_pins_b: can1-1 { + pins1 { + pinmux = ; /* CAN1_TX */ + }; + pins2 { + pinmux = ; /* CAN1_RX */ + bias-pull-up; + }; + }; + + can1_pins_c: can1-2 { + pins1 { + pinmux = ; /* CAN1_TX */ + }; + pins2 { + pinmux = ; /* CAN1_RX */ + bias-pull-up; + + }; + }; + + can1_pins_d: can1-3 { + pins1 { + pinmux = ; /* CAN1_TX */ + }; + pins2 { + pinmux = ; /* CAN1_RX */ + bias-pull-up; + + }; + }; + + can2_pins_a: can2-0 { + pins1 { + pinmux = ; /* CAN2_TX */ + }; + pins2 { + pinmux = ; /* CAN2_RX */ + bias-pull-up; + }; + }; + + can2_pins_b: can2-1 { + pins1 { + pinmux = ; /* CAN2_TX */ + }; + pins2 { + pinmux = ; /* CAN2_RX */ + bias-pull-up; + }; + }; + + can3_pins_a: can3-0 { + pins1 { + pinmux = ; /* CAN3_TX */ + }; + pins2 { + pinmux = ; /* CAN3_RX */ + bias-pull-up; + }; + }; + + can3_pins_b: can3-1 { + pins1 { + pinmux = ; /* CAN3_TX */ + }; + pins2 { + pinmux = ; /* CAN3_RX */ + bias-pull-up; + }; + }; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f746.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f746.dtsi @@ -265,8 +265,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM13)>; @@ -281,8 +279,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM14)>; @@ -366,9 +362,9 @@ status = "disabled"; }; - i2c3: i2c@40005C00 { + i2c3: i2c@40005c00 { compatible = "st,stm32f7-i2c"; - reg = <0x40005C00 0x400>; + reg = <0x40005c00 0x400>; interrupts = <72>, <73>; resets = <&rcc STM32F7_APB1_RESET(I2C3)>; @@ -533,8 +529,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM10)>; @@ -549,8 +543,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM11)>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32f769-disco.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32f769-disco.dts @@ -75,12 +75,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32h743.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32h743.dtsi @@ -438,8 +438,6 @@ }; lptimer4: timer@58002c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58002c00 0x400>; clocks = <&rcc LPTIM4_CK>; @@ -454,8 +452,6 @@ }; lptimer5: timer@58003000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58003000 0x400>; clocks = <&rcc LPTIM5_CK>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32mp157a-avenger96.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32mp157a-avenger96.dts @@ -91,6 +91,9 @@ #address-cells = <1>; #size-cells = <0>; compatible = "snps,dwmac-mdio"; + reset-gpios = <&gpioz 2 GPIO_ACTIVE_LOW>; + reset-delay-us = <1000>; + phy0: ethernet-phy@7 { reg = <7>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/stm32mp157c.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/stm32mp157c.dtsi @@ -515,7 +515,7 @@ compatible = "st,stm32-cec"; reg = <0x40016000 0x400>; interrupts = ; - clocks = <&rcc CEC_K>, <&clk_lse>; + clocks = <&rcc CEC_K>, <&rcc CEC>; clock-names = "cec", "hdmi-cec"; status = "disabled"; }; @@ -773,7 +773,7 @@ #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; + reg = <0x4 0x20>; clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 87 0x400 0x01>; @@ -783,7 +783,7 @@ sai1b: audio-controller@4400a024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI1_K>; clock-names = "sai_ck"; dmas = <&dmamux1 88 0x400 0x01>; @@ -804,7 +804,7 @@ sai2a: audio-controller@4400b004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x4 0x1c>; + reg = <0x4 0x20>; clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 89 0x400 0x01>; @@ -814,7 +814,7 @@ sai2b: audio-controller@4400b024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI2_K>; clock-names = "sai_ck"; dmas = <&dmamux1 90 0x400 0x01>; @@ -835,7 +835,7 @@ sai3a: audio-controller@4400c004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x04 0x1c>; + reg = <0x04 0x20>; clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 113 0x400 0x01>; @@ -845,7 +845,7 @@ sai3b: audio-controller@4400c024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI3_K>; clock-names = "sai_ck"; dmas = <&dmamux1 114 0x400 0x01>; @@ -1191,7 +1191,7 @@ sai4a: audio-controller@50027004 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-a"; - reg = <0x04 0x1c>; + reg = <0x04 0x20>; clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 99 0x400 0x01>; @@ -1201,7 +1201,7 @@ sai4b: audio-controller@50027024 { #sound-dai-cells = <0>; compatible = "st,stm32-sai-sub-b"; - reg = <0x24 0x1c>; + reg = <0x24 0x20>; clocks = <&rcc SAI4_K>; clock-names = "sai_ck"; dmas = <&dmamux1 100 0x400 0x01>; @@ -1311,12 +1311,6 @@ status = "disabled"; }; - stmmac_axi_config_0: stmmac-axi-config { - snps,wr_osr_lmt = <0x7>; - snps,rd_osr_lmt = <0x7>; - snps,blen = <0 0 0 0 16 8 4>; - }; - ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; @@ -1339,6 +1333,12 @@ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; status = "disabled"; + + stmmac_axi_config_0: stmmac-axi-config { + snps,wr_osr_lmt = <0x7>; + snps,rd_osr_lmt = <0x7>; + snps,blen = <0 0 0 0 16 8 4>; + }; }; usbh_ohci: usbh-ohci@5800c000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun4i-a10.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun4i-a10.dtsi @@ -143,7 +143,7 @@ trips { cpu_alert0: cpu-alert0 { /* milliCelsius */ - temperature = <850000>; + temperature = <85000>; hysteresis = <2000>; type = "passive"; }; @@ -198,7 +198,7 @@ default-pool { compatible = "shared-dma-pool"; size = <0x6000000>; - alloc-ranges = <0x4a000000 0x6000000>; + alloc-ranges = <0x40000000 0x10000000>; reusable; linux,cma-default; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun5i.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun5i.dtsi @@ -117,7 +117,7 @@ default-pool { compatible = "shared-dma-pool"; size = <0x6000000>; - alloc-ranges = <0x4a000000 0x6000000>; + alloc-ranges = <0x40000000 0x10000000>; reusable; linux,cma-default; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun6i-a31-hummingbird.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun6i-a31-hummingbird.dts @@ -154,7 +154,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts @@ -130,7 +130,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_gmac_3v3>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-bananapi.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-bananapi.dts @@ -132,7 +132,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_gmac_3v3>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-bananapro.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-bananapro.dts @@ -110,7 +110,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_gmac_3v3>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-cubietruck.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-cubietruck.dts @@ -151,7 +151,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts @@ -112,7 +112,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts @@ -1,5 +1,5 @@ /* - * Copyright 2015 Adam Sampson + * Copyright 2015-2020 Adam Sampson * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -115,7 +115,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun7i-a20.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun7i-a20.dtsi @@ -180,7 +180,7 @@ default-pool { compatible = "shared-dma-pool"; size = <0x6000000>; - alloc-ranges = <0x4a000000 0x6000000>; + alloc-ranges = <0x40000000 0x10000000>; reusable; linux,cma-default; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-a83t-bananapi-m3.dts @@ -131,7 +131,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_sw>; phy-handle = <&rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; allwinner,rx-delay-ps = <700>; allwinner,tx-delay-ps = <700>; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -101,7 +101,7 @@ initial-mode = <1>; /* initialize in HUB mode */ disabled-ports = <1>; intn-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ - reset-gpios = <&pio 4 16 GPIO_ACTIVE_HIGH>; /* PE16 */ + reset-gpios = <&pio 4 16 GPIO_ACTIVE_LOW>; /* PE16 */ connect-gpios = <&pio 4 17 GPIO_ACTIVE_HIGH>; /* PE17 */ refclk-frequency = <19200000>; }; @@ -183,7 +183,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_dldo4>; phy-handle = <&rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts @@ -358,8 +358,8 @@ }; ®_dldo3 { - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-name = "vdd-csi"; }; @@ -482,7 +482,8 @@ }; &usbphy { - usb0_id_det-gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */ + usb0_id_det-gpios = <&pio 7 11 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH11 */ + usb0_vbus_power-supply = <&usb_power_supply>; usb0_vbus-supply = <®_drivevbus>; usb1_vbus-supply = <®_vmain>; usb2_vbus-supply = <®_vmain>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-a83t.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -313,7 +313,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-a83t-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_PLL_DE>; clock-names = "bus", --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-h2-plus-bananapi-m2-zero.dts @@ -31,7 +31,7 @@ pwr_led { label = "bananapi-m2-zero:red:pwr"; - gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; /* PL10 */ + gpios = <&r_pio 0 10 GPIO_ACTIVE_LOW>; /* PL10 */ default-state = "on"; }; }; @@ -62,6 +62,30 @@ states = <1100000 0>, <1300000 1>; }; + reg_vcc_dram: vcc-dram { + compatible = "regulator-fixed"; + regulator-name = "vcc-dram"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */ + vin-supply = <®_vcc5v0>; + }; + + reg_vcc1v2: vcc1v2 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + vin-supply = <®_vcc5v0>; + }; + wifi_pwrseq: wifi_pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>; /* PL7 */ --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts @@ -169,7 +169,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mxicy,mx25l1606e", "winbond,w25q128"; + compatible = "mxicy,mx25l1606e", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-h3-orangepi-pc-plus.dts @@ -53,11 +53,6 @@ }; }; -&emac { - /* LEDs changed to active high on the plus */ - /delete-property/ allwinner,leds-active-low; -}; - &mmc1 { vmmc-supply = <®_vcc3v3>; bus-width = <4>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-h3-orangepi-plus2e.dts @@ -67,7 +67,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-h3.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-h3.dtsi @@ -80,7 +80,7 @@ #cooling-cells = <2>; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <1>; @@ -90,7 +90,7 @@ #cooling-cells = <2>; }; - cpu@2 { + cpu2: cpu@2 { compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <2>; @@ -100,7 +100,7 @@ #cooling-cells = <2>; }; - cpu@3 { + cpu3: cpu@3 { compatible = "arm,cortex-a7"; device_type = "cpu"; reg = <3>; @@ -111,6 +111,15 @@ }; }; + pmu { + compatible = "arm,cortex-a7-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + timer { compatible = "arm,armv7-timer"; interrupts = , --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts @@ -129,7 +129,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_dc1sw>; status = "okay"; }; @@ -223,16 +223,16 @@ }; ®_dc1sw { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-name = "vcc-gmac-phy"; }; ®_dcdc1 { regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "vcc-3v0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; }; ®_dcdc2 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-r40.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-r40.dtsi @@ -118,7 +118,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-r40-de2-clk", "allwinner,sun8i-h3-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -266,6 +266,16 @@ #phy-cells = <1>; }; + ahci: sata@1c18000 { + compatible = "allwinner,sun8i-r40-ahci"; + reg = <0x01c18000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>; + resets = <&ccu RST_BUS_SATA>; + reset-names = "ahci"; + status = "disabled"; + }; + ehci1: usb@1c19000 { compatible = "allwinner,sun8i-r40-ehci", "generic-ehci"; reg = <0x01c19000 0x100>; @@ -557,17 +567,6 @@ #size-cells = <0>; }; - ahci: sata@1c18000 { - compatible = "allwinner,sun8i-r40-ahci"; - reg = <0x01c18000 0x1000>; - interrupts = ; - clocks = <&ccu CLK_BUS_SATA>, <&ccu CLK_SATA>; - resets = <&ccu RST_BUS_SATA>; - reset-names = "ahci"; - status = "disabled"; - - }; - gmac: ethernet@1c50000 { compatible = "allwinner,sun8i-r40-gmac"; syscon = <&ccu>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-v3s.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-v3s.dtsi @@ -105,7 +105,7 @@ display_clocks: clock@1000000 { compatible = "allwinner,sun8i-v3s-de2-clk"; - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -423,7 +423,7 @@ gic: interrupt-controller@1c81000 { compatible = "arm,gic-400"; reg = <0x01c81000 0x1000>, - <0x01c82000 0x1000>, + <0x01c82000 0x2000>, <0x01c84000 0x2000>, <0x01c86000 0x2000>; interrupt-controller; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts @@ -120,7 +120,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_dc1sw>; status = "okay"; }; @@ -198,16 +198,16 @@ }; ®_dc1sw { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; regulator-name = "vcc-gmac-phy"; }; ®_dcdc1 { regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "vcc-3v0"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3"; }; ®_dcdc2 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts @@ -129,7 +129,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_cldo1>; status = "okay"; }; @@ -280,8 +280,8 @@ reg_dcdc5: dcdc5 { regulator-always-on; - regulator-min-microvolt = <1425000>; - regulator-max-microvolt = <1575000>; + regulator-min-microvolt = <1450000>; + regulator-max-microvolt = <1550000>; regulator-name = "vcc-dram"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sun9i-a80-optimus.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/sun9i-a80-optimus.dts @@ -124,7 +124,7 @@ pinctrl-names = "default"; pinctrl-0 = <&gmac_rgmii_pins>; phy-handle = <&phy1>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-supply = <®_cldo1>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/suniv-f1c100s.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/suniv-f1c100s.dtsi @@ -104,8 +104,10 @@ wdt: watchdog@1c20ca0 { compatible = "allwinner,suniv-f1c100s-wdt", - "allwinner,sun4i-a10-wdt"; + "allwinner,sun6i-a31-wdt"; reg = <0x01c20ca0 0x20>; + interrupts = <16>; + clocks = <&osc32k>; }; uart0: serial@1c25000 { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sunxi-bananapi-m2-plus-v1.2.dtsi @@ -16,15 +16,27 @@ regulator-type = "voltage"; regulator-boot-on; regulator-always-on; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1300000>; + regulator-min-microvolt = <1108475>; + regulator-max-microvolt = <1308475>; regulator-ramp-delay = <50>; /* 4ms */ gpios = <&r_pio 0 1 GPIO_ACTIVE_HIGH>; /* PL1 */ gpios-states = <0x1>; - states = <1100000 0>, <1300000 1>; + states = <1108475 0>, <1308475 1>; }; }; &cpu0 { cpu-supply = <®_vdd_cpux>; }; + +&cpu1 { + cpu-supply = <®_vdd_cpux>; +}; + +&cpu2 { + cpu-supply = <®_vdd_cpux>; +}; + +&cpu3 { + cpu-supply = <®_vdd_cpux>; +}; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sunxi-bananapi-m2-plus.dtsi @@ -126,7 +126,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/sunxi-h3-h5.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/sunxi-h3-h5.dtsi @@ -113,7 +113,7 @@ display_clocks: clock@1000000 { /* compatible is in per SoC .dtsi file */ - reg = <0x01000000 0x100000>; + reg = <0x01000000 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/tegra20-tamonten.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/tegra20-tamonten.dtsi @@ -183,10 +183,11 @@ }; conf_ata { nvidia,pins = "ata", "atb", "atc", "atd", "ate", - "cdev1", "cdev2", "dap1", "dtb", "gma", - "gmb", "gmc", "gmd", "gme", "gpu7", - "gpv", "i2cp", "pta", "rm", "slxa", - "slxk", "spia", "spib", "uac"; + "cdev1", "cdev2", "dap1", "dtb", "dtf", + "gma", "gmb", "gmc", "gmd", "gme", "gpu7", + "gpv", "i2cp", "irrx", "irtx", "pta", + "rm", "slxa", "slxk", "spia", "spib", + "uac"; nvidia,pull = ; nvidia,tristate = ; }; @@ -202,7 +203,7 @@ }; conf_crtp { nvidia,pins = "crtp", "dap2", "dap3", "dap4", - "dtc", "dte", "dtf", "gpu", "sdio1", + "dtc", "dte", "gpu", "sdio1", "slxc", "slxd", "spdi", "spdo", "spig", "uda"; nvidia,pull = ; @@ -211,7 +212,7 @@ conf_ddc { nvidia,pins = "ddc", "dta", "dtd", "kbca", "kbcb", "kbcc", "kbcd", "kbce", "kbcf", - "sdc"; + "sdc", "uad", "uca"; nvidia,pull = ; nvidia,tristate = ; }; @@ -221,10 +222,9 @@ "lvp0", "owc", "sdb"; nvidia,tristate = ; }; - conf_irrx { - nvidia,pins = "irrx", "irtx", "sdd", "spic", - "spie", "spih", "uaa", "uab", "uad", - "uca", "ucb"; + conf_sdd { + nvidia,pins = "sdd", "spic", "spie", "spih", + "uaa", "uab", "ucb"; nvidia,pull = ; nvidia,tristate = ; }; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/uniphier-pxs2.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/uniphier-pxs2.dtsi @@ -571,7 +571,7 @@ clocks = <&sys_clk 6>; reset-names = "ether"; resets = <&sys_rst 6>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; local-mac-address = [00 00 00 00 00 00]; socionext,syscon-phy-mode = <&soc_glue 0>; @@ -585,8 +585,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65a00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 134 4>, <0 135 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 134 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; clock-names = "ref", "bus_early", "suspend"; @@ -681,8 +681,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65c00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 137 4>, <0 138 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 137 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; clock-names = "ref", "bus_early", "suspend"; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/versatile-ab.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/versatile-ab.dts @@ -195,16 +195,15 @@ #size-cells = <1>; ranges; - vic: intc@10140000 { + vic: interrupt-controller@10140000 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; reg = <0x10140000 0x1000>; - clear-mask = <0xffffffff>; valid-mask = <0xffffffff>; }; - sic: intc@10003000 { + sic: interrupt-controller@10003000 { compatible = "arm,versatile-sic"; interrupt-controller; #interrupt-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/versatile-pb.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/versatile-pb.dts @@ -7,7 +7,7 @@ amba { /* The Versatile PB is using more SIC IRQ lines than the AB */ - sic: intc@10003000 { + sic: interrupt-controller@10003000 { clear-mask = <0xffffffff>; /* * Valid interrupt lines mask according to --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -31,7 +31,7 @@ #interrupt-cells = <1>; ranges; - nor_flash: flash@0,00000000 { + nor_flash: flash@0 { compatible = "arm,vexpress-flash", "cfi-flash"; reg = <0 0x00000000 0x04000000>, <4 0x00000000 0x04000000>; @@ -41,13 +41,13 @@ }; }; - psram@1,00000000 { + psram@100000000 { compatible = "arm,vexpress-psram", "mtd-ram"; reg = <1 0x00000000 0x02000000>; bank-width = <4>; }; - ethernet@2,02000000 { + ethernet@202000000 { compatible = "smsc,lan9118", "smsc,lan9115"; reg = <2 0x02000000 0x10000>; interrupts = <15>; @@ -59,14 +59,14 @@ vddvario-supply = <&v2m_fixed_3v3>; }; - usb@2,03000000 { + usb@203000000 { compatible = "nxp,usb-isp1761"; reg = <2 0x03000000 0x20000>; interrupts = <16>; port1-otg; }; - iofpga@3,00000000 { + iofpga@300000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/vexpress-v2p-ca5s.dts +++ linux-oracle-5.4.0/arch/arm/boot/dts/vexpress-v2p-ca5s.dts @@ -132,6 +132,7 @@ reg = <0x2c0f0000 0x1000>; interrupts = <0 84 4>; cache-level = <2>; + cache-unified; }; pmu { --- linux-oracle-5.4.0.orig/arch/arm/boot/dts/vfxxx.dtsi +++ linux-oracle-5.4.0/arch/arm/boot/dts/vfxxx.dtsi @@ -495,7 +495,7 @@ }; ocotp: ocotp@400a5000 { - compatible = "fsl,vf610-ocotp"; + compatible = "fsl,vf610-ocotp", "syscon"; reg = <0x400a5000 0x1000>; clocks = <&clks VF610_CLK_OCOTP>; }; --- linux-oracle-5.4.0.orig/arch/arm/configs/aspeed_g5_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/aspeed_g5_defconfig @@ -139,6 +139,7 @@ CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_ASPEED_VUART=y CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_ASPEED_KCS_IPMI_BMC=y CONFIG_ASPEED_BT_IPMI_BMC=y --- linux-oracle-5.4.0.orig/arch/arm/configs/exynos_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/exynos_defconfig @@ -38,6 +38,7 @@ CONFIG_CRYPTO_SHA512_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_CHACHA20_NEON=m +CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y @@ -92,6 +93,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_ATA=y @@ -290,6 +292,7 @@ CONFIG_COMMON_CLK_MAX77686=y CONFIG_COMMON_CLK_S2MPS11=y CONFIG_EXYNOS_IOMMU=y +CONFIG_PM_DEVFREQ=y CONFIG_DEVFREQ_GOV_PERFORMANCE=y CONFIG_DEVFREQ_GOV_POWERSAVE=y CONFIG_DEVFREQ_GOV_USERSPACE=y @@ -348,9 +351,13 @@ CONFIG_DYNAMIC_DEBUG=y CONFIG_DEBUG_INFO=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_DEBUG_KERNEL=y CONFIG_SOFTLOCKUP_DETECTOR=y # CONFIG_DETECT_HUNG_TASK is not set CONFIG_PROVE_LOCKING=y CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y --- linux-oracle-5.4.0.orig/arch/arm/configs/imx_v6_v7_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/imx_v6_v7_defconfig @@ -460,6 +460,7 @@ CONFIG_FONT_8x16=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y # CONFIG_SCHED_DEBUG is not set CONFIG_PROVE_LOCKING=y # CONFIG_DEBUG_BUGVERBOSE is not set --- linux-oracle-5.4.0.orig/arch/arm/configs/omap2plus_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/omap2plus_defconfig @@ -552,5 +552,6 @@ CONFIG_DEBUG_INFO_SPLIT=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_FS=y CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_BUGVERBOSE is not set --- linux-oracle-5.4.0.orig/arch/arm/configs/rpc_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/rpc_defconfig @@ -32,7 +32,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/arm/configs/s3c2410_defconfig +++ linux-oracle-5.4.0/arch/arm/configs/s3c2410_defconfig @@ -202,7 +202,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_CONSTANTS=y --- linux-oracle-5.4.0.orig/arch/arm/crypto/Kconfig +++ linux-oracle-5.4.0/arch/arm/crypto/Kconfig @@ -30,7 +30,7 @@ config CRYPTO_SHA1_ARM_CE tristate "SHA1 digest algorithm (ARM v8 Crypto Extensions)" - depends on KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) select CRYPTO_SHA1_ARM select CRYPTO_HASH help @@ -39,7 +39,7 @@ config CRYPTO_SHA2_ARM_CE tristate "SHA-224/256 digest algorithm (ARM v8 Crypto Extensions)" - depends on KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) select CRYPTO_SHA256_ARM select CRYPTO_HASH help @@ -96,7 +96,7 @@ config CRYPTO_AES_ARM_CE tristate "Accelerated AES using ARMv8 Crypto Extensions" - depends on KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) select CRYPTO_BLKCIPHER select CRYPTO_LIB_AES select CRYPTO_SIMD @@ -106,7 +106,7 @@ config CRYPTO_GHASH_ARM_CE tristate "PMULL-accelerated GHASH using NEON/ARMv8 Crypto Extensions" - depends on KERNEL_MODE_NEON + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) select CRYPTO_HASH select CRYPTO_CRYPTD select CRYPTO_GF128MUL @@ -118,12 +118,14 @@ config CRYPTO_CRCT10DIF_ARM_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" - depends on KERNEL_MODE_NEON && CRC_T10DIF + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) + depends on CRC_T10DIF select CRYPTO_HASH config CRYPTO_CRC32_ARM_CE tristate "CRC32(C) digest algorithm using CRC and/or PMULL instructions" - depends on KERNEL_MODE_NEON && CRC32 + depends on KERNEL_MODE_NEON && (CC_IS_CLANG || GCC_VERSION >= 40800) + depends on CRC32 select CRYPTO_HASH config CRYPTO_CHACHA20_NEON --- linux-oracle-5.4.0.orig/arch/arm/crypto/Makefile +++ linux-oracle-5.4.0/arch/arm/crypto/Makefile @@ -12,32 +12,12 @@ obj-$(CONFIG_CRYPTO_CHACHA20_NEON) += chacha-neon.o obj-$(CONFIG_CRYPTO_NHPOLY1305_NEON) += nhpoly1305-neon.o -ce-obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o -ce-obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o -ce-obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o -ce-obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o -ce-obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o -crc-obj-$(CONFIG_CRYPTO_CRC32_ARM_CE) += crc32-arm-ce.o - -ifneq ($(crc-obj-y)$(crc-obj-m),) -ifeq ($(call as-instr,.arch armv8-a\n.arch_extension crc,y,n),y) -ce-obj-y += $(crc-obj-y) -ce-obj-m += $(crc-obj-m) -else -$(warning These CRC Extensions modules need binutils 2.23 or higher) -$(warning $(crc-obj-y) $(crc-obj-m)) -endif -endif - -ifneq ($(ce-obj-y)$(ce-obj-m),) -ifeq ($(call as-instr,.fpu crypto-neon-fp-armv8,y,n),y) -obj-y += $(ce-obj-y) -obj-m += $(ce-obj-m) -else -$(warning These ARMv8 Crypto Extensions modules need binutils 2.23 or higher) -$(warning $(ce-obj-y) $(ce-obj-m)) -endif -endif +obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o +obj-$(CONFIG_CRYPTO_SHA1_ARM_CE) += sha1-arm-ce.o +obj-$(CONFIG_CRYPTO_SHA2_ARM_CE) += sha2-arm-ce.o +obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o +obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM_CE) += crct10dif-arm-ce.o +obj-$(CONFIG_CRYPTO_CRC32_ARM_CE) += crc32-arm-ce.o aes-arm-y := aes-cipher-core.o aes-cipher-glue.o aes-arm-bs-y := aes-neonbs-core.o aes-neonbs-glue.o --- linux-oracle-5.4.0.orig/arch/arm/crypto/aes-ce-core.S +++ linux-oracle-5.4.0/arch/arm/crypto/aes-ce-core.S @@ -386,20 +386,32 @@ .Lctrloop4x: subs r4, r4, #4 bmi .Lctr1x - add r6, r6, #1 + + /* + * NOTE: the sequence below has been carefully tweaked to avoid + * a silicon erratum that exists in Cortex-A57 (#1742098) and + * Cortex-A72 (#1655431) cores, where AESE/AESMC instruction pairs + * may produce an incorrect result if they take their input from a + * register of which a single 32-bit lane has been updated the last + * time it was modified. To work around this, the lanes of registers + * q0-q3 below are not manipulated individually, and the different + * counter values are prepared by successive manipulations of q7. + */ + add ip, r6, #1 vmov q0, q7 + rev ip, ip + add lr, r6, #2 + vmov s31, ip @ set lane 3 of q1 via q7 + add ip, r6, #3 + rev lr, lr vmov q1, q7 - rev ip, r6 - add r6, r6, #1 + vmov s31, lr @ set lane 3 of q2 via q7 + rev ip, ip vmov q2, q7 - vmov s7, ip - rev ip, r6 - add r6, r6, #1 + vmov s31, ip @ set lane 3 of q3 via q7 + add r6, r6, #4 vmov q3, q7 - vmov s11, ip - rev ip, r6 - add r6, r6, #1 - vmov s15, ip + vld1.8 {q4-q5}, [r1]! vld1.8 {q6}, [r1]! vld1.8 {q15}, [r1]! --- linux-oracle-5.4.0.orig/arch/arm/crypto/crct10dif-ce-core.S +++ linux-oracle-5.4.0/arch/arm/crypto/crct10dif-ce-core.S @@ -72,7 +72,7 @@ #endif .text - .arch armv7-a + .arch armv8-a .fpu crypto-neon-fp-armv8 init_crc .req r0 --- linux-oracle-5.4.0.orig/arch/arm/crypto/ghash-ce-core.S +++ linux-oracle-5.4.0/arch/arm/crypto/ghash-ce-core.S @@ -8,6 +8,9 @@ #include #include + .arch armv8-a + .fpu crypto-neon-fp-armv8 + SHASH .req q0 T1 .req q1 XL .req q2 @@ -88,7 +91,6 @@ T3_H .req d17 .text - .fpu crypto-neon-fp-armv8 .macro __pmull_p64, rd, rn, rm, b1, b2, b3, b4 vmull.p64 \rd, \rn, \rm --- linux-oracle-5.4.0.orig/arch/arm/crypto/nhpoly1305-neon-glue.c +++ linux-oracle-5.4.0/arch/arm/crypto/nhpoly1305-neon-glue.c @@ -30,7 +30,7 @@ return crypto_nhpoly1305_update(desc, src, srclen); do { - unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); + unsigned int n = min_t(unsigned int, srclen, SZ_4K); kernel_neon_begin(); crypto_nhpoly1305_update_helper(desc, src, n, _nh_neon); --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha1-ce-core.S +++ linux-oracle-5.4.0/arch/arm/crypto/sha1-ce-core.S @@ -10,6 +10,7 @@ #include .text + .arch armv8-a .fpu crypto-neon-fp-armv8 k0 .req q0 --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha2-ce-core.S +++ linux-oracle-5.4.0/arch/arm/crypto/sha2-ce-core.S @@ -10,6 +10,7 @@ #include .text + .arch armv8-a .fpu crypto-neon-fp-armv8 k0 .req q7 --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha256-armv4.pl +++ linux-oracle-5.4.0/arch/arm/crypto/sha256-armv4.pl @@ -175,7 +175,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -471,7 +470,8 @@ stmdb sp!,{r4-r12,lr} sub $H,sp,#16*4+16 - adrl $Ktbl,K256 + adr $Ktbl,.Lsha256_block_data_order + sub $Ktbl,$Ktbl,#.Lsha256_block_data_order-K256 bic $H,$H,#15 @ align for 128-bit stores mov $t2,sp mov sp,$H @ alloca --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha256-core.S_shipped +++ linux-oracle-5.4.0/arch/arm/crypto/sha256-core.S_shipped @@ -56,7 +56,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -1885,7 +1884,8 @@ stmdb sp!,{r4-r12,lr} sub r11,sp,#16*4+16 - adrl r14,K256 + adr r14,.Lsha256_block_data_order + sub r14,r14,#.Lsha256_block_data_order-K256 bic r11,r11,#15 @ align for 128-bit stores mov r12,sp mov sp,r11 @ alloca --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha256_glue.c +++ linux-oracle-5.4.0/arch/arm/crypto/sha256_glue.c @@ -25,8 +25,8 @@ #include "sha256_glue.h" -asmlinkage void sha256_block_data_order(u32 *digest, const void *data, - unsigned int num_blks); +asmlinkage void sha256_block_data_order(struct sha256_state *state, + const u8 *data, int num_blks); int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data, unsigned int len) @@ -34,23 +34,20 @@ /* make sure casting to sha256_block_fn() is safe */ BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0); - return sha256_base_do_update(desc, data, len, - (sha256_block_fn *)sha256_block_data_order); + return sha256_base_do_update(desc, data, len, sha256_block_data_order); } EXPORT_SYMBOL(crypto_sha256_arm_update); static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out) { - sha256_base_do_finalize(desc, - (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_finalize(desc, sha256_block_data_order); return sha256_base_finish(desc, out); } int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - sha256_base_do_update(desc, data, len, - (sha256_block_fn *)sha256_block_data_order); + sha256_base_do_update(desc, data, len, sha256_block_data_order); return crypto_sha256_arm_final(desc, out); } EXPORT_SYMBOL(crypto_sha256_arm_finup); --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha512-armv4.pl +++ linux-oracle-5.4.0/arch/arm/crypto/sha512-armv4.pl @@ -212,7 +212,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -602,7 +601,8 @@ dmb @ errata #451034 on early Cortex A8 add $len,$inp,$len,lsl#7 @ len to point at the end of inp VFP_ABI_PUSH - adrl $Ktbl,K512 + adr $Ktbl,.Lsha512_block_data_order + sub $Ktbl,$Ktbl,.Lsha512_block_data_order-K512 vldmia $ctx,{$A-$H} @ load context .Loop_neon: ___ --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha512-core.S_shipped +++ linux-oracle-5.4.0/arch/arm/crypto/sha512-core.S_shipped @@ -79,7 +79,6 @@ #else .syntax unified # ifdef __thumb2__ -# define adrl adr .thumb # else .code 32 @@ -543,7 +542,8 @@ dmb @ errata #451034 on early Cortex A8 add r2,r1,r2,lsl#7 @ len to point at the end of inp VFP_ABI_PUSH - adrl r3,K512 + adr r3,.Lsha512_block_data_order + sub r3,r3,.Lsha512_block_data_order-K512 vldmia r0,{d16-d23} @ load context .Loop_neon: vshr.u64 d24,d20,#14 @ 0 --- linux-oracle-5.4.0.orig/arch/arm/crypto/sha512-glue.c +++ linux-oracle-5.4.0/arch/arm/crypto/sha512-glue.c @@ -25,27 +25,25 @@ MODULE_ALIAS_CRYPTO("sha384-arm"); MODULE_ALIAS_CRYPTO("sha512-arm"); -asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks); +asmlinkage void sha512_block_data_order(struct sha512_state *state, + u8 const *src, int blocks); int sha512_arm_update(struct shash_desc *desc, const u8 *data, unsigned int len) { - return sha512_base_do_update(desc, data, len, - (sha512_block_fn *)sha512_block_data_order); + return sha512_base_do_update(desc, data, len, sha512_block_data_order); } static int sha512_arm_final(struct shash_desc *desc, u8 *out) { - sha512_base_do_finalize(desc, - (sha512_block_fn *)sha512_block_data_order); + sha512_base_do_finalize(desc, sha512_block_data_order); return sha512_base_finish(desc, out); } int sha512_arm_finup(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { - sha512_base_do_update(desc, data, len, - (sha512_block_fn *)sha512_block_data_order); + sha512_base_do_update(desc, data, len, sha512_block_data_order); return sha512_arm_final(desc, out); } --- linux-oracle-5.4.0.orig/arch/arm/include/asm/assembler.h +++ linux-oracle-5.4.0/arch/arm/include/asm/assembler.h @@ -18,11 +18,11 @@ #endif #include -#include #include #include #include #include +#include #define IOMEM(x) (x) @@ -107,6 +107,16 @@ .endm #endif +#if __LINUX_ARM_ARCH__ < 7 + .macro dsb, args + mcr p15, 0, r0, c7, c10, 4 + .endm + + .macro isb, args + mcr p15, 0, r0, c7, c5, 4 + .endm +#endif + .macro asm_trace_hardirqs_off, save=1 #if defined(CONFIG_TRACE_IRQFLAGS) .if \save @@ -269,10 +279,9 @@ .endif ;\ .popsection #define ALT_UP_B(label) \ - .equ up_b_offset, label - 9998b ;\ .pushsection ".alt.smp.init", "a" ;\ .long 9998b ;\ - W(b) . + up_b_offset ;\ + W(b) . + (label - 9998b) ;\ .popsection #else #define ALT_SMP(instr...) @@ -446,79 +455,6 @@ .size \name , . - \name .endm - .macro csdb -#ifdef CONFIG_THUMB2_KERNEL - .inst.w 0xf3af8014 -#else - .inst 0xe320f014 -#endif - .endm - - .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req -#ifndef CONFIG_CPU_USE_DOMAINS - adds \tmp, \addr, #\size - 1 - sbcscc \tmp, \tmp, \limit - bcs \bad -#ifdef CONFIG_CPU_SPECTRE - movcs \addr, #0 - csdb -#endif -#endif - .endm - - .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req -#ifdef CONFIG_CPU_SPECTRE - sub \tmp, \limit, #1 - subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr - addhs \tmp, \tmp, #1 @ if (tmp >= 0) { - subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } - movlo \addr, #0 @ if (tmp < 0) addr = NULL - csdb -#endif - .endm - - .macro uaccess_disable, tmp, isb=1 -#ifdef CONFIG_CPU_SW_DOMAIN_PAN - /* - * Whenever we re-enter userspace, the domains should always be - * set appropriately. - */ - mov \tmp, #DACR_UACCESS_DISABLE - mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register - .if \isb - instr_sync - .endif -#endif - .endm - - .macro uaccess_enable, tmp, isb=1 -#ifdef CONFIG_CPU_SW_DOMAIN_PAN - /* - * Whenever we re-enter userspace, the domains should always be - * set appropriately. - */ - mov \tmp, #DACR_UACCESS_ENABLE - mcr p15, 0, \tmp, c3, c0, 0 - .if \isb - instr_sync - .endif -#endif - .endm - - .macro uaccess_save, tmp -#ifdef CONFIG_CPU_SW_DOMAIN_PAN - mrc p15, 0, \tmp, c3, c0, 0 - str \tmp, [sp, #SVC_DACR] -#endif - .endm - - .macro uaccess_restore -#ifdef CONFIG_CPU_SW_DOMAIN_PAN - ldr r0, [sp, #SVC_DACR] - mcr p15, 0, r0, c3, c0, 0 -#endif - .endm - .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo .macro ret\c, reg #if __LINUX_ARM_ARCH__ < 6 --- linux-oracle-5.4.0.orig/arch/arm/include/asm/bugs.h +++ linux-oracle-5.4.0/arch/arm/include/asm/bugs.h @@ -1,7 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * arch/arm/include/asm/bugs.h - * * Copyright (C) 1995-2003 Russell King */ #ifndef __ASM_BUGS_H @@ -10,10 +8,8 @@ extern void check_writebuffer_bugs(void); #ifdef CONFIG_MMU -extern void check_bugs(void); extern void check_other_bugs(void); #else -#define check_bugs() do { } while (0) #define check_other_bugs() do { } while (0) #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/clocksource.h +++ linux-oracle-5.4.0/arch/arm/include/asm/clocksource.h @@ -1,8 +1,17 @@ #ifndef _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H +enum vdso_arch_clockmode { + /* vdso clocksource not usable */ + VDSO_CLOCKMODE_NONE, + /* vdso clocksource usable */ + VDSO_CLOCKMODE_ARCHTIMER, + VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT = VDSO_CLOCKMODE_ARCHTIMER, +}; + struct arch_clocksource_data { - bool vdso_direct; /* Usable for direct VDSO access? */ + /* Usable for direct VDSO access? */ + enum vdso_arch_clockmode clock_mode; }; #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/exception.h +++ linux-oracle-5.4.0/arch/arm/include/asm/exception.h @@ -10,10 +10,6 @@ #include -#ifdef CONFIG_FUNCTION_GRAPH_TRACER #define __exception_irq_entry __irq_entry -#else -#define __exception_irq_entry -#endif #endif /* __ASM_ARM_EXCEPTION_H */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/fixmap.h +++ linux-oracle-5.4.0/arch/arm/include/asm/fixmap.h @@ -2,7 +2,7 @@ #ifndef _ASM_FIXMAP_H #define _ASM_FIXMAP_H -#define FIXADDR_START 0xffc00000UL +#define FIXADDR_START 0xffc80000UL #define FIXADDR_END 0xfff00000UL #define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE) --- linux-oracle-5.4.0.orig/arch/arm/include/asm/ftrace.h +++ linux-oracle-5.4.0/arch/arm/include/asm/ftrace.h @@ -16,6 +16,9 @@ #ifdef CONFIG_DYNAMIC_FTRACE struct dyn_arch_ftrace { +#ifdef CONFIG_ARM_MODULE_PLTS + struct module *mod; +#endif }; static inline unsigned long ftrace_call_adjust(unsigned long addr) --- linux-oracle-5.4.0.orig/arch/arm/include/asm/futex.h +++ linux-oracle-5.4.0/arch/arm/include/asm/futex.h @@ -164,8 +164,13 @@ preempt_enable(); #endif - if (!ret) - *oval = oldval; + /* + * Store unconditionally. If ret != 0 the extra store is the least + * of the worries but GCC cannot figure out that __futex_atomic_op() + * is either setting ret to -EFAULT or storing the old value in + * oldval which results in a uninitialized warning at the call site. + */ + *oval = oldval; return ret; } --- linux-oracle-5.4.0.orig/arch/arm/include/asm/insn.h +++ linux-oracle-5.4.0/arch/arm/include/asm/insn.h @@ -13,18 +13,18 @@ } unsigned long -__arm_gen_branch(unsigned long pc, unsigned long addr, bool link); +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn); static inline unsigned long arm_gen_branch(unsigned long pc, unsigned long addr) { - return __arm_gen_branch(pc, addr, false); + return __arm_gen_branch(pc, addr, false, true); } static inline unsigned long -arm_gen_branch_link(unsigned long pc, unsigned long addr) +arm_gen_branch_link(unsigned long pc, unsigned long addr, bool warn) { - return __arm_gen_branch(pc, addr, true); + return __arm_gen_branch(pc, addr, true, warn); } #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/io.h +++ linux-oracle-5.4.0/arch/arm/include/asm/io.h @@ -457,6 +457,9 @@ extern int valid_phys_addr_range(phys_addr_t addr, size_t size); extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); extern int devmem_is_allowed(unsigned long pfn); +extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, + unsigned long flags); +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap #endif /* --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kexec-internal.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kexec-internal.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ARM_KEXEC_INTERNAL_H +#define _ARM_KEXEC_INTERNAL_H + +struct kexec_relocate_data { + unsigned long kexec_start_address; + unsigned long kexec_indirection_page; + unsigned long kexec_mach_type; + unsigned long kexec_r2; +}; + +#endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kprobes.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kprobes.h @@ -44,20 +44,20 @@ unsigned long val, void *data); /* optinsn template addresses */ -extern __visible kprobe_opcode_t optprobe_template_entry; -extern __visible kprobe_opcode_t optprobe_template_val; -extern __visible kprobe_opcode_t optprobe_template_call; -extern __visible kprobe_opcode_t optprobe_template_end; -extern __visible kprobe_opcode_t optprobe_template_sub_sp; -extern __visible kprobe_opcode_t optprobe_template_add_sp; -extern __visible kprobe_opcode_t optprobe_template_restore_begin; -extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn; -extern __visible kprobe_opcode_t optprobe_template_restore_end; +extern __visible kprobe_opcode_t optprobe_template_entry[]; +extern __visible kprobe_opcode_t optprobe_template_val[]; +extern __visible kprobe_opcode_t optprobe_template_call[]; +extern __visible kprobe_opcode_t optprobe_template_end[]; +extern __visible kprobe_opcode_t optprobe_template_sub_sp[]; +extern __visible kprobe_opcode_t optprobe_template_add_sp[]; +extern __visible kprobe_opcode_t optprobe_template_restore_begin[]; +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[]; +extern __visible kprobe_opcode_t optprobe_template_restore_end[]; #define MAX_OPTIMIZED_LENGTH 4 #define MAX_OPTINSN_SIZE \ - ((unsigned long)&optprobe_template_end - \ - (unsigned long)&optprobe_template_entry) + ((unsigned long)optprobe_template_end - \ + (unsigned long)optprobe_template_entry) #define RELATIVEJUMP_SIZE 4 struct arch_optimized_insn { --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kvm_asm.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kvm_asm.h @@ -56,7 +56,7 @@ extern void __kvm_flush_vm_context(void); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid(struct kvm *kvm); -extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); +extern void __kvm_flush_cpu_context(struct kvm_vcpu *vcpu); extern void __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high); --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kvm_emulate.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kvm_emulate.h @@ -14,13 +14,25 @@ #include /* arm64 compatibility macros */ +#define PSR_AA32_MODE_FIQ FIQ_MODE +#define PSR_AA32_MODE_SVC SVC_MODE #define PSR_AA32_MODE_ABT ABT_MODE #define PSR_AA32_MODE_UND UND_MODE #define PSR_AA32_T_BIT PSR_T_BIT +#define PSR_AA32_F_BIT PSR_F_BIT #define PSR_AA32_I_BIT PSR_I_BIT #define PSR_AA32_A_BIT PSR_A_BIT #define PSR_AA32_E_BIT PSR_E_BIT #define PSR_AA32_IT_MASK PSR_IT_MASK +#define PSR_AA32_GE_MASK 0x000f0000 +#define PSR_AA32_DIT_BIT 0x00200000 +#define PSR_AA32_PAN_BIT 0x00400000 +#define PSR_AA32_SSBS_BIT 0x00800000 +#define PSR_AA32_Q_BIT PSR_Q_BIT +#define PSR_AA32_V_BIT PSR_V_BIT +#define PSR_AA32_C_BIT PSR_C_BIT +#define PSR_AA32_Z_BIT PSR_Z_BIT +#define PSR_AA32_N_BIT PSR_N_BIT unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num); @@ -41,6 +53,11 @@ *__vcpu_spsr(vcpu) = v; } +static inline unsigned long host_spsr_to_spsr32(unsigned long spsr) +{ + return spsr; +} + static inline unsigned long vcpu_get_reg(struct kvm_vcpu *vcpu, u8 reg_num) { @@ -177,12 +194,17 @@ return kvm_vcpu_get_hsr(vcpu) & HSR_SSE; } +static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu) +{ + return false; +} + static inline int kvm_vcpu_dabt_get_rd(struct kvm_vcpu *vcpu) { return (kvm_vcpu_get_hsr(vcpu) & HSR_SRT_MASK) >> HSR_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_iss1tw(struct kvm_vcpu *vcpu) +static inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_DABT_S1PTW; } @@ -214,16 +236,21 @@ return kvm_vcpu_get_hsr(vcpu) & HSR_IL; } -static inline u8 kvm_vcpu_trap_get_class(struct kvm_vcpu *vcpu) +static inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) >> HSR_EC_SHIFT; } -static inline bool kvm_vcpu_trap_is_iabt(struct kvm_vcpu *vcpu) +static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu) { return kvm_vcpu_trap_get_class(vcpu) == HSR_EC_IABT; } +static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu); +} + static inline u8 kvm_vcpu_trap_get_fault(struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & HSR_FSC; @@ -341,6 +368,7 @@ } } -static inline void vcpu_ptrauth_setup_lazy(struct kvm_vcpu *vcpu) {} +static inline bool vcpu_has_ptrauth(struct kvm_vcpu *vcpu) { return false; } +static inline void vcpu_ptrauth_disable(struct kvm_vcpu *vcpu) { } #endif /* __ARM_KVM_EMULATE_H__ */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kvm_host.h @@ -266,7 +266,7 @@ #define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range(struct kvm *kvm, - unsigned long start, unsigned long end); + unsigned long start, unsigned long end, unsigned flags); int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu); @@ -335,6 +335,7 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_init_debug(void) {} +static inline void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {} static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {} @@ -421,4 +422,6 @@ return true; } +#define kvm_arm_vcpu_loaded(vcpu) (false) + #endif /* __ARM_KVM_HOST_H__ */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/kvm_mmio.h +++ linux-oracle-5.4.0/arch/arm/include/asm/kvm_mmio.h @@ -14,6 +14,8 @@ struct kvm_decode { unsigned long rt; bool sign_extend; + /* Not used on 32-bit arm */ + bool sixty_four; }; void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data); --- linux-oracle-5.4.0.orig/arch/arm/include/asm/mach/map.h +++ linux-oracle-5.4.0/arch/arm/include/asm/mach/map.h @@ -27,6 +27,7 @@ MT_HIGH_VECTORS, MT_MEMORY_RWX, MT_MEMORY_RW, + MT_MEMORY_RO, MT_ROM, MT_MEMORY_RWX_NONCACHED, MT_MEMORY_RW_DTCM, --- linux-oracle-5.4.0.orig/arch/arm/include/asm/memory.h +++ linux-oracle-5.4.0/arch/arm/include/asm/memory.h @@ -67,6 +67,10 @@ */ #define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) +#define FDT_FIXED_BASE UL(0xff800000) +#define FDT_FIXED_SIZE (2 * SECTION_SIZE) +#define FDT_VIRT_BASE(physbase) ((void *)(FDT_FIXED_BASE | (physbase) % SECTION_SIZE)) + #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) /* * Allow 16MB-aligned ioremap pages @@ -107,6 +111,7 @@ #define MODULES_VADDR PAGE_OFFSET #define XIP_VIRT_ADDR(physaddr) (physaddr) +#define FDT_VIRT_BASE(physbase) ((void *)(physbase)) #endif /* !CONFIG_MMU */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/module.h +++ linux-oracle-5.4.0/arch/arm/include/asm/module.h @@ -19,8 +19,18 @@ }; #endif +#define PLT_ENT_STRIDE L1_CACHE_BYTES +#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32)) +#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT) + +struct plt_entries { + u32 ldr[PLT_ENT_COUNT]; + u32 lit[PLT_ENT_COUNT]; +}; + struct mod_plt_sec { struct elf32_shdr *plt; + struct plt_entries *plt_ent; int plt_count; }; --- linux-oracle-5.4.0.orig/arch/arm/include/asm/percpu.h +++ linux-oracle-5.4.0/arch/arm/include/asm/percpu.h @@ -5,6 +5,8 @@ #ifndef _ASM_ARM_PERCPU_H_ #define _ASM_ARM_PERCPU_H_ +#include + /* * Same as asm-generic/percpu.h, except that we store the per cpu offset * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7 --- linux-oracle-5.4.0.orig/arch/arm/include/asm/perf_event.h +++ linux-oracle-5.4.0/arch/arm/include/asm/perf_event.h @@ -17,7 +17,7 @@ #define perf_arch_fetch_caller_regs(regs, __ip) { \ (regs)->ARM_pc = (__ip); \ - (regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \ + frame_pointer((regs)) = (unsigned long) __builtin_frame_address(0); \ (regs)->ARM_sp = current_stack_pointer; \ (regs)->ARM_cpsr = SVC_MODE; \ } --- linux-oracle-5.4.0.orig/arch/arm/include/asm/pgtable-2level.h +++ linux-oracle-5.4.0/arch/arm/include/asm/pgtable-2level.h @@ -75,6 +75,8 @@ #define PTE_HWTABLE_OFF (PTE_HWTABLE_PTRS * sizeof(pte_t)) #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u32)) +#define MAX_POSSIBLE_PHYSMEM_BITS 32 + /* * PMD_SHIFT determines the size of the area a second-level page table can map * PGDIR_SHIFT determines what a third-level page table entry can map --- linux-oracle-5.4.0.orig/arch/arm/include/asm/pgtable-3level.h +++ linux-oracle-5.4.0/arch/arm/include/asm/pgtable-3level.h @@ -25,6 +25,8 @@ #define PTE_HWTABLE_OFF (0) #define PTE_HWTABLE_SIZE (PTRS_PER_PTE * sizeof(u64)) +#define MAX_POSSIBLE_PHYSMEM_BITS 40 + /* * PGDIR_SHIFT determines the size a top-level page table entry can map. */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/pgtable-nommu.h +++ linux-oracle-5.4.0/arch/arm/include/asm/pgtable-nommu.h @@ -52,12 +52,6 @@ typedef pte_t *pte_addr_t; /* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -#define ZERO_PAGE(vaddr) (virt_to_page(0)) - -/* * Mark the prot value as uncacheable and unbufferable. */ #define pgprot_noncached(prot) (prot) --- linux-oracle-5.4.0.orig/arch/arm/include/asm/pgtable.h +++ linux-oracle-5.4.0/arch/arm/include/asm/pgtable.h @@ -10,6 +10,15 @@ #include #include +#ifndef __ASSEMBLY__ +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern struct page *empty_zero_page; +#define ZERO_PAGE(vaddr) (empty_zero_page) +#endif + #ifndef CONFIG_MMU #include @@ -166,13 +175,6 @@ #define __S111 __PAGE_SHARED_EXEC #ifndef __ASSEMBLY__ -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -extern struct page *empty_zero_page; -#define ZERO_PAGE(vaddr) (empty_zero_page) - extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; --- linux-oracle-5.4.0.orig/arch/arm/include/asm/prom.h +++ linux-oracle-5.4.0/arch/arm/include/asm/prom.h @@ -9,12 +9,12 @@ #ifdef CONFIG_OF -extern const struct machine_desc *setup_machine_fdt(unsigned int dt_phys); +extern const struct machine_desc *setup_machine_fdt(void *dt_virt); extern void __init arm_dt_init_cpu_maps(void); #else /* CONFIG_OF */ -static inline const struct machine_desc *setup_machine_fdt(unsigned int dt_phys) +static inline const struct machine_desc *setup_machine_fdt(void *dt_virt) { return NULL; } --- linux-oracle-5.4.0.orig/arch/arm/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/arm/include/asm/ptrace.h @@ -164,5 +164,31 @@ ((current_stack_pointer | (THREAD_SIZE - 1)) - 7) - 1; \ }) + +/* + * Update ITSTATE after normal execution of an IT block instruction. + * + * The 8 IT state bits are split into two parts in CPSR: + * ITSTATE<1:0> are in CPSR<26:25> + * ITSTATE<7:2> are in CPSR<15:10> + */ +static inline unsigned long it_advance(unsigned long cpsr) +{ + if ((cpsr & 0x06000400) == 0) { + /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ + cpsr &= ~PSR_IT_MASK; + } else { + /* We need to shift left ITSTATE<4:0> */ + const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ + unsigned long it = cpsr & mask; + it <<= 1; + it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ + it &= mask; + cpsr &= ~mask; + cpsr |= it; + } + return cpsr; +} + #endif /* __ASSEMBLY__ */ #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/spectre.h +++ linux-oracle-5.4.0/arch/arm/include/asm/spectre.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_SPECTRE_H +#define __ASM_SPECTRE_H + +enum { + SPECTRE_UNAFFECTED, + SPECTRE_MITIGATED, + SPECTRE_VULNERABLE, +}; + +enum { + __SPECTRE_V2_METHOD_BPIALL, + __SPECTRE_V2_METHOD_ICIALLU, + __SPECTRE_V2_METHOD_SMC, + __SPECTRE_V2_METHOD_HVC, + __SPECTRE_V2_METHOD_LOOP8, +}; + +enum { + SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL), + SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU), + SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC), + SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC), + SPECTRE_V2_METHOD_LOOP8 = BIT(__SPECTRE_V2_METHOD_LOOP8), +}; + +#ifdef CONFIG_GENERIC_CPU_VULNERABILITIES +void spectre_v2_update_state(unsigned int state, unsigned int methods); +#else +static inline void spectre_v2_update_state(unsigned int state, + unsigned int methods) +{} +#endif + +int spectre_bhb_update_vectors(unsigned int method); + +#endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/timex.h +++ linux-oracle-5.4.0/arch/arm/include/asm/timex.h @@ -11,5 +11,6 @@ typedef unsigned long cycles_t; #define get_cycles() ({ cycles_t c; read_current_timer(&c) ? 0 : c; }) +#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback()) #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/uaccess-asm.h +++ linux-oracle-5.4.0/arch/arm/include/asm/uaccess-asm.h @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ASM_UACCESS_ASM_H__ +#define __ASM_UACCESS_ASM_H__ + +#include +#include +#include +#include + + .macro csdb +#ifdef CONFIG_THUMB2_KERNEL + .inst.w 0xf3af8014 +#else + .inst 0xe320f014 +#endif + .endm + + .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req +#ifndef CONFIG_CPU_USE_DOMAINS + adds \tmp, \addr, #\size - 1 + sbcscc \tmp, \tmp, \limit + bcs \bad +#ifdef CONFIG_CPU_SPECTRE + movcs \addr, #0 + csdb +#endif +#endif + .endm + + .macro uaccess_mask_range_ptr, addr:req, size:req, limit:req, tmp:req +#ifdef CONFIG_CPU_SPECTRE + sub \tmp, \limit, #1 + subs \tmp, \tmp, \addr @ tmp = limit - 1 - addr + addhs \tmp, \tmp, #1 @ if (tmp >= 0) { + subshs \tmp, \tmp, \size @ tmp = limit - (addr + size) } + movlo \addr, #0 @ if (tmp < 0) addr = NULL + csdb +#endif + .endm + + .macro uaccess_disable, tmp, isb=1 +#ifdef CONFIG_CPU_SW_DOMAIN_PAN + /* + * Whenever we re-enter userspace, the domains should always be + * set appropriately. + */ + mov \tmp, #DACR_UACCESS_DISABLE + mcr p15, 0, \tmp, c3, c0, 0 @ Set domain register + .if \isb + instr_sync + .endif +#endif + .endm + + .macro uaccess_enable, tmp, isb=1 +#ifdef CONFIG_CPU_SW_DOMAIN_PAN + /* + * Whenever we re-enter userspace, the domains should always be + * set appropriately. + */ + mov \tmp, #DACR_UACCESS_ENABLE + mcr p15, 0, \tmp, c3, c0, 0 + .if \isb + instr_sync + .endif +#endif + .endm + +#if defined(CONFIG_CPU_SW_DOMAIN_PAN) || defined(CONFIG_CPU_USE_DOMAINS) +#define DACR(x...) x +#else +#define DACR(x...) +#endif + + /* + * Save the address limit on entry to a privileged exception. + * + * If we are using the DACR for kernel access by the user accessors + * (CONFIG_CPU_USE_DOMAINS=y), always reset the DACR kernel domain + * back to client mode, whether or not \disable is set. + * + * If we are using SW PAN, set the DACR user domain to no access + * if \disable is set. + */ + .macro uaccess_entry, tsk, tmp0, tmp1, tmp2, disable + ldr \tmp1, [\tsk, #TI_ADDR_LIMIT] + mov \tmp2, #TASK_SIZE + str \tmp2, [\tsk, #TI_ADDR_LIMIT] + DACR( mrc p15, 0, \tmp0, c3, c0, 0) + DACR( str \tmp0, [sp, #SVC_DACR]) + str \tmp1, [sp, #SVC_ADDR_LIMIT] + .if \disable && IS_ENABLED(CONFIG_CPU_SW_DOMAIN_PAN) + /* kernel=client, user=no access */ + mov \tmp2, #DACR_UACCESS_DISABLE + mcr p15, 0, \tmp2, c3, c0, 0 + instr_sync + .elseif IS_ENABLED(CONFIG_CPU_USE_DOMAINS) + /* kernel=client */ + bic \tmp2, \tmp0, #domain_mask(DOMAIN_KERNEL) + orr \tmp2, \tmp2, #domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) + mcr p15, 0, \tmp2, c3, c0, 0 + instr_sync + .endif + .endm + + /* Restore the user access state previously saved by uaccess_entry */ + .macro uaccess_exit, tsk, tmp0, tmp1 + ldr \tmp1, [sp, #SVC_ADDR_LIMIT] + DACR( ldr \tmp0, [sp, #SVC_DACR]) + str \tmp1, [\tsk, #TI_ADDR_LIMIT] + DACR( mcr p15, 0, \tmp0, c3, c0, 0) + .endm + +#undef DACR + +#endif /* __ASM_UACCESS_ASM_H__ */ --- linux-oracle-5.4.0.orig/arch/arm/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/arm/include/asm/uaccess.h @@ -143,16 +143,6 @@ extern int __get_user_64t_2(void *); extern int __get_user_64t_4(void *); -#define __GUP_CLOBBER_1 "lr", "cc" -#ifdef CONFIG_CPU_USE_DOMAINS -#define __GUP_CLOBBER_2 "ip", "lr", "cc" -#else -#define __GUP_CLOBBER_2 "lr", "cc" -#endif -#define __GUP_CLOBBER_4 "lr", "cc" -#define __GUP_CLOBBER_32t_8 "lr", "cc" -#define __GUP_CLOBBER_8 "lr", "cc" - #define __get_user_x(__r2, __p, __e, __l, __s) \ __asm__ __volatile__ ( \ __asmeq("%0", "r0") __asmeq("%1", "r2") \ @@ -160,7 +150,7 @@ "bl __get_user_" #__s \ : "=&r" (__e), "=r" (__r2) \ : "0" (__p), "r" (__l) \ - : __GUP_CLOBBER_##__s) + : "ip", "lr", "cc") /* narrowing a double-word get into a single 32bit word register: */ #ifdef __ARMEB__ @@ -182,7 +172,7 @@ "bl __get_user_64t_" #__s \ : "=&r" (__e), "=r" (__r2) \ : "0" (__p), "r" (__l) \ - : __GUP_CLOBBER_##__s) + : "ip", "lr", "cc") #else #define __get_user_x_64t __get_user_x #endif --- linux-oracle-5.4.0.orig/arch/arm/include/asm/vfpmacros.h +++ linux-oracle-5.4.0/arch/arm/include/asm/vfpmacros.h @@ -19,23 +19,25 @@ @ read all the working registers back into the VFP .macro VFPFLDMIA, base, tmp + .fpu vfpv2 #if __LINUX_ARM_ARCH__ < 6 - LDC p11, cr0, [\base],#33*4 @ FLDMIAX \base!, {d0-d15} + fldmiax \base!, {d0-d15} #else - LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15} + vldmia \base!, {d0-d15} #endif #ifdef CONFIG_VFPv3 + .fpu vfpv3 #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] tst \tmp, #HWCAP_VFPD32 - ldclne p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + vldmiane \base!, {d16-d31} addeq \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field cmp \tmp, #2 @ 32 x 64bit registers? - ldcleq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31} + vldmiaeq \base!, {d16-d31} addne \base, \base, #32*4 @ step over unused register space #endif #endif @@ -44,22 +46,23 @@ @ write all the working registers out of the VFP .macro VFPFSTMIA, base, tmp #if __LINUX_ARM_ARCH__ < 6 - STC p11, cr0, [\base],#33*4 @ FSTMIAX \base!, {d0-d15} + fstmiax \base!, {d0-d15} #else - STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15} + vstmia \base!, {d0-d15} #endif #ifdef CONFIG_VFPv3 + .fpu vfpv3 #if __LINUX_ARM_ARCH__ <= 6 ldr \tmp, =elf_hwcap @ may not have MVFR regs ldr \tmp, [\tmp, #0] tst \tmp, #HWCAP_VFPD32 - stclne p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + vstmiane \base!, {d16-d31} addeq \base, \base, #32*4 @ step over unused register space #else VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0 and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field cmp \tmp, #2 @ 32 x 64bit registers? - stcleq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31} + vstmiaeq \base!, {d16-d31} addne \base, \base, #32*4 @ step over unused register space #endif #endif --- linux-oracle-5.4.0.orig/arch/arm/kernel/Makefile +++ linux-oracle-5.4.0/arch/arm/kernel/Makefile @@ -17,10 +17,14 @@ # Object file lists. obj-y := elf.o entry-common.o irq.o opcodes.o \ - process.o ptrace.o reboot.o return_address.o \ + process.o ptrace.o reboot.o \ setup.o signal.o sigreturn_codes.o \ stacktrace.o sys_arm.o time.o traps.o +ifneq ($(CONFIG_ARM_UNWIND),y) +obj-$(CONFIG_FRAME_POINTER) += return_address.o +endif + obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o @@ -102,4 +106,6 @@ obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o +obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o + extra-y := $(head-y) vmlinux.lds --- linux-oracle-5.4.0.orig/arch/arm/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/arm/kernel/asm-offsets.c @@ -15,6 +15,7 @@ #include #endif #include +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include "signal.h" /* @@ -159,6 +161,8 @@ DEFINE(SLEEP_SAVE_SP_PHYS, offsetof(struct sleep_save_sp, save_ptr_stash_phys)); DEFINE(SLEEP_SAVE_SP_VIRT, offsetof(struct sleep_save_sp, save_ptr_stash)); #endif + DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); + DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); BLANK(); DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); @@ -190,5 +194,9 @@ DEFINE(MPU_RGN_PRBAR, offsetof(struct mpu_rgn, prbar)); DEFINE(MPU_RGN_PRLAR, offsetof(struct mpu_rgn, prlar)); #endif + DEFINE(KEXEC_START_ADDR, offsetof(struct kexec_relocate_data, kexec_start_address)); + DEFINE(KEXEC_INDIR_PAGE, offsetof(struct kexec_relocate_data, kexec_indirection_page)); + DEFINE(KEXEC_MACH_TYPE, offsetof(struct kexec_relocate_data, kexec_mach_type)); + DEFINE(KEXEC_R2, offsetof(struct kexec_relocate_data, kexec_r2)); return 0; } --- linux-oracle-5.4.0.orig/arch/arm/kernel/atags.h +++ linux-oracle-5.4.0/arch/arm/kernel/atags.h @@ -2,11 +2,11 @@ void convert_to_tag_list(struct tag *tags); #ifdef CONFIG_ATAGS -const struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, +const struct machine_desc *setup_machine_tags(void *__atags_vaddr, unsigned int machine_nr); #else static inline const struct machine_desc * __init __noreturn -setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +setup_machine_tags(void *__atags_vaddr, unsigned int machine_nr) { early_print("no ATAGS support: can't continue\n"); while (true); --- linux-oracle-5.4.0.orig/arch/arm/kernel/atags_parse.c +++ linux-oracle-5.4.0/arch/arm/kernel/atags_parse.c @@ -176,7 +176,7 @@ } const struct machine_desc * __init -setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +setup_machine_tags(void *atags_vaddr, unsigned int machine_nr) { struct tag *tags = (struct tag *)&default_tags; const struct machine_desc *mdesc = NULL, *p; @@ -197,8 +197,8 @@ if (!mdesc) return NULL; - if (__atags_pointer) - tags = phys_to_virt(__atags_pointer); + if (atags_vaddr) + tags = atags_vaddr; else if (mdesc->atag_offset) tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); --- linux-oracle-5.4.0.orig/arch/arm/kernel/bugs.c +++ linux-oracle-5.4.0/arch/arm/kernel/bugs.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include #include #include @@ -11,7 +12,7 @@ #endif } -void __init check_bugs(void) +void __init arch_cpu_finalize_init(void) { check_writebuffer_bugs(); check_other_bugs(); --- linux-oracle-5.4.0.orig/arch/arm/kernel/devtree.c +++ linux-oracle-5.4.0/arch/arm/kernel/devtree.c @@ -203,12 +203,12 @@ /** * setup_machine_fdt - Machine setup when an dtb was passed to the kernel - * @dt_phys: physical address of dt blob + * @dt_virt: virtual address of dt blob * * If a dtb was passed to the kernel in r2, then use it to choose the * correct machine_desc and to setup the system. */ -const struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys) +const struct machine_desc * __init setup_machine_fdt(void *dt_virt) { const struct machine_desc *mdesc, *mdesc_best = NULL; @@ -221,7 +221,7 @@ mdesc_best = &__mach_desc_GENERIC_DT; #endif - if (!dt_phys || !early_init_dt_verify(phys_to_virt(dt_phys))) + if (!dt_virt || !early_init_dt_verify(dt_virt)) return NULL; mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach); --- linux-oracle-5.4.0.orig/arch/arm/kernel/elf.c +++ linux-oracle-5.4.0/arch/arm/kernel/elf.c @@ -78,13 +78,32 @@ EXPORT_SYMBOL(elf_set_personality); /* - * Set READ_IMPLIES_EXEC if: - * - the binary requires an executable stack - * - we're running on a CPU which doesn't support NX. + * An executable for which elf_read_implies_exec() returns TRUE will + * have the READ_IMPLIES_EXEC personality flag set automatically. + * + * The decision process for determining the results are: + * + * CPU: | lacks NX* | has NX | + * ELF: | | | + * ---------------------|------------|------------| + * missing PT_GNU_STACK | exec-all | exec-all | + * PT_GNU_STACK == RWX | exec-all | exec-stack | + * PT_GNU_STACK == RW | exec-all | exec-none | + * + * exec-all : all PROT_READ user mappings are executable, except when + * backed by files on a noexec-filesystem. + * exec-none : only PROT_EXEC user mappings are executable. + * exec-stack: only the stack and PROT_EXEC user mappings are executable. + * + * *this column has no architectural effect: NX markings are ignored by + * hardware, but may have behavioral effects when "wants X" collides with + * "cannot be X" constraints in memory permission flags, as in + * https://lkml.kernel.org/r/20190418055759.GA3155@mellanox.com + * */ int arm_elf_read_implies_exec(int executable_stack) { - if (executable_stack != EXSTACK_DISABLE_X) + if (executable_stack == EXSTACK_DEFAULT) return 1; if (cpu_architecture() < CPU_ARCH_ARMv6) return 1; --- linux-oracle-5.4.0.orig/arch/arm/kernel/entry-armv.S +++ linux-oracle-5.4.0/arch/arm/kernel/entry-armv.S @@ -27,6 +27,7 @@ #include #include #include +#include #include "entry-header.S" #include @@ -179,15 +180,7 @@ stmia r7, {r2 - r6} get_thread_info tsk - ldr r0, [tsk, #TI_ADDR_LIMIT] - mov r1, #TASK_SIZE - str r1, [tsk, #TI_ADDR_LIMIT] - str r0, [sp, #SVC_ADDR_LIMIT] - - uaccess_save r0 - .if \uaccess - uaccess_disable r0 - .endif + uaccess_entry tsk, r0, r1, r2, \uaccess .if \trace #ifdef CONFIG_TRACE_IRQFLAGS @@ -259,31 +252,10 @@ #else svc_entry #endif - @ - @ call emulation code, which returns using r9 if it has emulated - @ the instruction, or the more conventional lr if we are to treat - @ this as a real undefined instruction - @ - @ r0 - instruction - @ -#ifndef CONFIG_THUMB2_KERNEL - ldr r0, [r4, #-4] -#else - mov r1, #2 - ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 - cmp r0, #0xe800 @ 32-bit instruction if xx >= 0 - blo __und_svc_fault - ldrh r9, [r4] @ bottom 16 bits - add r4, r4, #2 - str r4, [sp, #S_PC] - orr r0, r9, r0, lsl #16 -#endif - badr r9, __und_svc_finish - mov r2, r4 - bl call_fpe mov r1, #4 @ PC correction to apply -__und_svc_fault: + THUMB( tst r5, #PSR_T_BIT ) @ exception taken in Thumb mode? + THUMB( movne r1, #2 ) @ if so, fix up PC correction mov r0, sp @ struct pt_regs *regs bl __und_fault @@ -624,11 +596,9 @@ tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 reteq lr and r8, r0, #0x00000f00 @ mask out CP number - THUMB( lsr r8, r8, #8 ) mov r7, #1 - add r6, r10, #TI_USED_CP - ARM( strb r7, [r6, r8, lsr #8] ) @ set appropriate used_cp[] - THUMB( strb r7, [r6, r8] ) @ set appropriate used_cp[] + add r6, r10, r8, lsr #8 @ add used_cp[] array offset first + strb r7, [r6, #TI_USED_CP] @ set appropriate used_cp[] #ifdef CONFIG_IWMMXT @ Test if we need to give access to iWMMXt coprocessors ldr r5, [r10, #TI_FLAGS] @@ -637,7 +607,7 @@ bcs iwmmxt_task_enable #endif ARM( add pc, pc, r8, lsr #6 ) - THUMB( lsl r8, r8, #2 ) + THUMB( lsr r8, r8, #6 ) THUMB( add pc, r8 ) nop @@ -1035,12 +1005,11 @@ sub lr, lr, #\correction .endif - @ - @ Save r0, lr_ (parent PC) and spsr_ - @ (parent CPSR) - @ + @ Save r0, lr_ (parent PC) stmia sp, {r0, lr} @ save r0, lr - mrs lr, spsr + + @ Save spsr_ (parent CPSR) +2: mrs lr, spsr str lr, [sp, #8] @ save spsr @ @@ -1061,6 +1030,44 @@ movs pc, lr @ branch to handler in SVC mode ENDPROC(vector_\name) +#ifdef CONFIG_HARDEN_BRANCH_HISTORY + .subsection 1 + .align 5 +vector_bhb_loop8_\name: + .if \correction + sub lr, lr, #\correction + .endif + + @ Save r0, lr_ (parent PC) + stmia sp, {r0, lr} + + @ bhb workaround + mov r0, #8 +3: W(b) . + 4 + subs r0, r0, #1 + bne 3b + dsb + isb + b 2b +ENDPROC(vector_bhb_loop8_\name) + +vector_bhb_bpiall_\name: + .if \correction + sub lr, lr, #\correction + .endif + + @ Save r0, lr_ (parent PC) + stmia sp, {r0, lr} + + @ bhb workaround + mcr p15, 0, r0, c7, c5, 6 @ BPIALL + @ isb not needed due to "movs pc, lr" in the vector stub + @ which gives a "context synchronisation". + b 2b +ENDPROC(vector_bhb_bpiall_\name) + .previous +#endif + .align 2 @ handler addresses follow this label 1: @@ -1069,6 +1076,10 @@ .section .stubs, "ax", %progbits @ This must be the first word .word vector_swi +#ifdef CONFIG_HARDEN_BRANCH_HISTORY + .word vector_bhb_loop8_swi + .word vector_bhb_bpiall_swi +#endif vector_rst: ARM( swi SYS_ERROR0 ) @@ -1183,8 +1194,10 @@ * FIQ "NMI" handler *----------------------------------------------------------------------------- * Handle a FIQ using the SVC stack allowing FIQ act like NMI on x86 - * systems. + * systems. This must be the last vector stub, so lets place it in its own + * subsection. */ + .subsection 2 vector_stub fiq, FIQ_MODE, 4 .long __fiq_usr @ 0 (USR_26 / USR_32) @@ -1217,6 +1230,30 @@ W(b) vector_irq W(b) vector_fiq +#ifdef CONFIG_HARDEN_BRANCH_HISTORY + .section .vectors.bhb.loop8, "ax", %progbits +.L__vectors_bhb_loop8_start: + W(b) vector_rst + W(b) vector_bhb_loop8_und + W(ldr) pc, .L__vectors_bhb_loop8_start + 0x1004 + W(b) vector_bhb_loop8_pabt + W(b) vector_bhb_loop8_dabt + W(b) vector_addrexcptn + W(b) vector_bhb_loop8_irq + W(b) vector_bhb_loop8_fiq + + .section .vectors.bhb.bpiall, "ax", %progbits +.L__vectors_bhb_bpiall_start: + W(b) vector_rst + W(b) vector_bhb_bpiall_und + W(ldr) pc, .L__vectors_bhb_bpiall_start + 0x1008 + W(b) vector_bhb_bpiall_pabt + W(b) vector_bhb_bpiall_dabt + W(b) vector_addrexcptn + W(b) vector_bhb_bpiall_irq + W(b) vector_bhb_bpiall_fiq +#endif + .data .align 2 --- linux-oracle-5.4.0.orig/arch/arm/kernel/entry-common.S +++ linux-oracle-5.4.0/arch/arm/kernel/entry-common.S @@ -163,12 +163,36 @@ */ .align 5 +#ifdef CONFIG_HARDEN_BRANCH_HISTORY +ENTRY(vector_bhb_loop8_swi) + sub sp, sp, #PT_REGS_SIZE + stmia sp, {r0 - r12} + mov r8, #8 +1: b 2f +2: subs r8, r8, #1 + bne 1b + dsb + isb + b 3f +ENDPROC(vector_bhb_loop8_swi) + + .align 5 +ENTRY(vector_bhb_bpiall_swi) + sub sp, sp, #PT_REGS_SIZE + stmia sp, {r0 - r12} + mcr p15, 0, r8, c7, c5, 6 @ BPIALL + isb + b 3f +ENDPROC(vector_bhb_bpiall_swi) +#endif + .align 5 ENTRY(vector_swi) #ifdef CONFIG_CPU_V7M v7m_exception_entry #else sub sp, sp, #PT_REGS_SIZE stmia sp, {r0 - r12} @ Calling r0 - r12 +3: ARM( add r8, sp, #S_PC ) ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr THUMB( mov r8, sp ) --- linux-oracle-5.4.0.orig/arch/arm/kernel/entry-header.S +++ linux-oracle-5.4.0/arch/arm/kernel/entry-header.S @@ -6,6 +6,7 @@ #include #include #include +#include #include @ Bad Abort numbers @@ -217,9 +218,7 @@ blne trace_hardirqs_off #endif .endif - ldr r1, [sp, #SVC_ADDR_LIMIT] - uaccess_restore - str r1, [tsk, #TI_ADDR_LIMIT] + uaccess_exit tsk, r0, r1 #ifndef CONFIG_THUMB2_KERNEL @ ARM mode SVC restore @@ -263,9 +262,7 @@ @ on the stack remains correct). @ .macro svc_exit_via_fiq - ldr r1, [sp, #SVC_ADDR_LIMIT] - uaccess_restore - str r1, [tsk, #TI_ADDR_LIMIT] + uaccess_exit tsk, r0, r1 #ifndef CONFIG_THUMB2_KERNEL @ ARM mode restore mov r0, sp --- linux-oracle-5.4.0.orig/arch/arm/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/arm/kernel/ftrace.c @@ -71,9 +71,10 @@ return 0; } -static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) +static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr, + bool warn) { - return arm_gen_branch_link(pc, addr); + return arm_gen_branch_link(pc, addr, warn); } static int ftrace_modify_code(unsigned long pc, unsigned long old, @@ -112,14 +113,14 @@ int ret; pc = (unsigned long)&ftrace_call; - new = ftrace_call_replace(pc, (unsigned long)func); + new = ftrace_call_replace(pc, (unsigned long)func, true); ret = ftrace_modify_code(pc, 0, new, false); #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS if (!ret) { pc = (unsigned long)&ftrace_regs_call; - new = ftrace_call_replace(pc, (unsigned long)func); + new = ftrace_call_replace(pc, (unsigned long)func, true); ret = ftrace_modify_code(pc, 0, new, false); } @@ -132,10 +133,22 @@ { unsigned long new, old; unsigned long ip = rec->ip; + unsigned long aaddr = adjust_address(rec, addr); + struct module *mod = NULL; + +#ifdef CONFIG_ARM_MODULE_PLTS + mod = rec->arch.mod; +#endif old = ftrace_nop_replace(rec); - new = ftrace_call_replace(ip, adjust_address(rec, addr)); + new = ftrace_call_replace(ip, aaddr, !mod); +#ifdef CONFIG_ARM_MODULE_PLTS + if (!new && mod) { + aaddr = get_module_plt(mod, ip, aaddr); + new = ftrace_call_replace(ip, aaddr, true); + } +#endif return ftrace_modify_code(rec->ip, old, new, true); } @@ -148,9 +161,9 @@ unsigned long new, old; unsigned long ip = rec->ip; - old = ftrace_call_replace(ip, adjust_address(rec, old_addr)); + old = ftrace_call_replace(ip, adjust_address(rec, old_addr), true); - new = ftrace_call_replace(ip, adjust_address(rec, addr)); + new = ftrace_call_replace(ip, adjust_address(rec, addr), true); return ftrace_modify_code(rec->ip, old, new, true); } @@ -160,12 +173,29 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { + unsigned long aaddr = adjust_address(rec, addr); unsigned long ip = rec->ip; unsigned long old; unsigned long new; int ret; - old = ftrace_call_replace(ip, adjust_address(rec, addr)); +#ifdef CONFIG_ARM_MODULE_PLTS + /* mod is only supplied during module loading */ + if (!mod) + mod = rec->arch.mod; + else + rec->arch.mod = mod; +#endif + + old = ftrace_call_replace(ip, aaddr, + !IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || !mod); +#ifdef CONFIG_ARM_MODULE_PLTS + if (!old && mod) { + aaddr = get_module_plt(mod, ip, aaddr); + old = ftrace_call_replace(ip, aaddr, true); + } +#endif + new = ftrace_nop_replace(rec); ret = ftrace_modify_code(ip, old, new, true); --- linux-oracle-5.4.0.orig/arch/arm/kernel/head.S +++ linux-oracle-5.4.0/arch/arm/kernel/head.S @@ -274,11 +274,10 @@ * We map 2 sections in case the ATAGs/DTB crosses a section boundary. */ mov r0, r2, lsr #SECTION_SHIFT - movs r0, r0, lsl #SECTION_SHIFT - subne r3, r0, r8 - addne r3, r3, #PAGE_OFFSET - addne r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) - orrne r6, r7, r0 + cmp r2, #0 + ldrne r3, =FDT_FIXED_BASE >> (SECTION_SHIFT - PMD_ORDER) + addne r3, r3, r4 + orrne r6, r7, r0, lsl #SECTION_SHIFT strne r6, [r3], #1 << PMD_ORDER addne r6, r6, #1 << SECTION_SHIFT strne r6, [r3] @@ -672,11 +671,7 @@ bcc 1b bx lr #else -#ifdef CONFIG_CPU_ENDIAN_BE8 - moveq r0, #0x00004000 @ set bit 22, mov to mvn instruction -#else moveq r0, #0x400000 @ set bit 22, mov to mvn instruction -#endif b 2f 1: ldr ip, [r7, r3] #ifdef CONFIG_CPU_ENDIAN_BE8 @@ -685,7 +680,7 @@ tst ip, #0x000f0000 @ check the rotation field orrne ip, ip, r6, lsl #24 @ mask in offset bits 31-24 biceq ip, ip, #0x00004000 @ clear bit 22 - orreq ip, ip, r0 @ mask in offset bits 7-0 + orreq ip, ip, r0, ror #8 @ mask in offset bits 7-0 #else bic ip, ip, #0x000000ff tst ip, #0xf00 @ check the rotation field --- linux-oracle-5.4.0.orig/arch/arm/kernel/hw_breakpoint.c +++ linux-oracle-5.4.0/arch/arm/kernel/hw_breakpoint.c @@ -623,7 +623,7 @@ hw->address &= ~alignment_mask; hw->ctrl.len <<= offset; - if (is_default_overflow_handler(bp)) { + if (uses_default_overflow_handler(bp)) { /* * Mismatch breakpoints are required for single-stepping * breakpoints. @@ -680,26 +680,68 @@ arch_install_hw_breakpoint(bp); } +/* + * Arm32 hardware does not always report a watchpoint hit address that matches + * one of the watchpoints set. It can also report an address "near" the + * watchpoint if a single instruction access both watched and unwatched + * addresses. There is no straight-forward way, short of disassembling the + * offending instruction, to map that address back to the watchpoint. This + * function computes the distance of the memory access from the watchpoint as a + * heuristic for the likelyhood that a given access triggered the watchpoint. + * + * See this same function in the arm64 platform code, which has the same + * problem. + * + * The function returns the distance of the address from the bytes watched by + * the watchpoint. In case of an exact match, it returns 0. + */ +static u32 get_distance_from_watchpoint(unsigned long addr, u32 val, + struct arch_hw_breakpoint_ctrl *ctrl) +{ + u32 wp_low, wp_high; + u32 lens, lene; + + lens = __ffs(ctrl->len); + lene = __fls(ctrl->len); + + wp_low = val + lens; + wp_high = val + lene; + if (addr < wp_low) + return wp_low - addr; + else if (addr > wp_high) + return addr - wp_high; + else + return 0; +} + +static int watchpoint_fault_on_uaccess(struct pt_regs *regs, + struct arch_hw_breakpoint *info) +{ + return !user_mode(regs) && info->ctrl.privilege == ARM_BREAKPOINT_USER; +} + static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - int i, access; - u32 val, ctrl_reg, alignment_mask; + int i, access, closest_match = 0; + u32 min_dist = -1, dist; + u32 val, ctrl_reg; struct perf_event *wp, **slots; struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; slots = this_cpu_ptr(wp_on_reg); + /* + * Find all watchpoints that match the reported address. If no exact + * match is found. Attribute the hit to the closest watchpoint. + */ + rcu_read_lock(); for (i = 0; i < core_num_wrps; ++i) { - rcu_read_lock(); - wp = slots[i]; - if (wp == NULL) - goto unlock; + continue; - info = counter_arch_bp(wp); /* * The DFAR is an unknown value on debug architectures prior * to 7.1. Since we only allow a single watchpoint on these @@ -708,50 +750,69 @@ */ if (debug_arch < ARM_DEBUG_ARCH_V7_1) { BUG_ON(i > 0); + info = counter_arch_bp(wp); info->trigger = wp->attr.bp_addr; } else { - if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) - alignment_mask = 0x7; - else - alignment_mask = 0x3; - - /* Check if the watchpoint value matches. */ - val = read_wb_reg(ARM_BASE_WVR + i); - if (val != (addr & ~alignment_mask)) - goto unlock; - - /* Possible match, check the byte address select. */ - ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); - decode_ctrl_reg(ctrl_reg, &ctrl); - if (!((1 << (addr & alignment_mask)) & ctrl.len)) - goto unlock; - /* Check that the access type matches. */ if (debug_exception_updates_fsr()) { access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : HW_BREAKPOINT_R; if (!(access & hw_breakpoint_type(wp))) - goto unlock; + continue; + } + + val = read_wb_reg(ARM_BASE_WVR + i); + ctrl_reg = read_wb_reg(ARM_BASE_WCR + i); + decode_ctrl_reg(ctrl_reg, &ctrl); + dist = get_distance_from_watchpoint(addr, val, &ctrl); + if (dist < min_dist) { + min_dist = dist; + closest_match = i; } + /* Is this an exact match? */ + if (dist != 0) + continue; /* We have a winner. */ + info = counter_arch_bp(wp); info->trigger = addr; } pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); + + /* + * If we triggered a user watchpoint from a uaccess routine, + * then handle the stepping ourselves since userspace really + * can't help us with this. + */ + if (watchpoint_fault_on_uaccess(regs, info)) + goto step; + perf_bp_event(wp, regs); /* - * If no overflow handler is present, insert a temporary - * mismatch breakpoint so we can single-step over the - * watchpoint trigger. + * Defer stepping to the overflow handler if one is installed. + * Otherwise, insert a temporary mismatch breakpoint so that + * we can single-step over the watchpoint trigger. */ - if (is_default_overflow_handler(wp)) - enable_single_step(wp, instruction_pointer(regs)); + if (!uses_default_overflow_handler(wp)) + continue; +step: + enable_single_step(wp, instruction_pointer(regs)); + } -unlock: - rcu_read_unlock(); + if (min_dist > 0 && min_dist != -1) { + /* No exact match found. */ + wp = slots[closest_match]; + info = counter_arch_bp(wp); + info->trigger = addr; + pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); + perf_bp_event(wp, regs); + if (uses_default_overflow_handler(wp)) + enable_single_step(wp, instruction_pointer(regs)); } + + rcu_read_unlock(); } static void watchpoint_single_step_handler(unsigned long pc) @@ -822,7 +883,7 @@ info->trigger = addr; pr_debug("breakpoint fired: address = 0x%x\n", addr); perf_bp_event(bp, regs); - if (!bp->overflow_handler) + if (uses_default_overflow_handler(bp)) enable_single_step(bp, addr); goto unlock; } --- linux-oracle-5.4.0.orig/arch/arm/kernel/hyp-stub.S +++ linux-oracle-5.4.0/arch/arm/kernel/hyp-stub.S @@ -146,10 +146,9 @@ #if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER) @ make CNTP_* and CNTPCT accessible from PL1 mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 - lsr r7, #16 - and r7, #0xf - cmp r7, #1 - bne 1f + ubfx r7, r7, #16, #4 + teq r7, #0 + beq 1f mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL orr r7, r7, #3 @ PL1PCEN | PL1PCTEN mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL --- linux-oracle-5.4.0.orig/arch/arm/kernel/insn.c +++ linux-oracle-5.4.0/arch/arm/kernel/insn.c @@ -3,8 +3,9 @@ #include #include -static unsigned long -__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link) +static unsigned long __arm_gen_branch_thumb2(unsigned long pc, + unsigned long addr, bool link, + bool warn) { unsigned long s, j1, j2, i1, i2, imm10, imm11; unsigned long first, second; @@ -12,7 +13,7 @@ offset = (long)addr - (long)(pc + 4); if (offset < -16777216 || offset > 16777214) { - WARN_ON_ONCE(1); + WARN_ON_ONCE(warn); return 0; } @@ -33,8 +34,8 @@ return __opcode_thumb32_compose(first, second); } -static unsigned long -__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link) +static unsigned long __arm_gen_branch_arm(unsigned long pc, unsigned long addr, + bool link, bool warn) { unsigned long opcode = 0xea000000; long offset; @@ -44,7 +45,7 @@ offset = (long)addr - (long)(pc + 8); if (unlikely(offset < -33554432 || offset > 33554428)) { - WARN_ON_ONCE(1); + WARN_ON_ONCE(warn); return 0; } @@ -54,10 +55,10 @@ } unsigned long -__arm_gen_branch(unsigned long pc, unsigned long addr, bool link) +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn) { if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) - return __arm_gen_branch_thumb2(pc, addr, link); + return __arm_gen_branch_thumb2(pc, addr, link, warn); else - return __arm_gen_branch_arm(pc, addr, link); + return __arm_gen_branch_arm(pc, addr, link, warn); } --- linux-oracle-5.4.0.orig/arch/arm/kernel/iwmmxt.S +++ linux-oracle-5.4.0/arch/arm/kernel/iwmmxt.S @@ -16,6 +16,7 @@ #include #include #include +#include "iwmmxt.h" #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) #define PJ4(code...) code @@ -113,33 +114,33 @@ concan_dump: - wstrw wCSSF, [r1, #MMX_WCSSF] - wstrw wCASF, [r1, #MMX_WCASF] - wstrw wCGR0, [r1, #MMX_WCGR0] - wstrw wCGR1, [r1, #MMX_WCGR1] - wstrw wCGR2, [r1, #MMX_WCGR2] - wstrw wCGR3, [r1, #MMX_WCGR3] + wstrw wCSSF, r1, MMX_WCSSF + wstrw wCASF, r1, MMX_WCASF + wstrw wCGR0, r1, MMX_WCGR0 + wstrw wCGR1, r1, MMX_WCGR1 + wstrw wCGR2, r1, MMX_WCGR2 + wstrw wCGR3, r1, MMX_WCGR3 1: @ MUP? wRn tst r2, #0x2 beq 2f - wstrd wR0, [r1, #MMX_WR0] - wstrd wR1, [r1, #MMX_WR1] - wstrd wR2, [r1, #MMX_WR2] - wstrd wR3, [r1, #MMX_WR3] - wstrd wR4, [r1, #MMX_WR4] - wstrd wR5, [r1, #MMX_WR5] - wstrd wR6, [r1, #MMX_WR6] - wstrd wR7, [r1, #MMX_WR7] - wstrd wR8, [r1, #MMX_WR8] - wstrd wR9, [r1, #MMX_WR9] - wstrd wR10, [r1, #MMX_WR10] - wstrd wR11, [r1, #MMX_WR11] - wstrd wR12, [r1, #MMX_WR12] - wstrd wR13, [r1, #MMX_WR13] - wstrd wR14, [r1, #MMX_WR14] - wstrd wR15, [r1, #MMX_WR15] + wstrd wR0, r1, MMX_WR0 + wstrd wR1, r1, MMX_WR1 + wstrd wR2, r1, MMX_WR2 + wstrd wR3, r1, MMX_WR3 + wstrd wR4, r1, MMX_WR4 + wstrd wR5, r1, MMX_WR5 + wstrd wR6, r1, MMX_WR6 + wstrd wR7, r1, MMX_WR7 + wstrd wR8, r1, MMX_WR8 + wstrd wR9, r1, MMX_WR9 + wstrd wR10, r1, MMX_WR10 + wstrd wR11, r1, MMX_WR11 + wstrd wR12, r1, MMX_WR12 + wstrd wR13, r1, MMX_WR13 + wstrd wR14, r1, MMX_WR14 + wstrd wR15, r1, MMX_WR15 2: teq r0, #0 @ anything to load? reteq lr @ if not, return @@ -147,30 +148,30 @@ concan_load: @ Load wRn - wldrd wR0, [r0, #MMX_WR0] - wldrd wR1, [r0, #MMX_WR1] - wldrd wR2, [r0, #MMX_WR2] - wldrd wR3, [r0, #MMX_WR3] - wldrd wR4, [r0, #MMX_WR4] - wldrd wR5, [r0, #MMX_WR5] - wldrd wR6, [r0, #MMX_WR6] - wldrd wR7, [r0, #MMX_WR7] - wldrd wR8, [r0, #MMX_WR8] - wldrd wR9, [r0, #MMX_WR9] - wldrd wR10, [r0, #MMX_WR10] - wldrd wR11, [r0, #MMX_WR11] - wldrd wR12, [r0, #MMX_WR12] - wldrd wR13, [r0, #MMX_WR13] - wldrd wR14, [r0, #MMX_WR14] - wldrd wR15, [r0, #MMX_WR15] + wldrd wR0, r0, MMX_WR0 + wldrd wR1, r0, MMX_WR1 + wldrd wR2, r0, MMX_WR2 + wldrd wR3, r0, MMX_WR3 + wldrd wR4, r0, MMX_WR4 + wldrd wR5, r0, MMX_WR5 + wldrd wR6, r0, MMX_WR6 + wldrd wR7, r0, MMX_WR7 + wldrd wR8, r0, MMX_WR8 + wldrd wR9, r0, MMX_WR9 + wldrd wR10, r0, MMX_WR10 + wldrd wR11, r0, MMX_WR11 + wldrd wR12, r0, MMX_WR12 + wldrd wR13, r0, MMX_WR13 + wldrd wR14, r0, MMX_WR14 + wldrd wR15, r0, MMX_WR15 @ Load wCx - wldrw wCSSF, [r0, #MMX_WCSSF] - wldrw wCASF, [r0, #MMX_WCASF] - wldrw wCGR0, [r0, #MMX_WCGR0] - wldrw wCGR1, [r0, #MMX_WCGR1] - wldrw wCGR2, [r0, #MMX_WCGR2] - wldrw wCGR3, [r0, #MMX_WCGR3] + wldrw wCSSF, r0, MMX_WCSSF + wldrw wCASF, r0, MMX_WCASF + wldrw wCGR0, r0, MMX_WCGR0 + wldrw wCGR1, r0, MMX_WCGR1 + wldrw wCGR2, r0, MMX_WCGR2 + wldrw wCGR3, r0, MMX_WCGR3 @ clear CUP/MUP (only if r1 != 0) teq r1, #0 --- linux-oracle-5.4.0.orig/arch/arm/kernel/iwmmxt.h +++ linux-oracle-5.4.0/arch/arm/kernel/iwmmxt.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __IWMMXT_H__ +#define __IWMMXT_H__ + +.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +.set .LwR\b, \b +.set .Lr\b, \b +.endr + +.set .LwCSSF, 0x2 +.set .LwCASF, 0x3 +.set .LwCGR0, 0x8 +.set .LwCGR1, 0x9 +.set .LwCGR2, 0xa +.set .LwCGR3, 0xb + +.macro wldrd, reg:req, base:req, offset:req +.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wldrw, reg:req, base:req, offset:req +.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrd, reg:req, base:req, offset:req +.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrw, reg:req, base:req, offset:req +.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +#ifdef __clang__ + +#define wCon c1 + +.macro tmrc, dest:req, control:req +mrc p1, 0, \dest, \control, c0, 0 +.endm + +.macro tmcr, control:req, src:req +mcr p1, 0, \src, \control, c0, 0 +.endm +#endif + +#endif --- linux-oracle-5.4.0.orig/arch/arm/kernel/kgdb.c +++ linux-oracle-5.4.0/arch/arm/kernel/kgdb.c @@ -154,22 +154,38 @@ return 0; } -static struct undef_hook kgdb_brkpt_hook = { +static struct undef_hook kgdb_brkpt_arm_hook = { .instr_mask = 0xffffffff, .instr_val = KGDB_BREAKINST, - .cpsr_mask = MODE_MASK, + .cpsr_mask = PSR_T_BIT | MODE_MASK, .cpsr_val = SVC_MODE, .fn = kgdb_brk_fn }; -static struct undef_hook kgdb_compiled_brkpt_hook = { +static struct undef_hook kgdb_brkpt_thumb_hook = { + .instr_mask = 0xffff, + .instr_val = KGDB_BREAKINST & 0xffff, + .cpsr_mask = PSR_T_BIT | MODE_MASK, + .cpsr_val = PSR_T_BIT | SVC_MODE, + .fn = kgdb_brk_fn +}; + +static struct undef_hook kgdb_compiled_brkpt_arm_hook = { .instr_mask = 0xffffffff, .instr_val = KGDB_COMPILED_BREAK, - .cpsr_mask = MODE_MASK, + .cpsr_mask = PSR_T_BIT | MODE_MASK, .cpsr_val = SVC_MODE, .fn = kgdb_compiled_brk_fn }; +static struct undef_hook kgdb_compiled_brkpt_thumb_hook = { + .instr_mask = 0xffff, + .instr_val = KGDB_COMPILED_BREAK & 0xffff, + .cpsr_mask = PSR_T_BIT | MODE_MASK, + .cpsr_val = PSR_T_BIT | SVC_MODE, + .fn = kgdb_compiled_brk_fn +}; + static int __kgdb_notify(struct die_args *args, unsigned long cmd) { struct pt_regs *regs = args->regs; @@ -210,8 +226,10 @@ if (ret != 0) return ret; - register_undef_hook(&kgdb_brkpt_hook); - register_undef_hook(&kgdb_compiled_brkpt_hook); + register_undef_hook(&kgdb_brkpt_arm_hook); + register_undef_hook(&kgdb_brkpt_thumb_hook); + register_undef_hook(&kgdb_compiled_brkpt_arm_hook); + register_undef_hook(&kgdb_compiled_brkpt_thumb_hook); return 0; } @@ -224,8 +242,10 @@ */ void kgdb_arch_exit(void) { - unregister_undef_hook(&kgdb_brkpt_hook); - unregister_undef_hook(&kgdb_compiled_brkpt_hook); + unregister_undef_hook(&kgdb_brkpt_arm_hook); + unregister_undef_hook(&kgdb_brkpt_thumb_hook); + unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook); + unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook); unregister_die_notifier(&kgdb_notifier); } --- linux-oracle-5.4.0.orig/arch/arm/kernel/machine_kexec.c +++ linux-oracle-5.4.0/arch/arm/kernel/machine_kexec.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,11 +25,6 @@ extern void relocate_new_kernel(void); extern const unsigned int relocate_new_kernel_size; -extern unsigned long kexec_start_address; -extern unsigned long kexec_indirection_page; -extern unsigned long kexec_mach_type; -extern unsigned long kexec_boot_atags; - static atomic_t waiting_for_crash_ipi; /* @@ -161,6 +157,7 @@ void machine_kexec(struct kimage *image) { unsigned long page_list, reboot_entry_phys; + struct kexec_relocate_data *data; void (*reboot_entry)(void); void *reboot_code_buffer; @@ -176,18 +173,17 @@ reboot_code_buffer = page_address(image->control_code_page); - /* Prepare parameters for reboot_code_buffer*/ - set_kernel_text_rw(); - kexec_start_address = image->start; - kexec_indirection_page = page_list; - kexec_mach_type = machine_arch_type; - kexec_boot_atags = image->arch.kernel_r2; - /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, &relocate_new_kernel, relocate_new_kernel_size); + data = reboot_code_buffer + relocate_new_kernel_size; + data->kexec_start_address = image->start; + data->kexec_indirection_page = page_list; + data->kexec_mach_type = machine_arch_type; + data->kexec_r2 = image->arch.kernel_r2; + /* get the identity mapping physical address for the reboot code */ reboot_entry_phys = virt_to_idmap(reboot_entry); --- linux-oracle-5.4.0.orig/arch/arm/kernel/module-plts.c +++ linux-oracle-5.4.0/arch/arm/kernel/module-plts.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -11,10 +12,6 @@ #include #include -#define PLT_ENT_STRIDE L1_CACHE_BYTES -#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32)) -#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT) - #ifdef CONFIG_THUMB2_KERNEL #define PLT_ENT_LDR __opcode_to_mem_thumb32(0xf8dff000 | \ (PLT_ENT_STRIDE - 4)) @@ -23,9 +20,11 @@ (PLT_ENT_STRIDE - 8)) #endif -struct plt_entries { - u32 ldr[PLT_ENT_COUNT]; - u32 lit[PLT_ENT_COUNT]; +static const u32 fixed_plts[] = { +#ifdef CONFIG_DYNAMIC_FTRACE + FTRACE_ADDR, + MCOUNT_ADDR, +#endif }; static bool in_init(const struct module *mod, unsigned long loc) @@ -33,14 +32,40 @@ return loc - (u32)mod->init_layout.base < mod->init_layout.size; } +static void prealloc_fixed(struct mod_plt_sec *pltsec, struct plt_entries *plt) +{ + int i; + + if (!ARRAY_SIZE(fixed_plts) || pltsec->plt_count) + return; + pltsec->plt_count = ARRAY_SIZE(fixed_plts); + + for (i = 0; i < ARRAY_SIZE(plt->ldr); ++i) + plt->ldr[i] = PLT_ENT_LDR; + + BUILD_BUG_ON(sizeof(fixed_plts) > sizeof(plt->lit)); + memcpy(plt->lit, fixed_plts, sizeof(fixed_plts)); +} + u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val) { struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core : &mod->arch.init; + struct plt_entries *plt; + int idx; + + /* cache the address, ELF header is available only during module load */ + if (!pltsec->plt_ent) + pltsec->plt_ent = (struct plt_entries *)pltsec->plt->sh_addr; + plt = pltsec->plt_ent; - struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr; - int idx = 0; + prealloc_fixed(pltsec, plt); + + for (idx = 0; idx < ARRAY_SIZE(fixed_plts); ++idx) + if (plt->lit[idx] == val) + return (u32)&plt->ldr[idx]; + idx = 0; /* * Look for an existing entry pointing to 'val'. Given that the * relocations are sorted, this will be the last entry we allocated. @@ -188,8 +213,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod) { - unsigned long core_plts = 0; - unsigned long init_plts = 0; + unsigned long core_plts = ARRAY_SIZE(fixed_plts); + unsigned long init_plts = ARRAY_SIZE(fixed_plts); Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum; Elf32_Sym *syms = NULL; @@ -244,6 +269,7 @@ mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE, sizeof(struct plt_entries)); mod->arch.core.plt_count = 0; + mod->arch.core.plt_ent = NULL; mod->arch.init.plt->sh_type = SHT_NOBITS; mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC; @@ -251,6 +277,7 @@ mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE, sizeof(struct plt_entries)); mod->arch.init.plt_count = 0; + mod->arch.init.plt_ent = NULL; pr_debug("%s: plt=%x, init.plt=%x\n", __func__, mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size); --- linux-oracle-5.4.0.orig/arch/arm/kernel/perf_callchain.c +++ linux-oracle-5.4.0/arch/arm/kernel/perf_callchain.c @@ -62,9 +62,10 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct frame_tail __user *tail; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -98,9 +99,10 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct stackframe fr; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -111,18 +113,21 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs) { - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) - return perf_guest_cbs->get_guest_ip(); + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + + if (guest_cbs && guest_cbs->is_in_guest()) + return guest_cbs->get_guest_ip(); return instruction_pointer(regs); } unsigned long perf_misc_flags(struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); int misc = 0; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { - if (perf_guest_cbs->is_user_mode()) + if (guest_cbs && guest_cbs->is_in_guest()) { + if (guest_cbs->is_user_mode()) misc |= PERF_RECORD_MISC_GUEST_USER; else misc |= PERF_RECORD_MISC_GUEST_KERNEL; --- linux-oracle-5.4.0.orig/arch/arm/kernel/perf_event_v7.c +++ linux-oracle-5.4.0/arch/arm/kernel/perf_event_v7.c @@ -773,10 +773,10 @@ pr_err("CPU%u writing wrong counter %d\n", smp_processor_id(), idx); } else if (idx == ARMV7_IDX_CYCLE_COUNTER) { - asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" ((u32)value)); } else { armv7_pmnc_select_counter(idx); - asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value)); + asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" ((u32)value)); } } --- linux-oracle-5.4.0.orig/arch/arm/kernel/process.c +++ linux-oracle-5.4.0/arch/arm/kernel/process.c @@ -224,8 +224,8 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); int -copy_thread(unsigned long clone_flags, unsigned long stack_start, - unsigned long stk_sz, struct task_struct *p) +copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, + unsigned long stk_sz, struct task_struct *p, unsigned long tls) { struct thread_info *thread = task_thread_info(p); struct pt_regs *childregs = task_pt_regs(p); @@ -259,7 +259,7 @@ clear_ptrace_hw_breakpoint(p); if (clone_flags & CLONE_SETTLS) - thread->tp_value[0] = childregs->ARM_r3; + thread->tp_value[0] = tls; thread->tp_value[1] = get_tpuser(); thread_notify(THREAD_NOTIFY_COPY, thread); --- linux-oracle-5.4.0.orig/arch/arm/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/arm/kernel/ptrace.c @@ -219,8 +219,8 @@ }; static struct undef_hook thumb_break_hook = { - .instr_mask = 0xffff, - .instr_val = 0xde01, + .instr_mask = 0xffffffff, + .instr_val = 0x0000de01, .cpsr_mask = PSR_T_BIT, .cpsr_val = PSR_T_BIT, .fn = break_trap, --- linux-oracle-5.4.0.orig/arch/arm/kernel/relocate_kernel.S +++ linux-oracle-5.4.0/arch/arm/kernel/relocate_kernel.S @@ -5,14 +5,16 @@ #include #include +#include #include .align 3 /* not needed for this code, but keeps fncpy() happy */ ENTRY(relocate_new_kernel) - ldr r0,kexec_indirection_page - ldr r1,kexec_start_address + adr r7, relocate_new_kernel_end + ldr r0, [r7, #KEXEC_INDIR_PAGE] + ldr r1, [r7, #KEXEC_START_ADDR] /* * If there is no indirection page (we are doing crashdumps) @@ -57,34 +59,16 @@ 2: /* Jump to relocated kernel */ - mov lr,r1 - mov r0,#0 - ldr r1,kexec_mach_type - ldr r2,kexec_boot_atags - ARM( ret lr ) - THUMB( bx lr ) - - .align - - .globl kexec_start_address -kexec_start_address: - .long 0x0 - - .globl kexec_indirection_page -kexec_indirection_page: - .long 0x0 - - .globl kexec_mach_type -kexec_mach_type: - .long 0x0 - - /* phy addr of the atags for the new kernel */ - .globl kexec_boot_atags -kexec_boot_atags: - .long 0x0 + mov lr, r1 + mov r0, #0 + ldr r1, [r7, #KEXEC_MACH_TYPE] + ldr r2, [r7, #KEXEC_R2] + ARM( ret lr ) + THUMB( bx lr ) ENDPROC(relocate_new_kernel) + .align 3 relocate_new_kernel_end: .globl relocate_new_kernel_size --- linux-oracle-5.4.0.orig/arch/arm/kernel/return_address.c +++ linux-oracle-5.4.0/arch/arm/kernel/return_address.c @@ -7,8 +7,6 @@ */ #include #include - -#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) #include #include @@ -53,6 +51,4 @@ return NULL; } -#endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */ - EXPORT_SYMBOL_GPL(return_address); --- linux-oracle-5.4.0.orig/arch/arm/kernel/setup.c +++ linux-oracle-5.4.0/arch/arm/kernel/setup.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -543,9 +544,11 @@ * In Thumb-2, msr with an immediate value is not allowed. */ #ifdef CONFIG_THUMB2_KERNEL -#define PLC "r" +#define PLC_l "l" +#define PLC_r "r" #else -#define PLC "I" +#define PLC_l "I" +#define PLC_r "I" #endif /* @@ -567,15 +570,15 @@ "msr cpsr_c, %9" : : "r" (stk), - PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), "I" (offsetof(struct stack, irq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | ABT_MODE), "I" (offsetof(struct stack, abt[0])), - PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - PLC (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), "I" (offsetof(struct stack, fiq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + PLC_l (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); #endif } @@ -1075,19 +1078,27 @@ void __init setup_arch(char **cmdline_p) { - const struct machine_desc *mdesc; + const struct machine_desc *mdesc = NULL; + void *atags_vaddr = NULL; + + if (__atags_pointer) + atags_vaddr = FDT_VIRT_BASE(__atags_pointer); setup_processor(); - mdesc = setup_machine_fdt(__atags_pointer); + if (atags_vaddr) { + mdesc = setup_machine_fdt(atags_vaddr); + if (mdesc) + memblock_reserve(__atags_pointer, + fdt_totalsize(atags_vaddr)); + } if (!mdesc) - mdesc = setup_machine_tags(__atags_pointer, __machine_arch_type); + mdesc = setup_machine_tags(atags_vaddr, __machine_arch_type); if (!mdesc) { early_print("\nError: invalid dtb and unrecognized/unsupported machine ID\n"); early_print(" r1=0x%08x, r2=0x%08x\n", __machine_arch_type, __atags_pointer); if (__atags_pointer) - early_print(" r2[]=%*ph\n", 16, - phys_to_virt(__atags_pointer)); + early_print(" r2[]=%*ph\n", 16, atags_vaddr); dump_machine_table(); } --- linux-oracle-5.4.0.orig/arch/arm/kernel/signal.c +++ linux-oracle-5.4.0/arch/arm/kernel/signal.c @@ -694,18 +694,20 @@ addr = page_address(page); + /* Poison the entire page */ + memset32(addr, __opcode_to_mem_arm(0xe7fddef1), + PAGE_SIZE / sizeof(u32)); + /* Give the signal return code some randomness */ offset = 0x200 + (get_random_int() & 0x7fc); signal_return_offset = offset; - /* - * Copy signal return handlers into the vector page, and - * set sigreturn to be a pointer to these. - */ + /* Copy signal return handlers into the page */ memcpy(addr + offset, sigreturn_codes, sizeof(sigreturn_codes)); - ptr = (unsigned long)addr + offset; - flush_icache_range(ptr, ptr + sizeof(sigreturn_codes)); + /* Flush out all instructions in this page */ + ptr = (unsigned long)addr; + flush_icache_range(ptr, ptr + PAGE_SIZE); return page; } --- linux-oracle-5.4.0.orig/arch/arm/kernel/smccc-call.S +++ linux-oracle-5.4.0/arch/arm/kernel/smccc-call.S @@ -3,7 +3,9 @@ * Copyright (c) 2015, Linaro Limited */ #include +#include +#include #include #include #include @@ -27,7 +29,14 @@ UNWIND( .save {r4-r7}) ldm r12, {r4-r7} \instr - pop {r4-r7} + ldr r4, [sp, #36] + cmp r4, #0 + beq 1f // No quirk structure + ldr r5, [r4, #ARM_SMCCC_QUIRK_ID_OFFS] + cmp r5, #ARM_SMCCC_QUIRK_QCOM_A6 + bne 1f // No quirk present + str r6, [r4, #ARM_SMCCC_QUIRK_STATE_OFFS] +1: pop {r4-r7} ldr r12, [sp, #(4 * 4)] stm r12, {r0-r3} bx lr --- linux-oracle-5.4.0.orig/arch/arm/kernel/smp.c +++ linux-oracle-5.4.0/arch/arm/kernel/smp.c @@ -240,6 +240,10 @@ if (ret) return ret; +#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY + remove_cpu_topology(cpu); +#endif + /* * Take this CPU offline. Once we clear this, we can't return, * and we must not schedule until we're ready to give up the cpu. --- linux-oracle-5.4.0.orig/arch/arm/kernel/spectre.c +++ linux-oracle-5.4.0/arch/arm/kernel/spectre.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include + +#include + +static bool _unprivileged_ebpf_enabled(void) +{ +#ifdef CONFIG_BPF_SYSCALL + return !sysctl_unprivileged_bpf_disabled; +#else + return false; +#endif +} + +ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "Mitigation: __user pointer sanitization\n"); +} + +static unsigned int spectre_v2_state; +static unsigned int spectre_v2_methods; + +void spectre_v2_update_state(unsigned int state, unsigned int method) +{ + if (state > spectre_v2_state) + spectre_v2_state = state; + spectre_v2_methods |= method; +} + +ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, + char *buf) +{ + const char *method; + + if (spectre_v2_state == SPECTRE_UNAFFECTED) + return sprintf(buf, "%s\n", "Not affected"); + + if (spectre_v2_state != SPECTRE_MITIGATED) + return sprintf(buf, "%s\n", "Vulnerable"); + + if (_unprivileged_ebpf_enabled()) + return sprintf(buf, "Vulnerable: Unprivileged eBPF enabled\n"); + + switch (spectre_v2_methods) { + case SPECTRE_V2_METHOD_BPIALL: + method = "Branch predictor hardening"; + break; + + case SPECTRE_V2_METHOD_ICIALLU: + method = "I-cache invalidation"; + break; + + case SPECTRE_V2_METHOD_SMC: + case SPECTRE_V2_METHOD_HVC: + method = "Firmware call"; + break; + + case SPECTRE_V2_METHOD_LOOP8: + method = "History overwrite"; + break; + + default: + method = "Multiple mitigations"; + break; + } + + return sprintf(buf, "Mitigation: %s\n", method); +} --- linux-oracle-5.4.0.orig/arch/arm/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/arm/kernel/stacktrace.c @@ -22,6 +22,19 @@ * A simple function epilogue looks like this: * ldm sp, {fp, sp, pc} * + * When compiled with clang, pc and sp are not pushed. A simple function + * prologue looks like this when built with clang: + * + * stmdb {..., fp, lr} + * add fp, sp, #x + * sub sp, sp, #y + * + * A simple function epilogue looks like this when built with clang: + * + * sub sp, fp, #x + * ldm {..., fp, pc} + * + * * Note that with framepointer enabled, even the leaf functions have the same * prologue and epilogue, therefore we can ignore the LR value in this case. */ @@ -34,14 +47,24 @@ low = frame->sp; high = ALIGN(low, THREAD_SIZE); +#ifdef CONFIG_CC_IS_CLANG + /* check current frame pointer is within bounds */ + if (fp < low + 4 || fp > high - 4) + return -EINVAL; + + frame->sp = frame->fp; + frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp)); + frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 4)); +#else /* check current frame pointer is within bounds */ if (fp < low + 12 || fp > high - 4) return -EINVAL; /* restore the registers from the stack frame */ - frame->fp = *(unsigned long *)(fp - 12); - frame->sp = *(unsigned long *)(fp - 8); - frame->pc = *(unsigned long *)(fp - 4); + frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 12)); + frame->sp = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 8)); + frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp - 4)); +#endif return 0; } @@ -92,6 +115,8 @@ return 0; regs = (struct pt_regs *)frame->sp; + if ((unsigned long)®s[1] > ALIGN(frame->sp, THREAD_SIZE)) + return 0; trace->entries[trace->nr_entries++] = regs->ARM_pc; --- linux-oracle-5.4.0.orig/arch/arm/kernel/suspend.c +++ linux-oracle-5.4.0/arch/arm/kernel/suspend.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include @@ -27,12 +28,22 @@ return -EINVAL; /* + * Function graph tracer state gets incosistent when the kernel + * calls functions that never return (aka suspend finishers) hence + * disable graph tracing during their execution. + */ + pause_graph_tracing(); + + /* * Provide a temporary page table with an identity mapping for * the MMU-enable code, required for resuming. On successful * resume (indicated by a zero return code), we need to switch * back to the correct page tables. */ ret = __cpu_suspend(arg, fn, __mpidr); + + unpause_graph_tracing(); + if (ret == 0) { cpu_switch_mm(mm->pgd, mm); local_flush_bp_all(); @@ -46,7 +57,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) { u32 __mpidr = cpu_logical_map(smp_processor_id()); - return __cpu_suspend(arg, fn, __mpidr); + int ret; + + pause_graph_tracing(); + ret = __cpu_suspend(arg, fn, __mpidr); + unpause_graph_tracing(); + + return ret; } #define idmap_pgd NULL #endif --- linux-oracle-5.4.0.orig/arch/arm/kernel/topology.c +++ linux-oracle-5.4.0/arch/arm/kernel/topology.c @@ -196,9 +196,8 @@ struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; unsigned int mpidr; - /* If the cpu topology has been already set, just return */ - if (cpuid_topo->core_id != -1) - return; + if (cpuid_topo->package_id != -1) + goto topology_populated; mpidr = read_cpuid_mpidr(); @@ -231,14 +230,15 @@ cpuid_topo->package_id = -1; } - update_siblings_masks(cpuid); - update_cpu_capacity(cpuid); pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", cpuid, cpu_topology[cpuid].thread_id, cpu_topology[cpuid].core_id, cpu_topology[cpuid].package_id, mpidr); + +topology_populated: + update_siblings_masks(cpuid); } static inline int cpu_corepower_flags(void) --- linux-oracle-5.4.0.orig/arch/arm/kernel/traps.c +++ linux-oracle-5.4.0/arch/arm/kernel/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -64,14 +65,16 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) { + unsigned long end = frame + 4 + sizeof(struct pt_regs); + #ifdef CONFIG_KALLSYMS printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif - if (in_entry_text(from)) - dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); + if (in_entry_text(from) && end <= ALIGN(frame, THREAD_SIZE)) + dump_mem("", "Exception stack", frame + 4, end); } void dump_backtrace_stm(u32 *stack, u32 instruction) @@ -338,7 +341,7 @@ if (panic_on_oops) panic("Fatal exception"); if (signr) - do_exit(signr); + make_task_dead(signr); } /* @@ -797,10 +800,59 @@ } #endif +#ifndef CONFIG_CPU_V7M +static void copy_from_lma(void *vma, void *lma_start, void *lma_end) +{ + memcpy(vma, lma_start, lma_end - lma_start); +} + +static void flush_vectors(void *vma, size_t offset, size_t size) +{ + unsigned long start = (unsigned long)vma + offset; + unsigned long end = start + size; + + flush_icache_range(start, end); +} + +#ifdef CONFIG_HARDEN_BRANCH_HISTORY +int spectre_bhb_update_vectors(unsigned int method) +{ + extern char __vectors_bhb_bpiall_start[], __vectors_bhb_bpiall_end[]; + extern char __vectors_bhb_loop8_start[], __vectors_bhb_loop8_end[]; + void *vec_start, *vec_end; + + if (system_state > SYSTEM_SCHEDULING) { + pr_err("CPU%u: Spectre BHB workaround too late - system vulnerable\n", + smp_processor_id()); + return SPECTRE_VULNERABLE; + } + + switch (method) { + case SPECTRE_V2_METHOD_LOOP8: + vec_start = __vectors_bhb_loop8_start; + vec_end = __vectors_bhb_loop8_end; + break; + + case SPECTRE_V2_METHOD_BPIALL: + vec_start = __vectors_bhb_bpiall_start; + vec_end = __vectors_bhb_bpiall_end; + break; + + default: + pr_err("CPU%u: unknown Spectre BHB state %d\n", + smp_processor_id(), method); + return SPECTRE_VULNERABLE; + } + + copy_from_lma(vectors_page, vec_start, vec_end); + flush_vectors(vectors_page, 0, vec_end - vec_start); + + return SPECTRE_MITIGATED; +} +#endif + void __init early_trap_init(void *vectors_base) { -#ifndef CONFIG_CPU_V7M - unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; unsigned i; @@ -821,17 +873,20 @@ * into the vector page, mapped at 0xffff0000, and ensure these * are visible to the instruction stream. */ - memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); - memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); + copy_from_lma(vectors_base, __vectors_start, __vectors_end); + copy_from_lma(vectors_base + 0x1000, __stubs_start, __stubs_end); kuser_init(vectors_base); - flush_icache_range(vectors, vectors + PAGE_SIZE * 2); + flush_vectors(vectors_base, 0, PAGE_SIZE * 2); +} #else /* ifndef CONFIG_CPU_V7M */ +void __init early_trap_init(void *vectors_base) +{ /* * on V7-M there is no need to copy the vector table to a dedicated * memory area. The address is configurable and so a table in the kernel * image can be used. */ -#endif } +#endif --- linux-oracle-5.4.0.orig/arch/arm/kernel/unwind.c +++ linux-oracle-5.4.0/arch/arm/kernel/unwind.c @@ -300,6 +300,29 @@ return URC_OK; } +static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl) +{ + unsigned long bytes = 0; + unsigned long insn; + unsigned long result = 0; + + /* + * unwind_get_byte() will advance `ctrl` one instruction at a time, so + * loop until we get an instruction byte where bit 7 is not set. + * + * Note: This decodes a maximum of 4 bytes to output 28 bits data where + * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence + * it is sufficient for unwinding the stack. + */ + do { + insn = unwind_get_byte(ctrl); + result |= (insn & 0x7f) << (bytes * 7); + bytes++; + } while (!!(insn & 0x80) && (bytes != sizeof(result))); + + return result; +} + /* * Execute the current unwind instruction. */ @@ -353,7 +376,7 @@ if (ret) goto error; } else if (insn == 0xb2) { - unsigned long uleb128 = unwind_get_byte(ctrl); + unsigned long uleb128 = unwind_decode_uleb128(ctrl); ctrl->vrs[SP] += 0x204 + (uleb128 << 2); } else { --- linux-oracle-5.4.0.orig/arch/arm/kernel/vdso.c +++ linux-oracle-5.4.0/arch/arm/kernel/vdso.c @@ -93,6 +93,8 @@ */ np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); if (!np) + np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); + if (!np) goto out_put; if (of_property_read_bool(np, "arm,cpu-registers-not-fw-configured")) @@ -279,7 +281,7 @@ if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) return false; - if (!tk->tkr_mono.clock->archdata.vdso_direct) + if (tk->tkr_mono.clock->archdata.clock_mode != VDSO_CLOCKMODE_ARCHTIMER) return false; return true; --- linux-oracle-5.4.0.orig/arch/arm/kernel/vmlinux-xip.lds.S +++ linux-oracle-5.4.0/arch/arm/kernel/vmlinux-xip.lds.S @@ -180,7 +180,7 @@ ASSERT((_end - __bss_start) >= 12288, ".bss too small for CONFIG_XIP_DEFLATED_DATA") #endif -#ifdef CONFIG_ARM_MPU +#if defined(CONFIG_ARM_MPU) && !defined(CONFIG_COMPILE_TEST) /* * Due to PMSAv7 restriction on base address and size we have to * enforce minimal alignment restrictions. It was seen that weaker --- linux-oracle-5.4.0.orig/arch/arm/kernel/vmlinux.lds.h +++ linux-oracle-5.4.0/arch/arm/kernel/vmlinux.lds.h @@ -25,6 +25,19 @@ #define ARM_MMU_DISCARD(x) x #endif +/* + * ld.lld does not support NOCROSSREFS: + * https://github.com/ClangBuiltLinux/linux/issues/1609 + */ +#ifdef CONFIG_LD_IS_LLD +#define NOCROSSREFS +#endif + +/* Set start/end symbol names to the LMA for the section */ +#define ARM_LMA(sym, section) \ + sym##_start = LOADADDR(section); \ + sym##_end = LOADADDR(section) + SIZEOF(section) + #define PROC_INFO \ . = ALIGN(4); \ __proc_info_begin = .; \ @@ -100,19 +113,31 @@ * only thing that matters is their relative offsets */ #define ARM_VECTORS \ - __vectors_start = .; \ - .vectors 0xffff0000 : AT(__vectors_start) { \ - *(.vectors) \ + __vectors_lma = .; \ + OVERLAY 0xffff0000 : NOCROSSREFS AT(__vectors_lma) { \ + .vectors { \ + *(.vectors) \ + } \ + .vectors.bhb.loop8 { \ + *(.vectors.bhb.loop8) \ + } \ + .vectors.bhb.bpiall { \ + *(.vectors.bhb.bpiall) \ + } \ } \ - . = __vectors_start + SIZEOF(.vectors); \ - __vectors_end = .; \ + ARM_LMA(__vectors, .vectors); \ + ARM_LMA(__vectors_bhb_loop8, .vectors.bhb.loop8); \ + ARM_LMA(__vectors_bhb_bpiall, .vectors.bhb.bpiall); \ + . = __vectors_lma + SIZEOF(.vectors) + \ + SIZEOF(.vectors.bhb.loop8) + \ + SIZEOF(.vectors.bhb.bpiall); \ \ - __stubs_start = .; \ - .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \ + __stubs_lma = .; \ + .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_lma) { \ *(.stubs) \ } \ - . = __stubs_start + SIZEOF(.stubs); \ - __stubs_end = .; \ + ARM_LMA(__stubs, .stubs); \ + . = __stubs_lma + SIZEOF(.stubs); \ \ PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); --- linux-oracle-5.4.0.orig/arch/arm/kvm/hyp/tlb.c +++ linux-oracle-5.4.0/arch/arm/kvm/hyp/tlb.c @@ -45,7 +45,7 @@ __kvm_tlb_flush_vmid(kvm); } -void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) +void __hyp_text __kvm_flush_cpu_context(struct kvm_vcpu *vcpu) { struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); @@ -54,6 +54,7 @@ isb(); write_sysreg(0, TLBIALL); + write_sysreg(0, ICIALLU); dsb(nsh); isb(); --- linux-oracle-5.4.0.orig/arch/arm/lib/copy_from_user.S +++ linux-oracle-5.4.0/arch/arm/lib/copy_from_user.S @@ -118,7 +118,7 @@ ENDPROC(arm_copy_from_user) - .pushsection .fixup,"ax" + .pushsection .text.fixup,"ax" .align 0 copy_abort_preamble ldmfd sp!, {r1, r2, r3} --- linux-oracle-5.4.0.orig/arch/arm/lib/findbit.S +++ linux-oracle-5.4.0/arch/arm/lib/findbit.S @@ -40,8 +40,8 @@ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) */ ENTRY(_find_next_zero_bit_le) - teq r1, #0 - beq 3b + cmp r2, r1 + bhs 3b ands ip, r2, #7 beq 1b @ If new byte, goto old routine ARM( ldrb r3, [r0, r2, lsr #3] ) @@ -81,8 +81,8 @@ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) */ ENTRY(_find_next_bit_le) - teq r1, #0 - beq 3b + cmp r2, r1 + bhs 3b ands ip, r2, #7 beq 1b @ If new byte, goto old routine ARM( ldrb r3, [r0, r2, lsr #3] ) @@ -115,8 +115,8 @@ ENDPROC(_find_first_zero_bit_be) ENTRY(_find_next_zero_bit_be) - teq r1, #0 - beq 3b + cmp r2, r1 + bhs 3b ands ip, r2, #7 beq 1b @ If new byte, goto old routine eor r3, r2, #0x18 @ big endian byte ordering @@ -149,8 +149,8 @@ ENDPROC(_find_first_bit_be) ENTRY(_find_next_bit_be) - teq r1, #0 - beq 3b + cmp r2, r1 + bhs 3b ands ip, r2, #7 beq 1b @ If new byte, goto old routine eor r3, r2, #0x18 @ big endian byte ordering --- linux-oracle-5.4.0.orig/arch/arm/lib/memset.S +++ linux-oracle-5.4.0/arch/arm/lib/memset.S @@ -16,6 +16,7 @@ ENTRY(mmioset) ENTRY(memset) UNWIND( .fnstart ) + and r1, r1, #255 @ cast to unsigned char ands r3, r0, #3 @ 1 unaligned? mov ip, r0 @ preserve r0 as return value bne 6f @ 1 --- linux-oracle-5.4.0.orig/arch/arm/lib/xor-neon.c +++ linux-oracle-5.4.0/arch/arm/lib/xor-neon.c @@ -26,8 +26,9 @@ * While older versions of GCC do not generate incorrect code, they fail to * recognize the parallel nature of these functions, and emit plain ARM code, * which is known to be slower than the optimized ARM code in asm-arm/xor.h. + * + * #warning This code requires at least version 4.6 of GCC */ -#warning This code requires at least version 4.6 of GCC #endif #pragma GCC diagnostic ignored "-Wunused-variable" --- linux-oracle-5.4.0.orig/arch/arm/mach-at91/pm.c +++ linux-oracle-5.4.0/arch/arm/mach-at91/pm.c @@ -103,7 +103,7 @@ static const struct of_device_id sama5d2_ws_ids[] = { { .compatible = "atmel,sama5d2-gem", .data = &ws_info[0] }, - { .compatible = "atmel,at91rm9200-rtc", .data = &ws_info[1] }, + { .compatible = "atmel,sama5d2-rtc", .data = &ws_info[1] }, { .compatible = "atmel,sama5d3-udc", .data = &ws_info[2] }, { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, @@ -114,12 +114,12 @@ }; static const struct of_device_id sam9x60_ws_ids[] = { - { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] }, + { .compatible = "microchip,sam9x60-rtc", .data = &ws_info[1] }, { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] }, { .compatible = "usb-ehci", .data = &ws_info[2] }, - { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] }, + { .compatible = "microchip,sam9x60-rtt", .data = &ws_info[4] }, { .compatible = "cdns,sam9x60-macb", .data = &ws_info[5] }, { /* sentinel */ } }; @@ -592,13 +592,13 @@ sram_pool = gen_pool_get(&pdev->dev, NULL); if (!sram_pool) { pr_warn("%s: sram pool unavailable!\n", __func__); - return; + goto out_put_device; } sram_base = gen_pool_alloc(sram_pool, at91_pm_suspend_in_sram_sz); if (!sram_base) { pr_warn("%s: unable to alloc sram!\n", __func__); - return; + goto out_put_device; } sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base); @@ -606,12 +606,17 @@ at91_pm_suspend_in_sram_sz, false); if (!at91_suspend_sram_fn) { pr_warn("SRAM: Could not map\n"); - return; + goto out_put_device; } /* Copy the pm suspend handler to SRAM */ at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); + return; + +out_put_device: + put_device(&pdev->dev); + return; } static bool __init at91_is_pm_mode_active(int pm_mode) @@ -691,6 +696,12 @@ soc_pm.data.suspend_mode = AT91_PM_ULP0; } +static const struct of_device_id atmel_shdwc_ids[] = { + { .compatible = "atmel,sama5d2-shdwc" }, + { .compatible = "microchip,sam9x60-shdwc" }, + { /* sentinel. */ } +}; + static void __init at91_pm_modes_init(void) { struct device_node *np; @@ -700,7 +711,7 @@ !at91_is_pm_mode_active(AT91_PM_ULP1)) return; - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc"); + np = of_find_matching_node(NULL, atmel_shdwc_ids); if (!np) { pr_warn("%s: failed to find shdwc!\n", __func__); goto ulp1_default; @@ -751,6 +762,7 @@ { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] }, { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] }, + { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] }, { /* sentinel */ }, }; @@ -765,6 +777,7 @@ pmc_np = of_find_matching_node_and_match(NULL, atmel_pmc_ids, &of_id); soc_pm.data.pmc = of_iomap(pmc_np, 0); + of_node_put(pmc_np); if (!soc_pm.data.pmc) { pr_err("AT91: PM not supported, PMC not found\n"); return; --- linux-oracle-5.4.0.orig/arch/arm/mach-at91/pm_suspend.S +++ linux-oracle-5.4.0/arch/arm/mach-at91/pm_suspend.S @@ -268,6 +268,10 @@ orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] + /* Quirk for SAM9X60's PMC */ + nop + nop + wait_mckrdy /* Enable the crystal oscillator */ --- linux-oracle-5.4.0.orig/arch/arm/mach-axxia/platsmp.c +++ linux-oracle-5.4.0/arch/arm/mach-axxia/platsmp.c @@ -39,6 +39,7 @@ return -ENOENT; syscon = of_iomap(syscon_np, 0); + of_node_put(syscon_np); if (!syscon) return -ENOMEM; --- linux-oracle-5.4.0.orig/arch/arm/mach-bcm/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-bcm/Kconfig @@ -214,7 +214,6 @@ select HAVE_ARM_ARCH_TIMER select BRCMSTB_L2_IRQ select BCM7120_L2_IRQ - select ARCH_HAS_HOLES_MEMORYMODEL select ZONE_DMA if ARM_LPAE select SOC_BRCMSTB select SOC_BUS --- linux-oracle-5.4.0.orig/arch/arm/mach-bcm/bcm_kona_smc.c +++ linux-oracle-5.4.0/arch/arm/mach-bcm/bcm_kona_smc.c @@ -54,6 +54,7 @@ return -ENODEV; prop_val = of_get_address(node, 0, &prop_size, NULL); + of_node_put(node); if (!prop_val) return -EINVAL; --- linux-oracle-5.4.0.orig/arch/arm/mach-cns3xxx/core.c +++ linux-oracle-5.4.0/arch/arm/mach-cns3xxx/core.c @@ -376,6 +376,7 @@ /* De-Asscer SATA Reset */ cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SATA)); } + of_node_put(dn); dn = of_find_compatible_node(NULL, NULL, "cavium,cns3420-sdhci"); if (of_device_is_available(dn)) { @@ -389,6 +390,7 @@ cns3xxx_pwr_clk_en(CNS3XXX_PWR_CLK_EN(SDIO)); cns3xxx_pwr_soft_rst(CNS3XXX_PWR_SOFTWARE_RST(SDIO)); } + of_node_put(dn); pm_power_off = cns3xxx_power_off; --- linux-oracle-5.4.0.orig/arch/arm/mach-davinci/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-davinci/Kconfig @@ -3,12 +3,13 @@ menuconfig ARCH_DAVINCI bool "TI DaVinci" depends on ARCH_MULTI_V5 + select CPU_ARM926T select DAVINCI_TIMER select ZONE_DMA - select ARCH_HAS_HOLES_MEMORYMODEL select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS_OF if PM && OF select REGMAP_MMIO + select RESET_CONTROLLER select HAVE_IDE select PINCTRL_SINGLE --- linux-oracle-5.4.0.orig/arch/arm/mach-davinci/board-da850-evm.c +++ linux-oracle-5.4.0/arch/arm/mach-davinci/board-da850-evm.c @@ -1101,11 +1101,13 @@ int ret; u32 val; struct davinci_soc_info *soc_info = &davinci_soc_info; - u8 rmii_en = soc_info->emac_pdata->rmii_en; + u8 rmii_en; if (!machine_is_davinci_da850_evm()) return 0; + rmii_en = soc_info->emac_pdata->rmii_en; + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); val = __raw_readl(cfg_chip3_base); --- linux-oracle-5.4.0.orig/arch/arm/mach-davinci/pm.c +++ linux-oracle-5.4.0/arch/arm/mach-davinci/pm.c @@ -62,7 +62,7 @@ /* Configure sleep count in deep sleep register */ val = __raw_readl(pm_config.deepsleep_reg); - val &= ~DEEPSLEEP_SLEEPCOUNT_MASK, + val &= ~DEEPSLEEP_SLEEPCOUNT_MASK; val |= pm_config.sleepcount; __raw_writel(val, pm_config.deepsleep_reg); --- linux-oracle-5.4.0.orig/arch/arm/mach-ep93xx/core.c +++ linux-oracle-5.4.0/arch/arm/mach-ep93xx/core.c @@ -337,6 +337,7 @@ GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), GPIO_LOOKUP_IDX("G", 0, NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), + { } }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-ep93xx/timer-ep93xx.c +++ linux-oracle-5.4.0/arch/arm/mach-ep93xx/timer-ep93xx.c @@ -9,6 +9,7 @@ #include #include #include "soc.h" +#include "platform.h" /************************************************************************* * Timer handling for EP93xx @@ -60,7 +61,7 @@ return ret; } -u64 ep93xx_clocksource_read(struct clocksource *c) +static u64 ep93xx_clocksource_read(struct clocksource *c) { u64 ret; --- linux-oracle-5.4.0.orig/arch/arm/mach-exynos/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-exynos/Kconfig @@ -8,7 +8,6 @@ menuconfig ARCH_EXYNOS bool "Samsung EXYNOS" depends on ARCH_MULTI_V7 - select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA select ARM_GIC --- linux-oracle-5.4.0.orig/arch/arm/mach-exynos/exynos.c +++ linux-oracle-5.4.0/arch/arm/mach-exynos/exynos.c @@ -46,6 +46,7 @@ sysram_base_addr = of_iomap(node, 0); sysram_base_phys = of_translate_address(node, of_get_address(node, 0, NULL, NULL)); + of_node_put(node); break; } @@ -53,6 +54,7 @@ if (!of_device_is_available(node)) continue; sysram_ns_base_addr = of_iomap(node, 0); + of_node_put(node); break; } } @@ -134,6 +136,7 @@ np = of_find_matching_node(NULL, exynos_dt_pmu_match); if (np) pmu_base_addr = of_iomap(np, 0); + of_node_put(np); } static void __init exynos_init_irq(void) --- linux-oracle-5.4.0.orig/arch/arm/mach-exynos/mcpm-exynos.c +++ linux-oracle-5.4.0/arch/arm/mach-exynos/mcpm-exynos.c @@ -26,6 +26,7 @@ #define EXYNOS5420_USE_L2_COMMON_UP_STATE BIT(30) static void __iomem *ns_sram_base_addr __ro_after_init; +static bool secure_firmware __ro_after_init; /* * The common v7_exit_coherency_flush API could not be used because of the @@ -58,15 +59,16 @@ static int exynos_cpu_powerup(unsigned int cpu, unsigned int cluster) { unsigned int cpunr = cpu + (cluster * EXYNOS5420_CPUS_PER_CLUSTER); + bool state; pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); if (cpu >= EXYNOS5420_CPUS_PER_CLUSTER || cluster >= EXYNOS5420_NR_CLUSTERS) return -EINVAL; - if (!exynos_cpu_power_state(cpunr)) { - exynos_cpu_power_up(cpunr); - + state = exynos_cpu_power_state(cpunr); + exynos_cpu_power_up(cpunr); + if (!state && secure_firmware) { /* * This assumes the cluster number of the big cores(Cortex A15) * is 0 and the Little cores(Cortex A7) is 1. @@ -258,6 +260,8 @@ return -ENOMEM; } + secure_firmware = exynos_secure_firmware_available(); + /* * To increase the stability of KFC reset we need to program * the PMU SPARE3 register --- linux-oracle-5.4.0.orig/arch/arm/mach-footbridge/cats-pci.c +++ linux-oracle-5.4.0/arch/arm/mach-footbridge/cats-pci.c @@ -15,14 +15,14 @@ #include /* cats host-specific stuff */ -static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; +static int irqmap_cats[] = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; static u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin) { return 0; } -static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->irq >= 255) return -1; /* not a valid interrupt. */ --- linux-oracle-5.4.0.orig/arch/arm/mach-footbridge/dc21285.c +++ linux-oracle-5.4.0/arch/arm/mach-footbridge/dc21285.c @@ -66,15 +66,15 @@ if (addr) switch (size) { case 1: - asm("ldrb %0, [%1, %2]" + asm volatile("ldrb %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 2: - asm("ldrh %0, [%1, %2]" + asm volatile("ldrh %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 4: - asm("ldr %0, [%1, %2]" + asm volatile("ldr %0, [%1, %2]" : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; } @@ -100,17 +100,17 @@ if (addr) switch (size) { case 1: - asm("strb %0, [%1, %2]" + asm volatile("strb %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; case 2: - asm("strh %0, [%1, %2]" + asm volatile("strh %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; case 4: - asm("str %0, [%1, %2]" + asm volatile("str %0, [%1, %2]" : : "r" (value), "r" (addr), "r" (where) : "cc"); break; --- linux-oracle-5.4.0.orig/arch/arm/mach-footbridge/ebsa285-pci.c +++ linux-oracle-5.4.0/arch/arm/mach-footbridge/ebsa285-pci.c @@ -14,9 +14,9 @@ #include #include -static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; +static int irqmap_ebsa285[] = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; -static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { if (dev->vendor == PCI_VENDOR_ID_CONTAQ && dev->device == PCI_DEVICE_ID_CONTAQ_82C693) --- linux-oracle-5.4.0.orig/arch/arm/mach-footbridge/netwinder-pci.c +++ linux-oracle-5.4.0/arch/arm/mach-footbridge/netwinder-pci.c @@ -18,7 +18,7 @@ * We now use the slot ID instead of the device identifiers to select * which interrupt is routed where. */ -static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) +static int netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (slot) { case 0: /* host bridge */ --- linux-oracle-5.4.0.orig/arch/arm/mach-footbridge/personal-pci.c +++ linux-oracle-5.4.0/arch/arm/mach-footbridge/personal-pci.c @@ -14,13 +14,12 @@ #include #include -static int irqmap_personal_server[] __initdata = { +static int irqmap_personal_server[] = { IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI }; -static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot, - u8 pin) +static int personal_server_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { unsigned char line; --- linux-oracle-5.4.0.orig/arch/arm/mach-highbank/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-highbank/Kconfig @@ -2,7 +2,6 @@ config ARCH_HIGHBANK bool "Calxeda ECX-1000/2000 (Highbank/Midway)" depends on ARCH_MULTI_V7 - select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA select ARM_ERRATA_764369 if SMP --- linux-oracle-5.4.0.orig/arch/arm/mach-hisi/platsmp.c +++ linux-oracle-5.4.0/arch/arm/mach-hisi/platsmp.c @@ -67,14 +67,17 @@ } ctrl_base = of_iomap(np, 0); if (!ctrl_base) { + of_node_put(np); pr_err("failed to map address\n"); return; } if (of_property_read_u32(np, "smp-offset", &offset) < 0) { + of_node_put(np); pr_err("failed to find smp-offset property\n"); return; } ctrl_base += offset; + of_node_put(np); } } @@ -160,6 +163,7 @@ if (WARN_ON(!node)) return -1; ctrl_base = of_iomap(node, 0); + of_node_put(node); /* set the secondary core boot from DDR */ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-imx/Kconfig @@ -520,6 +520,7 @@ bool "i.MX6 UltraLite support" select PINCTRL_IMX6UL select SOC_IMX6 + select ARM_ERRATA_814220 help This enables support for Freescale i.MX6 UltraLite processor. @@ -556,6 +557,7 @@ select PINCTRL_IMX7D select SOC_IMX7D_CA7 if ARCH_MULTI_V7 select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M + select ARM_ERRATA_814220 if ARCH_MULTI_V7 help This enables support for Freescale i.MX7 Dual processor. --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/Makefile +++ linux-oracle-5.4.0/arch/arm/mach-imx/Makefile @@ -91,6 +91,10 @@ obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o endif +ifeq ($(CONFIG_ARM_CPU_SUSPEND),y) +AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a +obj-$(CONFIG_SOC_IMX6) += resume-imx6.o +endif obj-$(CONFIG_SOC_IMX6) += pm-imx6.o obj-$(CONFIG_SOC_IMX1) += mach-imx1.o --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/common.h +++ linux-oracle-5.4.0/arch/arm/mach-imx/common.h @@ -109,17 +109,17 @@ int imx_cpu_kill(unsigned int cpu); #ifdef CONFIG_SUSPEND -void v7_cpu_resume(void); void imx53_suspend(void __iomem *ocram_vbase); extern const u32 imx53_suspend_sz; void imx6_suspend(void __iomem *ocram_vbase); #else -static inline void v7_cpu_resume(void) {} static inline void imx53_suspend(void __iomem *ocram_vbase) {} static const u32 imx53_suspend_sz; static inline void imx6_suspend(void __iomem *ocram_vbase) {} #endif +void v7_cpu_resume(void); + void imx6_pm_ccm_init(const char *ccm_compat); void imx6q_pm_init(void); void imx6dl_pm_init(void); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/cpu-imx25.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/cpu-imx25.c @@ -23,6 +23,7 @@ np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim"); iim_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!iim_base); rev = readl(iim_base + MXC_IIMSREV); iounmap(iim_base); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/cpu-imx27.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/cpu-imx27.c @@ -9,6 +9,7 @@ */ #include +#include #include #include "hardware.h" @@ -17,16 +18,24 @@ static int mx27_cpu_partnumber; #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ +#define SYSCTRL_OFFSET 0x800 /* Offset from CCM base address */ static int mx27_read_cpu_rev(void) { + void __iomem *ccm_base; + struct device_node *np; u32 val; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); + ccm_base = of_iomap(np, 0); + of_node_put(np); + BUG_ON(!ccm_base); /* * now we have access to the IO registers. As we need * the silicon revision very early we read it here to * avoid any further hooks */ - val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); + val = imx_readl(ccm_base + SYSCTRL_OFFSET + SYS_CHIP_ID); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/cpu-imx31.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/cpu-imx31.c @@ -6,6 +6,7 @@ */ #include +#include #include #include "common.h" @@ -32,10 +33,17 @@ static int mx31_read_cpu_rev(void) { + void __iomem *iim_base; + struct device_node *np; u32 i, srev; + np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim"); + iim_base = of_iomap(np, 0); + of_node_put(np); + BUG_ON(!iim_base); + /* read SREV register from IIM module */ - srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(iim_base + MXC_IIMSREV); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/cpu-imx35.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/cpu-imx35.c @@ -5,6 +5,7 @@ * Copyright (c) 2009 Daniel Mack */ #include +#include #include #include "hardware.h" @@ -14,9 +15,16 @@ static int mx35_read_cpu_rev(void) { + void __iomem *iim_base; + struct device_node *np; u32 rev; - rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim"); + iim_base = of_iomap(np, 0); + of_node_put(np); + BUG_ON(!iim_base); + + rev = imx_readl(iim_base + MXC_IIMSREV); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/cpu-imx5.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/cpu-imx5.c @@ -28,6 +28,7 @@ np = of_find_compatible_node(NULL, NULL, compat); iim_base = of_iomap(np, 0); + of_node_put(np); WARN_ON(!iim_base); srev = readl(iim_base + IIM_SREV) & 0xff; --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/mmdc.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/mmdc.c @@ -99,10 +99,12 @@ cpumask_t cpu; struct hrtimer hrtimer; unsigned int active_events; + int id; struct device *dev; struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; struct hlist_node node; struct fsl_mmdc_devtype_data *devtype_data; + struct clk *mmdc_ipg_clk; }; /* @@ -432,8 +434,6 @@ static int mmdc_pmu_init(struct mmdc_pmu *pmu_mmdc, void __iomem *mmdc_base, struct device *dev) { - int mmdc_num; - *pmu_mmdc = (struct mmdc_pmu) { .pmu = (struct pmu) { .task_ctx_nr = perf_invalid_context, @@ -451,26 +451,29 @@ .active_events = 0, }; - mmdc_num = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); + pmu_mmdc->id = ida_simple_get(&mmdc_ida, 0, 0, GFP_KERNEL); - return mmdc_num; + return pmu_mmdc->id; } static int imx_mmdc_remove(struct platform_device *pdev) { struct mmdc_pmu *pmu_mmdc = platform_get_drvdata(pdev); + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); perf_pmu_unregister(&pmu_mmdc->pmu); + iounmap(pmu_mmdc->mmdc_base); + clk_disable_unprepare(pmu_mmdc->mmdc_ipg_clk); kfree(pmu_mmdc); return 0; } -static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base) +static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base, + struct clk *mmdc_ipg_clk) { struct mmdc_pmu *pmu_mmdc; char *name; - int mmdc_num; int ret; const struct of_device_id *of_id = of_match_device(imx_mmdc_dt_ids, &pdev->dev); @@ -493,13 +496,18 @@ cpuhp_mmdc_state = ret; } - mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); - if (mmdc_num == 0) - name = "mmdc"; - else - name = devm_kasprintf(&pdev->dev, - GFP_KERNEL, "mmdc%d", mmdc_num); + ret = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); + if (ret < 0) + goto pmu_free; + + name = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "mmdc%d", ret); + if (!name) { + ret = -ENOMEM; + goto pmu_release_id; + } + pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, @@ -522,6 +530,8 @@ pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); hrtimer_cancel(&pmu_mmdc->hrtimer); +pmu_release_id: + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); pmu_free: kfree(pmu_mmdc); return ret; @@ -529,7 +539,7 @@ #else #define imx_mmdc_remove NULL -#define imx_mmdc_perf_init(pdev, mmdc_base) 0 +#define imx_mmdc_perf_init(pdev, mmdc_base, mmdc_ipg_clk) 0 #endif static int imx_mmdc_probe(struct platform_device *pdev) @@ -567,7 +577,13 @@ val &= ~(1 << BP_MMDC_MAPSR_PSD); writel_relaxed(val, reg); - return imx_mmdc_perf_init(pdev, mmdc_base); + err = imx_mmdc_perf_init(pdev, mmdc_base, mmdc_ipg_clk); + if (err) { + iounmap(mmdc_base); + clk_disable_unprepare(mmdc_ipg_clk); + } + + return err; } int imx_mmdc_get_ddr_type(void) --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/pm-imx5.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/pm-imx5.c @@ -295,14 +295,14 @@ if (!ocram_pool) { pr_warn("%s: ocram pool unavailable!\n", __func__); ret = -ENODEV; - goto put_node; + goto put_device; } ocram_base = gen_pool_alloc(ocram_pool, size); if (!ocram_base) { pr_warn("%s: unable to alloc ocram!\n", __func__); ret = -ENOMEM; - goto put_node; + goto put_device; } phys = gen_pool_virt_to_phys(ocram_pool, ocram_base); @@ -312,6 +312,8 @@ if (virt_out) *virt_out = virt; +put_device: + put_device(&pdev->dev); put_node: of_node_put(node); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/pm-imx6.c +++ linux-oracle-5.4.0/arch/arm/mach-imx/pm-imx6.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -493,14 +494,14 @@ if (!ocram_pool) { pr_warn("%s: ocram pool unavailable!\n", __func__); ret = -ENODEV; - goto put_node; + goto put_device; } ocram_base = gen_pool_alloc(ocram_pool, MX6Q_SUSPEND_OCRAM_SIZE); if (!ocram_base) { pr_warn("%s: unable to alloc ocram!\n", __func__); ret = -ENOMEM; - goto put_node; + goto put_device; } ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); @@ -523,7 +524,7 @@ ret = imx6_pm_get_base(&pm_info->mmdc_base, socdata->mmdc_compat); if (ret) { pr_warn("%s: failed to get mmdc base %d!\n", __func__, ret); - goto put_node; + goto put_device; } ret = imx6_pm_get_base(&pm_info->src_base, socdata->src_compat); @@ -570,7 +571,7 @@ &imx6_suspend, MX6Q_SUSPEND_OCRAM_SIZE - sizeof(*pm_info)); - goto put_node; + goto put_device; pl310_cache_map_failed: iounmap(pm_info->gpc_base.vbase); @@ -580,6 +581,8 @@ iounmap(pm_info->src_base.vbase); src_map_failed: iounmap(pm_info->mmdc_base.vbase); +put_device: + put_device(&pdev->dev); put_node: of_node_put(node); @@ -616,6 +619,7 @@ static void imx6_pm_stby_poweroff(void) { + gic_cpu_if_down(0); imx6_set_lpm(STOP_POWER_OFF); imx6q_suspend_finish(0); --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/resume-imx6.S +++ linux-oracle-5.4.0/arch/arm/mach-imx/resume-imx6.S @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include +#include +#include +#include +#include "hardware.h" + +/* + * The following code must assume it is running from physical address + * where absolute virtual addresses to the data section have to be + * turned into relative ones. + */ + +ENTRY(v7_cpu_resume) + bl v7_invalidate_l1 +#ifdef CONFIG_CACHE_L2X0 + bl l2c310_early_resume +#endif + b cpu_resume +ENDPROC(v7_cpu_resume) --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/suspend-imx53.S +++ linux-oracle-5.4.0/arch/arm/mach-imx/suspend-imx53.S @@ -28,11 +28,11 @@ * ^ * ^ * imx53_suspend code - * PM_INFO structure(imx53_suspend_info) + * PM_INFO structure(imx5_cpu_suspend_info) * ======================== low address ======================= */ -/* Offsets of members of struct imx53_suspend_info */ +/* Offsets of members of struct imx5_cpu_suspend_info */ #define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 --- linux-oracle-5.4.0.orig/arch/arm/mach-imx/suspend-imx6.S +++ linux-oracle-5.4.0/arch/arm/mach-imx/suspend-imx6.S @@ -67,6 +67,7 @@ #define MX6Q_CCM_CCR 0x0 .align 3 + .arm .macro sync_l2_cache @@ -327,17 +328,3 @@ ret lr ENDPROC(imx6_suspend) - -/* - * The following code must assume it is running from physical address - * where absolute virtual addresses to the data section have to be - * turned into relative ones. - */ - -ENTRY(v7_cpu_resume) - bl v7_invalidate_l1 -#ifdef CONFIG_CACHE_L2X0 - bl l2c310_early_resume -#endif - b cpu_resume -ENDPROC(v7_cpu_resume) --- linux-oracle-5.4.0.orig/arch/arm/mach-integrator/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-integrator/Kconfig @@ -4,6 +4,8 @@ depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 select ARM_AMBA select COMMON_CLK_VERSATILE + select CMA + select DMA_CMA select HAVE_TCM select ICST select MFD_SYSCON @@ -35,14 +37,13 @@ select ARM_VIC select GPIO_PL061 select GPIOLIB + select REGULATOR + select REGULATOR_FIXED_VOLTAGE help The IM-PD1 is an add-on logic module for the Integrator which allows ARM(R) Ltd PrimeCells to be developed and evaluated. The IM-PD1 can be found on the Integrator/PP2 platform. - To compile this driver as a module, choose M here: the - module will be called impd1. - config INTEGRATOR_CM7TDMI bool "Integrator/CM7TDMI core module" depends on ARCH_INTEGRATOR_AP --- linux-oracle-5.4.0.orig/arch/arm/mach-iop32x/include/mach/entry-macro.S +++ linux-oracle-5.4.0/arch/arm/mach-iop32x/include/mach/entry-macro.S @@ -20,7 +20,7 @@ mrc p6, 0, \irqstat, c8, c0, 0 @ Read IINTSRC cmp \irqstat, #0 clzne \irqnr, \irqstat - rsbne \irqnr, \irqnr, #31 + rsbne \irqnr, \irqnr, #32 .endm .macro arch_ret_to_user, tmp1, tmp2 --- linux-oracle-5.4.0.orig/arch/arm/mach-iop32x/include/mach/irqs.h +++ linux-oracle-5.4.0/arch/arm/mach-iop32x/include/mach/irqs.h @@ -9,6 +9,6 @@ #ifndef __IRQS_H #define __IRQS_H -#define NR_IRQS 32 +#define NR_IRQS 33 #endif --- linux-oracle-5.4.0.orig/arch/arm/mach-iop32x/irq.c +++ linux-oracle-5.4.0/arch/arm/mach-iop32x/irq.c @@ -32,14 +32,14 @@ static void iop32x_irq_mask(struct irq_data *d) { - iop32x_mask &= ~(1 << d->irq); + iop32x_mask &= ~(1 << (d->irq - 1)); intctl_write(iop32x_mask); } static void iop32x_irq_unmask(struct irq_data *d) { - iop32x_mask |= 1 << d->irq; + iop32x_mask |= 1 << (d->irq - 1); intctl_write(iop32x_mask); } @@ -65,7 +65,7 @@ machine_is_em7210()) *IOP3XX_PCIIRSR = 0x0f; - for (i = 0; i < NR_IRQS; i++) { + for (i = 1; i < NR_IRQS; i++) { irq_set_chip_and_handler(i, &ext_chip, handle_level_irq); irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE); } --- linux-oracle-5.4.0.orig/arch/arm/mach-iop32x/irqs.h +++ linux-oracle-5.4.0/arch/arm/mach-iop32x/irqs.h @@ -7,36 +7,40 @@ #ifndef __IOP32X_IRQS_H #define __IOP32X_IRQS_H +/* Interrupts in Linux start at 1, hardware starts at 0 */ + +#define IOP_IRQ(x) ((x) + 1) + /* * IOP80321 chipset interrupts */ -#define IRQ_IOP32X_DMA0_EOT 0 -#define IRQ_IOP32X_DMA0_EOC 1 -#define IRQ_IOP32X_DMA1_EOT 2 -#define IRQ_IOP32X_DMA1_EOC 3 -#define IRQ_IOP32X_AA_EOT 6 -#define IRQ_IOP32X_AA_EOC 7 -#define IRQ_IOP32X_CORE_PMON 8 -#define IRQ_IOP32X_TIMER0 9 -#define IRQ_IOP32X_TIMER1 10 -#define IRQ_IOP32X_I2C_0 11 -#define IRQ_IOP32X_I2C_1 12 -#define IRQ_IOP32X_MESSAGING 13 -#define IRQ_IOP32X_ATU_BIST 14 -#define IRQ_IOP32X_PERFMON 15 -#define IRQ_IOP32X_CORE_PMU 16 -#define IRQ_IOP32X_BIU_ERR 17 -#define IRQ_IOP32X_ATU_ERR 18 -#define IRQ_IOP32X_MCU_ERR 19 -#define IRQ_IOP32X_DMA0_ERR 20 -#define IRQ_IOP32X_DMA1_ERR 21 -#define IRQ_IOP32X_AA_ERR 23 -#define IRQ_IOP32X_MSG_ERR 24 -#define IRQ_IOP32X_SSP 25 -#define IRQ_IOP32X_XINT0 27 -#define IRQ_IOP32X_XINT1 28 -#define IRQ_IOP32X_XINT2 29 -#define IRQ_IOP32X_XINT3 30 -#define IRQ_IOP32X_HPI 31 +#define IRQ_IOP32X_DMA0_EOT IOP_IRQ(0) +#define IRQ_IOP32X_DMA0_EOC IOP_IRQ(1) +#define IRQ_IOP32X_DMA1_EOT IOP_IRQ(2) +#define IRQ_IOP32X_DMA1_EOC IOP_IRQ(3) +#define IRQ_IOP32X_AA_EOT IOP_IRQ(6) +#define IRQ_IOP32X_AA_EOC IOP_IRQ(7) +#define IRQ_IOP32X_CORE_PMON IOP_IRQ(8) +#define IRQ_IOP32X_TIMER0 IOP_IRQ(9) +#define IRQ_IOP32X_TIMER1 IOP_IRQ(10) +#define IRQ_IOP32X_I2C_0 IOP_IRQ(11) +#define IRQ_IOP32X_I2C_1 IOP_IRQ(12) +#define IRQ_IOP32X_MESSAGING IOP_IRQ(13) +#define IRQ_IOP32X_ATU_BIST IOP_IRQ(14) +#define IRQ_IOP32X_PERFMON IOP_IRQ(15) +#define IRQ_IOP32X_CORE_PMU IOP_IRQ(16) +#define IRQ_IOP32X_BIU_ERR IOP_IRQ(17) +#define IRQ_IOP32X_ATU_ERR IOP_IRQ(18) +#define IRQ_IOP32X_MCU_ERR IOP_IRQ(19) +#define IRQ_IOP32X_DMA0_ERR IOP_IRQ(20) +#define IRQ_IOP32X_DMA1_ERR IOP_IRQ(21) +#define IRQ_IOP32X_AA_ERR IOP_IRQ(23) +#define IRQ_IOP32X_MSG_ERR IOP_IRQ(24) +#define IRQ_IOP32X_SSP IOP_IRQ(25) +#define IRQ_IOP32X_XINT0 IOP_IRQ(27) +#define IRQ_IOP32X_XINT1 IOP_IRQ(28) +#define IRQ_IOP32X_XINT2 IOP_IRQ(29) +#define IRQ_IOP32X_XINT3 IOP_IRQ(30) +#define IRQ_IOP32X_HPI IOP_IRQ(31) #endif --- linux-oracle-5.4.0.orig/arch/arm/mach-ixp4xx/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-ixp4xx/Kconfig @@ -13,7 +13,6 @@ select I2C select I2C_IOP3XX select PCI - select TIMER_OF select USE_OF help Say 'Y' here to support Device Tree-based IXP4xx platforms. --- linux-oracle-5.4.0.orig/arch/arm/mach-keystone/keystone.c +++ linux-oracle-5.4.0/arch/arm/mach-keystone/keystone.c @@ -62,7 +62,7 @@ static long long __init keystone_pv_fixup(void) { long long offset; - phys_addr_t mem_start, mem_end; + u64 mem_start, mem_end; mem_start = memblock_start_of_DRAM(); mem_end = memblock_end_of_DRAM(); @@ -75,7 +75,7 @@ if (mem_start < KEYSTONE_HIGH_PHYS_START || mem_end > KEYSTONE_HIGH_PHYS_END) { pr_crit("Invalid address space for memory (%08llx-%08llx)\n", - (u64)mem_start, (u64)mem_end); + mem_start, mem_end); return 0; } --- linux-oracle-5.4.0.orig/arch/arm/mach-mediatek/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-mediatek/Kconfig @@ -30,6 +30,7 @@ config MACH_MT7629 bool "MediaTek MT7629 SoCs support" default ARCH_MEDIATEK + select HAVE_ARM_ARCH_TIMER config MACH_MT8127 bool "MediaTek MT8127 SoCs support" --- linux-oracle-5.4.0.orig/arch/arm/mach-meson/platsmp.c +++ linux-oracle-5.4.0/arch/arm/mach-meson/platsmp.c @@ -71,6 +71,7 @@ } sram_base = of_iomap(node, 0); + of_node_put(node); if (!sram_base) { pr_err("Couldn't map SRAM registers\n"); return; @@ -91,6 +92,7 @@ } scu_base = of_iomap(node, 0); + of_node_put(node); if (!scu_base) { pr_err("Couldn't map SCU registers\n"); return; --- linux-oracle-5.4.0.orig/arch/arm/mach-mmp/sram.c +++ linux-oracle-5.4.0/arch/arm/mach-mmp/sram.c @@ -72,6 +72,8 @@ if (!info) return -ENOMEM; + platform_set_drvdata(pdev, info); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no memory resource defined\n"); @@ -107,8 +109,6 @@ list_add(&info->node, &sram_bank_list); mutex_unlock(&sram_lock); - platform_set_drvdata(pdev, info); - dev_info(&pdev->dev, "initialized\n"); return 0; @@ -127,17 +127,19 @@ struct sram_bank_info *info; info = platform_get_drvdata(pdev); - if (info == NULL) - return -ENODEV; - mutex_lock(&sram_lock); - list_del(&info->node); - mutex_unlock(&sram_lock); + if (info->sram_size) { + mutex_lock(&sram_lock); + list_del(&info->node); + mutex_unlock(&sram_lock); + + gen_pool_destroy(info->gpool); + iounmap(info->sram_virt); + kfree(info->pool_name); + } - gen_pool_destroy(info->gpool); - iounmap(info->sram_virt); - kfree(info->pool_name); kfree(info); + return 0; } --- linux-oracle-5.4.0.orig/arch/arm/mach-mmp/time.c +++ linux-oracle-5.4.0/arch/arm/mach-mmp/time.c @@ -44,18 +44,21 @@ static void __iomem *mmp_timer_base = TIMERS_VIRT_BASE; /* - * FIXME: the timer needs some delay to stablize the counter capture + * Read the timer through the CVWR register. Delay is required after requesting + * a read. The CR register cannot be directly read due to metastability issues + * documented in the PXA168 software manual. */ static inline uint32_t timer_read(void) { - int delay = 100; + uint32_t val; + int delay = 3; __raw_writel(1, mmp_timer_base + TMR_CVWR(1)); while (delay--) - cpu_relax(); + val = __raw_readl(mmp_timer_base + TMR_CVWR(1)); - return __raw_readl(mmp_timer_base + TMR_CVWR(1)); + return val; } static u64 notrace mmp_read_sched_clock(void) --- linux-oracle-5.4.0.orig/arch/arm/mach-mxs/mach-mxs.c +++ linux-oracle-5.4.0/arch/arm/mach-mxs/mach-mxs.c @@ -387,8 +387,10 @@ root = of_find_node_by_path("/"); ret = of_property_read_string(root, "model", &soc_dev_attr->machine); - if (ret) + if (ret) { + kfree(soc_dev_attr); return; + } soc_dev_attr->family = "Freescale MXS Family"; soc_dev_attr->soc_id = mxs_get_soc_id(); --- linux-oracle-5.4.0.orig/arch/arm/mach-npcm/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-npcm/Kconfig @@ -11,7 +11,7 @@ depends on ARCH_MULTI_V7 select PINCTRL_NPCM7XX select NPCM7XX_TIMER - select ARCH_REQUIRE_GPIOLIB + select GPIOLIB select CACHE_L2X0 select ARM_GIC select HAVE_ARM_TWD if SMP --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/ams-delta-fiq-handler.S +++ linux-oracle-5.4.0/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -15,6 +15,7 @@ #include #include +#include #include "ams-delta-fiq.h" #include "board-ams-delta.h" --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/clock.c +++ linux-oracle-5.4.0/arch/arm/mach-omap1/clock.c @@ -41,7 +41,7 @@ unsigned long omap1_uart_recalc(struct clk *clk) { unsigned int val = __raw_readl(clk->enable_reg); - return val & clk->enable_bit ? 48000000 : 12000000; + return val & 1 << clk->enable_bit ? 48000000 : 12000000; } unsigned long omap1_sossi_recalc(struct clk *clk) --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/pm.c +++ linux-oracle-5.4.0/arch/arm/mach-omap1/pm.c @@ -596,11 +596,6 @@ return IRQ_HANDLED; } -static struct irqaction omap_wakeup_irq = { - .name = "peripheral wakeup", - .handler = omap_wakeup_interrupt -}; - static const struct platform_suspend_ops omap_pm_ops = { @@ -613,6 +608,7 @@ static int __init omap_pm_init(void) { int error = 0; + int irq; if (!cpu_class_is_omap1()) return -ENODEV; @@ -656,9 +652,12 @@ arm_pm_idle = omap1_pm_idle; if (cpu_is_omap7xx()) - setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq); + irq = INT_7XX_WAKE_UP_REQ; else if (cpu_is_omap16xx()) - setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); + irq = INT_1610_WAKE_UP_REQ; + if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", + NULL)) + pr_err("Failed to request irq %d (peripheral wakeup)\n", irq); /* Program new power ramp-up time * (0 for most boards since we don't lower voltage when in deep sleep) --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/time.c +++ linux-oracle-5.4.0/arch/arm/mach-omap1/time.c @@ -155,15 +155,11 @@ return IRQ_HANDLED; } -static struct irqaction omap_mpu_timer1_irq = { - .name = "mpu_timer1", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap_mpu_timer1_interrupt, -}; - static __init void omap_init_mpu_timer(unsigned long rate) { - setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); + if (request_irq(INT_TIMER1, omap_mpu_timer1_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "mpu_timer1", NULL)) + pr_err("Failed to request irq %d (mpu_timer1)\n", INT_TIMER1); omap_mpu_timer_start(0, (rate / HZ) - 1, 1); clockevent_mpu_timer1.cpumask = cpumask_of(0); --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/timer.c +++ linux-oracle-5.4.0/arch/arm/mach-omap1/timer.c @@ -165,7 +165,7 @@ kfree(pdata); err_free_pdev: - platform_device_unregister(pdev); + platform_device_put(pdev); return ret; } --- linux-oracle-5.4.0.orig/arch/arm/mach-omap1/timer32k.c +++ linux-oracle-5.4.0/arch/arm/mach-omap1/timer32k.c @@ -148,15 +148,11 @@ return IRQ_HANDLED; } -static struct irqaction omap_32k_timer_irq = { - .name = "32KHz timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap_32k_timer_interrupt, -}; - static __init void omap_init_32k_timer(void) { - setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); + if (request_irq(INT_OS_TIMER, omap_32k_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, "32KHz timer", NULL)) + pr_err("Failed to request irq %d(32KHz timer)\n", INT_OS_TIMER); clockevent_32k_timer.cpumask = cpumask_of(0); clockevents_config_and_register(&clockevent_32k_timer, --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-omap2/Kconfig @@ -94,7 +94,7 @@ config ARCH_OMAP2PLUS bool select ARCH_HAS_BANDGAP - select ARCH_HAS_HOLES_MEMORYMODEL + select ARCH_HAS_RESET_CONTROLLER select ARCH_OMAP select CLKSRC_MMIO select GENERIC_IRQ_CHIP --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/board-generic.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/board-generic.c @@ -327,7 +327,7 @@ .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap5_realtime_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = dra74x_boards_compat, .restart = omap44xx_restart, MACHINE_END @@ -350,7 +350,7 @@ .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, .init_machine = omap_generic_init, - .init_time = omap5_realtime_timer_init, + .init_time = omap3_gptimer_timer_init, .dt_compat = dra72x_boards_compat, .restart = omap44xx_restart, MACHINE_END --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/board-n8x0.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/board-n8x0.c @@ -322,6 +322,7 @@ static void n8x0_mmc_callback(void *data, u8 card_mask) { +#ifdef CONFIG_MMC_OMAP int bit, *openp, index; if (board_is_n800()) { @@ -339,7 +340,6 @@ else *openp = 0; -#ifdef CONFIG_MMC_OMAP omap_mmc_notify_cover_event(mmc_device, index, *openp); #else pr_warn("MMC: notify cover event not available\n"); --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/cpuidle34xx.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/cpuidle34xx.c @@ -109,6 +109,7 @@ int index) { struct omap3_idle_statedata *cx = &omap3_idle_data[index]; + int error; if (omap_irq_pending() || need_resched()) goto return_sleep_time; @@ -125,8 +126,11 @@ * Call idle CPU PM enter notifier chain so that * VFP context is saved. */ - if (cx->mpu_state == PWRDM_POWER_OFF) - cpu_pm_enter(); + if (cx->mpu_state == PWRDM_POWER_OFF) { + error = cpu_pm_enter(); + if (error) + goto out_clkdm_set; + } /* Execute ARM wfi */ omap_sram_idle(); @@ -139,6 +143,7 @@ pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) cpu_pm_exit(); +out_clkdm_set: /* Re-allow idle for C1 */ if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/cpuidle44xx.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/cpuidle44xx.c @@ -122,6 +122,7 @@ { struct idle_statedata *cx = state_ptr + index; u32 mpuss_can_lose_context = 0; + int error; /* * CPU0 has to wait and stay ON until CPU1 is OFF state. @@ -150,27 +151,37 @@ (cx->mpu_logic_state == PWRDM_POWER_OFF); /* Enter broadcast mode for periodic timers */ - tick_broadcast_enable(); + RCU_NONIDLE(tick_broadcast_enable()); /* Enter broadcast mode for one-shot timers */ - tick_broadcast_enter(); + RCU_NONIDLE(tick_broadcast_enter()); /* * Call idle CPU PM enter notifier chain so that * VFP and per CPU interrupt context is saved. */ - cpu_pm_enter(); + error = cpu_pm_enter(); + if (error) + goto cpu_pm_out; if (dev->cpu == 0) { pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); - omap_set_pwrdm_state(mpu_pd, cx->mpu_state); + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); /* * Call idle CPU cluster PM enter notifier chain * to save GIC and wakeupgen context. */ - if (mpuss_can_lose_context) - cpu_cluster_pm_enter(); + if (mpuss_can_lose_context) { + error = cpu_cluster_pm_enter(); + if (error) { + index = 0; + cx = state_ptr + index; + pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); + RCU_NONIDLE(omap_set_pwrdm_state(mpu_pd, cx->mpu_state)); + mpuss_can_lose_context = 0; + } + } } omap4_enter_lowpower(dev->cpu, cx->cpu_state); @@ -183,9 +194,9 @@ mpuss_can_lose_context) gic_dist_disable(); - clkdm_deny_idle(cpu_clkdm[1]); - omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON); - clkdm_allow_idle(cpu_clkdm[1]); + RCU_NONIDLE(clkdm_deny_idle(cpu_clkdm[1])); + RCU_NONIDLE(omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON)); + RCU_NONIDLE(clkdm_allow_idle(cpu_clkdm[1])); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD) && mpuss_can_lose_context) { @@ -198,19 +209,20 @@ } /* - * Call idle CPU PM exit notifier chain to restore - * VFP and per CPU IRQ context. - */ - cpu_pm_exit(); - - /* * Call idle CPU cluster PM exit notifier chain * to restore GIC and wakeupgen context. */ if (dev->cpu == 0 && mpuss_can_lose_context) cpu_cluster_pm_exit(); - tick_broadcast_exit(); + /* + * Call idle CPU PM exit notifier chain to restore + * VFP and per CPU IRQ context. + */ + cpu_pm_exit(); + +cpu_pm_out: + RCU_NONIDLE(tick_broadcast_exit()); fail: cpuidle_coupled_parallel_barrier(dev, &abort_barrier); --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/display.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/display.c @@ -211,6 +211,7 @@ node = of_find_node_by_name(NULL, "omap4_padconf_global"); if (node) omap4_dsi_mux_syscon = syscon_node_to_regmap(node); + of_node_put(node); return 0; } @@ -259,10 +260,13 @@ if (!pdev) { pr_err("Unable to find DSS platform device\n"); + of_node_put(node); return -ENODEV; } r = of_platform_populate(node, NULL, NULL, &pdev->dev); + put_device(&pdev->dev); + of_node_put(node); if (r) { pr_err("Unable to populate DSS submodule devices\n"); return r; --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/id.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/id.c @@ -797,10 +797,15 @@ soc_dev_attr->machine = soc_name; soc_dev_attr->family = omap_get_family(); + if (!soc_dev_attr->family) { + kfree(soc_dev_attr); + return; + } soc_dev_attr->revision = soc_rev; soc_dev = soc_device_register(soc_dev_attr); if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->family); kfree(soc_dev_attr); return; } --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/omap-iommu.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/omap-iommu.c @@ -11,14 +11,43 @@ #include "omap_hwmod.h" #include "omap_device.h" +#include "clockdomain.h" #include "powerdomain.h" +static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev, + bool enable) +{ + static struct clockdomain *emu_clkdm; + static DEFINE_SPINLOCK(emu_lock); + static atomic_t count; + struct device_node *np = pdev->dev.of_node; + + if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu")) + return; + + if (!emu_clkdm) { + emu_clkdm = clkdm_lookup("emu_clkdm"); + if (WARN_ON_ONCE(!emu_clkdm)) + return; + } + + spin_lock(&emu_lock); + + if (enable && (atomic_inc_return(&count) == 1)) + clkdm_deny_idle(emu_clkdm); + else if (!enable && (atomic_dec_return(&count) == 0)) + clkdm_allow_idle(emu_clkdm); + + spin_unlock(&emu_lock); +} + int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request, u8 *pwrst) { struct powerdomain *pwrdm; struct omap_device *od; u8 next_pwrst; + int ret = 0; od = to_omap_device(pdev); if (!od) @@ -31,13 +60,21 @@ if (!pwrdm) return -EINVAL; - if (request) + if (request) { *pwrst = pwrdm_read_next_pwrst(pwrdm); + omap_iommu_dra7_emu_swsup_config(pdev, true); + } if (*pwrst > PWRDM_POWER_RET) - return 0; + goto out; next_pwrst = request ? PWRDM_POWER_ON : *pwrst; - return pwrdm_set_next_pwrst(pwrdm, next_pwrst); + ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst); + +out: + if (!request) + omap_iommu_dra7_emu_swsup_config(pdev, false); + + return ret; } --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/omap4-common.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/omap4-common.c @@ -314,10 +314,12 @@ np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); gic_dist_base_addr = of_iomap(np, 0); + of_node_put(np); WARN_ON(!gic_dist_base_addr); np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer"); twd_base = of_iomap(np, 0); + of_node_put(np); WARN_ON(!twd_base); skip_errata_init: --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/omap_device.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/omap_device.c @@ -234,10 +234,12 @@ break; case BUS_NOTIFY_BIND_DRIVER: od = to_omap_device(pdev); - if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED) && - pm_runtime_status_suspended(dev)) { + if (od) { od->_driver_status = BUS_NOTIFY_BIND_DRIVER; - pm_runtime_set_active(dev); + if (od->_state == OMAP_DEVICE_STATE_ENABLED && + pm_runtime_status_suspended(dev)) { + pm_runtime_set_active(dev); + } } break; case BUS_NOTIFY_ADD_DEVICE: --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/omap_hwmod.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/omap_hwmod.c @@ -782,8 +782,10 @@ for_each_matching_node(np, ti_clkctrl_match_table) { ret = _setup_clkctrl_provider(np); - if (ret) + if (ret) { + of_node_put(np); break; + } } return ret; @@ -3535,7 +3537,7 @@ }; static const struct omap_hwmod_reset omap_reset_quirks[] = { - { .match = "dss", .len = 3, .reset = omap_dss_reset, }, + { .match = "dss_core", .len = 8, .reset = omap_dss_reset, }, { .match = "hdq1w", .len = 5, .reset = omap_hdq1w_reset, }, { .match = "i2c", .len = 3, .reset = omap_i2c_reset, }, { .match = "wd_timer", .len = 8, .reset = omap2_wd_timer_reset, }, @@ -3656,6 +3658,8 @@ oh->flags |= HWMOD_SWSUP_SIDLE_ACT; if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY) oh->flags |= HWMOD_SWSUP_MSTANDBY; + if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO) + oh->flags |= HWMOD_CLKDM_NOAUTO; error = omap_hwmod_check_module(dev, oh, data, sysc_fields, rev_offs, sysc_offs, syss_offs, --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/pdata-quirks.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/pdata-quirks.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -45,6 +44,17 @@ static struct of_dev_auxdata omap_auxdata_lookup[]; static struct twl4030_gpio_platform_data twl_gpio_auxdata; +#if IS_ENABLED(CONFIG_OMAP_IOMMU) +int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request, + u8 *pwrst); +#else +static inline int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, + bool request, u8 *pwrst) +{ + return 0; +} +#endif + #ifdef CONFIG_MACH_NOKIA_N8X0 static void __init omap2420_n8x0_legacy_init(void) { @@ -269,14 +279,6 @@ am35xx_emac_reset(); } -static struct platform_device omap3_rom_rng_device = { - .name = "omap3-rom-rng", - .id = -1, - .dev = { - .platform_data = rx51_secure_rng_call, - }, -}; - static void __init nokia_n900_legacy_init(void) { hsmmc2_internal_input_clk(); @@ -292,9 +294,6 @@ pr_warn("RX-51: Not enabling ARM errata 430973 workaround\n"); pr_warn("Thumb binaries may crash randomly without this workaround\n"); } - - pr_info("RX-51: Registering OMAP3 HWRNG device\n"); - platform_device_register(&omap3_rom_rng_device); } } @@ -311,131 +310,18 @@ } /* omap3pandora legacy devices */ -#define PANDORA_WIFI_IRQ_GPIO 21 -#define PANDORA_WIFI_NRESET_GPIO 23 static struct platform_device pandora_backlight = { .name = "pandora-backlight", .id = -1, }; -static struct regulator_consumer_supply pandora_vmmc3_supply[] = { - REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"), -}; - -static struct regulator_init_data pandora_vmmc3 = { - .constraints = { - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .num_consumer_supplies = ARRAY_SIZE(pandora_vmmc3_supply), - .consumer_supplies = pandora_vmmc3_supply, -}; - -static struct fixed_voltage_config pandora_vwlan = { - .supply_name = "vwlan", - .microvolts = 1800000, /* 1.8V */ - .startup_delay = 50000, /* 50ms */ - .init_data = &pandora_vmmc3, -}; - -static struct platform_device pandora_vwlan_device = { - .name = "reg-fixed-voltage", - .id = 1, - .dev = { - .platform_data = &pandora_vwlan, - }, -}; - -static struct gpiod_lookup_table pandora_vwlan_gpiod_table = { - .dev_id = "reg-fixed-voltage.1", - .table = { - /* - * As this is a low GPIO number it should be at the first - * GPIO bank. - */ - GPIO_LOOKUP("gpio-0-31", PANDORA_WIFI_NRESET_GPIO, - NULL, GPIO_ACTIVE_HIGH), - { }, - }, -}; - -static void pandora_wl1251_init_card(struct mmc_card *card) -{ - /* - * We have TI wl1251 attached to MMC3. Pass this information to - * SDIO core because it can't be probed by normal methods. - */ - if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) { - card->quirks |= MMC_QUIRK_NONSTD_SDIO; - card->cccr.wide_bus = 1; - card->cis.vendor = 0x104c; - card->cis.device = 0x9066; - card->cis.blksize = 512; - card->cis.max_dtr = 24000000; - card->ocr = 0x80; - } -} - -static struct omap2_hsmmc_info pandora_mmc3[] = { - { - .mmc = 3, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, - .init_card = pandora_wl1251_init_card, - }, - {} /* Terminator */ -}; - -static void __init pandora_wl1251_init(void) -{ - struct wl1251_platform_data pandora_wl1251_pdata; - int ret; - - memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata)); - - pandora_wl1251_pdata.power_gpio = -1; - - ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq"); - if (ret < 0) - goto fail; - - pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO); - if (pandora_wl1251_pdata.irq < 0) - goto fail_irq; - - pandora_wl1251_pdata.use_eeprom = true; - ret = wl1251_set_platform_data(&pandora_wl1251_pdata); - if (ret < 0) - goto fail_irq; - - return; - -fail_irq: - gpio_free(PANDORA_WIFI_IRQ_GPIO); -fail: - pr_err("wl1251 board initialisation failed\n"); -} - static void __init omap3_pandora_legacy_init(void) { platform_device_register(&pandora_backlight); - gpiod_add_lookup_table(&pandora_vwlan_gpiod_table); - platform_device_register(&pandora_vwlan_device); - omap_hsmmc_init(pandora_mmc3); - omap_hsmmc_late_init(pandora_mmc3); - pandora_wl1251_init(); } #endif /* CONFIG_ARCH_OMAP3 */ -#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) -static struct iommu_platform_data omap4_iommu_pdata = { - .reset_name = "mmu_cache", - .assert_reset = omap_device_assert_hardreset, - .deassert_reset = omap_device_deassert_hardreset, - .device_enable = omap_device_enable, - .device_idle = omap_device_idle, -}; -#endif - #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX) static struct wkup_m3_platform_data wkup_m3_data = { .reset_name = "wkup_m3", @@ -451,6 +337,10 @@ #endif #ifdef CONFIG_SOC_DRA7XX +static struct iommu_platform_data dra7_ipu1_dsp_iommu_pdata = { + .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint, +}; + static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1; static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2; static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3; @@ -472,10 +362,14 @@ static struct clockdomain *ti_sysc_find_one_clockdomain(struct clk *clk) { + struct clk_hw *hw = __clk_get_hw(clk); struct clockdomain *clkdm = NULL; struct clk_hw_omap *hwclk; - hwclk = to_clk_hw_omap(__clk_get_hw(clk)); + hwclk = to_clk_hw_omap(hw); + if (!omap2_clk_is_hw_omap(hw)) + return NULL; + if (hwclk && hwclk->clkdm_name) clkdm = clkdm_lookup(hwclk->clkdm_name); @@ -638,6 +532,7 @@ OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL), OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0", &am35xx_emac_pdata), + OF_DEV_AUXDATA("nokia,n900-rom-rng", 0, NULL, rx51_secure_rng_call), /* McBSP modules with sidetone core */ #if IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) OF_DEV_AUXDATA("ti,omap3-mcbsp", 0x49022000, "49022000.mcbsp", &mcbsp_pdata), @@ -653,10 +548,6 @@ &wkup_m3_data), #endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) - OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu", - &omap4_iommu_pdata), - OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu", - &omap4_iommu_pdata), OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000, "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]), OF_DEV_AUXDATA("ti,omap4-smartreflex-core", 0x4a0dd000, @@ -671,6 +562,12 @@ &dra7_hsmmc_data_mmc2), OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc", &dra7_hsmmc_data_mmc3), + OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x40d01000, "40d01000.mmu", + &dra7_ipu1_dsp_iommu_pdata), + OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu", + &dra7_ipu1_dsp_iommu_pdata), + OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu", + &dra7_ipu1_dsp_iommu_pdata), #endif /* Common auxdata */ OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata), --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/pm34xx.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/pm34xx.c @@ -194,6 +194,7 @@ int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON; u32 sdrc_pwr = 0; + int error; mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { @@ -222,8 +223,11 @@ pwrdm_pre_transition(NULL); /* PER */ - if (per_next_state == PWRDM_POWER_OFF) - cpu_cluster_pm_enter(); + if (per_next_state == PWRDM_POWER_OFF) { + error = cpu_cluster_pm_enter(); + if (error) + return; + } /* CORE */ if (core_next_state < PWRDM_POWER_ON) { --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/powerdomain.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/powerdomain.c @@ -174,7 +174,7 @@ break; case PWRDM_STATE_PREV: prev = pwrdm_read_prev_pwrst(pwrdm); - if (pwrdm->state != prev) + if (prev >= 0 && pwrdm->state != prev) pwrdm->state_counter[prev]++; if (prev == PWRDM_POWER_RET) _update_logic_membank_counters(pwrdm); --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/prm3xxx.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/prm3xxx.c @@ -708,6 +708,7 @@ } irq_num = of_irq_get(np, 0); + of_node_put(np); if (irq_num == -EPROBE_DEFER) return irq_num; --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/sleep34xx.S +++ linux-oracle-5.4.0/arch/arm/mach-omap2/sleep34xx.S @@ -72,7 +72,7 @@ stmfd sp!, {lr} @ save registers on stack /* Setup so that we will disable and enable l2 */ mov r1, #0x1 - adrl r3, l2dis_3630_offset @ may be too distant for plain adr + adr r3, l2dis_3630_offset ldr r2, [r3] @ value for offset str r1, [r2, r3] @ write to l2dis_3630 ldmfd sp!, {pc} @ restore regs and return --- linux-oracle-5.4.0.orig/arch/arm/mach-omap2/timer.c +++ linux-oracle-5.4.0/arch/arm/mach-omap2/timer.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -63,15 +64,28 @@ /* Clockevent code */ -static struct omap_dm_timer clkev; -static struct clock_event_device clockevent_gpt; - /* Clockevent hwmod for am335x and am437x suspend */ static struct omap_hwmod *clockevent_gpt_hwmod; /* Clockesource hwmod for am437x suspend */ static struct omap_hwmod *clocksource_gpt_hwmod; +struct dmtimer_clockevent { + struct clock_event_device dev; + struct omap_dm_timer timer; +}; + +static struct dmtimer_clockevent clockevent; + +static struct omap_dm_timer *to_dmtimer(struct clock_event_device *clockevent) +{ + struct dmtimer_clockevent *clkevt = + container_of(clockevent, struct dmtimer_clockevent, dev); + struct omap_dm_timer *timer = &clkevt->timer; + + return timer; +} + #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER static unsigned long arch_timer_freq; @@ -83,24 +97,21 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = &clockevent_gpt; - - __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW); + struct dmtimer_clockevent *clkevt = dev_id; + struct clock_event_device *evt = &clkevt->dev; + struct omap_dm_timer *timer = &clkevt->timer; + __omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW); evt->event_handler(evt); return IRQ_HANDLED; } -static struct irqaction omap2_gp_timer_irq = { - .name = "gp_timer", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap2_gp_timer_interrupt, -}; - static int omap2_gp_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST, + struct omap_dm_timer *timer = to_dmtimer(evt); + + __omap_dm_timer_load_start(timer, OMAP_TIMER_CTRL_ST, 0xffffffff - cycles, OMAP_TIMER_POSTED); return 0; @@ -108,22 +119,26 @@ static int omap2_gp_timer_shutdown(struct clock_event_device *evt) { - __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate); + struct omap_dm_timer *timer = to_dmtimer(evt); + + __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate); + return 0; } static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) { + struct omap_dm_timer *timer = to_dmtimer(evt); u32 period; - __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate); + __omap_dm_timer_stop(timer, OMAP_TIMER_POSTED, timer->rate); - period = clkev.rate / HZ; + period = timer->rate / HZ; period -= 1; /* Looks like we need to first set the load value separately */ - __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, 0xffffffff - period, + __omap_dm_timer_write(timer, OMAP_TIMER_LOAD_REG, 0xffffffff - period, OMAP_TIMER_POSTED); - __omap_dm_timer_load_start(&clkev, + __omap_dm_timer_load_start(timer, OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, 0xffffffff - period, OMAP_TIMER_POSTED); return 0; @@ -137,26 +152,17 @@ omap_hwmod_idle(clockevent_gpt_hwmod); } -static void omap_clkevt_unidle(struct clock_event_device *unused) +static void omap_clkevt_unidle(struct clock_event_device *evt) { + struct omap_dm_timer *timer = to_dmtimer(evt); + if (!clockevent_gpt_hwmod) return; omap_hwmod_enable(clockevent_gpt_hwmod); - __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); + __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW); } -static struct clock_event_device clockevent_gpt = { - .features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_ONESHOT, - .rating = 300, - .set_next_event = omap2_gp_timer_set_next_event, - .set_state_shutdown = omap2_gp_timer_shutdown, - .set_state_periodic = omap2_gp_timer_set_periodic, - .set_state_oneshot = omap2_gp_timer_shutdown, - .tick_resume = omap2_gp_timer_shutdown, -}; - static const struct of_device_id omap_timer_match[] __initconst = { { .compatible = "ti,omap2420-timer", }, { .compatible = "ti,omap3430-timer", }, @@ -362,47 +368,104 @@ } #endif -static void __init omap2_gp_clockevent_init(int gptimer_id, - const char *fck_source, - const char *property) +static void __init dmtimer_clkevt_init_common(struct dmtimer_clockevent *clkevt, + int gptimer_id, + const char *fck_source, + unsigned int features, + const struct cpumask *cpumask, + const char *property, + int rating, const char *name) { + struct omap_dm_timer *timer = &clkevt->timer; int res; - clkev.id = gptimer_id; - clkev.errata = omap_dm_timer_get_errata(); + timer->id = gptimer_id; + timer->errata = omap_dm_timer_get_errata(); + clkevt->dev.features = features; + clkevt->dev.rating = rating; + clkevt->dev.set_next_event = omap2_gp_timer_set_next_event; + clkevt->dev.set_state_shutdown = omap2_gp_timer_shutdown; + clkevt->dev.set_state_periodic = omap2_gp_timer_set_periodic; + clkevt->dev.set_state_oneshot = omap2_gp_timer_shutdown; + clkevt->dev.tick_resume = omap2_gp_timer_shutdown; /* * For clock-event timers we never read the timer counter and * so we are not impacted by errata i103 and i767. Therefore, * we can safely ignore this errata for clock-event timers. */ - __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); + __omap_dm_timer_override_errata(timer, OMAP_TIMER_ERRATA_I103_I767); - res = omap_dm_timer_init_one(&clkev, fck_source, property, - &clockevent_gpt.name, OMAP_TIMER_POSTED); + res = omap_dm_timer_init_one(timer, fck_source, property, + &clkevt->dev.name, OMAP_TIMER_POSTED); BUG_ON(res); - omap2_gp_timer_irq.dev_id = &clkev; - setup_irq(clkev.irq, &omap2_gp_timer_irq); + clkevt->dev.cpumask = cpumask; + clkevt->dev.irq = omap_dm_timer_get_irq(timer); - __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); + if (request_irq(clkevt->dev.irq, omap2_gp_timer_interrupt, + IRQF_TIMER | IRQF_IRQPOLL, name, clkevt)) + pr_err("Failed to request irq %d (gp_timer)\n", clkevt->dev.irq); - clockevent_gpt.cpumask = cpu_possible_mask; - clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); - clockevents_config_and_register(&clockevent_gpt, clkev.rate, - 3, /* Timer internal resynch latency */ - 0xffffffff); + __omap_dm_timer_int_enable(timer, OMAP_TIMER_INT_OVERFLOW); if (soc_is_am33xx() || soc_is_am43xx()) { - clockevent_gpt.suspend = omap_clkevt_idle; - clockevent_gpt.resume = omap_clkevt_unidle; + clkevt->dev.suspend = omap_clkevt_idle; + clkevt->dev.resume = omap_clkevt_unidle; clockevent_gpt_hwmod = - omap_hwmod_lookup(clockevent_gpt.name); + omap_hwmod_lookup(clkevt->dev.name); } - pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, - clkev.rate); + pr_info("OMAP clockevent source: %s at %lu Hz\n", clkevt->dev.name, + timer->rate); +} + +static DEFINE_PER_CPU(struct dmtimer_clockevent, dmtimer_percpu_timer); + +static int omap_gptimer_starting_cpu(unsigned int cpu) +{ + struct dmtimer_clockevent *clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu); + struct clock_event_device *dev = &clkevt->dev; + struct omap_dm_timer *timer = &clkevt->timer; + + clockevents_config_and_register(dev, timer->rate, 3, ULONG_MAX); + irq_force_affinity(dev->irq, cpumask_of(cpu)); + + return 0; +} + +static int __init dmtimer_percpu_quirk_init(void) +{ + struct dmtimer_clockevent *clkevt; + struct clock_event_device *dev; + struct device_node *arm_timer; + struct omap_dm_timer *timer; + int cpu = 0; + + arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); + if (of_device_is_available(arm_timer)) { + pr_warn_once("ARM architected timer wrap issue i940 detected\n"); + return 0; + } + + for_each_possible_cpu(cpu) { + clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu); + dev = &clkevt->dev; + timer = &clkevt->timer; + + dmtimer_clkevt_init_common(clkevt, 0, "timer_sys_ck", + CLOCK_EVT_FEAT_ONESHOT, + cpumask_of(cpu), + "assigned-clock-parents", + 500, "percpu timer"); + } + + cpuhp_setup_state(CPUHP_AP_OMAP_DM_TIMER_STARTING, + "clockevents/omap/gptimer:starting", + omap_gptimer_starting_cpu, NULL); + + return 0; } /* Clocksource code */ @@ -542,7 +605,15 @@ { omap_clk_init(); omap_dmtimer_init(); - omap2_gp_clockevent_init(clkev_nr, clkev_src, clkev_prop); + dmtimer_clkevt_init_common(&clockevent, clkev_nr, clkev_src, + CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + cpu_possible_mask, clkev_prop, 300, "clockevent"); + clockevents_config_and_register(&clockevent.dev, clockevent.timer.rate, + 3, /* Timer internal resynch latency */ + 0xffffffff); + + if (soc_is_dra7xx()) + dmtimer_percpu_quirk_init(); /* Enable the use of clocksource="gp_timer" kernel parameter */ if (use_gptimer_clksrc || gptimer) @@ -571,7 +642,7 @@ #endif /* CONFIG_ARCH_OMAP3 */ #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_AM33XX) || \ - defined(CONFIG_SOC_AM43XX) + defined(CONFIG_SOC_AM43XX) || defined(CONFIG_SOC_DRA7XX) void __init omap3_gptimer_timer_init(void) { __omap_sync32k_timer_init(2, "timer_sys_ck", NULL, @@ -629,6 +700,7 @@ } rate = clk_get_rate(sys_clk); + clk_put(sys_clk); if (soc_is_dra7xx()) { /* --- linux-oracle-5.4.0.orig/arch/arm/mach-orion5x/board-dt.c +++ linux-oracle-5.4.0/arch/arm/mach-orion5x/board-dt.c @@ -63,6 +63,9 @@ if (of_machine_is_compatible("maxtor,shared-storage-2")) mss2_init(); + if (of_machine_is_compatible("lacie,d2-network")) + d2net_init(); + of_platform_default_populate(NULL, orion5x_auxdata_lookup, NULL); } --- linux-oracle-5.4.0.orig/arch/arm/mach-orion5x/common.h +++ linux-oracle-5.4.0/arch/arm/mach-orion5x/common.h @@ -75,6 +75,12 @@ static inline void mss2_init(void) {} #endif +#ifdef CONFIG_MACH_D2NET_DT +void d2net_init(void); +#else +static inline void d2net_init(void) {} +#endif + /***************************************************************************** * Helpers to access Orion registers ****************************************************************************/ --- linux-oracle-5.4.0.orig/arch/arm/mach-pxa/cm-x300.c +++ linux-oracle-5.4.0/arch/arm/mach-pxa/cm-x300.c @@ -355,13 +355,13 @@ static struct gpiod_lookup_table cm_x300_spi_gpiod_table = { .dev_id = "spi_gpio", .table = { - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_SCL, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_SCL - GPIO_LCD_BASE, "sck", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DIN, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_DIN - GPIO_LCD_BASE, "mosi", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_DOUT, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_DOUT - GPIO_LCD_BASE, "miso", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("gpio-pxa", GPIO_LCD_CS, + GPIO_LOOKUP("pca9555.1", GPIO_LCD_CS - GPIO_LCD_BASE, "cs", GPIO_ACTIVE_HIGH), { }, }, --- linux-oracle-5.4.0.orig/arch/arm/mach-pxa/magician.c +++ linux-oracle-5.4.0/arch/arm/mach-pxa/magician.c @@ -675,7 +675,7 @@ static struct gpiod_lookup_table bq24022_gpiod_table = { .dev_id = "gpio-regulator", .table = { - GPIO_LOOKUP("gpio-pxa", EGPIO_MAGICIAN_BQ24022_ISET2, + GPIO_LOOKUP("htc-egpio-0", EGPIO_MAGICIAN_BQ24022_ISET2 - MAGICIAN_EGPIO_BASE, NULL, GPIO_ACTIVE_HIGH), GPIO_LOOKUP("gpio-pxa", GPIO30_MAGICIAN_BQ24022_nCHARGE_EN, "enable", GPIO_ACTIVE_LOW), --- linux-oracle-5.4.0.orig/arch/arm/mach-pxa/sharpsl_pm.c +++ linux-oracle-5.4.0/arch/arm/mach-pxa/sharpsl_pm.c @@ -220,8 +220,6 @@ { schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); } -EXPORT_SYMBOL(sharpsl_battery_kick); - static void sharpsl_battery_thread(struct work_struct *private_) { --- linux-oracle-5.4.0.orig/arch/arm/mach-pxa/spitz.c +++ linux-oracle-5.4.0/arch/arm/mach-pxa/spitz.c @@ -9,7 +9,6 @@ */ #include -#include /* symbol_get ; symbol_put */ #include #include #include @@ -514,17 +513,6 @@ .gpio_cs = SPITZ_GPIO_ADS7846_CS, }; -static void spitz_bl_kick_battery(void) -{ - void (*kick_batt)(void); - - kick_batt = symbol_get(sharpsl_battery_kick); - if (kick_batt) { - kick_batt(); - symbol_put(sharpsl_battery_kick); - } -} - static struct corgi_lcd_platform_data spitz_lcdcon_info = { .init_mode = CORGI_LCD_MODE_VGA, .max_intensity = 0x2f, @@ -532,7 +520,7 @@ .limit_mask = 0x0b, .gpio_backlight_cont = SPITZ_GPIO_BACKLIGHT_CONT, .gpio_backlight_on = SPITZ_GPIO_BACKLIGHT_ON, - .kick_battery = spitz_bl_kick_battery, + .kick_battery = sharpsl_battery_kick, }; static struct pxa2xx_spi_chip spitz_lcdcon_chip = { --- linux-oracle-5.4.0.orig/arch/arm/mach-pxa/tosa.c +++ linux-oracle-5.4.0/arch/arm/mach-pxa/tosa.c @@ -295,9 +295,9 @@ .table = { GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_nSD_DETECT, "cd", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_SD_WP, + GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_SD_WP - TOSA_SCOOP_GPIO_BASE, "wp", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_PWR_ON, + GPIO_LOOKUP("sharp-scoop.0", TOSA_GPIO_PWR_ON - TOSA_SCOOP_GPIO_BASE, "power", GPIO_ACTIVE_HIGH), { }, }, --- linux-oracle-5.4.0.orig/arch/arm/mach-realview/platsmp-dt.c +++ linux-oracle-5.4.0/arch/arm/mach-realview/platsmp-dt.c @@ -66,6 +66,7 @@ return; } map = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(map)) { pr_err("PLATSMP: No syscon regmap\n"); return; --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-at2440evb.c @@ -143,7 +143,7 @@ .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPG(10) */ - GPIO_LOOKUP("GPG", 10, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 10, "cd", GPIO_ACTIVE_LOW), { }, }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-h1940.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-h1940.c @@ -468,9 +468,9 @@ .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(5) */ - GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 5, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_LOW), { }, }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-jive.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-jive.c @@ -237,11 +237,11 @@ unsigned long set; if (options == NULL || options[0] == '\0') - return 0; + return 1; if (kstrtoul(options, 10, &set)) { printk(KERN_ERR "failed to parse mtdset=%s\n", options); - return 0; + return 1; } switch (set) { @@ -256,7 +256,7 @@ "using default.", set); } - return 0; + return 1; } /* parse the mtdset= option given to the kernel command line */ --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-mini2440.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-mini2440.c @@ -244,9 +244,9 @@ .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPG(8) */ - GPIO_LOOKUP("GPG", 8, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 8, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_HIGH), { }, }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-n30.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-n30.c @@ -359,9 +359,9 @@ .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(1) */ - GPIO_LOOKUP("GPF", 1, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 1, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPG(10) */ - GPIO_LOOKUP("GPG", 10, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOG", 10, "wp", GPIO_ACTIVE_LOW), { }, }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-s3c24xx/mach-rx1950.c +++ linux-oracle-5.4.0/arch/arm/mach-s3c24xx/mach-rx1950.c @@ -567,9 +567,9 @@ .dev_id = "s3c2410-sdi", .table = { /* Card detect S3C2410_GPF(5) */ - GPIO_LOOKUP("GPF", 5, "cd", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOF", 5, "cd", GPIO_ACTIVE_LOW), /* Write protect S3C2410_GPH(8) */ - GPIO_LOOKUP("GPH", 8, "wp", GPIO_ACTIVE_LOW), + GPIO_LOOKUP("GPIOH", 8, "wp", GPIO_ACTIVE_LOW), { }, }, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-s5pv210/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-s5pv210/Kconfig @@ -8,7 +8,6 @@ config ARCH_S5PV210 bool "Samsung S5PV210/S5PC110" depends on ARCH_MULTI_V7 - select ARCH_HAS_HOLES_MEMORYMODEL select ARM_VIC select CLKSRC_SAMSUNG_PWM select COMMON_CLK_SAMSUNG --- linux-oracle-5.4.0.orig/arch/arm/mach-sa1100/assabet.c +++ linux-oracle-5.4.0/arch/arm/mach-sa1100/assabet.c @@ -653,7 +653,7 @@ */ static void __init get_assabet_scr(void) { - unsigned long uninitialized_var(scr), i; + unsigned long scr, i; GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */ --- linux-oracle-5.4.0.orig/arch/arm/mach-sa1100/jornada720_ssp.c +++ linux-oracle-5.4.0/arch/arm/mach-sa1100/jornada720_ssp.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * arch/arm/mac-sa1100/jornada720_ssp.c * * Copyright (C) 2006/2007 Kristoffer Ericson @@ -26,6 +26,7 @@ /** * jornada_ssp_reverse - reverses input byte + * @byte: input byte to reverse * * we need to reverse all data we receive from the mcu due to its physical location * returns : 01110111 -> 11101110 @@ -46,6 +47,7 @@ /** * jornada_ssp_byte - waits for ready ssp bus and sends byte + * @byte: input byte to transmit * * waits for fifo buffer to clear and then transmits, if it doesn't then we will * timeout after rounds. Needs mcu running before its called. @@ -77,6 +79,7 @@ /** * jornada_ssp_inout - decide if input is command or trading byte + * @byte: input byte to send (may be %TXDUMMY) * * returns : (jornada_ssp_byte(byte)) on success * : %-ETIMEDOUT on timeout failure --- linux-oracle-5.4.0.orig/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ linux-oracle-5.4.0/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -125,6 +125,7 @@ list_for_each_entry_safe(pos, tmp, &quirk_list, list) { list_del(&pos->list); + of_node_put(pos->np); kfree(pos); } @@ -154,8 +155,10 @@ return -ENODEV; for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) { - if (!of_device_is_available(np)) + if (!of_device_is_available(np)) { + of_node_put(np); break; + } ret = of_property_read_u32(np, "reg", &addr); if (ret) /* Skip invalid entry and continue */ @@ -164,6 +167,7 @@ quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); if (!quirk) { ret = -ENOMEM; + of_node_put(np); goto err_mem; } @@ -171,11 +175,12 @@ memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg)); quirk->id = id; - quirk->np = np; + quirk->np = of_node_get(np); quirk->i2c_msg.addr = addr; ret = of_irq_parse_one(np, 0, argsa); if (ret) { /* Skip invalid entry and continue */ + of_node_put(np); kfree(quirk); continue; } @@ -222,6 +227,7 @@ err_mem: list_for_each_entry_safe(pos, tmp, &quirk_list, list) { list_del(&pos->list); + of_node_put(pos->np); kfree(pos); } --- linux-oracle-5.4.0.orig/arch/arm/mach-socfpga/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-socfpga/Kconfig @@ -2,6 +2,7 @@ menuconfig ARCH_SOCFPGA bool "Altera SOCFPGA family" depends on ARCH_MULTI_V7 + select ARCH_HAS_RESET_CONTROLLER select ARCH_SUPPORTS_BIG_ENDIAN select ARM_AMBA select ARM_GIC @@ -19,6 +20,7 @@ select PL310_ERRATA_727915 select PL310_ERRATA_753970 if PL310 select PL310_ERRATA_769419 + select RESET_CONTROLLER if ARCH_SOCFPGA config SOCFPGA_SUSPEND --- linux-oracle-5.4.0.orig/arch/arm/mach-socfpga/core.h +++ linux-oracle-5.4.0/arch/arm/mach-socfpga/core.h @@ -33,7 +33,7 @@ u32 socfpga_sdram_self_refresh(u32 sdr_base); extern unsigned int socfpga_sdram_self_refresh_sz; -extern char secondary_trampoline, secondary_trampoline_end; +extern char secondary_trampoline[], secondary_trampoline_end[]; extern unsigned long socfpga_cpu1start_addr; --- linux-oracle-5.4.0.orig/arch/arm/mach-socfpga/platsmp.c +++ linux-oracle-5.4.0/arch/arm/mach-socfpga/platsmp.c @@ -20,14 +20,14 @@ static int socfpga_boot_secondary(unsigned int cpu, struct task_struct *idle) { - int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + int trampoline_size = secondary_trampoline_end - secondary_trampoline; if (socfpga_cpu1start_addr) { /* This will put CPU #1 into reset. */ writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + SOCFPGA_RSTMGR_MODMPURST); - memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); + memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); writel(__pa_symbol(secondary_startup), sys_manager_base_addr + (socfpga_cpu1start_addr & 0x000000ff)); @@ -45,12 +45,12 @@ static int socfpga_a10_boot_secondary(unsigned int cpu, struct task_struct *idle) { - int trampoline_size = &secondary_trampoline_end - &secondary_trampoline; + int trampoline_size = secondary_trampoline_end - secondary_trampoline; if (socfpga_cpu1start_addr) { writel(RSTMGR_MPUMODRST_CPU1, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_MODMPURST); - memcpy(phys_to_virt(0), &secondary_trampoline, trampoline_size); + memcpy(phys_to_virt(0), secondary_trampoline, trampoline_size); writel(__pa_symbol(secondary_startup), sys_manager_base_addr + (socfpga_cpu1start_addr & 0x00000fff)); --- linux-oracle-5.4.0.orig/arch/arm/mach-socfpga/pm.c +++ linux-oracle-5.4.0/arch/arm/mach-socfpga/pm.c @@ -49,14 +49,14 @@ if (!ocram_pool) { pr_warn("%s: ocram pool unavailable!\n", __func__); ret = -ENODEV; - goto put_node; + goto put_device; } ocram_base = gen_pool_alloc(ocram_pool, socfpga_sdram_self_refresh_sz); if (!ocram_base) { pr_warn("%s: unable to alloc ocram!\n", __func__); ret = -ENOMEM; - goto put_node; + goto put_device; } ocram_pbase = gen_pool_virt_to_phys(ocram_pool, ocram_base); @@ -67,7 +67,7 @@ if (!suspend_ocram_base) { pr_warn("%s: __arm_ioremap_exec failed!\n", __func__); ret = -ENOMEM; - goto put_node; + goto put_device; } /* Copy the code that puts DDR in self refresh to ocram */ @@ -81,6 +81,8 @@ if (!socfpga_sdram_self_refresh_in_ocram) ret = -EFAULT; +put_device: + put_device(&pdev->dev); put_node: of_node_put(np); --- linux-oracle-5.4.0.orig/arch/arm/mach-spear/time.c +++ linux-oracle-5.4.0/arch/arm/mach-spear/time.c @@ -93,7 +93,7 @@ 200, 16, clocksource_mmio_readw_up); } -static inline void timer_shutdown(struct clock_event_device *evt) +static inline void spear_timer_shutdown(struct clock_event_device *evt) { u16 val = readw(gpt_base + CR(CLKEVT)); @@ -104,7 +104,7 @@ static int spear_shutdown(struct clock_event_device *evt) { - timer_shutdown(evt); + spear_timer_shutdown(evt); return 0; } @@ -114,7 +114,7 @@ u16 val; /* stop the timer */ - timer_shutdown(evt); + spear_timer_shutdown(evt); val = readw(gpt_base + CR(CLKEVT)); val |= CTRL_ONE_SHOT; @@ -129,7 +129,7 @@ u16 val; /* stop the timer */ - timer_shutdown(evt); + spear_timer_shutdown(evt); period = clk_get_rate(gpt_clk) / HZ; period >>= CTRL_PRESCALER16; --- linux-oracle-5.4.0.orig/arch/arm/mach-sunxi/mc_smp.c +++ linux-oracle-5.4.0/arch/arm/mach-sunxi/mc_smp.c @@ -804,16 +804,16 @@ for (i = 0; i < ARRAY_SIZE(sunxi_mc_smp_data); i++) { ret = of_property_match_string(node, "enable-method", sunxi_mc_smp_data[i].enable_method); - if (!ret) + if (ret >= 0) break; } - is_a83t = sunxi_mc_smp_data[i].is_a83t; - of_node_put(node); - if (ret) + if (ret < 0) return -ENODEV; + is_a83t = sunxi_mc_smp_data[i].is_a83t; + if (!sunxi_mc_smp_cpu_table_init()) return -EINVAL; --- linux-oracle-5.4.0.orig/arch/arm/mach-sunxi/sunxi.c +++ linux-oracle-5.4.0/arch/arm/mach-sunxi/sunxi.c @@ -66,6 +66,7 @@ "allwinner,sun8i-h2-plus", "allwinner,sun8i-h3", "allwinner,sun8i-r40", + "allwinner,sun8i-v3", "allwinner,sun8i-v3s", NULL, }; --- linux-oracle-5.4.0.orig/arch/arm/mach-tango/Kconfig +++ linux-oracle-5.4.0/arch/arm/mach-tango/Kconfig @@ -3,7 +3,6 @@ bool "Sigma Designs Tango4 (SMP87xx)" depends on ARCH_MULTI_V7 # Cortex-A9 MPCore r3p0, PL310 r3p2 - select ARCH_HAS_HOLES_MEMORYMODEL select ARM_ERRATA_754322 select ARM_ERRATA_764369 if SMP select ARM_ERRATA_775420 --- linux-oracle-5.4.0.orig/arch/arm/mach-tegra/reset-handler.S +++ linux-oracle-5.4.0/arch/arm/mach-tegra/reset-handler.S @@ -44,16 +44,16 @@ cmp r6, #TEGRA20 beq 1f @ Yes /* Clear the flow controller flags for this CPU. */ - cpu_to_csr_reg r1, r0 + cpu_to_csr_reg r3, r0 mov32 r2, TEGRA_FLOW_CTRL_BASE - ldr r1, [r2, r1] + ldr r1, [r2, r3] /* Clear event & intr flag */ orr r1, r1, \ #FLOW_CTRL_CSR_INTR_FLAG | FLOW_CTRL_CSR_EVENT_FLAG movw r0, #0x3FFD @ enable, cluster_switch, immed, bitmaps @ & ext flags for CPU power mgnt bic r1, r1, r0 - str r1, [r2] + str r1, [r2, r3] 1: mov32 r9, 0xc09 --- linux-oracle-5.4.0.orig/arch/arm/mach-tegra/sleep-tegra30.S +++ linux-oracle-5.4.0/arch/arm/mach-tegra/sleep-tegra30.S @@ -370,6 +370,14 @@ pll_locked r1, r0, CLK_RESET_PLLC_BASE pll_locked r1, r0, CLK_RESET_PLLX_BASE + tegra_get_soc_id TEGRA_APB_MISC_BASE, r1 + cmp r1, #TEGRA30 + beq 1f + ldr r1, [r0, #CLK_RESET_PLLP_BASE] + bic r1, r1, #(1<<31) @ disable PllP bypass + str r1, [r0, #CLK_RESET_PLLP_BASE] +1: + mov32 r7, TEGRA_TMRUS_BASE ldr r1, [r7] add r1, r1, #LOCK_DELAY @@ -630,7 +638,10 @@ str r0, [r4, #PMC_PLLP_WB0_OVERRIDE] /* disable PLLP, PLLA, PLLC and PLLX */ + tegra_get_soc_id TEGRA_APB_MISC_BASE, r1 + cmp r1, #TEGRA30 ldr r0, [r5, #CLK_RESET_PLLP_BASE] + orrne r0, r0, #(1 << 31) @ enable PllP bypass on fast cluster bic r0, r0, #(1 << 30) str r0, [r5, #CLK_RESET_PLLP_BASE] ldr r0, [r5, #CLK_RESET_PLLA_BASE] --- linux-oracle-5.4.0.orig/arch/arm/mach-tegra/tegra.c +++ linux-oracle-5.4.0/arch/arm/mach-tegra/tegra.c @@ -106,8 +106,8 @@ }; DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)") - .l2c_aux_val = 0x3c400001, - .l2c_aux_mask = 0xc20fc3fe, + .l2c_aux_val = 0x3c400000, + .l2c_aux_mask = 0xc20fc3ff, .smp = smp_ops(tegra_smp_ops), .map_io = tegra_map_common_io, .init_early = tegra_init_early, --- linux-oracle-5.4.0.orig/arch/arm/mach-vexpress/dcscb.c +++ linux-oracle-5.4.0/arch/arm/mach-vexpress/dcscb.c @@ -143,6 +143,7 @@ if (!node) return -ENODEV; dcscb_base = of_iomap(node, 0); + of_node_put(node); if (!dcscb_base) return -EADDRNOTAVAIL; cfg = readl_relaxed(dcscb_base + DCS_CFG_R); --- linux-oracle-5.4.0.orig/arch/arm/mach-vexpress/spc.c +++ linux-oracle-5.4.0/arch/arm/mach-vexpress/spc.c @@ -551,8 +551,9 @@ static int __init ve_spc_clk_init(void) { - int cpu; + int cpu, cluster; struct clk *clk; + bool init_opp_table[MAX_CLUSTERS] = { false }; if (!info) return 0; /* Continue only if SPC is initialised */ @@ -578,8 +579,17 @@ continue; } + cluster = topology_physical_package_id(cpu_dev->id); + if (cluster < 0 || init_opp_table[cluster]) + continue; + if (ve_init_opp_table(cpu_dev)) pr_warn("failed to initialise cpu%d opp table\n", cpu); + else if (dev_pm_opp_set_sharing_cpus(cpu_dev, + topology_core_cpumask(cpu_dev->id))) + pr_warn("failed to mark OPPs shared for cpu%d\n", cpu); + else + init_opp_table[cluster] = true; } platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0); --- linux-oracle-5.4.0.orig/arch/arm/mach-zynq/common.c +++ linux-oracle-5.4.0/arch/arm/mach-zynq/common.c @@ -77,6 +77,7 @@ } zynq_devcfg_base = of_iomap(np, 0); + of_node_put(np); if (!zynq_devcfg_base) { pr_err("%s: Unable to map I/O memory\n", __func__); return -1; --- linux-oracle-5.4.0.orig/arch/arm/mach-zynq/slcr.c +++ linux-oracle-5.4.0/arch/arm/mach-zynq/slcr.c @@ -213,6 +213,7 @@ zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr"); if (IS_ERR(zynq_slcr_regmap)) { pr_err("%s: failed to find zynq-slcr\n", __func__); + of_node_put(np); return -ENODEV; } --- linux-oracle-5.4.0.orig/arch/arm/mm/Kconfig +++ linux-oracle-5.4.0/arch/arm/mm/Kconfig @@ -743,6 +743,7 @@ config CPU_BIG_ENDIAN bool "Build big-endian kernel" depends on ARCH_SUPPORTS_BIG_ENDIAN + depends on !LD_IS_LLD help Say Y if you plan on running a kernel in big-endian mode. Note that your board must be properly built and your board @@ -752,7 +753,7 @@ config CPU_ENDIAN_BE8 bool depends on CPU_BIG_ENDIAN - default CPU_V6 || CPU_V6K || CPU_V7 + default CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M help Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors. @@ -832,6 +833,7 @@ config CPU_SPECTRE bool + select GENERIC_CPU_VULNERABILITIES config HARDEN_BRANCH_PREDICTOR bool "Harden the branch predictor against aliasing attacks" if EXPERT @@ -852,6 +854,16 @@ If unsure, say Y. +config HARDEN_BRANCH_HISTORY + bool "Harden Spectre style attacks against branch history" if EXPERT + depends on CPU_SPECTRE + default y + help + Speculation attacks against some high-performance processors can + make use of branch history to influence future speculation. When + taking an exception, a sequence of branches overwrites the branch + history, or branch history is invalidated. + config TLS_REG_EMUL bool select NEED_KUSER_HELPERS --- linux-oracle-5.4.0.orig/arch/arm/mm/alignment.c +++ linux-oracle-5.4.0/arch/arm/mm/alignment.c @@ -799,7 +799,7 @@ static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - union offset_union uninitialized_var(offset); + union offset_union offset; unsigned long instrptr; int (*handler)(unsigned long addr, u32 instr, struct pt_regs *regs); unsigned int type; @@ -935,6 +935,9 @@ if (type == TYPE_LDST) do_alignment_finish_ldst(addr, instr, regs, offset); + if (thumb_mode(regs)) + regs->ARM_cpsr = it_advance(regs->ARM_cpsr); + return 0; bad_or_fault: --- linux-oracle-5.4.0.orig/arch/arm/mm/cache-l2x0.c +++ linux-oracle-5.4.0/arch/arm/mm/cache-l2x0.c @@ -1249,20 +1249,28 @@ ret = of_property_read_u32(np, "prefetch-data", &val); if (ret == 0) { - if (val) + if (val) { prefetch |= L310_PREFETCH_CTRL_DATA_PREFETCH; - else + *aux_val |= L310_PREFETCH_CTRL_DATA_PREFETCH; + } else { prefetch &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; + *aux_val &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; + } + *aux_mask &= ~L310_PREFETCH_CTRL_DATA_PREFETCH; } else if (ret != -EINVAL) { pr_err("L2C-310 OF prefetch-data property value is missing\n"); } ret = of_property_read_u32(np, "prefetch-instr", &val); if (ret == 0) { - if (val) + if (val) { prefetch |= L310_PREFETCH_CTRL_INSTR_PREFETCH; - else + *aux_val |= L310_PREFETCH_CTRL_INSTR_PREFETCH; + } else { prefetch &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; + *aux_val &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; + } + *aux_mask &= ~L310_PREFETCH_CTRL_INSTR_PREFETCH; } else if (ret != -EINVAL) { pr_err("L2C-310 OF prefetch-instr property value is missing\n"); } --- linux-oracle-5.4.0.orig/arch/arm/mm/dma-mapping-nommu.c +++ linux-oracle-5.4.0/arch/arm/mm/dma-mapping-nommu.c @@ -35,7 +35,7 @@ unsigned long attrs) { - void *ret = dma_alloc_from_global_coherent(size, dma_handle); + void *ret = dma_alloc_from_global_coherent(dev, size, dma_handle); /* * dma_alloc_from_global_coherent() may fail because: --- linux-oracle-5.4.0.orig/arch/arm/mm/dma-mapping.c +++ linux-oracle-5.4.0/arch/arm/mm/dma-mapping.c @@ -221,7 +221,7 @@ static int __dma_supported(struct device *dev, u64 mask, bool warn) { - unsigned long max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); + unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit); /* * Translate the device's DMA mask to a PFN limit. This @@ -2332,15 +2332,15 @@ } #ifdef CONFIG_SWIOTLB -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_page_cpu_to_dev(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), size, dir); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_page_dev_to_cpu(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), size, dir); --- linux-oracle-5.4.0.orig/arch/arm/mm/fault.c +++ linux-oracle-5.4.0/arch/arm/mm/fault.c @@ -124,7 +124,7 @@ show_pte(KERN_ALERT, mm, addr); die("Oops", regs, fsr); bust_spinlocks(0); - do_exit(SIGKILL); + make_task_dead(SIGKILL); } /* --- linux-oracle-5.4.0.orig/arch/arm/mm/flush.c +++ linux-oracle-5.4.0/arch/arm/mm/flush.c @@ -280,6 +280,8 @@ return; page = pfn_to_page(pfn); + if (PageReserved(page)) + return; if (cache_is_vipt_aliasing()) mapping = page_mapping_file(page); else --- linux-oracle-5.4.0.orig/arch/arm/mm/init.c +++ linux-oracle-5.4.0/arch/arm/mm/init.c @@ -91,18 +91,6 @@ */ phys_addr_t arm_dma_limit; unsigned long arm_dma_pfn_limit; - -static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, - unsigned long dma_size) -{ - if (size[0] <= dma_size) - return; - - size[ZONE_NORMAL] = size[0] - dma_size; - size[ZONE_DMA] = dma_size; - hole[ZONE_NORMAL] = hole[0]; - hole[ZONE_DMA] = 0; -} #endif void __init setup_dma_zone(const struct machine_desc *mdesc) @@ -120,67 +108,38 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low, unsigned long max_high) { - unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; - struct memblock_region *reg; - - /* - * initialise the zones. - */ - memset(zone_size, 0, sizeof(zone_size)); + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; - /* - * The memory size has already been determined. If we need - * to do anything fancy with the allocation of this memory - * to the zones, now is the time to do it. - */ - zone_size[0] = max_low - min; -#ifdef CONFIG_HIGHMEM - zone_size[ZONE_HIGHMEM] = max_high - max_low; +#ifdef CONFIG_ZONE_DMA + max_zone_pfn[ZONE_DMA] = min(arm_dma_pfn_limit, max_low); #endif - - /* - * Calculate the size of the holes. - * holes = node_size - sum(bank_sizes) - */ - memcpy(zhole_size, zone_size, sizeof(zhole_size)); - for_each_memblock(memory, reg) { - unsigned long start = memblock_region_memory_base_pfn(reg); - unsigned long end = memblock_region_memory_end_pfn(reg); - - if (start < max_low) { - unsigned long low_end = min(end, max_low); - zhole_size[0] -= low_end - start; - } + max_zone_pfn[ZONE_NORMAL] = max_low; #ifdef CONFIG_HIGHMEM - if (end > max_low) { - unsigned long high_start = max(start, max_low); - zhole_size[ZONE_HIGHMEM] -= end - high_start; - } -#endif - } - -#ifdef CONFIG_ZONE_DMA - /* - * Adjust the sizes according to any special requirements for - * this machine type. - */ - if (arm_dma_zone_size) - arm_adjust_dma_zone(zone_size, zhole_size, - arm_dma_zone_size >> PAGE_SHIFT); + max_zone_pfn[ZONE_HIGHMEM] = max_high; #endif - - free_area_init_node(0, zone_size, min, zhole_size); + free_area_init(max_zone_pfn); } #ifdef CONFIG_HAVE_ARCH_PFN_VALID int pfn_valid(unsigned long pfn) { phys_addr_t addr = __pfn_to_phys(pfn); + unsigned long pageblock_size = PAGE_SIZE * pageblock_nr_pages; if (__phys_to_pfn(addr) != pfn) return 0; - return memblock_is_map_memory(__pfn_to_phys(pfn)); + /* + * If address less than pageblock_size bytes away from a present + * memory chunk there still will be a memory map entry for it + * because we round freed memory map to the pageblock boundaries. + */ + if (memblock_overlaps_region(&memblock.memory, + ALIGN_DOWN(addr, pageblock_size), + pageblock_size)) + return 1; + + return 0; } EXPORT_SYMBOL(pfn_valid); #endif @@ -274,7 +233,6 @@ if (mdesc->reserve) mdesc->reserve(); - early_init_fdt_reserve_self(); early_init_fdt_scan_reserved_mem(); /* reserve memory for DMA contiguous allocations */ @@ -305,7 +263,7 @@ sparse_init(); /* - * Now free the memory - free_area_init_node needs + * Now free the memory - free_area_init needs * the sparse mem_map arrays initialized by sparse_init() * for memmap_init_zone(), otherwise all PFNs are invalid. */ @@ -323,7 +281,7 @@ *p++ = 0xe7fddef0; } -static inline void +static inline void __init free_memmap(unsigned long start_pfn, unsigned long end_pfn) { struct page *start_pg, *end_pg; @@ -372,14 +330,14 @@ */ start = min(start, ALIGN(prev_end, PAGES_PER_SECTION)); -#else +#endif /* - * Align down here since the VM subsystem insists that the - * memmap entries are valid from the bank start aligned to - * MAX_ORDER_NR_PAGES. + * Align down here since many operations in VM subsystem + * presume that there are no holes in the memory map inside + * a pageblock */ - start = round_down(start, MAX_ORDER_NR_PAGES); -#endif + start = round_down(start, pageblock_nr_pages); + /* * If we had a previous bank, and there is a space * between the current bank and the previous, free it. @@ -388,18 +346,20 @@ free_memmap(prev_end, start); /* - * Align up here since the VM subsystem insists that the - * memmap entries are valid from the bank end aligned to - * MAX_ORDER_NR_PAGES. + * Align up here since many operations in VM subsystem + * presume that there are no holes in the memory map inside + * a pageblock */ prev_end = ALIGN(memblock_region_memory_end_pfn(reg), - MAX_ORDER_NR_PAGES); + pageblock_nr_pages); } #ifdef CONFIG_SPARSEMEM - if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) + if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION)) { + prev_end = ALIGN(prev_end, pageblock_nr_pages); free_memmap(prev_end, ALIGN(prev_end, PAGES_PER_SECTION)); + } #endif } @@ -470,7 +430,11 @@ void __init mem_init(void) { #ifdef CONFIG_ARM_LPAE - swiotlb_init(1); + if (swiotlb_force == SWIOTLB_FORCE || + max_pfn > arm_dma_pfn_limit) + swiotlb_init(1); + else + swiotlb_force = SWIOTLB_NO_FORCE; #endif set_max_mapnr(pfn_to_page(max_pfn) - mem_map); --- linux-oracle-5.4.0.orig/arch/arm/mm/ioremap.c +++ linux-oracle-5.4.0/arch/arm/mm/ioremap.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -301,7 +302,8 @@ * Don't allow RAM to be mapped with mismatched attributes - this * causes problems with ARMv6+ */ - if (WARN_ON(pfn_valid(pfn) && mtype != MT_MEMORY_RW)) + if (WARN_ON(memblock_is_map_memory(PFN_PHYS(pfn)) && + mtype != MT_MEMORY_RW)) return NULL; area = get_vm_area_caller(size, VM_IOREMAP, caller); @@ -498,3 +500,11 @@ { early_ioremap_setup(); } + +bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, + unsigned long flags) +{ + unsigned long pfn = PHYS_PFN(offset); + + return memblock_is_map_memory(pfn); +} --- linux-oracle-5.4.0.orig/arch/arm/mm/mmu.c +++ linux-oracle-5.4.0/arch/arm/mm/mmu.c @@ -39,6 +39,8 @@ #include "mm.h" #include "tcm.h" +extern unsigned long __atags_pointer; + /* * empty_zero_page is a special page that is used for * zero-initialized data and COW. @@ -227,12 +229,14 @@ static int __init early_cachepolicy(char *p) { pr_warn("cachepolicy kernel parameter not supported without cp15\n"); + return 0; } early_param("cachepolicy", early_cachepolicy); static int __init noalign_setup(char *__unused) { pr_warn("noalign kernel parameter not supported without cp15\n"); + return 1; } __setup("noalign", noalign_setup); @@ -312,6 +316,17 @@ .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, + [MT_MEMORY_RO] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_XN | L_PTE_RDONLY, + .prot_l1 = PMD_TYPE_TABLE, +#ifdef CONFIG_ARM_LPAE + .prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2, +#else + .prot_sect = PMD_TYPE_SECT, +#endif + .domain = DOMAIN_KERNEL, + }, [MT_ROM] = { .prot_sect = PMD_TYPE_SECT, .domain = DOMAIN_KERNEL, @@ -413,9 +428,9 @@ FIXADDR_END); BUG_ON(idx >= __end_of_fixed_addresses); - /* we only support device mappings until pgprot_kernel has been set */ + /* We support only device mappings before pgprot_kernel is set. */ if (WARN_ON(pgprot_val(prot) != pgprot_val(FIXMAP_PAGE_IO) && - pgprot_val(pgprot_kernel) == 0)) + pgprot_val(prot) && pgprot_val(pgprot_kernel) == 0)) return; if (pgprot_val(prot)) @@ -511,6 +526,7 @@ /* Also setup NX memory mapping */ mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN; + mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_XN; } if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) { /* @@ -593,6 +609,7 @@ mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; #endif /* @@ -613,6 +630,8 @@ mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S; mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED; + mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY_RO].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED; mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S; mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED; @@ -676,6 +695,8 @@ mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot; mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd; mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot; + mem_types[MT_MEMORY_RO].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_MEMORY_RO].prot_pte |= kern_pgprot; mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot; mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask; mem_types[MT_ROM].prot_sect |= cp->pmd; @@ -962,7 +983,7 @@ return; } - if ((md->type == MT_DEVICE || md->type == MT_ROM) && + if (md->type == MT_DEVICE && md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START && (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n", @@ -1352,6 +1373,15 @@ for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); + if (__atags_pointer) { + /* create a read-only mapping of the device tree */ + map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK); + map.virtual = FDT_FIXED_BASE; + map.length = FDT_FIXED_SIZE; + map.type = MT_MEMORY_RO; + create_mapping(&map); + } + /* * Map the kernel if it is XIP. * It is always first in the modulearea. @@ -1512,8 +1542,7 @@ } #ifdef CONFIG_ARM_PV_FIXUP -extern unsigned long __atags_pointer; -typedef void pgtables_remap(long long offset, unsigned long pgd, void *bdata); +typedef void pgtables_remap(long long offset, unsigned long pgd); pgtables_remap lpae_pgtables_remap_asm; /* @@ -1526,7 +1555,6 @@ unsigned long pa_pgd; unsigned int cr, ttbcr; long long offset; - void *boot_data; if (!mdesc->pv_fixup) return; @@ -1543,7 +1571,6 @@ */ lpae_pgtables_remap = (pgtables_remap *)(unsigned long)__pa(lpae_pgtables_remap_asm); pa_pgd = __pa(swapper_pg_dir); - boot_data = __va(__atags_pointer); barrier(); pr_info("Switching physical address space to 0x%08llx\n", @@ -1579,7 +1606,7 @@ * needs to be assembly. It's fairly simple, as we're using the * temporary tables setup by the initial assembly code. */ - lpae_pgtables_remap(offset, pa_pgd, boot_data); + lpae_pgtables_remap(offset, pa_pgd); /* Re-enable the caches and cacheable TLB walks */ asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr)); --- linux-oracle-5.4.0.orig/arch/arm/mm/nommu.c +++ linux-oracle-5.4.0/arch/arm/mm/nommu.c @@ -26,6 +26,13 @@ unsigned long vectors_base; +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; +EXPORT_SYMBOL(empty_zero_page); + #ifdef CONFIG_ARM_MPU struct mpu_rgn_info mpu_rgn_info; #endif @@ -148,9 +155,21 @@ */ void __init paging_init(const struct machine_desc *mdesc) { + void *zero_page; + early_trap_init((void *)vectors_base); mpu_setup(); + + /* allocate the zero page. */ + zero_page = (void *)memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!zero_page) + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", + __func__, PAGE_SIZE, PAGE_SIZE); + bootmem_init(); + + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); } /* --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm1020.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm1020.S @@ -491,7 +491,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm1020_proc_info,#object __arm1020_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm1020e.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm1020e.S @@ -449,7 +449,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm1020e_proc_info,#object __arm1020e_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm1022.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm1022.S @@ -443,7 +443,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm1022_proc_info,#object __arm1022_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm1026.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm1026.S @@ -138,7 +138,7 @@ mov ip, #0 __flush_whole_cache: #ifndef CONFIG_CPU_DCACHE_DISABLE -1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate +1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test, clean, invalidate bne 1b #endif tst r2, #VM_EXEC @@ -363,7 +363,7 @@ #ifdef CONFIG_MMU mov r1, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE -1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate +1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test, clean, invalidate bne 1b #endif #ifndef CONFIG_CPU_ICACHE_DISABLE @@ -437,7 +437,7 @@ string cpu_arm1026_name, "ARM1026EJ-S" .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm1026_proc_info,#object __arm1026_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm720.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm720.S @@ -172,7 +172,7 @@ * See for a definition of this structure. */ - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro arm720_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cpu_flush:req .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm740.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm740.S @@ -128,7 +128,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm740_proc_info,#object __arm740_proc_info: .long 0x41807400 --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm7tdmi.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm7tdmi.S @@ -72,7 +72,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro arm7tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, \ extra_hwcaps=0 --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm920.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm920.S @@ -434,7 +434,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm920_proc_info,#object __arm920_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm922.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm922.S @@ -412,7 +412,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm922_proc_info,#object __arm922_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm925.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm925.S @@ -477,7 +477,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro arm925_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm926.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm926.S @@ -131,7 +131,7 @@ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else -1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate +1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate bne 1b #endif tst r2, #VM_EXEC @@ -358,7 +358,7 @@ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache #else @ && 'Clean & Invalidate whole DCache' -1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate +1: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate bne 1b #endif mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache @@ -460,7 +460,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm926_proc_info,#object __arm926_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm940.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm940.S @@ -340,7 +340,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm940_proc_info,#object __arm940_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm946.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm946.S @@ -395,7 +395,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __arm946_proc_info,#object __arm946_proc_info: .long 0x41009460 --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-arm9tdmi.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-arm9tdmi.S @@ -66,7 +66,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro arm9tdmi_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req .type __\name\()_proc_info, #object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-fa526.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-fa526.S @@ -185,7 +185,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __fa526_proc_info,#object __fa526_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-feroceon.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-feroceon.S @@ -571,7 +571,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro feroceon_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache:req .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-macros.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-macros.S @@ -5,6 +5,7 @@ * VMA_VM_FLAGS * VM_EXEC */ +#include #include #include @@ -30,7 +31,7 @@ * act_mm - get current->active_mm */ .macro act_mm, rd - bic \rd, sp, #8128 + bic \rd, sp, #(THREAD_SIZE - 1) & ~63 bic \rd, \rd, #63 ldr \rd, [\rd, #TI_TASK] .if (TSK_ACTIVE_MM > IMM12_MASK) @@ -341,6 +342,7 @@ .macro define_tlb_functions name:req, flags_up:req, flags_smp .type \name\()_tlb_fns, #object + .align 2 ENTRY(\name\()_tlb_fns) .long \name\()_flush_user_tlb_range .long \name\()_flush_kern_tlb_range --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-mohawk.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-mohawk.S @@ -416,7 +416,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __88sv331x_proc_info,#object __88sv331x_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-sa110.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-sa110.S @@ -196,7 +196,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .type __sa110_proc_info,#object __sa110_proc_info: --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-sa1100.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-sa1100.S @@ -239,7 +239,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro sa1100_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-v6.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-v6.S @@ -261,7 +261,7 @@ string cpu_elf_name, "v6" .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" /* * Match any ARMv6 processor core. --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-v7-bugs.c +++ linux-oracle-5.4.0/arch/arm/mm/proc-v7-bugs.c @@ -7,8 +7,35 @@ #include #include #include +#include #include +#ifdef CONFIG_ARM_PSCI +static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, + ARM_SMCCC_ARCH_WORKAROUND_1, &res); + + switch ((int)res.a0) { + case SMCCC_RET_SUCCESS: + return SPECTRE_MITIGATED; + + case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: + return SPECTRE_UNAFFECTED; + + default: + return SPECTRE_VULNERABLE; + } +} +#else +static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void) +{ + return SPECTRE_VULNERABLE; +} +#endif + #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn); @@ -37,13 +64,60 @@ arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL); } -static void cpu_v7_spectre_init(void) +static unsigned int spectre_v2_install_workaround(unsigned int method) { const char *spectre_v2_method = NULL; int cpu = smp_processor_id(); if (per_cpu(harden_branch_predictor_fn, cpu)) - return; + return SPECTRE_MITIGATED; + + switch (method) { + case SPECTRE_V2_METHOD_BPIALL: + per_cpu(harden_branch_predictor_fn, cpu) = + harden_branch_predictor_bpiall; + spectre_v2_method = "BPIALL"; + break; + + case SPECTRE_V2_METHOD_ICIALLU: + per_cpu(harden_branch_predictor_fn, cpu) = + harden_branch_predictor_iciallu; + spectre_v2_method = "ICIALLU"; + break; + + case SPECTRE_V2_METHOD_HVC: + per_cpu(harden_branch_predictor_fn, cpu) = + call_hvc_arch_workaround_1; + cpu_do_switch_mm = cpu_v7_hvc_switch_mm; + spectre_v2_method = "hypervisor"; + break; + + case SPECTRE_V2_METHOD_SMC: + per_cpu(harden_branch_predictor_fn, cpu) = + call_smc_arch_workaround_1; + cpu_do_switch_mm = cpu_v7_smc_switch_mm; + spectre_v2_method = "firmware"; + break; + } + + if (spectre_v2_method) + pr_info("CPU%u: Spectre v2: using %s workaround\n", + smp_processor_id(), spectre_v2_method); + + return SPECTRE_MITIGATED; +} +#else +static unsigned int spectre_v2_install_workaround(unsigned int method) +{ + pr_info_once("Spectre V2: workarounds disabled by configuration\n"); + + return SPECTRE_VULNERABLE; +} +#endif + +static void cpu_v7_spectre_v2_init(void) +{ + unsigned int state, method = 0; switch (read_cpuid_part()) { case ARM_CPU_PART_CORTEX_A8: @@ -52,29 +126,37 @@ case ARM_CPU_PART_CORTEX_A17: case ARM_CPU_PART_CORTEX_A73: case ARM_CPU_PART_CORTEX_A75: - per_cpu(harden_branch_predictor_fn, cpu) = - harden_branch_predictor_bpiall; - spectre_v2_method = "BPIALL"; + state = SPECTRE_MITIGATED; + method = SPECTRE_V2_METHOD_BPIALL; break; case ARM_CPU_PART_CORTEX_A15: case ARM_CPU_PART_BRAHMA_B15: - per_cpu(harden_branch_predictor_fn, cpu) = - harden_branch_predictor_iciallu; - spectre_v2_method = "ICIALLU"; + state = SPECTRE_MITIGATED; + method = SPECTRE_V2_METHOD_ICIALLU; + break; + + case ARM_CPU_PART_BRAHMA_B53: + /* Requires no workaround */ + state = SPECTRE_UNAFFECTED; break; -#ifdef CONFIG_ARM_PSCI default: /* Other ARM CPUs require no workaround */ - if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) + if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) { + state = SPECTRE_UNAFFECTED; break; + } /* fallthrough */ - /* Cortex A57/A72 require firmware workaround */ + /* Cortex A57/A72 require firmware workaround */ case ARM_CPU_PART_CORTEX_A57: case ARM_CPU_PART_CORTEX_A72: { struct arm_smccc_res res; + state = spectre_v2_get_cpu_fw_mitigation_state(); + if (state != SPECTRE_MITIGATED) + break; + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) break; @@ -84,10 +166,7 @@ ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 != 0) break; - per_cpu(harden_branch_predictor_fn, cpu) = - call_hvc_arch_workaround_1; - cpu_do_switch_mm = cpu_v7_hvc_switch_mm; - spectre_v2_method = "hypervisor"; + method = SPECTRE_V2_METHOD_HVC; break; case PSCI_CONDUIT_SMC: @@ -95,29 +174,97 @@ ARM_SMCCC_ARCH_WORKAROUND_1, &res); if ((int)res.a0 != 0) break; - per_cpu(harden_branch_predictor_fn, cpu) = - call_smc_arch_workaround_1; - cpu_do_switch_mm = cpu_v7_smc_switch_mm; - spectre_v2_method = "firmware"; + method = SPECTRE_V2_METHOD_SMC; break; default: + state = SPECTRE_VULNERABLE; break; } } -#endif } - if (spectre_v2_method) - pr_info("CPU%u: Spectre v2: using %s workaround\n", - smp_processor_id(), spectre_v2_method); + if (state == SPECTRE_MITIGATED) + state = spectre_v2_install_workaround(method); + + spectre_v2_update_state(state, method); +} + +#ifdef CONFIG_HARDEN_BRANCH_HISTORY +static int spectre_bhb_method; + +static const char *spectre_bhb_method_name(int method) +{ + switch (method) { + case SPECTRE_V2_METHOD_LOOP8: + return "loop"; + + case SPECTRE_V2_METHOD_BPIALL: + return "BPIALL"; + + default: + return "unknown"; + } +} + +static int spectre_bhb_install_workaround(int method) +{ + if (spectre_bhb_method != method) { + if (spectre_bhb_method) { + pr_err("CPU%u: Spectre BHB: method disagreement, system vulnerable\n", + smp_processor_id()); + + return SPECTRE_VULNERABLE; + } + + if (spectre_bhb_update_vectors(method) == SPECTRE_VULNERABLE) + return SPECTRE_VULNERABLE; + + spectre_bhb_method = method; + + pr_info("CPU%u: Spectre BHB: enabling %s workaround for all CPUs\n", + smp_processor_id(), spectre_bhb_method_name(method)); + } + + return SPECTRE_MITIGATED; } #else -static void cpu_v7_spectre_init(void) +static int spectre_bhb_install_workaround(int method) { + return SPECTRE_VULNERABLE; } #endif +static void cpu_v7_spectre_bhb_init(void) +{ + unsigned int state, method = 0; + + switch (read_cpuid_part()) { + case ARM_CPU_PART_CORTEX_A15: + case ARM_CPU_PART_BRAHMA_B15: + case ARM_CPU_PART_CORTEX_A57: + case ARM_CPU_PART_CORTEX_A72: + state = SPECTRE_MITIGATED; + method = SPECTRE_V2_METHOD_LOOP8; + break; + + case ARM_CPU_PART_CORTEX_A73: + case ARM_CPU_PART_CORTEX_A75: + state = SPECTRE_MITIGATED; + method = SPECTRE_V2_METHOD_BPIALL; + break; + + default: + state = SPECTRE_UNAFFECTED; + break; + } + + if (state == SPECTRE_MITIGATED) + state = spectre_bhb_install_workaround(method); + + spectre_v2_update_state(state, method); +} + static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned, u32 mask, const char *msg) { @@ -146,16 +293,18 @@ void cpu_v7_ca8_ibe(void) { if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6))) - cpu_v7_spectre_init(); + cpu_v7_spectre_v2_init(); } void cpu_v7_ca15_ibe(void) { if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0))) - cpu_v7_spectre_init(); + cpu_v7_spectre_v2_init(); + cpu_v7_spectre_bhb_init(); } void cpu_v7_bugs_init(void) { - cpu_v7_spectre_init(); + cpu_v7_spectre_v2_init(); + cpu_v7_spectre_bhb_init(); } --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-v7.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-v7.S @@ -644,7 +644,7 @@ string cpu_elf_name, "v7" .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" /* * Standard v7 proc info content --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-v7m.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-v7m.S @@ -93,7 +93,7 @@ ret lr ENDPROC(cpu_cm7_proc_fin) - .section ".init.text", #alloc, #execinstr + .section ".init.text", "ax" __v7m_cm7_setup: mov r8, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP) @@ -177,7 +177,7 @@ string cpu_elf_name "v7m" string cpu_v7m_name "ARMv7-M" - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro __v7m_proc name, initfunc, cache_fns = nop_cache_fns, hwcaps = 0, proc_fns = v7m_processor_functions .long 0 /* proc_info_list.__cpu_mm_mmu_flags */ --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-xsc3.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-xsc3.S @@ -496,7 +496,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro xsc3_proc_info name:req, cpu_val:req, cpu_mask:req .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/proc-xscale.S +++ linux-oracle-5.4.0/arch/arm/mm/proc-xscale.S @@ -610,7 +610,7 @@ .align - .section ".proc.info.init", #alloc + .section ".proc.info.init", "a" .macro xscale_proc_info name:req, cpu_val:req, cpu_mask:req, cpu_name:req, cache .type __\name\()_proc_info,#object --- linux-oracle-5.4.0.orig/arch/arm/mm/pv-fixup-asm.S +++ linux-oracle-5.4.0/arch/arm/mm/pv-fixup-asm.S @@ -39,8 +39,8 @@ /* Update level 2 entries for the boot data */ add r7, r2, #0x1000 - add r7, r7, r3, lsr #SECTION_SHIFT - L2_ORDER - bic r7, r7, #(1 << L2_ORDER) - 1 + movw r3, #FDT_FIXED_BASE >> (SECTION_SHIFT - L2_ORDER) + add r7, r7, r3 ldrd r4, r5, [r7] adds r4, r4, r0 adc r5, r5, r1 --- linux-oracle-5.4.0.orig/arch/arm/net/bpf_jit_32.c +++ linux-oracle-5.4.0/arch/arm/net/bpf_jit_32.c @@ -36,6 +36,10 @@ * +-----+ * |RSVD | JIT scratchpad * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) + * | ... | caller-saved registers + * +-----+ + * | ... | arguments passed on stack + * ARM_SP during call => +-----| * | | * | ... | Function call stack * | | @@ -63,6 +67,12 @@ * * When popping registers off the stack at the end of a BPF function, we * reference them via the current ARM_FP register. + * + * Some eBPF operations are implemented via a call to a helper function. + * Such calls are "invisible" in the eBPF code, so it is up to the calling + * program to preserve any caller-saved ARM registers during the call. The + * JIT emits code to push and pop those registers onto the stack, immediately + * above the callee stack frame. */ #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ @@ -70,6 +80,8 @@ #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) +#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3) + enum { /* Stack layout - these are offsets from (top of stack - 4) */ BPF_R2_HI, @@ -464,6 +476,7 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) { + const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1); const s8 *tmp = bpf2a32[TMP_REG_1]; #if __LINUX_ARM_ARCH__ == 7 @@ -495,11 +508,17 @@ emit(ARM_MOV_R(ARM_R0, rm), ctx); } + /* Push caller-saved registers on stack */ + emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx); + /* Call appropriate function */ emit_mov_i(ARM_IP, op == BPF_DIV ? (u32)jit_udiv32 : (u32)jit_mod32, ctx); emit_blx_r(ARM_IP, ctx); + /* Restore caller-saved registers from stack */ + emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx); + /* Save return value */ if (rd != ARM_R0) emit(ARM_MOV_R(rd, ARM_R0), ctx); @@ -929,7 +948,11 @@ rd = arm_bpf_get_reg64(dst, tmp, ctx); /* Do LSR operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for LSR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_LSR, val), ctx); @@ -955,7 +978,11 @@ rd = arm_bpf_get_reg64(dst, tmp, ctx); /* Do ARSH operation */ - if (val < 32) { + if (val == 0) { + /* An immediate value of 0 encodes a shift amount of 32 + * for ASR. To shift by 0, don't do anything. + */ + } else if (val < 32) { emit(ARM_MOV_SI(tmp2[1], rd[1], SRTYPE_LSR, val), ctx); emit(ARM_ORR_SI(rd[1], tmp2[1], rd[0], SRTYPE_ASL, 32 - val), ctx); emit(ARM_MOV_SI(rd[0], rd[0], SRTYPE_ASR, val), ctx); @@ -992,21 +1019,35 @@ arm_bpf_put_reg32(dst_hi, rd[0], ctx); } +static bool is_ldst_imm(s16 off, const u8 size) +{ + s16 off_max = 0; + + switch (size) { + case BPF_B: + case BPF_W: + off_max = 0xfff; + break; + case BPF_H: + off_max = 0xff; + break; + case BPF_DW: + /* Need to make sure off+4 does not overflow. */ + off_max = 0xfff - 4; + break; + } + return -off_max <= off && off <= off_max; +} + /* *(size *)(dst + off) = src */ static inline void emit_str_r(const s8 dst, const s8 src[], - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; - s32 off_max; s8 rd; rd = arm_bpf_get_reg32(dst, tmp[1], ctx); - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], rd), ctx); rd = tmp[0]; @@ -1035,18 +1076,12 @@ /* dst = *(size*)(src + off) */ static inline void emit_ldx_r(const s8 dst[], const s8 src, - s32 off, struct jit_ctx *ctx, const u8 sz){ + s16 off, struct jit_ctx *ctx, const u8 sz){ const s8 *tmp = bpf2a32[TMP_REG_1]; const s8 *rd = is_stacked(dst_lo) ? tmp : dst; s8 rm = src; - s32 off_max; - - if (sz == BPF_H) - off_max = 0xff; - else - off_max = 0xfff; - if (off < 0 || off > off_max) { + if (!is_ldst_imm(off, sz)) { emit_a32_mov_i(tmp[0], off, ctx); emit(ARM_ADD_R(tmp[0], tmp[0], src), ctx); rm = tmp[0]; @@ -1586,6 +1621,9 @@ rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: --- linux-oracle-5.4.0.orig/arch/arm/nwfpe/Makefile +++ linux-oracle-5.4.0/arch/arm/nwfpe/Makefile @@ -11,3 +11,9 @@ entry.o nwfpe-$(CONFIG_FPE_NWFPE_XP) += extended_cpdo.o + +# Try really hard to avoid generating calls to __aeabi_uldivmod() from +# float64_rem() due to loop elision. +ifdef CONFIG_CC_IS_CLANG +CFLAGS_softfloat.o += -mllvm -replexitval=never +endif --- linux-oracle-5.4.0.orig/arch/arm/plat-samsung/Kconfig +++ linux-oracle-5.4.0/arch/arm/plat-samsung/Kconfig @@ -241,6 +241,7 @@ depends on PM && DEBUG_KERNEL depends on PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210 depends on DEBUG_EXYNOS_UART || DEBUG_S3C24XX_UART || DEBUG_S3C2410_UART + depends on DEBUG_LL && MMU help Say Y here if you want verbose debugging from the PM Suspend and Resume code. See --- linux-oracle-5.4.0.orig/arch/arm/probes/decode.h +++ linux-oracle-5.4.0/arch/arm/probes/decode.h @@ -14,6 +14,7 @@ #include #include #include +#include #include void __init arm_probes_decode_init(void); @@ -35,31 +36,6 @@ #endif -/* - * Update ITSTATE after normal execution of an IT block instruction. - * - * The 8 IT state bits are split into two parts in CPSR: - * ITSTATE<1:0> are in CPSR<26:25> - * ITSTATE<7:2> are in CPSR<15:10> - */ -static inline unsigned long it_advance(unsigned long cpsr) - { - if ((cpsr & 0x06000400) == 0) { - /* ITSTATE<2:0> == 0 means end of IT block, so clear IT state */ - cpsr &= ~PSR_IT_MASK; - } else { - /* We need to shift left ITSTATE<4:0> */ - const unsigned long mask = 0x06001c00; /* Mask ITSTATE<4:0> */ - unsigned long it = cpsr & mask; - it <<= 1; - it |= it >> (27 - 10); /* Carry ITSTATE<2> to correct place */ - it &= mask; - cpsr &= ~mask; - cpsr |= it; - } - return cpsr; -} - static inline void __kprobes bx_write_pc(long pcv, struct pt_regs *regs) { long cpsr = regs->ARM_cpsr; --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/checkers-common.c +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/checkers-common.c @@ -40,7 +40,7 @@ * Different from other insn uses imm8, the real addressing offset of * STRD in T32 encoding should be imm8 * 4. See ARMARM description. */ -enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, +static enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn, struct arch_probes_insn *asi, const struct decode_header *h) { --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/core.c +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/core.c @@ -231,7 +231,7 @@ * kprobe, and that level is reserved for user kprobe handlers, so we can't * risk encountering a new kprobe in an interrupt handler. */ -void __kprobes kprobe_handler(struct pt_regs *regs) +static void __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p, *cur; struct kprobe_ctlblk *kcb; @@ -534,7 +534,7 @@ #endif /* !CONFIG_THUMB2_KERNEL */ -int __init arch_init_kprobes() +int __init arch_init_kprobes(void) { arm_probes_decode_init(); #ifdef CONFIG_THUMB2_KERNEL --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/opt-arm.c +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/opt-arm.c @@ -85,21 +85,21 @@ "optprobe_template_end:\n"); #define TMPL_VAL_IDX \ - ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_val - (unsigned long *)optprobe_template_entry) #define TMPL_CALL_IDX \ - ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_call - (unsigned long *)optprobe_template_entry) #define TMPL_END_IDX \ - ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_end - (unsigned long *)optprobe_template_entry) #define TMPL_ADD_SP \ - ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_add_sp - (unsigned long *)optprobe_template_entry) #define TMPL_SUB_SP \ - ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_sub_sp - (unsigned long *)optprobe_template_entry) #define TMPL_RESTORE_BEGIN \ - ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_restore_begin - (unsigned long *)optprobe_template_entry) #define TMPL_RESTORE_ORIGN_INSN \ - ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_restore_orig_insn - (unsigned long *)optprobe_template_entry) #define TMPL_RESTORE_END \ - ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry) + ((unsigned long *)optprobe_template_restore_end - (unsigned long *)optprobe_template_entry) /* * ARM can always optimize an instruction when using ARM ISA, except @@ -145,8 +145,6 @@ } } -extern void kprobe_handler(struct pt_regs *regs); - static void optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) { @@ -234,7 +232,7 @@ } /* Copy arch-dep-instance from template. */ - memcpy(code, (unsigned long *)&optprobe_template_entry, + memcpy(code, (unsigned long *)optprobe_template_entry, TMPL_END_IDX * sizeof(kprobe_opcode_t)); /* Adjust buffer according to instruction. */ --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/test-core.c +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/test-core.c @@ -720,7 +720,7 @@ [REG_TYPE_NOSPPCX] = COVERAGE_ANY_REG | COVERAGE_SP, }; -unsigned coverage_start_registers(const struct decode_header *h) +static unsigned coverage_start_registers(const struct decode_header *h) { unsigned regs = 0; int i; --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/test-core.h +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/test-core.h @@ -453,3 +453,7 @@ #else void kprobe_arm_test_cases(void); #endif + +void __kprobes_test_case_start(void); +void __kprobes_test_case_end_16(void); +void __kprobes_test_case_end_32(void); --- linux-oracle-5.4.0.orig/arch/arm/probes/kprobes/test-thumb.c +++ linux-oracle-5.4.0/arch/arm/probes/kprobes/test-thumb.c @@ -441,21 +441,21 @@ "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,"]", + TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,"]", + TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RRX("tbh [r",1,9f, ", r",14,1,"]", + TEST_RRX("tbh [r",1,9f, ", r",14,1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" @@ -468,10 +468,10 @@ TEST_UNSUPPORTED("strexb r0, r1, [r2]") TEST_UNSUPPORTED("strexh r0, r1, [r2]") - TEST_UNSUPPORTED("strexd r0, r1, [r2]") + TEST_UNSUPPORTED("strexd r0, r1, r2, [r2]") TEST_UNSUPPORTED("ldrexb r0, [r1]") TEST_UNSUPPORTED("ldrexh r0, [r1]") - TEST_UNSUPPORTED("ldrexd r0, [r1]") + TEST_UNSUPPORTED("ldrexd r0, r1, [r1]") TEST_GROUP("Data-processing (shifted register) and (modified immediate)") --- linux-oracle-5.4.0.orig/arch/arm/probes/uprobes/core.c +++ linux-oracle-5.4.0/arch/arm/probes/uprobes/core.c @@ -204,7 +204,7 @@ static struct undef_hook uprobes_arm_break_hook = { .instr_mask = 0x0fffffff, .instr_val = (UPROBE_SWBP_ARM_INSN & 0x0fffffff), - .cpsr_mask = MODE_MASK, + .cpsr_mask = (PSR_T_BIT | MODE_MASK), .cpsr_val = USR_MODE, .fn = uprobe_trap_handler, }; @@ -212,7 +212,7 @@ static struct undef_hook uprobes_arm_ss_hook = { .instr_mask = 0x0fffffff, .instr_val = (UPROBE_SS_ARM_INSN & 0x0fffffff), - .cpsr_mask = MODE_MASK, + .cpsr_mask = (PSR_T_BIT | MODE_MASK), .cpsr_val = USR_MODE, .fn = uprobe_trap_handler, }; --- linux-oracle-5.4.0.orig/arch/arm/vfp/Makefile +++ linux-oracle-5.4.0/arch/arm/vfp/Makefile @@ -8,6 +8,4 @@ # ccflags-y := -DDEBUG # asflags-y := -DDEBUG -KBUILD_AFLAGS :=$(KBUILD_AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp -mfloat-abi=soft) - obj-y += vfpmodule.o entry.o vfphw.o vfpsingle.o vfpdouble.o --- linux-oracle-5.4.0.orig/arch/arm/vfp/entry.S +++ linux-oracle-5.4.0/arch/arm/vfp/entry.S @@ -37,20 +37,3 @@ .align 2 .LCvfp: .word vfp_vector - -@ This code is called if the VFP does not exist. It needs to flag the -@ failure to the VFP initialisation code. - - __INIT -ENTRY(vfp_testing_entry) - dec_preempt_count_ti r10, r4 - ldr r0, VFP_arch_address - str r0, [r0] @ set to non-zero value - ret r9 @ we have handled the fault -ENDPROC(vfp_testing_entry) - - .align 2 -VFP_arch_address: - .word VFP_arch - - __FINIT --- linux-oracle-5.4.0.orig/arch/arm/vfp/vfphw.S +++ linux-oracle-5.4.0/arch/arm/vfp/vfphw.S @@ -78,11 +78,6 @@ ENTRY(vfp_support_entry) DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10 - ldr r3, [sp, #S_PSR] @ Neither lazy restore nor FP exceptions - and r3, r3, #MODE_MASK @ are supported in kernel mode - teq r3, #USR_MODE - bne vfp_kmode_exception @ Returns through lr - VFPFMRX r1, FPEXC @ Is the VFP enabled? DBGSTR1 "fpexc %08x", r1 tst r1, #FPEXC_EN @@ -258,11 +253,14 @@ ENTRY(vfp_get_float) tbl_branch r0, r3, #3 + .fpu vfpv2 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mrc p10, 0, r0, c\dr, c0, 0 @ fmrs r0, s0 +1: vmov r0, s\dr ret lr .org 1b + 8 -1: mrc p10, 0, r0, c\dr, c0, 4 @ fmrs r0, s1 + .endr + .irp dr,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +1: vmov r0, s\dr ret lr .org 1b + 8 .endr @@ -270,11 +268,14 @@ ENTRY(vfp_put_float) tbl_branch r1, r3, #3 + .fpu vfpv2 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mcr p10, 0, r0, c\dr, c0, 0 @ fmsr r0, s0 +1: vmov s\dr, r0 ret lr .org 1b + 8 -1: mcr p10, 0, r0, c\dr, c0, 4 @ fmsr r0, s1 + .endr + .irp dr,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +1: vmov s\dr, r0 ret lr .org 1b + 8 .endr @@ -282,15 +283,17 @@ ENTRY(vfp_get_double) tbl_branch r0, r3, #3 + .fpu vfpv2 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: fmrrd r0, r1, d\dr +1: vmov r0, r1, d\dr ret lr .org 1b + 8 .endr #ifdef CONFIG_VFPv3 @ d16 - d31 registers - .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mrrc p11, 3, r0, r1, c\dr @ fmrrd r0, r1, d\dr + .fpu vfpv3 + .irp dr,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +1: vmov r0, r1, d\dr ret lr .org 1b + 8 .endr @@ -304,15 +307,17 @@ ENTRY(vfp_put_double) tbl_branch r2, r3, #3 + .fpu vfpv2 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: fmdrr d\dr, r0, r1 +1: vmov d\dr, r0, r1 ret lr .org 1b + 8 .endr #ifdef CONFIG_VFPv3 + .fpu vfpv3 @ d16 - d31 registers - .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 -1: mcrr p11, 3, r0, r1, c\dr @ fmdrr r0, r1, d\dr + .irp dr,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 +1: vmov d\dr, r0, r1 ret lr .org 1b + 8 .endr --- linux-oracle-5.4.0.orig/arch/arm/vfp/vfpmodule.c +++ linux-oracle-5.4.0/arch/arm/vfp/vfpmodule.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "vfpinstr.h" @@ -31,7 +32,6 @@ /* * Our undef handlers (in entry.S) */ -asmlinkage void vfp_testing_entry(void); asmlinkage void vfp_support_entry(void); asmlinkage void vfp_null_entry(void); @@ -42,7 +42,7 @@ * Used in startup: set to non-zero if VFP checks fail * After startup, holds VFP architecture */ -unsigned int VFP_arch; +static unsigned int __initdata VFP_arch; /* * The pointer to the vfpstate structure of the thread which currently @@ -436,7 +436,7 @@ * present on all CPUs within a SMP complex. Needs to be called prior to * vfp_init(). */ -void vfp_disable(void) +void __init vfp_disable(void) { if (VFP_arch) { pr_debug("%s: should be called prior to vfp_init\n", __func__); @@ -642,7 +642,9 @@ return 0; } -void vfp_kmode_exception(void) +#ifdef CONFIG_KERNEL_MODE_NEON + +static int vfp_kmode_exception(struct pt_regs *regs, unsigned int instr) { /* * If we reach this point, a floating point exception has been raised @@ -660,9 +662,51 @@ pr_crit("BUG: unsupported FP instruction in kernel mode\n"); else pr_crit("BUG: FP instruction issued in kernel mode with FP unit disabled\n"); + pr_crit("FPEXC == 0x%08x\n", fmrx(FPEXC)); + return 1; } -#ifdef CONFIG_KERNEL_MODE_NEON +static struct undef_hook vfp_kmode_exception_hook[] = {{ + .instr_mask = 0xfe000000, + .instr_val = 0xf2000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xff100000, + .instr_val = 0xf4000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xef000000, + .instr_val = 0xef000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE | PSR_T_BIT, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0xff100000, + .instr_val = 0xf9000000, + .cpsr_mask = MODE_MASK | PSR_T_BIT, + .cpsr_val = SVC_MODE | PSR_T_BIT, + .fn = vfp_kmode_exception, +}, { + .instr_mask = 0x0c000e00, + .instr_val = 0x0c000a00, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = vfp_kmode_exception, +}}; + +static int __init vfp_kmode_exception_hook_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(vfp_kmode_exception_hook); i++) + register_undef_hook(&vfp_kmode_exception_hook[i]); + return 0; +} +subsys_initcall(vfp_kmode_exception_hook_init); /* * Kernel-side NEON support functions @@ -708,6 +752,21 @@ #endif /* CONFIG_KERNEL_MODE_NEON */ +static int __init vfp_detect(struct pt_regs *regs, unsigned int instr) +{ + VFP_arch = UINT_MAX; /* mark as not present */ + regs->ARM_pc += 4; + return 0; +} + +static struct undef_hook vfp_detect_hook __initdata = { + .instr_mask = 0x0c000e00, + .instr_val = 0x0c000a00, + .cpsr_mask = MODE_MASK, + .cpsr_val = SVC_MODE, + .fn = vfp_detect, +}; + /* * VFP support code initialisation. */ @@ -728,10 +787,11 @@ * The handler is already setup to just log calls, so * we just need to read the VFPSID register. */ - vfp_vector = vfp_testing_entry; + register_undef_hook(&vfp_detect_hook); barrier(); vfpsid = fmrx(FPSID); barrier(); + unregister_undef_hook(&vfp_detect_hook); vfp_vector = vfp_null_entry; pr_info("VFP support v0.3: "); --- linux-oracle-5.4.0.orig/arch/arm/xen/enlighten.c +++ linux-oracle-5.4.0/arch/arm/xen/enlighten.c @@ -354,7 +354,8 @@ * for secondary CPUs as they are brought up. * For uniformity we use VCPUOP_register_vcpu_info even on cpu0. */ - xen_vcpu_info = alloc_percpu(struct vcpu_info); + xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info), + 1 << fls(sizeof(struct vcpu_info) - 1)); if (xen_vcpu_info == NULL) return -ENOMEM; @@ -370,8 +371,6 @@ return -ENOMEM; } gnttab_init(); - if (!xen_initial_domain()) - xenbus_probe(NULL); /* * Making sure board specific code will not set up ops for --- linux-oracle-5.4.0.orig/arch/arm/xen/mm.c +++ linux-oracle-5.4.0/arch/arm/xen/mm.c @@ -70,20 +70,20 @@ * pfn_valid returns true the pages is local and we can use the native * dma-direct functions, otherwise we call the Xen specific version. */ -void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle, - phys_addr_t paddr, size_t size, enum dma_data_direction dir) +void xen_dma_sync_for_cpu(dma_addr_t handle, phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { if (pfn_valid(PFN_DOWN(handle))) - arch_sync_dma_for_cpu(dev, paddr, size, dir); + arch_sync_dma_for_cpu(paddr, size, dir); else if (dir != DMA_TO_DEVICE) dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); } -void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle, - phys_addr_t paddr, size_t size, enum dma_data_direction dir) +void xen_dma_sync_for_device(dma_addr_t handle, phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { if (pfn_valid(PFN_DOWN(handle))) - arch_sync_dma_for_device(dev, paddr, size, dir); + arch_sync_dma_for_device(paddr, size, dir); else if (dir == DMA_FROM_DEVICE) dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL); else --- linux-oracle-5.4.0.orig/arch/arm/xen/p2m.c +++ linux-oracle-5.4.0/arch/arm/xen/p2m.c @@ -62,11 +62,12 @@ unsigned long __pfn_to_mfn(unsigned long pfn) { - struct rb_node *n = phys_to_mach.rb_node; + struct rb_node *n; struct xen_p2m_entry *entry; unsigned long irqflags; read_lock_irqsave(&p2m_lock, irqflags); + n = phys_to_mach.rb_node; while (n) { entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); if (entry->pfn <= pfn && @@ -93,10 +94,39 @@ int i; for (i = 0; i < count; i++) { + struct gnttab_unmap_grant_ref unmap; + int rc; + if (map_ops[i].status) continue; - set_phys_to_machine(map_ops[i].host_addr >> XEN_PAGE_SHIFT, - map_ops[i].dev_bus_addr >> XEN_PAGE_SHIFT); + if (likely(set_phys_to_machine(map_ops[i].host_addr >> XEN_PAGE_SHIFT, + map_ops[i].dev_bus_addr >> XEN_PAGE_SHIFT))) + continue; + + /* + * Signal an error for this slot. This in turn requires + * immediate unmapping. + */ + map_ops[i].status = GNTST_general_error; + unmap.host_addr = map_ops[i].host_addr, + unmap.handle = map_ops[i].handle; + map_ops[i].handle = ~0; + if (map_ops[i].flags & GNTMAP_device_map) + unmap.dev_bus_addr = map_ops[i].dev_bus_addr; + else + unmap.dev_bus_addr = 0; + + /* + * Pre-populate the status field, to be recognizable in + * the log message below. + */ + unmap.status = 1; + + rc = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, + &unmap, 1); + if (rc || unmap.status != GNTST_okay) + pr_err_once("gnttab unmap failed: rc=%d st=%d\n", + rc, unmap.status); } return 0; @@ -124,10 +154,11 @@ int rc; unsigned long irqflags; struct xen_p2m_entry *p2m_entry; - struct rb_node *n = phys_to_mach.rb_node; + struct rb_node *n; if (mfn == INVALID_P2M_ENTRY) { write_lock_irqsave(&p2m_lock, irqflags); + n = phys_to_mach.rb_node; while (n) { p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); if (p2m_entry->pfn <= pfn && --- linux-oracle-5.4.0.orig/arch/arm64/Kconfig +++ linux-oracle-5.4.0/arch/arm64/Kconfig @@ -139,6 +139,7 @@ select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL select HAVE_CONTEXT_TRACKING + select HAVE_COPY_THREAD_TLS select HAVE_DEBUG_BUGVERBOSE select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_CONTIGUOUS @@ -152,7 +153,6 @@ select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING - select HAVE_MEMBLOCK_NODE_MAP if NUMA select HAVE_NMI select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS @@ -180,7 +180,6 @@ select PCI_SYSCALL if PCI select POWER_RESET select POWER_SUPPLY - select REFCOUNT_FULL select SPARSE_IRQ select SWIOTLB select SYSCTL_EXCEPTION_TRACE @@ -488,7 +487,7 @@ help This option adds a workaround for ARM Cortex-A55 Erratum 1024718. - Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect + Affected Cortex-A55 cores (all revisions) could cause incorrect update of the hardware dirty bit when the DBM/AP bits are updated without a break-before-make. The workaround is to disable the usage of hardware DBM locally on the affected cores. CPUs not affected by @@ -558,6 +557,78 @@ If unsure, say Y. +config ARM64_ERRATUM_1542419 + bool "Neoverse-N1: workaround mis-ordering of instruction fetches" + default y + help + This option adds a workaround for ARM Neoverse-N1 erratum + 1542419. + + Affected Neoverse-N1 cores could execute a stale instruction when + modified by another CPU. The workaround depends on a firmware + counterpart. + + Workaround the issue by hiding the DIC feature from EL0. This + forces user-space to perform cache maintenance. + + If unsure, say Y. + +config ARM64_ERRATUM_1742098 + bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence" + depends on COMPAT + default y + help + This option removes the AES hwcap for aarch32 user-space to + workaround erratum 1742098 on Cortex-A57 and Cortex-A72. + + Affected parts may corrupt the AES state if an interrupt is + taken between a pair of AES instructions. These instructions + are only present if the cryptography extensions are present. + All software should have a fallback implementation for CPUs + that don't implement the cryptography extensions. + + If unsure, say Y. + +config ARM64_ERRATUM_3194386 + bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing" + default y + help + This option adds the workaround for the following errata: + + * ARM Cortex-A76 erratum 3324349 + * ARM Cortex-A77 erratum 3324348 + * ARM Cortex-A78 erratum 3324344 + * ARM Cortex-A78C erratum 3324346 + * ARM Cortex-A78C erratum 3324347 + * ARM Cortex-A710 erratam 3324338 + * ARM Cortex-A715 errartum 3456084 + * ARM Cortex-A720 erratum 3456091 + * ARM Cortex-A725 erratum 3456106 + * ARM Cortex-X1 erratum 3324344 + * ARM Cortex-X1C erratum 3324346 + * ARM Cortex-X2 erratum 3324338 + * ARM Cortex-X3 erratum 3324335 + * ARM Cortex-X4 erratum 3194386 + * ARM Cortex-X925 erratum 3324334 + * ARM Neoverse-N1 erratum 3324349 + * ARM Neoverse N2 erratum 3324339 + * ARM Neoverse-N3 erratum 3456111 + * ARM Neoverse-V1 erratum 3324341 + * ARM Neoverse V2 erratum 3324336 + * ARM Neoverse-V3 erratum 3312417 + + On affected cores "MSR SSBS, #0" instructions may not affect + subsequent speculative instructions, which may permit unexepected + speculative store bypassing. + + Work around this problem by placing a Speculation Barrier (SB) or + Instruction Synchronization Barrier (ISB) after kernel changes to + SSBS. The presence of the SSBS special-purpose register is hidden + from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace + will use the PR_SPEC_STORE_BYPASS prctl to change SSBS. + + If unsure, say Y. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y @@ -891,7 +962,7 @@ config NODES_SHIFT int "Maximum NUMA Nodes (as a power of 2)" range 1 10 - default "2" + default "4" depends on NEED_MULTIPLE_NODES help Specify the maximum number of NUMA Nodes available on the target @@ -1048,6 +1119,7 @@ config FORCE_MAX_ZONEORDER int default "14" if (ARM64_64K_PAGES && TRANSPARENT_HUGEPAGE) + default "13" if (ARCH_THUNDER && ARM64_4K_PAGES) default "12" if (ARM64_16K_PAGES && TRANSPARENT_HUGEPAGE) default "11" help @@ -1122,6 +1194,15 @@ If unsure, say Y. +config MITIGATE_SPECTRE_BRANCH_HISTORY + bool "Mitigate Spectre style attacks against branch history" if EXPERT + default y + help + Speculation attacks against some high-performance processors can + make use of branch history to influence future speculation. + When taking an exception from user-space, a sequence of branches + or a firmware call overwrites the branch history. + config RODATA_FULL_DEFAULT_ENABLED bool "Apply r/o permissions of VM areas also to their linear aliases" default y --- linux-oracle-5.4.0.orig/arch/arm64/Kconfig.platforms +++ linux-oracle-5.4.0/arch/arm64/Kconfig.platforms @@ -54,6 +54,7 @@ config ARCH_BERLIN bool "Marvell Berlin SoC Family" select DW_APB_ICTL + select DW_APB_TIMER_OF select GPIOLIB select PINCTRL help @@ -224,6 +225,7 @@ config ARCH_SYNQUACER bool "Socionext SynQuacer SoC Family" + select IRQ_FASTEOI_HIERARCHY_HANDLERS config ARCH_TEGRA bool "NVIDIA Tegra SoC Family" --- linux-oracle-5.4.0.orig/arch/arm64/Makefile +++ linux-oracle-5.4.0/arch/arm64/Makefile @@ -18,7 +18,7 @@ # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour # for relative relocs, since this leads to better Image compression # with the relocation offsets always being zero. -LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \ +LDFLAGS_vmlinux += -shared -Bsymbolic -z notext \ $(call ld-option, --no-apply-dynamic-relocs) endif @@ -72,23 +72,31 @@ include/generated/asm-offsets.h)) endif +# Ensure that if the compiler supports branch protection we default it +# off. +KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none) + ifeq ($(CONFIG_CPU_BIG_ENDIAN), y) KBUILD_CPPFLAGS += -mbig-endian CHECKFLAGS += -D__AARCH64EB__ AS += -EB # Prefer the baremetal ELF build target, but not all toolchains include # it so fall back to the standard linux version if needed. -KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb) +KBUILD_LDFLAGS += -EB $(call ld-option, -maarch64elfb, -maarch64linuxb -z norelro) UTS_MACHINE := aarch64_be else KBUILD_CPPFLAGS += -mlittle-endian CHECKFLAGS += -D__AARCH64EL__ AS += -EL # Same as above, prefer ELF but fall back to linux target if needed. -KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux) +KBUILD_LDFLAGS += -EL $(call ld-option, -maarch64elf, -maarch64linux -z norelro) UTS_MACHINE := aarch64 endif +ifeq ($(CONFIG_LD_IS_LLD), y) +KBUILD_LDFLAGS += -z norelro +endif + CHECKFLAGS += -D__aarch64__ ifeq ($(CONFIG_ARM64_MODULE_PLTS),y) @@ -142,6 +150,8 @@ PHONY += vdso_install vdso_install: $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso $@ + $(if $(CONFIG_COMPAT_VDSO), \ + $(Q)$(MAKE) $(build)=arch/arm64/kernel/vdso32 $@) # We use MRPROPER_FILES and CLEAN_FILES now archclean: --- linux-oracle-5.4.0.orig/arch/arm64/boot/Makefile +++ linux-oracle-5.4.0/arch/arm64/boot/Makefile @@ -16,7 +16,7 @@ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S -targets := Image Image.gz +targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/actions/s700.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/actions/s700.dtsi @@ -231,7 +231,7 @@ pinctrl: pinctrl@e01b0000 { compatible = "actions,s700-pinctrl"; - reg = <0x0 0xe01b0000 0x0 0x1000>; + reg = <0x0 0xe01b0000 0x0 0x100>; clocks = <&cmu CLK_GPIO>; gpio-controller; gpio-ranges = <&pinctrl 0 0 136>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -127,7 +127,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&ext_rgmii_phy>; phy-supply = <®_dc1sw>; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts @@ -15,7 +15,7 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; vmmc-supply = <®_dcdc1>; - vqmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_eldo1>; bus-width = <8>; non-removable; cap-mmc-hw-reset; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts @@ -140,7 +140,7 @@ &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; - vmmc-supply = <®_aldo2>; + vmmc-supply = <®_dcdc1>; vqmmc-supply = <®_dldo4>; mmc-pwrseq = <&wifi_pwrseq>; bus-width = <4>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts @@ -78,7 +78,7 @@ leds { compatible = "gpio-leds"; - status { + led-0 { label = "orangepi:green:status"; gpios = <&pio 7 11 GPIO_ACTIVE_HIGH>; /* PH11 */ }; @@ -129,7 +129,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&ext_rgmii_phy>; phy-supply = <®_gmac_3v3>; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts @@ -11,3 +11,7 @@ compatible = "pine64,pine64-lts", "allwinner,sun50i-r18", "allwinner,sun50i-a64"; }; + +&mmc0 { + broken-cd; /* card detect is broken on *some* boards */ +}; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts @@ -52,7 +52,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii"; + phy-mode = "rgmii-txid"; phy-handle = <&ext_rgmii_phy>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts @@ -103,8 +103,6 @@ }; &ehci0 { - phys = <&usbphy 0>; - phy-names = "usb"; status = "okay"; }; @@ -142,6 +140,7 @@ pinctrl-0 = <&mmc2_pins>, <&mmc2_ds_pin>; vmmc-supply = <®_dcdc1>; vqmmc-supply = <®_eldo1>; + max-frequency = <200000000>; bus-width = <8>; non-removable; cap-mmc-hw-reset; @@ -150,8 +149,6 @@ }; &ohci0 { - phys = <&usbphy 0>; - phy-names = "usb"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi @@ -55,10 +55,9 @@ pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; vmmc-supply = <®_dcdc1>; - non-removable; disable-wp; bus-width = <4>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 push-pull switch */ status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -142,6 +142,15 @@ clock-output-names = "ext-osc32k"; }; + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + psci { compatible = "arm,psci-0.2"; method = "smc"; @@ -218,7 +227,7 @@ display_clocks: clock@0 { compatible = "allwinner,sun50i-a64-de2-clk"; - reg = <0x0 0x100000>; + reg = <0x0 0x10000>; clocks = <&ccu CLK_BUS_DE>, <&ccu CLK_DE>; clock-names = "bus", @@ -467,7 +476,7 @@ resets = <&ccu RST_BUS_MMC2>; reset-names = "ahb"; interrupts = ; - max-frequency = <200000000>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -521,6 +530,8 @@ <&ccu CLK_USB_OHCI0>; resets = <&ccu RST_BUS_OHCI0>, <&ccu RST_BUS_EHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; status = "disabled"; }; @@ -531,6 +542,8 @@ clocks = <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>; resets = <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts @@ -114,7 +114,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts @@ -157,7 +157,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts @@ -164,7 +164,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts @@ -72,7 +72,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi @@ -54,21 +54,21 @@ enable-method = "psci"; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a53"; device_type = "cpu"; reg = <1>; enable-method = "psci"; }; - cpu@2 { + cpu2: cpu@2 { compatible = "arm,cortex-a53"; device_type = "cpu"; reg = <2>; enable-method = "psci"; }; - cpu@3 { + cpu3: cpu@3 { compatible = "arm,cortex-a53"; device_type = "cpu"; reg = <3>; @@ -76,6 +76,15 @@ }; }; + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + psci { compatible = "arm,psci-0.2"; method = "smc"; @@ -146,8 +155,7 @@ , , , - , - ; + ; interrupt-names = "gp", "gpmmu", "pp", @@ -158,8 +166,7 @@ "pp2", "ppmmu2", "pp3", - "ppmmu3", - "pmu"; + "ppmmu3"; clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>; clock-names = "bus", "core"; resets = <&ccu RST_BUS_GPU>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts @@ -83,7 +83,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&ext_rgmii_pins>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&ext_rgmii_phy>; phy-supply = <®_aldo2>; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts @@ -66,7 +66,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&ext_rgmii_pins>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; phy-handle = <&ext_rgmii_phy>; phy-supply = <®_aldo2>; allwinner,rx-delay-ps = <200>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi @@ -70,6 +70,15 @@ clock-output-names = "ext_osc32k"; }; + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + psci { compatible = "arm,psci-0.2"; method = "smc"; @@ -323,6 +332,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -339,6 +349,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -355,6 +366,7 @@ interrupts = ; pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -524,6 +536,8 @@ <&ccu CLK_USB_OHCI0>; resets = <&ccu RST_BUS_OHCI0>, <&ccu RST_BUS_EHCI0>; + phys = <&usb2phy 0>; + phy-names = "usb"; status = "disabled"; }; @@ -534,6 +548,8 @@ clocks = <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>; resets = <&ccu RST_BUS_OHCI0>; + phys = <&usb2phy 0>; + phy-names = "usb"; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi @@ -61,10 +61,10 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <0 120 8>, - <0 121 8>, - <0 122 8>, - <0 123 8>; + interrupts = <0 170 4>, + <0 171 4>, + <0 172 4>, + <0 173 4>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, @@ -77,7 +77,7 @@ method = "smc"; }; - intc: intc@fffc1000 { + intc: interrupt-controller@fffc1000 { compatible = "arm,gic-400", "arm,cortex-a15-gic"; #interrupt-cells = <3>; interrupt-controller; @@ -302,7 +302,7 @@ status = "disabled"; }; - nand: nand@ffb90000 { + nand: nand-controller@ffb90000 { #address-cells = <1>; #size-cells = <0>; compatible = "altr,socfpga-denali-nand"; @@ -445,7 +445,7 @@ clock-names = "timer"; }; - uart0: serial0@ffc02000 { + uart0: serial@ffc02000 { compatible = "snps,dw-apb-uart"; reg = <0xffc02000 0x100>; interrupts = <0 108 4>; @@ -456,7 +456,7 @@ status = "disabled"; }; - uart1: serial1@ffc02100 { + uart1: serial@ffc02100 { compatible = "snps,dw-apb-uart"; reg = <0xffc02100 0x100>; interrupts = <0 109 4>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts @@ -129,7 +129,7 @@ status = "okay"; clock-frequency = <100000>; i2c-sda-falling-time-ns = <890>; /* hcnt */ - i2c-sdl-falling-time-ns = <890>; /* lcnt */ + i2c-scl-falling-time-ns = <890>; /* lcnt */ adc@14 { compatible = "lltc,ltc2497"; @@ -155,6 +155,7 @@ }; &qspi { + status = "okay"; flash@0 { #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-axg.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-axg.dtsi @@ -150,7 +150,7 @@ scpi_clocks: clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: clock-controller { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>; @@ -159,7 +159,7 @@ }; scpi_sensors: sensors { - compatible = "amlogic,meson-gxbb-scpi-sensors"; + compatible = "amlogic,meson-gxbb-scpi-sensors", "arm,scpi-sensors"; #thermal-sensor-cells = <1>; }; }; @@ -1162,7 +1162,7 @@ toddr_a: audio-controller@100 { compatible = "amlogic,axg-toddr"; - reg = <0x0 0x100 0x0 0x1c>; + reg = <0x0 0x100 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_A"; interrupts = ; @@ -1173,7 +1173,7 @@ toddr_b: audio-controller@140 { compatible = "amlogic,axg-toddr"; - reg = <0x0 0x140 0x0 0x1c>; + reg = <0x0 0x140 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_B"; interrupts = ; @@ -1184,7 +1184,7 @@ toddr_c: audio-controller@180 { compatible = "amlogic,axg-toddr"; - reg = <0x0 0x180 0x0 0x1c>; + reg = <0x0 0x180 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_C"; interrupts = ; @@ -1195,7 +1195,7 @@ frddr_a: audio-controller@1c0 { compatible = "amlogic,axg-frddr"; - reg = <0x0 0x1c0 0x0 0x1c>; + reg = <0x0 0x1c0 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_A"; interrupts = ; @@ -1206,7 +1206,7 @@ frddr_b: audio-controller@200 { compatible = "amlogic,axg-frddr"; - reg = <0x0 0x200 0x0 0x1c>; + reg = <0x0 0x200 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_B"; interrupts = ; @@ -1217,7 +1217,7 @@ frddr_c: audio-controller@240 { compatible = "amlogic,axg-frddr"; - reg = <0x0 0x240 0x0 0x1c>; + reg = <0x0 0x240 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_C"; interrupts = ; @@ -1705,7 +1705,7 @@ sd_emmc_b: sd@5000 { compatible = "amlogic,meson-axg-mmc"; reg = <0x0 0x5000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; clocks = <&clkc CLKID_SD_EMMC_B>, <&clkc CLKID_SD_EMMC_B_CLK0>, @@ -1717,7 +1717,7 @@ sd_emmc_c: mmc@7000 { compatible = "amlogic,meson-axg-mmc"; reg = <0x0 0x7000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; clocks = <&clkc CLKID_SD_EMMC_C>, <&clkc CLKID_SD_EMMC_C_CLK0>, @@ -1728,18 +1728,18 @@ }; sram: sram@fffc0000 { - compatible = "amlogic,meson-axg-sram", "mmio-sram"; + compatible = "mmio-sram"; reg = <0x0 0xfffc0000 0x0 0x20000>; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x0 0xfffc0000 0x20000>; - cpu_scp_lpri: scp-shmem@13000 { + cpu_scp_lpri: scp-sram@13000 { compatible = "amlogic,meson-axg-scp-shmem"; reg = <0x13000 0x400>; }; - cpu_scp_hpri: scp-shmem@13400 { + cpu_scp_hpri: scp-sram@13400 { compatible = "amlogic,meson-axg-scp-shmem"; reg = <0x13400 0x400>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi @@ -76,6 +76,12 @@ no-map; }; + /* 32 MiB reserved for ARM Trusted Firmware (BL32) */ + secmon_reserved_bl32: secmon@5300000 { + reg = <0x0 0x05300000 0x0 0x2000000>; + no-map; + }; + linux,cma { compatible = "shared-dma-pool"; reusable; @@ -167,6 +173,8 @@ hwrng: rng@218 { compatible = "amlogic,meson-rng"; reg = <0x0 0x218 0x0 0x4>; + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; }; }; @@ -1368,10 +1376,9 @@ dmc: bus@38000 { compatible = "simple-bus"; - reg = <0x0 0x38000 0x0 0x400>; #address-cells = <2>; #size-cells = <2>; - ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>; + ranges = <0x0 0x0 0x0 0x38000 0x0 0x2000>; canvas: video-lut@48 { compatible = "amlogic,canvas"; @@ -1509,7 +1516,7 @@ toddr_a: audio-controller@100 { compatible = "amlogic,g12a-toddr", "amlogic,axg-toddr"; - reg = <0x0 0x100 0x0 0x1c>; + reg = <0x0 0x100 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_A"; interrupts = ; @@ -1521,7 +1528,7 @@ toddr_b: audio-controller@140 { compatible = "amlogic,g12a-toddr", "amlogic,axg-toddr"; - reg = <0x0 0x140 0x0 0x1c>; + reg = <0x0 0x140 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_B"; interrupts = ; @@ -1533,7 +1540,7 @@ toddr_c: audio-controller@180 { compatible = "amlogic,g12a-toddr", "amlogic,axg-toddr"; - reg = <0x0 0x180 0x0 0x1c>; + reg = <0x0 0x180 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "TODDR_C"; interrupts = ; @@ -1545,7 +1552,7 @@ frddr_a: audio-controller@1c0 { compatible = "amlogic,g12a-frddr", "amlogic,axg-frddr"; - reg = <0x0 0x1c0 0x0 0x1c>; + reg = <0x0 0x1c0 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_A"; interrupts = ; @@ -1557,7 +1564,7 @@ frddr_b: audio-controller@200 { compatible = "amlogic,g12a-frddr", "amlogic,axg-frddr"; - reg = <0x0 0x200 0x0 0x1c>; + reg = <0x0 0x200 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_B"; interrupts = ; @@ -1569,7 +1576,7 @@ frddr_c: audio-controller@240 { compatible = "amlogic,g12a-frddr", "amlogic,axg-frddr"; - reg = <0x0 0x240 0x0 0x1c>; + reg = <0x0 0x240 0x0 0x2c>; #sound-dai-cells = <0>; sound-name-prefix = "FRDDR_C"; interrupts = ; @@ -1775,7 +1782,7 @@ #address-cells = <1>; #size-cells = <0>; - internal_ephy: ethernet_phy@8 { + internal_ephy: ethernet-phy@8 { compatible = "ethernet-phy-id0180.3301", "ethernet-phy-ieee802.3-c22"; interrupts = ; @@ -2309,7 +2316,7 @@ sd_emmc_a: sd@ffe03000 { compatible = "amlogic,meson-axg-mmc"; reg = <0x0 0xffe03000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; clocks = <&clkc CLKID_SD_EMMC_A>, <&clkc CLKID_SD_EMMC_A_CLK0>, @@ -2321,7 +2328,7 @@ sd_emmc_b: sd@ffe05000 { compatible = "amlogic,meson-axg-mmc"; reg = <0x0 0xffe05000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; clocks = <&clkc CLKID_SD_EMMC_B>, <&clkc CLKID_SD_EMMC_B_CLK0>, @@ -2333,7 +2340,7 @@ sd_emmc_c: mmc@ffe07000 { compatible = "amlogic,meson-axg-mmc"; reg = <0x0 0xffe07000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; clocks = <&clkc CLKID_SD_EMMC_C>, <&clkc CLKID_SD_EMMC_C_CLK0>, @@ -2365,7 +2372,7 @@ reg = <0x0 0xff400000 0x0 0x40000>; interrupts = ; clocks = <&clkc CLKID_USB1_DDR_BRIDGE>; - clock-names = "ddr"; + clock-names = "otg"; phys = <&usb2_phy1>; phy-names = "usb2-phy"; dr_mode = "peripheral"; @@ -2380,7 +2387,8 @@ interrupts = ; dr_mode = "host"; snps,dis_u2_susphy_quirk; - snps,quirk-frame-length-adjustment; + snps,quirk-frame-length-adjustment = <0x20>; + snps,parkmode-disable-ss-quirk; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>; - vin-supply = <&dc_in>; + pwm-supply = <&dc_in>; pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; @@ -157,14 +157,6 @@ regulator-always-on; }; - reserved-memory { - /* TEE Reserved Memory */ - bl32_reserved: bl32@5000000 { - reg = <0x0 0x05300000 0x0 0x2000000>; - no-map; - }; - }; - sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>; - vin-supply = <&main_12v>; + pwm-supply = <&main_12v>; pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts @@ -139,7 +139,7 @@ regulator-min-microvolt = <721000>; regulator-max-microvolt = <1022000>; - vin-supply = <&dc_in>; + pwm-supply = <&dc_in>; pwms = <&pwm_AO_cd 1 1250 0>; pwm-dutycycle-range = <100 0>; @@ -340,7 +340,7 @@ eee-broken-1000t; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi @@ -54,26 +54,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <731000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <731000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <731000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <666666666>; - opp-microvolt = <731000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <731000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi @@ -11,26 +11,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <731000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <731000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <731000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <667000000>; - opp-microvolt = <731000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <761000>; @@ -71,26 +51,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <731000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <731000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <731000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <667000000>; - opp-microvolt = <731000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <731000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi @@ -152,6 +152,10 @@ clock-latency = <50000>; }; +&frddr_a { + status = "okay"; +}; + &frddr_b { status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi @@ -11,26 +11,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <731000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <731000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <731000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <667000000>; - opp-microvolt = <731000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <731000>; @@ -71,26 +51,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <751000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <751000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <751000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <667000000>; - opp-microvolt = <751000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <771000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -41,6 +41,12 @@ no-map; }; + /* 32 MiB reserved for ARM Trusted Firmware (BL32) */ + secmon_reserved_bl32: secmon@5300000 { + reg = <0x0 0x05300000 0x0 0x2000000>; + no-map; + }; + linux,cma { compatible = "shared-dma-pool"; reusable; @@ -166,7 +172,7 @@ reg = <0x14 0x10>; }; - eth_mac: eth_mac@34 { + eth_mac: eth-mac@34 { reg = <0x34 0x10>; }; @@ -183,7 +189,7 @@ scpi_clocks: clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi_clocks@0 { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>; @@ -345,20 +351,20 @@ }; sram: sram@c8000000 { - compatible = "amlogic,meson-gx-sram", "amlogic,meson-gxbb-sram", "mmio-sram"; + compatible = "mmio-sram"; reg = <0x0 0xc8000000 0x0 0x14000>; #address-cells = <1>; #size-cells = <1>; ranges = <0 0x0 0xc8000000 0x14000>; - cpu_scp_lpri: scp-shmem@0 { - compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; + cpu_scp_lpri: scp-sram@0 { + compatible = "amlogic,meson-gxbb-scp-shmem"; reg = <0x13000 0x400>; }; - cpu_scp_hpri: scp-shmem@200 { - compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; + cpu_scp_hpri: scp-sram@200 { + compatible = "amlogic,meson-gxbb-scp-shmem"; reg = <0x13400 0x400>; }; }; @@ -458,7 +464,7 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>; - hwrng: rng { + hwrng: rng@0 { compatible = "amlogic,meson-rng"; reg = <0x0 0x0 0x0 0x4>; }; @@ -522,21 +528,21 @@ sd_emmc_a: mmc@70000 { compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc"; reg = <0x0 0x70000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; }; sd_emmc_b: mmc@72000 { compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc"; reg = <0x0 0x72000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; }; sd_emmc_c: mmc@74000 { compatible = "amlogic,meson-gx-mmc", "amlogic,meson-gxbb-mmc"; reg = <0x0 0x74000 0x0 0x800>; - interrupts = ; + interrupts = ; status = "disabled"; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts @@ -165,7 +165,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -138,7 +138,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; @@ -296,7 +296,7 @@ }; &usb0_phy { - status = "okay"; + status = "disabled"; phy-supply = <&usb_otg_pwr>; }; @@ -306,7 +306,7 @@ }; &usb0 { - status = "okay"; + status = "disabled"; }; &usb1 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -126,7 +126,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi @@ -6,6 +6,7 @@ */ #include "meson-gxbb.dtsi" +#include / { aliases { @@ -64,6 +65,7 @@ regulator-name = "VDDIO_AO18"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-always-on; }; vcc_3v3: regulator-vcc_3v3 { @@ -147,7 +149,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; }; }; @@ -157,6 +159,7 @@ status = "okay"; pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; pinctrl-names = "default"; + hdmi-supply = <&vddio_ao18>; }; &hdmi_tx_tmds_port { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -326,8 +326,8 @@ <&reset RESET_HDMI_SYSTEM_RESET>, <&reset RESET_HDMI_TX>; reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; - clocks = <&clkc CLKID_HDMI_PCLK>, - <&clkc CLKID_CLK81>, + clocks = <&clkc CLKID_HDMI>, + <&clkc CLKID_HDMI_PCLK>, <&clkc CLKID_GCLK_VENCI_INT0>; clock-names = "isfr", "iahb", "venci"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-libretech-ac.dts @@ -9,7 +9,7 @@ #include -#include "meson-gxl-s905x.dtsi" +#include "meson-gxl-s805x.dtsi" / { compatible = "libretech,aml-s805x-ac", "amlogic,s805x", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s805x-p241.dts @@ -9,7 +9,7 @@ #include -#include "meson-gxl-s905x.dtsi" +#include "meson-gxl-s805x.dtsi" / { compatible = "amlogic,p241", "amlogic,s805x", "amlogic,meson-gxl"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s805x.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s805x.dtsi @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 BayLibre SAS + * Author: Neil Armstrong + */ + +#include "meson-gxl-s905x.dtsi" + +/ { + compatible = "amlogic,s805x", "amlogic,meson-gxl"; +}; + +/* The S805X Package doesn't seem to handle the 744MHz OPP correctly */ +&mali { + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>; /* Do Nothing */ +}; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts @@ -82,7 +82,7 @@ /* External PHY reset is shared with internal PHY Led signal */ reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-phicomm-n1.dts @@ -18,7 +18,7 @@ leds { compatible = "gpio-leds"; - status { + led { label = "n1:white:status"; gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>; default-state = "on"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts @@ -33,11 +33,9 @@ gpio-keys-polled { compatible = "gpio-keys-polled"; - #address-cells = <1>; - #size-cells = <0>; poll-interval = <100>; - button@0 { + power-button { label = "power"; linux,code = ; gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>; @@ -192,6 +190,9 @@ bluetooth { compatible = "brcm,bcm43438-bt"; shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi @@ -273,8 +273,8 @@ <&reset RESET_HDMI_SYSTEM_RESET>, <&reset RESET_HDMI_TX>; reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; - clocks = <&clkc CLKID_HDMI_PCLK>, - <&clkc CLKID_CLK81>, + clocks = <&clkc CLKID_HDMI>, + <&clkc CLKID_HDMI_PCLK>, <&clkc CLKID_GCLK_VENCI_INT0>; clock-names = "isfr", "iahb", "venci"; }; @@ -288,6 +288,11 @@ }; }; +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + &i2c_A { clocks = <&clkc CLKID_I2C>; }; @@ -695,7 +700,7 @@ }; }; - eth-phy-mux { + eth-phy-mux@55c { compatible = "mdio-mux-mmioreg", "mdio-mux"; #address-cells = <1>; #size-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts @@ -251,7 +251,7 @@ reg = <0>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; @@ -327,7 +327,7 @@ #size-cells = <0>; bus-width = <4>; - max-frequency = <50000000>; + max-frequency = <60000000>; non-removable; disable-wp; @@ -395,7 +395,7 @@ #size-cells = <1>; compatible = "winbond,w25q16", "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <3000000>; + spi-max-frequency = <104000000>; }; }; @@ -409,6 +409,9 @@ bluetooth { compatible = "brcm,bcm43438-bt"; shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; + max-speed = <2000000>; + clocks = <&wifi32k>; + clock-names = "lpo"; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts @@ -112,7 +112,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxm-q200.dts @@ -64,7 +64,7 @@ /* External PHY reset is shared with internal PHY Led signal */ reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; interrupt-parent = <&gpio_intc>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-gxm-rbox-pro.dts @@ -114,7 +114,7 @@ max-speed = <1000>; reset-assert-us = <10000>; - reset-deassert-us = <30000>; + reset-deassert-us = <80000>; reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi @@ -43,13 +43,13 @@ white { label = "vim3:white:sys"; - gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>; + gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; red { label = "vim3:red"; - gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>; + gpios = <&gpio_expander 5 GPIO_ACTIVE_HIGH>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts @@ -164,14 +164,6 @@ regulator-always-on; }; - reserved-memory { - /* TEE Reserved Memory */ - bl32_reserved: bl32@5000000 { - reg = <0x0 0x05300000 0x0 0x2000000>; - no-map; - }; - }; - sdio_pwrseq: sdio-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>; @@ -361,6 +353,9 @@ bluetooth { compatible = "brcm,bcm43438-bt"; + interrupt-parent = <&gpio_intc>; + interrupts = <95 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wakeup"; shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; max-speed = <2000000>; clocks = <&wifi32k>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi @@ -55,26 +55,6 @@ compatible = "operating-points-v2"; opp-shared; - opp-100000000 { - opp-hz = /bits/ 64 <100000000>; - opp-microvolt = <730000>; - }; - - opp-250000000 { - opp-hz = /bits/ 64 <250000000>; - opp-microvolt = <730000>; - }; - - opp-500000000 { - opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <730000>; - }; - - opp-667000000 { - opp-hz = /bits/ 64 <666666666>; - opp-microvolt = <750000>; - }; - opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; opp-microvolt = <770000>; @@ -90,7 +70,7 @@ opp-microvolt = <790000>; }; - opp-1512000000 { + opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; opp-microvolt = <800000>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/foundation-v8-gicv2.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/foundation-v8-gicv2.dtsi @@ -8,7 +8,7 @@ gic: interrupt-controller@2c001000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <2>; + #address-cells = <1>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, <0x0 0x2c002000 0 0x2000>, --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dtsi @@ -8,9 +8,9 @@ gic: interrupt-controller@2f000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x2f000000 0x100000>; interrupt-controller; reg = <0x0 0x2f000000 0x0 0x10000>, <0x0 0x2f100000 0x0 0x200000>, @@ -22,7 +22,7 @@ its: its@2f020000 { compatible = "arm,gic-v3-its"; msi-controller; - reg = <0x0 0x2f020000 0x0 0x20000>; + reg = <0x20000 0x20000>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/foundation-v8.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -107,51 +107,51 @@ #interrupt-cells = <1>; interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, - <0 0 1 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, - <0 0 2 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, - <0 0 3 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, - <0 0 4 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <0 0 5 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, - <0 0 6 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, - <0 0 7 &gic 0 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, - <0 0 8 &gic 0 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, - <0 0 9 &gic 0 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, - <0 0 10 &gic 0 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, - <0 0 11 &gic 0 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>, - <0 0 12 &gic 0 0 GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, - <0 0 13 &gic 0 0 GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, - <0 0 14 &gic 0 0 GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, - <0 0 15 &gic 0 0 GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, - <0 0 16 &gic 0 0 GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, - <0 0 17 &gic 0 0 GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, - <0 0 18 &gic 0 0 GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, - <0 0 19 &gic 0 0 GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, - <0 0 20 &gic 0 0 GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>, - <0 0 21 &gic 0 0 GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>, - <0 0 22 &gic 0 0 GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>, - <0 0 23 &gic 0 0 GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>, - <0 0 24 &gic 0 0 GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>, - <0 0 25 &gic 0 0 GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>, - <0 0 26 &gic 0 0 GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, - <0 0 27 &gic 0 0 GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>, - <0 0 28 &gic 0 0 GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>, - <0 0 29 &gic 0 0 GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>, - <0 0 30 &gic 0 0 GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>, - <0 0 31 &gic 0 0 GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>, - <0 0 32 &gic 0 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, - <0 0 33 &gic 0 0 GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, - <0 0 34 &gic 0 0 GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, - <0 0 35 &gic 0 0 GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>, - <0 0 36 &gic 0 0 GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>, - <0 0 37 &gic 0 0 GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>, - <0 0 38 &gic 0 0 GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>, - <0 0 39 &gic 0 0 GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, - <0 0 40 &gic 0 0 GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, - <0 0 41 &gic 0 0 GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>, - <0 0 42 &gic 0 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 &gic 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <0 0 1 &gic 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>, + <0 0 2 &gic 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, + <0 0 3 &gic 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <0 0 4 &gic 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <0 0 5 &gic 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <0 0 6 &gic 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <0 0 7 &gic 0 GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <0 0 8 &gic 0 GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <0 0 9 &gic 0 GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <0 0 10 &gic 0 GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <0 0 11 &gic 0 GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>, + <0 0 12 &gic 0 GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, + <0 0 13 &gic 0 GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, + <0 0 14 &gic 0 GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, + <0 0 15 &gic 0 GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, + <0 0 16 &gic 0 GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, + <0 0 17 &gic 0 GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, + <0 0 18 &gic 0 GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, + <0 0 19 &gic 0 GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, + <0 0 20 &gic 0 GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>, + <0 0 21 &gic 0 GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>, + <0 0 22 &gic 0 GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>, + <0 0 23 &gic 0 GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>, + <0 0 24 &gic 0 GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>, + <0 0 25 &gic 0 GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>, + <0 0 26 &gic 0 GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>, + <0 0 27 &gic 0 GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>, + <0 0 28 &gic 0 GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>, + <0 0 29 &gic 0 GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>, + <0 0 30 &gic 0 GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>, + <0 0 31 &gic 0 GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>, + <0 0 32 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>, + <0 0 33 &gic 0 GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>, + <0 0 34 &gic 0 GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>, + <0 0 35 &gic 0 GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>, + <0 0 36 &gic 0 GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>, + <0 0 37 &gic 0 GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>, + <0 0 38 &gic 0 GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>, + <0 0 39 &gic 0 GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>, + <0 0 40 &gic 0 GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>, + <0 0 41 &gic 0 GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>, + <0 0 42 &gic 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; - ethernet@2,02000000 { + ethernet@202000000 { compatible = "smsc,lan91c111"; reg = <2 0x02000000 0x10000>; interrupts = <15>; @@ -178,7 +178,7 @@ clock-output-names = "v2m:refclk32khz"; }; - iofpga@3,00000000 { + iofpga@300000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/fvp-base-revc.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/fvp-base-revc.dts @@ -161,10 +161,10 @@ bus-range = <0x0 0x1>; reg = <0x0 0x40000000 0x0 0x10000000>; ranges = <0x2000000 0x0 0x50000000 0x0 0x50000000 0x0 0x10000000>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; msi-map = <0x0 &its 0x0 0x10000>; iommu-map = <0x0 &smmu 0x0 0x10000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/juno-base.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -6,7 +6,6 @@ /* * Devices shared by all Juno boards */ - dma-ranges = <0 0 0 0 0x100 0>; memtimer: timer@2a810000 { compatible = "arm,armv7-timer-mem"; @@ -63,35 +62,35 @@ <0x0 0x2c02f000 0 0x2000>, <0x0 0x2c04f000 0 0x2000>, <0x0 0x2c06f000 0 0x2000>; - #address-cells = <2>; + #address-cells = <1>; #interrupt-cells = <3>; - #size-cells = <2>; + #size-cells = <1>; interrupt-controller; interrupts = ; - ranges = <0 0 0 0x2c1c0000 0 0x40000>; + ranges = <0 0 0x2c1c0000 0x40000>; v2m_0: v2m@0 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0 0 0 0x10000>; + reg = <0 0x10000>; }; v2m@10000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0 0x10000 0 0x10000>; + reg = <0x10000 0x10000>; }; v2m@20000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0 0x20000 0 0x10000>; + reg = <0x20000 0x10000>; }; v2m@30000 { compatible = "arm,gic-v2m-frame"; msi-controller; - reg = <0 0x30000 0 0x10000>; + reg = <0x30000 0x10000>; }; }; @@ -520,10 +519,10 @@ <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic 0 0 GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic 0 0 GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic 0 0 GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; msi-parent = <&v2m_0>; status = "disabled"; iommu-map-mask = <0x0>; /* RC has no means to output PCI RID */ @@ -538,13 +537,13 @@ clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi-dvfs { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>, <1>, <2>; clock-output-names = "atlclk", "aplclk","gpuclk"; }; - scpi_clk: scpi-clk { + scpi_clk: clocks-1 { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; clock-indices = <3>; @@ -552,7 +551,7 @@ }; }; - scpi_devpd: scpi-power-domains { + scpi_devpd: power-controller { compatible = "arm,scpi-power-domains"; num-domains = <2>; #power-domain-cells = <1>; @@ -787,19 +786,19 @@ #interrupt-cells = <1>; interrupt-map-mask = <0 0 15>; - interrupt-map = <0 0 0 &gic 0 0 GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, - <0 0 1 &gic 0 0 GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, - <0 0 2 &gic 0 0 GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, - <0 0 3 &gic 0 0 GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, - <0 0 4 &gic 0 0 GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, - <0 0 5 &gic 0 0 GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, - <0 0 6 &gic 0 0 GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, - <0 0 7 &gic 0 0 GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, - <0 0 8 &gic 0 0 GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, - <0 0 9 &gic 0 0 GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, - <0 0 10 &gic 0 0 GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, - <0 0 11 &gic 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <0 0 12 &gic 0 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 &gic 0 GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, + <0 0 1 &gic 0 GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>, + <0 0 2 &gic 0 GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, + <0 0 3 &gic 0 GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <0 0 4 &gic 0 GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <0 0 5 &gic 0 GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <0 0 6 &gic 0 GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <0 0 7 &gic 0 GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <0 0 8 &gic 0 GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <0 0 9 &gic 0 GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <0 0 10 &gic 0 GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <0 0 11 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <0 0 12 &gic 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; }; site2: tlx@60000000 { @@ -809,6 +808,6 @@ ranges = <0 0 0x60000000 0x10000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0>; - interrupt-map = <0 0 &gic 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 &gic 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/juno-clocks.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/juno-clocks.dtsi @@ -8,10 +8,10 @@ */ / { /* SoC fixed clocks */ - soc_uartclk: refclk7273800hz { + soc_uartclk: refclk7372800hz { compatible = "fixed-clock"; #clock-cells = <0>; - clock-frequency = <7273800>; + clock-frequency = <7372800>; clock-output-names = "juno:uartclk"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -103,7 +103,7 @@ }; }; - flash@0,00000000 { + flash@0 { /* 2 * 32MiB NOR Flash memory mounted on CS0 */ compatible = "arm,vexpress-flash", "cfi-flash"; reg = <0 0x00000000 0x04000000>; @@ -120,7 +120,7 @@ }; }; - ethernet@2,00000000 { + ethernet@200000000 { compatible = "smsc,lan9118", "smsc,lan9115"; reg = <2 0x00000000 0x10000>; interrupts = <3>; @@ -133,7 +133,7 @@ vddvario-supply = <&mb_fixed_3v3>; }; - iofpga@3,00000000 { + iofpga@300000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/rtsm_ve-motherboard-rs2.dtsi @@ -9,7 +9,7 @@ motherboard { arm,v2m-memory-map = "rs2"; - iofpga@3,00000000 { + iofpga@300000000 { virtio-p9@140000 { compatible = "virtio,mmio"; reg = <0x140000 0x200>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -17,14 +17,14 @@ #interrupt-cells = <1>; ranges; - flash@0,00000000 { + flash@0 { compatible = "arm,vexpress-flash", "cfi-flash"; reg = <0 0x00000000 0x04000000>, <4 0x00000000 0x04000000>; bank-width = <4>; }; - ethernet@2,02000000 { + ethernet@202000000 { compatible = "smsc,lan91c111"; reg = <2 0x02000000 0x10000>; interrupts = <15>; @@ -51,7 +51,7 @@ clock-output-names = "v2m:refclk32khz"; }; - iofpga@3,00000000 { + iofpga@300000000 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/broadcom/northstar2/ns2-svk.dts @@ -111,8 +111,8 @@ compatible = "silabs,si3226x"; reg = <0>; spi-max-frequency = <5000000>; - spi-cpha = <1>; - spi-cpol = <1>; + spi-cpha; + spi-cpol; pl022,hierarchy = <0>; pl022,interface = <0>; pl022,slave-tx-disable = <0>; @@ -135,8 +135,8 @@ at25,byte-len = <0x8000>; at25,addr-mode = <2>; at25,page-size = <64>; - spi-cpha = <1>; - spi-cpol = <1>; + spi-cpha; + spi-cpol; pl022,hierarchy = <0>; pl022,interface = <0>; pl022,slave-tx-disable = <0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi @@ -687,7 +687,7 @@ }; }; - sata: ahci@663f2000 { + sata: sata@663f2000 { compatible = "brcm,iproc-ahci", "generic-ahci"; reg = <0x663f2000 0x1000>; dma-coherent; @@ -745,7 +745,7 @@ }; qspi: spi@66470200 { - compatible = "brcm,spi-bcm-qspi", "brcm,spi-ns2-qspi"; + compatible = "brcm,spi-ns2-qspi", "brcm,spi-bcm-qspi"; reg = <0x66470200 0x184>, <0x66470000 0x124>, <0x67017408 0x004>, --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/broadcom/stingray/stingray-usb.dtsi @@ -4,21 +4,26 @@ */ usb { compatible = "simple-bus"; - dma-ranges; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x0 0x68500000 0x00400000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0x68500000 0x0 0x00400000>; + + /* + * Internally, USB bus to the interconnect can only address up + * to 40-bit + */ + dma-ranges = <0 0 0 0 0x100 0x0>; usbphy0: usb-phy@0 { compatible = "brcm,sr-usb-combo-phy"; - reg = <0x00000000 0x100>; + reg = <0x0 0x00000000 0x0 0x100>; #phy-cells = <1>; status = "disabled"; }; xhci0: usb@1000 { compatible = "generic-xhci"; - reg = <0x00001000 0x1000>; + reg = <0x0 0x00001000 0x0 0x1000>; interrupts = ; phys = <&usbphy0 1>, <&usbphy0 0>; phy-names = "phy0", "phy1"; @@ -28,7 +33,7 @@ bdc0: usb@2000 { compatible = "brcm,bdc-v0.16"; - reg = <0x00002000 0x1000>; + reg = <0x0 0x00002000 0x0 0x1000>; interrupts = ; phys = <&usbphy0 0>, <&usbphy0 1>; phy-names = "phy0", "phy1"; @@ -38,21 +43,21 @@ usbphy1: usb-phy@10000 { compatible = "brcm,sr-usb-combo-phy"; - reg = <0x00010000 0x100>; + reg = <0x0 0x00010000 0x0 0x100>; #phy-cells = <1>; status = "disabled"; }; usbphy2: usb-phy@20000 { compatible = "brcm,sr-usb-hs-phy"; - reg = <0x00020000 0x100>; + reg = <0x0 0x00020000 0x0 0x100>; #phy-cells = <0>; status = "disabled"; }; xhci1: usb@11000 { compatible = "generic-xhci"; - reg = <0x00011000 0x1000>; + reg = <0x0 0x00011000 0x0 0x1000>; interrupts = ; phys = <&usbphy1 1>, <&usbphy2>, <&usbphy1 0>; phy-names = "phy0", "phy1", "phy2"; @@ -62,7 +67,7 @@ bdc1: usb@21000 { compatible = "brcm,bdc-v0.16"; - reg = <0x00021000 0x1000>; + reg = <0x0 0x00021000 0x0 0x1000>; interrupts = ; phys = <&usbphy2>; phy-names = "phy0"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi @@ -389,7 +389,7 @@ s2mps13-pmic@66 { compatible = "samsung,s2mps13-pmic"; interrupt-parent = <&gpa0>; - interrupts = <7 IRQ_TYPE_NONE>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; reg = <0x66>; samsung,s2mps11-wrstbi-ground; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/exynos/exynos5433.dtsi @@ -18,8 +18,8 @@ / { compatible = "samsung,exynos5433"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; interrupt-parent = <&gic>; @@ -311,7 +311,7 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x0 0x0 0x0 0x18000000>; chipid@10000000 { compatible = "samsung,exynos4210-chipid"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/exynos/exynos7-espresso.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/exynos/exynos7-espresso.dts @@ -90,7 +90,7 @@ s2mps15_pmic@66 { compatible = "samsung,s2mps15-pmic"; reg = <0x66>; - interrupts = <2 IRQ_TYPE_NONE>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpa0>; pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; @@ -157,6 +157,7 @@ regulator-min-microvolt = <700000>; regulator-max-microvolt = <1150000>; regulator-enable-ramp-delay = <125>; + regulator-always-on; }; ldo8_reg: LDO8 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/exynos/exynos7.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/exynos/exynos7.dtsi @@ -12,8 +12,8 @@ / { compatible = "samsung,exynos7"; interrupt-parent = <&gic>; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; aliases { pinctrl0 = &pinctrl_alive; @@ -90,15 +90,17 @@ }; psci { - compatible = "arm,psci-0.2"; + compatible = "arm,psci"; method = "smc"; + cpu_off = <0x84000002>; + cpu_on = <0xC4000003>; }; soc: soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0 0 0 0x18000000>; chipid@10000000 { compatible = "samsung,exynos4210-chipid"; @@ -111,7 +113,7 @@ #address-cells = <0>; interrupt-controller; reg = <0x11001000 0x1000>, - <0x11002000 0x1000>, + <0x11002000 0x2000>, <0x11004000 0x2000>, <0x11006000 0x2000>; }; @@ -494,13 +496,6 @@ pmu_system_controller: system-controller@105c0000 { compatible = "samsung,exynos7-pmu", "syscon"; reg = <0x105c0000 0x5000>; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; - mask = <0x1>; - }; }; rtc: rtc@10590000 { @@ -650,3 +645,4 @@ }; #include "exynos7-pinctrl.dtsi" +#include "arm/exynos-syscon-restart.dtsi" --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi @@ -177,6 +177,7 @@ ranges = <0x0 0x00 0x1700000 0x100000>; reg = <0x00 0x1700000 0x0 0x100000>; interrupts = ; + dma-coherent; sec_jr0: jr@10000 { compatible = "fsl,sec-v5.4-job-ring", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts @@ -161,11 +161,6 @@ vcc-supply = <&sb_3v3>; }; - rtc@51 { - compatible = "nxp,pcf2129"; - reg = <0x51>; - }; - eeprom@56 { compatible = "atmel,24c512"; reg = <0x56>; @@ -209,6 +204,15 @@ }; +&i2c1 { + status = "okay"; + + rtc@51 { + compatible = "nxp,pcf2129"; + reg = <0x51>; + }; +}; + &enetc_port1 { phy-handle = <&qds_phy1>; phy-connection-type = "rgmii-id"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -65,7 +65,7 @@ }; }; - sysclk: clock-sysclk { + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <100000000>; @@ -102,8 +102,8 @@ reboot { compatible ="syscon-reboot"; - regmap = <&dcfg>; - offset = <0xb0>; + regmap = <&rst>; + offset = <0>; mask = <0x02>; }; @@ -151,14 +151,20 @@ ddr: memory-controller@1080000 { compatible = "fsl,qoriq-memory-controller"; reg = <0x0 0x1080000 0x0 0x1000>; - interrupts = ; - big-endian; + interrupts = ; + little-endian; }; dcfg: syscon@1e00000 { compatible = "fsl,ls1028a-dcfg", "syscon"; reg = <0x0 0x1e00000 0x0 0x10000>; - big-endian; + little-endian; + }; + + rst: syscon@1e60000 { + compatible = "syscon"; + reg = <0x0 0x1e60000 0x0 0x10000>; + little-endian; }; scfg: syscon@1fc0000 { @@ -281,6 +287,24 @@ status = "disabled"; }; + can0: can@2180000 { + compatible = "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan"; + reg = <0x0 0x2180000 0x0 0x10000>; + interrupts = ; + clocks = <&sysclk>, <&clockgen 4 1>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + can1: can@2190000 { + compatible = "fsl,ls1028ar1-flexcan", "fsl,lx2160ar1-flexcan"; + reg = <0x0 0x2190000 0x0 0x10000>; + interrupts = ; + clocks = <&sysclk>, <&clockgen 4 1>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + duart0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x00 0x21c0500 0x0 0x100>; @@ -490,14 +514,14 @@ compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen 4 15>, <&clockgen 4 15>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: watchdog@c010000 { compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen 4 15>, <&clockgen 4 15>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; sai1: audio-controller@f100000 { @@ -567,7 +591,7 @@ 0x00010004 0x0000003d 0x00010005 0x00000045 0x00010006 0x0000004d - 0x00010007 0x00000045 + 0x00010007 0x00000055 0x00010008 0x0000005e 0x00010009 0x00000066 0x0001000a 0x0000006e @@ -667,7 +691,7 @@ ethernet@0,4 { compatible = "fsl,enetc-ptp"; reg = <0x000400 0 0 0 0>; - clocks = <&clockgen 4 0>; + clocks = <&clockgen 2 3>; little-endian; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1043-post.dtsi @@ -20,6 +20,8 @@ }; &fman0 { + fsl,erratum-a050385; + /* these aliases provide the FMan ports mapping */ enet0: ethernet@e0000 { }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1043a-rdb.dts @@ -119,12 +119,12 @@ ethernet@e4000 { phy-handle = <&rgmii_phy1>; - phy-connection-type = "rgmii-txid"; + phy-connection-type = "rgmii-id"; }; ethernet@e6000 { phy-handle = <&rgmii_phy2>; - phy-connection-type = "rgmii-txid"; + phy-connection-type = "rgmii-id"; }; ethernet@e8000 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -241,6 +241,7 @@ ranges = <0x0 0x00 0x1700000 0x100000>; reg = <0x00 0x1700000 0x0 0x100000>; interrupts = <0 75 0x4>; + dma-coherent; sec_jr0: jr@10000 { compatible = "fsl,sec-v5.4-job-ring", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts @@ -83,15 +83,9 @@ }; eeprom@52 { - compatible = "atmel,24c512"; + compatible = "onnn,cat24c04", "atmel,24c04"; reg = <0x52>; }; - - eeprom@53 { - compatible = "atmel,24c512"; - reg = <0x53>; - }; - }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts @@ -58,14 +58,9 @@ }; eeprom@52 { - compatible = "atmel,24c512"; + compatible = "onnn,cat24c05", "atmel,24c04"; reg = <0x52>; }; - - eeprom@53 { - compatible = "atmel,24c512"; - reg = <0x53>; - }; }; &i2c3 { @@ -127,12 +122,12 @@ &fman0 { ethernet@e4000 { phy-handle = <&rgmii_phy1>; - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; }; ethernet@e6000 { phy-handle = <&rgmii_phy2>; - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; }; ethernet@e8000 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi @@ -244,6 +244,7 @@ ranges = <0x0 0x00 0x1700000 0x100000>; reg = <0x00 0x1700000 0x0 0x100000>; interrupts = ; + dma-coherent; sec_jr0: jr@10000 { compatible = "fsl,sec-v5.4-job-ring", @@ -304,7 +305,7 @@ dcfg: dcfg@1ee0000 { compatible = "fsl,ls1046a-dcfg", "syscon"; - reg = <0x0 0x1ee0000 0x0 0x10000>; + reg = <0x0 0x1ee0000 0x0 0x1000>; big-endian; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi @@ -637,59 +637,59 @@ }; cluster1_core0_watchdog: wdt@c000000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: wdt@c010000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core2_watchdog: wdt@c020000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc020000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core3_watchdog: wdt@c030000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc030000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core0_watchdog: wdt@c100000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core1_watchdog: wdt@c110000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core2_watchdog: wdt@c120000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc120000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core3_watchdog: wdt@c130000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc130000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; fsl_mc: fsl-mc@80c000000 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -227,59 +227,59 @@ }; cluster1_core0_watchdog: wdt@c000000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc000000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster1_core1_watchdog: wdt@c010000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc010000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core0_watchdog: wdt@c100000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc100000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster2_core1_watchdog: wdt@c110000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc110000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster3_core0_watchdog: wdt@c200000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc200000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster3_core1_watchdog: wdt@c210000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc210000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster4_core0_watchdog: wdt@c300000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc300000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; cluster4_core1_watchdog: wdt@c310000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xc310000 0x0 0x1000>; clocks = <&clockgen 4 3>, <&clockgen 4 3>; - clock-names = "apb_pclk", "wdog_clk"; + clock-names = "wdog_clk", "apb_pclk"; }; crypto: crypto@8000000 { @@ -501,7 +501,6 @@ clocks = <&clockgen 4 3>; clock-names = "dspi"; spi-num-chipselects = <5>; - bus-num = <0>; }; esdhc: esdhc@2140000 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mm-evk.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mm-evk.dts @@ -62,6 +62,8 @@ cpudai: simple-audio-card,cpu { sound-dai = <&sai3>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; }; simple-audio-card,codec { @@ -229,7 +231,7 @@ ldo1_reg: LDO1 { regulator-name = "LDO1"; - regulator-min-microvolt = <3000000>; + regulator-min-microvolt = <1600000>; regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; @@ -237,7 +239,7 @@ ldo2_reg: LDO2 { regulator-name = "LDO2"; - regulator-min-microvolt = <900000>; + regulator-min-microvolt = <800000>; regulator-max-microvolt = <900000>; regulator-boot-on; regulator-always-on; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h @@ -124,7 +124,7 @@ #define MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0 #define MX8MM_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0 #define MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0 -#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0 +#define MX8MM_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0 #define MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0 #define MX8MM_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0 #define MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0 @@ -585,7 +585,7 @@ #define MX8MM_IOMUXC_UART1_RXD_GPIO5_IO22 0x234 0x49C 0x000 0x5 0x0 #define MX8MM_IOMUXC_UART1_RXD_TPSMP_HDATA24 0x234 0x49C 0x000 0x7 0x0 #define MX8MM_IOMUXC_UART1_TXD_UART1_DCE_TX 0x238 0x4A0 0x000 0x0 0x0 -#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x0 +#define MX8MM_IOMUXC_UART1_TXD_UART1_DTE_RX 0x238 0x4A0 0x4F4 0x0 0x1 #define MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x238 0x4A0 0x000 0x1 0x0 #define MX8MM_IOMUXC_UART1_TXD_GPIO5_IO23 0x238 0x4A0 0x000 0x5 0x0 #define MX8MM_IOMUXC_UART1_TXD_TPSMP_HDATA25 0x238 0x4A0 0x000 0x7 0x0 --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -126,7 +126,7 @@ opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; - opp-microvolt = <900000>; + opp-microvolt = <950000>; opp-supported-hw = <0xc>, <0x7>; clock-latency-ns = <150000>; opp-suspend; @@ -479,14 +479,18 @@ <&clk IMX8MM_CLK_AUDIO_AHB>, <&clk IMX8MM_CLK_IPG_AUDIO_ROOT>, <&clk IMX8MM_SYS_PLL3>, - <&clk IMX8MM_VIDEO_PLL1>; + <&clk IMX8MM_VIDEO_PLL1>, + <&clk IMX8MM_AUDIO_PLL1>, + <&clk IMX8MM_AUDIO_PLL2>; assigned-clock-parents = <&clk IMX8MM_SYS_PLL3_OUT>, <&clk IMX8MM_SYS_PLL1_800M>; assigned-clock-rates = <0>, <400000000>, <400000000>, <750000000>, - <594000000>; + <594000000>, + <393216000>, + <361267200>; }; src: reset-controller@30390000 { @@ -741,7 +745,7 @@ reg = <0x30bd0000 0x10000>; interrupts = ; clocks = <&clk IMX8MM_CLK_SDMA1_ROOT>, - <&clk IMX8MM_CLK_SDMA1_ROOT>; + <&clk IMX8MM_CLK_AHB>; clock-names = "ipg", "ahb"; #dma-cells = <3>; fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; @@ -834,10 +838,10 @@ clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>; }; - gpmi: nand-controller@33002000{ + gpmi: nand-controller@33002000 { compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts @@ -213,6 +213,10 @@ interrupts = <3 GPIO_ACTIVE_LOW>; rohm,reset-snvs-powered; + #clock-cells = <0>; + clocks = <&osc_32k 0>; + clock-output-names = "clk-32k-out"; + regulators { buck1_reg: BUCK1 { regulator-name = "BUCK1"; @@ -268,7 +272,7 @@ ldo1_reg: LDO1 { regulator-name = "LDO1"; - regulator-min-microvolt = <3000000>; + regulator-min-microvolt = <1600000>; regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; @@ -276,7 +280,7 @@ ldo2_reg: LDO2 { regulator-name = "LDO2"; - regulator-min-microvolt = <900000>; + regulator-min-microvolt = <800000>; regulator-max-microvolt = <900000>; regulator-boot-on; regulator-always-on; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mn.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mn.dtsi @@ -616,7 +616,7 @@ reg = <0x30bd0000 0x10000>; interrupts = ; clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>, - <&clk IMX8MN_CLK_SDMA1_ROOT>; + <&clk IMX8MN_CLK_AHB>; clock-names = "ipg", "ahb"; #dma-cells = <3>; fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; @@ -677,28 +677,6 @@ #index-cells = <1>; reg = <0x32e40200 0x200>; }; - - usbotg2: usb@32e50000 { - compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb"; - reg = <0x32e50000 0x200>; - interrupts = ; - clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>; - clock-names = "usb1_ctrl_root_clk"; - assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>, - <&clk IMX8MN_CLK_USB_CORE_REF>; - assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>, - <&clk IMX8MN_SYS_PLL1_100M>; - fsl,usbphy = <&usbphynop2>; - fsl,usbmisc = <&usbmisc2 0>; - status = "disabled"; - }; - - usbmisc2: usbmisc@32e50200 { - compatible = "fsl,imx8mn-usbmisc", "fsl,imx7d-usbmisc"; - #index-cells = <1>; - reg = <0x32e50200 0x200>; - }; - }; dma_apbh: dma-controller@33000000 { @@ -717,7 +695,7 @@ gpmi: nand-controller@33002000 { compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; @@ -744,14 +722,6 @@ compatible = "usb-nop-xceiv"; clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; - assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>; - clock-names = "main_clk"; - }; - - usbphynop2: usbphynop2 { - compatible = "usb-nop-xceiv"; - clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; - assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>; clock-names = "main_clk"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts @@ -421,7 +421,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_imu>; interrupt-parent = <&gpio3>; - interrupts = <19 IRQ_TYPE_LEVEL_LOW>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; vdd-supply = <®_3v3_p>; vddio-supply = <®_3v3_p>; }; @@ -743,6 +743,7 @@ }; &usb3_phy0 { + vbus-supply = <®_5v_p>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mq-pinfunc.h @@ -130,7 +130,7 @@ #define MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0x0A4 0x30C 0x000 0x0 0x0 #define MX8MQ_IOMUXC_SD1_CMD_GPIO2_IO1 0x0A4 0x30C 0x000 0x5 0x0 #define MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x0A8 0x310 0x000 0x0 0x0 -#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x31 0x000 0x5 0x0 +#define MX8MQ_IOMUXC_SD1_DATA0_GPIO2_IO2 0x0A8 0x310 0x000 0x5 0x0 #define MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x0AC 0x314 0x000 0x0 0x0 #define MX8MQ_IOMUXC_SD1_DATA1_GPIO2_IO3 0x0AC 0x314 0x000 0x5 0x0 #define MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x0B0 0x318 0x000 0x0 0x0 --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi @@ -45,8 +45,8 @@ reg_12p0_main: regulator-12p0-main { compatible = "regulator-fixed"; regulator-name = "12V_MAIN"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; regulator-always-on; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -349,7 +349,7 @@ tmu: tmu@30260000 { compatible = "fsl,imx8mq-tmu"; reg = <0x30260000 0x10000>; - interrupt = ; + interrupts = ; clocks = <&clk IMX8MQ_CLK_TMU_ROOT>; little-endian; fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>; @@ -516,6 +516,7 @@ gpc: gpc@303a0000 { compatible = "fsl,imx8mq-gpc"; reg = <0x303a0000 0x10000>; + interrupts = ; interrupt-parent = <&gic>; interrupt-controller; #interrupt-cells = <3>; @@ -1055,6 +1056,14 @@ <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>, <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; + assigned-clocks = <&clk IMX8MQ_CLK_PCIE1_CTRL>, + <&clk IMX8MQ_CLK_PCIE1_PHY>, + <&clk IMX8MQ_CLK_PCIE1_AUX>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; + assigned-clock-rates = <250000000>, <100000000>, + <10000000>; status = "disabled"; }; @@ -1084,6 +1093,14 @@ <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_EN>, <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; + assigned-clocks = <&clk IMX8MQ_CLK_PCIE2_CTRL>, + <&clk IMX8MQ_CLK_PCIE2_PHY>, + <&clk IMX8MQ_CLK_PCIE2_AUX>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; + assigned-clock-rates = <250000000>, <100000000>, + <10000000>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts @@ -52,11 +52,6 @@ compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; }; - - ethphy1: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <1>; - }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts @@ -530,6 +530,17 @@ status = "ok"; compatible = "adi,adv7533"; reg = <0x39>; + adi,dsi-lanes = <4>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + }; + port@1 { + reg = <1>; + }; + }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/hisilicon/hi3660.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/hisilicon/hi3660.dtsi @@ -1086,7 +1086,7 @@ }; watchdog0: watchdog@e8a06000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xe8a06000 0x0 0x1000>; interrupts = ; clocks = <&crg_ctrl HI3660_OSC32K>; @@ -1094,7 +1094,7 @@ }; watchdog1: watchdog@e8a07000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xe8a07000 0x0 0x1000>; interrupts = ; clocks = <&crg_ctrl HI3660_OSC32K>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi @@ -58,7 +58,7 @@ gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; reg = <0x0 0xf1001000 0x0 0x1000>, /* GICD */ - <0x0 0xf1002000 0x0 0x100>; /* GICC */ + <0x0 0xf1002000 0x0 0x2000>; /* GICC */ #address-cells = <0>; #interrupt-cells = <3>; interrupt-controller; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/hisilicon/hi6220-hikey.dts @@ -516,7 +516,7 @@ reg = <0x39>; interrupt-parent = <&gpio1>; interrupts = <1 2>; - pd-gpio = <&gpio0 4 0>; + pd-gpios = <&gpio0 4 0>; adi,dsi-lanes = <4>; #sound-dai-cells = <0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/hisilicon/hi6220.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/hisilicon/hi6220.dtsi @@ -839,7 +839,7 @@ }; watchdog0: watchdog@f8005000 { - compatible = "arm,sp805-wdt", "arm,primecell"; + compatible = "arm,sp805", "arm,primecell"; reg = <0x0 0xf8005000 0x0 0x1000>; interrupts = ; clocks = <&ao_ctrl HI6220_WDT0_PCLK>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/intel/socfpga_agilex.dtsi @@ -47,10 +47,10 @@ pmu { compatible = "arm,armv8-pmuv3"; - interrupts = <0 120 8>, - <0 121 8>, - <0 122 8>, - <0 123 8>; + interrupts = <0 170 4>, + <0 171 4>, + <0 172 4>, + <0 173 4>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, @@ -82,7 +82,7 @@ ranges = <0 0 0 0xffffffff>; gmac0: ethernet@ff800000 { - compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; reg = <0xff800000 0x2000>; interrupts = <0 90 4>; interrupt-names = "macirq"; @@ -97,7 +97,7 @@ }; gmac1: ethernet@ff802000 { - compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; reg = <0xff802000 0x2000>; interrupts = <0 91 4>; interrupt-names = "macirq"; @@ -112,7 +112,7 @@ }; gmac2: ethernet@ff804000 { - compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; reg = <0xff804000 0x2000>; interrupts = <0 92 4>; interrupt-names = "macirq"; @@ -369,7 +369,7 @@ }; usb0: usb@ffb00000 { - compatible = "snps,dwc2"; + compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2"; reg = <0xffb00000 0x40000>; interrupts = <0 93 4>; phys = <&usbphy0>; @@ -381,7 +381,7 @@ }; usb1: usb@ffb40000 { - compatible = "snps,dwc2"; + compatible = "intel,socfpga-agilex-hsotg", "snps,dwc2"; reg = <0xffb40000 0x40000>; interrupts = <0 94 4>; phys = <&usbphy0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-3720-db.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-3720-db.dts @@ -128,6 +128,9 @@ /* CON15(V2.0)/CON17(V1.4) : PCIe / CON15(V2.0)/CON12(V1.4) :mini-PCIe */ &pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; + reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts @@ -19,6 +19,16 @@ model = "Globalscale Marvell ESPRESSOBin Board"; compatible = "globalscale,espressobin", "marvell,armada3720", "marvell,armada3710"; + aliases { + ethernet0 = ð0; + /* for dsa slave device */ + ethernet1 = &switch0port1; + ethernet2 = &switch0port2; + ethernet3 = &switch0port3; + serial0 = &uart0; + serial1 = &uart1; + }; + chosen { stdout-path = "serial0:115200n8"; }; @@ -49,6 +59,7 @@ phys = <&comphy1 0>; pinctrl-names = "default"; pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; + reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; }; /* J6 */ @@ -141,7 +152,7 @@ #address-cells = <1>; #size-cells = <0>; - port@0 { + switch0port0: port@0 { reg = <0>; label = "cpu"; ethernet = <ð0>; @@ -152,19 +163,19 @@ }; }; - port@1 { + switch0port1: port@1 { reg = <1>; label = "wan"; phy-handle = <&switch0phy0>; }; - port@2 { + switch0port2: port@2 { reg = <2>; label = "lan0"; phy-handle = <&switch0phy1>; }; - port@3 { + switch0port3: port@3 { reg = <3>; label = "lan1"; phy-handle = <&switch0phy2>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts @@ -18,6 +18,7 @@ aliases { spi0 = &spi0; + ethernet0 = ð0; ethernet1 = ð1; }; @@ -95,7 +96,7 @@ }; sfp: sfp { - compatible = "sff,sfp+"; + compatible = "sff,sfp"; i2c-bus = <&i2c0>; los-gpio = <&moxtet_sfp 0 GPIO_ACTIVE_HIGH>; tx-fault-gpio = <&moxtet_sfp 1 GPIO_ACTIVE_HIGH>; @@ -106,24 +107,30 @@ /* enabled by U-Boot if SFP module is present */ status = "disabled"; }; + + firmware { + armada-3700-rwtm { + compatible = "marvell,armada-3700-rwtm-firmware", "cznic,turris-mox-rwtm"; + }; + }; }; &i2c0 { pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>; clock-frequency = <100000>; + /delete-property/ mrvl,i2c-fast-mode; status = "okay"; + /* MCP7940MT-I/MNY RTC */ rtc@6f { compatible = "microchip,mcp7940x"; reg = <0x6f>; + interrupt-parent = <&gpiosb>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO2_5 */ }; }; -&pcie_reset_pins { - function = "gpio"; -}; - &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; @@ -131,6 +138,28 @@ max-link-speed = <2>; reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; phys = <&comphy1 0>; + /* + * U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property + * contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and + * 2 size cells and also expects that the second range starts at 16 MB offset. Also it + * expects that first range uses same address for PCI (child) and CPU (parent) cells (so + * no remapping) and that this address is the lowest from all specified ranges. If these + * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address + * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window + * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB. + * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in + * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix): + * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7 + * https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf + * https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33 + * Bug related to requirement of same child and parent addresses for first range is fixed + * in U-Boot version 2022.04 by following commit: + * https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17 + */ + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x81000000 0 0xe8000000 0 0xe8000000 0 0x01000000 /* Port 0 IO */ + 0x82000000 0 0xe9000000 0 0xe9000000 0 0x07000000>; /* Port 0 MEM */ /* enabled by U-Boot if PCIe module is present */ status = "disabled"; @@ -144,7 +173,7 @@ pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; phy-mode = "rgmii-id"; - phy = <&phy1>; + phy-handle = <&phy1>; status = "okay"; }; @@ -171,6 +200,8 @@ marvell,pad-type = "sd"; vqmmc-supply = <&vsdio_reg>; mmc-pwrseq = <&sdhci1_pwrseq>; + /* forbid SDR104 for FCC purposes */ + sdhci-caps-mask = <0x2 0x0>; status = "okay"; }; @@ -200,7 +231,7 @@ }; partition@20000 { - label = "u-boot"; + label = "a53-firmware"; reg = <0x20000 0x160000>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts @@ -143,6 +143,7 @@ phy-mode = "sgmii"; status = "okay"; managed = "in-band-status"; + phys = <&comphy1 0>; sfp = <&sfp_eth0>; }; @@ -150,11 +151,14 @@ phy-mode = "sgmii"; status = "okay"; managed = "in-band-status"; + phys = <&comphy0 1>; sfp = <&sfp_eth1>; }; &usb3 { status = "okay"; + phys = <&usb2_utmi_otg_phy>; + phy-names = "usb2-utmi-otg-phy"; }; &uart0 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -134,7 +134,7 @@ uart0: serial@12000 { compatible = "marvell,armada-3700-uart"; - reg = <0x12000 0x200>; + reg = <0x12000 0x18>; clocks = <&xtalclk>; interrupts = , @@ -156,7 +156,8 @@ }; nb_periph_clk: nb-periph-clk@13000 { - compatible = "marvell,armada-3700-periph-clock-nb"; + compatible = "marvell,armada-3700-periph-clock-nb", + "syscon"; reg = <0x13000 0x100>; clocks = <&tbg 0>, <&tbg 1>, <&tbg 2>, <&tbg 3>, <&xtalclk>; @@ -317,7 +318,7 @@ pcie_reset_pins: pcie-reset-pins { groups = "pcie1"; - function = "pcie"; + function = "gpio"; }; pcie_clkreq_pins: pcie-clkreq-pins { @@ -486,8 +487,15 @@ #interrupt-cells = <1>; msi-parent = <&pcie0>; msi-controller; - ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ - 0x81000000 0 0xe9000000 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ + /* + * The 128 MiB address range [0xe8000000-0xf0000000] is + * dedicated for PCIe and can be assigned to 8 windows + * with size a power of two. Use one 64 KiB window for + * IO at the end and the remaining seven windows + * (totaling 127 MiB) for MEM. + */ + ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x07f00000 /* Port 0 MEM */ + 0x81000000 0 0x00000000 0 0xefff0000 0 0x00010000>; /* Port 0 IO */ interrupt-map-mask = <0 0 0 7>; interrupt-map = <0 0 0 1 &pcie_intc 0>, <0 0 0 2 &pcie_intc 1>, @@ -499,4 +507,12 @@ }; }; }; + + firmware { + armada-3700-rwtm { + compatible = "marvell,armada-3700-rwtm-firmware"; + mboxes = <&rwtm 0>; + status = "okay"; + }; + }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts @@ -367,6 +367,7 @@ pinctrl-0 = <&cp0_copper_eth_phy_reset>; reset-gpios = <&cp0_gpio2 11 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; + reset-deassert-us = <10000>; }; switch0: switch0@4 { @@ -408,6 +409,8 @@ reg = <5>; label = "cpu"; ethernet = <&cp1_eth2>; + phy-mode = "2500base-x"; + managed = "in-band-status"; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi @@ -71,6 +71,7 @@ tx-fault-gpio = <&cp1_gpio1 26 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp1_sfpp0_pins>; + maximum-power-milliwatt = <2000>; }; sfp_eth1: sfp-eth1 { @@ -83,6 +84,7 @@ tx-fault-gpio = <&cp0_gpio2 30 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp1_sfpp1_pins &cp0_sfpp1_pins>; + maximum-power-milliwatt = <2000>; }; sfp_eth3: sfp-eth3 { @@ -95,6 +97,7 @@ tx-fault-gpio = <&cp0_gpio2 19 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&cp0_sfp_1g_pins &cp1_sfp_1g_pins>; + maximum-power-milliwatt = <2000>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi @@ -21,6 +21,7 @@ reg = <0x000>; enable-method = "psci"; #cooling-cells = <2>; + clocks = <&cpu_clk 0>; }; cpu1: cpu@1 { device_type = "cpu"; @@ -28,6 +29,7 @@ reg = <0x001>; enable-method = "psci"; #cooling-cells = <2>; + clocks = <&cpu_clk 0>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/marvell/armada-cp110.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/marvell/armada-cp110.dtsi @@ -438,10 +438,10 @@ CP110_LABEL(nand_controller): nand@720000 { /* - * Due to the limitation of the pins available - * this controller is only usable on the CPM - * for A7K and on the CPS for A8K. - */ + * Due to the limitation of the pins available + * this controller is only usable on the CPM + * for A7K and on the CPS for A8K. + */ compatible = "marvell,armada-8k-nand-controller", "marvell,armada370-nand-controller"; reg = <0x720000 0x54>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt2712-evb.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt2712-evb.dts @@ -26,14 +26,14 @@ stdout-path = "serial0:921600n8"; }; - cpus_fixed_vproc0: fixedregulator@0 { + cpus_fixed_vproc0: regulator-vproc-buck0 { compatible = "regulator-fixed"; regulator-name = "vproc_buck0"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; }; - cpus_fixed_vproc1: fixedregulator@1 { + cpus_fixed_vproc1: regulator-vproc-buck1 { compatible = "regulator-fixed"; regulator-name = "vproc_buck1"; regulator-min-microvolt = <1000000>; @@ -50,7 +50,7 @@ id-gpio = <&pio 14 GPIO_ACTIVE_HIGH>; }; - usb_p0_vbus: regulator@2 { + usb_p0_vbus: regulator-usb-p0-vbus { compatible = "regulator-fixed"; regulator-name = "p0_vbus"; regulator-min-microvolt = <5000000>; @@ -59,7 +59,7 @@ enable-active-high; }; - usb_p1_vbus: regulator@3 { + usb_p1_vbus: regulator-usb-p1-vbus { compatible = "regulator-fixed"; regulator-name = "p1_vbus"; regulator-min-microvolt = <5000000>; @@ -68,7 +68,7 @@ enable-active-high; }; - usb_p2_vbus: regulator@4 { + usb_p2_vbus: regulator-usb-p2-vbus { compatible = "regulator-fixed"; regulator-name = "p2_vbus"; regulator-min-microvolt = <5000000>; @@ -77,7 +77,7 @@ enable-active-high; }; - usb_p3_vbus: regulator@5 { + usb_p3_vbus: regulator-usb-p3-vbus { compatible = "regulator-fixed"; regulator-name = "p3_vbus"; regulator-min-microvolt = <5000000>; @@ -105,15 +105,89 @@ proc-supply = <&cpus_fixed_vproc1>; }; +ð { + phy-mode ="rgmii-rxid"; + phy-handle = <ðernet_phy0>; + mediatek,tx-delay-ps = <1530>; + snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <ð_default>; + pinctrl-1 = <ð_sleep>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + ethernet_phy0: ethernet-phy@5 { + compatible = "ethernet-phy-id0243.0d90"; + reg = <0x5>; + }; + }; +}; + &pio { - usb0_id_pins_float: usb0_iddig { + eth_default: eth-default-pins { + tx_pins { + pinmux = , + , + , + , + , + ; + drive-strength = ; + }; + rx_pins { + pinmux = , + , + , + , + , + ; + input-enable; + }; + mdio_pins { + pinmux = , + ; + drive-strength = ; + input-enable; + }; + }; + + eth_sleep: eth-sleep-pins { + tx_pins { + pinmux = , + , + , + , + , + ; + }; + rx_pins { + pinmux = , + , + , + , + , + ; + input-disable; + }; + mdio_pins { + pinmux = , + ; + input-disable; + bias-disable; + }; + }; + + usb0_id_pins_float: usb0-iddig-pins { pins_iddig { pinmux = ; bias-pull-up; }; }; - usb1_id_pins_float: usb1_iddig { + usb1_id_pins_float: usb1-iddig-pins { pins_iddig { pinmux = ; bias-pull-up; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt2712e.dtsi @@ -160,70 +160,70 @@ #clock-cells = <0>; }; - clk26m: oscillator@0 { + clk26m: oscillator-26m { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <26000000>; clock-output-names = "clk26m"; }; - clk32k: oscillator@1 { + clk32k: oscillator-32k { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32768>; clock-output-names = "clk32k"; }; - clkfpc: oscillator@2 { + clkfpc: oscillator-50m { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <50000000>; clock-output-names = "clkfpc"; }; - clkaud_ext_i_0: oscillator@3 { + clkaud_ext_i_0: oscillator-aud0 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <6500000>; clock-output-names = "clkaud_ext_i_0"; }; - clkaud_ext_i_1: oscillator@4 { + clkaud_ext_i_1: oscillator-aud1 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <196608000>; clock-output-names = "clkaud_ext_i_1"; }; - clkaud_ext_i_2: oscillator@5 { + clkaud_ext_i_2: oscillator-aud2 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <180633600>; clock-output-names = "clkaud_ext_i_2"; }; - clki2si0_mck_i: oscillator@6 { + clki2si0_mck_i: oscillator-i2s0 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <30000000>; clock-output-names = "clki2si0_mck_i"; }; - clki2si1_mck_i: oscillator@7 { + clki2si1_mck_i: oscillator-i2s1 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <30000000>; clock-output-names = "clki2si1_mck_i"; }; - clki2si2_mck_i: oscillator@8 { + clki2si2_mck_i: oscillator-i2s2 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <30000000>; clock-output-names = "clki2si2_mck_i"; }; - clktdmin_mclk_i: oscillator@9 { + clktdmin_mclk_i: oscillator-mclk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <30000000>; @@ -249,10 +249,11 @@ #clock-cells = <1>; }; - infracfg: syscon@10001000 { + infracfg: clock-controller@10001000 { compatible = "mediatek,mt2712-infracfg", "syscon"; reg = <0 0x10001000 0 0x1000>; #clock-cells = <1>; + #reset-cells = <1>; }; pericfg: syscon@10003000 { @@ -266,7 +267,7 @@ reg = <0 0x10005000 0 0x1000>; }; - pio: pinctrl@10005000 { + pio: pinctrl@1000b000 { compatible = "mediatek,mt2712-pinctrl"; reg = <0 0x1000b000 0 0x1000>; mediatek,pctl-regmap = <&syscfg_pctl_a>; @@ -632,6 +633,71 @@ status = "disabled"; }; + stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <0x7>; + snps,rd_osr_lmt = <0x7>; + snps,blen = <0 0 0 0 16 8 4>; + }; + + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + snps,rx-sched-sp; + queue0 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x0>; + snps,priority = <0x0>; + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <3>; + snps,tx-sched-wrr; + queue0 { + snps,weight = <0x10>; + snps,dcb-algorithm; + snps,priority = <0x0>; + }; + queue1 { + snps,weight = <0x11>; + snps,dcb-algorithm; + snps,priority = <0x1>; + }; + queue2 { + snps,weight = <0x12>; + snps,dcb-algorithm; + snps,priority = <0x2>; + }; + }; + + eth: ethernet@1101c000 { + compatible = "mediatek,mt2712-gmac"; + reg = <0 0x1101c000 0 0x1300>; + interrupts = ; + interrupt-names = "macirq"; + mac-address = [00 55 7b b5 7d f7]; + clock-names = "axi", + "apb", + "mac_main", + "ptp_ref"; + clocks = <&pericfg CLK_PERI_GMAC>, + <&pericfg CLK_PERI_GMAC_PCLK>, + <&topckgen CLK_TOP_ETHER_125M_SEL>, + <&topckgen CLK_TOP_ETHER_50M_SEL>; + assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>, + <&topckgen CLK_TOP_ETHER_50M_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>, + <&topckgen CLK_TOP_APLL1_D3>; + power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>; + mediatek,pericfg = <&pericfg>; + snps,axi-config = <&stmmac_axi_setup>; + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; + snps,txpbl = <1>; + snps,rxpbl = <1>; + clk_csr = <0>; + status = "disabled"; + }; + mmc0: mmc@11230000 { compatible = "mediatek,mt2712-mmc"; reg = <0 0x11230000 0 0x1000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt6797.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt6797.dtsi @@ -102,7 +102,7 @@ }; }; - clk26m: oscillator@0 { + clk26m: oscillator-26m { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <26000000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts @@ -49,7 +49,7 @@ wps { label = "wps"; linux,code = ; - gpios = <&pio 102 GPIO_ACTIVE_HIGH>; + gpios = <&pio 102 GPIO_ACTIVE_LOW>; }; }; @@ -69,8 +69,9 @@ }; }; - memory { + memory@40000000 { reg = <0 0x40000000 0 0x40000000>; + device_type = "memory"; }; reg_1p8v: regulator-1p8v { @@ -234,8 +235,8 @@ /* eMMC is shared pin with parallel NAND */ emmc_pins_default: emmc-pins-default { mux { - function = "emmc", "emmc_rst"; - groups = "emmc"; + function = "emmc"; + groups = "emmc", "emmc_rst"; }; /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts @@ -55,8 +55,9 @@ }; }; - memory { + memory@40000000 { reg = <0 0x40000000 0 0x20000000>; + device_type = "memory"; }; reg_1p8v: regulator-1p8v { @@ -197,8 +198,8 @@ /* eMMC is shared pin with parallel NAND */ emmc_pins_default: emmc-pins-default { mux { - function = "emmc", "emmc_rst"; - groups = "emmc"; + function = "emmc"; + groups = "emmc", "emmc_rst"; }; /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt7622.dtsi @@ -244,7 +244,7 @@ clock-names = "hif_sel"; }; - cir: cir@10009000 { + cir: ir-receiver@10009000 { compatible = "mediatek,mt7622-cir"; reg = <0 0x10009000 0 0x1000>; interrupts = ; @@ -428,6 +428,7 @@ pwm: pwm@11006000 { compatible = "mediatek,mt7622-pwm"; reg = <0 0x11006000 0 0x1000>; + #pwm-cells = <2>; interrupts = ; clocks = <&topckgen CLK_TOP_PWM_SEL>, <&pericfg CLK_PERI_PWM_PD>, @@ -506,7 +507,6 @@ <&pericfg CLK_PERI_AUXADC_PD>; clock-names = "therm", "auxadc"; resets = <&pericfg MT7622_PERI_THERM_SW_RST>; - reset-names = "therm"; mediatek,auxadc = <&auxadc>; mediatek,apmixedsys = <&apmixedsys>; nvmem-cells = <&thermal_calibration>; @@ -686,6 +686,8 @@ clocks = <&pericfg CLK_PERI_MSDC30_0_PD>, <&topckgen CLK_TOP_MSDC50_0_SEL>; clock-names = "source", "hclk"; + resets = <&pericfg MT7622_PERI_MSDC0_SW_RST>; + reset-names = "hrst"; status = "disabled"; }; @@ -696,6 +698,8 @@ clocks = <&pericfg CLK_PERI_MSDC30_1_PD>, <&topckgen CLK_TOP_AXI_SEL>; clock-names = "source", "hclk"; + resets = <&pericfg MT7622_PERI_MSDC1_SW_RST>; + reset-names = "hrst"; status = "disabled"; }; @@ -896,9 +900,7 @@ }; eth: ethernet@1b100000 { - compatible = "mediatek,mt7622-eth", - "mediatek,mt2701-eth", - "syscon"; + compatible = "mediatek,mt7622-eth"; reg = <0 0x1b100000 0 0x20000>; interrupts = , , --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt8173-evb.dts @@ -43,7 +43,7 @@ id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>; }; - usb_p1_vbus: regulator@0 { + usb_p1_vbus: regulator-usb-p1 { compatible = "regulator-fixed"; regulator-name = "usb_vbus"; regulator-min-microvolt = <5000000>; @@ -52,7 +52,7 @@ enable-active-high; }; - usb_p0_vbus: regulator@1 { + usb_p0_vbus: regulator-usb-p0 { compatible = "regulator-fixed"; regulator-name = "vbus"; regulator-min-microvolt = <5000000>; @@ -303,11 +303,10 @@ interrupt-controller; #interrupt-cells = <2>; - mt6397regulator: mt6397regulator { + regulators { compatible = "mediatek,mt6397-regulator"; mt6397_vpca15_reg: buck_vpca15 { - regulator-compatible = "buck_vpca15"; regulator-name = "vpca15"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -316,7 +315,6 @@ }; mt6397_vpca7_reg: buck_vpca7 { - regulator-compatible = "buck_vpca7"; regulator-name = "vpca7"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -325,7 +323,6 @@ }; mt6397_vsramca15_reg: buck_vsramca15 { - regulator-compatible = "buck_vsramca15"; regulator-name = "vsramca15"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -334,7 +331,6 @@ }; mt6397_vsramca7_reg: buck_vsramca7 { - regulator-compatible = "buck_vsramca7"; regulator-name = "vsramca7"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -343,7 +339,6 @@ }; mt6397_vcore_reg: buck_vcore { - regulator-compatible = "buck_vcore"; regulator-name = "vcore"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -352,7 +347,6 @@ }; mt6397_vgpu_reg: buck_vgpu { - regulator-compatible = "buck_vgpu"; regulator-name = "vgpu"; regulator-min-microvolt = < 700000>; regulator-max-microvolt = <1350000>; @@ -361,7 +355,6 @@ }; mt6397_vdrm_reg: buck_vdrm { - regulator-compatible = "buck_vdrm"; regulator-name = "vdrm"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1400000>; @@ -370,7 +363,6 @@ }; mt6397_vio18_reg: buck_vio18 { - regulator-compatible = "buck_vio18"; regulator-name = "vio18"; regulator-min-microvolt = <1620000>; regulator-max-microvolt = <1980000>; @@ -379,19 +371,16 @@ }; mt6397_vtcxo_reg: ldo_vtcxo { - regulator-compatible = "ldo_vtcxo"; regulator-name = "vtcxo"; regulator-always-on; }; mt6397_va28_reg: ldo_va28 { - regulator-compatible = "ldo_va28"; regulator-name = "va28"; regulator-always-on; }; mt6397_vcama_reg: ldo_vcama { - regulator-compatible = "ldo_vcama"; regulator-name = "vcama"; regulator-min-microvolt = <1500000>; regulator-max-microvolt = <2800000>; @@ -399,18 +388,15 @@ }; mt6397_vio28_reg: ldo_vio28 { - regulator-compatible = "ldo_vio28"; regulator-name = "vio28"; regulator-always-on; }; mt6397_vusb_reg: ldo_vusb { - regulator-compatible = "ldo_vusb"; regulator-name = "vusb"; }; mt6397_vmc_reg: ldo_vmc { - regulator-compatible = "ldo_vmc"; regulator-name = "vmc"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; @@ -418,7 +404,6 @@ }; mt6397_vmch_reg: ldo_vmch { - regulator-compatible = "ldo_vmch"; regulator-name = "vmch"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3300000>; @@ -426,7 +411,6 @@ }; mt6397_vemc_3v3_reg: ldo_vemc3v3 { - regulator-compatible = "ldo_vemc3v3"; regulator-name = "vemc_3v3"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3300000>; @@ -434,7 +418,6 @@ }; mt6397_vgp1_reg: ldo_vgp1 { - regulator-compatible = "ldo_vgp1"; regulator-name = "vcamd"; regulator-min-microvolt = <1220000>; regulator-max-microvolt = <3300000>; @@ -442,7 +425,6 @@ }; mt6397_vgp2_reg: ldo_vgp2 { - regulator-compatible = "ldo_vgp2"; regulator-name = "vcamio"; regulator-min-microvolt = <1000000>; regulator-max-microvolt = <3300000>; @@ -450,7 +432,6 @@ }; mt6397_vgp3_reg: ldo_vgp3 { - regulator-compatible = "ldo_vgp3"; regulator-name = "vcamaf"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <3300000>; @@ -458,7 +439,6 @@ }; mt6397_vgp4_reg: ldo_vgp4 { - regulator-compatible = "ldo_vgp4"; regulator-name = "vgp4"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <3300000>; @@ -466,7 +446,6 @@ }; mt6397_vgp5_reg: ldo_vgp5 { - regulator-compatible = "ldo_vgp5"; regulator-name = "vgp5"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <3000000>; @@ -474,7 +453,6 @@ }; mt6397_vgp6_reg: ldo_vgp6 { - regulator-compatible = "ldo_vgp6"; regulator-name = "vgp6"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <3300000>; @@ -482,7 +460,6 @@ }; mt6397_vibr_reg: ldo_vibr { - regulator-compatible = "ldo_vibr"; regulator-name = "vibr"; regulator-min-microvolt = <1300000>; regulator-max-microvolt = <3300000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -238,21 +238,21 @@ cpu_on = <0x84000003>; }; - clk26m: oscillator@0 { + clk26m: oscillator0 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <26000000>; clock-output-names = "clk26m"; }; - clk32k: oscillator@1 { + clk32k: oscillator1 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32000>; clock-output-names = "clk32k"; }; - cpum_ck: oscillator@2 { + cpum_ck: oscillator2 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -268,19 +268,19 @@ sustainable-power = <1500>; /* milliwatts */ trips { - threshold: trip-point@0 { + threshold: trip-point0 { temperature = <68000>; hysteresis = <2000>; type = "passive"; }; - target: trip-point@1 { + target: trip-point1 { temperature = <85000>; hysteresis = <2000>; type = "passive"; }; - cpu_crit: cpu_crit@0 { + cpu_crit: cpu_crit0 { temperature = <115000>; hysteresis = <2000>; type = "critical"; @@ -288,13 +288,13 @@ }; cooling-maps { - map@0 { + map0 { trip = <&target>; cooling-device = <&cpu0 0 0>, <&cpu1 0 0>; contribution = <3072>; }; - map@1 { + map1 { trip = <&target>; cooling-device = <&cpu2 0 0>, <&cpu3 0 0>; @@ -308,7 +308,7 @@ #address-cells = <2>; #size-cells = <2>; ranges; - vpu_dma_reserved: vpu_dma_mem_region { + vpu_dma_reserved: vpu_dma_mem_region@b7000000 { compatible = "shared-dma-pool"; reg = <0 0xb7000000 0 0x500000>; alignment = <0x1000>; @@ -360,7 +360,7 @@ reg = <0 0x10005000 0 0x1000>; }; - pio: pinctrl@10005000 { + pio: pinctrl@1000b000 { compatible = "mediatek,mt8173-pinctrl"; reg = <0 0x1000b000 0 0x1000>; mediatek,pctl-regmap = <&syscfg_pctl_a>; @@ -567,7 +567,7 @@ status = "disabled"; }; - gic: interrupt-controller@10220000 { + gic: interrupt-controller@10221000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; interrupt-parent = <&gic>; @@ -1137,7 +1137,7 @@ <&mmsys CLK_MM_DSI1_DIGITAL>, <&mipi_tx1>; clock-names = "engine", "digital", "hs"; - phy = <&mipi_tx1>; + phys = <&mipi_tx1>; phy-names = "dphy"; status = "disabled"; }; @@ -1397,8 +1397,8 @@ "venc_lt_sel"; assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>, <&topckgen CLK_TOP_VENC_LT_SEL>; - assigned-clock-parents = <&topckgen CLK_TOP_VENCPLL_D2>, - <&topckgen CLK_TOP_UNIVPLL1_D2>; + assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>, + <&topckgen CLK_TOP_VCODECPLL_370P5>; }; vencltsys: clock-controller@19000000 { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts @@ -9,8 +9,8 @@ compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124"; aliases { - rtc0 = "/i2c@7000d000/as3722@40"; - rtc1 = "/rtc@7000e000"; + rtc0 = &as3722; + rtc1 = &tegra_rtc; serial0 = &uarta; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra132.dtsi @@ -569,7 +569,7 @@ status = "disabled"; }; - rtc@7000e000 { + tegra_rtc: rtc@7000e000 { compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc"; reg = <0x0 0x7000e000 0x0 0x100>; interrupts = ; @@ -1082,13 +1082,13 @@ cpu@0 { device_type = "cpu"; - compatible = "nvidia,denver"; + compatible = "nvidia,tegra132-denver"; reg = <0>; }; cpu@1 { device_type = "cpu"; - compatible = "nvidia,denver"; + compatible = "nvidia,tegra132-denver"; reg = <1>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts @@ -10,18 +10,6 @@ model = "NVIDIA Jetson TX2 Developer Kit"; compatible = "nvidia,p2771-0000", "nvidia,tegra186"; - aconnect { - status = "okay"; - - dma-controller@2930000 { - status = "okay"; - }; - - interrupt-controller@2a40000 { - status = "okay"; - }; - }; - i2c@3160000 { power-monitor@42 { compatible = "ti,ina3221"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -309,8 +309,9 @@ compatible = "nvidia,tegra186-sdhci"; reg = <0x0 0x03400000 0x0 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA186_CLK_SDMMC1>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA186_CLK_SDMMC1>, + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; resets = <&bpmp TEGRA186_RESET_SDMMC1>; reset-names = "sdhci"; iommus = <&smmu TEGRA186_SID_SDMMC1>; @@ -335,8 +336,9 @@ compatible = "nvidia,tegra186-sdhci"; reg = <0x0 0x03420000 0x0 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA186_CLK_SDMMC2>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA186_CLK_SDMMC2>, + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; resets = <&bpmp TEGRA186_RESET_SDMMC2>; reset-names = "sdhci"; iommus = <&smmu TEGRA186_SID_SDMMC2>; @@ -356,8 +358,9 @@ compatible = "nvidia,tegra186-sdhci"; reg = <0x0 0x03440000 0x0 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA186_CLK_SDMMC3>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA186_CLK_SDMMC3>, + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; resets = <&bpmp TEGRA186_RESET_SDMMC3>; reset-names = "sdhci"; iommus = <&smmu TEGRA186_SID_SDMMC3>; @@ -379,8 +382,9 @@ compatible = "nvidia,tegra186-sdhci"; reg = <0x0 0x03460000 0x0 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA186_CLK_SDMMC4>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA186_CLK_SDMMC4>, + <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>, <&bpmp TEGRA186_CLK_PLLC4_VCO>; assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>; @@ -705,7 +709,7 @@ ccplex@e000000 { compatible = "nvidia,tegra186-ccplex-cluster"; - reg = <0x0 0x0e000000 0x0 0x3fffff>; + reg = <0x0 0x0e000000 0x0 0x400000>; nvidia,bpmp = <&bpmp>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi @@ -32,7 +32,7 @@ phy-reset-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 5) GPIO_ACTIVE_LOW>; phy-handle = <&phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; mdio { #address-cells = <1>; @@ -309,9 +309,8 @@ regulator-name = "VDD_12V"; regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; - gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_LOW>; + gpio = <&gpio TEGRA194_MAIN_GPIO(A, 1) GPIO_ACTIVE_HIGH>; regulator-boot-on; - enable-active-low; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -144,7 +144,7 @@ nvidia,schmitt = ; nvidia,lpdr = ; nvidia,enable-input = ; - nvidia,io-high-voltage = ; + nvidia,io-hv = ; nvidia,tristate = ; nvidia,pull = ; }; @@ -156,7 +156,7 @@ nvidia,schmitt = ; nvidia,lpdr = ; nvidia,enable-input = ; - nvidia,io-high-voltage = ; + nvidia,io-hv = ; nvidia,tristate = ; nvidia,pull = ; }; @@ -403,8 +403,9 @@ compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; reg = <0x03400000 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA194_CLK_SDMMC1>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA194_CLK_SDMMC1>, + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; resets = <&bpmp TEGRA194_RESET_SDMMC1>; reset-names = "sdhci"; nvidia,pad-autocal-pull-up-offset-3v3-timeout = @@ -425,8 +426,9 @@ compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; reg = <0x03440000 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA194_CLK_SDMMC3>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA194_CLK_SDMMC3>, + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; resets = <&bpmp TEGRA194_RESET_SDMMC3>; reset-names = "sdhci"; nvidia,pad-autocal-pull-up-offset-1v8 = <0x00>; @@ -448,8 +450,9 @@ compatible = "nvidia,tegra194-sdhci", "nvidia,tegra186-sdhci"; reg = <0x03460000 0x10000>; interrupts = ; - clocks = <&bpmp TEGRA194_CLK_SDMMC4>; - clock-names = "sdhci"; + clocks = <&bpmp TEGRA194_CLK_SDMMC4>, + <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>, <&bpmp TEGRA194_CLK_PLLC4>; assigned-clock-parents = @@ -689,7 +692,7 @@ hsp_aon: hsp@c150000 { compatible = "nvidia,tegra194-hsp", "nvidia,tegra186-hsp"; - reg = <0x0c150000 0xa0000>; + reg = <0x0c150000 0x90000>; interrupts = , , , @@ -1151,7 +1154,7 @@ }; pcie@14100000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14100000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x30000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1192,12 +1195,12 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x30100000 0x0 0x30100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x12 0x00000000 0x12 0x00000000 0x0 0x30000000 /* prefetchable memory (768MB) */ + 0xc3000000 0x12 0x00000000 0x12 0x00000000 0x0 0x30000000 /* prefetchable memory (768MB) */ 0x82000000 0x0 0x40000000 0x12 0x30000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */ }; pcie@14120000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14120000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x32000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1238,12 +1241,12 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x32100000 0x0 0x32100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x12 0x40000000 0x12 0x40000000 0x0 0x30000000 /* prefetchable memory (768MB) */ + 0xc3000000 0x12 0x40000000 0x12 0x40000000 0x0 0x30000000 /* prefetchable memory (768MB) */ 0x82000000 0x0 0x40000000 0x12 0x70000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */ }; pcie@14140000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX1A>; reg = <0x00 0x14140000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x34000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1284,12 +1287,12 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x34100000 0x0 0x34100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x12 0x80000000 0x12 0x80000000 0x0 0x30000000 /* prefetchable memory (768MB) */ + 0xc3000000 0x12 0x80000000 0x12 0x80000000 0x0 0x30000000 /* prefetchable memory (768MB) */ 0x82000000 0x0 0x40000000 0x12 0xb0000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */ }; pcie@14160000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x36000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1330,12 +1333,12 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x36100000 0x0 0x36100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x14 0x00000000 0x14 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ + 0xc3000000 0x14 0x00000000 0x14 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ 0x82000000 0x0 0x40000000 0x17 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */ }; pcie@14180000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x38000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1376,12 +1379,12 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x38100000 0x0 0x38100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x18 0x00000000 0x18 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ + 0xc3000000 0x18 0x00000000 0x18 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ 0x82000000 0x0 0x40000000 0x1b 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */ }; pcie@141a0000 { - compatible = "nvidia,tegra194-pcie", "snps,dw-pcie"; + compatible = "nvidia,tegra194-pcie"; power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ 0x00 0x3a000000 0x0 0x00040000 /* configuration space (256K) */ @@ -1426,10 +1429,109 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x3a100000 0x0 0x3a100000 0x0 0x00100000 /* downstream I/O (1MB) */ - 0xc2000000 0x1c 0x00000000 0x1c 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ + 0xc3000000 0x1c 0x00000000 0x1c 0x00000000 0x3 0x40000000 /* prefetchable memory (13GB) */ 0x82000000 0x0 0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */ }; + pcie_ep@14160000 { + compatible = "nvidia,tegra194-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX4A>; + reg = <0x00 0x14160000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x36040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x36080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x14 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <4>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_4>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_4_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_4>; + reset-names = "apb", "core"; + + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 4>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@14180000 { + compatible = "nvidia,tegra194-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8B>; + reg = <0x00 0x14180000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x38040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x38080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x18 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + clocks = <&bpmp TEGRA194_CLK_PEX0_CORE_0>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX0_CORE_0_APB>, + <&bpmp TEGRA194_RESET_PEX0_CORE_0>; + reset-names = "apb", "core"; + + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 0>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + + pcie_ep@141a0000 { + compatible = "nvidia,tegra194-pcie-ep"; + power-domains = <&bpmp TEGRA194_POWER_DOMAIN_PCIEX8A>; + reg = <0x00 0x141a0000 0x0 0x00020000 /* appl registers (128K) */ + 0x00 0x3a040000 0x0 0x00040000 /* iATU_DMA reg space (256K) */ + 0x00 0x3a080000 0x0 0x00040000 /* DBI reg space (256K) */ + 0x1c 0x00000000 0x4 0x00000000>; /* Address Space (16G) */ + reg-names = "appl", "atu_dma", "dbi", "addr_space"; + + status = "disabled"; + + num-lanes = <8>; + num-ib-windows = <2>; + num-ob-windows = <8>; + + pinctrl-names = "default"; + pinctrl-0 = <&clkreq_c5_bi_dir_state>; + + clocks = <&bpmp TEGRA194_CLK_PEX1_CORE_5>; + clock-names = "core"; + + resets = <&bpmp TEGRA194_RESET_PEX1_CORE_5_APB>, + <&bpmp TEGRA194_RESET_PEX1_CORE_5>; + reset-names = "apb", "core"; + + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + + nvidia,bpmp = <&bpmp 5>; + + nvidia,aspm-cmrt-us = <60>; + nvidia,aspm-pwr-on-t-us = <20>; + nvidia,aspm-l0s-entrance-latency-us = <3>; + }; + sysram@40000000 { compatible = "nvidia,tegra194-sysram", "mmio-sram"; reg = <0x0 0x40000000 0x0 0x50000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi @@ -1612,7 +1612,7 @@ regulator-name = "VDD_HDMI_5V0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - gpio = <&exp1 12 GPIO_ACTIVE_LOW>; + gpio = <&exp1 12 GPIO_ACTIVE_HIGH>; enable-active-high; vin-supply = <&vdd_5v0_sys>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -917,6 +917,7 @@ <&tegra_car 128>, /* hda2hdmi */ <&tegra_car 111>; /* hda2codec_2x */ reset-names = "hda", "hda2hdmi", "hda2codec_2x"; + power-domains = <&pd_sor>; status = "disabled"; }; @@ -1116,8 +1117,9 @@ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0000 0x0 0x200>; interrupts = ; - clocks = <&tegra_car TEGRA210_CLK_SDMMC1>; - clock-names = "sdhci"; + clocks = <&tegra_car TEGRA210_CLK_SDMMC1>, + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; + clock-names = "sdhci", "tmclk"; resets = <&tegra_car 14>; reset-names = "sdhci"; pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", @@ -1144,8 +1146,9 @@ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0200 0x0 0x200>; interrupts = ; - clocks = <&tegra_car TEGRA210_CLK_SDMMC2>; - clock-names = "sdhci"; + clocks = <&tegra_car TEGRA210_CLK_SDMMC2>, + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; + clock-names = "sdhci", "tmclk"; resets = <&tegra_car 9>; reset-names = "sdhci"; pinctrl-names = "sdmmc-1v8-drv"; @@ -1161,8 +1164,9 @@ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0400 0x0 0x200>; interrupts = ; - clocks = <&tegra_car TEGRA210_CLK_SDMMC3>; - clock-names = "sdhci"; + clocks = <&tegra_car TEGRA210_CLK_SDMMC3>, + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; + clock-names = "sdhci", "tmclk"; resets = <&tegra_car 69>; reset-names = "sdhci"; pinctrl-names = "sdmmc-3v3", "sdmmc-1v8", @@ -1184,8 +1188,9 @@ compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci"; reg = <0x0 0x700b0600 0x0 0x200>; interrupts = ; - clocks = <&tegra_car TEGRA210_CLK_SDMMC4>; - clock-names = "sdhci"; + clocks = <&tegra_car TEGRA210_CLK_SDMMC4>, + <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>; + clock-names = "sdhci", "tmclk"; resets = <&tegra_car 15>; reset-names = "sdhci"; pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi @@ -77,425 +77,427 @@ enable-gpios = <&pm8994_gpios 15 0>; }; }; +}; - soc { - serial@7570000 { - label = "BT-UART"; - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp1_uart1_default>; - pinctrl-1 = <&blsp1_uart1_sleep>; +&blsp1_uart1 { + label = "BT-UART"; + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp1_uart1_default>; + pinctrl-1 = <&blsp1_uart1_sleep>; - bluetooth { - compatible = "qcom,qca6174-bt"; + bluetooth { + compatible = "qcom,qca6174-bt"; - /* bt_disable_n gpio */ - enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>; + /* bt_disable_n gpio */ + enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>; - clocks = <&divclk4>; - }; - }; + clocks = <&divclk4>; + }; +}; - serial@75b0000 { - label = "LS-UART1"; - status = "okay"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp2_uart1_2pins_default>; - pinctrl-1 = <&blsp2_uart1_2pins_sleep>; - }; +&blsp2_uart1 { + label = "LS-UART1"; + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp2_uart1_2pins_default>; + pinctrl-1 = <&blsp2_uart1_2pins_sleep>; +}; - serial@75b1000 { - label = "LS-UART0"; - status = "disabled"; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&blsp2_uart2_4pins_default>; - pinctrl-1 = <&blsp2_uart2_4pins_sleep>; - }; +&blsp2_uart2 { + label = "LS-UART0"; + status = "disabled"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&blsp2_uart2_4pins_default>; + pinctrl-1 = <&blsp2_uart2_4pins_sleep>; +}; - i2c@7577000 { - /* On Low speed expansion */ - label = "LS-I2C0"; - status = "okay"; - }; +&blsp1_i2c2 { + /* On Low speed expansion */ + label = "LS-I2C0"; + status = "okay"; +}; - i2c@75b6000 { - /* On Low speed expansion */ - label = "LS-I2C1"; - status = "okay"; - }; +&blsp2_i2c1 { + /* On Low speed expansion */ + label = "LS-I2C1"; + status = "okay"; +}; - spi@7575000 { - /* On Low speed expansion */ - label = "LS-SPI0"; - status = "okay"; - }; +&blsp1_spi0 { + /* On Low speed expansion */ + label = "LS-SPI0"; + status = "okay"; +}; - i2c@75b5000 { - /* On High speed expansion */ - label = "HS-I2C2"; - status = "okay"; - }; +&blsp2_i2c0 { + /* On High speed expansion */ + label = "HS-I2C2"; + status = "okay"; +}; - spi@75ba000{ - /* On High speed expansion */ - label = "HS-SPI1"; - status = "okay"; - }; +&blsp2_spi5 { + /* On High speed expansion */ + label = "HS-SPI1"; + status = "okay"; +}; - sdhci@74a4900 { - /* External SD card */ - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; - pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; - cd-gpios = <&msmgpio 38 0x1>; - vmmc-supply = <&pm8994_l21>; - vqmmc-supply = <&pm8994_l13>; - status = "okay"; - }; +&camss { + vdda-supply = <&pm8994_l2>; +}; - phy@627000 { - status = "okay"; - }; +&sdhc2 { + /* External SD card */ + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + cd-gpios = <&msmgpio 38 0x1>; + vmmc-supply = <&pm8994_l21>; + vqmmc-supply = <&pm8994_l13>; + status = "okay"; +}; - ufshc@624000 { - status = "okay"; - }; +&ufsphy { + status = "okay"; - pinctrl@1010000 { - gpio-line-names = - "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */ - "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */ - "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */ - "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */ - "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */ - "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */ - "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */ - "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */ - "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */ - "TP93", /* GPIO_9 */ - "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */ - "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */ - "NC", /* GPIO_12 */ - "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */ - "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ - "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */ - "TP99", /* GPIO_16 */ - "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */ - "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */ - "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */ - "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */ - "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */ - "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */ - "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */ - "GPIO-D", /* GPIO_24, LSEC pin 26 */ - "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */ - "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */ - "BLSP6_I2C_SDA", /* GPIO_27 */ - "BLSP6_I2C_SCL", /* GPIO_28 */ - "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */ - "GPIO30", /* GPIO_30, S HSEC pin 4 */ - "HDMI_CEC", /* GPIO_31 */ - "HDMI_DDC_CLOCK", /* GPIO_32 */ - "HDMI_DDC_DATA", /* GPIO_33 */ - "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */ - "PCIE0_RST_N", /* GPIO_35 */ - "PCIE0_CLKREQ_N", /* GPIO_36 */ - "PCIE0_WAKE", /* GPIO_37 */ - "SD_CARD_DET_N", /* GPIO_38 */ - "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */ - "W_DISABLE_N", /* GPIO_40 */ - "[BLSP9_UART_TX]", /* GPIO_41 */ - "[BLSP9_UART_RX]", /* GPIO_42 */ - "[BLSP2_UART_CTS_N]", /* GPIO_43 */ - "[BLSP2_UART_RFR_N]", /* GPIO_44 */ - "[BLSP3_UART_TX]", /* GPIO_45 */ - "[BLSP3_UART_RX]", /* GPIO_46 */ - "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */ - "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */ - "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */ - "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */ - "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */ - "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */ - "[CODEC_INT1_N]", /* GPIO_53 */ - "[CODEC_INT2_N]", /* GPIO_54 */ - "[BLSP7_I2C_SDA]", /* GPIO_55 */ - "[BLSP7_I2C_SCL]", /* GPIO_56 */ - "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */ - "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */ - "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */ - "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */ - "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */ - "GPIO-E", /* GPIO_62, LSEC pin 27 */ - "TP87", /* GPIO_63 */ - "[CODEC_RST_N]", /* GPIO_64 */ - "[PCM1_CLK]", /* GPIO_65 */ - "[PCM1_SYNC]", /* GPIO_66 */ - "[PCM1_DIN]", /* GPIO_67 */ - "[PCM1_DOUT]", /* GPIO_68 */ - "AUDIO_REF_CLK", /* GPIO_69 */ - "SLIMBUS_CLK", /* GPIO_70 */ - "SLIMBUS_DATA0", /* GPIO_71 */ - "SLIMBUS_DATA1", /* GPIO_72 */ - "NC", /* GPIO_73 */ - "NC", /* GPIO_74 */ - "NC", /* GPIO_75 */ - "NC", /* GPIO_76 */ - "TP94", /* GPIO_77 */ - "NC", /* GPIO_78 */ - "TP95", /* GPIO_79 */ - "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */ - "TP88", /* GPIO_81 */ - "TP89", /* GPIO_82 */ - "TP90", /* GPIO_83 */ - "TP91", /* GPIO_84 */ - "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */ - "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */ - "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */ - "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */ - "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */ - "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */ - "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */ - "NC", /* GPIO_92 */ - "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */ - "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */ - "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */ - "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */ - "NC", /* GPIO_97 */ - "CAM1_STANDBY_N", /* GPIO_98 */ - "NC", /* GPIO_99 */ - "NC", /* GPIO_100 */ - "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */ - "BOOT_CONFIG1", /* GPIO_102 */ - "USB_HUB_RESET", /* GPIO_103 */ - "CAM1_RST_N", /* GPIO_104 */ - "NC", /* GPIO_105 */ - "NC", /* GPIO_106 */ - "NC", /* GPIO_107 */ - "NC", /* GPIO_108 */ - "NC", /* GPIO_109 */ - "NC", /* GPIO_110 */ - "NC", /* GPIO_111 */ - "NC", /* GPIO_112 */ - "PMI8994_BUA", /* GPIO_113 */ - "PCIE2_RST_N", /* GPIO_114 */ - "PCIE2_CLKREQ_N", /* GPIO_115 */ - "PCIE2_WAKE", /* GPIO_116 */ - "SSC_IRQ_0", /* GPIO_117 */ - "SSC_IRQ_1", /* GPIO_118 */ - "SSC_IRQ_2", /* GPIO_119 */ - "NC", /* GPIO_120 */ - "GPIO121", /* GPIO_121, S HSEC pin 2 */ - "NC", /* GPIO_122 */ - "SSC_IRQ_6", /* GPIO_123 */ - "SSC_IRQ_7", /* GPIO_124 */ - "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */ - "BOOT_CONFIG5", /* GPIO_126 */ - "NC", /* GPIO_127 */ - "NC", /* GPIO_128 */ - "BOOT_CONFIG7", /* GPIO_129 */ - "PCIE1_RST_N", /* GPIO_130 */ - "PCIE1_CLKREQ_N", /* GPIO_131 */ - "PCIE1_WAKE", /* GPIO_132 */ - "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */ - "NC", /* GPIO_134 */ - "NC", /* GPIO_135 */ - "BOOT_CONFIG8", /* GPIO_136 */ - "NC", /* GPIO_137 */ - "NC", /* GPIO_138 */ - "GPS_SSBI2", /* GPIO_139 */ - "GPS_SSBI1", /* GPIO_140 */ - "NC", /* GPIO_141 */ - "NC", /* GPIO_142 */ - "NC", /* GPIO_143 */ - "BOOT_CONFIG6", /* GPIO_144 */ - "NC", /* GPIO_145 */ - "NC", /* GPIO_146 */ - "NC", /* GPIO_147 */ - "NC", /* GPIO_148 */ - "NC"; /* GPIO_149 */ - }; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; - qcom,spmi@400f000 { - pmic@0 { - gpios@c000 { - gpio-line-names = - "NC", - "KEY_VOLP_N", - "NC", - "BL1_PWM", - "GPIO-F", /* BL0_PWM, LSEC pin 28 */ - "BL1_EN", - "NC", - "WLAN_EN", - "NC", - "NC", - "NC", - "NC", - "NC", - "NC", - "DIVCLK1", - "DIVCLK2", - "DIVCLK3", - "DIVCLK4", - "BT_EN", - "PMIC_SLB", - "PMIC_BUA", - "USB_VBUS_DET"; - }; - - mpps@a000 { - gpio-line-names = - "VDDPX_BIAS", - "WIFI_LED", - "NC", - "BT_LED", - "PM_MPP05", - "PM_MPP06", - "PM_MPP07", - "NC"; - }; - }; + vdda-phy-max-microamp = <18380>; + vdda-pll-max-microamp = <9440>; - pmic@2 { - gpios@c000 { - gpio-line-names = - "NC", - "SPKR_AMP_EN1", - "SPKR_AMP_EN2", - "TP61", - "NC", - "USB2_VBUS_DET", - "NC", - "NC", - "NC", - "NC"; - }; - }; - }; + vddp-ref-clk-supply = <&pm8994_l25>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; +}; - phy@34000 { - status = "okay"; - }; +&ufshc { + status = "okay"; - phy@7410000 { - status = "okay"; - }; + vcc-supply = <&pm8994_l20>; + vccq-supply = <&pm8994_l25>; + vccq2-supply = <&pm8994_s4>; + + vcc-max-microamp = <600000>; + vccq-max-microamp = <450000>; + vccq2-max-microamp = <450000>; +}; - phy@7411000 { - status = "okay"; - }; +&msmgpio { + gpio-line-names = + "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */ + "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */ + "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */ + "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */ + "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */ + "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */ + "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */ + "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */ + "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */ + "TP93", /* GPIO_9 */ + "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */ + "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */ + "NC", /* GPIO_12 */ + "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */ + "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */ + "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */ + "TP99", /* GPIO_16 */ + "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */ + "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */ + "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */ + "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */ + "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */ + "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */ + "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */ + "GPIO-D", /* GPIO_24, LSEC pin 26 */ + "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */ + "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */ + "BLSP6_I2C_SDA", /* GPIO_27 */ + "BLSP6_I2C_SCL", /* GPIO_28 */ + "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */ + "GPIO30", /* GPIO_30, S HSEC pin 4 */ + "HDMI_CEC", /* GPIO_31 */ + "HDMI_DDC_CLOCK", /* GPIO_32 */ + "HDMI_DDC_DATA", /* GPIO_33 */ + "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */ + "PCIE0_RST_N", /* GPIO_35 */ + "PCIE0_CLKREQ_N", /* GPIO_36 */ + "PCIE0_WAKE", /* GPIO_37 */ + "SD_CARD_DET_N", /* GPIO_38 */ + "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */ + "W_DISABLE_N", /* GPIO_40 */ + "[BLSP9_UART_TX]", /* GPIO_41 */ + "[BLSP9_UART_RX]", /* GPIO_42 */ + "[BLSP2_UART_CTS_N]", /* GPIO_43 */ + "[BLSP2_UART_RFR_N]", /* GPIO_44 */ + "[BLSP3_UART_TX]", /* GPIO_45 */ + "[BLSP3_UART_RX]", /* GPIO_46 */ + "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */ + "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */ + "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */ + "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */ + "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */ + "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */ + "[CODEC_INT1_N]", /* GPIO_53 */ + "[CODEC_INT2_N]", /* GPIO_54 */ + "[BLSP7_I2C_SDA]", /* GPIO_55 */ + "[BLSP7_I2C_SCL]", /* GPIO_56 */ + "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */ + "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */ + "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */ + "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */ + "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */ + "GPIO-E", /* GPIO_62, LSEC pin 27 */ + "TP87", /* GPIO_63 */ + "[CODEC_RST_N]", /* GPIO_64 */ + "[PCM1_CLK]", /* GPIO_65 */ + "[PCM1_SYNC]", /* GPIO_66 */ + "[PCM1_DIN]", /* GPIO_67 */ + "[PCM1_DOUT]", /* GPIO_68 */ + "AUDIO_REF_CLK", /* GPIO_69 */ + "SLIMBUS_CLK", /* GPIO_70 */ + "SLIMBUS_DATA0", /* GPIO_71 */ + "SLIMBUS_DATA1", /* GPIO_72 */ + "NC", /* GPIO_73 */ + "NC", /* GPIO_74 */ + "NC", /* GPIO_75 */ + "NC", /* GPIO_76 */ + "TP94", /* GPIO_77 */ + "NC", /* GPIO_78 */ + "TP95", /* GPIO_79 */ + "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */ + "TP88", /* GPIO_81 */ + "TP89", /* GPIO_82 */ + "TP90", /* GPIO_83 */ + "TP91", /* GPIO_84 */ + "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */ + "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */ + "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */ + "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */ + "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */ + "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */ + "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */ + "NC", /* GPIO_92 */ + "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */ + "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */ + "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */ + "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */ + "NC", /* GPIO_97 */ + "CAM1_STANDBY_N", /* GPIO_98 */ + "NC", /* GPIO_99 */ + "NC", /* GPIO_100 */ + "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */ + "BOOT_CONFIG1", /* GPIO_102 */ + "USB_HUB_RESET", /* GPIO_103 */ + "CAM1_RST_N", /* GPIO_104 */ + "NC", /* GPIO_105 */ + "NC", /* GPIO_106 */ + "NC", /* GPIO_107 */ + "NC", /* GPIO_108 */ + "NC", /* GPIO_109 */ + "NC", /* GPIO_110 */ + "NC", /* GPIO_111 */ + "NC", /* GPIO_112 */ + "PMI8994_BUA", /* GPIO_113 */ + "PCIE2_RST_N", /* GPIO_114 */ + "PCIE2_CLKREQ_N", /* GPIO_115 */ + "PCIE2_WAKE", /* GPIO_116 */ + "SSC_IRQ_0", /* GPIO_117 */ + "SSC_IRQ_1", /* GPIO_118 */ + "SSC_IRQ_2", /* GPIO_119 */ + "NC", /* GPIO_120 */ + "GPIO121", /* GPIO_121, S HSEC pin 2 */ + "NC", /* GPIO_122 */ + "SSC_IRQ_6", /* GPIO_123 */ + "SSC_IRQ_7", /* GPIO_124 */ + "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */ + "BOOT_CONFIG5", /* GPIO_126 */ + "NC", /* GPIO_127 */ + "NC", /* GPIO_128 */ + "BOOT_CONFIG7", /* GPIO_129 */ + "PCIE1_RST_N", /* GPIO_130 */ + "PCIE1_CLKREQ_N", /* GPIO_131 */ + "PCIE1_WAKE", /* GPIO_132 */ + "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */ + "NC", /* GPIO_134 */ + "NC", /* GPIO_135 */ + "BOOT_CONFIG8", /* GPIO_136 */ + "NC", /* GPIO_137 */ + "NC", /* GPIO_138 */ + "GPS_SSBI2", /* GPIO_139 */ + "GPS_SSBI1", /* GPIO_140 */ + "NC", /* GPIO_141 */ + "NC", /* GPIO_142 */ + "NC", /* GPIO_143 */ + "BOOT_CONFIG6", /* GPIO_144 */ + "NC", /* GPIO_145 */ + "NC", /* GPIO_146 */ + "NC", /* GPIO_147 */ + "NC", /* GPIO_148 */ + "NC"; /* GPIO_149 */ +}; - phy@7412000 { - status = "okay"; - }; +&pm8994_gpios { + gpio-line-names = + "NC", + "KEY_VOLP_N", + "NC", + "BL1_PWM", + "GPIO-F", /* BL0_PWM, LSEC pin 28 */ + "BL1_EN", + "NC", + "WLAN_EN", + "NC", + "NC", + "NC", + "NC", + "NC", + "NC", + "DIVCLK1", + "DIVCLK2", + "DIVCLK3", + "DIVCLK4", + "BT_EN", + "PMIC_SLB", + "PMIC_BUA", + "USB_VBUS_DET"; +}; - usb@6af8800 { - status = "okay"; - extcon = <&usb3_id>; - - dwc3@6a00000 { - extcon = <&usb3_id>; - dr_mode = "otg"; - }; - }; +&pm8994_mpps { + gpio-line-names = + "VDDPX_BIAS", + "WIFI_LED", + "NC", + "BT_LED", + "PM_MPP05", + "PM_MPP06", + "PM_MPP07", + "NC"; +}; - usb3_id: usb3-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb3_vbus_det_gpio>; - }; +&pmi8994_gpios { + gpio-line-names = + "NC", + "SPKR_AMP_EN1", + "SPKR_AMP_EN2", + "TP61", + "NC", + "USB2_VBUS_DET", + "NC", + "NC", + "NC", + "NC"; +}; - usb@76f8800 { - status = "okay"; - extcon = <&usb2_id>; - - dwc3@7600000 { - extcon = <&usb2_id>; - dr_mode = "otg"; - maximum-speed = "high-speed"; - }; - }; +&pcie_phy { + status = "okay"; - usb2_id: usb2-id { - compatible = "linux,extcon-usb-gpio"; - id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&usb2_vbus_det_gpio>; - }; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; +}; - wlan_en: wlan-en-1-8v { - pinctrl-names = "default"; - pinctrl-0 = <&wlan_en_gpios>; - compatible = "regulator-fixed"; - regulator-name = "wlan-en-regulator"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - gpio = <&pm8994_gpios 8 0>; - - /* WLAN card specific delay */ - startup-delay-us = <70000>; - enable-active-high; - }; +&usb3phy { + status = "okay"; - agnoc@0 { - pcie@600000 { - status = "okay"; - perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>; - vddpe-3v3-supply = <&wlan_en>; - }; + vdda-phy-supply = <&pm8994_l28>; + vdda-pll-supply = <&pm8994_l12>; - pcie@608000 { - status = "okay"; - perst-gpio = <&msmgpio 130 GPIO_ACTIVE_LOW>; - }; +}; - pcie@610000 { - status = "okay"; - perst-gpio = <&msmgpio 114 GPIO_ACTIVE_LOW>; - }; - }; +&hsusb_phy1 { + status = "okay"; - slim_msm: slim@91c0000 { - ngd@1 { - wcd9335: codec@1{ - clock-names = "mclk", "slimbus"; - clocks = <&div1_mclk>, - <&rpmcc RPM_SMD_BB_CLK1>; - }; - }; - }; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; +}; - mdss@900000 { - status = "okay"; +&hsusb_phy2 { + status = "okay"; - mdp@901000 { - status = "okay"; - }; + vdda-pll-supply = <&pm8994_l12>; + vdda-phy-dpdm-supply = <&pm8994_l24>; +}; - hdmi-phy@9a0600 { - status = "okay"; +&usb3 { + status = "okay"; + extcon = <&usb3_id>; + + dwc3@6a00000 { + extcon = <&usb3_id>; + dr_mode = "otg"; + }; +}; - vddio-supply = <&pm8994_l12>; - vcca-supply = <&pm8994_l28>; - #phy-cells = <0>; - }; +&usb2 { + status = "okay"; + extcon = <&usb2_id>; + + dwc3@7600000 { + extcon = <&usb2_id>; + dr_mode = "otg"; + maximum-speed = "high-speed"; + }; +}; - hdmi-tx@9a0000 { - status = "okay"; +&pcie0 { + status = "okay"; + perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>; + vddpe-3v3-supply = <&wlan_en>; + vdda-supply = <&pm8994_l28>; +}; - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>; - pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>; +&pcie1 { + status = "okay"; + perst-gpio = <&msmgpio 130 GPIO_ACTIVE_LOW>; + vdda-supply = <&pm8994_l28>; +}; - core-vdda-supply = <&pm8994_l12>; - core-vcc-supply = <&pm8994_s4>; - }; - }; - }; +&pcie2 { + status = "okay"; + perst-gpio = <&msmgpio 114 GPIO_ACTIVE_LOW>; + vdda-supply = <&pm8994_l28>; +}; + +&wcd9335 { + clock-names = "mclk", "slimbus"; + clocks = <&div1_mclk>, + <&rpmcc RPM_SMD_BB_CLK1>; + + vdd-buck-supply = <&pm8994_s4>; + vdd-buck-sido-supply = <&pm8994_s4>; + vdd-tx-supply = <&pm8994_s4>; + vdd-rx-supply = <&pm8994_s4>; + vdd-io-supply = <&pm8994_s4>; +}; + +&mdss { + status = "okay"; +}; + +&mdp { + status = "okay"; +}; + +&hdmi_phy { + status = "okay"; + + vddio-supply = <&pm8994_l12>; + vcca-supply = <&pm8994_l28>; + #phy-cells = <0>; +}; + +&hdmi { + status = "okay"; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>; + pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>; + core-vdda-supply = <&pm8994_l12>; + core-vcc-supply = <&pm8994_s4>; +}; + +/ { gpio_keys { compatible = "gpio-keys"; #address-cells = <1>; @@ -623,6 +625,8 @@ l21 { regulator-min-microvolt = <2950000>; regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + regulator-system-load = <200000>; }; l22 { regulator-min-microvolt = <3300000>; @@ -665,6 +669,35 @@ }; }; }; + + usb2_id: usb2-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb2_vbus_det_gpio>; + }; + + usb3_id: usb3-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_vbus_det_gpio>; + }; + + wlan_en: wlan-en-1-8v { + pinctrl-names = "default"; + pinctrl-0 = <&wlan_en_gpios>; + compatible = "regulator-fixed"; + regulator-name = "wlan-en-regulator"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&pm8994_gpios 8 0>; + + /* WLAN card specific delay */ + startup-delay-us = <70000>; + enable-active-high; + }; }; &spmi_bus { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/ipq8074-hk01.dts @@ -20,7 +20,7 @@ stdout-path = "serial0"; }; - memory { + memory@40000000 { device_type = "memory"; reg = <0x0 0x40000000 0x0 0x20000000>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/ipq8074.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/ipq8074.dtsi @@ -253,7 +253,7 @@ status = "disabled"; }; - qpic_nand: nand@79b0000 { + qpic_nand: nand-controller@79b0000 { compatible = "qcom,ipq8074-nand"; reg = <0x79b0000 0x10000>; #address-cells = <1>; @@ -482,7 +482,7 @@ clocks { sleep_clk: sleep_clk { compatible = "fixed-clock"; - clock-frequency = <32000>; + clock-frequency = <32768>; #clock-cells = <0>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -508,7 +508,7 @@ pins = "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"; drive-strength = <8>; - bias-pull-none; + bias-disable; }; }; cdc_pdm_lines_sus: pdm_lines_off { @@ -521,7 +521,7 @@ pins = "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"; drive-strength = <2>; - bias-disable; + bias-pull-down; }; }; }; @@ -537,7 +537,7 @@ pins = "gpio113", "gpio114", "gpio115", "gpio116"; drive-strength = <8>; - bias-pull-none; + bias-disable; }; }; @@ -565,7 +565,7 @@ pinconf { pins = "gpio110"; drive-strength = <8>; - bias-pull-none; + bias-disable; }; }; @@ -591,7 +591,7 @@ pinconf { pins = "gpio116"; drive-strength = <8>; - bias-pull-none; + bias-disable; }; }; ext_mclk_tlmm_lines_sus: mclk_lines_off { @@ -619,7 +619,7 @@ pins = "gpio112", "gpio117", "gpio118", "gpio119"; drive-strength = <8>; - bias-pull-none; + bias-disable; }; }; ext_sec_tlmm_lines_sus: tlmm_lines_off { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -16,8 +16,8 @@ #size-cells = <2>; aliases { - sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ - sdhc2 = &sdhc_2; /* SDC2 SD card slot */ + mmc0 = &sdhc_1; /* SDC1 eMMC slot */ + mmc1 = &sdhc_2; /* SDC2 SD card slot */ }; chosen { }; @@ -53,7 +53,7 @@ no-map; }; - reserved@8668000 { + reserved@86680000 { reg = <0x0 0x86680000 0x0 0x80000>; no-map; }; @@ -66,7 +66,7 @@ qcom,client-id = <1>; }; - rfsa@867e00000 { + rfsa@867e0000 { reg = <0x0 0x867e0000 0x0 0x20000>; no-map; }; @@ -175,14 +175,14 @@ }; thermal-zones { - cpu0_1-thermal { + cpu0-1-thermal { polling-delay-passive = <250>; polling-delay = <1000>; thermal-sensors = <&tsens 4>; trips { - cpu0_1_alert0: trip-point@0 { + cpu0_1_alert0: trip-point0 { temperature = <75000>; hysteresis = <2000>; type = "passive"; @@ -205,14 +205,14 @@ }; }; - cpu2_3-thermal { + cpu2-3-thermal { polling-delay-passive = <250>; polling-delay = <1000>; thermal-sensors = <&tsens 3>; trips { - cpu2_3_alert0: trip-point@0 { + cpu2_3_alert0: trip-point0 { temperature = <75000>; hysteresis = <2000>; type = "passive"; @@ -242,7 +242,7 @@ thermal-sensors = <&tsens 2>; trips { - gpu_alert0: trip-point@0 { + gpu_alert0: trip-point0 { temperature = <75000>; hysteresis = <2000>; type = "passive"; @@ -262,7 +262,7 @@ thermal-sensors = <&tsens 1>; trips { - cam_alert0: trip-point@0 { + cam_alert0: trip-point0 { temperature = <75000>; hysteresis = <2000>; type = "hot"; @@ -277,7 +277,7 @@ thermal-sensors = <&tsens 0>; trips { - modem_alert0: trip-point@0 { + modem_alert0: trip-point0 { temperature = <85000>; hysteresis = <2000>; type = "hot"; @@ -934,7 +934,7 @@ reg-names = "mdp_phys"; interrupt-parent = <&mdss>; - interrupts = <0 0>; + interrupts = <0>; clocks = <&gcc GCC_MDSS_AHB_CLK>, <&gcc GCC_MDSS_AXI_CLK>, @@ -966,7 +966,7 @@ reg-names = "dsi_ctrl"; interrupt-parent = <&mdss>; - interrupts = <4 0>; + interrupts = <4>; assigned-clocks = <&gcc BYTE0_CLK_SRC>, <&gcc PCLK0_CLK_SRC>; @@ -1097,8 +1097,8 @@ vddmx-supply = <&pm8916_l3>; vddpx-supply = <&pm8916_l7>; - qcom,state = <&wcnss_smp2p_out 0>; - qcom,state-names = "stop"; + qcom,smem-states = <&wcnss_smp2p_out 0>; + qcom,smem-state-names = "stop"; pinctrl-names = "default"; pinctrl-0 = <&wcnss_pin_a>; @@ -1451,7 +1451,7 @@ }; }; - camss: camss@1b00000 { + camss: camss@1b0ac00 { compatible = "qcom,msm8916-camss"; reg = <0x1b0ac00 0x200>, <0x1b00030 0x4>, --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts @@ -30,3 +30,7 @@ }; }; }; + +&msmgpio { + gpio-reserved-ranges = <85 4>; +}; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -433,6 +433,19 @@ }; }; + etm { + compatible = "qcom,coresight-remote-etm"; + + out-ports { + port { + modem_etm_out_funnel_in2: endpoint { + remote-endpoint = + <&funnel_in2_in_modem_etm>; + }; + }; + }; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -571,7 +584,7 @@ rpm_msg_ram: memory@68000 { compatible = "qcom,rpm-msg-ram"; - reg = <0x68000 0x6000>; + reg = <0x00068000 0x6000>; }; rng: rng@83000 { @@ -583,28 +596,28 @@ tcsr_mutex_regs: syscon@740000 { compatible = "syscon"; - reg = <0x740000 0x20000>; + reg = <0x00740000 0x20000>; }; tsens0: thermal-sensor@4a9000 { compatible = "qcom,msm8996-tsens"; - reg = <0x4a9000 0x1000>, /* TM */ - <0x4a8000 0x1000>; /* SROT */ + reg = <0x004a9000 0x1000>, /* TM */ + <0x004a8000 0x1000>; /* SROT */ #qcom,sensors = <13>; #thermal-sensor-cells = <1>; }; tsens1: thermal-sensor@4ad000 { compatible = "qcom,msm8996-tsens"; - reg = <0x4ad000 0x1000>, /* TM */ - <0x4ac000 0x1000>; /* SROT */ + reg = <0x004ad000 0x1000>, /* TM */ + <0x004ac000 0x1000>; /* SROT */ #qcom,sensors = <8>; #thermal-sensor-cells = <1>; }; tcsr: syscon@7a0000 { compatible = "qcom,tcsr-msm8996", "syscon"; - reg = <0x7a0000 0x18000>; + reg = <0x007a0000 0x18000>; }; intc: interrupt-controller@9bc0000 { @@ -620,7 +633,7 @@ apcs_glb: mailbox@9820000 { compatible = "qcom,msm8996-apcs-hmss-global"; - reg = <0x9820000 0x1000>; + reg = <0x09820000 0x1000>; #mbox-cells = <1>; }; @@ -630,7 +643,7 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; - reg = <0x300000 0x90000>; + reg = <0x00300000 0x90000>; }; stm@3002000 { @@ -736,6 +749,14 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + in-ports { + port { + funnel_in2_in_modem_etm: endpoint { + remote-endpoint = + <&modem_etm_out_funnel_in2>; + }; + }; + }; out-ports { port { @@ -1103,7 +1124,7 @@ kryocc: clock-controller@6400000 { compatible = "qcom,apcc-msm8996"; - reg = <0x6400000 0x90000>; + reg = <0x06400000 0x90000>; #clock-cells = <1>; }; @@ -1149,7 +1170,7 @@ blsp2_uart1: serial@75b0000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; - reg = <0x75b0000 0x1000>; + reg = <0x075b0000 0x1000>; interrupts = ; clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; @@ -1215,7 +1236,7 @@ sdhc2: sdhci@74a4900 { status = "disabled"; compatible = "qcom,sdhci-msm-v4"; - reg = <0x74a4900 0x314>, <0x74a4000 0x800>; + reg = <0x074a4900 0x314>, <0x074a4000 0x800>; reg-names = "hc_mem", "core_mem"; interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>, @@ -1300,11 +1321,11 @@ spmi_bus: qcom,spmi@400f000 { compatible = "qcom,spmi-pmic-arb"; - reg = <0x400f000 0x1000>, - <0x4400000 0x800000>, - <0x4c00000 0x800000>, - <0x5800000 0x200000>, - <0x400a000 0x002100>; + reg = <0x0400f000 0x1000>, + <0x04400000 0x800000>, + <0x04c00000 0x800000>, + <0x05800000 0x200000>, + <0x0400a000 0x002100>; reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; interrupt-names = "periph_irq"; interrupts = ; @@ -1318,20 +1339,10 @@ ufsphy: phy@627000 { compatible = "qcom,msm8996-ufs-phy-qmp-14nm"; - reg = <0x627000 0xda8>; + reg = <0x00627000 0xda8>; reg-names = "phy_mem"; #phy-cells = <0>; - vdda-phy-supply = <&pm8994_l28>; - vdda-pll-supply = <&pm8994_l12>; - - vdda-phy-max-microamp = <18380>; - vdda-pll-max-microamp = <9440>; - - vddp-ref-clk-supply = <&pm8994_l25>; - vddp-ref-clk-max-microamp = <100>; - vddp-ref-clk-always-on; - clock-names = "ref_clk_src", "ref_clk"; clocks = <&rpmcc RPM_SMD_LN_BB_CLK>, <&gcc GCC_UFS_CLKREF_CLK>; @@ -1341,20 +1352,12 @@ ufshc: ufshc@624000 { compatible = "qcom,ufshc"; - reg = <0x624000 0x2500>; + reg = <0x00624000 0x2500>; interrupts = ; phys = <&ufsphy>; phy-names = "ufsphy"; - vcc-supply = <&pm8994_l20>; - vccq-supply = <&pm8994_l25>; - vccq2-supply = <&pm8994_s4>; - - vcc-max-microamp = <600000>; - vccq-max-microamp = <450000>; - vccq2-max-microamp = <450000>; - power-domains = <&gcc UFS_GDSC>; clock-names = @@ -1383,7 +1386,7 @@ <&gcc GCC_UFS_RX_SYMBOL_0_CLK>; freq-table-hz = <100000000 200000000>, - <0 0>, + <100000000 200000000>, <0 0>, <0 0>, <0 0>, @@ -1408,7 +1411,7 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; - reg = <0x8c0000 0x40000>; + reg = <0x008c0000 0x40000>; assigned-clocks = <&mmcc MMPLL9_PLL>, <&mmcc MMPLL1_PLL>, <&mmcc MMPLL3_PLL>, @@ -1423,7 +1426,7 @@ qfprom@74000 { compatible = "qcom,qfprom"; - reg = <0x74000 0x8ff>; + reg = <0x00074000 0x8ff>; #address-cells = <1>; #size-cells = <1>; @@ -1443,9 +1446,9 @@ }; }; - phy@34000 { + pcie_phy: phy@34000 { compatible = "qcom,msm8996-qmp-pcie-phy"; - reg = <0x34000 0x488>; + reg = <0x00034000 0x488>; #clock-cells = <1>; #address-cells = <1>; #size-cells = <1>; @@ -1456,9 +1459,6 @@ <&gcc GCC_PCIE_CLKREF_CLK>; clock-names = "aux", "cfg_ahb", "ref"; - vdda-phy-supply = <&pm8994_l28>; - vdda-pll-supply = <&pm8994_l12>; - resets = <&gcc GCC_PCIE_PHY_BCR>, <&gcc GCC_PCIE_PHY_COM_BCR>, <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>; @@ -1466,9 +1466,9 @@ status = "disabled"; pciephy_0: lane@35000 { - reg = <0x035000 0x130>, - <0x035200 0x200>, - <0x035400 0x1dc>; + reg = <0x00035000 0x130>, + <0x00035200 0x200>, + <0x00035400 0x1dc>; #phy-cells = <0>; clock-output-names = "pcie_0_pipe_clk_src"; @@ -1479,9 +1479,9 @@ }; pciephy_1: lane@36000 { - reg = <0x036000 0x130>, - <0x036200 0x200>, - <0x036400 0x1dc>; + reg = <0x00036000 0x130>, + <0x00036200 0x200>, + <0x00036400 0x1dc>; #phy-cells = <0>; clock-output-names = "pcie_1_pipe_clk_src"; @@ -1492,9 +1492,9 @@ }; pciephy_2: lane@37000 { - reg = <0x037000 0x130>, - <0x037200 0x200>, - <0x037400 0x1dc>; + reg = <0x00037000 0x130>, + <0x00037200 0x200>, + <0x00037400 0x1dc>; #phy-cells = <0>; clock-output-names = "pcie_2_pipe_clk_src"; @@ -1505,9 +1505,9 @@ }; }; - phy@7410000 { + usb3phy: phy@7410000 { compatible = "qcom,msm8996-qmp-usb3-phy"; - reg = <0x7410000 0x1c4>; + reg = <0x07410000 0x1c4>; #clock-cells = <1>; #address-cells = <1>; #size-cells = <1>; @@ -1518,18 +1518,15 @@ <&gcc GCC_USB3_CLKREF_CLK>; clock-names = "aux", "cfg_ahb", "ref"; - vdda-phy-supply = <&pm8994_l28>; - vdda-pll-supply = <&pm8994_l12>; - resets = <&gcc GCC_USB3_PHY_BCR>, <&gcc GCC_USB3PHY_PHY_BCR>; reset-names = "phy", "common"; status = "disabled"; ssusb_phy_0: lane@7410200 { - reg = <0x7410200 0x200>, - <0x7410400 0x130>, - <0x7410600 0x1a8>; + reg = <0x07410200 0x200>, + <0x07410400 0x130>, + <0x07410600 0x1a8>; #phy-cells = <0>; clock-output-names = "usb3_phy_pipe_clk_src"; @@ -1540,16 +1537,13 @@ hsusb_phy1: phy@7411000 { compatible = "qcom,msm8996-qusb2-phy"; - reg = <0x7411000 0x180>; + reg = <0x07411000 0x180>; #phy-cells = <0>; clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, <&gcc GCC_RX1_USB2_CLKREF_CLK>; clock-names = "cfg_ahb", "ref"; - vdda-pll-supply = <&pm8994_l12>; - vdda-phy-dpdm-supply = <&pm8994_l24>; - resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; nvmem-cells = <&qusb2p_hstx_trim>; status = "disabled"; @@ -1557,16 +1551,13 @@ hsusb_phy2: phy@7412000 { compatible = "qcom,msm8996-qusb2-phy"; - reg = <0x7412000 0x180>; + reg = <0x07412000 0x180>; #phy-cells = <0>; clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>, <&gcc GCC_RX2_USB2_CLKREF_CLK>; clock-names = "cfg_ahb", "ref"; - vdda-pll-supply = <&pm8994_l12>; - vdda-phy-dpdm-supply = <&pm8994_l24>; - resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; nvmem-cells = <&qusb2s_hstx_trim>; status = "disabled"; @@ -1574,7 +1565,7 @@ usb2: usb@76f8800 { compatible = "qcom,msm8996-dwc3", "qcom,dwc3"; - reg = <0x76f8800 0x400>; + reg = <0x076f8800 0x400>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -1594,16 +1585,18 @@ dwc3@7600000 { compatible = "snps,dwc3"; - reg = <0x7600000 0xcc00>; + reg = <0x07600000 0xcc00>; interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>; phys = <&hsusb_phy2>; phy-names = "usb2-phy"; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; }; }; usb3: usb@6af8800 { compatible = "qcom,msm8996-dwc3", "qcom,dwc3"; - reg = <0x6af8800 0x400>; + reg = <0x06af8800 0x400>; #address-cells = <1>; #size-cells = <1>; ranges; @@ -1624,16 +1617,18 @@ dwc3@6a00000 { compatible = "snps,dwc3"; - reg = <0x6a00000 0xcc00>; + reg = <0x06a00000 0xcc00>; interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>; phys = <&hsusb_phy1>, <&ssusb_phy_0>; phy-names = "usb2-phy", "usb3-phy"; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; }; }; vfe_smmu: iommu@da0000 { compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; - reg = <0xda0000 0x10000>; + reg = <0x00da0000 0x10000>; #global-interrupts = <1>; interrupts = , @@ -1649,20 +1644,20 @@ camss: camss@a00000 { compatible = "qcom,msm8996-camss"; - reg = <0xa34000 0x1000>, - <0xa00030 0x4>, - <0xa35000 0x1000>, - <0xa00038 0x4>, - <0xa36000 0x1000>, - <0xa00040 0x4>, - <0xa30000 0x100>, - <0xa30400 0x100>, - <0xa30800 0x100>, - <0xa30c00 0x100>, - <0xa31000 0x500>, - <0xa00020 0x10>, - <0xa10000 0x1000>, - <0xa14000 0x1000>; + reg = <0x00a34000 0x1000>, + <0x00a00030 0x4>, + <0x00a35000 0x1000>, + <0x00a00038 0x4>, + <0x00a36000 0x1000>, + <0x00a00040 0x4>, + <0x00a30000 0x100>, + <0x00a30400 0x100>, + <0x00a30800 0x100>, + <0x00a30c00 0x100>, + <0x00a31000 0x500>, + <0x00a00020 0x10>, + <0x00a10000 0x1000>, + <0x00a14000 0x1000>; reg-names = "csiphy0", "csiphy0_clk_mux", "csiphy1", @@ -1677,16 +1672,16 @@ "csi_clk_mux", "vfe0", "vfe1"; - interrupts = , - , - , - , - , - , - , - , - , - ; + interrupts = , + , + , + , + , + , + , + , + , + ; interrupt-names = "csiphy0", "csiphy1", "csiphy2", @@ -1770,7 +1765,6 @@ "vfe1_stream", "vfe_ahb", "vfe_axi"; - vdda-supply = <&pm8994_l2>; iommus = <&vfe_smmu 0>, <&vfe_smmu 1>, <&vfe_smmu 2>, @@ -1784,7 +1778,7 @@ adreno_smmu: iommu@b40000 { compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; - reg = <0xb40000 0x10000>; + reg = <0x00b40000 0x10000>; #global-interrupts = <1>; interrupts = , @@ -1801,7 +1795,7 @@ mdp_smmu: iommu@d00000 { compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; - reg = <0xd00000 0x10000>; + reg = <0x00d00000 0x10000>; #global-interrupts = <1>; interrupts = , @@ -1817,7 +1811,7 @@ lpass_q6_smmu: iommu@1600000 { compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; - reg = <0x1600000 0x20000>; + reg = <0x01600000 0x20000>; #iommu-cells = <1>; power-domains = <&gcc HLOS1_VOTE_LPASS_CORE_GDSC>; @@ -1882,9 +1876,6 @@ pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>; pinctrl-1 = <&pcie0_clkreq_sleep &pcie0_perst_default &pcie0_wake_sleep>; - - vdda-supply = <&pm8994_l28>; - linux,pci-domain = <0>; clocks = <&gcc GCC_PCIE_0_PIPE_CLK>, @@ -1937,8 +1928,6 @@ pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>; pinctrl-1 = <&pcie1_clkreq_sleep &pcie1_perst_default &pcie1_wake_sleep>; - - vdda-supply = <&pm8994_l28>; linux,pci-domain = <1>; clocks = <&gcc GCC_PCIE_1_PIPE_CLK>, @@ -1990,8 +1979,6 @@ pinctrl-0 = <&pcie2_clkreq_default &pcie2_perst_default &pcie2_wake_default>; pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep >; - vdda-supply = <&pm8994_l28>; - linux,pci-domain = <2>; clocks = <&gcc GCC_PCIE_2_PIPE_CLK>, <&gcc GCC_PCIE_2_AUX_CLK>, @@ -2011,7 +1998,7 @@ { compatible = "qcom,bam-v1.7.0"; qcom,controlled-remotely; - reg = <0x9184000 0x32000>; + reg = <0x09184000 0x32000>; num-channels = <31>; interrupts = <0 164 IRQ_TYPE_LEVEL_HIGH>; #dma-cells = <1>; @@ -2021,7 +2008,7 @@ slim_msm: slim@91c0000 { compatible = "qcom,slim-ngd-v1.5.0"; - reg = <0x91c0000 0x2C000>; + reg = <0x091c0000 0x2C000>; reg-names = "ctrl"; interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; dmas = <&slimbam 3>, <&slimbam 4>, @@ -2056,12 +2043,6 @@ slim-ifc-dev = <&tasha_ifd>; - vdd-buck-supply = <&pm8994_s4>; - vdd-buck-sido-supply = <&pm8994_s4>; - vdd-tx-supply = <&pm8994_s4>; - vdd-rx-supply = <&pm8994_s4>; - vdd-io-supply = <&pm8994_s4>; - #sound-dai-cells = <1>; }; }; @@ -2071,7 +2052,7 @@ compatible = "qcom,adreno-530.2", "qcom,adreno"; #stream-id-cells = <16>; - reg = <0xb00000 0x3f000>; + reg = <0x00b00000 0x3f000>; reg-names = "kgsl_3d0_reg_memory"; interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>; @@ -2094,9 +2075,6 @@ nvmem-cells = <&gpu_speed_bin>; nvmem-cell-names = "speed_bin"; - qcom,gpu-quirk-two-pass-use-wfi; - qcom,gpu-quirk-fault-detect-mask; - operating-points-v2 = <&gpu_opp_table>; gpu_opp_table: opp-table { @@ -2145,9 +2123,9 @@ mdss: mdss@900000 { compatible = "qcom,mdss"; - reg = <0x900000 0x1000>, - <0x9b0000 0x1040>, - <0x9b8000 0x1040>; + reg = <0x00900000 0x1000>, + <0x009b0000 0x1040>, + <0x009b8000 0x1040>; reg-names = "mdss_phys", "vbif_phys", "vbif_nrt_phys"; @@ -2167,7 +2145,7 @@ mdp: mdp@901000 { compatible = "qcom,mdp5"; - reg = <0x901000 0x90000>; + reg = <0x00901000 0x90000>; reg-names = "mdp_phys"; interrupt-parent = <&mdss>; @@ -2243,12 +2221,12 @@ hdmi_phy: hdmi-phy@9a0600 { #phy-cells = <0>; compatible = "qcom,hdmi-phy-8996"; - reg = <0x9a0600 0x1c4>, - <0x9a0a00 0x124>, - <0x9a0c00 0x124>, - <0x9a0e00 0x124>, - <0x9a1000 0x124>, - <0x9a1200 0x0c8>; + reg = <0x009a0600 0x1c4>, + <0x009a0a00 0x124>, + <0x009a0c00 0x124>, + <0x009a0e00 0x124>, + <0x009a1000 0x124>, + <0x009a1200 0x0c8>; reg-names = "hdmi_pll", "hdmi_tx_l0", "hdmi_tx_l1", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi @@ -23,6 +23,43 @@ }; }; +/* + * The laptop FW does not appear to support the retention state as it is + * not advertised as enabled in ACPI, and enabling it in DT can cause boot + * hangs. + */ +&CPU0 { + cpu-idle-states = <&LITTLE_CPU_SLEEP_1>; +}; + +&CPU1 { + cpu-idle-states = <&LITTLE_CPU_SLEEP_1>; +}; + +&CPU2 { + cpu-idle-states = <&LITTLE_CPU_SLEEP_1>; +}; + +&CPU3 { + cpu-idle-states = <&LITTLE_CPU_SLEEP_1>; +}; + +&CPU4 { + cpu-idle-states = <&BIG_CPU_SLEEP_1>; +}; + +&CPU5 { + cpu-idle-states = <&BIG_CPU_SLEEP_1>; +}; + +&CPU6 { + cpu-idle-states = <&BIG_CPU_SLEEP_1>; +}; + +&CPU7 { + cpu-idle-states = <&BIG_CPU_SLEEP_1>; +}; + &qusb2phy { status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8998-mtp.dtsi @@ -27,6 +27,66 @@ status = "okay"; }; +&etf { + status = "okay"; +}; + +&etm1 { + status = "okay"; +}; + +&etm2 { + status = "okay"; +}; + +&etm3 { + status = "okay"; +}; + +&etm4 { + status = "okay"; +}; + +&etm5 { + status = "okay"; +}; + +&etm6 { + status = "okay"; +}; + +&etm7 { + status = "okay"; +}; + +&etm8 { + status = "okay"; +}; + +&etr { + status = "okay"; +}; + +&funnel1 { + status = "okay"; +}; + +&funnel2 { + status = "okay"; +}; + +&funnel3 { + status = "okay"; +}; + +&funnel4 { + status = "okay"; +}; + +&funnel5 { + status = "okay"; +}; + &pm8005_lsid1 { pm8005-regulators { compatible = "qcom,pm8005-regulators"; @@ -51,6 +111,10 @@ vdda-phy-dpdm-supply = <&vreg_l24a_3p075>; }; +&replicator1 { + status = "okay"; +}; + &rpm_requests { pm8998-regulators { compatible = "qcom,rpm-pm8998-regulators"; @@ -249,6 +313,10 @@ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; }; +&stm { + status = "okay"; +}; + &ufshc { vcc-supply = <&vreg_l20a_2p95>; vccq-supply = <&vreg_l26a_1p2>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -246,38 +246,42 @@ LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 { compatible = "arm,idle-state"; idle-state-name = "little-retention"; + /* CPU Retention (C2D), L2 Active */ arm,psci-suspend-param = <0x00000002>; entry-latency-us = <81>; exit-latency-us = <86>; - min-residency-us = <200>; + min-residency-us = <504>; }; LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 { compatible = "arm,idle-state"; idle-state-name = "little-power-collapse"; + /* CPU + L2 Power Collapse (C3, D4) */ arm,psci-suspend-param = <0x40000003>; - entry-latency-us = <273>; - exit-latency-us = <612>; - min-residency-us = <1000>; + entry-latency-us = <814>; + exit-latency-us = <4562>; + min-residency-us = <9183>; local-timer-stop; }; BIG_CPU_SLEEP_0: cpu-sleep-1-0 { compatible = "arm,idle-state"; idle-state-name = "big-retention"; + /* CPU Retention (C2D), L2 Active */ arm,psci-suspend-param = <0x00000002>; entry-latency-us = <79>; exit-latency-us = <82>; - min-residency-us = <200>; + min-residency-us = <1302>; }; BIG_CPU_SLEEP_1: cpu-sleep-1-1 { compatible = "arm,idle-state"; idle-state-name = "big-power-collapse"; + /* CPU + L2 Power Collapse (C3, D4) */ arm,psci-suspend-param = <0x40000003>; - entry-latency-us = <336>; - exit-latency-us = <525>; - min-residency-us = <1000>; + entry-latency-us = <724>; + exit-latency-us = <2027>; + min-residency-us = <9419>; local-timer-stop; }; }; @@ -868,10 +872,10 @@ interrupts = ; interrupt-names = "msi"; interrupt-map-mask = <0 0 0 0x7>; - interrupt-map = <0 0 0 1 &intc 0 135 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &intc 0 136 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &intc 0 138 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &intc 0 139 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &intc 0 0 135 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 136 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 138 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 139 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gcc GCC_PCIE_0_PIPE_CLK>, <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, @@ -985,7 +989,7 @@ tcsr_mutex_regs: syscon@1f40000 { compatible = "syscon"; - reg = <0x01f40000 0x20000>; + reg = <0x01f40000 0x40000>; }; tlmm: pinctrl@3400000 { @@ -998,11 +1002,12 @@ #interrupt-cells = <0x2>; }; - stm@6002000 { + stm: stm@6002000 { compatible = "arm,coresight-stm", "arm,primecell"; reg = <0x06002000 0x1000>, <0x16280000 0x180000>; reg-names = "stm-base", "stm-data-base"; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1016,9 +1021,10 @@ }; }; - funnel@6041000 { + funnel1: funnel@6041000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0x06041000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1045,9 +1051,10 @@ }; }; - funnel@6042000 { + funnel2: funnel@6042000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0x06042000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1075,9 +1082,10 @@ }; }; - funnel@6045000 { + funnel3: funnel@6045000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0x06045000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1113,9 +1121,10 @@ }; }; - replicator@6046000 { + replicator1: replicator@6046000 { compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; reg = <0x06046000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1137,9 +1146,10 @@ }; }; - etf@6047000 { + etf: etf@6047000 { compatible = "arm,coresight-tmc", "arm,primecell"; reg = <0x06047000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1163,9 +1173,10 @@ }; }; - etr@6048000 { + etr: etr@6048000 { compatible = "arm,coresight-tmc", "arm,primecell"; reg = <0x06048000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1181,9 +1192,10 @@ }; }; - etm@7840000 { + etm1: etm@7840000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07840000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1200,9 +1212,10 @@ }; }; - etm@7940000 { + etm2: etm@7940000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07940000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1219,9 +1232,10 @@ }; }; - etm@7a40000 { + etm3: etm@7a40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07a40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1238,9 +1252,10 @@ }; }; - etm@7b40000 { + etm4: etm@7b40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07b40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1257,9 +1272,10 @@ }; }; - funnel@7b60000 { /* APSS Funnel */ + funnel4: funnel@7b60000 { /* APSS Funnel */ compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07b60000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1343,9 +1359,10 @@ }; }; - funnel@7b70000 { + funnel5: funnel@7b70000 { compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; reg = <0x07b70000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; @@ -1369,66 +1386,78 @@ }; }; - etm@7c40000 { + etm5: etm@7c40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07c40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; cpu = <&CPU4>; - port{ - etm4_out: endpoint { - remote-endpoint = <&apss_funnel_in4>; + out-ports { + port{ + etm4_out: endpoint { + remote-endpoint = <&apss_funnel_in4>; + }; }; }; }; - etm@7d40000 { + etm6: etm@7d40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07d40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; cpu = <&CPU5>; - port{ - etm5_out: endpoint { - remote-endpoint = <&apss_funnel_in5>; + out-ports { + port{ + etm5_out: endpoint { + remote-endpoint = <&apss_funnel_in5>; + }; }; }; }; - etm@7e40000 { + etm7: etm@7e40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07e40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; cpu = <&CPU6>; - port{ - etm6_out: endpoint { - remote-endpoint = <&apss_funnel_in6>; + out-ports { + port{ + etm6_out: endpoint { + remote-endpoint = <&apss_funnel_in6>; + }; }; }; }; - etm@7f40000 { + etm8: etm@7f40000 { compatible = "arm,coresight-etm4x", "arm,primecell"; reg = <0x07f40000 0x1000>; + status = "disabled"; clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; cpu = <&CPU7>; - port{ - etm7_out: endpoint { - remote-endpoint = <&apss_funnel_in7>; + out-ports { + port{ + etm7_out: endpoint { + remote-endpoint = <&apss_funnel_in7>; + }; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/pm8150.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/pm8150.dtsi @@ -17,7 +17,7 @@ #size-cells = <0>; pon: power-on@800 { - compatible = "qcom,pm8916-pon"; + compatible = "qcom,pm8998-pon"; reg = <0x0800>; pwrkey { compatible = "qcom,pm8941-pwrkey"; @@ -73,18 +73,8 @@ reg = <0xc000>; gpio-controller; #gpio-cells = <2>; - interrupts = <0x0 0xc0 0x0 IRQ_TYPE_NONE>, - <0x0 0xc1 0x0 IRQ_TYPE_NONE>, - <0x0 0xc2 0x0 IRQ_TYPE_NONE>, - <0x0 0xc3 0x0 IRQ_TYPE_NONE>, - <0x0 0xc4 0x0 IRQ_TYPE_NONE>, - <0x0 0xc5 0x0 IRQ_TYPE_NONE>, - <0x0 0xc6 0x0 IRQ_TYPE_NONE>, - <0x0 0xc7 0x0 IRQ_TYPE_NONE>, - <0x0 0xc8 0x0 IRQ_TYPE_NONE>, - <0x0 0xc9 0x0 IRQ_TYPE_NONE>, - <0x0 0xca 0x0 IRQ_TYPE_NONE>, - <0x0 0xcb 0x0 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/pm8150b.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/pm8150b.dtsi @@ -62,18 +62,8 @@ reg = <0xc000>; gpio-controller; #gpio-cells = <2>; - interrupts = <0x2 0xc0 0x0 IRQ_TYPE_NONE>, - <0x2 0xc1 0x0 IRQ_TYPE_NONE>, - <0x2 0xc2 0x0 IRQ_TYPE_NONE>, - <0x2 0xc3 0x0 IRQ_TYPE_NONE>, - <0x2 0xc4 0x0 IRQ_TYPE_NONE>, - <0x2 0xc5 0x0 IRQ_TYPE_NONE>, - <0x2 0xc6 0x0 IRQ_TYPE_NONE>, - <0x2 0xc7 0x0 IRQ_TYPE_NONE>, - <0x2 0xc8 0x0 IRQ_TYPE_NONE>, - <0x2 0xc9 0x0 IRQ_TYPE_NONE>, - <0x2 0xca 0x0 IRQ_TYPE_NONE>, - <0x2 0xcb 0x0 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/pm8150l.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/pm8150l.dtsi @@ -56,18 +56,8 @@ reg = <0xc000>; gpio-controller; #gpio-cells = <2>; - interrupts = <0x4 0xc0 0x0 IRQ_TYPE_NONE>, - <0x4 0xc1 0x0 IRQ_TYPE_NONE>, - <0x4 0xc2 0x0 IRQ_TYPE_NONE>, - <0x4 0xc3 0x0 IRQ_TYPE_NONE>, - <0x4 0xc4 0x0 IRQ_TYPE_NONE>, - <0x4 0xc5 0x0 IRQ_TYPE_NONE>, - <0x4 0xc6 0x0 IRQ_TYPE_NONE>, - <0x4 0xc7 0x0 IRQ_TYPE_NONE>, - <0x4 0xc8 0x0 IRQ_TYPE_NONE>, - <0x4 0xc9 0x0 IRQ_TYPE_NONE>, - <0x4 0xca 0x0 IRQ_TYPE_NONE>, - <0x4 0xcb 0x0 IRQ_TYPE_NONE>; + interrupt-controller; + #interrupt-cells = <2>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -113,7 +113,7 @@ wcd_codec: codec@f000 { compatible = "qcom,pm8916-wcd-analog-codec"; - reg = <0xf000 0x200>; + reg = <0xf000>; reg-names = "pmic-codec-core"; clocks = <&gcc GCC_CODEC_DIGCODEC_CLK>; clock-names = "mclk"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi @@ -43,7 +43,7 @@ vddrf-supply = <&vreg_l1_1p3>; vddch0-supply = <&vdd_ch0_3p3>; - local-bd-address = [ 02 00 00 00 5a ad ]; + local-bd-address = [ 00 00 00 00 00 00 ]; max-speed = <3200000>; }; @@ -73,6 +73,7 @@ regulator-always-on; regulator-boot-on; regulator-name = "vdd_apc"; + regulator-initial-mode = <1>; regulator-min-microvolt = <1048000>; regulator-max-microvolt = <1384000>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/qcs404.dtsi @@ -533,7 +533,7 @@ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; resets = <&gcc GCC_PCIEPHY_0_PHY_BCR>, - <&gcc 21>; + <&gcc GCC_PCIE_0_PIPE_ARES>; reset-names = "phy", "pipe"; clock-output-names = "pcie_0_pipe_clk"; @@ -991,12 +991,12 @@ <&gcc GCC_PCIE_0_SLV_AXI_CLK>; clock-names = "iface", "aux", "master_bus", "slave_bus"; - resets = <&gcc 18>, - <&gcc 17>, - <&gcc 15>, - <&gcc 19>, + resets = <&gcc GCC_PCIE_0_AXI_MASTER_ARES>, + <&gcc GCC_PCIE_0_AXI_SLAVE_ARES>, + <&gcc GCC_PCIE_0_AXI_MASTER_STICKY_ARES>, + <&gcc GCC_PCIE_0_CORE_STICKY_ARES>, <&gcc GCC_PCIE_0_BCR>, - <&gcc 16>; + <&gcc GCC_PCIE_0_AHB_ARES>; reset-names = "axi_m", "axi_s", "axi_m_sticky", --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi @@ -165,6 +165,8 @@ /delete-node/ &venus_mem; /delete-node/ &cdsp_mem; /delete-node/ &cdsp_pas; +/delete-node/ &zap_shader; +/delete-node/ &gpu_mem; /* Increase the size from 120 MB to 128 MB */ &mpss_region { @@ -1308,7 +1310,7 @@ config { pins = "gpio126"; function = "gpio"; - bias-no-pull; + bias-disable; drive-strength = <2>; output-low; }; @@ -1318,7 +1320,7 @@ config { pins = "gpio126"; function = "gpio"; - bias-no-pull; + bias-disable; drive-strength = <2>; output-high; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -53,8 +53,8 @@ user4 { label = "green:user4"; gpios = <&pm8998_gpio 13 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "panic-indicator"; default-state = "off"; + panic-indicator; }; wlan { @@ -337,7 +337,9 @@ &gcc { protected-clocks = , , - ; + , + , + ; }; &pm8998_gpio { @@ -517,6 +519,8 @@ vdd-1.8-xo-supply = <&vreg_l7a_1p8>; vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + + qcom,snoc-host-cap-8bit-quirk; }; /* PINCTRL - additions to nodes defined in sdm845.dtsi */ --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -468,6 +468,8 @@ vdd-1.8-xo-supply = <&vreg_l7a_1p8>; vdd-1.3-rfa-supply = <&vreg_l17a_1p3>; vdd-3.3-ch0-supply = <&vreg_l25a_3p3>; + + qcom,snoc-host-cap-8bit-quirk; }; /* PINCTRL - additions to nodes defined in sdm845.dtsi */ --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -715,6 +715,7 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SDM845_CX>; }; qfprom@784000 { @@ -1419,6 +1420,8 @@ clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; + power-domains = <&gcc UFS_PHY_GDSC>; + resets = <&ufs_mem_hc 0>; reset-names = "ufsphy"; status = "disabled"; @@ -2500,10 +2503,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -2544,10 +2547,10 @@ <&gcc GCC_USB30_SEC_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -2824,7 +2827,7 @@ qcom,gmu = <&gmu>; - zap-shader { + zap_shader: zap-shader { memory-region = <&gpu_mem>; }; @@ -2939,6 +2942,15 @@ #power-domain-cells = <1>; }; + pdc_intc: interrupt-controller@b220000 { + compatible = "qcom,sdm845-pdc", "qcom,pdc"; + reg = <0 0x0b220000 0 0x30000>; + qcom,pdc-ranges = <0 480 94>, <94 609 15>, <115 630 7>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + pdc_reset: reset-controller@b2e0000 { compatible = "qcom,sdm845-pdc-global"; reg = <0 0x0b2e0000 0 0x20000>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -232,7 +232,9 @@ &gcc { protected-clocks = , , - ; + , + , + ; }; &i2c1 { @@ -243,24 +245,23 @@ &i2c3 { status = "okay"; clock-frequency = <400000>; + /* Overwrite pinctrl-0 from sdm845.dtsi */ + pinctrl-0 = <&qup_i2c3_default &i2c3_hid_active>; - hid@15 { + tsel: hid@15 { compatible = "hid-over-i2c"; reg = <0x15>; hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>; + interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; }; - hid@2c { + tsc2: hid@2c { compatible = "hid-over-i2c"; reg = <0x2c>; hid-descr-addr = <0x20>; - interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>; - - pinctrl-names = "default"; - pinctrl-0 = <&i2c2_hid_active>; + interrupts-extended = <&tlmm 37 IRQ_TYPE_LEVEL_HIGH>; }; }; @@ -268,15 +269,15 @@ status = "okay"; clock-frequency = <400000>; - hid@10 { + tsc1: hid@10 { compatible = "hid-over-i2c"; reg = <0x10>; hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>; + interrupts-extended = <&tlmm 125 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; - pinctrl-0 = <&i2c6_hid_active>; + pinctrl-0 = <&i2c5_hid_active>; }; }; @@ -284,7 +285,7 @@ status = "okay"; clock-frequency = <400000>; - hid@5c { + ecsh: hid@5c { compatible = "hid-over-i2c"; reg = <0x5c>; hid-descr-addr = <0x1>; @@ -292,13 +293,15 @@ interrupts-extended = <&tlmm 92 IRQ_TYPE_LEVEL_LOW>; pinctrl-names = "default"; - pinctrl-0 = <&i2c12_hid_active>; + pinctrl-0 = <&i2c11_hid_active>; }; }; &qup_i2c12_default { - drive-strength = <2>; - bias-disable; + pinmux { + drive-strength = <2>; + bias-disable; + }; }; &qup_uart6_default { @@ -335,7 +338,7 @@ &tlmm { gpio-reserved-ranges = <0 4>, <81 4>; - i2c2_hid_active: i2c2-hid-active { + i2c3_hid_active: i2c2-hid-active { pins = <37>; function = "gpio"; @@ -344,7 +347,7 @@ drive-strength = <2>; }; - i2c6_hid_active: i2c6-hid-active { + i2c5_hid_active: i2c5-hid-active { pins = <125>; function = "gpio"; @@ -353,7 +356,7 @@ drive-strength = <2>; }; - i2c12_hid_active: i2c12-hid-active { + i2c11_hid_active: i2c11-hid-active { pins = <92>; function = "gpio"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -336,7 +336,7 @@ <0x0 0x03D00000 0x0 0x300000>; reg-names = "west", "east", "north", "south"; interrupts = ; - gpio-ranges = <&tlmm 0 0 175>; + gpio-ranges = <&tlmm 0 0 176>; gpio-controller; #gpio-cells = <2>; interrupt-controller; @@ -459,9 +459,9 @@ qcom,tcs-offset = <0xd00>; qcom,drv-id = <2>; qcom,tcs-config = , - , - , - ; + , + , + ; rpmhcc: clock-controller { compatible = "qcom,sm8150-rpmh-clk"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/cat875.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/cat875.dtsi @@ -22,7 +22,6 @@ status = "okay"; phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; reg = <0>; interrupt-parent = <&gpio2>; interrupts = <21 IRQ_TYPE_LEVEL_LOW>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/hihope-common.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/hihope-common.dtsi @@ -86,7 +86,7 @@ label = "rcar-sound"; - dais = <&rsnd_port0>; + dais = <&rsnd_port>; }; vbus0_usb2: regulator-vbus0-usb2 { @@ -191,7 +191,7 @@ port@2 { reg = <2>; dw_hdmi0_snd_in: endpoint { - remote-endpoint = <&rsnd_endpoint0>; + remote-endpoint = <&rsnd_endpoint>; }; }; }; @@ -327,17 +327,15 @@ /* Single DAI */ #sound-dai-cells = <0>; - ports { - rsnd_port0: port@0 { - rsnd_endpoint0: endpoint { - remote-endpoint = <&dw_hdmi0_snd_in>; - - dai-format = "i2s"; - bitclock-master = <&rsnd_endpoint0>; - frame-master = <&rsnd_endpoint0>; + rsnd_port: port { + rsnd_endpoint: endpoint { + remote-endpoint = <&dw_hdmi0_snd_in>; + + dai-format = "i2s"; + bitclock-master = <&rsnd_endpoint>; + frame-master = <&rsnd_endpoint>; - playback = <&ssi2>; - }; + playback = <&ssi2>; }; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi @@ -23,7 +23,6 @@ status = "okay"; phy0: ethernet-phy@0 { - rxc-skew-ps = <1500>; reg = <0>; interrupt-parent = <&gpio2>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -1726,17 +1726,6 @@ "ssi.1", "ssi.0"; status = "disabled"; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; - }; - port@1 { - reg = <1>; - }; - }; - rcar_sound,ctu { ctu00: ctu-0 { }; ctu01: ctu-1 { }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a774c0.dtsi @@ -49,17 +49,14 @@ opp-shared; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; opp-suspend; }; @@ -1212,9 +1209,8 @@ reg = <0 0xe6ea0000 0 0x0064>; interrupts = ; clocks = <&cpg CPG_MOD 210>; - dmas = <&dmac1 0x43>, <&dmac1 0x42>, - <&dmac2 0x43>, <&dmac2 0x42>; - dma-names = "tx", "rx", "tx", "rx"; + dmas = <&dmac0 0x43>, <&dmac0 0x42>; + dma-names = "tx", "rx"; power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts @@ -59,7 +59,7 @@ memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ - reg = <0x0 0x48000000 0x0 0x38000000>; + reg = <0x0 0x48000000 0x0 0x78000000>; }; osc5_clk: osc5-clock { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77970.dtsi @@ -652,7 +652,7 @@ }; pwm3: pwm@e6e33000 { - compatible = "renesas,pwm-r8a7790", "renesas,pwm-rcar"; + compatible = "renesas,pwm-r8a77970", "renesas,pwm-rcar"; reg = <0 0xe6e33000 0 8>; #pwm-cells = <2>; clocks = <&cpg CPG_MOD 523>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77980.dtsi @@ -990,8 +990,8 @@ reg = <1>; - vin4csi41: endpoint@2 { - reg = <2>; + vin4csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin4>; }; }; @@ -1018,8 +1018,8 @@ reg = <1>; - vin5csi41: endpoint@2 { - reg = <2>; + vin5csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin5>; }; }; @@ -1046,8 +1046,8 @@ reg = <1>; - vin6csi41: endpoint@2 { - reg = <2>; + vin6csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin6>; }; }; @@ -1074,8 +1074,8 @@ reg = <1>; - vin7csi41: endpoint@2 { - reg = <2>; + vin7csi41: endpoint@3 { + reg = <3>; remote-endpoint = <&csi41vin7>; }; }; @@ -1318,6 +1318,7 @@ ipmmu_vip0: mmu@e7b00000 { compatible = "renesas,ipmmu-r8a77980"; reg = <0 0xe7b00000 0 0x1000>; + renesas,ipmmu-main = <&ipmmu_mm 4>; power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; #iommu-cells = <1>; }; @@ -1325,6 +1326,7 @@ ipmmu_vip1: mmu@e7960000 { compatible = "renesas,ipmmu-r8a77980"; reg = <0 0xe7960000 0 0x1000>; + renesas,ipmmu-main = <&ipmmu_mm 11>; power-domains = <&sysc R8A77980_PD_ALWAYS_ON>; #iommu-cells = <1>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts @@ -636,7 +636,6 @@ /* audio_clkout0/1/2/3 */ #clock-cells = <1>; clock-frequency = <12288000 11289600>; - clkout-lr-synchronous; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77990.dtsi @@ -60,17 +60,14 @@ opp-shared; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <820000>; clock-latency-ns = <300000>; opp-suspend; }; @@ -1168,9 +1165,8 @@ reg = <0 0xe6ea0000 0 0x0064>; interrupts = ; clocks = <&cpg CPG_MOD 210>; - dmas = <&dmac1 0x43>, <&dmac1 0x42>, - <&dmac2 0x43>, <&dmac2 0x42>; - dma-names = "tx", "rx", "tx", "rx"; + dmas = <&dmac0 0x43>, <&dmac0 0x42>; + dma-names = "tx", "rx"; power-domains = <&sysc R8A77990_PD_ALWAYS_ON>; resets = <&cpg 210>; #address-cells = <1>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/r8a77995-draak.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/r8a77995-draak.dts @@ -277,10 +277,6 @@ interrupt-parent = <&gpio1>; interrupts = <28 IRQ_TYPE_LEVEL_LOW>; - /* Depends on LVDS */ - max-clock = <135000000>; - min-vrefresh = <50>; - adi,input-depth = <8>; adi,input-colorspace = "rgb"; adi,input-clock = "1x"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi @@ -269,7 +269,7 @@ }; scif1_pins: scif1 { - groups = "scif1_data_b", "scif1_ctrl"; + groups = "scif1_data_b"; function = "scif1"; }; @@ -329,7 +329,6 @@ &scif1 { pinctrl-0 = <&scif1_pins>; pinctrl-names = "default"; - uart-has-rtscts; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/renesas/ulcb.dtsi @@ -470,6 +470,7 @@ mmc-hs200-1_8v; mmc-hs400-1_8v; non-removable; + full-pwr-cycle-in-suspend; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/px30.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -213,28 +213,31 @@ #size-cells = <0>; /* These power domains are grouped by VD_LOGIC */ - pd_usb@PX30_PD_USB { + power-domain@PX30_PD_USB { reg = ; clocks = <&cru HCLK_HOST>, <&cru HCLK_OTG>, <&cru SCLK_OTG_ADP>; pm_qos = <&qos_usb_host>, <&qos_usb_otg>; + #power-domain-cells = <0>; }; - pd_sdcard@PX30_PD_SDCARD { + power-domain@PX30_PD_SDCARD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sdmmc>; + #power-domain-cells = <0>; }; - pd_gmac@PX30_PD_GMAC { + power-domain@PX30_PD_GMAC { reg = ; clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>, <&cru SCLK_MAC_REF>, <&cru SCLK_GMAC_RX_TX>; pm_qos = <&qos_gmac>; + #power-domain-cells = <0>; }; - pd_mmc_nand@PX30_PD_MMC_NAND { + power-domain@PX30_PD_MMC_NAND { reg = ; clocks = <&cru HCLK_NANDC>, <&cru HCLK_EMMC>, @@ -246,15 +249,17 @@ <&cru SCLK_SFC>; pm_qos = <&qos_emmc>, <&qos_nand>, <&qos_sdio>, <&qos_sfc>; + #power-domain-cells = <0>; }; - pd_vpu@PX30_PD_VPU { + power-domain@PX30_PD_VPU { reg = ; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>, <&cru SCLK_CORE_VPU>; pm_qos = <&qos_vpu>, <&qos_vpu_r128>; + #power-domain-cells = <0>; }; - pd_vo@PX30_PD_VO { + power-domain@PX30_PD_VO { reg = ; clocks = <&cru ACLK_RGA>, <&cru ACLK_VOPB>, @@ -269,8 +274,9 @@ <&cru SCLK_VOPB_PWM>; pm_qos = <&qos_rga_rd>, <&qos_rga_wr>, <&qos_vop_m0>, <&qos_vop_m1>; + #power-domain-cells = <0>; }; - pd_vi@PX30_PD_VI { + power-domain@PX30_PD_VI { reg = ; clocks = <&cru ACLK_CIF>, <&cru ACLK_ISP>, @@ -280,11 +286,13 @@ pm_qos = <&qos_isp_128>, <&qos_isp_rd>, <&qos_isp_wr>, <&qos_isp_m1>, <&qos_vip>; + #power-domain-cells = <0>; }; - pd_gpu@PX30_PD_GPU { + power-domain@PX30_PD_GPU { reg = ; clocks = <&cru SCLK_GPU>; pm_qos = <&qos_gpu>; + #power-domain-cells = <0>; }; }; }; @@ -768,7 +776,7 @@ interrupts = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; pinctrl-names = "default"; @@ -783,7 +791,7 @@ interrupts = ; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; pinctrl-names = "default"; @@ -798,7 +806,7 @@ interrupts = ; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; max-frequency = <150000000>; power-domains = <&power PX30_PD_MMC_NAND>; @@ -860,7 +868,7 @@ vopl_mmu: iommu@ff470f00 { compatible = "rockchip,iommu"; reg = <0x0 0xff470f00 0x0 0x100>; - interrupts = ; + interrupts = ; interrupt-names = "vopl_mmu"; clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>; clock-names = "aclk", "hclk"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -86,13 +86,13 @@ assigned-clock-rate = <50000000>; assigned-clocks = <&cru SCLK_MAC2PHY>; assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>; - + status = "okay"; }; &i2c1 { status = "okay"; - rk805: rk805@18 { + rk805: pmic@18 { compatible = "rockchip,rk805"; reg = <0x18>; interrupt-parent = <&gpio2>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts @@ -90,7 +90,6 @@ linux,default-trigger = "heartbeat"; gpios = <&rk805 1 GPIO_ACTIVE_LOW>; default-state = "on"; - mode = <0x23>; }; user { @@ -98,7 +97,6 @@ linux,default-trigger = "mmc1"; gpios = <&rk805 0 GPIO_ACTIVE_LOW>; default-state = "off"; - mode = <0x05>; }; }; }; @@ -333,6 +331,7 @@ }; &usb20_otg { + dr_mode = "host"; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -169,7 +169,7 @@ &i2c1 { status = "okay"; - rk805: rk805@18 { + rk805: pmic@18 { compatible = "rockchip,rk805"; reg = <0x18>; interrupt-parent = <&gpio2>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -270,15 +270,19 @@ #address-cells = <1>; #size-cells = <0>; - pd_hevc@RK3328_PD_HEVC { + power-domain@RK3328_PD_HEVC { reg = ; + clocks = <&cru SCLK_VENC_CORE>; + #power-domain-cells = <0>; }; - pd_video@RK3328_PD_VIDEO { + power-domain@RK3328_PD_VIDEO { reg = ; + #power-domain-cells = <0>; }; - pd_vpu@RK3328_PD_VPU { + power-domain@RK3328_PD_VPU { reg = ; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; + #power-domain-cells = <0>; }; }; @@ -555,7 +559,7 @@ gpu: gpu@ff300000 { compatible = "rockchip,rk3328-mali", "arm,mali-450"; - reg = <0x0 0xff300000 0x0 0x40000>; + reg = <0x0 0xff300000 0x0 0x30000>; interrupts = , , , @@ -667,8 +671,7 @@ compatible = "rockchip,rk3328-dw-hdmi"; reg = <0x0 0xff3c0000 0x0 0x20000>; reg-io-width = <4>; - interrupts = , - ; + interrupts = ; clocks = <&cru PCLK_HDMI>, <&cru SCLK_HDMI_SFC>, <&cru SCLK_RTC32K>; @@ -684,11 +687,20 @@ status = "disabled"; ports { - hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; + hdmi_in_vop: endpoint { remote-endpoint = <&vop_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; @@ -754,8 +766,8 @@ <0>, <24000000>, <24000000>, <24000000>, <15000000>, <15000000>, - <100000000>, <100000000>, - <100000000>, <100000000>, + <300000000>, <100000000>, + <400000000>, <100000000>, <50000000>, <100000000>, <100000000>, <100000000>, <50000000>, <50000000>, @@ -1190,8 +1202,8 @@ uart0 { uart0_xfer: uart0-xfer { - rockchip,pins = <1 RK_PB1 1 &pcfg_pull_up>, - <1 RK_PB0 1 &pcfg_pull_none>; + rockchip,pins = <1 RK_PB1 1 &pcfg_pull_none>, + <1 RK_PB0 1 &pcfg_pull_up>; }; uart0_cts: uart0-cts { @@ -1209,8 +1221,8 @@ uart1 { uart1_xfer: uart1-xfer { - rockchip,pins = <3 RK_PA4 4 &pcfg_pull_up>, - <3 RK_PA6 4 &pcfg_pull_none>; + rockchip,pins = <3 RK_PA4 4 &pcfg_pull_none>, + <3 RK_PA6 4 &pcfg_pull_up>; }; uart1_cts: uart1-cts { @@ -1228,15 +1240,15 @@ uart2-0 { uart2m0_xfer: uart2m0-xfer { - rockchip,pins = <1 RK_PA0 2 &pcfg_pull_up>, - <1 RK_PA1 2 &pcfg_pull_none>; + rockchip,pins = <1 RK_PA0 2 &pcfg_pull_none>, + <1 RK_PA1 2 &pcfg_pull_up>; }; }; uart2-1 { uart2m1_xfer: uart2m1-xfer { - rockchip,pins = <2 RK_PA0 1 &pcfg_pull_up>, - <2 RK_PA1 1 &pcfg_pull_none>; + rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, + <2 RK_PA1 1 &pcfg_pull_up>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi @@ -56,7 +56,6 @@ fan: fan@18 { compatible = "ti,amc6821"; reg = <0x18>; - #cooling-cells = <2>; }; rtc_twi: rtc@6f { @@ -156,7 +155,7 @@ pinctrl-0 = <&rgmii_pins>; snps,reset-active-low; snps,reset-delays-us = <0 10000 50000>; - snps,reset-gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>; + snps,reset-gpio = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>; tx_delay = <0x10>; rx_delay = <0x10>; status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -686,6 +686,7 @@ dma-names = "tx"; pinctrl-names = "default"; pinctrl-0 = <&spdif_tx>; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -697,6 +698,7 @@ clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>; dmas = <&dmac_bus 6>, <&dmac_bus 7>; dma-names = "tx", "rx"; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -710,6 +712,7 @@ dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&i2s_8ch_bus>; + #sound-dai-cells = <0>; status = "disabled"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts @@ -666,12 +666,15 @@ sd-uhs-sdr104; /* Power supply */ - vqmmc-supply = &vcc1v8_s3; /* IO line */ - vmmc-supply = &vcc_sdio; /* card's power */ + vqmmc-supply = <&vcc1v8_s3>; /* IO line */ + vmmc-supply = <&vcc_sdio>; /* card's power */ + #address-cells = <1>; + #size-cells = <0>; status = "okay"; brcmf: wifi@1 { + reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio0>; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts @@ -77,3 +77,8 @@ }; }; }; + +&wlan_host_wake_l { + /* Kevin has an external pull up, but Bob does not. */ + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; +}; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi @@ -237,6 +237,14 @@ &edp { status = "okay"; + /* + * eDP PHY/clk don't sync reliably at anything other than 24 MHz. Only + * set this here, because rk3399-gru.dtsi ensures we can generate this + * off GPLL=600MHz, whereas some other RK3399 boards may not. + */ + assigned-clocks = <&cru PCLK_EDP>; + assigned-clock-rates = <24000000>; + ports { edp_out: port@1 { reg = <1>; @@ -397,6 +405,7 @@ }; wlan_host_wake_l: wlan-host-wake-l { + /* Kevin has an external pull up, but Bob does not */ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -281,7 +281,7 @@ sound: sound { compatible = "rockchip,rk3399-gru-sound"; - rockchip,cpu = <&i2s0 &i2s2>; + rockchip,cpu = <&i2s0 &spdif>; }; }; @@ -432,10 +432,6 @@ status = "okay"; }; -&i2s2 { - status = "okay"; -}; - &io_domains { status = "okay"; @@ -532,6 +528,17 @@ vqmmc-supply = <&ppvar_sd_card_io>; }; +&spdif { + status = "okay"; + + /* + * SPDIF is routed internally to DP; we either don't use these pins, or + * mux them to something else. + */ + /delete-property/ pinctrl-0; + /delete-property/ pinctrl-names; +}; + &spi1 { status = "okay"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi @@ -654,9 +654,12 @@ sd-uhs-sdr104; vqmmc-supply = <&vcc1v8_s3>; vmmc-supply = <&vccio_sd>; + #address-cells = <1>; + #size-cells = <0>; status = "okay"; brcmf: wifi@1 { + reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio0>; interrupts = ; @@ -682,7 +685,6 @@ &sdhci { bus-width = <8>; mmc-hs400-1_8v; - mmc-hs400-enhanced-strobe; non-removable; status = "okay"; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts @@ -49,7 +49,7 @@ regulator-boot-on; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - vim-supply = <&vcc3v3_sys>; + vin-supply = <&vcc3v3_sys>; }; vcc3v3_sys: vcc3v3-sys { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts @@ -94,33 +94,6 @@ }; }; -&gpu_thermal { - trips { - gpu_warm: gpu_warm { - temperature = <55000>; - hysteresis = <2000>; - type = "active"; - }; - - gpu_hot: gpu_hot { - temperature = <65000>; - hysteresis = <2000>; - type = "active"; - }; - }; - cooling-maps { - map1 { - trip = <&gpu_warm>; - cooling-device = <&fan THERMAL_NO_LIMIT 1>; - }; - - map2 { - trip = <&gpu_hot>; - cooling-device = <&fan 2 THERMAL_NO_LIMIT>; - }; - }; -}; - &pinctrl { ir { ir_rx: ir-rx { --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts @@ -648,9 +648,12 @@ pinctrl-names = "default"; pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; sd-uhs-sdr104; + #address-cells = <1>; + #size-cells = <0>; status = "okay"; brcmf: wifi@1 { + reg = <1>; compatible = "brcm,bcm4329-fmac"; interrupt-parent = <&gpio0>; interrupts = ; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts @@ -203,7 +203,7 @@ cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp; - max-frequency = <150000000>; + max-frequency = <40000000>; pinctrl-names = "default"; pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; vmmc-supply = <&vcc3v3_baseboard>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi @@ -101,8 +101,7 @@ vcc5v0_host: vcc5v0-host-regulator { compatible = "regulator-fixed"; - gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; - enable-active-low; + gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&vcc5v0_host_en>; regulator-name = "vcc5v0_host"; @@ -149,6 +148,22 @@ drive-impedance-ohm = <33>; }; +&gpio3 { + /* + * The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module + * eMMC and SPI flash powered-down initially (in fact it keeps the + * reset signal asserted). BIOS_DISABLE_OVERRIDE pin allows to override + * that signal so that eMMC and SPI can be used regardless of the state + * of the signal. + */ + bios-disable-override-hog { + gpios = ; + gpio-hog; + line-name = "bios_disable_override"; + output-high; + }; +}; + &gmac { assigned-clocks = <&cru SCLK_RMII_SRC>; assigned-clock-parents = <&clkin_gmac>; @@ -157,11 +172,11 @@ phy-mode = "rgmii"; pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - snps,reset-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + snps,reset-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; snps,reset-active-low; snps,reset-delays-us = <0 10000 50000>; tx_delay = <0x10>; - rx_delay = <0x10>; + rx_delay = <0x23>; status = "okay"; }; @@ -426,16 +441,27 @@ gpio1830-supply = <&vcc_1v8>; }; -&pmu_io_domains { - status = "okay"; - pmu1830-supply = <&vcc_1v8>; -}; - -&pwm2 { - status = "okay"; +&pcie_clkreqn_cpm { + rockchip,pins = + <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; }; &pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&q7_thermal_pin &bios_disable_override_hog_pin>; + + gpios { + bios_disable_override_hog_pin: bios-disable-override-hog-pin { + rockchip,pins = + <3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + q7_thermal_pin: q7-thermal-pin { + rockchip,pins = + <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + i2c8 { i2c8_xfer_a: i2c8-xfer { rockchip,pins = @@ -466,7 +492,22 @@ }; }; +&pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_1v8>; +}; + +&pwm2 { + status = "okay"; +}; + &sdhci { + /* + * Signal integrity isn't great at 200MHz but 100MHz has proven stable + * enough. + */ + max-frequency = <100000000>; + bus-width = <8>; mmc-hs400-1_8v; mmc-hs400-enhanced-strobe; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts @@ -441,7 +441,6 @@ &i2s1 { rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; - status = "okay"; }; &i2s2 { @@ -452,7 +451,7 @@ status = "okay"; bt656-supply = <&vcc_3v0>; - audio-supply = <&vcc_3v0>; + audio-supply = <&vcc1v8_codec>; sdmmc-supply = <&vcc_sdio>; gpio1830-supply = <&vcc_3v0>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi @@ -557,7 +557,7 @@ bluetooth { compatible = "brcm,bcm43438-bt"; clocks = <&rk808 1>; - clock-names = "ext_clock"; + clock-names = "txco"; device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>; host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts @@ -159,7 +159,7 @@ status = "okay"; rt5651: rt5651@1a { - compatible = "rockchip,rt5651"; + compatible = "realtek,rt5651"; reg = <0x1a>; clocks = <&cru SCLK_I2S_8CH_OUT>; clock-names = "mclk"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -29,6 +29,9 @@ i2c6 = &i2c6; i2c7 = &i2c7; i2c8 = &i2c8; + mmc0 = &sdio0; + mmc1 = &sdmmc; + mmc2 = &sdhci; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -229,6 +232,7 @@ reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; reg-names = "axi-base", "apb-base"; + device_type = "pci"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; @@ -247,7 +251,6 @@ <0 0 0 2 &pcie0_intc 1>, <0 0 0 3 &pcie0_intc 2>, <0 0 0 4 &pcie0_intc 3>; - linux,pci-domain = <0>; max-link-speed = <1>; msi-map = <0x0 &its 0x0 0x1000>; phys = <&pcie_phy 0>, <&pcie_phy 1>, @@ -410,7 +413,7 @@ reset-names = "usb3-otg"; status = "disabled"; - usbdrd_dwc3_0: dwc3 { + usbdrd_dwc3_0: usb@fe800000 { compatible = "snps,dwc3"; reg = <0x0 0xfe800000 0x0 0x100000>; interrupts = ; @@ -446,7 +449,7 @@ reset-names = "usb3-otg"; status = "disabled"; - usbdrd_dwc3_1: dwc3 { + usbdrd_dwc3_1: usb@fe900000 { compatible = "snps,dwc3"; reg = <0x0 0xfe900000 0x0 0x100000>; interrupts = ; @@ -998,6 +1001,7 @@ clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; pm_qos = <&qos_iep>; + #power-domain-cells = <0>; }; pd_rga@RK3399_PD_RGA { reg = ; @@ -1005,12 +1009,14 @@ <&cru HCLK_RGA>; pm_qos = <&qos_rga_r>, <&qos_rga_w>; + #power-domain-cells = <0>; }; pd_vcodec@RK3399_PD_VCODEC { reg = ; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; pm_qos = <&qos_video_m0>; + #power-domain-cells = <0>; }; pd_vdu@RK3399_PD_VDU { reg = ; @@ -1018,6 +1024,7 @@ <&cru HCLK_VDU>; pm_qos = <&qos_video_m1_r>, <&qos_video_m1_w>; + #power-domain-cells = <0>; }; /* These power domains are grouped by VD_GPU */ @@ -1025,43 +1032,63 @@ reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; + #power-domain-cells = <0>; }; /* These power domains are grouped by VD_LOGIC */ pd_edp@RK3399_PD_EDP { reg = ; clocks = <&cru PCLK_EDP_CTRL>; + #power-domain-cells = <0>; }; pd_emmc@RK3399_PD_EMMC { reg = ; clocks = <&cru ACLK_EMMC>; pm_qos = <&qos_emmc>; + #power-domain-cells = <0>; }; pd_gmac@RK3399_PD_GMAC { reg = ; clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>; pm_qos = <&qos_gmac>; + #power-domain-cells = <0>; }; pd_sd@RK3399_PD_SD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sd>; + #power-domain-cells = <0>; }; pd_sdioaudio@RK3399_PD_SDIOAUDIO { reg = ; clocks = <&cru HCLK_SDIO>; pm_qos = <&qos_sdioaudio>; + #power-domain-cells = <0>; + }; + pd_tcpc0@RK3399_PD_TCPD0 { + reg = ; + clocks = <&cru SCLK_UPHY0_TCPDCORE>, + <&cru SCLK_UPHY0_TCPDPHY_REF>; + #power-domain-cells = <0>; + }; + pd_tcpc1@RK3399_PD_TCPD1 { + reg = ; + clocks = <&cru SCLK_UPHY1_TCPDCORE>, + <&cru SCLK_UPHY1_TCPDPHY_REF>; + #power-domain-cells = <0>; }; pd_usb3@RK3399_PD_USB3 { reg = ; clocks = <&cru ACLK_USB3>; pm_qos = <&qos_usb_otg0>, <&qos_usb_otg1>; + #power-domain-cells = <0>; }; pd_vio@RK3399_PD_VIO { reg = ; + #power-domain-cells = <1>; #address-cells = <1>; #size-cells = <0>; @@ -1071,6 +1098,7 @@ <&cru HCLK_HDCP>, <&cru PCLK_HDCP>; pm_qos = <&qos_hdcp>; + #power-domain-cells = <0>; }; pd_isp0@RK3399_PD_ISP0 { reg = ; @@ -1078,6 +1106,7 @@ <&cru HCLK_ISP0>; pm_qos = <&qos_isp0_m0>, <&qos_isp0_m1>; + #power-domain-cells = <0>; }; pd_isp1@RK3399_PD_ISP1 { reg = ; @@ -1085,19 +1114,11 @@ <&cru HCLK_ISP1>; pm_qos = <&qos_isp1_m0>, <&qos_isp1_m1>; - }; - pd_tcpc0@RK3399_PD_TCPC0 { - reg = ; - clocks = <&cru SCLK_UPHY0_TCPDCORE>, - <&cru SCLK_UPHY0_TCPDPHY_REF>; - }; - pd_tcpc1@RK3399_PD_TCPC1 { - reg = ; - clocks = <&cru SCLK_UPHY1_TCPDCORE>, - <&cru SCLK_UPHY1_TCPDPHY_REF>; + #power-domain-cells = <0>; }; pd_vo@RK3399_PD_VO { reg = ; + #power-domain-cells = <1>; #address-cells = <1>; #size-cells = <0>; @@ -1107,12 +1128,14 @@ <&cru HCLK_VOP0>; pm_qos = <&qos_vop_big_r>, <&qos_vop_big_w>; + #power-domain-cells = <0>; }; pd_vopl@RK3399_PD_VOPL { reg = ; clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; pm_qos = <&qos_vop_little>; + #power-domain-cells = <0>; }; }; }; @@ -1444,6 +1467,7 @@ reg = <0xf780 0x24>; clocks = <&sdhci>; clock-names = "emmcclk"; + drive-impedance-ohm = <50>; #phy-cells = <0>; status = "disabled"; }; @@ -1454,7 +1478,6 @@ clock-names = "refclk"; #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; - drive-impedance-ohm = <50>; reset-names = "phy"; status = "disabled"; }; @@ -1740,21 +1763,25 @@ hdmi: hdmi@ff940000 { compatible = "rockchip,rk3399-dw-hdmi"; reg = <0x0 0xff940000 0x0 0x20000>; + reg-io-width = <4>; interrupts = ; clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, - <&cru PLL_VPLL>, + <&cru SCLK_HDMI_CEC>, <&cru PCLK_VIO_GRF>, - <&cru SCLK_HDMI_CEC>; - clock-names = "iahb", "isfr", "vpll", "grf", "cec"; + <&cru PLL_VPLL>; + clock-names = "iahb", "isfr", "cec", "grf", "vpll"; power-domains = <&power RK3399_PD_HDCP>; - reg-io-width = <4>; rockchip,grf = <&grf>; #sound-dai-cells = <0>; status = "disabled"; ports { - hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + + hdmi_in: port@0 { + reg = <0>; #address-cells = <1>; #size-cells = <0>; @@ -1767,6 +1794,10 @@ remote-endpoint = <&vopl_out_hdmi>; }; }; + + hdmi_out: port@1 { + reg = <1>; + }; }; }; @@ -1881,10 +1912,10 @@ gpu: gpu@ff9a0000 { compatible = "rockchip,rk3399-mali", "arm,mali-t860"; reg = <0x0 0xff9a0000 0x0 0x10000>; - interrupts = , - , - ; - interrupt-names = "gpu", "job", "mmu"; + interrupts = , + , + ; + interrupt-names = "job", "mmu", "gpu"; clocks = <&cru ACLK_GPU>; power-domains = <&power RK3399_PD_GPU>; status = "disabled"; @@ -2314,7 +2345,7 @@ }; }; - sleep { + suspend { ap_pwroff: ap-pwroff { rockchip,pins = <1 RK_PA5 1 &pcfg_pull_none>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi @@ -718,7 +718,7 @@ clocks = <&sys_clk 6>; reset-names = "ether"; resets = <&sys_rst 6>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; local-mac-address = [00 00 00 00 00 00]; socionext,syscon-phy-mode = <&soc_glue 0>; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi @@ -509,7 +509,7 @@ clocks = <&sys_clk 6>; reset-names = "ether"; resets = <&sys_rst 6>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; local-mac-address = [00 00 00 00 00 00]; socionext,syscon-phy-mode = <&soc_glue 0>; @@ -530,7 +530,7 @@ clocks = <&sys_clk 7>; reset-names = "ether"; resets = <&sys_rst 7>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; local-mac-address = [00 00 00 00 00 00]; socionext,syscon-phy-mode = <&soc_glue 1>; @@ -544,8 +544,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65a00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 134 4>, <0 135 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 134 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb2>; clock-names = "ref", "bus_early", "suspend"; @@ -646,8 +646,8 @@ compatible = "socionext,uniphier-dwc3", "snps,dwc3"; status = "disabled"; reg = <0x65c00000 0xcd00>; - interrupt-names = "host", "peripheral"; - interrupts = <0 137 4>, <0 138 4>; + interrupt-names = "dwc_usb3"; + interrupts = <0 137 4>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usb1>, <&pinctrl_usb3>; clock-names = "ref", "bus_early", "suspend"; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -307,6 +307,7 @@ interrupts = ; dma-coherent; power-domains = <&k3_pds 151 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>; assigned-clock-parents = <&k3_clks 151 4>, /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ <&k3_clks 151 9>; /* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */ @@ -346,6 +347,7 @@ interrupts = ; dma-coherent; power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>; + clocks = <&k3_clks 152 2>; assigned-clocks = <&k3_clks 152 2>; assigned-clock-parents = <&k3_clks 152 4>; /* set REF_CLK to 20MHz i.e. PER0_PLL/48 */ --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -43,6 +43,7 @@ smmu0: smmu@36600000 { compatible = "arm,smmu-v3"; reg = <0x0 0x36600000 0x0 0x100000>; + power-domains = <&k3_pds 229 TI_SCI_PD_EXCLUSIVE>; interrupt-parent = <&gic500>; interrupts = , ; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/ti/k3-j721e.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/ti/k3-j721e.dtsi @@ -60,7 +60,7 @@ i-cache-sets = <256>; d-cache-size = <0x8000>; d-cache-line-size = <64>; - d-cache-sets = <128>; + d-cache-sets = <256>; next-level-cache = <&L2_0>; }; @@ -74,7 +74,7 @@ i-cache-sets = <256>; d-cache-size = <0x8000>; d-cache-line-size = <64>; - d-cache-sets = <128>; + d-cache-sets = <256>; next-level-cache = <&L2_0>; }; }; @@ -84,7 +84,7 @@ cache-level = <2>; cache-size = <0x100000>; cache-line-size = <64>; - cache-sets = <2048>; + cache-sets = <1024>; next-level-cache = <&msmc_l3>; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts +++ linux-oracle-5.4.0/arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts @@ -131,7 +131,7 @@ reg = <0>; partition@0 { - label = "data"; + label = "spi0-data"; reg = <0x0 0x100000>; }; }; @@ -149,7 +149,7 @@ reg = <0>; partition@0 { - label = "data"; + label = "spi1-data"; reg = <0x0 0x84000>; }; }; --- linux-oracle-5.4.0.orig/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ linux-oracle-5.4.0/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -419,7 +419,7 @@ }; i2c0: i2c@ff020000 { - compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10"; + compatible = "cdns,i2c-r1p14"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 17 4>; @@ -429,7 +429,7 @@ }; i2c1: i2c@ff030000 { - compatible = "cdns,i2c-r1p14", "cdns,i2c-r1p10"; + compatible = "cdns,i2c-r1p14"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 18 4>; @@ -582,7 +582,7 @@ }; uart0: serial@ff000000 { - compatible = "cdns,uart-r1p12", "xlnx,xuartps"; + compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 21 4>; @@ -591,7 +591,7 @@ }; uart1: serial@ff010000 { - compatible = "cdns,uart-r1p12", "xlnx,xuartps"; + compatible = "xlnx,zynqmp-uart", "cdns,uart-r1p12"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 22 4>; --- linux-oracle-5.4.0.orig/arch/arm64/crypto/Kconfig +++ linux-oracle-5.4.0/arch/arm64/crypto/Kconfig @@ -59,6 +59,7 @@ select CRYPTO_HASH select CRYPTO_GF128MUL select CRYPTO_LIB_AES + select CRYPTO_AEAD config CRYPTO_CRCT10DIF_ARM64_CE tristate "CRCT10DIF digest algorithm using PMULL instructions" --- linux-oracle-5.4.0.orig/arch/arm64/crypto/aes-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/aes-glue.c @@ -55,7 +55,7 @@ #define aes_mac_update neon_aes_mac_update MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON"); #endif -#if defined(USE_V8_CRYPTO_EXTENSIONS) || !defined(CONFIG_CRYPTO_AES_ARM64_BS) +#if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS) MODULE_ALIAS_CRYPTO("ecb(aes)"); MODULE_ALIAS_CRYPTO("cbc(aes)"); MODULE_ALIAS_CRYPTO("ctr(aes)"); @@ -668,7 +668,7 @@ } static struct skcipher_alg aes_algs[] = { { -#if defined(USE_V8_CRYPTO_EXTENSIONS) || !defined(CONFIG_CRYPTO_AES_ARM64_BS) +#if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS) .base = { .cra_name = "__ecb(aes)", .cra_driver_name = "__ecb-aes-" MODE, --- linux-oracle-5.4.0.orig/arch/arm64/crypto/aes-neonbs-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/aes-neonbs-glue.c @@ -384,7 +384,7 @@ goto xts_tail; kernel_neon_end(); - skcipher_walk_done(&walk, nbytes); + err = skcipher_walk_done(&walk, nbytes); } if (err || likely(!tail)) --- linux-oracle-5.4.0.orig/arch/arm64/crypto/ghash-ce-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/ghash-ce-glue.c @@ -261,7 +261,7 @@ static struct shash_alg ghash_alg[] = {{ .base.cra_name = "ghash", .base.cra_driver_name = "ghash-neon", - .base.cra_priority = 100, + .base.cra_priority = 150, .base.cra_blocksize = GHASH_BLOCK_SIZE, .base.cra_ctxsize = sizeof(struct ghash_key), .base.cra_module = THIS_MODULE, --- linux-oracle-5.4.0.orig/arch/arm64/crypto/nhpoly1305-neon-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/nhpoly1305-neon-glue.c @@ -30,7 +30,7 @@ return crypto_nhpoly1305_update(desc, src, srclen); do { - unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); + unsigned int n = min_t(unsigned int, srclen, SZ_4K); kernel_neon_begin(); crypto_nhpoly1305_update_helper(desc, src, n, _nh_neon); --- linux-oracle-5.4.0.orig/arch/arm64/crypto/sha1-ce-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/sha1-ce-glue.c @@ -19,6 +19,7 @@ MODULE_DESCRIPTION("SHA1 secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("sha1"); struct sha1_ce_state { struct sha1_state sst; --- linux-oracle-5.4.0.orig/arch/arm64/crypto/sha2-ce-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/sha2-ce-glue.c @@ -19,6 +19,8 @@ MODULE_DESCRIPTION("SHA-224/SHA-256 secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("sha224"); +MODULE_ALIAS_CRYPTO("sha256"); struct sha256_ce_state { struct sha256_state sst; --- linux-oracle-5.4.0.orig/arch/arm64/crypto/sha3-ce-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/sha3-ce-glue.c @@ -23,6 +23,10 @@ MODULE_DESCRIPTION("SHA3 secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("sha3-224"); +MODULE_ALIAS_CRYPTO("sha3-256"); +MODULE_ALIAS_CRYPTO("sha3-384"); +MODULE_ALIAS_CRYPTO("sha3-512"); asmlinkage void sha3_ce_transform(u64 *st, const u8 *data, int blocks, int md_len); --- linux-oracle-5.4.0.orig/arch/arm64/crypto/sha512-ce-glue.c +++ linux-oracle-5.4.0/arch/arm64/crypto/sha512-ce-glue.c @@ -23,6 +23,8 @@ MODULE_DESCRIPTION("SHA-384/SHA-512 secure hash using ARMv8 Crypto Extensions"); MODULE_AUTHOR("Ard Biesheuvel "); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS_CRYPTO("sha384"); +MODULE_ALIAS_CRYPTO("sha512"); asmlinkage void sha512_ce_transform(struct sha512_state *sst, u8 const *src, int blocks); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/acpi.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/acpi.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -31,14 +32,14 @@ * is therefore used to delimit the MADT GICC structure minimum length * appropriately. */ -#define ACPI_MADT_GICC_MIN_LENGTH ACPI_OFFSET( \ +#define ACPI_MADT_GICC_MIN_LENGTH offsetof( \ struct acpi_madt_generic_interrupt, efficiency_class) #define BAD_MADT_GICC_ENTRY(entry, end) \ (!(entry) || (entry)->header.length < ACPI_MADT_GICC_MIN_LENGTH || \ (unsigned long)(entry) + (entry)->header.length > (end)) -#define ACPI_MADT_GICC_SPE (ACPI_OFFSET(struct acpi_madt_generic_interrupt, \ +#define ACPI_MADT_GICC_SPE (offsetof(struct acpi_madt_generic_interrupt, \ spe_interrupt) + sizeof(u16)) /* Basic configuration for ACPI */ @@ -109,6 +110,18 @@ return acpi_cpu_get_madt_gicc(cpu)->uid; } +static inline int get_cpu_for_acpi_id(u32 uid) +{ + int cpu; + + for (cpu = 0; cpu < nr_cpu_ids; cpu++) + if (acpi_cpu_get_madt_gicc(cpu) && + uid == get_acpi_id_for_cpu(cpu)) + return cpu; + + return -EINVAL; +} + static inline void arch_fix_phys_package_id(int num, u32 slot) { } void __init acpi_init_cpus(void); int apei_claim_sea(struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/alternative.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/alternative.h @@ -35,13 +35,16 @@ static inline void apply_alternatives_module(void *start, size_t length) { } #endif -#define ALTINSTR_ENTRY(feature,cb) \ +#define ALTINSTR_ENTRY(feature) \ " .word 661b - .\n" /* label */ \ - " .if " __stringify(cb) " == 0\n" \ " .word 663f - .\n" /* new instruction */ \ - " .else\n" \ + " .hword " __stringify(feature) "\n" /* feature bit */ \ + " .byte 662b-661b\n" /* source len */ \ + " .byte 664f-663f\n" /* replacement len */ + +#define ALTINSTR_ENTRY_CB(feature, cb) \ + " .word 661b - .\n" /* label */ \ " .word " __stringify(cb) "- .\n" /* callback */ \ - " .endif\n" \ " .hword " __stringify(feature) "\n" /* feature bit */ \ " .byte 662b-661b\n" /* source len */ \ " .byte 664f-663f\n" /* replacement len */ @@ -62,33 +65,40 @@ * * Alternatives with callbacks do not generate replacement instructions. */ -#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled, cb) \ +#define __ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg_enabled) \ ".if "__stringify(cfg_enabled)" == 1\n" \ "661:\n\t" \ oldinstr "\n" \ "662:\n" \ ".pushsection .altinstructions,\"a\"\n" \ - ALTINSTR_ENTRY(feature,cb) \ + ALTINSTR_ENTRY(feature) \ ".popsection\n" \ - " .if " __stringify(cb) " == 0\n" \ - ".pushsection .altinstr_replacement, \"a\"\n" \ + ".subsection 1\n" \ "663:\n\t" \ newinstr "\n" \ "664:\n\t" \ - ".popsection\n\t" \ ".org . - (664b-663b) + (662b-661b)\n\t" \ - ".org . - (662b-661b) + (664b-663b)\n" \ - ".else\n\t" \ + ".org . - (662b-661b) + (664b-663b)\n\t" \ + ".previous\n" \ + ".endif\n" + +#define __ALTERNATIVE_CFG_CB(oldinstr, feature, cfg_enabled, cb) \ + ".if "__stringify(cfg_enabled)" == 1\n" \ + "661:\n\t" \ + oldinstr "\n" \ + "662:\n" \ + ".pushsection .altinstructions,\"a\"\n" \ + ALTINSTR_ENTRY_CB(feature, cb) \ + ".popsection\n" \ "663:\n\t" \ "664:\n\t" \ - ".endif\n" \ ".endif\n" #define _ALTERNATIVE_CFG(oldinstr, newinstr, feature, cfg, ...) \ - __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg), 0) + __ALTERNATIVE_CFG(oldinstr, newinstr, feature, IS_ENABLED(cfg)) #define ALTERNATIVE_CB(oldinstr, cb) \ - __ALTERNATIVE_CFG(oldinstr, "NOT_AN_INSTRUCTION", ARM64_CB_PATCH, 1, cb) + __ALTERNATIVE_CFG_CB(oldinstr, ARM64_CB_PATCH, 1, cb) #else #include @@ -107,11 +117,11 @@ 662: .pushsection .altinstructions, "a" altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 663: \insn2 -664: .popsection - .org . - (664b-663b) + (662b-661b) +664: .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) + .previous .endif .endm @@ -150,7 +160,7 @@ .pushsection .altinstructions, "a" altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f .popsection - .pushsection .altinstr_replacement, "ax" + .subsection 1 .align 2 /* So GAS knows label 661 is suitably aligned */ 661: .endm @@ -169,9 +179,9 @@ .macro alternative_else 662: .if .Lasm_alt_mode==0 - .pushsection .altinstr_replacement, "ax" + .subsection 1 .else - .popsection + .previous .endif 663: .endm @@ -181,11 +191,11 @@ */ .macro alternative_endif 664: - .if .Lasm_alt_mode==0 - .popsection - .endif .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) + .if .Lasm_alt_mode==0 + .previous + .endif .endm /* @@ -211,7 +221,7 @@ .macro user_alt, label, oldinstr, newinstr, cond 9999: alternative_insn "\oldinstr", "\newinstr", \cond - _ASM_EXTABLE 9999b, \label + _asm_extable 9999b, \label .endm /* --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/arch_gicv3.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/arch_gicv3.h @@ -109,7 +109,7 @@ return read_sysreg_s(SYS_ICC_PMR_EL1); } -static inline void gic_write_pmr(u32 val) +static __always_inline void gic_write_pmr(u32 val) { write_sysreg_s(val, SYS_ICC_PMR_EL1); } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/arch_timer.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/arch_timer.h @@ -58,6 +58,7 @@ u64 (*read_cntvct_el0)(void); int (*set_next_event_phys)(unsigned long, struct clock_event_device *); int (*set_next_event_virt)(unsigned long, struct clock_event_device *); + bool disable_compat_vdso; }; DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *, @@ -164,25 +165,6 @@ isb(); } -/* - * Ensure that reads of the counter are treated the same as memory reads - * for the purposes of ordering by subsequent memory barriers. - * - * This insanity brought to you by speculative system register reads, - * out-of-order memory accesses, sequence locks and Thomas Gleixner. - * - * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html - */ -#define arch_counter_enforce_ordering(val) do { \ - u64 tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - static __always_inline u64 __arch_counter_get_cntpct_stable(void) { u64 cnt; @@ -223,8 +205,6 @@ return cnt; } -#undef arch_counter_enforce_ordering - static inline int arch_timer_arch_init(void) { return 0; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/asm-bug.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/asm-bug.h @@ -28,6 +28,7 @@ 14470: .long 14471f - 14470b; \ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ .short flags; \ + .align 2; \ .popsection; \ 14471: #else --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/asm-uaccess.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/asm-uaccess.h @@ -15,10 +15,10 @@ .macro __uaccess_ttbr0_disable, tmp1 mrs \tmp1, ttbr1_el1 // swapper_pg_dir bic \tmp1, \tmp1, #TTBR_ASID_MASK - sub \tmp1, \tmp1, #RESERVED_TTBR0_SIZE // reserved_ttbr0 just before swapper_pg_dir + sub \tmp1, \tmp1, #PAGE_SIZE // reserved_pg_dir just before swapper_pg_dir msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1 isb - add \tmp1, \tmp1, #RESERVED_TTBR0_SIZE + add \tmp1, \tmp1, #PAGE_SIZE msr ttbr1_el1, \tmp1 // set reserved ASID isb .endm --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/assembler.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/assembler.h @@ -111,6 +111,13 @@ .endm /* + * Clear Branch History instruction + */ + .macro clearbhb + hint #22 + .endm + +/* * Speculation barrier */ .macro sb @@ -462,6 +469,7 @@ .endm /* + * Deprecated! Use SYM_FUNC_{START,START_WEAK,END}_PI instead. * Annotate a function as position independent, i.e., safe to be called before * the kernel virtual mapping is activated. */ @@ -756,4 +764,30 @@ .Lyield_out_\@ : .endm + .macro __mitigate_spectre_bhb_loop tmp +#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY +alternative_cb spectre_bhb_patch_loop_iter + mov \tmp, #32 // Patched to correct the immediate +alternative_cb_end +.Lspectre_bhb_loop\@: + b . + 4 + subs \tmp, \tmp, #1 + b.ne .Lspectre_bhb_loop\@ + sb +#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ + .endm + + /* Save/restores x0-x3 to the stack */ + .macro __mitigate_spectre_bhb_fw +#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + stp x0, x1, [sp, #-16]! + stp x2, x3, [sp, #-16]! + mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3 +alternative_cb arm64_update_smccc_conduit + nop // Patched to SMC/HVC #0 +alternative_cb_end + ldp x2, x3, [sp], #16 + ldp x0, x1, [sp], #16 +#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ + .endm #endif /* __ASM_ASSEMBLER_H */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/atomic.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/atomic.h @@ -17,7 +17,7 @@ #include #define ATOMIC_OP(op) \ -static inline void arch_##op(int i, atomic_t *v) \ +static __always_inline void arch_##op(int i, atomic_t *v) \ { \ __lse_ll_sc_body(op, i, v); \ } @@ -32,7 +32,7 @@ #undef ATOMIC_OP #define ATOMIC_FETCH_OP(name, op) \ -static inline int arch_##op##name(int i, atomic_t *v) \ +static __always_inline int arch_##op##name(int i, atomic_t *v) \ { \ return __lse_ll_sc_body(op##name, i, v); \ } @@ -56,7 +56,7 @@ #undef ATOMIC_FETCH_OPS #define ATOMIC64_OP(op) \ -static inline void arch_##op(long i, atomic64_t *v) \ +static __always_inline void arch_##op(long i, atomic64_t *v) \ { \ __lse_ll_sc_body(op, i, v); \ } @@ -71,7 +71,7 @@ #undef ATOMIC64_OP #define ATOMIC64_FETCH_OP(name, op) \ -static inline long arch_##op##name(long i, atomic64_t *v) \ +static __always_inline long arch_##op##name(long i, atomic64_t *v) \ { \ return __lse_ll_sc_body(op##name, i, v); \ } @@ -94,7 +94,7 @@ #undef ATOMIC64_FETCH_OP #undef ATOMIC64_FETCH_OPS -static inline long arch_atomic64_dec_if_positive(atomic64_t *v) +static __always_inline long arch_atomic64_dec_if_positive(atomic64_t *v) { return __lse_ll_sc_body(atomic64_dec_if_positive, v); } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/atomic_ll_sc.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/atomic_ll_sc.h @@ -12,19 +12,6 @@ #include -#if IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) && IS_ENABLED(CONFIG_AS_LSE) -#define __LL_SC_FALLBACK(asm_ops) \ -" b 3f\n" \ -" .subsection 1\n" \ -"3:\n" \ -asm_ops "\n" \ -" b 4f\n" \ -" .previous\n" \ -"4:\n" -#else -#define __LL_SC_FALLBACK(asm_ops) asm_ops -#endif - #ifndef CONFIG_CC_HAS_K_CONSTRAINT #define K #endif @@ -43,12 +30,11 @@ int result; \ \ asm volatile("// atomic_" #op "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %2\n" \ -"1: ldxr %w0, %2\n" \ -" " #asm_op " %w0, %w0, %w3\n" \ -" stxr %w1, %w0, %2\n" \ -" cbnz %w1, 1b\n") \ + " prfm pstl1strm, %2\n" \ + "1: ldxr %w0, %2\n" \ + " " #asm_op " %w0, %w0, %w3\n" \ + " stxr %w1, %w0, %2\n" \ + " cbnz %w1, 1b\n" \ : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i)); \ } @@ -61,13 +47,12 @@ int result; \ \ asm volatile("// atomic_" #op "_return" #name "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %2\n" \ -"1: ld" #acq "xr %w0, %2\n" \ -" " #asm_op " %w0, %w0, %w3\n" \ -" st" #rel "xr %w1, %w0, %2\n" \ -" cbnz %w1, 1b\n" \ -" " #mb ) \ + " prfm pstl1strm, %2\n" \ + "1: ld" #acq "xr %w0, %2\n" \ + " " #asm_op " %w0, %w0, %w3\n" \ + " st" #rel "xr %w1, %w0, %2\n" \ + " cbnz %w1, 1b\n" \ + " " #mb \ : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i) \ : cl); \ @@ -83,13 +68,12 @@ int val, result; \ \ asm volatile("// atomic_fetch_" #op #name "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %3\n" \ -"1: ld" #acq "xr %w0, %3\n" \ -" " #asm_op " %w1, %w0, %w4\n" \ -" st" #rel "xr %w2, %w1, %3\n" \ -" cbnz %w2, 1b\n" \ -" " #mb ) \ + " prfm pstl1strm, %3\n" \ + "1: ld" #acq "xr %w0, %3\n" \ + " " #asm_op " %w1, %w0, %w4\n" \ + " st" #rel "xr %w2, %w1, %3\n" \ + " cbnz %w2, 1b\n" \ + " " #mb \ : "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i) \ : cl); \ @@ -142,12 +126,11 @@ unsigned long tmp; \ \ asm volatile("// atomic64_" #op "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %2\n" \ -"1: ldxr %0, %2\n" \ -" " #asm_op " %0, %0, %3\n" \ -" stxr %w1, %0, %2\n" \ -" cbnz %w1, 1b") \ + " prfm pstl1strm, %2\n" \ + "1: ldxr %0, %2\n" \ + " " #asm_op " %0, %0, %3\n" \ + " stxr %w1, %0, %2\n" \ + " cbnz %w1, 1b" \ : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i)); \ } @@ -160,13 +143,12 @@ unsigned long tmp; \ \ asm volatile("// atomic64_" #op "_return" #name "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %2\n" \ -"1: ld" #acq "xr %0, %2\n" \ -" " #asm_op " %0, %0, %3\n" \ -" st" #rel "xr %w1, %0, %2\n" \ -" cbnz %w1, 1b\n" \ -" " #mb ) \ + " prfm pstl1strm, %2\n" \ + "1: ld" #acq "xr %0, %2\n" \ + " " #asm_op " %0, %0, %3\n" \ + " st" #rel "xr %w1, %0, %2\n" \ + " cbnz %w1, 1b\n" \ + " " #mb \ : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i) \ : cl); \ @@ -176,19 +158,18 @@ #define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\ static inline long \ -__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v) \ +__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v) \ { \ s64 result, val; \ unsigned long tmp; \ \ asm volatile("// atomic64_fetch_" #op #name "\n" \ - __LL_SC_FALLBACK( \ -" prfm pstl1strm, %3\n" \ -"1: ld" #acq "xr %0, %3\n" \ -" " #asm_op " %1, %0, %4\n" \ -" st" #rel "xr %w2, %1, %3\n" \ -" cbnz %w2, 1b\n" \ -" " #mb ) \ + " prfm pstl1strm, %3\n" \ + "1: ld" #acq "xr %0, %3\n" \ + " " #asm_op " %1, %0, %4\n" \ + " st" #rel "xr %w2, %1, %3\n" \ + " cbnz %w2, 1b\n" \ + " " #mb \ : "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter) \ : __stringify(constraint) "r" (i) \ : cl); \ @@ -240,15 +221,14 @@ unsigned long tmp; asm volatile("// atomic64_dec_if_positive\n" - __LL_SC_FALLBACK( -" prfm pstl1strm, %2\n" -"1: ldxr %0, %2\n" -" subs %0, %0, #1\n" -" b.lt 2f\n" -" stlxr %w1, %0, %2\n" -" cbnz %w1, 1b\n" -" dmb ish\n" -"2:") + " prfm pstl1strm, %2\n" + "1: ldxr %0, %2\n" + " subs %0, %0, #1\n" + " b.lt 2f\n" + " stlxr %w1, %0, %2\n" + " cbnz %w1, 1b\n" + " dmb ish\n" + "2:" : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) : : "cc", "memory"); @@ -274,7 +254,6 @@ old = (u##sz)old; \ \ asm volatile( \ - __LL_SC_FALLBACK( \ " prfm pstl1strm, %[v]\n" \ "1: ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n" \ " eor %" #w "[tmp], %" #w "[oldval], %" #w "[old]\n" \ @@ -282,7 +261,7 @@ " st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n" \ " cbnz %w[tmp], 1b\n" \ " " #mb "\n" \ - "2:") \ + "2:" \ : [tmp] "=&r" (tmp), [oldval] "=&r" (oldval), \ [v] "+Q" (*(u##sz *)ptr) \ : [old] __stringify(constraint) "r" (old), [new] "r" (new) \ @@ -326,7 +305,6 @@ unsigned long tmp, ret; \ \ asm volatile("// __cmpxchg_double" #name "\n" \ - __LL_SC_FALLBACK( \ " prfm pstl1strm, %2\n" \ "1: ldxp %0, %1, %2\n" \ " eor %0, %0, %3\n" \ @@ -336,8 +314,8 @@ " st" #rel "xp %w0, %5, %6, %2\n" \ " cbnz %w0, 1b\n" \ " " #mb "\n" \ - "2:") \ - : "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr) \ + "2:" \ + : "=&r" (tmp), "=&r" (ret), "+Q" (*(__uint128_t *)ptr) \ : "r" (old1), "r" (old2), "r" (new1), "r" (new2) \ : cl); \ \ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/atomic_lse.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/atomic_lse.h @@ -11,10 +11,11 @@ #define __ASM_ATOMIC_LSE_H #define ATOMIC_OP(op, asm_op) \ -static inline void __lse_atomic_##op(int i, atomic_t *v) \ +static inline void __lse_atomic_##op(int i, atomic_t *v) \ { \ asm volatile( \ -" " #asm_op " %w[i], %[v]\n" \ + __LSE_PREAMBLE \ + " " #asm_op " %w[i], %[v]\n" \ : [i] "+r" (i), [v] "+Q" (v->counter) \ : "r" (v)); \ } @@ -30,7 +31,8 @@ static inline int __lse_atomic_fetch_##op##name(int i, atomic_t *v) \ { \ asm volatile( \ -" " #asm_op #mb " %w[i], %w[i], %[v]" \ + __LSE_PREAMBLE \ + " " #asm_op #mb " %w[i], %w[i], %[v]" \ : [i] "+r" (i), [v] "+Q" (v->counter) \ : "r" (v) \ : cl); \ @@ -58,6 +60,7 @@ u32 tmp; \ \ asm volatile( \ + __LSE_PREAMBLE \ " ldadd" #mb " %w[i], %w[tmp], %[v]\n" \ " add %w[i], %w[i], %w[tmp]" \ : [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp) \ @@ -77,6 +80,7 @@ static inline void __lse_atomic_and(int i, atomic_t *v) { asm volatile( + __LSE_PREAMBLE " mvn %w[i], %w[i]\n" " stclr %w[i], %[v]" : [i] "+&r" (i), [v] "+Q" (v->counter) @@ -87,6 +91,7 @@ static inline int __lse_atomic_fetch_and##name(int i, atomic_t *v) \ { \ asm volatile( \ + __LSE_PREAMBLE \ " mvn %w[i], %w[i]\n" \ " ldclr" #mb " %w[i], %w[i], %[v]" \ : [i] "+&r" (i), [v] "+Q" (v->counter) \ @@ -106,6 +111,7 @@ static inline void __lse_atomic_sub(int i, atomic_t *v) { asm volatile( + __LSE_PREAMBLE " neg %w[i], %w[i]\n" " stadd %w[i], %[v]" : [i] "+&r" (i), [v] "+Q" (v->counter) @@ -118,12 +124,13 @@ u32 tmp; \ \ asm volatile( \ + __LSE_PREAMBLE \ " neg %w[i], %w[i]\n" \ " ldadd" #mb " %w[i], %w[tmp], %[v]\n" \ " add %w[i], %w[i], %w[tmp]" \ : [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp) \ : "r" (v) \ - : cl); \ + : cl); \ \ return i; \ } @@ -139,6 +146,7 @@ static inline int __lse_atomic_fetch_sub##name(int i, atomic_t *v) \ { \ asm volatile( \ + __LSE_PREAMBLE \ " neg %w[i], %w[i]\n" \ " ldadd" #mb " %w[i], %w[i], %[v]" \ : [i] "+&r" (i), [v] "+Q" (v->counter) \ @@ -159,7 +167,8 @@ static inline void __lse_atomic64_##op(s64 i, atomic64_t *v) \ { \ asm volatile( \ -" " #asm_op " %[i], %[v]\n" \ + __LSE_PREAMBLE \ + " " #asm_op " %[i], %[v]\n" \ : [i] "+r" (i), [v] "+Q" (v->counter) \ : "r" (v)); \ } @@ -175,7 +184,8 @@ static inline long __lse_atomic64_fetch_##op##name(s64 i, atomic64_t *v)\ { \ asm volatile( \ -" " #asm_op #mb " %[i], %[i], %[v]" \ + __LSE_PREAMBLE \ + " " #asm_op #mb " %[i], %[i], %[v]" \ : [i] "+r" (i), [v] "+Q" (v->counter) \ : "r" (v) \ : cl); \ @@ -203,6 +213,7 @@ unsigned long tmp; \ \ asm volatile( \ + __LSE_PREAMBLE \ " ldadd" #mb " %[i], %x[tmp], %[v]\n" \ " add %[i], %[i], %x[tmp]" \ : [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp) \ @@ -222,6 +233,7 @@ static inline void __lse_atomic64_and(s64 i, atomic64_t *v) { asm volatile( + __LSE_PREAMBLE " mvn %[i], %[i]\n" " stclr %[i], %[v]" : [i] "+&r" (i), [v] "+Q" (v->counter) @@ -232,6 +244,7 @@ static inline long __lse_atomic64_fetch_and##name(s64 i, atomic64_t *v) \ { \ asm volatile( \ + __LSE_PREAMBLE \ " mvn %[i], %[i]\n" \ " ldclr" #mb " %[i], %[i], %[v]" \ : [i] "+&r" (i), [v] "+Q" (v->counter) \ @@ -251,6 +264,7 @@ static inline void __lse_atomic64_sub(s64 i, atomic64_t *v) { asm volatile( + __LSE_PREAMBLE " neg %[i], %[i]\n" " stadd %[i], %[v]" : [i] "+&r" (i), [v] "+Q" (v->counter) @@ -258,11 +272,12 @@ } #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...) \ -static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v) \ +static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)\ { \ unsigned long tmp; \ \ asm volatile( \ + __LSE_PREAMBLE \ " neg %[i], %[i]\n" \ " ldadd" #mb " %[i], %x[tmp], %[v]\n" \ " add %[i], %[i], %x[tmp]" \ @@ -284,6 +299,7 @@ static inline long __lse_atomic64_fetch_sub##name(s64 i, atomic64_t *v) \ { \ asm volatile( \ + __LSE_PREAMBLE \ " neg %[i], %[i]\n" \ " ldadd" #mb " %[i], %[i], %[v]" \ : [i] "+&r" (i), [v] "+Q" (v->counter) \ @@ -305,6 +321,7 @@ unsigned long tmp; asm volatile( + __LSE_PREAMBLE "1: ldr %x[tmp], %[v]\n" " subs %[ret], %x[tmp], #1\n" " b.lt 2f\n" @@ -332,6 +349,7 @@ unsigned long tmp; \ \ asm volatile( \ + __LSE_PREAMBLE \ " mov %" #w "[tmp], %" #w "[old]\n" \ " cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n" \ " mov %" #w "[ret], %" #w "[tmp]" \ @@ -379,12 +397,13 @@ register unsigned long x4 asm ("x4") = (unsigned long)ptr; \ \ asm volatile( \ + __LSE_PREAMBLE \ " casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\ " eor %[old1], %[old1], %[oldval1]\n" \ " eor %[old2], %[old2], %[oldval2]\n" \ " orr %[old1], %[old1], %[old2]" \ : [old1] "+&r" (x0), [old2] "+&r" (x1), \ - [v] "+Q" (*(unsigned long *)ptr) \ + [v] "+Q" (*(__uint128_t *)ptr) \ : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \ [oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \ : cl); \ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/barrier.h @@ -57,6 +57,25 @@ return mask; } +/* + * Ensure that reads of the counter are treated the same as memory reads + * for the purposes of ordering by subsequent memory barriers. + * + * This insanity brought to you by speculative system register reads, + * out-of-order memory accesses, sequence locks and Thomas Gleixner. + * + * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html + */ +#define arch_counter_enforce_ordering(val) do { \ + u64 tmp, _val = (val); \ + \ + asm volatile( \ + " eor %0, %1, %1\n" \ + " add %0, sp, %0\n" \ + " ldr xzr, [%0]" \ + : "=r" (tmp) : "r" (_val)); \ +} while (0) + #define __smp_mb() dmb(ish) #define __smp_rmb() dmb(ishld) #define __smp_wmb() dmb(ishst) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/brk-imm.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/brk-imm.h @@ -10,6 +10,7 @@ * #imm16 values used for BRK instruction generation * 0x004: for installing kprobes * 0x005: for installing uprobes + * 0x006: for kprobe software single-step * Allowed values for kgdb are 0x400 - 0x7ff * 0x100: for triggering a fault on purpose (reserved) * 0x400: for dynamic BRK instruction @@ -19,6 +20,7 @@ */ #define KPROBES_BRK_IMM 0x004 #define UPROBES_BRK_IMM 0x005 +#define KPROBES_BRK_SS_IMM 0x006 #define FAULT_BRK_IMM 0x100 #define KGDB_DYN_DBG_BRK_IMM 0x400 #define KGDB_COMPILED_DBG_BRK_IMM 0x401 --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cache.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cache.h @@ -11,6 +11,7 @@ #define CTR_L1IP_MASK 3 #define CTR_DMINLINE_SHIFT 16 #define CTR_IMINLINE_SHIFT 0 +#define CTR_IMINLINE_MASK 0xf #define CTR_ERG_SHIFT 20 #define CTR_CWG_SHIFT 24 #define CTR_CWG_MASK 15 @@ -18,7 +19,7 @@ #define CTR_DIC_SHIFT 29 #define CTR_CACHE_MINLINE_MASK \ - (0xf << CTR_DMINLINE_SHIFT | 0xf << CTR_IMINLINE_SHIFT) + (0xf << CTR_DMINLINE_SHIFT | CTR_IMINLINE_MASK << CTR_IMINLINE_SHIFT) #define CTR_L1IP(ctr) (((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cacheflush.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cacheflush.h @@ -79,7 +79,7 @@ * IPI all online CPUs so that they undergo a context synchronization * event and are forced to refetch the new instructions. */ -#ifdef CONFIG_KGDB + /* * KGDB performs cache maintenance with interrupts disabled, so we * will deadlock trying to IPI the secondary CPUs. In theory, we can @@ -89,9 +89,9 @@ * the patching operation, so we don't need extra IPIs here anyway. * In which case, add a KGDB-specific bodge and return early. */ - if (kgdb_connected && irqs_disabled()) + if (in_dbg_master()) return; -#endif + kick_all_cpus_sync(); } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/checksum.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/checksum.h @@ -19,16 +19,17 @@ { __uint128_t tmp; u64 sum; + int n = ihl; /* we want it signed */ tmp = *(const __uint128_t *)iph; iph += 16; - ihl -= 4; + n -= 4; tmp += ((tmp >> 64) | (tmp << 64)); sum = tmp >> 64; do { sum += *(const u32 *)iph; iph += 4; - } while (--ihl); + } while (--n > 0); sum += ((sum >> 32) | (sum << 32)); return csum_fold((__force u32)(sum >> 32)); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/clocksource.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/clocksource.h @@ -2,8 +2,11 @@ #ifndef _ASM_CLOCKSOURCE_H #define _ASM_CLOCKSOURCE_H +#include + struct arch_clocksource_data { - bool vdso_direct; /* Usable for direct VDSO access? */ + /* Usable for direct VDSO access? */ + enum vdso_arch_clockmode clock_mode; }; #endif --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/compat.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/compat.h @@ -4,6 +4,9 @@ */ #ifndef __ASM_COMPAT_H #define __ASM_COMPAT_H + +#include + #ifdef CONFIG_COMPAT /* @@ -13,8 +16,6 @@ #include #include -#include - #define COMPAT_USER_HZ 100 #ifdef __AARCH64EB__ #define COMPAT_UTS_MACHINE "armv8b\0\0" --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cpu.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cpu.h @@ -25,6 +25,7 @@ u64 reg_id_aa64dfr1; u64 reg_id_aa64isar0; u64 reg_id_aa64isar1; + u64 reg_id_aa64isar2; u64 reg_id_aa64mmfr0; u64 reg_id_aa64mmfr1; u64 reg_id_aa64mmfr2; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cpucaps.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cpucaps.h @@ -54,7 +54,11 @@ #define ARM64_WORKAROUND_1463225 44 #define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM 45 #define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM 46 +#define ARM64_WORKAROUND_1542419 47 +#define ARM64_SPECTRE_BHB 48 +#define ARM64_WORKAROUND_1742098 49 +#define ARM64_WORKAROUND_SPECULATIVE_SSBS 50 -#define ARM64_NCAPS 47 +#define ARM64_NCAPS 51 #endif /* __ASM_CPUCAPS_H */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cpufeature.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cpufeature.h @@ -262,6 +262,8 @@ /* * CPU feature detected at boot time based on feature of one or more CPUs. * All possible conflicts for a late CPU are ignored. + * NOTE: this means that a late CPU with the feature will *not* cause the + * capability to be advertised by cpus_have_*cap()! */ #define ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE \ (ARM64_CPUCAP_SCOPE_LOCAL_CPU | \ @@ -447,6 +449,29 @@ return cpuid_feature_extract_unsigned_field_width(features, field, 4); } +/* + * Fields that identify the version of the Performance Monitors Extension do + * not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825, + * "Alternative ID scheme used for the Performance Monitors Extension version". + */ +static inline u64 __attribute_const__ +cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap) +{ + u64 val = cpuid_feature_extract_unsigned_field(features, field); + u64 mask = GENMASK_ULL(field + 3, field); + + /* Treat IMPLEMENTATION DEFINED functionality as unimplemented */ + if (val == 0xf) + val = 0; + + if (val > cap) { + features &= ~mask; + features |= (cap << field) & mask; + } + + return features; +} + static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp) { return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift); @@ -506,6 +531,34 @@ return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1)); } +static inline bool supports_csv2p3(int scope) +{ + u64 pfr0; + u8 csv2_val; + + if (scope == SCOPE_LOCAL_CPU) + pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1); + else + pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1); + + csv2_val = cpuid_feature_extract_unsigned_field(pfr0, + ID_AA64PFR0_CSV2_SHIFT); + return csv2_val == 3; +} + +static inline bool supports_clearbhb(int scope) +{ + u64 isar2; + + if (scope == SCOPE_LOCAL_CPU) + isar2 = read_sysreg_s(SYS_ID_AA64ISAR2_EL1); + else + isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); + + return cpuid_feature_extract_unsigned_field(isar2, + ID_AA64ISAR2_CLEARBHB_SHIFT); +} + static inline bool system_supports_32bit_el0(void) { return cpus_have_const_cap(ARM64_HAS_32BIT_EL0); @@ -601,7 +654,7 @@ cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF)); } -static inline bool system_uses_irq_prio_masking(void) +static __always_inline bool system_uses_irq_prio_masking(void) { return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING); @@ -637,6 +690,18 @@ void arm64_set_ssbd_mitigation(bool state); +/* Watch out, ordering is important here. */ +enum mitigation_state { + SPECTRE_UNAFFECTED, + SPECTRE_MITIGATED, + SPECTRE_VULNERABLE, +}; + +enum mitigation_state arm64_get_spectre_bhb_state(void); +bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope); +u8 spectre_bhb_loop_affected(int scope); +void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused); + extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/cputype.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/cputype.h @@ -41,7 +41,7 @@ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) #define MIDR_CPU_MODEL(imp, partnum) \ - (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ + ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ (0xf << MIDR_ARCHITECTURE_SHIFT) | \ ((partnum) << MIDR_PARTNUM_SHIFT)) @@ -59,6 +59,7 @@ #define ARM_CPU_IMP_NVIDIA 0x4E #define ARM_CPU_IMP_FUJITSU 0x46 #define ARM_CPU_IMP_HISI 0x48 +#define ARM_CPU_IMP_AMPERE 0xC0 #define ARM_CPU_PART_AEM_V8 0xD0F #define ARM_CPU_PART_FOUNDATION 0xD00 @@ -71,6 +72,24 @@ #define ARM_CPU_PART_CORTEX_A55 0xD05 #define ARM_CPU_PART_CORTEX_A76 0xD0B #define ARM_CPU_PART_NEOVERSE_N1 0xD0C +#define ARM_CPU_PART_CORTEX_A77 0xD0D +#define ARM_CPU_PART_NEOVERSE_V1 0xD40 +#define ARM_CPU_PART_CORTEX_A78 0xD41 +#define ARM_CPU_PART_CORTEX_X1 0xD44 +#define ARM_CPU_PART_CORTEX_A710 0xD47 +#define ARM_CPU_PART_CORTEX_A715 0xD4D +#define ARM_CPU_PART_CORTEX_X2 0xD48 +#define ARM_CPU_PART_NEOVERSE_N2 0xD49 +#define ARM_CPU_PART_CORTEX_A78C 0xD4B +#define ARM_CPU_PART_CORTEX_X1C 0xD4C +#define ARM_CPU_PART_CORTEX_X3 0xD4E +#define ARM_CPU_PART_NEOVERSE_V2 0xD4F +#define ARM_CPU_PART_CORTEX_A720 0xD81 +#define ARM_CPU_PART_CORTEX_X4 0xD82 +#define ARM_CPU_PART_NEOVERSE_V3 0xD84 +#define ARM_CPU_PART_CORTEX_X925 0xD85 +#define ARM_CPU_PART_CORTEX_A725 0xD87 +#define ARM_CPU_PART_NEOVERSE_N3 0xD8E #define APM_CPU_PART_POTENZA 0x000 @@ -93,6 +112,8 @@ #define HISI_CPU_PART_TSV110 0xD01 +#define AMPERE_CPU_PART_AMPERE1 0xAC3 + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) @@ -102,6 +123,24 @@ #define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) +#define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) +#define MIDR_NEOVERSE_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V1) +#define MIDR_CORTEX_A78 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78) +#define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) +#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) +#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) +#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) +#define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) +#define MIDR_CORTEX_X1C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C) +#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3) +#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2) +#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720) +#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4) +#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3) +#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925) +#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725) +#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) @@ -115,6 +154,7 @@ #define MIDR_NVIDIA_CARMEL MIDR_CPU_MODEL(ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_CARMEL) #define MIDR_FUJITSU_A64FX MIDR_CPU_MODEL(ARM_CPU_IMP_FUJITSU, FUJITSU_CPU_PART_A64FX) #define MIDR_HISI_TSV110 MIDR_CPU_MODEL(ARM_CPU_IMP_HISI, HISI_CPU_PART_TSV110) +#define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ #define MIDR_FUJITSU_ERRATUM_010001 MIDR_FUJITSU_A64FX --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/daifflags.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/daifflags.h @@ -36,7 +36,7 @@ trace_hardirqs_off(); } -static inline unsigned long local_daif_save(void) +static inline unsigned long local_daif_save_flags(void) { unsigned long flags; @@ -48,6 +48,15 @@ flags |= PSR_I_BIT; } + return flags; +} + +static inline unsigned long local_daif_save(void) +{ + unsigned long flags; + + flags = local_daif_save_flags(); + local_daif_mask(); return flags; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/debug-monitors.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/debug-monitors.h @@ -53,6 +53,7 @@ /* kprobes BRK opcodes with ESR encoding */ #define BRK64_OPCODE_KPROBES (AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5)) +#define BRK64_OPCODE_KPROBES_SS (AARCH64_BREAK_MON | (KPROBES_BRK_SS_IMM << 5)) /* uprobes BRK opcodes with ESR encoding */ #define BRK64_OPCODE_UPROBES (AARCH64_BREAK_MON | (UPROBES_BRK_IMM << 5)) @@ -109,10 +110,13 @@ void user_rewind_single_step(struct task_struct *task); void user_fastforward_single_step(struct task_struct *task); +void user_regs_reset_single_step(struct user_pt_regs *regs, + struct task_struct *task); void kernel_enable_single_step(struct pt_regs *regs); void kernel_disable_single_step(void); int kernel_active_single_step(void); +void kernel_rewind_single_step(struct pt_regs *regs); #ifdef CONFIG_HAVE_HW_BREAKPOINT int reinstall_suspended_bps(struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/elf.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/elf.h @@ -96,7 +96,28 @@ */ #define elf_check_arch(x) ((x)->e_machine == EM_AARCH64) -#define elf_read_implies_exec(ex,stk) (stk != EXSTACK_DISABLE_X) +/* + * An executable for which elf_read_implies_exec() returns TRUE will + * have the READ_IMPLIES_EXEC personality flag set automatically. + * + * The decision process for determining the results are: + * + * CPU*: | arm32 | arm64 | + * ELF: | | | + * ---------------------|------------|------------| + * missing PT_GNU_STACK | exec-all | exec-none | + * PT_GNU_STACK == RWX | exec-stack | exec-stack | + * PT_GNU_STACK == RW | exec-none | exec-none | + * + * exec-all : all PROT_READ user mappings are executable, except when + * backed by files on a noexec-filesystem. + * exec-none : only PROT_EXEC user mappings are executable. + * exec-stack: only the stack and PROT_EXEC user mappings are executable. + * + * *all arm64 CPUs support NX, so there is no "lacks NX" column. + * + */ +#define compat_elf_read_implies_exec(ex, stk) (stk == EXSTACK_DEFAULT) #define CORE_DUMP_USE_REGSET #define ELF_EXEC_PAGESIZE PAGE_SIZE --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/fixmap.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/fixmap.h @@ -63,9 +63,11 @@ #endif /* CONFIG_ACPI_APEI_GHES */ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 + FIX_ENTRY_TRAMP_TEXT3, + FIX_ENTRY_TRAMP_TEXT2, + FIX_ENTRY_TRAMP_TEXT1, FIX_ENTRY_TRAMP_DATA, - FIX_ENTRY_TRAMP_TEXT, -#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT)) +#define TRAMP_VALIAS (__fix_to_virt(FIX_ENTRY_TRAMP_TEXT1)) #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ __end_of_permanent_fixed_addresses, --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/io.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/io.h @@ -204,4 +204,8 @@ extern int devmem_is_allowed(unsigned long pfn); +extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, + unsigned long flags); +#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap + #endif /* __ASM_IO_H */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kernel-pgtable.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kernel-pgtable.h @@ -65,8 +65,8 @@ #define EARLY_KASLR (0) #endif -#define EARLY_ENTRIES(vstart, vend, shift) (((vend) >> (shift)) \ - - ((vstart) >> (shift)) + 1 + EARLY_KASLR) +#define EARLY_ENTRIES(vstart, vend, shift) \ + ((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1 + EARLY_KASLR) #define EARLY_PGDS(vstart, vend) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT)) @@ -89,12 +89,6 @@ #define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR + TEXT_OFFSET, _end)) #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) -#ifdef CONFIG_ARM64_SW_TTBR0_PAN -#define RESERVED_TTBR0_SIZE (PAGE_SIZE) -#else -#define RESERVED_TTBR0_SIZE (0) -#endif - /* Initial memory map size */ #if ARM64_SWAPPER_USES_SECTION_MAPS #define SWAPPER_BLOCK_SHIFT SECTION_SHIFT --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kprobes.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kprobes.h @@ -16,7 +16,7 @@ #include #define __ARCH_WANT_KPROBES_INSN_SLOT -#define MAX_INSN_SIZE 1 +#define MAX_INSN_SIZE 2 #define flush_insn_slot(p) do { } while (0) #define kretprobe_blacklist_size 0 --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_arm.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_arm.h @@ -72,11 +72,12 @@ * IMO: Override CPSR.I and enable signaling with VI * FMO: Override CPSR.F and enable signaling with VF * SWIO: Turn set/way invalidates into set/way clean+invalidate + * PTW: Take a stage2 fault if a stage1 walk steps in device memory */ #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \ - HCR_FMO | HCR_IMO) + HCR_FMO | HCR_IMO | HCR_PTW ) #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF) #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK) #define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H) @@ -275,6 +276,7 @@ #define CPTR_EL2_DEFAULT CPTR_EL2_RES1 /* Hyp Debug Configuration Register bits */ +#define MDCR_EL2_TTRF (1 << 19) #define MDCR_EL2_TPMS (1 << 14) #define MDCR_EL2_E2PB_MASK (UL(0x3)) #define MDCR_EL2_E2PB_SHIFT (UL(12)) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_asm.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_asm.h @@ -60,7 +60,7 @@ extern void __kvm_flush_vm_context(void); extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); extern void __kvm_tlb_flush_vmid(struct kvm *kvm); -extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu); +extern void __kvm_flush_cpu_context(struct kvm_vcpu *vcpu); extern void __kvm_timer_set_cntvoff(u32 cntvoff_low, u32 cntvoff_high); @@ -88,6 +88,34 @@ *__hyp_this_cpu_ptr(sym); \ }) +#define __KVM_EXTABLE(from, to) \ + " .pushsection __kvm_ex_table, \"a\"\n" \ + " .align 3\n" \ + " .long (" #from " - .), (" #to " - .)\n" \ + " .popsection\n" + + +#define __kvm_at(at_op, addr) \ +( { \ + int __kvm_at_err = 0; \ + u64 spsr, elr; \ + asm volatile( \ + " mrs %1, spsr_el2\n" \ + " mrs %2, elr_el2\n" \ + "1: at "at_op", %3\n" \ + " isb\n" \ + " b 9f\n" \ + "2: msr spsr_el2, %1\n" \ + " msr elr_el2, %2\n" \ + " mov %w0, %4\n" \ + "9:\n" \ + __KVM_EXTABLE(1b, 2b) \ + : "+r" (__kvm_at_err), "=&r" (spsr), "=&r" (elr) \ + : "r" (addr), "i" (-EFAULT)); \ + __kvm_at_err; \ +} ) + + #else /* __ASSEMBLY__ */ .macro hyp_adr_this_cpu reg, sym, tmp @@ -113,6 +141,21 @@ kern_hyp_va \vcpu .endm +/* + * KVM extable for unexpected exceptions. + * In the same format _asm_extable, but output to a different section so that + * it can be mapped to EL2. The KVM version is not sorted. The caller must + * ensure: + * x18 has the hypervisor value to allow any Shadow-Call-Stack instrumented + * code to write to it, and that SPSR_EL2 and ELR_EL2 are restored by the fixup. + */ +.macro _kvm_extable, from, to + .pushsection __kvm_ex_table, "a" + .align 3 + .long (\from - .), (\to - .) + .popsection +.endm + #endif #endif /* __ARM_KVM_ASM_H__ */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_emulate.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_emulate.h @@ -97,12 +97,6 @@ vcpu->arch.hcr_el2 &= ~(HCR_API | HCR_APK); } -static inline void vcpu_ptrauth_setup_lazy(struct kvm_vcpu *vcpu) -{ - if (vcpu_has_ptrauth(vcpu)) - vcpu_ptrauth_disable(vcpu); -} - static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu) { return vcpu->arch.vsesr_el2; @@ -204,6 +198,38 @@ vcpu_gp_regs(vcpu)->spsr[KVM_SPSR_EL1] = v; } +/* + * The layout of SPSR for an AArch32 state is different when observed from an + * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32 + * view given an AArch64 view. + * + * In ARM DDI 0487E.a see: + * + * - The AArch64 view (SPSR_EL2) in section C5.2.18, page C5-426 + * - The AArch32 view (SPSR_abt) in section G8.2.126, page G8-6256 + * - The AArch32 view (SPSR_und) in section G8.2.132, page G8-6280 + * + * Which show the following differences: + * + * | Bit | AA64 | AA32 | Notes | + * +-----+------+------+-----------------------------| + * | 24 | DIT | J | J is RES0 in ARMv8 | + * | 21 | SS | DIT | SS doesn't exist in AArch32 | + * + * ... and all other bits are (currently) common. + */ +static inline unsigned long host_spsr_to_spsr32(unsigned long spsr) +{ + const unsigned long overlap = BIT(24) | BIT(21); + unsigned long dit = !!(spsr & PSR_AA32_DIT_BIT); + + spsr &= ~overlap; + + spsr |= dit << 21; + + return spsr; +} + static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu) { u32 mode; @@ -263,12 +289,17 @@ return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SSE); } +static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu) +{ + return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SF); +} + static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) { return (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; } -static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) +static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu) { return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); } @@ -276,7 +307,7 @@ static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) { return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR) || - kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */ + kvm_vcpu_abt_iss1tw(vcpu); /* AF/DBM update */ } static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu) @@ -305,6 +336,11 @@ return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW; } +static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu) +{ + return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu); +} + static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) { return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC; @@ -342,6 +378,27 @@ static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu) { + if (kvm_vcpu_abt_iss1tw(vcpu)) { + /* + * Only a permission fault on a S1PTW should be + * considered as a write. Otherwise, page tables baked + * in a read-only memslot will result in an exception + * being delivered in the guest. + * + * The drawback is that we end-up faulting twice if the + * guest is using any of HW AF/DB: a translation fault + * to map the page containing the PT (read only at + * first), then a permission fault to allow the flags + * to be set. + */ + switch (kvm_vcpu_trap_get_fault_type(vcpu)) { + case ESR_ELx_FSC_PERM: + return true; + default: + return false; + } + } + if (kvm_vcpu_trap_is_iabt(vcpu)) return false; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_host.h @@ -182,6 +182,7 @@ #define c2_TTBR1 (TTBR1_EL1 * 2) /* Translation Table Base Register 1 */ #define c2_TTBR1_high (c2_TTBR1 + 1) /* TTBR1 top 32 bits */ #define c2_TTBCR (TCR_EL1 * 2) /* Translation Table Base Control R. */ +#define c2_TTBCR2 (c2_TTBCR + 1) /* Translation Table Base Control R. 2 */ #define c3_DACR (DACR32_EL2 * 2)/* Domain Access Control Register */ #define c5_DFSR (ESR_EL1 * 2) /* Data Fault Status Register */ #define c5_IFSR (IFSR32_EL2 * 2)/* Instruction Fault Status Register */ @@ -209,6 +210,7 @@ #define cp14_DBGWCR0 (DBGWCR0_EL1 * 2) #define cp14_DBGWVR0 (DBGWVR0_EL1 * 2) #define cp14_DBGDCCINT (MDCCINT_EL1 * 2) +#define cp14_DBGVCR (DBGVCR32_EL2 * 2) #define NR_COPRO_REGS (NR_SYS_REGS * 2) @@ -392,8 +394,10 @@ * CP14 and CP15 live in the same array, as they are backed by the * same system registers. */ -#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r)]) -#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r)]) +#define CPx_BIAS IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) + +#define vcpu_cp14(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) +#define vcpu_cp15(v,r) ((v)->arch.ctxt.copro[(r) ^ CPx_BIAS]) struct kvm_vm_stat { ulong remote_tlb_flush; @@ -425,7 +429,7 @@ #define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range(struct kvm *kvm, - unsigned long start, unsigned long end); + unsigned long start, unsigned long end, unsigned flags); int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); @@ -548,6 +552,7 @@ static inline void kvm_arch_vcpu_block_finish(struct kvm_vcpu *vcpu) {} void kvm_arm_init_debug(void); +void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu); void kvm_arm_setup_debug(struct kvm_vcpu *vcpu); void kvm_arm_clear_debug(struct kvm_vcpu *vcpu); void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu); @@ -677,4 +682,6 @@ #define kvm_arm_vcpu_sve_finalized(vcpu) \ ((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED) +#define kvm_arm_vcpu_loaded(vcpu) ((vcpu)->arch.sysregs_loaded_on_cpu) + #endif /* __ARM64_KVM_HOST_H__ */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_hyp.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_hyp.h @@ -71,6 +71,9 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu); void __debug_switch_to_host(struct kvm_vcpu *vcpu); +void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu); +void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu); + void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_mmio.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_mmio.h @@ -10,13 +10,11 @@ #include #include -/* - * This is annoying. The mmio code requires this, even if we don't - * need any decoding. To be fixed. - */ struct kvm_decode { unsigned long rt; bool sign_extend; + /* Witdth of the register accessed by the faulting instruction is 64-bits */ + bool sixty_four; }; void kvm_mmio_write_buf(void *buf, unsigned int len, unsigned long data); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/kvm_mmu.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/kvm_mmu.h @@ -478,7 +478,9 @@ void *vect = kern_hyp_va(kvm_ksym_ref(__kvm_hyp_vector)); int slot = -1; - if (cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR) && data->fn) { + if ((cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR) || + cpus_have_const_cap(ARM64_SPECTRE_BHB)) && + data && data->template_start) { vect = kern_hyp_va(kvm_ksym_ref(__bp_harden_hyp_vecs_start)); slot = data->hyp_vectors_slot; } @@ -507,7 +509,8 @@ * !HBP + HEL2 -> allocate one vector slot and use exec mapping * HBP + HEL2 -> use hardened vertors and use exec mapping */ - if (cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR)) { + if (cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR) || + cpus_have_const_cap(ARM64_SPECTRE_BHB)) { __kvm_bp_vect_base = kvm_ksym_ref(__bp_harden_hyp_vecs_start); __kvm_bp_vect_base = kern_hyp_va(__kvm_bp_vect_base); } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/linkage.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/linkage.h @@ -4,4 +4,20 @@ #define __ALIGN .align 2 #define __ALIGN_STR ".align 2" +/* + * Annotate a function as position independent, i.e., safe to be called before + * the kernel virtual mapping is activated. + */ +#define SYM_FUNC_START_PI(x) \ + SYM_FUNC_START_ALIAS(__pi_##x); \ + SYM_FUNC_START(x) + +#define SYM_FUNC_START_WEAK_PI(x) \ + SYM_FUNC_START_ALIAS(__pi_##x); \ + SYM_FUNC_START_WEAK(x) + +#define SYM_FUNC_END_PI(x) \ + SYM_FUNC_END(x); \ + SYM_FUNC_END_ALIAS(__pi_##x) + #endif --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/lse.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/lse.h @@ -6,6 +6,8 @@ #if defined(CONFIG_AS_LSE) && defined(CONFIG_ARM64_LSE_ATOMICS) +#define __LSE_PREAMBLE ".arch_extension lse\n" + #include #include #include @@ -14,8 +16,6 @@ #include #include -__asm__(".arch_extension lse"); - extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS]; extern struct static_key_false arm64_const_caps_ready; @@ -34,7 +34,7 @@ /* In-line patching at runtime */ #define ARM64_LSE_ATOMIC_INSN(llsc, lse) \ - ALTERNATIVE(llsc, lse, ARM64_HAS_LSE_ATOMICS) + ALTERNATIVE(llsc, __LSE_PREAMBLE lse, ARM64_HAS_LSE_ATOMICS) #else /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/memory.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/memory.h @@ -178,7 +178,6 @@ #include #include -extern s64 physvirt_offset; extern s64 memstart_addr; /* PHYS_OFFSET - the physical address of the start of memory. */ #define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; }) @@ -219,7 +218,7 @@ ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55)) #define untagged_addr(addr) ({ \ - u64 __addr = (__force u64)addr; \ + u64 __addr = (__force u64)(addr); \ __addr &= __untagged_addr(__addr); \ (__force __typeof__(addr))__addr; \ }) @@ -248,13 +247,13 @@ /* - * The linear kernel range starts at the bottom of the virtual address - * space. Testing the top bit for the start of the region is a - * sufficient check and avoids having to worry about the tag. + * Check whether an arbitrary address is within the linear map, which + * lives in the [PAGE_OFFSET, PAGE_END) interval at the bottom of the + * kernel's TTBR1 address range. */ -#define __is_lm_address(addr) (!(((u64)addr) & BIT(vabits_actual - 1))) +#define __is_lm_address(addr) (((u64)(addr) ^ PAGE_OFFSET) < (PAGE_END - PAGE_OFFSET)) -#define __lm_to_phys(addr) (((addr) + physvirt_offset)) +#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET) #define __kimg_to_phys(addr) ((addr) - kimage_voffset) #define __virt_to_phys_nodebug(x) ({ \ @@ -272,7 +271,7 @@ #define __phys_addr_symbol(x) __pa_symbol_nodebug(x) #endif /* CONFIG_DEBUG_VIRTUAL */ -#define __phys_to_virt(x) ((unsigned long)((x) - physvirt_offset)) +#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET) #define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset)) /* @@ -316,6 +315,11 @@ #define ARCH_PFN_OFFSET ((unsigned long)PHYS_PFN_OFFSET) #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL) +#define page_to_virt(x) ({ \ + __typeof__(x) __page = x; \ + void *__addr = __va(page_to_phys(__page)); \ + (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\ +}) #define virt_to_page(x) pfn_to_page(virt_to_pfn(x)) #else #define page_to_virt(x) ({ \ @@ -333,7 +337,7 @@ #endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */ #define virt_addr_valid(addr) ({ \ - __typeof__(addr) __addr = addr; \ + __typeof__(addr) __addr = __tag_reset(addr); \ __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ }) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/mmu.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/mmu.h @@ -29,7 +29,7 @@ */ #define ASID(mm) ((mm)->context.id.counter & 0xffff) -static inline bool arm64_kernel_unmapped_at_el0(void) +static __always_inline bool arm64_kernel_unmapped_at_el0(void) { return IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0) && cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0); @@ -82,6 +82,12 @@ struct bp_hardening_data { int hyp_vectors_slot; bp_hardening_cb_t fn; + + /* + * template_start is only used by the BHB mitigation to identify the + * hyp_vectors_slot sequence. + */ + const char *template_start; }; #if (defined(CONFIG_HARDEN_BRANCH_PREDICTOR) || \ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/mmu_context.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/mmu_context.h @@ -36,11 +36,11 @@ } /* - * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0. + * Set TTBR0 to reserved_pg_dir. No translations will be possible via TTBR0. */ static inline void cpu_set_reserved_ttbr0(void) { - unsigned long ttbr = phys_to_ttbr(__pa_symbol(empty_zero_page)); + unsigned long ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); write_sysreg(ttbr, ttbr0_el1); isb(); @@ -63,10 +63,7 @@ static inline bool __cpu_uses_extended_idmap(void) { - if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52)) - return false; - - return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)); + return unlikely(idmap_t0sz != TCR_T0SZ(vabits_actual)); } /* @@ -187,9 +184,9 @@ return; if (mm == &init_mm) - ttbr = __pa_symbol(empty_zero_page); + ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); else - ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48; + ttbr = phys_to_ttbr(virt_to_phys(mm->pgd)) | ASID(mm) << 48; WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr); } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/numa.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/numa.h @@ -25,6 +25,9 @@ /* Returns a pointer to the cpumask of CPUs on Node 'node'. */ static inline const struct cpumask *cpumask_of_node(int node) { + if (node == NUMA_NO_NODE) + return cpu_all_mask; + return node_to_cpumask_map[node]; } #endif --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/pgtable-hwdef.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/pgtable-hwdef.h @@ -215,6 +215,7 @@ #define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x)) #define TCR_TxSZ_WIDTH 6 #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET) +#define TCR_T1SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T1SZ_OFFSET) #define TCR_EPD0_SHIFT 7 #define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/pgtable-prot.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/pgtable-prot.h @@ -54,7 +54,7 @@ #define PAGE_HYP __pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_HYP_XN) #define PAGE_HYP_EXEC __pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY) #define PAGE_HYP_RO __pgprot(_HYP_PAGE_DEFAULT | PTE_HYP | PTE_RDONLY | PTE_HYP_XN) -#define PAGE_HYP_DEVICE __pgprot(PROT_DEVICE_nGnRE | PTE_HYP) +#define PAGE_HYP_DEVICE __pgprot(_PROT_DEFAULT | PTE_ATTRINDX(MT_DEVICE_nGnRE) | PTE_HYP | PTE_HYP_XN) #define PAGE_S2_MEMATTR(attr) \ ({ \ @@ -85,13 +85,12 @@ #define PAGE_SHARED_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) #define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN) #define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN) -#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN) #define __P000 PAGE_NONE #define __P001 PAGE_READONLY #define __P010 PAGE_READONLY #define __P011 PAGE_READONLY -#define __P100 PAGE_EXECONLY +#define __P100 PAGE_READONLY_EXEC #define __P101 PAGE_READONLY_EXEC #define __P110 PAGE_READONLY_EXEC #define __P111 PAGE_READONLY_EXEC @@ -100,7 +99,7 @@ #define __S001 PAGE_READONLY #define __S010 PAGE_SHARED #define __S011 PAGE_SHARED -#define __S100 PAGE_EXECONLY +#define __S100 PAGE_READONLY_EXEC #define __S101 PAGE_READONLY_EXEC #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/pgtable.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/pgtable.h @@ -23,6 +23,8 @@ #define VMALLOC_START (MODULES_END) #define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K) +#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) + #define FIRST_USER_ADDRESS 0UL #ifndef __ASSEMBLY__ @@ -33,8 +35,6 @@ #include #include -extern struct page *vmemmap; - extern void __pte_error(const char *file, int line, unsigned long val); extern void __pmd_error(const char *file, int line, unsigned long val); extern void __pud_error(const char *file, int line, unsigned long val); @@ -54,9 +54,15 @@ * page table entry, taking care of 52-bit addresses. */ #ifdef CONFIG_ARM64_PA_BITS_52 -#define __pte_to_phys(pte) \ - ((pte_val(pte) & PTE_ADDR_LOW) | ((pte_val(pte) & PTE_ADDR_HIGH) << 36)) -#define __phys_to_pte_val(phys) (((phys) | ((phys) >> 36)) & PTE_ADDR_MASK) +static inline phys_addr_t __pte_to_phys(pte_t pte) +{ + return (pte_val(pte) & PTE_ADDR_LOW) | + ((pte_val(pte) & PTE_ADDR_HIGH) << 36); +} +static inline pteval_t __phys_to_pte_val(phys_addr_t phys) +{ + return (phys | (phys >> 36)) & PTE_ADDR_MASK; +} #else #define __pte_to_phys(pte) (pte_val(pte) & PTE_ADDR_MASK) #define __phys_to_pte_val(phys) (phys) @@ -96,14 +102,8 @@ #define pte_dirty(pte) (pte_sw_dirty(pte) || pte_hw_dirty(pte)) #define pte_valid(pte) (!!(pte_val(pte) & PTE_VALID)) -/* - * Execute-only user mappings do not have the PTE_USER bit set. All valid - * kernel mappings have the PTE_UXN bit set. - */ #define pte_valid_not_user(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN)) -#define pte_valid_young(pte) \ - ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF)) + ((pte_val(pte) & (PTE_VALID | PTE_USER)) == PTE_VALID) #define pte_valid_user(pte) \ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) @@ -111,14 +111,17 @@ * Could the pte be present in the TLB? We must check mm_tlb_flush_pending * so that we don't erroneously return false for pages that have been * remapped as PROT_NONE but are yet to be flushed from the TLB. + * Note that we can't make any assumptions based on the state of the access + * flag, since ptep_clear_flush_young() elides a DSB when invalidating the + * TLB. */ #define pte_accessible(mm, pte) \ - (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte)) + (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte)) /* * p??_access_permitted() is true for valid user mappings (subject to the - * write permission check) other than user execute-only which do not have the - * PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set. + * write permission check). PROT_NONE mappings do not have the PTE_VALID bit + * set. */ #define pte_access_permitted(pte, write) \ (pte_valid_user(pte) && (!(write) || pte_write(pte))) @@ -139,13 +142,6 @@ return pte; } -static inline pte_t pte_wrprotect(pte_t pte) -{ - pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); - pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); - return pte; -} - static inline pte_t pte_mkwrite(pte_t pte) { pte = set_pte_bit(pte, __pgprot(PTE_WRITE)); @@ -171,6 +167,20 @@ return pte; } +static inline pte_t pte_wrprotect(pte_t pte) +{ + /* + * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY + * clear), set the PTE_DIRTY bit. + */ + if (pte_hw_dirty(pte)) + pte = pte_mkdirty(pte); + + pte = clear_pte_bit(pte, __pgprot(PTE_WRITE)); + pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); + return pte; +} + static inline pte_t pte_mkold(pte_t pte) { return clear_pte_bit(pte, __pgprot(PTE_AF)); @@ -460,7 +470,9 @@ extern pgd_t init_pg_end[]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; +extern pgd_t idmap_pg_end[]; extern pgd_t tramp_pg_dir[PTRS_PER_PGD]; +extern pgd_t reserved_pg_dir[PTRS_PER_PGD]; extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd); @@ -667,6 +679,12 @@ if (pte_hw_dirty(pte)) pte = pte_mkdirty(pte); pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); + /* + * If we end up clearing hw dirtiness for a sw-dirty PTE, set hardware + * dirtiness again. + */ + if (pte_sw_dirty(pte)) + pte = pte_mkdirty(pte); return pte; } @@ -785,12 +803,6 @@ pte = READ_ONCE(*ptep); do { old_pte = pte; - /* - * If hardware-dirty (PTE_WRITE/DBM bit set and PTE_RDONLY - * clear), set the PTE_DIRTY bit. - */ - if (pte_hw_dirty(pte)) - pte = pte_mkdirty(pte); pte = pte_wrprotect(pte); pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep), pte_val(old_pte), pte_val(pte)); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/pointer_auth.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/pointer_auth.h @@ -3,7 +3,6 @@ #define __ASM_POINTER_AUTH_H #include -#include #include #include @@ -30,6 +29,13 @@ struct ptrauth_key apga; }; +/* + * Only include random.h once ptrauth_keys_* structures are defined + * to avoid yet another circular include hell (random.h * ends up + * including asm/smp.h, which requires ptrauth_keys_kernel). + */ +#include + static inline void ptrauth_keys_init(struct ptrauth_keys *keys) { if (system_supports_address_auth()) { --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/processor.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/processor.h @@ -184,8 +184,9 @@ static inline void start_thread_common(struct pt_regs *regs, unsigned long pc) { + s32 previous_syscall = regs->syscallno; memset(regs, 0, sizeof(*regs)); - forget_syscall(regs); + regs->syscallno = previous_syscall; regs->pc = pc; if (system_uses_irq_prio_masking()) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/ptrace.h @@ -62,6 +62,7 @@ #define PSR_AA32_I_BIT 0x00000080 #define PSR_AA32_A_BIT 0x00000100 #define PSR_AA32_E_BIT 0x00000200 +#define PSR_AA32_PAN_BIT 0x00400000 #define PSR_AA32_SSBS_BIT 0x00800000 #define PSR_AA32_DIT_BIT 0x01000000 #define PSR_AA32_Q_BIT 0x08000000 @@ -298,7 +299,17 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) { - return regs->regs[0]; + unsigned long val = regs->regs[0]; + + /* + * Audit currently uses regs_return_value() instead of + * syscall_get_return_value(). Apply the same sign-extension here until + * audit is updated to use syscall_get_return_value(). + */ + if (compat_user_mode(regs)) + val = sign_extend64(val, 31); + + return val; } static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/sections.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/sections.h @@ -15,8 +15,14 @@ extern char __idmap_text_start[], __idmap_text_end[]; extern char __initdata_begin[], __initdata_end[]; extern char __inittext_begin[], __inittext_end[]; +extern char __exittext_begin[], __exittext_end[]; extern char __irqentry_text_start[], __irqentry_text_end[]; extern char __mmuoff_data_start[], __mmuoff_data_end[]; extern char __entry_tramp_text_start[], __entry_tramp_text_end[]; +static inline size_t entry_tramp_text_size(void) +{ + return __entry_tramp_text_end - __entry_tramp_text_start; +} + #endif /* __ASM_SECTIONS_H */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/smp.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/smp.h @@ -46,7 +46,12 @@ * Logical CPU mapping. */ extern u64 __cpu_logical_map[NR_CPUS]; -#define cpu_logical_map(cpu) __cpu_logical_map[cpu] +extern u64 cpu_logical_map(int cpu); + +static inline void set_cpu_logical_map(int cpu, u64 hwid) +{ + __cpu_logical_map[cpu] = hwid; +} struct seq_file; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/syscall.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/syscall.h @@ -29,25 +29,36 @@ regs->regs[0] = regs->orig_x0; } +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + unsigned long val = regs->regs[0]; + + if (is_compat_thread(task_thread_info(task))) + val = sign_extend64(val, 31); + + return val; +} static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - unsigned long error = regs->regs[0]; - return IS_ERR_VALUE(error) ? error : 0; -} + unsigned long error = syscall_get_return_value(task, regs); -static inline long syscall_get_return_value(struct task_struct *task, - struct pt_regs *regs) -{ - return regs->regs[0]; + return IS_ERR_VALUE(error) ? error : 0; } static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - regs->regs[0] = (long) error ? error : val; + if (error) + val = error; + + if (is_compat_thread(task_thread_info(task))) + val = lower_32_bits(val); + + regs->regs[0] = val; } #define SYSCALL_MAX_ARGS 6 --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/syscall_wrapper.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/syscall_wrapper.h @@ -8,7 +8,7 @@ #ifndef __ASM_SYSCALL_WRAPPER_H #define __ASM_SYSCALL_WRAPPER_H -struct pt_regs; +#include #define SC_ARM64_REGS_TO_ARGS(x, ...) \ __MAP(x,__SC_ARGS \ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/sysreg.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/sysreg.h @@ -49,7 +49,9 @@ #ifndef CONFIG_BROKEN_GAS_INST #ifdef __ASSEMBLY__ -#define __emit_inst(x) .inst (x) +// The space separator is omitted so that __emit_inst(x) can be parsed as +// either an assembler directive or an assembler macro argument. +#define __emit_inst(x) .inst(x) #else #define __emit_inst(x) ".inst " __stringify((x)) "\n\t" #endif @@ -100,8 +102,14 @@ #define SB_BARRIER_INSN __SYS_BARRIER_INSN(0, 7, 31) #define SYS_DC_ISW sys_insn(1, 0, 7, 6, 2) +#define SYS_DC_IGSW sys_insn(1, 0, 7, 6, 4) +#define SYS_DC_IGDSW sys_insn(1, 0, 7, 6, 6) #define SYS_DC_CSW sys_insn(1, 0, 7, 10, 2) +#define SYS_DC_CGSW sys_insn(1, 0, 7, 10, 4) +#define SYS_DC_CGDSW sys_insn(1, 0, 7, 10, 6) #define SYS_DC_CISW sys_insn(1, 0, 7, 14, 2) +#define SYS_DC_CIGSW sys_insn(1, 0, 7, 14, 4) +#define SYS_DC_CIGDSW sys_insn(1, 0, 7, 14, 6) #define SYS_OSDTRRX_EL1 sys_reg(2, 0, 0, 0, 2) #define SYS_MDCCINT_EL1 sys_reg(2, 0, 0, 2, 0) @@ -163,6 +171,7 @@ #define SYS_ID_AA64ISAR0_EL1 sys_reg(3, 0, 0, 6, 0) #define SYS_ID_AA64ISAR1_EL1 sys_reg(3, 0, 0, 6, 1) +#define SYS_ID_AA64ISAR2_EL1 sys_reg(3, 0, 0, 6, 2) #define SYS_ID_AA64MMFR0_EL1 sys_reg(3, 0, 0, 7, 0) #define SYS_ID_AA64MMFR1_EL1 sys_reg(3, 0, 0, 7, 1) @@ -573,6 +582,21 @@ #define ID_AA64ISAR1_GPI_NI 0x0 #define ID_AA64ISAR1_GPI_IMP_DEF 0x1 +/* id_aa64isar2 */ +#define ID_AA64ISAR2_CLEARBHB_SHIFT 28 +#define ID_AA64ISAR2_RPRES_SHIFT 4 +#define ID_AA64ISAR2_WFXT_SHIFT 0 + +#define ID_AA64ISAR2_RPRES_8BIT 0x0 +#define ID_AA64ISAR2_RPRES_12BIT 0x1 +/* + * Value 0x1 has been removed from the architecture, and is + * reserved, but has not yet been removed from the ARM ARM + * as of ARM DDI 0487G.b. + */ +#define ID_AA64ISAR2_WFXT_NI 0x0 +#define ID_AA64ISAR2_WFXT_SUPPORTED 0x2 + /* id_aa64pfr0 */ #define ID_AA64PFR0_CSV3_SHIFT 60 #define ID_AA64PFR0_CSV2_SHIFT 56 @@ -644,6 +668,7 @@ #endif /* id_aa64mmfr1 */ +#define ID_AA64MMFR1_ECBHB_SHIFT 60 #define ID_AA64MMFR1_PAN_SHIFT 20 #define ID_AA64MMFR1_LOR_SHIFT 16 #define ID_AA64MMFR1_HPD_SHIFT 12 @@ -672,6 +697,12 @@ #define ID_AA64DFR0_TRACEVER_SHIFT 4 #define ID_AA64DFR0_DEBUGVER_SHIFT 0 +#define ID_AA64DFR0_PMUVER_8_1 0x4 + +#define ID_DFR0_PERFMON_SHIFT 24 + +#define ID_DFR0_PERFMON_8_1 0x4 + #define ID_ISAR5_RDM_SHIFT 24 #define ID_ISAR5_CRC32_SHIFT 16 #define ID_ISAR5_SHA2_SHIFT 12 --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/thread_info.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/thread_info.h @@ -91,6 +91,7 @@ #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_UPROBE (1 << TIF_UPROBE) #define _TIF_FSCHECK (1 << TIF_FSCHECK) +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_SVE (1 << TIF_SVE) --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/uaccess.h @@ -62,8 +62,13 @@ { unsigned long ret, limit = current_thread_info()->addr_limit; + /* + * Asynchronous I/O running in a kernel thread does not have the + * TIF_TAGGED_ADDR flag of the process owning the mm, so always untag + * the user address before checking. + */ if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI) && - test_thread_flag(TIF_TAGGED_ADDR)) + (current->flags & PF_KTHREAD || test_thread_flag(TIF_TAGGED_ADDR))) addr = untagged_addr(addr); __chk_user_ptr(addr); @@ -107,8 +112,8 @@ local_irq_save(flags); ttbr = read_sysreg(ttbr1_el1); ttbr &= ~TTBR_ASID_MASK; - /* reserved_ttbr0 placed before swapper_pg_dir */ - write_sysreg(ttbr - RESERVED_TTBR0_SIZE, ttbr0_el1); + /* reserved_pg_dir placed before swapper_pg_dir */ + write_sysreg(ttbr - PAGE_SIZE, ttbr0_el1); isb(); /* Set reserved ASID */ write_sysreg(ttbr, ttbr1_el1); --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/unistd.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/unistd.h @@ -25,8 +25,8 @@ #define __NR_compat_gettimeofday 78 #define __NR_compat_sigreturn 119 #define __NR_compat_rt_sigreturn 173 -#define __NR_compat_clock_getres 247 #define __NR_compat_clock_gettime 263 +#define __NR_compat_clock_getres 264 #define __NR_compat_clock_gettime64 403 #define __NR_compat_clock_getres_time64 406 @@ -42,7 +42,6 @@ #endif #define __ARCH_WANT_SYS_CLONE -#define __ARCH_WANT_SYS_CLONE3 #ifndef __COMPAT_SYSCALL_NR #include --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/uprobes.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/uprobes.h @@ -10,21 +10,19 @@ #include #include -#define MAX_UINSN_BYTES AARCH64_INSN_SIZE - -#define UPROBE_SWBP_INSN BRK64_OPCODE_UPROBES +#define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE -#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES +#define UPROBE_XOL_SLOT_BYTES AARCH64_INSN_SIZE -typedef u32 uprobe_opcode_t; +typedef __le32 uprobe_opcode_t; struct arch_uprobe_task { }; struct arch_uprobe { union { - u8 insn[MAX_UINSN_BYTES]; - u8 ixol[MAX_UINSN_BYTES]; + __le32 insn; + __le32 ixol; }; struct arch_probe_insn api; bool simulate; --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/vdso/clocksource.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/vdso/clocksource.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_VDSOCLOCKSOURCE_H +#define __ASM_VDSOCLOCKSOURCE_H + +enum vdso_arch_clockmode { + /* vdso clocksource not usable */ + VDSO_CLOCKMODE_NONE, + /* vdso clocksource for both 32 and 64bit tasks */ + VDSO_CLOCKMODE_ARCHTIMER, + /* vdso clocksource for 64bit tasks only */ + VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT, +}; + +#endif --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/vdso/compat_gettimeofday.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/vdso/compat_gettimeofday.h @@ -10,6 +10,7 @@ #include #include +#include #include #define __VDSO_USE_SYSCALL ULLONG_MAX @@ -117,10 +118,10 @@ u64 res; /* - * clock_mode == 0 implies that vDSO are enabled otherwise + * clock_mode == ARCHTIMER implies that vDSO are enabled otherwise * fallback on syscall. */ - if (clock_mode) + if (clock_mode != VDSO_CLOCKMODE_ARCHTIMER) return __VDSO_USE_SYSCALL; /* --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/vdso/gettimeofday.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/vdso/gettimeofday.h @@ -10,6 +10,8 @@ #include #include +#include + #define __VDSO_USE_SYSCALL ULLONG_MAX #define VDSO_HAS_CLOCK_GETRES 1 @@ -71,10 +73,10 @@ u64 res; /* - * clock_mode == 0 implies that vDSO are enabled otherwise + * clock_mode != NONE implies that vDSO are enabled otherwise * fallback on syscall. */ - if (clock_mode) + if (clock_mode == VDSO_CLOCKMODE_NONE) return __VDSO_USE_SYSCALL; /* @@ -83,11 +85,7 @@ */ isb(); asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); - /* - * This isb() is required to prevent that the seq lock is - * speculated.# - */ - isb(); + arch_counter_enforce_ordering(res); return res; } --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/vdso/vsyscall.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/vdso/vsyscall.h @@ -24,9 +24,7 @@ static __always_inline int __arm64_get_clock_mode(struct timekeeper *tk) { - u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct; - - return use_syscall; + return tk->tkr_mono.clock->archdata.clock_mode; } #define __arch_get_clock_mode __arm64_get_clock_mode --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/vectors.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/vectors.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2022 ARM Ltd. + */ +#ifndef __ASM_VECTORS_H +#define __ASM_VECTORS_H + +#include +#include + +#include + +extern char vectors[]; +extern char tramp_vectors[]; +extern char __bp_harden_el1_vectors[]; + +/* + * Note: the order of this enum corresponds to two arrays in entry.S: + * tramp_vecs and __bp_harden_el1_vectors. By default the canonical + * 'full fat' vectors are used directly. + */ +enum arm64_bp_harden_el1_vectors { +#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + /* + * Perform the BHB loop mitigation, before branching to the canonical + * vectors. + */ + EL1_VECTOR_BHB_LOOP, + + /* + * Make the SMC call for firmware mitigation, before branching to the + * canonical vectors. + */ + EL1_VECTOR_BHB_FW, + + /* + * Use the ClearBHB instruction, before branching to the canonical + * vectors. + */ + EL1_VECTOR_BHB_CLEAR_INSN, +#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ + + /* + * Remap the kernel before branching to the canonical vectors. + */ + EL1_VECTOR_KPTI, +}; + +#ifndef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY +#define EL1_VECTOR_BHB_LOOP -1 +#define EL1_VECTOR_BHB_FW -1 +#define EL1_VECTOR_BHB_CLEAR_INSN -1 +#endif /* !CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ + +/* The vectors to use on return from EL0. e.g. to remap the kernel */ +DECLARE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector); + +#ifndef CONFIG_UNMAP_KERNEL_AT_EL0 +#define TRAMP_VALIAS 0ul +#endif + +static inline const char * +arm64_get_bp_hardening_vector(enum arm64_bp_harden_el1_vectors slot) +{ + if (arm64_kernel_unmapped_at_el0()) + return (char *)(TRAMP_VALIAS + SZ_2K * slot); + + WARN_ON_ONCE(slot == EL1_VECTOR_KPTI); + + return __bp_harden_el1_vectors + SZ_2K * slot; +} + +#endif /* __ASM_VECTORS_H */ --- linux-oracle-5.4.0.orig/arch/arm64/include/asm/word-at-a-time.h +++ linux-oracle-5.4.0/arch/arm64/include/asm/word-at-a-time.h @@ -53,7 +53,7 @@ */ static inline unsigned long load_unaligned_zeropad(const void *addr) { - unsigned long ret, offset; + unsigned long ret, tmp; /* Load word from unaligned pointer addr */ asm( @@ -61,9 +61,9 @@ "2:\n" " .pushsection .fixup,\"ax\"\n" " .align 2\n" - "3: and %1, %2, #0x7\n" - " bic %2, %2, #0x7\n" - " ldr %0, [%2]\n" + "3: bic %1, %2, #0x7\n" + " ldr %0, [%1]\n" + " and %1, %2, #0x7\n" " lsl %1, %1, #0x3\n" #ifndef __AARCH64EB__ " lsr %0, %0, %1\n" @@ -73,7 +73,7 @@ " b 2b\n" " .popsection\n" _ASM_EXTABLE(1b, 3b) - : "=&r" (ret), "=&r" (offset) + : "=&r" (ret), "=&r" (tmp) : "r" (addr), "Q" (*(unsigned long *)addr)); return ret; --- linux-oracle-5.4.0.orig/arch/arm64/include/uapi/asm/kvm.h +++ linux-oracle-5.4.0/arch/arm64/include/uapi/asm/kvm.h @@ -240,6 +240,11 @@ #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED 3 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED (1U << 4) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3 KVM_REG_ARM_FW_REG(3) +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL 0 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL 1 +#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED 2 + /* SVE registers */ #define KVM_REG_ARM64_SVE (0x15 << KVM_REG_ARM_COPROC_SHIFT) --- linux-oracle-5.4.0.orig/arch/arm64/include/uapi/asm/ptrace.h +++ linux-oracle-5.4.0/arch/arm64/include/uapi/asm/ptrace.h @@ -49,6 +49,7 @@ #define PSR_SSBS_BIT 0x00001000 #define PSR_PAN_BIT 0x00400000 #define PSR_UAO_BIT 0x00800000 +#define PSR_DIT_BIT 0x01000000 #define PSR_V_BIT 0x10000000 #define PSR_C_BIT 0x20000000 #define PSR_Z_BIT 0x40000000 --- linux-oracle-5.4.0.orig/arch/arm64/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/arm64/include/uapi/asm/unistd.h @@ -19,5 +19,6 @@ #define __ARCH_WANT_NEW_STAT #define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_SYS_CLONE3 #include --- linux-oracle-5.4.0.orig/arch/arm64/kernel/acpi.c +++ linux-oracle-5.4.0/arch/arm64/kernel/acpi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -269,12 +270,19 @@ int apei_claim_sea(struct pt_regs *regs) { int err = -ENOENT; + bool return_to_irqs_enabled; unsigned long current_flags; if (!IS_ENABLED(CONFIG_ACPI_APEI_GHES)) return err; - current_flags = arch_local_save_flags(); + current_flags = local_daif_save_flags(); + + /* current_flags isn't useful here as daif doesn't tell us about pNMI */ + return_to_irqs_enabled = !irqs_disabled_flags(arch_local_save_flags()); + + if (regs) + return_to_irqs_enabled = interrupts_enabled(regs); /* * SEA can interrupt SError, mask it and describe this as an NMI so @@ -284,6 +292,23 @@ nmi_enter(); err = ghes_notify_sea(); nmi_exit(); + + /* + * APEI NMI-like notifications are deferred to irq_work. Unless + * we interrupted irqs-masked code, we can do that now. + */ + if (!err) { + if (return_to_irqs_enabled) { + local_daif_restore(DAIF_PROCCTX_NOIRQ); + __irq_enter(); + irq_work_run(); + __irq_exit(); + } else { + pr_warn_ratelimited("APEI work queued but not completed"); + err = -EINPROGRESS; + } + } + local_daif_restore(current_flags); return err; --- linux-oracle-5.4.0.orig/arch/arm64/kernel/acpi_numa.c +++ linux-oracle-5.4.0/arch/arm64/kernel/acpi_numa.c @@ -27,24 +27,13 @@ #include -static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE }; +static int acpi_early_node_map[NR_CPUS] __initdata = { [0 ... NR_CPUS - 1] = NUMA_NO_NODE }; int __init acpi_numa_get_nid(unsigned int cpu) { return acpi_early_node_map[cpu]; } -static inline int get_cpu_for_acpi_id(u32 uid) -{ - int cpu; - - for (cpu = 0; cpu < nr_cpu_ids; cpu++) - if (uid == get_acpi_id_for_cpu(cpu)) - return cpu; - - return -EINVAL; -} - static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header, const unsigned long end) { --- linux-oracle-5.4.0.orig/arch/arm64/kernel/alternative.c +++ linux-oracle-5.4.0/arch/arm64/kernel/alternative.c @@ -41,27 +41,15 @@ /* * Check if the target PC is within an alternative block. */ -static bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc) +static __always_inline bool branch_insn_requires_update(struct alt_instr *alt, unsigned long pc) { - unsigned long replptr; - - if (kernel_text_address(pc)) - return true; - - replptr = (unsigned long)ALT_REPL_PTR(alt); - if (pc >= replptr && pc <= (replptr + alt->alt_len)) - return false; - - /* - * Branching into *another* alternate sequence is doomed, and - * we're not even trying to fix it up. - */ - BUG(); + unsigned long replptr = (unsigned long)ALT_REPL_PTR(alt); + return !(pc >= replptr && pc <= (replptr + alt->alt_len)); } #define align_down(x, a) ((unsigned long)(x) & ~(((unsigned long)(a)) - 1)) -static u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr) +static __always_inline u32 get_alt_insn(struct alt_instr *alt, __le32 *insnptr, __le32 *altinsnptr) { u32 insn; @@ -106,7 +94,7 @@ return insn; } -static void patch_alternative(struct alt_instr *alt, +static noinstr void patch_alternative(struct alt_instr *alt, __le32 *origptr, __le32 *updptr, int nr_inst) { __le32 *replptr; --- linux-oracle-5.4.0.orig/arch/arm64/kernel/armv8_deprecated.c +++ linux-oracle-5.4.0/arch/arm64/kernel/armv8_deprecated.c @@ -59,6 +59,7 @@ static LIST_HEAD(insn_emulation); static int nr_insn_emulated __initdata; static DEFINE_RAW_SPINLOCK(insn_emulation_lock); +static DEFINE_MUTEX(insn_emulation_mutex); static void register_emulation_hooks(struct insn_emulation_ops *ops) { @@ -207,10 +208,12 @@ loff_t *ppos) { int ret = 0; - struct insn_emulation *insn = (struct insn_emulation *) table->data; - enum insn_emulation_mode prev_mode = insn->current_mode; + struct insn_emulation *insn; + enum insn_emulation_mode prev_mode; - table->data = &insn->current_mode; + mutex_lock(&insn_emulation_mutex); + insn = container_of(table->data, struct insn_emulation, current_mode); + prev_mode = insn->current_mode; ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write || prev_mode == insn->current_mode) @@ -223,7 +226,7 @@ update_insn_emulation_mode(insn, INSN_UNDEF); } ret: - table->data = insn; + mutex_unlock(&insn_emulation_mutex); return ret; } @@ -247,7 +250,7 @@ sysctl->maxlen = sizeof(int); sysctl->procname = insn->ops->name; - sysctl->data = insn; + sysctl->data = &insn->current_mode; sysctl->extra1 = &insn->min; sysctl->extra2 = &insn->max; sysctl->proc_handler = emulation_proc_handler; @@ -601,7 +604,7 @@ }, { /* Thumb mode */ - .instr_mask = 0x0000fff7, + .instr_mask = 0xfffffff7, .instr_val = 0x0000b650, .pstate_mask = (PSR_AA32_T_BIT | PSR_AA32_MODE_MASK), .pstate_val = (PSR_AA32_T_BIT | PSR_AA32_MODE_USR), --- linux-oracle-5.4.0.orig/arch/arm64/kernel/cacheinfo.c +++ linux-oracle-5.4.0/arch/arm64/kernel/cacheinfo.c @@ -43,9 +43,10 @@ this_leaf->type = type; } -static int __init_cache_level(unsigned int cpu) +int init_cache_level(unsigned int cpu) { - unsigned int ctype, level, leaves, fw_level; + unsigned int ctype, level, leaves; + int fw_level; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { @@ -63,6 +64,9 @@ else fw_level = acpi_find_last_cache_level(cpu); + if (fw_level < 0) + return fw_level; + if (level < fw_level) { /* * some external caches not specified in CLIDR_EL1 @@ -78,25 +82,24 @@ return 0; } -static int __populate_cache_leaves(unsigned int cpu) +int populate_cache_leaves(unsigned int cpu) { unsigned int level, idx; enum cache_type type; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - struct cacheinfo *this_leaf = this_cpu_ci->info_list; + struct cacheinfo *infos = this_cpu_ci->info_list; for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && - idx < this_cpu_ci->num_leaves; idx++, level++) { + idx < this_cpu_ci->num_leaves; level++) { type = get_cache_type(level); if (type == CACHE_TYPE_SEPARATE) { - ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); - ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); + if (idx + 1 >= this_cpu_ci->num_leaves) + break; + ci_leaf_init(&infos[idx++], CACHE_TYPE_DATA, level); + ci_leaf_init(&infos[idx++], CACHE_TYPE_INST, level); } else { - ci_leaf_init(this_leaf++, type, level); + ci_leaf_init(&infos[idx++], type, level); } } return 0; } - -DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) -DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/cpu_errata.c +++ linux-oracle-5.4.0/arch/arm64/kernel/cpu_errata.c @@ -13,6 +13,7 @@ #include #include #include +#include static bool __maybe_unused is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) @@ -88,13 +89,21 @@ } static void -cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *__unused) +cpu_enable_trap_ctr_access(const struct arm64_cpu_capabilities *cap) { u64 mask = arm64_ftr_reg_ctrel0.strict_mask; + bool enable_uct_trap = false; /* Trap CTR_EL0 access on this CPU, only if it has a mismatch */ if ((read_cpuid_cachetype() & mask) != (arm64_ftr_reg_ctrel0.sys_val & mask)) + enable_uct_trap = true; + + /* ... or if the system is affected by an erratum */ + if (cap->capability == ARM64_WORKAROUND_1542419) + enable_uct_trap = true; + + if (enable_uct_trap) sysreg_clear_set(sctlr_el1, SCTLR_EL1_UCT, 0); } @@ -108,6 +117,16 @@ #ifdef CONFIG_KVM_INDIRECT_VECTORS extern char __smccc_workaround_1_smc_start[]; extern char __smccc_workaround_1_smc_end[]; +extern char __smccc_workaround_3_smc_start[]; +extern char __smccc_workaround_3_smc_end[]; +extern char __spectre_bhb_loop_k8_start[]; +extern char __spectre_bhb_loop_k8_end[]; +extern char __spectre_bhb_loop_k24_start[]; +extern char __spectre_bhb_loop_k24_end[]; +extern char __spectre_bhb_loop_k32_start[]; +extern char __spectre_bhb_loop_k32_end[]; +extern char __spectre_bhb_clearbhb_start[]; +extern char __spectre_bhb_clearbhb_end[]; static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start, const char *hyp_vecs_end) @@ -121,11 +140,11 @@ __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K); } +static DEFINE_RAW_SPINLOCK(bp_lock); static void install_bp_hardening_cb(bp_hardening_cb_t fn, const char *hyp_vecs_start, const char *hyp_vecs_end) { - static DEFINE_RAW_SPINLOCK(bp_lock); int cpu, slot = -1; /* @@ -151,8 +170,12 @@ __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end); } - __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); - __this_cpu_write(bp_hardening_data.fn, fn); + if (fn != __this_cpu_read(bp_hardening_data.fn)) { + __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); + __this_cpu_write(bp_hardening_data.fn, fn); + __this_cpu_write(bp_hardening_data.template_start, + hyp_vecs_start); + } raw_spin_unlock(&bp_lock); } #else @@ -349,6 +372,19 @@ asm volatile(SET_PSTATE_SSBS(0)); else asm volatile(SET_PSTATE_SSBS(1)); + + /* + * SSBS is self-synchronizing and is intended to affect + * subsequent speculative instructions, but some CPUs can + * speculate with a stale value of SSBS. + * + * Mitigate this with an unconditional speculation barrier, as + * CPUs could mis-speculate branches and bypass a conditional + * barrier. + */ + if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386)) + spec_bar(); + return; } @@ -484,6 +520,12 @@ return required; } +static void cpu_enable_ssbd_mitigation(const struct arm64_cpu_capabilities *cap) +{ + if (ssbd_state != ARM64_SSBD_FORCE_DISABLE) + cap->matches(cap, SCOPE_LOCAL_CPU); +} + /* known invulnerable cores */ static const struct midr_range arm64_ssb_cpus[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), @@ -575,6 +617,7 @@ MIDR_ALL_VERSIONS(MIDR_CORTEX_A53), MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), MIDR_ALL_VERSIONS(MIDR_BRAHMA_B53), + MIDR_ALL_VERSIONS(MIDR_HISI_TSV110), { /* sentinel */ } }; @@ -626,6 +669,12 @@ return (need_wa > 0); } +static void +cpu_enable_branch_predictor_hardening(const struct arm64_cpu_capabilities *cap) +{ + cap->matches(cap, SCOPE_LOCAL_CPU); +} + static const __maybe_unused struct midr_range tx2_family_cpus[] = { MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), @@ -650,6 +699,18 @@ return false; } +static bool __maybe_unused +has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry, + int scope) +{ + u32 midr = read_cpuid_id(); + bool has_dic = read_cpuid_cachetype() & BIT(CTR_DIC_SHIFT); + const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1); + + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + return is_midr_in_range(midr, &range) && has_dic; +} + #ifdef CONFIG_HARDEN_EL2_VECTORS static const struct midr_range arm64_harden_el2_vectors[] = { @@ -772,6 +833,40 @@ }; #endif +#ifdef CONFIG_ARM64_ERRATUM_1742098 +static struct midr_range broken_aarch32_aes[] = { + MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + {}, +}; +#endif + +#ifdef CONFIG_ARM64_ERRATUM_3194386 +static const struct midr_range erratum_spec_ssbs_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A725), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X4), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X925), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3), + {} +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -873,9 +968,11 @@ }, #endif { + .desc = "Branch predictor hardening", .capability = ARM64_HARDEN_BRANCH_PREDICTOR, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = check_branch_predictor, + .cpu_enable = cpu_enable_branch_predictor_hardening, }, #ifdef CONFIG_HARDEN_EL2_VECTORS { @@ -889,13 +986,27 @@ .capability = ARM64_SSBD, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .matches = has_ssbd_mitigation, + .cpu_enable = cpu_enable_ssbd_mitigation, .midr_range_list = arm64_ssb_cpus, }, + { + .desc = "Spectre-BHB", + .capability = ARM64_SPECTRE_BHB, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = is_spectre_bhb_affected, + .cpu_enable = spectre_bhb_enable_mitigation, + }, #ifdef CONFIG_ARM64_ERRATUM_1418040 { .desc = "ARM erratum 1418040", .capability = ARM64_WORKAROUND_1418040, ERRATA_MIDR_RANGE_LIST(erratum_1418040_list), + /* + * We need to allow affected CPUs to come in late, but + * also need the non-affected CPUs to be able to come + * in at any point in time. Wonderful. + */ + .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE, }, #endif #ifdef CONFIG_ARM64_ERRATUM_1165522 @@ -927,6 +1038,31 @@ ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), }, #endif +#ifdef CONFIG_ARM64_ERRATUM_1542419 + { + /* we depend on the firmware portion for correctness */ + .desc = "ARM erratum 1542419 (kernel portion)", + .capability = ARM64_WORKAROUND_1542419, + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + .matches = has_neoverse_n1_erratum_1542419, + .cpu_enable = cpu_enable_trap_ctr_access, + }, +#endif +#ifdef CONFIG_ARM64_ERRATUM_1742098 + { + .desc = "ARM erratum 1742098", + .capability = ARM64_WORKAROUND_1742098, + CAP_MIDR_RANGE_LIST(broken_aarch32_aes), + .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, + }, +#endif +#ifdef CONFIG_ARM64_ERRATUM_3194386 + { + .desc = "SSBS not fully self-synchronizing", + .capability = ARM64_WORKAROUND_SPECULATIVE_SSBS, + ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list), + }, +#endif { } }; @@ -937,15 +1073,41 @@ return sprintf(buf, "Mitigation: __user pointer sanitization\n"); } +static const char *get_bhb_affected_string(enum mitigation_state bhb_state) +{ + switch (bhb_state) { + case SPECTRE_UNAFFECTED: + return ""; + default: + case SPECTRE_VULNERABLE: + return ", but not BHB"; + case SPECTRE_MITIGATED: + return ", BHB"; + } +} + ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) { + enum mitigation_state bhb_state = arm64_get_spectre_bhb_state(); + const char *bhb_str = get_bhb_affected_string(bhb_state); + const char *v2_str = "Branch predictor hardening"; + switch (get_spectre_v2_workaround_state()) { case ARM64_BP_HARDEN_NOT_REQUIRED: - return sprintf(buf, "Not affected\n"); - case ARM64_BP_HARDEN_WA_NEEDED: - return sprintf(buf, "Mitigation: Branch predictor hardening\n"); - case ARM64_BP_HARDEN_UNKNOWN: + if (bhb_state == SPECTRE_UNAFFECTED) + return sprintf(buf, "Not affected\n"); + + /* + * Platforms affected by Spectre-BHB can't report + * "Not affected" for Spectre-v2. + */ + v2_str = "CSV2"; + fallthrough; + case ARM64_BP_HARDEN_WA_NEEDED: + return sprintf(buf, "Mitigation: %s%s\n", v2_str, bhb_str); + case ARM64_BP_HARDEN_UNKNOWN: + fallthrough; default: return sprintf(buf, "Vulnerable\n"); } @@ -967,3 +1129,348 @@ return sprintf(buf, "Vulnerable\n"); } + +/* + * We try to ensure that the mitigation state can never change as the result of + * onlining a late CPU. + */ +static void update_mitigation_state(enum mitigation_state *oldp, + enum mitigation_state new) +{ + enum mitigation_state state; + + do { + state = READ_ONCE(*oldp); + if (new <= state) + break; + } while (cmpxchg_relaxed(oldp, state, new) != state); +} + +/* + * Spectre BHB. + * + * A CPU is either: + * - Mitigated by a branchy loop a CPU specific number of times, and listed + * in our "loop mitigated list". + * - Mitigated in software by the firmware Spectre v2 call. + * - Has the ClearBHB instruction to perform the mitigation. + * - Has the 'Exception Clears Branch History Buffer' (ECBHB) feature, so no + * software mitigation in the vectors is needed. + * - Has CSV2.3, so is unaffected. + */ +static enum mitigation_state spectre_bhb_state; + +enum mitigation_state arm64_get_spectre_bhb_state(void) +{ + return spectre_bhb_state; +} + +/* + * This must be called with SCOPE_LOCAL_CPU for each type of CPU, before any + * SCOPE_SYSTEM call will give the right answer. + */ +u8 spectre_bhb_loop_affected(int scope) +{ + u8 k = 0; + static u8 max_bhb_k; + + if (scope == SCOPE_LOCAL_CPU) { + static const struct midr_range spectre_bhb_k32_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X1), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), + MIDR_ALL_VERSIONS(MIDR_CORTEX_X2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1), + {}, + }; + static const struct midr_range spectre_bhb_k24_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A76), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A77), + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1), + {}, + }; + static const struct midr_range spectre_bhb_k11_list[] = { + MIDR_ALL_VERSIONS(MIDR_AMPERE1), + {}, + }; + static const struct midr_range spectre_bhb_k8_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A72), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A57), + {}, + }; + + if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k32_list)) + k = 32; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k24_list)) + k = 24; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k11_list)) + k = 11; + else if (is_midr_in_range_list(read_cpuid_id(), spectre_bhb_k8_list)) + k = 8; + + max_bhb_k = max(max_bhb_k, k); + } else { + k = max_bhb_k; + } + + return k; +} + +static enum mitigation_state spectre_bhb_get_cpu_fw_mitigation_state(void) +{ + int ret; + struct arm_smccc_res res; + + if (psci_ops.smccc_version == SMCCC_VERSION_1_0) + return SPECTRE_VULNERABLE; + + switch (psci_ops.conduit) { + case PSCI_CONDUIT_HVC: + arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, + ARM_SMCCC_ARCH_WORKAROUND_3, &res); + break; + + case PSCI_CONDUIT_SMC: + arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID, + ARM_SMCCC_ARCH_WORKAROUND_3, &res); + break; + + default: + return SPECTRE_VULNERABLE; + } + + ret = res.a0; + switch (ret) { + case SMCCC_RET_SUCCESS: + return SPECTRE_MITIGATED; + case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED: + return SPECTRE_UNAFFECTED; + default: + fallthrough; + case SMCCC_RET_NOT_SUPPORTED: + return SPECTRE_VULNERABLE; + } +} + +static bool is_spectre_bhb_fw_affected(int scope) +{ + static bool system_affected; + enum mitigation_state fw_state; + bool has_smccc = (psci_ops.smccc_version >= SMCCC_VERSION_1_1); + static const struct midr_range spectre_bhb_firmware_mitigated_list[] = { + MIDR_ALL_VERSIONS(MIDR_CORTEX_A73), + MIDR_ALL_VERSIONS(MIDR_CORTEX_A75), + {}, + }; + bool cpu_in_list = is_midr_in_range_list(read_cpuid_id(), + spectre_bhb_firmware_mitigated_list); + + if (scope != SCOPE_LOCAL_CPU) + return system_affected; + + fw_state = spectre_bhb_get_cpu_fw_mitigation_state(); + if (cpu_in_list || (has_smccc && fw_state == SPECTRE_MITIGATED)) { + system_affected = true; + return true; + } + + return false; +} + +static bool supports_ecbhb(int scope) +{ + u64 mmfr1; + + if (scope == SCOPE_LOCAL_CPU) + mmfr1 = read_sysreg_s(SYS_ID_AA64MMFR1_EL1); + else + mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); + + return cpuid_feature_extract_unsigned_field(mmfr1, + ID_AA64MMFR1_ECBHB_SHIFT); +} + +bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, + int scope) +{ + WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible()); + + if (supports_csv2p3(scope)) + return false; + + if (supports_clearbhb(scope)) + return true; + + if (spectre_bhb_loop_affected(scope)) + return true; + + if (is_spectre_bhb_fw_affected(scope)) + return true; + + return false; +} + +static void this_cpu_set_vectors(enum arm64_bp_harden_el1_vectors slot) +{ + const char *v = arm64_get_bp_hardening_vector(slot); + + if (slot < 0) + return; + + __this_cpu_write(this_cpu_vector, v); + + /* + * When KPTI is in use, the vectors are switched when exiting to + * user-space. + */ + if (arm64_kernel_unmapped_at_el0()) + return; + + write_sysreg(v, vbar_el1); + isb(); +} + +#ifdef CONFIG_KVM_INDIRECT_VECTORS +static const char *kvm_bhb_get_vecs_end(const char *start) +{ + if (start == __smccc_workaround_3_smc_start) + return __smccc_workaround_3_smc_end; + else if (start == __spectre_bhb_loop_k8_start) + return __spectre_bhb_loop_k8_end; + else if (start == __spectre_bhb_loop_k24_start) + return __spectre_bhb_loop_k24_end; + else if (start == __spectre_bhb_loop_k32_start) + return __spectre_bhb_loop_k32_end; + else if (start == __spectre_bhb_clearbhb_start) + return __spectre_bhb_clearbhb_end; + + return NULL; +} + +static void kvm_setup_bhb_slot(const char *hyp_vecs_start) +{ + int cpu, slot = -1; + const char *hyp_vecs_end; + + if (!IS_ENABLED(CONFIG_KVM) || !is_hyp_mode_available()) + return; + + hyp_vecs_end = kvm_bhb_get_vecs_end(hyp_vecs_start); + if (WARN_ON_ONCE(!hyp_vecs_start || !hyp_vecs_end)) + return; + + raw_spin_lock(&bp_lock); + for_each_possible_cpu(cpu) { + if (per_cpu(bp_hardening_data.template_start, cpu) == hyp_vecs_start) { + slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu); + break; + } + } + + if (slot == -1) { + slot = atomic_inc_return(&arm64_el2_vector_last_slot); + BUG_ON(slot >= BP_HARDEN_EL2_SLOTS); + __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end); + } + + if (hyp_vecs_start != __this_cpu_read(bp_hardening_data.template_start)) { + __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot); + __this_cpu_write(bp_hardening_data.template_start, + hyp_vecs_start); + } + raw_spin_unlock(&bp_lock); +} +#else +#define __smccc_workaround_3_smc_start NULL +#define __spectre_bhb_loop_k8_start NULL +#define __spectre_bhb_loop_k24_start NULL +#define __spectre_bhb_loop_k32_start NULL +#define __spectre_bhb_clearbhb_start NULL + +static void kvm_setup_bhb_slot(const char *hyp_vecs_start) { } +#endif + +void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *entry) +{ + enum mitigation_state fw_state, state = SPECTRE_VULNERABLE; + + if (!is_spectre_bhb_affected(entry, SCOPE_LOCAL_CPU)) + return; + + if (get_spectre_v2_workaround_state() == ARM64_BP_HARDEN_UNKNOWN) { + /* No point mitigating Spectre-BHB alone. */ + } else if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) { + pr_info_once("spectre-bhb mitigation disabled by compile time option\n"); + } else if (cpu_mitigations_off()) { + pr_info_once("spectre-bhb mitigation disabled by command line option\n"); + } else if (supports_ecbhb(SCOPE_LOCAL_CPU)) { + state = SPECTRE_MITIGATED; + } else if (supports_clearbhb(SCOPE_LOCAL_CPU)) { + kvm_setup_bhb_slot(__spectre_bhb_clearbhb_start); + this_cpu_set_vectors(EL1_VECTOR_BHB_CLEAR_INSN); + + state = SPECTRE_MITIGATED; + } else if (spectre_bhb_loop_affected(SCOPE_LOCAL_CPU)) { + switch (spectre_bhb_loop_affected(SCOPE_SYSTEM)) { + case 8: + /* + * A57/A72-r0 will already have selected the + * spectre-indirect vector, which is sufficient + * for BHB too. + */ + if (!__this_cpu_read(bp_hardening_data.fn)) + kvm_setup_bhb_slot(__spectre_bhb_loop_k8_start); + break; + case 24: + kvm_setup_bhb_slot(__spectre_bhb_loop_k24_start); + break; + case 32: + kvm_setup_bhb_slot(__spectre_bhb_loop_k32_start); + break; + default: + WARN_ON_ONCE(1); + } + this_cpu_set_vectors(EL1_VECTOR_BHB_LOOP); + + state = SPECTRE_MITIGATED; + } else if (is_spectre_bhb_fw_affected(SCOPE_LOCAL_CPU)) { + fw_state = spectre_bhb_get_cpu_fw_mitigation_state(); + if (fw_state == SPECTRE_MITIGATED) { + kvm_setup_bhb_slot(__smccc_workaround_3_smc_start); + this_cpu_set_vectors(EL1_VECTOR_BHB_FW); + + /* + * With WA3 in the vectors, the WA1 calls can be + * removed. + */ + __this_cpu_write(bp_hardening_data.fn, NULL); + + state = SPECTRE_MITIGATED; + } + } + + update_mitigation_state(&spectre_bhb_state, state); +} + +/* Patched to correct the immediate */ +void noinstr spectre_bhb_patch_loop_iter(struct alt_instr *alt, + __le32 *origptr, __le32 *updptr, int nr_inst) +{ + u8 rd; + u32 insn; + u16 loop_count = spectre_bhb_loop_affected(SCOPE_SYSTEM); + + BUG_ON(nr_inst != 1); /* MOV -> MOV */ + + if (!IS_ENABLED(CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY)) + return; + + insn = le32_to_cpu(*origptr); + rd = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn); + insn = aarch64_insn_gen_movewide(rd, loop_count, 0, + AARCH64_INSN_VARIANT_64BIT, + AARCH64_INSN_MOVEWIDE_ZERO); + *updptr++ = cpu_to_le32(insn); +} --- linux-oracle-5.4.0.orig/arch/arm64/kernel/cpufeature.c +++ linux-oracle-5.4.0/arch/arm64/kernel/cpufeature.c @@ -10,19 +10,23 @@ #include #include #include +#include #include #include #include #include #include + #include #include #include #include +#include #include #include #include #include +#include #include /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ @@ -32,9 +36,7 @@ #define COMPAT_ELF_HWCAP_DEFAULT \ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ - COMPAT_HWCAP_TLS|COMPAT_HWCAP_VFP|\ - COMPAT_HWCAP_VFPv3|COMPAT_HWCAP_VFPv4|\ - COMPAT_HWCAP_NEON|COMPAT_HWCAP_IDIV|\ + COMPAT_HWCAP_TLS|COMPAT_HWCAP_IDIV|\ COMPAT_HWCAP_LPAE) unsigned int compat_elf_hwcap __read_mostly = COMPAT_ELF_HWCAP_DEFAULT; unsigned int compat_elf_hwcap2 __read_mostly; @@ -47,6 +49,8 @@ /* Need also bit for ARM64_CB_PATCH */ DECLARE_BITMAP(boot_capabilities, ARM64_NPATCHABLE); +DEFINE_PER_CPU_READ_MOSTLY(const char *, this_cpu_vector) = vectors; + /* * Flag to indicate if we have computed the system wide * capabilities based on the boot time active CPUs. This @@ -152,6 +156,11 @@ ARM64_FTR_END, }; +static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_CLEARBHB_SHIFT, 4, 0), + ARM64_FTR_END, +}; + static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = { ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV2_SHIFT, 4, 0), @@ -162,11 +171,10 @@ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0), S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI), S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_FP_SHIFT, 4, ID_AA64PFR0_FP_NI), - /* Linux doesn't care about the EL3 */ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL3_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL2_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL1_SHIFT, 4, ID_AA64PFR0_EL1_64BIT_ONLY), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_EL0_SHIFT, 4, ID_AA64PFR0_EL0_64BIT_ONLY), ARM64_FTR_END, }; @@ -280,11 +288,34 @@ * of support. */ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_PMUVER_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_TRACEVER_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6), ARM64_FTR_END, }; +static const struct arm64_ftr_bits ftr_mvfr0[] = { + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPROUND_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSHVEC_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSQRT_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDIVIDE_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPTRAP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_SIMD_SHIFT, 4, 0), + ARM64_FTR_END, +}; + +static const struct arm64_ftr_bits ftr_mvfr1[] = { + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDFMAC_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPHP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDHP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDSP_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDINT_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDLS_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPDNAN_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPFTZ_SHIFT, 4, 0), + ARM64_FTR_END, +}; + static const struct arm64_ftr_bits ftr_mvfr2[] = { ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), /* FPMisc */ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* SIMDMisc */ @@ -300,10 +331,10 @@ static const struct arm64_ftr_bits ftr_id_isar5[] = { ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_RDM_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SEVL_SHIFT, 4, 0), ARM64_FTR_END, }; @@ -322,7 +353,7 @@ }; static const struct arm64_ftr_bits ftr_id_dfr0[] = { - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), + /* [31:28] TraceFilt */ S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0xf), /* PerfMon */ ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0), @@ -343,7 +374,7 @@ * Common ftr bits for a 32bit register with all hidden, strict * attributes, with 4bit feature fields and a default safe value of * 0. Covers the following 32bit registers: - * id_isar[0-4], id_mmfr[1-3], id_pfr1, mvfr[0-1] + * id_isar[1-3], id_mmfr[1-3] */ static const struct arm64_ftr_bits ftr_generic_32bits[] = { ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), @@ -398,8 +429,8 @@ ARM64_FTR_REG(SYS_ID_MMFR4_EL1, ftr_id_mmfr4), /* Op1 = 0, CRn = 0, CRm = 3 */ - ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_generic_32bits), - ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_generic_32bits), + ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_mvfr0), + ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_mvfr1), ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2), /* Op1 = 0, CRn = 0, CRm = 4 */ @@ -414,6 +445,7 @@ /* Op1 = 0, CRn = 0, CRm = 6 */ ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0), ARM64_FTR_REG(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1), + ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2), /* Op1 = 0, CRn = 0, CRm = 7 */ ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0), @@ -585,6 +617,7 @@ init_cpu_ftr_reg(SYS_ID_AA64DFR1_EL1, info->reg_id_aa64dfr1); init_cpu_ftr_reg(SYS_ID_AA64ISAR0_EL1, info->reg_id_aa64isar0); init_cpu_ftr_reg(SYS_ID_AA64ISAR1_EL1, info->reg_id_aa64isar1); + init_cpu_ftr_reg(SYS_ID_AA64ISAR2_EL1, info->reg_id_aa64isar2); init_cpu_ftr_reg(SYS_ID_AA64MMFR0_EL1, info->reg_id_aa64mmfr0); init_cpu_ftr_reg(SYS_ID_AA64MMFR1_EL1, info->reg_id_aa64mmfr1); init_cpu_ftr_reg(SYS_ID_AA64MMFR2_EL1, info->reg_id_aa64mmfr2); @@ -708,6 +741,8 @@ info->reg_id_aa64isar0, boot->reg_id_aa64isar0); taint |= check_update_ftr_reg(SYS_ID_AA64ISAR1_EL1, cpu, info->reg_id_aa64isar1, boot->reg_id_aa64isar1); + taint |= check_update_ftr_reg(SYS_ID_AA64ISAR2_EL1, cpu, + info->reg_id_aa64isar2, boot->reg_id_aa64isar2); /* * Differing PARange support is fine as long as all peripherals and @@ -721,9 +756,6 @@ taint |= check_update_ftr_reg(SYS_ID_AA64MMFR2_EL1, cpu, info->reg_id_aa64mmfr2, boot->reg_id_aa64mmfr2); - /* - * EL3 is not our concern. - */ taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu, info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0); taint |= check_update_ftr_reg(SYS_ID_AA64PFR1_EL1, cpu, @@ -845,6 +877,7 @@ read_sysreg_case(SYS_ID_AA64MMFR2_EL1); read_sysreg_case(SYS_ID_AA64ISAR0_EL1); read_sysreg_case(SYS_ID_AA64ISAR1_EL1); + read_sysreg_case(SYS_ID_AA64ISAR2_EL1); read_sysreg_case(SYS_CNTFRQ_EL0); read_sysreg_case(SYS_CTR_EL0); @@ -866,17 +899,39 @@ return val >= entry->min_field_value; } -static bool -has_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope) +static u64 +read_scoped_sysreg(const struct arm64_cpu_capabilities *entry, int scope) { - u64 val; - WARN_ON(scope == SCOPE_LOCAL_CPU && preemptible()); if (scope == SCOPE_SYSTEM) - val = read_sanitised_ftr_reg(entry->sys_reg); + return read_sanitised_ftr_reg(entry->sys_reg); else - val = __read_sysreg_by_encoding(entry->sys_reg); + return __read_sysreg_by_encoding(entry->sys_reg); +} + +static bool +has_user_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope) +{ + int mask; + struct arm64_ftr_reg *regp; + u64 val = read_scoped_sysreg(entry, scope); + + regp = get_arm64_ftr_reg(entry->sys_reg); + if (!regp) + return false; + + mask = cpuid_feature_extract_unsigned_field(regp->user_mask, + entry->field_pos); + if (!mask) + return false; + + return feature_matches(val, entry); +} +static bool +has_cpuid_feature(const struct arm64_cpu_capabilities *entry, int scope) +{ + u64 val = read_scoped_sysreg(entry, scope); return feature_matches(val, entry); } @@ -1045,6 +1100,12 @@ static bool kpti_applied = false; int cpu = smp_processor_id(); + if (__this_cpu_read(this_cpu_vector) == vectors) { + const char *v = arm64_get_bp_hardening_vector(EL1_VECTOR_KPTI); + + __this_cpu_write(this_cpu_vector, v); + } + /* * We don't need to rewrite the page-tables if either we've done * it already or we have KASLR enabled and therefore have not @@ -1098,7 +1159,7 @@ /* List of CPUs which have broken DBM support. */ static const struct midr_range cpus[] = { #ifdef CONFIG_ARM64_ERRATUM_1024718 - MIDR_RANGE(MIDR_CORTEX_A55, 0, 0, 1, 0), // A55 r0p0 -r1p0 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), #endif {}, }; @@ -1266,6 +1327,25 @@ } #endif +static void user_feature_fixup(void) +{ + if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) { + struct arm64_ftr_reg *regp; + + regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1); + if (regp) + regp->user_mask &= ~GENMASK(7, 4); /* SSBS */ + } +} + +static void elf_hwcap_fixup(void) +{ +#ifdef CONFIG_ARM64_ERRATUM_1742098 + if (cpus_have_const_cap(ARM64_WORKAROUND_1742098)) + compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES; +#endif /* ARM64_ERRATUM_1742098 */ +} + static const struct arm64_cpu_capabilities arm64_features[] = { { .desc = "GIC system register CPU interface", @@ -1367,7 +1447,7 @@ { /* FP/SIMD is not implemented */ .capability = ARM64_HAS_NO_FPSIMD, - .type = ARM64_CPUCAP_SYSTEM_FEATURE, + .type = ARM64_CPUCAP_BOOT_RESTRICTED_CPU_LOCAL_FEATURE, .min_field_value = 0, .matches = has_no_fpsimd, }, @@ -1570,7 +1650,7 @@ }; #define HWCAP_CPUID_MATCH(reg, field, s, min_value) \ - .matches = has_cpuid_feature, \ + .matches = has_user_cpuid_feature, \ .sys_reg = reg, \ .field_pos = field, \ .sign = s, \ @@ -1595,6 +1675,12 @@ .match_list = list, \ } +#define HWCAP_CAP_MATCH(match, cap_type, cap) \ + { \ + __HWCAP_CAP(#cap, cap_type, cap) \ + .matches = match, \ + } + #ifdef CONFIG_ARM64_PTR_AUTH static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = { { @@ -1668,8 +1754,35 @@ {}, }; +#ifdef CONFIG_COMPAT +static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) +{ + /* + * Check that all of MVFR1_EL1.{SIMDSP, SIMDInt, SIMDLS} are available, + * in line with that of arm32 as in vfp_init(). We make sure that the + * check is future proof, by making sure value is non-zero. + */ + u32 mvfr1; + + WARN_ON(scope == SCOPE_LOCAL_CPU && preemptible()); + if (scope == SCOPE_SYSTEM) + mvfr1 = read_sanitised_ftr_reg(SYS_MVFR1_EL1); + else + mvfr1 = read_sysreg_s(SYS_MVFR1_EL1); + + return cpuid_feature_extract_unsigned_field(mvfr1, MVFR1_SIMDSP_SHIFT) && + cpuid_feature_extract_unsigned_field(mvfr1, MVFR1_SIMDINT_SHIFT) && + cpuid_feature_extract_unsigned_field(mvfr1, MVFR1_SIMDLS_SHIFT); +} +#endif + static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { #ifdef CONFIG_COMPAT + HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON), + HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), + /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ + HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP), + HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3), HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL), HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES), HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1), @@ -2054,10 +2167,13 @@ setup_system_capabilities(); mark_const_caps_ready(); + user_feature_fixup(); setup_elf_hwcaps(arm64_elf_hwcaps); - if (system_supports_32bit_el0()) + if (system_supports_32bit_el0()) { setup_elf_hwcaps(compat_elf_hwcaps); + elf_hwcap_fixup(); + } if (system_uses_ttbr0_pan()) pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n"); @@ -2090,7 +2206,7 @@ /* * We emulate only the following system register space. - * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7] + * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 2 - 7] * See Table C5-6 System instruction encodings for System register accesses, * ARMv8 ARM(ARM DDI 0487A.f) for more details. */ @@ -2100,7 +2216,7 @@ sys_reg_CRn(id) == 0x0 && sys_reg_Op1(id) == 0x0 && (sys_reg_CRm(id) == 0 || - ((sys_reg_CRm(id) >= 4) && (sys_reg_CRm(id) <= 7)))); + ((sys_reg_CRm(id) >= 2) && (sys_reg_CRm(id) <= 7)))); } /* --- linux-oracle-5.4.0.orig/arch/arm64/kernel/cpuidle.c +++ linux-oracle-5.4.0/arch/arm64/kernel/cpuidle.c @@ -53,6 +53,9 @@ struct acpi_lpi_state *lpi; struct acpi_processor *pr = per_cpu(processors, cpu); + if (unlikely(!pr || !pr->flags.has_lpi)) + return -EINVAL; + /* * If the PSCI cpu_suspend function hook has not been initialized * idle states must not be enabled, so bail out @@ -60,9 +63,6 @@ if (!psci_ops.cpu_suspend) return -EOPNOTSUPP; - if (unlikely(!pr || !pr->flags.has_lpi)) - return -EINVAL; - count = pr->power.count - 1; if (count <= 0) return -ENODEV; --- linux-oracle-5.4.0.orig/arch/arm64/kernel/cpuinfo.c +++ linux-oracle-5.4.0/arch/arm64/kernel/cpuinfo.c @@ -344,6 +344,7 @@ info->reg_id_aa64dfr1 = read_cpuid(ID_AA64DFR1_EL1); info->reg_id_aa64isar0 = read_cpuid(ID_AA64ISAR0_EL1); info->reg_id_aa64isar1 = read_cpuid(ID_AA64ISAR1_EL1); + info->reg_id_aa64isar2 = read_cpuid(ID_AA64ISAR2_EL1); info->reg_id_aa64mmfr0 = read_cpuid(ID_AA64MMFR0_EL1); info->reg_id_aa64mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); info->reg_id_aa64mmfr2 = read_cpuid(ID_AA64MMFR2_EL1); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/crash_core.c +++ linux-oracle-5.4.0/arch/arm64/kernel/crash_core.c @@ -6,6 +6,14 @@ #include #include +#include + +static inline u64 get_tcr_el1_t1sz(void); + +static inline u64 get_tcr_el1_t1sz(void) +{ + return (read_sysreg(tcr_el1) & TCR_T1SZ_MASK) >> TCR_T1SZ_OFFSET; +} void arch_crash_save_vmcoreinfo(void) { @@ -15,5 +23,7 @@ kimage_voffset); vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n", PHYS_OFFSET); + vmcoreinfo_append_str("NUMBER(TCR_EL1_T1SZ)=0x%llx\n", + get_tcr_el1_t1sz()); vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/crash_dump.c +++ linux-oracle-5.4.0/arch/arm64/kernel/crash_dump.c @@ -64,5 +64,7 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) { memcpy(buf, phys_to_virt((phys_addr_t)*ppos), count); + *ppos += count; + return count; } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/debug-monitors.c +++ linux-oracle-5.4.0/arch/arm64/kernel/debug-monitors.c @@ -141,17 +141,20 @@ /* * Single step API and exception handling. */ -static void set_regs_spsr_ss(struct pt_regs *regs) +static void set_user_regs_spsr_ss(struct user_pt_regs *regs) { regs->pstate |= DBG_SPSR_SS; } -NOKPROBE_SYMBOL(set_regs_spsr_ss); +NOKPROBE_SYMBOL(set_user_regs_spsr_ss); -static void clear_regs_spsr_ss(struct pt_regs *regs) +static void clear_user_regs_spsr_ss(struct user_pt_regs *regs) { regs->pstate &= ~DBG_SPSR_SS; } -NOKPROBE_SYMBOL(clear_regs_spsr_ss); +NOKPROBE_SYMBOL(clear_user_regs_spsr_ss); + +#define set_regs_spsr_ss(r) set_user_regs_spsr_ss(&(r)->user_regs) +#define clear_regs_spsr_ss(r) clear_user_regs_spsr_ss(&(r)->user_regs) static DEFINE_SPINLOCK(debug_hook_lock); static LIST_HEAD(user_step_hook); @@ -393,17 +396,26 @@ * If single step is active for this thread, then set SPSR.SS * to 1 to avoid returning to the active-pending state. */ - if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) set_regs_spsr_ss(task_pt_regs(task)); } NOKPROBE_SYMBOL(user_rewind_single_step); void user_fastforward_single_step(struct task_struct *task) { - if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) clear_regs_spsr_ss(task_pt_regs(task)); } +void user_regs_reset_single_step(struct user_pt_regs *regs, + struct task_struct *task) +{ + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) + set_user_regs_spsr_ss(regs); + else + clear_user_regs_spsr_ss(regs); +} + /* Kernel API */ void kernel_enable_single_step(struct pt_regs *regs) { @@ -429,6 +441,11 @@ } NOKPROBE_SYMBOL(kernel_active_single_step); +void kernel_rewind_single_step(struct pt_regs *regs) +{ + set_regs_spsr_ss(regs); +} + /* ptrace API */ void user_enable_single_step(struct task_struct *task) { --- linux-oracle-5.4.0.orig/arch/arm64/kernel/efi.c +++ linux-oracle-5.4.0/arch/arm64/kernel/efi.c @@ -12,6 +12,14 @@ #include +static bool region_is_misaligned(const efi_memory_desc_t *md) +{ + if (PAGE_SIZE == EFI_PAGE_SIZE) + return false; + return !PAGE_ALIGNED(md->phys_addr) || + !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT); +} + /* * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be * executable, everything else can be mapped with the XN bits @@ -25,14 +33,22 @@ if (type == EFI_MEMORY_MAPPED_IO) return PROT_DEVICE_nGnRE; - if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), - "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) + if (region_is_misaligned(md)) { + static bool __initdata code_is_misaligned; + /* - * If the region is not aligned to the page size of the OS, we - * can not use strict permissions, since that would also affect - * the mapping attributes of the adjacent regions. + * Regions that are not aligned to the OS page size cannot be + * mapped with strict permissions, as those might interfere + * with the permissions that are needed by the adjacent + * region's mapping. However, if we haven't encountered any + * misaligned runtime code regions so far, we can safely use + * non-executable permissions for non-code regions. */ - return pgprot_val(PAGE_KERNEL_EXEC); + code_is_misaligned |= (type == EFI_RUNTIME_SERVICES_CODE); + + return code_is_misaligned ? pgprot_val(PAGE_KERNEL_EXEC) + : pgprot_val(PAGE_KERNEL); + } /* R-- */ if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == @@ -62,19 +78,16 @@ bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE || md->type == EFI_RUNTIME_SERVICES_DATA); - if (!PAGE_ALIGNED(md->phys_addr) || - !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) { - /* - * If the end address of this region is not aligned to page - * size, the mapping is rounded up, and may end up sharing a - * page frame with the next UEFI memory region. If we create - * a block entry now, we may need to split it again when mapping - * the next region, and support for that is going to be removed - * from the MMU routines. So avoid block mappings altogether in - * that case. - */ + /* + * If this region is not aligned to the page size used by the OS, the + * mapping will be rounded outwards, and may end up sharing a page + * frame with an adjacent runtime memory region. Given that the page + * table descriptor covering the shared page will be rewritten when the + * adjacent region gets mapped, we must avoid block mappings here so we + * don't have to worry about splitting them when that happens. + */ + if (region_is_misaligned(md)) page_mappings_only = true; - } create_pgd_mapping(mm, md->phys_addr, md->virt_addr, md->num_pages << EFI_PAGE_SHIFT, @@ -101,6 +114,9 @@ BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && md->type != EFI_RUNTIME_SERVICES_DATA); + if (region_is_misaligned(md)) + return 0; + /* * Calling apply_to_page_range() is only safe on regions that are * guaranteed to be mapped down to pages. Since we are only called --- linux-oracle-5.4.0.orig/arch/arm64/kernel/entry.S +++ linux-oracle-5.4.0/arch/arm64/kernel/entry.S @@ -59,18 +59,21 @@ .macro kernel_ventry, el, label, regsize = 64 .align 7 -#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -alternative_if ARM64_UNMAP_KERNEL_AT_EL0 +.Lventry_start\@: .if \el == 0 + /* + * This must be the first instruction of the EL0 vector entries. It is + * skipped by the trampoline vectors, to trigger the cleanup. + */ + b .Lskip_tramp_vectors_cleanup\@ .if \regsize == 64 mrs x30, tpidrro_el0 msr tpidrro_el0, xzr .else mov x30, xzr .endif +.Lskip_tramp_vectors_cleanup\@: .endif -alternative_else_nop_endif -#endif sub sp, sp, #S_FRAME_SIZE #ifdef CONFIG_VMAP_STACK @@ -116,11 +119,15 @@ mrs x0, tpidrro_el0 #endif b el\()\el\()_\label +.org .Lventry_start\@ + 128 // Did we overflow the ventry slot? .endm - .macro tramp_alias, dst, sym + .macro tramp_alias, dst, sym, tmp mov_q \dst, TRAMP_VALIAS - add \dst, \dst, #(\sym - .entry.tramp.text) + adr_l \tmp, \sym + add \dst, \dst, \tmp + adr_l \tmp, .entry.tramp.text + sub \dst, \dst, \tmp .endm // This macro corrupts x0-x3. It is the caller's duty @@ -361,21 +368,25 @@ ldp x24, x25, [sp, #16 * 12] ldp x26, x27, [sp, #16 * 13] ldp x28, x29, [sp, #16 * 14] - ldr lr, [sp, #S_LR] - add sp, sp, #S_FRAME_SIZE // restore sp .if \el == 0 -alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 +alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 + ldr lr, [sp, #S_LR] + add sp, sp, #S_FRAME_SIZE // restore sp + eret +alternative_else_nop_endif #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 bne 5f - msr far_el1, x30 - tramp_alias x30, tramp_exit_native + msr far_el1, x29 + tramp_alias x30, tramp_exit_native, x29 br x30 5: - tramp_alias x30, tramp_exit_compat + tramp_alias x30, tramp_exit_compat, x29 br x30 #endif .else + ldr lr, [sp, #S_LR] + add sp, sp, #S_FRAME_SIZE // restore sp eret .endif sb @@ -1012,15 +1023,10 @@ .popsection // .entry.text -#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -/* - * Exception vectors trampoline. - */ - .pushsection ".entry.tramp.text", "ax" - + // Move from tramp_pg_dir to swapper_pg_dir .macro tramp_map_kernel, tmp mrs \tmp, ttbr1_el1 - add \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE) + add \tmp, \tmp, #(2 * PAGE_SIZE) bic \tmp, \tmp, #USER_ASID_FLAG msr ttbr1_el1, \tmp #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 @@ -1037,9 +1043,10 @@ #endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */ .endm + // Move from swapper_pg_dir to tramp_pg_dir .macro tramp_unmap_kernel, tmp mrs \tmp, ttbr1_el1 - sub \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE) + sub \tmp, \tmp, #(2 * PAGE_SIZE) orr \tmp, \tmp, #USER_ASID_FLAG msr ttbr1_el1, \tmp /* @@ -1049,12 +1056,47 @@ */ .endm - .macro tramp_ventry, regsize = 64 + .macro tramp_data_page dst + adr_l \dst, .entry.tramp.text + sub \dst, \dst, PAGE_SIZE + .endm + + .macro tramp_data_read_var dst, var +#ifdef CONFIG_RANDOMIZE_BASE + tramp_data_page \dst + add \dst, \dst, #:lo12:__entry_tramp_data_\var + ldr \dst, [\dst] +#else + ldr \dst, =\var +#endif + .endm + +#define BHB_MITIGATION_NONE 0 +#define BHB_MITIGATION_LOOP 1 +#define BHB_MITIGATION_FW 2 +#define BHB_MITIGATION_INSN 3 + + .macro tramp_ventry, vector_start, regsize, kpti, bhb .align 7 1: .if \regsize == 64 msr tpidrro_el0, x30 // Restored in kernel_ventry .endif + + .if \bhb == BHB_MITIGATION_LOOP + /* + * This sequence must appear before the first indirect branch. i.e. the + * ret out of tramp_ventry. It appears here because x30 is free. + */ + __mitigate_spectre_bhb_loop x30 + .endif // \bhb == BHB_MITIGATION_LOOP + + .if \bhb == BHB_MITIGATION_INSN + clearbhb + isb + .endif // \bhb == BHB_MITIGATION_INSN + + .if \kpti == 1 /* * Defend against branch aliasing attacks by pushing a dummy * entry onto the return stack and using a RET instruction to @@ -1064,46 +1106,79 @@ b . 2: tramp_map_kernel x30 -#ifdef CONFIG_RANDOMIZE_BASE - adr x30, tramp_vectors + PAGE_SIZE alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003 - ldr x30, [x30] -#else - ldr x30, =vectors -#endif + tramp_data_read_var x30, vectors alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM - prfm plil1strm, [x30, #(1b - tramp_vectors)] + prfm plil1strm, [x30, #(1b - \vector_start)] alternative_else_nop_endif + msr vbar_el1, x30 - add x30, x30, #(1b - tramp_vectors) isb + .else + ldr x30, =vectors + .endif // \kpti == 1 + + .if \bhb == BHB_MITIGATION_FW + /* + * The firmware sequence must appear before the first indirect branch. + * i.e. the ret out of tramp_ventry. But it also needs the stack to be + * mapped to save/restore the registers the SMC clobbers. + */ + __mitigate_spectre_bhb_fw + .endif // \bhb == BHB_MITIGATION_FW + + add x30, x30, #(1b - \vector_start + 4) ret +.org 1b + 128 // Did we overflow the ventry slot? .endm .macro tramp_exit, regsize = 64 - adr x30, tramp_vectors + tramp_data_read_var x30, this_cpu_vector +alternative_if_not ARM64_HAS_VIRT_HOST_EXTN + mrs x29, tpidr_el1 +alternative_else + mrs x29, tpidr_el2 +alternative_endif + ldr x30, [x30, x29] + msr vbar_el1, x30 - tramp_unmap_kernel x30 + ldr lr, [sp, #S_LR] + tramp_unmap_kernel x29 .if \regsize == 64 - mrs x30, far_el1 + mrs x29, far_el1 .endif + add sp, sp, #S_FRAME_SIZE // restore sp eret sb .endm - .align 11 -ENTRY(tramp_vectors) + .macro generate_tramp_vector, kpti, bhb +.Lvector_start\@: .space 0x400 - tramp_ventry - tramp_ventry - tramp_ventry - tramp_ventry - - tramp_ventry 32 - tramp_ventry 32 - tramp_ventry 32 - tramp_ventry 32 + .rept 4 + tramp_ventry .Lvector_start\@, 64, \kpti, \bhb + .endr + .rept 4 + tramp_ventry .Lvector_start\@, 32, \kpti, \bhb + .endr + .endm + +#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 +/* + * Exception vectors trampoline. + * The order must match __bp_harden_el1_vectors and the + * arm64_bp_harden_el1_vectors enum. + */ + .pushsection ".entry.tramp.text", "ax" + .align 11 +ENTRY(tramp_vectors) +#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_LOOP + generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_FW + generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_INSN +#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ + generate_tramp_vector kpti=1, bhb=BHB_MITIGATION_NONE END(tramp_vectors) ENTRY(tramp_exit_native) @@ -1121,12 +1196,56 @@ .align PAGE_SHIFT .globl __entry_tramp_data_start __entry_tramp_data_start: +__entry_tramp_data_vectors: .quad vectors +#ifdef CONFIG_ARM_SDE_INTERFACE +__entry_tramp_data___sdei_asm_handler: + .quad __sdei_asm_handler +#endif /* CONFIG_ARM_SDE_INTERFACE */ +__entry_tramp_data_this_cpu_vector: + .quad this_cpu_vector .popsection // .rodata #endif /* CONFIG_RANDOMIZE_BASE */ #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ /* + * Exception vectors for spectre mitigations on entry from EL1 when + * kpti is not in use. + */ + .macro generate_el1_vector, bhb +.Lvector_start\@: + kernel_ventry 1, sync_invalid // Synchronous EL1t + kernel_ventry 1, irq_invalid // IRQ EL1t + kernel_ventry 1, fiq_invalid // FIQ EL1t + kernel_ventry 1, error_invalid // Error EL1t + + kernel_ventry 1, sync // Synchronous EL1h + kernel_ventry 1, irq // IRQ EL1h + kernel_ventry 1, fiq_invalid // FIQ EL1h + kernel_ventry 1, error // Error EL1h + + .rept 4 + tramp_ventry .Lvector_start\@, 64, 0, \bhb + .endr + .rept 4 + tramp_ventry .Lvector_start\@, 32, 0, \bhb + .endr + .endm + +/* The order must match tramp_vecs and the arm64_bp_harden_el1_vectors enum. */ + .pushsection ".entry.text", "ax" + .align 11 +SYM_CODE_START(__bp_harden_el1_vectors) +#ifdef CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + generate_el1_vector bhb=BHB_MITIGATION_LOOP + generate_el1_vector bhb=BHB_MITIGATION_FW + generate_el1_vector bhb=BHB_MITIGATION_INSN +#endif /* CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY */ +SYM_CODE_END(__bp_harden_el1_vectors) + .popsection + + +/* * Register switch for AArch64. The callee-saved registers need to be saved * and restored. On entry: * x0 = previous task_struct (must be preserved across the switch) @@ -1212,13 +1331,7 @@ */ 1: str x4, [x1, #(SDEI_EVENT_INTREGS + S_ORIG_ADDR_LIMIT)] -#ifdef CONFIG_RANDOMIZE_BASE - adr x4, tramp_vectors + PAGE_SIZE - add x4, x4, #:lo12:__sdei_asm_trampoline_next_handler - ldr x4, [x4] -#else - ldr x4, =__sdei_asm_handler -#endif + tramp_data_read_var x4, __sdei_asm_handler br x4 ENDPROC(__sdei_asm_entry_trampoline) NOKPROBE(__sdei_asm_entry_trampoline) @@ -1241,12 +1354,6 @@ NOKPROBE(__sdei_asm_exit_trampoline) .ltorg .popsection // .entry.tramp.text -#ifdef CONFIG_RANDOMIZE_BASE -.pushsection ".rodata", "a" -__sdei_asm_trampoline_next_handler: - .quad __sdei_asm_handler -.popsection // .rodata -#endif /* CONFIG_RANDOMIZE_BASE */ #endif /* CONFIG_UNMAP_KERNEL_AT_EL0 */ /* @@ -1342,7 +1449,7 @@ alternative_else_nop_endif #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 - tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline + tramp_alias dst=x5, sym=__sdei_asm_exit_trampoline, tmp=x3 br x5 #endif ENDPROC(__sdei_asm_handler) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/fpsimd.c +++ linux-oracle-5.4.0/arch/arm64/kernel/fpsimd.c @@ -269,6 +269,7 @@ */ static void task_fpsimd_load(void) { + WARN_ON(!system_supports_fpsimd()); WARN_ON(!have_cpu_fpsimd_context()); if (system_supports_sve() && test_thread_flag(TIF_SVE)) @@ -289,6 +290,7 @@ this_cpu_ptr(&fpsimd_last_state); /* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */ + WARN_ON(!system_supports_fpsimd()); WARN_ON(!have_cpu_fpsimd_context()); if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) { @@ -336,7 +338,7 @@ return sve_vl_from_vq(__bit_to_vq(bit)); } -#ifdef CONFIG_SYSCTL +#if defined(CONFIG_ARM64_SVE) && defined(CONFIG_SYSCTL) static int sve_proc_do_default_vl(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, @@ -382,9 +384,9 @@ return 0; } -#else /* ! CONFIG_SYSCTL */ +#else /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */ static int __init sve_sysctl_init(void) { return 0; } -#endif /* ! CONFIG_SYSCTL */ +#endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */ #define ZREG(sve_state, vq, n) ((char *)(sve_state) + \ (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET)) @@ -496,7 +498,7 @@ void sve_alloc(struct task_struct *task) { if (task->thread.sve_state) { - memset(task->thread.sve_state, 0, sve_state_size(current)); + memset(task->thread.sve_state, 0, sve_state_size(task)); return; } @@ -1092,6 +1094,7 @@ struct fpsimd_last_state_struct *last = this_cpu_ptr(&fpsimd_last_state); + WARN_ON(!system_supports_fpsimd()); last->st = ¤t->thread.uw.fpsimd_state; last->sve_state = current->thread.sve_state; last->sve_vl = current->thread.sve_vl; @@ -1114,6 +1117,7 @@ struct fpsimd_last_state_struct *last = this_cpu_ptr(&fpsimd_last_state); + WARN_ON(!system_supports_fpsimd()); WARN_ON(!in_softirq() && !irqs_disabled()); last->st = st; @@ -1128,8 +1132,19 @@ */ void fpsimd_restore_current_state(void) { - if (!system_supports_fpsimd()) + /* + * For the tasks that were created before we detected the absence of + * FP/SIMD, the TIF_FOREIGN_FPSTATE could be set via fpsimd_thread_switch(), + * e.g, init. This could be then inherited by the children processes. + * If we later detect that the system doesn't support FP/SIMD, + * we must clear the flag for all the tasks to indicate that the + * FPSTATE is clean (as we can't have one) to avoid looping for ever in + * do_notify_resume(). + */ + if (!system_supports_fpsimd()) { + clear_thread_flag(TIF_FOREIGN_FPSTATE); return; + } get_cpu_fpsimd_context(); @@ -1148,7 +1163,7 @@ */ void fpsimd_update_current_state(struct user_fpsimd_state const *state) { - if (!system_supports_fpsimd()) + if (WARN_ON(!system_supports_fpsimd())) return; get_cpu_fpsimd_context(); @@ -1179,7 +1194,13 @@ void fpsimd_flush_task_state(struct task_struct *t) { t->thread.fpsimd_cpu = NR_CPUS; - + /* + * If we don't support fpsimd, bail out after we have + * reset the fpsimd_cpu for this task and clear the + * FPSTATE. + */ + if (!system_supports_fpsimd()) + return; barrier(); set_tsk_thread_flag(t, TIF_FOREIGN_FPSTATE); @@ -1193,6 +1214,7 @@ */ static void fpsimd_flush_cpu_state(void) { + WARN_ON(!system_supports_fpsimd()); __this_cpu_write(fpsimd_last_state.st, NULL); set_thread_flag(TIF_FOREIGN_FPSTATE); } @@ -1203,6 +1225,8 @@ */ void fpsimd_save_and_flush_cpu_state(void) { + if (!system_supports_fpsimd()) + return; WARN_ON(preemptible()); __get_cpu_fpsimd_context(); fpsimd_save(); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/arm64/kernel/ftrace.c @@ -69,14 +69,26 @@ { unsigned long pc = rec->ip; u32 old, new; - long offset = (long)pc - (long)addr; + long offset = (long)addr - (long)pc; if (offset < -SZ_128M || offset >= SZ_128M) { #ifdef CONFIG_ARM64_MODULE_PLTS - struct plt_entry trampoline, *dst; struct module *mod; /* + * There is only one ftrace trampoline per module. For now, + * this is not a problem since on arm64, all dynamic ftrace + * invocations are routed via ftrace_caller(). This will need + * to be revisited if support for multiple ftrace entry points + * is added in the future, but for now, the pr_err() below + * deals with a theoretical issue only. + */ + if (addr != FTRACE_ADDR) { + pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); + return -EINVAL; + } + + /* * On kernels that support module PLTs, the offset between the * branch instruction and its target may legally exceed the * range of an ordinary relative 'bl' opcode. In this case, we @@ -93,46 +105,7 @@ if (WARN_ON(!mod)) return -EINVAL; - /* - * There is only one ftrace trampoline per module. For now, - * this is not a problem since on arm64, all dynamic ftrace - * invocations are routed via ftrace_caller(). This will need - * to be revisited if support for multiple ftrace entry points - * is added in the future, but for now, the pr_err() below - * deals with a theoretical issue only. - * - * Note that PLTs are place relative, and plt_entries_equal() - * checks whether they point to the same target. Here, we need - * to check if the actual opcodes are in fact identical, - * regardless of the offset in memory so use memcmp() instead. - */ - dst = mod->arch.ftrace_trampoline; - trampoline = get_plt_entry(addr, dst); - if (memcmp(dst, &trampoline, sizeof(trampoline))) { - if (plt_entry_is_initialized(dst)) { - pr_err("ftrace: far branches to multiple entry points unsupported inside a single module\n"); - return -EINVAL; - } - - /* point the trampoline to our ftrace entry point */ - module_disable_ro(mod); - *dst = trampoline; - module_enable_ro(mod, true); - - /* - * Ensure updated trampoline is visible to instruction - * fetch before we patch in the branch. Although the - * architecture doesn't require an IPI in this case, - * Neoverse-N1 erratum #1542419 does require one - * if the TLB maintenance in module_enable_ro() is - * skipped due to rodata_enabled. It doesn't seem worth - * it to make it conditional given that this is - * certainly not a fast-path. - */ - flush_icache_range((unsigned long)&dst[0], - (unsigned long)&dst[1]); - } - addr = (unsigned long)dst; + addr = (unsigned long)mod->arch.ftrace_trampoline; #else /* CONFIG_ARM64_MODULE_PLTS */ return -EINVAL; #endif /* CONFIG_ARM64_MODULE_PLTS */ @@ -153,7 +126,7 @@ unsigned long pc = rec->ip; bool validate = true; u32 old = 0, new; - long offset = (long)pc - (long)addr; + long offset = (long)addr - (long)pc; if (offset < -SZ_128M || offset >= SZ_128M) { #ifdef CONFIG_ARM64_MODULE_PLTS --- linux-oracle-5.4.0.orig/arch/arm64/kernel/head.S +++ linux-oracle-5.4.0/arch/arm64/kernel/head.S @@ -194,7 +194,7 @@ * to be composed of multiple pages. (This effectively scales the end index). * * vstart: virtual address of start of range - * vend: virtual address of end of range + * vend: virtual address of end of range - we map [vstart, vend] * shift: shift used to transform virtual address into index * ptrs: number of entries in page table * istart: index in table corresponding to vstart @@ -231,17 +231,18 @@ * * tbl: location of page table * rtbl: address to be used for first level page table entry (typically tbl + PAGE_SIZE) - * vstart: start address to map - * vend: end address to map - we map [vstart, vend] + * vstart: virtual address of start of range + * vend: virtual address of end of range - we map [vstart, vend - 1] * flags: flags to use to map last level entries * phys: physical address corresponding to vstart - physical memory is contiguous * pgds: the number of pgd entries * * Temporaries: istart, iend, tmp, count, sv - these need to be different registers - * Preserves: vstart, vend, flags - * Corrupts: tbl, rtbl, istart, iend, tmp, count, sv + * Preserves: vstart, flags + * Corrupts: tbl, rtbl, vend, istart, iend, tmp, count, sv */ .macro map_memory, tbl, rtbl, vstart, vend, flags, phys, pgds, istart, iend, tmp, count, sv + sub \vend, \vend, #1 add \rtbl, \tbl, #PAGE_SIZE mov \sv, \rtbl mov \count, #0 @@ -337,7 +338,7 @@ */ adrp x5, __idmap_text_end clz x5, x5 - cmp x5, TCR_T0SZ(VA_BITS) // default T0SZ small enough? + cmp x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough? b.ge 1f // .. then skip VA range extension adr_l x6, idmap_t0sz @@ -393,13 +394,19 @@ /* * Since the page tables have been populated with non-cacheable - * accesses (MMU disabled), invalidate the idmap and swapper page - * tables again to remove any speculatively loaded cache lines. + * accesses (MMU disabled), invalidate those tables again to + * remove any speculatively loaded cache lines. */ + dmb sy + adrp x0, idmap_pg_dir + adrp x1, idmap_pg_end + sub x1, x1, x0 + bl __inval_dcache_area + + adrp x0, init_pg_dir adrp x1, init_pg_end sub x1, x1, x0 - dmb sy bl __inval_dcache_area ret x28 @@ -964,6 +971,7 @@ tlbi vmalle1 // Remove any stale TLB entries dsb nsh + isb msr sctlr_el1, x19 // re-enable the MMU isb --- linux-oracle-5.4.0.orig/arch/arm64/kernel/hw_breakpoint.c +++ linux-oracle-5.4.0/arch/arm64/kernel/hw_breakpoint.c @@ -654,7 +654,7 @@ perf_bp_event(bp, regs); /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(bp)) + if (uses_default_overflow_handler(bp)) step = 1; unlock: rcu_read_unlock(); @@ -730,6 +730,27 @@ return 0; } +static int watchpoint_report(struct perf_event *wp, unsigned long addr, + struct pt_regs *regs) +{ + int step = uses_default_overflow_handler(wp); + struct arch_hw_breakpoint *info = counter_arch_bp(wp); + + info->trigger = addr; + + /* + * If we triggered a user watchpoint from a uaccess routine, then + * handle the stepping ourselves since userspace really can't help + * us with this. + */ + if (!user_mode(regs) && info->ctrl.privilege == AARCH64_BREAKPOINT_EL0) + step = 1; + else + perf_bp_event(wp, regs); + + return step; +} + static int watchpoint_handler(unsigned long addr, unsigned int esr, struct pt_regs *regs) { @@ -739,7 +760,6 @@ u64 val; struct perf_event *wp, **slots; struct debug_info *debug_info; - struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; slots = this_cpu_ptr(wp_on_reg); @@ -777,25 +797,13 @@ if (dist != 0) continue; - info = counter_arch_bp(wp); - info->trigger = addr; - perf_bp_event(wp, regs); - - /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(wp)) - step = 1; + step = watchpoint_report(wp, addr, regs); } - if (min_dist > 0 && min_dist != -1) { - /* No exact match found. */ - wp = slots[closest_match]; - info = counter_arch_bp(wp); - info->trigger = addr; - perf_bp_event(wp, regs); - /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(wp)) - step = 1; - } + /* No exact match found? */ + if (min_dist > 0 && min_dist != -1) + step = watchpoint_report(slots[closest_match], addr, regs); + rcu_read_unlock(); if (!step) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/insn.c +++ linux-oracle-5.4.0/arch/arm64/kernel/insn.c @@ -21,6 +21,7 @@ #include #include #include +#include #define AARCH64_INSN_SF_BIT BIT(31) #define AARCH64_INSN_N_BIT BIT(22) @@ -78,16 +79,29 @@ static DEFINE_RAW_SPINLOCK(patch_lock); +static bool is_exit_text(unsigned long addr) +{ + /* discarded with init text/data */ + return system_state < SYSTEM_RUNNING && + addr >= (unsigned long)__exittext_begin && + addr < (unsigned long)__exittext_end; +} + +static bool is_image_text(unsigned long addr) +{ + return core_kernel_text(addr) || is_exit_text(addr); +} + static void __kprobes *patch_map(void *addr, int fixmap) { unsigned long uintaddr = (uintptr_t) addr; - bool module = !core_kernel_text(uintaddr); + bool image = is_image_text(uintaddr); struct page *page; - if (module && IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) - page = vmalloc_to_page(addr); - else if (!module) + if (image) page = phys_to_page(__pa_symbol(addr)); + else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + page = vmalloc_to_page(addr); else return addr; @@ -193,8 +207,8 @@ int i, ret = 0; struct aarch64_insn_patch *pp = arg; - /* The first CPU becomes master */ - if (atomic_inc_return(&pp->cpu_count) == 1) { + /* The last CPU becomes master */ + if (atomic_inc_return(&pp->cpu_count) == num_online_cpus()) { for (i = 0; ret == 0 && i < pp->insn_cnt; i++) ret = aarch64_insn_patch_text_nosync(pp->text_addrs[i], pp->new_insns[i]); @@ -1508,16 +1522,10 @@ u32 insn) { unsigned int immr, imms, n, ones, ror, esz, tmp; - u64 mask = ~0UL; - - /* Can't encode full zeroes or full ones */ - if (!imm || !~imm) - return AARCH64_BREAK_FAULT; + u64 mask; switch (variant) { case AARCH64_INSN_VARIANT_32BIT: - if (upper_32_bits(imm)) - return AARCH64_BREAK_FAULT; esz = 32; break; case AARCH64_INSN_VARIANT_64BIT: @@ -1529,6 +1537,12 @@ return AARCH64_BREAK_FAULT; } + mask = GENMASK(esz - 1, 0); + + /* Can't encode full zeroes, full ones, or value wider than the mask */ + if (!imm || imm == mask || imm & ~mask) + return AARCH64_BREAK_FAULT; + /* * Inverse of Replicate(). Try to spot a repeating pattern * with a pow2 stride. --- linux-oracle-5.4.0.orig/arch/arm64/kernel/kgdb.c +++ linux-oracle-5.4.0/arch/arm64/kernel/kgdb.c @@ -223,6 +223,8 @@ */ if (!kernel_active_single_step()) kernel_enable_single_step(linux_regs); + else + kernel_rewind_single_step(linux_regs); err = 0; break; default: @@ -252,7 +254,7 @@ if (!kgdb_single_step) return DBG_HOOK_ERROR; - kgdb_handle_exception(1, SIGTRAP, 0, regs); + kgdb_handle_exception(0, SIGTRAP, 0, regs); return DBG_HOOK_HANDLED; } NOKPROBE_SYMBOL(kgdb_step_brk_fn); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/machine_kexec.c +++ linux-oracle-5.4.0/arch/arm64/kernel/machine_kexec.c @@ -189,6 +189,7 @@ * the offline CPUs. Therefore, we must use the __* variant here. */ __flush_icache_range((uintptr_t)reboot_code_buffer, + (uintptr_t)reboot_code_buffer + arm64_relocate_new_kernel_size); /* Flush the kimage list and its buffers. */ --- linux-oracle-5.4.0.orig/arch/arm64/kernel/machine_kexec_file.c +++ linux-oracle-5.4.0/arch/arm64/kernel/machine_kexec_file.c @@ -150,8 +150,10 @@ /* duplicate a device tree blob */ ret = fdt_open_into(initial_boot_params, buf, buf_size); - if (ret) + if (ret) { + vfree(buf); return -EINVAL; + } ret = setup_dtb(image, initrd_load_addr, initrd_len, cmdline, buf); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/module-plts.c +++ linux-oracle-5.4.0/arch/arm64/kernel/module-plts.c @@ -270,8 +270,7 @@ mod->arch.core.plt_shndx = i; else if (!strcmp(secstrings + sechdrs[i].sh_name, ".init.plt")) mod->arch.init.plt_shndx = i; - else if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE) && - !strcmp(secstrings + sechdrs[i].sh_name, + else if (!strcmp(secstrings + sechdrs[i].sh_name, ".text.ftrace_trampoline")) tramp = sechdrs + i; else if (sechdrs[i].sh_type == SHT_SYMTAB) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/module.c +++ linux-oracle-5.4.0/arch/arm64/kernel/module.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -470,22 +471,48 @@ return -ENOEXEC; } -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) +static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + const char *name) { const Elf_Shdr *s, *se; const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) { - if (strcmp(".altinstructions", secstrs + s->sh_name) == 0) - apply_alternatives_module((void *)s->sh_addr, s->sh_size); -#ifdef CONFIG_ARM64_MODULE_PLTS - if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE) && - !strcmp(".text.ftrace_trampoline", secstrs + s->sh_name)) - me->arch.ftrace_trampoline = (void *)s->sh_addr; -#endif + if (strcmp(name, secstrs + s->sh_name) == 0) + return s; } + return NULL; +} + +static int module_init_ftrace_plt(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *mod) +{ +#if defined(CONFIG_ARM64_MODULE_PLTS) && defined(CONFIG_DYNAMIC_FTRACE) + const Elf_Shdr *s; + struct plt_entry *plt; + + s = find_section(hdr, sechdrs, ".text.ftrace_trampoline"); + if (!s) + return -ENOEXEC; + + plt = (void *)s->sh_addr; + *plt = get_plt_entry(FTRACE_ADDR, plt); + mod->arch.ftrace_trampoline = plt; +#endif return 0; } + +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + struct module *me) +{ + const Elf_Shdr *s; + s = find_section(hdr, sechdrs, ".altinstructions"); + if (s) + apply_alternatives_module((void *)s->sh_addr, s->sh_size); + + return module_init_ftrace_plt(hdr, sechdrs, me); +} --- linux-oracle-5.4.0.orig/arch/arm64/kernel/module.lds +++ linux-oracle-5.4.0/arch/arm64/kernel/module.lds @@ -1,5 +1,5 @@ SECTIONS { - .plt (NOLOAD) : { BYTE(0) } - .init.plt (NOLOAD) : { BYTE(0) } - .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } + .plt 0 : { BYTE(0) } + .init.plt 0 : { BYTE(0) } + .text.ftrace_trampoline 0 : { BYTE(0) } } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/perf_callchain.c +++ linux-oracle-5.4.0/arch/arm64/kernel/perf_callchain.c @@ -102,7 +102,9 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -147,9 +149,10 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct stackframe frame; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -160,18 +163,21 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs) { - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) - return perf_guest_cbs->get_guest_ip(); + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + + if (guest_cbs && guest_cbs->is_in_guest()) + return guest_cbs->get_guest_ip(); return instruction_pointer(regs); } unsigned long perf_misc_flags(struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); int misc = 0; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { - if (perf_guest_cbs->is_user_mode()) + if (guest_cbs && guest_cbs->is_in_guest()) { + if (guest_cbs->is_user_mode()) misc |= PERF_RECORD_MISC_GUEST_USER; else misc |= PERF_RECORD_MISC_GUEST_KERNEL; --- linux-oracle-5.4.0.orig/arch/arm64/kernel/perf_event.c +++ linux-oracle-5.4.0/arch/arm64/kernel/perf_event.c @@ -155,7 +155,7 @@ pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); - return sprintf(page, "event=0x%03llx\n", pmu_attr->id); + return sprintf(page, "event=0x%04llx\n", pmu_attr->id); } #define ARMV8_EVENT_ATTR(name, config) \ @@ -303,10 +303,13 @@ test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) return attr->mode; - pmu_attr->id -= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; - if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && - test_bit(pmu_attr->id, cpu_pmu->pmceid_ext_bitmap)) - return attr->mode; + if (pmu_attr->id >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) { + u64 id = pmu_attr->id - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; + + if (id < ARMV8_PMUV3_MAX_COMMON_EVENTS && + test_bit(id, cpu_pmu->pmceid_ext_bitmap)) + return attr->mode; + } return 0; } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/perf_regs.c +++ linux-oracle-5.4.0/arch/arm64/kernel/perf_regs.c @@ -15,15 +15,34 @@ return 0; /* - * Compat (i.e. 32 bit) mode: - * - PC has been set in the pt_regs struct in kernel_entry, - * - Handle SP and LR here. + * Our handling of compat tasks (PERF_SAMPLE_REGS_ABI_32) is weird, but + * we're stuck with it for ABI compatability reasons. + * + * For a 32-bit consumer inspecting a 32-bit task, then it will look at + * the first 16 registers (see arch/arm/include/uapi/asm/perf_regs.h). + * These correspond directly to a prefix of the registers saved in our + * 'struct pt_regs', with the exception of the PC, so we copy that down + * (x15 corresponds to SP_hyp in the architecture). + * + * So far, so good. + * + * The oddity arises when a 64-bit consumer looks at a 32-bit task and + * asks for registers beyond PERF_REG_ARM_MAX. In this case, we return + * SP_usr, LR_usr and PC in the positions where the AArch64 SP, LR and + * PC registers would normally live. The initial idea was to allow a + * 64-bit unwinder to unwind a 32-bit task and, although it's not clear + * how well that works in practice, somebody might be relying on it. + * + * At the time we make a sample, we don't know whether the consumer is + * 32-bit or 64-bit, so we have to cater for both possibilities. */ if (compat_user_mode(regs)) { if ((u32)idx == PERF_REG_ARM64_SP) return regs->compat_sp; if ((u32)idx == PERF_REG_ARM64_LR) return regs->compat_lr; + if (idx == 15) + return regs->pc; } if ((u32)idx == PERF_REG_ARM64_SP) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/probes/decode-insn.c +++ linux-oracle-5.4.0/arch/arm64/kernel/probes/decode-insn.c @@ -96,10 +96,6 @@ aarch64_insn_is_blr(insn) || aarch64_insn_is_ret(insn)) { api->handler = simulate_br_blr_ret; - } else if (aarch64_insn_is_ldr_lit(insn)) { - api->handler = simulate_ldr_literal; - } else if (aarch64_insn_is_ldrsw_lit(insn)) { - api->handler = simulate_ldrsw_literal; } else { /* * Instruction cannot be stepped out-of-line and we don't @@ -137,6 +133,17 @@ probe_opcode_t insn = le32_to_cpu(*addr); probe_opcode_t *scan_end = NULL; unsigned long size = 0, offset = 0; + struct arch_probe_insn *api = &asi->api; + + if (aarch64_insn_is_ldr_lit(insn)) { + api->handler = simulate_ldr_literal; + decoded = INSN_GOOD_NO_SLOT; + } else if (aarch64_insn_is_ldrsw_lit(insn)) { + api->handler = simulate_ldrsw_literal; + decoded = INSN_GOOD_NO_SLOT; + } else { + decoded = arm_probe_decode_insn(insn, &asi->api); + } /* * If there's a symbol defined in front of and near enough to @@ -154,7 +161,6 @@ else scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; } - decoded = arm_probe_decode_insn(insn, &asi->api); if (decoded != INSN_REJECTED && scan_end) if (is_probed_address_atomic(addr - 1, scan_end)) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/probes/kprobes.c +++ linux-oracle-5.4.0/arch/arm64/kernel/probes/kprobes.c @@ -36,25 +36,16 @@ static void __kprobes post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *); -static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode) -{ - void *addrs[1]; - u32 insns[1]; - - addrs[0] = addr; - insns[0] = opcode; - - return aarch64_insn_patch_text(addrs, insns, 1); -} - static void __kprobes arch_prepare_ss_slot(struct kprobe *p) { + kprobe_opcode_t *addr = p->ainsn.api.insn; + void *addrs[] = {addr, addr + 1}; + u32 insns[] = {p->opcode, BRK64_OPCODE_KPROBES_SS}; + /* prepare insn slot */ - patch_text(p->ainsn.api.insn, p->opcode); + aarch64_insn_patch_text(addrs, insns, 2); - flush_icache_range((uintptr_t) (p->ainsn.api.insn), - (uintptr_t) (p->ainsn.api.insn) + - MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + flush_icache_range((uintptr_t)addr, (uintptr_t)(addr + MAX_INSN_SIZE)); /* * Needs restoring of return address after stepping xol. @@ -134,13 +125,18 @@ /* arm kprobe: install breakpoint in text */ void __kprobes arch_arm_kprobe(struct kprobe *p) { - patch_text(p->addr, BRK64_OPCODE_KPROBES); + void *addr = p->addr; + u32 insn = BRK64_OPCODE_KPROBES; + + aarch64_insn_patch_text(&addr, &insn, 1); } /* disarm kprobe: remove breakpoint from text */ void __kprobes arch_disarm_kprobe(struct kprobe *p) { - patch_text(p->addr, p->opcode); + void *addr = p->addr; + + aarch64_insn_patch_text(&addr, &p->opcode, 1); } void __kprobes arch_remove_kprobe(struct kprobe *p) @@ -169,20 +165,15 @@ } /* - * Interrupts need to be disabled before single-step mode is set, and not - * reenabled until after single-step mode ends. - * Without disabling interrupt on local CPU, there is a chance of - * interrupt occurrence in the period of exception return and start of - * out-of-line single-step, that result in wrongly single stepping - * into the interrupt handler. + * Mask all of DAIF while executing the instruction out-of-line, to keep things + * simple and avoid nesting exceptions. Interrupts do have to be disabled since + * the kprobe state is per-CPU and doesn't get migrated. */ static void __kprobes kprobes_save_local_irqflag(struct kprobe_ctlblk *kcb, struct pt_regs *regs) { kcb->saved_irqflag = regs->pstate & DAIF_MASK; - regs->pstate |= PSR_I_BIT; - /* Unmask PSTATE.D for enabling software step exceptions. */ - regs->pstate &= ~PSR_D_BIT; + regs->pstate |= DAIF_MASK; } static void __kprobes kprobes_restore_local_irqflag(struct kprobe_ctlblk *kcb, @@ -225,10 +216,7 @@ slot = (unsigned long)p->ainsn.api.insn; set_ss_context(kcb, slot); /* mark pending ss */ - - /* IRQs and single stepping do not mix well. */ kprobes_save_local_irqflag(kcb, regs); - kernel_enable_single_step(regs); instruction_pointer_set(regs, slot); } else { /* insn simulation */ @@ -279,12 +267,8 @@ } /* call post handler */ kcb->kprobe_status = KPROBE_HIT_SSDONE; - if (cur->post_handler) { - /* post_handler can hit breakpoint and single step - * again, so we enable D-flag for recursive exception. - */ + if (cur->post_handler) cur->post_handler(cur, regs, 0); - } reset_current_kprobe(); } @@ -308,8 +292,6 @@ if (!instruction_pointer(regs)) BUG(); - kernel_disable_single_step(); - if (kcb->kprobe_status == KPROBE_REENTER) restore_previous_kprobe(kcb); else @@ -371,10 +353,6 @@ * pre-handler and it returned non-zero, it will * modify the execution path and no need to single * stepping. Let's just reset current kprobe and exit. - * - * pre_handler can hit a breakpoint and can step thru - * before return, keep PSTATE D-flag enabled until - * pre_handler return back. */ if (!p->pre_handler || !p->pre_handler(p, regs)) { setup_singlestep(p, regs, kcb, 0); @@ -405,7 +383,7 @@ } static int __kprobes -kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr) +kprobe_breakpoint_ss_handler(struct pt_regs *regs, unsigned int esr) { struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); int retval; @@ -415,16 +393,15 @@ if (retval == DBG_HOOK_HANDLED) { kprobes_restore_local_irqflag(kcb, regs); - kernel_disable_single_step(); - post_kprobe_handler(kcb, regs); } return retval; } -static struct step_hook kprobes_step_hook = { - .fn = kprobe_single_step_handler, +static struct break_hook kprobes_break_ss_hook = { + .imm = KPROBES_BRK_SS_IMM, + .fn = kprobe_breakpoint_ss_handler, }; static int __kprobes @@ -568,7 +545,7 @@ int __init arch_init_kprobes(void) { register_kernel_break_hook(&kprobes_break_hook); - register_kernel_step_hook(&kprobes_step_hook); + register_kernel_break_hook(&kprobes_break_ss_hook); return 0; } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/probes/simulate-insn.c +++ linux-oracle-5.4.0/arch/arm64/kernel/probes/simulate-insn.c @@ -170,17 +170,15 @@ void __kprobes simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) { - u64 *load_addr; + unsigned long load_addr; int xn = opcode & 0x1f; - int disp; - disp = ldr_displacement(opcode); - load_addr = (u64 *) (addr + disp); + load_addr = addr + ldr_displacement(opcode); if (opcode & (1 << 30)) /* x0-x30 */ - set_x_reg(regs, xn, *load_addr); + set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr)); else /* w0-w30 */ - set_w_reg(regs, xn, *load_addr); + set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr)); instruction_pointer_set(regs, instruction_pointer(regs) + 4); } @@ -188,14 +186,12 @@ void __kprobes simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) { - s32 *load_addr; + unsigned long load_addr; int xn = opcode & 0x1f; - int disp; - disp = ldr_displacement(opcode); - load_addr = (s32 *) (addr + disp); + load_addr = addr + ldr_displacement(opcode); - set_x_reg(regs, xn, *load_addr); + set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr)); instruction_pointer_set(regs, instruction_pointer(regs) + 4); } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/probes/uprobes.c +++ linux-oracle-5.4.0/arch/arm64/kernel/probes/uprobes.c @@ -38,11 +38,11 @@ /* TODO: Currently we do not support AARCH32 instruction probing */ if (mm->context.flags & MMCF_AARCH32) - return -ENOTSUPP; + return -EOPNOTSUPP; else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) return -EINVAL; - insn = *(probe_opcode_t *)(&auprobe->insn[0]); + insn = le32_to_cpu(auprobe->insn); switch (arm_probe_decode_insn(insn, &auprobe->api)) { case INSN_REJECTED: @@ -108,7 +108,7 @@ if (!auprobe->simulate) return false; - insn = *(probe_opcode_t *)(&auprobe->insn[0]); + insn = le32_to_cpu(auprobe->insn); addr = instruction_pointer(regs); if (auprobe->api.handler) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/process.c +++ linux-oracle-5.4.0/arch/arm64/kernel/process.c @@ -56,7 +56,7 @@ #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include -unsigned long __stack_chk_guard __read_mostly; +unsigned long __stack_chk_guard __ro_after_init; EXPORT_SYMBOL(__stack_chk_guard); #endif @@ -360,8 +360,8 @@ asmlinkage void ret_from_fork(void) asm("ret_from_fork"); -int copy_thread(unsigned long clone_flags, unsigned long stack_start, - unsigned long stk_sz, struct task_struct *p) +int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start, + unsigned long stk_sz, struct task_struct *p, unsigned long tls) { struct pt_regs *childregs = task_pt_regs(p); @@ -394,11 +394,11 @@ } /* - * If a TLS pointer was passed to clone (4th argument), use it - * for the new thread. + * If a TLS pointer was passed to clone, use it for the new + * thread. */ if (clone_flags & CLONE_SETTLS) - p->thread.uw.tp_value = childregs->regs[3]; + p->thread.uw.tp_value = tls; } else { memset(childregs, 0, sizeof(struct pt_regs)); childregs->pstate = PSR_MODE_EL1h; @@ -434,7 +434,7 @@ if (is_compat_thread(task_thread_info(next))) write_sysreg(next->thread.uw.tp_value, tpidrro_el0); - else if (!arm64_kernel_unmapped_at_el0()) + else write_sysreg(0, tpidrro_el0); write_sysreg(*task_user_tls(next), tpidr_el0); @@ -466,6 +466,13 @@ if (unlikely(next->flags & PF_KTHREAD)) return; + /* + * If all CPUs implement the SSBS extension, then we just need to + * context-switch the PSTATE field. + */ + if (cpu_have_feature(cpu_feature(SSBS))) + return; + /* If the mitigation is enabled, then we leave SSBS clear. */ if ((arm64_get_ssbd_state() == ARM64_SSBD_FORCE_ENABLE) || test_tsk_thread_flag(next, TIF_SSBD)) @@ -492,6 +499,30 @@ } /* + * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. + * Ensure access is disabled when switching to a 32bit task, ensure + * access is enabled when switching to a 64bit task. + */ +static void erratum_1418040_thread_switch(struct task_struct *next) +{ + if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) || + !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) + return; + + if (is_compat_thread(task_thread_info(next))) + sysreg_clear_set(cntkctl_el1, ARCH_TIMER_USR_VCT_ACCESS_EN, 0); + else + sysreg_clear_set(cntkctl_el1, 0, ARCH_TIMER_USR_VCT_ACCESS_EN); +} + +static void erratum_1418040_new_exec(void) +{ + preempt_disable(); + erratum_1418040_thread_switch(current); + preempt_enable(); +} + +/* * Thread switching. */ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, @@ -507,6 +538,7 @@ uao_thread_switch(next); ptrauth_thread_switch(next); ssbs_thread_switch(next); + erratum_1418040_thread_switch(next); /* * Complete any pending TLB or cache maintenance on this CPU in case @@ -565,6 +597,7 @@ current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0; ptrauth_thread_init_user(current); + erratum_1418040_new_exec(); } #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI --- linux-oracle-5.4.0.orig/arch/arm64/kernel/psci.c +++ linux-oracle-5.4.0/arch/arm64/kernel/psci.c @@ -66,7 +66,6 @@ static void cpu_psci_cpu_die(unsigned int cpu) { - int ret; /* * There are no known implementations of PSCI actually using the * power state field, pass a sensible default for now. @@ -74,14 +73,13 @@ u32 state = PSCI_POWER_STATE_TYPE_POWER_DOWN << PSCI_0_2_POWER_STATE_TYPE_SHIFT; - ret = psci_ops.cpu_off(state); - - pr_crit("unable to power off CPU%u (%d)\n", cpu, ret); + psci_ops.cpu_off(state); } static int cpu_psci_cpu_kill(unsigned int cpu) { - int err, i; + int err; + unsigned long start, end; if (!psci_ops.affinity_info) return 0; @@ -91,16 +89,18 @@ * while it is dying. So, try again a few times. */ - for (i = 0; i < 10; i++) { + start = jiffies; + end = start + msecs_to_jiffies(100); + do { err = psci_ops.affinity_info(cpu_logical_map(cpu), 0); if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) { - pr_info("CPU%d killed.\n", cpu); + pr_info("CPU%d killed (polled %d ms)\n", cpu, + jiffies_to_msecs(jiffies - start)); return 0; } - msleep(10); - pr_info("Retrying again to check for CPU kill\n"); - } + usleep_range(100, 1000); + } while (time_before(jiffies, end)); pr_warn("CPU%d may not have shut down cleanly (AFFINITY_INFO reports %d)\n", cpu, err); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/arm64/kernel/ptrace.c @@ -615,6 +615,13 @@ return 0; } +static int fpr_active(struct task_struct *target, const struct user_regset *regset) +{ + if (!system_supports_fpsimd()) + return -ENODEV; + return regset->n; +} + /* * TODO: update fp accessors for lazy context switching (sync/flush hwstate) */ @@ -637,6 +644,9 @@ unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { + if (!system_supports_fpsimd()) + return -EINVAL; + if (target == current) fpsimd_preserve_current_state(); @@ -676,6 +686,9 @@ { int ret; + if (!system_supports_fpsimd()) + return -EINVAL; + ret = __fpr_set(target, regset, pos, count, kbuf, ubuf, 0); if (ret) return ret; @@ -1134,6 +1147,7 @@ */ .size = sizeof(u32), .align = sizeof(u32), + .active = fpr_active, .get = fpr_get, .set = fpr_set }, @@ -1348,6 +1362,9 @@ compat_ulong_t fpscr; int ret, vregs_end_pos; + if (!system_supports_fpsimd()) + return -EINVAL; + uregs = &target->thread.uw.fpsimd_state; if (target == current) @@ -1381,6 +1398,9 @@ compat_ulong_t fpscr; int ret, vregs_end_pos; + if (!system_supports_fpsimd()) + return -EINVAL; + uregs = &target->thread.uw.fpsimd_state; vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t); @@ -1438,6 +1458,7 @@ .n = VFP_STATE_SIZE / sizeof(compat_ulong_t), .size = sizeof(compat_ulong_t), .align = sizeof(compat_ulong_t), + .active = fpr_active, .get = compat_vfp_get, .set = compat_vfp_set }, @@ -1798,20 +1819,32 @@ saved_reg = regs->regs[regno]; regs->regs[regno] = dir; - if (dir == PTRACE_SYSCALL_EXIT) + if (dir == PTRACE_SYSCALL_ENTER) { + if (tracehook_report_syscall_entry(regs)) + forget_syscall(regs); + regs->regs[regno] = saved_reg; + } else if (!test_thread_flag(TIF_SINGLESTEP)) { tracehook_report_syscall_exit(regs, 0); - else if (tracehook_report_syscall_entry(regs)) - forget_syscall(regs); + regs->regs[regno] = saved_reg; + } else { + regs->regs[regno] = saved_reg; - regs->regs[regno] = saved_reg; + /* + * Signal a pseudo-step exception since we are stepping but + * tracer modifications to the registers may have rewound the + * state machine. + */ + tracehook_report_syscall_exit(regs, 1); + } } int syscall_trace_enter(struct pt_regs *regs) { - if (test_thread_flag(TIF_SYSCALL_TRACE) || - test_thread_flag(TIF_SYSCALL_EMU)) { + unsigned long flags = READ_ONCE(current_thread_info()->flags); + + if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); - if (!in_syscall(regs) || test_thread_flag(TIF_SYSCALL_EMU)) + if (flags & _TIF_SYSCALL_EMU) return -1; } @@ -1830,12 +1863,14 @@ void syscall_trace_exit(struct pt_regs *regs) { + unsigned long flags = READ_ONCE(current_thread_info()->flags); + audit_syscall_exit(regs); - if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) - trace_sys_exit(regs, regs_return_value(regs)); + if (flags & _TIF_SYSCALL_TRACEPOINT) + trace_sys_exit(regs, syscall_get_return_value(current, regs)); - if (test_thread_flag(TIF_SYSCALL_TRACE)) + if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)) tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT); rseq_syscall(regs); @@ -1913,8 +1948,8 @@ */ int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task) { - if (!test_tsk_thread_flag(task, TIF_SINGLESTEP)) - regs->pstate &= ~DBG_SPSR_SS; + /* https://lore.kernel.org/lkml/20191118131525.GA4180@willie-the-truck */ + user_regs_reset_single_step(regs, task); if (is_compat_thread(task_thread_info(task))) return valid_compat_regs(regs); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/setup.c +++ linux-oracle-5.4.0/arch/arm64/kernel/setup.c @@ -85,7 +85,7 @@ void __init smp_setup_processor_id(void) { u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; - cpu_logical_map(0) = mpidr; + set_cpu_logical_map(0, mpidr); /* * clear __my_cpu_offset on boot CPU to avoid hang caused by @@ -276,6 +276,12 @@ u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; +u64 cpu_logical_map(int cpu) +{ + return __cpu_logical_map[cpu]; +} +EXPORT_SYMBOL_GPL(cpu_logical_map); + void __init setup_arch(char **cmdline_p) { init_mm.start_code = (unsigned long) _text; @@ -350,7 +356,7 @@ * faults in case uaccess_enable() is inadvertently called by the init * thread. */ - init_task.thread_info.ttbr0 = __pa_symbol(empty_zero_page); + init_task.thread_info.ttbr0 = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); #endif #ifdef CONFIG_VT --- linux-oracle-5.4.0.orig/arch/arm64/kernel/signal.c +++ linux-oracle-5.4.0/arch/arm64/kernel/signal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -782,7 +783,6 @@ */ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { - struct task_struct *tsk = current; sigset_t *oldset = sigmask_to_save(); int usig = ksig->sig; int ret; @@ -806,14 +806,8 @@ */ ret |= !valid_user_regs(®s->user_regs, current); - /* - * Fast forward the stepping logic so we step into the signal - * handler. - */ - if (!ret) - user_fastforward_single_step(tsk); - - signal_setup_done(ret, ksig, 0); + /* Step into the signal handler if we are stepping */ + signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); } /* @@ -875,7 +869,7 @@ retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ksig.ka.sa.sa_flags & SA_RESTART)))) { - regs->regs[0] = -EINTR; + syscall_set_return_value(current, regs, -EINTR, 0); regs->pc = continue_addr; } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/smp.c +++ linux-oracle-5.4.0/arch/arm64/kernel/smp.c @@ -215,6 +215,7 @@ if (system_uses_irq_prio_masking()) init_gic_priority_masking(); + rcu_cpu_starting(cpu); preempt_disable(); trace_hardirqs_off(); @@ -387,6 +388,7 @@ /* Mark this CPU absent */ set_cpu_present(cpu, 0); + rcu_report_dead(cpu); #ifdef CONFIG_HOTPLUG_CPU update_cpu_boot_status(CPU_KILL_ME); @@ -549,7 +551,7 @@ return; /* map the logical cpu id to cpu MPIDR */ - cpu_logical_map(cpu_count) = hwid; + set_cpu_logical_map(cpu_count, hwid); cpu_madt_gicc[cpu_count] = *processor; @@ -663,7 +665,7 @@ goto next; pr_debug("cpu logical map 0x%llx\n", hwid); - cpu_logical_map(cpu_count) = hwid; + set_cpu_logical_map(cpu_count, hwid); early_map_cpu_to_node(cpu_count, of_node_to_nid(dn)); next: @@ -704,7 +706,7 @@ for (i = 1; i < nr_cpu_ids; i++) { if (cpu_logical_map(i) != INVALID_HWID) { if (smp_cpu_setup(i)) - cpu_logical_map(i) = INVALID_HWID; + set_cpu_logical_map(i, INVALID_HWID); } } } @@ -955,11 +957,22 @@ } #endif +/* + * The number of CPUs online, not counting this CPU (which may not be + * fully online and so not counted in num_online_cpus()). + */ +static inline unsigned int num_other_online_cpus(void) +{ + unsigned int this_cpu_online = cpu_online(smp_processor_id()); + + return num_online_cpus() - this_cpu_online; +} + void smp_send_stop(void) { unsigned long timeout; - if (num_online_cpus() > 1) { + if (num_other_online_cpus()) { cpumask_t mask; cpumask_copy(&mask, cpu_online_mask); @@ -972,10 +985,10 @@ /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; - while (num_online_cpus() > 1 && timeout--) + while (num_other_online_cpus() && timeout--) udelay(1); - if (num_online_cpus() > 1) + if (num_other_online_cpus()) pr_warning("SMP: failed to stop secondary CPUs %*pbl\n", cpumask_pr_args(cpu_online_mask)); @@ -998,7 +1011,11 @@ cpus_stopped = 1; - if (num_online_cpus() == 1) { + /* + * If this cpu is the only one alive at this point in time, online or + * not, there are no stop messages to be sent around, so just back out. + */ + if (num_other_online_cpus() == 0) { sdei_mask_local_cpu(); return; } @@ -1006,7 +1023,7 @@ cpumask_copy(&mask, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &mask); - atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); + atomic_set(&waiting_for_crash_ipi, num_other_online_cpus()); pr_crit("SMP: stopping secondary CPUs\n"); smp_cross_call(&mask, IPI_CPU_CRASH_STOP); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/sys_compat.c +++ linux-oracle-5.4.0/arch/arm64/kernel/sys_compat.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include +#include #include static long @@ -30,6 +32,15 @@ if (fatal_signal_pending(current)) return 0; + if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) { + /* + * The workaround requires an inner-shareable tlbi. + * We pick the reserved-ASID to minimise the impact. + */ + __tlbi(aside1is, __TLBI_VADDR(0, 0)); + dsb(ish); + } + ret = __flush_cache_user_range(start, start + chunk); if (ret) return ret; @@ -104,6 +115,6 @@ (compat_thumb_mode(regs) ? 2 : 4); arm64_notify_die("Oops - bad compat syscall(2)", regs, - SIGILL, ILL_ILLTRP, addr, scno); + SIGILL, ILL_ILLTRP, addr, 0); return 0; } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/syscall.c +++ linux-oracle-5.4.0/arch/arm64/kernel/syscall.c @@ -50,7 +50,7 @@ ret = do_ni_syscall(regs, scno); } - regs->regs[0] = ret; + syscall_set_return_value(current, regs, 0, ret); } static inline bool has_syscall_work(unsigned long flags) @@ -99,13 +99,13 @@ regs->syscallno = scno; cortex_a76_erratum_1463225_svc_handler(); + user_exit_irqoff(); local_daif_restore(DAIF_PROCCTX); - user_exit(); if (has_syscall_work(flags)) { /* set default errno for user-issued syscall(-1) */ if (scno == NO_SYSCALL) - regs->regs[0] = -ENOSYS; + syscall_set_return_value(current, regs, -ENOSYS, 0); scno = syscall_trace_enter(regs); if (scno == NO_SYSCALL) goto trace_exit; @@ -121,7 +121,7 @@ if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { local_daif_mask(); flags = current_thread_info()->flags; - if (!has_syscall_work(flags)) { + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { /* * We're off to userspace, where interrupts are * always enabled after we restore the flags from --- linux-oracle-5.4.0.orig/arch/arm64/kernel/topology.c +++ linux-oracle-5.4.0/arch/arm64/kernel/topology.c @@ -21,44 +21,6 @@ #include #include -void store_cpu_topology(unsigned int cpuid) -{ - struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; - u64 mpidr; - - if (cpuid_topo->package_id != -1) - goto topology_populated; - - mpidr = read_cpuid_mpidr(); - - /* Uniprocessor systems can rely on default topology values */ - if (mpidr & MPIDR_UP_BITMASK) - return; - - /* Create cpu topology mapping based on MPIDR. */ - if (mpidr & MPIDR_MT_BITMASK) { - /* Multiprocessor system : Multi-threads per core */ - cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); - cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); - cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) | - MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8; - } else { - /* Multiprocessor system : Single-thread per core */ - cpuid_topo->thread_id = -1; - cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); - cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) | - MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 | - MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16; - } - - pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", - cpuid, cpuid_topo->package_id, cpuid_topo->core_id, - cpuid_topo->thread_id, mpidr); - -topology_populated: - update_siblings_masks(cpuid); -} - #ifdef CONFIG_ACPI static bool __init acpi_cpu_is_threaded(int cpu) { --- linux-oracle-5.4.0.orig/arch/arm64/kernel/traps.c +++ linux-oracle-5.4.0/arch/arm64/kernel/traps.c @@ -202,7 +202,7 @@ raw_spin_unlock_irqrestore(&die_lock, flags); if (ret != NOTIFY_STOP) - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } static void arm64_show_signal(int signo, const char *str) @@ -470,6 +470,15 @@ int rt = ESR_ELx_SYS64_ISS_RT(esr); unsigned long val = arm64_ftr_reg_user_value(&arm64_ftr_reg_ctrel0); + if (cpus_have_const_cap(ARM64_WORKAROUND_1542419)) { + /* Hide DIC so that we can trap the unnecessary maintenance...*/ + val &= ~BIT(CTR_DIC_SHIFT); + + /* ... and fake IminLine to reduce the number of traps. */ + val &= ~CTR_IMINLINE_MASK; + val |= (PAGE_SHIFT - 2) & CTR_IMINLINE_MASK; + } + pt_regs_write_reg(regs, rt, val); arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); --- linux-oracle-5.4.0.orig/arch/arm64/kernel/vdso.c +++ linux-oracle-5.4.0/arch/arm64/kernel/vdso.c @@ -260,18 +260,7 @@ if (ret) return ret; - ret = aarch32_alloc_kuser_vdso_page(); - if (ret) { - unsigned long c_vvar = - (unsigned long)page_to_virt(aarch32_vdso_pages[C_VVAR]); - unsigned long c_vdso = - (unsigned long)page_to_virt(aarch32_vdso_pages[C_VDSO]); - - free_page(c_vvar); - free_page(c_vdso); - } - - return ret; + return aarch32_alloc_kuser_vdso_page(); } #else static int __aarch32_alloc_vdso_pages(void) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/vdso/Makefile +++ linux-oracle-5.4.0/arch/arm64/kernel/vdso/Makefile @@ -32,7 +32,7 @@ OBJECT_FILES_NON_STANDARD := y KCOV_INSTRUMENT := n -CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny +CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -fasynchronous-unwind-tables ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) --- linux-oracle-5.4.0.orig/arch/arm64/kernel/vdso/vdso.lds.S +++ linux-oracle-5.4.0/arch/arm64/kernel/vdso/vdso.lds.S @@ -28,6 +28,13 @@ .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } + /* + * Discard .note.gnu.property sections which are unused and have + * different alignment requirement from vDSO note sections. + */ + /DISCARD/ : { + *(.note.GNU-stack .note.gnu.property) + } .note : { *(.note.*) } :text :note . = ALIGN(16); @@ -48,7 +55,6 @@ PROVIDE(end = .); /DISCARD/ : { - *(.note.GNU-stack) *(.data .data.* .gnu.linkonce.d.* .sdata*) *(.bss .sbss .dynbss .dynsbss) } --- linux-oracle-5.4.0.orig/arch/arm64/kernel/vdso32/Makefile +++ linux-oracle-5.4.0/arch/arm64/kernel/vdso32/Makefile @@ -32,7 +32,8 @@ # As a result we set our own flags here. # KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile -VDSO_CPPFLAGS := -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include) +VDSO_CPPFLAGS := -D__KERNEL__ -nostdinc +VDSO_CPPFLAGS += -isystem $(shell $(CC_COMPAT) -print-file-name=include 2>/dev/null) VDSO_CPPFLAGS += $(LINUXINCLUDE) # Common C and assembly flags @@ -190,7 +191,7 @@ cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ # Install commands for the unstripped file -quiet_cmd_vdso_install = INSTALL $@ +quiet_cmd_vdso_install = INSTALL32 $@ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/vdso32.so vdso.so: $(obj)/vdso.so.dbg --- linux-oracle-5.4.0.orig/arch/arm64/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/arm64/kernel/vmlinux.lds.S @@ -24,6 +24,13 @@ jiffies = jiffies_64; + +#define HYPERVISOR_EXTABLE \ + . = ALIGN(SZ_8); \ + __start___kvm_ex_table = .; \ + *(__kvm_ex_table) \ + __stop___kvm_ex_table = .; + #define HYPERVISOR_TEXT \ /* \ * Align to 4 KB so that \ @@ -39,6 +46,7 @@ __hyp_idmap_text_end = .; \ __hyp_text_start = .; \ *(.hyp.text) \ + HYPERVISOR_EXTABLE \ __hyp_text_end = .; #define IDMAP_TEXT \ @@ -142,28 +150,30 @@ . = ALIGN(PAGE_SIZE); idmap_pg_dir = .; . += IDMAP_DIR_SIZE; + idmap_pg_end = .; #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 tramp_pg_dir = .; . += PAGE_SIZE; #endif -#ifdef CONFIG_ARM64_SW_TTBR0_PAN - reserved_ttbr0 = .; - . += RESERVED_TTBR0_SIZE; -#endif + reserved_pg_dir = .; + . += PAGE_SIZE; + swapper_pg_dir = .; . += PAGE_SIZE; - swapper_pg_end = .; . = ALIGN(SEGMENT_ALIGN); __init_begin = .; __inittext_begin = .; INIT_TEXT_SECTION(8) + + __exittext_begin = .; .exit.text : { ARM_EXIT_KEEP(EXIT_TEXT) } + __exittext_end = .; . = ALIGN(4); .altinstructions : { @@ -171,9 +181,6 @@ *(.altinstructions) __alt_instructions_end = .; } - .altinstr_replacement : { - *(.altinstr_replacement) - } . = ALIGN(PAGE_SIZE); __inittext_end = .; @@ -269,7 +276,7 @@ <= SZ_4K, "Hibernate exit text too big or misaligned") #endif #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 -ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE, +ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE, "Entry trampoline text too big") #endif /* --- linux-oracle-5.4.0.orig/arch/arm64/kvm/debug.c +++ linux-oracle-5.4.0/arch/arm64/kvm/debug.c @@ -69,6 +69,64 @@ } /** + * kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value + * + * @vcpu: the vcpu pointer + * + * This ensures we will trap access to: + * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) + * - Debug ROM Address (MDCR_EL2_TDRA) + * - OS related registers (MDCR_EL2_TDOSA) + * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) + * - Self-hosted Trace Filter controls (MDCR_EL2_TTRF) + */ +static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu) +{ + /* + * This also clears MDCR_EL2_E2PB_MASK to disable guest access + * to the profiling buffer. + */ + vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; + vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | + MDCR_EL2_TPMS | + MDCR_EL2_TTRF | + MDCR_EL2_TPMCR | + MDCR_EL2_TDRA | + MDCR_EL2_TDOSA); + + /* Is the VM being debugged by userspace? */ + if (vcpu->guest_debug) + /* Route all software debug exceptions to EL2 */ + vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; + + /* + * Trap debug register access when one of the following is true: + * - Userspace is using the hardware to debug the guest + * (KVM_GUESTDBG_USE_HW is set). + * - The guest is not using debug (KVM_ARM64_DEBUG_DIRTY is clear). + */ + if ((vcpu->guest_debug & KVM_GUESTDBG_USE_HW) || + !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) + vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; + + trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); +} + +/** + * kvm_arm_vcpu_init_debug - setup vcpu debug traps + * + * @vcpu: the vcpu pointer + * + * Set vcpu initial mdcr_el2 value. + */ +void kvm_arm_vcpu_init_debug(struct kvm_vcpu *vcpu) +{ + preempt_disable(); + kvm_arm_setup_mdcr_el2(vcpu); + preempt_enable(); +} + +/** * kvm_arm_reset_debug_ptr - reset the debug ptr to point to the vcpu state */ @@ -83,12 +141,7 @@ * @vcpu: the vcpu pointer * * This is called before each entry into the hypervisor to setup any - * debug related registers. Currently this just ensures we will trap - * access to: - * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) - * - Debug ROM Address (MDCR_EL2_TDRA) - * - OS related registers (MDCR_EL2_TDOSA) - * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) + * debug related registers. * * Additionally, KVM only traps guest accesses to the debug registers if * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY @@ -100,27 +153,14 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) { - bool trap_debug = !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY); - unsigned long mdscr; + unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2; trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug); - /* - * This also clears MDCR_EL2_E2PB_MASK to disable guest access - * to the profiling buffer. - */ - vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK; - vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | - MDCR_EL2_TPMS | - MDCR_EL2_TPMCR | - MDCR_EL2_TDRA | - MDCR_EL2_TDOSA); + kvm_arm_setup_mdcr_el2(vcpu); /* Is Guest debugging in effect? */ if (vcpu->guest_debug) { - /* Route all software debug exceptions to EL2 */ - vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE; - /* Save guest debug state */ save_guest_debug_regs(vcpu); @@ -174,7 +214,6 @@ vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state; vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; - trap_debug = true; trace_kvm_arm_set_regset("BKPTS", get_num_brps(), &vcpu->arch.debug_ptr->dbg_bcr[0], @@ -189,15 +228,14 @@ BUG_ON(!vcpu->guest_debug && vcpu->arch.debug_ptr != &vcpu->arch.vcpu_debug_state); - /* Trap debug register access */ - if (trap_debug) - vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; - /* If KDE or MDE are set, perform a full save/restore cycle. */ if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE)) vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY; - trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2); + /* Write mdcr_el2 changes since vcpu_load on VHE systems */ + if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2) + write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); + trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1)); } --- linux-oracle-5.4.0.orig/arch/arm64/kvm/guest.c +++ linux-oracle-5.4.0/arch/arm64/kvm/guest.c @@ -186,6 +186,7 @@ case PSR_AA32_MODE_SVC: case PSR_AA32_MODE_ABT: case PSR_AA32_MODE_UND: + case PSR_AA32_MODE_SYS: if (!vcpu_el1_is_32bit(vcpu)) return -EINVAL; break; @@ -202,6 +203,13 @@ } memcpy((u32 *)regs + off, valp, KVM_REG_SIZE(reg->id)); + + if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) { + int i; + + for (i = 0; i < 16; i++) + *vcpu_reg32(vcpu, i) = (u32)*vcpu_reg32(vcpu, i); + } out: return err; } --- linux-oracle-5.4.0.orig/arch/arm64/kvm/handle_exit.c +++ linux-oracle-5.4.0/arch/arm64/kvm/handle_exit.c @@ -162,31 +162,16 @@ return 1; } -#define __ptrauth_save_key(regs, key) \ -({ \ - regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1); \ - regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1); \ -}) - /* * Handle the guest trying to use a ptrauth instruction, or trying to access a * ptrauth register. */ void kvm_arm_vcpu_ptrauth_trap(struct kvm_vcpu *vcpu) { - struct kvm_cpu_context *ctxt; - - if (vcpu_has_ptrauth(vcpu)) { + if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_enable(vcpu); - ctxt = vcpu->arch.host_cpu_context; - __ptrauth_save_key(ctxt->sys_regs, APIA); - __ptrauth_save_key(ctxt->sys_regs, APIB); - __ptrauth_save_key(ctxt->sys_regs, APDA); - __ptrauth_save_key(ctxt->sys_regs, APDB); - __ptrauth_save_key(ctxt->sys_regs, APGA); - } else { + else kvm_inject_undefined(vcpu); - } } /* --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp-init.S +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp-init.S @@ -136,11 +136,15 @@ 1: cmp x0, #HVC_RESET_VECTORS b.ne 1f -reset: + /* - * Reset kvm back to the hyp stub. Do not clobber x0-x4 in - * case we coming via HVC_SOFT_RESTART. + * Set the HVC_RESET_VECTORS return code before entering the common + * path so that we do not clobber x0-x2 in case we are coming via + * HVC_SOFT_RESTART. */ + mov x0, xzr +reset: + /* Reset kvm back to the hyp stub. */ mrs x5, sctlr_el2 ldr x6, =SCTLR_ELx_FLAGS bic x5, x5, x6 // Clear SCTL_M and etc @@ -151,7 +155,6 @@ /* Install stub vectors */ adr_l x5, __hyp_stub_vectors msr vbar_el2, x5 - mov x0, xzr eret 1: /* Bad stub call */ --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp/debug-sr.c +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp/debug-sr.c @@ -168,6 +168,21 @@ write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1); } +void __hyp_text __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) +{ + /* + * Non-VHE: Disable and flush SPE data generation + * VHE: The vcpu can run, but it can't hide. + */ + __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1); + +} + +void __hyp_text __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) +{ + __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1); +} + void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *host_ctxt; @@ -175,13 +190,6 @@ struct kvm_guest_debug_arch *host_dbg; struct kvm_guest_debug_arch *guest_dbg; - /* - * Non-VHE: Disable and flush SPE data generation - * VHE: The vcpu can run, but it can't hide. - */ - if (!has_vhe()) - __debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1); - if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) return; @@ -201,8 +209,6 @@ struct kvm_guest_debug_arch *host_dbg; struct kvm_guest_debug_arch *guest_dbg; - if (!has_vhe()) - __debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1); if (!(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY)) return; --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp/entry.S +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp/entry.S @@ -173,20 +173,23 @@ // This is our single instruction exception window. A pending // SError is guaranteed to occur at the earliest when we unmask // it, and at the latest just after the ISB. - .global abort_guest_exit_start abort_guest_exit_start: isb - .global abort_guest_exit_end abort_guest_exit_end: msr daifset, #4 // Mask aborts + ret - // If the exception took place, restore the EL1 exception - // context so that we can report some information. - // Merge the exception code with the SError pending bit. - tbz x0, #ARM_EXIT_WITH_SERROR_BIT, 1f + _kvm_extable abort_guest_exit_start, 9997f + _kvm_extable abort_guest_exit_end, 9997f +9997: + msr daifset, #4 // Mask aborts + mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) + + // restore the EL1 exception context so that we can report some + // information. Merge the exception code with the SError pending bit. msr elr_el2, x2 msr esr_el2, x3 msr spsr_el2, x4 --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp/hyp-entry.S +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp/hyp-entry.S @@ -15,6 +15,30 @@ #include #include +.macro save_caller_saved_regs_vect + /* x0 and x1 were saved in the vector entry */ + stp x2, x3, [sp, #-16]! + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + stp x8, x9, [sp, #-16]! + stp x10, x11, [sp, #-16]! + stp x12, x13, [sp, #-16]! + stp x14, x15, [sp, #-16]! + stp x16, x17, [sp, #-16]! +.endm + +.macro restore_caller_saved_regs_vect + ldp x16, x17, [sp], #16 + ldp x14, x15, [sp], #16 + ldp x12, x13, [sp], #16 + ldp x10, x11, [sp], #16 + ldp x8, x9, [sp], #16 + ldp x6, x7, [sp], #16 + ldp x4, x5, [sp], #16 + ldp x2, x3, [sp], #16 + ldp x0, x1, [sp], #16 +.endm + .text .pushsection .hyp.text, "ax" @@ -89,6 +113,10 @@ /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */ eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \ ARM_SMCCC_ARCH_WORKAROUND_2) + cbz w1, wa_epilogue + + eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_2 ^ \ + ARM_SMCCC_ARCH_WORKAROUND_3) cbnz w1, el1_trap #ifdef CONFIG_ARM64_SSBD @@ -142,13 +170,19 @@ b __guest_exit el2_sync: - /* Check for illegal exception return, otherwise panic */ + /* Check for illegal exception return */ mrs x0, spsr_el2 + tbnz x0, #20, 1f - /* if this was something else, then panic! */ - tst x0, #PSR_IL_BIT - b.eq __hyp_panic + save_caller_saved_regs_vect + stp x29, x30, [sp, #-16]! + bl kvm_unexpected_el2_exception + ldp x29, x30, [sp], #16 + restore_caller_saved_regs_vect + + eret +1: /* Let's attempt a recovery from the illegal exception return */ get_vcpu_ptr x1, x0 mov x0, #ARM_EXCEPTION_IL @@ -156,27 +190,14 @@ el2_error: - ldp x0, x1, [sp], #16 + save_caller_saved_regs_vect + stp x29, x30, [sp, #-16]! + + bl kvm_unexpected_el2_exception + + ldp x29, x30, [sp], #16 + restore_caller_saved_regs_vect - /* - * Only two possibilities: - * 1) Either we come from the exit path, having just unmasked - * PSTATE.A: change the return code to an EL2 fault, and - * carry on, as we're already in a sane state to handle it. - * 2) Or we come from anywhere else, and that's a bug: we panic. - * - * For (1), x0 contains the original return code and x1 doesn't - * contain anything meaningful at that stage. We can reuse them - * as temp registers. - * For (2), who cares? - */ - mrs x0, elr_el2 - adr x1, abort_guest_exit_start - cmp x0, x1 - adr x1, abort_guest_exit_end - ccmp x0, x1, #4, ne - b.ne __hyp_panic - mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT) eret sb @@ -330,4 +351,64 @@ ldp x0, x1, [sp, #(8 * 2)] add sp, sp, #(8 * 4) ENTRY(__smccc_workaround_1_smc_end) + +ENTRY(__smccc_workaround_3_smc_start) + esb + sub sp, sp, #(8 * 4) + stp x2, x3, [sp, #(8 * 0)] + stp x0, x1, [sp, #(8 * 2)] + mov w0, #ARM_SMCCC_ARCH_WORKAROUND_3 + smc #0 + ldp x2, x3, [sp, #(8 * 0)] + ldp x0, x1, [sp, #(8 * 2)] + add sp, sp, #(8 * 4) +ENTRY(__smccc_workaround_3_smc_end) + +ENTRY(__spectre_bhb_loop_k8_start) + esb + sub sp, sp, #(8 * 2) + stp x0, x1, [sp, #(8 * 0)] + mov x0, #8 +2: b . + 4 + subs x0, x0, #1 + b.ne 2b + dsb nsh + isb + ldp x0, x1, [sp, #(8 * 0)] + add sp, sp, #(8 * 2) +ENTRY(__spectre_bhb_loop_k8_end) + +ENTRY(__spectre_bhb_loop_k24_start) + esb + sub sp, sp, #(8 * 2) + stp x0, x1, [sp, #(8 * 0)] + mov x0, #8 +2: b . + 4 + subs x0, x0, #1 + b.ne 2b + dsb nsh + isb + ldp x0, x1, [sp, #(8 * 0)] + add sp, sp, #(8 * 2) +ENTRY(__spectre_bhb_loop_k24_end) + +ENTRY(__spectre_bhb_loop_k32_start) + esb + sub sp, sp, #(8 * 2) + stp x0, x1, [sp, #(8 * 0)] + mov x0, #8 +2: b . + 4 + subs x0, x0, #1 + b.ne 2b + dsb nsh + isb + ldp x0, x1, [sp, #(8 * 0)] + add sp, sp, #(8 * 2) +ENTRY(__spectre_bhb_loop_k32_end) + +ENTRY(__spectre_bhb_clearbhb_start) + esb + clearbhb + isb +ENTRY(__spectre_bhb_clearbhb_end) #endif --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp/switch.c +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp/switch.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -24,11 +25,23 @@ #include #include #include +#include + +extern struct exception_table_entry __start___kvm_ex_table; +extern struct exception_table_entry __stop___kvm_ex_table; /* Check whether the FP regs were dirtied while in the host-side run loop: */ static bool __hyp_text update_fp_enabled(struct kvm_vcpu *vcpu) { - if (vcpu->arch.host_thread_info->flags & _TIF_FOREIGN_FPSTATE) + /* + * When the system doesn't support FP/SIMD, we cannot rely on + * the _TIF_FOREIGN_FPSTATE flag. However, we always inject an + * abort on the very first access to FP and thus we should never + * see KVM_ARM64_FP_ENABLED. For added safety, make sure we always + * trap the accesses. + */ + if (!system_supports_fpsimd() || + vcpu->arch.host_thread_info->flags & _TIF_FOREIGN_FPSTATE) vcpu->arch.flags &= ~(KVM_ARM64_FP_ENABLED | KVM_ARM64_FP_HOST); @@ -140,7 +153,7 @@ static void deactivate_traps_vhe(void) { - extern char vectors[]; /* kernel exception vectors */ + const char *host_vectors = vectors; write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2); /* @@ -151,7 +164,10 @@ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522)); write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); - write_sysreg(vectors, vbar_el1); + + if (!arm64_kernel_unmapped_at_el0()) + host_vectors = __this_cpu_read(this_cpu_vector); + write_sysreg(host_vectors, vbar_el1); } NOKPROBE_SYMBOL(deactivate_traps_vhe); @@ -249,10 +265,10 @@ * saved the guest context yet, and we may return early... */ par = read_sysreg(par_el1); - asm volatile("at s1e1r, %0" : : "r" (far)); - isb(); - - tmp = read_sysreg(par_el1); + if (!__kvm_at("s1e1r", far)) + tmp = read_sysreg(par_el1); + else + tmp = SYS_PAR_EL1_F; /* back to the guest */ write_sysreg(par, par_el1); if (unlikely(tmp & SYS_PAR_EL1_F)) @@ -484,7 +500,7 @@ kvm_vcpu_trap_get_fault_type(vcpu) == FSC_FAULT && kvm_vcpu_dabt_isvalid(vcpu) && !kvm_vcpu_dabt_isextabt(vcpu) && - !kvm_vcpu_dabt_iss1tw(vcpu); + !kvm_vcpu_abt_iss1tw(vcpu); if (valid) { int ret = __vgic_v2_perform_cpuif_access(vcpu); @@ -670,6 +686,15 @@ __sysreg_save_state_nvhe(host_ctxt); + /* + * We must flush and disable the SPE buffer for nVHE, as + * the translation regime(EL1&0) is going to be loaded with + * that of the guest. And we must do this before we change the + * translation regime to EL2 (via MDCR_EL2_EPB == 0) and + * before we load guest Stage1. + */ + __debug_save_host_buffers_nvhe(vcpu); + __activate_vm(kern_hyp_va(vcpu->kvm)); __activate_traps(vcpu); @@ -708,11 +733,13 @@ if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) __fpsimd_save_fpexc32(vcpu); + __debug_switch_to_host(vcpu); + /* * This must come after restoring the host sysregs, since a non-VHE * system may enable SPE here and make use of the TTBRs. */ - __debug_switch_to_host(vcpu); + __debug_restore_host_buffers_nvhe(vcpu); if (pmu_switch_needed) __pmu_switch_to_host(host_ctxt); @@ -746,7 +773,7 @@ * making sure it is a kernel address and not a PC-relative * reference. */ - asm volatile("ldr %0, =__hyp_panic_string" : "=r" (str_va)); + asm volatile("ldr %0, =%1" : "=r" (str_va) : "S" (__hyp_panic_string)); __hyp_do_panic(str_va, spsr, elr, @@ -783,3 +810,30 @@ unreachable(); } + +asmlinkage void __hyp_text kvm_unexpected_el2_exception(void) +{ + unsigned long addr, fixup; + struct kvm_cpu_context *host_ctxt; + struct exception_table_entry *entry, *end; + unsigned long elr_el2 = read_sysreg(elr_el2); + + entry = hyp_symbol_addr(__start___kvm_ex_table); + end = hyp_symbol_addr(__stop___kvm_ex_table); + host_ctxt = &__hyp_this_cpu_ptr(kvm_host_data)->host_ctxt; + + while (entry < end) { + addr = (unsigned long)&entry->insn + entry->insn; + fixup = (unsigned long)&entry->fixup + entry->fixup; + + if (addr != elr_el2) { + entry++; + continue; + } + + write_sysreg(fixup, elr_el2); + return; + } + + hyp_panic(host_ctxt); +} --- linux-oracle-5.4.0.orig/arch/arm64/kvm/hyp/tlb.c +++ linux-oracle-5.4.0/arch/arm64/kvm/hyp/tlb.c @@ -182,7 +182,7 @@ __tlb_switch_to_host(kvm, &cxt); } -void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) +void __hyp_text __kvm_flush_cpu_context(struct kvm_vcpu *vcpu) { struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); struct tlb_inv_context cxt; @@ -191,6 +191,7 @@ __tlb_switch_to_guest(kvm, &cxt); __tlbi(vmalle1); + asm volatile("ic iallu"); dsb(nsh); isb(); --- linux-oracle-5.4.0.orig/arch/arm64/kvm/inject_fault.c +++ linux-oracle-5.4.0/arch/arm64/kvm/inject_fault.c @@ -14,9 +14,6 @@ #include #include -#define PSTATE_FAULT_BITS_64 (PSR_MODE_EL1h | PSR_A_BIT | PSR_F_BIT | \ - PSR_I_BIT | PSR_D_BIT) - #define CURRENT_EL_SP_EL0_VECTOR 0x0 #define CURRENT_EL_SP_ELx_VECTOR 0x200 #define LOWER_EL_AArch64_VECTOR 0x400 @@ -50,6 +47,69 @@ return vcpu_read_sys_reg(vcpu, VBAR_EL1) + exc_offset + type; } +/* + * When an exception is taken, most PSTATE fields are left unchanged in the + * handler. However, some are explicitly overridden (e.g. M[4:0]). Luckily all + * of the inherited bits have the same position in the AArch64/AArch32 SPSR_ELx + * layouts, so we don't need to shuffle these for exceptions from AArch32 EL0. + * + * For the SPSR_ELx layout for AArch64, see ARM DDI 0487E.a page C5-429. + * For the SPSR_ELx layout for AArch32, see ARM DDI 0487E.a page C5-426. + * + * Here we manipulate the fields in order of the AArch64 SPSR_ELx layout, from + * MSB to LSB. + */ +static unsigned long get_except64_pstate(struct kvm_vcpu *vcpu) +{ + unsigned long sctlr = vcpu_read_sys_reg(vcpu, SCTLR_EL1); + unsigned long old, new; + + old = *vcpu_cpsr(vcpu); + new = 0; + + new |= (old & PSR_N_BIT); + new |= (old & PSR_Z_BIT); + new |= (old & PSR_C_BIT); + new |= (old & PSR_V_BIT); + + // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests) + + new |= (old & PSR_DIT_BIT); + + // PSTATE.UAO is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D5-2579. + + // PSTATE.PAN is unchanged unless SCTLR_ELx.SPAN == 0b0 + // SCTLR_ELx.SPAN is RES1 when ARMv8.1-PAN is not implemented + // See ARM DDI 0487E.a, page D5-2578. + new |= (old & PSR_PAN_BIT); + if (!(sctlr & SCTLR_EL1_SPAN)) + new |= PSR_PAN_BIT; + + // PSTATE.SS is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D2-2452. + + // PSTATE.IL is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, page D1-2306. + + // PSTATE.SSBS is set to SCTLR_ELx.DSSBS upon any exception to AArch64 + // See ARM DDI 0487E.a, page D13-3258 + if (sctlr & SCTLR_ELx_DSSBS) + new |= PSR_SSBS_BIT; + + // PSTATE.BTYPE is set to zero upon any exception to AArch64 + // See ARM DDI 0487E.a, pages D1-2293 to D1-2294. + + new |= PSR_D_BIT; + new |= PSR_A_BIT; + new |= PSR_I_BIT; + new |= PSR_F_BIT; + + new |= PSR_MODE_EL1h; + + return new; +} + static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr) { unsigned long cpsr = *vcpu_cpsr(vcpu); @@ -59,7 +119,7 @@ vcpu_write_elr_el1(vcpu, *vcpu_pc(vcpu)); *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); - *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; + *vcpu_cpsr(vcpu) = get_except64_pstate(vcpu); vcpu_write_spsr(vcpu, cpsr); vcpu_write_sys_reg(vcpu, addr, FAR_EL1); @@ -94,7 +154,7 @@ vcpu_write_elr_el1(vcpu, *vcpu_pc(vcpu)); *vcpu_pc(vcpu) = get_except_vector(vcpu, except_type_sync); - *vcpu_cpsr(vcpu) = PSTATE_FAULT_BITS_64; + *vcpu_cpsr(vcpu) = get_except64_pstate(vcpu); vcpu_write_spsr(vcpu, cpsr); /* --- linux-oracle-5.4.0.orig/arch/arm64/kvm/reset.c +++ linux-oracle-5.4.0/arch/arm64/kvm/reset.c @@ -258,7 +258,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { const struct kvm_regs *cpu_reset; - int ret = -EINVAL; + int ret; bool loaded; /* Reset PMU outside of the non-preemptible section */ @@ -281,15 +281,19 @@ if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) || test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features)) { - if (kvm_vcpu_enable_ptrauth(vcpu)) + if (kvm_vcpu_enable_ptrauth(vcpu)) { + ret = -EINVAL; goto out; + } } switch (vcpu->arch.target) { default: if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { - if (!cpu_has_32bit_el1()) + if (!cpu_has_32bit_el1()) { + ret = -EINVAL; goto out; + } cpu_reset = &default_regs_reset32; } else { cpu_reset = &default_regs_reset; @@ -374,10 +378,10 @@ pr_info("kvm: Limiting the IPA size due to kernel %s Address limit\n", (va_max < pa_max) ? "Virtual" : "Physical"); - WARN(ipa_max < KVM_PHYS_SHIFT, - "KVM IPA limit (%d bit) is smaller than default size\n", ipa_max); kvm_ipa_limit = ipa_max; - kvm_info("IPA Size Limit: %dbits\n", kvm_ipa_limit); + kvm_info("IPA Size Limit: %d bits%s\n", kvm_ipa_limit, + ((kvm_ipa_limit < KVM_PHYS_SHIFT) ? + " (Reduced IPA size, limited VM/VMM compatibility)" : "")); } /* @@ -404,6 +408,11 @@ return -EINVAL; } else { phys_shift = KVM_PHYS_SHIFT; + if (phys_shift > kvm_ipa_limit) { + pr_warn_once("%s using unsupported default IPA limit, upgrade your VMM\n", + current->comm); + return -EINVAL; + } } parange = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1) & 7; --- linux-oracle-5.4.0.orig/arch/arm64/kvm/sys_regs.c +++ linux-oracle-5.4.0/arch/arm64/kvm/sys_regs.c @@ -432,14 +432,14 @@ struct sys_reg_params *p, const struct sys_reg_desc *rd) { - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; + u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; if (p->is_write) reg_to_dbg(vcpu, p, dbg_reg); else dbg_to_reg(vcpu, p, dbg_reg); - trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); + trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); return true; } @@ -447,7 +447,7 @@ static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -457,7 +457,7 @@ static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm]; if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -467,21 +467,21 @@ static void reset_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { - vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg] = rd->val; + vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val; } static bool trap_bcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *rd) { - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; + u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; if (p->is_write) reg_to_dbg(vcpu, p, dbg_reg); else dbg_to_reg(vcpu, p, dbg_reg); - trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); + trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); return true; } @@ -489,7 +489,7 @@ static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -500,7 +500,7 @@ static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm]; if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -510,22 +510,22 @@ static void reset_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { - vcpu->arch.vcpu_debug_state.dbg_bcr[rd->reg] = rd->val; + vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val; } static bool trap_wvr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *rd) { - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; + u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; if (p->is_write) reg_to_dbg(vcpu, p, dbg_reg); else dbg_to_reg(vcpu, p, dbg_reg); - trace_trap_reg(__func__, rd->reg, p->is_write, - vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]); + trace_trap_reg(__func__, rd->CRm, p->is_write, + vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]); return true; } @@ -533,7 +533,7 @@ static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -543,7 +543,7 @@ static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm]; if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -553,21 +553,21 @@ static void reset_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { - vcpu->arch.vcpu_debug_state.dbg_wvr[rd->reg] = rd->val; + vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val; } static bool trap_wcr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *rd) { - u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; + u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; if (p->is_write) reg_to_dbg(vcpu, p, dbg_reg); else dbg_to_reg(vcpu, p, dbg_reg); - trace_trap_reg(__func__, rd->reg, p->is_write, *dbg_reg); + trace_trap_reg(__func__, rd->CRm, p->is_write, *dbg_reg); return true; } @@ -575,7 +575,7 @@ static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; if (copy_from_user(r, uaddr, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -585,7 +585,7 @@ static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd, const struct kvm_one_reg *reg, void __user *uaddr) { - __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg]; + __u64 *r = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm]; if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0) return -EFAULT; @@ -595,7 +595,7 @@ static void reset_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd) { - vcpu->arch.vcpu_debug_state.dbg_wcr[rd->reg] = rd->val; + vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val; } static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) @@ -625,6 +625,10 @@ { u64 pmcr, val; + /* No PMU available, PMCR_EL0 may UNDEF... */ + if (!kvm_arm_support_pmu_v3()) + return; + pmcr = read_sysreg(pmcr_el0); /* * Writable bits of PMCR_EL0 (ARMV8_PMU_PMCR_MASK) are reset to UNKNOWN @@ -1085,6 +1089,16 @@ (0xfUL << ID_AA64ISAR1_API_SHIFT) | (0xfUL << ID_AA64ISAR1_GPA_SHIFT) | (0xfUL << ID_AA64ISAR1_GPI_SHIFT)); + } else if (id == SYS_ID_AA64DFR0_EL1) { + /* Limit guests to PMUv3 for ARMv8.1 */ + val = cpuid_feature_cap_perfmon_field(val, + ID_AA64DFR0_PMUVER_SHIFT, + ID_AA64DFR0_PMUVER_8_1); + } else if (id == SYS_ID_DFR0_EL1) { + /* Limit guests to PMUv3 for ARMv8.1 */ + val = cpuid_feature_cap_perfmon_field(val, + ID_DFR0_PERFMON_SHIFT, + ID_DFR0_PERFMON_8_1); } return val; @@ -1132,16 +1146,6 @@ return REG_HIDDEN_USER | REG_HIDDEN_GUEST; } -/* Visibility overrides for SVE-specific ID registers */ -static unsigned int sve_id_visibility(const struct kvm_vcpu *vcpu, - const struct sys_reg_desc *rd) -{ - if (vcpu_has_sve(vcpu)) - return 0; - - return REG_HIDDEN_USER; -} - /* Generate the emulated ID_AA64ZFR0_EL1 value exposed to the guest */ static u64 guest_id_aa64zfr0_el1(const struct kvm_vcpu *vcpu) { @@ -1168,9 +1172,6 @@ { u64 val; - if (WARN_ON(!vcpu_has_sve(vcpu))) - return -ENOENT; - val = guest_id_aa64zfr0_el1(vcpu); return reg_to_user(uaddr, &val, reg->id); } @@ -1183,9 +1184,6 @@ int err; u64 val; - if (WARN_ON(!vcpu_has_sve(vcpu))) - return -ENOENT; - err = reg_from_user(&val, uaddr, id); if (err) return err; @@ -1280,10 +1278,16 @@ static bool access_csselr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) { + int reg = r->reg; + + /* See the 32bit mapping in kvm_host.h */ + if (p->is_aarch32) + reg = r->reg / 2; + if (p->is_write) - vcpu_write_sys_reg(vcpu, p->regval, r->reg); + vcpu_write_sys_reg(vcpu, p->regval, reg); else - p->regval = vcpu_read_sys_reg(vcpu, r->reg); + p->regval = vcpu_read_sys_reg(vcpu, reg); return true; } @@ -1442,7 +1446,7 @@ ID_SANITISED(ID_AA64PFR1_EL1), ID_UNALLOCATED(4,2), ID_UNALLOCATED(4,3), - { SYS_DESC(SYS_ID_AA64ZFR0_EL1), access_id_aa64zfr0_el1, .get_user = get_id_aa64zfr0_el1, .set_user = set_id_aa64zfr0_el1, .visibility = sve_id_visibility }, + { SYS_DESC(SYS_ID_AA64ZFR0_EL1), access_id_aa64zfr0_el1, .get_user = get_id_aa64zfr0_el1, .set_user = set_id_aa64zfr0_el1, }, ID_UNALLOCATED(4,5), ID_UNALLOCATED(4,6), ID_UNALLOCATED(4,7), @@ -1460,7 +1464,7 @@ /* CRm=6 */ ID_SANITISED(ID_AA64ISAR0_EL1), ID_SANITISED(ID_AA64ISAR1_EL1), - ID_UNALLOCATED(6,2), + ID_SANITISED(ID_AA64ISAR2_EL1), ID_UNALLOCATED(6,3), ID_UNALLOCATED(6,4), ID_UNALLOCATED(6,5), @@ -1740,9 +1744,9 @@ { Op1( 0), CRn( 0), CRm( 1), Op2( 0), trap_raz_wi }, DBG_BCR_BVR_WCR_WVR(1), /* DBGDCCINT */ - { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32 }, + { Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32, NULL, cp14_DBGDCCINT }, /* DBGDSCRext */ - { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32 }, + { Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32, NULL, cp14_DBGDSCRext }, DBG_BCR_BVR_WCR_WVR(2), /* DBGDTR[RT]Xint */ { Op1( 0), CRn( 0), CRm( 3), Op2( 0), trap_raz_wi }, @@ -1757,7 +1761,7 @@ { Op1( 0), CRn( 0), CRm( 6), Op2( 2), trap_raz_wi }, DBG_BCR_BVR_WCR_WVR(6), /* DBGVCR */ - { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32 }, + { Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32, NULL, cp14_DBGVCR }, DBG_BCR_BVR_WCR_WVR(7), DBG_BCR_BVR_WCR_WVR(8), DBG_BCR_BVR_WCR_WVR(9), @@ -1847,6 +1851,7 @@ { Op1( 0), CRn( 2), CRm( 0), Op2( 0), access_vm_reg, NULL, c2_TTBR0 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 1), access_vm_reg, NULL, c2_TTBR1 }, { Op1( 0), CRn( 2), CRm( 0), Op2( 2), access_vm_reg, NULL, c2_TTBCR }, + { Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, c2_TTBCR2 }, { Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, c3_DACR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, c5_DFSR }, { Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, c5_IFSR }, @@ -2360,8 +2365,11 @@ if ((id & KVM_REG_ARM_COPROC_MASK) != KVM_REG_ARM64_SYSREG) return NULL; + if (!index_to_params(id, ¶ms)) + return NULL; + table = get_target_table(vcpu->arch.target, true, &num); - r = find_reg_by_id(id, ¶ms, table, num); + r = find_reg(¶ms, table, num); if (!r) r = find_reg(¶ms, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); --- linux-oracle-5.4.0.orig/arch/arm64/lib/clear_page.S +++ linux-oracle-5.4.0/arch/arm64/lib/clear_page.S @@ -14,7 +14,7 @@ * Parameters: * x0 - dest */ -ENTRY(clear_page) +SYM_FUNC_START(clear_page) mrs x1, dczid_el0 and w1, w1, #0xf mov x2, #4 @@ -25,5 +25,5 @@ tst x0, #(PAGE_SIZE - 1) b.ne 1b ret -ENDPROC(clear_page) +SYM_FUNC_END(clear_page) EXPORT_SYMBOL(clear_page) --- linux-oracle-5.4.0.orig/arch/arm64/lib/clear_user.S +++ linux-oracle-5.4.0/arch/arm64/lib/clear_user.S @@ -19,7 +19,7 @@ * * Alignment fixed up by hardware. */ -ENTRY(__arch_clear_user) +SYM_FUNC_START(__arch_clear_user) mov x2, x1 // save the size for fixup return subs x1, x1, #8 b.mi 2f @@ -40,7 +40,7 @@ uao_user_alternative 9f, strb, sttrb, wzr, x0, 0 5: mov x0, #0 ret -ENDPROC(__arch_clear_user) +SYM_FUNC_END(__arch_clear_user) EXPORT_SYMBOL(__arch_clear_user) .section .fixup,"ax" --- linux-oracle-5.4.0.orig/arch/arm64/lib/copy_from_user.S +++ linux-oracle-5.4.0/arch/arm64/lib/copy_from_user.S @@ -53,12 +53,12 @@ .endm end .req x5 -ENTRY(__arch_copy_from_user) +SYM_FUNC_START(__arch_copy_from_user) add end, x0, x2 #include "copy_template.S" mov x0, #0 // Nothing to copy ret -ENDPROC(__arch_copy_from_user) +SYM_FUNC_END(__arch_copy_from_user) EXPORT_SYMBOL(__arch_copy_from_user) .section .fixup,"ax" --- linux-oracle-5.4.0.orig/arch/arm64/lib/copy_in_user.S +++ linux-oracle-5.4.0/arch/arm64/lib/copy_in_user.S @@ -55,12 +55,12 @@ end .req x5 -ENTRY(__arch_copy_in_user) +SYM_FUNC_START(__arch_copy_in_user) add end, x0, x2 #include "copy_template.S" mov x0, #0 ret -ENDPROC(__arch_copy_in_user) +SYM_FUNC_END(__arch_copy_in_user) EXPORT_SYMBOL(__arch_copy_in_user) .section .fixup,"ax" --- linux-oracle-5.4.0.orig/arch/arm64/lib/copy_page.S +++ linux-oracle-5.4.0/arch/arm64/lib/copy_page.S @@ -17,7 +17,7 @@ * x0 - dest * x1 - src */ -ENTRY(copy_page) +SYM_FUNC_START(copy_page) alternative_if ARM64_HAS_NO_HW_PREFETCH // Prefetch three cache lines ahead. prfm pldl1strm, [x1, #128] @@ -75,5 +75,5 @@ stnp x16, x17, [x0, #112] ret -ENDPROC(copy_page) +SYM_FUNC_END(copy_page) EXPORT_SYMBOL(copy_page) --- linux-oracle-5.4.0.orig/arch/arm64/lib/copy_to_user.S +++ linux-oracle-5.4.0/arch/arm64/lib/copy_to_user.S @@ -52,12 +52,12 @@ .endm end .req x5 -ENTRY(__arch_copy_to_user) +SYM_FUNC_START(__arch_copy_to_user) add end, x0, x2 #include "copy_template.S" mov x0, #0 ret -ENDPROC(__arch_copy_to_user) +SYM_FUNC_END(__arch_copy_to_user) EXPORT_SYMBOL(__arch_copy_to_user) .section .fixup,"ax" --- linux-oracle-5.4.0.orig/arch/arm64/lib/crc32.S +++ linux-oracle-5.4.0/arch/arm64/lib/crc32.S @@ -85,17 +85,17 @@ .endm .align 5 -ENTRY(crc32_le) +SYM_FUNC_START(crc32_le) alternative_if_not ARM64_HAS_CRC32 b crc32_le_base alternative_else_nop_endif __crc32 -ENDPROC(crc32_le) +SYM_FUNC_END(crc32_le) .align 5 -ENTRY(__crc32c_le) +SYM_FUNC_START(__crc32c_le) alternative_if_not ARM64_HAS_CRC32 b __crc32c_le_base alternative_else_nop_endif __crc32 c -ENDPROC(__crc32c_le) +SYM_FUNC_END(__crc32c_le) --- linux-oracle-5.4.0.orig/arch/arm64/lib/memchr.S +++ linux-oracle-5.4.0/arch/arm64/lib/memchr.S @@ -19,7 +19,7 @@ * Returns: * x0 - address of first occurrence of 'c' or 0 */ -WEAK(memchr) +SYM_FUNC_START_WEAK_PI(memchr) and w1, w1, #0xff 1: subs x2, x2, #1 b.mi 2f @@ -30,5 +30,5 @@ ret 2: mov x0, #0 ret -ENDPIPROC(memchr) +SYM_FUNC_END_PI(memchr) EXPORT_SYMBOL_NOKASAN(memchr) --- linux-oracle-5.4.0.orig/arch/arm64/lib/memcmp.S +++ linux-oracle-5.4.0/arch/arm64/lib/memcmp.S @@ -46,7 +46,7 @@ limit_wd .req x12 mask .req x13 -WEAK(memcmp) +SYM_FUNC_START_WEAK_PI(memcmp) cbz limit, .Lret0 eor tmp1, src1, src2 tst tmp1, #7 @@ -243,5 +243,5 @@ .Lret0: mov result, #0 ret -ENDPIPROC(memcmp) +SYM_FUNC_END_PI(memcmp) EXPORT_SYMBOL_NOKASAN(memcmp) --- linux-oracle-5.4.0.orig/arch/arm64/lib/memcpy.S +++ linux-oracle-5.4.0/arch/arm64/lib/memcpy.S @@ -56,12 +56,11 @@ stp \ptr, \regB, [\regC], \val .endm - .weak memcpy -ENTRY(__memcpy) -ENTRY(memcpy) +SYM_FUNC_START_ALIAS(__memcpy) +SYM_FUNC_START_WEAK_PI(memcpy) #include "copy_template.S" ret -ENDPIPROC(memcpy) +SYM_FUNC_END_PI(memcpy) EXPORT_SYMBOL(memcpy) -ENDPROC(__memcpy) +SYM_FUNC_END_ALIAS(__memcpy) EXPORT_SYMBOL(__memcpy) --- linux-oracle-5.4.0.orig/arch/arm64/lib/memmove.S +++ linux-oracle-5.4.0/arch/arm64/lib/memmove.S @@ -45,9 +45,8 @@ D_l .req x13 D_h .req x14 - .weak memmove -ENTRY(__memmove) -ENTRY(memmove) +SYM_FUNC_START_ALIAS(__memmove) +SYM_FUNC_START_WEAK_PI(memmove) cmp dstin, src b.lo __memcpy add tmp1, src, count @@ -184,7 +183,7 @@ tst count, #0x3f b.ne .Ltail63 ret -ENDPIPROC(memmove) +SYM_FUNC_END_PI(memmove) EXPORT_SYMBOL(memmove) -ENDPROC(__memmove) +SYM_FUNC_END_ALIAS(__memmove) EXPORT_SYMBOL(__memmove) --- linux-oracle-5.4.0.orig/arch/arm64/lib/memset.S +++ linux-oracle-5.4.0/arch/arm64/lib/memset.S @@ -42,9 +42,8 @@ tmp3w .req w9 tmp3 .req x9 - .weak memset -ENTRY(__memset) -ENTRY(memset) +SYM_FUNC_START_ALIAS(__memset) +SYM_FUNC_START_WEAK_PI(memset) mov dst, dstin /* Preserve return value. */ and A_lw, val, #255 orr A_lw, A_lw, A_lw, lsl #8 @@ -203,7 +202,7 @@ ands count, count, zva_bits_x b.ne .Ltail_maybe_long ret -ENDPIPROC(memset) +SYM_FUNC_END_PI(memset) EXPORT_SYMBOL(memset) -ENDPROC(__memset) +SYM_FUNC_END_ALIAS(__memset) EXPORT_SYMBOL(__memset) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strchr.S +++ linux-oracle-5.4.0/arch/arm64/lib/strchr.S @@ -18,7 +18,7 @@ * Returns: * x0 - address of first occurrence of 'c' or 0 */ -WEAK(strchr) +SYM_FUNC_START_WEAK(strchr) and w1, w1, #0xff 1: ldrb w2, [x0], #1 cmp w2, w1 @@ -28,5 +28,5 @@ cmp w2, w1 csel x0, x0, xzr, eq ret -ENDPROC(strchr) +SYM_FUNC_END(strchr) EXPORT_SYMBOL_NOKASAN(strchr) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strcmp.S +++ linux-oracle-5.4.0/arch/arm64/lib/strcmp.S @@ -48,7 +48,7 @@ zeroones .req x10 pos .req x11 -WEAK(strcmp) +SYM_FUNC_START_WEAK_PI(strcmp) eor tmp1, src1, src2 mov zeroones, #REP8_01 tst tmp1, #7 @@ -219,5 +219,5 @@ lsr data1, data1, #56 sub result, data1, data2, lsr #56 ret -ENDPIPROC(strcmp) +SYM_FUNC_END_PI(strcmp) EXPORT_SYMBOL_NOKASAN(strcmp) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strlen.S +++ linux-oracle-5.4.0/arch/arm64/lib/strlen.S @@ -44,7 +44,7 @@ #define REP8_7f 0x7f7f7f7f7f7f7f7f #define REP8_80 0x8080808080808080 -WEAK(strlen) +SYM_FUNC_START_WEAK_PI(strlen) mov zeroones, #REP8_01 bic src, srcin, #15 ands tmp1, srcin, #15 @@ -111,5 +111,5 @@ csinv data1, data1, xzr, le csel data2, data2, data2a, le b .Lrealigned -ENDPIPROC(strlen) +SYM_FUNC_END_PI(strlen) EXPORT_SYMBOL_NOKASAN(strlen) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strncmp.S +++ linux-oracle-5.4.0/arch/arm64/lib/strncmp.S @@ -52,7 +52,7 @@ mask .req x14 endloop .req x15 -WEAK(strncmp) +SYM_FUNC_START_WEAK_PI(strncmp) cbz limit, .Lret0 eor tmp1, src1, src2 mov zeroones, #REP8_01 @@ -295,5 +295,5 @@ .Lret0: mov result, #0 ret -ENDPIPROC(strncmp) +SYM_FUNC_END_PI(strncmp) EXPORT_SYMBOL_NOKASAN(strncmp) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strnlen.S +++ linux-oracle-5.4.0/arch/arm64/lib/strnlen.S @@ -47,7 +47,7 @@ #define REP8_7f 0x7f7f7f7f7f7f7f7f #define REP8_80 0x8080808080808080 -WEAK(strnlen) +SYM_FUNC_START_WEAK_PI(strnlen) cbz limit, .Lhit_limit mov zeroones, #REP8_01 bic src, srcin, #15 @@ -156,5 +156,5 @@ .Lhit_limit: mov len, limit ret -ENDPIPROC(strnlen) +SYM_FUNC_END_PI(strnlen) EXPORT_SYMBOL_NOKASAN(strnlen) --- linux-oracle-5.4.0.orig/arch/arm64/lib/strrchr.S +++ linux-oracle-5.4.0/arch/arm64/lib/strrchr.S @@ -18,7 +18,7 @@ * Returns: * x0 - address of last occurrence of 'c' or 0 */ -WEAK(strrchr) +SYM_FUNC_START_WEAK_PI(strrchr) mov x3, #0 and w1, w1, #0xff 1: ldrb w2, [x0], #1 @@ -29,5 +29,5 @@ b 1b 2: mov x0, x3 ret -ENDPIPROC(strrchr) +SYM_FUNC_END_PI(strrchr) EXPORT_SYMBOL_NOKASAN(strrchr) --- linux-oracle-5.4.0.orig/arch/arm64/lib/tishift.S +++ linux-oracle-5.4.0/arch/arm64/lib/tishift.S @@ -7,7 +7,7 @@ #include -ENTRY(__ashlti3) +SYM_FUNC_START(__ashlti3) cbz x2, 1f mov x3, #64 sub x3, x3, x2 @@ -26,10 +26,10 @@ lsl x1, x0, x1 mov x0, x2 ret -ENDPROC(__ashlti3) +SYM_FUNC_END(__ashlti3) EXPORT_SYMBOL(__ashlti3) -ENTRY(__ashrti3) +SYM_FUNC_START(__ashrti3) cbz x2, 1f mov x3, #64 sub x3, x3, x2 @@ -48,10 +48,10 @@ asr x0, x1, x0 mov x1, x2 ret -ENDPROC(__ashrti3) +SYM_FUNC_END(__ashrti3) EXPORT_SYMBOL(__ashrti3) -ENTRY(__lshrti3) +SYM_FUNC_START(__lshrti3) cbz x2, 1f mov x3, #64 sub x3, x3, x2 @@ -70,5 +70,5 @@ lsr x0, x1, x0 mov x1, x2 ret -ENDPROC(__lshrti3) +SYM_FUNC_END(__lshrti3) EXPORT_SYMBOL(__lshrti3) --- linux-oracle-5.4.0.orig/arch/arm64/mm/cache.S +++ linux-oracle-5.4.0/arch/arm64/mm/cache.S @@ -228,8 +228,6 @@ * - dir - DMA direction */ ENTRY(__dma_map_area) - cmp w2, #DMA_FROM_DEVICE - b.eq __dma_inv_area b __dma_clean_area ENDPIPROC(__dma_map_area) --- linux-oracle-5.4.0.orig/arch/arm64/mm/dma-mapping.c +++ linux-oracle-5.4.0/arch/arm64/mm/dma-mapping.c @@ -13,14 +13,14 @@ #include -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_map_area(phys_to_virt(paddr), size, dir); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_unmap_area(phys_to_virt(paddr), size, dir); } --- linux-oracle-5.4.0.orig/arch/arm64/mm/fault.c +++ linux-oracle-5.4.0/arch/arm64/mm/fault.c @@ -296,7 +296,7 @@ show_pte(addr); die("Oops", regs, esr); bust_spinlocks(0); - do_exit(SIGKILL); + make_task_dead(SIGKILL); } static void __do_kernel_fault(unsigned long addr, unsigned int esr, @@ -403,8 +403,8 @@ } } -#define VM_FAULT_BADMAP 0x010000 -#define VM_FAULT_BADACCESS 0x020000 +#define VM_FAULT_BADMAP ((__force vm_fault_t)0x010000) +#define VM_FAULT_BADACCESS ((__force vm_fault_t)0x020000) static vm_fault_t __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int mm_flags, unsigned long vm_flags) @@ -454,7 +454,7 @@ const struct fault_info *inf; struct mm_struct *mm = current->mm; vm_fault_t fault, major = 0; - unsigned long vm_flags = VM_READ | VM_WRITE; + unsigned long vm_flags = VM_READ | VM_WRITE | VM_EXEC; unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; if (kprobe_page_fault(regs, esr)) @@ -654,11 +654,13 @@ inf = esr_to_fault_info(esr); - /* - * Return value ignored as we rely on signal merging. - * Future patches will make this more robust. - */ - apei_claim_sea(regs); + if (user_mode(regs) && apei_claim_sea(regs) == 0) { + /* + * APEI claimed this as a firmware-first notification. + * Some processing deferred to task_work before ret_to_user(). + */ + return 0; + } if (esr & ESR_ELx_FnV) siaddr = NULL; --- linux-oracle-5.4.0.orig/arch/arm64/mm/hugetlbpage.c +++ linux-oracle-5.4.0/arch/arm64/mm/hugetlbpage.c @@ -230,6 +230,8 @@ ptep = (pte_t *)pudp; } else if (sz == (CONT_PTE_SIZE)) { pmdp = pmd_alloc(mm, pudp, addr); + if (!pmdp) + return NULL; WARN_ON(addr & (sz - 1)); /* --- linux-oracle-5.4.0.orig/arch/arm64/mm/init.c +++ linux-oracle-5.4.0/arch/arm64/mm/init.c @@ -50,12 +50,6 @@ s64 memstart_addr __ro_after_init = -1; EXPORT_SYMBOL(memstart_addr); -s64 physvirt_offset __ro_after_init; -EXPORT_SYMBOL(physvirt_offset); - -struct page *vmemmap __ro_after_init; -EXPORT_SYMBOL(vmemmap); - phys_addr_t arm64_dma_phys_limit __ro_after_init; #ifdef CONFIG_KEXEC_CORE @@ -180,8 +174,6 @@ return min(offset + (1ULL << 32), memblock_end_of_DRAM()); } -#ifdef CONFIG_NUMA - static void __init zone_sizes_init(unsigned long min, unsigned long max) { unsigned long max_zone_pfns[MAX_NR_ZONES] = {0}; @@ -191,53 +183,9 @@ #endif max_zone_pfns[ZONE_NORMAL] = max; - free_area_init_nodes(max_zone_pfns); -} - -#else - -static void __init zone_sizes_init(unsigned long min, unsigned long max) -{ - struct memblock_region *reg; - unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; - unsigned long max_dma = min; - - memset(zone_size, 0, sizeof(zone_size)); - - /* 4GB maximum for 32-bit only capable devices */ -#ifdef CONFIG_ZONE_DMA32 - max_dma = PFN_DOWN(arm64_dma_phys_limit); - zone_size[ZONE_DMA32] = max_dma - min; -#endif - zone_size[ZONE_NORMAL] = max - max_dma; - - memcpy(zhole_size, zone_size, sizeof(zhole_size)); - - for_each_memblock(memory, reg) { - unsigned long start = memblock_region_memory_base_pfn(reg); - unsigned long end = memblock_region_memory_end_pfn(reg); - - if (start >= max) - continue; - -#ifdef CONFIG_ZONE_DMA32 - if (start < max_dma) { - unsigned long dma_end = min(end, max_dma); - zhole_size[ZONE_DMA32] -= dma_end - start; - } -#endif - if (end > max_dma) { - unsigned long normal_end = min(end, max); - unsigned long normal_start = max(start, max_dma); - zhole_size[ZONE_NORMAL] -= normal_end - normal_start; - } - } - - free_area_init_node(0, zone_size, min, zhole_size); + free_area_init(max_zone_pfns); } -#endif /* CONFIG_NUMA */ - int pfn_valid(unsigned long pfn) { phys_addr_t addr = pfn << PAGE_SHIFT; @@ -251,6 +199,18 @@ if (!valid_section(__nr_to_section(pfn_to_section_nr(pfn)))) return 0; + + /* + * ZONE_DEVICE memory does not have the memblock entries. + * memblock_is_map_memory() check for ZONE_DEVICE based + * addresses will always fail. Even the normal hotplugged + * memory will never have MEMBLOCK_NOMAP flag set in their + * memblock entries. Skip memblock search for all non early + * memory sections covering all of hotplug memory including + * both normal and ZONE_DEVICE based. + */ + if (!early_section(__pfn_to_section(pfn))) + return pfn_section_valid(__pfn_to_section(pfn), pfn); #endif return memblock_is_map_memory(addr); } @@ -321,20 +281,6 @@ memstart_addr = round_down(memblock_start_of_DRAM(), ARM64_MEMSTART_ALIGN); - physvirt_offset = PHYS_OFFSET - PAGE_OFFSET; - - vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)); - - /* - * If we are running with a 52-bit kernel VA config on a system that - * does not support it, we have to offset our vmemmap and physvirt_offset - * s.t. we avoid the 52-bit portion of the direct linear map - */ - if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) { - vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT; - physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48); - } - /* * Remove the memory that we will not be able to cover with the * linear mapping. Take care not to clip the kernel which may be @@ -350,6 +296,16 @@ } /* + * If we are running with a 52-bit kernel VA config on a system that + * does not support it, we have to place the available physical + * memory in the 48-bit addressable part of the linear region, i.e., + * we have to move it upward. Since memstart_addr represents the + * physical address of PAGE_OFFSET, we have to *subtract* from it. + */ + if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) + memstart_addr -= _PAGE_OFFSET(48) - _PAGE_OFFSET(52); + + /* * Apply the memory limit if it was set. Since the kernel may be loaded * high up in memory, add back the kernel region that must be accessible * via the linear mapping. --- linux-oracle-5.4.0.orig/arch/arm64/mm/ioremap.c +++ linux-oracle-5.4.0/arch/arm64/mm/ioremap.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -100,3 +101,11 @@ { early_ioremap_setup(); } + +bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, + unsigned long flags) +{ + unsigned long pfn = PHYS_PFN(offset); + + return memblock_is_map_memory(pfn); +} --- linux-oracle-5.4.0.orig/arch/arm64/mm/mmu.c +++ linux-oracle-5.4.0/arch/arm64/mm/mmu.c @@ -38,7 +38,7 @@ #define NO_BLOCK_MAPPINGS BIT(0) #define NO_CONT_MAPPINGS BIT(1) -u64 idmap_t0sz = TCR_T0SZ(VA_BITS); +u64 idmap_t0sz = TCR_T0SZ(VA_BITS_MIN); u64 idmap_ptrs_per_pgd = PTRS_PER_PGD; u64 __section(".mmuoff.data.write") vabits_actual; @@ -399,7 +399,7 @@ static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot) { - if ((virt >= PAGE_END) && (virt < VMALLOC_START)) { + if (virt < PAGE_OFFSET) { pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n", &phys, virt); return; @@ -426,7 +426,7 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot) { - if ((virt >= PAGE_END) && (virt < VMALLOC_START)) { + if (virt < PAGE_OFFSET) { pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n", &phys, virt); return; @@ -583,6 +583,8 @@ #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 static int __init map_entry_trampoline(void) { + int i; + pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC; phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start); @@ -591,11 +593,15 @@ /* Map only the text into the trampoline page table */ memset(tramp_pg_dir, 0, PGD_SIZE); - __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE, - prot, __pgd_pgtable_alloc, 0); + __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, + entry_tramp_text_size(), prot, + __pgd_pgtable_alloc, NO_BLOCK_MAPPINGS); /* Map both the text and data into the kernel page table */ - __set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot); + for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) + __set_fixmap(FIX_ENTRY_TRAMP_TEXT1 - i, + pa_start + i * PAGE_SIZE, prot); + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { extern char __entry_tramp_data_start[]; @@ -1069,7 +1075,6 @@ { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct zone *zone; /* * FIXME: Cleanup page tables (also in arch_add_memory() in case @@ -1078,7 +1083,6 @@ * unplug. ARCH_ENABLE_MEMORY_HOTREMOVE must not be * unlocked yet. */ - zone = page_zone(pfn_to_page(start_pfn)); - __remove_pages(zone, start_pfn, nr_pages, altmap); + __remove_pages(start_pfn, nr_pages, altmap); } #endif --- linux-oracle-5.4.0.orig/arch/arm64/mm/numa.c +++ linux-oracle-5.4.0/arch/arm64/mm/numa.c @@ -46,7 +46,11 @@ */ const struct cpumask *cpumask_of_node(int node) { - if (WARN_ON(node >= nr_node_ids)) + + if (node == NUMA_NO_NODE) + return cpu_all_mask; + + if (WARN_ON(node < 0 || node >= nr_node_ids)) return cpu_none_mask; if (WARN_ON(node_to_cpumask_map[node] == NULL)) @@ -350,13 +354,16 @@ struct memblock_region *mblk; /* Check that valid nid is set to memblks */ - for_each_memblock(memory, mblk) - if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) { + for_each_memblock(memory, mblk) { + int mblk_nid = memblock_get_region_node(mblk); + + if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) { pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n", - mblk->nid, mblk->base, + mblk_nid, mblk->base, mblk->base + mblk->size - 1); return -EINVAL; } + } /* Finally register nodes. */ for_each_node_mask(nid, numa_nodes_parsed) { --- linux-oracle-5.4.0.orig/arch/arm64/mm/physaddr.c +++ linux-oracle-5.4.0/arch/arm64/mm/physaddr.c @@ -9,7 +9,7 @@ phys_addr_t __virt_to_phys(unsigned long x) { - WARN(!__is_lm_address(x), + WARN(!__is_lm_address(__tag_reset(x)), "virt_to_phys used for non-linear address: %pK (%pS)\n", (void *)x, (void *)x); --- linux-oracle-5.4.0.orig/arch/arm64/mm/proc.S +++ linux-oracle-5.4.0/arch/arm64/mm/proc.S @@ -166,7 +166,7 @@ .pushsection ".idmap.text", "awx" .macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2 - adrp \tmp1, empty_zero_page + adrp \tmp1, reserved_pg_dir phys_to_ttbr \tmp2, \tmp1 offset_ttbr1 \tmp2, \tmp1 msr ttbr1_el1, \tmp2 --- linux-oracle-5.4.0.orig/arch/arm64/net/bpf_jit_comp.c +++ linux-oracle-5.4.0/arch/arm64/net/bpf_jit_comp.c @@ -141,14 +141,17 @@ } } -static inline int bpf2a64_offset(int bpf_to, int bpf_from, +static inline int bpf2a64_offset(int bpf_insn, int off, const struct jit_ctx *ctx) { - int to = ctx->offset[bpf_to]; - /* -1 to account for the Branch instruction */ - int from = ctx->offset[bpf_from] - 1; - - return to - from; + /* BPF JMP offset is relative to the next instruction */ + bpf_insn++; + /* + * Whereas arm64 branch instructions encode the offset + * from the branch itself, so we must subtract 1 from the + * instruction offset. + */ + return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1); } static void jit_fill_hole(void *area, unsigned int size) @@ -532,7 +535,7 @@ /* JUMP off */ case BPF_JMP | BPF_JA: - jmp_offset = bpf2a64_offset(i + off, i, ctx); + jmp_offset = bpf2a64_offset(i, off, ctx); check_imm26(jmp_offset); emit(A64_B(jmp_offset), ctx); break; @@ -559,7 +562,7 @@ case BPF_JMP32 | BPF_JSLE | BPF_X: emit(A64_CMP(is64, dst, src), ctx); emit_cond_jmp: - jmp_offset = bpf2a64_offset(i + off, i, ctx); + jmp_offset = bpf2a64_offset(i, off, ctx); check_imm19(jmp_offset); switch (BPF_OP(code)) { case BPF_JEQ: @@ -698,6 +701,19 @@ } break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + /* + * Nothing required here. + * + * In case of arm64, we rely on the firmware mitigation of + * Speculative Store Bypass as controlled via the ssbd kernel + * parameter. Whenever the mitigation is enabled, it works + * for all of the kernel code with no need to provide any + * additional instructions. + */ + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: @@ -780,10 +796,21 @@ const struct bpf_prog *prog = ctx->prog; int i; + /* + * - offset[0] offset of the end of prologue, + * start of the 1st instruction. + * - offset[1] - offset of the end of 1st instruction, + * start of the 2nd instruction + * [....] + * - offset[3] - offset of the end of 3rd instruction, + * start of 4th instruction + */ for (i = 0; i < prog->len; i++) { const struct bpf_insn *insn = &prog->insnsi[i]; int ret; + if (ctx->image == NULL) + ctx->offset[i] = ctx->idx; ret = build_insn(insn, ctx, extra_pass); if (ret > 0) { i++; @@ -791,11 +818,16 @@ ctx->offset[i] = ctx->idx; continue; } - if (ctx->image == NULL) - ctx->offset[i] = ctx->idx; if (ret) return ret; } + /* + * offset is allocated with prog->len + 1 so fill in + * the last element with the offset after the last + * instruction (end of program) + */ + if (ctx->image == NULL) + ctx->offset[i] = ctx->idx; return 0; } @@ -871,21 +903,24 @@ memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; - ctx.offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + ctx.offset = kcalloc(prog->len + 1, sizeof(int), GFP_KERNEL); if (ctx.offset == NULL) { prog = orig_prog; goto out_off; } - /* 1. Initial fake pass to compute ctx->idx. */ - - /* Fake pass to fill in ctx->offset. */ - if (build_body(&ctx, extra_pass)) { + /* + * 1. Initial fake pass to compute ctx->idx and ctx->offset. + * + * BPF line info needs ctx->offset[i] to be the offset of + * instruction[i] in jited image, so build prologue first. + */ + if (build_prologue(&ctx, was_classic)) { prog = orig_prog; goto out_off; } - if (build_prologue(&ctx, was_classic)) { + if (build_body(&ctx, extra_pass)) { prog = orig_prog; goto out_off; } @@ -938,6 +973,7 @@ bpf_jit_binary_free(header); prog->bpf_func = NULL; prog->jited = 0; + prog->jited_len = 0; goto out_off; } bpf_jit_binary_lock_ro(header); @@ -951,7 +987,12 @@ prog->jited_len = image_size; if (!prog->is_func || extra_pass) { - bpf_prog_fill_jited_linfo(prog, ctx.offset); + int i; + + /* offset[prog->len] is the size of program */ + for (i = 0; i <= prog->len; i++) + ctx.offset[i] *= AARCH64_INSN_SIZE; + bpf_prog_fill_jited_linfo(prog, ctx.offset + 1); out_off: kfree(ctx.offset); kfree(jit_data); @@ -964,6 +1005,11 @@ return prog; } +u64 bpf_jit_alloc_exec_limit(void) +{ + return BPF_JIT_REGION_SIZE; +} + void *bpf_jit_alloc_exec(unsigned long size) { return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START, --- linux-oracle-5.4.0.orig/arch/c6x/mm/dma-coherent.c +++ linux-oracle-5.4.0/arch/c6x/mm/dma-coherent.c @@ -140,7 +140,7 @@ sizeof(long)); } -static void c6x_dma_sync(struct device *dev, phys_addr_t paddr, size_t size, +static void c6x_dma_sync(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { BUG_ON(!valid_dma_direction(dir)); @@ -160,14 +160,14 @@ } } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - return c6x_dma_sync(dev, paddr, size, dir); + return c6x_dma_sync(paddr, size, dir); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - return c6x_dma_sync(dev, paddr, size, dir); + return c6x_dma_sync(paddr, size, dir); } --- linux-oracle-5.4.0.orig/arch/c6x/mm/init.c +++ linux-oracle-5.4.0/arch/c6x/mm/init.c @@ -33,7 +33,7 @@ void __init paging_init(void) { struct pglist_data *pgdat = NODE_DATA(0); - unsigned long zones_size[MAX_NR_ZONES] = {0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; empty_zero_page = (unsigned long) memblock_alloc(PAGE_SIZE, PAGE_SIZE); @@ -49,11 +49,9 @@ /* * Define zones */ - zones_size[ZONE_NORMAL] = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT; - pgdat->node_zones[ZONE_NORMAL].zone_start_pfn = - __pa(PAGE_OFFSET) >> PAGE_SHIFT; + max_zone_pfn[ZONE_NORMAL] = memory_end >> PAGE_SHIFT; - free_area_init(zones_size); + free_area_init(max_zone_pfn); } void __init mem_init(void) --- linux-oracle-5.4.0.orig/arch/csky/Kconfig +++ linux-oracle-5.4.0/arch/csky/Kconfig @@ -36,6 +36,7 @@ select GX6605S_TIMER if CPU_CK610 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_AUDITSYSCALL + select HAVE_COPY_THREAD_TLS select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER @@ -74,7 +75,7 @@ config CPU_HAS_LDSTEX bool help - For SMP, CPU needs "ldex&stex" instrcutions to atomic operations. + For SMP, CPU needs "ldex&stex" instructions for atomic operations. config CPU_NEED_TLBSYNC bool @@ -219,7 +220,7 @@ int "Maximum zone order" default "11" -config RAM_BASE +config DRAM_BASE hex "DRAM start addr (the same with memory-section in dts)" default 0x0 --- linux-oracle-5.4.0.orig/arch/csky/abiv1/alignment.c +++ linux-oracle-5.4.0/arch/csky/abiv1/alignment.c @@ -294,7 +294,7 @@ __func__, opcode, rz, rx, imm, addr); show_regs(regs); bust_spinlocks(0); - do_exit(SIGKILL); + make_task_dead(SIGKILL); } force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr); --- linux-oracle-5.4.0.orig/arch/csky/abiv1/inc/abi/entry.h +++ linux-oracle-5.4.0/arch/csky/abiv1/inc/abi/entry.h @@ -16,14 +16,16 @@ #define LSAVE_A4 40 #define LSAVE_A5 44 +#define usp ss1 + .macro USPTOKSP - mtcr sp, ss1 + mtcr sp, usp mfcr sp, ss0 .endm .macro KSPTOUSP mtcr sp, ss0 - mfcr sp, ss1 + mfcr sp, usp .endm .macro SAVE_ALL epc_inc @@ -45,7 +47,13 @@ add lr, r13 stw lr, (sp, 8) + mov lr, sp + addi lr, 32 + addi lr, 32 + addi lr, 16 + bt 2f mfcr lr, ss1 +2: stw lr, (sp, 16) stw a0, (sp, 20) @@ -79,9 +87,10 @@ ldw a0, (sp, 12) mtcr a0, epsr btsti a0, 31 + bt 1f ldw a0, (sp, 16) mtcr a0, ss1 - +1: ldw a0, (sp, 24) ldw a1, (sp, 28) ldw a2, (sp, 32) @@ -102,9 +111,9 @@ addi sp, 32 addi sp, 8 - bt 1f + bt 2f KSPTOUSP -1: +2: rte .endm @@ -158,15 +167,12 @@ * BA Reserved C D V */ cprcr r6, cpcr30 - lsri r6, 28 - lsli r6, 28 + lsri r6, 29 + lsli r6, 29 addi r6, 0xe cpwcr r6, cpcr30 - lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0xe + movi r6, 0 cpwcr r6, cpcr31 .endm --- linux-oracle-5.4.0.orig/arch/csky/abiv2/fpu.c +++ linux-oracle-5.4.0/arch/csky/abiv2/fpu.c @@ -10,11 +10,6 @@ #define MTCR_DIST 0xC0006420 #define MFCR_DIST 0xC0006020 -void __init init_fpu(void) -{ - mtcr("cr<1, 2>", 0); -} - /* * fpu_libc_helper() is to help libc to excute: * - mfcr %a, cr<1, 2> --- linux-oracle-5.4.0.orig/arch/csky/abiv2/inc/abi/entry.h +++ linux-oracle-5.4.0/arch/csky/abiv2/inc/abi/entry.h @@ -13,6 +13,8 @@ #define LSAVE_A1 28 #define LSAVE_A2 32 #define LSAVE_A3 36 +#define LSAVE_A4 40 +#define LSAVE_A5 44 #define KSPTOUSP #define USPTOKSP @@ -31,7 +33,13 @@ mfcr lr, epsr stw lr, (sp, 12) + btsti lr, 31 + bf 1f + addi lr, sp, 152 + br 2f +1: mfcr lr, usp +2: stw lr, (sp, 16) stw a0, (sp, 20) @@ -64,8 +72,10 @@ mtcr a0, epc ldw a0, (sp, 12) mtcr a0, epsr + btsti a0, 31 ldw a0, (sp, 16) mtcr a0, usp + mtcr a0, ss0 #ifdef CONFIG_CPU_HAS_HILO ldw a0, (sp, 140) @@ -86,6 +96,9 @@ addi sp, 40 ldm r16-r30, (sp) addi sp, 72 + bf 1f + mfcr sp, ss0 +1: rte .endm @@ -214,16 +227,13 @@ */ mfcr r6, cr<30, 15> /* Get MSA0 */ 2: - lsri r6, 28 - lsli r6, 28 + lsri r6, 29 + lsli r6, 29 addi r6, 0x1ce mtcr r6, cr<30, 15> /* Set MSA0 */ - lsri r6, 28 - addi r6, 2 - lsli r6, 28 - addi r6, 0x1ce - mtcr r6, cr<31, 15> /* Set MSA1 */ + movi r6, 0 + mtcr r6, cr<31, 15> /* Clr MSA1 */ /* enable MMU */ mfcr r6, cr18 --- linux-oracle-5.4.0.orig/arch/csky/abiv2/inc/abi/fpu.h +++ linux-oracle-5.4.0/arch/csky/abiv2/inc/abi/fpu.h @@ -9,7 +9,8 @@ int fpu_libc_helper(struct pt_regs *regs); void fpu_fpe(struct pt_regs *regs); -void __init init_fpu(void); + +static inline void init_fpu(void) { mtcr("cr<1, 2>", 0); } void save_to_user_fp(struct user_fp *user_fp); void restore_from_user_fp(struct user_fp *user_fp); --- linux-oracle-5.4.0.orig/arch/csky/include/asm/page.h +++ linux-oracle-5.4.0/arch/csky/include/asm/page.h @@ -28,7 +28,7 @@ #define SSEG_SIZE 0x20000000 #define LOWMEM_LIMIT (SSEG_SIZE * 2) -#define PHYS_OFFSET_OFFSET (CONFIG_RAM_BASE & (SSEG_SIZE - 1)) +#define PHYS_OFFSET_OFFSET (CONFIG_DRAM_BASE & (SSEG_SIZE - 1)) #ifndef __ASSEMBLY__ --- linux-oracle-5.4.0.orig/arch/csky/include/asm/processor.h +++ linux-oracle-5.4.0/arch/csky/include/asm/processor.h @@ -43,6 +43,7 @@ struct thread_struct { unsigned long ksp; /* kernel stack pointer */ unsigned long sr; /* saved status register */ + unsigned long trap_no; /* saved status register */ /* FPU regs */ struct user_fp __aligned(16) user_fp; --- linux-oracle-5.4.0.orig/arch/csky/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/csky/include/asm/uaccess.h @@ -254,7 +254,7 @@ extern int __get_user_bad(void); -#define __copy_user(to, from, n) \ +#define ___copy_to_user(to, from, n) \ do { \ int w0, w1, w2, w3; \ asm volatile( \ @@ -289,31 +289,34 @@ " subi %0, 4 \n" \ " br 3b \n" \ "5: cmpnei %0, 0 \n" /* 1B */ \ - " bf 8f \n" \ + " bf 13f \n" \ " ldb %3, (%2, 0) \n" \ "6: stb %3, (%1, 0) \n" \ " addi %2, 1 \n" \ " addi %1, 1 \n" \ " subi %0, 1 \n" \ " br 5b \n" \ - "7: br 8f \n" \ + "7: subi %0, 4 \n" \ + "8: subi %0, 4 \n" \ + "12: subi %0, 4 \n" \ + " br 13f \n" \ ".section __ex_table, \"a\" \n" \ ".align 2 \n" \ - ".long 2b, 7b \n" \ - ".long 9b, 7b \n" \ - ".long 10b, 7b \n" \ + ".long 2b, 13f \n" \ + ".long 4b, 13f \n" \ + ".long 6b, 13f \n" \ + ".long 9b, 12b \n" \ + ".long 10b, 8b \n" \ ".long 11b, 7b \n" \ - ".long 4b, 7b \n" \ - ".long 6b, 7b \n" \ ".previous \n" \ - "8: \n" \ + "13: \n" \ : "=r"(n), "=r"(to), "=r"(from), "=r"(w0), \ "=r"(w1), "=r"(w2), "=r"(w3) \ : "0"(n), "1"(to), "2"(from) \ : "memory"); \ } while (0) -#define __copy_user_zeroing(to, from, n) \ +#define ___copy_from_user(to, from, n) \ do { \ int tmp; \ int nsave; \ @@ -356,22 +359,22 @@ " addi %1, 1 \n" \ " subi %0, 1 \n" \ " br 5b \n" \ - "8: mov %3, %0 \n" \ - " movi %4, 0 \n" \ - "9: stb %4, (%1, 0) \n" \ - " addi %1, 1 \n" \ - " subi %3, 1 \n" \ - " cmpnei %3, 0 \n" \ - " bt 9b \n" \ - " br 7f \n" \ + "8: stw %3, (%1, 0) \n" \ + " subi %0, 4 \n" \ + " bf 7f \n" \ + "9: subi %0, 8 \n" \ + " bf 7f \n" \ + "13: stw %3, (%1, 8) \n" \ + " subi %0, 12 \n" \ + " bf 7f \n" \ ".section __ex_table, \"a\" \n" \ ".align 2 \n" \ - ".long 2b, 8b \n" \ + ".long 2b, 7f \n" \ + ".long 4b, 7f \n" \ + ".long 6b, 7f \n" \ ".long 10b, 8b \n" \ - ".long 11b, 8b \n" \ - ".long 12b, 8b \n" \ - ".long 4b, 8b \n" \ - ".long 6b, 8b \n" \ + ".long 11b, 9b \n" \ + ".long 12b,13b \n" \ ".previous \n" \ "7: \n" \ : "=r"(n), "=r"(to), "=r"(from), "=r"(nsave), \ --- linux-oracle-5.4.0.orig/arch/csky/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/csky/include/uapi/asm/unistd.h @@ -1,9 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_NEW_STAT #define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_SYS_CLONE3 #define __ARCH_WANT_SET_GET_RLIMIT #define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_SYNC_FILE_RANGE2 #include #define __NR_set_thread_area (__NR_arch_specific_syscall + 0) --- linux-oracle-5.4.0.orig/arch/csky/kernel/atomic.S +++ linux-oracle-5.4.0/arch/csky/kernel/atomic.S @@ -17,10 +17,12 @@ mfcr a3, epc addi a3, TRAP0_SIZE - subi sp, 8 + subi sp, 16 stw a3, (sp, 0) mfcr a3, epsr stw a3, (sp, 4) + mfcr a3, usp + stw a3, (sp, 8) psrset ee #ifdef CONFIG_CPU_HAS_LDSTEX @@ -47,7 +49,9 @@ mtcr a3, epc ldw a3, (sp, 4) mtcr a3, epsr - addi sp, 8 + ldw a3, (sp, 8) + mtcr a3, usp + addi sp, 16 KSPTOUSP rte END(csky_cmpxchg) --- linux-oracle-5.4.0.orig/arch/csky/kernel/entry.S +++ linux-oracle-5.4.0/arch/csky/kernel/entry.S @@ -170,8 +170,10 @@ ldw a3, (sp, LSAVE_A3) #if defined(__CSKYABIV2__) subi sp, 8 - stw r5, (sp, 0x4) - stw r4, (sp, 0x0) + ldw r9, (sp, LSAVE_A4) + stw r9, (sp, 0x0) + ldw r9, (sp, LSAVE_A5) + stw r9, (sp, 0x4) #else ldw r6, (sp, LSAVE_A4) ldw r7, (sp, LSAVE_A5) @@ -318,8 +320,6 @@ mfcr a2, psr /* Save PSR value */ stw a2, (a3, THREAD_SR) /* Save PSR in task struct */ - bclri a2, 6 /* Disable interrupts */ - mtcr a2, psr SAVE_SWITCH_STACK --- linux-oracle-5.4.0.orig/arch/csky/kernel/head.S +++ linux-oracle-5.4.0/arch/csky/kernel/head.S @@ -21,6 +21,11 @@ ENTRY(_start_smp_secondary) SETUP_MMU + /* copy msa1 from CPU0 */ + lrw r6, secondary_msa1 + ld.w r6, (r6, 0) + mtcr r6, cr<31, 15> + /* set stack point */ lrw r6, secondary_stack ld.w r6, (r6, 0) --- linux-oracle-5.4.0.orig/arch/csky/kernel/perf_callchain.c +++ linux-oracle-5.4.0/arch/csky/kernel/perf_callchain.c @@ -12,12 +12,17 @@ static int unwind_frame_kernel(struct stackframe *frame) { - if (kstack_end((void *)frame->fp)) + unsigned long low = (unsigned long)task_stack_page(current); + unsigned long high = low + THREAD_SIZE; + + if (unlikely(frame->fp < low || frame->fp > high)) return -EPERM; - if (frame->fp & 0x3 || frame->fp < TASK_SIZE) + + if (kstack_end((void *)frame->fp) || frame->fp & 0x3) return -EPERM; *frame = *(struct stackframe *)frame->fp; + if (__kernel_text_address(frame->lr)) { int graph = 0; @@ -81,10 +86,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); unsigned long fp = 0; /* C-SKY does not support virtualization. */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) + if (guest_cbs && guest_cbs->is_in_guest()) return; fp = regs->regs[4]; @@ -105,10 +111,11 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct stackframe fr; /* C-SKY does not support virtualization. */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { pr_warn("C-SKY does not support perf in guest mode!"); return; } --- linux-oracle-5.4.0.orig/arch/csky/kernel/process.c +++ linux-oracle-5.4.0/arch/csky/kernel/process.c @@ -34,10 +34,11 @@ return sw->r15; } -int copy_thread(unsigned long clone_flags, +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, unsigned long kthread_arg, - struct task_struct *p) + struct task_struct *p, + unsigned long tls) { struct switch_stack *childstack; struct pt_regs *childregs = task_pt_regs(p); @@ -64,7 +65,7 @@ childregs->usp = usp; if (clone_flags & CLONE_SETTLS) task_thread_info(p)->tp_value = childregs->tls - = childregs->regs[0]; + = tls; childregs->a0 = 0; childstack->r15 = (unsigned long) ret_from_fork; --- linux-oracle-5.4.0.orig/arch/csky/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/csky/kernel/ptrace.c @@ -96,7 +96,8 @@ if (ret) return ret; - regs.sr = task_pt_regs(target)->sr; + /* BIT(0) of regs.sr is Condition Code/Carry bit */ + regs.sr = (regs.sr & BIT(0)) | (task_pt_regs(target)->sr & ~BIT(0)); #ifdef CONFIG_CPU_HAS_HILO regs.dcsr = task_pt_regs(target)->dcsr; #endif --- linux-oracle-5.4.0.orig/arch/csky/kernel/setup.c +++ linux-oracle-5.4.0/arch/csky/kernel/setup.c @@ -24,26 +24,11 @@ }; #endif -phys_addr_t __init_memblock memblock_end_of_REG0(void) -{ - return (memblock.memory.regions[0].base + - memblock.memory.regions[0].size); -} - -phys_addr_t __init_memblock memblock_start_of_REG1(void) -{ - return memblock.memory.regions[1].base; -} - -size_t __init_memblock memblock_size_of_REG1(void) -{ - return memblock.memory.regions[1].size; -} - static void __init csky_memblock_init(void) { - unsigned long zone_size[MAX_NR_ZONES]; - unsigned long zhole_size[MAX_NR_ZONES]; + unsigned long lowmem_size = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); + unsigned long sseg_size = PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET); + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; signed long size; memblock_reserve(__pa(_stext), _end - _stext); @@ -56,55 +41,31 @@ memblock_dump_all(); - memset(zone_size, 0, sizeof(zone_size)); - memset(zhole_size, 0, sizeof(zhole_size)); - min_low_pfn = PFN_UP(memblock_start_of_DRAM()); - max_pfn = PFN_DOWN(memblock_end_of_DRAM()); - - max_low_pfn = PFN_UP(memblock_end_of_REG0()); - if (max_low_pfn == 0) - max_low_pfn = max_pfn; + max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM()); size = max_pfn - min_low_pfn; - if (memblock.memory.cnt > 1) { - zone_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn; - zhole_size[ZONE_NORMAL] = - PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn; - } else { - if (size <= PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET)) - zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn; - else { - zone_size[ZONE_NORMAL] = - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL]; - } + if (size >= lowmem_size) { + max_low_pfn = min_low_pfn + lowmem_size; + write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE); + } else if (size > sseg_size) { + max_low_pfn = min_low_pfn + sseg_size; } -#ifdef CONFIG_HIGHMEM - size = 0; - if (memblock.memory.cnt > 1) { - size = PFN_DOWN(memblock_size_of_REG1()); - highstart_pfn = PFN_DOWN(memblock_start_of_REG1()); - } else { - size = max_pfn - min_low_pfn - - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - highstart_pfn = min_low_pfn + - PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET); - } + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; - if (size > 0) - zone_size[ZONE_HIGHMEM] = size; +#ifdef CONFIG_HIGHMEM + max_zone_pfn[ZONE_HIGHMEM] = max_pfn; - highend_pfn = max_pfn; + highstart_pfn = max_low_pfn; + highend_pfn = max_pfn; #endif memblock_set_current_limit(PFN_PHYS(max_low_pfn)); dma_contiguous_reserve(0); - free_area_init_node(0, zone_size, min_low_pfn, zhole_size); + free_area_init(max_zone_pfn); } void __init setup_arch(char **cmdline_p) --- linux-oracle-5.4.0.orig/arch/csky/kernel/signal.c +++ linux-oracle-5.4.0/arch/csky/kernel/signal.c @@ -52,10 +52,14 @@ struct sigcontext __user *sc) { int err = 0; + unsigned long sr = regs->sr; /* sc_pt_regs is structured the same as the start of pt_regs */ err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs)); + /* BIT(0) of regs->sr is Condition Code/Carry bit */ + regs->sr = (sr & ~1) | (regs->sr & 1); + /* Restore the floating-point state. */ err |= restore_fpu_state(sc); --- linux-oracle-5.4.0.orig/arch/csky/kernel/smp.c +++ linux-oracle-5.4.0/arch/csky/kernel/smp.c @@ -22,6 +22,9 @@ #include #include #include +#ifdef CONFIG_CPU_HAS_FPU +#include +#endif struct ipi_data_struct { unsigned long bits ____cacheline_aligned; @@ -120,7 +123,7 @@ int rc; if (ipi_irq == 0) - panic("%s IRQ mapping failed\n", __func__); + return; rc = request_percpu_irq(ipi_irq, handle_ipi, "IPI Interrupt", &ipi_dummy_dev); @@ -156,6 +159,8 @@ volatile unsigned int secondary_ccr; volatile unsigned int secondary_stack; +unsigned long secondary_msa1; + int __cpu_up(unsigned int cpu, struct task_struct *tidle) { unsigned long mask = 1 << cpu; @@ -164,6 +169,7 @@ (unsigned int) task_stack_page(tidle) + THREAD_SIZE - 8; secondary_hint = mfcr("cr31"); secondary_ccr = mfcr("cr18"); + secondary_msa1 = read_mmu_msa1(); /* * Because other CPUs are in reset status, we must flush data --- linux-oracle-5.4.0.orig/arch/csky/kernel/traps.c +++ linux-oracle-5.4.0/arch/csky/kernel/traps.c @@ -85,7 +85,7 @@ pr_err("%s: %08x\n", str, nr); show_regs(regs); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } void buserr(struct pt_regs *regs) @@ -115,8 +115,9 @@ int sig; unsigned long vector; siginfo_t info; + struct task_struct *tsk = current; - vector = (mfcr("psr") >> 16) & 0xff; + vector = (regs->sr >> 16) & 0xff; switch (vector) { case VEC_ZERODIV: @@ -129,6 +130,7 @@ sig = SIGTRAP; break; case VEC_ILLEGAL: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode ILLEGAL", regs, vector); #ifndef CONFIG_CPU_NO_USER_BKPT if (*(uint16_t *)instruction_pointer(regs) != USR_BKPT) @@ -146,16 +148,20 @@ sig = SIGTRAP; break; case VEC_ACCESS: + tsk->thread.trap_no = vector; return buserr(regs); #ifdef CONFIG_CPU_NEED_SOFTALIGN case VEC_ALIGN: + tsk->thread.trap_no = vector; return csky_alignment(regs); #endif #ifdef CONFIG_CPU_HAS_FPU case VEC_FPE: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode FPE", regs, vector); return fpu_fpe(regs); case VEC_PRIV: + tsk->thread.trap_no = vector; die_if_kernel("Kernel mode PRIV", regs, vector); if (fpu_libc_helper(regs)) return; @@ -164,5 +170,8 @@ sig = SIGSEGV; break; } + + tsk->thread.trap_no = vector; + send_sig(sig, current, 0); } --- linux-oracle-5.4.0.orig/arch/csky/lib/usercopy.c +++ linux-oracle-5.4.0/arch/csky/lib/usercopy.c @@ -7,10 +7,7 @@ unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n) { - if (access_ok(from, n)) - __copy_user_zeroing(to, from, n); - else - memset(to, 0, n); + ___copy_from_user(to, from, n); return n; } EXPORT_SYMBOL(raw_copy_from_user); @@ -18,8 +15,7 @@ unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n) { - if (access_ok(to, n)) - __copy_user(to, from, n); + ___copy_to_user(to, from, n); return n; } EXPORT_SYMBOL(raw_copy_to_user); --- linux-oracle-5.4.0.orig/arch/csky/mm/Makefile +++ linux-oracle-5.4.0/arch/csky/mm/Makefile @@ -1,8 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only ifeq ($(CONFIG_CPU_HAS_CACHEV2),y) obj-y += cachev2.o +CFLAGS_REMOVE_cachev2.o = $(CC_FLAGS_FTRACE) else obj-y += cachev1.o +CFLAGS_REMOVE_cachev1.o = $(CC_FLAGS_FTRACE) endif obj-y += dma-mapping.o --- linux-oracle-5.4.0.orig/arch/csky/mm/dma-mapping.c +++ linux-oracle-5.4.0/arch/csky/mm/dma-mapping.c @@ -58,8 +58,8 @@ cache_op(page_to_phys(page), size, dma_wbinv_set_zero_range); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: @@ -74,8 +74,8 @@ } } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: --- linux-oracle-5.4.0.orig/arch/csky/mm/fault.c +++ linux-oracle-5.4.0/arch/csky/mm/fault.c @@ -179,11 +179,14 @@ bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (user_mode(regs)) { + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; force_sig_fault(SIGSEGV, si_code, (void __user *)address); return; } no_context: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) return; @@ -198,6 +201,8 @@ die_if_kernel("Oops", regs, write); out_of_memory: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + /* * We ran out of memory, call the OOM killer, and return the userspace * (which will retry the fault, or kill us if we got oom-killed). @@ -206,6 +211,8 @@ return; do_sigbus: + tsk->thread.trap_no = (regs->sr >> 16) & 0xff; + up_read(&mm->mmap_sem); /* Kernel mode? Handle exceptions or die */ --- linux-oracle-5.4.0.orig/arch/csky/mm/init.c +++ linux-oracle-5.4.0/arch/csky/mm/init.c @@ -31,6 +31,7 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss; pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss; +EXPORT_SYMBOL(invalid_pte_table); unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss; EXPORT_SYMBOL(empty_zero_page); --- linux-oracle-5.4.0.orig/arch/h8300/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/h8300/kernel/asm-offsets.c @@ -63,6 +63,9 @@ OFFSET(TI_FLAGS, thread_info, flags); OFFSET(TI_CPU, thread_info, cpu); OFFSET(TI_PRE, thread_info, preempt_count); +#ifdef CONFIG_PREEMPTION + DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count)); +#endif return 0; } --- linux-oracle-5.4.0.orig/arch/h8300/kernel/traps.c +++ linux-oracle-5.4.0/arch/h8300/kernel/traps.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -110,7 +111,7 @@ dump(fp); spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } static int kstack_depth_to_print = 24; --- linux-oracle-5.4.0.orig/arch/h8300/mm/fault.c +++ linux-oracle-5.4.0/arch/h8300/mm/fault.c @@ -52,7 +52,7 @@ printk(" at virtual address %08lx\n", address); if (!user_mode(regs)) die("Oops", regs, error_code); - do_exit(SIGKILL); + make_task_dead(SIGKILL); return 1; } --- linux-oracle-5.4.0.orig/arch/h8300/mm/init.c +++ linux-oracle-5.4.0/arch/h8300/mm/init.c @@ -83,10 +83,10 @@ start_mem, end_mem); { - unsigned long zones_size[MAX_NR_ZONES] = {0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; - zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; - free_area_init(zones_size); + max_zone_pfn[ZONE_NORMAL] = end_mem >> PAGE_SHIFT; + free_area_init(max_zone_pfn); } } --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/atomic.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/atomic.h @@ -91,7 +91,7 @@ "1: %0 = memw_locked(%1);\n" \ " %0 = "#op "(%0,%2);\n" \ " memw_locked(%1,P3)=%0;\n" \ - " if !P3 jump 1b;\n" \ + " if (!P3) jump 1b;\n" \ : "=&r" (output) \ : "r" (&v->counter), "r" (i) \ : "memory", "p3" \ @@ -107,7 +107,7 @@ "1: %0 = memw_locked(%1);\n" \ " %0 = "#op "(%0,%2);\n" \ " memw_locked(%1,P3)=%0;\n" \ - " if !P3 jump 1b;\n" \ + " if (!P3) jump 1b;\n" \ : "=&r" (output) \ : "r" (&v->counter), "r" (i) \ : "memory", "p3" \ @@ -124,7 +124,7 @@ "1: %0 = memw_locked(%2);\n" \ " %1 = "#op "(%0,%3);\n" \ " memw_locked(%2,P3)=%1;\n" \ - " if !P3 jump 1b;\n" \ + " if (!P3) jump 1b;\n" \ : "=&r" (output), "=&r" (val) \ : "r" (&v->counter), "r" (i) \ : "memory", "p3" \ @@ -173,7 +173,7 @@ " }" " memw_locked(%2, p3) = %1;" " {" - " if !p3 jump 1b;" + " if (!p3) jump 1b;" " }" "2:" : "=&r" (__oldval), "=&r" (tmp) --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/bitops.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/bitops.h @@ -38,7 +38,7 @@ "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -62,7 +62,7 @@ "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -88,7 +88,7 @@ "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -223,7 +223,7 @@ int r; asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n" - "{ if P0 %0 = #0; if !P0 %0 = add(%0,#1);}\n" + "{ if (P0) %0 = #0; if (!P0) %0 = add(%0,#1);}\n" : "=&r" (r) : "r" (x) : "p0"); --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/cmpxchg.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/cmpxchg.h @@ -30,7 +30,7 @@ __asm__ __volatile__ ( "1: %0 = memw_locked(%1);\n" /* load into retval */ " memw_locked(%1,P0) = %2;\n" /* store into memory */ - " if !P0 jump 1b;\n" + " if (!P0) jump 1b;\n" : "=&r" (retval) : "r" (ptr), "r" (x) : "memory", "p0" @@ -56,7 +56,7 @@ __typeof__(ptr) __ptr = (ptr); \ __typeof__(*(ptr)) __old = (old); \ __typeof__(*(ptr)) __new = (new); \ - __typeof__(*(ptr)) __oldval = 0; \ + __typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0; \ \ asm volatile( \ "1: %0 = memw_locked(%1);\n" \ --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/futex.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/futex.h @@ -16,7 +16,7 @@ /* For example: %1 = %4 */ \ insn \ "2: memw_locked(%3,p2) = %1;\n" \ - " if !p2 jump 1b;\n" \ + " if (!p2) jump 1b;\n" \ " %1 = #0;\n" \ "3:\n" \ ".section .fixup,\"ax\"\n" \ @@ -84,10 +84,10 @@ "1: %1 = memw_locked(%3)\n" " {\n" " p2 = cmp.eq(%1,%4)\n" - " if !p2.new jump:NT 3f\n" + " if (!p2.new) jump:NT 3f\n" " }\n" "2: memw_locked(%3,p2) = %5\n" - " if !p2 jump 1b\n" + " if (!p2) jump 1b\n" "3:\n" ".section .fixup,\"ax\"\n" "4: %0 = #%6\n" --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/io.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/io.h @@ -171,16 +171,10 @@ #define writew_relaxed __raw_writew #define writel_relaxed __raw_writel -/* - * Need an mtype somewhere in here, for cache type deals? - * This is probably too long for an inline. - */ -void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size); +void __iomem *ioremap(unsigned long phys_addr, unsigned long size); +#define ioremap_nocache ioremap +#define ioremap_uc(X, Y) ioremap((X), (Y)) -static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size) -{ - return ioremap_nocache(phys_addr, size); -} static inline void iounmap(volatile void __iomem *addr) { --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/spinlock.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/spinlock.h @@ -30,9 +30,9 @@ __asm__ __volatile__( "1: R6 = memw_locked(%0);\n" " { P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -46,7 +46,7 @@ "1: R6 = memw_locked(%0);\n" " R6 = add(R6,#-1);\n" " memw_locked(%0,P3) = R6\n" - " if !P3 jump 1b;\n" + " if (!P3) jump 1b;\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -61,7 +61,7 @@ __asm__ __volatile__( " R6 = memw_locked(%1);\n" " { %0 = #0; P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" - " { if !P3 jump 1f; }\n" + " { if (!P3) jump 1f; }\n" " memw_locked(%1,P3) = R6;\n" " { %0 = P3 }\n" "1:\n" @@ -78,9 +78,9 @@ __asm__ __volatile__( "1: R6 = memw_locked(%0)\n" " { P3 = cmp.eq(R6,#0); R6 = #-1;}\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -94,7 +94,7 @@ __asm__ __volatile__( " R6 = memw_locked(%1)\n" " { %0 = #0; P3 = cmp.eq(R6,#0); R6 = #-1;}\n" - " { if !P3 jump 1f; }\n" + " { if (!P3) jump 1f; }\n" " memw_locked(%1,P3) = R6;\n" " %0 = P3;\n" "1:\n" @@ -117,9 +117,9 @@ __asm__ __volatile__( "1: R6 = memw_locked(%0);\n" " P3 = cmp.eq(R6,#0);\n" - " { if !P3 jump 1b; R6 = #1; }\n" + " { if (!P3) jump 1b; R6 = #1; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -139,7 +139,7 @@ __asm__ __volatile__( " R6 = memw_locked(%1);\n" " P3 = cmp.eq(R6,#0);\n" - " { if !P3 jump 1f; R6 = #1; %0 = #0; }\n" + " { if (!P3) jump 1f; R6 = #1; %0 = #0; }\n" " memw_locked(%1,P3) = R6;\n" " %0 = P3;\n" "1:\n" --- linux-oracle-5.4.0.orig/arch/hexagon/include/asm/syscalls.h +++ linux-oracle-5.4.0/arch/hexagon/include/asm/syscalls.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice, + u32 a2, u32 a3, u32 a4, u32 a5); --- linux-oracle-5.4.0.orig/arch/hexagon/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/hexagon/include/uapi/asm/unistd.h @@ -36,5 +36,6 @@ #define __ARCH_WANT_SYS_VFORK #define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_SYNC_FILE_RANGE2 #include --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/dma.c +++ linux-oracle-5.4.0/arch/hexagon/kernel/dma.c @@ -55,8 +55,8 @@ gen_pool_free(coherent_pool, (unsigned long) vaddr, size); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { void *addr = phys_to_virt(paddr); --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/hexagon_ksyms.c +++ linux-oracle-5.4.0/arch/hexagon/kernel/hexagon_ksyms.c @@ -20,7 +20,7 @@ EXPORT_SYMBOL(__vmsetie); EXPORT_SYMBOL(__vmyield); EXPORT_SYMBOL(empty_zero_page); -EXPORT_SYMBOL(ioremap_nocache); +EXPORT_SYMBOL(ioremap); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/hexagon/kernel/stacktrace.c @@ -11,8 +11,6 @@ #include #include -register unsigned long current_frame_pointer asm("r30"); - struct stackframe { unsigned long fp; unsigned long rets; @@ -30,7 +28,7 @@ low = (unsigned long)task_stack_page(current); high = low + THREAD_SIZE; - fp = current_frame_pointer; + fp = (unsigned long)__builtin_frame_address(0); while (fp >= low && fp <= (high - sizeof(*frame))) { frame = (struct stackframe *)fp; --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/syscalltab.c +++ linux-oracle-5.4.0/arch/hexagon/kernel/syscalltab.c @@ -14,6 +14,13 @@ #undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), +SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice, + SC_ARG64(offset), SC_ARG64(len)) +{ + return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice); +} +#define sys_fadvise64_64 sys_hexagon_fadvise64_64 + void *sys_call_table[__NR_syscalls] = { #include }; --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/traps.c +++ linux-oracle-5.4.0/arch/hexagon/kernel/traps.c @@ -202,8 +202,10 @@ printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == - NOTIFY_STOP) + NOTIFY_STOP) { + spin_unlock_irq(&die.lock); return 1; + } print_modules(); show_regs(regs); @@ -221,7 +223,7 @@ panic("Fatal exception"); oops_exit(); - do_exit(err); + make_task_dead(err); return 0; } --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/vm_entry.S +++ linux-oracle-5.4.0/arch/hexagon/kernel/vm_entry.S @@ -369,7 +369,7 @@ R26.L = #LO(do_work_pending); R0 = #VM_INT_DISABLE; } - if P0 jump check_work_pending + if (P0) jump check_work_pending { R0 = R25; callr R24 --- linux-oracle-5.4.0.orig/arch/hexagon/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/hexagon/kernel/vmlinux.lds.S @@ -60,13 +60,8 @@ _end = .; - /DISCARD/ : { - EXIT_TEXT - EXIT_DATA - EXIT_CALL - } - STABS_DEBUG DWARF_DEBUG + DISCARDS } --- linux-oracle-5.4.0.orig/arch/hexagon/lib/io.c +++ linux-oracle-5.4.0/arch/hexagon/lib/io.c @@ -27,6 +27,7 @@ *dst++ = *src; } +EXPORT_SYMBOL(__raw_readsw); /* * __raw_writesw - read words a short at a time @@ -47,6 +48,7 @@ } +EXPORT_SYMBOL(__raw_writesw); /* Pretty sure len is pre-adjusted for the length of the access already */ void __raw_readsl(const void __iomem *addr, void *data, int len) @@ -62,6 +64,7 @@ } +EXPORT_SYMBOL(__raw_readsl); void __raw_writesl(void __iomem *addr, const void *data, int len) { @@ -76,3 +79,4 @@ } +EXPORT_SYMBOL(__raw_writesl); --- linux-oracle-5.4.0.orig/arch/hexagon/mm/init.c +++ linux-oracle-5.4.0/arch/hexagon/mm/init.c @@ -91,7 +91,7 @@ */ void __init paging_init(void) { - unsigned long zones_sizes[MAX_NR_ZONES] = {0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; /* * This is not particularly well documented anywhere, but @@ -101,9 +101,9 @@ * adjust accordingly. */ - zones_sizes[ZONE_NORMAL] = max_low_pfn; + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; - free_area_init(zones_sizes); /* sets up the zonelists and mem_map */ + free_area_init(max_zone_pfn); /* sets up the zonelists and mem_map */ /* * Start of high memory area. Will probably need something more --- linux-oracle-5.4.0.orig/arch/hexagon/mm/ioremap.c +++ linux-oracle-5.4.0/arch/hexagon/mm/ioremap.c @@ -9,7 +9,7 @@ #include #include -void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size) +void __iomem *ioremap(unsigned long phys_addr, unsigned long size) { unsigned long last_addr, addr; unsigned long offset = phys_addr & ~PAGE_MASK; --- linux-oracle-5.4.0.orig/arch/ia64/Kconfig +++ linux-oracle-5.4.0/arch/ia64/Kconfig @@ -8,6 +8,7 @@ config IA64 bool + select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_SERIO select ACPI @@ -31,7 +32,6 @@ select HAVE_FUNCTION_TRACER select TTY select HAVE_ARCH_TRACEHOOK - select HAVE_MEMBLOCK_NODE_MAP select HAVE_VIRT_CPU_ACCOUNTING select ARCH_HAS_DMA_COHERENT_TO_PFN select ARCH_HAS_SYNC_DMA_FOR_CPU @@ -360,7 +360,7 @@ depends on PROC_KCORE config IA64_MCA_RECOVERY - tristate "MCA recovery from errors other than TLB." + bool "MCA recovery from errors other than TLB." config PERFMON bool "Performance monitor support" --- linux-oracle-5.4.0.orig/arch/ia64/Kconfig.debug +++ linux-oracle-5.4.0/arch/ia64/Kconfig.debug @@ -39,7 +39,7 @@ config IA64_DEBUG_CMPXCHG bool "Turn on compare-and-exchange bug checking (slow!)" - depends on DEBUG_KERNEL + depends on DEBUG_KERNEL && PRINTK help Selecting this option turns on bug checking for the IA-64 compare-and-exchange instructions. This is slow! Itaniums --- linux-oracle-5.4.0.orig/arch/ia64/Makefile +++ linux-oracle-5.4.0/arch/ia64/Makefile @@ -40,7 +40,7 @@ endif quiet_cmd_gzip = GZIP $@ -cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@ +cmd_gzip = cat $(real-prereqs) | $(KGZIP) -n -f -9 > $@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ --- linux-oracle-5.4.0.orig/arch/ia64/configs/zx1_defconfig +++ linux-oracle-5.4.0/arch/ia64/configs/zx1_defconfig @@ -35,7 +35,6 @@ CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/ia64/include/asm/module.h +++ linux-oracle-5.4.0/arch/ia64/include/asm/module.h @@ -14,16 +14,20 @@ struct elf64_shdr; /* forward declration */ struct mod_arch_specific { + /* Used only at module load time. */ struct elf64_shdr *core_plt; /* core PLT section */ struct elf64_shdr *init_plt; /* init PLT section */ struct elf64_shdr *got; /* global offset table */ struct elf64_shdr *opd; /* official procedure descriptors */ struct elf64_shdr *unwind; /* unwind-table section */ unsigned long gp; /* global-pointer for module */ + unsigned int next_got_entry; /* index of next available got entry */ + /* Used at module run and cleanup time. */ void *core_unw_table; /* core unwind-table cookie returned by unwinder */ void *init_unw_table; /* init unwind-table cookie returned by unwinder */ - unsigned int next_got_entry; /* index of next available got entry */ + void *opd_addr; /* symbolize uses .opd to get to actual function */ + unsigned long opd_size; }; #define MODULE_PROC_FAMILY "ia64" --- linux-oracle-5.4.0.orig/arch/ia64/include/asm/processor.h +++ linux-oracle-5.4.0/arch/ia64/include/asm/processor.h @@ -552,7 +552,7 @@ { unsigned int reg = vector / 64; unsigned int bit = vector % 64; - u64 irr; + unsigned long irr; switch (reg) { case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break; --- linux-oracle-5.4.0.orig/arch/ia64/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/ia64/include/asm/ptrace.h @@ -54,8 +54,7 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs) { - /* FIXME: should this be bspstore + nr_dirty regs? */ - return regs->ar_bspstore; + return regs->r12; } static inline int is_syscall_success(struct pt_regs *regs) @@ -79,11 +78,6 @@ unsigned long __ip = instruction_pointer(regs); \ (__ip & ~3UL) + ((__ip & 3UL) << 2); \ }) -/* - * Why not default? Because user_stack_pointer() on ia64 gives register - * stack backing store instead... - */ -#define current_user_stack_pointer() (current_pt_regs()->r12) /* given a pointer to a task_struct, return the user's pt_regs */ # define task_pt_regs(t) (((struct pt_regs *) ((char *) (t) + IA64_STK_OFFSET)) - 1) --- linux-oracle-5.4.0.orig/arch/ia64/include/asm/syscall.h +++ linux-oracle-5.4.0/arch/ia64/include/asm/syscall.h @@ -32,7 +32,7 @@ static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return regs->r10 == -1 ? regs->r8:0; + return regs->r10 == -1 ? -regs->r8:0; } static inline long syscall_get_return_value(struct task_struct *task, --- linux-oracle-5.4.0.orig/arch/ia64/include/asm/timex.h +++ linux-oracle-5.4.0/arch/ia64/include/asm/timex.h @@ -39,6 +39,7 @@ ret = ia64_getreg(_IA64_REG_AR_ITC); return ret; } +#define get_cycles get_cycles extern void ia64_cpu_local_tick (void); extern unsigned long long ia64_native_sched_clock (void); --- linux-oracle-5.4.0.orig/arch/ia64/kernel/Makefile +++ linux-oracle-5.4.0/arch/ia64/kernel/Makefile @@ -41,7 +41,7 @@ endif obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o -obj-$(CONFIG_BINFMT_ELF) += elfcore.o +obj-$(CONFIG_ELF_CORE) += elfcore.o # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 --- linux-oracle-5.4.0.orig/arch/ia64/kernel/acpi.c +++ linux-oracle-5.4.0/arch/ia64/kernel/acpi.c @@ -448,7 +448,8 @@ if (srat_num_cpus == 0) { node_set_online(0); node_cpuid[0].phys_id = hard_smp_processor_id(); - return; + slit_distance(0, 0) = LOCAL_DISTANCE; + goto out; } /* @@ -491,7 +492,7 @@ for (j = 0; j < MAX_NUMNODES; j++) slit_distance(i, j) = i == j ? LOCAL_DISTANCE : REMOTE_DISTANCE; - return; + goto out; } memset(numa_slit, -1, sizeof(numa_slit)); @@ -516,6 +517,8 @@ printk("\n"); } #endif +out: + node_possible_map = node_online_map; } #endif /* CONFIG_ACPI_NUMA */ --- linux-oracle-5.4.0.orig/arch/ia64/kernel/err_inject.c +++ linux-oracle-5.4.0/arch/ia64/kernel/err_inject.c @@ -59,7 +59,7 @@ char *buf) \ { \ u32 cpu=dev->id; \ - return sprintf(buf, "%lx\n", name[cpu]); \ + return sprintf(buf, "%llx\n", name[cpu]); \ } #define store(name) \ @@ -86,9 +86,9 @@ #ifdef ERR_INJ_DEBUG printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); - printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]); - printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); - printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", + printk(KERN_DEBUG "err_type_info=%llx,\n", err_type_info[cpu]); + printk(KERN_DEBUG "err_struct_info=%llx,\n", err_struct_info[cpu]); + printk(KERN_DEBUG "err_data_buffer=%llx, %llx, %llx.\n", err_data_buffer[cpu].data1, err_data_buffer[cpu].data2, err_data_buffer[cpu].data3); @@ -117,8 +117,8 @@ #ifdef ERR_INJ_DEBUG printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); - printk(KERN_DEBUG "capabilities=%lx,\n", capabilities[cpu]); - printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); + printk(KERN_DEBUG "capabilities=%llx,\n", capabilities[cpu]); + printk(KERN_DEBUG "resources=%llx\n", resources[cpu]); #endif return size; } @@ -131,7 +131,7 @@ char *buf) { unsigned int cpu=dev->id; - return sprintf(buf, "%lx\n", phys_addr[cpu]); + return sprintf(buf, "%llx\n", phys_addr[cpu]); } static ssize_t @@ -145,7 +145,7 @@ ret = get_user_pages_fast(virt_addr, 1, FOLL_WRITE, NULL); if (ret<=0) { #ifdef ERR_INJ_DEBUG - printk("Virtual address %lx is not existing.\n",virt_addr); + printk("Virtual address %llx is not existing.\n", virt_addr); #endif return -EINVAL; } @@ -163,7 +163,7 @@ { unsigned int cpu=dev->id; - return sprintf(buf, "%lx, %lx, %lx\n", + return sprintf(buf, "%llx, %llx, %llx\n", err_data_buffer[cpu].data1, err_data_buffer[cpu].data2, err_data_buffer[cpu].data3); @@ -178,13 +178,13 @@ int ret; #ifdef ERR_INJ_DEBUG - printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n", + printk("write err_data_buffer=[%llx,%llx,%llx] on cpu%d\n", err_data_buffer[cpu].data1, err_data_buffer[cpu].data2, err_data_buffer[cpu].data3, cpu); #endif - ret=sscanf(buf, "%lx, %lx, %lx", + ret = sscanf(buf, "%llx, %llx, %llx", &err_data_buffer[cpu].data1, &err_data_buffer[cpu].data2, &err_data_buffer[cpu].data3); --- linux-oracle-5.4.0.orig/arch/ia64/kernel/kprobes.c +++ linux-oracle-5.4.0/arch/ia64/kernel/kprobes.c @@ -411,7 +411,7 @@ struct hlist_node *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = - ((struct fnptr *)kretprobe_trampoline)->ip; + (unsigned long)dereference_function_descriptor(kretprobe_trampoline); INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); @@ -487,7 +487,7 @@ ri->ret_addr = (kprobe_opcode_t *)regs->b0; /* Replace the return addr with trampoline addr */ - regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; + regs->b0 = (unsigned long)dereference_function_descriptor(kretprobe_trampoline); } /* Check the instruction in the slot is break */ @@ -991,14 +991,14 @@ int __init arch_init_kprobes(void) { trampoline_p.addr = - (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; + dereference_function_descriptor(kretprobe_trampoline); return register_kprobe(&trampoline_p); } int __kprobes arch_trampoline_kprobe(struct kprobe *p) { if (p->addr == - (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip) + dereference_function_descriptor(kretprobe_trampoline)) return 1; return 0; --- linux-oracle-5.4.0.orig/arch/ia64/kernel/mca.c +++ linux-oracle-5.4.0/arch/ia64/kernel/mca.c @@ -1851,7 +1851,7 @@ data = mca_bootmem(); first_time = 0; } else - data = (void *)__get_free_pages(GFP_KERNEL, + data = (void *)__get_free_pages(GFP_ATOMIC, get_order(sz)); if (!data) panic("Could not allocate MCA memory for cpu %d\n", --- linux-oracle-5.4.0.orig/arch/ia64/kernel/mca_drv.c +++ linux-oracle-5.4.0/arch/ia64/kernel/mca_drv.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -176,7 +177,7 @@ spin_unlock(&mca_bh_lock); /* This process is about to be killed itself */ - do_exit(SIGKILL); + make_task_dead(SIGKILL); } /** @@ -343,7 +344,7 @@ /* - 2 - */ sect_min_size = sal_log_sect_min_sizes[0]; - for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++) + for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++) if (sect_min_size > sal_log_sect_min_sizes[i]) sect_min_size = sal_log_sect_min_sizes[i]; --- linux-oracle-5.4.0.orig/arch/ia64/kernel/module.c +++ linux-oracle-5.4.0/arch/ia64/kernel/module.c @@ -905,9 +905,31 @@ int module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { + struct mod_arch_specific *mas = &mod->arch; + DEBUGP("%s: init: entry=%p\n", __func__, mod->init); - if (mod->arch.unwind) + if (mas->unwind) register_unwind_table(mod); + + /* + * ".opd" was already relocated to the final destination. Store + * it's address for use in symbolizer. + */ + mas->opd_addr = (void *)mas->opd->sh_addr; + mas->opd_size = mas->opd->sh_size; + + /* + * Module relocation was already done at this point. Section + * headers are about to be deleted. Wipe out load-time context. + */ + mas->core_plt = NULL; + mas->init_plt = NULL; + mas->got = NULL; + mas->opd = NULL; + mas->unwind = NULL; + mas->gp = 0; + mas->next_got_entry = 0; + return 0; } @@ -926,10 +948,9 @@ void *dereference_module_function_descriptor(struct module *mod, void *ptr) { - Elf64_Shdr *opd = mod->arch.opd; + struct mod_arch_specific *mas = &mod->arch; - if (ptr < (void *)opd->sh_addr || - ptr >= (void *)(opd->sh_addr + opd->sh_size)) + if (ptr < mas->opd_addr || ptr >= mas->opd_addr + mas->opd_size) return ptr; return dereference_function_descriptor(ptr); --- linux-oracle-5.4.0.orig/arch/ia64/kernel/process.c +++ linux-oracle-5.4.0/arch/ia64/kernel/process.c @@ -444,7 +444,7 @@ do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) { unsigned long mask, sp, nat_bits = 0, ar_rnat, urbs_end, cfm; - unsigned long uninitialized_var(ip); /* GCC be quiet */ + unsigned long ip; elf_greg_t *dst = arg; struct pt_regs *pt; char nat; --- linux-oracle-5.4.0.orig/arch/ia64/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/ia64/kernel/ptrace.c @@ -2147,27 +2147,39 @@ { struct syscall_get_set_args *args = data; struct pt_regs *pt = args->regs; - unsigned long *krbs, cfm, ndirty; + unsigned long *krbs, cfm, ndirty, nlocals, nouts; int i, count; if (unw_unwind_to_user(info) < 0) return; + /* + * We get here via a few paths: + * - break instruction: cfm is shared with caller. + * syscall args are in out= regs, locals are non-empty. + * - epsinstruction: cfm is set by br.call + * locals don't exist. + * + * For both cases argguments are reachable in cfm.sof - cfm.sol. + * CFM: [ ... | sor: 17..14 | sol : 13..7 | sof : 6..0 ] + */ cfm = pt->cr_ifs; + nlocals = (cfm >> 7) & 0x7f; /* aka sol */ + nouts = (cfm & 0x7f) - nlocals; /* aka sof - sol */ krbs = (unsigned long *)info->task + IA64_RBS_OFFSET/8; ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19)); count = 0; if (in_syscall(pt)) - count = min_t(int, args->n, cfm & 0x7f); + count = min_t(int, args->n, nouts); + /* Iterate over outs. */ for (i = 0; i < count; i++) { + int j = ndirty + nlocals + i + args->i; if (args->rw) - *ia64_rse_skip_regs(krbs, ndirty + i + args->i) = - args->args[i]; + *ia64_rse_skip_regs(krbs, j) = args->args[i]; else - args->args[i] = *ia64_rse_skip_regs(krbs, - ndirty + i + args->i); + args->args[i] = *ia64_rse_skip_regs(krbs, j); } if (!args->rw) { --- linux-oracle-5.4.0.orig/arch/ia64/kernel/salinfo.c +++ linux-oracle-5.4.0/arch/ia64/kernel/salinfo.c @@ -581,7 +581,7 @@ * 'data' contains an integer that corresponds to the feature we're * testing */ -static int proc_salinfo_show(struct seq_file *m, void *v) +static int __maybe_unused proc_salinfo_show(struct seq_file *m, void *v) { unsigned long data = (unsigned long)v; seq_puts(m, (sal_platform_features & data) ? "1\n" : "0\n"); --- linux-oracle-5.4.0.orig/arch/ia64/kernel/setup.c +++ linux-oracle-5.4.0/arch/ia64/kernel/setup.c @@ -1073,8 +1073,7 @@ } } -void __init -check_bugs (void) +void __init arch_cpu_finalize_init(void) { ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles, (unsigned long) __end___mckinley_e9_bundles); --- linux-oracle-5.4.0.orig/arch/ia64/kernel/topology.c +++ linux-oracle-5.4.0/arch/ia64/kernel/topology.c @@ -3,9 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * This file contains NUMA specific variables and functions which can - * be split away from DISCONTIGMEM and are used on NUMA machines with - * contiguous memory. + * This file contains NUMA specific variables and functions which are used on + * NUMA machines with contiguous memory. * 2002/08/07 Erich Focht * Populate cpu entries in sysfs for non-numa systems as well * Intel Corporation - Ashok Raj --- linux-oracle-5.4.0.orig/arch/ia64/kernel/traps.c +++ linux-oracle-5.4.0/arch/ia64/kernel/traps.c @@ -85,7 +85,7 @@ if (panic_on_oops) panic("Fatal exception"); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); return 0; } --- linux-oracle-5.4.0.orig/arch/ia64/mm/contig.c +++ linux-oracle-5.4.0/arch/ia64/mm/contig.c @@ -81,7 +81,7 @@ return __per_cpu_start + __per_cpu_offset[smp_processor_id()]; } -static inline void +static inline __init void alloc_per_cpu_data(void) { size_t size = PERCPU_PAGE_SIZE * num_possible_cpus(); @@ -210,6 +210,6 @@ printk("Virtual mem_map starts at 0x%p\n", mem_map); } #endif /* !CONFIG_VIRTUAL_MEM_MAP */ - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } --- linux-oracle-5.4.0.orig/arch/ia64/mm/discontig.c +++ linux-oracle-5.4.0/arch/ia64/mm/discontig.c @@ -95,7 +95,7 @@ * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been * called yet. Note that node 0 will also count all non-existent cpus. */ -static int __meminit early_nr_cpus_node(int node) +static int early_nr_cpus_node(int node) { int cpu, n = 0; @@ -110,7 +110,7 @@ * compute_pernodesize - compute size of pernode data * @node: the node id. */ -static unsigned long __meminit compute_pernodesize(int node) +static unsigned long compute_pernodesize(int node) { unsigned long pernodesize = 0, cpus; @@ -180,7 +180,7 @@ void __init setup_per_cpu_areas(void) { struct pcpu_alloc_info *ai; - struct pcpu_group_info *uninitialized_var(gi); + struct pcpu_group_info *gi; unsigned int *cpu_map; void *base; unsigned long base_offset; @@ -367,7 +367,7 @@ } } -static void __meminit scatter_node_data(void) +static void scatter_node_data(void) { pg_data_t **dst; int node; @@ -627,7 +627,7 @@ max_zone_pfns[ZONE_DMA32] = max_dma; #endif max_zone_pfns[ZONE_NORMAL] = max_pfn; - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } --- linux-oracle-5.4.0.orig/arch/ia64/mm/fault.c +++ linux-oracle-5.4.0/arch/ia64/mm/fault.c @@ -272,7 +272,7 @@ regs = NULL; bust_spinlocks(0); if (regs) - do_exit(SIGKILL); + make_task_dead(SIGKILL); return; out_of_memory: --- linux-oracle-5.4.0.orig/arch/ia64/mm/init.c +++ linux-oracle-5.4.0/arch/ia64/mm/init.c @@ -73,8 +73,8 @@ * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to * flush them when they get mapped into an executable vm-area. */ -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { unsigned long pfn = PHYS_PFN(paddr); @@ -518,7 +518,7 @@ if (map_start < map_end) memmap_init_zone((unsigned long)(map_end - map_start), args->nid, args->zone, page_to_pfn(map_start), - MEMMAP_EARLY, NULL); + MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); return 0; } @@ -527,8 +527,8 @@ unsigned long start_pfn) { if (!vmem_map) { - memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY, - NULL); + memmap_init_zone(size, nid, zone, start_pfn, + MEMINIT_EARLY, NULL, MIGRATE_MOVABLE); } else { struct page *start; struct memmap_init_callback_data args; @@ -689,9 +689,7 @@ { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct zone *zone; - zone = page_zone(pfn_to_page(start_pfn)); - __remove_pages(zone, start_pfn, nr_pages, altmap); + __remove_pages(start_pfn, nr_pages, altmap); } #endif --- linux-oracle-5.4.0.orig/arch/ia64/mm/numa.c +++ linux-oracle-5.4.0/arch/ia64/mm/numa.c @@ -3,9 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * This file contains NUMA specific variables and functions which can - * be split away from DISCONTIGMEM and are used on NUMA machines with - * contiguous memory. + * This file contains NUMA specific variables and functions which are used on + * NUMA machines with contiguous memory. * * 2002/08/07 Erich Focht */ --- linux-oracle-5.4.0.orig/arch/ia64/mm/tlb.c +++ linux-oracle-5.4.0/arch/ia64/mm/tlb.c @@ -369,7 +369,7 @@ void ia64_tlb_init(void) { - ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */ + ia64_ptce_info_t ptce_info; u64 tr_pgbits; long status; pal_vm_info_1_u_t vm_info_1; --- linux-oracle-5.4.0.orig/arch/ia64/scripts/unwcheck.py +++ linux-oracle-5.4.0/arch/ia64/scripts/unwcheck.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # SPDX-License-Identifier: GPL-2.0 # # Usage: unwcheck.py FILE --- linux-oracle-5.4.0.orig/arch/m68k/68000/entry.S +++ linux-oracle-5.4.0/arch/m68k/68000/entry.S @@ -47,6 +47,8 @@ jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 + jeq ret_from_exception movel %sp@(PT_OFF_ORIG_D0),%d1 movel #-ENOSYS,%d0 cmpl #NR_syscalls,%d1 --- linux-oracle-5.4.0.orig/arch/m68k/Kconfig +++ linux-oracle-5.4.0/arch/m68k/Kconfig @@ -4,6 +4,7 @@ default y select ARCH_32BIT_OFF_T select ARCH_HAS_BINFMT_FLAT + select ARCH_HAS_CPU_FINALIZE_INIT if MMU select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA select ARCH_MIGHT_HAVE_PC_PARPORT if ISA --- linux-oracle-5.4.0.orig/arch/m68k/Kconfig.bus +++ linux-oracle-5.4.0/arch/m68k/Kconfig.bus @@ -63,7 +63,7 @@ endif -if !MMU +if COLDFIRE config ISA_DMA_API def_bool !M5272 --- linux-oracle-5.4.0.orig/arch/m68k/Kconfig.cpu +++ linux-oracle-5.4.0/arch/m68k/Kconfig.cpu @@ -309,7 +309,7 @@ config M68KFPU_EMU bool "Math emulation support" - depends on MMU + depends on M68KCLASSIC && FPU help At some point in the future, this will cause floating-point math instructions to be emulated by the kernel on machines that lack a --- linux-oracle-5.4.0.orig/arch/m68k/Kconfig.devices +++ linux-oracle-5.4.0/arch/m68k/Kconfig.devices @@ -19,6 +19,7 @@ # We have a dedicated heartbeat LED. :-) config PROC_HARDWARE bool "/proc/hardware support" + depends on PROC_FS help Say Y here to support the /proc/hardware file, which gives you access to information about the machine you're running on, --- linux-oracle-5.4.0.orig/arch/m68k/Kconfig.machine +++ linux-oracle-5.4.0/arch/m68k/Kconfig.machine @@ -23,6 +23,9 @@ this kernel on an Atari, say Y here and browse the material available in ; otherwise say N. +config ATARI_KBD_CORE + bool + config MAC bool "Macintosh support" depends on MMU @@ -187,6 +190,7 @@ config MEMORY_RESERVE int "Memory reservation (MiB)" depends on (UCSIMM || UCDIMM) + default 0 help Reserve certain memory regions on 68x328 based boards. @@ -316,6 +320,7 @@ config UBOOT bool "Support for U-Boot command line parameters" + depends on COLDFIRE help If you say Y here kernel will try to collect command line parameters from the initial u-boot stack. --- linux-oracle-5.4.0.orig/arch/m68k/Makefile +++ linux-oracle-5.4.0/arch/m68k/Makefile @@ -135,10 +135,10 @@ ifndef CONFIG_KGDB cp vmlinux vmlinux.tmp $(STRIP) vmlinux.tmp - gzip -9c vmlinux.tmp >vmlinux.gz + $(KGZIP) -9c vmlinux.tmp >vmlinux.gz rm vmlinux.tmp else - gzip -9c vmlinux >vmlinux.gz + $(KGZIP) -9c vmlinux >vmlinux.gz endif bzImage: vmlinux.bz2 @@ -148,10 +148,10 @@ ifndef CONFIG_KGDB cp vmlinux vmlinux.tmp $(STRIP) vmlinux.tmp - bzip2 -1c vmlinux.tmp >vmlinux.bz2 + $(KBZIP2) -1c vmlinux.tmp >vmlinux.bz2 rm vmlinux.tmp else - bzip2 -1c vmlinux >vmlinux.bz2 + $(KBZIP2) -1c vmlinux >vmlinux.bz2 endif archclean: --- linux-oracle-5.4.0.orig/arch/m68k/amiga/config.c +++ linux-oracle-5.4.0/arch/m68k/amiga/config.c @@ -180,6 +180,15 @@ dev->slotsize = be16_to_cpu(cd->cd_SlotSize); dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr); dev->boardsize = be32_to_cpu(cd->cd_BoardSize); + + /* CS-LAB Warp 1260 workaround */ + if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) && + dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) { + + /* turn off all interrupts */ + pr_info("Warp 1260 card detected: applying interrupt storm workaround\n"); + *(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff; + } } else pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n"); #endif /* CONFIG_ZORRO */ --- linux-oracle-5.4.0.orig/arch/m68k/atari/ataints.c +++ linux-oracle-5.4.0/arch/m68k/atari/ataints.c @@ -302,11 +302,7 @@ if (ATARIHW_PRESENT(SCU)) { /* init the SCU if present */ - tt_scu.sys_mask = 0x10; /* enable VBL (for the cursor) and - * disable HSYNC interrupts (who - * needs them?) MFP and SCC are - * enabled in VME mask - */ + tt_scu.sys_mask = 0x0; /* disable all interrupts */ tt_scu.vme_mask = 0x60; /* enable MFP and SCC ints */ } else { /* If no SCU and no Hades, the HSYNC interrupt needs to be --- linux-oracle-5.4.0.orig/arch/m68k/coldfire/device.c +++ linux-oracle-5.4.0/arch/m68k/coldfire/device.c @@ -92,7 +92,7 @@ .dev.platform_data = mcf_uart_platform_data, }; -#if IS_ENABLED(CONFIG_FEC) +#ifdef MCFFEC_BASE0 #ifdef CONFIG_M5441x #define FEC_NAME "enet-fec" @@ -144,6 +144,7 @@ .platform_data = FEC_PDATA, } }; +#endif /* MCFFEC_BASE0 */ #ifdef MCFFEC_BASE1 static struct resource mcf_fec1_resources[] = { @@ -181,7 +182,6 @@ } }; #endif /* MCFFEC_BASE1 */ -#endif /* CONFIG_FEC */ #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) /* @@ -556,12 +556,12 @@ static struct platform_device *mcf_devices[] __initdata = { &mcf_uart, -#if IS_ENABLED(CONFIG_FEC) +#ifdef MCFFEC_BASE0 &mcf_fec0, +#endif #ifdef MCFFEC_BASE1 &mcf_fec1, #endif -#endif #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI) &mcf_qspi, #endif --- linux-oracle-5.4.0.orig/arch/m68k/coldfire/entry.S +++ linux-oracle-5.4.0/arch/m68k/coldfire/entry.S @@ -92,6 +92,8 @@ jbsr syscall_trace_enter RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 + jeq ret_from_exception movel %d3,%a0 jbsr %a0@ movel %d0,%sp@(PT_OFF_D0) /* save the return value */ --- linux-oracle-5.4.0.orig/arch/m68k/coldfire/pci.c +++ linux-oracle-5.4.0/arch/m68k/coldfire/pci.c @@ -216,8 +216,10 @@ /* Keep a virtual mapping to IO/config space active */ iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE); - if (iospace == 0) + if (iospace == 0) { + pci_free_host_bridge(bridge); return -ENODEV; + } pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n", (u32) iospace); --- linux-oracle-5.4.0.orig/arch/m68k/configs/amiga_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/amiga_defconfig @@ -334,7 +334,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/apollo_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/apollo_defconfig @@ -319,7 +319,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/atari_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/atari_defconfig @@ -334,7 +334,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/bvme6000_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/bvme6000_defconfig @@ -316,7 +316,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/hp300_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/hp300_defconfig @@ -318,7 +318,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/mac_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/mac_defconfig @@ -325,7 +325,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/multi_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/multi_defconfig @@ -358,7 +358,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/mvme147_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/mvme147_defconfig @@ -315,7 +315,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/mvme16x_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/mvme16x_defconfig @@ -316,7 +316,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/q40_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/q40_defconfig @@ -324,7 +324,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/sun3_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/sun3_defconfig @@ -313,7 +313,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/configs/sun3x_defconfig +++ linux-oracle-5.4.0/arch/m68k/configs/sun3x_defconfig @@ -313,7 +313,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SAS_ATTRS=m --- linux-oracle-5.4.0.orig/arch/m68k/emu/nfeth.c +++ linux-oracle-5.4.0/arch/m68k/emu/nfeth.c @@ -254,8 +254,8 @@ for (i = 0; i < MAX_UNIT; i++) { if (nfeth_dev[i]) { - unregister_netdev(nfeth_dev[0]); - free_netdev(nfeth_dev[0]); + unregister_netdev(nfeth_dev[i]); + free_netdev(nfeth_dev[i]); } } free_irq(nfEtherIRQ, nfeth_interrupt); --- linux-oracle-5.4.0.orig/arch/m68k/fpsp040/skeleton.S +++ linux-oracle-5.4.0/arch/m68k/fpsp040/skeleton.S @@ -499,12 +499,13 @@ dbf %d0,morein rts - .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: - jbra fpsp040_die + jbsr fpsp040_die + jbra .Lnotkern - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .long in_ea,1b --- linux-oracle-5.4.0.orig/arch/m68k/ifpsp060/os.S +++ linux-oracle-5.4.0/arch/m68k/ifpsp060/os.S @@ -379,11 +379,11 @@ | Execption handling for movs access to illegal memory - .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: moveq #-1,%d1 rts -.section __ex_table,#alloc +.section __ex_table,"a" .align 4 .long dmrbuae,1b .long dmrwuae,1b --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/cmpxchg.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/cmpxchg.h @@ -33,7 +33,7 @@ x = tmp; break; default: - tmp = __invalid_xchg_size(x, ptr, size); + x = __invalid_xchg_size(x, ptr, size); break; } --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/m53xxacr.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/m53xxacr.h @@ -89,9 +89,9 @@ * coherency though in all cases. And for copyback caches we will need * to push cached data as well. */ -#define CACHE_INIT CACR_CINVA -#define CACHE_INVALIDATE CACR_CINVA -#define CACHE_INVALIDATED CACR_CINVA +#define CACHE_INIT (CACHE_MODE + CACR_CINVA - CACR_EC) +#define CACHE_INVALIDATE (CACHE_MODE + CACR_CINVA) +#define CACHE_INVALIDATED (CACHE_MODE + CACR_CINVA) #define ACR0_MODE ((CONFIG_RAMBASE & 0xff000000) + \ (0x000f0000) + \ --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/mac_via.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/mac_via.h @@ -257,6 +257,7 @@ struct irq_desc; +extern void via_l2_flush(int writeback); extern void via_register_interrupts(void); extern void via_irq_enable(int); extern void via_irq_disable(int); --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/mcfgpio.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/mcfgpio.h @@ -144,7 +144,7 @@ * read-modify-write as well as those controlled by the EPORT and GPIO modules. */ #define MCFGPIO_SCR_START 40 -#elif defined(CONFIGM5441x) +#elif defined(CONFIG_M5441x) /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */ #define MCFGPIO_SCR_START 0 #else --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/mvme147hw.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/mvme147hw.h @@ -66,6 +66,9 @@ #define PCC_INT_ENAB 0x08 #define PCC_TIMER_INT_CLR 0x80 + +#define PCC_TIMER_TIC_EN 0x01 +#define PCC_TIMER_COC_EN 0x02 #define PCC_TIMER_CLR_OVF 0x04 #define PCC_LEVEL_ABORT 0x07 @@ -90,8 +93,8 @@ #define M147_SCC_B_ADDR 0xfffe3000 #define M147_SCC_PCLK 5000000 -#define MVME147_IRQ_SCSI_PORT (IRQ_USER+0x45) -#define MVME147_IRQ_SCSI_DMA (IRQ_USER+0x46) +#define MVME147_IRQ_SCSI_PORT (IRQ_USER + 5) +#define MVME147_IRQ_SCSI_DMA (IRQ_USER + 6) /* SCC interrupts, for MVME147 */ --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/pgtable_no.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/pgtable_no.h @@ -42,7 +42,8 @@ * ZERO_PAGE is a global shared page that is always zero: used * for zero-mapped memory areas etc.. */ -#define ZERO_PAGE(vaddr) (virt_to_page(0)) +extern void *empty_zero_page; +#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) /* * All 32bit addresses are effectively valid for vmalloc... --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/raw_io.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/raw_io.h @@ -17,21 +17,21 @@ * two accesses to memory, which may be undesirable for some devices. */ #define in_8(addr) \ - ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) + ({ u8 __v = (*(__force volatile u8 *) (unsigned long)(addr)); __v; }) #define in_be16(addr) \ - ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) + ({ u16 __v = (*(__force volatile u16 *) (unsigned long)(addr)); __v; }) #define in_be32(addr) \ - ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) + ({ u32 __v = (*(__force volatile u32 *) (unsigned long)(addr)); __v; }) #define in_le16(addr) \ - ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) + ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (unsigned long)(addr)); __v; }) #define in_le32(addr) \ - ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) + ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (unsigned long)(addr)); __v; }) -#define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) -#define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) -#define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) -#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) -#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) +#define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b)) +#define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w)) +#define out_be32(addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l)) +#define out_le16(addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w)) +#define out_le32(addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(addr)) = cpu_to_le32(l)) #define raw_inb in_8 #define raw_inw in_be16 --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/timex.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/timex.h @@ -35,7 +35,7 @@ { if (mach_random_get_entropy) return mach_random_get_entropy(); - return 0; + return random_get_entropy_fallback(); } #define random_get_entropy random_get_entropy --- linux-oracle-5.4.0.orig/arch/m68k/include/asm/vga.h +++ linux-oracle-5.4.0/arch/m68k/include/asm/vga.h @@ -9,7 +9,7 @@ */ #ifndef CONFIG_PCI -#include +#include #include /* @@ -29,9 +29,9 @@ #define inw_p(port) 0 #define outb_p(port, val) do { } while (0) #define outw(port, val) do { } while (0) -#define readb raw_inb -#define writeb raw_outb -#define writew raw_outw +#define readb __raw_readb +#define writeb __raw_writeb +#define writew __raw_writew #endif /* CONFIG_PCI */ #endif /* _ASM_M68K_VGA_H */ --- linux-oracle-5.4.0.orig/arch/m68k/kernel/dma.c +++ linux-oracle-5.4.0/arch/m68k/kernel/dma.c @@ -61,8 +61,8 @@ #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */ -void arch_sync_dma_for_device(struct device *dev, phys_addr_t handle, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t handle, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_BIDIRECTIONAL: --- linux-oracle-5.4.0.orig/arch/m68k/kernel/early_printk.c +++ linux-oracle-5.4.0/arch/m68k/kernel/early_printk.c @@ -12,8 +12,9 @@ #include #include -extern void mvme16x_cons_write(struct console *co, - const char *str, unsigned count); + +#include "../mvme147/mvme147.h" +#include "../mvme16x/mvme16x.h" asmlinkage void __init debug_cons_nputs(const char *s, unsigned n); @@ -22,7 +23,9 @@ { #if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \ defined(CONFIG_COLDFIRE)) - if (MACH_IS_MVME16x) + if (MACH_IS_MVME147) + mvme147_scc_write(c, s, n); + else if (MACH_IS_MVME16x) mvme16x_cons_write(c, s, n); else debug_cons_nputs(s, n); --- linux-oracle-5.4.0.orig/arch/m68k/kernel/entry.S +++ linux-oracle-5.4.0/arch/m68k/kernel/entry.S @@ -160,9 +160,12 @@ jbsr syscall_trace RESTORE_SWITCH_STACK addql #4,%sp + addql #1,%d0 | optimization for cmpil #-1,%d0 + jeq ret_from_syscall movel %sp@(PT_OFF_ORIG_D0),%d0 cmpl #NR_syscalls,%d0 jcs syscall + jra ret_from_syscall badsys: movel #-ENOSYS,%sp@(PT_OFF_D0) jra ret_from_syscall @@ -179,6 +182,8 @@ movel %curptr@(TASK_STACK),%a1 tstb %a1@(TINFO_FLAGS+2) jge 1f + lea %sp@(SWITCH_STACK_SIZE),%a1 + movel %a1,%curptr@(TASK_THREAD+THREAD_ESP0) jbsr syscall_trace 1: RESTORE_SWITCH_STACK addql #4,%sp @@ -422,7 +427,9 @@ movec %a0,%dfc /* restore status register */ - movew %a1@(TASK_THREAD+THREAD_SR),%sr + movew %a1@(TASK_THREAD+THREAD_SR),%d0 + oriw #0x0700,%d0 + movew %d0,%sr rts --- linux-oracle-5.4.0.orig/arch/m68k/kernel/relocate_kernel.S +++ linux-oracle-5.4.0/arch/m68k/kernel/relocate_kernel.S @@ -26,7 +26,7 @@ lea %pc@(.Lcopy),%a4 2: addl #0x00000000,%a4 /* virt_to_phys() */ - .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 2b+2 .previous @@ -49,7 +49,7 @@ lea %pc@(.Lcont040),%a4 5: addl #0x00000000,%a4 /* virt_to_phys() */ - .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 5b+2 .previous --- linux-oracle-5.4.0.orig/arch/m68k/kernel/setup_mm.c +++ linux-oracle-5.4.0/arch/m68k/kernel/setup_mm.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -527,7 +528,7 @@ module_init(proc_hardware_init); #endif -void check_bugs(void) +void __init arch_cpu_finalize_init(void) { #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU) if (m68k_fputype == 0) { --- linux-oracle-5.4.0.orig/arch/m68k/kernel/setup_no.c +++ linux-oracle-5.4.0/arch/m68k/kernel/setup_no.c @@ -139,7 +139,8 @@ pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ", __bss_stop, memory_start, memory_start, memory_end); - memblock_add(memory_start, memory_end - memory_start); + memblock_add(_rambase, memory_end - _rambase); + memblock_reserve(_rambase, memory_start - _rambase); /* Keep a copy of command line */ *cmdline_p = &command_line[0]; --- linux-oracle-5.4.0.orig/arch/m68k/kernel/signal.c +++ linux-oracle-5.4.0/arch/m68k/kernel/signal.c @@ -448,7 +448,7 @@ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) { fpu_version = sc->sc_fpstate[0]; - if (CPU_IS_020_OR_030 && + if (CPU_IS_020_OR_030 && !regs->stkadj && regs->vector >= (VEC_FPBRUC * 4) && regs->vector <= (VEC_FPNAN * 4)) { /* Clear pending exception in 68882 idle frame */ @@ -511,7 +511,7 @@ if (!(CPU_IS_060 || CPU_IS_COLDFIRE)) context_size = fpstate[1]; fpu_version = fpstate[0]; - if (CPU_IS_020_OR_030 && + if (CPU_IS_020_OR_030 && !regs->stkadj && regs->vector >= (VEC_FPBRUC * 4) && regs->vector <= (VEC_FPNAN * 4)) { /* Clear pending exception in 68882 idle frame */ @@ -829,18 +829,24 @@ return 0; } +static inline struct pt_regs *rte_regs(struct pt_regs *regs) +{ + return (void *)regs + regs->stkadj; +} + static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) { + struct pt_regs *tregs = rte_regs(regs); sc->sc_mask = mask; sc->sc_usp = rdusp(); sc->sc_d0 = regs->d0; sc->sc_d1 = regs->d1; sc->sc_a0 = regs->a0; sc->sc_a1 = regs->a1; - sc->sc_sr = regs->sr; - sc->sc_pc = regs->pc; - sc->sc_formatvec = regs->format << 12 | regs->vector; + sc->sc_sr = tregs->sr; + sc->sc_pc = tregs->pc; + sc->sc_formatvec = tregs->format << 12 | tregs->vector; save_a5_state(sc, regs); save_fpu_state(sc, regs); } @@ -848,6 +854,7 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs) { struct switch_stack *sw = (struct switch_stack *)regs - 1; + struct pt_regs *tregs = rte_regs(regs); greg_t __user *gregs = uc->uc_mcontext.gregs; int err = 0; @@ -868,43 +875,50 @@ err |= __put_user(sw->a5, &gregs[13]); err |= __put_user(sw->a6, &gregs[14]); err |= __put_user(rdusp(), &gregs[15]); - err |= __put_user(regs->pc, &gregs[16]); - err |= __put_user(regs->sr, &gregs[17]); - err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec); + err |= __put_user(tregs->pc, &gregs[16]); + err |= __put_user(tregs->sr, &gregs[17]); + err |= __put_user((tregs->format << 12) | tregs->vector, &uc->uc_formatvec); err |= rt_save_fpu_state(uc, regs); return err; } static inline void __user * -get_sigframe(struct ksignal *ksig, size_t frame_size) +get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size) { unsigned long usp = sigsp(rdusp(), ksig); + unsigned long gap = 0; + + if (CPU_IS_020_OR_030 && tregs->format == 0xb) { + /* USP is unreliable so use worst-case value */ + gap = 256; + } - return (void __user *)((usp - frame_size) & -8UL); + return (void __user *)((usp - gap - frame_size) & -8UL); } static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; - int fsize = frame_extra_sizes(regs->format); + struct pt_regs *tregs = rte_regs(regs); + int fsize = frame_extra_sizes(tregs->format); struct sigcontext context; int err = 0, sig = ksig->sig; if (fsize < 0) { pr_debug("setup_frame: Unknown frame format %#x\n", - regs->format); + tregs->format); return -EFAULT; } - frame = get_sigframe(ksig, sizeof(*frame) + fsize); + frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize); if (fsize) err |= copy_to_user (frame + 1, regs + 1, fsize); err |= __put_user(sig, &frame->sig); - err |= __put_user(regs->vector, &frame->code); + err |= __put_user(tregs->vector, &frame->code); err |= __put_user(&frame->sc, &frame->psc); if (_NSIG_WORDS > 1) @@ -930,33 +944,27 @@ push_cache ((unsigned long) &frame->retcode); /* - * Set up registers for signal handler. All the state we are about - * to destroy is successfully copied to sigframe. - */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ksig->ka.sa.sa_handler; - adjustformat(regs); - - /* * This is subtle; if we build more than one sigframe, all but the * first one will see frame format 0 and have fsize == 0, so we won't * screw stkadj. */ - if (fsize) + if (fsize) { regs->stkadj = fsize; - - /* Prepare to skip over the extra stuff in the exception frame. */ - if (regs->stkadj) { - struct pt_regs *tregs = - (struct pt_regs *)((ulong)regs + regs->stkadj); + tregs = rte_regs(regs); pr_debug("Performing stackadjust=%04lx\n", regs->stkadj); - /* This must be copied with decreasing addresses to - handle overlaps. */ tregs->vector = 0; tregs->format = 0; - tregs->pc = regs->pc; tregs->sr = regs->sr; } + + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ + wrusp ((unsigned long) frame); + tregs->pc = (unsigned long) ksig->ka.sa.sa_handler; + adjustformat(regs); + return 0; } @@ -964,7 +972,8 @@ struct pt_regs *regs) { struct rt_sigframe __user *frame; - int fsize = frame_extra_sizes(regs->format); + struct pt_regs *tregs = rte_regs(regs); + int fsize = frame_extra_sizes(tregs->format); int err = 0, sig = ksig->sig; if (fsize < 0) { @@ -973,7 +982,7 @@ return -EFAULT; } - frame = get_sigframe(ksig, sizeof(*frame)); + frame = get_sigframe(ksig, tregs, sizeof(*frame)); if (fsize) err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize); @@ -1014,33 +1023,26 @@ push_cache ((unsigned long) &frame->retcode); /* - * Set up registers for signal handler. All the state we are about - * to destroy is successfully copied to sigframe. - */ - wrusp ((unsigned long) frame); - regs->pc = (unsigned long) ksig->ka.sa.sa_handler; - adjustformat(regs); - - /* * This is subtle; if we build more than one sigframe, all but the * first one will see frame format 0 and have fsize == 0, so we won't * screw stkadj. */ - if (fsize) + if (fsize) { regs->stkadj = fsize; - - /* Prepare to skip over the extra stuff in the exception frame. */ - if (regs->stkadj) { - struct pt_regs *tregs = - (struct pt_regs *)((ulong)regs + regs->stkadj); + tregs = rte_regs(regs); pr_debug("Performing stackadjust=%04lx\n", regs->stkadj); - /* This must be copied with decreasing addresses to - handle overlaps. */ tregs->vector = 0; tregs->format = 0; - tregs->pc = regs->pc; tregs->sr = regs->sr; } + + /* + * Set up registers for signal handler. All the state we are about + * to destroy is successfully copied to sigframe. + */ + wrusp ((unsigned long) frame); + tregs->pc = (unsigned long) ksig->ka.sa.sa_handler; + adjustformat(regs); return 0; } --- linux-oracle-5.4.0.orig/arch/m68k/kernel/sys_m68k.c +++ linux-oracle-5.4.0/arch/m68k/kernel/sys_m68k.c @@ -388,6 +388,8 @@ ret = -EPERM; if (!capable(CAP_SYS_ADMIN)) goto out; + + down_read(¤t->mm->mmap_sem); } else { struct vm_area_struct *vma; --- linux-oracle-5.4.0.orig/arch/m68k/kernel/traps.c +++ linux-oracle-5.4.0/arch/m68k/kernel/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -550,7 +551,8 @@ errorcode |= 2; if (mmusr & (MMU_I | MMU_WP)) { - if (ssw & 4) { + /* We might have an exception table for this PC */ + if (ssw & 4 && !search_exception_tables(fp->ptregs.pc)) { pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n", ssw & RW ? "read" : "write", fp->un.fmtb.daddr, @@ -1139,7 +1141,7 @@ pr_crit("%s: %08x\n", str, nr); show_registers(fp); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } asmlinkage void set_esp0(unsigned long ssp) @@ -1153,7 +1155,7 @@ */ asmlinkage void fpsp040_die(void) { - do_exit(SIGSEGV); + force_sigsegv(SIGSEGV); } #ifdef CONFIG_M68KFPU_EMU --- linux-oracle-5.4.0.orig/arch/m68k/mac/config.c +++ linux-oracle-5.4.0/arch/m68k/mac/config.c @@ -59,7 +59,6 @@ extern void iop_init(void); extern void via_init(void); extern void via_init_clock(irq_handler_t func); -extern void via_flush_cache(void); extern void oss_init(void); extern void psc_init(void); extern void baboon_init(void); @@ -130,21 +129,6 @@ return unknown; } -/* - * Flip into 24bit mode for an instant - flushes the L2 cache card. We - * have to disable interrupts for this. Our IRQ handlers will crap - * themselves if they take an IRQ in 24bit mode! - */ - -static void mac_cache_card_flush(int writeback) -{ - unsigned long flags; - - local_irq_save(flags); - via_flush_cache(); - local_irq_restore(flags); -} - void __init config_mac(void) { if (!MACH_IS_MAC) @@ -175,9 +159,8 @@ * not. */ - if (macintosh_config->ident == MAC_MODEL_IICI - || macintosh_config->ident == MAC_MODEL_IIFX) - mach_l2_flush = mac_cache_card_flush; + if (macintosh_config->ident == MAC_MODEL_IICI) + mach_l2_flush = via_l2_flush; } --- linux-oracle-5.4.0.orig/arch/m68k/mac/iop.c +++ linux-oracle-5.4.0/arch/m68k/mac/iop.c @@ -183,7 +183,7 @@ static __inline__ void iop_stop(volatile struct mac_iop *iop) { - iop->status_ctrl &= ~IOP_RUN; + iop->status_ctrl = IOP_AUTOINC; } static __inline__ void iop_start(volatile struct mac_iop *iop) @@ -191,14 +191,9 @@ iop->status_ctrl = IOP_RUN | IOP_AUTOINC; } -static __inline__ void iop_bypass(volatile struct mac_iop *iop) -{ - iop->status_ctrl |= IOP_BYPASS; -} - static __inline__ void iop_interrupt(volatile struct mac_iop *iop) { - iop->status_ctrl |= IOP_IRQ; + iop->status_ctrl = IOP_IRQ | IOP_RUN | IOP_AUTOINC; } static int iop_alive(volatile struct mac_iop *iop) @@ -244,7 +239,6 @@ } else { iop_base[IOP_NUM_SCC] = (struct mac_iop *) SCC_IOP_BASE_QUADRA; } - iop_base[IOP_NUM_SCC]->status_ctrl = 0x87; iop_scc_present = 1; } else { iop_base[IOP_NUM_SCC] = NULL; @@ -256,7 +250,7 @@ } else { iop_base[IOP_NUM_ISM] = (struct mac_iop *) ISM_IOP_BASE_QUADRA; } - iop_base[IOP_NUM_ISM]->status_ctrl = 0; + iop_stop(iop_base[IOP_NUM_ISM]); iop_ism_present = 1; } else { iop_base[IOP_NUM_ISM] = NULL; @@ -416,7 +410,8 @@ msg->status = IOP_MSGSTATUS_UNUSED; msg = msg->next; iop_send_queue[iop_num][chan] = msg; - if (msg) iop_do_send(msg); + if (msg && iop_readb(iop, IOP_ADDR_SEND_STATE + chan) == IOP_MSG_IDLE) + iop_do_send(msg); } /* @@ -490,16 +485,12 @@ if (!(q = iop_send_queue[iop_num][chan])) { iop_send_queue[iop_num][chan] = msg; + iop_do_send(msg); } else { while (q->next) q = q->next; q->next = msg; } - if (iop_readb(iop_base[iop_num], - IOP_ADDR_SEND_STATE + chan) == IOP_MSG_IDLE) { - iop_do_send(msg); - } - return 0; } --- linux-oracle-5.4.0.orig/arch/m68k/mac/misc.c +++ linux-oracle-5.4.0/arch/m68k/mac/misc.c @@ -452,30 +452,18 @@ void mac_reset(void) { - if (macintosh_config->adb_type == MAC_ADB_II && - macintosh_config->ident != MAC_MODEL_SE30) { - /* need ROMBASE in booter */ - /* indeed, plus need to MAP THE ROM !! */ - - if (mac_bi_data.rombase == 0) - mac_bi_data.rombase = 0x40800000; - - /* works on some */ - rom_reset = (void *) (mac_bi_data.rombase + 0xa); - - local_irq_disable(); - rom_reset(); #ifdef CONFIG_ADB_CUDA - } else if (macintosh_config->adb_type == MAC_ADB_EGRET || - macintosh_config->adb_type == MAC_ADB_CUDA) { + if (macintosh_config->adb_type == MAC_ADB_EGRET || + macintosh_config->adb_type == MAC_ADB_CUDA) { cuda_restart(); + } else #endif #ifdef CONFIG_ADB_PMU - } else if (macintosh_config->adb_type == MAC_ADB_PB2) { + if (macintosh_config->adb_type == MAC_ADB_PB2) { pmu_restart(); + } else #endif - } else if (CPU_IS_030) { - + if (CPU_IS_030) { /* 030-specific reset routine. The idea is general, but the * specific registers to reset are '030-specific. Until I * have a non-030 machine, I can't test anything else. @@ -523,6 +511,18 @@ "jmp %/a0@\n\t" /* jump to the reset vector */ ".chip 68k" : : "r" (offset), "a" (rombase) : "a0"); + } else { + /* need ROMBASE in booter */ + /* indeed, plus need to MAP THE ROM !! */ + + if (mac_bi_data.rombase == 0) + mac_bi_data.rombase = 0x40800000; + + /* works on some */ + rom_reset = (void *)(mac_bi_data.rombase + 0xa); + + local_irq_disable(); + rom_reset(); } /* should never get here */ --- linux-oracle-5.4.0.orig/arch/m68k/mac/via.c +++ linux-oracle-5.4.0/arch/m68k/mac/via.c @@ -294,10 +294,14 @@ * the system into 24-bit mode for an instant. */ -void via_flush_cache(void) +void via_l2_flush(int writeback) { + unsigned long flags; + + local_irq_save(flags); via2[gBufB] &= ~VIA2B_vMode32; via2[gBufB] |= VIA2B_vMode32; + local_irq_restore(flags); } /* --- linux-oracle-5.4.0.orig/arch/m68k/mm/fault.c +++ linux-oracle-5.4.0/arch/m68k/mm/fault.c @@ -48,7 +48,7 @@ pr_alert("Unable to handle kernel access"); pr_cont(" at virtual address %p\n", addr); die_if_kernel("Oops", regs, 0 /*error_code*/); - do_exit(SIGKILL); + make_task_dead(SIGKILL); } return 1; --- linux-oracle-5.4.0.orig/arch/m68k/mm/init.c +++ linux-oracle-5.4.0/arch/m68k/mm/init.c @@ -89,7 +89,7 @@ * page_alloc get different views of the world. */ unsigned long end_mem = memory_end & PAGE_MASK; - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; high_memory = (void *) end_mem; @@ -103,8 +103,8 @@ */ set_fs (USER_DS); - zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; - free_area_init(zones_size); + max_zone_pfn[ZONE_DMA] = end_mem >> PAGE_SHIFT; + free_area_init(max_zone_pfn); } #endif /* CONFIG_MMU */ --- linux-oracle-5.4.0.orig/arch/m68k/mm/mcfmmu.c +++ linux-oracle-5.4.0/arch/m68k/mm/mcfmmu.c @@ -39,7 +39,7 @@ pte_t *pg_table; unsigned long address, size; unsigned long next_pgtable, bootmem_end; - unsigned long zones_size[MAX_NR_ZONES]; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; enum zone_type zone; int i; @@ -80,11 +80,8 @@ } current->mm = NULL; - - for (zone = 0; zone < MAX_NR_ZONES; zone++) - zones_size[zone] = 0x0; - zones_size[ZONE_DMA] = num_pages; - free_area_init(zones_size); + max_zone_pfn[ZONE_DMA] = PFN_DOWN(_ramend); + free_area_init(max_zone_pfn); } int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word) @@ -164,7 +161,7 @@ m68k_memory[0].addr = _rambase; m68k_memory[0].size = _ramend - _rambase; - memblock_add(m68k_memory[0].addr, m68k_memory[0].size); + memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0); /* compute total pages in system */ num_pages = PFN_DOWN(_ramend - _rambase); --- linux-oracle-5.4.0.orig/arch/m68k/mm/motorola.c +++ linux-oracle-5.4.0/arch/m68k/mm/motorola.c @@ -213,7 +213,7 @@ */ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; unsigned long min_addr, max_addr; unsigned long addr; int i; @@ -234,7 +234,7 @@ min_addr = m68k_memory[0].addr; max_addr = min_addr + m68k_memory[0].size; - memblock_add(m68k_memory[0].addr, m68k_memory[0].size); + memblock_add_node(m68k_memory[0].addr, m68k_memory[0].size, 0); for (i = 1; i < m68k_num_memory;) { if (m68k_memory[i].addr < min_addr) { printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n", @@ -245,7 +245,7 @@ (m68k_num_memory - i) * sizeof(struct m68k_mem_info)); continue; } - memblock_add(m68k_memory[i].addr, m68k_memory[i].size); + memblock_add_node(m68k_memory[i].addr, m68k_memory[i].size, i); addr = m68k_memory[i].addr + m68k_memory[i].size; if (addr > max_addr) max_addr = addr; @@ -296,12 +296,11 @@ #ifdef DEBUG printk ("before free_area_init\n"); #endif - for (i = 0; i < m68k_num_memory; i++) { - zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT; - free_area_init_node(i, zones_size, - m68k_memory[i].addr >> PAGE_SHIFT, NULL); + for (i = 0; i < m68k_num_memory; i++) if (node_present_pages(i)) node_set_state(i, N_NORMAL_MEMORY); - } + + max_zone_pfn[ZONE_DMA] = memblock_end_of_DRAM(); + free_area_init(max_zone_pfn); } --- linux-oracle-5.4.0.orig/arch/m68k/mm/sun3mmu.c +++ linux-oracle-5.4.0/arch/m68k/mm/sun3mmu.c @@ -42,7 +42,7 @@ unsigned long address; unsigned long next_pgtable; unsigned long bootmem_end; - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; unsigned long size; empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); @@ -89,14 +89,10 @@ current->mm = NULL; /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ - zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; + max_zone_pfn[ZONE_DMA] = ((unsigned long)high_memory) >> PAGE_SHIFT; /* I really wish I knew why the following change made things better... -- Sam */ -/* free_area_init(zones_size); */ - free_area_init_node(0, zones_size, - (__pa(PAGE_OFFSET) >> PAGE_SHIFT) + 1, NULL); + free_area_init(max_zone_pfn); } - - --- linux-oracle-5.4.0.orig/arch/m68k/mvme147/config.c +++ linux-oracle-5.4.0/arch/m68k/mvme147/config.c @@ -36,6 +36,7 @@ #include #include +#include "mvme147.h" static void mvme147_get_model(char *model); extern void mvme147_sched_init(irq_handler_t handler); @@ -117,8 +118,10 @@ unsigned long flags; local_irq_save(flags); - m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; - m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF; + m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF | PCC_TIMER_COC_EN | + PCC_TIMER_TIC_EN; + m147_pcc->t1_int_cntrl = PCC_INT_ENAB | PCC_TIMER_INT_CLR | + PCC_LEVEL_TIMER1; clk_total += PCC_TIMER_CYCLES; timer_routine(0, NULL); local_irq_restore(flags); @@ -136,10 +139,10 @@ /* Init the clock with a value */ /* The clock counter increments until 0xFFFF then reloads */ m147_pcc->t1_preload = PCC_TIMER_PRELOAD; - m147_pcc->t1_cntrl = 0x0; /* clear timer */ - m147_pcc->t1_cntrl = 0x3; /* start timer */ - m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR; /* clear pending ints */ - m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1; + m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF | PCC_TIMER_COC_EN | + PCC_TIMER_TIC_EN; + m147_pcc->t1_int_cntrl = PCC_INT_ENAB | PCC_TIMER_INT_CLR | + PCC_LEVEL_TIMER1; clocksource_register_hz(&mvme147_clk, PCC_TIMER_CLOCK_FREQ); } @@ -187,3 +190,32 @@ } return 0; } + +static void scc_delay(void) +{ + __asm__ __volatile__ ("nop; nop;"); +} + +static void scc_write(char ch) +{ + do { + scc_delay(); + } while (!(in_8(M147_SCC_A_ADDR) & BIT(2))); + scc_delay(); + out_8(M147_SCC_A_ADDR, 8); + scc_delay(); + out_8(M147_SCC_A_ADDR, ch); +} + +void mvme147_scc_write(struct console *co, const char *str, unsigned int count) +{ + unsigned long flags; + + local_irq_save(flags); + while (count--) { + if (*str == '\n') + scc_write('\r'); + scc_write(*str++); + } + local_irq_restore(flags); +} --- linux-oracle-5.4.0.orig/arch/m68k/mvme147/mvme147.h +++ linux-oracle-5.4.0/arch/m68k/mvme147/mvme147.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +struct console; + +/* config.c */ +void mvme147_scc_write(struct console *co, const char *str, unsigned int count); --- linux-oracle-5.4.0.orig/arch/m68k/mvme16x/config.c +++ linux-oracle-5.4.0/arch/m68k/mvme16x/config.c @@ -39,6 +39,8 @@ #include #include +#include "mvme16x.h" + extern t_bdid mvme_bdid; static MK48T08ptr_t volatile rtc = (MK48T08ptr_t)MVME_RTC_BASE; @@ -368,6 +370,7 @@ #define PCCTOVR1_COC_EN 0x02 #define PCCTOVR1_OVR_CLR 0x04 +#define PCCTIC1_INT_LEVEL 6 #define PCCTIC1_INT_CLR 0x08 #define PCCTIC1_INT_EN 0x10 @@ -377,8 +380,8 @@ unsigned long flags; local_irq_save(flags); - out_8(PCCTIC1, in_8(PCCTIC1) | PCCTIC1_INT_CLR); - out_8(PCCTOVR1, PCCTOVR1_OVR_CLR); + out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN); + out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL); clk_total += PCC_TIMER_CYCLES; timer_routine(0, NULL); local_irq_restore(flags); @@ -392,14 +395,15 @@ int irq; /* Using PCCchip2 or MC2 chip tick timer 1 */ - out_be32(PCCTCNT1, 0); - out_be32(PCCTCMP1, PCC_TIMER_CYCLES); - out_8(PCCTOVR1, in_8(PCCTOVR1) | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN); - out_8(PCCTIC1, PCCTIC1_INT_EN | 6); if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, IRQF_TIMER, "timer", timer_routine)) panic ("Couldn't register timer int"); + out_be32(PCCTCNT1, 0); + out_be32(PCCTCMP1, PCC_TIMER_CYCLES); + out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN); + out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL); + clocksource_register_hz(&mvme16x_clk, PCC_TIMER_CLOCK_FREQ); if (brdno == 0x0162 || brdno == 0x172) --- linux-oracle-5.4.0.orig/arch/m68k/mvme16x/mvme16x.h +++ linux-oracle-5.4.0/arch/m68k/mvme16x/mvme16x.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +struct console; + +/* config.c */ +void mvme16x_cons_write(struct console *co, const char *str, unsigned count); --- linux-oracle-5.4.0.orig/arch/m68k/q40/config.c +++ linux-oracle-5.4.0/arch/m68k/q40/config.c @@ -264,6 +264,7 @@ { int tmp = Q40_RTC_CTRL; + pll->pll_ctrl = 0; pll->pll_value = tmp & Q40_RTC_PLL_MASK; if (tmp & Q40_RTC_PLL_SIGN) pll->pll_value = -pll->pll_value; --- linux-oracle-5.4.0.orig/arch/microblaze/Kconfig +++ linux-oracle-5.4.0/arch/microblaze/Kconfig @@ -32,7 +32,6 @@ select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER - select HAVE_MEMBLOCK_NODE_MAP select HAVE_OPROFILE select HAVE_PCI select IRQ_DOMAIN --- linux-oracle-5.4.0.orig/arch/microblaze/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/microblaze/include/asm/uaccess.h @@ -171,27 +171,27 @@ #define __get_user(x, ptr) \ ({ \ - unsigned long __gu_val = 0; \ long __gu_err; \ switch (sizeof(*(ptr))) { \ case 1: \ - __get_user_asm("lbu", (ptr), __gu_val, __gu_err); \ + __get_user_asm("lbu", (ptr), x, __gu_err); \ break; \ case 2: \ - __get_user_asm("lhu", (ptr), __gu_val, __gu_err); \ + __get_user_asm("lhu", (ptr), x, __gu_err); \ break; \ case 4: \ - __get_user_asm("lw", (ptr), __gu_val, __gu_err); \ + __get_user_asm("lw", (ptr), x, __gu_err); \ break; \ - case 8: \ - __gu_err = __copy_from_user(&__gu_val, ptr, 8); \ - if (__gu_err) \ - __gu_err = -EFAULT; \ + case 8: { \ + __u64 __x = 0; \ + __gu_err = raw_copy_from_user(&__x, ptr, 8) ? \ + -EFAULT : 0; \ + (x) = (typeof(x))(typeof((x) - (x)))__x; \ break; \ + } \ default: \ /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\ } \ - x = (__force __typeof__(*(ptr))) __gu_val; \ __gu_err; \ }) --- linux-oracle-5.4.0.orig/arch/microblaze/kernel/Makefile +++ linux-oracle-5.4.0/arch/microblaze/kernel/Makefile @@ -7,7 +7,6 @@ # Do not trace early boot code and low level code CFLAGS_REMOVE_timer.o = -pg CFLAGS_REMOVE_intc.o = -pg -CFLAGS_REMOVE_early_printk.o = -pg CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_process.o = -pg endif --- linux-oracle-5.4.0.orig/arch/microblaze/kernel/cpu/cache.c +++ linux-oracle-5.4.0/arch/microblaze/kernel/cpu/cache.c @@ -92,7 +92,8 @@ #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size) \ do { \ int align = ~(cache_line_length - 1); \ - end = min(start + cache_size, end); \ + if (start < UINT_MAX - cache_size) \ + end = min(start + cache_size, end); \ start &= align; \ } while (0) --- linux-oracle-5.4.0.orig/arch/microblaze/kernel/cpu/cpuinfo-static.c +++ linux-oracle-5.4.0/arch/microblaze/kernel/cpu/cpuinfo-static.c @@ -18,7 +18,7 @@ static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER; #define err_printk(x) \ - early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n"); + pr_err("ERROR: Microblaze " x "-different for kernel and DTS\n"); void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu) { --- linux-oracle-5.4.0.orig/arch/microblaze/kernel/dma.c +++ linux-oracle-5.4.0/arch/microblaze/kernel/dma.c @@ -15,7 +15,7 @@ #include #include -static void __dma_sync(struct device *dev, phys_addr_t paddr, size_t size, +static void __dma_sync(phys_addr_t paddr, size_t size, enum dma_data_direction direction) { switch (direction) { @@ -31,14 +31,14 @@ } } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - __dma_sync(dev, paddr, size, dir); + __dma_sync(paddr, size, dir); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - __dma_sync(dev, paddr, size, dir); + __dma_sync(paddr, size, dir); } --- linux-oracle-5.4.0.orig/arch/microblaze/kernel/exceptions.c +++ linux-oracle-5.4.0/arch/microblaze/kernel/exceptions.c @@ -44,10 +44,10 @@ pr_warn("Oops: %s, sig: %ld\n", str, err); show_regs(fp); spin_unlock_irq(&die_lock); - /* do_exit() should take care of panic'ing from an interrupt + /* make_task_dead() should take care of panic'ing from an interrupt * context so we don't handle it here */ - do_exit(err); + make_task_dead(err); } /* for user application debugging */ --- linux-oracle-5.4.0.orig/arch/microblaze/mm/init.c +++ linux-oracle-5.4.0/arch/microblaze/mm/init.c @@ -108,7 +108,7 @@ #endif /* We don't have holes in memory map */ - free_area_init_nodes(zones_size); + free_area_init(zones_size); } void __init setup_memory(void) @@ -276,11 +276,6 @@ { unsigned int kstart, ksize; - if (!memblock.reserved.cnt) { - pr_emerg("Error memory count\n"); - machine_restart(NULL); - } - if ((u32) memblock.memory.regions[0].size < 0x400000) { pr_emerg("Memory must be greater than 4MB\n"); machine_restart(NULL); --- linux-oracle-5.4.0.orig/arch/mips/Kconfig +++ linux-oracle-5.4.0/arch/mips/Kconfig @@ -5,6 +5,7 @@ select ARCH_32BIT_OFF_T if !64BIT select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT select ARCH_CLOCKSOURCE_DATA + select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_SUPPORTS_UPROBES @@ -46,7 +47,8 @@ select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES select HAVE_ASM_MODVERSIONS - select HAVE_EBPF_JIT if (!CPU_MICROMIPS) + select HAVE_CBPF_JIT if !64BIT && !CPU_MICROMIPS + select HAVE_EBPF_JIT if 64BIT && !CPU_MICROMIPS && TARGET_ISA_REV >= 2 select HAVE_CONTEXT_TRACKING select HAVE_COPY_THREAD_TLS select HAVE_C_RECORDMCOUNT @@ -66,7 +68,6 @@ select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_LD_DEAD_CODE_DATA_ELIMINATION - select HAVE_MEMBLOCK_NODE_MAP select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_OPROFILE @@ -293,6 +294,9 @@ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK + select SYS_HAS_CPU_BMIPS32_3300 + select SYS_HAS_CPU_BMIPS4350 + select SYS_HAS_CPU_BMIPS4380 select SWAP_IO_SPACE select GPIOLIB select HAVE_CLK @@ -862,6 +866,7 @@ select I8253 select I8259 select ISA + select MIPS_L1_CACHE_SHIFT_6 select SWAP_IO_SPACE if CPU_BIG_ENDIAN select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 @@ -1391,6 +1396,7 @@ select WEAK_REORDERING_BEYOND_LLSC select MIPS_PGD_C0_CONTEXT select MIPS_L1_CACHE_SHIFT_6 + select MIPS_FP_SUPPORT select GPIOLIB select SWIOTLB help @@ -3053,7 +3059,7 @@ config PGTABLE_LEVELS int default 4 if PAGE_SIZE_4KB && MIPS_VA_BITS_48 - default 3 if 64BIT && !PAGE_SIZE_64KB + default 3 if 64BIT && (!PAGE_SIZE_64KB || MIPS_VA_BITS_48) default 2 config MIPS_AUTO_PFN_OFFSET --- linux-oracle-5.4.0.orig/arch/mips/Makefile +++ linux-oracle-5.4.0/arch/mips/Makefile @@ -272,7 +272,7 @@ ifdef CONFIG_64BIT ifndef KBUILD_SYM32 ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0) - KBUILD_SYM32 = y + KBUILD_SYM32 = $(call cc-option-yn, -msym32) endif endif @@ -285,12 +285,23 @@ endif endif +# When linking a 32-bit executable the LLVM linker cannot cope with a +# 32-bit load address that has been sign-extended to 64 bits. Simply +# remove the upper 32 bits then, as it is safe to do so with other +# linkers. +ifdef CONFIG_64BIT + load-ld = $(load-y) +else + load-ld = $(subst 0xffffffff,0x,$(load-y)) +endif + KBUILD_AFLAGS += $(cflags-y) KBUILD_CFLAGS += $(cflags-y) -KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) +KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) -DLINKER_LOAD_ADDRESS=$(load-ld) KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ + LINKER_LOAD_ADDRESS=$(load-ld) \ VMLINUX_ENTRY_ADDRESS=$(entry-y) \ PLATFORM="$(platform-y)" \ ITS_INPUTS="$(its-y)" @@ -309,7 +320,7 @@ ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ - egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ + egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') endif --- linux-oracle-5.4.0.orig/arch/mips/Makefile.postlink +++ linux-oracle-5.4.0/arch/mips/Makefile.postlink @@ -12,7 +12,7 @@ include scripts/Kbuild.include CMD_RELOCS = arch/mips/boot/tools/relocs -quiet_cmd_relocs = RELOCS $@ +quiet_cmd_relocs = RELOCS $@ cmd_relocs = $(CMD_RELOCS) $@ # `@true` prevents complaint when there is nothing to be done --- linux-oracle-5.4.0.orig/arch/mips/alchemy/board-xxs1500.c +++ linux-oracle-5.4.0/arch/mips/alchemy/board-xxs1500.c @@ -18,6 +18,7 @@ #include #include #include +#include #include const char *get_system_type(void) --- linux-oracle-5.4.0.orig/arch/mips/alchemy/common/clock.c +++ linux-oracle-5.4.0/arch/mips/alchemy/common/clock.c @@ -152,6 +152,7 @@ { struct clk_init_data id; struct clk_hw *h; + struct clk *clk; h = kzalloc(sizeof(*h), GFP_KERNEL); if (!h) @@ -164,7 +165,13 @@ id.ops = &alchemy_clkops_cpu; h->init = &id; - return clk_register(NULL, h); + clk = clk_register(NULL, h); + if (IS_ERR(clk)) { + pr_err("failed to register clock\n"); + kfree(h); + } + + return clk; } /* AUXPLLs ************************************************************/ --- linux-oracle-5.4.0.orig/arch/mips/alchemy/devboards/db1000.c +++ linux-oracle-5.4.0/arch/mips/alchemy/devboards/db1000.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -165,14 +164,10 @@ /******************************************************************************/ +#ifdef CONFIG_MMC_AU1X static irqreturn_t db1100_mmc_cd(int irq, void *ptr) { - void (*mmc_cd)(struct mmc_host *, unsigned long); - /* link against CONFIG_MMC=m */ - mmc_cd = symbol_get(mmc_detect_change); - mmc_cd(ptr, msecs_to_jiffies(500)); - symbol_put(mmc_detect_change); - + mmc_detect_change(ptr, msecs_to_jiffies(500)); return IRQ_HANDLED; } @@ -375,6 +370,7 @@ .num_resources = ARRAY_SIZE(au1100_mmc1_res), .resource = au1100_mmc1_res, }; +#endif /* CONFIG_MMC_AU1X */ /******************************************************************************/ @@ -438,8 +434,10 @@ static struct platform_device *db1100_devs[] = { &au1100_lcd_device, +#ifdef CONFIG_MMC_AU1X &db1100_mmc0_dev, &db1100_mmc1_dev, +#endif }; int __init db1000_dev_setup(void) --- linux-oracle-5.4.0.orig/arch/mips/alchemy/devboards/db1200.c +++ linux-oracle-5.4.0/arch/mips/alchemy/devboards/db1200.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -327,6 +326,7 @@ /**********************************************************************/ +#ifdef CONFIG_MMC_AU1X /* SD carddetects: they're supposed to be edge-triggered, but ack * doesn't seem to work (CPLD Rev 2). Instead, the screaming one * is disabled and its counterpart enabled. The 200ms timeout is @@ -340,14 +340,7 @@ static irqreturn_t db1200_mmc_cdfn(int irq, void *ptr) { - void (*mmc_cd)(struct mmc_host *, unsigned long); - - /* link against CONFIG_MMC=m */ - mmc_cd = symbol_get(mmc_detect_change); - if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(200)); - symbol_put(mmc_detect_change); - } + mmc_detect_change(ptr, msecs_to_jiffies(200)); msleep(100); /* debounce */ if (irq == DB1200_SD0_INSERT_INT) @@ -431,14 +424,7 @@ static irqreturn_t pb1200_mmc1_cdfn(int irq, void *ptr) { - void (*mmc_cd)(struct mmc_host *, unsigned long); - - /* link against CONFIG_MMC=m */ - mmc_cd = symbol_get(mmc_detect_change); - if (mmc_cd) { - mmc_cd(ptr, msecs_to_jiffies(200)); - symbol_put(mmc_detect_change); - } + mmc_detect_change(ptr, msecs_to_jiffies(200)); msleep(100); /* debounce */ if (irq == PB1200_SD1_INSERT_INT) @@ -599,6 +585,7 @@ .num_resources = ARRAY_SIZE(au1200_mmc1_res), .resource = au1200_mmc1_res, }; +#endif /* CONFIG_MMC_AU1X */ /**********************************************************************/ @@ -766,7 +753,9 @@ static struct platform_device *db1200_devs[] __initdata = { NULL, /* PSC0, selected by S6.8 */ &db1200_ide_dev, +#ifdef CONFIG_MMC_AU1X &db1200_mmc0_dev, +#endif &au1200_lcd_dev, &db1200_eth_dev, &db1200_nand_dev, @@ -777,7 +766,9 @@ }; static struct platform_device *pb1200_devs[] __initdata = { +#ifdef CONFIG_MMC_AU1X &pb1200_mmc1_dev, +#endif }; /* Some peripheral base addresses differ on the PB1200 */ @@ -856,7 +847,7 @@ i2c_register_board_info(0, db1200_i2c_devs, ARRAY_SIZE(db1200_i2c_devs)); spi_register_board_info(db1200_spi_devs, - ARRAY_SIZE(db1200_i2c_devs)); + ARRAY_SIZE(db1200_spi_devs)); /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) --- linux-oracle-5.4.0.orig/arch/mips/alchemy/devboards/db1300.c +++ linux-oracle-5.4.0/arch/mips/alchemy/devboards/db1300.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -451,6 +450,7 @@ /**********************************************************************/ +#ifdef CONFIG_MMC_AU1X static irqreturn_t db1300_mmc_cd(int irq, void *ptr) { disable_irq_nosync(irq); @@ -459,14 +459,7 @@ static irqreturn_t db1300_mmc_cdfn(int irq, void *ptr) { - void (*mmc_cd)(struct mmc_host *, unsigned long); - - /* link against CONFIG_MMC=m. We can only be called once MMC core has - * initialized the controller, so symbol_get() should always succeed. - */ - mmc_cd = symbol_get(mmc_detect_change); - mmc_cd(ptr, msecs_to_jiffies(200)); - symbol_put(mmc_detect_change); + mmc_detect_change(ptr, msecs_to_jiffies(200)); msleep(100); /* debounce */ if (irq == DB1300_SD1_INSERT_INT) @@ -640,6 +633,7 @@ .resource = au1300_sd0_res, .num_resources = ARRAY_SIZE(au1300_sd0_res), }; +#endif /* CONFIG_MMC_AU1X */ /**********************************************************************/ @@ -777,8 +771,10 @@ &db1300_5waysw_dev, &db1300_nand_dev, &db1300_ide_dev, +#ifdef CONFIG_MMC_AU1X &db1300_sd0_dev, &db1300_sd1_dev, +#endif &db1300_lcd_dev, &db1300_ac97_dev, &db1300_i2s_dev, --- linux-oracle-5.4.0.orig/arch/mips/alchemy/devboards/db1550.c +++ linux-oracle-5.4.0/arch/mips/alchemy/devboards/db1550.c @@ -588,7 +588,7 @@ i2c_register_board_info(0, db1550_i2c_devs, ARRAY_SIZE(db1550_i2c_devs)); spi_register_board_info(db1550_spi_devs, - ARRAY_SIZE(db1550_i2c_devs)); + ARRAY_SIZE(db1550_spi_devs)); c = clk_get(NULL, "psc0_intclk"); if (!IS_ERR(c)) { --- linux-oracle-5.4.0.orig/arch/mips/bcm47xx/Kconfig +++ linux-oracle-5.4.0/arch/mips/bcm47xx/Kconfig @@ -27,6 +27,7 @@ select BCMA select BCMA_HOST_SOC select BCMA_DRIVER_MIPS + select BCMA_DRIVER_PCI if PCI select BCMA_DRIVER_PCI_HOSTMODE if PCI select BCMA_DRIVER_GPIO default y --- linux-oracle-5.4.0.orig/arch/mips/bcm47xx/prom.c +++ linux-oracle-5.4.0/arch/mips/bcm47xx/prom.c @@ -85,7 +85,7 @@ pr_debug("Assume 128MB RAM\n"); break; } - if (!memcmp(prom_init, prom_init + mem, 32)) + if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32)) break; } lowmem = mem; @@ -162,7 +162,7 @@ off = EXTVBASE + __pa(off); for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { - if (!memcmp(prom_init, (void *)(off + extmem), 16)) + if (!memcmp((void *)prom_init, (void *)(off + extmem), 16)) break; } extmem -= lowmem; --- linux-oracle-5.4.0.orig/arch/mips/bcm63xx/clk.c +++ linux-oracle-5.4.0/arch/mips/bcm63xx/clk.c @@ -361,6 +361,8 @@ */ int clk_enable(struct clk *clk) { + if (!clk) + return 0; mutex_lock(&clocks_mutex); clk_enable_unlocked(clk); mutex_unlock(&clocks_mutex); @@ -381,6 +383,18 @@ EXPORT_SYMBOL(clk_disable); +struct clk *clk_get_parent(struct clk *clk) +{ + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + unsigned long clk_get_rate(struct clk *clk) { if (!clk) --- linux-oracle-5.4.0.orig/arch/mips/bmips/dma.c +++ linux-oracle-5.4.0/arch/mips/bmips/dma.c @@ -64,7 +64,9 @@ return dma_addr; } -void arch_sync_dma_for_cpu_all(struct device *dev) +bool bmips_rac_flush_disable; + +void arch_sync_dma_for_cpu_all(void) { void __iomem *cbr = BMIPS_GET_CBR(); u32 cfg; @@ -74,6 +76,9 @@ boot_cpu_type() != CPU_BMIPS4380) return; + if (unlikely(bmips_rac_flush_disable)) + return; + /* Flush stale data out of the readahead cache */ cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); --- linux-oracle-5.4.0.orig/arch/mips/bmips/setup.c +++ linux-oracle-5.4.0/arch/mips/bmips/setup.c @@ -34,6 +34,8 @@ #define REG_BCM6328_OTP ((void __iomem *)CKSEG1ADDR(0x1000062c)) #define BCM6328_TP1_DISABLED BIT(9) +extern bool bmips_rac_flush_disable; + static const unsigned long kbase = VMLINUX_LOAD_ADDRESS & 0xfff00000; struct bmips_quirk { @@ -103,6 +105,13 @@ * disable SMP for now */ bmips_smp_enabled = 0; + + /* + * RAC flush causes kernel panics on BCM6358 when booting from TP1 + * because the bootloader is not initializing it properly. + */ + bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) || + !!BMIPS_GET_CBR(); } static void bcm6368_quirks(void) @@ -167,7 +176,7 @@ dtb = phys_to_virt(fw_arg2); else if (fw_passed_dtb) /* UHI interface or appended dtb */ dtb = (void *)fw_passed_dtb; - else if (__dtb_start != __dtb_end) + else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start; else panic("no dtb found"); --- linux-oracle-5.4.0.orig/arch/mips/boot/Makefile +++ linux-oracle-5.4.0/arch/mips/boot/Makefile @@ -123,7 +123,7 @@ targets += vmlinux.its targets += vmlinux.gz.its targets += vmlinux.bz2.its -targets += vmlinux.lzmo.its +targets += vmlinux.lzma.its targets += vmlinux.lzo.its quiet_cmd_cpp_its_S = ITS $@ --- linux-oracle-5.4.0.orig/arch/mips/boot/compressed/Makefile +++ linux-oracle-5.4.0/arch/mips/boot/compressed/Makefile @@ -29,8 +29,11 @@ -DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ -DKERNEL_ENTRY=$(VMLINUX_ENTRY_ADDRESS) +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n + # decompressor objects (linked with vmlinuz) -vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o +vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/bswapsi.o ifdef CONFIG_DEBUG_ZBOOT vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o @@ -44,7 +47,7 @@ $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c $(call cmd,shipped) -vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o +vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o extra-y += ashldi3.c $(obj)/ashldi3.c: $(obj)/%.c: $(srctree)/lib/%.c FORCE @@ -87,7 +90,7 @@ VMLINUZ_LOAD_ADDRESS := $(zload-y) else VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \ - $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS)) + $(obj)/vmlinux.bin $(LINKER_LOAD_ADDRESS)) endif UIMAGE_LOADADDR = $(VMLINUZ_LOAD_ADDRESS) --- linux-oracle-5.4.0.orig/arch/mips/boot/compressed/decompress.c +++ linux-oracle-5.4.0/arch/mips/boot/compressed/decompress.c @@ -7,12 +7,15 @@ * Author: Wu Zhangjin */ +#define DISABLE_BRANCH_PROFILING + #include #include #include #include #include +#include /* * These two variables specify the free mem region @@ -113,7 +116,7 @@ dtb_size = fdt_totalsize((void *)&__appended_dtb); /* last four bytes is always image size in little endian */ - image_size = le32_to_cpup((void *)&__image_end - 4); + image_size = get_unaligned_le32((void *)&__image_end - 4); /* copy dtb to where the booted kernel will expect it */ memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size, --- linux-oracle-5.4.0.orig/arch/mips/boot/compressed/string.c +++ linux-oracle-5.4.0/arch/mips/boot/compressed/string.c @@ -5,6 +5,7 @@ * Very small subset of simple string routines */ +#include #include void *memcpy(void *dest, const void *src, size_t n) @@ -27,3 +28,19 @@ ss[i] = c; return s; } + +void * __weak memmove(void *dest, const void *src, size_t n) +{ + unsigned int i; + const char *s = src; + char *d = dest; + + if ((uintptr_t)dest < (uintptr_t)src) { + for (i = 0; i < n; i++) + d[i] = s[i]; + } else { + for (i = n; i > 0; i--) + d[i - 1] = s[i - 1]; + } + return dest; +} --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/brcm/bcm3368.dtsi +++ linux-oracle-5.4.0/arch/mips/boot/dts/brcm/bcm3368.dtsi @@ -59,7 +59,7 @@ periph_cntl: syscon@fff8c008 { compatible = "syscon"; - reg = <0xfff8c000 0x4>; + reg = <0xfff8c008 0x4>; native-endian; }; --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/brcm/bcm63268.dtsi +++ linux-oracle-5.4.0/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -59,7 +59,7 @@ periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; }; --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/brcm/bcm6358.dtsi +++ linux-oracle-5.4.0/arch/mips/boot/dts/brcm/bcm6358.dtsi @@ -59,7 +59,7 @@ periph_cntl: syscon@fffe0008 { compatible = "syscon"; - reg = <0xfffe0000 0x4>; + reg = <0xfffe0008 0x4>; native-endian; }; --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/brcm/bcm6362.dtsi +++ linux-oracle-5.4.0/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -59,7 +59,7 @@ periph_cntl: syscon@10000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; }; --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/brcm/bcm6368.dtsi +++ linux-oracle-5.4.0/arch/mips/boot/dts/brcm/bcm6368.dtsi @@ -59,7 +59,7 @@ periph_cntl: syscon@100000008 { compatible = "syscon"; - reg = <0x10000000 0xc>; + reg = <0x10000008 0x4>; native-endian; }; --- linux-oracle-5.4.0.orig/arch/mips/boot/dts/ingenic/qi_lb60.dts +++ linux-oracle-5.4.0/arch/mips/boot/dts/ingenic/qi_lb60.dts @@ -69,7 +69,7 @@ "Speaker", "OUTL", "Speaker", "OUTR", "INL", "LOUT", - "INL", "ROUT"; + "INR", "ROUT"; simple-audio-card,aux-devs = <&>; --- linux-oracle-5.4.0.orig/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ linux-oracle-5.4.0/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -211,7 +211,7 @@ { cvmx_helper_link_info_t result; - WARN(!octeon_is_simulation(), + WARN_ONCE(!octeon_is_simulation(), "Using deprecated link status - please update your DT"); /* Unless we fix it later, all links are defaulted to down */ --- linux-oracle-5.4.0.orig/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ linux-oracle-5.4.0/arch/mips/cavium-octeon/executive/cvmx-helper.c @@ -1100,7 +1100,7 @@ if (index == 0) result = __cvmx_helper_rgmii_link_get(ipd_port); else { - WARN(1, "Using deprecated link status - please update your DT"); + WARN_ONCE(1, "Using deprecated link status - please update your DT"); result.s.full_duplex = 1; result.s.link_up = 1; result.s.speed = 1000; --- linux-oracle-5.4.0.orig/arch/mips/cavium-octeon/octeon-irq.c +++ linux-oracle-5.4.0/arch/mips/cavium-octeon/octeon-irq.c @@ -127,6 +127,16 @@ static int octeon_irq_force_ciu_mapping(struct irq_domain *domain, int irq, int line, int bit) { + struct device_node *of_node; + int ret; + + of_node = irq_domain_get_of_node(domain); + if (!of_node) + return -EINVAL; + ret = irq_alloc_desc_at(irq, of_node_to_nid(of_node)); + if (ret < 0) + return ret; + return irq_domain_associate(domain, irq, line << 6 | bit); } @@ -2199,6 +2209,9 @@ } cd = kzalloc(sizeof(*cd), GFP_KERNEL); + if (!cd) + return -ENOMEM; + cd->host_data = host_data; cd->bit = hw; --- linux-oracle-5.4.0.orig/arch/mips/cavium-octeon/octeon-platform.c +++ linux-oracle-5.4.0/arch/mips/cavium-octeon/octeon-platform.c @@ -86,11 +86,12 @@ "refclk-frequency", &clock_rate); if (i) { dev_err(dev, "No UCTL \"refclk-frequency\"\n"); + of_node_put(uctl_node); goto exit; } i = of_property_read_string(uctl_node, "refclk-type", &clock_type); - + of_node_put(uctl_node); if (!i && strcmp("crystal", clock_type) == 0) is_crystal_clock = true; } @@ -328,6 +329,7 @@ pd->dev.platform_data = &octeon_ehci_pdata; octeon_ehci_hw_start(&pd->dev); + put_device(&pd->dev); return ret; } @@ -391,6 +393,7 @@ pd->dev.platform_data = &octeon_ohci_pdata; octeon_ohci_hw_start(&pd->dev); + put_device(&pd->dev); return ret; } --- linux-oracle-5.4.0.orig/arch/mips/cavium-octeon/octeon-usb.c +++ linux-oracle-5.4.0/arch/mips/cavium-octeon/octeon-usb.c @@ -518,6 +518,7 @@ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { + put_device(&pdev->dev); dev_err(&pdev->dev, "No memory resources\n"); return -ENXIO; } @@ -529,8 +530,10 @@ * know the difference. */ base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(base)) + if (IS_ERR(base)) { + put_device(&pdev->dev); return PTR_ERR(base); + } mutex_lock(&dwc3_octeon_clocks_mutex); dwc3_octeon_clocks_start(&pdev->dev, (u64)base); @@ -541,6 +544,7 @@ devm_iounmap(&pdev->dev, base); devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); + put_device(&pdev->dev); } } while (node != NULL); --- linux-oracle-5.4.0.orig/arch/mips/configs/bigsur_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/bigsur_defconfig @@ -112,7 +112,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m CONFIG_ATA=y --- linux-oracle-5.4.0.orig/arch/mips/configs/decstation_64_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/decstation_64_defconfig @@ -53,8 +53,6 @@ CONFIG_NETWORK_SECMARK=y CONFIG_IP_SCTP=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m -CONFIG_DECNET_ROUTER=y # CONFIG_WIRELESS is not set # CONFIG_UEVENT_HELPER is not set # CONFIG_FW_LOADER is not set --- linux-oracle-5.4.0.orig/arch/mips/configs/decstation_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/decstation_defconfig @@ -49,8 +49,6 @@ CONFIG_NETWORK_SECMARK=y CONFIG_IP_SCTP=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m -CONFIG_DECNET_ROUTER=y # CONFIG_WIRELESS is not set # CONFIG_UEVENT_HELPER is not set # CONFIG_FW_LOADER is not set --- linux-oracle-5.4.0.orig/arch/mips/configs/decstation_r4k_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/decstation_r4k_defconfig @@ -48,8 +48,6 @@ CONFIG_NETWORK_SECMARK=y CONFIG_IP_SCTP=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m -CONFIG_DECNET_ROUTER=y # CONFIG_WIRELESS is not set # CONFIG_UEVENT_HELPER is not set # CONFIG_FW_LOADER is not set --- linux-oracle-5.4.0.orig/arch/mips/configs/fuloong2e_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/fuloong2e_defconfig @@ -99,7 +99,6 @@ CONFIG_ATA_OVER_ETH=m CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOWLEVEL is not set --- linux-oracle-5.4.0.orig/arch/mips/configs/gpr_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/gpr_defconfig @@ -69,7 +69,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -99,7 +98,6 @@ CONFIG_ATM_BR2684=m CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m CONFIG_LLC2=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m --- linux-oracle-5.4.0.orig/arch/mips/configs/ip27_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/ip27_defconfig @@ -99,7 +99,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_CONSTANTS=y --- linux-oracle-5.4.0.orig/arch/mips/configs/ip32_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/ip32_defconfig @@ -50,7 +50,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/mips/configs/jazz_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/jazz_defconfig @@ -106,7 +106,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -127,7 +126,6 @@ CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE=m -CONFIG_DECNET=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m @@ -191,7 +189,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/mips/configs/loongson3_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/loongson3_defconfig @@ -231,7 +231,7 @@ CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_DRM=y -CONFIG_DRM_RADEON=y +CONFIG_DRM_RADEON=m CONFIG_FB_RADEON=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=m --- linux-oracle-5.4.0.orig/arch/mips/configs/malta_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/malta_defconfig @@ -239,7 +239,6 @@ CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/mips/configs/malta_kvm_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/malta_kvm_defconfig @@ -247,7 +247,6 @@ CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/mips/configs/malta_kvm_guest_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/malta_kvm_guest_defconfig @@ -245,7 +245,6 @@ CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/mips/configs/maltaup_xpa_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/maltaup_xpa_defconfig @@ -245,7 +245,6 @@ CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y --- linux-oracle-5.4.0.orig/arch/mips/configs/mtx1_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/mtx1_defconfig @@ -117,7 +117,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -147,7 +146,6 @@ CONFIG_ATM_BR2684=m CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m CONFIG_LLC2=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m --- linux-oracle-5.4.0.orig/arch/mips/configs/nlm_xlp_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/nlm_xlp_defconfig @@ -200,7 +200,6 @@ CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_IP6_NF_SECURITY=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -234,7 +233,6 @@ CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y -CONFIG_DECNET=m CONFIG_LLC2=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m --- linux-oracle-5.4.0.orig/arch/mips/configs/nlm_xlr_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/nlm_xlr_defconfig @@ -198,7 +198,6 @@ CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m CONFIG_IP6_NF_SECURITY=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -232,7 +231,6 @@ CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m CONFIG_VLAN_8021Q_GVRP=y -CONFIG_DECNET=m CONFIG_LLC2=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m --- linux-oracle-5.4.0.orig/arch/mips/configs/rm200_defconfig +++ linux-oracle-5.4.0/arch/mips/configs/rm200_defconfig @@ -116,7 +116,6 @@ CONFIG_IP6_NF_TARGET_REJECT=m CONFIG_IP6_NF_MANGLE=m CONFIG_IP6_NF_RAW=m -CONFIG_DECNET_NF_GRABULATOR=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m CONFIG_BRIDGE_EBT_T_FILTER=m @@ -137,7 +136,6 @@ CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE=m -CONFIG_DECNET=m CONFIG_NET_SCHED=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m @@ -203,7 +201,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/mips/dec/int-handler.S +++ linux-oracle-5.4.0/arch/mips/dec/int-handler.S @@ -131,7 +131,7 @@ */ mfc0 t0,CP0_CAUSE # get pending interrupts mfc0 t1,CP0_STATUS -#ifdef CONFIG_32BIT +#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT) lw t2,cpu_fpu_mask #endif andi t0,ST0_IM # CAUSE.CE may be non-zero! @@ -139,7 +139,7 @@ beqz t0,spurious -#ifdef CONFIG_32BIT +#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT) and t2,t0 bnez t2,fpu # handle FPU immediately #endif @@ -280,7 +280,7 @@ j dec_irq_dispatch nop -#ifdef CONFIG_32BIT +#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT) fpu: lw t0,fpu_kstat_irq nop --- linux-oracle-5.4.0.orig/arch/mips/dec/prom/Makefile +++ linux-oracle-5.4.0/arch/mips/dec/prom/Makefile @@ -6,4 +6,4 @@ lib-y += init.o memory.o cmdline.o identify.o console.o -lib-$(CONFIG_32BIT) += locore.o +lib-$(CONFIG_CPU_R3000) += locore.o --- linux-oracle-5.4.0.orig/arch/mips/dec/setup.c +++ linux-oracle-5.4.0/arch/mips/dec/setup.c @@ -6,7 +6,7 @@ * for more details. * * Copyright (C) 1998 Harald Koerfgen - * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki + * Copyright (C) 2000, 2001, 2002, 2003, 2005, 2020 Maciej W. Rozycki */ #include #include @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include +#include #include #include #include @@ -29,7 +31,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -166,6 +170,9 @@ ioport_resource.start = ~0UL; ioport_resource.end = 0UL; + + /* Stay away from the firmware working memory area for now. */ + memblock_reserve(PHYS_OFFSET, __pa_symbol(&_text) - PHYS_OFFSET); } /* @@ -759,7 +766,8 @@ dec_interrupt[DEC_IRQ_HALT] = -1; /* Register board interrupts: FPU and cascade. */ - if (dec_interrupt[DEC_IRQ_FPU] >= 0 && cpu_has_fpu) { + if (IS_ENABLED(CONFIG_MIPS_FP_SUPPORT) && + dec_interrupt[DEC_IRQ_FPU] >= 0 && cpu_has_fpu) { struct irq_desc *desc_fpu; int irq_fpu; --- linux-oracle-5.4.0.orig/arch/mips/fw/lib/cmdline.c +++ linux-oracle-5.4.0/arch/mips/fw/lib/cmdline.c @@ -51,7 +51,7 @@ { char *result = NULL; - if (_fw_envp != NULL) { + if (_fw_envp != NULL && fw_envp(0) != NULL) { /* * Return a pointer to the given environment variable. * YAMON uses "name", "value" pairs, while U-Boot uses --- linux-oracle-5.4.0.orig/arch/mips/generic/board-boston.its.S +++ linux-oracle-5.4.0/arch/mips/generic/board-boston.its.S @@ -1,22 +1,22 @@ / { images { - fdt@boston { + fdt-boston { description = "img,boston Device Tree"; data = /incbin/("boot/dts/img/boston.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@boston { + conf-boston { description = "Boston Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@boston"; + kernel = "kernel"; + fdt = "fdt-boston"; }; }; }; --- linux-oracle-5.4.0.orig/arch/mips/generic/board-ni169445.its.S +++ linux-oracle-5.4.0/arch/mips/generic/board-ni169445.its.S @@ -1,22 +1,22 @@ / { images { - fdt@ni169445 { + fdt-ni169445 { description = "NI 169445 device tree"; data = /incbin/("boot/dts/ni/169445.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@ni169445 { + conf-ni169445 { description = "NI 169445 Linux Kernel"; - kernel = "kernel@0"; - fdt = "fdt@ni169445"; + kernel = "kernel"; + fdt = "fdt-ni169445"; }; }; }; --- linux-oracle-5.4.0.orig/arch/mips/generic/board-ocelot.its.S +++ linux-oracle-5.4.0/arch/mips/generic/board-ocelot.its.S @@ -1,40 +1,40 @@ /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ / { images { - fdt@ocelot_pcb123 { + fdt-ocelot_pcb123 { description = "MSCC Ocelot PCB123 Device Tree"; data = /incbin/("boot/dts/mscc/ocelot_pcb123.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; - fdt@ocelot_pcb120 { + fdt-ocelot_pcb120 { description = "MSCC Ocelot PCB120 Device Tree"; data = /incbin/("boot/dts/mscc/ocelot_pcb120.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@ocelot_pcb123 { + conf-ocelot_pcb123 { description = "Ocelot Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@ocelot_pcb123"; + kernel = "kernel"; + fdt = "fdt-ocelot_pcb123"; }; - conf@ocelot_pcb120 { + conf-ocelot_pcb120 { description = "Ocelot Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@ocelot_pcb120"; + kernel = "kernel"; + fdt = "fdt-ocelot_pcb120"; }; }; }; --- linux-oracle-5.4.0.orig/arch/mips/generic/board-xilfpga.its.S +++ linux-oracle-5.4.0/arch/mips/generic/board-xilfpga.its.S @@ -1,22 +1,22 @@ / { images { - fdt@xilfpga { + fdt-xilfpga { description = "MIPSfpga (xilfpga) Device Tree"; data = /incbin/("boot/dts/xilfpga/nexys4ddr.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@xilfpga { + conf-xilfpga { description = "MIPSfpga Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@xilfpga"; + kernel = "kernel"; + fdt = "fdt-xilfpga"; }; }; }; --- linux-oracle-5.4.0.orig/arch/mips/generic/vmlinux.its.S +++ linux-oracle-5.4.0/arch/mips/generic/vmlinux.its.S @@ -6,7 +6,7 @@ #address-cells = ; images { - kernel@0 { + kernel { description = KERNEL_NAME; data = /incbin/(VMLINUX_BINARY); type = "kernel"; @@ -15,18 +15,18 @@ compression = VMLINUX_COMPRESSION; load = /bits/ ADDR_BITS ; entry = /bits/ ADDR_BITS ; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - default = "conf@default"; + default = "conf-default"; - conf@default { + conf-default { description = "Generic Linux kernel"; - kernel = "kernel@0"; + kernel = "kernel"; }; }; }; --- linux-oracle-5.4.0.orig/arch/mips/generic/yamon-dt.c +++ linux-oracle-5.4.0/arch/mips/generic/yamon-dt.c @@ -75,7 +75,7 @@ __init int yamon_dt_append_memory(void *fdt, const struct yamon_mem_region *regions) { - unsigned long phys_memsize, memsize; + unsigned long phys_memsize = 0, memsize; __be32 mem_array[2 * MAX_MEM_ARRAY_ENTRIES]; unsigned int mem_entries; int i, err, mem_off; --- linux-oracle-5.4.0.orig/arch/mips/include/asm/asm.h +++ linux-oracle-5.4.0/arch/mips/include/asm/asm.h @@ -20,10 +20,27 @@ #include #include +#ifndef __VDSO__ +/* + * Emit CFI data in .debug_frame sections, not .eh_frame sections. + * We don't do DWARF unwinding at runtime, so only the offline DWARF + * information is useful to anyone. Note we should change this if we + * ever decide to enable DWARF unwinding at runtime. + */ +#define CFI_SECTIONS .cfi_sections .debug_frame +#else + /* + * For the vDSO, emit both runtime unwind information and debug + * symbols for the .dbg file. + */ +#define CFI_SECTIONS +#endif + /* * LEAF - declare leaf routine */ #define LEAF(symbol) \ + CFI_SECTIONS; \ .globl symbol; \ .align 2; \ .type symbol, @function; \ @@ -36,6 +53,7 @@ * NESTED - declare nested routine entry point */ #define NESTED(symbol, framesize, rpc) \ + CFI_SECTIONS; \ .globl symbol; \ .align 2; \ .type symbol, @function; \ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/bugs.h +++ linux-oracle-5.4.0/arch/mips/include/asm/bugs.h @@ -1,17 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * This is included by init/main.c to check for architecture-dependent bugs. - * * Copyright (C) 2007 Maciej W. Rozycki - * - * Needs: - * void check_bugs(void); */ #ifndef _ASM_BUGS_H #define _ASM_BUGS_H #include -#include #include #include @@ -31,17 +25,6 @@ #endif } -static inline void check_bugs(void) -{ - unsigned int cpu = smp_processor_id(); - - cpu_data[cpu].udelay_val = loops_per_jiffy; - check_bugs32(); -#ifdef CONFIG_64BIT - check_bugs64(); -#endif -} - static inline int r4k_daddiu_bug(void) { #ifdef CONFIG_64BIT --- linux-oracle-5.4.0.orig/arch/mips/include/asm/checksum.h +++ linux-oracle-5.4.0/arch/mips/include/asm/checksum.h @@ -276,7 +276,8 @@ " .set pop" : "=&r" (sum), "=&r" (tmp) : "r" (saddr), "r" (daddr), - "0" (htonl(len)), "r" (htonl(proto)), "r" (sum)); + "0" (htonl(len)), "r" (htonl(proto)), "r" (sum) + : "memory"); return csum_fold(sum); } --- linux-oracle-5.4.0.orig/arch/mips/include/asm/cmpxchg.h +++ linux-oracle-5.4.0/arch/mips/include/asm/cmpxchg.h @@ -239,6 +239,7 @@ " .set " MIPS_ISA_ARCH_LEVEL " \n" /* Load 64 bits from ptr */ "1: lld %L0, %3 # __cmpxchg64 \n" + " .set pop \n" /* * Split the 64 bit value we loaded into the 2 registers that hold the * ret variable. @@ -266,6 +267,8 @@ " or %L1, %L1, $at \n" " .set at \n" # endif + " .set push \n" + " .set " MIPS_ISA_ARCH_LEVEL " \n" /* Attempt to store new at ptr */ " scd %L1, %2 \n" /* If we failed, loop! */ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/cpu-features.h +++ linux-oracle-5.4.0/arch/mips/include/asm/cpu-features.h @@ -124,7 +124,24 @@ #define cpu_has_tx39_cache __opt(MIPS_CPU_TX39_CACHE) #endif #ifndef cpu_has_octeon_cache -#define cpu_has_octeon_cache 0 +#define cpu_has_octeon_cache \ +({ \ + int __res; \ + \ + switch (boot_cpu_type()) { \ + case CPU_CAVIUM_OCTEON: \ + case CPU_CAVIUM_OCTEON_PLUS: \ + case CPU_CAVIUM_OCTEON2: \ + case CPU_CAVIUM_OCTEON3: \ + __res = 1; \ + break; \ + \ + default: \ + __res = 0; \ + } \ + \ + __res; \ +}) #endif /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work. */ #ifndef cpu_has_fpu @@ -288,10 +305,12 @@ # define cpu_has_mips32r6 __isa_ge_or_flag(6, MIPS_CPU_ISA_M32R6) #endif #ifndef cpu_has_mips64r1 -# define cpu_has_mips64r1 __isa_range_or_flag(1, 6, MIPS_CPU_ISA_M64R1) +# define cpu_has_mips64r1 (cpu_has_64bits && \ + __isa_range_or_flag(1, 6, MIPS_CPU_ISA_M64R1)) #endif #ifndef cpu_has_mips64r2 -# define cpu_has_mips64r2 __isa_range_or_flag(2, 6, MIPS_CPU_ISA_M64R2) +# define cpu_has_mips64r2 (cpu_has_64bits && \ + __isa_range_or_flag(2, 6, MIPS_CPU_ISA_M64R2)) #endif #ifndef cpu_has_mips64r6 # define cpu_has_mips64r6 __isa_ge_and_flag(6, MIPS_CPU_ISA_M64R6) @@ -339,7 +358,7 @@ ({ \ int __res; \ \ - switch (current_cpu_type()) { \ + switch (boot_cpu_type()) { \ case CPU_M14KC: \ case CPU_74K: \ case CPU_1074K: \ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/cpu-type.h +++ linux-oracle-5.4.0/arch/mips/include/asm/cpu-type.h @@ -47,6 +47,7 @@ case CPU_34K: case CPU_1004K: case CPU_74K: + case CPU_1074K: case CPU_M14KC: case CPU_M14KEC: case CPU_INTERAPTIV: --- linux-oracle-5.4.0.orig/arch/mips/include/asm/dec/prom.h +++ linux-oracle-5.4.0/arch/mips/include/asm/dec/prom.h @@ -43,16 +43,11 @@ */ #define REX_PROM_MAGIC 0x30464354 -#ifdef CONFIG_64BIT - -#define prom_is_rex(magic) 1 /* KN04 and KN05 are REX PROMs. */ - -#else /* !CONFIG_64BIT */ - -#define prom_is_rex(magic) ((magic) == REX_PROM_MAGIC) - -#endif /* !CONFIG_64BIT */ - +/* KN04 and KN05 are REX PROMs, so only do the check for R3k systems. */ +static inline bool prom_is_rex(u32 magic) +{ + return !IS_ENABLED(CONFIG_CPU_R3000) || magic == REX_PROM_MAGIC; +} /* * 3MIN/MAXINE PROM entry points for DS5000/1xx's, DS5000/xx's and @@ -75,7 +70,7 @@ */ typedef struct { int pagesize; - unsigned char bitmap[0]; + unsigned char bitmap[]; } memmap; --- linux-oracle-5.4.0.orig/arch/mips/include/asm/div64.h +++ linux-oracle-5.4.0/arch/mips/include/asm/div64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2004 Maciej W. Rozycki + * Copyright (C) 2000, 2004, 2021 Maciej W. Rozycki * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) * * This file is subject to the terms and conditions of the GNU General Public @@ -9,25 +9,18 @@ #ifndef __ASM_DIV64_H #define __ASM_DIV64_H -#include - -#if BITS_PER_LONG == 64 +#include -#include +#if BITS_PER_LONG == 32 /* * No traps on overflows for any of these... */ -#define __div64_32(n, base) \ -({ \ +#define do_div64_32(res, high, low, base) ({ \ unsigned long __cf, __tmp, __tmp2, __i; \ unsigned long __quot32, __mod32; \ - unsigned long __high, __low; \ - unsigned long long __n; \ \ - __high = *__n >> 32; \ - __low = __n; \ __asm__( \ " .set push \n" \ " .set noat \n" \ @@ -51,18 +44,48 @@ " subu %0, %0, %z6 \n" \ " addiu %2, %2, 1 \n" \ "3: \n" \ - " bnez %4, 0b\n\t" \ - " srl %5, %1, 0x1f\n\t" \ + " bnez %4, 0b \n" \ + " srl %5, %1, 0x1f \n" \ " .set pop" \ : "=&r" (__mod32), "=&r" (__tmp), \ "=&r" (__quot32), "=&r" (__cf), \ "=&r" (__i), "=&r" (__tmp2) \ - : "Jr" (base), "0" (__high), "1" (__low)); \ + : "Jr" (base), "0" (high), "1" (low)); \ \ - (__n) = __quot32; \ + (res) = __quot32; \ __mod32; \ }) -#endif /* BITS_PER_LONG == 64 */ +#define __div64_32(n, base) ({ \ + unsigned long __upper, __low, __high, __radix; \ + unsigned long long __quot; \ + unsigned long long __div; \ + unsigned long __mod; \ + \ + __div = (*n); \ + __radix = (base); \ + \ + __high = __div >> 32; \ + __low = __div; \ + \ + if (__high < __radix) { \ + __upper = __high; \ + __high = 0; \ + } else { \ + __upper = __high % __radix; \ + __high /= __radix; \ + } \ + \ + __mod = do_div64_32(__low, __upper, __low, __radix); \ + \ + __quot = __high; \ + __quot = __quot << 32 | __low; \ + (*n) = __quot; \ + __mod; \ +}) + +#endif /* BITS_PER_LONG == 32 */ + +#include #endif /* __ASM_DIV64_H */ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/fw/fw.h +++ linux-oracle-5.4.0/arch/mips/include/asm/fw/fw.h @@ -26,6 +26,6 @@ extern void fw_meminit(void); extern char *fw_getenv(char *name); extern unsigned long fw_getenvl(char *name); -extern void fw_init_early_console(char port); +extern void fw_init_early_console(void); #endif /* __ASM_FW_H_ */ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/highmem.h +++ linux-oracle-5.4.0/arch/mips/include/asm/highmem.h @@ -36,7 +36,7 @@ * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#ifdef CONFIG_PHYS_ADDR_T_64BIT +#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) #define LAST_PKMAP 512 #else #define LAST_PKMAP 1024 --- linux-oracle-5.4.0.orig/arch/mips/include/asm/hugetlb.h +++ linux-oracle-5.4.0/arch/mips/include/asm/hugetlb.h @@ -53,7 +53,13 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - flush_tlb_page(vma, addr & huge_page_mask(hstate_vma(vma))); + /* + * clear the huge pte entry firstly, so that the other smp threads will + * not get old pte entry after finishing flush_tlb_page and before + * setting new huge pte entry + */ + huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); + flush_tlb_page(vma, addr); } #define __HAVE_ARCH_HUGE_PTE_NONE --- linux-oracle-5.4.0.orig/arch/mips/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/mips/include/asm/kvm_host.h @@ -274,8 +274,12 @@ #define MIPS3_PG_SHIFT 6 #define MIPS3_PG_FRAME 0x3fffffc0 +#if defined(CONFIG_64BIT) +#define VPN2_MASK GENMASK(cpu_vmbits - 1, 13) +#else #define VPN2_MASK 0xffffe000 -#define KVM_ENTRYHI_ASID MIPS_ENTRYHI_ASID +#endif +#define KVM_ENTRYHI_ASID cpu_asid_mask(&boot_cpu_data) #define TLB_IS_GLOBAL(x) ((x).tlb_lo[0] & (x).tlb_lo[1] & ENTRYLO_G) #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) #define TLB_ASID(x) ((x).tlb_hi & KVM_ENTRYHI_ASID) @@ -935,7 +939,7 @@ #define KVM_ARCH_WANT_MMU_NOTIFIER int kvm_unmap_hva_range(struct kvm *kvm, - unsigned long start, unsigned long end); + unsigned long start, unsigned long end, unsigned flags); int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); --- linux-oracle-5.4.0.orig/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h +++ linux-oracle-5.4.0/arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h @@ -28,7 +28,6 @@ #define cpu_has_6k_cache 0 #define cpu_has_8k_cache 0 #define cpu_has_tx39_cache 0 -#define cpu_has_fpu 1 #define cpu_has_nofpuex 0 #define cpu_has_32fpr 1 #define cpu_has_counter 1 --- linux-oracle-5.4.0.orig/arch/mips/include/asm/mach-rc32434/pci.h +++ linux-oracle-5.4.0/arch/mips/include/asm/mach-rc32434/pci.h @@ -377,7 +377,7 @@ PCI_CFG04_STAT_SSE | \ PCI_CFG04_STAT_PE) -#define KORINA_CNFG1 ((KORINA_STAT<<16)|KORINA_CMD) +#define KORINA_CNFG1 (KORINA_STAT | KORINA_CMD) #define KORINA_REVID 0 #define KORINA_CLASS_CODE 0 --- linux-oracle-5.4.0.orig/arch/mips/include/asm/mips-cm.h +++ linux-oracle-5.4.0/arch/mips/include/asm/mips-cm.h @@ -11,6 +11,7 @@ #ifndef __MIPS_ASM_MIPS_CM_H__ #define __MIPS_ASM_MIPS_CM_H__ +#include #include #include @@ -153,8 +154,8 @@ #define CM_GCR_REV_MINOR GENMASK(7, 0) #define CM_ENCODE_REV(major, minor) \ - (((major) << __ffs(CM_GCR_REV_MAJOR)) | \ - ((minor) << __ffs(CM_GCR_REV_MINOR))) + (FIELD_PREP(CM_GCR_REV_MAJOR, major) | \ + FIELD_PREP(CM_GCR_REV_MINOR, minor)) #define CM_REV_CM2 CM_ENCODE_REV(6, 0) #define CM_REV_CM2_5 CM_ENCODE_REV(7, 0) @@ -227,6 +228,10 @@ GCR_ACCESSOR_RO(32, 0x0f0, cpc_status) #define CM_GCR_CPC_STATUS_EX BIT(0) +/* GCR_ACCESS - Controls core/IOCU access to GCRs */ +GCR_ACCESSOR_RW(32, 0x120, access_cm3) +#define CM_GCR_ACCESS_ACCESSEN GENMASK(7, 0) + /* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */ GCR_ACCESSOR_RW(32, 0x130, l2_config) #define CM_GCR_L2_CONFIG_BYPASS BIT(20) @@ -362,10 +367,10 @@ static inline unsigned int mips_cm_max_vp_width(void) { extern int smp_num_siblings; - uint32_t cfg; if (mips_cm_revision() >= CM_REV_CM3) - return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW; + return FIELD_GET(CM_GCR_SYS_CONFIG2_MAXVPW, + read_gcr_sys_config2()); if (mips_cm_present()) { /* @@ -373,8 +378,7 @@ * number of VP(E)s, and if that ever changes then this will * need revisiting. */ - cfg = read_gcr_cl_config() & CM_GCR_Cx_CONFIG_PVPE; - return (cfg >> __ffs(CM_GCR_Cx_CONFIG_PVPE)) + 1; + return FIELD_GET(CM_GCR_Cx_CONFIG_PVPE, read_gcr_cl_config()) + 1; } if (IS_ENABLED(CONFIG_SMP)) --- linux-oracle-5.4.0.orig/arch/mips/include/asm/mipsregs.h +++ linux-oracle-5.4.0/arch/mips/include/asm/mipsregs.h @@ -750,7 +750,7 @@ /* MAAR bit definitions */ #define MIPS_MAAR_VH (_U64CAST_(1) << 63) -#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) +#define MIPS_MAAR_ADDR GENMASK_ULL(55, 12) #define MIPS_MAAR_ADDR_SHIFT 12 #define MIPS_MAAR_S (_ULCAST_(1) << 1) #define MIPS_MAAR_VL (_ULCAST_(1) << 0) @@ -2007,7 +2007,7 @@ ({ int __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips32r2\n\t" \ + ".set\tmips32r5\n\t" \ _ASM_SET_VIRT \ "mfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ @@ -2020,7 +2020,7 @@ ({ unsigned long long __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips64r2\n\t" \ + ".set\tmips64r5\n\t" \ _ASM_SET_VIRT \ "dmfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ @@ -2033,7 +2033,7 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips32r2\n\t" \ + ".set\tmips32r5\n\t" \ _ASM_SET_VIRT \ "mtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ @@ -2045,7 +2045,7 @@ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips64r2\n\t" \ + ".set\tmips64r5\n\t" \ _ASM_SET_VIRT \ "dmtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/mmzone.h +++ linux-oracle-5.4.0/arch/mips/include/asm/mmzone.h @@ -20,10 +20,4 @@ #define nid_to_addrbase(nid) 0 #endif -#ifdef CONFIG_DISCONTIGMEM - -#define pfn_to_nid(pfn) pa_to_nid((pfn) << PAGE_SHIFT) - -#endif /* CONFIG_DISCONTIGMEM */ - #endif /* _ASM_MMZONE_H_ */ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ linux-oracle-5.4.0/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -315,7 +315,7 @@ /* Functions to return string based on type */ #define ENUM_BRD_TYPE_CASE(x) \ - case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */ + case x: return (&#x[16]); /* Skip CVMX_BOARD_TYPE_ */ static inline const char *cvmx_board_type_to_string(enum cvmx_board_types_enum type) { @@ -404,7 +404,7 @@ } #define ENUM_CHIP_TYPE_CASE(x) \ - case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */ + case x: return (&#x[15]); /* Skip CVMX_CHIP_TYPE */ static inline const char *cvmx_chip_type_to_string(enum cvmx_chip_types_enum type) { --- linux-oracle-5.4.0.orig/arch/mips/include/asm/pgtable-32.h +++ linux-oracle-5.4.0/arch/mips/include/asm/pgtable-32.h @@ -155,6 +155,7 @@ #if defined(CONFIG_XPA) +#define MAX_POSSIBLE_PHYSMEM_BITS 40 #define pte_pfn(x) (((unsigned long)((x).pte_high >> _PFN_SHIFT)) | (unsigned long)((x).pte_low << _PAGE_PRESENT_SHIFT)) static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) @@ -170,6 +171,7 @@ #elif defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) +#define MAX_POSSIBLE_PHYSMEM_BITS 36 #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot) @@ -184,6 +186,7 @@ #else +#define MAX_POSSIBLE_PHYSMEM_BITS 32 #ifdef CONFIG_CPU_VR41XX #define pte_pfn(x) ((unsigned long)((x).pte >> (PAGE_SHIFT + 2))) #define pfn_pte(pfn, prot) __pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot)) --- linux-oracle-5.4.0.orig/arch/mips/include/asm/pgtable-64.h +++ linux-oracle-5.4.0/arch/mips/include/asm/pgtable-64.h @@ -18,10 +18,12 @@ #include #define __ARCH_USE_5LEVEL_HACK -#if defined(CONFIG_PAGE_SIZE_64KB) && !defined(CONFIG_MIPS_VA_BITS_48) +#if CONFIG_PGTABLE_LEVELS == 2 #include -#elif !(defined(CONFIG_PAGE_SIZE_4KB) && defined(CONFIG_MIPS_VA_BITS_48)) +#elif CONFIG_PGTABLE_LEVELS == 3 #include +#else +#include #endif /* @@ -216,6 +218,9 @@ return pgd_val(pgd); } +#define pgd_phys(pgd) virt_to_phys((void *)pgd_val(pgd)) +#define pgd_page(pgd) (pfn_to_page(pgd_phys(pgd) >> PAGE_SHIFT)) + static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) { return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(address); --- linux-oracle-5.4.0.orig/arch/mips/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/mips/include/asm/ptrace.h @@ -60,6 +60,7 @@ unsigned long val) { regs->cp0_epc = val; + regs->cp0_cause &= ~CAUSEF_BD; } /* Query offset/name of register from its name/offset */ @@ -156,7 +157,7 @@ #define instruction_pointer(regs) ((regs)->cp0_epc) #define profile_pc(regs) instruction_pointer(regs) -extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall); +extern asmlinkage long syscall_trace_enter(struct pt_regs *regs); extern asmlinkage void syscall_trace_leave(struct pt_regs *regs); extern void die(const char *, struct pt_regs *) __noreturn; --- linux-oracle-5.4.0.orig/arch/mips/include/asm/setup.h +++ linux-oracle-5.4.0/arch/mips/include/asm/setup.h @@ -16,7 +16,7 @@ unsigned int reg_shift, unsigned int timeout) {} #endif -extern void set_handler(unsigned long offset, void *addr, unsigned long len); +void set_handler(unsigned long offset, const void *addr, unsigned long len); extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len); typedef void (*vi_handler_t)(void); --- linux-oracle-5.4.0.orig/arch/mips/include/asm/string.h +++ linux-oracle-5.4.0/arch/mips/include/asm/string.h @@ -10,127 +10,6 @@ #ifndef _ASM_STRING_H #define _ASM_STRING_H - -/* - * Most of the inline functions are rather naive implementations so I just - * didn't bother updating them for 64-bit ... - */ -#ifdef CONFIG_32BIT - -#ifndef IN_STRING_C - -#define __HAVE_ARCH_STRCPY -static __inline__ char *strcpy(char *__dest, __const__ char *__src) -{ - char *__xdest = __dest; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%1,1\n\t" - "sb\t$1,(%0)\n\t" - "bnez\t$1,1b\n\t" - "addiu\t%0,1\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (__dest), "=r" (__src) - : "0" (__dest), "1" (__src) - : "memory"); - - return __xdest; -} - -#define __HAVE_ARCH_STRNCPY -static __inline__ char *strncpy(char *__dest, __const__ char *__src, size_t __n) -{ - char *__xdest = __dest; - - if (__n == 0) - return __xdest; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t$1,(%1)\n\t" - "subu\t%2,1\n\t" - "sb\t$1,(%0)\n\t" - "beqz\t$1,2f\n\t" - "addiu\t%0,1\n\t" - "bnez\t%2,1b\n\t" - "addiu\t%1,1\n" - "2:\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (__dest), "=r" (__src), "=r" (__n) - : "0" (__dest), "1" (__src), "2" (__n) - : "memory"); - - return __xdest; -} - -#define __HAVE_ARCH_STRCMP -static __inline__ int strcmp(__const__ char *__cs, __const__ char *__ct) -{ - int __res; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n\t" - "lbu\t%2,(%0)\n" - "1:\tlbu\t$1,(%1)\n\t" - "addiu\t%0,1\n\t" - "bne\t$1,%2,2f\n\t" - "addiu\t%1,1\n\t" - "bnez\t%2,1b\n\t" - "lbu\t%2,(%0)\n\t" -#if defined(CONFIG_CPU_R3000) - "nop\n\t" -#endif - "move\t%2,$1\n" - "2:\tsubu\t%2,$1\n" - "3:\t.set\tat\n\t" - ".set\treorder" - : "=r" (__cs), "=r" (__ct), "=r" (__res) - : "0" (__cs), "1" (__ct)); - - return __res; -} - -#endif /* !defined(IN_STRING_C) */ - -#define __HAVE_ARCH_STRNCMP -static __inline__ int -strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count) -{ - int __res; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - ".set\tnoat\n" - "1:\tlbu\t%3,(%0)\n\t" - "beqz\t%2,2f\n\t" - "lbu\t$1,(%1)\n\t" - "subu\t%2,1\n\t" - "bne\t$1,%3,3f\n\t" - "addiu\t%0,1\n\t" - "bnez\t%3,1b\n\t" - "addiu\t%1,1\n" - "2:\n\t" -#if defined(CONFIG_CPU_R3000) - "nop\n\t" -#endif - "move\t%3,$1\n" - "3:\tsubu\t%3,$1\n\t" - ".set\tat\n\t" - ".set\treorder" - : "=r" (__cs), "=r" (__ct), "=r" (__count), "=r" (__res) - : "0" (__cs), "1" (__ct), "2" (__count)); - - return __res; -} -#endif /* CONFIG_32BIT */ - #define __HAVE_ARCH_MEMSET extern void *memset(void *__s, int __c, size_t __count); --- linux-oracle-5.4.0.orig/arch/mips/include/asm/switch_to.h +++ linux-oracle-5.4.0/arch/mips/include/asm/switch_to.h @@ -97,7 +97,7 @@ } \ } while (0) #else -# define __sanitize_fcr31(next) +# define __sanitize_fcr31(next) do { (void) (next); } while (0) #endif /* --- linux-oracle-5.4.0.orig/arch/mips/include/asm/syscall.h +++ linux-oracle-5.4.0/arch/mips/include/asm/syscall.h @@ -38,7 +38,7 @@ static inline long syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return current_thread_info()->syscall; + return task_thread_info(task)->syscall; } static inline void mips_syscall_update_nr(struct task_struct *task, --- linux-oracle-5.4.0.orig/arch/mips/include/asm/thread_info.h +++ linux-oracle-5.4.0/arch/mips/include/asm/thread_info.h @@ -49,8 +49,26 @@ .addr_limit = KERNEL_DS, \ } -/* How to get the thread information struct from C. */ +/* + * A pointer to the struct thread_info for the currently executing thread is + * held in register $28/$gp. + * + * We declare __current_thread_info as a global register variable rather than a + * local register variable within current_thread_info() because clang doesn't + * support explicit local register variables. + * + * When building the VDSO we take care not to declare the global register + * variable because this causes GCC to not preserve the value of $28/$gp in + * functions that change its value (which is common in the PIC VDSO when + * accessing the GOT). Since the VDSO shouldn't be accessing + * __current_thread_info anyway we declare it extern in order to cause a link + * failure if it's referenced. + */ +#ifdef __VDSO__ +extern struct thread_info *__current_thread_info; +#else register struct thread_info *__current_thread_info __asm__("$28"); +#endif static inline struct thread_info *current_thread_info(void) { --- linux-oracle-5.4.0.orig/arch/mips/include/asm/timex.h +++ linux-oracle-5.4.0/arch/mips/include/asm/timex.h @@ -40,9 +40,9 @@ typedef unsigned int cycles_t; /* - * On R4000/R4400 before version 5.0 an erratum exists such that if the - * cycle counter is read in the exact moment that it is matching the - * compare register, no interrupt will be generated. + * On R4000/R4400 an erratum exists such that if the cycle counter is + * read in the exact moment that it is matching the compare register, + * no interrupt will be generated. * * There is a suggested workaround and also the erratum can't strike if * the compare interrupt isn't being used as the clock source device. @@ -63,7 +63,7 @@ if (!__builtin_constant_p(cpu_has_counter)) asm volatile("" : "=m" (cpu_data[0].options)); if (likely(cpu_has_counter && - prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0)))) + prid > (PRID_IMP_R4000 | PRID_REV_ENCODE_44(15, 15)))) return 1; else return 0; @@ -76,25 +76,24 @@ else return 0; /* no usable counter */ } +#define get_cycles get_cycles /* * Like get_cycles - but where c0_count is not available we desperately * use c0_random in an attempt to get at least a little bit of entropy. - * - * R6000 and R6000A neither have a count register nor a random register. - * That leaves no entropy source in the CPU itself. */ static inline unsigned long random_get_entropy(void) { - unsigned int prid = read_c0_prid(); - unsigned int imp = prid & PRID_IMP_MASK; + unsigned int c0_random; - if (can_use_mips_counter(prid)) + if (can_use_mips_counter(read_c0_prid())) return read_c0_count(); - else if (likely(imp != PRID_IMP_R6000 && imp != PRID_IMP_R6000A)) - return read_c0_random(); + + if (cpu_has_3kex) + c0_random = (read_c0_random() >> 8) & 0x3f; else - return 0; /* no usable register */ + c0_random = read_c0_random() & 0x3f; + return (random_get_entropy_fallback() << 6) | (0x3f - c0_random); } #define random_get_entropy random_get_entropy --- linux-oracle-5.4.0.orig/arch/mips/include/asm/vdso/gettimeofday.h +++ linux-oracle-5.4.0/arch/mips/include/asm/vdso/gettimeofday.h @@ -26,7 +26,11 @@ #define __VDSO_USE_SYSCALL ULLONG_MAX -#ifdef CONFIG_MIPS_CLOCK_VSYSCALL +#if MIPS_ISA_REV < 6 +#define VDSO_SYSCALL_CLOBBERS "hi", "lo", +#else +#define VDSO_SYSCALL_CLOBBERS +#endif static __always_inline long gettimeofday_fallback( struct __kernel_old_timeval *_tv, @@ -43,22 +47,13 @@ : "=r" (ret), "=r" (error) : "r" (tv), "r" (tz), "r" (nr) : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + "$14", "$15", "$24", "$25", + VDSO_SYSCALL_CLOBBERS + "memory"); return error ? -ret : ret; } -#else - -static __always_inline long gettimeofday_fallback( - struct __kernel_old_timeval *_tv, - struct timezone *_tz) -{ - return -1; -} - -#endif - static __always_inline long clock_gettime_fallback( clockid_t _clkid, struct __kernel_timespec *_ts) @@ -78,7 +73,9 @@ : "=r" (ret), "=r" (error) : "r" (clkid), "r" (ts), "r" (nr) : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + "$14", "$15", "$24", "$25", + VDSO_SYSCALL_CLOBBERS + "memory"); return error ? -ret : ret; } @@ -102,7 +99,9 @@ : "=r" (ret), "=r" (error) : "r" (clkid), "r" (ts), "r" (nr) : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + "$14", "$15", "$24", "$25", + VDSO_SYSCALL_CLOBBERS + "memory"); return error ? -ret : ret; } @@ -126,7 +125,9 @@ : "=r" (ret), "=r" (error) : "r" (clkid), "r" (ts), "r" (nr) : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + "$14", "$15", "$24", "$25", + VDSO_SYSCALL_CLOBBERS + "memory"); return error ? -ret : ret; } @@ -146,7 +147,9 @@ : "=r" (ret), "=r" (error) : "r" (clkid), "r" (ts), "r" (nr) : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", - "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + "$14", "$15", "$24", "$25", + VDSO_SYSCALL_CLOBBERS + "memory"); return error ? -ret : ret; } --- linux-oracle-5.4.0.orig/arch/mips/include/asm/vdso/vdso.h +++ linux-oracle-5.4.0/arch/mips/include/asm/vdso/vdso.h @@ -67,7 +67,7 @@ static inline void __iomem *get_gic(const struct vdso_data *data) { - return (void __iomem *)data - PAGE_SIZE; + return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE; } #endif /* CONFIG_CLKSRC_MIPS_GIC */ --- linux-oracle-5.4.0.orig/arch/mips/include/asm/vpe.h +++ linux-oracle-5.4.0/arch/mips/include/asm/vpe.h @@ -104,7 +104,6 @@ struct list_head tc_list; /* Thread contexts */ }; -extern unsigned long physical_memsize; extern struct vpe_control vpecontrol; extern const struct file_operations vpe_fops; --- linux-oracle-5.4.0.orig/arch/mips/jazz/jazzdma.c +++ linux-oracle-5.4.0/arch/mips/jazz/jazzdma.c @@ -592,7 +592,7 @@ phys_addr_t phys = page_to_phys(page) + offset; if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - arch_sync_dma_for_device(dev, phys, size, dir); + arch_sync_dma_for_device(phys, size, dir); return vdma_alloc(phys, size); } @@ -600,7 +600,7 @@ size_t size, enum dma_data_direction dir, unsigned long attrs) { if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - arch_sync_dma_for_cpu(dev, vdma_log2phys(dma_addr), size, dir); + arch_sync_dma_for_cpu(vdma_log2phys(dma_addr), size, dir); vdma_free(dma_addr); } @@ -612,7 +612,7 @@ for_each_sg(sglist, sg, nents, i) { if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - arch_sync_dma_for_device(dev, sg_phys(sg), sg->length, + arch_sync_dma_for_device(sg_phys(sg), sg->length, dir); sg->dma_address = vdma_alloc(sg_phys(sg), sg->length); if (sg->dma_address == DMA_MAPPING_ERROR) @@ -631,8 +631,7 @@ for_each_sg(sglist, sg, nents, i) { if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) - arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, - dir); + arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); vdma_free(sg->dma_address); } } @@ -640,13 +639,13 @@ static void jazz_dma_sync_single_for_device(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { - arch_sync_dma_for_device(dev, vdma_log2phys(addr), size, dir); + arch_sync_dma_for_device(vdma_log2phys(addr), size, dir); } static void jazz_dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { - arch_sync_dma_for_cpu(dev, vdma_log2phys(addr), size, dir); + arch_sync_dma_for_cpu(vdma_log2phys(addr), size, dir); } static void jazz_dma_sync_sg_for_device(struct device *dev, @@ -656,7 +655,7 @@ int i; for_each_sg(sgl, sg, nents, i) - arch_sync_dma_for_device(dev, sg_phys(sg), sg->length, dir); + arch_sync_dma_for_device(sg_phys(sg), sg->length, dir); } static void jazz_dma_sync_sg_for_cpu(struct device *dev, @@ -666,7 +665,7 @@ int i; for_each_sg(sgl, sg, nents, i) - arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir); + arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); } const struct dma_map_ops jazz_dma_ops = { --- linux-oracle-5.4.0.orig/arch/mips/jz4740/setup.c +++ linux-oracle-5.4.0/arch/mips/jz4740/setup.c @@ -61,7 +61,7 @@ jz4740_reset_init(); - if (__dtb_start != __dtb_end) + if (&__dtb_start != &__dtb_end) dtb = __dtb_start; else dtb = (void *)fw_passed_dtb; --- linux-oracle-5.4.0.orig/arch/mips/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/mips/kernel/asm-offsets.c @@ -100,6 +100,7 @@ OFFSET(TI_PRE_COUNT, thread_info, preempt_count); OFFSET(TI_ADDR_LIMIT, thread_info, addr_limit); OFFSET(TI_REGS, thread_info, regs); + OFFSET(TI_SYSCALL, thread_info, syscall); DEFINE(_THREAD_SIZE, THREAD_SIZE); DEFINE(_THREAD_MASK, THREAD_MASK); DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE); --- linux-oracle-5.4.0.orig/arch/mips/kernel/cacheinfo.c +++ linux-oracle-5.4.0/arch/mips/kernel/cacheinfo.c @@ -17,7 +17,7 @@ leaf++; \ } while (0) -static int __init_cache_level(unsigned int cpu) +int init_cache_level(unsigned int cpu) { struct cpuinfo_mips *c = ¤t_cpu_data; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); @@ -50,21 +50,46 @@ return 0; } -static int __populate_cache_leaves(unsigned int cpu) +static void fill_cpumask_siblings(int cpu, cpumask_t *cpu_map) +{ + int cpu1; + + for_each_possible_cpu(cpu1) + if (cpus_are_siblings(cpu, cpu1)) + cpumask_set_cpu(cpu1, cpu_map); +} + +static void fill_cpumask_cluster(int cpu, cpumask_t *cpu_map) +{ + int cpu1; + int cluster = cpu_cluster(&cpu_data[cpu]); + + for_each_possible_cpu(cpu1) + if (cpu_cluster(&cpu_data[cpu1]) == cluster) + cpumask_set_cpu(cpu1, cpu_map); +} + +int populate_cache_leaves(unsigned int cpu) { struct cpuinfo_mips *c = ¤t_cpu_data; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cacheinfo *this_leaf = this_cpu_ci->info_list; if (c->icache.waysize) { + /* L1 caches are per core */ + fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); populate_cache(dcache, this_leaf, 1, CACHE_TYPE_DATA); + fill_cpumask_siblings(cpu, &this_leaf->shared_cpu_map); populate_cache(icache, this_leaf, 1, CACHE_TYPE_INST); } else { populate_cache(dcache, this_leaf, 1, CACHE_TYPE_UNIFIED); } - if (c->scache.waysize) + if (c->scache.waysize) { + /* L2 cache is per cluster */ + fill_cpumask_cluster(cpu, &this_leaf->shared_cpu_map); populate_cache(scache, this_leaf, 2, CACHE_TYPE_UNIFIED); + } if (c->tcache.waysize) populate_cache(tcache, this_leaf, 3, CACHE_TYPE_UNIFIED); @@ -73,6 +98,3 @@ return 0; } - -DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) -DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) --- linux-oracle-5.4.0.orig/arch/mips/kernel/elf.c +++ linux-oracle-5.4.0/arch/mips/kernel/elf.c @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_MIPS_FP_SUPPORT @@ -309,6 +310,11 @@ struct cpuinfo_mips *c = &boot_cpu_data; struct task_struct *t = current; + /* Do this early so t->thread.fpu.fcr31 won't be clobbered in case + * we are preempted before the lose_fpu(0) in start_thread. + */ + lose_fpu(0); + t->thread.fpu.fcr31 = c->fpu_csr31; switch (state->nan_2008) { case 0: --- linux-oracle-5.4.0.orig/arch/mips/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/mips/kernel/ftrace.c @@ -264,7 +264,7 @@ #define S_R_SP (0xafb0 << 16) /* s{d,w} R, offset(sp) */ #define OFFSET_MASK 0xffff /* stack offset range: 0 ~ PT_SIZE */ -unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long +static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long old_parent_ra, unsigned long parent_ra_addr, unsigned long fp) { unsigned long sp, ip, tmp; --- linux-oracle-5.4.0.orig/arch/mips/kernel/genex.S +++ linux-oracle-5.4.0/arch/mips/kernel/genex.S @@ -474,20 +474,20 @@ .endm .macro __build_clear_fpe + CLI + TRACE_IRQS_OFF .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 SET_HARDFLOAT cfc1 a1, fcr31 .set pop - CLI - TRACE_IRQS_OFF .endm .macro __build_clear_msa_fpe - _cfcmsa a1, MSA_CSR CLI TRACE_IRQS_OFF + _cfcmsa a1, MSA_CSR .endm .macro __build_clear_ade --- linux-oracle-5.4.0.orig/arch/mips/kernel/jump_label.c +++ linux-oracle-5.4.0/arch/mips/kernel/jump_label.c @@ -56,7 +56,7 @@ * The branch offset must fit in the instruction's 26 * bit field. */ - WARN_ON((offset >= BIT(25)) || + WARN_ON((offset >= (long)BIT(25)) || (offset < -(long)BIT(25))); insn.j_format.opcode = bc6_op; --- linux-oracle-5.4.0.orig/arch/mips/kernel/mips-cm.c +++ linux-oracle-5.4.0/arch/mips/kernel/mips-cm.c @@ -119,9 +119,9 @@ "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07", "0x08", "0x09", "0x0a", "0x0b", "0x0c", "0x0d", "0x0e", "0x0f", - "0x10", "0x11", "0x12", "0x13", - "0x14", "0x15", "0x16", "INTVN_WR_ERR", - "INTVN_RD_ERR", "0x19", "0x1a", "0x1b", + "0x10", "INTVN_WR_ERR", "INTVN_RD_ERR", "0x13", + "0x14", "0x15", "0x16", "0x17", + "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" }; @@ -179,8 +179,7 @@ phys_addr_t addr; /* L2-only sync was introduced with CM major revision 6 */ - major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR) >> - __ffs(CM_GCR_REV_MAJOR); + major_rev = FIELD_GET(CM_GCR_REV_MAJOR, read_gcr_rev()); if (major_rev < 6) return; @@ -263,13 +262,13 @@ preempt_disable(); if (cm_rev >= CM_REV_CM3) { - val = core << __ffs(CM3_GCR_Cx_OTHER_CORE); - val |= vp << __ffs(CM3_GCR_Cx_OTHER_VP); + val = FIELD_PREP(CM3_GCR_Cx_OTHER_CORE, core) | + FIELD_PREP(CM3_GCR_Cx_OTHER_VP, vp); if (cm_rev >= CM_REV_CM3_5) { val |= CM_GCR_Cx_OTHER_CLUSTER_EN; - val |= cluster << __ffs(CM_GCR_Cx_OTHER_CLUSTER); - val |= block << __ffs(CM_GCR_Cx_OTHER_BLOCK); + val |= FIELD_PREP(CM_GCR_Cx_OTHER_CLUSTER, cluster); + val |= FIELD_PREP(CM_GCR_Cx_OTHER_BLOCK, block); } else { WARN_ON(cluster != 0); WARN_ON(block != CM_GCR_Cx_OTHER_BLOCK_LOCAL); @@ -299,7 +298,7 @@ spin_lock_irqsave(&per_cpu(cm_core_lock, curr_core), per_cpu(cm_core_lock_flags, curr_core)); - val = core << __ffs(CM_GCR_Cx_OTHER_CORENUM); + val = FIELD_PREP(CM_GCR_Cx_OTHER_CORENUM, core); } write_gcr_cl_other(val); @@ -343,8 +342,8 @@ cm_other = read_gcr_error_mult(); if (revision < CM_REV_CM3) { /* CM2 */ - cause = cm_error >> __ffs(CM_GCR_ERROR_CAUSE_ERRTYPE); - ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); + cause = FIELD_GET(CM_GCR_ERROR_CAUSE_ERRTYPE, cm_error); + ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other); if (!cause) return; @@ -386,8 +385,8 @@ ulong core_id_bits, vp_id_bits, cmd_bits, cmd_group_bits; ulong cm3_cca_bits, mcp_bits, cm3_tr_bits, sched_bit; - cause = cm_error >> __ffs64(CM3_GCR_ERROR_CAUSE_ERRTYPE); - ocause = cm_other >> __ffs(CM_GCR_ERROR_MULT_ERR2ND); + cause = FIELD_GET(CM3_GCR_ERROR_CAUSE_ERRTYPE, cm_error); + ocause = FIELD_GET(CM_GCR_ERROR_MULT_ERR2ND, cm_other); if (!cause) return; --- linux-oracle-5.4.0.orig/arch/mips/kernel/mips-cpc.c +++ linux-oracle-5.4.0/arch/mips/kernel/mips-cpc.c @@ -27,6 +27,7 @@ cpc_node = of_find_compatible_node(of_root, NULL, "mti,mips-cpc"); if (cpc_node) { err = of_address_to_resource(cpc_node, 0, &res); + of_node_put(cpc_node); if (!err) return res.start; } --- linux-oracle-5.4.0.orig/arch/mips/kernel/proc.c +++ linux-oracle-5.4.0/arch/mips/kernel/proc.c @@ -168,7 +168,7 @@ { unsigned long i = *pos; - return i < NR_CPUS ? (void *) (i + 1) : NULL; + return i < nr_cpu_ids ? (void *) (i + 1) : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) --- linux-oracle-5.4.0.orig/arch/mips/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/mips/kernel/ptrace.c @@ -1399,16 +1399,13 @@ * Notification of system call entry/exit * - triggered by current->work.syscall_trace */ -asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) +asmlinkage long syscall_trace_enter(struct pt_regs *regs) { user_exit(); - current_thread_info()->syscall = syscall; - if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (tracehook_report_syscall_entry(regs)) return -1; - syscall = current_thread_info()->syscall; } #ifdef CONFIG_SECCOMP @@ -1417,7 +1414,7 @@ struct seccomp_data sd; unsigned long args[6]; - sd.nr = syscall; + sd.nr = current_thread_info()->syscall; sd.arch = syscall_get_arch(current); syscall_get_arguments(current, regs, args); for (i = 0; i < 6; i++) @@ -1427,23 +1424,23 @@ ret = __secure_computing(&sd); if (ret == -1) return ret; - syscall = current_thread_info()->syscall; } #endif if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[2]); - audit_syscall_entry(syscall, regs->regs[4], regs->regs[5], + audit_syscall_entry(current_thread_info()->syscall, + regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); /* * Negative syscall numbers are mistaken for rejected syscalls, but * won't have had the return value set appropriately, so we do so now. */ - if (syscall < 0) + if (current_thread_info()->syscall < 0) syscall_set_return_value(current, regs, -ENOSYS, 0); - return syscall; + return current_thread_info()->syscall; } /* --- linux-oracle-5.4.0.orig/arch/mips/kernel/r2300_fpu.S +++ linux-oracle-5.4.0/arch/mips/kernel/r2300_fpu.S @@ -29,8 +29,8 @@ #define EX2(a,b) \ 9: a,##b; \ .section __ex_table,"a"; \ - PTR 9b,bad_stack; \ - PTR 9b+4,bad_stack; \ + PTR 9b,fault; \ + PTR 9b+4,fault; \ .previous .set mips1 --- linux-oracle-5.4.0.orig/arch/mips/kernel/relocate.c +++ linux-oracle-5.4.0/arch/mips/kernel/relocate.c @@ -187,8 +187,14 @@ static inline __init unsigned long rotate_xor(unsigned long hash, const void *area, size_t size) { - size_t i; - unsigned long *ptr = (unsigned long *)area; + const typeof(hash) *ptr = PTR_ALIGN(area, sizeof(hash)); + size_t diff, i; + + diff = (void *)ptr - area; + if (unlikely(size < diff + sizeof(hash))) + return hash; + + size = ALIGN_DOWN(size - diff, sizeof(hash)); for (i = 0; i < size / sizeof(hash); i++) { /* Rotate by odd number of bits and XOR. */ --- linux-oracle-5.4.0.orig/arch/mips/kernel/scall32-o32.S +++ linux-oracle-5.4.0/arch/mips/kernel/scall32-o32.S @@ -80,6 +80,18 @@ PTR load_a7, bad_stack_a7 .previous + /* + * syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + */ + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_WORK_SYSCALL_ENTRY and t0, t1 @@ -117,16 +129,7 @@ SAVE_STATIC move a0, sp - /* - * syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - */ - move a1, v0 - subu t2, v0, __NR_O32_Linux - bnez t2, 1f /* __NR_syscall at offset 0 */ - lw a1, PT_R4(sp) - -1: jal syscall_trace_enter + jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-oracle-5.4.0.orig/arch/mips/kernel/scall64-n32.S +++ linux-oracle-5.4.0/arch/mips/kernel/scall64-n32.S @@ -44,6 +44,8 @@ sd a3, PT_R26(sp) # save a3 for syscall restarting + LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -72,7 +74,6 @@ n32_syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-oracle-5.4.0.orig/arch/mips/kernel/scall64-n64.S +++ linux-oracle-5.4.0/arch/mips/kernel/scall64-n64.S @@ -47,6 +47,8 @@ sd a3, PT_R26(sp) # save a3 for syscall restarting + LONG_S v0, TI_SYSCALL($28) # Store syscall number + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -83,7 +85,6 @@ syscall_trace_entry: SAVE_STATIC move a0, sp - move a1, v0 jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-oracle-5.4.0.orig/arch/mips/kernel/scall64-o32.S +++ linux-oracle-5.4.0/arch/mips/kernel/scall64-o32.S @@ -79,6 +79,22 @@ PTR load_a7, bad_stack_a7 .previous + /* + * absolute syscall number is in v0 unless we called syscall(__NR_###) + * where the real syscall number is in a0 + * note: NR_syscall is the first O32 syscall but the macro is + * only defined when compiling with -mabi=32 (CONFIG_32BIT) + * therefore __NR_O32_Linux is used (4000) + */ + + subu t2, v0, __NR_O32_Linux + bnez t2, 1f /* __NR_syscall at offset 0 */ + LONG_S a0, TI_SYSCALL($28) # Save a0 as syscall number + b 2f +1: + LONG_S v0, TI_SYSCALL($28) # Save v0 as syscall number +2: + li t1, _TIF_WORK_SYSCALL_ENTRY LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 @@ -113,22 +129,7 @@ sd a7, PT_R11(sp) # For indirect syscalls move a0, sp - /* - * absolute syscall number is in v0 unless we called syscall(__NR_###) - * where the real syscall number is in a0 - * note: NR_syscall is the first O32 syscall but the macro is - * only defined when compiling with -mabi=32 (CONFIG_32BIT) - * therefore __NR_O32_Linux is used (4000) - */ - .set push - .set reorder - subu t1, v0, __NR_O32_Linux - move a1, v0 - bnez t1, 1f /* __NR_syscall at offset 0 */ - ld a1, PT_R4(sp) /* Arg1 for __NR_syscall case */ - .set pop - -1: jal syscall_trace_enter + jal syscall_trace_enter bltz v0, 1f # seccomp failed? Skip syscall --- linux-oracle-5.4.0.orig/arch/mips/kernel/setup.c +++ linux-oracle-5.4.0/arch/mips/kernel/setup.c @@ -11,6 +11,8 @@ * Copyright (C) 2000, 2001, 2002, 2007 Maciej W. Rozycki */ #include +#include +#include #include #include #include @@ -190,10 +192,6 @@ pr_err("initrd start must be page aligned\n"); goto disable; } - if (initrd_start < PAGE_OFFSET) { - pr_err("initrd start < PAGE_OFFSET\n"); - goto disable; - } /* * Sanitize initrd addresses. For example firmware @@ -206,6 +204,11 @@ initrd_end = (unsigned long)__va(end); initrd_start = (unsigned long)__va(__pa(initrd_start)); + if (initrd_start < PAGE_OFFSET) { + pr_err("initrd start < PAGE_OFFSET\n"); + goto disable; + } + ROOT_DEV = Root_RAM0; return PFN_UP(end); disable: @@ -359,11 +362,11 @@ panic("Incorrect memory mapping !!!"); if (max_pfn > PFN_DOWN(HIGHMEM_START)) { + max_low_pfn = PFN_DOWN(HIGHMEM_START); #ifdef CONFIG_HIGHMEM - highstart_pfn = PFN_DOWN(HIGHMEM_START); + highstart_pfn = max_low_pfn; highend_pfn = max_pfn; #else - max_low_pfn = PFN_DOWN(HIGHMEM_START); max_pfn = max_low_pfn; #endif } @@ -494,7 +497,7 @@ if (ret != 0 || crash_size <= 0) return; - if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) { + if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 1)) { pr_warn("Invalid memory region reserved for crash kernel\n"); return; } @@ -529,8 +532,8 @@ static void __init check_kernel_sections_mem(void) { - phys_addr_t start = PFN_PHYS(PFN_DOWN(__pa_symbol(&_text))); - phys_addr_t size = PFN_PHYS(PFN_UP(__pa_symbol(&_end))) - start; + phys_addr_t start = __pa_symbol(&_text); + phys_addr_t size = __pa_symbol(&_end) - start; if (!memblock_is_region_memory(start, size)) { pr_info("Kernel sections are not in the memory maps\n"); @@ -653,7 +656,17 @@ crashk_res.end - crashk_res.start + 1); #endif device_tree_init(); + + /* + * In order to reduce the possibility of kernel panic when failed to + * get IO TLB memory under CONFIG_SWIOTLB, it is better to allocate + * low memory as small as possible before plat_swiotlb_setup(), so + * make sparse_init() using top-down allocation. + */ + memblock_set_bottom_up(false); sparse_init(); + memblock_set_bottom_up(true); + plat_swiotlb_setup(); dma_contiguous_reserve(PFN_PHYS(max_low_pfn)); @@ -801,3 +814,14 @@ } early_param("nocoherentio", setnocoherentio); #endif + +void __init arch_cpu_finalize_init(void) +{ + unsigned int cpu = smp_processor_id(); + + cpu_data[cpu].udelay_val = loops_per_jiffy; + check_bugs32(); + + if (IS_ENABLED(CONFIG_CPU_R4X00_BUGS64)) + check_bugs64(); +} --- linux-oracle-5.4.0.orig/arch/mips/kernel/smp-bmips.c +++ linux-oracle-5.4.0/arch/mips/kernel/smp-bmips.c @@ -241,6 +241,8 @@ */ static void bmips_init_secondary(void) { + bmips_cpu_setup(); + switch (current_cpu_type()) { case CPU_BMIPS4350: case CPU_BMIPS4380: --- linux-oracle-5.4.0.orig/arch/mips/kernel/smp-cps.c +++ linux-oracle-5.4.0/arch/mips/kernel/smp-cps.c @@ -229,7 +229,10 @@ write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB); /* Ensure the core can access the GCRs */ - set_gcr_access(1 << core); + if (mips_cm_revision() < CM_REV_CM3) + set_gcr_access(1 << core); + else + set_gcr_access_cm3(1 << core); if (mips_cpc_present()) { /* Reset the core */ @@ -423,9 +426,11 @@ wmb(); } } else { - pr_debug("Gating power to core %d\n", core); - /* Power down the core */ - cps_pm_enter_state(CPS_PM_POWER_GATED); + if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) { + pr_debug("Gating power to core %d\n", core); + /* Power down the core */ + cps_pm_enter_state(CPS_PM_POWER_GATED); + } } } --- linux-oracle-5.4.0.orig/arch/mips/kernel/smp.c +++ linux-oracle-5.4.0/arch/mips/kernel/smp.c @@ -361,6 +361,9 @@ cpu = smp_processor_id(); cpu_data[cpu].udelay_val = loops_per_jiffy; + set_cpu_sibling_map(cpu); + set_cpu_core_map(cpu); + cpumask_set_cpu(cpu, &cpu_coherent_mask); notify_cpu_starting(cpu); @@ -372,9 +375,6 @@ /* The CPU is running and counters synchronised, now mark it online */ set_cpu_online(cpu, true); - set_cpu_sibling_map(cpu); - set_cpu_core_map(cpu); - calculate_cpu_foreign_map(); /* --- linux-oracle-5.4.0.orig/arch/mips/kernel/syscall.c +++ linux-oracle-5.4.0/arch/mips/kernel/syscall.c @@ -239,12 +239,3 @@ { return -ENOSYS; } - -/* - * If we ever come here the user sp is bad. Zap the process right away. - * Due to the bad stack signaling wouldn't work. - */ -asmlinkage void bad_stack(void) -{ - do_exit(SIGSEGV); -} --- linux-oracle-5.4.0.orig/arch/mips/kernel/syscalls/Makefile +++ linux-oracle-5.4.0/arch/mips/kernel/syscalls/Makefile @@ -18,7 +18,7 @@ '$(syshdr_pfx_$(basetarget))' \ '$(syshdr_offset_$(basetarget))' -quiet_cmd_sysnr = SYSNR $@ +quiet_cmd_sysnr = SYSNR $@ cmd_sysnr = $(CONFIG_SHELL) '$(sysnr)' '$<' '$@' \ '$(sysnr_abis_$(basetarget))' \ '$(sysnr_pfx_$(basetarget))' \ --- linux-oracle-5.4.0.orig/arch/mips/kernel/syscalls/syscall_o32.tbl +++ linux-oracle-5.4.0/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -27,7 +27,7 @@ 17 o32 break sys_ni_syscall # 18 was sys_stat 18 o32 unused18 sys_ni_syscall -19 o32 lseek sys_lseek +19 o32 lseek sys_lseek compat_sys_lseek 20 o32 getpid sys_getpid 21 o32 mount sys_mount compat_sys_mount 22 o32 umount sys_oldumount --- linux-oracle-5.4.0.orig/arch/mips/kernel/time.c +++ linux-oracle-5.4.0/arch/mips/kernel/time.c @@ -18,12 +18,82 @@ #include #include #include +#include +#include #include #include #include #include +#ifdef CONFIG_CPU_FREQ + +static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref); +static DEFINE_PER_CPU(unsigned long, pcp_lpj_ref_freq); +static unsigned long glb_lpj_ref; +static unsigned long glb_lpj_ref_freq; + +static int cpufreq_callback(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct cpufreq_freqs *freq = data; + struct cpumask *cpus = freq->policy->cpus; + unsigned long lpj; + int cpu; + + /* + * Skip lpj numbers adjustment if the CPU-freq transition is safe for + * the loops delay. (Is this possible?) + */ + if (freq->flags & CPUFREQ_CONST_LOOPS) + return NOTIFY_OK; + + /* Save the initial values of the lpjes for future scaling. */ + if (!glb_lpj_ref) { + glb_lpj_ref = boot_cpu_data.udelay_val; + glb_lpj_ref_freq = freq->old; + + for_each_online_cpu(cpu) { + per_cpu(pcp_lpj_ref, cpu) = + cpu_data[cpu].udelay_val; + per_cpu(pcp_lpj_ref_freq, cpu) = freq->old; + } + } + + /* + * Adjust global lpj variable and per-CPU udelay_val number in + * accordance with the new CPU frequency. + */ + if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || + (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { + loops_per_jiffy = cpufreq_scale(glb_lpj_ref, + glb_lpj_ref_freq, + freq->new); + + for_each_cpu(cpu, cpus) { + lpj = cpufreq_scale(per_cpu(pcp_lpj_ref, cpu), + per_cpu(pcp_lpj_ref_freq, cpu), + freq->new); + cpu_data[cpu].udelay_val = (unsigned int)lpj; + } + } + + return NOTIFY_OK; +} + +static struct notifier_block cpufreq_notifier = { + .notifier_call = cpufreq_callback, +}; + +static int __init register_cpufreq_notifier(void) +{ + return cpufreq_register_notifier(&cpufreq_notifier, + CPUFREQ_TRANSITION_NOTIFIER); +} +core_initcall(register_cpufreq_notifier); + +#endif /* CONFIG_CPU_FREQ */ + /* * forward reference */ @@ -71,15 +141,10 @@ case CPU_R4400MC: /* * The published errata for the R4400 up to 3.0 say the CPU - * has the mfc0 from count bug. + * has the mfc0 from count bug. This seems the last version + * produced. */ - if ((current_cpu_data.processor_id & 0xff) <= 0x30) - return 1; - - /* - * we assume newer revisions are ok - */ - return 0; + return 1; } return 0; --- linux-oracle-5.4.0.orig/arch/mips/kernel/topology.c +++ linux-oracle-5.4.0/arch/mips/kernel/topology.c @@ -20,7 +20,7 @@ for_each_present_cpu(i) { struct cpu *c = &per_cpu(cpu_devices, i); - c->hotpluggable = 1; + c->hotpluggable = !!i; ret = register_cpu(c, i); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " --- linux-oracle-5.4.0.orig/arch/mips/kernel/traps.c +++ linux-oracle-5.4.0/arch/mips/kernel/traps.c @@ -415,7 +415,7 @@ if (regs && kexec_should_crash(current)) crash_kexec(regs); - do_exit(sig); + make_task_dead(sig); } extern struct exception_table_entry __start___dbe_table[]; @@ -1240,6 +1240,18 @@ err = own_fpu_inatomic(1); if (msa && !err) { enable_msa(); + /* + * with MSA enabled, userspace can see MSACSR + * and MSA regs, but the values in them are from + * other task before current task, restore them + * from saved fp/msa context + */ + write_msa_csr(current->thread.fpu.msacsr); + /* + * own_fpu_inatomic(1) just restore low 64bit, + * fix the high 64bit + */ + init_msa_upper(); set_thread_flag(TIF_USEDMSA); set_thread_flag(TIF_MSA_CTX_LIVE); } @@ -2008,19 +2020,19 @@ * If no shadow set is selected then use the default handler * that does normal register saving and standard interrupt exit */ - extern char except_vec_vi, except_vec_vi_lui; - extern char except_vec_vi_ori, except_vec_vi_end; - extern char rollback_except_vec_vi; - char *vec_start = using_rollback_handler() ? - &rollback_except_vec_vi : &except_vec_vi; + extern const u8 except_vec_vi[], except_vec_vi_lui[]; + extern const u8 except_vec_vi_ori[], except_vec_vi_end[]; + extern const u8 rollback_except_vec_vi[]; + const u8 *vec_start = using_rollback_handler() ? + rollback_except_vec_vi : except_vec_vi; #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN) - const int lui_offset = &except_vec_vi_lui - vec_start + 2; - const int ori_offset = &except_vec_vi_ori - vec_start + 2; + const int lui_offset = except_vec_vi_lui - vec_start + 2; + const int ori_offset = except_vec_vi_ori - vec_start + 2; #else - const int lui_offset = &except_vec_vi_lui - vec_start; - const int ori_offset = &except_vec_vi_ori - vec_start; + const int lui_offset = except_vec_vi_lui - vec_start; + const int ori_offset = except_vec_vi_ori - vec_start; #endif - const int handler_len = &except_vec_vi_end - vec_start; + const int handler_len = except_vec_vi_end - vec_start; if (handler_len > VECTORSPACING) { /* @@ -2126,6 +2138,7 @@ change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, status_set); + back_to_back_c0_hazard(); } unsigned int hwrena; @@ -2227,7 +2240,7 @@ } /* Install CPU exception handler */ -void set_handler(unsigned long offset, void *addr, unsigned long size) +void set_handler(unsigned long offset, const void *addr, unsigned long size) { #ifdef CONFIG_CPU_MICROMIPS memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size); --- linux-oracle-5.4.0.orig/arch/mips/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/mips/kernel/vmlinux.lds.S @@ -10,6 +10,8 @@ */ #define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir) +#define RUNTIME_DISCARD_EXIT + #include #undef mips @@ -50,7 +52,7 @@ /* . = 0xa800000000300000; */ . = 0xffffffff80300000; #endif - . = VMLINUX_LOAD_ADDRESS; + . = LINKER_LOAD_ADDRESS; /* read-only */ _text = .; /* Text and read-only data */ .text : { @@ -93,6 +95,7 @@ INIT_TASK_DATA(THREAD_SIZE) NOSAVE_DATA + PAGE_ALIGNED_DATA(PAGE_SIZE) CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) DATA_DATA @@ -225,6 +228,5 @@ *(.options) *(.pdr) *(.reginfo) - *(.eh_frame) } } --- linux-oracle-5.4.0.orig/arch/mips/kernel/vpe-cmp.c +++ linux-oracle-5.4.0/arch/mips/kernel/vpe-cmp.c @@ -75,7 +75,6 @@ static void vpe_device_release(struct device *cd) { - kfree(cd); } static struct class vpe_class = { @@ -157,6 +156,7 @@ device_del(&vpe_device); out_class: + put_device(&vpe_device); class_unregister(&vpe_class); out_chrdev: @@ -169,7 +169,7 @@ { struct vpe *v, *n; - device_del(&vpe_device); + device_unregister(&vpe_device); class_unregister(&vpe_class); unregister_chrdev(major, VPE_MODULE_NAME); --- linux-oracle-5.4.0.orig/arch/mips/kernel/vpe-mt.c +++ linux-oracle-5.4.0/arch/mips/kernel/vpe-mt.c @@ -92,12 +92,11 @@ write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); /* - * The sde-kit passes 'memsize' to __start in $a3, so set something - * here... Or set $a3 to zero and define DFLT_STACK_SIZE and - * DFLT_HEAP_SIZE when you compile your program + * We don't pass the memsize here, so VPE programs need to be + * compiled with DFLT_STACK_SIZE and DFLT_HEAP_SIZE defined. */ + mttgpr(7, 0); mttgpr(6, v->ntcs); - mttgpr(7, physical_memsize); /* set up VPE1 */ /* @@ -313,7 +312,6 @@ static void vpe_device_release(struct device *cd) { - kfree(cd); } static struct class vpe_class = { @@ -497,6 +495,7 @@ device_del(&vpe_device); out_class: + put_device(&vpe_device); class_unregister(&vpe_class); out_chrdev: @@ -509,7 +508,7 @@ { struct vpe *v, *n; - device_del(&vpe_device); + device_unregister(&vpe_device); class_unregister(&vpe_class); unregister_chrdev(major, VPE_MODULE_NAME); --- linux-oracle-5.4.0.orig/arch/mips/kernel/vpe.c +++ linux-oracle-5.4.0/arch/mips/kernel/vpe.c @@ -134,7 +134,7 @@ { list_del(&v->list); if (v->load_addr) - release_progmem(v); + release_progmem(v->load_addr); kfree(v); } --- linux-oracle-5.4.0.orig/arch/mips/kvm/mips.c +++ linux-oracle-5.4.0/arch/mips/kvm/mips.c @@ -131,6 +131,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { switch (type) { + case KVM_VM_MIPS_AUTO: + break; #ifdef CONFIG_KVM_MIPS_VZ case KVM_VM_MIPS_VZ: #else --- linux-oracle-5.4.0.orig/arch/mips/kvm/mmu.c +++ linux-oracle-5.4.0/arch/mips/kvm/mmu.c @@ -512,7 +512,8 @@ return 1; } -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, + unsigned flags) { handle_hva_to_gpa(kvm, start, end, &kvm_unmap_hva_handler, NULL); @@ -692,7 +693,7 @@ gfn_t gfn = gpa >> PAGE_SHIFT; int srcu_idx, err; kvm_pfn_t pfn; - pte_t *ptep, entry, old_pte; + pte_t *ptep, entry; bool writeable; unsigned long prot_bits; unsigned long mmu_seq; @@ -765,7 +766,6 @@ entry = pfn_pte(pfn, __pgprot(prot_bits)); /* Write the PTE */ - old_pte = *ptep; set_pte(ptep, entry); err = 0; --- linux-oracle-5.4.0.orig/arch/mips/lantiq/clk.c +++ linux-oracle-5.4.0/arch/mips/lantiq/clk.c @@ -50,6 +50,7 @@ { return &cpu_clk_generic[2]; } +EXPORT_SYMBOL_GPL(clk_get_io); struct clk *clk_get_ppe(void) { @@ -158,6 +159,18 @@ } EXPORT_SYMBOL(clk_deactivate); +struct clk *clk_get_parent(struct clk *clk) +{ + return NULL; +} +EXPORT_SYMBOL(clk_get_parent); + +int clk_set_parent(struct clk *clk, struct clk *parent) +{ + return 0; +} +EXPORT_SYMBOL(clk_set_parent); + static inline u32 get_counter_resolution(void) { u32 res; --- linux-oracle-5.4.0.orig/arch/mips/lantiq/falcon/sysctrl.c +++ linux-oracle-5.4.0/arch/mips/lantiq/falcon/sysctrl.c @@ -167,6 +167,8 @@ { struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + if (!clk) + return; clk->cl.dev_id = dev; clk->cl.con_id = NULL; clk->cl.clk = clk; --- linux-oracle-5.4.0.orig/arch/mips/lantiq/irq.c +++ linux-oracle-5.4.0/arch/mips/lantiq/irq.c @@ -302,7 +302,7 @@ generic_handle_irq(irq_linear_revmap(ltq_domain, hwirq)); /* if this is a EBU irq, we need to ack it or get a deadlock */ - if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT) + if (irq == LTQ_ICU_EBU_IRQ && !module && LTQ_EBU_PCC_ISTAT != 0) ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, LTQ_EBU_PCC_ISTAT); } --- linux-oracle-5.4.0.orig/arch/mips/lantiq/prom.c +++ linux-oracle-5.4.0/arch/mips/lantiq/prom.c @@ -23,12 +23,6 @@ EXPORT_SYMBOL_GPL(ebu_lock); /* - * This is needed by the VPE loader code, just set it to 0 and assume - * that the firmware hardcodes this value to something useful. - */ -unsigned long physical_memsize = 0L; - -/* * this struct is filled by the soc specific detection code and holds * information about the specific soc type, revision and name */ @@ -79,7 +73,7 @@ if (fw_passed_dtb) /* UHI interface */ dtb = (void *)fw_passed_dtb; - else if (__dtb_start != __dtb_end) + else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start; else panic("no dtb found"); --- linux-oracle-5.4.0.orig/arch/mips/lantiq/xway/dma.c +++ linux-oracle-5.4.0/arch/mips/lantiq/xway/dma.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -29,6 +30,7 @@ #define LTQ_DMA_PCTRL 0x44 #define LTQ_DMA_IRNEN 0xf4 +#define DMA_ID_CHNR GENMASK(26, 20) /* channel number */ #define DMA_DESCPT BIT(3) /* descriptor complete irq */ #define DMA_TX BIT(8) /* TX channel direction */ #define DMA_CHAN_ON BIT(0) /* channel on / off bit */ @@ -39,7 +41,6 @@ #define DMA_POLL BIT(31) /* turn on channel polling */ #define DMA_CLK_DIV4 BIT(6) /* polling clock divider */ #define DMA_2W_BURST BIT(1) /* 2 word burst length */ -#define DMA_MAX_CHANNEL 20 /* the soc has 20 channels */ #define DMA_ETOP_ENDIANNESS (0xf << 8) /* endianness swap etop channels */ #define DMA_WEIGHT (BIT(17) | BIT(16)) /* default channel wheight */ @@ -205,7 +206,7 @@ { struct clk *clk; struct resource *res; - unsigned id; + unsigned int id, nchannels; int i; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -221,21 +222,24 @@ clk_enable(clk); ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); + usleep_range(1, 10); + /* disable all interrupts */ ltq_dma_w32(0, LTQ_DMA_IRNEN); /* reset/configure each channel */ - for (i = 0; i < DMA_MAX_CHANNEL; i++) { + id = ltq_dma_r32(LTQ_DMA_ID); + nchannels = ((id & DMA_ID_CHNR) >> 20); + for (i = 0; i < nchannels; i++) { ltq_dma_w32(i, LTQ_DMA_CS); ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL); ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); } - id = ltq_dma_r32(LTQ_DMA_ID); dev_info(&pdev->dev, "Init done - hw rev: %X, ports: %d, channels: %d\n", - id & 0x1f, (id >> 16) & 0xf, id >> 20); + id & 0x1f, (id >> 16) & 0xf, nchannels); return 0; } --- linux-oracle-5.4.0.orig/arch/mips/lantiq/xway/gptu.c +++ linux-oracle-5.4.0/arch/mips/lantiq/xway/gptu.c @@ -122,6 +122,8 @@ { struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + if (!clk) + return; clk->cl.dev_id = dev_name(dev); clk->cl.con_id = con; clk->cl.clk = clk; --- linux-oracle-5.4.0.orig/arch/mips/lantiq/xway/sysctrl.c +++ linux-oracle-5.4.0/arch/mips/lantiq/xway/sysctrl.c @@ -311,6 +311,8 @@ { struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + if (!clk) + return; clk->cl.dev_id = dev; clk->cl.con_id = con; clk->cl.clk = clk; @@ -334,6 +336,8 @@ { struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + if (!clk) + return; clk->cl.dev_id = dev; clk->cl.con_id = con; clk->cl.clk = clk; @@ -352,24 +356,28 @@ struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL); /* main pci clock */ - clk->cl.dev_id = "17000000.pci"; - clk->cl.con_id = NULL; - clk->cl.clk = clk; - clk->rate = CLOCK_33M; - clk->rates = valid_pci_rates; - clk->enable = pci_enable; - clk->disable = pmu_disable; - clk->module = 0; - clk->bits = PMU_PCI; - clkdev_add(&clk->cl); + if (clk) { + clk->cl.dev_id = "17000000.pci"; + clk->cl.con_id = NULL; + clk->cl.clk = clk; + clk->rate = CLOCK_33M; + clk->rates = valid_pci_rates; + clk->enable = pci_enable; + clk->disable = pmu_disable; + clk->module = 0; + clk->bits = PMU_PCI; + clkdev_add(&clk->cl); + } /* use internal/external bus clock */ - clk_ext->cl.dev_id = "17000000.pci"; - clk_ext->cl.con_id = "external"; - clk_ext->cl.clk = clk_ext; - clk_ext->enable = pci_ext_enable; - clk_ext->disable = pci_ext_disable; - clkdev_add(&clk_ext->cl); + if (clk_ext) { + clk_ext->cl.dev_id = "17000000.pci"; + clk_ext->cl.con_id = "external"; + clk_ext->cl.clk = clk_ext; + clk_ext->enable = pci_ext_enable; + clk_ext->disable = pci_ext_disable; + clkdev_add(&clk_ext->cl); + } } /* xway socs can generate clocks on gpio pins */ @@ -389,9 +397,15 @@ char *name; name = kzalloc(sizeof("clkout0"), GFP_KERNEL); + if (!name) + continue; sprintf(name, "clkout%d", i); clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + if (!clk) { + kfree(name); + continue; + } clk->cl.dev_id = "1f103000.cgu"; clk->cl.con_id = name; clk->cl.clk = clk; @@ -514,8 +528,8 @@ clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP | PMU_PPE_TC); clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); - clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); - clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "afe", 1, 2, PMU_ANALOG_DSL_AFE); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); @@ -538,8 +552,8 @@ PMU_SWITCH | PMU_PPE_DPLUS | PMU_PPE_DPLUM | PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 | PMU_PPE_QSB | PMU_PPE_TOP); - clkdev_add_pmu("1e108000.gswip", "gphy0", 0, 0, PMU_GPHY); - clkdev_add_pmu("1e108000.gswip", "gphy1", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy0", 0, 0, PMU_GPHY); + clkdev_add_pmu("1e108000.switch", "gphy1", 0, 0, PMU_GPHY); clkdev_add_pmu("1e103000.sdio", NULL, 1, 0, PMU_SDIO); clkdev_add_pmu("1e103100.deu", NULL, 1, 0, PMU_DEU); clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE); --- linux-oracle-5.4.0.orig/arch/mips/lasat/picvue_proc.c +++ linux-oracle-5.4.0/arch/mips/lasat/picvue_proc.c @@ -39,7 +39,7 @@ pvc_write_string(pvc_lines[i], 0, i); } -static DECLARE_TASKLET(pvc_display_tasklet, &pvc_display, 0); +static DECLARE_TASKLET_OLD(pvc_display_tasklet, &pvc_display); static int pvc_line_proc_show(struct seq_file *m, void *v) { --- linux-oracle-5.4.0.orig/arch/mips/lib/dump_tlb.c +++ linux-oracle-5.4.0/arch/mips/lib/dump_tlb.c @@ -80,7 +80,7 @@ unsigned int pagemask, guestctl1 = 0, c0, c1, i; unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); - unsigned long uninitialized_var(s_mmid); + unsigned long s_mmid; #ifdef CONFIG_32BIT bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); int pwidth = xpa ? 11 : 8; --- linux-oracle-5.4.0.orig/arch/mips/lib/mips-atomic.c +++ linux-oracle-5.4.0/arch/mips/lib/mips-atomic.c @@ -37,7 +37,7 @@ */ notrace void arch_local_irq_disable(void) { - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -53,7 +53,7 @@ : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_disable); @@ -61,7 +61,7 @@ { unsigned long flags; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -78,7 +78,7 @@ : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); return flags; } @@ -88,7 +88,7 @@ { unsigned long __tmp1; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -106,7 +106,7 @@ : "0" (flags) : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_restore); --- linux-oracle-5.4.0.orig/arch/mips/lib/uncached.c +++ linux-oracle-5.4.0/arch/mips/lib/uncached.c @@ -37,10 +37,12 @@ */ unsigned long run_uncached(void *func) { - register long sp __asm__("$sp"); register long ret __asm__("$2"); long lfunc = (long)func, ufunc; long usp; + long sp; + + __asm__("move %0, $sp" : "=r" (sp)); if (sp >= (long)CKSEG0 && sp < (long)CKSEG2) usp = CKSEG1ADDR(sp); --- linux-oracle-5.4.0.orig/arch/mips/loongson32/common/platform.c +++ linux-oracle-5.4.0/arch/mips/loongson32/common/platform.c @@ -98,7 +98,7 @@ if (plat_dat->bus_id) { __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | GMAC1_USE_UART0, LS1X_MUX_CTRL0); - switch (plat_dat->interface) { + switch (plat_dat->phy_interface) { case PHY_INTERFACE_MODE_RGMII: val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); break; @@ -107,12 +107,12 @@ break; default: pr_err("unsupported mii mode %d\n", - plat_dat->interface); + plat_dat->phy_interface); return -ENOTSUPP; } val &= ~GMAC1_SHUT; } else { - switch (plat_dat->interface) { + switch (plat_dat->phy_interface) { case PHY_INTERFACE_MODE_RGMII: val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); break; @@ -121,7 +121,7 @@ break; default: pr_err("unsupported mii mode %d\n", - plat_dat->interface); + plat_dat->phy_interface); return -ENOTSUPP; } val &= ~GMAC0_SHUT; @@ -131,7 +131,7 @@ plat_dat = dev_get_platdata(&pdev->dev); val &= ~PHY_INTF_SELI; - if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) + if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII) val |= 0x4 << PHY_INTF_SELI_SHIFT; __raw_writel(val, LS1X_MUX_CTRL1); @@ -146,9 +146,9 @@ .bus_id = 0, .phy_addr = -1, #if defined(CONFIG_LOONGSON1_LS1B) - .interface = PHY_INTERFACE_MODE_MII, + .phy_interface = PHY_INTERFACE_MODE_MII, #elif defined(CONFIG_LOONGSON1_LS1C) - .interface = PHY_INTERFACE_MODE_RMII, + .phy_interface = PHY_INTERFACE_MODE_RMII, #endif .mdio_bus_data = &ls1x_mdio_bus_data, .dma_cfg = &ls1x_eth_dma_cfg, @@ -186,7 +186,7 @@ static struct plat_stmmacenet_data ls1x_eth1_pdata = { .bus_id = 1, .phy_addr = -1, - .interface = PHY_INTERFACE_MODE_MII, + .phy_interface = PHY_INTERFACE_MODE_MII, .mdio_bus_data = &ls1x_mdio_bus_data, .dma_cfg = &ls1x_eth_dma_cfg, .has_gmac = 1, --- linux-oracle-5.4.0.orig/arch/mips/loongson32/ls1c/board.c +++ linux-oracle-5.4.0/arch/mips/loongson32/ls1c/board.c @@ -15,7 +15,6 @@ static int __init ls1c_platform_init(void) { ls1x_serial_set_uartclk(&ls1x_uart_pdev); - ls1x_rtc_set_extclk(&ls1x_rtc_pdev); return platform_add_devices(ls1c_platform_devices, ARRAY_SIZE(ls1c_platform_devices)); --- linux-oracle-5.4.0.orig/arch/mips/loongson64/loongson-3/numa.c +++ linux-oracle-5.4.0/arch/mips/loongson64/loongson-3/numa.c @@ -200,6 +200,9 @@ if (node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) memblock_reserve((node_addrspace_offset | 0xfe000000), 32 << 20); + + /* Reserve pfn range 0~node[0]->node_start_pfn */ + memblock_reserve(0, PAGE_SIZE * start_pfn); } } --- linux-oracle-5.4.0.orig/arch/mips/loongson64/loongson-3/platform.c +++ linux-oracle-5.4.0/arch/mips/loongson64/loongson-3/platform.c @@ -27,6 +27,9 @@ continue; pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + if (!pdev) + return -ENOMEM; + pdev->name = loongson_sysconf.sensors[i].name; pdev->id = loongson_sysconf.sensors[i].id; pdev->dev.platform_data = &loongson_sysconf.sensors[i]; --- linux-oracle-5.4.0.orig/arch/mips/mm/c-r4k.c +++ linux-oracle-5.4.0/arch/mips/mm/c-r4k.c @@ -1560,7 +1560,7 @@ return 1; } -static void __init loongson2_sc_init(void) +static void loongson2_sc_init(void) { struct cpuinfo_mips *c = ¤t_cpu_data; @@ -1576,7 +1576,7 @@ c->options |= MIPS_CPU_INCLUSIVE_CACHES; } -static void __init loongson3_sc_init(void) +static void loongson3_sc_init(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config2, lsize; @@ -1676,7 +1676,11 @@ printk("MIPS secondary cache %ldkB, %s, linesize %d bytes.\n", scache_size >> 10, way_string[c->scache.ways], c->scache.linesz); + + if (current_cpu_type() == CPU_BMIPS5000) + c->options |= MIPS_CPU_INCLUSIVE_CACHES; } + #else if (!(c->scache.flags & MIPS_CACHE_NOT_PRESENT)) panic("Dunno how to handle MIPS32 / MIPS64 second level cache"); --- linux-oracle-5.4.0.orig/arch/mips/mm/dma-noncoherent.c +++ linux-oracle-5.4.0/arch/mips/mm/dma-noncoherent.c @@ -27,7 +27,7 @@ * R10000 and R12000 are used in such systems, the SGI IP28 Indigo² rsp. * SGI IP32 aka O2. */ -static inline bool cpu_needs_post_dma_flush(struct device *dev) +static inline bool cpu_needs_post_dma_flush(void) { switch (boot_cpu_type()) { case CPU_R10000: @@ -118,17 +118,17 @@ } while (left); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { dma_sync_phys(paddr, size, dir); } #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - if (cpu_needs_post_dma_flush(dev)) + if (cpu_needs_post_dma_flush()) dma_sync_phys(paddr, size, dir); } #endif --- linux-oracle-5.4.0.orig/arch/mips/mm/init.c +++ linux-oracle-5.4.0/arch/mips/mm/init.c @@ -84,7 +84,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) { enum fixed_addresses idx; - unsigned int uninitialized_var(old_mmid); + unsigned int old_mmid; unsigned long vaddr, flags, entrylo; unsigned long old_ctx; pte_t pte; @@ -416,9 +416,14 @@ (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10)); max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn; } + + max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; +#else + max_mapnr = max_low_pfn; #endif + high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); } #ifdef CONFIG_64BIT @@ -452,16 +457,6 @@ */ BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT)); -#ifdef CONFIG_HIGHMEM -#ifdef CONFIG_DISCONTIGMEM -#error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet" -#endif - max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; -#else - max_mapnr = max_low_pfn; -#endif - high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); - maar_init(); memblock_free_all(); setup_zero_pages(); /* Setup zeroed pages. */ --- linux-oracle-5.4.0.orig/arch/mips/mm/sc-mips.c +++ linux-oracle-5.4.0/arch/mips/mm/sc-mips.c @@ -147,7 +147,7 @@ return 1; } -static int __init mips_sc_probe_cm3(void) +static int mips_sc_probe_cm3(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned long cfg = read_gcr_l2_config(); @@ -181,7 +181,7 @@ return 0; } -static inline int __init mips_sc_probe(void) +static inline int mips_sc_probe(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int config1, config2; --- linux-oracle-5.4.0.orig/arch/mips/mm/tlb-r4k.c +++ linux-oracle-5.4.0/arch/mips/mm/tlb-r4k.c @@ -120,7 +120,7 @@ if (size <= (current_cpu_data.tlbsizeftlbsets ? current_cpu_data.tlbsize / 8 : current_cpu_data.tlbsize / 2)) { - unsigned long old_entryhi, uninitialized_var(old_mmid); + unsigned long old_entryhi, old_mmid; int newpid = cpu_asid(cpu, mm); old_entryhi = read_c0_entryhi(); @@ -214,7 +214,7 @@ int cpu = smp_processor_id(); if (cpu_context(cpu, vma->vm_mm) != 0) { - unsigned long uninitialized_var(old_mmid); + unsigned long old_mmid; unsigned long flags, old_entryhi; int idx; @@ -381,7 +381,7 @@ #ifdef CONFIG_XPA panic("Broken for XPA kernels"); #else - unsigned int uninitialized_var(old_mmid); + unsigned int old_mmid; unsigned long flags; unsigned long wired; unsigned long old_pagemask; @@ -437,6 +437,7 @@ } return mask == PM_HUGE_MASK; } +EXPORT_SYMBOL(has_transparent_hugepage); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ --- linux-oracle-5.4.0.orig/arch/mips/mm/tlbex.c +++ linux-oracle-5.4.0/arch/mips/mm/tlbex.c @@ -629,7 +629,7 @@ return; } - if (cpu_has_rixi && !!_PAGE_NO_EXEC) { + if (cpu_has_rixi && _PAGE_NO_EXEC != 0) { if (fill_includes_sw_bits) { UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); } else { @@ -1480,6 +1480,7 @@ static void setup_pw(void) { + unsigned int pwctl; unsigned long pgd_i, pgd_w; #ifndef __PAGETABLE_PMD_FOLDED unsigned long pmd_i, pmd_w; @@ -1506,6 +1507,7 @@ pte_i = ilog2(_PAGE_GLOBAL); pte_w = 0; + pwctl = 1 << 30; /* Set PWDirExt */ #ifndef __PAGETABLE_PMD_FOLDED write_c0_pwfield(pgd_i << 24 | pmd_i << 12 | pt_i << 6 | pte_i); @@ -1516,8 +1518,9 @@ #endif #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT - write_c0_pwctl(1 << 6 | psn); + pwctl |= (1 << 6 | psn); #endif + write_c0_pwctl(pwctl); write_c0_kpgd((long)swapper_pg_dir); kscratch_used_mask |= (1 << 7); /* KScratch6 is used for KPGD */ } @@ -2565,7 +2568,7 @@ unsigned long entry; unsigned pabits, fillbits; - if (!cpu_has_rixi || !_PAGE_NO_EXEC) { + if (!cpu_has_rixi || _PAGE_NO_EXEC == 0) { /* * We'll only be making use of the fact that we can rotate bits * into the fill if the CPU supports RIXI, so don't bother --- linux-oracle-5.4.0.orig/arch/mips/mti-malta/malta-dtshim.c +++ linux-oracle-5.4.0/arch/mips/mti-malta/malta-dtshim.c @@ -22,7 +22,7 @@ #define ROCIT_CONFIG_GEN1_MEMMAP_SHIFT 8 #define ROCIT_CONFIG_GEN1_MEMMAP_MASK (0xf << 8) -static unsigned char fdt_buf[16 << 10] __initdata; +static unsigned char fdt_buf[16 << 10] __initdata __aligned(8); /* determined physical memory size, not overridden by command line args */ extern unsigned long physical_memsize; --- linux-oracle-5.4.0.orig/arch/mips/mti-malta/malta-platform.c +++ linux-oracle-5.4.0/arch/mips/mti-malta/malta-platform.c @@ -47,7 +47,8 @@ .mapbase = 0x1f000900, /* The CBUS UART */ .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, .uartclk = 3686400, /* Twice the usual clk! */ - .iotype = UPIO_MEM32, + .iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ? + UPIO_MEM32BE : UPIO_MEM32, .flags = CBUS_UART_FLAGS, .regshift = 3, }, --- linux-oracle-5.4.0.orig/arch/mips/net/Makefile +++ linux-oracle-5.4.0/arch/mips/net/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only # MIPS networking code +obj-$(CONFIG_MIPS_CBPF_JIT) += bpf_jit.o bpf_jit_asm.o obj-$(CONFIG_MIPS_EBPF_JIT) += ebpf_jit.o --- linux-oracle-5.4.0.orig/arch/mips/net/bpf_jit.c +++ linux-oracle-5.4.0/arch/mips/net/bpf_jit.c @@ -0,0 +1,1299 @@ +/* + * Just-In-Time compiler for BPF filters on MIPS + * + * Copyright (c) 2014 Imagination Technologies Ltd. + * Author: Markos Chandras + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bpf_jit.h" + +/* ABI + * r_skb_hl SKB header length + * r_data SKB data pointer + * r_off Offset + * r_A BPF register A + * r_X BPF register X + * r_skb *skb + * r_M *scratch memory + * r_skb_len SKB length + * + * On entry (*bpf_func)(*skb, *filter) + * a0 = MIPS_R_A0 = skb; + * a1 = MIPS_R_A1 = filter; + * + * Stack + * ... + * M[15] + * M[14] + * M[13] + * ... + * M[0] <-- r_M + * saved reg k-1 + * saved reg k-2 + * ... + * saved reg 0 <-- r_sp + * + * + * Packet layout + * + * <--------------------- len ------------------------> + * <--skb-len(r_skb_hl)-->< ----- skb->data_len ------> + * ---------------------------------------------------- + * | skb->data | + * ---------------------------------------------------- + */ + +#define ptr typeof(unsigned long) + +#define SCRATCH_OFF(k) (4 * (k)) + +/* JIT flags */ +#define SEEN_CALL (1 << BPF_MEMWORDS) +#define SEEN_SREG_SFT (BPF_MEMWORDS + 1) +#define SEEN_SREG_BASE (1 << SEEN_SREG_SFT) +#define SEEN_SREG(x) (SEEN_SREG_BASE << (x)) +#define SEEN_OFF SEEN_SREG(2) +#define SEEN_A SEEN_SREG(3) +#define SEEN_X SEEN_SREG(4) +#define SEEN_SKB SEEN_SREG(5) +#define SEEN_MEM SEEN_SREG(6) +/* SEEN_SK_DATA also implies skb_hl an skb_len */ +#define SEEN_SKB_DATA (SEEN_SREG(7) | SEEN_SREG(1) | SEEN_SREG(0)) + +/* Arguments used by JIT */ +#define ARGS_USED_BY_JIT 2 /* only applicable to 64-bit */ + +#define SBIT(x) (1 << (x)) /* Signed version of BIT() */ + +/** + * struct jit_ctx - JIT context + * @skf: The sk_filter + * @prologue_bytes: Number of bytes for prologue + * @idx: Instruction index + * @flags: JIT flags + * @offsets: Instruction offsets + * @target: Memory location for the compiled filter + */ +struct jit_ctx { + const struct bpf_prog *skf; + unsigned int prologue_bytes; + u32 idx; + u32 flags; + u32 *offsets; + u32 *target; +}; + + +static inline int optimize_div(u32 *k) +{ + /* power of 2 divides can be implemented with right shift */ + if (!(*k & (*k-1))) { + *k = ilog2(*k); + return 1; + } + + return 0; +} + +static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx); + +/* Simply emit the instruction if the JIT memory space has been allocated */ +#define emit_instr(ctx, func, ...) \ +do { \ + if ((ctx)->target != NULL) { \ + u32 *p = &(ctx)->target[ctx->idx]; \ + uasm_i_##func(&p, ##__VA_ARGS__); \ + } \ + (ctx)->idx++; \ +} while (0) + +/* + * Similar to emit_instr but it must be used when we need to emit + * 32-bit or 64-bit instructions + */ +#define emit_long_instr(ctx, func, ...) \ +do { \ + if ((ctx)->target != NULL) { \ + u32 *p = &(ctx)->target[ctx->idx]; \ + UASM_i_##func(&p, ##__VA_ARGS__); \ + } \ + (ctx)->idx++; \ +} while (0) + +/* Determine if immediate is within the 16-bit signed range */ +static inline bool is_range16(s32 imm) +{ + return !(imm >= SBIT(15) || imm < -SBIT(15)); +} + +static inline void emit_addu(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, addu, dst, src1, src2); +} + +static inline void emit_nop(struct jit_ctx *ctx) +{ + emit_instr(ctx, nop); +} + +/* Load a u32 immediate to a register */ +static inline void emit_load_imm(unsigned int dst, u32 imm, struct jit_ctx *ctx) +{ + if (ctx->target != NULL) { + /* addiu can only handle s16 */ + if (!is_range16(imm)) { + u32 *p = &ctx->target[ctx->idx]; + uasm_i_lui(&p, r_tmp_imm, (s32)imm >> 16); + p = &ctx->target[ctx->idx + 1]; + uasm_i_ori(&p, dst, r_tmp_imm, imm & 0xffff); + } else { + u32 *p = &ctx->target[ctx->idx]; + uasm_i_addiu(&p, dst, r_zero, imm); + } + } + ctx->idx++; + + if (!is_range16(imm)) + ctx->idx++; +} + +static inline void emit_or(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, or, dst, src1, src2); +} + +static inline void emit_ori(unsigned int dst, unsigned src, u32 imm, + struct jit_ctx *ctx) +{ + if (imm >= BIT(16)) { + emit_load_imm(r_tmp, imm, ctx); + emit_or(dst, src, r_tmp, ctx); + } else { + emit_instr(ctx, ori, dst, src, imm); + } +} + +static inline void emit_daddiu(unsigned int dst, unsigned int src, + int imm, struct jit_ctx *ctx) +{ + /* + * Only used for stack, so the imm is relatively small + * and it fits in 15-bits + */ + emit_instr(ctx, daddiu, dst, src, imm); +} + +static inline void emit_addiu(unsigned int dst, unsigned int src, + u32 imm, struct jit_ctx *ctx) +{ + if (!is_range16(imm)) { + emit_load_imm(r_tmp, imm, ctx); + emit_addu(dst, r_tmp, src, ctx); + } else { + emit_instr(ctx, addiu, dst, src, imm); + } +} + +static inline void emit_and(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, and, dst, src1, src2); +} + +static inline void emit_andi(unsigned int dst, unsigned int src, + u32 imm, struct jit_ctx *ctx) +{ + /* If imm does not fit in u16 then load it to register */ + if (imm >= BIT(16)) { + emit_load_imm(r_tmp, imm, ctx); + emit_and(dst, src, r_tmp, ctx); + } else { + emit_instr(ctx, andi, dst, src, imm); + } +} + +static inline void emit_xor(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, xor, dst, src1, src2); +} + +static inline void emit_xori(ptr dst, ptr src, u32 imm, struct jit_ctx *ctx) +{ + /* If imm does not fit in u16 then load it to register */ + if (imm >= BIT(16)) { + emit_load_imm(r_tmp, imm, ctx); + emit_xor(dst, src, r_tmp, ctx); + } else { + emit_instr(ctx, xori, dst, src, imm); + } +} + +static inline void emit_stack_offset(int offset, struct jit_ctx *ctx) +{ + emit_long_instr(ctx, ADDIU, r_sp, r_sp, offset); +} + +static inline void emit_subu(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, subu, dst, src1, src2); +} + +static inline void emit_neg(unsigned int reg, struct jit_ctx *ctx) +{ + emit_subu(reg, r_zero, reg, ctx); +} + +static inline void emit_sllv(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + emit_instr(ctx, sllv, dst, src, sa); +} + +static inline void emit_sll(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + /* sa is 5-bits long */ + if (sa >= BIT(5)) + /* Shifting >= 32 results in zero */ + emit_jit_reg_move(dst, r_zero, ctx); + else + emit_instr(ctx, sll, dst, src, sa); +} + +static inline void emit_srlv(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + emit_instr(ctx, srlv, dst, src, sa); +} + +static inline void emit_srl(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + /* sa is 5-bits long */ + if (sa >= BIT(5)) + /* Shifting >= 32 results in zero */ + emit_jit_reg_move(dst, r_zero, ctx); + else + emit_instr(ctx, srl, dst, src, sa); +} + +static inline void emit_slt(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, slt, dst, src1, src2); +} + +static inline void emit_sltu(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, sltu, dst, src1, src2); +} + +static inline void emit_sltiu(unsigned dst, unsigned int src, + unsigned int imm, struct jit_ctx *ctx) +{ + /* 16 bit immediate */ + if (!is_range16((s32)imm)) { + emit_load_imm(r_tmp, imm, ctx); + emit_sltu(dst, src, r_tmp, ctx); + } else { + emit_instr(ctx, sltiu, dst, src, imm); + } + +} + +/* Store register on the stack */ +static inline void emit_store_stack_reg(ptr reg, ptr base, + unsigned int offset, + struct jit_ctx *ctx) +{ + emit_long_instr(ctx, SW, reg, offset, base); +} + +static inline void emit_store(ptr reg, ptr base, unsigned int offset, + struct jit_ctx *ctx) +{ + emit_instr(ctx, sw, reg, offset, base); +} + +static inline void emit_load_stack_reg(ptr reg, ptr base, + unsigned int offset, + struct jit_ctx *ctx) +{ + emit_long_instr(ctx, LW, reg, offset, base); +} + +static inline void emit_load(unsigned int reg, unsigned int base, + unsigned int offset, struct jit_ctx *ctx) +{ + emit_instr(ctx, lw, reg, offset, base); +} + +static inline void emit_load_byte(unsigned int reg, unsigned int base, + unsigned int offset, struct jit_ctx *ctx) +{ + emit_instr(ctx, lb, reg, offset, base); +} + +static inline void emit_half_load(unsigned int reg, unsigned int base, + unsigned int offset, struct jit_ctx *ctx) +{ + emit_instr(ctx, lh, reg, offset, base); +} + +static inline void emit_half_load_unsigned(unsigned int reg, unsigned int base, + unsigned int offset, struct jit_ctx *ctx) +{ + emit_instr(ctx, lhu, reg, offset, base); +} + +static inline void emit_mul(unsigned int dst, unsigned int src1, + unsigned int src2, struct jit_ctx *ctx) +{ + emit_instr(ctx, mul, dst, src1, src2); +} + +static inline void emit_div(unsigned int dst, unsigned int src, + struct jit_ctx *ctx) +{ + if (ctx->target != NULL) { + u32 *p = &ctx->target[ctx->idx]; + uasm_i_divu(&p, dst, src); + p = &ctx->target[ctx->idx + 1]; + uasm_i_mflo(&p, dst); + } + ctx->idx += 2; /* 2 insts */ +} + +static inline void emit_mod(unsigned int dst, unsigned int src, + struct jit_ctx *ctx) +{ + if (ctx->target != NULL) { + u32 *p = &ctx->target[ctx->idx]; + uasm_i_divu(&p, dst, src); + p = &ctx->target[ctx->idx + 1]; + uasm_i_mfhi(&p, dst); + } + ctx->idx += 2; /* 2 insts */ +} + +static inline void emit_dsll(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + emit_instr(ctx, dsll, dst, src, sa); +} + +static inline void emit_dsrl32(unsigned int dst, unsigned int src, + unsigned int sa, struct jit_ctx *ctx) +{ + emit_instr(ctx, dsrl32, dst, src, sa); +} + +static inline void emit_wsbh(unsigned int dst, unsigned int src, + struct jit_ctx *ctx) +{ + emit_instr(ctx, wsbh, dst, src); +} + +/* load pointer to register */ +static inline void emit_load_ptr(unsigned int dst, unsigned int src, + int imm, struct jit_ctx *ctx) +{ + /* src contains the base addr of the 32/64-pointer */ + emit_long_instr(ctx, LW, dst, imm, src); +} + +/* load a function pointer to register */ +static inline void emit_load_func(unsigned int reg, ptr imm, + struct jit_ctx *ctx) +{ + if (IS_ENABLED(CONFIG_64BIT)) { + /* At this point imm is always 64-bit */ + emit_load_imm(r_tmp, (u64)imm >> 32, ctx); + emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */ + emit_ori(r_tmp, r_tmp_imm, (imm >> 16) & 0xffff, ctx); + emit_dsll(r_tmp_imm, r_tmp, 16, ctx); /* left shift by 16 */ + emit_ori(reg, r_tmp_imm, imm & 0xffff, ctx); + } else { + emit_load_imm(reg, imm, ctx); + } +} + +/* Move to real MIPS register */ +static inline void emit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx) +{ + emit_long_instr(ctx, ADDU, dst, src, r_zero); +} + +/* Move to JIT (32-bit) register */ +static inline void emit_jit_reg_move(ptr dst, ptr src, struct jit_ctx *ctx) +{ + emit_addu(dst, src, r_zero, ctx); +} + +/* Compute the immediate value for PC-relative branches. */ +static inline u32 b_imm(unsigned int tgt, struct jit_ctx *ctx) +{ + if (ctx->target == NULL) + return 0; + + /* + * We want a pc-relative branch. We only do forward branches + * so tgt is always after pc. tgt is the instruction offset + * we want to jump to. + + * Branch on MIPS: + * I: target_offset <- sign_extend(offset) + * I+1: PC += target_offset (delay slot) + * + * ctx->idx currently points to the branch instruction + * but the offset is added to the delay slot so we need + * to subtract 4. + */ + return ctx->offsets[tgt] - + (ctx->idx * 4 - ctx->prologue_bytes) - 4; +} + +static inline void emit_bcond(int cond, unsigned int reg1, unsigned int reg2, + unsigned int imm, struct jit_ctx *ctx) +{ + if (ctx->target != NULL) { + u32 *p = &ctx->target[ctx->idx]; + + switch (cond) { + case MIPS_COND_EQ: + uasm_i_beq(&p, reg1, reg2, imm); + break; + case MIPS_COND_NE: + uasm_i_bne(&p, reg1, reg2, imm); + break; + case MIPS_COND_ALL: + uasm_i_b(&p, imm); + break; + default: + pr_warn("%s: Unhandled branch conditional: %d\n", + __func__, cond); + } + } + ctx->idx++; +} + +static inline void emit_b(unsigned int imm, struct jit_ctx *ctx) +{ + emit_bcond(MIPS_COND_ALL, r_zero, r_zero, imm, ctx); +} + +static inline void emit_jalr(unsigned int link, unsigned int reg, + struct jit_ctx *ctx) +{ + emit_instr(ctx, jalr, link, reg); +} + +static inline void emit_jr(unsigned int reg, struct jit_ctx *ctx) +{ + emit_instr(ctx, jr, reg); +} + +static inline u16 align_sp(unsigned int num) +{ + /* Double word alignment for 32-bit, quadword for 64-bit */ + unsigned int align = IS_ENABLED(CONFIG_64BIT) ? 16 : 8; + num = (num + (align - 1)) & -align; + return num; +} + +static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) +{ + int i = 0, real_off = 0; + u32 sflags, tmp_flags; + + /* Adjust the stack pointer */ + if (offset) + emit_stack_offset(-align_sp(offset), ctx); + + tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT; + /* sflags is essentially a bitmap */ + while (tmp_flags) { + if ((sflags >> i) & 0x1) { + emit_store_stack_reg(MIPS_R_S0 + i, r_sp, real_off, + ctx); + real_off += SZREG; + } + i++; + tmp_flags >>= 1; + } + + /* save return address */ + if (ctx->flags & SEEN_CALL) { + emit_store_stack_reg(r_ra, r_sp, real_off, ctx); + real_off += SZREG; + } + + /* Setup r_M leaving the alignment gap if necessary */ + if (ctx->flags & SEEN_MEM) { + if (real_off % (SZREG * 2)) + real_off += SZREG; + emit_long_instr(ctx, ADDIU, r_M, r_sp, real_off); + } +} + +static void restore_bpf_jit_regs(struct jit_ctx *ctx, + unsigned int offset) +{ + int i, real_off = 0; + u32 sflags, tmp_flags; + + tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT; + /* sflags is a bitmap */ + i = 0; + while (tmp_flags) { + if ((sflags >> i) & 0x1) { + emit_load_stack_reg(MIPS_R_S0 + i, r_sp, real_off, + ctx); + real_off += SZREG; + } + i++; + tmp_flags >>= 1; + } + + /* restore return address */ + if (ctx->flags & SEEN_CALL) + emit_load_stack_reg(r_ra, r_sp, real_off, ctx); + + /* Restore the sp and discard the scrach memory */ + if (offset) + emit_stack_offset(align_sp(offset), ctx); +} + +static unsigned int get_stack_depth(struct jit_ctx *ctx) +{ + int sp_off = 0; + + + /* How may s* regs do we need to preserved? */ + sp_off += hweight32(ctx->flags >> SEEN_SREG_SFT) * SZREG; + + if (ctx->flags & SEEN_MEM) + sp_off += 4 * BPF_MEMWORDS; /* BPF_MEMWORDS are 32-bit */ + + if (ctx->flags & SEEN_CALL) + sp_off += SZREG; /* Space for our ra register */ + + return sp_off; +} + +static void build_prologue(struct jit_ctx *ctx) +{ + int sp_off; + + /* Calculate the total offset for the stack pointer */ + sp_off = get_stack_depth(ctx); + save_bpf_jit_regs(ctx, sp_off); + + if (ctx->flags & SEEN_SKB) + emit_reg_move(r_skb, MIPS_R_A0, ctx); + + if (ctx->flags & SEEN_SKB_DATA) { + /* Load packet length */ + emit_load(r_skb_len, r_skb, offsetof(struct sk_buff, len), + ctx); + emit_load(r_tmp, r_skb, offsetof(struct sk_buff, data_len), + ctx); + /* Load the data pointer */ + emit_load_ptr(r_skb_data, r_skb, + offsetof(struct sk_buff, data), ctx); + /* Load the header length */ + emit_subu(r_skb_hl, r_skb_len, r_tmp, ctx); + } + + if (ctx->flags & SEEN_X) + emit_jit_reg_move(r_X, r_zero, ctx); + + /* + * Do not leak kernel data to userspace, we only need to clear + * r_A if it is ever used. In fact if it is never used, we + * will not save/restore it, so clearing it in this case would + * corrupt the state of the caller. + */ + if (bpf_needs_clear_a(&ctx->skf->insns[0]) && + (ctx->flags & SEEN_A)) + emit_jit_reg_move(r_A, r_zero, ctx); +} + +static void build_epilogue(struct jit_ctx *ctx) +{ + unsigned int sp_off; + + /* Calculate the total offset for the stack pointer */ + + sp_off = get_stack_depth(ctx); + restore_bpf_jit_regs(ctx, sp_off); + + /* Return */ + emit_jr(r_ra, ctx); + emit_nop(ctx); +} + +#define CHOOSE_LOAD_FUNC(K, func) \ + ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative : func) : \ + func##_positive) + +static bool is_bad_offset(int b_off) +{ + return b_off > 0x1ffff || b_off < -0x20000; +} + +static int build_body(struct jit_ctx *ctx) +{ + const struct bpf_prog *prog = ctx->skf; + const struct sock_filter *inst; + unsigned int i, off, condt; + u32 k, b_off __maybe_unused; + u8 (*sk_load_func)(unsigned long *skb, int offset); + + for (i = 0; i < prog->len; i++) { + u16 code; + + inst = &(prog->insns[i]); + pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n", + __func__, inst->code, inst->jt, inst->jf, inst->k); + k = inst->k; + code = bpf_anc_helper(inst); + + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + switch (code) { + case BPF_LD | BPF_IMM: + /* A <- k ==> li r_A, k */ + ctx->flags |= SEEN_A; + emit_load_imm(r_A, k, ctx); + break; + case BPF_LD | BPF_W | BPF_LEN: + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); + /* A <- len ==> lw r_A, offset(skb) */ + ctx->flags |= SEEN_SKB | SEEN_A; + off = offsetof(struct sk_buff, len); + emit_load(r_A, r_skb, off, ctx); + break; + case BPF_LD | BPF_MEM: + /* A <- M[k] ==> lw r_A, offset(M) */ + ctx->flags |= SEEN_MEM | SEEN_A; + emit_load(r_A, r_M, SCRATCH_OFF(k), ctx); + break; + case BPF_LD | BPF_W | BPF_ABS: + /* A <- P[k:4] */ + sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_word); + goto load; + case BPF_LD | BPF_H | BPF_ABS: + /* A <- P[k:2] */ + sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_half); + goto load; + case BPF_LD | BPF_B | BPF_ABS: + /* A <- P[k:1] */ + sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_byte); +load: + emit_load_imm(r_off, k, ctx); +load_common: + ctx->flags |= SEEN_CALL | SEEN_OFF | + SEEN_SKB | SEEN_A | SEEN_SKB_DATA; + + emit_load_func(r_s0, (ptr)sk_load_func, ctx); + emit_reg_move(MIPS_R_A0, r_skb, ctx); + emit_jalr(MIPS_R_RA, r_s0, ctx); + /* Load second argument to delay slot */ + emit_reg_move(MIPS_R_A1, r_off, ctx); + /* Check the error value */ + emit_bcond(MIPS_COND_EQ, r_ret, 0, b_imm(i + 1, ctx), + ctx); + /* Load return register on DS for failures */ + emit_reg_move(r_ret, r_zero, ctx); + /* Return with error */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_b(b_off, ctx); + emit_nop(ctx); + break; + case BPF_LD | BPF_W | BPF_IND: + /* A <- P[X + k:4] */ + sk_load_func = sk_load_word; + goto load_ind; + case BPF_LD | BPF_H | BPF_IND: + /* A <- P[X + k:2] */ + sk_load_func = sk_load_half; + goto load_ind; + case BPF_LD | BPF_B | BPF_IND: + /* A <- P[X + k:1] */ + sk_load_func = sk_load_byte; +load_ind: + ctx->flags |= SEEN_OFF | SEEN_X; + emit_addiu(r_off, r_X, k, ctx); + goto load_common; + case BPF_LDX | BPF_IMM: + /* X <- k */ + ctx->flags |= SEEN_X; + emit_load_imm(r_X, k, ctx); + break; + case BPF_LDX | BPF_MEM: + /* X <- M[k] */ + ctx->flags |= SEEN_X | SEEN_MEM; + emit_load(r_X, r_M, SCRATCH_OFF(k), ctx); + break; + case BPF_LDX | BPF_W | BPF_LEN: + /* X <- len */ + ctx->flags |= SEEN_X | SEEN_SKB; + off = offsetof(struct sk_buff, len); + emit_load(r_X, r_skb, off, ctx); + break; + case BPF_LDX | BPF_B | BPF_MSH: + /* X <- 4 * (P[k:1] & 0xf) */ + ctx->flags |= SEEN_X | SEEN_CALL | SEEN_SKB; + /* Load offset to a1 */ + emit_load_func(r_s0, (ptr)sk_load_byte, ctx); + /* + * This may emit two instructions so it may not fit + * in the delay slot. So use a0 in the delay slot. + */ + emit_load_imm(MIPS_R_A1, k, ctx); + emit_jalr(MIPS_R_RA, r_s0, ctx); + emit_reg_move(MIPS_R_A0, r_skb, ctx); /* delay slot */ + /* Check the error value */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_bcond(MIPS_COND_NE, r_ret, 0, b_off, ctx); + emit_reg_move(r_ret, r_zero, ctx); + /* We are good */ + /* X <- P[1:K] & 0xf */ + emit_andi(r_X, r_A, 0xf, ctx); + /* X << 2 */ + emit_b(b_imm(i + 1, ctx), ctx); + emit_sll(r_X, r_X, 2, ctx); /* delay slot */ + break; + case BPF_ST: + /* M[k] <- A */ + ctx->flags |= SEEN_MEM | SEEN_A; + emit_store(r_A, r_M, SCRATCH_OFF(k), ctx); + break; + case BPF_STX: + /* M[k] <- X */ + ctx->flags |= SEEN_MEM | SEEN_X; + emit_store(r_X, r_M, SCRATCH_OFF(k), ctx); + break; + case BPF_ALU | BPF_ADD | BPF_K: + /* A += K */ + ctx->flags |= SEEN_A; + emit_addiu(r_A, r_A, k, ctx); + break; + case BPF_ALU | BPF_ADD | BPF_X: + /* A += X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_addu(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_SUB | BPF_K: + /* A -= K */ + ctx->flags |= SEEN_A; + emit_addiu(r_A, r_A, -k, ctx); + break; + case BPF_ALU | BPF_SUB | BPF_X: + /* A -= X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_subu(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_MUL | BPF_K: + /* A *= K */ + /* Load K to scratch register before MUL */ + ctx->flags |= SEEN_A; + emit_load_imm(r_s0, k, ctx); + emit_mul(r_A, r_A, r_s0, ctx); + break; + case BPF_ALU | BPF_MUL | BPF_X: + /* A *= X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_mul(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_DIV | BPF_K: + /* A /= k */ + if (k == 1) + break; + if (optimize_div(&k)) { + ctx->flags |= SEEN_A; + emit_srl(r_A, r_A, k, ctx); + break; + } + ctx->flags |= SEEN_A; + emit_load_imm(r_s0, k, ctx); + emit_div(r_A, r_s0, ctx); + break; + case BPF_ALU | BPF_MOD | BPF_K: + /* A %= k */ + if (k == 1) { + ctx->flags |= SEEN_A; + emit_jit_reg_move(r_A, r_zero, ctx); + } else { + ctx->flags |= SEEN_A; + emit_load_imm(r_s0, k, ctx); + emit_mod(r_A, r_s0, ctx); + } + break; + case BPF_ALU | BPF_DIV | BPF_X: + /* A /= X */ + ctx->flags |= SEEN_X | SEEN_A; + /* Check if r_X is zero */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_bcond(MIPS_COND_EQ, r_X, r_zero, b_off, ctx); + emit_load_imm(r_ret, 0, ctx); /* delay slot */ + emit_div(r_A, r_X, ctx); + break; + case BPF_ALU | BPF_MOD | BPF_X: + /* A %= X */ + ctx->flags |= SEEN_X | SEEN_A; + /* Check if r_X is zero */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_bcond(MIPS_COND_EQ, r_X, r_zero, b_off, ctx); + emit_load_imm(r_ret, 0, ctx); /* delay slot */ + emit_mod(r_A, r_X, ctx); + break; + case BPF_ALU | BPF_OR | BPF_K: + /* A |= K */ + ctx->flags |= SEEN_A; + emit_ori(r_A, r_A, k, ctx); + break; + case BPF_ALU | BPF_OR | BPF_X: + /* A |= X */ + ctx->flags |= SEEN_A; + emit_ori(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_XOR | BPF_K: + /* A ^= k */ + ctx->flags |= SEEN_A; + emit_xori(r_A, r_A, k, ctx); + break; + case BPF_ANC | SKF_AD_ALU_XOR_X: + case BPF_ALU | BPF_XOR | BPF_X: + /* A ^= X */ + ctx->flags |= SEEN_A; + emit_xor(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_AND | BPF_K: + /* A &= K */ + ctx->flags |= SEEN_A; + emit_andi(r_A, r_A, k, ctx); + break; + case BPF_ALU | BPF_AND | BPF_X: + /* A &= X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_and(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_LSH | BPF_K: + /* A <<= K */ + ctx->flags |= SEEN_A; + emit_sll(r_A, r_A, k, ctx); + break; + case BPF_ALU | BPF_LSH | BPF_X: + /* A <<= X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_sllv(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_RSH | BPF_K: + /* A >>= K */ + ctx->flags |= SEEN_A; + emit_srl(r_A, r_A, k, ctx); + break; + case BPF_ALU | BPF_RSH | BPF_X: + ctx->flags |= SEEN_A | SEEN_X; + emit_srlv(r_A, r_A, r_X, ctx); + break; + case BPF_ALU | BPF_NEG: + /* A = -A */ + ctx->flags |= SEEN_A; + emit_neg(r_A, ctx); + break; + case BPF_JMP | BPF_JA: + /* pc += K */ + b_off = b_imm(i + k + 1, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_b(b_off, ctx); + emit_nop(ctx); + break; + case BPF_JMP | BPF_JEQ | BPF_K: + /* pc += ( A == K ) ? pc->jt : pc->jf */ + condt = MIPS_COND_EQ | MIPS_COND_K; + goto jmp_cmp; + case BPF_JMP | BPF_JEQ | BPF_X: + ctx->flags |= SEEN_X; + /* pc += ( A == X ) ? pc->jt : pc->jf */ + condt = MIPS_COND_EQ | MIPS_COND_X; + goto jmp_cmp; + case BPF_JMP | BPF_JGE | BPF_K: + /* pc += ( A >= K ) ? pc->jt : pc->jf */ + condt = MIPS_COND_GE | MIPS_COND_K; + goto jmp_cmp; + case BPF_JMP | BPF_JGE | BPF_X: + ctx->flags |= SEEN_X; + /* pc += ( A >= X ) ? pc->jt : pc->jf */ + condt = MIPS_COND_GE | MIPS_COND_X; + goto jmp_cmp; + case BPF_JMP | BPF_JGT | BPF_K: + /* pc += ( A > K ) ? pc->jt : pc->jf */ + condt = MIPS_COND_GT | MIPS_COND_K; + goto jmp_cmp; + case BPF_JMP | BPF_JGT | BPF_X: + ctx->flags |= SEEN_X; + /* pc += ( A > X ) ? pc->jt : pc->jf */ + condt = MIPS_COND_GT | MIPS_COND_X; +jmp_cmp: + /* Greater or Equal */ + if ((condt & MIPS_COND_GE) || + (condt & MIPS_COND_GT)) { + if (condt & MIPS_COND_K) { /* K */ + ctx->flags |= SEEN_A; + emit_sltiu(r_s0, r_A, k, ctx); + } else { /* X */ + ctx->flags |= SEEN_A | + SEEN_X; + emit_sltu(r_s0, r_A, r_X, ctx); + } + /* A < (K|X) ? r_scrach = 1 */ + b_off = b_imm(i + inst->jf + 1, ctx); + emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, + ctx); + emit_nop(ctx); + /* A > (K|X) ? scratch = 0 */ + if (condt & MIPS_COND_GT) { + /* Checking for equality */ + ctx->flags |= SEEN_A | SEEN_X; + if (condt & MIPS_COND_K) + emit_load_imm(r_s0, k, ctx); + else + emit_jit_reg_move(r_s0, r_X, + ctx); + b_off = b_imm(i + inst->jf + 1, ctx); + emit_bcond(MIPS_COND_EQ, r_A, r_s0, + b_off, ctx); + emit_nop(ctx); + /* Finally, A > K|X */ + b_off = b_imm(i + inst->jt + 1, ctx); + emit_b(b_off, ctx); + emit_nop(ctx); + } else { + /* A >= (K|X) so jump */ + b_off = b_imm(i + inst->jt + 1, ctx); + emit_b(b_off, ctx); + emit_nop(ctx); + } + } else { + /* A == K|X */ + if (condt & MIPS_COND_K) { /* K */ + ctx->flags |= SEEN_A; + emit_load_imm(r_s0, k, ctx); + /* jump true */ + b_off = b_imm(i + inst->jt + 1, ctx); + emit_bcond(MIPS_COND_EQ, r_A, r_s0, + b_off, ctx); + emit_nop(ctx); + /* jump false */ + b_off = b_imm(i + inst->jf + 1, + ctx); + emit_bcond(MIPS_COND_NE, r_A, r_s0, + b_off, ctx); + emit_nop(ctx); + } else { /* X */ + /* jump true */ + ctx->flags |= SEEN_A | SEEN_X; + b_off = b_imm(i + inst->jt + 1, + ctx); + emit_bcond(MIPS_COND_EQ, r_A, r_X, + b_off, ctx); + emit_nop(ctx); + /* jump false */ + b_off = b_imm(i + inst->jf + 1, ctx); + emit_bcond(MIPS_COND_NE, r_A, r_X, + b_off, ctx); + emit_nop(ctx); + } + } + break; + case BPF_JMP | BPF_JSET | BPF_K: + ctx->flags |= SEEN_A; + /* pc += (A & K) ? pc -> jt : pc -> jf */ + emit_load_imm(r_s1, k, ctx); + emit_and(r_s0, r_A, r_s1, ctx); + /* jump true */ + b_off = b_imm(i + inst->jt + 1, ctx); + emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx); + emit_nop(ctx); + /* jump false */ + b_off = b_imm(i + inst->jf + 1, ctx); + emit_b(b_off, ctx); + emit_nop(ctx); + break; + case BPF_JMP | BPF_JSET | BPF_X: + ctx->flags |= SEEN_X | SEEN_A; + /* pc += (A & X) ? pc -> jt : pc -> jf */ + emit_and(r_s0, r_A, r_X, ctx); + /* jump true */ + b_off = b_imm(i + inst->jt + 1, ctx); + emit_bcond(MIPS_COND_NE, r_s0, r_zero, b_off, ctx); + emit_nop(ctx); + /* jump false */ + b_off = b_imm(i + inst->jf + 1, ctx); + emit_b(b_off, ctx); + emit_nop(ctx); + break; + case BPF_RET | BPF_A: + ctx->flags |= SEEN_A; + if (i != prog->len - 1) { + /* + * If this is not the last instruction + * then jump to the epilogue + */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_b(b_off, ctx); + } + emit_reg_move(r_ret, r_A, ctx); /* delay slot */ + break; + case BPF_RET | BPF_K: + /* + * It can emit two instructions so it does not fit on + * the delay slot. + */ + emit_load_imm(r_ret, k, ctx); + if (i != prog->len - 1) { + /* + * If this is not the last instruction + * then jump to the epilogue + */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_b(b_off, ctx); + emit_nop(ctx); + } + break; + case BPF_MISC | BPF_TAX: + /* X = A */ + ctx->flags |= SEEN_X | SEEN_A; + emit_jit_reg_move(r_X, r_A, ctx); + break; + case BPF_MISC | BPF_TXA: + /* A = X */ + ctx->flags |= SEEN_A | SEEN_X; + emit_jit_reg_move(r_A, r_X, ctx); + break; + /* AUX */ + case BPF_ANC | SKF_AD_PROTOCOL: + /* A = ntohs(skb->protocol */ + ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + protocol) != 2); + off = offsetof(struct sk_buff, protocol); + emit_half_load(r_A, r_skb, off, ctx); +#ifdef CONFIG_CPU_LITTLE_ENDIAN + /* This needs little endian fixup */ + if (cpu_has_wsbh) { + /* R2 and later have the wsbh instruction */ + emit_wsbh(r_A, r_A, ctx); + } else { + /* Get first byte */ + emit_andi(r_tmp_imm, r_A, 0xff, ctx); + /* Shift it */ + emit_sll(r_tmp, r_tmp_imm, 8, ctx); + /* Get second byte */ + emit_srl(r_tmp_imm, r_A, 8, ctx); + emit_andi(r_tmp_imm, r_tmp_imm, 0xff, ctx); + /* Put everyting together in r_A */ + emit_or(r_A, r_tmp, r_tmp_imm, ctx); + } +#endif + break; + case BPF_ANC | SKF_AD_CPU: + ctx->flags |= SEEN_A | SEEN_OFF; + /* A = current_thread_info()->cpu */ + BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, + cpu) != 4); + off = offsetof(struct thread_info, cpu); + /* $28/gp points to the thread_info struct */ + emit_load(r_A, 28, off, ctx); + break; + case BPF_ANC | SKF_AD_IFINDEX: + /* A = skb->dev->ifindex */ + case BPF_ANC | SKF_AD_HATYPE: + /* A = skb->dev->type */ + ctx->flags |= SEEN_SKB | SEEN_A; + off = offsetof(struct sk_buff, dev); + /* Load *dev pointer */ + emit_load_ptr(r_s0, r_skb, off, ctx); + /* error (0) in the delay slot */ + b_off = b_imm(prog->len, ctx); + if (is_bad_offset(b_off)) + return -E2BIG; + emit_bcond(MIPS_COND_EQ, r_s0, r_zero, b_off, ctx); + emit_reg_move(r_ret, r_zero, ctx); + if (code == (BPF_ANC | SKF_AD_IFINDEX)) { + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4); + off = offsetof(struct net_device, ifindex); + emit_load(r_A, r_s0, off, ctx); + } else { /* (code == (BPF_ANC | SKF_AD_HATYPE) */ + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, type) != 2); + off = offsetof(struct net_device, type); + emit_half_load_unsigned(r_A, r_s0, off, ctx); + } + break; + case BPF_ANC | SKF_AD_MARK: + ctx->flags |= SEEN_SKB | SEEN_A; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); + off = offsetof(struct sk_buff, mark); + emit_load(r_A, r_skb, off, ctx); + break; + case BPF_ANC | SKF_AD_RXHASH: + ctx->flags |= SEEN_SKB | SEEN_A; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); + off = offsetof(struct sk_buff, hash); + emit_load(r_A, r_skb, off, ctx); + break; + case BPF_ANC | SKF_AD_VLAN_TAG: + ctx->flags |= SEEN_SKB | SEEN_A; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + vlan_tci) != 2); + off = offsetof(struct sk_buff, vlan_tci); + emit_half_load_unsigned(r_A, r_skb, off, ctx); + break; + case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT: + ctx->flags |= SEEN_SKB | SEEN_A; + emit_load_byte(r_A, r_skb, PKT_VLAN_PRESENT_OFFSET(), ctx); + if (PKT_VLAN_PRESENT_BIT) + emit_srl(r_A, r_A, PKT_VLAN_PRESENT_BIT, ctx); + if (PKT_VLAN_PRESENT_BIT < 7) + emit_andi(r_A, r_A, 1, ctx); + break; + case BPF_ANC | SKF_AD_PKTTYPE: + ctx->flags |= SEEN_SKB; + + emit_load_byte(r_tmp, r_skb, PKT_TYPE_OFFSET(), ctx); + /* Keep only the last 3 bits */ + emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); +#ifdef __BIG_ENDIAN_BITFIELD + /* Get the actual packet type to the lower 3 bits */ + emit_srl(r_A, r_A, 5, ctx); +#endif + break; + case BPF_ANC | SKF_AD_QUEUE: + ctx->flags |= SEEN_SKB | SEEN_A; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + queue_mapping) != 2); + BUILD_BUG_ON(offsetof(struct sk_buff, + queue_mapping) > 0xff); + off = offsetof(struct sk_buff, queue_mapping); + emit_half_load_unsigned(r_A, r_skb, off, ctx); + break; + default: + pr_debug("%s: Unhandled opcode: 0x%02x\n", __FILE__, + inst->code); + return -1; + } + } + + /* compute offsets only during the first pass */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + return 0; +} + +void bpf_jit_compile(struct bpf_prog *fp) +{ + struct jit_ctx ctx; + unsigned int alloc_size, tmp_idx; + + if (!bpf_jit_enable) + return; + + memset(&ctx, 0, sizeof(ctx)); + + ctx.offsets = kcalloc(fp->len + 1, sizeof(*ctx.offsets), GFP_KERNEL); + if (ctx.offsets == NULL) + return; + + ctx.skf = fp; + + if (build_body(&ctx)) + goto out; + + tmp_idx = ctx.idx; + build_prologue(&ctx); + ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; + /* just to complete the ctx.idx count */ + build_epilogue(&ctx); + + alloc_size = 4 * ctx.idx; + ctx.target = module_alloc(alloc_size); + if (ctx.target == NULL) + goto out; + + /* Clean it */ + memset(ctx.target, 0, alloc_size); + + ctx.idx = 0; + + /* Generate the actual JIT code */ + build_prologue(&ctx); + if (build_body(&ctx)) { + module_memfree(ctx.target); + goto out; + } + build_epilogue(&ctx); + + /* Update the icache */ + flush_icache_range((ptr)ctx.target, (ptr)(ctx.target + ctx.idx)); + + if (bpf_jit_enable > 1) + /* Dump JIT code */ + bpf_jit_dump(fp->len, alloc_size, 2, ctx.target); + + fp->bpf_func = (void *)ctx.target; + fp->jited = 1; + +out: + kfree(ctx.offsets); +} + +void bpf_jit_free(struct bpf_prog *fp) +{ + if (fp->jited) + module_memfree(fp->bpf_func); + + bpf_prog_unlock_free(fp); +} --- linux-oracle-5.4.0.orig/arch/mips/net/bpf_jit_asm.S +++ linux-oracle-5.4.0/arch/mips/net/bpf_jit_asm.S @@ -0,0 +1,285 @@ +/* + * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF + * compiler. + * + * Copyright (C) 2015 Imagination Technologies Ltd. + * Author: Markos Chandras + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + +#include +#include +#include +#include "bpf_jit.h" + +/* ABI + * + * r_skb_hl skb header length + * r_skb_data skb data + * r_off(a1) offset register + * r_A BPF register A + * r_X PF register X + * r_skb(a0) *skb + * r_M *scratch memory + * r_skb_le skb length + * r_s0 Scratch register 0 + * r_s1 Scratch register 1 + * + * On entry: + * a0: *skb + * a1: offset (imm or imm + X) + * + * All non-BPF-ABI registers are free for use. On return, we only + * care about r_ret. The BPF-ABI registers are assumed to remain + * unmodified during the entire filter operation. + */ + +#define skb a0 +#define offset a1 +#define SKF_LL_OFF (-0x200000) /* Can't include linux/filter.h in assembly */ + + /* We know better :) so prevent assembler reordering etc */ + .set noreorder + +#define is_offset_negative(TYPE) \ + /* If offset is negative we have more work to do */ \ + slti t0, offset, 0; \ + bgtz t0, bpf_slow_path_##TYPE##_neg; \ + /* Be careful what follows in DS. */ + +#define is_offset_in_header(SIZE, TYPE) \ + /* Reading from header? */ \ + addiu $r_s0, $r_skb_hl, -SIZE; \ + slt t0, $r_s0, offset; \ + bgtz t0, bpf_slow_path_##TYPE; \ + +LEAF(sk_load_word) + is_offset_negative(word) +FEXPORT(sk_load_word_positive) + is_offset_in_header(4, word) + /* Offset within header boundaries */ + PTR_ADDU t1, $r_skb_data, offset + .set reorder + lw $r_A, 0(t1) + .set noreorder +#ifdef CONFIG_CPU_LITTLE_ENDIAN +# if MIPS_ISA_REV >= 2 + wsbh t0, $r_A + rotr $r_A, t0, 16 +# else + sll t0, $r_A, 24 + srl t1, $r_A, 24 + srl t2, $r_A, 8 + or t0, t0, t1 + andi t2, t2, 0xff00 + andi t1, $r_A, 0xff00 + or t0, t0, t2 + sll t1, t1, 8 + or $r_A, t0, t1 +# endif +#endif + jr $r_ra + move $r_ret, zero + END(sk_load_word) + +LEAF(sk_load_half) + is_offset_negative(half) +FEXPORT(sk_load_half_positive) + is_offset_in_header(2, half) + /* Offset within header boundaries */ + PTR_ADDU t1, $r_skb_data, offset + lhu $r_A, 0(t1) +#ifdef CONFIG_CPU_LITTLE_ENDIAN +# if MIPS_ISA_REV >= 2 + wsbh $r_A, $r_A +# else + sll t0, $r_A, 8 + srl t1, $r_A, 8 + andi t0, t0, 0xff00 + or $r_A, t0, t1 +# endif +#endif + jr $r_ra + move $r_ret, zero + END(sk_load_half) + +LEAF(sk_load_byte) + is_offset_negative(byte) +FEXPORT(sk_load_byte_positive) + is_offset_in_header(1, byte) + /* Offset within header boundaries */ + PTR_ADDU t1, $r_skb_data, offset + lbu $r_A, 0(t1) + jr $r_ra + move $r_ret, zero + END(sk_load_byte) + +/* + * call skb_copy_bits: + * (prototype in linux/skbuff.h) + * + * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len) + * + * o32 mandates we leave 4 spaces for argument registers in case + * the callee needs to use them. Even though we don't care about + * the argument registers ourselves, we need to allocate that space + * to remain ABI compliant since the callee may want to use that space. + * We also allocate 2 more spaces for $r_ra and our return register (*to). + * + * n64 is a bit different. The *caller* will allocate the space to preserve + * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no + * good reason but it does not matter that much really. + * + * (void *to) is returned in r_s0 + * + */ +#ifdef CONFIG_CPU_LITTLE_ENDIAN +#define DS_OFFSET(SIZE) (4 * SZREG) +#else +#define DS_OFFSET(SIZE) ((4 * SZREG) + (4 - SIZE)) +#endif +#define bpf_slow_path_common(SIZE) \ + /* Quick check. Are we within reasonable boundaries? */ \ + LONG_ADDIU $r_s1, $r_skb_len, -SIZE; \ + sltu $r_s0, offset, $r_s1; \ + beqz $r_s0, fault; \ + /* Load 4th argument in DS */ \ + LONG_ADDIU a3, zero, SIZE; \ + PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ + PTR_LA t0, skb_copy_bits; \ + PTR_S $r_ra, (5 * SZREG)($r_sp); \ + /* Assign low slot to a2 */ \ + PTR_ADDIU a2, $r_sp, DS_OFFSET(SIZE); \ + jalr t0; \ + /* Reset our destination slot (DS but it's ok) */ \ + INT_S zero, (4 * SZREG)($r_sp); \ + /* \ + * skb_copy_bits returns 0 on success and -EFAULT \ + * on error. Our data live in a2. Do not bother with \ + * our data if an error has been returned. \ + */ \ + /* Restore our frame */ \ + PTR_L $r_ra, (5 * SZREG)($r_sp); \ + INT_L $r_s0, (4 * SZREG)($r_sp); \ + bltz v0, fault; \ + PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ + move $r_ret, zero; \ + +NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp) + bpf_slow_path_common(4) +#ifdef CONFIG_CPU_LITTLE_ENDIAN +# if MIPS_ISA_REV >= 2 + wsbh t0, $r_s0 + jr $r_ra + rotr $r_A, t0, 16 +# else + sll t0, $r_s0, 24 + srl t1, $r_s0, 24 + srl t2, $r_s0, 8 + or t0, t0, t1 + andi t2, t2, 0xff00 + andi t1, $r_s0, 0xff00 + or t0, t0, t2 + sll t1, t1, 8 + jr $r_ra + or $r_A, t0, t1 +# endif +#else + jr $r_ra + move $r_A, $r_s0 +#endif + + END(bpf_slow_path_word) + +NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp) + bpf_slow_path_common(2) +#ifdef CONFIG_CPU_LITTLE_ENDIAN +# if MIPS_ISA_REV >= 2 + jr $r_ra + wsbh $r_A, $r_s0 +# else + sll t0, $r_s0, 8 + andi t1, $r_s0, 0xff00 + andi t0, t0, 0xff00 + srl t1, t1, 8 + jr $r_ra + or $r_A, t0, t1 +# endif +#else + jr $r_ra + move $r_A, $r_s0 +#endif + + END(bpf_slow_path_half) + +NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp) + bpf_slow_path_common(1) + jr $r_ra + move $r_A, $r_s0 + + END(bpf_slow_path_byte) + +/* + * Negative entry points + */ + .macro bpf_is_end_of_data + li t0, SKF_LL_OFF + /* Reading link layer data? */ + slt t1, offset, t0 + bgtz t1, fault + /* Be careful what follows in DS. */ + .endm +/* + * call skb_copy_bits: + * (prototype in linux/filter.h) + * + * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, + * int k, unsigned int size) + * + * see above (bpf_slow_path_common) for ABI restrictions + */ +#define bpf_negative_common(SIZE) \ + PTR_ADDIU $r_sp, $r_sp, -(6 * SZREG); \ + PTR_LA t0, bpf_internal_load_pointer_neg_helper; \ + PTR_S $r_ra, (5 * SZREG)($r_sp); \ + jalr t0; \ + li a2, SIZE; \ + PTR_L $r_ra, (5 * SZREG)($r_sp); \ + /* Check return pointer */ \ + beqz v0, fault; \ + PTR_ADDIU $r_sp, $r_sp, 6 * SZREG; \ + /* Preserve our pointer */ \ + move $r_s0, v0; \ + /* Set return value */ \ + move $r_ret, zero; \ + +bpf_slow_path_word_neg: + bpf_is_end_of_data +NESTED(sk_load_word_negative, (6 * SZREG), $r_sp) + bpf_negative_common(4) + jr $r_ra + lw $r_A, 0($r_s0) + END(sk_load_word_negative) + +bpf_slow_path_half_neg: + bpf_is_end_of_data +NESTED(sk_load_half_negative, (6 * SZREG), $r_sp) + bpf_negative_common(2) + jr $r_ra + lhu $r_A, 0($r_s0) + END(sk_load_half_negative) + +bpf_slow_path_byte_neg: + bpf_is_end_of_data +NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp) + bpf_negative_common(1) + jr $r_ra + lbu $r_A, 0($r_s0) + END(sk_load_byte_negative) + +fault: + jr $r_ra + addiu $r_ret, zero, 1 --- linux-oracle-5.4.0.orig/arch/mips/net/ebpf_jit.c +++ linux-oracle-5.4.0/arch/mips/net/ebpf_jit.c @@ -604,6 +604,7 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx) { int off, b_off; + int tcc_reg; ctx->flags |= EBPF_SEEN_TC; /* @@ -616,14 +617,14 @@ b_off = b_imm(this_idx + 1, ctx); emit_instr(ctx, bne, MIPS_R_AT, MIPS_R_ZERO, b_off); /* - * if (--TCC < 0) + * if (TCC-- < 0) * goto out; */ /* Delay slot */ - emit_instr(ctx, daddiu, MIPS_R_T5, - (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4, -1); + tcc_reg = (ctx->flags & EBPF_TCC_IN_V1) ? MIPS_R_V1 : MIPS_R_S4; + emit_instr(ctx, daddiu, MIPS_R_T5, tcc_reg, -1); b_off = b_imm(this_idx + 1, ctx); - emit_instr(ctx, bltz, MIPS_R_T5, b_off); + emit_instr(ctx, bltz, tcc_reg, b_off); /* * prog = array->ptrs[index]; * if (prog == NULL) @@ -1354,6 +1355,9 @@ } break; + case BPF_ST | BPF_NOSPEC: /* speculation barrier */ + break; + case BPF_ST | BPF_B | BPF_MEM: case BPF_ST | BPF_H | BPF_MEM: case BPF_ST | BPF_W | BPF_MEM: @@ -1803,7 +1807,7 @@ unsigned int image_size; u8 *image_ptr; - if (!prog->jit_requested || MIPS_ISA_REV < 2) + if (!prog->jit_requested) return prog; tmp = bpf_jit_blind_constants(prog); --- linux-oracle-5.4.0.orig/arch/mips/pci/ops-rc32434.c +++ linux-oracle-5.4.0/arch/mips/pci/ops-rc32434.c @@ -112,8 +112,8 @@ * gives them time to settle */ if (where == PCI_VENDOR_ID) { - if (ret == 0xffffffff || ret == 0x00000000 || - ret == 0x0000ffff || ret == 0xffff0000) { + if (*val == 0xffffffff || *val == 0x00000000 || + *val == 0x0000ffff || *val == 0xffff0000) { if (delay > 4) return 0; delay *= 2; --- linux-oracle-5.4.0.orig/arch/mips/pci/pci-legacy.c +++ linux-oracle-5.4.0/arch/mips/pci/pci-legacy.c @@ -166,8 +166,13 @@ res = hose->mem_resource; break; } - if (res != NULL) - of_pci_range_to_resource(&range, node, res); + if (res != NULL) { + res->name = node->full_name; + res->flags = range.flags; + res->start = range.cpu_addr; + res->end = range.cpu_addr + range.size - 1; + res->parent = res->child = res->sibling = NULL; + } } } --- linux-oracle-5.4.0.orig/arch/mips/pci/pci-mt7620.c +++ linux-oracle-5.4.0/arch/mips/pci/pci-mt7620.c @@ -30,6 +30,7 @@ #define RALINK_GPIOMODE 0x60 #define PPLL_CFG1 0x9c +#define PPLL_LD BIT(23) #define PPLL_DRV 0xa0 #define PDRV_SW_SET BIT(31) @@ -239,8 +240,8 @@ rt_sysc_m32(0, RALINK_PCIE0_CLK_EN, RALINK_CLKCFG1); mdelay(100); - if (!(rt_sysc_r32(PPLL_CFG1) & PDRV_SW_SET)) { - dev_err(&pdev->dev, "MT7620 PPLL unlock\n"); + if (!(rt_sysc_r32(PPLL_CFG1) & PPLL_LD)) { + dev_err(&pdev->dev, "pcie PLL not locked, aborting init\n"); reset_control_assert(rstpcie0); rt_sysc_m32(RALINK_PCIE0_CLK_EN, 0, RALINK_CLKCFG1); return -1; --- linux-oracle-5.4.0.orig/arch/mips/pci/pci-rt2880.c +++ linux-oracle-5.4.0/arch/mips/pci/pci-rt2880.c @@ -180,7 +180,6 @@ int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { - u16 cmd; int irq = -1; if (dev->bus->number != 0) @@ -188,8 +187,6 @@ switch (PCI_SLOT(dev->devfn)) { case 0x00: - rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); - (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); break; case 0x11: irq = RT288X_CPU_IRQ_PCI; @@ -201,16 +198,6 @@ break; } - pci_write_config_byte((struct pci_dev *) dev, - PCI_CACHE_LINE_SIZE, 0x14); - pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF); - pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | - PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | - PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; - pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd); - pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE, - dev->irq); return irq; } @@ -251,6 +238,30 @@ int pcibios_plat_dev_init(struct pci_dev *dev) { + static bool slot0_init; + + /* + * Nobody seems to initialize slot 0, but this platform requires it, so + * do it once when some other slot is being enabled. The PCI subsystem + * should configure other slots properly, so no need to do anything + * special for those. + */ + if (!slot0_init && dev->bus->number == 0) { + u16 cmd; + u32 bar0; + + slot0_init = true; + + pci_bus_write_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0, + 0x08000000); + pci_bus_read_config_dword(dev->bus, 0, PCI_BASE_ADDRESS_0, + &bar0); + + pci_bus_read_config_word(dev->bus, 0, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_bus_write_config_word(dev->bus, 0, PCI_COMMAND, cmd); + } + return 0; } --- linux-oracle-5.4.0.orig/arch/mips/pci/pci-xtalk-bridge.c +++ linux-oracle-5.4.0/arch/mips/pci/pci-xtalk-bridge.c @@ -279,16 +279,15 @@ struct bridge_irq_chip_data *data = d->chip_data; int bit = d->parent_data->hwirq; int pin = d->hwirq; - nasid_t nasid; int ret, cpu; ret = irq_chip_set_affinity_parent(d, mask, force); if (ret >= 0) { cpu = cpumask_first_and(mask, cpu_online_mask); - nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); + data->nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); bridge_write(data->bc, b_int_addr[pin].addr, (((data->bc->intr_addr >> 30) & 0x30000) | - bit | (nasid << 8))); + bit | (data->nasid << 8))); bridge_read(data->bc, b_wid_tflush); } return ret; @@ -445,9 +444,10 @@ return -ENOMEM; domain = irq_domain_create_hierarchy(parent, 0, 8, fn, &bridge_domain_ops, NULL); - irq_domain_free_fwnode(fn); - if (!domain) + if (!domain) { + irq_domain_free_fwnode(fn); return -ENOMEM; + } pci_set_flags(PCI_PROBE_ONLY); @@ -539,6 +539,7 @@ pci_free_resource_list(&host->windows); err_remove_domain: irq_domain_remove(domain); + irq_domain_free_fwnode(fn); return err; } @@ -546,8 +547,10 @@ { struct pci_bus *bus = platform_get_drvdata(pdev); struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); + struct fwnode_handle *fn = bc->domain->fwnode; irq_domain_remove(bc->domain); + irq_domain_free_fwnode(fn); pci_lock_rescan_remove(); pci_stop_root_bus(bus); pci_remove_root_bus(bus); --- linux-oracle-5.4.0.orig/arch/mips/pci/pcie-octeon.c +++ linux-oracle-5.4.0/arch/mips/pci/pcie-octeon.c @@ -230,12 +230,18 @@ { union cvmx_pcie_address pcie_addr; union cvmx_pciercx_cfg006 pciercx_cfg006; + union cvmx_pciercx_cfg032 pciercx_cfg032; pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port)); if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0)) return 0; + pciercx_cfg032.u32 = + cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port)); + if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1)) + return 0; + pcie_addr.u64 = 0; pcie_addr.config.upper = 2; pcie_addr.config.io = 1; --- linux-oracle-5.4.0.orig/arch/mips/pic32/pic32mzda/early_console.c +++ linux-oracle-5.4.0/arch/mips/pic32/pic32mzda/early_console.c @@ -27,7 +27,7 @@ #define U_BRG(x) (UART_BASE(x) + 0x40) static void __iomem *uart_base; -static char console_port = -1; +static int console_port = -1; static int __init configure_uart_pins(int port) { @@ -47,7 +47,7 @@ return 0; } -static void __init configure_uart(char port, int baud) +static void __init configure_uart(int port, int baud) { u32 pbclk; @@ -60,7 +60,7 @@ uart_base + PIC32_SET(U_STA(port))); } -static void __init setup_early_console(char port, int baud) +static void __init setup_early_console(int port, int baud) { if (configure_uart_pins(port)) return; @@ -130,16 +130,15 @@ return baud; } -void __init fw_init_early_console(char port) +void __init fw_init_early_console(void) { char *arch_cmdline = pic32_getcmdline(); - int baud = -1; + int baud, port; uart_base = ioremap_nocache(PIC32_BASE_UART, 0xc00); baud = get_baud_from_cmdline(arch_cmdline); - if (port == -1) - port = get_port_from_cmdline(arch_cmdline); + port = get_port_from_cmdline(arch_cmdline); if (port == -1) port = EARLY_CONSOLE_PORT; --- linux-oracle-5.4.0.orig/arch/mips/pic32/pic32mzda/init.c +++ linux-oracle-5.4.0/arch/mips/pic32/pic32mzda/init.c @@ -28,7 +28,7 @@ if (fw_passed_dtb && !fw_arg2 && !fw_arg3) return (ulong)fw_passed_dtb; - if (__dtb_start < __dtb_end) + if (&__dtb_start < &__dtb_end) ftaddr = (ulong)__dtb_start; return ftaddr; @@ -60,7 +60,7 @@ strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); #ifdef CONFIG_EARLY_PRINTK - fw_init_early_console(-1); + fw_init_early_console(); #endif pic32_config_init(); } --- linux-oracle-5.4.0.orig/arch/mips/ralink/Kconfig +++ linux-oracle-5.4.0/arch/mips/ralink/Kconfig @@ -51,6 +51,7 @@ select MIPS_GIC select COMMON_CLK select CLKSRC_MIPS_GIC + select HAVE_PCI if PCI_MT7621 endchoice choice --- linux-oracle-5.4.0.orig/arch/mips/ralink/ill_acc.c +++ linux-oracle-5.4.0/arch/mips/ralink/ill_acc.c @@ -61,6 +61,7 @@ pdev = of_find_device_by_node(np); if (!pdev) { pr_err("%pOFn: failed to lookup pdev\n", np); + of_node_put(np); return -EINVAL; } --- linux-oracle-5.4.0.orig/arch/mips/ralink/of.c +++ linux-oracle-5.4.0/arch/mips/ralink/of.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,7 @@ __iomem void *rt_sysc_membase; __iomem void *rt_memc_membase; +EXPORT_SYMBOL_GPL(rt_sysc_membase); __iomem void *plat_of_remap_node(const char *node) { @@ -75,7 +77,7 @@ */ if (fw_passed_dtb) dtb = (void *)fw_passed_dtb; - else if (__dtb_start != __dtb_end) + else if (&__dtb_start != &__dtb_end) dtb = (void *)__dtb_start; __dt_setup_arch(dtb); --- linux-oracle-5.4.0.orig/arch/mips/rb532/devices.c +++ linux-oracle-5.4.0/arch/mips/rb532/devices.c @@ -310,11 +310,9 @@ static int __init setup_kmac(char *s) { printk(KERN_INFO "korina mac = %s\n", s); - if (!mac_pton(s, korina_dev0_data.mac)) { + if (!mac_pton(s, korina_dev0_data.mac)) printk(KERN_ERR "Invalid mac\n"); - return -EINVAL; - } - return 0; + return 1; } __setup("kmac=", setup_kmac); --- linux-oracle-5.4.0.orig/arch/mips/sgi-ip27/ip27-irq.c +++ linux-oracle-5.4.0/arch/mips/sgi-ip27/ip27-irq.c @@ -73,6 +73,9 @@ int cpu; cpu = cpumask_first_and(mask, cpu_online_mask); + if (cpu >= nr_cpu_ids) + cpu = cpumask_any(cpu_online_mask); + nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); hd->cpu = cpu; if (!cputoslice(cpu)) { @@ -139,6 +142,7 @@ /* use CPU connected to nearest hub */ hub = hub_data(NASID_TO_COMPACT_NODEID(info->nasid)); setup_hub_mask(hd, &hub->h_cpus); + info->nasid = cpu_to_node(hd->cpu); /* Make sure it's not already pending when we connect it. */ REMOTE_HUB_CLR_INTR(info->nasid, swlevel); --- linux-oracle-5.4.0.orig/arch/mips/sgi-ip27/ip27-memory.c +++ linux-oracle-5.4.0/arch/mips/sgi-ip27/ip27-memory.c @@ -455,7 +455,7 @@ pagetable_init(); zones_size[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(zones_size); + free_area_init(zones_size); } void __init mem_init(void) --- linux-oracle-5.4.0.orig/arch/mips/sni/a20r.c +++ linux-oracle-5.4.0/arch/mips/sni/a20r.c @@ -143,7 +143,10 @@ }, }; -static u32 a20r_ack_hwint(void) +/* + * Trigger chipset to update CPU's CAUSE IP field + */ +static u32 a20r_update_cause_ip(void) { u32 status = read_c0_status(); @@ -205,12 +208,14 @@ int irq; clear_c0_status(IE_IRQ0); - status = a20r_ack_hwint(); + status = a20r_update_cause_ip(); cause = read_c0_cause(); irq = ffs(((cause & status) >> 8) & 0xf8); if (likely(irq > 0)) do_IRQ(SNI_A20R_IRQ_BASE + irq - 1); + + a20r_update_cause_ip(); set_c0_status(IE_IRQ0); } --- linux-oracle-5.4.0.orig/arch/mips/sni/time.c +++ linux-oracle-5.4.0/arch/mips/sni/time.c @@ -18,14 +18,14 @@ { *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV; + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV & 0xff; wmb(); *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8; wmb(); *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb(); - *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV; + *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV & 0xff; wmb(); *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8; wmb(); --- linux-oracle-5.4.0.orig/arch/mips/tools/elf-entry.c +++ linux-oracle-5.4.0/arch/mips/tools/elf-entry.c @@ -51,11 +51,14 @@ nread = fread(&hdr, 1, sizeof(hdr), file); if (nread != sizeof(hdr)) { perror("Unable to read input file"); + fclose(file); return EXIT_FAILURE; } - if (memcmp(hdr.ehdr32.e_ident, ELFMAG, SELFMAG)) + if (memcmp(hdr.ehdr32.e_ident, ELFMAG, SELFMAG)) { + fclose(file); die("Input is not an ELF\n"); + } switch (hdr.ehdr32.e_ident[EI_CLASS]) { case ELFCLASS32: @@ -67,6 +70,7 @@ entry = be32toh(hdr.ehdr32.e_entry); break; default: + fclose(file); die("Invalid ELF encoding\n"); } @@ -83,14 +87,17 @@ entry = be64toh(hdr.ehdr64.e_entry); break; default: + fclose(file); die("Invalid ELF encoding\n"); } break; default: + fclose(file); die("Invalid ELF class\n"); } printf("0x%016" PRIx64 "\n", entry); + fclose(file); return EXIT_SUCCESS; } --- linux-oracle-5.4.0.orig/arch/mips/vdso/Makefile +++ linux-oracle-5.4.0/arch/mips/vdso/Makefile @@ -16,12 +16,9 @@ $(filter -march=%,$(KBUILD_CFLAGS)) \ $(filter -m%-float,$(KBUILD_CFLAGS)) \ $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \ + $(CLANG_FLAGS) \ -D__VDSO__ -ifdef CONFIG_CC_IS_CLANG -ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS)) -endif - # # The -fno-jump-tables flag only prevents the compiler from generating # jump tables but does not prevent the compiler from emitting absolute --- linux-oracle-5.4.0.orig/arch/mips/vdso/genvdso.c +++ linux-oracle-5.4.0/arch/mips/vdso/genvdso.c @@ -122,6 +122,7 @@ if (fstat(fd, &stat) != 0) { fprintf(stderr, "%s: Failed to stat '%s': %s\n", program_name, path, strerror(errno)); + close(fd); return NULL; } @@ -130,6 +131,7 @@ if (addr == MAP_FAILED) { fprintf(stderr, "%s: Failed to map '%s': %s\n", program_name, path, strerror(errno)); + close(fd); return NULL; } @@ -139,6 +141,7 @@ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) { fprintf(stderr, "%s: '%s' is not an ELF file\n", program_name, path); + close(fd); return NULL; } @@ -150,6 +153,7 @@ default: fprintf(stderr, "%s: '%s' has invalid ELF class\n", program_name, path); + close(fd); return NULL; } @@ -161,6 +165,7 @@ default: fprintf(stderr, "%s: '%s' has invalid ELF data order\n", program_name, path); + close(fd); return NULL; } @@ -168,15 +173,18 @@ fprintf(stderr, "%s: '%s' has invalid ELF machine (expected EM_MIPS)\n", program_name, path); + close(fd); return NULL; } else if (swap_uint16(ehdr->e_type) != ET_DYN) { fprintf(stderr, "%s: '%s' has invalid ELF type (expected ET_DYN)\n", program_name, path); + close(fd); return NULL; } *_size = stat.st_size; + close(fd); return addr; } @@ -280,10 +288,12 @@ /* Calculate and write symbol offsets to */ if (!get_symbols(dbg_vdso_path, dbg_vdso)) { unlink(out_path); + fclose(out_file); return EXIT_FAILURE; } fprintf(out_file, "};\n"); + fclose(out_file); return EXIT_SUCCESS; } --- linux-oracle-5.4.0.orig/arch/mips/vdso/vgettimeofday.c +++ linux-oracle-5.4.0/arch/mips/vdso/vgettimeofday.c @@ -17,12 +17,22 @@ return __cvdso_clock_gettime32(clock, ts); } +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL + +/* + * This is behind the ifdef so that we don't provide the symbol when there's no + * possibility of there being a usable clocksource, because there's nothing we + * can do without it. When libc fails the symbol lookup it should fall back on + * the standard syscall path. + */ int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) { return __cvdso_gettimeofday(tv, tz); } +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ + int __vdso_clock_getres(clockid_t clock_id, struct old_timespec32 *res) { @@ -43,12 +53,22 @@ return __cvdso_clock_gettime(clock, ts); } +#ifdef CONFIG_MIPS_CLOCK_VSYSCALL + +/* + * This is behind the ifdef so that we don't provide the symbol when there's no + * possibility of there being a usable clocksource, because there's nothing we + * can do without it. When libc fails the symbol lookup it should fall back on + * the standard syscall path. + */ int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz) { return __cvdso_gettimeofday(tv, tz); } +#endif /* CONFIG_MIPS_CLOCK_VSYSCALL */ + int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res) { --- linux-oracle-5.4.0.orig/arch/mips/vr41xx/common/icu.c +++ linux-oracle-5.4.0/arch/mips/vr41xx/common/icu.c @@ -640,8 +640,6 @@ printk(KERN_ERR "spurious ICU interrupt: %04x,%04x\n", pend1, pend2); - atomic_inc(&irq_err_count); - return -1; } --- linux-oracle-5.4.0.orig/arch/nds32/include/asm/cacheflush.h +++ linux-oracle-5.4.0/arch/nds32/include/asm/cacheflush.h @@ -9,7 +9,11 @@ #define PG_dcache_dirty PG_arch_1 void flush_icache_range(unsigned long start, unsigned long end); +#define flush_icache_range flush_icache_range + void flush_icache_page(struct vm_area_struct *vma, struct page *page); +#define flush_icache_page flush_icache_page + #ifdef CONFIG_CPU_CACHE_ALIASING void flush_cache_mm(struct mm_struct *mm); void flush_cache_dup_mm(struct mm_struct *mm); @@ -40,12 +44,11 @@ #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&(mapping)->i_pages) #else -#include -#undef flush_icache_range -#undef flush_icache_page -#undef flush_icache_user_range void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len); +#define flush_icache_user_range flush_icache_user_range + +#include #endif #endif /* __NDS32_CACHEFLUSH_H__ */ --- linux-oracle-5.4.0.orig/arch/nds32/include/asm/memory.h +++ linux-oracle-5.4.0/arch/nds32/include/asm/memory.h @@ -76,18 +76,12 @@ * virt_to_page(k) convert a _valid_ virtual address to struct page * * virt_addr_valid(k) indicates whether a virtual address is valid */ -#ifndef CONFIG_DISCONTIGMEM - #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET #define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) #define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) #define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) -#else /* CONFIG_DISCONTIGMEM */ -#error CONFIG_DISCONTIGMEM is not supported yet. -#endif /* !CONFIG_DISCONTIGMEM */ - #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #endif --- linux-oracle-5.4.0.orig/arch/nds32/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/nds32/include/asm/uaccess.h @@ -71,9 +71,7 @@ * versions are void (ie, don't return a value as such). */ -#define get_user __get_user \ - -#define __get_user(x, ptr) \ +#define get_user(x, ptr) \ ({ \ long __gu_err = 0; \ __get_user_check((x), (ptr), __gu_err); \ @@ -86,6 +84,14 @@ (void)0; \ }) +#define __get_user(x, ptr) \ +({ \ + long __gu_err = 0; \ + const __typeof__(*(ptr)) __user *__p = (ptr); \ + __get_user_err((x), __p, (__gu_err)); \ + __gu_err; \ +}) + #define __get_user_check(x, ptr, err) \ ({ \ const __typeof__(*(ptr)) __user *__p = (ptr); \ @@ -166,12 +172,18 @@ : "r"(addr), "i"(-EFAULT) \ : "cc") -#define put_user __put_user \ +#define put_user(x, ptr) \ +({ \ + long __pu_err = 0; \ + __put_user_check((x), (ptr), __pu_err); \ + __pu_err; \ +}) #define __put_user(x, ptr) \ ({ \ long __pu_err = 0; \ - __put_user_err((x), (ptr), __pu_err); \ + __typeof__(*(ptr)) __user *__p = (ptr); \ + __put_user_err((x), __p, __pu_err); \ __pu_err; \ }) --- linux-oracle-5.4.0.orig/arch/nds32/kernel/dma.c +++ linux-oracle-5.4.0/arch/nds32/kernel/dma.c @@ -46,8 +46,8 @@ } while (left); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_FROM_DEVICE: @@ -61,8 +61,8 @@ } } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { switch (dir) { case DMA_TO_DEVICE: --- linux-oracle-5.4.0.orig/arch/nds32/kernel/fpu.c +++ linux-oracle-5.4.0/arch/nds32/kernel/fpu.c @@ -223,7 +223,7 @@ } } else if (fpcsr & FPCSR_mskRIT) { if (!user_mode(regs)) - do_exit(SIGILL); + make_task_dead(SIGILL); si_signo = SIGILL; } --- linux-oracle-5.4.0.orig/arch/nds32/kernel/perf_event_cpu.c +++ linux-oracle-5.4.0/arch/nds32/kernel/perf_event_cpu.c @@ -1363,6 +1363,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); unsigned long fp = 0; unsigned long gp = 0; unsigned long lp = 0; @@ -1371,7 +1372,7 @@ leaf_fp = 0; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -1479,9 +1480,10 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct stackframe fr; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* We don't support guest os callchain now */ return; } @@ -1493,20 +1495,23 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + /* However, NDS32 does not support virtualization */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) - return perf_guest_cbs->get_guest_ip(); + if (guest_cbs && guest_cbs->is_in_guest()) + return guest_cbs->get_guest_ip(); return instruction_pointer(regs); } unsigned long perf_misc_flags(struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); int misc = 0; /* However, NDS32 does not support virtualization */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { - if (perf_guest_cbs->is_user_mode()) + if (guest_cbs && guest_cbs->is_in_guest()) { + if (guest_cbs->is_user_mode()) misc |= PERF_RECORD_MISC_GUEST_USER; else misc |= PERF_RECORD_MISC_GUEST_KERNEL; --- linux-oracle-5.4.0.orig/arch/nds32/kernel/traps.c +++ linux-oracle-5.4.0/arch/nds32/kernel/traps.c @@ -184,7 +184,7 @@ bust_spinlocks(0); spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } EXPORT_SYMBOL(die); @@ -288,7 +288,7 @@ pr_emerg("unhandled_interruption\n"); show_regs(regs); if (!user_mode(regs)) - do_exit(SIGKILL); + make_task_dead(SIGKILL); force_sig(SIGKILL); } @@ -299,7 +299,7 @@ addr, type); show_regs(regs); if (!user_mode(regs)) - do_exit(SIGKILL); + make_task_dead(SIGKILL); force_sig(SIGKILL); } @@ -326,7 +326,7 @@ pr_emerg("Reserved Instruction\n"); show_regs(regs); if (!user_mode(regs)) - do_exit(SIGILL); + make_task_dead(SIGILL); force_sig(SIGILL); } --- linux-oracle-5.4.0.orig/arch/nds32/mm/cacheflush.c +++ linux-oracle-5.4.0/arch/nds32/mm/cacheflush.c @@ -239,7 +239,7 @@ { struct address_space *mapping; - mapping = page_mapping(page); + mapping = page_mapping_file(page); if (mapping && !mapping_mapped(mapping)) set_bit(PG_dcache_dirty, &page->flags); else { --- linux-oracle-5.4.0.orig/arch/nds32/mm/init.c +++ linux-oracle-5.4.0/arch/nds32/mm/init.c @@ -31,16 +31,13 @@ static void __init zone_sizes_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; - /* Clear the zone sizes */ - memset(zones_size, 0, sizeof(zones_size)); - - zones_size[ZONE_NORMAL] = max_low_pfn; + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = max_pfn; + max_zone_pfn[ZONE_HIGHMEM] = max_pfn; #endif - free_area_init(zones_size); + free_area_init(max_zone_pfn); } --- linux-oracle-5.4.0.orig/arch/nds32/mm/mmap.c +++ linux-oracle-5.4.0/arch/nds32/mm/mmap.c @@ -59,7 +59,7 @@ vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vma->vm_start)) + (!vma || addr + len <= vm_start_gap(vma))) return addr; } --- linux-oracle-5.4.0.orig/arch/nios2/boot/Makefile +++ linux-oracle-5.4.0/arch/nios2/boot/Makefile @@ -20,7 +20,7 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -$(obj)/vmImage: $(obj)/vmlinux.gz +$(obj)/vmImage: $(obj)/vmlinux.gz FORCE $(call if_changed,uimage) @$(kecho) 'Kernel: $@ is ready' --- linux-oracle-5.4.0.orig/arch/nios2/boot/dts/10m50_devboard.dts +++ linux-oracle-5.4.0/arch/nios2/boot/dts/10m50_devboard.dts @@ -97,7 +97,7 @@ rx-fifo-depth = <8192>; tx-fifo-depth = <8192>; address-bits = <48>; - max-frame-size = <1518>; + max-frame-size = <1500>; local-mac-address = [00 00 00 00 00 00]; altr,has-supplementary-unicast; altr,enable-sup-addr = <1>; --- linux-oracle-5.4.0.orig/arch/nios2/boot/dts/3c120_devboard.dts +++ linux-oracle-5.4.0/arch/nios2/boot/dts/3c120_devboard.dts @@ -106,7 +106,7 @@ interrupt-names = "rx_irq", "tx_irq"; rx-fifo-depth = <8192>; tx-fifo-depth = <8192>; - max-frame-size = <1518>; + max-frame-size = <1500>; local-mac-address = [ 00 00 00 00 00 00 ]; phy-mode = "rgmii-id"; phy-handle = <&phy0>; --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/entry.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/entry.h @@ -50,7 +50,8 @@ stw r13, PT_R13(sp) stw r14, PT_R14(sp) stw r15, PT_R15(sp) - stw r2, PT_ORIG_R2(sp) + movi r24, -1 + stw r24, PT_ORIG_R2(sp) stw r7, PT_ORIG_R7(sp) stw ra, PT_RA(sp) --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/irqflags.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/irqflags.h @@ -9,7 +9,7 @@ static inline unsigned long arch_local_save_flags(void) { - return RDCTL(CTL_STATUS); + return RDCTL(CTL_FSTATUS); } /* @@ -18,7 +18,7 @@ */ static inline void arch_local_irq_restore(unsigned long flags) { - WRCTL(CTL_STATUS, flags); + WRCTL(CTL_FSTATUS, flags); } static inline void arch_local_irq_disable(void) --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/ptrace.h @@ -74,6 +74,8 @@ ((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE)\ - 1) +#define force_successful_syscall_return() (current_pt_regs()->orig_r2 = -1) + int do_syscall_trace_enter(void); void do_syscall_trace_exit(void); #endif /* __ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/registers.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/registers.h @@ -11,7 +11,7 @@ #endif /* control register numbers */ -#define CTL_STATUS 0 +#define CTL_FSTATUS 0 #define CTL_ESTATUS 1 #define CTL_BSTATUS 2 #define CTL_IENABLE 3 --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/timex.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/timex.h @@ -8,5 +8,8 @@ typedef unsigned long cycles_t; extern cycles_t get_cycles(void); +#define get_cycles get_cycles + +#define random_get_entropy() (((unsigned long)get_cycles()) ?: random_get_entropy_fallback()) #endif --- linux-oracle-5.4.0.orig/arch/nios2/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/nios2/include/asm/uaccess.h @@ -89,6 +89,7 @@ /* Optimized macros */ #define __get_user_asm(val, insn, addr, err) \ { \ + unsigned long __gu_val; \ __asm__ __volatile__( \ " movi %0, %3\n" \ "1: " insn " %1, 0(%2)\n" \ @@ -97,14 +98,20 @@ " .section __ex_table,\"a\"\n" \ " .word 1b, 2b\n" \ " .previous" \ - : "=&r" (err), "=r" (val) \ + : "=&r" (err), "=r" (__gu_val) \ : "r" (addr), "i" (-EFAULT)); \ + val = (__force __typeof__(*(addr)))__gu_val; \ } -#define __get_user_unknown(val, size, ptr, err) do { \ +extern void __get_user_unknown(void); + +#define __get_user_8(val, ptr, err) do { \ + u64 __val = 0; \ err = 0; \ - if (__copy_from_user(&(val), ptr, size)) { \ + if (raw_copy_from_user(&(__val), ptr, sizeof(val))) { \ err = -EFAULT; \ + } else { \ + val = (typeof(val))(typeof((val) - (val)))__val; \ } \ } while (0) @@ -120,8 +127,11 @@ case 4: \ __get_user_asm(val, "ldw", ptr, err); \ break; \ + case 8: \ + __get_user_8(val, ptr, err); \ + break; \ default: \ - __get_user_unknown(val, size, ptr, err); \ + __get_user_unknown(); \ break; \ } \ } while (0) @@ -130,9 +140,7 @@ ({ \ long __gu_err = -EFAULT; \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ - unsigned long __gu_val = 0; \ - __get_user_common(__gu_val, sizeof(*(ptr)), __gu_ptr, __gu_err);\ - (x) = (__force __typeof__(x))__gu_val; \ + __get_user_common(x, sizeof(*(ptr)), __gu_ptr, __gu_err); \ __gu_err; \ }) @@ -140,11 +148,9 @@ ({ \ long __gu_err = -EFAULT; \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ - unsigned long __gu_val = 0; \ if (access_ok( __gu_ptr, sizeof(*__gu_ptr))) \ - __get_user_common(__gu_val, sizeof(*__gu_ptr), \ + __get_user_common(x, sizeof(*__gu_ptr), \ __gu_ptr, __gu_err); \ - (x) = (__force __typeof__(x))__gu_val; \ __gu_err; \ }) --- linux-oracle-5.4.0.orig/arch/nios2/kernel/entry.S +++ linux-oracle-5.4.0/arch/nios2/kernel/entry.S @@ -185,6 +185,7 @@ ldw r5, PT_R5(sp) local_restart: + stw r2, PT_ORIG_R2(sp) /* Check that the requested system call is within limits */ movui r1, __NR_syscalls bgeu r2, r1, ret_invsyscall @@ -192,7 +193,6 @@ movhi r11, %hiadj(sys_call_table) add r1, r1, r11 ldw r1, %lo(sys_call_table)(r1) - beq r1, r0, ret_invsyscall /* Check if we are being traced */ GET_THREAD_INFO r11 @@ -213,6 +213,9 @@ translate_rc_and_ret: movi r1, 0 bge r2, zero, 3f + ldw r1, PT_ORIG_R2(sp) + addi r1, r1, 1 + beq r1, zero, 3f sub r2, zero, r2 movi r1, 1 3: @@ -255,9 +258,9 @@ ldw r6, PT_R6(sp) ldw r7, PT_R7(sp) - /* Fetch the syscall function, we don't need to check the boundaries - * since this is already done. - */ + /* Fetch the syscall function. */ + movui r1, __NR_syscalls + bgeu r2, r1, traced_invsyscall slli r1, r2, 2 movhi r11,%hiadj(sys_call_table) add r1, r1, r11 @@ -276,6 +279,9 @@ translate_rc_and_ret2: movi r1, 0 bge r2, zero, 4f + ldw r1, PT_ORIG_R2(sp) + addi r1, r1, 1 + beq r1, zero, 4f sub r2, zero, r2 movi r1, 1 4: @@ -287,6 +293,11 @@ RESTORE_SWITCH_STACK br ret_from_exception + /* If the syscall number was invalid return ENOSYS */ +traced_invsyscall: + movi r2, -ENOSYS + br translate_rc_and_ret2 + Luser_return: GET_THREAD_INFO r11 /* get thread_info pointer */ ldw r10, TI_FLAGS(r11) /* get thread_info->flags */ @@ -336,9 +347,6 @@ /* skip if no interrupt is pending */ beq r12, r0, ret_from_interrupt - movi r24, -1 - stw r24, PT_ORIG_R2(sp) - /* * Process an external hardware interrupt. */ --- linux-oracle-5.4.0.orig/arch/nios2/kernel/signal.c +++ linux-oracle-5.4.0/arch/nios2/kernel/signal.c @@ -240,7 +240,7 @@ /* * If we were from a system call, check for system call restarting... */ - if (regs->orig_r2 >= 0) { + if (regs->orig_r2 >= 0 && regs->r1) { continue_addr = regs->ea; restart_addr = continue_addr - 4; retval = regs->r2; @@ -261,6 +261,7 @@ regs->ea = restart_addr; break; } + regs->orig_r2 = -1; } if (get_signal(&ksig)) { --- linux-oracle-5.4.0.orig/arch/nios2/kernel/syscall_table.c +++ linux-oracle-5.4.0/arch/nios2/kernel/syscall_table.c @@ -13,5 +13,6 @@ #define __SYSCALL(nr, call) [nr] = (call), void *sys_call_table[__NR_syscalls] = { + [0 ... __NR_syscalls-1] = sys_ni_syscall, #include }; --- linux-oracle-5.4.0.orig/arch/nios2/kernel/traps.c +++ linux-oracle-5.4.0/arch/nios2/kernel/traps.c @@ -37,10 +37,10 @@ show_regs(regs); spin_unlock_irq(&die_lock); /* - * do_exit() should take care of panic'ing from an interrupt + * make_task_dead() should take care of panic'ing from an interrupt * context so we don't handle it here */ - do_exit(err); + make_task_dead(err); } void _exception(int signo, struct pt_regs *regs, int code, unsigned long addr) --- linux-oracle-5.4.0.orig/arch/nios2/mm/dma-mapping.c +++ linux-oracle-5.4.0/arch/nios2/mm/dma-mapping.c @@ -18,8 +18,8 @@ #include #include -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { void *vaddr = phys_to_virt(paddr); @@ -42,8 +42,8 @@ } } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { void *vaddr = phys_to_virt(paddr); --- linux-oracle-5.4.0.orig/arch/nios2/mm/init.c +++ linux-oracle-5.4.0/arch/nios2/mm/init.c @@ -46,17 +46,15 @@ */ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; - - memset(zones_size, 0, sizeof(zones_size)); + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; pagetable_init(); pgd_current = swapper_pg_dir; - zones_size[ZONE_NORMAL] = max_mapnr; + max_zone_pfn[ZONE_NORMAL] = max_mapnr; /* pass the memory from the bootmem allocator to the main allocator */ - free_area_init(zones_size); + free_area_init(max_zone_pfn); flush_dcache_range((unsigned long)empty_zero_page, (unsigned long)empty_zero_page + PAGE_SIZE); --- linux-oracle-5.4.0.orig/arch/nios2/platform/Kconfig.platform +++ linux-oracle-5.4.0/arch/nios2/platform/Kconfig.platform @@ -37,6 +37,7 @@ config NIOS2_DTB_SOURCE_BOOL bool "Compile and link device tree into kernel image" + depends on !COMPILE_TEST help This allows you to specify a dts (device tree source) file which will be compiled and linked into the kernel image. --- linux-oracle-5.4.0.orig/arch/openrisc/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/openrisc/include/asm/barrier.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_BARRIER_H +#define __ASM_BARRIER_H + +#define mb() asm volatile ("l.msync" ::: "memory") + +#include + +#endif /* __ASM_BARRIER_H */ --- linux-oracle-5.4.0.orig/arch/openrisc/include/asm/timex.h +++ linux-oracle-5.4.0/arch/openrisc/include/asm/timex.h @@ -23,6 +23,7 @@ { return mfspr(SPR_TTCR); } +#define get_cycles get_cycles /* This isn't really used any more */ #define CLOCK_TICK_RATE 1000 --- linux-oracle-5.4.0.orig/arch/openrisc/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/openrisc/include/asm/uaccess.h @@ -164,19 +164,19 @@ #define __get_user_nocheck(x, ptr, size) \ ({ \ - long __gu_err, __gu_val; \ - __get_user_size(__gu_val, (ptr), (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + long __gu_err; \ + __get_user_size((x), (ptr), (size), __gu_err); \ __gu_err; \ }) #define __get_user_check(x, ptr, size) \ ({ \ - long __gu_err = -EFAULT, __gu_val = 0; \ - const __typeof__(*(ptr)) * __gu_addr = (ptr); \ - if (access_ok(__gu_addr, size)) \ - __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ - (x) = (__force __typeof__(*(ptr)))__gu_val; \ + long __gu_err = -EFAULT; \ + const __typeof__(*(ptr)) *__gu_addr = (ptr); \ + if (access_ok(__gu_addr, size)) \ + __get_user_size((x), __gu_addr, (size), __gu_err); \ + else \ + (x) = (__typeof__(*(ptr))) 0; \ __gu_err; \ }) @@ -190,11 +190,13 @@ case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \ case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \ case 8: __get_user_asm2(x, ptr, retval); break; \ - default: (x) = __get_user_bad(); \ + default: (x) = (__typeof__(*(ptr)))__get_user_bad(); \ } \ } while (0) #define __get_user_asm(x, addr, err, op) \ +{ \ + unsigned long __gu_tmp; \ __asm__ __volatile__( \ "1: "op" %1,0(%2)\n" \ "2:\n" \ @@ -208,10 +210,14 @@ " .align 2\n" \ " .long 1b,3b\n" \ ".previous" \ - : "=r"(err), "=r"(x) \ - : "r"(addr), "i"(-EFAULT), "0"(err)) + : "=r"(err), "=r"(__gu_tmp) \ + : "r"(addr), "i"(-EFAULT), "0"(err)); \ + (x) = (__typeof__(*(addr)))__gu_tmp; \ +} #define __get_user_asm2(x, addr, err) \ +{ \ + unsigned long long __gu_tmp; \ __asm__ __volatile__( \ "1: l.lwz %1,0(%2)\n" \ "2: l.lwz %H1,4(%2)\n" \ @@ -228,8 +234,11 @@ " .long 1b,4b\n" \ " .long 2b,4b\n" \ ".previous" \ - : "=r"(err), "=&r"(x) \ - : "r"(addr), "i"(-EFAULT), "0"(err)) + : "=r"(err), "=&r"(__gu_tmp) \ + : "r"(addr), "i"(-EFAULT), "0"(err)); \ + (x) = (__typeof__(*(addr)))( \ + (__typeof__((x)-(x)))__gu_tmp); \ +} /* more complex routines */ --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/dma.c +++ linux-oracle-5.4.0/arch/openrisc/kernel/dma.c @@ -125,7 +125,7 @@ free_pages_exact(vaddr, size); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t addr, size_t size, +void arch_sync_dma_for_device(phys_addr_t addr, size_t size, enum dma_data_direction dir) { unsigned long cl; --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/entry.S +++ linux-oracle-5.4.0/arch/openrisc/kernel/entry.S @@ -173,7 +173,6 @@ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ /* r30 already save */ ;\ -/* l.sw PT_GPR30(r1),r30*/ ;\ l.sw PT_GPR31(r1),r31 ;\ TRACE_IRQS_OFF_ENTRY ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ @@ -211,9 +210,8 @@ l.sw PT_GPR27(r1),r27 ;\ l.sw PT_GPR28(r1),r28 ;\ l.sw PT_GPR29(r1),r29 ;\ - /* r31 already saved */ ;\ - l.sw PT_GPR30(r1),r30 ;\ -/* l.sw PT_GPR31(r1),r31 */ ;\ + /* r30 already saved */ ;\ + l.sw PT_GPR31(r1),r31 ;\ /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ l.addi r30,r0,-1 ;\ l.sw PT_ORIG_GPR11(r1),r30 ;\ @@ -547,6 +545,7 @@ l.bnf 1f // ext irq enabled, all ok. l.nop +#ifdef CONFIG_PRINTK l.addi r1,r1,-0x8 l.movhi r3,hi(42f) l.ori r3,r3,lo(42f) @@ -560,6 +559,7 @@ .string "\n\rESR interrupt bug: in _external_irq_handler (ESR %x)\n\r" .align 4 .previous +#endif l.ori r4,r4,SPR_SR_IEE // fix the bug // l.sw PT_SR(r1),r4 @@ -1166,13 +1166,13 @@ l.movhi r29,hi(sys_clone) l.ori r29,r29,lo(sys_clone) l.j _fork_save_extra_regs_and_call - l.addi r7,r1,0 + l.nop ENTRY(__sys_fork) l.movhi r29,hi(sys_fork) l.ori r29,r29,lo(sys_fork) l.j _fork_save_extra_regs_and_call - l.addi r3,r1,0 + l.nop ENTRY(sys_rt_sigreturn) l.jal _sys_rt_sigreturn --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/head.S +++ linux-oracle-5.4.0/arch/openrisc/kernel/head.S @@ -521,6 +521,15 @@ l.ori r3,r0,0x1 l.mtspr r0,r3,SPR_SR + /* + * Start the TTCR as early as possible, so that the RNG can make use of + * measurements of boot time from the earliest opportunity. Especially + * important is that the TTCR does not return zero by the time we reach + * rand_initialize(). + */ + l.movhi r3,hi(SPR_TTMR_CR) + l.mtspr r0,r3,SPR_TTMR + CLEAR_GPR(r1) CLEAR_GPR(r2) CLEAR_GPR(r3) --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/setup.c +++ linux-oracle-5.4.0/arch/openrisc/kernel/setup.c @@ -274,10 +274,15 @@ pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy); + + of_node_put(cpu); } void __init setup_arch(char **cmdline_p) { + /* setup memblock allocator */ + setup_memory(); + unflatten_and_copy_device_tree(); setup_cpuinfo(); @@ -302,9 +307,6 @@ initrd_below_start_ok = 1; #endif - /* setup memblock allocator */ - setup_memory(); - /* paging_init() sets up the MMU and marks all pages as reserved */ paging_init(); --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/openrisc/kernel/stacktrace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -68,12 +69,25 @@ { unsigned long *sp = NULL; + if (!try_get_task_stack(tsk)) + return; + if (tsk == current) sp = (unsigned long *) &sp; - else - sp = (unsigned long *) KSTK_ESP(tsk); + else { + unsigned long ksp; + + /* Locate stack from kernel context */ + ksp = task_thread_info(tsk)->ksp; + ksp += STACK_FRAME_OVERHEAD; /* redzone */ + ksp += sizeof(struct pt_regs); + + sp = (unsigned long *) ksp; + } unwind_stack(trace, sp, save_stack_address_nosched); + + put_task_stack(tsk); } EXPORT_SYMBOL_GPL(save_stack_trace_tsk); --- linux-oracle-5.4.0.orig/arch/openrisc/kernel/traps.c +++ linux-oracle-5.4.0/arch/openrisc/kernel/traps.c @@ -218,7 +218,7 @@ __asm__ __volatile__("l.nop 1"); do {} while (1); #endif - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } /* This is normally the 'Oops' routine */ --- linux-oracle-5.4.0.orig/arch/openrisc/mm/cache.c +++ linux-oracle-5.4.0/arch/openrisc/mm/cache.c @@ -16,7 +16,7 @@ #include #include -static void cache_loop(struct page *page, const unsigned int reg) +static __always_inline void cache_loop(struct page *page, const unsigned int reg) { unsigned long paddr = page_to_pfn(page) << PAGE_SHIFT; unsigned long line = paddr & ~(L1_CACHE_BYTES - 1); --- linux-oracle-5.4.0.orig/arch/openrisc/mm/init.c +++ linux-oracle-5.4.0/arch/openrisc/mm/init.c @@ -45,17 +45,14 @@ static void __init zone_sizes_init(void) { - unsigned long zones_size[MAX_NR_ZONES]; - - /* Clear the zone sizes */ - memset(zones_size, 0, sizeof(zones_size)); + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; /* * We use only ZONE_NORMAL */ - zones_size[ZONE_NORMAL] = max_low_pfn; + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; - free_area_init(zones_size); + free_area_init(max_zone_pfn); } extern const char _s_kernel_ro[], _e_kernel_ro[]; --- linux-oracle-5.4.0.orig/arch/parisc/Kconfig +++ linux-oracle-5.4.0/arch/parisc/Kconfig @@ -11,6 +11,7 @@ select ARCH_WANT_FRAME_POINTERS select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_STRICT_KERNEL_RWX + select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_UBSAN_SANITIZE_ALL select ARCH_NO_SG_CHAIN select ARCH_SUPPORTS_MEMORY_FAILURE @@ -62,6 +63,7 @@ select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS + select HAVE_COPY_THREAD_TLS help The PA-RISC microprocessor is designed by Hewlett-Packard and used --- linux-oracle-5.4.0.orig/arch/parisc/Makefile +++ linux-oracle-5.4.0/arch/parisc/Makefile @@ -17,7 +17,12 @@ # Mike Shaver, Helge Deller and Martin K. Petersen # +ifdef CONFIG_PARISC_SELF_EXTRACT +boot := arch/parisc/boot +KBUILD_IMAGE := $(boot)/bzImage +else KBUILD_IMAGE := vmlinuz +endif NM = sh $(srctree)/arch/parisc/nm CHECKFLAGS += -D__hppa__=1 @@ -60,7 +65,6 @@ -DFTRACE_PATCHABLE_FUNCTION_SIZE=$(NOP_COUNT) CC_FLAGS_FTRACE := -fpatchable-function-entry=$(NOP_COUNT),$(shell echo $$(($(NOP_COUNT)-1))) -KBUILD_LDS_MODULE += $(srctree)/arch/parisc/kernel/module.lds endif OBJCOPY_FLAGS =-O binary -R .note -R .comment -S @@ -156,7 +160,7 @@ $(OBJCOPY) $(boot)/bzImage $@ else vmlinuz: vmlinux - @gzip -cf -9 $< > $@ + @$(KGZIP) -cf -9 $< > $@ endif install: --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/atomic.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/atomic.h @@ -212,6 +212,8 @@ _atomic_spin_unlock_irqrestore(v, flags); } +#define atomic64_set_release(v, i) atomic64_set((v), (i)) + static __inline__ s64 atomic64_read(const atomic64_t *v) { --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/barrier.h @@ -26,6 +26,67 @@ #define __smp_rmb() mb() #define __smp_wmb() mb() +#define __smp_store_release(p, v) \ +do { \ + typeof(p) __p = (p); \ + union { typeof(*p) __val; char __c[1]; } __u = \ + { .__val = (__force typeof(*p)) (v) }; \ + compiletime_assert_atomic_type(*p); \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile("stb,ma %0,0(%1)" \ + : : "r"(*(__u8 *)__u.__c), "r"(__p) \ + : "memory"); \ + break; \ + case 2: \ + asm volatile("sth,ma %0,0(%1)" \ + : : "r"(*(__u16 *)__u.__c), "r"(__p) \ + : "memory"); \ + break; \ + case 4: \ + asm volatile("stw,ma %0,0(%1)" \ + : : "r"(*(__u32 *)__u.__c), "r"(__p) \ + : "memory"); \ + break; \ + case 8: \ + if (IS_ENABLED(CONFIG_64BIT)) \ + asm volatile("std,ma %0,0(%1)" \ + : : "r"(*(__u64 *)__u.__c), "r"(__p) \ + : "memory"); \ + break; \ + } \ +} while (0) + +#define __smp_load_acquire(p) \ +({ \ + union { typeof(*p) __val; char __c[1]; } __u; \ + typeof(p) __p = (p); \ + compiletime_assert_atomic_type(*p); \ + switch (sizeof(*p)) { \ + case 1: \ + asm volatile("ldb,ma 0(%1),%0" \ + : "=r"(*(__u8 *)__u.__c) : "r"(__p) \ + : "memory"); \ + break; \ + case 2: \ + asm volatile("ldh,ma 0(%1),%0" \ + : "=r"(*(__u16 *)__u.__c) : "r"(__p) \ + : "memory"); \ + break; \ + case 4: \ + asm volatile("ldw,ma 0(%1),%0" \ + : "=r"(*(__u32 *)__u.__c) : "r"(__p) \ + : "memory"); \ + break; \ + case 8: \ + if (IS_ENABLED(CONFIG_64BIT)) \ + asm volatile("ldd,ma 0(%1),%0" \ + : "=r"(*(__u64 *)__u.__c) : "r"(__p) \ + : "memory"); \ + break; \ + } \ + __u.__val; \ +}) #include #endif /* !__ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/cacheflush.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/cacheflush.h @@ -57,6 +57,11 @@ #define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages) #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages) +#define flush_dcache_mmap_lock_irqsave(mapping, flags) \ + xa_lock_irqsave(&mapping->i_pages, flags) +#define flush_dcache_mmap_unlock_irqrestore(mapping, flags) \ + xa_unlock_irqrestore(&mapping->i_pages, flags) + #define flush_icache_page(vma,page) do { \ flush_kernel_dcache_page(page); \ --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/checksum.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/checksum.h @@ -42,31 +42,32 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { unsigned int sum; + unsigned long t0, t1, t2; __asm__ __volatile__ ( " ldws,ma 4(%1), %0\n" " addib,<= -4, %2, 2f\n" "\n" -" ldws 4(%1), %%r20\n" -" ldws 8(%1), %%r21\n" -" add %0, %%r20, %0\n" -" ldws,ma 12(%1), %%r19\n" -" addc %0, %%r21, %0\n" -" addc %0, %%r19, %0\n" -"1: ldws,ma 4(%1), %%r19\n" -" addib,< 0, %2, 1b\n" -" addc %0, %%r19, %0\n" +" ldws 4(%1), %4\n" +" ldws 8(%1), %5\n" +" add %0, %4, %0\n" +" ldws,ma 12(%1), %3\n" +" addc %0, %5, %0\n" +" addc %0, %3, %0\n" +"1: ldws,ma 4(%1), %3\n" +" addib,> -1, %2, 1b\n" +" addc %0, %3, %0\n" "\n" -" extru %0, 31, 16, %%r20\n" -" extru %0, 15, 16, %%r21\n" -" addc %%r20, %%r21, %0\n" -" extru %0, 15, 16, %%r21\n" -" add %0, %%r21, %0\n" +" extru %0, 31, 16, %4\n" +" extru %0, 15, 16, %5\n" +" addc %4, %5, %0\n" +" extru %0, 15, 16, %5\n" +" add %0, %5, %0\n" " subi -1, %0, %0\n" "2:\n" - : "=r" (sum), "=r" (iph), "=r" (ihl) + : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2) : "1" (iph), "2" (ihl) - : "r19", "r20", "r21", "memory"); + : "memory"); return (__force __sum16)sum; } @@ -126,6 +127,10 @@ __u32 len, __u8 proto, __wsum sum) { + unsigned long t0, t1, t2, t3; + + len += proto; /* add 16-bit proto + len */ + __asm__ __volatile__ ( #if BITS_PER_LONG > 32 @@ -136,20 +141,20 @@ ** Try to keep 4 registers with "live" values ahead of the ALU. */ -" ldd,ma 8(%1), %%r19\n" /* get 1st saddr word */ -" ldd,ma 8(%2), %%r20\n" /* get 1st daddr word */ -" add %8, %3, %3\n"/* add 16-bit proto + len */ -" add %%r19, %0, %0\n" -" ldd,ma 8(%1), %%r21\n" /* 2cd saddr */ -" ldd,ma 8(%2), %%r22\n" /* 2cd daddr */ -" add,dc %%r20, %0, %0\n" -" add,dc %%r21, %0, %0\n" -" add,dc %%r22, %0, %0\n" +" depdi 0, 31, 32, %0\n"/* clear upper half of incoming checksum */ +" ldd,ma 8(%1), %4\n" /* get 1st saddr word */ +" ldd,ma 8(%2), %5\n" /* get 1st daddr word */ +" add %4, %0, %0\n" +" ldd,ma 8(%1), %6\n" /* 2nd saddr */ +" ldd,ma 8(%2), %7\n" /* 2nd daddr */ +" add,dc %5, %0, %0\n" +" add,dc %6, %0, %0\n" +" add,dc %7, %0, %0\n" " add,dc %3, %0, %0\n" /* fold in proto+len | carry bit */ -" extrd,u %0, 31, 32, %%r19\n" /* copy upper half down */ -" depdi 0, 31, 32, %0\n" /* clear upper half */ -" add %%r19, %0, %0\n" /* fold into 32-bits */ -" addc 0, %0, %0\n" /* add carry */ +" extrd,u %0, 31, 32, %4\n"/* copy upper half down */ +" depdi 0, 31, 32, %0\n"/* clear upper half */ +" add,dc %4, %0, %0\n" /* fold into 32-bits, plus carry */ +" addc 0, %0, %0\n" /* add final carry */ #else @@ -158,30 +163,30 @@ ** Insn stream is serialized on the carry bit here too. ** result from the previous operation (eg r0 + x) */ - -" ldw,ma 4(%1), %%r19\n" /* get 1st saddr word */ -" ldw,ma 4(%2), %%r20\n" /* get 1st daddr word */ -" add %8, %3, %3\n" /* add 16-bit proto + len */ -" add %%r19, %0, %0\n" -" ldw,ma 4(%1), %%r21\n" /* 2cd saddr */ -" addc %%r20, %0, %0\n" -" ldw,ma 4(%2), %%r22\n" /* 2cd daddr */ -" addc %%r21, %0, %0\n" -" ldw,ma 4(%1), %%r19\n" /* 3rd saddr */ -" addc %%r22, %0, %0\n" -" ldw,ma 4(%2), %%r20\n" /* 3rd daddr */ -" addc %%r19, %0, %0\n" -" ldw,ma 4(%1), %%r21\n" /* 4th saddr */ -" addc %%r20, %0, %0\n" -" ldw,ma 4(%2), %%r22\n" /* 4th daddr */ -" addc %%r21, %0, %0\n" -" addc %%r22, %0, %0\n" -" addc %3, %0, %0\n" /* fold in proto+len, catch carry */ +" ldw,ma 4(%1), %4\n" /* get 1st saddr word */ +" ldw,ma 4(%2), %5\n" /* get 1st daddr word */ +" add %4, %0, %0\n" +" ldw,ma 4(%1), %6\n" /* 2nd saddr */ +" addc %5, %0, %0\n" +" ldw,ma 4(%2), %7\n" /* 2nd daddr */ +" addc %6, %0, %0\n" +" ldw,ma 4(%1), %4\n" /* 3rd saddr */ +" addc %7, %0, %0\n" +" ldw,ma 4(%2), %5\n" /* 3rd daddr */ +" addc %4, %0, %0\n" +" ldw,ma 4(%1), %6\n" /* 4th saddr */ +" addc %5, %0, %0\n" +" ldw,ma 4(%2), %7\n" /* 4th daddr */ +" addc %6, %0, %0\n" +" addc %7, %0, %0\n" +" addc %3, %0, %0\n" /* fold in proto+len */ +" addc 0, %0, %0\n" /* add carry */ #endif - : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len) - : "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto) - : "r19", "r20", "r21", "r22", "memory"); + : "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len), + "=r" (t0), "=r" (t1), "=r" (t2), "=r" (t3) + : "0" (sum), "1" (saddr), "2" (daddr), "3" (len) + : "memory"); return csum_fold(sum); } --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/cmpxchg.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/cmpxchg.h @@ -44,8 +44,14 @@ ** if (((unsigned long)p & 0xf) == 0) ** return __ldcw(p); */ -#define xchg(ptr, x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))) +#define xchg(ptr, x) \ +({ \ + __typeof__(*(ptr)) __ret; \ + __typeof__(*(ptr)) _x_ = (x); \ + __ret = (__typeof__(*(ptr))) \ + __xchg((unsigned long)_x_, (ptr), sizeof(*(ptr))); \ + __ret; \ +}) /* bug catcher for when unsupported size is used - won't link */ extern void __cmpxchg_called_with_bad_pointer(void); @@ -54,6 +60,7 @@ extern unsigned long __cmpxchg_u32(volatile unsigned int *m, unsigned int old, unsigned int new_); extern u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new_); +extern u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new_); /* don't worry...optimizer will get rid of most of this */ static inline unsigned long @@ -65,6 +72,7 @@ #endif case 4: return __cmpxchg_u32((unsigned int *)ptr, (unsigned int)old, (unsigned int)new_); + case 1: return __cmpxchg_u8((u8 *)ptr, old & 0xff, new_ & 0xff); } __cmpxchg_called_with_bad_pointer(); return old; --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/hardware.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/hardware.h @@ -10,12 +10,12 @@ #define SVERSION_ANY_ID PA_SVERSION_ANY_ID struct hp_hardware { - unsigned short hw_type:5; /* HPHW_xxx */ - unsigned short hversion; - unsigned long sversion:28; - unsigned short opt; - const char name[80]; /* The hardware description */ -}; + unsigned int hw_type:8; /* HPHW_xxx */ + unsigned int hversion:12; + unsigned int sversion:12; + unsigned char opt; + unsigned char name[59]; /* The hardware description */ +} __packed; struct parisc_device; --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/kexec.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/kexec.h @@ -2,8 +2,6 @@ #ifndef _ASM_PARISC_KEXEC_H #define _ASM_PARISC_KEXEC_H -#ifdef CONFIG_KEXEC - /* Maximum physical address we can use pages from */ #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) /* Maximum address we can reach in physical address mode */ @@ -32,6 +30,4 @@ #endif /* __ASSEMBLY__ */ -#endif /* CONFIG_KEXEC */ - #endif /* _ASM_PARISC_KEXEC_H */ --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/ldcw.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/ldcw.h @@ -2,14 +2,28 @@ #ifndef __PARISC_LDCW_H #define __PARISC_LDCW_H -#ifndef CONFIG_PA20 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, and GCC only guarantees 8-byte alignment for stack locals, we can't be assured of 16-byte alignment for atomic lock data even if we specify "__attribute ((aligned(16)))" in the type declaration. So, we use a struct containing an array of four ints for the atomic lock type and dynamically select the 16-byte aligned int from the array - for the semaphore. */ + for the semaphore. */ + +/* From: "Jim Hull" + I've attached a summary of the change, but basically, for PA 2.0, as + long as the ",CO" (coherent operation) completer is implemented, then the + 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead + they only require "natural" alignment (4-byte for ldcw, 8-byte for + ldcd). + + Although the cache control hint is accepted by all PA 2.0 processors, + it is only implemented on PA8800/PA8900 CPUs. Prior PA8X00 CPUs still + require 16-byte alignment. If the address is unaligned, the operation + of the instruction is undefined. The ldcw instruction does not generate + unaligned data reference traps so misaligned accesses are not detected. + This hid the problem for years. So, restore the 16-byte alignment dropped + by Kyle McMartin in "Remove __ldcw_align for PA-RISC 2.0 processors". */ #define __PA_LDCW_ALIGNMENT 16 #define __PA_LDCW_ALIGN_ORDER 4 @@ -19,22 +33,12 @@ & ~(__PA_LDCW_ALIGNMENT - 1); \ (volatile unsigned int *) __ret; \ }) -#define __LDCW "ldcw" -#else /*CONFIG_PA20*/ -/* From: "Jim Hull" - I've attached a summary of the change, but basically, for PA 2.0, as - long as the ",CO" (coherent operation) completer is specified, then the - 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead - they only require "natural" alignment (4-byte for ldcw, 8-byte for - ldcd). */ - -#define __PA_LDCW_ALIGNMENT 4 -#define __PA_LDCW_ALIGN_ORDER 2 -#define __ldcw_align(a) (&(a)->slock) +#ifdef CONFIG_PA20 #define __LDCW "ldcw,co" - -#endif /*!CONFIG_PA20*/ +#else +#define __LDCW "ldcw" +#endif /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. We don't explicitly expose that "*a" may be written as reload --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/led.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/led.h @@ -11,8 +11,8 @@ #define LED1 0x02 #define LED0 0x01 /* bottom (or furthest left) LED */ -#define LED_LAN_TX LED0 /* for LAN transmit activity */ -#define LED_LAN_RCV LED1 /* for LAN receive activity */ +#define LED_LAN_RCV LED0 /* for LAN receive activity */ +#define LED_LAN_TX LED1 /* for LAN transmit activity */ #define LED_DISK_IO LED2 /* for disk activity */ #define LED_HEARTBEAT LED3 /* heartbeat */ --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/page.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/page.h @@ -181,7 +181,7 @@ #include #include -#define PAGE0 ((struct zeropage *)__PAGE_OFFSET) +#define PAGE0 ((struct zeropage *)absolute_pointer(__PAGE_OFFSET)) /* DEFINITION OF THE ZERO-PAGE (PAG0) */ /* based on work by Jason Eckhardt (jason@equator.com) */ --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/processor.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/processor.h @@ -97,7 +97,6 @@ unsigned long cpu_loc; /* CPU location from PAT firmware */ unsigned int state; struct parisc_device *dev; - unsigned long loops_per_jiffy; }; extern struct system_cpuinfo_parisc boot_cpu_data; --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/ropes.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/ropes.h @@ -86,6 +86,9 @@ struct ioc ioc[MAX_IOC]; }; +/* list of SBA's in system, see drivers/parisc/sba_iommu.c */ +extern struct sba_device *sba_list; + #define ASTRO_RUNWAY_PORT 0x582 #define IKE_MERCED_PORT 0x803 #define REO_MERCED_PORT 0x804 --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/spinlock.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/spinlock.h @@ -37,12 +37,8 @@ volatile unsigned int *a; a = __ldcw_align(x); -#ifdef CONFIG_SMP - (void) __ldcw(a); -#else - mb(); -#endif - *a = 1; + /* Release with ordered store. */ + __asm__ __volatile__("stw,ma %0,0(%1)" : : "r"(1), "r"(a) : "memory"); } static inline int arch_spin_trylock(arch_spinlock_t *x) --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/spinlock_types.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/spinlock_types.h @@ -3,13 +3,8 @@ #define __ASM_SPINLOCK_TYPES_H typedef struct { -#ifdef CONFIG_PA20 - volatile unsigned int slock; -# define __ARCH_SPIN_LOCK_UNLOCKED { 1 } -#else volatile unsigned int lock[4]; # define __ARCH_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } -#endif } arch_spinlock_t; typedef struct { --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/string.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/string.h @@ -8,19 +8,4 @@ #define __HAVE_ARCH_MEMCPY void * memcpy(void * dest,const void *src,size_t count); -#define __HAVE_ARCH_STRLEN -extern size_t strlen(const char *s); - -#define __HAVE_ARCH_STRCPY -extern char *strcpy(char *dest, const char *src); - -#define __HAVE_ARCH_STRNCPY -extern char *strncpy(char *dest, const char *src, size_t count); - -#define __HAVE_ARCH_STRCAT -extern char *strcat(char *dest, const char *src); - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *, int, size_t); - #endif --- linux-oracle-5.4.0.orig/arch/parisc/include/asm/timex.h +++ linux-oracle-5.4.0/arch/parisc/include/asm/timex.h @@ -12,9 +12,10 @@ typedef unsigned long cycles_t; -static inline cycles_t get_cycles (void) +static inline cycles_t get_cycles(void) { return mfctl(16); } +#define get_cycles get_cycles #endif --- linux-oracle-5.4.0.orig/arch/parisc/include/uapi/asm/mman.h +++ linux-oracle-5.4.0/arch/parisc/include/uapi/asm/mman.h @@ -48,28 +48,27 @@ #define MADV_DONTFORK 10 /* don't inherit across fork */ #define MADV_DOFORK 11 /* do inherit across fork */ -#define MADV_COLD 20 /* deactivate these pages */ -#define MADV_PAGEOUT 21 /* reclaim these pages */ - -#define MADV_MERGEABLE 65 /* KSM may merge identical pages */ -#define MADV_UNMERGEABLE 66 /* KSM may not merge identical pages */ +#define MADV_MERGEABLE 12 /* KSM may merge identical pages */ +#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ -#define MADV_HUGEPAGE 67 /* Worth backing with hugepages */ -#define MADV_NOHUGEPAGE 68 /* Not worth backing with hugepages */ +#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ +#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ -#define MADV_DONTDUMP 69 /* Explicity exclude from the core dump, +#define MADV_DONTDUMP 16 /* Explicity exclude from the core dump, overrides the coredump filter bits */ -#define MADV_DODUMP 70 /* Clear the MADV_NODUMP flag */ +#define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */ -#define MADV_WIPEONFORK 71 /* Zero memory on fork, child only */ -#define MADV_KEEPONFORK 72 /* Undo MADV_WIPEONFORK */ +#define MADV_WIPEONFORK 18 /* Zero memory on fork, child only */ +#define MADV_KEEPONFORK 19 /* Undo MADV_WIPEONFORK */ + +#define MADV_COLD 20 /* deactivate these pages */ +#define MADV_PAGEOUT 21 /* reclaim these pages */ #define MADV_HWPOISON 100 /* poison a page for testing */ #define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ /* compatibility flags */ #define MAP_FILE 0 -#define MAP_VARIABLE 0 #define PKEY_DISABLE_ACCESS 0x1 #define PKEY_DISABLE_WRITE 0x2 --- linux-oracle-5.4.0.orig/arch/parisc/include/uapi/asm/pdc.h +++ linux-oracle-5.4.0/arch/parisc/include/uapi/asm/pdc.h @@ -465,6 +465,7 @@ unsigned long arch_rev; unsigned long pot_key; unsigned long curr_key; + unsigned long width; /* default of PSW_W bit (1=enabled) */ }; struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */ --- linux-oracle-5.4.0.orig/arch/parisc/install.sh +++ linux-oracle-5.4.0/arch/parisc/install.sh @@ -39,6 +39,7 @@ if [ -n "${INSTALLKERNEL}" ]; then if [ -x ~/bin/${INSTALLKERNEL} ]; then exec ~/bin/${INSTALLKERNEL} "$@"; fi if [ -x /sbin/${INSTALLKERNEL} ]; then exec /sbin/${INSTALLKERNEL} "$@"; fi + if [ -x /usr/sbin/${INSTALLKERNEL} ]; then exec /usr/sbin/${INSTALLKERNEL} "$@"; fi fi # Default install --- linux-oracle-5.4.0.orig/arch/parisc/kernel/Makefile +++ linux-oracle-5.4.0/arch/parisc/kernel/Makefile @@ -37,5 +37,5 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_KEXEC) += kexec.o relocate_kernel.o +obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o obj-$(CONFIG_KEXEC_FILE) += kexec_file.o --- linux-oracle-5.4.0.orig/arch/parisc/kernel/cache.c +++ linux-oracle-5.4.0/arch/parisc/kernel/cache.c @@ -328,6 +328,7 @@ struct vm_area_struct *mpnt; unsigned long offset; unsigned long addr, old_addr = 0; + unsigned long flags; pgoff_t pgoff; if (mapping && !mapping_mapped(mapping)) { @@ -347,7 +348,7 @@ * declared as MAP_PRIVATE or MAP_SHARED), so we only need * to flush one address here for them all to become coherent */ - flush_dcache_mmap_lock(mapping); + flush_dcache_mmap_lock_irqsave(mapping, flags); vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; addr = mpnt->vm_start + offset; @@ -370,7 +371,7 @@ old_addr = addr; } } - flush_dcache_mmap_unlock(mapping); + flush_dcache_mmap_unlock_irqrestore(mapping, flags); } EXPORT_SYMBOL(flush_dcache_page); --- linux-oracle-5.4.0.orig/arch/parisc/kernel/drivers.c +++ linux-oracle-5.4.0/arch/parisc/kernel/drivers.c @@ -520,7 +520,6 @@ dev->id.hversion_rev = iodc_data[1] & 0x0f; dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) | (iodc_data[5] << 8) | iodc_data[6]; - dev->hpa.name = parisc_pathname(dev); dev->hpa.start = hpa; /* This is awkward. The STI spec says that gfx devices may occupy * 32MB or 64MB. Unfortunately, we don't know how to tell whether @@ -534,10 +533,10 @@ dev->hpa.end = hpa + 0xfff; } dev->hpa.flags = IORESOURCE_MEM; - name = parisc_hardware_description(&dev->id); - if (name) { - strlcpy(dev->name, name, sizeof(dev->name)); - } + dev->hpa.name = dev->name; + name = parisc_hardware_description(&dev->id) ? : "unknown"; + snprintf(dev->name, sizeof(dev->name), "%s [%s]", + name, parisc_pathname(dev)); /* Silently fail things like mouse ports which are subsumed within * the keyboard controller @@ -810,7 +809,7 @@ static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, struct device *parent); -static void walk_lower_bus(struct parisc_device *dev) +static void __init walk_lower_bus(struct parisc_device *dev) { unsigned long io_io_low, io_io_high; @@ -883,15 +882,13 @@ &root); } -static void print_parisc_device(struct parisc_device *dev) +static __init void print_parisc_device(struct parisc_device *dev) { - char hw_path[64]; - static int count; + static int count __initdata; - print_pa_hwpath(dev, hw_path); - pr_info("%d. %s at 0x%px [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }", - ++count, dev->name, (void*) dev->hpa.start, hw_path, dev->id.hw_type, - dev->id.hversion_rev, dev->id.hversion, dev->id.sversion); + pr_info("%d. %s at %pap { type:%d, hv:%#x, sv:%#x, rev:%#x }", + ++count, dev->name, &(dev->hpa.start), dev->id.hw_type, + dev->id.hversion, dev->id.sversion, dev->id.hversion_rev); if (dev->num_addrs) { int k; @@ -927,9 +924,9 @@ pr_info("#define PARISC_MODEL \"%s\"\n\n", boot_cpu_data.pdc.sys_model_name); + #define p ((unsigned long *)&boot_cpu_data.pdc.model) pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", - #define p ((unsigned long *)&boot_cpu_data.pdc.model) p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); #undef p @@ -1080,7 +1077,7 @@ -static int print_one_device(struct device * dev, void * data) +static __init int print_one_device(struct device * dev, void * data) { struct parisc_device * pdev = to_parisc_device(dev); --- linux-oracle-5.4.0.orig/arch/parisc/kernel/entry.S +++ linux-oracle-5.4.0/arch/parisc/kernel/entry.S @@ -454,7 +454,6 @@ nop LDREG 0(\ptp),\pte bb,<,n \pte,_PAGE_PRESENT_BIT,3f - LDCW 0(\tmp),\tmp1 b \fault stw \spc,0(\tmp) 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) @@ -464,23 +463,26 @@ 3: .endm - /* Release pa_tlb_lock lock without reloading lock address. */ - .macro tlb_unlock0 spc,tmp,tmp1 + /* Release pa_tlb_lock lock without reloading lock address. + Note that the values in the register spc are limited to + NR_SPACE_IDS (262144). Thus, the stw instruction always + stores a nonzero value even when register spc is 64 bits. + We use an ordered store to ensure all prior accesses are + performed prior to releasing the lock. */ + .macro tlb_unlock0 spc,tmp #ifdef CONFIG_SMP 98: or,COND(=) %r0,\spc,%r0 - LDCW 0(\tmp),\tmp1 - or,COND(=) %r0,\spc,%r0 - stw \spc,0(\tmp) + stw,ma \spc,0(\tmp) 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) #endif .endm /* Release pa_tlb_lock lock. */ - .macro tlb_unlock1 spc,tmp,tmp1 + .macro tlb_unlock1 spc,tmp #ifdef CONFIG_SMP 98: load_pa_tlb_lock \tmp 99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) - tlb_unlock0 \spc,\tmp,\tmp1 + tlb_unlock0 \spc,\tmp #endif .endm @@ -509,13 +511,13 @@ * to a CPU TLB 4k PFN (4k => 12 bits to shift) */ #define PAGE_ADD_SHIFT (PAGE_SHIFT-12) #define PAGE_ADD_HUGE_SHIFT (REAL_HPAGE_SHIFT-12) + #define PFN_START_BIT (63-ASM_PFN_PTE_SHIFT+(63-58)-PAGE_ADD_SHIFT) /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ .macro convert_for_tlb_insert20 pte,tmp #ifdef CONFIG_HUGETLB_PAGE copy \pte,\tmp - extrd,u \tmp,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ - 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte + extrd,u \tmp,PFN_START_BIT,PFN_START_BIT+1,\pte depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_SHIFT,\pte @@ -523,8 +525,7 @@ depdi _HUGE_PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_HUGE_SHIFT,\pte #else /* Huge pages disabled */ - extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\ - 64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte + extrd,u \pte,PFN_START_BIT,PFN_START_BIT+1,\pte depdi _PAGE_SIZE_ENCODING_DEFAULT,63,\ (63-58)+PAGE_ADD_SHIFT,\pte #endif @@ -1077,8 +1078,7 @@ STREG %r16, PT_ISR(%r29) STREG %r17, PT_IOR(%r29) -#if 0 && defined(CONFIG_64BIT) - /* Revisit when we have 64-bit code above 4Gb */ +#if defined(CONFIG_64BIT) b,n intr_save2 skip_save_ior: @@ -1086,8 +1086,7 @@ * need to adjust iasq/iaoq here in the same way we adjusted isr/ior * above. */ - extrd,u,* %r8,PSW_W_BIT,1,%r1 - cmpib,COND(=),n 1,%r1,intr_save2 + bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 /* adjust iasq/iaoq */ @@ -1163,7 +1162,7 @@ idtlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1189,7 +1188,7 @@ idtlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1223,7 +1222,7 @@ mtsp t1, %sr1 /* Restore sr1 */ - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1256,7 +1255,7 @@ mtsp t1, %sr1 /* Restore sr1 */ - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1285,7 +1284,7 @@ idtlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1313,7 +1312,7 @@ idtlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1420,7 +1419,7 @@ iitlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1444,7 +1443,7 @@ iitlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1478,7 +1477,7 @@ mtsp t1, %sr1 /* Restore sr1 */ - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1502,7 +1501,7 @@ mtsp t1, %sr1 /* Restore sr1 */ - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1532,7 +1531,7 @@ iitlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1552,7 +1551,7 @@ iitlbt pte,prot - tlb_unlock1 spc,t0,t1 + tlb_unlock1 spc,t0 rfir nop @@ -1582,7 +1581,7 @@ idtlbt pte,prot - tlb_unlock0 spc,t0,t1 + tlb_unlock0 spc,t0 rfir nop #else @@ -1608,7 +1607,7 @@ mtsp t1, %sr1 /* Restore sr1 */ - tlb_unlock0 spc,t0,t1 + tlb_unlock0 spc,t0 rfir nop @@ -1628,7 +1627,7 @@ idtlbt pte,prot - tlb_unlock0 spc,t0,t1 + tlb_unlock0 spc,t0 rfir nop #endif @@ -1839,8 +1838,8 @@ LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* Are we being ptraced? */ - ldw TASK_FLAGS(%r1),%r19 - ldi _TIF_SYSCALL_TRACE_MASK,%r2 + LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 + ldi _TIF_SINGLESTEP|_TIF_BLOCKSTEP,%r2 and,COND(=) %r19,%r2,%r0 b,n syscall_restore_rfi --- linux-oracle-5.4.0.orig/arch/parisc/kernel/firmware.c +++ linux-oracle-5.4.0/arch/parisc/kernel/firmware.c @@ -122,10 +122,10 @@ #ifdef CONFIG_64BIT if(unlikely(parisc_narrow_firmware)) { if((address & 0xff000000) == 0xf0000000) - return 0xf0f0f0f000000000UL | (u32)address; + return (0xfffffff0UL << 32) | (u32)address; if((address & 0xf0000000) == 0xf0000000) - return 0xffffffff00000000UL | (u32)address; + return (0xffffffffUL << 32) | (u32)address; } #endif return address; @@ -1229,7 +1229,7 @@ */ int pdc_iodc_print(const unsigned char *str, unsigned count) { - unsigned int i; + unsigned int i, found = 0; unsigned long flags; for (i = 0; i < count;) { @@ -1238,6 +1238,7 @@ iodc_dbuf[i+0] = '\r'; iodc_dbuf[i+1] = '\n'; i += 2; + found = 1; goto print; default: iodc_dbuf[i] = str[i]; @@ -1254,7 +1255,7 @@ __pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0); spin_unlock_irqrestore(&pdc_lock, flags); - return i; + return i - found; } #if !defined(BOOTLOADER) --- linux-oracle-5.4.0.orig/arch/parisc/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/parisc/kernel/ftrace.c @@ -80,7 +80,7 @@ #endif } -#ifdef CONFIG_FUNCTION_GRAPH_TRACER +#if defined(CONFIG_DYNAMIC_FTRACE) && defined(CONFIG_FUNCTION_GRAPH_TRACER) int ftrace_enable_ftrace_graph_caller(void) { return 0; --- linux-oracle-5.4.0.orig/arch/parisc/kernel/head.S +++ linux-oracle-5.4.0/arch/parisc/kernel/head.S @@ -22,7 +22,7 @@ #include #include - .level PA_ASM_LEVEL + .level 1.1 __INITDATA ENTRY(boot_args) @@ -69,6 +69,46 @@ stw,ma %arg2,4(%r1) stw,ma %arg3,4(%r1) +#if defined(CONFIG_PA20) + /* check for 64-bit capable CPU as required by current kernel */ + ldi 32,%r10 + mtctl %r10,%cr11 + .level 2.0 + mfctl,w %cr11,%r10 + .level 1.1 + comib,<>,n 0,%r10,$cpu_ok + + load32 PA(msg1),%arg0 + ldi msg1_end-msg1,%arg1 +$iodc_panic: + copy %arg0, %r10 + copy %arg1, %r11 + load32 PA(init_stack),%sp +#define MEM_CONS 0x3A0 + ldw MEM_CONS+32(%r0),%arg0 // HPA + ldi ENTRY_IO_COUT,%arg1 + ldw MEM_CONS+36(%r0),%arg2 // SPA + ldw MEM_CONS+8(%r0),%arg3 // layers + load32 PA(__bss_start),%r1 + stw %r1,-52(%sp) // arg4 + stw %r0,-56(%sp) // arg5 + stw %r10,-60(%sp) // arg6 = ptr to text + stw %r11,-64(%sp) // arg7 = len + stw %r0,-68(%sp) // arg8 + load32 PA(.iodc_panic_ret), %rp + ldw MEM_CONS+40(%r0),%r1 // ENTRY_IODC + bv,n (%r1) +.iodc_panic_ret: + b . /* wait endless with ... */ + or %r10,%r10,%r10 /* qemu idle sleep */ +msg1: .ascii "Can't boot kernel which was built for PA8x00 CPUs on this machine.\r\n" +msg1_end: + +$cpu_ok: +#endif + + .level PA_ASM_LEVEL + /* Initialize startup VM. Just map first 16/32 MB of memory */ load32 PA(swapper_pg_dir),%r4 mtctl %r4,%cr24 /* Initialize kernel root pointer */ --- linux-oracle-5.4.0.orig/arch/parisc/kernel/irq.c +++ linux-oracle-5.4.0/arch/parisc/kernel/irq.c @@ -376,7 +376,11 @@ /* * IRQ STACK - used for irq handler */ +#ifdef CONFIG_64BIT +#define IRQ_STACK_SIZE (4096 << 4) /* 64k irq stack size */ +#else #define IRQ_STACK_SIZE (4096 << 3) /* 32k irq stack size */ +#endif union irq_stack_union { unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; @@ -384,7 +388,7 @@ volatile unsigned int lock[1]; }; -DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { +static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { .slock = { 1,1,1,1 }, }; #endif --- linux-oracle-5.4.0.orig/arch/parisc/kernel/module.c +++ linux-oracle-5.4.0/arch/parisc/kernel/module.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -862,7 +863,7 @@ const char *strtab = NULL; const Elf_Shdr *s; char *secstrings; - int err, symindex = -1; + int symindex = -1; Elf_Sym *newptr, *oldptr; Elf_Shdr *symhdr = NULL; #ifdef DEBUG @@ -946,11 +947,13 @@ /* patch .altinstructions */ apply_alternatives(aseg, aseg + s->sh_size, me->name); +#ifdef CONFIG_DYNAMIC_FTRACE /* For 32 bit kernels we're compiling modules with * -ffunction-sections so we must relocate the addresses in the - *__mcount_loc section. + * ftrace callsite section. */ - if (symindex != -1 && !strcmp(secname, "__mcount_loc")) { + if (symindex != -1 && !strcmp(secname, FTRACE_CALLSITE_SECTION)) { + int err; if (s->sh_type == SHT_REL) err = apply_relocate((Elf_Shdr *)sechdrs, strtab, symindex, @@ -962,6 +965,7 @@ if (err) return err; } +#endif } return 0; } --- linux-oracle-5.4.0.orig/arch/parisc/kernel/parisc_ksyms.c +++ linux-oracle-5.4.0/arch/parisc/kernel/parisc_ksyms.c @@ -17,14 +17,11 @@ #include EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strcpy); -EXPORT_SYMBOL(strncpy); -EXPORT_SYMBOL(strcat); #include EXPORT_SYMBOL(__xchg8); EXPORT_SYMBOL(__xchg32); +EXPORT_SYMBOL(__cmpxchg_u8); EXPORT_SYMBOL(__cmpxchg_u32); EXPORT_SYMBOL(__cmpxchg_u64); #ifdef CONFIG_SMP --- linux-oracle-5.4.0.orig/arch/parisc/kernel/patch.c +++ linux-oracle-5.4.0/arch/parisc/kernel/patch.c @@ -40,10 +40,7 @@ *need_unmap = 1; set_fixmap(fixmap, page_to_phys(page)); - if (flags) - raw_spin_lock_irqsave(&patch_lock, *flags); - else - __acquire(&patch_lock); + raw_spin_lock_irqsave(&patch_lock, *flags); return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK)); } @@ -52,10 +49,7 @@ { clear_fixmap(fixmap); - if (flags) - raw_spin_unlock_irqrestore(&patch_lock, *flags); - else - __release(&patch_lock); + raw_spin_unlock_irqrestore(&patch_lock, *flags); } void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) @@ -67,8 +61,9 @@ int mapped; /* Make sure we don't have any aliases in cache */ - flush_kernel_vmap_range(addr, len); - flush_icache_range(start, end); + flush_kernel_dcache_range_asm(start, end); + flush_kernel_icache_range_asm(start, end); + flush_tlb_kernel_range(start, end); p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, &mapped); @@ -81,8 +76,10 @@ * We're crossing a page boundary, so * need to remap */ - flush_kernel_vmap_range((void *)fixmap, - (p-fixmap) * sizeof(*p)); + flush_kernel_dcache_range_asm((unsigned long)fixmap, + (unsigned long)p); + flush_tlb_kernel_range((unsigned long)fixmap, + (unsigned long)p); if (mapped) patch_unmap(FIX_TEXT_POKE0, &flags); p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, @@ -90,10 +87,10 @@ } } - flush_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p)); + flush_kernel_dcache_range_asm((unsigned long)fixmap, (unsigned long)p); + flush_tlb_kernel_range((unsigned long)fixmap, (unsigned long)p); if (mapped) patch_unmap(FIX_TEXT_POKE0, &flags); - flush_icache_range(start, end); } void __kprobes __patch_text(void *addr, u32 insn) --- linux-oracle-5.4.0.orig/arch/parisc/kernel/pci-dma.c +++ linux-oracle-5.4.0/arch/parisc/kernel/pci-dma.c @@ -439,16 +439,32 @@ free_pages((unsigned long)__va(dma_handle), order); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { + /* + * fdc: The data cache line is written back to memory, if and only if + * it is dirty, and then invalidated from the data cache. + */ flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - flush_kernel_dcache_range((unsigned long)phys_to_virt(paddr), size); + unsigned long addr = (unsigned long) phys_to_virt(paddr); + + switch (dir) { + case DMA_TO_DEVICE: + case DMA_BIDIRECTIONAL: + flush_kernel_dcache_range(addr, size); + return; + case DMA_FROM_DEVICE: + purge_kernel_dcache_range_asm(addr, addr + size); + return; + default: + BUG(); + } } void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, --- linux-oracle-5.4.0.orig/arch/parisc/kernel/process.c +++ linux-oracle-5.4.0/arch/parisc/kernel/process.c @@ -124,13 +124,18 @@ /* It seems we have no way to power the system off via * software. The user has to press the button himself. */ - printk(KERN_EMERG "System shut down completed.\n" - "Please power this system off now."); + printk("Power off or press RETURN to reboot.\n"); /* prevent soft lockup/stalled CPU messages for endless loop. */ rcu_sysrq_start(); lockup_detector_soft_poweroff(); - for (;;); + while (1) { + /* reboot if user presses RETURN key */ + if (pdc_iodc_getc() == 13) { + printk("Rebooting...\n"); + machine_restart(NULL); + } + } } void (*pm_power_off)(void); @@ -208,8 +213,8 @@ * Copy architecture-specific thread state */ int -copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long kthread_arg, struct task_struct *p) +copy_thread_tls(unsigned long clone_flags, unsigned long usp, + unsigned long kthread_arg, struct task_struct *p, unsigned long tls) { struct pt_regs *cregs = &(p->thread.regs); void *stack = task_stack_page(p); @@ -254,9 +259,9 @@ cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; cregs->kpc = (unsigned long) &child_return; - /* Setup thread TLS area from the 4th parameter in clone */ + /* Setup thread TLS area */ if (clone_flags & CLONE_SETTLS) - cregs->cr27 = cregs->gr[23]; + cregs->cr27 = tls; } return 0; --- linux-oracle-5.4.0.orig/arch/parisc/kernel/processor.c +++ linux-oracle-5.4.0/arch/parisc/kernel/processor.c @@ -163,7 +163,6 @@ if (cpuid) memset(p, 0, sizeof(struct cpuinfo_parisc)); - p->loops_per_jiffy = loops_per_jiffy; p->dev = dev; /* Save IODC data in case we need it */ p->hpa = dev->hpa.start; /* save CPU hpa */ p->cpuid = cpuid; /* save CPU id */ @@ -373,10 +372,18 @@ show_cpuinfo (struct seq_file *m, void *v) { unsigned long cpu; + char cpu_name[60], *p; + + /* strip PA path from CPU name to not confuse lscpu */ + strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); + p = strrchr(cpu_name, '['); + if (p) + *(--p) = 0; for_each_online_cpu(cpu) { - const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); #ifdef CONFIG_SMP + const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); + if (0 == cpuinfo->hpa) continue; #endif @@ -419,11 +426,9 @@ } seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities); - seq_printf(m, "model\t\t: %s\n" - "model name\t: %s\n", + seq_printf(m, "model\t\t: %s - %s\n", boot_cpu_data.pdc.sys_model_name, - cpuinfo->dev ? - cpuinfo->dev->name : "Unknown"); + cpu_name); seq_printf(m, "hversion\t: 0x%08x\n" "sversion\t: 0x%08x\n", @@ -434,8 +439,8 @@ show_cache_info(m); seq_printf(m, "bogomips\t: %lu.%02lu\n", - cpuinfo->loops_per_jiffy / (500000 / HZ), - (cpuinfo->loops_per_jiffy / (5000 / HZ)) % 100); + loops_per_jiffy / (500000 / HZ), + loops_per_jiffy / (5000 / HZ) % 100); seq_printf(m, "software id\t: %ld\n\n", boot_cpu_data.pdc.model.sw_id); --- linux-oracle-5.4.0.orig/arch/parisc/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/parisc/kernel/ptrace.c @@ -128,6 +128,12 @@ unsigned long tmp; long ret = -EIO; + unsigned long user_regs_struct_size = sizeof(struct user_regs_struct); +#ifdef CONFIG_64BIT + if (is_compat_task()) + user_regs_struct_size /= 2; +#endif + switch (request) { /* Read the word at location addr in the USER area. For ptraced @@ -183,14 +189,14 @@ return copy_regset_to_user(child, task_user_regset_view(current), REGSET_GENERAL, - 0, sizeof(struct user_regs_struct), + 0, user_regs_struct_size, datap); case PTRACE_SETREGS: /* Set all gp regs in the child. */ return copy_regset_from_user(child, task_user_regset_view(current), REGSET_GENERAL, - 0, sizeof(struct user_regs_struct), + 0, user_regs_struct_size, datap); case PTRACE_GETFPREGS: /* Get the child FPU state. */ @@ -304,6 +310,11 @@ } } break; + case PTRACE_GETREGS: + case PTRACE_SETREGS: + case PTRACE_GETFPREGS: + case PTRACE_SETFPREGS: + return arch_ptrace(child, request, addr, data); default: ret = compat_ptrace_request(child, request, addr, data); --- linux-oracle-5.4.0.orig/arch/parisc/kernel/real2.S +++ linux-oracle-5.4.0/arch/parisc/kernel/real2.S @@ -248,9 +248,6 @@ /* save fn */ copy %arg2, %r31 - /* set up the new ap */ - ldo 64(%arg1), %r29 - /* load up the arg registers from the saved arg area */ /* 32-bit calling convention passes first 4 args in registers */ ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */ @@ -262,7 +259,9 @@ ldd 7*REG_SZ(%arg1), %r19 ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */ + /* set up real-mode stack and real-mode ap */ tophys_r1 %sp + ldo -16(%sp), %r29 /* Reference param save area */ b,l rfi_virt2real,%r2 nop --- linux-oracle-5.4.0.orig/arch/parisc/kernel/signal.c +++ linux-oracle-5.4.0/arch/parisc/kernel/signal.c @@ -238,6 +238,12 @@ #endif usp = (regs->gr[30] & ~(0x01UL)); +#ifdef CONFIG_64BIT + if (is_compat_task()) { + /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ + usp = (compat_uint_t)usp; + } +#endif /*FIXME: frame_size parameter is unused, remove it. */ frame = get_sigframe(&ksig->ka, usp, sizeof(*frame)); --- linux-oracle-5.4.0.orig/arch/parisc/kernel/smp.c +++ linux-oracle-5.4.0/arch/parisc/kernel/smp.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,10 @@ IPI_CALL_FUNC, IPI_CPU_START, IPI_CPU_STOP, - IPI_CPU_TEST + IPI_CPU_TEST, +#ifdef CONFIG_KGDB + IPI_ENTER_KGDB, +#endif }; @@ -169,7 +173,12 @@ case IPI_CPU_TEST: smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); break; - +#ifdef CONFIG_KGDB + case IPI_ENTER_KGDB: + smp_debug(100, KERN_DEBUG "CPU%d ENTER_KGDB\n", this_cpu); + kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); + break; +#endif default: printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", this_cpu, which); @@ -225,6 +234,12 @@ } } +#ifdef CONFIG_KGDB +void kgdb_roundup_cpus(void) +{ + send_IPI_allbutself(IPI_ENTER_KGDB); +} +#endif inline void smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); } --- linux-oracle-5.4.0.orig/arch/parisc/kernel/sys_parisc.c +++ linux-oracle-5.4.0/arch/parisc/kernel/sys_parisc.c @@ -373,3 +373,30 @@ return err; } + +/* + * madvise() wrapper + * + * Up to kernel v6.1 parisc has different values than all other + * platforms for the MADV_xxx flags listed below. + * To keep binary compatibility with existing userspace programs + * translate the former values to the new values. + * + * XXX: Remove this wrapper in year 2025 (or later) + */ + +asmlinkage notrace long parisc_madvise(unsigned long start, size_t len_in, int behavior) +{ + switch (behavior) { + case 65: behavior = MADV_MERGEABLE; break; + case 66: behavior = MADV_UNMERGEABLE; break; + case 67: behavior = MADV_HUGEPAGE; break; + case 68: behavior = MADV_NOHUGEPAGE; break; + case 69: behavior = MADV_DONTDUMP; break; + case 70: behavior = MADV_DODUMP; break; + case 71: behavior = MADV_WIPEONFORK; break; + case 72: behavior = MADV_KEEPONFORK; break; + } + + return sys_madvise(start, len_in, behavior); +} --- linux-oracle-5.4.0.orig/arch/parisc/kernel/syscall.S +++ linux-oracle-5.4.0/arch/parisc/kernel/syscall.S @@ -217,10 +217,10 @@ #ifdef CONFIG_64BIT ldil L%sys_call_table, %r1 - or,= %r2,%r2,%r2 - addil L%(sys_call_table64-sys_call_table), %r1 + or,ev %r2,%r2,%r2 + ldil L%sys_call_table64, %r1 ldo R%sys_call_table(%r1), %r19 - or,= %r2,%r2,%r2 + or,ev %r2,%r2,%r2 ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19 @@ -355,10 +355,10 @@ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ ldil L%sys_call_table, %r1 - or,= %r2,%r2,%r2 - addil L%(sys_call_table64-sys_call_table), %r1 + or,ev %r2,%r2,%r2 + ldil L%sys_call_table64, %r1 ldo R%sys_call_table(%r1), %r19 - or,= %r2,%r2,%r2 + or,ev %r2,%r2,%r2 ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19 @@ -478,7 +478,7 @@ extrd,u %r1,PSW_W_BIT,1,%r1 /* sp must be aligned on 4, so deposit the W bit setting into * the bottom of sp temporarily */ - or,ev %r1,%r30,%r30 + or,od %r1,%r30,%r30 /* Clip LWS number to a 32-bit value for 32-bit processes */ depdi 0, 31, 32, %r20 @@ -640,11 +640,7 @@ sub,<> %r28, %r25, %r0 2: stw %r24, 0(%r26) /* Free lock */ -#ifdef CONFIG_SMP -98: LDCW 0(%sr2,%r20), %r1 /* Barrier */ -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG /* Clear thread register indicator */ stw %r0, 4(%sr2,%r20) @@ -658,11 +654,7 @@ 3: /* Error occurred on load or store */ /* Free lock */ -#ifdef CONFIG_SMP -98: LDCW 0(%sr2,%r20), %r1 /* Barrier */ -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG stw %r0, 4(%sr2,%r20) #endif @@ -863,11 +855,7 @@ cas2_end: /* Free lock */ -#ifdef CONFIG_SMP -98: LDCW 0(%sr2,%r20), %r1 /* Barrier */ -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) /* Enable interrupts */ ssm PSW_SM_I, %r0 /* Return to userspace, set no error */ @@ -877,11 +865,7 @@ 22: /* Error occurred on load or store */ /* Free lock */ -#ifdef CONFIG_SMP -98: LDCW 0(%sr2,%r20), %r1 /* Barrier */ -99: ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP) -#endif - stw %r20, 0(%sr2,%r20) + stw,ma %r20, 0(%sr2,%r20) ssm PSW_SM_I, %r0 ldo 1(%r0),%r28 b lws_exit @@ -947,6 +931,8 @@ END(sys_call_table) #ifdef CONFIG_64BIT +#undef __SYSCALL_WITH_COMPAT +#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) .align 8 ENTRY(sys_call_table64) #include /* 64-bit native syscalls */ --- linux-oracle-5.4.0.orig/arch/parisc/kernel/syscalls/syscall.tbl +++ linux-oracle-5.4.0/arch/parisc/kernel/syscalls/syscall.tbl @@ -108,7 +108,7 @@ 95 common fchown sys_fchown 96 common getpriority sys_getpriority 97 common setpriority sys_setpriority -98 common recv sys_recv +98 common recv sys_recv compat_sys_recv 99 common statfs sys_statfs compat_sys_statfs 100 common fstatfs sys_fstatfs compat_sys_fstatfs 101 common stat64 sys_stat64 @@ -131,11 +131,11 @@ 116 common sysinfo sys_sysinfo compat_sys_sysinfo 117 common shutdown sys_shutdown 118 common fsync sys_fsync -119 common madvise sys_madvise +119 common madvise parisc_madvise 120 common clone sys_clone_wrapper 121 common setdomainname sys_setdomainname 122 common sendfile sys_sendfile compat_sys_sendfile -123 common recvfrom sys_recvfrom +123 common recvfrom sys_recvfrom compat_sys_recvfrom 124 32 adjtimex sys_adjtimex_time32 124 64 adjtimex sys_adjtimex 125 common mprotect sys_mprotect @@ -413,7 +413,7 @@ 412 32 utimensat_time64 sys_utimensat sys_utimensat 413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64 414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents +416 32 io_pgetevents_time64 sys_io_pgetevents compat_sys_io_pgetevents_time64 417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64 418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend 419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive --- linux-oracle-5.4.0.orig/arch/parisc/kernel/time.c +++ linux-oracle-5.4.0/arch/parisc/kernel/time.c @@ -245,27 +245,13 @@ static int __init init_cr16_clocksource(void) { /* - * The cr16 interval timers are not syncronized across CPUs on - * different sockets, so mark them unstable and lower rating on - * multi-socket SMP systems. + * The cr16 interval timers are not syncronized across CPUs, even if + * they share the same socket. */ if (num_online_cpus() > 1 && !running_on_qemu) { - int cpu; - unsigned long cpu0_loc; - cpu0_loc = per_cpu(cpu_data, 0).cpu_loc; - - for_each_online_cpu(cpu) { - if (cpu == 0) - continue; - if ((cpu0_loc != 0) && - (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)) - continue; - - clocksource_cr16.name = "cr16_unstable"; - clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; - clocksource_cr16.rating = 0; - break; - } + clocksource_cr16.name = "cr16_unstable"; + clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; + clocksource_cr16.rating = 0; } /* XXX: We may want to mark sched_clock stable here if cr16 clocks are --- linux-oracle-5.4.0.orig/arch/parisc/kernel/traps.c +++ linux-oracle-5.4.0/arch/parisc/kernel/traps.c @@ -268,7 +268,7 @@ panic("Fatal exception"); oops_exit(); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } /* gdb uses break 4,8 */ @@ -305,8 +305,8 @@ #endif #ifdef CONFIG_KGDB - if (unlikely(iir == PARISC_KGDB_COMPILED_BREAK_INSN || - iir == PARISC_KGDB_BREAK_INSN)) { + if (unlikely((iir == PARISC_KGDB_COMPILED_BREAK_INSN || + iir == PARISC_KGDB_BREAK_INSN)) && !user_mode(regs)) { kgdb_handle_exception(9, SIGTRAP, 0, regs); return; } @@ -783,7 +783,7 @@ * unless pagefault_disable() was called before. */ - if (fault_space == 0 && !faulthandler_disabled()) + if (faulthandler_disabled() || fault_space == 0) { /* Clean up and return if in exception table. */ if (fixup_exception(regs)) --- linux-oracle-5.4.0.orig/arch/parisc/kernel/unaligned.c +++ linux-oracle-5.4.0/arch/parisc/kernel/unaligned.c @@ -107,7 +107,7 @@ #define R1(i) (((i)>>21)&0x1f) #define R2(i) (((i)>>16)&0x1f) #define R3(i) ((i)&0x1f) -#define FR3(i) ((((i)<<1)&0x1f)|(((i)>>6)&1)) +#define FR3(i) ((((i)&0x1f)<<1)|(((i)>>6)&1)) #define IM(i,n) (((i)>>1&((1<<(n-1))-1))|((i)&1?((0-1L)<<(n-1)):0)) #define IM5_2(i) IM((i)>>16,5) #define IM5_3(i) IM((i),5) @@ -340,7 +340,7 @@ : "r" (val), "r" (regs->ior), "r" (regs->isr) : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); - return 0; + return ret; } static int emulate_std(struct pt_regs *regs, int frreg, int flop) { @@ -397,7 +397,7 @@ __asm__ __volatile__ ( " mtsp %4, %%sr1\n" " zdep %2, 29, 2, %%r19\n" -" dep %%r0, 31, 2, %2\n" +" dep %%r0, 31, 2, %3\n" " mtsar %%r19\n" " zvdepi -2, 32, %%r19\n" "1: ldw 0(%%sr1,%3),%%r20\n" @@ -409,7 +409,7 @@ " andcm %%r21, %%r19, %%r21\n" " or %1, %%r20, %1\n" " or %2, %%r21, %2\n" -"3: stw %1,0(%%sr1,%1)\n" +"3: stw %1,0(%%sr1,%3)\n" "4: stw %%r1,4(%%sr1,%3)\n" "5: stw %2,8(%%sr1,%3)\n" " copy %%r0, %0\n" @@ -596,7 +596,6 @@ ret = ERR_NOTHANDLED; /* "undefined", but lets kill them. */ break; } -#ifdef CONFIG_PA20 switch (regs->iir & OPCODE2_MASK) { case OPCODE_FLDD_L: @@ -607,22 +606,23 @@ flop=1; ret = emulate_std(regs, R2(regs->iir),1); break; +#ifdef CONFIG_PA20 case OPCODE_LDD_L: ret = emulate_ldd(regs, R2(regs->iir),0); break; case OPCODE_STD_L: ret = emulate_std(regs, R2(regs->iir),0); break; - } #endif + } switch (regs->iir & OPCODE3_MASK) { case OPCODE_FLDW_L: flop=1; - ret = emulate_ldw(regs, R2(regs->iir),0); + ret = emulate_ldw(regs, R2(regs->iir), 1); break; case OPCODE_LDW_M: - ret = emulate_ldw(regs, R2(regs->iir),1); + ret = emulate_ldw(regs, R2(regs->iir), 0); break; case OPCODE_FSTW_L: --- linux-oracle-5.4.0.orig/arch/parisc/kernel/unwind.c +++ linux-oracle-5.4.0/arch/parisc/kernel/unwind.c @@ -21,6 +21,8 @@ #include #include +#include +#include /* #define DEBUG 1 */ #ifdef DEBUG @@ -203,6 +205,11 @@ return 0; } +static bool pc_is_kernel_fn(unsigned long pc, void *fn) +{ + return (unsigned long)dereference_kernel_function_descriptor(fn) == pc; +} + static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size) { /* @@ -221,7 +228,7 @@ extern void * const _call_on_stack; #endif /* CONFIG_IRQSTACKS */ - if (pc == (unsigned long) &handle_interruption) { + if (pc_is_kernel_fn(pc, handle_interruption)) { struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); dbg("Unwinding through handle_interruption()\n"); info->prev_sp = regs->gr[30]; @@ -229,13 +236,13 @@ return 1; } - if (pc == (unsigned long) &ret_from_kernel_thread || - pc == (unsigned long) &syscall_exit) { + if (pc_is_kernel_fn(pc, ret_from_kernel_thread) || + pc_is_kernel_fn(pc, syscall_exit)) { info->prev_sp = info->prev_ip = 0; return 1; } - if (pc == (unsigned long) &intr_return) { + if (pc_is_kernel_fn(pc, intr_return)) { struct pt_regs *regs; dbg("Found intr_return()\n"); @@ -246,20 +253,20 @@ return 1; } - if (pc == (unsigned long) &_switch_to_ret) { + if (pc_is_kernel_fn(pc, _switch_to) || + pc_is_kernel_fn(pc, _switch_to_ret)) { info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); return 1; } #ifdef CONFIG_IRQSTACKS - if (pc == (unsigned long) &_call_on_stack) { + if (pc_is_kernel_fn(pc, _call_on_stack)) { info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); return 1; } #endif - return 0; } --- linux-oracle-5.4.0.orig/arch/parisc/lib/Makefile +++ linux-oracle-5.4.0/arch/parisc/lib/Makefile @@ -3,7 +3,7 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memcpy.o \ - ucmpdi2.o delay.o string.o +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ + ucmpdi2.o delay.o obj-y := iomap.o --- linux-oracle-5.4.0.orig/arch/parisc/lib/bitops.c +++ linux-oracle-5.4.0/arch/parisc/lib/bitops.c @@ -79,3 +79,15 @@ _atomic_spin_unlock_irqrestore(ptr, flags); return (unsigned long)prev; } + +u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new) +{ + unsigned long flags; + u8 prev; + + _atomic_spin_lock_irqsave(ptr, flags); + if ((prev = *ptr) == old) + *ptr = new; + _atomic_spin_unlock_irqrestore(ptr, flags); + return prev; +} --- linux-oracle-5.4.0.orig/arch/parisc/lib/memset.c +++ linux-oracle-5.4.0/arch/parisc/lib/memset.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include +#include + +#define OPSIZ (BITS_PER_LONG/8) +typedef unsigned long op_t; + +void * +memset (void *dstpp, int sc, size_t len) +{ + unsigned int c = sc; + long int dstp = (long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + /* Do the shift in two steps to avoid warning if long has 32 bits. */ + cccc |= (cccc << 16) << 16; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} --- linux-oracle-5.4.0.orig/arch/parisc/math-emu/fpudispatch.c +++ linux-oracle-5.4.0/arch/parisc/math-emu/fpudispatch.c @@ -310,12 +310,15 @@ r1 &= ~3; fpregs[t+3] = fpregs[r1+3]; fpregs[t+2] = fpregs[r1+2]; + fallthrough; case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ fpregs[t] = fpregs[r1]; return(NOEXCEPTION); } + BUG(); case 3: /* FABS */ switch (fmt) { case 2: /* illegal */ @@ -325,13 +328,16 @@ r1 &= ~3; fpregs[t+3] = fpregs[r1+3]; fpregs[t+2] = fpregs[r1+2]; + fallthrough; case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ /* copy and clear sign bit */ fpregs[t] = fpregs[r1] & 0x7fffffff; return(NOEXCEPTION); } + BUG(); case 6: /* FNEG */ switch (fmt) { case 2: /* illegal */ @@ -341,13 +347,16 @@ r1 &= ~3; fpregs[t+3] = fpregs[r1+3]; fpregs[t+2] = fpregs[r1+2]; + fallthrough; case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ /* copy and invert sign bit */ fpregs[t] = fpregs[r1] ^ 0x80000000; return(NOEXCEPTION); } + BUG(); case 7: /* FNEGABS */ switch (fmt) { case 2: /* illegal */ @@ -357,13 +366,16 @@ r1 &= ~3; fpregs[t+3] = fpregs[r1+3]; fpregs[t+2] = fpregs[r1+2]; + fallthrough; case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ /* copy and set sign bit */ fpregs[t] = fpregs[r1] | 0x80000000; return(NOEXCEPTION); } + BUG(); case 4: /* FSQRT */ switch (fmt) { case 0: @@ -376,6 +388,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 5: /* FRND */ switch (fmt) { case 0: @@ -389,7 +402,7 @@ return(MAJOR_0C_EXCP); } } /* end of switch (subop) */ - + BUG(); case 1: /* class 1 */ df = extru(ir,fpdfpos,2); /* get dest format */ if ((df & 2) || (fmt & 2)) { @@ -419,6 +432,7 @@ case 3: /* dbl/dbl */ return(MAJOR_0C_EXCP); } + BUG(); case 1: /* FCNVXF */ switch(fmt) { case 0: /* sgl/sgl */ @@ -434,6 +448,7 @@ return(dbl_to_dbl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 2: /* FCNVFX */ switch(fmt) { case 0: /* sgl/sgl */ @@ -449,6 +464,7 @@ return(dbl_to_dbl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 3: /* FCNVFXT */ switch(fmt) { case 0: /* sgl/sgl */ @@ -464,6 +480,7 @@ return(dbl_to_dbl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 5: /* FCNVUF (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -479,6 +496,7 @@ return(dbl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 6: /* FCNVFU (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -494,6 +512,7 @@ return(dbl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 7: /* FCNVFUT (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -509,10 +528,11 @@ return(dbl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 4: /* undefined */ return(MAJOR_0C_EXCP); } /* end of switch subop */ - + BUG(); case 2: /* class 2 */ fpu_type_flags=fpregs[FPU_TYPE_FLAG_POS]; r2 = extru(ir, fpr2pos, 5) * sizeof(double)/sizeof(u_int); @@ -590,6 +610,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 1: /* FTEST */ switch (fmt) { case 0: @@ -609,8 +630,10 @@ case 3: return(MAJOR_0C_EXCP); } + BUG(); } /* end of switch subop */ } /* end of else for PA1.0 & PA1.1 */ + BUG(); case 3: /* class 3 */ r2 = extru(ir,fpr2pos,5) * sizeof(double)/sizeof(u_int); if (r2 == 0) @@ -633,6 +656,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 1: /* FSUB */ switch (fmt) { case 0: @@ -645,6 +669,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 2: /* FMPY */ switch (fmt) { case 0: @@ -657,6 +682,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 3: /* FDIV */ switch (fmt) { case 0: @@ -669,6 +695,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); case 4: /* FREM */ switch (fmt) { case 0: @@ -681,6 +708,7 @@ case 3: /* quad not implemented */ return(MAJOR_0C_EXCP); } + BUG(); } /* end of class 3 switch */ } /* end of switch(class) */ @@ -736,10 +764,12 @@ return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ fpregs[t] = fpregs[r1]; return(NOEXCEPTION); } + BUG(); case 3: /* FABS */ switch (fmt) { case 2: @@ -747,10 +777,12 @@ return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ fpregs[t] = fpregs[r1] & 0x7fffffff; return(NOEXCEPTION); } + BUG(); case 6: /* FNEG */ switch (fmt) { case 2: @@ -758,10 +790,12 @@ return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ fpregs[t] = fpregs[r1] ^ 0x80000000; return(NOEXCEPTION); } + BUG(); case 7: /* FNEGABS */ switch (fmt) { case 2: @@ -769,10 +803,12 @@ return(MAJOR_0E_EXCP); case 1: /* double */ fpregs[t+1] = fpregs[r1+1]; + fallthrough; case 0: /* single */ fpregs[t] = fpregs[r1] | 0x80000000; return(NOEXCEPTION); } + BUG(); case 4: /* FSQRT */ switch (fmt) { case 0: @@ -785,6 +821,7 @@ case 3: return(MAJOR_0E_EXCP); } + BUG(); case 5: /* FRMD */ switch (fmt) { case 0: @@ -798,7 +835,7 @@ return(MAJOR_0E_EXCP); } } /* end of switch (subop */ - + BUG(); case 1: /* class 1 */ df = extru(ir,fpdfpos,2); /* get dest format */ /* @@ -826,6 +863,7 @@ case 3: /* dbl/dbl */ return(MAJOR_0E_EXCP); } + BUG(); case 1: /* FCNVXF */ switch(fmt) { case 0: /* sgl/sgl */ @@ -841,6 +879,7 @@ return(dbl_to_dbl_fcnvxf(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 2: /* FCNVFX */ switch(fmt) { case 0: /* sgl/sgl */ @@ -856,6 +895,7 @@ return(dbl_to_dbl_fcnvfx(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 3: /* FCNVFXT */ switch(fmt) { case 0: /* sgl/sgl */ @@ -871,6 +911,7 @@ return(dbl_to_dbl_fcnvfxt(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 5: /* FCNVUF (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -886,6 +927,7 @@ return(dbl_to_dbl_fcnvuf(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 6: /* FCNVFU (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -901,6 +943,7 @@ return(dbl_to_dbl_fcnvfu(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 7: /* FCNVFUT (PA2.0 only) */ switch(fmt) { case 0: /* sgl/sgl */ @@ -916,9 +959,11 @@ return(dbl_to_dbl_fcnvfut(&fpregs[r1],0, &fpregs[t],status)); } + BUG(); case 4: /* undefined */ return(MAJOR_0C_EXCP); } /* end of switch subop */ + BUG(); case 2: /* class 2 */ /* * Be careful out there. @@ -994,6 +1039,7 @@ } } /* end of switch subop */ } /* end of else for PA1.0 & PA1.1 */ + BUG(); case 3: /* class 3 */ /* * Be careful out there. @@ -1026,6 +1072,7 @@ return(dbl_fadd(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); } + BUG(); case 1: /* FSUB */ switch (fmt) { case 0: @@ -1035,6 +1082,7 @@ return(dbl_fsub(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); } + BUG(); case 2: /* FMPY or XMPYU */ /* * check for integer multiply (x bit set) @@ -1071,6 +1119,7 @@ &fpregs[r2],&fpregs[t],status)); } } + BUG(); case 3: /* FDIV */ switch (fmt) { case 0: @@ -1080,6 +1129,7 @@ return(dbl_fdiv(&fpregs[r1],&fpregs[r2], &fpregs[t],status)); } + BUG(); case 4: /* FREM */ switch (fmt) { case 0: --- linux-oracle-5.4.0.orig/arch/parisc/mm/fixmap.c +++ linux-oracle-5.4.0/arch/parisc/mm/fixmap.c @@ -18,12 +18,9 @@ pte_t *pte; if (pmd_none(*pmd)) - pmd = pmd_alloc(NULL, pgd, vaddr); - - pte = pte_offset_kernel(pmd, vaddr); - if (pte_none(*pte)) pte = pte_alloc_kernel(pmd, vaddr); + pte = pte_offset_kernel(pmd, vaddr); set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); } --- linux-oracle-5.4.0.orig/arch/parisc/mm/init.c +++ linux-oracle-5.4.0/arch/parisc/mm/init.c @@ -347,9 +347,9 @@ static bool kernel_set_to_readonly; -static void __init map_pages(unsigned long start_vaddr, - unsigned long start_paddr, unsigned long size, - pgprot_t pgprot, int force) +static void __ref map_pages(unsigned long start_vaddr, + unsigned long start_paddr, unsigned long size, + pgprot_t pgprot, int force) { pgd_t *pg_dir; pmd_t *pmd; @@ -485,7 +485,7 @@ flush_tlb_all(); } -void __ref free_initmem(void) +void free_initmem(void) { unsigned long init_begin = (unsigned long)__init_begin; unsigned long init_end = (unsigned long)__init_end; @@ -499,7 +499,6 @@ /* The init text pages are marked R-X. We have to * flush the icache and mark them RW- * - * This is tricky, because map_pages is in the init section. * Do a dummy remap of the data section first (the data * section is already PAGE_KERNEL) to pull in the TLB entries * for map_kernel */ @@ -588,7 +587,7 @@ > BITS_PER_LONG); high_memory = __va((max_pfn << PAGE_SHIFT)); - set_max_mapnr(page_to_pfn(virt_to_page(high_memory - 1)) + 1); + set_max_mapnr(max_low_pfn); memblock_free_all(); #ifdef CONFIG_PA11 @@ -701,27 +700,11 @@ static void __init parisc_bootmem_free(void) { - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - unsigned long holes_size[MAX_NR_ZONES] = { 0, }; - unsigned long mem_start_pfn = ~0UL, mem_end_pfn = 0, mem_size_pfn = 0; - int i; - - for (i = 0; i < npmem_ranges; i++) { - unsigned long start = pmem_ranges[i].start_pfn; - unsigned long size = pmem_ranges[i].pages; - unsigned long end = start + size; - - if (mem_start_pfn > start) - mem_start_pfn = start; - if (mem_end_pfn < end) - mem_end_pfn = end; - mem_size_pfn += size; - } + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; - zones_size[0] = mem_end_pfn - mem_start_pfn; - holes_size[0] = zones_size[0] - mem_size_pfn; + max_zone_pfn[0] = memblock_end_of_DRAM(); - free_area_init_node(0, zones_size, mem_start_pfn, holes_size); + free_area_init(max_zone_pfn); } void __init paging_init(void) @@ -892,9 +875,9 @@ { int do_recycle; - __inc_irq_stat(irq_tlb_count); do_recycle = 0; spin_lock(&sid_lock); + __inc_irq_stat(irq_tlb_count); if (dirty_space_ids > RECYCLE_THRESHOLD) { BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */ get_dirty_sids(&recycle_ndirty,recycle_dirty_array); @@ -913,8 +896,8 @@ #else void flush_tlb_all(void) { - __inc_irq_stat(irq_tlb_count); spin_lock(&sid_lock); + __inc_irq_stat(irq_tlb_count); flush_tlb_all_local(NULL); recycle_sids(); spin_unlock(&sid_lock); --- linux-oracle-5.4.0.orig/arch/powerpc/Kconfig +++ linux-oracle-5.4.0/arch/powerpc/Kconfig @@ -133,7 +133,7 @@ select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64 - select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION) + select ARCH_HAS_STRICT_KERNEL_RWX if (PPC32 && !HIBERNATION) select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE select ARCH_HAS_UACCESS_MCSAFE if PPC64 @@ -147,6 +147,7 @@ select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF if PPC64 select ARCH_WANT_IPC_PARSE_VERSION + select ARCH_WANT_IRQS_OFF_ACTIVATE_MM select ARCH_WEAK_RELEASE_ACQUIRE select BINFMT_ELF select BUILDTIME_EXTABLE_SORT @@ -171,7 +172,7 @@ select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU select HAVE_ARCH_JUMP_LABEL - select HAVE_ARCH_KASAN if PPC32 + select HAVE_ARCH_KASAN if PPC32 && PPC_PAGE_SHIFT <= 14 select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT @@ -210,10 +211,9 @@ select HAVE_KRETPROBES select HAVE_LD_DEAD_CODE_DATA_ELIMINATION select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS - select HAVE_MEMBLOCK_NODE_MAP select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI if PERF_EVENTS || (PPC64 && PPC_BOOK3S) - select HAVE_HARDLOCKUP_DETECTOR_ARCH if (PPC64 && PPC_BOOK3S) + select HAVE_HARDLOCKUP_DETECTOR_ARCH if PPC64 && PPC_BOOK3S && SMP select HAVE_OPROFILE select HAVE_OPTPROBES if PPC64 select HAVE_PERF_EVENTS @@ -221,8 +221,7 @@ select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP - select HAVE_RCU_TABLE_FREE if SMP - select HAVE_RCU_TABLE_NO_INVALIDATE if HAVE_RCU_TABLE_FREE + select HAVE_RCU_TABLE_FREE select HAVE_MMU_GATHER_PAGE_SIZE select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN @@ -237,6 +236,7 @@ select NEED_DMA_MAP_STATE if PPC64 || NOT_COHERENT_CACHE select NEED_SG_DMA_LENGTH select OF + select OF_DMA_DEFAULT_COHERENT if !NOT_COHERENT_CACHE select OF_EARLY_FLATTREE select OLD_SIGACTION if PPC32 select OLD_SIGSUSPEND @@ -661,15 +661,6 @@ def_bool y depends on MEMORY_HOTPLUG -# Some NUMA nodes have memory ranges that span -# other nodes. Even though a pfn is valid and -# between a node's start and end pfns, it may not -# reside on that node. See memmap_init_zone() -# for details. -config NODES_SPAN_OTHER_NODES - def_bool y - depends on NEED_MULTIPLE_NODES - config STDBINUTILS bool "Using standard binutils settings" depends on 44x @@ -722,7 +713,7 @@ config PPC_256K_PAGES bool "256k page size" - depends on 44x && !STDBINUTILS + depends on 44x && !STDBINUTILS && !PPC_47x help Make the page size 256k. @@ -747,6 +738,7 @@ range 13 15 default "15" if PPC_256K_PAGES default "14" if PPC64 + default "14" if KASAN default "13" help Used to define the stack size. The default is almost always what you @@ -934,6 +926,28 @@ If unsure, say y. +config PPC_SECURE_BOOT + prompt "Enable secure boot support" + bool + depends on PPC_POWERNV + depends on IMA_ARCH_POLICY + help + Systems with firmware secure boot enabled need to define security + policies to extend secure boot to the OS. This config allows a user + to enable OS secure boot on systems that have firmware support for + it. If in doubt say N. + +config PPC_SECVAR_SYSFS + bool "Enable sysfs interface for POWER secure variables" + default y + depends on PPC_SECURE_BOOT + depends on SYSFS + help + POWER secure variables are managed and controlled by firmware. + These variables are exposed to userspace via sysfs to enable + read/write operations on these variables. Say Y if you have + secure boot enabled and want to expose variables to userspace. + endmenu config ISA_DMA_API @@ -1022,6 +1036,19 @@ Include support for RapidIO controller on Freescale embedded processors (MPC8548, MPC8641, etc). +config PPC_RTAS_FILTER + bool "Enable filtering of RTAS syscalls" + default y + depends on PPC_RTAS + help + The RTAS syscall API has security issues that could be used to + compromise system integrity. This option enforces restrictions on the + RTAS calls and arguments passed by userspace programs to mitigate + these issues. + + Say Y unless you know what you are doing and the filter is causing + problems for you. + endmenu config NONSTATIC_KERNEL --- linux-oracle-5.4.0.orig/arch/powerpc/Kconfig.debug +++ linux-oracle-5.4.0/arch/powerpc/Kconfig.debug @@ -234,7 +234,7 @@ config PPC_EARLY_DEBUG_CPM bool "Early serial debugging for Freescale CPM-based serial ports" - depends on SERIAL_CPM + depends on SERIAL_CPM=y help Select this to enable early debugging for Freescale chips using a CPM-based serial port. This assumes that the bootwrapper @@ -352,6 +352,7 @@ config FAIL_IOMMU bool "Fault-injection capability for IOMMU" depends on FAULT_INJECTION + depends on PCI || IBMVIO help Provide fault-injection capability for IOMMU. Each device can be selectively enabled via the fail_iommu property. @@ -371,7 +372,7 @@ config PPC_DEBUG_WX bool "Warn on W+X mappings at boot" - depends on PPC_PTDUMP + depends on PPC_PTDUMP && STRICT_KERNEL_RWX help Generate a warning if any W+X mappings are found at boot. --- linux-oracle-5.4.0.orig/arch/powerpc/Makefile +++ linux-oracle-5.4.0/arch/powerpc/Makefile @@ -17,23 +17,6 @@ # Set default 32 bits cross compilers for vdso and boot wrapper CROSS32_COMPILE ?= -ifeq ($(HAS_BIARCH),y) -ifeq ($(CROSS32_COMPILE),) -ifdef CONFIG_PPC32 -# These options will be overridden by any -mcpu option that the CPU -# or platform code sets later on the command line, but they are needed -# to set a sane 32-bit cpu target for the 64-bit cross compiler which -# may default to the wrong ISA. -KBUILD_CFLAGS += -mcpu=powerpc -KBUILD_AFLAGS += -mcpu=powerpc -endif -endif -endif - -ifdef CONFIG_PPC_BOOK3S_32 -KBUILD_CFLAGS += -mcpu=powerpc -endif - # If we're on a ppc/ppc64/ppc64le machine use that defconfig, otherwise just use # ppc64_defconfig because we have nothing better to go on. uname := $(shell uname -m) @@ -91,11 +74,13 @@ endif ifdef CONFIG_PPC64 +ifndef CONFIG_CC_IS_CLANG cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1) cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mcall-aixdesc) aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1) aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mabi=elfv2 endif +endif ifndef CONFIG_CC_IS_CLANG cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mno-strict-align @@ -108,7 +93,7 @@ ifeq ($(HAS_BIARCH),y) KBUILD_CFLAGS += -m$(BITS) -KBUILD_AFLAGS += -m$(BITS) -Wl,-a$(BITS) +KBUILD_AFLAGS += -m$(BITS) KBUILD_LDFLAGS += -m elf$(BITS)$(LDEMULATION) endif @@ -141,6 +126,7 @@ endif CFLAGS-$(CONFIG_PPC64) := $(call cc-option,-mtraceback=no) +ifndef CONFIG_CC_IS_CLANG ifdef CONFIG_CPU_LITTLE_ENDIAN CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc)) AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2) @@ -149,6 +135,7 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc) AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1) endif +endif CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc)) CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions) @@ -168,9 +155,9 @@ CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power9,-mtune=power8) else CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,$(call cc-option,-mtune=power5)) -CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mcpu=power5,-mcpu=power4) +CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power4 endif -else +else ifdef CONFIG_PPC_BOOK3E_64 CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 endif @@ -188,6 +175,7 @@ endif CFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) +AFLAGS-$(CONFIG_TARGET_CPU_BOOL) += $(call cc-option,-mcpu=$(CONFIG_TARGET_CPU)) # Altivec option not allowed with e500mc64 in GCC. ifdef CONFIG_ALTIVEC @@ -198,14 +186,6 @@ CFLAGS-$(CONFIG_E5500_CPU) += $(E5500_CPU) CFLAGS-$(CONFIG_E6500_CPU) += $(call cc-option,-mcpu=e6500,$(E5500_CPU)) -ifdef CONFIG_PPC32 -ifdef CONFIG_PPC_E500MC -CFLAGS-y += $(call cc-option,-mcpu=e500mc,-mcpu=powerpc) -else -CFLAGS-$(CONFIG_E500) += $(call cc-option,-mcpu=8540 -msoft-float,-mcpu=powerpc) -endif -endif - asinstr := $(call as-instr,lis 9$(comma)foo@high,-DHAVE_AS_ATHIGH=1) KBUILD_CPPFLAGS += -I $(srctree)/arch/$(ARCH) $(asinstr) @@ -246,7 +226,6 @@ cpu-as-$(CONFIG_4xx) += -Wa,-m405 cpu-as-$(CONFIG_ALTIVEC) += $(call as-option,-Wa$(comma)-maltivec) -cpu-as-$(CONFIG_E200) += -Wa,-me200 cpu-as-$(CONFIG_E500) += -Wa,-me500 # When using '-many -mpower4' gas will first try and find a matching power4 @@ -281,7 +260,7 @@ all: zImage # With make 3.82 we cannot mix normal and wildcard targets -BOOT_TARGETS1 := zImage zImage.initrd uImage +BOOT_TARGETS1 := zImage zImage.initrd uImage vmlinux.strip BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.% PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2) @@ -446,3 +425,11 @@ echo -n '*** Please use a different binutils version.' ; \ false ; \ fi + @if test "x${CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT}" = "xy" -a \ + "x${CONFIG_LD_IS_BFD}" = "xy" -a \ + "${CONFIG_LD_VERSION}" = "23700" ; then \ + echo -n '*** binutils 2.37 drops unused section symbols, which recordmcount ' ; \ + echo 'is unable to handle.' ; \ + echo '*** Please use a different binutils version.' ; \ + false ; \ + fi --- linux-oracle-5.4.0.orig/arch/powerpc/Makefile.postlink +++ linux-oracle-5.4.0/arch/powerpc/Makefile.postlink @@ -17,11 +17,11 @@ quiet_cmd_relocs_check = CHKREL $@ ifdef CONFIG_PPC_BOOK3S_64 cmd_relocs_check = \ - $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \ + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \ $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@" else cmd_relocs_check = \ - $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" endif # `@true` prevents complaint when there is nothing to be done --- linux-oracle-5.4.0.orig/arch/powerpc/boot/4xx.c +++ linux-oracle-5.4.0/arch/powerpc/boot/4xx.c @@ -228,7 +228,7 @@ dpath = 8; /* 64 bits */ /* get address pins (rows) */ - val = SDRAM0_READ(DDR0_42); + val = SDRAM0_READ(DDR0_42); row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT); if (row > max_row) --- linux-oracle-5.4.0.orig/arch/powerpc/boot/Makefile +++ linux-oracle-5.4.0/arch/powerpc/boot/Makefile @@ -30,6 +30,7 @@ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ + $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ $(LINUXINCLUDE) @@ -119,7 +120,7 @@ elf_util.c $(zlib-y) devtree.c stdlib.c \ oflib.c ofconsole.c cuboot.c -src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c +src-wlib-$(CONFIG_PPC_MPC52xx) += mpc52xx-psc.c src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S opal.c ifndef CONFIG_PPC64_BOOT_WRAPPER src-wlib-y += crtsavres.S --- linux-oracle-5.4.0.orig/arch/powerpc/boot/crt0.S +++ linux-oracle-5.4.0/arch/powerpc/boot/crt0.S @@ -44,9 +44,6 @@ p_pstack: .long _platform_stack_top #endif - .globl _zimage_start - /* Clang appears to require the .weak directive to be after the symbol - * is defined. See https://bugs.llvm.org/show_bug.cgi?id=38921 */ .weak _zimage_start _zimage_start: .globl _zimage_start_lib --- linux-oracle-5.4.0.orig/arch/powerpc/boot/devtree.c +++ linux-oracle-5.4.0/arch/powerpc/boot/devtree.c @@ -13,6 +13,7 @@ #include "string.h" #include "stdio.h" #include "ops.h" +#include "of.h" void dt_fixup_memory(u64 start, u64 size) { @@ -23,21 +24,25 @@ root = finddevice("/"); if (getprop(root, "#address-cells", &naddr, sizeof(naddr)) < 0) naddr = 2; + else + naddr = be32_to_cpu(naddr); if (naddr < 1 || naddr > 2) fatal("Can't cope with #address-cells == %d in /\n\r", naddr); if (getprop(root, "#size-cells", &nsize, sizeof(nsize)) < 0) nsize = 1; + else + nsize = be32_to_cpu(nsize); if (nsize < 1 || nsize > 2) fatal("Can't cope with #size-cells == %d in /\n\r", nsize); i = 0; if (naddr == 2) - memreg[i++] = start >> 32; - memreg[i++] = start & 0xffffffff; + memreg[i++] = cpu_to_be32(start >> 32); + memreg[i++] = cpu_to_be32(start & 0xffffffff); if (nsize == 2) - memreg[i++] = size >> 32; - memreg[i++] = size & 0xffffffff; + memreg[i++] = cpu_to_be32(size >> 32); + memreg[i++] = cpu_to_be32(size & 0xffffffff); memory = finddevice("/memory"); if (! memory) { @@ -45,9 +50,9 @@ setprop_str(memory, "device_type", "memory"); } - printf("Memory <- <0x%x", memreg[0]); + printf("Memory <- <0x%x", be32_to_cpu(memreg[0])); for (i = 1; i < (naddr + nsize); i++) - printf(" 0x%x", memreg[i]); + printf(" 0x%x", be32_to_cpu(memreg[i])); printf("> (%ldMB)\n\r", (unsigned long)(size >> 20)); setprop(memory, "reg", memreg, (naddr + nsize)*sizeof(u32)); @@ -65,10 +70,10 @@ printf("CPU bus-frequency <- 0x%x (%dMHz)\n\r", bus, MHZ(bus)); while ((devp = find_node_by_devtype(devp, "cpu"))) { - setprop_val(devp, "clock-frequency", cpu); - setprop_val(devp, "timebase-frequency", tb); + setprop_val(devp, "clock-frequency", cpu_to_be32(cpu)); + setprop_val(devp, "timebase-frequency", cpu_to_be32(tb)); if (bus > 0) - setprop_val(devp, "bus-frequency", bus); + setprop_val(devp, "bus-frequency", cpu_to_be32(bus)); } timebase_period_ns = 1000000000 / tb; @@ -80,7 +85,7 @@ if (devp) { printf("%s: clock-frequency <- %x (%dMHz)\n\r", path, freq, MHZ(freq)); - setprop_val(devp, "clock-frequency", freq); + setprop_val(devp, "clock-frequency", cpu_to_be32(freq)); } } @@ -133,8 +138,12 @@ { if (getprop(node, "#address-cells", naddr, 4) != 4) *naddr = 2; + else + *naddr = be32_to_cpu(*naddr); if (getprop(node, "#size-cells", nsize, 4) != 4) *nsize = 1; + else + *nsize = be32_to_cpu(*nsize); } static void copy_val(u32 *dest, u32 *src, int naddr) @@ -163,9 +172,9 @@ int i, carry = 0; for (i = MAX_ADDR_CELLS - 1; i >= MAX_ADDR_CELLS - naddr; i--) { - u64 tmp = (u64)reg[i] + add[i] + carry; + u64 tmp = (u64)be32_to_cpu(reg[i]) + be32_to_cpu(add[i]) + carry; carry = tmp >> 32; - reg[i] = (u32)tmp; + reg[i] = cpu_to_be32((u32)tmp); } return !carry; @@ -180,18 +189,18 @@ u32 end; for (i = 0; i < MAX_ADDR_CELLS; i++) { - if (reg[i] < range[i]) + if (be32_to_cpu(reg[i]) < be32_to_cpu(range[i])) return 0; - if (reg[i] > range[i]) + if (be32_to_cpu(reg[i]) > be32_to_cpu(range[i])) break; } for (i = 0; i < MAX_ADDR_CELLS; i++) { - end = range[i] + rangesize[i]; + end = be32_to_cpu(range[i]) + be32_to_cpu(rangesize[i]); - if (reg[i] < end) + if (be32_to_cpu(reg[i]) < end) break; - if (reg[i] > end) + if (be32_to_cpu(reg[i]) > end) return 0; } @@ -240,7 +249,6 @@ return 0; dt_get_reg_format(parent, &naddr, &nsize); - if (nsize > 2) return 0; @@ -252,10 +260,10 @@ copy_val(last_addr, prop_buf + offset, naddr); - ret_size = prop_buf[offset + naddr]; + ret_size = be32_to_cpu(prop_buf[offset + naddr]); if (nsize == 2) { ret_size <<= 32; - ret_size |= prop_buf[offset + naddr + 1]; + ret_size |= be32_to_cpu(prop_buf[offset + naddr + 1]); } for (;;) { @@ -278,7 +286,6 @@ offset = find_range(last_addr, prop_buf, prev_naddr, naddr, prev_nsize, buflen / 4); - if (offset < 0) return 0; @@ -296,8 +303,7 @@ if (naddr > 2) return 0; - ret_addr = ((u64)last_addr[2] << 32) | last_addr[3]; - + ret_addr = ((u64)be32_to_cpu(last_addr[2]) << 32) | be32_to_cpu(last_addr[3]); if (sizeof(void *) == 4 && (ret_addr >= 0x100000000ULL || ret_size > 0x100000000ULL || ret_addr + ret_size > 0x100000000ULL)) @@ -350,11 +356,14 @@ int dt_get_virtual_reg(void *node, void **addr, int nres) { unsigned long xaddr; - int n; + int n, i; n = getprop(node, "virtual-reg", addr, nres * 4); - if (n > 0) + if (n > 0) { + for (i = 0; i < n/4; i ++) + ((u32 *)addr)[i] = be32_to_cpu(((u32 *)addr)[i]); return n / 4; + } for (n = 0; n < nres; n++) { if (!dt_xlate_reg(node, n, &xaddr, NULL)) --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/charon.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/charon.dts @@ -35,7 +35,7 @@ }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/digsy_mtc.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/digsy_mtc.dts @@ -16,7 +16,7 @@ model = "intercontrol,digsy-mtc"; compatible = "intercontrol,digsy-mtc"; - memory { + memory@0 { reg = <0x00000000 0x02000000>; // 32MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/e500v1_power_isa.dtsi @@ -0,0 +1,51 @@ +/* + * e500v1 Power ISA Device Tree Source (include) + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/ { + cpus { + power-isa-version = "2.03"; + power-isa-b; // Base + power-isa-e; // Embedded + power-isa-atb; // Alternate Time Base + power-isa-cs; // Cache Specification + power-isa-e.le; // Embedded.Little-Endian + power-isa-e.pm; // Embedded.Performance Monitor + power-isa-ecl; // Embedded Cache Locking + power-isa-mmc; // Memory Coherence + power-isa-sp; // Signal Processing Engine + power-isa-sp.fs; // SPE.Embedded Float Scalar Single + power-isa-sp.fv; // SPE.Embedded Float Vector + mmu-type = "power-embedded"; + }; +}; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/mpc8540ads.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/mpc8540ads.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8540ADS"; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/mpc8541cds.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/mpc8541cds.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8541CDS"; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/mpc8555cds.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/mpc8555cds.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8555CDS"; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/mpc8560ads.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/mpc8560ads.dts @@ -7,7 +7,7 @@ /dts-v1/; -/include/ "e500v2_power_isa.dtsi" +/include/ "e500v1_power_isa.dtsi" / { model = "MPC8560ADS"; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -122,7 +122,15 @@ }; /include/ "pq3-i2c-0.dtsi" + i2c@3000 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-i2c-1.dtsi" + i2c@3100 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-duart-0.dtsi" /include/ "pq3-espi-0.dtsi" spi0: spi@7000 { --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -371,7 +371,23 @@ }; /include/ "qoriq-i2c-0.dtsi" + i2c@118000 { + fsl,i2c-erratum-a004447; + }; + + i2c@118100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-i2c-1.dtsi" + i2c@119000 { + fsl,i2c-erratum-a004447; + }; + + i2c@119100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-duart-0.dtsi" /include/ "qoriq-duart-1.dtsi" /include/ "qoriq-gpio-0.dtsi" --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi @@ -63,6 +63,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy0: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi @@ -60,6 +60,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy6: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi @@ -63,6 +63,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy1: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi @@ -60,6 +60,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy7: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-2.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #2 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x08: port@88000 { + cell-index = <0x8>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x88000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x28: port@a8000 { + cell-index = <0x28>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa8000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e0000 { + cell-index = <0>; + compatible = "fsl,fman-memac"; + reg = <0xe0000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; + }; + + mdio@e1000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-3.dtsi @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later +/* + * QorIQ FMan v3 10g port #3 device tree stub [ controller @ offset 0x400000 ] + * + * Copyright 2022 Sean Anderson + * Copyright 2012 - 2015 Freescale Semiconductor Inc. + */ + +fman@400000 { + fman0_rx_0x09: port@89000 { + cell-index = <0x9>; + compatible = "fsl,fman-v3-port-rx"; + reg = <0x89000 0x1000>; + fsl,fman-10g-port; + }; + + fman0_tx_0x29: port@a9000 { + cell-index = <0x29>; + compatible = "fsl,fman-v3-port-tx"; + reg = <0xa9000 0x1000>; + fsl,fman-10g-port; + }; + + ethernet@e2000 { + cell-index = <1>; + compatible = "fsl,fman-memac"; + reg = <0xe2000 0x1000>; + fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; + ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; + }; + + mdio@e3000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; + reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; + }; +}; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy0: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy1: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe5000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy2: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe7000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy3: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe9000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy4: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xeb000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy5: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi @@ -60,6 +60,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy14: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi @@ -60,6 +60,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy15: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy8: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy9: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe5000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy10: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe7000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy11: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe9000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy12: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi @@ -59,6 +59,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xeb000 0x1000>; + fsl,erratum-a011043; /* must ignore read errors */ pcsphy13: ethernet-phy@0 { reg = <0x0>; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi @@ -79,6 +79,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xfc000 0x1000>; + fsl,erratum-a009885; }; xmdio0: mdio@fd000 { @@ -86,6 +87,7 @@ #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xfd000 0x1000>; + fsl,erratum-a009885; }; }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/t1023rdb.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/t1023rdb.dts @@ -154,7 +154,7 @@ fm1mac3: ethernet@e4000 { phy-handle = <&sgmii_aqr_phy3>; - phy-connection-type = "sgmii-2500"; + phy-connection-type = "2500base-x"; sleep = <&rcpm 0x20000000>; }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi @@ -139,12 +139,12 @@ fman@400000 { ethernet@e6000 { phy-handle = <&phy_rgmii_0>; - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; }; ethernet@e8000 { phy-handle = <&phy_rgmii_1>; - phy-connection-type = "rgmii"; + phy-connection-type = "rgmii-id"; }; mdio0: mdio@fc000 { --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi @@ -609,8 +609,8 @@ /include/ "qoriq-bman1.dtsi" /include/ "qoriq-fman3-0.dtsi" -/include/ "qoriq-fman3-0-1g-0.dtsi" -/include/ "qoriq-fman3-0-1g-1.dtsi" +/include/ "qoriq-fman3-0-10g-2.dtsi" +/include/ "qoriq-fman3-0-10g-3.dtsi" /include/ "qoriq-fman3-0-1g-2.dtsi" /include/ "qoriq-fman3-0-1g-3.dtsi" /include/ "qoriq-fman3-0-1g-4.dtsi" @@ -659,3 +659,19 @@ interrupts = <16 2 1 9>; }; }; + +&fman0_rx_0x08 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_tx_0x28 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_rx_0x09 { + /delete-property/ fsl,fman-10g-port; +}; + +&fman0_tx_0x29 { + /delete-property/ fsl,fman-10g-port; +}; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/lite5200.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/lite5200.dts @@ -32,7 +32,7 @@ }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/lite5200b.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/lite5200b.dts @@ -31,7 +31,7 @@ led4 { gpios = <&gpio_simple 2 1>; }; }; - memory { + memory@0 { reg = <0x00000000 0x10000000>; // 256MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/media5200.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/media5200.dts @@ -32,7 +32,7 @@ }; }; - memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB RAM }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/mpc5200b.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/mpc5200b.dtsi @@ -33,7 +33,7 @@ }; }; - memory: memory { + memory: memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/o2d.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/o2d.dts @@ -12,7 +12,7 @@ model = "ifm,o2d"; compatible = "ifm,o2d"; - memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/o2d.dtsi +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/o2d.dtsi @@ -19,7 +19,7 @@ model = "ifm,o2d"; compatible = "ifm,o2d"; - memory { + memory@0 { reg = <0x00000000 0x04000000>; // 64MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/o2dnt2.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/o2dnt2.dts @@ -12,7 +12,7 @@ model = "ifm,o2dnt2"; compatible = "ifm,o2d"; - memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/o3dnt.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/o3dnt.dts @@ -12,7 +12,7 @@ model = "ifm,o3dnt"; compatible = "ifm,o2d"; - memory { + memory@0 { reg = <0x00000000 0x04000000>; // 64MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/pcm032.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/pcm032.dts @@ -22,7 +22,7 @@ model = "phytec,pcm032"; compatible = "phytec,pcm032"; - memory { + memory@0 { reg = <0x00000000 0x08000000>; // 128MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/dts/tqm5200.dts +++ linux-oracle-5.4.0/arch/powerpc/boot/dts/tqm5200.dts @@ -32,7 +32,7 @@ }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; // 64MB }; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/libfdt_env.h +++ linux-oracle-5.4.0/arch/powerpc/boot/libfdt_env.h @@ -6,6 +6,8 @@ #include #define INT_MAX ((int)(~0U>>1)) +#define UINT32_MAX ((u32)~0U) +#define INT32_MAX ((s32)(UINT32_MAX >> 1)) #include "of.h" --- linux-oracle-5.4.0.orig/arch/powerpc/boot/ns16550.c +++ linux-oracle-5.4.0/arch/powerpc/boot/ns16550.c @@ -15,6 +15,7 @@ #include "stdio.h" #include "io.h" #include "ops.h" +#include "of.h" #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ @@ -58,16 +59,20 @@ int n; u32 reg_offset; - if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) + if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) { + printf("virt reg parse fail...\r\n"); return -1; + } n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); if (n == sizeof(reg_offset)) - reg_base += reg_offset; + reg_base += be32_to_cpu(reg_offset); n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); if (n != sizeof(reg_shift)) reg_shift = 0; + else + reg_shift = be32_to_cpu(reg_shift); scdp->open = ns16550_open; scdp->putc = ns16550_putc; --- linux-oracle-5.4.0.orig/arch/powerpc/boot/serial.c +++ linux-oracle-5.4.0/arch/powerpc/boot/serial.c @@ -128,7 +128,7 @@ dt_is_compatible(devp, "fsl,cpm2-smc-uart")) rc = cpm_console_init(devp, &serial_cd); #endif -#ifdef CONFIG_PPC_MPC52XX +#ifdef CONFIG_PPC_MPC52xx else if (dt_is_compatible(devp, "fsl,mpc5200-psc-uart")) rc = mpc5200_psc_console_init(devp, &serial_cd); #endif --- linux-oracle-5.4.0.orig/arch/powerpc/boot/simple_alloc.c +++ linux-oracle-5.4.0/arch/powerpc/boot/simple_alloc.c @@ -114,8 +114,11 @@ return ptr; new = simple_malloc(size); - memcpy(new, ptr, p->size); - simple_free(ptr); + if (new) { + memcpy(new, ptr, p->size); + simple_free(ptr); + } + return new; } --- linux-oracle-5.4.0.orig/arch/powerpc/configs/85xx-hw.config +++ linux-oracle-5.4.0/arch/powerpc/configs/85xx-hw.config @@ -2,7 +2,6 @@ CONFIG_AT803X_PHY=y CONFIG_ATA=y CONFIG_BLK_DEV_SD=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_BLK_DEV_SR=y CONFIG_BROADCOM_PHY=y CONFIG_C293_PCIE=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/amigaone_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/amigaone_defconfig @@ -47,7 +47,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SYM53C8XX_2=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/chrp32_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/chrp32_defconfig @@ -45,7 +45,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SYM53C8XX_2=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/g5_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/g5_defconfig @@ -62,7 +62,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/maple_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/maple_defconfig @@ -41,7 +41,6 @@ # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_IPR=y CONFIG_ATA=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/mpc885_ads_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/mpc885_ads_defconfig @@ -39,6 +39,7 @@ # CONFIG_MTD_CFI_I2 is not set CONFIG_MTD_CFI_I4=y CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_OF=y # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/pasemi_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/pasemi_defconfig @@ -60,7 +60,6 @@ CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=y CONFIG_SCSI_CONSTANTS=y @@ -110,7 +109,6 @@ CONFIG_FB_NVIDIA_I2C=y CONFIG_FB_RADEON=y # CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/pmac32_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/pmac32_defconfig @@ -119,7 +119,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/powernv_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/powernv_defconfig @@ -111,7 +111,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/ppc64_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/ppc64_defconfig @@ -110,7 +110,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/ppc64e_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/ppc64e_defconfig @@ -60,7 +60,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/ppc6xx_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/ppc6xx_defconfig @@ -253,8 +253,6 @@ CONFIG_ATM_BR2684=m CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m -CONFIG_DECNET=m -CONFIG_DECNET_ROUTER=y CONFIG_IPX=m CONFIG_ATALK=m CONFIG_DEV_APPLETALK=m @@ -372,7 +370,6 @@ CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_OSST=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=m CONFIG_SCSI_ENCLOSURE=m @@ -778,7 +775,6 @@ CONFIG_FB_SM501=m CONFIG_FB_IBM_GXT4500=y CONFIG_LCD_PLATFORM=m -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/pseries_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/pseries_defconfig @@ -97,7 +97,6 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=m CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_FC_ATTRS=y --- linux-oracle-5.4.0.orig/arch/powerpc/configs/skiroot_defconfig +++ linux-oracle-5.4.0/arch/powerpc/configs/skiroot_defconfig @@ -83,7 +83,6 @@ # CONFIG_OCXL is not set CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SCAN_ASYNC=y --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/archrandom.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/archrandom.h @@ -6,44 +6,35 @@ #include -static inline int arch_get_random_long(unsigned long *v) +static inline bool arch_get_random_long(unsigned long *v) { - return 0; + return false; } -static inline int arch_get_random_int(unsigned int *v) +static inline bool arch_get_random_int(unsigned int *v) { - return 0; + return false; } -static inline int arch_get_random_seed_long(unsigned long *v) +static inline bool arch_get_random_seed_long(unsigned long *v) { if (ppc_md.get_random_seed) return ppc_md.get_random_seed(v); - return 0; + return false; } -static inline int arch_get_random_seed_int(unsigned int *v) + +static inline bool arch_get_random_seed_int(unsigned int *v) { unsigned long val; - int rc; + bool rc; - rc = arch_get_random_long(&val); + rc = arch_get_random_seed_long(&val); if (rc) *v = val; return rc; } - -static inline int arch_has_random(void) -{ - return 0; -} - -static inline int arch_has_random_seed(void) -{ - return !!ppc_md.get_random_seed; -} #endif /* CONFIG_ARCH_RANDOM */ #ifdef CONFIG_PPC_POWERNV --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/asm-prototypes.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/asm-prototypes.h @@ -152,9 +152,12 @@ /* Patch sites */ extern s32 patch__call_flush_count_cache; extern s32 patch__flush_count_cache_return; +extern s32 patch__flush_link_stack_return; +extern s32 patch__call_kvm_flush_link_stack; extern s32 patch__memset_nocache, patch__memcpy_nocache; extern long flush_count_cache; +extern long kvm_flush_link_stack; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM void kvmppc_save_tm_hv(struct kvm_vcpu *vcpu, u64 msr, bool preserve_nv); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/barrier.h @@ -44,6 +44,8 @@ # define SMPWMB eieio #endif +/* clang defines this macro for a builtin, which will not work with runtime patching */ +#undef __lwsync #define __lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory") #define dma_rmb() __lwsync() #define dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/bitops.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/bitops.h @@ -217,15 +217,34 @@ */ static __inline__ int fls(unsigned int x) { - return 32 - __builtin_clz(x); + int lz; + + if (__builtin_constant_p(x)) + return x ? 32 - __builtin_clz(x) : 0; + asm("cntlzw %0,%1" : "=r" (lz) : "r" (x)); + return 32 - lz; } #include +/* + * 64-bit can do this using one cntlzd (count leading zeroes doubleword) + * instruction; for 32-bit we use the generic version, which does two + * 32-bit fls calls. + */ +#ifdef CONFIG_PPC64 static __inline__ int fls64(__u64 x) { - return 64 - __builtin_clzll(x); + int lz; + + if (__builtin_constant_p(x)) + return x ? 64 - __builtin_clzll(x) : 0; + asm("cntlzd %0,%1" : "=r" (lz) : "r" (x)); + return 64 - lz; } +#else +#include +#endif #ifdef CONFIG_PPC64 unsigned int __arch_hweight8(unsigned int w); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/32/kup.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/32/kup.h @@ -2,6 +2,7 @@ #ifndef _ASM_POWERPC_BOOK3S_32_KUP_H #define _ASM_POWERPC_BOOK3S_32_KUP_H +#include #include #ifdef __ASSEMBLY__ @@ -75,7 +76,7 @@ .macro kuap_check current, gpr #ifdef CONFIG_PPC_KUAP_DEBUG - lwz \gpr2, KUAP(thread) + lwz \gpr, THREAD + KUAP(\current) 999: twnei \gpr, 0 EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE) #endif @@ -102,11 +103,13 @@ isync(); /* Context sync required after mtsrin() */ } -static inline void allow_user_access(void __user *to, const void __user *from, u32 size) +static __always_inline void allow_user_access(void __user *to, const void __user *from, + u32 size, unsigned long dir) { u32 addr, end; - if (__builtin_constant_p(to) && to == NULL) + BUILD_BUG_ON(!__builtin_constant_p(dir)); + if (!(dir & KUAP_WRITE)) return; addr = (__force u32)to; @@ -119,11 +122,16 @@ kuap_update_sr(mfsrin(addr) & ~SR_KS, addr, end); /* Clear Ks */ } -static inline void prevent_user_access(void __user *to, const void __user *from, u32 size) +static __always_inline void prevent_user_access(void __user *to, const void __user *from, + u32 size, unsigned long dir) { u32 addr = (__force u32)to; u32 end = min(addr + size, TASK_SIZE); + BUILD_BUG_ON(!__builtin_constant_p(dir)); + if (!(dir & KUAP_WRITE)) + return; + if (!addr || addr >= TASK_SIZE || !size) return; @@ -131,12 +139,17 @@ kuap_update_sr(mfsrin(addr) | SR_KS, addr, end); /* set Ks */ } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { + unsigned long begin = regs->kuap & 0xf0000000; + unsigned long end = regs->kuap << 28; + if (!is_write) return false; - return WARN(!regs->kuap, "Bug: write fault blocked by segment registers !"); + return WARN(address < begin || address >= end, + "Bug: write fault blocked by segment registers !"); } #endif /* CONFIG_PPC_KUAP */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/32/pgalloc.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/32/pgalloc.h @@ -49,7 +49,6 @@ #define get_hugepd_cache_index(x) (x) -#ifdef CONFIG_SMP static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) { @@ -66,13 +65,6 @@ pgtable_free(table, shift); } -#else -static inline void pgtable_free_tlb(struct mmu_gather *tlb, - void *table, int shift) -{ - pgtable_free(table, shift); -} -#endif static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, unsigned long address) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/32/pgtable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/32/pgtable.h @@ -37,8 +37,10 @@ */ #ifdef CONFIG_PTE_64BIT #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) +#define MAX_POSSIBLE_PHYSMEM_BITS 36 #else #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) +#define MAX_POSSIBLE_PHYSMEM_BITS 32 #endif /* @@ -555,9 +557,9 @@ if (pte_val(*ptep) & _PAGE_HASHPTE) flush_hash_entry(mm, ptep, addr); __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ + stw%X0 %2,%0\n\ eieio\n\ - stw%U0%X0 %L2,%1" + stw%X1 %L2,%1" : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -13,20 +13,19 @@ */ #define MAX_EA_BITS_PER_CONTEXT 46 -#define REGION_SHIFT (MAX_EA_BITS_PER_CONTEXT - 2) /* - * Our page table limit us to 64TB. Hence for the kernel mapping, - * each MAP area is limited to 16 TB. - * The four map areas are: linear mapping, vmap, IO and vmemmap + * Our page table limit us to 64TB. For 64TB physical memory, we only need 64GB + * of vmemmap space. To better support sparse memory layout, we use 61TB + * linear map range, 1TB of vmalloc, 1TB of I/O and 1TB of vmememmap. */ +#define REGION_SHIFT (40) #define H_KERN_MAP_SIZE (ASM_CONST(1) << REGION_SHIFT) /* - * Define the address range of the kernel non-linear virtual area - * 16TB + * Define the address range of the kernel non-linear virtual area (61TB) */ -#define H_KERN_VIRT_START ASM_CONST(0xc000100000000000) +#define H_KERN_VIRT_START ASM_CONST(0xc0003d0000000000) #ifndef __ASSEMBLY__ #define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE) @@ -85,6 +84,34 @@ #endif /* + * With 4K page size the real_pte machinery is all nops. + */ +static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset) +{ + return (real_pte_t){pte}; +} + +#define __rpte_to_pte(r) ((r).pte) + +static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index) +{ + return pte_val(__rpte_to_pte(rpte)) >> H_PAGE_F_GIX_SHIFT; +} + +#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ + do { \ + index = 0; \ + shift = mmu_psize_defs[psize].shift; \ + +#define pte_iterate_hashed_end() } while(0) + +/* + * We expect this to be called only for user addresses or kernel virtual + * addresses other than the linear mapping. + */ +#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K + +/* * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just * a matter of returning the PTE bits that need to be modified. On 64K PTE, * things are a little more involved and hence needs many more parameters to @@ -156,6 +183,12 @@ extern int hash__has_transparent_hugepage(void); #endif +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd) +{ + BUG(); + return pmd; +} + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -246,7 +246,7 @@ */ static inline int hash__pmd_trans_huge(pmd_t pmd) { - return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE)) == + return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)) == (_PAGE_PTE | H_PAGE_THP_HUGE)); } @@ -272,6 +272,12 @@ unsigned long addr, pmd_t *pmdp); extern int hash__has_transparent_hugepage(void); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ + +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)); +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/kup-radix.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/kup-radix.h @@ -11,13 +11,12 @@ #ifdef __ASSEMBLY__ -.macro kuap_restore_amr gpr #ifdef CONFIG_PPC_KUAP +.macro kuap_restore_amr gpr BEGIN_MMU_FTR_SECTION_NESTED(67) ld \gpr, STACK_REGS_KUAP(r1) mtspr SPRN_AMR, \gpr END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67) -#endif .endm .macro kuap_check_amr gpr1, gpr2 @@ -31,6 +30,7 @@ END_MMU_FTR_SECTION_NESTED_IFSET(MMU_FTR_RADIX_KUAP, 67) #endif .endm +#endif .macro kuap_save_amr_and_lock gpr1, gpr2, use_cr, msr_pr_cr #ifdef CONFIG_PPC_KUAP @@ -54,6 +54,10 @@ #else /* !__ASSEMBLY__ */ +#include + +DECLARE_STATIC_KEY_FALSE(uaccess_flush_key); + #ifdef CONFIG_PPC_KUAP #include @@ -77,32 +81,39 @@ isync(); } -static inline void allow_user_access(void __user *to, const void __user *from, - unsigned long size) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) +{ + return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) && + (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)), + "Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read"); +} +#else /* CONFIG_PPC_KUAP */ +static inline void kuap_restore_amr(struct pt_regs *regs, unsigned long amr) { } +static inline void set_kuap(unsigned long value) { } +#endif /* !CONFIG_PPC_KUAP */ + +static __always_inline void allow_user_access(void __user *to, const void __user *from, + unsigned long size, unsigned long dir) { // This is written so we can resolve to a single case at build time - if (__builtin_constant_p(to) && to == NULL) + BUILD_BUG_ON(!__builtin_constant_p(dir)); + if (dir == KUAP_READ) set_kuap(AMR_KUAP_BLOCK_WRITE); - else if (__builtin_constant_p(from) && from == NULL) + else if (dir == KUAP_WRITE) set_kuap(AMR_KUAP_BLOCK_READ); else set_kuap(0); } static inline void prevent_user_access(void __user *to, const void __user *from, - unsigned long size) + unsigned long size, unsigned long dir) { set_kuap(AMR_KUAP_BLOCKED); + if (static_branch_unlikely(&uaccess_flush_key)) + do_uaccess_flush(); } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) -{ - return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) && - (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)), - "Bug: %s fault blocked by AMR!", is_write ? "Write" : "Read"); -} -#endif /* CONFIG_PPC_KUAP */ - #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_KUP_RADIX_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/mmu-hash.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -600,8 +600,11 @@ * */ #define MAX_USER_CONTEXT ((ASM_CONST(1) << CONTEXT_BITS) - 2) + +// The + 2 accounts for INVALID_REGION and 1 more to avoid overlap with kernel #define MIN_USER_CONTEXT (MAX_KERNEL_CTX_CNT + MAX_VMALLOC_CTX_CNT + \ - MAX_IO_CTX_CNT + MAX_VMEMMAP_CTX_CNT) + MAX_IO_CTX_CNT + MAX_VMEMMAP_CTX_CNT + 2) + /* * For platforms that support on 65bit VA we limit the context bits */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/mmu.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/mmu.h @@ -225,14 +225,14 @@ extern void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size); -extern void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size); static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base, phys_addr_t first_memblock_size) { - if (early_radix_enabled()) - return radix__setup_initial_memory_limit(first_memblock_base, - first_memblock_size); + /* + * Hash has more strict restrictions. At this point we don't + * know which translations we will pick. Hence go with hash + * restrictions. + */ return hash__setup_initial_memory_limit(first_memblock_base, first_memblock_size); } --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/pgalloc.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/pgalloc.h @@ -19,9 +19,7 @@ extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long); extern void pmd_fragment_free(unsigned long *); extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); -#ifdef CONFIG_SMP extern void __tlb_remove_table(void *_table); -#endif void pte_frag_destroy(void *pte_frag); static inline pgd_t *radix__pgd_alloc(struct mm_struct *mm) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/pgtable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -324,32 +324,6 @@ #ifndef __ASSEMBLY__ -/* - * This is the default implementation of various PTE accessors, it's - * used in all cases except Book3S with 64K pages where we have a - * concept of sub-pages - */ -#ifndef __real_pte - -#define __real_pte(e, p, o) ((real_pte_t){(e)}) -#define __rpte_to_pte(r) ((r).pte) -#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT) - -#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ - do { \ - index = 0; \ - shift = mmu_psize_defs[psize].shift; \ - -#define pte_iterate_hashed_end() } while(0) - -/* - * We expect this to be called only for user addresses or kernel virtual - * addresses other than the linear mapping. - */ -#define pte_pagesize_index(mm, addr, pte) MMU_PAGE_4K - -#endif /* __real_pte */ - static inline unsigned long pte_update(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long clr, unsigned long set, int huge) @@ -998,10 +972,25 @@ #define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS) #define pgd_page_vaddr(pgd) __va(pgd_val(pgd) & ~PGD_MASKED_BITS) -#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) -#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1)) -#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) -#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) +static inline unsigned long pgd_index(unsigned long address) +{ + return (address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1); +} + +static inline unsigned long pud_index(unsigned long address) +{ + return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1); +} + +static inline unsigned long pmd_index(unsigned long address) +{ + return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); +} + +static inline unsigned long pte_index(unsigned long address) +{ + return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); +} /* * Find an entry in a page-table-directory. We combine the address region @@ -1303,7 +1292,9 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd) { - return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); + if (radix_enabled()) + return radix__pmd_mkdevmap(pmd); + return hash__pmd_mkdevmap(pmd); } static inline int pmd_devmap(pmd_t pmd) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/book3s/64/radix.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/book3s/64/radix.h @@ -206,8 +206,10 @@ * from ptesync, it should probably go into update_mmu_cache, rather * than set_pte_at (which is used to set ptes unrelated to faults). * - * Spurious faults to vmalloc region are not tolerated, so there is - * a ptesync in flush_cache_vmap. + * Spurious faults from the kernel memory are not tolerated, so there + * is a ptesync in flush_cache_vmap, and __map_kernel_page() follows + * the pte update sequence from ISA Book III 6.10 Translation Table + * Update Synchronization Requirements. */ } @@ -263,6 +265,11 @@ } #endif +static inline pmd_t radix__pmd_mkdevmap(pmd_t pmd) +{ + return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP)); +} + extern int __meminit radix__vmemmap_create_mapping(unsigned long start, unsigned long page_size, unsigned long phys); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/bpf_perf_event.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/bpf_perf_event.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_BPF_PERF_EVENT_H +#define _ASM_POWERPC_BPF_PERF_EVENT_H + +#include + +typedef struct user_pt_regs bpf_user_pt_regs_t; + +#endif /* _ASM_POWERPC_BPF_PERF_EVENT_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cache.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cache.h @@ -55,42 +55,48 @@ extern struct ppc64_caches ppc64_caches; -static inline u32 l1_cache_shift(void) +static inline u32 l1_dcache_shift(void) { return ppc64_caches.l1d.log_block_size; } -static inline u32 l1_cache_bytes(void) +static inline u32 l1_dcache_bytes(void) { return ppc64_caches.l1d.block_size; } + +static inline u32 l1_icache_shift(void) +{ + return ppc64_caches.l1i.log_block_size; +} + +static inline u32 l1_icache_bytes(void) +{ + return ppc64_caches.l1i.block_size; +} #else -static inline u32 l1_cache_shift(void) +static inline u32 l1_dcache_shift(void) { return L1_CACHE_SHIFT; } -static inline u32 l1_cache_bytes(void) +static inline u32 l1_dcache_bytes(void) { return L1_CACHE_BYTES; } -#endif -#endif /* ! __ASSEMBLY__ */ -#if defined(__ASSEMBLY__) -/* - * For a snooping icache, we still need a dummy icbi to purge all the - * prefetched instructions from the ifetch buffers. We also need a sync - * before the icbi to order the the actual stores to memory that might - * have modified instructions with the icbi. - */ -#define PURGE_PREFETCHED_INS \ - sync; \ - icbi 0,r3; \ - sync; \ - isync +static inline u32 l1_icache_shift(void) +{ + return L1_CACHE_SHIFT; +} + +static inline u32 l1_icache_bytes(void) +{ + return L1_CACHE_BYTES; +} + +#endif -#else #define __read_mostly __attribute__((__section__(".data..read_mostly"))) #ifdef CONFIG_PPC_BOOK3S_32 @@ -124,6 +130,17 @@ { __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); } + +static inline void icbi(void *addr) +{ + asm volatile ("icbi 0, %0" : : "r"(addr) : "memory"); +} + +static inline void iccci(void *addr) +{ + asm volatile ("iccci 0, %0" : : "r"(addr) : "memory"); +} + #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_CACHE_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cacheflush.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cacheflush.h @@ -42,29 +42,25 @@ #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void flush_icache_range(unsigned long, unsigned long); +void flush_icache_range(unsigned long start, unsigned long stop); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len); -extern void __flush_dcache_icache(void *page_va); extern void flush_dcache_icache_page(struct page *page); -#if defined(CONFIG_PPC32) && !defined(CONFIG_BOOKE) -extern void __flush_dcache_icache_phys(unsigned long physaddr); -#else -static inline void __flush_dcache_icache_phys(unsigned long physaddr) -{ - BUG(); -} -#endif +void __flush_dcache_icache(void *page); -/* - * Write any modified data cache blocks out to memory and invalidate them. - * Does not invalidate the corresponding instruction cache blocks. +/** + * flush_dcache_range(): Write any modified data cache blocks out to memory and + * invalidate them. Does not invalidate the corresponding instruction cache + * blocks. + * + * @start: the start address + * @stop: the stop address (exclusive) */ static inline void flush_dcache_range(unsigned long start, unsigned long stop) { - unsigned long shift = l1_cache_shift(); - unsigned long bytes = l1_cache_bytes(); + unsigned long shift = l1_dcache_shift(); + unsigned long bytes = l1_dcache_bytes(); void *addr = (void *)(start & ~(bytes - 1)); unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; @@ -89,8 +85,8 @@ */ static inline void clean_dcache_range(unsigned long start, unsigned long stop) { - unsigned long shift = l1_cache_shift(); - unsigned long bytes = l1_cache_bytes(); + unsigned long shift = l1_dcache_shift(); + unsigned long bytes = l1_dcache_bytes(); void *addr = (void *)(start & ~(bytes - 1)); unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; @@ -108,8 +104,8 @@ static inline void invalidate_dcache_range(unsigned long start, unsigned long stop) { - unsigned long shift = l1_cache_shift(); - unsigned long bytes = l1_cache_bytes(); + unsigned long shift = l1_dcache_shift(); + unsigned long bytes = l1_dcache_bytes(); void *addr = (void *)(start & ~(bytes - 1)); unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/code-patching.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/code-patching.h @@ -22,6 +22,7 @@ #define BRANCH_ABSOLUTE 0x2 bool is_offset_in_branch_range(long offset); +bool is_offset_in_cond_branch_range(long offset); unsigned int create_branch(const unsigned int *addr, unsigned long target, int flags); unsigned int create_cond_branch(const unsigned int *addr, @@ -72,7 +73,7 @@ #endif #define OP_RT_RA_MASK 0xffff0000UL -#define LIS_R2 0x3c020000UL +#define LIS_R2 0x3c400000UL #define ADDIS_R2_R12 0x3c4c0000UL #define ADDI_R2_R2 0x38420000UL --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cpm1.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cpm1.h @@ -68,6 +68,7 @@ #define PROFF_SPI ((uint)0x0180) #define PROFF_SCC3 ((uint)0x0200) #define PROFF_SMC1 ((uint)0x0280) +#define PROFF_DSP1 ((uint)0x02c0) #define PROFF_SCC4 ((uint)0x0300) #define PROFF_SMC2 ((uint)0x0380) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cpu_has_feature.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cpu_has_feature.h @@ -7,7 +7,7 @@ #include #include -static inline bool early_cpu_has_feature(unsigned long feature) +static __always_inline bool early_cpu_has_feature(unsigned long feature) { return !!((CPU_FTRS_ALWAYS & feature) || (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); @@ -46,7 +46,7 @@ return static_branch_likely(&cpu_feature_keys[i]); } #else -static inline bool cpu_has_feature(unsigned long feature) +static __always_inline bool cpu_has_feature(unsigned long feature) { return early_cpu_has_feature(feature); } --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cputable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cputable.h @@ -367,7 +367,7 @@ CPU_FTR_PPC_LE | CPU_FTR_NEED_PAIRED_STWCX) #define CPU_FTRS_82XX (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_NOEXECUTE) #define CPU_FTRS_G2_LE (CPU_FTR_COMMON | CPU_FTR_MAYBE_CAN_DOZE | \ - CPU_FTR_MAYBE_CAN_NAP) + CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_NOEXECUTE) #define CPU_FTRS_E300 (CPU_FTR_MAYBE_CAN_DOZE | \ CPU_FTR_MAYBE_CAN_NAP | \ CPU_FTR_COMMON | CPU_FTR_NOEXECUTE) @@ -407,7 +407,6 @@ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \ CPU_FTR_CELL_TB_BUG | CPU_FTR_SMT) -#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) /* 64-bit CPUs */ #define CPU_FTRS_PPC970 (CPU_FTR_LWSYNC | \ @@ -507,8 +506,6 @@ CPU_FTRS_7447 | CPU_FTRS_7447A | CPU_FTRS_82XX | CPU_FTRS_G2_LE | CPU_FTRS_E300 | CPU_FTRS_E300C2 | CPU_FTRS_CLASSIC32 | -#else - CPU_FTRS_GENERIC_32 | #endif #ifdef CONFIG_PPC_8xx CPU_FTRS_8XX | @@ -585,8 +582,6 @@ CPU_FTRS_7447 & CPU_FTRS_7447A & CPU_FTRS_82XX & CPU_FTRS_G2_LE & CPU_FTRS_E300 & CPU_FTRS_E300C2 & CPU_FTRS_CLASSIC32 & -#else - CPU_FTRS_GENERIC_32 & #endif #ifdef CONFIG_PPC_8xx CPU_FTRS_8XX & --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/cputhreads.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/cputhreads.h @@ -3,6 +3,7 @@ #define _ASM_POWERPC_CPUTHREADS_H #ifndef __ASSEMBLY__ +#include #include #include @@ -99,6 +100,36 @@ return cpu | (threads_per_core - 1); } +/* + * tlb_thread_siblings are siblings which share a TLB. This is not + * architected, is not something a hypervisor could emulate and a future + * CPU may change behaviour even in compat mode, so this should only be + * used on PowerNV, and only with care. + */ +static inline int cpu_first_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu & ~0x6; /* Big Core */ + else + return cpu_first_thread_sibling(cpu); +} + +static inline int cpu_last_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu | 0x6; /* Big Core */ + else + return cpu_last_thread_sibling(cpu); +} + +static inline int cpu_tlb_thread_sibling_step(void) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return 2; /* Big Core */ + else + return 1; +} + static inline u32 get_tensr(void) { #ifdef CONFIG_BOOKE --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/dcr-native.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/dcr-native.h @@ -53,8 +53,8 @@ #define mfdcr(rn) \ ({unsigned int rval; \ if (__builtin_constant_p(rn) && rn < 1024) \ - asm volatile("mfdcr %0," __stringify(rn) \ - : "=r" (rval)); \ + asm volatile("mfdcr %0, %1" : "=r" (rval) \ + : "n" (rn)); \ else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \ rval = mfdcrx(rn); \ else \ @@ -64,8 +64,8 @@ #define mtdcr(rn, v) \ do { \ if (__builtin_constant_p(rn) && rn < 1024) \ - asm volatile("mtdcr " __stringify(rn) ",%0" \ - : : "r" (v)); \ + asm volatile("mtdcr %0, %1" \ + : : "n" (rn), "r" (v)); \ else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR))) \ mtdcrx(rn, v); \ else \ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/drmem.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/drmem.h @@ -8,31 +8,44 @@ #ifndef _ASM_POWERPC_LMB_H #define _ASM_POWERPC_LMB_H +#include + struct drmem_lmb { u64 base_addr; u32 drc_index; u32 aa_index; u32 flags; -#ifdef CONFIG_MEMORY_HOTPLUG - int nid; -#endif }; struct drmem_lmb_info { struct drmem_lmb *lmbs; int n_lmbs; - u32 lmb_size; + u64 lmb_size; }; extern struct drmem_lmb_info *drmem_info; +static inline struct drmem_lmb *drmem_lmb_next(struct drmem_lmb *lmb, + const struct drmem_lmb *start) +{ + /* + * DLPAR code paths can take several milliseconds per element + * when interacting with firmware. Ensure that we don't + * unfairly monopolize the CPU. + */ + if (((++lmb - start) % 16) == 0) + cond_resched(); + + return lmb; +} + #define for_each_drmem_lmb_in_range(lmb, start, end) \ - for ((lmb) = (start); (lmb) <= (end); (lmb)++) + for ((lmb) = (start); (lmb) < (end); lmb = drmem_lmb_next(lmb, start)) #define for_each_drmem_lmb(lmb) \ for_each_drmem_lmb_in_range((lmb), \ &drmem_info->lmbs[0], \ - &drmem_info->lmbs[drmem_info->n_lmbs - 1]) + &drmem_info->lmbs[drmem_info->n_lmbs]) /* * The of_drconf_cell_v1 struct defines the layout of the LMB data @@ -66,7 +79,7 @@ #define DRCONF_MEM_AI_INVALID 0x00000040 #define DRCONF_MEM_RESERVED 0x00000080 -static inline u32 drmem_lmb_size(void) +static inline u64 drmem_lmb_size(void) { return drmem_info->lmb_size; } @@ -103,22 +116,4 @@ lmb->aa_index = 0xffffffff; } -#ifdef CONFIG_MEMORY_HOTPLUG -static inline void lmb_set_nid(struct drmem_lmb *lmb) -{ - lmb->nid = memory_add_physaddr_to_nid(lmb->base_addr); -} -static inline void lmb_clear_nid(struct drmem_lmb *lmb) -{ - lmb->nid = -1; -} -#else -static inline void lmb_set_nid(struct drmem_lmb *lmb) -{ -} -static inline void lmb_clear_nid(struct drmem_lmb *lmb) -{ -} -#endif - #endif /* _ASM_POWERPC_LMB_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/exception-64s.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/exception-64s.h @@ -61,11 +61,18 @@ nop; \ nop +#define ENTRY_FLUSH_SLOT \ + ENTRY_FLUSH_FIXUP_SECTION; \ + nop; \ + nop; \ + nop; + /* * r10 must be free to use, r13 must be paca */ #define INTERRUPT_TO_KERNEL \ - STF_ENTRY_BARRIER_SLOT + STF_ENTRY_BARRIER_SLOT; \ + ENTRY_FLUSH_SLOT /* * Macros for annotating the expected destination of (h)rfid @@ -127,6 +134,9 @@ hrfid; \ b hrfi_flush_fallback +#else /* __ASSEMBLY__ */ +/* Prototype for function defined in exceptions-64s.S */ +void do_uaccess_flush(void); #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_EXCEPTION_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/fadump-internal.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/fadump-internal.h @@ -64,12 +64,14 @@ }; /* fadump memory ranges info */ +#define RNG_NAME_SZ 16 struct fadump_mrange_info { - char name[16]; + char name[RNG_NAME_SZ]; struct fadump_memory_range *mem_ranges; u32 mem_ranges_sz; u32 mem_range_cnt; u32 max_mem_ranges; + bool is_static; }; /* Platform specific callback functions */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/feature-fixups.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/feature-fixups.h @@ -205,6 +205,22 @@ FTR_ENTRY_OFFSET 955b-956b; \ .popsection; +#define UACCESS_FLUSH_FIXUP_SECTION \ +959: \ + .pushsection __uaccess_flush_fixup,"a"; \ + .align 2; \ +960: \ + FTR_ENTRY_OFFSET 959b-960b; \ + .popsection; + +#define ENTRY_FLUSH_FIXUP_SECTION \ +957: \ + .pushsection __entry_flush_fixup,"a"; \ + .align 2; \ +958: \ + FTR_ENTRY_OFFSET 957b-958b; \ + .popsection; + #define RFI_FLUSH_FIXUP_SECTION \ 951: \ .pushsection __rfi_flush_fixup,"a"; \ @@ -237,8 +253,11 @@ #include extern long stf_barrier_fallback; +extern long entry_flush_fallback; extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup; extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup; +extern long __start___uaccess_flush_fixup, __stop___uaccess_flush_fixup; +extern long __start___entry_flush_fixup, __stop___entry_flush_fixup; extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/fixmap.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/fixmap.h @@ -77,7 +77,12 @@ static inline void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) { - map_kernel_page(fix_to_virt(idx), phys, flags); + if (__builtin_constant_p(idx)) + BUILD_BUG_ON(idx >= __end_of_fixed_addresses); + else if (WARN_ON(idx >= __end_of_fixed_addresses)) + return; + + map_kernel_page(__fix_to_virt(idx), phys, flags); } #endif /* !__ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/ftrace.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/ftrace.h @@ -96,7 +96,7 @@ #endif /* PPC64_ELF_ABI_v1 */ #endif /* CONFIG_FTRACE_SYSCALLS */ -#ifdef CONFIG_PPC64 +#if defined(CONFIG_PPC64) && defined(CONFIG_FUNCTION_TRACER) #include static inline void this_cpu_disable_ftrace(void) @@ -108,9 +108,12 @@ { get_paca()->ftrace_enabled = 1; } + +void ftrace_free_init_tramp(void); #else /* CONFIG_PPC64 */ static inline void this_cpu_disable_ftrace(void) { } static inline void this_cpu_enable_ftrace(void) { } +static inline void ftrace_free_init_tramp(void) { } #endif /* CONFIG_PPC64 */ #endif /* !__ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/futex.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/futex.h @@ -35,7 +35,7 @@ { int oldval = 0, ret; - allow_write_to_user(uaddr, sizeof(*uaddr)); + allow_read_write_user(uaddr, uaddr, sizeof(*uaddr)); pagefault_disable(); switch (op) { @@ -62,7 +62,7 @@ *oval = oldval; - prevent_write_to_user(uaddr, sizeof(*uaddr)); + prevent_read_write_user(uaddr, uaddr, sizeof(*uaddr)); return ret; } @@ -76,7 +76,8 @@ if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; - allow_write_to_user(uaddr, sizeof(*uaddr)); + allow_read_write_user(uaddr, uaddr, sizeof(*uaddr)); + __asm__ __volatile__ ( PPC_ATOMIC_ENTRY_BARRIER "1: lwarx %1,0,%3 # futex_atomic_cmpxchg_inatomic\n\ @@ -97,7 +98,8 @@ : "cc", "memory"); *uval = prev; - prevent_write_to_user(uaddr, sizeof(*uaddr)); + prevent_read_write_user(uaddr, uaddr, sizeof(*uaddr)); + return ret; } --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/hvcall.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/hvcall.h @@ -403,7 +403,7 @@ * Used for all but the craziest of phyp interfaces (see plpar_hcall9) */ #define PLPAR_HCALL_BUFSIZE 4 -long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); /** * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats @@ -417,7 +417,7 @@ * plpar_hcall, but plpar_hcall_raw works in real mode and does not * calculate hypervisor call statistics. */ -long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...); /** * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments @@ -428,8 +428,8 @@ * PLPAR_HCALL9_BUFSIZE to size the return argument buffer. */ #define PLPAR_HCALL9_BUFSIZE 9 -long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...); -long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...); +long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); +long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...); struct hvcall_mpp_data { unsigned long entitled_mem; @@ -444,7 +444,7 @@ unsigned long backing_mem; }; -int h_get_mpp(struct hvcall_mpp_data *); +long h_get_mpp(struct hvcall_mpp_data *mpp_data); struct hvcall_mpp_x_data { unsigned long coalesced_bytes; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/imc-pmu.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/imc-pmu.h @@ -132,7 +132,7 @@ * are inited. */ struct imc_pmu_ref { - struct mutex lock; + spinlock_t lock; unsigned int id; int refc; }; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/io.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/io.h @@ -46,7 +46,7 @@ * define properly based on the platform */ #ifndef CONFIG_PCI -#define _IO_BASE 0 +#define _IO_BASE POISON_POINTER_DELTA #define _ISA_MEM_BASE 0 #define PCI_DRAM_OFFSET 0 #elif defined(CONFIG_PPC32) @@ -345,25 +345,37 @@ */ static inline void __raw_rm_writeb(u8 val, volatile void __iomem *paddr) { - __asm__ __volatile__("stbcix %0,0,%1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + stbcix %0,0,%1; \ + .machine pop;" : : "r" (val), "r" (paddr) : "memory"); } static inline void __raw_rm_writew(u16 val, volatile void __iomem *paddr) { - __asm__ __volatile__("sthcix %0,0,%1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + sthcix %0,0,%1; \ + .machine pop;" : : "r" (val), "r" (paddr) : "memory"); } static inline void __raw_rm_writel(u32 val, volatile void __iomem *paddr) { - __asm__ __volatile__("stwcix %0,0,%1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + stwcix %0,0,%1; \ + .machine pop;" : : "r" (val), "r" (paddr) : "memory"); } static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr) { - __asm__ __volatile__("stdcix %0,0,%1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + stdcix %0,0,%1; \ + .machine pop;" : : "r" (val), "r" (paddr) : "memory"); } @@ -375,7 +387,10 @@ static inline u8 __raw_rm_readb(volatile void __iomem *paddr) { u8 ret; - __asm__ __volatile__("lbzcix %0,0, %1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + lbzcix %0,0, %1; \ + .machine pop;" : "=r" (ret) : "r" (paddr) : "memory"); return ret; } @@ -383,7 +398,10 @@ static inline u16 __raw_rm_readw(volatile void __iomem *paddr) { u16 ret; - __asm__ __volatile__("lhzcix %0,0, %1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + lhzcix %0,0, %1; \ + .machine pop;" : "=r" (ret) : "r" (paddr) : "memory"); return ret; } @@ -391,7 +409,10 @@ static inline u32 __raw_rm_readl(volatile void __iomem *paddr) { u32 ret; - __asm__ __volatile__("lwzcix %0,0, %1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + lwzcix %0,0, %1; \ + .machine pop;" : "=r" (ret) : "r" (paddr) : "memory"); return ret; } @@ -399,7 +420,10 @@ static inline u64 __raw_rm_readq(volatile void __iomem *paddr) { u64 ret; - __asm__ __volatile__("ldcix %0,0, %1" + __asm__ __volatile__(".machine push; \ + .machine power6; \ + ldcix %0,0, %1; \ + .machine pop;" : "=r" (ret) : "r" (paddr) : "memory"); return ret; } @@ -518,12 +542,12 @@ #define __do_inw(port) _rec_inw(port) #define __do_inl(port) _rec_inl(port) #else /* CONFIG_PPC32 */ -#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port); -#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port); -#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port); -#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port); +#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)(_IO_BASE+port)); +#define __do_inb(port) readb((PCI_IO_ADDR)(_IO_BASE + port)); +#define __do_inw(port) readw((PCI_IO_ADDR)(_IO_BASE + port)); +#define __do_inl(port) readl((PCI_IO_ADDR)(_IO_BASE + port)); #endif /* !CONFIG_PPC32 */ #ifdef CONFIG_EEH @@ -539,12 +563,12 @@ #define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n)) #define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n)) -#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) -#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) -#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) -#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) +#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n)) +#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) +#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) +#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n)) #define __do_memset_io(addr, c, n) \ _memset_io(PCI_FIX_ADDR(addr), c, n) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/kasan.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/kasan.h @@ -23,9 +23,7 @@ #define KASAN_SHADOW_OFFSET ASM_CONST(CONFIG_KASAN_SHADOW_OFFSET) -#define KASAN_SHADOW_END 0UL - -#define KASAN_SHADOW_SIZE (KASAN_SHADOW_END - KASAN_SHADOW_START) +#define KASAN_SHADOW_END (-(-KASAN_SHADOW_START >> KASAN_SHADOW_SCALE_SHIFT)) #ifdef CONFIG_KASAN void kasan_early_init(void); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/kup.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/kup.h @@ -2,7 +2,11 @@ #ifndef _ASM_POWERPC_KUP_H_ #define _ASM_POWERPC_KUP_H_ -#ifdef CONFIG_PPC64 +#define KUAP_READ 1 +#define KUAP_WRITE 2 +#define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE) + +#ifdef CONFIG_PPC_BOOK3S_64 #include #endif #ifdef CONFIG_PPC_8xx @@ -20,9 +24,15 @@ .macro kuap_restore sp, current, gpr1, gpr2, gpr3 .endm +.macro kuap_restore_amr gpr +.endm + .macro kuap_check current, gpr .endm +.macro kuap_check_amr gpr1, gpr2 +.endm + #endif #else /* !__ASSEMBLY__ */ @@ -41,33 +51,60 @@ void setup_kuap(bool disabled); #else static inline void setup_kuap(bool disabled) { } + +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) +{ + return false; +} + +static inline void kuap_check_amr(void) { } + +/* + * book3s/64/kup-radix.h defines these functions for the !KUAP case to flush + * the L1D cache after user accesses. Only include the empty stubs for other + * platforms. + */ +#ifndef CONFIG_PPC_BOOK3S_64 static inline void allow_user_access(void __user *to, const void __user *from, - unsigned long size) { } + unsigned long size, unsigned long dir) { } static inline void prevent_user_access(void __user *to, const void __user *from, - unsigned long size) { } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) { return false; } + unsigned long size, unsigned long dir) { } +#endif /* CONFIG_PPC_BOOK3S_64 */ #endif /* CONFIG_PPC_KUAP */ static inline void allow_read_from_user(const void __user *from, unsigned long size) { - allow_user_access(NULL, from, size); + allow_user_access(NULL, from, size, KUAP_READ); } static inline void allow_write_to_user(void __user *to, unsigned long size) { - allow_user_access(to, NULL, size); + allow_user_access(to, NULL, size, KUAP_WRITE); +} + +static inline void allow_read_write_user(void __user *to, const void __user *from, + unsigned long size) +{ + allow_user_access(to, from, size, KUAP_READ_WRITE); } static inline void prevent_read_from_user(const void __user *from, unsigned long size) { - prevent_user_access(NULL, from, size); + prevent_user_access(NULL, from, size, KUAP_READ); } static inline void prevent_write_to_user(void __user *to, unsigned long size) { - prevent_user_access(to, NULL, size); + prevent_user_access(to, NULL, size, KUAP_WRITE); +} + +static inline void prevent_read_write_user(void __user *to, const void __user *from, + unsigned long size) +{ + prevent_user_access(to, from, size, KUAP_READ_WRITE); } #endif /* !__ASSEMBLY__ */ -#endif /* _ASM_POWERPC_KUP_H_ */ +#endif /* _ASM_POWERPC_KUAP_H_ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/kvm_asm.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/kvm_asm.h @@ -150,4 +150,7 @@ #define KVM_INST_FETCH_FAILED -1 +/* Extract PO and XOP opcode fields */ +#define PO_XOP_OPCODE_MASK 0xfc0007fe + #endif /* __POWERPC_KVM_ASM_H__ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/kvm_host.h @@ -58,7 +58,8 @@ #define KVM_ARCH_WANT_MMU_NOTIFIER extern int kvm_unmap_hva_range(struct kvm *kvm, - unsigned long start, unsigned long end); + unsigned long start, unsigned long end, + unsigned flags); extern int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); extern int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); extern int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/machdep.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/machdep.h @@ -59,6 +59,9 @@ int (*pcibios_root_bridge_prepare)(struct pci_host_bridge *bridge); + /* finds all the pci_controllers present at boot */ + void (*discover_phbs)(void); + /* To setup PHBs when using automatic OF platform driver for PCI */ int (*pci_setup_phb)(struct pci_controller *host); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/mmu.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/mmu.h @@ -375,5 +375,9 @@ #include #endif +#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) +#define __HAVE_ARCH_RESERVED_KERNEL_PAGES +#endif + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_MMU_H_ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/mmu_context.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/mmu_context.h @@ -216,7 +216,7 @@ */ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { - switch_mm(prev, next, current); + switch_mm_irqs_off(prev, next, current); } /* We don't currently use enter_lazy_tlb() for anything */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/mmzone.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/mmzone.h @@ -42,9 +42,6 @@ #else #define memory_hotplug_max() memblock_end_of_DRAM() #endif /* CONFIG_NEED_MULTIPLE_NODES */ -#ifdef CONFIG_FA_DUMP -#define __HAVE_ARCH_RESERVED_KERNEL_PAGES -#endif #endif /* __KERNEL__ */ #endif /* _ASM_MMZONE_H_ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/32/kup-8xx.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/32/kup-8xx.h @@ -34,18 +34,19 @@ #include static inline void allow_user_access(void __user *to, const void __user *from, - unsigned long size) + unsigned long size, unsigned long dir) { mtspr(SPRN_MD_AP, MD_APG_INIT); } static inline void prevent_user_access(void __user *to, const void __user *from, - unsigned long size) + unsigned long size, unsigned long dir) { mtspr(SPRN_MD_AP, MD_APG_KUAP); } -static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) +static inline bool +bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write) { return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000), "Bug: fault blocked by AP register !"); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/32/pgtable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -148,8 +148,10 @@ */ #if defined(CONFIG_PPC32) && defined(CONFIG_PTE_64BIT) #define PTE_RPN_MASK (~((1ULL << PTE_RPN_SHIFT) - 1)) +#define MAX_POSSIBLE_PHYSMEM_BITS 36 #else #define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) +#define MAX_POSSIBLE_PHYSMEM_BITS 32 #endif /* --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/32/pte-8xx.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/32/pte-8xx.h @@ -91,6 +91,13 @@ #define pte_wrprotect pte_wrprotect +static inline int pte_read(pte_t pte) +{ + return (pte_val(pte) & _PAGE_RO) != _PAGE_NA; +} + +#define pte_read pte_read + static inline int pte_write(pte_t pte) { return !(pte_val(pte) & _PAGE_RO); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/64/pgtable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -244,7 +244,7 @@ { unsigned long old; - if (pte_young(*ptep)) + if (!pte_young(*ptep)) return 0; old = pte_update(mm, addr, ptep, _PAGE_ACCESSED, 0, 0); return (old & _PAGE_ACCESSED) != 0; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/pgalloc.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/pgalloc.h @@ -46,7 +46,6 @@ #define get_hugepd_cache_index(x) (x) -#ifdef CONFIG_SMP static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) { unsigned long pgf = (unsigned long)table; @@ -64,13 +63,6 @@ pgtable_free(table, shift); } -#else -static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift) -{ - pgtable_free(table, shift); -} -#endif - static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, unsigned long address) { --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/nohash/pgtable.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/nohash/pgtable.h @@ -45,7 +45,9 @@ return pte_val(pte) & _PAGE_RW; } #endif +#ifndef pte_read static inline int pte_read(pte_t pte) { return 1; } +#endif static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } static inline int pte_none(pte_t pte) { return (pte_val(pte) & ~_PTE_NONE_MASK) == 0; } @@ -199,9 +201,9 @@ */ if (IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_PTE_64BIT) && !percpu) { __asm__ __volatile__("\ - stw%U0%X0 %2,%0\n\ + stw%X0 %2,%0\n\ eieio\n\ - stw%U0%X0 %L2,%1" + stw%X1 %L2,%1" : "=m" (*ptep), "=m" (*((unsigned char *)ptep+4)) : "r" (pte) : "memory"); return; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/opal-api.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/opal-api.h @@ -211,7 +211,10 @@ #define OPAL_MPIPL_UPDATE 173 #define OPAL_MPIPL_REGISTER_TAG 174 #define OPAL_MPIPL_QUERY_TAG 175 -#define OPAL_LAST 175 +#define OPAL_SECVAR_GET 176 +#define OPAL_SECVAR_GET_NEXT 177 +#define OPAL_SECVAR_ENQUEUE_UPDATE 178 +#define OPAL_LAST 178 #define QUIESCE_HOLD 1 /* Spin all calls at entry */ #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/opal.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/opal.h @@ -298,6 +298,13 @@ int opal_sensor_group_enable(u32 group_hndl, int token, bool enable); int opal_nx_coproc_init(uint32_t chip_id, uint32_t ct); +int opal_secvar_get(const char *key, uint64_t key_len, u8 *data, + uint64_t *data_size); +int opal_secvar_get_next(const char *key, uint64_t *key_len, + uint64_t key_buf_size); +int opal_secvar_enqueue_update(const char *key, uint64_t key_len, u8 *data, + uint64_t data_size); + s64 opal_mpipl_update(enum opal_mpipl_ops op, u64 src, u64 dest, u64 size); s64 opal_mpipl_register_tag(enum opal_mpipl_tags tag, u64 addr); s64 opal_mpipl_query_tag(enum opal_mpipl_tags tag, u64 *addr); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/page.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/page.h @@ -132,7 +132,11 @@ #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) -#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) +#define virt_addr_valid(vaddr) ({ \ + unsigned long _addr = (unsigned long)vaddr; \ + _addr >= PAGE_OFFSET && _addr < (unsigned long)high_memory && \ + pfn_valid(virt_to_pfn(_addr)); \ +}) /* * On Book-E parts we need __va to parse the device tree and we can't @@ -212,6 +216,9 @@ #define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET) #else #ifdef CONFIG_PPC64 + +#define VIRTUAL_WARN_ON(x) WARN_ON(IS_ENABLED(CONFIG_DEBUG_VIRTUAL) && (x)) + /* * gcc miscompiles (unsigned long)(&static_var) - PAGE_OFFSET * with -mcmodel=medium, so we use & and | instead of - and + on 64-bit. @@ -219,13 +226,13 @@ */ #define __va(x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) >= PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) >= PAGE_OFFSET); \ (void *)(unsigned long)((phys_addr_t)(x) | PAGE_OFFSET); \ }) #define __pa(x) \ ({ \ - VIRTUAL_BUG_ON((unsigned long)(x) < PAGE_OFFSET); \ + VIRTUAL_WARN_ON((unsigned long)(x) < PAGE_OFFSET); \ (unsigned long)(x) & 0x0fffffffffffffffUL; \ }) @@ -295,8 +302,13 @@ /* * Some number of bits at the level of the page table that points to * a hugepte are used to encode the size. This masks those bits. + * On 8xx, HW assistance requires 4k alignment for the hugepte. */ +#ifdef CONFIG_PPC_8xx +#define HUGEPD_SHIFT_MASK 0xfff +#else #define HUGEPD_SHIFT_MASK 0x3f +#endif #ifndef __ASSEMBLY__ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/percpu.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/percpu.h @@ -10,8 +10,6 @@ #ifdef CONFIG_SMP -#include - #define __my_cpu_offset local_paca->data_offset #endif /* CONFIG_SMP */ @@ -19,4 +17,6 @@ #include +#include + #endif /* _ASM_POWERPC_PERCPU_H_ */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/perf_event.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/perf_event.h @@ -12,6 +12,8 @@ #ifdef CONFIG_PPC_PERF_CTRS #include +#else +static inline bool is_sier_available(void) { return false; } #endif #ifdef CONFIG_FSL_EMB_PERF_EVENT --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/pmc.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/pmc.h @@ -34,6 +34,13 @@ #endif } +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +static inline int ppc_get_pmu_inuse(void) +{ + return get_paca()->pmcregs_in_use; +} +#endif + extern void power4_enable_pmcs(void); #else /* CONFIG_PPC64 */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/pnv-pci.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/pnv-pci.h @@ -15,6 +15,7 @@ #define PCI_SLOT_ID_PREFIX (1UL << 63) #define PCI_SLOT_ID(phb_id, bdfn) \ (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb_id)) +#define PCI_PHB_SLOT_ID(phb_id) (phb_id) extern int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id); extern int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/ppc-opcode.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/ppc-opcode.h @@ -204,6 +204,7 @@ #define PPC_INST_ICBT 0x7c00002c #define PPC_INST_ICSWX 0x7c00032d #define PPC_INST_ICSWEPX 0x7c00076d +#define PPC_INST_DSSALL 0x7e00066c #define PPC_INST_ISEL 0x7c00001e #define PPC_INST_ISEL_MASK 0xfc00003e #define PPC_INST_LDARX 0x7c0000a8 @@ -439,6 +440,7 @@ __PPC_RA(a) | __PPC_RB(b)) #define PPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \ __PPC_RA(a) | __PPC_RB(b)) +#define PPC_DSSALL stringify_in_c(.long PPC_INST_DSSALL) #define PPC_LQARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LQARX | \ ___PPC_RT(t) | ___PPC_RA(a) | \ ___PPC_RB(b) | __PPC_EH(eh)) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/processor.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/processor.h @@ -291,7 +291,6 @@ #else #define INIT_THREAD { \ .ksp = INIT_SP, \ - .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \ .addr_limit = KERNEL_DS, \ .fpexc_mode = 0, \ .fscr = FSCR_TAR | FSCR_EBB \ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/ps3.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/ps3.h @@ -71,6 +71,7 @@ * @bus_addr: The 'translated' bus address of the region. * @len: The length in bytes of the region. * @offset: The offset from the start of memory of the region. + * @dma_mask: Device dma_mask. * @ioid: The IOID of the device who owns this region * @chunk_list: Opaque variable used by the ioc page manager. * @region_ops: struct ps3_dma_region_ops - dma region operations @@ -85,6 +86,7 @@ enum ps3_dma_region_type region_type; unsigned long len; unsigned long offset; + u64 dma_mask; /* driver variables (set by ps3_dma_region_create) */ unsigned long bus_addr; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/ptrace.h @@ -62,6 +62,9 @@ }; #endif + +#define STACK_FRAME_WITH_PT_REGS (STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)) + #ifdef __powerpc64__ /* @@ -203,7 +206,7 @@ #endif /* __powerpc64__ */ #define arch_has_single_step() (1) -#ifndef CONFIG_BOOK3S_601 +#ifndef CONFIG_PPC_BOOK3S_601 #define arch_has_block_step() (true) #else #define arch_has_block_step() (false) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/reg.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/reg.h @@ -796,7 +796,7 @@ #define THRM1_TIN (1 << 31) #define THRM1_TIV (1 << 30) #define THRM1_THRES(x) ((x&0x7f)<<23) -#define THRM3_SITV(x) ((x&0x3fff)<<1) +#define THRM3_SITV(x) ((x & 0x1fff) << 1) #define THRM1_TID (1<<2) #define THRM1_TIE (1<<1) #define THRM1_V (1<<0) --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/reg_fsl_emb.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/reg_fsl_emb.h @@ -12,9 +12,16 @@ #ifndef __ASSEMBLY__ /* Performance Monitor Registers */ #define mfpmr(rn) ({unsigned int rval; \ - asm volatile("mfpmr %0," __stringify(rn) \ + asm volatile(".machine push; " \ + ".machine e300; " \ + "mfpmr %0," __stringify(rn) ";" \ + ".machine pop; " \ : "=r" (rval)); rval;}) -#define mtpmr(rn, v) asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v)) +#define mtpmr(rn, v) asm volatile(".machine push; " \ + ".machine e300; " \ + "mtpmr " __stringify(rn) ",%0; " \ + ".machine pop; " \ + : : "r" (v)) #endif /* __ASSEMBLY__ */ /* Freescale Book E Performance Monitor APU Registers */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/rtas.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/rtas.h @@ -368,8 +368,6 @@ extern void rtas_progress(char *s, unsigned short hex); extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data); extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data); -extern int rtas_online_cpus_mask(cpumask_var_t cpus); -extern int rtas_offline_cpus_mask(cpumask_var_t cpus); extern int rtas_ibm_suspend_me(u64 handle); struct rtc_time; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/sections.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/sections.h @@ -5,8 +5,22 @@ #include #include + +#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed + #include +extern bool init_mem_is_free; + +static inline int arch_is_kernel_initmem_freed(unsigned long addr) +{ + if (!init_mem_is_free) + return 0; + + return addr >= (unsigned long)__init_begin && + addr < (unsigned long)__init_end; +} + extern char __head_end[]; #ifdef __powerpc64__ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/secure_boot.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/secure_boot.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Secure boot definitions + * + * Copyright (C) 2019 IBM Corporation + * Author: Nayna Jain + */ +#ifndef _ASM_POWER_SECURE_BOOT_H +#define _ASM_POWER_SECURE_BOOT_H + +#ifdef CONFIG_PPC_SECURE_BOOT + +bool is_ppc_secureboot_enabled(void); +bool is_ppc_trustedboot_enabled(void); + +#else + +static inline bool is_ppc_secureboot_enabled(void) +{ + return false; +} + +static inline bool is_ppc_trustedboot_enabled(void) +{ + return false; +} + +#endif +#endif --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/security_features.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/security_features.h @@ -9,7 +9,7 @@ #define _ASM_POWERPC_SECURITY_FEATURES_H -extern unsigned long powerpc_security_features; +extern u64 powerpc_security_features; extern bool rfi_flush; /* These are bit flags */ @@ -24,21 +24,26 @@ void do_stf_barrier_fixups(enum stf_barrier_type types); void setup_count_cache_flush(void); -static inline void security_ftr_set(unsigned long feature) +static inline void security_ftr_set(u64 feature) { powerpc_security_features |= feature; } -static inline void security_ftr_clear(unsigned long feature) +static inline void security_ftr_clear(u64 feature) { powerpc_security_features &= ~feature; } -static inline bool security_ftr_enabled(unsigned long feature) +static inline bool security_ftr_enabled(u64 feature) { return !!(powerpc_security_features & feature); } +#ifdef CONFIG_PPC_BOOK3S_64 +enum stf_barrier_type stf_barrier_type_get(void); +#else +static inline enum stf_barrier_type stf_barrier_type_get(void) { return STF_BARRIER_NONE; } +#endif // Features indicating support for Spectre/Meltdown mitigations @@ -81,12 +86,22 @@ // Software required to flush count cache on context switch #define SEC_FTR_FLUSH_COUNT_CACHE 0x0000000000000400ull +// Software required to flush link stack on context switch +#define SEC_FTR_FLUSH_LINK_STACK 0x0000000000001000ull + +// The L1-D cache should be flushed when entering the kernel +#define SEC_FTR_L1D_FLUSH_ENTRY 0x0000000000004000ull + +// The L1-D cache should be flushed after user accesses from the kernel +#define SEC_FTR_L1D_FLUSH_UACCESS 0x0000000000008000ull // Features enabled by default #define SEC_FTR_DEFAULT \ (SEC_FTR_L1D_FLUSH_HV | \ SEC_FTR_L1D_FLUSH_PR | \ SEC_FTR_BNDS_CHK_SPEC_BAR | \ + SEC_FTR_L1D_FLUSH_ENTRY | \ + SEC_FTR_L1D_FLUSH_UACCESS | \ SEC_FTR_FAVOUR_SECURITY) #endif /* _ASM_POWERPC_SECURITY_FEATURES_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/secvar.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/secvar.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 IBM Corporation + * Author: Nayna Jain + * + * PowerPC secure variable operations. + */ +#ifndef SECVAR_OPS_H +#define SECVAR_OPS_H + +#include +#include + +extern const struct secvar_operations *secvar_ops; + +struct secvar_operations { + int (*get)(const char *key, uint64_t key_len, u8 *data, + uint64_t *data_size); + int (*get_next)(const char *key, uint64_t *key_len, + uint64_t keybufsize); + int (*set)(const char *key, uint64_t key_len, u8 *data, + uint64_t data_size); +}; + +#ifdef CONFIG_PPC_SECURE_BOOT + +extern void set_secvar_ops(const struct secvar_operations *ops); + +#else + +static inline void set_secvar_ops(const struct secvar_operations *ops) { } + +#endif + +#endif --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/setjmp.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/setjmp.h @@ -7,7 +7,9 @@ #define JMP_BUF_LEN 23 -extern long setjmp(long *) __attribute__((returns_twice)); -extern void longjmp(long *, long) __attribute__((noreturn)); +typedef long jmp_buf[JMP_BUF_LEN]; + +extern int setjmp(jmp_buf env) __attribute__((returns_twice)); +extern void longjmp(jmp_buf env, int val) __attribute__((noreturn)); #endif /* _ASM_POWERPC_SETJMP_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/setup.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/setup.h @@ -52,12 +52,16 @@ }; void setup_rfi_flush(enum l1d_flush_type, bool enable); +void setup_entry_flush(bool enable); +void setup_uaccess_flush(bool enable); void do_rfi_flush_fixups(enum l1d_flush_type types); #ifdef CONFIG_PPC_BARRIER_NOSPEC void setup_barrier_nospec(void); #else static inline void setup_barrier_nospec(void) { }; #endif +void do_uaccess_flush_fixups(enum l1d_flush_type types); +void do_entry_flush_fixups(enum l1d_flush_type types); void do_barrier_nospec_fixups(bool enable); extern bool barrier_nospec_enabled; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/spinlock.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/spinlock.h @@ -15,6 +15,7 @@ * * (the type definitions are in asm/spinlock_types.h) */ +#include #include #ifdef CONFIG_PPC64 #include @@ -36,10 +37,12 @@ #endif #ifdef CONFIG_PPC_PSERIES +DECLARE_STATIC_KEY_FALSE(shared_processor); + #define vcpu_is_preempted vcpu_is_preempted static inline bool vcpu_is_preempted(int cpu) { - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) + if (!static_branch_unlikely(&shared_processor)) return false; return !!(be32_to_cpu(lppaca_of(cpu).yield_count) & 1); } --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/sstep.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/sstep.h @@ -160,9 +160,4 @@ */ extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op); -extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, - const void *mem, bool cross_endian); -extern void emulate_vsx_store(struct instruction_op *op, - const union vsx_reg *reg, void *mem, - bool cross_endian); extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/timex.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/timex.h @@ -17,11 +17,12 @@ static inline cycles_t get_cycles(void) { - if (IS_ENABLED(CONFIG_BOOK3S_601)) + if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) return 0; return mftb(); } +#define get_cycles get_cycles #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_TIMEX_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/tlb.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/tlb.h @@ -26,6 +26,17 @@ #define tlb_flush tlb_flush extern void tlb_flush(struct mmu_gather *tlb); +/* + * book3s: + * Hash does not use the linux page-tables, so we can avoid + * the TLB invalidate for page-table freeing, Radix otoh does use the + * page-tables and needs the TLBI. + * + * nohash: + * We still do TLB invalidate in the __pte_free_tlb routine before we + * add the page table pages to mmu gather table batch. + */ +#define tlb_needs_table_invalidate() radix_enabled() /* Get the generic bits... */ #include @@ -56,19 +67,6 @@ return false; return cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)); } -static inline void mm_reset_thread_local(struct mm_struct *mm) -{ - WARN_ON(atomic_read(&mm->context.copros) > 0); - /* - * It's possible for mm_access to take a reference on mm_users to - * access the remote mm from another thread, but it's not allowed - * to set mm_cpumask, so mm_users may be > 1 here. - */ - WARN_ON(current->mm != mm); - atomic_set(&mm->context.active_cpus, 1); - cpumask_clear(mm_cpumask(mm)); - cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); -} #else /* CONFIG_PPC_BOOK3S_64 */ static inline int mm_is_thread_local(struct mm_struct *mm) { --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/uaccess.h @@ -191,8 +191,11 @@ */ #define __get_user_atomic_128_aligned(kaddr, uaddr, err) \ __asm__ __volatile__( \ + ".machine push\n" \ + ".machine altivec\n" \ "1: lvx 0,0,%1 # get user\n" \ " stvx 0,0,%2 # put kernel\n" \ + ".machine pop\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: li %0,%3\n" \ @@ -313,9 +316,9 @@ unsigned long ret; barrier_nospec(); - allow_user_access(to, from, n); + allow_read_write_user(to, from, n); ret = __copy_tofrom_user(to, from, n); - prevent_user_access(to, from, n); + prevent_read_write_user(to, from, n); return ret; } #endif /* __powerpc64__ */ @@ -401,7 +404,7 @@ return n; } -extern unsigned long __clear_user(void __user *addr, unsigned long size); +unsigned long __arch_clear_user(void __user *addr, unsigned long size); static inline unsigned long clear_user(void __user *addr, unsigned long size) { @@ -409,12 +412,17 @@ might_fault(); if (likely(access_ok(addr, size))) { allow_write_to_user(addr, size); - ret = __clear_user(addr, size); + ret = __arch_clear_user(addr, size); prevent_write_to_user(addr, size); } return ret; } +static inline unsigned long __clear_user(void __user *addr, unsigned long size) +{ + return clear_user(addr, size); +} + extern long strncpy_from_user(char *dst, const char __user *src, long count); extern __must_check long strnlen_user(const char __user *str, long n); --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/vdso.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/vdso.h @@ -49,6 +49,7 @@ #define V_FUNCTION_BEGIN(name) \ .globl name; \ + .type name,@function; \ name: \ #define V_FUNCTION_END(name) \ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/vdso_datapage.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/vdso_datapage.h @@ -82,6 +82,7 @@ __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */ __s64 wtom_clock_sec; /* Wall to monotonic clock sec */ struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ + __u32 hrtimer_res; /* hrtimer resolution */ __u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */ __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ }; @@ -103,6 +104,7 @@ __s32 wtom_clock_nsec; struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */ __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */ + __u32 hrtimer_res; /* hrtimer resolution */ __u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */ __u32 dcache_block_size; /* L1 d-cache block size */ __u32 icache_block_size; /* L1 i-cache block size */ --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/word-at-a-time.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/word-at-a-time.h @@ -34,7 +34,7 @@ return leading_zero_bits >> 3; } -static inline bool has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) +static inline unsigned long has_zero(unsigned long val, unsigned long *data, const struct word_at_a_time *c) { unsigned long rhs = val | c->low_bits; *data = rhs; --- linux-oracle-5.4.0.orig/arch/powerpc/include/asm/xive-regs.h +++ linux-oracle-5.4.0/arch/powerpc/include/asm/xive-regs.h @@ -39,6 +39,7 @@ #define XIVE_ESB_VAL_P 0x2 #define XIVE_ESB_VAL_Q 0x1 +#define XIVE_ESB_INVALID 0xFF /* * Thread Management (aka "TM") registers --- linux-oracle-5.4.0.orig/arch/powerpc/include/uapi/asm/errno.h +++ linux-oracle-5.4.0/arch/powerpc/include/uapi/asm/errno.h @@ -2,6 +2,7 @@ #ifndef _ASM_POWERPC_ERRNO_H #define _ASM_POWERPC_ERRNO_H +#undef EDEADLOCK #include #undef EDEADLOCK --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/Makefile +++ linux-oracle-5.4.0/arch/powerpc/kernel/Makefile @@ -5,9 +5,6 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' -# Disable clang warning for using setjmp without setjmp.h header -CFLAGS_crash.o += $(call cc-disable-warning, builtin-requires-header) - ifdef CONFIG_PPC64 CFLAGS_prom_init.o += $(NO_MINIMAL_TOC) endif @@ -16,12 +13,14 @@ CFLAGS_btext.o += -fPIC endif +CFLAGS_early_32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_prom_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) CFLAGS_prom_init.o += $(call cc-option, -fno-stack-protector) +CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code @@ -39,7 +38,6 @@ ifdef CONFIG_KASAN CFLAGS_early_32.o += -DDISABLE_BRANCH_PROFILING CFLAGS_cputable.o += -DDISABLE_BRANCH_PROFILING -CFLAGS_prom_init.o += -DDISABLE_BRANCH_PROFILING CFLAGS_btext.o += -DDISABLE_BRANCH_PROFILING endif @@ -161,6 +159,9 @@ obj-y += ucall.o endif +obj-$(CONFIG_PPC_SECURE_BOOT) += secure_boot.o ima_arch.o secvar-ops.o +obj-$(CONFIG_PPC_SECVAR_SYSFS) += secvar-sysfs.o + # Disable GCOV, KCOV & sanitizers in odd or sensitive code GCOV_PROFILE_prom_init.o := n KCOV_INSTRUMENT_prom_init.o := n @@ -184,6 +185,9 @@ KCOV_INSTRUMENT_setup_64.o := n KCOV_INSTRUMENT_paca.o := n +CFLAGS_setup_64.o += -fno-stack-protector +CFLAGS_paca.o += -fno-stack-protector + extra-$(CONFIG_PPC_FPU) += fpu.o extra-$(CONFIG_ALTIVEC) += vector.o extra-$(CONFIG_PPC64) += entry_64.o --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/asm-offsets.c @@ -285,7 +285,7 @@ /* Interrupt register frame */ DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE); - DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); + DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_WITH_PT_REGS); STACK_PT_REGS_OFFSET(GPR0, gpr[0]); STACK_PT_REGS_OFFSET(GPR1, gpr[1]); STACK_PT_REGS_OFFSET(GPR2, gpr[2]); @@ -387,6 +387,7 @@ OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec); OFFSET(STAMP_XTIME, vdso_data, stamp_xtime); OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction); + OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res); OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size); OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size); OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size); @@ -417,7 +418,6 @@ DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); DEFINE(NSEC_PER_SEC, NSEC_PER_SEC); - DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); #ifdef CONFIG_BUG DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry)); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/btext.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/btext.c @@ -250,8 +250,10 @@ rc = btext_initialize(np); printk("result: %d\n", rc); } - if (rc == 0) + if (rc == 0) { + of_node_put(np); break; + } } return rc; } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/cpu_setup_power.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/cpu_setup_power.S @@ -184,7 +184,7 @@ __init_FSCR: mfspr r3,SPRN_FSCR - ori r3,r3,FSCR_TAR|FSCR_DSCR|FSCR_EBB + ori r3,r3,FSCR_TAR|FSCR_EBB mtspr SPRN_FSCR,r3 blr --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/cputable.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/cputable.c @@ -2193,11 +2193,13 @@ * oprofile_cpu_type already has a value, then we are * possibly overriding a real PVR with a logical one, * and, in that case, keep the current value for - * oprofile_cpu_type. + * oprofile_cpu_type. Futhermore, let's ensure that the + * fix for the PMAO bug is enabled on compatibility mode. */ if (old.oprofile_cpu_type != NULL) { t->oprofile_cpu_type = old.oprofile_cpu_type; t->oprofile_type = old.oprofile_type; + t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; } } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/dma-iommu.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/dma-iommu.c @@ -160,7 +160,8 @@ return bypass_mask; } - mask = 1ULL < (fls_long(tbl->it_offset + tbl->it_size) - 1); + mask = 1ULL << (fls_long(tbl->it_offset + tbl->it_size) + + tbl->it_page_shift - 1); mask += mask - 1; return mask; --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/dt_cpu_ftrs.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -139,7 +139,6 @@ /* Initialize the base environment -- clear FSCR/HFSCR. */ hv_mode = !!(mfmsr() & MSR_HV); if (hv_mode) { - /* CPU_FTR_HVMODE is used early in PACA setup */ cur_cpu_spec->cpu_features |= CPU_FTR_HVMODE; mtspr(SPRN_HFSCR, 0); } @@ -347,6 +346,14 @@ { u64 lpcr; + /* + * Linux relies on FSCR[DSCR] being clear, so that we can take the + * facility unavailable interrupt and track the task's usage of DSCR. + * See facility_unavailable_exception(). + * Clear the bit here so that feat_enable() doesn't set it. + */ + f->fscr_bit_nr = -1; + feat_enable(f); lpcr = mfspr(SPRN_LPCR); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/eeh.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/eeh.c @@ -368,14 +368,11 @@ pa = pte_pfn(*ptep); /* On radix we can do hugepage mappings for io, so handle that */ - if (hugepage_shift) { - pa <<= hugepage_shift; - pa |= token & ((1ul << hugepage_shift) - 1); - } else { - pa <<= PAGE_SHIFT; - pa |= token & (PAGE_SIZE - 1); - } + if (!hugepage_shift) + hugepage_shift = PAGE_SHIFT; + pa <<= PAGE_SHIFT; + pa |= token & ((1ul << hugepage_shift) - 1); return pa; } @@ -503,7 +500,7 @@ rc = 1; if (pe->state & EEH_PE_ISOLATED) { pe->check_count++; - if (pe->check_count % EEH_MAX_FAILS == 0) { + if (pe->check_count == EEH_MAX_FAILS) { dn = pci_device_to_OF_node(dev); if (dn) location = of_get_property(dn, "ibm,loc-code", --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/eeh_cache.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/eeh_cache.c @@ -272,8 +272,9 @@ { struct pci_io_addr_range *piar; struct rb_node *n; + unsigned long flags; - spin_lock(&pci_io_addr_cache_root.piar_lock); + spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); for (n = rb_first(&pci_io_addr_cache_root.rb_root); n; n = rb_next(n)) { piar = rb_entry(n, struct pci_io_addr_range, rb_node); @@ -281,7 +282,7 @@ (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", &piar->addr_lo, &piar->addr_hi, pci_name(piar->pcidev)); } - spin_unlock(&pci_io_addr_cache_root.piar_lock); + spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/eeh_driver.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/eeh_driver.c @@ -541,12 +541,6 @@ pci_iov_remove_virtfn(edev->physfn, pdn->vf_index); edev->pdev = NULL; - - /* - * We have to set the VF PE number to invalid one, which is - * required to plug the VF successfully. - */ - pdn->pe_number = IODA_INVALID_PE; #endif if (rmv_data) list_add(&edev->rmv_entry, &rmv_data->removed_vf_list); @@ -897,12 +891,12 @@ /* Log the event */ if (pe->type & EEH_PE_PHB) { - pr_err("EEH: PHB#%x failure detected, location: %s\n", + pr_err("EEH: Recovering PHB#%x, location: %s\n", pe->phb->global_number, eeh_pe_loc_get(pe)); } else { struct eeh_pe *phb_pe = eeh_phb_pe_get(pe->phb); - pr_err("EEH: Frozen PHB#%x-PE#%x detected\n", + pr_err("EEH: Recovering PHB#%x-PE#%x\n", pe->phb->global_number, pe->addr); pr_err("EEH: PE location: %s, PHB location: %s\n", eeh_pe_loc_get(pe), eeh_pe_loc_get(phb_pe)); @@ -1078,45 +1072,46 @@ } pr_info("EEH: Recovery successful.\n"); - } else { - /* - * About 90% of all real-life EEH failures in the field - * are due to poorly seated PCI cards. Only 10% or so are - * due to actual, failed cards. - */ - pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" - "Please try reseating or replacing it\n", - pe->phb->global_number, pe->addr); - - eeh_slot_error_detail(pe, EEH_LOG_PERM); + goto out; + } - /* Notify all devices that they're about to go down. */ - eeh_set_channel_state(pe, pci_channel_io_perm_failure); - eeh_set_irq_state(pe, false); - eeh_pe_report("error_detected(permanent failure)", pe, - eeh_report_failure, NULL); + /* + * About 90% of all real-life EEH failures in the field + * are due to poorly seated PCI cards. Only 10% or so are + * due to actual, failed cards. + */ + pr_err("EEH: Unable to recover from failure from PHB#%x-PE#%x.\n" + "Please try reseating or replacing it\n", + pe->phb->global_number, pe->addr); + + eeh_slot_error_detail(pe, EEH_LOG_PERM); + + /* Notify all devices that they're about to go down. */ + eeh_set_irq_state(pe, false); + eeh_pe_report("error_detected(permanent failure)", pe, + eeh_report_failure, NULL); + eeh_set_channel_state(pe, pci_channel_io_perm_failure); - /* Mark the PE to be removed permanently */ - eeh_pe_state_mark(pe, EEH_PE_REMOVED); + /* Mark the PE to be removed permanently */ + eeh_pe_state_mark(pe, EEH_PE_REMOVED); - /* - * Shut down the device drivers for good. We mark - * all removed devices correctly to avoid access - * the their PCI config any more. - */ - if (pe->type & EEH_PE_VF) { - eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); - eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); - } else { - eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); - eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + /* + * Shut down the device drivers for good. We mark + * all removed devices correctly to avoid access + * the their PCI config any more. + */ + if (pe->type & EEH_PE_VF) { + eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + } else { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); - pci_lock_rescan_remove(); - pci_hp_remove_devices(bus); - pci_unlock_rescan_remove(); - /* The passed PE should no longer be used */ - return; - } + pci_lock_rescan_remove(); + pci_hp_remove_devices(bus); + pci_unlock_rescan_remove(); + /* The passed PE should no longer be used */ + return; } out: @@ -1206,6 +1201,17 @@ eeh_pe_state_mark(pe, EEH_PE_RECOVERING); eeh_handle_normal_event(pe); } else { + eeh_for_each_pe(pe, tmp_pe) + eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev) + edev->mode &= ~EEH_DEV_NO_HANDLER; + + /* Notify all devices to be down */ + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); + eeh_pe_report( + "error_detected(permanent failure)", pe, + eeh_report_failure, NULL); + eeh_set_channel_state(pe, pci_channel_io_perm_failure); + pci_lock_rescan_remove(); list_for_each_entry(hose, &hose_list, list_node) { phb_pe = eeh_phb_pe_get(hose); @@ -1214,16 +1220,6 @@ (phb_pe->state & EEH_PE_RECOVERING)) continue; - eeh_for_each_pe(pe, tmp_pe) - eeh_pe_for_each_dev(tmp_pe, edev, tmp_edev) - edev->mode &= ~EEH_DEV_NO_HANDLER; - - /* Notify all devices to be down */ - eeh_pe_state_clear(pe, EEH_PE_PRI_BUS, true); - eeh_set_channel_state(pe, pci_channel_io_perm_failure); - eeh_pe_report( - "error_detected(permanent failure)", pe, - eeh_report_failure, NULL); bus = eeh_pe_bus_get(phb_pe); if (!bus) { pr_err("%s: Cannot find PCI bus for " --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/eeh_pe.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/eeh_pe.c @@ -922,6 +922,7 @@ { struct eeh_dev *edev; struct pci_dev *pdev; + struct pci_bus *bus = NULL; if (pe->type & EEH_PE_PHB) return pe->phb->bus; @@ -932,9 +933,11 @@ /* Retrieve the parent PCI bus of first (top) PCI device */ edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry); + pci_lock_rescan_remove(); pdev = eeh_dev_to_pci_dev(edev); if (pdev) - return pdev->bus; + bus = pdev->bus; + pci_unlock_rescan_remove(); - return NULL; + return bus; } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/entry_32.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/entry_32.S @@ -179,7 +179,7 @@ 2: /* if from kernel, check interrupted DOZE/NAP mode and * check for stack overflow */ - kuap_save_and_lock r11, r12, r9, r2, r0 + kuap_save_and_lock r11, r12, r9, r2, r6 addi r2, r12, -THREAD lwz r9,KSP_LIMIT(r12) cmplw r1,r9 /* if r1 <= ksp_limit */ @@ -284,6 +284,7 @@ rlwinm r9,r9,0,~MSR_EE lwz r12,_LINK(r11) /* and return to address in LR */ kuap_restore r11, r2, r3, r4, r5 + lwz r2, GPR2(r11) b fast_exception_return #endif @@ -335,6 +336,9 @@ .globl transfer_to_syscall transfer_to_syscall: +#ifdef CONFIG_PPC_BOOK3S_32 + kuep_lock r11, r12 +#endif #ifdef CONFIG_TRACE_IRQFLAGS andi. r12,r9,MSR_EE beq- trace_syscall_entry_irq_off @@ -704,7 +708,7 @@ stw r10,_CCR(r1) stw r1,KSP(r3) /* Set old stack pointer */ - kuap_check r2, r4 + kuap_check r2, r0 #ifdef CONFIG_SMP /* We need a sync somewhere here to make sure that if the * previous task gets rescheduled on another CPU, it sees all @@ -777,7 +781,7 @@ 1: lis r3,exc_exit_restart_end@ha addi r3,r3,exc_exit_restart_end@l cmplw r12,r3 -#if CONFIG_PPC_BOOK3S_601 +#ifdef CONFIG_PPC_BOOK3S_601 bge 2b #else bge 3f @@ -785,7 +789,7 @@ lis r4,exc_exit_restart@ha addi r4,r4,exc_exit_restart@l cmplw r12,r4 -#if CONFIG_PPC_BOOK3S_601 +#ifdef CONFIG_PPC_BOOK3S_601 blt 2b #else blt 3f --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/entry_64.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/entry_64.S @@ -537,6 +537,7 @@ /* Save LR into r9 */ mflr r9 + // Flush the link stack .rept 64 bl .+4 .endr @@ -546,6 +547,11 @@ .balign 32 /* Restore LR */ 1: mtlr r9 + + // If we're just flushing the link stack, return here +3: nop + patch_site 3b patch__flush_link_stack_return + li r9,0x7fff mtctr r9 --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/exceptions-64s.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/exceptions-64s.S @@ -1090,17 +1090,19 @@ bl machine_check_queue_event /* - * We have not used any non-volatile GPRs here, and as a rule - * most exception code including machine check does not. - * Therefore PACA_NAPSTATELOST does not need to be set. Idle - * wakeup will restore volatile registers. + * GPR-loss wakeups are relatively straightforward, because the + * idle sleep code has saved all non-volatile registers on its + * own stack, and r1 in PACAR1. * - * Load the original SRR1 into r3 for pnv_powersave_wakeup_mce. + * For no-loss wakeups the r1 and lr registers used by the + * early machine check handler have to be restored first. r2 is + * the kernel TOC, so no need to restore it. * * Then decrement MCE nesting after finishing with the stack. */ ld r3,_MSR(r1) ld r4,_LINK(r1) + ld r1,GPR1(r1) lhz r11,PACA_IN_MCE(r13) subi r11,r11,1 @@ -1109,7 +1111,7 @@ mtlr r4 rlwinm r10,r3,47-31,30,31 cmpwi cr1,r10,2 - bltlr cr1 /* no state loss, return to idle caller */ + bltlr cr1 /* no state loss, return to idle caller with r3=SRR1 */ b idle_return_gpr_loss #endif @@ -1148,7 +1150,7 @@ INT_HANDLER data_access, 0x300, ool=1, dar=1, dsisr=1, kvm=1 EXC_REAL_END(data_access, 0x300, 0x80) EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) - INT_HANDLER data_access, 0x300, virt=1, dar=1, dsisr=1 + INT_HANDLER data_access, 0x300, ool=1, virt=1, dar=1, dsisr=1 EXC_VIRT_END(data_access, 0x4300, 0x80) INT_KVM_HANDLER data_access, 0x300, EXC_STD, PACA_EXGEN, 1 EXC_COMMON_BEGIN(data_access_common) @@ -1203,7 +1205,7 @@ EXC_REAL_BEGIN(instruction_access, 0x400, 0x80) - INT_HANDLER instruction_access, 0x400, kvm=1 + INT_HANDLER instruction_access, 0x400, ool=1, kvm=1 EXC_REAL_END(instruction_access, 0x400, 0x80) EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80) INT_HANDLER instruction_access, 0x400, virt=1 @@ -1223,7 +1225,7 @@ EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80) - INT_HANDLER instruction_access_slb, 0x480, area=PACA_EXSLB, kvm=1 + INT_HANDLER instruction_access_slb, 0x480, ool=1, area=PACA_EXSLB, kvm=1 EXC_REAL_END(instruction_access_slb, 0x480, 0x80) EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) INT_HANDLER instruction_access_slb, 0x480, virt=1, area=PACA_EXSLB @@ -1363,17 +1365,17 @@ INT_HANDLER decrementer, 0x900, ool=1, bitmask=IRQS_DISABLED, kvm=1 EXC_REAL_END(decrementer, 0x900, 0x80) EXC_VIRT_BEGIN(decrementer, 0x4900, 0x80) - INT_HANDLER decrementer, 0x900, virt=1, bitmask=IRQS_DISABLED + INT_HANDLER decrementer, 0x900, ool=1, virt=1, bitmask=IRQS_DISABLED EXC_VIRT_END(decrementer, 0x4900, 0x80) INT_KVM_HANDLER decrementer, 0x900, EXC_STD, PACA_EXGEN, 0 EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt) EXC_REAL_BEGIN(hdecrementer, 0x980, 0x80) - INT_HANDLER hdecrementer, 0x980, hsrr=EXC_HV, kvm=1 + INT_HANDLER hdecrementer, 0x980, ool=1, hsrr=EXC_HV, kvm=1 EXC_REAL_END(hdecrementer, 0x980, 0x80) EXC_VIRT_BEGIN(hdecrementer, 0x4980, 0x80) - INT_HANDLER hdecrementer, 0x980, virt=1, hsrr=EXC_HV, kvm=1 + INT_HANDLER hdecrementer, 0x980, ool=1, virt=1, hsrr=EXC_HV, kvm=1 EXC_VIRT_END(hdecrementer, 0x4980, 0x80) INT_KVM_HANDLER hdecrementer, 0x980, EXC_HV, PACA_EXGEN, 0 EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt) @@ -2044,15 +2046,8 @@ .endr blr -TRAMP_REAL_BEGIN(rfi_flush_fallback) - SET_SCRATCH0(r13); - GET_PACA(r13); - std r1,PACA_EXRFI+EX_R12(r13) - ld r1,PACAKSAVE(r13) - std r9,PACA_EXRFI+EX_R9(r13) - std r10,PACA_EXRFI+EX_R10(r13) - std r11,PACA_EXRFI+EX_R11(r13) - mfctr r9 +/* Clobbers r10, r11, ctr */ +.macro L1D_DISPLACEMENT_FLUSH ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) ld r11,PACA_L1D_FLUSH_SIZE(r13) srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */ @@ -2063,7 +2058,7 @@ sync /* - * The load adresses are at staggered offsets within cachelines, + * The load addresses are at staggered offsets within cachelines, * which suits some pipelines better (on others it should not * hurt). */ @@ -2078,7 +2073,30 @@ ld r11,(0x80 + 8)*7(r10) addi r10,r10,0x80*8 bdnz 1b +.endm +TRAMP_REAL_BEGIN(entry_flush_fallback) + std r9,PACA_EXRFI+EX_R9(r13) + std r10,PACA_EXRFI+EX_R10(r13) + std r11,PACA_EXRFI+EX_R11(r13) + mfctr r9 + L1D_DISPLACEMENT_FLUSH + mtctr r9 + ld r9,PACA_EXRFI+EX_R9(r13) + ld r10,PACA_EXRFI+EX_R10(r13) + ld r11,PACA_EXRFI+EX_R11(r13) + blr + +TRAMP_REAL_BEGIN(rfi_flush_fallback) + SET_SCRATCH0(r13); + GET_PACA(r13); + std r1,PACA_EXRFI+EX_R12(r13) + ld r1,PACAKSAVE(r13) + std r9,PACA_EXRFI+EX_R9(r13) + std r10,PACA_EXRFI+EX_R10(r13) + std r11,PACA_EXRFI+EX_R11(r13) + mfctr r9 + L1D_DISPLACEMENT_FLUSH mtctr r9 ld r9,PACA_EXRFI+EX_R9(r13) ld r10,PACA_EXRFI+EX_R10(r13) @@ -2096,32 +2114,7 @@ std r10,PACA_EXRFI+EX_R10(r13) std r11,PACA_EXRFI+EX_R11(r13) mfctr r9 - ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) - ld r11,PACA_L1D_FLUSH_SIZE(r13) - srdi r11,r11,(7 + 3) /* 128 byte lines, unrolled 8x */ - mtctr r11 - DCBT_BOOK3S_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ - - /* order ld/st prior to dcbt stop all streams with flushing */ - sync - - /* - * The load adresses are at staggered offsets within cachelines, - * which suits some pipelines better (on others it should not - * hurt). - */ -1: - ld r11,(0x80 + 8)*0(r10) - ld r11,(0x80 + 8)*1(r10) - ld r11,(0x80 + 8)*2(r10) - ld r11,(0x80 + 8)*3(r10) - ld r11,(0x80 + 8)*4(r10) - ld r11,(0x80 + 8)*5(r10) - ld r11,(0x80 + 8)*6(r10) - ld r11,(0x80 + 8)*7(r10) - addi r10,r10,0x80*8 - bdnz 1b - + L1D_DISPLACEMENT_FLUSH mtctr r9 ld r9,PACA_EXRFI+EX_R9(r13) ld r10,PACA_EXRFI+EX_R10(r13) @@ -2130,6 +2123,19 @@ GET_SCRATCH0(r13); hrfid +USE_TEXT_SECTION() + +_GLOBAL(do_uaccess_flush) + UACCESS_FLUSH_FIXUP_SECTION + nop + nop + nop + blr + L1D_DISPLACEMENT_FLUSH + blr +_ASM_NOKPROBE_SYMBOL(do_uaccess_flush) +EXPORT_SYMBOL(do_uaccess_flush) + /* * Real mode exceptions actually use this too, but alternate * instruction code patches (which end up in the common .text area) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/fadump.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/fadump.c @@ -38,8 +38,17 @@ #ifndef CONFIG_PRESERVE_FA_DUMP static DEFINE_MUTEX(fadump_mutex); -struct fadump_mrange_info crash_mrange_info = { "crash", NULL, 0, 0, 0 }; -struct fadump_mrange_info reserved_mrange_info = { "reserved", NULL, 0, 0, 0 }; +struct fadump_mrange_info crash_mrange_info = { "crash", NULL, 0, 0, 0, false }; + +#define RESERVED_RNGS_SZ 16384 /* 16K - 128 entries */ +#define RESERVED_RNGS_CNT (RESERVED_RNGS_SZ / \ + sizeof(struct fadump_memory_range)) +static struct fadump_memory_range rngs[RESERVED_RNGS_CNT]; +struct fadump_mrange_info reserved_mrange_info = { "reserved", rngs, + RESERVED_RNGS_SZ, 0, + RESERVED_RNGS_CNT, true }; + +static void __init early_init_dt_scan_reserved_ranges(unsigned long node); #ifdef CONFIG_CMA static struct cma *fadump_cma; @@ -108,6 +117,11 @@ int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname, int depth, void *data) { + if (depth == 0) { + early_init_dt_scan_reserved_ranges(node); + return 0; + } + if (depth != 1) return 0; @@ -265,7 +279,7 @@ * that is required for a kernel to boot successfully. * */ -static inline u64 fadump_calculate_reserve_size(void) +static __init u64 fadump_calculate_reserve_size(void) { u64 base, size, bootmem_min; int ret; @@ -429,10 +443,72 @@ return ret; } +/* + * Returns true, if the given range overlaps with reserved memory ranges + * starting at idx. Also, updates idx to index of overlapping memory range + * with the given memory range. + * False, otherwise. + */ +static bool overlaps_reserved_ranges(u64 base, u64 end, int *idx) +{ + bool ret = false; + int i; + + for (i = *idx; i < reserved_mrange_info.mem_range_cnt; i++) { + u64 rbase = reserved_mrange_info.mem_ranges[i].base; + u64 rend = rbase + reserved_mrange_info.mem_ranges[i].size; + + if (end <= rbase) + break; + + if ((end > rbase) && (base < rend)) { + *idx = i; + ret = true; + break; + } + } + + return ret; +} + +/* + * Locate a suitable memory area to reserve memory for FADump. While at it, + * lookup reserved-ranges & avoid overlap with them, as they are used by F/W. + */ +static u64 __init fadump_locate_reserve_mem(u64 base, u64 size) +{ + struct fadump_memory_range *mrngs; + phys_addr_t mstart, mend; + int idx = 0; + u64 i, ret = 0; + + mrngs = reserved_mrange_info.mem_ranges; + for_each_free_mem_range(i, NUMA_NO_NODE, MEMBLOCK_NONE, + &mstart, &mend, NULL) { + pr_debug("%llu) mstart: %llx, mend: %llx, base: %llx\n", + i, mstart, mend, base); + + if (mstart > base) + base = PAGE_ALIGN(mstart); + + while ((mend > base) && ((mend - base) >= size)) { + if (!overlaps_reserved_ranges(base, base+size, &idx)) { + ret = base; + goto out; + } + + base = mrngs[idx].base + mrngs[idx].size; + base = PAGE_ALIGN(base); + } + } + +out: + return ret; +} + int __init fadump_reserve_mem(void) { - u64 base, size, mem_boundary, bootmem_min, align = PAGE_SIZE; - bool is_memblock_bottom_up = memblock_bottom_up(); + u64 base, size, mem_boundary, bootmem_min; int ret = 1; if (!fw_dump.fadump_enabled) @@ -453,9 +529,9 @@ PAGE_ALIGN(fadump_calculate_reserve_size()); #ifdef CONFIG_CMA if (!fw_dump.nocma) { - align = FADUMP_CMA_ALIGNMENT; fw_dump.boot_memory_size = - ALIGN(fw_dump.boot_memory_size, align); + ALIGN(fw_dump.boot_memory_size, + FADUMP_CMA_ALIGNMENT); } #endif @@ -523,13 +599,9 @@ * Reserve memory at an offset closer to bottom of the RAM to * minimize the impact of memory hot-remove operation. */ - memblock_set_bottom_up(true); - base = memblock_find_in_range(base, mem_boundary, size, align); - - /* Restore the previous allocation mode */ - memblock_set_bottom_up(is_memblock_bottom_up); + base = fadump_locate_reserve_mem(base, size); - if (!base) { + if (!base || (base + size > mem_boundary)) { pr_err("Failed to find memory chunk for reservation!\n"); goto error_out; } @@ -557,6 +629,7 @@ return ret; error_out: fw_dump.fadump_enabled = 0; + fw_dump.reserve_dump_area_size = 0; return 0; } @@ -726,10 +799,14 @@ static void fadump_free_mem_ranges(struct fadump_mrange_info *mrange_info) { + if (mrange_info->is_static) { + mrange_info->mem_range_cnt = 0; + return; + } + kfree(mrange_info->mem_ranges); - mrange_info->mem_ranges = NULL; - mrange_info->mem_ranges_sz = 0; - mrange_info->max_mem_ranges = 0; + memset((void *)((u64)mrange_info + RNG_NAME_SZ), 0, + (sizeof(struct fadump_mrange_info) - RNG_NAME_SZ)); } /* @@ -759,7 +836,6 @@ sizeof(struct fadump_memory_range)); return 0; } - static inline int fadump_add_mem_range(struct fadump_mrange_info *mrange_info, u64 base, u64 end) { @@ -778,7 +854,12 @@ start = mem_ranges[mrange_info->mem_range_cnt - 1].base; size = mem_ranges[mrange_info->mem_range_cnt - 1].size; - if ((start + size) == base) + /* + * Boot memory area needs separate PT_LOAD segment(s) as it + * is moved to a different location at the time of crash. + * So, fold only if the region is not boot memory area. + */ + if ((start + size) == base && start >= fw_dump.boot_mem_top) is_adjacent = true; } if (!is_adjacent) { @@ -786,6 +867,12 @@ if (mrange_info->mem_range_cnt == mrange_info->max_mem_ranges) { int ret; + if (mrange_info->is_static) { + pr_err("Reached array size limit for %s memory ranges\n", + mrange_info->name); + return -ENOSPC; + } + ret = fadump_alloc_mem_ranges(mrange_info); if (ret) return ret; @@ -1202,20 +1289,19 @@ * Scan reserved-ranges to consider them while reserving/releasing * memory for FADump. */ -static inline int fadump_scan_reserved_mem_ranges(void) +static void __init early_init_dt_scan_reserved_ranges(unsigned long node) { - struct device_node *root; const __be32 *prop; int len, ret = -1; unsigned long i; - root = of_find_node_by_path("/"); - if (!root) - return ret; + /* reserved-ranges already scanned */ + if (reserved_mrange_info.mem_range_cnt != 0) + return; - prop = of_get_property(root, "reserved-ranges", &len); + prop = of_get_flat_dt_prop(node, "reserved-ranges", &len); if (!prop) - return ret; + return; /* * Each reserved range is an (address,size) pair, 2 cells each, @@ -1237,7 +1323,8 @@ } } - return ret; + /* Compact reserved ranges */ + sort_and_merge_mem_ranges(&reserved_mrange_info); } /* @@ -1251,32 +1338,21 @@ u64 ra_start, ra_end, tstart; int i, ret; - fadump_scan_reserved_mem_ranges(); - ra_start = fw_dump.reserve_dump_area_start; ra_end = ra_start + fw_dump.reserve_dump_area_size; /* - * Add reserved dump area to reserved ranges list - * and exclude all these ranges while releasing memory. + * If reserved ranges array limit is hit, overwrite the last reserved + * memory range with reserved dump area to ensure it is excluded from + * the memory being released (reused for next FADump registration). */ - ret = fadump_add_mem_range(&reserved_mrange_info, ra_start, ra_end); - if (ret != 0) { - /* - * Not enough memory to setup reserved ranges but the system is - * running shortage of memory. So, release all the memory except - * Reserved dump area (reused for next fadump registration). - */ - if (begin < ra_end && end > ra_start) { - if (begin < ra_start) - fadump_release_reserved_area(begin, ra_start); - if (end > ra_end) - fadump_release_reserved_area(ra_end, end); - } else - fadump_release_reserved_area(begin, end); + if (reserved_mrange_info.mem_range_cnt == + reserved_mrange_info.max_mem_ranges) + reserved_mrange_info.mem_range_cnt--; + ret = fadump_add_mem_range(&reserved_mrange_info, ra_start, ra_end); + if (ret != 0) return; - } /* Get the reserved ranges list in order first. */ sort_and_merge_mem_ranges(&reserved_mrange_info); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/fpu.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/fpu.S @@ -24,6 +24,15 @@ #include #ifdef CONFIG_VSX +#define __REST_1FPVSR(n,c,base) \ +BEGIN_FTR_SECTION \ + b 2f; \ +END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ + REST_FPR(n,base); \ + b 3f; \ +2: REST_VSR(n,c,base); \ +3: + #define __REST_32FPVSRS(n,c,base) \ BEGIN_FTR_SECTION \ b 2f; \ @@ -42,9 +51,11 @@ 2: SAVE_32VSRS(n,c,base); \ 3: #else +#define __REST_1FPVSR(n,b,base) REST_FPR(n, base) #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) #endif +#define REST_1FPVSR(n,c,base) __REST_1FPVSR(n,__REG_##c,__REG_##base) #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) @@ -68,6 +79,7 @@ SAVE_32FPVSRS(0, R4, R3) mffs fr0 stfd fr0,FPSTATE_FPSCR(r3) + REST_1FPVSR(0, R4, R3) blr EXPORT_SYMBOL(store_fp_state) @@ -132,6 +144,7 @@ 2: SAVE_32FPVSRS(0, R4, R6) mffs fr0 stfd fr0,FPSTATE_FPSCR(r6) + REST_1FPVSR(0, R4, R6) blr /* --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/head_32.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/head_32.S @@ -418,14 +418,11 @@ cmplw 0,r1,r3 #endif mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP - li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -#else - li r1,_PAGE_PRESENT | _PAGE_EXEC -#endif + li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER #if defined(CONFIG_MODULES) || defined(CONFIG_DEBUG_PAGEALLOC) bge- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ #endif 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ @@ -484,13 +481,10 @@ lis r1,PAGE_OFFSET@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP - li r1, _PAGE_PRESENT | _PAGE_ACCESSED -#else - li r1, _PAGE_PRESENT -#endif + li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER bge- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1, _PAGE_PRESENT | _PAGE_ACCESSED addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -564,13 +558,10 @@ lis r1,PAGE_OFFSET@h /* check if kernel address */ cmplw 0,r1,r3 mfspr r2, SPRN_SPRG_PGDIR -#ifdef CONFIG_SWAP - li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED -#else - li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT -#endif + li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER bge- 112f lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ + li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -843,7 +834,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) blr -load_segment_registers: +_GLOBAL(load_segment_registers) li r0, NUM_USER_SEGMENTS /* load up user segment register values */ mtctr r0 /* for context 0 */ li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */ @@ -931,7 +922,7 @@ */ lis r5, abatron_pteptrs@h ori r5, r5, abatron_pteptrs@l - stw r5, 0xf0(r0) /* This much match your Abatron config */ + stw r5, 0xf0(0) /* This much match your Abatron config */ lis r6, swapper_pg_dir@h ori r6, r6, swapper_pg_dir@l tophys(r5, r5) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/head_64.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/head_64.S @@ -420,6 +420,10 @@ /* From now on, r24 is expected to be logical cpuid */ mr r24,r5 + /* Create a temp kernel stack for use before relocation is on. */ + ld r1,PACAEMERGSP(r13) + subi r1,r1,STACK_FRAME_OVERHEAD + /* See if we need to call a cpu state restore handler */ LOAD_REG_ADDR(r23, cur_cpu_spec) ld r23,0(r23) @@ -448,10 +452,6 @@ sync /* order paca.run and cur_cpu_spec */ isync /* In case code patching happened */ - /* Create a temp kernel stack for use before relocation is on. */ - ld r1,PACAEMERGSP(r13) - subi r1,r1,STACK_FRAME_OVERHEAD - b __secondary_start #endif /* SMP */ @@ -945,15 +945,8 @@ std r0,0(r4) #endif - /* The following gets the stack set up with the regs */ - /* pointing to the real addr of the kernel stack. This is */ - /* all done to support the C function call below which sets */ - /* up the htab. This is done because we have relocated the */ - /* kernel but are still running in real mode. */ - - LOAD_REG_ADDR(r3,init_thread_union) - /* set up a stack pointer */ + LOAD_REG_ADDR(r3,init_thread_union) LOAD_REG_IMMEDIATE(r1,THREAD_SIZE) add r1,r3,r1 li r0,0 @@ -999,7 +992,7 @@ bl start_kernel /* Not reached */ - trap +0: trap EMIT_BUG_ENTRY 0b, __FILE__, __LINE__, 0 /* --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/head_8xx.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/head_8xx.S @@ -191,7 +191,7 @@ /* On the MPC8xx, this is a software emulation interrupt. It occurs * for all unimplemented and illegal instructions. */ - EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD) + EXCEPTION(0x1000, SoftEmu, emulation_assist_interrupt, EXC_XFER_STD) /* Called from DataStoreTLBMiss when perf TLB misses events are activated */ #ifdef CONFIG_PERF_EVENTS @@ -229,9 +229,7 @@ InstructionTLBMiss: mtspr SPRN_SPRG_SCRATCH0, r10 -#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) mtspr SPRN_SPRG_SCRATCH1, r11 -#endif /* If we are faulting a kernel address, we have to use the * kernel page tables. @@ -278,27 +276,23 @@ #ifdef ITLB_MISS_KERNEL mtcr r11 #endif -#ifdef CONFIG_SWAP - rlwinm r11, r10, 32-5, _PAGE_PRESENT + rlwinm r11, r10, 32-7, _PAGE_PRESENT and r11, r11, r10 rlwimi r10, r11, 0, _PAGE_PRESENT -#endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 20 and 23 must be clear. * Software indicator bits 22, 24, 25, 26, and 27 must be * set. All other Linux PTE bits control the behavior * of the MMU. */ - rlwimi r10, r10, 0, 0x0f00 /* Clear bits 20-23 */ + rlwinm r10, r10, 0, ~0x0f00 /* Clear bits 20-23 */ rlwimi r10, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */ ori r10, r10, RPN_PATTERN | 0x200 /* Set 22 and 24-27 */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ /* Restore registers */ 0: mfspr r10, SPRN_SPRG_SCRATCH0 -#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) mfspr r11, SPRN_SPRG_SCRATCH1 -#endif rfi patch_site 0b, patch__itlbmiss_exit_1 @@ -308,9 +302,7 @@ addi r10, r10, 1 stw r10, (itlb_miss_counter - PAGE_OFFSET)@l(0) mfspr r10, SPRN_SPRG_SCRATCH0 -#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_SWAP) mfspr r11, SPRN_SPRG_SCRATCH1 -#endif rfi #endif @@ -394,11 +386,9 @@ * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5)); * r10 = (r10 & ~PRESENT) | r11; */ -#ifdef CONFIG_SWAP - rlwinm r11, r10, 32-5, _PAGE_PRESENT + rlwinm r11, r10, 32-7, _PAGE_PRESENT and r11, r11, r10 rlwimi r10, r11, 0, _PAGE_PRESENT -#endif /* The Linux PTE won't go exactly into the MMU TLB. * Software indicator bits 24, 25, 26, and 27 must be * set. All other Linux PTE bits control the behavior --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/head_fsl_booke.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/head_fsl_booke.S @@ -238,6 +238,9 @@ bl early_init +#ifdef CONFIG_KASAN + bl kasan_early_init +#endif #ifdef CONFIG_RELOCATABLE mr r3,r30 mr r4,r31 @@ -264,9 +267,6 @@ /* * Decide what sort of machine this is and initialize the MMU. */ -#ifdef CONFIG_KASAN - bl kasan_early_init -#endif mr r3,r30 mr r4,r31 bl machine_init --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/hw_breakpoint.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/hw_breakpoint.c @@ -247,6 +247,11 @@ return false; } +/* + * Handle a DABR or DAWR exception. + * + * Called in atomic context. + */ int hw_breakpoint_handler(struct die_args *args) { int rc = NOTIFY_STOP; @@ -315,6 +320,8 @@ /* * Handle single-step exceptions following a DABR hit. + * + * Called in atomic context. */ static int single_step_dabr_instruction(struct die_args *args) { @@ -355,6 +362,8 @@ /* * Handle debug exception notifications. + * + * Called in atomic context. */ int hw_breakpoint_exceptions_notify( struct notifier_block *unused, unsigned long val, void *data) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/idle.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/idle.c @@ -37,7 +37,7 @@ { ppc_md.power_save = NULL; cpuidle_disable = IDLE_POWERSAVE_OFF; - return 0; + return 1; } __setup("powersave=off", powersave_off); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/idle_6xx.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/idle_6xx.S @@ -129,7 +129,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM) mtspr SPRN_HID0,r4 BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) lwz r8,TI_LOCAL_FLAGS(r2) /* set napping bit */ --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/idle_book3s.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/idle_book3s.S @@ -50,28 +50,32 @@ std r1,PACAR1(r13) mflr r4 mfcr r5 - /* use stack red zone rather than a new frame for saving regs */ - std r2,-8*0(r1) - std r14,-8*1(r1) - std r15,-8*2(r1) - std r16,-8*3(r1) - std r17,-8*4(r1) - std r18,-8*5(r1) - std r19,-8*6(r1) - std r20,-8*7(r1) - std r21,-8*8(r1) - std r22,-8*9(r1) - std r23,-8*10(r1) - std r24,-8*11(r1) - std r25,-8*12(r1) - std r26,-8*13(r1) - std r27,-8*14(r1) - std r28,-8*15(r1) - std r29,-8*16(r1) - std r30,-8*17(r1) - std r31,-8*18(r1) - std r4,-8*19(r1) - std r5,-8*20(r1) + /* + * Use the stack red zone rather than a new frame for saving regs since + * in the case of no GPR loss the wakeup code branches directly back to + * the caller without deallocating the stack frame first. + */ + std r2,-8*1(r1) + std r14,-8*2(r1) + std r15,-8*3(r1) + std r16,-8*4(r1) + std r17,-8*5(r1) + std r18,-8*6(r1) + std r19,-8*7(r1) + std r20,-8*8(r1) + std r21,-8*9(r1) + std r22,-8*10(r1) + std r23,-8*11(r1) + std r24,-8*12(r1) + std r25,-8*13(r1) + std r26,-8*14(r1) + std r27,-8*15(r1) + std r28,-8*16(r1) + std r29,-8*17(r1) + std r30,-8*18(r1) + std r31,-8*19(r1) + std r4,-8*20(r1) + std r5,-8*21(r1) /* 168 bytes */ PPC_STOP b . /* catch bugs */ @@ -87,8 +91,8 @@ */ _GLOBAL(idle_return_gpr_loss) ld r1,PACAR1(r13) - ld r4,-8*19(r1) - ld r5,-8*20(r1) + ld r4,-8*20(r1) + ld r5,-8*21(r1) mtlr r4 mtcr r5 /* @@ -96,38 +100,40 @@ * from PACATOC. This could be avoided for that less common case * if KVM saved its r2. */ - ld r2,-8*0(r1) - ld r14,-8*1(r1) - ld r15,-8*2(r1) - ld r16,-8*3(r1) - ld r17,-8*4(r1) - ld r18,-8*5(r1) - ld r19,-8*6(r1) - ld r20,-8*7(r1) - ld r21,-8*8(r1) - ld r22,-8*9(r1) - ld r23,-8*10(r1) - ld r24,-8*11(r1) - ld r25,-8*12(r1) - ld r26,-8*13(r1) - ld r27,-8*14(r1) - ld r28,-8*15(r1) - ld r29,-8*16(r1) - ld r30,-8*17(r1) - ld r31,-8*18(r1) + ld r2,-8*1(r1) + ld r14,-8*2(r1) + ld r15,-8*3(r1) + ld r16,-8*4(r1) + ld r17,-8*5(r1) + ld r18,-8*6(r1) + ld r19,-8*7(r1) + ld r20,-8*8(r1) + ld r21,-8*9(r1) + ld r22,-8*10(r1) + ld r23,-8*11(r1) + ld r24,-8*12(r1) + ld r25,-8*13(r1) + ld r26,-8*14(r1) + ld r27,-8*15(r1) + ld r28,-8*16(r1) + ld r29,-8*17(r1) + ld r30,-8*18(r1) + ld r31,-8*19(r1) blr /* * This is the sequence required to execute idle instructions, as * specified in ISA v2.07 (and earlier). MSR[IR] and MSR[DR] must be 0. - * - * The 0(r1) slot is used to save r2 in isa206, so use that here. + * We have to store a GPR somewhere, ptesync, then reload it, and create + * a false dependency on the result of the load. It doesn't matter which + * GPR we store, or where we store it. We have already stored r2 to the + * stack at -8(r1) in isa206_idle_insn_mayloss, so use that. */ #define IDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ /* Magic NAP/SLEEP/WINKLE mode enter sequence */ \ - std r2,0(r1); \ + std r2,-8(r1); \ ptesync; \ - ld r2,0(r1); \ + ld r2,-8(r1); \ 236: cmpd cr0,r2,r2; \ bne 236b; \ IDLE_INST; \ @@ -152,28 +158,32 @@ std r1,PACAR1(r13) mflr r4 mfcr r5 - /* use stack red zone rather than a new frame for saving regs */ - std r2,-8*0(r1) - std r14,-8*1(r1) - std r15,-8*2(r1) - std r16,-8*3(r1) - std r17,-8*4(r1) - std r18,-8*5(r1) - std r19,-8*6(r1) - std r20,-8*7(r1) - std r21,-8*8(r1) - std r22,-8*9(r1) - std r23,-8*10(r1) - std r24,-8*11(r1) - std r25,-8*12(r1) - std r26,-8*13(r1) - std r27,-8*14(r1) - std r28,-8*15(r1) - std r29,-8*16(r1) - std r30,-8*17(r1) - std r31,-8*18(r1) - std r4,-8*19(r1) - std r5,-8*20(r1) + /* + * Use the stack red zone rather than a new frame for saving regs since + * in the case of no GPR loss the wakeup code branches directly back to + * the caller without deallocating the stack frame first. + */ + std r2,-8*1(r1) + std r14,-8*2(r1) + std r15,-8*3(r1) + std r16,-8*4(r1) + std r17,-8*5(r1) + std r18,-8*6(r1) + std r19,-8*7(r1) + std r20,-8*8(r1) + std r21,-8*9(r1) + std r22,-8*10(r1) + std r23,-8*11(r1) + std r24,-8*12(r1) + std r25,-8*13(r1) + std r26,-8*14(r1) + std r27,-8*15(r1) + std r28,-8*16(r1) + std r29,-8*17(r1) + std r30,-8*18(r1) + std r31,-8*19(r1) + std r4,-8*20(r1) + std r5,-8*21(r1) cmpwi r3,PNV_THREAD_NAP bne 1f IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/ima_arch.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/ima_arch.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 IBM Corporation + * Author: Nayna Jain + */ + +#include +#include + +bool arch_ima_get_secureboot(void) +{ + return is_ppc_secureboot_enabled(); +} + +/* + * The "secure_rules" are enabled only on "secureboot" enabled systems. + * These rules verify the file signatures against known good values. + * The "appraise_type=imasig|modsig" option allows the known good signature + * to be stored as an xattr or as an appended signature. + * + * To avoid duplicate signature verification as much as possible, the IMA + * policy rule for module appraisal is added only if CONFIG_MODULE_SIG + * is not enabled. + */ +static const char *const secure_rules[] = { + "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", +#ifndef CONFIG_MODULE_SIG + "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", +#endif + NULL +}; + +/* + * The "trusted_rules" are enabled only on "trustedboot" enabled systems. + * These rules add the kexec kernel image and kernel modules file hashes to + * the IMA measurement list. + */ +static const char *const trusted_rules[] = { + "measure func=KEXEC_KERNEL_CHECK", + "measure func=MODULE_CHECK", + NULL +}; + +/* + * The "secure_and_trusted_rules" contains rules for both the secure boot and + * trusted boot. The "template=ima-modsig" option includes the appended + * signature, when available, in the IMA measurement list. + */ +static const char *const secure_and_trusted_rules[] = { + "measure func=KEXEC_KERNEL_CHECK template=ima-modsig", + "measure func=MODULE_CHECK template=ima-modsig", + "appraise func=KEXEC_KERNEL_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", +#ifndef CONFIG_MODULE_SIG + "appraise func=MODULE_CHECK appraise_flag=check_blacklist appraise_type=imasig|modsig", +#endif + NULL +}; + +/* + * Returns the relevant IMA arch-specific policies based on the system secure + * boot state. + */ +const char *const *arch_get_ima_policy(void) +{ + if (is_ppc_secureboot_enabled()) { + if (IS_ENABLED(CONFIG_MODULE_SIG)) + set_module_sig_enforced(); + + if (is_ppc_trustedboot_enabled()) + return secure_and_trusted_rules; + else + return secure_rules; + } else if (is_ppc_trustedboot_enabled()) { + return trusted_rules; + } + + return NULL; +} --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/iommu.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/iommu.c @@ -133,17 +133,28 @@ return 0; } -static struct notifier_block fail_iommu_bus_notifier = { +/* + * PCI and VIO buses need separate notifier_block structs, since they're linked + * list nodes. Sharing a notifier_block would mean that any notifiers later + * registered for PCI buses would also get called by VIO buses and vice versa. + */ +static struct notifier_block fail_iommu_pci_bus_notifier = { .notifier_call = fail_iommu_bus_notify }; +#ifdef CONFIG_IBMVIO +static struct notifier_block fail_iommu_vio_bus_notifier = { + .notifier_call = fail_iommu_bus_notify +}; +#endif + static int __init fail_iommu_setup(void) { #ifdef CONFIG_PCI - bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier); + bus_register_notifier(&pci_bus_type, &fail_iommu_pci_bus_notifier); #endif #ifdef CONFIG_IBMVIO - bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier); + bus_register_notifier(&vio_bus_type, &fail_iommu_vio_bus_notifier); #endif return 0; @@ -1057,7 +1068,7 @@ spin_lock_irqsave(&tbl->large_pool.lock, flags); for (i = 0; i < tbl->nr_pools; i++) - spin_lock(&tbl->pools[i].lock); + spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); iommu_table_release_pages(tbl); @@ -1085,7 +1096,7 @@ spin_lock_irqsave(&tbl->large_pool.lock, flags); for (i = 0; i < tbl->nr_pools; i++) - spin_lock(&tbl->pools[i].lock); + spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); memset(tbl->it_map, 0, sz); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/irq.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/irq.c @@ -619,8 +619,6 @@ trace_irq_entry(regs); - check_stack_overflow(); - /* * Query the platform PIC for the interrupt & ack it. * @@ -652,6 +650,8 @@ irqsp = hardirq_ctx[raw_smp_processor_id()]; sirqsp = softirq_ctx[raw_smp_processor_id()]; + check_stack_overflow(); + /* Already there ? */ if (unlikely(cursp == irqsp || cursp == sirqsp)) { __do_irq(regs); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/kprobes.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/kprobes.c @@ -264,6 +264,10 @@ if (user_mode(regs)) return 0; + if (!IS_ENABLED(CONFIG_BOOKE) && + (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))) + return 0; + /* * We don't want to be preempted for the entire * duration of kprobe processing --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/kvm.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/kvm.c @@ -669,7 +669,7 @@ on_each_cpu(kvm_map_magic_page, &features, 1); /* Quick self-test to see if the mapping works */ - if (!fault_in_pages_readable((const char *)KVM_MAGIC_PAGE, sizeof(u32))) { + if (fault_in_pages_readable((const char *)KVM_MAGIC_PAGE, sizeof(u32))) { kvm_patching_worked = false; return; } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/l2cr_6xx.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/l2cr_6xx.S @@ -96,7 +96,7 @@ /* Stop DST streams */ BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) @@ -293,7 +293,7 @@ isync /* Stop DST streams */ - DSSALL + PPC_DSSALL sync /* Get the current enable bit of the L3CR into r4 */ @@ -402,7 +402,7 @@ _GLOBAL(__flush_disable_L1) /* Stop pending alitvec streams and memory accesses */ BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) sync --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/machine_kexec.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/machine_kexec.c @@ -114,11 +114,12 @@ void __init reserve_crashkernel(void) { - unsigned long long crash_size, crash_base; + unsigned long long crash_size, crash_base, total_mem_sz; int ret; + total_mem_sz = memory_limit ? memory_limit : memblock_phys_mem_size(); /* use common parsing */ - ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(), + ret = parse_crashkernel(boot_command_line, total_mem_sz, &crash_size, &crash_base); if (ret == 0 && crash_size > 0) { crashk_res.start = crash_base; @@ -145,11 +146,18 @@ if (!crashk_res.start) { #ifdef CONFIG_PPC64 /* - * On 64bit we split the RMO in half but cap it at half of - * a small SLB (128MB) since the crash kernel needs to place - * itself and some stacks to be in the first segment. + * On the LPAR platform place the crash kernel to mid of + * RMA size (512MB or more) to ensure the crash kernel + * gets enough space to place itself and some stack to be + * in the first segment. At the same time normal kernel + * also get enough space to allocate memory for essential + * system resource in the first segment. Keep the crash + * kernel starts at 128MB offset on other platforms. */ - crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2)); + if (firmware_has_feature(FW_FEATURE_LPAR)) + crashk_res.start = ppc64_rma_size / 2; + else + crashk_res.start = min(0x8000000ULL, (ppc64_rma_size / 2)); #else crashk_res.start = KDUMP_KERNELBASE; #endif @@ -177,6 +185,7 @@ /* Crash kernel trumps memory limit */ if (memory_limit && memory_limit <= crashk_res.end) { memory_limit = crashk_res.end + 1; + total_mem_sz = memory_limit; printk("Adjusted memory limit for crashkernel, now 0x%llx\n", memory_limit); } @@ -185,7 +194,7 @@ "for crashkernel (System RAM: %ldMB)\n", (unsigned long)(crash_size >> 20), (unsigned long)(crashk_res.start >> 20), - (unsigned long)(memblock_phys_mem_size() >> 20)); + (unsigned long)(total_mem_sz >> 20)); if (!memblock_is_region_memory(crashk_res.start, crash_size) || memblock_reserve(crashk_res.start, crash_size)) { --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/misc_32.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/misc_32.S @@ -317,126 +317,6 @@ #endif /* CONFIG_PPC_8xx */ /* - * Write any modified data cache blocks out to memory - * and invalidate the corresponding instruction cache blocks. - * This is a no-op on the 601. - * - * flush_icache_range(unsigned long start, unsigned long stop) - */ -_GLOBAL(flush_icache_range) -#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) - PURGE_PREFETCHED_INS - blr /* for 601 and e200, do nothing */ -#else - rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT - subf r4,r3,r4 - addi r4,r4,L1_CACHE_BYTES - 1 - srwi. r4,r4,L1_CACHE_SHIFT - beqlr - mtctr r4 - mr r6,r3 -1: dcbst 0,r3 - addi r3,r3,L1_CACHE_BYTES - bdnz 1b - sync /* wait for dcbst's to get to ram */ -#ifndef CONFIG_44x - mtctr r4 -2: icbi 0,r6 - addi r6,r6,L1_CACHE_BYTES - bdnz 2b -#else - /* Flash invalidate on 44x because we are passed kmapped addresses and - this doesn't work for userspace pages due to the virtually tagged - icache. Sigh. */ - iccci 0, r0 -#endif - sync /* additional sync needed on g4 */ - isync - blr -#endif -_ASM_NOKPROBE_SYMBOL(flush_icache_range) -EXPORT_SYMBOL(flush_icache_range) - -/* - * Flush a particular page from the data cache to RAM. - * Note: this is necessary because the instruction cache does *not* - * snoop from the data cache. - * This is a no-op on the 601 and e200 which have a unified cache. - * - * void __flush_dcache_icache(void *page) - */ -_GLOBAL(__flush_dcache_icache) -#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) - PURGE_PREFETCHED_INS - blr -#else - rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ - li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ - mtctr r4 - mr r6,r3 -0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_BYTES - bdnz 0b - sync -#ifdef CONFIG_44x - /* We don't flush the icache on 44x. Those have a virtual icache - * and we don't have access to the virtual address here (it's - * not the page vaddr but where it's mapped in user space). The - * flushing of the icache on these is handled elsewhere, when - * a change in the address space occurs, before returning to - * user space - */ -BEGIN_MMU_FTR_SECTION - blr -END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x) -#endif /* CONFIG_44x */ - mtctr r4 -1: icbi 0,r6 - addi r6,r6,L1_CACHE_BYTES - bdnz 1b - sync - isync - blr -#endif - -#ifndef CONFIG_BOOKE -/* - * Flush a particular page from the data cache to RAM, identified - * by its physical address. We turn off the MMU so we can just use - * the physical address (this may be a highmem page without a kernel - * mapping). - * - * void __flush_dcache_icache_phys(unsigned long physaddr) - */ -_GLOBAL(__flush_dcache_icache_phys) -#if defined(CONFIG_PPC_BOOK3S_601) || defined(CONFIG_E200) - PURGE_PREFETCHED_INS - blr /* for 601 and e200, do nothing */ -#else - mfmsr r10 - rlwinm r0,r10,0,28,26 /* clear DR */ - mtmsr r0 - isync - rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ - li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ - mtctr r4 - mr r6,r3 -0: dcbst 0,r3 /* Write line to ram */ - addi r3,r3,L1_CACHE_BYTES - bdnz 0b - sync - mtctr r4 -1: icbi 0,r6 - addi r6,r6,L1_CACHE_BYTES - bdnz 1b - sync - mtmsr r10 /* restore DR */ - isync - blr -#endif -#endif /* CONFIG_BOOKE */ - -/* * Copy a whole page. We use the dcbz instruction on the destination * to reduce memory traffic (it eliminates the unnecessary reads of * the destination into cache). This requires that the destination --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/misc_64.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/misc_64.S @@ -49,108 +49,6 @@ mtlr r0 blr - .section ".toc","aw" -PPC64_CACHES: - .tc ppc64_caches[TC],ppc64_caches - .section ".text" - -/* - * Write any modified data cache blocks out to memory - * and invalidate the corresponding instruction cache blocks. - * - * flush_icache_range(unsigned long start, unsigned long stop) - * - * flush all bytes from start through stop-1 inclusive - */ - -_GLOBAL_TOC(flush_icache_range) -BEGIN_FTR_SECTION - PURGE_PREFETCHED_INS - blr -END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) -/* - * Flush the data cache to memory - * - * Different systems have different cache line sizes - * and in some cases i-cache and d-cache line sizes differ from - * each other. - */ - ld r10,PPC64_CACHES@toc(r2) - lwz r7,DCACHEL1BLOCKSIZE(r10)/* Get cache block size */ - addi r5,r7,-1 - andc r6,r3,r5 /* round low to line bdy */ - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 /* ensure we get enough */ - lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of cache block size */ - srw. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - mtctr r8 -1: dcbst 0,r6 - add r6,r6,r7 - bdnz 1b - sync - -/* Now invalidate the instruction cache */ - - lwz r7,ICACHEL1BLOCKSIZE(r10) /* Get Icache block size */ - addi r5,r7,-1 - andc r6,r3,r5 /* round low to line bdy */ - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 - lwz r9,ICACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of Icache block size */ - srw. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - mtctr r8 -2: icbi 0,r6 - add r6,r6,r7 - bdnz 2b - isync - blr -_ASM_NOKPROBE_SYMBOL(flush_icache_range) -EXPORT_SYMBOL(flush_icache_range) - -/* - * Flush a particular page from the data cache to RAM. - * Note: this is necessary because the instruction cache does *not* - * snoop from the data cache. - * - * void __flush_dcache_icache(void *page) - */ -_GLOBAL(__flush_dcache_icache) -/* - * Flush the data cache to memory - * - * Different systems have different cache line sizes - */ - -BEGIN_FTR_SECTION - PURGE_PREFETCHED_INS - blr -END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - -/* Flush the dcache */ - ld r7,PPC64_CACHES@toc(r2) - clrrdi r3,r3,PAGE_SHIFT /* Page align */ - lwz r4,DCACHEL1BLOCKSPERPAGE(r7) /* Get # dcache blocks per page */ - lwz r5,DCACHEL1BLOCKSIZE(r7) /* Get dcache block size */ - mr r6,r3 - mtctr r4 -0: dcbst 0,r6 - add r6,r6,r5 - bdnz 0b - sync - -/* Now invalidate the icache */ - - lwz r4,ICACHEL1BLOCKSPERPAGE(r7) /* Get # icache blocks per page */ - lwz r5,ICACHEL1BLOCKSIZE(r7) /* Get icache block size */ - mtctr r4 -1: icbi 0,r3 - add r3,r3,r5 - bdnz 1b - isync - blr - _GLOBAL(__bswapdi2) EXPORT_SYMBOL(__bswapdi2) srdi r8,r3,32 --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/paca.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/paca.c @@ -86,7 +86,7 @@ * This is very early in boot, so no harm done if the kernel crashes at * this point. */ - BUG_ON(shared_lppaca_size >= shared_lppaca_total_size); + BUG_ON(shared_lppaca_size > shared_lppaca_total_size); return ptr; } @@ -214,11 +214,15 @@ /* On Book3E, initialize the TLB miss exception frames */ mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb); #else - /* In HV mode, we setup both HPACA and PACA to avoid problems + /* + * In HV mode, we setup both HPACA and PACA to avoid problems * if we do a GET_PACA() before the feature fixups have been - * applied + * applied. + * + * Normally you should test against CPU_FTR_HVMODE, but CPU features + * are not yet set up when we first reach here. */ - if (early_cpu_has_feature(CPU_FTR_HVMODE)) + if (mfmsr() & MSR_HV) mtspr(SPRN_SPRG_HPACA, local_paca); #endif mtspr(SPRN_SPRG_PACA, local_paca); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/pci-common.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/pci-common.c @@ -66,23 +66,35 @@ pci_dma_ops = dma_ops; } -/* - * This function should run under locking protection, specifically - * hose_spinlock. - */ static int get_phb_number(struct device_node *dn) { int ret, phb_id = -1; - u32 prop_32; u64 prop; /* * Try fixed PHB numbering first, by checking archs and reading - * the respective device-tree properties. Firstly, try powernv by - * reading "ibm,opal-phbid", only present in OPAL environment. + * the respective device-tree properties. Firstly, try reading + * standard "linux,pci-domain", then try reading "ibm,opal-phbid" + * (only present in powernv OPAL environment), then try device-tree + * alias and as the last try to use lower bits of "reg" property. */ - ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop); + ret = of_get_pci_domain_nr(dn); + if (ret >= 0) { + prop = ret; + ret = 0; + } + if (ret) + ret = of_property_read_u64(dn, "ibm,opal-phbid", &prop); + + if (ret) { + ret = of_alias_get_id(dn, "pci"); + if (ret >= 0) { + prop = ret; + ret = 0; + } + } if (ret) { + u32 prop_32; ret = of_property_read_u32_index(dn, "reg", 1, &prop_32); prop = prop_32; } @@ -90,18 +102,20 @@ if (!ret) phb_id = (int)(prop & (MAX_PHBS - 1)); + spin_lock(&hose_spinlock); + /* We need to be sure to not use the same PHB number twice. */ if ((phb_id >= 0) && !test_and_set_bit(phb_id, phb_bitmap)) - return phb_id; + goto out_unlock; - /* - * If not pseries nor powernv, or if fixed PHB numbering tried to add - * the same PHB number twice, then fallback to dynamic PHB numbering. - */ + /* If everything fails then fallback to dynamic PHB numbering. */ phb_id = find_first_zero_bit(phb_bitmap, MAX_PHBS); BUG_ON(phb_id >= MAX_PHBS); set_bit(phb_id, phb_bitmap); +out_unlock: + spin_unlock(&hose_spinlock); + return phb_id; } @@ -112,10 +126,13 @@ phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); if (phb == NULL) return NULL; - spin_lock(&hose_spinlock); + phb->global_number = get_phb_number(dev); + + spin_lock(&hose_spinlock); list_add_tail(&phb->list_node, &hose_list); spin_unlock(&hose_spinlock); + phb->dn = dev; phb->is_dynamic = slab_is_available(); #ifdef CONFIG_PPC64 @@ -347,6 +364,7 @@ } return NULL; } +EXPORT_SYMBOL(pci_find_hose_for_OF_device); struct pci_controller *pci_find_controller_for_domain(int domain_nr) { @@ -1577,6 +1595,7 @@ { return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap); } +EXPORT_SYMBOL_GPL(early_find_capability); struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) { @@ -1669,3 +1688,13 @@ } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); + + +static int __init discover_phbs(void) +{ + if (ppc_md.discover_phbs) + ppc_md.discover_phbs(); + + return 0; +} +core_initcall(discover_phbs); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/pci_dn.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/pci_dn.c @@ -244,9 +244,22 @@ continue; #ifdef CONFIG_EEH - /* Release EEH device for the VF */ + /* + * Release EEH state for this VF. The PCI core + * has already torn down the pci_dev for this VF, but + * we're responsible to removing the eeh_dev since it + * has the same lifetime as the pci_dn that spawned it. + */ edev = pdn_to_eeh_dev(pdn); if (edev) { + /* + * We allocate pci_dn's for the totalvfs count, + * but only only the vfs that were activated + * have a configured PE. + */ + if (edev->pe) + eeh_rmv_from_parent_pe(edev); + pdn->edev = NULL; kfree(edev); } @@ -312,6 +325,7 @@ INIT_LIST_HEAD(&pdn->list); parent = of_get_parent(dn); pdn->parent = parent ? PCI_DN(parent) : NULL; + of_node_put(parent); if (pdn->parent) list_add_tail(&pdn->list, &pdn->parent->child_list); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/process.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/process.c @@ -1218,29 +1218,31 @@ static void show_instructions(struct pt_regs *regs) { int i; + unsigned long nip = regs->nip; unsigned long pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int)); printk("Instruction dump:"); + /* + * If we were executing with the MMU off for instructions, adjust pc + * rather than printing XXXXXXXX. + */ + if (!IS_ENABLED(CONFIG_BOOKE) && !(regs->msr & MSR_IR)) { + pc = (unsigned long)phys_to_virt(pc); + nip = (unsigned long)phys_to_virt(regs->nip); + } + for (i = 0; i < NR_INSN_TO_PRINT; i++) { int instr; if (!(i % 8)) pr_cont("\n"); -#if !defined(CONFIG_BOOKE) - /* If executing with the IMMU off, adjust pc rather - * than print XXXXXXXX. - */ - if (!(regs->msr & MSR_IR)) - pc = (unsigned long)phys_to_virt(pc); -#endif - if (!__kernel_text_address(pc) || probe_kernel_address((const void *)pc, instr)) { pr_cont("XXXXXXXX "); } else { - if (regs->nip == pc) + if (nip == pc) pr_cont("<%08x> ", instr); else pr_cont("%08x ", instr); @@ -1717,7 +1719,7 @@ tm_reclaim_current(0); #endif - memset(regs->gpr, 0, sizeof(regs->gpr)); + memset(®s->gpr[1], 0, sizeof(regs->gpr) - sizeof(regs->gpr[0])); regs->ctr = 0; regs->link = 0; regs->xer = 0; @@ -1999,12 +2001,12 @@ return 0; do { - sp = *(unsigned long *)sp; + sp = READ_ONCE_NOCHECK(*(unsigned long *)sp); if (!validate_sp(sp, p, STACK_FRAME_OVERHEAD) || p->state == TASK_RUNNING) return 0; if (count > 0) { - ip = ((unsigned long *)sp)[STACK_FRAME_LR_SAVE]; + ip = READ_ONCE_NOCHECK(((unsigned long *)sp)[STACK_FRAME_LR_SAVE]); if (!in_sched_functions(ip)) return ip; } @@ -2079,7 +2081,7 @@ * See if this is an exception frame. * We look for the "regshere" marker in the current frame. */ - if (validate_sp(sp, tsk, STACK_INT_FRAME_SIZE) + if (validate_sp(sp, tsk, STACK_FRAME_WITH_PT_REGS) && stack[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { struct pt_regs *regs = (struct pt_regs *) (sp + STACK_FRAME_OVERHEAD); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/prom.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/prom.c @@ -266,7 +266,7 @@ }; #if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU) -static inline void identical_pvr_fixup(unsigned long node) +static __init void identical_pvr_fixup(unsigned long node) { unsigned int pvr; const char *model = of_get_flat_dt_prop(node, "model", NULL); @@ -685,6 +685,23 @@ static void tm_init(void) { } #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ +#ifdef CONFIG_PPC64 +static void __init save_fscr_to_task(void) +{ + /* + * Ensure the init_task (pid 0, aka swapper) uses the value of FSCR we + * have configured via the device tree features or via __init_FSCR(). + * That value will then be propagated to pid 1 (init) and all future + * processes. + */ + if (early_cpu_has_feature(CPU_FTR_ARCH_207S)) + init_task.thread.fscr = mfspr(SPRN_FSCR); +} +#else +static inline void save_fscr_to_task(void) {}; +#endif + + void __init early_init_devtree(void *params) { phys_addr_t limit; @@ -723,6 +740,13 @@ of_scan_flat_dt(early_init_dt_scan_root, NULL); of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); + /* + * As generic code authors expect to be able to use static keys + * in early_param() handlers, we initialize the static keys just + * before parsing early params (it's fine to call jump_label_init() + * more than once). + */ + jump_label_init(); parse_early_param(); /* make sure we've parsed cmdline for mem= before this */ @@ -773,6 +797,8 @@ BUG(); } + save_fscr_to_task(); + #if defined(CONFIG_SMP) && defined(CONFIG_PPC64) /* We'll later wait for secondaries to check in; there are * NCPUS-1 non-boot CPUs :-) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/prom_init.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/prom_init.c @@ -1053,7 +1053,7 @@ .reserved2 = 0, .reserved3 = 0, .subprocessors = 1, - .byte22 = OV5_FEAT(OV5_DRMEM_V2), + .byte22 = OV5_FEAT(OV5_DRMEM_V2) | OV5_FEAT(OV5_DRC_INFO), .intarch = 0, .mmu = 0, .hash_ext = 0, @@ -1305,14 +1305,10 @@ if (prop_len > sizeof(vec)) prom_printf("WARNING: ibm,arch-vec-5-platform-support longer than expected (len: %d)\n", prop_len); - prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", - &vec, sizeof(vec)); - for (i = 0; i < sizeof(vec); i += 2) { - prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2 - , vec[i] - , vec[i + 1]); - prom_parse_platform_support(vec[i], vec[i + 1], - &supported); + prom_getprop(prom.chosen, "ibm,arch-vec-5-platform-support", &vec, sizeof(vec)); + for (i = 0; i < prop_len; i += 2) { + prom_debug("%d: index = 0x%x val = 0x%x\n", i / 2, vec[i], vec[i + 1]); + prom_parse_platform_support(vec[i], vec[i + 1], &supported); } } @@ -1761,6 +1757,9 @@ if (token == 0) prom_panic("Could not get token for ibm,os-term\n"); os_term_args.token = cpu_to_be32(token); + os_term_args.nargs = cpu_to_be32(1); + os_term_args.nret = cpu_to_be32(1); + os_term_args.args[0] = cpu_to_be32(__pa(str)); prom_rtas_hcall((uint64_t)&os_term_args); } #endif /* CONFIG_PPC_SVM */ @@ -2857,7 +2856,7 @@ #endif #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC) -static void __init fixup_device_tree_pmac(void) +static void __init fixup_device_tree_pmac64(void) { phandle u3, i2c, mpic; u32 u3_rev; @@ -2897,7 +2896,31 @@ &parent, sizeof(parent)); } #else -#define fixup_device_tree_pmac() +#define fixup_device_tree_pmac64() +#endif + +#ifdef CONFIG_PPC_PMAC +static void __init fixup_device_tree_pmac(void) +{ + __be32 val = 1; + char type[8]; + phandle node; + + // Some pmacs are missing #size-cells on escc nodes + for (node = 0; prom_next_node(&node); ) { + type[0] = '\0'; + prom_getprop(node, "device_type", type, sizeof(type)); + if (prom_strcmp(type, "escc")) + continue; + + if (prom_getproplen(node, "#size-cells") != PROM_ERROR) + continue; + + prom_setprop(node, NULL, "#size-cells", &val, sizeof(val)); + } +} +#else +static inline void fixup_device_tree_pmac(void) { } #endif #ifdef CONFIG_PPC_EFIKA @@ -2920,7 +2943,7 @@ /* Check if the phy-handle property exists - bail if it does */ rv = prom_getprop(node, "phy-handle", prop, sizeof(prop)); - if (!rv) + if (rv <= 0) return; /* @@ -3122,6 +3145,7 @@ fixup_device_tree_maple_memory_controller(); fixup_device_tree_chrp(); fixup_device_tree_pmac(); + fixup_device_tree_pmac64(); fixup_device_tree_efika(); fixup_device_tree_pasemi(); } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/prom_init_check.sh +++ linux-oracle-5.4.0/arch/powerpc/kernel/prom_init_check.sh @@ -13,7 +13,7 @@ # If you really need to reference something from prom_init.o add # it to the list below: -grep "^CONFIG_KASAN=y$" .config >/dev/null +grep "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} >/dev/null if [ $? -eq 0 ] then MEM_FUNCS="__memcpy __memset" --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/ptrace.c @@ -3014,8 +3014,13 @@ flush_fp_to_thread(child); if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&tmp, &child->thread.TS_FPR(fpidx), - sizeof(long)); + if (IS_ENABLED(CONFIG_PPC32)) { + // On 32-bit the index we are passed refers to 32-bit words + tmp = ((u32 *)child->thread.fp_state.fpr)[fpidx]; + } else { + memcpy(&tmp, &child->thread.TS_FPR(fpidx), + sizeof(long)); + } else tmp = child->thread.fp_state.fpscr; } @@ -3047,8 +3052,13 @@ flush_fp_to_thread(child); if (fpidx < (PT_FPSCR - PT_FPR0)) - memcpy(&child->thread.TS_FPR(fpidx), &data, - sizeof(long)); + if (IS_ENABLED(CONFIG_PPC32)) { + // On 32-bit the index we are passed refers to 32-bit words + ((u32 *)child->thread.fp_state.fpr)[fpidx] = data; + } else { + memcpy(&child->thread.TS_FPR(fpidx), &data, + sizeof(long)); + } else child->thread.fp_state.fpscr = data; ret = 0; @@ -3398,4 +3408,7 @@ offsetof(struct user_pt_regs, result)); BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs)); + + // ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible + BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX)); } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/rtas.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/rtas.c @@ -51,10 +51,10 @@ EXPORT_SYMBOL(rtas); DEFINE_SPINLOCK(rtas_data_buf_lock); -EXPORT_SYMBOL(rtas_data_buf_lock); +EXPORT_SYMBOL_GPL(rtas_data_buf_lock); -char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; -EXPORT_SYMBOL(rtas_data_buf); +char rtas_data_buf[RTAS_DATA_BUF_SIZE] __aligned(SZ_4K); +EXPORT_SYMBOL_GPL(rtas_data_buf); unsigned long rtas_rmo_buf; @@ -63,7 +63,7 @@ * This is done like this so rtas_flash can be a module. */ void (*rtas_flash_term_hook)(int); -EXPORT_SYMBOL(rtas_flash_term_hook); +EXPORT_SYMBOL_GPL(rtas_flash_term_hook); /* RTAS use home made raw locking instead of spin_lock_irqsave * because those can be called from within really nasty contexts @@ -311,7 +311,7 @@ spin_unlock(&progress_lock); } -EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */ +EXPORT_SYMBOL_GPL(rtas_progress); /* needed by rtas_flash module */ int rtas_token(const char *service) { @@ -321,7 +321,7 @@ tokp = of_get_property(rtas.dev, service, NULL); return tokp ? be32_to_cpu(*tokp) : RTAS_UNKNOWN_SERVICE; } -EXPORT_SYMBOL(rtas_token); +EXPORT_SYMBOL_GPL(rtas_token); int rtas_service_present(const char *service) { @@ -398,7 +398,7 @@ buf = kmalloc(RTAS_ERROR_LOG_MAX, GFP_ATOMIC); } if (buf) - memcpy(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); + memmove(buf, rtas_err_buf, RTAS_ERROR_LOG_MAX); } return buf; @@ -481,7 +481,7 @@ } return ret; } -EXPORT_SYMBOL(rtas_call); +EXPORT_SYMBOL_GPL(rtas_call); /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. @@ -516,7 +516,7 @@ return ms; } -EXPORT_SYMBOL(rtas_busy_delay); +EXPORT_SYMBOL_GPL(rtas_busy_delay); static int rtas_error_rc(int rtas_rc) { @@ -562,7 +562,7 @@ return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_get_power_level); +EXPORT_SYMBOL_GPL(rtas_get_power_level); int rtas_set_power_level(int powerdomain, int level, int *setlevel) { @@ -580,7 +580,7 @@ return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_set_power_level); +EXPORT_SYMBOL_GPL(rtas_set_power_level); int rtas_get_sensor(int sensor, int index, int *state) { @@ -598,7 +598,7 @@ return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_get_sensor); +EXPORT_SYMBOL_GPL(rtas_get_sensor); int rtas_get_sensor_fast(int sensor, int index, int *state) { @@ -659,7 +659,7 @@ return rtas_error_rc(rc); return rc; } -EXPORT_SYMBOL(rtas_set_indicator); +EXPORT_SYMBOL_GPL(rtas_set_indicator); /* * Ignoring RTAS extended delay @@ -714,6 +714,7 @@ /* Must be in the RMO region, so we place it here */ static char rtas_os_term_buf[2048]; +static s32 ibm_os_term_token = RTAS_UNKNOWN_SERVICE; void rtas_os_term(char *str) { @@ -725,16 +726,20 @@ * this property may terminate the partition which we want to avoid * since it interferes with panic_timeout. */ - if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") || - RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term")) + if (ibm_os_term_token == RTAS_UNKNOWN_SERVICE) return; snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str); + /* + * Keep calling as long as RTAS returns a "try again" status, + * but don't use rtas_busy_delay(), which potentially + * schedules. + */ do { - status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL, + status = rtas_call(ibm_os_term_token, 1, 1, NULL, __pa(rtas_os_term_buf)); - } while (rtas_busy_delay(status)); + } while (rtas_busy_delay_time(status)); if (status != 0) printk(KERN_EMERG "ibm,os-term call failed %d\n", status); @@ -842,96 +847,6 @@ __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1); } -enum rtas_cpu_state { - DOWN, - UP, -}; - -#ifndef CONFIG_SMP -static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, - cpumask_var_t cpus) -{ - if (!cpumask_empty(cpus)) { - cpumask_clear(cpus); - return -EINVAL; - } else - return 0; -} -#else -/* On return cpumask will be altered to indicate CPUs changed. - * CPUs with states changed will be set in the mask, - * CPUs with status unchanged will be unset in the mask. */ -static int rtas_cpu_state_change_mask(enum rtas_cpu_state state, - cpumask_var_t cpus) -{ - int cpu; - int cpuret = 0; - int ret = 0; - - if (cpumask_empty(cpus)) - return 0; - - for_each_cpu(cpu, cpus) { - struct device *dev = get_cpu_device(cpu); - - switch (state) { - case DOWN: - cpuret = device_offline(dev); - break; - case UP: - cpuret = device_online(dev); - break; - } - if (cpuret < 0) { - pr_debug("%s: cpu_%s for cpu#%d returned %d.\n", - __func__, - ((state == UP) ? "up" : "down"), - cpu, cpuret); - if (!ret) - ret = cpuret; - if (state == UP) { - /* clear bits for unchanged cpus, return */ - cpumask_shift_right(cpus, cpus, cpu); - cpumask_shift_left(cpus, cpus, cpu); - break; - } else { - /* clear bit for unchanged cpu, continue */ - cpumask_clear_cpu(cpu, cpus); - } - } - cond_resched(); - } - - return ret; -} -#endif - -int rtas_online_cpus_mask(cpumask_var_t cpus) -{ - int ret; - - ret = rtas_cpu_state_change_mask(UP, cpus); - - if (ret) { - cpumask_var_t tmp_mask; - - if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL)) - return ret; - - /* Use tmp_mask to preserve cpus mask from first failure */ - cpumask_copy(tmp_mask, cpus); - rtas_offline_cpus_mask(tmp_mask); - free_cpumask_var(tmp_mask); - } - - return ret; -} - -int rtas_offline_cpus_mask(cpumask_var_t cpus) -{ - return rtas_cpu_state_change_mask(DOWN, cpus); -} - int rtas_ibm_suspend_me(u64 handle) { long state; @@ -939,8 +854,6 @@ unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; struct rtas_suspend_me_data data; DECLARE_COMPLETION_ONSTACK(done); - cpumask_var_t offline_mask; - int cpuret; if (!rtas_service_present("ibm,suspend-me")) return -ENOSYS; @@ -961,9 +874,6 @@ return -EIO; } - if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) - return -ENOMEM; - atomic_set(&data.working, 0); atomic_set(&data.done, 0); atomic_set(&data.error, 0); @@ -972,24 +882,8 @@ lock_device_hotplug(); - /* All present CPUs must be online */ - cpumask_andnot(offline_mask, cpu_present_mask, cpu_online_mask); - cpuret = rtas_online_cpus_mask(offline_mask); - if (cpuret) { - pr_err("%s: Could not bring present CPUs online.\n", __func__); - atomic_set(&data.error, cpuret); - goto out; - } - cpu_hotplug_disable(); - /* Check if we raced with a CPU-Offline Operation */ - if (!cpumask_equal(cpu_present_mask, cpu_online_mask)) { - pr_info("%s: Raced against a concurrent CPU-Offline\n", __func__); - atomic_set(&data.error, -EAGAIN); - goto out_hotplug_enable; - } - /* Call function on all CPUs. One of us will make the * rtas call */ @@ -1000,18 +894,11 @@ if (atomic_read(&data.error) != 0) printk(KERN_ERR "Error doing global join\n"); -out_hotplug_enable: - cpu_hotplug_enable(); - /* Take down CPUs not online prior to suspend */ - cpuret = rtas_offline_cpus_mask(offline_mask); - if (cpuret) - pr_warn("%s: Could not restore CPUs to offline state.\n", - __func__); + cpu_hotplug_enable(); -out: unlock_device_hotplug(); - free_cpumask_var(offline_mask); + return atomic_read(&data.error); } #else /* CONFIG_PPC_PSERIES */ @@ -1058,6 +945,156 @@ return NULL; } +#ifdef CONFIG_PPC_RTAS_FILTER + +/* + * The sys_rtas syscall, as originally designed, allows root to pass + * arbitrary physical addresses to RTAS calls. A number of RTAS calls + * can be abused to write to arbitrary memory and do other things that + * are potentially harmful to system integrity, and thus should only + * be used inside the kernel and not exposed to userspace. + * + * All known legitimate users of the sys_rtas syscall will only ever + * pass addresses that fall within the RMO buffer, and use a known + * subset of RTAS calls. + * + * Accordingly, we filter RTAS requests to check that the call is + * permitted, and that provided pointers fall within the RMO buffer. + * The rtas_filters list contains an entry for each permitted call, + * with the indexes of the parameters which are expected to contain + * addresses and sizes of buffers allocated inside the RMO buffer. + */ +struct rtas_filter { + const char *name; + int token; + /* Indexes into the args buffer, -1 if not used */ + int buf_idx1; + int size_idx1; + int buf_idx2; + int size_idx2; + + int fixed_size; +}; + +static struct rtas_filter rtas_filters[] __ro_after_init = { + { "ibm,activate-firmware", -1, -1, -1, -1, -1 }, + { "ibm,configure-connector", -1, 0, -1, 1, -1, 4096 }, /* Special cased */ + { "display-character", -1, -1, -1, -1, -1 }, + { "ibm,display-message", -1, 0, -1, -1, -1 }, + { "ibm,errinjct", -1, 2, -1, -1, -1, 1024 }, + { "ibm,close-errinjct", -1, -1, -1, -1, -1 }, + { "ibm,open-errinjct", -1, -1, -1, -1, -1 }, + { "ibm,get-config-addr-info2", -1, -1, -1, -1, -1 }, + { "ibm,get-dynamic-sensor-state", -1, 1, -1, -1, -1 }, + { "ibm,get-indices", -1, 2, 3, -1, -1 }, + { "get-power-level", -1, -1, -1, -1, -1 }, + { "get-sensor-state", -1, -1, -1, -1, -1 }, + { "ibm,get-system-parameter", -1, 1, 2, -1, -1 }, + { "get-time-of-day", -1, -1, -1, -1, -1 }, + { "ibm,get-vpd", -1, 0, -1, 1, 2 }, + { "ibm,lpar-perftools", -1, 2, 3, -1, -1 }, + { "ibm,platform-dump", -1, 4, 5, -1, -1 }, /* Special cased */ + { "ibm,read-slot-reset-state", -1, -1, -1, -1, -1 }, + { "ibm,scan-log-dump", -1, 0, 1, -1, -1 }, + { "ibm,set-dynamic-indicator", -1, 2, -1, -1, -1 }, + { "ibm,set-eeh-option", -1, -1, -1, -1, -1 }, + { "set-indicator", -1, -1, -1, -1, -1 }, + { "set-power-level", -1, -1, -1, -1, -1 }, + { "set-time-for-power-on", -1, -1, -1, -1, -1 }, + { "ibm,set-system-parameter", -1, 1, -1, -1, -1 }, + { "set-time-of-day", -1, -1, -1, -1, -1 }, + { "ibm,suspend-me", -1, -1, -1, -1, -1 }, + { "ibm,update-nodes", -1, 0, -1, -1, -1, 4096 }, + { "ibm,update-properties", -1, 0, -1, -1, -1, 4096 }, + { "ibm,physical-attestation", -1, 0, 1, -1, -1 }, +}; + +static bool in_rmo_buf(u32 base, u32 end) +{ + return base >= rtas_rmo_buf && + base < (rtas_rmo_buf + RTAS_RMOBUF_MAX) && + base <= end && + end >= rtas_rmo_buf && + end < (rtas_rmo_buf + RTAS_RMOBUF_MAX); +} + +static bool block_rtas_call(int token, int nargs, + struct rtas_args *args) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) { + struct rtas_filter *f = &rtas_filters[i]; + u32 base, size, end; + + if (token != f->token) + continue; + + if (f->buf_idx1 != -1) { + base = be32_to_cpu(args->args[f->buf_idx1]); + if (f->size_idx1 != -1) + size = be32_to_cpu(args->args[f->size_idx1]); + else if (f->fixed_size) + size = f->fixed_size; + else + size = 1; + + end = base + size - 1; + + /* + * Special case for ibm,platform-dump - NULL buffer + * address is used to indicate end of dump processing + */ + if (!strcmp(f->name, "ibm,platform-dump") && + base == 0) + return false; + + if (!in_rmo_buf(base, end)) + goto err; + } + + if (f->buf_idx2 != -1) { + base = be32_to_cpu(args->args[f->buf_idx2]); + if (f->size_idx2 != -1) + size = be32_to_cpu(args->args[f->size_idx2]); + else if (f->fixed_size) + size = f->fixed_size; + else + size = 1; + end = base + size - 1; + + /* + * Special case for ibm,configure-connector where the + * address can be 0 + */ + if (!strcmp(f->name, "ibm,configure-connector") && + base == 0) + return false; + + if (!in_rmo_buf(base, end)) + goto err; + } + + return false; + } + +err: + pr_err_ratelimited("sys_rtas: RTAS call blocked - exploit attempt?\n"); + pr_err_ratelimited("sys_rtas: token=0x%x, nargs=%d (called by %s)\n", + token, nargs, current->comm); + return true; +} + +#else + +static bool block_rtas_call(int token, int nargs, + struct rtas_args *args) +{ + return false; +} + +#endif /* CONFIG_PPC_RTAS_FILTER */ + /* We assume to be passed big endian arguments */ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) { @@ -1095,6 +1132,9 @@ args.rets = &args.args[nargs]; memset(args.rets, 0, nret * sizeof(rtas_arg_t)); + if (block_rtas_call(token, nargs, &args)) + return -EINVAL; + /* Need to handle ibm,suspend_me call specially */ if (token == ibm_suspend_me_token) { @@ -1156,6 +1196,9 @@ unsigned long rtas_region = RTAS_INSTANTIATE_MAX; u32 base, size, entry; int no_base, no_size, no_entry; +#ifdef CONFIG_PPC_RTAS_FILTER + int i; +#endif /* Get RTAS dev node and fill up our "rtas" structure with infos * about it. @@ -1177,6 +1220,13 @@ no_entry = of_property_read_u32(rtas.dev, "linux,rtas-entry", &entry); rtas.entry = no_entry ? rtas.base : entry; + /* + * Discover these now to avoid device tree lookups in the + * panic path. + */ + if (of_property_read_bool(rtas.dev, "ibm,extended-os-term")) + ibm_os_term_token = rtas_token("ibm,os-term"); + /* If RTAS was found, allocate the RMO buffer for it and look for * the stop-self token if any */ @@ -1195,6 +1245,12 @@ #ifdef CONFIG_RTAS_ERROR_LOGGING rtas_last_error_token = rtas_token("rtas-last-error"); #endif + +#ifdef CONFIG_PPC_RTAS_FILTER + for (i = 0; i < ARRAY_SIZE(rtas_filters); i++) { + rtas_filters[i].token = rtas_token(rtas_filters[i].name); + } +#endif } int __init early_init_dt_scan_rtas(unsigned long node, @@ -1209,6 +1265,12 @@ entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); +#ifdef CONFIG_PPC64 + /* need this feature to decide the crashkernel offset */ + if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL)) + powerpc_firmware_features |= FW_FEATURE_LPAR; +#endif + if (basep && entryp && sizep) { rtas.base = *basep; rtas.entry = *entryp; --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/rtas_flash.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/rtas_flash.c @@ -710,9 +710,9 @@ if (!rtas_validate_flash_data.buf) return -ENOMEM; - flash_block_cache = kmem_cache_create("rtas_flash_cache", - RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, - NULL); + flash_block_cache = kmem_cache_create_usercopy("rtas_flash_cache", + RTAS_BLK_SIZE, RTAS_BLK_SIZE, + 0, 0, RTAS_BLK_SIZE, NULL); if (!flash_block_cache) { printk(KERN_ERR "%s: failed to create block cache\n", __func__); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/secure_boot.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/secure_boot.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 IBM Corporation + * Author: Nayna Jain + */ +#include +#include +#include + +static struct device_node *get_ppc_fw_sb_node(void) +{ + static const struct of_device_id ids[] = { + { .compatible = "ibm,secureboot", }, + { .compatible = "ibm,secureboot-v1", }, + { .compatible = "ibm,secureboot-v2", }, + {}, + }; + + return of_find_matching_node(NULL, ids); +} + +bool is_ppc_secureboot_enabled(void) +{ + struct device_node *node; + bool enabled = false; + + node = get_ppc_fw_sb_node(); + enabled = of_property_read_bool(node, "os-secureboot-enforcing"); + + of_node_put(node); + + pr_info("Secure boot mode %s\n", enabled ? "enabled" : "disabled"); + + return enabled; +} + +bool is_ppc_trustedboot_enabled(void) +{ + struct device_node *node; + bool enabled = false; + + node = get_ppc_fw_sb_node(); + enabled = of_property_read_bool(node, "trusted-enabled"); + + of_node_put(node); + + pr_info("Trusted boot mode %s\n", enabled ? "enabled" : "disabled"); + + return enabled; +} --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/security.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/security.c @@ -16,7 +16,7 @@ #include -unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT; +u64 powerpc_security_features __read_mostly = SEC_FTR_DEFAULT; enum count_cache_flush_type { COUNT_CACHE_FLUSH_NONE = 0x1, @@ -24,6 +24,7 @@ COUNT_CACHE_FLUSH_HW = 0x4, }; static enum count_cache_flush_type count_cache_flush_type = COUNT_CACHE_FLUSH_NONE; +static bool link_stack_flush_enabled; bool barrier_nospec_enabled; static bool no_nospec; @@ -108,7 +109,7 @@ static __init int security_feature_debugfs_init(void) { debugfs_create_x64("security_features", 0400, powerpc_debugfs_root, - (u64 *)&powerpc_security_features); + &powerpc_security_features); return 0; } device_initcall(security_feature_debugfs_init); @@ -141,32 +142,33 @@ thread_priv = security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV); - if (rfi_flush || thread_priv) { + if (rfi_flush) { struct seq_buf s; seq_buf_init(&s, buf, PAGE_SIZE - 1); - seq_buf_printf(&s, "Mitigation: "); - - if (rfi_flush) - seq_buf_printf(&s, "RFI Flush"); - - if (rfi_flush && thread_priv) - seq_buf_printf(&s, ", "); - + seq_buf_printf(&s, "Mitigation: RFI Flush"); if (thread_priv) - seq_buf_printf(&s, "L1D private per thread"); + seq_buf_printf(&s, ", L1D private per thread"); seq_buf_printf(&s, "\n"); return s.len; } + if (thread_priv) + return sprintf(buf, "Vulnerable: L1D private per thread\n"); + if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)) return sprintf(buf, "Not affected\n"); return sprintf(buf, "Vulnerable\n"); } + +ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_meltdown(dev, attr, buf); +} #endif ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) @@ -212,11 +214,19 @@ if (ccd) seq_buf_printf(&s, "Indirect branch cache disabled"); + + if (link_stack_flush_enabled) + seq_buf_printf(&s, ", Software link stack flush"); + } else if (count_cache_flush_type != COUNT_CACHE_FLUSH_NONE) { seq_buf_printf(&s, "Mitigation: Software count cache flush"); if (count_cache_flush_type == COUNT_CACHE_FLUSH_HW) seq_buf_printf(&s, " (hardware accelerated)"); + + if (link_stack_flush_enabled) + seq_buf_printf(&s, ", Software link stack flush"); + } else if (btb_flush_enabled) { seq_buf_printf(&s, "Mitigation: Branch predictor state flush"); } else { @@ -246,6 +256,11 @@ early_param("no_stf_barrier", handle_no_stf_barrier); +enum stf_barrier_type stf_barrier_type_get(void) +{ + return stf_enabled_flush_types; +} + /* This is the generic flag used by other architectures */ static int __init handle_ssbd(char *p) { @@ -377,18 +392,49 @@ device_initcall(stf_barrier_debugfs_init); #endif /* CONFIG_DEBUG_FS */ +static void no_count_cache_flush(void) +{ + count_cache_flush_type = COUNT_CACHE_FLUSH_NONE; + pr_info("count-cache-flush: software flush disabled.\n"); +} + static void toggle_count_cache_flush(bool enable) { - if (!enable || !security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) { + if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE) && + !security_ftr_enabled(SEC_FTR_FLUSH_LINK_STACK)) + enable = false; + + if (!enable) { patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP); - count_cache_flush_type = COUNT_CACHE_FLUSH_NONE; - pr_info("count-cache-flush: software flush disabled.\n"); +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP); +#endif + pr_info("link-stack-flush: software flush disabled.\n"); + link_stack_flush_enabled = false; + no_count_cache_flush(); return; } + // This enables the branch from _switch to flush_count_cache patch_branch_site(&patch__call_flush_count_cache, (u64)&flush_count_cache, BRANCH_SET_LINK); +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + // This enables the branch from guest_exit_cont to kvm_flush_link_stack + patch_branch_site(&patch__call_kvm_flush_link_stack, + (u64)&kvm_flush_link_stack, BRANCH_SET_LINK); +#endif + + pr_info("link-stack-flush: software flush enabled.\n"); + link_stack_flush_enabled = true; + + // If we just need to flush the link stack, patch an early return + if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) { + patch_instruction_site(&patch__flush_link_stack_return, PPC_INST_BLR); + no_count_cache_flush(); + return; + } + if (!security_ftr_enabled(SEC_FTR_BCCTR_FLUSH_ASSIST)) { count_cache_flush_type = COUNT_CACHE_FLUSH_SW; pr_info("count-cache-flush: full software flush sequence enabled.\n"); @@ -407,11 +453,20 @@ if (no_spectrev2 || cpu_mitigations_off()) { if (security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED) || security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED)) - pr_warn("Spectre v2 mitigations not under software control, can't disable\n"); + pr_warn("Spectre v2 mitigations not fully under software control, can't disable\n"); enable = false; } + /* + * There's no firmware feature flag/hypervisor bit to tell us we need to + * flush the link stack on context switch. So we set it here if we see + * either of the Spectre v2 mitigations that aim to protect userspace. + */ + if (security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED) || + security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) + security_ftr_set(SEC_FTR_FLUSH_LINK_STACK); + toggle_count_cache_flush(enable); } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/secvar-ops.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/secvar-ops.c @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 IBM Corporation + * Author: Nayna Jain + * + * This file initializes secvar operations for PowerPC Secureboot + */ + +#include +#include + +const struct secvar_operations *secvar_ops __ro_after_init; + +void set_secvar_ops(const struct secvar_operations *ops) +{ + secvar_ops = ops; +} --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/secvar-sysfs.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/secvar-sysfs.c @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 IBM Corporation + * + * This code exposes secure variables to user via sysfs + */ + +#define pr_fmt(fmt) "secvar-sysfs: "fmt + +#include +#include +#include +#include +#include + +#define NAME_MAX_SIZE 1024 + +static struct kobject *secvar_kobj; +static struct kset *secvar_kset; + +static ssize_t format_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + ssize_t rc = 0; + struct device_node *node; + const char *format; + + node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); + if (!of_device_is_available(node)) + return -ENODEV; + + rc = of_property_read_string(node, "format", &format); + if (rc) + return rc; + + rc = sprintf(buf, "%s\n", format); + + of_node_put(node); + + return rc; +} + + +static ssize_t size_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + uint64_t dsize; + int rc; + + rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); + if (rc) { + pr_err("Error retrieving %s variable size %d\n", kobj->name, + rc); + return rc; + } + + return sprintf(buf, "%llu\n", dsize); +} + +static ssize_t data_read(struct file *filep, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, + size_t count) +{ + uint64_t dsize; + char *data; + int rc; + + rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, NULL, &dsize); + if (rc) { + pr_err("Error getting %s variable size %d\n", kobj->name, rc); + return rc; + } + pr_debug("dsize is %llu\n", dsize); + + data = kzalloc(dsize, GFP_KERNEL); + if (!data) + return -ENOMEM; + + rc = secvar_ops->get(kobj->name, strlen(kobj->name) + 1, data, &dsize); + if (rc) { + pr_err("Error getting %s variable %d\n", kobj->name, rc); + goto data_fail; + } + + rc = memory_read_from_buffer(buf, count, &off, data, dsize); + +data_fail: + kfree(data); + return rc; +} + +static ssize_t update_write(struct file *filep, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t off, + size_t count) +{ + int rc; + + pr_debug("count is %ld\n", count); + rc = secvar_ops->set(kobj->name, strlen(kobj->name) + 1, buf, count); + if (rc) { + pr_err("Error setting the %s variable %d\n", kobj->name, rc); + return rc; + } + + return count; +} + +static struct kobj_attribute format_attr = __ATTR_RO(format); + +static struct kobj_attribute size_attr = __ATTR_RO(size); + +static struct bin_attribute data_attr = __BIN_ATTR_RO(data, 0); + +static struct bin_attribute update_attr = __BIN_ATTR_WO(update, 0); + +static struct bin_attribute *secvar_bin_attrs[] = { + &data_attr, + &update_attr, + NULL, +}; + +static struct attribute *secvar_attrs[] = { + &size_attr.attr, + NULL, +}; + +static const struct attribute_group secvar_attr_group = { + .attrs = secvar_attrs, + .bin_attrs = secvar_bin_attrs, +}; +__ATTRIBUTE_GROUPS(secvar_attr); + +static struct kobj_type secvar_ktype = { + .sysfs_ops = &kobj_sysfs_ops, + .default_groups = secvar_attr_groups, +}; + +static int update_kobj_size(void) +{ + + struct device_node *node; + u64 varsize; + int rc = 0; + + node = of_find_compatible_node(NULL, NULL, "ibm,secvar-backend"); + if (!of_device_is_available(node)) { + rc = -ENODEV; + goto out; + } + + rc = of_property_read_u64(node, "max-var-size", &varsize); + if (rc) + goto out; + + data_attr.size = varsize; + update_attr.size = varsize; + +out: + of_node_put(node); + + return rc; +} + +static int secvar_sysfs_load(void) +{ + char *name; + uint64_t namesize = 0; + struct kobject *kobj; + int rc; + + name = kzalloc(NAME_MAX_SIZE, GFP_KERNEL); + if (!name) + return -ENOMEM; + + do { + rc = secvar_ops->get_next(name, &namesize, NAME_MAX_SIZE); + if (rc) { + if (rc != -ENOENT) + pr_err("error getting secvar from firmware %d\n", + rc); + break; + } + + kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + if (!kobj) { + rc = -ENOMEM; + break; + } + + kobject_init(kobj, &secvar_ktype); + + rc = kobject_add(kobj, &secvar_kset->kobj, "%s", name); + if (rc) { + pr_warn("kobject_add error %d for attribute: %s\n", rc, + name); + kobject_put(kobj); + kobj = NULL; + } + + if (kobj) + kobject_uevent(kobj, KOBJ_ADD); + + } while (!rc); + + kfree(name); + return rc; +} + +static int secvar_sysfs_init(void) +{ + int rc; + + if (!secvar_ops) { + pr_warn("secvar: failed to retrieve secvar operations.\n"); + return -ENODEV; + } + + secvar_kobj = kobject_create_and_add("secvar", firmware_kobj); + if (!secvar_kobj) { + pr_err("secvar: Failed to create firmware kobj\n"); + return -ENOMEM; + } + + rc = sysfs_create_file(secvar_kobj, &format_attr.attr); + if (rc) { + kobject_put(secvar_kobj); + return -ENOMEM; + } + + secvar_kset = kset_create_and_add("vars", NULL, secvar_kobj); + if (!secvar_kset) { + pr_err("secvar: sysfs kobject registration failed.\n"); + kobject_put(secvar_kobj); + return -ENOMEM; + } + + rc = update_kobj_size(); + if (rc) { + pr_err("Cannot read the size of the attribute\n"); + return rc; + } + + secvar_sysfs_load(); + + return 0; +} + +late_initcall(secvar_sysfs_init); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/setup-common.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/setup-common.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,7 @@ #include #include #include +#include #include "setup.h" @@ -855,6 +857,16 @@ */ initialize_cache_info(); + /* + * Lock down the kernel if booted in secure mode. This is required to + * maintain kernel integrity. + */ + if (IS_ENABLED(CONFIG_LOCK_DOWN_IN_SECURE_BOOT)) { + if (is_ppc_secureboot_enabled()) + security_lock_kernel_down("PowerNV Secure Boot mode", + LOCKDOWN_INTEGRITY_MAX); + } + /* Initialize RTAS if available. */ rtas_initialize(); @@ -903,8 +915,6 @@ /* On BookE, setup per-core TLB data structures. */ setup_tlb_core_data(); - - smp_release_cpus(); #endif /* Print various info about the machine that has been gathered so far. */ @@ -925,6 +935,8 @@ exc_lvl_early_init(); emergency_stack_init(); + smp_release_cpus(); + initmem_init(); early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/setup_64.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/setup_64.c @@ -290,18 +290,36 @@ /* -------- printk is _NOT_ safe to use here ! ------- */ - /* Try new device tree based feature discovery ... */ - if (!dt_cpu_ftrs_init(__va(dt_ptr))) - /* Otherwise use the old style CPU table */ - identify_cpu(0, mfspr(SPRN_PVR)); - - /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ + /* + * Assume we're on cpu 0 for now. + * + * We need to load a PACA very early for a few reasons. + * + * The stack protector canary is stored in the paca, so as soon as we + * call any stack protected code we need r13 pointing somewhere valid. + * + * If we are using kcov it will call in_task() in its instrumentation, + * which relies on the current task from the PACA. + * + * dt_cpu_ftrs_init() calls into generic OF/fdt code, as well as + * printk(), which can trigger both stack protector and kcov. + * + * percpu variables and spin locks also use the paca. + * + * So set up a temporary paca. It will be replaced below once we know + * what CPU we are on. + */ initialise_paca(&boot_paca, 0); setup_paca(&boot_paca); fixup_boot_paca(); /* -------- printk is now safe to use ------- */ + /* Try new device tree based feature discovery ... */ + if (!dt_cpu_ftrs_init(__va(dt_ptr))) + /* Otherwise use the old style CPU table */ + identify_cpu(0, mfspr(SPRN_PVR)); + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); @@ -523,6 +541,8 @@ lsizep = of_get_property(np, propnames[3], NULL); if (bsizep == NULL) bsizep = lsizep; + if (lsizep == NULL) + lsizep = bsizep; if (lsizep != NULL) lsize = be32_to_cpu(*lsizep); if (bsizep != NULL) @@ -839,7 +859,13 @@ static enum l1d_flush_type enabled_flush_types; static void *l1d_flush_fallback_area; static bool no_rfi_flush; +static bool no_entry_flush; +static bool no_uaccess_flush; bool rfi_flush; +bool entry_flush; +bool uaccess_flush; +DEFINE_STATIC_KEY_FALSE(uaccess_flush_key); +EXPORT_SYMBOL(uaccess_flush_key); static int __init handle_no_rfi_flush(char *p) { @@ -849,6 +875,22 @@ } early_param("no_rfi_flush", handle_no_rfi_flush); +static int __init handle_no_entry_flush(char *p) +{ + pr_info("entry-flush: disabled on command line."); + no_entry_flush = true; + return 0; +} +early_param("no_entry_flush", handle_no_entry_flush); + +static int __init handle_no_uaccess_flush(char *p) +{ + pr_info("uaccess-flush: disabled on command line."); + no_uaccess_flush = true; + return 0; +} +early_param("no_uaccess_flush", handle_no_uaccess_flush); + /* * The RFI flush is not KPTI, but because users will see doco that says to use * nopti we hijack that option here to also disable the RFI flush. @@ -880,6 +922,32 @@ rfi_flush = enable; } +void entry_flush_enable(bool enable) +{ + if (enable) { + do_entry_flush_fixups(enabled_flush_types); + on_each_cpu(do_nothing, NULL, 1); + } else { + do_entry_flush_fixups(L1D_FLUSH_NONE); + } + + entry_flush = enable; +} + +void uaccess_flush_enable(bool enable) +{ + if (enable) { + do_uaccess_flush_fixups(enabled_flush_types); + static_branch_enable(&uaccess_flush_key); + on_each_cpu(do_nothing, NULL, 1); + } else { + static_branch_disable(&uaccess_flush_key); + do_uaccess_flush_fixups(L1D_FLUSH_NONE); + } + + uaccess_flush = enable; +} + static void __ref init_fallback_flush(void) { u64 l1d_size, limit; @@ -938,10 +1006,28 @@ enabled_flush_types = types; - if (!no_rfi_flush && !cpu_mitigations_off()) + if (!cpu_mitigations_off() && !no_rfi_flush) rfi_flush_enable(enable); } +void setup_entry_flush(bool enable) +{ + if (cpu_mitigations_off()) + return; + + if (!no_entry_flush) + entry_flush_enable(enable); +} + +void setup_uaccess_flush(bool enable) +{ + if (cpu_mitigations_off()) + return; + + if (!no_uaccess_flush) + uaccess_flush_enable(enable); +} + #ifdef CONFIG_DEBUG_FS static int rfi_flush_set(void *data, u64 val) { @@ -969,9 +1055,63 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_rfi_flush, rfi_flush_get, rfi_flush_set, "%llu\n"); +static int entry_flush_set(void *data, u64 val) +{ + bool enable; + + if (val == 1) + enable = true; + else if (val == 0) + enable = false; + else + return -EINVAL; + + /* Only do anything if we're changing state */ + if (enable != entry_flush) + entry_flush_enable(enable); + + return 0; +} + +static int entry_flush_get(void *data, u64 *val) +{ + *val = entry_flush ? 1 : 0; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_entry_flush, entry_flush_get, entry_flush_set, "%llu\n"); + +static int uaccess_flush_set(void *data, u64 val) +{ + bool enable; + + if (val == 1) + enable = true; + else if (val == 0) + enable = false; + else + return -EINVAL; + + /* Only do anything if we're changing state */ + if (enable != uaccess_flush) + uaccess_flush_enable(enable); + + return 0; +} + +static int uaccess_flush_get(void *data, u64 *val) +{ + *val = uaccess_flush ? 1 : 0; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(fops_uaccess_flush, uaccess_flush_get, uaccess_flush_set, "%llu\n"); + static __init int rfi_flush_debugfs_init(void) { debugfs_create_file("rfi_flush", 0600, powerpc_debugfs_root, NULL, &fops_rfi_flush); + debugfs_create_file("entry_flush", 0600, powerpc_debugfs_root, NULL, &fops_entry_flush); + debugfs_create_file("uaccess_flush", 0600, powerpc_debugfs_root, NULL, &fops_uaccess_flush); return 0; } device_initcall(rfi_flush_debugfs_init); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/signal.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/signal.c @@ -200,14 +200,27 @@ * normal/non-checkpointed stack pointer. */ + unsigned long ret = tsk->thread.regs->gpr[1]; + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM BUG_ON(tsk != current); if (MSR_TM_ACTIVE(tsk->thread.regs->msr)) { + preempt_disable(); tm_reclaim_current(TM_CAUSE_SIGNAL); if (MSR_TM_TRANSACTIONAL(tsk->thread.regs->msr)) - return tsk->thread.ckpt_regs.gpr[1]; + ret = tsk->thread.ckpt_regs.gpr[1]; + + /* + * If we treclaim, we must clear the current thread's TM bits + * before re-enabling preemption. Otherwise we might be + * preempted and have the live MSR[TS] changed behind our back + * (tm_recheckpoint_new_task() would recheckpoint). Besides, we + * enter the signal handler in non-transactional state. + */ + tsk->thread.regs->msr &= ~MSR_TS_MASK; + preempt_enable(); } #endif - return tsk->thread.regs->gpr[1]; + return ret; } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/signal_32.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/signal_32.c @@ -489,19 +489,11 @@ */ static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame, - struct mcontext __user *tm_frame, int sigret) + struct mcontext __user *tm_frame, int sigret, + unsigned long msr) { - unsigned long msr = regs->msr; - WARN_ON(tm_suspend_disabled); - /* Remove TM bits from thread's MSR. The MSR in the sigcontext - * just indicates to userland that we were doing a transaction, but we - * don't want to return in transactional state. This also ensures - * that flush_fp_to_thread won't set TIF_RESTORE_TM again. - */ - regs->msr &= ~MSR_TS_MASK; - /* Save both sets of general registers */ if (save_general_regs(¤t->thread.ckpt_regs, frame) || save_general_regs(regs, tm_frame)) @@ -912,6 +904,10 @@ int sigret; unsigned long tramp; struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + /* Save the thread's msr before get_tm_stackpointer() changes it */ + unsigned long msr = regs->msr; +#endif BUG_ON(tsk != current); @@ -944,13 +940,13 @@ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM tm_frame = &rt_sf->uc_transact.uc_mcontext; - if (MSR_TM_ACTIVE(regs->msr)) { + if (MSR_TM_ACTIVE(msr)) { if (__put_user((unsigned long)&rt_sf->uc_transact, &rt_sf->uc.uc_link) || __put_user((unsigned long)tm_frame, &rt_sf->uc_transact.uc_regs)) goto badframe; - if (save_tm_user_regs(regs, frame, tm_frame, sigret)) + if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr)) goto badframe; } else @@ -1369,6 +1365,10 @@ int sigret; unsigned long tramp; struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + /* Save the thread's msr before get_tm_stackpointer() changes it */ + unsigned long msr = regs->msr; +#endif BUG_ON(tsk != current); @@ -1402,9 +1402,9 @@ #ifdef CONFIG_PPC_TRANSACTIONAL_MEM tm_mctx = &frame->mctx_transact; - if (MSR_TM_ACTIVE(regs->msr)) { + if (MSR_TM_ACTIVE(msr)) { if (save_tm_user_regs(regs, &frame->mctx, &frame->mctx_transact, - sigret)) + sigret, msr)) goto badframe; } else --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/signal_64.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/signal_64.c @@ -192,7 +192,8 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc, struct sigcontext __user *tm_sc, struct task_struct *tsk, - int signr, sigset_t *set, unsigned long handler) + int signr, sigset_t *set, unsigned long handler, + unsigned long msr) { /* When CONFIG_ALTIVEC is set, we _always_ setup v_regs even if the * process never used altivec yet (MSR_VEC is zero in pt_regs of @@ -207,12 +208,11 @@ elf_vrreg_t __user *tm_v_regs = sigcontext_vmx_regs(tm_sc); #endif struct pt_regs *regs = tsk->thread.regs; - unsigned long msr = tsk->thread.regs->msr; long err = 0; BUG_ON(tsk != current); - BUG_ON(!MSR_TM_ACTIVE(regs->msr)); + BUG_ON(!MSR_TM_ACTIVE(msr)); WARN_ON(tm_suspend_disabled); @@ -222,13 +222,6 @@ */ msr |= tsk->thread.ckpt_regs.msr & (MSR_FP | MSR_VEC | MSR_VSX); - /* Remove TM bits from thread's MSR. The MSR in the sigcontext - * just indicates to userland that we were doing a transaction, but we - * don't want to return in transactional state. This also ensures - * that flush_fp_to_thread won't set TIF_RESTORE_TM again. - */ - regs->msr &= ~MSR_TS_MASK; - #ifdef CONFIG_ALTIVEC err |= __put_user(v_regs, &sc->v_regs); err |= __put_user(tm_v_regs, &tm_sc->v_regs); @@ -480,8 +473,10 @@ err |= __get_user(tsk->thread.ckpt_regs.ccr, &sc->gp_regs[PT_CCR]); + /* Don't allow userspace to set the trap value */ + regs->trap = 0; + /* These regs are not checkpointed; they can go in 'regs'. */ - err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); @@ -824,6 +819,10 @@ unsigned long newsp = 0; long err = 0; struct pt_regs *regs = tsk->thread.regs; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + /* Save the thread's msr before get_tm_stackpointer() changes it */ + unsigned long msr = regs->msr; +#endif BUG_ON(tsk != current); @@ -841,7 +840,7 @@ err |= __put_user(0, &frame->uc.uc_flags); err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]); #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - if (MSR_TM_ACTIVE(regs->msr)) { + if (MSR_TM_ACTIVE(msr)) { /* The ucontext_t passed to userland points to the second * ucontext_t (for transactional state) with its uc_link ptr. */ @@ -849,7 +848,8 @@ err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext, &frame->uc_transact.uc_mcontext, tsk, ksig->sig, NULL, - (unsigned long)ksig->ka.sa.sa_handler); + (unsigned long)ksig->ka.sa.sa_handler, + msr); } else #endif { --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/smp.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/smp.c @@ -583,11 +583,43 @@ #endif #ifdef CONFIG_NMI_IPI +static void crash_stop_this_cpu(struct pt_regs *regs) +#else +static void crash_stop_this_cpu(void *dummy) +#endif +{ + /* + * Just busy wait here and avoid marking CPU as offline to ensure + * register data is captured appropriately. + */ + while (1) + cpu_relax(); +} + +void crash_smp_send_stop(void) +{ + static bool stopped = false; + + if (stopped) + return; + + stopped = true; + +#ifdef CONFIG_NMI_IPI + smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000); +#else + smp_call_function(crash_stop_this_cpu, NULL, 0); +#endif /* CONFIG_NMI_IPI */ +} + +#ifdef CONFIG_NMI_IPI static void nmi_stop_this_cpu(struct pt_regs *regs) { /* * IRQs are already hard disabled by the smp_handle_nmi_ipi. */ + set_cpu_online(smp_processor_id(), false); + spin_begin(); while (1) spin_cpu_relax(); @@ -603,6 +635,15 @@ static void stop_this_cpu(void *dummy) { hard_irq_disable(); + + /* + * Offlining CPUs in stop_this_cpu can result in scheduler warnings, + * (see commit de6e5d38417e), but printk_safe_flush_on_panic() wants + * to know other CPUs are offline before it breaks locks to flush + * printk buffers, in case we panic()ed while holding the lock. + */ + set_cpu_online(smp_processor_id(), false); + spin_begin(); while (1) spin_cpu_relax(); @@ -1254,6 +1295,9 @@ vdso_getcpu_init(); #endif + set_numa_node(numa_cpu_lookup_table[cpu]); + set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); + /* Update topology CPU masks */ add_cpu_to_masks(cpu); @@ -1266,9 +1310,6 @@ if (!cpumask_equal(cpu_l2_cache_mask(cpu), sibling_mask(cpu))) shared_caches = true; - set_numa_node(numa_cpu_lookup_table[cpu]); - set_numa_mem(local_memory_node(numa_cpu_lookup_table[cpu])); - smp_wmb(); notify_cpu_starting(cpu); set_cpu_online(cpu, true); @@ -1285,10 +1326,12 @@ BUG(); } +#ifdef CONFIG_PROFILING int setup_profiling_timer(unsigned int multiplier) { return 0; } +#endif #ifdef CONFIG_SCHED_SMT /* cpumask of CPUs with asymetric SMT dependancy */ --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/stacktrace.c @@ -8,6 +8,7 @@ * Copyright 2018 Nick Piggin, Michael Ellerman, IBM Corp. */ +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -230,17 +232,31 @@ static void raise_backtrace_ipi(cpumask_t *mask) { + struct paca_struct *p; unsigned int cpu; + u64 delay_us; for_each_cpu(cpu, mask) { - if (cpu == smp_processor_id()) + if (cpu == smp_processor_id()) { handle_backtrace_ipi(NULL); - else - smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, 5 * USEC_PER_SEC); - } + continue; + } - for_each_cpu(cpu, mask) { - struct paca_struct *p = paca_ptrs[cpu]; + delay_us = 5 * USEC_PER_SEC; + + if (smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, delay_us)) { + // Now wait up to 5s for the other CPU to do its backtrace + while (cpumask_test_cpu(cpu, mask) && delay_us) { + udelay(1); + delay_us--; + } + + // Other CPU cleared itself from the mask + if (delay_us) + continue; + } + + p = paca_ptrs[cpu]; cpumask_clear_cpu(cpu, mask); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/swsusp_32.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/swsusp_32.S @@ -181,7 +181,7 @@ #ifdef CONFIG_ALTIVEC /* Stop pending alitvec streams and memory accesses */ BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif sync --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/swsusp_asm64.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/swsusp_asm64.S @@ -142,7 +142,7 @@ _GLOBAL(swsusp_arch_resume) /* Stop pending alitvec streams and memory accesses */ BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) sync --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/sysfs.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/sysfs.c @@ -31,29 +31,27 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); -/* - * SMT snooze delay stuff, 64-bit only for now - */ - #ifdef CONFIG_PPC64 -/* Time in microseconds we delay before sleeping in the idle loop */ -static DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 }; +/* + * Snooze delay has not been hooked up since 3fa8cad82b94 ("powerpc/pseries/cpuidle: + * smt-snooze-delay cleanup.") and has been broken even longer. As was foretold in + * 2014: + * + * "ppc64_util currently utilises it. Once we fix ppc64_util, propose to clean + * up the kernel code." + * + * powerpc-utils stopped using it as of 1.3.8. At some point in the future this + * code should be removed. + */ static ssize_t store_smt_snooze_delay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct cpu *cpu = container_of(dev, struct cpu, dev); - ssize_t ret; - long snooze; - - ret = sscanf(buf, "%ld", &snooze); - if (ret != 1) - return -EINVAL; - - per_cpu(smt_snooze_delay, cpu->dev.id) = snooze; + pr_warn_once("%s (%d) stored to unsupported smt_snooze_delay, which has no effect.\n", + current->comm, current->pid); return count; } @@ -61,9 +59,9 @@ struct device_attribute *attr, char *buf) { - struct cpu *cpu = container_of(dev, struct cpu, dev); - - return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->dev.id)); + pr_warn_once("%s (%d) read from unsupported smt_snooze_delay\n", + current->comm, current->pid); + return sprintf(buf, "100\n"); } static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay, @@ -71,16 +69,10 @@ static int __init setup_smt_snooze_delay(char *str) { - unsigned int cpu; - long snooze; - if (!cpu_has_feature(CPU_FTR_SMT)) return 1; - snooze = simple_strtol(str, NULL, 10); - for_each_possible_cpu(cpu) - per_cpu(smt_snooze_delay, cpu) = snooze; - + pr_warn("smt-snooze-delay command line option has no effect\n"); return 1; } __setup("smt-snooze-delay=", setup_smt_snooze_delay); --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/systbl.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/systbl.S @@ -25,6 +25,7 @@ #include #undef __SYSCALL #else + .p2align 2 #define __SYSCALL(nr, entry) .long entry #include #undef __SYSCALL --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/tau_6xx.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/tau_6xx.c @@ -13,13 +13,14 @@ */ #include -#include #include #include #include #include #include #include +#include +#include #include #include @@ -39,9 +40,7 @@ unsigned char grew; } tau[NR_CPUS]; -struct timer_list tau_timer; - -#undef DEBUG +static bool tau_int_enable; /* TODO: put these in a /proc interface, with some sanity checks, and maybe * dynamic adjustment to minimize # of interrupts */ @@ -50,72 +49,49 @@ #define step_size 2 /* step size when temp goes out of range */ #define window_expand 1 /* expand the window by this much */ /* configurable values for shrinking the window */ -#define shrink_timer 2*HZ /* period between shrinking the window */ +#define shrink_timer 2000 /* period between shrinking the window */ #define min_window 2 /* minimum window size, degrees C */ static void set_thresholds(unsigned long cpu) { -#ifdef CONFIG_TAU_INT - /* - * setup THRM1, - * threshold, valid bit, enable interrupts, interrupt when below threshold - */ - mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID); + u32 maybe_tie = tau_int_enable ? THRM1_TIE : 0; - /* setup THRM2, - * threshold, valid bit, enable interrupts, interrupt when above threshold - */ - mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE); -#else - /* same thing but don't enable interrupts */ - mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TID); - mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V); -#endif + /* setup THRM1, threshold, valid bit, interrupt when below threshold */ + mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | maybe_tie | THRM1_TID); + + /* setup THRM2, threshold, valid bit, interrupt when above threshold */ + mtspr(SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | maybe_tie); } static void TAUupdate(int cpu) { - unsigned thrm; - -#ifdef DEBUG - printk("TAUupdate "); -#endif + u32 thrm; + u32 bits = THRM1_TIV | THRM1_TIN | THRM1_V; /* if both thresholds are crossed, the step_sizes cancel out * and the window winds up getting expanded twice. */ - if((thrm = mfspr(SPRN_THRM1)) & THRM1_TIV){ /* is valid? */ - if(thrm & THRM1_TIN){ /* crossed low threshold */ - if (tau[cpu].low >= step_size){ - tau[cpu].low -= step_size; - tau[cpu].high -= (step_size - window_expand); - } - tau[cpu].grew = 1; -#ifdef DEBUG - printk("low threshold crossed "); -#endif + thrm = mfspr(SPRN_THRM1); + if ((thrm & bits) == bits) { + mtspr(SPRN_THRM1, 0); + + if (tau[cpu].low >= step_size) { + tau[cpu].low -= step_size; + tau[cpu].high -= (step_size - window_expand); } + tau[cpu].grew = 1; + pr_debug("%s: low threshold crossed\n", __func__); } - if((thrm = mfspr(SPRN_THRM2)) & THRM1_TIV){ /* is valid? */ - if(thrm & THRM1_TIN){ /* crossed high threshold */ - if (tau[cpu].high <= 127-step_size){ - tau[cpu].low += (step_size - window_expand); - tau[cpu].high += step_size; - } - tau[cpu].grew = 1; -#ifdef DEBUG - printk("high threshold crossed "); -#endif + thrm = mfspr(SPRN_THRM2); + if ((thrm & bits) == bits) { + mtspr(SPRN_THRM2, 0); + + if (tau[cpu].high <= 127 - step_size) { + tau[cpu].low += (step_size - window_expand); + tau[cpu].high += step_size; } + tau[cpu].grew = 1; + pr_debug("%s: high threshold crossed\n", __func__); } - -#ifdef DEBUG - printk("grew = %d\n", tau[cpu].grew); -#endif - -#ifndef CONFIG_TAU_INT /* tau_timeout will do this if not using interrupts */ - set_thresholds(cpu); -#endif - } #ifdef CONFIG_TAU_INT @@ -140,17 +116,16 @@ static void tau_timeout(void * info) { int cpu; - unsigned long flags; int size; int shrink; - /* disabling interrupts *should* be okay */ - local_irq_save(flags); cpu = smp_processor_id(); -#ifndef CONFIG_TAU_INT - TAUupdate(cpu); -#endif + if (!tau_int_enable) + TAUupdate(cpu); + + /* Stop thermal sensor comparisons and interrupts */ + mtspr(SPRN_THRM3, 0); size = tau[cpu].high - tau[cpu].low; if (size > min_window && ! tau[cpu].grew) { @@ -173,32 +148,26 @@ set_thresholds(cpu); - /* - * Do the enable every time, since otherwise a bunch of (relatively) - * complex sleep code needs to be added. One mtspr every time - * tau_timeout is called is probably not a big deal. - * - * Enable thermal sensor and set up sample interval timer - * need 20 us to do the compare.. until a nice 'cpu_speed' function - * call is implemented, just assume a 500 mhz clock. It doesn't really - * matter if we take too long for a compare since it's all interrupt - * driven anyway. - * - * use a extra long time.. (60 us @ 500 mhz) + /* Restart thermal sensor comparisons and interrupts. + * The "PowerPC 740 and PowerPC 750 Microprocessor Datasheet" + * recommends that "the maximum value be set in THRM3 under all + * conditions." */ - mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E); - - local_irq_restore(flags); + mtspr(SPRN_THRM3, THRM3_SITV(0x1fff) | THRM3_E); } -static void tau_timeout_smp(struct timer_list *unused) -{ +static struct workqueue_struct *tau_workq; - /* schedule ourselves to be run again */ - mod_timer(&tau_timer, jiffies + shrink_timer) ; +static void tau_work_func(struct work_struct *work) +{ + msleep(shrink_timer); on_each_cpu(tau_timeout, NULL, 0); + /* schedule ourselves to be run again */ + queue_work(tau_workq, work); } +DECLARE_WORK(tau_work, tau_work_func); + /* * setup the TAU * @@ -231,21 +200,19 @@ return 1; } + tau_int_enable = IS_ENABLED(CONFIG_TAU_INT) && + !strcmp(cur_cpu_spec->platform, "ppc750"); - /* first, set up the window shrinking timer */ - timer_setup(&tau_timer, tau_timeout_smp, 0); - tau_timer.expires = jiffies + shrink_timer; - add_timer(&tau_timer); + tau_workq = alloc_workqueue("tau", WQ_UNBOUND, 1, 0); + if (!tau_workq) + return -ENOMEM; on_each_cpu(TAU_init_smp, NULL, 0); - printk("Thermal assist unit "); -#ifdef CONFIG_TAU_INT - printk("using interrupts, "); -#else - printk("using timers, "); -#endif - printk("shrink_timer: %d jiffies\n", shrink_timer); + queue_work(tau_workq, &tau_work); + + pr_info("Thermal assist unit using %s, shrink_timer: %d ms\n", + tau_int_enable ? "interrupts" : "workqueue", shrink_timer); tau_initialized = 1; return 0; --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/time.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/time.c @@ -232,7 +232,7 @@ * Accumulate stolen time by scanning the dispatch trace log. * Called on entry from user mode. */ -void accumulate_stolen_time(void) +void notrace accumulate_stolen_time(void) { u64 sst, ust; unsigned long save_irq_soft_mask = irq_soft_mask_return(); @@ -522,35 +522,6 @@ "i" (offsetof(struct paca_struct, irq_work_pending))); } -void arch_irq_work_raise(void) -{ - preempt_disable(); - set_irq_work_pending_flag(); - /* - * Non-nmi code running with interrupts disabled will replay - * irq_happened before it re-enables interrupts, so setthe - * decrementer there instead of causing a hardware exception - * which would immediately hit the masked interrupt handler - * and have the net effect of setting the decrementer in - * irq_happened. - * - * NMI interrupts can not check this when they return, so the - * decrementer hardware exception is raised, which will fire - * when interrupts are next enabled. - * - * BookE does not support this yet, it must audit all NMI - * interrupt handlers to ensure they call nmi_enter() so this - * check would be correct. - */ - if (IS_ENABLED(CONFIG_BOOKE) || !irqs_disabled() || in_nmi()) { - set_dec(1); - } else { - hard_irq_disable(); - local_paca->irq_happened |= PACA_IRQ_DEC; - } - preempt_enable(); -} - #else /* 32-bit */ DEFINE_PER_CPU(u8, irq_work_pending); @@ -559,16 +530,27 @@ #define test_irq_work_pending() __this_cpu_read(irq_work_pending) #define clear_irq_work_pending() __this_cpu_write(irq_work_pending, 0) +#endif /* 32 vs 64 bit */ + void arch_irq_work_raise(void) { + /* + * 64-bit code that uses irq soft-mask can just cause an immediate + * interrupt here that gets soft masked, if this is called under + * local_irq_disable(). It might be possible to prevent that happening + * by noticing interrupts are disabled and setting decrementer pending + * to be replayed when irqs are enabled. The problem there is that + * tracing can call irq_work_raise, including in code that does low + * level manipulations of irq soft-mask state (e.g., trace_hardirqs_on) + * which could get tangled up if we're messing with the same state + * here. + */ preempt_disable(); set_irq_work_pending_flag(); set_dec(1); preempt_enable(); } -#endif /* 32 vs 64 bit */ - #else /* CONFIG_IRQ_WORK */ #define test_irq_work_pending() 0 @@ -959,6 +941,7 @@ vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec; vdso_data->stamp_xtime = xt; vdso_data->stamp_sec_fraction = frac_sec; + vdso_data->hrtimer_res = hrtimer_resolution; smp_wmb(); ++(vdso_data->tb_update_count); } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/trace/ftrace.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/trace/ftrace.c @@ -328,9 +328,7 @@ /* Is this a known long jump tramp? */ for (i = 0; i < NUM_FTRACE_TRAMPS; i++) - if (!ftrace_tramps[i]) - break; - else if (ftrace_tramps[i] == tramp) + if (ftrace_tramps[i] == tramp) return 0; /* Is this a known plt tramp? */ @@ -868,6 +866,17 @@ extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[]; +void ftrace_free_init_tramp(void) +{ + int i; + + for (i = 0; i < NUM_FTRACE_TRAMPS && ftrace_tramps[i]; i++) + if (ftrace_tramps[i] == (unsigned long)ftrace_tramp_init) { + ftrace_tramps[i] = 0; + return; + } +} + int __init ftrace_dyn_arch_init(void) { int i; --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/trace/ftrace_64_mprofile.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/trace/ftrace_64_mprofile.S @@ -36,6 +36,9 @@ /* Save the original return address in A's stack frame */ std r0,LRSAVE(r1) + /* Create a minimal stack frame for representing B */ + stdu r1, -STACK_FRAME_MIN_SIZE(r1) + /* Create our stack frame + pt_regs */ stdu r1,-SWITCH_FRAME_SIZE(r1) @@ -52,7 +55,7 @@ SAVE_10GPRS(22, r1) /* Save previous stack pointer (r1) */ - addi r8, r1, SWITCH_FRAME_SIZE + addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE std r8, GPR1(r1) /* Load special regs for save below */ @@ -65,6 +68,8 @@ mflr r7 /* Save it as pt_regs->nip */ std r7, _NIP(r1) + /* Also save it in B's stackframe header for proper unwind */ + std r7, LRSAVE+SWITCH_FRAME_SIZE(r1) /* Save the read LR in pt_regs->link */ std r0, _LINK(r1) @@ -121,7 +126,7 @@ ld r2, 24(r1) /* Pop our stack frame */ - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE #ifdef CONFIG_LIVEPATCH /* Based on the cmpd above, if the NIP was altered handle livepatch */ @@ -145,7 +150,7 @@ mflr r3 mtctr r3 REST_GPR(3, r1) - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE mtlr r0 bctr @@ -153,6 +158,9 @@ /* Save the original return address in A's stack frame */ std r0, LRSAVE(r1) + /* Create a minimal stack frame for representing B */ + stdu r1, -STACK_FRAME_MIN_SIZE(r1) + /* Create our stack frame + pt_regs */ stdu r1, -SWITCH_FRAME_SIZE(r1) @@ -166,6 +174,7 @@ /* Get the _mcount() call site out of LR */ mflr r7 std r7, _NIP(r1) + std r7, LRSAVE+SWITCH_FRAME_SIZE(r1) /* Save callee's TOC in the ABI compliant location */ std r2, 24(r1) @@ -200,7 +209,7 @@ ld r2, 24(r1) /* Pop our stack frame */ - addi r1, r1, SWITCH_FRAME_SIZE + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE /* Reload original LR */ ld r0, LRSAVE(r1) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/traps.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/traps.c @@ -246,19 +246,26 @@ if (panic_on_oops) panic("Fatal exception"); - do_exit(signr); + make_task_dead(signr); } NOKPROBE_SYMBOL(oops_end); +static char *get_mmu_str(void) +{ + if (early_radix_enabled()) + return " MMU=Radix"; + if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) + return " MMU=Hash"; + return ""; +} + static int __die(const char *str, struct pt_regs *regs, long err) { printk("Oops: %s, sig: %ld [#%d]\n", str, err, ++die_counter); - printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s%s %s\n", + printk("%s PAGE_SIZE=%luK%s%s%s%s%s%s %s\n", IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN) ? "LE" : "BE", - PAGE_SIZE / 1024, - early_radix_enabled() ? " MMU=Radix" : "", - early_mmu_has_feature(MMU_FTR_HPTE_TABLE) ? " MMU=Hash" : "", + PAGE_SIZE / 1024, get_mmu_str(), IS_ENABLED(CONFIG_PREEMPT) ? " PREEMPT" : "", IS_ENABLED(CONFIG_SMP) ? " SMP" : "", IS_ENABLED(CONFIG_SMP) ? (" NR_CPUS=" __stringify(NR_CPUS)) : "", @@ -503,11 +510,14 @@ #ifdef CONFIG_PPC_BOOK3S_64 BUG_ON(get_paca()->in_nmi == 0); if (get_paca()->in_nmi > 1) - nmi_panic(regs, "Unrecoverable nested System Reset"); + die("Unrecoverable nested System Reset", regs, SIGABRT); #endif /* Must die if the interrupt is not recoverable */ - if (!(regs->msr & MSR_RI)) - nmi_panic(regs, "Unrecoverable System Reset"); + if (!(regs->msr & MSR_RI)) { + /* For the reason explained in die_mce, nmi_exit before die */ + nmi_exit(); + die("Unrecoverable System Reset", regs, SIGABRT); + } if (saved_hsrrs) { mtspr(SPRN_HSRR0, hsrr0); @@ -851,7 +861,7 @@ /* Must die if the interrupt is not recoverable */ if (!(regs->msr & MSR_RI)) - nmi_panic(regs, "Unrecoverable Machine check"); + die("Unrecoverable Machine check", regs, SIGBUS); return; @@ -870,7 +880,7 @@ { unsigned int ra, rb, t, i, sel, instr, rc; const void __user *addr; - u8 vbuf[16], *vdst; + u8 vbuf[16] __aligned(16), *vdst; unsigned long ea, msr, msr_mask; bool swap; @@ -1414,10 +1424,12 @@ return -EINVAL; } +#ifdef CONFIG_GENERIC_BUG int is_valid_bugaddr(unsigned long addr) { return is_kernel_addr(addr); } +#endif #ifdef CONFIG_MATH_EMULATION static int emulate_math(struct pt_regs *regs) --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vdso.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/vdso.c @@ -682,7 +682,7 @@ node = cpu_to_node(cpu); WARN_ON_ONCE(node > 0xffff); - val = (cpu & 0xfff) | ((node & 0xffff) << 16); + val = (cpu & 0xffff) | ((node & 0xffff) << 16); mtspr(SPRN_SPRG_VDSO_WRITE, val); get_paca()->sprg_vdso = val; --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vdso32/gettimeofday.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/vdso32/gettimeofday.S @@ -156,12 +156,15 @@ cror cr0*4+eq,cr0*4+eq,cr1*4+eq bne cr0,99f + mflr r12 + .cfi_register lr,r12 + bl __get_datapage@local /* get data page */ + lwz r5, CLOCK_HRTIMER_RES(r3) + mtlr r12 li r3,0 cmpli cr0,r4,0 crclr cr0*4+so beqlr - lis r5,CLOCK_REALTIME_RES@h - ori r5,r5,CLOCK_REALTIME_RES@l stw r3,TSPC32_TV_SEC(r4) stw r5,TSPC32_TV_NSEC(r4) blr --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vdso64/cacheflush.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/vdso64/cacheflush.S @@ -35,7 +35,7 @@ subf r8,r6,r4 /* compute length */ add r8,r8,r5 /* ensure we get enough */ lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10) - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ crclr cr0*4+so beqlr /* nothing to do? */ mtctr r8 @@ -52,7 +52,7 @@ subf r8,r6,r4 /* compute length */ add r8,r8,r5 lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10) - srw. r8,r8,r9 /* compute line count */ + srd. r8,r8,r9 /* compute line count */ crclr cr0*4+so beqlr /* nothing to do? */ mtctr r8 --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vdso64/gettimeofday.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -186,12 +186,15 @@ cror cr0*4+eq,cr0*4+eq,cr1*4+eq bne cr0,99f + mflr r12 + .cfi_register lr,r12 + bl V_LOCAL_FUNC(__get_datapage) + lwz r5, CLOCK_HRTIMER_RES(r3) + mtlr r12 li r3,0 cmpldi cr0,r4,0 crclr cr0*4+so beqlr - lis r5,CLOCK_REALTIME_RES@h - ori r5,r5,CLOCK_REALTIME_RES@l std r3,TSPC64_TV_SEC(r4) std r5,TSPC64_TV_NSEC(r4) blr --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vector.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/vector.S @@ -32,6 +32,7 @@ mfvscr v0 li r4, VRSTATE_VSCR stvx v0, r4, r3 + lvx v0, 0, r3 blr EXPORT_SYMBOL(store_vr_state) @@ -102,6 +103,7 @@ mfvscr v0 li r4,VRSTATE_VSCR stvx v0,r4,r7 + lvx v0,0,r7 blr #ifdef CONFIG_VSX --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/powerpc/kernel/vmlinux.lds.S @@ -6,6 +6,7 @@ #endif #define BSS_FIRST_SECTIONS *(.bss.prominit) +#define RUNTIME_DISCARD_EXIT #include #include @@ -98,10 +99,11 @@ ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); + *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); #ifdef CONFIG_PPC64 *(.tramp.ftrace.text); #endif + NOINSTR_TEXT SCHED_TEXT CPUIDLE_TEXT LOCK_TEXT @@ -144,6 +146,20 @@ } . = ALIGN(8); + __uaccess_flush_fixup : AT(ADDR(__uaccess_flush_fixup) - LOAD_OFFSET) { + __start___uaccess_flush_fixup = .; + *(__uaccess_flush_fixup) + __stop___uaccess_flush_fixup = .; + } + + . = ALIGN(8); + __entry_flush_fixup : AT(ADDR(__entry_flush_fixup) - LOAD_OFFSET) { + __start___entry_flush_fixup = .; + *(__entry_flush_fixup) + __stop___entry_flush_fixup = .; + } + + . = ALIGN(8); __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { __start___stf_exit_barrier_fixup = .; *(__stf_exit_barrier_fixup) @@ -196,6 +212,12 @@ .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { _sinittext = .; INIT_TEXT + + /* + *.init.text might be RO so we must ensure this section ends on + * a page boundary. + */ + . = ALIGN(PAGE_SIZE); _einittext = .; #ifdef CONFIG_PPC64 *(.tramp.ftrace.init); @@ -209,21 +231,9 @@ EXIT_TEXT } - .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { - INIT_DATA - } - - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { - INIT_SETUP(16) - } - - .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - INIT_CALLS - } + . = ALIGN(PAGE_SIZE); - .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { - CON_INITCALL - } + INIT_DATA_SECTION(16) . = ALIGN(8); __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { @@ -251,9 +261,6 @@ __stop___fw_ftr_fixup = .; } #endif - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - INIT_RAM_FS - } PERCPU_SECTION(L1_CACHE_BYTES) @@ -388,9 +395,12 @@ DISCARDS /DISCARD/ : { *(*.EMB.apuinfo) - *(.glink .iplt .plt .rela* .comment) + *(.glink .iplt .plt .comment) *(.gnu.version*) *(.gnu.attributes) *(.eh_frame) +#ifndef CONFIG_RELOCATABLE + *(.rela*) +#endif } } --- linux-oracle-5.4.0.orig/arch/powerpc/kernel/watchdog.c +++ linux-oracle-5.4.0/arch/powerpc/kernel/watchdog.c @@ -132,6 +132,10 @@ { cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask); cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask); + /* + * See wd_smp_clear_cpu_pending() + */ + smp_mb(); if (cpumask_empty(&wd_smp_cpus_pending)) { wd_smp_last_reset_tb = tb; cpumask_andnot(&wd_smp_cpus_pending, @@ -217,13 +221,44 @@ cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck); wd_smp_unlock(&flags); + } else { + /* + * The last CPU to clear pending should have reset the + * watchdog so we generally should not find it empty + * here if our CPU was clear. However it could happen + * due to a rare race with another CPU taking the + * last CPU out of the mask concurrently. + * + * We can't add a warning for it. But just in case + * there is a problem with the watchdog that is causing + * the mask to not be reset, try to kick it along here. + */ + if (unlikely(cpumask_empty(&wd_smp_cpus_pending))) + goto none_pending; } return; } + cpumask_clear_cpu(cpu, &wd_smp_cpus_pending); + + /* + * Order the store to clear pending with the load(s) to check all + * words in the pending mask to check they are all empty. This orders + * with the same barrier on another CPU. This prevents two CPUs + * clearing the last 2 pending bits, but neither seeing the other's + * store when checking if the mask is empty, and missing an empty + * mask, which ends with a false positive. + */ + smp_mb(); if (cpumask_empty(&wd_smp_cpus_pending)) { unsigned long flags; +none_pending: + /* + * Double check under lock because more than one CPU could see + * a clear mask with the lockless check after clearing their + * pending bits. + */ wd_smp_lock(&flags); if (cpumask_empty(&wd_smp_cpus_pending)) { wd_smp_last_reset_tb = tb; @@ -314,8 +349,12 @@ { unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000; int cpu = smp_processor_id(); - u64 tb = get_tb(); + u64 tb; + if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) + return; + + tb = get_tb(); if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) { per_cpu(wd_timer_tb, cpu) = tb; wd_smp_clear_cpu_pending(cpu, tb); --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s.c @@ -867,7 +867,8 @@ kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change); } -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, + unsigned flags) { return kvm->arch.kvm_ops->unmap_hva_range(kvm, start, end); } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -31,14 +31,15 @@ gva_t eaddr, void *to, void *from, unsigned long n) { - int uninitialized_var(old_pid), old_lpid; + int old_pid, old_lpid; unsigned long quadrant, ret = n; bool is_load = !!to; /* Can't access quadrants 1 or 2 in non-HV mode, call the HV to do it */ if (kvmhv_on_pseries()) return plpar_hcall_norets(H_COPY_TOFROM_GUEST, lpid, pid, eaddr, - __pa(to), __pa(from), n); + (to != NULL) ? __pa(to): 0, + (from != NULL) ? __pa(from): 0, n); quadrant = 1; if (!pid) @@ -353,7 +354,13 @@ static pte_t *kvmppc_pte_alloc(void) { - return kmem_cache_alloc(kvm_pte_cache, GFP_KERNEL); + pte_t *pte; + + pte = kmem_cache_alloc(kvm_pte_cache, GFP_KERNEL); + /* pmd_populate() will only reference _pa(pte). */ + kmemleak_ignore(pte); + + return pte; } static void kvmppc_pte_free(pte_t *ptep) @@ -363,7 +370,13 @@ static pmd_t *kvmppc_pmd_alloc(void) { - return kmem_cache_alloc(kvm_pmd_cache, GFP_KERNEL); + pmd_t *pmd; + + pmd = kmem_cache_alloc(kvm_pmd_cache, GFP_KERNEL); + /* pud_populate() will only reference _pa(pmd). */ + kmemleak_ignore(pmd); + + return pmd; } static void kvmppc_pmd_free(pmd_t *pmdp) @@ -1091,6 +1104,11 @@ kvm->arch.lpid); gpa += PAGE_SIZE; } + /* + * Increase the mmu notifier sequence number to prevent any page + * fault that read the memslot earlier from writing a PTE. + */ + kvm->mmu_notifier_seq++; spin_unlock(&kvm->mmu_lock); } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_64_vio.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_64_vio.c @@ -74,6 +74,7 @@ struct kvmppc_spapr_tce_iommu_table *stit, *tmp; struct iommu_table_group *table_group = NULL; + rcu_read_lock(); list_for_each_entry_rcu(stt, &kvm->arch.spapr_tce_tables, list) { table_group = iommu_group_get_iommudata(grp); @@ -88,7 +89,9 @@ kref_put(&stit->kref, kvm_spapr_tce_liobn_put); } } + cond_resched_rcu(); } + rcu_read_unlock(); } extern long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, @@ -106,21 +109,25 @@ if (!f.file) return -EBADF; + rcu_read_lock(); list_for_each_entry_rcu(stt, &kvm->arch.spapr_tce_tables, list) { if (stt == f.file->private_data) { found = true; break; } } + rcu_read_unlock(); - fdput(f); - - if (!found) + if (!found) { + fdput(f); return -EINVAL; + } table_group = iommu_group_get_iommudata(grp); - if (WARN_ON(!table_group)) + if (WARN_ON(!table_group)) { + fdput(f); return -EFAULT; + } for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) { struct iommu_table *tbltmp = table_group->tables[i]; @@ -141,9 +148,12 @@ break; } } - if (!tbl) + if (!tbl) { + fdput(f); return -EINVAL; + } + rcu_read_lock(); list_for_each_entry_rcu(stit, &stt->iommu_tables, next) { if (tbl != stit->tbl) continue; @@ -151,18 +161,24 @@ if (!kref_get_unless_zero(&stit->kref)) { /* stit is being destroyed */ iommu_tce_table_put(tbl); + rcu_read_unlock(); + fdput(f); return -ENOTTY; } /* * The table is already known to this KVM, we just increased * its KVM reference counter and can return. */ + rcu_read_unlock(); + fdput(f); return 0; } + rcu_read_unlock(); stit = kzalloc(sizeof(*stit), GFP_KERNEL); if (!stit) { iommu_tce_table_put(tbl); + fdput(f); return -ENOMEM; } @@ -171,6 +187,7 @@ list_add_rcu(&stit->next, &stt->iommu_tables); + fdput(f); return 0; } @@ -364,18 +381,19 @@ if (kvmppc_tce_to_ua(stt->kvm, tce, &ua)) return H_TOO_HARD; + rcu_read_lock(); list_for_each_entry_rcu(stit, &stt->iommu_tables, next) { unsigned long hpa = 0; struct mm_iommu_table_group_mem_t *mem; long shift = stit->tbl->it_page_shift; mem = mm_iommu_lookup(stt->kvm->mm, ua, 1ULL << shift); - if (!mem) - return H_TOO_HARD; - - if (mm_iommu_ua_to_hpa(mem, ua, shift, &hpa)) + if (!mem || mm_iommu_ua_to_hpa(mem, ua, shift, &hpa)) { + rcu_read_unlock(); return H_TOO_HARD; + } } + rcu_read_unlock(); return H_SUCCESS; } @@ -410,13 +428,19 @@ tbl[idx % TCES_PER_PAGE] = tce; } -static void kvmppc_clear_tce(struct mm_struct *mm, struct iommu_table *tbl, - unsigned long entry) +static void kvmppc_clear_tce(struct mm_struct *mm, struct kvmppc_spapr_tce_table *stt, + struct iommu_table *tbl, unsigned long entry) { - unsigned long hpa = 0; - enum dma_data_direction dir = DMA_NONE; + unsigned long i; + unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); + unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); + + for (i = 0; i < subpages; ++i) { + unsigned long hpa = 0; + enum dma_data_direction dir = DMA_NONE; - iommu_tce_xchg_no_kill(mm, tbl, entry, &hpa, &dir); + iommu_tce_xchg_no_kill(mm, tbl, io_entry + i, &hpa, &dir); + } } static long kvmppc_tce_iommu_mapped_dec(struct kvm *kvm, @@ -475,6 +499,8 @@ break; } + iommu_tce_kill(tbl, io_entry, subpages); + return ret; } @@ -534,6 +560,8 @@ break; } + iommu_tce_kill(tbl, io_entry, subpages); + return ret; } @@ -580,10 +608,9 @@ ret = kvmppc_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); - iommu_tce_kill(stit->tbl, entry, 1); if (ret != H_SUCCESS) { - kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); + kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry); goto unlock_exit; } } @@ -659,13 +686,13 @@ */ if (get_user(tce, tces + i)) { ret = H_TOO_HARD; - goto invalidate_exit; + goto unlock_exit; } tce = be64_to_cpu(tce); if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) { ret = H_PARAMETER; - goto invalidate_exit; + goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { @@ -674,19 +701,15 @@ iommu_tce_direction(tce)); if (ret != H_SUCCESS) { - kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, - entry); - goto invalidate_exit; + kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, + entry + i); + goto unlock_exit; } } kvmppc_tce_put(stt, entry + i, tce); } -invalidate_exit: - list_for_each_entry_lockless(stit, &stt->iommu_tables, next) - iommu_tce_kill(stit->tbl, entry, npages); - unlock_exit: srcu_read_unlock(&vcpu->kvm->srcu, idx); @@ -725,20 +748,16 @@ continue; if (ret == H_TOO_HARD) - goto invalidate_exit; + return ret; WARN_ON_ONCE(1); - kvmppc_clear_tce(vcpu->kvm->mm, stit->tbl, entry); + kvmppc_clear_tce(vcpu->kvm->mm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); -invalidate_exit: - list_for_each_entry_lockless(stit, &stt->iommu_tables, next) - iommu_tce_kill(stit->tbl, ioba >> stt->page_shift, npages); - return ret; } EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_64_vio_hv.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -177,10 +177,13 @@ idx -= stt->offset; page = stt->pages[idx / TCES_PER_PAGE]; /* - * page must not be NULL in real mode, - * kvmppc_rm_ioba_validate() must have taken care of this. + * kvmppc_rm_ioba_validate() allows pages not be allocated if TCE is + * being cleared, otherwise it returns H_TOO_HARD and we skip this. */ - WARN_ON_ONCE_RM(!page); + if (!page) { + WARN_ON_ONCE_RM(tce != 0); + return; + } tbl = kvmppc_page_address(page); tbl[idx % TCES_PER_PAGE] = tce; @@ -248,13 +251,19 @@ tbl->it_ops->tce_kill(tbl, entry, pages, true); } -static void kvmppc_rm_clear_tce(struct kvm *kvm, struct iommu_table *tbl, - unsigned long entry) +static void kvmppc_rm_clear_tce(struct kvm *kvm, struct kvmppc_spapr_tce_table *stt, + struct iommu_table *tbl, unsigned long entry) { - unsigned long hpa = 0; - enum dma_data_direction dir = DMA_NONE; + unsigned long i; + unsigned long subpages = 1ULL << (stt->page_shift - tbl->it_page_shift); + unsigned long io_entry = entry << (stt->page_shift - tbl->it_page_shift); + + for (i = 0; i < subpages; ++i) { + unsigned long hpa = 0; + enum dma_data_direction dir = DMA_NONE; - iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, entry, &hpa, &dir); + iommu_tce_xchg_no_kill_rm(kvm->mm, tbl, io_entry + i, &hpa, &dir); + } } static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm, @@ -317,6 +326,8 @@ break; } + iommu_tce_kill_rm(tbl, io_entry, subpages); + return ret; } @@ -380,6 +391,8 @@ break; } + iommu_tce_kill_rm(tbl, io_entry, subpages); + return ret; } @@ -425,10 +438,8 @@ ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt, stit->tbl, entry, ua, dir); - iommu_tce_kill_rm(stit->tbl, entry, 1); - if (ret != H_SUCCESS) { - kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); + kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry); return ret; } } @@ -568,7 +579,7 @@ ua = 0; if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) { ret = H_PARAMETER; - goto invalidate_exit; + goto unlock_exit; } list_for_each_entry_lockless(stit, &stt->iommu_tables, next) { @@ -577,19 +588,15 @@ iommu_tce_direction(tce)); if (ret != H_SUCCESS) { - kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, - entry); - goto invalidate_exit; + kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, + entry + i); + goto unlock_exit; } } kvmppc_rm_tce_put(stt, entry + i, tce); } -invalidate_exit: - list_for_each_entry_lockless(stit, &stt->iommu_tables, next) - iommu_tce_kill_rm(stit->tbl, entry, npages); - unlock_exit: if (rmap) unlock_rmap(rmap); @@ -632,20 +639,16 @@ continue; if (ret == H_TOO_HARD) - goto invalidate_exit; + return ret; WARN_ON_ONCE_RM(1); - kvmppc_rm_clear_tce(vcpu->kvm, stit->tbl, entry); + kvmppc_rm_clear_tce(vcpu->kvm, stt, stit->tbl, entry + i); } } for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) kvmppc_rm_tce_put(stt, ioba >> stt->page_shift, tce_value); -invalidate_exit: - list_for_each_entry_lockless(stit, &stt->iommu_tables, next) - iommu_tce_kill_rm(stit->tbl, ioba >> stt->page_shift, npages); - return ret; } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -2306,8 +2307,10 @@ HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP; if (cpu_has_feature(CPU_FTR_HVMODE)) { vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) vcpu->arch.hfscr |= HFSCR_TM; +#endif } if (cpu_has_feature(CPU_FTR_TM_COMP)) vcpu->arch.hfscr |= HFSCR_TM; @@ -2354,7 +2357,7 @@ mutex_unlock(&kvm->lock); if (!vcore) - goto free_vcpu; + goto uninit_vcpu; spin_lock(&vcore->lock); ++vcore->num_threads; @@ -2371,6 +2374,8 @@ return vcpu; +uninit_vcpu: + kvm_vcpu_uninit(vcpu); free_vcpu: kmem_cache_free(kvm_vcpu_cache, vcpu); out: @@ -2534,7 +2539,7 @@ cpumask_t *cpu_in_guest; int i; - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); if (nested) { cpumask_set_cpu(cpu, &nested->need_tlb_flush); cpu_in_guest = &nested->cpu_in_guest; @@ -2548,9 +2553,10 @@ * the other side is the first smp_mb() in kvmppc_run_core(). */ smp_mb(); - for (i = 0; i < threads_per_core; ++i) - if (cpumask_test_cpu(cpu + i, cpu_in_guest)) - smp_call_function_single(cpu + i, do_nothing, NULL, 1); + for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu); + i += cpu_tlb_thread_sibling_step()) + if (cpumask_test_cpu(i, cpu_in_guest)) + smp_call_function_single(i, do_nothing, NULL, 1); } static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) @@ -2581,8 +2587,8 @@ */ if (prev_cpu != pcpu) { if (prev_cpu >= 0 && - cpu_first_thread_sibling(prev_cpu) != - cpu_first_thread_sibling(pcpu)) + cpu_first_tlb_thread_sibling(prev_cpu) != + cpu_first_tlb_thread_sibling(pcpu)) radix_flush_cpu(kvm, prev_cpu, vcpu); if (nested) nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu; @@ -3554,6 +3560,18 @@ cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) kvmppc_restore_tm_hv(vcpu, vcpu->arch.shregs.msr, true); +#ifdef CONFIG_PPC_PSERIES + if (kvmhv_on_pseries()) { + barrier(); + if (vcpu->arch.vpa.pinned_addr) { + struct lppaca *lp = vcpu->arch.vpa.pinned_addr; + get_lppaca()->pmcregs_in_use = lp->pmcregs_in_use; + } else { + get_lppaca()->pmcregs_in_use = 1; + } + barrier(); + } +#endif kvmhv_load_guest_pmu(vcpu); msr_check_and_set(MSR_FP | MSR_VEC | MSR_VSX); @@ -3621,6 +3639,7 @@ if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested && kvmppc_get_gpr(vcpu, 3) == H_CEDE) { kvmppc_nested_cede(vcpu); + kvmppc_set_gpr(vcpu, 3, 0); trap = 0; } } else { @@ -3635,7 +3654,10 @@ vcpu->arch.dec_expires = dec + tb; vcpu->cpu = -1; vcpu->arch.thread_cpu = -1; + /* Save guest CTRL register, set runlatch to 1 */ vcpu->arch.ctrl = mfspr(SPRN_CTRLF); + if (!(vcpu->arch.ctrl & 1)) + mtspr(SPRN_CTRLT, vcpu->arch.ctrl | 1); vcpu->arch.iamr = mfspr(SPRN_IAMR); vcpu->arch.pspb = mfspr(SPRN_PSPB); @@ -3684,6 +3706,13 @@ save_pmu |= nesting_enabled(vcpu->kvm); kvmhv_save_guest_pmu(vcpu, save_pmu); +#ifdef CONFIG_PPC_PSERIES + if (kvmhv_on_pseries()) { + barrier(); + get_lppaca()->pmcregs_in_use = ppc_get_pmu_inuse(); + barrier(); + } +#endif vc->entry_exit_map = 0x101; vc->in_guest = 0; @@ -5188,6 +5217,12 @@ case KVM_PPC_ALLOCATE_HTAB: { u32 htab_order; + /* If we're a nested hypervisor, we currently only support radix */ + if (kvmhv_on_pseries()) { + r = -EOPNOTSUPP; + break; + } + r = -EFAULT; if (get_user(htab_order, (u32 __user *)argp)) break; --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_builtin.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_builtin.c @@ -821,6 +821,7 @@ "r" (0) : "memory"); } asm volatile("ptesync": : :"memory"); + // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory"); } else { for (set = 0; set < kvm->arch.tlb_sets; ++set) { @@ -831,7 +832,9 @@ rb += PPC_BIT(51); /* increment set number */ } asm volatile("ptesync": : :"memory"); - asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); + // POWER9 congruence-class TLBIEL leaves ERAT. Flush it now. + if (cpu_has_feature(CPU_FTR_ARCH_300)) + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } } @@ -847,7 +850,7 @@ * Thus we make all 4 threads use the same bit. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - pcpu = cpu_first_thread_sibling(pcpu); + pcpu = cpu_first_tlb_thread_sibling(pcpu); if (nested) need_tlb_flush = &nested->need_tlb_flush; --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_nested.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_nested.c @@ -51,7 +51,8 @@ hr->ppr = vcpu->arch.ppr; } -static void byteswap_pt_regs(struct pt_regs *regs) +/* Use noinline_for_stack due to https://bugs.llvm.org/show_bug.cgi?id=49610 */ +static noinline_for_stack void byteswap_pt_regs(struct pt_regs *regs) { unsigned long *addr = (unsigned long *) regs; @@ -231,6 +232,9 @@ if (vcpu->kvm->arch.l1_ptcr == 0) return H_NOT_AVAILABLE; + if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr)) + return H_BAD_MODE; + /* copy parameters in */ hv_ptr = kvmppc_get_gpr(vcpu, 4); err = kvm_vcpu_read_guest(vcpu, hv_ptr, &l2_hv, @@ -252,6 +256,23 @@ if (l2_hv.vcpu_token >= NR_CPUS) return H_PARAMETER; + /* + * L1 must have set up a suspended state to enter the L2 in a + * transactional state, and only in that case. These have to be + * filtered out here to prevent causing a TM Bad Thing in the + * host HRFID. We could synthesize a TM Bad Thing back to the L1 + * here but there doesn't seem like much point. + */ + if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) { + if (!MSR_TM_ACTIVE(l2_regs.msr)) + return H_BAD_MODE; + } else { + if (l2_regs.msr & MSR_TS_MASK) + return H_BAD_MODE; + if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK)) + return H_BAD_MODE; + } + /* translate lpid */ l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true); if (!l2) @@ -489,7 +510,7 @@ if (eaddr & (0xFFFUL << 52)) return H_PARAMETER; - buf = kzalloc(n, GFP_KERNEL); + buf = kzalloc(n, GFP_KERNEL | __GFP_NOWARN); if (!buf) return H_NO_MEM; --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -67,7 +67,7 @@ * so use the bit for the first thread to represent the core. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush); } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -291,13 +292,16 @@ * r3 contains the SRR1 wakeup value, SRR1 is trashed. */ _GLOBAL(idle_kvm_start_guest) - ld r4,PACAEMERGSP(r13) mfcr r5 mflr r0 - std r1,0(r4) - std r5,8(r4) - std r0,16(r4) - subi r1,r4,STACK_FRAME_OVERHEAD + std r5, 8(r1) // Save CR in caller's frame + std r0, 16(r1) // Save LR in caller's frame + // Create frame on emergency stack + ld r4, PACAEMERGSP(r13) + stdu r1, -SWITCH_FRAME_SIZE(r4) + // Switch to new frame on emergency stack + mr r1, r4 + std r3, 32(r1) // Save SRR1 wakeup value SAVE_NVGPRS(r1) /* @@ -349,6 +353,10 @@ kvm_secondary_got_guest: + // About to go to guest, clear saved SRR1 + li r0, 0 + std r0, 32(r1) + /* Set HSTATE_DSCR(r13) to something sensible */ ld r6, PACA_DSCR_DEFAULT(r13) std r6, HSTATE_DSCR(r13) @@ -440,13 +448,12 @@ mfspr r4, SPRN_LPCR rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 mtspr SPRN_LPCR, r4 - /* set up r3 for return */ - mfspr r3,SPRN_SRR1 + // Return SRR1 wakeup value, or 0 if we went into the guest + ld r3, 32(r1) REST_NVGPRS(r1) - addi r1, r1, STACK_FRAME_OVERHEAD - ld r0, 16(r1) - ld r5, 8(r1) - ld r1, 0(r1) + ld r1, 0(r1) // Switch back to caller stack + ld r0, 16(r1) // Reload LR + ld r5, 8(r1) // Reload CR mtlr r0 mtcr r5 blr @@ -1116,7 +1123,7 @@ ld r7, VCPU_GPR(R7)(r4) bne ret_to_ultra - lwz r0, VCPU_CR(r4) + ld r0, VCPU_CR(r4) mtcr r0 ld r0, VCPU_GPR(R0)(r4) @@ -1136,7 +1143,7 @@ * R3 = UV_RETURN */ ret_to_ultra: - lwz r0, VCPU_CR(r4) + ld r0, VCPU_CR(r4) mtcr r0 ld r0, VCPU_GPR(R3)(r4) @@ -1487,6 +1494,13 @@ 1: #endif /* CONFIG_KVM_XICS */ + /* + * Possibly flush the link stack here, before we do a blr in + * guest_exit_short_path. + */ +1: nop + patch_site 1b patch__call_kvm_flush_link_stack + /* If we came in through the P9 short path, go back out to C now */ lwz r0, STACK_SLOT_SHORT_PATH(r1) cmpwi r0, 0 @@ -1963,6 +1977,28 @@ mtlr r0 blr +.balign 32 +.global kvm_flush_link_stack +kvm_flush_link_stack: + /* Save LR into r0 */ + mflr r0 + + /* Flush the link stack. On Power8 it's up to 32 entries in size. */ + .rept 32 + bl .+4 + .endr + + /* And on Power9 it's up to 64. */ +BEGIN_FTR_SECTION + .rept 32 + bl .+4 + .endr +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300) + + /* Restore LR */ + mtlr r0 + blr + kvmppc_guest_external: /* External interrupt, first check for host_ipi. If this is * set, we know the host wants us out so let's do it now @@ -2499,7 +2535,7 @@ .globl hcall_real_table_end hcall_real_table_end: -_GLOBAL(kvmppc_h_set_xdabr) +_GLOBAL_TOC(kvmppc_h_set_xdabr) EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr) andi. r0, r5, DABRX_USER | DABRX_KERNEL beq 6f @@ -2509,7 +2545,7 @@ 6: li r3, H_PARAMETER blr -_GLOBAL(kvmppc_h_set_dabr) +_GLOBAL_TOC(kvmppc_h_set_dabr) EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr) li r5, DABRX_USER | DABRX_KERNEL 3: @@ -3107,7 +3143,7 @@ /* The following code handles the fake_suspend = 1 case */ mflr r0 std r0, PPC_LR_STKOFF(r1) - stdu r1, -PPC_MIN_STKFRM(r1) + stdu r1, -TM_FRAME_SIZE(r1) /* Turn on TM. */ mfmsr r8 @@ -3122,10 +3158,42 @@ END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG) nop + /* + * It's possible that treclaim. may modify registers, if we have lost + * track of fake-suspend state in the guest due to it using rfscv. + * Save and restore registers in case this occurs. + */ + mfspr r3, SPRN_DSCR + mfspr r4, SPRN_XER + mfspr r5, SPRN_AMR + /* SPRN_TAR would need to be saved here if the kernel ever used it */ + mfcr r12 + SAVE_NVGPRS(r1) + SAVE_GPR(2, r1) + SAVE_GPR(3, r1) + SAVE_GPR(4, r1) + SAVE_GPR(5, r1) + stw r12, 8(r1) + std r1, HSTATE_HOST_R1(r13) + /* We have to treclaim here because that's the only way to do S->N */ li r3, TM_CAUSE_KVM_RESCHED TRECLAIM(R3) + GET_PACA(r13) + ld r1, HSTATE_HOST_R1(r13) + REST_GPR(2, r1) + REST_GPR(3, r1) + REST_GPR(4, r1) + REST_GPR(5, r1) + lwz r12, 8(r1) + REST_NVGPRS(r1) + mtspr SPRN_DSCR, r3 + mtspr SPRN_XER, r4 + mtspr SPRN_AMR, r5 + mtcr r12 + HMT_MEDIUM + /* * We were in fake suspend, so we are not going to save the * register state as the guest checkpointed state (since @@ -3153,7 +3221,7 @@ std r5, VCPU_TFHAR(r9) std r6, VCPU_TFIAR(r9) - addi r1, r1, PPC_MIN_STKFRM + addi r1, r1, TM_FRAME_SIZE ld r0, PPC_LR_STKOFF(r1) mtlr r0 blr --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_tm.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_tm.c @@ -3,6 +3,8 @@ * Copyright 2017 Paul Mackerras, IBM Corp. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -44,7 +46,18 @@ u64 newmsr, bescr; int ra, rs; - switch (instr & 0xfc0007ff) { + /* + * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit + * in these instructions, so masking bit 31 out doesn't change these + * instructions. For treclaim., tsr., and trechkpt. instructions if bit + * 31 = 0 then they are per ISA invalid forms, however P9 UM, in section + * 4.6.10 Book II Invalid Forms, informs specifically that ignoring bit + * 31 is an acceptable way to handle these invalid forms that have + * bit 31 = 0. Moreover, for emulation purposes both forms (w/ and wo/ + * bit 31 set) can generate a softpatch interrupt. Hence both forms + * are handled below for these instructions so they behave the same way. + */ + switch (instr & PO_XOP_OPCODE_MASK) { case PPC_INST_RFID: /* XXX do we need to check for PR=0 here? */ newmsr = vcpu->arch.shregs.srr1; @@ -105,7 +118,8 @@ vcpu->arch.shregs.msr = newmsr; return RESUME_GUEST; - case PPC_INST_TSR: + /* ignore bit 31, see comment above */ + case (PPC_INST_TSR & PO_XOP_OPCODE_MASK): /* check for PR=1 and arch 2.06 bit set in PCR */ if ((msr & MSR_PR) && (vcpu->arch.vcore->pcr & PCR_ARCH_206)) { /* generate an illegal instruction interrupt */ @@ -140,7 +154,8 @@ vcpu->arch.shregs.msr = msr; return RESUME_GUEST; - case PPC_INST_TRECLAIM: + /* ignore bit 31, see comment above */ + case (PPC_INST_TRECLAIM & PO_XOP_OPCODE_MASK): /* check for TM disabled in the HFSCR or MSR */ if (!(vcpu->arch.hfscr & HFSCR_TM)) { /* generate an illegal instruction interrupt */ @@ -176,7 +191,8 @@ vcpu->arch.shregs.msr &= ~MSR_TS_MASK; return RESUME_GUEST; - case PPC_INST_TRECHKPT: + /* ignore bit 31, see comment above */ + case (PPC_INST_TRECHKPT & PO_XOP_OPCODE_MASK): /* XXX do we need to check for PR=0 here? */ /* check for TM disabled in the HFSCR or MSR */ if (!(vcpu->arch.hfscr & HFSCR_TM)) { @@ -208,6 +224,8 @@ } /* What should we do here? We didn't recognize the instruction */ - WARN_ON_ONCE(1); + kvmppc_core_queue_program(vcpu, SRR1_PROGILL); + pr_warn_ratelimited("Unrecognized TM-related instruction %#x for emulation", instr); + return RESUME_GUEST; } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_hv_tm_builtin.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_hv_tm_builtin.c @@ -23,7 +23,18 @@ u64 newmsr, msr, bescr; int rs; - switch (instr & 0xfc0007ff) { + /* + * rfid, rfebb, and mtmsrd encode bit 31 = 0 since it's a reserved bit + * in these instructions, so masking bit 31 out doesn't change these + * instructions. For the tsr. instruction if bit 31 = 0 then it is per + * ISA an invalid form, however P9 UM, in section 4.6.10 Book II Invalid + * Forms, informs specifically that ignoring bit 31 is an acceptable way + * to handle TM-related invalid forms that have bit 31 = 0. Moreover, + * for emulation purposes both forms (w/ and wo/ bit 31 set) can + * generate a softpatch interrupt. Hence both forms are handled below + * for tsr. to make them behave the same way. + */ + switch (instr & PO_XOP_OPCODE_MASK) { case PPC_INST_RFID: /* XXX do we need to check for PR=0 here? */ newmsr = vcpu->arch.shregs.srr1; @@ -73,7 +84,8 @@ vcpu->arch.shregs.msr = newmsr; return 1; - case PPC_INST_TSR: + /* ignore bit 31, see comment above */ + case (PPC_INST_TSR & PO_XOP_OPCODE_MASK): /* we know the MSR has the TS field = S (0b01) here */ msr = vcpu->arch.shregs.msr; /* check for PR=1 and arch 2.06 bit set in PCR */ --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_pr.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_pr.c @@ -1769,10 +1769,12 @@ err = kvmppc_mmu_init(vcpu); if (err < 0) - goto uninit_vcpu; + goto free_shared_page; return vcpu; +free_shared_page: + free_page((unsigned long)vcpu->arch.shared); uninit_vcpu: kvm_vcpu_uninit(vcpu); free_shadow_vcpu: --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_rtas.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_rtas.c @@ -240,6 +240,17 @@ * value so we can restore it on the way out. */ orig_rets = args.rets; + if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) { + /* + * Don't overflow our args array: ensure there is room for + * at least rets[0] (even if the call specifies 0 nret). + * + * Each handler must then check for the correct nargs and nret + * values, but they may always return failure in rets[0]. + */ + rc = -EINVAL; + goto fail; + } args.rets = &args.args[be32_to_cpu(args.nargs)]; mutex_lock(&vcpu->kvm->arch.rtas_token_lock); @@ -267,9 +278,17 @@ fail: /* * We only get here if the guest has called RTAS with a bogus - * args pointer. That means we can't get to the args, and so we - * can't fail the RTAS call. So fail right out to userspace, - * which should kill the guest. + * args pointer or nargs/nret values that would overflow the + * array. That means we can't get to the args, and so we can't + * fail the RTAS call. So fail right out to userspace, which + * should kill the guest. + * + * SLOF should actually pass the hcall return value from the + * rtas handler call in r3, so enter_rtas could be modified to + * return a failure indication in r3 and we could return such + * errors to the guest rather than failing to host userspace. + * However old guests that don't test for failure could then + * continue silently after errors, so for now we won't do this. */ return rc; } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_xive.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_xive.c @@ -2005,6 +2005,10 @@ pr_devel("Creating xive for partition\n"); + /* Already there ? */ + if (kvm->arch.xive) + return -EEXIST; + xive = kvmppc_xive_get_device(kvm, type); if (!xive) return -ENOMEM; @@ -2014,12 +2018,6 @@ xive->kvm = kvm; mutex_init(&xive->lock); - /* Already there ? */ - if (kvm->arch.xive) - ret = -EEXIST; - else - kvm->arch.xive = xive; - /* We use the default queue size set by the host */ xive->q_order = xive_native_default_eq_shift(); if (xive->q_order < PAGE_SHIFT) @@ -2039,6 +2037,7 @@ if (ret) return ret; + kvm->arch.xive = xive; return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/book3s_xive_native.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/book3s_xive_native.c @@ -50,6 +50,24 @@ } } +static int kvmppc_xive_native_configure_queue(u32 vp_id, struct xive_q *q, + u8 prio, __be32 *qpage, + u32 order, bool can_escalate) +{ + int rc; + __be32 *qpage_prev = q->qpage; + + rc = xive_native_configure_queue(vp_id, q, prio, qpage, order, + can_escalate); + if (rc) + return rc; + + if (qpage_prev) + put_page(virt_to_page(qpage_prev)); + + return rc; +} + void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu) { struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu; @@ -234,6 +252,13 @@ } state = &sb->irq_state[src]; + + /* Some sanity checking */ + if (!state->valid) { + pr_devel("%s: source %lx invalid !\n", __func__, irq); + return VM_FAULT_SIGBUS; + } + kvmppc_xive_select_irq(state, &hw_num, &xd); arch_spin_lock(&sb->lock); @@ -582,19 +607,14 @@ q->guest_qaddr = 0; q->guest_qshift = 0; - rc = xive_native_configure_queue(xc->vp_id, q, priority, - NULL, 0, true); + rc = kvmppc_xive_native_configure_queue(xc->vp_id, q, priority, + NULL, 0, true); if (rc) { pr_err("Failed to reset queue %d for VCPU %d: %d\n", priority, xc->server_num, rc); return rc; } - if (q->qpage) { - put_page(virt_to_page(q->qpage)); - q->qpage = NULL; - } - return 0; } @@ -624,17 +644,18 @@ srcu_idx = srcu_read_lock(&kvm->srcu); gfn = gpa_to_gfn(kvm_eq.qaddr); - page = gfn_to_page(kvm, gfn); - if (is_error_page(page)) { + + page_size = kvm_host_page_size(vcpu, gfn); + if (1ull << kvm_eq.qshift > page_size) { srcu_read_unlock(&kvm->srcu, srcu_idx); - pr_err("Couldn't get queue page %llx!\n", kvm_eq.qaddr); + pr_warn("Incompatible host page size %lx!\n", page_size); return -EINVAL; } - page_size = kvm_host_page_size(kvm, gfn); - if (1ull << kvm_eq.qshift > page_size) { + page = gfn_to_page(kvm, gfn); + if (is_error_page(page)) { srcu_read_unlock(&kvm->srcu, srcu_idx); - pr_warn("Incompatible host page size %lx!\n", page_size); + pr_err("Couldn't get queue page %llx!\n", kvm_eq.qaddr); return -EINVAL; } @@ -653,8 +674,8 @@ * OPAL level because the use of END ESBs is not supported by * Linux. */ - rc = xive_native_configure_queue(xc->vp_id, q, priority, - (__be32 *) qaddr, kvm_eq.qshift, true); + rc = kvmppc_xive_native_configure_queue(xc->vp_id, q, priority, + (__be32 *) qaddr, kvm_eq.qshift, true); if (rc) { pr_err("Failed to configure queue %d for VCPU %d: %d\n", priority, xc->server_num, rc); @@ -1081,7 +1102,6 @@ dev->private = xive; xive->dev = dev; xive->kvm = kvm; - kvm->arch.xive = xive; mutex_init(&xive->mapping_lock); mutex_init(&xive->lock); @@ -1102,6 +1122,7 @@ if (ret) return ret; + kvm->arch.xive = xive; return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/e500_mmu_host.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/e500_mmu_host.c @@ -734,7 +734,8 @@ return 0; } -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end) +int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, + unsigned flags) { /* kvm_unmap_hva flushes everything anyways */ kvm_unmap_hva(kvm, start); --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/emulate_loadstore.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/emulate_loadstore.c @@ -73,7 +73,6 @@ { struct kvm_run *run = vcpu->run; u32 inst; - int ra, rs, rt; enum emulation_result emulated = EMULATE_FAIL; int advance = 1; struct instruction_op op; @@ -85,10 +84,6 @@ if (emulated != EMULATE_DONE) return emulated; - ra = get_ra(inst); - rs = get_rs(inst); - rt = get_rt(inst); - vcpu->arch.mmio_vsx_copy_nums = 0; vcpu->arch.mmio_vsx_offset = 0; vcpu->arch.mmio_copy_type = KVMPPC_VSX_COPY_NONE; --- linux-oracle-5.4.0.orig/arch/powerpc/kvm/powerpc.c +++ linux-oracle-5.4.0/arch/powerpc/kvm/powerpc.c @@ -1495,7 +1495,7 @@ { enum emulation_result emulated = EMULATE_DONE; - if (vcpu->arch.mmio_vsx_copy_nums > 2) + if (vcpu->arch.mmio_vmx_copy_nums > 2) return EMULATE_FAIL; while (vcpu->arch.mmio_vmx_copy_nums) { @@ -1513,7 +1513,7 @@ return emulated; } -int kvmppc_get_vmx_dword(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_dword(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1531,7 +1531,7 @@ return result; } -int kvmppc_get_vmx_word(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_word(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1549,7 +1549,7 @@ return result; } -int kvmppc_get_vmx_hword(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_hword(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1567,7 +1567,7 @@ return result; } -int kvmppc_get_vmx_byte(struct kvm_vcpu *vcpu, int index, u64 *val) +static int kvmppc_get_vmx_byte(struct kvm_vcpu *vcpu, int index, u64 *val) { union kvmppc_one_reg reg; int vmx_offset = 0; @@ -1592,7 +1592,7 @@ unsigned int index = rs & KVM_MMIO_REG_MASK; enum emulation_result emulated = EMULATE_DONE; - if (vcpu->arch.mmio_vsx_copy_nums > 2) + if (vcpu->arch.mmio_vmx_copy_nums > 2) return EMULATE_FAIL; vcpu->arch.io_gpr = rs; @@ -1950,8 +1950,10 @@ break; r = -ENXIO; - if (!xive_enabled()) + if (!xive_enabled()) { + fdput(f); break; + } r = -EPERM; dev = kvm_device_from_filp(f.file); @@ -2035,9 +2037,9 @@ { struct kvm_enable_cap cap; r = -EFAULT; - vcpu_load(vcpu); if (copy_from_user(&cap, argp, sizeof(cap))) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); vcpu_put(vcpu); break; @@ -2061,9 +2063,9 @@ case KVM_DIRTY_TLB: { struct kvm_dirty_tlb dirty; r = -EFAULT; - vcpu_load(vcpu); if (copy_from_user(&dirty, argp, sizeof(dirty))) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); vcpu_put(vcpu); break; --- linux-oracle-5.4.0.orig/arch/powerpc/lib/Makefile +++ linux-oracle-5.4.0/arch/powerpc/lib/Makefile @@ -16,6 +16,9 @@ CFLAGS_feature-fixups.o += -DDISABLE_BRANCH_PROFILING endif +CFLAGS_code-patching.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_feature-fixups.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) + obj-y += alloc.o code-patching.o feature-fixups.o pmem.o ifndef CONFIG_KASAN @@ -31,8 +34,8 @@ # 64-bit linker creates .sfpr on demand for final link (vmlinux), # so it is only needed for modules, and only for older linkers which # do not support --save-restore-funcs -ifeq ($(call ld-ifversion, -lt, 225000000, y),y) -extra-$(CONFIG_PPC64) += crtsavres.o +ifeq ($(call ld-ifversion, -lt, 225000000, y)$(CONFIG_PPC64),yy) +always += crtsavres.o endif obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ @@ -58,6 +61,6 @@ obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o obj-$(CONFIG_ALTIVEC) += xor_vmx.o xor_vmx_glue.o -CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec) +CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec) obj-$(CONFIG_PPC64) += $(obj64-y) --- linux-oracle-5.4.0.orig/arch/powerpc/lib/code-patching.c +++ linux-oracle-5.4.0/arch/powerpc/lib/code-patching.c @@ -45,7 +45,7 @@ { struct vm_struct *area; - area = get_vm_area(PAGE_SIZE, VM_ALLOC); + area = get_vm_area(PAGE_SIZE, 0); if (!area) { WARN_ONCE(1, "Failed to create text area for cpu %d\n", cpu); @@ -221,6 +221,11 @@ return (offset >= -0x2000000 && offset <= 0x1fffffc && !(offset & 0x3)); } +bool is_offset_in_cond_branch_range(long offset) +{ + return offset >= -0x8000 && offset <= 0x7fff && !(offset & 0x3); +} + /* * Helper to check if a given instruction is a conditional branch * Derived from the conditional checks in analyse_instr() @@ -274,7 +279,7 @@ offset = offset - (unsigned long)addr; /* Check we can represent the target in the instruction format */ - if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3) + if (!is_offset_in_cond_branch_range(offset)) return 0; /* Mask out the flags and target, so they don't step on each other. */ --- linux-oracle-5.4.0.orig/arch/powerpc/lib/feature-fixups.c +++ linux-oracle-5.4.0/arch/powerpc/lib/feature-fixups.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -221,11 +222,143 @@ : "unknown"); } +static int __do_stf_barrier_fixups(void *data) +{ + enum stf_barrier_type *types = data; + + do_stf_entry_barrier_fixups(*types); + do_stf_exit_barrier_fixups(*types); + + return 0; +} void do_stf_barrier_fixups(enum stf_barrier_type types) { - do_stf_entry_barrier_fixups(types); - do_stf_exit_barrier_fixups(types); + /* + * The call to the fallback entry flush, and the fallback/sync-ori exit + * flush can not be safely patched in/out while other CPUs are executing + * them. So call __do_stf_barrier_fixups() on one CPU while all other CPUs + * spin in the stop machine core with interrupts hard disabled. + */ + stop_machine(__do_stf_barrier_fixups, &types, NULL); +} + +void do_uaccess_flush_fixups(enum l1d_flush_type types) +{ + unsigned int instrs[4], *dest; + long *start, *end; + int i; + + start = PTRRELOC(&__start___uaccess_flush_fixup); + end = PTRRELOC(&__stop___uaccess_flush_fixup); + + instrs[0] = 0x60000000; /* nop */ + instrs[1] = 0x60000000; /* nop */ + instrs[2] = 0x60000000; /* nop */ + instrs[3] = 0x4e800020; /* blr */ + + i = 0; + if (types == L1D_FLUSH_FALLBACK) { + instrs[3] = 0x60000000; /* nop */ + /* fallthrough to fallback flush */ + } + + if (types & L1D_FLUSH_ORI) { + instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */ + instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ + } + + if (types & L1D_FLUSH_MTTRIG) + instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ + + for (i = 0; start < end; start++, i++) { + dest = (void *)start + *start; + + pr_devel("patching dest %lx\n", (unsigned long)dest); + + patch_instruction(dest, instrs[0]); + + patch_instruction((dest + 1), instrs[1]); + patch_instruction((dest + 2), instrs[2]); + patch_instruction((dest + 3), instrs[3]); + } + + printk(KERN_DEBUG "uaccess-flush: patched %d locations (%s flush)\n", i, + (types == L1D_FLUSH_NONE) ? "no" : + (types == L1D_FLUSH_FALLBACK) ? "fallback displacement" : + (types & L1D_FLUSH_ORI) ? (types & L1D_FLUSH_MTTRIG) + ? "ori+mttrig type" + : "ori type" : + (types & L1D_FLUSH_MTTRIG) ? "mttrig type" + : "unknown"); +} + +static int __do_entry_flush_fixups(void *data) +{ + enum l1d_flush_type types = *(enum l1d_flush_type *)data; + unsigned int instrs[3], *dest; + long *start, *end; + int i; + + start = PTRRELOC(&__start___entry_flush_fixup); + end = PTRRELOC(&__stop___entry_flush_fixup); + + instrs[0] = 0x60000000; /* nop */ + instrs[1] = 0x60000000; /* nop */ + instrs[2] = 0x60000000; /* nop */ + + i = 0; + if (types == L1D_FLUSH_FALLBACK) { + instrs[i++] = 0x7d4802a6; /* mflr r10 */ + instrs[i++] = 0x60000000; /* branch patched below */ + instrs[i++] = 0x7d4803a6; /* mtlr r10 */ + } + + if (types & L1D_FLUSH_ORI) { + instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier */ + instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ + } + + if (types & L1D_FLUSH_MTTRIG) + instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ + + for (i = 0; start < end; start++, i++) { + dest = (void *)start + *start; + + pr_devel("patching dest %lx\n", (unsigned long)dest); + + patch_instruction(dest, instrs[0]); + + if (types == L1D_FLUSH_FALLBACK) + patch_branch((dest + 1), (unsigned long)&entry_flush_fallback, + BRANCH_SET_LINK); + else + patch_instruction((dest + 1), instrs[1]); + + patch_instruction((dest + 2), instrs[2]); + } + + printk(KERN_DEBUG "entry-flush: patched %d locations (%s flush)\n", i, + (types == L1D_FLUSH_NONE) ? "no" : + (types == L1D_FLUSH_FALLBACK) ? "fallback displacement" : + (types & L1D_FLUSH_ORI) ? (types & L1D_FLUSH_MTTRIG) + ? "ori+mttrig type" + : "ori type" : + (types & L1D_FLUSH_MTTRIG) ? "mttrig type" + : "unknown"); + + return 0; +} + +void do_entry_flush_fixups(enum l1d_flush_type types) +{ + /* + * The call to the fallback flush can not be safely patched in/out while + * other CPUs are executing it. So call __do_entry_flush_fixups() on one + * CPU while all other CPUs spin in the stop machine core with interrupts + * hard disabled. + */ + stop_machine(__do_entry_flush_fixups, &types, NULL); } void do_rfi_flush_fixups(enum l1d_flush_type types) --- linux-oracle-5.4.0.orig/arch/powerpc/lib/sstep.c +++ linux-oracle-5.4.0/arch/powerpc/lib/sstep.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -469,6 +470,8 @@ } u; nb = GETSIZE(op->type); + if (nb > sizeof(u)) + return -EINVAL; if (!address_ok(regs, ea, nb)) return -EFAULT; rn = op->reg; @@ -519,6 +522,8 @@ } u; nb = GETSIZE(op->type); + if (nb > sizeof(u)) + return -EINVAL; if (!address_ok(regs, ea, nb)) return -EFAULT; rn = op->reg; @@ -563,6 +568,9 @@ u8 b[sizeof(__vector128)]; } u = {}; + if (size > sizeof(u)) + return -EINVAL; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; /* align to multiple of size */ @@ -590,6 +598,9 @@ u8 b[sizeof(__vector128)]; } u; + if (size > sizeof(u)) + return -EINVAL; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; /* align to multiple of size */ @@ -653,8 +664,8 @@ #endif /* __powerpc64 */ #ifdef CONFIG_VSX -void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, - const void *mem, bool rev) +static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, + const void *mem, bool rev) { int size, read_size; int i, j; @@ -734,11 +745,9 @@ break; } } -EXPORT_SYMBOL_GPL(emulate_vsx_load); -NOKPROBE_SYMBOL(emulate_vsx_load); -void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, - void *mem, bool rev) +static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg, + void *mem, bool rev) { int size, write_size; int i, j; @@ -810,8 +819,6 @@ break; } } -EXPORT_SYMBOL_GPL(emulate_vsx_store); -NOKPROBE_SYMBOL(emulate_vsx_store); static nokprobe_inline int do_vsx_load(struct instruction_op *op, unsigned long ea, struct pt_regs *regs, @@ -906,7 +913,10 @@ #define __put_user_asmx(x, addr, err, op, cr) \ __asm__ __volatile__( \ + ".machine push\n" \ + ".machine power8\n" \ "1: " op " %2,0,%3\n" \ + ".machine pop\n" \ " mfcr %1\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ @@ -919,7 +929,10 @@ #define __get_user_asmx(x, addr, err, op) \ __asm__ __volatile__( \ + ".machine push\n" \ + ".machine power8\n" \ "1: "op" %1,0,%2\n" \ + ".machine pop\n" \ "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: li %0,%3\n" \ @@ -2787,12 +2800,14 @@ case BARRIER_EIEIO: eieio(); break; +#ifdef CONFIG_PPC64 case BARRIER_LWSYNC: asm volatile("lwsync" : : : "memory"); break; case BARRIER_PTESYNC: asm volatile("ptesync" : : : "memory"); break; +#endif } break; @@ -2910,7 +2925,7 @@ __put_user_asmx(op->val, ea, err, "stbcx.", cr); break; case 2: - __put_user_asmx(op->val, ea, err, "stbcx.", cr); + __put_user_asmx(op->val, ea, err, "sthcx.", cr); break; #endif case 4: --- linux-oracle-5.4.0.orig/arch/powerpc/lib/string_32.S +++ linux-oracle-5.4.0/arch/powerpc/lib/string_32.S @@ -17,7 +17,7 @@ LG_CACHELINE_BYTES = L1_CACHE_SHIFT CACHELINE_MASK = (L1_CACHE_BYTES-1) -_GLOBAL(__clear_user) +_GLOBAL(__arch_clear_user) /* * Use dcbz on the complete cache lines in the destination * to set them to zero. This requires that the destination @@ -87,4 +87,4 @@ EX_TABLE(8b, 91b) EX_TABLE(9b, 91b) -EXPORT_SYMBOL(__clear_user) +EXPORT_SYMBOL(__arch_clear_user) --- linux-oracle-5.4.0.orig/arch/powerpc/lib/string_64.S +++ linux-oracle-5.4.0/arch/powerpc/lib/string_64.S @@ -17,7 +17,7 @@ .section ".text" /** - * __clear_user: - Zero a block of memory in user space, with less checking. + * __arch_clear_user: - Zero a block of memory in user space, with less checking. * @to: Destination address, in user space. * @n: Number of bytes to zero. * @@ -58,7 +58,7 @@ mr r3,r4 blr -_GLOBAL_TOC(__clear_user) +_GLOBAL_TOC(__arch_clear_user) cmpdi r4,32 neg r6,r3 li r0,0 @@ -181,4 +181,4 @@ cmpdi r4,32 blt .Lshort_clear b .Lmedium_clear -EXPORT_SYMBOL(__clear_user) +EXPORT_SYMBOL(__arch_clear_user) --- linux-oracle-5.4.0.orig/arch/powerpc/math-emu/math_efp.c +++ linux-oracle-5.4.0/arch/powerpc/math-emu/math_efp.c @@ -17,6 +17,7 @@ #include #include +#include #include #include --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s32/mmu.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s32/mmu.c @@ -187,6 +187,7 @@ int i; unsigned long base = (unsigned long)_stext - PAGE_OFFSET; unsigned long top = (unsigned long)_etext - PAGE_OFFSET; + unsigned long border = (unsigned long)__init_begin - PAGE_OFFSET; unsigned long size; if (IS_ENABLED(CONFIG_PPC_BOOK3S_601)) @@ -201,9 +202,10 @@ size = block_size(base, top); size = max(size, 128UL << 10); if ((top - base) > size) { - if (strict_kernel_rwx_enabled()) - pr_warn("Kernel _etext not properly aligned\n"); size <<= 1; + if (strict_kernel_rwx_enabled() && base + size > border) + pr_warn("Some RW data is getting mapped X. " + "Adjust CONFIG_DATA_SHIFT to avoid that.\n"); } setibat(i++, PAGE_OFFSET + base, base, size, PAGE_KERNEL_TEXT); base += size; --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/hash_utils.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/hash_utils.c @@ -294,10 +294,18 @@ ret = mmu_hash_ops.hpte_insert(hpteg, vpn, paddr, tprot, HPTE_V_BOLTED, psize, psize, ssize); - + if (ret == -1) { + /* Try to remove a non bolted entry */ + ret = mmu_hash_ops.hpte_remove(hpteg); + if (ret != -1) + ret = mmu_hash_ops.hpte_insert(hpteg, vpn, paddr, tprot, + HPTE_V_BOLTED, psize, psize, + ssize); + } if (ret < 0) break; + cond_resched(); #ifdef CONFIG_DEBUG_PAGEALLOC if (debug_pagealloc_enabled() && (paddr >> PAGE_SHIFT) < linear_map_hash_count) --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/iommu_api.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/iommu_api.c @@ -121,24 +121,6 @@ goto free_exit; } - pageshift = PAGE_SHIFT; - for (i = 0; i < entries; ++i) { - struct page *page = mem->hpages[i]; - - /* - * Allow to use larger than 64k IOMMU pages. Only do that - * if we are backed by hugetlb. - */ - if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) - pageshift = page_shift(compound_head(page)); - mem->pageshift = min(mem->pageshift, pageshift); - /* - * We don't need struct page reference any more, switch - * to physical address. - */ - mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT; - } - good_exit: atomic64_set(&mem->mapped, 1); mem->used = 1; @@ -158,6 +140,27 @@ } } + if (mem->dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) { + /* + * Allow to use larger than 64k IOMMU pages. Only do that + * if we are backed by hugetlb. Skip device memory as it is not + * backed with page structs. + */ + pageshift = PAGE_SHIFT; + for (i = 0; i < entries; ++i) { + struct page *page = mem->hpages[i]; + + if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) + pageshift = page_shift(compound_head(page)); + mem->pageshift = min(mem->pageshift, pageshift); + /* + * We don't need struct page reference any more, switch + * to physical address. + */ + mem->hpas[i] = page_to_pfn(page) << PAGE_SHIFT; + } + } + list_add_rcu(&mem->next, &mm->context.iommu_group_mem_list); mutex_unlock(&mem_list_mutex); --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/pgtable.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/pgtable.c @@ -378,7 +378,6 @@ } } -#ifdef CONFIG_SMP void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index) { unsigned long pgf = (unsigned long)table; @@ -395,12 +394,6 @@ return pgtable_free(table, index); } -#else -void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index) -{ - return pgtable_free(table, index); -} -#endif #ifdef CONFIG_PROC_FS atomic_long_t direct_pages_count[MMU_PAGE_COUNT]; @@ -449,6 +442,7 @@ set_pte_at(vma->vm_mm, addr, ptep, pte); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE /* * For hash translation mode, we use the deposited table to store hash slot * information and they are stored at PTRS_PER_PMD offset from related pmd @@ -470,6 +464,7 @@ return true; } +#endif /* * Does the CPU support tlbie? --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/pkeys.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/pkeys.c @@ -83,13 +83,17 @@ scan_pkey_feature(); /* - * Let's assume 32 pkeys on P8 bare metal, if its not defined by device - * tree. We make this exception since skiboot forgot to expose this - * property on power8. + * Let's assume 32 pkeys on P8/P9 bare metal, if its not defined by device + * tree. We make this exception since some version of skiboot forgot to + * expose this property on power8/9. */ - if (!pkeys_devtree_defined && !firmware_has_feature(FW_FEATURE_LPAR) && - cpu_has_feature(CPU_FTRS_POWER8)) - pkeys_total = 32; + if (!pkeys_devtree_defined && !firmware_has_feature(FW_FEATURE_LPAR)) { + unsigned long pvr = mfspr(SPRN_PVR); + + if (PVR_VER(pvr) == PVR_POWER8 || PVR_VER(pvr) == PVR_POWER8E || + PVR_VER(pvr) == PVR_POWER8NVL || PVR_VER(pvr) == PVR_POWER9) + pkeys_total = 32; + } /* * Adjust the upper limit, based on the number of bits supported by @@ -367,12 +371,14 @@ return true; pkey_shift = pkeyshift(pkey); - if (execute && !(read_iamr() & (IAMR_EX_BIT << pkey_shift))) - return true; + if (execute) + return !(read_iamr() & (IAMR_EX_BIT << pkey_shift)); + + amr = read_amr(); + if (write) + return !(amr & (AMR_WR_BIT << pkey_shift)); - amr = read_amr(); /* Delay reading amr until absolutely needed */ - return ((!write && !(amr & (AMR_RD_BIT << pkey_shift))) || - (write && !(amr & (AMR_WR_BIT << pkey_shift)))); + return !(amr & (AMR_RD_BIT << pkey_shift)); } bool arch_pte_access_permitted(u64 pte, bool write, bool execute) --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/radix_pgtable.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -97,7 +97,7 @@ set_the_pte: set_pte_at(&init_mm, ea, ptep, pfn_pte(pfn, flags)); - smp_wmb(); + asm volatile("ptesync": : :"memory"); return 0; } @@ -155,7 +155,7 @@ set_the_pte: set_pte_at(&init_mm, ea, ptep, pfn_pte(pfn, flags)); - smp_wmb(); + asm volatile("ptesync": : :"memory"); return 0; } @@ -643,21 +643,6 @@ } } -void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size) -{ - /* - * We don't currently support the first MEMBLOCK not mapping 0 - * physical on those processors - */ - BUG_ON(first_memblock_base != 0); - - /* - * Radix mode is not limited by RMA / VRMA addressing. - */ - ppc64_rma_size = ULONG_MAX; -} - #ifdef CONFIG_MEMORY_HOTPLUG static void free_pte_table(pte_t *pte_start, pmd_t *pmd) { @@ -1033,8 +1018,8 @@ pte_t entry, unsigned long address, int psize) { struct mm_struct *mm = vma->vm_mm; - unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_RW | _PAGE_EXEC); + unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_SOFT_DIRTY | + _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); unsigned long change = pte_val(entry) ^ pte_val(*ptep); /* --- linux-oracle-5.4.0.orig/arch/powerpc/mm/book3s64/radix_tlb.c +++ linux-oracle-5.4.0/arch/powerpc/mm/book3s64/radix_tlb.c @@ -639,19 +639,29 @@ struct mm_struct *mm = arg; unsigned long pid = mm->context.id; + /* + * A kthread could have done a mmget_not_zero() after the flushing CPU + * checked mm_is_singlethreaded, and be in the process of + * kthread_use_mm when interrupted here. In that case, current->mm will + * be set to mm, because kthread_use_mm() setting ->mm and switching to + * the mm is done with interrupts off. + */ if (current->mm == mm) - return; /* Local CPU */ + goto out_flush; if (current->active_mm == mm) { - /* - * Must be a kernel thread because sender is single-threaded. - */ - BUG_ON(current->mm); + WARN_ON_ONCE(current->mm != NULL); + /* Is a kernel thread and is using mm as the lazy tlb */ mmgrab(&init_mm); - switch_mm(mm, &init_mm, current); current->active_mm = &init_mm; + switch_mm_irqs_off(mm, &init_mm, current); mmdrop(mm); } + + atomic_dec(&mm->context.active_cpus); + cpumask_clear_cpu(smp_processor_id(), mm_cpumask(mm)); + +out_flush: _tlbiel_pid(pid, RIC_FLUSH_ALL); } @@ -666,7 +676,6 @@ */ smp_call_function_many(mm_cpumask(mm), do_exit_flush_lazy_tlb, (void *)mm, 1); - mm_reset_thread_local(mm); } void radix__flush_tlb_mm(struct mm_struct *mm) --- linux-oracle-5.4.0.orig/arch/powerpc/mm/dma-noncoherent.c +++ linux-oracle-5.4.0/arch/powerpc/mm/dma-noncoherent.c @@ -104,14 +104,14 @@ #endif } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_sync_page(paddr, size, dir); } -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { __dma_sync_page(paddr, size, dir); } --- linux-oracle-5.4.0.orig/arch/powerpc/mm/drmem.c +++ linux-oracle-5.4.0/arch/powerpc/mm/drmem.c @@ -362,10 +362,8 @@ if (!drmem_info->lmbs) return; - for_each_drmem_lmb(lmb) { + for_each_drmem_lmb(lmb) read_drconf_v1_cell(lmb, &prop); - lmb_set_nid(lmb); - } } static void __init init_drmem_v2_lmbs(const __be32 *prop) @@ -410,8 +408,6 @@ lmb->aa_index = dr_cell.aa_index; lmb->flags = dr_cell.flags; - - lmb_set_nid(lmb); } } } --- linux-oracle-5.4.0.orig/arch/powerpc/mm/fault.c +++ linux-oracle-5.4.0/arch/powerpc/mm/fault.c @@ -204,9 +204,7 @@ { int is_exec = TRAP(regs) == 0x400; - /* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */ - if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT | - DSISR_PROTFAULT))) { + if (is_exec) { pr_crit_ratelimited("kernel tried to execute %s page (%lx) - exploit attempt? (uid: %d)\n", address >= TASK_SIZE ? "exec-protected" : "user", address, @@ -233,7 +231,7 @@ // Read/write fault in a valid region (the exception table search passed // above), but blocked by KUAP is bad, it can never succeed. - if (bad_kuap_fault(regs, is_write)) + if (bad_kuap_fault(regs, address, is_write)) return true; // What's left? Kernel fault on user in well defined regions (extable @@ -241,6 +239,9 @@ return false; } +// This comes from 64-bit struct rt_sigframe + __SIGNAL_FRAMESIZE +#define SIGFRAME_MAX_SIZE (4096 + 128) + static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address, struct vm_area_struct *vma, unsigned int flags, bool *must_retry) @@ -248,7 +249,7 @@ /* * N.B. The POWER/Open ABI allows programs to access up to * 288 bytes below the stack pointer. - * The kernel signal delivery code writes up to about 1.5kB + * The kernel signal delivery code writes a bit over 4KB * below the stack pointer (r1) before decrementing it. * The exec code can write slightly over 640kB to the stack * before setting the user r1. Thus we allow the stack to @@ -273,7 +274,7 @@ * between the last mapped region and the stack will * expand the stack rather than segfaulting. */ - if (address + 2048 >= uregs->gpr[1]) + if (address + SIGFRAME_MAX_SIZE >= uregs->gpr[1]) return false; if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) && @@ -346,7 +347,6 @@ static inline void cmo_account_page_fault(void) { } #endif /* CONFIG_PPC_SMLPAR */ -#ifdef CONFIG_PPC_BOOK3S static void sanity_check_fault(bool is_write, bool is_user, unsigned long error_code, unsigned long address) { @@ -354,12 +354,18 @@ * Userspace trying to access kernel address, we get PROTFAULT for that. */ if (is_user && address >= TASK_SIZE) { + if ((long)address == -1) + return; + pr_crit_ratelimited("%s[%d]: User access of kernel address (%lx) - exploit attempt? (uid: %d)\n", current->comm, current->pid, address, from_kuid(&init_user_ns, current_uid())); return; } + if (!IS_ENABLED(CONFIG_PPC_BOOK3S)) + return; + /* * For hash translation mode, we should never get a * PROTFAULT. Any update to pte to reduce access will result in us @@ -394,10 +400,6 @@ WARN_ON_ONCE(error_code & DSISR_PROTFAULT); } -#else -static void sanity_check_fault(bool is_write, bool is_user, - unsigned long error_code, unsigned long address) { } -#endif /* CONFIG_PPC_BOOK3S */ /* * Define the correct "is_write" bit in error_code based --- linux-oracle-5.4.0.orig/arch/powerpc/mm/hugetlbpage.c +++ linux-oracle-5.4.0/arch/powerpc/mm/hugetlbpage.c @@ -53,20 +53,24 @@ if (pshift >= pdshift) { cachep = PGT_CACHE(PTE_T_ORDER); num_hugepd = 1 << (pshift - pdshift); + new = NULL; } else if (IS_ENABLED(CONFIG_PPC_8xx)) { - cachep = PGT_CACHE(PTE_INDEX_SIZE); + cachep = NULL; num_hugepd = 1; + new = pte_alloc_one(mm); } else { cachep = PGT_CACHE(pdshift - pshift); num_hugepd = 1; + new = NULL; } - if (!cachep) { + if (!cachep && !new) { WARN_ONCE(1, "No page table cache created for hugetlb tables"); return -ENOMEM; } - new = kmem_cache_alloc(cachep, pgtable_gfp_flags(mm, GFP_KERNEL)); + if (cachep) + new = kmem_cache_alloc(cachep, pgtable_gfp_flags(mm, GFP_KERNEL)); BUG_ON(pshift > HUGEPD_SHIFT_MASK); BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK); @@ -97,7 +101,10 @@ if (i < num_hugepd) { for (i = i - 1 ; i >= 0; i--, hpdp--) *hpdp = __hugepd(0); - kmem_cache_free(cachep, new); + if (cachep) + kmem_cache_free(cachep, new); + else + pte_free(mm, new); } else { kmemleak_ignore(new); } @@ -324,8 +331,7 @@ if (shift >= pdshift) hugepd_free(tlb, hugepte); else if (IS_ENABLED(CONFIG_PPC_8xx)) - pgtable_free_tlb(tlb, hugepte, - get_hugepd_cache_index(PTE_INDEX_SIZE)); + pgtable_free_tlb(tlb, hugepte, 0); else pgtable_free_tlb(tlb, hugepte, get_hugepd_cache_index(pdshift - shift)); @@ -639,12 +645,13 @@ * if we have pdshift and shift value same, we don't * use pgt cache for hugepd. */ - if (pdshift > shift && IS_ENABLED(CONFIG_PPC_8xx)) - pgtable_cache_add(PTE_INDEX_SIZE); - else if (pdshift > shift) - pgtable_cache_add(pdshift - shift); - else if (IS_ENABLED(CONFIG_PPC_FSL_BOOK3E) || IS_ENABLED(CONFIG_PPC_8xx)) + if (pdshift > shift) { + if (!IS_ENABLED(CONFIG_PPC_8xx)) + pgtable_cache_add(pdshift - shift); + } else if (IS_ENABLED(CONFIG_PPC_FSL_BOOK3E) || + IS_ENABLED(CONFIG_PPC_8xx)) { pgtable_cache_add(PTE_T_ORDER); + } configured = true; } --- linux-oracle-5.4.0.orig/arch/powerpc/mm/init-common.c +++ linux-oracle-5.4.0/arch/powerpc/mm/init-common.c @@ -104,7 +104,7 @@ * as to leave enough 0 bits in the address to contain it. */ unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1, HUGEPD_SHIFT_MASK + 1); - struct kmem_cache *new; + struct kmem_cache *new = NULL; /* It would be nice if this was a BUILD_BUG_ON(), but at the * moment, gcc doesn't seem to recognize is_power_of_2 as a @@ -117,7 +117,8 @@ align = max_t(unsigned long, align, minalign); name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); - new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); + if (name) + new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); if (!new) panic("Could not allocate pgtable cache for order %d", shift); --- linux-oracle-5.4.0.orig/arch/powerpc/mm/init_64.c +++ linux-oracle-5.4.0/arch/powerpc/mm/init_64.c @@ -178,7 +178,7 @@ unsigned long nr_pfn = page_size / sizeof(struct page); unsigned long start_pfn = page_to_pfn((struct page *)start); - if ((start_pfn + nr_pfn) > altmap->end_pfn) + if ((start_pfn + nr_pfn - 1) > altmap->end_pfn) return true; if (start_pfn < altmap->base_pfn) @@ -279,8 +279,7 @@ start = _ALIGN_DOWN(start, page_size); if (altmap) { alt_start = altmap->base_pfn; - alt_end = altmap->base_pfn + altmap->reserve + - altmap->free + altmap->alloc + altmap->align; + alt_end = altmap->base_pfn + altmap->reserve + altmap->free; } pr_debug("vmemmap_free %lx...%lx\n", start, end); @@ -415,9 +414,16 @@ if (!(mfmsr() & MSR_HV)) early_check_vec5(); - if (early_radix_enabled()) + if (early_radix_enabled()) { radix__early_init_devtree(); - else + /* + * We have finalized the translation we are going to use by now. + * Radix mode is not limited by RMA / VRMA addressing. + * Hence don't limit memblock allocations. + */ + ppc64_rma_size = ULONG_MAX; + memblock_set_current_limit(MEMBLOCK_ALLOC_ANYWHERE); + } else hash__early_init_devtree(); } #endif /* CONFIG_PPC_BOOK3S_64 */ --- linux-oracle-5.4.0.orig/arch/powerpc/mm/kasan/Makefile +++ linux-oracle-5.4.0/arch/powerpc/mm/kasan/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 KASAN_SANITIZE := n +KCOV_INSTRUMENT := n obj-$(CONFIG_PPC32) += kasan_init_32.o --- linux-oracle-5.4.0.orig/arch/powerpc/mm/kasan/kasan_init_32.c +++ linux-oracle-5.4.0/arch/powerpc/mm/kasan/kasan_init_32.c @@ -90,8 +90,10 @@ if (ret) return ret; - if (!slab_is_available()) + if (!slab_is_available()) { + k_start = k_start & PAGE_MASK; block = memblock_alloc(k_end - k_start, PAGE_SIZE); + } for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); @@ -117,11 +119,11 @@ kasan_populate_pte(kasan_early_shadow_pte, prot); - for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) { + for (k_cur = k_start & PAGE_MASK; k_cur != k_end; k_cur += PAGE_SIZE) { pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur); pte_t *ptep = pte_offset_kernel(pmd, k_cur); - if ((pte_val(*ptep) & PTE_RPN_MASK) != pa) + if (pte_page(*ptep) != virt_to_page(lm_alias(kasan_early_shadow_page))) continue; __set_pte_at(&init_mm, k_cur, ptep, pfn_pte(PHYS_PFN(pa), prot), 0); --- linux-oracle-5.4.0.orig/arch/powerpc/mm/mem.c +++ linux-oracle-5.4.0/arch/powerpc/mm/mem.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -104,6 +105,27 @@ return -ENODEV; } +#define FLUSH_CHUNK_SIZE SZ_1G +/** + * flush_dcache_range_chunked(): Write any modified data cache blocks out to + * memory and invalidate them, in chunks of up to FLUSH_CHUNK_SIZE + * Does not invalidate the corresponding instruction cache blocks. + * + * @start: the start address + * @stop: the stop address (exclusive) + * @chunk: the max size of the chunks + */ +static void flush_dcache_range_chunked(unsigned long start, unsigned long stop, + unsigned long chunk) +{ + unsigned long i; + + for (i = start; i < stop; i += chunk) { + flush_dcache_range(i, min(stop, i + chunk)); + cond_resched(); + } +} + int __ref arch_add_memory(int nid, u64 start, u64 size, struct mhp_restrictions *restrictions) { @@ -120,7 +142,8 @@ start, start + size, rc); return -EFAULT; } - flush_dcache_range(start, start + size); + + flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE); return __add_pages(nid, start_pfn, nr_pages, restrictions); } @@ -130,14 +153,14 @@ { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); int ret; - __remove_pages(page_zone(page), start_pfn, nr_pages, altmap); + __remove_pages(start_pfn, nr_pages, altmap); /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); - flush_dcache_range(start, start + size); + flush_dcache_range_chunked(start, start + size, FLUSH_CHUNK_SIZE); + ret = remove_section_mapping(start, start + size); WARN_ON_ONCE(ret); @@ -246,7 +269,7 @@ max_zone_pfns[ZONE_HIGHMEM] = max_pfn; #endif - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); mark_nonram_nosave(); } @@ -260,6 +283,14 @@ BUILD_BUG_ON(MMU_PAGE_COUNT > 16); #ifdef CONFIG_SWIOTLB + /* + * Some platforms (e.g. 85xx) limit DMA-able memory way below + * 4G. We force memblock to bottom-up mode to ensure that the + * memory allocated in swiotlb_init() is DMA-able. + * As it's the last memblock allocation, no need to reset it + * back to to-down. + */ + memblock_set_bottom_up(true); swiotlb_init(0); #endif @@ -316,7 +347,124 @@ mark_initmem_nx(); init_mem_is_free = true; free_initmem_default(POISON_FREE_INITMEM); + ftrace_free_init_tramp(); +} + +/** + * flush_coherent_icache() - if a CPU has a coherent icache, flush it + * @addr: The base address to use (can be any valid address, the whole cache will be flushed) + * Return true if the cache was flushed, false otherwise + */ +static inline bool flush_coherent_icache(unsigned long addr) +{ + /* + * For a snooping icache, we still need a dummy icbi to purge all the + * prefetched instructions from the ifetch buffers. We also need a sync + * before the icbi to order the the actual stores to memory that might + * have modified instructions with the icbi. + */ + if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { + mb(); /* sync */ + allow_read_from_user((const void __user *)addr, L1_CACHE_BYTES); + icbi((void *)addr); + prevent_read_from_user((const void __user *)addr, L1_CACHE_BYTES); + mb(); /* sync */ + isync(); + return true; + } + + return false; +} + +/** + * invalidate_icache_range() - Flush the icache by issuing icbi across an address range + * @start: the start address + * @stop: the stop address (exclusive) + */ +static void invalidate_icache_range(unsigned long start, unsigned long stop) +{ + unsigned long shift = l1_icache_shift(); + unsigned long bytes = l1_icache_bytes(); + char *addr = (char *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); + unsigned long i; + + for (i = 0; i < size >> shift; i++, addr += bytes) + icbi(addr); + + mb(); /* sync */ + isync(); +} + +/** + * flush_icache_range: Write any modified data cache blocks out to memory + * and invalidate the corresponding blocks in the instruction cache + * + * Generic code will call this after writing memory, before executing from it. + * + * @start: the start address + * @stop: the stop address (exclusive) + */ +void flush_icache_range(unsigned long start, unsigned long stop) +{ + if (flush_coherent_icache(start)) + return; + + clean_dcache_range(start, stop); + + if (IS_ENABLED(CONFIG_44x)) { + /* + * Flash invalidate on 44x because we are passed kmapped + * addresses and this doesn't work for userspace pages due to + * the virtually tagged icache. + */ + iccci((void *)start); + mb(); /* sync */ + isync(); + } else + invalidate_icache_range(start, stop); +} +EXPORT_SYMBOL(flush_icache_range); + +#if !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64) +/** + * flush_dcache_icache_phys() - Flush a page by it's physical address + * @physaddr: the physical address of the page + */ +static void flush_dcache_icache_phys(unsigned long physaddr) +{ + unsigned long bytes = l1_dcache_bytes(); + unsigned long nb = PAGE_SIZE / bytes; + unsigned long addr = physaddr & PAGE_MASK; + unsigned long msr, msr0; + unsigned long loop1 = addr, loop2 = addr; + + msr0 = mfmsr(); + msr = msr0 & ~MSR_DR; + /* + * This must remain as ASM to prevent potential memory accesses + * while the data MMU is disabled + */ + asm volatile( + " mtctr %2;\n" + " mtmsr %3;\n" + " isync;\n" + "0: dcbst 0, %0;\n" + " addi %0, %0, %4;\n" + " bdnz 0b;\n" + " sync;\n" + " mtctr %2;\n" + "1: icbi 0, %1;\n" + " addi %1, %1, %4;\n" + " bdnz 1b;\n" + " sync;\n" + " mtmsr %5;\n" + " isync;\n" + : "+&r" (loop1), "+&r" (loop2) + : "r" (nb), "r" (msr), "i" (bytes), "r" (msr0) + : "ctr", "memory"); } +#endif // !defined(CONFIG_PPC_8xx) && !defined(CONFIG_PPC64) /* * This is called when a page has been modified by the kernel. @@ -350,12 +498,46 @@ __flush_dcache_icache(start); kunmap_atomic(start); } else { - __flush_dcache_icache_phys(page_to_pfn(page) << PAGE_SHIFT); + unsigned long addr = page_to_pfn(page) << PAGE_SHIFT; + + if (flush_coherent_icache(addr)) + return; + flush_dcache_icache_phys(addr); } #endif } EXPORT_SYMBOL(flush_dcache_icache_page); +/** + * __flush_dcache_icache(): Flush a particular page from the data cache to RAM. + * Note: this is necessary because the instruction cache does *not* + * snoop from the data cache. + * + * @page: the address of the page to flush + */ +void __flush_dcache_icache(void *p) +{ + unsigned long addr = (unsigned long)p; + + if (flush_coherent_icache(addr)) + return; + + clean_dcache_range(addr, addr + PAGE_SIZE); + + /* + * We don't flush the icache on 44x. Those have a virtual icache and we + * don't have access to the virtual address here (it's not the page + * vaddr but where it's mapped in user space). The flushing of the + * icache on these is handled elsewhere, when a change in the address + * space occurs, before returning to user space. + */ + + if (mmu_has_feature(MMU_FTR_TYPE_44x)) + return; + + invalidate_icache_range(addr, addr + PAGE_SIZE); +} + void clear_user_page(void *page, unsigned long vaddr, struct page *pg) { clear_page(page); --- linux-oracle-5.4.0.orig/arch/powerpc/mm/mmu_context.c +++ linux-oracle-5.4.0/arch/powerpc/mm/mmu_context.c @@ -79,7 +79,7 @@ * context */ if (cpu_has_feature(CPU_FTR_ALTIVEC)) - asm volatile ("dssall"); + asm volatile (PPC_DSSALL); if (new_on_cpu) radix_kvm_prefetch_workaround(next); --- linux-oracle-5.4.0.orig/arch/powerpc/mm/nohash/tlb_low.S +++ linux-oracle-5.4.0/arch/powerpc/mm/nohash/tlb_low.S @@ -397,7 +397,7 @@ * extern void loadcam_entry(unsigned int index) * * Load TLBCAM[index] entry in to the L2 CAM MMU - * Must preserve r7, r8, r9, and r10 + * Must preserve r7, r8, r9, r10 and r11 */ _GLOBAL(loadcam_entry) mflr r5 @@ -433,6 +433,10 @@ */ _GLOBAL(loadcam_multi) mflr r8 + /* Don't switch to AS=1 if already there */ + mfmsr r11 + andi. r11,r11,MSR_IS + bne 10f /* * Set up temporary TLB entry that is the same as what we're @@ -458,6 +462,7 @@ mtmsr r6 isync +10: mr r9,r3 add r10,r3,r4 2: bl loadcam_entry @@ -466,6 +471,10 @@ mr r3,r9 blt 2b + /* Don't return to AS=0 if we were in AS=1 at function start */ + andi. r11,r11,MSR_IS + bne 3f + /* Return to AS=0 and clear the temporary entry */ mfmsr r6 rlwinm. r6,r6,0,~(MSR_IS|MSR_DS) @@ -481,6 +490,7 @@ tlbwe isync +3: mtlr r8 blr #endif --- linux-oracle-5.4.0.orig/arch/powerpc/mm/pgtable_32.c +++ linux-oracle-5.4.0/arch/powerpc/mm/pgtable_32.c @@ -207,7 +207,7 @@ unsigned long numpages = PFN_UP((unsigned long)_einittext) - PFN_DOWN((unsigned long)_sinittext); - if (v_block_mapped((unsigned long)_stext + 1)) + if (v_block_mapped((unsigned long)_sinittext)) mmu_mark_initmem_nx(); else change_page_attr(page, numpages, PAGE_KERNEL); @@ -219,8 +219,9 @@ struct page *page; unsigned long numpages; - if (v_block_mapped((unsigned long)_sinittext)) { + if (v_block_mapped((unsigned long)_stext + 1)) { mmu_mark_rodata_ro(); + ptdump_check_wx(); return; } --- linux-oracle-5.4.0.orig/arch/powerpc/mm/ptdump/hashpagetable.c +++ linux-oracle-5.4.0/arch/powerpc/mm/ptdump/hashpagetable.c @@ -259,7 +259,7 @@ for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) { lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes); - if (lpar_rc != H_SUCCESS) + if (lpar_rc) continue; for (j = 0; j < 4; j++) { if (HPTE_V_COMPARE(ptes[j].v, want_v) && --- linux-oracle-5.4.0.orig/arch/powerpc/mm/ptdump/ptdump.c +++ linux-oracle-5.4.0/arch/powerpc/mm/ptdump/ptdump.c @@ -58,6 +58,7 @@ unsigned long start_address; unsigned long start_pa; unsigned long last_pa; + unsigned long page_size; unsigned int level; u64 current_flags; bool check_wx; @@ -155,9 +156,9 @@ #endif pt_dump_seq_printf(st->seq, REG "-" REG " ", st->start_address, addr - 1); - if (st->start_pa == st->last_pa && st->start_address + PAGE_SIZE != addr) { + if (st->start_pa == st->last_pa && st->start_address + st->page_size != addr) { pt_dump_seq_printf(st->seq, "[" REG "]", st->start_pa); - delta = PAGE_SIZE >> 10; + delta = st->page_size >> 10; } else { pt_dump_seq_printf(st->seq, " " REG " ", st->start_pa); delta = (addr - st->start_address) >> 10; @@ -173,10 +174,12 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr) { + pte_t pte = __pte(st->current_flags); + if (!IS_ENABLED(CONFIG_PPC_DEBUG_WX) || !st->check_wx) return; - if (!((st->current_flags & pgprot_val(PAGE_KERNEL_X)) == pgprot_val(PAGE_KERNEL_X))) + if (!pte_write(pte) || !pte_exec(pte)) return; WARN_ONCE(1, "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n", @@ -186,7 +189,7 @@ } static void note_page(struct pg_state *st, unsigned long addr, - unsigned int level, u64 val) + unsigned int level, u64 val, unsigned long page_size) { u64 flag = val & pg_level[level].mask; u64 pa = val & PTE_RPN_MASK; @@ -198,6 +201,7 @@ st->start_address = addr; st->start_pa = pa; st->last_pa = pa; + st->page_size = page_size; pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name); /* * Dump the section of virtual memory when: @@ -209,7 +213,7 @@ */ } else if (flag != st->current_flags || level != st->level || addr >= st->marker[1].start_address || - (pa != st->last_pa + PAGE_SIZE && + (pa != st->last_pa + st->page_size && (pa != st->start_pa || st->start_pa != st->last_pa))) { /* Check the PTE flags */ @@ -237,6 +241,7 @@ st->start_address = addr; st->start_pa = pa; st->last_pa = pa; + st->page_size = page_size; st->current_flags = flag; st->level = level; } else { @@ -252,7 +257,7 @@ for (i = 0; i < PTRS_PER_PTE; i++, pte++) { addr = start + i * PAGE_SIZE; - note_page(st, addr, 4, pte_val(*pte)); + note_page(st, addr, 4, pte_val(*pte), PAGE_SIZE); } } @@ -269,7 +274,7 @@ /* pmd exists */ walk_pte(st, pmd, addr); else - note_page(st, addr, 3, pmd_val(*pmd)); + note_page(st, addr, 3, pmd_val(*pmd), PMD_SIZE); } } @@ -285,7 +290,7 @@ /* pud exists */ walk_pmd(st, pud, addr); else - note_page(st, addr, 2, pud_val(*pud)); + note_page(st, addr, 2, pud_val(*pud), PUD_SIZE); } } @@ -304,7 +309,7 @@ /* pgd exists */ walk_pud(st, pgd, addr); else - note_page(st, addr, 1, pgd_val(*pgd)); + note_page(st, addr, 1, pgd_val(*pgd), PGDIR_SIZE); } } @@ -359,7 +364,7 @@ /* Traverse kernel page tables */ walk_pagetables(&st); - note_page(&st, 0, 0, 0); + note_page(&st, 0, 0, 0, 0); return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/mm/ptdump/shared.c +++ linux-oracle-5.4.0/arch/powerpc/mm/ptdump/shared.c @@ -17,9 +17,9 @@ .clear = " ", }, { .mask = _PAGE_RW, - .val = _PAGE_RW, - .set = "rw", - .clear = "r ", + .val = 0, + .set = "r ", + .clear = "rw", }, { .mask = _PAGE_EXEC, .val = _PAGE_EXEC, @@ -31,6 +31,11 @@ .set = "present", .clear = " ", }, { + .mask = _PAGE_COHERENT, + .val = _PAGE_COHERENT, + .set = "coherent", + .clear = " ", + }, { .mask = _PAGE_GUARDED, .val = _PAGE_GUARDED, .set = "guarded", --- linux-oracle-5.4.0.orig/arch/powerpc/mm/slice.c +++ linux-oracle-5.4.0/arch/powerpc/mm/slice.c @@ -50,7 +50,7 @@ #endif -static inline bool slice_addr_is_low(unsigned long addr) +static inline notrace bool slice_addr_is_low(unsigned long addr) { u64 tmp = (u64)addr; @@ -659,7 +659,7 @@ mm_ctx_user_psize(¤t->mm->context), 1); } -unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) +unsigned int notrace get_slice_psize(struct mm_struct *mm, unsigned long addr) { unsigned char *psizes; int index, mask_index; --- linux-oracle-5.4.0.orig/arch/powerpc/net/bpf_jit.h +++ linux-oracle-5.4.0/arch/powerpc/net/bpf_jit.h @@ -11,6 +11,7 @@ #ifndef __ASSEMBLY__ #include +#include #ifdef PPC64_ELF_ABI_v1 #define FUNCTION_DESCR_SIZE 24 @@ -180,13 +181,26 @@ #define PPC_NEG(d, a) EMIT(PPC_INST_NEG | ___PPC_RT(d) | ___PPC_RA(a)) /* Long jump; (unconditional 'branch') */ -#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \ - (((dest) - (ctx->idx * 4)) & 0x03fffffc)) +#define PPC_JMP(dest) \ + do { \ + long offset = (long)(dest) - (ctx->idx * 4); \ + if (!is_offset_in_branch_range(offset)) { \ + pr_err_ratelimited("Branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \ + return -ERANGE; \ + } \ + EMIT(PPC_INST_BRANCH | (offset & 0x03fffffc)); \ + } while (0) /* "cond" here covers BO:BI fields. */ -#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \ - (((cond) & 0x3ff) << 16) | \ - (((dest) - (ctx->idx * 4)) & \ - 0xfffc)) +#define PPC_BCC_SHORT(cond, dest) \ + do { \ + long offset = (long)(dest) - (ctx->idx * 4); \ + if (!is_offset_in_cond_branch_range(offset)) { \ + pr_err_ratelimited("Conditional branch offset 0x%lx (@%u) out of range\n", offset, ctx->idx); \ + return -ERANGE; \ + } \ + EMIT(PPC_INST_BRANCH_COND | (((cond) & 0x3ff) << 16) | (offset & 0xfffc)); \ + } while (0) + /* Sign-extended 32-bit immediate load */ #define PPC_LI32(d, i) do { \ if ((int)(uintptr_t)(i) >= -32768 && \ @@ -225,11 +239,6 @@ #define PPC_FUNC_ADDR(d,i) do { PPC_LI32(d, i); } while(0) #endif -static inline bool is_nearbranch(int offset) -{ - return (offset < 32768) && (offset >= -32768); -} - /* * The fly in the ointment of code size changing from pass to pass is * avoided by padding the short branch case with a NOP. If code size differs @@ -238,7 +247,7 @@ * state. */ #define PPC_BCC(cond, dest) do { \ - if (is_nearbranch((dest) - (ctx->idx * 4))) { \ + if (is_offset_in_cond_branch_range((long)(dest) - (ctx->idx * 4))) { \ PPC_BCC_SHORT(cond, dest); \ PPC_NOP(); \ } else { \ --- linux-oracle-5.4.0.orig/arch/powerpc/net/bpf_jit64.h +++ linux-oracle-5.4.0/arch/powerpc/net/bpf_jit64.h @@ -16,18 +16,18 @@ * with our redzone usage. * * [ prev sp ] <------------- - * [ nv gpr save area ] 6*8 | + * [ nv gpr save area ] 5*8 | * [ tail_call_cnt ] 8 | - * [ local_tmp_var ] 8 | + * [ local_tmp_var ] 16 | * fp (r31) --> [ ebpf stack space ] upto 512 | * [ frame header ] 32/112 | * sp (r1) ---> [ stack pointer ] -------------- */ /* for gpr non volatile registers BPG_REG_6 to 10 */ -#define BPF_PPC_STACK_SAVE (6*8) +#define BPF_PPC_STACK_SAVE (5*8) /* for bpf JIT code internal usage */ -#define BPF_PPC_STACK_LOCALS 16 +#define BPF_PPC_STACK_LOCALS 24 /* stack frame excluding BPF stack, ensure this is quadword aligned */ #define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + \ BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE) --- linux-oracle-5.4.0.orig/arch/powerpc/net/bpf_jit_comp64.c +++ linux-oracle-5.4.0/arch/powerpc/net/bpf_jit_comp64.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "bpf_jit64.h" @@ -56,9 +57,9 @@ * [ prev sp ] <------------- * [ ... ] | * sp (r1) ---> [ stack pointer ] -------------- - * [ nv gpr save area ] 6*8 + * [ nv gpr save area ] 5*8 * [ tail_call_cnt ] 8 - * [ local_tmp_var ] 8 + * [ local_tmp_var ] 16 * [ unused red zone ] 208 bytes protected */ static int bpf_jit_stack_local(struct codegen_context *ctx) @@ -66,12 +67,12 @@ if (bpf_has_stack_frame(ctx)) return STACK_FRAME_MIN_SIZE + ctx->stack_size; else - return -(BPF_PPC_STACK_SAVE + 16); + return -(BPF_PPC_STACK_SAVE + 24); } static int bpf_jit_stack_tailcallcnt(struct codegen_context *ctx) { - return bpf_jit_stack_local(ctx) + 8; + return bpf_jit_stack_local(ctx) + 16; } static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg) @@ -224,7 +225,7 @@ PPC_BLRL(); } -static void bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out) +static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out) { /* * By now, the eBPF program has already setup parameters in r3, r4 and r5 @@ -285,14 +286,39 @@ bpf_jit_emit_common_epilogue(image, ctx); PPC_BCTR(); + /* out: */ + return 0; } +/* + * We spill into the redzone always, even if the bpf program has its own stackframe. + * Offsets hardcoded based on BPF_PPC_STACK_SAVE -- see bpf_jit_stack_local() + */ +void bpf_stf_barrier(void); + +asm ( +" .global bpf_stf_barrier ;" +" bpf_stf_barrier: ;" +" std 21,-64(1) ;" +" std 22,-56(1) ;" +" sync ;" +" ld 21,-64(1) ;" +" ld 22,-56(1) ;" +" ori 31,31,0 ;" +" .rept 14 ;" +" b 1f ;" +" 1: ;" +" .endr ;" +" blr ;" +); + /* Assemble the body code between the prologue & epilogue */ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, struct codegen_context *ctx, u32 *addrs, bool extra_pass) { + enum stf_barrier_type stf_barrier = stf_barrier_type_get(); const struct bpf_insn *insn = fp->insnsi; int flen = fp->len; int i, ret; @@ -347,18 +373,25 @@ PPC_SUB(dst_reg, dst_reg, src_reg); goto bpf_alu32_trunc; case BPF_ALU | BPF_ADD | BPF_K: /* (u32) dst += (u32) imm */ - case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ case BPF_ALU64 | BPF_ADD | BPF_K: /* dst += imm */ + if (!imm) { + goto bpf_alu32_trunc; + } else if (imm >= -32768 && imm < 32768) { + PPC_ADDI(dst_reg, dst_reg, IMM_L(imm)); + } else { + PPC_LI32(b2p[TMP_REG_1], imm); + PPC_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]); + } + goto bpf_alu32_trunc; + case BPF_ALU | BPF_SUB | BPF_K: /* (u32) dst -= (u32) imm */ case BPF_ALU64 | BPF_SUB | BPF_K: /* dst -= imm */ - if (BPF_OP(code) == BPF_SUB) - imm = -imm; - if (imm) { - if (imm >= -32768 && imm < 32768) - PPC_ADDI(dst_reg, dst_reg, IMM_L(imm)); - else { - PPC_LI32(b2p[TMP_REG_1], imm); - PPC_ADD(dst_reg, dst_reg, b2p[TMP_REG_1]); - } + if (!imm) { + goto bpf_alu32_trunc; + } else if (imm > -32768 && imm <= 32768) { + PPC_ADDI(dst_reg, dst_reg, IMM_L(-imm)); + } else { + PPC_LI32(b2p[TMP_REG_1], imm); + PPC_SUB(dst_reg, dst_reg, b2p[TMP_REG_1]); } goto bpf_alu32_trunc; case BPF_ALU | BPF_MUL | BPF_X: /* (u32) dst *= (u32) src */ @@ -408,8 +441,14 @@ case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */ if (imm == 0) return -EINVAL; - else if (imm == 1) - goto bpf_alu32_trunc; + if (imm == 1) { + if (BPF_OP(code) == BPF_DIV) { + goto bpf_alu32_trunc; + } else { + PPC_LI(dst_reg, 0); + break; + } + } PPC_LI32(b2p[TMP_REG_1], imm); switch (BPF_CLASS(code)) { @@ -645,6 +684,36 @@ break; /* + * BPF_ST NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + if (!security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) || + (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) && + (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) || !cpu_has_feature(CPU_FTR_HVMODE)))) + break; + + switch (stf_barrier) { + case STF_BARRIER_EIEIO: + EMIT(0x7c0006ac | 0x02000000); + break; + case STF_BARRIER_SYNC_ORI: + EMIT(PPC_INST_SYNC); + PPC_LD(b2p[TMP_REG_1], 13, 0); + PPC_ORI(31, 31, 0); + break; + case STF_BARRIER_FALLBACK: + EMIT(PPC_INST_MFLR | ___PPC_RT(b2p[TMP_REG_1])); + PPC_LI64(12, dereference_kernel_function_descriptor(bpf_stf_barrier)); + PPC_MTCTR(12); + EMIT(PPC_INST_BCTR | 0x1); + PPC_MTLR(b2p[TMP_REG_1]); + break; + case STF_BARRIER_NONE: + break; + } + break; + + /* * BPF_ST(X) */ case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src */ @@ -989,7 +1058,9 @@ */ case BPF_JMP | BPF_TAIL_CALL: ctx->seen |= SEEN_TAILCALL; - bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]); + ret = bpf_jit_emit_tail_call(image, ctx, addrs[i + 1]); + if (ret < 0) + return ret; break; default: --- linux-oracle-5.4.0.orig/arch/powerpc/perf/callchain.c +++ linux-oracle-5.4.0/arch/powerpc/perf/callchain.c @@ -64,6 +64,7 @@ next_sp = fp[0]; if (next_sp == sp + STACK_INT_FRAME_SIZE && + validate_sp(sp, current, STACK_INT_FRAME_SIZE) && fp[STACK_FRAME_MARKER] == STACK_FRAME_REGS_MARKER) { /* * This looks like an interrupt frame for an --- linux-oracle-5.4.0.orig/arch/powerpc/perf/core-book3s.c +++ linux-oracle-5.4.0/arch/powerpc/perf/core-book3s.c @@ -133,6 +133,9 @@ bool is_sier_available(void) { + if (!ppmu) + return false; + if (ppmu->flags & PPMU_HAS_SIER) return true; @@ -1522,9 +1525,16 @@ ret = 0; out: if (has_branch_stack(event)) { - power_pmu_bhrb_enable(event); - cpuhw->bhrb_filter = ppmu->bhrb_filter_map( - event->attr.branch_sample_type); + u64 bhrb_filter = -1; + + if (ppmu->bhrb_filter_map) + bhrb_filter = ppmu->bhrb_filter_map( + event->attr.branch_sample_type); + + if (bhrb_filter != -1) { + cpuhw->bhrb_filter = bhrb_filter; + power_pmu_bhrb_enable(event); + } } perf_pmu_enable(event->pmu); @@ -1846,7 +1856,6 @@ int n; int err; struct cpu_hw_events *cpuhw; - u64 bhrb_filter; if (!ppmu) return -ENOENT; @@ -1952,7 +1961,10 @@ err = power_check_constraints(cpuhw, events, cflags, n + 1); if (has_branch_stack(event)) { - bhrb_filter = ppmu->bhrb_filter_map( + u64 bhrb_filter = -1; + + if (ppmu->bhrb_filter_map) + bhrb_filter = ppmu->bhrb_filter_map( event->attr.branch_sample_type); if (bhrb_filter == -1) { @@ -2065,7 +2077,17 @@ left += period; if (left <= 0) left = period; - record = siar_valid(regs); + + /* + * If address is not requested in the sample via + * PERF_SAMPLE_IP, just record that sample irrespective + * of SIAR valid check. + */ + if (event->attr.sample_type & PERF_SAMPLE_IP) + record = siar_valid(regs); + else + record = 1; + event->hw.last_period = event->hw.sample_period; } if (left < 0x80000000LL) @@ -2078,6 +2100,17 @@ perf_event_update_userpage(event); /* + * Due to hardware limitation, sometimes SIAR could sample a kernel + * address even when freeze on supervisor state (kernel) is set in + * MMCR2. Check attr.exclude_kernel and address to drop the sample in + * these cases. + */ + if (event->attr.exclude_kernel && + (event->attr.sample_type & PERF_SAMPLE_IP) && + is_kernel_addr(mfspr(SPRN_SIAR))) + record = 0; + + /* * Finally record data if requested. */ if (record) { @@ -2106,6 +2139,10 @@ if (perf_event_overflow(event, &data, regs)) power_pmu_stop(event, 0); + } else if (period) { + /* Account for interrupt in case of invalid SIAR */ + if (perf_event_account_interrupt(event)) + power_pmu_stop(event, 0); } } --- linux-oracle-5.4.0.orig/arch/powerpc/perf/hv-24x7.c +++ linux-oracle-5.4.0/arch/powerpc/perf/hv-24x7.c @@ -1313,7 +1313,7 @@ } domain = event_get_domain(event); - if (domain >= HV_PERF_DOMAIN_MAX) { + if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { pr_devel("invalid domain %d\n", domain); return -EINVAL; } @@ -1400,16 +1400,6 @@ h24x7hw = &get_cpu_var(hv_24x7_hw); h24x7hw->events[i] = event; put_cpu_var(h24x7hw); - /* - * Clear the event count so we can compute the _change_ - * in the 24x7 raw counter value at the end of the txn. - * - * Note that we could alternatively read the 24x7 value - * now and save its value in event->hw.prev_count. But - * that would require issuing a hcall, which would then - * defeat the purpose of using the txn interface. - */ - local64_set(&event->count, 0); } put_cpu_var(hv_24x7_reqb); --- linux-oracle-5.4.0.orig/arch/powerpc/perf/hv-gpci-requests.h +++ linux-oracle-5.4.0/arch/powerpc/perf/hv-gpci-requests.h @@ -79,6 +79,7 @@ ) #include I(REQUEST_END) +#ifdef ENABLE_EVENTS_COUNTERINFO_V6 /* * Not available for counter_info_version >= 0x8, use * run_instruction_cycles_by_partition(0x100) instead. @@ -92,10 +93,11 @@ __count(0x10, 8, cycles) ) #include I(REQUEST_END) +#endif #define REQUEST_NAME system_performance_capabilities #define REQUEST_NUM 0x40 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__field(0, 1, perf_collect_privileged) __field(0x1, 1, capability_mask) @@ -103,6 +105,7 @@ ) #include I(REQUEST_END) +#ifdef ENABLE_EVENTS_COUNTERINFO_V6 #define REQUEST_NAME processor_bus_utilization_abc_links #define REQUEST_NUM 0x50 #define REQUEST_IDX_KIND "hw_chip_id=?" @@ -194,6 +197,7 @@ __count(0x28, 8, instructions_completed) ) #include I(REQUEST_END) +#endif /* Processor_core_power_mode (0x95) skipped, no counters */ /* Affinity_domain_information_by_virtual_processor (0xA0) skipped, @@ -223,7 +227,7 @@ #define REQUEST_NAME system_hypervisor_times #define REQUEST_NUM 0xF0 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__count(0, 8, time_spent_to_dispatch_virtual_processors) __count(0x8, 8, time_spent_processing_virtual_processor_timers) @@ -234,7 +238,7 @@ #define REQUEST_NAME system_tlbie_count_and_time #define REQUEST_NUM 0xF4 -#define REQUEST_IDX_KIND "starting_index=0xffffffffffffffff" +#define REQUEST_IDX_KIND "starting_index=0xffffffff" #include I(REQUEST_BEGIN) REQUEST(__count(0, 8, tlbie_instructions_issued) /* --- linux-oracle-5.4.0.orig/arch/powerpc/perf/hv-gpci.c +++ linux-oracle-5.4.0/arch/powerpc/perf/hv-gpci.c @@ -70,7 +70,7 @@ static struct attribute_group event_group = { .name = "events", - .attrs = hv_gpci_event_attrs, + /* .attrs is set in init */ }; #define HV_CAPS_ATTR(_name, _format) \ @@ -153,6 +153,20 @@ ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); + + /* + * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL', + * specifies that the current buffer size cannot accommodate + * all the information and a partial buffer returned. + * Since in this function we are only accessing data for a given starting index, + * we don't need to accommodate whole data and can get required count by + * accessing first entry data. + * Hence hcall fails only incase the ret value is other than H_SUCCESS or + * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B). + */ + if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B) + ret = 0; + if (ret) { pr_devel("hcall failed: 0x%lx\n", ret); goto out; @@ -164,7 +178,7 @@ */ count = 0; for (i = offset; i < offset + length; i++) - count |= arg->bytes[i] << (i - offset); + count |= (u64)(arg->bytes[i]) << ((length - 1 - (i - offset)) * 8); *value = count; out: @@ -217,6 +231,7 @@ { u64 count; u8 length; + unsigned long ret; /* Not our event */ if (event->attr.type != event->pmu->type) @@ -247,13 +262,23 @@ } /* check if the request works... */ - if (single_gpci_request(event_get_request(event), + ret = single_gpci_request(event_get_request(event), event_get_starting_index(event), event_get_secondary_index(event), event_get_counter_info_version(event), event_get_offset(event), length, - &count)) { + &count); + + /* + * ret value as H_AUTHORITY implies that partition is not permitted to retrieve + * performance information, and required to set + * "Enable Performance Information Collection" option. + */ + if (ret == H_AUTHORITY) + return -EPERM; + + if (ret) { pr_devel("gpci hcall failed\n"); return -EINVAL; } @@ -280,6 +305,7 @@ int r; unsigned long hret; struct hv_perf_caps caps; + struct hv_gpci_request_buffer *arg; hv_gpci_assert_offsets_correct(); @@ -298,6 +324,36 @@ /* sampling not supported */ h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT; + arg = (void *)get_cpu_var(hv_gpci_reqb); + memset(arg, 0, HGPCI_REQ_BUFFER_SIZE); + + /* + * hcall H_GET_PERF_COUNTER_INFO populates the output + * counter_info_version value based on the system hypervisor. + * Pass the counter request 0x10 corresponds to request type + * 'Dispatch_timebase_by_processor', to get the supported + * counter_info_version. + */ + arg->params.counter_request = cpu_to_be32(0x10); + + r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, + virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); + if (r) { + pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r); + arg->params.counter_info_version_out = 0x8; + } + + /* + * Use counter_info_version_out value to assign + * required hv-gpci event list. + */ + if (arg->params.counter_info_version_out >= 0x8) + event_group.attrs = hv_gpci_event_attrs; + else + event_group.attrs = hv_gpci_event_attrs_v6; + + put_cpu_var(hv_gpci_reqb); + r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1); if (r) return r; --- linux-oracle-5.4.0.orig/arch/powerpc/perf/hv-gpci.h +++ linux-oracle-5.4.0/arch/powerpc/perf/hv-gpci.h @@ -53,6 +53,7 @@ #define REQUEST_FILE "../hv-gpci-requests.h" #define NAME_LOWER hv_gpci #define NAME_UPPER HV_GPCI +#define ENABLE_EVENTS_COUNTERINFO_V6 #include "req-gen/perf.h" #undef REQUEST_FILE #undef NAME_LOWER --- linux-oracle-5.4.0.orig/arch/powerpc/perf/imc-pmu.c +++ linux-oracle-5.4.0/arch/powerpc/perf/imc-pmu.c @@ -13,6 +13,7 @@ #include #include #include +#include /* Nest IMC data structures and variables */ @@ -44,6 +45,16 @@ static struct imc_pmu_ref *trace_imc_refc; static int trace_imc_mem_size; +/* + * Global data structure used to avoid races between thread, + * core and trace-imc + */ +static struct imc_pmu_ref imc_global_refc = { + .lock = __SPIN_LOCK_UNLOCKED(imc_global_refc.lock), + .id = 0, + .refc = 0, +}; + static struct imc_pmu *imc_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct imc_pmu, pmu); @@ -281,6 +292,8 @@ attr_group->attrs = attrs; do { ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value); + if (!ev_val_str) + continue; dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str); if (!dev_str) continue; @@ -288,6 +301,8 @@ attrs[j++] = dev_str; if (pmu->events[i].scale) { ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name); + if (!ev_scale_str) + continue; dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale); if (!dev_str) continue; @@ -297,6 +312,8 @@ if (pmu->events[i].unit) { ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name); + if (!ev_unit_str) + continue; dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit); if (!dev_str) continue; @@ -383,7 +400,7 @@ get_hard_smp_processor_id(cpu)); /* * If this is the last cpu in this chip then, skip the reference - * count mutex lock and make the reference count on this chip zero. + * count lock and make the reference count on this chip zero. */ ref = get_nest_pmu_ref(cpu); if (!ref) @@ -445,15 +462,15 @@ /* * See if we need to disable the nest PMU. * If no events are currently in use, then we have to take a - * mutex to ensure that we don't race with another task doing + * lock to ensure that we don't race with another task doing * enable or disable the nest counters. */ ref = get_nest_pmu_ref(event->cpu); if (!ref) return; - /* Take the mutex lock for this node and then decrement the reference count */ - mutex_lock(&ref->lock); + /* Take the lock for this node and then decrement the reference count */ + spin_lock(&ref->lock); if (ref->refc == 0) { /* * The scenario where this is true is, when perf session is @@ -465,7 +482,7 @@ * an OPAL call to disable the engine in that node. * */ - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); return; } ref->refc--; @@ -473,7 +490,7 @@ rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_NEST, get_hard_smp_processor_id(event->cpu)); if (rc) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("nest-imc: Unable to stop the counters for core %d\n", node_id); return; } @@ -481,7 +498,7 @@ WARN(1, "nest-imc: Invalid event reference count\n"); ref->refc = 0; } - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); } static int nest_imc_event_init(struct perf_event *event) @@ -540,26 +557,25 @@ /* * Get the imc_pmu_ref struct for this node. - * Take the mutex lock and then increment the count of nest pmu events - * inited. + * Take the lock and then increment the count of nest pmu events inited. */ ref = get_nest_pmu_ref(event->cpu); if (!ref) return -EINVAL; - mutex_lock(&ref->lock); + spin_lock(&ref->lock); if (ref->refc == 0) { rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_NEST, get_hard_smp_processor_id(event->cpu)); if (rc) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("nest-imc: Unable to start the counters for node %d\n", node_id); return rc; } } ++ref->refc; - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); event->destroy = nest_imc_counters_release; return 0; @@ -595,9 +611,8 @@ return -ENOMEM; mem_info->vbase = page_address(page); - /* Init the mutex */ core_imc_refc[core_id].id = core_id; - mutex_init(&core_imc_refc[core_id].lock); + spin_lock_init(&core_imc_refc[core_id].lock); rc = opal_imc_counters_init(OPAL_IMC_COUNTERS_CORE, __pa((void *)mem_info->vbase), @@ -686,9 +701,8 @@ perf_pmu_migrate_context(&core_imc_pmu->pmu, cpu, ncpu); } else { /* - * If this is the last cpu in this core then, skip taking refernce - * count mutex lock for this core and directly zero "refc" for - * this core. + * If this is the last cpu in this core then skip taking reference + * count lock for this core and directly zero "refc" for this core. */ opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, get_hard_smp_processor_id(cpu)); @@ -698,6 +712,16 @@ return -EINVAL; ref->refc = 0; + /* + * Reduce the global reference count, if this is the + * last cpu in this core and core-imc event running + * in this cpu. + */ + spin_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_CORE) + imc_global_refc.refc--; + + spin_unlock(&imc_global_refc.lock); } return 0; } @@ -710,6 +734,23 @@ ppc_core_imc_cpu_offline); } +static void reset_global_refc(struct perf_event *event) +{ + spin_lock(&imc_global_refc.lock); + imc_global_refc.refc--; + + /* + * If no other thread is running any + * event for this domain(thread/core/trace), + * set the global id to zero. + */ + if (imc_global_refc.refc <= 0) { + imc_global_refc.refc = 0; + imc_global_refc.id = 0; + } + spin_unlock(&imc_global_refc.lock); +} + static void core_imc_counters_release(struct perf_event *event) { int rc, core_id; @@ -720,17 +761,17 @@ /* * See if we need to disable the IMC PMU. * If no events are currently in use, then we have to take a - * mutex to ensure that we don't race with another task doing + * lock to ensure that we don't race with another task doing * enable or disable the core counters. */ core_id = event->cpu / threads_per_core; - /* Take the mutex lock and decrement the refernce count for this core */ + /* Take the lock and decrement the refernce count for this core */ ref = &core_imc_refc[core_id]; if (!ref) return; - mutex_lock(&ref->lock); + spin_lock(&ref->lock); if (ref->refc == 0) { /* * The scenario where this is true is, when perf session is @@ -742,7 +783,7 @@ * an OPAL call to disable the engine in that core. * */ - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); return; } ref->refc--; @@ -750,7 +791,7 @@ rc = opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, get_hard_smp_processor_id(event->cpu)); if (rc) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("IMC: Unable to stop the counters for core %d\n", core_id); return; } @@ -758,7 +799,9 @@ WARN(1, "core-imc: Invalid event reference count\n"); ref->refc = 0; } - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); + + reset_global_refc(event); } static int core_imc_event_init(struct perf_event *event) @@ -794,7 +837,6 @@ if ((!pcmi->vbase)) return -ENODEV; - /* Get the core_imc mutex for this core */ ref = &core_imc_refc[core_id]; if (!ref) return -EINVAL; @@ -802,22 +844,45 @@ /* * Core pmu units are enabled only when it is used. * See if this is triggered for the first time. - * If yes, take the mutex lock and enable the core counters. + * If yes, take the lock and enable the core counters. * If not, just increment the count in core_imc_refc struct. */ - mutex_lock(&ref->lock); + spin_lock(&ref->lock); if (ref->refc == 0) { rc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, get_hard_smp_processor_id(event->cpu)); if (rc) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("core-imc: Unable to start the counters for core %d\n", core_id); return rc; } } ++ref->refc; - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); + + /* + * Since the system can run either in accumulation or trace-mode + * of IMC at a time, core-imc events are allowed only if no other + * trace/thread imc events are enabled/monitored. + * + * Take the global lock, and check the refc.id + * to know whether any other trace/thread imc + * events are running. + */ + spin_lock(&imc_global_refc.lock); + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_CORE) { + /* + * No other trace/thread imc events are running in + * the system, so set the refc.id to core-imc. + */ + imc_global_refc.id = IMC_DOMAIN_CORE; + imc_global_refc.refc++; + } else { + spin_unlock(&imc_global_refc.lock); + return -EBUSY; + } + spin_unlock(&imc_global_refc.lock); event->hw.event_base = (u64)pcmi->vbase + (config & IMC_EVENT_OFFSET_MASK); event->destroy = core_imc_counters_release; @@ -877,7 +942,23 @@ static int ppc_thread_imc_cpu_offline(unsigned int cpu) { - mtspr(SPRN_LDBAR, 0); + /* + * Set the bit 0 of LDBAR to zero. + * + * If bit 0 of LDBAR is unset, it will stop posting + * the counter data to memory. + * For thread-imc, bit 0 of LDBAR will be set to 1 in the + * event_add function. So reset this bit here, to stop the updates + * to memory in the cpu_offline path. + */ + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); + + /* Reduce the refc if thread-imc event running on this cpu */ + spin_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_THREAD) + imc_global_refc.refc--; + spin_unlock(&imc_global_refc.lock); + return 0; } @@ -916,7 +997,22 @@ if (!target) return -EINVAL; + spin_lock(&imc_global_refc.lock); + /* + * Check if any other trace/core imc events are running in the + * system, if not set the global id to thread-imc. + */ + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_THREAD) { + imc_global_refc.id = IMC_DOMAIN_THREAD; + imc_global_refc.refc++; + } else { + spin_unlock(&imc_global_refc.lock); + return -EBUSY; + } + spin_unlock(&imc_global_refc.lock); + event->pmu->task_ctx_nr = perf_sw_context; + event->destroy = reset_global_refc; return 0; } @@ -1035,25 +1131,25 @@ /* * imc pmus are enabled only when it is used. * See if this is triggered for the first time. - * If yes, take the mutex lock and enable the counters. + * If yes, take the lock and enable the counters. * If not, just increment the count in ref count struct. */ ref = &core_imc_refc[core_id]; if (!ref) return -EINVAL; - mutex_lock(&ref->lock); + spin_lock(&ref->lock); if (ref->refc == 0) { if (opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE, get_hard_smp_processor_id(smp_processor_id()))) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("thread-imc: Unable to start the counter\ for core %d\n", core_id); return -EINVAL; } } ++ref->refc; - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); return 0; } @@ -1063,17 +1159,19 @@ int core_id; struct imc_pmu_ref *ref; - mtspr(SPRN_LDBAR, 0); - core_id = smp_processor_id() / threads_per_core; ref = &core_imc_refc[core_id]; + if (!ref) { + pr_debug("imc: Failed to get event reference count\n"); + return; + } - mutex_lock(&ref->lock); + spin_lock(&ref->lock); ref->refc--; if (ref->refc == 0) { if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_CORE, get_hard_smp_processor_id(smp_processor_id()))) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("thread-imc: Unable to stop the counters\ for core %d\n", core_id); return; @@ -1081,7 +1179,11 @@ } else if (ref->refc < 0) { ref->refc = 0; } - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); + + /* Set bit 0 of LDBAR to zero, to stop posting updates to memory */ + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); + /* * Take a snapshot and calculate the delta and update * the event counter values. @@ -1118,9 +1220,8 @@ } } - /* Init the mutex, if not already */ trace_imc_refc[core_id].id = core_id; - mutex_init(&trace_imc_refc[core_id].lock); + spin_lock_init(&trace_imc_refc[core_id].lock); mtspr(SPRN_LDBAR, 0); return 0; @@ -1133,7 +1234,18 @@ static int ppc_trace_imc_cpu_offline(unsigned int cpu) { - mtspr(SPRN_LDBAR, 0); + /* + * No need to set bit 0 of LDBAR to zero, as + * it is set to zero for imc trace-mode + * + * Reduce the refc if any trace-imc event running + * on this cpu. + */ + spin_lock(&imc_global_refc.lock); + if (imc_global_refc.id == IMC_DOMAIN_TRACE) + imc_global_refc.refc--; + spin_unlock(&imc_global_refc.lock); + return 0; } @@ -1226,29 +1338,26 @@ local_mem = get_trace_imc_event_base_addr(); ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | TRACE_IMC_ENABLE; - if (core_imc_refc) - ref = &core_imc_refc[core_id]; + /* trace-imc reference count */ + if (trace_imc_refc) + ref = &trace_imc_refc[core_id]; if (!ref) { - /* If core-imc is not enabled, use trace-imc reference count */ - if (trace_imc_refc) - ref = &trace_imc_refc[core_id]; - if (!ref) - return -EINVAL; + pr_debug("imc: Failed to get the event reference count\n"); + return -EINVAL; } + mtspr(SPRN_LDBAR, ldbar_value); - mutex_lock(&ref->lock); + spin_lock(&ref->lock); if (ref->refc == 0) { if (opal_imc_counters_start(OPAL_IMC_COUNTERS_TRACE, get_hard_smp_processor_id(smp_processor_id()))) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("trace-imc: Unable to start the counters for core %d\n", core_id); - mtspr(SPRN_LDBAR, 0); return -EINVAL; } } ++ref->refc; - mutex_unlock(&ref->lock); - + spin_unlock(&ref->lock); return 0; } @@ -1274,29 +1383,27 @@ int core_id = smp_processor_id() / threads_per_core; struct imc_pmu_ref *ref = NULL; - if (core_imc_refc) - ref = &core_imc_refc[core_id]; + if (trace_imc_refc) + ref = &trace_imc_refc[core_id]; if (!ref) { - /* If core-imc is not enabled, use trace-imc reference count */ - if (trace_imc_refc) - ref = &trace_imc_refc[core_id]; - if (!ref) - return; + pr_debug("imc: Failed to get event reference count\n"); + return; } - mtspr(SPRN_LDBAR, 0); - mutex_lock(&ref->lock); + + spin_lock(&ref->lock); ref->refc--; if (ref->refc == 0) { if (opal_imc_counters_stop(OPAL_IMC_COUNTERS_TRACE, get_hard_smp_processor_id(smp_processor_id()))) { - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); pr_err("trace-imc: Unable to stop the counters for core %d\n", core_id); return; } } else if (ref->refc < 0) { ref->refc = 0; } - mutex_unlock(&ref->lock); + spin_unlock(&ref->lock); + trace_imc_event_stop(event, flags); } @@ -1314,10 +1421,34 @@ if (event->attr.sample_period == 0) return -ENOENT; + /* + * Take the global lock, and make sure + * no other thread is running any core/thread imc + * events + */ + spin_lock(&imc_global_refc.lock); + if (imc_global_refc.id == 0 || imc_global_refc.id == IMC_DOMAIN_TRACE) { + /* + * No core/thread imc events are running in the + * system, so set the refc.id to trace-imc. + */ + imc_global_refc.id = IMC_DOMAIN_TRACE; + imc_global_refc.refc++; + } else { + spin_unlock(&imc_global_refc.lock); + return -EBUSY; + } + spin_unlock(&imc_global_refc.lock); + event->hw.idx = -1; target = event->hw.target; - event->pmu->task_ctx_nr = perf_hw_context; + /* + * There can only be a single PMU for perf_hw_context events which is assigned to + * core PMU. Hence use "perf_sw_context" for trace_imc. + */ + event->pmu->task_ctx_nr = perf_sw_context; + event->destroy = reset_global_refc; return 0; } @@ -1380,10 +1511,10 @@ i = 0; for_each_node(nid) { /* - * Mutex lock to avoid races while tracking the number of + * Take the lock to avoid races while tracking the number of * sessions using the chip's nest pmu units. */ - mutex_init(&nest_imc_refc[i].lock); + spin_lock_init(&nest_imc_refc[i].lock); /* * Loop to init the "id" with the node_id. Variable "i" initialized to @@ -1429,10 +1560,10 @@ static void thread_imc_ldbar_disable(void *dummy) { /* - * By Zeroing LDBAR, we disable thread-imc - * updates. + * By setting 0th bit of LDBAR to zero, we disable thread-imc + * updates to memory. */ - mtspr(SPRN_LDBAR, 0); + mtspr(SPRN_LDBAR, (mfspr(SPRN_LDBAR) & (~(1UL << 63)))); } void thread_imc_disable(void) --- linux-oracle-5.4.0.orig/arch/powerpc/perf/isa207-common.c +++ linux-oracle-5.4.0/arch/powerpc/perf/isa207-common.c @@ -269,6 +269,15 @@ mask |= CNST_PMC_MASK(pmc); value |= CNST_PMC_VAL(pmc); + + /* + * PMC5 and PMC6 are used to count cycles and instructions and + * they do not support most of the constraint bits. Add a check + * to exclude PMC5/6 from most of the constraints except for + * EBB/BHRB. + */ + if (pmc >= 5) + goto ebb_bhrb; } if (pmc <= 4) { @@ -317,7 +326,8 @@ if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK; value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); - } + } else if (event_is_threshold(event)) + return -1; } else { /* * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, @@ -335,6 +345,7 @@ } } +ebb_bhrb: if (!pmc && ebb) /* EBB events must specify the PMC */ return -1; @@ -353,8 +364,8 @@ * EBB events are pinned & exclusive, so this should never actually * hit, but we leave it as a fallback in case. */ - mask |= CNST_EBB_VAL(ebb); - value |= CNST_EBB_MASK; + mask |= CNST_EBB_MASK; + value |= CNST_EBB_VAL(ebb); *maskp = mask; *valp = value; --- linux-oracle-5.4.0.orig/arch/powerpc/perf/power9-pmu.c +++ linux-oracle-5.4.0/arch/powerpc/perf/power9-pmu.c @@ -131,11 +131,11 @@ /* Table of alternatives, sorted by column 0 */ static const unsigned int power9_event_alternatives[][MAX_ALT] = { - { PM_INST_DISP, PM_INST_DISP_ALT }, - { PM_RUN_CYC_ALT, PM_RUN_CYC }, - { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, - { PM_LD_MISS_L1, PM_LD_MISS_L1_ALT }, { PM_BR_2PATH, PM_BR_2PATH_ALT }, + { PM_INST_DISP, PM_INST_DISP_ALT }, + { PM_RUN_CYC_ALT, PM_RUN_CYC }, + { PM_LD_MISS_L1, PM_LD_MISS_L1_ALT }, + { PM_RUN_INST_CMPL_ALT, PM_RUN_INST_CMPL }, }; static int power9_get_alternatives(u64 event, unsigned int flags, u64 alt[]) --- linux-oracle-5.4.0.orig/arch/powerpc/perf/req-gen/perf.h +++ linux-oracle-5.4.0/arch/powerpc/perf/req-gen/perf.h @@ -139,6 +139,26 @@ #define REQUEST_(r_name, r_value, r_idx_1, r_fields) \ r_fields +/* Generate event list for platforms with counter_info_version 0x6 or below */ +static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = { +#include REQUEST_FILE + NULL +}; + +/* + * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci + * events were deprecated for platform firmware that supports + * counter_info_version 0x8 or above. + * Those deprecated events are still part of platform firmware that + * support counter_info_version 0x6 and below. As per the getPerfCountInfo + * v1.018 documentation there is no counter_info_version 0x7. + * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of + * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms + * that supports counter_info_version 0x8 or above. + */ +#undef ENABLE_EVENTS_COUNTERINFO_V6 + +/* Generate event list for platforms with counter_info_version 0x8 or above*/ static __maybe_unused struct attribute *hv_gpci_event_attrs[] = { #include REQUEST_FILE NULL --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/44x/Kconfig +++ linux-oracle-5.4.0/arch/powerpc/platforms/44x/Kconfig @@ -178,6 +178,7 @@ config CURRITUCK bool "IBM Currituck (476fpe) Support" depends on PPC_47x + select I2C select SWIOTLB select 476FPE select FORCE_PCI --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/44x/fsp2.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/44x/fsp2.c @@ -208,6 +208,7 @@ if (irq == NO_IRQ) { pr_err("device tree node %pOFn is missing a interrupt", np); + of_node_put(np); return; } @@ -215,6 +216,7 @@ if (rc) { pr_err("fsp_of_probe: request_irq failed: np=%pOF rc=%d", np, rc); + of_node_put(np); return; } } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/4xx/cpm.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/4xx/cpm.c @@ -327,6 +327,6 @@ static int __init cpm_powersave_off(char *arg) { cpm.powersave_off = 1; - return 0; + return 1; } __setup("powersave=off", cpm_powersave_off); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/4xx/pci.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/4xx/pci.c @@ -1242,7 +1242,7 @@ if (mbase == NULL) { printk(KERN_ERR "%pOF: Can't map internal config space !", port->node); - goto done; + return; } while (attempt && (0 == (in_le32(mbase + PECFG_460SX_DLLSTA) @@ -1252,9 +1252,7 @@ } if (attempt) port->link = 1; -done: iounmap(mbase); - } static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/512x/clock-commonclk.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/512x/clock-commonclk.c @@ -984,7 +984,7 @@ #define NODE_PREP do { \ of_address_to_resource(np, 0, &res); \ - snprintf(devname, sizeof(devname), "%08x.%s", res.start, np->name); \ + snprintf(devname, sizeof(devname), "%pa.%s", &res.start, np->name); \ } while (0) #define NODE_CHK(clkname, clkitem, regnode, regflag) do { \ --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/52xx/lite5200_sleep.S +++ linux-oracle-5.4.0/arch/powerpc/platforms/52xx/lite5200_sleep.S @@ -181,7 +181,7 @@ udelay: /* r11 - tb_ticks_per_usec, r12 - usecs, overwrites r13 */ mullw r12, r12, r11 mftb r13 /* start */ - addi r12, r13, r12 /* end */ + add r12, r13, r12 /* end */ 1: mftb r13 /* current */ cmp cr0, r13, r12 --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/52xx/mpc52xx_lpbfifo.c @@ -530,6 +530,7 @@ err_bcom_rx_irq: bcom_gen_bd_rx_release(lpbfifo.bcom_rx_task); err_bcom_rx: + free_irq(lpbfifo.irq, &lpbfifo); err_irq: iounmap(lpbfifo.regs); lpbfifo.regs = NULL; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -340,7 +340,7 @@ { int l1irq; int l2irq; - struct irq_chip *uninitialized_var(irqchip); + struct irq_chip *irqchip; void *hndlr; int type; u32 reg; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -107,7 +107,7 @@ goto next; unreg: - platform_device_del(pdev); + platform_device_put(pdev); err: pr_err("%pOF: registration failed\n", np); next: --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c @@ -94,9 +94,8 @@ pr_err("Could not map guts node address\n"); return -ENOMEM; } + qoriq_pm_ops = &mpc85xx_pm_ops; } - qoriq_pm_ops = &mpc85xx_pm_ops; - return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/8xx/cpm1.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/8xx/cpm1.c @@ -292,6 +292,7 @@ out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); } +EXPORT_SYMBOL(cpm_setbrg); struct cpm_ioport16 { __be16 dir, par, odr_sor, dat, intr; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/8xx/micropatch.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/8xx/micropatch.c @@ -361,6 +361,17 @@ if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) { smc_uart_t *smp; + if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) { + int i; + + for (i = 0; i < sizeof(*smp); i += 4) { + u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i]; + u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i]; + + out_be32(dst, in_be32(src)); + } + } + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; out_be16(&smp->smc_rpbase, 0x1ec0); smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2]; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/8xx/pic.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/8xx/pic.c @@ -153,6 +153,7 @@ if (mpc8xx_pic_host == NULL) { printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n"); ret = -ENOMEM; + goto out; } ret = 0; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/Kconfig +++ linux-oracle-5.4.0/arch/powerpc/platforms/Kconfig @@ -219,12 +219,11 @@ temperature within 2-4 degrees Celsius. This option shows the current on-die temperature in /proc/cpuinfo if the cpu supports it. - Unfortunately, on some chip revisions, this sensor is very inaccurate - and in many cases, does not work at all, so don't assume the cpu - temp is actually what /proc/cpuinfo says it is. + Unfortunately, this sensor is very inaccurate when uncalibrated, so + don't assume the cpu temp is actually what /proc/cpuinfo says it is. config TAU_INT - bool "Interrupt driven TAU driver (DANGEROUS)" + bool "Interrupt driven TAU driver (EXPERIMENTAL)" depends on TAU ---help--- The TAU supports an interrupt driven mode which causes an interrupt @@ -232,12 +231,7 @@ to get notified the temp has exceeded a range. With this option off, a timer is used to re-check the temperature periodically. - However, on some cpus it appears that the TAU interrupt hardware - is buggy and can cause a situation which would lead unexplained hard - lockups. - - Unless you are extending the TAU driver, or enjoy kernel/hardware - debugging, leave this option off. + If in doubt, say N here. config TAU_AVERAGE bool "Average high and low temp" --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/Kconfig.cputype +++ linux-oracle-5.4.0/arch/powerpc/platforms/Kconfig.cputype @@ -118,9 +118,9 @@ depends on PPC64 && CPU_LITTLE_ENDIAN select ARCH_HAS_FAST_MULTIPLIER -config GENERIC_CPU +config POWERPC_CPU bool "Generic 32 bits powerpc" - depends on PPC32 && !PPC_8xx + depends on PPC32 && !PPC_8xx && !PPC_85xx config CELL_CPU bool "Cell Broadband Engine" @@ -151,11 +151,11 @@ config E5500_CPU bool "Freescale e5500" - depends on E500 + depends on PPC64 && E500 config E6500_CPU bool "Freescale e6500" - depends on E500 + depends on PPC64 && E500 config 860_CPU bool "8xx family" @@ -174,11 +174,23 @@ depends on PPC_BOOK3S_32 select ALTIVEC +config E500_CPU + bool "e500 (8540)" + depends on PPC_85xx && !PPC_E500MC + +config E500MC_CPU + bool "e500mc" + depends on PPC_85xx && PPC_E500MC + +config TOOLCHAIN_DEFAULT_CPU + bool "Rely on the toolchain's implicit default CPU" + depends on PPC32 + endchoice config TARGET_CPU_BOOL bool - default !GENERIC_CPU + default !GENERIC_CPU && !TOOLCHAIN_DEFAULT_CPU config TARGET_CPU string @@ -193,6 +205,9 @@ default "e300c2" if E300C2_CPU default "e300c3" if E300C3_CPU default "G4" if G4_CPU + default "8540" if E500_CPU + default "e500mc" if E500MC_CPU + default "powerpc" if POWERPC_CPU config PPC_BOOK3S def_bool y @@ -389,7 +404,7 @@ config PPC_KUAP_DEBUG bool "Extra debugging for Kernel Userspace Access Protection" - depends on PPC_HAVE_KUAP && (PPC_RADIX_MMU || PPC_32) + depends on PPC_KUAP && (PPC_RADIX_MMU || PPC32) help Add extra debugging for Kernel Userspace Access Protection (KUAP) If you're unsure, say N. --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/Kconfig +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/Kconfig @@ -44,6 +44,7 @@ tristate "SPU file system" default m depends on PPC_CELL + depends on COREDUMP select SPU_BASE help The SPU file system is used to access Synergistic Processing --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/axon_msi.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/axon_msi.c @@ -226,6 +226,7 @@ if (!prop) { dev_dbg(&dev->dev, "axon_msi: no msi-address-(32|64) properties found\n"); + of_node_put(dn); return -ENOENT; } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/iommu.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/iommu.c @@ -976,6 +976,7 @@ if (hbase < dbase || (hend > (dbase + dsize))) { pr_debug("iommu: hash window doesn't fit in" "real DMA window\n"); + of_node_put(np); return -1; } } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/pervasive.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/pervasive.c @@ -77,6 +77,7 @@ switch (regs->msr & SRR1_WAKEMASK) { case SRR1_WAKEDEC: set_dec(1); + break; case SRR1_WAKEEE: /* * Handle these when interrupts get re-enabled and we take --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/spufs/file.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/spufs/file.c @@ -1978,8 +1978,9 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - int ret; struct spu_context *ctx = file->private_data; + u32 stat, data; + int ret; if (!access_ok(buf, len)) return -EFAULT; @@ -1988,11 +1989,16 @@ if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_mbox_info_read(ctx, buf, len, pos); + stat = ctx->csa.prob.mb_stat_R; + data = ctx->csa.prob.pu_mb_R; spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + /* EOF if there's no entry in the mbox */ + if (!(stat & 0x0000ff)) + return 0; + + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); } static const struct file_operations spufs_mbox_info_fops = { @@ -2019,6 +2025,7 @@ size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + u32 stat, data; int ret; if (!access_ok(buf, len)) @@ -2028,11 +2035,16 @@ if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_ibox_info_read(ctx, buf, len, pos); + stat = ctx->csa.prob.mb_stat_R; + data = ctx->csa.priv2.puint_mb_R; spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + /* EOF if there's no entry in the ibox */ + if (!(stat & 0xff0000)) + return 0; + + return simple_read_from_buffer(buf, len, pos, &data, sizeof(data)); } static const struct file_operations spufs_ibox_info_fops = { @@ -2041,6 +2053,11 @@ .llseek = generic_file_llseek, }; +static size_t spufs_wbox_info_cnt(struct spu_context *ctx) +{ + return (4 - ((ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8)) * sizeof(u32); +} + static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { @@ -2049,7 +2066,7 @@ u32 wbox_stat; wbox_stat = ctx->csa.prob.mb_stat_R; - cnt = 4 - ((wbox_stat & 0x00ff00) >> 8); + cnt = spufs_wbox_info_cnt(ctx); for (i = 0; i < cnt; i++) { data[i] = ctx->csa.spu_mailbox_data[i]; } @@ -2062,7 +2079,8 @@ size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - int ret; + u32 data[ARRAY_SIZE(ctx->csa.spu_mailbox_data)]; + int ret, count; if (!access_ok(buf, len)) return -EFAULT; @@ -2071,11 +2089,13 @@ if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_wbox_info_read(ctx, buf, len, pos); + count = spufs_wbox_info_cnt(ctx); + memcpy(&data, &ctx->csa.spu_mailbox_data, sizeof(data)); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &data, + count * sizeof(u32)); } static const struct file_operations spufs_wbox_info_fops = { @@ -2084,27 +2104,33 @@ .llseek = generic_file_llseek, }; -static ssize_t __spufs_dma_info_read(struct spu_context *ctx, - char __user *buf, size_t len, loff_t *pos) +static void spufs_get_dma_info(struct spu_context *ctx, + struct spu_dma_info *info) { - struct spu_dma_info info; - struct mfc_cq_sr *qp, *spuqp; int i; - info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; - info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; - info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; - info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; - info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; + info->dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; + info->dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; + info->dma_info_status = ctx->csa.spu_chnldata_RW[24]; + info->dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; + info->dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; for (i = 0; i < 16; i++) { - qp = &info.dma_info_command_data[i]; - spuqp = &ctx->csa.priv2.spuq[i]; + struct mfc_cq_sr *qp = &info->dma_info_command_data[i]; + struct mfc_cq_sr *spuqp = &ctx->csa.priv2.spuq[i]; qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; } +} + +static ssize_t __spufs_dma_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) +{ + struct spu_dma_info info; + + spufs_get_dma_info(ctx, &info); return simple_read_from_buffer(buf, len, pos, &info, sizeof info); @@ -2114,6 +2140,7 @@ size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + struct spu_dma_info info; int ret; if (!access_ok(buf, len)) @@ -2123,11 +2150,12 @@ if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_dma_info_read(ctx, buf, len, pos); + spufs_get_dma_info(ctx, &info); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &info, + sizeof(info)); } static const struct file_operations spufs_dma_info_fops = { @@ -2136,13 +2164,31 @@ .llseek = no_llseek, }; +static void spufs_get_proxydma_info(struct spu_context *ctx, + struct spu_proxydma_info *info) +{ + int i; + + info->proxydma_info_type = ctx->csa.prob.dma_querytype_RW; + info->proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; + info->proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; + + for (i = 0; i < 8; i++) { + struct mfc_cq_sr *qp = &info->proxydma_info_command_data[i]; + struct mfc_cq_sr *puqp = &ctx->csa.priv2.puq[i]; + + qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; + qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; + qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; + qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; + } +} + static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { struct spu_proxydma_info info; - struct mfc_cq_sr *qp, *puqp; int ret = sizeof info; - int i; if (len < ret) return -EINVAL; @@ -2150,18 +2196,7 @@ if (!access_ok(buf, len)) return -EFAULT; - info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; - info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; - info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; - for (i = 0; i < 8; i++) { - qp = &info.proxydma_info_command_data[i]; - puqp = &ctx->csa.priv2.puq[i]; - - qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; - qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; - qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; - qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; - } + spufs_get_proxydma_info(ctx, &info); return simple_read_from_buffer(buf, len, pos, &info, sizeof info); @@ -2171,17 +2206,19 @@ size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + struct spu_proxydma_info info; int ret; ret = spu_acquire_saved(ctx); if (ret) return ret; spin_lock(&ctx->csa.register_lock); - ret = __spufs_proxydma_info_read(ctx, buf, len, pos); + spufs_get_proxydma_info(ctx, &info); spin_unlock(&ctx->csa.register_lock); spu_release_saved(ctx); - return ret; + return simple_read_from_buffer(buf, len, pos, &info, + sizeof(info)); } static const struct file_operations spufs_proxydma_info_fops = { --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/cell/spufs/inode.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/cell/spufs/inode.c @@ -671,6 +671,7 @@ return; loader = of_get_property(dn, "loader", &size); + of_node_put(dn); if (!loader) return; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/embedded6xx/flipper-pic.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/embedded6xx/flipper-pic.c @@ -144,7 +144,7 @@ } io_base = ioremap(res.start, resource_size(&res)); - pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base); __flipper_quiesce(io_base); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -173,7 +173,7 @@ return NULL; } - pr_info("controller at 0x%08x mapped to 0x%p\n", res.start, io_base); + pr_info("controller at 0x%pa mapped to 0x%p\n", &res.start, io_base); __hlwd_quiesce(io_base); @@ -215,6 +215,7 @@ irq_set_chained_handler(cascade_virq, hlwd_pic_irq_cascade); hlwd_irq_host = host; + of_node_put(np); break; } } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/embedded6xx/linkstation.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -97,9 +97,6 @@ mpic_init(mpic); } -extern void avr_uart_configure(void); -extern void avr_uart_send(const char); - static void __noreturn linkstation_restart(char *cmd) { local_irq_disable(); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/embedded6xx/mpc10x.h +++ linux-oracle-5.4.0/arch/powerpc/platforms/embedded6xx/mpc10x.h @@ -156,4 +156,7 @@ /* For MPC107 boards that use the built-in openpic */ void mpc10x_set_openpic(void); +void avr_uart_configure(void); +void avr_uart_send(const char c); + #endif /* __PPC_KERNEL_MPC10X_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/embedded6xx/wii.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/embedded6xx/wii.c @@ -89,8 +89,8 @@ hw_regs = ioremap(res.start, resource_size(&res)); if (hw_regs) { - pr_info("%s at 0x%08x mapped to 0x%p\n", name, - res.start, hw_regs); + pr_info("%s at 0x%pa mapped to 0x%p\n", name, + &res.start, hw_regs); } out_put: --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/maple/setup.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/maple/setup.c @@ -294,23 +294,6 @@ return 1; } -define_machine(maple) { - .name = "Maple", - .probe = maple_probe, - .setup_arch = maple_setup_arch, - .init_IRQ = maple_init_IRQ, - .pci_irq_fixup = maple_pci_irq_fixup, - .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, - .restart = maple_restart, - .halt = maple_halt, - .get_boot_time = maple_get_boot_time, - .set_rtc_time = maple_set_rtc_time, - .get_rtc_time = maple_get_rtc_time, - .calibrate_decr = generic_calibrate_decr, - .progress = maple_progress, - .power_save = power4_idle, -}; - #ifdef CONFIG_EDAC /* * Register a platform device for CPC925 memory controller on @@ -367,3 +350,20 @@ } machine_device_initcall(maple, maple_cpc925_edac_setup); #endif + +define_machine(maple) { + .name = "Maple", + .probe = maple_probe, + .setup_arch = maple_setup_arch, + .init_IRQ = maple_init_IRQ, + .pci_irq_fixup = maple_pci_irq_fixup, + .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, + .restart = maple_restart, + .halt = maple_halt, + .get_boot_time = maple_get_boot_time, + .set_rtc_time = maple_set_rtc_time, + .get_rtc_time = maple_get_rtc_time, + .calibrate_decr = generic_calibrate_decr, + .progress = maple_progress, + .power_save = power4_idle, +}; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powermac/cache.S +++ linux-oracle-5.4.0/arch/powerpc/platforms/powermac/cache.S @@ -48,7 +48,7 @@ /* Stop DST streams */ BEGIN_FTR_SECTION - DSSALL + PPC_DSSALL sync END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) @@ -196,7 +196,7 @@ isync /* Stop prefetch streams */ - DSSALL + PPC_DSSALL sync /* Disable L2 prefetching */ --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powermac/low_i2c.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powermac/low_i2c.c @@ -582,6 +582,7 @@ bus->close = kw_i2c_close; bus->xfer = kw_i2c_xfer; mutex_init(&bus->mutex); + lockdep_register_key(&bus->lock_key); lockdep_set_class(&bus->mutex, &bus->lock_key); if (controller == busnode) bus->flags = pmac_i2c_multibus; @@ -811,6 +812,7 @@ bus->hostdata = bus + 1; bus->xfer = pmu_i2c_xfer; mutex_init(&bus->mutex); + lockdep_register_key(&bus->lock_key); lockdep_set_class(&bus->mutex, &bus->lock_key); bus->flags = pmac_i2c_multibus; list_add(&bus->link, &pmac_i2c_busses); @@ -934,6 +936,7 @@ bus->hostdata = bus + 1; bus->xfer = smu_i2c_xfer; mutex_init(&bus->mutex); + lockdep_register_key(&bus->lock_key); lockdep_set_class(&bus->mutex, &bus->lock_key); bus->flags = 0; list_add(&bus->link, &pmac_i2c_busses); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powermac/sleep.S +++ linux-oracle-5.4.0/arch/powerpc/platforms/powermac/sleep.S @@ -293,14 +293,7 @@ * we do any r1 memory access as we are not sure they * are in a sane state above the first 256Mb region */ - li r0,16 /* load up segment register values */ - mtctr r0 /* for context 0 */ - lis r3,0x2000 /* Ku = 1, VSID = 0 */ - li r4,0 -3: mtsrin r3,r4 - addi r3,r3,0x111 /* increment VSID */ - addis r4,r4,0x1000 /* address of next segment */ - bdnz 3b + bl load_segment_registers sync isync --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powermac/smp.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powermac/smp.c @@ -660,13 +660,13 @@ #endif /* !CONFIG_PPC64 */ -/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ -volatile static long int core99_l2_cache; -volatile static long int core99_l3_cache; - static void core99_init_caches(int cpu) { #ifndef CONFIG_PPC64 + /* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ + static long int core99_l2_cache; + static long int core99_l3_cache; + if (!cpu_has_feature(CPU_FTR_L2CR)) return; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/Makefile +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_PPC_VAS) += vas.o vas-window.o vas-debug.o obj-$(CONFIG_OCXL_BASE) += ocxl.o obj-$(CONFIG_SCOM_DEBUGFS) += opal-xscom.o +obj-$(CONFIG_PPC_SECURE_BOOT) += opal-secvar.o --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/memtrace.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/memtrace.c @@ -30,6 +30,7 @@ char name[16]; }; +static DEFINE_MUTEX(memtrace_mutex); static u64 memtrace_size; static struct memtrace_entry *memtrace_array; @@ -67,6 +68,23 @@ return 0; } +static void memtrace_clear_range(unsigned long start_pfn, + unsigned long nr_pages) +{ + unsigned long pfn; + + /* + * As pages are offline, we cannot trust the memmap anymore. As HIGHMEM + * does not apply, avoid passing around "struct page" and use + * clear_page() instead directly. + */ + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + if (IS_ALIGNED(pfn, PAGES_PER_SECTION)) + cond_resched(); + clear_page(__va(PFN_PHYS(pfn))); + } +} + /* called with device_hotplug_lock held */ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) { @@ -112,6 +130,11 @@ for (base_pfn = end_pfn; base_pfn > start_pfn; base_pfn -= nr_pages) { if (memtrace_offline_pages(nid, base_pfn, nr_pages) == true) { /* + * Clear the range while we still have a linear + * mapping. + */ + memtrace_clear_range(base_pfn, nr_pages); + /* * Remove memory in memory block size chunks so that * iomem resources are always split to the same size and * we never try to remove memory that spans two iomem @@ -268,6 +291,7 @@ static int memtrace_enable_set(void *data, u64 val) { + int rc = -EAGAIN; u64 bytes; /* @@ -280,25 +304,31 @@ return -EINVAL; } + mutex_lock(&memtrace_mutex); + /* Re-add/online previously removed/offlined memory */ if (memtrace_size) { if (memtrace_online()) - return -EAGAIN; + goto out_unlock; } - if (!val) - return 0; + if (!val) { + rc = 0; + goto out_unlock; + } /* Offline and remove memory */ if (memtrace_init_regions_runtime(val)) - return -EINVAL; + goto out_unlock; if (memtrace_init_debugfs()) - return -EINVAL; + goto out_unlock; memtrace_size = val; - - return 0; + rc = 0; +out_unlock: + mutex_unlock(&memtrace_mutex); + return rc; } static int memtrace_enable_get(void *data, u64 *val) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/npu-dma.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/npu-dma.c @@ -384,7 +384,8 @@ for (i = 0; i < npucomp->pe_num; ++i) { struct pnv_ioda_pe *pe = npucomp->pe[i]; - if (!pe->table_group.ops->take_ownership) + if (!pe->table_group.ops || + !pe->table_group.ops->take_ownership) continue; pe->table_group.ops->take_ownership(&pe->table_group); } @@ -400,7 +401,8 @@ for (i = 0; i < npucomp->pe_num; ++i) { struct pnv_ioda_pe *pe = npucomp->pe[i]; - if (!pe->table_group.ops->release_ownership) + if (!pe->table_group.ops || + !pe->table_group.ops->release_ownership) continue; pe->table_group.ops->release_ownership(&pe->table_group); } @@ -560,6 +562,11 @@ return -ENODEV; hose = pci_bus_to_host(npdev->bus); + if (hose->npu == NULL) { + dev_info_once(&npdev->dev, "Nvlink1 does not support contexts"); + return 0; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "Map LPAR opalid=%llu lparid=%u\n", @@ -607,6 +614,11 @@ return -ENODEV; hose = pci_bus_to_host(npdev->bus); + if (hose->npu == NULL) { + dev_info_once(&npdev->dev, "Nvlink1 does not support contexts"); + return 0; + } + nphb = hose->private_data; dev_dbg(&gpdev->dev, "destroy context opalid=%llu\n", --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-call.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-call.c @@ -290,3 +290,6 @@ OPAL_CALL(opal_mpipl_update, OPAL_MPIPL_UPDATE); OPAL_CALL(opal_mpipl_register_tag, OPAL_MPIPL_REGISTER_TAG); OPAL_CALL(opal_mpipl_query_tag, OPAL_MPIPL_QUERY_TAG); +OPAL_CALL(opal_secvar_get, OPAL_SECVAR_GET); +OPAL_CALL(opal_secvar_get_next, OPAL_SECVAR_GET_NEXT); +OPAL_CALL(opal_secvar_enqueue_update, OPAL_SECVAR_ENQUEUE_UPDATE); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-dump.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-dump.c @@ -318,15 +318,14 @@ return count; } -static struct dump_obj *create_dump_obj(uint32_t id, size_t size, - uint32_t type) +static void create_dump_obj(uint32_t id, size_t size, uint32_t type) { struct dump_obj *dump; int rc; dump = kzalloc(sizeof(*dump), GFP_KERNEL); if (!dump) - return NULL; + return; dump->kobj.kset = dump_kset; @@ -346,21 +345,39 @@ rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id); if (rc) { kobject_put(&dump->kobj); - return NULL; + return; } + /* + * As soon as the sysfs file for this dump is created/activated there is + * a chance the opal_errd daemon (or any userspace) might read and + * acknowledge the dump before kobject_uevent() is called. If that + * happens then there is a potential race between + * dump_ack_store->kobject_put() and kobject_uevent() which leads to a + * use-after-free of a kernfs object resulting in a kernel crash. + * + * To avoid that, we need to take a reference on behalf of the bin file, + * so that our reference remains valid while we call kobject_uevent(). + * We then drop our reference before exiting the function, leaving the + * bin file to drop the last reference (if it hasn't already). + */ + + /* Take a reference for the bin file */ + kobject_get(&dump->kobj); rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr); - if (rc) { + if (rc == 0) { + kobject_uevent(&dump->kobj, KOBJ_ADD); + + pr_info("%s: New platform dump. ID = 0x%x Size %u\n", + __func__, dump->id, dump->size); + } else { + /* Drop reference count taken for bin file */ kobject_put(&dump->kobj); - return NULL; } - pr_info("%s: New platform dump. ID = 0x%x Size %u\n", - __func__, dump->id, dump->size); - - kobject_uevent(&dump->kobj, KOBJ_ADD); - - return dump; + /* Drop our reference */ + kobject_put(&dump->kobj); + return; } static irqreturn_t process_dump(int irq, void *data) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-elog.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-elog.c @@ -179,14 +179,14 @@ return count; } -static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) +static void create_elog_obj(uint64_t id, size_t size, uint64_t type) { struct elog_obj *elog; int rc; elog = kzalloc(sizeof(*elog), GFP_KERNEL); if (!elog) - return NULL; + return; elog->kobj.kset = elog_kset; @@ -219,18 +219,37 @@ rc = kobject_add(&elog->kobj, NULL, "0x%llx", id); if (rc) { kobject_put(&elog->kobj); - return NULL; + return; } + /* + * As soon as the sysfs file for this elog is created/activated there is + * a chance the opal_errd daemon (or any userspace) might read and + * acknowledge the elog before kobject_uevent() is called. If that + * happens then there is a potential race between + * elog_ack_store->kobject_put() and kobject_uevent() which leads to a + * use-after-free of a kernfs object resulting in a kernel crash. + * + * To avoid that, we need to take a reference on behalf of the bin file, + * so that our reference remains valid while we call kobject_uevent(). + * We then drop our reference before exiting the function, leaving the + * bin file to drop the last reference (if it hasn't already). + */ + + /* Take a reference for the bin file */ + kobject_get(&elog->kobj); rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr); - if (rc) { + if (rc == 0) { + kobject_uevent(&elog->kobj, KOBJ_ADD); + } else { + /* Drop the reference taken for the bin file */ kobject_put(&elog->kobj); - return NULL; } - kobject_uevent(&elog->kobj, KOBJ_ADD); + /* Drop our reference */ + kobject_put(&elog->kobj); - return elog; + return; } static irqreturn_t elog_event(int irq, void *data) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-fadump.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-fadump.c @@ -60,7 +60,7 @@ addr = be64_to_cpu(addr); pr_debug("Kernel metadata addr: %llx\n", addr); opal_fdm_active = (void *)addr; - if (opal_fdm_active->registered_regions == 0) + if (be16_to_cpu(opal_fdm_active->registered_regions) == 0) return; ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_BOOT_MEM, &addr); @@ -95,17 +95,17 @@ static void opal_fadump_update_config(struct fw_dump *fadump_conf, const struct opal_fadump_mem_struct *fdm) { - pr_debug("Boot memory regions count: %d\n", fdm->region_cnt); + pr_debug("Boot memory regions count: %d\n", be16_to_cpu(fdm->region_cnt)); /* * The destination address of the first boot memory region is the * destination address of boot memory regions. */ - fadump_conf->boot_mem_dest_addr = fdm->rgn[0].dest; + fadump_conf->boot_mem_dest_addr = be64_to_cpu(fdm->rgn[0].dest); pr_debug("Destination address of boot memory regions: %#016llx\n", fadump_conf->boot_mem_dest_addr); - fadump_conf->fadumphdr_addr = fdm->fadumphdr_addr; + fadump_conf->fadumphdr_addr = be64_to_cpu(fdm->fadumphdr_addr); } /* @@ -126,9 +126,9 @@ fadump_conf->boot_memory_size = 0; pr_debug("Boot memory regions:\n"); - for (i = 0; i < fdm->region_cnt; i++) { - base = fdm->rgn[i].src; - size = fdm->rgn[i].size; + for (i = 0; i < be16_to_cpu(fdm->region_cnt); i++) { + base = be64_to_cpu(fdm->rgn[i].src); + size = be64_to_cpu(fdm->rgn[i].size); pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size); fadump_conf->boot_mem_addr[i] = base; @@ -143,7 +143,7 @@ * Start address of reserve dump area (permanent reservation) for * re-registering FADump after dump capture. */ - fadump_conf->reserve_dump_area_start = fdm->rgn[0].dest; + fadump_conf->reserve_dump_area_start = be64_to_cpu(fdm->rgn[0].dest); /* * Rarely, but it can so happen that system crashes before all @@ -155,13 +155,14 @@ * Hope the memory that could not be preserved only has pages * that are usually filtered out while saving the vmcore. */ - if (fdm->region_cnt > fdm->registered_regions) { + if (be16_to_cpu(fdm->region_cnt) > be16_to_cpu(fdm->registered_regions)) { pr_warn("Not all memory regions were saved!!!\n"); pr_warn(" Unsaved memory regions:\n"); - i = fdm->registered_regions; - while (i < fdm->region_cnt) { + i = be16_to_cpu(fdm->registered_regions); + while (i < be16_to_cpu(fdm->region_cnt)) { pr_warn("\t[%03d] base: 0x%llx, size: 0x%llx\n", - i, fdm->rgn[i].src, fdm->rgn[i].size); + i, be64_to_cpu(fdm->rgn[i].src), + be64_to_cpu(fdm->rgn[i].size)); i++; } @@ -170,7 +171,7 @@ } fadump_conf->boot_mem_top = (fadump_conf->boot_memory_size + hole_size); - fadump_conf->boot_mem_regs_cnt = fdm->region_cnt; + fadump_conf->boot_mem_regs_cnt = be16_to_cpu(fdm->region_cnt); opal_fadump_update_config(fadump_conf, fdm); } @@ -178,35 +179,38 @@ static void opal_fadump_init_metadata(struct opal_fadump_mem_struct *fdm) { fdm->version = OPAL_FADUMP_VERSION; - fdm->region_cnt = 0; - fdm->registered_regions = 0; - fdm->fadumphdr_addr = 0; + fdm->region_cnt = cpu_to_be16(0); + fdm->registered_regions = cpu_to_be16(0); + fdm->fadumphdr_addr = cpu_to_be64(0); } static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf) { u64 addr = fadump_conf->reserve_dump_area_start; + u16 reg_cnt; int i; opal_fdm = __va(fadump_conf->kernel_metadata); opal_fadump_init_metadata(opal_fdm); /* Boot memory regions */ + reg_cnt = be16_to_cpu(opal_fdm->region_cnt); for (i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) { - opal_fdm->rgn[i].src = fadump_conf->boot_mem_addr[i]; - opal_fdm->rgn[i].dest = addr; - opal_fdm->rgn[i].size = fadump_conf->boot_mem_sz[i]; + opal_fdm->rgn[i].src = cpu_to_be64(fadump_conf->boot_mem_addr[i]); + opal_fdm->rgn[i].dest = cpu_to_be64(addr); + opal_fdm->rgn[i].size = cpu_to_be64(fadump_conf->boot_mem_sz[i]); - opal_fdm->region_cnt++; + reg_cnt++; addr += fadump_conf->boot_mem_sz[i]; } + opal_fdm->region_cnt = cpu_to_be16(reg_cnt); /* * Kernel metadata is passed to f/w and retrieved in capture kerenl. * So, use it to save fadump header address instead of calculating it. */ - opal_fdm->fadumphdr_addr = (opal_fdm->rgn[0].dest + - fadump_conf->boot_memory_size); + opal_fdm->fadumphdr_addr = cpu_to_be64(be64_to_cpu(opal_fdm->rgn[0].dest) + + fadump_conf->boot_memory_size); opal_fadump_update_config(fadump_conf, opal_fdm); @@ -269,18 +273,21 @@ static int opal_fadump_register(struct fw_dump *fadump_conf) { s64 rc = OPAL_PARAMETER; + u16 registered_regs; int i, err = -EIO; - for (i = 0; i < opal_fdm->region_cnt; i++) { + registered_regs = be16_to_cpu(opal_fdm->registered_regions); + for (i = 0; i < be16_to_cpu(opal_fdm->region_cnt); i++) { rc = opal_mpipl_update(OPAL_MPIPL_ADD_RANGE, - opal_fdm->rgn[i].src, - opal_fdm->rgn[i].dest, - opal_fdm->rgn[i].size); + be64_to_cpu(opal_fdm->rgn[i].src), + be64_to_cpu(opal_fdm->rgn[i].dest), + be64_to_cpu(opal_fdm->rgn[i].size)); if (rc != OPAL_SUCCESS) break; - opal_fdm->registered_regions++; + registered_regs++; } + opal_fdm->registered_regions = cpu_to_be16(registered_regs); switch (rc) { case OPAL_SUCCESS: @@ -291,7 +298,8 @@ case OPAL_RESOURCE: /* If MAX regions limit in f/w is hit, warn and proceed. */ pr_warn("%d regions could not be registered for MPIPL as MAX limit is reached!\n", - (opal_fdm->region_cnt - opal_fdm->registered_regions)); + (be16_to_cpu(opal_fdm->region_cnt) - + be16_to_cpu(opal_fdm->registered_regions))); fadump_conf->dump_registered = 1; err = 0; break; @@ -312,7 +320,7 @@ * If some regions were registered before OPAL_MPIPL_ADD_RANGE * OPAL call failed, unregister all regions. */ - if ((err < 0) && (opal_fdm->registered_regions > 0)) + if ((err < 0) && (be16_to_cpu(opal_fdm->registered_regions) > 0)) opal_fadump_unregister(fadump_conf); return err; @@ -328,7 +336,7 @@ return -EIO; } - opal_fdm->registered_regions = 0; + opal_fdm->registered_regions = cpu_to_be16(0); fadump_conf->dump_registered = 0; return 0; } @@ -563,19 +571,20 @@ else fdm_ptr = opal_fdm; - for (i = 0; i < fdm_ptr->region_cnt; i++) { + for (i = 0; i < be16_to_cpu(fdm_ptr->region_cnt); i++) { /* * Only regions that are registered for MPIPL * would have dump data. */ if ((fadump_conf->dump_active) && - (i < fdm_ptr->registered_regions)) - dumped_bytes = fdm_ptr->rgn[i].size; + (i < be16_to_cpu(fdm_ptr->registered_regions))) + dumped_bytes = be64_to_cpu(fdm_ptr->rgn[i].size); seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ", - fdm_ptr->rgn[i].src, fdm_ptr->rgn[i].dest); + be64_to_cpu(fdm_ptr->rgn[i].src), + be64_to_cpu(fdm_ptr->rgn[i].dest)); seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n", - fdm_ptr->rgn[i].size, dumped_bytes); + be64_to_cpu(fdm_ptr->rgn[i].size), dumped_bytes); } /* Dump is active. Show reserved area start address. */ @@ -624,6 +633,7 @@ { const __be32 *prop; unsigned long dn; + __be64 be_addr; u64 addr = 0; int i, len; s64 ret; @@ -680,13 +690,13 @@ if (!prop) return; - ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &addr); - if ((ret != OPAL_SUCCESS) || !addr) { + ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &be_addr); + if ((ret != OPAL_SUCCESS) || !be_addr) { pr_err("Failed to get Kernel metadata (%lld)\n", ret); return; } - addr = be64_to_cpu(addr); + addr = be64_to_cpu(be_addr); pr_debug("Kernel metadata addr: %llx\n", addr); opal_fdm_active = __va(addr); @@ -697,14 +707,14 @@ } /* Kernel regions not registered with f/w for MPIPL */ - if (opal_fdm_active->registered_regions == 0) { + if (be16_to_cpu(opal_fdm_active->registered_regions) == 0) { opal_fdm_active = NULL; return; } - ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &addr); - if (addr) { - addr = be64_to_cpu(addr); + ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &be_addr); + if (be_addr) { + addr = be64_to_cpu(be_addr); pr_debug("CPU metadata addr: %llx\n", addr); opal_cpu_metadata = __va(addr); } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-fadump.h +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-fadump.h @@ -31,14 +31,14 @@ * OPAL FADump kernel metadata * * The address of this structure will be registered with f/w for retrieving - * and processing during crash dump. + * in the capture kernel to process the crash dump. */ struct opal_fadump_mem_struct { u8 version; u8 reserved[3]; - u16 region_cnt; /* number of regions */ - u16 registered_regions; /* Regions registered for MPIPL */ - u64 fadumphdr_addr; + __be16 region_cnt; /* number of regions */ + __be16 registered_regions; /* Regions registered for MPIPL */ + __be64 fadumphdr_addr; struct opal_mpipl_region rgn[FADUMP_MAX_MEM_REGS]; } __packed; @@ -135,7 +135,7 @@ for (i = 0; i < regs_cnt; i++, bufp += reg_entry_size) { reg_entry = (struct hdat_fadump_reg_entry *)bufp; val = (cpu_endian ? be64_to_cpu(reg_entry->reg_val) : - reg_entry->reg_val); + (u64)(reg_entry->reg_val)); opal_fadump_set_regval_regnum(regs, be32_to_cpu(reg_entry->reg_type), be32_to_cpu(reg_entry->reg_num), --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-imc.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-imc.c @@ -59,10 +59,6 @@ imc_debugfs_parent = debugfs_create_dir("imc", powerpc_debugfs_root); - /* - * Return here, either because 'imc' directory already exists, - * Or failed to create a new one. - */ if (!imc_debugfs_parent) return; @@ -135,7 +131,6 @@ } pmu_ptr->imc_counter_mmaped = true; - export_imc_mode_and_cmd(node, pmu_ptr); kfree(base_addr_arr); kfree(chipid_arr); return 0; @@ -151,7 +146,7 @@ * and domain as the inputs. * Allocates memory for the struct imc_pmu, sets up its domain, size and offsets */ -static int imc_pmu_create(struct device_node *parent, int pmu_index, int domain) +static struct imc_pmu *imc_pmu_create(struct device_node *parent, int pmu_index, int domain) { int ret = 0; struct imc_pmu *pmu_ptr; @@ -159,27 +154,23 @@ /* Return for unknown domain */ if (domain < 0) - return -EINVAL; + return NULL; /* memory for pmu */ pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL); if (!pmu_ptr) - return -ENOMEM; + return NULL; /* Set the domain */ pmu_ptr->domain = domain; ret = of_property_read_u32(parent, "size", &pmu_ptr->counter_mem_size); - if (ret) { - ret = -EINVAL; + if (ret) goto free_pmu; - } if (!of_property_read_u32(parent, "offset", &offset)) { - if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) { - ret = -EINVAL; + if (imc_get_mem_addr_nest(parent, pmu_ptr, offset)) goto free_pmu; - } } /* Function to register IMC pmu */ @@ -190,14 +181,14 @@ if (pmu_ptr->domain == IMC_DOMAIN_NEST) kfree(pmu_ptr->mem_info); kfree(pmu_ptr); - return ret; + return NULL; } - return 0; + return pmu_ptr; free_pmu: kfree(pmu_ptr); - return ret; + return NULL; } static void disable_nest_pmu_counters(void) @@ -254,6 +245,7 @@ static int opal_imc_counters_probe(struct platform_device *pdev) { struct device_node *imc_dev = pdev->dev.of_node; + struct imc_pmu *pmu; int pmu_count = 0, domain; bool core_imc_reg = false, thread_imc_reg = false; u32 type; @@ -269,6 +261,7 @@ } for_each_compatible_node(imc_dev, NULL, IMC_DTB_UNIT_COMPAT) { + pmu = NULL; if (of_property_read_u32(imc_dev, "type", &type)) { pr_warn("IMC Device without type property\n"); continue; @@ -285,7 +278,14 @@ domain = IMC_DOMAIN_THREAD; break; case IMC_TYPE_TRACE: - domain = IMC_DOMAIN_TRACE; + /* + * FIXME. Using trace_imc events to monitor application + * or KVM thread performance can cause a checkstop + * (system crash). + * Disable it for now. + */ + pr_info_once("IMC: disabling trace_imc PMU\n"); + domain = -1; break; default: pr_warn("IMC Unknown Device type \n"); @@ -293,9 +293,13 @@ break; } - if (!imc_pmu_create(imc_dev, pmu_count, domain)) { - if (domain == IMC_DOMAIN_NEST) + pmu = imc_pmu_create(imc_dev, pmu_count, domain); + if (pmu != NULL) { + if (domain == IMC_DOMAIN_NEST) { + if (!imc_debugfs_parent) + export_imc_mode_and_cmd(imc_dev, pmu); pmu_count++; + } if (domain == IMC_DOMAIN_CORE) core_imc_reg = true; if (domain == IMC_DOMAIN_THREAD) @@ -303,10 +307,6 @@ } } - /* If none of the nest units are registered, remove debugfs interface */ - if (pmu_count == 0) - debugfs_remove_recursive(imc_debugfs_parent); - /* If core imc is not registered, unregister thread-imc */ if (!core_imc_reg && thread_imc_reg) unregister_thread_imc(); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-irqchip.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -278,11 +278,14 @@ else name = kasprintf(GFP_KERNEL, "opal"); + if (!name) + continue; /* Install interrupt handler */ rc = request_irq(r->start, opal_interrupt, r->flags & IRQD_TRIGGER_MASK, name, NULL); if (rc) { pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); + kfree(name); continue; } } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-lpc.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-lpc.c @@ -396,6 +396,7 @@ if (!of_get_property(np, "primary", NULL)) continue; opal_lpc_chip_id = of_get_ibm_chip_id(np); + of_node_put(np); break; } if (opal_lpc_chip_id < 0) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-powercap.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-powercap.c @@ -196,6 +196,12 @@ j = 0; pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node); + if (!pcaps[i].pg.name) { + kfree(pcaps[i].pattrs); + kfree(pcaps[i].pg.attrs); + goto out_pcaps_pattrs; + } + if (has_min) { powercap_add_attr(min, "powercap-min", &pcaps[i].pattrs[j]); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-prd.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-prd.c @@ -372,6 +372,12 @@ .priority = 0, }; +static struct notifier_block opal_prd_event_nb2 = { + .notifier_call = opal_prd_msg_notifier, + .next = NULL, + .priority = 0, +}; + static int opal_prd_probe(struct platform_device *pdev) { int rc; @@ -393,9 +399,10 @@ return rc; } - rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb); + rc = opal_message_notifier_register(OPAL_MSG_PRD2, &opal_prd_event_nb2); if (rc) { pr_err("Couldn't register PRD2 event notifier\n"); + opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); return rc; } @@ -404,6 +411,8 @@ pr_err("failed to register miscdev\n"); opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); + opal_message_notifier_unregister(OPAL_MSG_PRD2, + &opal_prd_event_nb2); return rc; } @@ -414,6 +423,7 @@ { misc_deregister(&opal_prd_dev); opal_message_notifier_unregister(OPAL_MSG_PRD, &opal_prd_event_nb); + opal_message_notifier_unregister(OPAL_MSG_PRD2, &opal_prd_event_nb2); return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-secvar.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-secvar.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PowerNV code for secure variables + * + * Copyright (C) 2019 IBM Corporation + * Author: Claudio Carvalho + * Nayna Jain + * + * APIs to access secure variables managed by OPAL. + */ + +#define pr_fmt(fmt) "secvar: "fmt + +#include +#include +#include +#include +#include +#include + +static int opal_status_to_err(int rc) +{ + int err; + + switch (rc) { + case OPAL_SUCCESS: + err = 0; + break; + case OPAL_UNSUPPORTED: + err = -ENXIO; + break; + case OPAL_PARAMETER: + err = -EINVAL; + break; + case OPAL_RESOURCE: + err = -ENOSPC; + break; + case OPAL_HARDWARE: + err = -EIO; + break; + case OPAL_NO_MEM: + err = -ENOMEM; + break; + case OPAL_EMPTY: + err = -ENOENT; + break; + case OPAL_PARTIAL: + err = -EFBIG; + break; + default: + err = -EINVAL; + } + + return err; +} + +static int opal_get_variable(const char *key, uint64_t ksize, + u8 *data, uint64_t *dsize) +{ + int rc; + + if (!key || !dsize) + return -EINVAL; + + *dsize = cpu_to_be64(*dsize); + + rc = opal_secvar_get(key, ksize, data, dsize); + + *dsize = be64_to_cpu(*dsize); + + return opal_status_to_err(rc); +} + +static int opal_get_next_variable(const char *key, uint64_t *keylen, + uint64_t keybufsize) +{ + int rc; + + if (!key || !keylen) + return -EINVAL; + + *keylen = cpu_to_be64(*keylen); + + rc = opal_secvar_get_next(key, keylen, keybufsize); + + *keylen = be64_to_cpu(*keylen); + + return opal_status_to_err(rc); +} + +static int opal_set_variable(const char *key, uint64_t ksize, u8 *data, + uint64_t dsize) +{ + int rc; + + if (!key || !data) + return -EINVAL; + + rc = opal_secvar_enqueue_update(key, ksize, data, dsize); + + return opal_status_to_err(rc); +} + +static const struct secvar_operations opal_secvar_ops = { + .get = opal_get_variable, + .get_next = opal_get_next_variable, + .set = opal_set_variable, +}; + +static int opal_secvar_probe(struct platform_device *pdev) +{ + if (!opal_check_token(OPAL_SECVAR_GET) + || !opal_check_token(OPAL_SECVAR_GET_NEXT) + || !opal_check_token(OPAL_SECVAR_ENQUEUE_UPDATE)) { + pr_err("OPAL doesn't support secure variables\n"); + return -ENODEV; + } + + set_secvar_ops(&opal_secvar_ops); + + return 0; +} + +static const struct of_device_id opal_secvar_match[] = { + { .compatible = "ibm,secvar-backend",}, + {}, +}; + +static struct platform_driver opal_secvar_driver = { + .driver = { + .name = "secvar", + .of_match_table = opal_secvar_match, + }, +}; + +static int __init opal_secvar_init(void) +{ + return platform_driver_probe(&opal_secvar_driver, opal_secvar_probe); +} +device_initcall(opal_secvar_init); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal-xscom.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal-xscom.c @@ -165,6 +165,11 @@ ent->chip = chip; snprintf(ent->name, 16, "%08x", chip); ent->path.data = (void *)kasprintf(GFP_KERNEL, "%pOF", dn); + if (!ent->path.data) { + kfree(ent); + return -ENOMEM; + } + ent->path.size = strlen((char *)ent->path.data); dir = debugfs_create_dir(ent->name, root); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/opal.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/opal.c @@ -776,6 +776,7 @@ kobj = kobject_create_and_add("exports", opal_kobj); if (!kobj) { pr_warn("kobject_create_and_add() of exports failed\n"); + of_node_put(np); return; } @@ -1002,6 +1003,9 @@ /* Initialise OPAL Power control interface */ opal_power_control_init(); + /* Initialize OPAL secure variables */ + opal_pdev_init("ibm,secvar-backend"); + return 0; } machine_subsys_initcall(powernv, opal_init); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/pci-ioda.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/pci-ioda.c @@ -188,7 +188,7 @@ unsigned int pe_num = pe->pe_number; WARN_ON(pe->pdev); - WARN_ON(pe->npucomp); /* NPUs are not supposed to be freed */ + WARN_ON(pe->npucomp); /* NPUs for nvlink are not supposed to be freed */ kfree(pe->npucomp); memset(pe, 0, sizeof(struct pnv_ioda_pe)); clear_bit(pe_num, phb->ioda.pe_alloc); @@ -777,6 +777,34 @@ return 0; } +static void pnv_ioda_unset_peltv(struct pnv_phb *phb, + struct pnv_ioda_pe *pe, + struct pci_dev *parent) +{ + int64_t rc; + + while (parent) { + struct pci_dn *pdn = pci_get_pdn(parent); + + if (pdn && pdn->pe_number != IODA_INVALID_PE) { + rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, + pe->pe_number, + OPAL_REMOVE_PE_FROM_DOMAIN); + /* XXX What to do in case of error ? */ + } + parent = parent->bus->self; + } + + opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, + OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + + /* Disassociate PE in PELT */ + rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, + pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN); + if (rc) + pe_warn(pe, "OPAL error %lld remove self from PELTV\n", rc); +} + static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe) { struct pci_dev *parent; @@ -827,25 +855,13 @@ for (rid = pe->rid; rid < rid_end; rid++) phb->ioda.pe_rmap[rid] = IODA_INVALID_PE; - /* Release from all parents PELT-V */ - while (parent) { - struct pci_dn *pdn = pci_get_pdn(parent); - if (pdn && pdn->pe_number != IODA_INVALID_PE) { - rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number, - pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN); - /* XXX What to do in case of error ? */ - } - parent = parent->bus->self; - } - - opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number, - OPAL_EEH_ACTION_CLEAR_FREEZE_ALL); + /* + * Release from all parents PELT-V. NPUs don't have a PELTV + * table + */ + if (phb->type != PNV_PHB_NPU_NVLINK && phb->type != PNV_PHB_NPU_OCAPI) + pnv_ioda_unset_peltv(phb, pe, parent); - /* Disassociate PE in PELT */ - rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number, - pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN); - if (rc) - pe_warn(pe, "OPAL error %lld remove self from PELTV\n", rc); rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid, bcomp, dcomp, fcomp, OPAL_UNMAP_PE); if (rc) @@ -1062,20 +1078,20 @@ return NULL; } - /* NOTE: We get only one ref to the pci_dev for the pdn, not for the - * pointer in the PE data structure, both should be destroyed at the - * same time. However, this needs to be looked at more closely again - * once we actually start removing things (Hotplug, SR-IOV, ...) + /* NOTE: We don't get a reference for the pointer in the PE + * data structure, both the device and PE structures should be + * destroyed at the same time. However, removing nvlink + * devices will need some work. * * At some point we want to remove the PDN completely anyways */ - pci_dev_get(dev); pdn->pe_number = pe->pe_number; pe->flags = PNV_IODA_PE_DEV; pe->pdev = dev; pe->pbus = NULL; pe->mve_number = -1; pe->rid = dev->bus->number << 8 | pdn->devfn; + pe->device_count++; pe_info(pe, "Associated device to PE\n"); @@ -1084,13 +1100,13 @@ pnv_ioda_free_pe(pe); pdn->pe_number = IODA_INVALID_PE; pe->pdev = NULL; - pci_dev_put(dev); return NULL; } /* Put PE to the list */ + mutex_lock(&phb->ioda.pe_list_mutex); list_add_tail(&pe->list, &phb->ioda.pe_list); - + mutex_unlock(&phb->ioda.pe_list_mutex); return pe; } @@ -1206,6 +1222,14 @@ struct pnv_phb *phb = hose->private_data; /* + * Intentionally leak a reference on the npu device (for + * nvlink only; this is not an opencapi path) to make sure it + * never goes away, as it's been the case all along and some + * work is needed otherwise. + */ + pci_dev_get(npu_pdev); + + /* * Due to a hardware errata PE#0 on the NPU is reserved for * error handling. This means we only have three PEs remaining * which need to be assigned to four links, implying some @@ -1228,11 +1252,11 @@ */ dev_info(&npu_pdev->dev, "Associating to existing PE %x\n", pe_num); - pci_dev_get(npu_pdev); npu_pdn = pci_get_pdn(npu_pdev); rid = npu_pdev->bus->number << 8 | npu_pdn->devfn; npu_pdn->pe_number = pe_num; phb->ioda.pe_rmap[rid] = pe->pe_number; + pe->device_count++; /* Map the PE to this link */ rc = opal_pci_set_pe(phb->opal_id, pe_num, rid, @@ -1268,8 +1292,6 @@ { struct pci_controller *hose; struct pnv_phb *phb; - struct pci_bus *bus; - struct pci_dev *pdev; struct pnv_ioda_pe *pe; list_for_each_entry(hose, &hose_list, list_node) { @@ -1281,11 +1303,6 @@ if (phb->model == PNV_PHB_MODEL_NPU2) WARN_ON_ONCE(pnv_npu2_init(hose)); } - if (phb->type == PNV_PHB_NPU_OCAPI) { - bus = hose->bus; - list_for_each_entry(pdev, &bus->devices, bus_list) - pnv_ioda_setup_dev_PE(pdev); - } } list_for_each_entry(hose, &hose_list, list_node) { phb = hose->private_data; @@ -1558,6 +1575,10 @@ /* Reserve PE for each VF */ for (vf_index = 0; vf_index < num_vfs; vf_index++) { + int vf_devfn = pci_iov_virtfn_devfn(pdev, vf_index); + int vf_bus = pci_iov_virtfn_bus(pdev, vf_index); + struct pci_dn *vf_pdn; + if (pdn->m64_single_mode) pe_num = pdn->pe_num_map[vf_index]; else @@ -1570,13 +1591,11 @@ pe->pbus = NULL; pe->parent_dev = pdev; pe->mve_number = -1; - pe->rid = (pci_iov_virtfn_bus(pdev, vf_index) << 8) | - pci_iov_virtfn_devfn(pdev, vf_index); + pe->rid = (vf_bus << 8) | vf_devfn; pe_info(pe, "VF %04d:%02d:%02d.%d associated with PE#%x\n", hose->global_number, pdev->bus->number, - PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)), - PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)), pe_num); + PCI_SLOT(vf_devfn), PCI_FUNC(vf_devfn), pe_num); if (pnv_ioda_configure_pe(phb, pe)) { /* XXX What do we do here ? */ @@ -1590,6 +1609,15 @@ list_add_tail(&pe->list, &phb->ioda.pe_list); mutex_unlock(&phb->ioda.pe_list_mutex); + /* associate this pe to it's pdn */ + list_for_each_entry(vf_pdn, &pdn->parent->child_list, list) { + if (vf_pdn->busno == vf_bus && + vf_pdn->devfn == vf_devfn) { + vf_pdn->pe_number = pe_num; + break; + } + } + pnv_pci_ioda2_setup_dma_pe(phb, pe); #ifdef CONFIG_IOMMU_API iommu_register_group(&pe->table_group, @@ -2889,9 +2917,6 @@ struct pci_dn *pdn; int mul, total_vfs; - if (!pdev->is_physfn || pci_dev_is_added(pdev)) - return; - pdn = pci_get_pdn(pdev); pdn->vfs_expanded = 0; pdn->m64_single_mode = false; @@ -2966,6 +2991,30 @@ res->end = res->start - 1; } } + +static void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev) +{ + if (WARN_ON(pci_dev_is_added(pdev))) + return; + + if (pdev->is_virtfn) { + struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev); + + /* + * VF PEs are single-device PEs so their pdev pointer needs to + * be set. The pdev doesn't exist when the PE is allocated (in + * (pcibios_sriov_enable()) so we fix it up here. + */ + pe->pdev = pdev; + WARN_ON(!(pe->flags & PNV_IODA_PE_VF)); + } else if (pdev->is_physfn) { + /* + * For PFs adjust their allocated IOV resources to match what + * the PHB can support using it's M64 BAR table. + */ + pnv_pci_ioda_fixup_iov_resources(pdev); + } +} #endif /* CONFIG_PCI_IOV */ static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe, @@ -2976,7 +3025,8 @@ int index; int64_t rc; - if (!res || !res->flags || res->start > res->end) + if (!res || !res->flags || res->start > res->end || + res->flags & IORESOURCE_UNSET) return; if (res->flags & IORESOURCE_IO) { @@ -3383,6 +3433,28 @@ return true; } +static bool pnv_ocapi_enable_device_hook(struct pci_dev *dev) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + struct pci_dn *pdn; + struct pnv_ioda_pe *pe; + + if (!phb->initialized) + return true; + + pdn = pci_get_pdn(dev); + if (!pdn) + return false; + + if (pdn->pe_number == IODA_INVALID_PE) { + pe = pnv_ioda_setup_dev_PE(dev); + if (!pe) + return false; + } + return true; +} + static long pnv_pci_ioda1_unset_window(struct iommu_table_group *table_group, int num) { @@ -3512,7 +3584,10 @@ struct pnv_phb *phb = pe->phb; struct pnv_ioda_pe *slave, *tmp; + mutex_lock(&phb->ioda.pe_list_mutex); list_del(&pe->list); + mutex_unlock(&phb->ioda.pe_list_mutex); + switch (phb->type) { case PNV_PHB_IODA1: pnv_pci_ioda1_release_pe_dma(pe); @@ -3520,6 +3595,8 @@ case PNV_PHB_IODA2: pnv_pci_ioda2_release_pe_dma(pe); break; + case PNV_PHB_NPU_OCAPI: + break; default: WARN_ON(1); } @@ -3620,7 +3697,8 @@ }; static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = { - .enable_device_hook = pnv_pci_enable_device_hook, + .enable_device_hook = pnv_ocapi_enable_device_hook, + .release_device = pnv_pci_release_device, .window_alignment = pnv_pci_window_alignment, .reset_secondary_bus = pnv_pci_reset_secondary_bus, .shutdown = pnv_pci_ioda_shutdown, @@ -3862,7 +3940,7 @@ ppc_md.pcibios_default_alignment = pnv_pci_default_alignment; #ifdef CONFIG_PCI_IOV - ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources; + ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov; ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment; ppc_md.pcibios_sriov_enable = pnv_pcibios_sriov_enable; ppc_md.pcibios_sriov_disable = pnv_pcibios_sriov_disable; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/pci.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/pci.c @@ -38,7 +38,7 @@ int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id) { - struct device_node *parent = np; + struct device_node *node = np; u32 bdfn; u64 phbid; int ret; @@ -48,25 +48,29 @@ return -ENXIO; bdfn = ((bdfn & 0x00ffff00) >> 8); - while ((parent = of_get_parent(parent))) { - if (!PCI_DN(parent)) { - of_node_put(parent); + for (node = np; node; node = of_get_parent(node)) { + if (!PCI_DN(node)) { + of_node_put(node); break; } - if (!of_device_is_compatible(parent, "ibm,ioda2-phb") && - !of_device_is_compatible(parent, "ibm,ioda3-phb")) { - of_node_put(parent); + if (!of_device_is_compatible(node, "ibm,ioda2-phb") && + !of_device_is_compatible(node, "ibm,ioda3-phb") && + !of_device_is_compatible(node, "ibm,ioda2-npu2-opencapi-phb")) { + of_node_put(node); continue; } - ret = of_property_read_u64(parent, "ibm,opal-phbid", &phbid); + ret = of_property_read_u64(node, "ibm,opal-phbid", &phbid); if (ret) { - of_node_put(parent); + of_node_put(node); return -ENXIO; } - *id = PCI_SLOT_ID(phbid, bdfn); + if (of_device_is_compatible(node, "ibm,ioda2-npu2-opencapi-phb")) + *id = PCI_PHB_SLOT_ID(phbid); + else + *id = PCI_SLOT_ID(phbid, bdfn); return 0; } @@ -814,24 +818,6 @@ { struct pci_controller *hose = pci_bus_to_host(pdev->bus); struct pnv_phb *phb = hose->private_data; -#ifdef CONFIG_PCI_IOV - struct pnv_ioda_pe *pe; - struct pci_dn *pdn; - - /* Fix the VF pdn PE number */ - if (pdev->is_virtfn) { - pdn = pci_get_pdn(pdev); - WARN_ON(pdn->pe_number != IODA_INVALID_PE); - list_for_each_entry(pe, &phb->ioda.pe_list, list) { - if (pe->rid == ((pdev->bus->number << 8) | - (pdev->devfn & 0xff))) { - pdn->pe_number = pe->pe_number; - pe->pdev = pdev; - break; - } - } - } -#endif /* CONFIG_PCI_IOV */ if (phb && phb->dma_dev_setup) phb->dma_dev_setup(phb, pdev); @@ -945,6 +931,23 @@ if (!firmware_has_feature(FW_FEATURE_OPAL)) return; +#ifdef CONFIG_PCIEPORTBUS + /* + * On PowerNV PCIe devices are (currently) managed in cooperation + * with firmware. This isn't *strictly* required, but there's enough + * assumptions baked into both firmware and the platform code that + * it's unwise to allow the portbus services to be used. + * + * We need to fix this eventually, but for now set this flag to disable + * the portbus driver. The AER service isn't required since that AER + * events are handled via EEH. The pciehp hotplug driver can't work + * without kernel changes (and portbus binding breaks pnv_php). The + * other services also require some thinking about how we're going + * to integrate them. + */ + pcie_ports_disabled = true; +#endif + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/powernv.h +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/powernv.h @@ -35,4 +35,6 @@ u32 memcons_get_size(struct memcons *mc); struct memcons *memcons_init(struct device_node *node, const char *mc_prop_name); +void pnv_rng_init(void); + #endif /* _POWERNV_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/rng.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/rng.c @@ -17,6 +17,7 @@ #include #include #include +#include "powernv.h" #define DARN_ERR 0xFFFFFFFFFFFFFFFFul @@ -28,7 +29,6 @@ static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); - int powernv_hwrng_present(void) { struct powernv_rng *rng; @@ -43,7 +43,11 @@ unsigned long parity; /* Calculate the parity of the value */ - asm ("popcntd %0,%1" : "=r" (parity) : "r" (val)); + asm (".machine push; \ + .machine power7; \ + popcntd %0,%1; \ + .machine pop;" + : "=r" (parity) : "r" (val)); /* xor our value with the previous mask */ val ^= rng->mask; @@ -59,6 +63,8 @@ struct powernv_rng *rng; rng = raw_cpu_read(powernv_rng); + if (!rng) + return 0; *v = rng_whiten(rng, __raw_rm_readq(rng->regs_real)); @@ -94,9 +100,6 @@ return 0; } } - - pr_warn("Unable to use DARN for get_random_seed()\n"); - return -EIO; } @@ -159,32 +162,59 @@ rng_init_per_cpu(rng, dn); - pr_info_once("Registering arch random hook.\n"); - ppc_md.get_random_seed = powernv_get_random_long; return 0; } -static __init int rng_init(void) +static int __init pnv_get_random_long_early(unsigned long *v) { struct device_node *dn; - int rc; - for_each_compatible_node(dn, NULL, "ibm,power-rng") { - rc = rng_create(dn); - if (rc) { - pr_err("Failed creating rng for %pOF (%d).\n", - dn, rc); - continue; - } + if (!slab_is_available()) + return 0; - /* Create devices for hwrng driver */ - of_platform_device_create(dn, NULL, NULL); - } + if (cmpxchg(&ppc_md.get_random_seed, pnv_get_random_long_early, + NULL) != pnv_get_random_long_early) + return 0; - initialise_darn(); + for_each_compatible_node(dn, NULL, "ibm,power-rng") + rng_create(dn); + + if (!ppc_md.get_random_seed) + return 0; + return ppc_md.get_random_seed(v); +} + +void __init pnv_rng_init(void) +{ + struct device_node *dn; + + /* Prefer darn over the rest. */ + if (!initialise_darn()) + return; + + dn = of_find_compatible_node(NULL, NULL, "ibm,power-rng"); + if (dn) + ppc_md.get_random_seed = pnv_get_random_long_early; + + of_node_put(dn); +} + +static int __init pnv_rng_late_init(void) +{ + struct device_node *dn; + unsigned long v; + + /* In case it wasn't called during init for some other reason. */ + if (ppc_md.get_random_seed == pnv_get_random_long_early) + pnv_get_random_long_early(&v); + + if (ppc_md.get_random_seed == powernv_get_random_long) { + for_each_compatible_node(dn, NULL, "ibm,power-rng") + of_platform_device_create(dn, NULL, NULL); + } return 0; } -machine_subsys_initcall(powernv, rng_init); +machine_subsys_initcall(powernv, pnv_rng_late_init); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/setup.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/setup.c @@ -122,12 +122,29 @@ type = L1D_FLUSH_ORI; } + /* + * If we are non-Power9 bare metal, we don't need to flush on kernel + * entry or after user access: they fix a P9 specific vulnerability. + */ + if (!pvr_version_is(PVR_POWER9)) { + security_ftr_clear(SEC_FTR_L1D_FLUSH_ENTRY); + security_ftr_clear(SEC_FTR_L1D_FLUSH_UACCESS); + } + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && \ (security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR) || \ security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV)); setup_rfi_flush(type, enable); setup_count_cache_flush(); + + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && + security_ftr_enabled(SEC_FTR_L1D_FLUSH_ENTRY); + setup_entry_flush(enable); + + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && + security_ftr_enabled(SEC_FTR_L1D_FLUSH_UACCESS); + setup_uaccess_flush(enable); } static void __init pnv_setup_arch(void) @@ -151,6 +168,8 @@ powersave_nap = 1; /* XXX PMCS */ + + pnv_rng_init(); } static void __init pnv_init(void) @@ -169,11 +188,16 @@ add_preferred_console("hvc", 0, NULL); if (!radix_enabled()) { + size_t size = sizeof(struct slb_entry) * mmu_slb_size; int i; /* Allocate per cpu area to save old slb contents during MCE */ - for_each_possible_cpu(i) - paca_ptrs[i]->mce_faulty_slbs = memblock_alloc_node(mmu_slb_size, __alignof__(*paca_ptrs[i]->mce_faulty_slbs), cpu_to_node(i)); + for_each_possible_cpu(i) { + paca_ptrs[i]->mce_faulty_slbs = + memblock_alloc_node(size, + __alignof__(struct slb_entry), + cpu_to_node(i)); + } } } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/smp.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/smp.c @@ -43,7 +43,7 @@ #include #define DBG(fmt...) udbg_printf(fmt) #else -#define DBG(fmt...) +#define DBG(fmt...) do { } while (0) #endif static void pnv_smp_setup_cpu(int cpu) @@ -167,7 +167,6 @@ /* Standard hot unplug procedure */ idle_task_exit(); - current->active_mm = NULL; /* for sanity */ cpu = smp_processor_id(); DBG("CPU%d offline\n", cpu); generic_set_cpu_dead(cpu); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/powernv/ultravisor.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/powernv/ultravisor.c @@ -55,6 +55,7 @@ return -ENODEV; uv_memcons = memcons_init(node, "memcons"); + of_node_put(node); if (!uv_memcons) return -ENOENT; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/ps3/mm.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/ps3/mm.c @@ -6,6 +6,7 @@ * Copyright 2006 Sony Corp. */ +#include #include #include #include @@ -200,13 +201,14 @@ { int result; - DBG("%s:%d: map.vas_id = %llu\n", __func__, __LINE__, map.vas_id); - if (map.vas_id) { result = lv1_select_virtual_address_space(0); - BUG_ON(result); - result = lv1_destruct_virtual_address_space(map.vas_id); - BUG_ON(result); + result += lv1_destruct_virtual_address_space(map.vas_id); + + if (result) { + lv1_panic(0); + } + map.vas_id = 0; } } @@ -304,19 +306,20 @@ int result; if (!r->destroy) { - pr_info("%s:%d: Not destroying high region: %llxh %llxh\n", - __func__, __LINE__, r->base, r->size); return; } - DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base); - if (r->base) { result = lv1_release_memory(r->base); - BUG_ON(result); + + if (result) { + lv1_panic(0); + } + r->size = r->base = r->offset = 0; map.total = map.rm.size; } + ps3_mm_set_repository_highmem(NULL); } @@ -1116,6 +1119,7 @@ enum ps3_dma_region_type region_type, void *addr, unsigned long len) { unsigned long lpar_addr; + int result; lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0; @@ -1127,6 +1131,16 @@ r->offset -= map.r1.offset; r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size); + dev->core.dma_mask = &r->dma_mask; + + result = dma_set_mask_and_coherent(&dev->core, DMA_BIT_MASK(32)); + + if (result < 0) { + dev_err(&dev->core, "%s:%d: dma_set_mask_and_coherent failed: %d\n", + __func__, __LINE__, result); + return result; + } + switch (dev->dev_type) { case PS3_DEVICE_TYPE_SB: r->region_ops = (USE_DYNAMIC_DMA) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/cmm.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/cmm.c @@ -411,6 +411,10 @@ .dev_name = "cmm", }; +static void cmm_release_device(struct device *dev) +{ +} + /** * cmm_sysfs_register - Register with sysfs * @@ -426,6 +430,7 @@ dev->id = 0; dev->bus = &cmm_subsys; + dev->release = cmm_release_device; if ((rc = device_register(dev))) goto subsys_unregister; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/dlpar.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/dlpar.c @@ -127,7 +127,6 @@ #define NEXT_PROPERTY 3 #define PREV_PARENT 4 #define MORE_MEMORY 5 -#define CALL_AGAIN -2 #define ERR_CFG_USE -9003 struct device_node *dlpar_configure_connector(__be32 drc_index, @@ -168,6 +167,9 @@ spin_unlock(&rtas_data_buf_lock); + if (rtas_busy_delay(rc)) + continue; + switch (rc) { case COMPLETE: break; @@ -216,9 +218,6 @@ last_dn = last_dn->parent; break; - case CALL_AGAIN: - break; - case MORE_MEMORY: case ERR_CFG_USE: default: --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/eeh_pseries.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -472,8 +472,10 @@ switch(rets[0]) { case 0: - result = EEH_STATE_MMIO_ACTIVE | - EEH_STATE_DMA_ACTIVE; + result = EEH_STATE_MMIO_ACTIVE | + EEH_STATE_DMA_ACTIVE | + EEH_STATE_MMIO_ENABLED | + EEH_STATE_DMA_ENABLED; break; case 1: result = EEH_STATE_RESET_ACTIVE | --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -91,9 +91,6 @@ BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); - printk("cpu %u (hwid %u) Ready to die...\n", - smp_processor_id(), hard_smp_processor_id()); - rtas_call_unlocked(&args, rtas_stop_self_token, 0, 1, NULL); panic("Alas, I survived.\n"); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/hotplug-memory.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -27,7 +27,7 @@ unsigned long pseries_memory_block_size(void) { struct device_node *np; - unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; + u64 memblock_size = MIN_MEMORY_BLOCK_SIZE; struct resource r; np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); @@ -223,7 +223,7 @@ struct drmem_lmb **end_lmb) { struct drmem_lmb *lmb, *start, *end; - struct drmem_lmb *last_lmb; + struct drmem_lmb *limit; start = NULL; for_each_drmem_lmb(lmb) { @@ -236,10 +236,10 @@ if (!start) return -EINVAL; - end = &start[n_lmbs - 1]; + end = &start[n_lmbs]; - last_lmb = &drmem_info->lmbs[drmem_info->n_lmbs - 1]; - if (end > last_lmb) + limit = &drmem_info->lmbs[drmem_info->n_lmbs]; + if (end > limit) return -EINVAL; *start_lmb = start; @@ -279,7 +279,7 @@ return dlpar_change_lmb_state(lmb, false); } -static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) +static int pseries_remove_memblock(unsigned long base, unsigned long memblock_size) { unsigned long block_sz, start_pfn; int sections_per_block; @@ -310,10 +310,11 @@ static int pseries_remove_mem_node(struct device_node *np) { - const __be32 *regs; + const __be32 *prop; unsigned long base; - unsigned int lmb_size; + unsigned long lmb_size; int ret = -EINVAL; + int addr_cells, size_cells; /* * Check to see if we are actually removing memory @@ -324,12 +325,19 @@ /* * Find the base address and size of the memblock */ - regs = of_get_property(np, "reg", NULL); - if (!regs) + prop = of_get_property(np, "reg", NULL); + if (!prop) return ret; - base = be64_to_cpu(*(unsigned long *)regs); - lmb_size = be32_to_cpu(regs[3]); + addr_cells = of_n_addr_cells(np); + size_cells = of_n_size_cells(np); + + /* + * "reg" property represents (addr,size) tuple. + */ + base = of_read_number(prop, addr_cells); + prop += addr_cells; + lmb_size = of_read_number(prop, size_cells); pseries_remove_memblock(base, lmb_size); return 0; @@ -360,8 +368,10 @@ for (i = 0; i < scns_per_block; i++) { pfn = PFN_DOWN(phys_addr); - if (!pfn_present(pfn)) + if (!pfn_present(pfn)) { + phys_addr += MIN_MEMORY_BLOCK_SIZE; continue; + } rc &= is_mem_section_removable(pfn, PAGES_PER_SECTION); phys_addr += MIN_MEMORY_BLOCK_SIZE; @@ -374,25 +384,32 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb) { + struct memory_block *mem_block; unsigned long block_sz; int rc; if (!lmb_is_removable(lmb)) return -EINVAL; + mem_block = lmb_to_memblock(lmb); + if (mem_block == NULL) + return -EINVAL; + rc = dlpar_offline_lmb(lmb); - if (rc) + if (rc) { + put_device(&mem_block->dev); return rc; + } block_sz = pseries_memory_block_size(); - __remove_memory(lmb->nid, lmb->base_addr, block_sz); + __remove_memory(mem_block->nid, lmb->base_addr, block_sz); + put_device(&mem_block->dev); /* Update memory regions for memory remove */ memblock_remove(lmb->base_addr, block_sz); invalidate_lmb_associativity_index(lmb); - lmb_clear_nid(lmb); lmb->flags &= ~DRCONF_MEM_ASSIGNED; return 0; @@ -479,7 +496,7 @@ int lmb_found; int rc; - pr_info("Attempting to hot-remove LMB, drc index %x\n", drc_index); + pr_debug("Attempting to hot-remove LMB, drc index %x\n", drc_index); lmb_found = 0; for_each_drmem_lmb(lmb) { @@ -493,14 +510,15 @@ } } - if (!lmb_found) + if (!lmb_found) { + pr_debug("Failed to look up LMB for drc index %x\n", drc_index); rc = -EINVAL; - - if (rc) - pr_info("Failed to hot-remove memory at %llx\n", - lmb->base_addr); - else - pr_info("Memory at %llx was hot-removed\n", lmb->base_addr); + } else if (rc) { + pr_debug("Failed to hot-remove memory at %llx\n", + lmb->base_addr); + } else { + pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); + } return rc; } @@ -611,7 +629,7 @@ #else static inline int pseries_remove_memblock(unsigned long base, - unsigned int memblock_size) + unsigned long memblock_size) { return -EOPNOTSUPP; } @@ -649,7 +667,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb) { unsigned long block_sz; - int rc; + int nid, rc; if (lmb->flags & DRCONF_MEM_ASSIGNED) return -EINVAL; @@ -660,11 +678,13 @@ return rc; } - lmb_set_nid(lmb); block_sz = memory_block_size_bytes(); + /* Find the node id for this address. */ + nid = memory_add_physaddr_to_nid(lmb->base_addr); + /* Add the memory */ - rc = __add_memory(lmb->nid, lmb->base_addr, block_sz); + rc = __add_memory(nid, lmb->base_addr, block_sz); if (rc) { invalidate_lmb_associativity_index(lmb); return rc; @@ -672,9 +692,8 @@ rc = dlpar_online_lmb(lmb); if (rc) { - __remove_memory(lmb->nid, lmb->base_addr, block_sz); + __remove_memory(nid, lmb->base_addr, block_sz); invalidate_lmb_associativity_index(lmb); - lmb_clear_nid(lmb); } else { lmb->flags |= DRCONF_MEM_ASSIGNED; } @@ -752,8 +771,8 @@ if (!drmem_lmb_reserved(lmb)) continue; - pr_info("Memory at %llx (drc index %x) was hot-added\n", - lmb->base_addr, lmb->drc_index); + pr_debug("Memory at %llx (drc index %x) was hot-added\n", + lmb->base_addr, lmb->drc_index); drmem_remove_lmb_reservation(lmb); } rc = 0; @@ -943,10 +962,11 @@ static int pseries_add_mem_node(struct device_node *np) { - const __be32 *regs; + const __be32 *prop; unsigned long base; - unsigned int lmb_size; + unsigned long lmb_size; int ret = -EINVAL; + int addr_cells, size_cells; /* * Check to see if we are actually adding memory @@ -957,12 +977,18 @@ /* * Find the base and size of the memblock */ - regs = of_get_property(np, "reg", NULL); - if (!regs) + prop = of_get_property(np, "reg", NULL); + if (!prop) return ret; - base = be64_to_cpu(*(unsigned long *)regs); - lmb_size = be32_to_cpu(regs[3]); + addr_cells = of_n_addr_cells(np); + size_cells = of_n_size_cells(np); + /* + * "reg" property represents (addr,size) tuple. + */ + base = of_read_number(prop, addr_cells); + prop += addr_cells; + lmb_size = of_read_number(prop, size_cells); /* * Update memory region to represent the memory add --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/ibmebus.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/ibmebus.c @@ -450,6 +450,7 @@ if (err) { printk(KERN_WARNING "%s: device_register returned %i\n", __func__, err); + put_device(&ibmebus_bus_device); bus_unregister(&ibmebus_bus_type); return err; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/iommu.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/iommu.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "pseries.h" @@ -133,10 +132,10 @@ return be64_to_cpu(*tcep); } -static void tce_free_pSeriesLP(struct iommu_table*, long, long); +static void tce_free_pSeriesLP(unsigned long liobn, long, long); static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long); -static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, +static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift, long npages, unsigned long uaddr, enum dma_data_direction direction, unsigned long attrs) @@ -147,25 +146,25 @@ int ret = 0; long tcenum_start = tcenum, npages_start = npages; - rpn = __pa(uaddr) >> TCE_SHIFT; + rpn = __pa(uaddr) >> tceshift; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) proto_tce |= TCE_PCI_WRITE; while (npages--) { - tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; - rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce); + tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift; + rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce); if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) { ret = (int)rc; - tce_free_pSeriesLP(tbl, tcenum_start, + tce_free_pSeriesLP(liobn, tcenum_start, (npages_start - (npages + 1))); break; } if (rc && printk_ratelimit()) { printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); - printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tindex = 0x%llx\n", (u64)liobn); printk("\ttcenum = 0x%llx\n", (u64)tcenum); printk("\ttce val = 0x%llx\n", tce ); dump_stack(); @@ -194,7 +193,8 @@ unsigned long flags; if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) { - return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, + return tce_build_pSeriesLP(tbl->it_index, tcenum, + tbl->it_page_shift, npages, uaddr, direction, attrs); } @@ -210,8 +210,9 @@ /* If allocation fails, fall back to the loop implementation */ if (!tcep) { local_irq_restore(flags); - return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, - direction, attrs); + return tce_build_pSeriesLP(tbl->it_index, tcenum, + tbl->it_page_shift, + npages, uaddr, direction, attrs); } __this_cpu_write(tce_page, tcep); } @@ -262,16 +263,16 @@ return ret; } -static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) +static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages) { u64 rc; while (npages--) { - rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); + rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0); if (rc && printk_ratelimit()) { printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc); - printk("\tindex = 0x%llx\n", (u64)tbl->it_index); + printk("\tindex = 0x%llx\n", (u64)liobn); printk("\ttcenum = 0x%llx\n", (u64)tcenum); dump_stack(); } @@ -286,7 +287,7 @@ u64 rc; if (!firmware_has_feature(FW_FEATURE_MULTITCE)) - return tce_free_pSeriesLP(tbl, tcenum, npages); + return tce_free_pSeriesLP(tbl->it_index, tcenum, npages); rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); @@ -401,6 +402,19 @@ u64 rc = 0; long l, limit; + if (!firmware_has_feature(FW_FEATURE_MULTITCE)) { + unsigned long tceshift = be32_to_cpu(maprange->tce_shift); + unsigned long dmastart = (start_pfn << PAGE_SHIFT) + + be64_to_cpu(maprange->dma_base); + unsigned long tcenum = dmastart >> tceshift; + unsigned long npages = num_pfn << PAGE_SHIFT >> tceshift; + void *uaddr = __va(start_pfn << PAGE_SHIFT); + + return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn), + tcenum, tceshift, npages, (unsigned long) uaddr, + DMA_BIDIRECTIONAL, 0); + } + local_irq_disable(); /* to protect tcep and the page behind it */ tcep = __this_cpu_read(tce_page); @@ -1320,15 +1334,7 @@ of_reconfig_notifier_register(&iommu_reconfig_nb); register_memory_notifier(&iommu_mem_nb); - /* - * Secure guest memory is inacessible to devices so regular DMA isn't - * possible. - * - * In that case keep devices' dma_map_ops as NULL so that the generic - * DMA code path will use SWIOTLB to bounce buffers for DMA. - */ - if (!is_secure_guest()) - set_pci_dma_ops(&dma_iommu_ops); + set_pci_dma_ops(&dma_iommu_ops); } static int __init disable_multitce(char *str) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/lpar.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/lpar.c @@ -522,8 +522,10 @@ if (cmd) { rc = init_cpu_associativity(); - if (rc) + if (rc) { + destroy_cpu_associativity(); goto out; + } for_each_possible_cpu(cpu) { disp = per_cpu_ptr(&vcpu_disp_data, cpu); @@ -1416,22 +1418,22 @@ void __init pseries_lpar_read_hblkrm_characteristics(void) { + const s32 token = rtas_token("ibm,get-system-parameter"); unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH]; int call_status, len, idx, bpsize; if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) return; - spin_lock(&rtas_data_buf_lock); - memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - SPLPAR_TLB_BIC_TOKEN, - __pa(rtas_data_buf), - RTAS_DATA_BUF_SIZE); - memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH); - local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0'; - spin_unlock(&rtas_data_buf_lock); + do { + spin_lock(&rtas_data_buf_lock); + memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); + call_status = rtas_call(token, 3, 1, NULL, SPLPAR_TLB_BIC_TOKEN, + __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); + memcpy(local_buffer, rtas_data_buf, SPLPAR_TLB_BIC_MAXLENGTH); + local_buffer[SPLPAR_TLB_BIC_MAXLENGTH - 1] = '\0'; + spin_unlock(&rtas_data_buf_lock); + } while (rtas_busy_delay(call_status)); if (call_status != 0) { pr_warn("%s %s Error calling get-system-parameter (0x%x)\n", @@ -1869,10 +1871,10 @@ * h_get_mpp * H_GET_MPP hcall returns info in 7 parms */ -int h_get_mpp(struct hvcall_mpp_data *mpp_data) +long h_get_mpp(struct hvcall_mpp_data *mpp_data) { - int rc; - unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + long rc; rc = plpar_hcall9(H_GET_MPP, retbuf); @@ -1992,7 +1994,7 @@ { char name[16]; long i; - static struct dentry *vpa_dir; + struct dentry *vpa_dir; if (!firmware_has_feature(FW_FEATURE_SPLPAR)) return 0; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/lparcfg.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/lparcfg.c @@ -112,8 +112,8 @@ */ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data) { - unsigned long rc; - unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + long rc; rc = plpar_hcall9(H_GET_PPP, retbuf); @@ -159,7 +159,7 @@ struct hvcall_ppp_data ppp_data; struct device_node *root; const __be32 *perf_level; - int rc; + long rc; rc = h_get_ppp(&ppp_data); if (rc) @@ -289,6 +289,7 @@ */ static void parse_system_parameter_string(struct seq_file *m) { + const s32 token = rtas_token("ibm,get-system-parameter"); int call_status; unsigned char *local_buffer = kmalloc(SPLPAR_MAXLENGTH, GFP_KERNEL); @@ -298,16 +299,15 @@ return; } - spin_lock(&rtas_data_buf_lock); - memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); - call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, - NULL, - SPLPAR_CHARACTERISTICS_TOKEN, - __pa(rtas_data_buf), - RTAS_DATA_BUF_SIZE); - memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); - local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; - spin_unlock(&rtas_data_buf_lock); + do { + spin_lock(&rtas_data_buf_lock); + memset(rtas_data_buf, 0, SPLPAR_MAXLENGTH); + call_status = rtas_call(token, 3, 1, NULL, SPLPAR_CHARACTERISTICS_TOKEN, + __pa(rtas_data_buf), RTAS_DATA_BUF_SIZE); + memcpy(local_buffer, rtas_data_buf, SPLPAR_MAXLENGTH); + local_buffer[SPLPAR_MAXLENGTH - 1] = '\0'; + spin_unlock(&rtas_data_buf_lock); + } while (rtas_busy_delay(call_status)); if (call_status != 0) { printk(KERN_INFO @@ -435,10 +435,10 @@ { unsigned long maxmem = 0; - maxmem += drmem_info->n_lmbs * drmem_info->lmb_size; + maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size; maxmem += hugetlb_total_pages() * PAGE_SIZE; - seq_printf(m, "MaxMem=%ld\n", maxmem); + seq_printf(m, "MaxMem=%lu\n", maxmem); } static int pseries_lparcfg_data(struct seq_file *m, void *v) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/msi.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/msi.c @@ -4,6 +4,7 @@ * Copyright 2006-2007 Michael Ellerman, IBM Corp. */ +#include #include #include #include @@ -458,7 +459,28 @@ return hwirq; } - virq = irq_create_mapping(NULL, hwirq); + /* + * Depending on the number of online CPUs in the original + * kernel, it is likely for CPU #0 to be offline in a kdump + * kernel. The associated IRQs in the affinity mappings + * provided by irq_create_affinity_masks() are thus not + * started by irq_startup(), as per-design for managed IRQs. + * This can be a problem with multi-queue block devices driven + * by blk-mq : such a non-started IRQ is very likely paired + * with the single queue enforced by blk-mq during kdump (see + * blk_mq_alloc_tag_set()). This causes the device to remain + * silent and likely hangs the guest at some point. + * + * We don't really care for fine-grained affinity when doing + * kdump actually : simply ignore the pre-computed affinity + * masks in this case and let the default mask with all CPUs + * be used when creating the IRQ mappings. + */ + if (is_kdump_kernel()) + virq = irq_create_mapping(NULL, hwirq); + else + virq = irq_create_mapping_affinity(NULL, hwirq, + entry->affinity); if (!virq) { pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/of_helpers.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/of_helpers.c @@ -45,14 +45,14 @@ int of_read_drc_info_cell(struct property **prop, const __be32 **curval, struct of_drc_info *data) { - const char *p; + const char *p = (char *)(*curval); const __be32 *p2; if (!data) return -EINVAL; /* Get drc-type:encode-string */ - p = data->drc_type = (char*) (*curval); + data->drc_type = (char *)p; p = of_prop_next_string(*prop, p); if (!p) return -EINVAL; @@ -65,9 +65,7 @@ /* Get drc-index-start:encode-int */ p2 = (const __be32 *)p; - p2 = of_prop_next_u32(*prop, p2, &data->drc_index_start); - if (!p2) - return -EINVAL; + data->drc_index_start = be32_to_cpu(*p2); /* Get drc-name-suffix-start:encode-int */ p2 = of_prop_next_u32(*prop, p2, &data->drc_name_suffix_start); @@ -90,7 +88,7 @@ return -EINVAL; /* Should now know end of current entry */ - (*curval) = (void *)p2; + (*curval) = (void *)(++p2); data->last_drc_index = data->drc_index_start + ((data->num_sequential_elems - 1) * data->sequential_inc); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/papr_scm.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/papr_scm.c @@ -152,7 +152,7 @@ int len, read; int64_t ret; - if ((hdr->in_offset + hdr->in_length) >= p->metadata_size) + if ((hdr->in_offset + hdr->in_length) > p->metadata_size) return -EINVAL; for (len = hdr->in_length; len; len -= read) { @@ -206,7 +206,7 @@ __be64 data_be; int64_t ret; - if ((hdr->in_offset + hdr->in_length) >= p->metadata_size) + if ((hdr->in_offset + hdr->in_length) > p->metadata_size) return -EINVAL; for (len = hdr->in_length; len; len -= wrote) { @@ -342,6 +342,7 @@ p->bus = nvdimm_bus_register(NULL, &p->bus_desc); if (!p->bus) { dev_err(dev, "Error creating nvdimm bus %pOF\n", p->dn); + kfree(p->bus_desc.provider_name); return -ENXIO; } @@ -498,6 +499,7 @@ nvdimm_bus_unregister(p->bus); drc_pmem_unbind(p); + kfree(p->bus_desc.provider_name); kfree(p); return 0; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/pci_dlpar.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -66,6 +66,7 @@ int remove_phb_dynamic(struct pci_controller *phb) { struct pci_bus *b = phb->bus; + struct pci_host_bridge *host_bridge = to_pci_host_bridge(b->bridge); struct resource *res; int rc, i; @@ -92,7 +93,8 @@ /* Remove the PCI bus and unregister the bridge device from sysfs */ phb->bus = NULL; pci_remove_bus(b); - device_unregister(b->bridge); + host_bridge->bus = NULL; + device_unregister(&host_bridge->dev); /* Now release the IO resource */ if (res->flags & IORESOURCE_IO) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/pseries.h +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/pseries.h @@ -114,4 +114,6 @@ void pseries_setup_rfi_flush(void); void pseries_lpar_read_hblkrm_characteristics(void); +void pseries_rng_init(void); + #endif /* _PSERIES_PSERIES_H */ --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/ras.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/ras.c @@ -184,7 +184,6 @@ case EPOW_SHUTDOWN_ON_UPS: pr_emerg("Loss of system power detected. System is running on" " UPS/battery. Check RTAS error log for details\n"); - orderly_poweroff(true); break; case EPOW_SHUTDOWN_LOSS_OF_CRITICAL_FUNCTIONS: @@ -395,10 +394,11 @@ /* * Some versions of FWNMI place the buffer inside the 4kB page starting at * 0x7000. Other versions place it inside the rtas buffer. We check both. + * Minimum size of the buffer is 16 bytes. */ #define VALID_FWNMI_BUFFER(A) \ - ((((A) >= 0x7000) && ((A) < 0x7ff0)) || \ - (((A) >= rtas.base) && ((A) < (rtas.base + rtas.size - 16)))) + ((((A) >= 0x7000) && ((A) <= 0x8000 - 16)) || \ + (((A) >= rtas.base) && ((A) <= (rtas.base + rtas.size - 16)))) static inline struct rtas_error_log *fwnmi_get_errlog(void) { @@ -494,18 +494,55 @@ return 0; /* need to perform reset */ } +static int mce_handle_err_realmode(int disposition, u8 error_type) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (disposition == RTAS_DISP_NOT_RECOVERED) { + switch (error_type) { + case MC_ERROR_TYPE_SLB: + case MC_ERROR_TYPE_ERAT: + /* + * Store the old slb content in paca before flushing. + * Print this when we go to virtual mode. + * There are chances that we may hit MCE again if there + * is a parity error on the SLB entry we trying to read + * for saving. Hence limit the slb saving to single + * level of recursion. + */ + if (local_paca->in_mce == 1) + slb_save_contents(local_paca->mce_faulty_slbs); + flush_and_reload_slb(); + disposition = RTAS_DISP_FULLY_RECOVERED; + break; + default: + break; + } + } else if (disposition == RTAS_DISP_LIMITED_RECOVERY) { + /* Platform corrected itself but could be degraded */ + pr_err("MCE: limited recovery, system may be degraded\n"); + disposition = RTAS_DISP_FULLY_RECOVERED; + } +#endif + return disposition; +} -static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) +static int mce_handle_err_virtmode(struct pt_regs *regs, + struct rtas_error_log *errp, + struct pseries_mc_errorlog *mce_log, + int disposition) { struct mce_error_info mce_err = { 0 }; - unsigned long eaddr = 0, paddr = 0; - struct pseries_errorlog *pseries_log; - struct pseries_mc_errorlog *mce_log; - int disposition = rtas_error_disposition(errp); int initiator = rtas_error_initiator(errp); int severity = rtas_error_severity(errp); + unsigned long eaddr = 0, paddr = 0; u8 error_type, err_sub_type; + if (!mce_log) + goto out; + + error_type = mce_log->error_type; + err_sub_type = rtas_mc_error_sub_type(mce_log); + if (initiator == RTAS_INITIATOR_UNKNOWN) mce_err.initiator = MCE_INITIATOR_UNKNOWN; else if (initiator == RTAS_INITIATOR_CPU) @@ -544,18 +581,7 @@ mce_err.error_type = MCE_ERROR_TYPE_UNKNOWN; mce_err.error_class = MCE_ECLASS_UNKNOWN; - if (!rtas_error_extended(errp)) - goto out; - - pseries_log = get_pseries_errorlog(errp, PSERIES_ELOG_SECT_ID_MCE); - if (pseries_log == NULL) - goto out; - - mce_log = (struct pseries_mc_errorlog *)pseries_log->data; - error_type = mce_log->error_type; - err_sub_type = rtas_mc_error_sub_type(mce_log); - - switch (mce_log->error_type) { + switch (error_type) { case MC_ERROR_TYPE_UE: mce_err.error_type = MCE_ERROR_TYPE_UE; switch (err_sub_type) { @@ -652,40 +678,45 @@ mce_err.error_type = MCE_ERROR_TYPE_UNKNOWN; break; } - -#ifdef CONFIG_PPC_BOOK3S_64 - if (disposition == RTAS_DISP_NOT_RECOVERED) { - switch (error_type) { - case MC_ERROR_TYPE_SLB: - case MC_ERROR_TYPE_ERAT: - /* - * Store the old slb content in paca before flushing. - * Print this when we go to virtual mode. - * There are chances that we may hit MCE again if there - * is a parity error on the SLB entry we trying to read - * for saving. Hence limit the slb saving to single - * level of recursion. - */ - if (local_paca->in_mce == 1) - slb_save_contents(local_paca->mce_faulty_slbs); - flush_and_reload_slb(); - disposition = RTAS_DISP_FULLY_RECOVERED; - break; - default: - break; - } - } else if (disposition == RTAS_DISP_LIMITED_RECOVERY) { - /* Platform corrected itself but could be degraded */ - printk(KERN_ERR "MCE: limited recovery, system may " - "be degraded\n"); - disposition = RTAS_DISP_FULLY_RECOVERED; - } -#endif - out: save_mce_event(regs, disposition == RTAS_DISP_FULLY_RECOVERED, - &mce_err, regs->nip, eaddr, paddr); + &mce_err, regs->nip, eaddr, paddr); + return disposition; +} + +static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp) +{ + struct pseries_errorlog *pseries_log; + struct pseries_mc_errorlog *mce_log = NULL; + int disposition = rtas_error_disposition(errp); + u8 error_type; + + if (!rtas_error_extended(errp)) + goto out; + + pseries_log = get_pseries_errorlog(errp, PSERIES_ELOG_SECT_ID_MCE); + if (!pseries_log) + goto out; + + mce_log = (struct pseries_mc_errorlog *)pseries_log->data; + error_type = mce_log->error_type; + + disposition = mce_handle_err_realmode(disposition, error_type); + /* + * Enable translation as we will be accessing per-cpu variables + * in save_mce_event() which may fall outside RMO region, also + * leave it enabled because subsequently we will be queuing work + * to workqueues where again per-cpu variables accessed, besides + * fwnmi_release_errinfo() crashes when called in realmode on + * pseries. + * Note: All the realmode handling like flushing SLB entries for + * SLB multihit is done by now. + */ +out: + mtmsr(mfmsr() | MSR_IR | MSR_DR); + disposition = mce_handle_err_virtmode(regs, errp, mce_log, + disposition); return disposition; } --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/rng.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/rng.c @@ -10,6 +10,7 @@ #include #include #include +#include "pseries.h" static int pseries_get_random_long(unsigned long *v) @@ -24,18 +25,13 @@ return 0; } -static __init int rng_init(void) +void __init pseries_rng_init(void) { struct device_node *dn; dn = of_find_compatible_node(NULL, NULL, "ibm,random"); if (!dn) - return -ENODEV; - - pr_info("Registering arch random hook.\n"); - + return; ppc_md.get_random_seed = pseries_get_random_long; - - return 0; + of_node_put(dn); } -machine_subsys_initcall(pseries, rng_init); --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/setup.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/setup.c @@ -74,6 +74,9 @@ #include "pseries.h" #include "../../../../drivers/pci/pci.h" +DEFINE_STATIC_KEY_FALSE(shared_processor); +EXPORT_SYMBOL(shared_processor); + int CMO_PrPSP = -1; int CMO_SecPSP = -1; unsigned long CMO_PageSize = (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K); @@ -302,8 +305,8 @@ { void (*ctor)(void *) = get_dtl_cache_ctor(); - dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES, - DISPATCH_LOG_BYTES, 0, ctor); + dtl_cache = kmem_cache_create_usercopy("dtl", DISPATCH_LOG_BYTES, + DISPATCH_LOG_BYTES, 0, 0, DISPATCH_LOG_BYTES, ctor); if (!dtl_cache) { pr_warn("Failed to create dispatch trace log buffer cache\n"); pr_warn("Stolen time statistics will be unreliable\n"); @@ -558,6 +561,14 @@ setup_rfi_flush(types, enable); setup_count_cache_flush(); + + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && + security_ftr_enabled(SEC_FTR_L1D_FLUSH_ENTRY); + setup_entry_flush(enable); + + enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) && + security_ftr_enabled(SEC_FTR_L1D_FLUSH_UACCESS); + setup_uaccess_flush(enable); } #ifdef CONFIG_PCI_IOV @@ -758,6 +769,10 @@ if (firmware_has_feature(FW_FEATURE_LPAR)) { vpa_init(boot_cpuid); + + if (lppaca_shared_proc(get_lppaca())) + static_branch_enable(&shared_processor); + ppc_md.power_save = pseries_lpar_idle; ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; #ifdef CONFIG_PCI_IOV @@ -777,6 +792,8 @@ if (swiotlb_force == SWIOTLB_FORCE) ppc_swiotlb_enable = 1; + + pseries_rng_init(); } static void pseries_panic(char *str) --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/suspend.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/suspend.c @@ -13,7 +13,6 @@ #include #include #include -#include "../../kernel/cacheinfo.h" static u64 stream_id; static struct device suspend_dev; @@ -78,9 +77,7 @@ * Update configuration which can be modified based on device tree * changes during resume. */ - cacheinfo_cpu_offline(smp_processor_id()); post_mobility_fixup(); - cacheinfo_cpu_online(smp_processor_id()); } /** @@ -132,15 +129,11 @@ struct device_attribute *attr, const char *buf, size_t count) { - cpumask_var_t offline_mask; int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (!alloc_cpumask_var(&offline_mask, GFP_KERNEL)) - return -ENOMEM; - stream_id = simple_strtoul(buf, NULL, 16); do { @@ -150,32 +143,16 @@ } while (rc == -EAGAIN); if (!rc) { - /* All present CPUs must be online */ - cpumask_andnot(offline_mask, cpu_present_mask, - cpu_online_mask); - rc = rtas_online_cpus_mask(offline_mask); - if (rc) { - pr_err("%s: Could not bring present CPUs online.\n", - __func__); - goto out; - } - stop_topology_update(); rc = pm_suspend(PM_SUSPEND_MEM); start_topology_update(); - - /* Take down CPUs not online prior to suspend */ - if (!rtas_offline_cpus_mask(offline_mask)) - pr_warn("%s: Could not restore CPUs to offline " - "state.\n", __func__); } stream_id = 0; if (!rc) rc = count; -out: - free_cpumask_var(offline_mask); + return rc; } @@ -210,7 +187,6 @@ static const struct platform_suspend_ops pseries_suspend_ops = { .valid = suspend_valid_only_mem, - .begin = pseries_suspend_begin, .prepare_late = pseries_prepare_late, .enter = pseries_suspend_enter, }; --- linux-oracle-5.4.0.orig/arch/powerpc/platforms/pseries/vio.c +++ linux-oracle-5.4.0/arch/powerpc/platforms/pseries/vio.c @@ -36,7 +36,6 @@ .name = "vio", .type = "", .dev.init_name = "vio", - .dev.bus = &vio_bus_type, }; #ifdef CONFIG_PPC_SMLPAR @@ -1176,6 +1175,8 @@ if (tbl == NULL) return NULL; + kref_init(&tbl->it_kref); + of_parse_dma_window(dev->dev.of_node, dma_window, &tbl->it_index, &offset, &size); --- linux-oracle-5.4.0.orig/arch/powerpc/purgatory/Makefile +++ linux-oracle-5.4.0/arch/powerpc/purgatory/Makefile @@ -4,6 +4,11 @@ targets += trampoline.o purgatory.ro kexec-purgatory.c +# When profile-guided optimization is enabled, llvm emits two different +# overlapping text sections, which is not supported by kexec. Remove profile +# optimization flags. +KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS)) + LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined $(obj)/purgatory.ro: $(obj)/trampoline.o FORCE --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/dart_iommu.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/dart_iommu.c @@ -403,9 +403,10 @@ } /* Initialize the DART HW */ - if (dart_init(dn) != 0) + if (dart_init(dn) != 0) { + of_node_put(dn); return; - + } /* * U4 supports a DART bypass, we use it for 64-bit capable devices to * improve performance. However, that only works for devices connected @@ -418,6 +419,7 @@ /* Setup pci_dma ops */ set_pci_dma_ops(&dma_iommu_ops); + of_node_put(dn); } #ifdef CONFIG_PM --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/dcr-low.S +++ linux-oracle-5.4.0/arch/powerpc/sysdev/dcr-low.S @@ -11,7 +11,7 @@ #include #define DCR_ACCESS_PROLOG(table) \ - cmpli cr0,r3,1024; \ + cmplwi cr0,r3,1024; \ rlwinm r3,r3,4,18,27; \ lis r5,table@h; \ ori r5,r5,table@l; \ --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/fsl_gtm.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/fsl_gtm.c @@ -86,7 +86,7 @@ */ struct gtm_timer *gtm_get_timer16(void) { - struct gtm *gtm = NULL; + struct gtm *gtm; int i; list_for_each_entry(gtm, >ms, list_node) { @@ -103,7 +103,7 @@ spin_unlock_irq(>m->lock); } - if (gtm) + if (!list_empty(>ms)) return ERR_PTR(-EBUSY); return ERR_PTR(-ENODEV); } --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/fsl_msi.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/fsl_msi.c @@ -211,8 +211,10 @@ dev_err(&pdev->dev, "node %pOF has an invalid fsl,msi phandle %u\n", hose->dn, np->phandle); + of_node_put(np); return -EINVAL; } + of_node_put(np); } for_each_pci_msi_entry(entry, pdev) { @@ -571,10 +573,12 @@ .msiir_offset = 0x38, }; +#ifdef CONFIG_EPAPR_PARAVIRT static const struct fsl_msi_feature vmpic_msi_feature = { .fsl_pic_ip = FSL_PIC_IP_VMPIC, .msiir_offset = 0, }; +#endif static const struct of_device_id fsl_of_msi_ids[] = { { --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/fsl_pci.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/fsl_pci.c @@ -520,6 +520,7 @@ struct resource rsrc; const int *bus_range; u8 hdr_type, progif; + u32 class_code; struct device_node *dev; struct ccsr_pci __iomem *pci; u16 temp; @@ -593,6 +594,13 @@ PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS; if (fsl_pcie_check_link(hose)) hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; + /* Fix Class Code to PCI_CLASS_BRIDGE_PCI_NORMAL for pre-3.0 controller */ + if (in_be32(&pci->block_rev1) < PCIE_IP_REV_3_0) { + early_read_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, &class_code); + class_code &= 0xff; + class_code |= PCI_CLASS_BRIDGE_PCI_NORMAL << 8; + early_write_config_dword(hose, 0, 0, PCIE_FSL_CSR_CLASSCODE, class_code); + } } else { /* * Set PBFR(PCI Bus Function Register)[10] = 1 to --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/fsl_pci.h +++ linux-oracle-5.4.0/arch/powerpc/sysdev/fsl_pci.h @@ -18,6 +18,7 @@ #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ #define PCIE_LTSSM_L0 0x16 /* L0 state */ +#define PCIE_FSL_CSR_CLASSCODE 0x474 /* FSL GPEX CSR */ #define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ #define PCIE_IP_REV_3_0 0x02080300 /* PCIE IP block version Rev3.0 */ #define PIWAR_EN 0x80000000 /* Enable */ --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/fsl_rio.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/fsl_rio.c @@ -505,8 +505,10 @@ if (rc) { dev_err(&dev->dev, "Can't get %pOF property 'reg'\n", rmu_node); + of_node_put(rmu_node); goto err_rmu; } + of_node_put(rmu_node); rmu_regs_win = ioremap(rmu_regs.start, resource_size(&rmu_regs)); if (!rmu_regs_win) { dev_err(&dev->dev, "Unable to map rmu register window\n"); --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/mpic_msgr.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/mpic_msgr.c @@ -191,7 +191,7 @@ /* IO map the message register block. */ of_address_to_resource(np, 0, &rsrc); - msgr_block_addr = ioremap(rsrc.start, resource_size(&rsrc)); + msgr_block_addr = devm_ioremap(&dev->dev, rsrc.start, resource_size(&rsrc)); if (!msgr_block_addr) { dev_err(&dev->dev, "Failed to iomap MPIC message registers"); return -EFAULT; --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/tsi108_pci.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/tsi108_pci.c @@ -216,9 +216,8 @@ (hose)->ops = &tsi108_direct_pci_ops; - printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " - "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + pr_info("Found tsi108 PCI host bridge at 0x%pa. Firmware bus number: %d->%d\n", + &rsrc.start, hose->first_busno, hose->last_busno); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xics/icp-hv.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xics/icp-hv.c @@ -174,6 +174,7 @@ icp_ops = &icp_hv_ops; + of_node_put(np); return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xics/icp-native.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xics/icp-native.c @@ -235,6 +235,8 @@ rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation", cpu, hw_id); + if (!rname) + return -ENOMEM; if (!request_mem_region(addr, size, rname)) { pr_warn("icp_native: Could not reserve ICP MMIO for CPU %d, interrupt server #0x%x\n", cpu, hw_id); --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xics/icp-opal.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xics/icp-opal.c @@ -195,6 +195,7 @@ printk("XICS: Using OPAL ICP fallbacks\n"); + of_node_put(np); return 0; } --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xive/common.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xive/common.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -68,13 +69,6 @@ /* Xive state for each CPU */ static DEFINE_PER_CPU(struct xive_cpu *, xive_cpu); -/* - * A "disabled" interrupt should never fire, to catch problems - * we set its logical number to this - */ -#define XIVE_BAD_IRQ 0x7fffffff -#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) - /* An invalid CPU target */ #define XIVE_INVALID_TARGET (-1) @@ -263,6 +257,13 @@ xmon_printf("\n"); } +static struct irq_data *xive_get_irq_data(u32 hw_irq) +{ + unsigned int irq = irq_find_mapping(xive_irq_domain, hw_irq); + + return irq ? irq_get_irq_data(irq) : NULL; +} + int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d) { int rc; @@ -279,6 +280,9 @@ xmon_printf("IRQ 0x%08x : target=0x%x prio=%02x lirq=0x%x ", hw_irq, target, prio, lirq); + if (!d) + d = xive_get_irq_data(hw_irq); + if (d) { struct xive_irq_data *xd = irq_data_get_irq_handler_data(d); u64 val = xive_esb_read(xd, XIVE_ESB_GET); @@ -972,12 +976,22 @@ enum irqchip_irq_state which, bool *state) { struct xive_irq_data *xd = irq_data_get_irq_handler_data(data); + u8 pq; switch (which) { case IRQCHIP_STATE_ACTIVE: - *state = !xd->stale_p && - (xd->saved_p || - !!(xive_esb_read(xd, XIVE_ESB_GET) & XIVE_ESB_VAL_P)); + pq = xive_esb_read(xd, XIVE_ESB_GET); + + /* + * The esb value being all 1's means we couldn't get + * the PQ state of the interrupt through mmio. It may + * happen, for example when querying a PHB interrupt + * while the PHB is in an error state. We consider the + * interrupt to be inactive in that case. + */ + *state = (pq != XIVE_ESB_INVALID) && !xd->stale_p && + (xd->saved_p || (!!(pq & XIVE_ESB_VAL_P) && + !irqd_irq_disabled(data))); return 0; default: return -EINVAL; @@ -1007,12 +1021,16 @@ void xive_cleanup_irq_data(struct xive_irq_data *xd) { if (xd->eoi_mmio) { + unmap_kernel_range((unsigned long)xd->eoi_mmio, + 1u << xd->esb_shift); iounmap(xd->eoi_mmio); if (xd->eoi_mmio == xd->trig_mmio) xd->trig_mmio = NULL; xd->eoi_mmio = NULL; } if (xd->trig_mmio) { + unmap_kernel_range((unsigned long)xd->trig_mmio, + 1u << xd->esb_shift); iounmap(xd->trig_mmio); xd->trig_mmio = NULL; } @@ -1035,6 +1053,15 @@ xd->target = XIVE_INVALID_TARGET; irq_set_handler_data(virq, xd); + /* + * Turn OFF by default the interrupt being mapped. A side + * effect of this check is the mapping the ESB page of the + * interrupt in the Linux address space. This prevents page + * fault issues in the crash handler which masks all + * interrupts. + */ + xive_esb_read(xd, XIVE_ESB_SET_PQ_01); + return 0; } @@ -1132,7 +1159,7 @@ xc = per_cpu(xive_cpu, cpu); /* Check if we are already setup */ - if (xc->hw_ipi != 0) + if (xc->hw_ipi != XIVE_BAD_IRQ) return 0; /* Grab an IPI from the backend, this will populate xc->hw_ipi */ @@ -1169,7 +1196,7 @@ /* Disable the IPI and free the IRQ data */ /* Already cleaned up ? */ - if (xc->hw_ipi == 0) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; /* Mask the IPI */ @@ -1325,6 +1352,7 @@ if (np) xc->chip_id = of_get_ibm_chip_id(np); of_node_put(np); + xc->hw_ipi = XIVE_BAD_IRQ; per_cpu(xive_cpu, cpu) = xc; } --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xive/native.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xive/native.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -312,7 +313,7 @@ s64 rc; /* Free the IPI */ - if (!xc->hw_ipi) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; for (;;) { rc = opal_xive_free_irq(xc->hw_ipi); @@ -320,7 +321,7 @@ msleep(OPAL_BUSY_DELAY_MS); continue; } - xc->hw_ipi = 0; + xc->hw_ipi = XIVE_BAD_IRQ; break; } } @@ -646,6 +647,7 @@ pr_err("Failed to allocate provisioning page\n"); return false; } + kmemleak_ignore(p); opal_xive_donate_page(chip, __pa(p)); } return true; @@ -776,7 +778,7 @@ if (out_qpage) *out_qpage = be64_to_cpu(qpage); if (out_qsize) - *out_qsize = be32_to_cpu(qsize); + *out_qsize = be64_to_cpu(qsize); if (out_qeoi_page) *out_qeoi_page = be64_to_cpu(qeoi_page); if (out_escalate_irq) --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xive/spapr.c +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xive/spapr.c @@ -392,20 +392,28 @@ data->esb_shift = esb_shift; data->trig_page = trig_page; + data->hw_irq = hw_irq; + /* * No chip-id for the sPAPR backend. This has an impact how we * pick a target. See xive_pick_irq_target(). */ data->src_chip = XIVE_INVALID_CHIP_ID; + /* + * When the H_INT_ESB flag is set, the H_INT_ESB hcall should + * be used for interrupt management. Skip the remapping of the + * ESB pages which are not available. + */ + if (data->flags & XIVE_IRQ_FLAG_H_INT_ESB) + return 0; + data->eoi_mmio = ioremap(data->eoi_page, 1u << data->esb_shift); if (!data->eoi_mmio) { pr_err("Failed to map EOI page for irq 0x%x\n", hw_irq); return -ENOMEM; } - data->hw_irq = hw_irq; - /* Full function page supports trigger */ if (flags & XIVE_SRC_TRIGGER) { data->trig_mmio = data->eoi_mmio; @@ -414,6 +422,7 @@ data->trig_mmio = ioremap(data->trig_page, 1u << data->esb_shift); if (!data->trig_mmio) { + iounmap(data->eoi_mmio); pr_err("Failed to map trigger page for irq 0x%x\n", hw_irq); return -ENOMEM; } @@ -552,11 +561,11 @@ static void xive_spapr_put_ipi(unsigned int cpu, struct xive_cpu *xc) { - if (!xc->hw_ipi) + if (xc->hw_ipi == XIVE_BAD_IRQ) return; xive_irq_bitmap_free(xc->hw_ipi); - xc->hw_ipi = 0; + xc->hw_ipi = XIVE_BAD_IRQ; } #endif /* CONFIG_SMP */ @@ -675,6 +684,7 @@ } reg = of_get_property(rootdn, "ibm,plat-res-int-priorities", &len); + of_node_put(rootdn); if (!reg) { pr_err("Failed to read 'ibm,plat-res-int-priorities' property\n"); return false; --- linux-oracle-5.4.0.orig/arch/powerpc/sysdev/xive/xive-internal.h +++ linux-oracle-5.4.0/arch/powerpc/sysdev/xive/xive-internal.h @@ -5,6 +5,13 @@ #ifndef __XIVE_INTERNAL_H #define __XIVE_INTERNAL_H +/* + * A "disabled" interrupt should never fire, to catch problems + * we set its logical number to this + */ +#define XIVE_BAD_IRQ 0x7fffffff +#define XIVE_MAX_IRQ (XIVE_BAD_IRQ - 1) + /* Each CPU carry one of these with various per-CPU state */ struct xive_cpu { #ifdef CONFIG_SMP --- linux-oracle-5.4.0.orig/arch/powerpc/tools/relocs_check.sh +++ linux-oracle-5.4.0/arch/powerpc/tools/relocs_check.sh @@ -10,24 +10,29 @@ # based on relocs_check.pl # Copyright © 2009 IBM Corporation -if [ $# -lt 2 ]; then - echo "$0 [path to objdump] [path to vmlinux]" 1>&2 +if [ $# -lt 3 ]; then + echo "$0 [path to objdump] [path to nm] [path to vmlinux]" 1>&2 exit 1 fi -# Have Kbuild supply the path to objdump so we handle cross compilation. +# Have Kbuild supply the path to objdump and nm so we handle cross compilation. objdump="$1" -vmlinux="$2" +nm="$2" +vmlinux="$3" + +# Remove from the bad relocations those that match an undefined weak symbol +# which will result in an absolute relocation to 0. +# Weak unresolved symbols are of that form in nm output: +# " w _binary__btf_vmlinux_bin_end" +undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }') bad_relocs=$( -"$objdump" -R "$vmlinux" | +$objdump -R "$vmlinux" | # Only look at relocation lines. grep -E '\ - # R_PPC64_ADDR64 __crc_ # On PPC: # R_PPC_RELATIVE, R_PPC_ADDR16_HI, # R_PPC_ADDR16_HA,R_PPC_ADDR16_LO, @@ -39,8 +44,7 @@ R_PPC_ADDR16_HA R_PPC_RELATIVE R_PPC_NONE' | - grep -E -v '\:' | awk '{print $1}' ) BRANCHES=$( -"$objdump" -R "$vmlinux" -D --start-address=0xc000000000000000 \ +$objdump -R "$vmlinux" -D --start-address=0xc000000000000000 \ --stop-address=${end_intr} | grep -e "^c[0-9a-f]*:[[:space:]]*\([0-9a-f][0-9a-f][[:space:]]\)\{4\}[[:space:]]*b" | grep -v '\<__start_initialization_multiplatform>' | --- linux-oracle-5.4.0.orig/arch/powerpc/xmon/Makefile +++ linux-oracle-5.4.0/arch/powerpc/xmon/Makefile @@ -1,9 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # Makefile for xmon -# Disable clang warning for using setjmp without setjmp.h header -subdir-ccflags-y := $(call cc-disable-warning, builtin-requires-header) - GCOV_PROFILE := n KCOV_INSTRUMENT := n UBSAN_SANITIZE := n --- linux-oracle-5.4.0.orig/arch/powerpc/xmon/nonstdio.c +++ linux-oracle-5.4.0/arch/powerpc/xmon/nonstdio.c @@ -178,7 +178,7 @@ if (n && rc == 0) { /* No udbg hooks, fallback to printk() - dangerous */ - printk("%s", xmon_outbuf); + pr_cont("%s", xmon_outbuf); } } --- linux-oracle-5.4.0.orig/arch/powerpc/xmon/ppc-dis.c +++ linux-oracle-5.4.0/arch/powerpc/xmon/ppc-dis.c @@ -122,32 +122,21 @@ bool insn_is_short; ppc_cpu_t dialect; - dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON - | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; + dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON; - if (cpu_has_feature(CPU_FTRS_POWER5)) - dialect |= PPC_OPCODE_POWER5; + if (IS_ENABLED(CONFIG_PPC64)) + dialect |= PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | + PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | + PPC_OPCODE_POWER9; - if (cpu_has_feature(CPU_FTRS_CELL)) - dialect |= (PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC); + if (cpu_has_feature(CPU_FTR_TM)) + dialect |= PPC_OPCODE_HTM; - if (cpu_has_feature(CPU_FTRS_POWER6)) - dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC); - - if (cpu_has_feature(CPU_FTRS_POWER7)) - dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 - | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX); - - if (cpu_has_feature(CPU_FTRS_POWER8)) - dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 - | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM - | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX); - - if (cpu_has_feature(CPU_FTRS_POWER9)) - dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 - | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM - | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 - | PPC_OPCODE_VSX | PPC_OPCODE_VSX3); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + dialect |= PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2; + + if (cpu_has_feature(CPU_FTR_VSX)) + dialect |= PPC_OPCODE_VSX | PPC_OPCODE_VSX3; /* Get the major opcode of the insn. */ opcode = NULL; --- linux-oracle-5.4.0.orig/arch/powerpc/xmon/xmon.c +++ linux-oracle-5.4.0/arch/powerpc/xmon/xmon.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -187,6 +188,8 @@ static void dump_tlb_book3e(void); #endif +static void clear_all_bpt(void); + #ifdef CONFIG_PPC64 #define REG "%.16lx" #else @@ -283,10 +286,38 @@ " U show uptime information\n" " ? help\n" " # n limit output to n lines per page (for dp, dpa, dl)\n" -" zr reboot\n\ - zh halt\n" +" zr reboot\n" +" zh halt\n" ; +#ifdef CONFIG_SECURITY +static bool xmon_is_locked_down(void) +{ + static bool lockdown; + + if (!lockdown) { + lockdown = !!security_locked_down(LOCKDOWN_XMON_RW); + if (lockdown) { + printf("xmon: Disabled due to kernel lockdown\n"); + xmon_is_ro = true; + } + } + + if (!xmon_is_ro) { + xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR); + if (xmon_is_ro) + printf("xmon: Read-only due to kernel lockdown\n"); + } + + return lockdown; +} +#else /* CONFIG_SECURITY */ +static inline bool xmon_is_locked_down(void) +{ + return false; +} +#endif + static struct pt_regs *xmon_regs; static inline void sync(void) @@ -438,7 +469,10 @@ return false; } -#endif /* CONFIG_SMP */ +#else /* CONFIG_SMP */ +static inline void get_output_lock(void) {} +static inline void release_output_lock(void) {} +#endif static inline int unrecoverable_excp(struct pt_regs *regs) { @@ -455,6 +489,7 @@ int cmd = 0; struct bpt *bp; long recurse_jmp[JMP_BUF_LEN]; + bool locked_down; unsigned long offset; unsigned long flags; #ifdef CONFIG_SMP @@ -465,6 +500,8 @@ local_irq_save(flags); hard_irq_disable(); + locked_down = xmon_is_locked_down(); + if (!fromipi) { tracing_enabled = tracing_is_on(); tracing_off(); @@ -518,7 +555,8 @@ if (!fromipi) { get_output_lock(); - excprint(regs); + if (!locked_down) + excprint(regs); if (bp) { printf("cpu 0x%x stopped at breakpoint 0x%tx (", cpu, BP_NUM(bp)); @@ -570,10 +608,14 @@ } remove_bpts(); disable_surveillance(); - /* for breakpoint or single step, print the current instr. */ - if (bp || TRAP(regs) == 0xd00) - ppc_inst_dump(regs->nip, 1, 0); - printf("enter ? for help\n"); + + if (!locked_down) { + /* for breakpoint or single step, print curr insn */ + if (bp || TRAP(regs) == 0xd00) + ppc_inst_dump(regs->nip, 1, 0); + printf("enter ? for help\n"); + } + mb(); xmon_gate = 1; barrier(); @@ -597,8 +639,9 @@ spin_cpu_relax(); touch_nmi_watchdog(); } else { - cmd = cmds(regs); - if (cmd != 0) { + if (!locked_down) + cmd = cmds(regs); + if (locked_down || cmd != 0) { /* exiting xmon */ insert_bpts(); xmon_gate = 0; @@ -635,13 +678,16 @@ "can't continue\n"); remove_bpts(); disable_surveillance(); - /* for breakpoint or single step, print the current instr. */ - if (bp || TRAP(regs) == 0xd00) - ppc_inst_dump(regs->nip, 1, 0); - printf("enter ? for help\n"); + if (!locked_down) { + /* for breakpoint or single step, print current insn */ + if (bp || TRAP(regs) == 0xd00) + ppc_inst_dump(regs->nip, 1, 0); + printf("enter ? for help\n"); + } } - cmd = cmds(regs); + if (!locked_down) + cmd = cmds(regs); insert_bpts(); in_xmon = 0; @@ -670,7 +716,10 @@ } } #endif - insert_cpu_bpts(); + if (locked_down) + clear_all_bpt(); + else + insert_cpu_bpts(); touch_nmi_watchdog(); local_irq_restore(flags); @@ -1165,7 +1214,7 @@ unsigned long cpu, first_cpu, last_cpu; int timeout; - if (!scanhex(&cpu)) { + if (!scanhex(&cpu) || cpu >= num_possible_cpus()) { /* print cpus waiting or in xmon */ printf("cpus stopped:"); last_cpu = first_cpu = NR_CPUS; @@ -1894,15 +1943,14 @@ printf("pidr = %.16lx tidr = %.16lx\n", mfspr(SPRN_PID), mfspr(SPRN_TIDR)); - printf("asdr = %.16lx psscr = %.16lx\n", - mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR) - : mfspr(SPRN_PSSCR_PR)); + printf("psscr = %.16lx\n", + hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR)); if (!hv) return; - printf("ptcr = %.16lx\n", - mfspr(SPRN_PTCR)); + printf("ptcr = %.16lx asdr = %.16lx\n", + mfspr(SPRN_PTCR), mfspr(SPRN_ASDR)); #endif } @@ -2523,7 +2571,7 @@ termch = c; /* Put c back, it wasn't 'a' */ - if (scanhex(&num)) + if (scanhex(&num) && num < num_possible_cpus()) dump_one_paca(num); else dump_one_paca(xmon_owner); @@ -2620,7 +2668,7 @@ termch = c; /* Put c back, it wasn't 'a' */ - if (scanhex(&num)) + if (scanhex(&num) && num < num_possible_cpus()) dump_one_xive(num); else dump_one_xive(xmon_owner); @@ -3762,6 +3810,11 @@ #ifdef CONFIG_MAGIC_SYSRQ static void sysrq_handle_xmon(int key) { + if (xmon_is_locked_down()) { + clear_all_bpt(); + xmon_init(0); + return; + } /* ensure xmon is enabled */ xmon_init(1); debugger(get_irq_regs()); @@ -3783,7 +3836,6 @@ device_initcall(setup_xmon_sysrq); #endif /* CONFIG_MAGIC_SYSRQ */ -#ifdef CONFIG_DEBUG_FS static void clear_all_bpt(void) { int i; @@ -3801,18 +3853,22 @@ iabr = NULL; dabr.enabled = 0; } - - printf("xmon: All breakpoints cleared\n"); } +#ifdef CONFIG_DEBUG_FS static int xmon_dbgfs_set(void *data, u64 val) { xmon_on = !!val; xmon_init(xmon_on); /* make sure all breakpoints removed when disabling */ - if (!xmon_on) + if (!xmon_on) { clear_all_bpt(); + get_output_lock(); + printf("xmon: All breakpoints cleared\n"); + release_output_lock(); + } + return 0; } @@ -3838,7 +3894,11 @@ static int __init early_parse_xmon(char *p) { - if (!p || strncmp(p, "early", 5) == 0) { + if (xmon_is_locked_down()) { + xmon_init(0); + xmon_early = 0; + xmon_on = 0; + } else if (!p || strncmp(p, "early", 5) == 0) { /* just "xmon" is equivalent to "xmon=early" */ xmon_init(1); xmon_early = 1; --- linux-oracle-5.4.0.orig/arch/riscv/Kconfig +++ linux-oracle-5.4.0/arch/riscv/Kconfig @@ -31,8 +31,8 @@ select GENERIC_SMP_IDLE_THREAD select GENERIC_ATOMIC64 if !64BIT select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_SECCOMP_FILTER select HAVE_ASM_MODVERSIONS - select HAVE_MEMBLOCK_NODE_MAP select HAVE_DMA_CONTIGUOUS select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_PERF_EVENTS @@ -51,16 +51,16 @@ select PCI_MSI if PCI select RISCV_TIMER select GENERIC_IRQ_MULTI_HANDLER - select GENERIC_ARCH_TOPOLOGY if SMP + select GENERIC_ARCH_TOPOLOGY select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MMIOWB select HAVE_EBPF_JIT if 64BIT select EDAC_SUPPORT select ARCH_HAS_GIGANTIC_PAGE select ARCH_WANT_HUGE_PMD_SHARE if 64BIT - select SPARSEMEM_STATIC if 32BIT select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU select HAVE_ARCH_MMAP_RND_BITS + select HAVE_COPY_THREAD_TLS config ARCH_MMAP_RND_BITS_MIN default 18 if 64BIT @@ -100,7 +100,9 @@ config ARCH_SPARSEMEM_ENABLE def_bool y - select SPARSEMEM_VMEMMAP_ENABLE + depends on MMU + select SPARSEMEM_STATIC if 32BIT && SPARSEMEM + select SPARSEMEM_VMEMMAP_ENABLE if 64BIT config ARCH_SELECT_MEMORY_MODEL def_bool ARCH_SPARSEMEM_ENABLE @@ -137,6 +139,11 @@ config FIX_EARLYCON_MEM def_bool y +config ILLEGAL_POINTER_VALUE + hex + default 0 if 32BIT + default 0xdead000000000000 if 64BIT + config PGTABLE_LEVELS int default 3 if 64BIT @@ -272,6 +279,19 @@ source "kernel/Kconfig.hz" +config SECCOMP + bool "Enable seccomp to safely compute untrusted bytecode" + help + This kernel feature is useful for number crunching applications + that may need to compute untrusted bytecode during their + execution. By using pipes or other transports made available to + the process as file descriptors supporting the read/write + syscalls, it's possible to isolate those applications in + their own address space using seccomp. Once seccomp is + enabled via prctl(PR_SET_SECCOMP), it cannot be disabled + and the task is only allowed to execute a few safe syscalls + defined by each seccomp mode. + endmenu menu "Boot options" --- linux-oracle-5.4.0.orig/arch/riscv/Makefile +++ linux-oracle-5.4.0/arch/riscv/Makefile @@ -34,11 +34,28 @@ KBUILD_LDFLAGS += -melf32lriscv endif +ifeq ($(CONFIG_LD_IS_LLD),y) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 150000; echo $$?),0) + KBUILD_CFLAGS += -mno-relax + KBUILD_AFLAGS += -mno-relax +ifneq ($(LLVM_IAS),1) + KBUILD_CFLAGS += -Wa,-mno-relax + KBUILD_AFLAGS += -Wa,-mno-relax +endif +endif +endif + # ISA string setting riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c + +# Newer binutils versions default to ISA spec version 20191213 which moves some +# instructions from the I extension to the Zicsr and Zifencei extensions. +toolchain-need-zicsr-zifencei := $(call cc-option-yn, -march=$(riscv-march-y)_zicsr_zifencei) +riscv-march-$(toolchain-need-zicsr-zifencei) := $(riscv-march-y)_zicsr_zifencei + KBUILD_CFLAGS += -march=$(subst fd,,$(riscv-march-y)) KBUILD_AFLAGS += -march=$(riscv-march-y) @@ -58,7 +75,11 @@ KBUILD_CFLAGS += -fno-omit-frame-pointer endif +# Avoid generating .eh_frame sections. +KBUILD_CFLAGS += -fno-asynchronous-unwind-tables -fno-unwind-tables + KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax) +KBUILD_AFLAGS_MODULE += $(call as-option,-Wa$(comma)-mno-relax) # GCC versions that support the "-mstrict-align" option default to allowing # unaligned accesses. While unaligned accesses are explicitly allowed in the --- linux-oracle-5.4.0.orig/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts +++ linux-oracle-5.4.0/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts @@ -83,6 +83,7 @@ phy-mode = "gmii"; phy-handle = <&phy0>; phy0: ethernet-phy@0 { + compatible = "ethernet-phy-id0007.0771"; reg = <0>; }; }; --- linux-oracle-5.4.0.orig/arch/riscv/configs/defconfig +++ linux-oracle-5.4.0/arch/riscv/configs/defconfig @@ -62,6 +62,8 @@ CONFIG_HW_RANDOM_VIRTIO=y CONFIG_SPI=y CONFIG_SPI_SIFIVE=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SIFIVE=y # CONFIG_PTP_1588_CLOCK is not set CONFIG_DRM=y CONFIG_DRM_RADEON=y --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/asm-prototypes.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/asm-prototypes.h @@ -4,4 +4,8 @@ #include #include +long long __lshrti3(long long a, int b); +long long __ashrti3(long long a, int b); +long long __ashlti3(long long a, int b); + #endif /* _ASM_RISCV_PROTOTYPES_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/barrier.h @@ -58,8 +58,16 @@ * The AQ/RL pair provides a RCpc critical section, but there's not really any * way we can take advantage of that here because the ordering is only enforced * on that one lock. Thus, we're just doing a full fence. + * + * Since we allow writeX to be called from preemptive regions we need at least + * an "o" in the predecessor set to ensure device writes are visible before the + * task is marked as available for scheduling on a new hart. While I don't see + * any concrete reason we need a full IO fence, it seems safer to just upgrade + * this in order to avoid any IO crossing a scheduling boundary. In both + * instances the scheduler pairs this with an mb(), so nothing is necessary on + * the new hart. */ -#define smp_mb__after_spinlock() RISCV_FENCE(rw,rw) +#define smp_mb__after_spinlock() RISCV_FENCE(iorw,iorw) #include --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/cmpxchg.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/cmpxchg.h @@ -179,7 +179,7 @@ " bnez %1, 0b\n" \ "1:\n" \ : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ - : "rJ" (__old), "rJ" (__new) \ + : "rJ" ((long)__old), "rJ" (__new) \ : "memory"); \ break; \ case 8: \ @@ -224,7 +224,7 @@ RISCV_ACQUIRE_BARRIER \ "1:\n" \ : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ - : "rJ" (__old), "rJ" (__new) \ + : "rJ" ((long)__old), "rJ" (__new) \ : "memory"); \ break; \ case 8: \ @@ -270,7 +270,7 @@ " bnez %1, 0b\n" \ "1:\n" \ : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ - : "rJ" (__old), "rJ" (__new) \ + : "rJ" ((long)__old), "rJ" (__new) \ : "memory"); \ break; \ case 8: \ @@ -316,7 +316,7 @@ " fence rw, rw\n" \ "1:\n" \ : "=&r" (__ret), "=&r" (__rc), "+A" (*__ptr) \ - : "rJ" (__old), "rJ" (__new) \ + : "rJ" ((long)__old), "rJ" (__new) \ : "memory"); \ break; \ case 8: \ --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/ftrace.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/ftrace.h @@ -10,9 +10,19 @@ #endif #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +/* + * Clang prior to 13 had "mcount" instead of "_mcount": + * https://reviews.llvm.org/D98881 + */ +#if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000 +#define MCOUNT_NAME _mcount +#else +#define MCOUNT_NAME mcount +#endif + #define ARCH_SUPPORTS_FTRACE_OPS 1 #ifndef __ASSEMBLY__ -void _mcount(void); +void MCOUNT_NAME(void); static inline unsigned long ftrace_call_adjust(unsigned long addr) { return addr; @@ -33,7 +43,7 @@ * both auipc and jalr at the same time. */ -#define MCOUNT_ADDR ((unsigned long)_mcount) +#define MCOUNT_ADDR ((unsigned long)MCOUNT_NAME) #define JALR_SIGN_MASK (0x00000800) #define JALR_OFFSET_MASK (0x00000fff) #define AUIPC_OFFSET_MASK (0xfffff000) @@ -63,4 +73,11 @@ * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here. */ #define MCOUNT_INSN_SIZE 8 + +#ifndef __ASSEMBLY__ +struct dyn_ftrace; +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); +#define ftrace_init_nop ftrace_init_nop +#endif + #endif --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/io.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/io.h @@ -252,9 +252,9 @@ __io_reads_ins(ins, u8, b, __io_pbr(), __io_par(addr)) __io_reads_ins(ins, u16, w, __io_pbr(), __io_par(addr)) __io_reads_ins(ins, u32, l, __io_pbr(), __io_par(addr)) -#define insb(addr, buffer, count) __insb((void __iomem *)(long)addr, buffer, count) -#define insw(addr, buffer, count) __insw((void __iomem *)(long)addr, buffer, count) -#define insl(addr, buffer, count) __insl((void __iomem *)(long)addr, buffer, count) +#define insb(addr, buffer, count) __insb(PCI_IOBASE + (addr), buffer, count) +#define insw(addr, buffer, count) __insw(PCI_IOBASE + (addr), buffer, count) +#define insl(addr, buffer, count) __insl(PCI_IOBASE + (addr), buffer, count) __io_writes_outs(writes, u8, b, __io_bw(), __io_aw()) __io_writes_outs(writes, u16, w, __io_bw(), __io_aw()) @@ -266,22 +266,22 @@ __io_writes_outs(outs, u8, b, __io_pbw(), __io_paw()) __io_writes_outs(outs, u16, w, __io_pbw(), __io_paw()) __io_writes_outs(outs, u32, l, __io_pbw(), __io_paw()) -#define outsb(addr, buffer, count) __outsb((void __iomem *)(long)addr, buffer, count) -#define outsw(addr, buffer, count) __outsw((void __iomem *)(long)addr, buffer, count) -#define outsl(addr, buffer, count) __outsl((void __iomem *)(long)addr, buffer, count) +#define outsb(addr, buffer, count) __outsb(PCI_IOBASE + (addr), buffer, count) +#define outsw(addr, buffer, count) __outsw(PCI_IOBASE + (addr), buffer, count) +#define outsl(addr, buffer, count) __outsl(PCI_IOBASE + (addr), buffer, count) #ifdef CONFIG_64BIT __io_reads_ins(reads, u64, q, __io_br(), __io_ar(addr)) #define readsq(addr, buffer, count) __readsq(addr, buffer, count) __io_reads_ins(ins, u64, q, __io_pbr(), __io_par(addr)) -#define insq(addr, buffer, count) __insq((void __iomem *)addr, buffer, count) +#define insq(addr, buffer, count) __insq(PCI_IOBASE + (addr), buffer, count) __io_writes_outs(writes, u64, q, __io_bw(), __io_aw()) #define writesq(addr, buffer, count) __writesq(addr, buffer, count) __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw()) -#define outsq(addr, buffer, count) __outsq((void __iomem *)addr, buffer, count) +#define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count) #endif #include --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/page.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/page.h @@ -119,7 +119,10 @@ #endif /* __ASSEMBLY__ */ -#define virt_addr_valid(vaddr) (pfn_valid(virt_to_pfn(vaddr))) +#define virt_addr_valid(vaddr) ({ \ + unsigned long _addr = (unsigned long)vaddr; \ + (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \ +}) #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/pgtable-32.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/pgtable-32.h @@ -14,4 +14,6 @@ #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE - 1)) +#define MAX_POSSIBLE_PHYSMEM_BITS 34 + #endif /* _ASM_RISCV_PGTABLE_32_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/processor.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/processor.h @@ -22,6 +22,8 @@ #ifndef __ASSEMBLY__ +#include + struct task_struct; struct pt_regs; --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/seccomp.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/seccomp.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_SECCOMP_H +#define _ASM_SECCOMP_H + +#include + +#include + +#endif /* _ASM_SECCOMP_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/thread_info.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/thread_info.h @@ -12,7 +12,11 @@ #include /* thread information allocation */ +#ifdef CONFIG_64BIT +#define THREAD_SIZE_ORDER (2) +#else #define THREAD_SIZE_ORDER (1) +#endif #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) #ifndef __ASSEMBLY__ @@ -75,6 +79,7 @@ #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_SYSCALL_TRACEPOINT 6 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing */ +#define TIF_SECCOMP 8 /* syscall secure computing */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) @@ -82,11 +87,13 @@ #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) +#define _TIF_SECCOMP (1 << TIF_SECCOMP) #define _TIF_WORK_MASK \ (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED) #define _TIF_SYSCALL_WORK \ - (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT) + (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT | \ + _TIF_SECCOMP) #endif /* _ASM_RISCV_THREAD_INFO_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/riscv/include/asm/uaccess.h @@ -235,7 +235,7 @@ might_fault(); \ access_ok(__p, sizeof(*__p)) ? \ __get_user((x), __p) : \ - ((x) = 0, -EFAULT); \ + ((x) = (__force __typeof__(x))0, -EFAULT); \ }) #define __put_user_asm(insn, x, ptr, err) \ --- linux-oracle-5.4.0.orig/arch/riscv/include/uapi/asm/auxvec.h +++ linux-oracle-5.4.0/arch/riscv/include/uapi/asm/auxvec.h @@ -10,4 +10,7 @@ /* vDSO location */ #define AT_SYSINFO_EHDR 33 +/* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 1 + #endif /* _UAPI_ASM_RISCV_AUXVEC_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/uapi/asm/setup.h +++ linux-oracle-5.4.0/arch/riscv/include/uapi/asm/setup.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ + +#ifndef _UAPI_ASM_RISCV_SETUP_H +#define _UAPI_ASM_RISCV_SETUP_H + +#define COMMAND_LINE_SIZE 1024 + +#endif /* _UAPI_ASM_RISCV_SETUP_H */ --- linux-oracle-5.4.0.orig/arch/riscv/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/riscv/include/uapi/asm/unistd.h @@ -18,9 +18,10 @@ #ifdef __LP64__ #define __ARCH_WANT_NEW_STAT #define __ARCH_WANT_SET_GET_RLIMIT -#define __ARCH_WANT_SYS_CLONE3 #endif /* __LP64__ */ +#define __ARCH_WANT_SYS_CLONE3 + #include /* --- linux-oracle-5.4.0.orig/arch/riscv/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/riscv/kernel/asm-offsets.c @@ -4,8 +4,6 @@ * Copyright (C) 2017 SiFive */ -#define GENERATING_ASM_OFFSETS - #include #include #include --- linux-oracle-5.4.0.orig/arch/riscv/kernel/cacheinfo.c +++ linux-oracle-5.4.0/arch/riscv/kernel/cacheinfo.c @@ -16,7 +16,7 @@ this_leaf->type = type; } -static int __init_cache_level(unsigned int cpu) +int init_cache_level(unsigned int cpu) { struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct device_node *np = of_cpu_device_node_get(cpu); @@ -58,7 +58,7 @@ return 0; } -static int __populate_cache_leaves(unsigned int cpu) +int populate_cache_leaves(unsigned int cpu) { struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cacheinfo *this_leaf = this_cpu_ci->info_list; @@ -95,6 +95,3 @@ return 0; } - -DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) -DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) --- linux-oracle-5.4.0.orig/arch/riscv/kernel/entry.S +++ linux-oracle-5.4.0/arch/riscv/kernel/entry.S @@ -226,8 +226,26 @@ /* Check to make sure we don't jump to a bogus syscall number. */ li t0, __NR_syscalls la s0, sys_ni_syscall - /* Syscall number held in a7 */ - bgeu a7, t0, 1f + /* + * The tracer can change syscall number to valid/invalid value. + * We use syscall_set_nr helper in syscall_trace_enter thus we + * cannot trust the current value in a7 and have to reload from + * the current task pt_regs. + */ + REG_L a7, PT_A7(sp) + /* + * Syscall number held in a7. + * If syscall number is above allowed value, redirect to ni_syscall. + */ + bge a7, t0, 1f + /* + * Check if syscall is rejected by tracer or seccomp, i.e., a7 == -1. + * If yes, we pretend it was executed. + */ + li t1, -1 + beq a7, t1, ret_from_syscall_rejected + blt a7, t1, 1f + /* Call syscall */ la s0, sys_call_table slli t0, a7, RISCV_LGPTR add s0, s0, t0 @@ -238,6 +256,12 @@ ret_from_syscall: /* Set user a0 to kernel a0 */ REG_S a0, PT_A0(sp) + /* + * We didn't execute the actual syscall. + * Seccomp already set return value for the current task pt_regs. + * (If it was configured with SECCOMP_RET_ERRNO/TRACE) + */ +ret_from_syscall_rejected: /* Trace syscalls, but only if requested by the user. */ REG_L t0, TASK_TI_FLAGS(tp) andi t0, t0, _TIF_SYSCALL_WORK @@ -387,6 +411,7 @@ ENDPROC(__switch_to) .section ".rodata" + .align LGREG /* Exception vector table */ ENTRY(excp_vect_table) RISCV_PTR do_trap_insn_misaligned --- linux-oracle-5.4.0.orig/arch/riscv/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/riscv/kernel/ftrace.c @@ -88,6 +88,25 @@ return __ftrace_modify_call(rec->ip, addr, false); } + +/* + * This is called early on, and isn't wrapped by + * ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold + * text_mutex, which triggers a lockdep failure. SMP isn't running so we could + * just directly poke the text, but it's simpler to just take the lock + * ourselves. + */ +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) +{ + int out; + + ftrace_arch_code_modify_prepare(); + out = ftrace_make_nop(mod, rec, MCOUNT_ADDR); + ftrace_arch_code_modify_post_process(); + + return out; +} + int ftrace_update_ftrace_func(ftrace_func_t func) { int ret = __ftrace_modify_call((unsigned long)&ftrace_call, @@ -142,7 +161,7 @@ */ old = *parent; - if (function_graph_enter(old, self_addr, frame_pointer, parent)) + if (!function_graph_enter(old, self_addr, frame_pointer, parent)) *parent = return_hooker; } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/head.S +++ linux-oracle-5.4.0/arch/riscv/kernel/head.S @@ -26,6 +26,10 @@ /* reserved */ .word 0 .balign 8 +#ifdef CONFIG_RISCV_M_MODE + /* Image load offset (0MB) from start of RAM for M-mode */ + .dword 0 +#else #if __riscv_xlen == 64 /* Image load offset(2MB) from start of RAM */ .dword 0x200000 @@ -33,6 +37,7 @@ /* Image load offset(4MB) from start of RAM */ .dword 0x400000 #endif +#endif /* Effective size of kernel image */ .dword _end - _start .dword __HEAD_FLAGS --- linux-oracle-5.4.0.orig/arch/riscv/kernel/mcount.S +++ linux-oracle-5.4.0/arch/riscv/kernel/mcount.S @@ -47,8 +47,8 @@ ENTRY(ftrace_stub) #ifdef CONFIG_DYNAMIC_FTRACE - .global _mcount - .set _mcount, ftrace_stub + .global MCOUNT_NAME + .set MCOUNT_NAME, ftrace_stub #endif ret ENDPROC(ftrace_stub) @@ -78,7 +78,7 @@ #endif #ifndef CONFIG_DYNAMIC_FTRACE -ENTRY(_mcount) +ENTRY(MCOUNT_NAME) la t4, ftrace_stub #ifdef CONFIG_FUNCTION_GRAPH_TRACER la t0, ftrace_graph_return @@ -124,6 +124,6 @@ jalr t5 RESTORE_ABI_STATE ret -ENDPROC(_mcount) +ENDPROC(MCOUNT_NAME) #endif -EXPORT_SYMBOL(_mcount) +EXPORT_SYMBOL(MCOUNT_NAME) --- linux-oracle-5.4.0.orig/arch/riscv/kernel/module.c +++ linux-oracle-5.4.0/arch/riscv/kernel/module.c @@ -8,6 +8,23 @@ #include #include #include +#include +#include +#include +#include + +/* + * The auipc+jalr instruction pair can reach any PC-relative offset + * in the range [-2^31 - 2^11, 2^31 - 2^11) + */ +static bool riscv_insn_valid_32bit_offset(ptrdiff_t val) +{ +#ifdef CONFIG_32BIT + return true; +#else + return (-(1L << 31) - (1L << 11)) <= val && val < ((1L << 31) - (1L << 11)); +#endif +} static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v) { @@ -91,7 +108,7 @@ ptrdiff_t offset = (void *)v - (void *)location; s32 hi20; - if (offset != (s32)offset) { + if (!riscv_insn_valid_32bit_offset(offset)) { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", me->name, (long long)v, location); @@ -193,10 +210,9 @@ Elf_Addr v) { ptrdiff_t offset = (void *)v - (void *)location; - s32 fill_v = offset; u32 hi20, lo12; - if (offset != fill_v) { + if (!riscv_insn_valid_32bit_offset(offset)) { /* Only emit the plt entry if offset over 32-bit range */ if (IS_ENABLED(CONFIG_MODULE_SECTIONS)) { offset = module_emit_plt_entry(me, v); @@ -220,10 +236,9 @@ Elf_Addr v) { ptrdiff_t offset = (void *)v - (void *)location; - s32 fill_v = offset; u32 hi20, lo12; - if (offset != fill_v) { + if (!riscv_insn_valid_32bit_offset(offset)) { pr_err( "%s: target %016llx can not be addressed by the 32-bit offset from PC = %p\n", me->name, (long long)v, location); @@ -386,3 +401,15 @@ return 0; } + +#if defined(CONFIG_MMU) && defined(CONFIG_64BIT) +#define VMALLOC_MODULE_START \ + max(PFN_ALIGN((unsigned long)&_end - SZ_2G), VMALLOC_START) +void *module_alloc(unsigned long size) +{ + return __vmalloc_node_range(size, 1, VMALLOC_MODULE_START, + VMALLOC_END, GFP_KERNEL, + PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, + __builtin_return_address(0)); +} +#endif --- linux-oracle-5.4.0.orig/arch/riscv/kernel/module.lds +++ linux-oracle-5.4.0/arch/riscv/kernel/module.lds @@ -2,7 +2,7 @@ /* Copyright (C) 2017 Andes Technology Corporation */ SECTIONS { - .plt (NOLOAD) : { BYTE(0) } - .got (NOLOAD) : { BYTE(0) } - .got.plt (NOLOAD) : { BYTE(0) } + .plt : { BYTE(0) } + .got : { BYTE(0) } + .got.plt : { BYTE(0) } } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/perf_callchain.c +++ linux-oracle-5.4.0/arch/riscv/kernel/perf_callchain.c @@ -60,23 +60,24 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); unsigned long fp = 0; /* RISC-V does not support perf in guest mode. */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) + if (guest_cbs && guest_cbs->is_in_guest()) return; fp = regs->s0; perf_callchain_store(entry, regs->sepc); fp = user_backtrace(entry, fp, regs->ra); - while (fp && !(fp & 0x3) && entry->nr < entry->max_stack) + while (fp && !(fp & 0x7) && entry->nr < entry->max_stack) fp = user_backtrace(entry, fp, 0); } bool fill_callchain(unsigned long pc, void *entry) { - return perf_callchain_store(entry, pc); + return perf_callchain_store(entry, pc) == 0; } void notrace walk_stackframe(struct task_struct *task, @@ -84,8 +85,10 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + /* RISC-V does not support perf in guest mode. */ - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { pr_warn("RISC-V does not support perf in guest mode!"); return; } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/process.c +++ linux-oracle-5.4.0/arch/riscv/kernel/process.c @@ -99,11 +99,13 @@ return 0; } -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, struct task_struct *p) +int copy_thread_tls(unsigned long clone_flags, unsigned long usp, + unsigned long arg, struct task_struct *p, unsigned long tls) { struct pt_regs *childregs = task_pt_regs(p); + memset(&p->thread.s, 0, sizeof(p->thread.s)); + /* p->thread holds context to be restored by __switch_to() */ if (unlikely(p->flags & PF_KTHREAD)) { /* Kernel thread */ @@ -120,7 +122,7 @@ if (usp) /* User fork */ childregs->sp = usp; if (clone_flags & CLONE_SETTLS) - childregs->tp = childregs->a5; + childregs->tp = tls; childregs->a0 = 0; /* Return value of fork() */ p->thread.ra = (unsigned long)ret_from_fork; } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/riscv/kernel/ptrace.c @@ -154,6 +154,16 @@ if (tracehook_report_syscall_entry(regs)) syscall_set_nr(current, regs, -1); + /* + * Do the secure computing after ptrace; failures should be fast. + * If this fails we might have return value in a0 from seccomp + * (via SECCOMP_RET_ERRNO/TRACE). + */ + if (secure_computing(NULL) == -1) { + syscall_set_nr(current, regs, -1); + return; + } + #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, syscall_get_nr(current, regs)); --- linux-oracle-5.4.0.orig/arch/riscv/kernel/smp.c +++ linux-oracle-5.4.0/arch/riscv/kernel/smp.c @@ -51,7 +51,7 @@ return i; pr_err("Couldn't find cpu id for hartid [%d]\n", hartid); - return i; + return -ENOENT; } void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) --- linux-oracle-5.4.0.orig/arch/riscv/kernel/smpboot.c +++ linux-oracle-5.4.0/arch/riscv/kernel/smpboot.c @@ -46,6 +46,8 @@ { int cpuid; + store_cpu_topology(smp_processor_id()); + /* This covers non-smp usecase mandated by "nosmp" option */ if (max_cpus == 0) return; @@ -142,8 +144,8 @@ current->active_mm = mm; trap_init(); + store_cpu_topology(smp_processor_id()); notify_cpu_starting(smp_processor_id()); - update_siblings_masks(smp_processor_id()); set_cpu_online(smp_processor_id(), 1); /* * Remote TLB flushes are ignored while the CPU is offline, so emit --- linux-oracle-5.4.0.orig/arch/riscv/kernel/stacktrace.c +++ linux-oracle-5.4.0/arch/riscv/kernel/stacktrace.c @@ -63,7 +63,7 @@ #else /* !CONFIG_FRAME_POINTER */ -static void notrace walk_stackframe(struct task_struct *task, +void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg) { unsigned long sp, pc; @@ -89,7 +89,7 @@ while (!kstack_end(ksp)) { if (__kernel_text_address(pc) && unlikely(fn(pc, arg))) break; - pc = (*ksp++) - 0x4; + pc = READ_ONCE_NOCHECK(*ksp++) - 0x4; } } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/sys_riscv.c +++ linux-oracle-5.4.0/arch/riscv/kernel/sys_riscv.c @@ -8,6 +8,7 @@ #include #include #include +#include static long riscv_sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, @@ -16,6 +17,7 @@ { if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) return -EINVAL; + return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - page_shift_offset)); } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/time.c +++ linux-oracle-5.4.0/arch/riscv/kernel/time.c @@ -4,6 +4,8 @@ * Copyright (C) 2017 SiFive */ +#include +#include #include #include #include @@ -24,5 +26,9 @@ riscv_timebase = prop; lpj_fine = riscv_timebase / HZ; + + of_clk_init(NULL); timer_probe(); + + tick_setup_hrtimer_broadcast(); } --- linux-oracle-5.4.0.orig/arch/riscv/kernel/traps.c +++ linux-oracle-5.4.0/arch/riscv/kernel/traps.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,9 @@ ret = notify_die(DIE_OOPS, str, regs, 0, regs->scause, SIGSEGV); + if (regs && kexec_should_crash(current)) + crash_kexec(regs); + bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); spin_unlock_irq(&die_lock); @@ -53,7 +57,7 @@ if (panic_on_oops) panic("Fatal exception"); if (ret != NOTIFY_STOP) - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr) --- linux-oracle-5.4.0.orig/arch/riscv/kernel/vdso/Makefile +++ linux-oracle-5.4.0/arch/riscv/kernel/vdso/Makefile @@ -20,6 +20,9 @@ obj-y += vdso.o vdso-syms.o CPPFLAGS_vdso.lds += -P -C -U$(ARCH) +ifneq ($(filter vgettimeofday, $(vdso-syms)),) +CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY +endif # Disable gcov profiling for VDSO code GCOV_PROFILE := n @@ -33,15 +36,15 @@ $(call if_changed,vdsold) # We also create a special relocatable object that should mirror the symbol -# table and layout of the linked DSO. With ld -R we can then refer to -# these symbols in the kernel code rather than hand-coded addresses. +# table and layout of the linked DSO. With ld --just-symbols we can then +# refer to these symbols in the kernel code rather than hand-coded addresses. SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ -Wl,--build-id -Wl,--hash-style=both $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE $(call if_changed,vdsold) -LDFLAGS_vdso-syms.o := -r -R +LDFLAGS_vdso-syms.o := -r --just-symbols $(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE $(call if_changed,ld) @@ -58,7 +61,8 @@ cmd_vdsold = $(CC) $(KBUILD_CFLAGS) $(call cc-option, -no-pie) -nostdlib -nostartfiles $(SYSCFLAGS_$(@F)) \ -Wl,-T,$(filter-out FORCE,$^) -o $@.tmp && \ $(CROSS_COMPILE)objcopy \ - $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ + $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \ + rm $@.tmp # install commands for the unstripped file quiet_cmd_vdso_install = INSTALL $@ --- linux-oracle-5.4.0.orig/arch/riscv/kernel/vdso/vdso.lds.S +++ linux-oracle-5.4.0/arch/riscv/kernel/vdso/vdso.lds.S @@ -62,9 +62,11 @@ LINUX_4.15 { global: __vdso_rt_sigreturn; +#ifdef HAS_VGETTIMEOFDAY __vdso_gettimeofday; __vdso_clock_gettime; __vdso_clock_getres; +#endif __vdso_getcpu; __vdso_flush_icache; local: *; --- linux-oracle-5.4.0.orig/arch/riscv/lib/tishift.S +++ linux-oracle-5.4.0/arch/riscv/lib/tishift.S @@ -4,34 +4,73 @@ */ #include +#include -ENTRY(__lshrti3) +SYM_FUNC_START(__lshrti3) beqz a2, .L1 li a5,64 sub a5,a5,a2 - addi sp,sp,-16 sext.w a4,a5 blez a5, .L2 sext.w a2,a2 - sll a4,a1,a4 srl a0,a0,a2 - srl a1,a1,a2 + sll a4,a1,a4 + srl a2,a1,a2 or a0,a0,a4 - sd a1,8(sp) - sd a0,0(sp) - ld a0,0(sp) - ld a1,8(sp) - addi sp,sp,16 - ret + mv a1,a2 .L1: ret .L2: - negw a4,a4 - srl a1,a1,a4 - sd a1,0(sp) - sd zero,8(sp) - ld a0,0(sp) - ld a1,8(sp) - addi sp,sp,16 + negw a0,a4 + li a2,0 + srl a0,a1,a0 + mv a1,a2 + ret +SYM_FUNC_END(__lshrti3) +EXPORT_SYMBOL(__lshrti3) + +SYM_FUNC_START(__ashrti3) + beqz a2, .L3 + li a5,64 + sub a5,a5,a2 + sext.w a4,a5 + blez a5, .L4 + sext.w a2,a2 + srl a0,a0,a2 + sll a4,a1,a4 + sra a2,a1,a2 + or a0,a0,a4 + mv a1,a2 +.L3: + ret +.L4: + negw a0,a4 + srai a2,a1,0x3f + sra a0,a1,a0 + mv a1,a2 + ret +SYM_FUNC_END(__ashrti3) +EXPORT_SYMBOL(__ashrti3) + +SYM_FUNC_START(__ashlti3) + beqz a2, .L5 + li a5,64 + sub a5,a5,a2 + sext.w a4,a5 + blez a5, .L6 + sext.w a2,a2 + sll a1,a1,a2 + srl a4,a0,a4 + sll a2,a0,a2 + or a1,a1,a4 + mv a0,a2 +.L5: + ret +.L6: + negw a1,a4 + li a2,0 + sll a1,a0,a1 + mv a0,a2 ret -ENDPROC(__lshrti3) +SYM_FUNC_END(__ashlti3) +EXPORT_SYMBOL(__ashlti3) --- linux-oracle-5.4.0.orig/arch/riscv/mm/cacheflush.c +++ linux-oracle-5.4.0/arch/riscv/mm/cacheflush.c @@ -14,6 +14,7 @@ { sbi_remote_fence_i(NULL); } +EXPORT_SYMBOL(flush_icache_all); /* * Performs an icache flush for the given MM context. RISC-V has no direct @@ -70,6 +71,8 @@ { struct page *page = pte_page(pte); - if (!test_and_set_bit(PG_dcache_clean, &page->flags)) + if (!test_bit(PG_dcache_clean, &page->flags)) { flush_icache_all(); + set_bit(PG_dcache_clean, &page->flags); + } } --- linux-oracle-5.4.0.orig/arch/riscv/mm/fault.c +++ linux-oracle-5.4.0/arch/riscv/mm/fault.c @@ -189,7 +189,7 @@ (addr < PAGE_SIZE) ? "NULL pointer dereference" : "paging request", addr); die(regs, "Oops"); - do_exit(SIGKILL); + make_task_dead(SIGKILL); /* * We ran out of memory, call the OOM killer, and return the userspace --- linux-oracle-5.4.0.orig/arch/riscv/mm/init.c +++ linux-oracle-5.4.0/arch/riscv/mm/init.c @@ -37,7 +37,7 @@ #endif max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); } void setup_zero_page(void) @@ -98,7 +98,7 @@ for_each_memblock(memory, reg) { phys_addr_t end = reg->base + reg->size; - if (reg->base <= vmlinux_end && vmlinux_end <= end) { + if (reg->base <= vmlinux_start && vmlinux_end <= end) { mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); /* @@ -115,8 +115,9 @@ /* Reserve from the start of the kernel to the end of the kernel */ memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); - set_max_mapnr(PFN_DOWN(mem_size)); - max_low_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_pfn = PFN_DOWN(memblock_end_of_DRAM()); + max_low_pfn = max_pfn; + set_max_mapnr(max_low_pfn); #ifdef CONFIG_BLK_DEV_INITRD setup_initrd(); @@ -166,12 +167,11 @@ ptep = &fixmap_pte[pte_index(addr)]; - if (pgprot_val(prot)) { + if (pgprot_val(prot)) set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); - } else { + else pte_clear(&init_mm, addr, ptep); - local_flush_tlb_page(addr); - } + local_flush_tlb_page(addr); } static pte_t *__init get_pte_virt(phys_addr_t pa) --- linux-oracle-5.4.0.orig/arch/riscv/mm/tlbflush.c +++ linux-oracle-5.4.0/arch/riscv/mm/tlbflush.c @@ -2,6 +2,7 @@ #include #include +#include #include void flush_tlb_all(void) @@ -9,13 +10,33 @@ sbi_remote_sfence_vma(NULL, 0, -1); } +/* + * This function must not be called with cmask being null. + * Kernel may panic if cmask is NULL. + */ static void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start, unsigned long size) { struct cpumask hmask; + unsigned int cpuid; - riscv_cpuid_to_hartid_mask(cmask, &hmask); - sbi_remote_sfence_vma(hmask.bits, start, size); + if (cpumask_empty(cmask)) + return; + + cpuid = get_cpu(); + + if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) { + /* local cpu is the only cpu present in cpumask */ + if (size <= PAGE_SIZE) + local_flush_tlb_page(start); + else + local_flush_tlb_all(); + } else { + riscv_cpuid_to_hartid_mask(cmask, &hmask); + sbi_remote_sfence_vma(cpumask_bits(&hmask), start, size); + } + + put_cpu(); } void flush_tlb_mm(struct mm_struct *mm) --- linux-oracle-5.4.0.orig/arch/riscv/net/bpf_jit_comp.c +++ linux-oracle-5.4.0/arch/riscv/net/bpf_jit_comp.c @@ -120,6 +120,11 @@ return false; } +static void mark_fp(struct rv_jit_context *ctx) +{ + __set_bit(RV_CTX_F_SEEN_S5, &ctx->flags); +} + static void mark_call(struct rv_jit_context *ctx) { __set_bit(RV_CTX_F_SEEN_CALL, &ctx->flags); @@ -596,7 +601,8 @@ emit(rv_addi(RV_REG_SP, RV_REG_SP, stack_adjust), ctx); /* Set return value. */ - emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx); + if (reg == RV_REG_RA) + emit(rv_addi(RV_REG_A0, RV_REG_A5, 0), ctx); emit(rv_jalr(RV_REG_ZERO, reg, 0), ctx); } @@ -631,14 +637,14 @@ return -1; emit(rv_bgeu(RV_REG_A2, RV_REG_T1, off >> 1), ctx); - /* if (--TCC < 0) + /* if (TCC-- < 0) * goto out; */ emit(rv_addi(RV_REG_T1, tcc, -1), ctx); off = (tc_ninsn - (ctx->ninsns - start_insn)) << 2; if (is_13b_check(off, insn)) return -1; - emit(rv_blt(RV_REG_T1, RV_REG_ZERO, off >> 1), ctx); + emit(rv_blt(tcc, RV_REG_ZERO, off >> 1), ctx); /* prog = array->ptrs[index]; * if (!prog) @@ -1307,6 +1313,10 @@ emit(rv_ld(rd, 0, RV_REG_T1), ctx); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_B: emit_imm(RV_REG_T1, imm, ctx); @@ -1426,6 +1436,10 @@ { int stack_adjust = 0, store_offset, bpf_stack_adjust; + bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16); + if (bpf_stack_adjust) + mark_fp(ctx); + if (seen_reg(RV_REG_RA, ctx)) stack_adjust += 8; stack_adjust += 8; /* RV_REG_FP */ @@ -1443,7 +1457,6 @@ stack_adjust += 8; stack_adjust = round_up(stack_adjust, 16); - bpf_stack_adjust = round_up(ctx->prog->aux->stack_depth, 16); stack_adjust += bpf_stack_adjust; store_offset = stack_adjust - 8; --- linux-oracle-5.4.0.orig/arch/s390/Kconfig +++ linux-oracle-5.4.0/arch/s390/Kconfig @@ -155,12 +155,12 @@ select HAVE_KERNEL_UNCOMPRESSED select HAVE_KERNEL_XZ select HAVE_KPROBES + select HAVE_KPROBES_ON_FTRACE select HAVE_KRETPROBES select HAVE_KVM select HAVE_LIVEPATCH select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP - select HAVE_MEMBLOCK_NODE_MAP select HAVE_MEMBLOCK_PHYS_MAP select HAVE_MMU_GATHER_NO_GATHER select HAVE_MOD_ARCH_SPECIFIC @@ -541,7 +541,6 @@ config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE - select BUILD_BIN2C depends on CRYPTO depends on CRYPTO_SHA256 depends on CRYPTO_SHA256_S390 @@ -920,7 +919,7 @@ config APPLDATA_BASE def_bool n prompt "Linux - VM Monitor Stream, base infrastructure" - depends on PROC_FS + depends on PROC_SYSCTL help This provides a kernel interface for creating and updating z/VM APPLDATA monitor records. The monitor records are updated at certain time @@ -1006,3 +1005,11 @@ the KVM hypervisor. endmenu + +config KMSG_IDS + def_bool y + prompt "Kernel message numbers" + help + Select this option if you want to include a message number to the + prefix for kernel messages issued by the s390 architecture and + driver code. See "Documentation/s390/kmsg.txt" for more details. --- linux-oracle-5.4.0.orig/arch/s390/Makefile +++ linux-oracle-5.4.0/arch/s390/Makefile @@ -31,6 +31,16 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) + +ifdef CONFIG_CC_IS_GCC + ifeq ($(call cc-ifversion, -ge, 1200, y), y) + ifeq ($(call cc-ifversion, -lt, 1300, y), y) + KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) + KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, array-bounds) + endif + endif +endif + UTS_MACHINE := s390x STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384) CHECKFLAGS += -D__s390__ -D__s390x__ @@ -69,7 +79,7 @@ # cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls -ifeq ($(call cc-option-yn,-mpacked-stack),y) +ifeq ($(call cc-option-yn,-mpacked-stack -mbackchain -msoft-float),y) cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK endif @@ -146,7 +156,7 @@ #KBUILD_IMAGE is necessary for packaging targets like rpm-pkg, deb-pkg... KBUILD_IMAGE := $(boot)/bzImage -install: vmlinux +install: $(Q)$(MAKE) $(build)=$(boot) $@ bzImage: vmlinux --- linux-oracle-5.4.0.orig/arch/s390/appldata/appldata_os.c +++ linux-oracle-5.4.0/arch/s390/appldata/appldata_os.c @@ -75,7 +75,7 @@ (waiting for I/O) */ /* per cpu data */ - struct appldata_os_per_cpu os_cpu[0]; + struct appldata_os_per_cpu os_cpu[]; } __attribute__((packed)); static struct appldata_os_data *appldata_os_data; --- linux-oracle-5.4.0.orig/arch/s390/boot/Makefile +++ linux-oracle-5.4.0/arch/s390/boot/Makefile @@ -37,7 +37,7 @@ obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o obj-y += version.o pgm_check_info.o ctype.o text_dma.o -obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o +obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y) @@ -70,7 +70,7 @@ $(obj)/startup.a: $(OBJECTS) FORCE $(call if_changed,ar) -install: $(CONFIGURE) $(obj)/bzImage +install: sh -x $(srctree)/$(obj)/install.sh $(KERNELRELEASE) $(obj)/bzImage \ System.map "$(INSTALL_PATH)" --- linux-oracle-5.4.0.orig/arch/s390/boot/compressed/decompressor.c +++ linux-oracle-5.4.0/arch/s390/boot/compressed/decompressor.c @@ -30,13 +30,13 @@ extern unsigned char _compressed_end[]; #ifdef CONFIG_HAVE_KERNEL_BZIP2 -#define HEAP_SIZE 0x400000 +#define BOOT_HEAP_SIZE 0x400000 #else -#define HEAP_SIZE 0x10000 +#define BOOT_HEAP_SIZE 0x10000 #endif static unsigned long free_mem_ptr = (unsigned long) _end; -static unsigned long free_mem_end_ptr = (unsigned long) _end + HEAP_SIZE; +static unsigned long free_mem_end_ptr = (unsigned long) _end + BOOT_HEAP_SIZE; #ifdef CONFIG_KERNEL_GZIP #include "../../../../lib/decompress_inflate.c" @@ -62,7 +62,7 @@ #include "../../../../lib/decompress_unxz.c" #endif -#define decompress_offset ALIGN((unsigned long)_end + HEAP_SIZE, PAGE_SIZE) +#define decompress_offset ALIGN((unsigned long)_end + BOOT_HEAP_SIZE, PAGE_SIZE) unsigned long mem_safe_offset(void) { @@ -80,6 +80,6 @@ void *output = (void *)decompress_offset; __decompress(_compressed_start, _compressed_end - _compressed_start, - NULL, NULL, output, 0, NULL, error); + NULL, NULL, output, vmlinux.image_size, NULL, error); return output; } --- linux-oracle-5.4.0.orig/arch/s390/boot/compressed/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/s390/boot/compressed/vmlinux.lds.S @@ -78,10 +78,19 @@ _compressed_start = .; *(.vmlinux.bin.compressed) _compressed_end = .; - FILL(0xff); - . = ALIGN(4096); } - . = ALIGN(256); + +#define SB_TRAILER_SIZE 32 + /* Trailer needed for Secure Boot */ + . += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */ + . = ALIGN(4096) - SB_TRAILER_SIZE; + .sb.trailer : { + QUAD(0) + QUAD(0) + QUAD(0) + QUAD(0x000000207a49504c) + } + .bss : { _bss = . ; *(.bss) --- linux-oracle-5.4.0.orig/arch/s390/boot/head.S +++ linux-oracle-5.4.0/arch/s390/boot/head.S @@ -360,22 +360,23 @@ # the save area and does disabled wait with a faulty address. # ENTRY(startup_pgm_check_handler) - stmg %r0,%r15,__LC_SAVE_AREA_SYNC - la %r1,4095 - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1) - mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC - mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW + stmg %r8,%r15,__LC_SAVE_AREA_SYNC + la %r8,4095 + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r8) + stmg %r0,%r7,__LC_GPREGS_SAVE_AREA-4095(%r8) + mvc __LC_GPREGS_SAVE_AREA-4095+64(64,%r8),__LC_SAVE_AREA_SYNC + mvc __LC_PSW_SAVE_AREA-4095(16,%r8),__LC_PGM_OLD_PSW mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW ni __LC_RETURN_PSW,0xfc # remove IO and EX bits ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit oi __LC_RETURN_PSW+1,0x2 # set wait state bit - larl %r2,.Lold_psw_disabled_wait - stg %r2,__LC_PGM_NEW_PSW+8 - l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2) + larl %r9,.Lold_psw_disabled_wait + stg %r9,__LC_PGM_NEW_PSW+8 + l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r9) brasl %r14,print_pgm_check_info .Lold_psw_disabled_wait: - la %r1,4095 - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) + la %r8,4095 + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r8) lpswe __LC_RETURN_PSW # disabled wait .Ldump_info_stack: .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD --- linux-oracle-5.4.0.orig/arch/s390/boot/ipl_parm.c +++ linux-oracle-5.4.0/arch/s390/boot/ipl_parm.c @@ -14,6 +14,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; struct ipl_parameter_block __bootdata_preserved(ipl_block); int __bootdata_preserved(ipl_block_valid); +unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL; unsigned long __bootdata(vmalloc_size) = VMALLOC_DEFAULT_SIZE; unsigned long __bootdata(memory_end); @@ -27,22 +28,25 @@ register unsigned long _addr asm("0") = (unsigned long)addr; register unsigned long _rc asm("1") = 0; unsigned long reg1, reg2; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; asm volatile( + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" " epsw %0,%1\n" - " st %0,%[psw_pgm]\n" - " st %1,%[psw_pgm]+4\n" + " st %0,0(%[psw_pgm])\n" + " st %1,4(%[psw_pgm])\n" " larl %0,1f\n" - " stg %0,%[psw_pgm]+8\n" + " stg %0,8(%[psw_pgm])\n" " diag %[addr],%[subcode],0x308\n" - "1: nopr %%r7\n" + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" : "=&d" (reg1), "=&a" (reg2), - [psw_pgm] "=Q" (S390_lowcore.program_new_psw), + "+Q" (S390_lowcore.program_new_psw), + "=Q" (old), [addr] "+d" (_addr), "+d" (_rc) - : [subcode] "d" (subcode) + : [subcode] "d" (subcode), + [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return _rc; } @@ -69,30 +73,44 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size, const struct ipl_parameter_block *ipb) { - size_t count; - size_t i; + const __u8 *scp_data; + __u32 scp_data_len; int has_lowercase; + size_t count = 0; + size_t i; + + switch (ipb->pb0_hdr.pbt) { + case IPL_PBT_FCP: + scp_data_len = ipb->fcp.scp_data_len; + scp_data = ipb->fcp.scp_data; + break; + case IPL_PBT_NVME: + scp_data_len = ipb->nvme.scp_data_len; + scp_data = ipb->nvme.scp_data; + break; + default: + goto out; + } - count = min(size - 1, scpdata_length(ipb->fcp.scp_data, - ipb->fcp.scp_data_len)); + count = min(size - 1, scpdata_length(scp_data, scp_data_len)); if (!count) goto out; has_lowercase = 0; for (i = 0; i < count; i++) { - if (!isascii(ipb->fcp.scp_data[i])) { + if (!isascii(scp_data[i])) { count = 0; goto out; } - if (!has_lowercase && islower(ipb->fcp.scp_data[i])) + if (!has_lowercase && islower(scp_data[i])) has_lowercase = 1; } if (has_lowercase) - memcpy(dest, ipb->fcp.scp_data, count); + memcpy(dest, scp_data, count); else for (i = 0; i < count; i++) - dest[i] = tolower(ipb->fcp.scp_data[i]); + dest[i] = tolower(scp_data[i]); out: dest[count] = '\0'; return count; @@ -114,6 +132,7 @@ parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); break; case IPL_PBT_FCP: + case IPL_PBT_NVME: rc = ipl_block_get_ascii_scpdata( parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); break; @@ -229,6 +248,19 @@ if (!strcmp(param, "vmalloc") && val) vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); + if (!strcmp(param, "dfltcc")) { + if (!strcmp(val, "off")) + zlib_dfltcc_support = ZLIB_DFLTCC_DISABLED; + else if (!strcmp(val, "on")) + zlib_dfltcc_support = ZLIB_DFLTCC_FULL; + else if (!strcmp(val, "def_only")) + zlib_dfltcc_support = ZLIB_DFLTCC_DEFLATE_ONLY; + else if (!strcmp(val, "inf_only")) + zlib_dfltcc_support = ZLIB_DFLTCC_INFLATE_ONLY; + else if (!strcmp(val, "always")) + zlib_dfltcc_support = ZLIB_DFLTCC_FULL_DEBUG; + } + if (!strcmp(param, "noexec")) { rc = kstrtobool(val, &enabled); if (!rc && !enabled) --- linux-oracle-5.4.0.orig/arch/s390/boot/ipl_report.c +++ linux-oracle-5.4.0/arch/s390/boot/ipl_report.c @@ -57,11 +57,19 @@ if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE && intersects(INITRD_START, INITRD_SIZE, safe_addr, size)) safe_addr = INITRD_START + INITRD_SIZE; + if (intersects(safe_addr, size, (unsigned long)comps, comps->len)) { + safe_addr = (unsigned long)comps + comps->len; + goto repeat; + } for_each_rb_entry(comp, comps) if (intersects(safe_addr, size, comp->addr, comp->len)) { safe_addr = comp->addr + comp->len; goto repeat; } + if (intersects(safe_addr, size, (unsigned long)certs, certs->len)) { + safe_addr = (unsigned long)certs + certs->len; + goto repeat; + } for_each_rb_entry(cert, certs) if (intersects(safe_addr, size, cert->addr, cert->len)) { safe_addr = cert->addr + cert->len; --- linux-oracle-5.4.0.orig/arch/s390/boot/kaslr.c +++ linux-oracle-5.4.0/arch/s390/boot/kaslr.c @@ -75,7 +75,7 @@ *(unsigned long *) prng.parm_block ^= seed; for (i = 0; i < 16; i++) { cpacf_kmc(CPACF_KMC_PRNG, prng.parm_block, - (char *) entropy, (char *) entropy, + (u8 *) entropy, (u8 *) entropy, sizeof(entropy)); memcpy(prng.parm_block, entropy, sizeof(entropy)); } --- linux-oracle-5.4.0.orig/arch/s390/boot/mem_detect.c +++ linux-oracle-5.4.0/arch/s390/boot/mem_detect.c @@ -70,24 +70,27 @@ register unsigned long _ry asm("4") = 0x10; /* storage configuration */ int rc = -1; /* fail */ unsigned long reg1, reg2; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; asm volatile( + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" " epsw %0,%1\n" - " st %0,%[psw_pgm]\n" - " st %1,%[psw_pgm]+4\n" + " st %0,0(%[psw_pgm])\n" + " st %1,4(%[psw_pgm])\n" " larl %0,1f\n" - " stg %0,%[psw_pgm]+8\n" + " stg %0,8(%[psw_pgm])\n" " diag %[rx],%[ry],0x260\n" " ipm %[rc]\n" " srl %[rc],28\n" - "1:\n" + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" : "=&d" (reg1), "=&a" (reg2), - [psw_pgm] "=Q" (S390_lowcore.program_new_psw), + "+Q" (S390_lowcore.program_new_psw), + "=Q" (old), [rc] "+&d" (rc), [ry] "+d" (_ry) - : [rx] "d" (_rx1), "d" (_rx2) + : [rx] "d" (_rx1), "d" (_rx2), + [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return rc == 0 ? _ry : -1; } @@ -112,24 +115,30 @@ static int tprot(unsigned long addr) { - unsigned long pgm_addr; + unsigned long reg1, reg2; int rc = -EFAULT; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; - S390_lowcore.program_new_psw.mask = __extract_psw(); asm volatile( - " larl %[pgm_addr],1f\n" - " stg %[pgm_addr],%[psw_pgm_addr]\n" + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" + " epsw %[reg1],%[reg2]\n" + " st %[reg1],0(%[psw_pgm])\n" + " st %[reg2],4(%[psw_pgm])\n" + " larl %[reg1],1f\n" + " stg %[reg1],8(%[psw_pgm])\n" " tprot 0(%[addr]),0\n" " ipm %[rc]\n" " srl %[rc],28\n" - "1:\n" - : [pgm_addr] "=&d"(pgm_addr), - [psw_pgm_addr] "=Q"(S390_lowcore.program_new_psw.addr), - [rc] "+&d"(rc) - : [addr] "a"(addr) + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" + : [reg1] "=&d" (reg1), + [reg2] "=&a" (reg2), + [rc] "+&d" (rc), + "=Q" (S390_lowcore.program_new_psw.addr), + "=Q" (old) + : [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw), + [addr] "a" (addr) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return rc; } --- linux-oracle-5.4.0.orig/arch/s390/boot/startup.c +++ linux-oracle-5.4.0/arch/s390/boot/startup.c @@ -170,6 +170,11 @@ handle_relocs(__kaslr_offset); if (__kaslr_offset) { + /* + * Save KASLR offset for early dumps, before vmcore_info is set. + * Mark as uneven to distinguish from real vmcore_info pointer. + */ + S390_lowcore.vmcore_info = __kaslr_offset | 0x1UL; /* Clear non-relocated kernel */ if (IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) memset(img, 0, vmlinux.image_size); --- linux-oracle-5.4.0.orig/arch/s390/boot/text_dma.S +++ linux-oracle-5.4.0/arch/s390/boot/text_dma.S @@ -9,16 +9,6 @@ #include #include -#ifdef CC_USING_EXPOLINE - .pushsection .dma.text.__s390_indirect_jump_r14,"axG" -__dma__s390_indirect_jump_r14: - larl %r1,0f - ex 0,0(%r1) - j . -0: br %r14 - .popsection -#endif - .section .dma.text,"ax" /* * Simplified version of expoline thunk. The normal thunks can not be used here, @@ -27,11 +17,10 @@ * affects a few functions that are not performance-relevant. */ .macro BR_EX_DMA_r14 -#ifdef CC_USING_EXPOLINE - jg __dma__s390_indirect_jump_r14 -#else - br %r14 -#endif + larl %r1,0f + ex 0,0(%r1) + j . +0: br %r14 .endm /* --- linux-oracle-5.4.0.orig/arch/s390/boot/uv.c +++ linux-oracle-5.4.0/arch/s390/boot/uv.c @@ -3,7 +3,13 @@ #include #include +/* will be used in arch/s390/kernel/uv.c */ +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST int __bootdata_preserved(prot_virt_guest); +#endif +#if IS_ENABLED(CONFIG_KVM) +struct uv_info __bootdata_preserved(uv_info); +#endif void uv_query_info(void) { @@ -15,10 +21,25 @@ if (!test_facility(158)) return; - if (uv_call(0, (uint64_t)&uvcb)) + /* rc==0x100 means that there is additional data we do not process */ + if (uv_call(0, (uint64_t)&uvcb) && uvcb.header.rc != 0x100) return; + if (IS_ENABLED(CONFIG_KVM)) { + memcpy(uv_info.inst_calls_list, uvcb.inst_calls_list, sizeof(uv_info.inst_calls_list)); + uv_info.uv_base_stor_len = uvcb.uv_base_stor_len; + uv_info.guest_base_stor_len = uvcb.conf_base_phys_stor_len; + uv_info.guest_virt_base_stor_len = uvcb.conf_base_virt_stor_len; + uv_info.guest_virt_var_stor_len = uvcb.conf_virt_var_stor_len; + uv_info.guest_cpu_stor_len = uvcb.cpu_stor_len; + uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); + uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; + uv_info.max_guest_cpus = uvcb.max_guest_cpus; + } + +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST if (test_bit_inv(BIT_UVC_CMD_SET_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list) && test_bit_inv(BIT_UVC_CMD_REMOVE_SHARED_ACCESS, (unsigned long *)uvcb.inst_calls_list)) prot_virt_guest = 1; +#endif } --- linux-oracle-5.4.0.orig/arch/s390/configs/debug_defconfig +++ linux-oracle-5.4.0/arch/s390/configs/debug_defconfig @@ -62,7 +62,6 @@ CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y CONFIG_STATIC_KEYS_SELFTEST=y -CONFIG_REFCOUNT_FULL=y CONFIG_LOCK_EVENT_COUNTS=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y --- linux-oracle-5.4.0.orig/arch/s390/crypto/aes_s390.c +++ linux-oracle-5.4.0/arch/s390/crypto/aes_s390.c @@ -861,7 +861,7 @@ unsigned int nbytes) { gw->walk_bytes_remain -= nbytes; - scatterwalk_unmap(&gw->walk); + scatterwalk_unmap(gw->walk_ptr); scatterwalk_advance(&gw->walk, nbytes); scatterwalk_done(&gw->walk, 0, gw->walk_bytes_remain); gw->walk_ptr = NULL; @@ -936,7 +936,7 @@ goto out; } - scatterwalk_unmap(&gw->walk); + scatterwalk_unmap(gw->walk_ptr); gw->walk_ptr = NULL; gw->ptr = gw->buf; --- linux-oracle-5.4.0.orig/arch/s390/crypto/arch_random.c +++ linux-oracle-5.4.0/arch/s390/crypto/arch_random.c @@ -2,122 +2,17 @@ /* * s390 arch random implementation. * - * Copyright IBM Corp. 2017, 2018 + * Copyright IBM Corp. 2017, 2020 * Author(s): Harald Freudenberger - * - * The s390_arch_random_generate() function may be called from random.c - * in interrupt context. So this implementation does the best to be very - * fast. There is a buffer of random data which is asynchronously checked - * and filled by a workqueue thread. - * If there are enough bytes in the buffer the s390_arch_random_generate() - * just delivers these bytes. Otherwise false is returned until the - * worker thread refills the buffer. - * The worker fills the rng buffer by pulling fresh entropy from the - * high quality (but slow) true hardware random generator. This entropy - * is then spread over the buffer with an pseudo random generator PRNG. - * As the arch_get_random_seed_long() fetches 8 bytes and the calling - * function add_interrupt_randomness() counts this as 1 bit entropy the - * distribution needs to make sure there is in fact 1 bit entropy contained - * in 8 bytes of the buffer. The current values pull 32 byte entropy - * and scatter this into a 2048 byte buffer. So 8 byte in the buffer - * will contain 1 bit of entropy. - * The worker thread is rescheduled based on the charge level of the - * buffer but at least with 500 ms delay to avoid too much CPU consumption. - * So the max. amount of rng data delivered via arch_get_random_seed is - * limited to 4k bytes per second. */ #include #include #include -#include #include -#include #include DEFINE_STATIC_KEY_FALSE(s390_arch_random_available); atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0); EXPORT_SYMBOL(s390_arch_random_counter); - -#define ARCH_REFILL_TICKS (HZ/2) -#define ARCH_PRNG_SEED_SIZE 32 -#define ARCH_RNG_BUF_SIZE 2048 - -static DEFINE_SPINLOCK(arch_rng_lock); -static u8 *arch_rng_buf; -static unsigned int arch_rng_buf_idx; - -static void arch_rng_refill_buffer(struct work_struct *); -static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer); - -bool s390_arch_random_generate(u8 *buf, unsigned int nbytes) -{ - /* lock rng buffer */ - if (!spin_trylock(&arch_rng_lock)) - return false; - - /* try to resolve the requested amount of bytes from the buffer */ - arch_rng_buf_idx -= nbytes; - if (arch_rng_buf_idx < ARCH_RNG_BUF_SIZE) { - memcpy(buf, arch_rng_buf + arch_rng_buf_idx, nbytes); - atomic64_add(nbytes, &s390_arch_random_counter); - spin_unlock(&arch_rng_lock); - return true; - } - - /* not enough bytes in rng buffer, refill is done asynchronously */ - spin_unlock(&arch_rng_lock); - - return false; -} -EXPORT_SYMBOL(s390_arch_random_generate); - -static void arch_rng_refill_buffer(struct work_struct *unused) -{ - unsigned int delay = ARCH_REFILL_TICKS; - - spin_lock(&arch_rng_lock); - if (arch_rng_buf_idx > ARCH_RNG_BUF_SIZE) { - /* buffer is exhausted and needs refill */ - u8 seed[ARCH_PRNG_SEED_SIZE]; - u8 prng_wa[240]; - /* fetch ARCH_PRNG_SEED_SIZE bytes of entropy */ - cpacf_trng(NULL, 0, seed, sizeof(seed)); - /* blow this entropy up to ARCH_RNG_BUF_SIZE with PRNG */ - memset(prng_wa, 0, sizeof(prng_wa)); - cpacf_prno(CPACF_PRNO_SHA512_DRNG_SEED, - &prng_wa, NULL, 0, seed, sizeof(seed)); - cpacf_prno(CPACF_PRNO_SHA512_DRNG_GEN, - &prng_wa, arch_rng_buf, ARCH_RNG_BUF_SIZE, NULL, 0); - arch_rng_buf_idx = ARCH_RNG_BUF_SIZE; - } - delay += (ARCH_REFILL_TICKS * arch_rng_buf_idx) / ARCH_RNG_BUF_SIZE; - spin_unlock(&arch_rng_lock); - - /* kick next check */ - queue_delayed_work(system_long_wq, &arch_rng_work, delay); -} - -static int __init s390_arch_random_init(void) -{ - /* all the needed PRNO subfunctions available ? */ - if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG) && - cpacf_query_func(CPACF_PRNO, CPACF_PRNO_SHA512_DRNG_GEN)) { - - /* alloc arch random working buffer */ - arch_rng_buf = kmalloc(ARCH_RNG_BUF_SIZE, GFP_KERNEL); - if (!arch_rng_buf) - return -ENOMEM; - - /* kick worker queue job to fill the random buffer */ - queue_delayed_work(system_long_wq, - &arch_rng_work, ARCH_REFILL_TICKS); - - /* enable arch random to the outside world */ - static_branch_enable(&s390_arch_random_available); - } - - return 0; -} -arch_initcall(s390_arch_random_init); --- linux-oracle-5.4.0.orig/arch/s390/crypto/paes_s390.c +++ linux-oracle-5.4.0/arch/s390/crypto/paes_s390.c @@ -5,7 +5,7 @@ * s390 implementation of the AES Cipher Algorithm with protected keys. * * s390 Version: - * Copyright IBM Corp. 2017,2019 + * Copyright IBM Corp. 2017,2020 * Author(s): Martin Schwidefsky * Harald Freudenberger */ @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -31,11 +32,11 @@ * is called. As paes can handle different kinds of key blobs * and padding is also possible, the limits need to be generous. */ -#define PAES_MIN_KEYSIZE 64 -#define PAES_MAX_KEYSIZE 256 +#define PAES_MIN_KEYSIZE 16 +#define PAES_MAX_KEYSIZE 320 static u8 *ctrblk; -static DEFINE_SPINLOCK(ctrblk_lock); +static DEFINE_MUTEX(ctrblk_lock); static cpacf_mask_t km_functions, kmc_functions, kmctr_functions; @@ -52,19 +53,46 @@ unsigned int keylen; }; -static inline int _copy_key_to_kb(struct key_blob *kb, - const u8 *key, - unsigned int keylen) -{ - if (keylen <= sizeof(kb->keybuf)) +static inline int _key_to_kb(struct key_blob *kb, + const u8 *key, + unsigned int keylen) +{ + struct clearkey_header { + u8 type; + u8 res0[3]; + u8 version; + u8 res1[3]; + u32 keytype; + u32 len; + } __packed * h; + + switch (keylen) { + case 16: + case 24: + case 32: + /* clear key value, prepare pkey clear key token in keybuf */ + memset(kb->keybuf, 0, sizeof(kb->keybuf)); + h = (struct clearkey_header *) kb->keybuf; + h->version = 0x02; /* TOKVER_CLEAR_KEY */ + h->keytype = (keylen - 8) >> 3; + h->len = keylen; + memcpy(kb->keybuf + sizeof(*h), key, keylen); + kb->keylen = sizeof(*h) + keylen; kb->key = kb->keybuf; - else { - kb->key = kmalloc(keylen, GFP_KERNEL); - if (!kb->key) - return -ENOMEM; + break; + default: + /* other key material, let pkey handle this */ + if (keylen <= sizeof(kb->keybuf)) + kb->key = kb->keybuf; + else { + kb->key = kmalloc(keylen, GFP_KERNEL); + if (!kb->key) + return -ENOMEM; + } + memcpy(kb->key, key, keylen); + kb->keylen = keylen; + break; } - memcpy(kb->key, key, keylen); - kb->keylen = keylen; return 0; } @@ -81,16 +109,18 @@ struct s390_paes_ctx { struct key_blob kb; struct pkey_protkey pk; + spinlock_t pk_lock; unsigned long fc; }; struct s390_pxts_ctx { struct key_blob kb[2]; struct pkey_protkey pk[2]; + spinlock_t pk_lock; unsigned long fc; }; -static inline int __paes_convert_key(struct key_blob *kb, +static inline int __paes_keyblob2pkey(struct key_blob *kb, struct pkey_protkey *pk) { int i, ret; @@ -105,22 +135,18 @@ return ret; } -static int __paes_set_key(struct s390_paes_ctx *ctx) +static inline int __paes_convert_key(struct s390_paes_ctx *ctx) { - unsigned long fc; + struct pkey_protkey pkey; - if (__paes_convert_key(&ctx->kb, &ctx->pk)) + if (__paes_keyblob2pkey(&ctx->kb, &pkey)) return -EINVAL; - /* Pick the correct function code based on the protected key type */ - fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 : - (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 : - (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0; - - /* Check if the function code is available */ - ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0; + spin_lock_bh(&ctx->pk_lock); + memcpy(&ctx->pk, &pkey, sizeof(pkey)); + spin_unlock_bh(&ctx->pk_lock); - return ctx->fc ? 0 : -EINVAL; + return 0; } static int ecb_paes_init(struct crypto_tfm *tfm) @@ -128,6 +154,7 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); ctx->kb.key = NULL; + spin_lock_init(&ctx->pk_lock); return 0; } @@ -139,6 +166,24 @@ _free_kb_keybuf(&ctx->kb); } +static inline int __ecb_paes_set_key(struct s390_paes_ctx *ctx) +{ + unsigned long fc; + + if (__paes_convert_key(ctx)) + return -EINVAL; + + /* Pick the correct function code based on the protected key type */ + fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 : + (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 : + (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0; + + /* Check if the function code is available */ + ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0; + + return ctx->fc ? 0 : -EINVAL; +} + static int ecb_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len) { @@ -146,13 +191,14 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); _free_kb_keybuf(&ctx->kb); - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); + rc = _key_to_kb(&ctx->kb, in_key, key_len); if (rc) return rc; - if (__paes_set_key(ctx)) { + if (__ecb_paes_set_key(ctx)) { tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; return -EINVAL; + } return 0; } @@ -164,18 +210,31 @@ struct s390_paes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); unsigned int nbytes, n, k; int ret; + struct { + u8 key[MAXPROTKEYSIZE]; + } param; ret = blkcipher_walk_virt(desc, walk); + if (ret) + return ret; + + spin_lock_bh(&ctx->pk_lock); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); + while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); - k = cpacf_km(ctx->fc | modifier, ctx->pk.protkey, + k = cpacf_km(ctx->fc | modifier, ¶m, walk->dst.virt.addr, walk->src.virt.addr, n); if (k) ret = blkcipher_walk_done(desc, walk, nbytes - k); if (k < n) { - if (__paes_set_key(ctx) != 0) + if (__paes_convert_key(ctx)) return blkcipher_walk_done(desc, walk, -EIO); + spin_lock_bh(&ctx->pk_lock); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); } } return ret; @@ -229,6 +288,7 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); ctx->kb.key = NULL; + spin_lock_init(&ctx->pk_lock); return 0; } @@ -240,11 +300,11 @@ _free_kb_keybuf(&ctx->kb); } -static int __cbc_paes_set_key(struct s390_paes_ctx *ctx) +static inline int __cbc_paes_set_key(struct s390_paes_ctx *ctx) { unsigned long fc; - if (__paes_convert_key(&ctx->kb, &ctx->pk)) + if (__paes_convert_key(ctx)) return -EINVAL; /* Pick the correct function code based on the protected key type */ @@ -265,7 +325,7 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); _free_kb_keybuf(&ctx->kb); - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); + rc = _key_to_kb(&ctx->kb, in_key, key_len); if (rc) return rc; @@ -288,22 +348,31 @@ } param; ret = blkcipher_walk_virt(desc, walk); + if (ret) + return ret; + memcpy(param.iv, walk->iv, AES_BLOCK_SIZE); + spin_lock_bh(&ctx->pk_lock); memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); + while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { /* only use complete blocks */ n = nbytes & ~(AES_BLOCK_SIZE - 1); k = cpacf_kmc(ctx->fc | modifier, ¶m, walk->dst.virt.addr, walk->src.virt.addr, n); - if (k) + if (k) { + memcpy(walk->iv, param.iv, AES_BLOCK_SIZE); ret = blkcipher_walk_done(desc, walk, nbytes - k); + } if (k < n) { - if (__cbc_paes_set_key(ctx) != 0) + if (__paes_convert_key(ctx)) return blkcipher_walk_done(desc, walk, -EIO); + spin_lock_bh(&ctx->pk_lock); memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); } } - memcpy(walk->iv, param.iv, AES_BLOCK_SIZE); return ret; } @@ -357,6 +426,7 @@ ctx->kb[0].key = NULL; ctx->kb[1].key = NULL; + spin_lock_init(&ctx->pk_lock); return 0; } @@ -369,12 +439,27 @@ _free_kb_keybuf(&ctx->kb[1]); } -static int __xts_paes_set_key(struct s390_pxts_ctx *ctx) +static inline int __xts_paes_convert_key(struct s390_pxts_ctx *ctx) +{ + struct pkey_protkey pkey0, pkey1; + + if (__paes_keyblob2pkey(&ctx->kb[0], &pkey0) || + __paes_keyblob2pkey(&ctx->kb[1], &pkey1)) + return -EINVAL; + + spin_lock_bh(&ctx->pk_lock); + memcpy(&ctx->pk[0], &pkey0, sizeof(pkey0)); + memcpy(&ctx->pk[1], &pkey1, sizeof(pkey1)); + spin_unlock_bh(&ctx->pk_lock); + + return 0; +} + +static inline int __xts_paes_set_key(struct s390_pxts_ctx *ctx) { unsigned long fc; - if (__paes_convert_key(&ctx->kb[0], &ctx->pk[0]) || - __paes_convert_key(&ctx->kb[1], &ctx->pk[1])) + if (__xts_paes_convert_key(ctx)) return -EINVAL; if (ctx->pk[0].type != ctx->pk[1].type) @@ -406,10 +491,10 @@ _free_kb_keybuf(&ctx->kb[0]); _free_kb_keybuf(&ctx->kb[1]); - rc = _copy_key_to_kb(&ctx->kb[0], in_key, key_len); + rc = _key_to_kb(&ctx->kb[0], in_key, key_len); if (rc) return rc; - rc = _copy_key_to_kb(&ctx->kb[1], in_key + key_len, key_len); + rc = _key_to_kb(&ctx->kb[1], in_key + key_len, key_len); if (rc) return rc; @@ -449,15 +534,19 @@ } xts_param; ret = blkcipher_walk_virt(desc, walk); + if (ret) + return ret; + keylen = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 48 : 64; offset = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 16 : 0; -retry: + memset(&pcc_param, 0, sizeof(pcc_param)); memcpy(pcc_param.tweak, walk->iv, sizeof(pcc_param.tweak)); + spin_lock_bh(&ctx->pk_lock); memcpy(pcc_param.key + offset, ctx->pk[1].protkey, keylen); - cpacf_pcc(ctx->fc, pcc_param.key + offset); - memcpy(xts_param.key + offset, ctx->pk[0].protkey, keylen); + spin_unlock_bh(&ctx->pk_lock); + cpacf_pcc(ctx->fc, pcc_param.key + offset); memcpy(xts_param.init, pcc_param.xts, 16); while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { @@ -468,11 +557,15 @@ if (k) ret = blkcipher_walk_done(desc, walk, nbytes - k); if (k < n) { - if (__xts_paes_set_key(ctx) != 0) + if (__xts_paes_convert_key(ctx)) return blkcipher_walk_done(desc, walk, -EIO); - goto retry; + spin_lock_bh(&ctx->pk_lock); + memcpy(xts_param.key + offset, + ctx->pk[0].protkey, keylen); + spin_unlock_bh(&ctx->pk_lock); } } + return ret; } @@ -525,6 +618,7 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); ctx->kb.key = NULL; + spin_lock_init(&ctx->pk_lock); return 0; } @@ -536,11 +630,11 @@ _free_kb_keybuf(&ctx->kb); } -static int __ctr_paes_set_key(struct s390_paes_ctx *ctx) +static inline int __ctr_paes_set_key(struct s390_paes_ctx *ctx) { unsigned long fc; - if (__paes_convert_key(&ctx->kb, &ctx->pk)) + if (__paes_convert_key(ctx)) return -EINVAL; /* Pick the correct function code based on the protected key type */ @@ -562,7 +656,7 @@ struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); _free_kb_keybuf(&ctx->kb); - rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); + rc = _key_to_kb(&ctx->kb, in_key, key_len); if (rc) return rc; @@ -595,47 +689,62 @@ u8 buf[AES_BLOCK_SIZE], *ctrptr; unsigned int nbytes, n, k; int ret, locked; - - locked = spin_trylock(&ctrblk_lock); + struct { + u8 key[MAXPROTKEYSIZE]; + } param; ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); + if (ret) + return ret; + + spin_lock_bh(&ctx->pk_lock); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); + + locked = mutex_trylock(&ctrblk_lock); + + while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { n = AES_BLOCK_SIZE; if (nbytes >= 2*AES_BLOCK_SIZE && locked) n = __ctrblk_init(ctrblk, walk->iv, nbytes); ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv; - k = cpacf_kmctr(ctx->fc | modifier, ctx->pk.protkey, - walk->dst.virt.addr, walk->src.virt.addr, - n, ctrptr); + k = cpacf_kmctr(ctx->fc | modifier, ¶m, walk->dst.virt.addr, + walk->src.virt.addr, n, ctrptr); if (k) { if (ctrptr == ctrblk) memcpy(walk->iv, ctrptr + k - AES_BLOCK_SIZE, AES_BLOCK_SIZE); crypto_inc(walk->iv, AES_BLOCK_SIZE); - ret = blkcipher_walk_done(desc, walk, nbytes - n); + ret = blkcipher_walk_done(desc, walk, nbytes - k); } if (k < n) { - if (__ctr_paes_set_key(ctx) != 0) { + if (__paes_convert_key(ctx)) { if (locked) - spin_unlock(&ctrblk_lock); + mutex_unlock(&ctrblk_lock); return blkcipher_walk_done(desc, walk, -EIO); } + spin_lock_bh(&ctx->pk_lock); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); } } if (locked) - spin_unlock(&ctrblk_lock); + mutex_unlock(&ctrblk_lock); /* * final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { while (1) { - if (cpacf_kmctr(ctx->fc | modifier, - ctx->pk.protkey, buf, + if (cpacf_kmctr(ctx->fc | modifier, ¶m, buf, walk->src.virt.addr, AES_BLOCK_SIZE, walk->iv) == AES_BLOCK_SIZE) break; - if (__ctr_paes_set_key(ctx) != 0) + if (__paes_convert_key(ctx)) return blkcipher_walk_done(desc, walk, -EIO); + spin_lock_bh(&ctx->pk_lock); + memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE); + spin_unlock_bh(&ctx->pk_lock); } memcpy(walk->dst.virt.addr, buf, nbytes); crypto_inc(walk->iv, AES_BLOCK_SIZE); @@ -697,12 +806,12 @@ static void paes_s390_fini(void) { - if (ctrblk) - free_page((unsigned long) ctrblk); __crypto_unregister_alg(&ctr_paes_alg); __crypto_unregister_alg(&xts_paes_alg); __crypto_unregister_alg(&cbc_paes_alg); __crypto_unregister_alg(&ecb_paes_alg); + if (ctrblk) + free_page((unsigned long) ctrblk); } static int __init paes_s390_init(void) @@ -740,14 +849,14 @@ if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_128) || cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_192) || cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_256)) { - ret = crypto_register_alg(&ctr_paes_alg); - if (ret) - goto out_err; ctrblk = (u8 *) __get_free_page(GFP_KERNEL); if (!ctrblk) { ret = -ENOMEM; goto out_err; } + ret = crypto_register_alg(&ctr_paes_alg); + if (ret) + goto out_err; } return 0; --- linux-oracle-5.4.0.orig/arch/s390/crypto/sha_common.c +++ linux-oracle-5.4.0/arch/s390/crypto/sha_common.c @@ -74,14 +74,17 @@ struct s390_sha_ctx *ctx = shash_desc_ctx(desc); unsigned int bsize = crypto_shash_blocksize(desc->tfm); u64 bits; - unsigned int n, mbl_offset; + unsigned int n; + int mbl_offset; n = ctx->count % bsize; bits = ctx->count * 8; - mbl_offset = s390_crypto_shash_parmsize(ctx->func) / sizeof(u32); + mbl_offset = s390_crypto_shash_parmsize(ctx->func); if (mbl_offset < 0) return -EINVAL; + mbl_offset = mbl_offset / sizeof(u32); + /* set total msg bit length (mbl) in CPACF parmblock */ switch (ctx->func) { case CPACF_KLMD_SHA_1: --- linux-oracle-5.4.0.orig/arch/s390/hypfs/hypfs_diag.c +++ linux-oracle-5.4.0/arch/s390/hypfs/hypfs_diag.c @@ -437,7 +437,7 @@ int rc; if (diag204_probe()) { - pr_err("The hardware system does not support hypfs\n"); + pr_info("The hardware system does not support hypfs\n"); return -ENODATA; } --- linux-oracle-5.4.0.orig/arch/s390/hypfs/hypfs_vm.c +++ linux-oracle-5.4.0/arch/s390/hypfs/hypfs_vm.c @@ -20,6 +20,7 @@ static char local_guest[] = " "; static char all_guests[] = "* "; +static char *all_groups = all_guests; static char *guest_query; struct diag2fc_data { @@ -62,10 +63,11 @@ memcpy(parm_list.userid, query, NAME_LEN); ASCEBC(parm_list.userid, NAME_LEN); - parm_list.addr = (unsigned long) addr ; + memcpy(parm_list.aci_grp, all_groups, NAME_LEN); + ASCEBC(parm_list.aci_grp, NAME_LEN); + parm_list.addr = (unsigned long)addr; parm_list.size = size; parm_list.fmt = 0x02; - memset(parm_list.aci_grp, 0x40, NAME_LEN); rc = -1; diag_stat_inc(DIAG_STAT_X2FC); --- linux-oracle-5.4.0.orig/arch/s390/hypfs/inode.c +++ linux-oracle-5.4.0/arch/s390/hypfs/inode.c @@ -501,9 +501,9 @@ hypfs_vm_exit(); fail_hypfs_diag_exit: hypfs_diag_exit(); + pr_err("Initialization of hypfs failed with rc=%i\n", rc); fail_dbfs_exit: hypfs_dbfs_exit(); - pr_err("Initialization of hypfs failed with rc=%i\n", rc); return rc; } device_initcall(hypfs_init) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/archrandom.h +++ linux-oracle-5.4.0/arch/s390/include/asm/archrandom.h @@ -2,7 +2,7 @@ /* * Kernel interface for the s390 arch_random_* functions * - * Copyright IBM Corp. 2017 + * Copyright IBM Corp. 2017, 2022 * * Author: Harald Freudenberger * @@ -14,47 +14,41 @@ #ifdef CONFIG_ARCH_RANDOM #include +#include #include +#include DECLARE_STATIC_KEY_FALSE(s390_arch_random_available); extern atomic64_t s390_arch_random_counter; -bool s390_arch_random_generate(u8 *buf, unsigned int nbytes); - -static inline bool arch_has_random(void) -{ - return false; -} - -static inline bool arch_has_random_seed(void) -{ - if (static_branch_likely(&s390_arch_random_available)) - return true; - return false; -} - -static inline bool arch_get_random_long(unsigned long *v) +static inline bool __must_check arch_get_random_long(unsigned long *v) { return false; } -static inline bool arch_get_random_int(unsigned int *v) +static inline bool __must_check arch_get_random_int(unsigned int *v) { return false; } -static inline bool arch_get_random_seed_long(unsigned long *v) +static inline bool __must_check arch_get_random_seed_long(unsigned long *v) { - if (static_branch_likely(&s390_arch_random_available)) { - return s390_arch_random_generate((u8 *)v, sizeof(*v)); + if (static_branch_likely(&s390_arch_random_available) && + in_task()) { + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); + atomic64_add(sizeof(*v), &s390_arch_random_counter); + return true; } return false; } -static inline bool arch_get_random_seed_int(unsigned int *v) +static inline bool __must_check arch_get_random_seed_int(unsigned int *v) { - if (static_branch_likely(&s390_arch_random_available)) { - return s390_arch_random_generate((u8 *)v, sizeof(*v)); + if (static_branch_likely(&s390_arch_random_available) && + in_task()) { + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); + atomic64_add(sizeof(*v), &s390_arch_random_counter); + return true; } return false; } --- linux-oracle-5.4.0.orig/arch/s390/include/asm/cpu_mf.h +++ linux-oracle-5.4.0/arch/s390/include/asm/cpu_mf.h @@ -109,7 +109,9 @@ unsigned int AS:2; /* 29-30 PSW address-space control */ unsigned int I:1; /* 31 entry valid or invalid */ unsigned int CL:2; /* 32-33 Configuration Level */ - unsigned int:14; + unsigned int H:1; /* 34 Host Indicator */ + unsigned int LS:1; /* 35 Limited Sampling */ + unsigned int:12; unsigned int prim_asn:16; /* primary ASN */ unsigned long long ia; /* Instruction Address */ unsigned long long gpp; /* Guest Program Parameter */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/ctl_reg.h +++ linux-oracle-5.4.0/arch/s390/include/asm/ctl_reg.h @@ -11,6 +11,8 @@ #include #define CR0_CLOCK_COMPARATOR_SIGN BIT(63 - 10) +#define CR0_FETCH_PROTECTION_OVERRIDE BIT(63 - 38) +#define CR0_STORAGE_PROTECTION_OVERRIDE BIT(63 - 39) #define CR0_EMERGENCY_SIGNAL_SUBMASK BIT(63 - 49) #define CR0_EXTERNAL_CALL_SUBMASK BIT(63 - 50) #define CR0_CLOCK_COMPARATOR_SUBMASK BIT(63 - 52) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/debug.h +++ linux-oracle-5.4.0/arch/s390/include/asm/debug.h @@ -4,8 +4,8 @@ * * Copyright IBM Corp. 1999, 2000 */ -#ifndef DEBUG_H -#define DEBUG_H +#ifndef _ASM_S390_DEBUG_H +#define _ASM_S390_DEBUG_H #include #include @@ -416,4 +416,4 @@ #define PRINT_FATAL(x...) printk(KERN_DEBUG PRINTK_HEADER x) #endif /* DASD_DEBUG */ -#endif /* DEBUG_H */ +#endif /* _ASM_S390_DEBUG_H */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/diag.h +++ linux-oracle-5.4.0/arch/s390/include/asm/diag.h @@ -298,10 +298,8 @@ union diag318_info { unsigned long val; struct { - unsigned int cpnc : 8; - unsigned int cpvc_linux : 24; - unsigned char cpvc_distro[3]; - unsigned char zero; + unsigned long cpnc : 8; + unsigned long cpvc : 56; }; }; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/facility.h +++ linux-oracle-5.4.0/arch/s390/include/asm/facility.h @@ -53,8 +53,10 @@ unsigned long facilities_als[] = { FACILITIES_ALS }; if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { - if (__test_facility(nr, &facilities_als)) - return 1; + if (__test_facility(nr, &facilities_als)) { + if (!__is_defined(__DECOMPRESSOR)) + return 1; + } } return __test_facility(nr, &S390_lowcore.stfle_fac_list); } --- linux-oracle-5.4.0.orig/arch/s390/include/asm/fpu/api.h +++ linux-oracle-5.4.0/arch/s390/include/asm/fpu/api.h @@ -76,7 +76,7 @@ #define KERNEL_VXR_HIGH (KERNEL_VXR_V16V23|KERNEL_VXR_V24V31) #define KERNEL_VXR (KERNEL_VXR_LOW|KERNEL_VXR_HIGH) -#define KERNEL_FPR (KERNEL_FPC|KERNEL_VXR_V0V7) +#define KERNEL_FPR (KERNEL_FPC|KERNEL_VXR_LOW) struct kernel_fpu; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/ftrace.h +++ linux-oracle-5.4.0/arch/s390/include/asm/ftrace.h @@ -27,6 +27,7 @@ extern char ftrace_graph_caller_end; extern unsigned long ftrace_plt; +extern void *ftrace_func; struct dyn_arch_ftrace { }; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/futex.h +++ linux-oracle-5.4.0/arch/s390/include/asm/futex.h @@ -16,7 +16,8 @@ "3: jl 1b\n" \ " lhi %0,0\n" \ "4: sacf 768\n" \ - EX_TABLE(0b,4b) EX_TABLE(2b,4b) EX_TABLE(3b,4b) \ + EX_TABLE(0b,4b) EX_TABLE(1b,4b) \ + EX_TABLE(2b,4b) EX_TABLE(3b,4b) \ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ "=m" (*uaddr) \ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ @@ -45,7 +46,7 @@ break; case FUTEX_OP_ANDN: __futex_atomic_op("lr %2,%1\nnr %2,%5\n", - ret, oldval, newval, uaddr, oparg); + ret, oldval, newval, uaddr, ~oparg); break; case FUTEX_OP_XOR: __futex_atomic_op("lr %2,%1\nxr %2,%5\n", --- linux-oracle-5.4.0.orig/arch/s390/include/asm/gmap.h +++ linux-oracle-5.4.0/arch/s390/include/asm/gmap.h @@ -9,6 +9,7 @@ #ifndef _ASM_S390_GMAP_H #define _ASM_S390_GMAP_H +#include #include /* Generic bits for GMAP notification on DAT table entry changes. */ @@ -31,6 +32,7 @@ * @table: pointer to the page directory * @asce: address space control element for gmap page table * @pfault_enabled: defines if pfaults are applicable for the guest + * @guest_handle: protected virtual machine handle for the ultravisor * @host_to_rmap: radix tree with gmap_rmap lists * @children: list of shadow gmap structures * @pt_list: list of all page tables used in the shadow guest address space @@ -54,6 +56,8 @@ unsigned long asce_end; void *private; bool pfault_enabled; + /* only set for protected virtual machines */ + unsigned long guest_handle; /* Additional data for shadow guest address spaces */ struct radix_tree_root host_to_rmap; struct list_head children; @@ -144,4 +148,6 @@ void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4], unsigned long gaddr, unsigned long vmaddr); +int gmap_mark_unmergeable(void); +void s390_reset_acc(struct mm_struct *mm); #endif /* _ASM_S390_GMAP_H */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/hugetlb.h +++ linux-oracle-5.4.0/arch/s390/include/asm/hugetlb.h @@ -35,9 +35,11 @@ static inline int prepare_hugepage_range(struct file *file, unsigned long addr, unsigned long len) { - if (len & ~HPAGE_MASK) + struct hstate *h = hstate_file(file); + + if (len & ~huge_page_mask(h)) return -EINVAL; - if (addr & ~HPAGE_MASK) + if (addr & ~huge_page_mask(h)) return -EINVAL; return 0; } --- linux-oracle-5.4.0.orig/arch/s390/include/asm/ipl.h +++ linux-oracle-5.4.0/arch/s390/include/asm/ipl.h @@ -21,6 +21,7 @@ struct ipl_pb0_common common; struct ipl_pb0_fcp fcp; struct ipl_pb0_ccw ccw; + struct ipl_pb0_nvme nvme; char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; }; } __packed __aligned(PAGE_SIZE); @@ -30,6 +31,11 @@ #define IPL_BP_FCP_LEN (sizeof(struct ipl_pl_hdr) + \ sizeof(struct ipl_pb0_fcp)) #define IPL_BP0_FCP_LEN (sizeof(struct ipl_pb0_fcp)) + +#define IPL_BP_NVME_LEN (sizeof(struct ipl_pl_hdr) + \ + sizeof(struct ipl_pb0_nvme)) +#define IPL_BP0_NVME_LEN (sizeof(struct ipl_pb0_nvme)) + #define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \ sizeof(struct ipl_pb0_ccw)) #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw)) @@ -59,6 +65,7 @@ IPL_TYPE_FCP = 4, IPL_TYPE_FCP_DUMP = 8, IPL_TYPE_NSS = 16, + IPL_TYPE_NVME = 32, }; struct ipl_info @@ -74,6 +81,10 @@ u64 lun; } fcp; struct { + u32 fid; + u32 nsid; + } nvme; + struct { char name[NSS_NAME_SIZE + 1]; } nss; } data; @@ -109,6 +120,7 @@ unsigned char flags, unsigned short cert); int ipl_report_add_certificate(struct ipl_report *report, void *key, unsigned long addr, unsigned long len); +bool ipl_get_secureboot(void); /* * DIAG 308 support --- linux-oracle-5.4.0.orig/arch/s390/include/asm/kexec.h +++ linux-oracle-5.4.0/arch/s390/include/asm/kexec.h @@ -9,6 +9,8 @@ #ifndef _S390_KEXEC_H #define _S390_KEXEC_H +#include + #include #include #include @@ -74,7 +76,21 @@ int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, unsigned long addr); +#define ARCH_HAS_KIMAGE_ARCH + +struct kimage_arch { + void *ipl_buf; +}; + extern const struct kexec_file_ops s390_kexec_image_ops; extern const struct kexec_file_ops s390_kexec_elf_ops; +#ifdef CONFIG_KEXEC_FILE +struct purgatory_info; +int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + Elf_Shdr *section, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif /*_S390_KEXEC_H */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/kprobes.h +++ linux-oracle-5.4.0/arch/s390/include/asm/kprobes.h @@ -54,7 +54,6 @@ struct arch_specific_insn { /* copy of original instruction */ kprobe_opcode_t *insn; - unsigned int is_ftrace_insn : 1; }; struct prev_kprobe { --- linux-oracle-5.4.0.orig/arch/s390/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/s390/include/asm/kvm_host.h @@ -31,12 +31,12 @@ #define KVM_USER_MEM_SLOTS 32 /* - * These seem to be used for allocating ->chip in the routing table, - * which we don't use. 4096 is an out-of-thin-air value. If we need - * to look at ->chip later on, we'll need to revisit this. + * These seem to be used for allocating ->chip in the routing table, which we + * don't use. 1 is as small as we can get to reduce the needed memory. If we + * need to look at ->chip later on, we'll need to revisit this. */ #define KVM_NR_IRQCHIPS 1 -#define KVM_IRQCHIP_NUM_PINS 4096 +#define KVM_IRQCHIP_NUM_PINS 1 #define KVM_HALT_POLL_NS_DEFAULT 50000 /* s390-specific vcpu->requests bit members */ @@ -122,6 +122,17 @@ __u32 reserved; }; +#define CR0_INITIAL_MASK (CR0_UNUSED_56 | CR0_INTERRUPT_KEY_SUBMASK | \ + CR0_MEASUREMENT_ALERT_SUBMASK) +#define CR14_INITIAL_MASK (CR14_UNUSED_32 | CR14_UNUSED_33 | \ + CR14_EXTERNAL_DAMAGE_SUBMASK) + +#define SIDAD_SIZE_MASK 0xff +#define sida_origin(sie_block) \ + ((sie_block)->sidad & PAGE_MASK) +#define sida_size(sie_block) \ + ((((sie_block)->sidad & SIDAD_SIZE_MASK) + 1) * PAGE_SIZE) + #define CPUSTAT_STOPPED 0x80000000 #define CPUSTAT_WAIT 0x10000000 #define CPUSTAT_ECALL_PEND 0x08000000 @@ -155,7 +166,13 @@ __u8 reserved08[4]; /* 0x0008 */ #define PROG_IN_SIE (1<<0) __u32 prog0c; /* 0x000c */ - __u8 reserved10[16]; /* 0x0010 */ + union { + __u8 reserved10[16]; /* 0x0010 */ + struct { + __u64 pv_handle_cpu; + __u64 pv_handle_config; + }; + }; #define PROG_BLOCK_SIE (1<<0) #define PROG_REQUEST (1<<1) atomic_t prog20; /* 0x0020 */ @@ -204,10 +221,23 @@ #define ICPT_PARTEXEC 0x38 #define ICPT_IOINST 0x40 #define ICPT_KSS 0x5c +#define ICPT_MCHKREQ 0x60 +#define ICPT_INT_ENABLE 0x64 +#define ICPT_PV_INSTR 0x68 +#define ICPT_PV_NOTIFY 0x6c +#define ICPT_PV_PREF 0x70 __u8 icptcode; /* 0x0050 */ __u8 icptstatus; /* 0x0051 */ __u16 ihcpu; /* 0x0052 */ - __u8 reserved54[2]; /* 0x0054 */ + __u8 reserved54; /* 0x0054 */ +#define IICTL_CODE_NONE 0x00 +#define IICTL_CODE_MCHK 0x01 +#define IICTL_CODE_EXT 0x02 +#define IICTL_CODE_IO 0x03 +#define IICTL_CODE_RESTART 0x04 +#define IICTL_CODE_SPECIFICATION 0x10 +#define IICTL_CODE_OPERAND 0x11 + __u8 iictl; /* 0x0055 */ __u16 ipa; /* 0x0056 */ __u32 ipb; /* 0x0058 */ __u32 scaoh; /* 0x005c */ @@ -228,9 +258,10 @@ #define ECB3_RI 0x01 __u8 ecb3; /* 0x0063 */ __u32 scaol; /* 0x0064 */ - __u8 reserved68; /* 0x0068 */ + __u8 sdf; /* 0x0068 */ __u8 epdx; /* 0x0069 */ - __u8 reserved6a[2]; /* 0x006a */ + __u8 cpnc; /* 0x006a */ + __u8 reserved6b; /* 0x006b */ __u32 todpr; /* 0x006c */ #define GISA_FORMAT1 0x00000001 __u32 gd; /* 0x0070 */ @@ -244,31 +275,58 @@ #define HPID_KVM 0x4 #define HPID_VSIE 0x5 __u8 hpid; /* 0x00b8 */ - __u8 reservedb9[11]; /* 0x00b9 */ - __u16 extcpuaddr; /* 0x00c4 */ - __u16 eic; /* 0x00c6 */ + __u8 reservedb9[7]; /* 0x00b9 */ + union { + struct { + __u32 eiparams; /* 0x00c0 */ + __u16 extcpuaddr; /* 0x00c4 */ + __u16 eic; /* 0x00c6 */ + }; + __u64 mcic; /* 0x00c0 */ + } __packed; __u32 reservedc8; /* 0x00c8 */ - __u16 pgmilc; /* 0x00cc */ - __u16 iprcc; /* 0x00ce */ - __u32 dxc; /* 0x00d0 */ - __u16 mcn; /* 0x00d4 */ - __u8 perc; /* 0x00d6 */ - __u8 peratmid; /* 0x00d7 */ + union { + struct { + __u16 pgmilc; /* 0x00cc */ + __u16 iprcc; /* 0x00ce */ + }; + __u32 edc; /* 0x00cc */ + } __packed; + union { + struct { + __u32 dxc; /* 0x00d0 */ + __u16 mcn; /* 0x00d4 */ + __u8 perc; /* 0x00d6 */ + __u8 peratmid; /* 0x00d7 */ + }; + __u64 faddr; /* 0x00d0 */ + } __packed; __u64 peraddr; /* 0x00d8 */ __u8 eai; /* 0x00e0 */ __u8 peraid; /* 0x00e1 */ __u8 oai; /* 0x00e2 */ __u8 armid; /* 0x00e3 */ __u8 reservede4[4]; /* 0x00e4 */ - __u64 tecmc; /* 0x00e8 */ - __u8 reservedf0[12]; /* 0x00f0 */ + union { + __u64 tecmc; /* 0x00e8 */ + struct { + __u16 subchannel_id; /* 0x00e8 */ + __u16 subchannel_nr; /* 0x00ea */ + __u32 io_int_parm; /* 0x00ec */ + __u32 io_int_word; /* 0x00f0 */ + }; + } __packed; + __u8 reservedf4[8]; /* 0x00f4 */ #define CRYCB_FORMAT_MASK 0x00000003 #define CRYCB_FORMAT0 0x00000000 #define CRYCB_FORMAT1 0x00000001 #define CRYCB_FORMAT2 0x00000003 __u32 crycbd; /* 0x00fc */ __u64 gcr[16]; /* 0x0100 */ - __u64 gbea; /* 0x0180 */ + union { + __u64 gbea; /* 0x0180 */ + __u64 sidad; + }; __u8 reserved188[8]; /* 0x0188 */ __u64 sdnxo; /* 0x0190 */ __u8 reserved198[8]; /* 0x0198 */ @@ -296,7 +354,9 @@ struct sie_page { struct kvm_s390_sie_block sie_block; struct mcck_volatile_info mcck_info; /* 0x0200 */ - __u8 reserved218[1000]; /* 0x0218 */ + __u8 reserved218[360]; /* 0x0218 */ + __u64 pv_grregs[16]; /* 0x0380 */ + __u8 reserved400[512]; /* 0x0400 */ struct kvm_s390_itdb itdb; /* 0x0600 */ __u8 reserved700[2304]; /* 0x0700 */ }; @@ -470,6 +530,7 @@ IRQ_PEND_PFAULT_INIT, IRQ_PEND_EXT_HOST, IRQ_PEND_EXT_SERVICE, + IRQ_PEND_EXT_SERVICE_EV, IRQ_PEND_EXT_TIMING, IRQ_PEND_EXT_CPU_TIMER, IRQ_PEND_EXT_CLOCK_COMP, @@ -514,6 +575,7 @@ (1UL << IRQ_PEND_EXT_TIMING) | \ (1UL << IRQ_PEND_EXT_HOST) | \ (1UL << IRQ_PEND_EXT_SERVICE) | \ + (1UL << IRQ_PEND_EXT_SERVICE_EV) | \ (1UL << IRQ_PEND_VIRTIO) | \ (1UL << IRQ_PEND_PFAULT_INIT) | \ (1UL << IRQ_PEND_PFAULT_DONE)) @@ -530,6 +592,13 @@ #define IRQ_PEND_MCHK_MASK ((1UL << IRQ_PEND_MCHK_REP) | \ (1UL << IRQ_PEND_MCHK_EX)) +#define IRQ_PEND_EXT_II_MASK ((1UL << IRQ_PEND_EXT_CPU_TIMER) | \ + (1UL << IRQ_PEND_EXT_CLOCK_COMP) | \ + (1UL << IRQ_PEND_EXT_EMERGENCY) | \ + (1UL << IRQ_PEND_EXT_EXTERNAL) | \ + (1UL << IRQ_PEND_EXT_SERVICE) | \ + (1UL << IRQ_PEND_EXT_SERVICE_EV)) + struct kvm_s390_interrupt_info { struct list_head list; u64 type; @@ -588,6 +657,7 @@ struct kvm_s390_float_interrupt { unsigned long pending_irqs; + unsigned long masked_irqs; spinlock_t lock; struct list_head lists[FIRQ_LIST_COUNT]; int counters[FIRQ_MAX_COUNT]; @@ -639,6 +709,11 @@ unsigned long last_bp; }; +struct kvm_s390_pv_vcpu { + u64 handle; + unsigned long stor_base; +}; + struct kvm_vcpu_arch { struct kvm_s390_sie_block *sie_block; /* if vsie is active, currently executed shadow sie control block */ @@ -667,6 +742,8 @@ __u64 cputm_start; bool gs_enabled; bool skey_enabled; + struct kvm_s390_pv_vcpu pv; + union diag318_info diag318_info; }; struct kvm_vm_stat { @@ -695,9 +772,6 @@ bool masked; bool swap; bool suppressible; - struct rw_semaphore maps_lock; - struct list_head maps; - atomic_t nr_maps; }; #define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) @@ -840,6 +914,13 @@ DECLARE_BITMAP(kicked_mask, KVM_MAX_VCPUS); }; +struct kvm_s390_pv { + u64 handle; + u64 guest_len; + unsigned long stor_base; + void *stor_var; +}; + struct kvm_arch{ void *sca; int use_esca; @@ -873,8 +954,10 @@ atomic64_t cmma_dirty_pages; /* subset of available cpu features enabled by user space */ DECLARE_BITMAP(cpu_feat, KVM_S390_VM_CPU_FEAT_NR_BITS); + /* indexed by vcpu_idx */ DECLARE_BITMAP(idle_mask, KVM_MAX_VCPUS); struct kvm_s390_gisa_interrupt gisa_int; + struct kvm_s390_pv pv; }; #define KVM_HVA_ERR_BAD (-1UL) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/lowcore.h +++ linux-oracle-5.4.0/arch/s390/include/asm/lowcore.h @@ -141,7 +141,9 @@ /* br %r1 trampoline */ __u16 br_r1_trampoline; /* 0x0400 */ - __u8 pad_0x0402[0x0e00-0x0402]; /* 0x0402 */ + __u32 return_lpswe; /* 0x0402 */ + __u32 return_mcck_lpswe; /* 0x0406 */ + __u8 pad_0x040a[0x0e00-0x040a]; /* 0x040a */ /* * 0xe00 contains the address of the IPL Parameter Information --- linux-oracle-5.4.0.orig/arch/s390/include/asm/mmu.h +++ linux-oracle-5.4.0/arch/s390/include/asm/mmu.h @@ -16,6 +16,8 @@ unsigned long asce; unsigned long asce_limit; unsigned long vdso_base; + /* The mmu context belongs to a secure guest. */ + atomic_t is_protected; /* * The following bitfields need a down_write on the mm * semaphore when they are written to. As they are only --- linux-oracle-5.4.0.orig/arch/s390/include/asm/mmu_context.h +++ linux-oracle-5.4.0/arch/s390/include/asm/mmu_context.h @@ -23,6 +23,7 @@ INIT_LIST_HEAD(&mm->context.gmap_list); cpumask_clear(&mm->context.cpu_attach_mask); atomic_set(&mm->context.flush_count, 0); + atomic_set(&mm->context.is_protected, 0); mm->context.gmap_asce = 0; mm->context.flush_mm = 0; mm->context.compat_mm = test_thread_flag(TIF_31BIT); --- linux-oracle-5.4.0.orig/arch/s390/include/asm/numa.h +++ linux-oracle-5.4.0/arch/s390/include/asm/numa.h @@ -17,7 +17,6 @@ void numa_setup(void); int numa_pfn_to_nid(unsigned long pfn); -int __node_distance(int a, int b); void numa_update_cpu_topology(void); extern cpumask_t node_to_cpumask_map[MAX_NUMNODES]; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/page.h +++ linux-oracle-5.4.0/arch/s390/include/asm/page.h @@ -20,6 +20,8 @@ #define PAGE_SIZE _PAGE_SIZE #define PAGE_MASK _PAGE_MASK #define PAGE_DEFAULT_ACC 0 +/* storage-protection override */ +#define PAGE_SPO_ACC 9 #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) #define HPAGE_SHIFT 20 @@ -33,6 +35,8 @@ #define ARCH_HAS_PREPARE_HUGEPAGE #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH +#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA + #include #ifndef __ASSEMBLY__ @@ -40,7 +44,7 @@ static inline void storage_key_init_range(unsigned long start, unsigned long end) { - if (PAGE_DEFAULT_KEY) + if (PAGE_DEFAULT_KEY != 0) __storage_key_init_range(start, end); } @@ -151,6 +155,11 @@ #define HAVE_ARCH_FREE_PAGE #define HAVE_ARCH_ALLOC_PAGE +#if IS_ENABLED(CONFIG_PGSTE) +int arch_make_page_accessible(struct page *page); +#define HAVE_ARCH_MAKE_PAGE_ACCESSIBLE +#endif + #endif /* !__ASSEMBLY__ */ #define __PAGE_OFFSET 0x0UL --- linux-oracle-5.4.0.orig/arch/s390/include/asm/pci.h +++ linux-oracle-5.4.0/arch/s390/include/asm/pci.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -24,10 +25,16 @@ int pci_proc_domain(struct pci_bus *); #define ZPCI_BUS_NR 0 /* default bus number */ -#define ZPCI_DEVFN 0 /* default device number */ #define ZPCI_NR_DMA_SPACES 1 #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS +#define ZPCI_DOMAIN_BITMAP_SIZE (1 << 16) + +#ifdef PCI +#if (ZPCI_NR_DEVICES > ZPCI_DOMAIN_BITMAP_SIZE) +# error ZPCI_NR_DEVICES can not be bigger than ZPCI_DOMAIN_BITMAP_SIZE +#endif +#endif /* PCI */ /* PCI Function Controls */ #define ZPCI_FC_FN_ENABLED 0x80 @@ -95,10 +102,26 @@ struct s390_domain; +#define ZPCI_FUNCTIONS_PER_BUS 256 +struct zpci_bus { + struct kref kref; + struct pci_bus *bus; + struct zpci_dev *function[ZPCI_FUNCTIONS_PER_BUS]; + struct list_head resources; + struct list_head bus_next; + int pchid; + int domain_nr; + bool multifunction; + enum pci_bus_speed max_bus_speed; +}; + /* Private data per function */ struct zpci_dev { - struct pci_bus *bus; + struct zpci_bus *zbus; struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */ + struct list_head bus_next; + struct kref kref; + struct hotplug_slot hotplug_slot; enum zpci_state state; u32 fid; /* function ID, used by sclp */ @@ -107,7 +130,12 @@ u16 pchid; /* physical channel ID */ u8 pfgid; /* function group ID */ u8 pft; /* pci function type */ - u16 domain; + u8 port; + u8 rid_available : 1; + u8 has_hp_slot : 1; + u8 is_physfn : 1; + u8 reserved : 5; + unsigned int devfn; /* DEVFN part of the RID*/ struct mutex lock; u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */ @@ -167,15 +195,19 @@ extern const struct attribute_group *zpci_attr_groups[]; extern unsigned int s390_pci_force_floating __initdata; +extern unsigned int s390_pci_no_rid; /* ----------------------------------------------------------------------------- Prototypes ----------------------------------------------------------------------------- */ /* Base stuff */ -int zpci_create_device(struct zpci_dev *); -void zpci_remove_device(struct zpci_dev *zdev); +int zpci_create_device(struct zpci_dev *zdev); +void zpci_remove_device(struct zpci_dev *zdev, bool set_error); int zpci_enable_device(struct zpci_dev *); int zpci_disable_device(struct zpci_dev *); +void zpci_device_reserved(struct zpci_dev *zdev); +bool zpci_is_device_configured(struct zpci_dev *zdev); + int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); int zpci_unregister_ioat(struct zpci_dev *, u8); void zpci_remove_reserved_devices(void); @@ -183,12 +215,15 @@ /* CLP */ int clp_scan_pci_devices(void); int clp_rescan_pci_devices(void); -int clp_rescan_pci_devices_simple(void); +int clp_rescan_pci_devices_simple(u32 *fid); int clp_add_pci_device(u32, u32, int); int clp_enable_fh(struct zpci_dev *, u8); int clp_disable_fh(struct zpci_dev *); int clp_get_state(u32 fid, enum zpci_state *state); +/* UID */ +void update_uid_checking(bool new); + /* IOMMU Interface */ int zpci_init_iommu(struct zpci_dev *zdev); void zpci_destroy_iommu(struct zpci_dev *zdev); @@ -224,7 +259,14 @@ /* Helpers */ static inline struct zpci_dev *to_zpci(struct pci_dev *pdev) { - return pdev->sysdata; + struct zpci_bus *zbus = pdev->sysdata; + + return zbus->function[pdev->devfn]; +} + +static inline struct zpci_dev *to_zpci_dev(struct device *dev) +{ + return to_zpci(to_pci_dev(dev)); } struct zpci_dev *get_zdev_by_fid(u32); --- linux-oracle-5.4.0.orig/arch/s390/include/asm/pci_clp.h +++ linux-oracle-5.4.0/arch/s390/include/asm/pci_clp.h @@ -93,7 +93,10 @@ struct clp_rsp_query_pci { struct clp_rsp_hdr hdr; u16 vfn; /* virtual fn number */ - u16 : 6; + u16 : 3; + u16 rid_avail : 1; + u16 is_physfn : 1; + u16 reserved1 : 1; u16 mio_addr_avail : 1; u16 util_str_avail : 1; /* utility string available? */ u16 pfgid : 8; /* pci function group id */ @@ -102,12 +105,16 @@ u16 pchid; __le32 bar[PCI_BAR_COUNT]; u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */ - u32 : 16; + u16 : 12; + u16 port : 4; u8 fmb_len; u8 pft; /* pci function type */ u64 sdma; /* start dma as */ u64 edma; /* end dma as */ - u32 reserved[11]; +#define ZPCI_RID_MASK_DEVFN 0x00ff + u16 rid; /* BUS/DEVFN PCI address */ + u16 reserved0; + u32 reserved[10]; u32 uid; /* user defined id */ u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */ u32 reserved2[16]; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/pci_io.h +++ linux-oracle-5.4.0/arch/s390/include/asm/pci_io.h @@ -8,14 +8,21 @@ #include #include +/* I/O size constraints */ +#define ZPCI_MAX_READ_SIZE 8 +#define ZPCI_MAX_WRITE_SIZE 128 +#define ZPCI_BOUNDARY_SIZE (1 << 12) +#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1) + /* I/O Map */ #define ZPCI_IOMAP_SHIFT 48 -#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL +#define ZPCI_IOMAP_ADDR_SHIFT 62 +#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT) #define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) #define ZPCI_IOMAP_MAX_ENTRIES \ - ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) + (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT)) #define ZPCI_IOMAP_ADDR_IDX_MASK \ - (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE) + ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK) struct zpci_iomap_entry { u32 fh; @@ -120,16 +127,18 @@ int zpci_write_block(volatile void __iomem *dst, const void *src, unsigned long len); -static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) +static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max) { - int count = len > max ? max : len, size = 1; + int offset = dst & ZPCI_BOUNDARY_MASK; + int size; - while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { - dst = dst >> 1; - src = src >> 1; - size = size << 1; - } - return size; + size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max); + if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8)) + return size; + + if (size >= 8) + return 8; + return rounddown_pow_of_two(size); } static inline int zpci_memcpy_fromio(void *dst, @@ -139,8 +148,9 @@ int size, rc = 0; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) src, - (u64) dst, n, 8); + size = zpci_get_max_io_size((u64 __force) src, + (u64) dst, n, + ZPCI_MAX_READ_SIZE); rc = zpci_read_single(dst, src, size); if (rc) break; @@ -160,8 +170,9 @@ return -EINVAL; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) dst, - (u64) src, n, 128); + size = zpci_get_max_io_size((u64 __force) dst, + (u64) src, n, + ZPCI_MAX_WRITE_SIZE); if (size > 8) /* main path */ rc = zpci_write_block(dst, src, size); else --- linux-oracle-5.4.0.orig/arch/s390/include/asm/percpu.h +++ linux-oracle-5.4.0/arch/s390/include/asm/percpu.h @@ -29,15 +29,15 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ old__, new__, prev__; \ pcp_op_T__ *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ - prev__ = *ptr__; \ + prev__ = READ_ONCE(*ptr__); \ do { \ old__ = prev__; \ new__ = old__ op (val); \ prev__ = cmpxchg(ptr__, old__, new__); \ } while (prev__ != old__); \ - preempt_enable(); \ + preempt_enable_notrace(); \ new__; \ }) @@ -68,7 +68,7 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ if (__builtin_constant_p(val__) && \ ((szcast)val__ > -129) && ((szcast)val__ < 128)) { \ @@ -84,7 +84,7 @@ : [val__] "d" (val__) \ : "cc"); \ } \ - preempt_enable(); \ + preempt_enable_notrace(); \ } #define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int) @@ -95,14 +95,14 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ asm volatile( \ op " %[old__],%[val__],%[ptr__]\n" \ : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ : [val__] "d" (val__) \ : "cc"); \ - preempt_enable(); \ + preempt_enable_notrace(); \ old__ + val__; \ }) @@ -114,14 +114,14 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ val__ = (val); \ pcp_op_T__ old__, *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ asm volatile( \ op " %[old__],%[val__],%[ptr__]\n" \ : [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \ : [val__] "d" (val__) \ : "cc"); \ - preempt_enable(); \ + preempt_enable_notrace(); \ } #define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, "lan") @@ -136,10 +136,10 @@ typedef typeof(pcp) pcp_op_T__; \ pcp_op_T__ ret__; \ pcp_op_T__ *ptr__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ ret__ = cmpxchg(ptr__, oval, nval); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ }) @@ -152,10 +152,10 @@ ({ \ typeof(pcp) *ptr__; \ typeof(pcp) ret__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ ptr__ = raw_cpu_ptr(&(pcp)); \ ret__ = xchg(ptr__, nval); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ }) @@ -171,11 +171,11 @@ typeof(pcp1) *p1__; \ typeof(pcp2) *p2__; \ int ret__; \ - preempt_disable(); \ + preempt_disable_notrace(); \ p1__ = raw_cpu_ptr(&(pcp1)); \ p2__ = raw_cpu_ptr(&(pcp2)); \ ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__); \ - preempt_enable(); \ + preempt_enable_notrace(); \ ret__; \ }) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/pgalloc.h +++ linux-oracle-5.4.0/arch/s390/include/asm/pgalloc.h @@ -56,7 +56,12 @@ crst_table_init(table, _REGION2_ENTRY_EMPTY); return (p4d_t *) table; } -#define p4d_free(mm, p4d) crst_table_free(mm, (unsigned long *) p4d) + +static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) +{ + if (!mm_p4d_folded(mm)) + crst_table_free(mm, (unsigned long *) p4d); +} static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) { @@ -65,7 +70,12 @@ crst_table_init(table, _REGION3_ENTRY_EMPTY); return (pud_t *) table; } -#define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud) + +static inline void pud_free(struct mm_struct *mm, pud_t *pud) +{ + if (!mm_pud_folded(mm)) + crst_table_free(mm, (unsigned long *) pud); +} static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) { @@ -83,6 +93,8 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) { + if (mm_pmd_folded(mm)) + return; pgtable_pmd_page_dtor(virt_to_page(pmd)); crst_table_free(mm, (unsigned long *) pmd); } --- linux-oracle-5.4.0.orig/arch/s390/include/asm/pgtable.h +++ linux-oracle-5.4.0/arch/s390/include/asm/pgtable.h @@ -19,6 +19,7 @@ #include #include #include +#include extern pgd_t swapper_pg_dir[]; extern void paging_init(void); @@ -522,6 +523,15 @@ return 0; } +static inline int mm_is_protected(struct mm_struct *mm) +{ +#ifdef CONFIG_PGSTE + if (unlikely(atomic_read(&mm->context.is_protected))) + return 1; +#endif + return 0; +} + static inline int mm_alloc_pgste(struct mm_struct *mm) { #ifdef CONFIG_PGSTE @@ -756,6 +766,12 @@ return (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE) != 0; } +#define pud_write pud_write +static inline int pud_write(pud_t pud) +{ + return (pud_val(pud) & _REGION3_ENTRY_WRITE) != 0; +} + static inline int pmd_dirty(pmd_t pmd) { int dirty = 1; @@ -1071,7 +1087,12 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); + pte_t res; + + res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); + if (mm_is_protected(mm) && pte_present(res)) + uv_convert_from_secure(pte_val(res) & PAGE_MASK); + return res; } #define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION @@ -1083,7 +1104,12 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - return ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID)); + pte_t res; + + res = ptep_xchg_direct(vma->vm_mm, addr, ptep, __pte(_PAGE_INVALID)); + if (mm_is_protected(vma->vm_mm) && pte_present(res)) + uv_convert_from_secure(pte_val(res) & PAGE_MASK); + return res; } /* @@ -1098,12 +1124,17 @@ unsigned long addr, pte_t *ptep, int full) { + pte_t res; + if (full) { - pte_t pte = *ptep; + res = *ptep; *ptep = __pte(_PAGE_INVALID); - return pte; + } else { + res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); } - return ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID)); + if (mm_is_protected(mm) && pte_present(res)) + uv_convert_from_secure(pte_val(res) & PAGE_MASK); + return res; } #define __HAVE_ARCH_PTEP_SET_WRPROTECT @@ -1173,8 +1204,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { - if (!MACHINE_HAS_NX) - pte_val(entry) &= ~_PAGE_NOEXEC; if (pte_present(entry)) pte_val(entry) &= ~_PAGE_UNUSED; if (mm_has_pgste(mm)) @@ -1191,6 +1220,8 @@ { pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); + if (!MACHINE_HAS_NX) + pte_val(__pte) &= ~_PAGE_NOEXEC; return pte_mkyoung(__pte); } @@ -1241,26 +1272,46 @@ #define pgd_offset(mm, address) pgd_offset_raw(READ_ONCE((mm)->pgd), address) #define pgd_offset_k(address) pgd_offset(&init_mm, address) -static inline p4d_t *p4d_offset(pgd_t *pgd, unsigned long address) +static inline p4d_t *p4d_offset_lockless(pgd_t *pgdp, pgd_t pgd, unsigned long address) +{ + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1) + return (p4d_t *) pgd_deref(pgd) + p4d_index(address); + return (p4d_t *) pgdp; +} +#define p4d_offset_lockless p4d_offset_lockless + +static inline p4d_t *p4d_offset(pgd_t *pgdp, unsigned long address) +{ + return p4d_offset_lockless(pgdp, *pgdp, address); +} + +static inline pud_t *pud_offset_lockless(p4d_t *p4dp, p4d_t p4d, unsigned long address) +{ + if ((p4d_val(p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2) + return (pud_t *) p4d_deref(p4d) + pud_index(address); + return (pud_t *) p4dp; +} +#define pud_offset_lockless pud_offset_lockless + +static inline pud_t *pud_offset(p4d_t *p4dp, unsigned long address) { - if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R1) - return (p4d_t *) pgd_deref(*pgd) + p4d_index(address); - return (p4d_t *) pgd; + return pud_offset_lockless(p4dp, *p4dp, address); } +#define pud_offset pud_offset -static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address) +static inline pmd_t *pmd_offset_lockless(pud_t *pudp, pud_t pud, unsigned long address) { - if ((p4d_val(*p4d) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R2) - return (pud_t *) p4d_deref(*p4d) + pud_index(address); - return (pud_t *) p4d; + if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3) + return (pmd_t *) pud_deref(pud) + pmd_index(address); + return (pmd_t *) pudp; } +#define pmd_offset_lockless pmd_offset_lockless -static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) +static inline pmd_t *pmd_offset(pud_t *pudp, unsigned long address) { - if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) >= _REGION_ENTRY_TYPE_R3) - return (pmd_t *) pud_deref(*pud) + pmd_index(address); - return (pmd_t *) pud; + return pmd_offset_lockless(pudp, *pudp, address); } +#define pmd_offset pmd_offset static inline pte_t *pte_offset(pmd_t *pmd, unsigned long address) { --- linux-oracle-5.4.0.orig/arch/s390/include/asm/preempt.h +++ linux-oracle-5.4.0/arch/s390/include/asm/preempt.h @@ -52,10 +52,17 @@ static inline void __preempt_count_add(int val) { - if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) - __atomic_add_const(val, &S390_lowcore.preempt_count); - else - __atomic_add(val, &S390_lowcore.preempt_count); + /* + * With some obscure config options and CONFIG_PROFILE_ALL_BRANCHES + * enabled, gcc 12 fails to handle __builtin_constant_p(). + */ + if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) { + if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) { + __atomic_add_const(val, &S390_lowcore.preempt_count); + return; + } + } + __atomic_add(val, &S390_lowcore.preempt_count); } static inline void __preempt_count_sub(int val) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/processor.h +++ linux-oracle-5.4.0/arch/s390/include/asm/processor.h @@ -162,6 +162,7 @@ #define INIT_THREAD { \ .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ .fpu.regs = (void *) init_task.thread.fpu.fprs, \ + .last_break = 1, \ } /* @@ -214,7 +215,7 @@ return sp; } -static __no_kasan_or_inline unsigned short stap(void) +static __always_inline unsigned short stap(void) { unsigned short cpu_address; @@ -253,10 +254,10 @@ * Set PSW mask to specified value, while leaving the * PSW addr pointing to the next instruction. */ -static __no_kasan_or_inline void __load_psw_mask(unsigned long mask) +static __always_inline void __load_psw_mask(unsigned long mask) { + psw_t psw __uninitialized; unsigned long addr; - psw_t psw; psw.mask = mask; --- linux-oracle-5.4.0.orig/arch/s390/include/asm/qdio.h +++ linux-oracle-5.4.0/arch/s390/include/asm/qdio.h @@ -227,7 +227,7 @@ * @sbal: absolute SBAL address */ struct sl_element { - unsigned long sbal; + u64 sbal; } __attribute__ ((packed)); /** --- linux-oracle-5.4.0.orig/arch/s390/include/asm/sclp.h +++ linux-oracle-5.4.0/arch/s390/include/asm/sclp.h @@ -129,6 +129,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info); int sclp_pci_configure(u32 fid); int sclp_pci_deconfigure(u32 fid); +int sclp_ap_configure(u32 apid); +int sclp_ap_deconfigure(u32 apid); int sclp_pci_report(struct zpci_report_error_header *report, u32 fh, u32 fid); int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); --- linux-oracle-5.4.0.orig/arch/s390/include/asm/setup.h +++ linux-oracle-5.4.0/arch/s390/include/asm/setup.h @@ -8,6 +8,7 @@ #include #include +#include #define EP_OFFSET 0x10008 #define EP_STRING "S390EP" @@ -38,6 +39,7 @@ #define MACHINE_FLAG_NX BIT(15) #define MACHINE_FLAG_GS BIT(16) #define MACHINE_FLAG_SCC BIT(17) +#define MACHINE_FLAG_PCI_MIO BIT(18) #define LPP_MAGIC BIT(31) #define LPP_PID_MASK _AC(0xffffffff, UL) @@ -80,6 +82,13 @@ char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */ }; +extern unsigned int zlib_dfltcc_support; +#define ZLIB_DFLTCC_DISABLED 0 +#define ZLIB_DFLTCC_FULL 1 +#define ZLIB_DFLTCC_DEFLATE_ONLY 2 +#define ZLIB_DFLTCC_INFLATE_ONLY 3 +#define ZLIB_DFLTCC_FULL_DEBUG 4 + extern int noexec_disabled; extern int memory_end_set; extern unsigned long memory_end; @@ -105,6 +114,7 @@ #define MACHINE_HAS_NX (S390_lowcore.machine_flags & MACHINE_FLAG_NX) #define MACHINE_HAS_GS (S390_lowcore.machine_flags & MACHINE_FLAG_GS) #define MACHINE_HAS_SCC (S390_lowcore.machine_flags & MACHINE_FLAG_SCC) +#define MACHINE_HAS_PCI_MIO (S390_lowcore.machine_flags & MACHINE_FLAG_PCI_MIO) /* * Console mode. Override with conmode= @@ -157,6 +167,12 @@ return __kaslr_offset; } +static inline u32 gen_lpswe(unsigned long addr) +{ + BUILD_BUG_ON(addr > 0xfff); + return 0xb2b20000 | addr; +} + #else /* __ASSEMBLY__ */ #define IPL_DEVICE (IPL_DEVICE_OFFSET) --- linux-oracle-5.4.0.orig/arch/s390/include/asm/stacktrace.h +++ linux-oracle-5.4.0/arch/s390/include/asm/stacktrace.h @@ -79,12 +79,16 @@ CALL_ARGS_4(arg1, arg2, arg3, arg4); \ register unsigned long r4 asm("6") = (unsigned long)(arg5) -#define CALL_FMT_0 "=&d" (r2) : -#define CALL_FMT_1 "+&d" (r2) : -#define CALL_FMT_2 CALL_FMT_1 "d" (r3), -#define CALL_FMT_3 CALL_FMT_2 "d" (r4), -#define CALL_FMT_4 CALL_FMT_3 "d" (r5), -#define CALL_FMT_5 CALL_FMT_4 "d" (r6), +/* + * To keep this simple mark register 2-6 as being changed (volatile) + * by the called function, even though register 6 is saved/nonvolatile. + */ +#define CALL_FMT_0 "=&d" (r2) +#define CALL_FMT_1 "+&d" (r2) +#define CALL_FMT_2 CALL_FMT_1, "+&d" (r3) +#define CALL_FMT_3 CALL_FMT_2, "+&d" (r4) +#define CALL_FMT_4 CALL_FMT_3, "+&d" (r5) +#define CALL_FMT_5 CALL_FMT_4, "+&d" (r6) #define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory" #define CALL_CLOBBER_4 CALL_CLOBBER_5 @@ -105,10 +109,118 @@ " brasl 14,%[_fn]\n" \ " la 15,0(%[_prev])\n" \ : [_prev] "=&a" (prev), CALL_FMT_##nr \ - [_stack] "a" (stack), \ + : [_stack] "a" (stack), \ [_bc] "i" (offsetof(struct stack_frame, back_chain)), \ [_fn] "X" (fn) : CALL_CLOBBER_##nr); \ r2; \ }) +#define CALL_LARGS_0(...) \ + long dummy = 0 +#define CALL_LARGS_1(t1, a1) \ + long arg1 = (long)(t1)(a1) +#define CALL_LARGS_2(t1, a1, t2, a2) \ + CALL_LARGS_1(t1, a1); \ + long arg2 = (long)(t2)(a2) +#define CALL_LARGS_3(t1, a1, t2, a2, t3, a3) \ + CALL_LARGS_2(t1, a1, t2, a2); \ + long arg3 = (long)(t3)(a3) +#define CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4) \ + CALL_LARGS_3(t1, a1, t2, a2, t3, a3); \ + long arg4 = (long)(t4)(a4) +#define CALL_LARGS_5(t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \ + CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4); \ + long arg5 = (long)(t5)(a5) + +#define CALL_REGS_0 \ + register long r2 asm("2") = dummy +#define CALL_REGS_1 \ + register long r2 asm("2") = arg1 +#define CALL_REGS_2 \ + CALL_REGS_1; \ + register long r3 asm("3") = arg2 +#define CALL_REGS_3 \ + CALL_REGS_2; \ + register long r4 asm("4") = arg3 +#define CALL_REGS_4 \ + CALL_REGS_3; \ + register long r5 asm("5") = arg4 +#define CALL_REGS_5 \ + CALL_REGS_4; \ + register long r6 asm("6") = arg5 + +#define CALL_TYPECHECK_0(...) +#define CALL_TYPECHECK_1(t, a, ...) \ + typecheck(t, a) +#define CALL_TYPECHECK_2(t, a, ...) \ + CALL_TYPECHECK_1(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_3(t, a, ...) \ + CALL_TYPECHECK_2(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_4(t, a, ...) \ + CALL_TYPECHECK_3(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_5(t, a, ...) \ + CALL_TYPECHECK_4(__VA_ARGS__); \ + typecheck(t, a) + +#define CALL_PARM_0(...) void +#define CALL_PARM_1(t, a, ...) t +#define CALL_PARM_2(t, a, ...) t, CALL_PARM_1(__VA_ARGS__) +#define CALL_PARM_3(t, a, ...) t, CALL_PARM_2(__VA_ARGS__) +#define CALL_PARM_4(t, a, ...) t, CALL_PARM_3(__VA_ARGS__) +#define CALL_PARM_5(t, a, ...) t, CALL_PARM_4(__VA_ARGS__) +#define CALL_PARM_6(t, a, ...) t, CALL_PARM_5(__VA_ARGS__) + +/* + * Use call_on_stack() to call a function switching to a specified + * stack. Proper sign and zero extension of function arguments is + * done. Usage: + * + * rc = call_on_stack(nr, stack, rettype, fn, t1, a1, t2, a2, ...) + * + * - nr specifies the number of function arguments of fn. + * - stack specifies the stack to be used. + * - fn is the function to be called. + * - rettype is the return type of fn. + * - t1, a1, ... are pairs, where t1 must match the type of the first + * argument of fn, t2 the second, etc. a1 is the corresponding + * first function argument (not name), etc. + */ +#define call_on_stack(nr, stack, rettype, fn, ...) \ +({ \ + rettype (*__fn)(CALL_PARM_##nr(__VA_ARGS__)) = fn; \ + unsigned long frame = current_frame_address(); \ + unsigned long __stack = stack; \ + unsigned long prev; \ + CALL_LARGS_##nr(__VA_ARGS__); \ + CALL_REGS_##nr; \ + \ + CALL_TYPECHECK_##nr(__VA_ARGS__); \ + asm volatile( \ + " lgr %[_prev],15\n" \ + " lg 15,%[_stack]\n" \ + " stg %[_frame],%[_bc](15)\n" \ + " brasl 14,%[_fn]\n" \ + " lgr 15,%[_prev]\n" \ + : [_prev] "=&d" (prev), CALL_FMT_##nr \ + : [_stack] "R" (__stack), \ + [_bc] "i" (offsetof(struct stack_frame, back_chain)), \ + [_frame] "d" (frame), \ + [_fn] "X" (__fn) : CALL_CLOBBER_##nr); \ + (rettype)r2; \ +}) + +#define CALL_ON_STACK_NORETURN(fn, stack) \ +({ \ + asm volatile( \ + " la 15,0(%[_stack])\n" \ + " xc %[_bc](8,15),%[_bc](15)\n" \ + " brasl 14,%[_fn]\n" \ + ::[_bc] "i" (offsetof(struct stack_frame, back_chain)), \ + [_stack] "a" (stack), [_fn] "X" (fn)); \ + BUG(); \ +}) + #endif /* _ASM_S390_STACKTRACE_H */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/syscall.h +++ linux-oracle-5.4.0/arch/s390/include/asm/syscall.h @@ -33,7 +33,17 @@ static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { - return IS_ERR_VALUE(regs->gprs[2]) ? regs->gprs[2] : 0; + unsigned long error = regs->gprs[2]; +#ifdef CONFIG_COMPAT + if (test_tsk_thread_flag(task, TIF_31BIT)) { + /* + * Sign-extend the value so (int)-EFOO becomes (long)-EFOO + * and will match correctly in comparisons. + */ + error = (long)(int)error; + } +#endif + return IS_ERR_VALUE(error) ? error : 0; } static inline long syscall_get_return_value(struct task_struct *task, --- linux-oracle-5.4.0.orig/arch/s390/include/asm/timex.h +++ linux-oracle-5.4.0/arch/s390/include/asm/timex.h @@ -10,8 +10,9 @@ #ifndef _ASM_S390_TIMEX_H #define _ASM_S390_TIMEX_H -#include +#include #include +#include /* The value of the TOD clock for 1.1.1970. */ #define TOD_UNIX_EPOCH 0x7d91048bca000000ULL @@ -154,7 +155,7 @@ static inline unsigned long long get_tod_clock(void) { - unsigned char clk[STORE_CLOCK_EXT_SIZE]; + char clk[STORE_CLOCK_EXT_SIZE]; get_tod_clock_ext(clk); return *((unsigned long long *)&clk[1]); @@ -176,6 +177,7 @@ { return (cycles_t) get_tod_clock() >> 2; } +#define get_cycles get_cycles int get_phys_clock(unsigned long *clock); void init_cpu_timer(void); @@ -186,15 +188,18 @@ /** * get_clock_monotonic - returns current time in clock rate units * - * The caller must ensure that preemption is disabled. * The clock and tod_clock_base get changed via stop_machine. - * Therefore preemption must be disabled when calling this - * function, otherwise the returned value is not guaranteed to - * be monotonic. + * Therefore preemption must be disabled, otherwise the returned + * value is not guaranteed to be monotonic. */ static inline unsigned long long get_tod_clock_monotonic(void) { - return get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; + unsigned long long tod; + + preempt_disable_notrace(); + tod = get_tod_clock() - *(unsigned long long *) &tod_clock_base[1]; + preempt_enable_notrace(); + return tod; } /** --- linux-oracle-5.4.0.orig/arch/s390/include/asm/topology.h +++ linux-oracle-5.4.0/arch/s390/include/asm/topology.h @@ -68,11 +68,8 @@ #ifdef CONFIG_NUMA -#define cpu_to_node cpu_to_node -static inline int cpu_to_node(int cpu) -{ - return cpu_topology[cpu].node_id; -} +extern int __cpu_to_node(int cpu); +#define cpu_to_node __cpu_to_node /* Returns a pointer to the cpumask of CPUs on node 'node'. */ #define cpumask_of_node cpumask_of_node @@ -83,8 +80,6 @@ #define pcibus_to_node(bus) __pcibus_to_node(bus) -#define node_distance(a, b) __node_distance(a, b) - #else /* !CONFIG_NUMA */ #define numa_node_id numa_node_id --- linux-oracle-5.4.0.orig/arch/s390/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/s390/include/asm/uaccess.h @@ -60,54 +60,109 @@ #define INLINE_COPY_TO_USER #endif +unsigned long __must_check +_copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key); + +static __always_inline unsigned long __must_check +copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key) +{ + if (likely(check_copy_size(to, n, false))) + n = _copy_from_user_key(to, from, n, key); + return n; +} + +unsigned long __must_check +_copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key); + +static __always_inline unsigned long __must_check +copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key) +{ + if (likely(check_copy_size(from, n, true))) + n = _copy_to_user_key(to, from, n, key); + return n; +} + +union oac { + unsigned int val; + struct { + struct { + unsigned short key : 4; + unsigned short : 4; + unsigned short as : 2; + unsigned short : 4; + unsigned short k : 1; + unsigned short a : 1; + } oac1; + struct { + unsigned short key : 4; + unsigned short : 4; + unsigned short as : 2; + unsigned short : 4; + unsigned short k : 1; + unsigned short a : 1; + } oac2; + }; +}; + #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES -#define __put_get_user_asm(to, from, size, spec) \ -({ \ - register unsigned long __reg0 asm("0") = spec; \ - int __rc; \ - \ - asm volatile( \ - "0: mvcos %1,%3,%2\n" \ - "1: xr %0,%0\n" \ - "2:\n" \ - ".pushsection .fixup, \"ax\"\n" \ - "3: lhi %0,%5\n" \ - " jg 2b\n" \ - ".popsection\n" \ - EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ - : "=d" (__rc), "+Q" (*(to)) \ - : "d" (size), "Q" (*(from)), \ - "d" (__reg0), "K" (-EFAULT) \ - : "cc"); \ - __rc; \ +#define __put_get_user_asm(to, from, size, oac_spec) \ +({ \ + int __rc; \ + \ + asm volatile( \ + " lr 0,%[spec]\n" \ + "0: mvcos %[_to],%[_from],%[_size]\n" \ + "1: xr %[rc],%[rc]\n" \ + "2:\n" \ + ".pushsection .fixup, \"ax\"\n" \ + "3: lhi %[rc],%[retval]\n" \ + " jg 2b\n" \ + ".popsection\n" \ + EX_TABLE(0b,3b) EX_TABLE(1b,3b) \ + : [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \ + : [_size] "d" (size), [_from] "Q" (*(from)), \ + [retval] "K" (-EFAULT), [spec] "d" (oac_spec.val) \ + : "cc", "0"); \ + __rc; \ }) +#define __put_user_asm(to, from, size) \ + __put_get_user_asm(to, from, size, ((union oac) { \ + .oac1.as = PSW_BITS_AS_PRIMARY, \ + .oac1.a = 1 \ + })) + +#define __get_user_asm(to, from, size) \ + __put_get_user_asm(to, from, size, ((union oac) { \ + .oac2.as = PSW_BITS_AS_PRIMARY, \ + .oac2.a = 1 \ + })) \ + static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) { - unsigned long spec = 0x010000UL; int rc; switch (size) { case 1: - rc = __put_get_user_asm((unsigned char __user *)ptr, - (unsigned char *)x, - size, spec); + rc = __put_user_asm((unsigned char __user *)ptr, + (unsigned char *)x, + size); break; case 2: - rc = __put_get_user_asm((unsigned short __user *)ptr, - (unsigned short *)x, - size, spec); + rc = __put_user_asm((unsigned short __user *)ptr, + (unsigned short *)x, + size); break; case 4: - rc = __put_get_user_asm((unsigned int __user *)ptr, - (unsigned int *)x, - size, spec); + rc = __put_user_asm((unsigned int __user *)ptr, + (unsigned int *)x, + size); break; case 8: - rc = __put_get_user_asm((unsigned long __user *)ptr, - (unsigned long *)x, - size, spec); + rc = __put_user_asm((unsigned long __user *)ptr, + (unsigned long *)x, + size); break; } return rc; @@ -115,29 +170,28 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size) { - unsigned long spec = 0x01UL; int rc; switch (size) { case 1: - rc = __put_get_user_asm((unsigned char *)x, - (unsigned char __user *)ptr, - size, spec); + rc = __get_user_asm((unsigned char *)x, + (unsigned char __user *)ptr, + size); break; case 2: - rc = __put_get_user_asm((unsigned short *)x, - (unsigned short __user *)ptr, - size, spec); + rc = __get_user_asm((unsigned short *)x, + (unsigned short __user *)ptr, + size); break; case 4: - rc = __put_get_user_asm((unsigned int *)x, - (unsigned int __user *)ptr, - size, spec); + rc = __get_user_asm((unsigned int *)x, + (unsigned int __user *)ptr, + size); break; case 8: - rc = __put_get_user_asm((unsigned long *)x, - (unsigned long __user *)ptr, - size, spec); + rc = __get_user_asm((unsigned long *)x, + (unsigned long __user *)ptr, + size); break; } return rc; @@ -276,6 +330,6 @@ } int copy_to_user_real(void __user *dest, void *src, unsigned long count); -void s390_kernel_write(void *dst, const void *src, size_t size); +void *s390_kernel_write(void *dst, const void *src, size_t size); #endif /* __S390_UACCESS_H */ --- linux-oracle-5.4.0.orig/arch/s390/include/asm/uv.h +++ linux-oracle-5.4.0/arch/s390/include/asm/uv.h @@ -14,23 +14,67 @@ #include #include #include +#include #include +#include + +#define UVC_CC_OK 0 +#define UVC_CC_ERROR 1 +#define UVC_CC_BUSY 2 +#define UVC_CC_PARTIAL 3 #define UVC_RC_EXECUTED 0x0001 #define UVC_RC_INV_CMD 0x0002 #define UVC_RC_INV_STATE 0x0003 #define UVC_RC_INV_LEN 0x0005 #define UVC_RC_NO_RESUME 0x0007 +#define UVC_RC_NEED_DESTROY 0x8000 #define UVC_CMD_QUI 0x0001 +#define UVC_CMD_INIT_UV 0x000f +#define UVC_CMD_CREATE_SEC_CONF 0x0100 +#define UVC_CMD_DESTROY_SEC_CONF 0x0101 +#define UVC_CMD_CREATE_SEC_CPU 0x0120 +#define UVC_CMD_DESTROY_SEC_CPU 0x0121 +#define UVC_CMD_CONV_TO_SEC_STOR 0x0200 +#define UVC_CMD_CONV_FROM_SEC_STOR 0x0201 +#define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300 +#define UVC_CMD_UNPACK_IMG 0x0301 +#define UVC_CMD_VERIFY_IMG 0x0302 +#define UVC_CMD_CPU_RESET 0x0310 +#define UVC_CMD_CPU_RESET_INITIAL 0x0311 +#define UVC_CMD_PREPARE_RESET 0x0320 +#define UVC_CMD_CPU_RESET_CLEAR 0x0321 +#define UVC_CMD_CPU_SET_STATE 0x0330 +#define UVC_CMD_SET_UNSHARE_ALL 0x0340 +#define UVC_CMD_PIN_PAGE_SHARED 0x0341 +#define UVC_CMD_UNPIN_PAGE_SHARED 0x0342 #define UVC_CMD_SET_SHARED_ACCESS 0x1000 #define UVC_CMD_REMOVE_SHARED_ACCESS 0x1001 /* Bits in installed uv calls */ enum uv_cmds_inst { BIT_UVC_CMD_QUI = 0, + BIT_UVC_CMD_INIT_UV = 1, + BIT_UVC_CMD_CREATE_SEC_CONF = 2, + BIT_UVC_CMD_DESTROY_SEC_CONF = 3, + BIT_UVC_CMD_CREATE_SEC_CPU = 4, + BIT_UVC_CMD_DESTROY_SEC_CPU = 5, + BIT_UVC_CMD_CONV_TO_SEC_STOR = 6, + BIT_UVC_CMD_CONV_FROM_SEC_STOR = 7, BIT_UVC_CMD_SET_SHARED_ACCESS = 8, BIT_UVC_CMD_REMOVE_SHARED_ACCESS = 9, + BIT_UVC_CMD_SET_SEC_PARMS = 11, + BIT_UVC_CMD_UNPACK_IMG = 13, + BIT_UVC_CMD_VERIFY_IMG = 14, + BIT_UVC_CMD_CPU_RESET = 15, + BIT_UVC_CMD_CPU_RESET_INITIAL = 16, + BIT_UVC_CMD_CPU_SET_STATE = 17, + BIT_UVC_CMD_PREPARE_RESET = 18, + BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET = 19, + BIT_UVC_CMD_UNSHARE_ALL = 20, + BIT_UVC_CMD_PIN_PAGE_SHARED = 21, + BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, }; struct uv_cb_header { @@ -40,13 +84,127 @@ u16 rrc; /* Return Reason Code */ } __packed __aligned(8); +/* Query Ultravisor Information */ struct uv_cb_qui { struct uv_cb_header header; u64 reserved08; u64 inst_calls_list[4]; - u64 reserved30[15]; + u64 reserved30[2]; + u64 uv_base_stor_len; + u64 reserved48; + u64 conf_base_phys_stor_len; + u64 conf_base_virt_stor_len; + u64 conf_virt_var_stor_len; + u64 cpu_stor_len; + u32 reserved70[3]; + u32 max_num_sec_conf; + u64 max_guest_stor_addr; + u8 reserved88[158 - 136]; + u16 max_guest_cpus; + u8 reserveda0[200 - 160]; +} __packed __aligned(8); + +/* Initialize Ultravisor */ +struct uv_cb_init { + struct uv_cb_header header; + u64 reserved08[2]; + u64 stor_origin; + u64 stor_len; + u64 reserved28[4]; +} __packed __aligned(8); + +/* Create Guest Configuration */ +struct uv_cb_cgc { + struct uv_cb_header header; + u64 reserved08[2]; + u64 guest_handle; + u64 conf_base_stor_origin; + u64 conf_virt_stor_origin; + u64 reserved30; + u64 guest_stor_origin; + u64 guest_stor_len; + u64 guest_sca; + u64 guest_asce; + u64 reserved58[5]; +} __packed __aligned(8); + +/* Create Secure CPU */ +struct uv_cb_csc { + struct uv_cb_header header; + u64 reserved08[2]; + u64 cpu_handle; + u64 guest_handle; + u64 stor_origin; + u8 reserved30[6]; + u16 num; + u64 state_origin; + u64 reserved40[4]; +} __packed __aligned(8); + +/* Convert to Secure */ +struct uv_cb_cts { + struct uv_cb_header header; + u64 reserved08[2]; + u64 guest_handle; + u64 gaddr; +} __packed __aligned(8); + +/* Convert from Secure / Pin Page Shared */ +struct uv_cb_cfs { + struct uv_cb_header header; + u64 reserved08[2]; + u64 paddr; +} __packed __aligned(8); + +/* Set Secure Config Parameter */ +struct uv_cb_ssc { + struct uv_cb_header header; + u64 reserved08[2]; + u64 guest_handle; + u64 sec_header_origin; + u32 sec_header_len; + u32 reserved2c; + u64 reserved30[4]; } __packed __aligned(8); +/* Unpack */ +struct uv_cb_unp { + struct uv_cb_header header; + u64 reserved08[2]; + u64 guest_handle; + u64 gaddr; + u64 tweak[2]; + u64 reserved38[3]; +} __packed __aligned(8); + +#define PV_CPU_STATE_OPR 1 +#define PV_CPU_STATE_STP 2 +#define PV_CPU_STATE_CHKSTP 3 +#define PV_CPU_STATE_OPR_LOAD 5 + +struct uv_cb_cpu_set_state { + struct uv_cb_header header; + u64 reserved08[2]; + u64 cpu_handle; + u8 reserved20[7]; + u8 state; + u64 reserved28[5]; +}; + +/* + * A common UV call struct for calls that take no payload + * Examples: + * Destroy cpu/config + * Verify + */ +struct uv_cb_nodata { + struct uv_cb_header header; + u64 reserved08[2]; + u64 handle; + u64 reserved20[4]; +} __packed __aligned(8); + +/* Set Shared Access */ struct uv_cb_share { struct uv_cb_header header; u64 reserved08[3]; @@ -54,21 +212,76 @@ u64 reserved28; } __packed __aligned(8); -static inline int uv_call(unsigned long r1, unsigned long r2) +static inline int __uv_call(unsigned long r1, unsigned long r2) { int cc; asm volatile( - "0: .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" - " brc 3,0b\n" - " ipm %[cc]\n" - " srl %[cc],28\n" + " .insn rrf,0xB9A40000,%[r1],%[r2],0,0\n" + " ipm %[cc]\n" + " srl %[cc],28\n" : [cc] "=d" (cc) : [r1] "a" (r1), [r2] "a" (r2) : "memory", "cc"); return cc; } +static inline int uv_call(unsigned long r1, unsigned long r2) +{ + int cc; + + do { + cc = __uv_call(r1, r2); + } while (cc > 1); + return cc; +} + +/* Low level uv_call that avoids stalls for long running busy conditions */ +static inline int uv_call_sched(unsigned long r1, unsigned long r2) +{ + int cc; + + do { + cc = __uv_call(r1, r2); + cond_resched(); + } while (cc > 1); + return cc; +} + +/* + * special variant of uv_call that only transports the cpu or guest + * handle and the command, like destroy or verify. + */ +static inline int uv_cmd_nodata(u64 handle, u16 cmd, u16 *rc, u16 *rrc) +{ + struct uv_cb_nodata uvcb = { + .header.cmd = cmd, + .header.len = sizeof(uvcb), + .handle = handle, + }; + int cc; + + WARN(!handle, "No handle provided to Ultravisor call cmd %x\n", cmd); + cc = uv_call_sched(0, (u64)&uvcb); + *rc = uvcb.header.rc; + *rrc = uvcb.header.rrc; + return cc ? -EINVAL : 0; +} + +struct uv_info { + unsigned long inst_calls_list[4]; + unsigned long uv_base_stor_len; + unsigned long guest_base_stor_len; + unsigned long guest_virt_base_stor_len; + unsigned long guest_virt_var_stor_len; + unsigned long guest_cpu_stor_len; + unsigned long max_sec_stor_addr; + unsigned int max_num_sec_conf; + unsigned short max_guest_cpus; +}; + +extern struct uv_info uv_info; + #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST extern int prot_virt_guest; @@ -97,7 +310,10 @@ if (!uv_call(0, (u64)&uvcb)) return 0; - return -EINVAL; + pr_err("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n", + uvcb.header.cmd == UVC_CMD_SET_SHARED_ACCESS ? "Share" : "Unshare", + uvcb.header.rc, uvcb.header.rrc); + panic("System security cannot be guaranteed unless the system panics now.\n"); } /* @@ -121,11 +337,40 @@ return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS); } -void uv_query_info(void); #else #define is_prot_virt_guest() 0 static inline int uv_set_shared(unsigned long addr) { return 0; } static inline int uv_remove_shared(unsigned long addr) { return 0; } +#endif + +#if IS_ENABLED(CONFIG_KVM) +extern int prot_virt_host; + +static inline int is_prot_virt_host(void) +{ + return prot_virt_host; +} + +int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb); +int uv_convert_from_secure(unsigned long paddr); +int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr); + +void setup_uv(void); +void adjust_to_uv_max(unsigned long *vmax); +#else +#define is_prot_virt_host() 0 +static inline void setup_uv(void) {} +static inline void adjust_to_uv_max(unsigned long *vmax) {} + +static inline int uv_convert_from_secure(unsigned long paddr) +{ + return 0; +} +#endif + +#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM) +void uv_query_info(void); +#else static inline void uv_query_info(void) {} #endif --- linux-oracle-5.4.0.orig/arch/s390/include/asm/vdso.h +++ linux-oracle-5.4.0/arch/s390/include/asm/vdso.h @@ -36,6 +36,7 @@ __u32 tk_shift; /* Shift used for xtime_nsec 0x60 */ __u32 ts_dir; /* TOD steering direction 0x64 */ __u64 ts_end; /* TOD steering end 0x68 */ + __u32 hrtimer_res; /* hrtimer resolution 0x70 */ }; struct vdso_per_cpu_data { --- linux-oracle-5.4.0.orig/arch/s390/include/uapi/asm/ipl.h +++ linux-oracle-5.4.0/arch/s390/include/uapi/asm/ipl.h @@ -27,6 +27,7 @@ IPL_PBT_FCP = 0, IPL_PBT_SCP_DATA = 1, IPL_PBT_CCW = 2, + IPL_PBT_NVME = 4, }; /* IPL Parameter Block 0 with common fields */ @@ -67,6 +68,30 @@ #define IPL_PB0_FCP_OPT_IPL 0x10 #define IPL_PB0_FCP_OPT_DUMP 0x20 +/* IPL Parameter Block 0 for NVMe */ +struct ipl_pb0_nvme { + __u32 len; + __u8 pbt; + __u8 reserved1[3]; + __u8 loadparm[8]; + __u8 reserved2[304]; + __u8 opt; + __u8 reserved3[3]; + __u32 fid; + __u8 reserved4[12]; + __u32 nsid; + __u8 reserved5[4]; + __u32 bootprog; + __u8 reserved6[12]; + __u64 br_lba; + __u32 scp_data_len; + __u8 reserved7[260]; + __u8 scp_data[]; +} __packed; + +#define IPL_PB0_NVME_OPT_IPL 0x10 +#define IPL_PB0_NVME_OPT_DUMP 0x20 + /* IPL Parameter Block 0 for CCW */ struct ipl_pb0_ccw { __u32 len; --- linux-oracle-5.4.0.orig/arch/s390/include/uapi/asm/kvm.h +++ linux-oracle-5.4.0/arch/s390/include/uapi/asm/kvm.h @@ -231,11 +231,13 @@ #define KVM_SYNC_GSCB (1UL << 9) #define KVM_SYNC_BPBC (1UL << 10) #define KVM_SYNC_ETOKEN (1UL << 11) +#define KVM_SYNC_DIAG318 (1UL << 12) #define KVM_SYNC_S390_VALID_FIELDS \ (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \ KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \ - KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN) + KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \ + KVM_SYNC_DIAG318) /* length and alignment of the sdnx as a power of two */ #define SDNXC 8 @@ -264,7 +266,8 @@ __u8 reserved2 : 7; __u8 padding1[51]; /* riccb needs to be 64byte aligned */ __u8 riccb[64]; /* runtime instrumentation controls block */ - __u8 padding2[192]; /* sdnx needs to be 256byte aligned */ + __u64 diag318; /* diagnose 0x318 info */ + __u8 padding2[184]; /* sdnx needs to be 256byte aligned */ union { __u8 sdnx[SDNXL]; /* state description annex */ struct { --- linux-oracle-5.4.0.orig/arch/s390/include/uapi/asm/pkey.h +++ linux-oracle-5.4.0/arch/s390/include/uapi/asm/pkey.h @@ -25,10 +25,11 @@ #define MAXPROTKEYSIZE 64 /* a protected key blob may be up to 64 bytes */ #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */ #define MAXAESCIPHERKEYSIZE 136 /* our aes cipher keys have always 136 bytes */ +#define MINEP11AESKEYBLOBSIZE 256 /* min EP11 AES key blob size */ +#define MAXEP11AESKEYBLOBSIZE 320 /* max EP11 AES key blob size */ -/* Minimum and maximum size of a key blob */ +/* Minimum size of a key blob */ #define MINKEYBLOBSIZE SECKEYBLOBSIZE -#define MAXKEYBLOBSIZE MAXAESCIPHERKEYSIZE /* defines for the type field within the pkey_protkey struct */ #define PKEY_KEYTYPE_AES_128 1 @@ -39,6 +40,7 @@ enum pkey_key_type { PKEY_TYPE_CCA_DATA = (__u32) 1, PKEY_TYPE_CCA_CIPHER = (__u32) 2, + PKEY_TYPE_EP11 = (__u32) 3, }; /* the newer ioctls use a pkey_key_size enum for key size information */ @@ -200,7 +202,7 @@ /* * Generate secure key, version 2. - * Generate either a CCA AES secure key or a CCA AES cipher key. + * Generate CCA AES secure key, CCA AES cipher key or EP11 AES secure key. * There needs to be a list of apqns given with at least one entry in there. * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain * is not supported. The implementation walks through the list of apqns and @@ -210,10 +212,13 @@ * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to * generate a list of apqns based on the key type to generate. * The keygenflags argument is passed to the low level generation functions - * individual for the key type and has a key type specific meaning. Currently - * only CCA AES cipher keys react to this parameter: Use one or more of the - * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher - * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). + * individual for the key type and has a key type specific meaning. When + * generating CCA cipher keys you can use one or more of the PKEY_KEYGEN_* + * flags to widen the export possibilities. By default a cipher key is + * only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). + * The keygenflag argument for generating an EP11 AES key should either be 0 + * to use the defaults which are XCP_BLOB_ENCRYPT, XCP_BLOB_DECRYPT and + * XCP_BLOB_PROTKEY_EXTRACTABLE or a valid combination of XCP_BLOB_* flags. */ struct pkey_genseck2 { struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets*/ @@ -229,8 +234,8 @@ /* * Generate secure key from clear key value, version 2. - * Construct a CCA AES secure key or CCA AES cipher key from a given clear key - * value. + * Construct an CCA AES secure key, CCA AES cipher key or EP11 AES secure + * key from a given clear key value. * There needs to be a list of apqns given with at least one entry in there. * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain * is not supported. The implementation walks through the list of apqns and @@ -240,10 +245,13 @@ * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to * generate a list of apqns based on the key type to generate. * The keygenflags argument is passed to the low level generation functions - * individual for the key type and has a key type specific meaning. Currently - * only CCA AES cipher keys react to this parameter: Use one or more of the - * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher - * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). + * individual for the key type and has a key type specific meaning. When + * generating CCA cipher keys you can use one or more of the PKEY_KEYGEN_* + * flags to widen the export possibilities. By default a cipher key is + * only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). + * The keygenflag argument for generating an EP11 AES key should either be 0 + * to use the defaults which are XCP_BLOB_ENCRYPT, XCP_BLOB_DECRYPT and + * XCP_BLOB_PROTKEY_EXTRACTABLE or a valid combination of XCP_BLOB_* flags. */ struct pkey_clr2seck2 { struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */ @@ -266,14 +274,19 @@ * with one apqn able to handle this key. * The function also checks for the master key verification patterns * of the key matching to the current or alternate mkvp of the apqn. - * Currently CCA AES secure keys and CCA AES cipher keys are supported. - * The flags field is updated with some additional info about the apqn mkvp + * For CCA AES secure keys and CCA AES cipher keys this means to check + * the key's mkvp against the current or old mkvp of the apqns. The flags + * field is updated with some additional info about the apqn mkvp * match: If the current mkvp matches to the key's mkvp then the * PKEY_FLAGS_MATCH_CUR_MKVP bit is set, if the alternate mkvp matches to * the key's mkvp the PKEY_FLAGS_MATCH_ALT_MKVP is set. For CCA keys the * alternate mkvp is the old master key verification pattern. * CCA AES secure keys are also checked to have the CPACF export allowed * bit enabled (XPRTCPAC) in the kmf1 field. + * EP11 keys are also supported and the wkvp of the key is checked against + * the current wkvp of the apqns. There is no alternate for this type of + * key and so on a match the flag PKEY_FLAGS_MATCH_CUR_MKVP always is set. + * EP11 keys are also checked to have XCP_BLOB_PROTKEY_EXTRACTABLE set. * The ioctl returns 0 as long as the given or found apqn matches to * matches with the current or alternate mkvp to the key's mkvp. If the given * apqn does not match or there is no such apqn found, -1 with errno @@ -313,16 +326,20 @@ /* * Build a list of APQNs based on a key blob given. * Is able to find out which type of secure key is given (CCA AES secure - * key or CCA AES cipher key) and tries to find all matching crypto cards - * based on the MKVP and maybe other criterias (like CCA AES cipher keys - * need a CEX5C or higher). The list of APQNs is further filtered by the key's - * mkvp which needs to match to either the current mkvp or the alternate mkvp - * (which is the old mkvp on CCA adapters) of the apqns. The flags argument may - * be used to limit the matching apqns. If the PKEY_FLAGS_MATCH_CUR_MKVP is - * given, only the current mkvp of each apqn is compared. Likewise with the - * PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it is assumed to - * return apqns where either the current or the alternate mkvp + * key, CCA AES cipher key or EP11 AES key) and tries to find all matching + * crypto cards based on the MKVP and maybe other criterias (like CCA AES + * cipher keys need a CEX5C or higher, EP11 keys with BLOB_PKEY_EXTRACTABLE + * need a CEX7 and EP11 api version 4). The list of APQNs is further filtered + * by the key's mkvp which needs to match to either the current mkvp (CCA and + * EP11) or the alternate mkvp (old mkvp, CCA adapters only) of the apqns. The + * flags argument may be used to limit the matching apqns. If the + * PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of each apqn is + * compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it + * is assumed to return apqns where either the current or the alternate mkvp * matches. At least one of the matching flags needs to be given. + * The flags argument for EP11 keys has no further action and is currently + * ignored (but needs to be given as PKEY_FLAGS_MATCH_CUR_MKVP) as there is only + * the wkvp from the key to match against the apqn's wkvp. * The list of matching apqns is stored into the space given by the apqns * argument and the number of stored entries goes into apqn_entries. If the list * is empty (apqn_entries is 0) the apqn_entries field is updated to the number @@ -356,6 +373,10 @@ * If both are given, it is assumed to return apqns where either the * current or the alternate mkvp matches. If no match flag is given * (flags is 0) the mkvp values are ignored for the match process. + * For EP11 keys there is only the current wkvp. So if the apqns should also + * match to a given wkvp, then the PKEY_FLAGS_MATCH_CUR_MKVP flag should be + * set. The wkvp value is 32 bytes but only the leftmost 16 bytes are compared + * against the leftmost 16 byte of the wkvp of the apqn. * The list of matching apqns is stored into the space given by the apqns * argument and the number of stored entries goes into apqn_entries. If the list * is empty (apqn_entries is 0) the apqn_entries field is updated to the number --- linux-oracle-5.4.0.orig/arch/s390/include/uapi/asm/zcrypt.h +++ linux-oracle-5.4.0/arch/s390/include/uapi/asm/zcrypt.h @@ -36,12 +36,12 @@ * - length(n_modulus) = inputdatalength */ struct ica_rsa_modexpo { - char __user *inputdata; - unsigned int inputdatalength; - char __user *outputdata; - unsigned int outputdatalength; - char __user *b_key; - char __user *n_modulus; + __u8 __user *inputdata; + __u32 inputdatalength; + __u8 __user *outputdata; + __u32 outputdatalength; + __u8 __user *b_key; + __u8 __user *n_modulus; }; /** @@ -59,15 +59,15 @@ * - length(u_mult_inv) = inputdatalength/2 + 8 */ struct ica_rsa_modexpo_crt { - char __user *inputdata; - unsigned int inputdatalength; - char __user *outputdata; - unsigned int outputdatalength; - char __user *bp_key; - char __user *bq_key; - char __user *np_prime; - char __user *nq_prime; - char __user *u_mult_inv; + __u8 __user *inputdata; + __u32 inputdatalength; + __u8 __user *outputdata; + __u32 outputdatalength; + __u8 __user *bp_key; + __u8 __user *bq_key; + __u8 __user *np_prime; + __u8 __user *nq_prime; + __u8 __user *u_mult_inv; }; /** @@ -83,67 +83,67 @@ * key block */ struct CPRBX { - unsigned short cprb_len; /* CPRB length 220 */ - unsigned char cprb_ver_id; /* CPRB version id. 0x02 */ - unsigned char pad_000[3]; /* Alignment pad bytes */ - unsigned char func_id[2]; /* function id 0x5432 */ - unsigned char cprb_flags[4]; /* Flags */ - unsigned int req_parml; /* request parameter buffer len */ - unsigned int req_datal; /* request data buffer */ - unsigned int rpl_msgbl; /* reply message block length */ - unsigned int rpld_parml; /* replied parameter block len */ - unsigned int rpl_datal; /* reply data block len */ - unsigned int rpld_datal; /* replied data block len */ - unsigned int req_extbl; /* request extension block len */ - unsigned char pad_001[4]; /* reserved */ - unsigned int rpld_extbl; /* replied extension block len */ - unsigned char padx000[16 - sizeof(char *)]; - unsigned char *req_parmb; /* request parm block 'address' */ - unsigned char padx001[16 - sizeof(char *)]; - unsigned char *req_datab; /* request data block 'address' */ - unsigned char padx002[16 - sizeof(char *)]; - unsigned char *rpl_parmb; /* reply parm block 'address' */ - unsigned char padx003[16 - sizeof(char *)]; - unsigned char *rpl_datab; /* reply data block 'address' */ - unsigned char padx004[16 - sizeof(char *)]; - unsigned char *req_extb; /* request extension block 'addr'*/ - unsigned char padx005[16 - sizeof(char *)]; - unsigned char *rpl_extb; /* reply extension block 'address'*/ - unsigned short ccp_rtcode; /* server return code */ - unsigned short ccp_rscode; /* server reason code */ - unsigned int mac_data_len; /* Mac Data Length */ - unsigned char logon_id[8]; /* Logon Identifier */ - unsigned char mac_value[8]; /* Mac Value */ - unsigned char mac_content_flgs;/* Mac content flag byte */ - unsigned char pad_002; /* Alignment */ - unsigned short domain; /* Domain */ - unsigned char usage_domain[4];/* Usage domain */ - unsigned char cntrl_domain[4];/* Control domain */ - unsigned char S390enf_mask[4];/* S/390 enforcement mask */ - unsigned char pad_004[36]; /* reserved */ + __u16 cprb_len; /* CPRB length 220 */ + __u8 cprb_ver_id; /* CPRB version id. 0x02 */ + __u8 pad_000[3]; /* Alignment pad bytes */ + __u8 func_id[2]; /* function id 0x5432 */ + __u8 cprb_flags[4]; /* Flags */ + __u32 req_parml; /* request parameter buffer len */ + __u32 req_datal; /* request data buffer */ + __u32 rpl_msgbl; /* reply message block length */ + __u32 rpld_parml; /* replied parameter block len */ + __u32 rpl_datal; /* reply data block len */ + __u32 rpld_datal; /* replied data block len */ + __u32 req_extbl; /* request extension block len */ + __u8 pad_001[4]; /* reserved */ + __u32 rpld_extbl; /* replied extension block len */ + __u8 padx000[16 - sizeof(__u8 *)]; + __u8 __user *req_parmb; /* request parm block 'address' */ + __u8 padx001[16 - sizeof(__u8 *)]; + __u8 __user *req_datab; /* request data block 'address' */ + __u8 padx002[16 - sizeof(__u8 *)]; + __u8 __user *rpl_parmb; /* reply parm block 'address' */ + __u8 padx003[16 - sizeof(__u8 *)]; + __u8 __user *rpl_datab; /* reply data block 'address' */ + __u8 padx004[16 - sizeof(__u8 *)]; + __u8 __user *req_extb; /* request extension block 'addr'*/ + __u8 padx005[16 - sizeof(__u8 *)]; + __u8 __user *rpl_extb; /* reply extension block 'address'*/ + __u16 ccp_rtcode; /* server return code */ + __u16 ccp_rscode; /* server reason code */ + __u32 mac_data_len; /* Mac Data Length */ + __u8 logon_id[8]; /* Logon Identifier */ + __u8 mac_value[8]; /* Mac Value */ + __u8 mac_content_flgs; /* Mac content flag byte */ + __u8 pad_002; /* Alignment */ + __u16 domain; /* Domain */ + __u8 usage_domain[4]; /* Usage domain */ + __u8 cntrl_domain[4]; /* Control domain */ + __u8 S390enf_mask[4]; /* S/390 enforcement mask */ + __u8 pad_004[36]; /* reserved */ } __attribute__((packed)); /** * xcRB */ struct ica_xcRB { - unsigned short agent_ID; - unsigned int user_defined; - unsigned short request_ID; - unsigned int request_control_blk_length; - unsigned char padding1[16 - sizeof(char *)]; - char __user *request_control_blk_addr; - unsigned int request_data_length; - char padding2[16 - sizeof(char *)]; - char __user *request_data_address; - unsigned int reply_control_blk_length; - char padding3[16 - sizeof(char *)]; - char __user *reply_control_blk_addr; - unsigned int reply_data_length; - char padding4[16 - sizeof(char *)]; - char __user *reply_data_addr; - unsigned short priority_window; - unsigned int status; + __u16 agent_ID; + __u32 user_defined; + __u16 request_ID; + __u32 request_control_blk_length; + __u8 _padding1[16 - sizeof(__u8 *)]; + __u8 __user *request_control_blk_addr; + __u32 request_data_length; + __u8 _padding2[16 - sizeof(__u8 *)]; + __u8 __user *request_data_address; + __u32 reply_control_blk_length; + __u8 _padding3[16 - sizeof(__u8 *)]; + __u8 __user *reply_control_blk_addr; + __u32 reply_data_length; + __u8 __padding4[16 - sizeof(__u8 *)]; + __u8 __user *reply_data_addr; + __u16 priority_window; + __u32 status; } __attribute__((packed)); /** @@ -161,17 +161,17 @@ * @payload_len: Payload length */ struct ep11_cprb { - __u16 cprb_len; - unsigned char cprb_ver_id; - unsigned char pad_000[2]; - unsigned char flags; - unsigned char func_id[2]; - __u32 source_id; - __u32 target_id; - __u32 ret_code; - __u32 reserved1; - __u32 reserved2; - __u32 payload_len; + __u16 cprb_len; + __u8 cprb_ver_id; + __u8 pad_000[2]; + __u8 flags; + __u8 func_id[2]; + __u32 source_id; + __u32 target_id; + __u32 ret_code; + __u32 reserved1; + __u32 reserved2; + __u32 payload_len; } __attribute__((packed)); /** @@ -197,13 +197,13 @@ */ struct ep11_urb { __u16 targets_num; - __u64 targets; + __u8 __user *targets; __u64 weight; __u64 req_no; __u64 req_len; - __u64 req; + __u8 __user *req; __u64 resp_len; - __u64 resp; + __u8 __user *resp; } __attribute__((packed)); /** @@ -237,7 +237,9 @@ struct zcrypt_device_status_ext device[MAX_ZDEV_ENTRIES_EXT]; }; -#define AUTOSELECT 0xFFFFFFFF +#define AUTOSELECT 0xFFFFFFFF +#define AUTOSEL_AP ((__u16) 0xFFFF) +#define AUTOSEL_DOM ((__u16) 0xFFFF) #define ZCRYPT_IOCTL_MAGIC 'z' --- linux-oracle-5.4.0.orig/arch/s390/kernel/Makefile +++ linux-oracle-5.4.0/arch/s390/kernel/Makefile @@ -78,7 +78,11 @@ obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_diag.o obj-$(CONFIG_TRACEPOINTS) += trace.o +obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o # vdso obj-y += vdso64/ obj-$(CONFIG_COMPAT_VDSO) += vdso32/ + +# kernel message catalog +obj-$(CONFIG_KMSG_IDS) += kmsg.o --- linux-oracle-5.4.0.orig/arch/s390/kernel/asm-offsets.c +++ linux-oracle-5.4.0/arch/s390/kernel/asm-offsets.c @@ -76,6 +76,7 @@ OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir); OFFSET(__VDSO_TS_END, vdso_data, ts_end); + OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res); OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr); @@ -87,7 +88,6 @@ DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE); DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE); DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID); - DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC); BLANK(); /* idle data offsets */ @@ -125,6 +125,8 @@ OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code); OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address); OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr); + OFFSET(__LC_RETURN_LPSWE, lowcore, return_lpswe); + OFFSET(__LC_RETURN_MCCK_LPSWE, lowcore, return_mcck_lpswe); OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw); OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw); OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw); --- linux-oracle-5.4.0.orig/arch/s390/kernel/cpcmd.c +++ linux-oracle-5.4.0/arch/s390/kernel/cpcmd.c @@ -37,10 +37,12 @@ static int diag8_response(int cmdlen, char *response, int *rlen) { + unsigned long _cmdlen = cmdlen | 0x40000000L; + unsigned long _rlen = *rlen; register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; register unsigned long reg3 asm ("3") = (addr_t) response; - register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; - register unsigned long reg5 asm ("5") = *rlen; + register unsigned long reg4 asm ("4") = _cmdlen; + register unsigned long reg5 asm ("5") = _rlen; asm volatile( " diag %2,%0,0x8\n" --- linux-oracle-5.4.0.orig/arch/s390/kernel/crash_dump.c +++ linux-oracle-5.4.0/arch/s390/kernel/crash_dump.c @@ -44,7 +44,7 @@ u64 fprs[16]; u32 fpc; u32 prefix; - u64 todpreg; + u32 todpreg; u64 timer; u64 todcmp; u64 vxrs_low[16]; --- linux-oracle-5.4.0.orig/arch/s390/kernel/debug.c +++ linux-oracle-5.4.0/arch/s390/kernel/debug.c @@ -198,9 +198,10 @@ if (!areas) goto fail_malloc_areas; for (i = 0; i < nr_areas; i++) { + /* GFP_NOWARN to avoid user triggerable WARN, we handle fails */ areas[i] = kmalloc_array(pages_per_area, sizeof(debug_entry_t *), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (!areas[i]) goto fail_malloc_areas2; for (j = 0; j < pages_per_area; j++) { @@ -326,24 +327,6 @@ goto out; rc->mode = mode & ~S_IFMT; - - /* create root directory */ - rc->debugfs_root_entry = debugfs_create_dir(rc->name, - debug_debugfs_root_entry); - - /* append new element to linked list */ - if (!debug_area_first) { - /* first element in list */ - debug_area_first = rc; - rc->prev = NULL; - } else { - /* append element to end of list */ - debug_area_last->next = rc; - rc->prev = debug_area_last; - } - debug_area_last = rc; - rc->next = NULL; - refcount_set(&rc->ref_count, 1); out: return rc; @@ -403,27 +386,10 @@ */ static void debug_info_put(debug_info_t *db_info) { - int i; - if (!db_info) return; - if (refcount_dec_and_test(&db_info->ref_count)) { - for (i = 0; i < DEBUG_MAX_VIEWS; i++) { - if (!db_info->views[i]) - continue; - debugfs_remove(db_info->debugfs_entries[i]); - } - debugfs_remove(db_info->debugfs_root_entry); - if (db_info == debug_area_first) - debug_area_first = db_info->next; - if (db_info == debug_area_last) - debug_area_last = db_info->prev; - if (db_info->prev) - db_info->prev->next = db_info->next; - if (db_info->next) - db_info->next->prev = db_info->prev; + if (refcount_dec_and_test(&db_info->ref_count)) debug_info_free(db_info); - } } /* @@ -647,6 +613,31 @@ return 0; /* success */ } +/* Create debugfs entries and add to internal list. */ +static void _debug_register(debug_info_t *id) +{ + /* create root directory */ + id->debugfs_root_entry = debugfs_create_dir(id->name, + debug_debugfs_root_entry); + + /* append new element to linked list */ + if (!debug_area_first) { + /* first element in list */ + debug_area_first = id; + id->prev = NULL; + } else { + /* append element to end of list */ + debug_area_last->next = id; + id->prev = debug_area_last; + } + debug_area_last = id; + id->next = NULL; + + debug_register_view(id, &debug_level_view); + debug_register_view(id, &debug_flush_view); + debug_register_view(id, &debug_pages_view); +} + /** * debug_register_mode() - creates and initializes debug area. * @@ -676,19 +667,16 @@ if ((uid != 0) || (gid != 0)) pr_warn("Root becomes the owner of all s390dbf files in sysfs\n"); BUG_ON(!initialized); - mutex_lock(&debug_mutex); /* create new debug_info */ rc = debug_info_create(name, pages_per_area, nr_areas, buf_size, mode); - if (!rc) - goto out; - debug_register_view(rc, &debug_level_view); - debug_register_view(rc, &debug_flush_view); - debug_register_view(rc, &debug_pages_view); -out: - if (!rc) + if (rc) { + mutex_lock(&debug_mutex); + _debug_register(rc); + mutex_unlock(&debug_mutex); + } else { pr_err("Registering debug feature %s failed\n", name); - mutex_unlock(&debug_mutex); + } return rc; } EXPORT_SYMBOL(debug_register_mode); @@ -717,6 +705,27 @@ } EXPORT_SYMBOL(debug_register); +/* Remove debugfs entries and remove from internal list. */ +static void _debug_unregister(debug_info_t *id) +{ + int i; + + for (i = 0; i < DEBUG_MAX_VIEWS; i++) { + if (!id->views[i]) + continue; + debugfs_remove(id->debugfs_entries[i]); + } + debugfs_remove(id->debugfs_root_entry); + if (id == debug_area_first) + debug_area_first = id->next; + if (id == debug_area_last) + debug_area_last = id->prev; + if (id->prev) + id->prev->next = id->next; + if (id->next) + id->next->prev = id->prev; +} + /** * debug_unregister() - give back debug area. * @@ -730,8 +739,10 @@ if (!id) return; mutex_lock(&debug_mutex); - debug_info_put(id); + _debug_unregister(id); mutex_unlock(&debug_mutex); + + debug_info_put(id); } EXPORT_SYMBOL(debug_unregister); --- linux-oracle-5.4.0.orig/arch/s390/kernel/diag.c +++ linux-oracle-5.4.0/arch/s390/kernel/diag.c @@ -84,7 +84,7 @@ static void *show_diag_stat_start(struct seq_file *m, loff_t *pos) { - return *pos <= nr_cpu_ids ? (void *)((unsigned long) *pos + 1) : NULL; + return *pos <= NR_DIAG_STAT ? (void *)((unsigned long) *pos + 1) : NULL; } static void *show_diag_stat_next(struct seq_file *m, void *v, loff_t *pos) @@ -133,7 +133,7 @@ } EXPORT_SYMBOL(diag_stat_inc); -void diag_stat_inc_norecursion(enum diag_stat_enum nr) +void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr) { this_cpu_inc(diag_stat.counter[nr]); trace_s390_diagnose_norecursion(diag_map[nr].code); --- linux-oracle-5.4.0.orig/arch/s390/kernel/dis.c +++ linux-oracle-5.4.0/arch/s390/kernel/dis.c @@ -461,10 +461,11 @@ ptr += sprintf(ptr, "%%c%i", value); else if (operand->flags & OPERAND_VR) ptr += sprintf(ptr, "%%v%i", value); - else if (operand->flags & OPERAND_PCREL) - ptr += sprintf(ptr, "%lx", (signed int) value - + addr); - else if (operand->flags & OPERAND_SIGNED) + else if (operand->flags & OPERAND_PCREL) { + void *pcrel = (void *)((int)value + addr); + + ptr += sprintf(ptr, "%px", pcrel); + } else if (operand->flags & OPERAND_SIGNED) ptr += sprintf(ptr, "%i", value); else ptr += sprintf(ptr, "%u", value); @@ -536,7 +537,7 @@ else *ptr++ = ' '; addr = regs->psw.addr + start - 32; - ptr += sprintf(ptr, "%016lx: ", addr); + ptr += sprintf(ptr, "%px: ", (void *)addr); if (start + opsize >= end) break; for (i = 0; i < opsize; i++) @@ -556,7 +557,7 @@ void print_fn_code(unsigned char *code, unsigned long len) { - char buffer[64], *ptr; + char buffer[128], *ptr; int opsize, i; while (len) { @@ -564,7 +565,7 @@ opsize = insn_length(*code); if (opsize > len) break; - ptr += sprintf(ptr, "%p: ", code); + ptr += sprintf(ptr, "%px: ", code); for (i = 0; i < opsize; i++) ptr += sprintf(ptr, "%02x", code[i]); *ptr++ = '\t'; --- linux-oracle-5.4.0.orig/arch/s390/kernel/dumpstack.c +++ linux-oracle-5.4.0/arch/s390/kernel/dumpstack.c @@ -210,5 +210,5 @@ if (panic_on_oops) panic("Fatal exception: panic_on_oops"); oops_exit(); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } --- linux-oracle-5.4.0.orig/arch/s390/kernel/early.c +++ linux-oracle-5.4.0/arch/s390/kernel/early.c @@ -169,6 +169,8 @@ psw_t psw; psw.mask = PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA; + if (IS_ENABLED(CONFIG_KASAN)) + psw.mask |= PSW_MASK_DAT; psw.addr = (unsigned long) s390_base_ext_handler; S390_lowcore.external_new_psw = psw; psw.addr = (unsigned long) s390_base_pgm_handler; @@ -250,6 +252,10 @@ clock_comparator_max = -1ULL >> 1; __ctl_set_bit(0, 53); } + if (IS_ENABLED(CONFIG_PCI) && test_facility(153)) { + S390_lowcore.machine_flags |= MACHINE_FLAG_PCI_MIO; + /* the control bit is set during PCI initialization */ + } } static inline void save_vector_registers(void) --- linux-oracle-5.4.0.orig/arch/s390/kernel/entry.S +++ linux-oracle-5.4.0/arch/s390/kernel/entry.S @@ -115,26 +115,29 @@ .macro SWITCH_ASYNC savearea,timer tmhh %r8,0x0001 # interrupting from user ? - jnz 1f + jnz 2f lgr %r14,%r9 + cghi %r14,__LC_RETURN_LPSWE + je 0f slg %r14,BASED(.Lcritical_start) clg %r14,BASED(.Lcritical_length) - jhe 0f + jhe 1f +0: lghi %r11,\savearea # inside critical section, do cleanup brasl %r14,cleanup_critical tmhh %r8,0x0001 # retest problem state after cleanup - jnz 1f -0: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? + jnz 2f +1: lg %r14,__LC_ASYNC_STACK # are we already on the target stack? slgr %r14,%r15 srag %r14,%r14,STACK_SHIFT - jnz 2f + jnz 3f CHECK_STACK \savearea aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) - j 3f -1: UPDATE_VTIME %r14,%r15,\timer + j 4f +2: UPDATE_VTIME %r14,%r15,\timer BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP -2: lg %r15,__LC_ASYNC_STACK # load async stack -3: la %r11,STACK_FRAME_OVERHEAD(%r15) +3: lg %r15,__LC_ASYNC_STACK # load async stack +4: la %r11,STACK_FRAME_OVERHEAD(%r15) .endm .macro UPDATE_VTIME w1,w2,enter_timer @@ -365,9 +368,9 @@ jnz .Lsysc_nr_ok # svc 0: system call number in %r1 llgfr %r1,%r1 # clear high word in r1 + sth %r1,__PT_INT_CODE+2(%r11) cghi %r1,NR_syscalls jnl .Lsysc_nr_ok - sth %r1,__PT_INT_CODE+2(%r11) slag %r8,%r1,3 .Lsysc_nr_ok: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) @@ -401,7 +404,7 @@ stpt __LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_PSW + b __LC_RETURN_LPSWE(%r0) .Lsysc_done: # @@ -608,43 +611,50 @@ BPOFF stmg %r8,%r15,__LC_SAVE_AREA_SYNC lg %r10,__LC_LAST_BREAK - lg %r12,__LC_CURRENT + srag %r11,%r10,12 + jnz 0f + /* if __LC_LAST_BREAK is < 4096, it contains one of + * the lpswe addresses in lowcore. Set it to 1 (initial state) + * to prevent leaking that address to userspace. + */ + lghi %r10,1 +0: lg %r12,__LC_CURRENT lghi %r11,0 larl %r13,cleanup_critical lmg %r8,%r9,__LC_PGM_OLD_PSW tmhh %r8,0x0001 # test problem state bit - jnz 2f # -> fault in user space + jnz 3f # -> fault in user space #if IS_ENABLED(CONFIG_KVM) # cleanup critical section for program checks in sie64a lgr %r14,%r9 slg %r14,BASED(.Lsie_critical_start) clg %r14,BASED(.Lsie_critical_length) - jhe 0f + jhe 1f lg %r14,__SF_SIE_CONTROL(%r15) # get control block pointer ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE lctlg %c1,%c1,__LC_USER_ASCE # load primary asce larl %r9,sie_exit # skip forward to sie_exit lghi %r11,_PIF_GUEST_FAULT #endif -0: tmhh %r8,0x4000 # PER bit set in old PSW ? - jnz 1f # -> enabled, can't be a double fault +1: tmhh %r8,0x4000 # PER bit set in old PSW ? + jnz 2f # -> enabled, can't be a double fault tm __LC_PGM_ILC+3,0x80 # check for per exception jnz .Lpgm_svcper # -> single stepped svc -1: CHECK_STACK __LC_SAVE_AREA_SYNC +2: CHECK_STACK __LC_SAVE_AREA_SYNC aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) - # CHECK_VMAP_STACK branches to stack_overflow or 4f - CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,4f -2: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER + # CHECK_VMAP_STACK branches to stack_overflow or 5f + CHECK_VMAP_STACK __LC_SAVE_AREA_SYNC,5f +3: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP lg %r15,__LC_KERNEL_STACK lgr %r14,%r12 aghi %r14,__TASK_thread # pointer to thread_struct lghi %r13,__LC_PGM_TDB tm __LC_PGM_ILC+2,0x02 # check for transaction abort - jz 3f + jz 4f mvc __THREAD_trap_tdb(256,%r14),0(%r13) -3: stg %r10,__THREAD_last_break(%r14) -4: lgr %r13,%r11 +4: stg %r10,__THREAD_last_break(%r14) +5: lgr %r13,%r11 la %r11,STACK_FRAME_OVERHEAD(%r15) stmg %r0,%r7,__PT_R0(%r11) # clear user controlled registers to prevent speculative use @@ -663,14 +673,14 @@ stg %r13,__PT_FLAGS(%r11) stg %r10,__PT_ARGS(%r11) tm __LC_PGM_ILC+3,0x80 # check for per exception - jz 5f + jz 6f tmhh %r8,0x0001 # kernel per event ? jz .Lpgm_kprobe oi __PT_FLAGS+7(%r11),_PIF_PER_TRAP mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID -5: REENABLE_IRQS +6: REENABLE_IRQS xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) larl %r1,pgm_check_table llgh %r10,__PT_INT_CODE+2(%r11) @@ -775,7 +785,7 @@ mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER .Lio_exit_kernel: lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_PSW + b __LC_RETURN_LPSWE(%r0) .Lio_done: # @@ -983,6 +993,7 @@ * Load idle PSW. The second "half" of this function is in .Lcleanup_idle. */ ENTRY(psw_idle) + stg %r14,(__SF_GPRS+8*8)(%r15) stg %r3,__SF_EMPTY(%r15) larl %r1,.Lpsw_idle_lpsw+4 stg %r1,__SF_EMPTY+8(%r15) @@ -1214,7 +1225,7 @@ stpt __LC_EXIT_TIMER mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 0: lmg %r11,%r15,__PT_R11(%r11) - lpswe __LC_RETURN_MCCK_PSW + b __LC_RETURN_MCCK_LPSWE .Lmcck_panic: lg %r15,__LC_NODAT_STACK @@ -1271,6 +1282,8 @@ #endif ENTRY(cleanup_critical) + cghi %r9,__LC_RETURN_LPSWE + je .Lcleanup_lpswe #if IS_ENABLED(CONFIG_KVM) clg %r9,BASED(.Lcleanup_table_sie) # .Lsie_gmap jl 0f @@ -1424,6 +1437,7 @@ mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) mvc 0(64,%r11),__PT_R8(%r9) lmg %r0,%r7,__PT_R0(%r9) +.Lcleanup_lpswe: 1: lmg %r8,%r9,__LC_RETURN_PSW BR_EX %r14,%r11 .Lcleanup_sysc_restore_insn: @@ -1528,6 +1542,7 @@ .quad .Lsie_skip - .Lsie_entry #endif .section .rodata, "a" + .balign 8 #define SYSCALL(esame,emu) .quad __s390x_ ## esame .globl sys_call_table sys_call_table: --- linux-oracle-5.4.0.orig/arch/s390/kernel/entry.h +++ linux-oracle-5.4.0/arch/s390/kernel/entry.h @@ -24,6 +24,8 @@ void do_protection_exception(struct pt_regs *regs); void do_dat_exception(struct pt_regs *regs); +void do_secure_storage_access(struct pt_regs *regs); +void do_non_secure_storage_access(struct pt_regs *regs); void addressing_exception(struct pt_regs *regs); void data_exception(struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/s390/kernel/ftrace.c +++ linux-oracle-5.4.0/arch/s390/kernel/ftrace.c @@ -57,6 +57,7 @@ * > brasl %r0,ftrace_caller # offset 0 */ +void *ftrace_func __read_mostly = ftrace_stub; unsigned long ftrace_plt; static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) @@ -72,15 +73,6 @@ #endif } -static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn) -{ -#ifdef CONFIG_KPROBES - if (insn->opc == BREAKPOINT_INSTRUCTION) - return 1; -#endif - return 0; -} - static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn) { #ifdef CONFIG_KPROBES @@ -114,16 +106,6 @@ /* Initial code replacement */ ftrace_generate_orig_insn(&orig); ftrace_generate_nop_insn(&new); - } else if (is_kprobe_on_ftrace(&old)) { - /* - * If we find a breakpoint instruction, a kprobe has been - * placed at the beginning of the function. We write the - * constant KPROBE_ON_FTRACE_NOP into the remaining four - * bytes of the original instruction so that the kprobes - * handler can execute a nop, if it reaches this breakpoint. - */ - ftrace_generate_kprobe_call_insn(&orig); - ftrace_generate_kprobe_nop_insn(&new); } else { /* Replace ftrace call with a nop. */ ftrace_generate_call_insn(&orig, rec->ip); @@ -142,21 +124,10 @@ if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) return -EFAULT; - if (is_kprobe_on_ftrace(&old)) { - /* - * If we find a breakpoint instruction, a kprobe has been - * placed at the beginning of the function. We write the - * constant KPROBE_ON_FTRACE_CALL into the remaining four - * bytes of the original instruction so that the kprobes - * handler can execute a brasl if it reaches this breakpoint. - */ - ftrace_generate_kprobe_nop_insn(&orig); - ftrace_generate_kprobe_call_insn(&new); - } else { - /* Replace nop with an ftrace call. */ - ftrace_generate_nop_insn(&orig); - ftrace_generate_call_insn(&new, rec->ip); - } + /* Replace nop with an ftrace call. */ + ftrace_generate_nop_insn(&orig); + ftrace_generate_call_insn(&new, rec->ip); + /* Verify that the to be replaced code matches what we expect. */ if (memcmp(&orig, &old, sizeof(old))) return -EINVAL; @@ -166,6 +137,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) { + ftrace_func = func; return 0; } @@ -241,3 +213,45 @@ } #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ + +#ifdef CONFIG_KPROBES_ON_FTRACE +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *ops, struct pt_regs *regs) +{ + struct kprobe_ctlblk *kcb; + struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip); + + if (unlikely(!p) || kprobe_disabled(p)) + return; + + if (kprobe_running()) { + kprobes_inc_nmissed_count(p); + return; + } + + __this_cpu_write(current_kprobe, p); + + kcb = get_kprobe_ctlblk(); + kcb->kprobe_status = KPROBE_HIT_ACTIVE; + + instruction_pointer_set(regs, ip); + + if (!p->pre_handler || !p->pre_handler(p, regs)) { + + instruction_pointer_set(regs, ip + MCOUNT_INSN_SIZE); + + if (unlikely(p->post_handler)) { + kcb->kprobe_status = KPROBE_HIT_SSDONE; + p->post_handler(p, regs, 0); + } + } + __this_cpu_write(current_kprobe, NULL); +} +NOKPROBE_SYMBOL(kprobe_ftrace_handler); + +int arch_prepare_kprobe_ftrace(struct kprobe *p) +{ + p->ainsn.insn = NULL; + return 0; +} +#endif --- linux-oracle-5.4.0.orig/arch/s390/kernel/ipl.c +++ linux-oracle-5.4.0/arch/s390/kernel/ipl.c @@ -39,6 +39,7 @@ #define IPL_CCW_STR "ccw" #define IPL_FCP_STR "fcp" #define IPL_FCP_DUMP_STR "fcp_dump" +#define IPL_NVME_STR "nvme" #define IPL_NSS_STR "nss" #define DUMP_CCW_STR "ccw" @@ -93,6 +94,8 @@ return IPL_FCP_DUMP_STR; case IPL_TYPE_NSS: return IPL_NSS_STR; + case IPL_TYPE_NVME: + return IPL_NVME_STR; case IPL_TYPE_UNKNOWN: default: return IPL_UNKNOWN_STR; @@ -133,6 +136,7 @@ static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; static struct ipl_parameter_block *reipl_block_fcp; +static struct ipl_parameter_block *reipl_block_nvme; static struct ipl_parameter_block *reipl_block_ccw; static struct ipl_parameter_block *reipl_block_nss; static struct ipl_parameter_block *reipl_block_actual; @@ -258,6 +262,8 @@ return IPL_TYPE_FCP_DUMP; else return IPL_TYPE_FCP; + case IPL_PBT_NVME: + return IPL_TYPE_NVME; } return IPL_TYPE_UNKNOWN; } @@ -314,6 +320,8 @@ case IPL_TYPE_FCP: case IPL_TYPE_FCP_DUMP: return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno); + case IPL_TYPE_NVME: + return sprintf(page, "%08ux\n", ipl_block.nvme.fid); default: return 0; } @@ -342,15 +350,35 @@ return memory_read_from_buffer(buf, count, &off, scp_data, size); } + +static ssize_t ipl_nvme_scp_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned int size = ipl_block.nvme.scp_data_len; + void *scp_data = &ipl_block.nvme.scp_data; + + return memory_read_from_buffer(buf, count, &off, scp_data, size); +} + static struct bin_attribute ipl_scp_data_attr = __BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE); +static struct bin_attribute ipl_nvme_scp_data_attr = + __BIN_ATTR(scp_data, S_IRUGO, ipl_nvme_scp_data_read, NULL, PAGE_SIZE); + static struct bin_attribute *ipl_fcp_bin_attrs[] = { &ipl_parameter_attr, &ipl_scp_data_attr, NULL, }; +static struct bin_attribute *ipl_nvme_bin_attrs[] = { + &ipl_parameter_attr, + &ipl_nvme_scp_data_attr, + NULL, +}; + /* FCP ipl device attributes */ DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", @@ -362,6 +390,16 @@ DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)ipl_block.fcp.br_lba); +/* NVMe ipl device attributes */ +DEFINE_IPL_ATTR_RO(ipl_nvme, fid, "0x%08llx\n", + (unsigned long long)ipl_block.nvme.fid); +DEFINE_IPL_ATTR_RO(ipl_nvme, nsid, "0x%08llx\n", + (unsigned long long)ipl_block.nvme.nsid); +DEFINE_IPL_ATTR_RO(ipl_nvme, bootprog, "%lld\n", + (unsigned long long)ipl_block.nvme.bootprog); +DEFINE_IPL_ATTR_RO(ipl_nvme, br_lba, "%lld\n", + (unsigned long long)ipl_block.nvme.br_lba); + static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, struct kobj_attribute *attr, char *page) { @@ -396,6 +434,24 @@ .bin_attrs = ipl_fcp_bin_attrs, }; +static struct attribute *ipl_nvme_attrs[] = { + &sys_ipl_type_attr.attr, + &sys_ipl_nvme_fid_attr.attr, + &sys_ipl_nvme_nsid_attr.attr, + &sys_ipl_nvme_bootprog_attr.attr, + &sys_ipl_nvme_br_lba_attr.attr, + &sys_ipl_ccw_loadparm_attr.attr, + &sys_ipl_secure_attr.attr, + &sys_ipl_has_secure_attr.attr, + NULL, +}; + +static struct attribute_group ipl_nvme_attr_group = { + .attrs = ipl_nvme_attrs, + .bin_attrs = ipl_nvme_bin_attrs, +}; + + /* CCW ipl device attributes */ static struct attribute *ipl_ccw_attrs_vm[] = { @@ -429,6 +485,8 @@ static struct attribute *ipl_unknown_attrs[] = { &sys_ipl_type_attr.attr, + &sys_ipl_secure_attr.attr, + &sys_ipl_has_secure_attr.attr, NULL, }; @@ -471,6 +529,9 @@ case IPL_TYPE_FCP_DUMP: rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group); break; + case IPL_TYPE_NVME: + rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group); + break; default: rc = sysfs_create_group(&ipl_kset->kobj, &ipl_unknown_attr_group); @@ -706,6 +767,93 @@ .bin_attrs = reipl_fcp_bin_attrs, }; +/* NVME reipl device attributes */ + +static ssize_t reipl_nvme_scpdata_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + size_t size = reipl_block_nvme->nvme.scp_data_len; + void *scp_data = reipl_block_nvme->nvme.scp_data; + + return memory_read_from_buffer(buf, count, &off, scp_data, size); +} + +static ssize_t reipl_nvme_scpdata_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + size_t scpdata_len = count; + size_t padding; + + if (off) + return -EINVAL; + + memcpy(reipl_block_nvme->nvme.scp_data, buf, count); + if (scpdata_len % 8) { + padding = 8 - (scpdata_len % 8); + memset(reipl_block_nvme->nvme.scp_data + scpdata_len, + 0, padding); + scpdata_len += padding; + } + + reipl_block_nvme->hdr.len = IPL_BP_FCP_LEN + scpdata_len; + reipl_block_nvme->nvme.len = IPL_BP0_FCP_LEN + scpdata_len; + reipl_block_nvme->nvme.scp_data_len = scpdata_len; + + return count; +} + +static struct bin_attribute sys_reipl_nvme_scp_data_attr = + __BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_nvme_scpdata_read, + reipl_nvme_scpdata_write, DIAG308_SCPDATA_SIZE); + +static struct bin_attribute *reipl_nvme_bin_attrs[] = { + &sys_reipl_nvme_scp_data_attr, + NULL, +}; + +DEFINE_IPL_ATTR_RW(reipl_nvme, fid, "0x%08llx\n", "%llx\n", + reipl_block_nvme->nvme.fid); +DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n", + reipl_block_nvme->nvme.nsid); +DEFINE_IPL_ATTR_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n", + reipl_block_nvme->nvme.bootprog); +DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n", + reipl_block_nvme->nvme.br_lba); + +/* nvme wrapper */ +static ssize_t reipl_nvme_loadparm_show(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return reipl_generic_loadparm_show(reipl_block_nvme, page); +} + +static ssize_t reipl_nvme_loadparm_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t len) +{ + return reipl_generic_loadparm_store(reipl_block_nvme, buf, len); +} + +static struct kobj_attribute sys_reipl_nvme_loadparm_attr = + __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nvme_loadparm_show, + reipl_nvme_loadparm_store); + +static struct attribute *reipl_nvme_attrs[] = { + &sys_reipl_nvme_fid_attr.attr, + &sys_reipl_nvme_nsid_attr.attr, + &sys_reipl_nvme_bootprog_attr.attr, + &sys_reipl_nvme_br_lba_attr.attr, + &sys_reipl_nvme_loadparm_attr.attr, + NULL, +}; + +static struct attribute_group reipl_nvme_attr_group = { + .attrs = reipl_nvme_attrs, + .bin_attrs = reipl_nvme_bin_attrs +}; + /* CCW reipl device attributes */ DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ccw); @@ -850,6 +998,9 @@ case IPL_TYPE_FCP: reipl_block_actual = reipl_block_fcp; break; + case IPL_TYPE_NVME: + reipl_block_actual = reipl_block_nvme; + break; case IPL_TYPE_NSS: reipl_block_actual = reipl_block_nss; break; @@ -876,6 +1027,8 @@ rc = reipl_set_type(IPL_TYPE_CCW); else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) rc = reipl_set_type(IPL_TYPE_FCP); + else if (strncmp(buf, IPL_NVME_STR, strlen(IPL_NVME_STR)) == 0) + rc = reipl_set_type(IPL_TYPE_NVME); else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0) rc = reipl_set_type(IPL_TYPE_NSS); return (rc != 0) ? rc : len; @@ -886,6 +1039,7 @@ static struct kset *reipl_kset; static struct kset *reipl_fcp_kset; +static struct kset *reipl_nvme_kset; static void __reipl_run(void *unused) { @@ -898,6 +1052,10 @@ diag308(DIAG308_SET, reipl_block_fcp); diag308(DIAG308_LOAD_CLEAR, NULL); break; + case IPL_TYPE_NVME: + diag308(DIAG308_SET, reipl_block_nvme); + diag308(DIAG308_LOAD_CLEAR, NULL); + break; case IPL_TYPE_NSS: diag308(DIAG308_SET, reipl_block_nss); diag308(DIAG308_LOAD_CLEAR, NULL); @@ -1034,6 +1192,49 @@ return 0; } +static int __init reipl_nvme_init(void) +{ + int rc; + + reipl_block_nvme = (void *) get_zeroed_page(GFP_KERNEL); + if (!reipl_block_nvme) + return -ENOMEM; + + /* sysfs: create kset for mixing attr group and bin attrs */ + reipl_nvme_kset = kset_create_and_add(IPL_NVME_STR, NULL, + &reipl_kset->kobj); + if (!reipl_nvme_kset) { + free_page((unsigned long) reipl_block_nvme); + return -ENOMEM; + } + + rc = sysfs_create_group(&reipl_nvme_kset->kobj, &reipl_nvme_attr_group); + if (rc) { + kset_unregister(reipl_nvme_kset); + free_page((unsigned long) reipl_block_nvme); + return rc; + } + + if (ipl_info.type == IPL_TYPE_NVME) { + memcpy(reipl_block_nvme, &ipl_block, sizeof(ipl_block)); + /* + * Fix loadparm: There are systems where the (SCSI) LOADPARM + * is invalid in the IPL parameter block, so take it + * always from sclp_ipl_info. + */ + memcpy(reipl_block_nvme->nvme.loadparm, sclp_ipl_info.loadparm, + LOADPARM_LEN); + } else { + reipl_block_nvme->hdr.len = IPL_BP_NVME_LEN; + reipl_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION; + reipl_block_nvme->nvme.len = IPL_BP0_NVME_LEN; + reipl_block_nvme->nvme.pbt = IPL_PBT_NVME; + reipl_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_IPL; + } + reipl_capabilities |= IPL_TYPE_NVME; + return 0; +} + static int __init reipl_type_init(void) { enum ipl_type reipl_type = ipl_info.type; @@ -1049,6 +1250,9 @@ if (reipl_block->pb0_hdr.pbt == IPL_PBT_FCP) { memcpy(reipl_block_fcp, reipl_block, size); reipl_type = IPL_TYPE_FCP; + } else if (reipl_block->pb0_hdr.pbt == IPL_PBT_NVME) { + memcpy(reipl_block_nvme, reipl_block, size); + reipl_type = IPL_TYPE_NVME; } else if (reipl_block->pb0_hdr.pbt == IPL_PBT_CCW) { memcpy(reipl_block_ccw, reipl_block, size); reipl_type = IPL_TYPE_CCW; @@ -1075,6 +1279,9 @@ rc = reipl_fcp_init(); if (rc) return rc; + rc = reipl_nvme_init(); + if (rc) + return rc; rc = reipl_nss_init(); if (rc) return rc; @@ -1691,6 +1898,10 @@ ipl_info.data.fcp.wwpn = ipl_block.fcp.wwpn; ipl_info.data.fcp.lun = ipl_block.fcp.lun; break; + case IPL_TYPE_NVME: + ipl_info.data.nvme.fid = ipl_block.nvme.fid; + ipl_info.data.nvme.nsid = ipl_block.nvme.nsid; + break; case IPL_TYPE_NSS: case IPL_TYPE_UNKNOWN: /* We have no info to copy */ @@ -1783,7 +1994,7 @@ buf = vzalloc(report->size); if (!buf) - return ERR_PTR(-ENOMEM); + goto out; ptr = buf; memcpy(ptr, report->ipib, report->ipib->hdr.len); @@ -1822,6 +2033,7 @@ } BUG_ON(ptr > buf + report->size); +out: return buf; } @@ -1842,3 +2054,8 @@ } #endif + +bool ipl_get_secureboot(void) +{ + return !!ipl_secure_flag; +} --- linux-oracle-5.4.0.orig/arch/s390/kernel/irq.c +++ linux-oracle-5.4.0/arch/s390/kernel/irq.c @@ -294,11 +294,6 @@ return IRQ_HANDLED; } -static struct irqaction external_interrupt = { - .name = "EXT", - .handler = do_ext_interrupt, -}; - void __init init_ext_interrupts(void) { int idx; @@ -308,7 +303,8 @@ irq_set_chip_and_handler(EXT_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); - setup_irq(EXT_INTERRUPT, &external_interrupt); + if (request_irq(EXT_INTERRUPT, do_ext_interrupt, 0, "EXT", NULL)) + panic("Failed to register EXT interrupt\n"); } static DEFINE_SPINLOCK(irq_subclass_lock); --- linux-oracle-5.4.0.orig/arch/s390/kernel/jump_label.c +++ linux-oracle-5.4.0/arch/s390/kernel/jump_label.c @@ -36,7 +36,7 @@ unsigned char *ipe = (unsigned char *)expected; unsigned char *ipn = (unsigned char *)new; - pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); + pr_emerg("Jump label code mismatch at %pS [%px]\n", ipc, ipc); pr_emerg("Found: %6ph\n", ipc); pr_emerg("Expected: %6ph\n", ipe); pr_emerg("New: %6ph\n", ipn); --- linux-oracle-5.4.0.orig/arch/s390/kernel/kmsg.c +++ linux-oracle-5.4.0/arch/s390/kernel/kmsg.c @@ -0,0 +1,114 @@ +/* + * Message printing with message catalog prefixes. + * + * Copyright IBM Corp. 2012 + */ + +#include +#include +#include +#include +#include + +static inline u32 __printk_jhash(const void *key, u32 length) +{ + u32 a, b, c, len; + const u8 *k; + u8 zk[12]; + + a = b = 0x9e3779b9; + c = 0; + for (len = length + 12, k = key; len >= 12; len -= 12, k += 12) { + if (len >= 24) { + a += k[0] | k[1] << 8 | k[2] << 16 | k[3] << 24; + b += k[4] | k[5] << 8 | k[6] << 16 | k[7] << 24; + c += k[8] | k[9] << 8 | k[10] << 16 | k[11] << 24; + } else { + memset(zk, 0, 12); + memcpy(zk, k, len - 12); + a += zk[0] | zk[1] << 8 | zk[2] << 16 | zk[3] << 24; + b += zk[4] | zk[5] << 8 | zk[6] << 16 | zk[7] << 24; + c += (u32) zk[8] << 8; + c += (u32) zk[9] << 16; + c += (u32) zk[10] << 24; + c += length; + } + a -= b + c; a ^= (c>>13); + b -= a + c; b ^= (a<<8); + c -= a + b; c ^= (b>>13); + a -= b + c; a ^= (c>>12); + b -= a + c; b ^= (a<<16); + c -= a + b; c ^= (b>>5); + a -= b + c; a ^= (c>>3); + b -= a + c; b ^= (a<<10); + c -= a + b; c ^= (b>>15); + } + return c; +} + +/** + * __jhash_string - calculate the six digit jhash of a string + * @str: string to calculate the jhash + */ +unsigned long long __jhash_string(const char *str) +{ + return __printk_jhash(str, strlen(str)) & 0xffffff; +} +EXPORT_SYMBOL(__jhash_string); + +static int __dev_printk_hash(const char *level, const struct device *dev, + struct va_format *vaf) +{ + if (!dev) + return printk("%s(NULL device *): %pV", level, vaf); + + return printk("%s%s.%06x: %pV", level, dev_driver_string(dev), + __printk_jhash(vaf->fmt, strlen(vaf->fmt)) & 0xffffff, + vaf); +} + +int dev_printk_hash(const char *level, const struct device *dev, + const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + int r; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + r = __dev_printk_hash(level, dev, &vaf); + va_end(args); + + return r; +} +EXPORT_SYMBOL(dev_printk_hash); + +#define define_dev_printk_hash_level(func, kern_level) \ +int func(const struct device *dev, const char *fmt, ...) \ +{ \ + struct va_format vaf; \ + va_list args; \ + int r; \ + \ + va_start(args, fmt); \ + \ + vaf.fmt = fmt; \ + vaf.va = &args; \ + \ + r = __dev_printk_hash(kern_level, dev, &vaf); \ + va_end(args); \ + \ + return r; \ +} \ +EXPORT_SYMBOL(func); + +define_dev_printk_hash_level(dev_emerg_hash, KERN_EMERG); +define_dev_printk_hash_level(dev_alert_hash, KERN_ALERT); +define_dev_printk_hash_level(dev_crit_hash, KERN_CRIT); +define_dev_printk_hash_level(dev_err_hash, KERN_ERR); +define_dev_printk_hash_level(dev_warn_hash, KERN_WARNING); +define_dev_printk_hash_level(dev_notice_hash, KERN_NOTICE); +define_dev_printk_hash_level(_dev_info_hash, KERN_INFO); --- linux-oracle-5.4.0.orig/arch/s390/kernel/kprobes.c +++ linux-oracle-5.4.0/arch/s390/kernel/kprobes.c @@ -56,21 +56,10 @@ static void copy_instruction(struct kprobe *p) { - unsigned long ip = (unsigned long) p->addr; s64 disp, new_disp; u64 addr, new_addr; - if (ftrace_location(ip) == ip) { - /* - * If kprobes patches the instruction that is morphed by - * ftrace make sure that kprobes always sees the branch - * "jg .+24" that skips the mcount block or the "brcl 0,0" - * in case of hotpatch. - */ - ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn); - p->ainsn.is_ftrace_insn = 1; - } else - memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8)); + memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8)); p->opcode = p->ainsn.insn[0]; if (!probe_is_insn_relative_long(p->ainsn.insn)) return; @@ -136,11 +125,6 @@ } NOKPROBE_SYMBOL(arch_prepare_kprobe); -int arch_check_ftrace_location(struct kprobe *p) -{ - return 0; -} - struct swap_insn_args { struct kprobe *p; unsigned int arm_kprobe : 1; @@ -149,28 +133,11 @@ static int swap_instruction(void *data) { struct swap_insn_args *args = data; - struct ftrace_insn new_insn, *insn; struct kprobe *p = args->p; - size_t len; + u16 opc; - new_insn.opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode; - len = sizeof(new_insn.opc); - if (!p->ainsn.is_ftrace_insn) - goto skip_ftrace; - len = sizeof(new_insn); - insn = (struct ftrace_insn *) p->addr; - if (args->arm_kprobe) { - if (is_ftrace_nop(insn)) - new_insn.disp = KPROBE_ON_FTRACE_NOP; - else - new_insn.disp = KPROBE_ON_FTRACE_CALL; - } else { - ftrace_generate_call_insn(&new_insn, (unsigned long)p->addr); - if (insn->disp == KPROBE_ON_FTRACE_NOP) - ftrace_generate_nop_insn(&new_insn); - } -skip_ftrace: - s390_kernel_write(p->addr, &new_insn, len); + opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode; + s390_kernel_write(p->addr, &opc, sizeof(opc)); return 0; } NOKPROBE_SYMBOL(swap_instruction); @@ -255,6 +222,7 @@ { __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp); kcb->kprobe_status = kcb->prev_kprobe.status; + kcb->prev_kprobe.kp = NULL; } NOKPROBE_SYMBOL(pop_kprobe); @@ -464,24 +432,6 @@ unsigned long ip = regs->psw.addr; int fixup = probe_get_fixup_type(p->ainsn.insn); - /* Check if the kprobes location is an enabled ftrace caller */ - if (p->ainsn.is_ftrace_insn) { - struct ftrace_insn *insn = (struct ftrace_insn *) p->addr; - struct ftrace_insn call_insn; - - ftrace_generate_call_insn(&call_insn, (unsigned long) p->addr); - /* - * A kprobe on an enabled ftrace call site actually single - * stepped an unconditional branch (ftrace nop equivalent). - * Now we need to fixup things and pretend that a brasl r0,... - * was executed instead. - */ - if (insn->disp == KPROBE_ON_FTRACE_CALL) { - ip += call_insn.disp * 2 - MCOUNT_INSN_SIZE; - regs->gprs[0] = (unsigned long)p->addr + sizeof(*insn); - } - } - if (fixup & FIXUP_PSW_NORMAL) ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn; @@ -509,12 +459,11 @@ if (!p) return 0; + resume_execution(p, regs); if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) { kcb->kprobe_status = KPROBE_HIT_SSDONE; p->post_handler(p, regs, 0); } - - resume_execution(p, regs); pop_kprobe(kcb); preempt_enable_no_resched(); --- linux-oracle-5.4.0.orig/arch/s390/kernel/machine_kexec.c +++ linux-oracle-5.4.0/arch/s390/kernel/machine_kexec.c @@ -164,7 +164,9 @@ #ifdef CONFIG_CRASH_DUMP int rc; + preempt_disable(); rc = CALL_ON_STACK(do_start_kdump, S390_lowcore.nodat_stack, 1, image); + preempt_enable(); return rc == 0; #else return false; @@ -254,10 +256,10 @@ VMCOREINFO_SYMBOL(lowcore_ptr); VMCOREINFO_SYMBOL(high_memory); VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); - mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); vmcoreinfo_append_str("SDMA=%lx\n", __sdma); vmcoreinfo_append_str("EDMA=%lx\n", __edma); vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); + mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note()); } void machine_shutdown(void) --- linux-oracle-5.4.0.orig/arch/s390/kernel/machine_kexec_file.c +++ linux-oracle-5.4.0/arch/s390/kernel/machine_kexec_file.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; struct module_signature *ms; unsigned long sig_len; + int ret; /* Skip signature verification when not secure IPLed. */ if (!ipl_secure_flag) @@ -62,11 +64,18 @@ return -EBADMSG; } - return verify_pkcs7_signature(kernel, kernel_len, - kernel + kernel_len, sig_len, - VERIFY_USE_PLATFORM_KEYRING, - VERIFYING_MODULE_SIGNATURE, - NULL, NULL); + ret = verify_pkcs7_signature(kernel, kernel_len, + kernel + kernel_len, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) + ret = verify_pkcs7_signature(kernel, kernel_len, + kernel + kernel_len, sig_len, + VERIFY_USE_PLATFORM_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + return ret; } #endif /* CONFIG_KEXEC_SIG */ @@ -151,7 +160,7 @@ buf.mem += crashk_res.start; buf.memsz = buf.bufsz; - data->parm->initrd_start = buf.mem; + data->parm->initrd_start = data->memsz; data->parm->initrd_size = buf.memsz; data->memsz += buf.memsz; @@ -170,13 +179,12 @@ struct kexec_buf buf; unsigned long addr; void *ptr, *end; + int ret; buf.image = image; data->memsz = ALIGN(data->memsz, PAGE_SIZE); buf.mem = data->memsz; - if (image->type == KEXEC_TYPE_CRASH) - buf.mem += crashk_res.start; ptr = (void *)ipl_cert_list_addr; end = ptr + ipl_cert_list_size; @@ -199,9 +207,13 @@ ptr += len; } + ret = -ENOMEM; buf.buffer = ipl_report_finish(data->report); + if (!buf.buffer) + goto out; buf.bufsz = data->report->size; buf.memsz = buf.bufsz; + image->arch.ipl_buf = buf.buffer; data->memsz += buf.memsz; @@ -209,7 +221,12 @@ data->kernel_buf + offsetof(struct lowcore, ipl_parmblock_ptr); *lc_ipl_parmblock_ptr = (__u32)buf.mem; - return kexec_add_buffer(&buf); + if (image->type == KEXEC_TYPE_CRASH) + buf.mem += crashk_res.start; + + ret = kexec_add_buffer(&buf); +out: + return ret; } void *kexec_file_add_components(struct kimage *image, @@ -269,6 +286,7 @@ { Elf_Rela *relas; int i, r_type; + int ret; relas = (void *)pi->ehdr + relsec->sh_offset; @@ -303,7 +321,11 @@ addr = section->sh_addr + relas[i].r_offset; r_type = ELF64_R_TYPE(relas[i].r_info); - arch_kexec_do_relocs(r_type, loc, val, addr); + ret = arch_kexec_do_relocs(r_type, loc, val, addr); + if (ret) { + pr_err("Unknown rela relocation: %d\n", r_type); + return -ENOEXEC; + } } return 0; } @@ -321,3 +343,11 @@ return kexec_image_probe_default(image, buf, buf_len); } + +int arch_kimage_file_post_load_cleanup(struct kimage *image) +{ + vfree(image->arch.ipl_buf); + image->arch.ipl_buf = NULL; + + return kexec_image_post_load_cleanup_default(image); +} --- linux-oracle-5.4.0.orig/arch/s390/kernel/machine_kexec_reloc.c +++ linux-oracle-5.4.0/arch/s390/kernel/machine_kexec_reloc.c @@ -28,6 +28,7 @@ break; case R_390_64: /* Direct 64 bit. */ case R_390_GLOB_DAT: + case R_390_JMP_SLOT: *(u64 *)loc = val; break; case R_390_PC16: /* PC relative 16 bit. */ --- linux-oracle-5.4.0.orig/arch/s390/kernel/mcount.S +++ linux-oracle-5.4.0/arch/s390/kernel/mcount.S @@ -26,6 +26,12 @@ #define STACK_PTREGS (STACK_FRAME_OVERHEAD) #define STACK_PTREGS_GPRS (STACK_PTREGS + __PT_GPRS) #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) +#ifdef __PACK_STACK +/* allocate just enough for r14, r15 and backchain */ +#define TRACED_FUNC_FRAME_SIZE 24 +#else +#define TRACED_FUNC_FRAME_SIZE STACK_FRAME_OVERHEAD +#endif ENTRY(_mcount) BR_EX %r14 @@ -35,25 +41,39 @@ ENTRY(ftrace_caller) .globl ftrace_regs_caller .set ftrace_regs_caller,ftrace_caller + stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller + lghi %r14,0 # save condition code + ipm %r14 # don't put any instructions + sllg %r14,%r14,16 # clobbering CC before this point lgr %r1,%r15 #if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT)) aghi %r0,MCOUNT_RETURN_FIXUP #endif - aghi %r15,-STACK_FRAME_SIZE + # allocate stack frame for ftrace_caller to contain traced function + aghi %r15,-TRACED_FUNC_FRAME_SIZE stg %r1,__SF_BACKCHAIN(%r15) + stg %r0,(__SF_GPRS+8*8)(%r15) + stg %r15,(__SF_GPRS+9*8)(%r15) + # allocate pt_regs and stack frame for ftrace_trace_function + aghi %r15,-STACK_FRAME_SIZE stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) + stg %r14,(STACK_PTREGS_PSW)(%r15) + lg %r14,(__SF_GPRS+8*8)(%r1) # restore original return address + stosm (STACK_PTREGS_PSW)(%r15),0 + aghi %r1,-TRACED_FUNC_FRAME_SIZE + stg %r1,__SF_BACKCHAIN(%r15) stg %r0,(STACK_PTREGS_PSW+8)(%r15) stmg %r2,%r14,(STACK_PTREGS_GPRS+2*8)(%r15) #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES aghik %r2,%r0,-MCOUNT_INSN_SIZE lgrl %r4,function_trace_op - lgrl %r1,ftrace_trace_function + lgrl %r1,ftrace_func #else lgr %r2,%r0 aghi %r2,-MCOUNT_INSN_SIZE larl %r4,function_trace_op lg %r4,0(%r4) - larl %r1,ftrace_trace_function + larl %r1,ftrace_func lg %r1,0(%r1) #endif lgr %r3,%r14 --- linux-oracle-5.4.0.orig/arch/s390/kernel/nmi.c +++ linux-oracle-5.4.0/arch/s390/kernel/nmi.c @@ -179,7 +179,7 @@ "malfunction (code 0x%016lx).\n", mcck.mcck_code); printk(KERN_EMERG "mcck: task: %s, pid: %d.\n", current->comm, current->pid); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } } EXPORT_SYMBOL_GPL(s390_handle_mcck); --- linux-oracle-5.4.0.orig/arch/s390/kernel/perf_cpum_cf.c +++ linux-oracle-5.4.0/arch/s390/kernel/perf_cpum_cf.c @@ -199,7 +199,7 @@ [PERF_COUNT_HW_BUS_CYCLES] = -1, }; -static int __hw_perf_event_init(struct perf_event *event) +static int __hw_perf_event_init(struct perf_event *event, unsigned int type) { struct perf_event_attr *attr = &event->attr; struct hw_perf_event *hwc = &event->hw; @@ -207,7 +207,7 @@ int err = 0; u64 ev; - switch (attr->type) { + switch (type) { case PERF_TYPE_RAW: /* Raw events are used to access counters directly, * hence do not permit excludes */ @@ -292,19 +292,38 @@ return err; } +/* Events CPU_CYLCES and INSTRUCTIONS can be submitted with two different + * attribute::type values: + * - PERF_TYPE_HARDWARE: + * - pmu->type: + * Handle both type of invocations identical. They address the same hardware. + * The result is different when event modifiers exclude_kernel and/or + * exclude_user are also set. + */ +static int cpumf_pmu_event_type(struct perf_event *event) +{ + u64 ev = event->attr.config; + + if (cpumf_generic_events_basic[PERF_COUNT_HW_CPU_CYCLES] == ev || + cpumf_generic_events_basic[PERF_COUNT_HW_INSTRUCTIONS] == ev || + cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev || + cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev) + return PERF_TYPE_HARDWARE; + return PERF_TYPE_RAW; +} + static int cpumf_pmu_event_init(struct perf_event *event) { + unsigned int type = event->attr.type; int err; - switch (event->attr.type) { - case PERF_TYPE_HARDWARE: - case PERF_TYPE_HW_CACHE: - case PERF_TYPE_RAW: - err = __hw_perf_event_init(event); - break; - default: + if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW) + err = __hw_perf_event_init(event, type); + else if (event->pmu->type == type) + /* Registered as unknown PMU */ + err = __hw_perf_event_init(event, cpumf_pmu_event_type(event)); + else return -ENOENT; - } if (unlikely(err) && event->destroy) event->destroy(event); @@ -553,7 +572,7 @@ return -ENODEV; cpumf_pmu.attr_groups = cpumf_cf_event_group(); - rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW); + rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", -1); if (rc) pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); return rc; --- linux-oracle-5.4.0.orig/arch/s390/kernel/perf_cpum_cf_diag.c +++ linux-oracle-5.4.0/arch/s390/kernel/perf_cpum_cf_diag.c @@ -243,13 +243,13 @@ int err = -ENOENT; debug_sprintf_event(cf_diag_dbg, 5, - "%s event %p cpu %d config %#llx " + "%s event %p cpu %d config %#llx type:%u " "sample_type %#llx cf_diag_events %d\n", __func__, - event, event->cpu, attr->config, attr->sample_type, - atomic_read(&cf_diag_events)); + event, event->cpu, attr->config, event->pmu->type, + attr->sample_type, atomic_read(&cf_diag_events)); if (event->attr.config != PERF_EVENT_CPUM_CF_DIAG || - event->attr.type != PERF_TYPE_RAW) + event->attr.type != event->pmu->type) goto out; /* Raw events are used to access counters directly, @@ -308,7 +308,7 @@ case CPUMF_CTR_SET_CRYPTO: if (info->csvn >= 1 && info->csvn <= 5) ctrset_size = 16; - else if (info->csvn == 6) + else if (info->csvn == 6 || info->csvn == 7) ctrset_size = 20; break; case CPUMF_CTR_SET_EXT: @@ -318,7 +318,7 @@ ctrset_size = 48; else if (info->csvn >= 3 && info->csvn <= 5) ctrset_size = 128; - else if (info->csvn == 6) + else if (info->csvn == 6 || info->csvn == 7) ctrset_size = 160; break; case CPUMF_CTR_SET_MT_DIAG: @@ -693,7 +693,7 @@ } debug_register_view(cf_diag_dbg, &debug_sprintf_view); - rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", PERF_TYPE_RAW); + rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", -1); if (rc) { debug_unregister_view(cf_diag_dbg, &debug_sprintf_view); debug_unregister(cf_diag_dbg); --- linux-oracle-5.4.0.orig/arch/s390/kernel/perf_cpum_cf_events.c +++ linux-oracle-5.4.0/arch/s390/kernel/perf_cpum_cf_events.c @@ -238,6 +238,134 @@ CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); CPUMF_EVENT_ATTR(cf_z14, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); +CPUMF_EVENT_ATTR(cf_z15, L1D_RO_EXCL_WRITES, 0x0080); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_WRITES, 0x0081); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_MISSES, 0x0082); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_HPAGE_WRITES, 0x0083); +CPUMF_EVENT_ATTR(cf_z15, DTLB2_GPAGE_WRITES, 0x0084); +CPUMF_EVENT_ATTR(cf_z15, L1D_L2D_SOURCED_WRITES, 0x0085); +CPUMF_EVENT_ATTR(cf_z15, ITLB2_WRITES, 0x0086); +CPUMF_EVENT_ATTR(cf_z15, ITLB2_MISSES, 0x0087); +CPUMF_EVENT_ATTR(cf_z15, L1I_L2I_SOURCED_WRITES, 0x0088); +CPUMF_EVENT_ATTR(cf_z15, TLB2_PTE_WRITES, 0x0089); +CPUMF_EVENT_ATTR(cf_z15, TLB2_CRSTE_WRITES, 0x008a); +CPUMF_EVENT_ATTR(cf_z15, TLB2_ENGINES_BUSY, 0x008b); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TEND, 0x008c); +CPUMF_EVENT_ATTR(cf_z15, TX_NC_TEND, 0x008d); +CPUMF_EVENT_ATTR(cf_z15, L1C_TLB2_MISSES, 0x008f); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0090); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_MEMORY_SOURCED_WRITES, 0x0091); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_IV, 0x0092); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES, 0x0093); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_MEMORY_SOURCED_WRITES, 0x0094); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES_IV, 0x0095); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES, 0x0096); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES, 0x0097); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV, 0x0098); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES, 0x0099); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_MEMORY_SOURCED_WRITES, 0x009a); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES_IV, 0x009b); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONDRAWER_L4_SOURCED_WRITES, 0x009c); +CPUMF_EVENT_ATTR(cf_z15, L1D_OFFDRAWER_L4_SOURCED_WRITES, 0x009d); +CPUMF_EVENT_ATTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_RO, 0x009e); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES, 0x00a2); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_MEMORY_SOURCED_WRITES, 0x00a3); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES_IV, 0x00a4); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES, 0x00a5); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_MEMORY_SOURCED_WRITES, 0x00a6); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES_IV, 0x00a7); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES, 0x00a8); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES, 0x00a9); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV, 0x00aa); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES, 0x00ab); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_MEMORY_SOURCED_WRITES, 0x00ac); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES_IV, 0x00ad); +CPUMF_EVENT_ATTR(cf_z15, L1I_ONDRAWER_L4_SOURCED_WRITES, 0x00ae); +CPUMF_EVENT_ATTR(cf_z15, L1I_OFFDRAWER_L4_SOURCED_WRITES, 0x00af); +CPUMF_EVENT_ATTR(cf_z15, BCD_DFP_EXECUTION_SLOTS, 0x00e0); +CPUMF_EVENT_ATTR(cf_z15, VX_BCD_EXECUTION_SLOTS, 0x00e1); +CPUMF_EVENT_ATTR(cf_z15, DECIMAL_INSTRUCTIONS, 0x00e2); +CPUMF_EVENT_ATTR(cf_z15, LAST_HOST_TRANSLATIONS, 0x00e8); +CPUMF_EVENT_ATTR(cf_z15, TX_NC_TABORT, 0x00f3); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TABORT_NO_SPECIAL, 0x00f4); +CPUMF_EVENT_ATTR(cf_z15, TX_C_TABORT_SPECIAL, 0x00f5); +CPUMF_EVENT_ATTR(cf_z15, DFLT_ACCESS, 0x00f7); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CYCLES, 0x00fc); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CC, 0x00108); +CPUMF_EVENT_ATTR(cf_z15, DFLT_CCFINISH, 0x00109); +CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); +CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); +CPUMF_EVENT_ATTR(cf_z16, L1D_RO_EXCL_WRITES, 0x0080); +CPUMF_EVENT_ATTR(cf_z16, DTLB2_WRITES, 0x0081); +CPUMF_EVENT_ATTR(cf_z16, DTLB2_MISSES, 0x0082); +CPUMF_EVENT_ATTR(cf_z16, CRSTE_1MB_WRITES, 0x0083); +CPUMF_EVENT_ATTR(cf_z16, DTLB2_GPAGE_WRITES, 0x0084); +CPUMF_EVENT_ATTR(cf_z16, ITLB2_WRITES, 0x0086); +CPUMF_EVENT_ATTR(cf_z16, ITLB2_MISSES, 0x0087); +CPUMF_EVENT_ATTR(cf_z16, TLB2_PTE_WRITES, 0x0089); +CPUMF_EVENT_ATTR(cf_z16, TLB2_CRSTE_WRITES, 0x008a); +CPUMF_EVENT_ATTR(cf_z16, TLB2_ENGINES_BUSY, 0x008b); +CPUMF_EVENT_ATTR(cf_z16, TX_C_TEND, 0x008c); +CPUMF_EVENT_ATTR(cf_z16, TX_NC_TEND, 0x008d); +CPUMF_EVENT_ATTR(cf_z16, L1C_TLB2_MISSES, 0x008f); +CPUMF_EVENT_ATTR(cf_z16, DCW_REQ, 0x0091); +CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_IV, 0x0092); +CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_CHIP_HIT, 0x0093); +CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_DRAWER_HIT, 0x0094); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP, 0x0095); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_IV, 0x0096); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_CHIP_HIT, 0x0097); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_DRAWER_HIT, 0x0098); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_MODULE, 0x0099); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_DRAWER, 0x009a); +CPUMF_EVENT_ATTR(cf_z16, DCW_OFF_DRAWER, 0x009b); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_MEMORY, 0x009c); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_MODULE_MEMORY, 0x009d); +CPUMF_EVENT_ATTR(cf_z16, DCW_ON_DRAWER_MEMORY, 0x009e); +CPUMF_EVENT_ATTR(cf_z16, DCW_OFF_DRAWER_MEMORY, 0x009f); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_IV, 0x00a0); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_CHIP_HIT, 0x00a1); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_DRAWER_HIT, 0x00a2); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_IV, 0x00a3); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_CHIP_HIT, 0x00a4); +CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_DRAWER_HIT, 0x00a5); +CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_IV, 0x00a6); +CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_CHIP_HIT, 0x00a7); +CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_DRAWER_HIT, 0x00a8); +CPUMF_EVENT_ATTR(cf_z16, ICW_REQ, 0x00a9); +CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_IV, 0x00aa); +CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_CHIP_HIT, 0x00ab); +CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_DRAWER_HIT, 0x00ac); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP, 0x00ad); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_IV, 0x00ae); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_CHIP_HIT, 0x00af); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_DRAWER_HIT, 0x00b0); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_MODULE, 0x00b1); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_DRAWER, 0x00b2); +CPUMF_EVENT_ATTR(cf_z16, ICW_OFF_DRAWER, 0x00b3); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_MEMORY, 0x00b4); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_MODULE_MEMORY, 0x00b5); +CPUMF_EVENT_ATTR(cf_z16, ICW_ON_DRAWER_MEMORY, 0x00b6); +CPUMF_EVENT_ATTR(cf_z16, ICW_OFF_DRAWER_MEMORY, 0x00b7); +CPUMF_EVENT_ATTR(cf_z16, BCD_DFP_EXECUTION_SLOTS, 0x00e0); +CPUMF_EVENT_ATTR(cf_z16, VX_BCD_EXECUTION_SLOTS, 0x00e1); +CPUMF_EVENT_ATTR(cf_z16, DECIMAL_INSTRUCTIONS, 0x00e2); +CPUMF_EVENT_ATTR(cf_z16, LAST_HOST_TRANSLATIONS, 0x00e8); +CPUMF_EVENT_ATTR(cf_z16, TX_NC_TABORT, 0x00f4); +CPUMF_EVENT_ATTR(cf_z16, TX_C_TABORT_NO_SPECIAL, 0x00f5); +CPUMF_EVENT_ATTR(cf_z16, TX_C_TABORT_SPECIAL, 0x00f6); +CPUMF_EVENT_ATTR(cf_z16, DFLT_ACCESS, 0x00f8); +CPUMF_EVENT_ATTR(cf_z16, DFLT_CYCLES, 0x00fd); +CPUMF_EVENT_ATTR(cf_z16, SORTL, 0x0100); +CPUMF_EVENT_ATTR(cf_z16, DFLT_CC, 0x0109); +CPUMF_EVENT_ATTR(cf_z16, DFLT_CCFINISH, 0x010a); +CPUMF_EVENT_ATTR(cf_z16, NNPA_INVOCATIONS, 0x010b); +CPUMF_EVENT_ATTR(cf_z16, NNPA_COMPLETIONS, 0x010c); +CPUMF_EVENT_ATTR(cf_z16, NNPA_WAIT_LOCK, 0x010d); +CPUMF_EVENT_ATTR(cf_z16, NNPA_HOLD_LOCK, 0x010e); +CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0); +CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1); + static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = { CPUMF_EVENT_PTR(cf_fvn1, CPU_CYCLES), CPUMF_EVENT_PTR(cf_fvn1, INSTRUCTIONS), @@ -286,7 +414,7 @@ NULL, }; -static struct attribute *cpumcf_svn_6_pmu_event_attr[] __initdata = { +static struct attribute *cpumcf_svn_67_pmu_event_attr[] __initdata = { CPUMF_EVENT_PTR(cf_svn_12345, PRNG_FUNCTIONS), CPUMF_EVENT_PTR(cf_svn_12345, PRNG_CYCLES), CPUMF_EVENT_PTR(cf_svn_12345, PRNG_BLOCKED_FUNCTIONS), @@ -516,6 +644,141 @@ NULL, }; +static struct attribute *cpumcf_z15_pmu_event_attr[] __initdata = { + CPUMF_EVENT_PTR(cf_z15, L1D_RO_EXCL_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_HPAGE_WRITES), + CPUMF_EVENT_PTR(cf_z15, DTLB2_GPAGE_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_L2D_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, ITLB2_WRITES), + CPUMF_EVENT_PTR(cf_z15, ITLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, L1I_L2I_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_PTE_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_CRSTE_WRITES), + CPUMF_EVENT_PTR(cf_z15, TLB2_ENGINES_BUSY), + CPUMF_EVENT_PTR(cf_z15, TX_C_TEND), + CPUMF_EVENT_PTR(cf_z15, TX_NC_TEND), + CPUMF_EVENT_PTR(cf_z15, L1C_TLB2_MISSES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1D_ONDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_OFFDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1D_ONCHIP_L3_SOURCED_WRITES_RO), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCHIP_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_ONCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFCLUSTER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_MEMORY_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L3_SOURCED_WRITES_IV), + CPUMF_EVENT_PTR(cf_z15, L1I_ONDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, L1I_OFFDRAWER_L4_SOURCED_WRITES), + CPUMF_EVENT_PTR(cf_z15, BCD_DFP_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z15, VX_BCD_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z15, DECIMAL_INSTRUCTIONS), + CPUMF_EVENT_PTR(cf_z15, LAST_HOST_TRANSLATIONS), + CPUMF_EVENT_PTR(cf_z15, TX_NC_TABORT), + CPUMF_EVENT_PTR(cf_z15, TX_C_TABORT_NO_SPECIAL), + CPUMF_EVENT_PTR(cf_z15, TX_C_TABORT_SPECIAL), + CPUMF_EVENT_PTR(cf_z15, DFLT_ACCESS), + CPUMF_EVENT_PTR(cf_z15, DFLT_CYCLES), + CPUMF_EVENT_PTR(cf_z15, DFLT_CC), + CPUMF_EVENT_PTR(cf_z15, DFLT_CCFINISH), + CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE), + CPUMF_EVENT_PTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE), + NULL, +}; + +static struct attribute *cpumcf_z16_pmu_event_attr[] __initdata = { + CPUMF_EVENT_PTR(cf_z16, L1D_RO_EXCL_WRITES), + CPUMF_EVENT_PTR(cf_z16, DTLB2_WRITES), + CPUMF_EVENT_PTR(cf_z16, DTLB2_MISSES), + CPUMF_EVENT_PTR(cf_z16, CRSTE_1MB_WRITES), + CPUMF_EVENT_PTR(cf_z16, DTLB2_GPAGE_WRITES), + CPUMF_EVENT_PTR(cf_z16, ITLB2_WRITES), + CPUMF_EVENT_PTR(cf_z16, ITLB2_MISSES), + CPUMF_EVENT_PTR(cf_z16, TLB2_PTE_WRITES), + CPUMF_EVENT_PTR(cf_z16, TLB2_CRSTE_WRITES), + CPUMF_EVENT_PTR(cf_z16, TLB2_ENGINES_BUSY), + CPUMF_EVENT_PTR(cf_z16, TX_C_TEND), + CPUMF_EVENT_PTR(cf_z16, TX_NC_TEND), + CPUMF_EVENT_PTR(cf_z16, L1C_TLB2_MISSES), + CPUMF_EVENT_PTR(cf_z16, DCW_REQ), + CPUMF_EVENT_PTR(cf_z16, DCW_REQ_IV), + CPUMF_EVENT_PTR(cf_z16, DCW_REQ_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, DCW_REQ_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_IV), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_MODULE), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_DRAWER), + CPUMF_EVENT_PTR(cf_z16, DCW_OFF_DRAWER), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_MEMORY), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_MODULE_MEMORY), + CPUMF_EVENT_PTR(cf_z16, DCW_ON_DRAWER_MEMORY), + CPUMF_EVENT_PTR(cf_z16, DCW_OFF_DRAWER_MEMORY), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_IV), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_IV), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_IV), + CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, ICW_REQ), + CPUMF_EVENT_PTR(cf_z16, ICW_REQ_IV), + CPUMF_EVENT_PTR(cf_z16, ICW_REQ_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, ICW_REQ_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_IV), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_CHIP_HIT), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_DRAWER_HIT), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_MODULE), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_DRAWER), + CPUMF_EVENT_PTR(cf_z16, ICW_OFF_DRAWER), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_MEMORY), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_MODULE_MEMORY), + CPUMF_EVENT_PTR(cf_z16, ICW_ON_DRAWER_MEMORY), + CPUMF_EVENT_PTR(cf_z16, ICW_OFF_DRAWER_MEMORY), + CPUMF_EVENT_PTR(cf_z16, BCD_DFP_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z16, VX_BCD_EXECUTION_SLOTS), + CPUMF_EVENT_PTR(cf_z16, DECIMAL_INSTRUCTIONS), + CPUMF_EVENT_PTR(cf_z16, LAST_HOST_TRANSLATIONS), + CPUMF_EVENT_PTR(cf_z16, TX_NC_TABORT), + CPUMF_EVENT_PTR(cf_z16, TX_C_TABORT_NO_SPECIAL), + CPUMF_EVENT_PTR(cf_z16, TX_C_TABORT_SPECIAL), + CPUMF_EVENT_PTR(cf_z16, DFLT_ACCESS), + CPUMF_EVENT_PTR(cf_z16, DFLT_CYCLES), + CPUMF_EVENT_PTR(cf_z16, SORTL), + CPUMF_EVENT_PTR(cf_z16, DFLT_CC), + CPUMF_EVENT_PTR(cf_z16, DFLT_CCFINISH), + CPUMF_EVENT_PTR(cf_z16, NNPA_INVOCATIONS), + CPUMF_EVENT_PTR(cf_z16, NNPA_COMPLETIONS), + CPUMF_EVENT_PTR(cf_z16, NNPA_WAIT_LOCK), + CPUMF_EVENT_PTR(cf_z16, NNPA_HOLD_LOCK), + CPUMF_EVENT_PTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE), + CPUMF_EVENT_PTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE), + NULL, +}; + /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ static struct attribute_group cpumcf_pmu_events_group = { @@ -596,8 +859,8 @@ case 1 ... 5: csvn = cpumcf_svn_12345_pmu_event_attr; break; - case 6: - csvn = cpumcf_svn_6_pmu_event_attr; + case 6 ... 7: + csvn = cpumcf_svn_67_pmu_event_attr; break; default: csvn = none; @@ -624,9 +887,15 @@ break; case 0x3906: case 0x3907: + model = cpumcf_z14_pmu_event_attr; + break; case 0x8561: case 0x8562: - model = cpumcf_z14_pmu_event_attr; + model = cpumcf_z15_pmu_event_attr; + break; + case 0x3931: + case 0x3932: + model = cpumcf_z16_pmu_event_attr; break; default: model = none; --- linux-oracle-5.4.0.orig/arch/s390/kernel/perf_cpum_sf.c +++ linux-oracle-5.4.0/arch/s390/kernel/perf_cpum_sf.c @@ -193,7 +193,7 @@ unsigned long num_sdb, gfp_t gfp_flags) { int i, rc; - unsigned long *new, *tail; + unsigned long *new, *tail, *tail_prev = NULL; if (!sfb->sdbt || !sfb->tail) return -EINVAL; @@ -232,6 +232,7 @@ sfb->num_sdbt++; /* Link current page to tail of chain */ *tail = (unsigned long)(void *) new + 1; + tail_prev = tail; tail = new; } @@ -241,10 +242,22 @@ * issue, a new realloc call (if required) might succeed. */ rc = alloc_sample_data_block(tail, gfp_flags); - if (rc) + if (rc) { + /* Undo last SDBT. An SDBT with no SDB at its first + * entry but with an SDBT entry instead can not be + * handled by the interrupt handler code. + * Avoid this situation. + */ + if (tail_prev) { + sfb->num_sdbt--; + free_page((unsigned long) new); + tail = tail_prev; + } break; + } sfb->num_sdb++; tail++; + tail_prev = new = NULL; /* Allocated at least one SBD */ } /* Link sampling buffer to its origin */ @@ -1169,7 +1182,7 @@ sample = (struct hws_basic_entry *) *sdbt; while ((unsigned long *) sample < (unsigned long *) te) { /* Check for an empty sample */ - if (!sample->def) + if (!sample->def || sample->LS) break; /* Update perf event period */ @@ -1300,18 +1313,28 @@ */ if (flush_all && done) break; - - /* If an event overflow happened, discard samples by - * processing any remaining sample-data-blocks. - */ - if (event_overflow) - flush_all = 1; } /* Account sample overflows in the event hardware structure */ if (sampl_overflow) OVERFLOW_REG(hwc) = DIV_ROUND_UP(OVERFLOW_REG(hwc) + sampl_overflow, 1 + num_sdb); + + /* Perf_event_overflow() and perf_event_account_interrupt() limit + * the interrupt rate to an upper limit. Roughly 1000 samples per + * task tick. + * Hitting this limit results in a large number + * of throttled REF_REPORT_THROTTLE entries and the samples + * are dropped. + * Slightly increase the interval to avoid hitting this limit. + */ + if (event_overflow) { + SAMPL_RATE(hwc) += DIV_ROUND_UP(SAMPL_RATE(hwc), 10); + debug_sprintf_event(sfdbg, 1, "%s: rate adjustment %ld\n", + __func__, + DIV_ROUND_UP(SAMPL_RATE(hwc), 10)); + } + if (sampl_overflow || event_overflow) debug_sprintf_event(sfdbg, 4, "hw_perf_event_update: " "overflow stats: sample=%llu event=%llu\n", @@ -1389,7 +1412,7 @@ unsigned long head, base, offset; struct hws_trailer_entry *te; - if (WARN_ON_ONCE(handle->head & ~PAGE_MASK)) + if (handle->head & ~PAGE_MASK) return -EINVAL; aux->head = handle->head >> PAGE_SHIFT; @@ -1406,8 +1429,8 @@ idx = aux->empty_mark + 1; for (i = 0; i < range_scan; i++, idx++) { te = aux_sdb_trailer(aux, idx); - te->flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK; - te->flags = te->flags & ~SDB_TE_ALERT_REQ_MASK; + te->flags &= ~(SDB_TE_BUFFER_FULL_MASK | + SDB_TE_ALERT_REQ_MASK); te->overflow = 0; } /* Save the position of empty SDBs */ @@ -1454,8 +1477,7 @@ te = aux_sdb_trailer(aux, alert_index); do { orig_flags = te->flags; - orig_overflow = te->overflow; - *overflow = orig_overflow; + *overflow = orig_overflow = te->overflow; if (orig_flags & SDB_TE_BUFFER_FULL_MASK) { /* * SDB is already set by hardware. @@ -1558,7 +1580,7 @@ unsigned long num_sdb; aux = perf_get_aux(handle); - if (WARN_ON_ONCE(!aux)) + if (!aux) return; /* Inform user space new data arrived */ @@ -1566,6 +1588,7 @@ perf_aux_output_end(handle, size); num_sdb = aux->sfb.num_sdb; + num_sdb = aux->sfb.num_sdb; while (!done) { /* Get an output handle */ aux = perf_aux_output_begin(handle, cpuhw->event); @@ -1576,7 +1599,7 @@ debug_sprintf_event(sfdbg, 1, "AUX buffer used up\n"); break; } - if (WARN_ON_ONCE(!aux)) + if (!aux) return; /* Update head and alert_mark to new position */ @@ -1688,7 +1711,7 @@ } /* Allocate aux_buffer struct for the event */ - aux = kmalloc(sizeof(struct aux_buffer), GFP_KERNEL); + aux = kzalloc(sizeof(struct aux_buffer), GFP_KERNEL); if (!aux) goto no_aux; sfb = &aux->sfb; @@ -1813,12 +1836,8 @@ { struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf); - if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + if (!(event->hw.state & PERF_HES_STOPPED)) return; - - if (flags & PERF_EF_RELOAD) - WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); - perf_pmu_disable(event->pmu); event->hw.state = 0; cpuhw->lsctl.cs = 1; @@ -1843,7 +1862,9 @@ event->hw.state |= PERF_HES_STOPPED; if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) { - hw_perf_event_update(event, 1); + /* CPU hotplug off removes SDBs. No samples to extract. */ + if (cpuhw->flags & PMU_F_RESERVED) + hw_perf_event_update(event, 1); event->hw.state |= PERF_HES_UPTODATE; } perf_pmu_enable(event->pmu); @@ -2194,4 +2215,4 @@ } arch_initcall(init_cpum_sampling_pmu); -core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640); +core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0644); --- linux-oracle-5.4.0.orig/arch/s390/kernel/perf_event.c +++ linux-oracle-5.4.0/arch/s390/kernel/perf_event.c @@ -224,9 +224,13 @@ struct pt_regs *regs) { struct unwind_state state; + unsigned long addr; - unwind_for_each_frame(&state, current, regs, 0) - perf_callchain_store(entry, state.ip); + unwind_for_each_frame(&state, current, regs, 0) { + addr = unwind_get_return_address(&state); + if (!addr || perf_callchain_store(entry, addr)) + return; + } } /* Perf definitions for PMU event attributes in sysfs */ --- linux-oracle-5.4.0.orig/arch/s390/kernel/pgm_check.S +++ linux-oracle-5.4.0/arch/s390/kernel/pgm_check.S @@ -78,8 +78,8 @@ PGM_CHECK(do_dat_exception) /* 3a */ PGM_CHECK(do_dat_exception) /* 3b */ PGM_CHECK_DEFAULT /* 3c */ -PGM_CHECK_DEFAULT /* 3d */ -PGM_CHECK_DEFAULT /* 3e */ +PGM_CHECK(do_secure_storage_access) /* 3d */ +PGM_CHECK(do_non_secure_storage_access) /* 3e */ PGM_CHECK_DEFAULT /* 3f */ PGM_CHECK_DEFAULT /* 40 */ PGM_CHECK_DEFAULT /* 41 */ --- linux-oracle-5.4.0.orig/arch/s390/kernel/process.c +++ linux-oracle-5.4.0/arch/s390/kernel/process.c @@ -76,6 +76,18 @@ memcpy(dst, src, arch_task_struct_size); dst->thread.fpu.regs = dst->thread.fpu.fprs; + + /* + * Don't transfer over the runtime instrumentation or the guarded + * storage control block pointers. These fields are cleared here instead + * of in copy_thread() to avoid premature freeing of associated memory + * on fork() failure. Wait to clear the RI flag because ->stack still + * refers to the source thread. + */ + dst->thread.ri_cb = NULL; + dst->thread.gs_cb = NULL; + dst->thread.gs_bc_cb = NULL; + return 0; } @@ -105,6 +117,7 @@ p->thread.system_timer = 0; p->thread.hardirq_timer = 0; p->thread.softirq_timer = 0; + p->thread.last_break = 1; frame->sf.back_chain = 0; /* new return point is ret_from_fork */ @@ -132,13 +145,11 @@ frame->childregs.flags = 0; if (new_stackp) frame->childregs.gprs[15] = new_stackp; - - /* Don't copy runtime instrumentation info */ - p->thread.ri_cb = NULL; + /* + * Clear the runtime instrumentation flag after the above childregs + * copy. The CB pointer was already cleared in arch_dup_task_struct(). + */ frame->childregs.psw.mask &= ~PSW_MASK_RI; - /* Don't copy guarded storage control block */ - p->thread.gs_cb = NULL; - p->thread.gs_bc_cb = NULL; /* Set a new TLS ? */ if (clone_flags & CLONE_SETTLS) { --- linux-oracle-5.4.0.orig/arch/s390/kernel/processor.c +++ linux-oracle-5.4.0/arch/s390/kernel/processor.c @@ -165,8 +165,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long n = (unsigned long) v - 1; + unsigned long first = cpumask_first(cpu_online_mask); - if (!n) + if (n == first) show_cpu_summary(m, v); if (!machine_has_cpu_mhz) return 0; @@ -179,6 +180,8 @@ { if (*pos) *pos = cpumask_next(*pos - 1, cpu_online_mask); + else + *pos = cpumask_first(cpu_online_mask); return *pos < nr_cpu_ids ? (void *)*pos + 1 : NULL; } --- linux-oracle-5.4.0.orig/arch/s390/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/s390/kernel/ptrace.c @@ -324,6 +324,25 @@ child->thread.per_user.end = data; } +static void fixup_int_code(struct task_struct *child, addr_t data) +{ + struct pt_regs *regs = task_pt_regs(child); + int ilc = regs->int_code >> 16; + u16 insn; + + if (ilc > 6) + return; + + if (ptrace_access_vm(child, regs->psw.addr - (regs->int_code >> 16), + &insn, sizeof(insn), FOLL_FORCE) != sizeof(insn)) + return; + + /* double check that tracee stopped on svc instruction */ + if ((insn >> 8) != 0xa) + return; + + regs->int_code = 0x20000 | (data & 0xffff); +} /* * Write a word to the user area of a process at location addr. This * operation does have an additional problem compared to peek_user. @@ -335,7 +354,9 @@ struct user *dummy = NULL; addr_t offset; + if (addr < (addr_t) &dummy->regs.acrs) { + struct pt_regs *regs = task_pt_regs(child); /* * psw and gprs are stored on the stack */ @@ -353,7 +374,11 @@ /* Invalid addressing mode bits */ return -EINVAL; } - *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; + + if (test_pt_regs_flag(regs, PIF_SYSCALL) && + addr == offsetof(struct user, regs.gprs[2])) + fixup_int_code(child, data); + *(addr_t *)((addr_t) ®s->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { /* @@ -388,6 +413,7 @@ /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if ((unsigned int) data != 0 || test_fp_ctl(data >> (BITS_PER_LONG - 32))) return -EINVAL; @@ -477,9 +503,7 @@ } return 0; case PTRACE_GET_LAST_BREAK: - put_user(child->thread.last_break, - (unsigned long __user *) data); - return 0; + return put_user(child->thread.last_break, (unsigned long __user *)data); case PTRACE_ENABLE_TE: if (!MACHINE_HAS_TE) return -EIO; @@ -719,6 +743,10 @@ regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) | (__u64)(tmp & PSW32_ADDR_AMODE); } else { + + if (test_pt_regs_flag(regs, PIF_SYSCALL) && + addr == offsetof(struct compat_user, regs.gprs[2])) + fixup_int_code(child, data); /* gpr 0-15 */ *(__u32*)((addr_t) ®s->psw + addr*2 + 4) = tmp; } @@ -746,6 +774,7 @@ /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if (test_fp_ctl(tmp)) return -EINVAL; child->thread.fpu.fpc = data; @@ -827,9 +856,7 @@ } return 0; case PTRACE_GET_LAST_BREAK: - put_user(child->thread.last_break, - (unsigned int __user *) data); - return 0; + return put_user(child->thread.last_break, (unsigned int __user *)data); } return compat_ptrace_request(child, request, addr, data); } @@ -838,40 +865,45 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { unsigned long mask = -1UL; + long ret = -1; /* * The sysc_tracesys code in entry.S stored the system * call number to gprs[2]. */ if (test_thread_flag(TIF_SYSCALL_TRACE) && - (tracehook_report_syscall_entry(regs) || - regs->gprs[2] >= NR_syscalls)) { + tracehook_report_syscall_entry(regs)) { /* - * Tracing decided this syscall should not happen or the - * debugger stored an invalid system call number. Skip + * Tracing decided this syscall should not happen. Skip * the system call and the system call restart handling. */ - clear_pt_regs_flag(regs, PIF_SYSCALL); - return -1; + goto skip; } /* Do the secure computing check after ptrace. */ if (secure_computing(NULL)) { /* seccomp failures shouldn't expose any additional code. */ - return -1; + goto skip; } if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) - trace_sys_enter(regs, regs->gprs[2]); + trace_sys_enter(regs, regs->int_code & 0xffff); if (is_compat_task()) mask = 0xffffffff; - audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask, + audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask, regs->gprs[3] &mask, regs->gprs[4] &mask, regs->gprs[5] &mask); + if ((signed long)regs->gprs[2] >= NR_syscalls) { + regs->gprs[2] = -ENOSYS; + ret = -ENOSYS; + } return regs->gprs[2]; +skip: + clear_pt_regs_flag(regs, PIF_SYSCALL); + return ret; } asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) @@ -976,9 +1008,7 @@ int rc = 0; freg_t fprs[__NUM_FPRS]; - if (target == current) - save_fpu_regs(); - + save_fpu_regs(); if (MACHINE_HAS_VX) convert_vx_to_fp(fprs, target->thread.fpu.vxrs); else @@ -1256,7 +1286,6 @@ cb->pc == 1 && cb->qc == 0 && cb->reserved2 == 0 && - cb->key == PAGE_DEFAULT_KEY && cb->reserved3 == 0 && cb->reserved4 == 0 && cb->reserved5 == 0 && @@ -1320,7 +1349,11 @@ kfree(data); return -EINVAL; } - + /* + * Override access key in any case, since user space should + * not be able to set it, nor should it care about it. + */ + ri_cb.key = PAGE_DEFAULT_KEY >> 4; preempt_disable(); if (!target->thread.ri_cb) target->thread.ri_cb = data; --- linux-oracle-5.4.0.orig/arch/s390/kernel/runtime_instr.c +++ linux-oracle-5.4.0/arch/s390/kernel/runtime_instr.c @@ -57,7 +57,7 @@ cb->k = 1; cb->ps = 1; cb->pc = 1; - cb->key = PAGE_DEFAULT_KEY; + cb->key = PAGE_DEFAULT_KEY >> 4; cb->v = 1; } --- linux-oracle-5.4.0.orig/arch/s390/kernel/setup.c +++ linux-oracle-5.4.0/arch/s390/kernel/setup.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,7 @@ #include #include #include +#include #include "entry.h" /* @@ -92,10 +94,6 @@ unsigned long int_hwcap = 0; -#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST -int __bootdata_preserved(prot_virt_guest); -#endif - int __bootdata(noexec_disabled); int __bootdata(memory_end_set); unsigned long __bootdata(memory_end); @@ -111,6 +109,8 @@ unsigned long __bootdata_preserved(__sdma); unsigned long __bootdata_preserved(__edma); unsigned long __bootdata_preserved(__kaslr_offset); +unsigned int __bootdata_preserved(zlib_dfltcc_support); +EXPORT_SYMBOL(zlib_dfltcc_support); unsigned long VMALLOC_START; EXPORT_SYMBOL(VMALLOC_START); @@ -161,7 +161,7 @@ else if (CONSOLE_IS_3270) add_preferred_console("tty3270", 0, NULL); else if (CONSOLE_IS_VT220) - add_preferred_console("ttyS", 1, NULL); + add_preferred_console("ttysclp", 0, NULL); else if (CONSOLE_IS_HVC) add_preferred_console("hvc", 0, NULL); } @@ -355,7 +355,6 @@ void __init arch_call_rest_init(void) { - struct stack_frame *frame; unsigned long stack; stack = stack_alloc(); @@ -368,13 +367,7 @@ set_task_stack_end_magic(current); stack += STACK_INIT_OFFSET; S390_lowcore.kernel_stack = stack; - frame = (struct stack_frame *) stack; - memset(frame, 0, sizeof(*frame)); - /* Branch to rest_init on the new stack, never returns */ - asm volatile( - " la 15,0(%[_frame])\n" - " jg rest_init\n" - : : [_frame] "a" (frame)); + CALL_ON_STACK_NORETURN(rest_init, stack); } static void __init setup_lowcore_dat_off(void) @@ -457,6 +450,8 @@ lc->spinlock_index = 0; arch_spin_lock_setup(0); lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; @@ -571,6 +566,9 @@ vmax = _REGION1_SIZE; /* 4-level kernel page table */ } + if (is_prot_virt_host()) + adjust_to_uv_max(&vmax); + /* module area is at the end of the kernel address space. */ MODULES_END = vmax; MODULES_VADDR = MODULES_END - MODULES_LEN; @@ -631,7 +629,7 @@ /* * Make sure that the area behind memory_end is protected */ -static void reserve_memory_end(void) +static void __init reserve_memory_end(void) { if (memory_end_set) memblock_reserve(memory_end, ULONG_MAX); @@ -640,7 +638,7 @@ /* * Make sure that oldmem, where the dump is stored, is protected */ -static void reserve_oldmem(void) +static void __init reserve_oldmem(void) { #ifdef CONFIG_CRASH_DUMP if (OLDMEM_BASE) @@ -652,7 +650,7 @@ /* * Make sure that oldmem, where the dump is stored, is protected */ -static void remove_oldmem(void) +static void __init remove_oldmem(void) { #ifdef CONFIG_CRASH_DUMP if (OLDMEM_BASE) @@ -845,9 +843,6 @@ storage_key_init_range(reg->base, reg->base + reg->size); } psw_set_key(PAGE_DEFAULT_KEY); - - /* Only cosmetics */ - memblock_enforce_memory_limit(memblock_end_of_DRAM()); } /* @@ -926,9 +921,9 @@ if (MACHINE_HAS_VX) { elf_hwcap |= HWCAP_S390_VXRS; if (test_facility(134)) - elf_hwcap |= HWCAP_S390_VXRS_EXT; - if (test_facility(135)) elf_hwcap |= HWCAP_S390_VXRS_BCD; + if (test_facility(135)) + elf_hwcap |= HWCAP_S390_VXRS_EXT; if (test_facility(148)) elf_hwcap |= HWCAP_S390_VXRS_EXT2; if (test_facility(152)) @@ -1012,6 +1007,11 @@ if (stsi(vmms, 3, 2, 2) == 0 && vmms->count) add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count); memblock_free((unsigned long) vmms, PAGE_SIZE); + +#ifdef CONFIG_ARCH_RANDOM + if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG)) + static_branch_enable(&s390_arch_random_available); +#endif } /* @@ -1038,8 +1038,7 @@ { union diag318_info diag318_info = { .cpnc = CPNC_LINUX, - .cpvc_linux = 0, - .cpvc_distro = {0}, + .cpvc = 0, }; if (!sclp.has_diag318) @@ -1059,7 +1058,7 @@ if (!early_ipl_comp_list_addr) return; - if (ipl_block.hdr.flags & IPL_PL_FLAG_IPLSR) + if (ipl_block.hdr.flags & IPL_PL_FLAG_SIPL) pr_info("Linux is running with Secure-IPL enabled\n"); else pr_info("Linux is running with Secure-IPL disabled\n"); @@ -1103,6 +1102,12 @@ log_component_list(); +#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT + if (ipl_get_secureboot()) + security_lock_kernel_down("Secure IPL", + LOCKDOWN_INTEGRITY_MAX); +#endif + /* Have one command line that is parsed and saved in /proc/cmdline */ /* boot_command_line has been already set up in early.c */ *cmdline_p = boot_command_line; @@ -1117,6 +1122,7 @@ if (IS_ENABLED(CONFIG_EXPOLINE_AUTO)) nospec_auto_detect(); + jump_label_init(); parse_early_param(); #ifdef CONFIG_CRASH_DUMP /* Deactivate elfcorehdr= kernel parameter */ @@ -1151,6 +1157,8 @@ */ memblock_trim_memory(1UL << (MAX_ORDER - 1 + PAGE_SHIFT)); + if (is_prot_virt_host()) + setup_uv(); setup_memory_end(); setup_memory(); dma_contiguous_reserve(memory_end); --- linux-oracle-5.4.0.orig/arch/s390/kernel/smp.c +++ linux-oracle-5.4.0/arch/s390/kernel/smp.c @@ -145,7 +145,7 @@ static inline int pcpu_stopped(struct pcpu *pcpu) { - u32 uninitialized_var(status); + u32 status; if (__pcpu_sigp(pcpu->address, SIGP_SENSE, 0, &status) != SIGP_CC_STATUS_STORED) @@ -212,6 +212,8 @@ lc->spinlock_lockval = arch_spin_lockval(cpu); lc->spinlock_index = 0; lc->br_r1_trampoline = 0x07f1; /* br %r1 */ + lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); + lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); if (nmi_alloc_per_cpu(lc)) goto out_async; if (vdso_alloc_per_cpu(lc)) @@ -262,10 +264,13 @@ lc->spinlock_index = 0; lc->percpu_offset = __per_cpu_offset[cpu]; lc->kernel_asce = S390_lowcore.kernel_asce; + lc->user_asce = S390_lowcore.kernel_asce; lc->machine_flags = S390_lowcore.machine_flags; lc->user_timer = lc->system_timer = lc->steal_timer = lc->avg_steal_timer = 0; __ctl_store(lc->cregs_save_area, 0, 15); + lc->cregs_save_area[1] = lc->kernel_asce; + lc->cregs_save_area[7] = lc->vdso_asce; save_access_regs((unsigned int *) lc->access_regs_save_area); memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, sizeof(lc->stfle_fac_list)); @@ -398,7 +403,7 @@ return -1; } -bool arch_vcpu_is_preempted(int cpu) +bool notrace arch_vcpu_is_preempted(int cpu) { if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu)) return false; @@ -408,7 +413,7 @@ } EXPORT_SYMBOL(arch_vcpu_is_preempted); -void smp_yield_cpu(int cpu) +void notrace smp_yield_cpu(int cpu) { if (MACHINE_HAS_DIAG9C) { diag_stat_inc_norecursion(DIAG_STAT_X09C); @@ -724,39 +729,67 @@ static int smp_add_present_cpu(int cpu); -static int __smp_rescan_cpus(struct sclp_core_info *info, int sysfs_add) +static int smp_add_core(struct sclp_core_entry *core, cpumask_t *avail, + bool configured, bool early) { struct pcpu *pcpu; - cpumask_t avail; - int cpu, nr, i, j; + int cpu, nr, i; u16 address; nr = 0; - cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); - cpu = cpumask_first(&avail); - for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) { - if (sclp.has_core_type && info->core[i].type != boot_core_type) + if (sclp.has_core_type && core->type != boot_core_type) + return nr; + cpu = cpumask_first(avail); + address = core->core_id << smp_cpu_mt_shift; + for (i = 0; (i <= smp_cpu_mtid) && (cpu < nr_cpu_ids); i++) { + if (pcpu_find_address(cpu_present_mask, address + i)) continue; - address = info->core[i].core_id << smp_cpu_mt_shift; - for (j = 0; j <= smp_cpu_mtid; j++) { - if (pcpu_find_address(cpu_present_mask, address + j)) - continue; - pcpu = pcpu_devices + cpu; - pcpu->address = address + j; - pcpu->state = - (cpu >= info->configured*(smp_cpu_mtid + 1)) ? - CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; - smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); - set_cpu_present(cpu, true); - if (sysfs_add && smp_add_present_cpu(cpu) != 0) - set_cpu_present(cpu, false); - else - nr++; - cpu = cpumask_next(cpu, &avail); - if (cpu >= nr_cpu_ids) + pcpu = pcpu_devices + cpu; + pcpu->address = address + i; + if (configured) + pcpu->state = CPU_STATE_CONFIGURED; + else + pcpu->state = CPU_STATE_STANDBY; + smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); + set_cpu_present(cpu, true); + if (!early && smp_add_present_cpu(cpu) != 0) + set_cpu_present(cpu, false); + else + nr++; + cpumask_clear_cpu(cpu, avail); + cpu = cpumask_next(cpu, avail); + } + return nr; +} + +static int __smp_rescan_cpus(struct sclp_core_info *info, bool early) +{ + struct sclp_core_entry *core; + static cpumask_t avail; + bool configured; + u16 core_id; + int nr, i; + + nr = 0; + cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); + /* + * Add IPL core first (which got logical CPU number 0) to make sure + * that all SMT threads get subsequent logical CPU numbers. + */ + if (early) { + core_id = pcpu_devices[0].address >> smp_cpu_mt_shift; + for (i = 0; i < info->configured; i++) { + core = &info->core[i]; + if (core->core_id == core_id) { + nr += smp_add_core(core, &avail, true, early); break; + } } } + for (i = 0; i < info->combined; i++) { + configured = i < info->configured; + nr += smp_add_core(&info->core[i], &avail, configured, early); + } return nr; } @@ -805,18 +838,21 @@ /* Add CPUs present at boot */ get_online_cpus(); - __smp_rescan_cpus(info, 0); + __smp_rescan_cpus(info, true); put_online_cpus(); memblock_free_early((unsigned long)info, sizeof(*info)); } static void smp_init_secondary(void) { - int cpu = smp_processor_id(); + int cpu = raw_smp_processor_id(); S390_lowcore.last_update_clock = get_tod_clock(); restore_access_regs(S390_lowcore.access_regs_save_area); + set_cpu_flag(CIF_ASCE_PRIMARY); + set_cpu_flag(CIF_ASCE_SECONDARY); cpu_init(); + rcu_cpu_starting(cpu); preempt_disable(); init_cpu_timer(); vtime_init(); @@ -843,30 +879,18 @@ S390_lowcore.restart_source = -1UL; __ctl_load(S390_lowcore.cregs_save_area, 0, 15); __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_DAT); - CALL_ON_STACK(smp_init_secondary, S390_lowcore.kernel_stack, 0); + CALL_ON_STACK_NORETURN(smp_init_secondary, S390_lowcore.kernel_stack); } /* Upping and downing of CPUs */ int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - struct pcpu *pcpu; - int base, i, rc; + struct pcpu *pcpu = pcpu_devices + cpu; + int rc; - pcpu = pcpu_devices + cpu; if (pcpu->state != CPU_STATE_CONFIGURED) return -EIO; - base = smp_get_base_cpu(cpu); - for (i = 0; i <= smp_cpu_mtid; i++) { - if (base + i < nr_cpu_ids) - if (cpu_online(base + i)) - break; - } - /* - * If this is the first CPU of the core to get online - * do an initial CPU reset. - */ - if (i > smp_cpu_mtid && - pcpu_sigp_retry(pcpu_devices + base, SIGP_INITIAL_CPU_RESET, 0) != + if (pcpu_sigp_retry(pcpu, SIGP_INITIAL_CPU_RESET, 0) != SIGP_CC_ORDER_CODE_ACCEPTED) return -EIO; @@ -1148,7 +1172,7 @@ smp_get_core_info(info, 0); get_online_cpus(); mutex_lock(&smp_cpu_state_mutex); - nr = __smp_rescan_cpus(info, 1); + nr = __smp_rescan_cpus(info, false); mutex_unlock(&smp_cpu_state_mutex); put_online_cpus(); kfree(info); --- linux-oracle-5.4.0.orig/arch/s390/kernel/sthyi.c +++ linux-oracle-5.4.0/arch/s390/kernel/sthyi.c @@ -460,9 +460,9 @@ * * Fills the destination with system information returned by the STHYI * instruction. The data is generated by emulation or execution of STHYI, - * if available. The return value is the condition code that would be - * returned, the rc parameter is the return code which is passed in - * register R2 + 1. + * if available. The return value is either a negative error value or + * the condition code that would be returned, the rc parameter is the + * return code which is passed in register R2 + 1. */ int sthyi_fill(void *dst, u64 *rc) { --- linux-oracle-5.4.0.orig/arch/s390/kernel/syscalls/Makefile +++ linux-oracle-5.4.0/arch/s390/kernel/syscalls/Makefile @@ -12,7 +12,7 @@ uapi-hdrs-y := $(uapi)/unistd_32.h uapi-hdrs-y += $(uapi)/unistd_64.h -targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y)) +targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y)) PHONY += kapi uapi --- linux-oracle-5.4.0.orig/arch/s390/kernel/time.c +++ linux-oracle-5.4.0/arch/s390/kernel/time.c @@ -310,6 +310,7 @@ vdso_data->tk_mult = tk->tkr_mono.mult; vdso_data->tk_shift = tk->tkr_mono.shift; + vdso_data->hrtimer_res = hrtimer_resolution; smp_wmb(); ++vdso_data->tb_update_count; } @@ -353,8 +354,9 @@ static DEFINE_MUTEX(clock_sync_mutex); static unsigned long clock_sync_flags; -#define CLOCK_SYNC_HAS_STP 0 -#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_HAS_STP 0 +#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_STPINFO_VALID 2 /* * The get_clock function for the physical clock. It will get the current @@ -591,6 +593,22 @@ queue_work(time_sync_wq, &stp_work); } +static int __store_stpinfo(void) +{ + int rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + + if (rc) + clear_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + else + set_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + return rc; +} + +static int stpinfo_valid(void) +{ + return stp_online && test_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); +} + static int stp_sync_clock(void *data) { struct clock_sync_data *sync = data; @@ -612,8 +630,7 @@ if (rc == 0) { sync->clock_delta = clock_delta; clock_sync_global(clock_delta); - rc = chsc_sstpi(stp_page, &stp_info, - sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc == 0 && stp_info.tmd != 2) rc = -EAGAIN; } @@ -658,7 +675,7 @@ if (rc) goto out_unlock; - rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc || stp_info.c == 0) goto out_unlock; @@ -695,10 +712,14 @@ struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%016llx\n", - *(unsigned long long *) stp_info.ctnid); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%016llx\n", + *(unsigned long long *) stp_info.ctnid); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); @@ -707,9 +728,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.ctn); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.ctn); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); @@ -718,9 +743,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x2000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x2000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); @@ -729,9 +758,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x8000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x8000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); @@ -740,9 +773,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(stratum, 0400, stp_stratum_show, NULL); @@ -751,9 +788,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x0800)) - return -ENODATA; - return sprintf(buf, "%i\n", (int) stp_info.tto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x0800)) + ret = sprintf(buf, "%i\n", (int) stp_info.tto); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(time_offset, 0400, stp_time_offset_show, NULL); @@ -762,9 +803,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x4000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x4000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(time_zone_offset, 0400, @@ -774,9 +819,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tmd); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tmd); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); @@ -785,9 +834,13 @@ struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tst); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tst); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR(timing_state, 0400, stp_timing_state_show, NULL); --- linux-oracle-5.4.0.orig/arch/s390/kernel/topology.c +++ linux-oracle-5.4.0/arch/s390/kernel/topology.c @@ -65,6 +65,13 @@ cpumask_t cpus_with_topology; +int __cpu_to_node(int cpu) +{ + return cpu_topology[cpu].node_id; +} + +EXPORT_SYMBOL(__cpu_to_node); + static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) { cpumask_t mask; --- linux-oracle-5.4.0.orig/arch/s390/kernel/trace.c +++ linux-oracle-5.4.0/arch/s390/kernel/trace.c @@ -14,7 +14,7 @@ static DEFINE_PER_CPU(unsigned int, diagnose_trace_depth); -void trace_s390_diagnose_norecursion(int diag_nr) +void notrace trace_s390_diagnose_norecursion(int diag_nr) { unsigned long flags; unsigned int *depth; --- linux-oracle-5.4.0.orig/arch/s390/kernel/unwind_bc.c +++ linux-oracle-5.4.0/arch/s390/kernel/unwind_bc.c @@ -60,6 +60,11 @@ ip = READ_ONCE_NOCHECK(sf->gprs[8]); reliable = false; regs = NULL; + if (!__kernel_text_address(ip)) { + /* skip bogus %r14 */ + state->regs = NULL; + return unwind_next_frame(state); + } } else { sf = (struct stack_frame *) state->sp; sp = READ_ONCE_NOCHECK(sf->back_chain); --- linux-oracle-5.4.0.orig/arch/s390/kernel/uv.c +++ linux-oracle-5.4.0/arch/s390/kernel/uv.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Ultravisor functions and initialization + * + * Copyright IBM Corp. 2019, 2020 + */ +#define KMSG_COMPONENT "prot_virt" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* the bootdata_preserved fields come from ones in arch/s390/boot/uv.c */ +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST +int __bootdata_preserved(prot_virt_guest); +#endif + +#if IS_ENABLED(CONFIG_KVM) +int prot_virt_host; +EXPORT_SYMBOL(prot_virt_host); +struct uv_info __bootdata_preserved(uv_info); +EXPORT_SYMBOL(uv_info); + +static int __init prot_virt_setup(char *val) +{ + bool enabled; + int rc; + + rc = kstrtobool(val, &enabled); + if (!rc && enabled) + prot_virt_host = 1; + + if (is_prot_virt_guest() && prot_virt_host) { + prot_virt_host = 0; + pr_warn("Protected virtualization not available in protected guests."); + } + + if (prot_virt_host && !test_facility(158)) { + prot_virt_host = 0; + pr_warn("Protected virtualization not supported by the hardware."); + } + + return rc; +} +early_param("prot_virt", prot_virt_setup); + +static int __init uv_init(unsigned long stor_base, unsigned long stor_len) +{ + struct uv_cb_init uvcb = { + .header.cmd = UVC_CMD_INIT_UV, + .header.len = sizeof(uvcb), + .stor_origin = stor_base, + .stor_len = stor_len, + }; + + if (uv_call(0, (uint64_t)&uvcb)) { + pr_err("Ultravisor init failed with rc: 0x%x rrc: 0%x\n", + uvcb.header.rc, uvcb.header.rrc); + return -1; + } + return 0; +} + +void __init setup_uv(void) +{ + unsigned long uv_stor_base; + + uv_stor_base = (unsigned long)memblock_alloc_try_nid( + uv_info.uv_base_stor_len, SZ_1M, SZ_2G, + MEMBLOCK_ALLOC_ACCESSIBLE, NUMA_NO_NODE); + if (!uv_stor_base) { + pr_warn("Failed to reserve %lu bytes for ultravisor base storage\n", + uv_info.uv_base_stor_len); + goto fail; + } + + if (uv_init(uv_stor_base, uv_info.uv_base_stor_len)) { + memblock_free(uv_stor_base, uv_info.uv_base_stor_len); + goto fail; + } + + pr_info("Reserving %luMB as ultravisor base storage\n", + uv_info.uv_base_stor_len >> 20); + return; +fail: + pr_info("Disabling support for protected virtualization"); + prot_virt_host = 0; +} + +void adjust_to_uv_max(unsigned long *vmax) +{ + *vmax = min_t(unsigned long, *vmax, uv_info.max_sec_stor_addr); +} + +/* + * Requests the Ultravisor to pin the page in the shared state. This will + * cause an intercept when the guest attempts to unshare the pinned page. + */ +static int uv_pin_shared(unsigned long paddr) +{ + struct uv_cb_cfs uvcb = { + .header.cmd = UVC_CMD_PIN_PAGE_SHARED, + .header.len = sizeof(uvcb), + .paddr = paddr, + }; + + if (uv_call(0, (u64)&uvcb)) + return -EINVAL; + return 0; +} + +/* + * Requests the Ultravisor to encrypt a guest page and make it + * accessible to the host for paging (export). + * + * @paddr: Absolute host address of page to be exported + */ +int uv_convert_from_secure(unsigned long paddr) +{ + struct uv_cb_cfs uvcb = { + .header.cmd = UVC_CMD_CONV_FROM_SEC_STOR, + .header.len = sizeof(uvcb), + .paddr = paddr + }; + + if (uv_call(0, (u64)&uvcb)) + return -EINVAL; + return 0; +} + +/* + * Calculate the expected ref_count for a page that would otherwise have no + * further pins. This was cribbed from similar functions in other places in + * the kernel, but with some slight modifications. We know that a secure + * page can not be a huge page for example. + */ +static int expected_page_refs(struct page *page) +{ + int res; + + res = page_mapcount(page); + if (PageSwapCache(page)) { + res++; + } else if (page_mapping(page)) { + res++; + if (page_has_private(page)) + res++; + } + return res; +} + +static int make_secure_pte(pte_t *ptep, unsigned long addr, + struct page *exp_page, struct uv_cb_header *uvcb) +{ + pte_t entry = READ_ONCE(*ptep); + struct page *page; + int expected, cc = 0; + + if (!pte_present(entry)) + return -ENXIO; + if (pte_val(entry) & _PAGE_INVALID) + return -ENXIO; + + page = pte_page(entry); + if (page != exp_page) + return -ENXIO; + if (PageWriteback(page)) + return -EAGAIN; + expected = expected_page_refs(page); + if (!page_ref_freeze(page, expected)) + return -EBUSY; + set_bit(PG_arch_1, &page->flags); + /* + * If the UVC does not succeed or fail immediately, we don't want to + * loop for long, or we might get stall notifications. + * On the other hand, this is a complex scenario and we are holding a lot of + * locks, so we can't easily sleep and reschedule. We try only once, + * and if the UVC returned busy or partial completion, we return + * -EAGAIN and we let the callers deal with it. + */ + cc = __uv_call(0, (u64)uvcb); + page_ref_unfreeze(page, expected); + /* + * Return -ENXIO if the page was not mapped, -EINVAL for other errors. + * If busy or partially completed, return -EAGAIN. + */ + if (cc == UVC_CC_OK) + return 0; + else if (cc == UVC_CC_BUSY || cc == UVC_CC_PARTIAL) + return -EAGAIN; + return uvcb->rc == 0x10a ? -ENXIO : -EINVAL; +} + +/* + * Requests the Ultravisor to make a page accessible to a guest. + * If it's brought in the first time, it will be cleared. If + * it has been exported before, it will be decrypted and integrity + * checked. + */ +int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb) +{ + struct vm_area_struct *vma; + bool local_drain = false; + spinlock_t *ptelock; + unsigned long uaddr; + struct page *page; + pte_t *ptep; + int rc; + +again: + rc = -EFAULT; + down_read(&gmap->mm->mmap_sem); + + uaddr = __gmap_translate(gmap, gaddr); + if (IS_ERR_VALUE(uaddr)) + goto out; + vma = find_vma(gmap->mm, uaddr); + if (!vma) + goto out; + /* + * Secure pages cannot be huge and userspace should not combine both. + * In case userspace does it anyway this will result in an -EFAULT for + * the unpack. The guest is thus never reaching secure mode. If + * userspace is playing dirty tricky with mapping huge pages later + * on this will result in a segmentation fault. + */ + if (is_vm_hugetlb_page(vma)) + goto out; + + rc = -ENXIO; + page = follow_page(vma, uaddr, FOLL_WRITE); + if (IS_ERR_OR_NULL(page)) + goto out; + + lock_page(page); + ptep = get_locked_pte(gmap->mm, uaddr, &ptelock); + rc = make_secure_pte(ptep, uaddr, page, uvcb); + pte_unmap_unlock(ptep, ptelock); + unlock_page(page); +out: + up_read(&gmap->mm->mmap_sem); + + if (rc == -EAGAIN) { + /* + * If we are here because the UVC returned busy or partial + * completion, this is just a useless check, but it is safe. + */ + wait_on_page_writeback(page); + } else if (rc == -EBUSY) { + /* + * If we have tried a local drain and the page refcount + * still does not match our expected safe value, try with a + * system wide drain. This is needed if the pagevecs holding + * the page are on a different CPU. + */ + if (local_drain) { + lru_add_drain_all(); + /* We give up here, and let the caller try again */ + return -EAGAIN; + } + /* + * We are here if the page refcount does not match the + * expected safe value. The main culprits are usually + * pagevecs. With lru_add_drain() we drain the pagevecs + * on the local CPU so that hopefully the refcount will + * reach the expected safe value. + */ + lru_add_drain(); + local_drain = true; + /* And now we try again immediately after draining */ + goto again; + } else if (rc == -ENXIO) { + if (gmap_fault(gmap, gaddr, FAULT_FLAG_WRITE)) + return -EFAULT; + return -EAGAIN; + } + return rc; +} +EXPORT_SYMBOL_GPL(gmap_make_secure); + +int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr) +{ + struct uv_cb_cts uvcb = { + .header.cmd = UVC_CMD_CONV_TO_SEC_STOR, + .header.len = sizeof(uvcb), + .guest_handle = gmap->guest_handle, + .gaddr = gaddr, + }; + + return gmap_make_secure(gmap, gaddr, &uvcb); +} +EXPORT_SYMBOL_GPL(gmap_convert_to_secure); + +/* + * To be called with the page locked or with an extra reference! This will + * prevent gmap_make_secure from touching the page concurrently. Having 2 + * parallel make_page_accessible is fine, as the UV calls will become a + * no-op if the page is already exported. + */ +int arch_make_page_accessible(struct page *page) +{ + int rc = 0; + + /* Hugepage cannot be protected, so nothing to do */ + if (PageHuge(page)) + return 0; + + /* + * PG_arch_1 is used in 3 places: + * 1. for kernel page tables during early boot + * 2. for storage keys of huge pages and KVM + * 3. As an indication that this page might be secure. This can + * overindicate, e.g. we set the bit before calling + * convert_to_secure. + * As secure pages are never huge, all 3 variants can co-exists. + */ + if (!test_bit(PG_arch_1, &page->flags)) + return 0; + + rc = uv_pin_shared(page_to_phys(page)); + if (!rc) { + clear_bit(PG_arch_1, &page->flags); + return 0; + } + + rc = uv_convert_from_secure(page_to_phys(page)); + if (!rc) { + clear_bit(PG_arch_1, &page->flags); + return 0; + } + + return rc; +} +EXPORT_SYMBOL_GPL(arch_make_page_accessible); + +#endif + +#if defined(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) || IS_ENABLED(CONFIG_KVM) +static ssize_t uv_query_facilities(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return snprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n", + uv_info.inst_calls_list[0], + uv_info.inst_calls_list[1], + uv_info.inst_calls_list[2], + uv_info.inst_calls_list[3]); +} + +static struct kobj_attribute uv_query_facilities_attr = + __ATTR(facilities, 0444, uv_query_facilities, NULL); + +static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return snprintf(page, PAGE_SIZE, "%d\n", + uv_info.max_guest_cpus); +} + +static struct kobj_attribute uv_query_max_guest_cpus_attr = + __ATTR(max_cpus, 0444, uv_query_max_guest_cpus, NULL); + +static ssize_t uv_query_max_guest_vms(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return snprintf(page, PAGE_SIZE, "%d\n", + uv_info.max_num_sec_conf); +} + +static struct kobj_attribute uv_query_max_guest_vms_attr = + __ATTR(max_guests, 0444, uv_query_max_guest_vms, NULL); + +static ssize_t uv_query_max_guest_addr(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + return snprintf(page, PAGE_SIZE, "%lx\n", + uv_info.max_sec_stor_addr); +} + +static struct kobj_attribute uv_query_max_guest_addr_attr = + __ATTR(max_address, 0444, uv_query_max_guest_addr, NULL); + +static struct attribute *uv_query_attrs[] = { + &uv_query_facilities_attr.attr, + &uv_query_max_guest_cpus_attr.attr, + &uv_query_max_guest_vms_attr.attr, + &uv_query_max_guest_addr_attr.attr, + NULL, +}; + +static struct attribute_group uv_query_attr_group = { + .attrs = uv_query_attrs, +}; + +static ssize_t uv_is_prot_virt_guest(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + int val = 0; + +#ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST + val = prot_virt_guest; +#endif + return scnprintf(page, PAGE_SIZE, "%d\n", val); +} + +static ssize_t uv_is_prot_virt_host(struct kobject *kobj, + struct kobj_attribute *attr, char *page) +{ + int val = 0; + +#if IS_ENABLED(CONFIG_KVM) + val = prot_virt_host; +#endif + + return scnprintf(page, PAGE_SIZE, "%d\n", val); +} + +static struct kobj_attribute uv_prot_virt_guest = + __ATTR(prot_virt_guest, 0444, uv_is_prot_virt_guest, NULL); + +static struct kobj_attribute uv_prot_virt_host = + __ATTR(prot_virt_host, 0444, uv_is_prot_virt_host, NULL); + +static const struct attribute *uv_prot_virt_attrs[] = { + &uv_prot_virt_guest.attr, + &uv_prot_virt_host.attr, + NULL, +}; + +static struct kset *uv_query_kset; +static struct kobject *uv_kobj; + +static int __init uv_info_init(void) +{ + int rc = -ENOMEM; + + if (!test_facility(158)) + return 0; + + uv_kobj = kobject_create_and_add("uv", firmware_kobj); + if (!uv_kobj) + return -ENOMEM; + + rc = sysfs_create_files(uv_kobj, uv_prot_virt_attrs); + if (rc) + goto out_kobj; + + uv_query_kset = kset_create_and_add("query", NULL, uv_kobj); + if (!uv_query_kset) + goto out_ind_files; + + rc = sysfs_create_group(&uv_query_kset->kobj, &uv_query_attr_group); + if (!rc) + return 0; + + kset_unregister(uv_query_kset); +out_ind_files: + sysfs_remove_files(uv_kobj, uv_prot_virt_attrs); +out_kobj: + kobject_del(uv_kobj); + kobject_put(uv_kobj); + return rc; +} +device_initcall(uv_info_init); +#endif --- linux-oracle-5.4.0.orig/arch/s390/kernel/vdso64/Makefile +++ linux-oracle-5.4.0/arch/s390/kernel/vdso64/Makefile @@ -18,8 +18,8 @@ KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS)) KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin -KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \ - -Wl,--hash-style=both +ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \ + --hash-style=both --build-id -T $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64) $(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64) @@ -37,8 +37,8 @@ $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so # link rule for the .so file, .lds has to be first -$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE - $(call if_changed,vdso64ld) +$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE + $(call if_changed,ld) # strip rule for the .so file $(obj)/%.so: OBJCOPYFLAGS := -S @@ -50,8 +50,6 @@ $(call if_changed_dep,vdso64as) # actual build commands -quiet_cmd_vdso64ld = VDSO64L $@ - cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@ quiet_cmd_vdso64as = VDSO64A $@ cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $< --- linux-oracle-5.4.0.orig/arch/s390/kernel/vdso64/clock_getres.S +++ linux-oracle-5.4.0/arch/s390/kernel/vdso64/clock_getres.S @@ -17,12 +17,14 @@ .type __kernel_clock_getres,@function __kernel_clock_getres: CFI_STARTPROC - larl %r1,4f + larl %r1,3f + lg %r0,0(%r1) cghi %r2,__CLOCK_REALTIME_COARSE je 0f cghi %r2,__CLOCK_MONOTONIC_COARSE je 0f - larl %r1,3f + larl %r1,_vdso_data + llgf %r0,__VDSO_CLOCK_REALTIME_RES(%r1) cghi %r2,__CLOCK_REALTIME je 0f cghi %r2,__CLOCK_MONOTONIC @@ -36,7 +38,6 @@ jz 2f 0: ltgr %r3,%r3 jz 1f /* res == NULL */ - lg %r0,0(%r1) xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */ stg %r0,8(%r3) /* store tp->tv_usec */ 1: lghi %r2,0 @@ -45,6 +46,5 @@ svc 0 br %r14 CFI_ENDPROC -3: .quad __CLOCK_REALTIME_RES -4: .quad __CLOCK_COARSE_RES +3: .quad __CLOCK_COARSE_RES .size __kernel_clock_getres,.-__kernel_clock_getres --- linux-oracle-5.4.0.orig/arch/s390/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/s390/kernel/vmlinux.lds.S @@ -15,6 +15,8 @@ /* Handle ro_after_init data on our own. */ #define RO_AFTER_INIT_DATA +#define RUNTIME_DISCARD_EXIT + #include #include @@ -124,6 +126,7 @@ /* * Table with the patch locations to undo expolines */ + . = ALIGN(4); .nospec_call_table : { __nospec_call_start = . ; *(.s390_indirect*) @@ -188,5 +191,6 @@ DISCARDS /DISCARD/ : { *(.eh_frame) + *(.interp) } } --- linux-oracle-5.4.0.orig/arch/s390/kernel/vtime.c +++ linux-oracle-5.4.0/arch/s390/kernel/vtime.c @@ -136,7 +136,8 @@ " stck %1" /* Store current tod clock value */ #endif : "=Q" (S390_lowcore.last_update_timer), - "=Q" (S390_lowcore.last_update_clock)); + "=Q" (S390_lowcore.last_update_clock) + : : "cc"); clock = S390_lowcore.last_update_clock - clock; timer -= S390_lowcore.last_update_timer; @@ -213,13 +214,13 @@ virt_timer_expire(); steal = S390_lowcore.steal_timer; - avg_steal = S390_lowcore.avg_steal_timer / 2; + avg_steal = S390_lowcore.avg_steal_timer; if ((s64) steal > 0) { S390_lowcore.steal_timer = 0; - account_steal_time(steal); + account_steal_time(cputime_to_nsecs(steal)); avg_steal += steal; } - S390_lowcore.avg_steal_timer = avg_steal; + S390_lowcore.avg_steal_timer = avg_steal / 2; } /* --- linux-oracle-5.4.0.orig/arch/s390/kvm/Makefile +++ linux-oracle-5.4.0/arch/s390/kvm/Makefile @@ -9,6 +9,6 @@ ccflags-y := -Ivirt/kvm -Iarch/s390/kvm kvm-objs := $(common-objs) kvm-s390.o intercept.o interrupt.o priv.o sigp.o -kvm-objs += diag.o gaccess.o guestdbg.o vsie.o +kvm-objs += diag.o gaccess.o guestdbg.o vsie.o pv.o obj-$(CONFIG_KVM) += kvm.o --- linux-oracle-5.4.0.orig/arch/s390/kvm/diag.c +++ linux-oracle-5.4.0/arch/s390/kvm/diag.c @@ -2,7 +2,7 @@ /* * handling diagnose instructions * - * Copyright IBM Corp. 2008, 2011 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte * Christian Borntraeger @@ -78,7 +78,7 @@ vcpu->stat.diagnose_258++; if (vcpu->run->s.regs.gprs[rx] & 7) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); - rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); + rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm)); if (rc) return kvm_s390_inject_prog_cond(vcpu, rc); if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) @@ -187,6 +187,10 @@ return -EOPNOTSUPP; } + /* + * no need to check the return value of vcpu_stop as it can only have + * an error for protvirt, but protvirt means user cpu state + */ if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) kvm_s390_vcpu_stop(vcpu); vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM; --- linux-oracle-5.4.0.orig/arch/s390/kvm/gaccess.c +++ linux-oracle-5.4.0/arch/s390/kvm/gaccess.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -794,48 +795,270 @@ return 1; } -static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, - unsigned long *pages, unsigned long nr_pages, - const union asce asce, enum gacc_mode mode) +static int vm_check_access_key(struct kvm *kvm, u8 access_key, + enum gacc_mode mode, gpa_t gpa) +{ + u8 storage_key, access_control; + bool fetch_protected; + unsigned long hva; + int r; + + if (access_key == 0) + return 0; + + hva = gfn_to_hva(kvm, gpa_to_gfn(gpa)); + if (kvm_is_error_hva(hva)) + return PGM_ADDRESSING; + + down_read(¤t->mm->mmap_sem); + r = get_guest_storage_key(current->mm, hva, &storage_key); + up_read(¤t->mm->mmap_sem); + if (r) + return r; + access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key); + if (access_control == access_key) + return 0; + fetch_protected = storage_key & _PAGE_FP_BIT; + if ((mode == GACC_FETCH || mode == GACC_IFETCH) && !fetch_protected) + return 0; + return PGM_PROTECTION; +} + +static bool fetch_prot_override_applicable(struct kvm_vcpu *vcpu, enum gacc_mode mode, + union asce asce) +{ + psw_t *psw = &vcpu->arch.sie_block->gpsw; + unsigned long override; + + if (mode == GACC_FETCH || mode == GACC_IFETCH) { + /* check if fetch protection override enabled */ + override = vcpu->arch.sie_block->gcr[0]; + override &= CR0_FETCH_PROTECTION_OVERRIDE; + /* not applicable if subject to DAT && private space */ + override = override && !(psw_bits(*psw).dat && asce.p); + return override; + } + return false; +} + +static bool fetch_prot_override_applies(unsigned long ga, unsigned int len) +{ + return ga < 2048 && ga + len <= 2048; +} + +static bool storage_prot_override_applicable(struct kvm_vcpu *vcpu) +{ + /* check if storage protection override enabled */ + return vcpu->arch.sie_block->gcr[0] & CR0_STORAGE_PROTECTION_OVERRIDE; +} + +static bool storage_prot_override_applies(u8 access_control) +{ + /* matches special storage protection override key (9) -> allow */ + return access_control == PAGE_SPO_ACC; +} + +static int vcpu_check_access_key(struct kvm_vcpu *vcpu, u8 access_key, + enum gacc_mode mode, union asce asce, gpa_t gpa, + unsigned long ga, unsigned int len) +{ + u8 storage_key, access_control; + unsigned long hva; + int r; + + /* access key 0 matches any storage key -> allow */ + if (access_key == 0) + return 0; + /* + * caller needs to ensure that gfn is accessible, so we can + * assume that this cannot fail + */ + hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(gpa)); + down_read(¤t->mm->mmap_sem); + r = get_guest_storage_key(current->mm, hva, &storage_key); + up_read(¤t->mm->mmap_sem); + if (r) + return r; + access_control = FIELD_GET(_PAGE_ACC_BITS, storage_key); + /* access key matches storage key -> allow */ + if (access_control == access_key) + return 0; + if (mode == GACC_FETCH || mode == GACC_IFETCH) { + /* it is a fetch and fetch protection is off -> allow */ + if (!(storage_key & _PAGE_FP_BIT)) + return 0; + if (fetch_prot_override_applicable(vcpu, mode, asce) && + fetch_prot_override_applies(ga, len)) + return 0; + } + if (storage_prot_override_applicable(vcpu) && + storage_prot_override_applies(access_control)) + return 0; + return PGM_PROTECTION; +} + +/** + * guest_range_to_gpas() - Calculate guest physical addresses of page fragments + * covering a logical range + * @vcpu: virtual cpu + * @ga: guest address, start of range + * @ar: access register + * @gpas: output argument, may be NULL + * @len: length of range in bytes + * @asce: address-space-control element to use for translation + * @mode: access mode + * @access_key: access key to mach the range's storage keys against + * + * Translate a logical range to a series of guest absolute addresses, + * such that the concatenation of page fragments starting at each gpa make up + * the whole range. + * The translation is performed as if done by the cpu for the given @asce, @ar, + * @mode and state of the @vcpu. + * If the translation causes an exception, its program interruption code is + * returned and the &struct kvm_s390_pgm_info pgm member of @vcpu is modified + * such that a subsequent call to kvm_s390_inject_prog_vcpu() will inject + * a correct exception into the guest. + * The resulting gpas are stored into @gpas, unless it is NULL. + * + * Note: All fragments except the first one start at the beginning of a page. + * When deriving the boundaries of a fragment from a gpa, all but the last + * fragment end at the end of the page. + * + * Return: + * * 0 - success + * * <0 - translation could not be performed, for example if guest + * memory could not be accessed + * * >0 - an access exception occurred. In this case the returned value + * is the program interruption code and the contents of pgm may + * be used to inject an exception into the guest. + */ +static int guest_range_to_gpas(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, + unsigned long *gpas, unsigned long len, + const union asce asce, enum gacc_mode mode, + u8 access_key) { psw_t *psw = &vcpu->arch.sie_block->gpsw; + unsigned int offset = offset_in_page(ga); + unsigned int fragment_len; int lap_enabled, rc = 0; enum prot_type prot; + unsigned long gpa; lap_enabled = low_address_protection_enabled(vcpu, asce); - while (nr_pages) { + while (min(PAGE_SIZE - offset, len) > 0) { + fragment_len = min(PAGE_SIZE - offset, len); ga = kvm_s390_logical_to_effective(vcpu, ga); if (mode == GACC_STORE && lap_enabled && is_low_address(ga)) return trans_exc(vcpu, PGM_PROTECTION, ga, ar, mode, PROT_TYPE_LA); - ga &= PAGE_MASK; if (psw_bits(*psw).dat) { - rc = guest_translate(vcpu, ga, pages, asce, mode, &prot); + rc = guest_translate(vcpu, ga, &gpa, asce, mode, &prot); if (rc < 0) return rc; } else { - *pages = kvm_s390_real_to_abs(vcpu, ga); - if (kvm_is_error_gpa(vcpu->kvm, *pages)) + gpa = kvm_s390_real_to_abs(vcpu, ga); + if (kvm_is_error_gpa(vcpu->kvm, gpa)) rc = PGM_ADDRESSING; } if (rc) return trans_exc(vcpu, rc, ga, ar, mode, prot); - ga += PAGE_SIZE; - pages++; - nr_pages--; + rc = vcpu_check_access_key(vcpu, access_key, mode, asce, gpa, ga, + fragment_len); + if (rc) + return trans_exc(vcpu, rc, ga, ar, mode, PROT_TYPE_KEYC); + if (gpas) + *gpas++ = gpa; + offset = 0; + ga += fragment_len; + len -= fragment_len; + } + return 0; +} + +static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa, + void *data, unsigned int len) +{ + const unsigned int offset = offset_in_page(gpa); + const gfn_t gfn = gpa_to_gfn(gpa); + int rc; + + if (!gfn_to_memslot(kvm, gfn)) + return PGM_ADDRESSING; + if (mode == GACC_STORE) + rc = kvm_write_guest_page(kvm, gfn, data, offset, len); + else + rc = kvm_read_guest_page(kvm, gfn, data, offset, len); + return rc; +} + +static int +access_guest_page_with_key(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa, + void *data, unsigned int len, u8 access_key) +{ + struct kvm_memory_slot *slot; + bool writable; + gfn_t gfn; + hva_t hva; + int rc; + + gfn = gpa >> PAGE_SHIFT; + slot = gfn_to_memslot(kvm, gfn); + hva = gfn_to_hva_memslot_prot(slot, gfn, &writable); + + if (kvm_is_error_hva(hva)) + return PGM_ADDRESSING; + /* + * Check if it's a ro memslot, even tho that can't occur (they're unsupported). + * Don't try to actually handle that case. + */ + if (!writable && mode == GACC_STORE) + return -EOPNOTSUPP; + hva += offset_in_page(gpa); + if (mode == GACC_STORE) + rc = copy_to_user_key((void __user *)hva, data, len, access_key); + else + rc = copy_from_user_key(data, (void __user *)hva, len, access_key); + if (rc) + return PGM_PROTECTION; + if (mode == GACC_STORE) + mark_page_dirty(kvm, gfn); + return 0; +} + +int access_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, void *data, + unsigned long len, enum gacc_mode mode, u8 access_key) +{ + int offset = offset_in_page(gpa); + int fragment_len; + int rc; + + while (min(PAGE_SIZE - offset, len) > 0) { + fragment_len = min(PAGE_SIZE - offset, len); + rc = access_guest_page_with_key(kvm, mode, gpa, data, fragment_len, access_key); + if (rc) + return rc; + offset = 0; + len -= fragment_len; + data += fragment_len; + gpa += fragment_len; } return 0; } -int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, - unsigned long len, enum gacc_mode mode) +int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, + void *data, unsigned long len, enum gacc_mode mode, + u8 access_key) { psw_t *psw = &vcpu->arch.sie_block->gpsw; - unsigned long _len, nr_pages, gpa, idx; - unsigned long pages_array[2]; - unsigned long *pages; + unsigned long nr_pages, idx; + unsigned long gpa_array[2]; + unsigned int fragment_len; + unsigned long *gpas; + enum prot_type prot; int need_ipte_lock; union asce asce; + bool try_storage_prot_override; + bool try_fetch_prot_override; int rc; if (!len) @@ -845,55 +1068,87 @@ if (rc) return rc; nr_pages = (((ga & ~PAGE_MASK) + len - 1) >> PAGE_SHIFT) + 1; - pages = pages_array; - if (nr_pages > ARRAY_SIZE(pages_array)) - pages = vmalloc(array_size(nr_pages, sizeof(unsigned long))); - if (!pages) + gpas = gpa_array; + if (nr_pages > ARRAY_SIZE(gpa_array)) + gpas = vmalloc(array_size(nr_pages, sizeof(unsigned long))); + if (!gpas) return -ENOMEM; + try_fetch_prot_override = fetch_prot_override_applicable(vcpu, mode, asce); + try_storage_prot_override = storage_prot_override_applicable(vcpu); need_ipte_lock = psw_bits(*psw).dat && !asce.r; if (need_ipte_lock) ipte_lock(vcpu); - rc = guest_page_range(vcpu, ga, ar, pages, nr_pages, asce, mode); - for (idx = 0; idx < nr_pages && !rc; idx++) { - gpa = *(pages + idx) + (ga & ~PAGE_MASK); - _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); - if (mode == GACC_STORE) - rc = kvm_write_guest(vcpu->kvm, gpa, data, _len); - else - rc = kvm_read_guest(vcpu->kvm, gpa, data, _len); - len -= _len; - ga += _len; - data += _len; + /* + * Since we do the access further down ultimately via a move instruction + * that does key checking and returns an error in case of a protection + * violation, we don't need to do the check during address translation. + * Skip it by passing access key 0, which matches any storage key, + * obviating the need for any further checks. As a result the check is + * handled entirely in hardware on access, we only need to take care to + * forego key protection checking if fetch protection override applies or + * retry with the special key 9 in case of storage protection override. + */ + rc = guest_range_to_gpas(vcpu, ga, ar, gpas, len, asce, mode, 0); + if (rc) + goto out_unlock; + for (idx = 0; idx < nr_pages; idx++) { + fragment_len = min(PAGE_SIZE - offset_in_page(gpas[idx]), len); + if (try_fetch_prot_override && fetch_prot_override_applies(ga, fragment_len)) { + rc = access_guest_page(vcpu->kvm, mode, gpas[idx], + data, fragment_len); + } else { + rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx], + data, fragment_len, access_key); + } + if (rc == PGM_PROTECTION && try_storage_prot_override) + rc = access_guest_page_with_key(vcpu->kvm, mode, gpas[idx], + data, fragment_len, PAGE_SPO_ACC); + if (rc == PGM_PROTECTION) + prot = PROT_TYPE_KEYC; + if (rc) + break; + len -= fragment_len; + data += fragment_len; + ga = kvm_s390_logical_to_effective(vcpu, ga + fragment_len); } + if (rc > 0) + rc = trans_exc(vcpu, rc, ga, ar, mode, prot); +out_unlock: if (need_ipte_lock) ipte_unlock(vcpu); - if (nr_pages > ARRAY_SIZE(pages_array)) - vfree(pages); + if (nr_pages > ARRAY_SIZE(gpa_array)) + vfree(gpas); return rc; } int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, unsigned long len, enum gacc_mode mode) { - unsigned long _len, gpa; + unsigned int fragment_len; + unsigned long gpa; int rc = 0; while (len && !rc) { gpa = kvm_s390_real_to_abs(vcpu, gra); - _len = min(PAGE_SIZE - (gpa & ~PAGE_MASK), len); - if (mode) - rc = write_guest_abs(vcpu, gpa, data, _len); - else - rc = read_guest_abs(vcpu, gpa, data, _len); - len -= _len; - gra += _len; - data += _len; + fragment_len = min(PAGE_SIZE - offset_in_page(gpa), len); + rc = access_guest_page(vcpu->kvm, mode, gpa, data, fragment_len); + len -= fragment_len; + gra += fragment_len; + data += fragment_len; } + if (rc > 0) + vcpu->arch.pgm.code = rc; return rc; } /** - * guest_translate_address - translate guest logical into guest absolute address + * guest_translate_address_with_key - translate guest logical into guest absolute address + * @vcpu: virtual cpu + * @gva: Guest virtual address + * @ar: Access register + * @gpa: Guest physical address + * @mode: Translation access mode + * @access_key: access key to mach the storage key with * * Parameter semantics are the same as the ones from guest_translate. * The memory contents at the guest address are not changed. @@ -901,11 +1156,10 @@ * Note: The IPTE lock is not taken during this function, so the caller * has to take care of this. */ -int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, - unsigned long *gpa, enum gacc_mode mode) +int guest_translate_address_with_key(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, + unsigned long *gpa, enum gacc_mode mode, + u8 access_key) { - psw_t *psw = &vcpu->arch.sie_block->gpsw; - enum prot_type prot; union asce asce; int rc; @@ -913,47 +1167,59 @@ rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode); if (rc) return rc; - if (is_low_address(gva) && low_address_protection_enabled(vcpu, asce)) { - if (mode == GACC_STORE) - return trans_exc(vcpu, PGM_PROTECTION, gva, 0, - mode, PROT_TYPE_LA); - } - - if (psw_bits(*psw).dat && !asce.r) { /* Use DAT? */ - rc = guest_translate(vcpu, gva, gpa, asce, mode, &prot); - if (rc > 0) - return trans_exc(vcpu, rc, gva, 0, mode, prot); - } else { - *gpa = kvm_s390_real_to_abs(vcpu, gva); - if (kvm_is_error_gpa(vcpu->kvm, *gpa)) - return trans_exc(vcpu, rc, gva, PGM_ADDRESSING, mode, 0); - } - - return rc; + return guest_range_to_gpas(vcpu, gva, ar, gpa, 1, asce, mode, + access_key); } /** * check_gva_range - test a range of guest virtual addresses for accessibility + * @vcpu: virtual cpu + * @gva: Guest virtual address + * @ar: Access register + * @length: Length of test range + * @mode: Translation access mode + * @access_key: access key to mach the storage keys with */ int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, - unsigned long length, enum gacc_mode mode) + unsigned long length, enum gacc_mode mode, u8 access_key) { - unsigned long gpa; - unsigned long currlen; + union asce asce; int rc = 0; + rc = get_vcpu_asce(vcpu, &asce, gva, ar, mode); + if (rc) + return rc; ipte_lock(vcpu); - while (length > 0 && !rc) { - currlen = min(length, PAGE_SIZE - (gva % PAGE_SIZE)); - rc = guest_translate_address(vcpu, gva, ar, &gpa, mode); - gva += currlen; - length -= currlen; - } + rc = guest_range_to_gpas(vcpu, gva, ar, NULL, length, asce, mode, + access_key); ipte_unlock(vcpu); return rc; } +/** + * check_gpa_range - test a range of guest physical addresses for accessibility + * @kvm: virtual machine instance + * @gpa: guest physical address + * @length: length of test range + * @mode: access mode to test, relevant for storage keys + * @access_key: access key to mach the storage keys with + */ +int check_gpa_range(struct kvm *kvm, unsigned long gpa, unsigned long length, + enum gacc_mode mode, u8 access_key) +{ + unsigned int fragment_len; + int rc = 0; + + while (length && !rc) { + fragment_len = min(PAGE_SIZE - offset_in_page(gpa), length); + rc = vm_check_access_key(kvm, access_key, mode, gpa); + length -= fragment_len; + gpa += fragment_len; + } + return rc; +} + /** * kvm_s390_check_low_addr_prot_real - check for low-address protection * @gra: Guest real address --- linux-oracle-5.4.0.orig/arch/s390/kvm/gaccess.h +++ linux-oracle-5.4.0/arch/s390/kvm/gaccess.h @@ -18,17 +18,14 @@ /** * kvm_s390_real_to_abs - convert guest real address to guest absolute address - * @vcpu - guest virtual cpu + * @prefix - guest prefix * @gra - guest real address * * Returns the guest absolute address that corresponds to the passed guest real - * address @gra of a virtual guest cpu by applying its prefix. + * address @gra of by applying the given prefix. */ -static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu, - unsigned long gra) +static inline unsigned long _kvm_s390_real_to_abs(u32 prefix, unsigned long gra) { - unsigned long prefix = kvm_s390_get_prefix(vcpu); - if (gra < 2 * PAGE_SIZE) gra += prefix; else if (gra >= prefix && gra < prefix + 2 * PAGE_SIZE) @@ -37,6 +34,43 @@ } /** + * kvm_s390_real_to_abs - convert guest real address to guest absolute address + * @vcpu - guest virtual cpu + * @gra - guest real address + * + * Returns the guest absolute address that corresponds to the passed guest real + * address @gra of a virtual guest cpu by applying its prefix. + */ +static inline unsigned long kvm_s390_real_to_abs(struct kvm_vcpu *vcpu, + unsigned long gra) +{ + return _kvm_s390_real_to_abs(kvm_s390_get_prefix(vcpu), gra); +} + +/** + * _kvm_s390_logical_to_effective - convert guest logical to effective address + * @psw: psw of the guest + * @ga: guest logical address + * + * Convert a guest logical address to an effective address by applying the + * rules of the addressing mode defined by bits 31 and 32 of the given PSW + * (extendended/basic addressing mode). + * + * Depending on the addressing mode, the upper 40 bits (24 bit addressing + * mode), 33 bits (31 bit addressing mode) or no bits (64 bit addressing + * mode) of @ga will be zeroed and the remaining bits will be returned. + */ +static inline unsigned long _kvm_s390_logical_to_effective(psw_t *psw, + unsigned long ga) +{ + if (psw_bits(*psw).eaba == PSW_BITS_AMODE_64BIT) + return ga; + if (psw_bits(*psw).eaba == PSW_BITS_AMODE_31BIT) + return ga & ((1UL << 31) - 1); + return ga & ((1UL << 24) - 1); +} + +/** * kvm_s390_logical_to_effective - convert guest logical to effective address * @vcpu: guest virtual cpu * @ga: guest logical address @@ -52,13 +86,7 @@ static inline unsigned long kvm_s390_logical_to_effective(struct kvm_vcpu *vcpu, unsigned long ga) { - psw_t *psw = &vcpu->arch.sie_block->gpsw; - - if (psw_bits(*psw).eaba == PSW_BITS_AMODE_64BIT) - return ga; - if (psw_bits(*psw).eaba == PSW_BITS_AMODE_31BIT) - return ga & ((1UL << 31) - 1); - return ga & ((1UL << 24) - 1); + return _kvm_s390_logical_to_effective(&vcpu->arch.sie_block->gpsw, ga); } /* @@ -158,24 +186,34 @@ GACC_IFETCH, }; -int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, - u8 ar, unsigned long *gpa, enum gacc_mode mode); +int guest_translate_address_with_key(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, + unsigned long *gpa, enum gacc_mode mode, + u8 access_key); + int check_gva_range(struct kvm_vcpu *vcpu, unsigned long gva, u8 ar, - unsigned long length, enum gacc_mode mode); + unsigned long length, enum gacc_mode mode, u8 access_key); + +int check_gpa_range(struct kvm *kvm, unsigned long gpa, unsigned long length, + enum gacc_mode mode, u8 access_key); -int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, - unsigned long len, enum gacc_mode mode); +int access_guest_abs_with_key(struct kvm *kvm, gpa_t gpa, void *data, + unsigned long len, enum gacc_mode mode, u8 access_key); + +int access_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, + void *data, unsigned long len, enum gacc_mode mode, + u8 access_key); int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, unsigned long len, enum gacc_mode mode); /** - * write_guest - copy data from kernel space to guest space + * write_guest_with_key - copy data from kernel space to guest space * @vcpu: virtual cpu * @ga: guest address * @ar: access register * @data: source address in kernel space * @len: number of bytes to copy + * @access_key: access key the storage key needs to match * * Copy @len bytes from @data (kernel space) to @ga (guest address). * In order to copy data to guest space the PSW of the vcpu is inspected: @@ -186,8 +224,8 @@ * The addressing mode of the PSW is also inspected, so that address wrap * around is taken into account for 24-, 31- and 64-bit addressing mode, * if the to be copied data crosses page boundaries in guest address space. - * In addition also low address and DAT protection are inspected before - * copying any data (key protection is currently not implemented). + * In addition low address, DAT and key protection checks are performed before + * copying any data. * * This function modifies the 'struct kvm_s390_pgm_info pgm' member of @vcpu. * In case of an access exception (e.g. protection exception) pgm will contain @@ -215,10 +253,53 @@ * if data has been changed in guest space in case of an exception. */ static inline __must_check +int write_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, + void *data, unsigned long len, u8 access_key) +{ + return access_guest_with_key(vcpu, ga, ar, data, len, GACC_STORE, + access_key); +} + +/** + * write_guest - copy data from kernel space to guest space + * @vcpu: virtual cpu + * @ga: guest address + * @ar: access register + * @data: source address in kernel space + * @len: number of bytes to copy + * + * The behaviour of write_guest is identical to write_guest_with_key, except + * that the PSW access key is used instead of an explicit argument. + */ +static inline __must_check int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, unsigned long len) { - return access_guest(vcpu, ga, ar, data, len, GACC_STORE); + u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key; + + return write_guest_with_key(vcpu, ga, ar, data, len, access_key); +} + +/** + * read_guest_with_key - copy data from guest space to kernel space + * @vcpu: virtual cpu + * @ga: guest address + * @ar: access register + * @data: destination address in kernel space + * @len: number of bytes to copy + * @access_key: access key the storage key needs to match + * + * Copy @len bytes from @ga (guest address) to @data (kernel space). + * + * The behaviour of read_guest_with_key is identical to write_guest_with_key, + * except that data will be copied from guest space to kernel space. + */ +static inline __must_check +int read_guest_with_key(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, + void *data, unsigned long len, u8 access_key) +{ + return access_guest_with_key(vcpu, ga, ar, data, len, GACC_FETCH, + access_key); } /** @@ -231,14 +312,16 @@ * * Copy @len bytes from @ga (guest address) to @data (kernel space). * - * The behaviour of read_guest is identical to write_guest, except that - * data will be copied from guest space to kernel space. + * The behaviour of read_guest is identical to read_guest_with_key, except + * that the PSW access key is used instead of an explicit argument. */ static inline __must_check int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, u8 ar, void *data, unsigned long len) { - return access_guest(vcpu, ga, ar, data, len, GACC_FETCH); + u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key; + + return read_guest_with_key(vcpu, ga, ar, data, len, access_key); } /** @@ -259,7 +342,10 @@ int read_guest_instr(struct kvm_vcpu *vcpu, unsigned long ga, void *data, unsigned long len) { - return access_guest(vcpu, ga, 0, data, len, GACC_IFETCH); + u8 access_key = psw_bits(vcpu->arch.sie_block->gpsw).key; + + return access_guest_with_key(vcpu, ga, 0, data, len, GACC_IFETCH, + access_key); } /** @@ -316,11 +402,12 @@ * @len: number of bytes to copy * * Copy @len bytes from @data (kernel space) to @gra (guest real address). - * It is up to the caller to ensure that the entire guest memory range is - * valid memory before calling this function. * Guest low address and key protection are not checked. * - * Returns zero on success or -EFAULT on error. + * Returns zero on success, -EFAULT when copying from @data failed, or + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info + * is also stored to allow injecting into the guest (if applicable) using + * kvm_s390_inject_prog_cond(). * * If an error occurs data may have been copied partially to guest memory. */ @@ -339,11 +426,12 @@ * @len: number of bytes to copy * * Copy @len bytes from @gra (guest real address) to @data (kernel space). - * It is up to the caller to ensure that the entire guest memory range is - * valid memory before calling this function. * Guest key protection is not checked. * - * Returns zero on success or -EFAULT on error. + * Returns zero on success, -EFAULT when copying to @data failed, or + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info + * is also stored to allow injecting into the guest (if applicable) using + * kvm_s390_inject_prog_cond(). * * If an error occurs data may have been copied partially to kernel space. */ --- linux-oracle-5.4.0.orig/arch/s390/kvm/intercept.c +++ linux-oracle-5.4.0/arch/s390/kvm/intercept.c @@ -2,7 +2,7 @@ /* * in-kernel handling for sie intercepts * - * Copyright IBM Corp. 2008, 2014 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte * Christian Borntraeger @@ -16,6 +16,7 @@ #include #include #include +#include #include "kvm-s390.h" #include "gaccess.h" @@ -79,6 +80,10 @@ return rc; } + /* + * no need to check the return value of vcpu_stop as it can only have + * an error for protvirt, but protvirt means user cpu state + */ if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) kvm_s390_vcpu_stop(vcpu); return -EOPNOTSUPP; @@ -231,6 +236,13 @@ vcpu->stat.exit_program_interruption++; + /* + * Intercept 8 indicates a loop of specification exceptions + * for protected guests. + */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) + return -EOPNOTSUPP; + if (guestdbg_enabled(vcpu) && per_event(vcpu)) { rc = kvm_s390_handle_per_event(vcpu); if (rc) @@ -318,18 +330,18 @@ kvm_s390_get_regs_rre(vcpu, ®1, ®2); - /* Make sure that the source is paged-in */ - rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2], - reg2, &srcaddr, GACC_FETCH); + /* Ensure that the source is paged-in, no actual access -> no key checking */ + rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg2], + reg2, &srcaddr, GACC_FETCH, 0); if (rc) return kvm_s390_inject_prog_cond(vcpu, rc); rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0); if (rc != 0) return rc; - /* Make sure that the destination is paged-in */ - rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1], - reg1, &dstaddr, GACC_STORE); + /* Ensure that the source is paged-in, no actual access -> no key checking */ + rc = guest_translate_address_with_key(vcpu, vcpu->run->s.regs.gprs[reg1], + reg1, &dstaddr, GACC_STORE, 0); if (rc) return kvm_s390_inject_prog_cond(vcpu, rc); rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1); @@ -360,8 +372,8 @@ */ int handle_sthyi(struct kvm_vcpu *vcpu) { - int reg1, reg2, r = 0; - u64 code, addr, cc = 0, rc = 0; + int reg1, reg2, cc = 0, r = 0; + u64 code, addr, rc = 0; struct sthyi_sctns *sctns = NULL; if (!test_kvm_facility(vcpu->kvm, 74)) @@ -384,7 +396,7 @@ goto out; } - if (addr & ~PAGE_MASK) + if (!kvm_s390_pv_cpu_is_protected(vcpu) && (addr & ~PAGE_MASK)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); sctns = (void *)get_zeroed_page(GFP_KERNEL); @@ -392,13 +404,21 @@ return -ENOMEM; cc = sthyi_fill(sctns, &rc); - + if (cc < 0) { + free_page((unsigned long)sctns); + return cc; + } out: if (!cc) { - r = write_guest(vcpu, addr, reg2, sctns, PAGE_SIZE); - if (r) { - free_page((unsigned long)sctns); - return kvm_s390_inject_prog_cond(vcpu, r); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + memcpy((void *)(sida_origin(vcpu->arch.sie_block)), + sctns, PAGE_SIZE); + } else { + r = write_guest(vcpu, addr, reg2, sctns, PAGE_SIZE); + if (r) { + free_page((unsigned long)sctns); + return kvm_s390_inject_prog_cond(vcpu, r); + } } } @@ -444,6 +464,97 @@ return kvm_s390_inject_program_int(vcpu, PGM_OPERATION); } +static int handle_pv_spx(struct kvm_vcpu *vcpu) +{ + u32 pref = *(u32 *)vcpu->arch.sie_block->sidad; + + kvm_s390_set_prefix(vcpu, pref); + trace_kvm_s390_handle_prefix(vcpu, 1, pref); + return 0; +} + +static int handle_pv_sclp(struct kvm_vcpu *vcpu) +{ + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + + spin_lock(&fi->lock); + /* + * 2 cases: + * a: an sccb answering interrupt was already pending or in flight. + * As the sccb value is not known we can simply set some value to + * trigger delivery of a saved SCCB. UV will then use its saved + * copy of the SCCB value. + * b: an error SCCB interrupt needs to be injected so we also inject + * a fake SCCB address. Firmware will use the proper one. + * This makes sure, that both errors and real sccb returns will only + * be delivered after a notification intercept (instruction has + * finished) but not after others. + */ + fi->srv_signal.ext_params |= 0x43000; + set_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs); + clear_bit(IRQ_PEND_EXT_SERVICE, &fi->masked_irqs); + spin_unlock(&fi->lock); + return 0; +} + +static int handle_pv_uvc(struct kvm_vcpu *vcpu) +{ + struct uv_cb_share *guest_uvcb = (void *)vcpu->arch.sie_block->sidad; + struct uv_cb_cts uvcb = { + .header.cmd = UVC_CMD_UNPIN_PAGE_SHARED, + .header.len = sizeof(uvcb), + .guest_handle = kvm_s390_pv_get_handle(vcpu->kvm), + .gaddr = guest_uvcb->paddr, + }; + int rc; + + if (guest_uvcb->header.cmd != UVC_CMD_REMOVE_SHARED_ACCESS) { + WARN_ONCE(1, "Unexpected notification intercept for UVC 0x%x\n", + guest_uvcb->header.cmd); + return 0; + } + rc = gmap_make_secure(vcpu->arch.gmap, uvcb.gaddr, &uvcb); + /* + * If the unpin did not succeed, the guest will exit again for the UVC + * and we will retry the unpin. + */ + if (rc == -EINVAL) + return 0; + /* + * If we got -EAGAIN here, we simply return it. It will eventually + * get propagated all the way to userspace, which should then try + * again. + */ + return rc; +} + +static int handle_pv_notification(struct kvm_vcpu *vcpu) +{ + int ret; + + if (vcpu->arch.sie_block->ipa == 0xb210) + return handle_pv_spx(vcpu); + if (vcpu->arch.sie_block->ipa == 0xb220) + return handle_pv_sclp(vcpu); + if (vcpu->arch.sie_block->ipa == 0xb9a4) + return handle_pv_uvc(vcpu); + if (vcpu->arch.sie_block->ipa >> 8 == 0xae) { + /* + * Besides external call, other SIGP orders also cause a + * 108 (pv notify) intercept. In contrast to external call, + * these orders need to be emulated and hence the appropriate + * place to handle them is in handle_instruction(). + * So first try kvm_s390_handle_sigp_pei() and if that isn't + * successful, go on with handle_instruction(). + */ + ret = kvm_s390_handle_sigp_pei(vcpu); + if (!ret) + return ret; + } + + return handle_instruction(vcpu); +} + int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) { int rc, per_rc = 0; @@ -480,6 +591,28 @@ case ICPT_KSS: rc = kvm_s390_skey_check_enable(vcpu); break; + case ICPT_MCHKREQ: + case ICPT_INT_ENABLE: + /* + * PSW bit 13 or a CR (0, 6, 14) changed and we might + * now be able to deliver interrupts. The pre-run code + * will take care of this. + */ + rc = 0; + break; + case ICPT_PV_INSTR: + rc = handle_instruction(vcpu); + break; + case ICPT_PV_NOTIFY: + rc = handle_pv_notification(vcpu); + break; + case ICPT_PV_PREF: + rc = 0; + gmap_convert_to_secure(vcpu->arch.gmap, + kvm_s390_get_prefix(vcpu)); + gmap_convert_to_secure(vcpu->arch.gmap, + kvm_s390_get_prefix(vcpu) + PAGE_SIZE); + break; default: return -EOPNOTSUPP; } --- linux-oracle-5.4.0.orig/arch/s390/kvm/interrupt.c +++ linux-oracle-5.4.0/arch/s390/kvm/interrupt.c @@ -2,7 +2,7 @@ /* * handling kvm guest interrupts * - * Copyright IBM Corp. 2008, 2015 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte */ @@ -81,8 +81,9 @@ struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union esca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl; + union esca_sigp_ctrl new_val = {0}, old_val; + old_val = READ_ONCE(*sigp_ctrl); new_val.scn = src_id; new_val.c = 1; old_val.c = 0; @@ -93,8 +94,9 @@ struct bsca_block *sca = vcpu->kvm->arch.sca; union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union bsca_sigp_ctrl new_val = {0}, old_val = *sigp_ctrl; + union bsca_sigp_ctrl new_val = {0}, old_val; + old_val = READ_ONCE(*sigp_ctrl); new_val.scn = src_id; new_val.c = 1; old_val.c = 0; @@ -124,16 +126,18 @@ struct esca_block *sca = vcpu->kvm->arch.sca; union esca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union esca_sigp_ctrl old = *sigp_ctrl; + union esca_sigp_ctrl old; + old = READ_ONCE(*sigp_ctrl); expect = old.value; rc = cmpxchg(&sigp_ctrl->value, old.value, 0); } else { struct bsca_block *sca = vcpu->kvm->arch.sca; union bsca_sigp_ctrl *sigp_ctrl = &(sca->cpu[vcpu->vcpu_id].sigp_ctrl); - union bsca_sigp_ctrl old = *sigp_ctrl; + union bsca_sigp_ctrl old; + old = READ_ONCE(*sigp_ctrl); expect = old.value; rc = cmpxchg(&sigp_ctrl->value, old.value, 0); } @@ -324,8 +328,11 @@ static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu) { - return vcpu->kvm->arch.float_int.pending_irqs | - vcpu->arch.local_int.pending_irqs; + unsigned long pending = vcpu->kvm->arch.float_int.pending_irqs | + vcpu->arch.local_int.pending_irqs; + + pending &= ~vcpu->kvm->arch.float_int.masked_irqs; + return pending; } static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu) @@ -383,10 +390,18 @@ __clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &active_mask); if (!(vcpu->arch.sie_block->gcr[0] & CR0_CPU_TIMER_SUBMASK)) __clear_bit(IRQ_PEND_EXT_CPU_TIMER, &active_mask); - if (!(vcpu->arch.sie_block->gcr[0] & CR0_SERVICE_SIGNAL_SUBMASK)) + if (!(vcpu->arch.sie_block->gcr[0] & CR0_SERVICE_SIGNAL_SUBMASK)) { __clear_bit(IRQ_PEND_EXT_SERVICE, &active_mask); + __clear_bit(IRQ_PEND_EXT_SERVICE_EV, &active_mask); + } if (psw_mchk_disabled(vcpu)) active_mask &= ~IRQ_PEND_MCHK_MASK; + /* PV guest cpus can have a single interruption injected at a time. */ + if (kvm_s390_pv_cpu_is_protected(vcpu) && + vcpu->arch.sie_block->iictl != IICTL_CODE_NONE) + active_mask &= ~(IRQ_PEND_EXT_II_MASK | + IRQ_PEND_IO_MASK | + IRQ_PEND_MCHK_MASK); /* * Check both floating and local interrupt's cr14 because * bit IRQ_PEND_MCHK_REP could be set in both cases. @@ -408,13 +423,13 @@ static void __set_cpu_idle(struct kvm_vcpu *vcpu) { kvm_s390_set_cpuflags(vcpu, CPUSTAT_WAIT); - set_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + set_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static void __unset_cpu_idle(struct kvm_vcpu *vcpu) { kvm_s390_clear_cpuflags(vcpu, CPUSTAT_WAIT); - clear_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + clear_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static void __reset_intercept_indicators(struct kvm_vcpu *vcpu) @@ -479,19 +494,23 @@ static int __must_check __deliver_cpu_timer(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; - int rc; + int rc = 0; vcpu->stat.deliver_cputm++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CPU_TIMER, 0, 0); - - rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER, - (u16 *)__LC_EXT_INT_CODE); - rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); - rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_EXT; + vcpu->arch.sie_block->eic = EXT_IRQ_CPU_TIMER; + } else { + rc = put_guest_lc(vcpu, EXT_IRQ_CPU_TIMER, + (u16 *)__LC_EXT_INT_CODE); + rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); + rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + } clear_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); return rc ? -EFAULT : 0; } @@ -499,19 +518,23 @@ static int __must_check __deliver_ckc(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; - int rc; + int rc = 0; vcpu->stat.deliver_ckc++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_CLOCK_COMP, 0, 0); - - rc = put_guest_lc(vcpu, EXT_IRQ_CLK_COMP, - (u16 __user *)__LC_EXT_INT_CODE); - rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); - rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_EXT; + vcpu->arch.sie_block->eic = EXT_IRQ_CLK_COMP; + } else { + rc = put_guest_lc(vcpu, EXT_IRQ_CLK_COMP, + (u16 __user *)__LC_EXT_INT_CODE); + rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); + rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + } clear_bit(IRQ_PEND_EXT_CLOCK_COMP, &li->pending_irqs); return rc ? -EFAULT : 0; } @@ -553,6 +576,20 @@ union mci mci; int rc; + /* + * All other possible payload for a machine check (e.g. the register + * contents in the save area) will be handled by the ultravisor, as + * the hypervisor does not not have the needed information for + * protected guests. + */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_MCHK; + vcpu->arch.sie_block->mcic = mchk->mcic; + vcpu->arch.sie_block->faddr = mchk->failing_storage_address; + vcpu->arch.sie_block->edc = mchk->ext_damage_code; + return 0; + } + mci.val = mchk->mcic; /* take care of lazy register loading */ save_fpu_regs(); @@ -696,17 +733,21 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; - int rc; + int rc = 0; VCPU_EVENT(vcpu, 3, "%s", "deliver: cpu restart"); vcpu->stat.deliver_restart_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); - rc = write_guest_lc(vcpu, - offsetof(struct lowcore, restart_old_psw), - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw), - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_RESTART; + } else { + rc = write_guest_lc(vcpu, + offsetof(struct lowcore, restart_old_psw), + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw), + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + } clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); return rc ? -EFAULT : 0; } @@ -748,6 +789,12 @@ vcpu->stat.deliver_emergency_signal++; trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_EMERGENCY, cpu_addr, 0); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_EXT; + vcpu->arch.sie_block->eic = EXT_IRQ_EMERGENCY_SIG; + vcpu->arch.sie_block->extcpuaddr = cpu_addr; + return 0; + } rc = put_guest_lc(vcpu, EXT_IRQ_EMERGENCY_SIG, (u16 *)__LC_EXT_INT_CODE); @@ -776,6 +823,12 @@ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_EXTERNAL_CALL, extcall.code, 0); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_EXT; + vcpu->arch.sie_block->eic = EXT_IRQ_EXTERNAL_CALL; + vcpu->arch.sie_block->extcpuaddr = extcall.code; + return 0; + } rc = put_guest_lc(vcpu, EXT_IRQ_EXTERNAL_CALL, (u16 *)__LC_EXT_INT_CODE); @@ -787,6 +840,21 @@ return rc ? -EFAULT : 0; } +static int __deliver_prog_pv(struct kvm_vcpu *vcpu, u16 code) +{ + switch (code) { + case PGM_SPECIFICATION: + vcpu->arch.sie_block->iictl = IICTL_CODE_SPECIFICATION; + break; + case PGM_OPERAND: + vcpu->arch.sie_block->iictl = IICTL_CODE_OPERAND; + break; + default: + return -EINVAL; + } + return 0; +} + static int __must_check __deliver_prog(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; @@ -807,6 +875,10 @@ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_PROGRAM_INT, pgm_info.code, 0); + /* PER is handled by the ultravisor */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) + return __deliver_prog_pv(vcpu, pgm_info.code & ~PGM_PER); + switch (pgm_info.code & ~PGM_PER) { case PGM_AFX_TRANSLATION: case PGM_ASX_TRANSLATION: @@ -902,20 +974,49 @@ return rc ? -EFAULT : 0; } +#define SCCB_MASK 0xFFFFFFF8 +#define SCCB_EVENT_PENDING 0x3 + +static int write_sclp(struct kvm_vcpu *vcpu, u32 parm) +{ + int rc; + + if (kvm_s390_pv_cpu_get_handle(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_EXT; + vcpu->arch.sie_block->eic = EXT_IRQ_SERVICE_SIG; + vcpu->arch.sie_block->eiparams = parm; + return 0; + } + + rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE); + rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); + rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, + &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); + rc |= put_guest_lc(vcpu, parm, + (u32 *)__LC_EXT_PARAMS); + + return rc ? -EFAULT : 0; +} + static int __must_check __deliver_service(struct kvm_vcpu *vcpu) { struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; struct kvm_s390_ext_info ext; - int rc = 0; spin_lock(&fi->lock); - if (!(test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs))) { + if (test_bit(IRQ_PEND_EXT_SERVICE, &fi->masked_irqs) || + !(test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs))) { spin_unlock(&fi->lock); return 0; } ext = fi->srv_signal; memset(&fi->srv_signal, 0, sizeof(ext)); clear_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs); + clear_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs); + if (kvm_s390_pv_cpu_is_protected(vcpu)) + set_bit(IRQ_PEND_EXT_SERVICE, &fi->masked_irqs); spin_unlock(&fi->lock); VCPU_EVENT(vcpu, 4, "deliver: sclp parameter 0x%x", @@ -924,16 +1025,31 @@ trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, ext.ext_params, 0); - rc = put_guest_lc(vcpu, EXT_IRQ_SERVICE_SIG, (u16 *)__LC_EXT_INT_CODE); - rc |= put_guest_lc(vcpu, 0, (u16 *)__LC_EXT_CPU_ADDR); - rc |= write_guest_lc(vcpu, __LC_EXT_OLD_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= read_guest_lc(vcpu, __LC_EXT_NEW_PSW, - &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); - rc |= put_guest_lc(vcpu, ext.ext_params, - (u32 *)__LC_EXT_PARAMS); + return write_sclp(vcpu, ext.ext_params); +} - return rc ? -EFAULT : 0; +static int __must_check __deliver_service_ev(struct kvm_vcpu *vcpu) +{ + struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; + struct kvm_s390_ext_info ext; + + spin_lock(&fi->lock); + if (!(test_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs))) { + spin_unlock(&fi->lock); + return 0; + } + ext = fi->srv_signal; + /* only clear the event bit */ + fi->srv_signal.ext_params &= ~SCCB_EVENT_PENDING; + clear_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs); + spin_unlock(&fi->lock); + + VCPU_EVENT(vcpu, 4, "%s", "deliver: sclp parameter event"); + vcpu->stat.deliver_service_signal++; + trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_INT_SERVICE, + ext.ext_params, 0); + + return write_sclp(vcpu, SCCB_EVENT_PENDING); } static int __must_check __deliver_pfault_done(struct kvm_vcpu *vcpu) @@ -1028,6 +1144,15 @@ { int rc; + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->iictl = IICTL_CODE_IO; + vcpu->arch.sie_block->subchannel_id = io->subchannel_id; + vcpu->arch.sie_block->subchannel_nr = io->subchannel_nr; + vcpu->arch.sie_block->io_int_parm = io->io_int_parm; + vcpu->arch.sie_block->io_int_word = io->io_int_word; + return 0; + } + rc = put_guest_lc(vcpu, io->subchannel_id, (u16 *)__LC_SUBCHANNEL_ID); rc |= put_guest_lc(vcpu, io->subchannel_nr, (u16 *)__LC_SUBCHANNEL_NR); rc |= put_guest_lc(vcpu, io->io_int_parm, (u32 *)__LC_IO_INT_PARM); @@ -1329,6 +1454,9 @@ case IRQ_PEND_EXT_SERVICE: rc = __deliver_service(vcpu); break; + case IRQ_PEND_EXT_SERVICE_EV: + rc = __deliver_service_ev(vcpu); + break; case IRQ_PEND_PFAULT_DONE: rc = __deliver_pfault_done(vcpu); break; @@ -1421,7 +1549,7 @@ if (kvm_get_vcpu_by_id(vcpu->kvm, src_id) == NULL) return -EINVAL; - if (sclp.has_sigpif) + if (sclp.has_sigpif && !kvm_s390_pv_cpu_get_handle(vcpu)) return sca_inject_ext_call(vcpu, src_id); if (test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs)) @@ -1682,9 +1810,6 @@ return inti; } -#define SCCB_MASK 0xFFFFFFF8 -#define SCCB_EVENT_PENDING 0x3 - static int __inject_service(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) { @@ -1693,6 +1818,11 @@ kvm->stat.inject_service_signal++; spin_lock(&fi->lock); fi->srv_signal.ext_params |= inti->ext.ext_params & SCCB_EVENT_PENDING; + + /* We always allow events, track them separately from the sccb ints */ + if (fi->srv_signal.ext_params & SCCB_EVENT_PENDING) + set_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs); + /* * Early versions of the QEMU s390 bios will inject several * service interrupts after another without handling a @@ -1774,7 +1904,14 @@ kvm->stat.inject_io++; isc = int_word_to_isc(inti->io.io_int_word); - if (gi->origin && inti->type & KVM_S390_INT_IO_AI_MASK) { + /* + * Do not make use of gisa in protected mode. We do not use the lock + * checking variant as this is just a performance optimization and we + * do not hold the lock here. This is ok as the code will pick + * interrupts from both "lists" for delivery. + */ + if (!kvm_s390_pv_get_handle(kvm) && + gi->origin && inti->type & KVM_S390_INT_IO_AI_MASK) { VM_EVENT(kvm, 4, "%s isc %1u", "inject: I/O (AI/gisa)", isc); gisa_set_ipm_gisc(gi->origin, isc); kfree(inti); @@ -1835,7 +1972,8 @@ break; case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: if (!(type & KVM_S390_INT_IO_AI_MASK && - kvm->arch.gisa_int.origin)) + kvm->arch.gisa_int.origin) || + kvm_s390_pv_cpu_get_handle(dst_vcpu)) kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT); break; default: @@ -1982,6 +2120,13 @@ return test_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs); } +int kvm_s390_is_restart_irq_pending(struct kvm_vcpu *vcpu) +{ + struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; + + return test_bit(IRQ_PEND_RESTART, &li->pending_irqs); +} + void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu) { struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; @@ -2081,6 +2226,10 @@ struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; int i; + mutex_lock(&kvm->lock); + if (!kvm_s390_pv_is_protected(kvm)) + fi->masked_irqs = 0; + mutex_unlock(&kvm->lock); spin_lock(&fi->lock); fi->pending_irqs = 0; memset(&fi->srv_signal, 0, sizeof(fi->srv_signal)); @@ -2147,7 +2296,8 @@ n++; } } - if (test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs)) { + if (test_bit(IRQ_PEND_EXT_SERVICE, &fi->pending_irqs) || + test_bit(IRQ_PEND_EXT_SERVICE_EV, &fi->pending_irqs)) { if (n == max_irqs) { /* signal userspace to try again */ ret = -ENOMEM; @@ -2191,7 +2341,7 @@ return -EINVAL; if (!test_kvm_facility(kvm, 72)) - return -ENOTSUPP; + return -EOPNOTSUPP; mutex_lock(&fi->ais_lock); ais.simm = fi->simm; @@ -2328,9 +2478,6 @@ if (!adapter) return -ENOMEM; - INIT_LIST_HEAD(&adapter->maps); - init_rwsem(&adapter->maps_lock); - atomic_set(&adapter->nr_maps, 0); adapter->id = adapter_info.id; adapter->isc = adapter_info.isc; adapter->maskable = adapter_info.maskable; @@ -2355,87 +2502,12 @@ return ret; } -static int kvm_s390_adapter_map(struct kvm *kvm, unsigned int id, __u64 addr) -{ - struct s390_io_adapter *adapter = get_io_adapter(kvm, id); - struct s390_map_info *map; - int ret; - - if (!adapter || !addr) - return -EINVAL; - - map = kzalloc(sizeof(*map), GFP_KERNEL); - if (!map) { - ret = -ENOMEM; - goto out; - } - INIT_LIST_HEAD(&map->list); - map->guest_addr = addr; - map->addr = gmap_translate(kvm->arch.gmap, addr); - if (map->addr == -EFAULT) { - ret = -EFAULT; - goto out; - } - ret = get_user_pages_fast(map->addr, 1, FOLL_WRITE, &map->page); - if (ret < 0) - goto out; - BUG_ON(ret != 1); - down_write(&adapter->maps_lock); - if (atomic_inc_return(&adapter->nr_maps) < MAX_S390_ADAPTER_MAPS) { - list_add_tail(&map->list, &adapter->maps); - ret = 0; - } else { - put_page(map->page); - ret = -EINVAL; - } - up_write(&adapter->maps_lock); -out: - if (ret) - kfree(map); - return ret; -} - -static int kvm_s390_adapter_unmap(struct kvm *kvm, unsigned int id, __u64 addr) -{ - struct s390_io_adapter *adapter = get_io_adapter(kvm, id); - struct s390_map_info *map, *tmp; - int found = 0; - - if (!adapter || !addr) - return -EINVAL; - - down_write(&adapter->maps_lock); - list_for_each_entry_safe(map, tmp, &adapter->maps, list) { - if (map->guest_addr == addr) { - found = 1; - atomic_dec(&adapter->nr_maps); - list_del(&map->list); - put_page(map->page); - kfree(map); - break; - } - } - up_write(&adapter->maps_lock); - - return found ? 0 : -EINVAL; -} - void kvm_s390_destroy_adapters(struct kvm *kvm) { int i; - struct s390_map_info *map, *tmp; - for (i = 0; i < MAX_S390_IO_ADAPTERS; i++) { - if (!kvm->arch.adapters[i]) - continue; - list_for_each_entry_safe(map, tmp, - &kvm->arch.adapters[i]->maps, list) { - list_del(&map->list); - put_page(map->page); - kfree(map); - } + for (i = 0; i < MAX_S390_IO_ADAPTERS; i++) kfree(kvm->arch.adapters[i]); - } } static int modify_io_adapter(struct kvm_device *dev, @@ -2457,11 +2529,14 @@ if (ret > 0) ret = 0; break; + /* + * The following operations are no longer needed and therefore no-ops. + * The gpa to hva translation is done when an IRQ route is set up. The + * set_irq code uses get_user_pages_remote() to do the actual write. + */ case KVM_S390_IO_ADAPTER_MAP: - ret = kvm_s390_adapter_map(dev->kvm, req.id, req.addr); - break; case KVM_S390_IO_ADAPTER_UNMAP: - ret = kvm_s390_adapter_unmap(dev->kvm, req.id, req.addr); + ret = 0; break; default: ret = -EINVAL; @@ -2500,7 +2575,7 @@ int ret = 0; if (!test_kvm_facility(kvm, 72)) - return -ENOTSUPP; + return -EOPNOTSUPP; if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req))) return -EFAULT; @@ -2580,7 +2655,7 @@ struct kvm_s390_ais_all ais; if (!test_kvm_facility(kvm, 72)) - return -ENOTSUPP; + return -EOPNOTSUPP; if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais))) return -EFAULT; @@ -2700,19 +2775,15 @@ return swap ? (bit ^ (BITS_PER_LONG - 1)) : bit; } -static struct s390_map_info *get_map_info(struct s390_io_adapter *adapter, - u64 addr) +static struct page *get_map_page(struct kvm *kvm, u64 uaddr) { - struct s390_map_info *map; + struct page *page = NULL; - if (!adapter) - return NULL; - - list_for_each_entry(map, &adapter->maps, list) { - if (map->guest_addr == addr) - return map; - } - return NULL; + down_read(&kvm->mm->mmap_sem); + get_user_pages_remote(NULL, kvm->mm, uaddr, 1, FOLL_WRITE, + &page, NULL, NULL); + up_read(&kvm->mm->mmap_sem); + return page; } static int adapter_indicators_set(struct kvm *kvm, @@ -2721,30 +2792,35 @@ { unsigned long bit; int summary_set, idx; - struct s390_map_info *info; + struct page *ind_page, *summary_page; void *map; - info = get_map_info(adapter, adapter_int->ind_addr); - if (!info) + ind_page = get_map_page(kvm, adapter_int->ind_addr); + if (!ind_page) return -1; - map = page_address(info->page); - bit = get_ind_bit(info->addr, adapter_int->ind_offset, adapter->swap); - set_bit(bit, map); - idx = srcu_read_lock(&kvm->srcu); - mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT); - set_page_dirty_lock(info->page); - info = get_map_info(adapter, adapter_int->summary_addr); - if (!info) { - srcu_read_unlock(&kvm->srcu, idx); + summary_page = get_map_page(kvm, adapter_int->summary_addr); + if (!summary_page) { + put_page(ind_page); return -1; } - map = page_address(info->page); - bit = get_ind_bit(info->addr, adapter_int->summary_offset, - adapter->swap); + + idx = srcu_read_lock(&kvm->srcu); + map = page_address(ind_page); + bit = get_ind_bit(adapter_int->ind_addr, + adapter_int->ind_offset, adapter->swap); + set_bit(bit, map); + mark_page_dirty(kvm, adapter_int->ind_addr >> PAGE_SHIFT); + set_page_dirty_lock(ind_page); + map = page_address(summary_page); + bit = get_ind_bit(adapter_int->summary_addr, + adapter_int->summary_offset, adapter->swap); summary_set = test_and_set_bit(bit, map); - mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT); - set_page_dirty_lock(info->page); + mark_page_dirty(kvm, adapter_int->summary_addr >> PAGE_SHIFT); + set_page_dirty_lock(summary_page); srcu_read_unlock(&kvm->srcu, idx); + + put_page(ind_page); + put_page(summary_page); return summary_set ? 0 : 1; } @@ -2766,9 +2842,7 @@ adapter = get_io_adapter(kvm, e->adapter.adapter_id); if (!adapter) return -1; - down_read(&adapter->maps_lock); ret = adapter_indicators_set(kvm, adapter, &e->adapter); - up_read(&adapter->maps_lock); if ((ret > 0) && !adapter->masked) { ret = kvm_s390_inject_airq(kvm, adapter); if (ret == 0) @@ -2819,23 +2893,27 @@ struct kvm_kernel_irq_routing_entry *e, const struct kvm_irq_routing_entry *ue) { - int ret; + u64 uaddr; switch (ue->type) { + /* we store the userspace addresses instead of the guest addresses */ case KVM_IRQ_ROUTING_S390_ADAPTER: e->set = set_adapter_int; - e->adapter.summary_addr = ue->u.adapter.summary_addr; - e->adapter.ind_addr = ue->u.adapter.ind_addr; + uaddr = gmap_translate(kvm->arch.gmap, ue->u.adapter.summary_addr); + if (uaddr == -EFAULT) + return -EFAULT; + e->adapter.summary_addr = uaddr; + uaddr = gmap_translate(kvm->arch.gmap, ue->u.adapter.ind_addr); + if (uaddr == -EFAULT) + return -EFAULT; + e->adapter.ind_addr = uaddr; e->adapter.summary_offset = ue->u.adapter.summary_offset; e->adapter.ind_offset = ue->u.adapter.ind_offset; e->adapter.adapter_id = ue->u.adapter.adapter_id; - ret = 0; - break; + return 0; default: - ret = -EINVAL; + return -EINVAL; } - - return ret; } int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm, @@ -2984,18 +3062,19 @@ static void __airqs_kick_single_vcpu(struct kvm *kvm, u8 deliverable_mask) { - int vcpu_id, online_vcpus = atomic_read(&kvm->online_vcpus); + int vcpu_idx, online_vcpus = atomic_read(&kvm->online_vcpus); struct kvm_s390_gisa_interrupt *gi = &kvm->arch.gisa_int; struct kvm_vcpu *vcpu; + u8 vcpu_isc_mask; - for_each_set_bit(vcpu_id, kvm->arch.idle_mask, online_vcpus) { - vcpu = kvm_get_vcpu(kvm, vcpu_id); + for_each_set_bit(vcpu_idx, kvm->arch.idle_mask, online_vcpus) { + vcpu = kvm_get_vcpu(kvm, vcpu_idx); if (psw_ioint_disabled(vcpu)) continue; - deliverable_mask &= (u8)(vcpu->arch.sie_block->gcr[6] >> 24); - if (deliverable_mask) { + vcpu_isc_mask = (u8)(vcpu->arch.sie_block->gcr[6] >> 24); + if (deliverable_mask & vcpu_isc_mask) { /* lately kicked but not yet running */ - if (test_and_set_bit(vcpu_id, gi->kicked_mask)) + if (test_and_set_bit(vcpu_idx, gi->kicked_mask)) return; kvm_s390_vcpu_wakeup(vcpu); return; --- linux-oracle-5.4.0.orig/arch/s390/kvm/kvm-s390.c +++ linux-oracle-5.4.0/arch/s390/kvm/kvm-s390.c @@ -2,7 +2,7 @@ /* * hosting IBM Z kernel virtual machines (s390x) * - * Copyright IBM Corp. 2008, 2018 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte * Christian Borntraeger @@ -44,6 +44,7 @@ #include #include #include +#include #include "kvm-s390.h" #include "gaccess.h" @@ -219,6 +220,7 @@ static struct gmap_notifier gmap_notifier; static struct gmap_notifier vsie_gmap_notifier; debug_info_t *kvm_s390_dbf; +debug_info_t *kvm_s390_dbf_uv; /* Section: not file related */ int kvm_arch_hardware_enable(void) @@ -232,8 +234,10 @@ return 0; } +/* forward declarations */ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start, unsigned long end); +static int sca_switch_to_extended(struct kvm *kvm); static void kvm_clock_sync_scb(struct kvm_s390_sie_block *scb, u64 delta) { @@ -318,31 +322,31 @@ static inline int plo_test_bit(unsigned char nr) { - register unsigned long r0 asm("0") = (unsigned long) nr | 0x100; + unsigned long function = (unsigned long)nr | 0x100; int cc; asm volatile( + " lgr 0,%[function]\n" /* Parameter registers are ignored for "test bit" */ " plo 0,0,0,0(0)\n" " ipm %0\n" " srl %0,28\n" : "=d" (cc) - : "d" (r0) - : "cc"); + : [function] "d" (function) + : "cc", "0"); return cc == 0; } static __always_inline void __insn32_query(unsigned int opcode, u8 *query) { - register unsigned long r0 asm("0") = 0; /* query function */ - register unsigned long r1 asm("1") = (unsigned long) query; - asm volatile( - /* Parameter regs are ignored */ + " lghi 0,0\n" + " lgr 1,%[query]\n" + /* Parameter registers are ignored */ " .insn rrf,%[opc] << 16,2,4,6,0\n" : - : "d" (r0), "a" (r1), [opc] "i" (opcode) - : "cc", "memory"); + : [query] "d" ((unsigned long)query), [opc] "i" (opcode) + : "cc", "memory", "0", "1"); } #define INSN_SORTL 0xb938 @@ -453,16 +457,19 @@ int kvm_arch_init(void *opaque) { - int rc; + int rc = -ENOMEM; kvm_s390_dbf = debug_register("kvm-trace", 32, 1, 7 * sizeof(long)); if (!kvm_s390_dbf) return -ENOMEM; - if (debug_register_view(kvm_s390_dbf, &debug_sprintf_view)) { - rc = -ENOMEM; - goto out_debug_unreg; - } + kvm_s390_dbf_uv = debug_register("kvm-uv", 32, 1, 7 * sizeof(long)); + if (!kvm_s390_dbf_uv) + goto out; + + if (debug_register_view(kvm_s390_dbf, &debug_sprintf_view) || + debug_register_view(kvm_s390_dbf_uv, &debug_sprintf_view)) + goto out; kvm_s390_cpu_feat_init(); @@ -470,19 +477,17 @@ rc = kvm_register_device_ops(&kvm_flic_ops, KVM_DEV_TYPE_FLIC); if (rc) { pr_err("A FLIC registration call failed with rc=%d\n", rc); - goto out_debug_unreg; + goto out; } rc = kvm_s390_gib_init(GAL_ISC); if (rc) - goto out_gib_destroy; + goto out; return 0; -out_gib_destroy: - kvm_s390_gib_destroy(); -out_debug_unreg: - debug_unregister(kvm_s390_dbf); +out: + kvm_arch_exit(); return rc; } @@ -490,6 +495,7 @@ { kvm_s390_gib_destroy(); debug_unregister(kvm_s390_dbf); + debug_unregister(kvm_s390_dbf_uv); } /* Section: device related */ @@ -532,6 +538,9 @@ case KVM_CAP_S390_CMMA_MIGRATION: case KVM_CAP_S390_AIS: case KVM_CAP_S390_AIS_MIGRATION: + case KVM_CAP_S390_VCPU_RESETS: + case KVM_CAP_S390_DIAG318: + case KVM_CAP_S390_MEM_OP_EXTENSION: r = 1; break; case KVM_CAP_S390_HPAGE_1M: @@ -566,6 +575,9 @@ case KVM_CAP_S390_BPB: r = test_facility(82); break; + case KVM_CAP_S390_PROTECTED: + r = is_prot_virt_host(); + break; default: r = 0; } @@ -1084,6 +1096,8 @@ return 0; } +static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); + static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) { struct kvm_s390_vm_tod_clock gtod; @@ -1093,7 +1107,7 @@ if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx) return -EINVAL; - kvm_s390_set_tod_clock(kvm, >od); + __kvm_s390_set_tod_clock(kvm, >od); VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx", gtod.epoch_idx, gtod.tod); @@ -1124,7 +1138,7 @@ sizeof(gtod.tod))) return -EFAULT; - kvm_s390_set_tod_clock(kvm, >od); + __kvm_s390_set_tod_clock(kvm, >od); VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod); return 0; } @@ -1136,6 +1150,16 @@ if (attr->flags) return -EINVAL; + mutex_lock(&kvm->lock); + /* + * For protected guests, the TOD is managed by the ultravisor, so trying + * to change it will never bring the expected results. + */ + if (kvm_s390_pv_is_protected(kvm)) { + ret = -EOPNOTSUPP; + goto out_unlock; + } + switch (attr->attr) { case KVM_S390_VM_TOD_EXT: ret = kvm_s390_set_tod_ext(kvm, attr); @@ -1150,6 +1174,9 @@ ret = -ENXIO; break; } + +out_unlock: + mutex_unlock(&kvm->lock); return ret; } @@ -1932,6 +1959,9 @@ start = slot + 1; } + if (start >= slots->used_slots) + return slots->used_slots - 1; + if (gfn >= memslots[start].base_gfn && gfn < memslots[start].base_gfn + memslots[start].npages) { atomic_set(&slots->lru_slot, start); @@ -1979,6 +2009,10 @@ ms = slots->memslots + slotidx; ofs = 0; } + + if (cur_gfn < ms->base_gfn) + ofs = 0; + ofs = find_next_bit(kvm_second_dirty_bitmap(ms), ms->npages, ofs); while ((slotidx > 0) && (ofs >= ms->npages)) { slotidx--; @@ -2160,6 +2194,271 @@ return r; } +static int kvm_s390_cpus_from_pv(struct kvm *kvm, u16 *rcp, u16 *rrcp) +{ + struct kvm_vcpu *vcpu; + u16 rc, rrc; + int ret = 0; + int i; + + /* + * We ignore failures and try to destroy as many CPUs as possible. + * At the same time we must not free the assigned resources when + * this fails, as the ultravisor has still access to that memory. + * So kvm_s390_pv_destroy_cpu can leave a "wanted" memory leak + * behind. + * We want to return the first failure rc and rrc, though. + */ + kvm_for_each_vcpu(i, vcpu, kvm) { + mutex_lock(&vcpu->mutex); + if (kvm_s390_pv_destroy_cpu(vcpu, &rc, &rrc) && !ret) { + *rcp = rc; + *rrcp = rrc; + ret = -EIO; + } + mutex_unlock(&vcpu->mutex); + } + return ret; +} + +static int kvm_s390_cpus_to_pv(struct kvm *kvm, u16 *rc, u16 *rrc) +{ + int i, r = 0; + u16 dummy; + + struct kvm_vcpu *vcpu; + + kvm_for_each_vcpu(i, vcpu, kvm) { + mutex_lock(&vcpu->mutex); + r = kvm_s390_pv_create_cpu(vcpu, rc, rrc); + mutex_unlock(&vcpu->mutex); + if (r) + break; + } + if (r) + kvm_s390_cpus_from_pv(kvm, &dummy, &dummy); + return r; +} + +static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd) +{ + int r = 0; + u16 dummy; + void __user *argp = (void __user *)cmd->data; + + switch (cmd->cmd) { + case KVM_PV_ENABLE: { + r = -EINVAL; + if (kvm_s390_pv_is_protected(kvm)) + break; + + /* + * FMT 4 SIE needs esca. As we never switch back to bsca from + * esca, we need no cleanup in the error cases below + */ + r = sca_switch_to_extended(kvm); + if (r) + break; + + down_write(¤t->mm->mmap_sem); + r = gmap_mark_unmergeable(); + up_write(¤t->mm->mmap_sem); + if (r) + break; + + r = kvm_s390_pv_init_vm(kvm, &cmd->rc, &cmd->rrc); + if (r) + break; + + r = kvm_s390_cpus_to_pv(kvm, &cmd->rc, &cmd->rrc); + if (r) + kvm_s390_pv_deinit_vm(kvm, &dummy, &dummy); + + /* we need to block service interrupts from now on */ + set_bit(IRQ_PEND_EXT_SERVICE, &kvm->arch.float_int.masked_irqs); + break; + } + case KVM_PV_DISABLE: { + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = kvm_s390_cpus_from_pv(kvm, &cmd->rc, &cmd->rrc); + /* + * If a CPU could not be destroyed, destroy VM will also fail. + * There is no point in trying to destroy it. Instead return + * the rc and rrc from the first CPU that failed destroying. + */ + if (r) + break; + r = kvm_s390_pv_deinit_vm(kvm, &cmd->rc, &cmd->rrc); + + /* no need to block service interrupts any more */ + clear_bit(IRQ_PEND_EXT_SERVICE, &kvm->arch.float_int.masked_irqs); + break; + } + case KVM_PV_SET_SEC_PARMS: { + struct kvm_s390_pv_sec_parm parms = {}; + void *hdr; + + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = -EFAULT; + if (copy_from_user(&parms, argp, sizeof(parms))) + break; + + /* Currently restricted to 8KB */ + r = -EINVAL; + if (parms.length > PAGE_SIZE * 2) + break; + + r = -ENOMEM; + hdr = vmalloc(parms.length); + if (!hdr) + break; + + r = -EFAULT; + if (!copy_from_user(hdr, (void __user *)parms.origin, + parms.length)) + r = kvm_s390_pv_set_sec_parms(kvm, hdr, parms.length, + &cmd->rc, &cmd->rrc); + + vfree(hdr); + break; + } + case KVM_PV_UNPACK: { + struct kvm_s390_pv_unp unp = {}; + + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = -EFAULT; + if (copy_from_user(&unp, argp, sizeof(unp))) + break; + + r = kvm_s390_pv_unpack(kvm, unp.addr, unp.size, unp.tweak, + &cmd->rc, &cmd->rrc); + break; + } + case KVM_PV_VERIFY: { + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm), + UVC_CMD_VERIFY_IMG, &cmd->rc, &cmd->rrc); + KVM_UV_EVENT(kvm, 3, "PROTVIRT VERIFY: rc %x rrc %x", cmd->rc, + cmd->rrc); + break; + } + case KVM_PV_PREP_RESET: { + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm), + UVC_CMD_PREPARE_RESET, &cmd->rc, &cmd->rrc); + KVM_UV_EVENT(kvm, 3, "PROTVIRT PREP RESET: rc %x rrc %x", + cmd->rc, cmd->rrc); + break; + } + case KVM_PV_UNSHARE_ALL: { + r = -EINVAL; + if (!kvm_s390_pv_is_protected(kvm)) + break; + + r = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm), + UVC_CMD_SET_UNSHARE_ALL, &cmd->rc, &cmd->rrc); + KVM_UV_EVENT(kvm, 3, "PROTVIRT UNSHARE: rc %x rrc %x", + cmd->rc, cmd->rrc); + break; + } + default: + r = -ENOTTY; + } + return r; +} + +static bool access_key_invalid(u8 access_key) +{ + return access_key > 0xf; +} + +static int kvm_s390_vm_mem_op(struct kvm *kvm, struct kvm_s390_mem_op *mop) +{ + void __user *uaddr = (void __user *)mop->buf; + u64 supported_flags; + void *tmpbuf = NULL; + int r, srcu_idx; + + supported_flags = KVM_S390_MEMOP_F_SKEY_PROTECTION + | KVM_S390_MEMOP_F_CHECK_ONLY; + if (mop->flags & ~supported_flags || !mop->size) + return -EINVAL; + if (mop->size > MEM_OP_MAX_SIZE) + return -E2BIG; + if (kvm_s390_pv_is_protected(kvm)) + return -EINVAL; + if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) { + if (access_key_invalid(mop->key)) + return -EINVAL; + } else { + mop->key = 0; + } + if (!(mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY)) { + tmpbuf = vmalloc(mop->size); + if (!tmpbuf) + return -ENOMEM; + } + + srcu_idx = srcu_read_lock(&kvm->srcu); + + if (kvm_is_error_gpa(kvm, mop->gaddr)) { + r = PGM_ADDRESSING; + goto out_unlock; + } + + switch (mop->op) { + case KVM_S390_MEMOP_ABSOLUTE_READ: { + if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { + r = check_gpa_range(kvm, mop->gaddr, mop->size, GACC_FETCH, mop->key); + } else { + r = access_guest_abs_with_key(kvm, mop->gaddr, tmpbuf, + mop->size, GACC_FETCH, mop->key); + if (r == 0) { + if (copy_to_user(uaddr, tmpbuf, mop->size)) + r = -EFAULT; + } + } + break; + } + case KVM_S390_MEMOP_ABSOLUTE_WRITE: { + if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { + r = check_gpa_range(kvm, mop->gaddr, mop->size, GACC_STORE, mop->key); + } else { + if (copy_from_user(tmpbuf, uaddr, mop->size)) { + r = -EFAULT; + break; + } + r = access_guest_abs_with_key(kvm, mop->gaddr, tmpbuf, + mop->size, GACC_STORE, mop->key); + } + break; + } + default: + r = -EINVAL; + } + +out_unlock: + srcu_read_unlock(&kvm->srcu, srcu_idx); + + vfree(tmpbuf); + return r; +} + long kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -2257,6 +2556,42 @@ mutex_unlock(&kvm->slots_lock); break; } + case KVM_S390_PV_COMMAND: { + struct kvm_pv_cmd args; + + /* protvirt means user cpu state */ + kvm_s390_set_user_cpu_state_ctrl(kvm); + r = 0; + if (!is_prot_virt_host()) { + r = -EINVAL; + break; + } + if (copy_from_user(&args, argp, sizeof(args))) { + r = -EFAULT; + break; + } + if (args.flags) { + r = -EINVAL; + break; + } + mutex_lock(&kvm->lock); + r = kvm_s390_handle_pv(kvm, &args); + mutex_unlock(&kvm->lock); + if (copy_to_user(argp, &args, sizeof(args))) { + r = -EFAULT; + break; + } + break; + } + case KVM_S390_MEM_OP: { + struct kvm_s390_mem_op mem_op; + + if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0) + r = kvm_s390_vm_mem_op(kvm, &mem_op); + else + r = -EFAULT; + break; + } default: r = -ENOTTY; } @@ -2520,6 +2855,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) { + u16 rc, rrc; + VCPU_EVENT(vcpu, 3, "%s", "free cpu"); trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id); kvm_s390_clear_local_irqs(vcpu); @@ -2532,6 +2869,9 @@ if (vcpu->kvm->arch.use_cmma) kvm_s390_vcpu_unsetup_cmma(vcpu); + /* We can not hold the vcpu mutex here, we are already dying */ + if (kvm_s390_pv_cpu_get_handle(vcpu)) + kvm_s390_pv_destroy_cpu(vcpu, &rc, &rrc); free_page((unsigned long)(vcpu->arch.sie_block)); kvm_vcpu_uninit(vcpu); @@ -2556,10 +2896,20 @@ void kvm_arch_destroy_vm(struct kvm *kvm) { + u16 rc, rrc; + kvm_free_vcpus(kvm); sca_dispose(kvm); - debug_unregister(kvm->arch.dbf); kvm_s390_gisa_destroy(kvm); + /* + * We are already at the end of life and kvm->lock is not taken. + * This is ok as the file descriptor is closed by now and nobody + * can mess with the pv state. To avoid lockdep_assert_held from + * complaining we do not use kvm_s390_pv_is_protected. + */ + if (kvm_s390_pv_get_handle(kvm)) + kvm_s390_pv_deinit_vm(kvm, &rc, &rrc); + debug_unregister(kvm->arch.dbf); free_page((unsigned long)kvm->arch.sie_page2); if (!kvm_is_ucontrol(kvm)) gmap_remove(kvm->arch.gmap); @@ -2655,6 +3005,9 @@ unsigned int vcpu_idx; u32 scaol, scaoh; + if (kvm->arch.use_esca) + return 0; + new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL|__GFP_ZERO); if (!new_sca) return -ENOMEM; @@ -2715,7 +3068,8 @@ KVM_SYNC_ACRS | KVM_SYNC_CRS | KVM_SYNC_ARCH0 | - KVM_SYNC_PFAULT; + KVM_SYNC_PFAULT | + KVM_SYNC_DIAG318; kvm_s390_set_prefix(vcpu, 0); if (test_kvm_facility(vcpu->kvm, 64)) vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB; @@ -2847,35 +3201,6 @@ } -static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) -{ - /* this equals initial cpu reset in pop, but we don't switch to ESA */ - vcpu->arch.sie_block->gpsw.mask = 0UL; - vcpu->arch.sie_block->gpsw.addr = 0UL; - kvm_s390_set_prefix(vcpu, 0); - kvm_s390_set_cpu_timer(vcpu, 0); - vcpu->arch.sie_block->ckc = 0UL; - vcpu->arch.sie_block->todpr = 0; - memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64)); - vcpu->arch.sie_block->gcr[0] = CR0_UNUSED_56 | - CR0_INTERRUPT_KEY_SUBMASK | - CR0_MEASUREMENT_ALERT_SUBMASK; - vcpu->arch.sie_block->gcr[14] = CR14_UNUSED_32 | - CR14_UNUSED_33 | - CR14_EXTERNAL_DAMAGE_SUBMASK; - /* make sure the new fpc will be lazily loaded */ - save_fpu_regs(); - current->thread.fpu.fpc = 0; - vcpu->arch.sie_block->gbea = 1; - vcpu->arch.sie_block->pp = 0; - vcpu->arch.sie_block->fpf &= ~FPF_BPBC; - vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; - kvm_clear_async_pf_completion_queue(vcpu); - if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) - kvm_s390_vcpu_stop(vcpu); - kvm_s390_clear_local_irqs(vcpu); -} - void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) { mutex_lock(&vcpu->kvm->lock); @@ -2968,6 +3293,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) { int rc = 0; + u16 uvrc, uvrrc; atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | CPUSTAT_SM | @@ -3035,6 +3361,14 @@ kvm_s390_vcpu_crypto_setup(vcpu); + mutex_lock(&vcpu->kvm->lock); + if (kvm_s390_pv_is_protected(vcpu->kvm)) { + rc = kvm_s390_pv_create_cpu(vcpu, &uvrc, &uvrrc); + if (rc) + kvm_s390_vcpu_unsetup_cmma(vcpu); + } + mutex_unlock(&vcpu->kvm->lock); + return rc; } @@ -3091,6 +3425,7 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) { + clear_bit(vcpu->vcpu_idx, vcpu->kvm->arch.gisa_int.kicked_mask); return kvm_s390_vcpu_has_irq(vcpu, 0); } @@ -3290,10 +3625,60 @@ return r; } -static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) +static void kvm_arch_vcpu_ioctl_normal_reset(struct kvm_vcpu *vcpu) { - kvm_s390_vcpu_initial_reset(vcpu); - return 0; + vcpu->arch.sie_block->gpsw.mask &= ~PSW_MASK_RI; + vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; + memset(vcpu->run->s.regs.riccb, 0, sizeof(vcpu->run->s.regs.riccb)); + + kvm_clear_async_pf_completion_queue(vcpu); + if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) + kvm_s390_vcpu_stop(vcpu); + kvm_s390_clear_local_irqs(vcpu); +} + +static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) +{ + /* Initial reset is a superset of the normal reset */ + kvm_arch_vcpu_ioctl_normal_reset(vcpu); + + /* this equals initial cpu reset in pop, but we don't switch to ESA */ + vcpu->arch.sie_block->gpsw.mask = 0; + vcpu->arch.sie_block->gpsw.addr = 0; + kvm_s390_set_prefix(vcpu, 0); + kvm_s390_set_cpu_timer(vcpu, 0); + vcpu->arch.sie_block->ckc = 0; + memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr)); + vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK; + vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK; + vcpu->run->s.regs.fpc = 0; + /* + * Do not reset these registers in the protected case, as some of + * them are overlayed and they are not accessible in this case + * anyway. + */ + if (!kvm_s390_pv_cpu_is_protected(vcpu)) { + vcpu->arch.sie_block->gbea = 1; + vcpu->arch.sie_block->pp = 0; + vcpu->arch.sie_block->fpf &= ~FPF_BPBC; + vcpu->arch.sie_block->todpr = 0; + } +} + +static void kvm_arch_vcpu_ioctl_clear_reset(struct kvm_vcpu *vcpu) +{ + struct kvm_sync_regs *regs = &vcpu->run->s.regs; + + /* Clear reset is a superset of the initial reset */ + kvm_arch_vcpu_ioctl_initial_reset(vcpu); + + memset(®s->gprs, 0, sizeof(regs->gprs)); + memset(®s->vrs, 0, sizeof(regs->vrs)); + memset(®s->acrs, 0, sizeof(regs->acrs)); + memset(®s->gscb, 0, sizeof(regs->gscb)); + + regs->etoken = 0; + regs->etoken_extension = 0; } int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) @@ -3342,10 +3727,6 @@ vcpu_load(vcpu); - if (test_fp_ctl(fpu->fpc)) { - ret = -EINVAL; - goto out; - } vcpu->run->s.regs.fpc = fpu->fpc; if (MACHINE_HAS_VX) convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, @@ -3353,7 +3734,6 @@ else memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); -out: vcpu_put(vcpu); return ret; } @@ -3463,16 +3843,22 @@ vcpu_load(vcpu); /* user space knows about this interface - let it control the state */ - vcpu->kvm->arch.user_cpu_state_ctrl = 1; + kvm_s390_set_user_cpu_state_ctrl(vcpu->kvm); switch (mp_state->mp_state) { case KVM_MP_STATE_STOPPED: - kvm_s390_vcpu_stop(vcpu); + rc = kvm_s390_vcpu_stop(vcpu); break; case KVM_MP_STATE_OPERATING: - kvm_s390_vcpu_start(vcpu); + rc = kvm_s390_vcpu_start(vcpu); break; case KVM_MP_STATE_LOAD: + if (!kvm_s390_pv_cpu_is_protected(vcpu)) { + rc = -ENXIO; + break; + } + rc = kvm_s390_pv_set_cpu_state(vcpu, PV_CPU_STATE_OPR_LOAD); + break; case KVM_MP_STATE_CHECK_STOP: /* fall through - CHECK_STOP and LOAD are not supported yet */ default: @@ -3568,14 +3954,12 @@ return 0; } -void kvm_s390_set_tod_clock(struct kvm *kvm, - const struct kvm_s390_vm_tod_clock *gtod) +static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) { struct kvm_vcpu *vcpu; struct kvm_s390_tod_clock_ext htod; int i; - mutex_lock(&kvm->lock); preempt_disable(); get_tod_clock_ext((char *)&htod); @@ -3596,7 +3980,15 @@ kvm_s390_vcpu_unblock_all(kvm); preempt_enable(); +} + +int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) +{ + if (!mutex_trylock(&kvm->lock)) + return 0; + __kvm_s390_set_tod_clock(kvm, gtod); mutex_unlock(&kvm->lock); + return 1; } /** @@ -3725,7 +4117,7 @@ kvm_s390_patch_guest_per_regs(vcpu); } - clear_bit(vcpu->vcpu_id, vcpu->kvm->arch.gisa_int.kicked_mask); + clear_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.gisa_int.kicked_mask); vcpu->arch.sie_block->icptcode = 0; cpuflags = atomic_read(&vcpu->arch.sie_block->cpuflags); @@ -3824,9 +4216,11 @@ return vcpu_post_run_fault_in_sie(vcpu); } +#define PSW_INT_MASK (PSW_MASK_EXT | PSW_MASK_IO | PSW_MASK_MCHECK) static int __vcpu_run(struct kvm_vcpu *vcpu) { int rc, exit_reason; + struct sie_page *sie_page = (struct sie_page *)vcpu->arch.sie_block; /* * We try to hold kvm->srcu during most of vcpu_run (except when run- @@ -3848,8 +4242,28 @@ guest_enter_irqoff(); __disable_cpu_timer_accounting(vcpu); local_irq_enable(); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + memcpy(sie_page->pv_grregs, + vcpu->run->s.regs.gprs, + sizeof(sie_page->pv_grregs)); + } exit_reason = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + memcpy(vcpu->run->s.regs.gprs, + sie_page->pv_grregs, + sizeof(sie_page->pv_grregs)); + /* + * We're not allowed to inject interrupts on intercepts + * that leave the guest state in an "in-between" state + * where the next SIE entry will do a continuation. + * Fence interrupts in our "internal" PSW. + */ + if (vcpu->arch.sie_block->icptcode == ICPT_PV_INSTR || + vcpu->arch.sie_block->icptcode == ICPT_PV_PREF) { + vcpu->arch.sie_block->gpsw.mask &= ~PSW_INT_MASK; + } + } local_irq_disable(); __enable_cpu_timer_accounting(vcpu); guest_exit_irqoff(); @@ -3863,7 +4277,7 @@ return rc; } -static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +static void sync_regs_fmt2(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { struct runtime_instr_cb *riccb; struct gs_cb *gscb; @@ -3872,16 +4286,7 @@ gscb = (struct gs_cb *) &kvm_run->s.regs.gscb; vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask; vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr; - if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) - kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix); - if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) { - memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128); - /* some control register changes require a tlb flush */ - kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); - } if (kvm_run->kvm_dirty_regs & KVM_SYNC_ARCH0) { - kvm_s390_set_cpu_timer(vcpu, kvm_run->s.regs.cputm); - vcpu->arch.sie_block->ckc = kvm_run->s.regs.ckc; vcpu->arch.sie_block->todpr = kvm_run->s.regs.todpr; vcpu->arch.sie_block->pp = kvm_run->s.regs.pp; vcpu->arch.sie_block->gbea = kvm_run->s.regs.gbea; @@ -3893,6 +4298,11 @@ if (vcpu->arch.pfault_token == KVM_S390_PFAULT_TOKEN_INVALID) kvm_clear_async_pf_completion_queue(vcpu); } + if (kvm_run->kvm_dirty_regs & KVM_SYNC_DIAG318) { + vcpu->arch.diag318_info.val = kvm_run->s.regs.diag318; + vcpu->arch.sie_block->cpnc = vcpu->arch.diag318_info.cpnc; + VCPU_EVENT(vcpu, 3, "setting cpnc to %d", vcpu->arch.diag318_info.cpnc); + } /* * If userspace sets the riccb (e.g. after migration) to a valid state, * we should enable RI here instead of doing the lazy enablement. @@ -3922,6 +4332,36 @@ vcpu->arch.sie_block->fpf &= ~FPF_BPBC; vcpu->arch.sie_block->fpf |= kvm_run->s.regs.bpbc ? FPF_BPBC : 0; } + if (MACHINE_HAS_GS) { + preempt_disable(); + __ctl_set_bit(2, 4); + if (current->thread.gs_cb) { + vcpu->arch.host_gscb = current->thread.gs_cb; + save_gs_cb(vcpu->arch.host_gscb); + } + if (vcpu->arch.gs_enabled) { + current->thread.gs_cb = (struct gs_cb *) + &vcpu->run->s.regs.gscb; + restore_gs_cb(current->thread.gs_cb); + } + preempt_enable(); + } + /* SIE will load etoken directly from SDNX and therefore kvm_run */ +} + +static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + if (kvm_run->kvm_dirty_regs & KVM_SYNC_PREFIX) + kvm_s390_set_prefix(vcpu, kvm_run->s.regs.prefix); + if (kvm_run->kvm_dirty_regs & KVM_SYNC_CRS) { + memcpy(&vcpu->arch.sie_block->gcr, &kvm_run->s.regs.crs, 128); + /* some control register changes require a tlb flush */ + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); + } + if (kvm_run->kvm_dirty_regs & KVM_SYNC_ARCH0) { + kvm_s390_set_cpu_timer(vcpu, kvm_run->s.regs.cputm); + vcpu->arch.sie_block->ckc = kvm_run->s.regs.ckc; + } save_access_regs(vcpu->arch.host_acrs); restore_access_regs(vcpu->run->s.regs.acrs); /* save host (userspace) fprs/vrs */ @@ -3936,23 +4376,48 @@ if (test_fp_ctl(current->thread.fpu.fpc)) /* User space provided an invalid FPC, let's clear it */ current->thread.fpu.fpc = 0; + + /* Sync fmt2 only data */ + if (likely(!kvm_s390_pv_cpu_is_protected(vcpu))) { + sync_regs_fmt2(vcpu, kvm_run); + } else { + /* + * In several places we have to modify our internal view to + * not do things that are disallowed by the ultravisor. For + * example we must not inject interrupts after specific exits + * (e.g. 112 prefix page not secure). We do this by turning + * off the machine check, external and I/O interrupt bits + * of our PSW copy. To avoid getting validity intercepts, we + * do only accept the condition code from userspace. + */ + vcpu->arch.sie_block->gpsw.mask &= ~PSW_MASK_CC; + vcpu->arch.sie_block->gpsw.mask |= kvm_run->psw_mask & + PSW_MASK_CC; + } + + kvm_run->kvm_dirty_regs = 0; +} + +static void store_regs_fmt2(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + kvm_run->s.regs.todpr = vcpu->arch.sie_block->todpr; + kvm_run->s.regs.pp = vcpu->arch.sie_block->pp; + kvm_run->s.regs.gbea = vcpu->arch.sie_block->gbea; + kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == FPF_BPBC; + kvm_run->s.regs.diag318 = vcpu->arch.diag318_info.val; if (MACHINE_HAS_GS) { preempt_disable(); __ctl_set_bit(2, 4); - if (current->thread.gs_cb) { - vcpu->arch.host_gscb = current->thread.gs_cb; - save_gs_cb(vcpu->arch.host_gscb); - } - if (vcpu->arch.gs_enabled) { - current->thread.gs_cb = (struct gs_cb *) - &vcpu->run->s.regs.gscb; - restore_gs_cb(current->thread.gs_cb); - } + if (vcpu->arch.gs_enabled) + save_gs_cb(current->thread.gs_cb); + current->thread.gs_cb = vcpu->arch.host_gscb; + restore_gs_cb(vcpu->arch.host_gscb); + if (!vcpu->arch.host_gscb) + __ctl_clear_bit(2, 4); + vcpu->arch.host_gscb = NULL; preempt_enable(); } - /* SIE will load etoken directly from SDNX and therefore kvm_run */ - - kvm_run->kvm_dirty_regs = 0; + /* SIE will save etoken directly into SDNX and therefore kvm_run */ } static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -3963,13 +4428,9 @@ memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128); kvm_run->s.regs.cputm = kvm_s390_get_cpu_timer(vcpu); kvm_run->s.regs.ckc = vcpu->arch.sie_block->ckc; - kvm_run->s.regs.todpr = vcpu->arch.sie_block->todpr; - kvm_run->s.regs.pp = vcpu->arch.sie_block->pp; - kvm_run->s.regs.gbea = vcpu->arch.sie_block->gbea; kvm_run->s.regs.pft = vcpu->arch.pfault_token; kvm_run->s.regs.pfs = vcpu->arch.pfault_select; kvm_run->s.regs.pfc = vcpu->arch.pfault_compare; - kvm_run->s.regs.bpbc = (vcpu->arch.sie_block->fpf & FPF_BPBC) == FPF_BPBC; save_access_regs(vcpu->run->s.regs.acrs); restore_access_regs(vcpu->arch.host_acrs); /* Save guest register state */ @@ -3978,19 +4439,8 @@ /* Restore will be done lazily at return */ current->thread.fpu.fpc = vcpu->arch.host_fpregs.fpc; current->thread.fpu.regs = vcpu->arch.host_fpregs.regs; - if (MACHINE_HAS_GS) { - __ctl_set_bit(2, 4); - if (vcpu->arch.gs_enabled) - save_gs_cb(current->thread.gs_cb); - preempt_disable(); - current->thread.gs_cb = vcpu->arch.host_gscb; - restore_gs_cb(vcpu->arch.host_gscb); - preempt_enable(); - if (!vcpu->arch.host_gscb) - __ctl_clear_bit(2, 4); - vcpu->arch.host_gscb = NULL; - } - /* SIE will save etoken directly into SDNX and therefore kvm_run */ + if (likely(!kvm_s390_pv_cpu_is_protected(vcpu))) + store_regs_fmt2(vcpu, kvm_run); } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -4014,6 +4464,10 @@ kvm_sigset_activate(vcpu); + /* + * no need to check the return value of vcpu_start as it can only have + * an error for protvirt, but protvirt means user cpu state + */ if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) { kvm_s390_vcpu_start(vcpu); } else if (is_vcpu_stopped(vcpu)) { @@ -4151,18 +4605,27 @@ kvm_s390_sync_request(KVM_REQ_ENABLE_IBS, vcpu); } -void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu) +int kvm_s390_vcpu_start(struct kvm_vcpu *vcpu) { - int i, online_vcpus, started_vcpus = 0; + int i, online_vcpus, r = 0, started_vcpus = 0; if (!is_vcpu_stopped(vcpu)) - return; + return 0; trace_kvm_s390_vcpu_start_stop(vcpu->vcpu_id, 1); /* Only one cpu at a time may enter/leave the STOPPED state. */ spin_lock(&vcpu->kvm->arch.start_stop_lock); online_vcpus = atomic_read(&vcpu->kvm->online_vcpus); + /* Let's tell the UV that we want to change into the operating state */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + r = kvm_s390_pv_set_cpu_state(vcpu, PV_CPU_STATE_OPR); + if (r) { + spin_unlock(&vcpu->kvm->arch.start_stop_lock); + return r; + } + } + for (i = 0; i < online_vcpus; i++) { if (!is_vcpu_stopped(vcpu->kvm->vcpus[i])) started_vcpus++; @@ -4182,31 +4645,52 @@ kvm_s390_clear_cpuflags(vcpu, CPUSTAT_STOPPED); /* + * The real PSW might have changed due to a RESTART interpreted by the + * ultravisor. We block all interrupts and let the next sie exit + * refresh our view. + */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) + vcpu->arch.sie_block->gpsw.mask &= ~PSW_INT_MASK; + /* * Another VCPU might have used IBS while we were offline. * Let's play safe and flush the VCPU at startup. */ kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); spin_unlock(&vcpu->kvm->arch.start_stop_lock); - return; + return 0; } -void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu) +int kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu) { - int i, online_vcpus, started_vcpus = 0; + int i, online_vcpus, r = 0, started_vcpus = 0; struct kvm_vcpu *started_vcpu = NULL; if (is_vcpu_stopped(vcpu)) - return; + return 0; trace_kvm_s390_vcpu_start_stop(vcpu->vcpu_id, 0); /* Only one cpu at a time may enter/leave the STOPPED state. */ spin_lock(&vcpu->kvm->arch.start_stop_lock); online_vcpus = atomic_read(&vcpu->kvm->online_vcpus); - /* SIGP STOP and SIGP STOP AND STORE STATUS has been fully processed */ - kvm_s390_clear_stop_irq(vcpu); + /* Let's tell the UV that we want to change into the stopped state */ + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + r = kvm_s390_pv_set_cpu_state(vcpu, PV_CPU_STATE_STP); + if (r) { + spin_unlock(&vcpu->kvm->arch.start_stop_lock); + return r; + } + } + /* + * Set the VCPU to STOPPED and THEN clear the interrupt flag, + * now that the SIGP STOP and SIGP STOP AND STORE STATUS orders + * have been fully processed. This will ensure that the VCPU + * is kept BUSY if another VCPU is inquiring with SIGP SENSE. + */ kvm_s390_set_cpuflags(vcpu, CPUSTAT_STOPPED); + kvm_s390_clear_stop_irq(vcpu); + __disable_ibs_on_vcpu(vcpu); for (i = 0; i < online_vcpus; i++) { @@ -4225,7 +4709,7 @@ } spin_unlock(&vcpu->kvm->arch.start_stop_lock); - return; + return 0; } static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, @@ -4252,37 +4736,74 @@ return r; } -static long kvm_s390_guest_mem_op(struct kvm_vcpu *vcpu, +static long kvm_s390_vcpu_sida_op(struct kvm_vcpu *vcpu, struct kvm_s390_mem_op *mop) { void __user *uaddr = (void __user *)mop->buf; + int r = 0; + + if (mop->flags || !mop->size) + return -EINVAL; + if (mop->size + mop->sida_offset < mop->size) + return -EINVAL; + if (mop->size + mop->sida_offset > sida_size(vcpu->arch.sie_block)) + return -E2BIG; + if (!kvm_s390_pv_cpu_is_protected(vcpu)) + return -EINVAL; + + switch (mop->op) { + case KVM_S390_MEMOP_SIDA_READ: + if (copy_to_user(uaddr, (void *)(sida_origin(vcpu->arch.sie_block) + + mop->sida_offset), mop->size)) + r = -EFAULT; + + break; + case KVM_S390_MEMOP_SIDA_WRITE: + if (copy_from_user((void *)(sida_origin(vcpu->arch.sie_block) + + mop->sida_offset), uaddr, mop->size)) + r = -EFAULT; + break; + } + return r; +} + +static long kvm_s390_vcpu_mem_op(struct kvm_vcpu *vcpu, + struct kvm_s390_mem_op *mop) +{ + void __user *uaddr = (void __user *)mop->buf; void *tmpbuf = NULL; - int r, srcu_idx; + int r = 0; const u64 supported_flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION - | KVM_S390_MEMOP_F_CHECK_ONLY; + | KVM_S390_MEMOP_F_CHECK_ONLY + | KVM_S390_MEMOP_F_SKEY_PROTECTION; if (mop->flags & ~supported_flags || mop->ar >= NUM_ACRS || !mop->size) return -EINVAL; - if (mop->size > MEM_OP_MAX_SIZE) return -E2BIG; - + if (kvm_s390_pv_cpu_is_protected(vcpu)) + return -EINVAL; + if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) { + if (access_key_invalid(mop->key)) + return -EINVAL; + } else { + mop->key = 0; + } if (!(mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY)) { tmpbuf = vmalloc(mop->size); if (!tmpbuf) return -ENOMEM; } - srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - switch (mop->op) { case KVM_S390_MEMOP_LOGICAL_READ: if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { - r = check_gva_range(vcpu, mop->gaddr, mop->ar, - mop->size, GACC_FETCH); + r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, + GACC_FETCH, mop->key); break; } - r = read_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); + r = read_guest_with_key(vcpu, mop->gaddr, mop->ar, tmpbuf, + mop->size, mop->key); if (r == 0) { if (copy_to_user(uaddr, tmpbuf, mop->size)) r = -EFAULT; @@ -4290,22 +4811,19 @@ break; case KVM_S390_MEMOP_LOGICAL_WRITE: if (mop->flags & KVM_S390_MEMOP_F_CHECK_ONLY) { - r = check_gva_range(vcpu, mop->gaddr, mop->ar, - mop->size, GACC_STORE); + r = check_gva_range(vcpu, mop->gaddr, mop->ar, mop->size, + GACC_STORE, mop->key); break; } if (copy_from_user(tmpbuf, uaddr, mop->size)) { r = -EFAULT; break; } - r = write_guest(vcpu, mop->gaddr, mop->ar, tmpbuf, mop->size); + r = write_guest_with_key(vcpu, mop->gaddr, mop->ar, tmpbuf, + mop->size, mop->key); break; - default: - r = -EINVAL; } - srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); - if (r > 0 && (mop->flags & KVM_S390_MEMOP_F_INJECT_EXCEPTION) != 0) kvm_s390_inject_prog_irq(vcpu, &vcpu->arch.pgm); @@ -4313,6 +4831,31 @@ return r; } +static long kvm_s390_vcpu_memsida_op(struct kvm_vcpu *vcpu, + struct kvm_s390_mem_op *mop) +{ + int r, srcu_idx; + + srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); + + switch (mop->op) { + case KVM_S390_MEMOP_LOGICAL_READ: + case KVM_S390_MEMOP_LOGICAL_WRITE: + r = kvm_s390_vcpu_mem_op(vcpu, mop); + break; + case KVM_S390_MEMOP_SIDA_READ: + case KVM_S390_MEMOP_SIDA_WRITE: + /* we are locked against sida going away by the vcpu->mutex */ + r = kvm_s390_vcpu_sida_op(vcpu, mop); + break; + default: + r = -EINVAL; + } + + srcu_read_unlock(&vcpu->kvm->srcu, srcu_idx); + return r; +} + long kvm_arch_vcpu_async_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -4348,13 +4891,14 @@ void __user *argp = (void __user *)arg; int idx; long r; + u16 rc, rrc; vcpu_load(vcpu); switch (ioctl) { case KVM_S390_STORE_STATUS: idx = srcu_read_lock(&vcpu->kvm->srcu); - r = kvm_s390_vcpu_store_status(vcpu, arg); + r = kvm_s390_store_status_unloaded(vcpu, arg); srcu_read_unlock(&vcpu->kvm->srcu, idx); break; case KVM_S390_SET_INITIAL_PSW: { @@ -4366,12 +4910,43 @@ r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw); break; } + case KVM_S390_CLEAR_RESET: + r = 0; + kvm_arch_vcpu_ioctl_clear_reset(vcpu); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + r = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), + UVC_CMD_CPU_RESET_CLEAR, &rc, &rrc); + VCPU_EVENT(vcpu, 3, "PROTVIRT RESET CLEAR VCPU: rc %x rrc %x", + rc, rrc); + } + break; case KVM_S390_INITIAL_RESET: - r = kvm_arch_vcpu_ioctl_initial_reset(vcpu); + r = 0; + kvm_arch_vcpu_ioctl_initial_reset(vcpu); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + r = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), + UVC_CMD_CPU_RESET_INITIAL, + &rc, &rrc); + VCPU_EVENT(vcpu, 3, "PROTVIRT RESET INITIAL VCPU: rc %x rrc %x", + rc, rrc); + } + break; + case KVM_S390_NORMAL_RESET: + r = 0; + kvm_arch_vcpu_ioctl_normal_reset(vcpu); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + r = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), + UVC_CMD_CPU_RESET, &rc, &rrc); + VCPU_EVENT(vcpu, 3, "PROTVIRT RESET NORMAL VCPU: rc %x rrc %x", + rc, rrc); + } break; case KVM_SET_ONE_REG: case KVM_GET_ONE_REG: { struct kvm_one_reg reg; + r = -EINVAL; + if (kvm_s390_pv_cpu_is_protected(vcpu)) + break; r = -EFAULT; if (copy_from_user(®, argp, sizeof(reg))) break; @@ -4434,7 +5009,7 @@ struct kvm_s390_mem_op mem_op; if (copy_from_user(&mem_op, argp, sizeof(mem_op)) == 0) - r = kvm_s390_guest_mem_op(vcpu, &mem_op); + r = kvm_s390_vcpu_memsida_op(vcpu, &mem_op); else r = -EFAULT; break; @@ -4520,6 +5095,26 @@ if (mem->guest_phys_addr + mem->memory_size > kvm->arch.mem_limit) return -EINVAL; + /* When we are protected, we should not change the memory slots */ + if (kvm_s390_pv_get_handle(kvm)) + return -EINVAL; + + if (!kvm->arch.migration_mode) + return 0; + + /* + * Turn off migration mode when: + * - userspace creates a new memslot with dirty logging off, + * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and + * dirty logging is turned off. + * Migration mode expects dirty page logging being enabled to store + * its dirty bitmap. + */ + if (change != KVM_MR_DELETE && + !(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) + WARN(kvm_s390_vm_stop_migration(kvm), + "Failed to stop migration mode"); + return 0; } --- linux-oracle-5.4.0.orig/arch/s390/kvm/kvm-s390.h +++ linux-oracle-5.4.0/arch/s390/kvm/kvm-s390.h @@ -2,7 +2,7 @@ /* * definition for kvm on s390 * - * Copyright IBM Corp. 2008, 2009 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte * Christian Borntraeger @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,17 @@ #define IS_ITDB_VALID(vcpu) ((*(char *)vcpu->arch.sie_block->itdba == TDB_FORMAT1)) extern debug_info_t *kvm_s390_dbf; +extern debug_info_t *kvm_s390_dbf_uv; + +#define KVM_UV_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ +do { \ + debug_sprintf_event((d_kvm)->arch.dbf, d_loglevel, d_string "\n", \ + d_args); \ + debug_sprintf_event(kvm_s390_dbf_uv, d_loglevel, \ + "%d: " d_string "\n", (d_kvm)->userspace_pid, \ + d_args); \ +} while (0) + #define KVM_EVENT(d_loglevel, d_string, d_args...)\ do { \ debug_sprintf_event(kvm_s390_dbf, d_loglevel, d_string "\n", \ @@ -67,7 +79,7 @@ static inline int is_vcpu_idle(struct kvm_vcpu *vcpu) { - return test_bit(vcpu->vcpu_id, vcpu->kvm->arch.idle_mask); + return test_bit(kvm_vcpu_get_idx(vcpu), vcpu->kvm->arch.idle_mask); } static inline int kvm_is_ucontrol(struct kvm *kvm) @@ -196,6 +208,48 @@ return kvm->arch.user_cpu_state_ctrl != 0; } +static inline void kvm_s390_set_user_cpu_state_ctrl(struct kvm *kvm) +{ + if (kvm->arch.user_cpu_state_ctrl) + return; + + VM_EVENT(kvm, 3, "%s", "ENABLE: Userspace CPU state control"); + kvm->arch.user_cpu_state_ctrl = 1; +} + +/* implemented in pv.c */ +int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc); +int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc); +int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc); +int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc); +int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length, u16 *rc, + u16 *rrc); +int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size, + unsigned long tweak, u16 *rc, u16 *rrc); +int kvm_s390_pv_set_cpu_state(struct kvm_vcpu *vcpu, u8 state); + +static inline u64 kvm_s390_pv_get_handle(struct kvm *kvm) +{ + return kvm->arch.pv.handle; +} + +static inline u64 kvm_s390_pv_cpu_get_handle(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.pv.handle; +} + +static inline bool kvm_s390_pv_is_protected(struct kvm *kvm) +{ + lockdep_assert_held(&kvm->lock); + return !!kvm_s390_pv_get_handle(kvm); +} + +static inline bool kvm_s390_pv_cpu_is_protected(struct kvm_vcpu *vcpu) +{ + lockdep_assert_held(&vcpu->mutex); + return !!kvm_s390_pv_cpu_get_handle(vcpu); +} + /* implemented in interrupt.c */ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu); @@ -281,13 +335,12 @@ int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); /* implemented in kvm-s390.c */ -void kvm_s390_set_tod_clock(struct kvm *kvm, - const struct kvm_s390_vm_tod_clock *gtod); +int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); -void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); -void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); +int kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); +int kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu); void kvm_s390_vcpu_unblock(struct kvm_vcpu *vcpu); bool kvm_s390_vcpu_sie_inhibited(struct kvm_vcpu *vcpu); @@ -373,6 +426,7 @@ int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu); extern struct kvm_device_ops kvm_flic_ops; int kvm_s390_is_stop_irq_pending(struct kvm_vcpu *vcpu); +int kvm_s390_is_restart_irq_pending(struct kvm_vcpu *vcpu); void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu); int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *buf, int len); --- linux-oracle-5.4.0.orig/arch/s390/kvm/priv.c +++ linux-oracle-5.4.0/arch/s390/kvm/priv.c @@ -2,7 +2,7 @@ /* * handling privileged instructions * - * Copyright IBM Corp. 2008, 2018 + * Copyright IBM Corp. 2008, 2020 * * Author(s): Carsten Otte * Christian Borntraeger @@ -103,7 +103,20 @@ return kvm_s390_inject_prog_cond(vcpu, rc); VCPU_EVENT(vcpu, 3, "SCK: setting guest TOD to 0x%llx", gtod.tod); - kvm_s390_set_tod_clock(vcpu->kvm, >od); + /* + * To set the TOD clock the kvm lock must be taken, but the vcpu lock + * is already held in handle_set_clock. The usual lock order is the + * opposite. As SCK is deprecated and should not be used in several + * cases, for example when the multiple epoch facility or TOD clock + * steering facility is installed (see Principles of Operation), a + * slow path can be used. If the lock can not be taken via try_lock, + * the instruction will be retried via -EAGAIN at a later point in + * time. + */ + if (!kvm_s390_try_set_tod_clock(vcpu->kvm, >od)) { + kvm_s390_retry_instr(vcpu); + return -EAGAIN; + } kvm_s390_set_psw_cc(vcpu, 0); return 0; @@ -398,6 +411,8 @@ up_read(¤t->mm->mmap_sem); if (rc == -EFAULT) return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); + if (rc == -EAGAIN) + continue; if (rc < 0) return rc; start += PAGE_SIZE; @@ -626,10 +641,12 @@ * available for the guest are AQIC and TAPQ with the t bit set * since we do not set IC.3 (FIII) we currently will only intercept * the AQIC function code. + * Note: running nested under z/VM can result in intercepts for other + * function codes, e.g. PQAP(QCI). We do not support this and bail out. */ reg0 = vcpu->run->s.regs.gprs[0]; fc = (reg0 >> 24) & 0xff; - if (WARN_ON_ONCE(fc != 0x03)) + if (fc != 0x03) return -EOPNOTSUPP; /* PQAP instruction is allowed for guest kernel only */ @@ -872,7 +889,7 @@ operand2 = kvm_s390_get_base_disp_s(vcpu, &ar); - if (operand2 & 0xfff) + if (!kvm_s390_pv_cpu_is_protected(vcpu) && (operand2 & 0xfff)) return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); switch (fc) { @@ -893,8 +910,13 @@ handle_stsi_3_2_2(vcpu, (void *) mem); break; } - - rc = write_guest(vcpu, operand2, ar, (void *)mem, PAGE_SIZE); + if (kvm_s390_pv_cpu_is_protected(vcpu)) { + memcpy((void *)sida_origin(vcpu->arch.sie_block), (void *)mem, + PAGE_SIZE); + rc = 0; + } else { + rc = write_guest(vcpu, operand2, ar, (void *)mem, PAGE_SIZE); + } if (rc) { rc = kvm_s390_inject_prog_cond(vcpu, rc); goto out; @@ -1432,10 +1454,11 @@ static int handle_tprot(struct kvm_vcpu *vcpu) { - u64 address1, address2; - unsigned long hva, gpa; - int ret = 0, cc = 0; + u64 address, operand2; + unsigned long gpa; + u8 access_key; bool writable; + int ret, cc; u8 ar; vcpu->stat.instruction_tprot++; @@ -1443,43 +1466,46 @@ if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); - kvm_s390_get_base_disp_sse(vcpu, &address1, &address2, &ar, NULL); + kvm_s390_get_base_disp_sse(vcpu, &address, &operand2, &ar, NULL); + access_key = (operand2 & 0xf0) >> 4; - /* we only handle the Linux memory detection case: - * access key == 0 - * everything else goes to userspace. */ - if (address2 & 0xf0) - return -EOPNOTSUPP; if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) ipte_lock(vcpu); - ret = guest_translate_address(vcpu, address1, ar, &gpa, GACC_STORE); - if (ret == PGM_PROTECTION) { + + ret = guest_translate_address_with_key(vcpu, address, ar, &gpa, + GACC_STORE, access_key); + if (ret == 0) { + gfn_to_hva_prot(vcpu->kvm, gpa_to_gfn(gpa), &writable); + } else if (ret == PGM_PROTECTION) { + writable = false; /* Write protected? Try again with read-only... */ - cc = 1; - ret = guest_translate_address(vcpu, address1, ar, &gpa, - GACC_FETCH); + ret = guest_translate_address_with_key(vcpu, address, ar, &gpa, + GACC_FETCH, access_key); } - if (ret) { - if (ret == PGM_ADDRESSING || ret == PGM_TRANSLATION_SPEC) { - ret = kvm_s390_inject_program_int(vcpu, ret); - } else if (ret > 0) { - /* Translation not available */ - kvm_s390_set_psw_cc(vcpu, 3); + if (ret >= 0) { + cc = -1; + + /* Fetching permitted; storing permitted */ + if (ret == 0 && writable) + cc = 0; + /* Fetching permitted; storing not permitted */ + else if (ret == 0 && !writable) + cc = 1; + /* Fetching not permitted; storing not permitted */ + else if (ret == PGM_PROTECTION) + cc = 2; + /* Translation not available */ + else if (ret != PGM_ADDRESSING && ret != PGM_TRANSLATION_SPEC) + cc = 3; + + if (cc != -1) { + kvm_s390_set_psw_cc(vcpu, cc); ret = 0; + } else { + ret = kvm_s390_inject_program_int(vcpu, ret); } - goto out_unlock; } - hva = gfn_to_hva_prot(vcpu->kvm, gpa_to_gfn(gpa), &writable); - if (kvm_is_error_hva(hva)) { - ret = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); - } else { - if (!writable) - cc = 1; /* Write not permitted ==> read-only */ - kvm_s390_set_psw_cc(vcpu, cc); - /* Note: CC2 only occurs for storage keys (not supported yet) */ - } -out_unlock: if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) ipte_unlock(vcpu); return ret; --- linux-oracle-5.4.0.orig/arch/s390/kvm/pv.c +++ linux-oracle-5.4.0/arch/s390/kvm/pv.c @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Hosting Protected Virtual Machines + * + * Copyright IBM Corp. 2019, 2020 + * Author(s): Janosch Frank + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "kvm-s390.h" + +int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) +{ + int cc = 0; + + if (kvm_s390_pv_cpu_get_handle(vcpu)) { + cc = uv_cmd_nodata(kvm_s390_pv_cpu_get_handle(vcpu), + UVC_CMD_DESTROY_SEC_CPU, rc, rrc); + + KVM_UV_EVENT(vcpu->kvm, 3, + "PROTVIRT DESTROY VCPU %d: rc %x rrc %x", + vcpu->vcpu_id, *rc, *rrc); + WARN_ONCE(cc, "protvirt destroy cpu failed rc %x rrc %x", + *rc, *rrc); + } + /* Intended memory leak for something that should never happen. */ + if (!cc) + free_pages(vcpu->arch.pv.stor_base, + get_order(uv_info.guest_cpu_stor_len)); + + free_page(sida_origin(vcpu->arch.sie_block)); + vcpu->arch.sie_block->pv_handle_cpu = 0; + vcpu->arch.sie_block->pv_handle_config = 0; + memset(&vcpu->arch.pv, 0, sizeof(vcpu->arch.pv)); + vcpu->arch.sie_block->sdf = 0; + /* + * The sidad field (for sdf == 2) is now the gbea field (for sdf == 0). + * Use the reset value of gbea to avoid leaking the kernel pointer of + * the just freed sida. + */ + vcpu->arch.sie_block->gbea = 1; + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); + + return cc ? EIO : 0; +} + +int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, u16 *rc, u16 *rrc) +{ + struct uv_cb_csc uvcb = { + .header.cmd = UVC_CMD_CREATE_SEC_CPU, + .header.len = sizeof(uvcb), + }; + int cc; + + if (kvm_s390_pv_cpu_get_handle(vcpu)) + return -EINVAL; + + vcpu->arch.pv.stor_base = __get_free_pages(GFP_KERNEL, + get_order(uv_info.guest_cpu_stor_len)); + if (!vcpu->arch.pv.stor_base) + return -ENOMEM; + + /* Input */ + uvcb.guest_handle = kvm_s390_pv_get_handle(vcpu->kvm); + uvcb.num = vcpu->arch.sie_block->icpua; + uvcb.state_origin = (u64)vcpu->arch.sie_block; + uvcb.stor_origin = (u64)vcpu->arch.pv.stor_base; + + /* Alloc Secure Instruction Data Area Designation */ + vcpu->arch.sie_block->sidad = __get_free_page(GFP_KERNEL | __GFP_ZERO); + if (!vcpu->arch.sie_block->sidad) { + free_pages(vcpu->arch.pv.stor_base, + get_order(uv_info.guest_cpu_stor_len)); + return -ENOMEM; + } + + cc = uv_call(0, (u64)&uvcb); + *rc = uvcb.header.rc; + *rrc = uvcb.header.rrc; + KVM_UV_EVENT(vcpu->kvm, 3, + "PROTVIRT CREATE VCPU: cpu %d handle %llx rc %x rrc %x", + vcpu->vcpu_id, uvcb.cpu_handle, uvcb.header.rc, + uvcb.header.rrc); + + if (cc) { + u16 dummy; + + kvm_s390_pv_destroy_cpu(vcpu, &dummy, &dummy); + return -EIO; + } + + /* Output */ + vcpu->arch.pv.handle = uvcb.cpu_handle; + vcpu->arch.sie_block->pv_handle_cpu = uvcb.cpu_handle; + vcpu->arch.sie_block->pv_handle_config = kvm_s390_pv_get_handle(vcpu->kvm); + vcpu->arch.sie_block->sdf = 2; + kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); + return 0; +} + +/* only free resources when the destroy was successful */ +static void kvm_s390_pv_dealloc_vm(struct kvm *kvm) +{ + vfree(kvm->arch.pv.stor_var); + free_pages(kvm->arch.pv.stor_base, + get_order(uv_info.guest_base_stor_len)); + memset(&kvm->arch.pv, 0, sizeof(kvm->arch.pv)); +} + +static int kvm_s390_pv_alloc_vm(struct kvm *kvm) +{ + unsigned long base = uv_info.guest_base_stor_len; + unsigned long virt = uv_info.guest_virt_var_stor_len; + unsigned long npages = 0, vlen = 0; + struct kvm_memory_slot *memslot; + + kvm->arch.pv.stor_var = NULL; + kvm->arch.pv.stor_base = __get_free_pages(GFP_KERNEL, get_order(base)); + if (!kvm->arch.pv.stor_base) + return -ENOMEM; + + /* + * Calculate current guest storage for allocation of the + * variable storage, which is based on the length in MB. + * + * Slots are sorted by GFN + */ + mutex_lock(&kvm->slots_lock); + memslot = kvm_memslots(kvm)->memslots; + npages = memslot->base_gfn + memslot->npages; + mutex_unlock(&kvm->slots_lock); + + kvm->arch.pv.guest_len = npages * PAGE_SIZE; + + /* Allocate variable storage */ + vlen = ALIGN(virt * ((npages * PAGE_SIZE) / HPAGE_SIZE), PAGE_SIZE); + vlen += uv_info.guest_virt_base_stor_len; + kvm->arch.pv.stor_var = vzalloc(vlen); + if (!kvm->arch.pv.stor_var) + goto out_err; + return 0; + +out_err: + kvm_s390_pv_dealloc_vm(kvm); + return -ENOMEM; +} + +/* this should not fail, but if it does, we must not free the donated memory */ +int kvm_s390_pv_deinit_vm(struct kvm *kvm, u16 *rc, u16 *rrc) +{ + int cc; + + /* make all pages accessible before destroying the guest */ + s390_reset_acc(kvm->mm); + + cc = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm), + UVC_CMD_DESTROY_SEC_CONF, rc, rrc); + WRITE_ONCE(kvm->arch.gmap->guest_handle, 0); + atomic_set(&kvm->mm->context.is_protected, 0); + KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY VM: rc %x rrc %x", *rc, *rrc); + WARN_ONCE(cc, "protvirt destroy vm failed rc %x rrc %x", *rc, *rrc); + /* Inteded memory leak on "impossible" error */ + if (!cc) + kvm_s390_pv_dealloc_vm(kvm); + return cc ? -EIO : 0; +} + +int kvm_s390_pv_init_vm(struct kvm *kvm, u16 *rc, u16 *rrc) +{ + struct uv_cb_cgc uvcb = { + .header.cmd = UVC_CMD_CREATE_SEC_CONF, + .header.len = sizeof(uvcb) + }; + int cc, ret; + u16 dummy; + + ret = kvm_s390_pv_alloc_vm(kvm); + if (ret) + return ret; + + /* Inputs */ + uvcb.guest_stor_origin = 0; /* MSO is 0 for KVM */ + uvcb.guest_stor_len = kvm->arch.pv.guest_len; + uvcb.guest_asce = kvm->arch.gmap->asce; + uvcb.guest_sca = (unsigned long)kvm->arch.sca; + uvcb.conf_base_stor_origin = (u64)kvm->arch.pv.stor_base; + uvcb.conf_virt_stor_origin = (u64)kvm->arch.pv.stor_var; + + cc = uv_call_sched(0, (u64)&uvcb); + *rc = uvcb.header.rc; + *rrc = uvcb.header.rrc; + KVM_UV_EVENT(kvm, 3, "PROTVIRT CREATE VM: handle %llx len %llx rc %x rrc %x", + uvcb.guest_handle, uvcb.guest_stor_len, *rc, *rrc); + + /* Outputs */ + kvm->arch.pv.handle = uvcb.guest_handle; + + if (cc) { + if (uvcb.header.rc & UVC_RC_NEED_DESTROY) + kvm_s390_pv_deinit_vm(kvm, &dummy, &dummy); + else + kvm_s390_pv_dealloc_vm(kvm); + return -EIO; + } + kvm->arch.gmap->guest_handle = uvcb.guest_handle; + atomic_set(&kvm->mm->context.is_protected, 1); + return 0; +} + +int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length, u16 *rc, + u16 *rrc) +{ + struct uv_cb_ssc uvcb = { + .header.cmd = UVC_CMD_SET_SEC_CONF_PARAMS, + .header.len = sizeof(uvcb), + .sec_header_origin = (u64)hdr, + .sec_header_len = length, + .guest_handle = kvm_s390_pv_get_handle(kvm), + }; + int cc = uv_call(0, (u64)&uvcb); + + *rc = uvcb.header.rc; + *rrc = uvcb.header.rrc; + KVM_UV_EVENT(kvm, 3, "PROTVIRT VM SET PARMS: rc %x rrc %x", + *rc, *rrc); + return cc ? -EINVAL : 0; +} + +static int unpack_one(struct kvm *kvm, unsigned long addr, u64 tweak, + u64 offset, u16 *rc, u16 *rrc) +{ + struct uv_cb_unp uvcb = { + .header.cmd = UVC_CMD_UNPACK_IMG, + .header.len = sizeof(uvcb), + .guest_handle = kvm_s390_pv_get_handle(kvm), + .gaddr = addr, + .tweak[0] = tweak, + .tweak[1] = offset, + }; + int ret = gmap_make_secure(kvm->arch.gmap, addr, &uvcb); + + *rc = uvcb.header.rc; + *rrc = uvcb.header.rrc; + + if (ret && ret != -EAGAIN) + KVM_UV_EVENT(kvm, 3, "PROTVIRT VM UNPACK: failed addr %llx with rc %x rrc %x", + uvcb.gaddr, *rc, *rrc); + return ret; +} + +int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size, + unsigned long tweak, u16 *rc, u16 *rrc) +{ + u64 offset = 0; + int ret = 0; + + if (addr & ~PAGE_MASK || !size || size & ~PAGE_MASK) + return -EINVAL; + + KVM_UV_EVENT(kvm, 3, "PROTVIRT VM UNPACK: start addr %lx size %lx", + addr, size); + + while (offset < size) { + ret = unpack_one(kvm, addr, tweak, offset, rc, rrc); + if (ret == -EAGAIN) { + cond_resched(); + if (fatal_signal_pending(current)) + break; + continue; + } + if (ret) + break; + addr += PAGE_SIZE; + offset += PAGE_SIZE; + } + if (!ret) + KVM_UV_EVENT(kvm, 3, "%s", "PROTVIRT VM UNPACK: successful"); + return ret; +} + +int kvm_s390_pv_set_cpu_state(struct kvm_vcpu *vcpu, u8 state) +{ + struct uv_cb_cpu_set_state uvcb = { + .header.cmd = UVC_CMD_CPU_SET_STATE, + .header.len = sizeof(uvcb), + .cpu_handle = kvm_s390_pv_cpu_get_handle(vcpu), + .state = state, + }; + int cc; + + cc = uv_call(0, (u64)&uvcb); + KVM_UV_EVENT(vcpu->kvm, 3, "PROTVIRT SET CPU %d STATE %d rc %x rrc %x", + vcpu->vcpu_id, state, uvcb.header.rc, uvcb.header.rrc); + if (cc) + return -EINVAL; + return 0; +} --- linux-oracle-5.4.0.orig/arch/s390/kvm/sigp.c +++ linux-oracle-5.4.0/arch/s390/kvm/sigp.c @@ -151,22 +151,10 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter, u64 *status_reg) { - unsigned int i; - struct kvm_vcpu *v; - bool all_stopped = true; - - kvm_for_each_vcpu(i, v, vcpu->kvm) { - if (v == vcpu) - continue; - if (!is_vcpu_stopped(v)) - all_stopped = false; - } - *status_reg &= 0xffffffff00000000UL; /* Reject set arch order, with czam we're always in z/Arch mode. */ - *status_reg |= (all_stopped ? SIGP_STATUS_INVALID_PARAMETER : - SIGP_STATUS_INCORRECT_STATE); + *status_reg |= SIGP_STATUS_INVALID_PARAMETER; return SIGP_CC_STATUS_STORED; } @@ -288,6 +276,34 @@ if (!dst_vcpu) return SIGP_CC_NOT_OPERATIONAL; + /* + * SIGP RESTART, SIGP STOP, and SIGP STOP AND STORE STATUS orders + * are processed asynchronously. Until the affected VCPU finishes + * its work and calls back into KVM to clear the (RESTART or STOP) + * interrupt, we need to return any new non-reset orders "busy". + * + * This is important because a single VCPU could issue: + * 1) SIGP STOP $DESTINATION + * 2) SIGP SENSE $DESTINATION + * + * If the SIGP SENSE would not be rejected as "busy", it could + * return an incorrect answer as to whether the VCPU is STOPPED + * or OPERATING. + */ + if (order_code != SIGP_INITIAL_CPU_RESET && + order_code != SIGP_CPU_RESET) { + /* + * Lockless check. Both SIGP STOP and SIGP (RE)START + * properly synchronize everything while processing + * their orders, while the guest cannot observe a + * difference when issuing other orders from two + * different VCPUs. + */ + if (kvm_s390_is_stop_irq_pending(dst_vcpu) || + kvm_s390_is_restart_irq_pending(dst_vcpu)) + return SIGP_CC_BUSY; + } + switch (order_code) { case SIGP_SENSE: vcpu->stat.instruction_sigp_sense++; @@ -464,9 +480,9 @@ struct kvm_vcpu *dest_vcpu; u8 order_code = kvm_s390_get_base_disp_rs(vcpu, NULL); - trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); - if (order_code == SIGP_EXTERNAL_CALL) { + trace_kvm_s390_handle_sigp_pei(vcpu, order_code, cpu_addr); + dest_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, cpu_addr); BUG_ON(dest_vcpu == NULL); --- linux-oracle-5.4.0.orig/arch/s390/kvm/vsie.c +++ linux-oracle-5.4.0/arch/s390/kvm/vsie.c @@ -168,7 +168,8 @@ sizeof(struct kvm_s390_apcb0))) return -EFAULT; - bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb0)); + bitmap_and(apcb_s, apcb_s, apcb_h, + BITS_PER_BYTE * sizeof(struct kvm_s390_apcb0)); return 0; } @@ -190,7 +191,8 @@ sizeof(struct kvm_s390_apcb1))) return -EFAULT; - bitmap_and(apcb_s, apcb_s, apcb_h, sizeof(struct kvm_s390_apcb1)); + bitmap_and(apcb_s, apcb_s, apcb_h, + BITS_PER_BYTE * sizeof(struct kvm_s390_apcb1)); return 0; } @@ -540,14 +542,17 @@ if (test_kvm_cpu_feat(vcpu->kvm, KVM_S390_VM_CPU_FEAT_CEI)) scb_s->eca |= scb_o->eca & ECA_CEI; /* Epoch Extension */ - if (test_kvm_facility(vcpu->kvm, 139)) + if (test_kvm_facility(vcpu->kvm, 139)) { scb_s->ecd |= scb_o->ecd & ECD_MEF; + scb_s->epdx = scb_o->epdx; + } /* etoken */ if (test_kvm_facility(vcpu->kvm, 156)) scb_s->ecd |= scb_o->ecd & ECD_ETOKENF; scb_s->hpid = HPID_VSIE; + scb_s->cpnc = scb_o->cpnc; prepare_ibc(vcpu, vsie_page); rc = shadow_crycb(vcpu, vsie_page); @@ -1110,7 +1115,6 @@ gmap = gmap_shadow(vcpu->arch.gmap, asce, edat); if (IS_ERR(gmap)) return PTR_ERR(gmap); - gmap->private = vcpu->kvm; WRITE_ONCE(vsie_page->gmap, gmap); return 0; } @@ -1202,6 +1206,7 @@ scb_s->iprcc = PGM_ADDRESSING; scb_s->pgmilc = 4; scb_s->gpsw.addr = __rewind_psw(scb_s->gpsw, 4); + rc = 1; } return rc; } @@ -1223,8 +1228,14 @@ page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9); rcu_read_unlock(); if (page) { - if (page_ref_inc_return(page) == 2) - return page_to_virt(page); + if (page_ref_inc_return(page) == 2) { + if (page->index == addr) + return page_to_virt(page); + /* + * We raced with someone reusing + putting this vsie + * page before we grabbed it. + */ + } page_ref_dec(page); } @@ -1254,15 +1265,20 @@ kvm->arch.vsie.next++; kvm->arch.vsie.next %= nr_vcpus; } - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index != ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); } - page->index = addr; - /* double use of the same address */ + /* Mark it as invalid until it resides in the tree. */ + page->index = ULONG_MAX; + + /* Double use of the same address or allocation failure. */ if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) { page_ref_dec(page); mutex_unlock(&kvm->arch.vsie.mutex); return NULL; } + page->index = addr; mutex_unlock(&kvm->arch.vsie.mutex); vsie_page = page_to_virt(page); @@ -1355,7 +1371,9 @@ vsie_page = page_to_virt(page); release_gmap_shadow(vsie_page); /* free the radix tree entry */ - radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9); + if (page->index != ULONG_MAX) + radix_tree_delete(&kvm->arch.vsie.addr_to_page, + page->index >> 9); __free_page(page); } kvm->arch.vsie.page_count = 0; --- linux-oracle-5.4.0.orig/arch/s390/lib/string.c +++ linux-oracle-5.4.0/arch/s390/lib/string.c @@ -246,14 +246,13 @@ #ifdef __HAVE_ARCH_STRRCHR char *strrchr(const char *s, int c) { - size_t len = __strend(s) - s; + ssize_t len = __strend(s) - s; - if (len) - do { - if (s[len] == (char) c) - return (char *) s + len; - } while (--len > 0); - return NULL; + do { + if (s[len] == (char)c) + return (char *)s + len; + } while (--len >= 0); + return NULL; } EXPORT_SYMBOL(strrchr); #endif --- linux-oracle-5.4.0.orig/arch/s390/lib/uaccess.c +++ linux-oracle-5.4.0/arch/s390/lib/uaccess.c @@ -64,10 +64,13 @@ { mm_segment_t old_fs; unsigned long asce, cr; + unsigned long flags; old_fs = current->thread.mm_segment; if (old_fs & 1) return old_fs; + /* protect against a concurrent page table upgrade */ + local_irq_save(flags); current->thread.mm_segment |= 1; asce = S390_lowcore.kernel_asce; if (likely(old_fs == USER_DS)) { @@ -83,6 +86,7 @@ __ctl_load(asce, 7, 7); set_cpu_flag(CIF_ASCE_SECONDARY); } + local_irq_restore(flags); return old_fs; } EXPORT_SYMBOL(enable_sacf_uaccess); @@ -98,10 +102,16 @@ EXPORT_SYMBOL(disable_sacf_uaccess); static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr, - unsigned long size) + unsigned long size, unsigned long key) { - register unsigned long reg0 asm("0") = 0x01UL; unsigned long tmp1, tmp2; + union oac spec = { + .oac2.key = key, + .oac2.as = PSW_BITS_AS_PRIMARY, + .oac2.k = 1, + .oac2.a = 1, + }; + register unsigned long reg0 asm("0") = spec.val; tmp1 = -4096UL; asm volatile( @@ -128,7 +138,7 @@ } static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr, - unsigned long size) + unsigned long size, unsigned long key) { unsigned long tmp1, tmp2; mm_segment_t old_fs; @@ -137,12 +147,12 @@ tmp1 = -256UL; asm volatile( " sacf 0\n" - "0: mvcp 0(%0,%2),0(%1),%3\n" + "0: mvcp 0(%0,%2),0(%1),%[key]\n" "7: jz 5f\n" "1: algr %0,%3\n" " la %1,256(%1)\n" " la %2,256(%2)\n" - "2: mvcp 0(%0,%2),0(%1),%3\n" + "2: mvcp 0(%0,%2),0(%1),%[key]\n" "8: jnz 1b\n" " j 5f\n" "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ @@ -151,7 +161,7 @@ " slgr %4,%1\n" " clgr %0,%4\n" /* copy crosses next page boundary? */ " jnh 6f\n" - "4: mvcp 0(%4,%2),0(%1),%3\n" + "4: mvcp 0(%4,%2),0(%1),%[key]\n" "9: slgr %0,%4\n" " j 6f\n" "5: slgr %0,%0\n" @@ -159,24 +169,53 @@ EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); + : [key] "d" (key << 4) + : "cc", "memory"); disable_sacf_uaccess(old_fs); return size; } -unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) +static unsigned long raw_copy_from_user_key(void *to, const void __user *from, + unsigned long n, unsigned long key) { if (copy_with_mvcos()) - return copy_from_user_mvcos(to, from, n); - return copy_from_user_mvcp(to, from, n); + return copy_from_user_mvcos(to, from, n, key); + return copy_from_user_mvcp(to, from, n, key); +} + +unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) +{ + return raw_copy_from_user_key(to, from, n, 0); } EXPORT_SYMBOL(raw_copy_from_user); +unsigned long _copy_from_user_key(void *to, const void __user *from, + unsigned long n, unsigned long key) +{ + unsigned long res = n; + + might_fault(); + if (likely(access_ok(from, n))) { + kasan_check_write(to, n); + res = raw_copy_from_user_key(to, from, n, key); + } + if (unlikely(res)) + memset(to + (n - res), 0, res); + return res; +} +EXPORT_SYMBOL(_copy_from_user_key); + static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x, - unsigned long size) + unsigned long size, unsigned long key) { - register unsigned long reg0 asm("0") = 0x010000UL; unsigned long tmp1, tmp2; + union oac spec = { + .oac1.key = key, + .oac1.as = PSW_BITS_AS_PRIMARY, + .oac1.k = 1, + .oac1.a = 1, + }; + register unsigned long reg0 asm("0") = spec.val; tmp1 = -4096UL; asm volatile( @@ -203,7 +242,7 @@ } static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x, - unsigned long size) + unsigned long size, unsigned long key) { unsigned long tmp1, tmp2; mm_segment_t old_fs; @@ -212,12 +251,12 @@ tmp1 = -256UL; asm volatile( " sacf 0\n" - "0: mvcs 0(%0,%1),0(%2),%3\n" + "0: mvcs 0(%0,%1),0(%2),%[key]\n" "7: jz 5f\n" "1: algr %0,%3\n" " la %1,256(%1)\n" " la %2,256(%2)\n" - "2: mvcs 0(%0,%1),0(%2),%3\n" + "2: mvcs 0(%0,%1),0(%2),%[key]\n" "8: jnz 1b\n" " j 5f\n" "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ @@ -226,7 +265,7 @@ " slgr %4,%1\n" " clgr %0,%4\n" /* copy crosses next page boundary? */ " jnh 6f\n" - "4: mvcs 0(%4,%1),0(%2),%3\n" + "4: mvcs 0(%4,%1),0(%2),%[key]\n" "9: slgr %0,%4\n" " j 6f\n" "5: slgr %0,%0\n" @@ -234,24 +273,49 @@ EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); + : [key] "d" (key << 4) + : "cc", "memory"); disable_sacf_uaccess(old_fs); return size; } -unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) +static unsigned long raw_copy_to_user_key(void __user *to, const void *from, + unsigned long n, unsigned long key) { if (copy_with_mvcos()) - return copy_to_user_mvcos(to, from, n); - return copy_to_user_mvcs(to, from, n); + return copy_to_user_mvcos(to, from, n, key); + return copy_to_user_mvcs(to, from, n, key); +} + +unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + return raw_copy_to_user_key(to, from, n, 0); } EXPORT_SYMBOL(raw_copy_to_user); +unsigned long _copy_to_user_key(void __user *to, const void *from, + unsigned long n, unsigned long key) +{ + might_fault(); + if (access_ok(to, n)) { + kasan_check_read(from, n); + n = raw_copy_to_user_key(to, from, n, key); + } + return n; +} +EXPORT_SYMBOL(_copy_to_user_key); + static inline unsigned long copy_in_user_mvcos(void __user *to, const void __user *from, unsigned long size) { - register unsigned long reg0 asm("0") = 0x010001UL; unsigned long tmp1, tmp2; + union oac spec = { + .oac1.as = PSW_BITS_AS_PRIMARY, + .oac1.a = 1, + .oac2.as = PSW_BITS_AS_PRIMARY, + .oac2.a = 1, + }; + register unsigned long reg0 asm("0") = spec.val; tmp1 = -4096UL; /* FIXME: copy with reduced length. */ @@ -314,8 +378,12 @@ static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size) { - register unsigned long reg0 asm("0") = 0x010000UL; unsigned long tmp1, tmp2; + union oac spec = { + .oac1.as = PSW_BITS_AS_PRIMARY, + .oac1.a = 1, + }; + register unsigned long reg0 asm("0") = spec.val; tmp1 = -4096UL; asm volatile( @@ -335,7 +403,7 @@ "4: slgr %0,%0\n" "5:\n" EX_TABLE(0b,2b) EX_TABLE(3b,5b) - : "+a" (size), "+a" (to), "+a" (tmp1), "=a" (tmp2) + : "+&a" (size), "+&a" (to), "+a" (tmp1), "=&a" (tmp2) : "a" (empty_zero_page), "d" (reg0) : "cc", "memory"); return size; } --- linux-oracle-5.4.0.orig/arch/s390/mm/cmm.c +++ linux-oracle-5.4.0/arch/s390/mm/cmm.c @@ -98,11 +98,12 @@ (*counter)++; spin_unlock(&cmm_lock); nr--; + cond_resched(); } return nr; } -static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) +static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) { struct cmm_page_array *pa; unsigned long addr; @@ -126,6 +127,21 @@ return nr; } +static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) +{ + long inc = 0; + + while (nr) { + inc = min(256L, nr); + nr -= inc; + inc = __cmm_free_pages(inc, counter, list); + if (inc) + break; + cond_resched(); + } + return nr + inc; +} + static int cmm_oom_notify(struct notifier_block *self, unsigned long dummy, void *parm) { --- linux-oracle-5.4.0.orig/arch/s390/mm/fault.c +++ linux-oracle-5.4.0/arch/s390/mm/fault.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "../kernel/entry.h" #define __FAIL_ADDR_MASK -4096L @@ -432,7 +433,9 @@ flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; if (user_mode(regs)) flags |= FAULT_FLAG_USER; - if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400) + if ((trans_exc_code & store_indication) == 0x400) + access = VM_WRITE; + if (access == VM_WRITE) flags |= FAULT_FLAG_WRITE; down_read(&mm->mmap_sem); @@ -816,3 +819,80 @@ early_initcall(pfault_irq_init); #endif /* CONFIG_PFAULT */ + +#if IS_ENABLED(CONFIG_PGSTE) +void do_secure_storage_access(struct pt_regs *regs) +{ + unsigned long addr = regs->int_parm_long & __FAIL_ADDR_MASK; + struct vm_area_struct *vma; + struct mm_struct *mm; + struct page *page; + int rc; + + switch (get_fault_type(regs)) { + case USER_FAULT: + mm = current->mm; + down_read(&mm->mmap_sem); + vma = find_vma(mm, addr); + if (!vma) { + up_read(&mm->mmap_sem); + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); + break; + } + page = follow_page(vma, addr, FOLL_WRITE | FOLL_GET); + if (IS_ERR_OR_NULL(page)) { + up_read(&mm->mmap_sem); + break; + } + if (arch_make_page_accessible(page)) + send_sig(SIGSEGV, current, 0); + put_page(page); + up_read(&mm->mmap_sem); + break; + case KERNEL_FAULT: + page = phys_to_page(addr); + if (unlikely(!try_get_page(page))) + break; + rc = arch_make_page_accessible(page); + put_page(page); + if (rc) + BUG(); + break; + case VDSO_FAULT: + /* fallthrough */ + case GMAP_FAULT: + /* fallthrough */ + default: + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); + WARN_ON_ONCE(1); + } +} +NOKPROBE_SYMBOL(do_secure_storage_access); + +void do_non_secure_storage_access(struct pt_regs *regs) +{ + unsigned long gaddr = regs->int_parm_long & __FAIL_ADDR_MASK; + struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; + + if (get_fault_type(regs) != GMAP_FAULT) { + do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP); + WARN_ON_ONCE(1); + return; + } + + if (gmap_convert_to_secure(gmap, gaddr) == -EINVAL) + send_sig(SIGSEGV, current, 0); +} +NOKPROBE_SYMBOL(do_non_secure_storage_access); + +#else +void do_secure_storage_access(struct pt_regs *regs) +{ + default_trap_handler(regs); +} + +void do_non_secure_storage_access(struct pt_regs *regs) +{ + default_trap_handler(regs); +} +#endif --- linux-oracle-5.4.0.orig/arch/s390/mm/gmap.c +++ linux-oracle-5.4.0/arch/s390/mm/gmap.c @@ -684,9 +684,10 @@ vmaddr |= gaddr & ~PMD_MASK; /* Get pointer to the page table entry */ ptep = get_locked_pte(gmap->mm, vmaddr, &ptl); - if (likely(ptep)) + if (likely(ptep)) { ptep_zap_unused(gmap->mm, vmaddr, ptep, 0); - pte_unmap_unlock(ptep, ptl); + pte_unmap_unlock(ptep, ptl); + } } } EXPORT_SYMBOL_GPL(__gmap_zap); @@ -787,14 +788,18 @@ static inline unsigned long *gmap_table_walk(struct gmap *gmap, unsigned long gaddr, int level) { + const int asce_type = gmap->asce & _ASCE_TYPE_MASK; unsigned long *table; if ((gmap->asce & _ASCE_TYPE_MASK) + 4 < (level * 4)) return NULL; if (gmap_is_shadow(gmap) && gmap->removed) return NULL; - if (gaddr & (-1UL << (31 + ((gmap->asce & _ASCE_TYPE_MASK) >> 2)*11))) + + if (asce_type != _ASCE_TYPE_REGION1 && + gaddr & (-1UL << (31 + (asce_type >> 2) * 11))) return NULL; + table = gmap->table; switch (gmap->asce & _ASCE_TYPE_MASK) { case _ASCE_TYPE_REGION1: @@ -1173,6 +1178,7 @@ static inline void gmap_insert_rmap(struct gmap *sg, unsigned long vmaddr, struct gmap_rmap *rmap) { + struct gmap_rmap *temp; void __rcu **slot; BUG_ON(!gmap_is_shadow(sg)); @@ -1180,6 +1186,12 @@ if (slot) { rmap->next = radix_tree_deref_slot_protected(slot, &sg->guest_table_lock); + for (temp = rmap->next; temp; temp = temp->next) { + if (temp->raddr == rmap->raddr) { + kfree(rmap); + return; + } + } radix_tree_replace_slot(&sg->host_to_rmap, slot, rmap); } else { rmap->next = NULL; @@ -1658,6 +1670,7 @@ return ERR_PTR(-ENOMEM); new->mm = parent->mm; new->parent = gmap_get(parent); + new->private = parent->private; new->orig_asce = asce; new->edat_level = edat_level; new->initialized = false; @@ -1840,6 +1853,7 @@ goto out_free; } else if (*table & _REGION_ENTRY_ORIGIN) { rc = -EAGAIN; /* Race with shadow */ + goto out_free; } crst_table_init(s_r3t, _REGION3_ENTRY_EMPTY); /* mark as invalid as long as the parent table is not protected */ @@ -2480,23 +2494,36 @@ } EXPORT_SYMBOL_GPL(gmap_sync_dirty_log_pmd); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE +static int thp_split_walk_pmd_entry(pmd_t *pmd, unsigned long addr, + unsigned long end, struct mm_walk *walk) +{ + struct vm_area_struct *vma = walk->vma; + + split_huge_pmd(vma, pmd, addr); + return 0; +} + +static const struct mm_walk_ops thp_split_walk_ops = { + .pmd_entry = thp_split_walk_pmd_entry, +}; + static inline void thp_split_mm(struct mm_struct *mm) { -#ifdef CONFIG_TRANSPARENT_HUGEPAGE struct vm_area_struct *vma; - unsigned long addr; for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) { - for (addr = vma->vm_start; - addr < vma->vm_end; - addr += PAGE_SIZE) - follow_page(vma, addr, FOLL_SPLIT); vma->vm_flags &= ~VM_HUGEPAGE; vma->vm_flags |= VM_NOHUGEPAGE; + walk_page_vma(vma, &thp_split_walk_ops, NULL); } mm->def_flags |= VM_NOHUGEPAGE; -#endif } +#else +static inline void thp_split_mm(struct mm_struct *mm) +{ +} +#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ /* * Remove all empty zero pages from the mapping for lazy refaulting @@ -2548,6 +2575,22 @@ } EXPORT_SYMBOL_GPL(s390_enable_sie); +int gmap_mark_unmergeable(void) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + + for (vma = mm->mmap; vma; vma = vma->vm_next) { + if (ksm_madvise(vma, vma->vm_start, vma->vm_end, + MADV_UNMERGEABLE, &vma->vm_flags)) { + return -ENOMEM; + } + } + mm->def_flags &= ~VM_MERGEABLE; + return 0; +} +EXPORT_SYMBOL_GPL(gmap_mark_unmergeable); + /* * Enable storage key handling from now on and initialize the storage * keys with the default key. @@ -2560,6 +2603,18 @@ return 0; } +/* + * Give a chance to schedule after setting a key to 256 pages. + * We only hold the mm lock, which is a rwsem and the kvm srcu. + * Both can sleep. + */ +static int __s390_enable_skey_pmd(pmd_t *pmd, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + cond_resched(); + return 0; +} + static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr, unsigned long hmask, unsigned long next, struct mm_walk *walk) @@ -2579,21 +2634,22 @@ return 0; start = pmd_val(*pmd) & HPAGE_MASK; - end = start + HPAGE_SIZE - 1; + end = start + HPAGE_SIZE; __storage_key_init_range(start, end); set_bit(PG_arch_1, &page->flags); + cond_resched(); return 0; } static const struct mm_walk_ops enable_skey_walk_ops = { .hugetlb_entry = __s390_enable_skey_hugetlb, .pte_entry = __s390_enable_skey_pte, + .pmd_entry = __s390_enable_skey_pmd, }; int s390_enable_skey(void) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; int rc = 0; down_write(&mm->mmap_sem); @@ -2601,16 +2657,11 @@ goto out_up; mm->context.uses_skeys = 1; - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (ksm_madvise(vma, vma->vm_start, vma->vm_end, - MADV_UNMERGEABLE, &vma->vm_flags)) { - mm->context.uses_skeys = 0; - rc = -ENOMEM; - goto out_up; - } + rc = gmap_mark_unmergeable(); + if (rc) { + mm->context.uses_skeys = 0; + goto out_up; } - mm->def_flags &= ~VM_MERGEABLE; - walk_page_range(mm, 0, TASK_SIZE, &enable_skey_walk_ops, NULL); out_up: @@ -2640,3 +2691,38 @@ up_write(&mm->mmap_sem); } EXPORT_SYMBOL_GPL(s390_reset_cmma); + +/* + * make inaccessible pages accessible again + */ +static int __s390_reset_acc(pte_t *ptep, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pte_t pte = READ_ONCE(*ptep); + + if (pte_present(pte)) + WARN_ON_ONCE(uv_convert_from_secure(pte_val(pte) & PAGE_MASK)); + return 0; +} + +static const struct mm_walk_ops reset_acc_walk_ops = { + .pte_entry = __s390_reset_acc, +}; + +#include +void s390_reset_acc(struct mm_struct *mm) +{ + /* + * we might be called during + * reset: we walk the pages and clear + * close of all kvm file descriptors: we walk the pages and clear + * exit of process on fd closure: vma already gone, do nothing + */ + if (!mmget_not_zero(mm)) + return; + down_read(&mm->mmap_sem); + walk_page_range(mm, 0, TASK_SIZE, &reset_acc_walk_ops, NULL); + up_read(&mm->mmap_sem); + mmput(mm); +} +EXPORT_SYMBOL_GPL(s390_reset_acc); --- linux-oracle-5.4.0.orig/arch/s390/mm/hugetlbpage.c +++ linux-oracle-5.4.0/arch/s390/mm/hugetlbpage.c @@ -2,7 +2,7 @@ /* * IBM System z Huge TLB Page Support for Kernel. * - * Copyright IBM Corp. 2007,2016 + * Copyright IBM Corp. 2007,2020 * Author(s): Gerald Schaefer */ @@ -11,6 +11,9 @@ #include #include +#include +#include +#include /* * If the bit selected by single-bit bitmask "a" is set within "x", move @@ -114,7 +117,7 @@ _PAGE_YOUNG); #ifdef CONFIG_MEM_SOFT_DIRTY pte_val(pte) |= move_set_bit(rste, _SEGMENT_ENTRY_SOFT_DIRTY, - _PAGE_DIRTY); + _PAGE_SOFT_DIRTY); #endif pte_val(pte) |= move_set_bit(rste, _SEGMENT_ENTRY_NOEXEC, _PAGE_NOEXEC); @@ -143,7 +146,7 @@ } if (!test_and_set_bit(PG_arch_1, &page->flags)) - __storage_key_init_range(paddr, paddr + size - 1); + __storage_key_init_range(paddr, paddr + size); } void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, @@ -156,10 +159,13 @@ rste &= ~_SEGMENT_ENTRY_NOEXEC; /* Set correct table type for 2G hugepages */ - if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) - rste |= _REGION_ENTRY_TYPE_R3 | _REGION3_ENTRY_LARGE; - else + if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) { + if (likely(pte_present(pte))) + rste |= _REGION3_ENTRY_LARGE; + rste |= _REGION_ENTRY_TYPE_R3; + } else if (likely(pte_present(pte))) rste |= _SEGMENT_ENTRY_LARGE; + clear_huge_pte_skeys(mm, rste); pte_val(*ptep) = rste; } @@ -267,3 +273,98 @@ return 1; } __setup("hugepagesz=", setup_hugepagesz); + +static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file, + unsigned long addr, unsigned long len, + unsigned long pgoff, unsigned long flags) +{ + struct hstate *h = hstate_file(file); + struct vm_unmapped_area_info info; + + info.flags = 0; + info.length = len; + info.low_limit = current->mm->mmap_base; + info.high_limit = TASK_SIZE; + info.align_mask = PAGE_MASK & ~huge_page_mask(h); + info.align_offset = 0; + return vm_unmapped_area(&info); +} + +static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file, + unsigned long addr0, unsigned long len, + unsigned long pgoff, unsigned long flags) +{ + struct hstate *h = hstate_file(file); + struct vm_unmapped_area_info info; + unsigned long addr; + + info.flags = VM_UNMAPPED_AREA_TOPDOWN; + info.length = len; + info.low_limit = max(PAGE_SIZE, mmap_min_addr); + info.high_limit = current->mm->mmap_base; + info.align_mask = PAGE_MASK & ~huge_page_mask(h); + info.align_offset = 0; + addr = vm_unmapped_area(&info); + + /* + * A failed mmap() very likely causes application failure, + * so fall back to the bottom-up function here. This scenario + * can happen with large stack limits and large mmap() + * allocations. + */ + if (addr & ~PAGE_MASK) { + VM_BUG_ON(addr != -ENOMEM); + info.flags = 0; + info.low_limit = TASK_UNMAPPED_BASE; + info.high_limit = TASK_SIZE; + addr = vm_unmapped_area(&info); + } + + return addr; +} + +unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, unsigned long flags) +{ + struct hstate *h = hstate_file(file); + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + int rc; + + if (len & ~huge_page_mask(h)) + return -EINVAL; + if (len > TASK_SIZE - mmap_min_addr) + return -ENOMEM; + + if (flags & MAP_FIXED) { + if (prepare_hugepage_range(file, addr, len)) + return -EINVAL; + goto check_asce_limit; + } + + if (addr) { + addr = ALIGN(addr, huge_page_size(h)); + vma = find_vma(mm, addr); + if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && + (!vma || addr + len <= vm_start_gap(vma))) + goto check_asce_limit; + } + + if (mm->get_unmapped_area == arch_get_unmapped_area) + addr = hugetlb_get_unmapped_area_bottomup(file, addr, len, + pgoff, flags); + else + addr = hugetlb_get_unmapped_area_topdown(file, addr, len, + pgoff, flags); + if (addr & ~PAGE_MASK) + return addr; + +check_asce_limit: + if (addr + len > current->mm->context.asce_limit && + addr + len <= TASK_SIZE) { + rc = crst_table_upgrade(mm, addr + len); + if (rc) + return (unsigned long) rc; + } + return addr; +} --- linux-oracle-5.4.0.orig/arch/s390/mm/init.c +++ linux-oracle-5.4.0/arch/s390/mm/init.c @@ -121,7 +121,7 @@ memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); } void mark_rodata_ro(void) @@ -168,9 +168,9 @@ return; /* make sure bounce buffers are shared */ + swiotlb_force = SWIOTLB_FORCE; swiotlb_init(1); swiotlb_update_mem_attributes(); - swiotlb_force = SWIOTLB_FORCE; } void __init mem_init(void) @@ -291,10 +291,8 @@ { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct zone *zone; - zone = page_zone(pfn_to_page(start_pfn)); - __remove_pages(zone, start_pfn, nr_pages, altmap); + __remove_pages(start_pfn, nr_pages, altmap); vmem_remove_mapping(start, size); } #endif /* CONFIG_MEMORY_HOTPLUG */ --- linux-oracle-5.4.0.orig/arch/s390/mm/kasan_init.c +++ linux-oracle-5.4.0/arch/s390/mm/kasan_init.c @@ -101,6 +101,9 @@ pgt_prot = pgprot_val(PAGE_KERNEL_EXEC); sgt_prot = pgprot_val(SEGMENT_KERNEL_EXEC); + /* + * The first 1MB of 1:1 mapping is mapped with 4KB pages + */ while (address < end) { pg_dir = pgd_offset_k(address); if (pgd_none(*pg_dir)) { @@ -146,30 +149,26 @@ pm_dir = pmd_offset(pu_dir, address); if (pmd_none(*pm_dir)) { - if (mode == POPULATE_ZERO_SHADOW && - IS_ALIGNED(address, PMD_SIZE) && + if (IS_ALIGNED(address, PMD_SIZE) && end - address >= PMD_SIZE) { - pmd_populate(&init_mm, pm_dir, - kasan_early_shadow_pte); - address = (address + PMD_SIZE) & PMD_MASK; - continue; - } - /* the first megabyte of 1:1 is mapped with 4k pages */ - if (has_edat && address && end - address >= PMD_SIZE && - mode != POPULATE_ZERO_SHADOW) { - void *page; - - if (mode == POPULATE_ONE2ONE) { - page = (void *)address; - } else { - page = kasan_early_alloc_segment(); - memset(page, 0, _SEGMENT_SIZE); + if (mode == POPULATE_ZERO_SHADOW) { + pmd_populate(&init_mm, pm_dir, kasan_early_shadow_pte); + address = (address + PMD_SIZE) & PMD_MASK; + continue; + } else if (has_edat && address) { + void *page; + + if (mode == POPULATE_ONE2ONE) { + page = (void *)address; + } else { + page = kasan_early_alloc_segment(); + memset(page, 0, _SEGMENT_SIZE); + } + pmd_val(*pm_dir) = __pa(page) | sgt_prot; + address = (address + PMD_SIZE) & PMD_MASK; + continue; } - pmd_val(*pm_dir) = __pa(page) | sgt_prot; - address = (address + PMD_SIZE) & PMD_MASK; - continue; } - pt_dir = kasan_early_pte_alloc(); pmd_populate(&init_mm, pm_dir, pt_dir); } else if (pmd_large(*pm_dir)) { --- linux-oracle-5.4.0.orig/arch/s390/mm/maccess.c +++ linux-oracle-5.4.0/arch/s390/mm/maccess.c @@ -55,22 +55,29 @@ */ static DEFINE_SPINLOCK(s390_kernel_write_lock); -void notrace s390_kernel_write(void *dst, const void *src, size_t size) +notrace void *s390_kernel_write(void *dst, const void *src, size_t size) { + void *tmp = dst; unsigned long flags; long copied; spin_lock_irqsave(&s390_kernel_write_lock, flags); - while (size) { - copied = s390_kernel_write_odd(dst, src, size); - dst += copied; - src += copied; - size -= copied; + if (!(flags & PSW_MASK_DAT)) { + memcpy(dst, src, size); + } else { + while (size) { + copied = s390_kernel_write_odd(tmp, src, size); + tmp += copied; + src += copied; + size -= copied; + } } spin_unlock_irqrestore(&s390_kernel_write_lock, flags); + + return dst; } -static int __memcpy_real(void *dest, void *src, size_t count) +static int __no_sanitize_address __memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; register unsigned long _len1 asm("3") = (unsigned long) count; @@ -91,19 +98,23 @@ return rc; } -static unsigned long _memcpy_real(unsigned long dest, unsigned long src, - unsigned long count) +static unsigned long __no_sanitize_address _memcpy_real(unsigned long dest, + unsigned long src, + unsigned long count) { int irqs_disabled, rc; unsigned long flags; if (!count) return 0; - flags = __arch_local_irq_stnsm(0xf8UL); + flags = arch_local_irq_save(); irqs_disabled = arch_irqs_disabled_flags(flags); if (!irqs_disabled) trace_hardirqs_off(); + __arch_local_irq_stnsm(0xf8); // disable DAT rc = __memcpy_real((void *) dest, (void *) src, (size_t) count); + if (flags & PSW_MASK_DAT) + __arch_local_irq_stosm(0x04); // enable DAT if (!irqs_disabled) trace_hardirqs_on(); __arch_local_irq_ssm(flags); @@ -115,9 +126,15 @@ */ int memcpy_real(void *dest, void *src, size_t count) { - if (S390_lowcore.nodat_stack != 0) - return CALL_ON_STACK(_memcpy_real, S390_lowcore.nodat_stack, - 3, dest, src, count); + int rc; + + if (S390_lowcore.nodat_stack != 0) { + preempt_disable(); + rc = CALL_ON_STACK(_memcpy_real, S390_lowcore.nodat_stack, 3, + dest, src, count); + preempt_enable(); + return rc; + } /* * This is a really early memcpy_real call, the stacks are * not set up yet. Just call _memcpy_real on the early boot --- linux-oracle-5.4.0.orig/arch/s390/mm/page-states.c +++ linux-oracle-5.4.0/arch/s390/mm/page-states.c @@ -112,7 +112,7 @@ next = pmd_addr_end(addr, end); if (pmd_none(*pmd) || pmd_large(*pmd)) continue; - page = virt_to_page(pmd_val(*pmd)); + page = phys_to_page(pmd_val(*pmd)); set_bit(PG_arch_1, &page->flags); } while (pmd++, addr = next, addr != end); } @@ -130,8 +130,8 @@ if (pud_none(*pud) || pud_large(*pud)) continue; if (!pud_folded(*pud)) { - page = virt_to_page(pud_val(*pud)); - for (i = 0; i < 3; i++) + page = phys_to_page(pud_val(*pud)); + for (i = 0; i < 4; i++) set_bit(PG_arch_1, &page[i].flags); } mark_kernel_pmd(pud, addr, next); @@ -151,8 +151,8 @@ if (p4d_none(*p4d)) continue; if (!p4d_folded(*p4d)) { - page = virt_to_page(p4d_val(*p4d)); - for (i = 0; i < 3; i++) + page = phys_to_page(p4d_val(*p4d)); + for (i = 0; i < 4; i++) set_bit(PG_arch_1, &page[i].flags); } mark_kernel_pud(p4d, addr, next); @@ -173,8 +173,8 @@ if (pgd_none(*pgd)) continue; if (!pgd_folded(*pgd)) { - page = virt_to_page(pgd_val(*pgd)); - for (i = 0; i < 3; i++) + page = phys_to_page(pgd_val(*pgd)); + for (i = 0; i < 4; i++) set_bit(PG_arch_1, &page[i].flags); } mark_kernel_p4d(pgd, addr, next); --- linux-oracle-5.4.0.orig/arch/s390/mm/pgalloc.c +++ linux-oracle-5.4.0/arch/s390/mm/pgalloc.c @@ -70,8 +70,20 @@ { struct mm_struct *mm = arg; - if (current->active_mm == mm) - set_user_asce(mm); + /* we must change all active ASCEs to avoid the creation of new TLBs */ + if (current->active_mm == mm) { + S390_lowcore.user_asce = mm->context.asce; + if (current->thread.mm_segment == USER_DS) { + __ctl_load(S390_lowcore.user_asce, 1, 1); + /* Mark user-ASCE present in CR1 */ + clear_cpu_flag(CIF_ASCE_PRIMARY); + } + if (current->thread.mm_segment == USER_DS_SACF) { + __ctl_load(S390_lowcore.user_asce, 7, 7); + /* enable_sacf_uaccess does all or nothing */ + WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY)); + } + } __tlb_flush_local(); } @@ -243,13 +255,15 @@ /* Free 2K page table fragment of a 4K page */ bit = (__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)); spin_lock_bh(&mm->context.lock); - mask = atomic_xor_bits(&page->_refcount, 1U << (bit + 24)); + mask = atomic_xor_bits(&page->_refcount, 0x11U << (bit + 24)); mask >>= 24; if (mask & 3) list_add(&page->lru, &mm->context.pgtable_list); else list_del(&page->lru); spin_unlock_bh(&mm->context.lock); + mask = atomic_xor_bits(&page->_refcount, 0x10U << (bit + 24)); + mask >>= 24; if (mask != 0) return; } else { --- linux-oracle-5.4.0.orig/arch/s390/mm/pgtable.c +++ linux-oracle-5.4.0/arch/s390/mm/pgtable.c @@ -699,7 +699,7 @@ pte_clear(mm, addr, ptep); } if (reset) - pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; + pgste_val(pgste) &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); pgste_set_unlock(ptep, pgste); preempt_enable(); } @@ -716,7 +716,7 @@ pgste_val(pgste) |= PGSTE_GR_BIT | PGSTE_GC_BIT; ptev = pte_val(*ptep); if (!(ptev & _PAGE_INVALID) && (ptev & _PAGE_WRITE)) - page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 1); + page_set_storage_key(ptev & PAGE_MASK, PAGE_DEFAULT_KEY, 0); pgste_set_unlock(ptep, pgste); preempt_enable(); } @@ -970,6 +970,7 @@ int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc, unsigned long *oldpte, unsigned long *oldpgste) { + struct vm_area_struct *vma; unsigned long pgstev; spinlock_t *ptl; pgste_t pgste; @@ -979,6 +980,10 @@ WARN_ON_ONCE(orc > ESSA_MAX); if (unlikely(orc > ESSA_MAX)) return -EINVAL; + + vma = find_vma(mm, hva); + if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT; @@ -1071,10 +1076,14 @@ int set_pgste_bits(struct mm_struct *mm, unsigned long hva, unsigned long bits, unsigned long value) { + struct vm_area_struct *vma; spinlock_t *ptl; pgste_t new; pte_t *ptep; + vma = find_vma(mm, hva); + if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT; @@ -1099,9 +1108,13 @@ */ int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep) { + struct vm_area_struct *vma; spinlock_t *ptl; pte_t *ptep; + vma = find_vma(mm, hva); + if (!vma || hva < vma->vm_start || is_vm_hugetlb_page(vma)) + return -EFAULT; ptep = get_locked_pte(mm, hva, &ptl); if (unlikely(!ptep)) return -EFAULT; --- linux-oracle-5.4.0.orig/arch/s390/mm/vmem.c +++ linux-oracle-5.4.0/arch/s390/mm/vmem.c @@ -415,6 +415,10 @@ SET_MEMORY_RO | SET_MEMORY_X); __set_memory(__stext_dma, (__etext_dma - __stext_dma) >> PAGE_SHIFT, SET_MEMORY_RO | SET_MEMORY_X); + + /* we need lowcore executable for our LPSWE instructions */ + set_memory_x(0, 1); + pr_info("Write protected kernel read-only data: %luk\n", (unsigned long)(__end_rodata - _stext) >> 10); } --- linux-oracle-5.4.0.orig/arch/s390/net/bpf_jit_comp.c +++ linux-oracle-5.4.0/arch/s390/net/bpf_jit_comp.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -113,7 +114,7 @@ { u32 r1 = reg2hex[b1]; - if (!jit->seen_reg[r1] && r1 >= 6 && r1 <= 15) + if (r1 >= 6 && r1 <= 15 && !jit->seen_reg[r1]) jit->seen_reg[r1] = 1; } @@ -568,10 +569,10 @@ EMIT4(0xb9080000, dst_reg, src_reg); break; case BPF_ALU | BPF_ADD | BPF_K: /* dst = (u32) dst + (u32) imm */ - if (!imm) - break; - /* alfi %dst,imm */ - EMIT6_IMM(0xc20b0000, dst_reg, imm); + if (imm != 0) { + /* alfi %dst,imm */ + EMIT6_IMM(0xc20b0000, dst_reg, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_ADD | BPF_K: /* dst = dst + imm */ @@ -593,17 +594,22 @@ EMIT4(0xb9090000, dst_reg, src_reg); break; case BPF_ALU | BPF_SUB | BPF_K: /* dst = (u32) dst - (u32) imm */ - if (!imm) - break; - /* alfi %dst,-imm */ - EMIT6_IMM(0xc20b0000, dst_reg, -imm); + if (imm != 0) { + /* alfi %dst,-imm */ + EMIT6_IMM(0xc20b0000, dst_reg, -imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_SUB | BPF_K: /* dst = dst - imm */ if (!imm) break; - /* agfi %dst,-imm */ - EMIT6_IMM(0xc2080000, dst_reg, -imm); + if (imm == -0x80000000) { + /* algfi %dst,0x80000000 */ + EMIT6_IMM(0xc20a0000, dst_reg, 0x80000000); + } else { + /* agfi %dst,-imm */ + EMIT6_IMM(0xc2080000, dst_reg, -imm); + } break; /* * BPF_MUL @@ -618,10 +624,10 @@ EMIT4(0xb90c0000, dst_reg, src_reg); break; case BPF_ALU | BPF_MUL | BPF_K: /* dst = (u32) dst * (u32) imm */ - if (imm == 1) - break; - /* msfi %r5,imm */ - EMIT6_IMM(0xc2010000, dst_reg, imm); + if (imm != 1) { + /* msfi %r5,imm */ + EMIT6_IMM(0xc2010000, dst_reg, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_MUL | BPF_K: /* dst = dst * imm */ @@ -674,6 +680,8 @@ if (BPF_OP(insn->code) == BPF_MOD) /* lhgi %dst,0 */ EMIT4_IMM(0xa7090000, dst_reg, 0); + else + EMIT_ZERO(dst_reg); break; } /* lhi %w0,0 */ @@ -768,10 +776,10 @@ EMIT4(0xb9820000, dst_reg, src_reg); break; case BPF_ALU | BPF_XOR | BPF_K: /* dst = (u32) dst ^ (u32) imm */ - if (!imm) - break; - /* xilf %dst,imm */ - EMIT6_IMM(0xc0070000, dst_reg, imm); + if (imm != 0) { + /* xilf %dst,imm */ + EMIT6_IMM(0xc0070000, dst_reg, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_XOR | BPF_K: /* dst = dst ^ imm */ @@ -792,10 +800,10 @@ EMIT6_DISP_LH(0xeb000000, 0x000d, dst_reg, dst_reg, src_reg, 0); break; case BPF_ALU | BPF_LSH | BPF_K: /* dst = (u32) dst << (u32) imm */ - if (imm == 0) - break; - /* sll %dst,imm(%r0) */ - EMIT4_DISP(0x89000000, dst_reg, REG_0, imm); + if (imm != 0) { + /* sll %dst,imm(%r0) */ + EMIT4_DISP(0x89000000, dst_reg, REG_0, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_LSH | BPF_K: /* dst = dst << imm */ @@ -817,10 +825,10 @@ EMIT6_DISP_LH(0xeb000000, 0x000c, dst_reg, dst_reg, src_reg, 0); break; case BPF_ALU | BPF_RSH | BPF_K: /* dst = (u32) dst >> (u32) imm */ - if (imm == 0) - break; - /* srl %dst,imm(%r0) */ - EMIT4_DISP(0x88000000, dst_reg, REG_0, imm); + if (imm != 0) { + /* srl %dst,imm(%r0) */ + EMIT4_DISP(0x88000000, dst_reg, REG_0, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_RSH | BPF_K: /* dst = dst >> imm */ @@ -842,10 +850,10 @@ EMIT6_DISP_LH(0xeb000000, 0x000a, dst_reg, dst_reg, src_reg, 0); break; case BPF_ALU | BPF_ARSH | BPF_K: /* ((s32) dst >> imm */ - if (imm == 0) - break; - /* sra %dst,imm(%r0) */ - EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm); + if (imm != 0) { + /* sra %dst,imm(%r0) */ + EMIT4_DISP(0x8a000000, dst_reg, REG_0, imm); + } EMIT_ZERO(dst_reg); break; case BPF_ALU64 | BPF_ARSH | BPF_K: /* ((s64) dst) >>= imm */ @@ -913,6 +921,11 @@ } break; /* + * BPF_NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + break; + /* * BPF_ST(X) */ case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src_reg */ @@ -1369,10 +1382,10 @@ } memset(&jit, 0, sizeof(jit)); - jit.addrs = kcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL); + jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL); if (jit.addrs == NULL) { fp = orig_fp; - goto out; + goto free_addrs; } /* * Three initial passes: @@ -1422,7 +1435,7 @@ if (!fp->is_func || extra_pass) { bpf_prog_fill_jited_linfo(fp, jit.addrs + 1); free_addrs: - kfree(jit.addrs); + kvfree(jit.addrs); kfree(jit_data); fp->aux->jit_data = NULL; } --- linux-oracle-5.4.0.orig/arch/s390/numa/numa.c +++ linux-oracle-5.4.0/arch/s390/numa/numa.c @@ -49,12 +49,6 @@ mode->update_cpu_topology(); } -int __node_distance(int a, int b) -{ - return mode->distance ? mode->distance(a, b) : 0; -} -EXPORT_SYMBOL(__node_distance); - int numa_debug_enabled; /* --- linux-oracle-5.4.0.orig/arch/s390/pci/Makefile +++ linux-oracle-5.4.0/arch/s390/pci/Makefile @@ -4,4 +4,5 @@ # obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_dma.o pci_clp.o pci_sysfs.o \ - pci_event.o pci_debug.o pci_insn.o pci_mmio.o + pci_event.o pci_debug.o pci_insn.o pci_mmio.o \ + pci_bus.o --- linux-oracle-5.4.0.orig/arch/s390/pci/pci.c +++ linux-oracle-5.4.0/arch/s390/pci/pci.c @@ -35,17 +35,21 @@ #include #include +#include "pci_bus.h" + /* list of all detected zpci devices */ static LIST_HEAD(zpci_list); static DEFINE_SPINLOCK(zpci_list_lock); -static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); +static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE); static DEFINE_SPINLOCK(zpci_domain_lock); #define ZPCI_IOMAP_ENTRIES \ min(((unsigned long) ZPCI_NR_DEVICES * PCI_BAR_COUNT / 2), \ ZPCI_IOMAP_MAX_ENTRIES) +unsigned int s390_pci_no_rid; + static DEFINE_SPINLOCK(zpci_iomap_lock); static unsigned long *zpci_iomap_bitmap; struct zpci_iomap_entry *zpci_iomap_start; @@ -86,17 +90,12 @@ spin_unlock(&zpci_list_lock); list_for_each_entry_safe(zdev, tmp, &remove, entry) - zpci_remove_device(zdev); -} - -static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) -{ - return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; + zpci_device_reserved(zdev); } int pci_domain_nr(struct pci_bus *bus) { - return ((struct zpci_dev *) bus->sysdata)->domain; + return ((struct zpci_bus *) bus->sysdata)->domain_nr; } EXPORT_SYMBOL_GPL(pci_domain_nr); @@ -223,7 +222,7 @@ /* combine single writes by using store-block insn */ void __iowrite64_copy(void __iomem *to, const void *from, size_t count) { - zpci_memcpy_toio(to, from, count); + zpci_memcpy_toio(to, from, count * 8); } void __iomem *ioremap(unsigned long ioaddr, unsigned long size) @@ -371,29 +370,17 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val) { - struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; + struct zpci_dev *zdev = get_zdev_by_bus(bus, devfn); - if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_load(zdev, where, val, size); - - return ret; + return (zdev) ? zpci_cfg_load(zdev, where, val, size) : -ENODEV; } static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { - struct zpci_dev *zdev = get_zdev_by_bus(bus); - int ret; + struct zpci_dev *zdev = get_zdev_by_bus(bus, devfn); - if (!zdev || devfn != ZPCI_DEVFN) - ret = -ENODEV; - else - ret = zpci_cfg_store(zdev, where, val, size); - - return ret; + return (zdev) ? zpci_cfg_store(zdev, where, val, size) : -ENODEV; } static struct pci_ops pci_root_ops = { @@ -423,7 +410,7 @@ if (zpci_use_mio(zdev)) pdev->resource[i].start = - (resource_size_t __force) zdev->bars[i].mio_wb; + (resource_size_t __force) zdev->bars[i].mio_wt; else pdev->resource[i].start = (resource_size_t __force) pci_iomap_range_fh(pdev, i, 0, 0); @@ -504,15 +491,15 @@ return r; } -static int zpci_setup_bus_resources(struct zpci_dev *zdev, - struct list_head *resources) +int zpci_setup_bus_resources(struct zpci_dev *zdev, + struct list_head *resources) { unsigned long addr, size, flags; struct resource *res; int i, entry; snprintf(zdev->res_name, sizeof(zdev->res_name), - "PCI Bus %04x:%02x", zdev->domain, ZPCI_BUS_NR); + "PCI Bus %04x:%02x", zdev->uid, ZPCI_BUS_NR); for (i = 0; i < PCI_BAR_COUNT; i++) { if (!zdev->bars[i].size) @@ -530,7 +517,7 @@ flags |= IORESOURCE_MEM_64; if (zpci_use_mio(zdev)) - addr = (unsigned long) zdev->bars[i].mio_wb; + addr = (unsigned long) zdev->bars[i].mio_wt; else addr = ZPCI_ADDR(entry); size = 1UL << zdev->bars[i].size; @@ -563,9 +550,12 @@ int pcibios_add_device(struct pci_dev *pdev) { + struct zpci_dev *zdev = to_zpci(pdev); struct resource *res; int i; + /* The pdev has a reference to the zdev via its bus */ + zpci_zdev_get(zdev); if (pdev->is_physfn) pdev->no_vf_scan = 1; @@ -585,7 +575,10 @@ void pcibios_release_device(struct pci_dev *pdev) { + struct zpci_dev *zdev = to_zpci(pdev); + zpci_unmap_resources(pdev); + zpci_zdev_put(zdev); } int pcibios_enable_device(struct pci_dev *pdev, int mask) @@ -649,86 +642,54 @@ }; #endif /* CONFIG_HIBERNATE_CALLBACKS */ -static int zpci_alloc_domain(struct zpci_dev *zdev) +static int __zpci_register_domain(int domain) { - if (zpci_unique_uid) { - zdev->domain = (u16) zdev->uid; - if (zdev->domain >= ZPCI_NR_DEVICES) - return 0; - - spin_lock(&zpci_domain_lock); - if (test_bit(zdev->domain, zpci_domain)) { - spin_unlock(&zpci_domain_lock); - return -EEXIST; - } - set_bit(zdev->domain, zpci_domain); - spin_unlock(&zpci_domain_lock); - return 0; - } - spin_lock(&zpci_domain_lock); - zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); - if (zdev->domain == ZPCI_NR_DEVICES) { + if (test_bit(domain, zpci_domain)) { spin_unlock(&zpci_domain_lock); - return -ENOSPC; + pr_err("Domain %04x is already assigned\n", domain); + return -EEXIST; } - set_bit(zdev->domain, zpci_domain); + set_bit(domain, zpci_domain); spin_unlock(&zpci_domain_lock); - return 0; + return domain; } -static void zpci_free_domain(struct zpci_dev *zdev) +static int __zpci_alloc_domain(void) { - if (zdev->domain >= ZPCI_NR_DEVICES) - return; + int domain; spin_lock(&zpci_domain_lock); - clear_bit(zdev->domain, zpci_domain); + /* + * We can always auto allocate domains below ZPCI_NR_DEVICES. + * There is either a free domain or we have reached the maximum in + * which case we would have bailed earlier. + */ + domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); + set_bit(domain, zpci_domain); spin_unlock(&zpci_domain_lock); + return domain; } -void pcibios_remove_bus(struct pci_bus *bus) +int zpci_alloc_domain(int domain) { - struct zpci_dev *zdev = get_zdev_by_bus(bus); - - zpci_exit_slot(zdev); - zpci_cleanup_bus_resources(zdev); - zpci_destroy_iommu(zdev); - zpci_free_domain(zdev); - - spin_lock(&zpci_list_lock); - list_del(&zdev->entry); - spin_unlock(&zpci_list_lock); - - zpci_dbg(3, "rem fid:%x\n", zdev->fid); - kfree(zdev); + if (zpci_unique_uid) { + if (domain) + return __zpci_register_domain(domain); + pr_warn("UID checking was active but no UID is provided: switching to automatic domain allocation\n"); + update_uid_checking(false); + } + return __zpci_alloc_domain(); } -static int zpci_scan_bus(struct zpci_dev *zdev) +void zpci_free_domain(int domain) { - LIST_HEAD(resources); - int ret; - - ret = zpci_setup_bus_resources(zdev, &resources); - if (ret) - goto error; - - zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, - zdev, &resources); - if (!zdev->bus) { - ret = -EIO; - goto error; - } - zdev->bus->max_bus_speed = zdev->max_bus_speed; - pci_bus_add_devices(zdev->bus); - return 0; - -error: - zpci_cleanup_bus_resources(zdev); - pci_free_resource_list(&resources); - return ret; + spin_lock(&zpci_domain_lock); + clear_bit(domain, zpci_domain); + spin_unlock(&zpci_domain_lock); } + int zpci_enable_device(struct zpci_dev *zdev) { int rc; @@ -754,21 +715,68 @@ int zpci_disable_device(struct zpci_dev *zdev) { zpci_dma_exit_device(zdev); + /* + * The zPCI function may already be disabled by the platform, this is + * detected in clp_disable_fh() which becomes a no-op. + */ return clp_disable_fh(zdev); } EXPORT_SYMBOL_GPL(zpci_disable_device); +bool zpci_is_device_configured(struct zpci_dev *zdev) +{ + enum zpci_state state = zdev->state; + + return state != ZPCI_FN_STATE_RESERVED && + state != ZPCI_FN_STATE_STANDBY; +} + +/* zpci_remove_device - Removes the given zdev from the PCI core + * @zdev: the zdev to be removed from the PCI core + * @set_error: if true the device's error state is set to permanent failure + * + * Sets a zPCI device to a configured but offline state; the zPCI + * device is still accessible through its hotplug slot and the zPCI + * API but is removed from the common code PCI bus, making it + * no longer available to drivers. + */ +void zpci_remove_device(struct zpci_dev *zdev, bool set_error) +{ + struct zpci_bus *zbus = zdev->zbus; + struct pci_dev *pdev; + + if (!zdev->zbus->bus) + return; + + pdev = pci_get_slot(zbus->bus, zdev->devfn); + if (pdev) { + if (set_error) + pdev->error_state = pci_channel_io_perm_failure; + if (pdev->is_virtfn) { + zpci_remove_virtfn(pdev, zdev->vfn); + /* balance pci_get_slot */ + pci_dev_put(pdev); + return; + } + pci_stop_and_remove_bus_device_locked(pdev); + /* balance pci_get_slot */ + pci_dev_put(pdev); + } +} + int zpci_create_device(struct zpci_dev *zdev) { int rc; - rc = zpci_alloc_domain(zdev); - if (rc) - goto out; + kref_init(&zdev->kref); + + spin_lock(&zpci_list_lock); + list_add_tail(&zdev->entry, &zpci_list); + spin_unlock(&zpci_list_lock); rc = zpci_init_iommu(zdev); if (rc) - goto out_free; + goto out; mutex_init(&zdev->lock); if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { @@ -776,36 +784,81 @@ if (rc) goto out_destroy_iommu; } - rc = zpci_scan_bus(zdev); + + rc = zpci_bus_device_register(zdev, &pci_root_ops); if (rc) goto out_disable; - spin_lock(&zpci_list_lock); - list_add_tail(&zdev->entry, &zpci_list); - spin_unlock(&zpci_list_lock); - - zpci_init_slot(zdev); - return 0; out_disable: if (zdev->state == ZPCI_FN_STATE_ONLINE) zpci_disable_device(zdev); + out_destroy_iommu: zpci_destroy_iommu(zdev); -out_free: - zpci_free_domain(zdev); out: + spin_lock(&zpci_list_lock); + list_del(&zdev->entry); + spin_unlock(&zpci_list_lock); return rc; } -void zpci_remove_device(struct zpci_dev *zdev) +/** + * zpci_device_reserved() - Mark device as resverved + * @zdev: the zpci_dev that was reserved + * + * Handle the case that a given zPCI function was reserved by another system. + * After a call to this function the zpci_dev can not be found via + * get_zdev_by_fid() anymore but may still be accessible via existing + * references though it will not be functional anymore. + */ +void zpci_device_reserved(struct zpci_dev *zdev) +{ + if (zdev->has_hp_slot) + zpci_exit_slot(zdev); + /* + * Remove device from zpci_list as it is going away. This also + * makes sure we ignore subsequent zPCI events for this device. + */ + spin_lock(&zpci_list_lock); + list_del(&zdev->entry); + spin_unlock(&zpci_list_lock); + zdev->state = ZPCI_FN_STATE_RESERVED; + zpci_dbg(3, "rsv fid:%x\n", zdev->fid); + zpci_zdev_put(zdev); +} + +void zpci_release_device(struct kref *kref) { - if (!zdev->bus) - return; + struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref); - pci_stop_root_bus(zdev->bus); - pci_remove_root_bus(zdev->bus); + if (zdev->zbus->bus) + zpci_remove_device(zdev, false); + + switch (zdev->state) { + case ZPCI_FN_STATE_ONLINE: + case ZPCI_FN_STATE_CONFIGURED: + zpci_disable_device(zdev); + fallthrough; + case ZPCI_FN_STATE_STANDBY: + if (zdev->has_hp_slot) + zpci_exit_slot(zdev); + spin_lock(&zpci_list_lock); + list_del(&zdev->entry); + spin_unlock(&zpci_list_lock); + zpci_dbg(3, "rsv fid:%x\n", zdev->fid); + fallthrough; + case ZPCI_FN_STATE_RESERVED: + zpci_cleanup_bus_resources(zdev); + zpci_bus_device_unregister(zdev); + zpci_destroy_iommu(zdev); + fallthrough; + default: + break; + } + zpci_dbg(3, "rem fid:%x\n", zdev->fid); + kfree(zdev); } int zpci_report_error(struct pci_dev *pdev, @@ -854,7 +907,6 @@ } static unsigned int s390_pci_probe __initdata = 1; -static unsigned int s390_pci_no_mio __initdata; unsigned int s390_pci_force_floating __initdata; static unsigned int s390_pci_initialized; @@ -865,13 +917,17 @@ return NULL; } if (!strcmp(str, "nomio")) { - s390_pci_no_mio = 1; + S390_lowcore.machine_flags &= ~MACHINE_FLAG_PCI_MIO; return NULL; } if (!strcmp(str, "force_floating")) { s390_pci_force_floating = 1; return NULL; } + if (!strcmp(str, "norid")) { + s390_pci_no_rid = 1; + return NULL; + } return str; } @@ -890,7 +946,7 @@ if (!test_facility(69) || !test_facility(71)) return 0; - if (test_facility(153) && !s390_pci_no_mio) { + if (MACHINE_HAS_PCI_MIO) { static_branch_enable(&have_mio); ctl_set_bit(2, 5); } @@ -934,5 +990,5 @@ void zpci_rescan(void) { if (zpci_is_enabled()) - clp_rescan_pci_devices_simple(); + clp_rescan_pci_devices_simple(NULL); } --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_bus.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_bus.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright IBM Corp. 2020 + * + * Author(s): + * Pierre Morel + * + */ + +#define KMSG_COMPONENT "zpci" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pci_bus.h" + +static LIST_HEAD(zbus_list); +static DEFINE_SPINLOCK(zbus_list_lock); +static int zpci_nb_devices; + +/* zpci_bus_scan + * @zbus: the zbus holding the zdevices + * @ops: the pci operations + * + * The domain number must be set before pci_scan_root_bus is called. + * This function can be called once the domain is known, hence + * when the function_0 is dicovered. + */ +static int zpci_bus_scan(struct zpci_bus *zbus, int domain, struct pci_ops *ops) +{ + struct pci_bus *bus; + int rc; + + rc = zpci_alloc_domain(domain); + if (rc < 0) + return rc; + zbus->domain_nr = rc; + + bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, ops, zbus, &zbus->resources); + if (!bus) { + zpci_free_domain(zbus->domain_nr); + return -EFAULT; + } + + zbus->bus = bus; + pci_bus_add_devices(bus); + return 0; +} + +static void zpci_bus_release(struct kref *kref) +{ + struct zpci_bus *zbus = container_of(kref, struct zpci_bus, kref); + + if (zbus->bus) { + pci_lock_rescan_remove(); + pci_stop_root_bus(zbus->bus); + + zpci_free_domain(zbus->domain_nr); + pci_free_resource_list(&zbus->resources); + + pci_remove_root_bus(zbus->bus); + pci_unlock_rescan_remove(); + } + + spin_lock(&zbus_list_lock); + list_del(&zbus->bus_next); + spin_unlock(&zbus_list_lock); + kfree(zbus); +} + +static void zpci_bus_put(struct zpci_bus *zbus) +{ + kref_put(&zbus->kref, zpci_bus_release); +} + +static struct zpci_bus *zpci_bus_get(int pchid) +{ + struct zpci_bus *zbus; + + spin_lock(&zbus_list_lock); + list_for_each_entry(zbus, &zbus_list, bus_next) { + if (pchid == zbus->pchid) { + kref_get(&zbus->kref); + goto out_unlock; + } + } + zbus = NULL; +out_unlock: + spin_unlock(&zbus_list_lock); + return zbus; +} + +static struct zpci_bus *zpci_bus_alloc(int pchid) +{ + struct zpci_bus *zbus; + + zbus = kzalloc(sizeof(*zbus), GFP_KERNEL); + if (!zbus) + return NULL; + + zbus->pchid = pchid; + INIT_LIST_HEAD(&zbus->bus_next); + spin_lock(&zbus_list_lock); + list_add_tail(&zbus->bus_next, &zbus_list); + spin_unlock(&zbus_list_lock); + + kref_init(&zbus->kref); + INIT_LIST_HEAD(&zbus->resources); + + return zbus; +} + +#ifdef CONFIG_PCI_IOV +static int zpci_bus_link_virtfn(struct pci_dev *pdev, + struct pci_dev *virtfn, int vfid) +{ + int rc; + + rc = pci_iov_sysfs_link(pdev, virtfn, vfid); + if (rc) + return rc; + + virtfn->is_virtfn = 1; + virtfn->multifunction = 0; + virtfn->physfn = pci_dev_get(pdev); + + return 0; +} + +static int zpci_bus_setup_virtfn(struct zpci_bus *zbus, + struct pci_dev *virtfn, int vfn) +{ + int i, cand_devfn; + struct zpci_dev *zdev; + struct pci_dev *pdev; + int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/ + int rc = 0; + + if (!zbus->multifunction) + return 0; + + /* If the parent PF for the given VF is also configured in the + * instance, it must be on the same zbus. + * We can then identify the parent PF by checking what + * devfn the VF would have if it belonged to that PF using the PF's + * stride and offset. Only if this candidate devfn matches the + * actual devfn will we link both functions. + */ + for (i = 0; i < ZPCI_FUNCTIONS_PER_BUS; i++) { + zdev = zbus->function[i]; + if (zdev && zdev->is_physfn) { + pdev = pci_get_slot(zbus->bus, zdev->devfn); + if (!pdev) + continue; + cand_devfn = pci_iov_virtfn_devfn(pdev, vfid); + if (cand_devfn == virtfn->devfn) { + rc = zpci_bus_link_virtfn(pdev, virtfn, vfid); + /* balance pci_get_slot() */ + pci_dev_put(pdev); + break; + } + /* balance pci_get_slot() */ + pci_dev_put(pdev); + } + } + return rc; +} +#else +static inline int zpci_bus_setup_virtfn(struct zpci_bus *zbus, + struct pci_dev *virtfn, int vfn) +{ + return 0; +} +#endif + +void pcibios_bus_add_device(struct pci_dev *pdev) +{ + struct zpci_dev *zdev = to_zpci(pdev); + + /* + * With pdev->no_vf_scan the common PCI probing code does not + * perform PF/VF linking. + */ + if (zdev->vfn) { + zpci_bus_setup_virtfn(zdev->zbus, pdev, zdev->vfn); + pdev->no_command_memory = 1; + } +} + +static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev) +{ + struct pci_bus *bus; + struct resource_entry *window, *n; + struct resource *res; + struct pci_dev *pdev; + int rc; + + bus = zbus->bus; + if (!bus) + return -EINVAL; + + pdev = pci_get_slot(bus, zdev->devfn); + if (pdev) { + /* Device is already known. */ + pci_dev_put(pdev); + return 0; + } + + rc = zpci_init_slot(zdev); + if (rc) + return rc; + zdev->has_hp_slot = 1; + + resource_list_for_each_entry_safe(window, n, &zbus->resources) { + res = window->res; + pci_bus_add_resource(bus, res, 0); + } + + pdev = pci_scan_single_device(bus, zdev->devfn); + if (pdev) + pci_bus_add_device(pdev); + + return 0; +} + +static void zpci_bus_add_devices(struct zpci_bus *zbus) +{ + int i; + + for (i = 1; i < ZPCI_FUNCTIONS_PER_BUS; i++) + if (zbus->function[i]) + zpci_bus_add_device(zbus, zbus->function[i]); + + pci_lock_rescan_remove(); + pci_bus_add_devices(zbus->bus); + pci_unlock_rescan_remove(); +} + +int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops) +{ + struct zpci_bus *zbus = NULL; + int rc = -EBADF; + + if (zpci_nb_devices == ZPCI_NR_DEVICES) { + pr_warn("Adding PCI function %08x failed because the configured limit of %d is reached\n", + zdev->fid, ZPCI_NR_DEVICES); + return -ENOSPC; + } + zpci_nb_devices++; + + if (zdev->devfn >= ZPCI_FUNCTIONS_PER_BUS) + return -EINVAL; + + if (!s390_pci_no_rid && zdev->rid_available) + zbus = zpci_bus_get(zdev->pchid); + + if (!zbus) { + zbus = zpci_bus_alloc(zdev->pchid); + if (!zbus) + return -ENOMEM; + } + + zdev->zbus = zbus; + if (zbus->function[zdev->devfn]) { + pr_err("devfn %04x is already assigned\n", zdev->devfn); + goto error; /* rc already set */ + } + zbus->function[zdev->devfn] = zdev; + + zpci_setup_bus_resources(zdev, &zbus->resources); + + if (zbus->bus) { + if (!zbus->multifunction) { + WARN_ONCE(1, "zbus is not multifunction\n"); + goto error_bus; + } + if (!zdev->rid_available) { + WARN_ONCE(1, "rid_available not set for multifunction\n"); + goto error_bus; + } + rc = zpci_bus_add_device(zbus, zdev); + if (rc) + goto error_bus; + } else if (zdev->devfn == 0) { + if (zbus->multifunction && !zdev->rid_available) { + WARN_ONCE(1, "rid_available not set on function 0 for multifunction\n"); + goto error_bus; + } + rc = zpci_bus_scan(zbus, (u16)zdev->uid, ops); + if (rc) + goto error_bus; + zpci_bus_add_devices(zbus); + rc = zpci_init_slot(zdev); + if (rc) + goto error_bus; + zdev->has_hp_slot = 1; + zbus->multifunction = zdev->rid_available; + zbus->max_bus_speed = zdev->max_bus_speed; + } else { + zbus->multifunction = 1; + } + + return 0; + +error_bus: + zpci_nb_devices--; + zbus->function[zdev->devfn] = NULL; +error: + pr_err("Adding PCI function %08x failed\n", zdev->fid); + zpci_bus_put(zbus); + return rc; +} + +void zpci_bus_device_unregister(struct zpci_dev *zdev) +{ + struct zpci_bus *zbus = zdev->zbus; + + zpci_nb_devices--; + zbus->function[zdev->devfn] = NULL; + zpci_bus_put(zbus); +} --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_bus.h +++ linux-oracle-5.4.0/arch/s390/pci/pci_bus.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright IBM Corp. 2020 + * + * Author(s): + * Pierre Morel + * + */ + +int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops); +void zpci_bus_device_unregister(struct zpci_dev *zdev); +int zpci_bus_init(void); + +void zpci_release_device(struct kref *kref); +static inline void zpci_zdev_put(struct zpci_dev *zdev) +{ + kref_put(&zdev->kref, zpci_release_device); +} + +static inline void zpci_zdev_get(struct zpci_dev *zdev) +{ + kref_get(&zdev->kref); +} + +int zpci_alloc_domain(int domain); +void zpci_free_domain(int domain); +int zpci_setup_bus_resources(struct zpci_dev *zdev, + struct list_head *resources); + +static inline struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus, + unsigned int devfn) +{ + struct zpci_bus *zbus = bus->sysdata; + + return (devfn >= ZPCI_FUNCTIONS_PER_BUS) ? NULL : zbus->function[devfn]; +} + +#ifdef CONFIG_PCI_IOV +static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn) +{ + + pci_lock_rescan_remove(); + /* Linux' vfid's start at 0 vfn at 1 */ + pci_iov_remove_virtfn(pdev->physfn, vfn - 1); + pci_unlock_rescan_remove(); +} +#else /* CONFIG_PCI_IOV */ +static inline void zpci_remove_virtfn(struct pci_dev *pdev, int vfn) {} +#endif /* CONFIG_PCI_IOV */ --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_clp.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_clp.c @@ -24,7 +24,7 @@ bool zpci_unique_uid; -static void update_uid_checking(bool new) +void update_uid_checking(bool new) { if (zpci_unique_uid != new) zpci_dbg(1, "uid checking:%d\n", new); @@ -155,8 +155,13 @@ zdev->pfgid = response->pfgid; zdev->pft = response->pft; zdev->vfn = response->vfn; + zdev->port = response->port; zdev->uid = response->uid; zdev->fmb_length = sizeof(u32) * response->fmb_len; + zdev->rid_available = response->rid_avail; + zdev->is_physfn = response->is_physfn; + if (!s390_pci_no_rid && zdev->rid_available) + zdev->devfn = response->rid & ZPCI_RID_MASK_DEVFN; memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip)); if (response->util_str_avail) { @@ -240,12 +245,14 @@ } /* - * Enable/Disable a given PCI function defined by its function handle. + * Enable/Disable a given PCI function and update its function handle if + * necessary */ -static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) +static int clp_set_pci_fn(struct zpci_dev *zdev, u8 nr_dma_as, u8 command) { struct clp_req_rsp_set_pci *rrb; int rc, retries = 100; + u32 fid = zdev->fid; rrb = clp_alloc_block(GFP_KERNEL); if (!rrb) @@ -256,7 +263,7 @@ rrb->request.hdr.len = sizeof(rrb->request); rrb->request.hdr.cmd = CLP_SET_PCI_FN; rrb->response.hdr.len = sizeof(rrb->response); - rrb->request.fh = *fh; + rrb->request.fh = zdev->fh; rrb->request.oc = command; rrb->request.ndas = nr_dma_as; @@ -269,12 +276,17 @@ } } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY); - if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) - *fh = rrb->response.fh; - else { + if (rc || rrb->response.hdr.rsp != CLP_RC_OK) { zpci_err("Set PCI FN:\n"); zpci_err_clp(rrb->response.hdr.rsp, rc); - rc = -EIO; + } + + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) { + zdev->fh = rrb->response.fh; + } else if (!rc && rrb->response.hdr.rsp == CLP_RC_SETPCIFN_ALRDY && + rrb->response.fh == 0) { + /* Function is already in desired state - update handle */ + rc = clp_rescan_pci_devices_simple(&fid); } clp_free_block(rrb); return rc; @@ -282,18 +294,17 @@ int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as) { - u32 fh = zdev->fh; int rc; - rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN); - zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc); + rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_PCI_FN); + zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); if (rc) goto out; - zdev->fh = fh; if (zpci_use_mio(zdev)) { - rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_MIO); - zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc); + rc = clp_set_pci_fn(zdev, nr_dma_as, CLP_SET_ENABLE_MIO); + zpci_dbg(3, "ena mio fid:%x, fh:%x, rc:%d\n", + zdev->fid, zdev->fh, rc); if (rc) clp_disable_fh(zdev); } @@ -303,17 +314,13 @@ int clp_disable_fh(struct zpci_dev *zdev) { - u32 fh = zdev->fh; int rc; if (!zdev_enabled(zdev)) return 0; - rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN); - zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, fh, rc); - if (!rc) - zdev->fh = fh; - + rc = clp_set_pci_fn(zdev, 0, CLP_SET_DISABLE_PCI_FN); + zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); return rc; } @@ -370,10 +377,14 @@ static void __clp_update(struct clp_fh_list_entry *entry, void *data) { struct zpci_dev *zdev; + u32 *fid = data; if (!entry->vendor_id) return; + if (fid && *fid != entry->fid) + return; + zdev = get_zdev_by_fid(entry->fid); if (!zdev) return; @@ -413,7 +424,10 @@ return rc; } -int clp_rescan_pci_devices_simple(void) +/* Rescan PCI functions and refresh function handles. If fid is non-NULL only + * refresh the handle of the function matching @fid + */ +int clp_rescan_pci_devices_simple(u32 *fid) { struct clp_req_rsp_list_pci *rrb; int rc; @@ -422,7 +436,7 @@ if (!rrb) return -ENOMEM; - rc = clp_list_pci(rrb, NULL, __clp_update); + rc = clp_list_pci(rrb, fid, __clp_update); clp_free_block(rrb); return rc; --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_dma.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_dma.c @@ -543,6 +543,17 @@ s->dma_length = 0; } } + +static unsigned long *bitmap_vzalloc(size_t bits, gfp_t flags) +{ + size_t n = BITS_TO_LONGS(bits); + size_t bytes; + + if (unlikely(check_mul_overflow(n, sizeof(unsigned long), &bytes))) + return NULL; + + return vzalloc(bytes); +} int zpci_dma_init_device(struct zpci_dev *zdev) { @@ -579,13 +590,13 @@ zdev->end_dma - zdev->start_dma + 1); zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; - zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); + zdev->iommu_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); if (!zdev->iommu_bitmap) { rc = -ENOMEM; goto free_dma_table; } if (!s390_iommu_strict) { - zdev->lazy_bitmap = vzalloc(zdev->iommu_pages / 8); + zdev->lazy_bitmap = bitmap_vzalloc(zdev->iommu_pages, GFP_KERNEL); if (!zdev->lazy_bitmap) { rc = -ENOMEM; goto free_bitmap; --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_event.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_event.c @@ -14,6 +14,8 @@ #include #include +#include "pci_bus.h" + /* Content Code Description for PCI Function Error */ struct zpci_ccdf_err { u32 reserved1; @@ -53,7 +55,7 @@ zpci_err_hex(ccdf, sizeof(*ccdf)); if (zdev) - pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN); + pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); pr_err("%s: Event 0x%x reports an error for PCI function 0x%x\n", pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); @@ -74,46 +76,52 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) { struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); - struct pci_dev *pdev = NULL; enum zpci_state state; + struct pci_dev *pdev; int ret; - if (zdev) - pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN); - - pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n", - pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid); zpci_err("avail CCDF:\n"); zpci_err_hex(ccdf, sizeof(*ccdf)); switch (ccdf->pec) { case 0x0301: /* Reserved|Standby -> Configured */ if (!zdev) { - ret = clp_add_pci_device(ccdf->fid, ccdf->fh, 0); - if (ret) - break; - zdev = get_zdev_by_fid(ccdf->fid); + ret = clp_add_pci_device(ccdf->fid, ccdf->fh, 1); + break; } - if (!zdev || zdev->state != ZPCI_FN_STATE_STANDBY) + /* the configuration request may be stale */ + if (zdev->state != ZPCI_FN_STATE_STANDBY) break; - zdev->state = ZPCI_FN_STATE_CONFIGURED; zdev->fh = ccdf->fh; + zdev->state = ZPCI_FN_STATE_CONFIGURED; ret = zpci_enable_device(zdev); if (ret) break; + + /* the PCI function will be scanned once function 0 appears */ + if (!zdev->zbus->bus) + break; + + pdev = pci_scan_single_device(zdev->zbus->bus, zdev->devfn); + if (!pdev) + break; + + pci_bus_add_device(pdev); pci_lock_rescan_remove(); - pci_rescan_bus(zdev->bus); + pci_bus_add_devices(zdev->zbus->bus); pci_unlock_rescan_remove(); break; case 0x0302: /* Reserved -> Standby */ - if (!zdev) + if (!zdev) { clp_add_pci_device(ccdf->fid, ccdf->fh, 0); + break; + } + zdev->fh = ccdf->fh; break; case 0x0303: /* Deconfiguration requested */ if (!zdev) break; - if (pdev) - pci_stop_and_remove_bus_device_locked(pdev); + zpci_remove_device(zdev, false); ret = zpci_disable_device(zdev); if (ret) @@ -128,19 +136,17 @@ case 0x0304: /* Configured -> Standby|Reserved */ if (!zdev) break; - if (pdev) { - /* Give the driver a hint that the function is - * already unusable. */ - pdev->error_state = pci_channel_io_perm_failure; - pci_stop_and_remove_bus_device_locked(pdev); - } + /* Give the driver a hint that the function is + * already unusable. + */ + zpci_remove_device(zdev, true); zdev->fh = ccdf->fh; zpci_disable_device(zdev); zdev->state = ZPCI_FN_STATE_STANDBY; if (!clp_get_state(ccdf->fid, &state) && state == ZPCI_FN_STATE_RESERVED) { - zpci_remove_device(zdev); + zpci_device_reserved(zdev); } break; case 0x0306: /* 0x308 or 0x302 for multiple devices */ @@ -149,12 +155,11 @@ case 0x0308: /* Standby -> Reserved */ if (!zdev) break; - zpci_remove_device(zdev); + zpci_device_reserved(zdev); break; default: break; } - pci_dev_put(pdev); } void zpci_event_availability(void *data) --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_irq.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_irq.c @@ -115,7 +115,6 @@ .name = "PCI-MSI", .irq_unmask = pci_msi_unmask_irq, .irq_mask = pci_msi_mask_irq, - .irq_set_affinity = zpci_set_irq_affinity, }; static void zpci_handle_cpu_local_irq(bool rescan) @@ -276,7 +275,9 @@ rc = -EIO; if (hwirq - bit >= msi_vecs) break; - irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, msi->affinity); + irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, + (irq_delivery == DIRECTED) ? + msi->affinity : NULL); if (irq < 0) return -ENOMEM; rc = irq_set_msi_desc(irq, msi); --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_mmio.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_mmio.c @@ -11,6 +11,113 @@ #include #include #include +#include +#include + +static inline void zpci_err_mmio(u8 cc, u8 status, u64 offset) +{ + struct { + u64 offset; + u8 cc; + u8 status; + } data = {offset, cc, status}; + + zpci_err_hex(&data, sizeof(data)); +} + +static inline int __pcistb_mio_inuser( + void __iomem *ioaddr, const void __user *src, + u64 len, u8 *status) +{ + int cc = -ENXIO; + + asm volatile ( + " sacf 256\n" + "0: .insn rsy,0xeb00000000d4,%[len],%[ioaddr],%[src]\n" + "1: ipm %[cc]\n" + " srl %[cc],28\n" + "2: sacf 768\n" + EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) + : [cc] "+d" (cc), [len] "+d" (len) + : [ioaddr] "a" (ioaddr), [src] "Q" (*((u8 __force *)src)) + : "cc", "memory"); + *status = len >> 24 & 0xff; + return cc; +} + +static inline int __pcistg_mio_inuser( + void __iomem *ioaddr, const void __user *src, + u64 ulen, u8 *status) +{ + register u64 addr asm("2") = (u64 __force) ioaddr; + register u64 len asm("3") = ulen; + int cc = -ENXIO; + u64 val = 0; + u64 cnt = ulen; + u8 tmp; + + /* + * copy 0 < @len <= 8 bytes from @src into the right most bytes of + * a register, then store it to PCI at @ioaddr while in secondary + * address space. pcistg then uses the user mappings. + */ + asm volatile ( + " sacf 256\n" + "0: llgc %[tmp],0(%[src])\n" + "4: sllg %[val],%[val],8\n" + " aghi %[src],1\n" + " ogr %[val],%[tmp]\n" + " brctg %[cnt],0b\n" + "1: .insn rre,0xb9d40000,%[val],%[ioaddr]\n" + "2: ipm %[cc]\n" + " srl %[cc],28\n" + "3: sacf 768\n" + EX_TABLE(0b, 3b) EX_TABLE(4b, 3b) EX_TABLE(1b, 3b) EX_TABLE(2b, 3b) + : + [src] "+a" (src), [cnt] "+d" (cnt), + [val] "+d" (val), [tmp] "=d" (tmp), + [len] "+d" (len), [cc] "+d" (cc), + [ioaddr] "+a" (addr) + :: "cc", "memory"); + *status = len >> 24 & 0xff; + + /* did we read everything from user memory? */ + if (!cc && cnt != 0) + cc = -EFAULT; + + return cc; +} + +static inline int __memcpy_toio_inuser(void __iomem *dst, + const void __user *src, size_t n) +{ + int size, rc = 0; + u8 status = 0; + mm_segment_t old_fs; + + if (!src) + return -EINVAL; + + old_fs = enable_sacf_uaccess(); + while (n > 0) { + size = zpci_get_max_io_size((u64 __force) dst, + (u64 __force) src, n, + ZPCI_MAX_WRITE_SIZE); + if (size > 8) /* main path */ + rc = __pcistb_mio_inuser(dst, src, size, &status); + else + rc = __pcistg_mio_inuser(dst, src, size, &status); + if (rc) + break; + src += size; + dst += size; + n -= size; + } + disable_sacf_uaccess(old_fs); + if (rc) + zpci_err_mmio(rc, status, (__force u64) dst); + return rc; +} static long get_pfn(unsigned long user_addr, unsigned long access, unsigned long *pfn) @@ -21,7 +128,7 @@ down_read(¤t->mm->mmap_sem); ret = -EINVAL; vma = find_vma(current->mm, user_addr); - if (!vma) + if (!vma || user_addr < vma->vm_start) goto out; ret = -EACCES; if (!(vma->vm_flags & access)) @@ -46,6 +153,20 @@ if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) return -EINVAL; + + /* + * Only support read access to MIO capable devices on a MIO enabled + * system. Otherwise we would have to check for every address if it is + * a special ZPCI_ADDR and we would have to do a get_pfn() which we + * don't need for MIO capable devices. + */ + if (static_branch_likely(&have_mio)) { + ret = __memcpy_toio_inuser((void __iomem *) mmio_addr, + user_buffer, + length); + return ret; + } + if (length > 64) { buf = kmalloc(length, GFP_KERNEL); if (!buf) @@ -56,7 +177,8 @@ ret = get_pfn(mmio_addr, VM_WRITE, &pfn); if (ret) goto out; - io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); + io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | + (mmio_addr & ~PAGE_MASK)); ret = -EFAULT; if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) @@ -72,6 +194,78 @@ return ret; } +static inline int __pcilg_mio_inuser( + void __user *dst, const void __iomem *ioaddr, + u64 ulen, u8 *status) +{ + register u64 addr asm("2") = (u64 __force) ioaddr; + register u64 len asm("3") = ulen; + u64 cnt = ulen; + int shift = ulen * 8; + int cc = -ENXIO; + u64 val, tmp; + + /* + * read 0 < @len <= 8 bytes from the PCI memory mapped at @ioaddr (in + * user space) into a register using pcilg then store these bytes at + * user address @dst + */ + asm volatile ( + " sacf 256\n" + "0: .insn rre,0xb9d60000,%[val],%[ioaddr]\n" + "1: ipm %[cc]\n" + " srl %[cc],28\n" + " ltr %[cc],%[cc]\n" + " jne 4f\n" + "2: ahi %[shift],-8\n" + " srlg %[tmp],%[val],0(%[shift])\n" + "3: stc %[tmp],0(%[dst])\n" + "5: aghi %[dst],1\n" + " brctg %[cnt],2b\n" + "4: sacf 768\n" + EX_TABLE(0b, 4b) EX_TABLE(1b, 4b) EX_TABLE(3b, 4b) EX_TABLE(5b, 4b) + : + [cc] "+d" (cc), [val] "=d" (val), [len] "+d" (len), + [dst] "+a" (dst), [cnt] "+d" (cnt), [tmp] "=d" (tmp), + [shift] "+d" (shift) + : + [ioaddr] "a" (addr) + : "cc", "memory"); + + /* did we write everything to the user space buffer? */ + if (!cc && cnt != 0) + cc = -EFAULT; + + *status = len >> 24 & 0xff; + return cc; +} + +static inline int __memcpy_fromio_inuser(void __user *dst, + const void __iomem *src, + unsigned long n) +{ + int size, rc = 0; + u8 status; + mm_segment_t old_fs; + + old_fs = enable_sacf_uaccess(); + while (n > 0) { + size = zpci_get_max_io_size((u64 __force) src, + (u64 __force) dst, n, + ZPCI_MAX_READ_SIZE); + rc = __pcilg_mio_inuser(dst, src, size, &status); + if (rc) + break; + src += size; + dst += size; + n -= size; + } + disable_sacf_uaccess(old_fs); + if (rc) + zpci_err_mmio(rc, status, (__force u64) dst); + return rc; +} + SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, void __user *, user_buffer, size_t, length) { @@ -86,12 +280,27 @@ if (length <= 0 || PAGE_SIZE - (mmio_addr & ~PAGE_MASK) < length) return -EINVAL; + + /* + * Only support write access to MIO capable devices on a MIO enabled + * system. Otherwise we would have to check for every address if it is + * a special ZPCI_ADDR and we would have to do a get_pfn() which we + * don't need for MIO capable devices. + */ + if (static_branch_likely(&have_mio)) { + ret = __memcpy_fromio_inuser( + user_buffer, (const void __iomem *)mmio_addr, + length); + return ret; + } + if (length > 64) { buf = kmalloc(length, GFP_KERNEL); if (!buf) return -ENOMEM; - } else + } else { buf = local_buf; + } ret = get_pfn(mmio_addr, VM_READ, &pfn); if (ret) --- linux-oracle-5.4.0.orig/arch/s390/pci/pci_sysfs.c +++ linux-oracle-5.4.0/arch/s390/pci/pci_sysfs.c @@ -13,6 +13,8 @@ #include #include +#include "../../../drivers/pci/pci.h" + #include #define zpci_attr(name, fmt, member) \ @@ -31,6 +33,7 @@ zpci_attr(pfgid, "0x%02x\n", pfgid); zpci_attr(vfn, "0x%04x\n", vfn); zpci_attr(pft, "0x%02x\n", pft); +zpci_attr(port, "%d\n", port); zpci_attr(uid, "0x%x\n", uid); zpci_attr(segment0, "0x%02x\n", pfip[0]); zpci_attr(segment1, "0x%02x\n", pfip[1]); @@ -49,31 +52,50 @@ static ssize_t recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct kernfs_node *kn; struct pci_dev *pdev = to_pci_dev(dev); struct zpci_dev *zdev = to_zpci(pdev); - int ret; - - if (!device_remove_file_self(dev, attr)) - return count; + int ret = 0; + /* Can't use device_remove_self() here as that would lead us to lock + * the pci_rescan_remove_lock while holding the device' kernfs lock. + * This would create a possible deadlock with disable_slot() which is + * not directly protected by the device' kernfs lock but takes it + * during the device removal which happens under + * pci_rescan_remove_lock. + * + * This is analogous to sdev_store_delete() in + * drivers/scsi/scsi_sysfs.c + */ + kn = sysfs_break_active_protection(&dev->kobj, &attr->attr); + WARN_ON_ONCE(!kn); + /* device_remove_file() serializes concurrent calls ignoring all but + * the first + */ + device_remove_file(dev, attr); + + /* A concurrent call to recover_store() may slip between + * sysfs_break_active_protection() and the sysfs file removal. + * Once it unblocks from pci_lock_rescan_remove() the original pdev + * will already be removed. + */ pci_lock_rescan_remove(); - pci_stop_and_remove_bus_device(pdev); - ret = zpci_disable_device(zdev); - if (ret) - goto error; - - ret = zpci_enable_device(zdev); - if (ret) - goto error; - - pci_rescan_bus(zdev->bus); + if (pci_dev_is_added(pdev)) { + pci_stop_and_remove_bus_device(pdev); + ret = zpci_disable_device(zdev); + if (ret) + goto out; + + ret = zpci_enable_device(zdev); + if (ret) + goto out; + pci_rescan_bus(zdev->zbus->bus); + } +out: pci_unlock_rescan_remove(); - - return count; - -error: - pci_unlock_rescan_remove(); - return ret; + if (kn) + sysfs_unbreak_active_protection(kn); + return ret ? ret : count; } static DEVICE_ATTR_WO(recover); @@ -121,6 +143,7 @@ &dev_attr_pchid.attr, &dev_attr_pfgid.attr, &dev_attr_pft.attr, + &dev_attr_port.attr, &dev_attr_vfn.attr, &dev_attr_uid.attr, &dev_attr_recover.attr, --- linux-oracle-5.4.0.orig/arch/s390/purgatory/Makefile +++ linux-oracle-5.4.0/arch/s390/purgatory/Makefile @@ -15,8 +15,10 @@ $(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE $(call if_changed_rule,as_o_S) -$(obj)/string.o: $(srctree)/arch/s390/lib/string.c FORCE - $(call if_changed_rule,cc_o_c) +KCOV_INSTRUMENT := n +GCOV_PROFILE := n +UBSAN_SANITIZE := n +KASAN_SANITIZE := n KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare --- linux-oracle-5.4.0.orig/arch/s390/purgatory/head.S +++ linux-oracle-5.4.0/arch/s390/purgatory/head.S @@ -62,14 +62,15 @@ jh 10b .endm -.macro START_NEXT_KERNEL base +.macro START_NEXT_KERNEL base subcode lg %r4,kernel_entry-\base(%r13) lg %r5,load_psw_mask-\base(%r13) ogr %r4,%r5 stg %r4,0(%r0) xgr %r0,%r0 - diag %r0,%r0,0x308 + lghi %r1,\subcode + diag %r0,%r1,0x308 .endm .text @@ -123,7 +124,7 @@ je .start_crash_kernel /* start normal kernel */ - START_NEXT_KERNEL .base_crash + START_NEXT_KERNEL .base_crash 0 .return_old_kernel: lmg %r6,%r15,gprregs-.base_crash(%r13) @@ -227,7 +228,7 @@ MEMCPY %r9,%r10,%r11 /* start crash kernel */ - START_NEXT_KERNEL .base_dst + START_NEXT_KERNEL .base_dst 1 load_psw_mask: --- linux-oracle-5.4.0.orig/arch/s390/purgatory/string.c +++ linux-oracle-5.4.0/arch/s390/purgatory/string.c @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 +#define __HAVE_ARCH_MEMCMP /* arch function */ +#include "../lib/string.c" --- linux-oracle-5.4.0.orig/arch/sh/Kconfig +++ linux-oracle-5.4.0/arch/sh/Kconfig @@ -2,6 +2,7 @@ config SUPERH def_bool y select ARCH_HAS_BINFMT_FLAT if !MMU + select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_MIGHT_HAVE_PC_PARPORT @@ -9,7 +10,6 @@ select CLKDEV_LOOKUP select DMA_DECLARE_COHERENT select HAVE_IDE if HAS_IOPORT_MAP - select HAVE_MEMBLOCK_NODE_MAP select HAVE_OPROFILE select HAVE_ARCH_TRACEHOOK select HAVE_PERF_EVENTS --- linux-oracle-5.4.0.orig/arch/sh/Kconfig.debug +++ linux-oracle-5.4.0/arch/sh/Kconfig.debug @@ -26,6 +26,17 @@ every function call and will therefore incur a major performance hit. Most users should say N. +config EARLY_PRINTK + bool "Early printk" + depends on SH_STANDARD_BIOS + help + Say Y here to redirect kernel printk messages to the serial port + used by the SH-IPL bootloader, starting very early in the boot + process and ending when the kernel's serial console is initialised. + This option is only useful while porting the kernel to a new machine, + when the kernel may crash or hang before the serial console is + initialised. If unsure, say N. + config 4KSTACKS bool "Use 4Kb for kernel stacks instead of 8Kb" depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB @@ -58,6 +69,7 @@ config DWARF_UNWINDER bool "Enable the DWARF unwinder for stacktraces" + depends on DEBUG_KERNEL select FRAME_POINTER depends on SUPERH32 default n --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-ap325rxa/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-ap325rxa/setup.c @@ -529,7 +529,7 @@ device_initialize(&ap325rxa_ceu_device.dev); dma_declare_coherent_memory(&ap325rxa_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&ap325rxa_ceu_device); --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-ecovec24/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-ecovec24/setup.c @@ -1442,15 +1442,13 @@ device_initialize(&ecovec_ceu_devices[0]->dev); dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ecovec_ceu_devices[0]); device_initialize(&ecovec_ceu_devices[1]->dev); dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ecovec_ceu_devices[1]); gpiod_add_lookup_table(&cn12_power_gpiod_table); --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-kfr2r09/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-kfr2r09/setup.c @@ -603,7 +603,7 @@ device_initialize(&kfr2r09_ceu_device.dev); dma_declare_coherent_memory(&kfr2r09_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&kfr2r09_ceu_device); --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-landisk/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-landisk/setup.c @@ -82,6 +82,9 @@ static void __init landisk_setup(char **cmdline_p) { + /* I/O port identity mapping */ + __set_io_port_base(0); + /* LED ON */ __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED); --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-migor/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-migor/setup.c @@ -604,7 +604,7 @@ device_initialize(&migor_ceu_device.dev); dma_declare_coherent_memory(&migor_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&migor_ceu_device); --- linux-oracle-5.4.0.orig/arch/sh/boards/mach-se/7724/setup.c +++ linux-oracle-5.4.0/arch/sh/boards/mach-se/7724/setup.c @@ -939,15 +939,13 @@ device_initialize(&ms7724se_ceu_devices[0]->dev); dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ms7724se_ceu_devices[0]); device_initialize(&ms7724se_ceu_devices[1]->dev); dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ms7724se_ceu_devices[1]); return platform_add_devices(ms7724se_devices, --- linux-oracle-5.4.0.orig/arch/sh/configs/sh03_defconfig +++ linux-oracle-5.4.0/arch/sh/configs/sh03_defconfig @@ -46,7 +46,6 @@ CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y --- linux-oracle-5.4.0.orig/arch/sh/drivers/dma/Kconfig +++ linux-oracle-5.4.0/arch/sh/drivers/dma/Kconfig @@ -63,8 +63,7 @@ config G2_DMA tristate "G2 Bus DMA support" - depends on SH_DREAMCAST - select SH_DMA_API + depends on SH_DREAMCAST && SH_DMA_API help This enables support for the DMA controller for the Dreamcast's G2 bus. Drivers that want this will generally enable this on --- linux-oracle-5.4.0.orig/arch/sh/drivers/dma/dma-sh.c +++ linux-oracle-5.4.0/arch/sh/drivers/dma/dma-sh.c @@ -19,6 +19,18 @@ #include /* + * Some of the SoCs feature two DMAC modules. In such a case, the channels are + * distributed equally among them. + */ +#ifdef SH_DMAC_BASE1 +#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2) +#else +#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS +#endif + +#define SH_DMAC_CH_SZ 0x10 + +/* * Define the default configuration for dual address memory-memory transfer. * The 0x400 value represents auto-request, external->external. */ @@ -29,7 +41,7 @@ unsigned long base = SH_DMAC_BASE0; #ifdef SH_DMAC_BASE1 - if (chan >= 6) + if (chan >= SH_DMAC_NR_MD_CH) base = SH_DMAC_BASE1; #endif @@ -40,13 +52,13 @@ { unsigned long base = dma_find_base(chan); - /* Normalize offset calculation */ - if (chan >= 9) - chan -= 6; - if (chan >= 4) - base += 0x10; + chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ; + + /* DMAOR is placed inside the channel register space. Step over it. */ + if (chan >= DMAOR) + base += SH_DMAC_CH_SZ; - return base + (chan * 0x10); + return base + chan; } #ifdef CONFIG_SH_DMA_IRQ_MULTI @@ -250,12 +262,11 @@ #define NR_DMAOR 1 #endif -/* - * DMAOR bases are broken out amongst channel groups. DMAOR0 manages - * channels 0 - 5, DMAOR1 6 - 11 (optional). - */ -#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) -#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6) +#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR) +#define dmaor_write_reg(n, data) __raw_writew(data, \ + dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR) static inline int dmaor_reset(int no) { --- linux-oracle-5.4.0.orig/arch/sh/drivers/push-switch.c +++ linux-oracle-5.4.0/arch/sh/drivers/push-switch.c @@ -101,8 +101,8 @@ device_remove_file(&pdev->dev, &dev_attr_switch); platform_set_drvdata(pdev, NULL); - flush_work(&psw->work); del_timer_sync(&psw->debounce); + flush_work(&psw->work); free_irq(irq, pdev); kfree(psw); --- linux-oracle-5.4.0.orig/arch/sh/include/asm/pgalloc.h +++ linux-oracle-5.4.0/arch/sh/include/asm/pgalloc.h @@ -12,6 +12,7 @@ extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd); extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address); extern void pmd_free(struct mm_struct *mm, pmd_t *pmd); +#define __pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, (pmdp)) #endif static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, @@ -33,13 +34,4 @@ tlb_remove_page((tlb), (pte)); \ } while (0) -#if CONFIG_PGTABLE_LEVELS > 2 -#define __pmd_free_tlb(tlb, pmdp, addr) \ -do { \ - struct page *page = virt_to_page(pmdp); \ - pgtable_pmd_page_dtor(page); \ - tlb_remove_page((tlb), page); \ -} while (0); -#endif - #endif /* __ASM_SH_PGALLOC_H */ --- linux-oracle-5.4.0.orig/arch/sh/include/asm/processor.h +++ linux-oracle-5.4.0/arch/sh/include/asm/processor.h @@ -173,6 +173,8 @@ #define instruction_size(insn) (4) #endif +void select_idle_routine(void); + #endif /* __ASSEMBLY__ */ #ifdef CONFIG_SUPERH32 --- linux-oracle-5.4.0.orig/arch/sh/include/asm/processor_32.h +++ linux-oracle-5.4.0/arch/sh/include/asm/processor_32.h @@ -51,6 +51,7 @@ #define SR_FD 0x00008000 #define SR_MD 0x40000000 +#define SR_USER_MASK 0x00000303 // M, Q, S, T bits /* * DSP structure and data */ --- linux-oracle-5.4.0.orig/arch/sh/include/asm/sections.h +++ linux-oracle-5.4.0/arch/sh/include/asm/sections.h @@ -4,7 +4,7 @@ #include -extern long __machvec_start, __machvec_end; +extern char __machvec_start[], __machvec_end[]; extern char __uncached_start, __uncached_end; extern char __start_eh_frame[], __stop_eh_frame[]; --- linux-oracle-5.4.0.orig/arch/sh/include/asm/sfp-machine.h +++ linux-oracle-5.4.0/arch/sh/include/asm/sfp-machine.h @@ -13,6 +13,14 @@ #ifndef _SFP_MACHINE_H #define _SFP_MACHINE_H +#ifdef __BIG_ENDIAN__ +#define __BYTE_ORDER __BIG_ENDIAN +#define __LITTLE_ENDIAN 0 +#else +#define __BYTE_ORDER __LITTLE_ENDIAN +#define __BIG_ENDIAN 0 +#endif + #define _FP_W_TYPE_SIZE 32 #define _FP_W_TYPE unsigned long #define _FP_WS_TYPE signed long --- linux-oracle-5.4.0.orig/arch/sh/include/cpu-sh2a/cpu/sh7269.h +++ linux-oracle-5.4.0/arch/sh/include/cpu-sh2a/cpu/sh7269.h @@ -78,8 +78,15 @@ GPIO_FN_WDTOVF, /* CAN */ - GPIO_FN_CTX1, GPIO_FN_CRX1, GPIO_FN_CTX0, GPIO_FN_CTX0_CTX1, - GPIO_FN_CRX0, GPIO_FN_CRX0_CRX1, GPIO_FN_CRX0_CRX1_CRX2, + GPIO_FN_CTX2, GPIO_FN_CRX2, + GPIO_FN_CTX1, GPIO_FN_CRX1, + GPIO_FN_CTX0, GPIO_FN_CRX0, + GPIO_FN_CTX0_CTX1, GPIO_FN_CRX0_CRX1, + GPIO_FN_CTX0_CTX1_CTX2, GPIO_FN_CRX0_CRX1_CRX2, + GPIO_FN_CTX2_PJ21, GPIO_FN_CRX2_PJ20, + GPIO_FN_CTX1_PJ23, GPIO_FN_CRX1_PJ22, + GPIO_FN_CTX0_CTX1_PJ23, GPIO_FN_CRX0_CRX1_PJ22, + GPIO_FN_CTX0_CTX1_CTX2_PJ21, GPIO_FN_CRX0_CRX1_CRX2_PJ20, /* DMAC */ GPIO_FN_TEND0, GPIO_FN_DACK0, GPIO_FN_DREQ0, --- linux-oracle-5.4.0.orig/arch/sh/include/cpu-sh4/cpu/sh7734.h +++ linux-oracle-5.4.0/arch/sh/include/cpu-sh4/cpu/sh7734.h @@ -134,7 +134,7 @@ GPIO_FN_EX_WAIT1, GPIO_FN_SD1_DAT0_A, GPIO_FN_DREQ2, GPIO_FN_CAN1_TX_C, GPIO_FN_ET0_LINK_C, GPIO_FN_ET0_ETXD5_A, GPIO_FN_EX_WAIT0, GPIO_FN_TCLK1_B, - GPIO_FN_RD_WR, GPIO_FN_TCLK0, + GPIO_FN_RD_WR, GPIO_FN_TCLK0, GPIO_FN_CAN_CLK_B, GPIO_FN_ET0_ETXD4, GPIO_FN_EX_CS5, GPIO_FN_SD1_CMD_A, GPIO_FN_ATADIR, GPIO_FN_QSSL_B, GPIO_FN_ET0_ETXD3_A, GPIO_FN_EX_CS4, GPIO_FN_SD1_WP_A, GPIO_FN_ATAWR, GPIO_FN_QMI_QIO1_B, --- linux-oracle-5.4.0.orig/arch/sh/kernel/cpu/fpu.c +++ linux-oracle-5.4.0/arch/sh/kernel/cpu/fpu.c @@ -62,18 +62,20 @@ } if (!tsk_used_math(tsk)) { - local_irq_enable(); + int ret; /* * does a slab alloc which can sleep */ - if (init_fpu(tsk)) { + local_irq_enable(); + ret = init_fpu(tsk); + local_irq_disable(); + if (ret) { /* * ran out of memory! */ - do_group_exit(SIGKILL); + force_sig(SIGKILL); return; } - local_irq_disable(); } grab_fpu(regs); --- linux-oracle-5.4.0.orig/arch/sh/kernel/cpu/proc.c +++ linux-oracle-5.4.0/arch/sh/kernel/cpu/proc.c @@ -133,7 +133,7 @@ static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < NR_CPUS ? cpu_data + *pos : NULL; + return *pos < nr_cpu_ids ? cpu_data + *pos : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) { --- linux-oracle-5.4.0.orig/arch/sh/kernel/cpu/sh2/probe.c +++ linux-oracle-5.4.0/arch/sh/kernel/cpu/sh2/probe.c @@ -21,7 +21,7 @@ if (!of_flat_dt_is_compatible(node, "jcore,cache")) return 0; - j2_ccr_base = (u32 __iomem *)of_flat_dt_translate_address(node); + j2_ccr_base = ioremap(of_flat_dt_translate_address(node), 4); return 1; } --- linux-oracle-5.4.0.orig/arch/sh/kernel/cpu/sh4/sq.c +++ linux-oracle-5.4.0/arch/sh/kernel/cpu/sh4/sq.c @@ -380,7 +380,7 @@ if (unlikely(!sq_cache)) return ret; - sq_bitmap = kzalloc(size, GFP_KERNEL); + sq_bitmap = kcalloc(size, sizeof(long), GFP_KERNEL); if (unlikely(!sq_bitmap)) goto out; --- linux-oracle-5.4.0.orig/arch/sh/kernel/cpu/sh4a/smp-shx3.c +++ linux-oracle-5.4.0/arch/sh/kernel/cpu/sh4a/smp-shx3.c @@ -73,8 +73,9 @@ BUILD_BUG_ON(SMP_MSG_NR >= 8); for (i = 0; i < SMP_MSG_NR; i++) - request_irq(104 + i, ipi_interrupt_handler, - IRQF_PERCPU, "IPI", (void *)(long)i); + if (request_irq(104 + i, ipi_interrupt_handler, + IRQF_PERCPU, "IPI", (void *)(long)i)) + pr_err("Failed to request irq %d\n", i); for (i = 0; i < max_cpus; i++) set_cpu_present(i, true); --- linux-oracle-5.4.0.orig/arch/sh/kernel/dma-coherent.c +++ linux-oracle-5.4.0/arch/sh/kernel/dma-coherent.c @@ -25,7 +25,7 @@ * Pages from the page allocator may have data present in * cache. So flush the cache before using uncached memory. */ - arch_sync_dma_for_device(dev, virt_to_phys(ret), size, + arch_sync_dma_for_device(virt_to_phys(ret), size, DMA_BIDIRECTIONAL); ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size); @@ -59,8 +59,8 @@ iounmap(vaddr); } -void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { void *addr = sh_cacheop_vaddr(phys_to_virt(paddr)); --- linux-oracle-5.4.0.orig/arch/sh/kernel/entry-common.S +++ linux-oracle-5.4.0/arch/sh/kernel/entry-common.S @@ -199,7 +199,7 @@ mov.l @(OFF_R7,r15), r7 ! arg3 mov.l @(OFF_R3,r15), r3 ! syscall_nr ! - mov.l 2f, r10 ! Number of syscalls + mov.l 6f, r10 ! Number of syscalls cmp/hs r10, r3 bf syscall_call mov #-ENOSYS, r0 @@ -353,7 +353,7 @@ tst r9, r8 bf syscall_trace_entry ! - mov.l 2f, r8 ! Number of syscalls + mov.l 6f, r8 ! Number of syscalls cmp/hs r8, r3 bt syscall_badsys ! @@ -392,7 +392,7 @@ #if !defined(CONFIG_CPU_SH2) 1: .long TRA #endif -2: .long NR_syscalls +6: .long NR_syscalls 3: .long sys_call_table 7: .long do_syscall_trace_enter 8: .long do_syscall_trace_leave --- linux-oracle-5.4.0.orig/arch/sh/kernel/head_32.S +++ linux-oracle-5.4.0/arch/sh/kernel/head_32.S @@ -64,7 +64,7 @@ ldc r0, r6_bank #endif -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov r4, r12 ! Store device tree blob pointer in r12 #endif @@ -315,7 +315,7 @@ 10: #endif -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE mov.l 8f, r0 ! Make flat device tree available early. jsr @r0 mov r12, r4 @@ -346,7 +346,7 @@ 5: .long start_kernel 6: .long cpu_init 7: .long init_thread_union -#if defined(CONFIG_OF_FLATTREE) +#if defined(CONFIG_OF_EARLY_FLATTREE) 8: .long sh_fdt_init #endif --- linux-oracle-5.4.0.orig/arch/sh/kernel/idle.c +++ linux-oracle-5.4.0/arch/sh/kernel/idle.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include --- linux-oracle-5.4.0.orig/arch/sh/kernel/kprobes.c +++ linux-oracle-5.4.0/arch/sh/kernel/kprobes.c @@ -44,17 +44,12 @@ if (OPCODE_RTE(opcode)) return -EFAULT; /* Bad breakpoint */ + memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); p->opcode = opcode; return 0; } -void __kprobes arch_copy_kprobe(struct kprobe *p) -{ - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); - p->opcode = *p->addr; -} - void __kprobes arch_arm_kprobe(struct kprobe *p) { *p->addr = BREAKPOINT_INSTRUCTION; --- linux-oracle-5.4.0.orig/arch/sh/kernel/machvec.c +++ linux-oracle-5.4.0/arch/sh/kernel/machvec.c @@ -19,8 +19,8 @@ #define MV_NAME_SIZE 32 #define for_each_mv(mv) \ - for ((mv) = (struct sh_machine_vector *)&__machvec_start; \ - (mv) && (unsigned long)(mv) < (unsigned long)&__machvec_end; \ + for ((mv) = (struct sh_machine_vector *)__machvec_start; \ + (mv) && (unsigned long)(mv) < (unsigned long)__machvec_end; \ (mv)++) static struct sh_machine_vector * __init get_mv_byname(const char *name) @@ -86,8 +86,8 @@ if (!machvec_selected) { unsigned long machvec_size; - machvec_size = ((unsigned long)&__machvec_end - - (unsigned long)&__machvec_start); + machvec_size = ((unsigned long)__machvec_end - + (unsigned long)__machvec_start); /* * Sanity check for machvec section alignment. Ensure @@ -101,7 +101,7 @@ * vector (usually the only one) from .machvec.init. */ if (machvec_size >= sizeof(struct sh_machine_vector)) - sh_mv = *(struct sh_machine_vector *)&__machvec_start; + sh_mv = *(struct sh_machine_vector *)__machvec_start; } printk(KERN_NOTICE "Booting machvec: %s\n", get_system_type()); --- linux-oracle-5.4.0.orig/arch/sh/kernel/nmi_debug.c +++ linux-oracle-5.4.0/arch/sh/kernel/nmi_debug.c @@ -49,7 +49,7 @@ register_die_notifier(&nmi_debug_nb); if (*str != '=') - return 0; + return 1; for (p = str + 1; *p; p = sep + 1) { sep = strchr(p, ','); @@ -70,6 +70,6 @@ break; } - return 0; + return 1; } __setup("nmi_debug", nmi_debug_setup); --- linux-oracle-5.4.0.orig/arch/sh/kernel/setup.c +++ linux-oracle-5.4.0/arch/sh/kernel/setup.c @@ -43,6 +43,7 @@ #include #include #include +#include #include /* @@ -243,7 +244,7 @@ { } -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE void __ref sh_fdt_init(phys_addr_t dt_phys) { static int done = 0; @@ -330,7 +331,7 @@ /* Let earlyprintk output early console messages */ early_platform_driver_probe("earlyprintk", 1, 1); -#ifdef CONFIG_OF_FLATTREE +#ifdef CONFIG_OF_EARLY_FLATTREE #ifdef CONFIG_USE_BUILTIN_DTB unflatten_and_copy_device_tree(); #else @@ -362,3 +363,57 @@ { return sh_mv.mv_mode_pins() & pin; } + +void __init arch_cpu_finalize_init(void) +{ + char *p = &init_utsname()->machine[2]; /* "sh" */ + + select_idle_routine(); + + current_cpu_data.loops_per_jiffy = loops_per_jiffy; + + switch (current_cpu_data.family) { + case CPU_FAMILY_SH2: + *p++ = '2'; + break; + case CPU_FAMILY_SH2A: + *p++ = '2'; + *p++ = 'a'; + break; + case CPU_FAMILY_SH3: + *p++ = '3'; + break; + case CPU_FAMILY_SH4: + *p++ = '4'; + break; + case CPU_FAMILY_SH4A: + *p++ = '4'; + *p++ = 'a'; + break; + case CPU_FAMILY_SH4AL_DSP: + *p++ = '4'; + *p++ = 'a'; + *p++ = 'l'; + *p++ = '-'; + *p++ = 'd'; + *p++ = 's'; + *p++ = 'p'; + break; + case CPU_FAMILY_UNKNOWN: + /* + * Specifically use CPU_FAMILY_UNKNOWN rather than + * default:, so we're able to have the compiler whine + * about unhandled enumerations. + */ + break; + } + + pr_info("CPU: %s\n", get_cpu_subtype(¤t_cpu_data)); + +#ifndef __LITTLE_ENDIAN__ + /* 'eb' means 'Endian Big' */ + *p++ = 'e'; + *p++ = 'b'; +#endif + *p = '\0'; +} --- linux-oracle-5.4.0.orig/arch/sh/kernel/signal_32.c +++ linux-oracle-5.4.0/arch/sh/kernel/signal_32.c @@ -116,6 +116,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p) { unsigned int err = 0; + unsigned int sr = regs->sr & ~SR_USER_MASK; #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) COPY(regs[1]); @@ -131,6 +132,8 @@ COPY(sr); COPY(pc); #undef COPY + regs->sr = (regs->sr & SR_USER_MASK) | sr; + #ifdef CONFIG_SH_FPU if (boot_cpu_data.flags & CPU_HAS_FPU) { int owned_fp; --- linux-oracle-5.4.0.orig/arch/sh/kernel/traps.c +++ linux-oracle-5.4.0/arch/sh/kernel/traps.c @@ -57,7 +57,7 @@ if (panic_on_oops) panic("Fatal exception"); - do_exit(SIGSEGV); + make_task_dead(SIGSEGV); } void die_if_kernel(const char *str, struct pt_regs *regs, long err) --- linux-oracle-5.4.0.orig/arch/sh/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/sh/kernel/vmlinux.lds.S @@ -10,6 +10,7 @@ #define LOAD_OFFSET 0 OUTPUT_ARCH(sh) #endif +#define RUNTIME_DISCARD_EXIT #include #include --- linux-oracle-5.4.0.orig/arch/sh/lib/checksum.S +++ linux-oracle-5.4.0/arch/sh/lib/checksum.S @@ -33,7 +33,8 @@ */ /* - * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum); + * unsigned int csum_partial(const unsigned char *buf, int len, + * unsigned int sum); */ .text @@ -45,31 +46,11 @@ * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ + mov r5, r1 mov r4, r0 - tst #3, r0 ! Check alignment. - bt/s 2f ! Jump if alignment is ok. - mov r4, r7 ! Keep a copy to check for alignment + tst #2, r0 ! Check alignment. + bt 2f ! Jump if alignment is ok. ! - tst #1, r0 ! Check alignment. - bt 21f ! Jump if alignment is boundary of 2bytes. - - ! buf is odd - tst r5, r5 - add #-1, r5 - bt 9f - mov.b @r4+, r0 - extu.b r0, r0 - addc r0, r6 ! t=0 from previous tst - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 - mov r4, r0 - tst #2, r0 - bt 2f -21: - ! buf is 2 byte aligned (len could be 0) add #-2, r5 ! Alignment uses up two bytes. cmp/pz r5 ! bt/s 1f ! Jump if we had at least two bytes. @@ -77,17 +58,16 @@ bra 6f add #2, r5 ! r5 was < 2. Deal with it. 1: + mov r5, r1 ! Save new len for later use. mov.w @r4+, r0 extu.w r0, r0 addc r0, r6 bf 2f add #1, r6 2: - ! buf is 4 byte aligned (len could be 0) - mov r5, r1 mov #-5, r0 - shld r0, r1 - tst r1, r1 + shld r0, r5 + tst r5, r5 bt/s 4f ! if it's =0, go to 4f clrt .align 2 @@ -109,31 +89,30 @@ addc r0, r6 addc r2, r6 movt r0 - dt r1 + dt r5 bf/s 3b cmp/eq #1, r0 - ! here, we know r1==0 - addc r1, r6 ! add carry to r6 + ! here, we know r5==0 + addc r5, r6 ! add carry to r6 4: - mov r5, r0 + mov r1, r0 and #0x1c, r0 tst r0, r0 - bt 6f - ! 4 bytes or more remaining - mov r0, r1 - shlr2 r1 + bt/s 6f + mov r0, r5 + shlr2 r5 mov #0, r2 5: addc r2, r6 mov.l @r4+, r2 movt r0 - dt r1 + dt r5 bf/s 5b cmp/eq #1, r0 addc r2, r6 - addc r1, r6 ! r1==0 here, so it means add carry-bit + addc r5, r6 ! r5==0 here, so it means add carry-bit 6: - ! 3 bytes or less remaining + mov r1, r5 mov #3, r0 and r0, r5 tst r5, r5 @@ -159,16 +138,6 @@ mov #0, r0 addc r0, r6 9: - ! Check if the buffer was misaligned, if so realign sum - mov r7, r0 - tst #1, r0 - bt 10f - mov r6, r0 - shll8 r6 - shlr16 r0 - shlr8 r0 - or r0, r6 -10: rts mov r6, r0 --- linux-oracle-5.4.0.orig/arch/sh/math-emu/math.c +++ linux-oracle-5.4.0/arch/sh/math-emu/math.c @@ -468,109 +468,6 @@ } /** - * denormal_to_double - Given denormalized float number, - * store double float - * - * @fpu: Pointer to sh_fpu_soft structure - * @n: Index to FP register - */ -static void denormal_to_double(struct sh_fpu_soft_struct *fpu, int n) -{ - unsigned long du, dl; - unsigned long x = fpu->fpul; - int exp = 1023 - 126; - - if (x != 0 && (x & 0x7f800000) == 0) { - du = (x & 0x80000000); - while ((x & 0x00800000) == 0) { - x <<= 1; - exp--; - } - x &= 0x007fffff; - du |= (exp << 20) | (x >> 3); - dl = x << 29; - - fpu->fp_regs[n] = du; - fpu->fp_regs[n+1] = dl; - } -} - -/** - * ieee_fpe_handler - Handle denormalized number exception - * - * @regs: Pointer to register structure - * - * Returns 1 when it's handled (should not cause exception). - */ -static int ieee_fpe_handler(struct pt_regs *regs) -{ - unsigned short insn = *(unsigned short *)regs->pc; - unsigned short finsn; - unsigned long nextpc; - int nib[4] = { - (insn >> 12) & 0xf, - (insn >> 8) & 0xf, - (insn >> 4) & 0xf, - insn & 0xf}; - - if (nib[0] == 0xb || - (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ - regs->pr = regs->pc + 4; - - if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ - nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - else - nextpc = regs->pc + 4; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4; - else - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x4 && nib[3] == 0xb && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ - nextpc = regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x0 && nib[3] == 0x3 && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ - nextpc = regs->pc + 4 + regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (insn == 0x000b) { /* rts */ - nextpc = regs->pr; - finsn = *(unsigned short *) (regs->pc + 2); - } else { - nextpc = regs->pc + 2; - finsn = insn; - } - - if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ - struct task_struct *tsk = current; - - if ((tsk->thread.xstate->softfpu.fpscr & (1 << 17))) { - /* FPU error */ - denormal_to_double (&tsk->thread.xstate->softfpu, - (finsn >> 8) & 0xf); - tsk->thread.xstate->softfpu.fpscr &= - ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); - task_thread_info(tsk)->status |= TS_USEDFPU; - } else { - force_sig_fault(SIGFPE, FPE_FLTINV, - (void __user *)regs->pc); - } - - regs->pc = nextpc; - return 1; - } - - return 0; -} - -/** * fpu_init - Initialize FPU registers * @fpu: Pointer to software emulated FPU registers. */ --- linux-oracle-5.4.0.orig/arch/sh/math-emu/sfp-util.h +++ linux-oracle-5.4.0/arch/sh/math-emu/sfp-util.h @@ -67,7 +67,3 @@ } while (0) #define abort() return 0 - -#define __BYTE_ORDER __LITTLE_ENDIAN - - --- linux-oracle-5.4.0.orig/arch/sh/mm/init.c +++ linux-oracle-5.4.0/arch/sh/mm/init.c @@ -334,7 +334,7 @@ memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); } unsigned int mem_init_done = 0; @@ -434,9 +434,7 @@ { unsigned long start_pfn = PFN_DOWN(start); unsigned long nr_pages = size >> PAGE_SHIFT; - struct zone *zone; - zone = page_zone(pfn_to_page(start_pfn)); - __remove_pages(zone, start_pfn, nr_pages, altmap); + __remove_pages(start_pfn, nr_pages, altmap); } #endif /* CONFIG_MEMORY_HOTPLUG */ --- linux-oracle-5.4.0.orig/arch/sparc/Kconfig +++ linux-oracle-5.4.0/arch/sparc/Kconfig @@ -52,6 +52,7 @@ config SPARC32 def_bool !64BIT select ARCH_32BIT_OFF_T + select ARCH_HAS_CPU_FINALIZE_INIT if !SMP select ARCH_HAS_SYNC_DMA_FOR_CPU select GENERIC_ATOMIC64 select CLZ_TAB @@ -65,8 +66,6 @@ select HAVE_KRETPROBES select HAVE_KPROBES select HAVE_RCU_TABLE_FREE if SMP - select HAVE_RCU_TABLE_NO_INVALIDATE if HAVE_RCU_TABLE_FREE - select HAVE_MEMBLOCK_NODE_MAP select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD @@ -292,15 +291,6 @@ Specify the maximum number of NUMA Nodes available on the target system. Increases memory reserved to accommodate various tables. -# Some NUMA nodes have memory ranges that span -# other nodes. Even though a pfn is valid and -# between a node's start and end pfns, it may not -# reside on that node. See memmap_init_zone() -# for details. -config NODES_SPAN_OTHER_NODES - def_bool y - depends on NEED_MULTIPLE_NODES - config ARCH_SPARSEMEM_ENABLE def_bool y if SPARC64 select SPARSEMEM_VMEMMAP_ENABLE @@ -322,7 +312,7 @@ This config option is actually maximum order plus one. For example, a value of 13 means that the largest free memory block is 2^12 pages. -if SPARC64 +if SPARC64 || COMPILE_TEST source "kernel/power/Kconfig" endif @@ -525,7 +515,7 @@ bool depends on SPARC64 default y - select COMPAT_BINFMT_ELF + select COMPAT_BINFMT_ELF if BINFMT_ELF select HAVE_UID16 select ARCH_WANT_OLD_COMPAT_IPC select COMPAT_OLD_SIGACTION --- linux-oracle-5.4.0.orig/arch/sparc/configs/sparc64_defconfig +++ linux-oracle-5.4.0/arch/sparc/configs/sparc64_defconfig @@ -73,7 +73,6 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=m CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/io_64.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/io_64.h @@ -407,6 +407,7 @@ } #define ioremap_nocache(X,Y) ioremap((X),(Y)) +#define ioremap_uc(X,Y) ioremap((X),(Y)) #define ioremap_wc(X,Y) ioremap((X),(Y)) #define ioremap_wt(X,Y) ioremap((X),(Y)) --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/mman.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/mman.h @@ -57,35 +57,39 @@ { if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM | PROT_ADI)) return 0; - if (prot & PROT_ADI) { - if (!adi_capable()) - return 0; + return 1; +} - if (addr) { - struct vm_area_struct *vma; +#define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) +/* arch_validate_flags() - Ensure combination of flags is valid for a + * VMA. + */ +static inline bool arch_validate_flags(unsigned long vm_flags) +{ + /* If ADI is being enabled on this VMA, check for ADI + * capability on the platform and ensure VMA is suitable + * for ADI + */ + if (vm_flags & VM_SPARC_ADI) { + if (!adi_capable()) + return false; - vma = find_vma(current->mm, addr); - if (vma) { - /* ADI can not be enabled on PFN - * mapped pages - */ - if (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) - return 0; + /* ADI can not be enabled on PFN mapped pages */ + if (vm_flags & (VM_PFNMAP | VM_MIXEDMAP)) + return false; - /* Mergeable pages can become unmergeable - * if ADI is enabled on them even if they - * have identical data on them. This can be - * because ADI enabled pages with identical - * data may still not have identical ADI - * tags on them. Disallow ADI on mergeable - * pages. - */ - if (vma->vm_flags & VM_MERGEABLE) - return 0; - } - } + /* Mergeable pages can become unmergeable + * if ADI is enabled on them even if they + * have identical data on them. This can be + * because ADI enabled pages with identical + * data may still not have identical ADI + * tags on them. Disallow ADI on mergeable + * pages. + */ + if (vm_flags & VM_MERGEABLE) + return false; } - return 1; + return true; } #endif /* CONFIG_SPARC64 */ --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/oplib_64.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/oplib_64.h @@ -247,6 +247,7 @@ int prom_ihandle2path(int handle, char *buffer, int bufsize); /* Client interface level routines. */ +void prom_cif_init(void *cif_handler); void p1275_cmd_direct(unsigned long *); #endif /* !(__SPARC64_OPLIB_H) */ --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/smp_64.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/smp_64.h @@ -47,7 +47,6 @@ int hard_smp_processor_id(void); #define raw_smp_processor_id() (current_thread_info()->cpu) -void smp_fill_in_cpu_possible_map(void); void smp_fill_in_sib_core_maps(void); void cpu_play_dead(void); @@ -77,7 +76,6 @@ #define smp_fill_in_sib_core_maps() do { } while (0) #define smp_fetch_global_regs() do { } while (0) #define smp_fetch_global_pmu() do { } while (0) -#define smp_fill_in_cpu_possible_map() do { } while (0) #define smp_init_cpu_poke() do { } while (0) #define scheduler_poke() do { } while (0) --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/timex_32.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/timex_32.h @@ -9,8 +9,6 @@ #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ -/* XXX Maybe do something better at some point... -DaveM */ -typedef unsigned long cycles_t; -#define get_cycles() (0) +#include #endif --- linux-oracle-5.4.0.orig/arch/sparc/include/asm/tlb_64.h +++ linux-oracle-5.4.0/arch/sparc/include/asm/tlb_64.h @@ -28,6 +28,15 @@ #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) #define tlb_flush(tlb) flush_tlb_pending() +/* + * SPARC64's hardware TLB fill does not use the Linux page-tables + * and therefore we don't need a TLBI when freeing page-table pages. + */ + +#ifdef CONFIG_HAVE_RCU_TABLE_FREE +#define tlb_needs_table_invalidate() (false) +#endif + #include #endif /* _SPARC64_TLB_H */ --- linux-oracle-5.4.0.orig/arch/sparc/include/uapi/asm/ipcbuf.h +++ linux-oracle-5.4.0/arch/sparc/include/uapi/asm/ipcbuf.h @@ -15,19 +15,19 @@ struct ipc64_perm { - __kernel_key_t key; - __kernel_uid_t uid; - __kernel_gid_t gid; - __kernel_uid_t cuid; - __kernel_gid_t cgid; + __kernel_key_t key; + __kernel_uid32_t uid; + __kernel_gid32_t gid; + __kernel_uid32_t cuid; + __kernel_gid32_t cgid; #ifndef __arch64__ - unsigned short __pad0; + unsigned short __pad0; #endif - __kernel_mode_t mode; - unsigned short __pad1; - unsigned short seq; - unsigned long long __unused1; - unsigned long long __unused2; + __kernel_mode_t mode; + unsigned short __pad1; + unsigned short seq; + unsigned long long __unused1; + unsigned long long __unused2; }; #endif /* __SPARC_IPCBUF_H */ --- linux-oracle-5.4.0.orig/arch/sparc/include/uapi/asm/termbits.h +++ linux-oracle-5.4.0/arch/sparc/include/uapi/asm/termbits.h @@ -13,16 +13,6 @@ typedef unsigned long tcflag_t; #endif -#define NCC 8 -struct termio { - unsigned short c_iflag; /* input mode flags */ - unsigned short c_oflag; /* output mode flags */ - unsigned short c_cflag; /* control mode flags */ - unsigned short c_lflag; /* local mode flags */ - unsigned char c_line; /* line discipline */ - unsigned char c_cc[NCC]; /* control characters */ -}; - #define NCCS 17 struct termios { tcflag_t c_iflag; /* input mode flags */ --- linux-oracle-5.4.0.orig/arch/sparc/include/uapi/asm/termios.h +++ linux-oracle-5.4.0/arch/sparc/include/uapi/asm/termios.h @@ -40,5 +40,14 @@ unsigned short ws_ypixel; }; +#define NCC 8 +struct termio { + unsigned short c_iflag; /* input mode flags */ + unsigned short c_oflag; /* output mode flags */ + unsigned short c_cflag; /* control mode flags */ + unsigned short c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[NCC]; /* control characters */ +}; #endif /* _UAPI_SPARC_TERMIOS_H */ --- linux-oracle-5.4.0.orig/arch/sparc/kernel/ioport.c +++ linux-oracle-5.4.0/arch/sparc/kernel/ioport.c @@ -356,7 +356,9 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs) { - if (!sparc_dma_free_resource(cpu_addr, PAGE_ALIGN(size))) + size = PAGE_ALIGN(size); + + if (!sparc_dma_free_resource(cpu_addr, size)) return; dma_make_coherent(dma_addr, size); @@ -366,8 +368,8 @@ /* IIep is write-through, not flushing on cpu to device transfer. */ -void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, - size_t size, enum dma_data_direction dir) +void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { if (dir != PCI_DMA_TODEVICE) dma_make_coherent(paddr, PAGE_ALIGN(size)); --- linux-oracle-5.4.0.orig/arch/sparc/kernel/leon_pci_grpci1.c +++ linux-oracle-5.4.0/arch/sparc/kernel/leon_pci_grpci1.c @@ -696,7 +696,7 @@ return err; } -static const struct of_device_id grpci1_of_match[] __initconst = { +static const struct of_device_id grpci1_of_match[] = { { .name = "GAISLER_PCIFBRG", }, --- linux-oracle-5.4.0.orig/arch/sparc/kernel/leon_pci_grpci2.c +++ linux-oracle-5.4.0/arch/sparc/kernel/leon_pci_grpci2.c @@ -887,7 +887,7 @@ return err; } -static const struct of_device_id grpci2_of_match[] __initconst = { +static const struct of_device_id grpci2_of_match[] = { { .name = "GAISLER_GRPCI2", }, --- linux-oracle-5.4.0.orig/arch/sparc/kernel/mdesc.c +++ linux-oracle-5.4.0/arch/sparc/kernel/mdesc.c @@ -39,6 +39,7 @@ u32 node_sz; /* node block size */ u32 name_sz; /* name block size */ u32 data_sz; /* data block size */ + char data[]; } __attribute__((aligned(16))); struct mdesc_elem { @@ -612,7 +613,7 @@ static struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) { - return (struct mdesc_elem *) (mdesc + 1); + return (struct mdesc_elem *) mdesc->data; } static void *name_block(struct mdesc_hdr *mdesc) --- linux-oracle-5.4.0.orig/arch/sparc/kernel/nmi.c +++ linux-oracle-5.4.0/arch/sparc/kernel/nmi.c @@ -274,7 +274,7 @@ if (!strncmp(str, "panic", 5)) panic_on_timeout = 1; - return 0; + return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); --- linux-oracle-5.4.0.orig/arch/sparc/kernel/prom_64.c +++ linux-oracle-5.4.0/arch/sparc/kernel/prom_64.c @@ -483,7 +483,9 @@ ncpus_probed++; #ifdef CONFIG_SMP set_cpu_present(cpuid, true); - set_cpu_possible(cpuid, true); + + if (num_possible_cpus() < nr_cpu_ids) + set_cpu_possible(cpuid, true); #endif return NULL; } --- linux-oracle-5.4.0.orig/arch/sparc/kernel/ptrace_32.c +++ linux-oracle-5.4.0/arch/sparc/kernel/ptrace_32.c @@ -46,82 +46,79 @@ REGSET_FP, }; +static int regwindow32_get(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_from_user(uregs, (void __user *)reg_window, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE) != size) + return -EFAULT; + } + return 0; +} + +static int regwindow32_set(struct task_struct *target, + const struct pt_regs *regs, + u32 *uregs) +{ + unsigned long reg_window = regs->u_regs[UREG_I6]; + int size = 16 * sizeof(u32); + + if (target == current) { + if (copy_to_user((void __user *)reg_window, uregs, size)) + return -EFAULT; + } else { + if (access_process_vm(target, reg_window, uregs, size, + FOLL_FORCE | FOLL_WRITE) != size) + return -EFAULT; + } + return 0; +} + static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - unsigned long *k = kbuf; - unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - if (kbuf) { - for (; count > 0 && pos < 16; count--) - *k++ = regs->u_regs[pos++]; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (put_user(regs->u_regs[pos++], u++)) - return -EFAULT; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, ®_window[pos++]) || - put_user(reg, u++)) - return -EFAULT; - } - } - while (count > 0) { - switch (pos) { - case 32: /* PSR */ - reg = regs->psr; - break; - case 33: /* PC */ - reg = regs->pc; - break; - case 34: /* NPC */ - reg = regs->npc; - break; - case 35: /* Y */ - reg = regs->y; - break; - case 36: /* WIM */ - case 37: /* TBR */ - reg = 0; - break; - default: - goto finish; - } - - if (kbuf) - *k++ = reg; - else if (put_user(reg, u++)) + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) return -EFAULT; - pos++; - count--; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret || !count) + return ret; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + uregs[0] = regs->psr; + uregs[1] = regs->pc; + uregs[2] = regs->npc; + uregs[3] = regs->y; + uregs[4] = 0; /* WIM */ + uregs[5] = 0; /* TBR */ + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + uregs, + 32 * sizeof(u32), 38 * sizeof(u32)); } static int genregs32_set(struct task_struct *target, @@ -130,82 +127,58 @@ const void *kbuf, const void __user *ubuf) { struct pt_regs *regs = target->thread.kregs; - unsigned long __user *reg_window; - const unsigned long *k = kbuf; - const unsigned long __user *u = ubuf; - unsigned long reg; + u32 uregs[16]; + u32 psr; + int ret; if (target == current) flush_user_windows(); - pos /= sizeof(reg); - count /= sizeof(reg); - - if (kbuf) { - for (; count > 0 && pos < 16; count--) - regs->u_regs[pos++] = *k++; - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (put_user(*k++, ®_window[pos++])) - return -EFAULT; - } - } else { - for (; count > 0 && pos < 16; count--) { - if (get_user(reg, u++)) - return -EFAULT; - regs->u_regs[pos++] = reg; - } - - reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; - reg_window -= 16; - for (; count > 0 && pos < 32; count--) { - if (get_user(reg, u++) || - put_user(reg, ®_window[pos++])) - return -EFAULT; - } - } - while (count > 0) { - unsigned long psr; - - if (kbuf) - reg = *k++; - else if (get_user(reg, u++)) - return -EFAULT; - - switch (pos) { - case 32: /* PSR */ - psr = regs->psr; - psr &= ~(PSR_ICC | PSR_SYSCALL); - psr |= (reg & (PSR_ICC | PSR_SYSCALL)); - regs->psr = psr; - break; - case 33: /* PC */ - regs->pc = reg; - break; - case 34: /* NPC */ - regs->npc = reg; - break; - case 35: /* Y */ - regs->y = reg; - break; - case 36: /* WIM */ - case 37: /* TBR */ - break; - default: - goto finish; - } + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + regs->u_regs, + 0, 16 * sizeof(u32)); + if (ret || !count) + return ret; - pos++; - count--; + if (pos < 32 * sizeof(u32)) { + if (regwindow32_get(target, regs, uregs)) + return -EFAULT; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + uregs, + 16 * sizeof(u32), 32 * sizeof(u32)); + if (ret) + return ret; + if (regwindow32_set(target, regs, uregs)) + return -EFAULT; + if (!count) + return 0; } -finish: - pos *= sizeof(reg); - count *= sizeof(reg); - + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &psr, + 32 * sizeof(u32), 33 * sizeof(u32)); + if (ret) + return ret; + regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) | + (psr & (PSR_ICC | PSR_SYSCALL)); + if (!count) + return 0; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->pc, + 33 * sizeof(u32), 34 * sizeof(u32)); + if (ret || !count) + return ret; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->npc, + 34 * sizeof(u32), 35 * sizeof(u32)); + if (ret || !count) + return ret; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + ®s->y, + 35 * sizeof(u32), 36 * sizeof(u32)); + if (ret || !count) + return ret; return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - 38 * sizeof(reg), -1); + 36 * sizeof(u32), 38 * sizeof(u32)); } static int fpregs32_get(struct task_struct *target, --- linux-oracle-5.4.0.orig/arch/sparc/kernel/ptrace_64.c +++ linux-oracle-5.4.0/arch/sparc/kernel/ptrace_64.c @@ -572,19 +572,13 @@ for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) - ®_window[pos], + ®_window[pos++], ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) return -EFAULT; - if (access_process_vm(target, - (unsigned long) u, - ®, sizeof(reg), - FOLL_FORCE | FOLL_WRITE) - != sizeof(reg)) + if (put_user(reg, u++)) return -EFAULT; - pos++; - u++; } } } @@ -684,12 +678,7 @@ } } else { for (; count > 0 && pos < 32; count--) { - if (access_process_vm(target, - (unsigned long) - u, - ®, sizeof(reg), - FOLL_FORCE) - != sizeof(reg)) + if (get_user(reg, u++)) return -EFAULT; if (access_process_vm(target, (unsigned long) --- linux-oracle-5.4.0.orig/arch/sparc/kernel/setup_32.c +++ linux-oracle-5.4.0/arch/sparc/kernel/setup_32.c @@ -422,3 +422,10 @@ } subsys_initcall(topology_init); + +#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) +void __init arch_cpu_finalize_init(void) +{ + cpu_data(0).udelay_val = loops_per_jiffy; +} +#endif --- linux-oracle-5.4.0.orig/arch/sparc/kernel/setup_64.c +++ linux-oracle-5.4.0/arch/sparc/kernel/setup_64.c @@ -695,7 +695,6 @@ paging_init(); init_sparc64_elf_hwcap(); - smp_fill_in_cpu_possible_map(); /* * Once the OF device tree and MDESC have been setup and nr_cpus has * been parsed, we know the list of possible cpus. Therefore we can --- linux-oracle-5.4.0.orig/arch/sparc/kernel/smp_64.c +++ linux-oracle-5.4.0/arch/sparc/kernel/smp_64.c @@ -1039,38 +1039,9 @@ * are flush_tlb_*() routines, and these run after flush_cache_*() * which performs the flushw. * - * The SMP TLB coherency scheme we use works as follows: - * - * 1) mm->cpu_vm_mask is a bit mask of which cpus an address - * space has (potentially) executed on, this is the heuristic - * we use to avoid doing cross calls. - * - * Also, for flushing from kswapd and also for clones, we - * use cpu_vm_mask as the list of cpus to make run the TLB. - * - * 2) TLB context numbers are shared globally across all processors - * in the system, this allows us to play several games to avoid - * cross calls. - * - * One invariant is that when a cpu switches to a process, and - * that processes tsk->active_mm->cpu_vm_mask does not have the - * current cpu's bit set, that tlb context is flushed locally. - * - * If the address space is non-shared (ie. mm->count == 1) we avoid - * cross calls when we want to flush the currently running process's - * tlb state. This is done by clearing all cpu bits except the current - * processor's in current->mm->cpu_vm_mask and performing the - * flush locally only. This will force any subsequent cpus which run - * this task to flush the context from the local tlb if the process - * migrates to another cpu (again). - * - * 3) For shared address spaces (threads) and swapping we bite the - * bullet for most cases and perform the cross call (but only to - * the cpus listed in cpu_vm_mask). - * - * The performance gain from "optimizing" away the cross call for threads is - * questionable (in theory the big win for threads is the massive sharing of - * address space state across processors). + * mm->cpu_vm_mask is a bit mask of which cpus an address + * space has (potentially) executed on, this is the heuristic + * we use to limit cross calls. */ /* This currently is only used by the hugetlb arch pre-fault @@ -1080,18 +1051,13 @@ void smp_flush_tlb_mm(struct mm_struct *mm) { u32 ctx = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - if (atomic_read(&mm->mm_users) == 1) { - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - goto local_flush_and_out; - } + get_cpu(); smp_cross_call_masked(&xcall_flush_tlb_mm, ctx, 0, 0, mm_cpumask(mm)); -local_flush_and_out: __flush_tlb_mm(ctx, SECONDARY_CONTEXT); put_cpu(); @@ -1114,17 +1080,15 @@ { u32 ctx = CTX_HWBITS(mm->context); struct tlb_pending_info info; - int cpu = get_cpu(); + + get_cpu(); info.ctx = ctx; info.nr = nr; info.vaddrs = vaddrs; - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_call_function_many(mm_cpumask(mm), tlb_pending_func, - &info, 1); + smp_call_function_many(mm_cpumask(mm), tlb_pending_func, + &info, 1); __flush_tlb_pending(ctx, nr, vaddrs); @@ -1134,14 +1098,13 @@ void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) { unsigned long context = CTX_HWBITS(mm->context); - int cpu = get_cpu(); - if (mm == current->mm && atomic_read(&mm->mm_users) == 1) - cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); - else - smp_cross_call_masked(&xcall_flush_tlb_page, - context, vaddr, 0, - mm_cpumask(mm)); + get_cpu(); + + smp_cross_call_masked(&xcall_flush_tlb_page, + context, vaddr, 0, + mm_cpumask(mm)); + __flush_tlb_page(context, vaddr); put_cpu(); @@ -1250,20 +1213,6 @@ xcall_deliver_impl = hypervisor_xcall_deliver; } -void __init smp_fill_in_cpu_possible_map(void) -{ - int possible_cpus = num_possible_cpus(); - int i; - - if (possible_cpus > nr_cpu_ids) - possible_cpus = nr_cpu_ids; - - for (i = 0; i < possible_cpus; i++) - set_cpu_possible(i, true); - for (; i < NR_CPUS; i++) - set_cpu_possible(i, false); -} - void smp_fill_in_sib_core_maps(void) { unsigned int i; --- linux-oracle-5.4.0.orig/arch/sparc/kernel/syscalls/syscall.tbl +++ linux-oracle-5.4.0/arch/sparc/kernel/syscalls/syscall.tbl @@ -117,7 +117,7 @@ 90 common dup2 sys_dup2 91 32 setfsuid32 sys_setfsuid 92 common fcntl sys_fcntl compat_sys_fcntl -93 common select sys_select +93 common select sys_select compat_sys_select 94 32 setfsgid32 sys_setfsgid 95 common fsync sys_fsync 96 common setpriority sys_setpriority --- linux-oracle-5.4.0.orig/arch/sparc/kernel/traps_32.c +++ linux-oracle-5.4.0/arch/sparc/kernel/traps_32.c @@ -86,9 +86,7 @@ } printk("Instruction DUMP:"); instruction_dump ((unsigned long *) regs->pc); - if(regs->psr & PSR_PS) - do_exit(SIGKILL); - do_exit(SIGSEGV); + make_task_dead((regs->psr & PSR_PS) ? SIGKILL : SIGSEGV); } void do_hw_interrupt(struct pt_regs *regs, unsigned long type) --- linux-oracle-5.4.0.orig/arch/sparc/kernel/traps_64.c +++ linux-oracle-5.4.0/arch/sparc/kernel/traps_64.c @@ -275,14 +275,13 @@ asi = (regs->tstate >> 24); /* saved %asi */ else asi = (insn >> 5); /* immediate asi */ - if ((asi & 0xf2) == ASI_PNF) { - if (insn & 0x1000000) { /* op3[5:4]=3 */ - handle_ldf_stq(insn, regs); - return true; - } else if (insn & 0x200000) { /* op3[2], stores */ + if ((asi & 0xf6) == ASI_PNF) { + if (insn & 0x200000) /* op3[2], stores */ return false; - } - handle_ld_nf(insn, regs); + if (insn & 0x1000000) /* op3[5:4]=3 (fp) */ + handle_ldf_stq(insn, regs); + else + handle_ld_nf(insn, regs); return true; } } @@ -2565,9 +2564,7 @@ } if (panic_on_oops) panic("Fatal exception"); - if (regs->tstate & TSTATE_PRIV) - do_exit(SIGKILL); - do_exit(SIGSEGV); + make_task_dead((regs->tstate & TSTATE_PRIV)? SIGKILL : SIGSEGV); } EXPORT_SYMBOL(die_if_kernel); --- linux-oracle-5.4.0.orig/arch/sparc/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/sparc/kernel/vmlinux.lds.S @@ -172,12 +172,14 @@ } PERCPU_SECTION(SMP_CACHE_BYTES) -#ifdef CONFIG_JUMP_LABEL . = ALIGN(PAGE_SIZE); .exit.text : { EXIT_TEXT } -#endif + + .exit.data : { + EXIT_DATA + } . = ALIGN(PAGE_SIZE); __init_end = .; --- linux-oracle-5.4.0.orig/arch/sparc/lib/iomap.c +++ linux-oracle-5.4.0/arch/sparc/lib/iomap.c @@ -19,8 +19,10 @@ EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); +#ifdef CONFIG_PCI void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { /* nothing to do */ } EXPORT_SYMBOL(pci_iounmap); +#endif --- linux-oracle-5.4.0.orig/arch/sparc/lib/memset.S +++ linux-oracle-5.4.0/arch/sparc/lib/memset.S @@ -142,6 +142,7 @@ ZERO_LAST_BLOCKS(%o0, 0x48, %g2) ZERO_LAST_BLOCKS(%o0, 0x08, %g2) 13: + EXT(12b, 13b, 21f) be 8f andcc %o1, 4, %g0 --- linux-oracle-5.4.0.orig/arch/sparc/mm/init_32.c +++ linux-oracle-5.4.0/arch/sparc/mm/init_32.c @@ -197,6 +197,9 @@ size = memblock_phys_mem_size() - memblock_reserved_size(); *pages_avail = (size >> PAGE_SHIFT) - high_pages; + /* Only allow low memory to be allocated via memblock allocation */ + memblock_set_current_limit(max_low_pfn << PAGE_SHIFT); + return max_pfn; } --- linux-oracle-5.4.0.orig/arch/sparc/mm/init_64.c +++ linux-oracle-5.4.0/arch/sparc/mm/init_64.c @@ -2468,7 +2468,7 @@ max_zone_pfns[ZONE_NORMAL] = end_pfn; - free_area_init_nodes(max_zone_pfns); + free_area_init(max_zone_pfns); } printk("Booting Linux...\n"); @@ -2904,7 +2904,7 @@ if (!page) return NULL; if (!pgtable_pte_page_ctor(page)) { - free_unref_page(page); + __free_page(page); return NULL; } return (pte_t *) page_address(page); --- linux-oracle-5.4.0.orig/arch/sparc/mm/srmmu.c +++ linux-oracle-5.4.0/arch/sparc/mm/srmmu.c @@ -379,7 +379,6 @@ return NULL; page = pfn_to_page(__nocache_pa(pte) >> PAGE_SHIFT); if (!pgtable_pte_page_ctor(page)) { - __free_page(page); return NULL; } return page; @@ -979,24 +978,13 @@ kmap_init(); { - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long zholes_size[MAX_NR_ZONES]; - unsigned long npages; - int znum; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; - for (znum = 0; znum < MAX_NR_ZONES; znum++) - zones_size[znum] = zholes_size[znum] = 0; + max_zone_pfn[ZONE_DMA] = max_low_pfn; + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; + max_zone_pfn[ZONE_HIGHMEM] = highend_pfn; - npages = max_low_pfn - pfn_base; - - zones_size[ZONE_DMA] = npages; - zholes_size[ZONE_DMA] = npages - pages_avail; - - npages = highend_pfn - max_low_pfn; - zones_size[ZONE_HIGHMEM] = npages; - zholes_size[ZONE_HIGHMEM] = npages - calc_highpages(); - - free_area_init_node(0, zones_size, pfn_base, zholes_size); + free_area_init(max_zone_pfn); } } --- linux-oracle-5.4.0.orig/arch/sparc/net/bpf_jit_comp_64.c +++ linux-oracle-5.4.0/arch/sparc/net/bpf_jit_comp_64.c @@ -1287,6 +1287,9 @@ return 1; break; } + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: --- linux-oracle-5.4.0.orig/arch/sparc/prom/init_64.c +++ linux-oracle-5.4.0/arch/sparc/prom/init_64.c @@ -26,9 +26,6 @@ * routines in the prom library. * It gets passed the pointer to the PROM vector. */ - -extern void prom_cif_init(void *); - void __init prom_init(void *cif_handler) { phandle node; --- linux-oracle-5.4.0.orig/arch/sparc/prom/p1275.c +++ linux-oracle-5.4.0/arch/sparc/prom/p1275.c @@ -49,7 +49,7 @@ local_irq_restore(flags); } -void prom_cif_init(void *cif_handler, void *cif_stack) +void prom_cif_init(void *cif_handler) { p1275buf.prom_cif_handler = (void (*)(long *))cif_handler; } --- linux-oracle-5.4.0.orig/arch/sparc/vdso/vma.c +++ linux-oracle-5.4.0/arch/sparc/vdso/vma.c @@ -449,9 +449,8 @@ unsigned long val; err = kstrtoul(s, 10, &val); - if (err) - return err; - vdso_enabled = val; - return 0; + if (!err) + vdso_enabled = val; + return 1; } __setup("vdso=", vdso_setup); --- linux-oracle-5.4.0.orig/arch/um/Kconfig +++ linux-oracle-5.4.0/arch/um/Kconfig @@ -5,6 +5,7 @@ config UML bool default y + select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_KCOV select ARCH_NO_PREEMPT select HAVE_ARCH_AUDITSYSCALL @@ -14,6 +15,7 @@ select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE + select HAVE_COPY_THREAD_TLS select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select GENERIC_CLOCKEVENTS @@ -83,6 +85,19 @@ depends on !LD_SCRIPT_STATIC select MODULE_REL_CRCS if MODVERSIONS +config LD_SCRIPT_DYN_RPATH + bool "set rpath in the binary" if EXPERT + default y + depends on LD_SCRIPT_DYN + help + Add /lib (and /lib64 for 64-bit) to the linux binary's rpath + explicitly. + + You may need to turn this off if compiling for nix systems + that have their libraries in random /nix directories and + might otherwise unexpected use libraries from /lib or /lib64 + instead of the desired ones. + config HOSTFS tristate "Host filesystem" help --- linux-oracle-5.4.0.orig/arch/um/Kconfig.debug +++ linux-oracle-5.4.0/arch/um/Kconfig.debug @@ -17,6 +17,7 @@ bool "Enable gcov support" depends on DEBUG_INFO depends on !KCOV + depends on !MODULES help This option allows developers to retrieve coverage data from a UML session. --- linux-oracle-5.4.0.orig/arch/um/Makefile +++ linux-oracle-5.4.0/arch/um/Makefile @@ -118,7 +118,8 @@ $(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie) +LINK-$(CONFIG_LD_SCRIPT_DYN) += $(call cc-option, -no-pie) +LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \ $(call cc-option, -fno-stack-protector,) \ @@ -132,14 +133,23 @@ # The wrappers will select whether using "malloc" or the kernel allocator. LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc +# Avoid binutils 2.39+ warnings by marking the stack non-executable and +# ignorning warnings for the kallsyms sections. +LDFLAGS_EXECSTACK = -z noexecstack +ifeq ($(CONFIG_LD_IS_BFD),y) +LDFLAGS_EXECSTACK += $(call ld-option,--no-warn-rwx-segments) +endif + LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS),-Wl,$(opt)) # Used by link-vmlinux.sh which has special support for um link export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) +export LDFLAGS_vmlinux := $(LDFLAGS_EXECSTACK) # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. CLEAN_FILES += linux x.i gmon.out +MRPROPER_DIRS += arch/$(SUBARCH)/include/generated archclean: @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ --- linux-oracle-5.4.0.orig/arch/um/configs/i386_defconfig +++ linux-oracle-5.4.0/arch/um/configs/i386_defconfig @@ -35,6 +35,7 @@ CONFIG_XTERM_CHAN=y CONFIG_CON_CHAN="pts" CONFIG_SSL_CHAN="pts" +CONFIG_SOUND=m CONFIG_UML_SOUND=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y --- linux-oracle-5.4.0.orig/arch/um/configs/x86_64_defconfig +++ linux-oracle-5.4.0/arch/um/configs/x86_64_defconfig @@ -33,6 +33,7 @@ CONFIG_XTERM_CHAN=y CONFIG_CON_CHAN="pts" CONFIG_SSL_CHAN="pts" +CONFIG_SOUND=m CONFIG_UML_SOUND=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y --- linux-oracle-5.4.0.orig/arch/um/drivers/Kconfig +++ linux-oracle-5.4.0/arch/um/drivers/Kconfig @@ -104,24 +104,14 @@ config UML_SOUND tristate "Sound support" + depends on SOUND + select SOUND_OSS_CORE help This option enables UML sound support. If enabled, it will pull in - soundcore and the UML hostaudio relay, which acts as a intermediary + the UML hostaudio relay, which acts as a intermediary between the host's dsp and mixer devices and the UML sound system. It is safe to say 'Y' here. -config SOUND - tristate - default UML_SOUND - -config SOUND_OSS_CORE - bool - default UML_SOUND - -config HOSTAUDIO - tristate - default UML_SOUND - endmenu menu "UML Network Devices" @@ -337,7 +327,7 @@ endmenu config VIRTIO_UML - tristate "UML driver for virtio devices" + bool "UML driver for virtio devices" select VIRTIO help This driver provides support for virtio based paravirtual device --- linux-oracle-5.4.0.orig/arch/um/drivers/Makefile +++ linux-oracle-5.4.0/arch/um/drivers/Makefile @@ -52,7 +52,7 @@ obj-$(CONFIG_MCONSOLE) += mconsole.o obj-$(CONFIG_MMAPPER) += mmapper_kern.o obj-$(CONFIG_BLK_DEV_UBD) += ubd.o -obj-$(CONFIG_HOSTAUDIO) += hostaudio.o +obj-$(CONFIG_UML_SOUND) += hostaudio.o obj-$(CONFIG_NULL_CHAN) += null.o obj-$(CONFIG_PORT_CHAN) += port.o obj-$(CONFIG_PTY_CHAN) += pty.o --- linux-oracle-5.4.0.orig/arch/um/drivers/chan_user.c +++ linux-oracle-5.4.0/arch/um/drivers/chan_user.c @@ -26,10 +26,10 @@ n = read(fd, c_out, sizeof(*c_out)); if (n > 0) return n; - else if (errno == EAGAIN) - return 0; else if (n == 0) return -EIO; + else if (errno == EAGAIN) + return 0; return -errno; } @@ -220,7 +220,7 @@ unsigned long *stack_out) { struct winch_data data; - int fds[2], n, err; + int fds[2], n, err, pid; char c; err = os_pipe(fds, 1, 1); @@ -238,8 +238,9 @@ * problem with /dev/net/tun, which if held open by this * thread, prevents the TUN/TAP device from being reused. */ - err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); - if (err < 0) { + pid = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); + if (pid < 0) { + err = pid; printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n", -err); goto out_close; @@ -256,13 +257,14 @@ goto out_close; } - if (os_set_fd_block(*fd_out, 0)) { + err = os_set_fd_block(*fd_out, 0); + if (err) { printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd " "non-blocking.\n"); goto out_close; } - return err; + return pid; out_close: close(fds[1]); --- linux-oracle-5.4.0.orig/arch/um/drivers/line.c +++ linux-oracle-5.4.0/arch/um/drivers/line.c @@ -383,6 +383,7 @@ parse_chan_pair(NULL, line, n, opts, error_out); err = 0; } + *error_out = "configured as 'none'"; } else { char *new = kstrdup(init, GFP_KERNEL); if (!new) { @@ -406,6 +407,7 @@ } } if (err) { + *error_out = "failed to parse channel pair"; line->init_str = NULL; line->valid = 0; kfree(new); @@ -673,24 +675,26 @@ goto cleanup; } - *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), - .fd = fd, + *winch = ((struct winch) { .fd = fd, .tty_fd = tty_fd, .pid = pid, .port = port, .stack = stack }); + spin_lock(&winch_handler_lock); + list_add(&winch->list, &winch_handlers); + spin_unlock(&winch_handler_lock); + if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, IRQF_SHARED, "winch", winch) < 0) { printk(KERN_ERR "register_winch_irq - failed to register " "IRQ\n"); + spin_lock(&winch_handler_lock); + list_del(&winch->list); + spin_unlock(&winch_handler_lock); goto out_free; } - spin_lock(&winch_handler_lock); - list_add(&winch->list, &winch_handlers); - spin_unlock(&winch_handler_lock); - return; out_free: --- linux-oracle-5.4.0.orig/arch/um/drivers/mconsole_kern.c +++ linux-oracle-5.4.0/arch/um/drivers/mconsole_kern.c @@ -217,7 +217,7 @@ void mconsole_stop(struct mc_request *req) { - deactivate_fd(req->originating_fd, MCONSOLE_IRQ); + block_signals(); os_set_fd_block(req->originating_fd, 1); mconsole_reply(req, "stopped", 0, 0); for (;;) { @@ -240,6 +240,7 @@ } os_set_fd_block(req->originating_fd, 0); mconsole_reply(req, "", 0, 0); + unblock_signals(); } static DEFINE_SPINLOCK(mc_devices_lock); --- linux-oracle-5.4.0.orig/arch/um/drivers/net_kern.c +++ linux-oracle-5.4.0/arch/um/drivers/net_kern.c @@ -204,7 +204,7 @@ return 0; } -static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct uml_net_private *lp = netdev_priv(dev); unsigned long flags; @@ -347,7 +347,7 @@ static void net_device_release(struct device *dev) { - struct uml_net *device = dev_get_drvdata(dev); + struct uml_net *device = container_of(dev, struct uml_net, pdev.dev); struct net_device *netdev = device->dev; struct uml_net_private *lp = netdev_priv(netdev); --- linux-oracle-5.4.0.orig/arch/um/drivers/slip_user.c +++ linux-oracle-5.4.0/arch/um/drivers/slip_user.c @@ -145,7 +145,8 @@ } sfd = err; - if (set_up_tty(sfd)) + err = set_up_tty(sfd); + if (err) goto out_close2; pri->slave = sfd; --- linux-oracle-5.4.0.orig/arch/um/drivers/ubd_kern.c +++ linux-oracle-5.4.0/arch/um/drivers/ubd_kern.c @@ -47,18 +47,25 @@ /* Max request size is determined by sector mask - 32K */ #define UBD_MAX_REQUEST (8 * sizeof(long)) +struct io_desc { + char *buffer; + unsigned long length; + unsigned long sector_mask; + unsigned long long cow_offset; + unsigned long bitmap_words[2]; +}; + struct io_thread_req { struct request *req; int fds[2]; unsigned long offsets[2]; unsigned long long offset; - unsigned long length; - char *buffer; int sectorsize; - unsigned long sector_mask; - unsigned long long cow_offset; - unsigned long bitmap_words[2]; int error; + + int desc_cnt; + /* io_desc has to be the last element of the struct */ + struct io_desc io_desc[]; }; @@ -524,12 +531,7 @@ blk_queue_max_write_zeroes_sectors(io_req->req->q, 0); blk_queue_flag_clear(QUEUE_FLAG_DISCARD, io_req->req->q); } - if ((io_req->error) || (io_req->buffer == NULL)) - blk_mq_end_request(io_req->req, io_req->error); - else { - if (!blk_update_request(io_req->req, io_req->error, io_req->length)) - __blk_mq_end_request(io_req->req, io_req->error); - } + blk_mq_end_request(io_req->req, io_req->error); kfree(io_req); } } @@ -858,7 +860,7 @@ static void ubd_device_release(struct device *dev) { - struct ubd *ubd_dev = dev_get_drvdata(dev); + struct ubd *ubd_dev = container_of(dev, struct ubd, pdev.dev); blk_cleanup_queue(ubd_dev->queue); blk_mq_free_tag_set(&ubd_dev->tag_set); @@ -945,6 +947,7 @@ blk_queue_write_cache(ubd_dev->queue, true, false); blk_queue_max_segments(ubd_dev->queue, MAX_SG); + blk_queue_segment_boundary(ubd_dev->queue, PAGE_SIZE - 1); err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1154,7 +1157,7 @@ if (irq_req_buffer == NULL) { printk(KERN_ERR "Failed to initialize ubd buffering\n"); - return -1; + return -ENOMEM; } io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, sizeof(struct io_thread_req *), @@ -1165,7 +1168,7 @@ if (io_req_buffer == NULL) { printk(KERN_ERR "Failed to initialize ubd buffering\n"); - return -1; + return -ENOMEM; } platform_driver_register(&ubd_driver); mutex_lock(&ubd_lock); @@ -1288,37 +1291,74 @@ *cow_offset += bitmap_offset; } -static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, +static void cowify_req(struct io_thread_req *req, struct io_desc *segment, + unsigned long offset, unsigned long *bitmap, __u64 bitmap_offset, __u64 bitmap_len) { - __u64 sector = req->offset >> SECTOR_SHIFT; + __u64 sector = offset >> SECTOR_SHIFT; int i; - if (req->length > (sizeof(req->sector_mask) * 8) << SECTOR_SHIFT) + if (segment->length > (sizeof(segment->sector_mask) * 8) << SECTOR_SHIFT) panic("Operation too long"); if (req_op(req->req) == REQ_OP_READ) { - for (i = 0; i < req->length >> SECTOR_SHIFT; i++) { + for (i = 0; i < segment->length >> SECTOR_SHIFT; i++) { if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) ubd_set_bit(i, (unsigned char *) - &req->sector_mask); + &segment->sector_mask); + } + } else { + cowify_bitmap(offset, segment->length, &segment->sector_mask, + &segment->cow_offset, bitmap, bitmap_offset, + segment->bitmap_words, bitmap_len); + } +} + +static void ubd_map_req(struct ubd *dev, struct io_thread_req *io_req, + struct request *req) +{ + struct bio_vec bvec; + struct req_iterator iter; + int i = 0; + unsigned long byte_offset = io_req->offset; + int op = req_op(req); + + if (op == REQ_OP_WRITE_ZEROES || op == REQ_OP_DISCARD) { + io_req->io_desc[0].buffer = NULL; + io_req->io_desc[0].length = blk_rq_bytes(req); + } else { + rq_for_each_segment(bvec, req, iter) { + BUG_ON(i >= io_req->desc_cnt); + + io_req->io_desc[i].buffer = + page_address(bvec.bv_page) + bvec.bv_offset; + io_req->io_desc[i].length = bvec.bv_len; + i++; + } + } + + if (dev->cow.file) { + for (i = 0; i < io_req->desc_cnt; i++) { + cowify_req(io_req, &io_req->io_desc[i], byte_offset, + dev->cow.bitmap, dev->cow.bitmap_offset, + dev->cow.bitmap_len); + byte_offset += io_req->io_desc[i].length; } + } - else cowify_bitmap(req->offset, req->length, &req->sector_mask, - &req->cow_offset, bitmap, bitmap_offset, - req->bitmap_words, bitmap_len); } -static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req, - u64 off, struct bio_vec *bvec) +static struct io_thread_req *ubd_alloc_req(struct ubd *dev, struct request *req, + int desc_cnt) { - struct ubd *dev = hctx->queue->queuedata; struct io_thread_req *io_req; - int ret; + int i; - io_req = kmalloc(sizeof(struct io_thread_req), GFP_ATOMIC); + io_req = kmalloc(sizeof(*io_req) + + (desc_cnt * sizeof(struct io_desc)), + GFP_ATOMIC); if (!io_req) - return -ENOMEM; + return NULL; io_req->req = req; if (dev->cow.file) @@ -1326,26 +1366,41 @@ else io_req->fds[0] = dev->fd; io_req->error = 0; - - if (bvec != NULL) { - io_req->buffer = page_address(bvec->bv_page) + bvec->bv_offset; - io_req->length = bvec->bv_len; - } else { - io_req->buffer = NULL; - io_req->length = blk_rq_bytes(req); - } - io_req->sectorsize = SECTOR_SIZE; io_req->fds[1] = dev->fd; - io_req->cow_offset = -1; - io_req->offset = off; - io_req->sector_mask = 0; + io_req->offset = (u64) blk_rq_pos(req) << SECTOR_SHIFT; io_req->offsets[0] = 0; io_req->offsets[1] = dev->cow.data_offset; - if (dev->cow.file) - cowify_req(io_req, dev->cow.bitmap, - dev->cow.bitmap_offset, dev->cow.bitmap_len); + for (i = 0 ; i < desc_cnt; i++) { + io_req->io_desc[i].sector_mask = 0; + io_req->io_desc[i].cow_offset = -1; + } + + return io_req; +} + +static int ubd_submit_request(struct ubd *dev, struct request *req) +{ + int segs = 0; + struct io_thread_req *io_req; + int ret; + int op = req_op(req); + + if (op == REQ_OP_FLUSH) + segs = 0; + else if (op == REQ_OP_WRITE_ZEROES || op == REQ_OP_DISCARD) + segs = 1; + else + segs = blk_rq_nr_phys_segments(req); + + io_req = ubd_alloc_req(dev, req, segs); + if (!io_req) + return -ENOMEM; + + io_req->desc_cnt = segs; + if (segs) + ubd_map_req(dev, io_req, req); ret = os_write_file(thread_fd, &io_req, sizeof(io_req)); if (ret != sizeof(io_req)) { @@ -1356,22 +1411,6 @@ return ret; } -static int queue_rw_req(struct blk_mq_hw_ctx *hctx, struct request *req) -{ - struct req_iterator iter; - struct bio_vec bvec; - int ret; - u64 off = (u64)blk_rq_pos(req) << SECTOR_SHIFT; - - rq_for_each_segment(bvec, req, iter) { - ret = ubd_queue_one_vec(hctx, req, off, &bvec); - if (ret < 0) - return ret; - off += bvec.bv_len; - } - return 0; -} - static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1384,17 +1423,12 @@ spin_lock_irq(&ubd_dev->lock); switch (req_op(req)) { - /* operations with no lentgth/offset arguments */ case REQ_OP_FLUSH: - ret = ubd_queue_one_vec(hctx, req, 0, NULL); - break; case REQ_OP_READ: case REQ_OP_WRITE: - ret = queue_rw_req(hctx, req); - break; case REQ_OP_DISCARD: case REQ_OP_WRITE_ZEROES: - ret = ubd_queue_one_vec(hctx, req, (u64)blk_rq_pos(req) << 9, NULL); + ret = ubd_submit_request(ubd_dev, req); break; default: WARN_ON_ONCE(1); @@ -1482,22 +1516,22 @@ * will result in unpredictable behaviour and/or crashes. */ -static int update_bitmap(struct io_thread_req *req) +static int update_bitmap(struct io_thread_req *req, struct io_desc *segment) { int n; - if(req->cow_offset == -1) + if (segment->cow_offset == -1) return map_error(0); - n = os_pwrite_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words), req->cow_offset); - if (n != sizeof(req->bitmap_words)) + n = os_pwrite_file(req->fds[1], &segment->bitmap_words, + sizeof(segment->bitmap_words), segment->cow_offset); + if (n != sizeof(segment->bitmap_words)) return map_error(-n); return map_error(0); } -static void do_io(struct io_thread_req *req) +static void do_io(struct io_thread_req *req, struct io_desc *desc) { char *buf = NULL; unsigned long len; @@ -1512,21 +1546,20 @@ return; } - nsectors = req->length / req->sectorsize; + nsectors = desc->length / req->sectorsize; start = 0; do { - bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); + bit = ubd_test_bit(start, (unsigned char *) &desc->sector_mask); end = start; while((end < nsectors) && - (ubd_test_bit(end, (unsigned char *) - &req->sector_mask) == bit)) + (ubd_test_bit(end, (unsigned char *) &desc->sector_mask) == bit)) end++; off = req->offset + req->offsets[bit] + start * req->sectorsize; len = (end - start) * req->sectorsize; - if (req->buffer != NULL) - buf = &req->buffer[start * req->sectorsize]; + if (desc->buffer != NULL) + buf = &desc->buffer[start * req->sectorsize]; switch (req_op(req->req)) { case REQ_OP_READ: @@ -1566,7 +1599,8 @@ start = end; } while(start < nsectors); - req->error = update_bitmap(req); + req->offset += len; + req->error = update_bitmap(req, desc); } /* Changed in start_io_thread, which is serialized by being called only @@ -1599,14 +1633,21 @@ } for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { + struct io_thread_req *req = (*io_req_buffer)[count]; + int i; + io_count++; - do_io((*io_req_buffer)[count]); + for (i = 0; !req->error && i < req->desc_cnt; i++) + do_io(req, &(req->io_desc[i])); + } written = 0; do { - res = os_write_file(kernel_fd, ((char *) io_req_buffer) + written, n); + res = os_write_file(kernel_fd, + ((char *) io_req_buffer) + written, + n - written); if (res >= 0) { written += res; } --- linux-oracle-5.4.0.orig/arch/um/drivers/vector_kern.c +++ linux-oracle-5.4.0/arch/um/drivers/vector_kern.c @@ -746,6 +746,7 @@ if (parsed == NULL) { *error_out = "vector_config failed to parse parameters"; + kfree(params); return -EINVAL; } @@ -801,7 +802,8 @@ static void vector_device_release(struct device *dev) { - struct vector_device *device = dev_get_drvdata(dev); + struct vector_device *device = + container_of(dev, struct vector_device, pdev.dev); struct net_device *netdev = device->dev; list_del(&device->list); --- linux-oracle-5.4.0.orig/arch/um/drivers/virtio_uml.c +++ linux-oracle-5.4.0/arch/um/drivers/virtio_uml.c @@ -4,12 +4,12 @@ * * Copyright(c) 2019 Intel Corporation * - * This module allows virtio devices to be used over a vhost-user socket. + * This driver allows virtio devices to be used over a vhost-user socket. * * Guest devices can be instantiated by kernel module or command line * parameters. One device will be created for each parameter. Syntax: * - * [virtio_uml.]device=:[:] + * virtio_uml.device=:[:] * where: * := vhost-user socket path to connect * := virtio device id (as in virtio_ids.h) @@ -83,7 +83,7 @@ return 0; } -static int full_read(int fd, void *buf, int len) +static int full_read(int fd, void *buf, int len, bool abortable) { int rc; @@ -93,7 +93,7 @@ buf += rc; len -= rc; } - } while (len && (rc > 0 || rc == -EINTR)); + } while (len && (rc > 0 || rc == -EINTR || (!abortable && rc == -EAGAIN))); if (rc < 0) return rc; @@ -104,7 +104,7 @@ static int vhost_user_recv_header(int fd, struct vhost_user_msg *msg) { - return full_read(fd, msg, sizeof(msg->header)); + return full_read(fd, msg, sizeof(msg->header), true); } static int vhost_user_recv(int fd, struct vhost_user_msg *msg, @@ -118,7 +118,7 @@ size = msg->header.size; if (size > max_payload_size) return -EPROTO; - return full_read(fd, &msg->payload, size); + return full_read(fd, &msg->payload, size, false); } static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, @@ -959,6 +959,7 @@ } os_close_file(vu_dev->sock); + kfree(vu_dev); } /* Platform device */ @@ -977,7 +978,7 @@ if (!pdata) return -EINVAL; - vu_dev = devm_kzalloc(&pdev->dev, sizeof(*vu_dev), GFP_KERNEL); + vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); if (!vu_dev) return -ENOMEM; @@ -993,7 +994,7 @@ rc = os_connect_socket(pdata->socket_path); } while (rc == -EINTR); if (rc < 0) - return rc; + goto error_free; vu_dev->sock = rc; rc = vhost_user_init(vu_dev); @@ -1009,6 +1010,8 @@ error_init: os_close_file(vu_dev->sock); +error_free: + kfree(vu_dev); return rc; } --- linux-oracle-5.4.0.orig/arch/um/drivers/xterm.c +++ linux-oracle-5.4.0/arch/um/drivers/xterm.c @@ -18,6 +18,7 @@ struct xterm_chan { int pid; int helper_pid; + int chan_fd; char *title; int device; int raw; @@ -33,6 +34,7 @@ return NULL; *data = ((struct xterm_chan) { .pid = -1, .helper_pid = -1, + .chan_fd = -1, .device = device, .title = opts->xterm_title, .raw = opts->raw } ); @@ -149,6 +151,7 @@ goto out_kill; } + data->chan_fd = fd; new = xterm_fd(fd, &data->helper_pid); if (new < 0) { err = new; @@ -206,6 +209,8 @@ os_kill_process(data->helper_pid, 0); data->helper_pid = -1; + if (data->chan_fd != -1) + os_close_file(data->chan_fd); os_close_file(fd); } --- linux-oracle-5.4.0.orig/arch/um/include/asm/common.lds.S +++ linux-oracle-5.4.0/arch/um/include/asm/common.lds.S @@ -83,8 +83,8 @@ __preinit_array_end = .; } .init_array : { - /* dummy - we call this ourselves */ __init_array_start = .; + *(.init_array) __init_array_end = .; } .fini_array : { --- linux-oracle-5.4.0.orig/arch/um/include/asm/mmu.h +++ linux-oracle-5.4.0/arch/um/include/asm/mmu.h @@ -15,8 +15,6 @@ struct page *stub_pages[2]; } mm_context_t; -extern void __switch_mm(struct mm_id * mm_idp); - /* Avoid tangled inclusion with asm/ldt.h */ extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm); extern void free_ldt(struct mm_context *mm); --- linux-oracle-5.4.0.orig/arch/um/include/asm/ptrace-generic.h +++ linux-oracle-5.4.0/arch/um/include/asm/ptrace-generic.h @@ -36,7 +36,7 @@ extern unsigned long getreg(struct task_struct *child, int regno); extern int putreg(struct task_struct *child, int regno, unsigned long value); -extern int arch_copy_tls(struct task_struct *new); +extern int arch_set_tls(struct task_struct *new, unsigned long tls); extern void clear_flushed_tls(struct task_struct *task); extern int syscall_trace_enter(struct pt_regs *regs); extern void syscall_trace_leave(struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/um/include/asm/thread_info.h +++ linux-oracle-5.4.0/arch/um/include/asm/thread_info.h @@ -63,6 +63,7 @@ #define TIF_RESTORE_SIGMASK 7 #define TIF_NOTIFY_RESUME 8 #define TIF_SECCOMP 9 /* secure computing */ +#define TIF_SINGLESTEP 10 /* single stepping userspace */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -70,5 +71,6 @@ #define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #endif --- linux-oracle-5.4.0.orig/arch/um/include/asm/timex.h +++ linux-oracle-5.4.0/arch/um/include/asm/timex.h @@ -2,13 +2,8 @@ #ifndef __UM_TIMEX_H #define __UM_TIMEX_H -typedef unsigned long cycles_t; - -static inline cycles_t get_cycles (void) -{ - return 0; -} - #define CLOCK_TICK_RATE (HZ) +#include + #endif --- linux-oracle-5.4.0.orig/arch/um/include/shared/kern_util.h +++ linux-oracle-5.4.0/arch/um/include/shared/kern_util.h @@ -49,7 +49,7 @@ * Are we disallowed to sleep? Used to choose between GFP_KERNEL and * GFP_ATOMIC. */ -extern int __cant_sleep(void); +extern int __uml_cant_sleep(void); extern int get_current_pid(void); extern int copy_from_user_proc(void *to, void *from, int size); extern int cpu(void); --- linux-oracle-5.4.0.orig/arch/um/include/shared/registers.h +++ linux-oracle-5.4.0/arch/um/include/shared/registers.h @@ -16,8 +16,8 @@ extern int save_fpx_registers(int pid, unsigned long *fp_regs); extern int restore_fpx_registers(int pid, unsigned long *fp_regs); extern int save_registers(int pid, struct uml_pt_regs *regs); -extern int restore_registers(int pid, struct uml_pt_regs *regs); -extern int init_registers(int pid); +extern int restore_pid_registers(int pid, struct uml_pt_regs *regs); +extern int init_pid_registers(int pid); extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); extern unsigned long get_thread_reg(int reg, jmp_buf *buf); extern int get_fp_registers(int pid, unsigned long *regs); --- linux-oracle-5.4.0.orig/arch/um/include/shared/skas/mm_id.h +++ linux-oracle-5.4.0/arch/um/include/shared/skas/mm_id.h @@ -14,4 +14,6 @@ unsigned long stack; }; +void __switch_mm(struct mm_id *mm_idp); + #endif --- linux-oracle-5.4.0.orig/arch/um/kernel/Makefile +++ linux-oracle-5.4.0/arch/um/kernel/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o -obj-$(CONFIG_GCOV) += gmon_syms.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_STACKTRACE) += stacktrace.o --- linux-oracle-5.4.0.orig/arch/um/kernel/dyn.lds.S +++ linux-oracle-5.4.0/arch/um/kernel/dyn.lds.S @@ -6,6 +6,12 @@ ENTRY(_start) jiffies = jiffies_64; +VERSION { + { + local: *; + }; +} + SECTIONS { PROVIDE (__executable_start = START); @@ -103,6 +109,7 @@ be empty, which isn't pretty. */ . = ALIGN(32 / 8); .preinit_array : { *(.preinit_array) } + .init_array : { *(.init_array) } .fini_array : { *(.fini_array) } .data : { INIT_TASK_DATA(KERNEL_STACK_SIZE) --- linux-oracle-5.4.0.orig/arch/um/kernel/exec.c +++ linux-oracle-5.4.0/arch/um/kernel/exec.c @@ -44,7 +44,7 @@ { PT_REGS_IP(regs) = eip; PT_REGS_SP(regs) = esp; - current->ptrace &= ~PT_DTRACE; + clear_thread_flag(TIF_SINGLESTEP); #ifdef SUBARCH_EXECVE1 SUBARCH_EXECVE1(regs->regs); #endif --- linux-oracle-5.4.0.orig/arch/um/kernel/mem.c +++ linux-oracle-5.4.0/arch/um/kernel/mem.c @@ -154,8 +154,8 @@ void __init paging_init(void) { - unsigned long zones_size[MAX_NR_ZONES], vaddr; - int i; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; + unsigned long vaddr; empty_zero_page = (unsigned long *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE); @@ -163,12 +163,8 @@ panic("%s: Failed to allocate %lu bytes align=%lx\n", __func__, PAGE_SIZE, PAGE_SIZE); - for (i = 0; i < ARRAY_SIZE(zones_size); i++) - zones_size[i] = 0; - - zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - - (uml_physmem >> PAGE_SHIFT); - free_area_init(zones_size); + max_zone_pfn[ZONE_NORMAL] = end_iomem >> PAGE_SHIFT; + free_area_init(max_zone_pfn); /* * Fixed mappings, only the page table structure has to be --- linux-oracle-5.4.0.orig/arch/um/kernel/physmem.c +++ linux-oracle-5.4.0/arch/um/kernel/physmem.c @@ -80,10 +80,10 @@ unsigned long len, unsigned long long highmem) { unsigned long reserve = reserve_end - start; - long map_size = len - reserve; + unsigned long map_size = len - reserve; int err; - if(map_size <= 0) { + if (len <= reserve) { os_warn("Too few physical memory! Needed=%lu, given=%lu\n", reserve, len); exit(1); @@ -94,7 +94,7 @@ err = os_map_memory((void *) reserve_end, physmem_fd, reserve, map_size, 1, 1, 1); if (err < 0) { - os_warn("setup_physmem - mapping %ld bytes of memory at 0x%p " + os_warn("setup_physmem - mapping %lu bytes of memory at 0x%p " "failed - errno = %d\n", map_size, (void *) reserve_end, err); exit(1); --- linux-oracle-5.4.0.orig/arch/um/kernel/process.c +++ linux-oracle-5.4.0/arch/um/kernel/process.c @@ -153,8 +153,8 @@ userspace(¤t->thread.regs.regs, current_thread_info()->aux_fp_regs); } -int copy_thread(unsigned long clone_flags, unsigned long sp, - unsigned long arg, struct task_struct * p) +int copy_thread_tls(unsigned long clone_flags, unsigned long sp, + unsigned long arg, struct task_struct * p, unsigned long tls) { void (*handler)(void); int kthread = current->flags & PF_KTHREAD; @@ -188,7 +188,7 @@ * Set a new TLS for the child thread? */ if (clone_flags & CLONE_SETTLS) - ret = arch_copy_tls(p); + ret = arch_set_tls(p, tls); } return ret; @@ -258,7 +258,7 @@ local_irq_enable(); } -int __cant_sleep(void) { +int __uml_cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } @@ -380,7 +380,7 @@ { struct task_struct *task = t ? t : current; - if (!(task->ptrace & PT_DTRACE)) + if (!test_thread_flag(TIF_SINGLESTEP)) return 0; if (task->thread.singlestep_syscall) @@ -444,6 +444,6 @@ { int cpu = current_thread_info()->cpu; - return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu); + return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu) == 0; } --- linux-oracle-5.4.0.orig/arch/um/kernel/ptrace.c +++ linux-oracle-5.4.0/arch/um/kernel/ptrace.c @@ -12,7 +12,7 @@ void user_enable_single_step(struct task_struct *child) { - child->ptrace |= PT_DTRACE; + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->thread.singlestep_syscall = 0; #ifdef SUBARCH_SET_SINGLESTEPPING @@ -22,7 +22,7 @@ void user_disable_single_step(struct task_struct *child) { - child->ptrace &= ~PT_DTRACE; + clear_tsk_thread_flag(child, TIF_SINGLESTEP); child->thread.singlestep_syscall = 0; #ifdef SUBARCH_SET_SINGLESTEPPING @@ -121,7 +121,7 @@ } /* - * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and + * XXX Check TIF_SINGLESTEP for singlestepping check and * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check */ int syscall_trace_enter(struct pt_regs *regs) @@ -145,7 +145,7 @@ audit_syscall_exit(regs); /* Fake a debug trap */ - if (ptraced & PT_DTRACE) + if (test_thread_flag(TIF_SINGLESTEP)) send_sigtrap(®s->regs, 0); if (!test_thread_flag(TIF_SYSCALL_TRACE)) --- linux-oracle-5.4.0.orig/arch/um/kernel/sigio.c +++ linux-oracle-5.4.0/arch/um/kernel/sigio.c @@ -35,14 +35,14 @@ } /* These are called from os-Linux/sigio.c to protect its pollfds arrays. */ -static DEFINE_SPINLOCK(sigio_spinlock); +static DEFINE_MUTEX(sigio_mutex); void sigio_lock(void) { - spin_lock(&sigio_spinlock); + mutex_lock(&sigio_mutex); } void sigio_unlock(void) { - spin_unlock(&sigio_spinlock); + mutex_unlock(&sigio_mutex); } --- linux-oracle-5.4.0.orig/arch/um/kernel/signal.c +++ linux-oracle-5.4.0/arch/um/kernel/signal.c @@ -53,7 +53,7 @@ unsigned long sp; int err; - if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED)) + if (test_thread_flag(TIF_SINGLESTEP) && (current->ptrace & PT_PTRACED)) singlestep = 1; /* Did we come from a system call? */ @@ -128,7 +128,7 @@ * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ - if (current->ptrace & PT_DTRACE) + if (test_thread_flag(TIF_SINGLESTEP)) current->thread.singlestep_syscall = is_syscall(PT_REGS_IP(¤t->thread.regs)); --- linux-oracle-5.4.0.orig/arch/um/kernel/sysrq.c +++ linux-oracle-5.4.0/arch/um/kernel/sysrq.c @@ -17,7 +17,9 @@ static void _print_addr(void *data, unsigned long address, int reliable) { - pr_info(" [<%08lx>] %s%pS\n", address, reliable ? "" : "? ", + const char *loglvl = data; + + printk("%s [<%08lx>] %s%pS\n", loglvl, address, reliable ? "" : "? ", (void *)address); } @@ -25,9 +27,9 @@ .address = _print_addr }; -void show_stack(struct task_struct *task, unsigned long *stack) +void show_stack_loglvl(struct task_struct *task, unsigned long *stack, + const char *loglvl) { - unsigned long *sp = stack; struct pt_regs *segv_regs = current->thread.segv_regs; int i; @@ -38,10 +40,9 @@ } if (!stack) - sp = get_stack_pointer(task, segv_regs); + stack = get_stack_pointer(task, segv_regs); - pr_info("Stack:\n"); - stack = sp; + printk("%sStack:\n", loglvl); for (i = 0; i < 3 * STACKSLOTS_PER_LINE; i++) { if (kstack_end(stack)) break; @@ -49,9 +50,12 @@ pr_cont("\n"); pr_cont(" %08lx", *stack++); } - pr_cont("\n"); - pr_info("Call Trace:\n"); - dump_trace(current, &stackops, NULL); - pr_info("\n"); + printk("%sCall Trace:\n", loglvl); + dump_trace(task ?: current, &stackops, (void *)loglvl); +} + +void show_stack(struct task_struct *task, unsigned long *stack) +{ + show_stack_loglvl(task, stack, KERN_INFO); } --- linux-oracle-5.4.0.orig/arch/um/kernel/time.c +++ linux-oracle-5.4.0/arch/um/kernel/time.c @@ -256,9 +256,9 @@ return 1; } -__setup("time-travel-start", setup_time_travel_start); +__setup("time-travel-start=", setup_time_travel_start); __uml_help(setup_time_travel_start, -"time-travel-start=\n" +"time-travel-start=\n" "Configure the UML instance's wall clock to start at this value rather than\n" "the host's wall clock at the time of UML boot.\n"); #endif --- linux-oracle-5.4.0.orig/arch/um/kernel/tlb.c +++ linux-oracle-5.4.0/arch/um/kernel/tlb.c @@ -126,6 +126,9 @@ struct host_vm_op *last; int fd = -1, ret = 0; + if (virt + len > STUB_START && virt < STUB_END) + return -EINVAL; + if (hvc->userspace) fd = phys_mapping(phys, &offset); else @@ -163,7 +166,7 @@ struct host_vm_op *last; int ret = 0; - if ((addr >= STUB_START) && (addr < STUB_END)) + if (addr + len > STUB_START && addr < STUB_END) return -EINVAL; if (hvc->index != 0) { @@ -193,6 +196,9 @@ struct host_vm_op *last; int ret = 0; + if (addr + len > STUB_START && addr < STUB_END) + return -EINVAL; + if (hvc->index != 0) { last = &hvc->ops[hvc->index - 1]; if ((last->type == MPROTECT) && @@ -433,6 +439,10 @@ struct mm_id *mm_id; address &= PAGE_MASK; + + if (address >= STUB_START && address < STUB_END) + goto kill; + pgd = pgd_offset(mm, address); if (!pgd_present(*pgd)) goto kill; --- linux-oracle-5.4.0.orig/arch/um/kernel/um_arch.c +++ linux-oracle-5.4.0/arch/um/kernel/um_arch.c @@ -3,6 +3,7 @@ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) */ +#include #include #include #include @@ -77,7 +78,7 @@ static void *c_start(struct seq_file *m, loff_t *pos) { - return *pos < NR_CPUS ? cpu_data + *pos : NULL; + return *pos < nr_cpu_ids ? cpu_data + *pos : NULL; } static void *c_next(struct seq_file *m, void *v, loff_t *pos) @@ -353,7 +354,7 @@ setup_hostinfo(host_info, sizeof host_info); } -void __init check_bugs(void) +void __init arch_cpu_finalize_init(void) { arch_check_bugs(); os_check_bugs(); --- linux-oracle-5.4.0.orig/arch/um/kernel/uml.lds.S +++ linux-oracle-5.4.0/arch/um/kernel/uml.lds.S @@ -7,6 +7,12 @@ ENTRY(_start) jiffies = jiffies_64; +VERSION { + { + local: *; + }; +} + SECTIONS { /* This must contain the right address - not quite the default ELF one.*/ --- linux-oracle-5.4.0.orig/arch/um/kernel/vmlinux.lds.S +++ linux-oracle-5.4.0/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,4 @@ - +#define RUNTIME_DISCARD_EXIT KERNEL_STACK_SIZE = 4096 * (1 << CONFIG_KERNEL_STACK_ORDER); #ifdef CONFIG_LD_SCRIPT_STATIC --- linux-oracle-5.4.0.orig/arch/um/os-Linux/file.c +++ linux-oracle-5.4.0/arch/um/os-Linux/file.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include --- linux-oracle-5.4.0.orig/arch/um/os-Linux/helper.c +++ linux-oracle-5.4.0/arch/um/os-Linux/helper.c @@ -45,7 +45,7 @@ unsigned long stack, sp; int pid, fds[2], ret, n; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(0, __uml_cant_sleep()); if (stack == 0) return -ENOMEM; @@ -69,7 +69,7 @@ data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; - data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : + data.buf = __uml_cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : uml_kmalloc(PATH_MAX, UM_GFP_KERNEL); pid = clone(helper_child, (void *) sp, CLONE_VM, &data); if (pid < 0) { @@ -116,7 +116,7 @@ unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(0, __uml_cant_sleep()); if (stack == 0) return -ENOMEM; --- linux-oracle-5.4.0.orig/arch/um/os-Linux/irq.c +++ linux-oracle-5.4.0/arch/um/os-Linux/irq.c @@ -48,7 +48,7 @@ int os_event_mask(int irq_type) { if (irq_type == IRQ_READ) - return EPOLLIN | EPOLLPRI; + return EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP | EPOLLRDHUP; if (irq_type == IRQ_WRITE) return EPOLLOUT; return 0; --- linux-oracle-5.4.0.orig/arch/um/os-Linux/main.c +++ linux-oracle-5.4.0/arch/um/os-Linux/main.c @@ -170,7 +170,7 @@ * that they won't be delivered after the exec, when * they are definitely not expected. */ - unblock_signals_trace(); + unblock_signals(); os_info("\n"); /* Reboot */ --- linux-oracle-5.4.0.orig/arch/um/os-Linux/registers.c +++ linux-oracle-5.4.0/arch/um/os-Linux/registers.c @@ -21,7 +21,7 @@ return 0; } -int restore_registers(int pid, struct uml_pt_regs *regs) +int restore_pid_registers(int pid, struct uml_pt_regs *regs) { int err; @@ -36,7 +36,7 @@ static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[FP_SIZE]; -int init_registers(int pid) +int init_pid_registers(int pid) { int err; --- linux-oracle-5.4.0.orig/arch/um/os-Linux/skas/process.c +++ linux-oracle-5.4.0/arch/um/os-Linux/skas/process.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -641,10 +642,24 @@ UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); } +static bool noreboot; + +static int __init noreboot_cmd_param(char *str, int *add) +{ + noreboot = true; + return 0; +} + +__uml_setup("noreboot", noreboot_cmd_param, +"noreboot\n" +" Rather than rebooting, exit always, akin to QEMU's -no-reboot option.\n" +" This is useful if you're using CONFIG_PANIC_TIMEOUT in order to catch\n" +" crashes in CI\n"); + void reboot_skas(void) { block_signals_trace(); - UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); + UML_LONGJMP(&initial_jmpbuf, noreboot ? INIT_JMP_HALT : INIT_JMP_REBOOT); } void __switch_mm(struct mm_id *mm_idp) --- linux-oracle-5.4.0.orig/arch/um/os-Linux/start_up.c +++ linux-oracle-5.4.0/arch/um/os-Linux/start_up.c @@ -336,7 +336,7 @@ check_tmpexec(); pid = start_ptraced_child(); - if (init_registers(pid)) + if (init_pid_registers(pid)) fatal("Failed to initialize default registers"); stop_ptraced_child(pid, 1, 1); } --- linux-oracle-5.4.0.orig/arch/um/os-Linux/umid.c +++ linux-oracle-5.4.0/arch/um/os-Linux/umid.c @@ -137,20 +137,13 @@ { char pid[sizeof("nnnnn\0")], *end, *file; int dead, fd, p, n, err; - size_t filelen; + size_t filelen = strlen(dir) + sizeof("/pid") + 1; - err = asprintf(&file, "%s/pid", dir); - if (err < 0) - return 0; + file = malloc(filelen); + if (!file) + return -ENOMEM; - filelen = strlen(file); - - n = snprintf(file, filelen, "%s/pid", dir); - if (n >= filelen) { - printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n"); - err = -E2BIG; - goto out; - } + snprintf(file, filelen, "%s/pid", dir); dead = 0; fd = open(file, O_RDONLY); --- linux-oracle-5.4.0.orig/arch/um/os-Linux/util.c +++ linux-oracle-5.4.0/arch/um/os-Linux/util.c @@ -166,23 +166,38 @@ "quiet\n" " Turns off information messages during boot.\n\n"); +/* + * The os_info/os_warn functions will be called by helper threads. These + * have a very limited stack size and using the libc formatting functions + * may overflow the stack. + * So pull in the kernel vscnprintf and use that instead with a fixed + * on-stack buffer. + */ +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); + void os_info(const char *fmt, ...) { + char buf[256]; va_list list; + int len; if (quiet_info) return; va_start(list, fmt); - vfprintf(stderr, fmt, list); + len = vscnprintf(buf, sizeof(buf), fmt, list); + fwrite(buf, len, 1, stderr); va_end(list); } void os_warn(const char *fmt, ...) { + char buf[256]; va_list list; + int len; va_start(list, fmt); - vfprintf(stderr, fmt, list); + len = vscnprintf(buf, sizeof(buf), fmt, list); + fwrite(buf, len, 1, stderr); va_end(list); } --- linux-oracle-5.4.0.orig/arch/unicore32/include/asm/memory.h +++ linux-oracle-5.4.0/arch/unicore32/include/asm/memory.h @@ -60,7 +60,7 @@ #ifndef __ASSEMBLY__ #ifndef arch_adjust_zones -#define arch_adjust_zones(size, holes) do { } while (0) +#define arch_adjust_zones(max_zone_pfn) do { } while (0) #endif /* --- linux-oracle-5.4.0.orig/arch/unicore32/include/mach/memory.h +++ linux-oracle-5.4.0/arch/unicore32/include/mach/memory.h @@ -25,10 +25,10 @@ #if !defined(__ASSEMBLY__) && defined(CONFIG_PCI) -void puv3_pci_adjust_zones(unsigned long *size, unsigned long *holes); +void puv3_pci_adjust_zones(unsigned long *max_zone_pfn); -#define arch_adjust_zones(size, holes) \ - puv3_pci_adjust_zones(size, holes) +#define arch_adjust_zones(max_zone_pfn) \ + puv3_pci_adjust_zones(max_zone_pfn) #endif --- linux-oracle-5.4.0.orig/arch/unicore32/kernel/pci.c +++ linux-oracle-5.4.0/arch/unicore32/kernel/pci.c @@ -133,21 +133,11 @@ * This is really ugly and we need a better way of specifying * DMA-capable regions of memory. */ -void __init puv3_pci_adjust_zones(unsigned long *zone_size, - unsigned long *zhole_size) +void __init puv3_pci_adjust_zones(unsigned long max_zone_pfn) { unsigned int sz = SZ_128M >> PAGE_SHIFT; - /* - * Only adjust if > 128M on current system - */ - if (zone_size[0] <= sz) - return; - - zone_size[1] = zone_size[0] - sz; - zone_size[0] = sz; - zhole_size[1] = zhole_size[0]; - zhole_size[0] = 0; + max_zone_pfn[ZONE_DMA] = sz; } /* --- linux-oracle-5.4.0.orig/arch/unicore32/mm/init.c +++ linux-oracle-5.4.0/arch/unicore32/mm/init.c @@ -61,46 +61,21 @@ } } -static void __init uc32_bootmem_free(unsigned long min, unsigned long max_low, - unsigned long max_high) +static void __init uc32_bootmem_free(unsigned long max_low) { - unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES]; - struct memblock_region *reg; + unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 }; - /* - * initialise the zones. - */ - memset(zone_size, 0, sizeof(zone_size)); - - /* - * The memory size has already been determined. If we need - * to do anything fancy with the allocation of this memory - * to the zones, now is the time to do it. - */ - zone_size[0] = max_low - min; - - /* - * Calculate the size of the holes. - * holes = node_size - sum(bank_sizes) - */ - memcpy(zhole_size, zone_size, sizeof(zhole_size)); - for_each_memblock(memory, reg) { - unsigned long start = memblock_region_memory_base_pfn(reg); - unsigned long end = memblock_region_memory_end_pfn(reg); - - if (start < max_low) { - unsigned long low_end = min(end, max_low); - zhole_size[0] -= low_end - start; - } - } + max_zone_pfn[ZONE_DMA] = max_low; + max_zone_pfn[ZONE_NORMAL] = max_low; /* * Adjust the sizes according to any special requirements for * this machine type. + * This might lower ZONE_DMA limit. */ - arch_adjust_zones(zone_size, zhole_size); + arch_adjust_zones(max_zone_pfn); - free_area_init_node(0, zone_size, min, zhole_size); + free_area_init(max_zone_pfn); } int pfn_valid(unsigned long pfn) @@ -176,11 +151,11 @@ sparse_init(); /* - * Now free the memory - free_area_init_node needs + * Now free the memory - free_area_init needs * the sparse mem_map arrays initialized by sparse_init() * for memmap_init_zone(), otherwise all PFNs are invalid. */ - uc32_bootmem_free(min, max_low, max_high); + uc32_bootmem_free(max_low); high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1; --- linux-oracle-5.4.0.orig/arch/x86/Kconfig +++ linux-oracle-5.4.0/arch/x86/Kconfig @@ -60,6 +60,7 @@ select ARCH_CLOCKSOURCE_DATA select ARCH_CLOCKSOURCE_INIT select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI + select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_DEBUG_VIRTUAL select ARCH_HAS_DEVMEM_IS_ALLOWED select ARCH_HAS_ELF_RANDOMIZE @@ -73,7 +74,6 @@ select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL - select ARCH_HAS_REFCOUNT select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 select ARCH_HAS_UACCESS_MCSAFE if X86_64 && X86_MCE select ARCH_HAS_SET_MEMORY @@ -185,7 +185,6 @@ select HAVE_KRETPROBES select HAVE_KVM select HAVE_LIVEPATCH if X86_64 - select HAVE_MEMBLOCK_NODE_MAP select HAVE_MIXED_BREAKPOINTS_REGS select HAVE_MOD_ARCH_SPECIFIC select HAVE_MOVE_PMD @@ -550,6 +549,7 @@ depends on X86_EXTENDED_PLATFORM depends on NUMA depends on EFI + depends on KEXEC_CORE depends on X86_X2APIC depends on PCI ---help--- @@ -1424,7 +1424,7 @@ config HIGHMEM64G bool "64GB" - depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !WINCHIP3D && !MK6 + depends on !M486 && !M586 && !M586TSC && !M586MMX && !MGEODE_LX && !MGEODEGX1 && !MCYRIXIII && !MELAN && !MWINCHIPC6 && !MWINCHIP3D && !MK6 select X86_PAE ---help--- Select this if you have a 32-bit processor and more than 4 @@ -1540,7 +1540,6 @@ config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT bool "Activate AMD Secure Memory Encryption (SME) by default" - default y depends on AMD_MEM_ENCRYPT ---help--- Say yes to have system memory encrypted by default if running on @@ -1592,15 +1591,6 @@ ---help--- Enable ACPI SRAT based node topology detection. -# Some NUMA nodes have memory ranges that span -# other nodes. Even though a pfn is valid and -# between a node's start and end pfns, it may not -# reside on that node. See memmap_init_zone() -# for details. -config NODES_SPAN_OTHER_NODES - def_bool y - depends on X86_64_ACPI_NUMA - config NUMA_EMU bool "NUMA emulation" depends on NUMA @@ -1990,6 +1980,7 @@ depends on ACPI select UCS2_STRING select EFI_RUNTIME_WRAPPERS + select ARCH_USE_MEMREMAP_PROT ---help--- This enables the kernel to use EFI runtime services that are available (such as the EFI variable services). @@ -2480,6 +2471,25 @@ endmenu +config GDS_FORCE_MITIGATION + bool "Force GDS Mitigation" + depends on CPU_SUP_INTEL + default n + help + Gather Data Sampling (GDS) is a hardware vulnerability which allows + unprivileged speculative access to data which was previously stored in + vector registers. + + This option is equivalent to setting gather_data_sampling=force on the + command line. The microcode mitigation is used if present, otherwise + AVX is disabled as a mitigation. On affected systems that are missing + the microcode any userspace code that unconditionally uses AVX will + break with this option set. + + Setting this option on systems not vulnerable to GDS has no effect. + + If in doubt, say N. + config ARCH_HAS_ADD_PAGES def_bool y depends on X86_64 && ARCH_ENABLE_MEMORY_HOTPLUG @@ -2500,6 +2510,31 @@ def_bool y depends on X86_64 || X86_PAE +choice + prompt "Clear branch history" + depends on CPU_SUP_INTEL + default SPECTRE_BHI_AUTO + help + Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks + where the branch history buffer is poisoned to speculatively steer + indirect branches. + See + +config SPECTRE_BHI_ON + bool "on" + help + Equivalent to setting spectre_bhi=on command line parameter. +config SPECTRE_BHI_OFF + bool "off" + help + Equivalent to setting spectre_bhi=off command line parameter. +config SPECTRE_BHI_AUTO + bool "auto" + help + Equivalent to setting spectre_bhi=auto command line parameter. + +endchoice + config ARCH_ENABLE_HUGEPAGE_MIGRATION def_bool y depends on X86_64 && HUGETLB_PAGE && MIGRATION --- linux-oracle-5.4.0.orig/arch/x86/Kconfig.cpu +++ linux-oracle-5.4.0/arch/x86/Kconfig.cpu @@ -372,7 +372,7 @@ config X86_MINIMUM_CPU_FAMILY int default "64" if X86_64 - default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCRUSOE || MCORE2 || MK7 || MK8) + default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8) default "5" if X86_32 && X86_CMPXCHG64 default "4" --- linux-oracle-5.4.0.orig/arch/x86/Kconfig.debug +++ linux-oracle-5.4.0/arch/x86/Kconfig.debug @@ -307,6 +307,7 @@ config UNWINDER_FRAME_POINTER bool "Frame pointer unwinder" + select ARCH_WANT_FRAME_POINTERS select FRAME_POINTER ---help--- This option enables the frame pointer unwinder for unwinding kernel @@ -334,7 +335,3 @@ overhead. endchoice - -config FRAME_POINTER - depends on !UNWINDER_ORC && !UNWINDER_GUESS - bool --- linux-oracle-5.4.0.orig/arch/x86/Makefile +++ linux-oracle-5.4.0/arch/x86/Makefile @@ -34,12 +34,13 @@ REALMODE_CFLAGS := $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \ -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \ -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ - -mno-mmx -mno-sse + -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member) REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4)) +REALMODE_CFLAGS += $(CLANG_FLAGS) export REALMODE_CFLAGS # BITS is used as extension for files which are available in a 32 bit @@ -61,6 +62,9 @@ KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow KBUILD_CFLAGS += $(call cc-option,-mno-avx,) +# Intel CET isn't enabled in the kernel +KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) + ifeq ($(CONFIG_X86_32),y) BITS := 32 UTS_MACHINE := i386 --- linux-oracle-5.4.0.orig/arch/x86/Makefile.um +++ linux-oracle-5.4.0/arch/x86/Makefile.um @@ -44,7 +44,7 @@ # Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example. -LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64 +LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib64 LINK-y += -m64 endif --- linux-oracle-5.4.0.orig/arch/x86/boot/Makefile +++ linux-oracle-5.4.0/arch/x86/boot/Makefile @@ -87,7 +87,7 @@ SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' quiet_cmd_zoffset = ZOFFSET $@ cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ @@ -100,7 +100,7 @@ AFLAGS_header.o += -I$(objtree)/$(obj) $(obj)/header.o: $(obj)/zoffset.h -LDFLAGS_setup.elf := -m elf_i386 -T +LDFLAGS_setup.elf := -m elf_i386 -z noexecstack -T $(obj)/setup.elf: $(src)/setup.ld $(SETUP_OBJS) FORCE $(call if_changed,ld) --- linux-oracle-5.4.0.orig/arch/x86/boot/bioscall.S +++ linux-oracle-5.4.0/arch/x86/boot/bioscall.S @@ -32,7 +32,7 @@ movw %dx, %si movw %sp, %di movw $11, %cx - rep; movsd + rep; movsl /* Pop full state from the stack */ popal @@ -67,7 +67,7 @@ jz 4f movw %sp, %si movw $11, %cx - rep; movsd + rep; movsl 4: addw $44, %sp /* Restore state and return */ --- linux-oracle-5.4.0.orig/arch/x86/boot/boot.h +++ linux-oracle-5.4.0/arch/x86/boot/boot.h @@ -110,66 +110,78 @@ static inline u8 rdfs8(addr_t addr) { + u8 *ptr = (u8 *)absolute_pointer(addr); u8 v; - asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); + asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*ptr)); return v; } static inline u16 rdfs16(addr_t addr) { + u16 *ptr = (u16 *)absolute_pointer(addr); u16 v; - asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); + asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*ptr)); return v; } static inline u32 rdfs32(addr_t addr) { + u32 *ptr = (u32 *)absolute_pointer(addr); u32 v; - asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); + asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*ptr)); return v; } static inline void wrfs8(u8 v, addr_t addr) { - asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); + u8 *ptr = (u8 *)absolute_pointer(addr); + asm volatile("movb %1,%%fs:%0" : "+m" (*ptr) : "qi" (v)); } static inline void wrfs16(u16 v, addr_t addr) { - asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); + u16 *ptr = (u16 *)absolute_pointer(addr); + asm volatile("movw %1,%%fs:%0" : "+m" (*ptr) : "ri" (v)); } static inline void wrfs32(u32 v, addr_t addr) { - asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); + u32 *ptr = (u32 *)absolute_pointer(addr); + asm volatile("movl %1,%%fs:%0" : "+m" (*ptr) : "ri" (v)); } static inline u8 rdgs8(addr_t addr) { + u8 *ptr = (u8 *)absolute_pointer(addr); u8 v; - asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); + asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*ptr)); return v; } static inline u16 rdgs16(addr_t addr) { + u16 *ptr = (u16 *)absolute_pointer(addr); u16 v; - asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr)); + asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*ptr)); return v; } static inline u32 rdgs32(addr_t addr) { + u32 *ptr = (u32 *)absolute_pointer(addr); u32 v; - asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr)); + asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*ptr)); return v; } static inline void wrgs8(u8 v, addr_t addr) { - asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v)); + u8 *ptr = (u8 *)absolute_pointer(addr); + asm volatile("movb %1,%%gs:%0" : "+m" (*ptr) : "qi" (v)); } static inline void wrgs16(u16 v, addr_t addr) { - asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v)); + u16 *ptr = (u16 *)absolute_pointer(addr); + asm volatile("movw %1,%%gs:%0" : "+m" (*ptr) : "ri" (v)); } static inline void wrgs32(u32 v, addr_t addr) { - asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v)); + u32 *ptr = (u32 *)absolute_pointer(addr); + asm volatile("movl %1,%%gs:%0" : "+m" (*ptr) : "ri" (v)); } /* Note: these only return true/false, not a signed return value! */ --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/Makefile +++ linux-oracle-5.4.0/arch/x86/boot/compressed/Makefile @@ -38,6 +38,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += -Wno-pointer-sign +# Disable relocation relaxation in case the link is not PIE. +KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__ GCOV_PROFILE := n @@ -55,6 +57,10 @@ KBUILD_LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ && echo "-z noreloc-overflow -pie --no-dynamic-linker") endif + +KBUILD_LDFLAGS += -z noexecstack +KBUILD_LDFLAGS += $(call ld-option,--no-warn-rwx-segments) + LDFLAGS_vmlinux := -T hostprogs-y := mkpiggy @@ -102,7 +108,7 @@ quiet_cmd_check_data_rel = DATAREL $@ define cmd_check_data_rel for obj in $(filter %.o,$^); do \ - ${CROSS_COMPILE}readelf -S $$obj | grep -qF .rel.local && { \ + $(READELF) -S $$obj | grep -qF .rel.local && { \ echo "error: $$obj has data relocations!" >&2; \ exit 1; \ } || true; \ --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/acpi.c +++ linux-oracle-5.4.0/arch/x86/boot/compressed/acpi.c @@ -393,7 +393,13 @@ table = table_addr + sizeof(struct acpi_table_srat); while (table + sizeof(struct acpi_subtable_header) < table_end) { + sub_table = (struct acpi_subtable_header *)table; + if (!sub_table->length) { + debug_putstr("Invalid zero length SRAT subtable.\n"); + return 0; + } + if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) { struct acpi_srat_mem_affinity *ma; --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/head_32.S +++ linux-oracle-5.4.0/arch/x86/boot/compressed/head_32.S @@ -49,16 +49,17 @@ * Position Independent Executable (PIE) so that linker won't optimize * R_386_GOT32X relocation to its fixed symbol address. Older * linkers generate R_386_32 relocations against locally defined symbols, - * _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less + * _bss, _ebss, _got, _egot and _end, in PIE. It isn't wrong, just less * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle * R_386_32 relocations when relocating the kernel. To generate - * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as + * R_386_RELATIVE relocations, we mark _bss, _ebss, _got, _egot and _end as * hidden: */ .hidden _bss .hidden _ebss .hidden _got .hidden _egot + .hidden _end __HEAD ENTRY(startup_32) @@ -106,7 +107,7 @@ notl %eax andl %eax, %ebx cmpl $LOAD_PHYSICAL_ADDR, %ebx - jge 1f + jae 1f #endif movl $LOAD_PHYSICAL_ADDR, %ebx 1: @@ -209,7 +210,7 @@ #endif .text -.Lrelocated: +SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) /* * Clear BSS (stack is currently empty) @@ -260,6 +261,7 @@ */ xorl %ebx, %ebx jmp *%eax +SYM_FUNC_END(.Lrelocated) #ifdef CONFIG_EFI_STUB .data --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/head_64.S +++ linux-oracle-5.4.0/arch/x86/boot/compressed/head_64.S @@ -42,6 +42,7 @@ .hidden _ebss .hidden _got .hidden _egot + .hidden _end __HEAD .code32 @@ -106,7 +107,7 @@ notl %eax andl %eax, %ebx cmpl $LOAD_PHYSICAL_ADDR, %ebx - jge 1f + jae 1f #endif movl $LOAD_PHYSICAL_ADDR, %ebx 1: @@ -244,6 +245,11 @@ leal efi32_config(%ebp), %eax movl %eax, efi_config(%ebp) + /* Disable paging */ + movl %cr0, %eax + btrl $X86_CR0_PG_BIT, %eax + movl %eax, %cr0 + jmp startup_32 ENDPROC(efi32_stub_entry) #endif @@ -292,7 +298,7 @@ notq %rax andq %rax, %rbp cmpq $LOAD_PHYSICAL_ADDR, %rbp - jge 1f + jae 1f #endif movq $LOAD_PHYSICAL_ADDR, %rbp 1: @@ -375,11 +381,25 @@ /* Save the trampoline address in RCX */ movq %rax, %rcx + /* Set up 32-bit addressable stack */ + leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp + /* - * Load the address of trampoline_return() into RDI. - * It will be used by the trampoline to return to the main code. + * Preserve live 64-bit registers on the stack: this is necessary + * because the architecture does not guarantee that GPRs will retain + * their full 64-bit values across a 32-bit mode switch. + */ + pushq %rbp + pushq %rbx + pushq %rsi + + /* + * Push the 64-bit address of trampoline_return() onto the new stack. + * It will be used by the trampoline to return to the main code. Due to + * the 32-bit mode switch, it cannot be kept it in a register either. */ leaq trampoline_return(%rip), %rdi + pushq %rdi /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ pushq $__KERNEL32_CS @@ -387,6 +407,11 @@ pushq %rax lretq trampoline_return: + /* Restore live 64-bit registers */ + popq %rsi + popq %rbx + popq %rbp + /* Restore the stack, the 32-bit trampoline uses its own stack */ leaq boot_stack_end(%rbx), %rsp @@ -511,7 +536,7 @@ #endif .text -.Lrelocated: +SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) /* * Clear BSS (stack is currently empty) @@ -540,6 +565,7 @@ * Jump to the decompressed kernel. */ jmp *%rax +SYM_FUNC_END(.Lrelocated) /* * Adjust the global offset table @@ -566,7 +592,7 @@ /* * This is the 32-bit trampoline that will be copied over to low memory. * - * RDI contains the return address (might be above 4G). + * Return address is at the top of the stack (might be above 4G). * ECX contains the base address of the trampoline memory. * Non zero RDX means trampoline needs to enable 5-level paging. */ @@ -576,9 +602,6 @@ movl %eax, %ds movl %eax, %ss - /* Set up new stack */ - leal TRAMPOLINE_32BIT_STACK_END(%ecx), %esp - /* Disable paging */ movl %cr0, %eax btrl $X86_CR0_PG_BIT, %eax @@ -635,9 +658,10 @@ lret .code64 -.Lpaging_enabled: +SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled) /* Return from the trampoline */ - jmp *%rdi + retq +SYM_FUNC_END(.Lpaging_enabled) /* * The trampoline code has a size limit. @@ -647,11 +671,12 @@ .org trampoline_32bit_src + TRAMPOLINE_32BIT_CODE_SIZE .code32 -.Lno_longmode: +SYM_FUNC_START_LOCAL_NOALIGN(.Lno_longmode) /* This isn't an x86-64 CPU, so hang intentionally, we cannot continue */ 1: hlt jmp 1b +SYM_FUNC_END(.Lno_longmode) #include "../../kernel/verify_cpu.S" --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/kaslr_64.c +++ linux-oracle-5.4.0/arch/x86/boot/compressed/kaslr_64.c @@ -29,9 +29,6 @@ #define __PAGE_OFFSET __PAGE_OFFSET_BASE #include "../../mm/ident_map.c" -/* Used by pgtable.h asm code to force instruction serialization. */ -unsigned long __force_order; - /* Used to track our page table allocation area. */ struct alloc_pgt_data { unsigned char *pgt_buf; --- linux-oracle-5.4.0.orig/arch/x86/boot/compressed/pgtable_64.c +++ linux-oracle-5.4.0/arch/x86/boot/compressed/pgtable_64.c @@ -5,15 +5,6 @@ #include "pgtable.h" #include "../string.h" -/* - * __force_order is used by special_insns.h asm code to force instruction - * serialization. - * - * It is not referenced from the code, but GCC < 5 with -fPIE would fail - * due to an undefined symbol. Define it to make these ancient GCCs work. - */ -unsigned long __force_order; - #define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */ #define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */ --- linux-oracle-5.4.0.orig/arch/x86/boot/main.c +++ linux-oracle-5.4.0/arch/x86/boot/main.c @@ -33,7 +33,7 @@ u16 cl_offset; }; const struct old_cmdline * const oldcmd = - (const struct old_cmdline *)OLD_CL_ADDRESS; + absolute_pointer(OLD_CL_ADDRESS); BUILD_BUG_ON(sizeof(boot_params) != 4096); memcpy(&boot_params.hdr, &hdr, sizeof(hdr)); --- linux-oracle-5.4.0.orig/arch/x86/boot/pmjump.S +++ linux-oracle-5.4.0/arch/x86/boot/pmjump.S @@ -40,13 +40,13 @@ # Transition to 32-bit mode .byte 0x66, 0xea # ljmpl opcode -2: .long in_pm32 # offset +2: .long .Lin_pm32 # offset .word __BOOT_CS # segment ENDPROC(protected_mode_jump) .code32 .section ".text32","ax" -GLOBAL(in_pm32) +SYM_FUNC_START_LOCAL_NOALIGN(.Lin_pm32) # Set up data segments for flat 32-bit mode movl %ecx, %ds movl %ecx, %es @@ -72,4 +72,4 @@ lldt %cx jmpl *%eax # Jump to the 32-bit entrypoint -ENDPROC(in_pm32) +SYM_FUNC_END(.Lin_pm32) --- linux-oracle-5.4.0.orig/arch/x86/boot/setup.ld +++ linux-oracle-5.4.0/arch/x86/boot/setup.ld @@ -20,7 +20,7 @@ .initdata : { *(.initdata) } __end_init = .; - .text : { *(.text) } + .text : { *(.text .text.*) } .text32 : { *(.text32) } . = ALIGN(16); --- linux-oracle-5.4.0.orig/arch/x86/boot/video-vga.c +++ linux-oracle-5.4.0/arch/x86/boot/video-vga.c @@ -188,7 +188,7 @@ vga_set_vertical_end(60*8); } -static int vga_set_mode(struct mode_info *mode) +static int __attribute__((optimize("no-jump-tables"))) vga_set_mode(struct mode_info *mode) { /* Set the basic mode */ vga_set_basic_mode(); --- linux-oracle-5.4.0.orig/arch/x86/configs/i386_defconfig +++ linux-oracle-5.4.0/arch/x86/configs/i386_defconfig @@ -137,7 +137,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y @@ -205,7 +204,6 @@ CONFIG_FB_TILEBLITTING=y CONFIG_FB_EFI=y # CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set --- linux-oracle-5.4.0.orig/arch/x86/configs/x86_64_defconfig +++ linux-oracle-5.4.0/arch/x86/configs/x86_64_defconfig @@ -136,7 +136,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_SPI_ATTRS=y @@ -201,7 +200,6 @@ CONFIG_FB_TILEBLITTING=y CONFIG_FB_EFI=y # CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set --- linux-oracle-5.4.0.orig/arch/x86/crypto/aegis128-aesni-asm.S +++ linux-oracle-5.4.0/arch/x86/crypto/aegis128-aesni-asm.S @@ -20,7 +20,7 @@ #define T1 %xmm7 #define STATEP %rdi -#define LEN %rsi +#define LEN %esi #define SRC %rdx #define DST %rcx @@ -75,32 +75,32 @@ xor %r9d, %r9d pxor MSG, MSG - mov LEN, %r8 + mov LEN, %r8d and $0x1, %r8 jz .Lld_partial_1 - mov LEN, %r8 + mov LEN, %r8d and $0x1E, %r8 add SRC, %r8 mov (%r8), %r9b .Lld_partial_1: - mov LEN, %r8 + mov LEN, %r8d and $0x2, %r8 jz .Lld_partial_2 - mov LEN, %r8 + mov LEN, %r8d and $0x1C, %r8 add SRC, %r8 shl $0x10, %r9 mov (%r8), %r9w .Lld_partial_2: - mov LEN, %r8 + mov LEN, %r8d and $0x4, %r8 jz .Lld_partial_4 - mov LEN, %r8 + mov LEN, %r8d and $0x18, %r8 add SRC, %r8 shl $32, %r9 @@ -110,11 +110,11 @@ .Lld_partial_4: movq %r9, MSG - mov LEN, %r8 + mov LEN, %r8d and $0x8, %r8 jz .Lld_partial_8 - mov LEN, %r8 + mov LEN, %r8d and $0x10, %r8 add SRC, %r8 pslldq $8, MSG @@ -138,7 +138,7 @@ * %r10 */ __store_partial: - mov LEN, %r8 + mov LEN, %r8d mov DST, %r9 movq T0, %r10 @@ -676,7 +676,7 @@ call __store_partial /* mask with byte count: */ - movq LEN, T0 + movd LEN, T0 punpcklbw T0, T0 punpcklbw T0, T0 punpcklbw T0, T0 @@ -701,7 +701,8 @@ /* * void crypto_aegis128_aesni_final(void *state, void *tag_xor, - * u64 assoclen, u64 cryptlen); + * unsigned int assoclen, + * unsigned int cryptlen); */ ENTRY(crypto_aegis128_aesni_final) FRAME_BEGIN @@ -714,8 +715,8 @@ movdqu 0x40(STATEP), STATE4 /* prepare length block: */ - movq %rdx, MSG - movq %rcx, T0 + movd %edx, MSG + movd %ecx, T0 pslldq $8, T0 pxor T0, MSG psllq $3, MSG /* multiply by 8 (to get bit count) */ --- linux-oracle-5.4.0.orig/arch/x86/crypto/aes_ctrby8_avx-x86_64.S +++ linux-oracle-5.4.0/arch/x86/crypto/aes_ctrby8_avx-x86_64.S @@ -127,10 +127,6 @@ /* generate a unique variable for ddq_add_x */ -.macro setddq n - var_ddq_add = ddq_add_\n -.endm - /* generate a unique variable for xmm register */ .macro setxdata n var_xdata = %xmm\n @@ -140,9 +136,7 @@ .macro club name, id .altmacro - .if \name == DDQ_DATA - setddq %\id - .elseif \name == XDATA + .if \name == XDATA setxdata %\id .endif .noaltmacro @@ -165,9 +159,8 @@ .set i, 1 .rept (by - 1) - club DDQ_DATA, i club XDATA, i - vpaddq var_ddq_add(%rip), xcounter, var_xdata + vpaddq (ddq_add_1 + 16 * (i - 1))(%rip), xcounter, var_xdata vptest ddq_low_msk(%rip), var_xdata jnz 1f vpaddq ddq_high_add_1(%rip), var_xdata, var_xdata @@ -180,8 +173,7 @@ vmovdqa 1*16(p_keys), xkeyA vpxor xkey0, xdata0, xdata0 - club DDQ_DATA, by - vpaddq var_ddq_add(%rip), xcounter, xcounter + vpaddq (ddq_add_1 + 16 * (by - 1))(%rip), xcounter, xcounter vptest ddq_low_msk(%rip), xcounter jnz 1f vpaddq ddq_high_add_1(%rip), xcounter, xcounter --- linux-oracle-5.4.0.orig/arch/x86/crypto/aesni-intel_asm.S +++ linux-oracle-5.4.0/arch/x86/crypto/aesni-intel_asm.S @@ -266,7 +266,7 @@ PSHUFB_XMM %xmm2, %xmm0 movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv - PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, + PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7 movdqu HashKey(%arg2), %xmm13 CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \ @@ -319,7 +319,7 @@ # Main loop - Encrypt/Decrypt remaining blocks - cmp $0, %r13 + test %r13, %r13 je _zero_cipher_left_\@ sub $64, %r13 je _four_cipher_left_\@ @@ -438,7 +438,7 @@ mov PBlockLen(%arg2), %r12 - cmp $0, %r12 + test %r12, %r12 je _partial_done\@ GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 @@ -475,7 +475,7 @@ add $8, %r10 sub $8, %r11 psrldq $8, %xmm0 - cmp $0, %r11 + test %r11, %r11 je _return_T_done_\@ _T_4_\@: movd %xmm0, %eax @@ -483,7 +483,7 @@ add $4, %r10 sub $4, %r11 psrldq $4, %xmm0 - cmp $0, %r11 + test %r11, %r11 je _return_T_done_\@ _T_123_\@: movd %xmm0, %eax @@ -620,7 +620,7 @@ /* read the last <16B of AAD */ _get_AAD_rest\@: - cmp $0, %r11 + test %r11, %r11 je _get_AAD_done\@ READ_PARTIAL_BLOCK %r10, %r11, \TMP1, \TMP7 @@ -641,7 +641,7 @@ .macro PARTIAL_BLOCK CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \ AAD_HASH operation mov PBlockLen(%arg2), %r13 - cmp $0, %r13 + test %r13, %r13 je _partial_block_done_\@ # Leave Macro if no partial blocks # Read in input data without over reading cmp $16, \PLAIN_CYPH_LEN @@ -693,7 +693,7 @@ PSHUFB_XMM %xmm2, %xmm3 pxor %xmm3, \AAD_HASH - cmp $0, %r10 + test %r10, %r10 jl _partial_incomplete_1_\@ # GHASH computation for the last <16 Byte block @@ -728,7 +728,7 @@ PSHUFB_XMM %xmm2, %xmm9 pxor %xmm9, \AAD_HASH - cmp $0, %r10 + test %r10, %r10 jl _partial_incomplete_2_\@ # GHASH computation for the last <16 Byte block @@ -748,7 +748,7 @@ PSHUFB_XMM %xmm2, %xmm9 .endif # output encrypted Bytes - cmp $0, %r10 + test %r10, %r10 jl _partial_fill_\@ mov %r13, %r12 mov $16, %r13 @@ -978,7 +978,7 @@ * arg1, %arg3, %arg4 are used as pointers only, not modified * %r11 is the data offset value */ -.macro GHASH_4_ENCRYPT_4_PARALLEL_ENC TMP1 TMP2 TMP3 TMP4 TMP5 \ +.macro GHASH_4_ENCRYPT_4_PARALLEL_enc TMP1 TMP2 TMP3 TMP4 TMP5 \ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation movdqa \XMM1, \XMM5 @@ -1186,7 +1186,7 @@ * arg1, %arg3, %arg4 are used as pointers only, not modified * %r11 is the data offset value */ -.macro GHASH_4_ENCRYPT_4_PARALLEL_DEC TMP1 TMP2 TMP3 TMP4 TMP5 \ +.macro GHASH_4_ENCRYPT_4_PARALLEL_dec TMP1 TMP2 TMP3 TMP4 TMP5 \ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation movdqa \XMM1, \XMM5 @@ -1946,7 +1946,7 @@ ENDPROC(aesni_set_key) /* - * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) + * void aesni_enc(const void *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_enc) FRAME_BEGIN @@ -2137,7 +2137,7 @@ ENDPROC(_aesni_enc4) /* - * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) + * void aesni_dec (const void *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_dec) FRAME_BEGIN @@ -2726,25 +2726,18 @@ pxor CTR, IV; /* - * void aesni_xts_crypt8(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src, - * bool enc, u8 *iv) + * void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, + * const u8 *src, unsigned int len, le128 *iv) */ -ENTRY(aesni_xts_crypt8) +ENTRY(aesni_xts_encrypt) FRAME_BEGIN - cmpb $0, %cl - movl $0, %ecx - movl $240, %r10d - leaq _aesni_enc4, %r11 - leaq _aesni_dec4, %rax - cmovel %r10d, %ecx - cmoveq %rax, %r11 movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK movups (IVP), IV mov 480(KEYP), KLEN - addq %rcx, KEYP +.Lxts_enc_loop4: movdqa IV, STATE1 movdqu 0x00(INP), INC pxor INC, STATE1 @@ -2768,71 +2761,103 @@ pxor INC, STATE4 movdqu IV, 0x30(OUTP) - CALL_NOSPEC %r11 + call _aesni_enc4 movdqu 0x00(OUTP), INC pxor INC, STATE1 movdqu STATE1, 0x00(OUTP) - _aesni_gf128mul_x_ble() - movdqa IV, STATE1 - movdqu 0x40(INP), INC - pxor INC, STATE1 - movdqu IV, 0x40(OUTP) - movdqu 0x10(OUTP), INC pxor INC, STATE2 movdqu STATE2, 0x10(OUTP) - _aesni_gf128mul_x_ble() - movdqa IV, STATE2 - movdqu 0x50(INP), INC - pxor INC, STATE2 - movdqu IV, 0x50(OUTP) - movdqu 0x20(OUTP), INC pxor INC, STATE3 movdqu STATE3, 0x20(OUTP) - _aesni_gf128mul_x_ble() - movdqa IV, STATE3 - movdqu 0x60(INP), INC - pxor INC, STATE3 - movdqu IV, 0x60(OUTP) - movdqu 0x30(OUTP), INC pxor INC, STATE4 movdqu STATE4, 0x30(OUTP) _aesni_gf128mul_x_ble() - movdqa IV, STATE4 - movdqu 0x70(INP), INC - pxor INC, STATE4 - movdqu IV, 0x70(OUTP) - _aesni_gf128mul_x_ble() + add $64, INP + add $64, OUTP + sub $64, LEN + ja .Lxts_enc_loop4 + movups IV, (IVP) - CALL_NOSPEC %r11 + FRAME_END + ret +ENDPROC(aesni_xts_encrypt) + +/* + * void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *dst, + * const u8 *src, unsigned int len, le128 *iv) + */ +ENTRY(aesni_xts_decrypt) + FRAME_BEGIN + + movdqa .Lgf128mul_x_ble_mask, GF128MUL_MASK + movups (IVP), IV + + mov 480(KEYP), KLEN + add $240, KEYP - movdqu 0x40(OUTP), INC +.Lxts_dec_loop4: + movdqa IV, STATE1 + movdqu 0x00(INP), INC pxor INC, STATE1 - movdqu STATE1, 0x40(OUTP) + movdqu IV, 0x00(OUTP) - movdqu 0x50(OUTP), INC + _aesni_gf128mul_x_ble() + movdqa IV, STATE2 + movdqu 0x10(INP), INC + pxor INC, STATE2 + movdqu IV, 0x10(OUTP) + + _aesni_gf128mul_x_ble() + movdqa IV, STATE3 + movdqu 0x20(INP), INC + pxor INC, STATE3 + movdqu IV, 0x20(OUTP) + + _aesni_gf128mul_x_ble() + movdqa IV, STATE4 + movdqu 0x30(INP), INC + pxor INC, STATE4 + movdqu IV, 0x30(OUTP) + + call _aesni_dec4 + + movdqu 0x00(OUTP), INC + pxor INC, STATE1 + movdqu STATE1, 0x00(OUTP) + + movdqu 0x10(OUTP), INC pxor INC, STATE2 - movdqu STATE2, 0x50(OUTP) + movdqu STATE2, 0x10(OUTP) - movdqu 0x60(OUTP), INC + movdqu 0x20(OUTP), INC pxor INC, STATE3 - movdqu STATE3, 0x60(OUTP) + movdqu STATE3, 0x20(OUTP) - movdqu 0x70(OUTP), INC + movdqu 0x30(OUTP), INC pxor INC, STATE4 - movdqu STATE4, 0x70(OUTP) + movdqu STATE4, 0x30(OUTP) + + _aesni_gf128mul_x_ble() + + add $64, INP + add $64, OUTP + sub $64, LEN + ja .Lxts_dec_loop4 + + movups IV, (IVP) FRAME_END ret -ENDPROC(aesni_xts_crypt8) +ENDPROC(aesni_xts_decrypt) #endif --- linux-oracle-5.4.0.orig/arch/x86/crypto/aesni-intel_avx-x86_64.S +++ linux-oracle-5.4.0/arch/x86/crypto/aesni-intel_avx-x86_64.S @@ -370,7 +370,7 @@ _initial_blocks_encrypted\@: - cmp $0, %r13 + test %r13, %r13 je _zero_cipher_left\@ sub $128, %r13 @@ -529,7 +529,7 @@ vmovdqu HashKey(arg2), %xmm13 mov PBlockLen(arg2), %r12 - cmp $0, %r12 + test %r12, %r12 je _partial_done\@ #GHASH computation for the last <16 Byte block @@ -574,7 +574,7 @@ add $8, %r10 sub $8, %r11 vpsrldq $8, %xmm9, %xmm9 - cmp $0, %r11 + test %r11, %r11 je _return_T_done\@ _T_4\@: vmovd %xmm9, %eax @@ -582,7 +582,7 @@ add $4, %r10 sub $4, %r11 vpsrldq $4, %xmm9, %xmm9 - cmp $0, %r11 + test %r11, %r11 je _return_T_done\@ _T_123\@: vmovd %xmm9, %eax @@ -626,7 +626,7 @@ cmp $16, %r11 jge _get_AAD_blocks\@ vmovdqu \T8, \T7 - cmp $0, %r11 + test %r11, %r11 je _get_AAD_done\@ vpxor \T7, \T7, \T7 @@ -645,7 +645,7 @@ vpxor \T1, \T7, \T7 jmp _get_AAD_rest8\@ _get_AAD_rest4\@: - cmp $0, %r11 + test %r11, %r11 jle _get_AAD_rest0\@ mov (%r10), %eax movq %rax, \T1 @@ -750,7 +750,7 @@ .macro PARTIAL_BLOCK GHASH_MUL CYPH_PLAIN_OUT PLAIN_CYPH_IN PLAIN_CYPH_LEN DATA_OFFSET \ AAD_HASH ENC_DEC mov PBlockLen(arg2), %r13 - cmp $0, %r13 + test %r13, %r13 je _partial_block_done_\@ # Leave Macro if no partial blocks # Read in input data without over reading cmp $16, \PLAIN_CYPH_LEN @@ -802,7 +802,7 @@ vpshufb %xmm2, %xmm3, %xmm3 vpxor %xmm3, \AAD_HASH, \AAD_HASH - cmp $0, %r10 + test %r10, %r10 jl _partial_incomplete_1_\@ # GHASH computation for the last <16 Byte block @@ -837,7 +837,7 @@ vpshufb %xmm2, %xmm9, %xmm9 vpxor %xmm9, \AAD_HASH, \AAD_HASH - cmp $0, %r10 + test %r10, %r10 jl _partial_incomplete_2_\@ # GHASH computation for the last <16 Byte block @@ -857,7 +857,7 @@ vpshufb %xmm2, %xmm9, %xmm9 .endif # output encrypted Bytes - cmp $0, %r10 + test %r10, %r10 jl _partial_fill_\@ mov %r13, %r12 mov $16, %r13 --- linux-oracle-5.4.0.orig/arch/x86/crypto/aesni-intel_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/aesni-intel_glue.c @@ -83,10 +83,8 @@ asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, unsigned int key_len); -asmlinkage void aesni_enc(struct crypto_aes_ctx *ctx, u8 *out, - const u8 *in); -asmlinkage void aesni_dec(struct crypto_aes_ctx *ctx, u8 *out, - const u8 *in); +asmlinkage void aesni_enc(const void *ctx, u8 *out, const u8 *in); +asmlinkage void aesni_dec(const void *ctx, u8 *out, const u8 *in); asmlinkage void aesni_ecb_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len); asmlinkage void aesni_ecb_dec(struct crypto_aes_ctx *ctx, u8 *out, @@ -99,6 +97,12 @@ #define AVX_GEN2_OPTSIZE 640 #define AVX_GEN4_OPTSIZE 4096 +asmlinkage void aesni_xts_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, + const u8 *in, unsigned int len, u8 *iv); + +asmlinkage void aesni_xts_decrypt(const struct crypto_aes_ctx *ctx, u8 *out, + const u8 *in, unsigned int len, u8 *iv); + #ifdef CONFIG_X86_64 static void (*aesni_ctr_enc_tfm)(struct crypto_aes_ctx *ctx, u8 *out, @@ -106,9 +110,6 @@ asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); -asmlinkage void aesni_xts_crypt8(struct crypto_aes_ctx *ctx, u8 *out, - const u8 *in, bool enc, u8 *iv); - /* asmlinkage void aesni_gcm_enc() * void *ctx, AES Key schedule. Starts on a 16 byte boundary. * struct gcm_context_data. May be uninitialized. @@ -550,29 +551,24 @@ } -static void aesni_xts_tweak(void *ctx, u8 *out, const u8 *in) -{ - aesni_enc(ctx, out, in); -} - -static void aesni_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void aesni_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, GLUE_FUNC_CAST(aesni_enc)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, aesni_enc); } -static void aesni_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void aesni_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, GLUE_FUNC_CAST(aesni_dec)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, aesni_dec); } -static void aesni_xts_enc8(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void aesni_xts_enc32(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - aesni_xts_crypt8(ctx, (u8 *)dst, (const u8 *)src, true, (u8 *)iv); + aesni_xts_encrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv); } -static void aesni_xts_dec8(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void aesni_xts_dec32(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - aesni_xts_crypt8(ctx, (u8 *)dst, (const u8 *)src, false, (u8 *)iv); + aesni_xts_decrypt(ctx, dst, src, 32 * AES_BLOCK_SIZE, (u8 *)iv); } static const struct common_glue_ctx aesni_enc_xts = { @@ -580,11 +576,11 @@ .fpu_blocks_limit = 1, .funcs = { { - .num_blocks = 8, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(aesni_xts_enc8) } + .num_blocks = 32, + .fn_u = { .xts = aesni_xts_enc32 } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(aesni_xts_enc) } + .fn_u = { .xts = aesni_xts_enc } } } }; @@ -593,11 +589,11 @@ .fpu_blocks_limit = 1, .funcs = { { - .num_blocks = 8, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(aesni_xts_dec8) } + .num_blocks = 32, + .fn_u = { .xts = aesni_xts_dec32 } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(aesni_xts_dec) } + .fn_u = { .xts = aesni_xts_dec } } } }; @@ -606,8 +602,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&aesni_enc_xts, req, - XTS_TWEAK_CAST(aesni_xts_tweak), + return glue_xts_req_128bit(&aesni_enc_xts, req, aesni_enc, aes_ctx(ctx->raw_tweak_ctx), aes_ctx(ctx->raw_crypt_ctx), false); @@ -618,8 +613,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct aesni_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&aesni_dec_xts, req, - XTS_TWEAK_CAST(aesni_xts_tweak), + return glue_xts_req_128bit(&aesni_dec_xts, req, aesni_enc, aes_ctx(ctx->raw_tweak_ctx), aes_ctx(ctx->raw_crypt_ctx), true); @@ -707,7 +701,8 @@ struct crypto_aead *tfm = crypto_aead_reqtfm(req); unsigned long auth_tag_len = crypto_aead_authsize(tfm); const struct aesni_gcm_tfm_s *gcm_tfm = aesni_gcm_tfm; - struct gcm_context_data data AESNI_ALIGN_ATTR; + u8 databuf[sizeof(struct gcm_context_data) + (AESNI_ALIGN - 8)] __aligned(8); + struct gcm_context_data *data = PTR_ALIGN((void *)databuf, AESNI_ALIGN); struct scatter_walk dst_sg_walk = {}; unsigned long left = req->cryptlen; unsigned long len, srclen, dstlen; @@ -760,8 +755,7 @@ } kernel_fpu_begin(); - gcm_tfm->init(aes_ctx, &data, iv, - hash_subkey, assoc, assoclen); + gcm_tfm->init(aes_ctx, data, iv, hash_subkey, assoc, assoclen); if (req->src != req->dst) { while (left) { src = scatterwalk_map(&src_sg_walk); @@ -771,10 +765,10 @@ len = min(srclen, dstlen); if (len) { if (enc) - gcm_tfm->enc_update(aes_ctx, &data, + gcm_tfm->enc_update(aes_ctx, data, dst, src, len); else - gcm_tfm->dec_update(aes_ctx, &data, + gcm_tfm->dec_update(aes_ctx, data, dst, src, len); } left -= len; @@ -792,10 +786,10 @@ len = scatterwalk_clamp(&src_sg_walk, left); if (len) { if (enc) - gcm_tfm->enc_update(aes_ctx, &data, + gcm_tfm->enc_update(aes_ctx, data, src, src, len); else - gcm_tfm->dec_update(aes_ctx, &data, + gcm_tfm->dec_update(aes_ctx, data, src, src, len); } left -= len; @@ -804,7 +798,7 @@ scatterwalk_done(&src_sg_walk, 1, left); } } - gcm_tfm->finalize(aes_ctx, &data, authTag, auth_tag_len); + gcm_tfm->finalize(aes_ctx, data, authTag, auth_tag_len); kernel_fpu_end(); if (!assocmem) @@ -853,7 +847,8 @@ struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); void *aes_ctx = &(ctx->aes_key_expanded); - u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); + u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8); + u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN); unsigned int i; __be32 counter = cpu_to_be32(1); @@ -880,7 +875,8 @@ struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); void *aes_ctx = &(ctx->aes_key_expanded); - u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); + u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8); + u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN); unsigned int i; if (unlikely(req->assoclen != 16 && req->assoclen != 20)) @@ -1010,7 +1006,8 @@ struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct generic_gcmaes_ctx *ctx = generic_gcmaes_ctx_get(tfm); void *aes_ctx = &(ctx->aes_key_expanded); - u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); + u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8); + u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN); __be32 counter = cpu_to_be32(1); memcpy(iv, req->iv, 12); @@ -1026,7 +1023,8 @@ struct crypto_aead *tfm = crypto_aead_reqtfm(req); struct generic_gcmaes_ctx *ctx = generic_gcmaes_ctx_get(tfm); void *aes_ctx = &(ctx->aes_key_expanded); - u8 iv[16] __attribute__ ((__aligned__(AESNI_ALIGN))); + u8 ivbuf[16 + (AESNI_ALIGN - 8)] __aligned(8); + u8 *iv = PTR_ALIGN(&ivbuf[0], AESNI_ALIGN); memcpy(iv, req->iv, 12); *((__be32 *)(iv+12)) = counter; --- linux-oracle-5.4.0.orig/arch/x86/crypto/camellia_aesni_avx2_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/camellia_aesni_avx2_glue.c @@ -19,20 +19,17 @@ #define CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS 32 /* 32-way AVX2/AES-NI parallel cipher functions */ -asmlinkage void camellia_ecb_enc_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void camellia_ecb_dec_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); - -asmlinkage void camellia_cbc_dec_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void camellia_ctr_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); - -asmlinkage void camellia_xts_enc_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); -asmlinkage void camellia_xts_dec_32way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void camellia_ecb_enc_32way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void camellia_ecb_dec_32way(const void *ctx, u8 *dst, const u8 *src); + +asmlinkage void camellia_cbc_dec_32way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void camellia_ctr_32way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); + +asmlinkage void camellia_xts_enc_32way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +asmlinkage void camellia_xts_dec_32way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); static const struct common_glue_ctx camellia_enc = { .num_funcs = 4, @@ -40,16 +37,16 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_enc_32way) } + .fn_u = { .ecb = camellia_ecb_enc_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_enc_16way) } + .fn_u = { .ecb = camellia_ecb_enc_16way } }, { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } + .fn_u = { .ecb = camellia_enc_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } + .fn_u = { .ecb = camellia_enc_blk } } } }; @@ -59,16 +56,16 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_ctr_32way) } + .fn_u = { .ctr = camellia_ctr_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_ctr_16way) } + .fn_u = { .ctr = camellia_ctr_16way } }, { .num_blocks = 2, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } + .fn_u = { .ctr = camellia_crypt_ctr_2way } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } + .fn_u = { .ctr = camellia_crypt_ctr } } } }; @@ -78,13 +75,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc_32way) } + .fn_u = { .xts = camellia_xts_enc_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc_16way) } + .fn_u = { .xts = camellia_xts_enc_16way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc) } + .fn_u = { .xts = camellia_xts_enc } } } }; @@ -94,16 +91,16 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_dec_32way) } + .fn_u = { .ecb = camellia_ecb_dec_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_dec_16way) } + .fn_u = { .ecb = camellia_ecb_dec_16way } }, { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } + .fn_u = { .ecb = camellia_dec_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .ecb = camellia_dec_blk } } } }; @@ -113,16 +110,16 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_cbc_dec_32way) } + .fn_u = { .cbc = camellia_cbc_dec_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_cbc_dec_16way) } + .fn_u = { .cbc = camellia_cbc_dec_16way } }, { .num_blocks = 2, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } + .fn_u = { .cbc = camellia_decrypt_cbc_2way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .cbc = camellia_dec_blk } } } }; @@ -132,13 +129,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_AVX2_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec_32way) } + .fn_u = { .xts = camellia_xts_dec_32way } }, { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec_16way) } + .fn_u = { .xts = camellia_xts_dec_16way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec) } + .fn_u = { .xts = camellia_xts_dec } } } }; @@ -161,8 +158,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(camellia_enc_blk), - req); + return glue_cbc_encrypt_req_128bit(camellia_enc_blk, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -180,8 +176,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct camellia_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&camellia_enc_xts, req, - XTS_TWEAK_CAST(camellia_enc_blk), + return glue_xts_req_128bit(&camellia_enc_xts, req, camellia_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, false); } @@ -190,8 +185,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct camellia_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&camellia_dec_xts, req, - XTS_TWEAK_CAST(camellia_enc_blk), + return glue_xts_req_128bit(&camellia_dec_xts, req, camellia_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, true); } --- linux-oracle-5.4.0.orig/arch/x86/crypto/camellia_aesni_avx_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/camellia_aesni_avx_glue.c @@ -18,41 +18,36 @@ #define CAMELLIA_AESNI_PARALLEL_BLOCKS 16 /* 16-way parallel cipher functions (avx/aes-ni) */ -asmlinkage void camellia_ecb_enc_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void camellia_ecb_enc_16way(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(camellia_ecb_enc_16way); -asmlinkage void camellia_ecb_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void camellia_ecb_dec_16way(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(camellia_ecb_dec_16way); -asmlinkage void camellia_cbc_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void camellia_cbc_dec_16way(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(camellia_cbc_dec_16way); -asmlinkage void camellia_ctr_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void camellia_ctr_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); EXPORT_SYMBOL_GPL(camellia_ctr_16way); -asmlinkage void camellia_xts_enc_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void camellia_xts_enc_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); EXPORT_SYMBOL_GPL(camellia_xts_enc_16way); -asmlinkage void camellia_xts_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void camellia_xts_dec_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); EXPORT_SYMBOL_GPL(camellia_xts_dec_16way); -void camellia_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void camellia_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(camellia_enc_blk)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, camellia_enc_blk); } EXPORT_SYMBOL_GPL(camellia_xts_enc); -void camellia_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void camellia_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(camellia_dec_blk)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, camellia_dec_blk); } EXPORT_SYMBOL_GPL(camellia_xts_dec); @@ -62,13 +57,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_enc_16way) } + .fn_u = { .ecb = camellia_ecb_enc_16way } }, { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } + .fn_u = { .ecb = camellia_enc_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } + .fn_u = { .ecb = camellia_enc_blk } } } }; @@ -78,13 +73,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_ctr_16way) } + .fn_u = { .ctr = camellia_ctr_16way } }, { .num_blocks = 2, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } + .fn_u = { .ctr = camellia_crypt_ctr_2way } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } + .fn_u = { .ctr = camellia_crypt_ctr } } } }; @@ -94,10 +89,10 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc_16way) } + .fn_u = { .xts = camellia_xts_enc_16way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_enc) } + .fn_u = { .xts = camellia_xts_enc } } } }; @@ -107,13 +102,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_ecb_dec_16way) } + .fn_u = { .ecb = camellia_ecb_dec_16way } }, { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } + .fn_u = { .ecb = camellia_dec_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .ecb = camellia_dec_blk } } } }; @@ -123,13 +118,13 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_cbc_dec_16way) } + .fn_u = { .cbc = camellia_cbc_dec_16way } }, { .num_blocks = 2, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } + .fn_u = { .cbc = camellia_decrypt_cbc_2way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .cbc = camellia_dec_blk } } } }; @@ -139,10 +134,10 @@ .funcs = { { .num_blocks = CAMELLIA_AESNI_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec_16way) } + .fn_u = { .xts = camellia_xts_dec_16way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(camellia_xts_dec) } + .fn_u = { .xts = camellia_xts_dec } } } }; @@ -165,8 +160,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(camellia_enc_blk), - req); + return glue_cbc_encrypt_req_128bit(camellia_enc_blk, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -206,8 +200,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct camellia_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&camellia_enc_xts, req, - XTS_TWEAK_CAST(camellia_enc_blk), + return glue_xts_req_128bit(&camellia_enc_xts, req, camellia_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, false); } @@ -216,8 +209,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct camellia_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&camellia_dec_xts, req, - XTS_TWEAK_CAST(camellia_enc_blk), + return glue_xts_req_128bit(&camellia_dec_xts, req, camellia_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, true); } --- linux-oracle-5.4.0.orig/arch/x86/crypto/camellia_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/camellia_glue.c @@ -18,19 +18,17 @@ #include /* regular block cipher functions */ -asmlinkage void __camellia_enc_blk(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, bool xor); +asmlinkage void __camellia_enc_blk(const void *ctx, u8 *dst, const u8 *src, + bool xor); EXPORT_SYMBOL_GPL(__camellia_enc_blk); -asmlinkage void camellia_dec_blk(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void camellia_dec_blk(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(camellia_dec_blk); /* 2-way parallel cipher functions */ -asmlinkage void __camellia_enc_blk_2way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, bool xor); +asmlinkage void __camellia_enc_blk_2way(const void *ctx, u8 *dst, const u8 *src, + bool xor); EXPORT_SYMBOL_GPL(__camellia_enc_blk_2way); -asmlinkage void camellia_dec_blk_2way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void camellia_dec_blk_2way(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(camellia_dec_blk_2way); static void camellia_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) @@ -1267,8 +1265,10 @@ return camellia_setkey(&tfm->base, key, key_len); } -void camellia_decrypt_cbc_2way(void *ctx, u128 *dst, const u128 *src) +void camellia_decrypt_cbc_2way(const void *ctx, u8 *d, const u8 *s) { + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; u128 iv = *src; camellia_dec_blk_2way(ctx, (u8 *)dst, (u8 *)src); @@ -1277,9 +1277,11 @@ } EXPORT_SYMBOL_GPL(camellia_decrypt_cbc_2way); -void camellia_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void camellia_crypt_ctr(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblk; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; if (dst != src) *dst = *src; @@ -1291,9 +1293,11 @@ } EXPORT_SYMBOL_GPL(camellia_crypt_ctr); -void camellia_crypt_ctr_2way(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void camellia_crypt_ctr_2way(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblks[2]; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; if (dst != src) { dst[0] = src[0]; @@ -1315,10 +1319,10 @@ .funcs = { { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk_2way) } + .fn_u = { .ecb = camellia_enc_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } + .fn_u = { .ecb = camellia_enc_blk } } } }; @@ -1328,10 +1332,10 @@ .funcs = { { .num_blocks = 2, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr_2way) } + .fn_u = { .ctr = camellia_crypt_ctr_2way } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(camellia_crypt_ctr) } + .fn_u = { .ctr = camellia_crypt_ctr } } } }; @@ -1341,10 +1345,10 @@ .funcs = { { .num_blocks = 2, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk_2way) } + .fn_u = { .ecb = camellia_dec_blk_2way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .ecb = camellia_dec_blk } } } }; @@ -1354,10 +1358,10 @@ .funcs = { { .num_blocks = 2, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_decrypt_cbc_2way) } + .fn_u = { .cbc = camellia_decrypt_cbc_2way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(camellia_dec_blk) } + .fn_u = { .cbc = camellia_dec_blk } } } }; @@ -1373,8 +1377,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(camellia_enc_blk), - req); + return glue_cbc_encrypt_req_128bit(camellia_enc_blk, req); } static int cbc_decrypt(struct skcipher_request *req) --- linux-oracle-5.4.0.orig/arch/x86/crypto/cast6_avx_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/cast6_avx_glue.c @@ -20,20 +20,17 @@ #define CAST6_PARALLEL_BLOCKS 8 -asmlinkage void cast6_ecb_enc_8way(struct cast6_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void cast6_ecb_dec_8way(struct cast6_ctx *ctx, u8 *dst, - const u8 *src); - -asmlinkage void cast6_cbc_dec_8way(struct cast6_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void cast6_ctr_8way(struct cast6_ctx *ctx, u8 *dst, const u8 *src, +asmlinkage void cast6_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void cast6_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src); + +asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void cast6_ctr_8way(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -asmlinkage void cast6_xts_enc_8way(struct cast6_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); -asmlinkage void cast6_xts_dec_8way(struct cast6_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void cast6_xts_enc_8way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +asmlinkage void cast6_xts_dec_8way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); static int cast6_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) @@ -41,21 +38,21 @@ return cast6_setkey(&tfm->base, key, keylen); } -static void cast6_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void cast6_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(__cast6_encrypt)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, __cast6_encrypt); } -static void cast6_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void cast6_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(__cast6_decrypt)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, __cast6_decrypt); } -static void cast6_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void cast6_crypt_ctr(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblk; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; le128_to_be128(&ctrblk, iv); le128_inc(iv); @@ -70,10 +67,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_enc_8way) } + .fn_u = { .ecb = cast6_ecb_enc_8way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_encrypt) } + .fn_u = { .ecb = __cast6_encrypt } } } }; @@ -83,10 +80,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_ctr_8way) } + .fn_u = { .ctr = cast6_ctr_8way } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_crypt_ctr) } + .fn_u = { .ctr = cast6_crypt_ctr } } } }; @@ -96,10 +93,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc_8way) } + .fn_u = { .xts = cast6_xts_enc_8way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc) } + .fn_u = { .xts = cast6_xts_enc } } } }; @@ -109,10 +106,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_dec_8way) } + .fn_u = { .ecb = cast6_ecb_dec_8way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_decrypt) } + .fn_u = { .ecb = __cast6_decrypt } } } }; @@ -122,10 +119,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(cast6_cbc_dec_8way) } + .fn_u = { .cbc = cast6_cbc_dec_8way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__cast6_decrypt) } + .fn_u = { .cbc = __cast6_decrypt } } } }; @@ -135,10 +132,10 @@ .funcs = { { .num_blocks = CAST6_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec_8way) } + .fn_u = { .xts = cast6_xts_dec_8way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec) } + .fn_u = { .xts = cast6_xts_dec } } } }; @@ -154,8 +151,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(__cast6_encrypt), - req); + return glue_cbc_encrypt_req_128bit(__cast6_encrypt, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -199,8 +195,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct cast6_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&cast6_enc_xts, req, - XTS_TWEAK_CAST(__cast6_encrypt), + return glue_xts_req_128bit(&cast6_enc_xts, req, __cast6_encrypt, &ctx->tweak_ctx, &ctx->crypt_ctx, false); } @@ -209,8 +204,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct cast6_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&cast6_dec_xts, req, - XTS_TWEAK_CAST(__cast6_encrypt), + return glue_xts_req_128bit(&cast6_dec_xts, req, __cast6_encrypt, &ctx->tweak_ctx, &ctx->crypt_ctx, true); } --- linux-oracle-5.4.0.orig/arch/x86/crypto/chacha-avx512vl-x86_64.S +++ linux-oracle-5.4.0/arch/x86/crypto/chacha-avx512vl-x86_64.S @@ -172,7 +172,7 @@ # xor remaining bytes from partial register into output mov %rcx,%rax and $0xf,%rcx - jz .Ldone8 + jz .Ldone2 mov %rax,%r9 and $~0xf,%r9 @@ -438,7 +438,7 @@ # xor remaining bytes from partial register into output mov %rcx,%rax and $0xf,%rcx - jz .Ldone8 + jz .Ldone4 mov %rax,%r9 and $~0xf,%r9 --- linux-oracle-5.4.0.orig/arch/x86/crypto/crc32c-pcl-intel-asm_64.S +++ linux-oracle-5.4.0/arch/x86/crypto/crc32c-pcl-intel-asm_64.S @@ -170,7 +170,7 @@ ## branch into array lea jump_table(%rip), bufp - movzxw (bufp, %rax, 2), len + movzwq (bufp, %rax, 2), len lea crc_array(%rip), bufp lea (bufp, len, 1), bufp JMP_NOSPEC bufp --- linux-oracle-5.4.0.orig/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -19,6 +19,7 @@ #include #include #include +#include #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -54,7 +55,6 @@ const u8 *key, unsigned int keylen) { struct ghash_ctx *ctx = crypto_shash_ctx(tfm); - be128 *x = (be128 *)key; u64 a, b; if (keylen != GHASH_BLOCK_SIZE) { @@ -63,8 +63,8 @@ } /* perform multiplication by 'x' in GF(2^128) */ - a = be64_to_cpu(x->a); - b = be64_to_cpu(x->b); + a = get_unaligned_be64(key); + b = get_unaligned_be64(key + 8); ctx->shash.a = (b << 1) | (a >> 63); ctx->shash.b = (a << 1) | (b >> 63); --- linux-oracle-5.4.0.orig/arch/x86/crypto/glue_helper.c +++ linux-oracle-5.4.0/arch/x86/crypto/glue_helper.c @@ -134,7 +134,8 @@ src -= num_blocks - 1; dst -= num_blocks - 1; - gctx->funcs[i].fn_u.cbc(ctx, dst, src); + gctx->funcs[i].fn_u.cbc(ctx, (u8 *)dst, + (const u8 *)src); nbytes -= func_bytes; if (nbytes < bsize) @@ -188,7 +189,9 @@ /* Process multi-block batch */ do { - gctx->funcs[i].fn_u.ctr(ctx, dst, src, &ctrblk); + gctx->funcs[i].fn_u.ctr(ctx, (u8 *)dst, + (const u8 *)src, + &ctrblk); src += num_blocks; dst += num_blocks; nbytes -= func_bytes; @@ -210,7 +213,8 @@ be128_to_le128(&ctrblk, (be128 *)walk.iv); memcpy(&tmp, walk.src.virt.addr, nbytes); - gctx->funcs[gctx->num_funcs - 1].fn_u.ctr(ctx, &tmp, &tmp, + gctx->funcs[gctx->num_funcs - 1].fn_u.ctr(ctx, (u8 *)&tmp, + (const u8 *)&tmp, &ctrblk); memcpy(walk.dst.virt.addr, &tmp, nbytes); le128_to_be128((be128 *)walk.iv, &ctrblk); @@ -240,7 +244,8 @@ if (nbytes >= func_bytes) { do { - gctx->funcs[i].fn_u.xts(ctx, dst, src, + gctx->funcs[i].fn_u.xts(ctx, (u8 *)dst, + (const u8 *)src, walk->iv); src += num_blocks; @@ -354,8 +359,8 @@ } EXPORT_SYMBOL_GPL(glue_xts_req_128bit); -void glue_xts_crypt_128bit_one(void *ctx, u128 *dst, const u128 *src, le128 *iv, - common_glue_func_t fn) +void glue_xts_crypt_128bit_one(const void *ctx, u8 *dst, const u8 *src, + le128 *iv, common_glue_func_t fn) { le128 ivblk = *iv; @@ -363,13 +368,13 @@ gf128mul_x_ble(iv, &ivblk); /* CC <- T xor C */ - u128_xor(dst, src, (u128 *)&ivblk); + u128_xor((u128 *)dst, (const u128 *)src, (u128 *)&ivblk); /* PP <- D(Key2,CC) */ - fn(ctx, (u8 *)dst, (u8 *)dst); + fn(ctx, dst, dst); /* P <- T xor PP */ - u128_xor(dst, dst, (u128 *)&ivblk); + u128_xor((u128 *)dst, (u128 *)dst, (u128 *)&ivblk); } EXPORT_SYMBOL_GPL(glue_xts_crypt_128bit_one); --- linux-oracle-5.4.0.orig/arch/x86/crypto/nhpoly1305-avx2-glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/nhpoly1305-avx2-glue.c @@ -29,7 +29,7 @@ return crypto_nhpoly1305_update(desc, src, srclen); do { - unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); + unsigned int n = min_t(unsigned int, srclen, SZ_4K); kernel_fpu_begin(); crypto_nhpoly1305_update_helper(desc, src, n, _nh_avx2); --- linux-oracle-5.4.0.orig/arch/x86/crypto/nhpoly1305-sse2-glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/nhpoly1305-sse2-glue.c @@ -29,7 +29,7 @@ return crypto_nhpoly1305_update(desc, src, srclen); do { - unsigned int n = min_t(unsigned int, srclen, PAGE_SIZE); + unsigned int n = min_t(unsigned int, srclen, SZ_4K); kernel_fpu_begin(); crypto_nhpoly1305_update_helper(desc, src, n, _nh_sse2); --- linux-oracle-5.4.0.orig/arch/x86/crypto/serpent_avx2_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/serpent_avx2_glue.c @@ -19,18 +19,16 @@ #define SERPENT_AVX2_PARALLEL_BLOCKS 16 /* 16-way AVX2 parallel cipher functions */ -asmlinkage void serpent_ecb_enc_16way(struct serpent_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void serpent_ecb_dec_16way(struct serpent_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void serpent_cbc_dec_16way(void *ctx, u128 *dst, const u128 *src); +asmlinkage void serpent_ecb_enc_16way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void serpent_ecb_dec_16way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void serpent_cbc_dec_16way(const void *ctx, u8 *dst, const u8 *src); -asmlinkage void serpent_ctr_16way(void *ctx, u128 *dst, const u128 *src, +asmlinkage void serpent_ctr_16way(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -asmlinkage void serpent_xts_enc_16way(struct serpent_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); -asmlinkage void serpent_xts_dec_16way(struct serpent_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void serpent_xts_enc_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +asmlinkage void serpent_xts_dec_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); static int serpent_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) @@ -44,13 +42,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_enc_16way) } + .fn_u = { .ecb = serpent_ecb_enc_16way } }, { .num_blocks = 8, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_enc_8way_avx) } + .fn_u = { .ecb = serpent_ecb_enc_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } + .fn_u = { .ecb = __serpent_encrypt } } } }; @@ -60,13 +58,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_ctr_16way) } + .fn_u = { .ctr = serpent_ctr_16way } }, { .num_blocks = 8, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_ctr_8way_avx) } + .fn_u = { .ctr = serpent_ctr_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(__serpent_crypt_ctr) } + .fn_u = { .ctr = __serpent_crypt_ctr } } } }; @@ -76,13 +74,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc_16way) } + .fn_u = { .xts = serpent_xts_enc_16way } }, { .num_blocks = 8, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc_8way_avx) } + .fn_u = { .xts = serpent_xts_enc_8way_avx } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc) } + .fn_u = { .xts = serpent_xts_enc } } } }; @@ -92,13 +90,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_dec_16way) } + .fn_u = { .ecb = serpent_ecb_dec_16way } }, { .num_blocks = 8, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_dec_8way_avx) } + .fn_u = { .ecb = serpent_ecb_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .ecb = __serpent_decrypt } } } }; @@ -108,13 +106,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_cbc_dec_16way) } + .fn_u = { .cbc = serpent_cbc_dec_16way } }, { .num_blocks = 8, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_cbc_dec_8way_avx) } + .fn_u = { .cbc = serpent_cbc_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .cbc = __serpent_decrypt } } } }; @@ -124,13 +122,13 @@ .funcs = { { .num_blocks = 16, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec_16way) } + .fn_u = { .xts = serpent_xts_dec_16way } }, { .num_blocks = 8, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec_8way_avx) } + .fn_u = { .xts = serpent_xts_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec) } + .fn_u = { .xts = serpent_xts_dec } } } }; @@ -146,8 +144,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(__serpent_encrypt), - req); + return glue_cbc_encrypt_req_128bit(__serpent_encrypt, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -166,8 +163,8 @@ struct serpent_xts_ctx *ctx = crypto_skcipher_ctx(tfm); return glue_xts_req_128bit(&serpent_enc_xts, req, - XTS_TWEAK_CAST(__serpent_encrypt), - &ctx->tweak_ctx, &ctx->crypt_ctx, false); + __serpent_encrypt, &ctx->tweak_ctx, + &ctx->crypt_ctx, false); } static int xts_decrypt(struct skcipher_request *req) @@ -176,8 +173,8 @@ struct serpent_xts_ctx *ctx = crypto_skcipher_ctx(tfm); return glue_xts_req_128bit(&serpent_dec_xts, req, - XTS_TWEAK_CAST(__serpent_encrypt), - &ctx->tweak_ctx, &ctx->crypt_ctx, true); + __serpent_encrypt, &ctx->tweak_ctx, + &ctx->crypt_ctx, true); } static struct skcipher_alg serpent_algs[] = { --- linux-oracle-5.4.0.orig/arch/x86/crypto/serpent_avx_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/serpent_avx_glue.c @@ -20,33 +20,35 @@ #include /* 8-way parallel cipher functions */ -asmlinkage void serpent_ecb_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_ecb_enc_8way_avx(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx); -asmlinkage void serpent_ecb_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_ecb_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx); -asmlinkage void serpent_cbc_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_cbc_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src); EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx); -asmlinkage void serpent_ctr_8way_avx(struct serpent_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void serpent_ctr_8way_avx(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); EXPORT_SYMBOL_GPL(serpent_ctr_8way_avx); -asmlinkage void serpent_xts_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_xts_enc_8way_avx(const void *ctx, u8 *dst, const u8 *src, le128 *iv); EXPORT_SYMBOL_GPL(serpent_xts_enc_8way_avx); -asmlinkage void serpent_xts_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_xts_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src, le128 *iv); EXPORT_SYMBOL_GPL(serpent_xts_dec_8way_avx); -void __serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void __serpent_crypt_ctr(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblk; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; le128_to_be128(&ctrblk, iv); le128_inc(iv); @@ -56,17 +58,15 @@ } EXPORT_SYMBOL_GPL(__serpent_crypt_ctr); -void serpent_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void serpent_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(__serpent_encrypt)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, __serpent_encrypt); } EXPORT_SYMBOL_GPL(serpent_xts_enc); -void serpent_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void serpent_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(__serpent_decrypt)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, __serpent_decrypt); } EXPORT_SYMBOL_GPL(serpent_xts_dec); @@ -102,10 +102,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_enc_8way_avx) } + .fn_u = { .ecb = serpent_ecb_enc_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } + .fn_u = { .ecb = __serpent_encrypt } } } }; @@ -115,10 +115,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_ctr_8way_avx) } + .fn_u = { .ctr = serpent_ctr_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(__serpent_crypt_ctr) } + .fn_u = { .ctr = __serpent_crypt_ctr } } } }; @@ -128,10 +128,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc_8way_avx) } + .fn_u = { .xts = serpent_xts_enc_8way_avx } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_enc) } + .fn_u = { .xts = serpent_xts_enc } } } }; @@ -141,10 +141,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_ecb_dec_8way_avx) } + .fn_u = { .ecb = serpent_ecb_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .ecb = __serpent_decrypt } } } }; @@ -154,10 +154,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_cbc_dec_8way_avx) } + .fn_u = { .cbc = serpent_cbc_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .cbc = __serpent_decrypt } } } }; @@ -167,10 +167,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec_8way_avx) } + .fn_u = { .xts = serpent_xts_dec_8way_avx } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(serpent_xts_dec) } + .fn_u = { .xts = serpent_xts_dec } } } }; @@ -186,8 +186,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(__serpent_encrypt), - req); + return glue_cbc_encrypt_req_128bit(__serpent_encrypt, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -206,8 +205,8 @@ struct serpent_xts_ctx *ctx = crypto_skcipher_ctx(tfm); return glue_xts_req_128bit(&serpent_enc_xts, req, - XTS_TWEAK_CAST(__serpent_encrypt), - &ctx->tweak_ctx, &ctx->crypt_ctx, false); + __serpent_encrypt, &ctx->tweak_ctx, + &ctx->crypt_ctx, false); } static int xts_decrypt(struct skcipher_request *req) @@ -216,8 +215,8 @@ struct serpent_xts_ctx *ctx = crypto_skcipher_ctx(tfm); return glue_xts_req_128bit(&serpent_dec_xts, req, - XTS_TWEAK_CAST(__serpent_encrypt), - &ctx->tweak_ctx, &ctx->crypt_ctx, true); + __serpent_encrypt, &ctx->tweak_ctx, + &ctx->crypt_ctx, true); } static struct skcipher_alg serpent_algs[] = { --- linux-oracle-5.4.0.orig/arch/x86/crypto/serpent_sse2_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/serpent_sse2_glue.c @@ -31,9 +31,11 @@ return __serpent_setkey(crypto_skcipher_ctx(tfm), key, keylen); } -static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src) +static void serpent_decrypt_cbc_xway(const void *ctx, u8 *d, const u8 *s) { u128 ivs[SERPENT_PARALLEL_BLOCKS - 1]; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; unsigned int j; for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++) @@ -45,9 +47,11 @@ u128_xor(dst + (j + 1), dst + (j + 1), ivs + j); } -static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void serpent_crypt_ctr(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblk; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; le128_to_be128(&ctrblk, iv); le128_inc(iv); @@ -56,10 +60,12 @@ u128_xor(dst, src, (u128 *)&ctrblk); } -static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src, +static void serpent_crypt_ctr_xway(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblks[SERPENT_PARALLEL_BLOCKS]; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; unsigned int i; for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) { @@ -79,10 +85,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) } + .fn_u = { .ecb = serpent_enc_blk_xway } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) } + .fn_u = { .ecb = __serpent_encrypt } } } }; @@ -92,10 +98,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) } + .fn_u = { .ctr = serpent_crypt_ctr_xway } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) } + .fn_u = { .ctr = serpent_crypt_ctr } } } }; @@ -105,10 +111,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) } + .fn_u = { .ecb = serpent_dec_blk_xway } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .ecb = __serpent_decrypt } } } }; @@ -118,10 +124,10 @@ .funcs = { { .num_blocks = SERPENT_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) } + .fn_u = { .cbc = serpent_decrypt_cbc_xway } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) } + .fn_u = { .cbc = __serpent_decrypt } } } }; @@ -137,7 +143,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(__serpent_encrypt), + return glue_cbc_encrypt_req_128bit(__serpent_encrypt, req); } --- linux-oracle-5.4.0.orig/arch/x86/crypto/twofish_avx_glue.c +++ linux-oracle-5.4.0/arch/x86/crypto/twofish_avx_glue.c @@ -22,20 +22,17 @@ #define TWOFISH_PARALLEL_BLOCKS 8 /* 8-way parallel cipher functions */ -asmlinkage void twofish_ecb_enc_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void twofish_ecb_dec_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); - -asmlinkage void twofish_cbc_dec_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void twofish_ctr_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); - -asmlinkage void twofish_xts_enc_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); -asmlinkage void twofish_xts_dec_8way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void twofish_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void twofish_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src); + +asmlinkage void twofish_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void twofish_ctr_8way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); + +asmlinkage void twofish_xts_enc_8way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +asmlinkage void twofish_xts_dec_8way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); static int twofish_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) @@ -43,22 +40,19 @@ return twofish_setkey(&tfm->base, key, keylen); } -static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src) +static inline void twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src) { __twofish_enc_blk_3way(ctx, dst, src, false); } -static void twofish_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void twofish_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(twofish_enc_blk)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, twofish_enc_blk); } -static void twofish_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv) +static void twofish_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv) { - glue_xts_crypt_128bit_one(ctx, dst, src, iv, - GLUE_FUNC_CAST(twofish_dec_blk)); + glue_xts_crypt_128bit_one(ctx, dst, src, iv, twofish_dec_blk); } struct twofish_xts_ctx { @@ -93,13 +87,13 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_enc_8way) } + .fn_u = { .ecb = twofish_ecb_enc_8way } }, { .num_blocks = 3, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } + .fn_u = { .ecb = twofish_enc_blk_3way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } + .fn_u = { .ecb = twofish_enc_blk } } } }; @@ -109,13 +103,13 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_ctr_8way) } + .fn_u = { .ctr = twofish_ctr_8way } }, { .num_blocks = 3, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr_3way) } + .fn_u = { .ctr = twofish_enc_blk_ctr_3way } }, { .num_blocks = 1, - .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(twofish_enc_blk_ctr) } + .fn_u = { .ctr = twofish_enc_blk_ctr } } } }; @@ -125,10 +119,10 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_enc_8way) } + .fn_u = { .xts = twofish_xts_enc_8way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_enc) } + .fn_u = { .xts = twofish_xts_enc } } } }; @@ -138,13 +132,13 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_ecb_dec_8way) } + .fn_u = { .ecb = twofish_ecb_dec_8way } }, { .num_blocks = 3, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } + .fn_u = { .ecb = twofish_dec_blk_3way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } + .fn_u = { .ecb = twofish_dec_blk } } } }; @@ -154,13 +148,13 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_cbc_dec_8way) } + .fn_u = { .cbc = twofish_cbc_dec_8way } }, { .num_blocks = 3, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } + .fn_u = { .cbc = twofish_dec_blk_cbc_3way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } + .fn_u = { .cbc = twofish_dec_blk } } } }; @@ -170,10 +164,10 @@ .funcs = { { .num_blocks = TWOFISH_PARALLEL_BLOCKS, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_dec_8way) } + .fn_u = { .xts = twofish_xts_dec_8way } }, { .num_blocks = 1, - .fn_u = { .xts = GLUE_XTS_FUNC_CAST(twofish_xts_dec) } + .fn_u = { .xts = twofish_xts_dec } } } }; @@ -189,8 +183,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(twofish_enc_blk), - req); + return glue_cbc_encrypt_req_128bit(twofish_enc_blk, req); } static int cbc_decrypt(struct skcipher_request *req) @@ -208,8 +201,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct twofish_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&twofish_enc_xts, req, - XTS_TWEAK_CAST(twofish_enc_blk), + return glue_xts_req_128bit(&twofish_enc_xts, req, twofish_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, false); } @@ -218,8 +210,7 @@ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct twofish_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - return glue_xts_req_128bit(&twofish_dec_xts, req, - XTS_TWEAK_CAST(twofish_enc_blk), + return glue_xts_req_128bit(&twofish_dec_xts, req, twofish_enc_blk, &ctx->tweak_ctx, &ctx->crypt_ctx, true); } --- linux-oracle-5.4.0.orig/arch/x86/crypto/twofish_glue_3way.c +++ linux-oracle-5.4.0/arch/x86/crypto/twofish_glue_3way.c @@ -25,21 +25,22 @@ return twofish_setkey(&tfm->base, key, keylen); } -static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src) +static inline void twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src) { __twofish_enc_blk_3way(ctx, dst, src, false); } -static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst, +static inline void twofish_enc_blk_xor_3way(const void *ctx, u8 *dst, const u8 *src) { __twofish_enc_blk_3way(ctx, dst, src, true); } -void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src) +void twofish_dec_blk_cbc_3way(const void *ctx, u8 *d, const u8 *s) { u128 ivs[2]; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; ivs[0] = src[0]; ivs[1] = src[1]; @@ -51,9 +52,11 @@ } EXPORT_SYMBOL_GPL(twofish_dec_blk_cbc_3way); -void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv) +void twofish_enc_blk_ctr(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblk; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; if (dst != src) *dst = *src; @@ -66,10 +69,11 @@ } EXPORT_SYMBOL_GPL(twofish_enc_blk_ctr); -void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, - le128 *iv) +void twofish_enc_blk_ctr_3way(const void *ctx, u8 *d, const u8 *s, le128 *iv) { be128 ctrblks[3]; + u128 *dst = (u128 *)d; + const u128 *src = (const u128 *)s; if (dst != src) { dst[0] = src[0]; @@ -94,10 +98,10 @@ .funcs = { { .num_blocks = 3, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_3way) } + .fn_u = { .ecb = twofish_enc_blk_3way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk) } + .fn_u = { .ecb = twofish_enc_blk } } } }; @@ -107,10 +111,10 @@ .funcs = { { .num_blocks = 3, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr_3way) } + .fn_u = { .ctr = twofish_enc_blk_ctr_3way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_enc_blk_ctr) } + .fn_u = { .ctr = twofish_enc_blk_ctr } } } }; @@ -120,10 +124,10 @@ .funcs = { { .num_blocks = 3, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk_3way) } + .fn_u = { .ecb = twofish_dec_blk_3way } }, { .num_blocks = 1, - .fn_u = { .ecb = GLUE_FUNC_CAST(twofish_dec_blk) } + .fn_u = { .ecb = twofish_dec_blk } } } }; @@ -133,10 +137,10 @@ .funcs = { { .num_blocks = 3, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk_cbc_3way) } + .fn_u = { .cbc = twofish_dec_blk_cbc_3way } }, { .num_blocks = 1, - .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(twofish_dec_blk) } + .fn_u = { .cbc = twofish_dec_blk } } } }; @@ -152,8 +156,7 @@ static int cbc_encrypt(struct skcipher_request *req) { - return glue_cbc_encrypt_req_128bit(GLUE_FUNC_CAST(twofish_enc_blk), - req); + return glue_cbc_encrypt_req_128bit(twofish_enc_blk, req); } static int cbc_decrypt(struct skcipher_request *req) --- linux-oracle-5.4.0.orig/arch/x86/entry/calling.h +++ linux-oracle-5.4.0/arch/x86/entry/calling.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include /* @@ -98,13 +100,6 @@ #define SIZEOF_PTREGS 21*8 .macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0 - /* - * Push registers and sanitize registers of values that a - * speculation attack might otherwise want to exploit. The - * lower registers are likely clobbered well before they - * could be put to use in a speculative execution gadget. - * Interleave XOR with PUSH for better uop scheduling: - */ .if \save_ret pushq %rsi /* pt_regs->si */ movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */ @@ -114,57 +109,58 @@ pushq %rsi /* pt_regs->si */ .endif pushq \rdx /* pt_regs->dx */ - xorl %edx, %edx /* nospec dx */ pushq %rcx /* pt_regs->cx */ - xorl %ecx, %ecx /* nospec cx */ pushq \rax /* pt_regs->ax */ pushq %r8 /* pt_regs->r8 */ - xorl %r8d, %r8d /* nospec r8 */ pushq %r9 /* pt_regs->r9 */ - xorl %r9d, %r9d /* nospec r9 */ pushq %r10 /* pt_regs->r10 */ - xorl %r10d, %r10d /* nospec r10 */ pushq %r11 /* pt_regs->r11 */ - xorl %r11d, %r11d /* nospec r11*/ pushq %rbx /* pt_regs->rbx */ - xorl %ebx, %ebx /* nospec rbx*/ pushq %rbp /* pt_regs->rbp */ - xorl %ebp, %ebp /* nospec rbp*/ pushq %r12 /* pt_regs->r12 */ - xorl %r12d, %r12d /* nospec r12*/ pushq %r13 /* pt_regs->r13 */ - xorl %r13d, %r13d /* nospec r13*/ pushq %r14 /* pt_regs->r14 */ - xorl %r14d, %r14d /* nospec r14*/ pushq %r15 /* pt_regs->r15 */ - xorl %r15d, %r15d /* nospec r15*/ UNWIND_HINT_REGS + .if \save_ret pushq %rsi /* return address on top of stack */ .endif + + /* + * Sanitize registers of values that a speculation attack might + * otherwise want to exploit. The lower registers are likely clobbered + * well before they could be put to use in a speculative execution + * gadget. + */ + xorl %edx, %edx /* nospec dx */ + xorl %ecx, %ecx /* nospec cx */ + xorl %r8d, %r8d /* nospec r8 */ + xorl %r9d, %r9d /* nospec r9 */ + xorl %r10d, %r10d /* nospec r10 */ + xorl %r11d, %r11d /* nospec r11 */ + xorl %ebx, %ebx /* nospec rbx */ + xorl %ebp, %ebp /* nospec rbp */ + xorl %r12d, %r12d /* nospec r12 */ + xorl %r13d, %r13d /* nospec r13 */ + xorl %r14d, %r14d /* nospec r14 */ + xorl %r15d, %r15d /* nospec r15 */ + .endm -.macro POP_REGS pop_rdi=1 skip_r11rcx=0 +.macro POP_REGS pop_rdi=1 popq %r15 popq %r14 popq %r13 popq %r12 popq %rbp popq %rbx - .if \skip_r11rcx - popq %rsi - .else popq %r11 - .endif popq %r10 popq %r9 popq %r8 popq %rax - .if \skip_r11rcx - popq %rsi - .else popq %rcx - .endif popq %rdx popq %rsi .if \pop_rdi @@ -315,6 +311,62 @@ #endif /* + * IBRS kernel mitigation for Spectre_v2. + * + * Assumes full context is established (PUSH_REGS, CR3 and GS) and it clobbers + * the regs it uses (AX, CX, DX). Must be called before the first RET + * instruction (NOTE! UNTRAIN_RET includes a RET instruction) + * + * The optional argument is used to save/restore the current value, + * which is used on the paranoid paths. + * + * Assumes x86_spec_ctrl_{base,current} to have SPEC_CTRL_IBRS set. + */ +.macro IBRS_ENTER save_reg + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS + movl $MSR_IA32_SPEC_CTRL, %ecx + +.ifnb \save_reg + rdmsr + shl $32, %rdx + or %rdx, %rax + mov %rax, \save_reg + test $SPEC_CTRL_IBRS, %eax + jz .Ldo_wrmsr_\@ + lfence + jmp .Lend_\@ +.Ldo_wrmsr_\@: +.endif + + movq PER_CPU_VAR(x86_spec_ctrl_current), %rdx + movl %edx, %eax + shr $32, %rdx + wrmsr +.Lend_\@: +.endm + +/* + * Similar to IBRS_ENTER, requires KERNEL GS,CR3 and clobbers (AX, CX, DX) + * regs. Must be called after the last RET. + */ +.macro IBRS_EXIT save_reg + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_KERNEL_IBRS + movl $MSR_IA32_SPEC_CTRL, %ecx + +.ifnb \save_reg + mov \save_reg, %rdx +.else + movq PER_CPU_VAR(x86_spec_ctrl_current), %rdx + andl $(~SPEC_CTRL_IBRS), %edx +.endif + + movl %edx, %eax + shr $32, %rdx + wrmsr +.Lend_\@: +.endm + +/* * Mitigate Spectre v1 for conditional swapgs code paths. * * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to --- linux-oracle-5.4.0.orig/arch/x86/entry/common.c +++ linux-oracle-5.4.0/arch/x86/entry/common.c @@ -218,6 +218,7 @@ user_enter_irqoff(); mds_user_clear_cpu_buffers(); + amd_clear_divider(); } #define SYSCALL_EXIT_WORK_FLAGS \ --- linux-oracle-5.4.0.orig/arch/x86/entry/entry_32.S +++ linux-oracle-5.4.0/arch/x86/entry/entry_32.S @@ -172,7 +172,7 @@ ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI .if \no_user_check == 0 /* coming from usermode? */ - testl $SEGMENT_RPL_MASK, PT_CS(%esp) + testl $USER_SEGMENT_RPL_MASK, PT_CS(%esp) jz .Lend_\@ .endif /* On user-cr3? */ @@ -205,64 +205,76 @@ #define CS_FROM_ENTRY_STACK (1 << 31) #define CS_FROM_USER_CR3 (1 << 30) #define CS_FROM_KERNEL (1 << 29) +#define CS_FROM_ESPFIX (1 << 28) .macro FIXUP_FRAME /* * The high bits of the CS dword (__csh) are used for CS_FROM_*. * Clear them in case hardware didn't do this for us. */ - andl $0x0000ffff, 3*4(%esp) + andl $0x0000ffff, 4*4(%esp) #ifdef CONFIG_VM86 - testl $X86_EFLAGS_VM, 4*4(%esp) + testl $X86_EFLAGS_VM, 5*4(%esp) jnz .Lfrom_usermode_no_fixup_\@ #endif - testl $SEGMENT_RPL_MASK, 3*4(%esp) + testl $USER_SEGMENT_RPL_MASK, 4*4(%esp) jnz .Lfrom_usermode_no_fixup_\@ - orl $CS_FROM_KERNEL, 3*4(%esp) + orl $CS_FROM_KERNEL, 4*4(%esp) /* * When we're here from kernel mode; the (exception) stack looks like: * - * 5*4(%esp) - - * 4*4(%esp) - flags - * 3*4(%esp) - cs - * 2*4(%esp) - ip - * 1*4(%esp) - orig_eax - * 0*4(%esp) - gs / function + * 6*4(%esp) - + * 5*4(%esp) - flags + * 4*4(%esp) - cs + * 3*4(%esp) - ip + * 2*4(%esp) - orig_eax + * 1*4(%esp) - gs / function + * 0*4(%esp) - fs * * Lets build a 5 entry IRET frame after that, such that struct pt_regs * is complete and in particular regs->sp is correct. This gives us - * the original 5 enties as gap: + * the original 6 enties as gap: * - * 12*4(%esp) - - * 11*4(%esp) - gap / flags - * 10*4(%esp) - gap / cs - * 9*4(%esp) - gap / ip - * 8*4(%esp) - gap / orig_eax - * 7*4(%esp) - gap / gs / function - * 6*4(%esp) - ss - * 5*4(%esp) - sp - * 4*4(%esp) - flags - * 3*4(%esp) - cs - * 2*4(%esp) - ip - * 1*4(%esp) - orig_eax - * 0*4(%esp) - gs / function + * 14*4(%esp) - + * 13*4(%esp) - gap / flags + * 12*4(%esp) - gap / cs + * 11*4(%esp) - gap / ip + * 10*4(%esp) - gap / orig_eax + * 9*4(%esp) - gap / gs / function + * 8*4(%esp) - gap / fs + * 7*4(%esp) - ss + * 6*4(%esp) - sp + * 5*4(%esp) - flags + * 4*4(%esp) - cs + * 3*4(%esp) - ip + * 2*4(%esp) - orig_eax + * 1*4(%esp) - gs / function + * 0*4(%esp) - fs */ pushl %ss # ss pushl %esp # sp (points at ss) - addl $6*4, (%esp) # point sp back at the previous context - pushl 6*4(%esp) # flags - pushl 6*4(%esp) # cs - pushl 6*4(%esp) # ip - pushl 6*4(%esp) # orig_eax - pushl 6*4(%esp) # gs / function + addl $7*4, (%esp) # point sp back at the previous context + pushl 7*4(%esp) # flags + pushl 7*4(%esp) # cs + pushl 7*4(%esp) # ip + pushl 7*4(%esp) # orig_eax + pushl 7*4(%esp) # gs / function + pushl 7*4(%esp) # fs .Lfrom_usermode_no_fixup_\@: .endm .macro IRET_FRAME + /* + * We're called with %ds, %es, %fs, and %gs from the interrupted + * frame, so we shouldn't use them. Also, we may be in ESPFIX + * mode and therefore have a nonzero SS base and an offset ESP, + * so any attempt to access the stack needs to use SS. (except for + * accesses through %esp, which automatically use SS.) + */ testl $CS_FROM_KERNEL, 1*4(%esp) jz .Lfinished_frame_\@ @@ -276,31 +288,40 @@ movl 5*4(%esp), %eax # (modified) regs->sp movl 4*4(%esp), %ecx # flags - movl %ecx, -4(%eax) + movl %ecx, %ss:-1*4(%eax) movl 3*4(%esp), %ecx # cs andl $0x0000ffff, %ecx - movl %ecx, -8(%eax) + movl %ecx, %ss:-2*4(%eax) movl 2*4(%esp), %ecx # ip - movl %ecx, -12(%eax) + movl %ecx, %ss:-3*4(%eax) movl 1*4(%esp), %ecx # eax - movl %ecx, -16(%eax) + movl %ecx, %ss:-4*4(%eax) popl %ecx - lea -16(%eax), %esp + lea -4*4(%eax), %esp popl %eax .Lfinished_frame_\@: .endm -.macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0 skip_gs=0 +.macro SAVE_ALL pt_regs_ax=%eax switch_stacks=0 skip_gs=0 unwind_espfix=0 cld .if \skip_gs == 0 PUSH_GS .endif - FIXUP_FRAME pushl %fs + + pushl %eax + movl $(__KERNEL_PERCPU), %eax + movl %eax, %fs +.if \unwind_espfix > 0 + UNWIND_ESPFIX_STACK +.endif + popl %eax + + FIXUP_FRAME pushl %es pushl %ds pushl \pt_regs_ax @@ -313,8 +334,6 @@ movl $(__USER_DS), %edx movl %edx, %ds movl %edx, %es - movl $(__KERNEL_PERCPU), %edx - movl %edx, %fs .if \skip_gs == 0 SET_KERNEL_GS %edx .endif @@ -324,8 +343,8 @@ .endif .endm -.macro SAVE_ALL_NMI cr3_reg:req - SAVE_ALL +.macro SAVE_ALL_NMI cr3_reg:req unwind_espfix=0 + SAVE_ALL unwind_espfix=\unwind_espfix BUG_IF_WRONG_CR3 @@ -357,6 +376,7 @@ 2: popl %es 3: popl %fs POP_GS \pop + IRET_FRAME .pushsection .fixup, "ax" 4: movl $0, (%esp) jmp 1b @@ -395,7 +415,8 @@ .macro CHECK_AND_APPLY_ESPFIX #ifdef CONFIG_X86_ESPFIX32 -#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + (GDT_ENTRY_ESPFIX_SS * 8) +#define GDT_ESPFIX_OFFSET (GDT_ENTRY_ESPFIX_SS * 8) +#define GDT_ESPFIX_SS PER_CPU_VAR(gdt_page) + GDT_ESPFIX_OFFSET ALTERNATIVE "jmp .Lend_\@", "", X86_BUG_ESPFIX @@ -729,7 +750,6 @@ movl %ebx, PER_CPU_VAR(stack_canary)+stack_canary_offset #endif -#ifdef CONFIG_RETPOLINE /* * When switching from a shallower to a deeper call stack * the RSB may either underflow or use entries populated @@ -738,7 +758,6 @@ * speculative execution to prevent attack. */ FILL_RETURN_BUFFER %ebx, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW -#endif /* restore callee-saved registers */ popfl @@ -848,9 +867,10 @@ * Xen doesn't set %esp to be precisely what the normal SYSENTER * entry point expects, so fix it up before using the normal path. */ -ENTRY(xen_sysenter_target) +SYM_CODE_START(xen_sysenter_target) addl $5*4, %esp /* remove xen-provided frame */ jmp .Lsysenter_past_esp +SYM_CODE_END(xen_sysenter_target) #endif /* @@ -1075,7 +1095,6 @@ /* Restore user state */ RESTORE_REGS pop=4 # skip orig_eax/error_code .Lirq_return: - IRET_FRAME /* * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization * when returning from IPI handler and when returning from @@ -1128,30 +1147,43 @@ * We can't call C functions using the ESPFIX stack. This code reads * the high word of the segment base from the GDT and swiches to the * normal stack and adjusts ESP with the matching offset. + * + * We might be on user CR3 here, so percpu data is not mapped and we can't + * access the GDT through the percpu segment. Instead, use SGDT to find + * the cpu_entry_area alias of the GDT. */ #ifdef CONFIG_X86_ESPFIX32 /* fixup the stack */ - mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */ - mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */ + pushl %ecx + subl $2*4, %esp + sgdt (%esp) + movl 2(%esp), %ecx /* GDT address */ + /* + * Careful: ECX is a linear pointer, so we need to force base + * zero. %cs is the only known-linear segment we have right now. + */ + mov %cs:GDT_ESPFIX_OFFSET + 4(%ecx), %al /* bits 16..23 */ + mov %cs:GDT_ESPFIX_OFFSET + 7(%ecx), %ah /* bits 24..31 */ shl $16, %eax + addl $2*4, %esp + popl %ecx addl %esp, %eax /* the adjusted stack pointer */ pushl $__KERNEL_DS pushl %eax lss (%esp), %esp /* switch to the normal stack segment */ #endif .endm + .macro UNWIND_ESPFIX_STACK + /* It's safe to clobber %eax, all other regs need to be preserved */ #ifdef CONFIG_X86_ESPFIX32 movl %ss, %eax /* see if on espfix stack */ cmpw $__ESPFIX_SS, %ax - jne 27f - movl $__KERNEL_DS, %eax - movl %eax, %ds - movl %eax, %es + jne .Lno_fixup_\@ /* switch to normal stack */ FIXUP_ESPFIX_STACK -27: +.Lno_fixup_\@: #endif .endm @@ -1341,11 +1373,6 @@ #ifdef CONFIG_XEN_PV ENTRY(xen_hypervisor_callback) - pushl $-1 /* orig_ax = -1 => not a system call */ - SAVE_ALL - ENCODE_FRAME_POINTER - TRACE_IRQS_OFF - /* * Check to see if we got the event in the critical * region in xen_iret_direct, after we've reenabled @@ -1353,16 +1380,17 @@ * iret instruction's behaviour where it delivers a * pending interrupt when enabling interrupts: */ - movl PT_EIP(%esp), %eax - cmpl $xen_iret_start_crit, %eax + cmpl $xen_iret_start_crit, (%esp) jb 1f - cmpl $xen_iret_end_crit, %eax + cmpl $xen_iret_end_crit, (%esp) jae 1f - - jmp xen_iret_crit_fixup - -ENTRY(xen_do_upcall) -1: mov %esp, %eax + call xen_iret_crit_fixup +1: + pushl $-1 /* orig_ax = -1 => not a system call */ + SAVE_ALL + ENCODE_FRAME_POINTER + TRACE_IRQS_OFF + mov %esp, %eax call xen_evtchn_do_upcall #ifndef CONFIG_PREEMPTION call xen_maybe_preempt_hcall @@ -1449,10 +1477,9 @@ common_exception_read_cr2: /* the function address is in %gs's slot on the stack */ - SAVE_ALL switch_stacks=1 skip_gs=1 + SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1 ENCODE_FRAME_POINTER - UNWIND_ESPFIX_STACK /* fixup %gs */ GS_TO_REG %ecx @@ -1474,9 +1501,8 @@ common_exception: /* the function address is in %gs's slot on the stack */ - SAVE_ALL switch_stacks=1 skip_gs=1 + SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1 ENCODE_FRAME_POINTER - UNWIND_ESPFIX_STACK /* fixup %gs */ GS_TO_REG %ecx @@ -1515,6 +1541,10 @@ ASM_CLAC #ifdef CONFIG_X86_ESPFIX32 + /* + * ESPFIX_SS is only ever set on the return to user path + * after we've switched to the entry stack. + */ pushl %eax movl %ss, %eax cmpw $__ESPFIX_SS, %ax @@ -1550,6 +1580,11 @@ movl %ebx, %esp .Lnmi_return: +#ifdef CONFIG_X86_ESPFIX32 + testl $CS_FROM_ESPFIX, PT_CS(%esp) + jnz .Lnmi_from_espfix +#endif + CHECK_AND_APPLY_ESPFIX RESTORE_ALL_NMI cr3_reg=%edi pop=4 jmp .Lirq_return @@ -1557,23 +1592,42 @@ #ifdef CONFIG_X86_ESPFIX32 .Lnmi_espfix_stack: /* - * create the pointer to lss back + * Create the pointer to LSS back */ pushl %ss pushl %esp addl $4, (%esp) - /* copy the iret frame of 12 bytes */ - .rept 3 - pushl 16(%esp) - .endr - pushl %eax - SAVE_ALL_NMI cr3_reg=%edi + + /* Copy the (short) IRET frame */ + pushl 4*4(%esp) # flags + pushl 4*4(%esp) # cs + pushl 4*4(%esp) # ip + + pushl %eax # orig_ax + + SAVE_ALL_NMI cr3_reg=%edi unwind_espfix=1 ENCODE_FRAME_POINTER - FIXUP_ESPFIX_STACK # %eax == %esp + + /* clear CS_FROM_KERNEL, set CS_FROM_ESPFIX */ + xorl $(CS_FROM_ESPFIX | CS_FROM_KERNEL), PT_CS(%esp) + xorl %edx, %edx # zero error code - call do_nmi + movl %esp, %eax # pt_regs pointer + jmp .Lnmi_from_sysenter_stack + +.Lnmi_from_espfix: RESTORE_ALL_NMI cr3_reg=%edi - lss 12+4(%esp), %esp # back to espfix stack + /* + * Because we cleared CS_FROM_KERNEL, IRET_FRAME 'forgot' to + * fix up the gap and long frame: + * + * 3 - original frame (exception) + * 2 - ESPFIX block (above) + * 6 - gap (FIXUP_FRAME) + * 5 - long frame (FIXUP_FRAME) + * 1 - orig_ax + */ + lss (1+5+6)*4(%esp), %esp # back to espfix stack jmp .Lirq_return #endif END(nmi) @@ -1592,6 +1646,7 @@ END(int3) ENTRY(general_protection) + ASM_CLAC pushl $do_general_protection jmp common_exception END(general_protection) @@ -1604,13 +1659,13 @@ END(async_page_fault) #endif -ENTRY(rewind_stack_do_exit) +ENTRY(rewind_stack_and_make_dead) /* Prevent any naive code from trying to unwind to our caller. */ xorl %ebp, %ebp movl PER_CPU_VAR(cpu_current_top_of_stack), %esi leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp - call do_exit + call make_task_dead 1: jmp 1b -END(rewind_stack_do_exit) +END(rewind_stack_and_make_dead) --- linux-oracle-5.4.0.orig/arch/x86/entry/entry_64.S +++ linux-oracle-5.4.0/arch/x86/entry/entry_64.S @@ -172,6 +172,11 @@ /* IRQs are off. */ movq %rax, %rdi movq %rsp, %rsi + + /* clobbers %rax, make sure it is after saving the syscall nr */ + IBRS_ENTER + CLEAR_BRANCH_HISTORY + call do_syscall_64 /* returns with IRQs disabled */ TRACE_IRQS_IRETQ /* we're about to change IF */ @@ -248,9 +253,8 @@ * perf profiles. Nothing jumps here. */ syscall_return_via_sysret: - /* rcx and r11 are already restored (see code above) */ - UNWIND_HINT_EMPTY - POP_REGS pop_rdi=0 skip_r11rcx=1 + IBRS_EXIT + POP_REGS pop_rdi=0 /* * Now all regs are restored except RSP and RDI. @@ -258,6 +262,7 @@ */ movq %rsp, %rdi movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp + UNWIND_HINT_EMPTY pushq RSP-RDI(%rdi) /* RSP */ pushq (%rdi) /* RDI */ @@ -301,7 +306,6 @@ movq %rbx, PER_CPU_VAR(fixed_percpu_data) + stack_canary_offset #endif -#ifdef CONFIG_RETPOLINE /* * When switching from a shallower to a deeper call stack * the RSB may either underflow or use entries populated @@ -310,7 +314,6 @@ * speculative execution to prevent attack. */ FILL_RETURN_BUFFER %r12, RSB_CLEAR_LOOPS, X86_FEATURE_RSB_CTXSW -#endif /* restore callee-saved registers */ popq %r15 @@ -512,7 +515,7 @@ * +----------------------------------------------------+ */ ENTRY(interrupt_entry) - UNWIND_HINT_FUNC + UNWIND_HINT_IRET_REGS offset=16 ASM_CLAC cld @@ -544,9 +547,9 @@ pushq 5*8(%rdi) /* regs->eflags */ pushq 4*8(%rdi) /* regs->cs */ pushq 3*8(%rdi) /* regs->ip */ + UNWIND_HINT_IRET_REGS pushq 2*8(%rdi) /* regs->orig_ax */ pushq 8(%rdi) /* return address */ - UNWIND_HINT_FUNC movq (%rdi), %rdi jmp 2f @@ -616,12 +619,13 @@ jz retint_kernel /* Interrupt came from user space */ -GLOBAL(retint_user) +.Lretint_user: mov %rsp,%rdi call prepare_exit_to_usermode TRACE_IRQS_IRETQ GLOBAL(swapgs_restore_regs_and_return_to_usermode) + IBRS_EXIT #ifdef CONFIG_DEBUG_ENTRY /* Assert that pt_regs indicates user mode. */ testb $3, CS(%rsp) @@ -637,6 +641,7 @@ */ movq %rsp, %rdi movq PER_CPU_VAR(cpu_tss_rw + TSS_sp0), %rsp + UNWIND_HINT_EMPTY /* Copy the IRET frame to the trampoline stack. */ pushq 6*8(%rdi) /* SS */ @@ -1247,7 +1252,13 @@ */ FENCE_SWAPGS_KERNEL_ENTRY - ret + /* + * Once we have CR3 and %GS setup save and set SPEC_CTRL. Just like + * CR3 above, keep the old value in a callee saved register. + */ + IBRS_ENTER save_reg=%r15 + + RET END(paranoid_entry) /* @@ -1275,12 +1286,20 @@ jmp .Lparanoid_exit_restore .Lparanoid_exit_no_swapgs: TRACE_IRQS_IRETQ_DEBUG + + /* + * Must restore IBRS state before both CR3 and %GS since we need access + * to the per-CPU x86_spec_ctrl_shadow variable. + */ + IBRS_EXIT save_reg=%r15 + /* Always restore stashed CR3 value (see paranoid_entry) */ RESTORE_CR3 scratch_reg=%rbx save_reg=%r14 .Lparanoid_exit_restore: jmp restore_regs_and_return_to_kernel END(paranoid_exit) + /* * Save all registers in pt_regs, and switch GS if needed. */ @@ -1300,6 +1319,7 @@ FENCE_SWAPGS_USER_ENTRY /* We have user CR3. Change to kernel CR3. */ SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + IBRS_ENTER .Lerror_entry_from_usermode_after_swapgs: /* Put us onto the real thread stack. */ @@ -1355,6 +1375,7 @@ SWAPGS FENCE_SWAPGS_USER_ENTRY SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + IBRS_ENTER /* * Pretend that the exception came from user mode: set up pt_regs @@ -1372,7 +1393,7 @@ TRACE_IRQS_OFF testb $3, CS(%rsp) jz retint_kernel - jmp retint_user + jmp .Lretint_user END(error_exit) /* @@ -1460,6 +1481,8 @@ PUSH_AND_CLEAR_REGS rdx=(%rdx) ENCODE_FRAME_POINTER + IBRS_ENTER + /* * At this point we no longer need to worry about stack damage * due to nesting -- we're on the normal thread stack and we're @@ -1683,6 +1706,9 @@ movq $-1, %rsi call do_nmi + /* Always restore stashed SPEC_CTRL value (see paranoid_entry) */ + IBRS_EXIT save_reg=%r15 + /* Always restore stashed CR3 value (see paranoid_entry) */ RESTORE_CR3 scratch_reg=%r15 save_reg=%r14 @@ -1732,14 +1758,71 @@ END(ignore_sysret) #endif -ENTRY(rewind_stack_do_exit) +ENTRY(rewind_stack_and_make_dead) UNWIND_HINT_FUNC /* Prevent any naive code from trying to unwind to our caller. */ xorl %ebp, %ebp movq PER_CPU_VAR(cpu_current_top_of_stack), %rax leaq -PTREGS_SIZE(%rax), %rsp - UNWIND_HINT_FUNC sp_offset=PTREGS_SIZE + UNWIND_HINT_REGS - call do_exit -END(rewind_stack_do_exit) + call make_task_dead +END(rewind_stack_and_make_dead) + +/* + * This sequence executes branches in order to remove user branch information + * from the branch history tracker in the Branch Predictor, therefore removing + * user influence on subsequent BTB lookups. + * + * It should be used on parts prior to Alder Lake. Newer parts should use the + * BHI_DIS_S hardware control instead. If a pre-Alder Lake part is being + * virtualized on newer hardware the VMM should protect against BHI attacks by + * setting BHI_DIS_S for the guests. + * + * CALLs/RETs are necessary to prevent Loop Stream Detector(LSD) from engaging + * and not clearing the branch history. The call tree looks like: + * + * call 1 + * call 2 + * call 2 + * call 2 + * call 2 + * call 2 + * ret + * ret + * ret + * ret + * ret + * ret + * + * This means that the stack is non-constant and ORC can't unwind it with %rsp + * alone. Therefore we unconditionally set up the frame pointer, which allows + * ORC to unwind properly. + * + * The alignment is for performance and not for safety, and may be safely + * refactored in the future if needed. + */ +ENTRY(clear_bhb_loop) + push %rbp + mov %rsp, %rbp + movl $5, %ecx + call 1f + jmp 5f + .align 64, 0xcc +1: call 2f + RET + .align 64, 0xcc +2: movl $5, %eax +3: jmp 4f + nop +4: sub $1, %eax + jnz 3b + sub $1, %ecx + jnz 1b + RET +5: lfence + pop %rbp + RET +END(clear_bhb_loop) +EXPORT_SYMBOL_GPL(clear_bhb_loop) --- linux-oracle-5.4.0.orig/arch/x86/entry/entry_64_compat.S +++ linux-oracle-5.4.0/arch/x86/entry/entry_64_compat.S @@ -4,7 +4,6 @@ * * Copyright 2000-2002 Andi Kleen, SuSE Labs. */ -#include "calling.h" #include #include #include @@ -17,6 +16,8 @@ #include #include +#include "calling.h" + .section .entry.text, "ax" /* @@ -135,6 +136,15 @@ */ TRACE_IRQS_OFF + /* + * CPU bugs mitigations mechanisms can call other functions. They + * should be invoked after making sure TF is cleared because + * single-step is ignored only for instructions inside the + * entry_SYSENTER_compat function. + */ + IBRS_ENTER + CLEAR_BRANCH_HISTORY + movq %rsp, %rdi call do_fast_syscall_32 /* XEN PV guests always use IRET path */ @@ -253,6 +263,9 @@ */ TRACE_IRQS_OFF + IBRS_ENTER + CLEAR_BRANCH_HISTORY + movq %rsp, %rdi call do_fast_syscall_32 /* XEN PV guests always use IRET path */ @@ -267,6 +280,9 @@ */ STACKLEAK_ERASE TRACE_IRQS_ON /* User mode traces as IRQs on. */ + + IBRS_EXIT + movq RBX(%rsp), %rbx /* pt_regs->rbx */ movq RBP(%rsp), %rbp /* pt_regs->rbp */ movq EFLAGS(%rsp), %r11 /* pt_regs->flags (in r11) */ @@ -408,6 +424,8 @@ * gate turned them off. */ TRACE_IRQS_OFF + IBRS_ENTER + CLEAR_BRANCH_HISTORY movq %rsp, %rdi call do_int80_syscall_32 --- linux-oracle-5.4.0.orig/arch/x86/entry/syscall_32.c +++ linux-oracle-5.4.0/arch/x86/entry/syscall_32.c @@ -10,13 +10,11 @@ #ifdef CONFIG_IA32_EMULATION /* On X86_64, we use struct pt_regs * to pass parameters to syscalls */ #define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *); - -/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */ -extern asmlinkage long sys_ni_syscall(const struct pt_regs *); - +#define __sys_ni_syscall __ia32_sys_ni_syscall #else /* CONFIG_IA32_EMULATION */ #define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); +#define __sys_ni_syscall sys_ni_syscall #endif /* CONFIG_IA32_EMULATION */ #include @@ -29,6 +27,6 @@ * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ - [0 ... __NR_syscall_compat_max] = &sys_ni_syscall, + [0 ... __NR_syscall_compat_max] = &__sys_ni_syscall, #include }; --- linux-oracle-5.4.0.orig/arch/x86/entry/syscall_64.c +++ linux-oracle-5.4.0/arch/x86/entry/syscall_64.c @@ -4,11 +4,17 @@ #include #include #include +#include #include #include -/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */ -extern asmlinkage long sys_ni_syscall(const struct pt_regs *); +extern asmlinkage long sys_ni_syscall(void); + +SYSCALL_DEFINE0(ni_syscall) +{ + return sys_ni_syscall(); +} + #define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *); #define __SYSCALL_X32(nr, sym, qual) __SYSCALL_64(nr, sym, qual) #include @@ -23,7 +29,7 @@ * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ - [0 ... __NR_syscall_max] = &sys_ni_syscall, + [0 ... __NR_syscall_max] = &__x64_sys_ni_syscall, #include }; @@ -40,7 +46,7 @@ * Smells like a compiler bug -- it doesn't work * when the & below is removed. */ - [0 ... __NR_syscall_x32_max] = &sys_ni_syscall, + [0 ... __NR_syscall_x32_max] = &__x64_sys_ni_syscall, #include }; --- linux-oracle-5.4.0.orig/arch/x86/entry/syscalls/syscall_32.tbl +++ linux-oracle-5.4.0/arch/x86/entry/syscalls/syscall_32.tbl @@ -124,13 +124,13 @@ 110 i386 iopl sys_iopl __ia32_sys_iopl 111 i386 vhangup sys_vhangup __ia32_sys_vhangup 112 i386 idle -113 i386 vm86old sys_vm86old sys_ni_syscall +113 i386 vm86old sys_vm86old __ia32_sys_ni_syscall 114 i386 wait4 sys_wait4 __ia32_compat_sys_wait4 115 i386 swapoff sys_swapoff __ia32_sys_swapoff 116 i386 sysinfo sys_sysinfo __ia32_compat_sys_sysinfo 117 i386 ipc sys_ipc __ia32_compat_sys_ipc 118 i386 fsync sys_fsync __ia32_sys_fsync -119 i386 sigreturn sys_sigreturn sys32_sigreturn +119 i386 sigreturn sys_sigreturn __ia32_compat_sys_sigreturn 120 i386 clone sys_clone __ia32_compat_sys_x86_clone 121 i386 setdomainname sys_setdomainname __ia32_sys_setdomainname 122 i386 uname sys_newuname __ia32_sys_newuname @@ -177,14 +177,14 @@ 163 i386 mremap sys_mremap __ia32_sys_mremap 164 i386 setresuid sys_setresuid16 __ia32_sys_setresuid16 165 i386 getresuid sys_getresuid16 __ia32_sys_getresuid16 -166 i386 vm86 sys_vm86 sys_ni_syscall +166 i386 vm86 sys_vm86 __ia32_sys_ni_syscall 167 i386 query_module 168 i386 poll sys_poll __ia32_sys_poll 169 i386 nfsservctl 170 i386 setresgid sys_setresgid16 __ia32_sys_setresgid16 171 i386 getresgid sys_getresgid16 __ia32_sys_getresgid16 172 i386 prctl sys_prctl __ia32_sys_prctl -173 i386 rt_sigreturn sys_rt_sigreturn sys32_rt_sigreturn +173 i386 rt_sigreturn sys_rt_sigreturn __ia32_compat_sys_rt_sigreturn 174 i386 rt_sigaction sys_rt_sigaction __ia32_compat_sys_rt_sigaction 175 i386 rt_sigprocmask sys_rt_sigprocmask __ia32_compat_sys_rt_sigprocmask 176 i386 rt_sigpending sys_rt_sigpending __ia32_compat_sys_rt_sigpending --- linux-oracle-5.4.0.orig/arch/x86/entry/vdso/Makefile +++ linux-oracle-5.4.0/arch/x86/entry/vdso/Makefile @@ -178,7 +178,7 @@ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' VDSO_LDFLAGS = -shared --hash-style=both --build-id \ - $(call ld-option, --eh-frame-hdr) -Bsymbolic + $(call ld-option, --eh-frame-hdr) -Bsymbolic -z noexecstack GCOV_PROFILE := n quiet_cmd_vdso_and_check = VDSO $@ --- linux-oracle-5.4.0.orig/arch/x86/entry/vdso/vdso32-setup.c +++ linux-oracle-5.4.0/arch/x86/entry/vdso/vdso32-setup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include --- linux-oracle-5.4.0.orig/arch/x86/entry/vdso/vma.c +++ linux-oracle-5.4.0/arch/x86/entry/vdso/vma.c @@ -222,8 +222,8 @@ /* Round the lowest possible end address up to a PMD boundary. */ end = (start + len + PMD_SIZE - 1) & PMD_MASK; - if (end >= TASK_SIZE_MAX) - end = TASK_SIZE_MAX; + if (end >= DEFAULT_MAP_WINDOW) + end = DEFAULT_MAP_WINDOW; end -= len; if (end > start) { @@ -323,7 +323,7 @@ static __init int vdso_setup(char *s) { vdso64_enabled = simple_strtoul(s, NULL, 0); - return 0; + return 1; } __setup("vdso=", vdso_setup); --- linux-oracle-5.4.0.orig/arch/x86/entry/vsyscall/vsyscall_64.c +++ linux-oracle-5.4.0/arch/x86/entry/vsyscall/vsyscall_64.c @@ -98,11 +98,6 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) { - /* - * XXX: if access_ok, get_user, and put_user handled - * sig_on_uaccess_err, this could go away. - */ - if (!access_ok((void __user *)ptr, size)) { struct thread_struct *thread = ¤t->thread; @@ -120,10 +115,8 @@ bool emulate_vsyscall(unsigned long error_code, struct pt_regs *regs, unsigned long address) { - struct task_struct *tsk; unsigned long caller; int vsyscall_nr, syscall_nr, tmp; - int prev_sig_on_uaccess_err; long ret; unsigned long orig_dx; @@ -172,8 +165,6 @@ goto sigsegv; } - tsk = current; - /* * Check for access_ok violations and find the syscall nr. * @@ -233,12 +224,8 @@ goto do_ret; /* skip requested */ /* - * With a real vsyscall, page faults cause SIGSEGV. We want to - * preserve that behavior to make writing exploits harder. + * With a real vsyscall, page faults cause SIGSEGV. */ - prev_sig_on_uaccess_err = current->thread.sig_on_uaccess_err; - current->thread.sig_on_uaccess_err = 1; - ret = -EFAULT; switch (vsyscall_nr) { case 0: @@ -261,23 +248,12 @@ break; } - current->thread.sig_on_uaccess_err = prev_sig_on_uaccess_err; - check_fault: if (ret == -EFAULT) { /* Bad news -- userspace fed a bad pointer to a vsyscall. */ warn_bad_vsyscall(KERN_INFO, regs, "vsyscall fault (exploit attempt?)"); - - /* - * If we failed to generate a signal for any reason, - * generate one here. (This should be impossible.) - */ - if (WARN_ON_ONCE(!sigismember(&tsk->pending.signal, SIGBUS) && - !sigismember(&tsk->pending.signal, SIGSEGV))) - goto sigsegv; - - return true; /* Don't emulate the ret. */ + goto sigsegv; } regs->ax = ret; --- linux-oracle-5.4.0.orig/arch/x86/events/Kconfig +++ linux-oracle-5.4.0/arch/x86/events/Kconfig @@ -10,11 +10,11 @@ available on NehalemEX and more modern processors. config PERF_EVENTS_INTEL_RAPL - tristate "Intel rapl performance events" - depends on PERF_EVENTS && CPU_SUP_INTEL && PCI + tristate "Intel/AMD rapl performance events" + depends on PERF_EVENTS && (CPU_SUP_INTEL || CPU_SUP_AMD) && PCI default y ---help--- - Include support for Intel rapl performance events for power + Include support for Intel and AMD rapl performance events for power monitoring on modern processors. config PERF_EVENTS_INTEL_CSTATE --- linux-oracle-5.4.0.orig/arch/x86/events/Makefile +++ linux-oracle-5.4.0/arch/x86/events/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only obj-y += core.o probe.o +obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += rapl.o obj-y += amd/ obj-$(CONFIG_X86_LOCAL_APIC) += msr.o obj-$(CONFIG_CPU_SUP_INTEL) += intel/ --- linux-oracle-5.4.0.orig/arch/x86/events/amd/core.c +++ linux-oracle-5.4.0/arch/x86/events/amd/core.c @@ -14,6 +14,10 @@ static DEFINE_PER_CPU(unsigned long, perf_nmi_tstamp); static unsigned long perf_nmi_window; +/* AMD Event 0xFFF: Merge. Used with Large Increment per Cycle events */ +#define AMD_MERGE_EVENT ((0xFULL << 32) | 0xFFULL) +#define AMD_MERGE_EVENT_ENABLE (AMD_MERGE_EVENT | ARCH_PERFMON_EVENTSEL_ENABLE) + static __initconst const u64 amd_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -246,6 +250,7 @@ [PERF_COUNT_HW_CPU_CYCLES] = 0x0076, [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, [PERF_COUNT_HW_CACHE_REFERENCES] = 0xff60, + [PERF_COUNT_HW_CACHE_MISSES] = 0x0964, [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c2, [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c3, [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x0287, @@ -301,6 +306,25 @@ return offset; } +/* + * AMD64 events are detected based on their event codes. + */ +static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc) +{ + return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff); +} + +static inline bool amd_is_pair_event_code(struct hw_perf_event *hwc) +{ + if (!(x86_pmu.flags & PMU_FL_PAIR)) + return false; + + switch (amd_get_event_code(hwc)) { + case 0x003: return true; /* Retired SSE/AVX FLOPs */ + default: return false; + } +} + static int amd_core_hw_config(struct perf_event *event) { if (event->attr.exclude_host && event->attr.exclude_guest) @@ -316,15 +340,10 @@ else if (event->attr.exclude_guest) event->hw.config |= AMD64_EVENTSEL_HOSTONLY; - return 0; -} + if ((x86_pmu.flags & PMU_FL_PAIR) && amd_is_pair_event_code(&event->hw)) + event->hw.flags |= PERF_X86_EVENT_PAIR; -/* - * AMD64 events are detected based on their event codes. - */ -static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc) -{ - return ((hwc->config >> 24) & 0x0f00) | (hwc->config & 0x00ff); + return 0; } static inline int amd_is_nb_event(struct hw_perf_event *hwc) @@ -864,6 +883,29 @@ } } +static struct event_constraint pair_constraint; + +static struct event_constraint * +amd_get_event_constraints_f17h(struct cpu_hw_events *cpuc, int idx, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (amd_is_pair_event_code(hwc)) + return &pair_constraint; + + return &unconstrained; +} + +static void amd_put_event_constraints_f17h(struct cpu_hw_events *cpuc, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (is_counter_pair(hwc)) + --cpuc->n_pair; +} + static ssize_t amd_event_sysfs_show(char *page, u64 config) { u64 event = (config & ARCH_PERFMON_EVENTSEL_EVENT) | @@ -907,33 +949,15 @@ static int __init amd_core_pmu_init(void) { + u64 even_ctr_mask = 0ULL; + int i; + if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) return 0; - /* Avoid calulating the value each time in the NMI handler */ + /* Avoid calculating the value each time in the NMI handler */ perf_nmi_window = msecs_to_jiffies(100); - switch (boot_cpu_data.x86) { - case 0x15: - pr_cont("Fam15h "); - x86_pmu.get_event_constraints = amd_get_event_constraints_f15h; - break; - case 0x17: - pr_cont("Fam17h "); - /* - * In family 17h, there are no event constraints in the PMC hardware. - * We fallback to using default amd_get_event_constraints. - */ - break; - case 0x18: - pr_cont("Fam18h "); - /* Using default amd_get_event_constraints. */ - break; - default: - pr_err("core perfctr but no constraints; unknown hardware!\n"); - return -ENODEV; - } - /* * If core performance counter extensions exists, we must use * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also @@ -948,6 +972,32 @@ */ x86_pmu.amd_nb_constraints = 0; + if (boot_cpu_data.x86 == 0x15) { + pr_cont("Fam15h "); + x86_pmu.get_event_constraints = amd_get_event_constraints_f15h; + } + if (boot_cpu_data.x86 >= 0x17) { + pr_cont("Fam17h+ "); + /* + * Family 17h and compatibles have constraints for Large + * Increment per Cycle events: they may only be assigned an + * even numbered counter that has a consecutive adjacent odd + * numbered counter following it. + */ + for (i = 0; i < x86_pmu.num_counters - 1; i += 2) + even_ctr_mask |= BIT_ULL(i); + + pair_constraint = (struct event_constraint) + __EVENT_CONSTRAINT(0, even_ctr_mask, 0, + x86_pmu.num_counters / 2, 0, + PERF_X86_EVENT_PAIR); + + x86_pmu.get_event_constraints = amd_get_event_constraints_f17h; + x86_pmu.put_event_constraints = amd_put_event_constraints_f17h; + x86_pmu.perf_ctr_pair_en = AMD_MERGE_EVENT_ENABLE; + x86_pmu.flags |= PMU_FL_PAIR; + } + pr_cont("core perfctr, "); return 0; } --- linux-oracle-5.4.0.orig/arch/x86/events/amd/ibs.c +++ linux-oracle-5.4.0/arch/x86/events/amd/ibs.c @@ -89,6 +89,8 @@ u64 max_period; unsigned long offset_mask[1]; int offset_max; + unsigned int fetch_count_reset_broken : 1; + unsigned int fetch_ignore_if_zero_rip : 1; struct cpu_perf_ibs __percpu *pcpu; struct attribute **format_attrs; @@ -310,6 +312,16 @@ hwc->config_base = perf_ibs->msr; hwc->config = config; + /* + * rip recorded by IbsOpRip will not be consistent with rsp and rbp + * recorded as part of interrupt regs. Thus we need to use rip from + * interrupt regs while unwinding call stack. Setting _EARLY flag + * makes sure we unwind call-stack before perf sample rip is set to + * IbsOpRip. + */ + if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) + event->attr.sample_type |= __PERF_SAMPLE_CALLCHAIN_EARLY; + return 0; } @@ -334,11 +346,15 @@ { u64 count = 0; + /* + * If the internal 27-bit counter rolled over, the count is MaxCnt + * and the lower 7 bits of CurCnt are randomized. + * Otherwise CurCnt has the full 27-bit current counter value. + */ if (config & IBS_OP_VAL) - count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */ - - if (ibs_caps & IBS_CAPS_RDWROPCNT) - count += (config & IBS_OP_CUR_CNT) >> 32; + count = (config & IBS_OP_MAX_CNT) << 4; + else if (ibs_caps & IBS_CAPS_RDWROPCNT) + count = (config & IBS_OP_CUR_CNT) >> 32; return count; } @@ -363,7 +379,12 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs, struct hw_perf_event *hwc, u64 config) { - wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask); + u64 tmp = hwc->config | config; + + if (perf_ibs->fetch_count_reset_broken) + wrmsrl(hwc->config_base, tmp & ~perf_ibs->enable_mask); + + wrmsrl(hwc->config_base, tmp | perf_ibs->enable_mask); } /* @@ -551,6 +572,7 @@ .start = perf_ibs_start, .stop = perf_ibs_stop, .read = perf_ibs_read, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE, }, .msr = MSR_AMD64_IBSOPCTL, .config_mask = IBS_OP_CONFIG_MASK, @@ -626,18 +648,24 @@ perf_ibs->offset_max, offset + 1); } while (offset < offset_max); + /* + * Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately + * depending on their availability. + * Can't add to offset_max as they are staggered + */ if (event->attr.sample_type & PERF_SAMPLE_RAW) { - /* - * Read IbsBrTarget and IbsOpData4 separately - * depending on their availability. - * Can't add to offset_max as they are staggered - */ - if (ibs_caps & IBS_CAPS_BRNTRGT) { - rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++); - size++; + if (perf_ibs == &perf_ibs_op) { + if (ibs_caps & IBS_CAPS_BRNTRGT) { + rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++); + size++; + } + if (ibs_caps & IBS_CAPS_OPDATA4) { + rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++); + size++; + } } - if (ibs_caps & IBS_CAPS_OPDATA4) { - rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++); + if (perf_ibs == &perf_ibs_fetch && (ibs_caps & IBS_CAPS_FETCHCTLEXTD)) { + rdmsrl(MSR_AMD64_ICIBSEXTDCTL, *buf++); size++; } } @@ -647,6 +675,10 @@ if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { regs.flags &= ~PERF_EFLAGS_EXACT; } else { + /* Workaround for erratum #1197 */ + if (perf_ibs->fetch_ignore_if_zero_rip && !(ibs_data.regs[1])) + goto out; + set_linear_ip(®s, ibs_data.regs[1]); regs.flags |= PERF_EFLAGS_EXACT; } @@ -661,6 +693,14 @@ data.raw = &raw; } + /* + * rip recorded by IbsOpRip will not be consistent with rsp and rbp + * recorded as part of interrupt regs. Thus we need to use rip from + * interrupt regs while unwinding call stack. + */ + if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) + data.callchain = perf_callchain(event, iregs); + throttle = perf_event_overflow(event, &data, ®s); out: if (throttle) { @@ -733,6 +773,16 @@ { struct attribute **attr = ibs_op_format_attrs; + /* + * Some chips fail to reset the fetch count when it is written; instead + * they need a 0-1 transition of IbsFetchEn. + */ + if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18) + perf_ibs_fetch.fetch_count_reset_broken = 1; + + if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10) + perf_ibs_fetch.fetch_ignore_if_zero_rip = 1; + perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); if (ibs_caps & IBS_CAPS_OPCNT) { --- linux-oracle-5.4.0.orig/arch/x86/events/amd/iommu.c +++ linux-oracle-5.4.0/arch/x86/events/amd/iommu.c @@ -18,8 +18,6 @@ #include "../perf_event.h" #include "iommu.h" -#define COUNTER_SHIFT 16 - /* iommu pmu conf masks */ #define GET_CSOURCE(x) ((x)->conf & 0xFFULL) #define GET_DEVID(x) (((x)->conf >> 8) & 0xFFFFULL) @@ -81,12 +79,12 @@ }; struct amd_iommu_event_desc { - struct kobj_attribute attr; + struct device_attribute attr; const char *event; }; -static ssize_t _iommu_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) +static ssize_t _iommu_event_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct amd_iommu_event_desc *event = container_of(attr, struct amd_iommu_event_desc, attr); @@ -285,22 +283,31 @@ WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE)); hwc->state = 0; + /* + * To account for power-gating, which prevents write to + * the counter, we need to enable the counter + * before setting up counter register. + */ + perf_iommu_enable_event(event); + if (flags & PERF_EF_RELOAD) { - u64 prev_raw_count = local64_read(&hwc->prev_count); + u64 count = 0; struct amd_iommu *iommu = perf_event_2_iommu(event); + /* + * Since the IOMMU PMU only support counting mode, + * the counter always start with value zero. + */ amd_iommu_pc_set_reg(iommu, hwc->iommu_bank, hwc->iommu_cntr, - IOMMU_PC_COUNTER_REG, &prev_raw_count); + IOMMU_PC_COUNTER_REG, &count); } - perf_iommu_enable_event(event); perf_event_update_userpage(event); - } static void perf_iommu_read(struct perf_event *event) { - u64 count, prev, delta; + u64 count; struct hw_perf_event *hwc = &event->hw; struct amd_iommu *iommu = perf_event_2_iommu(event); @@ -311,14 +318,11 @@ /* IOMMU pc counter register is only 48 bits */ count &= GENMASK_ULL(47, 0); - prev = local64_read(&hwc->prev_count); - if (local64_cmpxchg(&hwc->prev_count, prev, count) != prev) - return; - - /* Handle 48-bit counter overflow */ - delta = (count << COUNTER_SHIFT) - (prev << COUNTER_SHIFT); - delta >>= COUNTER_SHIFT; - local64_add(delta, &event->count); + /* + * Since the counter always start with value zero, + * simply just accumulate the count for the event. + */ + local64_add(count, &event->count); } static void perf_iommu_stop(struct perf_event *event, int flags) @@ -328,15 +332,16 @@ if (hwc->state & PERF_HES_UPTODATE) return; + /* + * To account for power-gating, in which reading the counter would + * return zero, we need to read the register before disabling. + */ + perf_iommu_read(event); + hwc->state |= PERF_HES_UPTODATE; + perf_iommu_disable_event(event); WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); hwc->state |= PERF_HES_STOPPED; - - if (hwc->state & PERF_HES_UPTODATE) - return; - - perf_iommu_read(event); - hwc->state |= PERF_HES_UPTODATE; } static int perf_iommu_add(struct perf_event *event, int flags) @@ -379,7 +384,7 @@ while (amd_iommu_v2_event_descs[i].attr.attr.name) i++; - attrs = kcalloc(i + 1, sizeof(struct attribute **), GFP_KERNEL); + attrs = kcalloc(i + 1, sizeof(*attrs), GFP_KERNEL); if (!attrs) return -ENOMEM; --- linux-oracle-5.4.0.orig/arch/x86/events/amd/power.c +++ linux-oracle-5.4.0/arch/x86/events/amd/power.c @@ -217,6 +217,7 @@ .stop = pmu_event_stop, .read = pmu_event_read, .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .module = THIS_MODULE, }; static int power_cpu_exit(unsigned int cpu) --- linux-oracle-5.4.0.orig/arch/x86/events/amd/uncore.c +++ linux-oracle-5.4.0/arch/x86/events/amd/uncore.c @@ -190,15 +190,12 @@ /* * NB and Last level cache counters (MSRs) are shared across all cores - * that share the same NB / Last level cache. Interrupts can be directed - * to a single target core, however, event counts generated by processes - * running on other cores cannot be masked out. So we do not support - * sampling and per-thread events. + * that share the same NB / Last level cache. On family 16h and below, + * Interrupts can be directed to a single target core, however, event + * counts generated by processes running on other cores cannot be masked + * out. So we do not support sampling and per-thread events via + * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: */ - if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) - return -EINVAL; - - /* and we do not enable counter overflow interrupts */ hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; hwc->idx = -1; @@ -306,7 +303,7 @@ .start = amd_uncore_start, .stop = amd_uncore_stop, .read = amd_uncore_read, - .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, }; static struct pmu amd_llc_pmu = { @@ -317,7 +314,7 @@ .start = amd_uncore_start, .stop = amd_uncore_stop, .read = amd_uncore_read, - .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, }; static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) --- linux-oracle-5.4.0.orig/arch/x86/events/core.c +++ linux-oracle-5.4.0/arch/x86/events/core.c @@ -375,7 +375,7 @@ * LBR and BTS are still mutually exclusive. */ if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt) - return 0; + goto out; if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) { mutex_lock(&pmc_reserve_mutex); @@ -387,6 +387,7 @@ mutex_unlock(&pmc_reserve_mutex); } +out: atomic_inc(&active_events); return 0; @@ -397,11 +398,15 @@ void x86_del_exclusive(unsigned int what) { + atomic_dec(&active_events); + + /* + * See the comment in x86_add_exclusive(). + */ if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt) return; atomic_dec(&x86_pmu.lbr_exclusive[what]); - atomic_dec(&active_events); } int x86_setup_perfctr(struct perf_event *event) @@ -612,6 +617,7 @@ int idx; for (idx = 0; idx < x86_pmu.num_counters; idx++) { + struct hw_perf_event *hwc = &cpuc->events[idx]->hw; u64 val; if (!test_bit(idx, cpuc->active_mask)) @@ -621,6 +627,8 @@ continue; val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; wrmsrl(x86_pmu_config_addr(idx), val); + if (is_counter_pair(hwc)) + wrmsrl(x86_pmu_config_addr(idx + 1), 0); } } @@ -693,7 +701,7 @@ int counter; /* counter index */ int unassigned; /* number of events to be assigned left */ int nr_gp; /* number of GP counters used */ - unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; + u64 used; }; /* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */ @@ -750,8 +758,12 @@ sched->saved_states--; sched->state = sched->saved[sched->saved_states]; - /* continue with next counter: */ - clear_bit(sched->state.counter++, sched->state.used); + /* this assignment didn't work out */ + /* XXX broken vs EVENT_PAIR */ + sched->state.used &= ~BIT_ULL(sched->state.counter); + + /* try the next one */ + sched->state.counter++; return true; } @@ -776,20 +788,32 @@ if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { idx = INTEL_PMC_IDX_FIXED; for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { - if (!__test_and_set_bit(idx, sched->state.used)) - goto done; + u64 mask = BIT_ULL(idx); + + if (sched->state.used & mask) + continue; + + sched->state.used |= mask; + goto done; } } /* Grab the first unused counter starting with idx */ idx = sched->state.counter; for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { - if (!__test_and_set_bit(idx, sched->state.used)) { - if (sched->state.nr_gp++ >= sched->max_gp) - return false; + u64 mask = BIT_ULL(idx); - goto done; - } + if (c->flags & PERF_X86_EVENT_PAIR) + mask |= mask << 1; + + if (sched->state.used & mask) + continue; + + if (sched->state.nr_gp++ >= sched->max_gp) + return false; + + sched->state.used |= mask; + goto done; } return false; @@ -866,12 +890,10 @@ int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) { struct event_constraint *c; - unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; struct perf_event *e; int n0, i, wmin, wmax, unsched = 0; struct hw_perf_event *hwc; - - bitmap_zero(used_mask, X86_PMC_IDX_MAX); + u64 used_mask = 0; /* * Compute the number of events already present; see x86_pmu_add(), @@ -914,6 +936,8 @@ * fastpath, try to reuse previous register */ for (i = 0; i < n; i++) { + u64 mask; + hwc = &cpuc->event_list[i]->hw; c = cpuc->event_constraint[i]; @@ -925,11 +949,16 @@ if (!test_bit(hwc->idx, c->idxmsk)) break; + mask = BIT_ULL(hwc->idx); + if (is_counter_pair(hwc)) + mask |= mask << 1; + /* not already used */ - if (test_bit(hwc->idx, used_mask)) + if (used_mask & mask) break; - __set_bit(hwc->idx, used_mask); + used_mask |= mask; + if (assign) assign[i] = hwc->idx; } @@ -952,6 +981,15 @@ READ_ONCE(cpuc->excl_cntrs->exclusive_present)) gpmax /= 2; + /* + * Reduce the amount of available counters to allow fitting + * the extra Merge events needed by large increment events. + */ + if (x86_pmu.flags & PMU_FL_PAIR) { + gpmax = x86_pmu.num_counters - cpuc->n_pair; + WARN_ON(gpmax <= 0); + } + unsched = perf_assign_events(cpuc->event_constraint, n, wmin, wmax, gpmax, assign); } @@ -1032,6 +1070,8 @@ return -EINVAL; cpuc->event_list[n] = leader; n++; + if (is_counter_pair(&leader->hw)) + cpuc->n_pair++; } if (!dogrp) return n; @@ -1046,6 +1086,8 @@ cpuc->event_list[n] = event; n++; + if (is_counter_pair(&event->hw)) + cpuc->n_pair++; } return n; } @@ -1232,6 +1274,13 @@ wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask); /* + * Clear the Merge event counter's upper 16 bits since + * we currently declare a 48-bit counter width + */ + if (is_counter_pair(hwc)) + wrmsrl(x86_pmu_event_addr(idx + 1), 0); + + /* * Due to erratum on certan cpu we need * a second write to be sure the register * is updated properly @@ -1641,9 +1690,12 @@ ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) { - struct perf_pmu_events_attr *pmu_attr = \ + struct perf_pmu_events_attr *pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); - u64 config = x86_pmu.event_map(pmu_attr->id); + u64 config = 0; + + if (pmu_attr->id < x86_pmu.max_events) + config = x86_pmu.event_map(pmu_attr->id); /* string trumps id */ if (pmu_attr->event_str) @@ -1712,6 +1764,9 @@ { struct perf_pmu_events_attr *pmu_attr; + if (idx >= x86_pmu.max_events) + return 0; + pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr.attr); /* str trumps id */ return pmu_attr->event_str || x86_pmu.event_map(idx) ? attr->mode : 0; @@ -2097,6 +2152,7 @@ if (err) { if (event->destroy) event->destroy(event); + event->destroy = NULL; } if (READ_ONCE(x86_pmu.attr_rdpmc) && @@ -2354,10 +2410,11 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct unwind_state state; unsigned long addr; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* TODO: We don't support guest os callchain now */ return; } @@ -2463,10 +2520,11 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); struct stack_frame frame; const unsigned long __user *fp; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { + if (guest_cbs && guest_cbs->is_in_guest()) { /* TODO: We don't support guest os callchain now */ return; } @@ -2550,18 +2608,21 @@ unsigned long perf_instruction_pointer(struct pt_regs *regs) { - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) - return perf_guest_cbs->get_guest_ip(); + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); + + if (guest_cbs && guest_cbs->is_in_guest()) + return guest_cbs->get_guest_ip(); return regs->ip + code_segment_base(regs); } unsigned long perf_misc_flags(struct pt_regs *regs) { + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); int misc = 0; - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { - if (perf_guest_cbs->is_user_mode()) + if (guest_cbs && guest_cbs->is_in_guest()) { + if (guest_cbs->is_user_mode()) misc |= PERF_RECORD_MISC_GUEST_USER; else misc |= PERF_RECORD_MISC_GUEST_KERNEL; --- linux-oracle-5.4.0.orig/arch/x86/events/intel/Makefile +++ linux-oracle-5.4.0/arch/x86/events/intel/Makefile @@ -2,8 +2,6 @@ obj-$(CONFIG_CPU_SUP_INTEL) += core.o bts.o obj-$(CONFIG_CPU_SUP_INTEL) += ds.o knc.o obj-$(CONFIG_CPU_SUP_INTEL) += lbr.o p4.o p6.o pt.o -obj-$(CONFIG_PERF_EVENTS_INTEL_RAPL) += intel-rapl-perf.o -intel-rapl-perf-objs := rapl.o obj-$(CONFIG_PERF_EVENTS_INTEL_UNCORE) += intel-uncore.o intel-uncore-objs := uncore.o uncore_nhmex.o uncore_snb.o uncore_snbep.o obj-$(CONFIG_PERF_EVENTS_INTEL_CSTATE) += intel-cstate.o --- linux-oracle-5.4.0.orig/arch/x86/events/intel/bts.c +++ linux-oracle-5.4.0/arch/x86/events/intel/bts.c @@ -63,9 +63,17 @@ static struct pmu bts_pmu; +static int buf_nr_pages(struct page *page) +{ + if (!PagePrivate(page)) + return 1; + + return 1 << page_private(page); +} + static size_t buf_size(struct page *page) { - return 1 << (PAGE_SHIFT + page_private(page)); + return buf_nr_pages(page) * PAGE_SIZE; } static void * @@ -83,9 +91,7 @@ /* count all the high order buffers */ for (pg = 0, nbuf = 0; pg < nr_pages;) { page = virt_to_page(pages[pg]); - if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1)) - return NULL; - pg += 1 << page_private(page); + pg += buf_nr_pages(page); nbuf++; } @@ -109,7 +115,7 @@ unsigned int __nr_pages; page = virt_to_page(pages[pg]); - __nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1; + __nr_pages = buf_nr_pages(page); buf->buf[nbuf].page = page; buf->buf[nbuf].offset = offset; buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0); --- linux-oracle-5.4.0.orig/arch/x86/events/intel/core.c +++ linux-oracle-5.4.0/arch/x86/events/intel/core.c @@ -243,21 +243,23 @@ static struct event_constraint intel_icl_event_constraints[] = { FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ - INTEL_UEVENT_CONSTRAINT(0x1c0, 0), /* INST_RETIRED.PREC_DIST */ + FIXED_EVENT_CONSTRAINT(0x01c0, 0), /* INST_RETIRED.PREC_DIST */ FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ FIXED_EVENT_CONSTRAINT(0x0300, 2), /* CPU_CLK_UNHALTED.REF */ FIXED_EVENT_CONSTRAINT(0x0400, 3), /* SLOTS */ INTEL_EVENT_CONSTRAINT_RANGE(0x03, 0x0a, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0x1f, 0x28, 0xf), INTEL_EVENT_CONSTRAINT(0x32, 0xf), /* SW_PREFETCH_ACCESS.* */ - INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x54, 0xf), + INTEL_EVENT_CONSTRAINT_RANGE(0x48, 0x56, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0x60, 0x8b, 0xf), INTEL_UEVENT_CONSTRAINT(0x04a3, 0xff), /* CYCLE_ACTIVITY.STALLS_TOTAL */ - INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff), /* CYCLE_ACTIVITY.STALLS_MEM_ANY */ + INTEL_UEVENT_CONSTRAINT(0x10a3, 0xff), /* CYCLE_ACTIVITY.CYCLES_MEM_ANY */ + INTEL_UEVENT_CONSTRAINT(0x14a3, 0xff), /* CYCLE_ACTIVITY.STALLS_MEM_ANY */ INTEL_EVENT_CONSTRAINT(0xa3, 0xf), /* CYCLE_ACTIVITY.* */ INTEL_EVENT_CONSTRAINT_RANGE(0xa8, 0xb0, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0xb7, 0xbd, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xe6, 0xf), + INTEL_EVENT_CONSTRAINT(0xef, 0xf), INTEL_EVENT_CONSTRAINT_RANGE(0xf0, 0xf4, 0xf), EVENT_CONSTRAINT_END }; @@ -1892,8 +1894,8 @@ static struct extra_reg intel_tnt_extra_regs[] __read_mostly = { /* must define OFFCORE_RSP_X first, see intel_fixup_er() */ - INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0xffffff9fffull, RSP_0), - INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0xffffff9fffull, RSP_1), + INTEL_UEVENT_EXTRA_REG(0x01b7, MSR_OFFCORE_RSP_0, 0x800ff0ffffff9fffull, RSP_0), + INTEL_UEVENT_EXTRA_REG(0x02b7, MSR_OFFCORE_RSP_1, 0xff0ffffff9fffull, RSP_1), EVENT_EXTRA_END }; @@ -2331,6 +2333,7 @@ { struct perf_sample_data data; struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + struct perf_guest_info_callbacks *guest_cbs; int bit; int handled = 0; @@ -2384,9 +2387,11 @@ */ if (__test_and_clear_bit(55, (unsigned long *)&status)) { handled++; - if (unlikely(perf_guest_cbs && perf_guest_cbs->is_in_guest() && - perf_guest_cbs->handle_intel_pt_intr)) - perf_guest_cbs->handle_intel_pt_intr(); + + guest_cbs = perf_get_guest_cbs(); + if (unlikely(guest_cbs && guest_cbs->is_in_guest() && + guest_cbs->handle_intel_pt_intr)) + guest_cbs->handle_intel_pt_intr(); else intel_pt_interrupt(); } @@ -3998,9 +4003,13 @@ INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 3, 0x07000009), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 4, 0x0f000009), INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_D, 5, 0x0e000002), - INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 2, 0x0b000014), + INTEL_CPU_DESC(INTEL_FAM6_BROADWELL_X, 1, 0x0b000014), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 3, 0x00000021), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 4, 0x00000000), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000), + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), @@ -4746,6 +4755,7 @@ break; case INTEL_FAM6_ATOM_TREMONT_D: + case INTEL_FAM6_ATOM_TREMONT: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, glp_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -5056,7 +5066,7 @@ extra_skl_attr = skl_format_attr; mem_attr = icl_events_attrs; tsx_attr = icl_tsx_events_attrs; - x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xca, .umask=0x02); + x86_pmu.rtm_abort_event = X86_CONFIG(.event=0xc9, .umask=0x04); x86_pmu.lbr_pt_coexist = true; intel_pmu_pebs_data_source_skl(pmem); pr_cont("Icelake events, "); --- linux-oracle-5.4.0.orig/arch/x86/events/intel/cstate.c +++ linux-oracle-5.4.0/arch/x86/events/intel/cstate.c @@ -40,17 +40,18 @@ * Model specific counters: * MSR_CORE_C1_RES: CORE C1 Residency Counter * perf code: 0x00 - * Available model: SLM,AMT,GLM,CNL + * Available model: SLM,AMT,GLM,CNL,TNT * Scope: Core (each processor core has a MSR) * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter * perf code: 0x01 * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM, - * CNL,KBL,CML + * CNL,KBL,CML,TNT * Scope: Core * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter * perf code: 0x02 * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, - * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL + * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, + * TNT * Scope: Core * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter * perf code: 0x03 @@ -60,17 +61,18 @@ * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. * perf code: 0x00 * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL, - * KBL,CML,ICL,TGL + * KBL,CML,ICL,TGL,TNT * Scope: Package (physical package) * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. * perf code: 0x01 * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, - * GLM,CNL,KBL,CML,ICL,TGL + * GLM,CNL,KBL,CML,ICL,TGL,TNT * Scope: Package (physical package) * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. * perf code: 0x02 - * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW - * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL + * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, + * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL, + * TNT * Scope: Package (physical package) * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. * perf code: 0x03 @@ -87,7 +89,8 @@ * Scope: Package (physical package) * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter. * perf code: 0x06 - * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL + * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL, + * TNT * Scope: Package (physical package) * */ @@ -104,14 +107,14 @@ MODULE_LICENSE("GPL"); #define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \ -static ssize_t __cstate_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ +static ssize_t __cstate_##_var##_show(struct device *dev, \ + struct device_attribute *attr, \ char *page) \ { \ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ return sprintf(page, _format "\n"); \ } \ -static struct kobj_attribute format_attr_##_var = \ +static struct device_attribute format_attr_##_var = \ __ATTR(_name, 0444, __cstate_##_var##_show, NULL) static ssize_t cstate_get_attr_cpumask(struct device *dev, @@ -640,8 +643,9 @@ X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_D, glm_cstates), - X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT_D, glm_cstates), + X86_CSTATES_MODEL(INTEL_FAM6_ATOM_TREMONT, glm_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, icl_cstates), X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, icl_cstates), --- linux-oracle-5.4.0.orig/arch/x86/events/intel/ds.c +++ linux-oracle-5.4.0/arch/x86/events/intel/ds.c @@ -669,9 +669,7 @@ static inline void intel_pmu_drain_pebs_buffer(void) { - struct pt_regs regs; - - x86_pmu.drain_pebs(®s); + x86_pmu.drain_pebs(NULL); } /* @@ -854,8 +852,13 @@ INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */ INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), /* MEM_INST_RETIRED.LOAD */ - INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), /* MEM_INST_RETIRED.STORE */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */ INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */ @@ -1713,6 +1716,8 @@ old = ((s64)(prev_raw_count << shift) >> shift); local64_add(new - old + count * period, &event->count); + local64_set(&hwc->period_left, -new); + perf_event_update_userpage(event); return 0; @@ -1734,6 +1739,7 @@ struct x86_perf_regs perf_regs; struct pt_regs *regs = &perf_regs.regs; void *at = get_next_pebs_record_by_bit(base, top, bit); + struct pt_regs dummy_iregs; if (hwc->flags & PERF_X86_EVENT_AUTO_RELOAD) { /* @@ -1746,6 +1752,9 @@ } else if (!intel_pmu_save_and_restart(event)) return; + if (!iregs) + iregs = &dummy_iregs; + while (count > 1) { setup_sample(event, iregs, at, &data, regs); perf_event_output(event, &data, regs); @@ -1755,16 +1764,22 @@ } setup_sample(event, iregs, at, &data, regs); - - /* - * All but the last records are processed. - * The last one is left to be able to call the overflow handler. - */ - if (perf_event_overflow(event, &data, regs)) { - x86_pmu_stop(event, 0); - return; + if (iregs == &dummy_iregs) { + /* + * The PEBS records may be drained in the non-overflow context, + * e.g., large PEBS + context switch. Perf should treat the + * last record the same as other PEBS records, and doesn't + * invoke the generic overflow handler. + */ + perf_event_output(event, &data, regs); + } else { + /* + * All but the last records are processed. + * The last one is left to be able to call the overflow handler. + */ + if (perf_event_overflow(event, &data, regs)) + x86_pmu_stop(event, 0); } - } static void intel_pmu_drain_pebs_core(struct pt_regs *iregs) @@ -1880,7 +1895,7 @@ */ if (!pebs_status && cpuc->pebs_enabled && !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1))) - pebs_status = cpuc->pebs_enabled; + pebs_status = p->status = cpuc->pebs_enabled; bit = find_first_bit((unsigned long *)&pebs_status, x86_pmu.max_pebs_events); @@ -1902,7 +1917,7 @@ * that caused the PEBS record. It's called collision. * If collision happened, the record will be dropped. */ - if (p->status != (1ULL << bit)) { + if (pebs_status != (1ULL << bit)) { for_each_set_bit(i, (unsigned long *)&pebs_status, size) error[i]++; continue; --- linux-oracle-5.4.0.orig/arch/x86/events/intel/pt.c +++ linux-oracle-5.4.0/arch/x86/events/intel/pt.c @@ -62,7 +62,7 @@ PT_CAP(single_range_output, 0, CPUID_ECX, BIT(2)), PT_CAP(output_subsys, 0, CPUID_ECX, BIT(3)), PT_CAP(payloads_lip, 0, CPUID_ECX, BIT(31)), - PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x3), + PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x7), PT_CAP(mtc_periods, 1, CPUID_EAX, 0xffff0000), PT_CAP(cycle_thresholds, 1, CPUID_EBX, 0xffff), PT_CAP(psb_periods, 1, CPUID_EBX, 0xffff0000), @@ -460,7 +460,7 @@ pt->filters.filter[range].msr_b = filter->msr_b; } - rtit_ctl |= filter->config << pt_address_ranges[range].reg_off; + rtit_ctl |= (u64)filter->config << pt_address_ranges[range].reg_off; } return rtit_ctl; @@ -782,11 +782,13 @@ buf->cur_idx++; if (buf->cur_idx == buf->cur->last) { - if (buf->cur == buf->last) + if (buf->cur == buf->last) { buf->cur = buf->first; - else + buf->wrapped = true; + } else { buf->cur = list_entry(buf->cur->list.next, struct topa, list); + } buf->cur_idx = 0; } } @@ -800,8 +802,11 @@ static void pt_update_head(struct pt *pt) { struct pt_buffer *buf = perf_get_aux(&pt->handle); + bool wrapped = buf->wrapped; u64 topa_idx, base, old; + buf->wrapped = false; + /* offset of the first region in this table from the beginning of buf */ base = buf->cur->offset + buf->output_off; @@ -814,7 +819,7 @@ } else { old = (local64_xchg(&buf->head, base) & ((buf->nr_pages << PAGE_SHIFT) - 1)); - if (base < old) + if (base < old || (base == old && wrapped)) base += buf->nr_pages << PAGE_SHIFT; local_add(base - old, &buf->data_size); @@ -827,7 +832,7 @@ */ static void *pt_buffer_region(struct pt_buffer *buf) { - return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT); + return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT); } /** @@ -935,7 +940,7 @@ * order allocations, there shouldn't be many of these. */ list_for_each_entry(topa, &buf->tables, list) { - if (topa->offset + topa->size > pg << PAGE_SHIFT) + if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT) goto found; } --- linux-oracle-5.4.0.orig/arch/x86/events/intel/pt.h +++ linux-oracle-5.4.0/arch/x86/events/intel/pt.h @@ -33,8 +33,8 @@ u64 rsvd2 : 1; u64 size : 4; u64 rsvd3 : 2; - u64 base : 36; - u64 rsvd4 : 16; + u64 base : 40; + u64 rsvd4 : 12; }; /* TSC to Core Crystal Clock Ratio */ @@ -64,6 +64,7 @@ * @lost: if data was lost/truncated * @head: logical write offset inside the buffer * @snapshot: if this is for a snapshot/overwrite counter + * @wrapped: buffer advance wrapped back to the first topa table * @stop_pos: STOP topa entry index * @intr_pos: INT topa entry index * @stop_te: STOP topa entry pointer @@ -80,6 +81,7 @@ local_t data_size; local64_t head; bool snapshot; + bool wrapped; long stop_pos, intr_pos; struct topa_entry *stop_te, *intr_te; void **data_pages; --- linux-oracle-5.4.0.orig/arch/x86/events/intel/uncore.c +++ linux-oracle-5.4.0/arch/x86/events/intel/uncore.c @@ -92,8 +92,8 @@ return map; } -ssize_t uncore_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) +ssize_t uncore_event_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct uncore_event_desc *event = container_of(attr, struct uncore_event_desc, attr); --- linux-oracle-5.4.0.orig/arch/x86/events/intel/uncore.h +++ linux-oracle-5.4.0/arch/x86/events/intel/uncore.h @@ -144,7 +144,7 @@ #define UNCORE_BOX_FLAG_CFL8_CBOX_MSR_OFFS 2 struct uncore_event_desc { - struct kobj_attribute attr; + struct device_attribute attr; const char *config; }; @@ -165,8 +165,8 @@ struct pci2phy_map *__find_pci2phy_map(int segment); int uncore_pcibus_to_physid(struct pci_bus *bus); -ssize_t uncore_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf); +ssize_t uncore_event_show(struct device *dev, + struct device_attribute *attr, char *buf); #define INTEL_UNCORE_EVENT_DESC(_name, _config) \ { \ @@ -175,14 +175,14 @@ } #define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \ -static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ - struct kobj_attribute *attr, \ +static ssize_t __uncore_##_var##_show(struct device *dev, \ + struct device_attribute *attr, \ char *page) \ { \ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \ return sprintf(page, _format "\n"); \ } \ -static struct kobj_attribute format_attr_##_var = \ +static struct device_attribute format_attr_##_var = \ __ATTR(_name, 0444, __uncore_##_var##_show, NULL) static inline bool uncore_pmc_fixed(int idx) --- linux-oracle-5.4.0.orig/arch/x86/events/intel/uncore_snb.c +++ linux-oracle-5.4.0/arch/x86/events/intel/uncore_snb.c @@ -15,6 +15,7 @@ #define PCI_DEVICE_ID_INTEL_SKL_HQ_IMC 0x1910 #define PCI_DEVICE_ID_INTEL_SKL_SD_IMC 0x190f #define PCI_DEVICE_ID_INTEL_SKL_SQ_IMC 0x191f +#define PCI_DEVICE_ID_INTEL_SKL_E3_IMC 0x1918 #define PCI_DEVICE_ID_INTEL_KBL_Y_IMC 0x590c #define PCI_DEVICE_ID_INTEL_KBL_U_IMC 0x5904 #define PCI_DEVICE_ID_INTEL_KBL_UQ_IMC 0x5914 @@ -109,6 +110,10 @@ #define ICL_UNC_CBO_0_PER_CTR0 0x702 #define ICL_UNC_CBO_MSR_OFFSET 0x8 +/* ICL ARB register */ +#define ICL_UNC_ARB_PER_CTR 0x3b1 +#define ICL_UNC_ARB_PERFEVTSEL 0x3b3 + DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); @@ -296,15 +301,21 @@ snb_uncore_arb.ops = &skl_uncore_msr_ops; } +static struct intel_uncore_ops icl_uncore_msr_ops = { + .disable_event = snb_uncore_msr_disable_event, + .enable_event = snb_uncore_msr_enable_event, + .read_counter = uncore_msr_read_counter, +}; + static struct intel_uncore_type icl_uncore_cbox = { .name = "cbox", - .num_counters = 4, + .num_counters = 2, .perf_ctr_bits = 44, .perf_ctr = ICL_UNC_CBO_0_PER_CTR0, .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, .event_mask = SNB_UNC_RAW_EVENT_MASK, .msr_offset = ICL_UNC_CBO_MSR_OFFSET, - .ops = &skl_uncore_msr_ops, + .ops = &icl_uncore_msr_ops, .format_group = &snb_uncore_format_group, }; @@ -333,13 +344,25 @@ .single_fixed = 1, .event_mask = SNB_UNC_CTL_EV_SEL_MASK, .format_group = &icl_uncore_clock_format_group, - .ops = &skl_uncore_msr_ops, + .ops = &icl_uncore_msr_ops, .event_descs = icl_uncore_events, }; +static struct intel_uncore_type icl_uncore_arb = { + .name = "arb", + .num_counters = 1, + .num_boxes = 1, + .perf_ctr_bits = 44, + .perf_ctr = ICL_UNC_ARB_PER_CTR, + .event_ctl = ICL_UNC_ARB_PERFEVTSEL, + .event_mask = SNB_UNC_RAW_EVENT_MASK, + .ops = &icl_uncore_msr_ops, + .format_group = &snb_uncore_format_group, +}; + static struct intel_uncore_type *icl_msr_uncores[] = { &icl_uncore_cbox, - &snb_uncore_arb, + &icl_uncore_arb, &icl_uncore_clockbox, NULL, }; @@ -357,7 +380,6 @@ { uncore_msr_uncores = icl_msr_uncores; icl_uncore_cbox.num_boxes = icl_get_cbox_num(); - snb_uncore_arb.ops = &skl_uncore_msr_ops; } enum { @@ -553,6 +575,22 @@ return 0; } +static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + /* + * SNB IMC counters are 32-bit and are laid out back to back + * in MMIO space. Therefore we must use a 32-bit accessor function + * using readq() from uncore_mmio_read_counter() causes problems + * because it is reading 64-bit at a time. This is okay for the + * uncore_perf_event_update() function because it drops the upper + * 32-bits but not okay for plain uncore_read_counter() as invoked + * in uncore_pmu_event_start(). + */ + return (u64)readl(box->io_addr + hwc->event_base); +} + static struct pmu snb_uncore_imc_pmu = { .task_ctx_nr = perf_invalid_context, .event_init = snb_uncore_imc_event_init, @@ -572,7 +610,7 @@ .disable_event = snb_uncore_imc_disable_event, .enable_event = snb_uncore_imc_enable_event, .hw_config = snb_uncore_imc_hw_config, - .read_counter = uncore_mmio_read_counter, + .read_counter = snb_uncore_imc_read_counter, }; static struct intel_uncore_type snb_uncore_imc = { @@ -658,6 +696,10 @@ .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SKL_E3_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* IMC */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBL_Y_IMC), .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), }, @@ -826,6 +868,7 @@ IMC_DEV(SKL_HQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core H Quad Core */ IMC_DEV(SKL_SD_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Dual Core */ IMC_DEV(SKL_SQ_IMC, &skl_uncore_pci_driver), /* 6th Gen Core S Quad Core */ + IMC_DEV(SKL_E3_IMC, &skl_uncore_pci_driver), /* Xeon E3 V5 Gen Core processor */ IMC_DEV(KBL_Y_IMC, &skl_uncore_pci_driver), /* 7th Gen Core Y */ IMC_DEV(KBL_U_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U */ IMC_DEV(KBL_UQ_IMC, &skl_uncore_pci_driver), /* 7th Gen Core U Quad Core */ --- linux-oracle-5.4.0.orig/arch/x86/events/intel/uncore_snbep.c +++ linux-oracle-5.4.0/arch/x86/events/intel/uncore_snbep.c @@ -369,11 +369,6 @@ #define SNR_M2M_PCI_PMON_BOX_CTL 0x438 #define SNR_M2M_PCI_PMON_UMASK_EXT 0xff -/* SNR PCIE3 */ -#define SNR_PCIE3_PCI_PMON_CTL0 0x508 -#define SNR_PCIE3_PCI_PMON_CTR0 0x4e8 -#define SNR_PCIE3_PCI_PMON_BOX_CTL 0x4e4 - /* SNR IMC */ #define SNR_IMC_MMIO_PMON_FIXED_CTL 0x54 #define SNR_IMC_MMIO_PMON_FIXED_CTR 0x38 @@ -1098,7 +1093,6 @@ SNBEP_PCI_QPI_PORT0_FILTER, SNBEP_PCI_QPI_PORT1_FILTER, BDX_PCI_QPI_PORT2_FILTER, - HSWEP_PCI_PCU_3, }; static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) @@ -2755,22 +2749,34 @@ NULL, }; -void hswep_uncore_cpu_init(void) +#define HSWEP_PCU_DID 0x2fc0 +#define HSWEP_PCU_CAPID4_OFFET 0x94 +#define hswep_get_chop(_cap) (((_cap) >> 6) & 0x3) + +static bool hswep_has_limit_sbox(unsigned int device) { - int pkg = boot_cpu_data.logical_proc_id; + struct pci_dev *dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL); + u32 capid4; + + if (!dev) + return false; + + pci_read_config_dword(dev, HSWEP_PCU_CAPID4_OFFET, &capid4); + pci_dev_put(dev); + if (!hswep_get_chop(capid4)) + return true; + + return false; +} +void hswep_uncore_cpu_init(void) +{ if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; /* Detect 6-8 core systems with only two SBOXes */ - if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) { - u32 capid4; - - pci_read_config_dword(uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3], - 0x94, &capid4); - if (((capid4 >> 6) & 0x3) == 0) - hswep_uncore_sbox.num_boxes = 2; - } + if (hswep_has_limit_sbox(HSWEP_PCU_DID)) + hswep_uncore_sbox.num_boxes = 2; uncore_msr_uncores = hswep_msr_uncores; } @@ -3033,11 +3039,6 @@ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, SNBEP_PCI_QPI_PORT1_FILTER), }, - { /* PCU.3 (for Capability registers) */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2fc0), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - HSWEP_PCI_PCU_3), - }, { /* end: all zeroes */ } }; @@ -3129,27 +3130,18 @@ EVENT_CONSTRAINT_END }; +#define BDX_PCU_DID 0x6fc0 + void bdx_uncore_cpu_init(void) { - int pkg = topology_phys_to_logical_pkg(boot_cpu_data.phys_proc_id); - if (bdx_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) bdx_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; uncore_msr_uncores = bdx_msr_uncores; - /* BDX-DE doesn't have SBOX */ - if (boot_cpu_data.x86_model == 86) { - uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; /* Detect systems with no SBOXes */ - } else if (uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]) { - struct pci_dev *pdev; - u32 capid4; - - pdev = uncore_extra_pci_dev[pkg].dev[HSWEP_PCI_PCU_3]; - pci_read_config_dword(pdev, 0x94, &capid4); - if (((capid4 >> 6) & 0x3) == 0) - bdx_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; - } + if ((boot_cpu_data.x86_model == 86) || hswep_has_limit_sbox(BDX_PCU_DID)) + uncore_msr_uncores[BDX_MSR_UNCORE_SBOX] = NULL; + hswep_uncore_pcu.constraints = bdx_uncore_pcu_constraints; } @@ -3370,11 +3362,6 @@ .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, BDX_PCI_QPI_PORT2_FILTER), }, - { /* PCU.3 (for Capability registers) */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x6fc0), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - HSWEP_PCI_PCU_3), - }, { /* end: all zeroes */ } }; @@ -3493,6 +3480,9 @@ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; struct extra_reg *er; int idx = 0; + /* Any of the CHA events may be filtered by Thread/Core-ID.*/ + if (event->hw.config & SNBEP_CBO_PMON_CTL_TID_EN) + idx = SKX_CHA_MSR_PMON_BOX_FILTER_TID; for (er = skx_uncore_cha_extra_regs; er->msr; er++) { if (er->event != (event->hw.config & er->config_mask)) @@ -3560,6 +3550,7 @@ UNCORE_EVENT_CONSTRAINT(0xc0, 0xc), UNCORE_EVENT_CONSTRAINT(0xc5, 0xc), UNCORE_EVENT_CONSTRAINT(0xd4, 0xc), + UNCORE_EVENT_CONSTRAINT(0xd5, 0xc), EVENT_CONSTRAINT_END }; @@ -4328,27 +4319,12 @@ .format_group = &snr_m2m_uncore_format_group, }; -static struct intel_uncore_type snr_uncore_pcie3 = { - .name = "pcie3", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .perf_ctr = SNR_PCIE3_PCI_PMON_CTR0, - .event_ctl = SNR_PCIE3_PCI_PMON_CTL0, - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, - .box_ctl = SNR_PCIE3_PCI_PMON_BOX_CTL, - .ops = &ivbep_uncore_pci_ops, - .format_group = &ivbep_uncore_format_group, -}; - enum { SNR_PCI_UNCORE_M2M, - SNR_PCI_UNCORE_PCIE3, }; static struct intel_uncore_type *snr_pci_uncores[] = { [SNR_PCI_UNCORE_M2M] = &snr_uncore_m2m, - [SNR_PCI_UNCORE_PCIE3] = &snr_uncore_pcie3, NULL, }; @@ -4357,10 +4333,6 @@ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x344a), .driver_data = UNCORE_PCI_DEV_FULL_DATA(12, 0, SNR_PCI_UNCORE_M2M, 0), }, - { /* PCIe3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x334a), - .driver_data = UNCORE_PCI_DEV_FULL_DATA(4, 0, SNR_PCI_UNCORE_PCIE3, 0), - }, { /* end: all zeroes */ } }; @@ -4415,7 +4387,7 @@ return; pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword); - addr = (pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; + addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; pci_read_config_dword(pdev, SNR_IMC_MMIO_MEM0_OFFSET, &pci_dword); addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12; @@ -4536,6 +4508,7 @@ INTEL_UNCORE_EVENT_DESC(write, "event=0xff,umask=0x21"), INTEL_UNCORE_EVENT_DESC(write.scale, "3.814697266e-6"), INTEL_UNCORE_EVENT_DESC(write.unit, "MiB"), + { /* end: all zeroes */ }, }; static struct intel_uncore_ops snr_uncore_imc_freerunning_ops = { --- linux-oracle-5.4.0.orig/arch/x86/events/msr.c +++ linux-oracle-5.4.0/arch/x86/events/msr.c @@ -75,8 +75,9 @@ case INTEL_FAM6_ATOM_GOLDMONT: case INTEL_FAM6_ATOM_GOLDMONT_D: - case INTEL_FAM6_ATOM_GOLDMONT_PLUS: + case INTEL_FAM6_ATOM_TREMONT_D: + case INTEL_FAM6_ATOM_TREMONT: case INTEL_FAM6_XEON_PHI_KNL: case INTEL_FAM6_XEON_PHI_KNM: --- linux-oracle-5.4.0.orig/arch/x86/events/perf_event.h +++ linux-oracle-5.4.0/arch/x86/events/perf_event.h @@ -77,6 +77,7 @@ #define PERF_X86_EVENT_AUTO_RELOAD 0x0200 /* use PEBS auto-reload */ #define PERF_X86_EVENT_LARGE_PEBS 0x0400 /* use large PEBS */ #define PERF_X86_EVENT_PEBS_VIA_PT 0x0800 /* use PT buffer for PEBS */ +#define PERF_X86_EVENT_PAIR 0x1000 /* Large Increment per Cycle */ struct amd_nb { int nb_id; /* NorthBridge id */ @@ -272,6 +273,7 @@ struct amd_nb *amd_nb; /* Inverted mask of bits to clear in the perf_ctr ctrl registers */ u64 perf_ctr_virt_mask; + int n_pair; /* Large increment events */ void *kfree_on_online[X86_PERF_KFREE_MAX]; }; @@ -686,6 +688,7 @@ * AMD bits */ unsigned int amd_nb_constraints : 1; + u64 perf_ctr_pair_en; /* * Extra registers for events @@ -735,6 +738,7 @@ #define PMU_FL_EXCL_ENABLED 0x8 /* exclusive counter active */ #define PMU_FL_PEBS_ALL 0x10 /* all events are valid PEBS events */ #define PMU_FL_TFA 0x20 /* deal with TSX force abort */ +#define PMU_FL_PAIR 0x40 /* merge counters for large incr. events */ #define EVENT_VAR(_id) event_attr_##_id #define EVENT_PTR(_id) &event_attr_##_id.attr.attr @@ -830,6 +834,11 @@ void x86_pmu_disable_all(void); +static inline bool is_counter_pair(struct hw_perf_event *hwc) +{ + return hwc->flags & PERF_X86_EVENT_PAIR; +} + static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc, u64 enable_mask) { @@ -837,6 +846,14 @@ if (hwc->extra_reg.reg) wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config); + + /* + * Add enabled Merge event on next counter + * if large increment event being enabled on this counter + */ + if (is_counter_pair(hwc)) + wrmsrl(x86_pmu_config_addr(hwc->idx + 1), x86_pmu.perf_ctr_pair_en); + wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask); } @@ -850,9 +867,13 @@ static inline void x86_pmu_disable_event(struct perf_event *event) { + u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask); struct hw_perf_event *hwc = &event->hw; - wrmsrl(hwc->config_base, hwc->config); + wrmsrl(hwc->config_base, hwc->config & ~disable_mask); + + if (is_counter_pair(hwc)) + wrmsrl(x86_pmu_config_addr(hwc->idx + 1), 0); } void x86_pmu_enable_event(struct perf_event *event); --- linux-oracle-5.4.0.orig/arch/x86/events/rapl.c +++ linux-oracle-5.4.0/arch/x86/events/rapl.c @@ -0,0 +1,793 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Support Intel/AMD RAPL energy consumption counters + * Copyright (C) 2013 Google, Inc., Stephane Eranian + * + * Intel RAPL interface is specified in the IA-32 Manual Vol3b + * section 14.7.1 (September 2013) + * + * AMD RAPL interface for Fam17h is described in the public PPR: + * https://bugzilla.kernel.org/show_bug.cgi?id=206537 + * + * RAPL provides more controls than just reporting energy consumption + * however here we only expose the 3 energy consumption free running + * counters (pp0, pkg, dram). + * + * Each of those counters increments in a power unit defined by the + * RAPL_POWER_UNIT MSR. On SandyBridge, this unit is 1/(2^16) Joules + * but it can vary. + * + * Counter to rapl events mappings: + * + * pp0 counter: consumption of all physical cores (power plane 0) + * event: rapl_energy_cores + * perf code: 0x1 + * + * pkg counter: consumption of the whole processor package + * event: rapl_energy_pkg + * perf code: 0x2 + * + * dram counter: consumption of the dram domain (servers only) + * event: rapl_energy_dram + * perf code: 0x3 + * + * gpu counter: consumption of the builtin-gpu domain (client only) + * event: rapl_energy_gpu + * perf code: 0x4 + * + * psys counter: consumption of the builtin-psys domain (client only) + * event: rapl_energy_psys + * perf code: 0x5 + * + * We manage those counters as free running (read-only). They may be + * use simultaneously by other tools, such as turbostat. + * + * The events only support system-wide mode counting. There is no + * sampling support because it does not make sense and is not + * supported by the RAPL hardware. + * + * Because we want to avoid floating-point operations in the kernel, + * the events are all reported in fixed point arithmetic (32.32). + * Tools must adjust the counts to convert them to Watts using + * the duration of the measurement. Tools may use a function such as + * ldexp(raw_count, -32); + */ + +#define pr_fmt(fmt) "RAPL PMU: " fmt + +#include +#include +#include +#include +#include +#include +#include "perf_event.h" +#include "probe.h" + +MODULE_LICENSE("GPL"); + +/* + * RAPL energy status counters + */ +enum perf_rapl_events { + PERF_RAPL_PP0 = 0, /* all cores */ + PERF_RAPL_PKG, /* entire package */ + PERF_RAPL_RAM, /* DRAM */ + PERF_RAPL_PP1, /* gpu */ + PERF_RAPL_PSYS, /* psys */ + + PERF_RAPL_MAX, + NR_RAPL_DOMAINS = PERF_RAPL_MAX, +}; + +static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = { + "pp0-core", + "package", + "dram", + "pp1-gpu", + "psys", +}; + +/* + * event code: LSB 8 bits, passed in attr->config + * any other bit is reserved + */ +#define RAPL_EVENT_MASK 0xFFULL +#define RAPL_CNTR_WIDTH 32 + +#define RAPL_EVENT_ATTR_STR(_name, v, str) \ +static struct perf_pmu_events_attr event_attr_##v = { \ + .attr = __ATTR(_name, 0444, perf_event_sysfs_show, NULL), \ + .id = 0, \ + .event_str = str, \ +}; + +struct rapl_pmu { + raw_spinlock_t lock; + int n_active; + int cpu; + struct list_head active_list; + struct pmu *pmu; + ktime_t timer_interval; + struct hrtimer hrtimer; +}; + +struct rapl_pmus { + struct pmu pmu; + unsigned int maxdie; + struct rapl_pmu *pmus[]; +}; + +struct rapl_model { + unsigned long events; + bool apply_quirk; +}; + + /* 1/2^hw_unit Joule */ +static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly; +static struct rapl_pmus *rapl_pmus; +static cpumask_t rapl_cpu_mask; +static unsigned int rapl_cntr_mask; +static u64 rapl_timer_ms; +static struct perf_msr rapl_msrs[]; + +static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu) +{ + unsigned int dieid = topology_logical_die_id(cpu); + + /* + * The unsigned check also catches the '-1' return value for non + * existent mappings in the topology map. + */ + return dieid < rapl_pmus->maxdie ? rapl_pmus->pmus[dieid] : NULL; +} + +static inline u64 rapl_read_counter(struct perf_event *event) +{ + u64 raw; + rdmsrl(event->hw.event_base, raw); + return raw; +} + +static inline u64 rapl_scale(u64 v, int cfg) +{ + if (cfg > NR_RAPL_DOMAINS) { + pr_warn("Invalid domain %d, failed to scale data\n", cfg); + return v; + } + /* + * scale delta to smallest unit (1/2^32) + * users must then scale back: count * 1/(1e9*2^32) to get Joules + * or use ldexp(count, -32). + * Watts = Joules/Time delta + */ + return v << (32 - rapl_hw_unit[cfg - 1]); +} + +static u64 rapl_event_update(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + u64 prev_raw_count, new_raw_count; + s64 delta, sdelta; + int shift = RAPL_CNTR_WIDTH; + +again: + prev_raw_count = local64_read(&hwc->prev_count); + rdmsrl(event->hw.event_base, new_raw_count); + + if (local64_cmpxchg(&hwc->prev_count, prev_raw_count, + new_raw_count) != prev_raw_count) { + cpu_relax(); + goto again; + } + + /* + * Now we have the new raw value and have updated the prev + * timestamp already. We can now calculate the elapsed delta + * (event-)time and add that to the generic event. + * + * Careful, not all hw sign-extends above the physical width + * of the count. + */ + delta = (new_raw_count << shift) - (prev_raw_count << shift); + delta >>= shift; + + sdelta = rapl_scale(delta, event->hw.config); + + local64_add(sdelta, &event->count); + + return new_raw_count; +} + +static void rapl_start_hrtimer(struct rapl_pmu *pmu) +{ + hrtimer_start(&pmu->hrtimer, pmu->timer_interval, + HRTIMER_MODE_REL_PINNED); +} + +static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer) +{ + struct rapl_pmu *pmu = container_of(hrtimer, struct rapl_pmu, hrtimer); + struct perf_event *event; + unsigned long flags; + + if (!pmu->n_active) + return HRTIMER_NORESTART; + + raw_spin_lock_irqsave(&pmu->lock, flags); + + list_for_each_entry(event, &pmu->active_list, active_entry) + rapl_event_update(event); + + raw_spin_unlock_irqrestore(&pmu->lock, flags); + + hrtimer_forward_now(hrtimer, pmu->timer_interval); + + return HRTIMER_RESTART; +} + +static void rapl_hrtimer_init(struct rapl_pmu *pmu) +{ + struct hrtimer *hr = &pmu->hrtimer; + + hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hr->function = rapl_hrtimer_handle; +} + +static void __rapl_pmu_event_start(struct rapl_pmu *pmu, + struct perf_event *event) +{ + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + + event->hw.state = 0; + + list_add_tail(&event->active_entry, &pmu->active_list); + + local64_set(&event->hw.prev_count, rapl_read_counter(event)); + + pmu->n_active++; + if (pmu->n_active == 1) + rapl_start_hrtimer(pmu); +} + +static void rapl_pmu_event_start(struct perf_event *event, int mode) +{ + struct rapl_pmu *pmu = event->pmu_private; + unsigned long flags; + + raw_spin_lock_irqsave(&pmu->lock, flags); + __rapl_pmu_event_start(pmu, event); + raw_spin_unlock_irqrestore(&pmu->lock, flags); +} + +static void rapl_pmu_event_stop(struct perf_event *event, int mode) +{ + struct rapl_pmu *pmu = event->pmu_private; + struct hw_perf_event *hwc = &event->hw; + unsigned long flags; + + raw_spin_lock_irqsave(&pmu->lock, flags); + + /* mark event as deactivated and stopped */ + if (!(hwc->state & PERF_HES_STOPPED)) { + WARN_ON_ONCE(pmu->n_active <= 0); + pmu->n_active--; + if (pmu->n_active == 0) + hrtimer_cancel(&pmu->hrtimer); + + list_del(&event->active_entry); + + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + } + + /* check if update of sw counter is necessary */ + if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { + /* + * Drain the remaining delta count out of a event + * that we are disabling: + */ + rapl_event_update(event); + hwc->state |= PERF_HES_UPTODATE; + } + + raw_spin_unlock_irqrestore(&pmu->lock, flags); +} + +static int rapl_pmu_event_add(struct perf_event *event, int mode) +{ + struct rapl_pmu *pmu = event->pmu_private; + struct hw_perf_event *hwc = &event->hw; + unsigned long flags; + + raw_spin_lock_irqsave(&pmu->lock, flags); + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + + if (mode & PERF_EF_START) + __rapl_pmu_event_start(pmu, event); + + raw_spin_unlock_irqrestore(&pmu->lock, flags); + + return 0; +} + +static void rapl_pmu_event_del(struct perf_event *event, int flags) +{ + rapl_pmu_event_stop(event, PERF_EF_UPDATE); +} + +static int rapl_pmu_event_init(struct perf_event *event) +{ + u64 cfg = event->attr.config & RAPL_EVENT_MASK; + int bit, ret = 0; + struct rapl_pmu *pmu; + + /* only look at RAPL events */ + if (event->attr.type != rapl_pmus->pmu.type) + return -ENOENT; + + /* check only supported bits are set */ + if (event->attr.config & ~RAPL_EVENT_MASK) + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG; + + if (!cfg || cfg >= NR_RAPL_DOMAINS + 1) + return -EINVAL; + + cfg = array_index_nospec((long)cfg, NR_RAPL_DOMAINS + 1); + bit = cfg - 1; + + /* check event supported */ + if (!(rapl_cntr_mask & (1 << bit))) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.sample_period) /* no sampling */ + return -EINVAL; + + /* must be done before validate_group */ + pmu = cpu_to_rapl_pmu(event->cpu); + if (!pmu) + return -EINVAL; + event->cpu = pmu->cpu; + event->pmu_private = pmu; + event->hw.event_base = rapl_msrs[bit].msr; + event->hw.config = cfg; + event->hw.idx = bit; + + return ret; +} + +static void rapl_pmu_event_read(struct perf_event *event) +{ + rapl_event_update(event); +} + +static ssize_t rapl_get_attr_cpumask(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL); + +static struct attribute *rapl_pmu_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group rapl_pmu_attr_group = { + .attrs = rapl_pmu_attrs, +}; + +RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); +RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); +RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); +RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); +RAPL_EVENT_ATTR_STR(energy-psys, rapl_psys, "event=0x05"); + +RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); +RAPL_EVENT_ATTR_STR(energy-psys.unit, rapl_psys_unit, "Joules"); + +/* + * we compute in 0.23 nJ increments regardless of MSR + */ +RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); +RAPL_EVENT_ATTR_STR(energy-psys.scale, rapl_psys_scale, "2.3283064365386962890625e-10"); + +/* + * There are no default events, but we need to create + * "events" group (with empty attrs) before updating + * it with detected events. + */ +static struct attribute *attrs_empty[] = { + NULL, +}; + +static struct attribute_group rapl_pmu_events_group = { + .name = "events", + .attrs = attrs_empty, +}; + +PMU_FORMAT_ATTR(event, "config:0-7"); +static struct attribute *rapl_formats_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group rapl_pmu_format_group = { + .name = "format", + .attrs = rapl_formats_attr, +}; + +static const struct attribute_group *rapl_attr_groups[] = { + &rapl_pmu_attr_group, + &rapl_pmu_format_group, + &rapl_pmu_events_group, + NULL, +}; + +static struct attribute *rapl_events_cores[] = { + EVENT_PTR(rapl_cores), + EVENT_PTR(rapl_cores_unit), + EVENT_PTR(rapl_cores_scale), + NULL, +}; + +static struct attribute_group rapl_events_cores_group = { + .name = "events", + .attrs = rapl_events_cores, +}; + +static struct attribute *rapl_events_pkg[] = { + EVENT_PTR(rapl_pkg), + EVENT_PTR(rapl_pkg_unit), + EVENT_PTR(rapl_pkg_scale), + NULL, +}; + +static struct attribute_group rapl_events_pkg_group = { + .name = "events", + .attrs = rapl_events_pkg, +}; + +static struct attribute *rapl_events_ram[] = { + EVENT_PTR(rapl_ram), + EVENT_PTR(rapl_ram_unit), + EVENT_PTR(rapl_ram_scale), + NULL, +}; + +static struct attribute_group rapl_events_ram_group = { + .name = "events", + .attrs = rapl_events_ram, +}; + +static struct attribute *rapl_events_gpu[] = { + EVENT_PTR(rapl_gpu), + EVENT_PTR(rapl_gpu_unit), + EVENT_PTR(rapl_gpu_scale), + NULL, +}; + +static struct attribute_group rapl_events_gpu_group = { + .name = "events", + .attrs = rapl_events_gpu, +}; + +static struct attribute *rapl_events_psys[] = { + EVENT_PTR(rapl_psys), + EVENT_PTR(rapl_psys_unit), + EVENT_PTR(rapl_psys_scale), + NULL, +}; + +static struct attribute_group rapl_events_psys_group = { + .name = "events", + .attrs = rapl_events_psys, +}; + +static bool test_msr(int idx, void *data) +{ + return test_bit(idx, (unsigned long *) data); +} + +static struct perf_msr rapl_msrs[] = { + [PERF_RAPL_PP0] = { MSR_PP0_ENERGY_STATUS, &rapl_events_cores_group, test_msr }, + [PERF_RAPL_PKG] = { MSR_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr }, + [PERF_RAPL_RAM] = { MSR_DRAM_ENERGY_STATUS, &rapl_events_ram_group, test_msr }, + [PERF_RAPL_PP1] = { MSR_PP1_ENERGY_STATUS, &rapl_events_gpu_group, test_msr }, + [PERF_RAPL_PSYS] = { MSR_PLATFORM_ENERGY_STATUS, &rapl_events_psys_group, test_msr }, +}; + +static int rapl_cpu_offline(unsigned int cpu) +{ + struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); + int target; + + /* Check if exiting cpu is used for collecting rapl events */ + if (!cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask)) + return 0; + + pmu->cpu = -1; + /* Find a new cpu to collect rapl events */ + target = cpumask_any_but(topology_die_cpumask(cpu), cpu); + + /* Migrate rapl events to the new target */ + if (target < nr_cpu_ids) { + cpumask_set_cpu(target, &rapl_cpu_mask); + pmu->cpu = target; + perf_pmu_migrate_context(pmu->pmu, cpu, target); + } + return 0; +} + +static int rapl_cpu_online(unsigned int cpu) +{ + struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu); + int target; + + if (!pmu) { + pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); + if (!pmu) + return -ENOMEM; + + raw_spin_lock_init(&pmu->lock); + INIT_LIST_HEAD(&pmu->active_list); + pmu->pmu = &rapl_pmus->pmu; + pmu->timer_interval = ms_to_ktime(rapl_timer_ms); + rapl_hrtimer_init(pmu); + + rapl_pmus->pmus[topology_logical_die_id(cpu)] = pmu; + } + + /* + * Check if there is an online cpu in the package which collects rapl + * events already. + */ + target = cpumask_any_and(&rapl_cpu_mask, topology_die_cpumask(cpu)); + if (target < nr_cpu_ids) + return 0; + + cpumask_set_cpu(cpu, &rapl_cpu_mask); + pmu->cpu = cpu; + return 0; +} + +static int rapl_check_hw_unit(bool apply_quirk) +{ + u64 msr_rapl_power_unit_bits; + int i; + + /* protect rdmsrl() to handle virtualization */ + if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) + return -1; + for (i = 0; i < NR_RAPL_DOMAINS; i++) + rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL; + + /* + * DRAM domain on HSW server and KNL has fixed energy unit which can be + * different than the unit from power unit MSR. See + * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2 + * of 2. Datasheet, September 2014, Reference Number: 330784-001 " + */ + if (apply_quirk) + rapl_hw_unit[PERF_RAPL_RAM] = 16; + + /* + * Calculate the timer rate: + * Use reference of 200W for scaling the timeout to avoid counter + * overflows. 200W = 200 Joules/sec + * Divide interval by 2 to avoid lockstep (2 * 100) + * if hw unit is 32, then we use 2 ms 1/200/2 + */ + rapl_timer_ms = 2; + if (rapl_hw_unit[0] < 32) { + rapl_timer_ms = (1000 / (2 * 100)); + rapl_timer_ms *= (1ULL << (32 - rapl_hw_unit[0] - 1)); + } + return 0; +} + +static void __init rapl_advertise(void) +{ + int i; + + pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n", + hweight32(rapl_cntr_mask), rapl_timer_ms); + + for (i = 0; i < NR_RAPL_DOMAINS; i++) { + if (rapl_cntr_mask & (1 << i)) { + pr_info("hw unit of domain %s 2^-%d Joules\n", + rapl_domain_names[i], rapl_hw_unit[i]); + } + } +} + +static void cleanup_rapl_pmus(void) +{ + int i; + + for (i = 0; i < rapl_pmus->maxdie; i++) + kfree(rapl_pmus->pmus[i]); + kfree(rapl_pmus); +} + +static const struct attribute_group *rapl_attr_update[] = { + &rapl_events_cores_group, + &rapl_events_pkg_group, + &rapl_events_ram_group, + &rapl_events_gpu_group, + &rapl_events_psys_group, + NULL, +}; + +static int __init init_rapl_pmus(void) +{ + int maxdie = topology_max_packages() * topology_max_die_per_package(); + size_t size; + + size = sizeof(*rapl_pmus) + maxdie * sizeof(struct rapl_pmu *); + rapl_pmus = kzalloc(size, GFP_KERNEL); + if (!rapl_pmus) + return -ENOMEM; + + rapl_pmus->maxdie = maxdie; + rapl_pmus->pmu.attr_groups = rapl_attr_groups; + rapl_pmus->pmu.attr_update = rapl_attr_update; + rapl_pmus->pmu.task_ctx_nr = perf_invalid_context; + rapl_pmus->pmu.event_init = rapl_pmu_event_init; + rapl_pmus->pmu.add = rapl_pmu_event_add; + rapl_pmus->pmu.del = rapl_pmu_event_del; + rapl_pmus->pmu.start = rapl_pmu_event_start; + rapl_pmus->pmu.stop = rapl_pmu_event_stop; + rapl_pmus->pmu.read = rapl_pmu_event_read; + rapl_pmus->pmu.module = THIS_MODULE; + rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE; + return 0; +} + +#define X86_RAPL_MODEL_MATCH(model, init) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)&init } + +static struct rapl_model model_snb = { + .events = BIT(PERF_RAPL_PP0) | + BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_PP1), + .apply_quirk = false, +}; + +static struct rapl_model model_snbep = { + .events = BIT(PERF_RAPL_PP0) | + BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_RAM), + .apply_quirk = false, +}; + +static struct rapl_model model_hsw = { + .events = BIT(PERF_RAPL_PP0) | + BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_RAM) | + BIT(PERF_RAPL_PP1), + .apply_quirk = false, +}; + +static struct rapl_model model_hsx = { + .events = BIT(PERF_RAPL_PP0) | + BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_RAM), + .apply_quirk = true, +}; + +static struct rapl_model model_knl = { + .events = BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_RAM), + .apply_quirk = true, +}; + +static struct rapl_model model_skl = { + .events = BIT(PERF_RAPL_PP0) | + BIT(PERF_RAPL_PKG) | + BIT(PERF_RAPL_RAM) | + BIT(PERF_RAPL_PP1) | + BIT(PERF_RAPL_PSYS), + .apply_quirk = false, +}; + +static const struct x86_cpu_id rapl_model_match[] __initconst = { + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE, model_snb), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SANDYBRIDGE_X, model_snbep), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE, model_snb), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_IVYBRIDGE_X, model_snbep), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_X, model_hsx), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_L, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_HASWELL_G, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_G, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_X, model_hsx), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_D, model_hsx), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, model_knl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, model_knl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_L, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X, model_hsx), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE_L, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_KABYLAKE, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_CANNONLAKE_L, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_D, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ATOM_GOLDMONT_PLUS, model_hsw), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE_L, model_skl), + X86_RAPL_MODEL_MATCH(INTEL_FAM6_ICELAKE, model_skl), + {}, +}; + +MODULE_DEVICE_TABLE(x86cpu, rapl_model_match); + +static int __init rapl_pmu_init(void) +{ + const struct x86_cpu_id *id; + struct rapl_model *rm; + int ret; + + id = x86_match_cpu(rapl_model_match); + if (!id) + return -ENODEV; + + rm = (struct rapl_model *) id->driver_data; + rapl_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_MAX, + false, (void *) &rm->events); + + ret = rapl_check_hw_unit(rm->apply_quirk); + if (ret) + return ret; + + ret = init_rapl_pmus(); + if (ret) + return ret; + + /* + * Install callbacks. Core will call them for each online cpu. + */ + ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_RAPL_ONLINE, + "perf/x86/rapl:online", + rapl_cpu_online, rapl_cpu_offline); + if (ret) + goto out; + + ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1); + if (ret) + goto out1; + + rapl_advertise(); + return 0; + +out1: + cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE); +out: + pr_warn("Initialization failed (%d), disabled\n", ret); + cleanup_rapl_pmus(); + return ret; +} +module_init(rapl_pmu_init); + +static void __exit intel_rapl_exit(void) +{ + cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_RAPL_ONLINE); + perf_pmu_unregister(&rapl_pmus->pmu); + cleanup_rapl_pmus(); +} +module_exit(intel_rapl_exit); --- linux-oracle-5.4.0.orig/arch/x86/hyperv/hv_init.c +++ linux-oracle-5.4.0/arch/x86/hyperv/hv_init.c @@ -19,9 +19,18 @@ #include #include #include +#include #include #include +#ifndef PKG_ABI +/* + * Preserve the ability to 'make deb-pkg' since PKG_ABI is provided + * by the Ubuntu build rules. + */ +#define PKG_ABI 0 +#endif + void *hv_hypercall_pg; EXPORT_SYMBOL_GPL(hv_hypercall_pg); @@ -154,7 +163,6 @@ struct hv_reenlightenment_control re_ctrl = { .vector = HYPERV_REENLIGHTENMENT_VECTOR, .enabled = 1, - .target_vp = hv_vp_index[smp_processor_id()] }; struct hv_tsc_emulation_control emu_ctrl = {.enabled = 1}; @@ -163,13 +171,20 @@ return; } + if (!hv_vp_index) + return; + hv_reenlightenment_cb = cb; /* Make sure callback is registered before we write to MSRs */ wmb(); + re_ctrl.target_vp = hv_vp_index[get_cpu()]; + wrmsrl(HV_X64_MSR_REENLIGHTENMENT_CONTROL, *((u64 *)&re_ctrl)); wrmsrl(HV_X64_MSR_TSC_EMULATION_CONTROL, *((u64 *)&emu_ctrl)); + + put_cpu(); } EXPORT_SYMBOL_GPL(set_hv_tscchange_cb); @@ -297,7 +312,7 @@ * 1. Register the guest ID * 2. Enable the hypercall and register the hypercall page */ - guest_id = generate_guest_id(0, LINUX_VERSION_CODE, 0); + guest_id = generate_guest_id(0x80 /*Canonical*/, LINUX_VERSION_CODE, PKG_ABI); wrmsrl(HV_X64_MSR_GUEST_OS_ID, guest_id); hv_hypercall_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_RX); @@ -354,11 +369,14 @@ } EXPORT_SYMBOL_GPL(hyperv_cleanup); -void hyperv_report_panic(struct pt_regs *regs, long err) +void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) { static bool panic_reported; u64 guest_id; + if (in_die && !panic_on_oops) + return; + /* * We prefer to report panic on 'die' chain as we have proper * registers to report, but if we miss it (e.g. on BUG()) we need --- linux-oracle-5.4.0.orig/arch/x86/hyperv/mmu.c +++ linux-oracle-5.4.0/arch/x86/hyperv/mmu.c @@ -66,11 +66,17 @@ if (!hv_hypercall_pg) goto do_native; - if (cpumask_empty(cpus)) - return; - local_irq_save(flags); + /* + * Only check the mask _after_ interrupt has been disabled to avoid the + * mask changing under our feet. + */ + if (cpumask_empty(cpus)) { + local_irq_restore(flags); + return; + } + flush_pcpu = (struct hv_tlb_flush **) this_cpu_ptr(hyperv_pcpu_input_arg); --- linux-oracle-5.4.0.orig/arch/x86/ia32/ia32_aout.c +++ linux-oracle-5.4.0/arch/x86/ia32/ia32_aout.c @@ -140,6 +140,7 @@ set_personality_ia32(false); setup_new_exec(bprm); + install_exec_creds(bprm); regs->cs = __USER32_CS; regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 = @@ -156,8 +157,6 @@ if (retval < 0) return retval; - install_exec_creds(bprm); - if (N_MAGIC(ex) == OMAGIC) { unsigned long text_addr, map_size; --- linux-oracle-5.4.0.orig/arch/x86/ia32/ia32_signal.c +++ linux-oracle-5.4.0/arch/x86/ia32/ia32_signal.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -118,7 +119,7 @@ return err; } -asmlinkage long sys32_sigreturn(void) +COMPAT_SYSCALL_DEFINE0(sigreturn) { struct pt_regs *regs = current_pt_regs(); struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8); @@ -144,7 +145,7 @@ return 0; } -asmlinkage long sys32_rt_sigreturn(void) +COMPAT_SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = current_pt_regs(); struct rt_sigframe_ia32 __user *frame; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/acenv.h +++ linux-oracle-5.4.0/arch/x86/include/asm/acenv.h @@ -13,7 +13,19 @@ /* Asm macros */ -#define ACPI_FLUSH_CPU_CACHE() wbinvd() +/* + * ACPI_FLUSH_CPU_CACHE() flushes caches on entering sleep states. + * It is required to prevent data loss. + * + * While running inside virtual machine, the kernel can bypass cache flushing. + * Changing sleep state in a virtual machine doesn't affect the host system + * sleep state and cannot lead to data loss. + */ +#define ACPI_FLUSH_CPU_CACHE() \ +do { \ + if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) \ + wbinvd(); \ +} while (0) int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/amd_nb.h +++ linux-oracle-5.4.0/arch/x86/include/asm/amd_nb.h @@ -118,7 +118,10 @@ #define amd_nb_num(x) 0 #define amd_nb_has_feature(x) false -#define node_to_amd_nb(x) NULL +static inline struct amd_northbridge *node_to_amd_nb(int node) +{ + return NULL; +} #define amd_gart_present(x) false #endif --- linux-oracle-5.4.0.orig/arch/x86/include/asm/apic.h +++ linux-oracle-5.4.0/arch/x86/include/asm/apic.h @@ -12,6 +12,7 @@ #include #include #include +#include #define ARCH_APICTIMER_STOPS_ON_C3 1 @@ -111,7 +112,7 @@ static inline u32 native_apic_mem_read(u32 reg) { - return *((volatile u32 *)(APIC_BASE + reg)); + return readl((void __iomem *)(APIC_BASE + reg)); } extern void native_apic_wait_icr_idle(void); @@ -140,6 +141,7 @@ extern void lapic_shutdown(void); extern void sync_Arb_IDs(void); extern void init_bsp_APIC(void); +extern void apic_intr_mode_select(void); extern void apic_intr_mode_init(void); extern void init_apic_mappings(void); void register_lapic_address(unsigned long address); @@ -173,6 +175,7 @@ extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask); extern void lapic_assign_system_vectors(void); extern void lapic_assign_legacy_vector(unsigned int isairq, bool replace); +extern void lapic_update_legacy_vectors(void); extern void lapic_online(void); extern void lapic_offline(void); extern bool apic_needs_pit(void); @@ -188,6 +191,7 @@ # define setup_secondary_APIC_clock x86_init_noop static inline void lapic_update_tsc_freq(void) { } static inline void init_bsp_APIC(void) { } +static inline void apic_intr_mode_select(void) { } static inline void apic_intr_mode_init(void) { } static inline void lapic_assign_system_vectors(void) { } static inline void lapic_assign_legacy_vector(unsigned int i, bool r) { } @@ -195,16 +199,6 @@ #endif /* !CONFIG_X86_LOCAL_APIC */ #ifdef CONFIG_X86_X2APIC -/* - * Make previous memory operations globally visible before - * sending the IPI through x2apic wrmsr. We need a serializing instruction or - * mfence for this. - */ -static inline void x2apic_wrmsr_fence(void) -{ - asm volatile("mfence" : : : "memory"); -} - static inline void native_apic_msr_write(u32 reg, u32 v) { if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || @@ -257,6 +251,7 @@ extern int x2apic_mode; extern int x2apic_phys; +extern void __init x2apic_set_max_apicid(u32 apicid); extern void __init check_x2apic(void); extern void x2apic_setup(void); static inline int x2apic_enabled(void) @@ -452,6 +447,14 @@ apic_eoi(); } + +static inline bool lapic_vector_set_in_irr(unsigned int vector) +{ + u32 irr = apic_read(APIC_IRR + (vector / 32 * 0x10)); + + return !!(irr & (1U << (vector % 32))); +} + static inline unsigned default_get_apic_id(unsigned long x) { unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/apm.h +++ linux-oracle-5.4.0/arch/x86/include/asm/apm.h @@ -35,6 +35,7 @@ __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" + ANNOTATE_RETPOLINE_SAFE /* FRBS */ "lcall *%%cs:apm_bios_entry\n\t" "setc %%al\n\t" "popl %%ebp\n\t" @@ -59,6 +60,7 @@ __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" + ANNOTATE_RETPOLINE_SAFE /* FRBS */ "lcall *%%cs:apm_bios_entry\n\t" "setc %%bl\n\t" "popl %%ebp\n\t" --- linux-oracle-5.4.0.orig/arch/x86/include/asm/archrandom.h +++ linux-oracle-5.4.0/arch/x86/include/asm/archrandom.h @@ -73,10 +73,6 @@ return ok; } -/* Conditional execution based on CPU type */ -#define arch_has_random() static_cpu_has(X86_FEATURE_RDRAND) -#define arch_has_random_seed() static_cpu_has(X86_FEATURE_RDSEED) - /* * These are the generic interfaces; they must not be declared if the * stubs in are to be invoked, @@ -86,22 +82,22 @@ static inline bool arch_get_random_long(unsigned long *v) { - return arch_has_random() ? rdrand_long(v) : false; + return static_cpu_has(X86_FEATURE_RDRAND) ? rdrand_long(v) : false; } static inline bool arch_get_random_int(unsigned int *v) { - return arch_has_random() ? rdrand_int(v) : false; + return static_cpu_has(X86_FEATURE_RDRAND) ? rdrand_int(v) : false; } static inline bool arch_get_random_seed_long(unsigned long *v) { - return arch_has_random_seed() ? rdseed_long(v) : false; + return static_cpu_has(X86_FEATURE_RDSEED) ? rdseed_long(v) : false; } static inline bool arch_get_random_seed_int(unsigned int *v) { - return arch_has_random_seed() ? rdseed_int(v) : false; + return static_cpu_has(X86_FEATURE_RDSEED) ? rdseed_int(v) : false; } extern void x86_init_rdrand(struct cpuinfo_x86 *c); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/asm.h +++ linux-oracle-5.4.0/arch/x86/include/asm/asm.h @@ -7,9 +7,11 @@ # define __ASM_FORM_RAW(x) x # define __ASM_FORM_COMMA(x) x, #else -# define __ASM_FORM(x) " " #x " " -# define __ASM_FORM_RAW(x) #x -# define __ASM_FORM_COMMA(x) " " #x "," +#include + +# define __ASM_FORM(x) " " __stringify(x) " " +# define __ASM_FORM_RAW(x) __stringify(x) +# define __ASM_FORM_COMMA(x) " " __stringify(x) "," #endif #ifndef __x86_64__ @@ -139,9 +141,6 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) -# define _ASM_EXTABLE_REFCOUNT(from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) - # define _ASM_NOKPROBE(entry) \ .pushsection "_kprobe_blacklist","aw" ; \ _ASM_ALIGN ; \ @@ -170,9 +169,6 @@ # define _ASM_EXTABLE_EX(from, to) \ _ASM_EXTABLE_HANDLE(from, to, ex_handler_ext) -# define _ASM_EXTABLE_REFCOUNT(from, to) \ - _ASM_EXTABLE_HANDLE(from, to, ex_handler_refcount) - /* For C file, we already have NOKPROBE_SYMBOL macro */ #endif --- linux-oracle-5.4.0.orig/arch/x86/include/asm/barrier.h +++ linux-oracle-5.4.0/arch/x86/include/asm/barrier.h @@ -84,4 +84,22 @@ #include +/* + * Make previous memory operations globally visible before + * a WRMSR. + * + * MFENCE makes writes visible, but only affects load/store + * instructions. WRMSR is unfortunately not a load/store + * instruction and is unaffected by MFENCE. The LFENCE ensures + * that the WRMSR is not reordered. + * + * Most WRMSRs are full serializing instructions themselves and + * do not require this barrier. This is only required for the + * IA32_TSC_DEADLINE and X2APIC MSRs. + */ +static inline void weak_wrmsr_fence(void) +{ + asm volatile("mfence; lfence" : : : "memory"); +} + #endif /* _ASM_X86_BARRIER_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/bugs.h +++ linux-oracle-5.4.0/arch/x86/include/asm/bugs.h @@ -4,8 +4,6 @@ #include -extern void check_bugs(void); - #if defined(CONFIG_CPU_SUP_INTEL) void check_mpx_erratum(struct cpuinfo_x86 *c); #else --- linux-oracle-5.4.0.orig/arch/x86/include/asm/cacheinfo.h +++ linux-oracle-5.4.0/arch/x86/include/asm/cacheinfo.h @@ -2,7 +2,7 @@ #ifndef _ASM_X86_CACHEINFO_H #define _ASM_X86_CACHEINFO_H -void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id); -void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id); +void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu); +void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu); #endif /* _ASM_X86_CACHEINFO_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/compat.h +++ linux-oracle-5.4.0/arch/x86/include/asm/compat.h @@ -31,15 +31,13 @@ typedef u64 __attribute__((aligned(4))) compat_u64; struct compat_stat { - compat_dev_t st_dev; - u16 __pad1; + u32 st_dev; compat_ino_t st_ino; compat_mode_t st_mode; compat_nlink_t st_nlink; __compat_uid_t st_uid; __compat_gid_t st_gid; - compat_dev_t st_rdev; - u16 __pad2; + u32 st_rdev; u32 st_size; u32 st_blksize; u32 st_blocks; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/cpu_device_id.h +++ linux-oracle-5.4.0/arch/x86/include/asm/cpu_device_id.h @@ -5,9 +5,163 @@ /* * Declare drivers belonging to specific x86 CPUs * Similar in spirit to pci_device_id and related PCI functions + * + * The wildcard initializers are in mod_devicetable.h because + * file2alias needs them. Sigh. */ - #include +/* Get the INTEL_FAM* model defines */ +#include +/* And the X86_VENDOR_* ones */ +#include + +/* Centaur FAM6 models */ +#define X86_CENTAUR_FAM6_C7_A 0xa +#define X86_CENTAUR_FAM6_C7_D 0xd +#define X86_CENTAUR_FAM6_NANO 0xf + +#define X86_STEPPINGS(mins, maxs) GENMASK(maxs, mins) +/** + * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching + * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@_vendor + * @_family: The family number or X86_FAMILY_ANY + * @_model: The model number, model constant or X86_MODEL_ANY + * @_steppings: Bitmask for steppings, stepping constant or X86_STEPPING_ANY + * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY + * @_data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * Use only if you need all selectors. Otherwise use one of the shorter + * macros of the X86_MATCH_* family. If there is no matching shorthand + * macro, consider to add one. If you really need to wrap one of the macros + * into another macro at the usage site for good reasons, then please + * start this local macro with X86_MATCH to allow easy grepping. + */ +#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ + _steppings, _feature, _data) { \ + .vendor = X86_VENDOR_##_vendor, \ + .family = _family, \ + .model = _model, \ + .steppings = _steppings, \ + .feature = _feature, \ + .driver_data = (unsigned long) _data \ +} + +/** + * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Macro for CPU matching + * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@_vendor + * @_family: The family number or X86_FAMILY_ANY + * @_model: The model number, model constant or X86_MODEL_ANY + * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY + * @_data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * The steppings arguments of X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE() is + * set to wildcards. + */ +#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, feature, data) \ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(vendor, family, model, \ + X86_STEPPING_ANY, feature, data) + +/** + * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature + * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@vendor + * @family: The family number or X86_FAMILY_ANY + * @feature: A X86_FEATURE bit + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are + * set to wildcards. + */ +#define X86_MATCH_VENDOR_FAM_FEATURE(vendor, family, feature, data) \ + X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, \ + X86_MODEL_ANY, feature, data) + +/** + * X86_MATCH_VENDOR_FEATURE - Macro for matching vendor and CPU feature + * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@vendor + * @feature: A X86_FEATURE bit + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are + * set to wildcards. + */ +#define X86_MATCH_VENDOR_FEATURE(vendor, feature, data) \ + X86_MATCH_VENDOR_FAM_FEATURE(vendor, X86_FAMILY_ANY, feature, data) + +/** + * X86_MATCH_FEATURE - Macro for matching a CPU feature + * @feature: A X86_FEATURE bit + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are + * set to wildcards. + */ +#define X86_MATCH_FEATURE(feature, data) \ + X86_MATCH_VENDOR_FEATURE(ANY, feature, data) + +/* Transitional to keep the existing code working */ +#define X86_FEATURE_MATCH(feature) X86_MATCH_FEATURE(feature, NULL) + +/** + * X86_MATCH_VENDOR_FAM_MODEL - Match vendor, family and model + * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@vendor + * @family: The family number or X86_FAMILY_ANY + * @model: The model number, model constant or X86_MODEL_ANY + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * All other missing arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are + * set to wildcards. + */ +#define X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, data) \ + X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, \ + X86_FEATURE_ANY, data) + +/** + * X86_MATCH_VENDOR_FAM - Match vendor and family + * @vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@vendor + * @family: The family number or X86_FAMILY_ANY + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * All other missing arguments to X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are + * set of wildcards. + */ +#define X86_MATCH_VENDOR_FAM(vendor, family, data) \ + X86_MATCH_VENDOR_FAM_MODEL(vendor, family, X86_MODEL_ANY, data) + +/** + * X86_MATCH_INTEL_FAM6_MODEL - Match vendor INTEL, family 6 and model + * @model: The model name without the INTEL_FAM6_ prefix or ANY + * The model name is expanded to INTEL_FAM6_@model internally + * @data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * The vendor is set to INTEL, the family to 6 and all other missing + * arguments of X86_MATCH_VENDOR_FAM_MODEL_FEATURE() are set to wildcards. + * + * See X86_MATCH_VENDOR_FAM_MODEL_FEATURE() for further information. + */ +#define X86_MATCH_INTEL_FAM6_MODEL(model, data) \ + X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data) /* * Match specific microcode revisions. --- linux-oracle-5.4.0.orig/arch/x86/include/asm/cpu_entry_area.h +++ linux-oracle-5.4.0/arch/x86/include/asm/cpu_entry_area.h @@ -78,8 +78,12 @@ /* * The GDT is just below entry_stack and thus serves (on x86_64) as - * a a read-only guard page. + * a read-only guard page. On 32-bit the GDT must be writeable, so + * it needs an extra guard page. */ +#ifdef CONFIG_X86_32 + char guard_entry_stack[PAGE_SIZE]; +#endif struct entry_stack_page entry_stack_page; /* @@ -94,7 +98,6 @@ */ struct cea_exception_stacks estacks; #endif -#ifdef CONFIG_CPU_SUP_INTEL /* * Per CPU debug store for Intel performance monitoring. Wastes a * full page at the moment. @@ -105,11 +108,9 @@ * Reserve enough fixmap PTEs. */ struct debug_store_buffers cpu_debug_buffers; -#endif }; -#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area)) -#define CPU_ENTRY_AREA_TOT_SIZE (CPU_ENTRY_AREA_SIZE * NR_CPUS) +#define CPU_ENTRY_AREA_SIZE (sizeof(struct cpu_entry_area)) DECLARE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); DECLARE_PER_CPU(struct cea_exception_stacks *, cea_exception_stacks); @@ -117,17 +118,23 @@ extern void setup_cpu_entry_areas(void); extern void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags); +/* Single page reserved for the readonly IDT mapping: */ #define CPU_ENTRY_AREA_RO_IDT CPU_ENTRY_AREA_BASE #define CPU_ENTRY_AREA_PER_CPU (CPU_ENTRY_AREA_RO_IDT + PAGE_SIZE) #define CPU_ENTRY_AREA_RO_IDT_VADDR ((void *)CPU_ENTRY_AREA_RO_IDT) -#define CPU_ENTRY_AREA_MAP_SIZE \ - (CPU_ENTRY_AREA_PER_CPU + CPU_ENTRY_AREA_TOT_SIZE - CPU_ENTRY_AREA_BASE) +#ifdef CONFIG_X86_32 +#define CPU_ENTRY_AREA_MAP_SIZE (CPU_ENTRY_AREA_PER_CPU + \ + (CPU_ENTRY_AREA_SIZE * NR_CPUS) - \ + CPU_ENTRY_AREA_BASE) +#else +#define CPU_ENTRY_AREA_MAP_SIZE P4D_SIZE +#endif extern struct cpu_entry_area *get_cpu_entry_area(int cpu); -static inline struct entry_stack *cpu_entry_stack(int cpu) +static __always_inline struct entry_stack *cpu_entry_stack(int cpu) { return &get_cpu_entry_area(cpu)->entry_stack_page.stack; } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/cpufeature.h +++ linux-oracle-5.4.0/arch/x86/include/asm/cpufeature.h @@ -30,6 +30,10 @@ CPUID_7_ECX, CPUID_8000_0007_EBX, CPUID_7_EDX, + CPUID_8000_001F_EAX, + CPUID_8000_0021_EAX, + CPUID_LNX_5, + NR_CPUID_WORDS, }; #ifdef CONFIG_X86_FEATURE_NAMES @@ -49,7 +53,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; #define test_cpu_cap(c, bit) \ - test_bit(bit, (unsigned long *)((c)->x86_capability)) + arch_test_bit(bit, (unsigned long *)((c)->x86_capability)) /* * There are 32 bits/features in each mask word. The high bits @@ -88,8 +92,11 @@ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) || \ REQUIRED_MASK_CHECK || \ - BUILD_BUG_ON_ZERO(NCAPINTS != 19)) + BUILD_BUG_ON_ZERO(NCAPINTS != 22)) #define DISABLED_MASK_BIT_SET(feature_bit) \ ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \ @@ -111,8 +118,11 @@ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \ CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) || \ DISABLED_MASK_CHECK || \ - BUILD_BUG_ON_ZERO(NCAPINTS != 19)) + BUILD_BUG_ON_ZERO(NCAPINTS != 22)) #define cpu_has(c, bit) \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/cpufeatures.h +++ linux-oracle-5.4.0/arch/x86/include/asm/cpufeatures.h @@ -13,8 +13,8 @@ /* * Defines x86 CPU feature bits */ -#define NCAPINTS 19 /* N 32-bit words worth of info */ -#define NBUGINTS 1 /* N 32-bit bug flags */ +#define NCAPINTS 22 /* N 32-bit words worth of info */ +#define NBUGINTS 2 /* N 32-bit bug flags */ /* * Note: If the comment begins with a quoted string, that string is used @@ -96,6 +96,7 @@ #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in IA32 userspace */ #define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in IA32 userspace */ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* REP microcode works well */ +/* FREE! ( 3*32+17) */ #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" LFENCE synchronizes RDTSC */ #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ @@ -107,6 +108,7 @@ #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* Extended APICID (8 bits) */ #define X86_FEATURE_AMD_DCM ( 3*32+27) /* AMD multi-node processor */ #define X86_FEATURE_APERFMPERF ( 3*32+28) /* P-State hardware coordination feedback capability (APERF/MPERF MSRs) */ +/* free ( 3*32+29) */ #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ #define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */ @@ -199,23 +201,23 @@ #define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ -#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ +/* FREE! ( 7*32+10) */ #define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */ -#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ -#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ +#define X86_FEATURE_KERNEL_IBRS ( 7*32+12) /* "" Set/clear IBRS on kernel entry/exit */ +#define X86_FEATURE_RSB_VMEXIT ( 7*32+13) /* "" Fill RSB on VM-Exit */ #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ -#define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ +/* FREE! ( 7*32+20) */ #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */ #define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */ -#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ +#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */ #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */ @@ -284,6 +286,11 @@ #define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ #define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */ #define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */ +#define X86_FEATURE_RRSBA_CTRL (11*32+11) /* "" RET prediction control */ +#define X86_FEATURE_RETPOLINE (11*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +#define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */ +#define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */ +#define X86_FEATURE_MSR_TSX_CTRL (11*32+18) /* "" MSR IA32_TSX_CTRL (Intel) implemented */ /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ @@ -300,6 +307,8 @@ #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ +#define X86_FEATURE_BTC_NO (13*32+29) /* "" Not vulnerable to Branch Type Confusion */ +#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* "" IBPB clears return address predictor */ /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ @@ -357,6 +366,7 @@ #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ #define X86_FEATURE_AVX512_VP2INTERSECT (18*32+ 8) /* AVX-512 Intersect for D/Q */ +#define X86_FEATURE_SRBDS_CTRL (18*32+ 9) /* "" SRBDS mitigation MSR available */ #define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */ #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ @@ -366,6 +376,26 @@ #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ +/* AMD-defined memory encryption features, CPUID level 0x8000001f (EAX), word 19 */ +#define X86_FEATURE_SME (19*32+ 0) /* AMD Secure Memory Encryption */ +#define X86_FEATURE_SEV (19*32+ 1) /* AMD Secure Encrypted Virtualization */ +#define X86_FEATURE_VM_PAGE_FLUSH (19*32+ 2) /* "" VM Page Flush MSR is supported */ +#define X86_FEATURE_SEV_ES (19*32+ 3) /* AMD Secure Encrypted Virtualization - Encrypted State */ +#define X86_FEATURE_SME_COHERENT (19*32+10) /* "" AMD hardware-enforced cache coherency */ + +#define X86_FEATURE_AUTOIBRS (20*32+ 8) /* "" Automatic IBRS */ + +/* + * Extended auxiliary flags: Linux defined - for features scattered in various + * CPUID levels like 0x80000022, etc and Linux defined features. + * + * Reuse free bits when adding new feature flags! + */ +#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */ +#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */ +#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */ +#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */ + /* * BUG word(s) */ @@ -401,5 +431,15 @@ #define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ - +#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ +#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ +#define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */ +#define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */ +#define X86_BUG_MMIO_UNKNOWN X86_BUG(28) /* CPU is too old and its MMIO Stale Data status is unknown */ +#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */ +#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */ + +/* BUG word 2 */ +#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ +#define X86_BUG_BHI X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */ #endif /* _ASM_X86_CPUFEATURES_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crash.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crash.h @@ -2,10 +2,18 @@ #ifndef _ASM_X86_CRASH_H #define _ASM_X86_CRASH_H +struct kimage; + int crash_load_segments(struct kimage *image); int crash_copy_backup_region(struct kimage *image); int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params); void crash_smp_send_stop(void); +#ifdef CONFIG_KEXEC_CORE +void __init crash_reserve_low_1M(void); +#else +static inline void __init crash_reserve_low_1M(void) { } +#endif + #endif /* _ASM_X86_CRASH_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crypto/camellia.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crypto/camellia.h @@ -32,65 +32,60 @@ unsigned int keylen); /* regular block cipher functions */ -asmlinkage void __camellia_enc_blk(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, bool xor); -asmlinkage void camellia_dec_blk(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void __camellia_enc_blk(const void *ctx, u8 *dst, const u8 *src, + bool xor); +asmlinkage void camellia_dec_blk(const void *ctx, u8 *dst, const u8 *src); /* 2-way parallel cipher functions */ -asmlinkage void __camellia_enc_blk_2way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, bool xor); -asmlinkage void camellia_dec_blk_2way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void __camellia_enc_blk_2way(const void *ctx, u8 *dst, const u8 *src, + bool xor); +asmlinkage void camellia_dec_blk_2way(const void *ctx, u8 *dst, const u8 *src); /* 16-way parallel cipher functions (avx/aes-ni) */ -asmlinkage void camellia_ecb_enc_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void camellia_ecb_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); - -asmlinkage void camellia_cbc_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void camellia_ctr_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); - -asmlinkage void camellia_xts_enc_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); -asmlinkage void camellia_xts_dec_16way(struct camellia_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void camellia_ecb_enc_16way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void camellia_ecb_dec_16way(const void *ctx, u8 *dst, const u8 *src); -static inline void camellia_enc_blk(struct camellia_ctx *ctx, u8 *dst, - const u8 *src) +asmlinkage void camellia_cbc_dec_16way(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void camellia_ctr_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); + +asmlinkage void camellia_xts_enc_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +asmlinkage void camellia_xts_dec_16way(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); + +static inline void camellia_enc_blk(const void *ctx, u8 *dst, const u8 *src) { __camellia_enc_blk(ctx, dst, src, false); } -static inline void camellia_enc_blk_xor(struct camellia_ctx *ctx, u8 *dst, - const u8 *src) +static inline void camellia_enc_blk_xor(const void *ctx, u8 *dst, const u8 *src) { __camellia_enc_blk(ctx, dst, src, true); } -static inline void camellia_enc_blk_2way(struct camellia_ctx *ctx, u8 *dst, +static inline void camellia_enc_blk_2way(const void *ctx, u8 *dst, const u8 *src) { __camellia_enc_blk_2way(ctx, dst, src, false); } -static inline void camellia_enc_blk_xor_2way(struct camellia_ctx *ctx, u8 *dst, +static inline void camellia_enc_blk_xor_2way(const void *ctx, u8 *dst, const u8 *src) { __camellia_enc_blk_2way(ctx, dst, src, true); } /* glue helpers */ -extern void camellia_decrypt_cbc_2way(void *ctx, u128 *dst, const u128 *src); -extern void camellia_crypt_ctr(void *ctx, u128 *dst, const u128 *src, +extern void camellia_decrypt_cbc_2way(const void *ctx, u8 *dst, const u8 *src); +extern void camellia_crypt_ctr(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -extern void camellia_crypt_ctr_2way(void *ctx, u128 *dst, const u128 *src, +extern void camellia_crypt_ctr_2way(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -extern void camellia_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv); -extern void camellia_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv); +extern void camellia_xts_enc(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); +extern void camellia_xts_dec(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); #endif /* ASM_X86_CAMELLIA_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crypto/glue_helper.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crypto/glue_helper.h @@ -11,18 +11,13 @@ #include #include -typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); -typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src); -typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src, +typedef void (*common_glue_func_t)(const void *ctx, u8 *dst, const u8 *src); +typedef void (*common_glue_cbc_func_t)(const void *ctx, u8 *dst, const u8 *src); +typedef void (*common_glue_ctr_func_t)(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -typedef void (*common_glue_xts_func_t)(void *ctx, u128 *dst, const u128 *src, +typedef void (*common_glue_xts_func_t)(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -#define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) -#define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn)) -#define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn)) -#define GLUE_XTS_FUNC_CAST(fn) ((common_glue_xts_func_t)(fn)) - struct common_glue_func_entry { unsigned int num_blocks; /* number of blocks that @fn will process */ union { @@ -116,7 +111,8 @@ common_glue_func_t tweak_fn, void *tweak_ctx, void *crypt_ctx, bool decrypt); -extern void glue_xts_crypt_128bit_one(void *ctx, u128 *dst, const u128 *src, - le128 *iv, common_glue_func_t fn); +extern void glue_xts_crypt_128bit_one(const void *ctx, u8 *dst, + const u8 *src, le128 *iv, + common_glue_func_t fn); #endif /* _CRYPTO_GLUE_HELPER_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crypto/serpent-avx.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crypto/serpent-avx.h @@ -15,26 +15,26 @@ struct serpent_ctx crypt_ctx; }; -asmlinkage void serpent_ecb_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_ecb_enc_8way_avx(const void *ctx, u8 *dst, const u8 *src); -asmlinkage void serpent_ecb_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_ecb_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src); -asmlinkage void serpent_cbc_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_cbc_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src); -asmlinkage void serpent_ctr_8way_avx(struct serpent_ctx *ctx, u8 *dst, - const u8 *src, le128 *iv); +asmlinkage void serpent_ctr_8way_avx(const void *ctx, u8 *dst, const u8 *src, + le128 *iv); -asmlinkage void serpent_xts_enc_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_xts_enc_8way_avx(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -asmlinkage void serpent_xts_dec_8way_avx(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_xts_dec_8way_avx(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -extern void __serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, +extern void __serpent_crypt_ctr(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -extern void serpent_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv); -extern void serpent_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv); +extern void serpent_xts_enc(const void *ctx, u8 *dst, const u8 *src, le128 *iv); +extern void serpent_xts_dec(const void *ctx, u8 *dst, const u8 *src, le128 *iv); extern int xts_serpent_setkey(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crypto/serpent-sse2.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crypto/serpent-sse2.h @@ -9,25 +9,23 @@ #define SERPENT_PARALLEL_BLOCKS 4 -asmlinkage void __serpent_enc_blk_4way(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void __serpent_enc_blk_4way(const struct serpent_ctx *ctx, u8 *dst, const u8 *src, bool xor); -asmlinkage void serpent_dec_blk_4way(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_dec_blk_4way(const struct serpent_ctx *ctx, u8 *dst, const u8 *src); -static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_enc_blk_xway(const void *ctx, u8 *dst, const u8 *src) { __serpent_enc_blk_4way(ctx, dst, src, false); } -static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_enc_blk_xway_xor(const struct serpent_ctx *ctx, + u8 *dst, const u8 *src) { __serpent_enc_blk_4way(ctx, dst, src, true); } -static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_dec_blk_xway(const void *ctx, u8 *dst, const u8 *src) { serpent_dec_blk_4way(ctx, dst, src); } @@ -36,25 +34,23 @@ #define SERPENT_PARALLEL_BLOCKS 8 -asmlinkage void __serpent_enc_blk_8way(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void __serpent_enc_blk_8way(const struct serpent_ctx *ctx, u8 *dst, const u8 *src, bool xor); -asmlinkage void serpent_dec_blk_8way(struct serpent_ctx *ctx, u8 *dst, +asmlinkage void serpent_dec_blk_8way(const struct serpent_ctx *ctx, u8 *dst, const u8 *src); -static inline void serpent_enc_blk_xway(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_enc_blk_xway(const void *ctx, u8 *dst, const u8 *src) { __serpent_enc_blk_8way(ctx, dst, src, false); } -static inline void serpent_enc_blk_xway_xor(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_enc_blk_xway_xor(const struct serpent_ctx *ctx, + u8 *dst, const u8 *src) { __serpent_enc_blk_8way(ctx, dst, src, true); } -static inline void serpent_dec_blk_xway(struct serpent_ctx *ctx, u8 *dst, - const u8 *src) +static inline void serpent_dec_blk_xway(const void *ctx, u8 *dst, const u8 *src) { serpent_dec_blk_8way(ctx, dst, src); } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/crypto/twofish.h +++ linux-oracle-5.4.0/arch/x86/include/asm/crypto/twofish.h @@ -7,22 +7,19 @@ #include /* regular block cipher functions from twofish_x86_64 module */ -asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); -asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void twofish_enc_blk(const void *ctx, u8 *dst, const u8 *src); +asmlinkage void twofish_dec_blk(const void *ctx, u8 *dst, const u8 *src); /* 3-way parallel cipher functions */ -asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src, bool xor); -asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, - const u8 *src); +asmlinkage void __twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src, + bool xor); +asmlinkage void twofish_dec_blk_3way(const void *ctx, u8 *dst, const u8 *src); /* helpers from twofish_x86_64-3way module */ -extern void twofish_dec_blk_cbc_3way(void *ctx, u128 *dst, const u128 *src); -extern void twofish_enc_blk_ctr(void *ctx, u128 *dst, const u128 *src, +extern void twofish_dec_blk_cbc_3way(const void *ctx, u8 *dst, const u8 *src); +extern void twofish_enc_blk_ctr(const void *ctx, u8 *dst, const u8 *src, le128 *iv); -extern void twofish_enc_blk_ctr_3way(void *ctx, u128 *dst, const u128 *src, +extern void twofish_enc_blk_ctr_3way(const void *ctx, u8 *dst, const u8 *src, le128 *iv); #endif /* ASM_X86_TWOFISH_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/disabled-features.h +++ linux-oracle-5.4.0/arch/x86/include/asm/disabled-features.h @@ -84,6 +84,9 @@ #define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP) #define DISABLED_MASK17 0 #define DISABLED_MASK18 0 -#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) +#define DISABLED_MASK19 0 +#define DISABLED_MASK20 0 +#define DISABLED_MASK21 0 +#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22) #endif /* _ASM_X86_DISABLED_FEATURES_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/dma.h +++ linux-oracle-5.4.0/arch/x86/include/asm/dma.h @@ -74,7 +74,7 @@ #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT) /* 4GB broken PCI/AGP hardware bus master zone */ -#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT) +#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT)) #ifdef CONFIG_X86_32 /* The maximum address that we can perform a DMA transfer to on this platform */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/elf.h +++ linux-oracle-5.4.0/arch/x86/include/asm/elf.h @@ -281,9 +281,29 @@ /* * An executable for which elf_read_implies_exec() returns TRUE will * have the READ_IMPLIES_EXEC personality flag set automatically. + * + * The decision process for determining the results are: + * + * CPU: | lacks NX* | has NX, ia32 | has NX, x86_64 | + * ELF: | | | | + * ---------------------|------------|------------------|----------------| + * missing PT_GNU_STACK | exec-all | exec-all | exec-none | + * PT_GNU_STACK == RWX | exec-stack | exec-stack | exec-stack | + * PT_GNU_STACK == RW | exec-none | exec-none | exec-none | + * + * exec-all : all PROT_READ user mappings are executable, except when + * backed by files on a noexec-filesystem. + * exec-none : only PROT_EXEC user mappings are executable. + * exec-stack: only the stack and PROT_EXEC user mappings are executable. + * + * *this column has no architectural effect: NX markings are ignored by + * hardware, but may have behavioral effects when "wants X" collides with + * "cannot be X" constraints in memory permission flags, as in + * https://lkml.kernel.org/r/20190418055759.GA3155@mellanox.com + * */ #define elf_read_implies_exec(ex, executable_stack) \ - (executable_stack != EXSTACK_DISABLE_X) + (mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT) struct task_struct; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/emulate_prefix.h +++ linux-oracle-5.4.0/arch/x86/include/asm/emulate_prefix.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_EMULATE_PREFIX_H +#define _ASM_X86_EMULATE_PREFIX_H + +/* + * Virt escape sequences to trigger instruction emulation; + * ideally these would decode to 'whole' instruction and not destroy + * the instruction stream; sadly this is not true for the 'kvm' one :/ + */ + +#define __XEN_EMULATE_PREFIX 0x0f,0x0b,0x78,0x65,0x6e /* ud2 ; .ascii "xen" */ +#define __KVM_EMULATE_PREFIX 0x0f,0x0b,0x6b,0x76,0x6d /* ud2 ; .ascii "kvm" */ + +#endif --- linux-oracle-5.4.0.orig/arch/x86/include/asm/fixmap.h +++ linux-oracle-5.4.0/arch/x86/include/asm/fixmap.h @@ -156,7 +156,7 @@ extern pte_t *pkmap_page_table; void __native_set_fixmap(enum fixed_addresses idx, pte_t pte); -void native_set_fixmap(enum fixed_addresses idx, +void native_set_fixmap(unsigned /* enum fixed_addresses */ idx, phys_addr_t phys, pgprot_t flags); #ifndef CONFIG_PARAVIRT_XXL --- linux-oracle-5.4.0.orig/arch/x86/include/asm/fpu/api.h +++ linux-oracle-5.4.0/arch/x86/include/asm/fpu/api.h @@ -16,14 +16,25 @@ * Use kernel_fpu_begin/end() if you intend to use FPU in kernel context. It * disables preemption so be careful if you intend to use it for long periods * of time. - * If you intend to use the FPU in softirq you need to check first with + * If you intend to use the FPU in irq/softirq you need to check first with * irq_fpu_usable() if it is possible. */ -extern void kernel_fpu_begin(void); + +/* Kernel FPU states to initialize in kernel_fpu_begin_mask() */ +#define KFPU_387 _BITUL(0) /* 387 state will be initialized */ +#define KFPU_MXCSR _BITUL(1) /* MXCSR will be initialized */ + +extern void kernel_fpu_begin_mask(unsigned int kfpu_mask); extern void kernel_fpu_end(void); extern bool irq_fpu_usable(void); extern void fpregs_mark_activate(void); +/* Code that is unaware of kernel_fpu_begin_mask() can use this */ +static inline void kernel_fpu_begin(void) +{ + kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); +} + /* * Use fpregs_lock() while editing CPU's FPU registers or fpu->state. * A context switch will (and softirq might) save CPU's FPU registers to --- linux-oracle-5.4.0.orig/arch/x86/include/asm/fpu/internal.h +++ linux-oracle-5.4.0/arch/x86/include/asm/fpu/internal.h @@ -41,7 +41,7 @@ extern void fpu__init_cpu(void); extern void fpu__init_system_xstate(void); extern void fpu__init_cpu_xstate(void); -extern void fpu__init_system(struct cpuinfo_x86 *c); +extern void fpu__init_system(void); extern void fpu__init_check_bugs(void); extern void fpu__resume_cpu(void); extern u64 fpu__get_supported_xfeatures_mask(void); @@ -102,6 +102,7 @@ } extern void fpstate_sanitize_xstate(struct fpu *fpu); +/* Returns 0 or the negated trap number, which results in -EFAULT for #PF */ #define user_insn(insn, output, input...) \ ({ \ int err; \ @@ -109,14 +110,14 @@ might_fault(); \ \ asm volatile(ASM_STAC "\n" \ - "1:" #insn "\n\t" \ + "1: " #insn "\n" \ "2: " ASM_CLAC "\n" \ ".section .fixup,\"ax\"\n" \ - "3: movl $-1,%[err]\n" \ + "3: negl %%eax\n" \ " jmp 2b\n" \ ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err), output \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err), output \ : "0"(0), input); \ err; \ }) @@ -203,6 +204,14 @@ asm volatile("fxsaveq %[fx]" : [fx] "=m" (fpu->state.fxsave)); } +static inline void fxsave(struct fxregs_state *fx) +{ + if (IS_ENABLED(CONFIG_X86_32)) + asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx)); + else + asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx)); +} + /* These macros all use (%edi)/(%rdi) as the single memory argument. */ #define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27" #define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37" @@ -210,16 +219,20 @@ #define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f" #define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f" +/* + * After this @err contains 0 on success or the negated trap number when + * the operation raises an exception. For faults this results in -EFAULT. + */ #define XSTATE_OP(op, st, lmask, hmask, err) \ asm volatile("1:" op "\n\t" \ "xor %[err], %[err]\n" \ "2:\n\t" \ ".pushsection .fixup,\"ax\"\n\t" \ - "3: movl $-2,%[err]\n\t" \ + "3: negl %%eax\n\t" \ "jmp 2b\n\t" \ ".popsection\n\t" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err) \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err) \ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") @@ -271,28 +284,6 @@ * This function is called only during boot time when x86 caps are not set * up and alternative can not be used yet. */ -static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) -{ - u64 mask = -1; - u32 lmask = mask; - u32 hmask = mask >> 32; - int err; - - WARN_ON(system_state != SYSTEM_BOOTING); - - if (boot_cpu_has(X86_FEATURE_XSAVES)) - XSTATE_OP(XSAVES, xstate, lmask, hmask, err); - else - XSTATE_OP(XSAVE, xstate, lmask, hmask, err); - - /* We should never fault when copying to a kernel buffer: */ - WARN_ON_FPU(err); -} - -/* - * This function is called only during boot time when x86 caps are not set - * up and alternative can not be used yet. - */ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) { u64 mask = -1; @@ -509,7 +500,7 @@ static inline int fpregs_state_valid(struct fpu *fpu, unsigned int cpu) { - return fpu == this_cpu_read_stable(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; + return fpu == this_cpu_read(fpu_fpregs_owner_ctx) && cpu == fpu->last_cpu; } /* @@ -569,9 +560,11 @@ * The FPU context is only stored/restored for a user task and * PF_KTHREAD is used to distinguish between kernel and user threads. */ -static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu) +static inline void switch_fpu_prepare(struct task_struct *prev, int cpu) { - if (static_cpu_has(X86_FEATURE_FPU) && !(current->flags & PF_KTHREAD)) { + struct fpu *old_fpu = &prev->thread.fpu; + + if (static_cpu_has(X86_FEATURE_FPU) && !(prev->flags & PF_KTHREAD)) { if (!copy_fpregs_to_fpstate(old_fpu)) old_fpu->last_cpu = -1; else @@ -590,10 +583,11 @@ * Load PKRU from the FPU context if available. Delay loading of the * complete FPU state until the return to userland. */ -static inline void switch_fpu_finish(struct fpu *new_fpu) +static inline void switch_fpu_finish(struct task_struct *next) { u32 pkru_val = init_pkru_value; struct pkru_state *pk; + struct fpu *next_fpu = &next->thread.fpu; if (!static_cpu_has(X86_FEATURE_FPU)) return; @@ -607,10 +601,17 @@ * PKRU state is switched eagerly because it needs to be valid before we * return to userland e.g. for a copy_to_user() operation. */ - if (current->mm) { - pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); - if (pk) - pkru_val = pk->pkru; + if (!(next->flags & PF_KTHREAD)) { + /* + * If the PKRU bit in xsave.header.xfeatures is not set, + * then the PKRU component was in init state, which means + * XRSTOR will set PKRU to 0. If the bit is not set then + * get_xsave_addr() will return NULL because the PKRU value + * in memory is not valid. This means pkru_val has to be + * set to 0 and not to init_pkru_value. + */ + pk = get_xsave_addr(&next_fpu->state.xsave, XFEATURE_PKRU); + pkru_val = pk ? pk->pkru : 0; } __write_pkru(pkru_val); } @@ -619,6 +620,11 @@ * MXCSR and XCR definitions: */ +static inline void ldmxcsr(u32 mxcsr) +{ + asm volatile("ldmxcsr %0" :: "m" (mxcsr)); +} + extern unsigned int mxcsr_feature_mask; #define XCR_XFEATURE_ENABLED_MASK 0x00000000 --- linux-oracle-5.4.0.orig/arch/x86/include/asm/hyperv-tlfs.h +++ linux-oracle-5.4.0/arch/x86/include/asm/hyperv-tlfs.h @@ -721,7 +721,7 @@ u64 guest_rip; u32 hv_clean_fields; - u32 hv_padding_32; + u32 padding32_1; u32 hv_synthetic_controls; struct { u32 nested_flush_hypercall:1; @@ -729,7 +729,7 @@ u32 reserved:30; } __packed hv_enlightenments_control; u32 hv_vp_id; - + u32 padding32_2; u64 hv_vm_id; u64 partition_assist_page; u64 padding64_4[4]; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/i8259.h +++ linux-oracle-5.4.0/arch/x86/include/asm/i8259.h @@ -67,6 +67,8 @@ void (*make_irq)(unsigned int irq); }; +void legacy_pic_pcat_compat(void); + extern struct legacy_pic *legacy_pic; extern struct legacy_pic null_legacy_pic; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/insn.h +++ linux-oracle-5.4.0/arch/x86/include/asm/insn.h @@ -45,6 +45,7 @@ struct insn_field immediate2; /* for 64bit imm or seg16 */ }; + int emulate_prefix_size; insn_attr_t attr; unsigned char opnd_bytes; unsigned char addr_bytes; @@ -128,6 +129,11 @@ return (insn->vex_prefix.nbytes == 4); } +static inline int insn_has_emulate_prefix(struct insn *insn) +{ + return !!insn->emulate_prefix_size; +} + /* Ensure this instruction is decoded completely */ static inline int insn_complete(struct insn *insn) { @@ -195,6 +201,21 @@ return insn_offset_displacement(insn) + insn->displacement.nbytes; } +/** + * for_each_insn_prefix() -- Iterate prefixes in the instruction + * @insn: Pointer to struct insn. + * @idx: Index storage. + * @prefix: Prefix byte. + * + * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix + * and the index is stored in @idx (note that this @idx is just for a cursor, + * do not change it.) + * Since prefixes.nbytes can be bigger than 4 if some prefixes + * are repeated, it cannot be used for looping over the prefixes. + */ +#define for_each_insn_prefix(insn, idx, prefix) \ + for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) + #define POP_SS_OPCODE 0x1f #define MOV_SREG_OPCODE 0x8e --- linux-oracle-5.4.0.orig/arch/x86/include/asm/intel-family.h +++ linux-oracle-5.4.0/arch/x86/include/asm/intel-family.h @@ -35,6 +35,9 @@ * The #define line may optionally include a comment including platform names. */ +/* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */ +#define INTEL_FAM6_ANY X86_MODEL_ANY + #define INTEL_FAM6_CORE_YONAH 0x0E #define INTEL_FAM6_CORE2_MEROM 0x0F @@ -86,6 +89,19 @@ #define INTEL_FAM6_COMETLAKE 0xA5 #define INTEL_FAM6_COMETLAKE_L 0xA6 +#define INTEL_FAM6_ROCKETLAKE 0xA7 + +/* Hybrid Core/Atom Processors */ + +#define INTEL_FAM6_LAKEFIELD 0x8A +#define INTEL_FAM6_ALDERLAKE 0x97 +#define INTEL_FAM6_ALDERLAKE_L 0x9A +#define INTEL_FAM6_ALDERLAKE_N 0xBE + +#define INTEL_FAM6_RAPTORLAKE 0xB7 +#define INTEL_FAM6_RAPTORLAKE_P 0xBA +#define INTEL_FAM6_RAPTORLAKE_S 0xBF + /* "Small Core" Processors (Atom) */ #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ @@ -111,12 +127,16 @@ #define INTEL_FAM6_ATOM_TREMONT_D 0x86 /* Jacobsville */ #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */ +#define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */ /* Xeon Phi */ #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ #define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */ +/* Family 5 */ +#define INTEL_FAM5_QUARK_X1000 0x09 /* Quark X1000 SoC */ + /* Useful macros */ #define INTEL_CPU_FAM_ANY(_family, _model, _driver_data) \ { \ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/kasan.h +++ linux-oracle-5.4.0/arch/x86/include/asm/kasan.h @@ -28,9 +28,12 @@ #ifdef CONFIG_KASAN void __init kasan_early_init(void); void __init kasan_init(void); +void __init kasan_populate_shadow_for_vaddr(void *va, size_t size, int nid); #else static inline void kasan_early_init(void) { } static inline void kasan_init(void) { } +static inline void kasan_populate_shadow_for_vaddr(void *va, size_t size, + int nid) { } #endif #endif --- linux-oracle-5.4.0.orig/arch/x86/include/asm/kexec.h +++ linux-oracle-5.4.0/arch/x86/include/asm/kexec.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -201,6 +202,14 @@ extern void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages); #define arch_kexec_pre_free_pages arch_kexec_pre_free_pages +#ifdef CONFIG_KEXEC_FILE +struct purgatory_info; +int arch_kexec_apply_relocations_add(struct purgatory_info *pi, + Elf_Shdr *section, + const Elf_Shdr *relsec, + const Elf_Shdr *symtab); +#define arch_kexec_apply_relocations_add arch_kexec_apply_relocations_add +#endif #endif typedef void crash_vmclear_fn(void); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/kvm_host.h +++ linux-oracle-5.4.0/arch/x86/include/asm/kvm_host.h @@ -380,19 +380,17 @@ void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long root); unsigned long (*get_cr3)(struct kvm_vcpu *vcpu); u64 (*get_pdptr)(struct kvm_vcpu *vcpu, int index); - int (*page_fault)(struct kvm_vcpu *vcpu, gva_t gva, u32 err, + int (*page_fault)(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u32 err, bool prefault); void (*inject_page_fault)(struct kvm_vcpu *vcpu, struct x86_exception *fault); - gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access, - struct x86_exception *exception); + gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gpa_t gva_or_gpa, + u32 access, struct x86_exception *exception); gpa_t (*translate_gpa)(struct kvm_vcpu *vcpu, gpa_t gpa, u32 access, struct x86_exception *exception); int (*sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp); void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva, hpa_t root_hpa); - void (*update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, - u64 *spte, const void *pte); hpa_t root_hpa; gpa_t root_cr3; union kvm_mmu_role mmu_role; @@ -550,6 +548,7 @@ unsigned long cr4; unsigned long cr4_guest_owned_bits; unsigned long cr8; + u32 host_pkru; u32 pkru; u32 hflags; u64 efer; @@ -564,6 +563,7 @@ u64 ia32_misc_enable_msr; u64 smbase; u64 smi_count; + bool at_instruction_boundary; bool tpr_access_reporting; u64 ia32_xss; u64 microcode_version; @@ -667,10 +667,10 @@ bool pvclock_set_guest_stopped_request; struct { + u8 preempted; u64 msr_val; u64 last_steal; - struct gfn_to_hva_cache stime; - struct kvm_steal_time steal; + struct gfn_to_pfn_cache cache; } st; u64 tsc_offset; @@ -943,7 +943,6 @@ struct kvm_vm_stat { ulong mmu_shadow_zapped; ulong mmu_pte_write; - ulong mmu_pte_updated; ulong mmu_pde_zapped; ulong mmu_flooded; ulong mmu_recycled; @@ -983,6 +982,8 @@ u64 irq_injections; u64 nmi_injections; u64 req_event; + u64 preemption_reported; + u64 preemption_other; }; struct x86_instruction_info; @@ -1098,7 +1099,7 @@ void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu); void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); - void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); + int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr); @@ -1128,8 +1129,9 @@ bool (*xsaves_supported)(void); bool (*umip_emulated)(void); bool (*pt_supported)(void); + bool (*pku_supported)(void); - int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); + int (*check_nested_events)(struct kvm_vcpu *vcpu); void (*request_immediate_exit)(struct kvm_vcpu *vcpu); void (*sched_in)(struct kvm_vcpu *kvm, int cpu); @@ -1158,7 +1160,7 @@ void (*enable_log_dirty_pt_masked)(struct kvm *kvm, struct kvm_memory_slot *slot, gfn_t offset, unsigned long mask); - int (*write_log_dirty)(struct kvm_vcpu *vcpu); + int (*write_log_dirty)(struct kvm_vcpu *vcpu, gpa_t l2_gpa); /* pmu operations of sub-arch */ const struct kvm_pmu_ops *pmu_ops; @@ -1450,7 +1452,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); -int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u64 error_code, +int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, u64 error_code, void *insn, int insn_len); void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t gva, unsigned long pcid); @@ -1551,12 +1553,14 @@ _ASM_EXTABLE(666b, 667b) #define KVM_ARCH_WANT_MMU_NOTIFIER -int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end); +int kvm_unmap_hva_range(struct kvm *kvm, unsigned long start, unsigned long end, + unsigned flags); int kvm_age_hva(struct kvm *kvm, unsigned long start, unsigned long end); int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); +int kvm_cpu_has_extint(struct kvm_vcpu *v); int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event); @@ -1607,8 +1611,8 @@ static inline bool kvm_irq_is_postable(struct kvm_lapic_irq *irq) { /* We can only post Fixed and LowPrio IRQs */ - return (irq->delivery_mode == dest_Fixed || - irq->delivery_mode == dest_LowestPrio); + return (irq->delivery_mode == APIC_DM_FIXED || + irq->delivery_mode == APIC_DM_LOWEST); } static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) --- linux-oracle-5.4.0.orig/arch/x86/include/asm/kvm_para.h +++ linux-oracle-5.4.0/arch/x86/include/asm/kvm_para.h @@ -6,8 +6,6 @@ #include #include -extern void kvmclock_init(void); - #ifdef CONFIG_KVM_GUEST bool kvm_check_and_clear_guest_paused(void); #else @@ -85,13 +83,14 @@ } #ifdef CONFIG_KVM_GUEST +void kvmclock_init(void); +void kvmclock_disable(void); bool kvm_para_available(void); unsigned int kvm_arch_para_features(void); unsigned int kvm_arch_para_hints(void); void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); void kvm_async_pf_task_wake(u32 token); u32 kvm_read_and_reset_pf_reason(void); -extern void kvm_disable_steal_time(void); void do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address); #ifdef CONFIG_PARAVIRT_SPINLOCKS @@ -126,10 +125,6 @@ return 0; } -static inline void kvm_disable_steal_time(void) -{ - return; -} #endif #endif /* _ASM_X86_KVM_PARA_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/kvmclock.h +++ linux-oracle-5.4.0/arch/x86/include/asm/kvmclock.h @@ -2,6 +2,20 @@ #ifndef _ASM_X86_KVM_CLOCK_H #define _ASM_X86_KVM_CLOCK_H +#include + extern struct clocksource kvm_clock; +DECLARE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu); + +static inline struct pvclock_vcpu_time_info *this_cpu_pvti(void) +{ + return &this_cpu_read(hv_clock_per_cpu)->pvti; +} + +static inline struct pvclock_vsyscall_time_info *this_cpu_hvclock(void) +{ + return this_cpu_read(hv_clock_per_cpu); +} + #endif /* _ASM_X86_KVM_CLOCK_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/linkage.h +++ linux-oracle-5.4.0/arch/x86/include/asm/linkage.h @@ -13,9 +13,13 @@ #ifdef __ASSEMBLY__ -#define GLOBAL(name) \ - .globl name; \ - name: +/* + * GLOBAL is DEPRECATED + * + * use SYM_DATA_START, SYM_FUNC_START, SYM_INNER_LABEL, SYM_CODE_START, or + * similar + */ +#define GLOBAL(name) SYM_ENTRY(name, SYM_L_GLOBAL, SYM_A_NONE) #if defined(CONFIG_X86_64) || defined(CONFIG_X86_ALIGNMENT_16) #define __ALIGN .p2align 4, 0x90 --- linux-oracle-5.4.0.orig/arch/x86/include/asm/mce.h +++ linux-oracle-5.4.0/arch/x86/include/asm/mce.h @@ -290,6 +290,7 @@ /* These may be used by multiple smca_hwid_mcatypes */ enum smca_bank_types { SMCA_LS = 0, /* Load Store */ + SMCA_LS_V2, /* Load Store */ SMCA_IF, /* Instruction Fetch */ SMCA_L2_CACHE, /* L2 Cache */ SMCA_DE, /* Decoder Unit */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/mem_encrypt.h +++ linux-oracle-5.4.0/arch/x86/include/asm/mem_encrypt.h @@ -43,13 +43,13 @@ int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size); int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size); -/* Architecture __weak replacement functions */ -void __init mem_encrypt_init(void); void __init mem_encrypt_free_decrypted_mem(void); bool sme_active(void); bool sev_active(void); +void __init mem_encrypt_init(void); + #define __bss_decrypted __attribute__((__section__(".bss..decrypted"))) #else /* !CONFIG_AMD_MEM_ENCRYPT */ @@ -77,6 +77,8 @@ static inline int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; } +static inline void mem_encrypt_init(void) { } + #define __bss_decrypted #endif /* CONFIG_AMD_MEM_ENCRYPT */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/microcode.h +++ linux-oracle-5.4.0/arch/x86/include/asm/microcode.h @@ -5,10 +5,12 @@ #include #include #include +#include struct ucode_patch { struct list_head plist; void *data; /* Intel uses only this one */ + unsigned int size; u32 patch_id; u16 equiv_cpu; }; @@ -130,14 +132,16 @@ int __init microcode_init(void); extern void __init load_ucode_bsp(void); extern void load_ucode_ap(void); -void reload_early_microcode(void); +void reload_early_microcode(unsigned int cpu); extern bool get_builtin_firmware(struct cpio_data *cd, const char *name); extern bool initrd_gone; +void microcode_bsp_resume(void); #else static inline int __init microcode_init(void) { return 0; }; static inline void __init load_ucode_bsp(void) { } static inline void load_ucode_ap(void) { } -static inline void reload_early_microcode(void) { } +static inline void reload_early_microcode(unsigned int cpu) { } +static inline void microcode_bsp_resume(void) { } static inline bool get_builtin_firmware(struct cpio_data *cd, const char *name) { return false; } #endif --- linux-oracle-5.4.0.orig/arch/x86/include/asm/microcode_amd.h +++ linux-oracle-5.4.0/arch/x86/include/asm/microcode_amd.h @@ -41,18 +41,20 @@ unsigned int mpb[0]; }; -#define PATCH_MAX_SIZE PAGE_SIZE +#define PATCH_MAX_SIZE (3 * PAGE_SIZE) #ifdef CONFIG_MICROCODE_AMD extern void __init load_ucode_amd_bsp(unsigned int family); extern void load_ucode_amd_ap(unsigned int family); extern int __init save_microcode_in_initrd_amd(unsigned int family); -void reload_ucode_amd(void); +void reload_ucode_amd(unsigned int cpu); +extern void amd_check_microcode(void); #else static inline void __init load_ucode_amd_bsp(unsigned int family) {} static inline void load_ucode_amd_ap(unsigned int family) {} static inline int __init save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } -void reload_ucode_amd(void) {} +static inline void reload_ucode_amd(unsigned int cpu) {} +static inline void amd_check_microcode(void) {} #endif #endif /* _ASM_X86_MICROCODE_AMD_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/mmu_context.h +++ linux-oracle-5.4.0/arch/x86/include/asm/mmu_context.h @@ -379,6 +379,15 @@ temp_mm_state_t temp_state; lockdep_assert_irqs_disabled(); + + /* + * Make sure not to be in TLB lazy mode, as otherwise we'll end up + * with a stale address space WITHOUT being in lazy mode after + * restoring the previous mm. + */ + if (this_cpu_read(cpu_tlbstate.is_lazy)) + leave_mm(smp_processor_id()); + temp_state.mm = this_cpu_read(cpu_tlbstate.loaded_mm); switch_mm_irqs_off(NULL, mm, current); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/msr-index.h +++ linux-oracle-5.4.0/arch/x86/include/asm/msr-index.h @@ -30,6 +30,7 @@ #define _EFER_SVME 12 /* Enable virtualization */ #define _EFER_LMSLE 13 /* Long Mode Segment Limit Enable */ #define _EFER_FFXSR 14 /* Enable Fast FXSAVE/FXRSTOR */ +#define _EFER_AUTOIBRS 21 /* Enable Automatic IBRS */ #define EFER_SCE (1<<_EFER_SCE) #define EFER_LME (1<<_EFER_LME) @@ -38,6 +39,7 @@ #define EFER_SVME (1<<_EFER_SVME) #define EFER_LMSLE (1<<_EFER_LMSLE) #define EFER_FFXSR (1<<_EFER_FFXSR) +#define EFER_AUTOIBRS (1<<_EFER_AUTOIBRS) /* Intel MSRs. Some also available on other CPUs */ @@ -47,6 +49,15 @@ #define SPEC_CTRL_STIBP BIT(SPEC_CTRL_STIBP_SHIFT) /* STIBP mask */ #define SPEC_CTRL_SSBD_SHIFT 2 /* Speculative Store Bypass Disable bit */ #define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */ +#define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */ +#define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT) +#define SPEC_CTRL_BHI_DIS_S_SHIFT 10 /* Disable Branch History Injection behavior */ +#define SPEC_CTRL_BHI_DIS_S BIT(SPEC_CTRL_BHI_DIS_S_SHIFT) + +/* A mask for bits which the kernel toggles when controlling mitigations */ +#define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \ + | SPEC_CTRL_RRSBA_DIS_S \ + | SPEC_CTRL_BHI_DIS_S) #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ @@ -82,6 +93,7 @@ #define MSR_IA32_ARCH_CAPABILITIES 0x0000010a #define ARCH_CAP_RDCL_NO BIT(0) /* Not susceptible to Meltdown */ #define ARCH_CAP_IBRS_ALL BIT(1) /* Enhanced IBRS support */ +#define ARCH_CAP_RSBA BIT(2) /* RET may use alternative branch predictors */ #define ARCH_CAP_SKIP_VMENTRY_L1DFLUSH BIT(3) /* Skip L1D flush on vmentry */ #define ARCH_CAP_SSB_NO BIT(4) /* * Not susceptible to Speculative Store Bypass @@ -105,6 +117,54 @@ * Not susceptible to * TSX Async Abort (TAA) vulnerabilities. */ +#define ARCH_CAP_SBDR_SSDP_NO BIT(13) /* + * Not susceptible to SBDR and SSDP + * variants of Processor MMIO stale data + * vulnerabilities. + */ +#define ARCH_CAP_FBSDP_NO BIT(14) /* + * Not susceptible to FBSDP variant of + * Processor MMIO stale data + * vulnerabilities. + */ +#define ARCH_CAP_PSDP_NO BIT(15) /* + * Not susceptible to PSDP variant of + * Processor MMIO stale data + * vulnerabilities. + */ +#define ARCH_CAP_FB_CLEAR BIT(17) /* + * VERW clears CPU fill buffer + * even on MDS_NO CPUs. + */ +#define ARCH_CAP_FB_CLEAR_CTRL BIT(18) /* + * MSR_IA32_MCU_OPT_CTRL[FB_CLEAR_DIS] + * bit available to control VERW + * behavior. + */ +#define ARCH_CAP_RRSBA BIT(19) /* + * Indicates RET may use predictors + * other than the RSB. With eIBRS + * enabled predictions in kernel mode + * are restricted to targets in + * kernel. + */ +#define ARCH_CAP_BHI_NO BIT(20) /* + * CPU is not affected by Branch + * History Injection. + */ +#define ARCH_CAP_PBRSB_NO BIT(24) /* + * Not susceptible to Post-Barrier + * Return Stack Buffer Predictions. + */ +#define ARCH_CAP_GDS_CTRL BIT(25) /* + * CPU is vulnerable to Gather + * Data Sampling (GDS) and + * has controls for mitigation. + */ +#define ARCH_CAP_GDS_NO BIT(26) /* + * CPU is not vulnerable to Gather + * Data Sampling (GDS). + */ #define MSR_IA32_FLUSH_CMD 0x0000010b #define L1D_FLUSH BIT(0) /* @@ -119,6 +179,13 @@ #define TSX_CTRL_RTM_DISABLE BIT(0) /* Disable RTM feature */ #define TSX_CTRL_CPUID_CLEAR BIT(1) /* Disable TSX enumeration */ +/* SRBDS support */ +#define MSR_IA32_MCU_OPT_CTRL 0x00000123 +#define RNGDS_MITG_DIS BIT(0) +#define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */ +#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */ +#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */ + #define MSR_IA32_SYSENTER_CS 0x00000174 #define MSR_IA32_SYSENTER_ESP 0x00000175 #define MSR_IA32_SYSENTER_EIP 0x00000176 @@ -411,6 +478,13 @@ #define MSR_AMD64_OSVW_STATUS 0xc0010141 #define MSR_AMD64_LS_CFG 0xc0011020 #define MSR_AMD64_DC_CFG 0xc0011022 +#define MSR_AMD64_TW_CFG 0xc0011023 + +#define MSR_AMD64_DE_CFG 0xc0011029 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) +#define MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT 9 + #define MSR_AMD64_BU_CFG2 0xc001102a #define MSR_AMD64_IBSFETCHCTL 0xc0011030 #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 @@ -428,14 +502,20 @@ #define MSR_AMD64_IBSOP_REG_MASK ((1UL< +#include #include #include #include #include +#include +#include +#include +#include /* * This should be used immediately before a retpoline alternative. It tells * objtool where the retpolines are so that it can make sense of the control @@ -44,24 +49,44 @@ * the optimal version — two calls, each with their own speculation * trap should their return address end up getting used, in a loop. */ +#ifdef CONFIG_X86_64 #define __FILL_RETURN_BUFFER(reg, nr, sp) \ mov $(nr/2), reg; \ 771: \ + ANNOTATE_INTRA_FUNCTION_CALL; \ call 772f; \ 773: /* speculation trap */ \ + UNWIND_HINT_EMPTY; \ pause; \ lfence; \ jmp 773b; \ 772: \ + ANNOTATE_INTRA_FUNCTION_CALL; \ call 774f; \ 775: /* speculation trap */ \ + UNWIND_HINT_EMPTY; \ pause; \ lfence; \ jmp 775b; \ 774: \ + add $(BITS_PER_LONG/8) * 2, sp; \ dec reg; \ jnz 771b; \ + /* barrier for jnz misprediction */ \ + lfence; +#else +/* + * i386 doesn't unconditionally have LFENCE, as such it can't + * do a loop. + */ +#define __FILL_RETURN_BUFFER(reg, nr, sp) \ + .rept nr; \ + call 772f; \ + int3; \ +772:; \ + .endr; \ add $(BITS_PER_LONG/8) * nr, sp; +#endif #ifdef __ASSEMBLY__ @@ -115,7 +140,7 @@ ANNOTATE_NOSPEC_ALTERNATIVE ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *\reg), \ __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ - __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_AMD + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *\reg), X86_FEATURE_RETPOLINE_LFENCE #else jmp *\reg #endif @@ -126,26 +151,50 @@ ANNOTATE_NOSPEC_ALTERNATIVE ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *\reg), \ __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ - __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_AMD + __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *\reg), X86_FEATURE_RETPOLINE_LFENCE #else call *\reg #endif .endm +.macro ISSUE_UNBALANCED_RET_GUARD + ANNOTATE_INTRA_FUNCTION_CALL; + call .Lunbalanced_ret_guard_\@ + int3 +.Lunbalanced_ret_guard_\@: + add $(BITS_PER_LONG/8), %_ASM_SP + lfence +.endm + /* * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP * monstrosity above, manually. */ -.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req -#ifdef CONFIG_RETPOLINE - ANNOTATE_NOSPEC_ALTERNATIVE - ALTERNATIVE "jmp .Lskip_rsb_\@", \ - __stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)) \ - \ftr +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req ftr2 +.ifb \ftr2 + ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr +.else + ALTERNATIVE_2 "jmp .Lskip_rsb_\@", "", \ftr, "jmp .Lunbalanced_\@", \ftr2 +.endif + __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP) +.Lunbalanced_\@: + ISSUE_UNBALANCED_RET_GUARD .Lskip_rsb_\@: -#endif .endm +#ifdef CONFIG_X86_64 +.macro CLEAR_BRANCH_HISTORY + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP +.endm + +.macro CLEAR_BRANCH_HISTORY_VMEXIT + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT +.endm +#else +#define CLEAR_BRANCH_HISTORY +#define CLEAR_BRANCH_HISTORY_VMEXIT +#endif + #else /* __ASSEMBLY__ */ #define ANNOTATE_RETPOLINE_SAFE \ @@ -154,6 +203,10 @@ _ASM_PTR " 999b\n\t" \ ".popsection\n\t" +#ifdef CONFIG_X86_64 +extern void clear_bhb_loop(void); +#endif + #ifdef CONFIG_RETPOLINE #ifdef CONFIG_X86_64 @@ -171,7 +224,7 @@ "lfence;\n" \ ANNOTATE_RETPOLINE_SAFE \ "call *%[thunk_target]\n", \ - X86_FEATURE_RETPOLINE_AMD) + X86_FEATURE_RETPOLINE_LFENCE) # define THUNK_TARGET(addr) [thunk_target] "r" (addr) #else /* CONFIG_X86_32 */ @@ -201,7 +254,7 @@ "lfence;\n" \ ANNOTATE_RETPOLINE_SAFE \ "call *%[thunk_target]\n", \ - X86_FEATURE_RETPOLINE_AMD) + X86_FEATURE_RETPOLINE_LFENCE) # define THUNK_TARGET(addr) [thunk_target] "rm" (addr) #endif @@ -213,9 +266,12 @@ /* The Spectre V2 mitigation variants */ enum spectre_v2_mitigation { SPECTRE_V2_NONE, - SPECTRE_V2_RETPOLINE_GENERIC, - SPECTRE_V2_RETPOLINE_AMD, - SPECTRE_V2_IBRS_ENHANCED, + SPECTRE_V2_RETPOLINE, + SPECTRE_V2_LFENCE, + SPECTRE_V2_EIBRS, + SPECTRE_V2_EIBRS_RETPOLINE, + SPECTRE_V2_EIBRS_LFENCE, + SPECTRE_V2_IBRS, }; /* The indirect branch speculation control variants */ @@ -279,6 +335,9 @@ /* The Intel SPEC CTRL MSR base value cache */ extern u64 x86_spec_ctrl_base; +DECLARE_PER_CPU(u64, x86_spec_ctrl_current); +extern void update_spec_ctrl_cond(u64 val); +extern u64 spec_ctrl_current(void); /* * With retpoline, we must use IBRS to restrict branch prediction @@ -288,18 +347,16 @@ */ #define firmware_restrict_branch_speculation_start() \ do { \ - u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS; \ - \ preempt_disable(); \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, \ + spec_ctrl_current() | SPEC_CTRL_IBRS, \ X86_FEATURE_USE_IBRS_FW); \ } while (0) #define firmware_restrict_branch_speculation_end() \ do { \ - u64 val = x86_spec_ctrl_base; \ - \ - alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, \ + spec_ctrl_current(), \ X86_FEATURE_USE_IBRS_FW); \ preempt_enable(); \ } while (0) @@ -311,6 +368,8 @@ DECLARE_STATIC_KEY_FALSE(mds_user_clear); DECLARE_STATIC_KEY_FALSE(mds_idle_clear); +DECLARE_STATIC_KEY_FALSE(mmio_stale_data_clear); + #include /** @@ -320,7 +379,7 @@ * combination with microcode which triggers a CPU buffer flush when the * instruction is executed. */ -static inline void mds_clear_cpu_buffers(void) +static __always_inline void mds_clear_cpu_buffers(void) { static const u16 ds = __KERNEL_DS; @@ -341,7 +400,7 @@ * * Clear CPU buffers if the corresponding static key is enabled */ -static inline void mds_user_clear_cpu_buffers(void) +static __always_inline void mds_user_clear_cpu_buffers(void) { if (static_branch_likely(&mds_user_clear)) mds_clear_cpu_buffers(); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/numa.h +++ linux-oracle-5.4.0/arch/x86/include/asm/numa.h @@ -11,13 +11,6 @@ #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) -/* - * Too small node sizes may confuse the VM badly. Usually they - * result from BIOS bugs. So dont recognize nodes as standalone - * NUMA entities that have less than this amount of RAM listed: - */ -#define NODE_MIN_SIZE (4*1024*1024) - extern int numa_off; /* --- linux-oracle-5.4.0.orig/arch/x86/include/asm/page_64_types.h +++ linux-oracle-5.4.0/arch/x86/include/asm/page_64_types.h @@ -15,7 +15,7 @@ #define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) -#define EXCEPTION_STACK_ORDER (0 + KASAN_STACK_ORDER) +#define EXCEPTION_STACK_ORDER (1 + KASAN_STACK_ORDER) #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) #define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER) --- linux-oracle-5.4.0.orig/arch/x86/include/asm/pci-direct.h +++ linux-oracle-5.4.0/arch/x86/include/asm/pci-direct.h @@ -10,9 +10,11 @@ extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset); extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset); extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset); +extern u32 pci_early_find_cap(int bus, int slot, int func, int cap); extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val); extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val); extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val); +extern unsigned int pci_early_clear_msi; extern int early_pci_allowed(void); #endif /* _ASM_X86_PCI_DIRECT_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/pgtable.h +++ linux-oracle-5.4.0/arch/x86/include/asm/pgtable.h @@ -253,6 +253,7 @@ } #ifdef CONFIG_TRANSPARENT_HUGEPAGE +/* NOTE: when predicate huge page, consider also pmd_devmap, or use pmd_large */ static inline int pmd_trans_huge(pmd_t pmd) { return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE; @@ -624,12 +625,15 @@ return __pmd(val); } -/* mprotect needs to preserve PAT bits when updating vm_page_prot */ +/* + * mprotect needs to preserve PAT and encryption bits when updating + * vm_page_prot + */ #define pgprot_modify pgprot_modify static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) { pgprotval_t preservebits = pgprot_val(oldprot) & _PAGE_CHG_MASK; - pgprotval_t addbits = pgprot_val(newprot); + pgprotval_t addbits = pgprot_val(newprot) & ~_PAGE_CHG_MASK; return __pgprot(preservebits | addbits); } @@ -1371,8 +1375,8 @@ #endif #endif -#define PKRU_AD_BIT 0x1 -#define PKRU_WD_BIT 0x2 +#define PKRU_AD_BIT 0x1u +#define PKRU_WD_BIT 0x2u #define PKRU_BITS_PER_PKEY 2 #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS --- linux-oracle-5.4.0.orig/arch/x86/include/asm/pgtable_32_types.h +++ linux-oracle-5.4.0/arch/x86/include/asm/pgtable_32_types.h @@ -44,11 +44,11 @@ * Define this here and validate with BUILD_BUG_ON() in pgtable_32.c * to avoid include recursion hell */ -#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 40) +#define CPU_ENTRY_AREA_PAGES (NR_CPUS * 39) -#define CPU_ENTRY_AREA_BASE \ - ((FIXADDR_TOT_START - PAGE_SIZE * (CPU_ENTRY_AREA_PAGES + 1)) \ - & PMD_MASK) +/* The +1 is for the readonly IDT page: */ +#define CPU_ENTRY_AREA_BASE \ + ((FIXADDR_TOT_START - PAGE_SIZE*(CPU_ENTRY_AREA_PAGES+1)) & PMD_MASK) #define LDT_BASE_ADDR \ ((CPU_ENTRY_AREA_BASE - PAGE_SIZE) & PMD_MASK) --- linux-oracle-5.4.0.orig/arch/x86/include/asm/pgtable_types.h +++ linux-oracle-5.4.0/arch/x86/include/asm/pgtable_types.h @@ -123,7 +123,7 @@ */ #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_SOFT_DIRTY | _PAGE_DEVMAP) + _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC) #define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE) /* @@ -147,6 +147,7 @@ #endif #define _PAGE_CACHE_MASK (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT) +#define _PAGE_LARGE_CACHE_MASK (_PAGE_PWT | _PAGE_PCD | _PAGE_PAT_LARGE) #define _PAGE_NOCACHE (cachemode2protval(_PAGE_CACHE_MODE_UC)) #define _PAGE_CACHE_WP (cachemode2protval(_PAGE_CACHE_MODE_WP)) --- linux-oracle-5.4.0.orig/arch/x86/include/asm/pkeys.h +++ linux-oracle-5.4.0/arch/x86/include/asm/pkeys.h @@ -4,6 +4,11 @@ #define ARCH_DEFAULT_PKEY 0 +/* + * If more than 16 keys are ever supported, a thorough audit + * will be necessary to ensure that the types that store key + * numbers and masks have sufficient capacity. + */ #define arch_max_pkey() (boot_cpu_has(X86_FEATURE_OSPKE) ? 16 : 1) extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, --- linux-oracle-5.4.0.orig/arch/x86/include/asm/processor.h +++ linux-oracle-5.4.0/arch/x86/include/asm/processor.h @@ -334,7 +334,7 @@ #define INVALID_IO_BITMAP_OFFSET 0x8000 struct entry_stack { - unsigned long words[64]; + char stack[PAGE_SIZE]; }; struct entry_stack_page { @@ -487,7 +487,6 @@ mm_segment_t addr_limit; - unsigned int sig_on_uaccess_err:1; unsigned int uaccess_err:1; /* uaccess failed */ /* Floating point and extended processor state */ @@ -507,15 +506,6 @@ } /* - * Thread-synchronous status. - * - * This is different from the flags in that nobody else - * ever touches our thread-synchronous status, so we don't - * have to worry about atomic accesses. - */ -#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ - -/* * Set IOPL bits in EFLAGS from given mask */ static inline void native_set_iopl_mask(unsigned mask) @@ -936,9 +926,11 @@ #ifdef CONFIG_CPU_SUP_AMD extern u16 amd_get_nb_id(int cpu); extern u32 amd_get_nodes_per_socket(void); +extern void amd_clear_divider(void); #else static inline u16 amd_get_nb_id(int cpu) { return 0; } static inline u32 amd_get_nodes_per_socket(void) { return 0; } +static inline void amd_clear_divider(void) { } #endif static inline uint32_t hypervisor_cpuid_base(const char *sig, uint32_t leaves) @@ -995,4 +987,6 @@ TAA_MITIGATION_TSX_DISABLED, }; +extern bool gds_ucode_mitigated(void); + #endif /* _ASM_X86_PROCESSOR_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/proto.h +++ linux-oracle-5.4.0/arch/x86/include/asm/proto.h @@ -4,6 +4,8 @@ #include +struct task_struct; + /* misc architecture specific prototypes */ void syscall_init(void); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/ptrace.h +++ linux-oracle-5.4.0/arch/x86/include/asm/ptrace.h @@ -309,8 +309,8 @@ static const unsigned int argument_offs[] = { #ifdef __i386__ offsetof(struct pt_regs, ax), - offsetof(struct pt_regs, cx), offsetof(struct pt_regs, dx), + offsetof(struct pt_regs, cx), #define NR_REG_ARGUMENTS 3 #else offsetof(struct pt_regs, di), --- linux-oracle-5.4.0.orig/arch/x86/include/asm/realmode.h +++ linux-oracle-5.4.0/arch/x86/include/asm/realmode.h @@ -82,6 +82,7 @@ } void reserve_real_mode(void); +void load_trampoline_pgtable(void); #endif /* __ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/reboot.h +++ linux-oracle-5.4.0/arch/x86/include/asm/reboot.h @@ -25,6 +25,8 @@ #define MRR_BIOS 0 #define MRR_APM 1 +void cpu_emergency_disable_virtualization(void); + typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); void nmi_panic_self_stop(struct pt_regs *regs); void nmi_shootdown_cpus(nmi_shootdown_cb callback); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/required-features.h +++ linux-oracle-5.4.0/arch/x86/include/asm/required-features.h @@ -101,6 +101,9 @@ #define REQUIRED_MASK16 0 #define REQUIRED_MASK17 0 #define REQUIRED_MASK18 0 -#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) +#define REQUIRED_MASK19 0 +#define REQUIRED_MASK20 0 +#define REQUIRED_MASK21 0 +#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22) #endif /* _ASM_X86_REQUIRED_FEATURES_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/resctrl_sched.h +++ linux-oracle-5.4.0/arch/x86/include/asm/resctrl_sched.h @@ -51,24 +51,27 @@ * simple as possible. * Must be called with preemption disabled. */ -static void __resctrl_sched_in(void) +static inline void __resctrl_sched_in(struct task_struct *tsk) { struct resctrl_pqr_state *state = this_cpu_ptr(&pqr_state); u32 closid = state->default_closid; u32 rmid = state->default_rmid; + u32 tmp; /* * If this task has a closid/rmid assigned, use it. * Else use the closid/rmid assigned to this cpu. */ if (static_branch_likely(&rdt_alloc_enable_key)) { - if (current->closid) - closid = current->closid; + tmp = READ_ONCE(tsk->closid); + if (tmp) + closid = tmp; } if (static_branch_likely(&rdt_mon_enable_key)) { - if (current->rmid) - rmid = current->rmid; + tmp = READ_ONCE(tsk->rmid); + if (tmp) + rmid = tmp; } if (closid != state->cur_closid || rmid != state->cur_rmid) { @@ -78,15 +81,15 @@ } } -static inline void resctrl_sched_in(void) +static inline void resctrl_sched_in(struct task_struct *tsk) { if (static_branch_likely(&rdt_enable_key)) - __resctrl_sched_in(); + __resctrl_sched_in(tsk); } #else -static inline void resctrl_sched_in(void) {} +static inline void resctrl_sched_in(struct task_struct *tsk) {} #endif /* CONFIG_X86_CPU_RESCTRL */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/segment.h +++ linux-oracle-5.4.0/arch/x86/include/asm/segment.h @@ -31,6 +31,18 @@ */ #define SEGMENT_RPL_MASK 0x3 +/* + * When running on Xen PV, the actual privilege level of the kernel is 1, + * not 0. Testing the Requested Privilege Level in a segment selector to + * determine whether the context is user mode or kernel mode with + * SEGMENT_RPL_MASK is wrong because the PV kernel's privilege level + * matches the 0x3 mask. + * + * Testing with USER_SEGMENT_RPL_MASK is valid for both native and Xen PV + * kernels because privilege level 2 is never used. + */ +#define USER_SEGMENT_RPL_MASK 0x2 + /* User mode is privilege level 3: */ #define USER_RPL 0x3 --- linux-oracle-5.4.0.orig/arch/x86/include/asm/set_memory.h +++ linux-oracle-5.4.0/arch/x86/include/asm/set_memory.h @@ -85,28 +85,35 @@ void set_kernel_text_ro(void); #ifdef CONFIG_X86_64 -static inline int set_mce_nospec(unsigned long pfn) +/* + * Prevent speculative access to the page by either unmapping + * it (if we do not require access to any part of the page) or + * marking it uncacheable (if we want to try to retrieve data + * from non-poisoned lines in the page). + */ +static inline int set_mce_nospec(unsigned long pfn, bool unmap) { unsigned long decoy_addr; int rc; /* - * Mark the linear address as UC to make sure we don't log more - * errors because of speculative access to the page. * We would like to just call: - * set_memory_uc((unsigned long)pfn_to_kaddr(pfn), 1); + * set_memory_XX((unsigned long)pfn_to_kaddr(pfn), 1); * but doing that would radically increase the odds of a * speculative access to the poison page because we'd have * the virtual address of the kernel 1:1 mapping sitting * around in registers. * Instead we get tricky. We create a non-canonical address * that looks just like the one we want, but has bit 63 flipped. - * This relies on set_memory_uc() properly sanitizing any __pa() + * This relies on set_memory_XX() properly sanitizing any __pa() * results with __PHYSICAL_MASK or PTE_PFN_MASK. */ decoy_addr = (pfn << PAGE_SHIFT) + (PAGE_OFFSET ^ BIT(63)); - rc = set_memory_uc(decoy_addr, 1); + if (unmap) + rc = set_memory_np(decoy_addr, 1); + else + rc = set_memory_uc(decoy_addr, 1); if (rc) pr_warn("Could not invalidate pfn=0x%lx from 1:1 map\n", pfn); return rc; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/setup.h +++ linux-oracle-5.4.0/arch/x86/include/asm/setup.h @@ -94,27 +94,16 @@ void *extend_brk(size_t size, size_t align); /* - * Reserve space in the brk section. The name must be unique within - * the file, and somewhat descriptive. The size is in bytes. Must be - * used at file scope. + * Reserve space in the .brk section, which is a block of memory from which the + * caller is allowed to allocate very early (before even memblock is available) + * by calling extend_brk(). All allocated memory will be eventually converted + * to memblock. Any leftover unallocated memory will be freed. * - * (This uses a temp function to wrap the asm so we can pass it the - * size parameter; otherwise we wouldn't be able to. We can't use a - * "section" attribute on a normal variable because it always ends up - * being @progbits, which ends up allocating space in the vmlinux - * executable.) + * The size is in bytes. */ -#define RESERVE_BRK(name,sz) \ - static void __section(.discard.text) __used notrace \ - __brk_reservation_fn_##name##__(void) { \ - asm volatile ( \ - ".pushsection .brk_reservation,\"aw\",@nobits;" \ - ".brk." #name ":" \ - " 1:.skip %c0;" \ - " .size .brk." #name ", . - 1b;" \ - " .popsection" \ - : : "i" (sz)); \ - } +#define RESERVE_BRK(name, size) \ + __section(.bss..brk) __aligned(1) __used \ + static char __brk_##name[size] /* Helper for reserving space for arrays of things */ #define RESERVE_BRK_ARRAY(type, name, entries) \ @@ -132,12 +121,19 @@ #endif /* __i386__ */ #endif /* _SETUP */ -#else -#define RESERVE_BRK(name,sz) \ - .pushsection .brk_reservation,"aw",@nobits; \ -.brk.name: \ -1: .skip sz; \ - .size .brk.name,.-1b; \ + +#else /* __ASSEMBLY */ + +.macro __RESERVE_BRK name, size + .pushsection .bss..brk, "aw" +SYM_DATA_START(__brk_\name) + .skip \size +SYM_DATA_END(__brk_\name) .popsection +.endm + +#define RESERVE_BRK(name, size) __RESERVE_BRK name, size + #endif /* __ASSEMBLY__ */ + #endif /* _ASM_X86_SETUP_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/smap.h +++ linux-oracle-5.4.0/arch/x86/include/asm/smap.h @@ -57,8 +57,10 @@ { unsigned long flags; - asm volatile (ALTERNATIVE("", "pushf; pop %0; " __ASM_CLAC, - X86_FEATURE_SMAP) + asm volatile ("# smap_save\n\t" + ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP) + "pushf; pop %0; " __ASM_CLAC "\n\t" + "1:" : "=rm" (flags) : : "memory", "cc"); return flags; @@ -66,7 +68,10 @@ static __always_inline void smap_restore(unsigned long flags) { - asm volatile (ALTERNATIVE("", "push %0; popf", X86_FEATURE_SMAP) + asm volatile ("# smap_restore\n\t" + ALTERNATIVE("jmp 1f", "", X86_FEATURE_SMAP) + "push %0; popf\n\t" + "1:" : : "g" (flags) : "memory", "cc"); } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/special_insns.h +++ linux-oracle-5.4.0/arch/x86/include/asm/special_insns.h @@ -10,45 +10,47 @@ #include /* - * Volatile isn't enough to prevent the compiler from reordering the - * read/write functions for the control registers and messing everything up. - * A memory clobber would solve the problem, but would prevent reordering of - * all loads stores around it, which can hurt performance. Solution is to - * use a variable and mimic reads and writes to it to enforce serialization + * The compiler should not reorder volatile asm statements with respect to each + * other: they should execute in program order. However GCC 4.9.x and 5.x have + * a bug (which was fixed in 8.1, 7.3 and 6.5) where they might reorder + * volatile asm. The write functions are not affected since they have memory + * clobbers preventing reordering. To prevent reads from being reordered with + * respect to writes, use a dummy memory operand. */ -extern unsigned long __force_order; + +#define __FORCE_ORDER "m"(*(unsigned int *)0x1000UL) void native_write_cr0(unsigned long val); static inline unsigned long native_read_cr0(void) { unsigned long val; - asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr0,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static inline unsigned long native_read_cr2(void) { unsigned long val; - asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr2,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static inline void native_write_cr2(unsigned long val) { - asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order)); + asm volatile("mov %0,%%cr2": : "r" (val) : "memory"); } static inline unsigned long __native_read_cr3(void) { unsigned long val; - asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr3,%0\n\t" : "=r" (val) : __FORCE_ORDER); return val; } static inline void native_write_cr3(unsigned long val) { - asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order)); + asm volatile("mov %0,%%cr3": : "r" (val) : "memory"); } static inline unsigned long native_read_cr4(void) @@ -63,10 +65,10 @@ asm volatile("1: mov %%cr4, %0\n" "2:\n" _ASM_EXTABLE(1b, 2b) - : "=r" (val), "=m" (__force_order) : "0" (0)); + : "=r" (val) : "0" (0), __FORCE_ORDER); #else /* CR4 always exists on x86_64. */ - asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order)); + asm volatile("mov %%cr4,%0\n\t" : "=r" (val) : __FORCE_ORDER); #endif return val; } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/stackprotector.h +++ linux-oracle-5.4.0/arch/x86/include/asm/stackprotector.h @@ -55,8 +55,13 @@ /* * Initialize the stackprotector canary value. * - * NOTE: this must only be called from functions that never return, + * NOTE: this must only be called from functions that never return * and it must always be inlined. + * + * In addition, it should be called from a compilation unit for which + * stack protector is disabled. Alternatively, the caller should not end + * with a function call which gets tail-call optimized as that would + * lead to checking a modified canary value. */ static __always_inline void boot_init_stack_canary(void) { --- linux-oracle-5.4.0.orig/arch/x86/include/asm/suspend_32.h +++ linux-oracle-5.4.0/arch/x86/include/asm/suspend_32.h @@ -21,7 +21,6 @@ #endif unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; - bool misc_enable_saved; struct saved_msrs saved_msrs; struct desc_ptr gdt_desc; struct desc_ptr idt; @@ -30,6 +29,7 @@ unsigned long tr; unsigned long safety; unsigned long return_address; + bool misc_enable_saved; } __attribute__((packed)); /* routines for saving/restoring kernel state */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/suspend_64.h +++ linux-oracle-5.4.0/arch/x86/include/asm/suspend_64.h @@ -14,9 +14,13 @@ * Image of the saved processor state, used by the low level ACPI suspend to * RAM code and by the low level hibernation code. * - * If you modify it, fix arch/x86/kernel/acpi/wakeup_64.S and make sure that - * __save/__restore_processor_state(), defined in arch/x86/kernel/suspend_64.c, - * still work as required. + * If you modify it, check how it is used in arch/x86/kernel/acpi/wakeup_64.S + * and make sure that __save/__restore_processor_state(), defined in + * arch/x86/power/cpu.c, still work as required. + * + * Because the structure is packed, make sure to avoid unaligned members. For + * optimisation purposes but also because tools like kmemleak only search for + * pointers that are aligned. */ struct saved_context { struct pt_regs regs; @@ -36,7 +40,6 @@ unsigned long cr0, cr2, cr3, cr4; u64 misc_enable; - bool misc_enable_saved; struct saved_msrs saved_msrs; unsigned long efer; u16 gdt_pad; /* Unused */ @@ -48,6 +51,7 @@ unsigned long tr; unsigned long safety; unsigned long return_address; + bool misc_enable_saved; } __attribute__((packed)); #define loaddebug(thread,register) \ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/svm.h +++ linux-oracle-5.4.0/arch/x86/include/asm/svm.h @@ -119,6 +119,8 @@ #define V_IGN_TPR_SHIFT 20 #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) +#define V_IRQ_INJECTION_BITS_MASK (V_IRQ_MASK | V_INTR_PRIO_MASK | V_IGN_TPR_MASK) + #define V_INTR_MASKING_SHIFT 24 #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) --- linux-oracle-5.4.0.orig/arch/x86/include/asm/sync_core.h +++ linux-oracle-5.4.0/arch/x86/include/asm/sync_core.h @@ -16,12 +16,13 @@ /* With PTI, we unconditionally serialize before running user code. */ if (static_cpu_has(X86_FEATURE_PTI)) return; + /* - * Return from interrupt and NMI is done through iret, which is core - * serializing. + * Even if we're in an interrupt, we might reschedule before returning, + * in which case we could switch to a different thread in the same mm + * and return using SYSRET or SYSEXIT. Instead of trying to keep + * track of our need to sync the core, just sync right away. */ - if (in_irq() || in_nmi()) - return; sync_core(); } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/syscall.h +++ linux-oracle-5.4.0/arch/x86/include/asm/syscall.h @@ -94,7 +94,12 @@ struct pt_regs *regs, unsigned long *args) { - memcpy(args, ®s->bx, 6 * sizeof(args[0])); + args[0] = regs->bx; + args[1] = regs->cx; + args[2] = regs->dx; + args[3] = regs->si; + args[4] = regs->di; + args[5] = regs->bp; } static inline void syscall_set_arguments(struct task_struct *task, --- linux-oracle-5.4.0.orig/arch/x86/include/asm/syscall_wrapper.h +++ linux-oracle-5.4.0/arch/x86/include/asm/syscall_wrapper.h @@ -6,18 +6,37 @@ #ifndef _ASM_X86_SYSCALL_WRAPPER_H #define _ASM_X86_SYSCALL_WRAPPER_H +struct pt_regs; + /* Mapping of registers to parameters for syscalls on x86-64 and x32 */ #define SC_X86_64_REGS_TO_ARGS(x, ...) \ __MAP(x,__SC_ARGS \ ,,regs->di,,regs->si,,regs->dx \ ,,regs->r10,,regs->r8,,regs->r9) \ + +/* SYSCALL_PT_ARGS is Adapted from s390x */ +#define SYSCALL_PT_ARG6(m, t1, t2, t3, t4, t5, t6) \ + SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5), m(t6, (regs->bp)) +#define SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5) \ + SYSCALL_PT_ARG4(m, t1, t2, t3, t4), m(t5, (regs->di)) +#define SYSCALL_PT_ARG4(m, t1, t2, t3, t4) \ + SYSCALL_PT_ARG3(m, t1, t2, t3), m(t4, (regs->si)) +#define SYSCALL_PT_ARG3(m, t1, t2, t3) \ + SYSCALL_PT_ARG2(m, t1, t2), m(t3, (regs->dx)) +#define SYSCALL_PT_ARG2(m, t1, t2) \ + SYSCALL_PT_ARG1(m, t1), m(t2, (regs->cx)) +#define SYSCALL_PT_ARG1(m, t1) m(t1, (regs->bx)) +#define SYSCALL_PT_ARGS(x, ...) SYSCALL_PT_ARG##x(__VA_ARGS__) + +#define __SC_COMPAT_CAST(t, a) \ + (__typeof(__builtin_choose_expr(__TYPE_IS_L(t), 0, 0U))) \ + (unsigned int)a + /* Mapping of registers to parameters for syscalls on i386 */ #define SC_IA32_REGS_TO_ARGS(x, ...) \ - __MAP(x,__SC_ARGS \ - ,,(unsigned int)regs->bx,,(unsigned int)regs->cx \ - ,,(unsigned int)regs->dx,,(unsigned int)regs->si \ - ,,(unsigned int)regs->di,,(unsigned int)regs->bp) + SYSCALL_PT_ARGS(x, __SC_COMPAT_CAST, \ + __MAP(x, __SC_TYPE, __VA_ARGS__)) \ #ifdef CONFIG_IA32_EMULATION /* @@ -28,13 +47,21 @@ * kernel/sys_ni.c and SYS_NI in kernel/time/posix-stubs.c to cover this * case as well. */ +#define __IA32_COMPAT_SYS_STUB0(x, name) \ + asmlinkage long __ia32_compat_sys_##name(const struct pt_regs *regs);\ + ALLOW_ERROR_INJECTION(__ia32_compat_sys_##name, ERRNO); \ + asmlinkage long __ia32_compat_sys_##name(const struct pt_regs *regs)\ + { \ + return __se_compat_sys_##name(); \ + } + #define __IA32_COMPAT_SYS_STUBx(x, name, ...) \ asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs);\ ALLOW_ERROR_INJECTION(__ia32_compat_sys##name, ERRNO); \ asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs)\ { \ return __se_compat_sys##name(SC_IA32_REGS_TO_ARGS(x,__VA_ARGS__));\ - } \ + } #define __IA32_SYS_STUBx(x, name, ...) \ asmlinkage long __ia32_sys##name(const struct pt_regs *regs); \ @@ -48,16 +75,23 @@ * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias * named __ia32_sys_*() */ -#define SYSCALL_DEFINE0(sname) \ - SYSCALL_METADATA(_##sname, 0); \ - asmlinkage long __x64_sys_##sname(void); \ - ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \ - SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname); \ - asmlinkage long __x64_sys_##sname(void) - -#define COND_SYSCALL(name) \ - cond_syscall(__x64_sys_##name); \ - cond_syscall(__ia32_sys_##name) + +#define SYSCALL_DEFINE0(sname) \ + SYSCALL_METADATA(_##sname, 0); \ + asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\ + ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \ + SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname); \ + asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused) + +#define COND_SYSCALL(name) \ + asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused) \ + { \ + return sys_ni_syscall(); \ + } \ + asmlinkage __weak long __ia32_sys_##name(const struct pt_regs *__unused)\ + { \ + return sys_ni_syscall(); \ + } #define SYS_NI(name) \ SYSCALL_ALIAS(__x64_sys_##name, sys_ni_posix_timers); \ @@ -75,15 +109,24 @@ * of the x86-64-style parameter ordering of x32 syscalls. The syscalls common * with x86_64 obviously do not need such care. */ +#define __X32_COMPAT_SYS_STUB0(x, name, ...) \ + asmlinkage long __x32_compat_sys_##name(const struct pt_regs *regs);\ + ALLOW_ERROR_INJECTION(__x32_compat_sys_##name, ERRNO); \ + asmlinkage long __x32_compat_sys_##name(const struct pt_regs *regs)\ + { \ + return __se_compat_sys_##name();\ + } + #define __X32_COMPAT_SYS_STUBx(x, name, ...) \ asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs);\ ALLOW_ERROR_INJECTION(__x32_compat_sys##name, ERRNO); \ asmlinkage long __x32_compat_sys##name(const struct pt_regs *regs)\ { \ return __se_compat_sys##name(SC_X86_64_REGS_TO_ARGS(x,__VA_ARGS__));\ - } \ + } #else /* CONFIG_X86_X32 */ +#define __X32_COMPAT_SYS_STUB0(x, name) #define __X32_COMPAT_SYS_STUBx(x, name, ...) #endif /* CONFIG_X86_X32 */ @@ -94,6 +137,17 @@ * mapping of registers to parameters, we need to generate stubs for each * of them. */ +#define COMPAT_SYSCALL_DEFINE0(name) \ + static long __se_compat_sys_##name(void); \ + static inline long __do_compat_sys_##name(void); \ + __IA32_COMPAT_SYS_STUB0(x, name) \ + __X32_COMPAT_SYS_STUB0(x, name) \ + static long __se_compat_sys_##name(void) \ + { \ + return __do_compat_sys_##name(); \ + } \ + static inline long __do_compat_sys_##name(void) + #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ static long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ @@ -181,15 +235,19 @@ * macros to work correctly. */ #ifndef SYSCALL_DEFINE0 -#define SYSCALL_DEFINE0(sname) \ - SYSCALL_METADATA(_##sname, 0); \ - asmlinkage long __x64_sys_##sname(void); \ - ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \ - asmlinkage long __x64_sys_##sname(void) +#define SYSCALL_DEFINE0(sname) \ + SYSCALL_METADATA(_##sname, 0); \ + asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\ + ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \ + asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused) #endif #ifndef COND_SYSCALL -#define COND_SYSCALL(name) cond_syscall(__x64_sys_##name) +#define COND_SYSCALL(name) \ + asmlinkage __weak long __x64_sys_##name(const struct pt_regs *__unused) \ + { \ + return sys_ni_syscall(); \ + } #endif #ifndef SYS_NI @@ -201,7 +259,6 @@ * For VSYSCALLS, we need to declare these three syscalls with the new * pt_regs-based calling convention for in-kernel use. */ -struct pt_regs; asmlinkage long __x64_sys_getcpu(const struct pt_regs *regs); asmlinkage long __x64_sys_gettimeofday(const struct pt_regs *regs); asmlinkage long __x64_sys_time(const struct pt_regs *regs); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/thread_info.h +++ linux-oracle-5.4.0/arch/x86/include/asm/thread_info.h @@ -221,10 +221,31 @@ #endif +/* + * Thread-synchronous status. + * + * This is different from the flags in that nobody else + * ever touches our thread-synchronous status, so we don't + * have to worry about atomic accesses. + */ +#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ + +#ifndef __ASSEMBLY__ #ifdef CONFIG_COMPAT #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ +#define TS_COMPAT_RESTART 0x0008 + +#define arch_set_restart_data arch_set_restart_data + +static inline void arch_set_restart_data(struct restart_block *restart) +{ + struct thread_info *ti = current_thread_info(); + if (ti->status & TS_COMPAT) + ti->status |= TS_COMPAT_RESTART; + else + ti->status &= ~TS_COMPAT_RESTART; +} #endif -#ifndef __ASSEMBLY__ #ifdef CONFIG_X86_32 #define in_ia32_syscall() true --- linux-oracle-5.4.0.orig/arch/x86/include/asm/timex.h +++ linux-oracle-5.4.0/arch/x86/include/asm/timex.h @@ -5,6 +5,15 @@ #include #include +static inline unsigned long random_get_entropy(void) +{ + if (!IS_ENABLED(CONFIG_X86_TSC) && + !cpu_feature_enabled(X86_FEATURE_TSC)) + return random_get_entropy_fallback(); + return rdtsc(); +} +#define random_get_entropy random_get_entropy + /* Assume we use the PIT time source for the clock tick */ #define CLOCK_TICK_RATE PIT_TICK_RATE --- linux-oracle-5.4.0.orig/arch/x86/include/asm/topology.h +++ linux-oracle-5.4.0/arch/x86/include/asm/topology.h @@ -110,6 +110,8 @@ #define topology_die_id(cpu) (cpu_data(cpu).cpu_die_id) #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) +extern unsigned int __max_die_per_package; + #ifdef CONFIG_SMP #define topology_die_cpumask(cpu) (per_cpu(cpu_die_map, cpu)) #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) @@ -118,8 +120,6 @@ extern unsigned int __max_logical_packages; #define topology_max_packages() (__max_logical_packages) -extern unsigned int __max_die_per_package; - static inline int topology_max_die_per_package(void) { return __max_die_per_package; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/tsc.h +++ linux-oracle-5.4.0/arch/x86/include/asm/tsc.h @@ -22,13 +22,12 @@ static inline cycles_t get_cycles(void) { -#ifndef CONFIG_X86_TSC - if (!boot_cpu_has(X86_FEATURE_TSC)) + if (!IS_ENABLED(CONFIG_X86_TSC) && + !cpu_feature_enabled(X86_FEATURE_TSC)) return 0; -#endif - return rdtsc(); } +#define get_cycles get_cycles extern struct system_counterval_t convert_art_to_tsc(u64 art); extern struct system_counterval_t convert_art_ns_to_tsc(u64 art_ns); --- linux-oracle-5.4.0.orig/arch/x86/include/asm/uaccess.h +++ linux-oracle-5.4.0/arch/x86/include/asm/uaccess.h @@ -378,18 +378,6 @@ : "=r" (err), ltype(x) \ : "m" (__m(addr)), "i" (errret), "0" (err)) -#define __get_user_asm_nozero(x, addr, err, itype, rtype, ltype, errret) \ - asm volatile("\n" \ - "1: mov"itype" %2,%"rtype"1\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: mov %3,%0\n" \ - " jmp 2b\n" \ - ".previous\n" \ - _ASM_EXTABLE_UA(1b, 3b) \ - : "=r" (err), ltype(x) \ - : "m" (__m(addr)), "i" (errret), "0" (err)) - /* * This doesn't do __uaccess_begin/end - the exception handling * around it must do that. @@ -453,6 +441,103 @@ __builtin_expect(__gu_err, 0); \ }) +#ifdef CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT +#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm_volatile_goto("\n" \ + "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ + _ASM_EXTABLE_UA(1b, %l[label]) \ + : CC_OUT(z) (success), \ + [ptr] "+m" (*_ptr), \ + [old] "+a" (__old) \ + : [new] ltype (__new) \ + : "memory" \ + : label); \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) + +#ifdef CONFIG_X86_32 +#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm_volatile_goto("\n" \ + "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ + _ASM_EXTABLE_UA(1b, %l[label]) \ + : CC_OUT(z) (success), \ + "+A" (__old), \ + [ptr] "+m" (*_ptr) \ + : "b" ((u32)__new), \ + "c" ((u32)((u64)__new >> 32)) \ + : "memory" \ + : label); \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) +#endif // CONFIG_X86_32 +#else // !CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT +#define __try_cmpxchg_user_asm(itype, ltype, _ptr, _pold, _new, label) ({ \ + int __err = 0; \ + bool success; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm volatile("\n" \ + "1: " LOCK_PREFIX "cmpxchg"itype" %[new], %[ptr]\n"\ + CC_SET(z) \ + "2:\n" \ + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, \ + %[errout]) \ + : CC_OUT(z) (success), \ + [errout] "+r" (__err), \ + [ptr] "+m" (*_ptr), \ + [old] "+a" (__old) \ + : [new] ltype (__new) \ + : "memory"); \ + if (unlikely(__err)) \ + goto label; \ + if (unlikely(!success)) \ + *_old = __old; \ + likely(success); }) + +#ifdef CONFIG_X86_32 +/* + * Unlike the normal CMPXCHG, hardcode ECX for both success/fail and error. + * There are only six GPRs available and four (EAX, EBX, ECX, and EDX) are + * hardcoded by CMPXCHG8B, leaving only ESI and EDI. If the compiler uses + * both ESI and EDI for the memory operand, compilation will fail if the error + * is an input+output as there will be no register available for input. + */ +#define __try_cmpxchg64_user_asm(_ptr, _pold, _new, label) ({ \ + int __result; \ + __typeof__(_ptr) _old = (__typeof__(_ptr))(_pold); \ + __typeof__(*(_ptr)) __old = *_old; \ + __typeof__(*(_ptr)) __new = (_new); \ + asm volatile("\n" \ + "1: " LOCK_PREFIX "cmpxchg8b %[ptr]\n" \ + "mov $0, %%ecx\n\t" \ + "setz %%cl\n" \ + "2:\n" \ + _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %%ecx) \ + : [result]"=c" (__result), \ + "+A" (__old), \ + [ptr] "+m" (*_ptr) \ + : "b" ((u32)__new), \ + "c" ((u32)((u64)__new >> 32)) \ + : "memory", "cc"); \ + if (unlikely(__result < 0)) \ + goto label; \ + if (unlikely(!__result)) \ + *_old = __old; \ + likely(__result); }) +#endif // CONFIG_X86_32 +#endif // CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT + /* FIXME: this hack is definitely wrong -AK */ struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct __user *)(x)) @@ -734,6 +819,51 @@ if (unlikely(__gu_err)) goto err_label; \ } while (0) +extern void __try_cmpxchg_user_wrong_size(void); + +#ifndef CONFIG_X86_32 +#define __try_cmpxchg64_user_asm(_ptr, _oldp, _nval, _label) \ + __try_cmpxchg_user_asm("q", "r", (_ptr), (_oldp), (_nval), _label) +#endif + +/* + * Force the pointer to u to match the size expected by the asm helper. + * clang/LLVM compiles all cases and only discards the unused paths after + * processing errors, which breaks i386 if the pointer is an 8-byte value. + */ +#define unsafe_try_cmpxchg_user(_ptr, _oldp, _nval, _label) ({ \ + bool __ret; \ + __chk_user_ptr(_ptr); \ + switch (sizeof(*(_ptr))) { \ + case 1: __ret = __try_cmpxchg_user_asm("b", "q", \ + (__force u8 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 2: __ret = __try_cmpxchg_user_asm("w", "r", \ + (__force u16 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 4: __ret = __try_cmpxchg_user_asm("l", "r", \ + (__force u32 *)(_ptr), (_oldp), \ + (_nval), _label); \ + break; \ + case 8: __ret = __try_cmpxchg64_user_asm((__force u64 *)(_ptr), (_oldp),\ + (_nval), _label); \ + break; \ + default: __try_cmpxchg_user_wrong_size(); \ + } \ + __ret; }) + +/* "Returns" 0 on success, 1 on failure, -EFAULT if the access faults. */ +#define __try_cmpxchg_user(_ptr, _oldp, _nval, _label) ({ \ + int __ret = -EFAULT; \ + __uaccess_begin_nospec(); \ + __ret = !unsafe_try_cmpxchg_user(_ptr, _oldp, _nval, _label); \ +_label: \ + __uaccess_end(); \ + __ret; \ + }) + /* * We want the unsafe accessors to always be inlined and use * the error labels - thus the macro games. --- linux-oracle-5.4.0.orig/arch/x86/include/asm/uaccess_32.h +++ linux-oracle-5.4.0/arch/x86/include/asm/uaccess_32.h @@ -23,33 +23,6 @@ static __always_inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - if (__builtin_constant_p(n)) { - unsigned long ret; - - switch (n) { - case 1: - ret = 0; - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u8 *)to, from, ret, - "b", "b", "=q", 1); - __uaccess_end(); - return ret; - case 2: - ret = 0; - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u16 *)to, from, ret, - "w", "w", "=r", 2); - __uaccess_end(); - return ret; - case 4: - ret = 0; - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u32 *)to, from, ret, - "l", "k", "=r", 4); - __uaccess_end(); - return ret; - } - } return __copy_user_ll(to, (__force const void *)from, n); } --- linux-oracle-5.4.0.orig/arch/x86/include/asm/uaccess_64.h +++ linux-oracle-5.4.0/arch/x86/include/asm/uaccess_64.h @@ -65,117 +65,13 @@ static __always_inline __must_check unsigned long raw_copy_from_user(void *dst, const void __user *src, unsigned long size) { - int ret = 0; - - if (!__builtin_constant_p(size)) - return copy_user_generic(dst, (__force void *)src, size); - switch (size) { - case 1: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u8 *)dst, (u8 __user *)src, - ret, "b", "b", "=q", 1); - __uaccess_end(); - return ret; - case 2: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u16 *)dst, (u16 __user *)src, - ret, "w", "w", "=r", 2); - __uaccess_end(); - return ret; - case 4: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u32 *)dst, (u32 __user *)src, - ret, "l", "k", "=r", 4); - __uaccess_end(); - return ret; - case 8: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, - ret, "q", "", "=r", 8); - __uaccess_end(); - return ret; - case 10: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, - ret, "q", "", "=r", 10); - if (likely(!ret)) - __get_user_asm_nozero(*(u16 *)(8 + (char *)dst), - (u16 __user *)(8 + (char __user *)src), - ret, "w", "w", "=r", 2); - __uaccess_end(); - return ret; - case 16: - __uaccess_begin_nospec(); - __get_user_asm_nozero(*(u64 *)dst, (u64 __user *)src, - ret, "q", "", "=r", 16); - if (likely(!ret)) - __get_user_asm_nozero(*(u64 *)(8 + (char *)dst), - (u64 __user *)(8 + (char __user *)src), - ret, "q", "", "=r", 8); - __uaccess_end(); - return ret; - default: - return copy_user_generic(dst, (__force void *)src, size); - } + return copy_user_generic(dst, (__force void *)src, size); } static __always_inline __must_check unsigned long raw_copy_to_user(void __user *dst, const void *src, unsigned long size) { - int ret = 0; - - if (!__builtin_constant_p(size)) - return copy_user_generic((__force void *)dst, src, size); - switch (size) { - case 1: - __uaccess_begin(); - __put_user_asm(*(u8 *)src, (u8 __user *)dst, - ret, "b", "b", "iq", 1); - __uaccess_end(); - return ret; - case 2: - __uaccess_begin(); - __put_user_asm(*(u16 *)src, (u16 __user *)dst, - ret, "w", "w", "ir", 2); - __uaccess_end(); - return ret; - case 4: - __uaccess_begin(); - __put_user_asm(*(u32 *)src, (u32 __user *)dst, - ret, "l", "k", "ir", 4); - __uaccess_end(); - return ret; - case 8: - __uaccess_begin(); - __put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "er", 8); - __uaccess_end(); - return ret; - case 10: - __uaccess_begin(); - __put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "er", 10); - if (likely(!ret)) { - asm("":::"memory"); - __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst, - ret, "w", "w", "ir", 2); - } - __uaccess_end(); - return ret; - case 16: - __uaccess_begin(); - __put_user_asm(*(u64 *)src, (u64 __user *)dst, - ret, "q", "", "er", 16); - if (likely(!ret)) { - asm("":::"memory"); - __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst, - ret, "q", "", "er", 8); - } - __uaccess_end(); - return ret; - default: - return copy_user_generic((__force void *)dst, src, size); - } + return copy_user_generic((__force void *)dst, src, size); } static __always_inline __must_check --- linux-oracle-5.4.0.orig/arch/x86/include/asm/unwind.h +++ linux-oracle-5.4.0/arch/x86/include/asm/unwind.h @@ -19,7 +19,7 @@ #if defined(CONFIG_UNWINDER_ORC) bool signal, full_regs; unsigned long sp, bp, ip; - struct pt_regs *regs; + struct pt_regs *regs, *prev_regs; #elif defined(CONFIG_UNWINDER_FRAME_POINTER) bool got_irq; unsigned long *bp, *orig_sp, ip; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/unwind_hints.h +++ linux-oracle-5.4.0/arch/x86/include/asm/unwind_hints.h @@ -101,7 +101,7 @@ ".popsection\n\t" #define UNWIND_HINT_SAVE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_SAVE, 0) - +#define UNWIND_HINT_EMPTY #define UNWIND_HINT_RESTORE UNWIND_HINT(0, 0, UNWIND_HINT_TYPE_RESTORE, 0) #endif /* __ASSEMBLY__ */ --- linux-oracle-5.4.0.orig/arch/x86/include/asm/virtext.h +++ linux-oracle-5.4.0/arch/x86/include/asm/virtext.h @@ -30,15 +30,22 @@ } -/** Disable VMX on the current CPU +/** + * cpu_vmxoff() - Disable VMX on the current CPU * - * vmxoff causes a undefined-opcode exception if vmxon was not run - * on the CPU previously. Only call this function if you know VMX - * is enabled. + * Disable VMX and clear CR4.VMXE (even if VMXOFF faults) + * + * Note, VMXOFF causes a #UD if the CPU is !post-VMXON, but it's impossible to + * atomically track post-VMXON state, e.g. this may be called in NMI context. + * Eat all faults as all other faults on VMXOFF faults are mode related, i.e. + * faults are guaranteed to be due to the !post-VMXON check unless the CPU is + * magically in RM, VM86, compat mode, or at CPL>0. */ static inline void cpu_vmxoff(void) { - asm volatile ("vmxoff"); + asm_volatile_goto("1: vmxoff\n\t" + _ASM_EXTABLE(1b, %l[fault]) :::: fault); +fault: cr4_clear_bits(X86_CR4_VMXE); } @@ -88,12 +95,6 @@ return 0; } - if (boot_cpu_data.extended_cpuid_level < SVM_CPUID_FUNC) { - if (msg) - *msg = "can't execute cpuid_8000000a"; - return 0; - } - if (!boot_cpu_has(X86_FEATURE_SVM)) { if (msg) *msg = "svm not available"; @@ -113,7 +114,21 @@ wrmsrl(MSR_VM_HSAVE_PA, 0); rdmsrl(MSR_EFER, efer); - wrmsrl(MSR_EFER, efer & ~EFER_SVME); + if (efer & EFER_SVME) { + /* + * Force GIF=1 prior to disabling SVM to ensure INIT and NMI + * aren't blocked, e.g. if a fatal error occurred between CLGI + * and STGI. Note, STGI may #UD if SVM is disabled from NMI + * context between reading EFER and executing STGI. In that + * case, GIF must already be set, otherwise the NMI would have + * been blocked, so just eat the fault. + */ + asm_volatile_goto("1: stgi\n\t" + _ASM_EXTABLE(1b, %l[fault]) + ::: "memory" : fault); +fault: + wrmsrl(MSR_EFER, efer & ~EFER_SVME); + } } /** Makes sure SVM is disabled, if it is supported on the CPU --- linux-oracle-5.4.0.orig/arch/x86/include/asm/vmx.h +++ linux-oracle-5.4.0/arch/x86/include/asm/vmx.h @@ -19,8 +19,8 @@ /* * Definitions of Primary Processor-Based VM-Execution Controls. */ -#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004 -#define CPU_BASED_USE_TSC_OFFSETING 0x00000008 +#define CPU_BASED_INTR_WINDOW_EXITING 0x00000004 +#define CPU_BASED_USE_TSC_OFFSETTING 0x00000008 #define CPU_BASED_HLT_EXITING 0x00000080 #define CPU_BASED_INVLPG_EXITING 0x00000200 #define CPU_BASED_MWAIT_EXITING 0x00000400 @@ -31,7 +31,7 @@ #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 #define CPU_BASED_CR8_STORE_EXITING 0x00100000 #define CPU_BASED_TPR_SHADOW 0x00200000 -#define CPU_BASED_VIRTUAL_NMI_PENDING 0x00400000 +#define CPU_BASED_NMI_WINDOW_EXITING 0x00400000 #define CPU_BASED_MOV_DR_EXITING 0x00800000 #define CPU_BASED_UNCOND_IO_EXITING 0x01000000 #define CPU_BASED_USE_IO_BITMAPS 0x02000000 --- linux-oracle-5.4.0.orig/arch/x86/include/asm/x86_init.h +++ linux-oracle-5.4.0/arch/x86/include/asm/x86_init.h @@ -51,12 +51,14 @@ * are set up. * @intr_init: interrupt init code * @trap_init: platform specific trap setup + * @intr_mode_select: interrupt delivery mode selection * @intr_mode_init: interrupt delivery mode setup */ struct x86_init_irqs { void (*pre_vector_init)(void); void (*intr_init)(void); void (*trap_init)(void); + void (*intr_mode_select)(void); void (*intr_mode_init)(void); }; --- linux-oracle-5.4.0.orig/arch/x86/include/asm/xen/interface.h +++ linux-oracle-5.4.0/arch/x86/include/asm/xen/interface.h @@ -379,12 +379,9 @@ * Prefix forces emulation of some non-trapping instructions. * Currently only CPUID. */ -#ifdef __ASSEMBLY__ -#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ; -#define XEN_CPUID XEN_EMULATE_PREFIX cpuid -#else -#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; " -#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid" -#endif +#include + +#define XEN_EMULATE_PREFIX __ASM_FORM(.byte __XEN_EMULATE_PREFIX ;) +#define XEN_CPUID XEN_EMULATE_PREFIX __ASM_FORM(cpuid) #endif /* _ASM_X86_XEN_INTERFACE_H */ --- linux-oracle-5.4.0.orig/arch/x86/include/uapi/asm/unistd.h +++ linux-oracle-5.4.0/arch/x86/include/uapi/asm/unistd.h @@ -2,8 +2,15 @@ #ifndef _UAPI_ASM_X86_UNISTD_H #define _UAPI_ASM_X86_UNISTD_H -/* x32 syscall flag bit */ -#define __X32_SYSCALL_BIT 0x40000000UL +/* + * x32 syscall flag bit. Some user programs expect syscall NR macros + * and __X32_SYSCALL_BIT to have type int, even though syscall numbers + * are, for practical purposes, unsigned long. + * + * Fortunately, expressions like (nr & ~__X32_SYSCALL_BIT) do the right + * thing regardless. + */ +#define __X32_SYSCALL_BIT 0x40000000 #ifndef __KERNEL__ # ifdef __i386__ --- linux-oracle-5.4.0.orig/arch/x86/include/uapi/asm/vmx.h +++ linux-oracle-5.4.0/arch/x86/include/uapi/asm/vmx.h @@ -33,7 +33,7 @@ #define EXIT_REASON_TRIPLE_FAULT 2 #define EXIT_REASON_INIT_SIGNAL 3 -#define EXIT_REASON_PENDING_INTERRUPT 7 +#define EXIT_REASON_INTERRUPT_WINDOW 7 #define EXIT_REASON_NMI_WINDOW 8 #define EXIT_REASON_TASK_SWITCH 9 #define EXIT_REASON_CPUID 10 @@ -94,7 +94,7 @@ { EXIT_REASON_EXTERNAL_INTERRUPT, "EXTERNAL_INTERRUPT" }, \ { EXIT_REASON_TRIPLE_FAULT, "TRIPLE_FAULT" }, \ { EXIT_REASON_INIT_SIGNAL, "INIT_SIGNAL" }, \ - { EXIT_REASON_PENDING_INTERRUPT, "PENDING_INTERRUPT" }, \ + { EXIT_REASON_INTERRUPT_WINDOW, "INTERRUPT_WINDOW" }, \ { EXIT_REASON_NMI_WINDOW, "NMI_WINDOW" }, \ { EXIT_REASON_TASK_SWITCH, "TASK_SWITCH" }, \ { EXIT_REASON_CPUID, "CPUID" }, \ --- linux-oracle-5.4.0.orig/arch/x86/kernel/acpi/boot.c +++ linux-oracle-5.4.0/arch/x86/kernel/acpi/boot.c @@ -140,6 +140,9 @@ madt->address); } + if (madt->flags & ACPI_MADT_PCAT_COMPAT) + legacy_pic_pcat_compat(); + default_acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id); @@ -1339,6 +1342,17 @@ return 0; } +static int __init disable_acpi_xsdt(const struct dmi_system_id *d) +{ + if (!acpi_force) { + pr_notice("%s detected: force use of acpi=rsdt\n", d->ident); + acpi_gbl_do_not_use_xsdt = TRUE; + } else { + pr_notice("Warning: DMI blacklist says broken, but acpi XSDT forced\n"); + } + return 0; +} + static int __init dmi_disable_acpi(const struct dmi_system_id *d) { if (!acpi_force) { @@ -1463,6 +1477,19 @@ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), }, }, + /* + * Boxes that need ACPI XSDT use disabled due to corrupted tables + */ + { + .callback = disable_acpi_xsdt, + .ident = "Advantech DAC-BJ01", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "NEC"), + DMI_MATCH(DMI_PRODUCT_NAME, "Bearlake CRB Board"), + DMI_MATCH(DMI_BIOS_VERSION, "V1.12"), + DMI_MATCH(DMI_BIOS_DATE, "02/01/2011"), + }, + }, {} }; @@ -1553,10 +1580,18 @@ /* * Initialize the ACPI boot-time table parser. */ - if (acpi_table_init()) { + if (acpi_locate_initial_tables()) disable_acpi(); - return; - } + else + acpi_reserve_initial_tables(); +} + +int __init early_acpi_boot_init(void) +{ + if (acpi_disabled) + return 1; + + acpi_table_init_complete(); acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf); @@ -1569,18 +1604,9 @@ } else { printk(KERN_WARNING PREFIX "Disabling ACPI support\n"); disable_acpi(); - return; + return 1; } } -} - -int __init early_acpi_boot_init(void) -{ - /* - * If acpi_disabled, bail out - */ - if (acpi_disabled) - return 1; /* * Process the Multiple APIC Description Table (MADT), if present @@ -1740,7 +1766,7 @@ new = (((old & ~0x3) + 2) + ((old >> 1) & 0x1)); val = cmpxchg(lock, old, new); } while (unlikely (val != old)); - return (new < 3) ? -1 : 0; + return ((new & 0x3) < 3) ? -1 : 0; } int __acpi_release_global_lock(unsigned int *lock) --- linux-oracle-5.4.0.orig/arch/x86/kernel/acpi/cstate.c +++ linux-oracle-5.4.0/arch/x86/kernel/acpi/cstate.c @@ -161,7 +161,8 @@ /* Make sure we are running on right CPU */ - retval = work_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx); + retval = call_on_cpu(cpu, acpi_processor_ffh_cstate_probe_cpu, cx, + false); if (retval == 0) { /* Use the hint in CST */ percpu_entry->states[cx->index].eax = cx->address; --- linux-oracle-5.4.0.orig/arch/x86/kernel/acpi/wakeup_32.S +++ linux-oracle-5.4.0/arch/x86/kernel/acpi/wakeup_32.S @@ -3,14 +3,14 @@ #include #include #include +#include # Copyright 2003, 2008 Pavel Machek #include #include +#include # Copyright 2003 Pavel Machek %px", start, end); + + /* + * In the case CONFIG_X86_5LEVEL=y, KASAN_SHADOW_START is defined using + * cpu_feature_enabled(X86_FEATURE_LA57) and is therefore patched here. + * During the process, KASAN becomes confused seeing partial LA57 + * conversion and triggers a false-positive out-of-bound report. + * + * Disable KASAN until the patching is complete. + */ + kasan_disable_current(); + /* * The scan order should be from start to end. A later scanned * alternative code can overwrite previously scanned alternative code. @@ -434,6 +445,8 @@ text_poke_early(instr, insn_buff, insn_buff_sz); } + + kasan_enable_current(); } #ifdef CONFIG_SMP @@ -772,8 +785,8 @@ } else { local_irq_save(flags); memcpy(addr, opcode, len); - local_irq_restore(flags); sync_core(); + local_irq_restore(flags); /* * Could also do a CLFLUSH here to speed up CPU recovery; but --- linux-oracle-5.4.0.orig/arch/x86/kernel/amd_nb.c +++ linux-oracle-5.4.0/arch/x86/kernel/amd_nb.c @@ -18,10 +18,13 @@ #define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 #define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0 #define PCI_DEVICE_ID_AMD_17H_M30H_ROOT 0x1480 +#define PCI_DEVICE_ID_AMD_17H_M60H_ROOT 0x1630 #define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4 0x1494 +#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F4 0x144c #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4 0x1444 +#define PCI_DEVICE_ID_AMD_19H_DF_F4 0x1654 /* Protect the PCI config register pairs used for SMN and DF indirect access. */ static DEFINE_MUTEX(smn_mutex); @@ -32,6 +35,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_ROOT) }, {} }; @@ -50,8 +54,10 @@ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) }, {} }; EXPORT_SYMBOL_GPL(amd_nb_misc_ids); @@ -65,7 +71,9 @@ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, {} }; @@ -158,7 +166,14 @@ int amd_smn_read(u16 node, u32 address, u32 *value) { - return __amd_smn_rw(node, address, value, false); + int err = __amd_smn_rw(node, address, value, false); + + if (PCI_POSSIBLE_ERROR(*value)) { + err = -ENODEV; + *value = 0; + } + + return err; } EXPORT_SYMBOL_GPL(amd_smn_read); @@ -523,6 +538,10 @@ static __init int init_amd_nbs(void) { + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD && + boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) + return 0; + amd_cache_northbridges(); amd_cache_gart(); --- linux-oracle-5.4.0.orig/arch/x86/kernel/aperture_64.c +++ linux-oracle-5.4.0/arch/x86/kernel/aperture_64.c @@ -126,32 +126,6 @@ } -/* Find a PCI capability */ -static u32 __init find_cap(int bus, int slot, int func, int cap) -{ - int bytes; - u8 pos; - - if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) & - PCI_STATUS_CAP_LIST)) - return 0; - - pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST); - for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) { - u8 id; - - pos &= ~3; - id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID); - if (id == 0xff) - break; - if (id == cap) - return pos; - pos = read_pci_config_byte(bus, slot, func, - pos+PCI_CAP_LIST_NEXT); - } - return 0; -} - /* Read a standard AGPv3 bridge header */ static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order) { @@ -240,8 +214,8 @@ case PCI_CLASS_BRIDGE_HOST: case PCI_CLASS_BRIDGE_OTHER: /* needed? */ /* AGP bridge? */ - cap = find_cap(bus, slot, func, - PCI_CAP_ID_AGP); + cap = pci_early_find_cap(bus, slot, + func, PCI_CAP_ID_AGP); if (!cap) break; *valid_agp = 1; --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/apic.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/apic.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -167,7 +168,7 @@ { apic_calibrate_pmtmr = 1; notsc_setup(NULL); - return 0; + return 1; } __setup("apicpmtimer", setup_apicpmtimer); #endif @@ -352,8 +353,6 @@ * According to Intel, MFENCE can do the serialization here. */ asm volatile("mfence" : : : "memory"); - - printk_once(KERN_DEBUG "TSC deadline timer enabled\n"); return; } @@ -411,10 +410,9 @@ if (vector && !eilvt_entry_is_changeable(vector, new)) /* may not change if vectors are different */ return rsvd; - rsvd = atomic_cmpxchg(&eilvt_offsets[offset], rsvd, new); - } while (rsvd != new); + } while (!atomic_try_cmpxchg(&eilvt_offsets[offset], &rsvd, new)); - rsvd &= ~APIC_EILVT_MASKED; + rsvd = new & ~APIC_EILVT_MASKED; if (rsvd && rsvd != vector) pr_info("LVT offset %d assigned for vector 0x%02x\n", offset, rsvd); @@ -474,6 +472,9 @@ { u64 tsc; + /* This MSR is special and need a special fence: */ + weak_wrmsr_fence(); + tsc = rdtsc(); wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR)); return 0; @@ -490,7 +491,19 @@ v = apic_read(APIC_LVTT); v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); apic_write(APIC_LVTT, v); - apic_write(APIC_TMICT, 0); + + /* + * Setting APIC_LVT_MASKED (above) should be enough to tell + * the hardware that this timer will never fire. But AMD + * erratum 411 and some Intel CPU behavior circa 2024 say + * otherwise. Time for belt and suspenders programming: mask + * the timer _and_ zero the counter registers: + */ + if (v & APIC_LVT_TIMER_TSCDEADLINE) + wrmsrl(MSR_IA32_TSC_DEADLINE, 0); + else + apic_write(APIC_TMICT, 0); + return 0; } @@ -552,7 +565,7 @@ #define DEADLINE_MODEL_MATCH_REV(model, rev) \ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, (unsigned long)rev } -static u32 hsx_deadline_rev(void) +static __init u32 hsx_deadline_rev(void) { switch (boot_cpu_data.x86_stepping) { case 0x02: return 0x3a; /* EP */ @@ -562,7 +575,7 @@ return ~0U; } -static u32 bdx_deadline_rev(void) +static __init u32 bdx_deadline_rev(void) { switch (boot_cpu_data.x86_stepping) { case 0x02: return 0x00000011; @@ -574,7 +587,7 @@ return ~0U; } -static u32 skx_deadline_rev(void) +static __init u32 skx_deadline_rev(void) { switch (boot_cpu_data.x86_stepping) { case 0x03: return 0x01000136; @@ -587,7 +600,7 @@ return ~0U; } -static const struct x86_cpu_id deadline_match[] = { +static const struct x86_cpu_id deadline_match[] __initconst = { DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_HASWELL_X, hsx_deadline_rev), DEADLINE_MODEL_MATCH_REV ( INTEL_FAM6_BROADWELL_X, 0x0b000020), DEADLINE_MODEL_MATCH_FUNC( INTEL_FAM6_BROADWELL_D, bdx_deadline_rev), @@ -609,18 +622,19 @@ {}, }; -static void apic_check_deadline_errata(void) +static __init bool apic_validate_deadline_timer(void) { const struct x86_cpu_id *m; u32 rev; - if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER) || - boot_cpu_has(X86_FEATURE_HYPERVISOR)) - return; + if (!boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + return false; + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return true; m = x86_match_cpu(deadline_match); if (!m) - return; + return true; /* * Function pointers will have the MSB set due to address layout, @@ -632,11 +646,12 @@ rev = (u32)m->driver_data; if (boot_cpu_data.microcode >= rev) - return; + return true; setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER); pr_err(FW_BUG "TSC_DEADLINE disabled due to Errata; " "please update microcode to version: 0x%x (or later)\n", rev); + return false; } /* @@ -830,8 +845,17 @@ if (!tsc_khz || !cpu_khz) return true; - /* Is there an APIC at all? */ - if (!boot_cpu_has(X86_FEATURE_APIC)) + /* Is there an APIC at all or is it disabled? */ + if (!boot_cpu_has(X86_FEATURE_APIC) || disable_apic) + return true; + + /* + * If interrupt delivery mode is legacy PIC or virtual wire without + * configuration, the local APIC timer wont be set up. Make sure + * that the PIT is initialized. + */ + if (apic_intr_mode == APIC_PIC || + apic_intr_mode == APIC_VIRTUAL_WIRE_NO_CONFIG) return true; /* Virt guests may lack ARAT, but still have DEADLINE */ @@ -1322,7 +1346,7 @@ enum apic_intr_mode_id apic_intr_mode __ro_after_init; -static int __init apic_intr_mode_select(void) +static int __init __apic_intr_mode_select(void) { /* Check kernel option */ if (disable_apic) { @@ -1384,6 +1408,12 @@ return APIC_SYMMETRIC_IO; } +/* Select the interrupt delivery mode for the BSP */ +void __init apic_intr_mode_select(void) +{ + apic_intr_mode = __apic_intr_mode_select(); +} + /* * An initial setup of the virtual wire mode. */ @@ -1440,8 +1470,6 @@ { bool upmode = IS_ENABLED(CONFIG_UP_LATE_INIT); - apic_intr_mode = apic_intr_mode_select(); - switch (apic_intr_mode) { case APIC_PIC: pr_info("APIC: Keep in PIC mode(8259)\n"); @@ -1873,20 +1901,22 @@ return; if (remap_mode != IRQ_REMAP_X2APIC_MODE) { - /* IR is required if there is APIC ID > 255 even when running - * under KVM + /* + * Using X2APIC without IR is not architecturally supported + * on bare metal but may be supported in guests. */ - if (max_physical_apicid > 255 || - !x86_init.hyper.x2apic_available()) { + if (!x86_init.hyper.x2apic_available()) { pr_info("x2apic: IRQ remapping doesn't support X2APIC mode\n"); x2apic_disable(); return; } /* - * without IR all CPUs can be addressed by IOAPIC/MSI - * only in physical mode + * Without IR, all CPUs can be addressed by IOAPIC/MSI only + * in physical mode, and CPUs with an APIC ID that cannnot + * be addressed must not be brought online. */ + x2apic_set_max_apicid(255); x2apic_phys = 1; } x2apic_enable(); @@ -2085,7 +2115,8 @@ { unsigned int new_apicid; - apic_check_deadline_errata(); + if (apic_validate_deadline_timer()) + pr_info("TSC deadline timer available\n"); if (x2apic_mode) { boot_cpu_physical_apicid = read_apic_id(); @@ -2334,6 +2365,11 @@ [0 ... NR_CPUS - 1] = -1, }; +bool arch_match_cpu_phys_id(int cpu, u64 phys_id) +{ + return phys_id == cpuid_to_apicid[cpu]; +} + #ifdef CONFIG_SMP /** * apic_id_is_primary_thread - Check whether APIC ID belongs to a primary thread @@ -2554,6 +2590,7 @@ end_local_APIC_setup(); irq_remap_enable_fault_handling(); setup_IO_APIC(); + lapic_update_legacy_vectors(); } #ifdef CONFIG_UP_LATE_INIT --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/io_apic.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/io_apic.c @@ -1046,6 +1046,16 @@ if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { irq = mp_irqs[idx].srcbusirq; legacy = mp_is_legacy_irq(irq); + /* + * IRQ2 is unusable for historical reasons on systems which + * have a legacy PIC. See the comment vs. IRQ2 further down. + * + * If this gets removed at some point then the related code + * in lapic_assign_system_vectors() needs to be adjusted as + * well. + */ + if (legacy && irq == PIC_CASCADE_IR) + return -EINVAL; } mutex_lock(&ioapic_mutex); @@ -1727,9 +1737,10 @@ static inline bool ioapic_irqd_mask(struct irq_data *data) { - /* If we are moving the irq we need to mask it */ + /* If we are moving the IRQ we need to mask it */ if (unlikely(irqd_is_setaffinity_pending(data))) { - mask_ioapic_irq(data); + if (!irqd_irq_masked(data)) + mask_ioapic_irq(data); return true; } return false; @@ -1766,7 +1777,9 @@ */ if (!io_apic_level_ack_pending(data->chip_data)) irq_move_masked_irq(data); - unmask_ioapic_irq(data); + /* If the IRQ is masked in the core, leave it: */ + if (!irqd_irq_masked(data)) + unmask_ioapic_irq(data); } } #else @@ -1948,7 +1961,8 @@ .irq_set_affinity = ioapic_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static struct irq_chip ioapic_ir_chip __read_mostly = { @@ -1961,7 +1975,8 @@ .irq_set_affinity = ioapic_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static inline void init_IO_APIC_traps(void) @@ -2253,6 +2268,7 @@ legacy_pic->init(0); legacy_pic->make_irq(0); apic_write(APIC_LVT0, APIC_DM_EXTINT); + legacy_pic->unmask(0); unlock_ExtINT_logic(); @@ -2326,12 +2342,12 @@ ip->irqdomain = irq_domain_create_linear(fn, hwirqs, cfg->ops, (void *)(long)ioapic); - /* Release fw handle if it was allocated above */ - if (!cfg->dev) - irq_domain_free_fwnode(fn); - - if (!ip->irqdomain) + if (!ip->irqdomain) { + /* Release fw handle if it was allocated above */ + if (!cfg->dev) + irq_domain_free_fwnode(fn); return -ENOMEM; + } ip->irqdomain->parent = parent; @@ -2345,8 +2361,13 @@ static void ioapic_destroy_irqdomain(int idx) { + struct ioapic_domain_cfg *cfg = &ioapics[idx].irqdomain_cfg; + struct fwnode_handle *fn = ioapics[idx].irqdomain->fwnode; + if (ioapics[idx].irqdomain) { irq_domain_remove(ioapics[idx].irqdomain); + if (!cfg->dev) + irq_domain_free_fwnode(fn); ioapics[idx].irqdomain = NULL; } } @@ -2434,17 +2455,21 @@ unsigned int arch_dynirq_lower_bound(unsigned int from) { + unsigned int ret; + /* * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use * gsi_top if ioapic_dynirq_base hasn't been initialized yet. */ - if (!ioapic_initialized) - return gsi_top; + ret = ioapic_dynirq_base ? : gsi_top; + /* - * For DT enabled machines ioapic_dynirq_base is irrelevant and not - * updated. So simply return @from if ioapic_dynirq_base == 0. + * For DT enabled machines ioapic_dynirq_base is irrelevant and + * always 0. gsi_top can be 0 if there is no IO/APIC registered. + * 0 is an invalid interrupt number for dynamic allocations. Return + * @from instead. */ - return ioapic_dynirq_base ? : from; + return ret ? : from; } #ifdef CONFIG_X86_32 --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/msi.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/msi.c @@ -23,10 +23,8 @@ static struct irq_domain *msi_default_domain; -static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) +static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg) { - struct irq_cfg *cfg = irqd_cfg(data); - msg->address_hi = MSI_ADDR_BASE_HI; if (x2apic_enabled()) @@ -47,6 +45,129 @@ MSI_DATA_VECTOR(cfg->vector); } +static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg) +{ + __irq_msi_compose_msg(irqd_cfg(data), msg); +} + +static void irq_msi_update_msg(struct irq_data *irqd, struct irq_cfg *cfg) +{ + struct msi_msg msg[2] = { [1] = { }, }; + + __irq_msi_compose_msg(cfg, msg); + irq_data_get_irq_chip(irqd)->irq_write_msi_msg(irqd, msg); +} + +static int +msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force) +{ + struct irq_cfg old_cfg, *cfg = irqd_cfg(irqd); + struct irq_data *parent = irqd->parent_data; + unsigned int cpu; + int ret; + + /* Save the current configuration */ + cpu = cpumask_first(irq_data_get_effective_affinity_mask(irqd)); + old_cfg = *cfg; + + /* Allocate a new target vector */ + ret = parent->chip->irq_set_affinity(parent, mask, force); + if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE) + return ret; + + /* + * For non-maskable and non-remapped MSI interrupts the migration + * to a different destination CPU and a different vector has to be + * done careful to handle the possible stray interrupt which can be + * caused by the non-atomic update of the address/data pair. + * + * Direct update is possible when: + * - The MSI is maskable (remapped MSI does not use this code path)). + * The quirk bit is not set in this case. + * - The new vector is the same as the old vector + * - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up) + * - The interrupt is not yet started up + * - The new destination CPU is the same as the old destination CPU + */ + if (!irqd_msi_nomask_quirk(irqd) || + cfg->vector == old_cfg.vector || + old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR || + !irqd_is_started(irqd) || + cfg->dest_apicid == old_cfg.dest_apicid) { + irq_msi_update_msg(irqd, cfg); + return ret; + } + + /* + * Paranoia: Validate that the interrupt target is the local + * CPU. + */ + if (WARN_ON_ONCE(cpu != smp_processor_id())) { + irq_msi_update_msg(irqd, cfg); + return ret; + } + + /* + * Redirect the interrupt to the new vector on the current CPU + * first. This might cause a spurious interrupt on this vector if + * the device raises an interrupt right between this update and the + * update to the final destination CPU. + * + * If the vector is in use then the installed device handler will + * denote it as spurious which is no harm as this is a rare event + * and interrupt handlers have to cope with spurious interrupts + * anyway. If the vector is unused, then it is marked so it won't + * trigger the 'No irq handler for vector' warning in do_IRQ(). + * + * This requires to hold vector lock to prevent concurrent updates to + * the affected vector. + */ + lock_vector_lock(); + + /* + * Mark the new target vector on the local CPU if it is currently + * unused. Reuse the VECTOR_RETRIGGERED state which is also used in + * the CPU hotplug path for a similar purpose. This cannot be + * undone here as the current CPU has interrupts disabled and + * cannot handle the interrupt before the whole set_affinity() + * section is done. In the CPU unplug case, the current CPU is + * about to vanish and will not handle any interrupts anymore. The + * vector is cleaned up when the CPU comes online again. + */ + if (IS_ERR_OR_NULL(this_cpu_read(vector_irq[cfg->vector]))) + this_cpu_write(vector_irq[cfg->vector], VECTOR_RETRIGGERED); + + /* Redirect it to the new vector on the local CPU temporarily */ + old_cfg.vector = cfg->vector; + irq_msi_update_msg(irqd, &old_cfg); + + /* Now transition it to the target CPU */ + irq_msi_update_msg(irqd, cfg); + + /* + * All interrupts after this point are now targeted at the new + * vector/CPU. + * + * Drop vector lock before testing whether the temporary assignment + * to the local CPU was hit by an interrupt raised in the device, + * because the retrigger function acquires vector lock again. + */ + unlock_vector_lock(); + + /* + * Check whether the transition raced with a device interrupt and + * is pending in the local APICs IRR. It is safe to do this outside + * of vector lock as the irq_desc::lock of this interrupt is still + * held and interrupts are disabled: The check is not accessing the + * underlying vector store. It's just checking the local APIC's + * IRR. + */ + if (lapic_vector_set_in_irr(cfg->vector)) + irq_data_get_irq_chip(irqd)->irq_retrigger(irqd); + + return ret; +} + /* * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, * which implement the MSI or MSI-X Capability Structure. @@ -58,7 +179,9 @@ .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_compose_msi_msg = irq_msi_compose_msg, - .flags = IRQCHIP_SKIP_SET_WAKE, + .irq_set_affinity = msi_set_affinity, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) @@ -142,10 +265,13 @@ msi_default_domain = pci_msi_create_irq_domain(fn, &pci_msi_domain_info, parent); - irq_domain_free_fwnode(fn); } - if (!msi_default_domain) + if (!msi_default_domain) { + irq_domain_free_fwnode(fn); pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n"); + } else { + msi_default_domain->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK; + } } #ifdef CONFIG_IRQ_REMAP @@ -156,7 +282,8 @@ .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_vcpu_affinity = irq_chip_set_vcpu_affinity_parent, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static struct msi_domain_info pci_msi_ir_domain_info = { @@ -178,7 +305,8 @@ if (!fn) return NULL; d = pci_msi_create_irq_domain(fn, &pci_msi_ir_domain_info, parent); - irq_domain_free_fwnode(fn); + if (!d) + irq_domain_free_fwnode(fn); return d; } #endif @@ -198,7 +326,8 @@ .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_compose_msi_msg = irq_msi_compose_msg, .irq_write_msi_msg = dmar_msi_write_msg, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static irq_hw_number_t dmar_msi_get_hwirq(struct msi_domain_info *info, @@ -241,7 +370,8 @@ if (fn) { dmar_domain = msi_create_irq_domain(fn, &dmar_msi_domain_info, x86_vector_domain); - irq_domain_free_fwnode(fn); + if (!dmar_domain) + irq_domain_free_fwnode(fn); } out: mutex_unlock(&dmar_lock); @@ -295,7 +425,7 @@ .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_compose_msi_msg = irq_msi_compose_msg, .irq_write_msi_msg = hpet_msi_write_msg, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_AFFINITY_PRE_STARTUP, }; static irq_hw_number_t hpet_msi_get_hwirq(struct msi_domain_info *info, @@ -366,7 +496,10 @@ } d = msi_create_irq_domain(fn, domain_info, parent); - irq_domain_free_fwnode(fn); + if (!d) { + irq_domain_free_fwnode(fn); + kfree(domain_info); + } return d; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/vector.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/vector.c @@ -272,20 +272,24 @@ const struct cpumask *affmsk = irq_data_get_affinity_mask(irqd); int node = irq_data_get_node(irqd); - if (node == NUMA_NO_NODE) - goto all; - /* Try the intersection of @affmsk and node mask */ - cpumask_and(vector_searchmask, cpumask_of_node(node), affmsk); - if (!assign_vector_locked(irqd, vector_searchmask)) - return 0; - /* Try the node mask */ - if (!assign_vector_locked(irqd, cpumask_of_node(node))) - return 0; -all: + if (node != NUMA_NO_NODE) { + /* Try the intersection of @affmsk and node mask */ + cpumask_and(vector_searchmask, cpumask_of_node(node), affmsk); + if (!assign_vector_locked(irqd, vector_searchmask)) + return 0; + } + /* Try the full affinity mask */ cpumask_and(vector_searchmask, affmsk, cpu_online_mask); if (!assign_vector_locked(irqd, vector_searchmask)) return 0; + + if (node != NUMA_NO_NODE) { + /* Try the node mask */ + if (!assign_vector_locked(irqd, cpumask_of_node(node))) + return 0; + } + /* Try the full online mask */ return assign_vector_locked(irqd, cpu_online_mask); } @@ -446,12 +450,10 @@ trace_vector_activate(irqd->irq, apicd->is_managed, apicd->can_reserve, reserve); - /* Nothing to do for fixed assigned vectors */ - if (!apicd->can_reserve && !apicd->is_managed) - return 0; - raw_spin_lock_irqsave(&vector_lock, flags); - if (reserve || irqd_is_managed_and_shutdown(irqd)) + if (!apicd->can_reserve && !apicd->is_managed) + assign_irq_vector_any_locked(irqd); + else if (reserve || irqd_is_managed_and_shutdown(irqd)) vector_assign_managed_shutdown(irqd); else if (apicd->is_managed) ret = activate_managed(irqd); @@ -556,6 +558,10 @@ irqd->chip_data = apicd; irqd->hwirq = virq + i; irqd_set_single_target(irqd); + + /* Don't invoke affinity setter on deactivated interrupts */ + irqd_set_affinity_on_activate(irqd); + /* * Legacy vectors are already assigned when the IOAPIC * takes them over. They stay on the same vector. This is @@ -674,6 +680,26 @@ irq_matrix_assign_system(vector_matrix, ISA_IRQ_VECTOR(irq), replace); } +void __init lapic_update_legacy_vectors(void) +{ + unsigned int i; + + if (IS_ENABLED(CONFIG_X86_IO_APIC) && nr_ioapics > 0) + return; + + /* + * If the IO/APIC is disabled via config, kernel command line or + * lack of enumeration then all legacy interrupts are routed + * through the PIC. Make sure that they are marked as legacy + * vectors. PIC_CASCADE_IRQ has already been marked in + * lapic_assign_system_vectors(). + */ + for (i = 0; i < nr_legacy_irqs(); i++) { + if (i != PIC_CASCADE_IR) + lapic_assign_legacy_vector(i, true); + } +} + void __init lapic_assign_system_vectors(void) { unsigned int i, vector = 0; @@ -703,7 +729,6 @@ x86_vector_domain = irq_domain_create_tree(fn, &x86_vector_domain_ops, NULL); BUG_ON(x86_vector_domain == NULL); - irq_domain_free_fwnode(fn); irq_set_default_host(x86_vector_domain); arch_init_msi_domain(x86_vector_domain); @@ -769,20 +794,10 @@ static int apic_set_affinity(struct irq_data *irqd, const struct cpumask *dest, bool force) { - struct apic_chip_data *apicd = apic_chip_data(irqd); int err; - /* - * Core code can call here for inactive interrupts. For inactive - * interrupts which use managed or reservation mode there is no - * point in going through the vector assignment right now as the - * activation will assign a vector which fits the destination - * cpumask. Let the core code store the destination mask and be - * done with it. - */ - if (!irqd_is_activated(irqd) && - (apicd->is_managed || apicd->can_reserve)) - return IRQ_SET_MASK_OK; + if (WARN_ON_ONCE(!irqd_is_activated(irqd))) + return -EIO; raw_spin_lock(&vector_lock); cpumask_and(vector_searchmask, dest, cpu_online_mask); @@ -898,7 +913,8 @@ hlist_add_head(&apicd->clist, per_cpu_ptr(&cleanup_list, cpu)); apic->send_IPI(cpu, IRQ_MOVE_CLEANUP_VECTOR); } else { - apicd->prev_vector = 0; + pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu); + free_moved_vector(apicd); } raw_spin_unlock(&vector_lock); } @@ -934,6 +950,7 @@ */ void irq_force_complete_move(struct irq_desc *desc) { + unsigned int cpu = smp_processor_id(); struct apic_chip_data *apicd; struct irq_data *irqd; unsigned int vector; @@ -958,10 +975,11 @@ goto unlock; /* - * If prev_vector is empty, no action required. + * If prev_vector is empty or the descriptor is neither currently + * nor previously on the outgoing CPU no action required. */ vector = apicd->prev_vector; - if (!vector) + if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu)) goto unlock; /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/x2apic_cluster.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/x2apic_cluster.c @@ -29,7 +29,8 @@ { u32 dest = per_cpu(x86_cpu_to_logical_apicid, cpu); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); __x2apic_send_IPI_dest(dest, vector, APIC_DEST_LOGICAL); } @@ -41,7 +42,8 @@ unsigned long flags; u32 dest; - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); local_irq_save(flags); tmpmsk = this_cpu_cpumask_var_ptr(ipi_mask); --- linux-oracle-5.4.0.orig/arch/x86/kernel/apic/x2apic_phys.c +++ linux-oracle-5.4.0/arch/x86/kernel/apic/x2apic_phys.c @@ -8,6 +8,12 @@ int x2apic_phys; static struct apic apic_x2apic_phys; +static u32 x2apic_max_apicid __ro_after_init; + +void __init x2apic_set_max_apicid(u32 apicid) +{ + x2apic_max_apicid = apicid; +} static int __init set_x2apic_phys_mode(char *arg) { @@ -37,7 +43,8 @@ { u32 dest = per_cpu(x86_cpu_to_apicid, cpu); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); __x2apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL); } @@ -48,7 +55,8 @@ unsigned long this_cpu; unsigned long flags; - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); local_irq_save(flags); @@ -89,7 +97,10 @@ static int x2apic_phys_probe(void) { - if (x2apic_mode && (x2apic_phys || x2apic_fadt_phys())) + if (!x2apic_mode) + return 0; + + if (x2apic_phys || x2apic_fadt_phys()) return 1; return apic == &apic_x2apic_phys; @@ -98,6 +109,9 @@ /* Common x2apic functions, also used by x2apic_cluster */ int x2apic_apic_id_valid(u32 apicid) { + if (x2apic_max_apicid && apicid > x2apic_max_apicid) + return 0; + return 1; } @@ -116,7 +130,8 @@ { unsigned long cfg = __prepare_ICR(which, vector, 0); - x2apic_wrmsr_fence(); + /* x2apic MSRs are special and need a special fence: */ + weak_wrmsr_fence(); native_x2apic_icr_write(cfg, 0); } --- linux-oracle-5.4.0.orig/arch/x86/kernel/apm_32.c +++ linux-oracle-5.4.0/arch/x86/kernel/apm_32.c @@ -238,12 +238,6 @@ #endif /* - * The apm_bios device is one of the misc char devices. - * This is its minor number. - */ -#define APM_MINOR_DEV 134 - -/* * Various options can be changed at boot time as follows: * (We allow underscores for compatibility with the modules code) * apm=on/off enable/disable APM --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/amd.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/amd.c @@ -26,10 +26,6 @@ #include "cpu.h" -static const int amd_erratum_383[]; -static const int amd_erratum_400[]; -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum); - /* * nodes_per_socket: Stores the number of nodes per socket. * Refer to Fam15h Models 00-0fh BKDG - CPUID Fn8000_001E_ECX @@ -37,6 +33,87 @@ */ static u32 nodes_per_socket = 1; +/* + * AMD errata checking + * + * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or + * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that + * have an OSVW id assigned, which it takes as first argument. Both take a + * variable number of family-specific model-stepping ranges created by + * AMD_MODEL_RANGE(). + * + * Example: + * + * const int amd_erratum_319[] = + * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), + * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), + * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); + */ + +#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } +#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } +#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ + ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) +#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) +#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) +#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) + +static const int amd_erratum_400[] = + AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), + AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); + +static const int amd_erratum_383[] = + AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); + +/* #1054: Instructions Retired Performance Counter May Be Inaccurate */ +static const int amd_erratum_1054[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0, 0, 0x2f, 0xf)); + +static const int amd_zenbleed[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x30, 0x0, 0x4f, 0xf), + AMD_MODEL_RANGE(0x17, 0x60, 0x0, 0x7f, 0xf), + AMD_MODEL_RANGE(0x17, 0x90, 0x0, 0x91, 0xf), + AMD_MODEL_RANGE(0x17, 0xa0, 0x0, 0xaf, 0xf)); + +static const int amd_div0[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x17, 0x00, 0x0, 0x2f, 0xf), + AMD_MODEL_RANGE(0x17, 0x50, 0x0, 0x5f, 0xf)); + +static const int amd_erratum_1485[] = + AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x19, 0x10, 0x0, 0x1f, 0xf), + AMD_MODEL_RANGE(0x19, 0x60, 0x0, 0xaf, 0xf)); + +static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) +{ + int osvw_id = *erratum++; + u32 range; + u32 ms; + + if (osvw_id >= 0 && osvw_id < 65536 && + cpu_has(cpu, X86_FEATURE_OSVW)) { + u64 osvw_len; + + rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); + if (osvw_id < osvw_len) { + u64 osvw_bits; + + rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), + osvw_bits); + return osvw_bits & (1ULL << (osvw_id & 0x3f)); + } + } + + /* OSVW unavailable or ID unknown, match family-model-stepping range */ + ms = (cpu->x86_model << 4) | cpu->x86_stepping; + while ((range = *erratum++)) + if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && + (ms >= AMD_MODEL_RANGE_START(range)) && + (ms <= AMD_MODEL_RANGE_END(range))) + return true; + + return false; +} + static inline int rdmsrl_amd_safe(unsigned msr, unsigned long long *p) { u32 gprs[8] = { 0 }; @@ -334,7 +411,6 @@ */ static void amd_get_topology(struct cpuinfo_x86 *c) { - u8 node_id; int cpu = smp_processor_id(); /* get information required for multi-node processors */ @@ -344,7 +420,7 @@ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); - node_id = ecx & 0xff; + c->cpu_die_id = ecx & 0xff; if (c->x86 == 0x15) c->cu_id = ebx & 0xff; @@ -364,15 +440,15 @@ if (!err) c->x86_coreid_bits = get_count_order(c->x86_max_cores); - cacheinfo_amd_init_llc_id(c, cpu, node_id); + cacheinfo_amd_init_llc_id(c, cpu); } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - node_id = value & 7; + c->cpu_die_id = value & 7; - per_cpu(cpu_llc_id, cpu) = node_id; + per_cpu(cpu_llc_id, cpu) = c->cpu_die_id; } else return; @@ -397,7 +473,7 @@ /* Convert the initial APIC ID into the socket ID */ c->phys_proc_id = c->initial_apicid >> bits; /* use socket ID also for last level cache */ - per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; + per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id; } u16 amd_get_nb_id(int cpu) @@ -545,12 +621,12 @@ u32 ecx; ecx = cpuid_ecx(0x8000001e); - nodes_per_socket = ((ecx >> 8) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((ecx >> 8) & 7) + 1; } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - nodes_per_socket = ((value >> 3) & 7) + 1; + __max_die_per_package = nodes_per_socket = ((value >> 3) & 7) + 1; } if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) && @@ -587,7 +663,7 @@ * If BIOS has not enabled SME then don't advertise the * SME feature (set in scattered.c). * For SEV: If BIOS has not enabled SEV then don't advertise the - * SEV feature (set in scattered.c). + * SEV and SEV_ES feature (set in scattered.c). * * In all cases, since support for SME and SEV requires long mode, * don't advertise the feature under CONFIG_X86_32. @@ -615,9 +691,10 @@ return; clear_all: - clear_cpu_cap(c, X86_FEATURE_SME); + setup_clear_cpu_cap(X86_FEATURE_SME); clear_sev: - clear_cpu_cap(c, X86_FEATURE_SEV); + setup_clear_cpu_cap(X86_FEATURE_SEV); + setup_clear_cpu_cap(X86_FEATURE_SEV_ES); } } @@ -794,8 +871,6 @@ set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); } -#define MSR_AMD64_DE_CFG 0xC0011029 - static void init_amd_ln(struct cpuinfo_x86 *c) { /* @@ -894,12 +969,73 @@ node_reclaim_distance = 32; #endif + /* Fix up CPUID bits, but only if not virtualised. */ + if (!cpu_has(c, X86_FEATURE_HYPERVISOR)) { + + /* Erratum 1076: CPB feature bit not being set in CPUID. */ + if (!cpu_has(c, X86_FEATURE_CPB)) + set_cpu_cap(c, X86_FEATURE_CPB); + + /* + * Zen3 (Fam19 model < 0x10) parts are not susceptible to + * Branch Type Confusion, but predate the allocation of the + * BTC_NO bit. + */ + if (c->x86 == 0x19 && !cpu_has(c, X86_FEATURE_BTC_NO)) + set_cpu_cap(c, X86_FEATURE_BTC_NO); + } + /* - * Fix erratum 1076: CPB feature bit not being set in CPUID. - * Always set it, except when running under a hypervisor. + * Work around Erratum 1386. The XSAVES instruction malfunctions in + * certain circumstances on Zen1/2 uarch, and not all parts have had + * updated microcode at the time of writing (March 2023). + * + * Affected parts all have no supervisor XSAVE states, meaning that + * the XSAVEC instruction (which works fine) is equivalent. */ - if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_CPB)) - set_cpu_cap(c, X86_FEATURE_CPB); + if (c->x86 == 0x17) + clear_cpu_cap(c, X86_FEATURE_XSAVES); +} + +static bool cpu_has_zenbleed_microcode(void) +{ + u32 good_rev = 0; + + switch (boot_cpu_data.x86_model) { + case 0x30 ... 0x3f: good_rev = 0x0830107b; break; + case 0x60 ... 0x67: good_rev = 0x0860010c; break; + case 0x68 ... 0x6f: good_rev = 0x08608107; break; + case 0x70 ... 0x7f: good_rev = 0x08701033; break; + case 0xa0 ... 0xaf: good_rev = 0x08a00009; break; + + default: + return false; + break; + } + + if (boot_cpu_data.microcode < good_rev) + return false; + + return true; +} + +static void zenbleed_check(struct cpuinfo_x86 *c) +{ + if (!cpu_has_amd_erratum(c, amd_zenbleed)) + return; + + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) + return; + + if (!cpu_has(c, X86_FEATURE_AVX)) + return; + + if (!cpu_has_zenbleed_microcode()) { + pr_notice_once("Zenbleed: please update your microcode for the most optimal fix\n"); + msr_set_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); + } else { + msr_clear_bit(MSR_AMD64_DE_CFG, MSR_AMD64_DE_CFG_ZEN2_FP_BACKUP_FIX_BIT); + } } static void init_amd(struct cpuinfo_x86 *c) @@ -956,8 +1092,8 @@ * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. */ - msr_set_bit(MSR_F10H_DECFG, - MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); + msr_set_bit(MSR_AMD64_DE_CFG, + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); /* A serializing LFENCE stops RDTSC speculation */ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); @@ -978,6 +1114,24 @@ /* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */ if (!cpu_has(c, X86_FEATURE_XENPV)) set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); + + /* + * Turn on the Instructions Retired free counter on machines not + * susceptible to erratum #1054 "Instructions Retired Performance + * Counter May Be Inaccurate". + */ + if (cpu_has(c, X86_FEATURE_IRPERF) && + !cpu_has_amd_erratum(c, amd_erratum_1054)) + msr_set_bit(MSR_K7_HWCR, MSR_K7_HWCR_IRPERF_EN_BIT); + + check_null_seg_clears_base(c); + + zenbleed_check(c); + + if (cpu_has_amd_erratum(c, amd_div0)) { + pr_notice_once("AMD Zen1 DIV0 bug detected. Disable SMT for full protection.\n"); + setup_force_cpu_bug(X86_BUG_DIV0); + } } #ifdef CONFIG_X86_32 @@ -1073,70 +1227,6 @@ cpu_dev_register(amd_cpu_dev); -/* - * AMD errata checking - * - * Errata are defined as arrays of ints using the AMD_LEGACY_ERRATUM() or - * AMD_OSVW_ERRATUM() macros. The latter is intended for newer errata that - * have an OSVW id assigned, which it takes as first argument. Both take a - * variable number of family-specific model-stepping ranges created by - * AMD_MODEL_RANGE(). - * - * Example: - * - * const int amd_erratum_319[] = - * AMD_LEGACY_ERRATUM(AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0x4, 0x2), - * AMD_MODEL_RANGE(0x10, 0x8, 0x0, 0x8, 0x0), - * AMD_MODEL_RANGE(0x10, 0x9, 0x0, 0x9, 0x0)); - */ - -#define AMD_LEGACY_ERRATUM(...) { -1, __VA_ARGS__, 0 } -#define AMD_OSVW_ERRATUM(osvw_id, ...) { osvw_id, __VA_ARGS__, 0 } -#define AMD_MODEL_RANGE(f, m_start, s_start, m_end, s_end) \ - ((f << 24) | (m_start << 16) | (s_start << 12) | (m_end << 4) | (s_end)) -#define AMD_MODEL_RANGE_FAMILY(range) (((range) >> 24) & 0xff) -#define AMD_MODEL_RANGE_START(range) (((range) >> 12) & 0xfff) -#define AMD_MODEL_RANGE_END(range) ((range) & 0xfff) - -static const int amd_erratum_400[] = - AMD_OSVW_ERRATUM(1, AMD_MODEL_RANGE(0xf, 0x41, 0x2, 0xff, 0xf), - AMD_MODEL_RANGE(0x10, 0x2, 0x1, 0xff, 0xf)); - -static const int amd_erratum_383[] = - AMD_OSVW_ERRATUM(3, AMD_MODEL_RANGE(0x10, 0, 0, 0xff, 0xf)); - - -static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) -{ - int osvw_id = *erratum++; - u32 range; - u32 ms; - - if (osvw_id >= 0 && osvw_id < 65536 && - cpu_has(cpu, X86_FEATURE_OSVW)) { - u64 osvw_len; - - rdmsrl(MSR_AMD64_OSVW_ID_LENGTH, osvw_len); - if (osvw_id < osvw_len) { - u64 osvw_bits; - - rdmsrl(MSR_AMD64_OSVW_STATUS + (osvw_id >> 6), - osvw_bits); - return osvw_bits & (1ULL << (osvw_id & 0x3f)); - } - } - - /* OSVW unavailable or ID unknown, match family-model-stepping range */ - ms = (cpu->x86_model << 4) | cpu->x86_stepping; - while ((range = *erratum++)) - if ((cpu->x86 == AMD_MODEL_RANGE_FAMILY(range)) && - (ms >= AMD_MODEL_RANGE_START(range)) && - (ms <= AMD_MODEL_RANGE_END(range))) - return true; - - return false; -} - void set_dr_addr_mask(unsigned long mask, int dr) { if (!boot_cpu_has(X86_FEATURE_BPEXT)) @@ -1155,3 +1245,33 @@ break; } } + +static void zenbleed_check_cpu(void *unused) +{ + struct cpuinfo_x86 *c = &cpu_data(smp_processor_id()); + + zenbleed_check(c); + + if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && + cpu_has_amd_erratum(c, amd_erratum_1485)) + msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT); +} + +void amd_check_microcode(void) +{ + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) + return; + + on_each_cpu(zenbleed_check_cpu, NULL, 1); +} + +/* + * Issue a DIV 0/1 insn to clear any division data from previous DIV + * operations. + */ +void noinstr amd_clear_divider(void) +{ + asm volatile(ALTERNATIVE("", "div %2\n\t", X86_BUG_DIV0) + :: "a" (0), "d" (0), "r" (1)); +} +EXPORT_SYMBOL_GPL(amd_clear_divider); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/bugs.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/bugs.c @@ -9,7 +9,6 @@ * - Andrew D. Balsa (code cleanup). */ #include -#include #include #include #include @@ -25,32 +24,71 @@ #include #include #include -#include #include -#include #include #include #include +#include #include "cpu.h" static void __init spectre_v1_select_mitigation(void); static void __init spectre_v2_select_mitigation(void); +static void __init retbleed_select_mitigation(void); +static void __init spectre_v2_user_select_mitigation(void); static void __init ssb_select_mitigation(void); static void __init l1tf_select_mitigation(void); static void __init mds_select_mitigation(void); +static void __init md_clear_update_mitigation(void); +static void __init md_clear_select_mitigation(void); static void __init taa_select_mitigation(void); +static void __init mmio_select_mitigation(void); +static void __init srbds_select_mitigation(void); +static void __init gds_select_mitigation(void); -/* The base value of the SPEC_CTRL MSR that always has to be preserved. */ +/* The base value of the SPEC_CTRL MSR without task-specific bits set */ u64 x86_spec_ctrl_base; EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); + +/* The current value of the SPEC_CTRL MSR with task-specific bits set */ +DEFINE_PER_CPU(u64, x86_spec_ctrl_current); +EXPORT_SYMBOL_GPL(x86_spec_ctrl_current); + +static u64 __ro_after_init x86_arch_cap_msr; + static DEFINE_MUTEX(spec_ctrl_mutex); +/* Update SPEC_CTRL MSR and its cached copy unconditionally */ +static void update_spec_ctrl(u64 val) +{ + this_cpu_write(x86_spec_ctrl_current, val); + wrmsrl(MSR_IA32_SPEC_CTRL, val); +} + /* - * The vendor and possibly platform specific bits which can be modified in - * x86_spec_ctrl_base. + * Keep track of the SPEC_CTRL MSR value for the current task, which may differ + * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). */ -static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS; +void update_spec_ctrl_cond(u64 val) +{ + if (this_cpu_read(x86_spec_ctrl_current) == val) + return; + + this_cpu_write(x86_spec_ctrl_current, val); + + /* + * When KERNEL_IBRS this MSR is written on return-to-user, unless + * forced the update can be delayed until that time. + */ + if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS)) + wrmsrl(MSR_IA32_SPEC_CTRL, val); +} + +u64 spec_ctrl_current(void) +{ + return this_cpu_read(x86_spec_ctrl_current); +} +EXPORT_SYMBOL_GPL(spec_ctrl_current); /* * AMD specific MSR info for Speculative Store Bypass control. @@ -73,100 +111,63 @@ DEFINE_STATIC_KEY_FALSE(mds_idle_clear); EXPORT_SYMBOL_GPL(mds_idle_clear); -void __init check_bugs(void) -{ - identify_boot_cpu(); - - /* - * identify_boot_cpu() initialized SMT support information, let the - * core code know. - */ - cpu_smt_check_topology(); - - if (!IS_ENABLED(CONFIG_SMP)) { - pr_info("CPU: "); - print_cpu_info(&boot_cpu_data); - } +/* Controls CPU Fill buffer clear before KVM guest MMIO accesses */ +DEFINE_STATIC_KEY_FALSE(mmio_stale_data_clear); +EXPORT_SYMBOL_GPL(mmio_stale_data_clear); +void __init cpu_select_mitigations(void) +{ /* * Read the SPEC_CTRL MSR to account for reserved bits which may * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD * init code as it is not enumerated and depends on the family. */ - if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) + if (cpu_feature_enabled(X86_FEATURE_MSR_SPEC_CTRL)) { rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); - /* Allow STIBP in MSR_SPEC_CTRL if supported */ - if (boot_cpu_has(X86_FEATURE_STIBP)) - x86_spec_ctrl_mask |= SPEC_CTRL_STIBP; + /* + * Previously running kernel (kexec), may have some controls + * turned ON. Clear them and let the mitigations setup below + * rediscover them based on configuration. + */ + x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK; + } + + x86_arch_cap_msr = x86_read_arch_cap_msr(); /* Select the proper CPU mitigations before patching alternatives: */ spectre_v1_select_mitigation(); spectre_v2_select_mitigation(); - ssb_select_mitigation(); - l1tf_select_mitigation(); - mds_select_mitigation(); - taa_select_mitigation(); - - arch_smt_update(); - -#ifdef CONFIG_X86_32 /* - * Check whether we are able to run this kernel safely on SMP. - * - * - i386 is no longer supported. - * - In order to run on anything without a TSC, we need to be - * compiled for a i486. + * retbleed_select_mitigation() relies on the state set by + * spectre_v2_select_mitigation(); specifically it wants to know about + * spectre_v2=ibrs. */ - if (boot_cpu_data.x86 < 4) - panic("Kernel requires i486+ for 'invlpg' and other features"); - - init_utsname()->machine[1] = - '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); - alternative_instructions(); - - fpu__init_check_bugs(); -#else /* CONFIG_X86_64 */ - alternative_instructions(); - + retbleed_select_mitigation(); /* - * Make sure the first 2MB area is not mapped by huge pages - * There are typically fixed size MTRRs in there and overlapping - * MTRRs into large pages causes slow downs. - * - * Right now we don't do that with gbpages because there seems - * very little benefit for that case. + * spectre_v2_user_select_mitigation() relies on the state set by + * retbleed_select_mitigation(); specifically the STIBP selection is + * forced for UNRET. */ - if (!direct_gbpages) - set_memory_4k((unsigned long)__va(0), 1); -#endif + spectre_v2_user_select_mitigation(); + ssb_select_mitigation(); + l1tf_select_mitigation(); + md_clear_select_mitigation(); + srbds_select_mitigation(); + gds_select_mitigation(); } +/* + * NOTE: For VMX, this function is not called in the vmexit path. + * It uses vmx_spec_ctrl_restore_host() instead. + */ void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) { - u64 msrval, guestval, hostval = x86_spec_ctrl_base; + u64 msrval, guestval = guest_spec_ctrl, hostval = spec_ctrl_current(); struct thread_info *ti = current_thread_info(); - /* Is MSR_SPEC_CTRL implemented ? */ if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { - /* - * Restrict guest_spec_ctrl to supported values. Clear the - * modifiable bits in the host base value and or the - * modifiable bits from the guest value. - */ - guestval = hostval & ~x86_spec_ctrl_mask; - guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; - - /* SSBD controlled in MSR_SPEC_CTRL */ - if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || - static_cpu_has(X86_FEATURE_AMD_SSBD)) - hostval |= ssbd_tif_to_spec_ctrl(ti->flags); - - /* Conditional STIBP enabled? */ - if (static_branch_unlikely(&switch_to_cond_stibp)) - hostval |= stibp_tif_to_spec_ctrl(ti->flags); - if (hostval != guestval) { msrval = setguest ? guestval : hostval; wrmsrl(MSR_IA32_SPEC_CTRL, msrval); @@ -245,8 +246,6 @@ (mds_nosmt || cpu_mitigations_auto_nosmt())) cpu_smt_disable(false); } - - pr_info("%s\n", mds_strings[mds_mitigation]); } static int __init mds_cmdline(char *str) @@ -286,8 +285,6 @@ static void __init taa_select_mitigation(void) { - u64 ia32_cap; - if (!boot_cpu_has_bug(X86_BUG_TAA)) { taa_mitigation = TAA_MITIGATION_OFF; return; @@ -296,7 +293,7 @@ /* TSX previously disabled by tsx=off */ if (!boot_cpu_has(X86_FEATURE_RTM)) { taa_mitigation = TAA_MITIGATION_TSX_DISABLED; - goto out; + return; } if (cpu_mitigations_off()) { @@ -304,9 +301,13 @@ return; } - /* TAA mitigation is turned off on the cmdline (tsx_async_abort=off) */ - if (taa_mitigation == TAA_MITIGATION_OFF) - goto out; + /* + * TAA mitigation via VERW is turned off if both + * tsx_async_abort=off and mds=off are specified. + */ + if (taa_mitigation == TAA_MITIGATION_OFF && + mds_mitigation == MDS_MITIGATION_OFF) + return; if (boot_cpu_has(X86_FEATURE_MD_CLEAR)) taa_mitigation = TAA_MITIGATION_VERW; @@ -322,9 +323,8 @@ * On MDS_NO=1 CPUs if ARCH_CAP_TSX_CTRL_MSR is not set, microcode * update is required. */ - ia32_cap = x86_read_arch_cap_msr(); - if ( (ia32_cap & ARCH_CAP_MDS_NO) && - !(ia32_cap & ARCH_CAP_TSX_CTRL_MSR)) + if ( (x86_arch_cap_msr & ARCH_CAP_MDS_NO) && + !(x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR)) taa_mitigation = TAA_MITIGATION_UCODE_NEEDED; /* @@ -338,9 +338,6 @@ if (taa_nosmt || cpu_mitigations_auto_nosmt()) cpu_smt_disable(false); - -out: - pr_info("%s\n", taa_strings[taa_mitigation]); } static int __init tsx_async_abort_parse_cmdline(char *str) @@ -365,6 +362,383 @@ early_param("tsx_async_abort", tsx_async_abort_parse_cmdline); #undef pr_fmt +#define pr_fmt(fmt) "MMIO Stale Data: " fmt + +enum mmio_mitigations { + MMIO_MITIGATION_OFF, + MMIO_MITIGATION_UCODE_NEEDED, + MMIO_MITIGATION_VERW, +}; + +/* Default mitigation for Processor MMIO Stale Data vulnerabilities */ +static enum mmio_mitigations mmio_mitigation __ro_after_init = MMIO_MITIGATION_VERW; +static bool mmio_nosmt __ro_after_init = false; + +static const char * const mmio_strings[] = { + [MMIO_MITIGATION_OFF] = "Vulnerable", + [MMIO_MITIGATION_UCODE_NEEDED] = "Vulnerable: Clear CPU buffers attempted, no microcode", + [MMIO_MITIGATION_VERW] = "Mitigation: Clear CPU buffers", +}; + +static void __init mmio_select_mitigation(void) +{ + if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) || + boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) || + cpu_mitigations_off()) { + mmio_mitigation = MMIO_MITIGATION_OFF; + return; + } + + if (mmio_mitigation == MMIO_MITIGATION_OFF) + return; + + /* + * Enable CPU buffer clear mitigation for host and VMM, if also affected + * by MDS or TAA. Otherwise, enable mitigation for VMM only. + */ + if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) && + boot_cpu_has(X86_FEATURE_RTM))) + static_branch_enable(&mds_user_clear); + else + static_branch_enable(&mmio_stale_data_clear); + + /* + * If Processor-MMIO-Stale-Data bug is present and Fill Buffer data can + * be propagated to uncore buffers, clearing the Fill buffers on idle + * is required irrespective of SMT state. + */ + if (!(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) + static_branch_enable(&mds_idle_clear); + + /* + * Check if the system has the right microcode. + * + * CPU Fill buffer clear mitigation is enumerated by either an explicit + * FB_CLEAR or by the presence of both MD_CLEAR and L1D_FLUSH on MDS + * affected systems. + */ + if ((x86_arch_cap_msr & ARCH_CAP_FB_CLEAR) || + (boot_cpu_has(X86_FEATURE_MD_CLEAR) && + boot_cpu_has(X86_FEATURE_FLUSH_L1D) && + !(x86_arch_cap_msr & ARCH_CAP_MDS_NO))) + mmio_mitigation = MMIO_MITIGATION_VERW; + else + mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED; + + if (mmio_nosmt || cpu_mitigations_auto_nosmt()) + cpu_smt_disable(false); +} + +static int __init mmio_stale_data_parse_cmdline(char *str) +{ + if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) + return 0; + + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) { + mmio_mitigation = MMIO_MITIGATION_OFF; + } else if (!strcmp(str, "full")) { + mmio_mitigation = MMIO_MITIGATION_VERW; + } else if (!strcmp(str, "full,nosmt")) { + mmio_mitigation = MMIO_MITIGATION_VERW; + mmio_nosmt = true; + } + + return 0; +} +early_param("mmio_stale_data", mmio_stale_data_parse_cmdline); + +#undef pr_fmt +#define pr_fmt(fmt) "" fmt + +static void __init md_clear_update_mitigation(void) +{ + if (cpu_mitigations_off()) + return; + + if (!static_key_enabled(&mds_user_clear)) + goto out; + + /* + * mds_user_clear is now enabled. Update MDS, TAA and MMIO Stale Data + * mitigation, if necessary. + */ + if (mds_mitigation == MDS_MITIGATION_OFF && + boot_cpu_has_bug(X86_BUG_MDS)) { + mds_mitigation = MDS_MITIGATION_FULL; + mds_select_mitigation(); + } + if (taa_mitigation == TAA_MITIGATION_OFF && + boot_cpu_has_bug(X86_BUG_TAA)) { + taa_mitigation = TAA_MITIGATION_VERW; + taa_select_mitigation(); + } + if (mmio_mitigation == MMIO_MITIGATION_OFF && + boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) { + mmio_mitigation = MMIO_MITIGATION_VERW; + mmio_select_mitigation(); + } +out: + if (boot_cpu_has_bug(X86_BUG_MDS)) + pr_info("MDS: %s\n", mds_strings[mds_mitigation]); + if (boot_cpu_has_bug(X86_BUG_TAA)) + pr_info("TAA: %s\n", taa_strings[taa_mitigation]); + if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) + pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]); + else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) + pr_info("MMIO Stale Data: Unknown: No mitigations\n"); +} + +static void __init md_clear_select_mitigation(void) +{ + mds_select_mitigation(); + taa_select_mitigation(); + mmio_select_mitigation(); + + /* + * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update + * and print their mitigation after MDS, TAA and MMIO Stale Data + * mitigation selection is done. + */ + md_clear_update_mitigation(); +} + +#undef pr_fmt +#define pr_fmt(fmt) "SRBDS: " fmt + +enum srbds_mitigations { + SRBDS_MITIGATION_OFF, + SRBDS_MITIGATION_UCODE_NEEDED, + SRBDS_MITIGATION_FULL, + SRBDS_MITIGATION_TSX_OFF, + SRBDS_MITIGATION_HYPERVISOR, +}; + +static enum srbds_mitigations srbds_mitigation __ro_after_init = SRBDS_MITIGATION_FULL; + +static const char * const srbds_strings[] = { + [SRBDS_MITIGATION_OFF] = "Vulnerable", + [SRBDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", + [SRBDS_MITIGATION_FULL] = "Mitigation: Microcode", + [SRBDS_MITIGATION_TSX_OFF] = "Mitigation: TSX disabled", + [SRBDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", +}; + +static bool srbds_off; + +void update_srbds_msr(void) +{ + u64 mcu_ctrl; + + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return; + + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; + + if (!boot_cpu_has(X86_FEATURE_SRBDS_CTRL)) + return; + + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + + switch (srbds_mitigation) { + case SRBDS_MITIGATION_OFF: + case SRBDS_MITIGATION_TSX_OFF: + mcu_ctrl |= RNGDS_MITG_DIS; + break; + case SRBDS_MITIGATION_FULL: + mcu_ctrl &= ~RNGDS_MITG_DIS; + break; + default: + break; + } + + wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); +} + +static void __init srbds_select_mitigation(void) +{ + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return; + + /* + * Check to see if this is one of the MDS_NO systems supporting TSX that + * are only exposed to SRBDS when TSX is enabled or when CPU is affected + * by Processor MMIO Stale Data vulnerability. + */ + if ((x86_arch_cap_msr & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) && + !boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) + srbds_mitigation = SRBDS_MITIGATION_TSX_OFF; + else if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + srbds_mitigation = SRBDS_MITIGATION_HYPERVISOR; + else if (!boot_cpu_has(X86_FEATURE_SRBDS_CTRL)) + srbds_mitigation = SRBDS_MITIGATION_UCODE_NEEDED; + else if (cpu_mitigations_off() || srbds_off) + srbds_mitigation = SRBDS_MITIGATION_OFF; + + update_srbds_msr(); + pr_info("%s\n", srbds_strings[srbds_mitigation]); +} + +static int __init srbds_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!boot_cpu_has_bug(X86_BUG_SRBDS)) + return 0; + + srbds_off = !strcmp(str, "off"); + return 0; +} +early_param("srbds", srbds_parse_cmdline); + +#undef pr_fmt +#define pr_fmt(fmt) "GDS: " fmt + +enum gds_mitigations { + GDS_MITIGATION_OFF, + GDS_MITIGATION_UCODE_NEEDED, + GDS_MITIGATION_FORCE, + GDS_MITIGATION_FULL, + GDS_MITIGATION_FULL_LOCKED, + GDS_MITIGATION_HYPERVISOR, +}; + +#if IS_ENABLED(CONFIG_GDS_FORCE_MITIGATION) +static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FORCE; +#else +static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL; +#endif + +static const char * const gds_strings[] = { + [GDS_MITIGATION_OFF] = "Vulnerable", + [GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode", + [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode", + [GDS_MITIGATION_FULL] = "Mitigation: Microcode", + [GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)", + [GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status", +}; + +bool gds_ucode_mitigated(void) +{ + return (gds_mitigation == GDS_MITIGATION_FULL || + gds_mitigation == GDS_MITIGATION_FULL_LOCKED); +} +EXPORT_SYMBOL_GPL(gds_ucode_mitigated); + +void update_gds_msr(void) +{ + u64 mcu_ctrl_after; + u64 mcu_ctrl; + + switch (gds_mitigation) { + case GDS_MITIGATION_OFF: + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + mcu_ctrl |= GDS_MITG_DIS; + break; + case GDS_MITIGATION_FULL_LOCKED: + /* + * The LOCKED state comes from the boot CPU. APs might not have + * the same state. Make sure the mitigation is enabled on all + * CPUs. + */ + case GDS_MITIGATION_FULL: + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + mcu_ctrl &= ~GDS_MITG_DIS; + break; + case GDS_MITIGATION_FORCE: + case GDS_MITIGATION_UCODE_NEEDED: + case GDS_MITIGATION_HYPERVISOR: + return; + }; + + wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + + /* + * Check to make sure that the WRMSR value was not ignored. Writes to + * GDS_MITG_DIS will be ignored if this processor is locked but the boot + * processor was not. + */ + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after); + WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after); +} + +static void __init gds_select_mitigation(void) +{ + u64 mcu_ctrl; + + if (!boot_cpu_has_bug(X86_BUG_GDS)) + return; + + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { + gds_mitigation = GDS_MITIGATION_HYPERVISOR; + goto out; + } + + if (cpu_mitigations_off()) + gds_mitigation = GDS_MITIGATION_OFF; + /* Will verify below that mitigation _can_ be disabled */ + + /* No microcode */ + if (!(x86_arch_cap_msr & ARCH_CAP_GDS_CTRL)) { + if (gds_mitigation == GDS_MITIGATION_FORCE) { + /* + * This only needs to be done on the boot CPU so do it + * here rather than in update_gds_msr() + */ + setup_clear_cpu_cap(X86_FEATURE_AVX); + pr_warn("Microcode update needed! Disabling AVX as mitigation.\n"); + } else { + gds_mitigation = GDS_MITIGATION_UCODE_NEEDED; + } + goto out; + } + + /* Microcode has mitigation, use it */ + if (gds_mitigation == GDS_MITIGATION_FORCE) + gds_mitigation = GDS_MITIGATION_FULL; + + rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl); + if (mcu_ctrl & GDS_MITG_LOCKED) { + if (gds_mitigation == GDS_MITIGATION_OFF) + pr_warn("Mitigation locked. Disable failed.\n"); + + /* + * The mitigation is selected from the boot CPU. All other CPUs + * _should_ have the same state. If the boot CPU isn't locked + * but others are then update_gds_msr() will WARN() of the state + * mismatch. If the boot CPU is locked update_gds_msr() will + * ensure the other CPUs have the mitigation enabled. + */ + gds_mitigation = GDS_MITIGATION_FULL_LOCKED; + } + + update_gds_msr(); +out: + pr_info("%s\n", gds_strings[gds_mitigation]); +} + +static int __init gds_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!boot_cpu_has_bug(X86_BUG_GDS)) + return 0; + + if (!strcmp(str, "off")) + gds_mitigation = GDS_MITIGATION_OFF; + else if (!strcmp(str, "force")) + gds_mitigation = GDS_MITIGATION_FORCE; + + return 0; +} +early_param("gather_data_sampling", gds_parse_cmdline); + +#undef pr_fmt #define pr_fmt(fmt) "Spectre V1 : " fmt enum spectre_v1_mitigation { @@ -456,13 +830,106 @@ } early_param("nospectre_v1", nospectre_v1_cmdline); -#undef pr_fmt -#define pr_fmt(fmt) "Spectre V2 : " fmt - static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = SPECTRE_V2_NONE; -static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init = +#undef pr_fmt +#define pr_fmt(fmt) "RETBleed: " fmt + +enum retbleed_mitigation { + RETBLEED_MITIGATION_NONE, + RETBLEED_MITIGATION_IBRS, + RETBLEED_MITIGATION_EIBRS, +}; + +enum retbleed_mitigation_cmd { + RETBLEED_CMD_OFF, + RETBLEED_CMD_AUTO, +}; + +const char * const retbleed_strings[] = { + [RETBLEED_MITIGATION_NONE] = "Vulnerable", + [RETBLEED_MITIGATION_IBRS] = "Mitigation: IBRS", + [RETBLEED_MITIGATION_EIBRS] = "Mitigation: Enhanced IBRS", +}; + +static enum retbleed_mitigation retbleed_mitigation __ro_after_init = + RETBLEED_MITIGATION_NONE; +static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init = + RETBLEED_CMD_AUTO; + +static int __init retbleed_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) + retbleed_cmd = RETBLEED_CMD_OFF; + else if (!strcmp(str, "auto")) + retbleed_cmd = RETBLEED_CMD_AUTO; + else + pr_err("Unknown retbleed option (%s). Defaulting to 'auto'\n", str); + + return 0; +} +early_param("retbleed", retbleed_parse_cmdline); + +#define RETBLEED_UNTRAIN_MSG "WARNING: BTB untrained return thunk mitigation is only effective on AMD/Hygon!\n" +#define RETBLEED_COMPILER_MSG "WARNING: kernel not compiled with RETPOLINE or -mfunction-return capable compiler!\n" +#define RETBLEED_INTEL_MSG "WARNING: Spectre v2 mitigation leaves CPU vulnerable to RETBleed attacks, data leaks possible!\n" + +static void __init retbleed_select_mitigation(void) +{ + if (!boot_cpu_has_bug(X86_BUG_RETBLEED) || cpu_mitigations_off()) + return; + + switch (retbleed_cmd) { + case RETBLEED_CMD_OFF: + return; + + case RETBLEED_CMD_AUTO: + default: + /* + * The Intel mitigation (IBRS) was already selected in + * spectre_v2_select_mitigation(). + */ + + break; + } + + switch (retbleed_mitigation) { + default: + break; + } + + /* + * Let IBRS trump all on Intel without affecting the effects of the + * retbleed= cmdline option. + */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { + switch (spectre_v2_enabled) { + case SPECTRE_V2_IBRS: + retbleed_mitigation = RETBLEED_MITIGATION_IBRS; + break; + case SPECTRE_V2_EIBRS: + case SPECTRE_V2_EIBRS_RETPOLINE: + case SPECTRE_V2_EIBRS_LFENCE: + retbleed_mitigation = RETBLEED_MITIGATION_EIBRS; + break; + default: + pr_err(RETBLEED_INTEL_MSG); + } + } + + pr_info("%s\n", retbleed_strings[retbleed_mitigation]); +} + +#undef pr_fmt +#define pr_fmt(fmt) "Spectre V2 : " fmt + +static enum spectre_v2_user_mitigation spectre_v2_user_stibp __ro_after_init = + SPECTRE_V2_USER_NONE; +static enum spectre_v2_user_mitigation spectre_v2_user_ibpb __ro_after_init = SPECTRE_V2_USER_NONE; #ifdef CONFIG_RETPOLINE @@ -486,6 +953,33 @@ static inline const char *spectre_v2_module_string(void) { return ""; } #endif +#define SPECTRE_V2_LFENCE_MSG "WARNING: LFENCE mitigation is not recommended for this CPU, data leaks possible!\n" +#define SPECTRE_V2_EIBRS_EBPF_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS on, data leaks possible via Spectre v2 BHB attacks!\n" +#define SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG "WARNING: Unprivileged eBPF is enabled with eIBRS+LFENCE mitigation and SMT, data leaks possible via Spectre v2 BHB attacks!\n" +#define SPECTRE_V2_IBRS_PERF_MSG "WARNING: IBRS mitigation selected on Enhanced IBRS CPU, this may cause unnecessary performance loss\n" + +#ifdef CONFIG_BPF_SYSCALL +void unpriv_ebpf_notify(int new_state) +{ + if (new_state) + return; + + /* Unprivileged eBPF is enabled */ + + switch (spectre_v2_enabled) { + case SPECTRE_V2_EIBRS: + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); + break; + case SPECTRE_V2_EIBRS_LFENCE: + if (sched_smt_active()) + pr_err(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); + break; + default: + break; + } +} +#endif + static inline bool match_option(const char *arg, int arglen, const char *opt) { int len = strlen(opt); @@ -500,7 +994,11 @@ SPECTRE_V2_CMD_FORCE, SPECTRE_V2_CMD_RETPOLINE, SPECTRE_V2_CMD_RETPOLINE_GENERIC, - SPECTRE_V2_CMD_RETPOLINE_AMD, + SPECTRE_V2_CMD_RETPOLINE_LFENCE, + SPECTRE_V2_CMD_EIBRS, + SPECTRE_V2_CMD_EIBRS_RETPOLINE, + SPECTRE_V2_CMD_EIBRS_LFENCE, + SPECTRE_V2_CMD_IBRS, }; enum spectre_v2_user_cmd { @@ -541,13 +1039,15 @@ pr_info("spectre_v2_user=%s forced on command line.\n", reason); } +static __ro_after_init enum spectre_v2_mitigation_cmd spectre_v2_cmd; + static enum spectre_v2_user_cmd __init -spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd) +spectre_v2_parse_user_cmdline(void) { char arg[20]; int ret, i; - switch (v2_cmd) { + switch (spectre_v2_cmd) { case SPECTRE_V2_CMD_NONE: return SPECTRE_V2_USER_CMD_NONE; case SPECTRE_V2_CMD_FORCE: @@ -573,8 +1073,20 @@ return SPECTRE_V2_USER_CMD_AUTO; } +static inline bool spectre_v2_in_eibrs_mode(enum spectre_v2_mitigation mode) +{ + return mode == SPECTRE_V2_EIBRS || + mode == SPECTRE_V2_EIBRS_RETPOLINE || + mode == SPECTRE_V2_EIBRS_LFENCE; +} + +static inline bool spectre_v2_in_ibrs_mode(enum spectre_v2_mitigation mode) +{ + return spectre_v2_in_eibrs_mode(mode) || mode == SPECTRE_V2_IBRS; +} + static void __init -spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) +spectre_v2_user_select_mitigation(void) { enum spectre_v2_user_mitigation mode = SPECTRE_V2_USER_NONE; bool smt_possible = IS_ENABLED(CONFIG_SMP); @@ -587,7 +1099,7 @@ cpu_smt_control == CPU_SMT_NOT_SUPPORTED) smt_possible = false; - cmd = spectre_v2_parse_user_cmdline(v2_cmd); + cmd = spectre_v2_parse_user_cmdline(); switch (cmd) { case SPECTRE_V2_USER_CMD_NONE: goto set_mode; @@ -608,24 +1120,17 @@ break; } - /* - * At this point, an STIBP mode other than "off" has been set. - * If STIBP support is not being forced, check if STIBP always-on - * is preferred. - */ - if (mode != SPECTRE_V2_USER_STRICT && - boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) - mode = SPECTRE_V2_USER_STRICT_PREFERRED; - /* Initialize Indirect Branch Prediction Barrier */ if (boot_cpu_has(X86_FEATURE_IBPB)) { setup_force_cpu_cap(X86_FEATURE_USE_IBPB); + spectre_v2_user_ibpb = mode; switch (cmd) { case SPECTRE_V2_USER_CMD_FORCE: case SPECTRE_V2_USER_CMD_PRCTL_IBPB: case SPECTRE_V2_USER_CMD_SECCOMP_IBPB: static_branch_enable(&switch_mm_always_ibpb); + spectre_v2_user_ibpb = SPECTRE_V2_USER_STRICT; break; case SPECTRE_V2_USER_CMD_PRCTL: case SPECTRE_V2_USER_CMD_AUTO: @@ -641,28 +1146,47 @@ "always-on" : "conditional"); } - /* If enhanced IBRS is enabled no STIBP required */ - if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) + /* + * If no STIBP, Intel enhanced IBRS is enabled, or SMT impossible, STIBP + * is not required. + * + * Intel's Enhanced IBRS also protects against cross-thread branch target + * injection in user-mode as the IBRS bit remains always set which + * implicitly enables cross-thread protections. However, in legacy IBRS + * mode, the IBRS bit is set only on kernel entry and cleared on return + * to userspace. AMD Automatic IBRS also does not protect userspace. + * These modes therefore disable the implicit cross-thread protection, + * so allow for STIBP to be selected in those cases. + */ + if (!boot_cpu_has(X86_FEATURE_STIBP) || + !smt_possible || + (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && + !boot_cpu_has(X86_FEATURE_AUTOIBRS))) return; /* - * If SMT is not possible or STIBP is not available clear the STIBP - * mode. + * At this point, an STIBP mode other than "off" has been set. + * If STIBP support is not being forced, check if STIBP always-on + * is preferred. */ - if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP)) - mode = SPECTRE_V2_USER_NONE; + if (mode != SPECTRE_V2_USER_STRICT && + boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON)) + mode = SPECTRE_V2_USER_STRICT_PREFERRED; + + spectre_v2_user_stibp = mode; + set_mode: - spectre_v2_user = mode; - /* Only print the STIBP mode when SMT possible */ - if (smt_possible) - pr_info("%s\n", spectre_v2_user_strings[mode]); + pr_info("%s\n", spectre_v2_user_strings[mode]); } static const char * const spectre_v2_strings[] = { [SPECTRE_V2_NONE] = "Vulnerable", - [SPECTRE_V2_RETPOLINE_GENERIC] = "Mitigation: Full generic retpoline", - [SPECTRE_V2_RETPOLINE_AMD] = "Mitigation: Full AMD retpoline", - [SPECTRE_V2_IBRS_ENHANCED] = "Mitigation: Enhanced IBRS", + [SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines", + [SPECTRE_V2_LFENCE] = "Mitigation: LFENCE", + [SPECTRE_V2_EIBRS] = "Mitigation: Enhanced / Automatic IBRS", + [SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced / Automatic IBRS + LFENCE", + [SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced / Automatic IBRS + Retpolines", + [SPECTRE_V2_IBRS] = "Mitigation: IBRS", }; static const struct { @@ -673,9 +1197,14 @@ { "off", SPECTRE_V2_CMD_NONE, false }, { "on", SPECTRE_V2_CMD_FORCE, true }, { "retpoline", SPECTRE_V2_CMD_RETPOLINE, false }, - { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_AMD, false }, + { "retpoline,amd", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, + { "retpoline,lfence", SPECTRE_V2_CMD_RETPOLINE_LFENCE, false }, { "retpoline,generic", SPECTRE_V2_CMD_RETPOLINE_GENERIC, false }, + { "eibrs", SPECTRE_V2_CMD_EIBRS, false }, + { "eibrs,lfence", SPECTRE_V2_CMD_EIBRS_LFENCE, false }, + { "eibrs,retpoline", SPECTRE_V2_CMD_EIBRS_RETPOLINE, false }, { "auto", SPECTRE_V2_CMD_AUTO, false }, + { "ibrs", SPECTRE_V2_CMD_IBRS, false }, }; static void __init spec_v2_print_cond(const char *reason, bool secure) @@ -711,17 +1240,48 @@ } if ((cmd == SPECTRE_V2_CMD_RETPOLINE || - cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || - cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && + cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || + cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC || + cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || + cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && !IS_ENABLED(CONFIG_RETPOLINE)) { - pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); + pr_err("%s selected but not compiled in. Switching to AUTO select\n", + mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + + if ((cmd == SPECTRE_V2_CMD_EIBRS || + cmd == SPECTRE_V2_CMD_EIBRS_LFENCE || + cmd == SPECTRE_V2_CMD_EIBRS_RETPOLINE) && + !boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { + pr_err("%s selected but CPU doesn't have Enhanced or Automatic IBRS. Switching to AUTO select\n", + mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + + if ((cmd == SPECTRE_V2_CMD_RETPOLINE_LFENCE || + cmd == SPECTRE_V2_CMD_EIBRS_LFENCE) && + !boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { + pr_err("%s selected, but CPU doesn't have a serializing LFENCE. Switching to AUTO select\n", + mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + + if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { + pr_err("%s selected but not Intel CPU. Switching to AUTO select\n", + mitigation_options[i].option); + return SPECTRE_V2_CMD_AUTO; + } + + if (cmd == SPECTRE_V2_CMD_IBRS && !boot_cpu_has(X86_FEATURE_IBRS)) { + pr_err("%s selected but CPU doesn't have IBRS. Switching to AUTO select\n", + mitigation_options[i].option); return SPECTRE_V2_CMD_AUTO; } - if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD && - boot_cpu_data.x86_vendor != X86_VENDOR_HYGON && - boot_cpu_data.x86_vendor != X86_VENDOR_AMD) { - pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n"); + if (cmd == SPECTRE_V2_CMD_IBRS && boot_cpu_has(X86_FEATURE_XENPV)) { + pr_err("%s selected but running as XenPV guest. Switching to AUTO select\n", + mitigation_options[i].option); return SPECTRE_V2_CMD_AUTO; } @@ -730,6 +1290,160 @@ return cmd; } +static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void) +{ + if (!IS_ENABLED(CONFIG_RETPOLINE)) { + pr_err("Kernel not compiled with retpoline; no mitigation available!"); + return SPECTRE_V2_NONE; + } + + return SPECTRE_V2_RETPOLINE; +} + +static bool __ro_after_init rrsba_disabled; + +/* Disable in-kernel use of non-RSB RET predictors */ +static void __init spec_ctrl_disable_kernel_rrsba(void) +{ + if (rrsba_disabled) + return; + + if (!(x86_arch_cap_msr & ARCH_CAP_RRSBA)) { + rrsba_disabled = true; + return; + } + + if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL)) + return; + + x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S; + update_spec_ctrl(x86_spec_ctrl_base); + rrsba_disabled = true; +} + +static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode) +{ + /* + * Similar to context switches, there are two types of RSB attacks + * after VM exit: + * + * 1) RSB underflow + * + * 2) Poisoned RSB entry + * + * When retpoline is enabled, both are mitigated by filling/clearing + * the RSB. + * + * When IBRS is enabled, while #1 would be mitigated by the IBRS branch + * prediction isolation protections, RSB still needs to be cleared + * because of #2. Note that SMEP provides no protection here, unlike + * user-space-poisoned RSB entries. + * + * eIBRS should protect against RSB poisoning, but if the EIBRS_PBRSB + * bug is present then a LITE version of RSB protection is required, + * just a single call needs to retire before a RET is executed. + */ + switch (mode) { + case SPECTRE_V2_NONE: + return; + + case SPECTRE_V2_EIBRS_LFENCE: + case SPECTRE_V2_EIBRS: + if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { + setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); + pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n"); + } + return; + + case SPECTRE_V2_EIBRS_RETPOLINE: + case SPECTRE_V2_RETPOLINE: + case SPECTRE_V2_LFENCE: + case SPECTRE_V2_IBRS: + setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); + pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n"); + return; + } + + pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit"); + dump_stack(); +} + +/* + * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by + * branch history in userspace. Not needed if BHI_NO is set. + */ +static bool __init spec_ctrl_bhi_dis(void) +{ + if (!boot_cpu_has(X86_FEATURE_BHI_CTRL)) + return false; + + x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S; + update_spec_ctrl(x86_spec_ctrl_base); + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW); + + return true; +} + +enum bhi_mitigations { + BHI_MITIGATION_OFF, + BHI_MITIGATION_ON, + BHI_MITIGATION_AUTO, +}; + +static enum bhi_mitigations bhi_mitigation __ro_after_init = + IS_ENABLED(CONFIG_SPECTRE_BHI_ON) ? BHI_MITIGATION_ON : + IS_ENABLED(CONFIG_SPECTRE_BHI_OFF) ? BHI_MITIGATION_OFF : + BHI_MITIGATION_AUTO; + +static int __init spectre_bhi_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) + bhi_mitigation = BHI_MITIGATION_OFF; + else if (!strcmp(str, "on")) + bhi_mitigation = BHI_MITIGATION_ON; + else if (!strcmp(str, "auto")) + bhi_mitigation = BHI_MITIGATION_AUTO; + else + pr_err("Ignoring unknown spectre_bhi option (%s)", str); + + return 0; +} +early_param("spectre_bhi", spectre_bhi_parse_cmdline); + +static void __init bhi_select_mitigation(void) +{ + if (bhi_mitigation == BHI_MITIGATION_OFF) + return; + + /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */ + if (boot_cpu_has(X86_FEATURE_RETPOLINE) && + !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) { + spec_ctrl_disable_kernel_rrsba(); + if (rrsba_disabled) + return; + } + + if (spec_ctrl_bhi_dis()) + return; + + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + /* Mitigate KVM by default */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT); + pr_info("Spectre BHI mitigation: SW BHB clearing on vm exit\n"); + + if (bhi_mitigation == BHI_MITIGATION_AUTO) + return; + + /* Mitigate syscalls when the mitigation is forced =on */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP); + pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n"); +} + static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -750,86 +1464,168 @@ case SPECTRE_V2_CMD_FORCE: case SPECTRE_V2_CMD_AUTO: if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) { - mode = SPECTRE_V2_IBRS_ENHANCED; - /* Force it so VMEXIT will restore correctly */ - x86_spec_ctrl_base |= SPEC_CTRL_IBRS; - wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); - goto specv2_set_mode; + mode = SPECTRE_V2_EIBRS; + break; + } + + if (boot_cpu_has_bug(X86_BUG_RETBLEED) && + retbleed_cmd != RETBLEED_CMD_OFF && + boot_cpu_has(X86_FEATURE_IBRS) && + boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { + mode = SPECTRE_V2_IBRS; + break; } - if (IS_ENABLED(CONFIG_RETPOLINE)) - goto retpoline_auto; + + mode = spectre_v2_select_retpoline(); break; - case SPECTRE_V2_CMD_RETPOLINE_AMD: - if (IS_ENABLED(CONFIG_RETPOLINE)) - goto retpoline_amd; + + case SPECTRE_V2_CMD_RETPOLINE_LFENCE: + pr_err(SPECTRE_V2_LFENCE_MSG); + mode = SPECTRE_V2_LFENCE; break; + case SPECTRE_V2_CMD_RETPOLINE_GENERIC: - if (IS_ENABLED(CONFIG_RETPOLINE)) - goto retpoline_generic; + mode = SPECTRE_V2_RETPOLINE; break; + case SPECTRE_V2_CMD_RETPOLINE: - if (IS_ENABLED(CONFIG_RETPOLINE)) - goto retpoline_auto; + mode = spectre_v2_select_retpoline(); + break; + + case SPECTRE_V2_CMD_IBRS: + mode = SPECTRE_V2_IBRS; + break; + + case SPECTRE_V2_CMD_EIBRS: + mode = SPECTRE_V2_EIBRS; + break; + + case SPECTRE_V2_CMD_EIBRS_LFENCE: + mode = SPECTRE_V2_EIBRS_LFENCE; + break; + + case SPECTRE_V2_CMD_EIBRS_RETPOLINE: + mode = SPECTRE_V2_EIBRS_RETPOLINE; break; } - pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); - return; -retpoline_auto: - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || - boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) { - retpoline_amd: - if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { - pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); - goto retpoline_generic; + if (mode == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) + pr_err(SPECTRE_V2_EIBRS_EBPF_MSG); + + if (spectre_v2_in_ibrs_mode(mode)) { + if (boot_cpu_has(X86_FEATURE_AUTOIBRS)) { + msr_set_bit(MSR_EFER, _EFER_AUTOIBRS); + } else { + x86_spec_ctrl_base |= SPEC_CTRL_IBRS; + update_spec_ctrl(x86_spec_ctrl_base); } - mode = SPECTRE_V2_RETPOLINE_AMD; - setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); - setup_force_cpu_cap(X86_FEATURE_RETPOLINE); - } else { - retpoline_generic: - mode = SPECTRE_V2_RETPOLINE_GENERIC; + } + + switch (mode) { + case SPECTRE_V2_NONE: + case SPECTRE_V2_EIBRS: + break; + + case SPECTRE_V2_IBRS: + setup_force_cpu_cap(X86_FEATURE_KERNEL_IBRS); + if (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED)) + pr_warn(SPECTRE_V2_IBRS_PERF_MSG); + break; + + case SPECTRE_V2_LFENCE: + case SPECTRE_V2_EIBRS_LFENCE: + setup_force_cpu_cap(X86_FEATURE_RETPOLINE_LFENCE); + fallthrough; + + case SPECTRE_V2_RETPOLINE: + case SPECTRE_V2_EIBRS_RETPOLINE: setup_force_cpu_cap(X86_FEATURE_RETPOLINE); + break; } -specv2_set_mode: + /* + * Disable alternate RSB predictions in kernel when indirect CALLs and + * JMPs gets protection against BHI and Intramode-BTI, but RET + * prediction from a non-RSB predictor is still a risk. + */ + if (mode == SPECTRE_V2_EIBRS_LFENCE || + mode == SPECTRE_V2_EIBRS_RETPOLINE || + mode == SPECTRE_V2_RETPOLINE) + spec_ctrl_disable_kernel_rrsba(); + + if (boot_cpu_has(X86_BUG_BHI)) + bhi_select_mitigation(); + spectre_v2_enabled = mode; pr_info("%s\n", spectre_v2_strings[mode]); /* - * If spectre v2 protection has been enabled, unconditionally fill - * RSB during a context switch; this protects against two independent - * issues: + * If Spectre v2 protection has been enabled, fill the RSB during a + * context switch. In general there are two types of RSB attacks + * across context switches, for which the CALLs/RETs may be unbalanced. + * + * 1) RSB underflow + * + * Some Intel parts have "bottomless RSB". When the RSB is empty, + * speculated return targets may come from the branch predictor, + * which could have a user-poisoned BTB or BHB entry. + * + * AMD has it even worse: *all* returns are speculated from the BTB, + * regardless of the state of the RSB. + * + * When IBRS or eIBRS is enabled, the "user -> kernel" attack + * scenario is mitigated by the IBRS branch prediction isolation + * properties, so the RSB buffer filling wouldn't be necessary to + * protect against this type of attack. + * + * The "user -> user" attack scenario is mitigated by RSB filling. + * + * 2) Poisoned RSB entry * - * - RSB underflow (and switch to BTB) on Skylake+ - * - SpectreRSB variant of spectre v2 on X86_BUG_SPECTRE_V2 CPUs + * If the 'next' in-kernel return stack is shorter than 'prev', + * 'next' could be tricked into speculating with a user-poisoned RSB + * entry. + * + * The "user -> kernel" attack scenario is mitigated by SMEP and + * eIBRS. + * + * The "user -> user" scenario, also known as SpectreBHB, requires + * RSB clearing. + * + * So to mitigate all cases, unconditionally fill RSB on context + * switches. + * + * FIXME: Is this pointless for retbleed-affected AMD? */ setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); + spectre_v2_determine_rsb_fill_type_at_vmexit(mode); + /* - * Retpoline means the kernel is safe because it has no indirect - * branches. Enhanced IBRS protects firmware too, so, enable restricted - * speculation around firmware calls only when Enhanced IBRS isn't - * supported. + * Retpoline protects the kernel, but doesn't protect firmware. IBRS + * and Enhanced IBRS protect firmware too, so enable IBRS around + * firmware calls only when IBRS / Enhanced / Automatic IBRS aren't + * otherwise enabled. * * Use "mode" to check Enhanced IBRS instead of boot_cpu_has(), because * the user might select retpoline on the kernel command line and if * the CPU supports Enhanced IBRS, kernel might un-intentionally not * enable IBRS around firmware calls. */ - if (boot_cpu_has(X86_FEATURE_IBRS) && mode != SPECTRE_V2_IBRS_ENHANCED) { + if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) { setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); pr_info("Enabling Restricted Speculation for firmware calls\n"); } /* Set up IBPB and STIBP depending on the general spectre V2 command */ - spectre_v2_user_select_mitigation(cmd); + spectre_v2_cmd = cmd; } static void update_stibp_msr(void * __unused) { - wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP); + update_spec_ctrl(val); } /* Update x86_spec_ctrl_base in case SMT state changed. */ @@ -875,20 +1671,27 @@ if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY)) return; - if (sched_smt_active()) + if (sched_smt_active()) { static_branch_enable(&mds_idle_clear); - else + } else if (mmio_mitigation == MMIO_MITIGATION_OFF || + (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) { static_branch_disable(&mds_idle_clear); + } } #define MDS_MSG_SMT "MDS CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for more details.\n" #define TAA_MSG_SMT "TAA CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/tsx_async_abort.html for more details.\n" +#define MMIO_MSG_SMT "MMIO Stale Data CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/processor_mmio_stale_data.html for more details.\n" void cpu_bugs_smt_update(void) { mutex_lock(&spec_ctrl_mutex); - switch (spectre_v2_user) { + if (sched_smt_active() && unprivileged_ebpf_enabled() && + spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) + pr_warn_once(SPECTRE_V2_EIBRS_LFENCE_EBPF_SMT_MSG); + + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: break; case SPECTRE_V2_USER_STRICT: @@ -923,6 +1726,16 @@ break; } + switch (mmio_mitigation) { + case MMIO_MITIGATION_VERW: + case MMIO_MITIGATION_UCODE_NEEDED: + if (sched_smt_active()) + pr_warn_once(MMIO_MSG_SMT); + break; + case MMIO_MITIGATION_OFF: + break; + } + mutex_unlock(&spec_ctrl_mutex); } @@ -1027,16 +1840,6 @@ } /* - * If SSBD is controlled by the SPEC_CTRL MSR, then set the proper - * bit in the mask to allow guests to use the mitigation even in the - * case where the host does not enable it. - */ - if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || - static_cpu_has(X86_FEATURE_AMD_SSBD)) { - x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; - } - - /* * We have three CPU feature flags that are in play here: * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible. * - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass @@ -1053,7 +1856,7 @@ x86_amd_ssb_disable(); } else { x86_spec_ctrl_base |= SPEC_CTRL_SSBD; - wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + update_spec_ctrl(x86_spec_ctrl_base); } } @@ -1127,19 +1930,40 @@ return 0; } +static bool is_spec_ib_user_controlled(void) +{ + return spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP; +} + static int ib_prctl_set(struct task_struct *task, unsigned long ctrl) { switch (ctrl) { case PR_SPEC_ENABLE: - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return 0; /* - * Indirect branch speculation is always disabled in strict - * mode. + * With strict mode for both IBPB and STIBP, the instruction + * code paths avoid checking this task flag and instead, + * unconditionally run the instruction. However, STIBP and IBPB + * are independent and either can be set to conditionally + * enabled regardless of the mode of the other. + * + * If either is set to conditional, allow the task flag to be + * updated, unless it was force-disabled by a previous prctl + * call. Currently, this is possible on an AMD CPU which has the + * feature X86_FEATURE_AMD_STIBP_ALWAYS_ON. In this case, if the + * kernel is booted with 'spectre_v2_user=seccomp', then + * spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP and + * spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED. */ - if (spectre_v2_user == SPECTRE_V2_USER_STRICT || - spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) + if (!is_spec_ib_user_controlled() || + task_spec_ib_force_disable(task)) return -EPERM; + task_clear_spec_ib_disable(task); task_update_spec_tif(task); break; @@ -1149,15 +1973,19 @@ * Indirect branch speculation is always allowed when * mitigation is force disabled. */ - if (spectre_v2_user == SPECTRE_V2_USER_NONE) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return -EPERM; - if (spectre_v2_user == SPECTRE_V2_USER_STRICT || - spectre_v2_user == SPECTRE_V2_USER_STRICT_PREFERRED) + + if (!is_spec_ib_user_controlled()) return 0; + task_set_spec_ib_disable(task); if (ctrl == PR_SPEC_FORCE_DISABLE) task_set_spec_ib_force_disable(task); task_update_spec_tif(task); + if (task == current) + indirect_branch_prediction_barrier(); break; default: return -ERANGE; @@ -1183,7 +2011,8 @@ { if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); - if (spectre_v2_user == SPECTRE_V2_USER_SECCOMP) + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP || + spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) ib_prctl_set(task, PR_SPEC_FORCE_DISABLE); } #endif @@ -1214,22 +2043,21 @@ if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) return PR_SPEC_NOT_AFFECTED; - switch (spectre_v2_user) { - case SPECTRE_V2_USER_NONE: + if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE && + spectre_v2_user_stibp == SPECTRE_V2_USER_NONE) return PR_SPEC_ENABLE; - case SPECTRE_V2_USER_PRCTL: - case SPECTRE_V2_USER_SECCOMP: + else if (is_spec_ib_user_controlled()) { if (task_spec_ib_force_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; if (task_spec_ib_disable(task)) return PR_SPEC_PRCTL | PR_SPEC_DISABLE; return PR_SPEC_PRCTL | PR_SPEC_ENABLE; - case SPECTRE_V2_USER_STRICT: - case SPECTRE_V2_USER_STRICT_PREFERRED: + } else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT || + spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED) return PR_SPEC_DISABLE; - default: + else return PR_SPEC_NOT_AFFECTED; - } } int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) @@ -1247,7 +2075,7 @@ void x86_spec_ctrl_setup_ap(void) { if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) - wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + update_spec_ctrl(x86_spec_ctrl_base); if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) x86_amd_ssb_disable(); @@ -1398,87 +2226,105 @@ static ssize_t l1tf_show_state(char *buf) { if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_AUTO) - return sprintf(buf, "%s\n", L1TF_DEFAULT_MSG); + return sysfs_emit(buf, "%s\n", L1TF_DEFAULT_MSG); if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_EPT_DISABLED || (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_NEVER && sched_smt_active())) { - return sprintf(buf, "%s; VMX: %s\n", L1TF_DEFAULT_MSG, - l1tf_vmx_states[l1tf_vmx_mitigation]); + return sysfs_emit(buf, "%s; VMX: %s\n", L1TF_DEFAULT_MSG, + l1tf_vmx_states[l1tf_vmx_mitigation]); } - return sprintf(buf, "%s; VMX: %s, SMT %s\n", L1TF_DEFAULT_MSG, - l1tf_vmx_states[l1tf_vmx_mitigation], - sched_smt_active() ? "vulnerable" : "disabled"); + return sysfs_emit(buf, "%s; VMX: %s, SMT %s\n", L1TF_DEFAULT_MSG, + l1tf_vmx_states[l1tf_vmx_mitigation], + sched_smt_active() ? "vulnerable" : "disabled"); } static ssize_t itlb_multihit_show_state(char *buf) { if (itlb_multihit_kvm_mitigation) - return sprintf(buf, "KVM: Mitigation: Split huge pages\n"); + return sysfs_emit(buf, "KVM: Mitigation: Split huge pages\n"); else - return sprintf(buf, "KVM: Vulnerable\n"); + return sysfs_emit(buf, "KVM: Vulnerable\n"); } #else static ssize_t l1tf_show_state(char *buf) { - return sprintf(buf, "%s\n", L1TF_DEFAULT_MSG); + return sysfs_emit(buf, "%s\n", L1TF_DEFAULT_MSG); } static ssize_t itlb_multihit_show_state(char *buf) { - return sprintf(buf, "Processor vulnerable\n"); + return sysfs_emit(buf, "Processor vulnerable\n"); } #endif static ssize_t mds_show_state(char *buf) { if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { - return sprintf(buf, "%s; SMT Host state unknown\n", - mds_strings[mds_mitigation]); + return sysfs_emit(buf, "%s; SMT Host state unknown\n", + mds_strings[mds_mitigation]); } if (boot_cpu_has(X86_BUG_MSBDS_ONLY)) { - return sprintf(buf, "%s; SMT %s\n", mds_strings[mds_mitigation], - (mds_mitigation == MDS_MITIGATION_OFF ? "vulnerable" : - sched_smt_active() ? "mitigated" : "disabled")); + return sysfs_emit(buf, "%s; SMT %s\n", mds_strings[mds_mitigation], + (mds_mitigation == MDS_MITIGATION_OFF ? "vulnerable" : + sched_smt_active() ? "mitigated" : "disabled")); } - return sprintf(buf, "%s; SMT %s\n", mds_strings[mds_mitigation], - sched_smt_active() ? "vulnerable" : "disabled"); + return sysfs_emit(buf, "%s; SMT %s\n", mds_strings[mds_mitigation], + sched_smt_active() ? "vulnerable" : "disabled"); } static ssize_t tsx_async_abort_show_state(char *buf) { if ((taa_mitigation == TAA_MITIGATION_TSX_DISABLED) || (taa_mitigation == TAA_MITIGATION_OFF)) - return sprintf(buf, "%s\n", taa_strings[taa_mitigation]); + return sysfs_emit(buf, "%s\n", taa_strings[taa_mitigation]); if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { - return sprintf(buf, "%s; SMT Host state unknown\n", - taa_strings[taa_mitigation]); + return sysfs_emit(buf, "%s; SMT Host state unknown\n", + taa_strings[taa_mitigation]); } - return sprintf(buf, "%s; SMT %s\n", taa_strings[taa_mitigation], - sched_smt_active() ? "vulnerable" : "disabled"); + return sysfs_emit(buf, "%s; SMT %s\n", taa_strings[taa_mitigation], + sched_smt_active() ? "vulnerable" : "disabled"); +} + +static ssize_t mmio_stale_data_show_state(char *buf) +{ + if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) + return sysfs_emit(buf, "Unknown: No mitigations\n"); + + if (mmio_mitigation == MMIO_MITIGATION_OFF) + return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]); + + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { + return sysfs_emit(buf, "%s; SMT Host state unknown\n", + mmio_strings[mmio_mitigation]); + } + + return sysfs_emit(buf, "%s; SMT %s\n", mmio_strings[mmio_mitigation], + sched_smt_active() ? "vulnerable" : "disabled"); } static char *stibp_state(void) { - if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) + if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && + !boot_cpu_has(X86_FEATURE_AUTOIBRS)) return ""; - switch (spectre_v2_user) { + switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: - return ", STIBP: disabled"; + return "; STIBP: disabled"; case SPECTRE_V2_USER_STRICT: - return ", STIBP: forced"; + return "; STIBP: forced"; case SPECTRE_V2_USER_STRICT_PREFERRED: - return ", STIBP: always-on"; + return "; STIBP: always-on"; case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_SECCOMP: if (static_key_enabled(&switch_to_cond_stibp)) - return ", STIBP: conditional"; + return "; STIBP: conditional"; } return ""; } @@ -1487,43 +2333,108 @@ { if (boot_cpu_has(X86_FEATURE_IBPB)) { if (static_key_enabled(&switch_mm_always_ibpb)) - return ", IBPB: always-on"; + return "; IBPB: always-on"; if (static_key_enabled(&switch_mm_cond_ibpb)) - return ", IBPB: conditional"; - return ", IBPB: disabled"; + return "; IBPB: conditional"; + return "; IBPB: disabled"; } return ""; } +static char *pbrsb_eibrs_state(void) +{ + if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { + if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) || + boot_cpu_has(X86_FEATURE_RSB_VMEXIT)) + return "; PBRSB-eIBRS: SW sequence"; + else + return "; PBRSB-eIBRS: Vulnerable"; + } else { + return "; PBRSB-eIBRS: Not affected"; + } +} + +static const char * const spectre_bhi_state(void) +{ + if (!boot_cpu_has_bug(X86_BUG_BHI)) + return "; BHI: Not affected"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW)) + return "; BHI: BHI_DIS_S"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP)) + return "; BHI: SW loop, KVM: SW loop"; + else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && + !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) && + rrsba_disabled) + return "; BHI: Retpoline"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT)) + return "; BHI: Vulnerable, KVM: SW loop"; + + return "; BHI: Vulnerable"; +} + +static ssize_t spectre_v2_show_state(char *buf) +{ + if (spectre_v2_enabled == SPECTRE_V2_LFENCE) + return sysfs_emit(buf, "Vulnerable: LFENCE\n"); + + if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled()) + return sysfs_emit(buf, "Vulnerable: eIBRS with unprivileged eBPF\n"); + + if (sched_smt_active() && unprivileged_ebpf_enabled() && + spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) + return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); + + return sprintf(buf, "%s%s%s%s%s%s%s%s\n", + spectre_v2_strings[spectre_v2_enabled], + ibpb_state(), + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "", + stibp_state(), + boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "", + pbrsb_eibrs_state(), + spectre_bhi_state(), + /* this should always be at the end */ + spectre_v2_module_string()); +} + +static ssize_t srbds_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", srbds_strings[srbds_mitigation]); +} + +static ssize_t retbleed_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", retbleed_strings[retbleed_mitigation]); +} + +static ssize_t gds_show_state(char *buf) +{ + return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]); +} + static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, char *buf, unsigned int bug) { if (!boot_cpu_has_bug(bug)) - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); switch (bug) { case X86_BUG_CPU_MELTDOWN: if (boot_cpu_has(X86_FEATURE_PTI)) - return sprintf(buf, "Mitigation: PTI\n"); + return sysfs_emit(buf, "Mitigation: PTI\n"); if (hypervisor_is_type(X86_HYPER_XEN_PV)) - return sprintf(buf, "Unknown (XEN PV detected, hypervisor mitigation required)\n"); + return sysfs_emit(buf, "Unknown (XEN PV detected, hypervisor mitigation required)\n"); break; case X86_BUG_SPECTRE_V1: - return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); + return sysfs_emit(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); case X86_BUG_SPECTRE_V2: - return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], - ibpb_state(), - boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", - stibp_state(), - boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", - spectre_v2_module_string()); + return spectre_v2_show_state(buf); case X86_BUG_SPEC_STORE_BYPASS: - return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); + return sysfs_emit(buf, "%s\n", ssb_strings[ssb_mode]); case X86_BUG_L1TF: if (boot_cpu_has(X86_FEATURE_L1TF_PTEINV)) @@ -1539,11 +2450,24 @@ case X86_BUG_ITLB_MULTIHIT: return itlb_multihit_show_state(buf); + case X86_BUG_SRBDS: + return srbds_show_state(buf); + + case X86_BUG_MMIO_STALE_DATA: + case X86_BUG_MMIO_UNKNOWN: + return mmio_stale_data_show_state(buf); + + case X86_BUG_RETBLEED: + return retbleed_show_state(buf); + + case X86_BUG_GDS: + return gds_show_state(buf); + default: break; } - return sprintf(buf, "Vulnerable\n"); + return sysfs_emit(buf, "Vulnerable\n"); } ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) @@ -1585,4 +2509,27 @@ { return cpu_show_common(dev, attr, buf, X86_BUG_ITLB_MULTIHIT); } + +ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_SRBDS); +} + +ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf) +{ + if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN)) + return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_UNKNOWN); + else + return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA); +} + +ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED); +} + +ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_GDS); +} #endif --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/cacheinfo.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/cacheinfo.c @@ -646,7 +646,7 @@ return i; } -void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) +void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu) { /* * We may have multiple LLCs if L3 caches exist, so check if we @@ -657,7 +657,7 @@ if (c->x86 < 0x17) { /* LLC is at the node level. */ - per_cpu(cpu_llc_id, cpu) = node_id; + per_cpu(cpu_llc_id, cpu) = c->cpu_die_id; } else if (c->x86 == 0x17 && c->x86_model <= 0x1F) { /* * LLC is at the core complex level. @@ -684,7 +684,7 @@ } } -void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id) +void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu) { /* * We may have multiple LLCs if L3 caches exist, so check if we @@ -795,7 +795,7 @@ cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); /* If bit 31 is set, this is an unknown format */ - for (j = 0 ; j < 3 ; j++) + for (j = 0 ; j < 4 ; j++) if (regs[j] & (1 << 31)) regs[j] = 0; @@ -985,7 +985,7 @@ this_leaf->priv = base->nb; } -static int __init_cache_level(unsigned int cpu) +int init_cache_level(unsigned int cpu) { struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); @@ -1014,7 +1014,7 @@ id4_regs->id = c->apicid >> index_msb; } -static int __populate_cache_leaves(unsigned int cpu) +int populate_cache_leaves(unsigned int cpu) { unsigned int idx, ret; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); @@ -1033,6 +1033,3 @@ return 0; } - -DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level) -DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves) --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/common.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/common.c @@ -17,10 +17,14 @@ #include #include #include +#include #include +#include #include #include +#include +#include #include #include #include @@ -57,6 +61,7 @@ #ifdef CONFIG_X86_LOCAL_APIC #include #endif +#include #include "cpu.h" @@ -366,6 +371,9 @@ cr4_clear_bits(X86_CR4_UMIP); } +/* These bits should not change their value after CPU init is finished. */ +static const unsigned long cr4_pinned_mask = + X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | X86_CR4_FSGSBASE; static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning); static unsigned long cr4_pinned_bits __ro_after_init; @@ -374,7 +382,7 @@ unsigned long bits_missing = 0; set_register: - asm volatile("mov %0,%%cr0": "+r" (val), "+m" (__force_order)); + asm volatile("mov %0,%%cr0": "+r" (val) : : "memory"); if (static_branch_likely(&cr_pinning)) { if (unlikely((val & X86_CR0_WP) != X86_CR0_WP)) { @@ -390,20 +398,20 @@ void native_write_cr4(unsigned long val) { - unsigned long bits_missing = 0; + unsigned long bits_changed = 0; set_register: - asm volatile("mov %0,%%cr4": "+r" (val), "+m" (cr4_pinned_bits)); + asm volatile("mov %0,%%cr4": "+r" (val) : : "memory"); if (static_branch_likely(&cr_pinning)) { - if (unlikely((val & cr4_pinned_bits) != cr4_pinned_bits)) { - bits_missing = ~val & cr4_pinned_bits; - val |= bits_missing; + if (unlikely((val & cr4_pinned_mask) != cr4_pinned_bits)) { + bits_changed = (val & cr4_pinned_mask) ^ cr4_pinned_bits; + val = (val & ~cr4_pinned_mask) | cr4_pinned_bits; goto set_register; } - /* Warn after we've set the missing bits. */ - WARN_ONCE(bits_missing, "CR4 bits went missing: %lx!?\n", - bits_missing); + /* Warn after we've corrected the changed bits. */ + WARN_ONCE(bits_changed, "pinned CR4 bits changed: 0x%lx!?\n", + bits_changed); } } EXPORT_SYMBOL(native_write_cr4); @@ -415,7 +423,7 @@ if (boot_cpu_has(X86_FEATURE_PCID)) cr4 |= X86_CR4_PCIDE; if (static_branch_likely(&cr_pinning)) - cr4 |= cr4_pinned_bits; + cr4 = (cr4 & ~cr4_pinned_mask) | cr4_pinned_bits; __write_cr4(cr4); @@ -430,10 +438,7 @@ */ static void __init setup_cr_pinning(void) { - unsigned long mask; - - mask = (X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP); - cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & mask; + cr4_pinned_bits = this_cpu_read(cpu_tlbstate.cr4) & cr4_pinned_mask; static_key_enable(&cr_pinning.key); } @@ -444,8 +449,6 @@ static __always_inline void setup_pku(struct cpuinfo_x86 *c) { - struct pkru_state *pk; - /* check the boot processor, plus compile options for PKU: */ if (!cpu_feature_enabled(X86_FEATURE_PKU)) return; @@ -456,15 +459,12 @@ return; cr4_set_bits(X86_CR4_PKE); - pk = get_xsave_addr(&init_fpstate.xsave, XFEATURE_PKRU); - if (pk) - pk->pkru = init_pkru_value; /* * Seting X86_CR4_PKE will cause the X86_FEATURE_OSPKE * cpuid bit to be set. We need to ensure that we * update that bit in this CPU's "cpu_info". */ - get_cpu_cap(c); + set_cpu_cap(c, X86_FEATURE_OSPKE); } #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS @@ -961,6 +961,12 @@ if (c->extended_cpuid_level >= 0x8000000a) c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); + if (c->extended_cpuid_level >= 0x8000001f) + c->x86_capability[CPUID_8000_001F_EAX] = cpuid_eax(0x8000001f); + + if (c->extended_cpuid_level >= 0x80000021) + c->x86_capability[CPUID_8000_0021_EAX] = cpuid_eax(0x80000021); + init_scattered_cpuid_features(c); init_speculation_control(c); init_cqm(c); @@ -1024,6 +1030,10 @@ #define MSBDS_ONLY BIT(5) #define NO_SWAPGS BIT(6) #define NO_ITLB_MULTIHIT BIT(7) +#define NO_SPECTRE_V2 BIT(8) +#define NO_EIBRS_PBRSB BIT(9) +#define NO_MMIO BIT(10) +#define NO_BHI BIT(11) #define VULNWL(_vendor, _family, _model, _whitelist) \ { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } @@ -1044,6 +1054,11 @@ VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), /* Intel Family 6 */ + VULNWL_INTEL(TIGERLAKE, NO_MMIO), + VULNWL_INTEL(TIGERLAKE_L, NO_MMIO), + VULNWL_INTEL(ALDERLAKE, NO_MMIO), + VULNWL_INTEL(ALDERLAKE_L, NO_MMIO), + VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), @@ -1062,9 +1077,9 @@ VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), + VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), + VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), + VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), /* * Technically, swapgs isn't serializing on AMD (despite it previously @@ -1074,65 +1089,154 @@ * good enough for our purposes. */ - VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT), + VULNWL_INTEL(ATOM_TREMONT, NO_EIBRS_PBRSB), + VULNWL_INTEL(ATOM_TREMONT_L, NO_EIBRS_PBRSB), + VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), /* AMD Family 0xf - 0x12 */ - VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ - VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), - VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI | NO_EIBRS_PBRSB), + VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI | NO_EIBRS_PBRSB), + + /* Zhaoxin Family 7 */ + VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_MMIO | NO_BHI), + VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_MMIO | NO_BHI), + {} +}; + +#define VULNBL(vendor, family, model, blacklist) \ + X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, blacklist) + +#define VULNBL_INTEL_STEPPINGS(model, steppings, issues) \ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, \ + INTEL_FAM6_##model, steppings, \ + X86_FEATURE_ANY, issues) + +#define VULNBL_AMD(family, blacklist) \ + VULNBL(AMD, family, X86_MODEL_ANY, blacklist) + +#define VULNBL_HYGON(family, blacklist) \ + VULNBL(HYGON, family, X86_MODEL_ANY, blacklist) + +#define SRBDS BIT(0) +/* CPU is affected by X86_BUG_MMIO_STALE_DATA */ +#define MMIO BIT(1) +/* CPU is affected by Shared Buffers Data Sampling (SBDS), a variant of X86_BUG_MMIO_STALE_DATA */ +#define MMIO_SBDS BIT(2) +/* CPU is affected by RETbleed, speculating where you would not expect it */ +#define RETBLEED BIT(3) +/* CPU is affected by SMT (cross-thread) return predictions */ +#define SMT_RSB BIT(4) +/* CPU is affected by GDS */ +#define GDS BIT(5) + +static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { + VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_G, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(HASWELL_X, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(BROADWELL_D, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), + VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), + VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS), + VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED), + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS), + VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS), + VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED), + VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS), + + VULNBL_AMD(0x15, RETBLEED), + VULNBL_AMD(0x16, RETBLEED), + VULNBL_AMD(0x17, RETBLEED | SMT_RSB), + VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), {} }; -static bool __init cpu_matches(unsigned long which) +static bool __init cpu_matches(const struct x86_cpu_id *table, unsigned long which) { - const struct x86_cpu_id *m = x86_match_cpu(cpu_vuln_whitelist); + const struct x86_cpu_id *m = x86_match_cpu(table); return m && !!(m->driver_data & which); } u64 x86_read_arch_cap_msr(void) { - u64 ia32_cap = 0; + u64 x86_arch_cap_msr = 0; if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES)) - rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, x86_arch_cap_msr); + + return x86_arch_cap_msr; +} - return ia32_cap; +static bool arch_cap_mmio_immune(u64 x86_arch_cap_msr) +{ + return (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO && + x86_arch_cap_msr & ARCH_CAP_PSDP_NO && + x86_arch_cap_msr & ARCH_CAP_SBDR_SSDP_NO); } static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) { - u64 ia32_cap = x86_read_arch_cap_msr(); + u64 x86_arch_cap_msr = x86_read_arch_cap_msr(); /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */ - if (!cpu_matches(NO_ITLB_MULTIHIT) && !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) + if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) && + !(x86_arch_cap_msr & ARCH_CAP_PSCHANGE_MC_NO)) setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT); - if (cpu_matches(NO_SPECULATION)) + if (cpu_matches(cpu_vuln_whitelist, NO_SPECULATION)) return; setup_force_cpu_bug(X86_BUG_SPECTRE_V1); - setup_force_cpu_bug(X86_BUG_SPECTRE_V2); - if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) && + if (!cpu_matches(cpu_vuln_whitelist, NO_SPECTRE_V2)) + setup_force_cpu_bug(X86_BUG_SPECTRE_V2); + + if (!cpu_matches(cpu_vuln_whitelist, NO_SSB) && + !(x86_arch_cap_msr & ARCH_CAP_SSB_NO) && !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); - if (ia32_cap & ARCH_CAP_IBRS_ALL) + /* + * AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature + * flag and protect from vendor-specific bugs via the whitelist. + */ + if ((x86_arch_cap_msr & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) { setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); + if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) && + !(x86_arch_cap_msr & ARCH_CAP_PBRSB_NO)) + setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB); + } - if (!cpu_matches(NO_MDS) && !(ia32_cap & ARCH_CAP_MDS_NO)) { + if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) && + !(x86_arch_cap_msr & ARCH_CAP_MDS_NO)) { setup_force_cpu_bug(X86_BUG_MDS); - if (cpu_matches(MSBDS_ONLY)) + if (cpu_matches(cpu_vuln_whitelist, MSBDS_ONLY)) setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); } - if (!cpu_matches(NO_SWAPGS)) + if (!cpu_matches(cpu_vuln_whitelist, NO_SWAPGS)) setup_force_cpu_bug(X86_BUG_SWAPGS); /* @@ -1145,21 +1249,76 @@ * TSX_CTRL check alone is not sufficient for cases when the microcode * update is not present or running as guest that don't get TSX_CTRL. */ - if (!(ia32_cap & ARCH_CAP_TAA_NO) && + if (!(x86_arch_cap_msr & ARCH_CAP_TAA_NO) && (cpu_has(c, X86_FEATURE_RTM) || - (ia32_cap & ARCH_CAP_TSX_CTRL_MSR))) + (x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR))) setup_force_cpu_bug(X86_BUG_TAA); - if (cpu_matches(NO_MELTDOWN)) + /* + * SRBDS affects CPUs which support RDRAND or RDSEED and are listed + * in the vulnerability blacklist. + * + * Some of the implications and mitigation of Shared Buffers Data + * Sampling (SBDS) are similar to SRBDS. Give SBDS same treatment as + * SRBDS. + */ + if ((cpu_has(c, X86_FEATURE_RDRAND) || + cpu_has(c, X86_FEATURE_RDSEED)) && + cpu_matches(cpu_vuln_blacklist, SRBDS | MMIO_SBDS)) + setup_force_cpu_bug(X86_BUG_SRBDS); + + /* + * Processor MMIO Stale Data bug enumeration + * + * Affected CPU list is generally enough to enumerate the vulnerability, + * but for virtualization case check for ARCH_CAP MSR bits also, VMM may + * not want the guest to enumerate the bug. + * + * Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist, + * nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits. + */ + if (!arch_cap_mmio_immune(x86_arch_cap_msr)) { + if (cpu_matches(cpu_vuln_blacklist, MMIO)) + setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); + else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO)) + setup_force_cpu_bug(X86_BUG_MMIO_UNKNOWN); + } + + if (!cpu_has(c, X86_FEATURE_BTC_NO)) { + if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (x86_arch_cap_msr & ARCH_CAP_RSBA)) + setup_force_cpu_bug(X86_BUG_RETBLEED); + } + + if (cpu_matches(cpu_vuln_blacklist, SMT_RSB)) + setup_force_cpu_bug(X86_BUG_SMT_RSB); + + /* + * Check if CPU is vulnerable to GDS. If running in a virtual machine on + * an affected processor, the VMM may have disabled the use of GATHER by + * disabling AVX2. The only way to do this in HW is to clear XCR0[2], + * which means that AVX will be disabled. + */ + if (cpu_matches(cpu_vuln_blacklist, GDS) && !(x86_arch_cap_msr & ARCH_CAP_GDS_NO) && + boot_cpu_has(X86_FEATURE_AVX)) + setup_force_cpu_bug(X86_BUG_GDS); + + /* When virtualized, eIBRS could be hidden, assume vulnerable */ + if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) && + !cpu_matches(cpu_vuln_whitelist, NO_BHI) && + (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || + boot_cpu_has(X86_FEATURE_HYPERVISOR))) + setup_force_cpu_bug(X86_BUG_BHI); + + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; /* Rogue Data Cache Load? No! */ - if (ia32_cap & ARCH_CAP_RDCL_NO) + if (x86_arch_cap_msr & ARCH_CAP_RDCL_NO) return; setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); - if (cpu_matches(NO_L1TF)) + if (cpu_matches(cpu_vuln_whitelist, NO_L1TF)) return; setup_force_cpu_bug(X86_BUG_L1TF); @@ -1235,8 +1394,6 @@ cpu_set_bug_bits(c); - fpu__init_system(c); - #ifdef CONFIG_X86_32 /* * Regardless of whether PCID is enumerated, the SDM says @@ -1296,9 +1453,8 @@ early_identify_cpu(&boot_cpu_data); } -static void detect_null_seg_behavior(struct cpuinfo_x86 *c) +static bool detect_null_seg_behavior(void) { -#ifdef CONFIG_X86_64 /* * Empirically, writing zero to a segment selector on AMD does * not clear the base, whereas writing zero to a segment @@ -1319,10 +1475,43 @@ wrmsrl(MSR_FS_BASE, 1); loadsegment(fs, 0); rdmsrl(MSR_FS_BASE, tmp); - if (tmp != 0) - set_cpu_bug(c, X86_BUG_NULL_SEG); wrmsrl(MSR_FS_BASE, old_base); -#endif + return tmp == 0; +} + +void check_null_seg_clears_base(struct cpuinfo_x86 *c) +{ + /* BUG_NULL_SEG is only relevant with 64bit userspace */ + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + /* Zen3 CPUs advertise Null Selector Clears Base in CPUID. */ + if (c->extended_cpuid_level >= 0x80000021 && + cpuid_eax(0x80000021) & BIT(6)) + return; + + /* + * CPUID bit above wasn't set. If this kernel is still running + * as a HV guest, then the HV has decided not to advertize + * that CPUID bit for whatever reason. For example, one + * member of the migration pool might be vulnerable. Which + * means, the bug is present: set the BUG flag and return. + */ + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) { + set_cpu_bug(c, X86_BUG_NULL_SEG); + return; + } + + /* + * Zen2 CPUs also have this behaviour, but no CPUID bit. + * 0x18 is the respective family for Hygon. + */ + if ((c->x86 == 0x17 || c->x86 == 0x18) && + detect_null_seg_behavior()) + return; + + /* All the remaining ones are affected */ + set_cpu_bug(c, X86_BUG_NULL_SEG); } static void generic_identify(struct cpuinfo_x86 *c) @@ -1358,8 +1547,6 @@ get_model_name(c); /* Default name */ - detect_null_seg_behavior(c); - /* * ESPFIX is a strange bug. All real CPUs have it. Paravirt * systems that run Linux at CPL > 0 may or may not have the @@ -1597,6 +1784,9 @@ mtrr_ap_init(); validate_apic_and_package_id(c); x86_spec_ctrl_setup_ap(); + update_srbds_msr(); + if (boot_cpu_has_bug(X86_BUG_GDS)) + update_gds_msr(); } static __init int setup_noclflush(char *arg) @@ -1785,7 +1975,7 @@ unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu)); struct desc_struct d = { }; - if (boot_cpu_has(X86_FEATURE_RDTSCP)) + if (boot_cpu_has(X86_FEATURE_RDTSCP) || boot_cpu_has(X86_FEATURE_RDPID)) write_rdtscp_aux(cpudata); /* Store CPU and node number in limit. */ @@ -1895,8 +2085,6 @@ clear_all_debug_regs(); dbg_restore_debug_regs(); - fpu__init_cpu(); - if (is_uv_system()) uv_cpu_init(); @@ -1954,8 +2142,6 @@ clear_all_debug_regs(); dbg_restore_debug_regs(); - fpu__init_cpu(); - load_fixmap_gdt(cpu); } #endif @@ -1974,6 +2160,8 @@ /* Reload CPUID max function as it might've changed. */ info.cpuid_level = cpuid_eax(0); + amd_check_microcode(); + /* * Copy all capability leafs to pick up the synthetic ones so that * memcmp() below doesn't fail on that. The ones coming from CPUID will @@ -2000,3 +2188,69 @@ /* Check whether IPI broadcasting can be enabled */ apic_smt_update(); } + +void __init arch_cpu_finalize_init(void) +{ + identify_boot_cpu(); + + /* + * identify_boot_cpu() initialized SMT support information, let the + * core code know. + */ + cpu_smt_check_topology(); + + if (!IS_ENABLED(CONFIG_SMP)) { + pr_info("CPU: "); + print_cpu_info(&boot_cpu_data); + } + + cpu_select_mitigations(); + + arch_smt_update(); + + if (IS_ENABLED(CONFIG_X86_32)) { + /* + * Check whether this is a real i386 which is not longer + * supported and fixup the utsname. + */ + if (boot_cpu_data.x86 < 4) + panic("Kernel requires i486+ for 'invlpg' and other features"); + + init_utsname()->machine[1] = + '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); + } + + /* + * Must be before alternatives because it might set or clear + * feature bits. + */ + fpu__init_system(); + fpu__init_cpu(); + + alternative_instructions(); + + if (IS_ENABLED(CONFIG_X86_64)) { + /* + * Make sure the first 2MB area is not mapped by huge pages + * There are typically fixed size MTRRs in there and overlapping + * MTRRs into large pages causes slow downs. + * + * Right now we don't do that with gbpages because there seems + * very little benefit for that case. + */ + if (!direct_gbpages) + set_memory_4k((unsigned long)__va(0), 1); + } else { + fpu__init_check_bugs(); + } + + /* + * This needs to be called before any devices perform DMA + * operations that might use the SWIOTLB bounce buffers. It will + * mark the bounce buffers as decrypted so that their usage will + * not cause "plain-text" data to be decrypted when accessed. It + * must be called after late_time_init() so that Hyper-V x86/x64 + * hypercalls work when the SWIOTLB bounce buffers are decrypted. + */ + mem_encrypt_init(); +} --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/cpu.h +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/cpu.h @@ -73,10 +73,14 @@ extern int detect_extended_topology(struct cpuinfo_x86 *c); extern int detect_ht_early(struct cpuinfo_x86 *c); extern void detect_ht(struct cpuinfo_x86 *c); +extern void check_null_seg_clears_base(struct cpuinfo_x86 *c); unsigned int aperfmperf_get_khz(int cpu); +void cpu_select_mitigations(void); extern void x86_spec_ctrl_setup_ap(void); +extern void update_srbds_msr(void); +extern void update_gds_msr(void); extern u64 x86_read_arch_cap_msr(void); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/cpuid-deps.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/cpuid-deps.c @@ -44,7 +44,10 @@ { X86_FEATURE_F16C, X86_FEATURE_XMM2, }, { X86_FEATURE_AES, X86_FEATURE_XMM2 }, { X86_FEATURE_SHA_NI, X86_FEATURE_XMM2 }, + { X86_FEATURE_GFNI, X86_FEATURE_XMM2 }, { X86_FEATURE_FMA, X86_FEATURE_AVX }, + { X86_FEATURE_VAES, X86_FEATURE_AVX }, + { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX }, { X86_FEATURE_AVX2, X86_FEATURE_AVX, }, { X86_FEATURE_AVX512F, X86_FEATURE_AVX, }, { X86_FEATURE_AVX512IFMA, X86_FEATURE_AVX512F }, @@ -56,9 +59,6 @@ { X86_FEATURE_AVX512VL, X86_FEATURE_AVX512F }, { X86_FEATURE_AVX512VBMI, X86_FEATURE_AVX512F }, { X86_FEATURE_AVX512_VBMI2, X86_FEATURE_AVX512VL }, - { X86_FEATURE_GFNI, X86_FEATURE_AVX512VL }, - { X86_FEATURE_VAES, X86_FEATURE_AVX512VL }, - { X86_FEATURE_VPCLMULQDQ, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_VNNI, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_BITALG, X86_FEATURE_AVX512VL }, { X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F }, --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/cyrix.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/cyrix.c @@ -152,8 +152,8 @@ u8 ccr3; local_irq_save(flags); - /* Suspend on halt power saving and enable #SUSP pin */ - setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x88); + /* Suspend on halt power saving */ + setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x08); ccr3 = getCx86(CX86_CCR3); setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/hygon.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/hygon.c @@ -64,7 +64,6 @@ */ static void hygon_get_topology(struct cpuinfo_x86 *c) { - u8 node_id; int cpu = smp_processor_id(); /* get information required for multi-node processors */ @@ -74,7 +73,7 @@ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); - node_id = ecx & 0xff; + c->cpu_die_id = ecx & 0xff; c->cpu_core_id = ebx & 0xff; @@ -89,17 +88,21 @@ if (!err) c->x86_coreid_bits = get_count_order(c->x86_max_cores); - /* Socket ID is ApicId[6] for these processors. */ - c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; + /* + * Socket ID is ApicId[6] for the processors with model <= 0x3 + * when running on host. + */ + if (!boot_cpu_has(X86_FEATURE_HYPERVISOR) && c->x86_model <= 0x3) + c->phys_proc_id = c->apicid >> APICID_SOCKET_ID_BIT; - cacheinfo_hygon_init_llc_id(c, cpu, node_id); + cacheinfo_hygon_init_llc_id(c, cpu); } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - node_id = value & 7; + c->cpu_die_id = value & 7; - per_cpu(cpu_llc_id, cpu) = node_id; + per_cpu(cpu_llc_id, cpu) = c->cpu_die_id; } else return; @@ -122,7 +125,7 @@ /* Convert the initial APIC ID into the socket ID */ c->phys_proc_id = c->initial_apicid >> bits; /* use socket ID also for last level cache */ - per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; + per_cpu(cpu_llc_id, cpu) = c->cpu_die_id = c->phys_proc_id; } static void srat_detect_node(struct cpuinfo_x86 *c) @@ -336,8 +339,8 @@ * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present. */ - msr_set_bit(MSR_F10H_DECFG, - MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); + msr_set_bit(MSR_AMD64_DE_CFG, + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); /* A serializing LFENCE stops RDTSC speculation */ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); @@ -351,6 +354,8 @@ /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */ if (!cpu_has(c, X86_FEATURE_XENPV)) set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); + + check_null_seg_clears_base(c); } static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c) --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/intel.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/intel.c @@ -97,7 +97,7 @@ static int __init ring3mwait_disable(char *__unused) { ring3mwait_disabled = true; - return 0; + return 1; } __setup("ring3mwait=disable", ring3mwait_disable); @@ -187,6 +187,90 @@ return false; } +#define MSR_IA32_TME_ACTIVATE 0x982 + +/* Helpers to access TME_ACTIVATE MSR */ +#define TME_ACTIVATE_LOCKED(x) (x & 0x1) +#define TME_ACTIVATE_ENABLED(x) (x & 0x2) + +#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ +#define TME_ACTIVATE_POLICY_AES_XTS_128 0 + +#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ + +#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ +#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 + +/* Values for mktme_status (SW only construct) */ +#define MKTME_ENABLED 0 +#define MKTME_DISABLED 1 +#define MKTME_UNINITIALIZED 2 +static int mktme_status = MKTME_UNINITIALIZED; + +static void detect_tme_early(struct cpuinfo_x86 *c) +{ + u64 tme_activate, tme_policy, tme_crypto_algs; + int keyid_bits = 0, nr_keyids = 0; + static u64 tme_activate_cpu0 = 0; + + rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); + + if (mktme_status != MKTME_UNINITIALIZED) { + if (tme_activate != tme_activate_cpu0) { + /* Broken BIOS? */ + pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); + pr_err_once("x86/tme: MKTME is not usable\n"); + mktme_status = MKTME_DISABLED; + + /* Proceed. We may need to exclude bits from x86_phys_bits. */ + } + } else { + tme_activate_cpu0 = tme_activate; + } + + if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) { + pr_info_once("x86/tme: not enabled by BIOS\n"); + mktme_status = MKTME_DISABLED; + return; + } + + if (mktme_status != MKTME_UNINITIALIZED) + goto detect_keyid_bits; + + pr_info("x86/tme: enabled by BIOS\n"); + + tme_policy = TME_ACTIVATE_POLICY(tme_activate); + if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128) + pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); + + tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate); + if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { + pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", + tme_crypto_algs); + mktme_status = MKTME_DISABLED; + } +detect_keyid_bits: + keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate); + nr_keyids = (1UL << keyid_bits) - 1; + if (nr_keyids) { + pr_info_once("x86/mktme: enabled by BIOS\n"); + pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); + } else { + pr_info_once("x86/mktme: disabled by BIOS\n"); + } + + if (mktme_status == MKTME_UNINITIALIZED) { + /* MKTME is usable */ + mktme_status = MKTME_ENABLED; + } + + /* + * KeyID bits effectively lower the number of physical address + * bits. Update cpuinfo_x86::x86_phys_bits accordingly. + */ + c->x86_phys_bits -= keyid_bits; +} + static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; @@ -339,6 +423,13 @@ */ if (detect_extended_topology_early(c) < 0) detect_ht_early(c); + + /* + * Adjust the number of physical bits early because it affects the + * valid bits of the MTRR mask registers. + */ + if (cpu_has(c, X86_FEATURE_TME)) + detect_tme_early(c); } #ifdef CONFIG_X86_32 @@ -540,90 +631,6 @@ } } -#define MSR_IA32_TME_ACTIVATE 0x982 - -/* Helpers to access TME_ACTIVATE MSR */ -#define TME_ACTIVATE_LOCKED(x) (x & 0x1) -#define TME_ACTIVATE_ENABLED(x) (x & 0x2) - -#define TME_ACTIVATE_POLICY(x) ((x >> 4) & 0xf) /* Bits 7:4 */ -#define TME_ACTIVATE_POLICY_AES_XTS_128 0 - -#define TME_ACTIVATE_KEYID_BITS(x) ((x >> 32) & 0xf) /* Bits 35:32 */ - -#define TME_ACTIVATE_CRYPTO_ALGS(x) ((x >> 48) & 0xffff) /* Bits 63:48 */ -#define TME_ACTIVATE_CRYPTO_AES_XTS_128 1 - -/* Values for mktme_status (SW only construct) */ -#define MKTME_ENABLED 0 -#define MKTME_DISABLED 1 -#define MKTME_UNINITIALIZED 2 -static int mktme_status = MKTME_UNINITIALIZED; - -static void detect_tme(struct cpuinfo_x86 *c) -{ - u64 tme_activate, tme_policy, tme_crypto_algs; - int keyid_bits = 0, nr_keyids = 0; - static u64 tme_activate_cpu0 = 0; - - rdmsrl(MSR_IA32_TME_ACTIVATE, tme_activate); - - if (mktme_status != MKTME_UNINITIALIZED) { - if (tme_activate != tme_activate_cpu0) { - /* Broken BIOS? */ - pr_err_once("x86/tme: configuration is inconsistent between CPUs\n"); - pr_err_once("x86/tme: MKTME is not usable\n"); - mktme_status = MKTME_DISABLED; - - /* Proceed. We may need to exclude bits from x86_phys_bits. */ - } - } else { - tme_activate_cpu0 = tme_activate; - } - - if (!TME_ACTIVATE_LOCKED(tme_activate) || !TME_ACTIVATE_ENABLED(tme_activate)) { - pr_info_once("x86/tme: not enabled by BIOS\n"); - mktme_status = MKTME_DISABLED; - return; - } - - if (mktme_status != MKTME_UNINITIALIZED) - goto detect_keyid_bits; - - pr_info("x86/tme: enabled by BIOS\n"); - - tme_policy = TME_ACTIVATE_POLICY(tme_activate); - if (tme_policy != TME_ACTIVATE_POLICY_AES_XTS_128) - pr_warn("x86/tme: Unknown policy is active: %#llx\n", tme_policy); - - tme_crypto_algs = TME_ACTIVATE_CRYPTO_ALGS(tme_activate); - if (!(tme_crypto_algs & TME_ACTIVATE_CRYPTO_AES_XTS_128)) { - pr_err("x86/mktme: No known encryption algorithm is supported: %#llx\n", - tme_crypto_algs); - mktme_status = MKTME_DISABLED; - } -detect_keyid_bits: - keyid_bits = TME_ACTIVATE_KEYID_BITS(tme_activate); - nr_keyids = (1UL << keyid_bits) - 1; - if (nr_keyids) { - pr_info_once("x86/mktme: enabled by BIOS\n"); - pr_info_once("x86/mktme: %d KeyIDs available\n", nr_keyids); - } else { - pr_info_once("x86/mktme: disabled by BIOS\n"); - } - - if (mktme_status == MKTME_UNINITIALIZED) { - /* MKTME is usable */ - mktme_status = MKTME_ENABLED; - } - - /* - * KeyID bits effectively lower the number of physical address - * bits. Update cpuinfo_x86::x86_phys_bits accordingly. - */ - c->x86_phys_bits -= keyid_bits; -} - static void init_cpuid_fault(struct cpuinfo_x86 *c) { u64 msr; @@ -758,9 +765,6 @@ if (cpu_has(c, X86_FEATURE_VMX)) detect_vmx_virtcap(c); - if (cpu_has(c, X86_FEATURE_TME)) - detect_tme(c); - init_intel_misc_features(c); if (tsx_ctrl_state == TSX_CTRL_ENABLE) @@ -791,26 +795,37 @@ } #endif -#define TLB_INST_4K 0x01 -#define TLB_INST_4M 0x02 -#define TLB_INST_2M_4M 0x03 - -#define TLB_INST_ALL 0x05 -#define TLB_INST_1G 0x06 - -#define TLB_DATA_4K 0x11 -#define TLB_DATA_4M 0x12 -#define TLB_DATA_2M_4M 0x13 -#define TLB_DATA_4K_4M 0x14 - -#define TLB_DATA_1G 0x16 - -#define TLB_DATA0_4K 0x21 -#define TLB_DATA0_4M 0x22 -#define TLB_DATA0_2M_4M 0x23 +#define TLB_INST_4K 0x01 +#define TLB_INST_4M 0x02 +#define TLB_INST_2M_4M 0x03 + +#define TLB_INST_ALL 0x05 +#define TLB_INST_1G 0x06 + +#define TLB_DATA_4K 0x11 +#define TLB_DATA_4M 0x12 +#define TLB_DATA_2M_4M 0x13 +#define TLB_DATA_4K_4M 0x14 + +#define TLB_DATA_1G 0x16 +#define TLB_DATA_1G_2M_4M 0x17 + +#define TLB_DATA0_4K 0x21 +#define TLB_DATA0_4M 0x22 +#define TLB_DATA0_2M_4M 0x23 + +#define STLB_4K 0x41 +#define STLB_4K_2M 0x42 -#define STLB_4K 0x41 -#define STLB_4K_2M 0x42 +/* + * All of leaf 0x2's one-byte TLB descriptors implies the same number of + * entries for their respective TLB types. The 0x63 descriptor is an + * exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries + * for 2MB or 4MB pages. Encode descriptor 0x63 dTLB entry count for + * 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the + * intel_tlb_table[] mapping. + */ +#define TLB_0x63_2M_4M_ENTRIES 32 static const struct _tlb_table intel_tlb_table[] = { { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, @@ -832,7 +847,8 @@ { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, { 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" }, - { 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" }, + { 0x63, TLB_DATA_1G_2M_4M, 4, " TLB_DATA 1 GByte pages, 4-way set associative" + " (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here)" }, { 0x6b, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 8-way associative" }, { 0x6c, TLB_DATA_2M_4M, 128, " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" }, { 0x6d, TLB_DATA_1G, 16, " TLB_DATA 1 GByte pages, fully associative" }, @@ -932,6 +948,12 @@ if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; break; + case TLB_DATA_1G_2M_4M: + if (tlb_lld_2m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES) + tlb_lld_2m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES; + if (tlb_lld_4m[ENTRIES] < TLB_0x63_2M_4M_ENTRIES) + tlb_lld_4m[ENTRIES] = TLB_0x63_2M_4M_ENTRIES; + fallthrough; case TLB_DATA_1G: if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries) tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries; @@ -955,7 +977,7 @@ cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); /* If bit 31 is set, this is an unknown format */ - for (j = 0 ; j < 3 ; j++) + for (j = 0 ; j < 4 ; j++) if (regs[j] & (1 << 31)) regs[j] = 0; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/match.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/match.c @@ -16,12 +16,17 @@ * respective wildcard entries. * * A typical table entry would be to match a specific CPU - * { X86_VENDOR_INTEL, 6, 0x12 } - * or to match a specific CPU feature - * { X86_FEATURE_MATCH(X86_FEATURE_FOOBAR) } + * + * X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_BROADWELL, + * X86_FEATURE_ANY, NULL); * * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY, - * %X86_MODEL_ANY, %X86_FEATURE_ANY or 0 (except for vendor) + * %X86_MODEL_ANY, %X86_FEATURE_ANY (except for vendor) + * + * asm/cpu_device_id.h contains a set of useful macros which are shortcuts + * for various common selections. The above can be shortened to: + * + * X86_MATCH_INTEL_FAM6_MODEL(BROADWELL, NULL); * * Arrays used to match for this should also be declared using * MODULE_DEVICE_TABLE(x86cpu, ...) @@ -34,13 +39,18 @@ const struct x86_cpu_id *m; struct cpuinfo_x86 *c = &boot_cpu_data; - for (m = match; m->vendor | m->family | m->model | m->feature; m++) { + for (m = match; + m->vendor | m->family | m->model | m->steppings | m->feature; + m++) { if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) continue; if (m->family != X86_FAMILY_ANY && c->x86 != m->family) continue; if (m->model != X86_MODEL_ANY && c->x86_model != m->model) continue; + if (m->steppings != X86_STEPPING_ANY && + !(BIT(c->x86_stepping) & m->steppings)) + continue; if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) continue; return m; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/amd.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/amd.c @@ -78,6 +78,7 @@ static struct smca_bank_name smca_names[] = { [SMCA_LS] = { "load_store", "Load Store Unit" }, + [SMCA_LS_V2] = { "load_store", "Load Store Unit" }, [SMCA_IF] = { "insn_fetch", "Instruction Fetch Unit" }, [SMCA_L2_CACHE] = { "l2_cache", "L2 Cache" }, [SMCA_DE] = { "decode_unit", "Decode Unit" }, @@ -138,6 +139,7 @@ /* ZN Core (HWID=0xB0) MCA types */ { SMCA_LS, HWID_MCATYPE(0xB0, 0x0), 0x1FFFFF }, + { SMCA_LS_V2, HWID_MCATYPE(0xB0, 0x10), 0xFFFFFF }, { SMCA_IF, HWID_MCATYPE(0xB0, 0x1), 0x3FFF }, { SMCA_L2_CACHE, HWID_MCATYPE(0xB0, 0x2), 0xF }, { SMCA_DE, HWID_MCATYPE(0xB0, 0x3), 0x1FF }, @@ -266,10 +268,10 @@ smca_set_misc_banks_map(bank, cpu); /* Return early if this bank was already initialized. */ - if (smca_banks[bank].hwid) + if (smca_banks[bank].hwid && smca_banks[bank].hwid->hwid_mcatype != 0) return; - if (rdmsr_safe_on_cpu(cpu, MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) { + if (rdmsr_safe(MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) { pr_warn("Failed to read MCA_IPID for bank %d\n", bank); return; } @@ -1161,9 +1163,12 @@ .store = store, }; +static void threshold_block_release(struct kobject *kobj); + static struct kobj_type threshold_ktype = { .sysfs_ops = &threshold_ops, .default_attrs = default_attrs, + .release = threshold_block_release, }; static const char *get_name(unsigned int bank, struct threshold_block *b) @@ -1196,8 +1201,9 @@ return buf_mcatype; } -static int allocate_threshold_blocks(unsigned int cpu, unsigned int bank, - unsigned int block, u32 address) +static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb, + unsigned int bank, unsigned int block, + u32 address) { struct threshold_block *b = NULL; u32 low, high; @@ -1241,16 +1247,12 @@ INIT_LIST_HEAD(&b->miscj); - if (per_cpu(threshold_banks, cpu)[bank]->blocks) { - list_add(&b->miscj, - &per_cpu(threshold_banks, cpu)[bank]->blocks->miscj); - } else { - per_cpu(threshold_banks, cpu)[bank]->blocks = b; - } + if (tb->blocks) + list_add(&b->miscj, &tb->blocks->miscj); + else + tb->blocks = b; - err = kobject_init_and_add(&b->kobj, &threshold_ktype, - per_cpu(threshold_banks, cpu)[bank]->kobj, - get_name(bank, b)); + err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b)); if (err) goto out_free; recurse: @@ -1258,7 +1260,7 @@ if (!address) return 0; - err = allocate_threshold_blocks(cpu, bank, block, address); + err = allocate_threshold_blocks(cpu, tb, bank, block, address); if (err) goto out_free; @@ -1343,8 +1345,6 @@ goto out_free; } - per_cpu(threshold_banks, cpu)[bank] = b; - if (is_shared_bank(bank)) { refcount_set(&b->cpus, 1); @@ -1355,9 +1355,13 @@ } } - err = allocate_threshold_blocks(cpu, bank, 0, msr_ops.misc(bank)); - if (!err) - goto out; + err = allocate_threshold_blocks(cpu, b, bank, 0, msr_ops.misc(bank)); + if (err) + goto out_free; + + per_cpu(threshold_banks, cpu)[bank] = b; + + return 0; out_free: kfree(b); @@ -1366,8 +1370,12 @@ return err; } -static void deallocate_threshold_block(unsigned int cpu, - unsigned int bank) +static void threshold_block_release(struct kobject *kobj) +{ + kfree(to_block(kobj)); +} + +static void deallocate_threshold_block(unsigned int cpu, unsigned int bank) { struct threshold_block *pos = NULL; struct threshold_block *tmp = NULL; @@ -1377,13 +1385,11 @@ return; list_for_each_entry_safe(pos, tmp, &head->blocks->miscj, miscj) { - kobject_put(&pos->kobj); list_del(&pos->miscj); - kfree(pos); + kobject_put(&pos->kobj); } - kfree(per_cpu(threshold_banks, cpu)[bank]->blocks); - per_cpu(threshold_banks, cpu)[bank]->blocks = NULL; + kobject_put(&head->blocks->kobj); } static void __threshold_remove_blocks(struct threshold_bank *b) --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/core.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/core.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -310,11 +311,18 @@ panic("Panicing machine check CPU died"); } -static void mce_panic(const char *msg, struct mce *final, char *exp) +static noinstr void mce_panic(const char *msg, struct mce *final, char *exp) { - int apei_err = 0; struct llist_node *pending; struct mce_evt_llist *l; + int apei_err = 0; + struct page *p; + + /* + * Allow instrumentation around external facilities usage. Not that it + * matters a whole lot since the machine is going to panic anyway. + */ + instrumentation_begin(); if (!fake_panic) { /* @@ -329,7 +337,7 @@ } else { /* Don't log too much for fake panic */ if (atomic_inc_return(&mce_fake_panicked) > 1) - return; + goto out; } pending = mce_gen_pool_prepare_records(); /* First print corrected ones that are still unlogged */ @@ -364,9 +372,26 @@ if (!fake_panic) { if (panic_timeout == 0) panic_timeout = mca_cfg.panic_timeout; + + /* + * Kdump skips the poisoned page in order to avoid + * touching the error bits again. Poison the page even + * if the error is fatal and the machine is about to + * panic. + */ + if (kexec_crash_loaded()) { + if (final && (final->status & MCI_STATUS_ADDRV)) { + p = pfn_to_online_page(final->addr >> PAGE_SHIFT); + if (p) + SetPageHWPoison(p); + } + } panic(msg); } else pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); + +out: + instrumentation_end(); } /* Support code for software error injection */ @@ -388,10 +413,38 @@ return -1; } +static void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr) +{ + if (wrmsr) { + pr_emerg("MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, (unsigned int)regs->dx, (unsigned int)regs->ax, + regs->ip, (void *)regs->ip); + } else { + pr_emerg("MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pS)\n", + (unsigned int)regs->cx, regs->ip, (void *)regs->ip); + } + + show_stack_regs(regs); + + panic("MCA architectural violation!\n"); + + while (true) + cpu_relax(); +} + +__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr) +{ + ex_handler_msr_mce(regs, false); + return true; +} + /* MSR access wrappers used for error injection */ static u64 mce_rdmsrl(u32 msr) { - u64 v; + DECLARE_ARGS(val, low, high); if (__this_cpu_read(injectm.finished)) { int offset = msr_to_offset(msr); @@ -401,21 +454,33 @@ return *(u64 *)((char *)this_cpu_ptr(&injectm) + offset); } - if (rdmsrl_safe(msr, &v)) { - WARN_ONCE(1, "mce: Unable to read MSR 0x%x!\n", msr); - /* - * Return zero in case the access faulted. This should - * not happen normally but can happen if the CPU does - * something weird, or if the code is buggy. - */ - v = 0; - } + /* + * RDMSR on MCA MSRs should not fault. If they do, this is very much an + * architectural violation and needs to be reported to hw vendor. Panic + * the box to not allow any further progress. + */ + asm volatile("1: rdmsr\n" + "2:\n" + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_rdmsr_fault) + : EAX_EDX_RET(val, low, high) : "c" (msr)); - return v; + + return EAX_EDX_VAL(val, low, high); +} + +__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr) +{ + ex_handler_msr_mce(regs, true); + return true; } static void mce_wrmsrl(u32 msr, u64 v) { + u32 low, high; + if (__this_cpu_read(injectm.finished)) { int offset = msr_to_offset(msr); @@ -423,7 +488,15 @@ *(u64 *)((char *)this_cpu_ptr(&injectm) + offset) = v; return; } - wrmsrl(msr, v); + + low = (u32)v; + high = (u32)(v >> 32); + + /* See comment in mce_rdmsrl() */ + asm volatile("1: wrmsr\n" + "2:\n" + _ASM_EXTABLE_HANDLE(1b, 2b, ex_handler_wrmsr_fault) + : : "c" (msr), "a"(low), "d" (high) : "memory"); } /* @@ -533,6 +606,13 @@ } EXPORT_SYMBOL_GPL(mce_is_memory_error); +static bool whole_page(struct mce *m) +{ + if (!mca_cfg.ser || !(m->status & MCI_STATUS_MISCV)) + return true; + return MCI_MISC_ADDR_LSB(m->misc) >= PAGE_SHIFT; +} + bool mce_is_correctable(struct mce *m) { if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED) @@ -601,7 +681,7 @@ if (mce_usable_address(mce) && (mce->severity == MCE_AO_SEVERITY)) { pfn = mce->addr >> PAGE_SHIFT; if (!memory_failure(pfn, 0)) - set_mce_nospec(pfn); + set_mce_nospec(pfn, whole_page(mce)); } return NOTIFY_OK; @@ -636,7 +716,7 @@ /* * Read ADDR and MISC registers. */ -static void mce_read_aux(struct mce *m, int i) +static noinstr void mce_read_aux(struct mce *m, int i) { if (m->status & MCI_STATUS_MISCV) m->misc = mce_rdmsrl(msr_ops.misc(i)); @@ -814,8 +894,8 @@ if (quirk_no_way_out) quirk_no_way_out(i, m, regs); + m->bank = i; if (mce_severity(m, mca_cfg.tolerant, &tmp, true) >= MCE_PANIC_SEVERITY) { - m->bank = i; mce_read_aux(m, i); *msg = tmp; return 1; @@ -1016,10 +1096,13 @@ * Synchronize between CPUs after main scanning loop. * This invokes the bulk of the Monarch processing. */ -static int mce_end(int order) +static noinstr int mce_end(int order) { - int ret = -1; u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; + int ret = -1; + + /* Allow instrumentation around external facilities. */ + instrumentation_begin(); if (!timeout) goto reset; @@ -1063,7 +1146,8 @@ /* * Don't reset anything. That's done by the Monarch. */ - return 0; + ret = 0; + goto out; } /* @@ -1078,6 +1162,10 @@ * Let others run again. */ atomic_set(&mce_executing, 0); + +out: + instrumentation_end(); + return ret; } @@ -1103,7 +1191,7 @@ if (ret) pr_err("Memory error not recovered"); else - set_mce_nospec(m->addr >> PAGE_SHIFT); + set_mce_nospec(m->addr >> PAGE_SHIFT, whole_page(m)); return ret; } @@ -1306,8 +1394,10 @@ * When there's any problem use only local no_way_out state. */ if (!lmce) { - if (mce_end(order) < 0) - no_way_out = worst >= MCE_PANIC_SEVERITY; + if (mce_end(order) < 0) { + if (!no_way_out) + no_way_out = worst >= MCE_PANIC_SEVERITY; + } } else { /* * If there was a fatal machine check we should have @@ -2138,12 +2228,14 @@ return -EINVAL; b = &per_cpu(mce_banks_array, s->id)[bank]; - if (!b->init) return -ENODEV; b->ctl = new; + + mutex_lock(&mce_sysfs_mutex); mce_restart(); + mutex_unlock(&mce_sysfs_mutex); return size; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/inject.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/inject.c @@ -347,7 +347,7 @@ char buf[MAX_FLAG_OPT_SIZE], *__buf; int err; - if (cnt > MAX_FLAG_OPT_SIZE) + if (!cnt || cnt > MAX_FLAG_OPT_SIZE) return -EINVAL; if (copy_from_user(&buf, ubuf, cnt)) @@ -511,7 +511,7 @@ */ if (inj_type == DFR_INT_INJ) { i_mce.status |= MCI_STATUS_DEFERRED; - i_mce.status |= (i_mce.status & ~MCI_STATUS_UC); + i_mce.status &= ~MCI_STATUS_UC; } /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/intel.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/intel.c @@ -489,17 +489,18 @@ return; if ((val & 3UL) == 1UL) { - /* PPIN available but disabled: */ + /* PPIN locked in disabled mode */ return; } - /* If PPIN is disabled, but not locked, try to enable: */ - if (!(val & 3UL)) { + /* If PPIN is disabled, try to enable */ + if (!(val & 2UL)) { wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); rdmsrl_safe(MSR_PPIN_CTL, &val); } - if ((val & 3UL) == 2UL) + /* Is the enable bit set? */ + if (val & 2UL) set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); } } --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/internal.h +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/internal.h @@ -172,4 +172,14 @@ static inline bool amd_filter_mce(struct mce *m) { return false; }; #endif +__visible bool ex_handler_rdmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr); + +__visible bool ex_handler_wrmsr_fault(const struct exception_table_entry *fixup, + struct pt_regs *regs, int trapnr, + unsigned long error_code, + unsigned long fault_addr); + #endif /* __X86_MCE_INTERNAL_H__ */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/severity.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/severity.c @@ -9,9 +9,11 @@ #include #include #include -#include #include +#include +#include + #include "internal.h" /* @@ -40,9 +42,14 @@ unsigned char context; unsigned char excp; unsigned char covered; + unsigned char cpu_model; + unsigned char cpu_minstepping; + unsigned char bank_lo, bank_hi; char *msg; } severities[] = { #define MCESEV(s, m, c...) { .sev = MCE_ ## s ## _SEVERITY, .msg = m, ## c } +#define BANK_RANGE(l, h) .bank_lo = l, .bank_hi = h +#define MODEL_STEPPING(m, s) .cpu_model = m, .cpu_minstepping = s #define KERNEL .context = IN_KERNEL #define USER .context = IN_USER #define KERNEL_RECOV .context = IN_KERNEL_RECOV @@ -97,7 +104,6 @@ KEEP, "Corrected error", NOSER, BITCLR(MCI_STATUS_UC) ), - /* * known AO MCACODs reported via MCE or CMC: * @@ -113,6 +119,18 @@ AO, "Action optional: last level cache writeback error", SER, MASK(MCI_UC_AR|MCACOD, MCI_STATUS_UC|MCACOD_L3WB) ), + /* + * Quirk for Skylake/Cascade Lake. Patrol scrubber may be configured + * to report uncorrected errors using CMCI with a special signature. + * UC=0, MSCOD=0x0010, MCACOD=binary(000X 0000 1100 XXXX) reported + * in one of the memory controller banks. + * Set severity to "AO" for same action as normal patrol scrub error. + */ + MCESEV( + AO, "Uncorrected Patrol Scrub Error", + SER, MASK(MCI_STATUS_UC|MCI_ADDR|0xffffeff0, MCI_ADDR|0x001000c0), + MODEL_STEPPING(INTEL_FAM6_SKYLAKE_X, 4), BANK_RANGE(13, 18) + ), /* ignore OVER for UCNA */ MCESEV( @@ -320,6 +338,12 @@ continue; if (s->excp && excp != s->excp) continue; + if (s->cpu_model && boot_cpu_data.x86_model != s->cpu_model) + continue; + if (s->cpu_minstepping && boot_cpu_data.x86_stepping < s->cpu_minstepping) + continue; + if (s->bank_lo && (m->bank < s->bank_lo || m->bank > s->bank_hi)) + continue; if (msg) *msg = s->msg; s->covered = 1; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mce/therm_throt.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mce/therm_throt.c @@ -188,7 +188,7 @@ /* if we just entered the thermal event */ if (new_event) { if (event == THERMAL_THROTTLING_EVENT) - pr_crit("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", + pr_warn("CPU%d: %s temperature above threshold, cpu clock throttled (total events = %lu)\n", this_cpu, level == CORE_LEVEL ? "Core" : "Package", state->count); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/microcode/amd.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/microcode/amd.c @@ -55,7 +55,9 @@ }; static u32 ucode_new_rev; -static u8 amd_ucode_patch[PATCH_MAX_SIZE]; + +/* One blob per node. */ +static u8 amd_ucode_patch[MAX_NUMNODES][PATCH_MAX_SIZE]; /* * Microcode patch container file is prepended to the initrd in cpio @@ -429,7 +431,7 @@ patch = (u8 (*)[PATCH_MAX_SIZE])__pa_nodebug(&amd_ucode_patch); #else new_rev = &ucode_new_rev; - patch = &amd_ucode_patch; + patch = &amd_ucode_patch[0]; #endif desc.cpuid_1_eax = cpuid_1_eax; @@ -441,7 +443,13 @@ return ret; native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); - if (rev >= mc->hdr.patch_id) + + /* + * Allow application of the same revision to pick up SMT-specific + * changes even if the revision of the other SMT thread is already + * up-to-date. + */ + if (rev > mc->hdr.patch_id) return ret; if (!__apply_microcode_amd(mc)) { @@ -523,8 +531,12 @@ native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); - /* Check whether we have saved a new patch already: */ - if (*new_rev && rev < mc->hdr.patch_id) { + /* + * Check whether a new patch has been saved already. Also, allow application of + * the same revision in order to pick up SMT-thread-specific configuration even + * if the sibling SMT thread already has an up-to-date revision. + */ + if (*new_rev && rev <= mc->hdr.patch_id) { if (!__apply_microcode_amd(mc)) { *new_rev = mc->hdr.patch_id; return; @@ -538,8 +550,7 @@ apply_microcode_early_amd(cpuid_1_eax, cp.data, cp.size, false); } -static enum ucode_state -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size); +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); int __init save_microcode_in_initrd_amd(unsigned int cpuid_1_eax) { @@ -557,19 +568,19 @@ if (!desc.mc) return -EINVAL; - ret = load_microcode_amd(true, x86_family(cpuid_1_eax), desc.data, desc.size); + ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); if (ret > UCODE_UPDATED) return -EINVAL; return 0; } -void reload_ucode_amd(void) +void reload_ucode_amd(unsigned int cpu) { - struct microcode_amd *mc; u32 rev, dummy; + struct microcode_amd *mc; - mc = (struct microcode_amd *)amd_ucode_patch; + mc = (struct microcode_amd *)amd_ucode_patch[cpu_to_node(cpu)]; rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); @@ -689,7 +700,7 @@ rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); /* need to apply patch? */ - if (rev >= mc_amd->hdr.patch_id) { + if (rev > mc_amd->hdr.patch_id) { ret = UCODE_OK; goto out; } @@ -783,6 +794,7 @@ kfree(patch); return -EINVAL; } + patch->size = *patch_size; mc_hdr = (struct microcode_header_amd *)(fw + SECTION_HDR_SIZE); proc_id = mc_hdr->processor_rev_id; @@ -834,9 +846,10 @@ return UCODE_OK; } -static enum ucode_state -load_microcode_amd(bool save, u8 family, const u8 *data, size_t size) +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) { + struct cpuinfo_x86 *c; + unsigned int nid, cpu; struct ucode_patch *p; enum ucode_state ret; @@ -849,22 +862,22 @@ return ret; } - p = find_patch(0); - if (!p) { - return ret; - } else { - if (boot_cpu_data.microcode >= p->patch_id) - return ret; + for_each_node(nid) { + cpu = cpumask_first(cpumask_of_node(nid)); + c = &cpu_data(cpu); + + p = find_patch(cpu); + if (!p) + continue; - ret = UCODE_NEW; - } + if (c->microcode >= p->patch_id) + continue; - /* save BSP's matching patch for early load */ - if (!save) - return ret; + ret = UCODE_NEW; - memset(amd_ucode_patch, 0, PATCH_MAX_SIZE); - memcpy(amd_ucode_patch, p->data, min_t(u32, ksize(p->data), PATCH_MAX_SIZE)); + memset(&amd_ucode_patch[nid], 0, PATCH_MAX_SIZE); + memcpy(&amd_ucode_patch[nid], p->data, min_t(u32, p->size, PATCH_MAX_SIZE)); + } return ret; } @@ -890,12 +903,11 @@ { char fw_name[36] = "amd-ucode/microcode_amd.bin"; struct cpuinfo_x86 *c = &cpu_data(cpu); - bool bsp = c->cpu_index == boot_cpu_data.cpu_index; enum ucode_state ret = UCODE_NFOUND; const struct firmware *fw; /* reload ucode container only on the boot cpu */ - if (!refresh_fw || !bsp) + if (!refresh_fw) return UCODE_OK; if (c->x86 >= 0x15) @@ -910,7 +922,7 @@ if (!verify_container(fw->data, fw->size, false)) goto fw_release; - ret = load_microcode_amd(bsp, c->x86, fw->data, fw->size); + ret = load_microcode_amd(c->x86, fw->data, fw->size); fw_release: release_firmware(fw); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/microcode/core.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/microcode/core.c @@ -322,7 +322,7 @@ #endif } -void reload_early_microcode(void) +void reload_early_microcode(unsigned int cpu) { int vendor, family; @@ -336,7 +336,7 @@ break; case X86_VENDOR_AMD: if (family >= 0x10) - reload_ucode_amd(); + reload_ucode_amd(cpu); break; default: break; @@ -626,16 +626,16 @@ if (val != 1) return size; - tmp_ret = microcode_ops->request_microcode_fw(bsp, µcode_pdev->dev, true); - if (tmp_ret != UCODE_NEW) - return size; - get_online_cpus(); ret = check_online_cpus(); if (ret) goto put; + tmp_ret = microcode_ops->request_microcode_fw(bsp, µcode_pdev->dev, true); + if (tmp_ret != UCODE_NEW) + goto put; + mutex_lock(µcode_mutex); ret = microcode_reload_late(); mutex_unlock(µcode_mutex); @@ -772,9 +772,9 @@ }; /** - * mc_bp_resume - Update boot CPU microcode during resume. + * microcode_bsp_resume - Update boot CPU microcode during resume. */ -static void mc_bp_resume(void) +void microcode_bsp_resume(void) { int cpu = smp_processor_id(); struct ucode_cpu_info *uci = ucode_cpu_info + cpu; @@ -782,11 +782,11 @@ if (uci->valid && uci->mc) microcode_ops->apply_microcode(cpu); else if (!uci->mc) - reload_early_microcode(); + reload_early_microcode(cpu); } static struct syscore_ops mc_syscore_ops = { - .resume = mc_bp_resume, + .resume = microcode_bsp_resume, }; static int mc_cpu_starting(unsigned int cpu) --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/microcode/intel.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/microcode/intel.c @@ -100,53 +100,6 @@ return find_matching_signature(mc, csig, cpf); } -/* - * Given CPU signature and a microcode patch, this function finds if the - * microcode patch has matching family and model with the CPU. - * - * %true - if there's a match - * %false - otherwise - */ -static bool microcode_matches(struct microcode_header_intel *mc_header, - unsigned long sig) -{ - unsigned long total_size = get_totalsize(mc_header); - unsigned long data_size = get_datasize(mc_header); - struct extended_sigtable *ext_header; - unsigned int fam_ucode, model_ucode; - struct extended_signature *ext_sig; - unsigned int fam, model; - int ext_sigcount, i; - - fam = x86_family(sig); - model = x86_model(sig); - - fam_ucode = x86_family(mc_header->sig); - model_ucode = x86_model(mc_header->sig); - - if (fam == fam_ucode && model == model_ucode) - return true; - - /* Look for ext. headers: */ - if (total_size <= data_size + MC_HEADER_SIZE) - return false; - - ext_header = (void *) mc_header + data_size + MC_HEADER_SIZE; - ext_sig = (void *)ext_header + EXT_HEADER_SIZE; - ext_sigcount = ext_header->count; - - for (i = 0; i < ext_sigcount; i++) { - fam_ucode = x86_family(ext_sig->sig); - model_ucode = x86_model(ext_sig->sig); - - if (fam == fam_ucode && model == model_ucode) - return true; - - ext_sig++; - } - return false; -} - static struct ucode_patch *memdup_patch(void *data, unsigned int size) { struct ucode_patch *p; @@ -164,7 +117,7 @@ return p; } -static void save_microcode_patch(void *data, unsigned int size) +static void save_microcode_patch(struct ucode_cpu_info *uci, void *data, unsigned int size) { struct microcode_header_intel *mc_hdr, *mc_saved_hdr; struct ucode_patch *iter, *tmp, *p = NULL; @@ -210,6 +163,9 @@ if (!p) return; + if (!find_matching_signature(p->data, uci->cpu_sig.sig, uci->cpu_sig.pf)) + return; + /* * Save for early loading. On 32-bit, that needs to be a physical * address as the APs are running from physical addresses, before @@ -344,13 +300,14 @@ size -= mc_size; - if (!microcode_matches(mc_header, uci->cpu_sig.sig)) { + if (!find_matching_signature(data, uci->cpu_sig.sig, + uci->cpu_sig.pf)) { data += mc_size; continue; } if (save) { - save_microcode_patch(data, mc_size); + save_microcode_patch(uci, data, mc_size); goto next; } @@ -483,14 +440,14 @@ * Save this microcode patch. It will be loaded early when a CPU is * hot-added or resumes. */ -static void save_mc_for_early(u8 *mc, unsigned int size) +static void save_mc_for_early(struct ucode_cpu_info *uci, u8 *mc, unsigned int size) { /* Synchronization during CPU hotplug. */ static DEFINE_MUTEX(x86_cpu_microcode_mutex); mutex_lock(&x86_cpu_microcode_mutex); - save_microcode_patch(mc, size); + save_microcode_patch(uci, mc, size); show_saved_mc(); mutex_unlock(&x86_cpu_microcode_mutex); @@ -702,7 +659,6 @@ else iup = &intel_ucode_patch; -reget: if (!*iup) { patch = __load_ucode_intel(&uci); if (!patch) @@ -713,12 +669,7 @@ uci.mc = *iup; - if (apply_microcode_early(&uci, true)) { - /* Mixed-silicon system? Try to refetch the proper patch: */ - *iup = NULL; - - goto reget; - } + apply_microcode_early(&uci, true); } static struct microcode_intel *find_patch(struct ucode_cpu_info *uci) @@ -934,7 +885,7 @@ * permanent memory. So it will be loaded early when a CPU is hot added * or resumes. */ - save_mc_for_early(new_mc, new_mc_size); + save_mc_for_early(uci, new_mc, new_mc_size); pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", cpu, new_rev, uci->cpu_sig.rev); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mshyperv.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mshyperv.c @@ -82,7 +82,7 @@ inc_irq_stat(hyperv_stimer0_count); if (hv_stimer0_handler) hv_stimer0_handler(); - add_interrupt_randomness(HYPERV_STIMER0_VECTOR, 0); + add_interrupt_randomness(HYPERV_STIMER0_VECTOR); ack_APIC_irq(); exiting_irq(); @@ -227,8 +227,8 @@ ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES); ms_hyperv.hints = cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); - pr_info("Hyper-V: features 0x%x, hints 0x%x\n", - ms_hyperv.features, ms_hyperv.hints); + pr_info("Hyper-V: features 0x%x, hints 0x%x, misc 0x%x\n", + ms_hyperv.features, ms_hyperv.hints, ms_hyperv.misc_features); ms_hyperv.max_vp_index = cpuid_eax(HYPERV_CPUID_IMPLEMENT_LIMITS); ms_hyperv.max_lp_index = cpuid_ebx(HYPERV_CPUID_IMPLEMENT_LIMITS); @@ -256,6 +256,7 @@ ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { x86_platform.calibrate_tsc = hv_get_tsc_khz; x86_platform.calibrate_cpu = hv_get_tsc_khz; + setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ); } if (ms_hyperv.hints & HV_X64_ENLIGHTENED_VMCS_RECOMMENDED) { @@ -263,6 +264,16 @@ cpuid_eax(HYPERV_CPUID_NESTED_FEATURES); } + /* + * Hyper-V expects to get crash register data or kmsg when + * crash enlightment is available and system crashes. Set + * crash_kexec_post_notifiers to be true to make sure that + * calling crash enlightment interface before running kdump + * kernel. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) + crash_kexec_post_notifiers = true; + #ifdef CONFIG_X86_LOCAL_APIC if (ms_hyperv.features & HV_X64_ACCESS_FREQUENCY_MSRS && ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mtrr/generic.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mtrr/generic.c @@ -167,9 +167,6 @@ *repeat = 0; *uniform = 1; - /* Make end inclusive instead of exclusive */ - end--; - prev_match = MTRR_TYPE_INVALID; for (i = 0; i < num_var_ranges; ++i) { unsigned short start_state, end_state, inclusive; @@ -261,6 +258,9 @@ int repeat; u64 partial_end; + /* Make end inclusive instead of exclusive */ + end--; + if (!mtrr_state_set) return MTRR_TYPE_INVALID; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/mtrr/mtrr.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/mtrr/mtrr.c @@ -794,8 +794,6 @@ if (!use_intel() || mtrr_aps_delayed_init) return; - rcu_cpu_starting(smp_processor_id()); - /* * Ideally we should hold mtrr_mutex here to avoid mtrr entries * changed, but this routine will be called in cpu boot time, @@ -819,7 +817,7 @@ { int first_cpu; - if (!mtrr_enabled()) + if (!mtrr_enabled() || !mtrr_state.have_fixed) return; first_cpu = cpumask_first(cpu_online_mask); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/resctrl/core.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/resctrl/core.c @@ -250,7 +250,7 @@ return false; } -static bool __get_mem_config_intel(struct rdt_resource *r) +static __init bool __get_mem_config_intel(struct rdt_resource *r) { union cpuid_0x10_3_eax eax; union cpuid_0x10_x_edx edx; @@ -260,6 +260,7 @@ r->num_closid = edx.split.cos_max + 1; r->membw.max_delay = eax.split.max_delay + 1; r->default_ctrl = MAX_MBA_BW; + r->membw.mbm_width = MBM_CNTR_WIDTH; if (ecx & MBA_IS_LINEAR) { r->membw.delay_linear = true; r->membw.min_bw = MAX_MBA_BW - r->membw.max_delay; @@ -276,7 +277,7 @@ return true; } -static bool __rdt_get_mem_config_amd(struct rdt_resource *r) +static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r) { union cpuid_0x10_3_eax eax; union cpuid_0x10_x_edx edx; @@ -289,6 +290,7 @@ /* AMD does not use delay */ r->membw.delay_linear = false; + r->membw.mbm_width = MBM_CNTR_WIDTH_AMD; r->membw.min_bw = 0; r->membw.bw_gran = 1; /* Max value is 2048, Data width should be 4 in decimal */ @@ -578,12 +580,16 @@ d->id = id; cpumask_set_cpu(cpu, &d->cpu_mask); + rdt_domain_reconfigure_cdp(r); + if (r->alloc_capable && domain_setup_ctrlval(r, d)) { kfree(d); return; } if (r->mon_capable && domain_setup_mon_state(r, d)) { + kfree(d->ctrl_val); + kfree(d->mbps_val); kfree(d); return; } @@ -618,7 +624,7 @@ if (static_branch_unlikely(&rdt_mon_enable_key)) rmdir_mondata_subdir_allrdtgrp(r, d->id); list_del(&d->list); - if (is_mbm_enabled()) + if (r->mon_capable && is_mbm_enabled()) cancel_delayed_work(&d->mbm_over); if (is_llc_occupancy_enabled() && has_busy_rmid(r, d)) { /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/resctrl/internal.h +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/resctrl/internal.h @@ -32,6 +32,7 @@ #define CQM_LIMBOCHECK_INTERVAL 1000 #define MBM_CNTR_WIDTH 24 +#define MBM_CNTR_WIDTH_AMD 44 #define MBM_OVERFLOW_INTERVAL 1000 #define MAX_MBA_BW 100u #define MBA_IS_LINEAR 0x4 @@ -57,6 +58,7 @@ } DECLARE_STATIC_KEY_FALSE(rdt_enable_key); +DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key); /** * struct mon_evt - Entry in the event list of a resource @@ -274,7 +276,6 @@ * struct mbm_state - status for each MBM counter in each domain * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) * @prev_msr Value of IA32_QM_CTR for this RMID last time we read it - * @chunks_bw Total local data moved. Used for bandwidth calculation * @prev_bw_msr:Value of previous IA32_QM_CTR for bandwidth counting * @prev_bw The most recent bandwidth in MBps * @delta_bw Difference between the current and previous bandwidth @@ -283,7 +284,6 @@ struct mbm_state { u64 chunks; u64 prev_msr; - u64 chunks_bw; u64 prev_bw_msr; u32 prev_bw; u32 delta_bw; @@ -367,6 +367,7 @@ * @min_bw: Minimum memory bandwidth percentage user can request * @bw_gran: Granularity at which the memory bandwidth is allocated * @delay_linear: True if memory B/W delay is in linear scale + * @mbm_width: memory B/W monitor counter width * @mba_sc: True if MBA software controller(mba_sc) is enabled * @mb_map: Mapping of memory B/W percentage to memory B/W delay */ @@ -375,6 +376,7 @@ u32 min_bw; u32 bw_gran; u32 delay_linear; + u32 mbm_width; bool mba_sc; u32 *mb_map; }; @@ -600,5 +602,6 @@ void __check_limbo(struct rdt_domain *d, bool force_free); bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r); bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r); +void rdt_domain_reconfigure_cdp(struct rdt_resource *r); #endif /* _ASM_X86_RESCTRL_INTERNAL_H */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/resctrl/monitor.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/resctrl/monitor.c @@ -216,21 +216,21 @@ static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr) { - u64 shift = 64 - MBM_CNTR_WIDTH, chunks; + u64 shift, chunks; + shift = 64 - rdt_resources_all[RDT_RESOURCE_MBA].membw.mbm_width; chunks = (cur_msr << shift) - (prev_msr << shift); return chunks >>= shift; } -static int __mon_event_count(u32 rmid, struct rmid_read *rr) +static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) { struct mbm_state *m; u64 chunks, tval; tval = __rmid_read(rmid, rr->evtid); if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { - rr->val = tval; - return -EINVAL; + return tval; } switch (rr->evtid) { case QOS_L3_OCCUP_EVENT_ID: @@ -244,10 +244,10 @@ break; default: /* - * Code would never reach here because - * an invalid event id would fail the __rmid_read. + * Code would never reach here because an invalid + * event id would fail the __rmid_read. */ - return -EINVAL; + return RMID_VAL_ERROR; } if (rr->first) { @@ -279,8 +279,6 @@ return; chunks = mbm_overflow_count(m->prev_bw_msr, tval); - m->chunks_bw += chunks; - m->chunks = m->chunks_bw; cur_bw = (chunks * r->mon_scale) >> 20; if (m->delta_comp) @@ -299,23 +297,29 @@ struct rdtgroup *rdtgrp, *entry; struct rmid_read *rr = info; struct list_head *head; + u64 ret_val; rdtgrp = rr->rgrp; - if (__mon_event_count(rdtgrp->mon.rmid, rr)) - return; + ret_val = __mon_event_count(rdtgrp->mon.rmid, rr); /* - * For Ctrl groups read data from child monitor groups. + * For Ctrl groups read data from child monitor groups and + * add them together. Count events which are read successfully. + * Discard the rmid_read's reporting errors. */ head = &rdtgrp->mon.crdtgrp_list; if (rdtgrp->type == RDTCTRL_GROUP) { list_for_each_entry(entry, head, mon.crdtgrp_list) { - if (__mon_event_count(entry->mon.rmid, rr)) - return; + if (__mon_event_count(entry->mon.rmid, rr) == 0) + ret_val = 0; } } + + /* Report error if none of rmid_reads are successful */ + if (ret_val) + rr->val = ret_val; } /* @@ -450,15 +454,14 @@ } if (is_mbm_local_enabled()) { rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID; + __mon_event_count(rmid, &rr); /* * Call the MBA software controller only for the * control groups and when user has enabled * the software controller explicitly. */ - if (!is_mba_sc(NULL)) - __mon_event_count(rmid, &rr); - else + if (is_mba_sc(NULL)) mbm_bw_count(rmid, &rr); } } @@ -514,7 +517,7 @@ mutex_lock(&rdtgroup_mutex); - if (!static_branch_likely(&rdt_enable_key)) + if (!static_branch_likely(&rdt_mon_enable_key)) goto out_unlock; d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]); @@ -543,7 +546,7 @@ unsigned long delay = msecs_to_jiffies(delay_ms); int cpu; - if (!static_branch_likely(&rdt_enable_key)) + if (!static_branch_likely(&rdt_mon_enable_key)) return; cpu = cpumask_any(&dom->cpu_mask); dom->mbm_work_cpu = cpu; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/resctrl/pseudo_lock.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/resctrl/pseudo_lock.c @@ -416,6 +416,7 @@ struct pseudo_lock_region *plr = rdtgrp->plr; u32 rmid_p, closid_p; unsigned long i; + u64 saved_msr; #ifdef CONFIG_KASAN /* * The registers used for local register variables are also used @@ -459,6 +460,7 @@ * the buffer and evict pseudo-locked memory read earlier from the * cache. */ + saved_msr = __rdmsr(MSR_MISC_FEATURE_CONTROL); __wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); closid_p = this_cpu_read(pqr_state.cur_closid); rmid_p = this_cpu_read(pqr_state.cur_rmid); @@ -510,7 +512,7 @@ __wrmsr(IA32_PQR_ASSOC, rmid_p, closid_p); /* Re-enable the hardware prefetcher(s) */ - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsrl(MSR_MISC_FEATURE_CONTROL, saved_msr); local_irq_enable(); plr->thread_done = 1; @@ -867,6 +869,7 @@ static int measure_cycles_lat_fn(void *_plr) { struct pseudo_lock_region *plr = _plr; + u32 saved_low, saved_high; unsigned long i; u64 start, end; void *mem_r; @@ -875,6 +878,7 @@ /* * Disable hardware prefetchers. */ + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); mem_r = READ_ONCE(plr->kmem); /* @@ -891,7 +895,7 @@ end = rdtsc_ordered(); trace_pseudo_lock_mem_latency((u32)(end - start)); } - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); local_irq_enable(); plr->thread_done = 1; wake_up_interruptible(&plr->lock_thread_wq); @@ -936,6 +940,7 @@ u64 hits_before = 0, hits_after = 0, miss_before = 0, miss_after = 0; struct perf_event *miss_event, *hit_event; int hit_pmcnum, miss_pmcnum; + u32 saved_low, saved_high; unsigned int line_size; unsigned int size; unsigned long i; @@ -969,6 +974,7 @@ /* * Disable hardware prefetchers. */ + rdmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); wrmsr(MSR_MISC_FEATURE_CONTROL, prefetch_disable_bits, 0x0); /* Initialize rest of local variables */ @@ -1027,7 +1033,7 @@ */ rmb(); /* Re-enable hardware prefetchers */ - wrmsr(MSR_MISC_FEATURE_CONTROL, 0x0, 0x0); + wrmsr(MSR_MISC_FEATURE_CONTROL, saved_low, saved_high); local_irq_enable(); out_hit: perf_event_release_kernel(hit_event); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -311,7 +311,7 @@ * executing task might have its own closid selected. Just reuse * the context switch code. */ - resctrl_sched_in(); + resctrl_sched_in(current); } /* @@ -507,85 +507,102 @@ return ret ?: nbytes; } -struct task_move_callback { - struct callback_head work; - struct rdtgroup *rdtgrp; -}; - -static void move_myself(struct callback_head *head) +/** + * rdtgroup_remove - the helper to remove resource group safely + * @rdtgrp: resource group to remove + * + * On resource group creation via a mkdir, an extra kernfs_node reference is + * taken to ensure that the rdtgroup structure remains accessible for the + * rdtgroup_kn_unlock() calls where it is removed. + * + * Drop the extra reference here, then free the rdtgroup structure. + * + * Return: void + */ +static void rdtgroup_remove(struct rdtgroup *rdtgrp) { - struct task_move_callback *callback; - struct rdtgroup *rdtgrp; - - callback = container_of(head, struct task_move_callback, work); - rdtgrp = callback->rdtgrp; + kernfs_put(rdtgrp->kn); + kfree(rdtgrp); +} +static void _update_task_closid_rmid(void *task) +{ /* - * If resource group was deleted before this task work callback - * was invoked, then assign the task to root group and free the - * resource group. + * If the task is still current on this CPU, update PQR_ASSOC MSR. + * Otherwise, the MSR is updated when the task is scheduled in. */ - if (atomic_dec_and_test(&rdtgrp->waitcount) && - (rdtgrp->flags & RDT_DELETED)) { - current->closid = 0; - current->rmid = 0; - kfree(rdtgrp); - } - - preempt_disable(); - /* update PQR_ASSOC MSR to make resource group go into effect */ - resctrl_sched_in(); - preempt_enable(); + if (task == current) + resctrl_sched_in(task); +} - kfree(callback); +static void update_task_closid_rmid(struct task_struct *t) +{ + if (IS_ENABLED(CONFIG_SMP) && task_curr(t)) + smp_call_function_single(task_cpu(t), _update_task_closid_rmid, t, 1); + else + _update_task_closid_rmid(t); } static int __rdtgroup_move_task(struct task_struct *tsk, struct rdtgroup *rdtgrp) { - struct task_move_callback *callback; - int ret; - - callback = kzalloc(sizeof(*callback), GFP_KERNEL); - if (!callback) - return -ENOMEM; - callback->work.func = move_myself; - callback->rdtgrp = rdtgrp; + /* If the task is already in rdtgrp, no need to move the task. */ + if ((rdtgrp->type == RDTCTRL_GROUP && tsk->closid == rdtgrp->closid && + tsk->rmid == rdtgrp->mon.rmid) || + (rdtgrp->type == RDTMON_GROUP && tsk->rmid == rdtgrp->mon.rmid && + tsk->closid == rdtgrp->mon.parent->closid)) + return 0; /* - * Take a refcount, so rdtgrp cannot be freed before the - * callback has been invoked. + * Set the task's closid/rmid before the PQR_ASSOC MSR can be + * updated by them. + * + * For ctrl_mon groups, move both closid and rmid. + * For monitor groups, can move the tasks only from + * their parent CTRL group. */ - atomic_inc(&rdtgrp->waitcount); - ret = task_work_add(tsk, &callback->work, true); - if (ret) { - /* - * Task is exiting. Drop the refcount and free the callback. - * No need to check the refcount as the group cannot be - * deleted before the write function unlocks rdtgroup_mutex. - */ - atomic_dec(&rdtgrp->waitcount); - kfree(callback); - rdt_last_cmd_puts("Task exited\n"); - } else { - /* - * For ctrl_mon groups move both closid and rmid. - * For monitor groups, can move the tasks only from - * their parent CTRL group. - */ - if (rdtgrp->type == RDTCTRL_GROUP) { - tsk->closid = rdtgrp->closid; - tsk->rmid = rdtgrp->mon.rmid; - } else if (rdtgrp->type == RDTMON_GROUP) { - if (rdtgrp->mon.parent->closid == tsk->closid) { - tsk->rmid = rdtgrp->mon.rmid; - } else { - rdt_last_cmd_puts("Can't move task to different control group\n"); - ret = -EINVAL; - } + + if (rdtgrp->type == RDTCTRL_GROUP) { + WRITE_ONCE(tsk->closid, rdtgrp->closid); + WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid); + } else if (rdtgrp->type == RDTMON_GROUP) { + if (rdtgrp->mon.parent->closid == tsk->closid) { + WRITE_ONCE(tsk->rmid, rdtgrp->mon.rmid); + } else { + rdt_last_cmd_puts("Can't move task to different control group\n"); + return -EINVAL; } } - return ret; + + /* + * Ensure the task's closid and rmid are written before determining if + * the task is current that will decide if it will be interrupted. + * This pairs with the full barrier between the rq->curr update and + * resctrl_sched_in() during context switch. + */ + smp_mb(); + + /* + * By now, the task's closid and rmid are set. If the task is current + * on a CPU, the PQR_ASSOC MSR needs to be updated to make the resource + * group go into effect. If the task is not current, the MSR will be + * updated when the task is scheduled in. + */ + update_task_closid_rmid(tsk); + + return 0; +} + +static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_alloc_capable && + (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); +} + +static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) +{ + return (rdt_mon_capable && + (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); } /** @@ -603,8 +620,7 @@ rcu_read_lock(); for_each_process_thread(p, t) { - if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || - (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) { + if (is_closid_match(t, r) || is_rmid_match(t, r)) { ret = 1; break; } @@ -699,12 +715,15 @@ static void show_rdt_tasks(struct rdtgroup *r, struct seq_file *s) { struct task_struct *p, *t; + pid_t pid; rcu_read_lock(); for_each_process_thread(p, t) { - if ((r->type == RDTCTRL_GROUP && t->closid == r->closid) || - (r->type == RDTMON_GROUP && t->rmid == r->mon.rmid)) - seq_printf(s, "%d\n", t->pid); + if (is_closid_match(t, r) || is_rmid_match(t, r)) { + pid = task_pid_vnr(t); + if (pid) + seq_printf(s, "%d\n", pid); + } } rcu_read_unlock(); } @@ -1027,6 +1046,7 @@ _d_cdp = rdt_find_domain(_r_cdp, d->id, NULL); if (WARN_ON(IS_ERR_OR_NULL(_d_cdp))) { _r_cdp = NULL; + _d_cdp = NULL; ret = -EINVAL; } @@ -1617,7 +1637,6 @@ if (IS_ERR(kn_subdir)) return PTR_ERR(kn_subdir); - kernfs_get(kn_subdir); ret = rdtgroup_kn_set_ugid(kn_subdir); if (ret) return ret; @@ -1640,7 +1659,6 @@ kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); if (IS_ERR(kn_info)) return PTR_ERR(kn_info); - kernfs_get(kn_info); ret = rdtgroup_add_files(kn_info, RF_TOP_INFO); if (ret) @@ -1661,12 +1679,6 @@ goto out_destroy; } - /* - * This extra ref will be put in kernfs_remove() and guarantees - * that @rdtgrp->kn is always accessible. - */ - kernfs_get(kn_info); - ret = rdtgroup_kn_set_ugid(kn_info); if (ret) goto out_destroy; @@ -1695,12 +1707,6 @@ if (dest_kn) *dest_kn = kn; - /* - * This extra ref will be put in kernfs_remove() and guarantees - * that @rdtgrp->kn is always accessible. - */ - kernfs_get(kn); - ret = rdtgroup_kn_set_ugid(kn); if (ret) goto out_destroy; @@ -1741,9 +1747,6 @@ struct rdt_domain *d; int cpu; - if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL)) - return -ENOMEM; - if (level == RDT_RESOURCE_L3) update = l3_qos_cfg_update; else if (level == RDT_RESOURCE_L2) @@ -1751,6 +1754,9 @@ else return -EINVAL; + if (!zalloc_cpumask_var(&cpu_mask, GFP_KERNEL)) + return -ENOMEM; + r_l = &rdt_resources_all[level]; list_for_each_entry(d, &r_l->domains, list) { /* Pick one CPU from each domain instance to update MSR */ @@ -1769,6 +1775,19 @@ return 0; } +/* Restore the qos cfg state when a domain comes online */ +void rdt_domain_reconfigure_cdp(struct rdt_resource *r) +{ + if (!r->alloc_capable) + return; + + if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA]) + l2_qos_cfg_update(&r->alloc_enabled); + + if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA]) + l3_qos_cfg_update(&r->alloc_enabled); +} + /* * Enable or disable the MBA software controller * which helps user specify bandwidth in MBps. @@ -1914,8 +1933,7 @@ rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) rdtgroup_pseudo_lock_remove(rdtgrp); kernfs_unbreak_active_protection(kn); - kernfs_put(rdtgrp->kn); - kfree(rdtgrp); + rdtgroup_remove(rdtgrp); } else { kernfs_unbreak_active_protection(kn); } @@ -1970,17 +1988,15 @@ if (rdt_mon_capable) { ret = mongroup_create_dir(rdtgroup_default.kn, - NULL, "mon_groups", + &rdtgroup_default, "mon_groups", &kn_mongrp); if (ret < 0) goto out_info; - kernfs_get(kn_mongrp); ret = mkdir_mondata_all(rdtgroup_default.kn, &rdtgroup_default, &kn_mondata); if (ret < 0) goto out_mongrp; - kernfs_get(kn_mondata); rdtgroup_default.mon.mon_data_kn = kn_mondata; } @@ -2146,18 +2162,6 @@ return 0; } -static bool is_closid_match(struct task_struct *t, struct rdtgroup *r) -{ - return (rdt_alloc_capable && - (r->type == RDTCTRL_GROUP) && (t->closid == r->closid)); -} - -static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r) -{ - return (rdt_mon_capable && - (r->type == RDTMON_GROUP) && (t->rmid == r->mon.rmid)); -} - /* * Move tasks from one to the other group. If @from is NULL, then all tasks * in the systems are moved unconditionally (used for teardown). @@ -2175,22 +2179,26 @@ for_each_process_thread(p, t) { if (!from || is_closid_match(t, from) || is_rmid_match(t, from)) { - t->closid = to->closid; - t->rmid = to->mon.rmid; + WRITE_ONCE(t->closid, to->closid); + WRITE_ONCE(t->rmid, to->mon.rmid); -#ifdef CONFIG_SMP /* - * This is safe on x86 w/o barriers as the ordering - * of writing to task_cpu() and t->on_cpu is - * reverse to the reading here. The detection is - * inaccurate as tasks might move or schedule - * before the smp function call takes place. In - * such a case the function call is pointless, but + * Order the closid/rmid stores above before the loads + * in task_curr(). This pairs with the full barrier + * between the rq->curr update and resctrl_sched_in() + * during context switch. + */ + smp_mb(); + + /* + * If the task is on a CPU, set the CPU in the mask. + * The detection is inaccurate as tasks might move or + * schedule before the smp function call takes place. + * In such a case the function call is pointless, but * there is no other side effect. */ - if (mask && t->on_cpu) + if (IS_ENABLED(CONFIG_SMP) && mask && task_curr(t)) cpumask_set_cpu(task_cpu(t), mask); -#endif } } read_unlock(&tasklist_lock); @@ -2205,7 +2213,11 @@ list_for_each_entry_safe(sentry, stmp, head, mon.crdtgrp_list) { free_rmid(sentry->mon.rmid); list_del(&sentry->mon.crdtgrp_list); - kfree(sentry); + + if (atomic_read(&sentry->waitcount) != 0) + sentry->flags = RDT_DELETED; + else + rdtgroup_remove(sentry); } } @@ -2243,7 +2255,11 @@ kernfs_remove(rdtgrp->kn); list_del(&rdtgrp->rdtgroup_list); - kfree(rdtgrp); + + if (atomic_read(&rdtgrp->waitcount) != 0) + rdtgrp->flags = RDT_DELETED; + else + rdtgroup_remove(rdtgrp); } /* Notify online CPUs to update per cpu storage and PQR_ASSOC MSR */ update_closid_rmid(cpu_online_mask, &rdtgroup_default); @@ -2343,11 +2359,6 @@ if (IS_ERR(kn)) return PTR_ERR(kn); - /* - * This extra ref will be put in kernfs_remove() and guarantees - * that kn is always accessible. - */ - kernfs_get(kn); ret = rdtgroup_kn_set_ugid(kn); if (ret) goto out_destroy; @@ -2446,7 +2457,7 @@ /* * Create the mon_data directory first. */ - ret = mongroup_create_dir(parent_kn, NULL, "mon_data", &kn); + ret = mongroup_create_dir(parent_kn, prgrp, "mon_data", &kn); if (ret) return ret; @@ -2645,7 +2656,7 @@ uint files = 0; int ret; - prdtgrp = rdtgroup_kn_lock_live(prgrp_kn); + prdtgrp = rdtgroup_kn_lock_live(parent_kn); if (!prdtgrp) { ret = -ENODEV; goto out_unlock; @@ -2683,8 +2694,8 @@ /* * kernfs_remove() will drop the reference count on "kn" which * will free it. But we still need it to stick around for the - * rdtgroup_kn_unlock(kn} call below. Take one extra reference - * here, which will be dropped inside rdtgroup_kn_unlock(). + * rdtgroup_kn_unlock(kn) call. Take one extra reference here, + * which will be dropped by kernfs_put() in rdtgroup_remove(). */ kernfs_get(kn); @@ -2718,18 +2729,19 @@ kernfs_activate(kn); /* - * The caller unlocks the prgrp_kn upon success. + * The caller unlocks the parent_kn upon success. */ return 0; out_idfree: free_rmid(rdtgrp->mon.rmid); out_destroy: + kernfs_put(rdtgrp->kn); kernfs_remove(rdtgrp->kn); out_free_rgrp: kfree(rdtgrp); out_unlock: - rdtgroup_kn_unlock(prgrp_kn); + rdtgroup_kn_unlock(parent_kn); return ret; } @@ -2737,7 +2749,7 @@ { kernfs_remove(rgrp->kn); free_rmid(rgrp->mon.rmid); - kfree(rgrp); + rdtgroup_remove(rgrp); } /* @@ -2767,7 +2779,7 @@ */ list_add_tail(&rdtgrp->mon.crdtgrp_list, &prgrp->mon.crdtgrp_list); - rdtgroup_kn_unlock(prgrp_kn); + rdtgroup_kn_unlock(parent_kn); return ret; } @@ -2810,7 +2822,7 @@ * Create an empty mon_groups directory to hold the subset * of tasks and cpus to monitor. */ - ret = mongroup_create_dir(kn, NULL, "mon_groups", NULL); + ret = mongroup_create_dir(kn, rdtgrp, "mon_groups", NULL); if (ret) { rdt_last_cmd_puts("kernfs subdir error\n"); goto out_del_list; @@ -2826,7 +2838,7 @@ out_common_fail: mkdir_rdt_prepare_clean(rdtgrp); out_unlock: - rdtgroup_kn_unlock(prgrp_kn); + rdtgroup_kn_unlock(parent_kn); return ret; } @@ -2899,11 +2911,6 @@ WARN_ON(list_empty(&prdtgrp->mon.crdtgrp_list)); list_del(&rdtgrp->mon.crdtgrp_list); - /* - * one extra hold on this, will drop when we kfree(rdtgrp) - * in rdtgroup_kn_unlock() - */ - kernfs_get(kn); kernfs_remove(rdtgrp->kn); return 0; @@ -2915,11 +2922,6 @@ rdtgrp->flags = RDT_DELETED; list_del(&rdtgrp->rdtgroup_list); - /* - * one extra hold on this, will drop when we kfree(rdtgrp) - * in rdtgroup_kn_unlock() - */ - kernfs_get(kn); kernfs_remove(rdtgrp->kn); return 0; } @@ -2952,13 +2954,13 @@ closid_free(rdtgrp->closid); free_rmid(rdtgrp->mon.rmid); + rdtgroup_ctrl_remove(kn, rdtgrp); + /* * Free all the child monitor group rmids. */ free_all_child_rdtgrp(rdtgrp); - rdtgroup_ctrl_remove(kn, rdtgrp); - return 0; } @@ -2985,7 +2987,8 @@ * If the rdtgroup is a mon group and parent directory * is a valid "mon_groups" directory, remove the mon group. */ - if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) { + if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn && + rdtgrp != &rdtgroup_default) { if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP || rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) { ret = rdtgroup_ctrl_remove(kn, rdtgrp); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/scattered.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/scattered.c @@ -26,6 +26,8 @@ static const struct cpuid_bit cpuid_bits[] = { { X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 }, { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, + { X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 }, + { X86_FEATURE_BHI_CTRL, CPUID_EDX, 4, 0x00000007, 2 }, { X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 }, { X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 }, { X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 }, @@ -39,8 +41,6 @@ { X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 }, { X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 }, - { X86_FEATURE_SME, CPUID_EAX, 0, 0x8000001f, 0 }, - { X86_FEATURE_SEV, CPUID_EAX, 1, 0x8000001f, 0 }, { 0, 0, 0, 0, 0 } }; --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/topology.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/topology.c @@ -25,10 +25,10 @@ #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) -#ifdef CONFIG_SMP unsigned int __max_die_per_package __read_mostly = 1; EXPORT_SYMBOL(__max_die_per_package); +#ifdef CONFIG_SMP /* * Check if given CPUID extended toplogy "leaf" is implemented */ @@ -79,7 +79,7 @@ * initial apic id, which also represents 32-bit extended x2apic id. */ c->initial_apicid = edx; - smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); + smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx)); #endif return 0; } @@ -107,7 +107,8 @@ */ cpuid_count(leaf, SMT_LEVEL, &eax, &ebx, &ecx, &edx); c->initial_apicid = edx; - core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); + core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); + smp_num_siblings = max_t(int, smp_num_siblings, LEVEL_MAX_SIBLINGS(ebx)); core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); die_level_siblings = LEVEL_MAX_SIBLINGS(ebx); die_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/tsx.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/tsx.c @@ -55,24 +55,6 @@ wrmsrl(MSR_IA32_TSX_CTRL, tsx); } -static bool __init tsx_ctrl_is_supported(void) -{ - u64 ia32_cap = x86_read_arch_cap_msr(); - - /* - * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this - * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. - * - * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a - * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES - * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get - * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, - * tsx= cmdline requests will do nothing on CPUs without - * MSR_IA32_TSX_CTRL support. - */ - return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR); -} - static enum tsx_ctrl_states x86_get_tsx_auto_mode(void) { if (boot_cpu_has_bug(X86_BUG_TAA)) @@ -86,9 +68,22 @@ char arg[5] = {}; int ret; - if (!tsx_ctrl_is_supported()) + /* + * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this + * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. + * + * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a + * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES + * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get + * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, + * tsx= cmdline requests will do nothing on CPUs without + * MSR_IA32_TSX_CTRL support. + */ + if (!(x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR)) return; + setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL); + ret = cmdline_find_option(boot_command_line, "tsx", arg, sizeof(arg)); if (ret >= 0) { if (!strcmp(arg, "on")) { @@ -115,11 +110,12 @@ tsx_disable(); /* - * tsx_disable() will change the state of the - * RTM CPUID bit. Clear it here since it is now - * expected to be not set. + * tsx_disable() will change the state of the RTM and HLE CPUID + * bits. Clear them here since they are now expected to be not + * set. */ setup_clear_cpu_cap(X86_FEATURE_RTM); + setup_clear_cpu_cap(X86_FEATURE_HLE); } else if (tsx_ctrl_state == TSX_CTRL_ENABLE) { /* @@ -131,10 +127,10 @@ tsx_enable(); /* - * tsx_enable() will change the state of the - * RTM CPUID bit. Force it here since it is now - * expected to be set. + * tsx_enable() will change the state of the RTM and HLE CPUID + * bits. Force them here since they are now expected to be set. */ setup_force_cpu_cap(X86_FEATURE_RTM); + setup_force_cpu_cap(X86_FEATURE_HLE); } } --- linux-oracle-5.4.0.orig/arch/x86/kernel/cpu/umwait.c +++ linux-oracle-5.4.0/arch/x86/kernel/cpu/umwait.c @@ -17,12 +17,6 @@ */ static u32 umwait_control_cached = UMWAIT_CTRL_VAL(100000, UMWAIT_C02_ENABLE); -u32 get_umwait_control_msr(void) -{ - return umwait_control_cached; -} -EXPORT_SYMBOL_GPL(get_umwait_control_msr); - /* * Cache the original IA32_UMWAIT_CONTROL MSR value which is configured by * hardware or BIOS before kernel boot. --- linux-oracle-5.4.0.orig/arch/x86/kernel/crash.c +++ linux-oracle-5.4.0/arch/x86/kernel/crash.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -36,9 +37,9 @@ #include #include #include -#include #include #include +#include /* Used while preparing memory map entries for second kernel */ struct crash_memmap_data { @@ -68,6 +69,19 @@ rcu_read_unlock(); } +/* + * When the crashkernel option is specified, only use the low + * 1M for the real mode trampoline. + */ +void __init crash_reserve_low_1M(void) +{ + if (cmdline_find_option(boot_command_line, "crashkernel", NULL, 0) < 0) + return; + + memblock_reserve(0, 1<<20); + pr_info("Reserving the low 1M of memory for crashkernel\n"); +} + #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static void kdump_nmi_callback(int cpu, struct pt_regs *regs) @@ -79,15 +93,6 @@ */ cpu_crash_vmclear_loaded_vmcss(); - /* Disable VMX or SVM if needed. - * - * We need to disable virtualization on all CPUs. - * Having VMX or SVM enabled on any CPU may break rebooting - * after the kdump kernel has finished its task. - */ - cpu_emergency_vmxoff(); - cpu_emergency_svm_disable(); - /* * Disable Intel PT to stop its logging */ @@ -146,12 +151,7 @@ */ cpu_crash_vmclear_loaded_vmcss(); - /* Booting kdump kernel with VMX or SVM enabled won't work, - * because (among other limitations) we can't disable paging - * with the virt flags. - */ - cpu_emergency_vmxoff(); - cpu_emergency_svm_disable(); + cpu_emergency_disable_virtualization(); /* * Disable Intel PT to stop its logging @@ -349,7 +349,7 @@ struct crash_memmap_data cmd; struct crash_mem *cmem; - cmem = vzalloc(sizeof(struct crash_mem)); + cmem = vzalloc(struct_size(cmem, ranges, 1)); if (!cmem) return -ENOMEM; --- linux-oracle-5.4.0.orig/arch/x86/kernel/devicetree.c +++ linux-oracle-5.4.0/arch/x86/kernel/devicetree.c @@ -91,7 +91,7 @@ ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (ret) - return ret; + return pcibios_err_to_errno(ret); if (!pin) return 0; --- linux-oracle-5.4.0.orig/arch/x86/kernel/doublefault.c +++ linux-oracle-5.4.0/arch/x86/kernel/doublefault.c @@ -65,6 +65,9 @@ .ss = __KERNEL_DS, .ds = __USER_DS, .fs = __KERNEL_PERCPU, +#ifndef CONFIG_X86_32_LAZY_GS + .gs = __KERNEL_STACK_CANARY, +#endif .__cr3 = __pa_nodebug(swapper_pg_dir), }; --- linux-oracle-5.4.0.orig/arch/x86/kernel/dumpstack.c +++ linux-oracle-5.4.0/arch/x86/kernel/dumpstack.c @@ -171,7 +171,6 @@ printk("%sCall Trace:\n", log_lvl); unwind_start(&state, task, regs, stack); - stack = stack ? : get_stack_pointer(task, regs); regs = unwind_get_entry_regs(&state, &partial); /* @@ -190,9 +189,13 @@ * - hardirq stack * - entry stack */ - for ( ; stack; stack = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { + for (stack = stack ?: get_stack_pointer(task, regs); + stack; + stack = stack_info.next_sp) { const char *stack_name; + stack = PTR_ALIGN(stack, sizeof(long)); + if (get_stack_info(stack, task, &stack_info, &visit_mask)) { /* * We weren't on a valid stack. It's possible that @@ -326,7 +329,7 @@ } NOKPROBE_SYMBOL(oops_begin); -void __noreturn rewind_stack_do_exit(int signr); +void __noreturn rewind_stack_and_make_dead(int signr); void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { @@ -361,7 +364,7 @@ * reuse the task stack and that existing poisons are invalid. */ kasan_unpoison_task_stack(current); - rewind_stack_do_exit(signr); + rewind_stack_and_make_dead(signr); } NOKPROBE_SYMBOL(oops_end); --- linux-oracle-5.4.0.orig/arch/x86/kernel/early-quirks.c +++ linux-oracle-5.4.0/arch/x86/kernel/early-quirks.c @@ -28,6 +28,37 @@ #include #include +static void __init early_pci_clear_msi(int bus, int slot, int func) +{ + int pos; + u16 ctrl; + + if (likely(!pci_early_clear_msi)) + return; + + pr_info_once("Clearing MSI/MSI-X enable bits early in boot (quirk)\n"); + + pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSI); + if (pos) { + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS); + ctrl &= ~PCI_MSI_FLAGS_ENABLE; + write_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS, ctrl); + + /* Read again to flush previous write */ + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS); + } + + pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSIX); + if (pos) { + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS); + ctrl &= ~PCI_MSIX_FLAGS_ENABLE; + write_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS, ctrl); + + /* Read again to flush previous write */ + ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS); + } +} + static void __init fix_hypertransport_config(int num, int slot, int func) { u32 htcfg; @@ -515,6 +546,7 @@ .stolen_size = gen9_stolen_size, }; +/* Intel integrated GPUs for which we need to reserve "stolen memory" */ static const struct pci_device_id intel_early_ids[] __initconst = { INTEL_I830_IDS(&i830_early_ops), INTEL_I845G_IDS(&i845_early_ops), @@ -587,6 +619,13 @@ u16 device; int i; + /* + * Reserve "stolen memory" for an integrated GPU. If we've already + * found one, there's nothing to do for other (discrete) GPUs. + */ + if (resource_size(&intel_graphics_stolen_res)) + return; + device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); for (i = 0; i < ARRAY_SIZE(intel_early_ids); i++) { @@ -699,7 +738,7 @@ { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, - QFLAG_APPLY_ONCE, intel_graphics_quirks }, + 0, intel_graphics_quirks }, /* * HPET on the current version of the Baytrail platform has accuracy * problems: it will halt in deep idle state - so we disable it. @@ -710,10 +749,9 @@ */ { PCI_VENDOR_ID_INTEL, 0x0f00, PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, - { PCI_VENDOR_ID_INTEL, 0x3ec4, - PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, { PCI_VENDOR_ID_BROADCOM, 0x4331, PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset}, + { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, early_pci_clear_msi}, {} }; @@ -766,6 +804,10 @@ PCI_HEADER_TYPE); if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) { + /* pci_early_clear_msi scans the buses differently. */ + if (pci_early_clear_msi) + return -1; + sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS); if (sec > num) early_pci_scan_bus(sec); @@ -792,8 +834,13 @@ void __init early_quirks(void) { + int bus; + if (!early_pci_allowed()) return; early_pci_scan_bus(0); + /* pci_early_clear_msi scans more buses. */ + for (bus = 1; pci_early_clear_msi && bus < 256; bus++) + early_pci_scan_bus(bus); } --- linux-oracle-5.4.0.orig/arch/x86/kernel/fpu/core.c +++ linux-oracle-5.4.0/arch/x86/kernel/fpu/core.c @@ -82,7 +82,7 @@ } EXPORT_SYMBOL(irq_fpu_usable); -void kernel_fpu_begin(void) +void kernel_fpu_begin_mask(unsigned int kfpu_mask) { preempt_disable(); @@ -101,8 +101,15 @@ copy_fpregs_to_fpstate(¤t->thread.fpu); } __cpu_invalidate_fpregs_state(); + + /* Put sane initial values into the control registers. */ + if (likely(kfpu_mask & KFPU_MXCSR) && boot_cpu_has(X86_FEATURE_XMM)) + ldmxcsr(MXCSR_DEFAULT); + + if (unlikely(kfpu_mask & KFPU_387) && boot_cpu_has(X86_FEATURE_FPU)) + asm volatile ("fninit"); } -EXPORT_SYMBOL_GPL(kernel_fpu_begin); +EXPORT_SYMBOL_GPL(kernel_fpu_begin_mask); void kernel_fpu_end(void) { --- linux-oracle-5.4.0.orig/arch/x86/kernel/fpu/init.c +++ linux-oracle-5.4.0/arch/x86/kernel/fpu/init.c @@ -50,7 +50,7 @@ fpu__init_cpu_xstate(); } -static bool fpu__probe_without_cpuid(void) +static bool __init fpu__probe_without_cpuid(void) { unsigned long cr0; u16 fsw, fcw; @@ -68,7 +68,7 @@ return fsw == 0 && (fcw & 0x103f) == 0x003f; } -static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) +static void __init fpu__init_system_early_generic(void) { if (!boot_cpu_has(X86_FEATURE_CPUID) && !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { @@ -139,9 +139,6 @@ unsigned int fpu_kernel_xstate_size; EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size); -/* Get alignment of the TYPE. */ -#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test) - /* * Enforce that 'MEMBER' is the last field of 'TYPE'. * @@ -149,8 +146,8 @@ * because that's how C aligns structs. */ #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \ - BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \ - TYPE_ALIGN(TYPE))) + BUILD_BUG_ON(sizeof(TYPE) != \ + ALIGN(offsetofend(TYPE, MEMBER), _Alignof(TYPE))) /* * We append the 'struct fpu' to the task_struct: @@ -242,9 +239,9 @@ */ static void __init fpu__init_parse_early_param(void) { - char arg[32]; + char arg[128]; char *argptr = arg; - int bit; + int arglen, res, bit; #ifdef CONFIG_X86_32 if (cmdline_find_option_bool(boot_command_line, "no387")) @@ -267,22 +264,36 @@ if (cmdline_find_option_bool(boot_command_line, "noxsaves")) setup_clear_cpu_cap(X86_FEATURE_XSAVES); - if (cmdline_find_option(boot_command_line, "clearcpuid", arg, - sizeof(arg)) && - get_option(&argptr, &bit) && - bit >= 0 && - bit < NCAPINTS * 32) - setup_clear_cpu_cap(bit); + arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg)); + if (arglen <= 0) + return; + + pr_info("Clearing CPUID bits:"); + do { + res = get_option(&argptr, &bit); + if (res == 0 || res == 3) + break; + + /* If the argument was too long, the last bit may be cut off */ + if (res == 1 && arglen >= sizeof(arg)) + break; + + if (bit >= 0 && bit < NCAPINTS * 32) { + pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit)); + setup_clear_cpu_cap(bit); + } + } while (res == 2); + pr_cont("\n"); } /* * Called on the boot CPU once per system bootup, to set up the initial * FPU state that is later cloned into all processes: */ -void __init fpu__init_system(struct cpuinfo_x86 *c) +void __init fpu__init_system(void) { fpu__init_parse_early_param(); - fpu__init_system_early_generic(c); + fpu__init_system_early_generic(); /* * The FPU has to be operational for some of the --- linux-oracle-5.4.0.orig/arch/x86/kernel/fpu/regset.c +++ linux-oracle-5.4.0/arch/x86/kernel/fpu/regset.c @@ -124,7 +124,7 @@ /* * A whole standard-format XSAVE buffer is needed: */ - if ((pos != 0) || (count < fpu_user_xstate_size)) + if (pos != 0 || count != fpu_user_xstate_size) return -EFAULT; xsave = &fpu->state.xsave; --- linux-oracle-5.4.0.orig/arch/x86/kernel/fpu/signal.c +++ linux-oracle-5.4.0/arch/x86/kernel/fpu/signal.c @@ -289,13 +289,17 @@ return 0; } - if (!access_ok(buf, size)) - return -EACCES; + if (!access_ok(buf, size)) { + ret = -EACCES; + goto out; + } - if (!static_cpu_has(X86_FEATURE_FPU)) - return fpregs_soft_set(current, NULL, - 0, sizeof(struct user_i387_ia32_struct), - NULL, buf) != 0; + if (!static_cpu_has(X86_FEATURE_FPU)) { + ret = fpregs_soft_set(current, NULL, 0, + sizeof(struct user_i387_ia32_struct), + NULL, buf); + goto out; + } if (use_xsave()) { struct _fpx_sw_bytes fx_sw_user; @@ -333,7 +337,7 @@ if (ia32_fxstate) { ret = __copy_from_user(&env, buf, sizeof(env)); if (ret) - goto err_out; + goto out; envp = &env; } else { /* @@ -352,6 +356,7 @@ fpregs_unlock(); return 0; } + fpregs_deactivate(fpu); fpregs_unlock(); } @@ -368,7 +373,7 @@ ret = validate_xstate_header(&fpu->state.xsave.header); } if (ret) - goto err_out; + goto out; sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); @@ -381,7 +386,7 @@ ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size); if (ret) { ret = -EFAULT; - goto err_out; + goto out; } sanitize_restored_xstate(&fpu->state, envp, xfeatures, fx_only); @@ -396,16 +401,18 @@ } else { ret = __copy_from_user(&fpu->state.fsave, buf_fx, state_size); if (ret) - goto err_out; + goto out; fpregs_lock(); ret = copy_kernel_to_fregs_err(&fpu->state.fsave); } if (!ret) fpregs_mark_activate(); + else + fpregs_deactivate(fpu); fpregs_unlock(); -err_out: +out: if (ret) fpu__clear(fpu); return ret; --- linux-oracle-5.4.0.orig/arch/x86/kernel/fpu/xstate.c +++ linux-oracle-5.4.0/arch/x86/kernel/fpu/xstate.c @@ -399,12 +399,32 @@ } /* + * All supported features have either init state all zeros or are + * handled in setup_init_fpu() individually. This is an explicit + * feature list and does not use XFEATURE_MASK*SUPPORTED to catch + * newly added supported features at build time and make people + * actually look at the init state for the new feature. + */ +#define XFEATURES_INIT_FPSTATE_HANDLED \ + (XFEATURE_MASK_FP | \ + XFEATURE_MASK_SSE | \ + XFEATURE_MASK_YMM | \ + XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_ZMM_Hi256 | \ + XFEATURE_MASK_Hi16_ZMM | \ + XFEATURE_MASK_PKRU | \ + XFEATURE_MASK_BNDREGS | \ + XFEATURE_MASK_BNDCSR) + +/* * setup the xstate image representing the init state */ static void __init setup_init_fpu_buf(void) { static int on_boot_cpu __initdata = 1; + BUILD_BUG_ON(XCNTXT_MASK != XFEATURES_INIT_FPSTATE_HANDLED); + WARN_ON_FPU(!on_boot_cpu); on_boot_cpu = 0; @@ -423,10 +443,22 @@ copy_kernel_to_xregs_booting(&init_fpstate.xsave); /* - * Dump the init state again. This is to identify the init state - * of any feature which is not represented by all zero's. + * All components are now in init state. Read the state back so + * that init_fpstate contains all non-zero init state. This only + * works with XSAVE, but not with XSAVEOPT and XSAVES because + * those use the init optimization which skips writing data for + * components in init state. + * + * XSAVE could be used, but that would require to reshuffle the + * data when XSAVES is available because XSAVES uses xstate + * compaction. But doing so is a pointless exercise because most + * components have an all zeros init state except for the legacy + * ones (FP and SSE). Those can be saved with FXSAVE into the + * legacy area. Adding new features requires to ensure that init + * state is all zeroes or if not to add the necessary handling + * here. */ - copy_xregs_to_kernel_booting(&init_fpstate.xsave); + fxsave(&init_fpstate.fxsave); } static int xfeature_uncompacted_offset(int xfeature_nr) @@ -773,6 +805,14 @@ fpu__init_prepare_fx_sw_frame(); setup_init_fpu_buf(); setup_xstate_comp(); + + /* + * CPU capabilities initialization runs before FPU init. So + * X86_FEATURE_OSXSAVE is not set. Now that XSAVE is completely + * functional, set the feature bit so depending code works. + */ + setup_force_cpu_cap(X86_FEATURE_OSXSAVE); + print_xstate_offset_size(); pr_info("x86/fpu: Enabled xstate features 0x%llx, context size is %d bytes, using '%s' format.\n", @@ -895,8 +935,6 @@ #ifdef CONFIG_ARCH_HAS_PKEYS -#define NR_VALID_PKRU_BITS (CONFIG_NR_PROTECTION_KEYS * 2) -#define PKRU_VALID_MASK (NR_VALID_PKRU_BITS - 1) /* * This will go out and modify PKRU register to set the access * rights for @pkey to @init_val. @@ -915,6 +953,13 @@ if (!boot_cpu_has(X86_FEATURE_OSPKE)) return -EINVAL; + /* + * This code should only be called with valid 'pkey' + * values originating from in-kernel users. Complain + * if a bad value is observed. + */ + WARN_ON_ONCE(pkey >= arch_max_pkey()); + /* Set the bits we need in PKRU: */ if (init_val & PKEY_DISABLE_ACCESS) new_pkru_bits |= PKRU_AD_BIT; @@ -952,18 +997,31 @@ return true; } -/* - * This is similar to user_regset_copyout(), but will not add offset to - * the source data pointer or increment pos, count, kbuf, and ubuf. - */ -static inline void -__copy_xstate_to_kernel(void *kbuf, const void *data, - unsigned int offset, unsigned int size, unsigned int size_total) +static void fill_gap(unsigned to, void **kbuf, unsigned *pos, unsigned *count) { - if (offset < size_total) { - unsigned int copy = min(size, size_total - offset); + if (*pos < to) { + unsigned size = to - *pos; + + if (size > *count) + size = *count; + memcpy(*kbuf, (void *)&init_fpstate.xsave + *pos, size); + *kbuf += size; + *pos += size; + *count -= size; + } +} - memcpy(kbuf + offset, data, copy); +static void copy_part(unsigned offset, unsigned size, void *from, + void **kbuf, unsigned *pos, unsigned *count) +{ + fill_gap(offset, kbuf, pos, count); + if (size > *count) + size = *count; + if (size) { + memcpy(*kbuf, from, size); + *kbuf += size; + *pos += size; + *count -= size; } } @@ -976,8 +1034,9 @@ */ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) { - unsigned int offset, size; struct xstate_header header; + const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr); + unsigned count = size_total; int i; /* @@ -993,46 +1052,42 @@ header.xfeatures = xsave->header.xfeatures; header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; + if (header.xfeatures & XFEATURE_MASK_FP) + copy_part(0, off_mxcsr, + &xsave->i387, &kbuf, &offset_start, &count); + if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM)) + copy_part(off_mxcsr, MXCSR_AND_FLAGS_SIZE, + &xsave->i387.mxcsr, &kbuf, &offset_start, &count); + if (header.xfeatures & XFEATURE_MASK_FP) + copy_part(offsetof(struct fxregs_state, st_space), 128, + &xsave->i387.st_space, &kbuf, &offset_start, &count); + if (header.xfeatures & XFEATURE_MASK_SSE) + copy_part(xstate_offsets[XFEATURE_SSE], 256, + &xsave->i387.xmm_space, &kbuf, &offset_start, &count); + /* + * Fill xsave->i387.sw_reserved value for ptrace frame: + */ + copy_part(offsetof(struct fxregs_state, sw_reserved), 48, + xstate_fx_sw_bytes, &kbuf, &offset_start, &count); /* * Copy xregs_state->header: */ - offset = offsetof(struct xregs_state, header); - size = sizeof(header); + copy_part(offsetof(struct xregs_state, header), sizeof(header), + &header, &kbuf, &offset_start, &count); - __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total); - - for (i = 0; i < XFEATURE_MAX; i++) { + for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { /* * Copy only in-use xstates: */ if ((header.xfeatures >> i) & 1) { void *src = __raw_xsave_addr(xsave, i); - offset = xstate_offsets[i]; - size = xstate_sizes[i]; - - /* The next component has to fit fully into the output buffer: */ - if (offset + size > size_total) - break; - - __copy_xstate_to_kernel(kbuf, src, offset, size, size_total); + copy_part(xstate_offsets[i], xstate_sizes[i], + src, &kbuf, &offset_start, &count); } } - - if (xfeatures_mxcsr_quirk(header.xfeatures)) { - offset = offsetof(struct fxregs_state, mxcsr); - size = MXCSR_AND_FLAGS_SIZE; - __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total); - } - - /* - * Fill xsave->i387.sw_reserved value for ptrace frame: - */ - offset = offsetof(struct fxregs_state, sw_reserved); - size = sizeof(xstate_fx_sw_bytes); - - __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total); + fill_gap(size_total, &kbuf, &offset_start, &count); return 0; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/ftrace_32.S +++ linux-oracle-5.4.0/arch/x86/kernel/ftrace_32.S @@ -89,7 +89,7 @@ ret END(ftrace_caller) -ENTRY(ftrace_regs_caller) +SYM_CODE_START(ftrace_regs_caller) /* * We're here from an mcount/fentry CALL, and the stack frame looks like: * @@ -163,6 +163,7 @@ popl %eax jmp .Lftrace_ret +SYM_CODE_END(ftrace_regs_caller) #ifdef CONFIG_FUNCTION_GRAPH_TRACER ENTRY(ftrace_graph_caller) --- linux-oracle-5.4.0.orig/arch/x86/kernel/head64.c +++ linux-oracle-5.4.0/arch/x86/kernel/head64.c @@ -383,6 +383,8 @@ { memset(__bss_start, 0, (unsigned long) __bss_stop - (unsigned long) __bss_start); + memset(__brk_base, 0, + (unsigned long) __brk_limit - (unsigned long) __brk_base); } static unsigned long get_cmd_line_ptr(void) --- linux-oracle-5.4.0.orig/arch/x86/kernel/head_32.S +++ linux-oracle-5.4.0/arch/x86/kernel/head_32.S @@ -26,6 +26,7 @@ #include #include #include +#include /* Physical address */ #define pa(X) ((X) - __PAGE_OFFSET) @@ -64,7 +65,7 @@ * can. */ __HEAD -ENTRY(startup_32) +SYM_CODE_START(startup_32) movl pa(initial_stack),%ecx /* test KEEP_SEGMENTS flag to see if the bootloader is asking @@ -153,6 +154,7 @@ movl pa(subarch_entries)(,%eax,4), %eax subl $__PAGE_OFFSET, %eax + ANNOTATE_RETPOLINE_SAFE jmp *%eax .Lbad_subarch: @@ -172,6 +174,7 @@ #else jmp .Ldefault_entry #endif /* CONFIG_PARAVIRT */ +SYM_CODE_END(startup_32) #ifdef CONFIG_HOTPLUG_CPU /* @@ -302,6 +305,7 @@ movl setup_once_ref,%eax andl %eax,%eax jz 1f # Did we do this already? + ANNOTATE_RETPOLINE_SAFE call *%eax 1: @@ -571,6 +575,16 @@ # error "Kernel PMDs should be 1, 2 or 3" # endif .align PAGE_SIZE /* needs to be page-sized too */ + +#ifdef CONFIG_PAGE_TABLE_ISOLATION + /* + * PTI needs another page so sync_initial_pagetable() works correctly + * and does not scribble over the data which is placed behind the + * actual initial_page_table. See clone_pgd_range(). + */ + .fill 1024, 4, 0 +#endif + #endif .data --- linux-oracle-5.4.0.orig/arch/x86/kernel/head_64.S +++ linux-oracle-5.4.0/arch/x86/kernel/head_64.S @@ -335,12 +335,6 @@ jmp restore_regs_and_return_to_kernel END(early_idt_handler_common) - __INITDATA - - .balign 4 -GLOBAL(early_recursion_flag) - .long 0 - #define NEXT_PAGE(name) \ .balign PAGE_SIZE; \ GLOBAL(name) @@ -375,6 +369,8 @@ .endr __INITDATA + .balign 4 + NEXT_PGD_PAGE(early_top_pgt) .fill 512,8,0 .fill PTI_USER_PGD_FILL,8,0 @@ -382,6 +378,9 @@ NEXT_PAGE(early_dynamic_pgts) .fill 512*EARLY_DYNAMIC_PAGE_TABLES,8,0 +GLOBAL(early_recursion_flag) + .long 0 + .data #if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH) --- linux-oracle-5.4.0.orig/arch/x86/kernel/hpet.c +++ linux-oracle-5.4.0/arch/x86/kernel/hpet.c @@ -9,6 +9,7 @@ #include #include +#include #undef pr_fmt #define pr_fmt(fmt) "hpet: " fmt @@ -806,6 +807,83 @@ return false; } +static bool __init mwait_pc10_supported(void) +{ + unsigned int eax, ebx, ecx, mwait_substates; + + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return false; + + if (!cpu_feature_enabled(X86_FEATURE_MWAIT)) + return false; + + if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) + return false; + + cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &mwait_substates); + + return (ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) && + (ecx & CPUID5_ECX_INTERRUPT_BREAK) && + (mwait_substates & (0xF << 28)); +} + +/* + * Check whether the system supports PC10. If so force disable HPET as that + * stops counting in PC10. This check is overbroad as it does not take any + * of the following into account: + * + * - ACPI tables + * - Enablement of intel_idle + * - Command line arguments which limit intel_idle C-state support + * + * That's perfectly fine. HPET is a piece of hardware designed by committee + * and the only reasons why it is still in use on modern systems is the + * fact that it is impossible to reliably query TSC and CPU frequency via + * CPUID or firmware. + * + * If HPET is functional it is useful for calibrating TSC, but this can be + * done via PMTIMER as well which seems to be the last remaining timer on + * X86/INTEL platforms that has not been completely wreckaged by feature + * creep. + * + * In theory HPET support should be removed altogether, but there are older + * systems out there which depend on it because TSC and APIC timer are + * dysfunctional in deeper C-states. + * + * It's only 20 years now that hardware people have been asked to provide + * reliable and discoverable facilities which can be used for timekeeping + * and per CPU timer interrupts. + * + * The probability that this problem is going to be solved in the + * forseeable future is close to zero, so the kernel has to be cluttered + * with heuristics to keep up with the ever growing amount of hardware and + * firmware trainwrecks. Hopefully some day hardware people will understand + * that the approach of "This can be fixed in software" is not sustainable. + * Hope dies last... + */ +static bool __init hpet_is_pc10_damaged(void) +{ + unsigned long long pcfg; + + /* Check whether PC10 substates are supported */ + if (!mwait_pc10_supported()) + return false; + + /* Check whether PC10 is enabled in PKG C-state limit */ + rdmsrl(MSR_PKG_CST_CONFIG_CONTROL, pcfg); + if ((pcfg & 0xF) < 8) + return false; + + if (hpet_force_user) { + pr_warn("HPET force enabled via command line, but dysfunctional in PC10.\n"); + return false; + } + + pr_info("HPET dysfunctional in PC10. Force disabled.\n"); + boot_hpet_disable = true; + return true; +} + /** * hpet_enable - Try to setup the HPET timer. Returns 1 on success. */ @@ -819,6 +897,9 @@ if (!is_hpet_capable()) return 0; + if (hpet_is_pc10_damaged()) + return 0; + hpet_set_mapping(); if (!hpet_virt_address) return 0; --- linux-oracle-5.4.0.orig/arch/x86/kernel/i8253.c +++ linux-oracle-5.4.0/arch/x86/kernel/i8253.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -39,9 +40,15 @@ bool __init pit_timer_init(void) { - if (!use_pit()) + if (!use_pit()) { + /* + * Don't just ignore the PIT. Ensure it's stopped, because + * VMMs otherwise steal CPU time just to pointlessly waggle + * the (masked) IRQ. + */ + clockevent_i8253_disable(); return false; - + } clockevent_i8253_init(true); global_clock_event = &i8253_clockevent; return true; --- linux-oracle-5.4.0.orig/arch/x86/kernel/i8259.c +++ linux-oracle-5.4.0/arch/x86/kernel/i8259.c @@ -32,6 +32,7 @@ */ static void init_8259A(int auto_eoi); +static bool pcat_compat __ro_after_init; static int i8259A_auto_eoi; DEFINE_RAW_SPINLOCK(i8259A_lock); @@ -114,6 +115,7 @@ disable_irq_nosync(irq); io_apic_irqs &= ~(1< 0 or has_legacy_pic() == true. This is silly + * when the system has an IO/APIC because then PIC is not required + * at all, except for really old machines where the timer interrupt + * must be routed through the PIC. So just pretend that the PIC is + * there and let legacy_pic->init() initialize it for nothing. + * + * Alternatively this could just try to initialize the PIC and + * repeat the probe, but for cases where there is no PIC that's + * just pointless. + */ + if (pcat_compat) + return nr_legacy_irqs(); + /* - * Check to see if we have a PIC. - * Mask all except the cascade and read - * back the value we just wrote. If we don't - * have a PIC, we will read 0xff as opposed to the - * value we wrote. + * Check to see if we have a PIC. Mask all except the cascade and + * read back the value we just wrote. If we don't have a PIC, we + * will read 0xff as opposed to the value we wrote. */ raw_spin_lock_irqsave(&i8259A_lock, flags); @@ -430,5 +449,9 @@ return 0; } - device_initcall(i8259A_init_ops); + +void __init legacy_pic_pcat_compat(void) +{ + pcat_compat = true; +} --- linux-oracle-5.4.0.orig/arch/x86/kernel/idt.c +++ linux-oracle-5.4.0/arch/x86/kernel/idt.c @@ -318,7 +318,11 @@ #ifdef CONFIG_X86_LOCAL_APIC for_each_clear_bit_from(i, system_vectors, NR_VECTORS) { - set_bit(i, system_vectors); + /* + * Don't set the non assigned system vectors in the + * system_vectors bitmap. Otherwise they show up in + * /proc/interrupts. + */ entry = spurious_entries_start + 8 * (i - FIRST_SYSTEM_VECTOR); set_intr_gate(i, entry); } --- linux-oracle-5.4.0.orig/arch/x86/kernel/ima_arch.c +++ linux-oracle-5.4.0/arch/x86/kernel/ima_arch.c @@ -10,8 +10,6 @@ static enum efi_secureboot_mode get_sb_mode(void) { - efi_char16_t efi_SecureBoot_name[] = L"SecureBoot"; - efi_char16_t efi_SetupMode_name[] = L"SecureBoot"; efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; efi_status_t status; unsigned long size; @@ -25,7 +23,7 @@ } /* Get variable contents into buffer */ - status = efi.get_variable(efi_SecureBoot_name, &efi_variable_guid, + status = efi.get_variable(L"SecureBoot", &efi_variable_guid, NULL, &size, &secboot); if (status == EFI_NOT_FOUND) { pr_info("ima: secureboot mode disabled\n"); @@ -38,7 +36,7 @@ } size = sizeof(setupmode); - status = efi.get_variable(efi_SetupMode_name, &efi_variable_guid, + status = efi.get_variable(L"SetupMode", &efi_variable_guid, NULL, &size, &setupmode); if (status != EFI_SUCCESS) /* ignore unknown SetupMode */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/irq.c +++ linux-oracle-5.4.0/arch/x86/kernel/irq.c @@ -295,8 +295,10 @@ { if (handler) kvm_posted_intr_wakeup_handler = handler; - else + else { kvm_posted_intr_wakeup_handler = dummy_handler; + synchronize_rcu(); + } } EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler); --- linux-oracle-5.4.0.orig/arch/x86/kernel/irq_64.c +++ linux-oracle-5.4.0/arch/x86/kernel/irq_64.c @@ -43,7 +43,7 @@ pages[i] = pfn_to_page(pa >> PAGE_SHIFT); } - va = vmap(pages, IRQ_STACK_SIZE / PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL); + va = vmap(pages, IRQ_STACK_SIZE / PAGE_SIZE, VM_MAP, PAGE_KERNEL); if (!va) return -ENOMEM; --- linux-oracle-5.4.0.orig/arch/x86/kernel/irqinit.c +++ linux-oracle-5.4.0/arch/x86/kernel/irqinit.c @@ -72,8 +72,10 @@ legacy_pic->init(0); - for (i = 0; i < nr_legacy_irqs(); i++) + for (i = 0; i < nr_legacy_irqs(); i++) { irq_set_chip_and_handler(i, chip, handle_level_irq); + irq_set_status_flags(i, IRQ_LEVEL); + } } void __init init_IRQ(void) --- linux-oracle-5.4.0.orig/arch/x86/kernel/kexec-bzimage64.c +++ linux-oracle-5.4.0/arch/x86/kernel/kexec-bzimage64.c @@ -210,8 +210,7 @@ params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch; /* Copying screen_info will do? */ - memcpy(¶ms->screen_info, &boot_params.screen_info, - sizeof(struct screen_info)); + memcpy(¶ms->screen_info, &screen_info, sizeof(struct screen_info)); /* Fill in memsize later */ params->screen_info.ext_mem_k = 0; --- linux-oracle-5.4.0.orig/arch/x86/kernel/kprobes/core.c +++ linux-oracle-5.4.0/arch/x86/kernel/kprobes/core.c @@ -157,6 +157,8 @@ int can_boost(struct insn *insn, void *addr) { kprobe_opcode_t opcode; + insn_byte_t prefix; + int i; if (search_exception_tables((unsigned long)addr)) return 0; /* Page fault may occur on this address. */ @@ -169,9 +171,14 @@ if (insn->opcode.nbytes != 1) return 0; - /* Can't boost Address-size override prefix */ - if (unlikely(inat_is_address_size_prefix(insn->attr))) - return 0; + for_each_insn_prefix(insn, i, prefix) { + insn_attr_t attr; + + attr = inat_get_opcode_attribute(prefix); + /* Can't boost Address-size override prefix and CS override prefix */ + if (prefix == 0x2e || inat_is_address_size_prefix(attr)) + return 0; + } opcode = insn->opcode.bytes[0]; @@ -196,8 +203,8 @@ /* clear and set flags are boostable */ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); default: - /* CS override prefix and call are not boostable */ - return (opcode != 0x2e && opcode != 0x9a); + /* call is not boostable */ + return opcode != 0x9a; } } @@ -351,6 +358,10 @@ kernel_insn_init(insn, dest, MAX_INSN_SIZE); insn_get_length(insn); + /* We can not probe force emulate prefixed instruction */ + if (insn_has_emulate_prefix(insn)) + return 0; + /* Another subsystem puts a breakpoint, failed to recover */ if (insn->opcode.bytes[0] == BREAKPOINT_INSTRUCTION) return 0; @@ -746,16 +757,11 @@ NOKPROBE_SYMBOL(kretprobe_trampoline); STACK_FRAME_NON_STANDARD(kretprobe_trampoline); -static struct kprobe kretprobe_kprobe = { - .addr = (void *)kretprobe_trampoline, -}; - /* * Called from kretprobe_trampoline */ __used __visible void *trampoline_handler(struct pt_regs *regs) { - struct kprobe_ctlblk *kcb; struct kretprobe_instance *ri = NULL; struct hlist_head *head, empty_rp; struct hlist_node *tmp; @@ -765,16 +771,12 @@ void *frame_pointer; bool skipped = false; - preempt_disable(); - /* * Set a dummy kprobe for avoiding kretprobe recursion. * Since kretprobe never run in kprobe handler, kprobe must not * be running at this point. */ - kcb = get_kprobe_ctlblk(); - __this_cpu_write(current_kprobe, &kretprobe_kprobe); - kcb->kprobe_status = KPROBE_HIT_ACTIVE; + kprobe_busy_begin(); INIT_HLIST_HEAD(&empty_rp); kretprobe_hash_lock(current, &head, &flags); @@ -850,7 +852,7 @@ __this_cpu_write(current_kprobe, &ri->rp->kp); ri->ret_addr = correct_ret_addr; ri->rp->handler(ri, regs); - __this_cpu_write(current_kprobe, &kretprobe_kprobe); + __this_cpu_write(current_kprobe, &kprobe_busy); } recycle_rp_inst(ri, &empty_rp); @@ -866,8 +868,7 @@ kretprobe_hash_unlock(current, &flags); - __this_cpu_write(current_kprobe, NULL); - preempt_enable(); + kprobe_busy_end(); hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { hlist_del(&ri->hlist); @@ -1029,6 +1030,11 @@ * So clear it by resetting the current kprobe: */ regs->flags &= ~X86_EFLAGS_TF; + /* + * Since the single step (trap) has been cancelled, + * we need to restore BTF here. + */ + restore_btf(); /* * If the TF flag was set before the kprobe hit, --- linux-oracle-5.4.0.orig/arch/x86/kernel/kprobes/opt.c +++ linux-oracle-5.4.0/arch/x86/kernel/kprobes/opt.c @@ -43,8 +43,8 @@ /* This function only handles jump-optimized kprobe */ if (kp && kprobe_optimized(kp)) { op = container_of(kp, struct optimized_kprobe, kp); - /* If op->list is not empty, op is under optimizing */ - if (list_empty(&op->list)) + /* If op is optimized or under unoptimizing */ + if (list_empty(&op->list) || optprobe_queued_unopt(op)) goto found; } } @@ -314,7 +314,7 @@ for (i = 1; i < op->optinsn.size; i++) { p = get_kprobe(op->kp.addr + i); - if (p && !kprobe_disabled(p)) + if (p && !kprobe_disarmed(p)) return -EEXIST; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/kvm.c +++ linux-oracle-5.4.0/arch/x86/kernel/kvm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include static int kvmapf = 1; @@ -57,6 +59,7 @@ DEFINE_PER_CPU_DECRYPTED(struct kvm_steal_time, steal_time) __aligned(64) __visible; static int has_steal_clock = 0; +static int has_guest_poll = 0; /* * No need for any "IO delay" on KVM */ @@ -321,8 +324,7 @@ wrmsrl(MSR_KVM_ASYNC_PF_EN, pa); __this_cpu_write(apf_reason.enabled, 1); - printk(KERN_INFO"KVM setup async PF for cpu %d\n", - smp_processor_id()); + pr_info("setup async PF for cpu %d\n", smp_processor_id()); } if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) { @@ -347,35 +349,17 @@ wrmsrl(MSR_KVM_ASYNC_PF_EN, 0); __this_cpu_write(apf_reason.enabled, 0); - printk(KERN_INFO"Unregister pv shared memory for cpu %d\n", - smp_processor_id()); + pr_info("disable async PF for cpu %d\n", smp_processor_id()); } -static void kvm_pv_guest_cpu_reboot(void *unused) +static void kvm_disable_steal_time(void) { - /* - * We disable PV EOI before we load a new kernel by kexec, - * since MSR_KVM_PV_EOI_EN stores a pointer into old kernel's memory. - * New kernel can re-enable when it boots. - */ - if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) - wrmsrl(MSR_KVM_PV_EOI_EN, 0); - kvm_pv_disable_apf(); - kvm_disable_steal_time(); -} + if (!has_steal_clock) + return; -static int kvm_pv_reboot_notify(struct notifier_block *nb, - unsigned long code, void *unused) -{ - if (code == SYS_RESTART) - on_each_cpu(kvm_pv_guest_cpu_reboot, NULL, 1); - return NOTIFY_DONE; + wrmsr(MSR_KVM_STEAL_TIME, 0, 0); } -static struct notifier_block kvm_pv_reboot_nb = { - .notifier_call = kvm_pv_reboot_notify, -}; - static u64 kvm_steal_clock(int cpu) { u64 steal; @@ -393,14 +377,6 @@ return steal; } -void kvm_disable_steal_time(void) -{ - if (!has_steal_clock) - return; - - wrmsr(MSR_KVM_STEAL_TIME, 0, 0); -} - static inline void __set_percpu_decrypted(void *ptr, unsigned long size) { early_set_memory_decrypted((unsigned long) ptr, size); @@ -428,6 +404,27 @@ } } +static void kvm_guest_cpu_offline(bool shutdown) +{ + kvm_disable_steal_time(); + if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) + wrmsrl(MSR_KVM_PV_EOI_EN, 0); + kvm_pv_disable_apf(); + if (!shutdown) + apf_task_wake_all(); + kvmclock_disable(); +} + +static int kvm_cpu_online(unsigned int cpu) +{ + unsigned long flags; + + local_irq_save(flags); + kvm_guest_cpu_init(); + local_irq_restore(flags); + return 0; +} + #ifdef CONFIG_SMP #define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG) @@ -464,7 +461,7 @@ } else if (apic_id < min && max - apic_id < KVM_IPI_CLUSTER_SIZE) { ipi_bitmap <<= min - apic_id; min = apic_id; - } else if (apic_id < min + KVM_IPI_CLUSTER_SIZE) { + } else if (apic_id > min && apic_id < min + KVM_IPI_CLUSTER_SIZE) { max = apic_id < max ? max : apic_id; } else { ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, @@ -547,31 +544,46 @@ kvm_spinlock_init(); } -static void kvm_guest_cpu_offline(void) +static int kvm_cpu_down_prepare(unsigned int cpu) { - kvm_disable_steal_time(); - if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) - wrmsrl(MSR_KVM_PV_EOI_EN, 0); - kvm_pv_disable_apf(); - apf_task_wake_all(); -} + unsigned long flags; -static int kvm_cpu_online(unsigned int cpu) -{ - local_irq_disable(); - kvm_guest_cpu_init(); - local_irq_enable(); + local_irq_save(flags); + kvm_guest_cpu_offline(false); + local_irq_restore(flags); return 0; } -static int kvm_cpu_down_prepare(unsigned int cpu) +#endif + +static int kvm_suspend(void) { - local_irq_disable(); - kvm_guest_cpu_offline(); - local_irq_enable(); + u64 val = 0; + + kvm_guest_cpu_offline(false); + +#ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL + if (kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL)) + rdmsrl(MSR_KVM_POLL_CONTROL, val); + has_guest_poll = !(val & 1); +#endif return 0; } + +static void kvm_resume(void) +{ + kvm_cpu_online(raw_smp_processor_id()); + +#ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL + if (kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL) && has_guest_poll) + wrmsrl(MSR_KVM_POLL_CONTROL, 0); #endif +} + +static struct syscore_ops kvm_syscore_ops = { + .suspend = kvm_suspend, + .resume = kvm_resume, +}; static void __init kvm_apf_trap_init(void) { @@ -606,6 +618,37 @@ native_flush_tlb_others(flushmask, info); } +static void kvm_pv_guest_cpu_reboot(void *unused) +{ + kvm_guest_cpu_offline(true); +} + +static int kvm_pv_reboot_notify(struct notifier_block *nb, + unsigned long code, void *unused) +{ + if (code == SYS_RESTART) + on_each_cpu(kvm_pv_guest_cpu_reboot, NULL, 1); + return NOTIFY_DONE; +} + +static struct notifier_block kvm_pv_reboot_nb = { + .notifier_call = kvm_pv_reboot_notify, +}; + +/* + * After a PV feature is registered, the host will keep writing to the + * registered memory location. If the guest happens to shutdown, this memory + * won't be valid. In cases like kexec, in which you install a new kernel, this + * means a random memory location will be kept being written. + */ +#ifdef CONFIG_KEXEC_CORE +static void kvm_crash_shutdown(struct pt_regs *regs) +{ + kvm_guest_cpu_offline(true); + native_machine_crash_shutdown(regs); +} +#endif + static void __init kvm_guest_init(void) { int i; @@ -649,6 +692,12 @@ kvm_guest_cpu_init(); #endif +#ifdef CONFIG_KEXEC_CORE + machine_ops.crash_shutdown = kvm_crash_shutdown; +#endif + + register_syscore_ops(&kvm_syscore_ops); + /* * Hard lockup detection is enabled by default. Disable it, as guests * can get false positives too easily, for example if the host is --- linux-oracle-5.4.0.orig/arch/x86/kernel/kvmclock.c +++ linux-oracle-5.4.0/arch/x86/kernel/kvmclock.c @@ -20,13 +20,12 @@ #include #include #include -#include #include static int kvmclock __initdata = 1; static int kvmclock_vsyscall __initdata = 1; -static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME; -static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK; +static int msr_kvm_system_time __ro_after_init; +static int msr_kvm_wall_clock __ro_after_init; static u64 kvm_sched_clock_offset __ro_after_init; static int __init parse_no_kvmclock(char *arg) @@ -51,18 +50,9 @@ static struct pvclock_vsyscall_time_info hv_clock_boot[HVC_BOOT_ARRAY_SIZE] __bss_decrypted __aligned(PAGE_SIZE); static struct pvclock_wall_clock wall_clock __bss_decrypted; -static DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu); static struct pvclock_vsyscall_time_info *hvclock_mem; - -static inline struct pvclock_vcpu_time_info *this_cpu_pvti(void) -{ - return &this_cpu_read(hv_clock_per_cpu)->pvti; -} - -static inline struct pvclock_vsyscall_time_info *this_cpu_hvclock(void) -{ - return this_cpu_read(hv_clock_per_cpu); -} +DEFINE_PER_CPU(struct pvclock_vsyscall_time_info *, hv_clock_per_cpu); +EXPORT_PER_CPU_SYMBOL_GPL(hv_clock_per_cpu); /* * The wallclock is the time of day when we booted. Since then, some time may @@ -197,28 +187,10 @@ } #endif -/* - * After the clock is registered, the host will keep writing to the - * registered memory location. If the guest happens to shutdown, this memory - * won't be valid. In cases like kexec, in which you install a new kernel, this - * means a random memory location will be kept being written. So before any - * kind of shutdown from our side, we unregister the clock by writing anything - * that does not have the 'enable' bit set in the msr - */ -#ifdef CONFIG_KEXEC_CORE -static void kvm_crash_shutdown(struct pt_regs *regs) -{ - native_write_msr(msr_kvm_system_time, 0, 0); - kvm_disable_steal_time(); - native_machine_crash_shutdown(regs); -} -#endif - -static void kvm_shutdown(void) +void kvmclock_disable(void) { - native_write_msr(msr_kvm_system_time, 0, 0); - kvm_disable_steal_time(); - native_machine_shutdown(); + if (msr_kvm_system_time) + native_write_msr(msr_kvm_system_time, 0, 0); } static void __init kvmclock_init_mem(void) @@ -315,7 +287,10 @@ if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; - } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { + } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { + msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; + msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; + } else { return; } @@ -346,10 +321,6 @@ #endif x86_platform.save_sched_clock_state = kvm_save_sched_clock_state; x86_platform.restore_sched_clock_state = kvm_restore_sched_clock_state; - machine_ops.shutdown = kvm_shutdown; -#ifdef CONFIG_KEXEC_CORE - machine_ops.crash_shutdown = kvm_crash_shutdown; -#endif kvm_get_preset_lpj(); /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/module.c +++ linux-oracle-5.4.0/arch/x86/kernel/module.c @@ -114,6 +114,7 @@ *location += sym->st_value; break; case R_386_PC32: + case R_386_PLT32: /* Add the value, subtract its position */ *location += sym->st_value - (uint32_t)location; break; --- linux-oracle-5.4.0.orig/arch/x86/kernel/nmi.c +++ linux-oracle-5.4.0/arch/x86/kernel/nmi.c @@ -104,18 +104,21 @@ } fs_initcall(nmi_warning_debugfs); -static void nmi_max_handler(struct irq_work *w) +static void nmi_check_duration(struct nmiaction *action, u64 duration) { - struct nmiaction *a = container_of(w, struct nmiaction, irq_work); int remainder_ns, decimal_msecs; - u64 whole_msecs = READ_ONCE(a->max_duration); - remainder_ns = do_div(whole_msecs, (1000 * 1000)); + if (duration < nmi_longest_ns || duration < action->max_duration) + return; + + action->max_duration = duration; + + remainder_ns = do_div(duration, (1000 * 1000)); decimal_msecs = remainder_ns / 1000; printk_ratelimited(KERN_INFO "INFO: NMI handler (%ps) took too long to run: %lld.%03d msecs\n", - a->handler, whole_msecs, decimal_msecs); + action->handler, duration, decimal_msecs); } static int nmi_handle(unsigned int type, struct pt_regs *regs) @@ -142,11 +145,7 @@ delta = sched_clock() - delta; trace_nmi_handler(a->handler, (int)delta, thishandled); - if (delta < nmi_longest_ns || delta < a->max_duration) - continue; - - a->max_duration = delta; - irq_work_queue(&a->irq_work); + nmi_check_duration(a, delta); } rcu_read_unlock(); @@ -164,8 +163,6 @@ if (!action->handler) return -EINVAL; - init_irq_work(&action->irq_work, nmi_max_handler); - raw_spin_lock_irqsave(&desc->lock, flags); /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/pmem.c +++ linux-oracle-5.4.0/arch/x86/kernel/pmem.c @@ -27,6 +27,11 @@ * simply here to trigger the module to load on demand. */ pdev = platform_device_alloc("e820_pmem", -1); - return platform_device_add(pdev); + + rc = platform_device_add(pdev); + if (rc) + platform_device_put(pdev); + + return rc; } device_initcall(register_e820_pmem); --- linux-oracle-5.4.0.orig/arch/x86/kernel/process.c +++ linux-oracle-5.4.0/arch/x86/kernel/process.c @@ -428,28 +428,20 @@ lockdep_assert_irqs_disabled(); - /* - * If TIF_SSBD is different, select the proper mitigation - * method. Note that if SSBD mitigation is disabled or permanentely - * enabled this branch can't be taken because nothing can set - * TIF_SSBD. - */ - if (tif_diff & _TIF_SSBD) { - if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + /* Handle change of TIF_SSBD depending on the mitigation method. */ + if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_ssb_virt_state(tifn); - } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + } else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) { + if (tif_diff & _TIF_SSBD) amd_set_core_ssb_state(tifn); - } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || - static_cpu_has(X86_FEATURE_AMD_SSBD)) { - msr |= ssbd_tif_to_spec_ctrl(tifn); - updmsr = true; - } + } else if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD) || + static_cpu_has(X86_FEATURE_AMD_SSBD)) { + updmsr |= !!(tif_diff & _TIF_SSBD); + msr |= ssbd_tif_to_spec_ctrl(tifn); } - /* - * Only evaluate TIF_SPEC_IB if conditional STIBP is enabled, - * otherwise avoid the MSR write. - */ + /* Only evaluate TIF_SPEC_IB if conditional STIBP is enabled. */ if (IS_ENABLED(CONFIG_SMP) && static_branch_unlikely(&switch_to_cond_stibp)) { updmsr |= !!(tif_diff & _TIF_SPEC_IB); @@ -457,7 +449,7 @@ } if (updmsr) - wrmsrl(MSR_IA32_SPEC_CTRL, msr); + update_spec_ctrl_cond(msr); } static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk) @@ -667,6 +659,10 @@ */ static int prefer_mwait_c1_over_halt(const struct cpuinfo_x86 *c) { + /* User has disallowed the use of MWAIT. Fallback to HALT */ + if (boot_option_idle_override == IDLE_NOMWAIT) + return 0; + if (c->x86_vendor != X86_VENDOR_INTEL) return 0; @@ -777,9 +773,8 @@ } else if (!strcmp(str, "nomwait")) { /* * If the boot option of "idle=nomwait" is added, - * it means that mwait will be disabled for CPU C2/C3 - * states. In such case it won't touch the variable - * of boot_option_idle_override. + * it means that mwait will be disabled for CPU C1/C2/C3 + * states. */ boot_option_idle_override = IDLE_NOMWAIT; } else @@ -798,7 +793,10 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) { - return randomize_page(mm->brk, 0x02000000); + if (mmap_is_ia32()) + return randomize_page(mm->brk, SZ_32M); + + return randomize_page(mm->brk, SZ_1G); } /* --- linux-oracle-5.4.0.orig/arch/x86/kernel/process_32.c +++ linux-oracle-5.4.0/arch/x86/kernel/process_32.c @@ -229,14 +229,12 @@ { struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; - struct fpu *prev_fpu = &prev->fpu; - struct fpu *next_fpu = &next->fpu; int cpu = smp_processor_id(); /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ if (!test_thread_flag(TIF_NEED_FPU_LOAD)) - switch_fpu_prepare(prev_fpu, cpu); + switch_fpu_prepare(prev_p, cpu); /* * Save away %gs. No need to save %fs, as it was saved on the @@ -292,10 +290,10 @@ this_cpu_write(current_task, next_p); - switch_fpu_finish(next_fpu); + switch_fpu_finish(next_p); /* Load the Intel cache allocation PQR MSR. */ - resctrl_sched_in(); + resctrl_sched_in(next_p); return prev_p; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/process_64.c +++ linux-oracle-5.4.0/arch/x86/kernel/process_64.c @@ -316,7 +316,7 @@ */ mutex_lock(&task->mm->context.lock); ldt = task->mm->context.ldt; - if (unlikely(idx >= ldt->nr_entries)) + if (unlikely(!ldt || idx >= ldt->nr_entries)) base = 0; else base = get_desc_base(ldt->entries + idx); @@ -505,15 +505,13 @@ { struct thread_struct *prev = &prev_p->thread; struct thread_struct *next = &next_p->thread; - struct fpu *prev_fpu = &prev->fpu; - struct fpu *next_fpu = &next->fpu; int cpu = smp_processor_id(); WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) && this_cpu_read(irq_count) != -1); if (!test_thread_flag(TIF_NEED_FPU_LOAD)) - switch_fpu_prepare(prev_fpu, cpu); + switch_fpu_prepare(prev_p, cpu); /* We must save %fs and %gs before load_TLS() because * %fs and %gs may be cleared by load_TLS(). @@ -565,7 +563,7 @@ this_cpu_write(current_task, next_p); this_cpu_write(cpu_current_top_of_stack, task_top_of_stack(next_p)); - switch_fpu_finish(next_fpu); + switch_fpu_finish(next_p); /* Reload sp0. */ update_task_stack(next_p); @@ -612,7 +610,7 @@ } /* Load the Intel cache allocation PQR MSR. */ - resctrl_sched_in(); + resctrl_sched_in(next_p); return prev_p; } --- linux-oracle-5.4.0.orig/arch/x86/kernel/quirks.c +++ linux-oracle-5.4.0/arch/x86/kernel/quirks.c @@ -95,7 +95,7 @@ static void ich_force_enable_hpet(struct pci_dev *dev) { u32 val; - u32 uninitialized_var(rcba); + u32 rcba; int err = 0; if (hpet_address || force_hpet_address) @@ -185,7 +185,7 @@ static void old_ich_force_hpet_resume(void) { u32 val; - u32 uninitialized_var(gen_cntl); + u32 gen_cntl; if (!force_hpet_address || !cached_dev) return; @@ -207,7 +207,7 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev) { u32 val; - u32 uninitialized_var(gen_cntl); + u32 gen_cntl; if (hpet_address || force_hpet_address) return; @@ -298,7 +298,7 @@ static void vt8237_force_enable_hpet(struct pci_dev *dev) { - u32 uninitialized_var(val); + u32 val; if (hpet_address || force_hpet_address) return; @@ -429,7 +429,7 @@ static void nvidia_force_enable_hpet(struct pci_dev *dev) { - u32 uninitialized_var(val); + u32 val; if (hpet_address || force_hpet_address) return; --- linux-oracle-5.4.0.orig/arch/x86/kernel/reboot.c +++ linux-oracle-5.4.0/arch/x86/kernel/reboot.c @@ -32,6 +32,7 @@ #include #include #include +#include /* * Power off function, if any @@ -113,25 +114,17 @@ spin_unlock(&rtc_lock); /* - * Switch back to the initial page table. + * Switch to the trampoline page table. */ -#ifdef CONFIG_X86_32 - load_cr3(initial_page_table); -#else - write_cr3(real_mode_header->trampoline_pgd); - - /* Exiting long mode will fail if CR4.PCIDE is set. */ - if (boot_cpu_has(X86_FEATURE_PCID)) - cr4_clear_bits(X86_CR4_PCIDE); -#endif + load_trampoline_pgtable(); /* Jump to the identity-mapped low memory code */ #ifdef CONFIG_X86_32 - asm volatile("jmpl *%0" : : + asm volatile(ANNOTATE_RETPOLINE_SAFE "jmpl *%0" : : "rm" (real_mode_header->machine_real_restart_asm), "a" (type)); #else - asm volatile("ljmpl *%0" : : + asm volatile(ANNOTATE_RETPOLINE_SAFE "ljmpl *%0" : : "m" (real_mode_header->machine_real_restart_asm), "D" (type)); #endif @@ -197,6 +190,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"), }, }, + { /* Handle problems with rebooting on Apple MacBook6,1 */ + .callback = set_pci_reboot, + .ident = "Apple MacBook6,1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"), + }, + }, { /* Handle problems with rebooting on Apple MacBookPro5 */ .callback = set_pci_reboot, .ident = "Apple MacBookPro5", @@ -380,10 +381,11 @@ }, { /* Handle problems with rebooting on the OptiPlex 990. */ .callback = set_pci_reboot, - .ident = "Dell OptiPlex 990", + .ident = "Dell OptiPlex 990 BIOS A0x", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), + DMI_MATCH(DMI_BIOS_VERSION, "A0"), }, }, { /* Handle problems with rebooting on Dell 300's */ @@ -469,6 +471,15 @@ }, }, + { /* PCIe Wifi card isn't detected after reboot otherwise */ + .callback = set_pci_reboot, + .ident = "Zotac ZBOX CI327 nano", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "NA"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZBOX-CI327NANO-GS-01"), + }, + }, + /* Sony */ { /* Handle problems with rebooting on Sony VGN-Z540N */ .callback = set_bios_reboot, @@ -478,7 +489,46 @@ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), }, }, - + { /* Handle problems with rebooting on the Latitude E6520. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6520", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6520"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 790. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 790", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 790"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 990. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 990", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), + }, + }, + { /* Handle problems with rebooting on the Latitude E6220. */ + .callback = set_pci_reboot, + .ident = "Dell Latitude E6220", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6220"), + }, + }, + { /* Handle problems with rebooting on the OptiPlex 390. */ + .callback = set_pci_reboot, + .ident = "Dell OptiPlex 390", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 390"), + }, + }, { } }; @@ -518,42 +568,29 @@ } } -static void vmxoff_nmi(int cpu, struct pt_regs *regs) -{ - cpu_emergency_vmxoff(); -} +static inline void nmi_shootdown_cpus_on_restart(void); -/* Use NMIs as IPIs to tell all CPUs to disable virtualization */ -static void emergency_vmx_disable_all(void) +static void emergency_reboot_disable_virtualization(void) { /* Just make sure we won't change CPUs while doing this */ local_irq_disable(); /* - * We need to disable VMX on all CPUs before rebooting, otherwise - * we risk hanging up the machine, because the CPU ignore INIT - * signals when VMX is enabled. + * Disable virtualization on all CPUs before rebooting to avoid hanging + * the system, as VMX and SVM block INIT when running in the host. * - * We can't take any locks and we may be on an inconsistent - * state, so we use NMIs as IPIs to tell the other CPUs to disable - * VMX and halt. + * We can't take any locks and we may be on an inconsistent state, so + * use NMIs as IPIs to tell the other CPUs to disable VMX/SVM and halt. * - * For safety, we will avoid running the nmi_shootdown_cpus() - * stuff unnecessarily, but we don't have a way to check - * if other CPUs have VMX enabled. So we will call it only if the - * CPU we are running on has VMX enabled. - * - * We will miss cases where VMX is not enabled on all CPUs. This - * shouldn't do much harm because KVM always enable VMX on all - * CPUs anyway. But we can miss it on the small window where KVM - * is still enabling VMX. - */ - if (cpu_has_vmx() && cpu_vmx_enabled()) { - /* Disable VMX on this CPU. */ - cpu_vmxoff(); + * Do the NMI shootdown even if virtualization is off on _this_ CPU, as + * other CPUs may have virtualization enabled. + */ + if (cpu_has_vmx() || cpu_has_svm(NULL)) { + /* Safely force _this_ CPU out of VMX/SVM operation. */ + cpu_emergency_disable_virtualization(); - /* Halt and disable VMX on the other CPUs */ - nmi_shootdown_cpus(vmxoff_nmi); + /* Disable VMX/SVM and halt on other CPUs. */ + nmi_shootdown_cpus_on_restart(); } } @@ -590,7 +627,7 @@ unsigned short mode; if (reboot_emergency) - emergency_vmx_disable_all(); + emergency_reboot_disable_virtualization(); tboot_shutdown(TB_SHUTDOWN_REBOOT); @@ -795,6 +832,17 @@ /* This is the CPU performing the emergency shutdown work. */ int crashing_cpu = -1; +/* + * Disable virtualization, i.e. VMX or SVM, to ensure INIT is recognized during + * reboot. VMX blocks INIT if the CPU is post-VMXON, and SVM blocks INIT if + * GIF=0, i.e. if the crash occurred between CLGI and STGI. + */ +void cpu_emergency_disable_virtualization(void) +{ + cpu_emergency_vmxoff(); + cpu_emergency_svm_disable(); +} + #if defined(CONFIG_SMP) static nmi_shootdown_cb shootdown_callback; @@ -817,7 +865,14 @@ return NMI_HANDLED; local_irq_disable(); - shootdown_callback(cpu, regs); + if (shootdown_callback) + shootdown_callback(cpu, regs); + + /* + * Prepare the CPU for reboot _after_ invoking the callback so that the + * callback can safely use virtualization instructions, e.g. VMCLEAR. + */ + cpu_emergency_disable_virtualization(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -828,18 +883,32 @@ return NMI_HANDLED; } -/* - * Halt all other CPUs, calling the specified function on each of them +/** + * nmi_shootdown_cpus - Stop other CPUs via NMI + * @callback: Optional callback to be invoked from the NMI handler + * + * The NMI handler on the remote CPUs invokes @callback, if not + * NULL, first and then disables virtualization to ensure that + * INIT is recognized during reboot. * - * This function can be used to halt all other CPUs on crash - * or emergency reboot time. The function passed as parameter - * will be called inside a NMI handler on all CPUs. + * nmi_shootdown_cpus() can only be invoked once. After the first + * invocation all other CPUs are stuck in crash_nmi_callback() and + * cannot respond to a second NMI. */ void nmi_shootdown_cpus(nmi_shootdown_cb callback) { unsigned long msecs; + local_irq_disable(); + /* + * Avoid certain doom if a shootdown already occurred; re-registering + * the NMI handler will cause list corruption, modifying the callback + * will do who knows what, etc... + */ + if (WARN_ON_ONCE(crash_ipi_issued)) + return; + /* Make a note of crashing cpu. Will be used in NMI callback. */ crashing_cpu = safe_smp_processor_id(); @@ -867,7 +936,17 @@ msecs--; } - /* Leave the nmi callback set */ + /* + * Leave the nmi callback set, shootdown is a one-time thing. Clearing + * the callback could result in a NULL pointer dereference if a CPU + * (finally) responds after the timeout expires. + */ +} + +static inline void nmi_shootdown_cpus_on_restart(void) +{ + if (!crash_ipi_issued) + nmi_shootdown_cpus(NULL); } /* @@ -897,6 +976,8 @@ /* No other CPUs to shoot down */ } +static inline void nmi_shootdown_cpus_on_restart(void) { } + void run_crash_ipi_callback(struct pt_regs *regs) { } --- linux-oracle-5.4.0.orig/arch/x86/kernel/relocate_kernel_32.S +++ linux-oracle-5.4.0/arch/x86/kernel/relocate_kernel_32.S @@ -8,6 +8,7 @@ #include #include #include +#include /* * Must be relocatable PIC code callable as a C function @@ -165,6 +166,7 @@ movl CP_PA_SWAP_PAGE(%edi), %esp addl $PAGE_SIZE, %esp 2: + ANNOTATE_RETPOLINE_SAFE call *%edx /* get the re-entry point of the peer system */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/relocate_kernel_64.S +++ linux-oracle-5.4.0/arch/x86/kernel/relocate_kernel_64.S @@ -9,6 +9,7 @@ #include #include #include +#include /* * Must be relocatable PIC code callable as a C function @@ -192,6 +193,7 @@ 1: popq %rdx leaq PAGE_SIZE(%r10), %rsp + ANNOTATE_RETPOLINE_SAFE call *%rdx /* get the re-entry point of the peer system */ --- linux-oracle-5.4.0.orig/arch/x86/kernel/setup.c +++ linux-oracle-5.4.0/arch/x86/kernel/setup.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include

' + - RDMA/bnxt_re: Fix missing le16_to_cpu + - RDMA/bnxt_re: Fix stat push into dma buffer on gen p5 devices + - bpf: Provide better register bounds after jmp32 instructions + - RDMA/bnxt_re: Fix chip number validation Broadcom's Gen P5 series + - ibmvnic: Fix completion structure initialization + - net: wireless: intel: iwlwifi: fix GRO_NORMAL packet stalling + - MIPS: futex: Restore \n after sync instructions + - btrfs: don't prematurely free work in reada_start_machine_worker() + - btrfs: don't prematurely free work in scrub_missing_raid56_worker() + - Revert "mmc: sdhci: Fix incorrect switch to HS mode" + - mmc: mediatek: fix CMD_TA to 2 for MT8173 HS200/HS400 mode + - tpm_tis: reserve chip for duration of tpm_tis_core_init + - tpm: fix invalid locking in NONBLOCKING mode + - iommu: fix KASAN use-after-free in iommu_insert_resv_region + - iommu: set group default domain before creating direct mappings + - iommu/vt-d: Fix dmar pte read access not set error + - iommu/vt-d: Set ISA bridge reserved region as relaxable + - iommu/vt-d: Allocate reserved region for ISA with correct permission + - can: xilinx_can: Fix missing Rx can packets on CANFD2.0 + - can: m_can: tcan4x5x: add required delay after reset + - can: j1939: j1939_sk_bind(): take priv after lock is held + - can: flexcan: fix possible deadlock and out-of-order reception after wakeup + - can: flexcan: poll MCR_LPM_ACK instead of GPR ACK for stop mode + acknowledgment + - can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices + - spi: dw: Correct handling of native chipselect + - spi: cadence: Correct handling of native chipselect + - usb: xhci: Fix build warning seen with CONFIG_PM=n + - drm/amdgpu: fix uninitialized variable pasid_mapping_needed + - ath10k: Revert "ath10k: add cleanup in ath10k_sta_state()" + - RDMA/siw: Fix post_recv QP state locking + - md: avoid invalid memory access for array sb->dev_roles + - s390/ftrace: fix endless recursion in function_graph tracer + - ARM: dts: Fix vcsi regulator to be always-on for droid4 to prevent hangs + - can: flexcan: add low power enter/exit acknowledgment helper + - usbip: Fix receive error in vhci-hcd when using scatter-gather + - usbip: Fix error path of vhci_recv_ret_submit() + - spi: fsl: don't map irq during probe + - spi: fsl: use platform_get_irq() instead of of_irq_to_resource() + - efi/memreserve: Register reservations as 'reserved' in /proc/iomem + - cpufreq: Avoid leaving stale IRQ work items during CPU offline + - KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails + - mm: vmscan: protect shrinker idr replace with CONFIG_MEMCG + - USB: EHCI: Do not return -EPIPE when hub is disconnected + - intel_th: pci: Add Comet Lake PCH-V support + - intel_th: pci: Add Elkhart Lake SOC support + - intel_th: Fix freeing IRQs + - intel_th: msu: Fix window switching without windows + - platform/x86: hp-wmi: Make buffer for HPWMI_FEATURE2_QUERY 128 bytes + - staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value + - tty/serial: atmel: fix out of range clock divider handling + - serial: sprd: Add clearing break interrupt operation + - pinctrl: baytrail: Really serialize all register accesses + - clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table + - clk: imx: clk-composite-8m: add lock to gate/mux + - clk: imx: pll14xx: fix clk_pll14xx_wait_lock + - ext4: fix ext4_empty_dir() for directories with holes + - ext4: check for directory entries too close to block end + - ext4: unlock on error in ext4_expand_extra_isize() + - ext4: validate the debug_want_extra_isize mount option at parse time + - iocost: over-budget forced IOs should schedule async delay + - KVM: PPC: Book3S HV: Fix regression on big endian hosts + - kvm: x86: Host feature SSBD doesn't imply guest feature SPEC_CTRL_SSBD + - kvm: x86: Host feature SSBD doesn't imply guest feature AMD_SSBD + - KVM: arm/arm64: Properly handle faulting of device mappings + - KVM: arm64: Ensure 'params' is initialised when looking up sys register + - x86/MCE/AMD: Do not use rdmsr_safe_on_cpu() in smca_configure() + - x86/MCE/AMD: Allow Reserved types to be overwritten in smca_banks[] + - x86/mce: Fix possibly incorrect severity calculation on AMD + - powerpc/vcpu: Assume dedicated processors as non-preempt + - powerpc/irq: fix stack overflow verification + - ocxl: Fix concurrent AFU open and device removal + - mmc: sdhci-msm: Correct the offset and value for DDR_CONFIG register + - mmc: sdhci-of-esdhc: Revert "mmc: sdhci-of-esdhc: add erratum A-009204 + support" + - mmc: sdhci: Update the tuning failed messages to pr_debug level + - mmc: sdhci-of-esdhc: fix P2020 errata handling + - mmc: sdhci: Workaround broken command queuing on Intel GLK + - mmc: sdhci: Add a quirk for broken command queuing + - nbd: fix shutdown and recv work deadlock v2 + - iwlwifi: pcie: move power gating workaround earlier in the flow + - Linux 5.4.7 + + * Focal update: v5.4.6 upstream stable release (LP: #1858427) + - Revert "UBUNTU: SAUCE: drm/i915/fbc: disable framebuffer compression on + IceLake" + - USB: Fix incorrect DMA allocations for local memory pool drivers + - mmc: block: Make card_busy_detect() a bit more generic + - mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response + - mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() + - mmc: core: Re-work HW reset for SDIO cards + - PCI/switchtec: Read all 64 bits of part_event_bitmap + - PCI/PM: Always return devices to D0 when thawing + - PCI: pciehp: Avoid returning prematurely from sysfs requests + - PCI: Fix Intel ACS quirk UPDCR register address + - PCI/MSI: Fix incorrect MSI-X masking on resume + - PCI: Do not use bus number zero from EA capability + - PCI: rcar: Fix missing MACCTLR register setting in initialization sequence + - PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3 + - PM / QoS: Redefine FREQ_QOS_MAX_DEFAULT_VALUE to S32_MAX + - block: fix "check bi_size overflow before merge" + - xtensa: use MEMBLOCK_ALLOC_ANYWHERE for KASAN shadow map + - gfs2: Multi-block allocations in gfs2_page_mkwrite + - gfs2: fix glock reference problem in gfs2_trans_remove_revoke + - xtensa: fix TLB sanity checker + - xtensa: fix syscall_set_return_value + - rpmsg: glink: Set tail pointer to 0 at end of FIFO + - rpmsg: glink: Fix reuse intents memory leak issue + - rpmsg: glink: Fix use after free in open_ack TIMEOUT case + - rpmsg: glink: Put an extra reference during cleanup + - rpmsg: glink: Fix rpmsg_register_device err handling + - rpmsg: glink: Don't send pending rx_done during remove + - rpmsg: glink: Free pending deferred work on remove + - cifs: smbd: Return -EAGAIN when transport is reconnecting + - cifs: smbd: Only queue work for error recovery on memory registration + - cifs: smbd: Add messages on RDMA session destroy and reconnection + - cifs: smbd: Return -EINVAL when the number of iovs exceeds SMBDIRECT_MAX_SGE + - cifs: smbd: Return -ECONNABORTED when trasnport is not in connected state + - cifs: Don't display RDMA transport on reconnect + - CIFS: Respect O_SYNC and O_DIRECT flags during reconnect + - CIFS: Close open handle after interrupted close + - CIFS: Do not miss cancelled OPEN responses + - CIFS: Fix NULL pointer dereference in mid callback + - ARM: dts: s3c64xx: Fix init order of clock providers + - ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume() + - vfio/pci: call irq_bypass_unregister_producer() before freeing irq + - dma-buf: Fix memory leak in sync_file_merge() + - drm/panfrost: Fix a race in panfrost_ioctl_madvise() + - drm/panfrost: Fix a BO leak in panfrost_ioctl_mmap_bo() + - drm/panfrost: Fix a race in panfrost_gem_free_object() + - drm/mgag200: Extract device type from flags + - drm/mgag200: Store flags from PCI driver data in device structure + - drm/mgag200: Add workaround for HW that does not support 'startadd' + - drm/mgag200: Flag all G200 SE A machines as broken wrt + - drm: meson: venc: cvbs: fix CVBS mode matching + - dm mpath: remove harmful bio-based optimization + - dm btree: increase rebalance threshold in __rebalance2() + - dm clone metadata: Track exact changes per transaction + - dm clone metadata: Use a two phase commit + - dm clone: Flush destination device before committing metadata + - dm thin metadata: Add support for a pre-commit callback + - dm thin: Flush data device before committing metadata + - scsi: ufs: Disable autohibern8 feature in Cadence UFS + - scsi: iscsi: Fix a potential deadlock in the timeout handler + - scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd + - scsi: qla2xxx: Initialize free_work before flushing it + - scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX + - scsi: qla2xxx: Change discovery state before PLOGI + - scsi: qla2xxx: Correctly retrieve and interpret active flash region + - scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd + - drm/nouveau/kms/nv50-: Call outp_atomic_check_view() before handling PBN + - drm/nouveau/kms/nv50-: Store the bpc we're using in nv50_head_atom + - drm/nouveau/kms/nv50-: Limit MST BPC to 8 + - drm/i915/fbc: Disable fbc by default on all glk+ + - drm/radeon: fix r1xx/r2xx register checker for POT textures + - drm/dp_mst: Correct the bug in drm_dp_update_payload_part1() + - drm/amd/display: re-enable wait in pipelock, but add timeout + - drm/amd/display: add default clocks if not able to fetch them + - drm/amdgpu: initialize vm_inv_eng0_sem for gfxhub and mmhub + - drm/amdgpu: invalidate mmhub semaphore workaround in gmc9/gmc10 + - drm/amdgpu/gfx10: explicitly wait for cp idle after halt/unhalt + - drm/amdgpu/gfx10: re-init clear state buffer after gpu reset + - drm/i915/gvt: Fix cmd length check for MI_ATOMIC + - drm/amdgpu: avoid using invalidate semaphore for picasso + - drm/amdgpu: add invalidate semaphore limit for SRIOV and picasso in gmc9 + - ALSA: hda: Fix regression by strip mask fix + - Linux 5.4.6 + + * Focal update: v5.4.5 upstream stable release (LP: #1858426) + - inet: protect against too small mtu values. + - mqprio: Fix out-of-bounds access in mqprio_dump + - net: bridge: deny dev_set_mac_address() when unregistering + - net: dsa: fix flow dissection on Tx path + - net: ethernet: ti: cpsw: fix extra rx interrupt + - net: sched: fix dump qlen for sch_mq/sch_mqprio with NOLOCK subqueues + - net_sched: validate TCA_KIND attribute in tc_chain_tmplt_add() + - net: thunderx: start phy before starting autonegotiation + - net/tls: Fix return values to avoid ENOTSUPP + - openvswitch: support asymmetric conntrack + - tcp: md5: fix potential overestimation of TCP option space + - tipc: fix ordering of tipc module init and exit routine + - net/mlx5e: Query global pause state before setting prio2buffer + - net: ipv6: add net argument to ip6_dst_lookup_flow + - net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup + - tcp: fix rejected syncookies due to stale timestamps + - tcp: tighten acceptance of ACKs not matching a child socket + - tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE() + - net: core: rename indirect block ingress cb function + - net: sched: allow indirect blocks to bind to clsact in TC + - cls_flower: Fix the behavior using port ranges with hw-offload + - gre: refetch erspan header from skb->data after pskb_may_pull() + - Fixed updating of ethertype in function skb_mpls_pop + - hsr: fix a NULL pointer dereference in hsr_dev_xmit() + - net: Fixed updating of ethertype in skb_mpls_push() + - net/mlx5e: Fix TXQ indices to be sequential + - act_ct: support asymmetric conntrack + - net/mlx5e: Fix SFF 8472 eeprom length + - net/mlx5e: Fix freeing flow with kfree() and not kvfree() + - net/mlx5e: Fix translation of link mode into speed + - net/mlx5e: ethtool, Fix analysis of speed setting + - page_pool: do not release pool until inflight == 0. + - xdp: obtain the mem_id mutex before trying to remove an entry. + - ionic: keep users rss hash across lif reset + - net: mscc: ocelot: unregister the PTP clock on deinit + - r8169: add missing RX enabling for WoL on RTL8125 + - Linux 5.4.5 + + * Focal update: v5.4.4 upstream stable release (LP: #1858424) + - usb: gadget: configfs: Fix missing spin_lock_init() + - usb: gadget: pch_udc: fix use after free + - nvme: Namepace identification descriptor list is optional + - Revert "nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T" + - scsi: lpfc: Fix bad ndlp ptr in xri aborted handling + - scsi: zfcp: trace channel log even for FCP command responses + - scsi: qla2xxx: Do command completion on abort timeout + - scsi: qla2xxx: Fix driver unload hang + - scsi: qla2xxx: Fix double scsi_done for abort path + - scsi: qla2xxx: Fix memory leak when sending I/O fails + - compat_ioctl: add compat_ptr_ioctl() + - ceph: fix compat_ioctl for ceph_dir_operations + - media: venus: remove invalid compat_ioctl32 handler + - USB: uas: honor flag to avoid CAPACITY16 + - USB: uas: heed CAPACITY_HEURISTICS + - USB: documentation: flags on usb-storage versus UAS + - usb: Allow USB device to be warm reset in suspended state + - usb: host: xhci-tegra: Correct phy enable sequence + - binder: fix incorrect calculation for num_valid + - staging: exfat: fix multiple definition error of `rename_file' + - staging: rtl8188eu: fix interface sanity check + - staging: rtl8712: fix interface sanity check + - staging: vchiq: call unregister_chrdev_region() when driver registration + fails + - staging: gigaset: fix general protection fault on probe + - staging: gigaset: fix illegal free on probe errors + - staging: gigaset: add endpoint-type sanity check + - usb: xhci: only set D3hot for pci device + - xhci: Fix memory leak in xhci_add_in_port() + - xhci: fix USB3 device initiated resume race with roothub autosuspend + - xhci: Increase STS_HALT timeout in xhci_suspend() + - xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default behaviour. + - xhci: make sure interrupts are restored to correct state + - interconnect: qcom: sdm845: Walk the list safely on node removal + - interconnect: qcom: qcs404: Walk the list safely on node removal + - usb: common: usb-conn-gpio: Don't log an error on probe deferral + - ARM: dts: pandora-common: define wl1251 as child node of mmc3 + - iio: adis16480: Add debugfs_reg_access entry + - iio: imu: st_lsm6dsx: fix ODR check in st_lsm6dsx_write_raw + - iio: adis16480: Fix scales factors + - iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting + - iio: imu: inv_mpu6050: fix temperature reporting using bad unit + - iio: adc: ad7606: fix reading unnecessary data from device + - iio: adc: ad7124: Enable internal reference + - USB: atm: ueagle-atm: add missing endpoint check + - USB: idmouse: fix interface sanity checks + - USB: serial: io_edgeport: fix epic endpoint lookup + - usb: roles: fix a potential use after free + - USB: adutux: fix interface sanity check + - usb: core: urb: fix URB structure initialization function + - usb: mon: Fix a deadlock in usbmon between mmap and read + - tpm: add check after commands attribs tab allocation + - tpm: Switch to platform_get_irq_optional() + - EDAC/altera: Use fast register IO for S10 IRQs + - brcmfmac: disable PCIe interrupts before bus reset + - mtd: spear_smi: Fix Write Burst mode + - mtd: rawnand: Change calculating of position page containing BBM + - virt_wifi: fix use-after-free in virt_wifi_newlink() + - virtio-balloon: fix managed page counts when migrating pages between zones + - usb: dwc3: pci: add ID for the Intel Comet Lake -H variant + - usb: dwc3: gadget: Fix logical condition + - usb: dwc3: gadget: Clear started flag for non-IOC + - usb: dwc3: ep0: Clear started flag on completion + - phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role" + - usb: typec: fix use after free in typec_register_port() + - iwlwifi: pcie: fix support for transmitting SKBs with fraglist + - btrfs: check page->mapping when loading free space cache + - btrfs: use btrfs_block_group_cache_done in update_block_group + - btrfs: use refcount_inc_not_zero in kill_all_nodes + - Btrfs: fix metadata space leak on fixup worker failure to set range as + delalloc + - Btrfs: fix negative subv_writers counter and data space leak after buffered + write + - btrfs: Avoid getting stuck during cyclic writebacks + - btrfs: Remove btrfs_bio::flags member + - Btrfs: send, skip backreference walking for extents with many references + - btrfs: record all roots for rename exchange on a subvol + - rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address + - rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer + - rtlwifi: rtl8192de: Fix missing enable interrupt flag + - lib: raid6: fix awk build warnings + - ovl: fix corner case of non-unique st_dev;st_ino + - ovl: relax WARN_ON() on rename to self + - hwrng: omap - Fix RNG wait loop timeout + - dm writecache: handle REQ_FUA + - dm zoned: reduce overhead of backing device checks + - workqueue: Fix spurious sanity check failures in destroy_workqueue() + - workqueue: Fix pwq ref leak in rescuer_thread() + - ASoC: rt5645: Fixed buddy jack support. + - ASoC: rt5645: Fixed typo for buddy jack support. + - ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report + - ASoC: fsl_audmix: Add spin lock to protect tdms + - md: improve handling of bio with REQ_PREFLUSH in md_flush_request() + - blk-mq: avoid sysfs buffer overflow with too many CPU cores + - cgroup: pids: use atomic64_t for pids->limit + - wil6210: check len before memcpy() calls + - ar5523: check NULL before memcpy() in ar5523_cmd() + - s390/mm: properly clear _PAGE_NOEXEC bit when it is not supported + - media: hantro: Fix s_fmt for dynamic resolution changes + - media: hantro: Fix motion vectors usage condition + - media: hantro: Fix picture order count table enable + - media: vimc: sen: remove unused kthread_sen field + - media: bdisp: fix memleak on release + - media: radio: wl1273: fix interrupt masking on release + - media: cec.h: CEC_OP_REC_FLAG_ values were swapped + - cpuidle: Do not unset the driver if it is there already + - cpuidle: teo: Ignore disabled idle states that are too deep + - cpuidle: teo: Rename local variable in teo_select() + - cpuidle: teo: Consider hits and misses metrics of disabled states + - cpuidle: teo: Fix "early hits" handling for disabled idle states + - cpuidle: use first valid target residency as poll time + - erofs: zero out when listxattr is called with no xattr + - perf tests: Fix out of bounds memory access + - drm/panfrost: Open/close the perfcnt BO + - powerpc/perf: Disable trace_imc pmu + - intel_th: Fix a double put_device() in error path + - intel_th: pci: Add Ice Lake CPU support + - intel_th: pci: Add Tiger Lake CPU support + - PM / devfreq: Lock devfreq in trans_stat_show + - cpufreq: powernv: fix stack bloat and hard limit on number of CPUs + - ALSA: fireface: fix return value in error path of isochronous resources + reservation + - ALSA: oxfw: fix return value in error path of isochronous resources + reservation + - ACPI / utils: Move acpi_dev_get_first_match_dev() under CONFIG_ACPI + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C7 to lpss_device_links + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C1 to lpss_device_links + - ACPI: LPSS: Add dmi quirk for skipping _DEP check for some device-links + - ACPI / hotplug / PCI: Allocate resources directly under the non-hotplug + bridge + - ACPI: OSL: only free map once in osl.c + - ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data() + - ACPI: EC: Rework flushing of pending work + - ACPI: PM: Avoid attaching ACPI PM domain to certain devices + - pinctrl: rza2: Fix gpio name typos + - pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type() + - pinctrl: samsung: Add of_node_put() before return in error path + - pinctrl: samsung: Fix device node refcount leaks in Exynos wakeup controller + init + - pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup + controller init + - pinctrl: samsung: Fix device node refcount leaks in init code + - pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup + controller init + - mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of + pandora_wl1251_init_card + - ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity + - RDMA/core: Fix ib_dma_max_seg_size() + - ppdev: fix PPGETTIME/PPSETTIME ioctls + - stm class: Lose the protocol driver when dropping its reference + - coresight: Serialize enabling/disabling a link device. + - powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB + - powerpc/xive: Prevent page fault issues in the machine crash handler + - powerpc: Allow flush_icache_range to work across ranges >4GB + - powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts + - video/hdmi: Fix AVI bar unpack + - quota: Check that quota is not dirty before release + - ext2: check err when partial != NULL + - quota: fix livelock in dquot_writeback_dquots + - ext4: Fix credit estimate for final inode freeing + - reiserfs: fix extended attributes on the root directory + - scsi: qla2xxx: Fix SRB leak on switch command timeout + - scsi: qla2xxx: Fix a dma_pool_free() call + - Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails" + - iio: ad7949: kill pointless "readback"-handling code + - iio: ad7949: fix channels mixups + - omap: pdata-quirks: revert pandora specific gpiod additions + - omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251 + - powerpc: Avoid clang warnings around setjmp and longjmp + - powerpc: Fix vDSO clock_getres() + - mm, memfd: fix COW issue on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings + - mm: memcg/slab: wait for !root kmem_cache refcnt killing on root kmem_cache + destruction + - ext4: work around deleting a file with i_nlink == 0 safely + - firmware: qcom: scm: Ensure 'a0' status code is treated as signed + - s390/smp,vdso: fix ASCE handling + - s390/kaslr: store KASLR offset for early dumps + - mm/shmem.c: cast the type of unmap_start to u64 + - powerpc: Define arch_is_kernel_initmem_freed() for lockdep + - USB: dummy-hcd: increase max number of devices to 32 + - rtc: disable uie before setting time and enable after + - splice: only read in as much information as there is pipe buffer space + - ext4: fix a bug in ext4_wait_for_tail_page_commit + - ext4: fix leak of quota reservations + - blk-mq: make sure that line break can be printed + - workqueue: Fix missing kfree(rescuer) in destroy_workqueue() + - r8169: fix rtl_hw_jumbo_disable for RTL8168evl + - EDAC/ghes: Do not warn when incrementing refcount on 0 + - Linux 5.4.4 + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] Change source package to linux-5.4 + - [Packaging] Don't use SRCPKGNAME for linux-libc-dev + - [Packaging] Remove linux-source-3 Provides: from linux-source + - [Packaging] Fix linux-doc in linux-image Suggests: + - [Debian] Read variants list into a variable + - [Packaging] Generate linux-libc-dev package only for primary variant + - [Packaging] Generate linux-doc for only the primary variant + - [Debian] Update linux source package name in debian/tests/* + - [Config] update annotations to match config changes + - [Config] disable PCI_MESON + - SAUCE: tools: hv: Update shebang to use python3 instead of python + - update dkms package versions + + -- Seth Forshee Wed, 08 Jan 2020 15:00:54 -0600 + +linux-5.4 (5.4.0-9.12) focal; urgency=medium + + * Empty entry. + + -- Seth Forshee Tue, 17 Dec 2019 07:09:13 -0600 + +linux (5.4.0-9.12) focal; urgency=medium + + * alsa/hda/realtek: the line-out jack doens't work on a dell AIO + (LP: #1855999) + - SAUCE: ALSA: hda/realtek - Line-out jack doesn't work on a Dell AIO + + * scsi: hisi_sas: Check sas_port before using it (LP: #1855952) + - scsi: hisi_sas: Check sas_port before using it + + * CVE-2019-19078 + - ath10k: fix memory leak + + * cifs: DFS Caching feature causing problems traversing multi-tier DFS setups + (LP: #1854887) + - cifs: Fix retrieval of DFS referrals in cifs_mount() + + * Support DPCD aux brightness control (LP: #1856134) + - SAUCE: drm/i915: Fix eDP DPCD aux max backlight calculations + - SAUCE: drm/i915: Assume 100% brightness when not in DPCD control mode + - SAUCE: drm/i915: Fix DPCD register order in intel_dp_aux_enable_backlight() + - SAUCE: drm/i915: Auto detect DPCD backlight support by default + - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED + panel + - USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision 4K sku + + * The system cannot resume from S3 if user unplugs the TB16 during suspend + state (LP: #1849269) + - PCI: pciehp: Do not disable interrupt twice on suspend + - PCI: pciehp: Prevent deadlock on disconnect + + * change kconfig of the soundwire bus driver from y to m (LP: #1855685) + - [Config]: SOUNDWIRE=m + + * alsa/sof: change to use hda hdmi codec driver to make hdmi audio on the + docking station work (LP: #1855666) + - ALSA: hda/hdmi - implement mst_no_extra_pcms flag + - ASoC: hdac_hda: add support for HDMI/DP as a HDA codec + - ASoC: Intel: skl-hda-dsp-generic: use snd-hda-codec-hdmi + - ASoC: Intel: skl-hda-dsp-generic: fix include guard name + - ASoC: SOF: Intel: add support for snd-hda-codec-hdmi + - ASoC: Intel: bxt-da7219-max98357a: common hdmi codec support + - ASoC: Intel: glk_rt5682_max98357a: common hdmi codec support + - ASoC: intel: sof_rt5682: common hdmi codec support + - ASoC: Intel: bxt_rt298: common hdmi codec support + - ASoC: SOF: enable sync_write in hdac_bus + - [config]: SND_SOC_SOF_HDA_COMMON_HDMI_CODEC=y + + * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312) + - SAUCE: USB: core: Make port power cycle a seperate helper function + - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state + + * Focal update: v5.4.3 upstream stable release (LP: #1856583) + - rsi: release skb if rsi_prepare_beacon fails + - arm64: tegra: Fix 'active-low' warning for Jetson TX1 regulator + - arm64: tegra: Fix 'active-low' warning for Jetson Xavier regulator + - perf scripts python: exported-sql-viewer.py: Fix use of TRUE with SQLite + - sparc64: implement ioremap_uc + - lp: fix sparc64 LPSETTIMEOUT ioctl + - time: Zero the upper 32-bits in __kernel_timespec on 32-bit + - mailbox: tegra: Fix superfluous IRQ error message + - staging/octeon: Use stubs for MIPS && !CAVIUM_OCTEON_SOC + - usb: gadget: u_serial: add missing port entry locking + - serial: 8250-mtk: Use platform_get_irq_optional() for optional irq + - tty: serial: fsl_lpuart: use the sg count from dma_map_sg + - tty: serial: msm_serial: Fix flow control + - serial: pl011: Fix DMA ->flush_buffer() + - serial: serial_core: Perform NULL checks for break_ctl ops + - serial: stm32: fix clearing interrupt error flags + - serial: 8250_dw: Avoid double error messaging when IRQ absent + - serial: ifx6x60: add missed pm_runtime_disable + - mwifiex: Re-work support for SDIO HW reset + - io_uring: fix dead-hung for non-iter fixed rw + - io_uring: transform send/recvmsg() -ERESTARTSYS to -EINTR + - fuse: fix leak of fuse_io_priv + - fuse: verify nlink + - fuse: verify write return + - fuse: verify attributes + - io_uring: fix missing kmap() declaration on powerpc + - io_uring: ensure req->submit is copied when req is deferred + - SUNRPC: Avoid RPC delays when exiting suspend + - ALSA: hda/realtek - Enable internal speaker of ASUS UX431FLC + - ALSA: hda/realtek - Fix inverted bass GPIO pin on Acer 8951G + - ALSA: pcm: oss: Avoid potential buffer overflows + - ALSA: hda - Add mute led support for HP ProBook 645 G4 + - ALSA: hda: Modify stream stripe mask only when needed + - soc: mediatek: cmdq: fixup wrong input order of write api + - Input: synaptics - switch another X1 Carbon 6 to RMI/SMbus + - Input: synaptics-rmi4 - re-enable IRQs in f34v7_do_reflash + - Input: synaptics-rmi4 - don't increment rmiaddr for SMBus transfers + - Input: goodix - add upside-down quirk for Teclast X89 tablet + - coresight: etm4x: Fix input validation for sysfs. + - Input: Fix memory leak in psxpad_spi_probe + - media: rc: mark input device as pointing stick + - x86/mm/32: Sync only to VMALLOC_END in vmalloc_sync_all() + - CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks + - CIFS: Fix SMB2 oplock break processing + - tty: vt: keyboard: reject invalid keycodes + - can: slcan: Fix use-after-free Read in slcan_open + - nfsd: Ensure CLONE persists data and metadata changes to the target file + - nfsd: restore NFSv3 ACL support + - kernfs: fix ino wrap-around detection + - jbd2: Fix possible overflow in jbd2_log_space_left() + - drm/msm: fix memleak on release + - drm: damage_helper: Fix race checking plane->state->fb + - drm/i810: Prevent underflow in ioctl + - arm64: Validate tagged addresses in access_ok() called from kernel threads + - arm64: dts: exynos: Revert "Remove unneeded address space mapping for soc + node" + - KVM: PPC: Book3S HV: XIVE: Free previous EQ page when setting up a new one + - KVM: PPC: Book3S HV: XIVE: Fix potential page leak on error path + - KVM: PPC: Book3S HV: XIVE: Set kvm->arch.xive when VPs are allocated + - KVM: nVMX: Always write vmcs02.GUEST_CR3 during nested VM-Enter + - KVM: arm/arm64: vgic: Don't rely on the wrong pending table + - KVM: x86: do not modify masked bits of shared MSRs + - KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES + - KVM: x86: Remove a spurious export of a static function + - KVM: x86: Grab KVM's srcu lock when setting nested state + - crypto: crypto4xx - fix double-free in crypto4xx_destroy_sdr + - crypto: atmel-aes - Fix IV handling when req->nbytes < ivsize + - crypto: af_alg - cast ki_complete ternary op to int + - crypto: geode-aes - switch to skcipher for cbc(aes) fallback + - crypto: ccp - fix uninitialized list head + - crypto: ecdh - fix big endian bug in ECC library + - crypto: user - fix memory leak in crypto_report + - spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register + - spi: stm32-qspi: Fix kernel oops when unbinding driver + - spi: atmel: Fix CS high support + - spi: Fix SPI_CS_HIGH setting when using native and GPIO CS + - spi: Fix NULL pointer when setting SPI_CS_HIGH for GPIO CS + - can: ucan: fix non-atomic allocation in completion handler + - RDMA/qib: Validate ->show()/store() callbacks before calling them + - rfkill: allocate static minor + - bdev: Factor out bdev revalidation into a common helper + - bdev: Refresh bdev size for disks without partitioning + - iomap: Fix pipe page leakage during splicing + - thermal: Fix deadlock in thermal thermal_zone_device_check + - vcs: prevent write access to vcsu devices + - Revert "serial/8250: Add support for NI-Serial PXI/PXIe+485 devices" + - binder: Fix race between mmap() and binder_alloc_print_pages() + - binder: Prevent repeated use of ->mmap() via NULL mapping + - binder: Handle start==NULL in binder_update_page_range() + - KVM: x86: fix out-of-bounds write in KVM_GET_EMULATED_CPUID (CVE-2019-19332) + - ALSA: hda - Fix pending unsol events at shutdown + - cpufreq: imx-cpufreq-dt: Correct i.MX8MN's default speed grade value + - md/raid0: Fix an error message in raid0_make_request() + - drm/mcde: Fix an error handling path in 'mcde_probe()' + - watchdog: aspeed: Fix clock behaviour for ast2600 + - EDAC/ghes: Fix locking and memory barrier issues + - perf script: Fix invalid LBR/binary mismatch error + - kselftest: Fix NULL INSTALL_PATH for TARGETS runlist + - Linux 5.4.3 + + * Realtek ALC256M with DTS Audio Processing internal microphone doesn't work + on Redmi Book 14 2019 (LP: #1846148) // Focal update: v5.4.3 upstream stable + release (LP: #1856583) + - ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop + + * Miscellaneous Ubuntu changes + - [Debian] add python depends to ubuntu-regression-suite + - SAUCE: selftests: net: tls: remove recv_rcvbuf test + - update dkms package versions + + -- Seth Forshee Mon, 16 Dec 2019 14:54:19 -0600 + +linux (5.4.0-8.11) focal; urgency=medium + + * focal/linux: 5.4.0-8.9 -proposed tracker (LP: #1855448) + + * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180) + - SAUCE: net: ena: fix issues in setting interrupt moderation params in + ethtool + - SAUCE: net: ena: fix too long default tx interrupt moderation interval + + * Kernel build log filled with "/bin/bash: line 5: warning: command + substitution: ignored null byte in input" (LP: #1853843) + - [Debian] Fix warnings when checking for modules signatures + + * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO + (LP: #1852581) + - [Packaging] Fix module signing with older modinfo + + * Fix MST support on Ice Lake (LP: #1854432) + - drm/i915: fix port checks for MST support on gen >= 11 + + * headphone has noise as not mute on dell machines with alc236/256 + (LP: #1854401) + - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236 + + * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2 + (LP: #1847450) + - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support + to intel_pmc_core driver + + * CVE-2019-14901 + - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() + + * CVE-2019-14896 // CVE-2019-14897 + - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor + + * CVE-2019-14895 + - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie() + + * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2 + (LP: #1847454) + - powercap/intel_rapl: add support for CometLake Mobile + - powercap/intel_rapl: add support for Cometlake desktop + + * External microphone can't work on some dell machines with the codec alc256 + or alc236 (LP: #1853791) + - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table + - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table + + * remount of multilower moved pivoted-root overlayfs root, results in I/O + errors on some modified files (LP: #1824407) + - SAUCE: ovl: fix lookup failure on multi lower squashfs + + * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2 + (LP: #1847451) + - SAUCE: tools/power turbostat: Add Cometlake support + + * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222) + - [Config] Enable ROCKCHIP support for arm64 + + * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer + works on Dell Venue 11 Pro 7140 (LP: #1846539) + - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy + driver + + * i40e: general protection fault in i40e_config_vf_promiscuous_mode + (LP: #1852663) + - SAUCE: i40e Fix GPF when deleting VMs + + * libbpf check_abi fails on ppc64el (LP: #1854974) + - libbpf: Fix readelf output parsing on powerpc with recent binutils + + * CVE-2019-19050 + - crypto: user - fix memory leak in crypto_reportstat + + * Make hotplugging docking station to Thunderbolt port more reliable + (LP: #1853991) + - PCI/PM: Add pcie_wait_for_link_delay() + - PCI/PM: Add missing link delays required by the PCIe spec + + * i915: Display flickers (monitor loses signal briefly) during "flickerfree" + boot, while showing the BIOS logo on a black background (LP: #1836858) + - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y + + * [CML] New device id's for CMP-H (LP: #1846335) + - i2c: i801: Add support for Intel Comet Lake PCH-H + - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash + - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs + + * Focal update: v5.4.2 upstream stable release (LP: #1855326) + - io_uring: async workers should inherit the user creds + - net: separate out the msghdr copy from ___sys_{send,recv}msg() + - net: disallow ancillary data for __sys_{send,recv}msg_file() + - crypto: inside-secure - Fix stability issue with Macchiatobin + - driver core: platform: use the correct callback type for bus_find_device + - usb: dwc2: use a longer core rest timeout in dwc2_core_reset() + - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param() + - staging: rtl8192e: fix potential use after free + - staging: rtl8723bs: Drop ACPI device ids + - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids + - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P + - mei: bus: prefix device names on bus with the bus name + - mei: me: add comet point V device id + - thunderbolt: Power cycle the router if NVM authentication fails + - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx + - gve: Fix the queue page list allocated pages count + - macvlan: schedule bc_work even if error + - mdio_bus: don't use managed reset-controller + - net: dsa: sja1105: fix sja1105_parse_rgmii_delays() + - net: macb: add missed tasklet_kill + - net: psample: fix skb_over_panic + - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues + - openvswitch: fix flow command message size + - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook + - slip: Fix use-after-free Read in slip_open + - sctp: cache netns in sctp_ep_common + - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info() + - openvswitch: remove another BUG_ON() + - net/tls: take into account that bpf_exec_tx_verdict() may free the record + - net/tls: free the record on encryption error + - net: skmsg: fix TLS 1.3 crash with full sk_msg + - selftests/tls: add a test for fragmented messages + - net/tls: remove the dead inplace_crypto code + - net/tls: use sg_next() to walk sg entries + - selftests: bpf: test_sockmap: handle file creation failures gracefully + - selftests: bpf: correct perror strings + - tipc: fix link name length check + - selftests: pmtu: use -oneline for ip route list cache + - r8169: fix jumbo configuration for RTL8168evl + - r8169: fix resume on cable plug-in + - ext4: add more paranoia checking in ext4_expand_extra_isize handling + - Revert "jffs2: Fix possible null-pointer dereferences in + jffs2_add_frag_to_fragtree()" + - crypto: talitos - Fix build error by selecting LIB_DES + - HID: core: check whether Usage Page item is after Usage ID items + - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer + - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size + - Linux 5.4.2 + + * no HDMI video output since GDM greeter after linux-oem-osp1 version + 5.0.0-1026 (LP: #1852386) + - drm/i915: Add new CNL PCH ID seen on a CML platform + - SAUCE: drm/i915: Fix detection for a CMP-V PCH + + * Please add patch fixing RK818 ID detection (LP: #1853192) + - SAUCE: mfd: rk808: Fix RK818 ID template + + * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721) + - HID: i2c-hid: fix no irq after reset on raydium 3118 + + * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901) + - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 + 2-in-1" + - lib: devres: add a helper function for ioremap_uc + - mfd: intel-lpss: Use devm_ioremap_uc for MMIO + + * Lenovo dock MAC Address pass through doesn't work in Ubuntu (LP: #1827961) + - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2 + + * Disable unreliable HPET on CFL-H system (LP: #1852216) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Config] Enable virtualbox dkms build + - [Config] update annotations to match current configs + - SAUCE: Add exfat module to signature inclusion list + + * Miscellaneous upstream changes + - Bluetooth: Fix invalid-free in bcsp_close() + - ath9k_hw: fix uninitialized variable data + - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe + - ath10k: Fix HOST capability QMI incompatibility + - ath10k: restore QCA9880-AR1A (v1) detection + - Revert "Bluetooth: hci_ll: set operational frequency earlier" + - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues" + - md/raid10: prevent access of uninitialized resync_pages offset + - x86/insn: Fix awk regexp warnings + - x86/speculation: Fix incorrect MDS/TAA mitigation status + - x86/speculation: Fix redundant MDS mitigation message + - nbd: prevent memory leak + - x86/stackframe/32: Repair 32-bit Xen PV + - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout + - x86/xen/32: Simplify ring check in xen_iret_crit_fixup() + - x86/doublefault/32: Fix stack canaries in the double fault handler + - x86/pti/32: Size initial_page_table correctly + - x86/cpu_entry_area: Add guard page for entry stack on 32bit + - x86/entry/32: Fix IRET exception + - x86/entry/32: Use %ss segment where required + - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL + - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry + - x86/entry/32: Fix NMI vs ESPFIX + - selftests/x86/mov_ss_trap: Fix the SYSENTER test + - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel + - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make + the CPU_ENTRY_AREA_PAGES assert precise + - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3 + - futex: Prevent robust futex exit race + - ALSA: usb-audio: Fix NULL dereference at parsing BADD + - ALSA: usb-audio: Fix Scarlett 6i6 Gen 2 port data + - media: vivid: Set vid_cap_streaming and vid_out_streaming to true + - media: vivid: Fix wrong locking that causes race conditions on streaming + stop + - media: usbvision: Fix invalid accesses after device disconnect + - media: usbvision: Fix races among open, close, and disconnect + - cpufreq: Add NULL checks to show() and store() methods of cpufreq + - futex: Move futex exit handling into futex code + - futex: Replace PF_EXITPIDONE with a state + - exit/exec: Seperate mm_release() + - futex: Split futex_mm_release() for exit/exec + - futex: Set task::futex_state to DEAD right after handling futex exit + - futex: Mark the begin of futex exit explicitly + - futex: Sanitize exit state handling + - futex: Provide state handling for exec() as well + - futex: Add mutex around futex exit + - futex: Provide distinct return value when owner is exiting + - futex: Prevent exit livelock + - media: uvcvideo: Fix error path in control parsing failure + - media: b2c2-flexcop-usb: add sanity checking + - media: cxusb: detect cxusb_ctrl_msg error in query + - media: imon: invalid dereference in imon_touch_event + - media: mceusb: fix out of bounds read in MCE receiver buffer + - ALSA: hda - Disable audio component for legacy Nvidia HDMI codecs + - USBIP: add config dependency for SGL_ALLOC + - usbip: tools: fix fd leakage in the function of read_attr_usbip_status + - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit() + - usb-serial: cp201x: support Mark-10 digital force gauge + - USB: chaoskey: fix error case of a timeout + - appledisplay: fix error handling in the scheduled work + - USB: serial: mos7840: add USB ID to support Moxa UPort 2210 + - USB: serial: mos7720: fix remote wakeup + - USB: serial: mos7840: fix remote wakeup + - USB: serial: option: add support for DW5821e with eSIM support + - USB: serial: option: add support for Foxconn T77W968 LTE modules + - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error + - powerpc/book3s64: Fix link stack flush on context switch + - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel + - Linux 5.4.1 + + -- Seth Forshee Fri, 06 Dec 2019 15:53:53 -0600 + +linux (5.4.0-7.8) focal; urgency=medium + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/bpf: Comment out BPF_CORE_READ's which cause clang to + segfault + - Update nvidia-430 to nvidia-440 + - [Config] Enable nvidia dkms build + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.4 + + -- Andrea Righi Mon, 25 Nov 2019 15:02:30 +0100 + +linux (5.4.0-6.7) focal; urgency=medium + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Config] updateconfigs after rebase to 5.4-rc8 + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc7 + + -- Andrea Righi Mon, 18 Nov 2019 12:08:01 +0100 + +linux (5.4.0-5.6) focal; urgency=medium + + * refcount underflow and type confusion in shiftfs (LP: #1850867) // + CVE-2019-15793 + - SAUCE: shiftfs: Correct id translation for lower fs operations + + * refcount underflow and type confusion in shiftfs (LP: #1850867) // + CVE-2019-15792 + - SAUCE: shiftfs: prevent type confusion + + * refcount underflow and type confusion in shiftfs (LP: #1850867) // + CVE-2019-15791 + - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling + + * Some EFI systems fail to boot in efi_init() when booted via maas + (LP: #1851810) + - SAUCE: efi: efi_get_memory_map -- increase map headroom + + * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281) + - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: avoid overflow in implicit constant conversion + + * dkms artifacts may expire from the pool (LP: #1850958) + - [Packaging] dkms -- try launchpad librarian for pool downloads + - [Packaging] dkms -- dkms-build quieten wget verbiage + + * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms + - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms + + * shiftfs: prevent exceeding project quotas (LP: #1849483) + - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities + + * shiftfs: fix fallocate() (LP: #1849482) + - SAUCE: shiftfs: setup correct s_maxbytes limit + + * The alsa hda driver is not loaded due to the missing of PCIID for Comet + Lake-S [8086:a3f0] (LP: #1852070) + - SAUCE: ALSA: hda: Add Cometlake-S PCI ID + + * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877) + - SAUCE: platform/x86: dell-uart-backlight: add missing status command + - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status + - SAUCE: platform/x86: dell-uart-backlight: add force parameter + - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms + + * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677) + - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags + + * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs + error path (LP: #1850994) // CVE-2019-15794 + - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails + - SAUCE: ovl: Restore vm_file value when lower fs mmap fails + + * Miscellaneous Ubuntu changes + - [Debian] Convert update-aufs.sh to use aufs5 + - SAUCE: import aufs driver + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc7 + + -- Seth Forshee Wed, 13 Nov 2019 11:56:35 -0800 + +linux (5.4.0-4.5) focal; urgency=medium + + * High power consumption using 5.0.0-25-generic (LP: #1840835) + - PCI: Add a helper to check Power Resource Requirements _PR3 existence + - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a + driver + - PCI: Fix missing inline for pci_pr3_present() + + * Fix signing of staging modules in eoan (LP: #1850234) + - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink + + * [20.04 FEAT] Set Architecture Level (ALS) to z13 (LP: #1837525) + - [Config] s390x bump march to z13, with tune to z15 + + * Miscellaneous Ubuntu changes + - [Debian]: do not skip tests for linux-hwe-edge + - update dkms package versions + - [Config] re-enable zfs + - [Config] rename module virtio_fs to virtiofs + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc6 + + -- Andrea Righi Mon, 04 Nov 2019 15:12:02 +0100 + +linux (5.4.0-3.4) focal; urgency=medium + + * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281) + - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test + + * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled + cloud (LP: #1848481) + - [Packaging] include iavf/i40evf in generic + + * CVE-2019-17666 + - SAUCE: rtlwifi: Fix potential overflow on P2P code + + * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes + to no (LP: #1848492) + - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x + from yes to no + + * Add Intel Comet Lake ethernet support (LP: #1848555) + - SAUCE: e1000e: Add support for Comet Lake + + * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE (LP: #1847744) + - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE + + * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL + platforms (LP: #1847192) + - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display + - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms + + * PM / hibernate: fix potential memory corruption (LP: #1847118) + - SAUCE: PM / hibernate: memory_bm_find_bit -- tighten node optimisation + + * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186) + - SAUCE: apparmor: fix nnp subset test for unconfined + + * overlayfs: allow with shiftfs as underlay (LP: #1846272) + - SAUCE: overlayfs: allow with shiftfs as underlay + + * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490) + - [Config] Fix SOF Kconfig options + + * linux won't build when new virtualbox version is present on the archive + (LP: #1848788) + - [Packaging]: download virtualbox from sources + + * Miscellaneous Ubuntu changes + - [Config] update annotations from configs + - [Config] updateconfigs after rebase to 5.4-rc5 + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc5 + + -- Seth Forshee Tue, 29 Oct 2019 12:01:27 -0500 + +linux (5.4.0-2.3) eoan; urgency=medium + + * Add installer support for iwlmvm adapters (LP: #1848236) + - d-i: Add iwlmvm to nic-modules + + * shiftfs: rework how shiftfs opens files (LP: #1846265) + - SAUCE: shiftfs: rework how shiftfs opens files + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Config] updateconfigs after rebase to 5.4-rc4 + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc4 + + -- Andrea Righi Mon, 21 Oct 2019 17:31:26 +0200 + +linux (5.4.0-1.2) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Config] updateconfigs after rebase to 5.4-rc3 + - [Config] add flexfb, fbtft_device and rio500 to modules.ignore + - [Config] amd64: ignore fbtft and all dependent modules + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc3 + + -- Andrea Righi Mon, 14 Oct 2019 19:48:52 +0200 + +linux (5.4.0-0.1) eoan; urgency=medium + + * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704) + - [Packaging] arm64: snapdragon: introduce a snapdragon flavour + - [Packaging] arm64: snapdragon: switch kernel format to Image + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y + - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y + - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y + - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y + - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y + - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y + - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y + - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y + - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y + - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y + - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y + - [Config] arm64: snapdragon: CONFIG_USB_OTG=y + - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y + - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y + - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y + - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y + - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y + - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to 5.4-rc2 + - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that + aren't present. + - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err(). + - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down + - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot + mode + - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode + - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature + verify + - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot + - SAUCE: (lockdown) security: lockdown: Make + CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic + - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure + - [Config] Enable lockdown under secure boot + - SAUCE: import aufs driver + - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3 + - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers + - [Config] enable aufs + - update dkms package versions + - [Config] disable zfs + - [Config] disable nvidia dkms build + - [Config] disable virtualbox dkms build + - [Debian] Generate stub reconstruct for -rc kernels + - Revert "UBUNTU: SAUCE: (namespace) block_dev: Forbid unprivileged mounting + when device is opened for writing" + - Revert "UBUNTU: SAUCE: (namespace) ext4: Add module parameter to enable user + namespace mounts" + - Revert "UBUNTU: SAUCE: (namespace) ext4: Add support for unprivileged mounts + from user namespaces" + - Revert "UBUNTU: SAUCE: (namespace) mtd: Check permissions towards mtd block + device inode when mounting" + - Revert "UBUNTU: SAUCE: (namespace) block_dev: Check permissions towards + block device inode when mounting" + - Revert "UBUNTU: SAUCE: (namespace) block_dev: Support checking inode + permissions in lookup_bdev()" + + [ Upstream Kernel Changes ] + + * Rebase to v5.4-rc2 + + -- Seth Forshee Fri, 11 Oct 2019 16:42:41 -0500 + +linux (5.4.0-0.0) eoan; urgency=medium + + * Dummy entry. + + -- Seth Forshee Tue, 08 Oct 2019 09:59:00 -0500 + +linux (5.3.0-17.18) eoan; urgency=medium + + * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641) + + * CVE-2019-17056 + - nfc: enforce CAP_NET_RAW for raw sockets + + * CVE-2019-17055 + - mISDN: enforce CAP_NET_RAW for raw sockets + + * CVE-2019-17054 + - appletalk: enforce CAP_NET_RAW for raw sockets + + * CVE-2019-17053 + - ieee802154: enforce CAP_NET_RAW for raw sockets + + * CVE-2019-17052 + - ax25: enforce CAP_NET_RAW for raw sockets + + * CVE-2019-15098 + - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe() + + * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices. + (LP: #1846470) + - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect + + * Re-enable linux-libc-dev build on i386 (LP: #1846508) + - [Packaging] Build only linux-libc-dev for i386 + - [Debian] final-checks -- ignore archtictures with no binaries + + * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic- + proposed (LP: #1845820) + - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT + + * Revert ESE DASD discard support (LP: #1846219) + - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes" + + * Miscellaneous Ubuntu changes + - update dkms package versions + + -- Seth Forshee Thu, 03 Oct 2019 16:57:05 -0500 + +linux (5.3.0-16.17) eoan; urgency=medium + + * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204) + + * zfs fails to build on s390x with debug symbols enabled (LP: #1846143) + - SAUCE: s390: Mark atomic const ops always inline + + -- Seth Forshee Tue, 01 Oct 2019 07:46:43 -0500 + +linux (5.3.0-15.16) eoan; urgency=medium + + * eoan/linux: 5.3.0-15.16 -proposed tracker (LP: #1845987) + + * Drop i386 build for 19.10 (LP: #1845714) + - [Packaging] Remove x32 arch references from control files + - [Debian] final-checks -- Get arch list from debian/control + + * ZFS kernel modules lack debug symbols (LP: #1840704) + - [Debian] Fix conditional for setting zfs debug package path + + * Use pyhon3-sphinx instead of python-sphinx for building html docs + (LP: #1845808) + - [Packaging] Update sphinx build dependencies to python3 packages + + * Kernel panic with 19.10 beta image (LP: #1845454) + - efi/tpm: Don't access event->count when it isn't mapped. + - efi/tpm: don't traverse an event log with no events + - efi/tpm: only set efi_tpm_final_log_size after successful event log parsing + + -- Seth Forshee Mon, 30 Sep 2019 11:57:20 -0500 + +linux (5.3.0-14.15) eoan; urgency=medium + + * eoan/linux: 5.3.0-14.15 -proposed tracker (LP: #1845728) + + * Drop i386 build for 19.10 (LP: #1845714) + - [Debian] Remove support for producing i386 kernels + - [Debian] Don't use CROSS_COMPILE for i386 configs + + * udevadm trigger will fail when trying to add /sys/devices/vio/ + (LP: #1845572) + - SAUCE: powerpc/vio: drop bus_type from parent device + + * Trying to online dasd drive results in invalid input/output from the kernel + on z/VM (LP: #1845323) + - SAUCE: s390/dasd: Fix error handling during online processing + + * intel-lpss driver conflicts with write-combining MTRR region (LP: #1845584) + - SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 2-in-1 + + * Support Hi1620 zip hw accelerator (LP: #1845355) + - [Config] Enable HiSilicon QM/ZIP as modules + - crypto: hisilicon - add queue management driver for HiSilicon QM module + - crypto: hisilicon - add hardware SGL support + - crypto: hisilicon - add HiSilicon ZIP accelerator support + - crypto: hisilicon - add SRIOV support for ZIP + - Documentation: Add debugfs doc for hisi_zip + - crypto: hisilicon - add debugfs for ZIP and QM + - MAINTAINERS: add maintainer for HiSilicon QM and ZIP controller driver + - crypto: hisilicon - fix kbuild warnings + - crypto: hisilicon - add dependency for CRYPTO_DEV_HISI_ZIP + - crypto: hisilicon - init curr_sgl_dma to fix compile warning + - crypto: hisilicon - add missing single_release + - crypto: hisilicon - fix error handle in hisi_zip_create_req_q + - crypto: hisilicon - Fix warning on printing %p with dma_addr_t + - crypto: hisilicon - Fix return value check in hisi_zip_acompress() + - crypto: hisilicon - avoid unused function warning + + * SafeSetID LSM should be built but disabled by default (LP: #1845391) + - LSM: SafeSetID: Stop releasing uninitialized ruleset + - [Config] Build SafeSetID LSM but don't enable it by default + + * CONFIG_LSM should not specify loadpin since it is not built (LP: #1845383) + - [Config] loadpin shouldn't be in CONFIG_LSM + + * Add new pci-id's for CML-S, ICL (LP: #1845317) + - drm/i915/icl: Add missing device ID + - drm/i915/cml: Add Missing PCI IDs + + * Thunderbolt support for ICL (LP: #1844680) + - thunderbolt: Correct path indices for PCIe tunnel + - thunderbolt: Move NVM upgrade support flag to struct icm + - thunderbolt: Use 32-bit writes when writing ring producer/consumer + - thunderbolt: Do not fail adding switch if some port is not implemented + - thunderbolt: Hide switch attributes that are not set + - thunderbolt: Expose active parts of NVM even if upgrade is not supported + - thunderbolt: Add support for Intel Ice Lake + - ACPI / property: Add two new Thunderbolt property GUIDs to the list + + * Ubuntu 19.10 - Additional PCI patch and fix (LP: #1844668) + - s390/pci: fix MSI message data + + * Enhanced Hardware Support - Finalize Naming (LP: #1842774) + - s390: add support for IBM z15 machines + - [Config] CONFIG_MARCH_Z15=n, CONFIG_TUNE_Z15=n + + * Eoan update: v5.3.1 upstream stable release (LP: #1845642) + - USB: usbcore: Fix slab-out-of-bounds bug during device reset + - media: tm6000: double free if usb disconnect while streaming + - phy: renesas: rcar-gen3-usb2: Disable clearing VBUS in over-current + - ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit + - net/sched: fix race between deactivation and dequeue for NOLOCK qdisc + - net_sched: let qdisc_put() accept NULL pointer + - udp: correct reuseport selection with connected sockets + - xen-netfront: do not assume sk_buff_head list is empty in error handling + - net: dsa: Fix load order between DSA drivers and taggers + - net: stmmac: Hold rtnl lock in suspend/resume callbacks + - KVM: coalesced_mmio: add bounds checking + - Documentation: sphinx: Add missing comma to list of strings + - firmware: google: check if size is valid when decoding VPD data + - serial: sprd: correct the wrong sequence of arguments + - tty/serial: atmel: reschedule TX after RX was started + - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds + - Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}" + - ovl: fix regression caused by overlapping layers detection + - phy: qcom-qmp: Correct ready status, again + - floppy: fix usercopy direction + - media: technisat-usb2: break out of loop at end of buffer + - Linux 5.3.1 + + * ZFS kernel modules lack debug symbols (LP: #1840704) + - [Debian]: Remove hardcoded $(pkgdir) in debug symbols handling + - [Debian]: Handle debug symbols for modules in extras too + - [Debian]: Check/link modules with debug symbols after DKMS modules + - [Debian]: Warn about modules without debug symbols + - [Debian]: dkms-build: new parameter for debug package directory + - [Debian]: dkms-build: zfs: support for debug symbols + - [Debian]: dkms-build: Avoid executing post-processor scripts twice + - [Debian]: dkms-build: Move zfs special-casing into configure script + + * /proc/self/maps paths missing on live session (was vlc won't start; eoan + 19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies) + (LP: #1842382) + - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs" + + -- Seth Forshee Fri, 27 Sep 2019 16:08:06 -0500 + +linux (5.3.0-13.14) eoan; urgency=medium + + * eoan/linux: 5.3.0-13.14 -proposed tracker (LP: #1845105) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * Miscellaneous Ubuntu changes + - [Debian] Remove binutils-dev build dependency + + -- Seth Forshee Mon, 23 Sep 2019 19:26:43 -0500 + +linux (5.3.0-12.13) eoan; urgency=medium + + * Change kernel compression method to improve boot speed (LP: #1840934) + - [Packaging] Add lz4 build dependency for s390x + + * Miscellaneous Ubuntu changes + - SAUCE: Remove spl and zfs source + + -- Seth Forshee Tue, 17 Sep 2019 13:36:26 +0200 + +linux (5.3.0-11.12) eoan; urgency=medium + + * eoan/linux: 5.3.0-11.12 -proposed tracker (LP: #1844144) + + * Suspend to RAM(S3) does not wake up for latest megaraid and mpt3sas + adapters(SAS3.5 onwards) (LP: #1838751) + - PCI: Restore Resizable BAR size bits correctly for 1MB BARs + + * s390/setup: Actually init kernel lock down (LP: #1843961) + - SAUCE: (lockdown) s390/setup: Actually init kernel lock down + + * cherrypick has_sipl fix (LP: #1843960) + - SAUCE: s390/sclp: Fix bit checked for has_sipl + + * Change kernel compression method to improve boot speed (LP: #1840934) + - [Config]: Switch kernel compression from LZO to LZ4 on s390x + + * Installation fails on eoan/PowerVM : missing /dev/nvram (LP: #1837726) + - [Config] CONFIG_NVRAM=y for ppc64el + + * Miscellaneous Ubuntu changes + - [Config]: remove nvram from ppc64el modules ABI + - [Config] Update annotations for recent config changes + - SAUCE: sched: Add __ASSEMBLY__ guards around struct clone_args + - SAUCE: i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630 + - SAUCE: arm64: dts: qcom: Add Lenovo Yoga C630 + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.3 + + -- Paolo Pisati Mon, 16 Sep 2019 16:18:27 +0200 + +linux (5.3.0-10.11) eoan; urgency=medium + + * eoan/linux: 5.3.0-10.11 -proposed tracker (LP: #1843232) + + * No sound inputs from the external microphone and headset on a Dell machine + (LP: #1842265) + - SAUCE: ALSA: hda - Expand pin_match function to match upcoming new tbls + - SAUCE: ALSA: hda - Define a fallback_pin_fixup_tbl for alc269 family + + * Horizontal corrupted line at top of screen caused by framebuffer compression + (LP: #1840236) + - SAUCE: drm/i915/fbc: disable framebuffer compression on IceLake + + * Add bpftool to linux-tools-common (LP: #1774815) + - [Debian] package bpftool in linux-tools-common + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc8 + + -- Paolo Pisati Mon, 09 Sep 2019 10:00:41 +0200 + +linux (5.3.0-9.10) eoan; urgency=medium + + * eoan/linux: 5.3.0-9.10 -proposed tracker (LP: #1842393) + + * shiftfs: mark kmem_cache as reclaimable (LP: #1842059) + - SAUCE: shiftfs: mark slab objects SLAB_RECLAIM_ACCOUNT + + * shiftfs: drop entries from cache on unlink (LP: #1841977) + - SAUCE: shiftfs: fix buggy unlink logic + + * Fix touchpad IRQ storm after S3 (LP: #1841396) + - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin + + * Please include DTBs for arm64 laptops (LP: #1842050) + - arm64: dts: qcom: Add Lenovo Miix 630 + - arm64: dts: qcom: Add HP Envy x2 + - arm64: dts: qcom: Add Asus NovaGo TP370QL + + * Miscellaneous Ubuntu changes + - SAUCE: import aufs driver + - [Packaging]: ignore vbox modules when vbox is disabled + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc7 + + -- Paolo Pisati Tue, 03 Sep 2019 10:27:33 +0200 + +linux (5.3.0-8.9) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + * Change kernel compression method to improve boot speed (LP: #1840934) + - [Config] change kernel compression method to improve boot speed + - [Packaging] add build dependencies for compression algorithms + + * realtek r8822be kernel module fails after update to linux kernel-headers + 5.0.0-21 (LP: #1838133) + - rtw88: Fix misuse of GENMASK macro + - rtw88: pci: Rearrange the memory usage for skb in RX ISR + - rtw88: pci: Use DMA sync instead of remapping in RX ISR + - rtw88: debug: dump tx power indexes in use + - rtw88: use txpwr_lmt_cfg_pair struct, not arrays + - rtw88: pci: remove set but not used variable 'ip_sel' + - rtw88: allow c2h operation in irq context + - rtw88: enclose c2h cmd handle with mutex + - rtw88: add BT co-existence support + - SAUCE: rtw88: pci: enable MSI interrupt + + * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482) + - [Config] Enable VIMC module + + * Goodix touchpad may drop first input event (LP: #1840075) + - Revert "UBUNTU: SAUCE: i2c: designware: add G3 3590 into i2c quirk" + - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk" + - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c + quirk" + - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk" + - mfd: intel-lpss: Remove D3cold delay + + * Include Sunix serial/parallel driver (LP: #1826716) + - serial: 8250_pci: Add support for Sunix serial boards + - parport: parport_serial: Add support for Sunix Multi I/O boards + + * enable lockdown on s390x when Secure IPL is performed (LP: #1839622) + - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure + - Ubuntu: [Config] Enable CONFIG_LOCK_DOWN_KERNEL on s390x. + + * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231) + - SAUCE: shiftfs: pass correct point down + + * shiftfs: add O_DIRECT support (LP: #1837223) + - SAUCE: shiftfs: add O_DIRECT support + + * Miscellaneous Ubuntu changes + - [Config] enable secureboot signing on s390x + - [Config] CONFIG_TEST_BLACKHOLE_DEV=m + - SAUCE: selftests: fib_tests: assign address to dummy1 for rp_filter tests + - [Debian] disable dkms builds for autopktest rebuilds + - update dkms package versions + - [Config] updateconfigs after v5.3-rc6 rebase + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc5 + + -- Paolo Pisati Mon, 26 Aug 2019 10:09:42 +0200 + +linux (5.3.0-7.8) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after v5.3-rc5 rebase + - remove missing module after updateconfigs + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc5 + + -- Paolo Pisati Mon, 19 Aug 2019 15:31:24 +0200 + +linux (5.3.0-6.7) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/bpf: prevent headers to be compiled as C code + + -- Seth Forshee Wed, 14 Aug 2019 13:25:01 -0500 + +linux (5.3.0-5.6) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Config] enable zfs build + + -- Seth Forshee Tue, 13 Aug 2019 09:16:06 -0500 + +linux (5.3.0-4.5) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + + * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight + timeout for bcache removal causes spurious failures (LP: #1796292) + - SAUCE: bcache: fix deadlock in bcache_allocator + + * shiftfs: allow overlayfs (LP: #1838677) + - SAUCE: shiftfs: enable overlayfs on shiftfs + + * Miscellaneous Ubuntu changes + - SAUCE: Revert "kbuild: modpost: do not parse unnecessary rules for vmlinux + modpost" + - update dkms package versions + - enable nvidia dkms build + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc4 + + -- Seth Forshee Mon, 12 Aug 2019 10:41:27 -0500 + +linux (5.3.0-3.4) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - update dkms package versions + - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers + - [Config] add mux-* to modules.ignore + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc3 + + -- Paolo Pisati Mon, 05 Aug 2019 18:17:09 +0200 + +linux (5.3.0-2.3) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - [Packaging] add build dependincy on fontconfig + + -- Seth Forshee Mon, 29 Jul 2019 12:18:46 -0400 + +linux (5.3.0-1.2) eoan; urgency=medium + + * System does not auto detect disconnection of external monitor (LP: #1835001) + - SAUCE: drm/i915: Add support for retrying hotplug + - SAUCE: drm/i915: Enable hotplug retry + + * Please enable CONFIG_SCSI_UFS_QCOM as a module on arm64 (LP: #1837332) + - [Config] Enable CONFIG_SCSI_UFS_QCOM as a module on arm64. + + * Add arm64 CONFIG_ARCH_MESON=y and related configs Edit (LP: #1820530) + - [Config] enable ARCH_MESON + - remove missing module + - [Config] update annotations after enabling ARCH_MESON for arm64 + + * Miscellaneous Ubuntu changes + - SAUCE: KVM: PPC: comment implicit fallthrough + - update dkms package versions + - [Config] enable vbox dkms build + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc2 + + -- Seth Forshee Sun, 28 Jul 2019 23:10:16 -0400 + +linux (5.3.0-0.1) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + * Miscellaneous Ubuntu changes + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and + KEXEC_SIG_FORCE + - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is + locked down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages + - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy + when locked down + - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation + defined + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module + signature verify + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates + - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in + Secure Boot mode + - SAUCE: import aufs driver + - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3 + - [Config] disable zfs dkms build + - [Config] disable nvidia dkms build + - [Config] disable vbox dkms build + - SAUCE: perf diff: use llabs for s64 vaules + + [ Upstream Kernel Changes ] + + * Rebase to v5.3-rc1 + + -- Seth Forshee Tue, 23 Jul 2019 21:45:44 -0500 + +linux (5.3.0-0.0) eoan; urgency=medium + + * Dummy entry. + + -- Seth Forshee Mon, 22 Jul 2019 10:19:04 -0500 + +linux (5.2.0-9.10) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * input/mouse: alps trackpoint-only device doesn't work (LP: #1836752) + - SAUCE: Input: alps - don't handle ALPS cs19 trackpoint-only device + - SAUCE: Input: alps - fix a mismatch between a condition check and its + comment + + * System does not auto detect disconnection of external monitor (LP: #1835001) + - SAUCE: drm/i915: Add support for retrying hotplug + - SAUCE: drm/i915: Enable hotplug retry + + * alsa/hdmi: add icelake hdmi audio support for a Dell machine (LP: #1836916) + - SAUCE: ALSA: hda/hdmi - Remove duplicated define + - SAUCE: ALSA: hda/hdmi - Fix i915 reverse port/pin mapping + + * First click on Goodix touchpad doesn't be recognized after runtime suspended + (LP: #1836836) + - SAUCE: i2c: designware: add G3 3590 into i2c quirk + + * ixgbe{vf} - Physical Function gets IRQ when VF checks link state + (LP: #1836760) + - ixgbevf: Use cached link state instead of re-reading the value for ethtool + + * Doing multiple squashfs (and other loop?) mounts in parallel breaks + (LP: #1836914) + - SAUCE: Revert "loop: Don't change loop device under exclusive opener" + + * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940) + - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64 + - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only + - [Config] add hibmc-drm to modules.ignore + + * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755) + - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine + + * Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64 + (LP: #1835054) + - [Config] Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64 + + * Unhide Nvidia HDA audio controller (LP: #1836308) + - PCI: Enable NVIDIA HDA controllers + + * Intel ethernet I219 may wrongly detect connection speed as 10Mbps + (LP: #1836177) + - e1000e: Make watchdog use delayed work + + * Sometimes touchpad(goodix) can't use tap function (LP: #1836020) + - SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c quirk + - SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk + + * Intel ethernet I219 has slow RX speed (LP: #1836152) + - e1000e: add workaround for possible stalled packet + - e1000e: disable force K1-off feature + + * bcache: risk of data loss on I/O errors in backing or caching devices + (LP: #1829563) + - Revert "bcache: set CACHE_SET_IO_DISABLE in bch_cached_dev_error()" + + * bnx2x driver causes 100% CPU load (LP: #1832082) + - bnx2x: Prevent ptp_task to be rescheduled indefinitely + + * fcf-protection=none patch with new version + - Revert "UBUNTU: SAUCE: kbuild: add -fcf-protection=none to retpoline flags" + - SAUCE: kbuild: add -fcf-protection=none when using retpoline flags + + * CVE-2019-12614 + - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property() + + * Eoan update: v5.2.1 upstream stable release (LP: #1836622) + - crypto: lrw - use correct alignmask + - crypto: talitos - rename alternative AEAD algos. + - fscrypt: don't set policy for a dead directory + - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + - media: stv0297: fix frequency range limit + - ALSA: usb-audio: Fix parse of UAC2 Extension Units + - ALSA: hda/realtek - Headphone Mic can't record after S3 + - tpm: Actually fail on TPM errors during "get random" + - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations + - block: fix .bi_size overflow + - block, bfq: NULL out the bic when it's no longer valid + - perf intel-pt: Fix itrace defaults for perf script + - perf auxtrace: Fix itrace defaults for perf script + - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation + - perf pmu: Fix uncore PMU alias list for ARM64 + - perf thread-stack: Fix thread stack return from kernel for kernel-only case + - perf header: Assign proper ff->ph in perf_event__synthesize_features() + - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + - x86/tls: Fix possible spectre-v1 in do_get_thread_area() + - Documentation: Add section about CPU vulnerabilities for Spectre + - Documentation/admin: Remove the vsyscall=native documentation + - mwifiex: Don't abort on small, spec-compliant vendor IEs + - USB: serial: ftdi_sio: add ID for isodebug v1 + - USB: serial: option: add support for GosunCn ME3630 RNDIS mode + - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled" + - p54usb: Fix race between disconnect and firmware loading + - usb: gadget: f_fs: data_len used before properly set + - usb: gadget: ether: Fix race between gether_disconnect and rx_submit + - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset() + - usb: renesas_usbhs: add a workaround for a race condition of workqueue + - drivers/usb/typec/tps6598x.c: fix portinfo width + - drivers/usb/typec/tps6598x.c: fix 4CC cmd write + - p54: fix crash during initialization + - staging: comedi: dt282x: fix a null pointer deref on interrupt + - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize() + - staging: bcm2835-camera: Restore return behavior of ctrl_set_bitrate() + - staging: comedi: amplc_pci230: fix null pointer deref on interrupt + - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro + - HID: Add another Primax PIXART OEM mouse quirk + - lkdtm: support llvm-objcopy + - binder: fix memory leak in error path + - binder: return errors from buffer copy functions + - iio: adc: stm32-adc: add missing vdda-supply + - coresight: Potential uninitialized variable in probe() + - coresight: etb10: Do not call smp_processor_id from preemptible + - coresight: tmc-etr: Do not call smp_processor_id() from preemptible + - coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from + preemptible + - coresight: tmc-etf: Do not call smp_processor_id from preemptible + - carl9170: fix misuse of device driver API + - Revert "x86/build: Move _etext to actual end of .text" + - VMCI: Fix integer overflow in VMCI handle arrays + - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()" + - staging: vchiq: make wait events interruptible + - staging: vchiq: revert "switch to wait_for_completion_killable" + - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work + - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex + - staging: bcm2835-camera: Ensure all buffers are returned on disable + - staging: bcm2835-camera: Remove check of the number of buffers supplied + - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming + - staging: rtl8712: reduce stack usage, again + - Linux 5.2.1 + - [Config] updateconfigs after v5.2.1 stable update + + * fcf-protection=none patch with upstream version + - Revert "UBUNTU: SAUCE: add -fcf-protection=none to retpoline flags" + - SAUCE: kbuild: add -fcf-protection=none to retpoline flags + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/ftrace: avoid failure when trying to probe a notrace + function + - SAUCE: selftests/powerpc/ptrace: fix build failure + - update dkms package versions + - [Packaging] add zlua to zfs-modules.ignore + - update dkms package versions + + -- Seth Forshee Fri, 19 Jul 2019 15:04:45 -0500 + +linux (5.2.0-8.9) eoan; urgency=medium + + * linux: 5.2.0-8.9 -proposed tracker (LP: #1835700) + + * Miscellaneous Ubuntu changes + - [Packaging] replace zfs and spl build with zfs 0.8.1-1ubuntu1 + - SAUCE: test_bpf: remove expected fail for Ctx heavy transformations test on + s390 + - SAUCE: add -fcf-protection=none to retpoline flags + - SAUCE: usbip: ensure strings copied using strncpy are null-terminated + - SAUCE: usbip: add -Wno-address-of-packed-member to EXTRA_CFLAGS + - SAUCE: perf jvmti: ensure strncpy result is null-terminated + - update dkms package versions + - add removed zfs modules to modules.ignore + + [ Upstream Kernel Changes ] + + * Rebase to v5.2 + + -- Seth Forshee Mon, 08 Jul 2019 07:13:41 -0500 + +linux (5.2.0-7.8) eoan; urgency=medium + + * Kernel panic upon resetting ixgbe SR-IOV VFIO virtual function using 5.0 + kernel (LP: #1829652) + - SAUCE: ixgbe: Avoid NULL pointer dereference with VF on non-IPsec hw + + * Hi1620 driver updates from upstream 5.2 merge window (LP: #1830815) + - net: hns3: initialize CPU reverse mapping + - net: hns3: refine the flow director handle + - net: hns3: add aRFS support for PF + - net: hns3: fix for FEC configuration + - RDMA/hns: Remove unnecessary print message in aeq + - RDMA/hns: Update CQE specifications + - RDMA/hns: Move spin_lock_irqsave to the correct place + - RDMA/hns: Remove jiffies operation in disable interrupt context + - RDMA/hns: Replace magic numbers with #defines + - net: hns3: fix compile warning without CONFIG_RFS_ACCEL + - net: hns3: fix for HNS3_RXD_GRO_SIZE_M macro + - net: hns3: add support for dump firmware statistics by debugfs + - net: hns3: use HCLGE_STATE_NIC_REGISTERED to indicate PF NIC client has + registered + - net: hns3: use HCLGE_STATE_ROCE_REGISTERED to indicate PF ROCE client has + registered + - net: hns3: use HCLGEVF_STATE_NIC_REGISTERED to indicate VF NIC client has + registered + - net: hns3: modify hclge_init_client_instance() + - net: hns3: modify hclgevf_init_client_instance() + - net: hns3: add handshake with hardware while doing reset + - net: hns3: stop schedule reset service while unloading driver + - net: hns3: adjust hns3_uninit_phy()'s location in the hns3_client_uninit() + - net: hns3: fix a memory leak issue for hclge_map_unmap_ring_to_vf_vector + - RDMA/hns: Bugfix for posting multiple srq work request + - net: hns3: remove redundant core reset + - net: hns3: don't configure new VLAN ID into VF VLAN table when it's full + - net: hns3: fix VLAN filter restore issue after reset + - net: hns3: set the port shaper according to MAC speed + - net: hns3: add a check to pointer in error_detected and slot_reset + - net: hns3: set ops to null when unregister ad_dev + - net: hns3: add handling of two bits in MAC tunnel interrupts + - net: hns3: remove setting bit of reset_requests when handling mac tunnel + interrupts + - net: hns3: add opcode about query and clear RAS & MSI-X to special opcode + - net: hns3: delay and separate enabling of NIC and ROCE HW errors + - RDMA/hns: fix inverted logic of readl read and shift + - RDMA/hns: Bugfix for filling the sge of srq + - net: hns3: log detail error info of ROCEE ECC and AXI errors + - net: hns3: fix wrong size of mailbox responding data + - net: hns3: make HW GRO handling compliant with SW GRO + - net: hns3: replace numa_node_id with numa_mem_id for buffer reusing + - net: hns3: refactor hns3_get_new_int_gl function + - net: hns3: trigger VF reset if a VF has an over_8bd_nfe_err + - net: hns3: delete the redundant user NIC codes + - net: hns3: small changes for magic numbers + - net: hns3: use macros instead of magic numbers + - net: hns3: refactor PF/VF RSS hash key configuration + - net: hns3: some modifications to simplify and optimize code + - net: hns3: fix some coding style issues + - net: hns3: delay setting of reset level for hw errors until slot_reset is + called + - net: hns3: fix avoid unnecessary resetting for the H/W errors which do not + require reset + - net: hns3: process H/W errors occurred before HNS dev initialization + - net: hns3: add recovery for the H/W errors occurred before the HNS dev + initialization + - net: hns3: some changes of MSI-X bits in PPU(RCB) + - net: hns3: extract handling of mpf/pf msi-x errors into functions + - net: hns3: clear restting state when initializing HW device + - net: hns3: free irq when exit from abnormal branch + - net: hns3: fix for dereferencing before null checking + - net: hns3: fix for skb leak when doing selftest + - net: hns3: delay ring buffer clearing during reset + - net: hns3: some variable modification + - net: hns3: fix dereference of ae_dev before it is null checked + - scsi: hisi_sas: Delete PHY timers when rmmod or probe failed + - scsi: hisi_sas: Fix the issue of argument mismatch of printing ecc errors + - scsi: hisi_sas: Reduce HISI_SAS_SGE_PAGE_CNT in size + - scsi: hisi_sas: Change the type of some numbers to unsigned + - scsi: hisi_sas: Ignore the error code between phy down to phy up + - scsi: hisi_sas: Disable stash for v3 hw + - net: hns3: Add missing newline at end of file + - RDMa/hns: Don't stuck in endless timeout loop + + * Sometimes touchpad automatically trigger double click (LP: #1833484) + - SAUCE: i2c: designware: Add disable runtime pm quirk + + * Add pointstick support on HP ZBook 17 G5 (LP: #1833387) + - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A" + + * depmod may prefer unsigned l-r-m nvidia modules to signed modules + (LP: #1834479) + - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/powerpc: disable signal_fuzzer test + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc7 + + -- Seth Forshee Mon, 01 Jul 2019 07:22:18 -0500 + +linux (5.2.0-6.7) eoan; urgency=medium + + * hinic: fix oops due to race in set_rx_mode (LP: #1832048) + - hinic: fix a bug in set rx mode + + * Miscellaneous Ubuntu changes + - rebase to v5.2-rc6 + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc6 + + -- Seth Forshee Sun, 23 Jun 2019 23:36:11 -0500 + +linux (5.2.0-5.6) eoan; urgency=medium + + * QCA9377 isn't being recognized sometimes (LP: #1757218) + - SAUCE: USB: Disable USB2 LPM at shutdown + + * shiftfs: allow changing ro/rw for subvolumes (LP: #1832316) + - SAUCE: shiftfs: allow changing ro/rw for subvolumes + + * Miscellaneous Ubuntu changes + - update dkms package versions + - [Packaging] replace nvidia-418 dkms build with nvidia-430 + - SAUCE: import aufs driver + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc5 + + -- Seth Forshee Mon, 17 Jun 2019 15:04:12 -0500 + +linux (5.2.0-4.5) eoan; urgency=medium + + * arm64: cma_alloc errors at boot (LP: #1823753) + - [Config] Bump CMA_SIZE_MBYTES to 32 on arm64 + - dma-contiguous: add dma_{alloc,free}_contiguous() helpers + - dma-contiguous: use fallback alloc_pages for single pages + - dma-contiguous: fix !CONFIG_DMA_CMA version of dma_{alloc, + free}_contiguous() + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_MFD_TQMX86=n for s390x + - [Config] CONFIG_GPIO_AMD_FCH=n for s390x + - [Config] CONFIG_BACKLIGHT_CLASS_DEVICE=n on s390x + - [Config] CONFIG_LCD_CLASS_DEVICE=n for s390x + - [Config] CONFIG_DRM_ETNAVIV=m for armhf generic-lpae + - [Config] CONFIG_DRM_NOUVEAU_SVM=n + - [Config] CONFIG_HWMON=n for s390x + - [Config] CONFIG_NEW_LEDS=n for s390x + - [Config] CONFIG_MTD_NAND_OMAP2=y for armhf + - [Config] CONFIG_VOP_BUS=n for non-amd64 arches + - [Config] CONFIG_TI_CPSW_PHY_SEL=n + - [Config] CONFIG_INTERCONNECT=n for s390x + - [Config] CONFIG_SCSI_GDTH=n for s390x + - [Config] CONFIG_PACKING=n for s390x + - [Config] CONFIG_ARCH_MILBEAUT=y for armhf + - [Config] update annotations following config review + - update dkms package versions + - [Config] enable nvidia dkms build + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc4 + + -- Seth Forshee Mon, 10 Jun 2019 07:00:11 -0500 + +linux (5.2.0-3.4) eoan; urgency=medium + + * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on + Ubuntu (LP: #1761379) + - [Packaging] Support building libperf-jvmti.so + + * Miscellaneous Ubuntu changes + - SAUCE: Revert "bpf, selftest: test global data/bss/rodata sections" + - update dkms package versions + - [Config] enable zfs + - rebase to v5.2-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc3 + + -- Seth Forshee Sun, 02 Jun 2019 21:48:50 -0500 + +linux (5.2.0-2.3) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - SAUCE: perf arm64: Fix mksyscalltbl when system kernel headers are ahead of + the kernel + + -- Seth Forshee Tue, 28 May 2019 07:12:39 -0500 + +linux (5.2.0-1.2) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_INTEGRITY_PLATFORM_KEYRING=y + - update dkms package versions + - [Config] enable vbox dkms build + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc2 + + -- Seth Forshee Mon, 27 May 2019 21:11:27 -0500 + +linux (5.2.0-0.1) eoan; urgency=medium + + * Miscellaneous Ubuntu changes + - SAUCE: import aufs driver + - [Packaging] disable ZFS + - [Packaging] disable nvidia + - [Packaging] dkms-build -- expand paths searched for make.log files + - add virtualbox-guest-dkms dkms package build + - enable vbox dkms build for amd64 and i386 + - update dkms package versions + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and + KEXEC_SIG_FORCE + - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is + locked down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages + - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy + when locked down + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module + signature verify + - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation + defined + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates + - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in + Secure Boot mode + - update dkms package versions + - [Config] disable vbox build + - SAUCE: s390: mark __cpacf_check_opcode() and cpacf_query_func() as + __always_inline + - SAUCE: IB/mlx5: use size_t instead of u64 when dividing + + [ Upstream Kernel Changes ] + + * Rebase to v5.2-rc1 + + -- Seth Forshee Tue, 21 May 2019 11:18:43 -0500 + +linux (5.2.0-0.0) eoan; urgency=medium + + * Dummy entry. + + -- Seth Forshee Tue, 21 May 2019 07:34:43 -0500 + +linux (5.1.0-2.2) eoan; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + * Eoan update: v5.1.2 upstream stable release (LP: #1829050) + - x86/msr-index: Cleanup bit defines + - x86/speculation: Consolidate CPU whitelists + - x86/speculation/mds: Add basic bug infrastructure for MDS + - x86/speculation/mds: Add BUG_MSBDS_ONLY + - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests + - x86/speculation/mds: Add mds_clear_cpu_buffers() + - x86/speculation/mds: Clear CPU buffers on exit to user + - x86/kvm/vmx: Add MDS protection when L1D Flush is not active + - x86/speculation/mds: Conditionally clear CPU buffers on idle entry + - x86/speculation/mds: Add mitigation control for MDS + - x86/speculation/mds: Add sysfs reporting for MDS + - x86/speculation/mds: Add mitigation mode VMWERV + - Documentation: Move L1TF to separate directory + - Documentation: Add MDS vulnerability documentation + - x86/speculation/mds: Add mds=full,nosmt cmdline option + - x86/speculation: Move arch_smt_update() call to after mitigation decisions + - x86/speculation/mds: Add SMT warning message + - x86/speculation/mds: Fix comment + - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off + - cpu/speculation: Add 'mitigations=' cmdline option + - x86/speculation: Support 'mitigations=' cmdline option + - powerpc/speculation: Support 'mitigations=' cmdline option + - s390/speculation: Support 'mitigations=' cmdline option + - x86/speculation/mds: Add 'mitigations=' support for MDS + - x86/mds: Add MDSUM variant to the MDS documentation + - Documentation: Correct the possible MDS sysfs values + - x86/speculation/mds: Fix documentation typo + - Linux 5.1.2 + + * Eoan update: v5.1.1 upstream stable release (LP: #1829046) + - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup() + - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings + - staging: greybus: power_supply: fix prop-descriptor request size + - staging: wilc1000: Avoid GFP_KERNEL allocation from atomic context. + - staging: most: cdev: fix chrdev_region leak in mod_exit + - staging: most: sound: pass correct device when creating a sound card + - usb: dwc3: Allow building USB_DWC3_QCOM without EXTCON + - usb: dwc3: Fix default lpm_nyet_threshold value + - USB: serial: f81232: fix interrupt worker not stop + - USB: cdc-acm: fix unthrottle races + - usb-storage: Set virt_boundary_mask to avoid SG overflows + - genirq: Prevent use-after-free and work list corruption + - intel_th: pci: Add Comet Lake support + - iio: adc: qcom-spmi-adc5: Fix of-based module autoloading + - cpufreq: armada-37xx: fix frequency calculation for opp + - ACPI / LPSS: Use acpi_lpss_* instead of acpi_subsys_* functions for + hibernate + - soc: sunxi: Fix missing dependency on REGMAP_MMIO + - scsi: lpfc: change snprintf to scnprintf for possible overflow + - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines + - scsi: qla2xxx: Set remote port devloss timeout to 0 + - scsi: qla2xxx: Fix device staying in blocked state + - Bluetooth: hidp: fix buffer overflow + - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections + - Bluetooth: Fix not initializing L2CAP tx_credits + - Bluetooth: hci_bcm: Fix empty regulator supplies for Intel Macs + - UAS: fix alignment of scatter/gather segments + - ASoC: Intel: avoid Oops if DMA setup fails + - i3c: Fix a shift wrap bug in i3c_bus_set_addr_slot_status() + - locking/futex: Allow low-level atomic operations to return -EAGAIN + - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP + - Linux 5.1.1 + + * shiftfs: lock security sensitive superblock flags (LP: #1827122) + - SAUCE: shiftfs: lock down certain superblock flags + + * Please package libbpf (which is done out of the kernel src) in Debian [for + 19.10] (LP: #1826410) + - SAUCE: tools -- fix add ability to disable libbfd + + * ratelimit cma_alloc messages (LP: #1828092) + - SAUCE: cma: ratelimit cma_alloc error messages + + * Headphone jack switch sense is inverted: plugging in headphones disables + headphone output (LP: #1824259) + - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board + + * There are 4 HDMI/Displayport audio output listed in sound setting without + attach any HDMI/DP monitor (LP: #1827967) + - ALSA: hda/hdmi - Read the pin sense from register when repolling + - ALSA: hda/hdmi - Consider eld_valid when reporting jack event + + * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864) + - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches + + * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error + Checking for all LINUX clients for devops4p10 (LP: #1766201) + - SAUCE: integrity: downgrade error to warning + + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] autoreconstruct -- base tag is always primary mainline version + + * [SRU] Please sync vbox modules from virtualbox 6.0.6 on next kernel update + (LP: #1825210) + - vbox-update: updates for renamed makefiles + - ubuntu: vbox -- update to 6.0.6-dfsg-1 + + * autofs kernel module missing (LP: #1824333) + - [Config] Update autofs4 path in inclusion list + + * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487) + - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch + + * CVE-2019-3874 + - sctp: implement memory accounting on tx path + - sctp: implement memory accounting on rx path + + * apparmor does not start in Disco LXD containers (LP: #1824812) + - SAUCE: shiftfs: use separate llseek method for directories + + * Miscellaneous Ubuntu changes + - [Packaging] autoreconstruct -- remove for -rc kernels + - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation + defined + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates + - [Config] (efi-lockdown): update configs after efi lockdown patch refresh + - [Packaging] don't delete efi_parser.c + - vbox-update -- do not fix up KERN_DIR or KBUILD_EXTMOD + - ubuntu: vbox -- update to 6.0.6-dfsg-2 + - add nvidia-418 dkms build + - remove virtualbox guest drivers + - [Packaging] dkms-build -- expand paths searched for make.log files + - add virtualbox-guest-dkms dkms package build + - enable vbox dkms build for amd64 and i386 + - [Config] update configs for v5.1(-rc7)? rebase + - update dkms package versions + - Add the ability to lock down access to the running kernel image + - Enforce module signatures if the kernel is locked down + - Restrict /dev/{mem,kmem,port} when the kernel is locked down + - kexec_load: Disable at runtime if the kernel is locked down + - Copy secure_boot flag in boot params across kexec reboot + - kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE + - kexec_file: Restrict at runtime if the kernel is locked down + - hibernate: Disable when the kernel is locked down + - uswsusp: Disable when the kernel is locked down + - PCI: Lock down BAR access when the kernel is locked down + - x86: Lock down IO port access when the kernel is locked down + - x86/msr: Restrict MSR access when the kernel is locked down + - ACPI: Limit access to custom_method when the kernel is locked down + - acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down + - acpi: Disable ACPI table override if the kernel is locked down + - acpi: Disable APEI error injection if the kernel is locked down + - Prohibit PCMCIA CIS storage when the kernel is locked down + - Lock down TIOCSSERIAL + - Lock down module params that specify hardware parameters (eg. ioport) + - x86/mmiotrace: Lock down the testmmiotrace module + - Lock down /proc/kcore + - Lock down kprobes + - bpf: Restrict kernel image access functions when the kernel is locked down + - Lock down perf + - debugfs: Restrict debugfs when the kernel is locked down + - lockdown: Print current->comm in restriction messages + - kexec: Allow kexec_file() with appropriate IMA policy when locked down + - Make get_cert_list() not complain about cert lists that aren't present. + - Add efi_status_to_str() and rework efi_status_to_err(). + - Make get_cert_list() use efi_status_to_str() to print error messages. + - efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode + - efi: Lock down the kernel if booted in secure boot mode + - KEYS: Make use of platform keyring for module signature verify + + * Miscellaneous upstream changes + - ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14) + + -- Seth Forshee Tue, 14 May 2019 12:32:56 -0500 + +linux (5.1.0-1.1) eoan; urgency=medium + + * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868) + - [Packaging]: really drop snapdragon + + * Miscellaneous Ubuntu changes + - SAUCE: fix vbox use of MAP_SHARED + - SAUCE: fix vbox use of vm_fault_t + - [Packaging] disable ZFS + - [Packaging] disable nvidia + - SAUCE: perf annotate: Fix build on 32 bit for BPF annotation + - [Config]: updateconfig after rebase to v5.1-rc + - [Config]: build ETNAVIV only on arm platforms + - [Config]: Disable CMA on non-arm platforms + - [Config]: MMC_CQHCI is needed by some built-in drivers + - [Config]: a.out support has been deprecated + - [Config]: R3964 was marked as BROKEN + - [Config]: Add SENSIRION_SGP30 module + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: tools: lib/bpf -- add generated headers to search + path" + - Revert "UBUNTU: SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK" + + -- Thadeu Lima de Souza Cascardo Thu, 25 Apr 2019 10:03:25 -0300 + +linux (5.1.0-0.0) eoan; urgency=medium + + * Dummy entry. + + -- Thadeu Lima de Souza Cascardo Thu, 25 Apr 2019 09:49:47 -0300 + +linux (5.0.0-13.14) disco; urgency=medium + + * linux: 5.0.0-13.14 -proposed tracker (LP: #1824819) + + * Display only has 640x480 (LP: #1824677) + - Revert "UBUNTU: SAUCE: drm/nouveau: Disable nouveau driver by default" + + * shiftfs: use after free when checking mount options (LP: #1824735) + - SAUCE: shiftfs: prevent use-after-free when verifying mount options + + -- Seth Forshee Mon, 15 Apr 2019 09:11:23 -0500 + +linux (5.0.0-12.13) disco; urgency=medium + + * linux: 5.0.0-12.13 -proposed tracker (LP: #1824726) + + * Linux 5.0 black screen on boot, display flickers (i915 regression with + certain laptop panels) (LP: #1824216) + - drm/i915/dp: revert back to max link rate and lane count on eDP + + * kernel BUG at fs/attr.c:287 when using shiftfs (LP: #1824717) + - SAUCE: shiftfs: fix passing of attrs to underaly for setattr + + -- Seth Forshee Sun, 14 Apr 2019 13:38:05 -0500 + +linux (5.0.0-11.12) disco; urgency=medium + + * linux: 5.0.0-11.12 -proposed tracker (LP: #1824383) + + * hns3: PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found [error status=0x1] + (LP: #1824194) + - net: hns3: fix for not calculating tx bd num correctly + + * disco: unable to use iptables/enable ufw under -virtual kernel + (LP: #1823862) + - [Packaging] add bpfilter to linux-modules + + * Make shiftfs a module rather than built-in (LP: #1824354) + - [Config] CONFIG_SHIFT_FS=m + + * shiftfs: chown sets untranslated ids in lower fs (LP: #1824350) + - SAUCE: shiftfs: use translated ids when chaning lower fs attrs + + * [Hyper-V] KVP daemon fails to start on first boot of disco VM (LP: #1820063) + - [Packaging] bind hv_kvp_daemon startup to hv_kvp device + + -- Seth Forshee Thu, 11 Apr 2019 10:17:19 -0500 + +linux (5.0.0-10.11) disco; urgency=medium + + * linux: 5.0.0-10.11 -proposed tracker (LP: #1823936) + + * Apparmor enforcement failure in lxc selftests (LP: #1823379) + - SAUCE: apparmor: Restore Y/N in /sys for apparmor's "enabled" + + * systemd cause kernel trace "BUG: unable to handle kernel paging request at + 6db23a14" on Cosmic i386 (LP: #1813244) + - openvswitch: fix flow actions reallocation + + -- Seth Forshee Tue, 09 Apr 2019 08:30:38 -0500 + +linux (5.0.0-9.10) disco; urgency=medium + + * linux: 5.0.0-9.10 -proposed tracker (LP: #1823228) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] update helper scripts + - [Packaging] resync retpoline extraction + + * Huawei Hi1822 NIC has poor performance (LP: #1820187) + - net-next/hinic: replace disable_irq_nosync/enable_irq + + * Add uid shifting overlay filesystem (shiftfs) (LP: #1823186) + - shiftfs: uid/gid shifting bind mount + - shiftfs: rework and extend + - shiftfs: support some btrfs ioctls + - [Config] enable shiftfs + + * Cannot boot or install - have to use nomodeset (LP: #1821820) + - Revert "drm/i915/fbdev: Actually configure untiled displays" + + * Disco update: v5.0.6 upstream stable release (LP: #1823060) + - netfilter: nf_tables: fix set double-free in abort path + - dccp: do not use ipv6 header for ipv4 flow + - genetlink: Fix a memory leak on error path + - gtp: change NET_UDP_TUNNEL dependency to select + - ipv6: make ip6_create_rt_rcu return ip6_null_entry instead of NULL + - mac8390: Fix mmio access size probe + - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S + - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6 + - net: datagram: fix unbounded loop in __skb_try_recv_datagram() + - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec + - net: phy: meson-gxl: fix interrupt support + - net: rose: fix a possible stack overflow + - net: stmmac: fix memory corruption with large MTUs + - net-sysfs: call dev_hold if kobject_init_and_add success + - net: usb: aqc111: Extend HWID table by QNAP device + - packets: Always register packet sk in the same order + - rhashtable: Still do rehash when we get EEXIST + - sctp: get sctphdr by offset in sctp_compute_cksum + - sctp: use memdup_user instead of vmemdup_user + - tcp: do not use ipv6 header for ipv4 flow + - tipc: allow service ranges to be connect()'ed on RDM/DGRAM + - tipc: change to check tipc_own_id to return in tipc_net_stop + - tipc: fix cancellation of topology subscriptions + - tun: properly test for IFF_UP + - vrf: prevent adding upper devices + - vxlan: Don't call gro_cells_destroy() before device is unregistered + - thunderx: enable page recycling for non-XDP case + - thunderx: eliminate extra calls to put_page() for pages held for recycling + - net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode + - net: mii: Fix PAUSE cap advertisement from linkmode_adv_to_lcl_adv_t() + helper + - net: phy: don't clear BMCR in genphy_soft_reset + - r8169: fix cable re-plugging issue + - ila: Fix rhashtable walker list corruption + - tun: add a missing rcu_read_unlock() in error path + - powerpc/fsl: Fix the flush of branch predictor. + - Btrfs: fix incorrect file size after shrinking truncate and fsync + - btrfs: remove WARN_ON in log_dir_items + - btrfs: don't report readahead errors and don't update statistics + - btrfs: Fix bound checking in qgroup_trace_new_subtree_blocks + - btrfs: Avoid possible qgroup_rsv_size overflow in + btrfs_calculate_inode_block_rsv_size + - Btrfs: fix assertion failure on fsync with NO_HOLES enabled + - locks: wake any locks blocked on request before deadlock check + - tracing: initialize variable in create_dyn_event() + - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time + - powerpc: bpf: Fix generation of load/store DW instructions + - vfio: ccw: only free cp on final interrupt + - NFS: Fix nfs4_lock_state refcounting in nfs4_alloc_{lock,unlock}data() + - NFS: fix mount/umount race in nlmclnt. + - NFSv4.1 don't free interrupted slot on open + - net: dsa: qca8k: remove leftover phy accessors + - ALSA: rawmidi: Fix potential Spectre v1 vulnerability + - ALSA: seq: oss: Fix Spectre v1 vulnerability + - ALSA: pcm: Fix possible OOB access in PCM oss plugins + - ALSA: pcm: Don't suspend stream in unrecoverable PCM state + - ALSA: hda/realtek - Fixed Headset Mic JD not stable + - ALSA: hda/realtek: merge alc_fixup_headset_jack to alc295_fixup_chromebook + - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO + - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB + - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286 + - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286 + - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic + - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256 + - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256 + - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256 + - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops + - kbuild: modversions: Fix relative CRC byte order interpretation + - fs/open.c: allow opening only regular files during execve() + - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock + - scsi: sd: Fix a race between closing an sd device and sd I/O + - scsi: sd: Quiesce warning if device does not report optimal I/O size + - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host + - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP + devices + - drm/rockchip: vop: reset scale mode when win is disabled + - tty/serial: atmel: Add is_half_duplex helper + - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped + - tty: mxs-auart: fix a potential NULL pointer dereference + - tty: atmel_serial: fix a potential NULL pointer dereference + - tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup + - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest + - staging: olpc_dcon_xo_1: add missing 'const' qualifier + - staging: speakup_soft: Fix alternate speech with other synths + - staging: vt6655: Remove vif check from vnt_interrupt + - staging: vt6655: Fix interrupt race condition on device start up. + - staging: erofs: fix to handle error path of erofs_vmap() + - staging: erofs: fix error handling when failed to read compresssed data + - staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir() + - serial: max310x: Fix to avoid potential NULL pointer dereference + - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference + - serial: sh-sci: Fix setting SCSCR_TIE while transferring data + - USB: serial: cp210x: add new device id + - USB: serial: ftdi_sio: add additional NovaTech products + - USB: serial: mos7720: fix mos_parport refcount imbalance on error path + - USB: serial: option: set driver_info for SIM5218 and compatibles + - USB: serial: option: add support for Quectel EM12 + - USB: serial: option: add Olicard 600 + - ACPI / CPPC: Fix guaranteed performance handling + - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc + - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links + - drivers/block/zram/zram_drv.c: fix idle/writeback string compare + - blk-mq: fix sbitmap ws_active for shared tags + - cpufreq: intel_pstate: Also use CPPC nominal_perf for base_frequency + - cpufreq: scpi: Fix use after free + - drm/vgem: fix use-after-free when drm_gem_handle_create() fails + - drm/vkms: fix use-after-free when drm_gem_handle_create() fails + - drm/i915: Mark AML 0x87CA as ULX + - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check + - drm/i915/icl: Fix the TRANS_DDI_FUNC_CTL2 bitfield macro + - gpio: exar: add a check for the return value of ida_simple_get fails + - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input + - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs + - usb: mtu3: fix EXTCON dependency + - USB: gadget: f_hid: fix deadlock in f_hidg_write() + - usb: common: Consider only available nodes for dr_mode + - mm/memory.c: fix modifying of page protection by insert_pfn() + - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk + - xhci: Fix port resume done detection for SS ports with LPM enabled + - usb: xhci: dbc: Don't free all memory with spinlock held + - xhci: Don't let USB3 ports stuck in polling state prevent suspend + - usb: cdc-acm: fix race during wakeup blocking TX traffic + - usb: typec: tcpm: Try PD-2.0 if sink does not respond to 3.0 source-caps + - usb: typec: Fix unchecked return value + - mm/hotplug: fix offline undo_isolate_page_range() + - mm: add support for kmem caches in DMA32 zone + - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging + - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified + - mm/debug.c: fix __dump_page when mapping->host is not set + - mm/memory_hotplug.c: fix notification in offline error path + - mm/page_isolation.c: fix a wrong flag in set_migratetype_isolate() + - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate + - perf pmu: Fix parser error for uncore event alias + - perf intel-pt: Fix TSC slip + - objtool: Query pkg-config for libelf location + - powerpc/pseries/energy: Use OF accessor functions to read ibm,drc-indexes + - powerpc/64: Fix memcmp reading past the end of src/dest + - powerpc/pseries/mce: Fix misleading print for TLB mutlihit + - watchdog: Respect watchdog cpumask on CPU hotplug + - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n + - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y + - KVM: Reject device ioctls from processes other than the VM's creator + - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts + - KVM: x86: update %rip after emulating IO + - bpf: do not restore dst_reg when cur_state is freed + - mt76x02u: use usb_bulk_msg to upload firmware + - Linux 5.0.6 + + * RDMA/hns updates for disco (LP: #1822897) + - RDMA/hns: Fix the bug with updating rq head pointer when flush cqe + - RDMA/hns: Bugfix for the scene without receiver queue + - RDMA/hns: Add constraint on the setting of local ACK timeout + - RDMA/hns: Modify the pbl ba page size for hip08 + - RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db + - RDMA/hns: Add the process of AEQ overflow for hip08 + - RDMA/hns: Add SCC context allocation support for hip08 + - RDMA/hns: Add SCC context clr support for hip08 + - RDMA/hns: Add timer allocation support for hip08 + - RDMA/hns: Remove set but not used variable 'rst' + - RDMA/hns: Make some function static + - RDMA/hns: Fix the Oops during rmmod or insmod ko when reset occurs + - RDMA/hns: Fix the chip hanging caused by sending mailbox&CMQ during reset + - RDMA/hns: Fix the chip hanging caused by sending doorbell during reset + - RDMA/hns: Limit minimum ROCE CQ depth to 64 + - RDMA/hns: Fix the state of rereg mr + - RDMA/hns: Set allocated memory to zero for wrid + - RDMA/hns: Delete useful prints for aeq subtype event + - RDMA/hns: Configure capacity of hns device + - RDMA/hns: Modify qp&cq&pd specification according to UM + - RDMA/hns: Bugfix for set hem of SCC + - RDMA/hns: Use GFP_ATOMIC in hns_roce_v2_modify_qp + + * autopkgtests run too often, too much and don't skip enough (LP: #1823056) + - Set +x on rebuild testcase. + - Skip rebuild test, for regression-suite deps. + - Make ubuntu-regression-suite skippable on unbootable kernels. + - make rebuild use skippable error codes when skipping. + - Only run regression-suite, if requested to. + + * touchpad not working on lenovo yoga 530 (LP: #1787775) + - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI" + - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base" + - i2c: add extra check to safe DMA buffer helper + - i2c: Add drivers for the AMD PCIe MP2 I2C controller + - [Config] Update config for AMD MP2 I2C driver + + * Detect SMP PHY control command errors (LP: #1822680) + - scsi: libsas: Check SMP PHY control function result + + * disable a.out support (LP: #1818552) + - [Config] Disable a.out support + - [Config] remove binfmt_aout from abi for i386 lowlatency + + * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868) + - [Packaging] remove snapdragon flavour support + - Revert "UBUNTU: SAUCE: (snapdragon) drm/msm/adv7511: wrap hacks under + CONFIG_ADV7511_SNAPDRAGON_HACKS #ifdefs" + - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: skip address change if dt + addr == default addr" + - Revert "UBUNTU: SAUCE: (snapdragon) DT: leds: Add Qualcomm Light Pulse + Generator binding" + - Revert "UBUNTU: SAUCE: (snapdragon) MAINTAINERS: Add Qualcomm Camera Control + Interface driver" + - Revert "UBUNTU: SAUCE: (snapdragon) dt-bindings: media: Binding document for + Qualcomm Camera Control Interface driver" + - Revert "UBUNTU: SAUCE: (snapdragon) leds: Add driver for Qualcomm LPG" + - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/adv7511: Don't rely on + interrupts for EDID parsing" + - Revert "UBUNTU: SAUCE: (snapdragon) drm/bridge/adv7511: Delay clearing of + HPD interrupt status" + - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: Fix I2C address" + - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix I2C address bug" + - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix run queue completion + timeout" + - Revert "UBUNTU: SAUCE: (snapdragon) camss: Do not register if no cameras are + present" + - Revert "UBUNTU: SAUCE: (snapdragon) i2c: Add Qualcomm Camera Control + Interface driver" + - Revert "UBUNTU: SAUCE: (snapdragon) ov5645: I2C address change" + - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Allow + REGULATOR_QCOM_SMD_RPM=m" + - Revert "UBUNTU: SAUCE: (snapdragon) cpufreq: Add apq8016 to cpufreq-dt- + platdev blacklist" + - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Add a helper to get an opp + regulator for device" + - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: HACK: Allow to set regulator + without opp_list" + - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Drop RCU usage in + dev_pm_opp_adjust_voltage()" + - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Support adjusting OPP voltages + at runtime" + - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Add floor and corner + operations" + - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Register with cpufreq- + dt" + - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: fix with new + reg_sequence structures" + - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Use raw mem access for + qfprom" + - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: Add support for CPR (Core + Power Reduction)" + - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/iommu: Remove runtime_put + calls in map/unmap" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable LEDS_QCOM_LPG" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'BBR' TCP + congestion algorithm" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'fq' and + 'fq_codel' qdiscs" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable + 'schedutil' CPUfreq governor" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: set USB_CONFIG_F_FS in + distro.config" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable + CONFIG_USB_CONFIGFS_F_FS by default" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add freq stat to sysfs" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: Enable camera drivers" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: disable ANALOG_TV and + DIGITAL_TV" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add more USB net + drivers" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable BT_QCOMSMD" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable + CFG80211_DEFAULT_PS by default" + - Revert "UBUNTU: SAUCE: (snapdragon) Force the SMD regulator driver to be + compiled-in" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: enable dm_mod and + dm_crypt" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: Enable a53/apcs and + avs" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable QCOM Venus" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable debug + friendly USB network adpater" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable WCN36xx" + - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs; add distro.config" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable QCOM audio + drivers for APQ8016 and DB410c" + - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable REMOTEPROC" + - [Config] fix abi for remove i2c-qcom-cci module + - [Config] update annotations + - [Config] update configs following snapdragon removal + + * Disco update: v5.0.5 upstream stable release (LP: #1822671) + - Revert "ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec" + - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist + - ALSA: firewire-motu: use 'version' field of unit directory to identify model + - mmc: pxamci: fix enum type confusion + - mmc: alcor: fix DMA reads + - mmc: mxcmmc: "Revert mmc: mxcmmc: handle highmem pages" + - mmc: renesas_sdhi: limit block count to 16 bit for old revisions + - drm/amdgpu: fix invalid use of change_bit + - drm/vmwgfx: Don't double-free the mode stored in par->set_mode + - drm/vmwgfx: Return 0 when gmrid::get_node runs out of ID's + - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE + - iommu/iova: Fix tracking of recently failed iova address + - libceph: wait for latest osdmap in ceph_monc_blacklist_add() + - udf: Fix crash on IO error during truncate + - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction. + - MIPS: Ensure ELF appended dtb is relocated + - MIPS: Fix kernel crash for R6 in jump label branch function + - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038 + - powerpc/security: Fix spectre_v2 reporting + - net/mlx5: Fix DCT creation bad flow + - scsi: core: Avoid that a kernel warning appears during system resume + - scsi: qla2xxx: Fix FC-AL connection target discovery + - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton + - scsi: ibmvscsi: Fix empty event pool access during host removal + - futex: Ensure that futex address is aligned in handle_futex_death() + - perf probe: Fix getting the kernel map + - objtool: Move objtool_file struct off the stack + - irqchip/gic-v3-its: Fix comparison logic in lpi_range_cmp + - clocksource/drivers/riscv: Fix clocksource mask + - ALSA: ac97: Fix of-node refcount unbalance + - ext4: fix NULL pointer dereference while journal is aborted + - ext4: fix data corruption caused by unaligned direct AIO + - ext4: brelse all indirect buffer in ext4_ind_remove_space() + - media: v4l2-ctrls.c/uvc: zero v4l2_event + - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf() + - Bluetooth: Fix decrementing reference count twice in releasing socket + - Bluetooth: hci_ldisc: Initialize hci_dev before open() + - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in + hci_uart_set_proto() + - drm/vkms: Fix flush_work() without INIT_WORK(). + - RDMA/cma: Rollback source IP address if failing to acquire device + - f2fs: fix to avoid deadlock of atomic file operations + - aio: simplify - and fix - fget/fput for io_submit() + - netfilter: ebtables: remove BUGPRINT messages + - loop: access lo_backing_file only when the loop device is Lo_bound + - x86/unwind: Handle NULL pointer calls better in frame unwinder + - x86/unwind: Add hardcoded ORC entry for NULL + - locking/lockdep: Add debug_locks check in __lock_downgrade() + - ALSA: hda - Record the current power state before suspend/resume calls + - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec + - Linux 5.0.5 + + * hisi_sas updates for disco (LP: #1822385) + - scsi: hisi_sas: send primitive NOTIFY to SSP situation only + - scsi: hisi_sas: shutdown axi bus to avoid exception CQ returned + - scsi: hisi_sas: remove the check of sas_dev status in + hisi_sas_I_T_nexus_reset() + - scsi: hisi_sas: Remove unused parameter of function hisi_sas_alloc() + - scsi: hisi_sas: Reject setting programmed minimum linkrate > 1.5G + - scsi: hisi_sas: Fix losing directly attached disk when hot-plug + - scsi: hisi_sas: Correct memory allocation size for DQ debugfs + - scsi: hisi_sas: Some misc tidy-up + - scsi: hisi_sas: Fix to only call scsi_get_prot_op() for non-NULL scsi_cmnd + - scsi: hisi_sas: Add missing seq_printf() call in hisi_sas_show_row_32() + - scsi: hisi_sas: Add support for DIX feature for v3 hw + - scsi: hisi_sas: Add manual trigger for debugfs dump + - scsi: hisi_sas: change queue depth from 512 to 4096 + - scsi: hisi_sas: Issue internal abort on all relevant queues + - scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw as experimental + - scsi: hisi_sas: Do some more tidy-up + - scsi: hisi_sas: Change return variable type in phy_up_v3_hw() + - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO + - scsi: hisi_sas: print PHY RX errors count for later revision of v3 hw + - scsi: hisi_sas: Set PHY linkrate when disconnected + - scsi: hisi_sas: Send HARD RESET to clear the previous affiliation of STP + target port + - scsi: hisi_sas: Change SERDES_CFG init value to increase reliability of + HiLink + - scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset() + + * [Patch][Raven 2] kernel 5.0.0 cannot boot because of psp response + (LP: #1822267) + - drm/amdgpu/psp: Fix can't detect psp INVOKE command failed + - drm/amdgpu/psp: ignore psp response status + + * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes + triggers system hang on i386 (LP: #1812845) + - btrfs: raid56: properly unmap parity page in finish_parity_scrub() + + * enable CONFIG_DRM_BOCHS (LP: #1795857) + - [Config] Reenable DRM_BOCHS as module + + * [Dell Precision 7530/5530 with Nvidia Quadro P1000] Live USB freezes or + cannot complete install when nouveau driver is loaded (crashing in GP100 + code) (LP: #1822026) + - SAUCE: drm/nouveau: Disable nouveau driver by default + + * Need to add Intel CML related pci-id's (LP: #1821863) + - drm/i915/cml: Add CML PCI IDS + - drm/i915/cml: Introduce Comet Lake PCH + + * ARM: Add support for the SDEI interface (LP: #1822005) + - ACPI / APEI: Don't wait to serialise with oops messages when panic()ing + - ACPI / APEI: Remove silent flag from ghes_read_estatus() + - ACPI / APEI: Switch estatus pool to use vmalloc memory + - ACPI / APEI: Make hest.c manage the estatus memory pool + - ACPI / APEI: Make estatus pool allocation a static size + - ACPI / APEI: Don't store CPER records physical address in struct ghes + - ACPI / APEI: Remove spurious GHES_TO_CLEAR check + - ACPI / APEI: Don't update struct ghes' flags in read/clear estatus + - ACPI / APEI: Generalise the estatus queue's notify code + - ACPI / APEI: Don't allow ghes_ack_error() to mask earlier errors + - ACPI / APEI: Move NOTIFY_SEA between the estatus-queue and NOTIFY_NMI + - ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue + - KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing + - arm64: KVM/mm: Move SEA handling behind a single 'claim' interface + - ACPI / APEI: Move locking to the notification helper + - ACPI / APEI: Let the notification helper specify the fixmap slot + - ACPI / APEI: Pass ghes and estatus separately to avoid a later copy + - ACPI / APEI: Make GHES estatus header validation more user friendly + - ACPI / APEI: Split ghes_read_estatus() to allow a peek at the CPER length + - ACPI / APEI: Only use queued estatus entry during in_nmi_queue_one_entry() + - ACPI / APEI: Use separate fixmap pages for arm64 NMI-like notifications + - firmware: arm_sdei: Add ACPI GHES registration helper + - ACPI / APEI: Add support for the SDEI GHES Notification type + + * CVE-2019-9857 + - inotify: Fix fsnotify_mark refcount leak in inotify_update_existing_watch() + + * scsi: libsas: Support SATA PHY connection rate unmatch fixing during + discovery (LP: #1821408) + - scsi: libsas: Support SATA PHY connection rate unmatch fixing during + discovery + + * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204) + - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list + + * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815) + - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill + + * hid-sensor-hub spamming dmesg in 4.20 (LP: #1818547) + - HID: Increase maximum report size allowed by hid_field_extract() + + * [disco] [5.0.0-7.8] can't mount guest cifs share (LP: #1821053) + - cifs: allow guest mounts to work for smb3.11 + - SMB3: Fix SMB3.1.1 guest mounts to Samba + + * Add HiSilicon SoC quirk for cpufreq (LP: #1821620) + - ACPI / CPPC: Add a helper to get desired performance + - cpufreq / cppc: Work around for Hisilicon CPPC cpufreq + + * Disco update: v5.0.4 upstream stable release (LP: #1821607) + - 9p: use inode->i_lock to protect i_size_write() under 32-bit + - 9p/net: fix memory leak in p9_client_create + - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode + - ASoC: codecs: pcm186x: fix wrong usage of DECLARE_TLV_DB_SCALE() + - ASoC: codecs: pcm186x: Fix energysense SLEEP bit + - iio: adc: exynos-adc: Fix NULL pointer exception on unbind + - iio: adc: exynos-adc: Use proper number of channels for Exynos4x12 + - mei: hbm: clean the feature flags on link reset + - mei: bus: move hw module get/put to probe/release + - stm class: Prevent division by zero + - stm class: Fix an endless loop in channel allocation + - crypto: caam - fix hash context DMA unmap size + - crypto: ccree - fix missing break in switch statement + - crypto: caam - fixed handling of sg list + - crypto: caam - fix DMA mapping of stack memory + - crypto: ccree - fix free of unallocated mlli buffer + - crypto: ccree - unmap buffer before copying IV + - crypto: ccree - don't copy zero size ciphertext + - crypto: cfb - add missing 'chunksize' property + - crypto: cfb - remove bogus memcpy() with src == dest + - crypto: ofb - fix handling partial blocks and make thread-safe + - crypto: ahash - fix another early termination in hash walk + - crypto: rockchip - fix scatterlist nents error + - crypto: rockchip - update new iv to device in multiple operations + - dax: Flush partial PMDs correctly + - nfit: Fix nfit_intel_shutdown_status() command submission + - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place + - acpi/nfit: Fix bus command validation + - nfit/ars: Attempt a short-ARS whenever the ARS state is idle at boot + - nfit/ars: Attempt short-ARS even in the no_init_ars case + - libnvdimm/label: Clear 'updating' flag after label-set update + - libnvdimm, pfn: Fix over-trim in trim_pfn_device() + - libnvdimm/pmem: Honor force_raw for legacy pmem regions + - libnvdimm: Fix altmap reservation size calculation + - fix cgroup_do_mount() handling of failure exits + - crypto: aead - set CRYPTO_TFM_NEED_KEY if ->setkey() fails + - crypto: aegis - fix handling chunked inputs + - crypto: arm/crct10dif - revert to C code for short inputs + - crypto: arm64/aes-neonbs - fix returning final keystream block + - crypto: arm64/crct10dif - revert to C code for short inputs + - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails + - crypto: morus - fix handling chunked inputs + - crypto: pcbc - remove bogus memcpy()s with src == dest + - crypto: skcipher - set CRYPTO_TFM_NEED_KEY if ->setkey() fails + - crypto: testmgr - skip crc32c context test for ahash algorithms + - crypto: x86/aegis - fix handling chunked inputs and MAY_SLEEP + - crypto: x86/aesni-gcm - fix crash on empty plaintext + - crypto: x86/morus - fix handling chunked inputs and MAY_SLEEP + - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling + - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine + - CIFS: Fix leaking locked VFS cache pages in writeback retry + - CIFS: Do not reset lease state to NONE on lease break + - CIFS: Do not skip SMB2 message IDs on send failures + - CIFS: Fix read after write for files with read caching + - smb3: make default i/o size for smb3 mounts larger + - tracing: Use strncpy instead of memcpy for string keys in hist triggers + - tracing: Do not free iter->trace in fail path of tracing_open_pipe() + - tracing/perf: Use strndup_user() instead of buggy open-coded version + - vmw_balloon: release lock on error in vmballoon_reset() + - xen: fix dom0 boot on huge systems + - ACPI / device_sysfs: Avoid OF modalias creation for removed device + - mmc: sdhci-esdhc-imx: fix HS400 timing issue + - mmc: renesas_sdhi: Fix card initialization failure in high speed mode + - mmc:fix a bug when max_discard is 0 + - spi: ti-qspi: Fix mmap read when more than one CS in use + - spi: pxa2xx: Setup maximum supported DMA transfer length + - spi: omap2-mcspi: Fix DMA and FIFO event trigger size mismatch + - spi: spi-gpio: fix SPI_CS_HIGH capability + - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35 + - regulator: max77620: Initialize values for DT properties + - regulator: s2mpa01: Fix step values for some LDOs + - mt76: fix corrupted software generated tx CCMP PN + - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR + - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown + - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer + instability + - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem + - s390/setup: fix early warning messages + - s390/virtio: handle find on invalid queue gracefully + - scsi: virtio_scsi: don't send sc payload with tmfs + - scsi: aacraid: Fix performance issue on logical drives + - scsi: sd: Optimal I/O size should be a multiple of physical block size + - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock + - scsi: qla2xxx: Fix LUN discovery if loop id is not assigned yet by firmware + - scsi: qla2xxx: Avoid PCI IRQ affinity mapping when multiqueue is not + supported + - scsi: qla2xxx: Use complete switch scan for RSCN events + - fs/devpts: always delete dcache dentry-s in dput() + - splice: don't merge into linked buffers + - ovl: During copy up, first copy up data and then xattrs + - ovl: Do not lose security.capability xattr over metadata file copy-up + - m68k: Add -ffreestanding to CFLAGS + - Btrfs: setup a nofs context for memory allocation at btrfs_create_tree() + - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl + - btrfs: scrub: fix circular locking dependency warning + - btrfs: drop the lock on error in btrfs_dev_replace_cancel + - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes + - btrfs: init csum_list before possible free + - Btrfs: fix corruption reading shared and compressed extents after hole + punching + - Btrfs: fix deadlock between clone/dedupe and rename + - soc: qcom: rpmh: Avoid accessing freed memory from batch API + - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer + - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table + - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code + - x86/kprobes: Prohibit probing on optprobe template code + - cpufreq: kryo: Release OPP tables on module removal + - cpufreq: tegra124: add missing of_node_put() + - cpufreq: pxa2xx: remove incorrect __init annotation + - ext4: fix check of inode in swap_inode_boot_loader + - ext4: cleanup pagecache before swap i_data + - mm: hwpoison: fix thp split handing in soft_offline_in_use_page() + - mm/vmalloc: fix size check for remap_vmalloc_range_partial() + - mm/memory.c: do_fault: avoid usage of stale vm_area_struct + - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv + - nvmem: core: don't check the return value of notifier chain call + - device property: Fix the length used in PROPERTY_ENTRY_STRING() + - intel_th: Don't reference unassigned outputs + - parport_pc: fix find_superio io compare code, should use equal test. + - i2c: tegra: fix maximum transfer size + - i2c: tegra: update maximum transfer size + - media: i2c: ov5640: Fix post-reset delay + - gpio: pca953x: Fix dereference of irq data in shutdown + - ext4: update quota information while swapping boot loader inode + - ext4: add mask of ext4 flags to swap + - ext4: fix crash during online resizing + - dma: Introduce dma_max_mapping_size() + - swiotlb: Introduce swiotlb_max_mapping_size() + - swiotlb: Add is_swiotlb_active() function + - PCI/ASPM: Use LTR if already enabled by platform + - PCI/DPC: Fix print AER status in DPC event handling + - PCI: qcom: Don't deassert reset GPIO during probe + - PCI: dwc: skip MSI init if MSIs have been explicitly disabled + - PCI: pci-bridge-emul: Create per-bridge copy of register behavior + - PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags + - IB/hfi1: Close race condition on user context disable and close + - IB/rdmavt: Fix loopback send with invalidate ordering + - IB/rdmavt: Fix concurrency panics in QP post_send and modify to error + - cxl: Wrap iterations over afu slices inside 'afu_list_lock' + - ext2: Fix underflow in ext2_max_size() + - clk: uniphier: Fix update register for CPU-gear + - clk: clk-twl6040: Fix imprecise external abort for pdmclk + - clk: samsung: exynos5: Fix possible NULL pointer exception on + platform_device_alloc() failure + - clk: samsung: exynos5: Fix kfree() of const memory on setting + driver_override + - clk: ingenic: Fix round_rate misbehaving with non-integer dividers + - clk: ingenic: Fix doc of ingenic_cgu_div_info + - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() + - usb: typec: tps6598x: handle block writes separately with plain-I2C adapters + - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit + - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO + - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart + - serial: 8250_pci: Fix number of ports for ACCES serial cards + - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954 + chip use the pci_pericom_setup() + - jbd2: clear dirty flag when revoking a buffer from an older transaction + - jbd2: fix compile warning when using JBUFFER_TRACE + - selinux: add the missing walk_size + len check in selinux_sctp_bind_connect + - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock + - powerpc/32: Clear on-stack exception marker upon exception return + - powerpc/wii: properly disable use of BATs when requested. + - powerpc/powernv: Make opal log only readable by root + - powerpc/83xx: Also save/restore SPRG4-7 during suspend + - powerpc/kvm: Save and restore host AMR/IAMR/UAMOR + - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit + - powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction + - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest + - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning + - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR + configuration + - powerpc/smp: Fix NMI IPI timeout + - powerpc/smp: Fix NMI IPI xmon timeout + - powerpc/traps: fix recoverability of machine check handling on book3s/32 + - powerpc/traps: Fix the message printed when stack overflows + - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify + - arm64: Fix HCR.TGE status for NMI contexts + - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals + - arm64: debug: Ensure debug handlers check triggering exception level + - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2 + - Revert "KVM/MMU: Flush tlb directly in the kvm_zap_gfn_range()" + - ipmi_si: Fix crash when using hard-coded device + - ipmi_si: fix use-after-free of resource->name + - dm: fix to_sector() for 32bit + - dm integrity: limit the rate of error messages + - media: cx25840: mark pad sig_types to fix cx231xx init + - mfd: sm501: Fix potential NULL pointer dereference + - cpcap-charger: generate events for userspace + - cpuidle: governor: Add new governors to cpuidle_governors again + - NFS: Fix I/O request leakages + - NFS: Fix an I/O request leakage in nfs_do_recoalesce + - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror() + - nfsd: fix performance-limiting session calculation + - nfsd: fix memory corruption caused by readdir + - nfsd: fix wrong check in write_v4_end_grace() + - NFSv4.1: Reinitialise sequence results before retransmitting a request + - svcrpc: fix UDP on servers with lots of threads + - PM / wakeup: Rework wakeup source timer cancellation + - PM / OPP: Update performance state when freq == old_freq + - bcache: treat stale && dirty keys as bad keys + - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata + - stable-kernel-rules.rst: add link to networking patch queue + - vt: perform safe console erase in the right order + - x86/unwind/orc: Fix ORC unwind table alignment + - perf intel-pt: Fix CYC timestamp calculation after OVF + - perf tools: Fix split_kallsyms_for_kcore() for trampoline symbols + - perf auxtrace: Define auxtrace record alignment + - perf intel-pt: Fix overlap calculation for padding + - perf/x86/intel/uncore: Fix client IMC events return huge result + - perf intel-pt: Fix divide by zero when TSC is not available + - md: Fix failed allocation of md_register_thread + - x86/kvmclock: set offset for kvm unstable clock + - x86/ftrace: Fix warning and considate ftrace_jmp_replace() and + ftrace_call_replace() + - tpm/tpm_crb: Avoid unaligned reads in crb_recv() + - tpm: Unify the send callback behaviour + - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt + - media: imx: prpencvf: Stop upstream before disabling IDMA channel + - media: lgdt330x: fix lock status reporting + - media: sun6i: Fix CSI regmap's max_register + - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming + - media: vimc: Add vimc-streamer for stream control + - media: imx-csi: Input connections to CSI should be optional + - media: imx: csi: Disable CSI immediately after last EOF + - media: imx: csi: Stop upstream before disabling IDMA channel + - drm/fb-helper: generic: Fix drm_fbdev_client_restore() + - drm/radeon/evergreen_cs: fix missing break in switch statement + - drm/amd/powerplay: correct power reading on fiji + - drm/amd/display: don't call dm_pp_ function from an fpu block + - KVM: Call kvm_arch_memslots_updated() before updating memslots + - KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run + - KVM: VMX: Zero out *all* general purpose registers after VM-Exit + - KVM: x86/mmu: Detect MMIO generation wrap in any address space + - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux + - KVM: nVMX: Sign extend displacements of VMX instr's mem operands + - KVM: nVMX: Apply addr size mask to effective address for VMX instructions + - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments + - KVM: nVMX: Check a single byte for VMCS "launched" in nested early checks + - net: dsa: lantiq_gswip: fix use-after-free on failed probe + - net: dsa: lantiq_gswip: fix OF child-node lookups + - s390/setup: fix boot crash for machine without EDAT-1 + - SUNRPC: Prevent thundering herd when the socket is not connected + - SUNRPC: Fix up RPC back channel transmission + - SUNRPC: Respect RPC call timeouts when retrying transmission + - Linux 5.0.4 + - [Config] update configs for 5.0.4 stable update + + * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu + system (LP: #1821271) + - iwlwifi: add new card for 9260 series + + * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881) + - [Config]: enable highdpi Terminus 16x32 font support + + * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990) + - iommu/amd: Fix NULL dereference bug in match_hid_uid + + * some codecs stop working after S3 (LP: #1820930) + - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec + - ALSA: hda - Don't trigger jackpoll_work in azx_resume + + * tcm_loop.ko: move from modules-extra into main modules package + (LP: #1817786) + - [Packaging] move tcm_loop.lo to main linux-modules package + + * C++ demangling support missing from perf (LP: #1396654) + - [Packaging] fix a mistype + + * r8169 doesn't get woken up by ethernet cable plugging, no PME generated + (LP: #1817676) + - PCI: pciehp: Disable Data Link Layer State Changed event on suspend + + * Disco update: v5.0.3 upstream stable release (LP: #1821074) + - connector: fix unsafe usage of ->real_parent + - fou, fou6: avoid uninit-value in gue_err() and gue6_err() + - gro_cells: make sure device is up in gro_cells_receive() + - ipv4/route: fail early when inet dev is missing + - l2tp: fix infoleak in l2tp_ip6_recvmsg() + - lan743x: Fix RX Kernel Panic + - lan743x: Fix TX Stall Issue + - net: hsr: fix memory leak in hsr_dev_finalize() + - net/hsr: fix possible crash in add_timer() + - net: sit: fix UBSAN Undefined behaviour in check_6rd + - net/x25: fix use-after-free in x25_device_event() + - net/x25: reset state in x25_connect() + - pptp: dst_release sk_dst_cache in pptp_sock_destruct + - ravb: Decrease TxFIFO depth of Q3 and Q2 to one + - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race + - rxrpc: Fix client call queueing, waiting for channel + - sctp: remove sched init from sctp_stream_init + - tcp: do not report TCP_CM_INQ of 0 for closed connections + - tcp: Don't access TCP_SKB_CB before initializing it + - tcp: handle inet_csk_reqsk_queue_add() failures + - vxlan: Fix GRO cells race condition between receive and link delete + - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() + - net/mlx4_core: Fix reset flow when in command polling mode + - net/mlx4_core: Fix locking in SRIOV mode when switching between events and + polling + - net/mlx4_core: Fix qp mtt size calculation + - net: dsa: mv88e6xxx: Set correct interface mode for CPU/DSA ports + - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock + - net: sched: flower: insert new filter to idr after setting its mask + - f2fs: wait on atomic writes to count F2FS_CP_WB_DATA + - perf/x86: Fixup typo in stub functions + - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against + Liquid Saffire 56 + - ALSA: firewire-motu: fix construction of PCM frame for capture direction + - ALSA: hda: Extend i915 component bind timeout + - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240 + - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294 + - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone + - ALSA: hda/realtek: Enable headset MIC of Acer TravelMate X514-51T with + ALC255 + - perf/x86/intel: Fix memory corruption + - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static + - It's wrong to add len to sector_nr in raid10 reshape twice + - drm: Block fb changes for async plane updates + - Linux 5.0.3 + + * Disco update: v5.0.2 upstream stable release (LP: #1820318) + - media: uvcvideo: Fix 'type' check leading to overflow + - Input: wacom_serial4 - add support for Wacom ArtPad II tablet + - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20 + - iscsi_ibft: Fix missing break in switch statement + - scsi: aacraid: Fix missing break in switch statement + - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub + - arm64: dts: zcu100-revC: Give wifi some time after power-on + - arm64: dts: hikey: Give wifi some time after power-on + - arm64: dts: hikey: Revert "Enable HS200 mode on eMMC" + - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3 + - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU + - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4 + - drm: disable uncached DMA optimization for ARM and arm64 + - media: Revert "media: rc: some events are dropped by userspace" + - Revert "PCI/PME: Implement runtime PM callbacks" + - bpf: Stop the psock parser before canceling its work + - gfs2: Fix missed wakeups in find_insert_glock + - staging: erofs: keep corrupted fs from crashing kernel in erofs_namei() + - staging: erofs: compressed_pages should not be accessed again after freed + - scripts/gdb: replace flags (MS_xyz -> SB_xyz) + - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom + - perf/x86/intel: Make cpuc allocations consistent + - perf/x86/intel: Generalize dynamic constraint creation + - x86: Add TSX Force Abort CPUID/MSR + - perf/x86/intel: Implement support for TSX Force Abort + - Linux 5.0.2 + + * Linux security module stacking support + - LSM: Introduce LSM_FLAG_LEGACY_MAJOR + - LSM: Provide separate ordered initialization + - LSM: Plumb visibility into optional "enabled" state + - LSM: Lift LSM selection out of individual LSMs + - LSM: Build ordered list of LSMs to initialize + - LSM: Introduce CONFIG_LSM + - LSM: Introduce "lsm=" for boottime LSM selection + - LSM: Tie enabling logic to presence in ordered list + - LSM: Prepare for reorganizing "security=" logic + - LSM: Refactor "security=" in terms of enable/disable + - LSM: Separate idea of "major" LSM from "exclusive" LSM + - apparmor: Remove SECURITY_APPARMOR_BOOTPARAM_VALUE + - selinux: Remove SECURITY_SELINUX_BOOTPARAM_VALUE + - LSM: Add all exclusive LSMs to ordered initialization + - LSM: Split LSM preparation from initialization + - LoadPin: Initialize as ordered LSM + - Yama: Initialize as ordered LSM + - LSM: Introduce enum lsm_order + - capability: Initialize as LSM_ORDER_FIRST + - procfs: add smack subdir to attrs + - Smack: Abstract use of cred security blob + - SELinux: Abstract use of cred security blob + - SELinux: Remove cred security blob poisoning + - SELinux: Remove unused selinux_is_enabled + - AppArmor: Abstract use of cred security blob + - TOMOYO: Abstract use of cred security blob + - Infrastructure management of the cred security blob + - SELinux: Abstract use of file security blob + - Smack: Abstract use of file security blob + - LSM: Infrastructure management of the file security + - SELinux: Abstract use of inode security blob + - Smack: Abstract use of inode security blob + - LSM: Infrastructure management of the inode security + - LSM: Infrastructure management of the task security + - SELinux: Abstract use of ipc security blobs + - Smack: Abstract use of ipc security blobs + - LSM: Infrastructure management of the ipc security blob + - TOMOYO: Update LSM flags to no longer be exclusive + - LSM: generalize flag passing to security_capable + - LSM: Make lsm_early_cred() and lsm_early_task() local functions. + - LSM: Make some functions static + - apparmor: Adjust offset when accessing task blob. + - LSM: Ignore "security=" when "lsm=" is specified + - LSM: Update list of SECURITYFS users in Kconfig + - apparmor: delete the dentry in aafs_remove() to avoid a leak + - apparmor: fix double free when unpack of secmark rules fails + - SAUCE: LSM: Infrastructure management of the sock security + - SAUCE: LSM: Limit calls to certain module hooks + - SAUCE: LSM: Special handling for secctx lsm hooks + - SAUCE: LSM: Specify which LSM to display with /proc/self/attr/display + - SAUCE: Fix-up af_unix mediation for sock infrastructure management + - SAUCE: Revert "apparmor: Fix warning about unused function + apparmor_ipv6_postroute" + - SAUCE: Revert "apparmor: fix checkpatch error in Parse secmark policy" + - SAUCE: Revert "apparmor: add #ifdef checks for secmark filtering" + - SAUCE: Revert "apparmor: Allow filtering based on secmark policy" + - SAUCE: Revert "apparmor: Parse secmark policy" + - SAUCE: Revert "apparmor: Add a wildcard secid" + - SAUCE: Revert "apparmor: fix bad debug check in apparmor_secid_to_secctx()" + - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR" + - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids" + - SAUCE: Revert "apparmor: Fix memory leak of rule on error exit path" + - SAUCE: Revert "apparmor: modify audit rule support to support profile + stacks" + - SAUCE: Revert "apparmor: Add support for audit rule filtering" + - SAUCE: Revert "apparmor: add the ability to get a task's secid" + - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes" + - SAUCE: apparmor: add proc subdir to attrs + - SAUCE: apparmor: add an apparmorfs entry to access current attrs + - SAUCE: apparmor: update flags to no longer be exclusive + - SAUCE: update configs and annotations for LSM stacking + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_EARLY_PRINTK_USB_XDBC=y + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - [Config] CONFIG_RANDOM_TRUST_CPU=y + - [Config] refresh annotations for recent config changes + - ubuntu: vbox -- update to 6.0.4-dfsg-7 + - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for + upcoming platform" + + -- Seth Forshee Thu, 04 Apr 2019 14:49:59 -0500 + +linux (5.0.0-8.9) disco; urgency=medium + + * linux: 5.0.0-8.9 -proposed tracker (LP: #1819759) + + * hisi_sas: add debugfs support (LP: #1819500) + - scsi: hisi_sas: Create root and device debugfs directories + - scsi: hisi_sas: Alloc debugfs snapshot buffer memory for all registers + - scsi: hisi_sas: Take debugfs snapshot for all regs + - scsi: hisi_sas: Debugfs global register create file and add file operations + - scsi: hisi_sas: Add debugfs for port registers + - scsi: hisi_sas: Add debugfs CQ file and add file operations + - scsi: hisi_sas: Add debugfs DQ file and add file operations + - scsi: hisi_sas: Add debugfs IOST file and add file operations + - scsi: hisi_sas: No need to check return value of debugfs_create functions + - scsi: hisi_sas: Fix type casting and missing static qualifier in debugfs + code + - scsi: hisi_sas: Add debugfs ITCT file and add file operations + + * [disco] hns driver updates from 5.1 merge window (LP: #1819535) + - net: hns: Use struct_size() in devm_kzalloc() + - net: hns3: modify enet reinitialization interface + - net: hns3: remove unused member in struct hns3_enet_ring + - net: hns3: remove unnecessary hns3_adjust_tqps_num + - net: hns3: reuse reinitialization interface in the hns3_set_channels + - net: hns3: add interface hclge_tm_bp_setup + - net: hns3: modify parameter checks in the hns3_set_channels + - net: hns3: remove redundant codes in hclge_knic_setup + - net: hns3: fix user configuration loss for ethtool -L + - net: hns3: adjust the use of alloc_tqps and num_tqps + - net: hns3: fix wrong combined count returned by ethtool -l + - net: hns3: do reinitialization while ETS configuration changed + - net: hns3: add HNAE3_RESTORE_CLIENT interface in enet module + - net: hns3: add calling roce callback function when link status change + - net: hns3: add rx multicast packets statistic + - net: hns3: refactor the statistics updating for netdev + - net: hns3: fix rss configuration lost problem when setting channel + - net: hns3: fix for shaper not setting when TC num changes + - net: hns3: fix bug of ethtool_ops.get_channels for VF + - net: hns3: clear param in ring when free ring + - net: hns3: Change fw error code NOT_EXEC to NOT_SUPPORTED + - net: hns3: do not return GE PFC setting err when initializing + - net: hns3: add ETS TC weight setting in SSU module + - net: hns3: add statistics for PFC frames and MAC control frames + - net: hns3: fix PFC not setting problem for DCB module + - net: hns3: don't update packet statistics for packets dropped by hardware + - net: hns3: clear pci private data when unload hns3 driver + - net: hns3: add error handling in hclge_ieee_setets + - net: hns3: fix return value handle issue for hclge_set_loopback() + - net: hns3: fix broadcast promisc issue for revision 0x20 + - net: hns3: After setting the loopback, add the status of getting MAC + - net: hns3: do reinitialization while mqprio configuration changed + - net: hns3: remove dcb_ops->map_update in hclge_dcb + - net: hns3: call hns3_nic_set_real_num_queue with netdev down + - net: hns3: add 8 BD limit for tx flow + - net: hns3: add initialization for nic state + - net: hns3: don't allow vf to enable promisc mode + - net: hns3: reuse the definition of l3 and l4 header info union + - net: hns3: fix VF dump register issue + - net: hns3: use the correct interface to stop|open port + - net: hns3: change hnae3_register_ae_dev() to int + - net: hns3: only support tc 0 for VF + - net: hns3: Fix NULL deref when unloading driver + - net: hns3: fix netif_napi_del() not do problem when unloading + - net: hns3: fix for rss result nonuniform + - net: hns3: fix improper error handling in the hclge_init_ae_dev() + - net: hns3: fix an issue for hclgevf_ae_get_hdev + - net: hns3: stop sending keep alive msg to PF when VF is resetting + - net: hns3: keep flow director state unchanged when reset + - net: hns3: Check for allocation failure + - net: hns3: fix a code style issue for hns3_update_new_int_gl() + - net: hns3: fix an issue for hns3_update_new_int_gl + - net: hns3: Modify parameter type from int to bool in set_gro_en + - net: hns3: code optimization for hclge_rx_buffer_calc + - net: hns3: add hclge_cmd_check_retval() to parse comman's return value + - net: hns3: move some set_bit statement into hclge_prepare_mac_addr + - net: hns3: fix a wrong checking in the hclge_tx_buffer_calc() + - net: hns3: fix the problem that the supported port is empty + - net: hns3: optimize the maximum TC macro + - net: hns3: don't allow user to change vlan filter state + - net: hns3: modify the upper limit judgment condition + - net: hns3: MAC table entry count function increases operation 0 value + protection measures + - net: hns3: make function hclge_set_all_vf_rst() static + - net: hns3: add pointer checking at the beginning of the exported functions. + - net: hns3: Check variable is valid before assigning it to another + - net: hns3: convert mac advertize and supported from u32 to link mode + - net: hns3: fix port info query issue for copper port + - net: hns3: modify print message of ssu common ecc errors + - net: hns3: some bugfix of ppu(rcb) ras errors + - net: hns3: enable 8~11th bit of mac common msi-x error + - net: hns3: fix 6th bit of ppp mpf abnormal errors + - net: hns3: Record VF unicast and multicast tables + - net: hns3: Record VF vlan tables + - net: hns3: uninitialize command queue while unloading PF driver + - net: hns3: clear command queue's registers when unloading VF driver + - net: hns3: add xps setting support for hns3 driver + - net: hns3: avoid mult + div op in critical data path + - net: hns3: limit some variable scope in critical data path + - net: hns3: remove some ops in struct hns3_nic_ops + - net: hns3: add unlikely for error handling in data path + - net: hns3: replace hnae3_set_bit and hnae3_set_field in data path + - net: hns3: remove hnae3_get_bit in data path + - net: hns3: add support to config depth for tx|rx ring separately + - net: hns3: enable VF VLAN filter for each VF when initializing + - net: hns3: fix get VF RSS issue + - net: hns3: fix setting of the hns reset_type for rdma hw errors + - net: hns3: fix improper error handling for hns3_client_start + - net: hns: use struct_size() in devm_kzalloc() + - net: hns3: Fix a logical vs bitwise typo + - net: hns3: add dma_rmb() for rx description + - net: hns3: fix to stop multiple HNS reset due to the AER changes + + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] dkms-build -- support building against packages in PPAs + - [Packaging] dkms-build: do not redownload files on subsequent passes + - [Packaging] dkms-build -- elide partial Built-Using information + - [Packaging] dkms-build -- remove retpoline data from final binary packages + - [Packaging] dkms-build--nvidia* -- check gcc version against primary build + - [Packaging] dkms-build -- add support for unversioned overrides + - [Packaging] dkms-build--nvidia-* -- convert to generic -N form + - [Packaging] fix-filenames -- handle exact string removal + - [Packaging] dkms-build--nvidia-N -- remove GCC versions + + * Disco update: v5.0.1 upstream stable release (LP: #1819515) + - cpufreq: Use struct kobj_attribute instead of struct global_attr + - staging: erofs: fix mis-acted TAIL merging behavior + - binder: create node flag to request sender's security context + - USB: serial: option: add Telit ME910 ECM composition + - USB: serial: cp210x: add ID for Ingenico 3070 + - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485 + - driver core: Postpone DMA tear-down until after devres release + - staging: erofs: fix fast symlink w/o xattr when fs xattr is on + - staging: erofs: fix memleak of inode's shared xattr array + - staging: erofs: fix race of initializing xattrs of a inode at the same time + - staging: erofs: fix illegal address access under memory pressure + - staging: comedi: ni_660x: fix missing break in switch statement + - staging: wilc1000: fix to set correct value for 'vif_num' + - staging: android: ion: fix sys heap pool's gfp_flags + - staging: android: ashmem: Don't call fallocate() with ashmem_mutex held. + - staging: android: ashmem: Avoid range_alloc() allocation with ashmem_mutex + held. + - ip6mr: Do not call __IP6_INC_STATS() from preemptible context + - net: dsa: mv88e6xxx: add call to mv88e6xxx_ports_cmode_init to probe for new + DSA framework + - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in + mv88e6xxx_port_set_duplex + - net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family + - net: mscc: Enable all ports in QSGMII + - net: sched: put back q.qlen into a single location + - net-sysfs: Fix mem leak in netdev_register_kobject + - qmi_wwan: Add support for Quectel EG12/EM12 + - sctp: call iov_iter_revert() after sending ABORT + - team: Free BPF filter when unregistering netdev + - tipc: fix RDM/DGRAM connect() regression + - x86/CPU/AMD: Set the CPB bit unconditionally on F17h + - x86/boot/compressed/64: Do not read legacy ROM on EFI system + - tracing: Fix event filters and triggers to handle negative numbers + - xhci: tegra: Prevent error pointer dereference + - usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on + INTEL_SUNRISEPOINT_LP_XHCI + - applicom: Fix potential Spectre v1 vulnerabilities + - alpha: wire up io_pgetevents system call + - MIPS: irq: Allocate accurate order pages for irq stack + - aio: Fix locking in aio_poll() + - xtensa: fix get_wchan + - gnss: sirf: fix premature wakeup interrupt enable + - USB: serial: cp210x: fix GPIO in autosuspend + - Revert "selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to + config" + - Revert "selftests: firmware: remove use of non-standard diff -Z option" + - selftests: firmware: fix verify_reqs() return value + - Bluetooth: btrtl: Restore old logic to assume firmware is already loaded + - Bluetooth: Fix locking in bt_accept_enqueue() for BH context + - Linux 5.0.1 + + * sky2 ethernet card doesn't work after returning from suspend + (LP: #1807259) // sky2 ethernet card link not up after suspend + (LP: #1809843) // Disco update: v5.0.1 upstream stable release + (LP: #1819515) + - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79 + + * tls selftest failures/hangs on i386 (LP: #1813607) + - [Config] CONFIG_TLS=n for i386 + + * CVE-2019-8980 + - exec: Fix mem leak in kernel_read_file + + * Miscellaneous Ubuntu changes + - SAUCE: selftests: net: Use 'ipproto ipv6-icmp' to match ICMPv6 headers + - [Config] enable nvidia build + - [Config] update gcc version to 8.3 + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: selftests: pmtu: disable accept_dad for tests" + + -- Thadeu Lima de Souza Cascardo Tue, 12 Mar 2019 16:15:44 -0300 + +linux (5.0.0-7.8) disco; urgency=medium + + * linux: 5.0.0-7.8 -proposed tracker (LP: #1818519) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * unnecessary request_queue freeze (LP: #1815733) + - block: avoid setting nr_requests to current value + - block: avoid setting none scheduler if it's already none + + * Miscellaneous Ubuntu changes + - SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on xfail + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.0 + + -- Seth Forshee Mon, 04 Mar 2019 08:46:10 -0600 + +linux (5.0.0-6.7) disco; urgency=medium + + * linux: 5.0.0-6.7 -proposed tracker (LP: #1817585) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] resync getabis + + * installer does not support iSCSI iBFT (LP: #1817321) + - d-i: add iscsi_ibft to scsi-modules + + * Silent "Unknown key" message when pressing keyboard backlight hotkey + (LP: #1817063) + - platform/x86: dell-wmi: Ignore new keyboard backlight change event + + * Fix I219 doesn't get woken up after plugging ethernet cable (LP: #1817058) + - e1000e: Disable runtime PM on CNP+ + + * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982) + - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted + + * CVE-2019-3460 + - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt + + * CVE-2019-3459 + - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer + + * kernel net tls selftest fails on 5.0 (LP: #1816716) + - SAUCE: Revert "selftests/tls: Add test for recv(PEEK) spanning across + multiple records" + + * Please enable CONFIG_DMA_CMA=y on arm64 (LP: #1803206) + - [Config] annotations -- enforce CONFIG_DMA_CMA and update notes + + * [19.04 FEAT] [LS1801] PCI Virtual function enablement (LP: #1814684) + - s390/pci: map IOV resources + - s390/pci: improve bar check + + * glibc 2.28-0ubuntu1 ADT test failure with linux 5.0.0-1.2 (LP: #1813060) + - SAUCE: prevent a glibc test failure when looking for obsolete types on + headers + + * Miscellaneous Ubuntu changes + - [Config] Enforce CONFIG_ZCRYPT_MULTIDEVNODES in annotations + - SAUCE: selftests: pmtu: disable accept_dad for tests + - SAUCE: arm64: add kernel config option to lock down when in Secure Boot mode + - SAUCE: selftests: net: Make test for VXLAN underlay in non-default VRF an + expected failure + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc8 + + -- Seth Forshee Mon, 25 Feb 2019 09:37:36 -0600 + +linux (5.0.0-5.6) disco; urgency=medium + + * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831) + - ALSA: hda/realtek - Headset microphone and internal speaker support for + System76 oryp5 + + * Miscellaneous Ubuntu changes + - [Config] Fix aufs menus in annotations file + - [Config] CONFIG_SAMPLE_TRACE_PRINTK=m + - [Config] Update annotations based on configs + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc7 + + -- Seth Forshee Mon, 18 Feb 2019 10:04:11 +0100 + +linux (5.0.0-4.5) disco; urgency=medium + + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] autoreconstruct -- base tag is always primary mainline version + + * [Packaging] Allow overlay of config annotations (LP: #1752072) + - [Packaging] config-check: Add an include directive + + * Miscellaneous Ubuntu changes + - hio -- stub out BIOVEC_PHYS_MERGEABLE for 4.20+ + - hio -- replace use of do_gettimeofday() + - hio -- part_round_stats() removed in 5.0 + - hio -- device_add_disk() grew a 'groups' argument in 4.20 + - enable hio build + - Revert "UBUNTU: [Packaging] autoreconstruct -- base tag is always primary + mainline version" + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc6 + + -- Seth Forshee Tue, 12 Feb 2019 08:15:32 -0600 + +linux (5.0.0-3.4) disco; urgency=medium + + * CONFIG_TEST_BPF is disabled (LP: #1813955) + - [Config]: Reenable TEST_BPF + + * Ignore "incomplete report" from Elan touchpanels (LP: #1813733) + - HID: i2c-hid: Ignore input report if there's no data present on Elan + touchpanels + + * SecureBoot support for arm64 (LP: #1804481) + - Build signed kernels for arm64 + + * Miscellaneous Ubuntu changes + - SAUCE: selftests: net: fix "from" match test in fib_rule_tests.sh + - [Config] CONFIG_PCMCIA=n for arm64 and s390x + - [Config] CONFIG_SERIAL_SC16IS7XX=n for s390x + - [Config] disable I2C TPM drivers for s390x + - [Config] CONFIG_RAPIDIO=n for s390x + - [Config] CONFIG_DMADEVICES=n for s390x + - [Config] disable gpio drivers for s390x + - [Config] CONFIG_SENSORS_OCC_P8_I2C=m for ppc64el + - [Config] disable I2C hardware drivers for s390x + - [Config] CONFIG_I3C=n for s390x + - [Config] CONFIG_SERIO=n for s390x + - [Config] disable misc drivers for s390x + - [Config] disable EEPROM drivers for s390x + - [Config] disable MFD drivers for s390x + - [Config] CONFIG_NVMEM=n for s390x + - [Config] CONFIG_MLXSW_I2C=n for s390x + - [Config] CONFIG_NET_VENDOR_MICROCHIP=n for s390x + - [Config] CONFIG_PPP=n for s390x + - [Config] CONFIG_PCCARD=n for s390x + - [Config] CONFIG_PCI_MESON=y + - [Config] CONFIG_SCSI_MYRB=n for s390x + - [Config] CONFIG_REGULATOR=n for s390x + - [Config] CONFIG_ZIIRAVE_WATCHDOG=n for s390x + - [Config] CONFIG_NCSI_OEM_CMD_GET_MAC=y + - [Config] update annotations following config review + - [Packaging] remove handoff check for uefi signing + - [Packaging] decompress gzipped efi images in signing tarball + - vbox-update: allow leading whitespace when fixing up KERN_DIR + - ubuntu: vbox -- update to 6.0.4-dfsg-3 + - vbox: remove remount check in sf_read_super_aux() + - enable vbox build + - [Config] CONFIG_ANDROID_BINDER_DEVICES="" + - SAUCE: import aufs driver + - [Config]: Enable aufs + - [Config] relocate aufs annotations to menu + - [Config] remove unmatched configs from annotations + - [Config] fix up abi for removed modules + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules + - SAUCE: (efi-lockdown) Move EFI signature blob parser to shared location + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - [Config] (efi-lockdown) enable importing of efi certificates for module sig + verification + + * Miscellaneous upstream changes + - binder: fix CONFIG_ANDROID_BINDER_DEVICES + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc5 + + -- Seth Forshee Tue, 05 Feb 2019 14:26:12 -0600 + +linux (5.0.0-2.3) disco; urgency=medium + + * kernel oops in bcache module (LP: #1793901) + - SAUCE: bcache: never writeback a discard operation + + * Enable sound card power saving by default (LP: #1804265) + - [Config] CONFIG_SND_HDA_POWER_SAVE_DEFAULT=1 + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: selftests: disable some failing networking tests" + - SAUCE: ashmem: turn into module + - SAUCE: binder: turn into module + - SAUCE: binder: give binder_alloc its own debug mask file + - [Config] enable binder and ashmem as modules + - SAUCE: selftests: net: replace AF_MAX with INT_MAX in socket.c + - SAUCE: selftests/ftrace: Fix tab expansion in trace_marker snapshot trigger + test + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc4 + + -- Seth Forshee Tue, 29 Jan 2019 06:57:32 -0600 + +linux (5.0.0-1.2) disco; urgency=medium + + * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812) + - USB: Add new USB LPM helpers + - USB: Consolidate LPM checks to avoid enabling LPM twice + + * bluetooth controller not detected with 4.15 kernel (LP: #1810797) + - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK + - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y + + * [19.04 FEAT| Enable virtio-gpu for s390x (LP: #1799467) + - [Config] enable virtio-gpu for s390x + + * Crash on "ip link add foo type ipip" (LP: #1811803) + - SAUCE: fan: Fix NULL pointer dereference + + * Fix not working Goodix touchpad (LP: #1811929) + - HID: i2c-hid: Disable runtime PM on Goodix touchpad + + * Miscellaneous Ubuntu changes + - update dkms package versions + - enable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc3 + + -- Seth Forshee Tue, 22 Jan 2019 13:56:17 -0600 + +linux (5.0.0-0.1) disco; urgency=medium + + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] dkms -- add per package post-process step + - [Packaging] dkms -- switch to a consistent build prefix length and strip + - [Packaging] nvidia -- build and sign nvidia packages and ship signatures + - [Packaging] nvidia -- make nvidia package version explicit + + * Add support for ALC3277 codec on new Dell edge gateways (LP: #1807334) + - [Config] CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m + + * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472) + - [Config] CONFIG_RTLWIFI_DEBUG_ST=n + + * Miscellaneous Ubuntu changes + - ubuntu -- disable vbox build + - ubuntu -- disable hio build + - Disable zfs build + - SAUCE: import aufs driver + - update dkms package versions + - [Config] disable aufs config options + - [Config] disable nvidia build + - update dropped.txt + - [Packaging] disable nvidia dkms builds for mainline + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation + defined + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - [Config] set config options for efi lockdown + - Revert "UBUNTU: SAUCE: import aufs driver" + + [ Upstream Kernel Changes ] + + * Rebase to v5.0-rc2 + + -- Seth Forshee Thu, 17 Jan 2019 12:31:29 -0600 + +linux (5.0.0-0.0) disco; urgency=medium + + * Dummy entry. + + -- Seth Forshee Wed, 16 Jan 2019 14:48:05 -0600 + +linux (4.20.0-2.3) disco; urgency=medium + + [ Upstream Kernel Changes ] + + * Rebase to v4.20 + + -- Seth Forshee Thu, 03 Jan 2019 12:11:43 -0600 + +linux (4.20.0-1.2) disco; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network + Adapter (LP: #1805607) + - SAUCE: ath10k: provide reset function for QCA9377 chip + + * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] dkms -- dkms package build packaging support + - [Packaging] dkms -- save build objects artifacts for validation + - [Packaging] dkms -- add general Built-Using: support + - [Packaging] simplify Provides comma handling + - [Packaging] zfs/spl -- remove packaging support for incorporated source + - [Packaging] zfs/spl -- remove incorporated source + - [Packaging] zfs/spl -- build via dkms + - [Packaging] zfs/spl -- make zfs package version explicit + - [Packaging] update-version-dkms -- sync archive versions to package + + * Miscellaneous Ubuntu changes + - [Packaging] update-version-dkms -- fix getting distrbution from changelog + - update dkms package versions + + [ Upstream Kernel Changes ] + + * Rebase to v4.20-rc6 + + -- Seth Forshee Tue, 11 Dec 2018 11:33:08 -0600 + +linux (4.20.0-0.1) disco; urgency=medium + + * Overlayfs in user namespace leaks directory content of inaccessible + directories (LP: #1793458) // CVE-2018-6559 + - Revert "ovl: relax permission checking on underlying layers" + - SAUCE: overlayfs: ensure mounter privileges when reading directories + + * Miscellaneous Ubuntu changes + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Fix for module sig verification + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: Import aufs driver + - ubuntu: vbox -- update to 5.2.22-dfsg-2 + - ubuntu -- disable vbox build + - ubuntu -- disable hio build + - Disable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.20-rc5 + + -- Seth Forshee Fri, 07 Dec 2018 07:13:42 -0600 + +linux (4.20.0-0.0) disco; urgency=medium + + * Dummy entry. + + -- Seth Forshee Thu, 06 Dec 2018 10:20:19 -0600 + +linux (4.19.0-8.9) disco; urgency=medium + + * linux: 4.19.0-8.9 -proposed tracker (LP: #1806952) + + * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838) + - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC + + * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818) + - igb: Fix an issue that PME is not enabled during runtime suspend + + * The line-out on the Dell Dock station can't work (LP: #1806532) + - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock + + * CVE-2018-19407 + - KVM: X86: Fix scan ioapic use-before-initialization + + * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle + (LP: #1805775) + - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being + disabled + + * Disco update: 4.19.6 upstream stable release (LP: #1806909) + - HID: steam: remove input device when a hid client is running. + - efi/libstub: arm: support building with clang + - usb: core: Fix hub port connection events lost + - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers + - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB + - usb: dwc3: core: Clean up ULPI device + - usb: dwc3: Fix NULL pointer exception in dwc3_pci_remove() + - xhci: Fix leaking USB3 shared_hcd at xhci removal + - xhci: handle port status events for removed USB3 hcd + - xhci: Add check for invalid byte size error when UAS devices are connected. + - usb: xhci: fix uninitialized completion when USB3 port got wrong status + - usb: xhci: fix timeout for transition from RExit to U0 + - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc + - usb: xhci: Prevent bus suspend if a port connect change or polling state is + detected + - ALSA: oss: Use kvzalloc() for local buffer allocations + - MAINTAINERS: Add Sasha as a stable branch maintainer + - Documentation/security-bugs: Clarify treatment of embargoed information + - Documentation/security-bugs: Postpone fix publication in exceptional cases + - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL + - mmc: sdhci-pci: Workaround GLK firmware failing to restore the tuning value + - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path + - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE + - iwlwifi: mvm: support sta_statistics() even on older firmware + - iwlwifi: mvm: fix regulatory domain update when the firmware starts + - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used + - brcmfmac: fix reporting support for 160 MHz channels + - opp: ti-opp-supply: Dynamically update u_volt_min + - opp: ti-opp-supply: Correct the supply in _get_optimal_vdd_voltage call + - tools/power/cpupower: fix compilation with STATIC=true + - v9fs_dir_readdir: fix double-free on p9stat_read error + - selinux: Add __GFP_NOWARN to allocation at str_read() + - Input: synaptics - avoid using uninitialized variable when probing + - bfs: add sanity check at bfs_fill_super() + - sctp: clear the transport of some out_chunk_list chunks in + sctp_assoc_rm_peer + - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd + - llc: do not use sk_eat_skb() + - mm: don't warn about large allocations for slab + - mm/memory.c: recheck page table entry with page table lock held + - tcp: do not release socket ownership in tcp_close() + - drm/fb-helper: Blacklist writeback when adding connectors to fbdev + - drm/amdgpu: Add missing firmware entry for HAINAN + - drm/vc4: Set ->legacy_cursor_update to false when doing non-async updates + - drm/amdgpu: Fix oops when pp_funcs->switch_power_profile is unset + - drm/i915: Disable LP3 watermarks on all SNB machines + - drm/ast: change resolution may cause screen blurred + - drm/ast: fixed cursor may disappear sometimes + - drm/ast: Remove existing framebuffers before loading driver + - can: flexcan: Unlock the MB unconditionally + - can: dev: can_get_echo_skb(): factor out non sending code to + __can_get_echo_skb() + - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to + access frame length + - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb + is accessed out of bounds + - can: dev: __can_get_echo_skb(): print error message, if trying to echo non + existing skb + - can: rx-offload: introduce can_rx_offload_get_echo_skb() and + can_rx_offload_queue_sorted() functions + - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to + can_rx_offload_queue_tail() + - can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*() + - can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure + - can: raw: check for CAN FD capable netdev in raw_sendmsg() + - can: hi311x: Use level-triggered interrupt + - can: flexcan: Always use last mailbox for TX + - can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct + flexcan_priv::tx_mb_idx + - ACPICA: AML interpreter: add region addresses in global list during + initialization + - IB/hfi1: Eliminate races in the SDMA send error path + - fsnotify: generalize handling of extra event flags + - fanotify: fix handling of events on child sub-directory + - pinctrl: meson: fix pinconf bias disable + - pinctrl: meson: fix gxbb ao pull register bits + - pinctrl: meson: fix gxl ao pull register bits + - pinctrl: meson: fix meson8 ao pull register bits + - pinctrl: meson: fix meson8b ao pull register bits + - tools/testing/nvdimm: Fix the array size for dimm devices. + - scsi: lpfc: fix remoteport access + - scsi: hisi_sas: Remove set but not used variable 'dq_list' + - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE + - cpufreq: imx6q: add return value check for voltage scale + - rtc: cmos: Do not export alarm rtc_ops when we do not support alarms + - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write + - crypto: simd - correctly take reqsize of wrapped skcipher into account + - floppy: fix race condition in __floppy_read_block_0() + - powerpc/io: Fix the IO workarounds code to work with Radix + - sched/fair: Fix cpu_util_wake() for 'execl' type workloads + - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs + - block: copy ioprio in __bio_clone_fast() and bounce + - SUNRPC: Fix a bogus get/put in generic_key_to_expire() + - riscv: add missing vdso_install target + - RISC-V: Silence some module warnings on 32-bit + - drm/amdgpu: fix bug with IH ring setup + - kdb: Use strscpy with destination buffer size + - NFSv4: Fix an Oops during delegation callbacks + - powerpc/numa: Suppress "VPHN is not supported" messages + - efi/arm: Revert deferred unmap of early memmap mapping + - z3fold: fix possible reclaim races + - mm, memory_hotplug: check zone_movable in has_unmovable_pages + - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset + - mm, page_alloc: check for max order in hot path + - dax: Avoid losing wakeup in dax_lock_mapping_entry + - include/linux/pfn_t.h: force '~' to be parsed as an unary operator + - tty: wipe buffer. + - tty: wipe buffer if not echoing data + - gfs2: Fix iomap buffer head reference counting bug + - rcu: Make need_resched() respond to urgent RCU-QS needs + - media: ov5640: Re-work MIPI startup sequence + - media: ov5640: Fix timings setup code + - media: ov5640: fix exposure regression + - media: ov5640: fix auto gain & exposure when changing mode + - media: ov5640: fix wrong binning value in exposure calculation + - media: ov5640: fix auto controls values when switching to manual mode + - Linux 4.19.6 + + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] limit preparation to linux-libc-dev in headers + - [Packaging] commonise debhelper invocation + - [Packaging] ABI -- accumulate abi information at the end of the build + - [Packaging] buildinfo -- add basic build information + - [Packaging] buildinfo -- add firmware information to the flavour ABI + - [Packaging] buildinfo -- add compiler information to the flavour ABI + - [Packaging] buildinfo -- add buildinfo support to getabis + - [Packaging] getabis -- handle all known package combinations + - [Packaging] getabis -- support parsing a simple version + + * linux packages should own /usr/lib/linux/triggers (LP: #1770256) + - [Packaging] own /usr/lib/linux/triggers + + * Miscellaneous upstream changes + - blk-mq: fix corruption with direct issue + + -- Seth Forshee Wed, 05 Dec 2018 09:18:30 -0600 + +linux (4.19.0-7.8) disco; urgency=medium + + * linux: 4.19.0-7.8 -proposed tracker (LP: #1805465) + + * Fix and issue that LG I2C touchscreen stops working after reboot + (LP: #1805085) + - HID: i2c-hid: Disable runtime PM for LG touchscreen + + * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) // + click/pop noise in the headphone on several lenovo laptops (LP: #1805079) + - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops + + * Regression: hinic performance degrades over time (LP: #1805248) + - Revert "net-next/hinic: add checksum offload and TSO support" + + * Disco update: 4.19.5 upstream stable release (LP: #1805461) + - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE + - cifs: don't dereference smb_file_target before null check + - cifs: fix return value for cifs_listxattr + - arm64: kprobe: make page to RO mode when allocate it + - block: brd: associate with queue until adding disk + - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset() + - net: hns3: bugfix for rtnl_lock's range in the hclge_reset() + - net: hns3: bugfix for handling mailbox while the command queue reinitialized + - net: hns3: bugfix for the initialization of command queue's spin lock + - ixgbe: fix MAC anti-spoofing filter after VFLR + - reiserfs: propagate errors from fill_with_dentries() properly + - hfs: prevent btree data loss on root split + - hfsplus: prevent btree data loss on root split + - perf unwind: Take pgoff into account when reporting elf to libdwfl + - um: Give start_idle_thread() a return code + - drm/edid: Add 6 bpc quirk for BOE panel. + - afs: Handle EIO from delivery function + - platform/x86: intel_telemetry: report debugfs failure + - clk: fixed-rate: fix of_node_get-put imbalance + - perf symbols: Set PLT entry/header sizes properly on Sparc + - fs/exofs: fix potential memory leak in mount option parsing + - clk: samsung: exynos5420: Enable PERIS clocks for suspend + - apparmor: Fix uninitialized value in aa_split_fqname + - x86/earlyprintk: Add a force option for pciserial device + - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307 + - clk: meson-axg: pcie: drop the mpll3 clock parent + - arm64: percpu: Initialize ret in the default case + - clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary + - clk: renesas: r9a06g032: Fix UART34567 clock rate + - clk: ti: fix OF child-node lookup + - serial: sh-sci: Fix receive on SCIFA/SCIFB variants with DMA + - netfilter: ipv6: fix oops when defragmenting locally generated fragments + - netfilter: bridge: define INT_MIN & INT_MAX in userspace + - s390/decompressor: add missing FORCE to build targets + - s390/vdso: add missing FORCE to build targets + - HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel + - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS" + - HID: alps: allow incoming reports when only the trackstick is opened + - Revert "netfilter: nft_numgen: add map lookups for numgen random operations" + - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and + replace + - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net + - netfilter: ipset: fix ip_set_list allocation failure + - s390/mm: fix mis-accounting of pgtable_bytes + - s390/mm: Fix ERROR: "__node_distance" undefined! + - bpf: fix bpf_prog_get_info_by_fd to return 0 func_lens for unpriv + - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment() + - netfilter: xt_IDLETIMER: add sysfs filename checking routine + - netfilter: ipset: Fix calling ip_set() macro at dumping + - netfilter: nft_compat: ebtables 'nat' table is normal chain type + - s390/qeth: fix HiperSockets sniffer + - s390/qeth: unregister netdevice only when registered + - net: hns3: Fix for out-of-bounds access when setting pfc back pressure + - hwmon: (ibmpowernv) Remove bogus __init annotations + - ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node + - ARM: dts: fsl: Fix improperly quoted stdout-path values + - Revert "drm/exynos/decon5433: implement frame counter" + - arm64: dts: renesas: r8a7795: add missing dma-names on hscif2 + - arm64: dts: renesas: condor: switch from EtherAVB to GEther + - xen/grant-table: Fix incorrect gnttab_dma_free_pages() pr_debug message + - clk: fixed-factor: fix of_node_get-put imbalance + - mtd: nand: Fix nanddev_pos_next_page() kernel-doc header + - lib/raid6: Fix arm64 test build + - drm/amd/display: Stop leaking planes + - block: Clear kernel memory before copying to user + - drm/amd/display: Drop reusing drm connector for MST + - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder() + - s390/perf: Change CPUM_CF return code in event init function + - ceph: quota: fix null pointer dereference in quota check + - of/device: Really only set bus DMA mask when appropriate + - nvme: make sure ns head inherits underlying device limits + - i2c: omap: Enable for ARCH_K3 + - i2c: qcom-geni: Fix runtime PM mismatch with child devices + - sched/core: Take the hotplug lock in sched_init_smp() + - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so + - perf tools: Do not zero sample_id_all for group members + - ice: Fix dead device link issue with flow control + - ice: Fix the bytecount sent to netdev_tx_sent_queue + - ice: Change req_speeds to be u16 + - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features + - qed: Fix memory/entry leak in qed_init_sp_request() + - qed: Fix blocking/unlimited SPQ entries leak + - qed: Fix SPQ entries not returned to pool in error flows + - qed: Fix potential memory corruption + - net: stmmac: Fix RX packet size > 8191 + - net: aquantia: fix potential IOMMU fault after driver unbind + - net: aquantia: fixed enable unicast on 32 macvlan + - net: aquantia: invalid checksumm offload implementation + - kbuild: deb-pkg: fix too low build version number + - Revert "scripts/setlocalversion: git: Make -dirty check more robust" + - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer() + - x86/mm: Move LDT remap out of KASLR region on 5-level paging + - x86/ldt: Unmap PTEs for the slot before freeing LDT pages + - x86/ldt: Remove unused variable in map_ldt_struct() + - media: v4l: event: Add subscription to list before calling "add" operation + - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver + - RISC-V: Fix raw_copy_{to,from}_user() + - uio: Fix an Oops on load + - ALSA: hda/realtek - Add quirk entry for HP Pavilion 15 + - ALSA: hda/ca0132 - Call pci_iounmap() instead of iounmap() + - can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit() + - can: kvaser_usb: Fix potential uninitialized variable use + - usb: cdc-acm: add entry for Hiro (Conexant) modem + - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub + - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB + - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data + - USB: misc: appledisplay: add 20" Apple Cinema Display + - gnss: serial: fix synchronous write timeout + - gnss: sirf: fix synchronous write timeout + - mtd: rawnand: atmel: fix OF child-node lookup + - drivers/misc/sgi-gru: fix Spectre v1 vulnerability + - ACPI / platform: Add SMB0001 HID to forbidden_id_list + - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges + - HID: Add quirk for Primax PIXART OEM mice + - HID: Add quirk for Microsoft PIXART OEM mouse + - libceph: fall back to sendmsg for slab pages + - mt76x0: run vco calibration for each channel configuration + - Linux 4.19.5 + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: Build signed kernels for arm64" + + -- Seth Forshee Tue, 27 Nov 2018 10:38:34 -0600 + +linux (4.19.0-6.7) disco; urgency=medium + + * linux: 4.19.0-6.7 -proposed tracker (LP: #1805195) + + * SecureBoot support for arm64 (LP: #1804481) + - Build signed kernels for arm64 + + * Add pointstick support for Cirque Touchpad (LP: #1805081) + - HID: multitouch: Add pointstick support for Cirque Touchpad + + * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF) + (LP: #1804588) + - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + + * Disco update: 4.19.4 upstream stable release (LP: #1805159) + - flow_dissector: do not dissect l4 ports for fragments + - ibmvnic: fix accelerated VLAN handling + - ip_tunnel: don't force DF when MTU is locked + - ipv6: fix a dst leak when removing its exception + - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF + - net: bcmgenet: protect stop from timeout + - net-gro: reset skb->pkt_type in napi_reuse_skb() + - sctp: not allow to set asoc prsctp_enable by sockopt + - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP + coalescing + - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths + - tipc: don't assume linear buffer when reading ancillary data + - tipc: fix lockdep warning when reinitilaizing sockets + - tuntap: fix multiqueue rx + - net: systemport: Protect stop from timeout + - net/sched: act_pedit: fix memory leak when IDR allocation fails + - net: sched: cls_flower: validate nested enc_opts_policy to avoid warning + - tipc: fix link re-establish failure + - net/mlx5e: Don't match on vlan non-existence if ethertype is wildcarded + - net/mlx5e: Claim TC hw offloads support only under a proper build config + - net/mlx5e: Adjust to max number of channles when re-attaching + - net/mlx5e: RX, verify received packet size in Linear Striding RQ + - Revert "sctp: remove sctp_transport_pmtu_check" + - net/mlx5e: Always use the match level enum when parsing TC rule match + - net/mlx5e: Fix selftest for small MTUs + - net/mlx5e: Removed unnecessary warnings in FEC caps query + - inet: frags: better deal with smp races + - l2tp: fix a sock refcnt leak in l2tp_tunnel_register + - net/mlx5: IPSec, Fix the SA context hash key + - net/mlx5e: IPoIB, Reset QP after channels are closed + - net: dsa: mv88e6xxx: Fix clearing of stats counters + - net: phy: realtek: fix RTL8201F sysfs name + - sctp: define SCTP_SS_DEFAULT for Stream schedulers + - net: qualcomm: rmnet: Fix incorrect assignment of real_dev + - net: dsa: microchip: initialize mutex before use + - sctp: fix strchange_flags name for Stream Change Event + - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs + - sctp: not increase stream's incnt before sending addstrm_in request + - mlxsw: spectrum: Fix IP2ME CPU policer configuration + - net: smsc95xx: Fix MTU range + - rxrpc: Fix lockup due to no error backoff after ack transmit error + - usbnet: smsc95xx: disable carrier check while suspending + - Revert "x86/speculation: Enable cross-hyperthread spectre v2 STIBP + mitigation" + - Linux 4.19.4 + + * Disco update: 4.19.3 upstream stable release (LP: #1805158) + - powerpc/traps: restore recoverability of machine_check interrupts + - powerpc/64/module: REL32 relocation range check + - powerpc/mm: Fix page table dump to work on Radix + - powerpc/mm: fix always true/false warning in slice.c + - drm/amd/display: fix bug of accessing invalid memory + - Input: wm97xx-ts - fix exit path + - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS + - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log() + - tty: check name length in tty_find_polling_driver() + - tracing/kprobes: Check the probe on unloaded module correctly + - drm/nouveau/secboot/acr: fix memory leak + - drm/amdgpu/powerplay: fix missing break in switch statements + - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL + - powerpc/nohash: fix undefined behaviour when testing page size support + - drm/msm/gpu: fix parameters in function msm_gpu_crashstate_capture + - drm/msm/disp/dpu: Use proper define for drm_encoder_init() 'encoder_type' + - drm/msm: dpu: Allow planes to extend past active display + - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak + - drm/omap: fix memory barrier bug in DMM driver + - drm/amd/display: Raise dispclk value for dce120 by 15% + - drm/amd/display: fix gamma not being applied + - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer + - media: pci: cx23885: handle adding to list failure + - media: coda: don't overwrite h.264 profile_idc on decoder instance + - MIPS: kexec: Mark CPU offline before disabling local IRQ + - powerpc/boot: Ensure _zimage_start is a weak symbol + - powerpc/memtrace: Remove memory in chunks + - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS + - staging: erofs: fix a missing endian conversion + - serial: 8250_of: Fix for lack of interrupt support + - sc16is7xx: Fix for multi-channel stall + - media: tvp5150: fix width alignment during set_selection() + - powerpc/selftests: Wait all threads to join + - staging:iio:ad7606: fix voltage scales + - drm: rcar-du: Update Gen3 output limitations + - drm/amdgpu: Fix SDMA TO after GPU reset v3 + - staging: most: video: fix registration of an empty comp core_component + - 9p locks: fix glock.client_id leak in do_lock + - udf: Prevent write-unsupported filesystem to be remounted read-write + - ARM: dts: imx6ull: keep IMX6UL_ prefix for signals on both i.MX6UL and + i.MX6ULL + - media: ov5640: fix mode change regression + - 9p: clear dangling pointers in p9stat_free + - drm/amdgpu: fix integer overflow test in amdgpu_bo_list_create() + - media: ov5640: fix restore of last mode set + - cdrom: fix improper type cast, which can leat to information leak. + - ovl: fix error handling in ovl_verify_set_fh() + - ovl: fix recursive oi->lock in ovl_link() + - ovl: check whiteout in ovl_create_over_whiteout() + - ovl: automatically enable redirect_dir on metacopy=on + - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout + - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters + - scsi: qla2xxx: Fix process response queue for ISP26XX and above + - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx + - scsi: qla2xxx: Fix early srb free on abort + - scsi: qla2xxx: shutdown chip if reset fail + - scsi: qla2xxx: Reject bsg request if chip is down. + - scsi: qla2xxx: Fix re-using LoopID when handle is in use + - scsi: qla2xxx: Fix for double free of SRB structure + - scsi: qla2xxx: Fix NVMe session hang on unload + - scsi: qla2xxx: Fix NVMe Target discovery + - scsi: qla2xxx: Fix duplicate switch database entries + - scsi: qla2xxx: Fix driver hang when FC-NVMe LUNs are configured + - vfs: fix FIGETBSZ ioctl on an overlayfs file + - fuse: Fix use-after-free in fuse_dev_do_read() + - fuse: Fix use-after-free in fuse_dev_do_write() + - fuse: fix blocked_waitq wakeup + - fuse: set FR_SENT while locked + - drm/msm: fix OF child-node lookup + - arm64: dts: stratix10: Support Ethernet Jumbo frame + - arm64: dts: stratix10: fix multicast filtering + - clk: meson-gxbb: set fclk_div3 as CLK_IS_CRITICAL + - clk: meson: axg: mark fdiv2 and fdiv3 as critical + - zram: close udev startup race condition as default groups + - MIPS: Loongson-3: Fix CPU UART irq delivery problem + - MIPS: Loongson-3: Fix BRIDGE irq delivery problem + - xtensa: add NOTES section to the linker script + - xtensa: make sure bFLT stack is 16 byte aligned + - xtensa: fix boot parameters address translation + - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP + - clk: s2mps11: Fix matching when built as module and DT node contains + compatible + - clk: at91: Fix division by zero in PLL recalc_rate() + - clk: sunxi-ng: h6: fix bus clocks' divider position + - clk: rockchip: fix wrong mmc sample phase shift for rk3328 + - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call + - libceph: bump CEPH_MSG_MAX_DATA_LEN + - Revert "ceph: fix dentry leak in splice_dentry()" + - thermal: core: Fix use-after-free in thermal_cooling_device_destroy_sysfs + - mach64: fix display corruption on big endian machines + - mach64: fix image corruption due to reading accelerator registers + - acpi/nfit, x86/mce: Handle only uncorrectable machine checks + - acpi/nfit, x86/mce: Validate a MCE's address before using it + - acpi, nfit: Fix ARS overflow continuation + - reset: hisilicon: fix potential NULL pointer dereference + - crypto: hisilicon - Fix NULL dereference for same dst and src + - crypto: hisilicon - Fix reference after free of memories on error path + - vhost/scsi: truncate T10 PI iov_iter to prot_bytes + - scsi: qla2xxx: Initialize port speed to avoid setting lower speed + - SCSI: fix queue cleanup race before queue initialization is done + - Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for + CONFIG_SWAP" + - soc: ti: QMSS: Fix usage of irq_set_affinity_hint + - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry + - ocfs2: free up write context when direct IO failed + - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings + - memory_hotplug: cond_resched in __remove_pages + - netfilter: conntrack: fix calculation of next bucket number in early_drop + - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm + - bonding/802.3ad: fix link_failure_count tracking + - mtd: spi-nor: cadence-quadspi: Return error code in + cqspi_direct_read_execute() + - mtd: nand: Fix nanddev_neraseblocks() + - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option + - hwmon: (core) Fix double-free in __hwmon_device_register() + - perf cs-etm: Correct CPU mode for samples + - perf stat: Handle different PMU names with common prefix + - perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc} + - perf intel-pt/bts: Calculate cpumode for synthesized samples + - perf intel-pt: Insert callchain context into synthesized callchains + - of, numa: Validate some distance map rules + - x86/cpu/vmware: Do not trace vmware_sched_clock() + - x86/hyper-v: Enable PIT shutdown quirk + - termios, tty/tty_baudrate.c: fix buffer overrun + - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2 + - watchdog/core: Add missing prototypes for weak functions + - btrfs: fix pinned underflow after transaction aborted + - Btrfs: fix missing data checksums after a ranged fsync (msync) + - Btrfs: fix cur_offset in the error case for nocow + - Btrfs: fix infinite loop on inode eviction after deduplication of eof block + - Btrfs: fix data corruption due to cloning of eof block + - btrfs: tree-checker: Fix misleading group system information + - clockevents/drivers/i8253: Add support for PIT shutdown quirk + - ext4: add missing brelse() update_backups()'s error path + - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path + - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path + - ext4: avoid potential extra brelse in setup_new_flex_group_blocks() + - ext4: missing !bh check in ext4_xattr_inode_write() + - ext4: fix possible inode leak in the retry loop of ext4_resize_fs() + - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty() + - ext4: avoid buffer leak in ext4_orphan_add() after prior errors + - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing + - ext4: avoid possible double brelse() in add_new_gdb() on error path + - ext4: fix possible leak of sbi->s_group_desc_leak in error path + - ext4: fix possible leak of s_journal_flag_rwsem in error path + - ext4: fix buffer leak in ext4_xattr_get_block() on error path + - ext4: release bs.bh before re-using in ext4_xattr_block_find() + - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path + - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path + - ext4: fix buffer leak in __ext4_read_dirblock() on error path + - mount: Prevent MNT_DETACH from disconnecting locked mounts + - mnt: fix __detach_mounts infinite loop + - uapi: fix linux/kfd_ioctl.h userspace compilation errors + - ARM: cpuidle: Don't register the driver when back-end init returns -ENXIO + - kdb: use correct pointer when 'btc' calls 'btt' + - kdb: print real address of pointers instead of hashed addresses + - sunrpc: correct the computation for page_ptr when truncating + - NFSv4: Don't exit the state manager without clearing + NFS4CLNT_MANAGER_RUNNING + - nfsd: COPY and CLONE operations require the saved filehandle to be set + - rtc: hctosys: Add missing range error reporting + - fuse: fix use-after-free in fuse_direct_IO() + - fuse: fix leaked notify reply + - fuse: fix possibly missed wake-up after abort + - selinux: check length properly in SCTP bind hook + - gfs2: Put bitmap buffers in put_super + - gfs2: Fix metadata read-ahead during truncate (2) + - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD + - crypto: user - fix leaking uninitialized memory to userspace + - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn + - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444! + - mm/swapfile.c: use kvzalloc for swap_info_struct allocation + - efi/arm/libstub: Pack FDT after populating it + - mm: don't reclaim inodes with many attached pages + - scripts/spdxcheck.py: make python3 compliant + - drm/rockchip: Allow driver to be shutdown on reboot/kexec + - drm/amdgpu: Fix typo in amdgpu_vmid_mgr_init + - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type + - drm/amdgpu: Suppress keypresses from ACPI_VIDEO events + - drm/nouveau: Check backlight IDs are >= 0, not > 0 + - drm/nouveau: Fix nv50_mstc->best_encoder() + - drm/amd/powerplay: Enable/Disable NBPSTATE on On/OFF of UVD + - drm/etnaviv: fix bogus fence complete check in timeout handler + - drm/dp_mst: Check if primary mstb is null + - drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003) + - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit + panel's native mode + - drm/i915: Use the correct crtc when sanitizing plane mapping + - drm/i915: Restore vblank interrupts earlier + - drm/i915: Don't unset intel_connector->mst_port + - drm/i915: Skip vcpi allocation for MSTB ports that are gone + - drm/i915: Large page offsets for pread/pwrite + - drm/i915/dp: Fix link retraining comment in intel_dp_long_pulse() + - drm/i915/dp: Restrict link retrain workaround to external monitors + - drm/i915/icl: Fix the macros for DFLEXDPMLE register bits + - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values + - drm/i915: Mark up GTT sizes as u64 + - drm/i915: Fix error handling for the NV12 fb dimensions check + - drm/i915: Fix ilk+ watermarks when disabling pipes + - drm/i915: Compare user's 64b GTT offset even on 32b + - drm/i915: Don't oops during modeset shutdown after lpe audio deinit + - drm/i915: Mark pin flags as u64 + - drm/i915/ringbuffer: Delay after EMIT_INVALIDATE for gen4/gen5 + - drm/i915/execlists: Force write serialisation into context image vs + execution + - drm/i915: Fix possible race in intel_dp_add_mst_connector() + - drm/i915: Fix NULL deref when re-enabling HPD IRQs on systems with MST + - drm/i915: Fix hpd handling for pins with two encoders + - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM + - Revert "ACPICA: AML interpreter: add region addresses in global list during + initialization" + - Linux 4.19.3 + + * glibc 2.28-0ubuntu1 ADT test failure with linux 4.19.0-5.6 (LP: #1805154) + - SAUCE: Revert "x86: vdso: Use $LD instead of $CC to link" + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.12-1ubuntu1, zfs to 0.7.12-1ubuntu1 + + -- Seth Forshee Mon, 26 Nov 2018 11:44:00 -0600 + +linux (4.19.0-5.6) disco; urgency=medium + + * crash in ENA driver on removing an interface (LP: #1802341) + - SAUCE: net: ena: fix crash during ena_remove() + + * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding + (LP: #1797367) + - s390/qeth: sanitize strings in debug messages + + * Disco update: 4.19.2 upstream stable release (LP: #1803410) + - bpf: fix partial copy of map_ptr when dst is scalar + - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit + - gpio: mxs: Get rid of external API call + - mtd: rawnand: marvell: fix the IRQ handler complete() condition + - mtd: maps: gpio-addr-flash: Fix ioremapped size + - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB + - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash + - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus + - spi: spi-mem: Adjust op len based on message/transfer size limitations + - spi: bcm-qspi: switch back to reading flash using smaller chunks + - spi: bcm-qspi: fix calculation of address length + - bcache: trace missed reading by cache_missed + - bcache: fix ioctl in flash device + - bcache: correct dirty data statistics + - bcache: fix miss key refill->end in writeback + - hwmon: (pmbus) Fix page count auto-detection. + - jffs2: free jffs2_sb_info through jffs2_kill_sb() + - block: setup bounce bio_sets properly + - block: make sure discard bio is aligned with logical block size + - block: make sure writesame bio is aligned with logical block size + - cpufreq: conservative: Take limits changes into account properly + - dma-mapping: fix panic caused by passing empty cma command line argument + - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges + - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer() + - ACPICA: AML interpreter: add region addresses in global list during + initialization + - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended + opcodes + - acpi, nfit: Fix Address Range Scrub completion tracking + - kprobes/x86: Use preempt_enable() in optimized_callback() + - mailbox: PCC: handle parse error + - parisc: Fix address in HPMC IVA + - parisc: Fix map_pages() to not overwrite existing pte entries + - parisc: Fix exported address of os_hpmc handler + - ALSA: hda - Add quirk for ASUS G751 laptop + - ALSA: hda - Fix headphone pin config for ASUS G751 + - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905) + - ALSA: hda: Add 2 more models to the power_save blacklist + - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops + - ALSA: hda - Fix incorrect clearance of thinkpad_acpi hooks + - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation + - x86/xen: Fix boot loader version reported for PVH guests + - x86/corruption-check: Fix panic in memory_corruption_check() when boot + option without value is provided + - x86/kvm/nVMX: allow bare VMXON state migration + - x86/mm/pat: Disable preemption around __flush_tlb_all() + - x86/numa_emulation: Fix uniform-split numa emulation + - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen + - net: socionext: Reset tx queue in ndo_stop + - net: loopback: clear skb->tstamp before netif_rx() + - locking/lockdep: Fix debug_locks off performance problem + - netfilter: xt_nat: fix DNAT target for shifted portmap ranges + - ataflop: fix error handling during setup + - swim: fix cleanup on setup error + - arm64: cpufeature: ctr: Fix cpu capability check for late CPUs + - hv_netvsc: fix vf serial matching with pci slot info + - nfp: devlink port split support for 1x100G CXP NIC + - tun: Consistently configure generic netdev params via rtnetlink + - s390/sthyi: Fix machine name validity indication + - hwmon: (pwm-fan) Set fan speed to 0 on suspend + - lightnvm: pblk: fix race on sysfs line state + - lightnvm: pblk: fix two sleep-in-atomic-context bugs + - lightnvm: pblk: fix race condition on metadata I/O + - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare} + - perf tools: Free temporary 'sys' string in read_event_files() + - perf tools: Cleanup trace-event-info 'tdata' leak + - perf tools: Free 'printk' string in parse_ftrace_printk() + - perf strbuf: Match va_{add,copy} with va_end + - cpupower: Fix coredump on VMWare + - bcache: Populate writeback_rate_minimum attribute + - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01 + - sdhci: acpi: add free_slot callback + - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset + - iwlwifi: pcie: avoid empty free RB queue + - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface + - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI + - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC + - wlcore: Fix BUG with clear completion on timeout + - ACPI/PPTT: Handle architecturally unknown cache types + - ACPI / PM: LPIT: Register sysfs attributes based on FADT + - ACPI / processor: Fix the return value of acpi_processor_ids_walk() + - cpufreq: dt: Try freeing static OPPs only if we have added them + - x86/intel_rdt: Show missing resctrl mount options + - mtd: rawnand: atmel: Fix potential NULL pointer dereference + - nvme: call nvme_complete_rq when nvmf_check_ready fails for mpath I/O + - ath10k: fix tx status flag setting for management frames + - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack + - ice: fix changing of ring descriptor size (ethtool -G) + - ice: update fw version check logic + - net: hns3: Fix for packet buffer setting bug + - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth + - Bluetooth: hci_qca: Remove hdev dereference in qca_close(). + - x86: boot: Fix EFI stub alignment + - net: hns3: Add nic state check before calling netif_tx_wake_queue + - net: hns3: Fix ets validate issue + - pinctrl: sunxi: fix 'pctrl->functions' allocation in + sunxi_pinctrl_build_state + - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux + - brcmfmac: fix for proper support of 160MHz bandwidth + - net: hns3: Check hdev state when getting link status + - net: hns3: Set STATE_DOWN bit of hdev state when stopping net + - net: phy: phylink: ensure the carrier is off when starting phylink + - block, bfq: correctly charge and reset entity service in all cases + - arm64: entry: Allow handling of undefined instructions from EL1 + - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON() + - spi: gpio: No MISO does not imply no RX + - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers + - pinctrl: qcom: spmi-mpp: Fix drive strength setting + - bpf/verifier: fix verifier instability + - failover: Add missing check to validate 'slave_dev' in + net_failover_slave_unregister + - perf tests: Fix record+probe_libc_inet_pton.sh without ping's debuginfo + - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant + - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant + - net: hns3: Preserve vlan 0 in hardware table + - net: hns3: Fix ping exited problem when doing lp selftest + - net: hns3: Fix for vf vlan delete failed problem + - net: dsa: mv88e6xxx: Fix writing to a PHY page. + - mt76x2u: run device cleanup routine if resume fails + - rsi: fix memory alignment issue in ARM32 platforms + - libertas_tf: prevent underflow in process_cmdrequest() + - iwlwifi: mvm: fix BAR seq ctrl reporting + - gpio: brcmstb: allow 0 width GPIO banks + - ixgbe: disallow IPsec Tx offload when in SR-IOV mode + - ixgbevf: VF2VF TCP RSS + - wil6210: fix RX buffers release and unmap + - ath10k: schedule hardware restart if WMI command times out + - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9 + - thermal: rcar_thermal: Prevent doing work after unbind + - thermal: da9062/61: Prevent hardware access during system suspend + - cifs: fix a credits leak for compund commands + - cgroup, netclassid: add a preemption point to write_classid + - net: stmmac: dwmac-sun8i: fix OF child-node lookup + - f2fs: fix to account IO correctly for cgroup writeback + - MD: Memory leak when flush bio size is zero + - md: fix memleak for mempool + - of: Add missing exports of node name compare functions + - scsi: esp_scsi: Track residual for PIO transfers + - scsi: ufs: Schedule clk gating work on correct queue + - UAPI: ndctl: Fix g++-unsupported initialisation in headers + - KVM: nVMX: Clear reserved bits of #DB exit qualification + - scsi: megaraid_sas: fix a missing-check bug + - RDMA/core: Do not expose unsupported counters + - RDMA/cm: Respect returned status of cm_init_av_by_path + - IB/ipoib: Clear IPCB before icmp_send + - RDMA/bnxt_re: Avoid accessing nq->bar_reg_iomem in failure case + - RDMA/bnxt_re: Fix recursive lock warning in debug kernel + - usb: host: ohci-at91: fix request of irq for optional gpio + - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic + - PCI: cadence: Use AXI region 0 to signal interrupts from EP + - usb: typec: tcpm: Report back negotiated PPS voltage and current + - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated + - f2fs: clear PageError on the read path + - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask + - VMCI: Resource wildcard match fixed + - PCI / ACPI: Enable wake automatically for power managed bridges + - xprtrdma: Reset credit grant properly after a disconnect + - irqchip/pdc: Setup all edge interrupts as rising edge at GIC + - usb: dwc2: fix call to vbus supply exit routine, call it unlocked + - usb: dwc2: fix a race with external vbus supply + - usb: gadget: udc: atmel: handle at91sam9rl PMC + - ext4: fix argument checking in EXT4_IOC_MOVE_EXT + - MD: fix invalid stored role for a disk + - PCI: cadence: Correct probe behaviour when failing to get PHY + - nvmem: check the return value of nvmem_add_cells() + - xhci: Avoid USB autosuspend when resuming USB2 ports. + - scsi: qla2xxx: Fix recursive mailbox timeout + - f2fs: fix to recover inode's crtime during POR + - f2fs: fix to recover inode's i_flags during POR + - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice + - coresight: etb10: Fix handling of perf mode + - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode + - crypto: caam - fix implicit casts in endianness helpers + - usb: chipidea: Prevent unbalanced IRQ disable + - Smack: ptrace capability use fixes + - driver/dma/ioat: Call del_timer_sync() without holding prep_lock + - ASoC: AMD: Fix capture unstable in beginning for some runs + - firmware: coreboot: Unmap ioregion after device population + - IB/ipoib: Use dev_port to expose network interface port numbers + - IB/mlx5: Allow transition of DCI QP to reset + - uio: ensure class is registered before devices + - scsi: lpfc: Correct soft lockup when running mds diagnostics + - scsi: lpfc: Correct race with abort on completion path + - f2fs: avoid sleeping under spin_lock + - f2fs: report error if quota off error during umount + - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace + init + - f2fs: fix to flush all dirty inodes recovered in readonly fs + - mfd: menelaus: Fix possible race condition and leak + - dmaengine: dma-jz4780: Return error if not probed from DT + - IB/rxe: fix for duplicate request processing and ack psns + - ALSA: hda: Check the non-cached stream buffers more explicitly + - cpupower: Fix AMD Family 0x17 msr_pstate size + - Revert "f2fs: fix to clear PG_checked flag in set_page_dirty()" + - f2fs: fix missing up_read + - f2fs: fix to recover cold bit of inode block during POR + - f2fs: fix to account IO correctly + - OPP: Free OPP table properly on performance state irregularities + - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings + - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250 + - xen-swiotlb: use actually allocated size on check physical continuous + - tpm: Restore functionality to xen vtpm driver. + - xen/blkfront: avoid NULL blkfront_info dereference on device removal + - xen/balloon: Support xend-based toolstack + - xen: fix race in xen_qlock_wait() + - xen: make xen_qlock_wait() nestable + - xen/pvh: increase early stack size + - xen/pvh: don't try to unplug emulated devices + - libertas: don't set URB_ZERO_PACKET on IN USB transfer + - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten + - usb: typec: tcpm: Fix APDO PPS order checking to be based on voltage + - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround" + - mt76: mt76x2: fix multi-interface beacon configuration + - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate() + - net/ipv4: defensive cipso option parsing + - dmaengine: ppc4xx: fix off-by-one build failure + - scsi: sched/wait: Add wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE + usage + - scsi: target: Fix target_wait_for_sess_cmds breakage with active signals + - libnvdimm: Hold reference on parent while scheduling async init + - libnvdimm, region: Fail badblocks listing for inactive regions + - libnvdimm, pmem: Fix badblocks population for 'raw' namespaces + - ASoC: intel: skylake: Add missing break in skl_tplg_get_token() + - ASoC: sta32x: set ->component pointer in private struct + - IB/mlx5: Fix MR cache initialization + - IB/rxe: Revise the ib_wr_opcode enum + - jbd2: fix use after free in jbd2_log_do_checkpoint() + - gfs2_meta: ->mount() can get NULL dev_name + - ext4: fix EXT4_IOC_SWAP_BOOT + - ext4: initialize retries variable in ext4_da_write_inline_data_begin() + - ext4: fix setattr project check in fssetxattr ioctl + - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR + - ext4: fix use-after-free race in ext4_remount()'s error path + - selinux: fix mounting of cgroup2 under older policies + - HID: wacom: Work around HID descriptor bug in DTK-2451 and DTH-2452 + - HID: hiddev: fix potential Spectre v1 + - EDAC, amd64: Add Family 17h, models 10h-2fh support + - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting + - EDAC, skx_edac: Fix logical channel intermediate decoding + - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP + - PCI/ASPM: Fix link_state teardown on device removal + - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk + - signal/GenWQE: Fix sending of SIGKILL + - signal: Guard against negative signal numbers in copy_siginfo_from_user32 + - crypto: lrw - Fix out-of bounds access on counter overflow + - crypto: tcrypt - fix ghash-generic speed test + - crypto: aesni - don't use GFP_ATOMIC allocation if the request doesn't cross + a page in gcm + - crypto: morus/generic - fix for big endian systems + - crypto: aegis/generic - fix for big endian systems + - crypto: speck - remove Speck + - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range() + - userfaultfd: disable irqs when taking the waitqueue lock + - ima: fix showing large 'violations' or 'runtime_measurements_count' + - ima: open a new file instance if no read permissions + - hugetlbfs: dirty pages as they are added to pagecache + - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly + - mm/hmm: fix race between hmm_mirror_unregister() and mmu_notifier callback + - KVM: arm/arm64: Ensure only THP is candidate for adjustment + - KVM: arm64: Fix caching of host MDCR_EL2 value + - kbuild: fix kernel/bounds.c 'W=1' warning + - iio: ad5064: Fix regulator handling + - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs() + - iio: adc: at91: fix acking DRDY irq on simple conversions + - iio: adc: at91: fix wrong channel number in triggered buffer mode + - w1: omap-hdq: fix missing bus unregister at removal + - smb3: allow stats which track session and share reconnects to be reset + - smb3: do not attempt cifs operation in smb3 query info error path + - smb3: on kerberos mount if server doesn't specify auth type use krb5 + - printk: Fix panic caused by passing log_buf_len to command line + - genirq: Fix race on spurious interrupt detection + - tpm: fix response size validation in tpm_get_random() + - NFC: nfcmrvl_uart: fix OF child-node lookup + - NFSv4.1: Fix the r/wsize checking + - nfs: Fix a missed page unlock after pg_doio() + - nfsd: correctly decrement odstate refcount in error path + - nfsd: Fix an Oops in free_session() + - lockd: fix access beyond unterminated strings in prints + - dm ioctl: harden copy_params()'s copy_from_user() from malicious users + - dm zoned: fix metadata block ref counting + - dm zoned: fix various dmz_get_mblock() issues + - media: ov7670: make "xclk" clock optional + - fsnotify: Fix busy inodes during unmount + - powerpc64/module elfv1: Set opd addresses after module relocation + - powerpc/msi: Fix compile error on mpc83xx + - powerpc/tm: Fix HFSCR bit for no suspend case + - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9 + - MIPS: OCTEON: fix out of bounds array access on CN68XX + - rtc: ds1307: fix ds1339 wakealarm support + - rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt' + - rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI + - power: supply: twl4030-charger: fix OF sibling-node lookup + - ocxl: Fix access to the AFU Descriptor Data + - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI + - TC: Set DMA masks for devices + - net: bcmgenet: fix OF child-node lookup + - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD + - Revert "media: dvbsky: use just one mutex for serializing device R/W ops" + - kgdboc: Passing ekgdboc to command line causes panic + - remoteproc: qcom: q6v5: Propagate EPROBE_DEFER + - media: cec: make cec_get_edid_spa_location() an inline function + - media: cec: integrate cec_validate_phys_addr() in cec-api.c + - xen: fix xen_qlock_wait() + - xen: remove size limit of privcmd-buf mapping interface + - xen-blkfront: fix kernel panic with negotiate_mq error path + - media: cec: add new tx/rx status bits to detect aborts/timeouts + - media: cec: fix the Signal Free Time calculation + - media: cec: forgot to cancel delayed work + - media: em28xx: use a default format if TRY_FMT fails + - media: tvp5150: avoid going past array on v4l2_querymenu() + - media: em28xx: fix input name for Terratec AV 350 + - media: em28xx: make v4l2-compliance happier by starting sequence on zero + - media: em28xx: fix handler for vidioc_s_input() + - media: adv7604: when the EDID is cleared, unconfigure CEC as well + - media: adv7842: when the EDID is cleared, unconfigure CEC as well + - drm/mediatek: fix OF sibling-node lookup + - media: media colorspaces*.rst: rename AdobeRGB to opRGB + - media: replace ADOBERGB by OPRGB + - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC + - arm64: lse: remove -fcall-used-x0 flag + - rpmsg: smd: fix memory leak on channel create + - Cramfs: fix abad comparison when wrap-arounds occur + - ARM: dts: socfpga: Fix SDRAM node address for Arria10 + - arm64: dts: stratix10: Correct System Manager register size + - soc: qcom: rmtfs-mem: Validate that scm is available + - soc/tegra: pmc: Fix child-node lookup + - selftests/ftrace: Fix synthetic event test to delete event correctly + - selftests/powerpc: Fix ptrace tm failure + - tracing: Return -ENOENT if there is no target synthetic event + - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled + - btrfs: Handle owner mismatch gracefully when walking up tree + - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock + - btrfs: fix error handling in free_log_tree + - btrfs: fix error handling in btrfs_dev_replace_start + - btrfs: Enhance btrfs_trim_fs function to handle error better + - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem + - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list + - btrfs: don't attempt to trim devices that don't support it + - btrfs: keep trim from interfering with transaction commits + - btrfs: wait on caching when putting the bg cache + - Btrfs: don't clean dirty pages during buffered writes + - btrfs: release metadata before running delayed refs + - btrfs: protect space cache inode alloc with GFP_NOFS + - btrfs: reset max_extent_size on clear in a bitmap + - btrfs: make sure we create all new block groups + - Btrfs: fix warning when replaying log after fsync of a tmpfile + - Btrfs: fix wrong dentries after fsync of file that got its parent replaced + - btrfs: qgroup: Dirty all qgroups before rescan + - Btrfs: fix null pointer dereference on compressed write path error + - Btrfs: fix assertion on fsync of regular file when using no-holes feature + - Btrfs: fix deadlock when writing out free space caches + - btrfs: reset max_extent_size properly + - btrfs: set max_extent_size properly + - btrfs: don't use ctl->free_space for max_extent_size + - btrfs: only free reserved extent if we didn't insert it + - btrfs: fix insert_reserved error handling + - btrfs: don't run delayed_iputs in commit + - btrfs: move the dio_sem higher up the callchain + - Btrfs: fix use-after-free during inode eviction + - Btrfs: fix use-after-free when dumping free space + - net: sched: Remove TCA_OPTIONS from policy + - vt: fix broken display when running aptitude + - bpf: wait for running BPF programs when updating map-in-map + - vga_switcheroo: Fix missing gpu_bound call at audio client registration + - MD: fix invalid stored role for a disk - try2 + - Linux 4.19.2 + + * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405) + - KVM: s390: vsie: simulate VCPU SIE entry/exit + - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART + - KVM: s390: refactor crypto initialization + - s390: vfio-ap: base implementation of VFIO AP device driver + - s390: vfio-ap: register matrix device with VFIO mdev framework + - s390: vfio-ap: sysfs interfaces to configure adapters + - s390: vfio-ap: sysfs interfaces to configure domains + - s390: vfio-ap: sysfs interfaces to configure control domains + - s390: vfio-ap: sysfs interface to view matrix mdev matrix + - KVM: s390: interface to clear CRYCB masks + - s390: vfio-ap: implement mediated device open callback + - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl + - s390: vfio-ap: zeroize the AP queues + - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl + - KVM: s390: Clear Crypto Control Block when using vSIE + - KVM: s390: vsie: Do the CRYCB validation first + - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear + - KVM: s390: vsie: Allow CRYCB FORMAT-2 + - KVM: s390: vsie: allow CRYCB FORMAT-1 + - KVM: s390: vsie: allow CRYCB FORMAT-0 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1 + - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2 + - KVM: s390: device attrs to enable/disable AP interpretation + - KVM: s390: CPU model support for AP virtualization + - s390: doc: detailed specifications for AP virtualization + - KVM: s390: fix locking for crypto setting error path + - KVM: s390: Tracing APCB changes + - s390: vfio-ap: setup APCB mask using KVM dedicated function + - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module. + + * Bypass of mount visibility through userns + mount propagation (LP: #1789161) + - mount: Retest MNT_LOCKED in do_umount + - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts + + * CVE-2018-18955: nested user namespaces with more than five extents + incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955 + - userns: also map extents in the reverse map to kernel IDs + + * kdump fail due to an IRQ storm (LP: #1797990) + - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code + - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot + - SAUCE: x86/quirks: Scan all busses for early PCI quirks + + * Disable LPM for Raydium Touchscreens (LP: #1802248) + - USB: quirks: Add no-lpm quirk for Raydium touchscreens + + * Power consumption during s2idle is higher than long idle(sk hynix) + (LP: #1801875) + - SAUCE: pci: prevent sk hynix nvme from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + + * Disco update: v4.19.1 upstream stable release (LP: #1801739) + - bridge: do not add port to router list when receives query with source + 0.0.0.0 + - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are + called + - net/mlx5e: fix csum adjustments caused by RXFCS + - net: sched: gred: pass the right attribute to gred_change_table_def() + - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules + - net: udp: fix handling of CHECKSUM_COMPLETE packets + - Revert "net: simplify sock_poll_wait" + - rtnetlink: Disallow FDB configuration for non-Ethernet device + - vhost: Fix Spectre V1 vulnerability + - bonding: fix length of actor system + - openvswitch: Fix push/pop ethernet validation + - net/ipv6: Allow onlink routes to have a device mismatch if it is the default + route + - net/smc: fix smc_buf_unuse to use the lgr pointer + - mlxsw: spectrum_switchdev: Don't ignore deletions of learned MACs + - mlxsw: core: Fix devlink unregister flow + - net: drop skb on failure in ip_check_defrag() + - net: Properly unlink GRO packets on overflow. + - r8169: fix broken Wake-on-LAN from S5 (poweroff) + - Revert "be2net: remove desc field from be_eq_obj" + - sctp: check policy more carefully when getting pr status + - sparc64: Export __node_distance. + - sparc64: Make corrupted user stacks more debuggable. + - sparc64: Wire up compat getpeername and getsockname. + - net: bridge: remove ipv6 zero address check in mcast queries + - Linux 4.19.1 + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.11-1ubuntu1, zfs to 0.7.11-3ubuntu1 + - [Config] updateconfigs after 4.19.2 stable update + - [Config] Disable unneded options for s390 + - [Config] Update annotations for 4.19 + + -- Seth Forshee Thu, 15 Nov 2018 09:55:37 -0800 + +linux (4.19.0-4.5) disco; urgency=medium + + * Add checksum offload and TSO support for HiNIC adapters (LP: #1800664) + - net-next/hinic: add checksum offload and TSO support + + * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater + than 255 bytes (LP: #1799794) + - ipmi:ssif: Add support for multi-part transmit messages > 2 parts + + * Packaging resync (LP: #1786013) + - [Package] add support for specifying the primary makefile + + * Update ENA driver to version 2.0.1K (LP: #1798182) + - net: ena: minor performance improvement + - net: ena: complete host info to match latest ENA spec + - net: ena: introduce Low Latency Queues data structures according to ENA spec + - net: ena: add functions for handling Low Latency Queues in ena_com + - net: ena: add functions for handling Low Latency Queues in ena_netdev + - net: ena: use CSUM_CHECKED device indication to report skb's checksum status + - net: ena: explicit casting and initialization, and clearer error handling + - net: ena: limit refill Rx threshold to 256 to avoid latency issues + - net: ena: change rx copybreak default to reduce kernel memory pressure + - net: ena: remove redundant parameter in ena_com_admin_init() + - net: ena: update driver version to 2.0.1 + - net: ena: fix indentations in ena_defs for better readability + - net: ena: Fix Kconfig dependency on X86 + - net: ena: enable Low Latency Queues + - net: ena: fix compilation error in xtensa architecture + + * [Bionic][Cosmic] ipmi: Fix timer race with module unload (LP: #1799281) + - ipmi: Fix timer race with module unload + + * Overlayfs in user namespace leaks directory content of inaccessible + directories (LP: #1793458) // CVE-2018-6559 + - SAUCE: overlayfs: ensure mounter privileges when reading directories + + * not able to unwind the stack from within __kernel_clock_gettime in the Linux + vDSO (LP: #1797963) + - powerpc/vdso: Correct call frame information + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Don't print secure boot state + from the efi stub" + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() use + efi_status_to_str() to print error messages." + - Revert "UBUNTU: SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err()." + - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() not complain + about cert lists that aren't present." + - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable + to be suppressed" + - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI + Secure Boot" + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser" + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add EFI signature data types" + - Revert "UBUNTU: SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time + addition of keys to secondary keyring" + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in + secure boot mode" + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to + indicate secure boot mode" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Copy secure_boot flag in boot params + across kexec reboot" + - Revert "UBUNTU: SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down perf" + - Revert "UBUNTU: SAUCE: (efi-lockdown) bpf: Restrict kernel image access + functions when the kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down kprobes" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down /proc/kcore" + - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the + testmmiotrace module" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down module params that specify + hardware parameters (eg. ioport)" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down TIOCSSERIAL" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable APEI error injection if + the kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable ACPI table override if + the kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param + when the kernel has been locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) ACPI: Limit access to custom_method + when the kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) x86: Lock down IO port access when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) PCI: Lock down BAR access when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is + locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) hibernate: Disable when the kernel is + locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Enforce module signatures if the + kernel is locked down" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Add a SysRq option to lift kernel + lockdown" + - Revert "UBUNTU: SAUCE: (efi-lockdown) Add the ability to lock down access to + the running kernel image" + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) efi/x86: Call efi_parse_options() from efi_main() + - SAUCE: (efi-lockdown) Fix for module sig verification + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules + - [Packaging] generate Vcs-Git url from changelog + - [Config] CONFIG_SCSI_MQ_DEFAULT=y + + -- Seth Forshee Fri, 02 Nov 2018 14:22:55 -0500 + +linux (4.19.0-3.4) cosmic; urgency=medium + + * Support Edge Gateway's Bluetooth LED (LP: #1798332) + - SAUCE: Bluetooth: Support for LED on Edge Gateways + + * Support Edge Gateway's WIFI LED (LP: #1798330) + - SAUCE: mwifiex: Switch WiFi LED state according to the device status + + [ Upstream Kernel Changes ] + + * Rebase to v4.19 + + -- Seth Forshee Mon, 22 Oct 2018 09:13:39 -0500 + +linux (4.19.0-2.3) cosmic; urgency=medium + + * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314) + - SAUCE: fscache: Fix race in decrementing refcount of op->npages + + * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957) + - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same + VM + + * The front MIC can't work on the Lenovo M715 (LP: #1797292) + - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715 + + * arm64: snapdragon: WARNING: CPU: 0 PID: 1 at drivers/irqchip/irq-gic.c:1016 + gic_irq_domain_translate (LP: #1797143) + - SAUCE: arm64: dts: msm8916: camms: fix gic_irq_domain_translate warnings + + * Dell new AIO requires a new uart backlight driver (LP: #1727235) + - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO + - updateconfigs for Dell UART backlight driver + + * Please make CONFIG_PWM_LPSS_PCI and CONFIG_PWM_LPSS_PLATFORM built in to + make brightness adjustment working on various BayTrail/CherryTrail-based + devices (LP: #1783964) + - [Config]: Make PWM_LPSS_* built-in + + * check and fix zkey required kernel modules locations in debs, udebs, and + initramfs (LP: #1794346) + - [Config] add s390 crypto modules to crypt-modules udeb + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_VBOXGUEST=n + - ubuntu: vbox -- update to 5.2.18-dfsg-2 + - ubuntu: enable vbox build + + [ Upstream Kernel Changes ] + + * Rebase to v4.19-rc8 + + -- Seth Forshee Mon, 15 Oct 2018 10:52:04 -0500 + +linux (4.19.0-1.2) cosmic; urgency=medium + + * Page leaking in cachefiles_read_backing_file while vmscan is active + (LP: #1793430) + - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan + is active + + * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463) + - Input: elantech - enable middle button of touchpad on ThinkPad P72 + + * Improvements to the kernel source package preparation (LP: #1793461) + - [Packaging] startnewrelease: add support for backport kernels + + * Fix unusable NVIDIA GPU after S3 (LP: #1793338) + - SAUCE: PCI: Reprogram bridge prefetch registers on resume + + * Error reported when creating ZFS pool with "-t" option, despite successful + pool creation (LP: #1769937) + - SAUCE: (noup) Update zfs to 0.7.9-3ubuntu6 + + * device hotplug of vfio devices can lead to deadlock in vfio_pci_release + (LP: #1792099) + - SAUCE: vfio -- release device lock before userspace requests + + * Miscellaneous Ubuntu changes + - [Packaging] retpoline -- fix temporary filenaming + - CONFIG_BCH_CONST_PARAMS=n + - Packaging: final-checks: remove trailing backport suffix + - SAUCE: import aufs driver + + [ Upstream Kernel Changes ] + + * Rebase to v4.19-rc5 + + -- Seth Forshee Tue, 25 Sep 2018 16:32:24 -0500 + +linux (4.19.0-0.1) cosmic; urgency=medium + + * Miscellaneous Ubuntu changes + - ubuntu -- disable vbox build + - Disable zfs build + - SAUCE: Import aufs driver + - Update dropped.txt + + [ Upstream Kernel Changes ] + + * Rebase to v4.19-rc3 + + -- Seth Forshee Thu, 13 Sep 2018 07:54:47 -0500 + +linux (4.19.0-0.0) cosmic; urgency=medium + + * Dummy entry. + + -- Seth Forshee Thu, 13 Sep 2018 06:44:09 -0500 + +linux (4.18.0-8.9) cosmic; urgency=medium + + * linux: 4.18.0-8.9 -proposed tracker (LP: #1791663) + + * Cosmic update to v4.18.7 stable release (LP: #1791660) + - rcu: Make expedited GPs handle CPU 0 being offline + - net: 6lowpan: fix reserved space for single frames + - net: mac802154: tx: expand tailroom if necessary + - 9p/net: Fix zero-copy path in the 9p virtio transport + - spi: davinci: fix a NULL pointer dereference + - spi: pxa2xx: Add support for Intel Ice Lake + - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe + - spi: cadence: Change usleep_range() to udelay(), for atomic context + - mmc: block: Fix unsupported parallel dispatch of requests + - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts + - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS + - readahead: stricter check for bdi io_pages + - block: fix infinite loop if the device loses discard capability + - block: blk_init_allocated_queue() set q->fq as NULL in the fail case + - block: really disable runtime-pm for blk-mq + - blkcg: Introduce blkg_root_lookup() + - block: Introduce blk_exit_queue() + - block: Ensure that a request queue is dissociated from the cgroup controller + - apparmor: fix bad debug check in apparmor_secid_to_secctx() + - dma-buf: Move BUG_ON from _add_shared_fence to _add_shared_inplace + - libertas: fix suspend and resume for SDIO connected cards + - media: Revert "[media] tvp5150: fix pad format frame height" + - mailbox: xgene-slimpro: Fix potential NULL pointer dereference + - Replace magic for trusting the secondary keyring with #define + - Fix kexec forbidding kernels signed with keys in the secondary keyring to + boot + - powerpc/fadump: handle crash memory ranges array index overflow + - powerpc/64s: Fix page table fragment refcount race vs speculative references + - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler. + - powerpc/pkeys: Give all threads control of their key permissions + - powerpc/pkeys: Deny read/write/execute by default + - powerpc/pkeys: key allocation/deallocation must not change pkey registers + - powerpc/pkeys: Save the pkey registers before fork + - powerpc/pkeys: Fix calculation of total pkeys. + - powerpc/pkeys: Preallocate execute-only key + - powerpc/nohash: fix pte_access_permitted() + - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls + - powerpc/powernv/pci: Work around races in PCI bridge enabling + - cxl: Fix wrong comparison in cxl_adapter_context_get() + - IB/mlx5: Honor cnt_set_id_valid flag instead of set_id + - IB/mlx5: Fix leaking stack memory to userspace + - IB/srpt: Fix srpt_cm_req_recv() error path (1/2) + - IB/srpt: Fix srpt_cm_req_recv() error path (2/2) + - IB/srpt: Support HCAs with more than two ports + - overflow.h: Add arithmetic shift helper + - RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq + - ib_srpt: Fix a use-after-free in srpt_close_ch() + - ib_srpt: Fix a use-after-free in __srpt_close_all_ch() + - RDMA/rxe: Set wqe->status correctly if an unexpected response is received + - 9p: fix multiple NULL-pointer-dereferences + - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed + - 9p/virtio: fix off-by-one error in sg list bounds check + - net/9p/client.c: version pointer uninitialized + - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the + kfree() + - dm integrity: change 'suspending' variable from bool to int + - dm thin: stop no_space_timeout worker when switching to write-mode + - dm cache metadata: save in-core policy_hint_size to on-disk superblock + - dm cache metadata: set dirty on all cache blocks after a crash + - dm crypt: don't decrease device limits + - dm writecache: fix a crash due to reading past end of dirty_bitmap + - uart: fix race between uart_put_char() and uart_shutdown() + - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer() + - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind() + - iio: sca3000: Fix missing return in switch + - iio: ad9523: Fix displayed phase + - iio: ad9523: Fix return value for ad952x_store() + - extcon: Release locking when sending the notification of connector state + - eventpoll.h: wrap casts in () properly + - vmw_balloon: fix inflation of 64-bit GFNs + - vmw_balloon: do not use 2MB without batching + - vmw_balloon: VMCI_DOORBELL_SET does not check status + - vmw_balloon: fix VMCI use when balloon built into kernel + - rtc: omap: fix resource leak in registration error path + - rtc: omap: fix potential crash on power off + - tracing: Do not call start/stop() functions when tracing_on does not change + - tracing/blktrace: Fix to allow setting same value + - printk/tracing: Do not trace printk_nmi_enter() + - livepatch: Validate module/old func name length + - uprobes: Use synchronize_rcu() not synchronize_sched() + - mfd: hi655x: Fix regmap area declared size for hi655x + - ovl: fix wrong use of impure dir cache in ovl_iterate() + - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure + - ACPICA: Clear status of all events when entering sleep states + - drivers/block/zram/zram_drv.c: fix bug storing backing_dev + - sched: idle: Avoid retaining the tick when it has been stopped + - cpuidle: menu: Handle stopped tick more aggressively + - cpufreq: governor: Avoid accessing invalid governor_data + - PM / sleep: wakeup: Fix build error caused by missing SRCU support + - ALSA: ac97: fix device initialization in the compat layer + - ALSA: ac97: fix check of pm_runtime_get_sync failure + - ALSA: ac97: fix unbalanced pm_runtime_enable + - i2c: designware: Re-init controllers with pm_disabled set on resume + - KVM: VMX: fixes for vmentry_l1d_flush module parameter + - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages + - xtensa: limit offsets in __loop_cache_{all,page} + - xtensa: increase ranges in ___invalidate_{i,d}cache_all + - block, bfq: return nbytes and not zero from struct cftype .write() method + - pnfs/blocklayout: off by one in bl_map_stripe() + - nfsd: fix leaked file lock with nfs exported overlayfs + - NFSv4 client live hangs after live data migration recovery + - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs + - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence() + - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset + - ARM: dts: am57xx-idk: Enable dual role for USB2 port + - pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data + - mm/tlb: Remove tlb_remove_table() non-concurrent condition + - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU- + VMSA + - iommu/vt-d: Add definitions for PFSID + - iommu/vt-d: Fix dev iotlb pfsid use + - sys: don't hold uts_sem while accessing userspace memory + - userns: move user access out of the mutex + - ubifs: Fix memory leak in lprobs self-check + - Revert "UBIFS: Fix potential integer overflow in allocation" + - ubifs: Check data node size before truncate + - ubifs: xattr: Don't operate on deleted inodes + - ubifs: Fix directory size calculation for symlinks + - ubifs: Fix synced_i_size calculation for xattr inodes + - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output + - pwm: tiehrpwm: Fix disabling of output of PWMs + - fb: fix lost console when the user unplugs a USB adapter + - udlfb: fix semaphore value leak + - udlfb: fix display corruption of the last line + - udlfb: don't switch if we are switching to the same videomode + - udlfb: set optimal write delay + - udlfb: make a local copy of fb_ops + - udlfb: handle allocation failure + - udlfb: set line_length in dlfb_ops_set_par + - getxattr: use correct xattr length + - libnvdimm: Use max contiguous area for namespace size + - libnvdimm: fix ars_status output length calculation + - bcache: release dc->writeback_lock properly in bch_writeback_thread() + - kconfig: fix "Can't open ..." in parallel build + - perf auxtrace: Fix queue resize + - crypto: vmx - Fix sleep-in-atomic bugs + - crypto: aesni - Use unaligned loads from gcm_context_data + - crypto: arm64/sm4-ce - check for the right CPU feature bit + - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3 + - crypto: caam/jr - fix descriptor DMA unmapping + - crypto: caam/qi - fix error path in xts setkey + - fs/quota: Fix spectre gadget in do_quotactl + - udf: Fix mounting of Win7 created UDF filesystems + - cpuidle: menu: Retain tick when shallow state is selected + - arm64: mm: always enable CONFIG_HOLES_IN_ZONE + - Linux 4.18.7 + + * CVE-2017-5715 + - s390: detect etoken facility + - KVM: s390: add etoken support for guests + + * Missing Intel GPU pci-id's (LP: #1789924) + - drm/i915/whl: Introducing Whiskey Lake platform + - drm/i915/aml: Introducing Amber Lake platform + - drm/i915/cfl: Add a new CFL PCI ID. + + * [18.10 FEAT] Add kernel config options for SMC-R/D (LP: #1789934) + - s390/ism: add device driver for internal shared memory + - CONFIG_ISM=y for s390 + + * Cosmic update to v4.18.6 stable release (LP: #1791105) + - PATCH scripts/kernel-doc + - scripts/kernel-doc: Escape all literal braces in regexes + - scsi: libsas: dynamically allocate and free ata host + - xprtrdma: Fix disconnect regression + - mei: don't update offset in write + - cifs: add missing support for ACLs in SMB 3.11 + - CIFS: fix uninitialized ptr deref in smb2 signing + - cifs: add missing debug entries for kconfig options + - cifs: use a refcount to protect open/closing the cached file handle + - cifs: check kmalloc before use + - smb3: enumerating snapshots was leaving part of the data off end + - smb3: Do not send SMB3 SET_INFO if nothing changed + - smb3: don't request leases in symlink creation and query + - smb3: fill in statfs fsid and correct namelen + - btrfs: use correct compare function of dirty_metadata_bytes + - btrfs: don't leak ret from do_chunk_alloc + - Btrfs: fix mount failure after fsync due to hard link recreation + - Btrfs: fix btrfs_write_inode vs delayed iput deadlock + - Btrfs: fix send failure when root has deleted files still open + - Btrfs: send, fix incorrect file layout after hole punching beyond eof + - hwmon: (k10temp) 27C Offset needed for Threadripper2 + - bpf, arm32: fix stack var offset in jit + - regulator: arizona-ldo1: Use correct device to get enable GPIO + - iommu/arm-smmu: Error out only if not enough context interrupts + - printk: Split the code for storing a message into the log buffer + - printk: Create helper function to queue deferred console handling + - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI + - kprobes/arm64: Fix %p uses in error messages + - arm64: Fix mismatched cache line size detection + - arm64: Handle mismatched cache type + - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid() + - arm64: dts: rockchip: corrected uart1 clock-names for rk3328 + - KVM: arm/arm64: Fix potential loss of ptimer interrupts + - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked + - KVM: arm/arm64: Skip updating PMD entry if no change + - KVM: arm/arm64: Skip updating PTE entry if no change + - s390/kvm: fix deadlock when killed by oom + - perf kvm: Fix subcommands on s390 + - stop_machine: Reflow cpu_stop_queue_two_works() + - stop_machine: Atomically queue and wake stopper threads + - ext4: check for NUL characters in extended attribute's name + - ext4: use ext4_warning() for sb_getblk failure + - ext4: sysfs: print ext4_super_block fields as little-endian + - ext4: reset error code in ext4_find_entry in fallback + - ext4: fix race when setting the bitmap corrupted flag + - x86/gpu: reserve ICL's graphics stolen memory + - platform/x86: wmi: Do not mix pages and kmalloc + - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too + - mm: move tlb_table_flush to tlb_flush_mmu_free + - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE + - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit + - x86/speculation/l1tf: Fix off-by-one error when warning that system has too + much RAM + - x86/speculation/l1tf: Suggest what to do on systems with too much RAM + - x86/vdso: Fix vDSO build if a retpoline is emitted + - x86/process: Re-export start_thread() + - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd + - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled + - fuse: Don't access pipe->buffers without pipe_lock() + - fuse: fix initial parallel dirops + - fuse: fix double request_end() + - fuse: fix unlocked access to processing queue + - fuse: umount should wait for all requests + - fuse: Fix oops at process_init_reply() + - fuse: Add missed unlock_page() to fuse_readpages_fill() + - lib/vsprintf: Do not handle %pO[^F] as %px + - udl-kms: change down_interruptible to down + - udl-kms: handle allocation failure + - udl-kms: fix crash due to uninitialized memory + - udl-kms: avoid division + - b43legacy/leds: Ensure NUL-termination of LED name string + - b43/leds: Ensure NUL-termination of LED name string + - ASoC: dpcm: don't merge format from invalid codec dai + - ASoC: zte: Fix incorrect PCM format bit usages + - ASoC: sirf: Fix potential NULL pointer dereference + - ASoC: wm_adsp: Correct DSP pointer for preloader control + - soc: qcom: rmtfs-mem: fix memleak in probe error paths + - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show() + - scsi: qla2xxx: Fix stalled relogin + - x86/vdso: Fix lsl operand order + - x86/nmi: Fix NMI uaccess race against CR3 switching + - x86/irqflags: Mark native_restore_fl extern inline + - x86/spectre: Add missing family 6 check to microcode check + - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+ + - hwmon: (nct6775) Fix potential Spectre v1 + - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit() + - x86: Allow generating user-space headers without a compiler + - s390/mm: fix addressing exception after suspend/resume + - s390/lib: use expoline for all bcr instructions + - s390: fix br_r1_trampoline for machines without exrl + - s390/qdio: reset old sbal_state flags + - s390/numa: move initial setup of node_to_cpumask_map + - s390/purgatory: Fix crash with expoline enabled + - s390/purgatory: Add missing FORCE to Makefile targets + - kprobes: Show blacklist addresses as same as kallsyms does + - kprobes: Replace %p with other pointer types + - kprobes/arm: Fix %p uses in error messages + - kprobes: Make list and blacklist root user read only + - MIPS: Correct the 64-bit DSP accumulator register size + - MIPS: memset.S: Fix byte_fixup for MIPSr6 + - MIPS: Always use -march=, not - shortcuts + - MIPS: Change definition of cpu_relax() for Loongson-3 + - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7 + - tpm: Return the actual size when receiving an unsupported command + - tpm: separate cmd_ready/go_idle from runtime_pm + - scsi: mpt3sas: Fix calltrace observed while running IO & reset + - scsi: mpt3sas: Fix _transport_smp_handler() error path + - scsi: sysfs: Introduce sysfs_{un,}break_active_protection() + - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock + - iscsi target: fix session creation failure handling + - mtd: rawnand: hynix: Use ->exec_op() in hynix_nand_reg_write_op() + - mtd: rawnand: fsmc: Stop using chip->read_buf() + - mtd: rawnand: marvell: add suspend and resume hooks + - mtd: rawnand: qcom: wait for desc completion in all BAM channels + - clk: rockchip: fix clk_i2sout parent selection bits on rk3399 + - clk: npcm7xx: fix memory allocation + - PM / clk: signedness bug in of_pm_clk_add_clks() + - power: generic-adc-battery: fix out-of-bounds write when copying channel + properties + - power: generic-adc-battery: check for duplicate properties copied from iio + channels + - watchdog: Mark watchdog touch functions as notrace + - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status + - x86/dumpstack: Don't dump kernel memory based on usermode RIP + - Linux 4.18.6 + - updateconfigs after v4.18.6 stable update + + * random oopses on s390 systems using NVMe devices (LP: #1790480) + - s390/pci: fix out of bounds access during irq setup + + * [18.10 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver + binding (LP: #1784331) + - s390/zcrypt: code beautify + - s390/zcrypt: AP bus support for alternate driver(s) + - s390/zcrypt: hex string mask improvements for apmask and aqmask. + + * performance drop with ATS enabled (LP: #1788097) + - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage + + * Fix MCE handling for user access of poisoned device-dax mapping + (LP: #1774366) + - device-dax: Convert to vmf_insert_mixed and vm_fault_t + - device-dax: Enable page_mapping() + - device-dax: Set page->index + - filesystem-dax: Set page->index + - mm, madvise_inject_error: Disable MADV_SOFT_OFFLINE for ZONE_DEVICE pages + - mm, dev_pagemap: Do not clear ->mapping on final put + - mm, madvise_inject_error: Let memory_failure() optionally take a page + reference + - mm, memory_failure: Collect mapping size in collect_procs() + - filesystem-dax: Introduce dax_lock_mapping_entry() + - mm, memory_failure: Teach memory_failure() about dev_pagemap pages + - x86/mm/pat: Prepare {reserve, free}_memtype() for "decoy" addresses + - x86/memory_failure: Introduce {set, clear}_mce_nospec() + - libnvdimm, pmem: Restore page attributes when clearing errors + + * Reconcile hns3 SAUCE patches with upstream (LP: #1787477) + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for + hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and + shift in hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default + assignment probelm" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring + configuration operation while resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell + phy driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when + resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status + register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset + frequently" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing + command queue register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during + global or core reset" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce + callback function" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear + reset cause" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in + hclgevf_main module" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp + selftest" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal + frame size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated + problem" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting + correctly" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in + pfc mode" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first + up" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback + function when link status change" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying + roce client" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and + definition" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return + value" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead + of kzalloc/dma_map_single" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while + dependency HNS3 set" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of + some structures" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant + hclge_cmd_csq_done" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters + in hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in + hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused + hclge_ring_to_dma_dir" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and + upper_32_bits" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector + in hns3_client_uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error + information" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state + state init|uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in + hnae3.c" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4 + and ipv6" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before + free vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for + init_client_instance and uninit_client_instance" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index + from hclge_bind_ring_with_vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in + last BD except VLD bit and buffer size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback + selftest" + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector + - net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - net: hns3: add vector status check before free vector + - net: hns3: add l4_type check for both ipv4 and ipv6 + - net: hns3: add unlikely for error check + - net: hns3: remove unused head file in hnae3.c + - net: hns3: extraction an interface for state init|uninit + - net: hns3: print the ret value in error information + - net: hns3: remove the Redundant put_vector in hns3_client_uninit + - net: hns3: remove back in struct hclge_hw + - net: hns3: use lower_32_bits and upper_32_bits + - net: hns3: remove unused hclge_ring_to_dma_dir + - net: hns3: remove useless code in hclge_cmd_send + - net: hns3: remove some redundant assignments + - net: hns3: simplify hclge_cmd_csq_clean + - net: hns3: remove a redundant hclge_cmd_csq_done + - net: hns3: remove some unused members of some structures + - net: hns3: give default option while dependency HNS3 set + - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single + - net: hns3: modify hnae_ to hnae3_ + - net: hns3: Fix tc setup when netdev is first up + - net: hns3: Fix for mac pause not disable in pfc mode + - net: hns3: Fix for waterline not setting correctly + - net: hns3: Fix for l4 checksum offload bug + - net: hns3: Fix for mailbox message truncated problem + - net: hns3: Add configure for mac minimal frame size + - net: hns3: Fix warning bug when doing lp selftest + - net: hns3: Fix get_vector ops in hclgevf_main module + - net: hns3: Remove the warning when clear reset cause + - net: hns3: Prevent sending command during global or core reset + - net: hns3: Modify the order of initializing command queue register + - net: hns3: Reset net device with rtnl_lock + - net: hns3: Prevent to request reset frequently + - net: hns3: Correct reset event status register + - net: hns3: Fix return value error in hns3_reset_notify_down_enet + - net: hns3: remove unnecessary ring configuration operation while resetting + - net: hns3: Fix for reset_level default assignment probelm + - net: hns3: Fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx + - net: hns3: Remove some redundant assignments + - net: hns3: Standardize the handle of return value + - net: hns3: Remove extra space and brackets + - net: hns3: Correct unreasonable code comments + - net: hns3: Use decimal for bit offset macros + - net: hns3: Modify inconsistent bit mask macros + - net: hns3: Fix misleading parameter name + - net: hns3: Remove unused struct member and definition + - net: hns3: Add SPDX tags to HNS3 PF driver + - net: hns3: Add support for serdes loopback selftest + - net: hns3: Fix for phy link issue when using marvell phy driver + + * [Regression] kernel crashdump fails on arm64 (LP: #1786878) + - arm64: export memblock_reserve()d regions via /proc/iomem + - drivers: acpi: add dependency of EFI for arm64 + - efi/arm: preserve early mapping of UEFI memory map longer for BGRT + - efi/arm: map UEFI memory map even w/o runtime services enabled + - arm64: acpi: fix alignment fault in accessing ACPI + - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y + - arm64: fix ACPI dependencies + - ACPI: fix menuconfig presentation of ACPI submenu + + * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780) + - r8152: disable RX aggregation on new Dell TB16 dock + + * Support Power Management for Thunderbolt Controller (LP: #1789358) + - thunderbolt: Use 64-bit DMA mask if supported by the platform + - thunderbolt: Do not unnecessarily call ICM get route + - thunderbolt: No need to take tb->lock in domain suspend/complete + - thunderbolt: Use correct ICM commands in system suspend + - thunderbolt: Add support for runtime PM + + * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940) + - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform + - SAUCE: i2c:amd move out pointer in union i2c_event_base + - SAUCE: i2c:amd Depends on ACPI + - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86 + + * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4 + machine (LP: #1789145) + - ALSA: hda/realtek - Fix HP Headset Mic can't record + + * Please enable CONFIG_PAGE_POISONING (LP: #1783651) + - [Config] Enable CONFIG_PAGE_POISONING configs + + * Tango platform uses __initcall without further checks (LP: #1787945) + - [Config] disable ARCH_TANGO + + * [18.10 FEAT] SMC-Direct (LP: #1786902) + - net/smc: determine port attributes independent from pnet table + - net/smc: add pnetid support + - net/smc: add base infrastructure for SMC-D and ISM + - net/smc: add pnetid support for SMC-D and ISM + - net/smc: add SMC-D support in CLC messages + - net/smc: add SMC-D support in data transfer + - net/smc: add SMC-D support in af_smc + - net/smc: add SMC-D diag support + - net/smc: provide smc mode in smc_diag.c + - net/smc: eliminate cursor read and write calls + - net/smc: add function to get link group from link + - net/smc: use DECLARE_BITMAP for rtokens_used_mask + - net/smc: remove local variable page in smc_rx_splice() + - net/smc: Remove a WARN_ON() statement + - net/smc: Simplify ib_post_(send|recv|srq_recv)() calls + - net/smc: fewer parameters for smc_llc_send_confirm_link() + - net/smc: use correct vlan gid of RoCE device + - net/smc: provide fallback reason code + - net/smc: improve delete link processing + - net: simplify sock_poll_wait + - net/smc: send response to test link signal + + * Miscellaneous Ubuntu changes + - [Config] update annotations for CONFIG_CRYPTO_SPECK_NEON + - [Config] fix up annotatios for CONFIG_CRYPTO_SPECK + + -- Seth Forshee Mon, 10 Sep 2018 07:08:38 -0500 + +linux (4.18.0-7.8) cosmic; urgency=medium + + * linux: 4.18.0-7.8 -proposed tracker (LP: #1789459) + + * pmtu.sh fails on 4.18 kernel (LP: #1789436) + - SAUCE: Revert "vti6: fix PMTU caching and reporting on xmit" + + -- Seth Forshee Tue, 28 Aug 2018 11:08:51 -0500 + +linux (4.18.0-6.7) cosmic; urgency=medium + + * linux: 4.18.0-6.7 -proposed tracker (LP: #1788881) + + * systemd 237-3ubuntu10 ADT test failure with linux 4.18.0-5.6 (LP: #1787440) + - Config: Disable BPF_JIT_ALWAYS_ON on i386 + + * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729) + - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias() + + * Cosmic update to v4.18.5 stable release (LP: #1788874) + - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[] + - pty: fix O_CLOEXEC for TIOCGPTPEER + - mm: Allow non-direct-map arguments to free_reserved_area() + - x86/mm/init: Pass unconverted symbol addresses to free_init_pages() + - x86/mm/init: Add helper for freeing kernel image pages + - x86/mm/init: Remove freed kernel image areas from alias mapping + - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2 + - ext4: fix spectre gadget in ext4_mb_regular_allocator() + - drm/i915/kvmgt: Fix potential Spectre v1 + - drm/amdgpu/pm: Fix potential Spectre v1 + - parisc: Remove unnecessary barriers from spinlock.h + - parisc: Remove ordered stores from syscall.S + - PCI: Restore resized BAR state on resume + - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM + - PCI: hotplug: Don't leak pci_slot on registration failure + - PCI: aardvark: Size bridges before resources allocation + - PCI: Skip MPS logic for Virtual Functions (VFs) + - PCI: pciehp: Fix use-after-free on unplug + - PCI: pciehp: Fix unprotected list iteration in IRQ handler + - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes + - i2c: imx: Fix race condition in dma read + - reiserfs: fix broken xattr handling (heap corruption, bad retval) + - Linux 4.18.5 + + * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898) + - [Config] CONFIG_SCLP_OFB=y for s390x + + * errors when scanning partition table of corrupted AIX disk (LP: #1787281) + - partitions/aix: fix usage of uninitialized lv_info and lvname structures + - partitions/aix: append null character to print data from disk + + * Apply NVMe bugfix from Google that bjf asked for (LP: #1787635) + - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event + + * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058) + - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio + + * Cosmic update to v4.18.4 stable release (LP: #1788454) + - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache + - net_sched: fix NULL pointer dereference when delete tcindex filter + - net_sched: Fix missing res info when create new tc_index filter + - r8169: don't use MSI-X on RTL8168g + - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs + - ALSA: hda - Turn CX8200 into D3 as well upon reboot + - ALSA: vx222: Fix invalid endian conversions + - ALSA: virmidi: Fix too long output trigger loop + - ALSA: cs5535audio: Fix invalid endian conversion + - ALSA: dice: fix wrong copy to rx parameters for Alesis iO26 + - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry + - ALSA: memalloc: Don't exceed over the requested size + - ALSA: vxpocket: Fix invalid endian conversions + - ALSA: seq: Fix poll() error return + - media: gl861: fix probe of dvb_usb_gl861 + - USB: serial: sierra: fix potential deadlock at close + - USB: serial: pl2303: add a new device id for ATEN + - USB: option: add support for DW5821e + - ACPI / PM: save NVS memory for ASUS 1025C laptop + - tty: serial: 8250: Revert NXP SC16C2552 workaround + - serial: 8250_exar: Read INT0 from slave device, too + - serial: 8250_dw: always set baud rate in dw8250_set_termios + - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC + - uio: fix wrong return value from uio_mmap() + - misc: sram: fix resource leaks in probe error path + - Revert "uio: use request_threaded_irq instead" + - Bluetooth: avoid killing an already killed socket + - isdn: Disable IIOCDBGVAR + - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd() + - hv/netvsc: Fix NULL dereference at single queue mode fallback + - r8169: don't use MSI-X on RTL8106e + - ip_vti: fix a null pointer deferrence when create vti fallback tunnel + - net: ethernet: mvneta: Fix napi structure mixup on armada 3700 + - net: mvneta: fix mvneta_config_rss on armada 3700 + - cls_matchall: fix tcf_unbind_filter missing + - Linux 4.18.4 + + * Cosmic update to v4.18.3 stable release (LP: #1788453) + - x86/speculation/l1tf: Exempt zeroed PTEs from inversion + - Linux 4.18.3 + + * Cosmic update to v4.18.2 stable release (LP: #1788452) + - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled + - x86: i8259: Add missing include file + - x86/hyper-v: Check for VP_INVAL in hyperv_flush_tlb_others() + - x86/platform/UV: Mark memblock related init code and data correctly + - x86/mm/pti: Clear Global bit more aggressively + - xen/pv: Call get_cpu_address_sizes to set x86_virt/phys_bits + - x86/mm: Disable ioremap free page handling on x86-PAE + - kbuild: verify that $DEPMOD is installed + - crypto: ccree - fix finup + - crypto: ccree - fix iv handling + - crypto: ccp - Check for NULL PSP pointer at module unload + - crypto: ccp - Fix command completion detection race + - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2() + - crypto: vmac - require a block cipher with 128-bit block size + - crypto: vmac - separate tfm and request context + - crypto: blkcipher - fix crash flushing dcache in error path + - crypto: ablkcipher - fix crash flushing dcache in error path + - crypto: skcipher - fix aligning block size in skcipher_copy_iv() + - crypto: skcipher - fix crash flushing dcache in error path + - ioremap: Update pgtable free interfaces with addr + - x86/mm: Add TLB purge to free pmd/pte page interfaces + - Linux 4.18.2 + + * Cosmic update to v4.18.2 stable release (LP: #1788452) // CVE-2018-9363 + - Bluetooth: hidp: buffer overflow in hidp_process_report + + * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before + walinuxagent.service (LP: #1739107) + - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before + walinuxagent.service + + * Miscellaneous Ubuntu changes + - SAUCE: ipvs: remove nbsp characters from Kconfig + - [Config] CONFIG_MPROFILE_KERNEL=y for ppc64el + - [Config] CONFIG_DRM_RCAR_LVDS=m for snapdragon + - [Config] CONFIG_MDIO_MSCC_MIIM=n for s390x + - [Config] CONFIG_NET_VENDOR_MICROSEMI=n, CONFIG_NET_VENDOR_NI=n for s390x + - [Config] update annotations following config review + - [Debian] set CROSS_COMPILE when generating kernel configs + - [Config] Disable the Speck cipher + + -- Seth Forshee Fri, 24 Aug 2018 14:18:15 -0500 + +linux (4.18.0-5.6) cosmic; urgency=medium + + * Cosmic update to v4.18.1 stable release (LP: #1787264) + - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests + - x86/speculation: Protect against userspace-userspace spectreRSB + - kprobes/x86: Fix %p uses in error messages + - x86/irqflags: Provide a declaration for native_save_fl + - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT + - x86/speculation/l1tf: Change order of offset/type in swap entry + - x86/speculation/l1tf: Protect swap entries against L1TF + - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation + - x86/speculation/l1tf: Make sure the first page is always reserved + - x86/speculation/l1tf: Add sysfs reporting for l1tf + - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings + - x86/speculation/l1tf: Limit swap file size to MAX_PA/2 + - x86/bugs: Move the l1tf function and define pr_fmt properly + - sched/smt: Update sched_smt_present at runtime + - x86/smp: Provide topology_is_primary_thread() + - x86/topology: Provide topology_smt_supported() + - cpu/hotplug: Make bringup/teardown of smp threads symmetric + - cpu/hotplug: Split do_cpu_down() + - cpu/hotplug: Provide knobs to control SMT + - x86/cpu: Remove the pointless CPU printout + - x86/cpu/AMD: Remove the pointless detect_ht() call + - x86/cpu/common: Provide detect_ht_early() + - x86/cpu/topology: Provide detect_extended_topology_early() + - x86/cpu/intel: Evaluate smp_num_siblings early + - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info + - x86/cpu/AMD: Evaluate smp_num_siblings early + - x86/apic: Ignore secondary threads if nosmt=force + - x86/speculation/l1tf: Extend 64bit swap file size limit + - x86/cpufeatures: Add detection of L1D cache flush support. + - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings + - x86/speculation/l1tf: Protect PAE swap entries against L1TF + - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE + - Revert "x86/apic: Ignore secondary threads if nosmt=force" + - cpu/hotplug: Boot HT siblings at least once + - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present + - x86/KVM/VMX: Add module argument for L1TF mitigation + - x86/KVM/VMX: Add L1D flush algorithm + - x86/KVM/VMX: Add L1D MSR based flush + - x86/KVM/VMX: Add L1D flush logic + - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers + - x86/KVM/VMX: Add find_msr() helper function + - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting + - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs + - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required + - cpu/hotplug: Online siblings when SMT control is turned on + - x86/litf: Introduce vmx status variable + - x86/kvm: Drop L1TF MSR list approach + - x86/l1tf: Handle EPT disabled state proper + - x86/kvm: Move l1tf setup function + - x86/kvm: Add static key for flush always + - x86/kvm: Serialize L1D flush parameter setter + - x86/kvm: Allow runtime control of L1D flush + - cpu/hotplug: Expose SMT control init function + - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early + - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations + - Documentation: Add section about CPU vulnerabilities + - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures + - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content + - Documentation/l1tf: Fix typos + - cpu/hotplug: detect SMT disabled by BIOS + - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush() + - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond' + - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush() + - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16 + - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d + - x86: Don't include linux/irq.h from asm/hardirq.h + - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d + - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr() + - Documentation/l1tf: Remove Yonah processors from not vulnerable list + - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability + - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry + - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry + - cpu/hotplug: Fix SMT supported evaluation + - x86/speculation/l1tf: Invert all not present mappings + - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert + - x86/mm/pat: Make set_memory_np() L1TF safe + - x86/mm/kmmio: Make the tracer robust against L1TF + - tools headers: Synchronise x86 cpufeatures.h for L1TF additions + - x86/microcode: Allow late microcode loading with SMT disabled + - x86/smp: fix non-SMP broken build due to redefinition of + apic_id_is_primary_thread + - cpu/hotplug: Non-SMP machines do not make use of booted_once + - x86/init: fix build with CONFIG_SWAP=n + - Linux 4.18.1 + - [Config] updateconfigs after v4.18.1 stable update + + * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816) + - [Config] Enable timestamping in network PHY devices + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_SYSCTL_SYSCALL=n + + [ Upstream Kernel Changes ] + + * Rebase to v4.18 + + -- Seth Forshee Wed, 15 Aug 2018 14:20:59 -0500 + +linux (4.18.0-4.5) cosmic; urgency=medium + + [ Upstream Kernel Changes ] + + * Rebase to v4.18-rc8 + + -- Seth Forshee Mon, 06 Aug 2018 13:54:02 -0500 + +linux (4.18.0-3.4) cosmic; urgency=medium + + * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and + Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950) + - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation + + * hinic interfaces aren't getting predictable names (LP: #1783138) + - hinic: Link the logical network device to the pci device in sysfs + + * libvirtd is unable to configure bridge devices inside of LXD containers + (LP: #1784501) + - kernfs: allow creating kernfs objects with arbitrary uid/gid + - sysfs, kobject: allow creating kobject belonging to arbitrary users + - kobject: kset_create_and_add() - fetch ownership info from parent + - driver core: set up ownership of class devices in sysfs + - net-sysfs: require net admin in the init ns for setting tx_maxrate + - net-sysfs: make sure objects belong to container's owner + - net: create reusable function for getting ownership info of sysfs inodes + - bridge: make sure objects belong to container's owner + - sysfs: Fix regression when adding a file to an existing group + + * locking sockets broken due to missing AppArmor socket mediation patches + (LP: #1780227) + - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets + + * Update2 for ocxl driver (LP: #1781436) + - ocxl: Fix page fault handler in case of fault on dying process + + * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689) + - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA + - vga_switcheroo: set audio client id according to bound GPU id + + * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540) + - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge + + * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166) + - snapcraft.yaml: stop invoking the obsolete (and non-existing) + 'firmware_install' target + + * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build + (LP: #1782116) + - snapcraft.yaml: copy retpoline-extract-one to scripts before build + + [ Upstream Kernel Changes ] + + * Rebase to v4.18-rc7 + + -- Seth Forshee Wed, 01 Aug 2018 08:49:40 -0500 + +linux (4.18.0-2.3) cosmic; urgency=medium + + * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364) + - SAUCE: (noup) zfs to 0.7.9-3ubuntu4 + + * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99: + comm stress-ng: Corrupt inode bitmap (LP: #1780137) + - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode + bitmap + + * Cloud-init causes potentially huge boot delays with 4.15 kernels + (LP: #1780062) + - random: Make getrandom() ready earlier + + * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736) + - scsi: hisi_sas: Update a couple of register settings for v3 hw + + * hisi_sas: Add missing PHY spinlock init (LP: #1777734) + - scsi: hisi_sas: Add missing PHY spinlock init + + * hisi_sas: improve read performance by pre-allocating slot DMA buffers + (LP: #1777727) + - scsi: hisi_sas: Use dmam_alloc_coherent() + - scsi: hisi_sas: Pre-allocate slot DMA buffers + + * hisi_sas: Failures during host reset (LP: #1777696) + - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw() + - scsi: hisi_sas: Fix the conflict between dev gone and host reset + - scsi: hisi_sas: Adjust task reject period during host reset + - scsi: hisi_sas: Add a flag to filter PHY events during reset + - scsi: hisi_sas: Release all remaining resources in clear nexus ha + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3 + - SAUCE: mm: Fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL + - Enable zfs build + - SAUCE: Import aufs driver + - Revert "UBUNTU: [Config]: set CONFIG_EDAC_DEBUG=y for ARM64" + - [Config] retpoline -- review and accept retpoline changes + + [ Upstream Kernel Changes ] + + * Rebase to v4.18-rc5 + * Rebase to v4.18-rc6 + + -- Seth Forshee Tue, 24 Jul 2018 08:41:22 -0500 + +linux (4.18.0-1.2) cosmic; urgency=medium + + [ Upstream Kernel Changes ] + + * Rebase to v4.18-rc4 + + -- Seth Forshee Mon, 09 Jul 2018 07:36:31 -0500 + +linux (4.18.0-0.1) cosmic; urgency=medium + + * Miscellaneous Ubuntu changes + - ubuntu -- disable vbox build + - Disable zfs build + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown + - SAUCE: (efi-lockdown) ima: require secure_boot rules in lockdown mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is + locked down + - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked + down + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Lock down module params that specify hardware + parameters (eg. ioport) + - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module + - SAUCE: (efi-lockdown) Lock down /proc/kcore + - SAUCE: (efi-lockdown) Lock down kprobes + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) Lock down perf + - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked + down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists + that aren't present. + - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework + efi_status_to_err(). + - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print + error messages. + - SAUCE: (efi-lockdown) lockdown: fix coordination of kernel module signature + verification + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub + - SAUCE: (namespace) block_dev: Support checking inode permissions in + lookup_bdev() + - SAUCE: (namespace) block_dev: Check permissions towards block device inode + when mounting + - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode + when mounting + - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user + namespaces + - SAUCE: (namespace) ext4: Add module parameter to enable user namespace + mounts + - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is + opened for writing + - SAUCE: Import aufs driver + - Update dropped.txt + - [Config] updateconfigs after 4.18-rc3 rebase + - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Remove snd_soc_codec use for 4.18 + + [ Upstream Kernel Changes ] + + * Rebase to v4.18-rc3 + + -- Seth Forshee Fri, 06 Jul 2018 10:46:37 -0500 + +linux (4.18.0-0.0) cosmic; urgency=medium + + * Dummy entry. + + -- Seth Forshee Tue, 03 Jul 2018 11:10:33 -0500 + +linux (4.17.0-4.5) cosmic; urgency=medium + + * linux: 4.17.0-4.5 -proposed tracker (LP: #1779399) + + * Update to ocxl driver for 18.04.1 (LP: #1775786) + - powerpc: Add TIDR CPU feature for POWER9 + - powerpc: Use TIDR CPU feature to control TIDR allocation + - powerpc: use task_pid_nr() for TID allocation + - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action + - ocxl: Expose the thread_id needed for wait on POWER9 + - ocxl: Add an IOCTL so userspace knows what OCXL features are available + - ocxl: Document new OCXL IOCTLs + - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait() + + * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823) + - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules + + * glibc pkeys test fail on powerpc (LP: #1776967) + - [Config] Temporarily disable CONFIG_PPC_MEM_KEYS + + * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520) + - Revert "drm/i915/edp: Allow alternate fixed mode for eDP if available." + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.9-3ubuntu1, zfs to 0.7.9-3ubuntu1 + + -- Seth Forshee Fri, 29 Jun 2018 13:37:52 -0500 + +linux (4.17.0-3.4) cosmic; urgency=medium + + * linux: 4.17.0-3.4 -proposed tracker (LP: #1779124) + + * Cosmic update to v4.17.3 stable release (LP: #1778997) + - net: aquantia: fix unsigned numvecs comparison with less than zero + - bonding: re-evaluate force_primary when the primary slave name changes + - cdc_ncm: avoid padding beyond end of skb + - ipv6: allow PMTU exceptions to local routes + - net: dsa: add error handling for pskb_trim_rcsum + - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620 + - net/sched: act_simple: fix parsing of TCA_DEF_DATA + - tcp: verify the checksum of the first data segment in a new connection + - tls: fix use-after-free in tls_push_record + - tls: fix waitall behavior in tls_sw_recvmsg + - socket: close race condition between sock_close() and sockfs_setattr() + - udp: fix rx queue len reported by diag and proc interface + - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds + vlan + - hv_netvsc: Fix a network regression after ifdown/ifup + - ACPICA: AML parser: attempt to continue loading table after error + - ext4: fix hole length detection in ext4_ind_map_blocks() + - ext4: update mtime in ext4_punch_hole even if no blocks are released + - ext4: do not allow external inodes for inline data + - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget() + - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs + - ext4: fix fencepost error in check for inode count overflow during resize + - driver core: Don't ignore class_dir_create_and_add() failure. + - Btrfs: allow empty subvol= again + - Btrfs: fix clone vs chattr NODATASUM race + - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2() + - btrfs: return error value if create_io_em failed in cow_file_range + - btrfs: scrub: Don't use inode pages for device replace + - ALSA: usb-audio: Disable the quirk for Nura headset + - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation + - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() + - ALSA: hda: add dock and led support for HP EliteBook 830 G5 + - ALSA: hda: add dock and led support for HP ProBook 640 G4 + - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read() + - smb3: fix various xid leaks + - smb3: on reconnect set PreviousSessionId field + - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session + expiry + - cifs: For SMB2 security informaion query, check for minimum sized security + descriptor instead of sizeof FileAllInformation class + - nbd: fix nbd device deletion + - nbd: update size when connected + - nbd: use bd_set_size when updating disk size + - blk-mq: reinit q->tag_set_list entry only after grace period + - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue + - cpufreq: Fix new policy initialization during limits updates via sysfs + - cpufreq: ti-cpufreq: Fix an incorrect error return value + - cpufreq: governors: Fix long idle detection logic in load calculation + - libata: zpodd: small read overflow in eject_tray() + - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk + - nvme/pci: Sync controller reset for AER slot_reset + - w1: mxc_w1: Enable clock before calling clk_get_rate() on it + - x86/vector: Fix the args of vector_alloc tracepoint + - x86/apic/vector: Prevent hlist corruption and leaks + - x86/apic: Provide apic_ack_irq() + - x86/ioapic: Use apic_ack_irq() + - x86/platform/uv: Use apic_ack_irq() + - irq_remapping: Use apic_ack_irq() + - genirq/generic_pending: Do not lose pending affinity update + - genirq/affinity: Defer affinity setting if irq chip is busy + - genirq/migration: Avoid out of line call if pending is not set + - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping + - media: uvcvideo: Prevent setting unavailable flags + - media: rc: ensure input/lirc device can be opened after register + - iwlwifi: fw: harden page loading code + - orangefs: set i_size on new symlink + - orangefs: report attributes_mask and attributes for statx + - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation + - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large + - vhost: fix info leak due to uninitialized memory + - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset + - Linux 4.17.3 + + * Use-after-free in sk_peer_label (LP: #1778646) + - SAUCE: apparmor: fix use after free in sk_peer_label + + * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390) + - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak. + + * Various fixes for CXL kernel module (LP: #1774471) + - cxl: Configure PSL to not use APC virtual machines + - cxl: Disable prefault_mode in Radix mode + + * Bluetooth not working (LP: #1764645) + - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models + + * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique + (LP: #1776750) + - scsi: hisi_sas: make SAS address of SATA disks unique + + * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491) + - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y + - SAUCE: wcn36xx: read MAC from file or randomly generate one + + * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636) + - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist + + * register on binfmt_misc may overflow and crash the system (LP: #1775856) + - fs/binfmt_misc.c: do not allow offset overflow + + * Network installs fail on SocioNext board (LP: #1775884) + - net: socionext: reset hardware in ndo_stop + - net: netsec: enable tx-irq during open callback + + * Fix several bugs in RDMA/hns driver (LP: #1770974) + - RDMA/hns: Drop local zgid in favor of core defined variable + - RDMA/hns: Add 64KB page size support for hip08 + - RDMA/hns: Rename the idx field of db + - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust + - RDMA/hns: Increase checking CMQ status timeout value + - RDMA/hns: Add reset process for RoCE in hip08 + - RDMA/hns: Fix the illegal memory operation when cross page + - RDMA/hns: Implement the disassociate_ucontext API + + * powerpc/livepatch: Implement reliable stack tracing for the consistency + model (LP: #1771844) + - powerpc/livepatch: Implement reliable stack tracing for the consistency + model + + * Adding back alx WoL feature (LP: #1772610) + - SAUCE: Revert "alx: remove WoL support" + - SAUCE: alx: add enable_wol paramenter + + * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103) + - scsi: lpfc: Fix WQ/CQ creation for older asic's. + - scsi: lpfc: Fix 16gb hbas failing cq create. + + * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5 + idle states when all CORES are guarded (LP: #1771780) + - powerpc/powernv/cpuidle: Init all present cpus for deep states + + * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970) + - net-next/hinic: add pci device ids for 25ge and 100ge card + + * Expose arm64 CPU topology to userspace (LP: #1770231) + - drivers: base: cacheinfo: move cache_setup_of_node() + - drivers: base: cacheinfo: setup DT cache properties early + - cacheinfo: rename of_node to fw_token + - arm64/acpi: Create arch specific cpu to acpi id helper + - ACPI/PPTT: Add Processor Properties Topology Table parsing + - [Config] CONFIG_ACPI_PPTT=y + - ACPI: Enable PPTT support on ARM64 + - drivers: base cacheinfo: Add support for ACPI based firmware tables + - arm64: Add support for ACPI based firmware tables + - arm64: topology: rename cluster_id + - arm64: topology: enable ACPI/PPTT based CPU topology + - ACPI: Add PPTT to injectable table list + - arm64: topology: divorce MC scheduling domain from core_siblings + + * Vcs-Git header on bionic linux source package points to zesty git tree + (LP: #1766055) + - [Packaging]: Update Vcs-Git + + * Request to revert SAUCE patches in the 18.04 SRU and update with upstream + version (LP: #1768431) + - scsi: cxlflash: Handle spurious interrupts + - scsi: cxlflash: Remove commmands from pending list on timeout + - scsi: cxlflash: Synchronize reset and remove ops + - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3 + + * hisi_sas robustness fixes (LP: #1774466) + - scsi: hisi_sas: delete timer when removing hisi_sas driver + - scsi: hisi_sas: print device id for errors + - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice + - scsi: hisi_sas: check host frozen before calling "done" function + - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task() + - scsi: hisi_sas: stop controller timer for reset + - scsi: hisi_sas: update PHY linkrate after a controller reset + - scsi: hisi_sas: change slot index allocation mode + - scsi: hisi_sas: Change common allocation mode of device id + - scsi: hisi_sas: Reset disks when discovered + - scsi: hisi_sas: Create a scsi_host_template per HW module + - scsi: hisi_sas: Init disks after controller reset + - scsi: hisi_sas: Try wait commands before before controller reset + - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot + - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command + - scsi: hisi_sas: Terminate STP reject quickly for v2 hw + - scsi: hisi_sas: Fix return value when get_free_slot() failed + - scsi: hisi_sas: Mark PHY as in reset for nexus reset + + * hisi_sas: Support newer v3 hardware (LP: #1774467) + - scsi: hisi_sas: update RAS feature for later revision of v3 HW + - scsi: hisi_sas: check IPTT is valid before using it for v3 hw + - scsi: hisi_sas: fix PI memory size + - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw + - scsi: hisi_sas: remove redundant handling to event95 for v3 + - scsi: hisi_sas: add readl poll timeout helper wrappers + - scsi: hisi_sas: workaround a v3 hw hilink bug + - scsi: hisi_sas: Add LED feature for v3 hw + + * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472) + - scsi: hisi_sas: optimise the usage of DQ locking + - scsi: hisi_sas: relocate smp sg map + - scsi: hisi_sas: make return type of prep functions void + - scsi: hisi_sas: allocate slot buffer earlier + - scsi: hisi_sas: Don't lock DQ for complete task sending + - scsi: hisi_sas: Use device lock to protect slot alloc/free + - scsi: hisi_sas: add check of device in hisi_sas_task_exec() + - scsi: hisi_sas: fix a typo in hisi_sas_task_prep() + + * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336) + - SAUCE: CacheFiles: fix a read_waiter/read_copier race + + * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306) + - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs + + * hns3 driver updates (LP: #1768670) + - net: hns3: Remove error log when getting pfc stats fails + - net: hns3: fix to correctly fetch l4 protocol outer header + - net: hns3: Fixes the out of bounds access in hclge_map_tqp + - net: hns3: Fixes the error legs in hclge_init_ae_dev function + - net: hns3: fix for phy_addr error in hclge_mac_mdio_config + - net: hns3: Fix to support autoneg only for port attached with phy + - net: hns3: fix a dead loop in hclge_cmd_csq_clean + - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls + - net: hns3: Remove packet statistics in the range of 8192~12287 + - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver + - net: hns3: Fix for setting mac address when resetting + - net: hns3: remove add/del_tunnel_udp in hns3_enet module + - net: hns3: fix for cleaning ring problem + - net: hns3: refactor the loopback related function + - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo + - net: hns3: Fix for the null pointer problem occurring when initializing + ae_dev failed + - net: hns3: Add a check for client instance init state + - net: hns3: Change return type of hnae3_register_ae_dev + - net: hns3: Change return type of hnae3_register_ae_algo + - net: hns3: Change return value in hnae3_register_client + - net: hns3: Fixes the back pressure setting when sriov is enabled + - net: hns3: Fix for fiber link up problem + - net: hns3: Add support of .sriov_configure in HNS3 driver + - net: hns3: Fixes the missing PCI iounmap for various legs + - net: hns3: Fixes error reported by Kbuild and internal review + - net: hns3: Fixes API to fetch ethernet header length with kernel default + - net: hns3: cleanup of return values in hclge_init_client_instance() + - net: hns3: Fix the missing client list node initialization + - net: hns3: Fix for hns3 module is loaded multiple times problem + - net: hns3: Use enums instead of magic number in hclge_is_special_opcode + - net: hns3: Fix for netdev not running problem after calling net_stop and + net_open + - net: hns3: Fixes kernel panic issue during rmmod hns3 driver + - net: hns3: Fix for CMDQ and Misc. interrupt init order problem + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config + - net: hns3: Add STRP_TAGP field support for hardware revision 0x21 + - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21) + - net: hns3: Fix for PF mailbox receving unknown message + - net: hns3: Fixes the state to indicate client-type initialization + - net: hns3: Fixes the init of the VALID BD info in the descriptor + - net: hns3: Removes unnecessary check when clearing TX/RX rings + - net: hns3: Clear TX/RX rings when stopping port & un-initializing client + - net: hns3: Remove unused led control code + - net: hns3: Adds support for led locate command for copper port + - net: hns3: Fixes initalization of RoCE handle and makes it conditional + - net: hns3: Disable vf vlan filter when vf vlan table is full + - net: hns3: Add support for IFF_ALLMULTI flag + - net: hns3: Add repeat address checking for setting mac address + - net: hns3: Fix setting mac address error + - net: hns3: Fix for service_task not running problem after resetting + - net: hns3: Fix for hclge_reset running repeatly problem + - net: hns3: Fix for phy not link up problem after resetting + - net: hns3: Add missing break in misc_irq_handle + - net: hns3: Fix for vxlan tx checksum bug + - net: hns3: Optimize the PF's process of updating multicast MAC + - net: hns3: Optimize the VF's process of updating multicast MAC + - SAUCE: {topost} net: hns3: add support for serdes loopback selftest + - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except + VLD bit and buffer size + - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from + hclge_bind_ring_with_vector + - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - SAUCE: {topost} net: hns3: add vector status check before free vector + - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6 + - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c + - SAUCE: {topost} net: hns3: extraction an interface for state state + init|uninit + - SAUCE: {topost} net: hns3: print the ret value in error information + - SAUCE: {topost} net: hns3: remove the Redundant put_vector in + hns3_client_uninit + - SAUCE: {topost} net: hns3: add unlikely for error check + - SAUCE: {topost} net: hns3: remove back in struct hclge_hw + - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits + - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir + - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean + - SAUCE: {topost} net: hns3: using modulo for cyclic counters in + hclge_cmd_send + - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done + - SAUCE: {topost} net: hns3: remove some unused members of some structures + - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set + - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of + kzalloc/dma_map_single + - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_ + - SAUCE: {topost} net: hns3: fix unused function warning in VF driver + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: standardize the handle of return value + - SAUCE: {topost} net: hns3: remove extra space and brackets + - SAUCE: {topost} net: hns3: fix unreasonable code comments + - SAUCE: {topost} net: hns3: use decimal for bit offset macros + - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros + - SAUCE: {topost} net: hns3: fix mislead parameter name + - SAUCE: {topost} net: hns3: remove unused struct member and definition + - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver + - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE + - SAUCE: {topost} net: hns3: optimize the process of notifying roce client + - SAUCE: {topost} net: hns3: Add calling roce callback function when link + status change + - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up + - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode + - SAUCE: {topost} net: hns3: fix for waterline not setting correctly + - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug + - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem + - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size + - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest + - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module + - SAUCE: {topost} net: hns3: remove the warning when clear reset cause + - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback + function + - SAUCE: {topost} net: hns3: prevent sending command during global or core + reset + - SAUCE: {topost} net: hns3: modify the order of initializeing command queue + register + - SAUCE: {topost} net: hns3: reset net device with rtnl_lock + - SAUCE: {topost} net: hns3: prevent to request reset frequently + - SAUCE: {topost} net: hns3: correct reset event status register + - SAUCE: {topost} net: hns3: separate roce from nic when resetting + - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver + - SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet + - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation + while resetting + - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm + - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx + - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response + - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message + - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process + + * CVE-2018-7755 + - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl + + * Incorrect blacklist of bcm2835_wdt (LP: #1766052) + - [Packaging] Fix missing watchdog for Raspberry Pi + + * kernel: Fix arch random implementation (LP: #1775391) + - s390/archrandom: Rework arch random implementation. + + * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux- + jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389) + - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device + + * Cosmic update to v4.17.2 stable release (LP: #1779117) + - crypto: chelsio - request to HW should wrap + - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers + - KVM: X86: Fix reserved bits check for MOV to CR3 + - KVM: x86: introduce linear_{read,write}_system + - kvm: fix typo in flag name + - kvm: nVMX: Enforce cpl=0 for VMX instructions + - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and + kvm_write_guest_virt_system + - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access + - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy + - NFC: pn533: don't send USB data off of the stack + - usbip: vhci_sysfs: fix potential Spectre v1 + - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver + - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive + - Input: xpad - add GPD Win 2 Controller USB IDs + - phy: qcom-qusb2: Fix crash if nvmem cell not specified + - usb: core: message: remove extra endianness conversion in + usb_set_isoch_delay + - usb: typec: wcove: Remove dependency on HW FSM + - usb: gadget: function: printer: avoid wrong list handling in printer_write() + - usb: gadget: udc: renesas_usb3: fix double phy_put() + - usb: gadget: udc: renesas_usb3: should remove debugfs + - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add + udc + - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc + - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error + - usb: gadget: udc: renesas_usb3: disable the controller's irqs for + reconnecting + - serial: sh-sci: Stop using printk format %pCr + - tty/serial: atmel: use port->name as name in request_irq() + - serial: samsung: fix maxburst parameter for DMA transactions + - serial: 8250: omap: Fix idling of clocks for unused uarts + - vmw_balloon: fixing double free when batching mode is off + - doc: fix sysfs ABI documentation + - arm64: defconfig: Enable CONFIG_PINCTRL_MT7622 by default + - tty: pl011: Avoid spuriously stuck-off interrupts + - crypto: ccree - correct host regs offset + - Input: goodix - add new ACPI id for GPD Win 2 touch screen + - Input: elan_i2c - add ELAN0612 (Lenovo v330 14IKB) ACPI ID + - crypto: caam - strip input zeros from RSA input buffer + - crypto: caam - fix DMA mapping dir for generated IV + - crypto: caam - fix IV DMA mapping and updating + - crypto: caam/qi - fix IV DMA mapping and updating + - crypto: caam - fix size of RSA prime factor q + - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK + - crypto: cavium - Limit result reading attempts + - crypto: vmx - Remove overly verbose printk from AES init routines + - crypto: vmx - Remove overly verbose printk from AES XTS init + - crypto: omap-sham - fix memleak + - Linux 4.17.2 + + * Cosmic update to v4.17.1 stable release (LP: #1779116) + - netfilter: nf_flow_table: attach dst to skbs + - bnx2x: use the right constant + - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds + - ipv6: omit traffic class when calculating flow hash + - l2tp: fix refcount leakage on PPPoL2TP sockets + - netdev-FAQ: clarify DaveM's position for stable backports + - net: metrics: add proper netlink validation + - net/packet: refine check for priv area size + - rtnetlink: validate attributes in do_setlink() + - sctp: not allow transport timeout value less than HZ/5 for hb_timer + - team: use netdev_features_t instead of u32 + - vrf: check the original netdevice for generating redirect + - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC + - ipmr: fix error path when ipmr_new_table fails + - PCI: hv: Do not wait forever on a device that has disappeared + - Linux 4.17.1 + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from + CONFIG_VMAP_STACK" + - Revert "UBUNTU: SAUCE: cred: Add clone_cred() interface" + - SAUCE: apparmor: userspace queries + - SAUCE: apparmor: patch to provide compatibility with v2.x net rules + - SAUCE: apparmor: af_unix mediation + + -- Seth Forshee Thu, 28 Jun 2018 08:03:32 -0500 + +linux (4.17.0-2.3) cosmic; urgency=medium + + * linux: 4.17.0-2.3 -proposed tracker (LP: #1776276) + + * Miscellaneous Ubuntu changes + - Config: remove IrDA from annotations + - Config: remove scsi drivers from annotations + - Config: remove BT_HCIBTUART from annotations + - Config: pstore zlib support was renamed + - Config: disable NVRAM for armhf on annotations + - Config: Disable VT on s390x + - Config: Update SSB and B43/B44 options + - Config: some options not supported on some arches anymore + - Config: renamed and removed options + - Config: TCG_CRB is required for IMA on ACPI systems + - Config: EXTCON_AXP288 depends on X86 + - Config: CONFIG_FSI depends on OF + - Config: DRM_RCAR_LVDS now depends on DRM + - CONFIG: Allow CONFIG_LEDS_MLXCPLD for i386 + - Config: Enable HINIC on arm64 + - Config: Set PPS and PTP_1588_CLOCK as y + - Config: Some NF_TABLES options are built-in now + - Config: GENERIC_CPU for ppc64el + - Config: KEXEC_FILE=n for s390x + - Config: CRYPTO_DEFLATE is needed by PSTORE_DEFLATE_COMPRESS + - Config: Disable STM32 support + - Config: Enable FORTIFY_SOURCE for armhf + - Config: use STRONG instead of AUTO for CC_STACKPROTECTOR + + [ Upstream Kernel Changes ] + + * Rebase to v4.17 + + -- Thadeu Lima de Souza Cascardo Mon, 11 Jun 2018 15:22:10 -0300 + +linux (4.17.0-1.2) cosmic; urgency=medium + + [ Seth Forshee ] + * [Config] enable EDAC_DEBUG on ARM64 (LP: #1772516) + - [Config]: set CONFIG_EDAC_DEBUG=y for ARM64 + + * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849) + - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on + num_possible_cpus() + + * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in + DELL XPS 13 9370 with firmware 1.50 (LP: #1763748) + - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device + + * Switch Build-Depends: transfig to fig2dev (LP: #1770770) + - [Config] update Build-Depends: transfig to fig2dev + + * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails + to load (LP: #1728238) + - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for + unreleased firmware" + + * No driver for Huawei network adapters on arm64 (LP: #1769899) + - net-next/hinic: add arm64 support + + * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761) + - [Config] snapdragon: DRM_I2C_ADV7511=y + + * Add d-i support for Huawei NICs (LP: #1767490) + - d-i: add hinic to nic-modules udeb + + * Acer Swift sf314-52 power button not managed (LP: #1766054) + - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode + + * Include nfp driver in linux-modules (LP: #1768526) + - [Config] Add nfp.ko to generic inclusion list + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - [Config] Enable AUFS config options + - SAUCE: (efi-lockdown) Fix for module sig verification + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure + boot mode + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub + - [Config] CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y + - SAUCE: (efi-lockdown) really lock down kernel under EFI secure boot + - SAUCE: (noup) Update spl to 0.7.5-1ubuntu3, zfs to 0.7.5-1ubuntu17 + - enable zfs build + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: (efi-lockdown) ima: require secure_boot rules in + lockdown mode" + - Rebased to v4.17-rc6 + + -- Thadeu Lima de Souza Cascardo Tue, 22 May 2018 14:48:13 -0300 + +linux (4.17.0-0.1) bionic; urgency=medium + + [ Upstream Kernel Changes ] + + * Rebase to v4.17-rc4 + + -- Thadeu Lima de Souza Cascardo Tue, 08 May 2018 16:38:51 -0300 + +linux (4.17.0-0.0) bionic; urgency=medium + + * Dummy entry. + + -- Thadeu Lima de Souza Cascardo Fri, 27 Apr 2018 11:01:13 -0300 + +linux (4.16.0-4.5) bionic; urgency=medium + + * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130) + - tools/kvm_stat: Fix python3 syntax + - tools/kvm_stat: Don't use deprecated file() + - tools/kvm_stat: Remove unused function + - [Packaging] Add linux-tools-host package for VM host tools + - [Config] do_tools_host=true for amd64 + + * [Featire] CNL: Enable RAPL support (LP: #1685712) + - powercap: RAPL: Add support for Cannon Lake + + * Bionic update to v4.16.2 stable release (LP: #1763388) + - sparc64: Oracle DAX driver depends on SPARC64 + - arp: fix arp_filter on l3slave devices + - net: dsa: Discard frames from unused ports + - net/ipv6: Increment OUTxxx counters after netfilter hook + - net/sched: fix NULL dereference in the error path of tcf_bpf_init() + - pptp: remove a buggy dst release in pptp_connect() + - sctp: do not leak kernel memory to user space + - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6 + - vlan: also check phy_driver ts_info for vlan's real device + - net: fool proof dev_valid_name() + - ip_tunnel: better validate user provided tunnel names + - ipv6: sit: better validate user provided tunnel names + - ip6_gre: better validate user provided tunnel names + - ip6_tunnel: better validate user provided tunnel names + - vti6: better validate user provided tunnel names + - net_sched: fix a missing idr_remove() in u32_delete_key() + - nfp: use full 40 bits of the NSP buffer address + - Linux 4.16.2 + + * sky2 gigabit ethernet driver sometimes stops working after lid-open resume + from sleep (88E8055) (LP: #1758507) // Bionic update to v4.16.2 stable + release (LP: #1763388) + - sky2: Increase D3 delay to sky2 stops working after suspend + + * Merge the linux-snapdragon kernel into bionic master/snapdragon + (LP: #1763040) + - arm64: defconfig: enable REMOTEPROC + - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c + - kernel: configs; add distro.config + - arm64: configs: enable WCN36xx + - kernel: distro.config: enable debug friendly USB network adpater + - arm64: configs: enable QCOM Venus + - arm64: defconfig: Enable a53/apcs and avs + - arm64: defconfig: enable ondemand governor as default + - arm64: defconfig: enable QCOM_TSENS + - kernel: configs: enable dm_mod and dm_crypt + - Force the SMD regulator driver to be compiled-in + - arm64: defconfig: enable CFG80211_DEFAULT_PS by default + - arm64: configs: enable BT_QCOMSMD + - kernel: configs: add more USB net drivers + - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV + - arm64: configs: Enable camera drivers + - kernel: configs: add freq stat to sysfs + - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default + - arm64: defconfig: Enable QRTR features + - kernel: configs: set USB_CONFIG_F_FS in distro.config + - kernel: distro.config: enable 'schedutil' CPUfreq governor + - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs + - kernel: distro.config: enable 'BBR' TCP congestion algorithm + - arm64: defconfig: enable LEDS_QCOM_LPG + - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap + - power: avs: Add support for CPR (Core Power Reduction) + - power: avs: cpr: Use raw mem access for qfprom + - power: avs: cpr: fix with new reg_sequence structures + - power: avs: cpr: Register with cpufreq-dt + - regulator: smd: Add floor and corner operations + - PM / OPP: Support adjusting OPP voltages at runtime + - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage() + - PM / OPP: HACK: Allow to set regulator without opp_list + - PM / OPP: Add a helper to get an opp regulator for device + - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist + - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m + - ov5645: I2C address change + - i2c: Add Qualcomm Camera Control Interface driver + - camss: vfe: Skip first four frames from sensor + - camss: Do not register if no cameras are present + - i2c-qcom-cci: Fix run queue completion timeout + - i2c-qcom-cci: Fix I2C address bug + - media: ov5645: Fix I2C address + - drm/bridge/adv7511: Delay clearing of HPD interrupt status + - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing + - leds: Add driver for Qualcomm LPG + - wcn36xx: Fix warning due to duplicate scan_completed notification + - arm64: dts: Add CPR DT node for msm8916 + - arm64: dts: add spmi-regulator nodes + - arm64: dts: msm8916: Add cpufreq support + - arm64: dts: msm8916: Add a shared CPU opp table + - arm64: dts: msm8916: Add cpu cooling maps + - arm64: dts: pm8916: Mark the s2 regulator as always-on + - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node + - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver + - arm64: dts: qcom: msm8916: Add clock properties to the APCS node + - dt-bindings: media: Binding document for Qualcomm Camera Control Interface + driver + - MAINTAINERS: Add Qualcomm Camera Control Interface driver + - DT: leds: Add Qualcomm Light Pulse Generator binding + - arm64: dts: qcom: msm8996: Add mpp and lpg blocks + - arm64: dts: qcom: Add pwm node for pm8916 + - arm64: dts: qcom: Add user LEDs on db820c + - arm64: dts: qcom: Add WiFI/BT LEDs on db820c + - ARM: dts: qcom: Add LPG node to pm8941 + - ARM: dts: qcom: honami: Add LPG node and RGB LED + - arm64: dts: qcom: Add Camera Control Interface support + - arm64: dts: qcom: Add apps_iommu vfe child node + - arm64: dts: qcom: Add camss device node + - arm64: dts: qcom: Add ov5645 device nodes + - arm64: dts: msm8916: Fix camera sensors I2C addresses + - arm: dts: qcom: db410c: Enable PWM signal on MPP4 + - packaging: arm64: add a uboot flavour - part1 + - packaging: arm64: add a uboot flavour - part2 + - packaging: arm64: add a uboot flavour - part3 + - packaging: arm64: add a uboot flavour - part4 + - packaging: arm64: add a uboot flavour - part5 + - packaging: arm64: rename uboot flavour to snapdragon + - [Config] updateconfigs after qcomlt import + - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: MSM_GCC_8916=y + - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y + - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y + - [Config] arm64: snapdragon: QCOM_SMEM=y + - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: QCOM_CPR=y + - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y + - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y + - [Config] turn off DRM_MSM_REGISTER_LOGGING + - [Config] arm64: snapdragon: I2C_QUP=y + - [Config] arm64: snapdragon: SPI_QUP=y + - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y + - [Config] arm64: snapdragon: QCOM_SMSM=y + - [Config] arm64: snapdragon: QCOM_SMP2P=y + - [Config] arm64: snapdragon: DRM_MSM=y + - [Config] arm64: snapdragon: SND_SOC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m + - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m + - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y + - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y, + SND_SOC_MSM8916_WCD_DIGITAL=y + - SAUCE: media: ov5645: skip address change if dt addr == default addr + - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS + #ifdefs + - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y + - [Packaging] fix up snapdragon abi paths + + * LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: Manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: Manage task security blobs + - SAUCE: LSM stacking: LSM: Manage remaining security blobs + - SAUCE: LSM stacking: LSM: General stacking + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: add apparmor and selinux proc dirs + - SAUCE: LSM stacking: remove procfs context interface + + * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14 + (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: check for invalid zero sized writes + + * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems + (LP: #1762755) + - RDMA/hns: Support rq record doorbell for the user space + - RDMA/hns: Support cq record doorbell for the user space + - RDMA/hns: Support rq record doorbell for kernel space + - RDMA/hns: Support cq record doorbell for kernel space + - RDMA/hns: Fix cqn type and init resp + - RDMA/hns: Fix init resp when alloc ucontext + - RDMA/hns: Fix cq record doorbell enable in kernel + + * Replace LPC patchset with upstream version (LP: #1762758) + - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver" + - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support" + - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host + children" + - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT + bindings" + - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO + devices" + - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO + hosts" + - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method" + - lib: Add generic PIO mapping method + - PCI: Remove __weak tag from pci_register_io_range() + - PCI: Add fwnode handler as input param of pci_register_io_range() + - PCI: Apply the new generic I/O management on PCI IO hosts + - of: Add missing I/O range exception for indirect-IO devices + - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use + - ACPI / scan: Do not enumerate Indirect IO host children + - HISI LPC: Add ACPI support + - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver + + * Enable Tunneled Operations on POWER9 (LP: #1762448) + - powerpc/powernv: Enable tunneled operations + - cxl: read PHB indications from the device tree + + * PSL traces reset after PERST for debug AFU image (LP: #1762462) + - cxl: Enable NORST bit in PSL_DEBUG register for PSL9 + + * NFS + sec=krb5 is broken (LP: #1759791) + - sunrpc: remove incorrect HMAC request initialization + + * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128) + - d-i: add bcm2835 to block-modules + + * Backport USB core quirks (LP: #1762695) + - usb: core: Add "quirks" parameter for usbcore + - usb: core: Copy parameter string correctly and remove superfluous null check + - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks + + * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on failed' when + setting up a second end-to-end encrypted disk (LP: #1762353) + - SAUCE: s390/crypto: Adjust s390 aes and paes cipher + + * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719) + - s390: move nobp parameter functions to nospec-branch.c + - s390: add automatic detection of the spectre defense + - s390: report spectre mitigation via syslog + - s390: add sysfs attributes for spectre + - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390 + - s390: correct nospec auto detection init order + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 + - powerpc/64s: Wire up cpu_show_spectre_v2() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753 + - powerpc/64s: Wire up cpu_show_spectre_v1() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754 + - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code + - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again + - powerpc/rfi-flush: Always enable fallback flush on pseries + - powerpc/rfi-flush: Differentiate enabled and patched flush types + - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration + - powerpc/64s: Move cpu_show_meltdown() + - powerpc/64s: Enhance the information in cpu_show_meltdown() + - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush() + - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 // + CVE-2017-5753 // CVE-2017-5754 + - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags + - powerpc: Add security feature flags for Spectre/Meltdown + - powerpc/pseries: Set or clear security feature flags + - powerpc/powernv: Set or clear security feature flags + + * Hisilicon network subsystem 3 support (LP: #1761610) + - net: hns3: export pci table of hclge and hclgevf to userspace + - d-i: Add hns3 drivers to nic-modules + + * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534) + - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS + + * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712) + - perf vendor events: Drop incomplete multiple mapfile support + - perf vendor events: Fix error code in json_events() + - perf vendor events: Drop support for unused topic directories + - perf vendor events: Add support for pmu events vendor subdirectory + - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory + - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory + - perf vendor events: Add support for arch standard events + - perf vendor events arm64: Add armv8-recommended.json + - perf vendor events arm64: Fixup ThunderX2 to use recommended events + - perf vendor events arm64: fixup A53 to use recommended events + - perf vendor events arm64: add HiSilicon hip08 JSON file + - perf vendor events arm64: Enable JSON events for ThunderX2 B0 + + * Warning "cache flush timed out!" seen when unloading the cxl driver + (LP: #1762367) + - cxl: Check if PSL data-cache is available before issue flush request + + * Bionic update to v4.16.1 stable release (LP: #1763170) + - bitmap: fix memset optimization on big-endian systems + - USB: serial: ftdi_sio: add RT Systems VX-8 cable + - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator + - USB: serial: cp210x: add ELDAT Easywave RX09 id + - serial: 8250: Add Nuvoton NPCM UART + - mei: remove dev_err message on an unsupported ioctl + - /dev/mem: Avoid overwriting "err" in read_mem() + - media: usbtv: prevent double free in error case + - parport_pc: Add support for WCH CH382L PCI-E single parallel port card. + - crypto: lrw - Free rctx->ext with kzfree + - crypto: ccp - Fill the result buffer only on digest, finup, and final ops + - crypto: talitos - don't persistently map req_ctx->hw_context and + req_ctx->buf + - crypto: inside-secure - fix clock management + - crypto: testmgr - Fix incorrect values in PKCS#1 test vector + - crypto: talitos - fix IPsec cipher in length + - crypto: ahash - Fix early termination in hash walk + - crypto: caam - Fix null dereference at error path + - crypto: ccp - return an actual key size from RSA max_size callback + - crypto: arm,arm64 - Fix random regeneration of S_shipped + - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one + - Bluetooth: hci_bcm: Add 6 new ACPI HIDs + - Btrfs: fix unexpected cow in run_delalloc_nocow + - siox: fix possible buffer overflow in device_add_store + - staging: comedi: ni_mio_common: ack ai fifo error interrupts. + - Revert "base: arch_topology: fix section mismatch build warnings" + - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370 + - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list + - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad + - vt: change SGR 21 to follow the standards + - Fix slab name "biovec-(1<<(21-12))" + - signal: Correct the offset of si_pkey and si_lower in struct siginfo on m68k + - Linux 4.16.1 + + * [18.04][config] regression: nvme and nvme_core couldn't be built as modules + starting 4.15-rc2 (LP: #1759893) + - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for + build" + - [Config] CONFIG_BLK_DEV_NMVE=m + + * FFe: Enable configuring resume offset via sysfs (LP: #1760106) + - PM / hibernate: Make passing hibernate offsets more friendly + + * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine + type(pseries-bionic) complaining "KVM implementation does not support + Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026) + - powerpc: Use feature bit for RTC presence rather than timebase presence + - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit + - powerpc: Free up CPU feature bits on 64-bit machines + - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2 + - powerpc/powernv: Provide a way to force a core into SMT4 mode + - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9 + - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode + - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state + + * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775) + - thunderbolt: Resume control channel after hibernation image is created + - thunderbolt: Serialize PCIe tunnel creation with PCI rescan + - thunderbolt: Handle connecting device in place of host properly + - thunderbolt: Do not overwrite error code when domain adding fails + - thunderbolt: Wait a bit longer for root switch config space + - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM + - thunderbolt: Handle rejected Thunderbolt devices + - thunderbolt: Factor common ICM add and update operations out + - thunderbolt: Correct function name in kernel-doc comment + - thunderbolt: Add tb_switch_get() + - thunderbolt: Add tb_switch_find_by_route() + - thunderbolt: Add tb_xdomain_find_by_route() + - thunderbolt: Add constant for approval timeout + - thunderbolt: Move driver ready handling to struct icm + - thunderbolt: Add 'boot' attribute for devices + - thunderbolt: Add support for preboot ACL + - thunderbolt: Introduce USB only (SL4) security level + - thunderbolt: Add support for Intel Titan Ridge + + * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345) + - ath10k: update the IRAM bank number for QCA9377 + + * Fix an issue that when system in S3, USB keyboard can't wake up the system. + (LP: #1759511) + - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW + + * cxl: Fix timebase synchronization status on POWER9 missing (CAPI) + (LP: #1757228) + - cxl: Fix timebase synchronization status on P9 + + * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug + fixes (LP: #1752182) + - scsi: lpfc: Fix frequency of Release WQE CQEs + - scsi: lpfc: Increase CQ and WQ sizes for SCSI + - scsi: lpfc: move placement of target destroy on driver detach + - scsi: lpfc: correct debug counters for abort + - scsi: lpfc: Add WQ Full Logic for NVME Target + - scsi: lpfc: Fix PRLI handling when topology type changes + - scsi: lpfc: Fix IO failure during hba reset testing with nvme io. + - scsi: lpfc: Fix RQ empty firmware trap + - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target + - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing + - scsi: lpfc: Fix issue_lip if link is disabled + - scsi: lpfc: Indicate CONF support in NVMe PRLI + - scsi: lpfc: Fix SCSI io host reset causing kernel crash + - scsi: lpfc: Validate adapter support for SRIU option + - scsi: lpfc: Fix header inclusion in lpfc_nvmet + - scsi: lpfc: Treat SCSI Write operation Underruns as an error + - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap. + - scsi: lpfc: update driver version to 11.4.0.7 + - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright + - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers + - scsi: lpfc: Rework sli4 doorbell infrastructure + - scsi: lpfc: Add SLI-4 if_type=6 support to the code base + - scsi: lpfc: Add push-to-adapter support to sli4 + - scsi: lpfc: Add PCI Ids for if_type=6 hardware + - scsi: lpfc: Add 64G link speed support + - scsi: lpfc: Add if_type=6 support for cycling valid bits + - scsi: lpfc: Enable fw download on if_type=6 devices + - scsi: lpfc: Add embedded data pointers for enhanced performance + - scsi: lpfc: Fix nvme embedded io length on new hardware + - scsi: lpfc: Work around NVME cmd iu SGL type + - scsi: lpfc: update driver version to 12.0.0.0 + - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018 + - scsi: lpfc: use __raw_writeX on DPP copies + - scsi: lpfc: Add missing unlock in WQ full logic + + * /dev/bcache/by-uuid links not created after reboot (LP: #1729145) + - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent + + * DKMS driver builds fail with: Cannot use CONFIG_STACK_VALIDATION=y, please + install libelf-dev, libelf-devel or elfutils-libelf-devel (LP: #1760876) + - [Packaging] include the retpoline extractor in the headers + + * Use med_with_dipm SATA LPM to save more power for mobile platforms + (LP: #1759547) + - [Config] CONFIG_SATA_MOBILE_LPM_POLICY=3 + + * Miscellaneous Ubuntu changes + - [Packaging] Only install cloud init files when do_tools_common=true + - SAUCE: Import aufs driver + - [Config] Enable AUFS config options + + -- Seth Forshee Thu, 12 Apr 2018 09:30:56 -0500 + +linux (4.16.0-3.4) bionic; urgency=medium + + * Allow multiple mounts of zfs datasets (LP: #1759848) + - SAUCE: Allow mounting datasets more than once (LP: #1759848) + + * zfs system process hung on container stop/delete (LP: #1754584) + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)" + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + + * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64 + (LP: #1755073) + - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK + + * CAPI Flash (cxlflash) update (LP: #1752672) + - SAUCE: cxlflash: Preserve number of interrupts for master contexts + - SAUCE: cxlflash: Avoid clobbering context control register value + - SAUCE: cxlflash: Add argument identifier names + - SAUCE: cxlflash: Introduce OCXL backend + - SAUCE: cxlflash: Hardware AFU for OCXL + - SAUCE: cxlflash: Read host function configuration + - SAUCE: cxlflash: Setup function acTag range + - SAUCE: cxlflash: Read host AFU configuration + - SAUCE: cxlflash: Setup AFU acTag range + - SAUCE: cxlflash: Setup AFU PASID + - SAUCE: cxlflash: Adapter context support for OCXL + - SAUCE: cxlflash: Use IDR to manage adapter contexts + - SAUCE: cxlflash: Support adapter file descriptors for OCXL + - SAUCE: cxlflash: Support adapter context discovery + - SAUCE: cxlflash: Support image reload policy modification + - SAUCE: cxlflash: MMIO map the AFU + - SAUCE: cxlflash: Support starting an adapter context + - SAUCE: cxlflash: Support process specific mappings + - SAUCE: cxlflash: Support AFU state toggling + - SAUCE: cxlflash: Support reading adapter VPD data + - SAUCE: cxlflash: Setup function OCXL link + - SAUCE: cxlflash: Setup OCXL transaction layer + - SAUCE: cxlflash: Support process element lifecycle + - SAUCE: cxlflash: Support AFU interrupt management + - SAUCE: cxlflash: Support AFU interrupt mapping and registration + - SAUCE: cxlflash: Support starting user contexts + - SAUCE: cxlflash: Support adapter context polling + - SAUCE: cxlflash: Support adapter context reading + - SAUCE: cxlflash: Support adapter context mmap and release + - SAUCE: cxlflash: Support file descriptor mapping + - SAUCE: cxlflash: Introduce object handle fop + - SAUCE: cxlflash: Setup LISNs for user contexts + - SAUCE: cxlflash: Setup LISNs for master contexts + - SAUCE: cxlflash: Update synchronous interrupt status bits + - SAUCE: cxlflash: Introduce OCXL context state machine + - SAUCE: cxlflash: Register for translation errors + - SAUCE: cxlflash: Support AFU reset + - SAUCE: cxlflash: Enable OCXL operations + + * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core + (LP: #1736393) + - SAUCE: drm/i915:Don't set chip specific data + - SAUCE: drm/i915: make previous commit affects Wyse 3040 only + + * zed process consuming 100% cpu (LP: #1751796) + - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796) + + * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to + "always" (LP: #1753708) + - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el + + * retpoline hints: primary infrastructure and initial hints (LP: #1758856) + - [Packaging] retpoline -- add safe usage hint support + - [Packaging] retpoline-check -- only report additions + - [Packaging] retpoline -- widen indirect call/jmp detection + - [Packaging] retpoline -- elide %rip relative indirections + - [Packaging] retpoline -- clear hint information from packages + - SAUCE: apm -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: EFI -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: early/late -- annotate indirect calls in early/late initialisation + code + - SAUCE: vga_set_mode -- avoid jump tables + - [Config] retpoine -- switch to new format + + * Miscellaneous Ubuntu changes + - [Packaging] final-checks -- remove check for empty retpoline files + - [Packaging] skip cloud tools packaging when not building package + + [ Upstream Kernel Changes ] + + * Rebase to v4.16 + + -- Seth Forshee Mon, 02 Apr 2018 16:15:36 -0500 + +linux (4.16.0-2.3) bionic; urgency=medium + + * devpts: handle bind-mounts (LP: #1755857) + - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC + - SAUCE: devpts: resolve devpts bind-mounts + - SAUCE: devpts: comment devpts_mntget() + - SAUCE: selftests: add devpts selftests + + * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103) + - d-i: add hisi_sas_v3_hw to scsi-modules + + * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094) + - SAUCE: scsi: hisi_sas: config for hip08 ES + - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace + + * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424) + - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove. + + * Fix ARC hit rate (LP: #1755158) + - SAUCE: Fix ARC hit rate (LP: #1755158) + + * ZFS setgid broken on 0.7 (LP: #1753288) + - SAUCE: Fix ZFS setgid + + * CONFIG_EFI=y on armhf (LP: #1726362) + - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings + + * [Feature] Add xHCI debug device support in the driver (LP: #1730832) + - [Config] CONFIG_USB_XHCI_DBGCAP=y + + * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655) + - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386 + - [Config] retpoline -- clean up i386 retpoline files + + * Miscellaneous Ubuntu changes + - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches + - [Config] fix up retpoline abi files + - [Config] fix up retpoline abi files + - d-i: Add netsec to nic-modules + + [ Upstream Kernel Changes ] + + * Rebase to v4.16-rc6 + + -- Seth Forshee Mon, 19 Mar 2018 14:09:49 -0500 + +linux (4.16.0-1.2) bionic; urgency=medium + + * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927) + - d-i: add cxgb4 to nic-modules + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_INDIRECT_PIO=y + - SAUCE: LIB: Introduce a generic PIO mapping method + - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range() + - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range() + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - SAUCE: ACPI / scan: do not enumerate Indirect IO host children + - SAUCE: HISI LPC: Add ACPI support + - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver + + * Miscellaneous Ubuntu changes + - SAUCE: tools: use CC for linking acpi tools + + [ Upstream Kernel Changes ] + + * Rebase to v4.16-rc3 + + -- Seth Forshee Wed, 28 Feb 2018 10:17:23 -0600 + +linux (4.16.0-0.1) bionic; urgency=medium + + * retpoline abi files are empty on i386 (LP: #1751021) + - [Packaging] retpoline-extract -- instantiate retpoline files for i386 + - [Packaging] final-checks -- sanity checking ABI contents + - [Packaging] final-checks -- check for empty retpoline files + + * Miscellaneous upstream changes + - disable vbox build + - Disable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.16-rc2 + + -- Seth Forshee Thu, 22 Feb 2018 08:58:57 -0600 + +linux (4.16.0-0.0) bionic; urgency=medium + + * Dummy entry + + -- Seth Forshee Wed, 21 Feb 2018 14:33:13 -0600 + +linux (4.15.0-10.11) bionic; urgency=medium + + * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250) + + * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10 + (LP: #1749202) + - swiotlb: suppress warning when __GFP_NOWARN is set + - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools + + * linux-tools: perf incorrectly linking libbfd (LP: #1748922) + - SAUCE: tools -- add ability to disable libbfd + - [Packaging] correct disablement of libbfd + + * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in + (LP: #1744058) + - ALSA: hda/realtek - update ALC225 depop optimize + + * [Artful] Support headset mode for DELL WYSE (LP: #1723913) + - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE + + * headset mic can't be detected on two Dell machines (LP: #1748807) + - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289 + - ALSA: hda - Fix headset mic detection problem for two Dell machines + + * Bionic update to v4.15.3 stable release (LP: #1749191) + - ip6mr: fix stale iterator + - net: igmp: add a missing rcu locking section + - qlcnic: fix deadlock bug + - qmi_wwan: Add support for Quectel EP06 + - r8169: fix RTL8168EP take too long to complete driver initialization. + - tcp: release sk_frag.page in tcp_disconnect + - vhost_net: stop device during reset owner + - ipv6: addrconf: break critical section in addrconf_verify_rtnl() + - ipv6: change route cache aging logic + - Revert "defer call to mem_cgroup_sk_alloc()" + - net: ipv6: send unsolicited NA after DAD + - rocker: fix possible null pointer dereference in + rocker_router_fib_event_work + - tcp_bbr: fix pacing_gain to always be unity when using lt_bw + - cls_u32: add missing RCU annotation. + - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only + - soreuseport: fix mem leak in reuseport_add_sock() + - net_sched: get rid of rcu_barrier() in tcf_block_put_ext() + - net: sched: fix use-after-free in tcf_block_put_ext + - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION + - media: soc_camera: soc_scale_crop: add missing + MODULE_DESCRIPTION/AUTHOR/LICENSE + - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE + - crypto: tcrypt - fix S/G table for test_aead_speed() + - Linux 4.15.3 + + * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) // + CVE-2018-1000026 + - net: create skb_gso_validate_mac_len() + - bnx2x: disable GSO where gso_size is too big for hardware + + * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567) + - net: hns: add ACPI mode support for ethtool -p + + * CVE-2017-5715 (Spectre v2 Intel) + - [Packaging] retpoline files must be sorted + - [Packaging] pull in retpoline files + + * [Feature] PXE boot with Intel Omni-Path (LP: #1712031) + - d-i: Add hfi1 to nic-modules + + * CVE-2017-5715 (Spectre v2 retpoline) + - [Packaging] retpoline -- add call site validation + - [Config] disable retpoline checks for first upload + + * Do not duplicate changelog entries assigned to more than one bug or CVE + (LP: #1743383) + - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better + + -- Seth Forshee Tue, 13 Feb 2018 11:33:58 -0600 + +linux (4.15.0-9.10) bionic; urgency=medium + + * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244) + + * Miscellaneous Ubuntu changes + - [Debian] tests -- remove gcc-multilib dependency for arm64 + + -- Seth Forshee Thu, 08 Feb 2018 11:25:04 -0600 + +linux (4.15.0-8.9) bionic; urgency=medium + + * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075) + + * Bionic update to v4.15.2 stable release (LP: #1748072) + - KVM: x86: Make indirect calls in emulator speculation safe + - KVM: VMX: Make indirect call speculation safe + - module/retpoline: Warn about missing retpoline in module + - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf + - x86/cpufeatures: Add Intel feature bits for Speculation Control + - x86/cpufeatures: Add AMD feature bits for Speculation Control + - x86/msr: Add definitions for new speculation control MSRs + - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown + - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes + - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support + - x86/alternative: Print unadorned pointers + - x86/nospec: Fix header guards names + - x86/bugs: Drop one "mitigation" from dmesg + - x86/cpu/bugs: Make retpoline module warning conditional + - x86/cpufeatures: Clean up Spectre v2 related CPUID flags + - x86/retpoline: Simplify vmexit_fill_RSB() + - x86/speculation: Simplify indirect_branch_prediction_barrier() + - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - iio: adc/accel: Fix up module licenses + - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - KVM: nVMX: Eliminate vmcs02 pool + - KVM: VMX: introduce alloc_loaded_vmcs + - objtool: Improve retpoline alternative handling + - objtool: Add support for alternatives at the end of a section + - objtool: Warn on stripped section symbol + - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP + - x86/spectre: Check CONFIG_RETPOLINE in command line parser + - x86/entry/64: Remove the SYSCALL64 fast path + - x86/entry/64: Push extra regs right away + - x86/asm: Move 'status' from thread_struct to thread_info + - Documentation: Document array_index_nospec + - array_index_nospec: Sanitize speculative array de-references + - x86: Implement array_index_mask_nospec + - x86: Introduce barrier_nospec + - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec + - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end} + - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec + - x86/get_user: Use pointer masking to limit speculation + - x86/syscall: Sanitize syscall table de-references under speculation + - vfs, fdtable: Prevent bounds-check bypass via speculative execution + - nl80211: Sanitize array index in parse_txq_params + - x86/spectre: Report get_user mitigation for spectre_v1 + - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable" + - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel + - x86/speculation: Use Indirect Branch Prediction Barrier in context switch + - x86/paravirt: Remove 'noreplace-paravirt' cmdline option + - KVM: VMX: make MSR bitmaps per-VCPU + - x86/kvm: Update spectre-v1 mitigation + - x86/retpoline: Avoid retpolines for built-in __init functions + - x86/spectre: Simplify spectre_v2 command line parsing + - x86/pti: Mark constant arrays as __initconst + - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL + - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX + - KVM/x86: Add IBPB support + - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES + - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL + - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL + - serial: core: mark port as initialized after successful IRQ change + - fpga: region: release of_parse_phandle nodes after use + - Linux 4.15.2 + + * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792) + - net: phy: core: remove now uneeded disabling of interrupts + - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m + - net: socionext: Add Synquacer NetSec driver + - net: socionext: include linux/io.h to fix build + - net: socionext: Fix error return code in netsec_netdev_open() + + * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746) + - [Config] CONFIG_EDAC_GHES=y + + * support thunderx2 vendor pmu events (LP: #1747523) + - perf pmu: Pass pmu as a parameter to get_cpuid_str() + - perf tools arm64: Add support for get_cpuid_str function. + - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices + - perf vendor events arm64: Add ThunderX2 implementation defined pmu core + events + - perf pmu: Add check for valid cpuid in perf_pmu__find_map() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Miscellaneous Ubuntu changes + - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations + + -- Seth Forshee Wed, 07 Feb 2018 21:13:27 -0600 + +linux (4.15.0-7.8) bionic; urgency=medium + + * Bionic update to v4.15.1 stable release (LP: #1747169) + - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops + - tools/gpio: Fix build error with musl libc + - gpio: stmpe: i2c transfer are forbiden in atomic context + - gpio: Fix kernel stack leak to userspace + - ALSA: hda - Reduce the suspend time consumption for ALC256 + - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH + - crypto: aesni - handle zero length dst buffer + - crypto: aesni - fix typo in generic_gcmaes_decrypt + - crypto: aesni - add wrapper for generic gcm(aes) + - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm- + aesni + - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm- + aesni + - crypto: inside-secure - fix hash when length is a multiple of a block + - crypto: inside-secure - avoid unmapping DMA memory that was not mapped + - crypto: sha3-generic - fixes for alignment and big endian operation + - crypto: af_alg - whitelist mask and type + - HID: wacom: EKR: ensure devres groups at higher indexes are released + - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events + - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE + - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - igb: Free IRQs when device is hotplugged + - ima/policy: fix parsing of fsuuid + - scsi: aacraid: Fix udev inquiry race condition + - scsi: aacraid: Fix hang in kdump + - scsi: storvsc: missing error code in storvsc_probe() + - staging: lustre: separate a connection destroy from free struct kib_conn + - staging: ccree: NULLify backup_info when unused + - staging: ccree: fix fips event irq handling build + - tty: fix data race between tty_init_dev and flush of buf + - usb: option: Add support for FS040U modem + - USB: serial: pl2303: new device id for Chilitag + - USB: cdc-acm: Do not log urb submission errors on disconnect + - CDC-ACM: apply quirk for card reader + - USB: serial: io_edgeport: fix possible sleep-in-atomic + - usbip: prevent bind loops on devices attached to vhci_hcd + - usbip: list: don't list devices attached to vhci_hcd + - USB: serial: simple: add Motorola Tetra driver + - usb: f_fs: Prevent gadget unbind if it is already unbound + - usb: uas: unconditionally bring back host after reset + - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc() + - ANDROID: binder: remove waitqueue when thread exits. + - android: binder: use VM_ALLOC to get vm area + - mei: me: allow runtime pm for platform with D0i3 + - serial: 8250_of: fix return code when probe function fails to get reset + - serial: 8250_uniphier: fix error return code in uniphier_uart_probe() + - serial: 8250_dw: Revert "Improve clock rate setting" + - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS + - spi: imx: do not access registers while clocks disabled + - iio: adc: stm32: fix scan of multiple channels with DMA + - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels + - test_firmware: fix missing unlock on error in config_num_requests_store() + - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened + - Input: synaptics-rmi4 - do not delete interrupt memory too early + - x86/efi: Clarify that reset attack mitigation needs appropriate userspace + - Linux 4.15.1 + + * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume + (LP: #1744712) + - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume" + - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten" + version + + * apparmor profile load in stacked policy container fails (LP: #1746463) + - SAUCE: apparmor: fix display of .ns_name for containers + + -- Seth Forshee Sun, 04 Feb 2018 11:56:32 +0100 + +linux (4.15.0-6.7) bionic; urgency=low + + * upload urgency should be medium by default (LP: #1745338) + - [Packaging] update urgency to medium by default + + * Shutdown hang on 16.04 with iscsi targets (LP: #1569925) + - scsi: libiscsi: Allow sd_shutdown on bad transport + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1 + - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM" + - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default" + + [ Upstream Kernel Changes ] + + * Rebase to v4.15 + + -- Seth Forshee Mon, 29 Jan 2018 08:47:07 -0600 + +linux (4.15.0-5.6) bionic; urgency=low + + * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted + (LP: #1744077) + - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly + + * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC + (LP: #1743638) + - [d-i] Add qede to nic-modules udeb + + * boot failure on AMD Raven + WesternXT (LP: #1742759) + - SAUCE: drm/amdgpu: add atpx quirk handling (v2) + + * Unable to handle kernel NULL pointer dereference at isci_task_abort_task + (LP: #1726519) + - SAUCE: Revert "scsi: libsas: allow async aborts" + + * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939) + - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y + + * Miscellaneous Ubuntu changes + - Rebase to v4.15-rc7 + - [Config] CONFIG_CPU_ISOLATION=y + - [Config] Update annotations following config review + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - ubuntu: vbox -- update to 5.2.6-dfsg-1 + - ubuntu: vbox: build fixes for 4.15 + - ubuntu: vbox -- update to 5.2.6-dfsg-2 + - hio: updates for timer api changes in 4.15 + - enable hio build + - Rebase to v4.15-rc9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc9 + + -- Seth Forshee Mon, 22 Jan 2018 10:16:05 -0600 + +linux (4.15.0-4.5) bionic; urgency=low + + * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device (LP: #1741166) + - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010 + + * External HDMI monitor failed to show screen on Lenovo X1 series + (LP: #1738523) + - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series + + * Miscellaneous Ubuntu changes + - [Debian] autoreconstruct - add resoration of execute permissions + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Wed, 10 Jan 2018 10:24:22 -0600 + +linux (4.15.0-3.4) bionic; urgency=low + + * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281) + - SAUCE: make sure ubuntu/xr-usb-serial builds for x86 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc6 + + -- Seth Forshee Wed, 03 Jan 2018 20:20:43 -0600 + +linux (4.15.0-2.3) bionic; urgency=low + + * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux + 4.15.0-1.2 (LP: #1737752) + - x86/mm: Unbreak modules that use the DMA API + + * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147) + - [Config] CONFIG_SPI_INTEL_SPI_*=n + + * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image + and udebs (LP: #1521712) + - [Config] Include ibmvnic in nic-modules + + * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542) + - [Config] Enable support for emulation of deprecated ARMv8 instructions + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761) + - Enable zfs build + - [Debian] add icp to zfs-modules.ignore + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Mon, 18 Dec 2017 09:27:13 -0600 + +linux (4.15.0-1.2) bionic; urgency=low + + * Disabling zfs does not always disable module checks for the zfs modules + (LP: #1737176) + - [Packaging] disable zfs module checks when zfs is disabled + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc3 + + -- Seth Forshee Sun, 10 Dec 2017 22:07:19 -0600 + +linux (4.15.0-0.1) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.2.2-dfsg-2 + - ubuntu: vbox: build fixes for 4.15 + - disable hio build + - [Config] Update kernel lockdown options to fix build errors + - Disable zfs build + - SAUCE: Import aufs driver + - [Config] Enable AUFS config options + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc2 + + -- Seth Forshee Fri, 08 Dec 2017 13:55:42 -0600 + +linux (4.14.0-11.13) bionic; urgency=low + + * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168) + + * CVE-2017-1000405 + - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Bionic update to v4.14.3 stable release (LP: #1735843) + - s390: fix transactional execution control register handling + - s390/noexec: execute kexec datamover without DAT + - s390/runtime instrumention: fix possible memory corruption + - s390/guarded storage: fix possible memory corruption + - s390/disassembler: add missing end marker for e7 table + - s390/disassembler: increase show_code buffer size + - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock + - ACPI / EC: Fix regression related to triggering source of EC event handling + - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq + - serdev: fix registration of second slave + - sched: Make resched_cpu() unconditional + - lib/mpi: call cond_resched() from mpi_powm() loop + - x86/boot: Fix boot failure when SMP MP-table is based at 0 + - x86/decoder: Add new TEST instruction pattern + - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing + - x86/entry/64: Add missing irqflags tracing to native_load_gs_index() + - perf/x86/intel: Hide TSX events when RTM is not supported + - arm64: Implement arch-specific pte_access_permitted() + - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE + - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE + - uapi: fix linux/tls.h userspace compilation error + - uapi: fix linux/rxrpc.h userspace compilation errors + - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP + - MIPS: ralink: Fix MT7628 pinmux + - MIPS: ralink: Fix typo in mt7628 pinmux function + - net: mvneta: fix handling of the Tx descriptor counter + - nbd: wait uninterruptible for the dead timeout + - nbd: don't start req until after the dead connection logic + - PM / OPP: Add missing of_node_put(np) + - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time + - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD + - PCI: hv: Use effective affinity mask + - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF + - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports + - ALSA: hda: Add Raven PCI ID + - dm integrity: allow unaligned bv_offset + - dm cache: fix race condition in the writeback mode overwrite_bio + optimisation + - dm crypt: allow unaligned bv_offset + - dm zoned: ignore last smaller runt zone + - dm mpath: remove annoying message of 'blk_get_request() returned -11' + - dm bufio: fix integer overflow when limiting maximum cache size + - ovl: Put upperdentry if ovl_check_origin() fails + - dm: allocate struct mapped_device with kvzalloc + - sched/rt: Simplify the IPI based RT balancing logic + - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver + - dm: fix race between dm_get_from_kobject() and __dm_destroy() + - dm: discard support requires all targets in a table support discards + - MIPS: Fix odd fp register warnings with MIPS64r2 + - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels + - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry + - MIPS: Fix an n32 core file generation regset support regression + - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1 + - MIPS: math-emu: Fix final emulation phase for certain instructions + - rt2x00usb: mark device removed when get ENOENT usb error + - mm/z3fold.c: use kref to prevent page free/compact race + - autofs: don't fail mount for transient error + - nilfs2: fix race condition that causes file system corruption + - fscrypt: lock mutex before checking for bounce page pool + - eCryptfs: use after free in ecryptfs_release_messaging() + - libceph: don't WARN() if user tries to add invalid key + - bcache: check ca->alloc_thread initialized before wake up it + - fs: guard_bio_eod() needs to consider partitions + - fanotify: fix fsnotify_prepare_user_wait() failure + - isofs: fix timestamps beyond 2027 + - btrfs: change how we decide to commit transactions during flushing + - f2fs: expose some sectors to user in inline data or dentry case + - NFS: Fix typo in nomigration mount option + - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()" + - nfs: Fix ugly referral attributes + - NFS: Avoid RCU usage in tracepoints + - NFS: revalidate "." etc correctly on "open". + - nfsd: deal with revoked delegations appropriately + - rtlwifi: rtl8192ee: Fix memory leak when loading firmware + - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time + - iwlwifi: fix firmware names for 9000 and A000 series hw + - md: fix deadlock error in recent patch. + - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write + - Bluetooth: btqcomsmd: Add support for BD address setup + - md/bitmap: revert a patch + - fsnotify: clean up fsnotify_prepare/finish_user_wait() + - fsnotify: pin both inode and vfsmount mark + - fsnotify: fix pinning group in fsnotify_prepare_user_wait() + - ata: fixes kernel crash while tracing ata_eh_link_autopsy event + - ext4: fix interaction between i_size, fallocate, and delalloc after a crash + - ext4: prevent data corruption with inline data + DAX + - ext4: prevent data corruption with journaling + DAX + - ALSA: pcm: update tstamp only if audio_tstamp changed + - ALSA: usb-audio: Add sanity checks to FE parser + - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU + - ALSA: usb-audio: Add sanity checks in v2 clock parsers + - ALSA: timer: Remove kernel warning at compat ioctl error paths + - ALSA: hda/realtek - Fix ALC275 no sound issue + - ALSA: hda: Fix too short HDMI/DP chmap reporting + - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization + - ALSA: hda/realtek - Fix ALC700 family no sound issue + - ASoC: sun8i-codec: Invert Master / Slave condition + - ASoC: sun8i-codec: Fix left and right channels inversion + - ASoC: sun8i-codec: Set the BCLK divider + - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method + - fix a page leak in vhost_scsi_iov_to_sgl() error recovery + - 9p: Fix missing commas in mount options + - fs/9p: Compare qid.path in v9fs_test_inode + - net/9p: Switch to wait_event_killable() + - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair() + - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics() + - scsi: lpfc: fix pci hot plug crash in timer management routines + - scsi: lpfc: fix pci hot plug crash in list_add call + - scsi: lpfc: Fix crash receiving ELS while detaching driver + - scsi: lpfc: Fix FCP hba_wqidx assignment + - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails + - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref + - iscsi-target: Fix non-immediate TMR reference leak + - target: fix null pointer regression in core_tmr_drain_tmr_list + - target: fix buffer offset in core_scsi3_pri_read_full_status + - target: Fix QUEUE_FULL + SCSI task attribute handling + - target: Fix caw_sem leak in transport_generic_request_failure + - target: Fix quiese during transport_write_pending_qf endless loop + - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK + - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid + - mtd: nand: Export nand_reset() symbol + - mtd: nand: atmel: Actually use the PM ops + - mtd: nand: omap2: Fix subpage write + - mtd: nand: Fix writing mtdoops to nand flash. + - mtd: nand: mtk: fix infinite ECC decode IRQ issue + - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence + - p54: don't unregister leds when they are not initialized + - block: Fix a race between blk_cleanup_queue() and timeout handling + - raid1: prevent freeze_array/wait_all_barriers deadlock + - genirq: Track whether the trigger type has been set + - irqchip/gic-v3: Fix ppi-partitions lookup + - lockd: double unregister of inetaddr notifiers + - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not + enabled + - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state + - KVM: SVM: obey guest PAT + - kvm: vmx: Reinstate support for CPUs without virtual NMI + - dax: fix PMD faults on zero-length files + - dax: fix general protection fault in dax_alloc_inode + - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status + - clk: ti: dra7-atl-clock: fix child-node lookups + - libnvdimm, dimm: clear 'locked' status on successful DIMM enable + - libnvdimm, pfn: make 'resource' attribute only readable by root + - libnvdimm, namespace: fix label initialization to use valid seq numbers + - libnvdimm, region : make 'resource' attribute only readable by root + - libnvdimm, namespace: make 'resource' attribute only readable by root + - svcrdma: Preserve CB send buffer across retransmits + - IB/srpt: Do not accept invalid initiator port names + - IB/cm: Fix memory corruption in handling CM request + - IB/hfi1: Fix incorrect available receive user context count + - IB/srp: Avoid that a cable pull can trigger a kernel crash + - IB/core: Avoid crash on pkey enforcement failed in received MADs + - IB/core: Only maintain real QPs in the security lists + - NFC: fix device-allocation error return + - spi-nor: intel-spi: Fix broken software sequencing codes + - i40e: Use smp_rmb rather than read_barrier_depends + - igb: Use smp_rmb rather than read_barrier_depends + - igbvf: Use smp_rmb rather than read_barrier_depends + - ixgbevf: Use smp_rmb rather than read_barrier_depends + - i40evf: Use smp_rmb rather than read_barrier_depends + - fm10k: Use smp_rmb rather than read_barrier_depends + - ixgbe: Fix skb list corruption on Power systems + - parisc: Fix validity check of pointer size argument in new CAS + implementation + - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX + - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX + - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id() + - powerpc/signal: Properly handle return value from uprobe_deny_signal() + - powerpc/64s: Fix masking of SRR1 bits on instruction fault + - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix 512T hint detection to use >= 128T + - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix fork() with 512TB process address space + - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary + - media: Don't do DMA on stack for firmware upload in the AS102 driver + - media: rc: check for integer overflow + - media: rc: nec decoder should not send both repeat and keycode + - cx231xx-cards: fix NULL-deref on missing association descriptor + - media: v4l2-ctrl: Fix flags field on Control events + - media: venus: fix wrong size on dma_free + - media: venus: venc: fix bytesused v4l2_plane field + - media: venus: reimplement decoder stop command + - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory + zone + - iwlwifi: fix wrong struct for a000 device + - iwlwifi: add a new a000 device + - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons + - iwlwifi: add new cards for a000 series + - iwlwifi: add new cards for 8265 series + - iwlwifi: add new cards for 8260 series + - iwlwifi: fix PCI IDs and configuration mapping for 9000 series + - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command + - e1000e: Fix error path in link detection + - e1000e: Fix return value test + - e1000e: Separate signaling for link check/link up + - e1000e: Avoid receiver overrun interrupt bursts + - e1000e: fix buffer overrun while the I219 is processing DMA transactions + - Linux 4.14.3 + + * Miscellaneous Ubuntu changes + - SAUCE: s390/topology: don't inline cpu_to_node + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 04 Dec 2017 09:08:07 -0600 + +linux (4.14.0-10.12) bionic; urgency=low + + * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901) + + * Miscellaneous Ubuntu changes + - SAUCE: Enable the ACPI kernel debugger and acpidbg tool + - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package + + -- Seth Forshee Tue, 28 Nov 2017 08:46:49 -0600 + +linux (4.14.0-9.11) bionic; urgency=low + + * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728) + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to + 0.7.3-1ubuntu1" + + -- Seth Forshee Mon, 27 Nov 2017 12:44:48 -0600 + +linux (4.14.0-8.10) bionic; urgency=low + + * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695) + + * Bionic update to v4.14.2 stable release (LP: #1734694) + - bio: ensure __bio_clone_fast copies bi_partno + - af_netlink: ensure that NLMSG_DONE never fails in dumps + - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets + - net: cdc_ncm: GetNtbFormat endian fix + - fealnx: Fix building error on MIPS + - net/sctp: Always set scope_id in sctp_inet6_skb_msgname + - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS + - serial: omap: Fix EFR write on RTS deassertion + - serial: 8250_fintek: Fix finding base_port with activated SuperIO + - tpm-dev-common: Reject too short writes + - rcu: Fix up pending cbs check in rcu_prepare_for_idle + - mm/pagewalk.c: report holes in hugetlb ranges + - ocfs2: fix cluster hang after a node dies + - ocfs2: should wait dio before inode lock in ocfs2_setattr() + - ipmi: fix unsigned long underflow + - mm/page_alloc.c: broken deferred calculation + - mm/page_ext.c: check if page_ext is not prepared + - coda: fix 'kernel memory exposure attempt' in fsync + - ipmi: Prefer ACPI system interfaces over SMBIOS ones + - Linux 4.14.2 + + * Bionic update to v4.14.1 stable release (LP: #1734693) + - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present + - dmaengine: dmatest: warn user when dma test times out + - media: imon: Fix null-ptr-deref in imon_probe + - media: dib0700: fix invalid dvb_detach argument + - crypto: dh - Fix double free of ctx->p + - crypto: dh - Don't permit 'p' to be 0 + - crypto: dh - Don't permit 'key' or 'g' size longer than 'p' + - crypto: brcm - Explicity ACK mailbox message + - USB: early: Use new USB product ID and strings for DbC device + - USB: usbfs: compute urb->actual_length for isochronous + - USB: Add delay-init quirk for Corsair K70 LUX keyboards + - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst + - USB: serial: metro-usb: stop I/O after failed open + - USB: serial: Change DbC debug device binding ID + - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update + - USB: serial: garmin_gps: fix I/O after failed probe and remove + - USB: serial: garmin_gps: fix memory leak on probe errors + - selftests/x86/protection_keys: Fix syscall NR redefinition warnings + - x86/MCE/AMD: Always give panic severity for UC errors in kernel context + - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface + - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table + - HID: cp2112: add HIDRAW dependency + - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection + - rpmsg: glink: Add missing MODULE_LICENSE + - staging: wilc1000: Fix bssid buffer offset in Txq + - staging: sm750fb: Fix parameter mistake in poke32 + - staging: ccree: fix 64 bit scatter/gather DMA ops + - staging: greybus: spilib: fix use-after-free after deregistration + - staging: rtl8188eu: Revert 4 commits breaking ARP + - spi: fix use-after-free at controller deregistration + - sparc32: Add cmpxchg64(). + - sparc64: mmu_context: Add missing include files + - sparc64: Fix page table walk for PUD hugepages + - Linux 4.14.1 + + * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660) + - [Config]: Set PANIC_TIMEOUT=10 on ppc64el + + * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users + (LP: #1732627) + - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 27 Nov 2017 07:43:44 -0600 + +linux (4.14.0-7.9) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: add base infastructure for socket mediation + - SAUCE: apparmor: af_unix mediation + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: manage task security blobs + - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs + - SAUCE: LSM stacking: LSM: general but not extreme module stacking + - SAUCE: LSM stacking: LSM: Complete task_alloc hook + - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: check for invalid zero sized writes + - [Config] Run updateconfigs after merging LSM stacking + - [Config] CONFIG_AMD_MEM_ENCRYPT=y + + [ Upstream Kernel Changes ] + + * Rebase to v4.14 + + -- Seth Forshee Mon, 13 Nov 2017 08:12:08 -0600 + +linux (4.14.0-6.8) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: add workarounds to enable ZFS for 4.14 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc8 + + -- Seth Forshee Mon, 06 Nov 2017 11:39:00 -0600 + +linux (4.14.0-5.7) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Fix invocation of dh_prep for dbgsym packages + + -- Seth Forshee Tue, 31 Oct 2017 07:07:23 -0500 + +linux (4.14.0-4.5) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Packaging] virtualbox -- reduce in kernel module versions + - vbox-update: Fix up KERN_DIR definitions + - ubuntu: vbox -- update to 5.2.0-dfsg-2 + - [Config] CONFIG_AMD_MEM_ENCRYPT=n + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc7 + + -- Seth Forshee Mon, 30 Oct 2017 13:29:20 -0500 + +linux (4.14.0-3.4) artful; urgency=low + + * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986) + - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3 + - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI + - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280 + + * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070) + - powerpc/64s: Add workaround for P9 vector CI load issue + + * Miscellaneous Ubuntu changes + - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties + - [Config] CONFIG_DRM_VBOXVIDEO=m + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Config] Reorder annotations file after enabling aufs + - vbox-update: Disable imported vboxvideo module + - ubuntu: vbox -- update to 5.1.30-dfsg-1 + - Enable vbox + - hio: Use correct sizes when initializing ssd_index_bits* arrays + - hio: Update io stat accounting for 4.14 + - Enable hio + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc5 + * Rebase to v4.14-rc6 + + -- Seth Forshee Mon, 23 Oct 2017 13:53:52 -0500 + +linux (4.14.0-2.3) artful; urgency=low + + * [Bug] USB controller failed to respond on Denverton after loading + intel_th_pci module (LP: #1715833) + - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH + + * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu + 17.10 (kernel 4.13) (LP: #1719290) + - SAUCE: s390: update zfcpdump_defconfig + + * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466) + - d-i: Add bnxt_en to nic-modules. + + * Miscellaneous Ubuntu changes + - [Config] Update annotations for 4.14-rc2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc3 + * Rebase to v4.14-rc4 + + -- Seth Forshee Wed, 11 Oct 2017 16:04:27 -0500 + +linux (4.14.0-1.2) artful; urgency=low + + * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045) + - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor + + * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091) + - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev + + * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland + (LP: #1718679) + - [Config] CONFIG_DRM_VBOXVIDEO=n + + * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734) + - [Config] Disable CONFIG_IPMMU_VMSA on arm64 + + * autopkgtest profile fails to build on armhf (LP: #1717920) + - [Packaging] autopkgtest -- disable d-i when dropping flavours + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_I2C_XLP9XX=m + - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc2 + + -- Seth Forshee Fri, 29 Sep 2017 09:09:11 -0400 + +linux (4.14.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable vbox build + - Disable hio build + - Disable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc1 + + -- Seth Forshee Tue, 19 Sep 2017 20:22:29 -0500 + +linux (4.13.0-11.12) artful; urgency=low + + * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699) + + * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399) + - s390/mm: fix local TLB flushing vs. detach of an mm address space + - s390/mm: fix race on mm->context.flush_mm + + * CVE-2017-1000251 + - Bluetooth: Properly check L2CAP config option output buffer length + + -- Seth Forshee Tue, 12 Sep 2017 10:18:38 -0500 + +linux (4.13.0-10.11) artful; urgency=low + + * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287) + + * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093) + - [Packaging] Add aufs-dkms to the Provides: for kernel packages + + * Artful update to v4.13.1 stable release (LP: #1716284) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + - USB: serial: option: add support for D-Link DWM-157 C1 + - usb: Add device quirk for Logitech HD Pro Webcam C920-C + - usb:xhci:Fix regression when ATI chipsets detected + - USB: musb: fix external abort on suspend + - ANDROID: binder: add padding to binder_fd_array_object. + - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES. + - USB: core: Avoid race of async_completed() w/ usbdev_release() + - staging/rts5208: fix incorrect shift to extract upper nybble + - staging: ccree: save ciphertext for CTS IV + - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks + - iio: adc: ti-ads1015: fix incorrect data rate setting update + - iio: adc: ti-ads1015: fix scale information for ADS1115 + - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set + - iio: adc: ti-ads1015: avoid getting stale result after runtime resume + - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks + - iio: adc: ti-ads1015: add adequate wait time to get correct conversion + - driver core: bus: Fix a potential double free + - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage + - binder: free memory on error + - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y + - crypto: caam/qi - fix compilation with DEBUG enabled + - thunderbolt: Fix reset response_type + - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock + - intel_th: pci: Add Cannon Lake PCH-H support + - intel_th: pci: Add Cannon Lake PCH-LP support + - ath10k: fix memory leak in rx ring buffer allocation + - drm/vgem: Pin our pages for dmabuf exports + - drm/ttm: Fix accounting error when fail to get pages for pool + - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly + - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter + - Bluetooth: Add support of 13d3:3494 RTL8723BE device + - iwlwifi: pci: add new PCI ID for 7265D + - dlm: avoid double-free on error path in dlm_device_{register,unregister} + - mwifiex: correct channel stat buffer overflows + - MCB: add support for SC31 to mcb-lpc + - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs + - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default + - drm/nouveau: Fix error handling in nv50_disp_atomic_commit + - workqueue: Fix flag collision + - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme + - cs5536: add support for IDE controller variant + - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE + - scsi: sg: recheck MMAP_IO request length with lock held + - of/device: Prevent buffer overflow in of_device_modalias() + - rtlwifi: Fix memory leak when firmware request fails + - rtlwifi: Fix fallback firmware loading + - Linux 4.13.1 + + * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + + * SRIOV: warning if unload VFs (LP: #1715073) + - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources + + * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578) + - i40e: avoid NVM acquire deadlock during NVM update + - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq + + * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted + twice when perf stat is done (perf:) (LP: #1714571) + - perf vendor events powerpc: Remove duplicate events + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Include vmd in storage-core-modules udeb + + * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064) + - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle + - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug + - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state + offline + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + + -- Seth Forshee Sun, 10 Sep 2017 17:48:59 -0500 + +linux (4.13.0-9.10) artful; urgency=low + + * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145) + + * EDAC sbridge: Failed to register device with error -22. (LP: #1714112) + - [Config] CONFIG_EDAC_GHES=n + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13 + + -- Seth Forshee Tue, 05 Sep 2017 07:51:19 -0500 + +linux (4.13.0-8.9) artful; urgency=low + + * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103) + - SAUCE: apparmor: fix apparmorfs DAC access, permissions + + * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137) + - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64 + + * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping + Harrisonville SDP (LP: #1709257) + - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake + - EDAC, pnd2: Mask off the lower four bits of a BAR + - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR + - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device + - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after + reading BAR + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - SAUCE: selftests/powerpc: Disable some ptrace selftests + - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x + - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el + - [Config] Disable CONFIG_MDIO_* options for s390x + - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x + - [Config] Update annotations for 4.13 + + -- Seth Forshee Thu, 31 Aug 2017 14:27:09 -0500 + +linux (4.13.0-7.8) artful; urgency=low + + * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904) + - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface + paths + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled" + + * Miscellaneous upstream changes + - seccomp: Provide matching filter for introspection + - seccomp: Sysctl to display available actions + - seccomp: Operation for checking if an action is available + - seccomp: Sysctl to configure actions that are allowed to be logged + - seccomp: Selftest for detection of filter flag support + - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW + - seccomp: Action to log before allowing + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc7 + + -- Seth Forshee Mon, 28 Aug 2017 08:12:24 -0500 + +linux (4.13.0-6.7) artful; urgency=low + + * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481) + - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A + + * sort ABI files with C.UTF-8 locale (LP: #1712345) + - [Packaging] sort ABI files with C.UTF-8 locale + + * igb: Support using Broadcom 54616 as PHY (LP: #1712024) + - SAUCE: igb: add support for using Broadcom 54616 as PHY + + * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220) + - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes + - powerpc/mm/radix: Improve TLB/PWC flushes + - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range + + * Linux 4.12 refuses to load self-signed modules under Secure Boot with + properly enrolled keys (LP: #1712168) + - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification + + * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432) + - [Config] CONFIG_BLK_DEV_NVME=m for s390 + + * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0 + (LP: #1711298) + - [Config] CONFIG_INTEL_ATOMISP=n + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: af_unix mediation + + * Miscellaneous upstream changes + - apparmor: Fix shadowed local variable in unpack_trans_table() + - apparmor: Fix logical error in verify_header() + - apparmor: Fix an error code in aafs_create() + - apparmor: Redundant condition: prev_ns. in [label.c:1498] + - apparmor: add the ability to mediate signals + - apparmor: add mount mediation + - apparmor: cleanup conditional check for label in label_print + - apparmor: add support for absolute root view based labels + - apparmor: make policy_unpack able to audit different info messages + - apparmor: add more debug asserts to apparmorfs + - apparmor: add base infastructure for socket mediation + - apparmor: move new_null_profile to after profile lookup fns() + - apparmor: fix race condition in null profile creation + - apparmor: ensure unconfined profiles have dfas initialized + - apparmor: fix incorrect type assignment when freeing proxies + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc6 + + -- Seth Forshee Wed, 23 Aug 2017 08:10:38 -0500 + +linux (4.13.0-5.6) artful; urgency=low + + * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630) + - perf pmu-events: Support additional POWER8+ PVR in mapfile + - perf vendor events: Add POWER9 PMU events + - perf vendor events: Add POWER9 PVRs to mapfile + - SAUCE: perf vendor events powerpc: remove suffix in mapfile + - SAUCE: perf vendor events powerpc: Update POWER9 events + + * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171) + - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el + + * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for + kernels able to boot without initramfs (LP: #1700972) + - [Debian] Don't depend on initramfs-tools + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - SAUCE: aufs -- Add missing argument to loop_switch() call + - [Config] Enable aufs + - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3 + - Enable zfs build + - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall() + - [Packaging] switch up to debhelper 9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc5 + + -- Seth Forshee Tue, 15 Aug 2017 09:24:16 -0500 + +linux (4.13.0-4.5) artful; urgency=low + + * Lenovo Yoga 910 Sensors (LP: #1708120) + - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Add vmd driver to generic inclusion list + + * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430) + - [Config] CONFIG_SATA_HIGHBANK=y + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-1 + - SAUCE: hio: Build fixes for 4.13 + - Enable hio build + - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1 + - [debian] use all rather than amd64 dkms debs for sync + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc4 + + -- Seth Forshee Tue, 08 Aug 2017 11:31:48 -0500 + +linux (4.13.0-3.4) artful; urgency=low + + * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495) + - [Packaging] tests -- reduce rebuild test to one flavour + - [Packaging] tests -- reduce rebuild test to one flavour -- use filter + + * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158) + - SAUCE: virtio_net: Revert mergeable buffer handling rework + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc3 + + -- Seth Forshee Mon, 31 Jul 2017 10:08:16 -0500 + +linux (4.13.0-2.3) artful; urgency=low + + * Change CONFIG_IBMVETH to module (LP: #1704479) + - [Config] CONFIG_IBMVETH=m + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc2 + + -- Seth Forshee Mon, 24 Jul 2017 13:58:08 -0500 + +linux (4.13.0-1.2) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Support sphinx-based kernel documentation + + -- Seth Forshee Thu, 20 Jul 2017 09:18:33 -0500 + +linux (4.13.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable hio + - Disable zfs build + - ubuntu: vbox -- update to 5.1.24-dfsg-1 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc1 + + -- Seth Forshee Wed, 19 Jul 2017 15:09:31 -0500 + +linux (4.12.0-7.8) artful; urgency=low + + * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on + (LP: #1673564) + - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding + - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers + - KVM: arm64: Make kvm_condition_valid32() accessible from EL2 + - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2 + - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler + - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers + - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line + - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler + - KVM: arm64: vgic-v3: Add misc Group-0 handlers + - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers + - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line + - arm64: Add MIDR values for Cavium cn83XX SoCs + - arm64: Add workaround for Cavium Thunder erratum 30115 + - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler + - KVM: arm64: Enable GICv3 common sysreg trapping via command-line + - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped + - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access + - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access + + * hns: under heavy load, NIC may fail and require reboot (LP: #1704146) + - net: hns: Bugfix for Tx timeout handling in hns driver + + * New ACPI identifiers for ThunderX SMMU (LP: #1703437) + - iommu/arm-smmu: Plumb in new ACPI identifiers + + * Transparent hugepages should default to enabled=madvise (LP: #1703742) + - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default + + * Artful update to v4.12.1 stable release (LP: #1703858) + - driver core: platform: fix race condition with driver_override + - RDMA/uverbs: Check port number supplied by user verbs cmds + - usb: dwc3: replace %p with %pK + - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + - usb: usbip: set buffer pointers to NULL after free + - Add USB quirk for HVR-950q to avoid intermittent device resets + - usb: Fix typo in the definition of Endpoint[out]Request + - USB: core: fix device node leak + - USB: serial: option: add two Longcheer device ids + - USB: serial: qcserial: new Sierra Wireless EM7305 device ID + - xhci: Limit USB2 port wake support for AMD Promontory hosts + - gfs2: Fix glock rhashtable rcu bug + - Add "shutdown" to "struct class". + - tpm: Issue a TPM2_Shutdown for TPM2 devices. + - tpm: fix a kernel memory leak in tpm-sysfs.c + - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error + - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings + - sched/fair, cpumask: Export for_each_cpu_wrap() + - sched/core: Implement new approach to scale select_idle_cpu() + - sched/numa: Use down_read_trylock() for the mmap_sem + - sched/numa: Override part of migrate_degrades_locality() when idle balancing + - sched/fair: Simplify wake_affine() for the single socket case + - sched/numa: Implement NUMA node level wake_affine() + - sched/fair: Remove effective_load() + - sched/numa: Hide numa_wake_affine() from UP build + - xen: avoid deadlock in xenbus driver + - crypto: drbg - Fixes panic in wait_for_completion call + - Linux 4.12.1 + + * cxlflash update request in the Xenial SRU stream (LP: #1702521) + - scsi: cxlflash: Combine the send queue locks + - scsi: cxlflash: Update cxlflash_afu_sync() to return errno + - scsi: cxlflash: Reset hardware queue context via specified register + - scsi: cxlflash: Schedule asynchronous reset of the host + - scsi: cxlflash: Handle AFU sync failures + - scsi: cxlflash: Track pending scsi commands in each hardware queue + - scsi: cxlflash: Flush pending commands in cleanup path + - scsi: cxlflash: Add scsi command abort handler + - scsi: cxlflash: Create character device to provide host management interface + - scsi: cxlflash: Separate AFU internal command handling from AFU sync + specifics + - scsi: cxlflash: Introduce host ioctl support + - scsi: cxlflash: Refactor AFU capability checking + - scsi: cxlflash: Support LUN provisioning + - scsi: cxlflash: Support AFU debug + - scsi: cxlflash: Support WS16 unmap + - scsi: cxlflash: Remove zeroing of private command data + - scsi: cxlflash: Update TMF command processing + - scsi: cxlflash: Avoid double free of character device + - scsi: cxlflash: Update send_tmf() parameters + - scsi: cxlflash: Update debug prints in reset handlers + + * make snap-pkg support (LP: #1700747) + - make snap-pkg support + + * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706) + - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge + + * arm64: fix crash reading /proc/kcore (LP: #1702749) + - fs/proc: kcore: use kcore_list type to check for vmalloc/module address + - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT + + * Opal and POWER9 DD2 (LP: #1702159) + - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9 + + * Data corruption with hio driver (LP: #1701316) + - SAUCE: hio: Fix incorrect use of enum req_opf values + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2 + - snapcraft.yaml: Sync with xenial + - [Config] CONFIG_CAVIUM_ERRATUM_30115=y + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and + MokSBState" + + -- Seth Forshee Fri, 14 Jul 2017 15:25:41 -0500 + +linux (4.12.0-6.7) artful; urgency=low + + * update ENA driver to 1.2.0k from net-next (LP: #1701575) + - net: ena: change return value for unsupported features unsupported return + value + - net: ena: add hardware hints capability to the driver + - net: ena: change sizeof() argument to be the type pointer + - net: ena: add reset reason for each device FLR + - net: ena: add support for out of order rx buffers refill + - net: ena: allow the driver to work with small number of msix vectors + - net: ena: use napi_schedule_irqoff when possible + - net: ena: separate skb allocation to dedicated function + - net: ena: use lower_32_bits()/upper_32_bits() to split dma address + - net: ena: update driver's rx drop statistics + - net: ena: update ena driver to version 1.2.0 + + * APST gets enabled against explicit kernel option (LP: #1699004) + - nvme: explicitly disable APST on quirked devices + + * Miscellaneous Ubuntu changes + - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40) + - SAUCE: hio updates for 4.12 + - SAUCE: Enable hio build + + -- Seth Forshee Wed, 05 Jul 2017 14:23:20 -0500 + +linux (4.12.0-5.6) artful; urgency=low + + * ERAT invalidate on context switch removal (LP: #1700819) + - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1 + + * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521) + - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9 + + * Miscellaneous Ubuntu changes + - d-i: Move qcom-emac from arm64 to shared nic-modules + + [ Upstream Kernel Changes ] + + * Rebase to v4.12 + + -- Seth Forshee Mon, 03 Jul 2017 07:52:02 -0500 + +linux (4.12.0-4.5) artful; urgency=low + + * aacraid driver may return uninitialized stack data to userspace + (LP: #1700077) + - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace + + * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651) + - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device + + * AACRAID for power9 platform (LP: #1689980) + - scsi: aacraid: Remove __GFP_DMA for raw srb memory + - scsi: aacraid: Fix DMAR issues with iommu=pt + - scsi: aacraid: Added 32 and 64 queue depth for arc natives + - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks + - scsi: aacraid: Remove reset support from check_health + - scsi: aacraid: Change wait time for fib completion + - scsi: aacraid: Log count info of scsi cmds before reset + - scsi: aacraid: Print ctrl status before eh reset + - scsi: aacraid: Using single reset mask for IOP reset + - scsi: aacraid: Rework IOP reset + - scsi: aacraid: Add periodic checks to see IOP reset status + - scsi: aacraid: Rework SOFT reset code + - scsi: aacraid: Rework aac_src_restart + - scsi: aacraid: Use correct function to get ctrl health + - scsi: aacraid: Make sure ioctl returns on controller reset + - scsi: aacraid: Enable ctrl reset for both hba and arc + - scsi: aacraid: Add reset debugging statements + - scsi: aacraid: Remove reference to Series-9 + - scsi: aacraid: Update driver version to 50834 + + * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700) + - SAUCE: drm: hibmc: Use set_busid function from drm core + + * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954) + - d-i: Add hibmc-drm to kernel-image udeb + + * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844) + - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2 + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x + - [Config] CONFIG_ATA=n for s390x + - [Config] Update annotations for 4.12 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc7 + + -- Seth Forshee Mon, 26 Jun 2017 11:27:29 -0500 + +linux (4.12.0-3.4) artful; urgency=low + + * Miscellaneous upstream changes + - ufs: fix the logics for tail relocation + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc6 + + -- Seth Forshee Mon, 19 Jun 2017 14:50:39 -0500 + +linux (4.12.0-2.3) artful; urgency=low + + * CVE-2014-9900 + - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in + ethtool_get_wol() + + * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen) + (LP: #1671360) + - pinctrl/amd: Use regular interrupt instead of chained + + * extend-diff-ignore should use exact matches (LP: #1693504) + - [Packaging] exact extend-diff-ignore matches + + * Miscellaneous Ubuntu changes + - SAUCE: efi: Don't print secure boot state from the efi stub + - ubuntu: vbox -- Update to 5.1.22-dfsg-1 + - SAUCE: vbox fixes for 4.12 + - Re-enable virtualbox build + - [Config] CONFIG_ORANGEFS_FS=m + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7 + - Enable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc4 + * Rebase to v4.12-rc5 + + -- Seth Forshee Sun, 11 Jun 2017 22:25:13 -0500 + +linux (4.12.0-1.2) artful; urgency=low + + * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337) + - [Config] Enable CONFIG_DRM_MGAG200 as module + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_LIBIO=y on arm64 only + - SAUCE: LIBIO: Introduce a generic PIO mapping method + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07 + - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host + I/O + - SAUCE: LPC: Add the ACPI LPC support + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO + + * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325) + - SAUCE: tty: Fix ldisc crash on reopened tty + + * Miscellaneous Ubuntu changes + - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa' + - Rebase to v4.12-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc3 + + -- Seth Forshee Mon, 29 May 2017 20:56:29 -0500 + +linux (4.12.0-0.1) artful; urgency=low + + * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614) + - [Config] CONFIG_ARM64_LSE_ATOMICS=y + + * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914) + - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64 + + * exec'ing a setuid binary from a threaded program sometimes fails to setuid + (LP: #1672819) + - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct + + * Miscellaneous Ubuntu changes + - Update find-missing-sauce.sh to compare to artful + - Update dropped.txt + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Disable virtualbox build + - Disable hio build + - SAUCE: securityfs: Replace CURRENT_TIME with current_time() + - Disable zfs build + - [Debian] Work out upstream tag for use with gen-auto-reconstruct + - SAUCE: Import aufs driver + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + - [Config] Enable aufs + - SAUCE: perf callchain: Include errno.h on x86 unconditinally + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc2 + + -- Seth Forshee Sun, 21 May 2017 23:44:44 -0500 + +linux (4.11.0-3.8) artful; urgency=low + + [ Seth Forshee ] + + * Release Tracking Bug + - LP: #1690999 + + * apparmor_parser hangs indefinitely when called by multiple threads + (LP: #1645037) + - SAUCE: apparmor: fix lock ordering for mkdir + + * apparmor leaking securityfs pin count (LP: #1660846) + - SAUCE: apparmor: fix leak on securityfs pin count + + * apparmor reference count leak when securityfs_setup_d_inode\ () fails + (LP: #1660845) + - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode() + fails + + * apparmor not checking error if security_pin_fs() fails (LP: #1660842) + - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails + + * libvirt profile is blocking global setrlimit despite having no rlimit rule + (LP: #1679704) + - SAUCE: apparmor: fix complain mode failure for rlimit mediation + - apparmor: update auditing of rlimit check to provide capability information + + * apparmor: does not provide a way to detect policy updataes (LP: #1678032) + - SAUCE: apparmor: add policy revision file interface + + * apparmor does not make support of query data visible (LP: #1678023) + - SAUCE: apparmor: add label data availability to the feature set + + * apparmor query interface does not make supported query info available + (LP: #1678030) + - SAUCE: apparmor: add information about the query inteface to the feature set + + * change_profile incorrect when using namespaces with a compound stack + (LP: #1677959) + - SAUCE: apparmor: fix label parse for stacked labels + + * Regression in 4.4.0-65-generic causes very frequent system crashes + (LP: #1669611) + - apparmor: sync of apparmor 3.6+ (17.04) + + * Artful update to 4.11.1 stable release (LP: #1690814) + - dm ioctl: prevent stack leak in dm ioctl call + - drm/sti: fix GDP size to support up to UHD resolution + - power: supply: lp8788: prevent out of bounds array access + - brcmfmac: Ensure pointer correctly set if skb data location changes + - brcmfmac: Make skb header writable before use + - sparc64: fix fault handling in NGbzero.S and GENbzero.S + - refcount: change EXPORT_SYMBOL markings + - net: macb: fix phy interrupt parsing + - tcp: fix access to sk->sk_state in tcp_poll() + - geneve: fix incorrect setting of UDP checksum flag + - bpf: enhance verifier to understand stack pointer arithmetic + - bpf, arm64: fix jit branch offset related to ldimm64 + - tcp: fix wraparound issue in tcp_lp + - net: ipv6: Do not duplicate DAD on link up + - net: usb: qmi_wwan: add Telit ME910 support + - tcp: do not inherit fastopen_req from parent + - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header + - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string + - ipv6: initialize route null entry in addrconf_init() + - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf + - tcp: randomize timestamps on syncookies + - bnxt_en: allocate enough space for ->ntp_fltr_bmap + - bpf: don't let ldimm64 leak map addresses on unprivileged + - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path + - f2fs: sanity check segment count + - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..." + - xen: Revert commits da72ff5bfcb0 and 72a9b186292d + - block: get rid of blk_integrity_revalidate() + - Linux 4.11.1 + + * Module signing exclusion for staging drivers does not work properly + (LP: #1690908) + - SAUCE: Fix module signing exclusion in package builds + + * perf: qcom: Add L3 cache PMU driver (LP: #1689856) + - [Config] CONFIG_QCOM_L3_PMU=y + - perf: qcom: Add L3 cache PMU driver + + * No PMU support for ACPI-based arm64 systems (LP: #1689661) + - drivers/perf: arm_pmu: rework per-cpu allocation + - drivers/perf: arm_pmu: manage interrupts per-cpu + - drivers/perf: arm_pmu: split irq request from enable + - drivers/perf: arm_pmu: remove pointless PMU disabling + - drivers/perf: arm_pmu: define armpmu_init_fn + - drivers/perf: arm_pmu: fold init into alloc + - drivers/perf: arm_pmu: factor out pmu registration + - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs() + - drivers/perf: arm_pmu: handle no platform_device + - drivers/perf: arm_pmu: rename irq request/free functions + - drivers/perf: arm_pmu: split cpu-local irq request/free + - drivers/perf: arm_pmu: move irq request/free into probe + - drivers/perf: arm_pmu: split out platform device probe logic + - arm64: add function to get a cpu's MADT GICC table + - [Config] CONFIG_ARM_PMU_ACPI=y + - drivers/perf: arm_pmu: add ACPI framework + - arm64: pmuv3: handle !PMUv3 when probing + - arm64: pmuv3: use arm_pmu ACPI framework + + * Fix NVLINK2 TCE route (LP: #1690155) + - powerpc/powernv: Fix TCE kill on NVLink2 + + * CVE-2017-0605 + - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline() + + * Miscellaneous Ubuntu changes + - [Config] Restore powerpc arch to annotations file + - [Config] Disable runtime testing modules + - [Config] Disable drivers not needed on s390x + - [Config] Update annotations for 4.11 + - [Config] updateconfigs after apparmor updates + + * Miscellaneous upstream changes + - apparmor: use SHASH_DESC_ON_STACK + - apparmor: fix invalid reference to index variable of iterator line 836 + - apparmor: fix parameters so that the permission test is bypassed at boot + - apparmor: Make path_max parameter readonly + - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show() + - apparmorfs: Use seq_putc() in two functions + - apparmor: provide information about path buffer size at boot + - apparmor: add/use fns to print hash string hex value + + -- Seth Forshee Tue, 16 May 2017 00:39:13 -0500 + +linux (4.11.0-2.7) artful; urgency=low + + * kernel-wedge fails in artful due to leftover squashfs-modules d-i files + (LP: #1688259) + - Remove squashfs-modules files from d-i + - [Config] as squashfs-modules is builtin kernel-image must Provides: it + + * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297) + - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform." + - d-i: initrd needs qcom_emac on amberwing platform. + + * update for V3 kernel bits and improved multiple fan slice support + (LP: #1470091) + - SAUCE: fan: tunnel multiple mapping mode (v3) + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5 + - Enable zfs + - SAUCE: fan: add VXLAN implementation + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Add EFI signature data types + - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader. + - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db + - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is + disabled + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Update dropped.txt + + [ Upstream Kernel Changes ] + + * rebase to v4.11 + + -- Seth Forshee Fri, 05 May 2017 07:43:14 -0500 + +linux (4.11.0-1.6) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Use default compression for all packages + - SAUCE: (namespace) block_dev: Support checking inode permissions in + lookup_bdev() + - SAUCE: (namespace) block_dev: Check permissions towards block device inode + when mounting + - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode + when mounting + - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes + - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root + - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb() + - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set + security.* xattrs + - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw + filesystems + - SAUCE: (namespace) fuse: Add support for pid namespaces + - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns + - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace + or a descendant + - SAUCE: (namespace) fuse: Allow user namespace mounts + - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user + namespaces + - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts + - SAUCE: (namespace) ext4: Add module parameter to enable user namespace + mounts + - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is + opened for writing + + -- Seth Forshee Wed, 26 Apr 2017 10:08:29 -0500 + +linux (4.11.0-0.5) artful; urgency=low + + * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain + (LP: #1684971) + - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain + + * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups + (LP: #1470250) + - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails + + * Enable virtual scsi server driver for Power (LP: #1615665) + - SAUCE: Return TCMU-generated sense data to fabric module + + * include/linux/security.h header syntax error with !CONFIG_SECURITYFS + (LP: #1630990) + - SAUCE: (no-up) include/linux/security.h -- fix syntax error with + CONFIG_SECURITYFS=n + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Debian] Add script to update virtualbox + - ubuntu: vbox -- Update to 5.1.20-dfsg-2 + - Enable vbox + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc8 + + -- Seth Forshee Tue, 25 Apr 2017 13:42:54 -0500 + +linux (4.11.0-0.4) zesty; urgency=low + + * POWER9: Improve performance on memory management (LP: #1681429) + - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm + flush + - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync + + * Miscellaneous Ubuntu changes + - find-missing-sauce.sh + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc7 + + -- Seth Forshee Tue, 18 Apr 2017 08:19:43 -0500 + +linux (4.11.0-0.3) zesty; urgency=low + + * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888) + - [Config] Disable CONFIG_HVC_UDBG on ppc64el + + * smartpqi driver needed in initram disk and installer (LP: #1680156) + - [Config] Add smartpqi to d-i + + * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315) + - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n + + * Miscellaneous Ubuntu changes + - [Config] flash-kernel should be a Breaks + - [Config] drop the info directory + - [Config] drop NOTES as obsolete + - [Config] drop changelog.historical as obsolete + - rebase to v4.11-rc6 + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc6 + + -- Tim Gardner Tue, 11 Apr 2017 07:16:52 -0600 + +linux (4.11.0-0.2) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc5 + + -- Tim Gardner Mon, 03 Apr 2017 08:26:07 +0100 + +linux (4.11.0-0.1) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc4 + - LP: #1591053 + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 + +linux (4.11.0-0.0) zesty; urgency=low + + * dummy entry + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 --- linux-oracle-5.4.0.orig/debian.master/config/README.rst +++ linux-oracle-5.4.0/debian.master/config/README.rst @@ -0,0 +1,185 @@ +================== +Config Annotations +================== + +:Author: Andrea Righi + +Overview +======== + +Each Ubuntu kernel needs to maintain its own .config for each supported +architecture and each flavour. + +Every time a new patch is applied or a kernel is rebased on top of a new +one, we need to update the .config's accordingly (config options can be +added, removed and also renamed). + +So, we need to make sure that some critical config options are always +matching the desired value in order to have a functional kernel. + +State of the art +================ + +At the moment configs are maintained as a set of Kconfig chunks (inside +`debian./config/`): a global one, plus per-arch / per-flavour +chunks. + +In addition to that, we need to maintain also a file called +'annotations'; the purpose of this file is to make sure that some +critical config options are not silently removed or changed when the +real .config is re-generated (for example after a rebase or after +applying a new set of patches). + +The main problem with this approach is that, often, we have duplicate +information that is stored both in the Kconfig chunks *and* in the +annotations files and, at the same time, the whole .config's information +is distributed between Kconfig chunks and annotations, making it hard to +maintain, review and manage in general. + +Proposed solution +================= + +The proposed solution is to store all the config information into the +"annotations" format and get rid of the config chunks (basically the +real .config's can be produced "compiling" annotations). + +Implementation +============== + +To help the management of the annotations an helper script is provided +(`debian/scripts/misc/annotations`): + +``` +usage: annotations [-h] [--version] [--file FILE] [--arch ARCH] [--flavour FLAVOUR] [--config CONFIG] + (--query | --export | --import FILE | --update FILE | --check FILE) + +Manage Ubuntu kernel .config and annotations + +options: + -h, --help show this help message and exit + --version, -v show program's version number and exit + --file FILE, -f FILE Pass annotations or .config file to be parsed + --arch ARCH, -a ARCH Select architecture + --flavour FLAVOUR, -l FLAVOUR + Select flavour (default is "generic") + --config CONFIG, -c CONFIG + Select a specific config option + +Action: + --query, -q Query annotations + --export, -e Convert annotations to .config format + --import FILE, -i FILE + Import a full .config for a specific arch and flavour into annotations + --update FILE, -u FILE + Import a partial .config into annotations (only resync configs specified in FILE) + --check FILE, -k FILE + Validate kernel .config with annotations +``` + +This script allows to query config settings (per arch/flavour/config), +export them into the Kconfig format (generating the real .config files) +and check if the final .config matches the rules defined in the +annotations. + +Examples (annotations is defined as an alias to `debian/scripts/annotations`): + + - Show settings for `CONFIG_DEBUG_INFO_BTF` for master kernel across all the + supported architectures and flavours: + +``` +$ annotations --query --config CONFIG_DEBUG_INFO_BTF +{ + "policy": { + "amd64": "y", + "arm64": "y", + "armhf": "n", + "ppc64el": "y", + "riscv64": "y", + "s390x": "y" + }, + "note": "'Needs newer pahole for armhf'" +} +``` + + - Dump kernel .config for arm64 and flavour generic-64k: + +``` +$ annotations --arch arm64 --flavour generic-64k --export +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_KERNEL=y +CONFIG_COMPAT=y +... +``` + + - Update annotations file with a new kernel .config for amd64 flavour + generic: + +``` +$ annotations --arch amd64 --flavour generic --import build/.config +``` + +Moreover, an additional kernelconfig commands are provided +(via debian/rules targets): + - `migrateconfigs`: automatically merge all the previous configs into + annotations (local changes still need to be committed) + +Annotations headers +=================== + +The main annotations file should contain a header to define the architectures +and flavours that are supported. + +Here is the format of the header for the generic kernel: +``` +# Menu: HEADER +# FORMAT: 4 +# ARCH: amd64 arm64 armhf ppc64el riscv64 s390x +# FLAVOUR: amd64-generic arm64-generic arm64-generic-64k armhf-generic armhf-generic-lpae ppc64el-generic riscv64-generic s390x-generic + +``` + +Example header of a derivative (linux-aws): +``` +# Menu: HEADER +# FORMAT: 4 +# ARCH: amd64 arm64 +# FLAVOUR: amd64-aws arm64-aws +# FLAVOUR_DEP: {'amd64-aws': 'amd64-generic', 'arm64-aws': 'arm64-generic'} + +include "../../debian.master/config/annotations" + +# Below you can define only the specific linux-aws configs that differ from linux generic + +``` + +Pros and Cons +============= + + Pros: + - avoid duplicate information in .config's and annotations + - allow to easily define groups of config settings (for a specific + environment or feature, such as annotations.clouds, annotations.ubuntu, + annotations.snapd, etc.) + - config options are more accessible, easy to change and review + - we can easily document how config options are managed (and external + contributors won't be discouraged anymore when they need to to change a + config option) + + Cons: + - potential regressions: the new tool/scripts can have potential bugs, + so we could experience regressions due to some missed config changes + - kernel team need to understand the new process (even if everything + is transparent, kernel cranking process is the same, there might be + corner cases that need to be addressed and resolved manually) + +TODO +==== + + - Migrate all flavour and arch definitions into annotations (rather + than having this information defined in multiple places inside + debian/scripts); right now this information is "partially" migrated, + meaning that we need to define arches and flavours in the headers + section of annotations (so that the annotations tool can figure out + the list of supported arches and flavours), but arches and flavours + are still defined elsewhere, ideally we would like to have arches and + flavours defined only in one place: annotations. --- linux-oracle-5.4.0.orig/debian.master/config/annotations +++ linux-oracle-5.4.0/debian.master/config/annotations @@ -0,0 +1,12865 @@ +# Menu: HEADER +# FORMAT: 4 +# ARCH: amd64 arm64 armhf i386 ppc64el s390x +# FLAVOUR: amd64-generic amd64-lowlatency arm64-generic armhf-generic armhf-generic-lpae i386-generic i386-lowlatency ppc64el-generic s390x-generic + +CONFIG_ACPI_CUSTOM_DSDT_FILE policy<{'amd64': '""', 'i386': '""'}> +CONFIG_ACPI_CUSTOM_DSDT_FILE note<'might allow hardware damage'> + +CONFIG_ACPI_CUSTOM_METHOD policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_ACPI_CUSTOM_METHOD note<'SECURITY: allows arbitrary execution'> + +CONFIG_AGP policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AGP note<'not autoloadable'> + +CONFIG_ARCH_ROCKCHIP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_ROCKCHIP note<'LP:1566283 / LP:1825222'> + +CONFIG_ARCH_TANGO policy<{'armhf': 'n'}> +CONFIG_ARCH_TANGO note<'LP:1787945'> + +CONFIG_ARCH_ZX policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_ARCH_ZX note<'LP:1628503'> + +CONFIG_ARM64_ERRATUM_843419 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_843419 note<'LP:1647793'> + +CONFIG_ARM64_ERRATUM_858921 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_858921 note<'LP#1675509'> + +CONFIG_ARM64_LSE_ATOMICS policy<{'arm64': 'y'}> +CONFIG_ARM64_LSE_ATOMICS note<'LP:1691614'> + +CONFIG_ARM64_VA_BITS_48 policy<{'arm64': 'y'}> +CONFIG_ARM64_VA_BITS_48 note<'Cavium ThunderX 2-socket needs a minimum of 41 bits of VA'> + +CONFIG_ARMV8_DEPRECATED policy<{'arm64': 'y'}> +CONFIG_ARMV8_DEPRECATED note<'LP:1545542'> + +CONFIG_ARM_HIGHBANK_CPUIDLE policy<{'armhf-generic': 'n', 'armhf-generic-lpae': 'y'}> +CONFIG_ARM_HIGHBANK_CPUIDLE note<'broken on ecx-1000'> + +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT policy<{'arm64': 'n'}> +CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT note<'LP:1845820'> + +CONFIG_ASYMMETRIC_KEY_TYPE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ASYMMETRIC_KEY_TYPE note<'module signing'> + +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE note<'module signing'> + +CONFIG_ATA_PIIX policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_ATA_PIIX note<'LP:1627324'> + +CONFIG_AUFS_EXPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUFS_EXPORT note<'LP:1121699'> + +CONFIG_BINFMT_SCRIPT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BINFMT_SCRIPT note<'required if init is a shell script such as in initramfs-tools'> + +CONFIG_BLK_DEV_DM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_DM note<'LP:#560717'> + +CONFIG_BLK_DEV_NVME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_NVME note<'LP:#1759893'> + +CONFIG_BLK_DEV_RAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_RAM note<'LP #1593293'> + +CONFIG_BLK_DEV_RAM_SIZE policy<{'amd64': '65536', 'arm64': '65536', 'armhf': '65536', 'i386': '65536', 'ppc64el': '65536', 's390x': '65536'}> +CONFIG_BLK_DEV_RAM_SIZE note<'Ramdisk size should be a minimum of 64M'> + +CONFIG_BLK_DEV_SD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_SD note<'LP:1627330'> + +CONFIG_BLK_DEV_SR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_SR note<'LP:1627330'> + +CONFIG_BLK_DEV_THROTTLING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_THROTTLING note<'CGROUP disk consumption control'> + +CONFIG_BLK_DEV_UMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_UMEM note<'experimental NVRAM disk driver -- opt-in'> + +CONFIG_BT_HS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BT_HS note<'https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00435.html'> + +CONFIG_CHR_DEV_SG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CHR_DEV_SG note<'not autoloadable'> + +CONFIG_CMA_SIZE_MBYTES policy<{'arm64': '32', 'armhf': '32'}> +CONFIG_CMA_SIZE_MBYTES note<'LP:1823753'> + +CONFIG_COMPAT_BRK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_COMPAT_BRK note<'disables brk ASLR'> + +CONFIG_CP15_BARRIER_EMULATION policy<{'arm64': 'y'}> +CONFIG_CP15_BARRIER_EMULATION note<'LP:1545542'> + +CONFIG_CPUFREQ_DT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CPUFREQ_DT note<'not autoloadable'> + +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE note<'for bootspeed'> + +CONFIG_CPU_FREQ_GOV_CONSERVATIVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_CONSERVATIVE note<'not autoloadable'> + +CONFIG_CPU_FREQ_GOV_ONDEMAND policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_ONDEMAND note<'not autoloadable'> + +CONFIG_CPU_FREQ_GOV_PERFORMANCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_PERFORMANCE note<'not autoloadable'> + +CONFIG_CPU_FREQ_GOV_POWERSAVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_POWERSAVE note<'not autoloadable'> + +CONFIG_CPU_FREQ_GOV_USERSPACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_USERSPACE note<'not autoloadable'> + +CONFIG_CPU_FREQ_STAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_STAT note<'dependancy of boot essential'> + +CONFIG_CRASH_DUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRASH_DUMP note<'LP:1363180'> + +CONFIG_CRYPTO_SHA512 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_SHA512 note<'module signing'> + +CONFIG_CS5535_MFGPT policy<{'i386': 'n'}> +CONFIG_CS5535_MFGPT note<'should be disabled by default'> + +CONFIG_DEBUG_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_FS note<'required debug option'> + +CONFIG_DEBUG_INFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_INFO note<'required for debug packages'> + +CONFIG_DEBUG_INFO_SPLIT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_INFO_SPLIT note<'LP:1413646 and LP:1413664'> + +CONFIG_DEBUG_KERNEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_KERNEL note<'required debug option'> + +CONFIG_DEFAULT_MMAP_MIN_ADDR policy<{'amd64': '65536', 'arm64': '32768', 'armhf': '32768', 'i386': '65536', 'ppc64el': '65536', 's390x': '65536'}> +CONFIG_DEFAULT_MMAP_MIN_ADDR note<'LP:1418140 LP:1531327'> + +CONFIG_DEVKMEM policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEVKMEM note<'/dev/kmem is a large attack vector'> + +CONFIG_DEVTMPFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEVTMPFS note<'upstart requirement'> + +CONFIG_DEVTMPFS_MOUNT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEVTMPFS_MOUNT note<'upstart requirement'> + +CONFIG_DMA_CMA policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'i386': 'n', 's390x': 'n'}> +CONFIG_DMA_CMA note<'LP:1803206'> + +CONFIG_DRM_AMDGPU_CIK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_AMDGPU_CIK note<'LP:1661887 for zesty'> + +CONFIG_DRM_BOCHS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_BOCHS note<'LP#1916290'> + +CONFIG_DRM_HISI_HIBMC policy<{'arm64': 'm'}> +CONFIG_DRM_HISI_HIBMC note<'LP:1762940'> + +CONFIG_DRM_LEGACY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DRM_LEGACY note<'Consider re-enabling but not signing the modules'> + +CONFIG_DRM_MGAG200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_MGAG200 note<'LP#1693337'> + +CONFIG_DRM_STI policy<{'armhf': 'n'}> +CONFIG_DRM_STI note<'LP#1398458'> + +CONFIG_DRM_VBOXVIDEO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DRM_VBOXVIDEO note<'LP:1718679'> + +CONFIG_DVB_DUMMY_FE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DUMMY_FE note<'expert use only'> + +CONFIG_ECRYPT_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ECRYPT_FS note<'not autoloadable'> + +CONFIG_EFIVAR_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFIVAR_FS note<'needed for variable EFI update'> + +CONFIG_EFI_VARS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFI_VARS note<'EFI boot requirement (d-i) LP:#837332'> + +CONFIG_EVM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EVM note<'LP:1643652'> + +CONFIG_EVM_ATTR_FSUUID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EVM_ATTR_FSUUID note<'LP:1643652'> + +CONFIG_EVM_LOAD_X509 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_EVM_LOAD_X509 note<'LP:1643652'> + +CONFIG_EVM_X509_PATH policy<{'ppc64el': '"/etc/keys/x509_evm.der"'}> +CONFIG_EVM_X509_PATH note<'LP:1643652'> + +CONFIG_EXT2_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_EXT2_FS note<'ext4 handling via EXT4_USE_FOR_EXT23'> + +CONFIG_EXT3_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_EXT3_FS note<'ext4 handling via EXT4_USE_FOR_EXT23'> + +CONFIG_FA_DUMP policy<{'ppc64el': 'y'}> +CONFIG_FA_DUMP note<'LP:1415562'> + +CONFIG_FHANDLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FHANDLE note<'LP:1412543'> + +CONFIG_FUSE_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FUSE_FS note<'not autoloadable'> + +CONFIG_FW_LOADER_USER_HELPER_FALLBACK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FW_LOADER_USER_HELPER_FALLBACK note<'LP#1398458'> + +CONFIG_GPIO_EM policy<{'armhf': 'n'}> +CONFIG_GPIO_EM note<'h/w not encounted'> + +CONFIG_GPIO_TWL4030 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_TWL4030 note<'LP:#921934'> + +CONFIG_HIBERNATION policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HIBERNATION note<'LP:1867753'> + +CONFIG_HIO policy<{'amd64': 'm', 'arm64': 'n', 'armhf': 'n', 'i386': 'm', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HIO note<'LP:1635594'> + +CONFIG_HIPPI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HIPPI note<'DEPRECATED'> + +CONFIG_HOTPLUG_PCI_PCIE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HOTPLUG_PCI_PCIE note<'LP#1374440'> + +CONFIG_HOTPLUG_PCI_SHPC policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HOTPLUG_PCI_SHPC note<'LP#1374440'> + +CONFIG_HVC_UDBG policy<{'ppc64el': 'n'}> +CONFIG_HVC_UDBG note<'LP#1680888'> + +CONFIG_I2C_CHARDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_I2C_CHARDEV note<'LP:1417032'> + +CONFIG_IBMVNIC policy<{'ppc64el': 'm'}> +CONFIG_IBMVNIC note<'LP:#1628187'> + +CONFIG_IDLE_PAGE_TRACKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IDLE_PAGE_TRACKING note<'is there a cost associated with this?'> + +CONFIG_IIO_SIMPLE_DUMMY_BUFFER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IIO_SIMPLE_DUMMY_BUFFER note<'dummy driver'> + +CONFIG_IIO_SIMPLE_DUMMY_EVENTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IIO_SIMPLE_DUMMY_EVENTS note<'dummy driver'> + +CONFIG_IMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IMA note<'LP:1643652'> + +CONFIG_IMA_APPRAISE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IMA_APPRAISE note<'LP:1643652'> + +CONFIG_IMA_ARCH_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_IMA_ARCH_POLICY note<'LP:1866909'> + +CONFIG_IMA_DEFAULT_HASH_SHA256 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_IMA_DEFAULT_HASH_SHA256 note<'LP:1643652'> + +CONFIG_IMA_KEXEC policy<{'ppc64el': 'y'}> +CONFIG_IMA_KEXEC note<'LP:1643652'> + +CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY note<'LP:1667490'> + +CONFIG_IMA_READ_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_IMA_READ_POLICY note<'LP:1866909'> + +CONFIG_IMA_SIG_TEMPLATE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_IMA_SIG_TEMPLATE note<'LP:1643652'> + +CONFIG_IMA_WRITE_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_WRITE_POLICY note<'LP:1667490'> + +CONFIG_INPUT_UINPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_INPUT_UINPUT note<'LP:584812'> + +CONFIG_INTEGRITY_PLATFORM_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEGRITY_PLATFORM_KEYRING note<'Required for lockdown'> + +CONFIG_INTEL_IOMMU_DEFAULT_ON policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_INTEL_IOMMU_DEFAULT_ON note<'the IOMMU can trigger boot failures'> + +CONFIG_IOMMU_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IOMMU_DEBUGFS note<'Should not be enabled in production, LP #1861057'> + +CONFIG_IPDDP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IPDDP note<'LP:1559772'> + +CONFIG_IPMMU_VMSA policy<{'arm64': 'n', 'armhf': 'y'}> +CONFIG_IPMMU_VMSA note<'LP:1718734'> + +CONFIG_IPV6 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6 note<'if this is a module we get a module load for every ipv6 packet'> + +CONFIG_IP_PNP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IP_PNP note<'LP:1259861'> + +CONFIG_ISM policy<{'s390x': 'm'}> +CONFIG_ISM note<'LP:1789934'> + +CONFIG_KEXEC_BZIMAGE_VERIFY_SIG policy<{'amd64': 'y'}> +CONFIG_KEXEC_BZIMAGE_VERIFY_SIG note<'Q: check this is in sync with the kexec/kdump userspace'> + +CONFIG_KGDB_SERIAL_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KGDB_SERIAL_CONSOLE note<'early debugging support'> + +CONFIG_KVM policy<{'amd64': 'm', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'm', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KVM note<'LP:1532886'> + +CONFIG_LATENCYTOP policy<{'amd64-generic': 'n', 'amd64-lowlatency': 'y', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LATENCYTOP note<'https://lists.ubuntu.com/archives/kernel-team/2014-July/045006.html, LP#1655986'> + +CONFIG_LOAD_PPC_KEYS policy<{'ppc64el': 'y'}> +CONFIG_LOAD_PPC_KEYS note<'LP:1866909'> + +CONFIG_LOCALVERSION_AUTO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOCALVERSION_AUTO note<'triggers packaging failures'> + +CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE note<'LP:1709171 LP:1848492'> + +CONFIG_MFD_SM501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_SM501 note<'boot essential on OMAP4'> + +CONFIG_MFD_TPS65217 policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'n'}> +CONFIG_MFD_TPS65217 note<'boot essential on AM335x'> + +CONFIG_MMC_BLOCK policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_BLOCK note<'boot essential on armhf/arm64'> + +CONFIG_MMC_OMAP_HS policy<{'armhf': 'y'}> +CONFIG_MMC_OMAP_HS note<'boot essential on arm'> + +CONFIG_MMC_SDHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI note<'installation essential on omap/highbank'> + +CONFIG_MMC_SDHCI_PLTFM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_PLTFM note<'boot essential on highbank'> + +CONFIG_MODIFY_LDT_SYSCALL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MODIFY_LDT_SYSCALL note<'Q: check this with security'> + +CONFIG_MODVERSIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODVERSIONS note<'LP:1898716 -- required as we have a livepatch/drivers modules signing key'> + +CONFIG_MOUSE_INPORT policy<{'i386': 'n'}> +CONFIG_MOUSE_INPORT note<'very old ISA based mouse support'> + +CONFIG_MTD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MTD note<'boot essential on arm'> + +CONFIG_MTD_BLOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_BLOCK note<'boot essential on arm'> + +CONFIG_MTD_DOCG3 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_DOCG3 note<'LP:1792205'> + +CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE note<'can be enabled at runtime'> + +CONFIG_MTD_NAND_OMAP2 policy<{'armhf': 'y'}> +CONFIG_MTD_NAND_OMAP2 note<'boot essential on arm'> + +CONFIG_MTD_NAND_OMAP_BCH policy<{'armhf': 'y'}> +CONFIG_MTD_NAND_OMAP_BCH note<'boot essential on arm'> + +CONFIG_MTD_OF_PARTS policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm'}> +CONFIG_MTD_OF_PARTS note<'boot essential on arm'> + +CONFIG_MTD_ONENAND_VERIFY_WRITE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_ONENAND_VERIFY_WRITE note<'writes here are not checked in full without'> + +CONFIG_MTD_RAW_NAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_RAW_NAND note<'boot essential on arm'> + +CONFIG_NETWORK_PHY_TIMESTAMPING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETWORK_PHY_TIMESTAMPING note<'LP:1785816'> + +CONFIG_NET_9P policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_9P note<'LP:1557994'> + +CONFIG_NET_DROP_MONITOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_DROP_MONITOR note<'LP #1660634'> + +CONFIG_NET_SWITCHDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_SWITCHDEV note<'LP: #1865452, updated to y for s390x starting with focal'> + +CONFIG_NET_VENDOR_EMULEX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_EMULEX note<'LP:1543165'> + +CONFIG_NLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NLS note<'dependancy of boot essential'> + +CONFIG_NOP_USB_XCEIV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NOP_USB_XCEIV note<'boot essential on omap/highbank'> + +CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT note<'Selects CONFIG_DRM_LEGACY which is not wanted'> + +CONFIG_NO_HZ_IDLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NO_HZ_IDLE note<'LP:1413968'> + +CONFIG_NR_CPUS policy<{'amd64': '8192', 'arm64': '256', 'armhf': '4', 'i386': '8', 'ppc64el': '2048', 's390x': '512'}> +CONFIG_NR_CPUS note<'LP:1864198'> + +CONFIG_NUMA policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NUMA note<'LP:1543165 LP:1557690'> + +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NUMA_BALANCING_DEFAULT_ENABLED note<'LP:1557690'> + +CONFIG_NUMA_EMU policy<{'amd64': 'n', 's390x': 'n'}> +CONFIG_NUMA_EMU note<'LP:1864198'> + +CONFIG_NVMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NVMEM note<'Q: is this appropriate for s390x LP:1543165'> + +CONFIG_NVRAM policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'y'}> +CONFIG_NVRAM note<'LP#1837726'> + +CONFIG_N_GSM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_N_GSM note<'LP#1404670'> + +CONFIG_PAGE_POISONING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_POISONING note<'LP:1783651'> + +CONFIG_PAGE_POISONING_NO_SANITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_POISONING_NO_SANITY note<'LP:1783651'> + +CONFIG_PAGE_POISONING_ZERO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_POISONING_ZERO note<'LP:1783651'> + +CONFIG_PANIC_ON_OOPS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PANIC_ON_OOPS note<'keep working if at all possible'> + +CONFIG_PATA_HPT3X3_DMA policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PATA_HPT3X3_DMA note<'DMA mode is documented problematic'> + +CONFIG_PCIEASPM_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_PCIEASPM_DEFAULT note<'LP#1398544'> + +CONFIG_PCIEPORTBUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_PCIEPORTBUS note<'LP#1665404'> + +CONFIG_PCI_NR_FUNCTIONS policy<{'s390x': '512'}> +CONFIG_PCI_NR_FUNCTIONS note<'LP:1866056'> + +CONFIG_PINCTRL_CHERRYVIEW policy<{'amd64': 'y', 'i386': 'm'}> +CONFIG_PINCTRL_CHERRYVIEW note<'LP #1630238'> + +CONFIG_PM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PM note<'LP:1867753'> + +CONFIG_PPC_MEM_KEYS policy<{'ppc64el': 'n'}> +CONFIG_PPC_MEM_KEYS note<'LP:1776967'> + +CONFIG_PPC_RTAS_FILTER policy<{'ppc64el': 'y'}> +CONFIG_PPC_RTAS_FILTER note<'CVE-2020-27777'> + +CONFIG_PPC_SECURE_BOOT policy<{'ppc64el': 'y'}> +CONFIG_PPC_SECURE_BOOT note<'LP:1855668'> + +CONFIG_PPC_SECVAR_SYSFS policy<{'ppc64el': 'y'}> +CONFIG_PPC_SECVAR_SYSFS note<'LP:1866909'> + +CONFIG_PREEMPT_NONE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_PREEMPT_NONE note<'LP:1543165'> + +CONFIG_PSI_DEFAULT_DISABLED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_PSI_DEFAULT_DISABLED note<'LP: #1876044'> + +CONFIG_QCOM_QDF2400_ERRATUM_0065 policy<{'arm64': 'y'}> +CONFIG_QCOM_QDF2400_ERRATUM_0065 note<'LP:1672486'> + +CONFIG_REGULATOR_FIXED_VOLTAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_FIXED_VOLTAGE note<'boot essential on arm'> + +CONFIG_REGULATOR_TPS65217 policy<{'arm64': 'm', 'armhf': 'y'}> +CONFIG_REGULATOR_TPS65217 note<'boot essential on AM335x'> + +CONFIG_REGULATOR_TWL4030 policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TWL4030 note<'boot requisite for omap4'> + +CONFIG_RTC_DRV_CMOS policy<{'amd64': 'y', 'armhf': 'm', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_CMOS note<'boot essential on i386/amd64'> + +CONFIG_RTC_DRV_EFI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RTC_DRV_EFI note<'LP:#1583738'> + +CONFIG_RTC_DRV_TWL4030 policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_TWL4030 note<'boot essential on OMAP3/OMAP4'> + +CONFIG_RT_GROUP_SCHED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RT_GROUP_SCHED note<'LP#1875665'> + +CONFIG_SAMPLE_TRACE_PRINTK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SAMPLE_TRACE_PRINTK note<'Required for ftrace selftests'> + +CONFIG_SATA_AHCI_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_AHCI_PLATFORM note<'boot essential on highbank'> + +CONFIG_SATA_HIGHBANK policy<{'armhf': 'y'}> +CONFIG_SATA_HIGHBANK note<'LP:1703430'> + +CONFIG_SCLP_OFB policy<{'s390x': 'y'}> +CONFIG_SCLP_OFB note<'LP:1787898'> + +CONFIG_SCSI_IPR_DUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SCSI_IPR_DUMP note<'LP:1343109'> + +CONFIG_SCSI_IPR_TRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SCSI_IPR_TRACE note<'LP:1343109'> + +CONFIG_SCSI_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_VIRTIO note<'tech preview of new feature'> + +CONFIG_SECURITY_SAFESETID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SAFESETID note<'LP:#1845391'> + +CONFIG_SECURITY_SELINUX_DISABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_SELINUX_DISABLE note<'LP#1680315'> + +CONFIG_SERIAL_DEV_BUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SERIAL_DEV_BUS note<'LP:1739939'> + +CONFIG_SERIAL_DEV_CTRL_TTYPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SERIAL_DEV_CTRL_TTYPORT note<'LP:1739939'> + +CONFIG_SERIAL_SH_SCI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_SH_SCI note<'LP: #2022361'> + +CONFIG_SERIAL_SH_SCI_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_SH_SCI_CONSOLE note<'LP: #2022361'> + +CONFIG_SERIAL_SH_SCI_EARLYCON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_SH_SCI_EARLYCON note<'LP: #2022361'> + +CONFIG_SETEND_EMULATION policy<{'arm64': 'y'}> +CONFIG_SETEND_EMULATION note<'LP:1545542'> + +CONFIG_SMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SMC note<'LP:1789934'> + +CONFIG_SMC_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SMC_DIAG note<'LP:1789934'> + +CONFIG_SND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND note<'not autoloadable on omap'> + +CONFIG_SND_HDA_POWER_SAVE_DEFAULT policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1'}> +CONFIG_SND_HDA_POWER_SAVE_DEFAULT note<'LP:1804265'> + +CONFIG_SND_HDA_RECONFIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_RECONFIG note<'allows fixes to be tested live'> + +CONFIG_SND_PCM_OSS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_PCM_OSS note<'deprecated in favour of pulseaudio emulation'> + +CONFIG_SND_SOC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC note<'not autoloadable on omap'> + +CONFIG_SND_SOC_AMD_RENOIR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_AMD_RENOIR note<'LP:1881046'> + +CONFIG_SND_SOC_AMD_RENOIR_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_AMD_RENOIR_MACH note<'LP:1881046'> + +CONFIG_SND_SOC_INTEL_CFL policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_CFL note<'deprecated'> + +CONFIG_SND_SOC_INTEL_CML_H policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_CML_H note<'deprecated'> + +CONFIG_SND_SOC_INTEL_CML_LP policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_CML_LP note<'deprecated'> + +CONFIG_SND_SOC_INTEL_CNL policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_CNL note<'deprecated'> + +CONFIG_SND_SOC_INTEL_SKYLAKE policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_SKYLAKE note<'deprecated'> + +CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC note<'deprecated'> + +CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC note<'LP:1848490'> + +CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC note<'LP:#1855666'> + +CONFIG_SND_SOC_SOF_HDA_LINK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_HDA_LINK note<'LP:1848490'> + +CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_SOC_SOF_NOCODEC_SUPPORT note<'LP:1848490'> + +CONFIG_SOUND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SOUND note<'not autoloadable on omap'> + +CONFIG_SOUNDWIRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SOUNDWIRE note<'LP:1855685'> + +CONFIG_SOUND_OSS_CORE_PRECLAIM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SOUND_OSS_CORE_PRECLAIM note<'LP#1105230 LP#1385510'> + +CONFIG_SPI_INTEL_SPI_PCI policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SPI_INTEL_SPI_PCI note<'LP:1734147'> + +CONFIG_SPI_INTEL_SPI_PLATFORM policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SPI_INTEL_SPI_PLATFORM note<'LP:1734147'> + +CONFIG_SQUASHFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS note<'LP#1593134'> + +CONFIG_SQUASHFS_4K_DEVBLK_SIZE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SQUASHFS_4K_DEVBLK_SIZE note<'non-default block size'> + +CONFIG_STACK_VALIDATION policy<{'amd64': 'y'}> +CONFIG_STACK_VALIDATION note<'needed for livepatch'> + +CONFIG_SWP_EMULATION policy<{'arm64': 'y'}> +CONFIG_SWP_EMULATION note<'LP:1545542'> + +CONFIG_SYSFS_DEPRECATED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SYSFS_DEPRECATED note<'ensure nothing is using these deprecated interfaces'> + +CONFIG_TCG_TIS_I2C_ATMEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_TCG_TIS_I2C_ATMEL note<'LP:1643652'> + +CONFIG_TCG_TIS_I2C_INFINEON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_TCG_TIS_I2C_INFINEON note<'LP:1643652'> + +CONFIG_TCG_TIS_I2C_NUVOTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_TCG_TIS_I2C_NUVOTON note<'LP:1643652'> + +CONFIG_TCG_TPM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TCG_TPM note<'needed for early validation'> + +CONFIG_TEST_BLACKHOLE_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TEST_BLACKHOLE_DEV note<'Used by net selftests'> + +CONFIG_TMPFS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TMPFS_POSIX_ACL note<'some /dev nodes require POSIX ACLs, like /dev/dsp'> + +CONFIG_TOUCHSCREEN_ELAN policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ELAN note<'LP #1630238'> + +CONFIG_UNWINDER_FRAME_POINTER policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_UNWINDER_FRAME_POINTER note<'needed for livepatch'> + +CONFIG_USB_EHCI_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EHCI_HCD note<'ensures USB 2.0/1.1 probe ordering'> + +CONFIG_USB_EHCI_HCD_PLATFORM policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'n', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_USB_EHCI_HCD_PLATFORM note<'Dont use the generic ehci/ohci code on omap, it doesnt work'> + +CONFIG_USB_HCD_BCMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'n', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HCD_BCMA note<'USB_{O,E}HCI_HCD_PLATFORM must be off on omap'> + +CONFIG_USB_HCD_SSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'n', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HCD_SSB note<'USB_{O,E}HCI_HCD_PLATFORM must be off on omap'> + +CONFIG_USB_M66592 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_M66592 note<'gadget device'> + +CONFIG_USB_MUSB_HDRC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MUSB_HDRC note<'not autoloadable on omap'> + +CONFIG_USB_OHCI_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_OHCI_HCD note<'ensures USB 2.0/1.1 probe ordering'> + +CONFIG_USB_OTG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_OTG note<'triggers breakage on x86 LP:1047527, LP:1411295'> + +CONFIG_USB_OTG_BLACKLIST_HUB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_OTG_BLACKLIST_HUB note<'OTG white/blacklists are disabled'> + +CONFIG_USB_OTG_WHITELIST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_OTG_WHITELIST note<'OTG white/blacklists are disabled'> + +CONFIG_USB_SERIAL_DEBUG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_DEBUG note<'not actually debug'> + +CONFIG_USB_UHCI_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_UHCI_HCD note<'ensures USB 2.0/1.1 probe ordering'> + +CONFIG_USB_XHCI_DBGCAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_XHCI_DBGCAP note<'LP:1730832'> + +CONFIG_USB_XHCI_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_XHCI_HCD note<'ensures USB 2.0/1.1 probe ordering'> + +CONFIG_VBOXGUEST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_VBOXGUEST note<'LP:1796647'> + +CONFIG_VFAT_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VFAT_FS note<'needed on arm to ensure we can write the kernel when replacing'> + +CONFIG_VFIO policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_VFIO note<'LP#1636733'> + +CONFIG_VFIO_PCI policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_VFIO_PCI note<'LP#1636733'> + +CONFIG_VIDEO_VIMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VIMC note<'LP#1831482'> + +CONFIG_VIRTIO_BLK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTIO_BLK note<'KVM paravirt support -- not autoloadable'> + +CONFIG_VIRTIO_MMIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_VIRTIO_MMIO note<'LP:1557689'> + +CONFIG_VIRTIO_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTIO_NET note<'KVM paravirt support -- not autoloadable'> + +CONFIG_X509_CERTIFICATE_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_X509_CERTIFICATE_PARSER note<'module signing'> + +CONFIG_X86_ACPI_CPUFREQ policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_ACPI_CPUFREQ note<'not autoloadable'> + +CONFIG_X86_CPUFREQ_NFORCE2 policy<{'i386': 'y'}> +CONFIG_X86_CPUFREQ_NFORCE2 note<'not autoloadable'> + +CONFIG_X86_LEGACY_VM86 policy<{'i386': 'y'}> +CONFIG_X86_LEGACY_VM86 note<'LP:1499089'> + +CONFIG_X86_PCC_CPUFREQ policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_PCC_CPUFREQ note<'not autoloadable'> + +CONFIG_X86_POWERNOW_K8 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_POWERNOW_K8 note<'not autoloadable'> + +CONFIG_X86_SPEEDSTEP_CENTRINO policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_CENTRINO note<'not autoloadable'> + +CONFIG_X86_SPEEDSTEP_ICH policy<{'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_ICH note<'not autoloadable'> + +CONFIG_X86_SPEEDSTEP_SMI policy<{'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_SMI note<'not autoloadable'> + +CONFIG_X86_UV policy<{'amd64': 'y'}> +CONFIG_X86_UV note<'LP:1863810'> + +CONFIG_XEN_512GB policy<{'amd64': 'y'}> +CONFIG_XEN_512GB note<'Q: is this related to the utlemming questions on memory size?'> + +CONFIG_XEN_ACPI_PROCESSOR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_ACPI_PROCESSOR note<'boot essential on XEN host'> + +CONFIG_XEN_BLKDEV_FRONTEND policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_BLKDEV_FRONTEND note<'not autoloadable -- XEN paravirt support'> + +CONFIG_XEN_NETDEV_FRONTEND policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_NETDEV_FRONTEND note<'not autoloadable -- XEN paravirt support'> + +CONFIG_XZ_DEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XZ_DEC note<'boot essential -- initramfs decompressor'> + +CONFIG_ZCRYPT_MULTIDEVNODES policy<{'s390x': 'y'}> +CONFIG_ZCRYPT_MULTIDEVNODES note<'LP:1805429'> + +CONFIG_ZLIB_DFLTCC policy<{'s390x': 'y'}> +CONFIG_ZLIB_DFLTCC note<'LP:1830208'> + +CONFIG_ZONE_DMA policy<{'amd64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ZONE_DMA note<'LP:1628523'> + + +# ---- Annotations without notes ---- + +CONFIG_104_QUAD_8 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_3C515 policy<{'i386': 'm'}> +CONFIG_60XX_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_64BIT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_64BIT_TIME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_6LOWPAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_6LOWPAN_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_EXT_HDR_DEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_EXT_HDR_HOP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_ICMPV6 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_GHC_UDP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_6LOWPAN_NHC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_DEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_FRAGMENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_HOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_MOBILITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_ROUTING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6LOWPAN_NHC_UDP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_6PACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_8139CP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_8139TOO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_8139TOO_8129 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_8139TOO_PIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_8139TOO_TUNE_TWISTER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_8139_OLD_RX_RESET policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_842_COMPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_842_DECOMPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_88EU_AP_MODE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_9P_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_9P_FSCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_9P_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_9P_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AB3100_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AB3100_OTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ABP060MG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ABX500_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_AC97_BUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ACCESSIBILITY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ACENIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ACENIC_OMIT_TIGON_I policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ACERHDF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACER_WIRELESS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACER_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACORN_PARTITION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_AC policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_ADXL policy<{'amd64': 'y'}> +CONFIG_ACPI_ALS policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_APEI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_APEI_EINJ policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_APEI_ERST_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_ACPI_APEI_GHES policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_APEI_MEMORY_FAILURE policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_APEI_PCIEAER policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_APEI_SEA policy<{'arm64': 'y'}> +CONFIG_ACPI_BATTERY policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_BGRT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_BUTTON policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_CCA_REQUIRED policy<{'arm64': 'y'}> +CONFIG_ACPI_CMPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_CONFIGFS policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_CONTAINER policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_CPPC_CPUFREQ policy<{'arm64': 'm'}> +CONFIG_ACPI_CPPC_LIB policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_CPU_FREQ_PSS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_DEBUG policy<{'amd64': 'y', 'arm64': 'n', 'i386': 'n'}> +CONFIG_ACPI_DEBUGGER policy<{'amd64': 'y', 'arm64': 'n', 'i386': 'n'}> +CONFIG_ACPI_DEBUGGER_USER policy<{'amd64': 'y'}> +CONFIG_ACPI_DOCK policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_EC_DEBUGFS policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_EXTLOG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_FAN policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_GENERIC_GSI policy<{'arm64': 'y'}> +CONFIG_ACPI_GTDT policy<{'arm64': 'y'}> +CONFIG_ACPI_HED policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_HMAT policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_HOTPLUG_CPU policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_HOTPLUG_IOAPIC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_HOTPLUG_MEMORY policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_I2C_OPREGION policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_IORT policy<{'arm64': 'y'}> +CONFIG_ACPI_IPMI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_LEGACY_TABLES_LOOKUP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_LPIT policy<{'amd64': 'y'}> +CONFIG_ACPI_MCFG policy<{'arm64': 'y'}> +CONFIG_ACPI_NFIT policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ACPI_NUMA policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_PCI_SLOT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_PPTT policy<{'arm64': 'y'}> +CONFIG_ACPI_PROCESSOR policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_PROCESSOR_AGGREGATOR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_PROCESSOR_CSTATE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_PROCESSOR_IDLE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_PROCFS_POWER policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_ACPI_REDUCED_HARDWARE_ONLY policy<{'amd64': 'n', 'arm64': 'y', 'i386': 'n'}> +CONFIG_ACPI_REV_OVERRIDE_POSSIBLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_SBS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_SLEEP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_SPCR_TABLE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ACPI_TABLE_UPGRADE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_TAD policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ACPI_THERMAL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_THERMAL_REL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_TOSHIBA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_VIDEO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACPI_WATCHDOG policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ACPI_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACQUIRE_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ACRN_GUEST policy<{'amd64': 'y'}> +CONFIG_AD2S1200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD2S1210 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD2S90 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5064 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD525X_DPOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_AD525X_DPOT_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD525X_DPOT_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5272 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5360 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5380 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5421 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5446 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5449 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5504 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5592R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5592R_BASE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5593R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5624R_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5686 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5686_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5696_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5755 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5758 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5761 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5764 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5791 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD5933 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7124 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7192 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7266 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7280 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7291 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7298 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7303 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7476 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7606 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7606_IFACE_PARALLEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7606_IFACE_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7746 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7766 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7768_1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7780 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7791 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7793 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7816 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7887 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7923 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD7949 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD799X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD8366 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD8801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD9523 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD9832 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD9834 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADAPTEC_STARFIRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADE7854 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADE7854_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADE7854_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADF4350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADF4371 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ADFS_FS_RW policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ADIN_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ADIS16080 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16130 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16136 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16203 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16209 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16240 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16260 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16400 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16460 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADIS16480 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADJD_S311 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADM8211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADT7316 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADT7316_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADT7316_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADVANTECH_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ADVISE_SYSCALLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ADXL372 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADXL372_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADXL372_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ADXRS450 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AD_SIGMA_DELTA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AEABI policy<{'armhf': 'y'}> +CONFIG_AFE4403 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AFE4404 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AFFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_AFIUCV policy<{'s390x': 'm'}> +CONFIG_AFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AFS_DEBUG_CURSOR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AFS_FSCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AF_KCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AF_RXRPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AF_RXRPC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AF_RXRPC_INJECT_LOSS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AF_RXRPC_IPV6 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AGP_ALI policy<{'i386': 'm'}> +CONFIG_AGP_AMD policy<{'i386': 'y'}> +CONFIG_AGP_AMD64 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_AGP_ATI policy<{'i386': 'm'}> +CONFIG_AGP_EFFICEON policy<{'i386': 'm'}> +CONFIG_AGP_INTEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_AGP_NVIDIA policy<{'i386': 'y'}> +CONFIG_AGP_SIS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_AGP_SWORKS policy<{'i386': 'm'}> +CONFIG_AGP_VIA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_AHC1EC0_WDT policy<{'amd64': 'm'}> +CONFIG_AHCI_BRCM policy<{'arm64': 'm'}> +CONFIG_AHCI_CEVA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_AHCI_DM816 policy<{'armhf': 'm'}> +CONFIG_AHCI_IMX policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_AHCI_MTK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_AHCI_MVEBU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_AHCI_QORIQ policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_AHCI_SUNXI policy<{'arm64': 'n'}> +CONFIG_AHCI_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_AHCI_XGENE policy<{'arm64': 'm'}> +CONFIG_AIC79XX_CMDS_PER_DEVICE policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32'}> +CONFIG_AIC79XX_DEBUG_ENABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_AIC79XX_DEBUG_MASK policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_AIC79XX_REG_PRETTY_PRINT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AIC79XX_RESET_DELAY_MS policy<{'amd64': '5000', 'arm64': '5000', 'armhf': '5000', 'i386': '5000', 'ppc64el': '5000'}> +CONFIG_AIC7XXX_CMDS_PER_DEVICE policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_AIC7XXX_DEBUG_ENABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_AIC7XXX_DEBUG_MASK policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_AIC7XXX_REG_PRETTY_PRINT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AIC7XXX_RESET_DELAY_MS policy<{'amd64': '5000', 'arm64': '5000', 'armhf': '5000', 'i386': '5000', 'ppc64el': '5000'}> +CONFIG_AIC94XX_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_AIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AIRO policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AIRO_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_AIX_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_AK09911 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AK8974 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_AK8975 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AL3320A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ALIENWARE_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ALIGNMENT_TRAP policy<{'armhf': 'y'}> +CONFIG_ALIM1535_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ALIM7101_WDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ALIX policy<{'i386': 'y'}> +CONFIG_ALLOW_DEV_COREDUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ALPINE_MSI policy<{'armhf': 'y'}> +CONFIG_ALTERA_FREEZE_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ALTERA_MBOX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ALTERA_MSGDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ALTERA_PR_IP_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ALTERA_PR_IP_CORE_PLAT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_ALTERA_STAPL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ALTERA_TSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ALTIVEC policy<{'ppc64el': 'y'}> +CONFIG_ALX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AL_FIC policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_AM2315 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AM335X_CONTROL_USB policy<{'armhf': 'm'}> +CONFIG_AM335X_PHY_USB policy<{'armhf': 'm'}> +CONFIG_AMBA_PL08X policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_AMD8111_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AMD_IOMMU policy<{'amd64': 'y'}> +CONFIG_AMD_IOMMU_V2 policy<{'amd64': 'm'}> +CONFIG_AMD_MEM_ENCRYPT policy<{'amd64': 'y'}> +CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT policy<{'amd64': 'n'}> +CONFIG_AMD_NB policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_AMD_NUMA policy<{'amd64': 'y'}> +CONFIG_AMD_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AMD_XGBE policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_AMD_XGBE_DCB policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_AMD_XGBE_HAVE_ECC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_AMIGA_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_AMILO_RFKILL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ANDROID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_ANDROID_BINDERFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ANDROID_BINDER_DEVICES policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""'}> +CONFIG_ANDROID_BINDER_IPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ANDROID_BINDER_IPC_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ANDROID_VSOC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_APB_TIMER policy<{'i386': 'y'}> +CONFIG_APDS9300 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_APDS9802ALS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_APDS9960 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_APM policy<{'i386': 'm'}> +CONFIG_APM_ALLOW_INTS policy<{'i386': 'n'}> +CONFIG_APM_CPU_IDLE policy<{'i386': 'n'}> +CONFIG_APM_DISPLAY_BLANK policy<{'i386': 'n'}> +CONFIG_APM_DO_ENABLE policy<{'i386': 'n'}> +CONFIG_APM_EMULATION policy<{'armhf': 'n'}> +CONFIG_APM_IGNORE_USER_SUSPEND policy<{'i386': 'n'}> +CONFIG_APPLDATA_BASE policy<{'s390x': 'y'}> +CONFIG_APPLDATA_MEM policy<{'s390x': 'm'}> +CONFIG_APPLDATA_NET_SUM policy<{'s390x': 'm'}> +CONFIG_APPLDATA_OS policy<{'s390x': 'm'}> +CONFIG_APPLE_GMUX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_APPLE_PROPERTIES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_APPLICOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_APQ_GCC_8084 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_APQ_MMCC_8084 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_AQTION policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_AQUANTIA_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AR5523 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCH_32BIT_OFF_T policy<{'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_ACTIONS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_AGILEX policy<{'arm64': 'y'}> +CONFIG_ARCH_ALPINE policy<{'arm64': 'n', 'armhf': 'y'}> +CONFIG_ARCH_ARTPEC policy<{'armhf': 'y'}> +CONFIG_ARCH_ASPEED policy<{'armhf': 'y'}> +CONFIG_ARCH_AT91 policy<{'armhf': 'n'}> +CONFIG_ARCH_AXXIA policy<{'armhf-generic-lpae': 'y'}> +CONFIG_ARCH_BCM policy<{'armhf': 'n'}> +CONFIG_ARCH_BCM2835 policy<{'arm64': 'y'}> +CONFIG_ARCH_BCM_IPROC policy<{'arm64': 'y'}> +CONFIG_ARCH_BERLIN policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_BINFMT_ELF_STATE policy<{'s390x': 'y'}> +CONFIG_ARCH_BITMAIN policy<{'arm64': 'y'}> +CONFIG_ARCH_BRCMSTB policy<{'arm64': 'y'}> +CONFIG_ARCH_CLOCKSOURCE_DATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_CLOCKSOURCE_INIT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_CPUIDLE_HALTPOLL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_CPU_PROBE_RELEASE policy<{'ppc64el': 'y'}> +CONFIG_ARCH_DEFCONFIG policy<{'amd64': '"arch/x86/configs/x86_64_defconfig"', 'i386': '"arch/x86/configs/i386_defconfig"'}> +CONFIG_ARCH_DIGICOLOR policy<{'armhf': 'n'}> +CONFIG_ARCH_DMA_ADDR_T_64BIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_DOVE policy<{'armhf': 'n'}> +CONFIG_ARCH_EBSA110 policy<{'armhf': 'n'}> +CONFIG_ARCH_EMEV2 policy<{'armhf': 'y'}> +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_ENABLE_THP_MIGRATION policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_EP93XX policy<{'armhf': 'n'}> +CONFIG_ARCH_EXYNOS policy<{'arm64': 'n', 'armhf': 'y'}> +CONFIG_ARCH_EXYNOS3 policy<{'armhf': 'n'}> +CONFIG_ARCH_EXYNOS4 policy<{'armhf': 'n'}> +CONFIG_ARCH_EXYNOS5 policy<{'armhf': 'y'}> +CONFIG_ARCH_FLATMEM_ENABLE policy<{'i386': 'y'}> +CONFIG_ARCH_FOOTBRIDGE policy<{'armhf': 'n'}> +CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_ADD_PAGES policy<{'amd64': 'y'}> +CONFIG_ARCH_HAS_BANDGAP policy<{'armhf': 'y'}> +CONFIG_ARCH_HAS_BINFMT_FLAT policy<{'armhf': 'y'}> +CONFIG_ARCH_HAS_CACHE_LINE_SIZE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_CPU_FINALIZE_INIT policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_CPU_RELAX policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_DEBUG_VIRTUAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN policy<{'arm64': 'y', 'armhf-generic-lpae': 'y'}> +CONFIG_ARCH_HAS_DMA_PREP_COHERENT policy<{'arm64': 'y'}> +CONFIG_ARCH_HAS_ELF_RANDOMIZE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_FAST_MULTIPLIER policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_FILTER_PGPROT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_FORTIFY_SOURCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_GIGANTIC_PAGE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_HUGEPD policy<{'ppc64el': 'y'}> +CONFIG_ARCH_HAS_KCOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_KEEPINITRD policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_HAS_KEXEC_PURGATORY policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS policy<{'ppc64el': 'y'}> +CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_MEM_ENCRYPT policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_MMIOWB policy<{'ppc64el': 'y'}> +CONFIG_ARCH_HAS_PHYS_TO_DMA policy<{'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_PKEYS policy<{'amd64': 'y'}> +CONFIG_ARCH_HAS_PMEM_API policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_PTE_DEVMAP policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_PTE_SPECIAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_RELR policy<{'arm64': 'y'}> +CONFIG_ARCH_HAS_RESET_CONTROLLER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_HAS_SCALED_CPUTIME policy<{'s390x': 'y'}> +CONFIG_ARCH_HAS_SETUP_DMA_OPS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_HAS_SET_DIRECT_MAP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_SET_MEMORY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_STRICT_MODULE_RWX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU policy<{'arm64': 'y', 'armhf-generic-lpae': 'y'}> +CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE policy<{'arm64': 'y', 'armhf-generic-lpae': 'y'}> +CONFIG_ARCH_HAS_SYSCALL_WRAPPER policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_HAS_TICK_BROADCAST policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_UACCESS_MCSAFE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H policy<{'armhf': 'y'}> +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HI3xxx policy<{'armhf': 'y'}> +CONFIG_ARCH_HIBERNATION_HEADER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_HIBERNATION_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_HIGHBANK policy<{'armhf': 'y'}> +CONFIG_ARCH_HIP01 policy<{'armhf': 'n'}> +CONFIG_ARCH_HIP04 policy<{'armhf': 'y'}> +CONFIG_ARCH_HISI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_HIX5HD2 policy<{'armhf': 'y'}> +CONFIG_ARCH_INLINE_READ_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_TRYLOCK policy<{'s390x': 'y'}> +CONFIG_ARCH_INLINE_READ_UNLOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_TRYLOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_UNLOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_TRYLOCK policy<{'s390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_UNLOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_ARCH_IOP32X policy<{'armhf': 'n'}> +CONFIG_ARCH_IXP4XX policy<{'armhf': 'n'}> +CONFIG_ARCH_K3 policy<{'arm64': 'y'}> +CONFIG_ARCH_K3_AM6_SOC policy<{'arm64': 'y'}> +CONFIG_ARCH_K3_J721E_SOC policy<{'arm64': 'y'}> +CONFIG_ARCH_KEEP_MEMBLOCK policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_KEYSTONE policy<{'armhf': 'n'}> +CONFIG_ARCH_LAYERSCAPE policy<{'arm64': 'y'}> +CONFIG_ARCH_LG1K policy<{'arm64': 'y'}> +CONFIG_ARCH_MAY_HAVE_PC_FDC policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_MDM9615 policy<{'armhf': 'y'}> +CONFIG_ARCH_MEDIATEK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_MEMORY_PROBE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_MESON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_MILBEAUT policy<{'armhf': 'y'}> +CONFIG_ARCH_MILBEAUT_M10V policy<{'armhf': 'y'}> +CONFIG_ARCH_MMAP_RND_BITS policy<{'amd64': '28', 'arm64': '18', 'armhf': '8', 'i386': '8', 'ppc64el': '28'}> +CONFIG_ARCH_MMAP_RND_BITS_MAX policy<{'amd64': '32', 'arm64': '33', 'armhf': '16', 'i386': '16', 'ppc64el': '29'}> +CONFIG_ARCH_MMAP_RND_BITS_MIN policy<{'amd64': '28', 'arm64': '18', 'armhf': '8', 'i386': '8', 'ppc64el': '14'}> +CONFIG_ARCH_MMAP_RND_COMPAT_BITS policy<{'amd64': '8', 'arm64': '11', 'ppc64el': '8'}> +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX policy<{'amd64': '16', 'arm64': '16', 'i386': '16', 'ppc64el': '13'}> +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN policy<{'amd64': '8', 'arm64': '11', 'i386': '8', 'ppc64el': '7'}> +CONFIG_ARCH_MMP policy<{'armhf': 'n'}> +CONFIG_ARCH_MSM8960 policy<{'armhf': 'y'}> +CONFIG_ARCH_MSM8974 policy<{'armhf': 'y'}> +CONFIG_ARCH_MSM8X60 policy<{'armhf': 'y'}> +CONFIG_ARCH_MULTIPLATFORM policy<{'armhf': 'y'}> +CONFIG_ARCH_MULTI_V6 policy<{'armhf': 'n'}> +CONFIG_ARCH_MULTI_V6_V7 policy<{'armhf': 'y'}> +CONFIG_ARCH_MULTI_V7 policy<{'armhf': 'y'}> +CONFIG_ARCH_MVEBU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_MXC policy<{'arm64': 'y', 'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED policy<{'armhf': 'y'}> +CONFIG_ARCH_NPCM policy<{'armhf': 'y'}> +CONFIG_ARCH_NPCM7XX policy<{'armhf': 'y'}> +CONFIG_ARCH_NR_GPIO policy<{'armhf': '1024'}> +CONFIG_ARCH_OMAP policy<{'armhf': 'y'}> +CONFIG_ARCH_OMAP1 policy<{'armhf': 'n'}> +CONFIG_ARCH_OMAP2PLUS policy<{'armhf': 'y'}> +CONFIG_ARCH_OMAP2PLUS_TYPICAL policy<{'armhf': 'y'}> +CONFIG_ARCH_OMAP3 policy<{'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_ARCH_OMAP4 policy<{'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_ARCH_OPTIONAL_KERNEL_RWX policy<{'armhf': 'y'}> +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT policy<{'armhf': 'y'}> +CONFIG_ARCH_PROC_KCORE_TEXT policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ARCH_PXA policy<{'armhf': 'n'}> +CONFIG_ARCH_QCOM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_R7S72100 policy<{'armhf': 'y'}> +CONFIG_ARCH_R7S9210 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A73A4 policy<{'armhf': 'n'}> +CONFIG_ARCH_R8A7740 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7743 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7744 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7745 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A77470 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A774A1 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A774C0 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A7778 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7779 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7790 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7791 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7792 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7793 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7794 policy<{'armhf': 'y'}> +CONFIG_ARCH_R8A7795 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A7796 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A77965 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A77970 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A77980 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A77990 policy<{'arm64': 'y'}> +CONFIG_ARCH_R8A77995 policy<{'arm64': 'y'}> +CONFIG_ARCH_R9A06G032 policy<{'armhf': 'y'}> +CONFIG_ARCH_RANDOM policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_RCAR_GEN1 policy<{'armhf': 'y'}> +CONFIG_ARCH_RCAR_GEN2 policy<{'armhf': 'y'}> +CONFIG_ARCH_RCAR_GEN3 policy<{'arm64': 'y'}> +CONFIG_ARCH_RDA policy<{'armhf': 'y'}> +CONFIG_ARCH_REALTEK policy<{'arm64': 'y'}> +CONFIG_ARCH_REALVIEW policy<{'armhf': 'n'}> +CONFIG_ARCH_RENESAS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_RMOBILE policy<{'armhf': 'y'}> +CONFIG_ARCH_RPC policy<{'armhf': 'n'}> +CONFIG_ARCH_RZN1 policy<{'armhf': 'y'}> +CONFIG_ARCH_S3C24XX policy<{'armhf': 'n'}> +CONFIG_ARCH_S5PV210 policy<{'armhf': 'n'}> +CONFIG_ARCH_SA1100 policy<{'armhf': 'n'}> +CONFIG_ARCH_SEATTLE policy<{'arm64': 'y'}> +CONFIG_ARCH_SELECT_MEMORY_MODEL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_SH73A0 policy<{'armhf': 'y'}> +CONFIG_ARCH_SIRF policy<{'armhf': 'n'}> +CONFIG_ARCH_SOCFPGA policy<{'armhf': 'n'}> +CONFIG_ARCH_SPARSEMEM_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SPARSEMEM_ENABLE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SPRD policy<{'arm64': 'y'}> +CONFIG_ARCH_STACKWALK policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ARCH_STI policy<{'armhf': 'n'}> +CONFIG_ARCH_STM32 policy<{'armhf': 'n'}> +CONFIG_ARCH_STRATIX10 policy<{'arm64': 'y'}> +CONFIG_ARCH_SUNXI policy<{'arm64': 'y', 'armhf': 'n'}> +CONFIG_ARCH_SUPPORTS_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN policy<{'armhf': 'y'}> +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SUPPORTS_INT128 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SUPPORTS_UPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_SUSPEND_NONZERO_CPU policy<{'ppc64el': 'y'}> +CONFIG_ARCH_SUSPEND_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ARCH_SYNQUACER policy<{'arm64': 'y'}> +CONFIG_ARCH_TEGRA policy<{'arm64': 'n', 'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_ARCH_TEGRA_114_SOC policy<{'armhf-generic': 'y'}> +CONFIG_ARCH_TEGRA_124_SOC policy<{'armhf-generic': 'y'}> +CONFIG_ARCH_TEGRA_2x_SOC policy<{'armhf-generic': 'y'}> +CONFIG_ARCH_TEGRA_3x_SOC policy<{'armhf-generic': 'y'}> +CONFIG_ARCH_THUNDER policy<{'arm64': 'y'}> +CONFIG_ARCH_THUNDER2 policy<{'arm64': 'y'}> +CONFIG_ARCH_U8500 policy<{'armhf': 'n'}> +CONFIG_ARCH_UNIPHIER policy<{'arm64': 'n', 'armhf': 'y'}> +CONFIG_ARCH_USES_HIGH_VMA_FLAGS policy<{'amd64': 'y'}> +CONFIG_ARCH_USES_PG_UNCACHED policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_USE_BUILTIN_BSWAP policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_USE_CMPXCHG_LOCKREF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_USE_MEMREMAP_PROT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_USE_QUEUED_RWLOCKS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_USE_QUEUED_SPINLOCKS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_VEXPRESS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA policy<{'armhf': 'y'}> +CONFIG_ARCH_VEXPRESS_DCSCB policy<{'armhf': 'y'}> +CONFIG_ARCH_VEXPRESS_SPC policy<{'armhf': 'y'}> +CONFIG_ARCH_VEXPRESS_TC2_PM policy<{'armhf': 'y'}> +CONFIG_ARCH_VIRT policy<{'armhf': 'y'}> +CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_ARCH_WANTS_THP_SWAP policy<{'amd64': 'y'}> +CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARCH_WANT_FRAME_POINTERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_WANT_GENERAL_HUGETLB policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_ARCH_WANT_HUGE_PMD_SHARE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ARCH_WANT_IPC_PARSE_VERSION policy<{'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM policy<{'ppc64el': 'y'}> +CONFIG_ARCH_WANT_OLD_COMPAT_IPC policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ARCH_WEAK_RELEASE_ACQUIRE policy<{'ppc64el': 'y'}> +CONFIG_ARCH_WM8850 policy<{'armhf': 'n'}> +CONFIG_ARCH_XGENE policy<{'arm64': 'y'}> +CONFIG_ARCH_ZYNQ policy<{'armhf': 'n'}> +CONFIG_ARCH_ZYNQMP policy<{'arm64': 'y'}> +CONFIG_ARCNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ARCNET_1051 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_1201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_CAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_COM20020 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_COM20020_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ARCNET_COM20020_ISA policy<{'i386': 'm'}> +CONFIG_ARCNET_COM20020_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_COM90xx policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_COM90xxIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCNET_RIM_I policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ARCX_ANYBUS_CONTROLLER policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_ARC_EMAC_CORE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM policy<{'armhf': 'y'}> +CONFIG_ARM64 policy<{'arm64': 'y'}> +CONFIG_ARM64_16K_PAGES policy<{'arm64': 'n'}> +CONFIG_ARM64_4K_PAGES policy<{'arm64': 'y'}> +CONFIG_ARM64_64K_PAGES policy<{'arm64': 'n'}> +CONFIG_ARM64_ACPI_PARKING_PROTOCOL policy<{'arm64': 'y'}> +CONFIG_ARM64_CNP policy<{'arm64': 'y'}> +CONFIG_ARM64_CONT_SHIFT policy<{'arm64': '4'}> +CONFIG_ARM64_CRYPTO policy<{'arm64': 'y'}> +CONFIG_ARM64_DEBUG_PRIORITY_MASKING policy<{'arm64': 'n'}> +CONFIG_ARM64_ERRATUM_1024718 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1165522 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1286807 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1418040 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1463225 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1542419 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_1742098 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_3194386 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_819472 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_824069 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_826319 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_827319 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_832075 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_834220 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_845719 policy<{'arm64': 'y'}> +CONFIG_ARM64_HW_AFDBM policy<{'arm64': 'y'}> +CONFIG_ARM64_MODULE_PLTS policy<{'arm64': 'y'}> +CONFIG_ARM64_PAGE_SHIFT policy<{'arm64': '12'}> +CONFIG_ARM64_PAN policy<{'arm64': 'y'}> +CONFIG_ARM64_PA_BITS policy<{'arm64': '48'}> +CONFIG_ARM64_PA_BITS_48 policy<{'arm64': 'y'}> +CONFIG_ARM64_PMEM policy<{'arm64': 'y'}> +CONFIG_ARM64_PSEUDO_NMI policy<{'arm64': 'y'}> +CONFIG_ARM64_PTDUMP_CORE policy<{'arm64': 'y'}> +CONFIG_ARM64_PTDUMP_DEBUGFS policy<{'arm64': 'n'}> +CONFIG_ARM64_PTR_AUTH policy<{'arm64': 'y'}> +CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET policy<{'arm64': 'n'}> +CONFIG_ARM64_RAS_EXTN policy<{'arm64': 'y'}> +CONFIG_ARM64_RELOC_TEST policy<{'arm64': 'n'}> +CONFIG_ARM64_SSBD policy<{'arm64': 'y'}> +CONFIG_ARM64_SVE policy<{'arm64': 'y'}> +CONFIG_ARM64_SW_TTBR0_PAN policy<{'arm64': 'y'}> +CONFIG_ARM64_TAGGED_ADDR_ABI policy<{'arm64': 'y'}> +CONFIG_ARM64_UAO policy<{'arm64': 'y'}> +CONFIG_ARM64_VA_BITS policy<{'arm64': '48'}> +CONFIG_ARM64_VA_BITS_39 policy<{'arm64': 'n'}> +CONFIG_ARM64_VHE policy<{'arm64': 'y'}> +CONFIG_ARM64_WORKAROUND_CLEAN_CACHE policy<{'arm64': 'y'}> +CONFIG_ARM64_WORKAROUND_REPEAT_TLBI policy<{'arm64': 'y'}> +CONFIG_ARMADA375_USBCLUSTER_PHY policy<{'armhf': 'y'}> +CONFIG_ARMADA_370_CLK policy<{'armhf': 'y'}> +CONFIG_ARMADA_370_XP_IRQ policy<{'armhf': 'y'}> +CONFIG_ARMADA_370_XP_TIMER policy<{'armhf': 'y'}> +CONFIG_ARMADA_375_CLK policy<{'armhf': 'y'}> +CONFIG_ARMADA_37XX_CLK policy<{'arm64': 'y'}> +CONFIG_ARMADA_37XX_RWTM_MBOX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARMADA_37XX_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARMADA_38X_CLK policy<{'armhf': 'y'}> +CONFIG_ARMADA_39X_CLK policy<{'armhf': 'y'}> +CONFIG_ARMADA_AP806_SYSCON policy<{'arm64': 'y'}> +CONFIG_ARMADA_AP_CPU_CLK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARMADA_AP_CP_HELPER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARMADA_CP110_SYSCON policy<{'arm64': 'y'}> +CONFIG_ARMADA_THERMAL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARMADA_XP_CLK policy<{'armhf': 'y'}> +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM policy<{'arm64': 'm'}> +CONFIG_ARM_AMBA policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_APPENDED_DTB policy<{'armhf': 'y'}> +CONFIG_ARM_ARCH_TIMER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_ARCH_TIMER_EVTSTREAM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND policy<{'arm64': 'y'}> +CONFIG_ARM_ARMADA_37XX_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_ARMADA_8K_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_ATAG_DTB_COMPAT policy<{'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND policy<{'armhf-generic': 'y'}> +CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER policy<{'armhf-generic': 'n'}> +CONFIG_ARM_BIG_LITTLE_CPUFREQ policy<{'armhf': 'm'}> +CONFIG_ARM_BIG_LITTLE_CPUIDLE policy<{'armhf': 'y'}> +CONFIG_ARM_BRCMSTB_AVS_CPUFREQ policy<{'arm64': 'm'}> +CONFIG_ARM_CCI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CCI400_COMMON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CCI400_PMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CCI400_PORT_CTRL policy<{'armhf': 'y'}> +CONFIG_ARM_CCI5xx_PMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CCI_PMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CCN policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CHARLCD policy<{'armhf': 'y'}> +CONFIG_ARM_CPUIDLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_CPU_SUSPEND policy<{'armhf': 'y'}> +CONFIG_ARM_CPU_TOPOLOGY policy<{'armhf': 'y'}> +CONFIG_ARM_CRYPTO policy<{'armhf': 'y'}> +CONFIG_ARM_DMA_IOMMU_ALIGNMENT policy<{'armhf': '8'}> +CONFIG_ARM_DMA_MEM_BUFFERABLE policy<{'armhf': 'y'}> +CONFIG_ARM_DMA_USE_IOMMU policy<{'armhf': 'y'}> +CONFIG_ARM_DSU_PMU policy<{'arm64': 'm'}> +CONFIG_ARM_ERRATA_430973 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_643719 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_720789 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_754322 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_754327 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_764369 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_773022 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_775420 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_798181 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_814220 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_818325_852422 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_821420 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_825619 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_852421 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_852423 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_857271 policy<{'armhf': 'y'}> +CONFIG_ARM_ERRATA_857272 policy<{'armhf': 'y'}> +CONFIG_ARM_EXYNOS_BUS_DEVFREQ policy<{'armhf': 'y'}> +CONFIG_ARM_EXYNOS_CPUIDLE policy<{'armhf': 'y'}> +CONFIG_ARM_GIC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_GIC_MAX_NR policy<{'arm64': '1', 'armhf': '1'}> +CONFIG_ARM_GIC_V2M policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_GIC_V3 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_GIC_V3_ITS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_GIC_V3_ITS_FSL_MC policy<{'arm64': 'y'}> +CONFIG_ARM_GIC_V3_ITS_PCI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_GLOBAL_TIMER policy<{'armhf': 'y'}> +CONFIG_ARM_HAS_SG_CHAIN policy<{'armhf': 'y'}> +CONFIG_ARM_HEAVY_MB policy<{'armhf': 'y'}> +CONFIG_ARM_HIGHBANK_CPUFREQ policy<{'armhf': 'm'}> +CONFIG_ARM_IMX6Q_CPUFREQ policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_ARM_IMX_CPUFREQ_DT policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_ARM_KPROBES_TEST policy<{'armhf': 'm'}> +CONFIG_ARM_L1_CACHE_SHIFT policy<{'armhf': '7'}> +CONFIG_ARM_L1_CACHE_SHIFT_6 policy<{'armhf': 'y'}> +CONFIG_ARM_L1_CACHE_SHIFT_7 policy<{'armhf': 'y'}> +CONFIG_ARM_LPAE policy<{'armhf-generic': 'n', 'armhf-generic-lpae': 'y'}> +CONFIG_ARM_MEDIATEK_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_MHU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_MODULE_PLTS policy<{'armhf': 'n'}> +CONFIG_ARM_MVEBU_V7_CPUIDLE policy<{'armhf': 'y'}> +CONFIG_ARM_OMAP2PLUS_CPUFREQ policy<{'armhf': 'y'}> +CONFIG_ARM_PATCH_IDIV policy<{'armhf': 'y'}> +CONFIG_ARM_PATCH_PHYS_VIRT policy<{'armhf': 'y'}> +CONFIG_ARM_PL172_MPMC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_PMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_PMU_ACPI policy<{'arm64': 'y'}> +CONFIG_ARM_PSCI policy<{'armhf': 'y'}> +CONFIG_ARM_PSCI_CHECKER policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_ARM_PSCI_CPUIDLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_PSCI_FW policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_PTDUMP_CORE policy<{'armhf': 'y'}> +CONFIG_ARM_PTDUMP_DEBUGFS policy<{'armhf': 'n'}> +CONFIG_ARM_QCOM_CPUFREQ_HW policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_QCOM_CPUFREQ_NVMEM policy<{'arm64': 'm'}> +CONFIG_ARM_RASPBERRYPI_CPUFREQ policy<{'arm64': 'm'}> +CONFIG_ARM_RK3399_DMC_DEVFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SBSA_WATCHDOG policy<{'arm64': 'm'}> +CONFIG_ARM_SCMI_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SCMI_POWER_DOMAIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SCMI_PROTOCOL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_SCPI_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SCPI_POWER_DOMAIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SCPI_PROTOCOL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SDE_INTERFACE policy<{'arm64': 'y'}> +CONFIG_ARM_SMMU policy<{'arm64': 'y', 'armhf': 'n'}> +CONFIG_ARM_SMMU_V3 policy<{'arm64': 'y'}> +CONFIG_ARM_SMMU_V3_PMU policy<{'arm64': 'm'}> +CONFIG_ARM_SP805_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ARM_SPE_PMU policy<{'arm64': 'm'}> +CONFIG_ARM_TEGRA124_CPUFREQ policy<{'armhf-generic': 'y'}> +CONFIG_ARM_TEGRA186_CPUFREQ policy<{'armhf-generic': 'm'}> +CONFIG_ARM_TEGRA20_CPUFREQ policy<{'armhf-generic': 'y'}> +CONFIG_ARM_TEGRA20_DEVFREQ policy<{'armhf-generic': 'm'}> +CONFIG_ARM_TEGRA_DEVFREQ policy<{'armhf-generic': 'm'}> +CONFIG_ARM_THUMB policy<{'armhf': 'y'}> +CONFIG_ARM_THUMBEE policy<{'armhf': 'y'}> +CONFIG_ARM_TIMER_SP804 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ARM_TI_CPUFREQ policy<{'armhf': 'y'}> +CONFIG_ARM_VEXPRESS_SPC_CPUFREQ policy<{'armhf': 'm'}> +CONFIG_ARM_VIRT_EXT policy<{'armhf': 'y'}> +CONFIG_AS3935 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ASHMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ASM_MODVERSIONS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ASN1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ASPEED_ADC policy<{'armhf': 'm'}> +CONFIG_ASPEED_BT_IPMI_BMC policy<{'armhf': 'm'}> +CONFIG_ASPEED_KCS_IPMI_BMC policy<{'armhf': 'm'}> +CONFIG_ASPEED_LPC_CTRL policy<{'armhf': 'm'}> +CONFIG_ASPEED_LPC_SNOOP policy<{'armhf': 'm'}> +CONFIG_ASPEED_P2A_CTRL policy<{'armhf': 'm'}> +CONFIG_ASPEED_WATCHDOG policy<{'armhf': 'y'}> +CONFIG_ASSOCIATIVE_ARRAY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ASUS_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ASUS_NB_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ASUS_WIRELESS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ASUS_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ASYNC_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ASYNC_MEMCPY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ASYNC_PQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ASYNC_RAID6_RECOV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ASYNC_RAID6_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA policy<{'arm64': 'y'}> +CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA policy<{'arm64': 'y'}> +CONFIG_ASYNC_TX_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ASYNC_XOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AT76C50X_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AT803X_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_ATAGS policy<{'armhf': 'y'}> +CONFIG_ATAGS_PROC policy<{'armhf': 'y'}> +CONFIG_ATALK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ATARI_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_ATA_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_ATA_BMDMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATA_GENERIC policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_ATA_OVER_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ATA_SFF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATA_VERBOSE_ERROR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH10K_AHB policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K_CE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH10K_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH10K_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH10K_SNOC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ATH10K_SPECTRAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH10K_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH5K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH5K_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH5K_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH5K_TRACER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH6KL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH6KL_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH6KL_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH6KL_TRACING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH6KL_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K_AHB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_BTCOEX_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_CHANNEL_CONTEXT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K_COMMON_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_COMMON_SPECTRAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_DYNACK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATH9K_HTC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K_HTC_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_HW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K_HWRNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_PCI_NO_EEPROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH9K_PCOEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_RFKILL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_STATION_STATISTICS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH9K_WOW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATH_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATH_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATL1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATL1C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATL1E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATL2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATLAS_PH_SENSOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ATMEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_AMBASSADOR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ATM_AMBASSADOR_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_ATM_BR2684 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_BR2684_IPFILTER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_CLIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_CLIP_NO_ICMP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATM_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_ENI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_ENI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_ENI_TUNE_BURST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_FIRESTREAM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ATM_FORE200E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_FORE200E_DEBUG policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_ATM_FORE200E_TX_RETRY policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'i386': '16', 'ppc64el': '16'}> +CONFIG_ATM_FORE200E_USE_TASKLET policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_HE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_HE_USE_SUNI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATM_HORIZON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ATM_HORIZON_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_ATM_IA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_IA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_IDT77252 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_IDT77252_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_IDT77252_RCV_ALL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_IDT77252_USE_SUNI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ATM_LANAI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_LANE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_MPOA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_NICSTAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_NICSTAR_USE_IDT77105 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_NICSTAR_USE_SUNI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ATM_SOLOS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ATM_ZATM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ATM_ZATM_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_ATOMIC64_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ATP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_AUDIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUDITSYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUDIT_ARCH policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUDIT_ARCH_COMPAT_GENERIC policy<{'arm64': 'y'}> +CONFIG_AUDIT_COMPAT_GENERIC policy<{'arm64': 'y'}> +CONFIG_AUDIT_GENERIC policy<{'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_AUFS_BDEV_LOOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUFS_BRANCH_MAX_1023 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_BRANCH_MAX_127 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUFS_BRANCH_MAX_32767 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_BRANCH_MAX_511 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_BR_FUSE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_BR_HFSPLUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AUFS_BR_RAMFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_DIRREN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUFS_FHSM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AUFS_HNOTIFY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_INO_T_64 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_AUFS_RDU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_SBILIST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AUFS_SHWH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_AUFS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_AURORA_NB8800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_AUTOFS4_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'y'}> +CONFIG_AUTOFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'y'}> +CONFIG_AUTO_ZRELADDR policy<{'armhf': 'y'}> +CONFIG_AUXDISPLAY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_AX25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AX25_DAMA_SLAVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_AX88796 policy<{'armhf': 'm'}> +CONFIG_AX88796B_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_AX88796_93CX6 policy<{'armhf': 'n'}> +CONFIG_AXI_DMAC policy<{'arm64': 'm'}> +CONFIG_AXP20X_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AXP20X_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AXP288_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_AXP288_CHARGER policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_AXP288_FUEL_GAUGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B43 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B43LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B43LEGACY_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43LEGACY_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_DMA_AND_PIO_MODE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_DMA_MODE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43LEGACY_HWRNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_PCICORE_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_PCI_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_PIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43LEGACY_PIO_MODE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43_BCMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_BCMA_PIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_BUSES_BCMA policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43_BUSES_BCMA_AND_SSB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_BUSES_SSB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43_HWRNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PCICORE_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PCI_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PHY_G policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PHY_HT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PHY_LP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PHY_N policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_PIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B43_SDIO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_B43_SSB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B44 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B44_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B44_PCICORE_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B44_PCI_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_B53 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B53_MDIO_DRIVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B53_MMAP_DRIVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B53_SERDES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B53_SPI_DRIVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_B53_SRAB_DRIVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_AAT2870 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_ADP5520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_ADP8860 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_ADP8870 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_APPLE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BACKLIGHT_ARCXCNN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_AS3711 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_BD6107 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_CARILLO_RANCH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BACKLIGHT_CLASS_DEVICE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_BACKLIGHT_DA903X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LM3533 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LM3630A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LM3639 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LP855X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LP8788 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_LV5207LP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_MAX8925 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_PANDORA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_PCF50633 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_PM8941_WLED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_PWM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_RAVE_SP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_SAHARA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BACKLIGHT_SKY81452 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKLIGHT_TPS65217 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_BACKLIGHT_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BACKTRACE_SELF_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BALLOON_COMPACTION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BASE_FULL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BASE_SMALL policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_BATMAN_ADV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BATMAN_ADV_BATMAN_V policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BATMAN_ADV_BLA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BATMAN_ADV_DAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BATMAN_ADV_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BATMAN_ADV_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BATMAN_ADV_MCAST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BATMAN_ADV_NC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BATMAN_ADV_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BATMAN_ADV_TRACING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BATTERY_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_ACT8945A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_AXP20X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_BQ27XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BATTERY_BQ27XXX_HDQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_BQ27XXX_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DA9030 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DA9150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DS2760 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DS2780 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DS2781 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_DS2782 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_GAUGE_LTC2941 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_LEGO_EV3 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_MAX17040 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_MAX17042 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_MAX1721X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_RT5033 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_RX51 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_SBS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BATTERY_TWL4030_MADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BAYCOM_EPP policy<{'armhf': 'm', 'i386': 'm'}> +CONFIG_BAYCOM_PAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BAYCOM_SER_FDX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BAYCOM_SER_HDX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BCACHE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BCACHE_CLOSURES_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BCACHE_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BCM2835_MBOX policy<{'arm64': 'y'}> +CONFIG_BCM2835_POWER policy<{'arm64': 'y'}> +CONFIG_BCM2835_THERMAL policy<{'arm64': 'm'}> +CONFIG_BCM2835_VCHIQ policy<{'arm64': 'm'}> +CONFIG_BCM2835_WDT policy<{'arm64': 'm'}> +CONFIG_BCM7038_L1_IRQ policy<{'arm64': 'y'}> +CONFIG_BCM7038_WDT policy<{'arm64': 'm'}> +CONFIG_BCM7XXX_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BCM87XX_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BCMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BCMA_BLOCKIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BCMA_DRIVER_GMAC_CMN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_DRIVER_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_DRIVER_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_HOST_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_HOST_PCI_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_HOST_SOC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMA_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BCMA_SFLASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BCMGENET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BCM_FLEXRM_MBOX policy<{'arm64': 'm'}> +CONFIG_BCM_IPROC_ADC policy<{'arm64': 'm'}> +CONFIG_BCM_KONA_USB2_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BCM_NET_PHYLIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BCM_NS_THERMAL policy<{'arm64': 'm'}> +CONFIG_BCM_PDC_MBOX policy<{'arm64': 'm'}> +CONFIG_BCM_SBA_RAID policy<{'arm64': 'm'}> +CONFIG_BCM_SR_THERMAL policy<{'arm64': 'm'}> +CONFIG_BCM_VIDEOCORE policy<{'arm64': 'm'}> +CONFIG_BD70528_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_BE2ISCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BE2NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BE2NET_BE2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BE2NET_BE3 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BE2NET_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BE2NET_LANCER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BE2NET_SKYHAWK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BEFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BEFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BERLIN2_ADC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_BFQ_CGROUP_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BFQ_GROUP_IOSCHED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BGMAC policy<{'arm64': 'y'}> +CONFIG_BGMAC_PLATFORM policy<{'arm64': 'y'}> +CONFIG_BH1750 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BH1780 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BIG_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BIG_LITTLE policy<{'armhf': 'y'}> +CONFIG_BINARY_PRINTF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BINFMT_ELF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BINFMT_ELF_FDPIC policy<{'armhf': 'y'}> +CONFIG_BINFMT_FLAT policy<{'armhf': 'y'}> +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK policy<{'armhf': 'y'}> +CONFIG_BINFMT_FLAT_OLD policy<{'armhf': 'y'}> +CONFIG_BINFMT_MISC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BINFMT_SHARED_FLAT policy<{'armhf': 'y'}> +CONFIG_BINFMT_ZFLAT policy<{'armhf': 'y'}> +CONFIG_BITREVERSE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_CGROUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_CGROUP_IOCOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_CGROUP_IOLATENCY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BLK_CMDLINE_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEBUG_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEBUG_FS_ZONED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_3W_XXXX_RAID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_BSG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_BSGLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_CRYPTOLOOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_DM_BUILTIN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_DRBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_FD policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BLK_DEV_FD_RAWCMD policy<{'amd64': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BLK_DEV_INITRD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_INTEGRITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_IO_TRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_LOOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_LOOP_MIN_COUNT policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8', 's390x': '8'}> +CONFIG_BLK_DEV_MD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_DEV_NBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_NULL_BLK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_PCIESSD_MTIP32XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_PMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BLK_DEV_RAM_COUNT policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'i386': '16', 'ppc64el': '16', 's390x': '16'}> +CONFIG_BLK_DEV_RBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BLK_DEV_RSXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_SKD policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_BLK_DEV_THROTTLING_LOW policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BLK_DEV_XPRAM policy<{'s390x': 'n'}> +CONFIG_BLK_DEV_ZONED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_MQ_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_MQ_RDMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_MQ_VIRTIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_PM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BLK_RQ_ALLOC_TIME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_SCSI_REQUEST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_SED_OPAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_WBT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLK_WBT_MQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BLOCK_COMPAT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BL_SWITCHER policy<{'armhf': 'y'}> +CONFIG_BL_SWITCHER_DUMMY_IF policy<{'armhf': 'm'}> +CONFIG_BMA180 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMA220 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_ACCEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_ACCEL_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_ACCEL_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_MAGN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_MAGN_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMC150_MAGN_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BME680 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BME680_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BME680_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMG160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMG160_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMG160_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMI160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMI160_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMI160_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMP280 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMP280_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BMP280_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BNA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BNX2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BNX2X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BNX2X_SRIOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BNXT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BNXT_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BNXT_FLOWER_OFFLOAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BNXT_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BNXT_SRIOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BOARD_TPCI200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BONDING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC policy<{'amd64': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE policy<{'amd64': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_BOOTPARAM_HOTPLUG_CPU0 policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_BOOTPARAM_HUNG_TASK_PANIC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_BOOTX_TEXT policy<{'ppc64el': 'n'}> +CONFIG_BOOT_PRINTK_DELAY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_BOUNCE policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'n'}> +CONFIG_BPF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPFILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPFILTER_UMH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BPF_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPF_JIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPF_JIT_ALWAYS_ON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPF_KPROBE_OVERRIDE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BPF_STREAM_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPF_SYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPF_UNPRIV_DEFAULT_OFF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BPQETHER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BQL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BRANCH_PROFILE_NONE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BRCMDBG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BRCMFMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BRCMFMAC_PCIE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRCMFMAC_PROTO_BCDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRCMFMAC_PROTO_MSGBUF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRCMFMAC_SDIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRCMFMAC_USB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRCMSMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BRCMSTB_GISB_ARB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_BRCMSTB_L2_IRQ policy<{'arm64': 'y'}> +CONFIG_BRCMSTB_PM policy<{'arm64': 'y'}> +CONFIG_BRCMSTB_THERMAL policy<{'arm64': 'm'}> +CONFIG_BRCMUTIL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BRCM_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_802_3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_AMONG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_ARP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_ARPREPLY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_BROUTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_DNAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_IP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_IP6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_LIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_LOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_MARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_MARK_T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_NFLOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_PKTTYPE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_REDIRECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_SNAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_STP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_T_FILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_T_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_EBT_VLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_IGMP_SNOOPING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BRIDGE_NETFILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_NF_EBTABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BRIDGE_VLAN_FILTERING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BROADCOM_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BSD_DISKLABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_BSD_PROCESS_ACCT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BSD_PROCESS_ACCT_V3 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BTREE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BTRFS_ASSERT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BTRFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BTRFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_BTRFS_FS_CHECK_INTEGRITY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BTRFS_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BTRFS_FS_REF_VERIFY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BTRFS_FS_RUN_SANITY_TESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BTT policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_6LOWPAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_ATH3K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_BCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_BNEP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_BNEP_MC_FILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_BNEP_PROTO_FILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_BREDR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_CMTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIBCM203X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIBFUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIBLUECARD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BT_HCIBPA10X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIBT3C policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BT_HCIBTSDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIBTUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIBTUSB_AUTOSUSPEND policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIBTUSB_BCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIBTUSB_MTK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIBTUSB_RTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIDTL1 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_BT_HCIRSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIUART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIUART_3WIRE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_AG6XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_ATH3K policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_BCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_BCSP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_H4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_INTEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_LL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_MRVL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_NOKIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HCIUART_QCA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIUART_RTL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_BT_HCIUART_SERDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_HCIVHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_HIDP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_INTEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_LE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_MRVL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_MRVL_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_MTKSDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_MTKUART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_QCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_QCOMSMD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_BT_RFCOMM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_RFCOMM_TTY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_BT_RTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BT_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_BT_WILINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_BUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BUG_ON_DATA_CORRUPTION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_BUILDTIME_EXTABLE_SORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BUILD_BIN2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_BUILD_SALT policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_C101 policy<{'i386': 'm'}> +CONFIG_C2PORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_C2PORT_DURAMAR_2150 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CACHEFILES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CACHEFILES_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CACHEFILES_HISTOGRAM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CACHE_FEROCEON_L2 policy<{'armhf': 'y'}> +CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH policy<{'armhf': 'n'}> +CONFIG_CACHE_L2X0 policy<{'armhf': 'y'}> +CONFIG_CACHE_L2X0_PMU policy<{'armhf': 'y'}> +CONFIG_CACHE_TAUROS2 policy<{'armhf': 'y'}> +CONFIG_CACHE_UNIPHIER policy<{'armhf': 'y'}> +CONFIG_CADENCE_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CAIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CAIF_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CAIF_HSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAIF_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAIF_SPI_SLAVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAIF_SPI_SYNC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CAIF_TTY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAIF_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAIF_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CALGARY_IOMMU policy<{'amd64': 'y'}> +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT policy<{'amd64': 'y'}> +CONFIG_CAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CAN_8DEV_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_BCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_CALC_BITTIMING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CAN_CC770 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_CC770_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_CC770_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_C_CAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_C_CAN_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_C_CAN_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_DEBUG_DEVICES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CAN_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_EMS_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_EMS_PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CAN_EMS_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_ESD_USB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_F81601 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_FLEXCAN policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_GRCAN policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_GS_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_GW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_HI311X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_IFI_CANFD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_J1939 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_JANZ_ICAN3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_KVASER_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_KVASER_PCIEFD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_KVASER_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_MCBA_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_MCP251X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_MSCAN policy<{'ppc64el': 'm'}> +CONFIG_CAN_M_CAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_M_CAN_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_M_CAN_TCAN4X5X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_PEAK_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_PEAK_PCIEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CAN_PEAK_PCIEFD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_PEAK_PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CAN_PEAK_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_PLX_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CAN_RCAR_CANFD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CAN_SJA1000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_SJA1000_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_SJA1000_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_SLCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_SOFTING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_SOFTING_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CAN_TI_HECC policy<{'armhf': 'm'}> +CONFIG_CAN_TSCAN1 policy<{'i386': 'm'}> +CONFIG_CAN_UCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_VCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_VXCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAN_XILINXCAN policy<{'arm64': 'm'}> +CONFIG_CAPI_AVM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CAPI_TRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CARDBUS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_CARDMAN_4000 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CARDMAN_4040 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CARL9170 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CARL9170_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CARL9170_HWRNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CARL9170_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CARL9170_WPC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CARMINE_DRAM_CUSTOM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CASSINI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CAVIUM_CPT policy<{'arm64': 'm'}> +CONFIG_CAVIUM_ERRATUM_22375 policy<{'arm64': 'y'}> +CONFIG_CAVIUM_ERRATUM_23144 policy<{'arm64': 'y'}> +CONFIG_CAVIUM_ERRATUM_23154 policy<{'arm64': 'y'}> +CONFIG_CAVIUM_ERRATUM_27456 policy<{'arm64': 'y'}> +CONFIG_CAVIUM_ERRATUM_30115 policy<{'arm64': 'y'}> +CONFIG_CAVIUM_PTP policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_CAVIUM_TX2_ERRATUM_219 policy<{'arm64': 'y'}> +CONFIG_CB710_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CB710_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CB710_DEBUG_ASSUMPTIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CC10001_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CCS811 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CCW policy<{'s390x': 'y'}> +CONFIG_CCWGROUP policy<{'s390x': 'm'}> +CONFIG_CCW_CONSOLE policy<{'s390x': 'y'}> +CONFIG_CC_CAN_LINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAS_ASM_GOTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAS_ASM_INLINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAS_KASAN_GENERIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAS_SANCOV_TRACE_PC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAS_SANE_STACKPROTECTOR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CC_HAS_STACKPROTECTOR_NONE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG policy<{'arm64': 'y'}> +CONFIG_CC_IS_GCC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CC_OPTIMIZE_FOR_SIZE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CDNS_I3C_MASTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CDROM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CDROM_PKTCDVD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CDROM_PKTCDVD_BUFFERS policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_CDROM_PKTCDVD_WCACHE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CEC_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CEC_GPIO policy<{'amd64-lowlatency': 'm', 'i386-lowlatency': 'm'}> +CONFIG_CEC_NOTIFIER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CEC_PIN policy<{'amd64-lowlatency': 'y', 'arm64': 'y', 'i386-lowlatency': 'y'}> +CONFIG_CEC_PIN_ERROR_INJ policy<{'amd64-lowlatency': 'n', 'arm64': 'n', 'i386-lowlatency': 'n'}> +CONFIG_CEC_PLATFORM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CEPH_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CEPH_FSCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CEPH_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CEPH_FS_SECURITY_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CEPH_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CEPH_LIB_PRETTYDEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CEPH_LIB_USE_DNS_RESOLVER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CFAG12864B policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CFAG12864B_RATE policy<{'amd64': '20', 'i386': '20'}> +CONFIG_CFG80211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CFG80211_CERTIFICATION_ONUS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CFG80211_CRDA_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_DEFAULT_PS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_DEVELOPER_WARNINGS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_WEXT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFG80211_WEXT_EXPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CFS_BANDWIDTH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_BPF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_CPUACCT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CGROUP_DEVICE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_FREEZER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_HUGETLB policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_NET_CLASSID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_NET_PRIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_PERF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_PIDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_RDMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_SCHED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CGROUP_WRITEBACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CHARGER_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_ADP5061 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_AXP20X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BD70528 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BQ2415X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BQ24190 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BQ24257 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BQ24735 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_BQ25890 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_CPCAP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CHARGER_CROS_USBPD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CHARGER_DA9150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_DETECTOR_MAX14656 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_ISP1704 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_LP8727 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_LP8788 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_LT3651 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MANAGER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHARGER_MAX14577 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MAX77650 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MAX77693 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MAX8903 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MAX8997 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_MAX8998 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_PCF50633 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_QCOM_SMBB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CHARGER_RT9455 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_SBS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_SC2731 policy<{'arm64': 'm'}> +CONFIG_CHARGER_SMB347 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_TPS65090 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_TPS65217 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CHARGER_TWL4030 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_UCS1002 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CHARGER_WILCO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CHARLCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHARLCD_BL_FLASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHARLCD_BL_OFF policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CHARLCD_BL_ON policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CHECKPOINT_RESTORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CHECK_SIGNATURE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHELSIO_IPSEC_INLINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHELSIO_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHELSIO_T1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHELSIO_T1_1G policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHELSIO_T3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHELSIO_T4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHELSIO_T4VF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CHELSIO_T4_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHELSIO_T4_FCOE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CHROMEOS_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CHROMEOS_PSTORE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CHROMEOS_TBMC policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_CHROME_PLATFORMS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_CHR_DEV_SCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CHR_DEV_ST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CHSC_SCH policy<{'s390x': 'm'}> +CONFIG_CICADA_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CIFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CIFS_ALLOW_INSECURE_LEGACY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_DEBUG2 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CIFS_DEBUG_DUMP_KEYS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CIFS_DFS_UPCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_FSCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_POSIX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_SMB_DIRECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CIFS_STATS2 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CIFS_UPCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_WEAK_PW_HASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIFS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CIO_DAC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CLANG_VERSION policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_CLEANCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CLKBLD_I8253 policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CLKDEV_LOOKUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_CLKEVT_I8253 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK policy<{'armhf': 'y'}> +CONFIG_CLKSRC_EXYNOS_MCT policy<{'armhf': 'y'}> +CONFIG_CLKSRC_I8253 policy<{'i386': 'y'}> +CONFIG_CLKSRC_IMX_GPT policy<{'armhf-generic': 'y'}> +CONFIG_CLKSRC_IMX_TPM policy<{'armhf-generic': 'y'}> +CONFIG_CLKSRC_MMIO policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLKSRC_QCOM policy<{'armhf': 'y'}> +CONFIG_CLKSRC_TI_32K policy<{'armhf': 'y'}> +CONFIG_CLKSRC_VERSATILE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_ACTIONS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_BCM2835 policy<{'arm64': 'y'}> +CONFIG_CLK_BCM_NS2 policy<{'arm64': 'y'}> +CONFIG_CLK_BCM_SR policy<{'arm64': 'y'}> +CONFIG_CLK_EMEV2 policy<{'armhf': 'y'}> +CONFIG_CLK_HSDK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_IMX8MM policy<{'arm64': 'y'}> +CONFIG_CLK_IMX8MN policy<{'arm64': 'y'}> +CONFIG_CLK_IMX8MQ policy<{'arm64': 'y'}> +CONFIG_CLK_IMX8QXP policy<{'arm64': 'y'}> +CONFIG_CLK_OWL_S500 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_OWL_S700 policy<{'arm64': 'y'}> +CONFIG_CLK_OWL_S900 policy<{'arm64': 'y'}> +CONFIG_CLK_QORIQ policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_R7S9210 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7740 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7743 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7745 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A77470 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A774A1 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A774C0 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A7778 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7779 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7790 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7791 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7792 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7794 policy<{'armhf': 'y'}> +CONFIG_CLK_R8A7795 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A7796 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A77965 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A77970 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A77980 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A77990 policy<{'arm64': 'y'}> +CONFIG_CLK_R8A77995 policy<{'arm64': 'y'}> +CONFIG_CLK_R9A06G032 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_RASPBERRYPI policy<{'arm64': 'm'}> +CONFIG_CLK_RCAR_GEN2 policy<{'armhf': 'y'}> +CONFIG_CLK_RCAR_GEN2_CPG policy<{'armhf': 'y'}> +CONFIG_CLK_RCAR_GEN3_CPG policy<{'arm64': 'y'}> +CONFIG_CLK_RCAR_USB2_CLOCK_SEL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_RENESAS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_RENESAS_CPG_MSSR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_RENESAS_CPG_MSTP policy<{'armhf': 'y'}> +CONFIG_CLK_RENESAS_DIV6 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_RENESAS_LEGACY policy<{'armhf': 'y'}> +CONFIG_CLK_RZA1 policy<{'armhf': 'y'}> +CONFIG_CLK_SH73A0 policy<{'armhf': 'y'}> +CONFIG_CLK_SP810 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLK_SUNXI policy<{'arm64': 'y'}> +CONFIG_CLK_SUNXI_CLOCKS policy<{'arm64': 'y'}> +CONFIG_CLK_SUNXI_PRCM_SUN6I policy<{'arm64': 'y'}> +CONFIG_CLK_SUNXI_PRCM_SUN8I policy<{'arm64': 'y'}> +CONFIG_CLK_SUNXI_PRCM_SUN9I policy<{'arm64': 'y'}> +CONFIG_CLK_TEGRA_BPMP policy<{'armhf-generic': 'y'}> +CONFIG_CLK_TWL6040 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CLK_UNIPHIER policy<{'armhf': 'y'}> +CONFIG_CLK_VEXPRESS_OSC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CLOCKSOURCE_WATCHDOG policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CLOCK_THERMAL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_CLONE_BACKWARDS policy<{'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CLONE_BACKWARDS2 policy<{'s390x': 'y'}> +CONFIG_CLS_U32_MARK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CLS_U32_PERF policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CLZ_TAB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CM32181 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CM3232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CM3323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CM3605 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CM36651 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CMA_ALIGNMENT policy<{'arm64': '8', 'armhf': '8'}> +CONFIG_CMA_AREAS policy<{'amd64': '7', 'arm64': '7', 'armhf': '7', 'i386': '7', 'ppc64el': '7', 's390x': '7'}> +CONFIG_CMA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CMA_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CMA_SIZE_SEL_MAX policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_CMA_SIZE_SEL_MBYTES policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CMA_SIZE_SEL_MIN policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_CMA_SIZE_SEL_PERCENTAGE policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_CMDLINE policy<{'arm64': '"console=ttyAMA0"', 'armhf': '""', 'ppc64el': '""'}> +CONFIG_CMDLINE_BOOL policy<{'amd64': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CMDLINE_FORCE policy<{'arm64': 'n'}> +CONFIG_CMDLINE_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_CMM policy<{'ppc64el': 'm', 's390x': 'y'}> +CONFIG_CMM_IUCV policy<{'s390x': 'y'}> +CONFIG_CMT_SPEECH policy<{'armhf-generic': 'm'}> +CONFIG_CNIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CODA_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CODE_PATCHING_SELFTEST policy<{'ppc64el': 'n'}> +CONFIG_COMEDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_8254 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_8255 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_8255_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_8255_SA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_1032 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_1500 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_1516 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_1564 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_16XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_2032 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_2200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_3120 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_3501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_APCI_3XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADDI_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADL_PCI6208 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADL_PCI7X3X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADL_PCI8164 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADL_PCI9111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADL_PCI9118 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADQ12B policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI1710 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI1720 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI1723 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI1724 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI1760 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ADV_PCI_DIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AIO_AIO12_8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AIO_IIRO_16 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_DIO200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_DIO200_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_DIO200_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PC236 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PC236_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PC236_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PC263_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PC263_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PCI224 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_AMPLC_PCI230 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_BOND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_C6XDIGIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CB_DAS16_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_CB_PCIDAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CB_PCIDAS64 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CB_PCIDDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CB_PCIMDAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CB_PCIMDDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_CONTEC_PCI_DIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAC02 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAQBOARD2000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS08 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS08_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_DAS08_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS08_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS16 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS16M1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS1800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS6402 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DAS800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB policy<{'amd64': '20480', 'arm64': '20480', 'armhf': '20480', 'i386': '20480', 'ppc64el': '20480'}> +CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB policy<{'amd64': '2048', 'arm64': '2048', 'armhf': '2048', 'i386': '2048', 'ppc64el': '2048'}> +CONFIG_COMEDI_DMM32AT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT2801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT2811 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT2814 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT2815 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT2817 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT282X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT3000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DT9812 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_DYNA_PCI10XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_FL512 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_GSC_HPDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ICP_MULTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_II_PCI20KC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ISADMA policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ISA_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_COMEDI_JR3_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_KCOMEDILIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_KE_COUNTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ME4000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_ME_DAQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_MF6X4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_MISC_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_COMEDI_MITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_MPC624 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_MULTIQ3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_6527 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_65XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_660X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_670X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_ATMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_ATMIO16D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_AT_A2150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_AT_AO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_DAQ_700_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_NI_DAQ_DIO24_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_NI_LABPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_LABPC_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_NI_LABPC_ISA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_LABPC_ISADMA policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_LABPC_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_MIO_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_NI_PCIDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_PCIMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_ROUTING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_TIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_TIOCMD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_NI_USB6501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PARPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCI_DRIVERS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL711 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL724 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL726 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL730 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL812 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL816 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCL818 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCM3724 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCMAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCMCIA_DRIVERS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_PCMDA12 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCMMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_PCMUIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_QUATECH_DAQP_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMEDI_RTD520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_RTI800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_RTI802 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_S526 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_S626 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_SSV_DNP policy<{'i386': 'm'}> +CONFIG_COMEDI_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_USBDUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_USBDUXFAST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_USBDUXSIGMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_USB_DRIVERS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMEDI_VMK80XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_COMMON_CLK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_COMMON_CLK_ASPEED policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_AXG policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_AXG_AUDIO policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_BD718XX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_CDCE706 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_CDCE925 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_CS2000_CP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_FIXED_MMIO policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_G12A policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_GXBB policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_HI3516CV300 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_HI3519 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_HI3660 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_HI3670 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_HI3798CV200 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_HI6220 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_HI655X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_IPROC policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_LOCHNAGAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_MAX77686 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_MAX9485 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_MEDIATEK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MESON8B policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_MESON_AO_CLKC policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MESON_CPU_DYNDIV policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MESON_DUALDIV policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MESON_EE_CLKC policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MESON_MPLL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MESON_PHASE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_MESON_PLL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MESON_REGMAP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MESON_SCLK_DIV policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_MESON_VID_PLL_DIV policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2701 policy<{'armhf': 'n'}> +CONFIG_COMMON_CLK_MT2712 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_BDPSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_IMGSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_JPGDECSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_MFGCFG policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_MMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_VDECSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT2712_VENCSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_AUDSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_CAMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_IMGSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_IPESYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_MFGCFG policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_MMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_VDECSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6779_VENCSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6797 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6797_IMGSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6797_MMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6797_VDECSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT6797_VENCSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT7622 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7622_AUDSYS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7622_ETHSYS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7622_HIFSYS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7629 policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7629_ETHSYS policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_MT7629_HIFSYS policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_MT8135 policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_MT8173 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT8183 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_AUDIOSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_CAMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_IMGSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_IPU_ADL policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_IPU_CONN policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_IPU_CORE0 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_IPU_CORE1 policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_MFGCFG policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_MMSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_VDECSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8183_VENCSYS policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_MT8516 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_MT8516_AUDSYS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_PALMAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_PWM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_RK808 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_S2MPS11 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_SAMSUNG policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_SCMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_SCPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_SI514 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_SI5341 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_SI5351 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_SI544 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_SI570 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_TI_ADPLL policy<{'armhf': 'y'}> +CONFIG_COMMON_CLK_VC5 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_CLK_VERSATILE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_COMMON_CLK_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_COMMON_CLK_XGENE policy<{'arm64': 'y'}> +CONFIG_COMMON_CLK_XLNX_CLKWZRD policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_COMMON_CLK_ZYNQMP policy<{'arm64': 'y'}> +CONFIG_COMMON_RESET_HI3660 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMMON_RESET_HI6220 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_COMPACTION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COMPAL_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COMPAT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COMPAT_32 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_COMPAT_32BIT_TIME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COMPAT_BINFMT_ELF policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COMPAT_FOR_U64_ALIGNMENT policy<{'amd64': 'y'}> +CONFIG_COMPAT_NETLINK_MESSAGES policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_COMPAT_OLD_SIGACTION policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COMPAT_VDSO policy<{'amd64': 'n', 'i386': 'n', 's390x': 'y'}> +CONFIG_COMPILE_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CONFIGFS_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CONNECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CONSOLE_LOGLEVEL_DEFAULT policy<{'amd64': '7', 'arm64': '7', 'armhf': '7', 'i386': '7', 'ppc64el': '7', 's390x': '7'}> +CONFIG_CONSOLE_LOGLEVEL_QUIET policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'i386': '4', 'ppc64el': '4', 's390x': '4'}> +CONFIG_CONSOLE_POLL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CONSOLE_TRANSLATIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CONTEXT_SWITCH_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CONTIG_ALLOC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_COPS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_COPS_DAYNA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_COPS_TANGENT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CORDIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_COREDUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CORESIGHT policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CORTINA_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_COSA policy<{'i386': 'm'}> +CONFIG_COUNTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CPA_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_CPCAP_ADC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CPU5_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CPUFREQ_DT_PLATDEV policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CPUMASK_OFFSTACK policy<{'amd64': 'y'}> +CONFIG_CPUSETS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CPU_32v6K policy<{'armhf': 'y'}> +CONFIG_CPU_32v7 policy<{'armhf': 'y'}> +CONFIG_CPU_ABRT_EV7 policy<{'armhf': 'y'}> +CONFIG_CPU_BIG_ENDIAN policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_CPU_BPREDICT_DISABLE policy<{'armhf': 'n'}> +CONFIG_CPU_CACHE_V7 policy<{'armhf': 'y'}> +CONFIG_CPU_CACHE_VIPT policy<{'armhf': 'y'}> +CONFIG_CPU_COPY_V6 policy<{'armhf': 'y'}> +CONFIG_CPU_CP15 policy<{'armhf': 'y'}> +CONFIG_CPU_CP15_MMU policy<{'armhf': 'y'}> +CONFIG_CPU_FREQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_CPU_FREQ_GOV_ATTR_SET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_FREQ_GOV_SCHEDUTIL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_HAS_ASID policy<{'armhf': 'y'}> +CONFIG_CPU_HOTPLUG_STATE_CONTROL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CPU_ICACHE_DISABLE policy<{'armhf': 'n'}> +CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND policy<{'armhf': 'y'}> +CONFIG_CPU_IDLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_IDLE_GOV_HALTPOLL policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_IDLE_GOV_LADDER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_IDLE_GOV_MENU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_IDLE_GOV_TEO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CPU_ISOLATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CPU_LITTLE_ENDIAN policy<{'ppc64el': 'y'}> +CONFIG_CPU_PABRT_V7 policy<{'armhf': 'y'}> +CONFIG_CPU_PJ4 policy<{'armhf': 'y'}> +CONFIG_CPU_PJ4B policy<{'armhf': 'y'}> +CONFIG_CPU_PM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CPU_RMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CPU_SPECTRE policy<{'armhf': 'y'}> +CONFIG_CPU_SUP_AMD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CPU_SUP_CENTAUR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CPU_SUP_CYRIX_32 policy<{'i386': 'y'}> +CONFIG_CPU_SUP_HYGON policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CPU_SUP_INTEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CPU_SUP_TRANSMETA_32 policy<{'i386': 'y'}> +CONFIG_CPU_SUP_UMC_32 policy<{'i386': 'y'}> +CONFIG_CPU_SUP_ZHAOXIN policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CPU_SW_DOMAIN_PAN policy<{'armhf-generic': 'y'}> +CONFIG_CPU_THERMAL policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_CPU_THUMB_CAPABLE policy<{'armhf': 'y'}> +CONFIG_CPU_TLB_V7 policy<{'armhf': 'y'}> +CONFIG_CPU_V7 policy<{'armhf': 'y'}> +CONFIG_CRAMFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CRAMFS_BLOCKDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CRAMFS_MTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_CRASH_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRC16 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRC32 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRC32_BIT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CRC32_SARWATE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CRC32_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CRC32_SLICEBY4 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_CRC32_SLICEBY8 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRC4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRC64 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRC7 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRC8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRC_CCITT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRC_ITU_T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRC_T10DIF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CROSS_MEMORY_ATTACH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_CHARDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_DEBUGFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_ISHTP policy<{'amd64': 'm'}> +CONFIG_CROS_EC_LIGHTBAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_LPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_PROTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_CROS_EC_RPMSG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CROS_EC_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_SYSFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CROS_EC_VBC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CROS_KBD_LED_BACKLIGHT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_CROS_USBPD_LOGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CRYPTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_842 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ACOMP2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ADIANTUM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_AEAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_AEAD2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_AEGIS128 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_AEGIS128_SIMD policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_CRYPTO_AES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_AES_ARM policy<{'armhf': 'm'}> +CONFIG_CRYPTO_AES_ARM64 policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM64_BS policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM64_CE_BLK policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM64_CE_CCM policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM64_NEON_BLK policy<{'arm64': 'm'}> +CONFIG_CRYPTO_AES_ARM_BS policy<{'armhf': 'm'}> +CONFIG_CRYPTO_AES_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_AES_NI_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_AES_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_AES_TI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_AKCIPHER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_AKCIPHER2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ALGAPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ALGAPI2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ANSI_CPRNG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ANUBIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ARC4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_AUTHENC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_BLKCIPHER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_BLKCIPHER2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_BLOWFISH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_BLOWFISH_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_BLOWFISH_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAMELLIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAMELLIA_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAST5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CAST5_AVX_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAST6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CAST6_AVX_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CAST_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CBC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_CCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CFB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CHACHA20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CHACHA20POLY1305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CHACHA20_NEON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_CHACHA20_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CRC32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CRC32C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_CRC32C_INTEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CRYPTO_CRC32C_VPMSUM policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_CRC32_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_CRC32_PCLMUL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_CRC32_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_CRCT10DIF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_CRCT10DIF_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_CRCT10DIF_PCLMUL policy<{'amd64': 'm'}> +CONFIG_CRYPTO_CRCT10DIF_VPMSUM policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_CRYPTD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_CTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_CTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DEFLATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_CRYPTO_DES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_DES3_EDE_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_DES_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_DEV_ARTPEC6 policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_ATMEL_ECC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CRYPTO_DEV_ATMEL_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_ATMEL_SHA204A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CRYPTO_DEV_BCM_SPU policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_CAVIUM_ZIP policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_CCP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_CRYPTO_DEV_CCP_CRYPTO policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_CCP_DD policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_CCP_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_CRYPTO_DEV_CCREE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_CHELSIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_CHELSIO_TLS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_CPT policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_EXYNOS_RNG policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI policy<{'arm64': 'y'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG policy<{'arm64': 'n', 'armhf-generic': 'n'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD policy<{'arm64': '255', 'armhf-generic': '255'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD policy<{'arm64': '2048', 'armhf-generic': '2048'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_JR policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE policy<{'arm64': '9', 'armhf-generic': '9'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_GEODE policy<{'i386': 'm'}> +CONFIG_CRYPTO_DEV_HIFN_795X policy<{'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_HIFN_795X_RNG policy<{'armhf-generic': 'y'}> +CONFIG_CRYPTO_DEV_HISI_HPRE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_HISI_QM policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_HISI_SEC policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_HISI_SEC2 policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_HISI_ZIP policy<{'arm64': 'm'}> +CONFIG_CRYPTO_DEV_MARVELL_CESA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_DEV_MEDIATEK policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_MXS_DCP policy<{'arm64': 'n', 'armhf-generic': 'n'}> +CONFIG_CRYPTO_DEV_NITROX policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_NITROX_CNN55XX policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CRYPTO_DEV_NX policy<{'ppc64el': 'y'}> +CONFIG_CRYPTO_DEV_NX_COMPRESS policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_DEV_OMAP policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_OMAP_AES policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_OMAP_DES policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_OMAP_SHAM policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_PADLOCK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_CRYPTO_DEV_PADLOCK_AES policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_PADLOCK_SHA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_C3XXX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_C3XXXVF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_C62X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_C62XVF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_DH895xCC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QAT_DH895xCCVF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_DEV_QCE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_DEV_QCOM_RNG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_DEV_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_DEV_S5P policy<{'armhf': 'm'}> +CONFIG_CRYPTO_DEV_SAFEXCEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_CRYPTO_DEV_SAHARA policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_CRYPTO_DEV_SP_CCP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_CRYPTO_DEV_SP_PSP policy<{'amd64': 'y'}> +CONFIG_CRYPTO_DEV_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_DEV_VMX policy<{'ppc64el': 'y'}> +CONFIG_CRYPTO_DEV_VMX_ENCRYPT policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_DH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DRBG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DRBG_CTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DRBG_HASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DRBG_HMAC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_DRBG_MENU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ECB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_ECC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ECDH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ECHAINIV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ECRDSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ENGINE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ESSIV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_FCRYPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_GCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_GF128MUL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_GHASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_GHASH_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_GHASH_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL policy<{'amd64': 'm'}> +CONFIG_CRYPTO_GHASH_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_GLUE_HELPER_X86 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_HASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_HASH2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_HASH_INFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_HMAC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_HW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_JITTERENTROPY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_KEYWRAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_KHAZAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_KPP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_KPP2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_LIB_AES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_LIB_ARC4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_LIB_DES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_LIB_SHA256 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_LRW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_LZ4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_LZ4HC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_MANAGER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_MANAGER2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_MD4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_MD5 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_MD5_PPC policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_MICHAEL_MIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_NHPOLY1305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_NHPOLY1305_AVX2 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_NHPOLY1305_NEON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_CRYPTO_NHPOLY1305_SSE2 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_NULL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_NULL2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_OFB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_PAES_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_PCBC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_PCRYPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_POLY1305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_POLY1305_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_RMD128 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_RMD160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_RMD256 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_RMD320 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_RNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_RNG2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_RNG_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_RSA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_SALSA20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SEED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SEQIV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_SERPENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SERPENT_AVX2_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SERPENT_AVX_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SERPENT_SSE2_586 policy<{'i386': 'm'}> +CONFIG_CRYPTO_SERPENT_SSE2_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SHA1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_SHA1_ARM policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA1_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA1_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA1_ARM_NEON policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA1_PPC policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_SHA1_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_SHA1_SSSE3 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SHA256 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_SHA256_ARM policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA256_ARM64 policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA256_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_SHA256_SSSE3 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SHA2_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA2_ARM_CE policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SHA3_256_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_SHA3_512_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_SHA3_ARM64 policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA512_ARM policy<{'armhf': 'm'}> +CONFIG_CRYPTO_SHA512_ARM64 policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA512_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SHA512_S390 policy<{'s390x': 'm'}> +CONFIG_CRYPTO_SHA512_SSSE3 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_SIMD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CRYPTO_SM3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SM3_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_SM4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_SM4_ARM64_CE policy<{'arm64': 'm'}> +CONFIG_CRYPTO_STATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_STREEBOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TEA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TGR192 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TWOFISH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TWOFISH_586 policy<{'i386': 'm'}> +CONFIG_CRYPTO_TWOFISH_AVX_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_TWOFISH_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_TWOFISH_X86_64 policy<{'amd64': 'm'}> +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY policy<{'amd64': 'm'}> +CONFIG_CRYPTO_USER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_USER_API policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_USER_API_AEAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_USER_API_HASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_USER_API_RNG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_USER_API_SKCIPHER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_VMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_VPMSUM_TESTER policy<{'ppc64el': 'm'}> +CONFIG_CRYPTO_WP512 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_XCBC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_XTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_CRYPTO_XXHASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CRYPTO_ZSTD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CS89x0 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_CS89x0_PLATFORM policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_CTCM policy<{'s390x': 'm'}> +CONFIG_CUSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_CW1200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CW1200_WLAN_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CW1200_WLAN_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CXD2880_SPI_DRV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CXL policy<{'ppc64el': 'm'}> +CONFIG_CXLFLASH policy<{'ppc64el': 'm'}> +CONFIG_CXL_AFU_DRIVER_OPS policy<{'ppc64el': 'y'}> +CONFIG_CXL_BASE policy<{'ppc64el': 'y'}> +CONFIG_CXL_LIB policy<{'ppc64el': 'y'}> +CONFIG_CX_ECAT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_CYCLADES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CYPRESS_FIRMWARE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_CYZ_INTR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DA280 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA311 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA9052_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA9055_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA9062_THERMAL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DA9062_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA9063_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DA9150_GPADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DASD policy<{'s390x': 'm'}> +CONFIG_DASD_DIAG policy<{'s390x': 'm'}> +CONFIG_DASD_ECKD policy<{'s390x': 'm'}> +CONFIG_DASD_EER policy<{'s390x': 'y'}> +CONFIG_DASD_FBA policy<{'s390x': 'm'}> +CONFIG_DASD_PROFILE policy<{'s390x': 'y'}> +CONFIG_DATA_SHIFT policy<{'ppc64el': '16'}> +CONFIG_DAVICOM_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DAX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DAX_DRIVER policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DCA policy<{'amd64': 'm'}> +CONFIG_DCACHE_WORD_ACCESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DCDBAS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DCSSBLK policy<{'s390x': 'm'}> +CONFIG_DDR policy<{'armhf': 'y'}> +CONFIG_DE2104X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DE2104X_DSL policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_DE4X5 policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DEBUGGER policy<{'ppc64el': 'y'}> +CONFIG_DEBUG_ALIGN_RODATA policy<{'arm64': 'n', 'armhf': 'y'}> +CONFIG_DEBUG_ATOMIC_SLEEP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_BLOCK_EXT_DEVT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_BOOT_PARAMS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DEBUG_BUGVERBOSE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_CREDENTIALS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_DEVRES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_DRIVER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_EFI policy<{'arm64': 'n'}> +CONFIG_DEBUG_ENTRY policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DEBUG_FORCE_WEAK_PER_CPU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_GPIO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_HIGHMEM policy<{'armhf': 'n', 'i386': 'n'}> +CONFIG_DEBUG_HOTPLUG_CPU0 policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DEBUG_INFO_BTF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_INFO_DWARF4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_INFO_REDUCED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_KERNEL_DC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DEBUG_KMEMLEAK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_KOBJECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_LIST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_LL policy<{'armhf': 'n'}> +CONFIG_DEBUG_LL_INCLUDE policy<{'armhf': '"mach/debug-macro.S"'}> +CONFIG_DEBUG_LOCKING_API_SELFTESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_LOCK_ALLOC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_MEMORY_INIT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_MISC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEBUG_MUTEXES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_NMI_SELFTEST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DEBUG_NOTIFIERS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_OBJECTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PAGEALLOC policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PAGE_REF policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PERF_USE_VMALLOC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PER_CPU_MAPS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PINCTRL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DEBUG_PLIST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_PREEMPT policy<{'amd64-lowlatency': 'n', 'i386-lowlatency': 'n'}> +CONFIG_DEBUG_RODATA_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_DEBUG_RSEQ policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_RT_MUTEXES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_RWSEMS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_SECTION_MISMATCH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_SG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_SHIRQ policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_SPINLOCK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_STACKOVERFLOW policy<{'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DEBUG_STACK_USAGE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_TEST_DRIVER_REMOVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_TIMEKEEPING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_TLBFLUSH policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DEBUG_USER policy<{'armhf': 'n'}> +CONFIG_DEBUG_VF_UART_PORT policy<{'armhf-generic': '1'}> +CONFIG_DEBUG_VIRTUAL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DEBUG_VM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_WQ_FORCE_RR_CPU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_WW_MUTEX_SLOWPATH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEBUG_WX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_DECOMPRESS_BZIP2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DECOMPRESS_GZIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DECOMPRESS_LZ4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DECOMPRESS_LZMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DECOMPRESS_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DECOMPRESS_XZ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEFAULT_CUBIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEFAULT_HOSTNAME policy<{'amd64': '"(none)"', 'arm64': '"(none)"', 'armhf': '"(none)"', 'i386': '"(none)"', 'ppc64el': '"(none)"', 's390x': '"(none)"'}> +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT policy<{'amd64': '120', 'arm64': '120', 'armhf': '120', 'i386': '120', 'ppc64el': '120', 's390x': '120'}> +CONFIG_DEFAULT_RENO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFAULT_SECURITY_APPARMOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEFAULT_SECURITY_DAC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFAULT_SECURITY_SELINUX policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFAULT_SECURITY_SMACK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFAULT_SECURITY_TOMOYO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFAULT_TCP_CONG policy<{'amd64': '"cubic"', 'arm64': '"cubic"', 'armhf': '"cubic"', 'i386': '"cubic"', 'ppc64el': '"cubic"', 's390x': '"cubic"'}> +CONFIG_DEFERRED_STRUCT_PAGE_INIT policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DEFXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DEFXX_MMIO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DELL_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_RBTN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_RBU policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_SMBIOS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_SMBIOS_SMM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DELL_SMBIOS_WMI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DELL_SMO8800 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_UART_BACKLIGHT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_WMI_AIO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_WMI_DESCRIPTOR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DELL_WMI_LED policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DEPRECATED_PARAM_STRUCT policy<{'armhf': 'n'}> +CONFIG_DETECT_HUNG_TASK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP policy<{'armhf': 'y'}> +CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU policy<{'armhf': 'y'}> +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DEVFREQ_GOV_PASSIVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVFREQ_GOV_PERFORMANCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVFREQ_GOV_POWERSAVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVFREQ_GOV_USERSPACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVFREQ_THERMAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEVICE_PRIVATE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_DEVMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEVPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DEV_APPLETALK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DEV_COREDUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DEV_DAX policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DEV_DAX_KMEM policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DEV_DAX_PMEM policy<{'amd64': 'm', 'ppc64el': 'm'}> +CONFIG_DEV_DAX_PMEM_COMPAT policy<{'amd64': 'm', 'ppc64el': 'm'}> +CONFIG_DEV_PAGEMAP_OPS policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_DHT11 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DIAG288_WATCHDOG policy<{'s390x': 'm'}> +CONFIG_DIMLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DL2K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DLCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DLCI_MAX policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_DLM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DLM_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DLN2_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DM9000 policy<{'armhf': 'm'}> +CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL policy<{'armhf': 'n'}> +CONFIG_DM9102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DMABUF_SELFTESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DMADEVICES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_DMADEVICES_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DMARD06 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DMARD09 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DMARD10 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DMAR_TABLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DMATEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DMA_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_DMA_API_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DMA_BCM2835 policy<{'arm64': 'y'}> +CONFIG_DMA_DECLARE_COHERENT policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DMA_DIRECT_REMAP policy<{'arm64': 'y'}> +CONFIG_DMA_ENGINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DMA_ENGINE_RAID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}> +CONFIG_DMA_FENCE_TRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DMA_OF policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DMA_OMAP policy<{'armhf': 'y'}> +CONFIG_DMA_REMAP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DMA_SHARED_BUFFER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DMA_SUN6I policy<{'arm64': 'm'}> +CONFIG_DMA_VIRTUAL_CHANNELS policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DMA_VIRT_OPS policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_DMIID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DMI_SYSFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_DM_BIO_PRISON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_BUFIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_CACHE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_CACHE_SMQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_CLONE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_CRYPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DM_DELAY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_DUST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DM_ERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_FLAKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_INIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DM_INTEGRITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_LOG_USERSPACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_LOG_WRITES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_MIRROR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_MULTIPATH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_MULTIPATH_QL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_MULTIPATH_ST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_PERSISTENT_DATA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_RAID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_SNAPSHOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_SWITCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_THIN_PROVISIONING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_UEVENT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DM_UNSTRIPED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_VERITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_VERITY_FEC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DM_WRITECACHE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_ZERO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DM_ZONED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DNOTIFY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DNS_RESOLVER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DOUBLEFAULT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DOVE_CLK policy<{'armhf': 'y'}> +CONFIG_DOVE_THERMAL policy<{'armhf': 'm'}> +CONFIG_DP83640_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DP83822_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DP83848_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DP83867_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DP83TC811_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DPAA2_CONSOLE policy<{'arm64': 'm'}> +CONFIG_DPAA_ERRATUM_A050385 policy<{'arm64': 'y'}> +CONFIG_DPM_WATCHDOG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DPOT_DAC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DPS310 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DPTF_POWER policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DQL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRA752_THERMAL policy<{'armhf': 'y'}> +CONFIG_DRAGONRISE_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRBD_FAULT_INJECTION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DRM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_AMDGPU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_AMDGPU_GART_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DRM_AMDGPU_SI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_AMDGPU_USERPTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_AMD_ACP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_AMD_DC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_AMD_DC_DCN1_0 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_AMD_DC_DCN2_0 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_AMD_DC_DCN2_1 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_AMD_DC_DSC_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_ANALOGIX_ANX78XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_ANALOGIX_DP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_ARCPGU policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_ARMADA policy<{'armhf': 'm'}> +CONFIG_DRM_ASPEED_GFX policy<{'armhf': 'm'}> +CONFIG_DRM_AST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_ATMEL_HLCDC policy<{'armhf': 'm'}> +CONFIG_DRM_BRIDGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_CDNS_DSI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_CIRRUS_QEMU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_DEBUG_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DRM_DP_AUX_CHARDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_DRM_DP_CEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_DRM_DUMB_VGA_DAC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_DW_HDMI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_DW_HDMI_AHB_AUDIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_DW_HDMI_CEC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_DW_HDMI_I2S_AUDIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_DW_MIPI_DSI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_ETNAVIV policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'm', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DRM_ETNAVIV_THERMAL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_EXYNOS policy<{'armhf': 'm'}> +CONFIG_DRM_EXYNOS5433_DECON policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS7_DECON policy<{'armhf': 'n'}> +CONFIG_DRM_EXYNOS_DSI policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_FIMC policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_FIMD policy<{'armhf': 'n'}> +CONFIG_DRM_EXYNOS_HDMI policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_IPP policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_MIC policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_MIXER policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_ROTATOR policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_SCALER policy<{'armhf': 'y'}> +CONFIG_DRM_EXYNOS_VIDI policy<{'armhf': 'n'}> +CONFIG_DRM_FBDEV_EMULATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_DRM_FBDEV_OVERALLOC policy<{'amd64': '100', 'arm64': '100', 'armhf': '100', 'i386': '100', 'ppc64el': '100', 's390x': '100'}> +CONFIG_DRM_FSL_DCU policy<{'armhf': 'm'}> +CONFIG_DRM_GEM_CMA_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_GEM_SHMEM_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_GM12U320 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_GMA3600 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_GMA500 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DRM_GMA600 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_HDLCD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_HDLCD_SHOW_UNDERRUN policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_DRM_HISI_KIRIN policy<{'arm64': 'm'}> +CONFIG_DRM_I2C_ADV7511 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_I2C_ADV7511_AUDIO policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_I2C_ADV7511_CEC policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_I2C_ADV7533 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_I2C_CH7006 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_I2C_NXP_TDA9950 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_I2C_NXP_TDA998X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_I2C_SIL164 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_I915 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DRM_I915_ALPHA_SUPPORT policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_CAPTURE_ERROR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_I915_COMPRESS_ERROR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_I915_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_DEBUG_GUC policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_DEBUG_MMIO policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_DEBUG_RUNTIME_PM policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_DEBUG_VBLANK_EVADE policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_FORCE_PROBE policy<{'amd64': '""', 'i386': '""'}> +CONFIG_DRM_I915_GVT policy<{'amd64': 'y'}> +CONFIG_DRM_I915_GVT_KVMGT policy<{'amd64': 'm'}> +CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_SELFTEST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_SPIN_REQUEST policy<{'amd64': '5', 'i386': '5'}> +CONFIG_DRM_I915_SW_FENCE_CHECK_DAG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND policy<{'amd64': '250', 'i386': '250'}> +CONFIG_DRM_I915_USERPTR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_I915_WERROR policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_DRM_IMX policy<{'armhf': 'm'}> +CONFIG_DRM_IMX_HDMI policy<{'armhf': 'm'}> +CONFIG_DRM_IMX_LDB policy<{'armhf': 'm'}> +CONFIG_DRM_IMX_PARALLEL_DISPLAY policy<{'armhf': 'm'}> +CONFIG_DRM_IMX_TVE policy<{'armhf': 'm'}> +CONFIG_DRM_KMS_CMA_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_KMS_FB_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_KMS_HELPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_KOMEDA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_LIMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_LOAD_EDID_FIRMWARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_LVDS_ENCODER policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_MALI_DISPLAY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MCDE policy<{'armhf': 'm'}> +CONFIG_DRM_MEDFIELD policy<{'i386': 'y'}> +CONFIG_DRM_MEDIATEK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MEDIATEK_HDMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MESON_DW_HDMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MIPI_DBI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_MIPI_DSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_MSM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_MSM_DSI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_10NM_PHY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_14NM_PHY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_20NM_PHY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_28NM_8960_PHY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_28NM_PHY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_DSI_PLL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_GPU_STATE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_GPU_SUDO policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_DRM_MSM_HDMI_HDCP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_MSM_REGISTER_LOGGING policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_DRM_MXS policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_DRM_MXSFB policy<{'arm64': 'm', 'armhf-generic': 'm', 'armhf-generic-lpae': '-'}> +CONFIG_DRM_NOUVEAU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_NOUVEAU_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DRM_NOUVEAU_SVM policy<{'amd64': 'n', 'ppc64el': 'n'}> +CONFIG_DRM_NXP_PTN3460 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_OMAP policy<{'armhf': 'n'}> +CONFIG_DRM_PANEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_PANEL_ARM_VERSATILE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_BRIDGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_ILITEK_IL9322 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_ILITEK_ILI9881C policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_INNOLUX_P079ZCA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_JDI_LT070ME05000 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_LG_LB035Q02 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_LG_LG4573 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_LVDS policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_NEC_NL8048HL11 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_NOVATEK_NT39016 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_ORIENTATION_QUIRKS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_PANEL_ORISETECH_OTM8009A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_RAYDIUM_RM67191 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_RAYDIUM_RM68200 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_RONBO_RB070D30 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_LD9040 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SEIKO_43WVF1G policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SHARP_LS037V7DW01 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SHARP_LS043T1LE01 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SIMPLE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SITRONIX_ST7701 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SITRONIX_ST7789V policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_SONY_ACX565AKM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_TPO_TD028TTEC1 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_TPO_TD043MTEA1 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_TPO_TPG110 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PANFROST policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_PARADE_PS8622 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_PL111 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_QXL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_RADEON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_RADEON_USERPTR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DRM_RCAR_DU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_RCAR_DW_HDMI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_RCAR_LVDS policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n'}> +CONFIG_DRM_RCAR_VSP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DRM_RCAR_WRITEBACK policy<{'arm64': 'y'}> +CONFIG_DRM_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DRM_SCHED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_SII902X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_SII9234 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_SIL_SII8620 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_STM policy<{'armhf': 'm'}> +CONFIG_DRM_STM_DSI policy<{'armhf': 'm'}> +CONFIG_DRM_SUN4I policy<{'arm64': 'm'}> +CONFIG_DRM_SUN4I_BACKEND policy<{'arm64': 'm'}> +CONFIG_DRM_SUN4I_HDMI policy<{'arm64': 'm'}> +CONFIG_DRM_SUN4I_HDMI_CEC policy<{'arm64': 'y'}> +CONFIG_DRM_SUN6I_DSI policy<{'arm64': 'm'}> +CONFIG_DRM_SUN8I_DW_HDMI policy<{'arm64': 'm'}> +CONFIG_DRM_SUN8I_MIXER policy<{'arm64': 'm'}> +CONFIG_DRM_SUN8I_TCON_TOP policy<{'arm64': 'm'}> +CONFIG_DRM_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_DRM_TEGRA_DEBUG policy<{'armhf-generic': 'n'}> +CONFIG_DRM_TEGRA_STAGING policy<{'armhf-generic': 'y'}> +CONFIG_DRM_THINE_THC63LVD1024 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_TILCDC policy<{'armhf': 'm'}> +CONFIG_DRM_TI_SN65DSI86 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_TI_TFP410 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_TOSHIBA_TC358764 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_TOSHIBA_TC358767 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_TTM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_TVE200 policy<{'armhf': 'm'}> +CONFIG_DRM_UDL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DRM_VC4 policy<{'arm64': 'm'}> +CONFIG_DRM_VC4_HDMI_CEC policy<{'arm64': 'y'}> +CONFIG_DRM_VGEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_VIRTIO_GPU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_VKMS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DRM_VMWGFX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_DRM_VMWGFX_FBCON policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_DRM_VRAM_HELPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DRM_XEN policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_DRM_XEN_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_DS1682 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DS1803 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DS4424 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DST_CACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DTC policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_DTL policy<{'ppc64el': 'y'}> +CONFIG_DTLK policy<{'i386': 'm'}> +CONFIG_DT_IDLE_STATES policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DUMMY_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DUMMY_CONSOLE_COLUMNS policy<{'amd64': '80', 'arm64': '80', 'i386': '80', 'ppc64el': '80', 's390x': '80'}> +CONFIG_DUMMY_CONSOLE_ROWS policy<{'amd64': '25', 'arm64': '25', 'i386': '25', 'ppc64el': '25', 's390x': '25'}> +CONFIG_DUMMY_IRQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DVB_A8293 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AF9013 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AF9033 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AS102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AS102_FE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ASCOT2E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ATBM8830 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AU8522 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AU8522_DTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AU8522_V4L policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AV7110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_AV7110_IR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_AV7110_OSD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_B2C2_FLEXCOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_B2C2_FLEXCOP_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_B2C2_FLEXCOP_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_BCM3510 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BT8XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BUDGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BUDGET_AV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BUDGET_CI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BUDGET_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_BUDGET_PATCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_C8SECTPFE policy<{'armhf': 'n'}> +CONFIG_DVB_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX22700 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX22702 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX24110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX24116 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX24117 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX24120 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CX24123 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CXD2099 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CXD2820R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CXD2841ER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_CXD2880 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DDBRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DDBRIDGE_MSIENABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_DEMUX_SECTION_LOSS_LOG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_DIB3000MB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DIB3000MC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DIB7000M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DIB7000P policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DIB8000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DIB9000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DM1105 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DRX39XYJ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DRXD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DRXK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DS3000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_DYNAMIC_MINORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_EC100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_FIREDTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_FIREDTV_INPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_GP8PSK_FE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_HELENE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_HOPPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_HORUS3A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ISL6405 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ISL6421 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ISL6423 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_IX2505V policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_L64781 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LG2160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LGDT3305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LGDT3306A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LGDT330X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LGS8GL5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LGS8GXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LNBH25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LNBH29 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LNBP21 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_LNBP22 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_M88DS3103 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_M88RS2000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MANTIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MAX_ADAPTERS policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_DVB_MB86A16 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MB86A20S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MMAP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_MN88443X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MN88472 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MN88473 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MT312 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MT352 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_MXL5XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_NET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_NETUP_UNIDVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_NGENE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_NXT200X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_NXT6000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_OR51132 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_OR51211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_PLATFORM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_PLL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_PLUTO2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_PT1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_PT3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_RTL2830 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_RTL2832 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_RTL2832_SDR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_S5H1409 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_S5H1411 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_S5H1420 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_S5H1432 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_S921 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SI2165 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SI2168 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SI21XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SMIPCIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SP2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SP8870 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_SP887X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STB0899 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STB6000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STB6100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0288 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0297 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0299 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0367 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0900 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV090x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV0910 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV6110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV6110x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_STV6111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TC90522 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA10021 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA10023 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA10048 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA1004X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA10071 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA10086 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA18271C2DD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA665x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA8083 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA8261 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TDA826X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TS2020 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TTUSB_BUDGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TTUSB_DEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TUA6100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TUNER_CX24113 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TUNER_DIB0070 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TUNER_DIB0090 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_TUNER_ITD1000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ULE_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_A800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AF9005 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AF9005_REMOTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AF9015 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AF9035 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_ANYSEE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AU6610 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AZ6007 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_AZ6027 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_CE6230 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_CINERGY_T2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_CXUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_CXUSB_ANALOG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_DVB_USB_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_USB_DIB0700 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DIB3000MC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DIBUSB_MB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DIBUSB_MB_FAULTY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_DVB_USB_DIBUSB_MC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DIGITV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DTT200U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DTV5100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DVBSKY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_DW2102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_EC168 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_GL861 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_GP8PSK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_LME2510 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_M920X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_MXL111SF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_NOVA_T_USB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_OPERA1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_PCTV452E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_RTL28XXU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_TECHNISAT_USB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_TTUSB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_UMT_010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_V2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_VP702X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_VP7045 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_USB_ZD1301 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_VES1820 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_VES1X93 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ZD1301_DEMOD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ZL10036 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ZL10039 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DVB_ZL10353 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DWC_XLGMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DWC_XLGMAC_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_DWMAC_DWC_QOS_ETH policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DWMAC_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DWMAC_IPQ806X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DWMAC_MEDIATEK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DWMAC_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DWMAC_QCOM_ETHQOS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DWMAC_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_DWMAC_SOCFPGA policy<{'arm64': 'm'}> +CONFIG_DWMAC_SUN8I policy<{'arm64': 'm'}> +CONFIG_DWMAC_SUNXI policy<{'arm64': 'n'}> +CONFIG_DW_APB_ICTL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DW_APB_TIMER policy<{'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_DW_APB_TIMER_OF policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_DW_AXI_DMAC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_DW_DMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_DMAC_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_DMAC_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_EDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_EDMA_PCIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_I3C_MASTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_DW_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_DYNAMIC_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DYNAMIC_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DYNAMIC_FTRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DYNAMIC_FTRACE_WITH_REGS policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_DYNAMIC_MEMORY_LAYOUT policy<{'amd64': 'y'}> +CONFIG_DYNAMIC_PHYSICAL_MASK policy<{'amd64': 'y'}> +CONFIG_E100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_E1000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_E1000E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_E1000E_HWTS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EADM_SCH policy<{'s390x': 'm'}> +CONFIG_EARLY_PRINTK policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EARLY_PRINTK_DBGP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EARLY_PRINTK_USB policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EARLY_PRINTK_USB_XDBC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EBC_C384_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ECHO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ECRYPT_FS_MESSAGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EDAC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_EDAC_ALTERA policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_ETHERNET policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_NAND policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_OCRAM policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_QSPI policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_SDMMC policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_SDRAM policy<{'arm64': 'y'}> +CONFIG_EDAC_ALTERA_USB policy<{'arm64': 'y'}> +CONFIG_EDAC_AMD64 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_AMD64_ERROR_INJECTION policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_EDAC_AMD76X policy<{'i386': 'm'}> +CONFIG_EDAC_ARMADA_XP policy<{'armhf': 'y'}> +CONFIG_EDAC_ATOMIC_SCRUB policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_EDAC_BLUEFIELD policy<{'arm64': 'm'}> +CONFIG_EDAC_CPC925 policy<{'ppc64el': 'm'}> +CONFIG_EDAC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_EDAC_DECODE_MCE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_E752X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_E7XXX policy<{'i386': 'm'}> +CONFIG_EDAC_GHES policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_EDAC_HIGHBANK_L2 policy<{'armhf': 'm'}> +CONFIG_EDAC_HIGHBANK_MC policy<{'armhf': 'm'}> +CONFIG_EDAC_I10NM policy<{'amd64': 'm'}> +CONFIG_EDAC_I3000 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I3200 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I5000 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I5100 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I5400 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I7300 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I7CORE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_I82860 policy<{'i386': 'm'}> +CONFIG_EDAC_I82875P policy<{'i386': 'm'}> +CONFIG_EDAC_I82975X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_IE31200 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_LAYERSCAPE policy<{'arm64': 'm'}> +CONFIG_EDAC_LEGACY_SYSFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_EDAC_PND2 policy<{'amd64': 'm'}> +CONFIG_EDAC_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_EDAC_R82600 policy<{'i386': 'm'}> +CONFIG_EDAC_SBRIDGE policy<{'amd64': 'm'}> +CONFIG_EDAC_SKX policy<{'amd64': 'm'}> +CONFIG_EDAC_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_EDAC_SYNOPSYS policy<{'arm64': 'm'}> +CONFIG_EDAC_THUNDERX policy<{'arm64': 'm'}> +CONFIG_EDAC_TI policy<{'armhf': 'm'}> +CONFIG_EDAC_X38 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EDAC_XGENE policy<{'arm64': 'm'}> +CONFIG_EDD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EDD_OFF policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EEEPC_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EEEPC_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EEH policy<{'ppc64el': 'y'}> +CONFIG_EEPROM_93CX6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EEPROM_93XX46 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EEPROM_AT24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EEPROM_AT25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EEPROM_EE1004 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EEPROM_IDT_89HPESX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EEPROM_LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EEPROM_MAX6875 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EFI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFI_ARMSTUB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_EFI_ARMSTUB_DTB_LOADER policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_EFI_BOOTLOADER_CONTROL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_EFI_CAPSULE_LOADER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'y'}> +CONFIG_EFI_CAPSULE_QUIRK_QUARK_CSH policy<{'i386': 'y'}> +CONFIG_EFI_CUSTOM_SSDT_OVERLAYS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_EFI_DEV_PATH_PARSER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EFI_EARLYCON policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_EFI_ESRT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFI_FAKE_MEMMAP policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_EFI_MIXED policy<{'amd64': 'y'}> +CONFIG_EFI_PARAMS_FROM_FDT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_EFI_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EFI_PGT_DUMP policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_EFI_RCI2_TABLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EFI_RUNTIME_MAP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EFI_RUNTIME_WRAPPERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFI_STUB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_EFI_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_EFI_VARS_PSTORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_EFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EINT_MTK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_EISA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EISA_NAMES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EISA_PCI_EISA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EISA_VIRTUAL_ROOT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EISA_VLB_PRIMING policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_EL3 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ELFCORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ELF_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EMAC_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_EMBEDDED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_EM_TIMER_STI policy<{'armhf': 'y'}> +CONFIG_ENABLE_MUST_CHECK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ENA_ETHERNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ENC28J60 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ENC28J60_WRITEVERIFY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ENCLOSURE_SERVICES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ENCRYPTED_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ENCX24J600 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ENERGY_MODEL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ENIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ENVELOPE_DETECTOR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_EPAPR_BOOT policy<{'ppc64el': 'y'}> +CONFIG_EPAPR_PARAVIRT policy<{'ppc64el': 'y'}> +CONFIG_EPIC100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EPOLL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EQUALIZER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_EROFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1', 's390x': '1'}> +CONFIG_EROFS_FS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_EROFS_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EROFS_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EROFS_FS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EROFS_FS_ZIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ET131X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ETEXT_SHIFT policy<{'ppc64el': '16'}> +CONFIG_ETHERNET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ETHOC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_EUROTECH_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EVENTFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EVENT_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EVM_ADD_XATTRS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EVM_EXTRA_SMACK_XATTRS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXFAT_DEBUG_MSG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_EXFAT_DEFAULT_CODEPAGE policy<{'amd64': '437', 'arm64': '437', 'armhf': '437', 'i386': '437', 'ppc64el': '437'}> +CONFIG_EXFAT_DEFAULT_IOCHARSET policy<{'amd64': '"utf8"', 'arm64': '"utf8"', 'armhf': '"utf8"', 'i386': '"utf8"', 'ppc64el': '"utf8"'}> +CONFIG_EXFAT_DELAYED_SYNC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_EXFAT_DISCARD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_EXFAT_DONT_MOUNT_VFAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_EXFAT_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXFAT_KERNEL_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_EXPERT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXPOLINE policy<{'s390x': 'y'}> +CONFIG_EXPOLINE_AUTO policy<{'s390x': 'y'}> +CONFIG_EXPOLINE_FULL policy<{'s390x': 'n'}> +CONFIG_EXPOLINE_OFF policy<{'s390x': 'n'}> +CONFIG_EXPORTFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXPORTFS_BLOCK_OPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXT4_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_EXT4_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXT4_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXT4_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXT4_USE_FOR_EXT2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_EXTCON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_EXTCON_ADC_JACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_ARIZONA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_AXP288 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EXTCON_FSA9480 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_INTEL_CHT_WC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EXTCON_INTEL_INT3496 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_EXTCON_INTEL_MRFLD policy<{'i386': 'm'}> +CONFIG_EXTCON_MAX14577 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_MAX3355 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_MAX77693 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_MAX77843 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_MAX8997 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_PALMAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_PTN5150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_QCOM_SPMI_MISC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_EXTCON_RT8973A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_SM5502 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTCON_USBC_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_EXTCON_USB_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_EXTRA_FIRMWARE policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_EXTRA_TARGETS policy<{'ppc64el': '""'}> +CONFIG_EXYNOS_ADC policy<{'armhf': 'm'}> +CONFIG_EXYNOS_AUDSS_CLK_CON policy<{'armhf': 'm'}> +CONFIG_EXYNOS_CHIPID policy<{'armhf': 'y'}> +CONFIG_EXYNOS_CPU_SUSPEND policy<{'armhf': 'y'}> +CONFIG_EXYNOS_IOMMU policy<{'armhf': 'y'}> +CONFIG_EXYNOS_IOMMU_DEBUG policy<{'armhf': 'n'}> +CONFIG_EXYNOS_MCPM policy<{'armhf': 'y'}> +CONFIG_EXYNOS_PMU policy<{'armhf': 'y'}> +CONFIG_EXYNOS_PMU_ARM_DRIVERS policy<{'armhf': 'y'}> +CONFIG_EXYNOS_PM_DOMAINS policy<{'armhf': 'y'}> +CONFIG_EXYNOS_SROM policy<{'armhf': 'y'}> +CONFIG_EXYNOS_THERMAL policy<{'armhf': 'y'}> +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_EZX_PCAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_F2FS_CHECK_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_F2FS_FAULT_INJECTION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_F2FS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_F2FS_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_F2FS_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_F2FS_FS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_F2FS_IO_TRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_F2FS_STAT_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_F71808E_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FAILOVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FAIR_GROUP_SCHED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FANOTIFY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FANOTIFY_ACCESS_PERMISSIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FARSYNC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FAT_DEFAULT_CODEPAGE policy<{'amd64': '437', 'arm64': '437', 'armhf': '437', 'i386': '437', 'ppc64el': '437', 's390x': '437'}> +CONFIG_FAT_DEFAULT_IOCHARSET policy<{'amd64': '"iso8859-1"', 'arm64': '"iso8859-1"', 'armhf': '"iso8859-1"', 'i386': '"iso8859-1"', 'ppc64el': '"iso8859-1"', 's390x': '"iso8859-1"'}> +CONFIG_FAT_DEFAULT_UTF8 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FAT_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FAULT_INJECTION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FB_3DFX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_3DFX_ACCEL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_3DFX_I2C policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_ARC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_ARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_ARMCLCD policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_FB_ASILIANT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FB_ATY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_ATY128 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_ATY128_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_ATY_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_ATY_CT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_ATY_GENERIC_LCD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_ATY_GX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_BACKLIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_BOOT_VESA_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_FB_CARILLO_RANCH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_CARMINE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_CARMINE_DRAM_EVAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_CFB_COPYAREA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_FB_CFB_FILLRECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_FB_CFB_IMAGEBLIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_FB_CFB_REV_PIXELS_IN_BYTE policy<{'armhf-generic': 'y'}> +CONFIG_FB_CIRRUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_CMDLINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FB_CYBER2000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_CYBER2000_DDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_DA8XX policy<{'armhf-generic': 'm'}> +CONFIG_FB_DDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_DEFERRED_IO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FB_EFI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_FB_FOREIGN_ENDIAN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FB_GEODE policy<{'i386': 'y'}> +CONFIG_FB_GEODE_GX policy<{'i386': 'm'}> +CONFIG_FB_GEODE_GX1 policy<{'i386': 'm'}> +CONFIG_FB_GEODE_LX policy<{'i386': 'm'}> +CONFIG_FB_HECUBA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_HGA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_HYPERV policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_I740 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_I810 policy<{'i386': 'm'}> +CONFIG_FB_I810_GTF policy<{'i386': 'n'}> +CONFIG_FB_IBM_GXT4500 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FB_IMSTT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FB_IMX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_FB_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_INTEL_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_FB_INTEL_I2C policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_FB_KYRO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_LE80578 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_MACMODES policy<{'ppc64el': 'y'}> +CONFIG_FB_MATROX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_MATROX_G policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_MATROX_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_MATROX_MAVEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_MATROX_MILLENIUM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_MATROX_MYSTIQUE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_MB862XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_MB862XX_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_MB862XX_LIME policy<{'ppc64el': 'n'}> +CONFIG_FB_MB862XX_PCI_GDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_METRONOME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_MODE_HELPERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FB_MX3 policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_FB_N411 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_NEOMAGIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_NOTIFY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FB_NVIDIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_NVIDIA_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_NVIDIA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_NVIDIA_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_OF policy<{'ppc64el': 'y'}> +CONFIG_FB_OMAP2 policy<{'armhf': 'm'}> +CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_CONNECTOR_DVI policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_CONNECTOR_HDMI policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DEBUG_SUPPORT policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DSS policy<{'armhf': 'm'}> +CONFIG_FB_OMAP2_DSS_DEBUG policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DSS_DEBUGFS policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DSS_DPI policy<{'armhf': 'y'}> +CONFIG_FB_OMAP2_DSS_DSI policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DSS_HDMI_COMMON policy<{'armhf': 'y'}> +CONFIG_FB_OMAP2_DSS_INIT policy<{'armhf': 'y'}> +CONFIG_FB_OMAP2_DSS_MIN_FCK_PER_PCK policy<{'armhf': '0'}> +CONFIG_FB_OMAP2_DSS_SDI policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_DSS_SLEEP_AFTER_VENC_RESET policy<{'armhf': 'y'}> +CONFIG_FB_OMAP2_DSS_VENC policy<{'armhf': 'y'}> +CONFIG_FB_OMAP2_ENCODER_OPA362 policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_ENCODER_TFP410 policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_ENCODER_TPD12S015 policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_NUM_FBS policy<{'armhf': '3'}> +CONFIG_FB_OMAP2_PANEL_DPI policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_PANEL_DSI_CM policy<{'armhf': 'n'}> +CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02 policy<{'armhf': 'n'}> +CONFIG_FB_OMAP4_DSS_HDMI policy<{'armhf': 'y'}> +CONFIG_FB_OMAP5_DSS_HDMI policy<{'armhf': 'n'}> +CONFIG_FB_OPENCORES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_PM2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_PM2_FIFO_DISCONNECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_PM3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA policy<{'armhf': 'y'}> +CONFIG_FB_RADEON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_RADEON_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_RADEON_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_RADEON_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_RIVA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_RIVA_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_RIVA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_RIVA_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_S1D13XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_S3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_S3_DDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_SAVAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_SAVAGE_ACCEL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_FB_SAVAGE_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_SH_MOBILE_LCDC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_FB_SIMPLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FB_SIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_SIS_300 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_SIS_315 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FB_SM501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_SM712 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_SM750 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_SMSCUFX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_SSD1307 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_SVGALIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_SYS_COPYAREA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FB_SYS_FILLRECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FB_SYS_FOPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FB_SYS_IMAGEBLIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FB_TFT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_AGM1264K_FL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_BD663474 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_HX8340BN policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_HX8347D policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_HX8353D policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_HX8357D policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9163 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9320 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9325 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9340 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9341 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9481 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ILI9486 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_PCD8544 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_RA8875 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_S6D02A1 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_S6D1121 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SH1106 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SSD1289 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SSD1305 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SSD1306 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SSD1331 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_SSD1351 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ST7735R policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_ST7789V policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_TINYLCD policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_TLS8204 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_UC1611 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_UC1701 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_UPD161704 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TFT_WATTEROTT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FB_TILEBLITTING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FB_TMIO policy<{'armhf': 'm'}> +CONFIG_FB_TMIO_ACCELL policy<{'armhf': 'y'}> +CONFIG_FB_TRIDENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_UDL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_UVESA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_VESA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_FB_VGA16 policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FB_VIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FB_VIA_DIRECT_PROCFS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_FB_VIA_X_COMPATIBILITY policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_FB_VIRTUAL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FB_VOODOO1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_VT8623 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FB_XILINX policy<{'arm64': 'm'}> +CONFIG_FCOE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FCOE_FNIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FDDI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FEALNX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FEC policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_FIB_RULES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FIELDBUS_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FILE_LOCKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FIND_BIT_BENCHMARK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FIQ policy<{'armhf-generic': 'y'}> +CONFIG_FIREWIRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FIREWIRE_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FIREWIRE_NOSY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FIREWIRE_OHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FIREWIRE_SBP2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FIREWIRE_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FIRMWARE_EDID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FIRMWARE_MEMMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_FIXED_PHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_FIX_EARLYCON_MEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_FLATMEM policy<{'armhf': 'y'}> +CONFIG_FLATMEM_MANUAL policy<{'i386': 'n'}> +CONFIG_FLAT_NODE_MEM_MAP policy<{'armhf': 'y'}> +CONFIG_FM10K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FONTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_10x18 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_6x10 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_6x11 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_7x14 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_8x16 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_8x8 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_ACORN_8x8 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_MINI_4x6 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_PEARL_8x8 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_SUN12x22 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_SUN8x16 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FONT_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FONT_TER16x32 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FORCEDETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FORCE_DYNAMIC_FTRACE policy<{'i386': 'y'}> +CONFIG_FORCE_MAX_ZONEORDER policy<{'arm64': '13', 'armhf-generic': '12', 'armhf-generic-lpae': '11', 'ppc64el': '9', 's390x': '9'}> +CONFIG_FORCE_PCI policy<{'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_FORCE_SMP policy<{'ppc64el': 'y'}> +CONFIG_FORTIFY_SOURCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FPGA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FPGA_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FPGA_DFL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_FPGA_DFL_AFU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_DFL_FME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_DFL_FME_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_DFL_FME_MGR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_DFL_FME_REGION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_DFL_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_MGR_ALTERA_CVP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FPGA_MGR_ALTERA_PS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_MGR_ICE40_SPI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_MGR_MACHXO2_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_MGR_STRATIX10_SOC policy<{'arm64': 'm'}> +CONFIG_FPGA_MGR_XILINX_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FPGA_MGR_ZYNQMP_FPGA policy<{'arm64': 'm'}> +CONFIG_FPGA_REGION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FRAMEBUFFER_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FRAME_POINTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_FRAME_VECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FRAME_WARN policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'i386': '1024', 'ppc64el': '2048', 's390x': '1024'}> +CONFIG_FREEZER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FRONTSWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FSCACHE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_FSCACHE_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FSCACHE_HISTOGRAM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FSCACHE_OBJECT_LIST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FSCACHE_STATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FSI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSI_MASTER_AST_CF policy<{'armhf': 'm'}> +CONFIG_FSI_MASTER_GPIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSI_MASTER_HUB policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSI_NEW_DEV_NODE policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}> +CONFIG_FSI_OCC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSI_SBEFIFO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSI_SCOM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSL_BMAN_TEST policy<{'arm64': 'm'}> +CONFIG_FSL_BMAN_TEST_API policy<{'arm64': 'n'}> +CONFIG_FSL_DPAA policy<{'arm64': 'y'}> +CONFIG_FSL_DPAA2 policy<{'arm64': 'y'}> +CONFIG_FSL_DPAA2_ETH policy<{'arm64': 'm'}> +CONFIG_FSL_DPAA2_ETHSW policy<{'arm64': 'm'}> +CONFIG_FSL_DPAA2_PTP_CLOCK policy<{'arm64': 'm'}> +CONFIG_FSL_DPAA_CHECKING policy<{'arm64': 'y'}> +CONFIG_FSL_DPAA_ETH policy<{'arm64': 'm'}> +CONFIG_FSL_EDMA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FSL_ENETC policy<{'arm64': 'm'}> +CONFIG_FSL_ENETC_HW_TIMESTAMPING policy<{'arm64': 'y'}> +CONFIG_FSL_ENETC_MDIO policy<{'arm64': 'm'}> +CONFIG_FSL_ENETC_PTP_CLOCK policy<{'arm64': 'm'}> +CONFIG_FSL_ENETC_VF policy<{'arm64': 'm'}> +CONFIG_FSL_ERRATUM_A008585 policy<{'arm64': 'y'}> +CONFIG_FSL_FMAN policy<{'arm64': 'y'}> +CONFIG_FSL_GUTS policy<{'arm64': 'y', 'armhf-generic': 'y', 'ppc64el': 'y'}> +CONFIG_FSL_IFC policy<{'arm64': 'y'}> +CONFIG_FSL_IMX8_DDR_PMU policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_FSL_LBC policy<{'ppc64el': 'y'}> +CONFIG_FSL_MC_BUS policy<{'arm64': 'y'}> +CONFIG_FSL_MC_DPIO policy<{'arm64': 'm'}> +CONFIG_FSL_PQ_MDIO policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_FSL_QDMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_FSL_QMAN_TEST policy<{'arm64': 'n'}> +CONFIG_FSL_XGMAC_MDIO policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_FSNOTIFY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_DAX policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_DAX_LIMITED policy<{'s390x': 'y'}> +CONFIG_FS_DAX_PMD policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_FS_ENCRYPTION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_IOMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_MBCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_VERITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_VERITY_BUILTIN_SIGNATURES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FS_VERITY_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FTGMAC100 policy<{'armhf': 'm'}> +CONFIG_FTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FTMAC100 policy<{'armhf': 'm'}> +CONFIG_FTM_QUADDEC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_FTRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FTRACE_MCOUNT_RECORD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FTRACE_STARTUP_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_FTRACE_SYSCALLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FTR_FIXUP_SELFTEST policy<{'ppc64el': 'n'}> +CONFIG_FTWDT010_WATCHDOG policy<{'armhf': 'm'}> +CONFIG_FUEL_GAUGE_SC27XX policy<{'arm64': 'm'}> +CONFIG_FUJITSU_ERRATUM_010001 policy<{'arm64': 'y'}> +CONFIG_FUJITSU_ES policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_FUJITSU_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FUJITSU_TABLET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_FUNCTION_ERROR_INJECTION policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FUNCTION_GRAPH_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FUNCTION_PROFILER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FUNCTION_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FUSION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_FUSION_CTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FUSION_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FUSION_LAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FUSION_LOGGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_FUSION_MAX_SGE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128'}> +CONFIG_FUSION_SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FUSION_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FUTEX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FUTEX_PI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FWTTY_MAX_CARD_PORTS policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32'}> +CONFIG_FWTTY_MAX_TOTAL_PORTS policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'i386': '64', 'ppc64el': '64'}> +CONFIG_FW_CFG_SYSFS policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_FW_CFG_SYSFS_CMDLINE policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_FW_LOADER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FW_LOADER_COMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FW_LOADER_PAGED_BUF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FW_LOADER_USER_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_FXAS21002C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FXAS21002C_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_FXAS21002C_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GACT_PROB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GADGET_UAC1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GADGET_UAC1_LEGACY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_GAMEPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GAMEPORT_EMU10K1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GAMEPORT_FM801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GAMEPORT_L4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GAMEPORT_NS558 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GARP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GART_IOMMU policy<{'amd64': 'y'}> +CONFIG_GCC_VERSION policy<{'amd64': '90400', 'arm64': '90400', 'armhf': '90400', 'i386': '90400', 'ppc64el': '90400', 's390x': '90400'}> +CONFIG_GCOV_KERNEL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_GDB_SCRIPTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GDS_FORCE_MITIGATION policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_GEMINI_ETHERNET policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GENERIC_ADC_BATTERY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GENERIC_ADC_THERMAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GENERIC_ALLOCATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_ARCH_TOPOLOGY policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GENERIC_BUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_BUG_RELATIVE_POINTERS policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}> +CONFIG_GENERIC_CALIBRATE_DELAY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_GENERIC_CLOCKEVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_GENERIC_CMOS_UPDATE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_CPU policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_CPU_AUTOPROBE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_CPU_VULNERABILITIES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_CSUM policy<{'arm64': 'y'}> +CONFIG_GENERIC_EARLY_IOREMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_GENERIC_FIND_FIRST_BIT policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_GENERIC_GETTIMEOFDAY policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_GENERIC_HWEIGHT policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_IDLE_POLL_SETUP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GENERIC_IOMAP policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_IRQ_CHIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_IRQ_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_GENERIC_IRQ_MIGRATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_IRQ_MULTI_HANDLER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GENERIC_IRQ_PROBE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_GENERIC_IRQ_RESERVATION_MODE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_GENERIC_IRQ_SHOW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_IRQ_SHOW_LEVEL policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_ISA_DMA policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_MSI_IRQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_MSI_IRQ_DOMAIN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_GENERIC_NET_UTILS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_PCI_IOMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_PENDING_IRQ policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_GENERIC_PHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_GENERIC_PHY_MIPI_DPHY policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_PINCONF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_PINCTRL_GROUPS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_PINMUX_FUNCTIONS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_SCHED_CLOCK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GENERIC_SMP_IDLE_THREAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_STRNCPY_FROM_USER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_STRNLEN_USER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GENERIC_TIME_VSYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GENERIC_VDSO_32 policy<{'i386': 'y'}> +CONFIG_GENEVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GENWQE policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY policy<{'amd64': '0', 'arm64': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_GEN_RTC policy<{'ppc64el': 'y'}> +CONFIG_GEOS policy<{'i386': 'y'}> +CONFIG_GFS2_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GFS2_FS_LOCKING_DLM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GIANFAR policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_GIGASET_BASE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GIGASET_CAPI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_GIGASET_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_GIGASET_M101 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GIGASET_M105 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GLOB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GLOB_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_GNSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GNSS_MTK_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GNSS_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GNSS_SIRF_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GNSS_UBX_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GOLDFISH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_GOOGLE_FIRMWARE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_GP2AP020A00F policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPD_POCKET_FAN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIOLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GPIOLIB_FASTPATH_LIMIT policy<{'amd64': '512', 'arm64': '512', 'armhf': '512', 'i386': '512', 'ppc64el': '512', 's390x': '512'}> +CONFIG_GPIOLIB_IRQCHIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GPIO_104_DIO_48E policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_104_IDIO_16 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_104_IDI_48 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_74X164 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_74XX_MMIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_GPIO_ADNP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ADP5520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ADP5588 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_ALTERA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_AMD8111 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_AMDPT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_GPIO_AMD_FCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_ARIZONA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ASPEED policy<{'armhf': 'm'}> +CONFIG_GPIO_BD70528 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_BD9571MWV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_GPIO_BT8XX policy<{'s390x': 'm'}> +CONFIG_GPIO_CADENCE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_CRYSTAL_COVE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_CS5535 policy<{'i386': 'm'}> +CONFIG_GPIO_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_DA9055 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_DAVINCI policy<{'arm64': 'y'}> +CONFIG_GPIO_DLN2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_DWAPB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_EIC_SPRD policy<{'arm64': 'm'}> +CONFIG_GPIO_EXAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_F7188X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_FTGPIO010 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_GENERIC policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_GPIO_GENERIC_PLATFORM policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GPIO_GPIO_MM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_GRGPIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_GW_PLD policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_HLWD policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ICH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_INTEL_MID policy<{'i386': 'y'}> +CONFIG_GPIO_IT87 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_JANZ_TTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_KEMPLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_LP3943 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_LP873X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_LP87565 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_LYNXPOINT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_GPIO_MADERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MAX3191X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MAX7300 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_MAX7301 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MAX730X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MAX732X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_MAX77620 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MAX77650 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MB86S7X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_MC33880 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MENZ127 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MERRIFIELD policy<{'i386': 'n'}> +CONFIG_GPIO_MLXBF policy<{'arm64': 'm'}> +CONFIG_GPIO_ML_IOH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_MOCKUP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_GPIO_MOXTET policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_MPC8XXX policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GPIO_MSIC policy<{'i386': 'y'}> +CONFIG_GPIO_MVEBU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GPIO_MXC policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_GPIO_OMAP policy<{'armhf': 'y'}> +CONFIG_GPIO_PALMAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_PCA953X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_PCF857X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_PCH policy<{'i386': 'm'}> +CONFIG_GPIO_PCIE_IDIO_24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GPIO_PCI_IDIO_16 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GPIO_PISOSR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_PL061 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_GPIO_PMIC_EIC_SPRD policy<{'arm64': 'm'}> +CONFIG_GPIO_RASPBERRYPI_EXP policy<{'arm64': 'm'}> +CONFIG_GPIO_RC5T583 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_GPIO_RDC321X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GPIO_SAMA5D2_PIOBU policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_SCH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_SCH311X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_SIOX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_SPRD policy<{'arm64': 'm'}> +CONFIG_GPIO_STMPE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_SYSCON policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GPIO_TC3589X policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_TEGRA policy<{'armhf-generic': 'y'}> +CONFIG_GPIO_THUNDERX policy<{'arm64': 'm'}> +CONFIG_GPIO_TIMBERDALE policy<{'i386': 'y'}> +CONFIG_GPIO_TPIC2810 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GPIO_TPS65086 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_TPS65218 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_TPS6586X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_TPS65910 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GPIO_TPS65912 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_TPS68470 policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_GPIO_TQMX86 policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_TS4800 policy<{'armhf-generic': 'm'}> +CONFIG_GPIO_TS4900 policy<{'armhf-generic': 'm'}> +CONFIG_GPIO_TWL6040 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_UCB1400 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_GPIO_VF610 policy<{'armhf-generic': 'y'}> +CONFIG_GPIO_VIPERBOARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_VX855 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_WHISKEY_COVE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_WINBOND policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_WM8350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_WM8994 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_WS16C48 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_GPIO_XGENE policy<{'arm64': 'y'}> +CONFIG_GPIO_XGENE_SB policy<{'arm64': 'm'}> +CONFIG_GPIO_XILINX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_GPIO_XLP policy<{'arm64': 'm'}> +CONFIG_GPIO_XRA1403 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GPIO_ZEVIO policy<{'armhf': 'y'}> +CONFIG_GPIO_ZYNQ policy<{'arm64': 'm'}> +CONFIG_GRACE_PERIOD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GREENASIA_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_GREYBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_GREYBUS_AUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_BOOTROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_BRIDGED_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_ES2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_FIRMWARE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_LIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_LOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_LOOPBACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_PWM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GREYBUS_VIBRATOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GRO_CELLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_GS_FPGABOOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_GTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_GUP_BENCHMARK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_GUP_GET_PTE_LOW_HIGH policy<{'i386': 'y'}> +CONFIG_GVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HABANA_AI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HALTPOLL_CPUIDLE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HAMACHI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HAMRADIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HANDLE_DOMAIN_IRQ policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HANGCHECK_TIMER policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_HAPPYMEAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HARDENED_USERCOPY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HARDENED_USERCOPY_FALLBACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HARDENED_USERCOPY_PAGESPAN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HARDEN_BRANCH_HISTORY policy<{'armhf': 'y'}> +CONFIG_HARDEN_BRANCH_PREDICTOR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HARDEN_EL2_VECTORS policy<{'arm64': 'y'}> +CONFIG_HARDIRQS_SW_RESEND policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_HARDLOCKUP_CHECK_TIMESTAMP policy<{'amd64': 'y'}> +CONFIG_HARDLOCKUP_DETECTOR policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HARDLOCKUP_DETECTOR_PERF policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAS_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAS_IOMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAS_IOPORT_MAP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_ACPI_APEI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HAVE_ACPI_APEI_NMI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_ALIGNED_STRUCT_PAGE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_AUDITSYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_BITREVERSE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES policy<{'amd64': 'y'}> +CONFIG_HAVE_ARCH_HUGE_VMAP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_ARCH_JUMP_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_KASAN policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_KASAN_SW_TAGS policy<{'arm64': 'y'}> +CONFIG_HAVE_ARCH_KGDB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_ARCH_MMAP_RND_BITS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_ARCH_NVRAM_OPS policy<{'ppc64el': 'y'}> +CONFIG_HAVE_ARCH_PFN_VALID policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HAVE_ARCH_PREL32_RELOCATIONS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HAVE_ARCH_SECCOMP_FILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_SOFT_DIRTY policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_STACKLEAK policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_HAVE_ARCH_TRACEHOOK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD policy<{'amd64': 'y'}> +CONFIG_HAVE_ARCH_VMAP_STACK policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}> +CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_ARM_ARCH_TIMER policy<{'armhf': 'y'}> +CONFIG_HAVE_ARM_SCU policy<{'armhf': 'y'}> +CONFIG_HAVE_ARM_SMCCC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HAVE_ARM_TWD policy<{'armhf': 'y'}> +CONFIG_HAVE_ASM_MODVERSIONS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_ATOMIC_IOMAP policy<{'i386': 'y'}> +CONFIG_HAVE_BOOTMEM_INFO_NODE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_CLK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_HAVE_CLK_PREPARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_HAVE_CMPXCHG_DOUBLE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_CMPXCHG_LOCAL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_CONTEXT_TRACKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_COPY_THREAD_TLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_C_RECORDMCOUNT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_DEBUG_BUGVERBOSE policy<{'arm64': 'y'}> +CONFIG_HAVE_DEBUG_KMEMLEAK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_DEBUG_STACKOVERFLOW policy<{'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_DMA_CONTIGUOUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_DYNAMIC_FTRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_EBPF_JIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_EISA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_EXIT_THREAD policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_HAVE_FAST_GUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_FENTRY policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_FTRACE_MCOUNT_RECORD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_FUNCTION_ARG_ACCESS_API policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HAVE_FUNCTION_ERROR_INJECTION policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_FUNCTION_GRAPH_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_FUNCTION_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_FUTEX_CMPXCHG policy<{'armhf': 'y', 's390x': 'y'}> +CONFIG_HAVE_GCC_PLUGINS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_GENERIC_VDSO policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_HARDLOCKUP_DETECTOR_ARCH policy<{'ppc64el': 'y'}> +CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_HW_BREAKPOINT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_IDE policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_IMA_KEXEC policy<{'ppc64el': 'y'}> +CONFIG_HAVE_IMX_ANATOP policy<{'armhf-generic': 'y'}> +CONFIG_HAVE_IMX_GPC policy<{'armhf-generic': 'y'}> +CONFIG_HAVE_IMX_MMDC policy<{'armhf-generic': 'y'}> +CONFIG_HAVE_IMX_SRC policy<{'armhf-generic': 'y'}> +CONFIG_HAVE_INTEL_TXT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_IOREMAP_PROT policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_IRQ_TIME_ACCOUNTING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_KERNEL_BZIP2 policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KERNEL_GZIP policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KERNEL_LZ4 policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KERNEL_LZMA policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KERNEL_LZO policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KERNEL_UNCOMPRESSED policy<{'s390x': 'y'}> +CONFIG_HAVE_KERNEL_XZ policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KPROBES_ON_FTRACE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KRETPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_ARCH_TLB_FLUSH_ALL policy<{'arm64': 'y', 'armhf-generic-lpae': 'y'}> +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_EVENTFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_INVALID_WAKEUPS policy<{'s390x': 'y'}> +CONFIG_HAVE_KVM_IRQCHIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_IRQFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_IRQ_BYPASS policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_KVM_IRQ_ROUTING policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_MSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y'}> +CONFIG_HAVE_KVM_NO_POLL policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL policy<{'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE policy<{'arm64': 'y'}> +CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION policy<{'ppc64el': 'y'}> +CONFIG_HAVE_LIVEPATCH policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_MARCH_Z10_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_Z13_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_Z196_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_Z900_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_Z990_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_Z9_109_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MARCH_ZEC12_FEATURES policy<{'s390x': 'y'}> +CONFIG_HAVE_MEMBLOCK_NODE_MAP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_MEMBLOCK_PHYS_MAP policy<{'s390x': 'y'}> +CONFIG_HAVE_MEMORYLESS_NODES policy<{'ppc64el': 'y'}> +CONFIG_HAVE_MEMORY_PRESENT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_MMIOTRACE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_MMU_GATHER_NO_GATHER policy<{'s390x': 'y'}> +CONFIG_HAVE_MMU_GATHER_PAGE_SIZE policy<{'ppc64el': 'y'}> +CONFIG_HAVE_MOD_ARCH_SPECIFIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_MOVE_PMD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_NET_DSA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_NMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_NMI_WATCHDOG policy<{'ppc64el': 'y'}> +CONFIG_HAVE_NOP_MCOUNT policy<{'s390x': 'y'}> +CONFIG_HAVE_OPROFILE policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_OPTPROBES policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_PATA_PLATFORM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HAVE_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_PCSPKR_PLATFORM policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_PERF_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_PERF_EVENTS_NMI policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_PERF_REGS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_PERF_USER_STACK_DUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_PNETID policy<{'s390x': 'm'}> +CONFIG_HAVE_PROC_CPU policy<{'armhf': 'y'}> +CONFIG_HAVE_RCU_TABLE_FREE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_RELIABLE_STACKTRACE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_RSEQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_S3C2410_I2C policy<{'armhf': 'y'}> +CONFIG_HAVE_S3C2410_WATCHDOG policy<{'armhf': 'y'}> +CONFIG_HAVE_S3C_RTC policy<{'armhf': 'y'}> +CONFIG_HAVE_SETUP_PER_CPU_AREA policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_SMP policy<{'armhf': 'y'}> +CONFIG_HAVE_STACKPROTECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HAVE_STACK_VALIDATION policy<{'amd64': 'y'}> +CONFIG_HAVE_SYSCALL_TRACEPOINTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_UID16 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_USER_RETURN_NOTIFIER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HAVE_VIRT_CPU_ACCOUNTING policy<{'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HBMC_AM654 policy<{'arm64': 'm'}> +CONFIG_HCALL_STATS policy<{'ppc64el': 'n'}> +CONFIG_HD44780 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDC100X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_CISCO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_FR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_PPP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_RAW_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDLC_X25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HDMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HDMI_LPE_AUDIO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HDQ_MASTER_OMAP policy<{'armhf': 'm'}> +CONFIG_HEADERS_INSTALL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HERMES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HERMES_CACHE_FW_ON_INIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HERMES_PRISM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_HFI1_DEBUG_SDMA_ORDER policy<{'amd64': 'n'}> +CONFIG_HFSPLUS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HI13X1_GMAC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HI3660_MBOX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HI6220_MBOX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HI8435 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HIBERNATE_CALLBACKS policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HIDRAW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_A4TECH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ACCUTOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ACRUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ACRUX_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_ALPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_APPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_APPLEIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ASUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_AUREAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_BATTERY_STRENGTH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_BELKIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_BETOP_FF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_BIGBEN_FF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CHERRY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CHICONY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CMEDIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CORSAIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_COUGAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CP2112 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CREATIVE_SB0540 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_CYPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_DRAGONRISE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ELAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ELECOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ELO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_EMS_FF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_EZKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GEMBIRD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GFRM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GOOGLE_HAMMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_HID_GREENASIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GT683R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_GYRATION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_HOLTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_HYPERV_MOUSE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HID_ICADE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_JABRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_KENSINGTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_KEYTOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_KYE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LCPOWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LENOVO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LOGITECH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LOGITECH_DJ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_LOGITECH_HIDPP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MACALLY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MAGICMOUSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MALTRON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MAYFLASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MICROSOFT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MONTEREY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_MULTITOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_NTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_NTRIG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ORTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PANTHERLORD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PENMOUNT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PETALYNX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PICOLCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PICOLCD_BACKLIGHT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PICOLCD_CIR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PICOLCD_FB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PICOLCD_LCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PICOLCD_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HID_PLANTRONICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PRIMAX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_PRODIKEYS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_REDRAGON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_RETRODE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_RMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ROCCAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SAITEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SAMSUNG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_ACCEL_3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_ALS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_CUSTOM_SENSOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_DEVICE_ROTATION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_GYRO_3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_HUB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_HUMIDITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_IIO_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_IIO_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_INCLINOMETER_3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_MAGNETOMETER_3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_PRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_PROX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SENSOR_TEMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SMARTJOYPLUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SONY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SPEEDLINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_STEAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_STEELSERIES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_SUNPLUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_THINGM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_THRUSTMASTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_TIVO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_TOPSEED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_TWINHAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_U2FZERO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_UCLOGIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_UDRAW_PS3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_VIEWSONIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_WACOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_WALTOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_WIIMOTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_XINMO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ZEROPLUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HID_ZYDACRON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HIGHMEM policy<{'armhf': 'y', 'i386': 'y'}> +CONFIG_HIGHMEM4G policy<{'i386': 'n'}> +CONFIG_HIGHMEM64G policy<{'i386': 'y'}> +CONFIG_HIGHPTE policy<{'armhf': 'y', 'i386': 'y'}> +CONFIG_HIGH_RES_TIMERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HINIC policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_HIP04_ETH policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HISILICON_ERRATUM_161010101 policy<{'arm64': 'y'}> +CONFIG_HISILICON_ERRATUM_161600802 policy<{'arm64': 'y'}> +CONFIG_HISILICON_IRQ_MBIGEN policy<{'arm64': 'y'}> +CONFIG_HISILICON_LPC policy<{'arm64': 'y'}> +CONFIG_HISI_DMA policy<{'arm64': 'n'}> +CONFIG_HISI_FEMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HISI_PMU policy<{'arm64': 'm'}> +CONFIG_HISI_THERMAL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HIST_TRIGGERS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HIX5HD2_GMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HMC6352 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HMC_DRV policy<{'s390x': 'm'}> +CONFIG_HMEM_REPORTING policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_HMM_MIRROR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HMS_ANYBUSS_BUS policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_HMS_PROFINET policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_HNS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS3_DCB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HNS3_ENET policy<{'arm64': 'm'}> +CONFIG_HNS3_HCLGE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS3_HCLGEVF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS_DSAF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS_ENET policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HNS_MDIO policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HOLES_IN_ZONE policy<{'arm64': 'y'}> +CONFIG_HOLTEK_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HOSTAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HOSTAP_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HOSTAP_FIRMWARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HOSTAP_FIRMWARE_NVRAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HOSTAP_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HOSTAP_PLX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HOSTESS_SV11 policy<{'i386': 'm'}> +CONFIG_HOTPLUG_CPU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HOTPLUG_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HOTPLUG_PCI_ACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HOTPLUG_PCI_ACPI_IBM policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_HOTPLUG_PCI_COMPAQ policy<{'i386': 'm'}> +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM policy<{'i386': 'y'}> +CONFIG_HOTPLUG_PCI_CPCI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HOTPLUG_PCI_CPCI_GENERIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HOTPLUG_PCI_CPCI_ZT5550 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HOTPLUG_PCI_IBM policy<{'i386': 'm'}> +CONFIG_HOTPLUG_PCI_POWERNV policy<{'ppc64el': 'm'}> +CONFIG_HOTPLUG_PCI_RPA policy<{'ppc64el': 'm'}> +CONFIG_HOTPLUG_PCI_RPA_DLPAR policy<{'ppc64el': 'm'}> +CONFIG_HOTPLUG_PCI_S390 policy<{'s390x': 'y'}> +CONFIG_HOTPLUG_SMT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HP03 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HP100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HP206C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HPET policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HPET_EMULATE_RTC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HPET_MMAP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HPET_MMAP_DEFAULT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HPET_TIMER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HPFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HPWDT_NMI_DECODING policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HP_ACCEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HP_ILO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HP_WATCHDOG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HP_WIRELESS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HP_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HSA_AMD policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_HSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HSI_BOARDINFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HSI_CHAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HSR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HSU_DMA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HSU_DMA_PCI policy<{'i386': 'm'}> +CONFIG_HT16K33 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_HTC_EGPIO policy<{'armhf': 'y'}> +CONFIG_HTC_I2CPLD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HTC_PASIC3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HTS221 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HTS221_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HTS221_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HTU21 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HUAWEI_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HUGETLBFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HUGETLB_PAGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HUGETLB_PAGE_SIZE_VARIABLE policy<{'ppc64el': 'y'}> +CONFIG_HVCS policy<{'ppc64el': 'm'}> +CONFIG_HVC_CONSOLE policy<{'ppc64el': 'y'}> +CONFIG_HVC_DCC policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_HVC_DRIVER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HVC_IRQ policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HVC_IUCV policy<{'s390x': 'y'}> +CONFIG_HVC_OLD_HVSI policy<{'ppc64el': 'y'}> +CONFIG_HVC_OPAL policy<{'ppc64el': 'y'}> +CONFIG_HVC_RTAS policy<{'ppc64el': 'y'}> +CONFIG_HVC_XEN policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HVC_XEN_FRONTEND policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_HV_PERF_CTRS policy<{'ppc64el': 'y'}> +CONFIG_HWLAT_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_HWMON_DEBUG_CHIP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_HWMON_VID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HWPOISON_INJECT policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_HWSPINLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_HWSPINLOCK_OMAP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HWSPINLOCK_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HWSPINLOCK_SPRD policy<{'arm64': 'm'}> +CONFIG_HW_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HW_PERF_EVENTS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_HW_RANDOM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HW_RANDOM_AMD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HW_RANDOM_BCM2835 policy<{'arm64': 'm'}> +CONFIG_HW_RANDOM_CAVIUM policy<{'arm64': 'm'}> +CONFIG_HW_RANDOM_EXYNOS policy<{'armhf': 'm'}> +CONFIG_HW_RANDOM_GEODE policy<{'i386': 'm'}> +CONFIG_HW_RANDOM_HISI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HW_RANDOM_HISI_V2 policy<{'arm64': 'm'}> +CONFIG_HW_RANDOM_IMX_RNGC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_HW_RANDOM_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HW_RANDOM_IPROC_RNG200 policy<{'arm64': 'm'}> +CONFIG_HW_RANDOM_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HW_RANDOM_MTK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HW_RANDOM_OMAP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HW_RANDOM_OMAP3_ROM policy<{'armhf-generic': 'm'}> +CONFIG_HW_RANDOM_OPTEE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_HW_RANDOM_POWERNV policy<{'ppc64el': 'm'}> +CONFIG_HW_RANDOM_PSERIES policy<{'ppc64el': 'm'}> +CONFIG_HW_RANDOM_S390 policy<{'s390x': 'm'}> +CONFIG_HW_RANDOM_TIMERIOMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_HW_RANDOM_TPM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_HW_RANDOM_VIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HW_RANDOM_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_HW_RANDOM_XGENE policy<{'arm64': 'm'}> +CONFIG_HX711 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HYPERV policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERVISOR_GUEST policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HYPERV_BALLOON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERV_IOMMU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HYPERV_KEYBOARD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERV_NET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERV_STORAGE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERV_TIMER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_HYPERV_UTILS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYPERV_VSOCKETS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_HYSDN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_HYSDN_CAPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_HZ policy<{'amd64-generic': '250', 'amd64-lowlatency': '1000', 'arm64': '250', 'armhf': '250', 'i386-generic': '250', 'i386-lowlatency': '1000', 'ppc64el': '250', 's390x': '100'}> +CONFIG_HZ_100 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_HZ_1000 policy<{'amd64-generic': 'n', 'amd64-lowlatency': 'y', 'arm64': 'n', 'armhf': 'n', 'i386-generic': 'n', 'i386-lowlatency': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HZ_200 policy<{'armhf': 'n'}> +CONFIG_HZ_250 policy<{'amd64-generic': 'y', 'amd64-lowlatency': 'n', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'i386-lowlatency': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_HZ_300 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_HZ_500 policy<{'armhf': 'n'}> +CONFIG_HZ_FIXED policy<{'armhf': '0'}> +CONFIG_HZ_PERIODIC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_I2C_ALGOBIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_I2C_ALGOPCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_ALI1535 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_ALI1563 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_ALI15X3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_AMD756 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_AMD756_S4882 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I2C_AMD8111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_AMD_MP2 policy<{'amd64': 'm', 'arm64': 'n', 'i386': 'n'}> +CONFIG_I2C_ARB_GPIO_CHALLENGE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_ASPEED policy<{'armhf': 'm'}> +CONFIG_I2C_AXXIA policy<{'armhf-generic-lpae': 'm'}> +CONFIG_I2C_BCM2835 policy<{'arm64': 'm'}> +CONFIG_I2C_BCM_IPROC policy<{'arm64': 'm'}> +CONFIG_I2C_BOARDINFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_I2C_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_I2C_CADENCE policy<{'arm64': 'n'}> +CONFIG_I2C_CBUS_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_CHT_WC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I2C_COMPAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_I2C_CROS_EC_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_I2C_DEBUG_ALGO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_I2C_DEBUG_BUS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_I2C_DEBUG_CORE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_I2C_DEMUX_PINCTRL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_DESIGNWARE_BAYTRAIL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_I2C_DESIGNWARE_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_I2C_DESIGNWARE_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_DESIGNWARE_PLATFORM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_I2C_DESIGNWARE_SLAVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_I2C_DIOLAN_U2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_DLN2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_EG20T policy<{'i386': 'm'}> +CONFIG_I2C_EMEV2 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'm', 'i386': 'n'}> +CONFIG_I2C_EXYNOS5 policy<{'armhf': 'm'}> +CONFIG_I2C_FSI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_GPIO_FAULT_INJECTOR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_I2C_HELPER_AUTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_I2C_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_HIX5HD2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_I801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_IMX policy<{'arm64': 'm', 'armhf-generic': 'y'}> +CONFIG_I2C_IMX_LPI2C policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_I2C_ISCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_ISMT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I2C_KEMPLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_MLXCPLD policy<{'amd64': 'm'}> +CONFIG_I2C_MPC policy<{'ppc64el': 'm'}> +CONFIG_I2C_MT65XX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_MULTI_INSTANTIATE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I2C_MUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_I2C_MUX_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MUX_GPMUX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_MUX_LTC4306 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MUX_MLXCPLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MUX_PCA9541 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MUX_PCA954x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MUX_PINCTRL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_MUX_REG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_MV64XXX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_NFORCE2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_NFORCE2_S4985 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I2C_NOMADIK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_NVIDIA_GPU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_OCORES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_OMAP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_I2C_OPAL policy<{'ppc64el': 'y'}> +CONFIG_I2C_OWL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_PARPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_PARPORT_LIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_PCA_ISA policy<{'i386': 'm'}> +CONFIG_I2C_PCA_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_PIIX4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_PXA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_PXA_SLAVE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_I2C_QCOM_GENI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_QUP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_RIIC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_RK3X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_ROBOTFUZZ_OSIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_S3C2410 policy<{'armhf': 'y'}> +CONFIG_I2C_SCMI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_I2C_SH_MOBILE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_SI470X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_SI4713 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_SIMTEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_SIS5595 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_SIS630 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_SIS96X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_SLAVE policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_I2C_SLAVE_EEPROM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_SMBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_SPRD policy<{'arm64': 'y'}> +CONFIG_I2C_STUB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_I2C_SYNQUACER policy<{'arm64': 'm'}> +CONFIG_I2C_TAOS_EVM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_I2C_TEGRA_BPMP policy<{'armhf-generic': 'm'}> +CONFIG_I2C_THUNDERX policy<{'arm64': 'm'}> +CONFIG_I2C_TINY_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_UNIPHIER policy<{'armhf': 'n'}> +CONFIG_I2C_UNIPHIER_F policy<{'armhf': 'n'}> +CONFIG_I2C_VERSATILE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_I2C_VIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_VIAPRO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_VIPERBOARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I2C_XGENE_SLIMPRO policy<{'arm64': 'm'}> +CONFIG_I2C_XILINX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I2C_XLP9XX policy<{'arm64': 'm'}> +CONFIG_I3C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I40E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I40EVF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_I40E_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_I6300ESB_WDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_I82092 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_I82365 policy<{'i386': 'm'}> +CONFIG_I8253_LOCK policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_I8K policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IA32_EMULATION policy<{'amd64': 'y'}> +CONFIG_IAQCORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IAVF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IB700_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IBMASR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IBMVETH policy<{'ppc64el': 'm'}> +CONFIG_IBMVIO policy<{'ppc64el': 'y'}> +CONFIG_IBMVMC policy<{'ppc64el': 'm'}> +CONFIG_IBM_ASM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IBM_BSR policy<{'ppc64el': 'm'}> +CONFIG_IBM_PARTITION policy<{'s390x': 'y'}> +CONFIG_IBM_RTL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ICPLUS_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ICS932S401 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ICST policy<{'armhf': 'y'}> +CONFIG_IDE policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IDEAPAD_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IDLE_INJECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IE6XX_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IEEE802154 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_IEEE802154_6LOWPAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_ADF7242 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_AT86RF230 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_AT86RF230_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IEEE802154_ATUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_CA8210 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IEEE802154_CA8210_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_IEEE802154_CC2520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_DRIVERS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_FAKELB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_HWSIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_MCR20A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_MRF24J40 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IEEE802154_NL802154_EXPERIMENTAL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IEEE802154_SOCKET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IFB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IGB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IGBVF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IGB_DCA policy<{'amd64': 'y'}> +CONFIG_IGB_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IGC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_IIO_ADIS_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ADIS_LIB_BUFFER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IIO_BUFFER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IIO_BUFFER_CB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_BUFFER_HW_CONSUMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_CONFIGFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_CONSUMERS_PER_TRIGGER policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'i386': '2', 'ppc64el': '2'}> +CONFIG_IIO_CROS_EC_ACCEL_LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_CROS_EC_BARO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_CROS_EC_LIGHT_PROX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_CROS_EC_SENSORS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_CROS_EC_SENSORS_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_IIO_HRTIMER_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_INTERRUPT_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_KFIFO_BUF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_MS_SENSORS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_MUX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_RESCALE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SIMPLE_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SSP_SENSORHUB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SSP_SENSORS_COMMONS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_ACCEL_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_ACCEL_I2C_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_ACCEL_SPI_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_GYRO_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_GYRO_I2C_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_GYRO_SPI_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_LSM6DSX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_LSM6DSX_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_LSM6DSX_I3C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_LSM6DSX_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_MAGN_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_MAGN_I2C_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_MAGN_SPI_3AXIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_PRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_PRESS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_PRESS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_SENSORS_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_SENSORS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_ST_SENSORS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SW_DEVICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SW_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_SYSFS_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_TIGHTLOOP_TRIGGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_TRIGGER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IIO_TRIGGERED_BUFFER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IIO_TRIGGERED_EVENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IKCONFIG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IKHEADERS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ILLEGAL_POINTER_VALUE policy<{'amd64': '0xdead000000000000', 'arm64': '0xdead000000000000', 'i386': '0', 'ppc64el': '0x5deadbeef0000000'}> +CONFIG_IMA_APPRAISE_BOOTPARAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IMA_APPRAISE_BUILD_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_APPRAISE_MODSIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IMA_BLACKLIST_KEYRING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_DEFAULT_HASH policy<{'amd64': '"sha1"', 'arm64': '"sha1"', 'armhf': '"sha1"', 'i386': '"sha1"', 'ppc64el': '"sha256"', 's390x': '"sha1"'}> +CONFIG_IMA_DEFAULT_HASH_SHA1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_IMA_DEFAULT_HASH_SHA512 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_DEFAULT_TEMPLATE policy<{'amd64': '"ima-ng"', 'arm64': '"ima-ng"', 'armhf': '"ima-ng"', 'i386': '"ima-ng"', 'ppc64el': '"ima-sig"', 's390x': '"ima-ng"'}> +CONFIG_IMA_LOAD_X509 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IMA_LSM_RULES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IMA_MEASURE_PCR_IDX policy<{'amd64': '10', 'arm64': '10', 'armhf': '10', 'i386': '10', 'ppc64el': '10', 's390x': '10'}> +CONFIG_IMA_NG_TEMPLATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_IMG_ASCII_LCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IMX2_WDT policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX7D_ADC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX7ULP_WDT policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_DMA policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_DSP policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_GPCV2 policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_GPCV2_PM_DOMAINS policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_IPUV3_CORE policy<{'armhf': 'm'}> +CONFIG_IMX_IRQSTEER policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_MBOX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_REMOTEPROC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_SCU policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_SCU_PD policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_SCU_SOC policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_IMX_SC_WDT policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_SDMA policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_THERMAL policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_IMX_WEIM policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_INA2XX_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INDIRECT_PIO policy<{'arm64': 'y'}> +CONFIG_INET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INET6_AH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET6_ESP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET6_ESP_OFFLOAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET6_IPCOMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET6_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET6_XFRM_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_AH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_DCCP_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_DIAG_DESTROY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INET_ESP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_ESP_OFFLOAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_IPCOMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_RAW_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_SCTP_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_TABLE_PERTURB_ORDER policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'i386': '16', 'ppc64el': '16', 's390x': '16'}> +CONFIG_INET_TCP_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_UDP_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INET_XFRM_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_ADDR_TRANS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_BNXT_RE policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INFINIBAND_CXGB3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INFINIBAND_CXGB4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INFINIBAND_EFA policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_INFINIBAND_EXP_LEGACY_VERBS_NEW_UAPI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INFINIBAND_HFI1 policy<{'amd64': 'm'}> +CONFIG_INFINIBAND_HNS policy<{'arm64': 'm'}> +CONFIG_INFINIBAND_HNS_HIP06 policy<{'arm64': 'y'}> +CONFIG_INFINIBAND_HNS_HIP08 policy<{'arm64': 'y'}> +CONFIG_INFINIBAND_I40IW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INFINIBAND_IPOIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_IPOIB_CM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_IPOIB_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INFINIBAND_ISER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_ISERT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_MTHCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_MTHCA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INFINIBAND_OCRDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INFINIBAND_ON_DEMAND_PAGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_OPA_VNIC policy<{'amd64': 'm'}> +CONFIG_INFINIBAND_QEDR policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_INFINIBAND_QIB policy<{'amd64': 'm'}> +CONFIG_INFINIBAND_QIB_DCA policy<{'amd64': 'y'}> +CONFIG_INFINIBAND_RDMAVT policy<{'amd64': 'm'}> +CONFIG_INFINIBAND_SRP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_SRPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_USER_ACCESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_USER_MAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INFINIBAND_USER_MEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_USNIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INFINIBAND_VIRT_DMA policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INFINIBAND_VMWARE_PVRDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_INFTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INITRAMFS_SOURCE policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_INIT_ENV_ARG_LIMIT policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32', 's390x': '32'}> +CONFIG_INIT_ON_ALLOC_DEFAULT_ON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INIT_ON_FREE_DEFAULT_ON policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INIT_STACK_NONE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_TRYLOCK policy<{'s390x': 'y'}> +CONFIG_INLINE_READ_UNLOCK policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_UNLOCK_IRQ policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_READ_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_TRYLOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_TRYLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_UNLOCK_IRQ policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_LOCK policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_LOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_LOCK_IRQ policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_LOCK_IRQSAVE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_TRYLOCK policy<{'s390x': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK_BH policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK_IRQ policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE policy<{'arm64': 'y', 's390x': 'y'}> +CONFIG_INOTIFY_USER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INPUT_88PM80X_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_88PM860X_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_AD714X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_AD714X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_AD714X_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_ADXL34X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_ADXL34X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_ADXL34X_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_APANEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INPUT_ARIZONA_HAPTICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_ATI_REMOTE2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_ATLAS_BTNS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INPUT_ATMEL_CAPTOUCH policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_AXP20X_PEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_BMA150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_CM109 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_CMA3000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_CMA3000_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_CPCAP_PWRBUTTON policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DA9052_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DA9055_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DA9063_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DRV260X_HAPTICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DRV2665_HAPTICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_DRV2667_HAPTICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_E3X0_BUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_EVBUG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_EVDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INPUT_FF_MEMLESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_GP2A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_GPIO_BEEPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_GPIO_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_GPIO_ROTARY_ENCODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_GPIO_VIBRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_HISI_POWERKEY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_INPUT_IDEAPAD_SLIDEBAR policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_IMS_PCU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_JOYDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_JOYSTICK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_KEYBOARD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_KEYSPAN_REMOTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_KXTJ9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_KXTJ9_POLLED_MODE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_INPUT_LEDS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MATRIXKMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_MAX77650_ONKEY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MAX77693_HAPTIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MAX8925_ONKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MAX8997_HAPTIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MC13783_PWRBUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MISC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_MMA8450 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_MOUSE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_MOUSEDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_MOUSEDEV_PSAUX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_INPUT_MOUSEDEV_SCREEN_X policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'i386': '1024', 'ppc64el': '1024'}> +CONFIG_INPUT_MOUSEDEV_SCREEN_Y policy<{'amd64': '768', 'arm64': '768', 'armhf': '768', 'i386': '768', 'ppc64el': '768'}> +CONFIG_INPUT_MSM_VIBRATOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PALMAS_PWRBUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PCAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PCF50633_PMU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PCF8574 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PCSPKR policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PM8941_PWRKEY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_INPUT_PM8XXX_VIBRATOR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_INPUT_PMIC8XXX_PWRKEY policy<{'armhf': 'm'}> +CONFIG_INPUT_POLLDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_POWERMATE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PWM_BEEPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_PWM_VIBRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_RAVE_SP_PWRBUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_REGULATOR_HAPTIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_RETU_PWRBUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_RK805_PWRKEY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_SC27XX_VIBRA policy<{'arm64': 'm'}> +CONFIG_INPUT_SOC_BUTTON_ARRAY policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_INPUT_SPARSEKMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INPUT_STPMIC1_ONKEY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_TABLET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_TOUCHSCREEN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_INPUT_TPS65218_PWRBUTTON policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_TWL4030_PWRBUTTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_TWL4030_VIBRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_TWL6040_VIBRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_WISTRON_BTNS policy<{'i386': 'm'}> +CONFIG_INPUT_WM831X_ON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INPUT_XEN_KBDDEV_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_INPUT_YEALINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INSTRUCTION_DECODER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INT3406_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INT340X_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEGRITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEGRITY_ASYMMETRIC_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEGRITY_AUDIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEGRITY_SIGNATURE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEGRITY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTEL_ATOMISP2_PM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_BXTWC_PMIC_TMU policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_BXT_PMIC_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_CHTDC_TI_PWRBTN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_CHT_INT33FE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_GTT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_HID_EVENT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_IDLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_IDMA64 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INTEL_INT0002_VGPIO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_IOATDMA policy<{'amd64': 'm'}> +CONFIG_INTEL_IOMMU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_IOMMU_FLOPPY_WA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_IOMMU_SVM policy<{'amd64': 'y', 'i386': '-'}> +CONFIG_INTEL_IPS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER policy<{'amd64': 'm'}> +CONFIG_INTEL_ISH_HID policy<{'amd64': 'm'}> +CONFIG_INTEL_MEI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MEI_HDCP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MEI_ME policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MEI_TXE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MEI_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MENLOW policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_MFLD_THERMAL policy<{'i386': 'm'}> +CONFIG_INTEL_MIC_BUS policy<{'amd64': 'm'}> +CONFIG_INTEL_MIC_CARD policy<{'amd64': 'm'}> +CONFIG_INTEL_MIC_HOST policy<{'amd64': 'm'}> +CONFIG_INTEL_MIC_X100_DMA policy<{'amd64': 'm'}> +CONFIG_INTEL_MID_POWER_BUTTON policy<{'i386': 'm'}> +CONFIG_INTEL_MID_PTI policy<{'i386': 'm'}> +CONFIG_INTEL_MID_WATCHDOG policy<{'i386': 'm'}> +CONFIG_INTEL_MRFLD_PWRBTN policy<{'i386': 'm'}> +CONFIG_INTEL_OAKTRAIL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_PCH_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_PMC_CORE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_PMC_IPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_POWERCLAMP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_PUNIT_IPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_RAPL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_RAPL_CORE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_RST policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SCU_IPC policy<{'i386': 'y'}> +CONFIG_INTEL_SCU_IPC_UTIL policy<{'i386': 'm'}> +CONFIG_INTEL_SCU_WATCHDOG policy<{'i386': 'y'}> +CONFIG_INTEL_SMARTCONNECT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SOC_DTS_IOSF_CORE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SOC_DTS_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SOC_PMIC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_SOC_PMIC_BXTWC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SOC_PMIC_CHTDC_TI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_SOC_PMIC_CHTWC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_SOC_PMIC_MRFLD policy<{'i386': 'm'}> +CONFIG_INTEL_SPEED_SELECT_INTERFACE policy<{'amd64': 'm'}> +CONFIG_INTEL_STRATIX10_RSU policy<{'arm64': 'm'}> +CONFIG_INTEL_STRATIX10_SERVICE policy<{'arm64': 'm'}> +CONFIG_INTEL_TELEMETRY policy<{'amd64': 'm'}> +CONFIG_INTEL_TH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TH_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_INTEL_TH_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INTEL_TH_GTH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TH_MSU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TH_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TH_PTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TH_STH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTEL_TURBO_MAX_3 policy<{'amd64': 'y'}> +CONFIG_INTEL_TXT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_INTEL_VBTN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_WMI_THUNDERBOLT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_INTEL_XWAY_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_INTERCONNECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_INTERCONNECT_QCOM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_INTERCONNECT_QCOM_QCS404 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_INTERCONNECT_QCOM_SDM845 policy<{'arm64': 'm'}> +CONFIG_INTERCONNECT_QCOM_SMD_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_INTERVAL_TREE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_INTERVAL_TREE_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_INV_MPU6050_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INV_MPU6050_IIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_INV_MPU6050_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IOMMU_API policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IOMMU_DEBUG policy<{'amd64': 'n'}> +CONFIG_IOMMU_DEFAULT_PASSTHROUGH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IOMMU_DMA policy<{'arm64': 'y'}> +CONFIG_IOMMU_HELPER policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IOMMU_IOVA policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic': 'm', 'i386': 'y'}> +CONFIG_IOMMU_IO_PGTABLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_IOMMU_IO_PGTABLE_ARMV7S policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_IOMMU_IO_PGTABLE_LPAE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_IOMMU_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IONIC policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_IOSCHED_BFQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IOSF_MBI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_IOSF_MBI_DEBUG policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_IO_DELAY_0X80 policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_IO_DELAY_0XED policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_IO_DELAY_NONE policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_IO_DELAY_UDELAY policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_IO_EVENT_IRQ policy<{'ppc64el': 'y'}> +CONFIG_IO_STRICT_DEVMEM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IO_URING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP6_NF_FILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_IPTABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MANGLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_AH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_EUI64 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_FRAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_HL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_IPV6HEADER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_MH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_OPTS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_RPFILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_RT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_MATCH_SRH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_SECURITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_TARGET_HL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_TARGET_MASQUERADE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_TARGET_NPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_TARGET_REJECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP6_NF_TARGET_SYNPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPACK_BUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_IPC_NS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPMB_DEVICE_INTERFACE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IPMI_DEVICE_INTERFACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPMI_DMI_DECODE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_IPMI_HANDLER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_IPMI_KCS_BMC policy<{'armhf': 'm'}> +CONFIG_IPMI_PANIC_EVENT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IPMI_PLAT_DATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPMI_POWERNV policy<{'ppc64el': 'm'}> +CONFIG_IPMI_POWEROFF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPMI_SI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPMI_SSIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPMI_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPQ_GCC_4019 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IPQ_GCC_806X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IPQ_GCC_8074 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IPQ_LCC_806X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IPV6_FOU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_FOU_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_GRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_ILA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_MIP6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_MROUTE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_MULTIPLE_TABLES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_NDISC_NODETYPE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_OPTIMISTIC_DAD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IPV6_PIMSM_V2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_ROUTER_PREF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_ROUTE_INFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_SEG6_BPF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_SEG6_HMAC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_SEG6_LWTUNNEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_SIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_SIT_6RD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_SUBTREES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPV6_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPV6_VTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPVLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPVLAN_L3S policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IPVTAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IPW2100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPW2100_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IPW2100_MONITOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPW2200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IPW2200_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IPW2200_MONITOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPW2200_PROMISCUOUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPW2200_QOS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPW2200_RADIOTAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IPWIRELESS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IP_ADVANCED_ROUTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_DCCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_DCCP_CCID2_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IP_DCCP_CCID3 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_IP_DCCP_CCID3_DEBUG policy<{'s390x': 'n'}> +CONFIG_IP_DCCP_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IP_DCCP_TFRC_LIB policy<{'s390x': 'y'}> +CONFIG_IP_FIB_TRIE_STATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_MROUTE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_MROUTE_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_MROUTE_MULTIPLE_TABLES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_MULTICAST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_MULTIPLE_TABLES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_NF_ARPFILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_ARPTABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_ARP_MANGLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_FILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_IPTABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_MANGLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_MATCH_AH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_MATCH_ECN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_MATCH_RPFILTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_MATCH_TTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_SECURITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_CLUSTERIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_ECN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_MASQUERADE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_NETMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_REDIRECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_REJECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_SYNPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_NF_TARGET_TTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_PIMSM_V1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_PIMSM_V2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_ROUTE_CLASSID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_ROUTE_MULTIPATH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_ROUTE_VERBOSE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_SCTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_BITMAP_IP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_BITMAP_IPMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_BITMAP_PORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IPMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IPMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IPPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IPPORTIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_IPPORTNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_MAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_NETIFACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_NETNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_NETPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_HASH_NETPORTNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_LIST_SET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_SET_MAX policy<{'amd64': '256', 'arm64': '256', 'armhf': '256', 'i386': '256', 'ppc64el': '256', 's390x': '256'}> +CONFIG_IP_VS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IP_VS_DH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_FO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_FTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_IPV6 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_LBLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_LBLCR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_LC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_MH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_MH_TAB_INDEX policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'i386': '12', 'ppc64el': '12', 's390x': '12'}> +CONFIG_IP_VS_NFCT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_NQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_OVF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_PE_SIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_PROTO_AH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_PROTO_AH_ESP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_PROTO_ESP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_PROTO_SCTP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_PROTO_TCP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_PROTO_UDP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IP_VS_RR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_SED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_SH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_SH_TAB_BITS policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8', 's390x': '8'}> +CONFIG_IP_VS_TAB_BITS policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'i386': '12', 'ppc64el': '12', 's390x': '12'}> +CONFIG_IP_VS_WLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IP_VS_WRR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IRQCHIP policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_IRQSOFF_TRACER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_IRQ_ALL_CPUS policy<{'ppc64el': 'y'}> +CONFIG_IRQ_BYPASS_MANAGER policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic': 'm', 'armhf-generic-lpae': 'y', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_IRQ_CROSSBAR policy<{'armhf': 'y'}> +CONFIG_IRQ_DOMAIN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IRQ_DOMAIN_HIERARCHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS policy<{'arm64': 'y'}> +CONFIG_IRQ_FORCED_THREADING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IRQ_FORCED_THREADING_DEFAULT policy<{'amd64-generic': 'n', 'amd64-lowlatency': 'y', 'arm64': 'n', 'armhf': 'n', 'i386-generic': 'n', 'i386-lowlatency': 'y', 'ppc64el': 'n'}> +CONFIG_IRQ_MSI_IOMMU policy<{'arm64': 'y'}> +CONFIG_IRQ_POLL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IRQ_REMAP policy<{'amd64': 'y'}> +CONFIG_IRQ_TIME_ACCOUNTING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IRQ_UNIPHIER_AIDET policy<{'armhf': 'y'}> +CONFIG_IRQ_WORK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_IR_ENE policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_IR_FINTEK policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_IR_GPIO_CIR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IR_GPIO_TX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IR_HIX5HD2 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IR_IGORPLUGUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_IGUANA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_IMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_IMON_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_IMON_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_ITE_CIR policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_IR_JVC_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_MCEUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_MCE_KBD_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IR_MTK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_IR_NEC_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_NUVOTON policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_IR_PWM_TX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IR_RC5_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_RC6_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_RCMM_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_REDRAT3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_RX51 policy<{'armhf': 'm'}> +CONFIG_IR_SANYO_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SERIAL_TRANSMITTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IR_SHARP_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SONY_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SPI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_IR_STREAMZAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_SUNXI policy<{'arm64': 'm'}> +CONFIG_IR_TTUSBIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IR_WINBOND_CIR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IR_XMP_DECODER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISA policy<{'i386': 'y'}> +CONFIG_ISAPNP policy<{'i386': 'y'}> +CONFIG_ISA_BUS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ISA_BUS_API policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ISA_DMA_API policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ISCSI_BOOT_SYSFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ISCSI_IBFT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_ISCSI_IBFT_FIND policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ISCSI_TARGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ISCSI_TARGET_CXGB4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISCSI_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ISDN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ISDN_CAPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISDN_CAPI_CAPI20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISDN_CAPI_MIDDLEWARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ISDN_DRV_AVMB1_AVM_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ISDN_DRV_AVMB1_B1ISA policy<{'i386': 'm'}> +CONFIG_ISDN_DRV_AVMB1_B1PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISDN_DRV_AVMB1_B1PCIV4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ISDN_DRV_AVMB1_C4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISDN_DRV_AVMB1_T1ISA policy<{'i386': 'm'}> +CONFIG_ISDN_DRV_AVMB1_T1PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISDN_DRV_GIGASET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISL29003 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ISL29020 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ISL29125 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISL29501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ISO9660_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_IT8712F_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_IT87_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ITCO_VENDOR_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_ITCO_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ITG3200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IUCV policy<{'s390x': 'y'}> +CONFIG_IWL3945 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWL4965 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWLDVM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWLEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWLEGACY_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IWLEGACY_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IWLMVM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWLWIFI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IWLWIFI_BCAST_FILTERING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IWLWIFI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_IWLWIFI_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IWLWIFI_DEVICE_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IWLWIFI_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IWLWIFI_OPMODE_MODULAR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IWMMXT policy<{'armhf': 'y'}> +CONFIG_IXGB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IXGBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IXGBEVF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_IXGBEVF_IPSEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IXGBE_DCA policy<{'amd64': 'y'}> +CONFIG_IXGBE_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IXGBE_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_IXGBE_IPSEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JAILHOUSE_GUEST policy<{'amd64': 'y'}> +CONFIG_JBD2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_JBD2_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_JFFS2_CMODE_FAVOURLZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_CMODE_NONE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_CMODE_PRIORITY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_CMODE_SIZE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_COMPRESSION_OPTIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JFFS2_FS_DEBUG policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_JFFS2_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_FS_WBUF_VERIFY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_FS_WRITEBUFFER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_FS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_RTIME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFFS2_RUBIN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_SUMMARY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFFS2_ZLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_JFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_JFS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JFS_STATISTICS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_JOLIET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_JOYSTICK_A3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_ADI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_ANALOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_AS5011 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_COBRA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_DB9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_FSIA6B policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_GAMECON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_GF2K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_GRIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_GRIP_MP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_GUILLEMOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_IFORCE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_IFORCE_232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_IFORCE_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_INTERACT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_JOYDUMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_MAGELLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_PSXPAD_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_PSXPAD_SPI_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JOYSTICK_PXRC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_SIDEWINDER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_SPACEBALL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_SPACEORB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_STINGER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_TMDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_TURBOGRAFX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_TWIDJOY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_WALKERA0701 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_WARRIOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_XPAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JOYSTICK_XPAD_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JOYSTICK_XPAD_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_JOYSTICK_ZHENHUA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JSA1212 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_JUMP_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_JUMP_LABEL_FEATURE_CHECKS policy<{'ppc64el': 'y'}> +CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG policy<{'ppc64el': 'n'}> +CONFIG_K3_DMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_KALLSYMS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KALLSYMS_ABSOLUTE_PERCPU policy<{'amd64': 'y'}> +CONFIG_KALLSYMS_ALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KALLSYMS_BASE_RELATIVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KARMA_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_KASAN policy<{'amd64': 'n', 'arm64': 'n', 's390x': 'n'}> +CONFIG_KASAN_STACK policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1', 's390x': '1'}> +CONFIG_KCOV policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_KDB_CONTINUE_CATASTROPHIC policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_KDB_DEFAULT_ENABLE policy<{'amd64': '0x1', 'arm64': '0x1', 'armhf': '0x1', 'i386': '0x1', 'ppc64el': '0x1'}> +CONFIG_KDB_KEYBOARD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KEMPLD_WDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KERNEL_BZIP2 policy<{'amd64': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_KERNEL_GZIP policy<{'amd64': 'n', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_KERNEL_LZ4 policy<{'amd64': 'y', 'armhf': 'n', 'i386': 'y', 's390x': 'y'}> +CONFIG_KERNEL_LZMA policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_KERNEL_LZO policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_KERNEL_MODE_NEON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_KERNEL_NOBP policy<{'s390x': 'n'}> +CONFIG_KERNEL_START policy<{'ppc64el': '0xc000000000000000'}> +CONFIG_KERNEL_UNCOMPRESSED policy<{'s390x': 'n'}> +CONFIG_KERNEL_XZ policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_KERNFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEXEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEXEC_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEXEC_ELF policy<{'ppc64el': 'y'}> +CONFIG_KEXEC_FILE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_KEXEC_IMAGE_VERIFY_SIG policy<{'arm64': 'n'}> +CONFIG_KEXEC_JUMP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_KEXEC_SIG policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_KEXEC_SIG_FORCE policy<{'amd64': 'n'}> +CONFIG_KEYBOARD_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_ADP5520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_ADP5588 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_ADP5589 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_APPLESPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_KEYBOARD_ATKBD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KEYBOARD_BCM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_KEYBOARD_CAP11XX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_KEYBOARD_DLINK_DIR685 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_GPIO_POLLED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_IMX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_KEYBOARD_LKKBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_LM8323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_LM8333 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_MATRIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_MAX7359 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_MCS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_MPR121 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_MTK_PMIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_NEWTON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_NVEC policy<{'armhf-generic': 'm'}> +CONFIG_KEYBOARD_OMAP4 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_OPENCORES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_PMIC8XXX policy<{'armhf': 'm'}> +CONFIG_KEYBOARD_QT1050 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_QT1070 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_QT2160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_SAMSUNG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_KEYBOARD_SNVS_PWRKEY policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_KEYBOARD_STMPE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_STOWAWAY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_SUN4I_LRADC policy<{'arm64': 'n'}> +CONFIG_KEYBOARD_SUNKBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_TC3589X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_TCA6416 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_TCA8418 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_KEYBOARD_TM2_TOUCHKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_TWL4030 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYBOARD_XTKBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEYS_COMPAT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEYS_REQUEST_CACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KEY_DH_OPERATIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KGDB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KGDB_KDB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KGDB_LOW_LEVEL_TRAP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_KGDB_TESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_KMSG_IDS policy<{'s390x': 'y'}> +CONFIG_KMX61 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KPC2000 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KPC2000_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KPC2000_DMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KPC2000_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KPC2000_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KPROBES_ON_FTRACE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KPROBES_SANITY_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_KPROBE_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KPROBE_EVENTS_ON_NOTRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_KPSS_XCC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_KRAITCC policy<{'armhf': 'm'}> +CONFIG_KRAIT_CLOCKS policy<{'armhf': 'y'}> +CONFIG_KRAIT_L2_ACCESSORS policy<{'armhf': 'y'}> +CONFIG_KRETPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KS0108 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KS0108_DELAY policy<{'amd64': '2', 'armhf': '2', 'i386': '2', 'ppc64el': '2'}> +CONFIG_KS0108_PORT policy<{'amd64': '0x378', 'armhf': '0x378', 'i386': '0x378', 'ppc64el': '0x378'}> +CONFIG_KS7010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KS8842 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KS8851 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KS8851_MLL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KSM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KSZ884X_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KUSER_HELPERS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_KVM_AMD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_KVM_AMD_SEV policy<{'amd64': 'y'}> +CONFIG_KVM_ARM_HOST policy<{'arm64': 'y', 'armhf-generic-lpae': 'y'}> +CONFIG_KVM_ARM_PMU policy<{'arm64': 'y'}> +CONFIG_KVM_ASYNC_PF policy<{'amd64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_KVM_ASYNC_PF_SYNC policy<{'s390x': 'y'}> +CONFIG_KVM_BOOK3S_64 policy<{'ppc64el': 'm'}> +CONFIG_KVM_BOOK3S_64_HANDLER policy<{'ppc64el': 'y'}> +CONFIG_KVM_BOOK3S_64_HV policy<{'ppc64el': 'm'}> +CONFIG_KVM_BOOK3S_64_PR policy<{'ppc64el': 'm'}> +CONFIG_KVM_BOOK3S_HANDLER policy<{'ppc64el': 'y'}> +CONFIG_KVM_BOOK3S_HV_EXIT_TIMING policy<{'ppc64el': 'n'}> +CONFIG_KVM_BOOK3S_HV_POSSIBLE policy<{'ppc64el': 'y'}> +CONFIG_KVM_BOOK3S_PR_POSSIBLE policy<{'ppc64el': 'y'}> +CONFIG_KVM_COMPAT policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_KVM_DEBUG_FS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y'}> +CONFIG_KVM_GUEST policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KVM_INDIRECT_VECTORS policy<{'arm64': 'y'}> +CONFIG_KVM_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_KVM_MMIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_KVM_MMU_AUDIT policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_KVM_S390_UCONTROL policy<{'s390x': 'n'}> +CONFIG_KVM_VFIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_KVM_XICS policy<{'ppc64el': 'y'}> +CONFIG_KVM_XIVE policy<{'ppc64el': 'y'}> +CONFIG_KXCJK1013 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KXSD9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KXSD9_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_KXSD9_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_L2TP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_L2TP_DEBUGFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_L2TP_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_L2TP_IP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_L2TP_V3 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LAN743X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LANCE policy<{'i386': 'm'}> +CONFIG_LANMEDIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LAPB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_LAPBETHER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LATTICE_ECP3_CONFIG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_AMS369FG06 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_CLASS_DEVICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_LCD_HX8357 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_ILI922X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_ILI9320 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_L4F00242T03 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_LMS283GF05 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_LMS501KF03 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_LTV350QV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_OTM3225A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_TDO24M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCD_VGG2432A4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LCS policy<{'s390x': 'm'}> +CONFIG_LDISC_AUTOLOAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LDM_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LDM_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_LD_DEAD_CODE_DATA_ELIMINATION policy<{'ppc64el': 'n'}> +CONFIG_LD_HEAD_STUB_CATCH policy<{'ppc64el': 'n'}> +CONFIG_LEDS_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_AAT1290 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_ADP5520 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_AN30259A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_APU policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LEDS_AS3645A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_ASIC3 policy<{'armhf': 'y'}> +CONFIG_LEDS_BCM6328 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_BCM6358 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_BD2802 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_BLINKM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_CLASS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_CLASS_FLASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_CLEVO_MAIL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LEDS_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_CR0014114 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_DA903X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_DAC124S085 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_INTEL_SS4200 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LEDS_IS31FL319X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_IS31FL32XX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_KTD2692 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3530 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3532 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3533 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM355x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3601X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM36274 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3642 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3692X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LM3697 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP3944 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP3952 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP5521 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP5523 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP5562 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP55XX_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP8501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP8788 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LP8860 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_LT3593 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MAX77650 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MAX77693 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MAX8997 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MC13783 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MENF21BMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MLXCPLD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LEDS_MLXREG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_MT6323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_NET48XX policy<{'i386': 'm'}> +CONFIG_LEDS_NIC78BX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LEDS_NS2 policy<{'armhf': 'm'}> +CONFIG_LEDS_OT200 policy<{'i386': 'm'}> +CONFIG_LEDS_PCA9532 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_PCA9532_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_PCA955X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_PCA955X_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_PCA963X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_PM8058 policy<{'armhf': 'm'}> +CONFIG_LEDS_POWERNV policy<{'ppc64el': 'm'}> +CONFIG_LEDS_PWM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_REGULATOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_SC27XX_BLTC policy<{'arm64': 'm'}> +CONFIG_LEDS_SPI_BYTE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_SYSCON policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TCA6507 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TI_LMU_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TLC591XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TRIGGER_ACTIVITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_AUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_BACKLIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_CAMERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_CPU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TRIGGER_DEFAULT_ON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_DISK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TRIGGER_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_HEARTBEAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_MTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TRIGGER_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_ONESHOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_PANIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEDS_TRIGGER_PATTERN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_TIMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_TRIGGER_TRANSIENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_USER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_WM831X_STATUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_WM8350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LEDS_WRAP policy<{'i386': 'm'}> +CONFIG_LED_TRIGGER_PHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LEGACY_PTYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LEGACY_PTY_COUNT policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_LEGACY_VSYSCALL_EMULATE policy<{'amd64': 'n'}> +CONFIG_LEGACY_VSYSCALL_NONE policy<{'amd64': 'n'}> +CONFIG_LEGACY_VSYSCALL_XONLY policy<{'amd64': 'y'}> +CONFIG_LG_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LIB80211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIB80211_CRYPT_CCMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIB80211_CRYPT_TKIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIB80211_CRYPT_WEP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIB80211_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LIBCRC32C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LIBERTAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBERTAS_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LIBERTAS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LIBERTAS_MESH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LIBERTAS_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBERTAS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBERTAS_THINFIRM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBERTAS_THINFIRM_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LIBERTAS_THINFIRM_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBERTAS_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBFC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LIBFCOE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LIBFDT policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_LIBIPW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIBIPW_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LIBNVDIMM policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_LIDAR_LITE_V2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LIQUIDIO policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_LIQUIDIO_VF policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_LIRC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LIVEPATCH policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LKDTM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LLC2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_LMP91000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LOAD_IPL_KEYS policy<{'s390x': 'y'}> +CONFIG_LOAD_UEFI_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_LOCALVERSION policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_LOCKD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LOCKDEP_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCKD_V4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCKUP_DETECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LOCK_DEBUGGING_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCK_DOWN_IN_SECURE_BOOT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCK_EVENT_COUNTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOCK_SPIN_ON_OWNER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LOCK_STAT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOCK_TORTURE_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOGIG940_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LOGIRUMBLEPAD2_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LOGITECH_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LOGIWHEELS_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_LOGO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_LOG_BUF_SHIFT policy<{'amd64': '18', 'arm64': '18', 'armhf': '17', 'i386': '17', 'ppc64el': '18', 's390x': '18'}> +CONFIG_LOG_CPU_MAX_BUF_SHIFT policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'i386': '12', 'ppc64el': '12', 's390x': '12'}> +CONFIG_LOOPBACK_TARGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LP8788_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LPARCFG policy<{'ppc64el': 'y'}> +CONFIG_LPC_ICH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_LPC_SCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_LP_CONSOLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_LRU_CACHE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LSI_ET1011C_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LSM policy<{'amd64': '"lockdown,yama,integrity,apparmor"', 'arm64': '"lockdown,yama,integrity,apparmor"', 'armhf': '"lockdown,yama,integrity,apparmor"', 'i386': '"lockdown,yama,integrity,apparmor"', 'ppc64el': '"lockdown,yama,integrity,apparmor"', 's390x': '"lockdown,yama,integrity,apparmor"'}> +CONFIG_LSM_MMAP_MIN_ADDR policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_LS_SCFG_MSI policy<{'arm64': 'y'}> +CONFIG_LTC1660 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTC2471 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTC2485 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTC2497 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTC2632 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTE_GDM724X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LTPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_LTR501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LV0104CS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_LWTUNNEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LWTUNNEL_BPF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LXT_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LZ4HC_COMPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LZ4_COMPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_LZ4_DECOMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LZO_COMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_LZO_DECOMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_M486 policy<{'i386': 'n'}> +CONFIG_M586 policy<{'i386': 'n'}> +CONFIG_M586MMX policy<{'i386': 'n'}> +CONFIG_M586TSC policy<{'i386': 'n'}> +CONFIG_M62332 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_M686 policy<{'i386': 'y'}> +CONFIG_MAC80211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAC80211_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_DEBUG_MENU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MAC80211_HAS_RC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_HWSIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAC80211_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_MESH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_MESSAGE_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_RC_DEFAULT policy<{'amd64': '"minstrel_ht"', 'arm64': '"minstrel_ht"', 'armhf': '"minstrel_ht"', 'i386': '"minstrel_ht"', 'ppc64el': '"minstrel_ht"'}> +CONFIG_MAC80211_RC_DEFAULT_MINSTREL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_RC_MINSTREL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MAC80211_STA_HASH_MAX_SIZE policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_MAC802154 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MACB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MACB_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MACB_USE_HWSTAMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_MACHZ_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MACH_ARMADA_370 policy<{'armhf': 'y'}> +CONFIG_MACH_ARMADA_375 policy<{'armhf': 'y'}> +CONFIG_MACH_ARMADA_38X policy<{'armhf': 'y'}> +CONFIG_MACH_ARMADA_39X policy<{'armhf': 'y'}> +CONFIG_MACH_ARMADA_XP policy<{'armhf': 'y'}> +CONFIG_MACH_ARTPEC6 policy<{'armhf': 'n'}> +CONFIG_MACH_ASPEED_G6 policy<{'armhf': 'y'}> +CONFIG_MACH_BERLIN_BG2 policy<{'armhf': 'y'}> +CONFIG_MACH_BERLIN_BG2CD policy<{'armhf': 'y'}> +CONFIG_MACH_BERLIN_BG2Q policy<{'armhf': 'y'}> +CONFIG_MACH_DOVE policy<{'armhf': 'y'}> +CONFIG_MACH_MESON6 policy<{'armhf': 'y'}> +CONFIG_MACH_MESON8 policy<{'armhf': 'y'}> +CONFIG_MACH_MT2701 policy<{'armhf': 'y'}> +CONFIG_MACH_MT6589 policy<{'armhf': 'y'}> +CONFIG_MACH_MT6592 policy<{'armhf': 'y'}> +CONFIG_MACH_MT7623 policy<{'armhf': 'y'}> +CONFIG_MACH_MT7629 policy<{'armhf': 'y'}> +CONFIG_MACH_MT8127 policy<{'armhf': 'y'}> +CONFIG_MACH_MT8135 policy<{'armhf': 'y'}> +CONFIG_MACH_MVEBU_ANY policy<{'armhf': 'y'}> +CONFIG_MACH_MVEBU_V7 policy<{'armhf': 'y'}> +CONFIG_MACH_OMAP3517EVM policy<{'armhf-generic': 'n'}> +CONFIG_MACH_OMAP3_PANDORA policy<{'armhf-generic': 'y'}> +CONFIG_MACH_OMAP_GENERIC policy<{'armhf': 'y'}> +CONFIG_MACINTOSH_DRIVERS policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MACSEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MACVLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MACVTAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MAC_EMUMOUSEBTN policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAC_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MADERA_IRQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAG3110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAGIC_SYSRQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE policy<{'amd64': '0x01b6', 'arm64': '0x01b6', 'armhf': '0x01b6', 'i386': '0x01b6', 'ppc64el': '0x01b6', 's390x': '0x01b6'}> +CONFIG_MAGIC_SYSRQ_SERIAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MAILBOX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MAILBOX_TEST policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MANAGER_SBS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MANDATORY_FILE_LOCKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MANTIS_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MARCH_Z10 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z13 policy<{'s390x': 'y'}> +CONFIG_MARCH_Z14 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z15 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z15_TUNE policy<{'s390x': 'y'}> +CONFIG_MARCH_Z196 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z900 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z990 policy<{'s390x': 'n'}> +CONFIG_MARCH_Z9_109 policy<{'s390x': 'n'}> +CONFIG_MARCH_ZEC12 policy<{'s390x': 'n'}> +CONFIG_MARVELL_10G_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MARVELL_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MATH_EMULATION policy<{'i386': 'n'}> +CONFIG_MATOM policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_MAX1027 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX11100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX1118 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX1363 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX30100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX30102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX31856 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX44000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX44009 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX517 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX5432 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX5481 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX5487 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX5821 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MAX63XX_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MAX77620_THERMAL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MAX77620_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MAX8925_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAX9611 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAXIM_THERMOCOUPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MAXSMP policy<{'amd64': 'y'}> +CONFIG_MAX_PHYSMEM_BITS policy<{'s390x': '46'}> +CONFIG_MAX_RAW_DEVS policy<{'amd64': '256', 'arm64': '256', 'armhf': '256', 'i386': '256', 'ppc64el': '256'}> +CONFIG_MB1232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MC3230 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MCB_LPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCB_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCORE2 policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_MCP320X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP3422 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP3911 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP4018 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP41010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP4131 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP4531 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP4725 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCP4922 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MCPM policy<{'armhf': 'y'}> +CONFIG_MCPM_QUAD_CLUSTER policy<{'armhf': 'y'}> +CONFIG_MCRUSOE policy<{'i386': 'n'}> +CONFIG_MCYRIXIII policy<{'i386': 'n'}> +CONFIG_MD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MDA_CONSOLE policy<{'i386': 'm'}> +CONFIG_MDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_ASPEED policy<{'armhf': 'm'}> +CONFIG_MDIO_BCM_IPROC policy<{'arm64': 'n'}> +CONFIG_MDIO_BCM_UNIMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MDIO_BITBANG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MDIO_BUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_MDIO_BUS_MUX policy<{'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_BUS_MUX_BCM_IPROC policy<{'arm64': 'y'}> +CONFIG_MDIO_BUS_MUX_GPIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_BUS_MUX_MESON_G12A policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MDIO_BUS_MUX_MMIOREG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_BUS_MUX_MULTIPLEXER policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_CAVIUM policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_DEVICE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MDIO_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_HISI_FEMAC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_MSCC_MIIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MDIO_OCTEON policy<{'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_MDIO_SUN4I policy<{'arm64': 'n'}> +CONFIG_MDIO_THUNDER policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MDIO_XGENE policy<{'arm64': 'm'}> +CONFIG_MDM_GCC_9615 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MDM_LCC_9615 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MD_AUTODETECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MD_CLUSTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_FAULTY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_LINEAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_MULTIPATH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'y'}> +CONFIG_MD_RAID0 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_RAID1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_RAID10 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MD_RAID456 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MEDIATEK_MT6577_AUXADC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MEDIATEK_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MEDIA_ALTERA_CI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_ANALOG_TV_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_ATTACH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_CAMERA_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_CEC_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_COMMON_OPTIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_CONTROLLER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_CONTROLLER_DVB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_CONTROLLER_REQUEST_API policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MEDIA_DIGITAL_TV_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_PCI_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_RADIO_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_SDR_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_SUBDRV_AUTOSELECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEDIA_SUPPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MEDIA_TUNER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_E4000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_FC0011 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_FC0012 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_FC0013 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_FC2580 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_IT913X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_M88RS6000T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MAX2165 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MC44S803 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MSI001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MT2060 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MT2063 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MT20XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MT2131 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MT2266 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MXL301RF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MXL5005S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_MXL5007T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_QM1D1B0004 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_QM1D1C0042 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_QT1010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_R820T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_SI2157 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_SIMPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA18212 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA18218 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA18250 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA18271 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA827X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA8290 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TDA9887 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TEA5761 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TEA5767 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_TUA9001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_XC2028 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_XC4000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_TUNER_XC5000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEDIA_USB_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MEFFICEON policy<{'i386': 'n'}> +CONFIG_MEGARAID_LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MEGARAID_MAILBOX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEGARAID_MM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEGARAID_NEWGEN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MEGARAID_SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MELAN policy<{'i386': 'n'}> +CONFIG_MELLANOX_PLATFORM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_MEMBARRIER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMCG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMCG_KMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMCG_SWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMCG_SWAP_ENABLED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MEMFD_CREATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MEMORY_BALLOON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY_FAILURE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_MEMORY_HOTPLUG policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY_HOTPLUG_SPARSE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY_HOTREMOVE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY_ISOLATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEMORY_NOTIFIER_ERROR_INJECT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MEMSTICK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MEMSTICK_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MEMSTICK_JMICRON_38X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEMSTICK_R592 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEMSTICK_REALTEK_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEMSTICK_REALTEK_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEMSTICK_TIFM_MS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEMSTICK_UNSAFE_RESUME policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MEMTEST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MEM_SOFT_DIRTY policy<{'amd64': 'y', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_MENF21BMC_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MENZ069_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MEN_A21_WDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MEN_Z188_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MESON6_TIMER policy<{'armhf': 'y'}> +CONFIG_MESON_CANVAS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESON_CLK_MEASURE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_EE_PM_DOMAINS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_EFUSE policy<{'arm64': 'm'}> +CONFIG_MESON_GXBB_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESON_GXL_PHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESON_GX_PM_DOMAINS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_GX_SOCINFO policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_IRQ_GPIO policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_MX_EFUSE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESON_MX_SOCINFO policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MESON_SARADC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESON_SM policy<{'arm64': 'y'}> +CONFIG_MESON_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MESSAGE_LOGLEVEL_DEFAULT policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'i386': '4', 'ppc64el': '4', 's390x': '4'}> +CONFIG_MFD_88PM800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_88PM805 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_88PM860X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_AAT2870_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_AC100 policy<{'arm64': 'n'}> +CONFIG_MFD_ACT8945A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_AHC1EC0 policy<{'amd64': 'm'}> +CONFIG_MFD_ALTERA_SYSMGR policy<{'arm64': 'y'}> +CONFIG_MFD_ARIZONA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_ARIZONA_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_ARIZONA_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_AS3711 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_AS3722 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_ASIC3 policy<{'armhf': 'y'}> +CONFIG_MFD_ATMEL_FLEXCOM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_ATMEL_HLCDC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_AXP20X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_AXP20X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_AXP20X_RSB policy<{'arm64': 'm'}> +CONFIG_MFD_BCM590XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_BD9571MWV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_MFD_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MFD_CROS_EC_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MFD_CS47L15 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS47L24 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS47L35 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS47L85 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS47L90 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS47L92 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_CS5535 policy<{'i386': 'm'}> +CONFIG_MFD_DA9052_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_DA9052_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_DA9055 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_DA9062 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_DA9063 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MFD_DA9150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_DLN2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_EXYNOS_LPASS policy<{'armhf': 'm'}> +CONFIG_MFD_HI6421_PMIC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_HI655X_PMIC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MFD_INTEL_LPSS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MFD_INTEL_LPSS_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MFD_INTEL_LPSS_PCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MFD_INTEL_MSIC policy<{'i386': 'y'}> +CONFIG_MFD_INTEL_QUARK_I2C_GPIO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MFD_JANZ_CMODIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_KEMPLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_LM3533 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_LOCHNAGAR policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_LP3943 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_LP8788 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MADERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_MADERA_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_MADERA_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_MAX14577 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MFD_MAX77620 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MAX77650 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_MAX77686 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MAX77693 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MFD_MAX77843 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MAX8907 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_MAX8925 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MAX8997 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MAX8998 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_MC13XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_MC13XXX_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_MC13XXX_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_MENF21BMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_MT6397 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_NVEC policy<{'armhf-generic': 'm'}> +CONFIG_MFD_OMAP_USB_HOST policy<{'armhf': 'y'}> +CONFIG_MFD_PALMAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_PCF50633 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_PM8XXX policy<{'armhf': 'm'}> +CONFIG_MFD_QCOM_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MFD_RC5T583 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_RDC321X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MFD_RETU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_RK808 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_RN5T618 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_ROHM_BD70528 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_ROHM_BD718XX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_RT5033 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_SC27XX_PMIC policy<{'arm64': 'm'}> +CONFIG_MFD_SEC_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_SI476X_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_SKY81452 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_SM501_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_SMSC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_SPMI_PMIC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MFD_STMFX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_STMPE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_STPMIC1 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_SUN4I_GPADC policy<{'arm64': 'm'}> +CONFIG_MFD_SUN6I_PRCM policy<{'arm64': 'y'}> +CONFIG_MFD_SYSCON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MFD_T7L66XB policy<{'armhf': 'y'}> +CONFIG_MFD_TC3589X policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TC6387XB policy<{'armhf': 'y'}> +CONFIG_MFD_TC6393XB policy<{'armhf': 'y'}> +CONFIG_MFD_TIMBERDALE policy<{'i386': 'm'}> +CONFIG_MFD_TI_AM335X_TSCADC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'i386': '-', 'ppc64el': '-', 's390x': '-'}> +CONFIG_MFD_TI_LMU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_TI_LP873X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_TI_LP87565 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_TMIO policy<{'armhf': 'y'}> +CONFIG_MFD_TPS65086 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_TPS65090 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TPS65218 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_TPS6586X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TPS65910 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TPS65912 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TPS65912_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MFD_TPS65912_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TPS68470 policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_MFD_TPS80031 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_TQMX86 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_TWL4030_AUDIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_VEXPRESS_SYSREG policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MFD_VIPERBOARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MFD_VX855 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MFD_WL1273_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_WM5102 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM5110 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM831X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM831X_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM831X_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM8350 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM8350_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM8400 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM8994 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MFD_WM8997 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MFD_WM8998 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MGEODEGX1 policy<{'i386': 'n'}> +CONFIG_MGEODE_LX policy<{'i386': 'n'}> +CONFIG_MICREL_KS8995MA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MICREL_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MICROCHIP_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MICROCHIP_T1_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MICROCODE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MICROCODE_AMD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MICROCODE_INTEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MICROCODE_OLD_INTERFACE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MICROSEMI_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MIC_COSM policy<{'amd64': 'm'}> +CONFIG_MIGHT_HAVE_CACHE_L2X0 policy<{'armhf': 'y'}> +CONFIG_MIGRATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MII policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MILBEAUT_TIMER policy<{'armhf': 'y'}> +CONFIG_MINIX_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MINIX_SUBPARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MISC_ALCOR_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MISC_FILESYSTEMS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MISC_RTSX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISC_RTSX_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MISC_RTSX_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_AVMFRITZ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_DSP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_HDLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_HFCMULTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_HFCPCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_HFCUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_INFINEON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_IPAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_ISAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_L1OIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_NETJET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_SPEEDFAX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MISDN_W6692 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY policy<{'arm64': 'y'}> +CONFIG_MIXCOMWD policy<{'i386': 'm'}> +CONFIG_MK6 policy<{'i386': 'n'}> +CONFIG_MK7 policy<{'i386': 'n'}> +CONFIG_MK8 policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_MKISS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MLX4_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX4_CORE_GEN2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX4_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX4_EN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX4_EN_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX4_INFINIBAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX5_ACCEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX5_CORE_EN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_CORE_EN_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_CORE_IPOIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_EN_ARFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_EN_IPSEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_EN_RXNFC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_EN_TLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_ESWITCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_FPGA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_FPGA_IPSEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_FPGA_TLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_INFINIBAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX5_MPFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_SW_STEERING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX5_TLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLX90614 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MLX90632 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MLXBF_TMFIFO policy<{'arm64': 'm'}> +CONFIG_MLXFW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLXREG_HOTPLUG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MLXREG_IO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MLXSW_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLXSW_CORE_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MLXSW_CORE_THERMAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MLXSW_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_MLXSW_MINIMAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MLXSW_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLXSW_SPECTRUM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLXSW_SPECTRUM_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MLXSW_SWITCHIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLXSW_SWITCHX2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MLX_PLATFORM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MLX_WDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_MMA7455 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA7455_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA7455_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA7660 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA8452 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA9551 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA9551_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMA9553 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_MMC35240 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMCONF_FAM10H policy<{'amd64': 'y'}> +CONFIG_MMC_ALCOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_ARMMMCI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MMC_BCM2835 policy<{'arm64': 'm'}> +CONFIG_MMC_BLOCK_MINORS policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_MMC_CAVIUM_THUNDERX policy<{'arm64': 'm'}> +CONFIG_MMC_CB710 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_CQHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MMC_DW policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_BLUEFIELD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_EXYNOS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_HI3798CV200 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_K3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_PCI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_PLTFM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_DW_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_MESON_GX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_MESON_MX_SDIO policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_MTK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_MVSDIO policy<{'armhf': 'm'}> +CONFIG_MMC_MXC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_MMC_OMAP policy<{'armhf': 'm'}> +CONFIG_MMC_QCOM_DML policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MMC_REALTEK_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_REALTEK_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_RICOH_MMC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MMC_SDHCI_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_MMC_SDHCI_AM654 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER policy<{'ppc64el': 'y'}> +CONFIG_MMC_SDHCI_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_MMC_SDHCI_CADENCE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_DOVE policy<{'armhf': 'm'}> +CONFIG_MMC_SDHCI_ESDHC_IMX policy<{'arm64': 'm', 'armhf-generic': 'y'}> +CONFIG_MMC_SDHCI_F_SDH30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_IO_ACCESSORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MMC_SDHCI_IPROC policy<{'arm64': 'm'}> +CONFIG_MMC_SDHCI_MSM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHCI_OF_ARASAN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHCI_OF_ASPEED policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_OF_AT91 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_OF_DWCMSHC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHCI_OF_ESDHC policy<{'arm64': 'm', 'armhf-generic': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_OF_HLWD policy<{'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_OMAP policy<{'arm64': '-', 'armhf': 'm', 'ppc64el': '-'}> +CONFIG_MMC_SDHCI_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHCI_PXAV3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHCI_S3C policy<{'armhf': 'm'}> +CONFIG_MMC_SDHCI_S3C_DMA policy<{'armhf': 'y'}> +CONFIG_MMC_SDHCI_SPRD policy<{'arm64': 'm'}> +CONFIG_MMC_SDHCI_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_MMC_SDHCI_XENON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_SDHI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHI_INTERNAL_DMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDHI_SYS_DMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SDRICOH_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MMC_SH_MMCIF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_STM32_SDMMC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MMC_SUNXI policy<{'arm64': 'm'}> +CONFIG_MMC_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MMC_TIFM_SD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_TMIO policy<{'armhf': 'm'}> +CONFIG_MMC_TMIO_CORE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MMC_TOSHIBA_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_MMC_USDHI6ROL0 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_USHC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_VIA_SDMMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_VUB300 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMC_WBSD policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MMIOTRACE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MMIOTRACE_TEST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_MMIOWB policy<{'ppc64el': 'y'}> +CONFIG_MMU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MMU_NOTIFIER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULES_TREE_LOOKUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULES_USE_ELF_REL policy<{'armhf': 'y', 'i386': 'y'}> +CONFIG_MODULES_USE_ELF_RELA policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_FORCE_LOAD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_FORCE_UNLOAD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_REL_CRCS policy<{'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_SIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_SIG_ALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_SIG_FORCE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_SIG_FORMAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_SIG_HASH policy<{'amd64': '"sha512"', 'arm64': '"sha512"', 'armhf': '"sha512"', 'i386': '"sha512"', 'ppc64el': '"sha512"', 's390x': '"sha512"'}> +CONFIG_MODULE_SIG_KEY policy<{'amd64': '"certs/signing_key.pem"', 'arm64': '"certs/signing_key.pem"', 'armhf': '"certs/signing_key.pem"', 'i386': '"certs/signing_key.pem"', 'ppc64el': '"certs/signing_key.pem"', 's390x': '"certs/signing_key.pem"'}> +CONFIG_MODULE_SIG_SHA1 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_SIG_SHA224 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_SIG_SHA256 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_SIG_SHA384 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_MODULE_SIG_SHA512 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_SRCVERSION_ALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MODULE_UNLOAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MONREADER policy<{'s390x': 'm'}> +CONFIG_MONWRITER policy<{'s390x': 'm'}> +CONFIG_MOST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_CDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_DIM2 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_SOUND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOST_VIDEO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_APPLETOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_BCM5974 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_CYAPA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_ELAN_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_ELAN_I2C_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_ELAN_I2C_SMBUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_LOGIBM policy<{'i386': 'm'}> +CONFIG_MOUSE_PC110PAD policy<{'i386': 'm'}> +CONFIG_MOUSE_PS2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_PS2_ALPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_BYD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_CYPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_ELANTECH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_ELANTECH_SMBUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_FOCALTECH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_LIFEBOOK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MOUSE_PS2_LOGIPS2PP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_SENTELIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_SMBUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_SYNAPTICS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_TOUCHKIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_TRACKPOINT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MOUSE_PS2_VMMOUSE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MOUSE_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_SYNAPTICS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_SYNAPTICS_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOUSE_VSXXXAA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOXA_INTELLIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOXA_SMARTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MOXTET policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MPENTIUM4 policy<{'i386': 'n'}> +CONFIG_MPENTIUMII policy<{'i386': 'n'}> +CONFIG_MPENTIUMIII policy<{'i386': 'n'}> +CONFIG_MPENTIUMM policy<{'i386': 'n'}> +CONFIG_MPIC policy<{'ppc64el': 'y'}> +CONFIG_MPIC_MSGR policy<{'ppc64el': 'n'}> +CONFIG_MPILIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MPL115 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MPL115_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MPL115_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MPL3115 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MPLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MPLS_IPTUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MPLS_ROUTING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MPROFILE_KERNEL policy<{'ppc64el': 'y'}> +CONFIG_MPSC policy<{'amd64': 'n'}> +CONFIG_MPU3050 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MPU3050_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MQ_IOSCHED_DEADLINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MQ_IOSCHED_KYBER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MRP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MS5611 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MS5611_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MS5611_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MS5637 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MSCC_OCELOT_SWITCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MSCC_OCELOT_SWITCH_OCELOT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MSDOS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_MSDOS_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MSI_BITMAP_SELFTEST policy<{'ppc64el': 'n'}> +CONFIG_MSI_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MSI_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MSM_GCC_8660 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8916 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8960 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8974 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8994 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8996 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_GCC_8998 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_IOMMU policy<{'armhf': 'n'}> +CONFIG_MSM_LCC_8960 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_MMCC_8960 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_MMCC_8974 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSM_MMCC_8996 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MSPRO_BLOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MS_BLOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT7601U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT7603E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT7615E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MT76_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x02_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x02_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x0E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x0U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x0_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x2E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x2U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MT76x2_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTDRAM_ERASE_SIZE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128'}> +CONFIG_MTDRAM_TOTAL_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'i386': '4096', 'ppc64el': '4096'}> +CONFIG_MTD_ABSENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_AFS_PARTS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_AMD76XROM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_AR7_PARTS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_BCM47XXSFLASH policy<{'armhf': 'm'}> +CONFIG_MTD_BLKDEVS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_BLOCK2MTD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_BLOCK_RO policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CFI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CFI_ADV_OPTIONS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_CFI_AMDSTD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CFI_I1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_CFI_I2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_CFI_INTELEXT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CFI_STAA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CFI_UTIL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_CK804XROM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_CMDLINE_PARTS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_COMPLEX_MAPPINGS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_DATAFLASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_DATAFLASH_OTP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_DATAFLASH_WRITE_VERIFY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_ESB2ROM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_GEN_PROBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_HYPERBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_ICHXROM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_IMPA7 policy<{'armhf': 'm'}> +CONFIG_MTD_INTEL_VR_NOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_JEDECPROBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_L440GX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_LPDDR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_LPDDR2_NVM policy<{'armhf': 'm'}> +CONFIG_MTD_MAP_BANK_WIDTH_1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_MAP_BANK_WIDTH_2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_MAP_BANK_WIDTH_4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_MCHP23K256 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_MTDRAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_BRCMNAND policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_CAFE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_CS553X policy<{'i386': 'm'}> +CONFIG_MTD_NAND_DENALI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_DENALI_DT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_DENALI_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_DISKONCHIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_NAND_ECC_SW_BCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_NAND_ECC_SW_HAMMING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_NAND_FSL_IFC policy<{'arm64': 'm'}> +CONFIG_MTD_NAND_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_GPMI_NAND policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_MTD_NAND_HISI504 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_MARVELL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_MTK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_MXC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_MTD_NAND_MXIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_NANDSIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_OMAP_BCH_BUILD policy<{'armhf': 'y'}> +CONFIG_MTD_NAND_ORION policy<{'armhf': 'm'}> +CONFIG_MTD_NAND_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTD_NAND_RICOH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_NAND_SUNXI policy<{'arm64': 'n'}> +CONFIG_MTD_NAND_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_MTD_NAND_TMIO policy<{'armhf': 'm'}> +CONFIG_MTD_NAND_VF610_NFC policy<{'armhf-generic': 'n'}> +CONFIG_MTD_NETtel policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_ONENAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_ONENAND_2X_PROGRAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_ONENAND_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_ONENAND_OMAP2 policy<{'armhf-generic': 'm'}> +CONFIG_MTD_ONENAND_OTP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_OOPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PARTITIONED_MASTER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_PCMCIA_ANONYMOUS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_MTD_PHRAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PHYSMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PHYSMAP_COMPAT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_PHYSMAP_GEMINI policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n'}> +CONFIG_MTD_PHYSMAP_GPIO_ADDR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_PHYSMAP_OF policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_PHYSMAP_VERSATILE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n'}> +CONFIG_MTD_PLATRAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PMC551 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_PMC551_BUGFIX policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_PMC551_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_POWERNV_FLASH policy<{'ppc64el': 'm'}> +CONFIG_MTD_QINFO_PROBE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_RAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK policy<{'amd64': '-1', 'arm64': '-1', 'armhf': '-1', 'i386': '-1', 'ppc64el': '-1'}> +CONFIG_MTD_REDBOOT_PARTS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_REDBOOT_PARTS_READONLY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_ROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SBC_GXX policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_SCB2_FLASH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MTD_SCx200_DOCFLASH policy<{'i386': 'm'}> +CONFIG_MTD_SHARPSL_PARTS policy<{'armhf': 'm'}> +CONFIG_MTD_SLRAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SM_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SPI_NAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SPI_NOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_SST25L policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_SWAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_TESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_MTD_UBI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_UBI_BEB_LIMIT policy<{'amd64': '20', 'arm64': '20', 'armhf': '20', 'i386': '20', 'ppc64el': '20'}> +CONFIG_MTD_UBI_BLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_UBI_FASTMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MTD_UBI_GLUEBI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MTD_UBI_WL_THRESHOLD policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'i386': '4096', 'ppc64el': '4096'}> +CONFIG_MTK_CMDQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_CMDQ_MBOX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_CQDMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_EFUSE policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_MTK_HSDMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_INFRACFG policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MTK_IOMMU policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_MTK_IOMMU_V1 policy<{'armhf': 'n'}> +CONFIG_MTK_PMIC_WRAP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_SCPSYS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MTK_SMI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MTK_THERMAL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTK_TIMER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MTK_UART_APDMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MTRR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MTRR_SANITIZER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT policy<{'amd64': '1', 'i386': '1'}> +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT policy<{'amd64': '1', 'i386': '1'}> +CONFIG_MULTIPLEXER policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MULTIUSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MUSB_PIO_ONLY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_MUTEX_SPIN_ON_OWNER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_MUX_ADG792A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MUX_ADGS1408 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MUX_GPIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MUX_MMIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_MV643XX_ETH policy<{'armhf': 'm'}> +CONFIG_MVEBU_CLK_COMMON policy<{'armhf': 'y'}> +CONFIG_MVEBU_CLK_COREDIV policy<{'armhf': 'y'}> +CONFIG_MVEBU_CLK_CPU policy<{'armhf': 'y'}> +CONFIG_MVEBU_DEVBUS policy<{'armhf': 'y'}> +CONFIG_MVEBU_GICP policy<{'arm64': 'y'}> +CONFIG_MVEBU_ICU policy<{'arm64': 'y'}> +CONFIG_MVEBU_MBUS policy<{'armhf': 'y'}> +CONFIG_MVEBU_ODMI policy<{'arm64': 'y'}> +CONFIG_MVEBU_PIC policy<{'arm64': 'y'}> +CONFIG_MVEBU_SEI policy<{'arm64': 'y'}> +CONFIG_MVIAC3_2 policy<{'i386': 'n'}> +CONFIG_MVIAC7 policy<{'i386': 'n'}> +CONFIG_MVMDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MVNETA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MVNETA_BM_ENABLE policy<{'armhf': 'n'}> +CONFIG_MVPP2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_MV_XOR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_MV_XOR_V2 policy<{'arm64': 'y'}> +CONFIG_MWAVE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MWIFIEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MWIFIEX_PCIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MWIFIEX_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MWIFIEX_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MWINCHIP3D policy<{'i386': 'n'}> +CONFIG_MWINCHIPC6 policy<{'i386': 'n'}> +CONFIG_MWL8K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MX3_IPU policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_MX3_IPU_IRQS policy<{'arm64': '4', 'armhf-generic': '4'}> +CONFIG_MXC4005 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MXC6255 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MXC_CLK policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_MXC_CLK_SCU policy<{'arm64': 'y'}> +CONFIG_MXC_TZIC policy<{'armhf-generic': 'y'}> +CONFIG_MXM_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_MXS_DMA policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_MYRI10GE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_MYRI10GE_DCA policy<{'amd64': 'y'}> +CONFIG_N2 policy<{'i386': 'm'}> +CONFIG_NAMESPACES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NATIONAL_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NATSEMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NAU7802 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NBPFAXI_DMA policy<{'armhf': 'm'}> +CONFIG_NCSI_OEM_CMD_GET_MAC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ND_BLK policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ND_BTT policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ND_CLAIM policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ND_PFN policy<{'amd64': 'm', 'ppc64el': 'm'}> +CONFIG_NE2000 policy<{'i386': 'm'}> +CONFIG_NE2K_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NEED_DMA_MAP_STATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NEED_MULTIPLE_NODES policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_NEED_SG_DMA_LENGTH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NEON policy<{'armhf': 'y'}> +CONFIG_NET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET5501 policy<{'i386': 'y'}> +CONFIG_NETCONSOLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETCONSOLE_DYNAMIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETDEVICES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETDEVSIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETDEV_NOTIFIER_ERROR_INJECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NETFILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_ADVANCED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_CONNCOUNT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_FAMILY_ARP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_FAMILY_BRIDGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_INGRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_NETLINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_NETLINK_ACCT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_NETLINK_GLUE_CT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETFILTER_NETLINK_LOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_NETLINK_OSF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_NETLINK_QUEUE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_SYNPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XTABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_CONNMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_BPF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CGROUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CLUSTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_COMMENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CONNBYTES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CONNLABEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CONNMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CONNTRACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_CPU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_DCCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_DEVGROUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_DSCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_ECN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_ESP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_HELPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_HL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_IPCOMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_IPRANGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_IPVS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_L2TP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_LENGTH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_LIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_MAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_MARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_MULTIPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_NFACCT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_OSF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_OWNER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_PHYSDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_PKTTYPE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_POLICY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_QUOTA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_RATEEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_REALM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_RECENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_SCTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_SOCKET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_STATE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_STATISTIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_STRING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_TCPMSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_TIME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_MATCH_U32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_SET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_AUDIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_CHECKSUM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_CLASSIFY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_CONNMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_CT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_DSCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_HL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_HMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_IDLETIMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_LED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NETFILTER_XT_TARGET_LOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_MARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_MASQUERADE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_NETMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_NFLOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_NFQUEUE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_NOTRACK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NETFILTER_XT_TARGET_RATEEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_REDIRECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_SECMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_TCPMSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_TEE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_TPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETFILTER_XT_TARGET_TRACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETIUCV policy<{'s390x': 'm'}> +CONFIG_NETLABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETLINK_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NETPOLL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NETWORK_FILESYSTEMS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETWORK_SECMARK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NETXEN_NIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_9P_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NET_9P_RDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_9P_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_9P_XEN policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_NET_ACT_BPF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_CONNMARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_CSUM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_CT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_CTINFO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_GACT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_IFE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NET_ACT_IPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_MIRRED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_MPLS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_PEDIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_POLICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_SAMPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_SIMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_SKBEDIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_SKBMOD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_TUNNEL_KEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_ACT_VLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CALXEDA_XGMAC policy<{'armhf': 'm'}> +CONFIG_NET_CLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_CLS_ACT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_CLS_BASIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_BPF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_CGROUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_FLOW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_FLOWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_FW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_MATCHALL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_ROUTE4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CLS_U32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_DEVLINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_DSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_BCM_SF2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_LANTIQ_GSWIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_LOOP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NET_DSA_MICROCHIP_KSZ8795 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MICROCHIP_KSZ9477 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MT7530 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MV88E6060 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MV88E6XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_DSA_MV88E6XXX_PTP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_DSA_QCA8K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_REALTEK_SMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_SJA1105 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_SJA1105_PTP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_DSA_SJA1105_TAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_DSA_SMSC_LAN9303 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_SMSC_LAN9303_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_SMSC_LAN9303_MDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_8021Q policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_BRCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_BRCM_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_BRCM_PREPEND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_DSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_EDSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_GSWIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_KSZ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_LAN9303 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_MTK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_QCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_SJA1105 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_TAG_TRAILER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_VITESSE_VSC73XX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_NET_DSA_VITESSE_VSC73XX_SPI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_NET_EGRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_EMATCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_EMATCH_CANID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NET_EMATCH_CMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_IPSET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_IPT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_META policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_NBYTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_STACK policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32', 's390x': '32'}> +CONFIG_NET_EMATCH_TEXT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_EMATCH_U32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_FAILOVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_FC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_FLOW_LIMIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_FOU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_FOU_IP_TUNNELS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_IFE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_INGRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_IPGRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_IPGRE_BROADCAST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_IPGRE_DEMUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_IPIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_IPVTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_IP_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_KEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_KEY_MIGRATE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NET_L3_MASTER_DEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_MPLS_GSO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_NCSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_NS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_NSH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_PKTGEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_POLL_CONTROLLER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_PTP_CLASSIFY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_REDIRECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_RX_BUSY_POLL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_SB1000 policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_NET_SCHED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_SCH_CAKE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_CBS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_CHOKE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_CODEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_DEFAULT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NET_SCH_DRR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_ETF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_FIFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_SCH_FQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_FQ_CODEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_GRED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_HFSC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_HHF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_HTB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_INGRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_MQPRIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_MULTIQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_NETEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_PIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_PLUG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_PRIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_QFQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_RED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_SFB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_SFQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_SKBPRIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_TAPRIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_TBF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SCH_TEQL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_SOCK_MSG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_TC_SKB_EXT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_TEAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TEAM_MODE_BROADCAST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TEAM_MODE_LOADBALANCE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TEAM_MODE_RANDOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TEAM_MODE_ROUNDROBIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_TULIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_UDP_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_VENDOR_3COM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_8390 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_VENDOR_ADAPTEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_AGERE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_ALACRITECH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_ALLWINNER policy<{'arm64': 'y'}> +CONFIG_NET_VENDOR_ALTEON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_AMAZON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_AMD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_AQUANTIA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_ARC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_ATHEROS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_AURORA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_BROADCOM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_BROCADE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_CADENCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_CAVIUM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_CHELSIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_CIRRUS policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_NET_VENDOR_CISCO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_CORTINA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_DEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_DLINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_EZCHIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_FARADAY policy<{'armhf': 'y'}> +CONFIG_NET_VENDOR_FREESCALE policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_NET_VENDOR_FUJITSU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_NET_VENDOR_GOOGLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_HISILICON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_NET_VENDOR_HP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_HUAWEI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_I825XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_VENDOR_IBM policy<{'ppc64el': 'y'}> +CONFIG_NET_VENDOR_INTEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_MARVELL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_MEDIATEK policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_NET_VENDOR_MELLANOX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_MICREL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_MICROCHIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_MICROSEMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_MYRI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_NATSEMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_NETERION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_NETRONOME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_NI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_NVIDIA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_OKI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_PACKET_ENGINES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_PENSANDO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_QLOGIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_QUALCOMM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_RDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_REALTEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_RENESAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_ROCKER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SAMSUNG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SEEQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SILAN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SMSC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SOCIONEXT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_SOLARFLARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_STMICRO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SUN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_SYNOPSYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NET_VENDOR_TEHUTI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_TI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_VIA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_WIZNET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NET_VENDOR_XILINX policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NET_VENDOR_XIRCOM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_NET_VRF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NET_XGENE policy<{'arm64': 'm'}> +CONFIG_NET_XGENE_V2 policy<{'arm64': 'm'}> +CONFIG_NEW_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_NFC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_NFC_DIGITAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_FDP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_FDP_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_HCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MEI_PHY policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NFC_MICROREAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MICROREAD_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MICROREAD_MEI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NFC_MRVL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MRVL_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MRVL_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MRVL_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_MRVL_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_NCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_NCI_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_NCI_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_NXP_NCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_NXP_NCI_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN533 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN533_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN533_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN544 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN544_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_PN544_MEI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NFC_PORT100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_S3FWRN5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_S3FWRN5_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_SHDLC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NFC_SIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST21NFCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST21NFCA_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST95HF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST_NCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST_NCI_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_ST_NCI_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFC_TRF7970A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFIT_SECURITY_DEBUG policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_NFP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_NFP_APP_ABM_NIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NFP_APP_FLOWER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NFP_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NFSD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFSD_BLOCKLAYOUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_FLEXFILELAYOUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_PNFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_SCSILAYOUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_V2_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_V3 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_V3_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_V4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFSD_V4_SECURITY_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_ACL_SUPPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFS_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFS_FSCACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_SWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_USE_KERNEL_DNS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_USE_LEGACY_DNS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NFS_V2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFS_V3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFS_V3_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_V4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFS_V4_1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN policy<{'amd64': '"kernel.org"', 'arm64': '"kernel.org"', 'armhf': '"kernel.org"', 'i386': '"kernel.org"', 'ppc64el': '"kernel.org"', 's390x': '"kernel.org"'}> +CONFIG_NFS_V4_1_MIGRATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_V4_2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFS_V4_SECURITY_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NFTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NFTL_RW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NFT_BRIDGE_META policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_BRIDGE_REJECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_COMPAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_CONNLIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_COUNTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_CT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_DUP_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_DUP_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_DUP_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FIB_INET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FIB_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FIB_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FIB_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FLOW_OFFLOAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_FWD_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_HASH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_LIMIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_LOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_MASQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_NUMGEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_OBJREF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_OSF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_QUEUE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_QUOTA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_REDIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_REJECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_REJECT_INET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_REJECT_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_REJECT_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_SOCKET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_SYNPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_TPROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_TUNNEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NFT_XFRM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_AMANDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_BROADCAST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_FTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_H323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_IRC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_LABELS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_MARK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_NETBIOS_NS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_PPTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_PROCFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NF_CONNTRACK_SANE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_SECMARK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_SIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_SNMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_TFTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CONNTRACK_TIMEOUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_TIMESTAMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CONNTRACK_ZONES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CT_NETLINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CT_NETLINK_HELPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CT_NETLINK_TIMEOUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_CT_PROTO_DCCP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CT_PROTO_GRE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CT_PROTO_SCTP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_CT_PROTO_UDPLITE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_DEFRAG_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_DEFRAG_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_DUP_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_DUP_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_DUP_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_FLOW_TABLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_FLOW_TABLE_INET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_FLOW_TABLE_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_FLOW_TABLE_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_ARP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_LOG_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_AMANDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_FTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_H323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_IRC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_MASQUERADE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_NAT_PPTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_REDIRECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_NAT_SIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_SNMP_BASIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_NAT_TFTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_REJECT_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_REJECT_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_SOCKET_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_SOCKET_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_TABLES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_TABLES_ARP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_TABLES_BRIDGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_TABLES_INET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_TABLES_IPV4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_TABLES_IPV6 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_TABLES_NETDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NF_TABLES_SET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_TPROXY_IPV4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NF_TPROXY_IPV6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NI65 policy<{'i386': 'm'}> +CONFIG_NI903X_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NIC7018_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NILFS2_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NIU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NI_XGE_MANAGEMENT_ENET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NL80211_TESTMODE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NLATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NLMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ASCII policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_1250 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_1251 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_437 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NLS_CODEPAGE_737 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_775 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_850 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_852 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_855 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_857 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_860 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_861 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_862 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_863 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_864 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_865 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_866 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_869 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_874 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_932 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_936 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_949 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_CODEPAGE_950 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_DEFAULT policy<{'amd64': '"utf8"', 'arm64': '"utf8"', 'armhf': '"utf8"', 'i386': '"utf8"', 'ppc64el': '"utf8"', 's390x': '"utf8"'}> +CONFIG_NLS_ISO8859_1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_13 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_14 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_15 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_7 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_ISO8859_9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_KOI8_R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_KOI8_U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_CELTIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_CENTEURO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_CROATIAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_CYRILLIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_GAELIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_GREEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_ICELAND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_INUIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_ROMAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_ROMANIAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_MAC_TURKISH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NLS_UTF8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NMI_IPI policy<{'ppc64el': 'y'}> +CONFIG_NOA1305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NODES_SHIFT policy<{'amd64': '10', 'arm64': '6', 'ppc64el': '8', 's390x': '4'}> +CONFIG_NODES_SPAN_OTHER_NODES policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NOHIGHMEM policy<{'i386': 'n'}> +CONFIG_NOKIA_MODEM policy<{'armhf-generic': 'm'}> +CONFIG_NONSTATIC_KERNEL policy<{'ppc64el': 'y'}> +CONFIG_NOP_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NORTEL_HERMES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NOTIFIER_ERROR_INJECTION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NOUVEAU_DEBUG policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'i386': '5', 'ppc64el': '5'}> +CONFIG_NOUVEAU_DEBUG_DEFAULT policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'i386': '3', 'ppc64el': '3'}> +CONFIG_NOUVEAU_DEBUG_MMU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NOUVEAU_PLATFORM_DRIVER policy<{'armhf-generic': 'y'}> +CONFIG_NOZOMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_NO_HZ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NO_HZ_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NO_HZ_FULL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}> +CONFIG_NO_IOPORT_MAP policy<{'armhf': 'y', 's390x': 'y'}> +CONFIG_NPCM7XX_KCS_IPMI_BMC policy<{'armhf': 'm'}> +CONFIG_NPCM7XX_TIMER policy<{'armhf': 'y'}> +CONFIG_NPCM7XX_WATCHDOG policy<{'armhf': 'y'}> +CONFIG_NPCM_ADC policy<{'armhf': 'm'}> +CONFIG_NR_CPUS_DEFAULT policy<{'amd64': '8192', 'i386': '8'}> +CONFIG_NR_CPUS_RANGE_BEGIN policy<{'amd64': '8192', 'i386': '2'}> +CONFIG_NR_CPUS_RANGE_END policy<{'amd64': '8192', 'i386': '8'}> +CONFIG_NR_IRQS policy<{'ppc64el': '512'}> +CONFIG_NS83820 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NSC_GPIO policy<{'i386': 'm'}> +CONFIG_NTB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_NTB_AMD policy<{'amd64': 'n'}> +CONFIG_NTB_IDT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_INTEL policy<{'amd64': 'm'}> +CONFIG_NTB_MSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NTB_MSI_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_NTB_NETDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_PERF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_PINGPONG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_SWITCHTEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_TOOL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTB_TRANSPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_NTFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NTFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NTFS_RW policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_NULL_TTY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NUMA_BALANCING policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NVDIMM_DAX policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_NVDIMM_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NVDIMM_PFN policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_NVEC_PAZ00 policy<{'armhf-generic': 'm'}> +CONFIG_NVEC_POWER policy<{'armhf-generic': 'm'}> +CONFIG_NVMEM_BCM_OCOTP policy<{'arm64': 'm'}> +CONFIG_NVMEM_IMX_IIM policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_NVMEM_IMX_OCOTP policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_NVMEM_IMX_OCOTP_SCU policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_NVMEM_REBOOT_MODE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_NVMEM_SNVS_LPGPR policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_NVMEM_SUNXI_SID policy<{'arm64': 'm'}> +CONFIG_NVMEM_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_NVMEM_VF610_OCOTP policy<{'armhf-generic': 'n'}> +CONFIG_NVMEM_ZYNQMP policy<{'arm64': 'y'}> +CONFIG_NVME_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_FABRICS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_MULTIPATH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_NVME_RDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TARGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TARGET_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TARGET_FCLOOP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_NVME_TARGET_LOOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TARGET_RDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TARGET_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NVME_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_NV_TCO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_NXP_TJA11XX_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_N_HDLC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_OABI_COMPAT policy<{'armhf': 'n'}> +CONFIG_OBJAGG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OCFS2_DEBUG_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_OCFS2_DEBUG_MASKLOG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OCFS2_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OCFS2_FS_O2CB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OCFS2_FS_STATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OCFS2_FS_USERSPACE_CLUSTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OCTEONTX2_AF policy<{'arm64': 'm'}> +CONFIG_OCTEONTX2_MBOX policy<{'arm64': 'm'}> +CONFIG_OCXL policy<{'ppc64el': 'm'}> +CONFIG_OCXL_BASE policy<{'ppc64el': 'y'}> +CONFIG_OF policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_OF_ADDRESS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_DMA_DEFAULT_COHERENT policy<{'ppc64el': 'y'}> +CONFIG_OF_DYNAMIC policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_EARLY_FLATTREE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_FLATTREE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_FPGA_REGION policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_OF_GPIO policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_IOMMU policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_IRQ policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_KOBJ policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_MDIO policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_NET policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_NUMA policy<{'arm64': 'y'}> +CONFIG_OF_OVERLAY policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_PMEM policy<{'arm64': 'm', 'armhf-generic-lpae': 'm', 'ppc64el': 'm'}> +CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}> +CONFIG_OF_RESERVED_MEM policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_RESOLVE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_OF_UNITTEST policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}> +CONFIG_OID_REGISTRY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OLD_SIGACTION policy<{'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_OLD_SIGSUSPEND policy<{'ppc64el': 'y'}> +CONFIG_OLD_SIGSUSPEND3 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_OMAP2PLUS_MBOX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_OMAP2_VRFB policy<{'armhf-generic': 'y'}> +CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE policy<{'armhf-generic': 'n'}> +CONFIG_OMAP3_SDRC_AC_TIMING policy<{'armhf-generic': 'n'}> +CONFIG_OMAP3_THERMAL policy<{'armhf-generic': 'n'}> +CONFIG_OMAP4_THERMAL policy<{'armhf-generic': 'y'}> +CONFIG_OMAP5_ERRATA_801819 policy<{'armhf': 'y'}> +CONFIG_OMAP_32K_TIMER policy<{'armhf': 'y'}> +CONFIG_OMAP_CONTROL_PHY policy<{'armhf': 'm'}> +CONFIG_OMAP_DM_TIMER policy<{'armhf': 'y'}> +CONFIG_OMAP_GPMC policy<{'armhf': 'y'}> +CONFIG_OMAP_GPMC_DEBUG policy<{'armhf': 'n'}> +CONFIG_OMAP_INTERCONNECT policy<{'armhf': 'y'}> +CONFIG_OMAP_INTERCONNECT_BARRIER policy<{'armhf': 'y'}> +CONFIG_OMAP_IOMMU policy<{'armhf': 'y'}> +CONFIG_OMAP_IOMMU_DEBUG policy<{'armhf': 'n'}> +CONFIG_OMAP_IRQCHIP policy<{'armhf': 'y'}> +CONFIG_OMAP_MBOX_KFIFO_SIZE policy<{'arm64': '256', 'armhf': '256'}> +CONFIG_OMAP_OCP2SCP policy<{'armhf': 'm'}> +CONFIG_OMAP_PACKAGE_CBB policy<{'armhf-generic': 'y'}> +CONFIG_OMAP_REMOTEPROC policy<{'armhf-generic': 'm'}> +CONFIG_OMAP_RESET_CLOCKS policy<{'armhf': 'y'}> +CONFIG_OMAP_SSI policy<{'armhf-generic': 'm'}> +CONFIG_OMAP_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_OMAP_WATCHDOG policy<{'armhf': 'm'}> +CONFIG_OMFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_OPAL_CORE policy<{'ppc64el': 'n'}> +CONFIG_OPAL_PRD policy<{'ppc64el': 'm'}> +CONFIG_OPENVSWITCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OPENVSWITCH_GENEVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OPENVSWITCH_GRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OPENVSWITCH_VXLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OPROFILE policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OPROFILE_EVENT_MULTIPLEX policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_OPROFILE_NMI_TIMER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_OPT3001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_OPTEE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES policy<{'arm64': '1', 'armhf': '1'}> +CONFIG_OPTIMIZE_INLINING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OPTPROBES policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ORANGEFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ORINOCO_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ORION_IRQCHIP policy<{'armhf': 'y'}> +CONFIG_ORION_TIMER policy<{'armhf': 'y'}> +CONFIG_ORION_WATCHDOG policy<{'armhf': 'm'}> +CONFIG_OSF_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_OUTER_CACHE policy<{'armhf': 'y'}> +CONFIG_OUTER_CACHE_SYNC policy<{'armhf': 'y'}> +CONFIG_OUTPUT_FORMAT policy<{'amd64': '"elf64-x86-64"', 'i386': '"elf32-i386"'}> +CONFIG_OVERLAY_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_OVERLAY_FS_INDEX policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_OVERLAY_FS_METACOPY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OVERLAY_FS_REDIRECT_DIR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_OVERLAY_FS_XINO_AUTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_OWL_DMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_OWL_PM_DOMAINS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_OWL_PM_DOMAINS_HELPER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_OWL_TIMER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_P54_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_P54_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_P54_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_P54_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_P54_SPI_DEFAULT_EEPROM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_P54_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PA12203001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PACKET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PACKET_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PACKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PACK_STACK policy<{'s390x': 'y'}> +CONFIG_PADATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_COUNTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_EXTENSION policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PAGE_OFFSET policy<{'armhf': '0xC0000000', 'i386': '0xC0000000', 'ppc64el': '0xc000000000000000'}> +CONFIG_PAGE_OWNER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PAGE_POOL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PAGE_TABLE_ISOLATION policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PALMAS_GPADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PANASONIC_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PANEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PANEL_CHANGE_MESSAGE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PANEL_PARPORT policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_PANEL_PROFILE policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'i386': '5', 'ppc64el': '5'}> +CONFIG_PANIC_ON_OOPS_VALUE policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_PANIC_TIMEOUT policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '10', 's390x': '0'}> +CONFIG_PANTHERLORD_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PAPR_SCM policy<{'ppc64el': 'm'}> +CONFIG_PARAVIRT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y'}> +CONFIG_PARAVIRT_CLOCK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PARAVIRT_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_PARAVIRT_SPINLOCKS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PARAVIRT_TIME_ACCOUNTING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_PARAVIRT_XXL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PARIDE policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_ATEN policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_BPCK policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_BPCK6 policy<{'armhf': 'm', 'i386': 'm'}> +CONFIG_PARIDE_COMM policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_DSTR policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_EPAT policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_EPATC8 policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PARIDE_EPIA policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_FIT2 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_FIT3 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_FRIQ policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_FRPW policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_KBIC policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_KTTI policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_ON20 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_ON26 policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_PCD policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_PD policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_PF policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_PG policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARIDE_PT policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARMAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PARPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PARPORT_1284 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PARPORT_AX88796 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARPORT_NOT_PC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PARPORT_PANEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARPORT_PC policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARPORT_PC_FIFO policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PARPORT_PC_PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PARPORT_PC_SUPERIO policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PARPORT_SERIAL policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PARTITION_ADVANCED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PARTITION_PERCPU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PATA_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_PATA_ALI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_AMD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_ARTOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_ATIIXP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_ATP867X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_CMD640_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_CMD64X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_CS5520 policy<{'i386': 'm'}> +CONFIG_PATA_CS5530 policy<{'i386': 'm'}> +CONFIG_PATA_CS5535 policy<{'i386': 'm'}> +CONFIG_PATA_CS5536 policy<{'i386': 'm'}> +CONFIG_PATA_CYPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_EFAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_HPT366 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_HPT37X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_HPT3X2N policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_HPT3X3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_IMX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_PATA_ISAPNP policy<{'i386': 'm'}> +CONFIG_PATA_IT8213 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_IT821X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_JMICRON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_MARVELL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_MPIIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_NETCELL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_NINJA32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_NS87410 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_NS87415 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_OF_PLATFORM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_OLDPIIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_OPTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_OPTIDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_PCMCIA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PATA_PDC2027X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_PDC_OLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_QDI policy<{'i386': 'm'}> +CONFIG_PATA_RADISYS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_RDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_RZ1000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_SC1200 policy<{'i386': 'm'}> +CONFIG_PATA_SCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_SERVERWORKS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_SIL680 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_SIS policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_PATA_TOSHIBA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_TRIFLEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_VIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_WINBOND policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PATA_WINBOND_VLB policy<{'i386': 'm'}> +CONFIG_PC104 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PC300TOO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PC8736x_GPIO policy<{'i386': 'm'}> +CONFIG_PC87413_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCC policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_PCCARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'n', 'i386': 'm', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PCCARD_NONSTATIC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCENGINES_APU2 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCF50633_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PCF50633_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PCH_CAN policy<{'i386': 'm'}> +CONFIG_PCH_DMA policy<{'i386': 'm'}> +CONFIG_PCH_GBE policy<{'i386': 'm'}> +CONFIG_PCH_PHUB policy<{'i386': 'm'}> +CONFIG_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI200SYN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PCIEAER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_PCIEAER_INJECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIEASPM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_PCIEASPM_PERFORMANCE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIEASPM_POWERSAVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIEASPM_POWER_SUPERSAVE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIE_AL policy<{'arm64': 'y'}> +CONFIG_PCIE_ALTERA policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_ALTERA_MSI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_ARMADA_8K policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_BW policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIE_CADENCE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCIE_CADENCE_EP policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCIE_CADENCE_HOST policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCIE_DPC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_PCIE_DW policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_DW_EP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_DW_HOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_DW_PLAT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_DW_PLAT_EP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_DW_PLAT_HOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_ECRC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 's390x': 'n'}> +CONFIG_PCIE_HISI_STB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_IPROC policy<{'arm64': 'm'}> +CONFIG_PCIE_IPROC_MSI policy<{'arm64': 'y'}> +CONFIG_PCIE_IPROC_PLATFORM policy<{'arm64': 'm'}> +CONFIG_PCIE_KIRIN policy<{'arm64': 'y'}> +CONFIG_PCIE_MEDIATEK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_MOBIVEIL policy<{'arm64': 'y'}> +CONFIG_PCIE_PME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCIE_PTM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_PCIE_QCOM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_RCAR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_ROCKCHIP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_ROCKCHIP_EP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCIE_ROCKCHIP_HOST policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PCIE_UNIPHIER policy<{'armhf': 'y'}> +CONFIG_PCIE_XILINX policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCIE_XILINX_NWL policy<{'arm64': 'y'}> +CONFIG_PCIPCWATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PCI_AARDVARK policy<{'arm64': 'y'}> +CONFIG_PCI_ATMEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PCI_ATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_BIOS policy<{'i386': 'y'}> +CONFIG_PCI_BRIDGE_EMUL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCI_CNB20LE_QUIRK policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_PCI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PCI_DIRECT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCI_DOMAINS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_DOMAINS_GENERIC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCI_DRA7XX policy<{'armhf': 'y'}> +CONFIG_PCI_DRA7XX_EP policy<{'armhf': 'y'}> +CONFIG_PCI_DRA7XX_HOST policy<{'armhf': 'y'}> +CONFIG_PCI_ECAM policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCI_ENDPOINT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_ENDPOINT_CONFIGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_ENDPOINT_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PCI_EPF_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PCI_FTPCI100 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCI_GOANY policy<{'i386': 'y'}> +CONFIG_PCI_GOBIOS policy<{'i386': 'n'}> +CONFIG_PCI_GODIRECT policy<{'i386': 'n'}> +CONFIG_PCI_GOMMCONFIG policy<{'i386': 'n'}> +CONFIG_PCI_HISI policy<{'arm64': 'y'}> +CONFIG_PCI_HOST_COMMON policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCI_HOST_GENERIC policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCI_HOST_THUNDER_ECAM policy<{'arm64': 'y'}> +CONFIG_PCI_HOST_THUNDER_PEM policy<{'arm64': 'y'}> +CONFIG_PCI_HYPERV policy<{'amd64': 'm'}> +CONFIG_PCI_HYPERV_INTERFACE policy<{'amd64': 'm'}> +CONFIG_PCI_IMX6 policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_PCI_IOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_KEYSTONE policy<{'arm64': 'y'}> +CONFIG_PCI_KEYSTONE_EP policy<{'arm64': 'y'}> +CONFIG_PCI_KEYSTONE_HOST policy<{'arm64': 'y'}> +CONFIG_PCI_LABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCI_LAYERSCAPE policy<{'arm64': 'y', 'armhf': 'n'}> +CONFIG_PCI_LAYERSCAPE_EP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PCI_LOCKLESS_CONFIG policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCI_MESON policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n'}> +CONFIG_PCI_MMCONFIG policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCI_MSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_MSI_IRQ_DOMAIN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PCI_MVEBU policy<{'armhf': 'y'}> +CONFIG_PCI_P2PDMA policy<{'amd64': 'n', 'ppc64el': 'n'}> +CONFIG_PCI_PASID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PCI_PF_STUB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PCI_PRI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PCI_QUIRKS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PCI_RCAR_GEN2 policy<{'armhf': 'y'}> +CONFIG_PCI_REALLOC_ENABLE_AUTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PCI_STUB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PCI_SW_SWITCHTEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PCI_SYSCALL policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PCI_TEGRA policy<{'armhf-generic': 'y'}> +CONFIG_PCI_V3_SEMI policy<{'armhf': 'y'}> +CONFIG_PCI_XEN policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCI_XGENE policy<{'arm64': 'y'}> +CONFIG_PCI_XGENE_MSI policy<{'arm64': 'y'}> +CONFIG_PCMCIA policy<{'amd64': 'm', 'arm64': 'n', 'i386': 'm'}> +CONFIG_PCMCIA_3C574 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_3C589 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_AHA152X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_ATMEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_AXNET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_FDOMAIN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_FMVJ18X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_HERMES policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_LOAD_CIS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PCMCIA_NINJA_SCSI policy<{'i386': 'm'}> +CONFIG_PCMCIA_NMCLAN policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_PCNET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_PROBE policy<{'i386': 'y'}> +CONFIG_PCMCIA_QLOGIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_RAYCS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_SMC91C92 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_SPECTRUM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_SYM53C500 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_WL3501 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_XIRC2PS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PCMCIA_XIRCOM policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_PCNET32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PCSPKR_PLATFORM policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PCWATCHDOG policy<{'i386': 'm'}> +CONFIG_PD6729 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PDA_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PDC_ADMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PEAQ_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PERCPU_STATS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PERCPU_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PERF_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PERF_EVENTS_AMD_POWER policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_PERF_EVENTS_INTEL_CSTATE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PERF_EVENTS_INTEL_RAPL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PERF_EVENTS_INTEL_UNCORE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PERF_USE_VMALLOC policy<{'armhf': 'y'}> +CONFIG_PERSISTENT_KEYRINGS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PFAULT policy<{'s390x': 'y'}> +CONFIG_PGSTE policy<{'s390x': 'y'}> +CONFIG_PGTABLE_LEVELS policy<{'amd64': '4', 'arm64': '4', 'armhf-generic': '2', 'armhf-generic-lpae': '3', 'i386': '3', 'ppc64el': '4', 's390x': '5'}> +CONFIG_PHANTOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PHONET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PHYLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_PHYLINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHYSICAL_ALIGN policy<{'amd64': '0x200000', 'i386': '0x1000000'}> +CONFIG_PHYSICAL_START policy<{'amd64': '0x1000000', 'i386': '0x1000000', 'ppc64el': '0x00000000'}> +CONFIG_PHYS_ADDR_T_64BIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PHY_AM654_SERDES policy<{'arm64': 'm'}> +CONFIG_PHY_BCM_NS_USB2 policy<{'arm64': 'm'}> +CONFIG_PHY_BCM_NS_USB3 policy<{'arm64': 'm'}> +CONFIG_PHY_BCM_SR_PCIE policy<{'arm64': 'm'}> +CONFIG_PHY_BCM_SR_USB policy<{'arm64': 'm'}> +CONFIG_PHY_BERLIN_SATA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_BERLIN_USB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_BRCM_SATA policy<{'arm64': 'y'}> +CONFIG_PHY_BRCM_USB policy<{'arm64': 'm'}> +CONFIG_PHY_CADENCE_DP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_CADENCE_DPHY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_CADENCE_SIERRA policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_CPCAP_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_DM816X_USB policy<{'armhf': 'm'}> +CONFIG_PHY_EXYNOS5250_SATA policy<{'armhf': 'y'}> +CONFIG_PHY_EXYNOS5250_USB2 policy<{'armhf': 'y'}> +CONFIG_PHY_EXYNOS5_USBDRD policy<{'armhf': 'm'}> +CONFIG_PHY_EXYNOS_DP_VIDEO policy<{'armhf': 'y'}> +CONFIG_PHY_EXYNOS_MIPI_VIDEO policy<{'armhf': 'y'}> +CONFIG_PHY_EXYNOS_PCIE policy<{'armhf': 'y'}> +CONFIG_PHY_FSL_IMX8MQ_USB policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_HI3660_USB policy<{'arm64': 'm'}> +CONFIG_PHY_HI6220_USB policy<{'arm64': 'm'}> +CONFIG_PHY_HISI_INNO_USB2 policy<{'arm64': 'm'}> +CONFIG_PHY_HISTB_COMBPHY policy<{'arm64': 'm'}> +CONFIG_PHY_HIX5HD2_SATA policy<{'armhf': 'm'}> +CONFIG_PHY_MAPPHONE_MDM6600 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_MESON8B_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MESON_G12A_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MESON_G12A_USB3_PCIE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MESON_GXL_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MESON_GXL_USB3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MIXEL_MIPI_DPHY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_MTK_TPHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MTK_UFS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MTK_XSPHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MVEBU_A3700_COMPHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MVEBU_A3700_UTMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MVEBU_A38X_COMPHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MVEBU_CP110_COMPHY policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_MVEBU_SATA policy<{'armhf': 'y'}> +CONFIG_PHY_NS2_PCIE policy<{'arm64': 'y'}> +CONFIG_PHY_NS2_USB_DRD policy<{'arm64': 'm'}> +CONFIG_PHY_OCELOT_SERDES policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_PXA_28NM_HSIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PHY_PXA_28NM_USB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PHY_QCOM_APQ8064_SATA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_IPQ806X_SATA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_PCIE2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_QMP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_QUSB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_UFS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_UFS_14NM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_QCOM_USB_HS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_QCOM_USB_HSIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_RCAR_GEN2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_RCAR_GEN3_PCIE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_RCAR_GEN3_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_RCAR_GEN3_USB3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_DP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_EMMC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_INNO_HDMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_INNO_USB2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_PCIE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_TYPEC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_ROCKCHIP_USB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PHY_SAMSUNG_USB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_SUN4I_USB policy<{'arm64': 'm'}> +CONFIG_PHY_SUN6I_MIPI_DPHY policy<{'arm64': 'm'}> +CONFIG_PHY_SUN9I_USB policy<{'arm64': 'n'}> +CONFIG_PHY_TEGRA_XUSB policy<{'armhf-generic': 'm'}> +CONFIG_PHY_TI_GMII_SEL policy<{'armhf': 'y'}> +CONFIG_PHY_TUSB1210 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PHY_UNIPHIER_PCIE policy<{'armhf': 'm'}> +CONFIG_PHY_UNIPHIER_USB2 policy<{'armhf': 'm'}> +CONFIG_PHY_UNIPHIER_USB3 policy<{'armhf': 'm'}> +CONFIG_PHY_XGENE policy<{'arm64': 'y'}> +CONFIG_PI433 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PID_IN_CONTEXTIDR policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_PID_NS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PINCONF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PINCTRL_AMD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_APQ8064 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_APQ8084 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_ARMADA_370 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_ARMADA_375 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_ARMADA_37XX policy<{'arm64': 'y'}> +CONFIG_PINCTRL_ARMADA_38X policy<{'armhf': 'y'}> +CONFIG_PINCTRL_ARMADA_39X policy<{'armhf': 'y'}> +CONFIG_PINCTRL_ARMADA_AP806 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_ARMADA_CP110 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_ARMADA_XP policy<{'armhf': 'y'}> +CONFIG_PINCTRL_AS370 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_AS3722 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_ASPEED policy<{'armhf': 'y'}> +CONFIG_PINCTRL_ASPEED_G6 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_AXP209 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_BAYTRAIL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PINCTRL_BCM2835 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_BERLIN policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_BERLIN_BG2 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_BERLIN_BG2CD policy<{'armhf': 'y'}> +CONFIG_PINCTRL_BERLIN_BG2Q policy<{'armhf': 'y'}> +CONFIG_PINCTRL_BERLIN_BG4CT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_BM1880 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_BROXTON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_CANNONLAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_CEDARFORK policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_CS47L15 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_CS47L35 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_CS47L85 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_CS47L90 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_CS47L92 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_DENVERTON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_DOVE policy<{'armhf': 'y'}> +CONFIG_PINCTRL_EXYNOS policy<{'armhf': 'y'}> +CONFIG_PINCTRL_EXYNOS_ARM policy<{'armhf': 'y'}> +CONFIG_PINCTRL_GEMINILAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_ICELAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_IMX policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX50 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX51 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX6Q policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX6SL policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX6SLL policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX6SX policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX6UL policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX7D policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX7ULP policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_IMX8MM policy<{'arm64': 'y'}> +CONFIG_PINCTRL_IMX8MN policy<{'arm64': 'y'}> +CONFIG_PINCTRL_IMX8MQ policy<{'arm64': 'y'}> +CONFIG_PINCTRL_IMX8QM policy<{'arm64': 'y'}> +CONFIG_PINCTRL_IMX8QXP policy<{'arm64': 'y'}> +CONFIG_PINCTRL_IMX_SCU policy<{'arm64': 'y'}> +CONFIG_PINCTRL_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_IPQ4019 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_IPQ8064 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_IPQ8074 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_IPROC_GPIO policy<{'arm64': 'y'}> +CONFIG_PINCTRL_LEWISBURG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_LOCHNAGAR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_MADERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_MAX77620 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_MCP23S08 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_MDM9615 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MERRIFIELD policy<{'i386': 'n'}> +CONFIG_PINCTRL_MESON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MESON8 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MESON8B policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MESON8_PMX policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MESON_AXG policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MESON_AXG_PMX policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MESON_G12A policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MESON_GXBB policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MESON_GXL policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MSM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MSM8660 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8916 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8960 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8994 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8996 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8998 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MSM8X74 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_MT2701 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MT2712 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT6397 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MT6765 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT6797 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT7622 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT7623 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MT7629 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MT8127 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MT8135 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_MT8173 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT8183 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MT8516 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MTK policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MTK_MOORE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_MTK_PARIS policy<{'arm64': 'y'}> +CONFIG_PINCTRL_MVEBU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_NPCM7XX policy<{'armhf': 'y'}> +CONFIG_PINCTRL_NS2_MUX policy<{'arm64': 'y'}> +CONFIG_PINCTRL_OCELOT policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_OWL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_PALMAS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_PFC_EMEV2 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7740 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7743 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7744 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7745 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A77470 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A774A1 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A774C0 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A7778 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7779 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7790 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7791 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7792 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7793 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7794 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_PFC_R8A7795 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A7796 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A77965 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A77970 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A77980 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A77990 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_R8A77995 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_PFC_SH73A0 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_QCOM_SPMI_PMIC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_QCOM_SSBI_PMIC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_QCS404 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_QDF2XXX policy<{'arm64': 'm'}> +CONFIG_PINCTRL_RK805 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_ROCKCHIP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_RZA1 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_RZA2 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_RZN1 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_S700 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_S900 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_SAMSUNG policy<{'armhf': 'y'}> +CONFIG_PINCTRL_SC7180 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_SDM660 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_SDM845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_SH_PFC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PINCTRL_SH_PFC_GPIO policy<{'armhf': 'y'}> +CONFIG_PINCTRL_SINGLE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_SM8150 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PINCTRL_SPRD policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SPRD_SC9860 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_STMFX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PINCTRL_SUN4I_A10 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN50I_A64 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN50I_A64_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN50I_H5 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN50I_H6 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN50I_H6_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN5I policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN6I_A31 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN6I_A31_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_A23 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_A23_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_A33 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_A83T policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_A83T_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_H3 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_H3_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN8I_V3S policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN9I_A80 policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUN9I_A80_R policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SUNRISEPOINT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PINCTRL_SUNXI policy<{'arm64': 'y'}> +CONFIG_PINCTRL_SX150X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PINCTRL_TEGRA policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TEGRA114 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TEGRA124 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TEGRA20 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TEGRA30 policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TEGRA_XUSB policy<{'armhf-generic': 'y'}> +CONFIG_PINCTRL_TI_IODELAY policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_LD11 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_LD20 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_LD4 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_LD6B policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_PRO4 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_PRO5 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_PXS2 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_PXS3 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_UNIPHIER_SLD8 policy<{'armhf': 'y'}> +CONFIG_PINCTRL_VF610 policy<{'armhf-generic': 'y'}> +CONFIG_PINMUX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PJ4B_ERRATA_4742 policy<{'armhf': 'y'}> +CONFIG_PKCS7_MESSAGE_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PKCS7_TEST_KEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PKCS8_PRIVATE_KEY_PARSER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PKEY policy<{'s390x': 'm'}> +CONFIG_PL310_ERRATA_588369 policy<{'armhf': 'y'}> +CONFIG_PL310_ERRATA_727915 policy<{'armhf': 'y'}> +CONFIG_PL310_ERRATA_753970 policy<{'armhf': 'y'}> +CONFIG_PL310_ERRATA_769419 policy<{'armhf': 'y'}> +CONFIG_PL320_MBOX policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_PL330_DMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PL353_SMC policy<{'armhf': 'm'}> +CONFIG_PLATFORM_MHU policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PLATFORM_SI4713 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PLAT_ORION policy<{'armhf': 'y'}> +CONFIG_PLAT_SAMSUNG policy<{'armhf': 'y'}> +CONFIG_PLAT_SPEAR policy<{'armhf': 'n'}> +CONFIG_PLAT_VERSATILE policy<{'armhf': 'y'}> +CONFIG_PLIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PLUGIN_HOSTCC policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_PLX_HERMES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PM8916_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PMBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PMC_ATOM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PMIC_ADP5520 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PMIC_DA903X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PMIC_DA9052 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PMIC_OPREGION policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_PMS7003 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PM_ADVANCED_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_AUTOSLEEP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PM_CLK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_PM_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_DEVFREQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PM_DEVFREQ_EVENT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_GENERIC_DOMAINS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_GENERIC_DOMAINS_OF policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PM_GENERIC_DOMAINS_SLEEP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_NOTIFIER_ERROR_INJECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PM_OPP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_SLEEP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_SLEEP_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_SLEEP_SMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_SLEEP_SMP_NONZERO_CPU policy<{'ppc64el': 'y'}> +CONFIG_PM_STD_PARTITION policy<{'amd64': '""', 'armhf': '""', 'i386': '""'}> +CONFIG_PM_TEST_SUSPEND policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PM_TRACE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PM_TRACE_RTC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PM_WAKELOCKS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_WAKELOCKS_GC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PM_WAKELOCKS_LIMIT policy<{'amd64': '100', 'arm64': '100', 'armhf': '100', 'i386': '100', 'ppc64el': '100'}> +CONFIG_PNFS_BLOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PNFS_FILE_LAYOUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PNFS_FLEXFILE_LAYOUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PNP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_PNPACPI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_PNPBIOS policy<{'i386': 'y'}> +CONFIG_PNPBIOS_PROC_FS policy<{'i386': 'y'}> +CONFIG_PNP_DEBUG_MESSAGES policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_POSIX_MQUEUE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_POSIX_MQUEUE_SYSCTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_POSIX_TIMERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_POWER7_CPU policy<{'ppc64el': 'n'}> +CONFIG_POWER8_CPU policy<{'ppc64el': 'n'}> +CONFIG_POWER9_CPU policy<{'ppc64el': 'n'}> +CONFIG_POWERCAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_POWERNV_CPUFREQ policy<{'ppc64el': 'y'}> +CONFIG_POWERNV_CPUIDLE policy<{'ppc64el': 'y'}> +CONFIG_POWERNV_OP_PANEL policy<{'ppc64el': 'm'}> +CONFIG_POWER_AVS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_POWER_AVS_OMAP policy<{'armhf-generic': 'y'}> +CONFIG_POWER_AVS_OMAP_CLASS3 policy<{'armhf-generic': 'y'}> +CONFIG_POWER_RESET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_POWER_RESET_AS3722 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_AXXIA policy<{'armhf-generic-lpae': 'y'}> +CONFIG_POWER_RESET_BRCMKONA policy<{'armhf': 'y'}> +CONFIG_POWER_RESET_BRCMSTB policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_POWER_RESET_GPIO policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_GPIO_RESTART policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_HISI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_POWER_RESET_LTC2952 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_MSM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_POWER_RESET_QCOM_PON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_POWER_RESET_QNAP policy<{'armhf': 'n'}> +CONFIG_POWER_RESET_RESTART policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_POWER_RESET_RMOBILE policy<{'armhf': 'm'}> +CONFIG_POWER_RESET_SC27XX policy<{'arm64': 'y'}> +CONFIG_POWER_RESET_SYSCON policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_SYSCON_POWEROFF policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_POWER_RESET_VERSATILE policy<{'armhf': 'y'}> +CONFIG_POWER_RESET_VEXPRESS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_POWER_RESET_XGENE policy<{'arm64': 'n'}> +CONFIG_POWER_SUPPLY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_POWER_SUPPLY_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_POWER_SUPPLY_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PPC policy<{'ppc64el': 'y'}> +CONFIG_PPC64 policy<{'ppc64el': 'y'}> +CONFIG_PPC64_BOOT_WRAPPER policy<{'ppc64el': 'y'}> +CONFIG_PPC64_SUPPORTS_MEMORY_FAILURE policy<{'ppc64el': 'y'}> +CONFIG_PPC_4K_PAGES policy<{'ppc64el': 'n'}> +CONFIG_PPC_64K_PAGES policy<{'ppc64el': 'y'}> +CONFIG_PPC_BARRIER_NOSPEC policy<{'ppc64el': 'y'}> +CONFIG_PPC_BOOK3E_64 policy<{'ppc64el': 'n'}> +CONFIG_PPC_BOOK3S policy<{'ppc64el': 'y'}> +CONFIG_PPC_BOOK3S_64 policy<{'ppc64el': 'y'}> +CONFIG_PPC_COPRO_BASE policy<{'ppc64el': 'y'}> +CONFIG_PPC_DAWR policy<{'ppc64el': 'y'}> +CONFIG_PPC_DENORMALISATION policy<{'ppc64el': 'y'}> +CONFIG_PPC_DISABLE_WERROR policy<{'ppc64el': 'n'}> +CONFIG_PPC_DOORBELL policy<{'ppc64el': 'y'}> +CONFIG_PPC_DT_CPU_FTRS policy<{'ppc64el': 'y'}> +CONFIG_PPC_EARLY_DEBUG policy<{'ppc64el': 'n'}> +CONFIG_PPC_EMULATED_STATS policy<{'ppc64el': 'n'}> +CONFIG_PPC_EPAPR_HV_BYTECHAN policy<{'ppc64el': 'n'}> +CONFIG_PPC_FAST_ENDIAN_SWITCH policy<{'ppc64el': 'n'}> +CONFIG_PPC_FPU policy<{'ppc64el': 'y'}> +CONFIG_PPC_HAVE_KUAP policy<{'ppc64el': 'y'}> +CONFIG_PPC_HAVE_KUEP policy<{'ppc64el': 'y'}> +CONFIG_PPC_HAVE_PMU_SUPPORT policy<{'ppc64el': 'y'}> +CONFIG_PPC_I8259 policy<{'ppc64el': 'y'}> +CONFIG_PPC_ICP_HV policy<{'ppc64el': 'y'}> +CONFIG_PPC_ICP_NATIVE policy<{'ppc64el': 'y'}> +CONFIG_PPC_ICS_RTAS policy<{'ppc64el': 'y'}> +CONFIG_PPC_INDIRECT_PIO policy<{'ppc64el': 'y'}> +CONFIG_PPC_IRQ_SOFT_MASK_DEBUG policy<{'ppc64el': 'n'}> +CONFIG_PPC_KUAP policy<{'ppc64el': 'y'}> +CONFIG_PPC_KUAP_DEBUG policy<{'ppc64el': 'n'}> +CONFIG_PPC_KUEP policy<{'ppc64el': 'y'}> +CONFIG_PPC_MEMTRACE policy<{'ppc64el': 'y'}> +CONFIG_PPC_MM_SLICES policy<{'ppc64el': 'y'}> +CONFIG_PPC_MSI_BITMAP policy<{'ppc64el': 'y'}> +CONFIG_PPC_NATIVE policy<{'ppc64el': 'y'}> +CONFIG_PPC_OF_BOOT_TRAMPOLINE policy<{'ppc64el': 'y'}> +CONFIG_PPC_P7_NAP policy<{'ppc64el': 'y'}> +CONFIG_PPC_PAGE_SHIFT policy<{'ppc64el': '16'}> +CONFIG_PPC_PERF_CTRS policy<{'ppc64el': 'y'}> +CONFIG_PPC_POWERNV policy<{'ppc64el': 'y'}> +CONFIG_PPC_PSERIES policy<{'ppc64el': 'y'}> +CONFIG_PPC_PTDUMP policy<{'ppc64el': 'n'}> +CONFIG_PPC_RADIX_MMU policy<{'ppc64el': 'y'}> +CONFIG_PPC_RADIX_MMU_DEFAULT policy<{'ppc64el': 'y'}> +CONFIG_PPC_RTAS policy<{'ppc64el': 'y'}> +CONFIG_PPC_RTAS_DAEMON policy<{'ppc64el': 'y'}> +CONFIG_PPC_SMLPAR policy<{'ppc64el': 'y'}> +CONFIG_PPC_SMP_MUXED_IPI policy<{'ppc64el': 'y'}> +CONFIG_PPC_SPLPAR policy<{'ppc64el': 'y'}> +CONFIG_PPC_SUBPAGE_PROT policy<{'ppc64el': 'y'}> +CONFIG_PPC_SVM policy<{'ppc64el': 'y'}> +CONFIG_PPC_TRANSACTIONAL_MEM policy<{'ppc64el': 'y'}> +CONFIG_PPC_UDBG_16550 policy<{'ppc64el': 'y'}> +CONFIG_PPC_VAS policy<{'ppc64el': 'y'}> +CONFIG_PPC_WATCHDOG policy<{'ppc64el': 'y'}> +CONFIG_PPC_WERROR policy<{'ppc64el': 'y'}> +CONFIG_PPC_XICS policy<{'ppc64el': 'y'}> +CONFIG_PPC_XIVE policy<{'ppc64el': 'y'}> +CONFIG_PPC_XIVE_NATIVE policy<{'ppc64el': 'y'}> +CONFIG_PPC_XIVE_SPAPR policy<{'ppc64el': 'y'}> +CONFIG_PPDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PPPOATM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPPOE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPPOL2TP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP_ASYNC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP_BSDCOMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP_DEFLATE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP_FILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PPP_MPPE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPP_MULTILINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PPP_SYNC_TTY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_PPS_CLIENT_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PPS_CLIENT_KTIMER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PPS_CLIENT_LDISC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_PPS_CLIENT_PARPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PPS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PPTP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PREEMPT policy<{'amd64-generic': 'n', 'amd64-lowlatency': 'y', 'arm64': 'n', 'armhf': 'n', 'i386-generic': 'n', 'i386-lowlatency': 'y', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PREEMPTION policy<{'amd64-lowlatency': 'y', 'i386-lowlatency': 'y'}> +CONFIG_PREEMPTIRQ_DELAY_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PREEMPTIRQ_EVENTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PREEMPT_COUNT policy<{'amd64-lowlatency': 'y', 'i386-lowlatency': 'y'}> +CONFIG_PREEMPT_NOTIFIERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PREEMPT_RCU policy<{'amd64-lowlatency': 'y', 'i386-lowlatency': 'y'}> +CONFIG_PREEMPT_TRACER policy<{'amd64-lowlatency': 'n', 'i386-lowlatency': 'n'}> +CONFIG_PREEMPT_VOLUNTARY policy<{'amd64-generic': 'y', 'amd64-lowlatency': 'n', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'i386-lowlatency': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PREVENT_FIRMWARE_BUILD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PRINTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PRINTK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PRINTK_CALLER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PRINTK_NMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT policy<{'amd64': '13', 'arm64': '13', 'armhf': '13', 'i386': '13', 'ppc64el': '13', 's390x': '13'}> +CONFIG_PRINTK_TIME policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PRINT_QUOTA_WARNING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PRINT_STACK_DEPTH policy<{'ppc64el': '64'}> +CONFIG_PRISM2_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PRISM54 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PROBE_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROCESSOR_SELECT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PROC_CHILDREN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_KCORE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_MEM_ALWAYS_FORCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_MEM_FORCE_PTRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PROC_MEM_NO_FORCE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PROC_PAGE_MONITOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_PID_ARCH_STATUS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PROC_PID_CPUSET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_SYSCTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_THERMAL_MMIO_RAPL policy<{'amd64': 'y'}> +CONFIG_PROC_VMCORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROC_VMCORE_DEVICE_DUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROFILE_ANNOTATED_BRANCHES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PROFILING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PROTECTED_VIRTUALIZATION_GUEST policy<{'s390x': 'y'}> +CONFIG_PROVE_LOCKING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_PROVIDE_OHCI1394_DMA_INIT policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_PSAMPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_PSERIES_CPUIDLE policy<{'ppc64el': 'y'}> +CONFIG_PSERIES_ENERGY policy<{'ppc64el': 'm'}> +CONFIG_PSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_PSTORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PSTORE_842_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_COMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PSTORE_COMPRESS_DEFAULT policy<{'amd64': '"deflate"', 'arm64': '"deflate"', 'armhf': '"deflate"', 'i386': '"deflate"', 'ppc64el': '"deflate"'}> +CONFIG_PSTORE_CONSOLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_DEFLATE_COMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PSTORE_FTRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_LZ4HC_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_LZ4_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_LZO_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_PMSG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PSTORE_RAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PSTORE_ZSTD_COMPRESS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_PTP_1588_CLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_PTP_1588_CLOCK_DTE policy<{'arm64': 'm'}> +CONFIG_PTP_1588_CLOCK_KVM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PTP_1588_CLOCK_PCH policy<{'i386': 'm'}> +CONFIG_PTP_1588_CLOCK_QORIQ policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_PUNIT_ATOM_DEBUG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_PVH policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PVPANIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PWM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_PWM_ATMEL_HLCDC_PWM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_BCM2835 policy<{'arm64': 'm'}> +CONFIG_PWM_BCM_IPROC policy<{'arm64': 'm'}> +CONFIG_PWM_BERLIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_PWM_CRC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PWM_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_PWM_FSL_FTM policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PWM_HIBVT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_IMX1 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_PWM_IMX27 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_PWM_IMX_TPM policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_PWM_LP3943 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PWM_LPSS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PWM_LPSS_PCI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PWM_LPSS_PLATFORM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_PWM_MEDIATEK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_MESON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_MTK_DISP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_OMAP_DMTIMER policy<{'armhf': 'm'}> +CONFIG_PWM_PCA9685 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PWM_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_RENESAS_TPU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_PWM_SAMSUNG policy<{'armhf': 'm'}> +CONFIG_PWM_SPRD policy<{'arm64': 'm'}> +CONFIG_PWM_STMPE policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_PWM_SUN4I policy<{'arm64': 'm'}> +CONFIG_PWM_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_PWM_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_PWM_TIECAP policy<{'arm64': 'm', 'armhf-generic': 'm', 'armhf-generic-lpae': 'n'}> +CONFIG_PWM_TIEHRPWM policy<{'arm64': 'm', 'armhf-generic': 'm', 'armhf-generic-lpae': 'n'}> +CONFIG_PWM_TIPWMSS policy<{'armhf-generic': 'y'}> +CONFIG_PWM_TWL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PWM_TWL_LED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_PWRSEQ_EMMC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PWRSEQ_SD8787 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PWRSEQ_SIMPLE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_PXA168_ETH policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCA7000 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_QCA7000_SPI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_QCA7000_UART policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_A53PLL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_AOSS_QMP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_APCS_IPC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_APR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_BAM_DMA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_CLK_APCS_MSM8916 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_CLK_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_CLK_RPMH policy<{'arm64': 'm'}> +CONFIG_QCOM_CLK_SMD_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_COINCELL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_COMMAND_DB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_EBI2 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_EMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_FALKOR_ERRATUM_1003 policy<{'arm64': 'y'}> +CONFIG_QCOM_FALKOR_ERRATUM_1009 policy<{'arm64': 'y'}> +CONFIG_QCOM_FALKOR_ERRATUM_E1041 policy<{'arm64': 'y'}> +CONFIG_QCOM_FASTRPC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_GDSC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_GENI_SE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_GLINK_SSR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_GSBI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_HFPLL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_HIDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_HIDMA_MGMT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_IOMMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_IRQ_COMBINER policy<{'arm64': 'y'}> +CONFIG_QCOM_L2_PMU policy<{'arm64': 'y'}> +CONFIG_QCOM_L3_PMU policy<{'arm64': 'y'}> +CONFIG_QCOM_LLCC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_MDT_LOADER policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_PDC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_PM policy<{'armhf': 'y'}> +CONFIG_QCOM_PM8XXX_XOADC policy<{'armhf': 'm'}> +CONFIG_QCOM_Q6V5_ADSP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_Q6V5_COMMON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_Q6V5_MSS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_Q6V5_PAS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_Q6V5_WCSS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_QFPROM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_QMI_HELPERS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_RMTFS_MEM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_RPMCC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_RPMH policy<{'arm64': 'y'}> +CONFIG_QCOM_RPMHPD policy<{'arm64': 'y'}> +CONFIG_QCOM_RPROC_COMMON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SCM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_SCM_32 policy<{'armhf': 'y'}> +CONFIG_QCOM_SCM_64 policy<{'arm64': 'y'}> +CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_QCOM_SMD_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SMEM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SMEM_STATE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_QCOM_SMP2P policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SMSM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SOCINFO policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SPMI_ADC5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_SPMI_IADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_SPMI_TEMP_ALARM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_SPMI_VADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_SYSMON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_TSENS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_VADC_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QCOM_WCNSS_CTRL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCOM_WCNSS_PIL policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_QCOM_WDT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCS_GCC_404 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QCS_TURING_404 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QDIO policy<{'s390x': 'm'}> +CONFIG_QED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QEDE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QEDF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QEDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QED_FCOE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QED_ISCSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QED_LL2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QED_OOO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QED_RDMA policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_QED_SRIOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QETH policy<{'s390x': 'm'}> +CONFIG_QETH_L2 policy<{'s390x': 'm'}> +CONFIG_QETH_L3 policy<{'s390x': 'm'}> +CONFIG_QFMT_V1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_QFMT_V2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_QLA3XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QLCNIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QLCNIC_DCB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QLCNIC_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QLCNIC_SRIOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_QLGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QNX4FS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_QNX6FS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_QNX6FS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_QORIQ_CPUFREQ policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QORIQ_THERMAL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_QRTR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QRTR_SMD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QRTR_TUN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_QSEMI_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_QTNFMAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QTNFMAC_PCIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_QUEUED_RWLOCKS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_QUEUED_SPINLOCKS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_QUOTA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_QUOTACTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_QUOTACTL_COMPAT policy<{'amd64': 'y'}> +CONFIG_QUOTA_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_QUOTA_NETLINK_INTERFACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_QUOTA_TREE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_R6040 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_R8169 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_R8188EU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_R8712U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_ADAPTERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RADIO_AZTECH policy<{'i386': 'm'}> +CONFIG_RADIO_CADET policy<{'i386': 'm'}> +CONFIG_RADIO_GEMTEK policy<{'i386': 'm'}> +CONFIG_RADIO_ISA policy<{'i386': 'm'}> +CONFIG_RADIO_MAXIRADIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_MIROPCM20 policy<{'i386': 'm'}> +CONFIG_RADIO_RTRACK policy<{'i386': 'm'}> +CONFIG_RADIO_RTRACK2 policy<{'i386': 'm'}> +CONFIG_RADIO_SAA7706H policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_SF16FMI policy<{'i386': 'm'}> +CONFIG_RADIO_SF16FMR2 policy<{'i386': 'm'}> +CONFIG_RADIO_SHARK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_SHARK2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_SI470X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_SI4713 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_SI476X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_TEA575X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_TEA5764 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_TEF6862 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_TERRATEC policy<{'i386': 'm'}> +CONFIG_RADIO_TIMBERDALE policy<{'i386': 'm'}> +CONFIG_RADIO_TRUST policy<{'i386': 'm'}> +CONFIG_RADIO_TYPHOON policy<{'i386': 'm'}> +CONFIG_RADIO_WL1273 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_WL128X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RADIO_ZOLTRIX policy<{'i386': 'm'}> +CONFIG_RAID6_PQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RAID6_PQ_BENCHMARK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RAID_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RANDOM32_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RANDOMIZE_BASE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_RANDOMIZE_MEMORY policy<{'amd64': 'y'}> +CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING policy<{'amd64': '0xa'}> +CONFIG_RANDOMIZE_MODULE_REGION_FULL policy<{'arm64': 'y'}> +CONFIG_RANDOM_TRUST_BOOTLOADER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RANDOM_TRUST_CPU policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RAPIDIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_RAPIDIO_CHMAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_CPS_GEN2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_CPS_XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RAPIDIO_DISC_TIMEOUT policy<{'amd64': '30', 'arm64': '30', 'armhf': '30', 'i386': '30', 'ppc64el': '30'}> +CONFIG_RAPIDIO_DMA_ENGINE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RAPIDIO_ENUM_BASIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_MPORT_CDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_RXS_GEN3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_TSI568 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_TSI57X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAPIDIO_TSI721 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_RAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RASPBERRYPI_FIRMWARE policy<{'arm64': 'y'}> +CONFIG_RASPBERRYPI_POWER policy<{'arm64': 'y'}> +CONFIG_RAS_CEC policy<{'amd64': 'y'}> +CONFIG_RAS_CEC_DEBUG policy<{'amd64': 'n'}> +CONFIG_RATIONAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RAVB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RAVE_SP_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_RAVE_SP_EEPROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAVE_SP_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RAW_DRIVER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_RBTREE_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RCAR_DMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RCAR_GEN3_THERMAL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RCAR_GYRO_ADC policy<{'armhf': 'm'}> +CONFIG_RCAR_THERMAL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RCU_CPU_STALL_TIMEOUT policy<{'amd64': '60', 'arm64': '60', 'armhf': '60', 'i386': '60', 'ppc64el': '21', 's390x': '21'}> +CONFIG_RCU_EQS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RCU_EXPERT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RCU_NEED_SEGCBLIST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RCU_PERF_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RCU_STALL_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RCU_TORTURE_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RCU_TRACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RC_ATI_REMOTE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RC_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_RC_DECODERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RC_DEVICES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RC_LOOPBACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RC_MAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RC_XBOX_DVD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RDA_INTC policy<{'armhf': 'y'}> +CONFIG_RDA_TIMER policy<{'armhf': 'y'}> +CONFIG_RDMA_RXE policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RDMA_SIW policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RDS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RDS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RDS_RDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RDS_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RD_BZIP2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RD_GZIP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RD_LZ4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RD_LZMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RD_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RD_XZ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_READABLE_ASM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_READ_ONLY_THP_FOR_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf-generic-lpae': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_REALTEK_AUTOPM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REALTEK_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_REBOOT_MODE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REED_SOLOMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REED_SOLOMON_DEC16 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REED_SOLOMON_DEC8 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REED_SOLOMON_ENC8 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REED_SOLOMON_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_REGMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REGMAP_AC97 policy<{'armhf-generic': 'm'}> +CONFIG_REGMAP_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REGMAP_I3C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGMAP_IRQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REGMAP_MMIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REGMAP_SCCB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGMAP_SLIMBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGMAP_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REGMAP_SPMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGMAP_W1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_REGULATOR_88PG86X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_88PM800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_88PM8607 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AAT2870 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AB3100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ACT8865 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ACT8945A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AD5398 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ANATOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ARIZONA_LDO1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ARIZONA_MICSUPP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AS3711 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AS3722 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_AXP20X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_BCM590XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_BD70528 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_BD718XX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_BD9571MWV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA903X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9055 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9062 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9063 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9210 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DA9211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_REGULATOR_FAN53555 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_HI6421 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_HI6421V530 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_HI655X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_REGULATOR_ISL6271A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_ISL9305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LM363X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LOCHNAGAR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP3971 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP3972 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP872X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP873X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP8755 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP87565 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LP8788 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LTC3589 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_LTC3676 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX14577 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX1586 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX77620 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX77650 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX77686 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX77693 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX77802 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8649 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8660 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8907 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8925 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8952 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8973 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8997 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MAX8998 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MC13783 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MC13892 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MC13XXX_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MCP16502 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MT6311 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MT6323 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_MT6380 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_REGULATOR_MT6397 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PALMAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PBIAS policy<{'armhf': 'm'}> +CONFIG_REGULATOR_PCAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PCF50633 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PFUZE100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PV88060 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PV88080 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PV88090 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_PWM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_QCOM_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_REGULATOR_QCOM_RPMH policy<{'arm64': 'm'}> +CONFIG_REGULATOR_QCOM_SMD_RPM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_REGULATOR_QCOM_SPMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_RC5T583 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_RK808 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_RN5T618 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_RT5033 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_S2MPA01 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_S2MPS11 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_S5M8767 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_SC2731 policy<{'arm64': 'm'}> +CONFIG_REGULATOR_SKY81452 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_SLG51000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_STPMIC1 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_SY8106A policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_SY8824X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TI_ABB policy<{'armhf': 'y'}> +CONFIG_REGULATOR_TPS51632 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS6105X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS62360 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65023 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS6507X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65086 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65090 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65132 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65218 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS6524X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS6586X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65910 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS65912 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_TPS80031 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_REGULATOR_USERSPACE_CONSUMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_VCTRL policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_VEXPRESS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_REGULATOR_VIRTUAL_CONSUMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_WM8350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_WM8400 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REGULATOR_WM8994 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_REISERFS_CHECK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_REISERFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_REISERFS_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REISERFS_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REISERFS_FS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_REISERFS_PROC_INFO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RELAY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RELOCATABLE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RELOCATABLE_TEST policy<{'ppc64el': 'n'}> +CONFIG_REMOTEPROC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_RENESAS_DMA policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RENESAS_INTC_IRQPIN policy<{'armhf': 'y'}> +CONFIG_RENESAS_IRQC policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RENESAS_OSTM policy<{'armhf': 'y'}> +CONFIG_RENESAS_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RENESAS_RZA1_IRQC policy<{'armhf': 'y'}> +CONFIG_RENESAS_RZAWDT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RENESAS_USB_DMAC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RENESAS_WDT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RESET_ATTACK_MITIGATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_RESET_BERLIN policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RESET_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_RESET_CONTROLLER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_RESET_HISI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RESET_IMX7 policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_RESET_MESON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RESET_MESON_AUDIO_ARB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RESET_QCOM_AOSS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RESET_QCOM_PDC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RESET_SCMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RESET_SIMPLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RESET_SUNXI policy<{'arm64': 'y'}> +CONFIG_RESET_TEGRA_BPMP policy<{'armhf-generic': 'y'}> +CONFIG_RESET_TI_SCI policy<{'arm64': 'm'}> +CONFIG_RESET_TI_SYSCON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RESET_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_RESET_UNIPHIER_GLUE policy<{'armhf': 'm'}> +CONFIG_RETPOLINE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_RETU_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RFD77402 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RFD_FTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RFKILL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_RFKILL_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RFKILL_INPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RFKILL_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RFS_ACCEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RING_BUFFER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RING_BUFFER_ALLOW_SWAP policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RING_BUFFER_BENCHMARK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RING_BUFFER_STARTUP_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_RIONET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RIONET_RX_SIZE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128'}> +CONFIG_RIONET_TX_SIZE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128'}> +CONFIG_RMI4_2D_SENSOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_RMI4_F03 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F03_SERIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RMI4_F11 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F12 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F30 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F34 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F54 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_F55 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RMI4_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RMI4_SMB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RMI4_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RMNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RN5T618_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_ROCKCHIP_ANALOGIX_DP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_CDN_DP policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_DW_HDMI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_DW_MIPI_DSI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_EFUSE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ROCKCHIP_GRF policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_INNO_HDMI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_IODOMAIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ROCKCHIP_IOMMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_LVDS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_MBOX policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ROCKCHIP_PM_DOMAINS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_RGB policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_RK3066_HDMI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKCHIP_SARADC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ROCKCHIP_THERMAL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_ROCKCHIP_TIMER policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_ROCKER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ROCKETPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RODATA_FULL_DEFAULT_ENABLED policy<{'arm64': 'y'}> +CONFIG_ROMFS_BACKED_BY_BLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ROMFS_BACKED_BY_BOTH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ROMFS_BACKED_BY_MTD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ROMFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ROMFS_ON_BLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ROSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPCSEC_GSS_KRB5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_RPMSG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPMSG_CHAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPMSG_QCOM_GLINK_NATIVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPMSG_QCOM_GLINK_RPM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPMSG_QCOM_GLINK_SMEM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RPMSG_QCOM_SMD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RPMSG_VIRTIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_RPR0521 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RSEQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RSI_91X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RSI_COEX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RSI_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RSI_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RSI_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RST_RCAR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RT2400PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2500PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2500USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2800PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2800PCI_RT3290 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800PCI_RT33XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800PCI_RT35XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800PCI_RT53XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2800USB_RT33XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB_RT3573 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB_RT35XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB_RT53XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB_RT55XX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800USB_UNKNOWN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2800_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2800_LIB_MMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2X00 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2X00_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RT2X00_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2X00_LIB_CRYPTO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2X00_LIB_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RT2X00_LIB_FIRMWARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2X00_LIB_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RT2X00_LIB_MMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2X00_LIB_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT2X00_LIB_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT61PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RT73USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTAS_ERROR_LOGGING policy<{'ppc64el': 'y'}> +CONFIG_RTAS_FLASH policy<{'ppc64el': 'm'}> +CONFIG_RTAS_PROC policy<{'ppc64el': 'y'}> +CONFIG_RTC_CLASS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_88PM80X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_AB3100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ABB5ZES3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ABEOZ9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ABX80X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_AM1805 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ARMADA38X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_AS3722 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ASPEED policy<{'armhf': 'm'}> +CONFIG_RTC_DRV_BD70528 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_BQ32K policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_BQ4802 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_BRCMSTB policy<{'arm64': 'm'}> +CONFIG_RTC_DRV_CADENCE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_CROS_EC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_RTC_DRV_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DA9055 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DA9063 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1286 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1302 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1307 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1307_CENTURY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_DS1343 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1347 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1374 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1374_WDT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_DS1390 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1511 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1553 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1672 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1685 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_DS1685_FAMILY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS1689 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_DS17285 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_DS1742 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS17485 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_DS17885 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_DS2404 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS3232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_DS3232_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_EM3027 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_FM3130 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_FSL_FTM_ALARM policy<{'arm64': 'm'}> +CONFIG_RTC_DRV_FTRTC010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_GENERIC policy<{'ppc64el': 'y'}> +CONFIG_RTC_DRV_HID_SENSOR_TIME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_HYM8563 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_IMXDI policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_RTC_DRV_IMX_SC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_RTC_DRV_ISL12022 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ISL12026 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_ISL1208 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_LP8788 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M41T80 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M41T80_WDT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_M41T93 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M41T94 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M48T35 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M48T59 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_M48T86 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX6900 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX6902 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX6916 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX77686 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX8907 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX8925 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX8997 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MAX8998 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MC13XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MCP795 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MESON policy<{'armhf': 'm'}> +CONFIG_RTC_DRV_MESON_VRTC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_MSM6242 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MT6397 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_MT7622 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_MV policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_RTC_DRV_MXC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_RTC_DRV_MXC_V2 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_RTC_DRV_OMAP policy<{'armhf': 'y'}> +CONFIG_RTC_DRV_OPAL policy<{'ppc64el': 'y'}> +CONFIG_RTC_DRV_PALMAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF2123 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF2127 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF50633 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF85063 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF8523 policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF85363 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF8563 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PCF8583 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_PL030 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_PL031 policy<{'arm64': 'm', 'armhf': 'y'}> +CONFIG_RTC_DRV_PM8XXX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_R7301 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_R9701 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RC5T583 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RK808 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RP5C01 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RS5C348 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RS5C372 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RTD119X policy<{'arm64': 'y'}> +CONFIG_RTC_DRV_RV3028 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RV3029C2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RV3029_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_DRV_RV8803 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RX4581 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RX6110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RX8010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RX8025 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_RX8581 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_S35390A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_S3C policy<{'armhf': 'y'}> +CONFIG_RTC_DRV_S5M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_SC27XX policy<{'arm64': 'm'}> +CONFIG_RTC_DRV_SD3078 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_SH policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_RTC_DRV_SNVS policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_STK17TA8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_SUN6I policy<{'arm64': 'y'}> +CONFIG_RTC_DRV_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_RTC_DRV_TEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_DRV_TPS6586X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_TPS65910 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_TPS80031 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_V3020 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_VRTC policy<{'i386': 'm'}> +CONFIG_RTC_DRV_WILCO_EC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_RTC_DRV_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_WM8350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_X1205 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_DRV_XGENE policy<{'arm64': 'y'}> +CONFIG_RTC_DRV_ZYNQMP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_RTC_HCTOSYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_HCTOSYS_DEVICE policy<{'amd64': '"rtc0"', 'arm64': '"rtc0"', 'armhf': '"rtc0"', 'i386': '"rtc0"', 'ppc64el': '"rtc0"'}> +CONFIG_RTC_I2C_AND_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_INTF_DEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_INTF_DEV_UIE_EMUL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTC_INTF_PROC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_INTF_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_LIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_MC146818_LIB policy<{'amd64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_NVMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_SYSTOHC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTC_SYSTOHC_DEVICE policy<{'amd64': '"rtc0"', 'arm64': '"rtc0"', 'armhf': '"rtc0"', 'i386': '"rtc0"', 'ppc64el': '"rtc0"'}> +CONFIG_RTD119X_WATCHDOG policy<{'arm64': 'y'}> +CONFIG_RTL8180 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8187 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8187_LEDS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTL8188EE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192CE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192CU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192C_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192DE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192EE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192SE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8192U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8723AE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8723BE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8723BS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8723_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8821AE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8XXXU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL8XXXU_UNTESTED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTLBTCOEXIST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLLIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLLIB_CRYPTO_CCMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLLIB_CRYPTO_TKIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLLIB_CRYPTO_WEP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLWIFI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLWIFI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RTLWIFI_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTLWIFI_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTL_CARDS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTS5208 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTW88 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTW88_8723DE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTW88_8822BE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTW88_8822CE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTW88_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTW88_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTW88_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_RTW88_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_RTW88_REGD_USER_REG_HINTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_RT_MUTEXES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RUNTIME_TESTING_MENU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RWSEM_SPIN_ON_OWNER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_RXKAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_S2IO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_S390 policy<{'s390x': 'y'}> +CONFIG_S390_AP_IOMMU policy<{'s390x': 'y'}> +CONFIG_S390_CCW_IOMMU policy<{'s390x': 'y'}> +CONFIG_S390_GUEST policy<{'s390x': 'y'}> +CONFIG_S390_HYPFS_FS policy<{'s390x': 'y'}> +CONFIG_S390_IOMMU policy<{'s390x': 'y'}> +CONFIG_S390_PRNG policy<{'s390x': 'm'}> +CONFIG_S390_PTDUMP policy<{'s390x': 'y'}> +CONFIG_S390_TAPE policy<{'s390x': 'm'}> +CONFIG_S390_TAPE_34XX policy<{'s390x': 'm'}> +CONFIG_S390_TAPE_3590 policy<{'s390x': 'm'}> +CONFIG_S390_VMUR policy<{'s390x': 'm'}> +CONFIG_S3C2410_WATCHDOG policy<{'armhf': 'm'}> +CONFIG_S5P_DEV_MFC policy<{'armhf': 'y'}> +CONFIG_SAMPLES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SAMPLE_CONFIGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_HW_BREAKPOINT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SAMPLE_KDB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SAMPLE_KFIFO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_KOBJECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_KPROBES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_LIVEPATCH policy<{'amd64': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_QMI_CLIENT policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_SAMPLE_RPMSG_CLIENT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SAMPLE_TRACE_EVENTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_VFIO_MDEV_MBOCHS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_VFIO_MDEV_MDPY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMPLE_VFIO_MDEV_MTTY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SAMSUNG_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SAMSUNG_MC policy<{'armhf': 'y'}> +CONFIG_SAMSUNG_Q10 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SATA_ACARD_AHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_AHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_AHCI_SEATTLE policy<{'arm64': 'm'}> +CONFIG_SATA_DWC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_DWC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SATA_DWC_OLD_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SATA_INIC162X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_MOBILE_LPM_POLICY policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'i386': '3', 'ppc64el': '3'}> +CONFIG_SATA_MV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_NV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_PMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SATA_PROMISE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_QSTOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SATA_SIL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_SIL24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_SIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_SVW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_SX4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_ULI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_VIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_VITESSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SATA_ZPODD policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_SBC7240_WDT policy<{'i386': 'm'}> +CONFIG_SBC8360_WDT policy<{'i386': 'm'}> +CONFIG_SBC_EPX_C3_WATCHDOG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SBC_FITPC2_WATCHDOG policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SBITMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SBNI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SBNI_MULTILINE policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SBP_TARGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SC1200_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SC27XX_ADC policy<{'arm64': 'm'}> +CONFIG_SC27XX_EFUSE policy<{'arm64': 'm'}> +CONFIG_SC92031 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCA3000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCANLOG policy<{'ppc64el': 'm'}> +CONFIG_SCC policy<{'i386': 'm'}> +CONFIG_SCC_DELAY policy<{'i386': 'n'}> +CONFIG_SCC_TRXECHO policy<{'i386': 'n'}> +CONFIG_SCHEDSTATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_AUTOGROUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_BOOK policy<{'s390x': 'y'}> +CONFIG_SCHED_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_DRAWER policy<{'s390x': 'y'}> +CONFIG_SCHED_HRTICK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_INFO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_MC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_SCHED_MC_PRIO policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SCHED_OMIT_FRAME_POINTER policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_SMT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_STACK_END_CHECK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCHED_TOPOLOGY policy<{'s390x': 'y'}> +CONFIG_SCHED_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCIF policy<{'amd64': 'm'}> +CONFIG_SCIF_BUS policy<{'amd64': 'm'}> +CONFIG_SCLP_CONSOLE policy<{'s390x': 'y'}> +CONFIG_SCLP_TTY policy<{'s390x': 'y'}> +CONFIG_SCLP_VT220_CONSOLE policy<{'s390x': 'y'}> +CONFIG_SCLP_VT220_TTY policy<{'s390x': 'y'}> +CONFIG_SCM_BLOCK policy<{'s390x': 'm'}> +CONFIG_SCM_BUS policy<{'s390x': 'y'}> +CONFIG_SCOM_DEBUGFS policy<{'ppc64el': 'y'}> +CONFIG_SCR24X policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SCSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_3W_9XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_3W_SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_AACRAID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_ACARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_ADVANSYS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_AHA152X policy<{'i386': 'm'}> +CONFIG_SCSI_AHA1542 policy<{'i386': 'm'}> +CONFIG_SCSI_AHA1740 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SCSI_AIC79XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_AIC7XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_AIC94XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_AM53C974 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_ARCMSR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_BFA_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_BNX2X_FCOE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_BNX2_ISCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_BUSLOGIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SCSI_CHELSIO_FCOE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_CONSTANTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_CXGB3_ISCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_CXGB4_ISCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_DC395x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_DEBUG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_DH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_DH_ALUA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_DH_EMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_DH_HP_SW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_DH_RDAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_DMX3191D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_DPT_I2O policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_ENCLOSURE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_ESAS2R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_FC_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_FDOMAIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_FDOMAIN_ISA policy<{'i386': 'm'}> +CONFIG_SCSI_FDOMAIN_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_FLASHPOINT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SCSI_GDTH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_GENERIC_NCR5380 policy<{'i386': 'm'}> +CONFIG_SCSI_HISI_SAS policy<{'arm64': 'm'}> +CONFIG_SCSI_HISI_SAS_PCI policy<{'arm64': 'm'}> +CONFIG_SCSI_HPSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_HPTIOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_IBMVFC policy<{'ppc64el': 'm'}> +CONFIG_SCSI_IBMVFC_TRACE policy<{'ppc64el': 'y'}> +CONFIG_SCSI_IBMVSCSI policy<{'ppc64el': 'm'}> +CONFIG_SCSI_IBMVSCSIS policy<{'ppc64el': 'm'}> +CONFIG_SCSI_IMM policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_INIA100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_INITIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_IPR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_IPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_ISCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SCSI_ISCSI_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_IZIP_EPP16 policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_IZIP_SLOW_CTR policy<{'amd64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_LOGGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_LOWLEVEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_LOWLEVEL_PCMCIA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SCSI_LPFC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_LPFC_DEBUG_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_MOD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_MPT2SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_MPT2SAS_MAX_SGE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128', 's390x': '128'}> +CONFIG_SCSI_MPT3SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_MPT3SAS_MAX_SGE policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'i386': '128', 'ppc64el': '128', 's390x': '128'}> +CONFIG_SCSI_MVSAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_MVSAS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_MVSAS_TASKLET policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_MVUMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_MYRB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_MYRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_NETLINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_NSP32 policy<{'armhf': 'm', 'i386': 'm'}> +CONFIG_SCSI_PM8001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_PMCRAID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_PPA policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_PROC_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_QLA_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_QLA_ISCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_QLOGIC_1280 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_QLOGIC_FAS policy<{'i386': 'm'}> +CONFIG_SCSI_SAS_ATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SCSI_SAS_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_SAS_HOST_SMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_SAS_LIBSAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_SCAN_ASYNC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCSI_SIM710 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SCSI_SMARTPQI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_SNIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_SNIC_DEBUG_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SCSI_SPI_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SCSI_SRP_ATTRS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_SCSI_STEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_SYM53C8XX_2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'i386': '16', 'ppc64el': '16'}> +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1'}> +CONFIG_SCSI_SYM53C8XX_MAX_TAGS policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'i386': '64', 'ppc64el': '64'}> +CONFIG_SCSI_SYM53C8XX_MMIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SCSI_UFSHCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCSI_UFSHCD_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_UFSHCD_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_UFS_BSG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SCSI_UFS_CDNS_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_UFS_DWC_TC_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_UFS_DWC_TC_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SCSI_UFS_HISI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SCSI_UFS_MEDIATEK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SCSI_UFS_QCOM policy<{'arm64': 'm', 'armhf': 'n'}> +CONFIG_SCSI_WD719X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SCTP_COOKIE_HMAC_MD5 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCTP_COOKIE_HMAC_SHA1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCTP_DBG_OBJCNT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SCx200 policy<{'i386': 'm'}> +CONFIG_SCx200HR_TIMER policy<{'i386': 'm'}> +CONFIG_SCx200_ACB policy<{'i386': 'm'}> +CONFIG_SCx200_GPIO policy<{'i386': 'm'}> +CONFIG_SCx200_WDT policy<{'i386': 'm'}> +CONFIG_SDIO_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SDLA policy<{'i386': 'm'}> +CONFIG_SDMA_VERBOSITY policy<{'amd64': 'n'}> +CONFIG_SDM_CAMCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_DISPCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_GCC_660 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_GCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_GPUCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_LPASSCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDM_VIDEOCC_845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SDR_MAX2175 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SDR_PLATFORM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SD_ADC_MODULATOR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SEALEVEL_4021 policy<{'i386': 'm'}> +CONFIG_SECCOMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECCOMP_FILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECONDARY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECTION_MISMATCH_WARN_ONLY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITYFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_APPARMOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_APPARMOR_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_APPARMOR_HASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_APPARMOR_HASH_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_DMESG_RESTRICT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_INFINIBAND policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_LOADPIN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_LOCKDOWN_LSM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_LOCKDOWN_LSM_EARLY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_NETWORK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_NETWORK_XFRM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_PATH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_PERF_EVENTS_RESTRICT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SELINUX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SELINUX_AVC_STATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SELINUX_BOOTPARAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1', 's390x': '1'}> +CONFIG_SECURITY_SELINUX_DEVELOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SMACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SMACK_APPEND_SIGNALS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_SMACK_BRINGUP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_SMACK_NETFILTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_TOMOYO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER policy<{'amd64': '"/sbin/init"', 'arm64': '"/sbin/init"', 'armhf': '"/sbin/init"', 'i386': '"/sbin/init"', 'ppc64el': '"/sbin/init"', 's390x': '"/sbin/init"'}> +CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY policy<{'amd64': '2048', 'arm64': '2048', 'armhf': '2048', 'i386': '2048', 'ppc64el': '2048', 's390x': '2048'}> +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'i386': '1024', 'ppc64el': '1024', 's390x': '1024'}> +CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SECURITY_TOMOYO_POLICY_LOADER policy<{'amd64': '"/sbin/tomoyo-init"', 'arm64': '"/sbin/tomoyo-init"', 'armhf': '"/sbin/tomoyo-init"', 'i386': '"/sbin/tomoyo-init"', 'ppc64el': '"/sbin/tomoyo-init"', 's390x': '"/sbin/tomoyo-init"'}> +CONFIG_SECURITY_YAMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SELECT_MEMORY_MODEL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SENSIRION_SGP30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ABITUGURU policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ABITUGURU3 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ACPI_POWER policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_AD7314 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_AD7414 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_AD7418 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADC128D818 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADCXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1021 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1025 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1026 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1029 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1031 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM1275 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADM9240 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADS7828 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADS7871 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7310 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7410 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7411 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7462 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7470 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7475 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ADT7X10 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_AHC1EC0_HWMON policy<{'amd64': 'm'}> +CONFIG_SENSORS_AMC6821 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_APDS990X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SENSORS_APPLESMC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ARM_SCMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SENSORS_ARM_SCPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SENSORS_AS370 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ASB100 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ASC7621 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ASPEED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ATK0110 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ATXP1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_BH1770 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SENSORS_CORETEMP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_DA9052_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_DA9055 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_DELL_SMM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_DME1737 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_DS1621 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_DS620 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_EMC1403 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_EMC2103 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_EMC6W201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_F71805F policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_F71882FG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_F75375S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_FAM15H_POWER policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_FSCHMD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_FTSTEUTATES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_G760A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_G762 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_GL518SM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_GL520SM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_GPIO_FAN policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_HDAPS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_HIH6130 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_HMC5843 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_HMC5843_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_HMC5843_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_I5500 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_I5K_AMB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IBMAEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IBMPEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IBMPOWERNV policy<{'ppc64el': 'm'}> +CONFIG_SENSORS_IBM_CFFPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IIO_HWMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_INA209 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_INA2XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_INA3221 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_INSPUR_IPSPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IR35221 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IR38064 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IRPS5401 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ISL29018 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ISL29028 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_ISL68137 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_IT87 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_JC42 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_K10TEMP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_K8TEMP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_LINEAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LIS3LV02D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LIS3_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SENSORS_LIS3_SPI policy<{'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM25066 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM3533 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM63 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM70 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM73 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM75 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM77 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM78 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM80 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM83 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM85 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM87 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM90 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM92 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM93 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM95234 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM95241 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LM95245 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LOCHNAGAR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC2945 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC2978 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC2978_REGULATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SENSORS_LTC2990 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC3815 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4151 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4215 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4222 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4245 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4260 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_LTC4261 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX1111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX16064 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX16065 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX1619 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX1668 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX197 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX20751 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX31722 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX31785 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX31790 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX34440 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX6621 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX6639 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX6642 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX6650 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX6697 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MAX8688 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MC13783_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MCP3021 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MENF21BMC_HWMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_MLXREG_FAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_NCT6683 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_NCT6775 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_NCT7802 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_NCT7904 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_NPCM7XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_NTC_THERMISTOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_OCC_P8_I2C policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_SENSORS_OCC_P9_SBE policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_SENSORS_PC87360 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_PC87427 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_PCF8591 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_PMBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_POWR1220 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_PWM_FAN policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_PXE1610 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_RASPBERRYPI_HWMON policy<{'arm64': 'm'}> +CONFIG_SENSORS_RM3100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_RM3100_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_RM3100_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SCH5627 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_SCH5636 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_SCH56XX_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_SHT15 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SHT21 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SHT3x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SHTC1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SIS5595 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SMM665 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_SMSC47B397 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_SMSC47M1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_SMSC47M192 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_STTS751 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TC654 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TC74 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_THMC50 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TMP102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TMP103 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TMP108 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TMP401 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TMP421 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TPS40422 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TPS53679 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_TSL2550 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SENSORS_TSL2563 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_UCD9000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_UCD9200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_VEXPRESS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SENSORS_VIA686A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_VIA_CPUTEMP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_VT1211 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_VT8231 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83627EHF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_W83627HF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SENSORS_W83773G policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83781D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83791D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83792D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83793 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83795 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83795_FANCTRL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SENSORS_W83L785TS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_W83L786NG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_WM8350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SENSORS_XGENE policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_SENSORS_ZL6100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_8250 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_ACCENT policy<{'i386': 'm'}> +CONFIG_SERIAL_8250_ASPEED_VUART policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_8250_BCM2835AUX policy<{'arm64': 'n'}> +CONFIG_SERIAL_8250_BOCA policy<{'i386': 'm'}> +CONFIG_SERIAL_8250_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SERIAL_8250_DETECT_IRQ policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SERIAL_8250_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_DW policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_8250_DWLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_EM policy<{'armhf': 'n'}> +CONFIG_SERIAL_8250_EXAR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_8250_EXAR_ST16C554 policy<{'i386': 'm'}> +CONFIG_SERIAL_8250_EXTENDED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_FINTEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y', 'ppc64el': 'n'}> +CONFIG_SERIAL_8250_FOURPORT policy<{'i386': 'm'}> +CONFIG_SERIAL_8250_FSL policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_HUB6 policy<{'i386': 'm'}> +CONFIG_SERIAL_8250_LPSS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SERIAL_8250_MANY_PORTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_MEN_MCB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_8250_MID policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SERIAL_8250_MT6577 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_8250_NR_UARTS policy<{'amd64': '48', 'arm64': '48', 'armhf': '48', 'i386': '48', 'ppc64el': '48'}> +CONFIG_SERIAL_8250_OMAP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SERIAL_8250_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_PNP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_SERIAL_8250_RSA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_RT288X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_RUNTIME_UARTS policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32'}> +CONFIG_SERIAL_8250_SHARE_IRQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_8250_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_SERIAL_ALTERA_JTAGUART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_ALTERA_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_ALTERA_UART_BAUDRATE policy<{'amd64': '115200', 'arm64': '115200', 'armhf': '115200', 'i386': '115200', 'ppc64el': '115200'}> +CONFIG_SERIAL_ALTERA_UART_MAXPORTS policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'i386': '4', 'ppc64el': '4'}> +CONFIG_SERIAL_AMBA_PL010 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SERIAL_AMBA_PL011 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_AMBA_PL011_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_ARC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_ARC_NR_PORTS policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1'}> +CONFIG_SERIAL_BCM63XX policy<{'armhf': 'm'}> +CONFIG_SERIAL_CONEXANT_DIGICOLOR policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_SERIAL_CORE_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_EARLYCON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_FSL_LINFLEXUART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_FSL_LPUART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_ICOM policy<{'ppc64el': 'm'}> +CONFIG_SERIAL_IFX6X60 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SERIAL_IMX policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_SERIAL_IMX_CONSOLE policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_SERIAL_IPOCTAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_JSM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_KGDB_NMI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_MAX3100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_MAX310X policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_MCTRL_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_MEN_Z135 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_MESON policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_MESON_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_MILBEAUT_USIO policy<{'armhf': 'm'}> +CONFIG_SERIAL_MILBEAUT_USIO_PORTS policy<{'armhf': '4'}> +CONFIG_SERIAL_MSM policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_MSM_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_MVEBU_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_MVEBU_UART policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_NONSTANDARD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SERIAL_OF_PLATFORM policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_OMAP policy<{'armhf': 'y'}> +CONFIG_SERIAL_OMAP_CONSOLE policy<{'armhf': 'y'}> +CONFIG_SERIAL_OWL policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_OWL_CONSOLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_PCH_UART policy<{'i386': 'm'}> +CONFIG_SERIAL_QCOM_GENI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SERIAL_RDA policy<{'armhf': 'y'}> +CONFIG_SERIAL_RDA_CONSOLE policy<{'armhf': 'y'}> +CONFIG_SERIAL_RP2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_RP2_NR_UARTS policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32'}> +CONFIG_SERIAL_SAMSUNG policy<{'armhf': 'm'}> +CONFIG_SERIAL_SAMSUNG_UARTS policy<{'armhf': '4'}> +CONFIG_SERIAL_SAMSUNG_UARTS_4 policy<{'armhf': 'y'}> +CONFIG_SERIAL_SC16IS7XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SERIAL_SC16IS7XX_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_SC16IS7XX_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_SC16IS7XX_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_SCCNXP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SERIAL_SCCNXP_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIAL_SH_SCI_DMA policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SERIAL_SH_SCI_NR_UARTS policy<{'arm64': '2', 'armhf': '2'}> +CONFIG_SERIAL_SIFIVE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SERIAL_SPRD policy<{'arm64': 'm'}> +CONFIG_SERIAL_ST_ASC policy<{'armhf': 'm'}> +CONFIG_SERIAL_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_SERIAL_TEGRA_TCU policy<{'armhf-generic': 'm'}> +CONFIG_SERIAL_TIMBERDALE policy<{'i386': 'm'}> +CONFIG_SERIAL_UARTLITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SERIAL_UARTLITE_NR_UARTS policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1', 's390x': '1'}> +CONFIG_SERIAL_XILINX_PS_UART policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SERIO_ALTERA_PS2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_AMBAKMI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SERIO_APBPS2 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_ARC_PS2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_CT82C710 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SERIO_GPIO_PS2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_I8042 policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIO_LIBPS2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SERIO_NVEC_PS2 policy<{'armhf-generic': 'm'}> +CONFIG_SERIO_PARKBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_PCIPS2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_PS2MULT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_RAW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_SERPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SERIO_SUN4I_PS2 policy<{'arm64': 'n'}> +CONFIG_SERIO_XILINX_XPS_PS2 policy<{'ppc64el': 'm'}> +CONFIG_SFC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SFC_FALCON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SFC_FALCON_MTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SFC_MCDI_LOGGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SFC_MCDI_MON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SFC_MTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SFC_SRIOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SFI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SFP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SGETMASK_SYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SGI_GRU policy<{'amd64': 'm'}> +CONFIG_SGI_GRU_DEBUG policy<{'amd64': 'n'}> +CONFIG_SGI_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SGI_XP policy<{'amd64': 'm'}> +CONFIG_SGL_ALLOC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SG_POOL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SG_SPLIT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SHIFT_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SHIFT_FS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SHMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SHUFFLE_PAGE_ALLOCATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SH_ETH policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SH_TIMER_CMT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SH_TIMER_MTU2 policy<{'armhf': 'y'}> +CONFIG_SH_TIMER_TMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SI1133 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SI1145 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SI7005 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SI7020 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SIGNALFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SIGNATURE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SIGNED_PE_FILE_VERIFICATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SIMPLE_GPIO policy<{'ppc64el': 'n'}> +CONFIG_SIMPLE_PM_BUS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SIOX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SIOX_BUS_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SIS190 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SIS900 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SKB_EXTENSIONS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SKFP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SKGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SKGE_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SKGE_GENESIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SKY2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SKY2_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SLAB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SLAB_FREELIST_HARDENED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLAB_FREELIST_RANDOM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLAB_MERGE_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLHC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SLICOSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SLIC_DS26522 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SLIMBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SLIM_QCOM_CTRL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SLIM_QCOM_NGD_CTRL policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SLIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SLIP_COMPRESSED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SLIP_MODE_SLIP6 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SLIP_SMART policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SLOB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SLUB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLUB_CPU_PARTIAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLUB_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLUB_DEBUG_ON policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SLUB_MEMCG_SYSFS_ON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SLUB_STATS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SMARTJOYPLUS_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SMC911X policy<{'armhf': 'm'}> +CONFIG_SMC9194 policy<{'i386': 'm'}> +CONFIG_SMC91X policy<{'arm64': 'y', 'armhf': 'm'}> +CONFIG_SMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SMP_ON_UP policy<{'armhf': 'y'}> +CONFIG_SMSC37B787_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SMSC911X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SMSC9420 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SMSC_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SMSC_SCH311X_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SMSGIUCV policy<{'s390x': 'y'}> +CONFIG_SMSGIUCV_EVENT policy<{'s390x': 'm'}> +CONFIG_SMS_SDIO_DRV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SMS_SIANO_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SMS_SIANO_MDTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SMS_SIANO_RC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SMS_USB_DRV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SM_FTL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SM_GCC_8150 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_AC97_CODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AC97_POWER_SAVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_AC97_POWER_SAVE_DEFAULT policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_SND_AD1816A policy<{'i386': 'm'}> +CONFIG_SND_AD1848 policy<{'i386': 'm'}> +CONFIG_SND_AD1889 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ADLIB policy<{'i386': 'm'}> +CONFIG_SND_ALI5451 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ALOOP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ALS100 policy<{'i386': 'm'}> +CONFIG_SND_ALS300 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ALS4000 policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ARM policy<{'armhf': 'y'}> +CONFIG_SND_ARMAACI policy<{'armhf': 'm'}> +CONFIG_SND_ASIHPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_ATIIXP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ATIIXP_MODEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ATMEL_SOC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AU8810 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AU8820 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AU8830 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AUDIO_GRAPH_CARD policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AW2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_AZT1605 policy<{'i386': 'm'}> +CONFIG_SND_AZT2316 policy<{'i386': 'm'}> +CONFIG_SND_AZT2320 policy<{'i386': 'm'}> +CONFIG_SND_AZT3328 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_BCD2000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_BCM2835 policy<{'arm64': 'm'}> +CONFIG_SND_BCM2835_SOC_I2S policy<{'arm64': 'm'}> +CONFIG_SND_BEBOB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_BT87X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_BT87X_OVERCLOCK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_CA0106 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_CMI8328 policy<{'i386': 'm'}> +CONFIG_SND_CMI8330 policy<{'i386': 'm'}> +CONFIG_SND_CMIPCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_COMPRESS_OFFLOAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm'}> +CONFIG_SND_CS4231 policy<{'i386': 'm'}> +CONFIG_SND_CS4236 policy<{'i386': 'm'}> +CONFIG_SND_CS4281 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_CS46XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_CS46XX_NEW_DSP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_CS5530 policy<{'i386': 'm'}> +CONFIG_SND_CS5535AUDIO policy<{'i386': 'm'}> +CONFIG_SND_CTXFI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DARLA20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DARLA24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_DESIGNWARE_I2S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_DESIGNWARE_PCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_SND_DICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DMAENGINE_PCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DMA_SGBUF policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_DYNAMIC_MINORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_ECHO3G policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_EMU10K1 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_EMU10K1X policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_EMU10K1_SEQ policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ENS1370 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ENS1371 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ES1688 policy<{'i386': 'm'}> +CONFIG_SND_ES18XX policy<{'i386': 'm'}> +CONFIG_SND_ES1938 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ES1968 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ES1968_INPUT policy<{'amd64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y'}> +CONFIG_SND_ES1968_RADIO policy<{'amd64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y'}> +CONFIG_SND_FIREFACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FIREWIRE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_FIREWIRE_DIGI00X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FIREWIRE_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FIREWIRE_MOTU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FIREWIRE_TASCAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FIREWORKS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FM801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_FM801_TEA575X_BOOL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_GINA20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_GINA24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_GUSCLASSIC policy<{'i386': 'm'}> +CONFIG_SND_GUSEXTREME policy<{'i386': 'm'}> +CONFIG_SND_GUSMAX policy<{'i386': 'm'}> +CONFIG_SND_HDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_ALIGNED_MMIO policy<{'armhf-generic': 'y'}> +CONFIG_SND_HDA_CODEC_ANALOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_CA0110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_CA0132 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_CA0132_DSP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_CODEC_CIRRUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_CMEDIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_CONEXANT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_HDMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_REALTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_SI3054 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_SIGMATEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_CODEC_VIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_COMPONENT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_DSP_LOADER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_EXT_CORE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_HDA_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_HWDEP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_I915 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_HDA_INPUT_BEEP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_INPUT_BEEP_MODE policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_SND_HDA_INTEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDA_PATCH_LOADER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_HDA_PREALLOC_SIZE policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'i386': '64', 'ppc64el': '64'}> +CONFIG_SND_HDA_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_SND_HDSP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HDSPM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HRTIMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_HWDEP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_I2S_HI6210_I2S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_ICE1712 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_ICE1724 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_IMX_SOC policy<{'arm64': 'm', 'armhf-generic': 'y'}> +CONFIG_SND_INDIGO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INDIGODJ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INDIGODJX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INDIGOIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INDIGOIOX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INTEL8X0 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INTEL8X0M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INTEL_DSP_CONFIG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_INTEL_NHLT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_SND_INTERWAVE policy<{'i386': 'm'}> +CONFIG_SND_INTERWAVE_STB policy<{'i386': 'm'}> +CONFIG_SND_ISA policy<{'i386': 'y'}> +CONFIG_SND_ISIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_JACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_JACK_INPUT_DEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_JAZZ16 policy<{'i386': 'm'}> +CONFIG_SND_KIRKWOOD_SOC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_KORG1212 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_LAYLA20 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_LAYLA24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_LOLA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_LX6464ES policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MAESTRO3 policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_MAESTRO3_INPUT policy<{'amd64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y'}> +CONFIG_SND_MAX_CARDS policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'i386': '32', 'ppc64el': '32'}> +CONFIG_SND_MESON_AXG_FIFO policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_FRDDR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_PDM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_SOUND_CARD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_SPDIFIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_SPDIFOUT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_TDMIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_TDMOUT policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_TDM_FORMATTER policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_TDM_INTERFACE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_AXG_TODDR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_CARD_UTILS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_CODEC_GLUE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MESON_G12A_TOHDMITX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_MIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MIRO policy<{'i386': 'm'}> +CONFIG_SND_MIXART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MIXER_OSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MONA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MPU401 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MPU401_UART policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MSND_CLASSIC policy<{'i386': 'm'}> +CONFIG_SND_MSND_PINNACLE policy<{'i386': 'm'}> +CONFIG_SND_MTPAV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_MTS64 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_NM256 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_OPL3SA2 policy<{'i386': 'm'}> +CONFIG_SND_OPL3_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_OPL3_LIB_SEQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_OPL4_LIB policy<{'i386': 'm'}> +CONFIG_SND_OPL4_LIB_SEQ policy<{'i386': 'm'}> +CONFIG_SND_OPTI92X_AD1848 policy<{'i386': 'm'}> +CONFIG_SND_OPTI92X_CS4231 policy<{'i386': 'm'}> +CONFIG_SND_OPTI93X policy<{'i386': 'm'}> +CONFIG_SND_OSSEMUL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_OXFW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_OXYGEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_OXYGEN_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_PCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_PCMCIA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_PCM_ELD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_PCM_IEC958 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_PCM_TIMER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_PCSP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_PCXHR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_PDAUDIOCF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_PORTMAN2X4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_PPC policy<{'ppc64el': 'y'}> +CONFIG_SND_PROC_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_RAWMIDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_RIPTIDE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_RME32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_RME96 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_RME9652 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SAMSUNG_I2S policy<{'armhf': 'm'}> +CONFIG_SND_SAMSUNG_PCM policy<{'armhf': 'm'}> +CONFIG_SND_SAMSUNG_SPDIF policy<{'armhf': 'm'}> +CONFIG_SND_SB16 policy<{'i386': 'm'}> +CONFIG_SND_SB16_CSP policy<{'i386': 'y'}> +CONFIG_SND_SB16_DSP policy<{'i386': 'm'}> +CONFIG_SND_SB8 policy<{'i386': 'm'}> +CONFIG_SND_SB8_DSP policy<{'i386': 'm'}> +CONFIG_SND_SBAWE policy<{'i386': 'm'}> +CONFIG_SND_SBAWE_SEQ policy<{'i386': 'm'}> +CONFIG_SND_SB_COMMON policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SC6000 policy<{'i386': 'm'}> +CONFIG_SND_SEQUENCER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQUENCER_OSS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_SEQ_DEVICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQ_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQ_HRTIMER_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SEQ_MIDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQ_MIDI_EMUL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQ_MIDI_EVENT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SEQ_VIRMIDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SERIAL_U16550 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SIMPLE_CARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SIMPLE_CARD_UTILS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SIS7019 policy<{'i386': 'm'}> +CONFIG_SND_SOC_AC97_BUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SOC_AC97_CODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_ACPI_INTEL_MATCH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_ADAU1701 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU1761 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU1761_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU1761_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU17X1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU7002 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ADAU_UTILS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4104 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4118 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4458 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4554 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4613 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK4642 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK5386 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AK5558 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ALC5623 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ALC5632 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_AMD_ACP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AMD_ACP3x policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_AMD_CZ_RT5645_MACH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_APQ8016_SBC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ARIZONA policy<{'armhf': 'm'}> +CONFIG_SND_SOC_ARNDALE_RT5631_ALC5631 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_BD28623 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_BT_SCO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_COMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_CPCAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CROS_EC_CODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_CS35L32 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS35L33 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS35L34 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS35L35 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS35L36 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4265 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4270 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4271 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4271_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4271_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L42 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L51 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L51_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L52 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L56 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42L73 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42XX8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS42XX8_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS43130 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4341 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS4349 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CS53L30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_CX2072X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_DA7213 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_DA7219 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_DAVINCI_MCASP policy<{'armhf': 'm'}> +CONFIG_SND_SOC_DMIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES7134 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES7241 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES8316 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES8328 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES8328_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ES8328_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_EUKREA_TLV320 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_FSL_ASOC_CARD policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SND_SOC_FSL_ASRC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_AUDMIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_ESAI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_MICFIL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_SAI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_SPDIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_SSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_FSL_UTILS policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SOC_GTM601 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_HDAC_HDA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_HDAC_HDMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_HDMI_CODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_I2C_AND_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SOC_IMG_I2S_IN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG_I2S_OUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG_PARALLEL_OUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG_SPDIF_IN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMG_SPDIF_OUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMX_AUDMIX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SND_SOC_IMX_AUDMUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_IMX_ES8328 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SND_SOC_IMX_MC13783 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_IMX_PCM_DMA policy<{'arm64': 'm', 'armhf-generic': 'y'}> +CONFIG_SND_SOC_IMX_PCM_FIQ policy<{'armhf-generic': 'y'}> +CONFIG_SND_SOC_IMX_SGTL5000 policy<{'arm64': 'm', 'armhf-generic': 'y'}> +CONFIG_SND_SOC_IMX_SPDIF policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SND_SOC_IMX_SSI policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_INNO_RK3036 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_INTEL_APL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BROADWELL_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BXT_RT298_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_GLK policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_HASWELL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_HASWELL_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_MACH policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_INTEL_SKL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKL_RT286_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SST policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SST_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SST_FIRMWARE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_INTEL_SST_TOPLEVEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_LOCHNAGAR_SC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_LPASS_APQ8016 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_LPASS_CPU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_LPASS_IPQ806X policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_LPASS_PLATFORM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MAX9759 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX98088 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX98090 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_MAX98095 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_MAX98357A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX98373 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX98504 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX9860 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX9867 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MAX98927 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MC13783 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_MEDIATEK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MIKROE_PROTO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MSM8916_WCD_ANALOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MSM8996 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MT2701 policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_SND_SOC_MT6351 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MT6358 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_MT6797 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MT6797_MT6351 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MT8173 policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_SND_SOC_MT8183 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MT8183_DA7219_MAX98357A policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_MTK_BTCVSD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_NAU8540 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_NAU8810 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_NAU8822 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_NAU8824 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_NAU8825 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_NOKIA_RX51 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_ODROID policy<{'armhf': 'm'}> +CONFIG_SND_SOC_OMAP3_PANDORA policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_OMAP3_TWL4030 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_OMAP_ABE_TWL6040 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_OMAP_DMIC policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_OMAP_MCBSP policy<{'armhf': 'm'}> +CONFIG_SND_SOC_OMAP_MCPDM policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_PCM1681 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM1789 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM1789_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM179X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM179X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM179X_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM186X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM186X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM186X_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3060 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3060_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3060_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3168A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3168A_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM3168A_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM512x policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM512x_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_PCM512x_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QCOM_COMMON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_ADM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_AFE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_AFE_DAI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_ASM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_ASM_DAI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_COMMON policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_CORE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_QDSP6_ROUTING policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_RK3288_HDMI_ANALOG policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_RK3328 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_RK3399_GRU_SOUND policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_RL6231 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_RL6347A policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_ROCKCHIP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ROCKCHIP_I2S policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ROCKCHIP_MAX98090 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ROCKCHIP_PDM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ROCKCHIP_RT5645 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_ROCKCHIP_SPDIF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_RT286 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT298 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5514 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5514_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5616 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_RT5631 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_RT5640 policy<{'amd64': 'm', 'armhf-generic': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5645 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_RT5651 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5660 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5663 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5670 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5677 policy<{'amd64': 'm', 'armhf-generic': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5677_SPI policy<{'amd64': 'm', 'armhf-generic': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_RT5682 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SAMSUNG policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SAMSUNG_TM2_WM5110 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SDM845 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_SGTL5000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic': 'y', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SH4_FSI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_SI476X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SIGMADSP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SIGMADSP_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SIGMADSP_REGMAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SIMPLE_AMPLIFIER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SIRF_AUDIO_CODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SMDK_WM8994_PCM policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SNOW policy<{'armhf': 'm'}> +CONFIG_SND_SOC_SOF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SOF_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_APOLLOLAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_APOLLOLAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_BAYTRAIL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_BAYTRAIL_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_CANNONLAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_CANNONLAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_COFFEELAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_COFFEELAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_COMETLAKE_H policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_COMETLAKE_H_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_COMETLAKE_LP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_COMETLAKE_LP_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_SOC_SOF_ELKHARTLAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_ELKHARTLAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_GEMINILAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_GEMINILAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_HDA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_HDA_COMMON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_ICELAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_ICELAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_IMX8 policy<{'arm64': 'm'}> +CONFIG_SND_SOC_SOF_IMX8_SUPPORT policy<{'arm64': 'y'}> +CONFIG_SND_SOC_SOF_IMX_TOPLEVEL policy<{'arm64': 'y'}> +CONFIG_SND_SOC_SOF_INTEL_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_INTEL_COMMON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_INTEL_PCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_MERRIFIELD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_MERRIFIELD_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_OF policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SOF_OPTIONS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SOF_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_SOC_SOF_TIGERLAKE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SOF_TIGERLAKE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_SOC_SOF_TOPLEVEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SOC_SOF_XTENSA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_SPDIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SPRD policy<{'arm64': 'm'}> +CONFIG_SND_SOC_SPRD_MCDT policy<{'arm64': 'y'}> +CONFIG_SND_SOC_SSM2305 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SSM2602 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SSM2602_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SSM2602_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_SSM4567 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_STA32X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_STA350 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_STI_SAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_STORM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SND_SOC_TAS2552 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TAS5086 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TAS571X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TAS5720 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TAS6424 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TDA7419 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA20_AC97 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA20_DAS policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA20_I2S policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA20_SPDIF policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA30_AHUB policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA30_I2S policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_ALC5632 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_MAX98090 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_RT5640 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_RT5677 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_SGTL5000 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_TRIMSLICE policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_WM8753 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_WM8903 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TEGRA_WM9712 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TFA9879 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TI_EDMA_PCM policy<{'armhf': 'm'}> +CONFIG_SND_SOC_TI_SDMA_PCM policy<{'armhf': 'm'}> +CONFIG_SND_SOC_TLV320AIC23 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TLV320AIC23_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TLV320AIC23_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TLV320AIC31XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TLV320AIC32X4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_TLV320AIC32X4_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_TLV320AIC32X4_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SND_SOC_TLV320AIC3X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TOPOLOGY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SOC_TPA6130A2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TS3A227E policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TSCS42XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TSCS454 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_TWL4030 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_TWL6040 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_UDA1334 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_SND_SOC_UNIPHIER_AIO policy<{'armhf': 'm'}> +CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC policy<{'armhf': 'm'}> +CONFIG_SND_SOC_UNIPHIER_LD11 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_UNIPHIER_PXS2 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_WCD9335 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM5110 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_WM8510 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8523 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8524 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8580 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8711 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8728 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8731 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8737 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8741 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8750 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8753 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8770 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8776 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8782 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8804 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8804_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8804_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8903 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8904 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8960 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8962 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8974 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8978 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8985 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_WM8994 policy<{'armhf': 'm'}> +CONFIG_SND_SOC_WM9712 policy<{'armhf-generic': 'm'}> +CONFIG_SND_SOC_WM_ADSP policy<{'armhf': 'm'}> +CONFIG_SND_SOC_WM_HUBS policy<{'armhf': 'm'}> +CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_XILINX_I2S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_XILINX_SPDIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_XTFPGA_I2S policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SOC_ZX_AUD96P22 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_SONICVIBES policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SSCAPE policy<{'i386': 'm'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SST_IPC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SST_IPC_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SST_IPC_PCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_SUN4I_CODEC policy<{'arm64': 'n'}> +CONFIG_SND_SUN4I_I2S policy<{'arm64': 'n'}> +CONFIG_SND_SUN4I_SPDIF policy<{'arm64': 'n'}> +CONFIG_SND_SUN50I_CODEC_ANALOG policy<{'arm64': 'm'}> +CONFIG_SND_SUN8I_ADDA_PR_REGMAP policy<{'arm64': 'm'}> +CONFIG_SND_SUN8I_CODEC policy<{'arm64': 'm'}> +CONFIG_SND_SUN8I_CODEC_ANALOG policy<{'arm64': 'm'}> +CONFIG_SND_SUPPORT_OLD_API policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_SYNTH_EMUX policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_TIMER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_TRIDENT policy<{'amd64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm'}> +CONFIG_SND_USB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_USB_6FIRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_AUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_USB_CAIAQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_CAIAQ_INPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_USB_HIFACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_LINE6 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_POD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_PODHD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_TONEPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_UA101 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_US122L policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_USB_USX2Y policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_USB_VARIAX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VERBOSE_PRINTK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SND_VERBOSE_PROCFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_VIA82XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VIA82XX_MODEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VIRMIDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VIRTUOSO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VMASTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SND_VX222 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_VXPOCKET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SND_VX_LIB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SND_WAVEFRONT policy<{'i386': 'm'}> +CONFIG_SND_WSS_LIB policy<{'i386': 'm'}> +CONFIG_SND_X86 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SND_XEN_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_SND_YMFPCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SNI_AVE policy<{'armhf': 'm'}> +CONFIG_SNI_NETSEC policy<{'arm64': 'm'}> +CONFIG_SOCIONEXT_SYNQUACER_PREITS policy<{'arm64': 'y'}> +CONFIG_SOCK_CGROUP_DATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SOCK_VALIDATE_XMIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SOC_AM33XX policy<{'armhf-generic': 'y', 'armhf-generic-lpae': 'n'}> +CONFIG_SOC_AM43XX policy<{'armhf': 'n'}> +CONFIG_SOC_ASPEED policy<{'armhf': 'y'}> +CONFIG_SOC_BRCMSTB policy<{'arm64': 'y', 'armhf': 'n'}> +CONFIG_SOC_BUS policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SOC_DRA7XX policy<{'armhf': 'y'}> +CONFIG_SOC_EXYNOS5250 policy<{'armhf': 'y'}> +CONFIG_SOC_EXYNOS5260 policy<{'armhf': 'y'}> +CONFIG_SOC_EXYNOS5410 policy<{'armhf': 'y'}> +CONFIG_SOC_EXYNOS5420 policy<{'armhf': 'y'}> +CONFIG_SOC_EXYNOS5800 policy<{'armhf': 'y'}> +CONFIG_SOC_HAS_OMAP2_SDRC policy<{'armhf': 'y'}> +CONFIG_SOC_HAS_REALTIME_COUNTER policy<{'armhf': 'y'}> +CONFIG_SOC_IMX5 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX50 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX51 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX53 policy<{'armhf-generic': 'n'}> +CONFIG_SOC_IMX6 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX6Q policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX6SL policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX6SLL policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX6SX policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX6UL policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX7D policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX7D_CA7 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_IMX7ULP policy<{'armhf-generic': 'y'}> +CONFIG_SOC_LS1021A policy<{'armhf-generic': 'n'}> +CONFIG_SOC_OMAP3430 policy<{'armhf-generic': 'y'}> +CONFIG_SOC_OMAP5 policy<{'armhf': 'n'}> +CONFIG_SOC_RENESAS policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SOC_SAMSUNG policy<{'armhf': 'y'}> +CONFIG_SOC_TEGRA_FLOWCTRL policy<{'armhf-generic': 'y'}> +CONFIG_SOC_TEGRA_FUSE policy<{'armhf-generic': 'y'}> +CONFIG_SOC_TEGRA_PMC policy<{'armhf-generic': 'y'}> +CONFIG_SOC_TEGRA_POWERGATE_BPMP policy<{'armhf-generic': 'y'}> +CONFIG_SOC_TI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SOC_TI81XX policy<{'armhf-generic': 'y'}> +CONFIG_SOC_VF610 policy<{'armhf-generic': 'y'}> +CONFIG_SOFTLOCKUP_DETECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SOFT_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SOFT_WATCHDOG_PRETIMEOUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SOLARIS_X86_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SONYPI policy<{'i386': 'm'}> +CONFIG_SONYPI_COMPAT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SONY_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SONY_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SOUNDWIRE_CADENCE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SOUNDWIRE_INTEL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SOUND_OSS_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SP5100_TCO policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SPAPR_TCE_IOMMU policy<{'ppc64el': 'y'}> +CONFIG_SPARSEMEM policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SPARSEMEM_EXTREME policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SPARSEMEM_MANUAL policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPARSEMEM_STATIC policy<{'i386': 'y'}> +CONFIG_SPARSEMEM_VMEMMAP policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SPARSEMEM_VMEMMAP_ENABLE policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SPARSE_IRQ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SPEAKUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_ACNTPC policy<{'i386': 'm'}> +CONFIG_SPEAKUP_SYNTH_ACNTSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_APOLLO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_AUDPTR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_BNS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_DECEXT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_DECPC policy<{'i386': 'm'}> +CONFIG_SPEAKUP_SYNTH_DECTLK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_DTLK policy<{'i386': 'm'}> +CONFIG_SPEAKUP_SYNTH_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_KEYPC policy<{'i386': 'm'}> +CONFIG_SPEAKUP_SYNTH_LTLK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_SOFT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_SPKOUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPEAKUP_SYNTH_TXPRT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPECTRE_BHI_AUTO policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SPECTRE_BHI_OFF policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SPECTRE_BHI_ON policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SPI_ALTERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_ARMADA_3700 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_ASPEED_SMC policy<{'armhf': 'm'}> +CONFIG_SPI_AXI_SPI_ENGINE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_BCM2835 policy<{'arm64': 'm'}> +CONFIG_SPI_BCM2835AUX policy<{'arm64': 'm'}> +CONFIG_SPI_BCM_QSPI policy<{'arm64': 'm'}> +CONFIG_SPI_BITBANG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_BUTTERFLY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_CADENCE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_CADENCE_QUADSPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SPI_DESIGNWARE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_DLN2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_DW_MID_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_DW_MMIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_DW_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_DYNAMIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_FSL_DSPI policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SPI_FSL_LIB policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_FSL_LPSPI policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SPI_FSL_QUADSPI policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SPI_FSL_SPI policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_HISI_SFC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_HISI_SFC_V3XX policy<{'arm64': 'm'}> +CONFIG_SPI_IMX policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_SPI_LM70_LLP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_LOOPBACK_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_MASTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_MEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_MESON_SPICC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_MESON_SPIFC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_MT65XX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_MTK_QUADSPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_MXIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_NPCM_FIU policy<{'armhf': 'm'}> +CONFIG_SPI_NPCM_PSPI policy<{'armhf': 'm'}> +CONFIG_SPI_NXP_FLEXSPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_OC_TINY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_OMAP24XX policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SPI_ORION policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_PL022 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_PXA2XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_PXA2XX_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_SPI_QCOM_GENI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_QCOM_QSPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_QUP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_ROCKCHIP policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'm', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SPI_RSPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_S3C64XX policy<{'armhf': 'm'}> +CONFIG_SPI_SC18IS602 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_SH_HSPI policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_SH_MSIOF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_SIFIVE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_SLAVE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SPI_SLAVE_MT27XX policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPI_SLAVE_SYSTEM_CONTROL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_SLAVE_TIME policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_SPIDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_SPRD policy<{'arm64': 'm'}> +CONFIG_SPI_SPRD_ADI policy<{'arm64': 'm'}> +CONFIG_SPI_SUN4I policy<{'arm64': 'n'}> +CONFIG_SPI_SUN6I policy<{'arm64': 'm'}> +CONFIG_SPI_SYNQUACER policy<{'arm64': 'm'}> +CONFIG_SPI_TEGRA114 policy<{'armhf-generic': 'm'}> +CONFIG_SPI_TEGRA20_SFLASH policy<{'armhf-generic': 'm'}> +CONFIG_SPI_TEGRA20_SLINK policy<{'armhf-generic': 'm'}> +CONFIG_SPI_THUNDERX policy<{'arm64': 'm'}> +CONFIG_SPI_TI_QSPI policy<{'armhf': 'm'}> +CONFIG_SPI_TLE62X0 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_TOPCLIFF_PCH policy<{'i386': 'm'}> +CONFIG_SPI_UNIPHIER policy<{'armhf': 'm'}> +CONFIG_SPI_XCOMM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPI_XILINX policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SPI_XLP policy<{'arm64': 'm'}> +CONFIG_SPI_ZYNQMP_GQSPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SPLIT_PTLOCK_CPUS policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'i386': '4', 'ppc64el': '4', 's390x': '4'}> +CONFIG_SPMI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SPMI_MSM_PMIC_ARB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPMI_PMIC_CLKDIV policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_SPRD_COMMON_CLK policy<{'arm64': 'm'}> +CONFIG_SPRD_DMA policy<{'arm64': 'm'}> +CONFIG_SPRD_SC9860_CLK policy<{'arm64': 'm'}> +CONFIG_SPRD_TIMER policy<{'arm64': 'y'}> +CONFIG_SPRD_WATCHDOG policy<{'arm64': 'm'}> +CONFIG_SPS30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SQUASHFS_DECOMP_MULTI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SQUASHFS_DECOMP_SINGLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_EMBEDDED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SQUASHFS_FILE_CACHE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SQUASHFS_FILE_DIRECT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'i386': '3', 'ppc64el': '3', 's390x': '3'}> +CONFIG_SQUASHFS_LZ4 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_XZ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_ZLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SQUASHFS_ZSTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SRAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SRAM_EXEC policy<{'armhf': 'y'}> +CONFIG_SRCU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SRF04 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SRF08 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SSB_B43_PCI_BRIDGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_BLOCKIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_DRIVER_GPIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_DRIVER_PCICORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_PCIHOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_PCIHOST_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_PCMCIAHOST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_SSB_PCMCIAHOST_POSSIBLE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_SSB_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SSB_SDIOHOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_SDIOHOST_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSB_SPROM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SSFDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SSI_PROTOCOL policy<{'armhf-generic': 'm'}> +CONFIG_STACKPROTECTOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_STACKPROTECTOR_PER_TASK policy<{'arm64': 'y'}> +CONFIG_STACKPROTECTOR_STRONG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_STACKTRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STACKTRACE_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STACK_TRACER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STAGING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_STAGING_APEX_DRIVER policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_STAGING_BOARD policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_STAGING_GASKET_FRAMEWORK policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_STAGING_MEDIA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_STANDALONE policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'i386': 'n', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STATIC_KEYS_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_STATIC_USERMODEHELPER policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_STE10XP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STK3310 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_STK8312 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_STK8BA50 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_STM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STMMAC_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_STMMAC_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_STMMAC_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_STMMAC_SELFTESTS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_STMPE_ADC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_STMPE_I2C policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_STMPE_SPI policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_STMP_DEVICE policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_STM_DUMMY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STM_PROTO_BASIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STM_PROTO_SYS_T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STM_SOURCE_CONSOLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STM_SOURCE_FTRACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STM_SOURCE_HEARTBEAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_STPMIC1_WATCHDOG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_STREAM_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STRICT_DEVMEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_STRICT_KERNEL_RWX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_STRICT_MODULE_RWX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_STRING_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_STRIP_ASM_SYMS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_STUB_CLK_HI3660 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_STUB_CLK_HI6220 policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_STX104 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_ST_UVIS25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ST_UVIS25_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ST_UVIS25_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SUN4I_EMAC policy<{'arm64': 'n'}> +CONFIG_SUN4I_GPADC policy<{'arm64': 'n'}> +CONFIG_SUN50I_A64_CCU policy<{'arm64': 'y'}> +CONFIG_SUN50I_DE2_BUS policy<{'arm64': 'y'}> +CONFIG_SUN50I_ERRATUM_UNKNOWN1 policy<{'arm64': 'y'}> +CONFIG_SUN50I_H6_CCU policy<{'arm64': 'y'}> +CONFIG_SUN50I_H6_R_CCU policy<{'arm64': 'y'}> +CONFIG_SUN8I_A83T_CCU policy<{'arm64': 'y'}> +CONFIG_SUN8I_DE2_CCU policy<{'arm64': 'y'}> +CONFIG_SUN8I_H3_CCU policy<{'arm64': 'y'}> +CONFIG_SUN8I_R_CCU policy<{'arm64': 'y'}> +CONFIG_SUNDANCE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SUNDANCE_MMIO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SUNGEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SUNGEM_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SUNRPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SUNRPC_BACKCHANNEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SUNRPC_DEBUG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SUNRPC_GSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SUNRPC_SWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SUNRPC_XPRT_RDMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_SUNXI_CCU policy<{'arm64': 'y'}> +CONFIG_SUNXI_RSB policy<{'arm64': 'm'}> +CONFIG_SUNXI_SRAM policy<{'arm64': 'y'}> +CONFIG_SUNXI_WATCHDOG policy<{'arm64': 'm'}> +CONFIG_SUN_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SURFACE3_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SURFACE_3_BUTTON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SURFACE_PRO3_BUTTON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SUSPEND policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SUSPEND_FREEZER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_SUSPEND_SKIP_SYNC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_SWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SWIOTLB policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SWIOTLB_XEN policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_SWPHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SWP_EMULATE policy<{'armhf': 'y'}> +CONFIG_SW_SYNC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SX9500 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SXGBE_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SYNCLINK policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SYNCLINKMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SYNCLINK_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_SYNCLINK_GT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SYNC_FILE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYN_COOKIES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSCON_REBOOT_MODE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_SYSCTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSCTL_EXCEPTION_TRACE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSCTL_SYSCALL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_SYSC_R8A7743 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7745 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A77470 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A774A1 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A774C0 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A7779 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7790 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7791 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7792 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7794 policy<{'armhf': 'y'}> +CONFIG_SYSC_R8A7795 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A7796 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A77965 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A77970 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A77980 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A77990 policy<{'arm64': 'y'}> +CONFIG_SYSC_R8A77995 policy<{'arm64': 'y'}> +CONFIG_SYSC_RCAR policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SYSC_RMOBILE policy<{'armhf': 'y'}> +CONFIG_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSFS_SYSCALL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEMPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_SYSTEM_BLACKLIST_HASH_LIST policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_SYSTEM_BLACKLIST_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEM_DATA_VERIFICATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEM_EXTRA_CERTIFICATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'i386': '4096', 'ppc64el': '4096', 's390x': '4096'}> +CONFIG_SYSTEM_REVOCATION_KEYS policy<{'amd64': '"debian/canonical-revoked-certs.pem"', 'arm64': '"debian/canonical-revoked-certs.pem"', 'armhf': '"debian/canonical-revoked-certs.pem"', 'i386': '"debian/canonical-revoked-certs.pem"', 'ppc64el': '"debian/canonical-revoked-certs.pem"', 's390x': '"debian/canonical-revoked-certs.pem"'}> +CONFIG_SYSTEM_REVOCATION_LIST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEM_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSTEM_TRUSTED_KEYS policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'i386': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}> +CONFIG_SYSV68_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_SYSVIPC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSVIPC_COMPAT policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSVIPC_SYSCTL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_SYSV_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_SYS_HYPERVISOR policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_SYS_SUPPORTS_APM_EMULATION policy<{'armhf': 'y'}> +CONFIG_SYS_SUPPORTS_EM_STI policy<{'armhf': 'y'}> +CONFIG_SYS_SUPPORTS_HUGETLBFS policy<{'arm64': 'y', 'armhf-generic-lpae': 'y', 'ppc64el': 'y'}> +CONFIG_SYS_SUPPORTS_SH_CMT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_SYS_SUPPORTS_SH_MTU2 policy<{'armhf': 'y'}> +CONFIG_SYS_SUPPORTS_SH_TMU policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_T5403 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_SERIAL_WACOM4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_ACECAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_AIPTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_GTCO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_HANWANG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_KBTAB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TABLET_USB_PEGASUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TAHVO_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TAHVO_USB_HOST_BY_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TARGET_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TASKSTATS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TASKS_RCU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TASK_DELAY_ACCT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TASK_IO_ACCOUNTING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TASK_XACCT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TC1100_WMI policy<{'i386': 'm'}> +CONFIG_TCG_ATMEL policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCG_CRB policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_TCG_FTPM_TEE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_TCG_IBMVTPM policy<{'ppc64el': 'y'}> +CONFIG_TCG_INFINEON policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_TCG_NSC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TCG_TIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TCG_TIS_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TCG_TIS_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCG_TIS_ST33ZP24 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCG_TIS_ST33ZP24_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TCG_TIS_ST33ZP24_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCG_VTPM_PROXY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCG_XEN policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_TCIC policy<{'i386': 'm'}> +CONFIG_TCM_FC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCM_FILEIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCM_IBLOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCM_PSCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCM_QLA2XXX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCM_QLA2XXX_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_TCM_USER2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_ADVANCED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TCP_CONG_BBR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_BIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_CDG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_CUBIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TCP_CONG_DCTCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_HSTCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_HTCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_HYBLA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_ILLINOIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_LP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_NV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_SCALABLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_VEGAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_VENO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_WESTWOOD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_CONG_YEAH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TCP_MD5SIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TCS3414 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TCS3472 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TEE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_TEGRA124_EMC policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA20_APB_DMA policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA20_EMC policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA210_ADMA policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_ACONNECT policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_AHB policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_BPMP policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_BPMP_THERMAL policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_CLK_DFLL policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_CLK_EMC policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_GMI policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_HOST1X policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_HOST1X_FIREWALL policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_HSP_MBOX policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_IOMMU_GART policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_IOMMU_SMMU policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_IVC policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_MC policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_SOCTHERM policy<{'armhf-generic': 'n'}> +CONFIG_TEGRA_TIMER policy<{'armhf-generic': 'y'}> +CONFIG_TEGRA_VDE policy<{'armhf-generic': 'm'}> +CONFIG_TEGRA_WATCHDOG policy<{'armhf-generic': 'm'}> +CONFIG_TEHUTI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TELCLOCK policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TERANETICS_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TEST_ASYNC_DRIVER_PROBE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_BITFIELD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_BITMAP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_BPF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TEST_FIRMWARE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_HASH policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_HEXDUMP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_IDA policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_KMOD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_KSTRTOX policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_LIST_SORT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_LIVEPATCH policy<{'amd64': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_LKM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_MEMCAT_P policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_MEMINIT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_OBJAGG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_OVERFLOW policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_PARMAN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TEST_PRINTF policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_RHASHTABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_SORT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_STACKINIT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_STATIC_KEYS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_STRING_HELPERS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_STRSCPY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_SYSCTL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_UDELAY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_USER_COPY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_UUID policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_VMALLOC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEST_XARRAY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TEXTSEARCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TEXTSEARCH_BM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TEXTSEARCH_FSM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TEXTSEARCH_KMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_THERMAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0'}> +CONFIG_THERMAL_EMULATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_GOV_BANG_BANG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_GOV_FAIR_SHARE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_GOV_POWER_ALLOCATOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_GOV_STEP_WISE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_GOV_USER_SPACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_MMIO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_THERMAL_OF policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_STATISTICS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THERMAL_WRITABLE_TRIPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THINKPAD_ACPI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_THINKPAD_ACPI_DEBUG policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_THINKPAD_ACPI_DEBUGFACILITIES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_THINKPAD_ACPI_HOTKEY_POLL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_THINKPAD_ACPI_UNSAFE_LEDS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_THINKPAD_ACPI_VIDEO policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_THP_SWAP policy<{'amd64': 'y'}> +CONFIG_THREAD_INFO_IN_TASK policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_THREAD_SHIFT policy<{'ppc64el': '14'}> +CONFIG_THRUSTMASTER_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_THUMB2_KERNEL policy<{'armhf': 'n'}> +CONFIG_THUNDERBOLT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_THUNDERBOLT_NET policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_THUNDERX2_PMU policy<{'arm64': 'm'}> +CONFIG_THUNDER_NIC_BGX policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_THUNDER_NIC_PF policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_THUNDER_NIC_RGX policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_THUNDER_NIC_VF policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}> +CONFIG_TICK_CPU_ACCOUNTING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TICK_ONESHOT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TIFM_7XX1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TIFM_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TIGON3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TIGON3_HWMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TIMB_DMA policy<{'i386': 'm'}> +CONFIG_TIMERFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TIMER_ACPI policy<{'arm64': 'y'}> +CONFIG_TIMER_IMX_SYS_CTR policy<{'arm64': 'y'}> +CONFIG_TIMER_OF policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_TIMER_PROBE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_TINYDRM_HX8357D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_ILI9225 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_ILI9341 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_MI0283QT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_REPAPER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_ST7586 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TINYDRM_ST7735R policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TIPC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TIPC_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TIPC_MEDIA_IB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TIPC_MEDIA_UDP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TI_ADC081C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC0832 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC084S021 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC108S102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC12138 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC128S052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADC161S626 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADS1015 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADS124S08 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADS7950 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADS8344 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TI_ADS8688 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TI_AM335X_ADC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'i386': '-', 'ppc64el': '-'}> +CONFIG_TI_CPPI41 policy<{'armhf': 'm'}> +CONFIG_TI_CPSW policy<{'armhf': 'y'}> +CONFIG_TI_CPSW_PHY_SEL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_TI_CPTS policy<{'armhf': 'y'}> +CONFIG_TI_CPTS_MOD policy<{'armhf': 'y'}> +CONFIG_TI_DAC082S085 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_DAC5571 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_DAC7311 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_DAC7612 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TI_DAVINCI_EMAC policy<{'armhf-generic': 'm'}> +CONFIG_TI_DAVINCI_MDIO policy<{'armhf': 'y'}> +CONFIG_TI_DMA_CROSSBAR policy<{'armhf': 'y'}> +CONFIG_TI_EDMA policy<{'armhf': 'y'}> +CONFIG_TI_EMIF policy<{'armhf': 'm'}> +CONFIG_TI_EMIF_SRAM policy<{'armhf-generic': 'm'}> +CONFIG_TI_MESSAGE_MANAGER policy<{'arm64': 'y'}> +CONFIG_TI_PIPE3 policy<{'armhf': 'm'}> +CONFIG_TI_SCI_CLK policy<{'arm64': 'm'}> +CONFIG_TI_SCI_CLK_PROBE_FROM_FW policy<{'arm64': 'n'}> +CONFIG_TI_SCI_INTA_IRQCHIP policy<{'arm64': 'y'}> +CONFIG_TI_SCI_INTA_MSI_DOMAIN policy<{'arm64': 'y'}> +CONFIG_TI_SCI_INTR_IRQCHIP policy<{'arm64': 'y'}> +CONFIG_TI_SCI_PM_DOMAINS policy<{'arm64': 'm'}> +CONFIG_TI_SCI_PROTOCOL policy<{'arm64': 'y'}> +CONFIG_TI_SOC_THERMAL policy<{'armhf': 'm'}> +CONFIG_TI_ST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TI_SYSC policy<{'armhf': 'y'}> +CONFIG_TI_THERMAL policy<{'armhf': 'y'}> +CONFIG_TI_TLC4541 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TLS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'n', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TLS_DEVICE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TMD_HERMES policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TMP006 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TMP007 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TMPFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TMPFS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TN3215 policy<{'s390x': 'y'}> +CONFIG_TN3215_CONSOLE policy<{'s390x': 'y'}> +CONFIG_TN3270 policy<{'s390x': 'y'}> +CONFIG_TN3270_CONSOLE policy<{'s390x': 'y'}> +CONFIG_TN3270_FS policy<{'s390x': 'm'}> +CONFIG_TN3270_TTY policy<{'s390x': 'y'}> +CONFIG_TOPSTAR_LAPTOP policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TORTURE_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TOSHIBA policy<{'i386': 'n'}> +CONFIG_TOSHIBA_BT_RFKILL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TOSHIBA_HAPS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TOSHIBA_WMI policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_TOUCHSCREEN_88PM860X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_AD7877 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_AD7879 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_AD7879_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_AD7879_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ADS7846 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_AR1021_I2C policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ATMEL_MXT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_AUO_PIXCIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_BU21013 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_BU21029 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_TOUCHSCREEN_COLIBRI_VF50 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CY8CTMG110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP4_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP4_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP4_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_CYTTSP_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_DA9034 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_DA9052 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_DMI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_TOUCHSCREEN_DYNAPRO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EDT_FT5X06 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EETI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EGALAX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EGALAX_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EKTF2127 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ELO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_EXC3000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_FUJITSU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_GOODIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_GUNZE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_HAMPSHIRE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_HIDEEP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_HTCPEN policy<{'i386': 'm'}> +CONFIG_TOUCHSCREEN_ILI210X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_IMX6UL_TSC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_INEXIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_IPROC policy<{'arm64': 'm'}> +CONFIG_TOUCHSCREEN_IQS5XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MAX11801 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MC13783 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MCS5000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MELFAS_MIP4 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MK712 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MMS114 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_MTOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_PCAP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_PENMOUNT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_PIXCIR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_PROPERTIES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_RASPBERRYPI_FW policy<{'arm64': 'm'}> +CONFIG_TOUCHSCREEN_RM_TS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ROHM_BU21023 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_S6SY761 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_SILEAD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_SIS_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ST1232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_STMFTS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_STMPE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_SUN4I policy<{'arm64': 'n'}> +CONFIG_TOUCHSCREEN_SUR40 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_SURFACE3_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_SX8654 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TI_AM335X_TSC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'i386': '-', 'ppc64el': '-'}> +CONFIG_TOUCHSCREEN_TOUCHIT213 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TOUCHRIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TOUCHWIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TPS6507X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TS4800 policy<{'armhf-generic': 'm'}> +CONFIG_TOUCHSCREEN_TSC2004 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TSC2005 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TSC2007 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TSC2007_IIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_TSC200X_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_TSC_SERIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_UCB1400 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_USB_3M policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_COMPOSITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_USB_DMC_TSC10 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_E2I policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_EASYTOUCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_EGALAX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_ELO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_ETURBO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_GOTOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_GUNZE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_IDEALTEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_IRTOUCH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_ITM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_JASTEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_NEXIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_PANJIT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_USB_ZYTRONIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_WACOM_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_WACOM_W8001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_WDT87XX_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_WM831X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_WM9705 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_WM9712 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_WM9713 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TOUCHSCREEN_WM97XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ZET6223 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TOUCHSCREEN_ZFORCE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TPL0102 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TPM_KEY_PARSER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_TPS6105X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TPS65010 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TPS6507X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TPS68470_PMIC_OPREGION policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_TQMX86_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_TRACEPOINTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACEPOINT_BENCHMARK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TRACER_MAX_TRACE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACER_SNAPSHOT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TRACE_CLOCK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACE_EVAL_MAP_FILE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TRACE_IRQFLAGS_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACE_ROUTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TRACE_SINK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACING_MAP policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRACING_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRANSPARENT_HUGEPAGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS policy<{'amd64': 'n', 'arm64': 'n', 'armhf-generic-lpae': 'n', 'i386': 'n', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_TRANSPARENT_HUGEPAGE_MADVISE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'n', 's390x': 'y'}> +CONFIG_TRANSPARENT_HUGE_PAGECACHE policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TREE_RCU policy<{'amd64-generic': 'y', 'arm64': 'y', 'armhf': 'y', 'i386-generic': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TREE_SRCU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TRUSTED_FOUNDATIONS policy<{'armhf': 'y'}> +CONFIG_TRUSTED_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TS4800_IRQ policy<{'armhf-generic': 'm'}> +CONFIG_TS4800_WATCHDOG policy<{'armhf-generic': 'm'}> +CONFIG_TSL2583 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TSL2772 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TSL4531 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TSYS01 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TSYS02D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TTPCI_EEPROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TTY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TTY_PRINTK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_TTY_PRINTK_LEVEL policy<{'amd64': '6', 'arm64': '6', 'armhf': '6', 'i386': '6', 'ppc64el': '6'}> +CONFIG_TULIP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TULIP_MMIO policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_TULIP_MWI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_TULIP_NAPI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_TUN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_TUNE_DEFAULT policy<{'s390x': 'n'}> +CONFIG_TUNE_Z10 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z13 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z14 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z15 policy<{'s390x': 'y'}> +CONFIG_TUNE_Z196 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z900 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z990 policy<{'s390x': 'n'}> +CONFIG_TUNE_Z9_109 policy<{'s390x': 'n'}> +CONFIG_TUNE_ZEC12 policy<{'s390x': 'n'}> +CONFIG_TUN_VNET_CROSS_LE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_TURRIS_MOX_RWTM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_TWL4030_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TWL4030_MADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TWL4030_POWER policy<{'armhf': 'y'}> +CONFIG_TWL4030_USB policy<{'armhf': 'm'}> +CONFIG_TWL4030_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TWL6030_GPADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TWL6030_USB policy<{'armhf': 'm'}> +CONFIG_TWL6040_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_TYPEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_DP_ALTMODE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_FUSB302 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_MUX_PI3USB30532 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_NVIDIA_ALTMODE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_RT1711H policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_TCPCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_TCPM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_TPS6598X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPEC_UCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_TYPHOON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UACCESS_WITH_MEMCPY policy<{'armhf': 'n'}> +CONFIG_UBIFS_ATIME_SUPPORT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_UBIFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UBIFS_FS_ADVANCED_COMPR policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_UBIFS_FS_AUTHENTICATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBIFS_FS_LZO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBIFS_FS_SECURITY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBIFS_FS_XATTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBIFS_FS_ZLIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBIFS_FS_ZSTD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UBSAN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_UBSAN_ALIGNMENT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UBUNTU_ODM_DRIVERS policy<{'amd64': 'y'}> +CONFIG_UCB1400_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UCLAMP_BUCKETS_COUNT policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'i386': '5', 'ppc64el': '5'}> +CONFIG_UCLAMP_TASK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UCLAMP_TASK_GROUP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UCS2_STRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y'}> +CONFIG_UCSI_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_UCSI_CCG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UDBG_RTAS_CONSOLE policy<{'ppc64el': 'n'}> +CONFIG_UDF_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_UDMABUF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UEFI_CPER policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_UEFI_CPER_ARM policy<{'arm64': 'y'}> +CONFIG_UEFI_CPER_X86 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_UEVENT_HELPER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UEVENT_HELPER_PATH policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_UFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_UFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UFS_FS_WRITE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_UHID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UID16 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 's390x': 'y'}> +CONFIG_UIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_UIO_AEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_CIF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_DMEM_GENIRQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_FSL_ELBC_GPCM policy<{'ppc64el': 'm'}> +CONFIG_UIO_FSL_ELBC_GPCM_NETX5152 policy<{'ppc64el': 'n'}> +CONFIG_UIO_HV_GENERIC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_UIO_MF624 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_NETX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_PCI_GENERIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_PDRV_GENIRQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_PRUSS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_UIO_SERCOS3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ULI526X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ULTRA policy<{'i386': 'm'}> +CONFIG_ULTRIX_PARTITION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_UNCOMPRESS_INCLUDE policy<{'armhf': '"debug/uncompress.h"'}> +CONFIG_UNICODE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UNICODE_NORMALIZATION_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_UNINLINE_SPIN_UNLOCK policy<{'amd64-lowlatency': 'y', 'i386-lowlatency': 'y'}> +CONFIG_UNIPHIER_EFUSE policy<{'armhf': 'm'}> +CONFIG_UNIPHIER_MDMAC policy<{'armhf': 'm'}> +CONFIG_UNIPHIER_SYSTEM_BUS policy<{'armhf': 'y'}> +CONFIG_UNIPHIER_THERMAL policy<{'armhf': 'm'}> +CONFIG_UNIPHIER_WATCHDOG policy<{'armhf': 'm'}> +CONFIG_UNISYSSPAR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_UNISYS_VISORBUS policy<{'amd64': 'm'}> +CONFIG_UNISYS_VISORHBA policy<{'amd64': 'm'}> +CONFIG_UNISYS_VISORINPUT policy<{'amd64': 'm'}> +CONFIG_UNISYS_VISORNIC policy<{'amd64': 'm'}> +CONFIG_UNIX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UNIX98_PTYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UNIXWARE_DISKLABEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_UNIX_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_UNIX_SCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UNMAP_KERNEL_AT_EL0 policy<{'arm64': 'y'}> +CONFIG_UNUSED_SYMBOLS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UNWINDER_GUESS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_UNWINDER_ORC policy<{'amd64': 'n'}> +CONFIG_UPROBES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UPROBE_EVENTS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_US5182D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USBIP_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USBIP_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USBIP_HOST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USBIP_VHCI_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USBIP_VHCI_HC_PORTS policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_USBIP_VHCI_NR_HCS policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'i386': '1', 'ppc64el': '1'}> +CONFIG_USBIP_VUDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USBPCWATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ACM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ADUTUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_AIRSPY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ALI_M5632 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_AMD5536UDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_AN2720 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ANNOUNCE_NEW_DEVICES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_APPLEDISPLAY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ARCH_HAS_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ARMLINUX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ASPEED_VHUB policy<{'armhf': 'm'}> +CONFIG_USB_ATM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_AUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_AUTOSUSPEND_DELAY policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'i386': '2', 'ppc64el': '2'}> +CONFIG_USB_BDC_UDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_BELKIN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_C67X00_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CATC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CDC_COMPOSITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CDC_PHONET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CDNS3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CDNS3_GADGET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CDNS3_HOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CDNS3_PCI_WRAP policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_USB_CHAOSKEY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CHIPIDEA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CHIPIDEA_HOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CHIPIDEA_OF policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CHIPIDEA_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CHIPIDEA_UDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_COMMON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CONFIGFS_ACM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_ECM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_ECM_SUBSET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_EEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_FS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_HID policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_LB_SS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_MIDI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_PRINTER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_TCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_UAC1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_UAC2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_F_UVC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_MASS_STORAGE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_NCM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_OBEX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_PHONET policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_RNDIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONFIGFS_SERIAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_CONN_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CXACRU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CYPRESS_CY7C63 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_CYTHERM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_DEFAULT_PERSIST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_DSBR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_DUMMY_HCD policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_DWC2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_DWC2_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_DWC2_DUAL_ROLE policy<{'armhf': 'n'}> +CONFIG_USB_DWC2_HOST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_DWC2_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_DWC2_PERIPHERAL policy<{'armhf': 'n'}> +CONFIG_USB_DWC2_TRACK_MISSED_SOFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_DWC3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_DWC3_DUAL_ROLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_DWC3_EXYNOS policy<{'armhf': 'm'}> +CONFIG_USB_DWC3_GADGET policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_DWC3_HAPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_DWC3_HOST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_DWC3_KEYSTONE policy<{'arm64': 'm'}> +CONFIG_USB_DWC3_MESON_G12A policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_DWC3_OF_SIMPLE policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_DWC3_OMAP policy<{'armhf': 'm'}> +CONFIG_USB_DWC3_PCI policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_USB_DWC3_QCOM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_DWC3_ULPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_DYNAMIC_MINORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EG20T policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_EHCI_EXYNOS policy<{'armhf': 'y'}> +CONFIG_USB_EHCI_FSL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_EHCI_HCD_NPCM7XX policy<{'armhf': 'm'}> +CONFIG_USB_EHCI_HCD_OMAP policy<{'armhf': 'm'}> +CONFIG_USB_EHCI_HCD_ORION policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_USB_EHCI_HCD_PPC_OF policy<{'ppc64el': 'y'}> +CONFIG_USB_EHCI_MXC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_USB_EHCI_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EHCI_ROOT_HUB_TT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EHCI_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_USB_EHCI_TT_NEWSCHED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EHSET_TEST_FIXTURE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_EMI26 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_EMI62 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_EMXX policy<{'arm64': 'm', 'armhf': 'y'}> +CONFIG_USB_EPSON2888 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ETH_EEM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ETH_RNDIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_EZUSB_FX2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_FOTG210_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_FOTG210_UDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_FSL_USB2 policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_USB_FTDI_ELAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_FUNCTIONFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_FUNCTIONFS_ETH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_FUNCTIONFS_GENERIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_FUNCTIONFS_RNDIS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_FUSB300 policy<{'armhf-generic': 'm'}> +CONFIG_USB_F_ACM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_ECM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_EEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_MASS_STORAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_MIDI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_NCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_OBEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_PHONET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_PRINTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_RNDIS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_SS_LB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_SUBSET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_TCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_UAC1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_UAC1_LEGACY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_UAC2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_F_UVC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GADGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GADGETFS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GADGET_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_GADGET_DEBUG_FILES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_GADGET_DEBUG_FS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'i386': '2', 'ppc64el': '2'}> +CONFIG_USB_GADGET_TARGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GADGET_VBUS_DRAW policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'i386': '2', 'ppc64el': '2'}> +CONFIG_USB_GADGET_XILINX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GL860 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GOKU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GPIO_VBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GR_UDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_BENQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_CONEX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_CPIA1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_DTCS033 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_ETOMS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_FINEPIX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_JEILINJ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_JL2005BCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_KINECT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_KONICA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_MARS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_MR97310A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_NW80X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_OV519 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_OV534 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_OV534_9 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_PAC207 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_PAC7302 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_PAC7311 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SE401 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SN9C2028 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SN9C20X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SONIXB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SONIXJ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA1528 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA500 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA501 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA505 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA506 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA508 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SPCA561 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SQ905 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SQ905C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SQ930X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_STK014 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_STK1135 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_STV0680 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_SUNPLUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_T613 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_TOPRO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_TOUPTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_TV8532 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_VC032X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_VICAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_XIRLINK_CIT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_GSPCA_ZC3XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_ACM_MS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_DBGP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_DBGP_PRINTK policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_G_DBGP_SERIAL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_G_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_MULTI policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'm', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_G_MULTI_CDC policy<{'armhf': 'y'}> +CONFIG_USB_G_MULTI_RNDIS policy<{'armhf': 'y'}> +CONFIG_USB_G_NCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_NOKIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_PRINTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_G_WEBCAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HACKRF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HCD_TEST_MODE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_HID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HIDDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_HSIC_USB3503 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HSIC_USB4604 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HSO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HUB_USB251XB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_HWA_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_IDMOUSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_IMX21_HCD policy<{'armhf-generic': 'm'}> +CONFIG_USB_IOWARRIOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_IPHETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ISIGHTFW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ISP116X_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ISP1301 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ISP1760 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ISP1760_DUAL_ROLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ISP1760_GADGET_ROLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_ISP1760_HCD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_ISP1760_HOST_ROLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_ISP1761_UDC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_KAWETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_KBD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_KC2190 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_KEENE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LAN78XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LEDS_TRIGGER_USBPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LED_TRIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_LEGOTOWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LIBCOMPOSITE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_LINK_LAYER_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_M5602 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MA901 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MASS_STORAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MAX3421_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MDC800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MICROTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MIDI_GADGET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MOUSE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MR800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MSI2500 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MTU3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_MTU3_DEBUG policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_USB_MTU3_DUAL_ROLE policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_USB_MTU3_GADGET policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_USB_MTU3_HOST policy<{'arm64': 'n', 'armhf': 'n'}> +CONFIG_USB_MUSB_AM335X_CHILD policy<{'armhf': 'm'}> +CONFIG_USB_MUSB_AM35X policy<{'armhf': 'm'}> +CONFIG_USB_MUSB_DSPS policy<{'armhf': 'm'}> +CONFIG_USB_MUSB_DUAL_ROLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_MUSB_GADGET policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_MUSB_HOST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_MUSB_OMAP2PLUS policy<{'armhf': 'm'}> +CONFIG_USB_MUSB_SUNXI policy<{'arm64': 'm'}> +CONFIG_USB_MUSB_TUSB6010 policy<{'armhf': 'm'}> +CONFIG_USB_MV_U3D policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MV_UDC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_MXS_PHY policy<{'arm64': 'y', 'armhf-generic': 'y'}> +CONFIG_USB_NET2272 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET2272_DMA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_NET2280 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_AQC111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_AX88179_178A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_AX8817X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDCETHER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDC_EEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDC_MBIM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDC_NCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDC_SUBSET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CDC_SUBSET_ENABLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CH9200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_CX82310_ETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_DM9601 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_DRIVERS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_GL620A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_HUAWEI_CDC_NCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_INT51X1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_KALMIA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_MCS7830 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_NET1080 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_PLUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_QMI_WWAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_RNDIS_HOST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_RNDIS_WLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_SMSC75XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_SMSC95XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_SR9700 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_SR9800 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_NET_ZAURUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_OHCI_EXYNOS policy<{'armhf': 'y'}> +CONFIG_USB_OHCI_HCD_OMAP3 policy<{'armhf-generic': 'm'}> +CONFIG_USB_OHCI_HCD_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_OHCI_HCD_PLATFORM policy<{'amd64': 'y', 'arm64': 'm', 'armhf-generic': 'm', 'armhf-generic-lpae': 'n', 'i386': 'y', 'ppc64el': 'm'}> +CONFIG_USB_OHCI_HCD_PPC_OF_BE policy<{'ppc64el': 'n'}> +CONFIG_USB_OHCI_HCD_PPC_OF_LE policy<{'ppc64el': 'n'}> +CONFIG_USB_OHCI_LITTLE_ENDIAN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_USB_OXU210HP_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_PEGASUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_PHY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_PRINTER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_PULSE8_CEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_PWC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_PWC_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_PWC_INPUT_EVDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_PXA27X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_R8A66597 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_R8A66597_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_RAINSHADOW_CEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_RAREMONO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_RENESAS_USB3 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_RENESAS_USBHS policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_RENESAS_USBHS_HCD policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_RENESAS_USBHS_UDC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_ROLES_INTEL_XHCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_USB_ROLE_SWITCH policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_RTL8150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_RTL8152 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_S2255 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_AIRCABLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_ARK3116 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_BELKIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_CH341 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_CP210X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_CYBERJACK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_CYPRESS_M8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_DIGI_ACCELEPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_EDGEPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_EDGEPORT_TI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_EMPEG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_F81232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_F8153X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_FTDI_SIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_GARMIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_GENERIC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_SERIAL_IPAQ policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_IPW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_IR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_IUU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_KEYSPAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_KEYSPAN_PDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_KLSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_KOBIL_SCT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_MCT_U232 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_METRO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_MOS7715_PARPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_SERIAL_MOS7720 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_MOS7840 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_MXUPORT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_NAVMAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_OMNINET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_OPTICON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_OPTION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_OTI6858 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_PL2303 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_QCAUX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_QT2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_QUALCOMM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SAFE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SAFE_PADDED policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_SERIAL_SIERRAWIRELESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SIMPLE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SPCP8X5 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SSU100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_SYMBOL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_TI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_UPD78F0730 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_VISOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_WHITEHEAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_WISHBONE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_WWAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_XIRCOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SERIAL_XSENS_MT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SEVSEG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SI470X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SI4713 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SIERRA_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SISUSBVGA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SL811_CS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_USB_SL811_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SL811_HCD_ISO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_SNP_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SNP_UDC_PLAT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SPEEDTOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STKWEBCAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_ALAUDA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_CYPRESS_ATACB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_DATAFAB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_STORAGE_ENE_UB6250 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_FREECOM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_ISD200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_JUMPSHOT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_KARMA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_ONETOUCH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_REALTEK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_SDDR09 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_SDDR55 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STORAGE_USBAT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_STV06XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_SUPPORT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_USB_TEGRA_PHY policy<{'armhf-generic': 'm'}> +CONFIG_USB_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_TMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_TRANCEVIBRATOR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_U132_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_UAS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_UEAGLEATM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_UHCI_ASPEED policy<{'armhf': 'y'}> +CONFIG_USB_UHCI_PLATFORM policy<{'armhf': 'y'}> +CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC policy<{'armhf': 'y'}> +CONFIG_USB_ULPI policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_USB_ULPI_BUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ULPI_VIEWPORT policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_USB_USBNET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_USS720 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_U_AUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_U_ETHER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_U_SERIAL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_VIDEO_CLASS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_VL600 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_WDM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_WHCI_HCD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_WUSB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_WUSB_CBAF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_WUSB_CBAF_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_USB_XHCI_HISTB policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_XHCI_MTK policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_XHCI_MVEBU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_XHCI_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_USB_XHCI_PLATFORM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_XHCI_RCAR policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_USB_XHCI_TEGRA policy<{'armhf-generic': 'm'}> +CONFIG_USB_XUSBATM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_YUREX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ZD1201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ZERO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USB_ZR364XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USELIB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_USERFAULTFD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_USERIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_USER_NS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_USER_RETURN_NOTIFIER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_USER_STACKTRACE_SUPPORT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_USE_OF policy<{'armhf': 'y'}> +CONFIG_USE_PERCPU_NUMA_NODE_ID policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}> +CONFIG_UTS_NS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_UV_MMTIMER policy<{'amd64': 'm'}> +CONFIG_UWB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UWB_HWA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UWB_I1480U policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_UWB_WHCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_U_SERIAL_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_V4L2_FLASH_LED_CLASS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_V4L2_FWNODE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_V4L2_MEM2MEM_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_V4L_MEM2MEM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_V4L_PLATFORM_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_V4L_RADIO_ISA_DRIVERS policy<{'i386': 'y'}> +CONFIG_V4L_TEST_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VALIDATE_FS_PARSER policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VCNL4000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VCNL4035 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VDSO policy<{'armhf': 'y'}> +CONFIG_VEML6070 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VERSION_SIGNATURE policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'i386': '""', 'ppc64el': '""', 's390x': '""'}> +CONFIG_VETH policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VEXPRESS_CONFIG policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_VEXPRESS_SYSCFG policy<{'arm64': 'y', 'armhf': 'y'}> +CONFIG_VF610_ADC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VF610_DAC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VFIO_AMBA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VFIO_AP policy<{'s390x': 'm'}> +CONFIG_VFIO_CCW policy<{'s390x': 'm'}> +CONFIG_VFIO_IOMMU_SPAPR_TCE policy<{'ppc64el': 'y'}> +CONFIG_VFIO_IOMMU_TYPE1 policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 's390x': 'm'}> +CONFIG_VFIO_MDEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VFIO_MDEV_DEVICE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VFIO_NOIOMMU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VFIO_PCI_IGD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VFIO_PCI_INTX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VFIO_PCI_MMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VFIO_PCI_NVLINK2 policy<{'ppc64el': 'y'}> +CONFIG_VFIO_PCI_VGA policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VFIO_PLATFORM policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VFIO_PLATFORM_AMDXGBE_RESET policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET policy<{'arm64': 'm'}> +CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VFIO_SPAPR_EEH policy<{'ppc64el': 'y'}> +CONFIG_VFIO_VIRQFD policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_VFP policy<{'armhf': 'y'}> +CONFIG_VFPv3 policy<{'armhf': 'y'}> +CONFIG_VF_USE_ARM_GLOBAL_TIMER policy<{'armhf-generic': 'y'}> +CONFIG_VF_USE_PIT_TIMER policy<{'armhf-generic': 'n'}> +CONFIG_VGASTATE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VGA_ARB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VGA_ARB_MAX_GPUS policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'i386': '16', 'ppc64el': '16'}> +CONFIG_VGA_CONSOLE policy<{'amd64': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VGA_SWITCHEROO policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VHOST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VHOST_CROSS_ENDIAN_LEGACY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_VHOST_NET policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VHOST_RING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VHOST_SCSI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VHOST_VSOCK policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIA_RHINE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIA_RHINE_MMIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIA_VELOCITY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIA_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEOBUF2_CORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_DMA_CONTIG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_DMA_SG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_MEMOPS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_V4L2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF2_VMALLOC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF_DMA_SG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF_GEN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOBUF_VMALLOC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEOMODE_HELPERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_AD5820 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_AD9389B policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADP1653 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7170 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7175 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7180 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7183 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7343 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7393 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV748X policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7511 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_ADV7511_CEC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VIDEO_ADV7604 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7604_CEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_ADV7842 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ADV7842_CEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_ADV_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VIDEO_AK7375 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_AK881X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ALLEGRO_DVT policy<{'arm64': 'm'}> +CONFIG_VIDEO_APTINA_PLL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ASPEED policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_AU0828 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_AU0828_RC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_AU0828_V4L2 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_BCM2835 policy<{'arm64': 'm'}> +CONFIG_VIDEO_BT819 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_BT848 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_BT856 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_BT866 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CADENCE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_CADENCE_CSI2RX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CADENCE_CSI2TX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CAFE_CCIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_VIDEO_COBALT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_CODA policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_VIDEO_CPIA2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CROS_EC_CEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_VIDEO_CS3308 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CS5345 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CS53L32A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX18 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX18_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX231XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX231XX_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX231XX_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX231XX_RC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_CX2341X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX23885 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX25821 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX25821_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX25840 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88_BLACKBIRD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88_ENABLE_VP3054 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_CX88_MPEG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_CX88_VP3054 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_DEV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_DT3155 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_DW9714 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_DW9807_VCM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_EM28XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_EM28XX_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_EM28XX_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_EM28XX_RC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_EM28XX_V4L2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ET8EK8 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_FB_IVTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_FB_IVTV_FORCE_PAT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VIDEO_FIXED_MINOR_RANGES policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VIDEO_GO7007 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_GO7007_LOADER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_GO7007_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_GO7007_USB_S2250_BOARD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_GS1662 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_HDPVR policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_HEXIUM_GEMINI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_HEXIUM_ORION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX214 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX258 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX274 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX319 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX355 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IMX7_CSI policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_IMX_CSI policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_IMX_MEDIA policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_IMX_PXP policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_VIDEO_IMX_VDOA policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_IPU3_CIO2 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_IPU3_IMGU policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_IR_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IVTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IVTV_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_IVTV_DEPRECATED_IOCTLS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VIDEO_KS0127 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_LM3560 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_LM3646 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_M52790 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_M5MOLS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MEDIATEK_VPU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_MEM2MEM_DEINTERLACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MESON_AO_CEC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_MESON_G12A_AO_CEC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_MESON_VDEC policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_MEYE policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_ML86V7667 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MSP3400 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9M001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9M032 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9M111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9P031 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9T001 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9T112 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9V011 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9V032 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MT9V111 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MUX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_MXB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_NOON010PC30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OMAP2_VOUT policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_OMAP2_VOUT_VRFB policy<{'armhf-generic': 'y'}> +CONFIG_VIDEO_OMAP3 policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_OMAP3_DEBUG policy<{'armhf-generic': 'n'}> +CONFIG_VIDEO_OMAP4 policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_OV13858 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV2640 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV2659 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV2680 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV2685 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5640 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5645 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5647 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5670 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5675 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV5695 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV6650 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV7251 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV7640 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV7670 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV772X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV7740 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV8856 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV9640 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_OV9650 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_PCI_SKELETON policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VIDEO_PVRUSB2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_PVRUSB2_DEBUGIFC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VIDEO_PVRUSB2_DVB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_PVRUSB2_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_QCOM_CAMSS policy<{'arm64': 'm'}> +CONFIG_VIDEO_QCOM_VENUS policy<{'arm64': 'm'}> +CONFIG_VIDEO_RCAR_CSI2 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RCAR_DRIF policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RCAR_VIN policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RENESAS_CEU policy<{'armhf': 'm'}> +CONFIG_VIDEO_RENESAS_FCP policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RENESAS_FDP1 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RENESAS_JPU policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RENESAS_VSP1 policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_RJ54N1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ROCKCHIP_RGA policy<{'arm64': 'm', 'armhf': 'm'}> +CONFIG_VIDEO_S5C73M3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_S5K4ECGX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_S5K5BAF policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_S5K6A3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_S5K6AA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA6588 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA6752HS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7110 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA711X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7127 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7134 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7134_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7134_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7134_GO7007 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7134_RC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_SAA7146 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7146_VV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7164 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA717X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAA7185 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS policy<{'armhf': 'n'}> +CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC policy<{'armhf': 'm'}> +CONFIG_VIDEO_SAMSUNG_S5P_CEC policy<{'armhf': 'm'}> +CONFIG_VIDEO_SAMSUNG_S5P_G2D policy<{'armhf': 'm'}> +CONFIG_VIDEO_SAMSUNG_S5P_JPEG policy<{'armhf': 'm'}> +CONFIG_VIDEO_SAMSUNG_S5P_MFC policy<{'armhf': 'm'}> +CONFIG_VIDEO_SECO_CEC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_SECO_RC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VIDEO_SH_VEU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SMIAPP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_VIDEO_SMIAPP_PLL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_VIDEO_SOLO6X10 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SONY_BTF_MPX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SR030PC30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_STK1160 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_STK1160_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_ST_MIPID02 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_SUN4I_CSI policy<{'arm64': 'm'}> +CONFIG_VIDEO_SUN6I_CSI policy<{'arm64': 'm'}> +CONFIG_VIDEO_SUNXI policy<{'arm64': 'y'}> +CONFIG_VIDEO_TC358743 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TC358743_CEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_TDA1997X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TDA7432 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TDA9840 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TEA6415C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TEA6420 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TEGRA_HDMI_CEC policy<{'armhf-generic': 'm'}> +CONFIG_VIDEO_THS7303 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_THS8200 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TI_CAL policy<{'armhf': 'm'}> +CONFIG_VIDEO_TI_CSC policy<{'armhf': 'm'}> +CONFIG_VIDEO_TI_SC policy<{'armhf': 'm'}> +CONFIG_VIDEO_TI_VPDMA policy<{'armhf': 'm'}> +CONFIG_VIDEO_TI_VPE policy<{'armhf': 'm'}> +CONFIG_VIDEO_TI_VPE_DEBUG policy<{'armhf': 'n'}> +CONFIG_VIDEO_TLV320AIC23B policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TM6000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TM6000_ALSA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TM6000_DVB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TUNER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TVAUDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TVEEPROM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TVP514X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TVP5150 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TVP7002 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW2804 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW5864 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW68 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW686X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW9903 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW9906 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_TW9910 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_UDA1342 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_UPD64031A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_UPD64083 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_USBTV policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_USBVISION policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_V4L2 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_V4L2_I2C policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_V4L2_SUBDEV_API policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_V4L2_TPG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VIA_CAMERA policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VIDEO_VICODEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VIM2M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VIVID policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VIVID_CEC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIDEO_VIVID_MAX_DEVS policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'i386': '64', 'ppc64el': '64'}> +CONFIG_VIDEO_VP27SMPX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VPX3220 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_VS6624 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_WM8739 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_WM8775 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_XILINX policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_XILINX_TPG policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIDEO_XILINX_VTC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_VIPERBOARD_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIRTIO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_BALLOON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_BLK_SCSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTIO_INPUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTIO_IOMMU policy<{'arm64': 'y'}> +CONFIG_VIRTIO_MENU policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VIRTIO_PCI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_PCI_LEGACY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRTIO_PMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf-generic-lpae': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VIRTIO_VSOCKETS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTIO_VSOCKETS_COMMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VIRTUALIZATION policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRT_CPU_ACCOUNTING policy<{'s390x': 'y'}> +CONFIG_VIRT_CPU_ACCOUNTING_GEN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}> +CONFIG_VIRT_CPU_ACCOUNTING_NATIVE policy<{'ppc64el': 'n', 's390x': 'y'}> +CONFIG_VIRT_DRIVERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VIRT_TO_BUS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_VIRT_WIFI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VITESSE_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VL53L0X_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VL6180 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VLAN_8021Q policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VLAN_8021Q_GVRP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VLAN_8021Q_MVRP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VM86 policy<{'i386': 'y'}> +CONFIG_VMAP_STACK policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}> +CONFIG_VMCP policy<{'s390x': 'y'}> +CONFIG_VMCP_CMA_SIZE policy<{'s390x': '4'}> +CONFIG_VMD policy<{'amd64': 'm'}> +CONFIG_VME_BUS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_VME_CA91CX42 policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VME_FAKE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VME_TSI148 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VME_USER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VMIVME_7805 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VMLOGRDR policy<{'s390x': 'm'}> +CONFIG_VMSPLIT_1G policy<{'armhf': 'n', 'i386': 'n'}> +CONFIG_VMSPLIT_2G policy<{'armhf': 'n', 'i386': 'n'}> +CONFIG_VMSPLIT_3G policy<{'armhf': 'y', 'i386': 'y'}> +CONFIG_VMSPLIT_3G_OPT policy<{'armhf-generic': 'n'}> +CONFIG_VMWARE_BALLOON policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VMWARE_PVSCSI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VMWARE_VMCI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VMWARE_VMCI_VSOCKETS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_VMXNET3 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 's390x': 'n'}> +CONFIG_VM_EVENT_COUNTERS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VOP policy<{'amd64': 'm'}> +CONFIG_VOP_BUS policy<{'amd64': 'm', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_VORTEX policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VSOCKETS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VSOCKETS_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VSOCKMON policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VSX policy<{'ppc64el': 'y'}> +CONFIG_VT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VT6655 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VT6656 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_VT_CONSOLE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VT_CONSOLE_SLEEP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_VT_HW_CONSOLE_BINDING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_VXFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_VXGE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_VXGE_DEBUG_TRACE_ALL policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_VXLAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_VZ89X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_W1_CON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_W1_MASTER_DS1WM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_MASTER_DS2482 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_MASTER_DS2490 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_MASTER_GPIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_MASTER_MATROX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_MASTER_MXC policy<{'arm64': 'm', 'armhf-generic': 'm'}> +CONFIG_W1_MASTER_SGI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2405 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2406 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2408 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2408_READBACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_W1_SLAVE_DS2413 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2423 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2431 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2433 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2433_CRC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_W1_SLAVE_DS2438 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS250X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2780 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2781 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS2805 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS28E04 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_DS28E17 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_SMEM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W1_SLAVE_THERM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_W83627HF_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_W83877F_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_W83977F_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WAFER_WDT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WAN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_WANT_DEV_COREDUMP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WANXL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WARN_ALL_UNSEEDED_RANDOM policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_WARN_DYNAMIC_STACK policy<{'s390x': 'n'}> +CONFIG_WATCHDOG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_NOWAYOUT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_WATCHDOG_OPEN_TIMEOUT policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'i386': '0', 'ppc64el': '0', 's390x': '0'}> +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_WATCHDOG_PRETIMEOUT_GOV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_WATCHDOG_RTAS policy<{'ppc64el': 'm'}> +CONFIG_WATCHDOG_SYSFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_WCN36XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WCN36XX_DEBUGFS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_WCN36XX_SNAPDRAGON_HACKS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_WD80x3 policy<{'i386': 'm'}> +CONFIG_WDAT_WDT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_WDT policy<{'i386': 'm'}> +CONFIG_WDTPCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_WEXT_CORE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WEXT_PRIV policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WEXT_PROC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WEXT_SPY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIL6210 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WIL6210_DEBUGFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIL6210_ISR_COR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIL6210_TRACING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WILC1000 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WILC1000_HW_OOB_INTR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WILC1000_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WILC1000_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WILCO_EC policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WILCO_EC_DEBUGFS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WILCO_EC_EVENTS policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WILCO_EC_TELEMETRY policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WILINK_PLATFORM_DATA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIMAX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_WIMAX_DEBUG_LEVEL policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_WIMAX_I2400M policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WIMAX_I2400M_DEBUG_LEVEL policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'i386': '8', 'ppc64el': '8'}> +CONFIG_WIMAX_I2400M_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WINBOND_840 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WINDFARM policy<{'ppc64el': 'm'}> +CONFIG_WIRELESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIRELESS_EXT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIRELESS_WDS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_WIZNET_BUS_ANY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WIZNET_BUS_DIRECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_WIZNET_BUS_INDIRECT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_WIZNET_W5100 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WIZNET_W5100_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WIZNET_W5300 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WKUP_M3_IPC policy<{'armhf-generic': 'n'}> +CONFIG_WKUP_M3_RPROC policy<{'armhf-generic': 'm'}> +CONFIG_WL1251 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WL1251_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WL1251_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WL12XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WL18XX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WLAN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_ADMTEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_ATH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_ATMEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_BROADCOM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_CISCO policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_INTEL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_INTERSIL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_MARVELL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_MEDIATEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_QUANTENNA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_RALINK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_REALTEK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_RSI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_ST policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_TI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLAN_VENDOR_ZYDAS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WLCORE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WLCORE_SDIO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WLCORE_SPI policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_WM831X_BACKUP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WM831X_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WM831X_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WM8350_POWER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WM8350_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_WMI_BMOF policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_WQ_POWER_EFFICIENT_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_WQ_WATCHDOG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_WW_MUTEX_SELFTEST policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_X25 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_X25_ASY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_X86 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_16BIT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_32 policy<{'i386': 'y'}> +CONFIG_X86_32_IRIS policy<{'i386': 'm'}> +CONFIG_X86_32_NON_STANDARD policy<{'i386': 'n'}> +CONFIG_X86_32_SMP policy<{'i386': 'y'}> +CONFIG_X86_5LEVEL policy<{'amd64': 'n'}> +CONFIG_X86_64 policy<{'amd64': 'y'}> +CONFIG_X86_64_ACPI_NUMA policy<{'amd64': 'y'}> +CONFIG_X86_64_SMP policy<{'amd64': 'y'}> +CONFIG_X86_ACPI_CPUFREQ_CPB policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_AMD_FREQ_SENSITIVITY policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_AMD_PLATFORM_DEVICE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_ANCIENT_MCE policy<{'i386': 'n'}> +CONFIG_X86_APM_BOOT policy<{'i386': 'y'}> +CONFIG_X86_BIGSMP policy<{'i386': 'n'}> +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_CHECK_BIOS_CORRUPTION policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_CMOV policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_CMPXCHG64 policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_CPA_STATISTICS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_CPUID policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_CPU_RESCTRL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_DEBUGCTLMSR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_DEBUG_FPU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_DECODER_SELFTEST policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_DEV_DMA_OPS policy<{'amd64': 'y'}> +CONFIG_X86_DIRECT_GBPAGES policy<{'amd64': 'y'}> +CONFIG_X86_ESPFIX32 policy<{'i386': 'y'}> +CONFIG_X86_ESPFIX64 policy<{'amd64': 'y'}> +CONFIG_X86_EXTENDED_PLATFORM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_E_POWERSAVER policy<{'i386': 'n'}> +CONFIG_X86_FEATURE_NAMES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_GENERIC policy<{'i386': 'y'}> +CONFIG_X86_GOLDFISH policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_GX_SUSPMOD policy<{'i386': 'm'}> +CONFIG_X86_HV_CALLBACK_VECTOR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_INTEL_LPSS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS policy<{'amd64': 'y'}> +CONFIG_X86_INTEL_MID policy<{'amd64': 'n', 'i386': 'y'}> +CONFIG_X86_INTEL_MPX policy<{'amd64': 'y'}> +CONFIG_X86_INTEL_PSTATE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_INTEL_QUARK policy<{'i386': 'n'}> +CONFIG_X86_INTEL_TSX_MODE_AUTO policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_INTEL_TSX_MODE_OFF policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_INTEL_TSX_MODE_ON policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_INTEL_UMIP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_INTEL_USERCOPY policy<{'i386': 'y'}> +CONFIG_X86_INTERNODE_CACHE_SHIFT policy<{'amd64': '6', 'i386': '6'}> +CONFIG_X86_IO_APIC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_L1_CACHE_SHIFT policy<{'amd64': '6', 'i386': '6'}> +CONFIG_X86_LOCAL_APIC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_LONGHAUL policy<{'i386': 'm'}> +CONFIG_X86_LONGRUN policy<{'i386': 'm'}> +CONFIG_X86_MCE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MCELOG_LEGACY policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MCE_AMD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MCE_INJECT policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_MCE_INTEL policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MCE_THRESHOLD policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MINIMUM_CPU_FAMILY policy<{'amd64': '64', 'i386': '6'}> +CONFIG_X86_MPPARSE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_MSR policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_NEED_RELOCS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_NUMACHIP policy<{'amd64': 'y'}> +CONFIG_X86_P4_CLOCKMOD policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_PAE policy<{'i386': 'y'}> +CONFIG_X86_PAT policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_PKG_TEMP_THERMAL policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_X86_PLATFORM_DEVICES policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_PMEM_LEGACY policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_PMEM_LEGACY_DEVICE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_PM_TIMER policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_POWERNOW_K6 policy<{'i386': 'm'}> +CONFIG_X86_POWERNOW_K7 policy<{'i386': 'm'}> +CONFIG_X86_POWERNOW_K7_ACPI policy<{'i386': 'y'}> +CONFIG_X86_PTDUMP policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_PTDUMP_CORE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_RDC321X policy<{'i386': 'n'}> +CONFIG_X86_REBOOTFIXUPS policy<{'i386': 'y'}> +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_RESERVE_LOW policy<{'amd64': '64', 'i386': '64'}> +CONFIG_X86_SFI_CPUFREQ policy<{'i386': 'm'}> +CONFIG_X86_SMAP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE policy<{'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_LIB policy<{'amd64': 'm', 'i386': 'y'}> +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK policy<{'i386': 'y'}> +CONFIG_X86_SUPPORTS_MEMORY_FAILURE policy<{'amd64': 'y'}> +CONFIG_X86_SYSFB policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_THERMAL_VECTOR policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_TSC policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_X86_USE_PPRO_CHECKSUM policy<{'i386': 'y'}> +CONFIG_X86_VERBOSE_BOOTUP policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_X86_VSMP policy<{'amd64': 'n'}> +CONFIG_X86_VSYSCALL_EMULATION policy<{'amd64': 'y'}> +CONFIG_X86_X2APIC policy<{'amd64': 'y'}> +CONFIG_X86_X32 policy<{'amd64': 'y'}> +CONFIG_XARRAY_MULTI policy<{'amd64': 'y', 'arm64': 'y', 'armhf-generic-lpae': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XDP_SOCKETS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XDP_SOCKETS_DIAG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XEN policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'i386': 'y'}> +CONFIG_XENFS policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_ACPI policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_AUTO_XLATE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_BACKEND policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_BALLOON policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_BALLOON_MEMORY_HOTPLUG policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_BALLOON_MEMORY_HOTPLUG_LIMIT policy<{'amd64': '512', 'i386': '4'}> +CONFIG_XEN_BLKDEV_BACKEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_COMPAT_XENFS policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_DEBUG_FS policy<{'amd64': 'n', 'i386': 'n'}> +CONFIG_XEN_DEV_EVTCHN policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_DOM0 policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_EFI policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_XEN_FBDEV_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_FRONT_PGDIR_SHBUF policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_GNTDEV policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_GNTDEV_DMABUF policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_GRANT_DEV_ALLOC policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_GRANT_DMA_ALLOC policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_HAVE_PVMMU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_HAVE_VPMU policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_MCE_LOG policy<{'amd64': 'y'}> +CONFIG_XEN_NETDEV_BACKEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_PCIDEV_BACKEND policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_XEN_PCIDEV_FRONTEND policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_XEN_PRIVCMD policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_PV policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_PVCALLS_BACKEND policy<{'amd64': 'n', 'arm64': 'n', 'i386': 'n'}> +CONFIG_XEN_PVCALLS_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_PVH policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_PVHVM policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_PVHVM_SMP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_PV_SMP policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_SAVE_RESTORE policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_SCRUB_PAGES_DEFAULT policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_SCSI_BACKEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_SCSI_FRONTEND policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_SYMS policy<{'amd64': 'y', 'i386': 'y'}> +CONFIG_XEN_SYS_HYPERVISOR policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XEN_WDT policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_XEN_XENBUS_FRONTEND policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_XFRM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFRM_ALGO policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XFRM_INTERFACE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XFRM_IPCOMP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XFRM_MIGRATE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_XFRM_OFFLOAD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFRM_STATISTICS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFRM_SUB_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_XFRM_USER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XFS_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_XFS_FS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XFS_ONLINE_SCRUB policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_XFS_POSIX_ACL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFS_QUOTA policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFS_RT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XFS_WARN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_XGENE_DMA policy<{'arm64': 'm'}> +CONFIG_XGENE_PMU policy<{'arm64': 'y'}> +CONFIG_XGENE_SLIMPRO_MBOX policy<{'arm64': 'm'}> +CONFIG_XIAOMI_WMI policy<{'amd64': 'm', 'i386': 'm'}> +CONFIG_XILINX_AXI_EMAC policy<{'amd64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_XILINX_DMA policy<{'arm64': 'm'}> +CONFIG_XILINX_GMII2RGMII policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XILINX_LL_TEMAC policy<{'amd64': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_XILINX_PR_DECOUPLER policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_XILINX_SDFEC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_XILINX_VCU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XILINX_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_XILINX_XADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_XILINX_ZYNQMP_DMA policy<{'arm64': 'm'}> +CONFIG_XILLYBUS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_XILLYBUS_OF policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_XILLYBUS_PCIE policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_XIL_AXIS_FIFO policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> +CONFIG_XMON policy<{'ppc64el': 'y'}> +CONFIG_XMON_DEFAULT policy<{'ppc64el': 'n'}> +CONFIG_XMON_DEFAULT_RO_MODE policy<{'ppc64el': 'y'}> +CONFIG_XMON_DISASSEMBLY policy<{'ppc64el': 'y'}> +CONFIG_XOR_BLOCKS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_XPS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XXHASH policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_XZ_DEC_ARM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_XZ_DEC_ARMTHUMB policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_XZ_DEC_BCJ policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_XZ_DEC_IA64 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_XZ_DEC_POWERPC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_XZ_DEC_SPARC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_XZ_DEC_TEST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_XZ_DEC_X86 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'n'}> +CONFIG_YAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_YELLOWFIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_YENTA policy<{'amd64': 'm', 'arm64': 'm', 'i386': 'm'}> +CONFIG_YENTA_ENE_TUNE policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_YENTA_O2 policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_YENTA_RICOH policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_YENTA_TI policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_YENTA_TOSHIBA policy<{'amd64': 'y', 'arm64': 'y', 'i386': 'y'}> +CONFIG_Z3FOLD policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ZBOOT_ROM_BSS policy<{'armhf': '0x0'}> +CONFIG_ZBOOT_ROM_TEXT policy<{'armhf': '0x0'}> +CONFIG_ZBUD policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZCRYPT policy<{'s390x': 'm'}> +CONFIG_ZD1211RW policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ZD1211RW_DEBUG policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n'}> +CONFIG_ZEROPLUS_FF policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y'}> +CONFIG_ZFCP policy<{'s390x': 'm'}> +CONFIG_ZIIRAVE_WATCHDOG policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'n'}> +CONFIG_ZISOFS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZLIB_DEFLATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'm'}> +CONFIG_ZLIB_INFLATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZONE_DEVICE policy<{'amd64': 'y', 'ppc64el': 'y'}> +CONFIG_ZONE_DMA32 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ZOPT2201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ZPA2326 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ZPA2326_I2C policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ZPA2326_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm'}> +CONFIG_ZPOOL policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZRAM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ZRAM_MEMORY_TRACKING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZRAM_WRITEBACK policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZSMALLOC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZSMALLOC_STAT policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'i386': 'n', 'ppc64el': 'n', 's390x': 'n'}> +CONFIG_ZSTD_COMPRESS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm', 'ppc64el': 'm', 's390x': 'm'}> +CONFIG_ZSTD_DECOMPRESS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZSWAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> +CONFIG_ZX_TDM policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'i386': 'm'}> +CONFIG_ZYNQMP_FIRMWARE policy<{'arm64': 'y'}> +CONFIG_ZYNQMP_FIRMWARE_DEBUG policy<{'arm64': 'n'}> +CONFIG_ZYNQMP_IPI_MBOX policy<{'arm64': 'y'}> +CONFIG_ZYNQMP_PM_DOMAINS policy<{'arm64': 'y'}> +CONFIG_ZYNQMP_POWER policy<{'arm64': 'y'}> --- linux-oracle-5.4.0.orig/debian.master/control.d/flavour-control.stub +++ linux-oracle-5.4.0/debian.master/control.d/flavour-control.stub @@ -0,0 +1,152 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# This file describes the template for packages that are created for each flavour +# in debian/control.d/vars.* +# +# This file gets edited in a couple of places. See the debian/control.stub rule in +# debian/rules. PGGVER, ABINUM, and SRCPKGNAME are all converted in the +# process of creating debian/control. +# +# The flavour specific strings (ARCH, DESC, etc) are converted using values from the various +# flavour files in debian/control.d/vars.* +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Provides: linux-image, fuse-module, aufs-dkms, =PROVIDES=${linux:rprovides} +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-PKGVER-ABINUM-FLAVOUR +Recommends: BOOTLOADER, initramfs-tools | linux-initramfs-tool +Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] +Conflicts: linux-image=SIGN-PEER-PKG=-PKGVER-ABINUM-FLAVOUR +Suggests: fdutils, linux-doc | SRCPKGNAME-source-PKGVER, SRCPKGNAME-tools, linux-headers-PKGVER-ABINUM-FLAVOUR +Description: Linux kernel image for version PKGVER on DESC + This package contains the=SIGN-ME-TXT= Linux kernel image for version PKGVER on + DESC. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${linux:BuiltUsing} +Description: Linux kernel extra modules for version PKGVER on DESC + Contains the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-extra-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-image-PKGVER-ABINUM-FLAVOUR | linux-image-unsigned-PKGVER-ABINUM-FLAVOUR, crda | wireless-crda +Description: Linux kernel extra modules for version PKGVER on DESC + This package contains the Linux kernel extra modules for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-headers-PKGVER-ABINUM, ${shlibs:Depends} +Provides: linux-headers, linux-headers-3.0 +Description: Linux kernel headers for version PKGVER on DESC + This package provides kernel header files for version PKGVER on + DESC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details. + +Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR-dbgsym +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends} +Provides: linux-debug +Description: Linux kernel debug image for version PKGVER on DESC + This package provides the=SIGN-ME-TXT= kernel debug image for version PKGVER on + DESC. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-tools-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-tools-PKGVER-ABINUM +Description: Linux kernel version specific tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version PKGVER-ABINUM on + =HUMAN=. + +Package: linux-cloud-tools-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-cloud-tools-PKGVER-ABINUM +Description: Linux kernel version specific cloud tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools for cloud for version PKGVER-ABINUM on + =HUMAN=. + +Package: linux-udebs-FLAVOUR +Build-Profiles: +XC-Package-Type: udeb +Section: debian-installer +Architecture: ARCH +Depends: ${udeb:Depends} +Description: Metapackage depending on kernel udebs + This package depends on the all udebs that the kernel build generated, + for easier version and migration tracking. + --- linux-oracle-5.4.0.orig/debian.master/control.d/generic.inclusion-list +++ linux-oracle-5.4.0/debian.master/control.d/generic.inclusion-list @@ -0,0 +1,258 @@ +arch/*/{crypto,kernel,oprofile} +arch/*/kvm/kvm.ko +arch/powerpc/kvm/kvm-hv.ko +arch/powerpc/kvm/kvm-pr.ko +arch/powerpc/kvm/vfio.ko +arch/powerpc/platforms/powernv/opal-prd.ko +arch/s390/* +arch/x86/kvm/kvm-amd.ko +arch/x86/kvm/kvm-intel.ko +crypto/* +drivers/acpi/* +drivers/ata/acard-ahci.ko +drivers/ata/ahci.ko +drivers/ata/ahci_platform.ko +drivers/ata/ata_generic.ko +drivers/ata/libahci.ko +drivers/ata/libahci_platform.ko +drivers/block/brd.ko +drivers/block/cryptoloop.ko +drivers/block/floppy.ko +drivers/block/loop.ko +drivers/block/nbd.ko +drivers/block/rbd.ko +drivers/block/virtio_blk.ko +drivers/block/xen-blkfront.ko +drivers/char/hangcheck-timer.ko +drivers/char/hw_random/powernv-rng.ko +drivers/char/hw_random/virtio-rng.ko +drivers/char/ipmi/* +drivers/char/ipmi/ipmi_msghandler.ko +drivers/char/lp.ko +drivers/char/nvram.ko +drivers/char/ppdev.ko +drivers/char/raw.ko +drivers/char/virtio_console.ko +drivers/crypto/nx/* +drivers/crypto/vmx/vmx-crypto.ko +drivers/firmware/efi/* +drivers/firmware/iscsi_ibft.ko +drivers/gpu/drm/ast/ast.ko +drivers/gpu/drm/bochs/bochs-drm.ko +drivers/gpu/drm/cirrus/cirrus.ko +drivers/gpu/drm/drm_kms_helper.ko +drivers/gpu/drm/drm.ko +drivers/gpu/drm/ttm/ttm.ko +drivers/gpu/drm/vboxvideo/vboxvideo.ko +drivers/gpu/drm/virtio/virtio-gpu.ko +drivers/gpu/drm/vmwgfx/vmwgfx.ko +drivers/gpu/drm/xen/drm_xen_front.ko +drivers/hid/hid-generic.ko +drivers/hid/hid-hyperv.ko +drivers/hid/hid.ko +drivers/hid/usbhid/usbhid.ko +drivers/hv/* +drivers/hwmon/ibmpowernv.ko +drivers/infiniband/core/ib_addr.ko +drivers/infiniband/core/ib_cm.ko +drivers/infiniband/core/ib_core.ko +drivers/infiniband/core/ib_mad.ko +drivers/infiniband/core/ib_sa.ko +drivers/infiniband/core/iw_cm.ko +drivers/infiniband/core/rdma_cm.ko +drivers/infiniband/ulp/iser/ib_iser.ko +drivers/infiniband/ulp/isert/ib_isert.ko +drivers/input/evbug.ko +drivers/input/gameport/gameport.ko +drivers/input/input-leds.ko +drivers/input/joydev.ko +drivers/input/misc/xen-kbdfront.ko +drivers/input/mouse/psmouse.ko +drivers/input/serio/hyperv-keyboard.ko +drivers/input/serio/serio_raw.ko +drivers/input/serio/serport.ko +drivers/input/touchscreen/usbtouchscreen.ko +drivers/leds/leds-powernv.ko +drivers/md/* +drivers/message/fusion* +drivers/misc/cxl/* +drivers/misc/eeprom/at24.ko +drivers/misc/vmw_balloon.ko +drivers/misc/vmw_vmci/vmw_vmci.ko +drivers/mtd/cmdlinepart.ko +drivers/mtd/devices/powernv_flash.ko +drivers/mtd/ofpart.ko +drivers/net/appletalk/ipddp.ko +drivers/net/bonding/bonding.ko +drivers/net/caif/caif_virtio.ko +drivers/net/dummy.ko +drivers/net/eql.ko +drivers/net/ethernet/8390/8390.ko +drivers/net/ethernet/8390/ne2k-pci.ko +drivers/net/ethernet/amazon/ena/ena.ko +drivers/net/ethernet/amd/pcnet32.ko +drivers/net/ethernet/broadcom/bnx2x/* +drivers/net/ethernet/broadcom/tg3.ko +drivers/net/ethernet/dec/tulip/* +drivers/net/ethernet/emulex/benet/* +drivers/net/ethernet/ibm/* +drivers/net/ethernet/intel/e1000/e1000.ko +drivers/net/ethernet/intel/e1000e/e1000e.ko +drivers/net/ethernet/intel/i40e/* +drivers/net/ethernet/intel/iavf/iavf.ko +drivers/net/ethernet/intel/igb/* +drivers/net/ethernet/intel/igbvf/igbvf.ko +drivers/net/ethernet/intel/ixgbe/* +drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko +drivers/net/ethernet/mellanox/* +drivers/net/ethernet/netronome/nfp/nfp.ko +drivers/net/ethernet/realtek/8139cp.ko +drivers/net/ethernet/realtek/8139too.ko +drivers/net/fddi/* +drivers/net/geneve.ko +drivers/net/hyperv/hv_netvsc.ko +drivers/net/ifb.ko +drivers/net/ipvlan/* +drivers/net/macvlan.ko +drivers/net/macvtap.ko +drivers/net/mii.ko +drivers/net/netconsole.ko +drivers/net/ppp/* +drivers/net/ppp/bsd_comp.ko +drivers/net/slip/* +drivers/net/veth.ko +drivers/net/virtio_net.ko +drivers/net/vmxnet3/vmxnet3.ko +drivers/net/vxlan.ko +drivers/net/xen-netback/* +drivers/net/xen-netfront.ko +drivers/nvme/host/nvme.ko +drivers/nvmem/nvmem_core.ko +drivers/parport/parport.ko +drivers/parport/parport_pc.ko +drivers/pci/host/vmd.ko +drivers/platform/x86/pvpanic.ko +drivers/pps/pps_core.ko +drivers/ptp/ptp.ko +drivers/s390/* +drivers/s390/block/xpram.ko +drivers/scsi/aacraid/* +drivers/scsi/BusLogic.ko +drivers/scsi/cxlflash/* +drivers/scsi/device_handler/scsi_dh_alua.ko +drivers/scsi/device_handler/scsi_dh_emc.ko +drivers/scsi/device_handler/scsi_dh_hp_sw.ko +drivers/scsi/device_handler/scsi_dh_rdac.ko +drivers/scsi/hv_storvsc.ko +drivers/scsi/ibmvscsi/* +drivers/scsi/ipr.ko +drivers/scsi/iscsi_boot_sysfs.ko +drivers/scsi/iscsi_tcp.ko +drivers/scsi/libiscsi.ko +drivers/scsi/libiscsi_tcp.ko +drivers/scsi/libsas/* +drivers/scsi/lpfc/* +drivers/scsi/megaraid/* +drivers/scsi/mpt3sas/* +drivers/scsi/osd/libosd.ko +drivers/scsi/osd/osd.ko +drivers/scsi/qla1280.ko +drivers/scsi/qla2xxx/* +drivers/scsi/raid_class.ko +drivers/scsi/scsi_transport_fc.ko +drivers/scsi/scsi_transport_iscsi.ko +drivers/scsi/scsi_transport_sas.ko +drivers/scsi/scsi_transport_spi.ko +drivers/scsi/sd_mod.ko +drivers/scsi/sr_mod.ko +drivers/scsi/virtio_scsi.ko +drivers/scsi/vmw_pvscsi.ko +drivers/target/target_core*.ko +drivers/target/loopback/tcm_loop.ko +drivers/tty/serial/jsm/* +drivers/uio/uio.ko +drivers/uio/uio_pdrv_genirq.ko +drivers/usb/host/* +drivers/usb/storage/uas.ko +drivers/usb/storage/usb-storage.ko +drivers/vfio/* +drivers/vhost/* +drivers/video/fbdev/* +drivers/video/vgastate.ko +drivers/virtio/* +drivers/watchdog/softdog.ko +drivers/xen/* +! find sound/core -name oss -prune -o -name *.ko -print +fs/9p/* +fs/aufs/aufs.ko +fs/autofs/autofs4.ko +fs/binfmt_misc.ko +fs/btrfs/* +fs/cachefiles/cachefiles.ko +fs/ceph/* +fs/cifs/* +fs/configfs/* +fs/dlm/dlm.ko +fs/ecryptfs/* +fs/efivarfs/* +fs/exofs/libore.ko +fs/ext4/* +fs/fat/* +fs/fscache/* +fs/fuse/* +fs/isofs/* +fs/lockd/* +fs/nfs/* +fs/nfs_common/* +fs/nfsd/* +fs/nls/nls_cp437.ko +fs/nls/nls_iso8859-1.ko +fs/overlayfs/* +fs/shiftfs.ko +fs/squashfs/* +fs/udf/* +fs/ufs/* +fs/xfs/* +lib/* +net/6lowpan/* +net/802/* +net/8021q/* +net/9p/* +net/appletalk/* +net/atm/* +net/ax25/* +net/bpfilter/* +net/bridge/* +net/can/* +net/ceph/libceph.ko +net/core/* +net/dccp/* +net/decnet/* +net/ieee802154/* +net/ipv4/* +net/ipv6/* +net/ipx/* +net/key/* +net/lapb/* +net/llc/* +net/netfilter/* +net/netlink/netlink_diag.ko +net/netrom/* +net/openvswitch/* +net/packet/af_packet_diag.ko +net/phonet/* +net/rose/* +net/rxrpc/* +net/sched/* +net/sctp/* +net/sunrpc/auth_gss/auth_rpcgss.ko +net/sunrpc/auth_gss/rpcsec_gss_krb5.ko +net/sunrpc/sunrpc.ko +net/tipc/* +net/unix/unix_diag.ko +net/vmw_vsock/* +net/x25/* +net/xfrm/* +sound/drivers/pcsp/snd-pcsp.ko +sound/pci/snd-ens1370.ko +sound/soundcore.ko --- linux-oracle-5.4.0.orig/debian.master/control.d/linux-doc.stub +++ linux-oracle-5.4.0/debian.master/control.d/linux-doc.stub @@ -0,0 +1,12 @@ +Package: linux-doc +Build-Profiles: +Architecture: all +Section: doc +Priority: optional +Depends: ${misc:Depends} +Description: Linux kernel specific documentation for version PKGVER + This package provides the various documents in the PKGVER kernel + Documentation/ subdirectory. These document kernel subsystems, APIs, device + drivers, and so on. See + /usr/share/doc/SRCPKGNAME-doc/00-INDEX for a list of what is + contained in each file. --- linux-oracle-5.4.0.orig/debian.master/control.d/linux-libc-dev.stub +++ linux-oracle-5.4.0/debian.master/control.d/linux-libc-dev.stub @@ -0,0 +1,12 @@ +Package: linux-libc-dev +Architecture: amd64 armhf arm64 i386 ppc64el riscv64 s390x +Depends: ${misc:Depends} +Conflicts: linux-kernel-headers +Replaces: linux-kernel-headers +Provides: linux-kernel-headers, aufs-dev +Multi-Arch: same +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. They are NOT meant to be used to build third-party modules for + your kernel. Use SRCPKGNAME-headers-* packages for that. --- linux-oracle-5.4.0.orig/debian.master/control.d/vars.generic +++ linux-oracle-5.4.0/debian.master/control.d/vars.generic @@ -0,0 +1,6 @@ +arch="amd64 armhf arm64 ppc64el s390x" +supported="Generic" +target="Geared toward desktop and server systems." +desc="=HUMAN= SMP" +bootloader="grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf] | grub-ieee1275 [ppc64el]" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64]" --- linux-oracle-5.4.0.orig/debian.master/control.d/vars.generic-lpae +++ linux-oracle-5.4.0/debian.master/control.d/vars.generic-lpae @@ -0,0 +1,6 @@ +arch="armhf" +supported="Generic LPAE" +target="Geared toward desktop and server systems." +desc="=HUMAN= SMP" +bootloader="flash-kernel [armhf] | grub-efi-arm [armhf]" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules" --- linux-oracle-5.4.0.orig/debian.master/control.d/vars.lowlatency +++ linux-oracle-5.4.0/debian.master/control.d/vars.lowlatency @@ -0,0 +1,6 @@ +arch="amd64" +supported="Lowlatency" +target="Geared toward desktop and server systems." +desc="=HUMAN= SMP" +bootloader="grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf]" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64]" --- linux-oracle-5.4.0.orig/debian.master/control.stub.in +++ linux-oracle-5.4.0/debian.master/control.stub.in @@ -0,0 +1,156 @@ +Source: SRCPKGNAME +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.9.4.0 +Build-Depends: + autoconf , + automake , + bc , + bison , + cpio, + curl , + debhelper (>= 9), + default-jdk-headless , + dh-systemd, + dkms , + dwarfdump , + dwarves [amd64 arm64 armhf ppc64el s390x] , + flex , + gawk , + java-common , + kernel-wedge, + kmod , + libaudit-dev , + libcap-dev , + libdw-dev , + libelf-dev , + libiberty-dev , + liblzma-dev , + libnewt-dev , + libnuma-dev [amd64 arm64 ppc64el s390x] , + libpci-dev , + libssl-dev , + libtool , + libudev-dev , + libunwind8-dev [amd64 arm64 armhf ppc64el] , + lz4 [amd64 s390x] , + makedumpfile [amd64] , + openssl , + pkg-config , + rsync , + uuid-dev , +Build-Depends-Indep: + asciidoc , + bzip2 , + docbook-utils , + fig2dev , + fontconfig , + ghostscript , + python3-docutils , + python3-sphinx , + python3-sphinx-rtd-theme , + sharutils , + xmlto , +Vcs-Git: git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/=SERIES= +XS-Testsuite: autopkgtest +#XS-Testsuite-Depends: gcc-4.7 binutils + +Package: linux-source-PKGVER +Build-Profiles: +Architecture: all +Section: devel +Priority: optional +Provides: linux-source +Depends: ${misc:Depends}, binutils, bzip2, coreutils +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version PKGVER with Ubuntu patches + This package provides the source code for the Linux kernel version + PKGVER. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: SRCPKGNAME-headers-PKGVER-ABINUM +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: devel +Priority: optional +Depends: ${misc:Depends}, coreutils +Description: Header files related to Linux kernel version PKGVER + This package provides kernel header files for version PKGVER, for sites + that want the latest kernel headers. Please read + /usr/share/doc/SRCPKGNAME-headers-PKGVER-ABINUM/debian.README.gz for details + +Package: SRCPKGNAME-tools-common +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: kernel +Priority: optional +Depends: ${misc:Depends}, lsb-release +Conflicts: linux-oem-5.6-tools-common +Replaces: linux-oem-5.6-tools-common +Description: Linux kernel version specific tools for version PKGVER + This package provides the architecture independent parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version PKGVER. + +Package: SRCPKGNAME-tools-PKGVER-ABINUM +Build-Profiles: +Architecture: amd64 armhf arm64 ppc64el s390x +Section: devel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common +Description: Linux kernel version specific tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version PKGVER-ABINUM on + =HUMAN=. + You probably want to install linux-tools-PKGVER-ABINUM-. + +Package: SRCPKGNAME-cloud-tools-common +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: kernel +Priority: optional +Depends: ${misc:Depends} +Description: Linux kernel version specific cloud tools for version PKGVER + This package provides the architecture independent parts for kernel + version locked tools for cloud tools for version PKGVER. + +Package: SRCPKGNAME-cloud-tools-PKGVER-ABINUM +Build-Profiles: +Architecture: amd64 armhf +Section: devel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-cloud-tools-common +Description: Linux kernel version specific cloud tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools for cloud tools for version PKGVER-ABINUM on + =HUMAN=. + You probably want to install linux-cloud-tools-PKGVER-ABINUM-. + +Package: SRCPKGNAME-tools-host +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: kernel +Priority: optional +Depends: ${misc:Depends}, python3 +Conflicts: linux-oem-5.6-tools-host +Replaces: linux-oem-5.6-tools-host +Description: Linux kernel VM host tools + This package provides kernel tools useful for VM hosts. + --- linux-oracle-5.4.0.orig/debian.master/copyright +++ linux-oracle-5.4.0/debian.master/copyright @@ -0,0 +1,29 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/amd64/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/amd64/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/amd64/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/amd64/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/amd64/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/amd64/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/arm64/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/arm64/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/arm64/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/arm64/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/arm64/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/arm64/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/armhf/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/armhf/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/i386/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/i386/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/i386/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/i386/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/i386/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/i386/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/nic-modules @@ -0,0 +1,14 @@ +e100/d101m_ucode.bin ? +e100/d101s_ucode.bin ? +e100/d102e_ucode.bin ? +bnx2/bnx2-mips-09-6.2.1b.fw ? +bnx2/bnx2-rv2p-06-6.0.15.fw ? +bnx2/bnx2-mips-06-6.2.3.fw ? +bnx2/bnx2-rv2p-09-6.0.17.fw ? +bnx2/bnx2-rv2p-09ax-6.0.17.fw ? +bnx2x/bnx2x-e1h-7.12.30.0.fw ? +bnx2x/bnx2x-e1-7.12.30.0.fw ? +bnx2x/bnx2x-e2-7.12.30.0.fw ? +tigon/tg3_tso5.bin ? +tigon/tg3_tso.bin ? +tigon/tg3.bin ? --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/powerpc/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/powerpc/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/powerpc/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/powerpc/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/powerpc/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/powerpc/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/ppc64el/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/ppc64el/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/ppc64el/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/ppc64el/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/ppc64el/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/ppc64el/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/s390x/README.txt +++ linux-oracle-5.4.0/debian.master/d-i/firmware/s390x/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/s390x/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/s390x/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/s390x/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/s390x/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/firmware/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/firmware/scsi-modules @@ -0,0 +1,3 @@ +qlogic/1040.bin ? +qlogic/12160.bin ? +qlogic/1280.bin ? --- linux-oracle-5.4.0.orig/debian.master/d-i/kernel-versions +++ linux-oracle-5.4.0/debian.master/d-i/kernel-versions @@ -0,0 +1,16 @@ +# arch version flavour installedname suffix bdep +amd64 - generic - - - + +i386 - generic - - - + +armhf - generic - - - +armhf - generic-lpae - - - + +arm64 - generic - - - + +ppc64el - generic - - - + +s390x - generic - - - + +# Ports +# arch version flavour installedname suffix bdep --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/fb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/fb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/floppy-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/serial-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/serial-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64-virtual/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64-virtual/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/fb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/fb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/firewire-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/firewire-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/floppy-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/input-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/ipmi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/nic-pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/nic-pcmcia-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/nic-usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/pata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/pata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/pcmcia-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/pcmcia-storage-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/pcmcia-storage-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/plip-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/ppp-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/sata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/serial-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/serial-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/speakup-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/speakup-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/amd64/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/amd64/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/input-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/ipmi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/nic-usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/plip-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/ppp-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/sata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/speakup-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/speakup-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/arm64/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/arm64/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/input-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/ipmi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/nic-usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/plip-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/ppp-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/sata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/speakup-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/speakup-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/armhf/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/armhf/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/block-modules @@ -0,0 +1,43 @@ +aoe ? +aten ? +bcm2835 ? +bpck ? +bpck6 ? +cciss ? +comm ? +cpqarray ? +DAC960 ? +dstr ? +epat ? +epia ? +fit2 ? +fit3 ? +friq ? +frpw ? +hpsa ? +hio ? +kbic ? +ktti ? +nbd ? +nvme ? +on20 ? +on26 ? +paride ? +pcd ? +pd ? +pf ? +pg ? +pt ? +sdhci-tegra ? +sx8 ? +umem ? +virtio_blk ? +xen-blkfront ? +mtip32xx ? +mmc_block ? +sdhci ? +sdhci-pci ? +sdhci-acpi ? +tifm_sd ? +dw_mmc ? +dw_mmc_pltfm ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/block-modules.powerpc +++ linux-oracle-5.4.0/debian.master/d-i/modules/block-modules.powerpc @@ -0,0 +1,31 @@ +aoe ? +aten ? +bpck ? +bpck6 ? +cciss ? +comm ? +cpqarray ? +DAC960 ? +dstr ? +epat ? +epia ? +fit2 ? +fit3 ? +friq ? +frpw ? +kbic ? +ktti ? +nbd ? +on20 ? +on26 ? +paride ? +pcd ? +pd ? +pf ? +pg ? +ps3disk ? +ps3vram ? +pt ? +sx8 ? +umem ? +virtio_blk ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/crypto-modules @@ -0,0 +1,78 @@ +aesni-intel ? +aes-x86_64 ? +af_alg ? +algif_hash ? +algif_skcipher ? +ansi_cprng ? +anubis ? +arc4 ? +async_memcpy ? +async_pq ? +async_raid6_recov ? +async_tx ? +async_xor ? +authenc ? +authencesn ? +blowfish_common ? +blowfish_generic ? +blowfish-x86_64 ? +camellia ? +cast5 ? +cast6 ? +ccm ? +crc32_generic ? +crc32c_generic ? +crc32-vx_s390 ? +cryptd ? +cryptoloop ? +crypto_null ? +crypto_user ? +ctr ? +cts ? +des_generic ? +fcrypt ? +gcm ? +gf128mul ? +ghash-clmulni-intel ? +ghash-generic ? +khazad ? +lrw ? +lzo ? +md4 ? +michael_mic ? +padlock-aes ? +padlock-sha ? +paes_s390 ? +pcbc ? +pcrypt ? +pkey ? +raid6test ? +rmd128 ? +rmd160 ? +rmd256 ? +rmd320 ? +salsa20_generic ? +salsa20-x86_64 ? +seed ? +seqiv ? +serpent_generic ? +serpent-sse2-x86_64 ? +sha1-ssse3 ? +sha512_generic ? +tcrypt ? +tea ? +tgr192 ? +twofish_common ? +twofish_generic ? +twofish-x86_64 ? +twofish-x86_64-3way ? +vmac ? +wp512 ? +xcbc ? +xor ? +xts ? +zcrypt ? +zcrypt_cex2a ? +zcrypt_cex4 ? +zcrypt_pcixcc ? +zlib ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/dasd-extra-modules.s390x +++ linux-oracle-5.4.0/debian.master/d-i/modules/dasd-extra-modules.s390x @@ -0,0 +1 @@ +dasd_diag_mod ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/dasd-modules.s390x +++ linux-oracle-5.4.0/debian.master/d-i/modules/dasd-modules.s390x @@ -0,0 +1,3 @@ +dasd_mod ? +dasd_fba_mod ? +dasd_eckd_mod ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/fat-modules @@ -0,0 +1,7 @@ +fat ? +vfat ? + +# Supporting modules ? +nls_cp437 ? +nls_iso8859-1 ? +nls_utf8 ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/fb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/fb-modules @@ -0,0 +1,3 @@ +fbcon ? +vesafb ? +vga16fb ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/firewire-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/firewire-core-modules @@ -0,0 +1,4 @@ +firewire-core ? +firewire-ohci ? +firewire-sbp2 ? +firewire-net ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/floppy-modules @@ -0,0 +1 @@ +floppy ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/fs-core-modules @@ -0,0 +1,6 @@ +ext2 ? +ext4 ? +jfs ? +reiserfs ? +xfs ? +zfs ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/fs-secondary-modules @@ -0,0 +1,5 @@ +btrfs ? +fuse ? +ntfs ? +hfs ? +hfsplus ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/fb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/fb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/floppy-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/serial-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/serial-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386-virtual/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386-virtual/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/fb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/fb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/firewire-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/firewire-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/floppy-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/input-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/ipmi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/mouse-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/nic-pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/nic-pcmcia-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/nic-usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/pata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/pata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/pcmcia-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/pcmcia-storage-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/pcmcia-storage-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/plip-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/ppp-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/sata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/serial-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/serial-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/speakup-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/speakup-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/i386/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/i386/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/input-modules @@ -0,0 +1,71 @@ +hid ? +hid-a4tech ? +hid-apple ? +hid-appleir ? +hid-aureal ? +hid-belkin ? +hid-bright ? +hid-cherry ? +hid-chicony ? +hid-corsair ? +hid-cp2112 ? +hid-cypress ? +hid-dell ? +hid-elecom ? +hid-elo ? +hid-ezkey ? +hid-generic ? +hid-gfrm ? +hid-gt683r ? +hid-gyration ? +hid-holtek-kbd ? +hid-holtek-mouse ? +hid-hyperv ? +hid-kensington ? +hid-keytouch ? +hid-kye ? +hid-lcpower ? +hid-lenovo ? +hid-logitech ? +hid-logitech-dj ? +hid-logitech-hidpp ? +hid-magicmouse ? +hid-microsoft ? +hid-monterey ? +hid-multitouch ? +hid-ntrig ? +hid-ortek ? +hid-penmount ? +hid-petalynx ? +hid-picolcd ? +hid-pl ? +hid-plantronics ? +hid-primax ? +hid-rmi ? +hid-roccat ? +hid-roccat-arvo ? +hid-roccat-common ? +hid-roccat-isku ? +hid-roccat-kone ? +hid-roccat-koneplus ? +hid-roccat-konepure ? +hid-roccat-kovaplus ? +hid-roccat-lua ? +hid-roccat-pyra ? +hid-roccat-ryos ? +hid-roccat-savu ? +hid-samsung ? +hid-sony ? +hid-speedlink ? +hid-sunplus ? +hid-thingm ? +hid-tivo ? +hid-topseed ? +hid-twinhan ? +hid-uclogic ? +hid-waltop ? +hid-wiimote ? +hid-xinmo ? +hid-zydacron ? +uhid ? +usbhid ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ipmi-modules @@ -0,0 +1,5 @@ +ipmi_devintf ? +ipmi_msghandler ? +ipmi_poweroff ? +ipmi_si ? +ipmi_watchdog ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/kernel-image @@ -0,0 +1,31 @@ +ast ? +gpio-pca953x ? +gpio-regulator ? +hibmc-drm ? +i2c-mux ? +i2c-mux-pinctrl ? +i2c-tegra ? +max8907 ? +max8907-regulator ? +nvec ? +nvec_kbd ? +nvec_paz00 ? +nvec_power ? +nvec_ps2 ? +palmas-regulator ? +rtc-em3027 ? +rtc-max8907 ? +rtc-palmas ? +rtc-tps6586x ? +rtc-tps65910 ? +tps51632-regulator ? +tps62360-regulator ? +tps65090-charger ? +tps65090-regulator ? +tps6586x-regulator ? +tps65910-regulator ? +host1x ? +tegra-drm ? +pwm_bl ? +pwm-tegra ? +panel-simple ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/md-modules @@ -0,0 +1,16 @@ +dm-crypt ? +dm-mirror ? +dm-raid ? +dm-snapshot ? +dm-zero ? +faulty ? +linear ? +multipath ? +raid0 ? +raid1 ? +raid10 ? +raid456 ? + +# Extras +dm-raid45 ? +dm-loop ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/message-modules @@ -0,0 +1,9 @@ +mptbase ? +mptctl ? +mptfc ? +mptlan ? +mptsas ? +mpt2sas ? +mpt3sas ? +mptscsih ? +mptspi ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/message-modules.powerpc +++ linux-oracle-5.4.0/debian.master/d-i/modules/message-modules.powerpc @@ -0,0 +1,7 @@ +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/mouse-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/mouse-modules @@ -0,0 +1,2 @@ +psmouse ? +usbmouse ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/multipath-modules @@ -0,0 +1,4 @@ +dm-multipath ? +dm-round-robin ? +dm-service-time ? +dm-queue-length ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/nfs-modules @@ -0,0 +1,6 @@ +nfs ? +nfs_acl ? +nfsv3 ? +lockd ? +sunrpc ? +cifs ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/nic-modules @@ -0,0 +1,209 @@ +3c359 ? +3c501 ? +3c503 ? +3c505 ? +3c507 ? +3c509 ? +3c515 ? +3c523 ? +3c527 ? +3c59x ? +8139cp ? +8139too ? +82596 ? +abyss ? +ac3200 ? +adm8211 ? +airo ? +airport ? +alx ? +amd8111e ? +amd-xgbe ? +aquantia ? +arcnet ? +arc-rawmode ? +arc-rimi ? +arlan ? +at1700 ? +ath5k ? +ath9k ? +ath9k_htc ? +atl1 ? +atl1c ? +atl1e ? +atl2 ? +atmel ? +atmel_pci ? +b44 ? +bcm87xx ? +be2net ? +bmac ? +bnx2 ? +bnx2x ? +bnxt_en ? +bonding ? +brcmfmac ? +brcmsmac ? +broadcom ? +xgmac ? +cassini ? +ccwgroup ? +com20020 ? +com20020-pci ? +com90io ? +com90xx ? +cs89x0 ? +ctcm ? +cxgb4 ? +de2104x ? +de4x5 ? +de600 ? +de620 ? +defxx ? +depca ? +dl2k ? +dmfe ? +dummy ? +e100 ? +e1000 ? +e1000e ? +e2100 ? +eepro ? +eepro100 ? +eexpress ? +enic ? +epic100 ? +eql ? +es3210 ? +eth16i ? +ewrk3 ? +fealnx ? +forcedeth ? +fsm ? +ibmveth ? +ibmvnic ? +igb ? +ps3_gelic ? +hamachi ? +hclge ? +hermes ? +hfi1 ? +hinic ? +hns_dsaf ? +hns_enet_drv ? +hns_mdio ? +hns3 ? +hp ? +hp100 ? +hp-plus ? +i40e ? +i40evf ? +ibmtr ? +ipddp ? +ipw2100 ? +ipw2200 ? +iwl3945 ? +iwl4965 ? +iwl-legacy ? +iwldvm ? +iwlmvm ? +iwlwifi ? +ixgb ? +ixgbe ? +lance ? +lanstreamer ? +lcs ? +lasi_82596 ? +lne390 ? +lp486e ? +mace ? +marvell ? +mdio-thunder ? +mlx4_core ? +mlx4_en ? +mlx5_core ? +mv643xx_eth ? +myri_sbus ? +natsemi ? +ne ? +ne2 ? +ne2k-pci ? +ne3210 ? +netconsole ? +netiucv ? +netsec ? +netxen_nic ? +ni5010 ? +ni52 ? +ni65 ? +nicpf ? +nicvf ? +niu ? +ns83820 ? +olympic ? +orinoco ? +orinoco_pci ? +orinoco_plx ? +orinoco_tmd ? +pcnet32 ? +qcom-emac ? +qede ? +qeth ? +qeth_l2 ? +qeth_l3 ? +qlcnic ? +r815x ? +r8169 ? +rate_control ? +realtek ? +rfc1051 ? +rfc1201 ? +rrunner ? +rt2400 ? +rt2400pci ? +rt2500 ? +rt2500pci ? +rt2800pci ? +rt61pci ? +s2io ? +sfc ? +shaper ? +sis190 ? +sis900 ? +spidernet ? +skfp ? +skge ? +sk98lin ? +sky2 ? +smc9194 ? +smc-ultra ? +smc-ultra32 ? +starfire ? +strip ? +sunbmac ? +sundance ? +sungem ? +sungem_phy ? +sunhme ? +sunlance ? +sunqe ? +sunvnet ? +tg3 ? +tlan ? +tms380tr ? +tmspci ? +tulip ? +tun ? +typhoon ? +uli526x ? +via-rhine ? +via-velocity ? +virtio_net ? +wavelan ? +wd ? +winbond-840 ? +yellowfin ? +znet ? +vmxnet3 ? +xen-netfront ? +xgene-enet ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nic-modules.powerpc +++ linux-oracle-5.4.0/debian.master/d-i/modules/nic-modules.powerpc @@ -0,0 +1,152 @@ +3c359 ? +3c501 ? +3c503 ? +3c505 ? +3c507 ? +3c509 ? +3c515 ? +3c523 ? +3c527 ? +3c59x ? +8139cp ? +8139too ? +82596 ? +abyss ? +ac3200 ? +adm8211 ? +airo ? +airport ? +amd8111e ? +arc4 ? +arcnet ? +arc-rawmode ? +arc-rimi ? +arlan ? +at1700 ? +atl1 ? +atl1e ? +atl2 ? +atmel ? +atmel_pci ? +b44 ? +bcm43xx ? +bcm43xx-mac80211 ? +bmac ? +bnx2 ? +bnx2x ? +bonding ? +cassini ? +com20020 ? +com20020-pci ? +com90io ? +com90xx ? +cs89x0 ? +de2104x ? +de4x5 ? +de600 ? +de620 ? +defxx ? +depca ? +dl2k ? +dmfe ? +dummy ? +e100 ? +e1000 ? +e1000e ? +e2100 ? +eepro ? +eepro100 ? +eexpress ? +epic100 ? +eql ? +es3210 ? +eth16i ? +ewrk3 ? +fealnx ? +forcedeth ? +igb ? +hamachi ? +hermes ? +hp ? +hp100 ? +hp-plus ? +ibmtr ? +ibmveth ? +ipddp ? +ipw2100 ? +ipw2200 ? +ipw3945 ? +ixgb ? +lance ? +lanstreamer ? +lasi_82596 ? +lne390 ? +lp486e ? +mace ? +mv643xx_eth ? +myri_sbus ? +natsemi ? +ne ? +ne2 ? +ne2k-pci ? +ne3210 ? +netconsole ? +netxen_nic ? +ni5010 ? +ni52 ? +ni65 ? +niu ? +ns83820 ? +olympic ? +orinoco ? +orinoco_pci ? +orinoco_plx ? +orinoco_tmd ? +pcnet32 ? +ps3_gelic ? +r8169 ? +rate_control ? +rfc1051 ? +rfc1201 ? +rrunner ? +rt2400 ? +rt2500 ? +rt61pci ? +s2io ? +shaper ? +sis190 ? +sis900 ? +spidernet ? +skfp ? +skge ? +sk98lin ? +sky2 ? +smc9194 ? +smc-ultra ? +smc-ultra32 ? +starfire ? +strip ? +sunbmac ? +sundance ? +sungem ? +sungem_phy ? +sunhme ? +sunlance ? +sunqe ? +sunvnet ? +tg3 ? +tlan ? +tms380tr ? +tmspci ? +tulip ? +tun ? +typhoon ? +uli526x ? +via-rhine ? +via-velocity ? +virtio_net ? +wavelan ? +wd ? +winbond-840 ? +yellowfin ? +znet ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nic-pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/nic-pcmcia-modules @@ -0,0 +1,19 @@ +3c574_cs ? +3c589_cs ? +airo_cs ? +atmel_cs ? +axnet_cs ? +com20020_cs ? +fmvj18x_cs ? +ibmtr_cs ? +netwave_cs ? +nmclan_cs ? +orinoco_cs ? +pcnet_cs ? +ray_cs ? +smc91c92_cs ? +wavelan_cs ? +wl3501_cs ? +xirc2ps_cs ? +xircom_cb ? +xircom_tulip_cb ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/nic-shared-modules @@ -0,0 +1,26 @@ +# PHY +8390 ? +mii ? + +# CRC modules +crc-ccitt ? +crc-itu-t ? +libcrc32c ? + +# mac80211 stuff +mac80211 ? +cfg80211 ? + +# rt2x00 lib (since rt2x00 is split across usb/pci/cb +rt2x00lib ? +rt2800lib ? + +# Atheros library (since drivers are split across nic-modules/nic-usb-modules) +ath ? + +# Wireless 802.11 modules +lib80211 ? +cfg80211 ? +lib80211_crypt_ccmp ? +lib80211_crypt_tkip ? +lib80211_crypt_wep ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/nic-usb-modules @@ -0,0 +1,34 @@ +ax88179_178a ? +catc ? +kaweth ? +pegasus ? +prism2_usb ? +rtl8150 ? +usbnet ? +zd1211rw ? +zd1201 ? +rt2500usb ? +rt73usb ? +rt2570 ? +rt2800usb ? +rt2x00usb ? +cdc_ether ? +asix ? +cdc_eem ? +cdc_ether ? +cdc-phonet ? +cdc_subset ? +dm9601 ? +gl620a ? +hso ? +int51x1 ? +mcs7830 ? +net1080 ? +plusb ? +rndis_host ? +r8152 ? +smsc95xx ? +zaurus ? +carl9170 ? +smsc75xx ? +smsc95xx ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/parport-modules @@ -0,0 +1,2 @@ +parport ? +parport_pc ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/pata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/pata-modules @@ -0,0 +1,47 @@ +pata_ali.ko ? +pata_amd.ko ? +pata_artop.ko ? +pata_atiixp.ko ? +pata_atp867x.ko ? +pata_cmd640.ko ? +pata_cmd64x.ko ? +pata_cs5520.ko ? +pata_cs5530.ko ? +pata_cs5535.ko ? +pata_cs5536.ko ? +pata_cypress.ko ? +pata_efar.ko ? +pata_hpt366.ko ? +pata_hpt37x.ko ? +pata_hpt3x2n.ko ? +pata_hpt3x3.ko ? +pata_isapnp.ko ? +pata_it8213.ko ? +pata_it821x.ko ? +pata_jmicron.ko ? +pata_legacy.ko ? +pata_macio.ko ? +pata_marvell.ko ? +pata_mpiix.ko ? +pata_netcell.ko ? +pata_ninja32.ko ? +pata_ns87410.ko ? +pata_ns87415.ko ? +pata_oldpiix.ko ? +pata_optidma.ko ? +pata_opti.ko ? +pata_pcmcia.ko ? +pata_pdc2027x.ko ? +pata_pdc202xx_old.ko ? +pata_qdi.ko ? +pata_radisys.ko ? +pata_rdc.ko ? +pata_rz1000.ko ? +pata_sc1200.ko ? +pata_sch.ko ? +pata_serverworks.ko ? +pata_sil680.ko ? +pata_sl82c105.ko ? +pata_triflex.ko ? +pata_via.ko ? +pata_winbond.ko ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/pcmcia-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/pcmcia-modules @@ -0,0 +1,8 @@ +i82092 ? +i82365 ? +pcmcia ? +pcmcia_core ? +pd6729 ? +rsrc_nonstatic ? +tcic ? +yenta_socket ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/pcmcia-storage-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/pcmcia-storage-modules @@ -0,0 +1,6 @@ +pata_pcmcia ? +qlogic_cs ? +fdomain_cs ? +aha152x_cs ? +nsp_cs ? +sym53c500_cs ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/plip-modules @@ -0,0 +1 @@ +plip ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/crypto-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/floppy-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/floppy-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/input-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/input-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/ipmi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/ipmi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/message-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/message-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/nic-usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/nic-usb-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/parport-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/parport-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/plip-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/plip-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/ppp-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/sata-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/scsi-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/storage-core-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppc64el/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppc64el/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/ppp-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/ppp-modules @@ -0,0 +1,6 @@ +ppp_async ? +ppp_deflate ? +ppp_mppe ? +pppoe ? +pppox ? +ppp_synctty ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/block-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/block-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/crypto-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/crypto-modules @@ -0,0 +1,2 @@ +#include +deflate ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/dasd-extra-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/dasd-extra-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/dasd-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/dasd-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/fat-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/fat-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/fs-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/fs-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/fs-secondary-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/fs-secondary-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/kernel-image +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/kernel-image @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/md-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/md-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/multipath-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/multipath-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/nfs-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/nfs-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/nic-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/nic-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/nic-shared-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/nic-shared-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/scsi-modules @@ -0,0 +1,2 @@ +#include +ipr ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/storage-core-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/virtio-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/s390x/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/s390x/vlan-modules @@ -0,0 +1 @@ +#include --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/sata-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/sata-modules @@ -0,0 +1,18 @@ +sata_inic162x.ko ? +sata_mv.ko ? +sata_nv.ko ? +sata_promise.ko ? +sata_qstor.ko ? +sata_sil24.ko ? +sata_sil.ko ? +sata_sis.ko ? +sata_svw.ko ? +sata_sx4.ko ? +sata_uli.ko ? +sata_via.ko ? +sata_vsc.ko ? +ahci_platform ? +ahci ? +acard-ahci ? +libahci ? +ahci_xgene ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/scsi-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/scsi-modules @@ -0,0 +1,137 @@ +# SCSI +raid_class ? +scsi_transport_spi ? +scsi_transport_fc ? +scsi_transport_iscsi ? +scsi_transport_sas ? +sr_mod ? +iscsi_tcp ? +libiscsi ? +amiga7xx ? +a3000 ? +a2091 ? +gvp11 ? +mvme147 ? +sgiwd93 ? +cyberstorm ? +cyberstormII ? +blz2060 ? +blz1230 ? +fastlane ? +oktagon_esp_mod ? +atari_scsi ? +mac_scsi ? +mac_esp ? +sun3_scsi ? +mvme16x ? +bvme6000 ? +sim710 ? +advansys ? +pm80xx ? +psi240i ? +BusLogic ? +dpt_i2o ? +u14-34f ? +ultrastor ? +aha152x ? +aha1542 ? +aha1740 ? +aic7xxx_old ? +ips ? +fd_mcs ? +fdomain ? +fnic ? +in2000 ? +g_NCR5380 ? +g_NCR5380_mmio ? +NCR53c406a ? +NCR_D700 ? +NCR_Q720_mod ? +sym53c416 ? +qlogicfas408 ? +qla1280 ? +pas16 ? +seagate ? +seagate ? +t128 ? +dmx3191d ? +dtc ? +zalon7xx ? +eata_pio ? +wd7000 ? +mca_53c9x ? +ibmmca ? +eata ? +dc395x ? +tmscsim ? +megaraid ? +atp870u ? +esp ? +gdth ? +initio ? +a100u2w ? +qlogicpti ? +ide-scsi ? +mesh ? +mac53c94 ? +pluto ? +dec_esp ? +3w-xxxx ? +3w-9xxx ? +ppa ? +imm ? +jazz_esp ? +sun3x_esp ? +fcal ? +lasi700 ? +nsp32 ? +hptiop ? +stex ? +osst ? +sg ? +ch ? +scsi_debug ? +aacraid ? +aic7xxx ? +aic79xx ? +aic94xx ? +arcmsr ? +acornscsi_mod ? +arxescsi ? +cumana_1 ? +cumana_2 ? +ecoscsi ? +oak ? +powertec ? +eesox ? +ibmvscsi ? +ibmvfc ? +libsas ? +lpfc ? +megaraid_mm ? +megaraid_mbox ? +megaraid_sas ? +qla2xxx ? +sym53c8xx ? +qla4xxx ? +mvsas ? +vmw_pvscsi ? +ums-cypress ? +be2iscsi ? +3w-sas ? +isci ? +mlx4_ib ? +mlx5_ib ? +zfcp ? +sd_mod ? +hisi_sas_v2_hw ? +hisi_sas_v3_hw ? +iscsi_ibft ? + +# device handlers +scsi_dh_alua ? +scsi_dh_emc ? +scsi_dh_rdac ? +scsi_dh_hp_sw ? + +smartpqi ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/scsi-modules.powerpc +++ linux-oracle-5.4.0/debian.master/d-i/modules/scsi-modules.powerpc @@ -0,0 +1,118 @@ +# SCSI +raid_class ? +scsi_transport_spi ? +scsi_transport_fc ? +scsi_transport_iscsi ? +scsi_transport_sas ? +iscsi_tcp ? +libiscsi ? +amiga7xx ? +a3000 ? +a2091 ? +gvp11 ? +mvme147 ? +sgiwd93 ? +cyberstorm ? +cyberstormII ? +blz2060 ? +blz1230 ? +fastlane ? +oktagon_esp_mod ? +atari_scsi ? +mac_scsi ? +mac_esp ? +sun3_scsi ? +mvme16x ? +bvme6000 ? +sim710 ? +advansys ? +psi240i ? +BusLogic ? +dpt_i2o ? +u14-34f ? +ultrastor ? +aha152x ? +aha1542 ? +aha1740 ? +aic7xxx_old ? +ips ? +fd_mcs ? +fdomain ? +in2000 ? +g_NCR5380 ? +g_NCR5380_mmio ? +NCR53c406a ? +NCR_D700 ? +NCR_Q720_mod ? +sym53c416 ? +qlogicfas408 ? +qla1280 ? +pas16 ? +seagate ? +seagate ? +t128 ? +dmx3191d ? +dtc ? +zalon7xx ? +eata_pio ? +wd7000 ? +mca_53c9x ? +ibmmca ? +ibmvfc ? +ibmvscsi ? +eata ? +dc395x ? +tmscsim ? +megaraid ? +atp870u ? +esp ? +gdth ? +initio ? +a100u2w ? +qlogicpti ? +ide-scsi ? +mesh ? +mac53c94 ? +pluto ? +dec_esp ? +3w-xxxx ? +3w-9xxx ? +ppa ? +imm ? +jazz_esp ? +sun3x_esp ? +fcal ? +lasi700 ? +nsp32 ? +ipr ? +hptiop ? +stex ? +osst ? +sg ? +ch ? +scsi_debug ? +aacraid ? +aic7xxx ? +aic79xx ? +aic94xx ? +arcmsr ? +acornscsi_mod ? +arxescsi ? +cumana_1 ? +cumana_2 ? +ecoscsi ? +oak ? +powertec ? +eesox ? +ibmvscsic ? +libsas ? +lpfc ? +megaraid_mm ? +megaraid_mbox ? +megaraid_sas ? +qla2xxx ? +sym53c8xx ? +qla4xxx ? +mvsas ? +sr_mod ? +sd_mod ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/serial-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/serial-modules @@ -0,0 +1,4 @@ +generic_serial ? +serial_cs ? +synclink_cs ? +hyperv-keyboard ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/speakup-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/speakup-modules @@ -0,0 +1,16 @@ +speakup ? +speakup_acntpc ? +speakup_acntsa ? +speakup_apollo ? +speakup_audptr ? +speakup_bns ? +speakup_decext ? +speakup_dectlk ? +speakup_dtlk ? +speakup_dummy ? +speakup_keypc ? +speakup_ltlk ? +speakup_soft ? +speakup_spkout ? +speakup_txprt ? +speakup_decpc ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/storage-core-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/storage-core-modules @@ -0,0 +1,15 @@ +# Core stacks +usb-storage ? + +# Block level +ata_piix ? +ata_generic ? + +# Loop modules +cryptoloop ? + +# Needs to be here for better cdrom initrd layout +isofs ? + +# Needed for NVMe disks under VMD PCIe domains +vmd ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/storage-core-modules.powerpc +++ linux-oracle-5.4.0/debian.master/d-i/modules/storage-core-modules.powerpc @@ -0,0 +1,13 @@ +# Core stacks +usb-storage ? + +# Block level + +# Loop modules +cryptoloop + +# Needs to be here for better cdrom initrd layout +isofs + +ps3stor_lib ? +ps3rom ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/usb-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/usb-modules @@ -0,0 +1,15 @@ +ehci-hcd ? +isp116x-hcd ? +isp1760 ? +ohci-hcd ? +r8a66597-hcd ? +sl811_cs ? +sl811-hcd ? +u132-hcd ? +uhci-hcd ? +xhci-hcd ? +xhci-plat-hcd ? +ehci-tegra ? +ehci-msm ? +ehci-platform ? +uas ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/virtio-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/virtio-modules @@ -0,0 +1,11 @@ +virtio_balloon ? +virtio_pci ? +virtio_ring ? +virtio-rng ? +virtio_scsi ? +hv_vmbus ? +hv_utils ? +hv_netvsc ? +hv_mouse ? +hv_storvsc ? +hv_balloon ? --- linux-oracle-5.4.0.orig/debian.master/d-i/modules/vlan-modules +++ linux-oracle-5.4.0/debian.master/d-i/modules/vlan-modules @@ -0,0 +1,3 @@ +slp ? +garp ? +8021q ? --- linux-oracle-5.4.0.orig/debian.master/d-i/package-list +++ linux-oracle-5.4.0/debian.master/d-i/package-list @@ -0,0 +1,203 @@ +Package: kernel-image +Provides: ext3-modules, ext4-modules, squashfs-modules +Provides_amd64: efi-modules, ext3-modules, ext4-modules, squashfs-modules +Provides_i386: efi-modules, ext3-modules, ext4-modules, squashfs-modules +Provides_ppc64el: ext3-modules, ext4-modules, fat-modules, squashfs-modules +Provides_s390x: ext3-modules, ext4-modules, ppp-modules, squashfs-modules +Description: kernel image and system map + +Package: dasd-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: DASD storage support + +Package: dasd-extra-modules +Depends: dasd-modules +Priority: extra +Description: DASD storage support -- extras + +Package: fat-modules +Depends: kernel-image +Priority: standard +Description: FAT filesystem support + This includes Windows FAT and VFAT support. + +Package: fb-modules +Depends: kernel-image +Priority: standard +Description: Framebuffer modules + +Package: firewire-core-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Firewire (IEEE-1394) Support + +Package: floppy-modules +Depends: kernel-image +Priority: standard +Description: Floppy driver support + +Package: fs-core-modules +Depends: kernel-image +Priority: standard +Provides: ext2-modules, jfs-modules, reiserfs-modules, xfs-modules +Description: Base filesystem modules + This includes jfs, reiserfs and xfs. + +Package: fs-secondary-modules +Depends: kernel-image, fat-modules +Priority: standard +Provides: btrfs-modules, ntfs-modules, hfs-modules +Description: Extra filesystem modules + This includes support for Windows NTFS and MacOS HFS/HFSPlus + +Package: input-modules +Depends: kernel-image, usb-modules +Priority: standard +Description: Support for various input methods + +Package: md-modules +Depends: kernel-image +Priority: standard +Provides: crypto-dm-modules +Description: Multi-device support (raid, device-mapper, lvm) + +Package: nic-modules +Depends: kernel-image, nic-shared-modules, virtio-modules +Priority: standard +Description: Network interface support + +Package: nic-pcmcia-modules +Depends: kernel-image, nic-shared-modules, nic-modules +Priority: standard +Description: PCMCIA network interface support + +Package: nic-usb-modules +Depends: kernel-image, nic-shared-modules, usb-modules +Priority: standard +Description: USB network interface support + +Package: nic-shared-modules +Depends: kernel-image, crypto-modules +Priority: standard +Description: nic shared modules + This package contains modules which support nic modules + +Package: parport-modules +Depends: kernel-image +Priority: standard +Description: Parallel port support + +Package: pata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: PATA support modules + +Package: pcmcia-modules +Depends: kernel-image +Priority: standard +Description: PCMCIA Modules + +Package: pcmcia-storage-modules +Depends: kernel-image, scsi-modules +Priority: standard +Description: PCMCIA storage support + +Package: plip-modules +Depends: kernel-image, nic-shared-modules, parport-modules +Priority: standard +Description: PLIP (parallel port) networking support + +Package: ppp-modules +Depends: kernel-image, nic-shared-modules, serial-modules +Priority: standard +Description: PPP (serial port) networking support + +Package: sata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SATA storage support + +Package: scsi-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SCSI storage support + +Package: serial-modules +Depends: kernel-image +Priority: standard +Description: Serial port support + +Package: storage-core-modules +Depends: kernel-image +Priority: standard +Provides: loop-modules +Description: Core storage support + Includes core SCSI, LibATA, USB-Storage. Also includes related block + devices for CD, Disk and Tape medium (and IDE Floppy). + +Package: usb-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Core USB support + +Package: nfs-modules +Priority: standard +Depends: kernel-image +Description: NFS filesystem drivers + Includes the NFS client driver, and supporting modules. + +Package: block-modules +Priority: standard +Provides: nbd-modules +Depends: kernel-image, storage-core-modules, parport-modules, virtio-modules +Description: Block storage devices + This package contains the block storage devices, including DAC960 and + paraide. + +Package: message-modules +Priority: standard +Depends: kernel-image, storage-core-modules, scsi-modules +Description: Fusion and i2o storage modules + This package containes the fusion and i2o storage modules. + +Package: crypto-modules +Priority: extra +Depends: kernel-image +Description: crypto modules + This package contains crypto modules. + +Package: virtio-modules +Priority: standard +Depends: kernel-image +Description: VirtIO Modules + Includes modules for VirtIO (virtual machine, generally kvm guests) + +Package: socket-modules +Depends: kernel-image +Priority: standard +Description: Unix socket support + +Package: mouse-modules +Depends: kernel-image, input-modules, usb-modules +Priority: extra +Description: Mouse support + This package contains mouse drivers for the Linux kernel. + +Package: vlan-modules +Depends: kernel-image +Priority: extra +Description: vlan modules + This package contains vlan (8021.Q) modules. + +Package: ipmi-modules +Depends: kernel-image +Priority: standard +Description: ipmi modules + +Package: multipath-modules +Depends: kernel-image +Priority: extra +Description: DM-Multipath support + This package contains modules for device-mapper multipath support. + --- linux-oracle-5.4.0.orig/debian.master/dkms-versions +++ linux-oracle-5.4.0/debian.master/dkms-versions @@ -0,0 +1,3 @@ +zfs-linux 0.8.3-1ubuntu12.18 +virtualbox 6.1.50-dfsg-1~ubuntu1.20.04.1 +wireguard-linux-compat 1.0.20201112-1~20.04.1 --- linux-oracle-5.4.0.orig/debian.master/etc/kernelconfig +++ linux-oracle-5.4.0/debian.master/etc/kernelconfig @@ -0,0 +1,7 @@ +if [ "$variant" = "ports" ]; then + archs="" + family='ports' +else + archs="amd64 i386 armhf arm64 ppc64el s390x" + family='ubuntu' +fi --- linux-oracle-5.4.0.orig/debian.master/modprobe.d/common.conf +++ linux-oracle-5.4.0/debian.master/modprobe.d/common.conf @@ -0,0 +1,3 @@ +# LP:1434842 -- disable OSS drivers by default to allow pulseaudio to emulate +blacklist snd-mixer-oss +blacklist snd-pcm-oss --- linux-oracle-5.4.0.orig/debian.master/reconstruct +++ linux-oracle-5.4.0/debian.master/reconstruct @@ -0,0 +1,125 @@ +# Recreate any symlinks created since the orig. +chmod +x 'arch/mips/pci/pcie-octeon.c' +chmod +x 'debian/cloud-tools/hv_get_dhcp_info' +chmod +x 'debian/cloud-tools/hv_get_dns_info' +chmod +x 'debian/cloud-tools/hv_set_ifconfig' +chmod +x 'debian/rules' +chmod +x 'debian/scripts/config-check' +chmod +x 'debian/scripts/control-create' +chmod +x 'debian/scripts/dkms-build' +chmod +x 'debian/scripts/dkms-build--nvidia-N' +chmod +x 'debian/scripts/dkms-build--virtualbox-guest' +chmod +x 'debian/scripts/dkms-build-configure--zfs' +chmod +x 'debian/scripts/file-downloader' +chmod +x 'debian/scripts/link-headers' +chmod +x 'debian/scripts/misc/annotations' +chmod +x 'debian/scripts/misc/arch-has-odm-enabled.sh' +chmod +x 'debian/scripts/misc/final-checks' +chmod +x 'debian/scripts/misc/find-missing-sauce.sh' +chmod +x 'debian/scripts/misc/find-obsolete-firmware' +chmod +x 'debian/scripts/misc/fw-to-ihex.sh' +chmod +x 'debian/scripts/misc/gen-auto-reconstruct' +chmod +x 'debian/scripts/misc/get-firmware' +chmod +x 'debian/scripts/misc/git-ubuntu-log' +chmod +x 'debian/scripts/misc/insert-changes.pl' +chmod +x 'debian/scripts/misc/insert-mainline-changes' +chmod +x 'debian/scripts/misc/insert-ubuntu-changes' +chmod +x 'debian/scripts/misc/kernel-wedge-arch.pl' +chmod +x 'debian/scripts/misc/kernelconfig' +chmod +x 'debian/scripts/misc/migrate-annotations' +chmod +x 'debian/scripts/misc/retag' +chmod +x 'debian/scripts/misc/splitconfig.pl' +chmod +x 'debian/scripts/misc/tristate.sh' +chmod +x 'debian/scripts/misc/update-aufs.sh' +chmod +x 'debian/scripts/module-inclusion' +chmod +x 'debian/scripts/retpoline-extract' +chmod +x 'debian/scripts/retpoline-extract-one' +chmod +x 'debian/templates/extra.postinst.in' +chmod +x 'debian/templates/extra.postrm.in' +chmod +x 'debian/templates/headers.postinst.in' +chmod +x 'debian/templates/image.postinst.in' +chmod +x 'debian/templates/image.postrm.in' +chmod +x 'debian/templates/image.preinst.in' +chmod +x 'debian/templates/image.prerm.in' +chmod +x 'debian/tests-build/check-aliases' +chmod +x 'debian/tests/rebuild' +chmod +x 'debian/tests/ubuntu-regression-suite' +chmod +x 'samples/bpf/lwt_len_hist.sh' +chmod +x 'samples/bpf/test_lwt_bpf.sh' +chmod +x 'scripts/kmsg-doc' +chmod +x 'scripts/parse-maintainers.pl' +chmod +x 'tools/testing/selftests/net/fib_nexthop_nongw.sh' +chmod +x 'tools/testing/selftests/netfilter/conntrack_vrf.sh' +# Remove any files deleted from the orig. +rm -f 'Documentation/devicetree/bindings/clock/axi-clkgen.txt' +rm -f 'Documentation/devicetree/bindings/gpu/samsung-rotator.txt' +rm -f 'Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml' +rm -f 'Documentation/networking/decnet.txt' +rm -f 'arch/alpha/include/asm/bugs.h' +rm -f 'arch/ia64/include/asm/bugs.h' +rm -f 'arch/m68k/include/asm/bugs.h' +rm -f 'arch/parisc/include/asm/bugs.h' +rm -f 'arch/parisc/kernel/module.lds' +rm -f 'arch/parisc/lib/string.S' +rm -f 'arch/powerpc/include/asm/bugs.h' +rm -f 'arch/powerpc/include/uapi/asm/bpf_perf_event.h' +rm -f 'arch/sh/include/asm/bugs.h' +rm -f 'arch/sparc/include/asm/bugs.h' +rm -f 'arch/um/include/asm/bugs.h' +rm -f 'arch/um/kernel/gmon_syms.c' +rm -f 'arch/x86/events/intel/rapl.c' +rm -f 'arch/x86/include/asm/refcount.h' +rm -f 'arch/xtensa/include/asm/bugs.h' +rm -f 'drivers/block/sx8.c' +rm -f 'drivers/crypto/hisilicon/sgl.h' +rm -f 'drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h' +rm -f 'drivers/iio/adc/stx104.c' +rm -f 'drivers/input/serio/i8042-ppcio.h' +rm -f 'drivers/net/can/dev.c' +rm -f 'drivers/net/can/rx-offload.c' +rm -f 'drivers/net/phy/mdio-i2c.h' +rm -f 'drivers/net/phy/mdio-xgene.h' +rm -f 'drivers/soc/qcom/llcc-sdm845.c' +rm -f 'drivers/soc/qcom/llcc-slice.c' +rm -f 'drivers/staging/mt7621-dma/mtk-hsdma.c' +rm -f 'include/Kbuild' +rm -f 'include/asm-generic/bugs.h' +rm -f 'include/linux/kd.h' +rm -f 'include/net/dn.h' +rm -f 'include/net/dn_dev.h' +rm -f 'include/net/dn_fib.h' +rm -f 'include/net/dn_neigh.h' +rm -f 'include/net/dn_nsp.h' +rm -f 'include/net/dn_route.h' +rm -f 'include/trace/events/random.h' +rm -f 'include/uapi/linux/dn.h' +rm -f 'include/uapi/linux/netfilter_decnet.h' +rm -f 'include/uapi/rdma/nes-abi.h' +rm -f 'kernel/elfcore.c' +rm -f 'net/decnet/Kconfig' +rm -f 'net/decnet/Makefile' +rm -f 'net/decnet/README' +rm -f 'net/decnet/af_decnet.c' +rm -f 'net/decnet/dn_dev.c' +rm -f 'net/decnet/dn_fib.c' +rm -f 'net/decnet/dn_neigh.c' +rm -f 'net/decnet/dn_nsp_in.c' +rm -f 'net/decnet/dn_nsp_out.c' +rm -f 'net/decnet/dn_route.c' +rm -f 'net/decnet/dn_rules.c' +rm -f 'net/decnet/dn_table.c' +rm -f 'net/decnet/dn_timer.c' +rm -f 'net/decnet/netfilter/Kconfig' +rm -f 'net/decnet/netfilter/Makefile' +rm -f 'net/decnet/netfilter/dn_rtmsg.c' +rm -f 'net/decnet/sysctl_net_decnet.c' +rm -f 'net/sched/cls_rsvp.c' +rm -f 'net/sched/cls_rsvp.h' +rm -f 'net/sched/cls_rsvp6.c' +rm -f 'net/sched/cls_tcindex.c' +rm -f 'net/sched/sch_atm.c' +rm -f 'net/sched/sch_cbq.c' +rm -f 'net/sched/sch_dsmark.c' +rm -f 'net/xfrm/xfrm_interface.c' +rm -f 'tools/build/feature/test-libpython-version.c' +exit 0 --- linux-oracle-5.4.0.orig/debian.master/rules.d/amd64.mk +++ linux-oracle-5.4.0/debian.master/rules.d/amd64.mk @@ -0,0 +1,27 @@ +human_arch = 64 bit x86 +build_arch = x86 +header_arch = $(build_arch) +defconfig = defconfig +flavours = generic lowlatency +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz +loader = grub +vdso = vdso_install +no_dumpfile = true +uefi_signed = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true +do_tools_x86 = true +do_tools_hyperv = true +do_tools_host = true +do_extras_package = true +do_tools_common = true +do_tools_acpidbg = true +do_zfs = true +do_dkms_vbox = true +do_dkms_wireguard = true +do_odm_drivers = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/arm64.mk +++ linux-oracle-5.4.0/debian.master/rules.d/arm64.mk @@ -0,0 +1,24 @@ +human_arch = ARMv8 +build_arch = arm64 +header_arch = arm64 +defconfig = defconfig +flavours = generic +build_image_generic = Image.gz +kernel_file_generic = arch/$(build_arch)/boot/Image.gz +install_file = vmlinuz +no_dumpfile = true +uefi_signed = true + +loader = grub +vdso = vdso_install + +do_extras_package = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true + +do_dtbs = true +do_zfs = true +do_dkms_wireguard = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/armhf.mk +++ linux-oracle-5.4.0/debian.master/rules.d/armhf.mk @@ -0,0 +1,21 @@ +human_arch = ARM (hard float) +build_arch = arm +header_arch = arm +defconfig = defconfig +flavours = generic generic-lpae +build_image = zImage +kernel_file = arch/$(build_arch)/boot/zImage +install_file = vmlinuz +no_dumpfile = true + +loader = grub + +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true + +do_dtbs = true + +do_dkms_wireguard = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/hooks.mk +++ linux-oracle-5.4.0/debian.master/rules.d/hooks.mk @@ -0,0 +1 @@ +do_enforce_all = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/i386.mk +++ linux-oracle-5.4.0/debian.master/rules.d/i386.mk @@ -0,0 +1,19 @@ +human_arch = 32 bit x86 +build_arch = i386 +header_arch = $(build_arch) +defconfig = defconfig +flavours = generic lowlatency +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz +loader = grub +vdso = vdso_install +no_dumpfile = true +do_flavour_image_package = false +do_tools = false +do_tools_common = false +do_extras_package = false +do_source_package = false +do_doc_package = false +do_flavour_header_package = false +do_common_headers_indep = false --- linux-oracle-5.4.0.orig/debian.master/rules.d/ppc64el.mk +++ linux-oracle-5.4.0/debian.master/rules.d/ppc64el.mk @@ -0,0 +1,22 @@ +human_arch = PowerPC 64el +build_arch = powerpc +header_arch = $(build_arch) +defconfig = pseries_le_defconfig +flavours = generic +build_image = vmlinux.strip +kernel_file = arch/powerpc/boot/vmlinux.strip +install_file = vmlinux +no_dumpfile = true +vdso = vdso_install +loader = grub +do_extras_package = true +opal_signed = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true + +#do_flavour_image_package = false +do_zfs = true +do_dkms_wireguard = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/riscv64.mk +++ linux-oracle-5.4.0/debian.master/rules.d/riscv64.mk @@ -0,0 +1,21 @@ +human_arch = RISC-V +build_arch = riscv +header_arch = $(build_arch) +defconfig = defconfig +flavours = generic +build_image = Image +kernel_file = arch/$(build_arch)/boot/Image +install_file = vmlinuz + +loader = grub +vdso = vdso_install +no_dumpfile = true + +do_flavour_image_package = false +do_tools = false +do_tools_common = false +do_extras_package = false +do_source_package = false +do_doc_package = false +do_flavour_header_package = false +do_common_headers_indep = false --- linux-oracle-5.4.0.orig/debian.master/rules.d/s390x.mk +++ linux-oracle-5.4.0/debian.master/rules.d/s390x.mk @@ -0,0 +1,22 @@ +human_arch = System 390x +build_arch = s390 +header_arch = $(build_arch) +defconfig = defconfig +flavours = generic +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz + +vdso = vdso_install +no_dumpfile = true + +do_extras_package = true +sipl_signed = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true + +do_zfs = true +do_dkms_wireguard = true --- linux-oracle-5.4.0.orig/debian.master/rules.d/x32.mk +++ linux-oracle-5.4.0/debian.master/rules.d/x32.mk @@ -0,0 +1,14 @@ +human_arch = 64 bit x86 (32 bit userspace) +build_arch = x86 +header_arch = $(build_arch) +defconfig = defconfig +flavours = +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz +loader = grub +vdso = vdso_install +no_dumpfile = true +uefi_signed = true + +do_flavour_image_package = false --- linux-oracle-5.4.0.orig/debian.master/tracking-bug +++ linux-oracle-5.4.0/debian.master/tracking-bug @@ -0,0 +1 @@ +2106869 2025.04.14-1 --- linux-oracle-5.4.0.orig/debian.master/upstream-stable +++ linux-oracle-5.4.0/debian.master/upstream-stable @@ -0,0 +1,3 @@ +# The following upstream stable releases have been ported: +[upstream-stable] + linux-5.4.y = v5.4.291 --- linux-oracle-5.4.0.orig/debian.oracle/changelog +++ linux-oracle-5.4.0/debian.oracle/changelog @@ -0,0 +1,57485 @@ +linux-oracle (5.4.0-1144.154) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1144.154 -proposed tracker (LP: #2106864) + + [ Ubuntu: 5.4.0-216.236 ] + + * focal/linux: 5.4.0-216.236 -proposed tracker (LP: #2106869) + * CVE-2023-52741 + - cifs: Fix use-after-free in rdata->read_into_pages() + * CVE-2021-47191 + - scsi: scsi_debug: Fix out-of-bound read in resp_readcap16() + * iommu/arm-smmu-v3: Don't reserve implementation defined register space + (LP: #2067864) + - iommu/arm-smmu-v3: Don't reserve implementation defined register space + * CVE-2025-21971 + - net_sched: Prevent creation of classes with TC_H_ROOT + * CVE-2024-56599 + - wifi: ath10k: avoid NULL pointer error during sdio remove + * Focal update: v5.4.291 upstream stable release (LP: #2106002) + - perf cs-etm: Add missing variable in cs_etm__process_queues() + - udf: Fix use of check_add_overflow() with mixed type arguments + - overflow: Add __must_check attribute to check_*() helpers + - overflow: Correct check_shl_overflow() comment + - overflow: Allow mixed type arguments + - afs: Fix directory format encoding struct + - partitions: ldm: remove the initial kernel-doc notation + - drm/etnaviv: Fix page property being used for non writecombine buffers + - wifi: rtlwifi: do not complete firmware loading needlessly + - rtlwifi: rtl8192se Rename RT_TRACE to rtl_dbg + - wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last step + - wifi: rtlwifi: usb: fix workqueue leak when probe fails + - dt-bindings: mmc: controller: clarify the address-cells description + - rtlwifi: replace usage of found with dedicated list iterator variable + - wifi: rtlwifi: remove unused timer and related code + - wifi: rtlwifi: remove unused dualmac control leftovers + - wifi: rtlwifi: pci: wait for firmware loading before releasing memory + - cpupower: fix TSC MHz calculation + - regulator: of: Implement the unwind path of of_regulator_match() + - wifi: wlcore: fix unbalanced pm_runtime calls + - selftests/harness: Display signed values correctly + - selftests: harness: fix printing of mismatch values in __EXPECT() + - clk: analogbits: Fix incorrect calculation of vco rate delta + - net/mlxfw: Drop hard coded max FW flash image size + - tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind + - ASoC: sun4i-spdif: Add clock multiplier settings + - perf header: Fix one memory leakage in process_bpf_btf() + - perf header: Fix one memory leakage in process_bpf_prog_info() + - ktest.pl: Remove unused declarations in run_bisect_test function + - padata: fix sysfs store callback check + - perf top: Don't complain about lack of vmlinux when not resolving some + kernel samples + - perf report: Fix misleading help message about --demangle + - RDMA/mlx4: Avoid false error about access to uninitialized gids array + - arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property + - arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names + - ARM: dts: mediatek: mt7623: fix IR nodename + - fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device() + - media: rc: iguanair: handle timeouts + - media: lmedm04: Use GFP_KERNEL for URB allocation/submission. + - media: lmedm04: Handle errors for lme2510_int_read + - PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy() + - media: mipi-csis: Add check for clk_enable() + - media: camif-core: Add check for clk_enable() + - media: uvcvideo: Propagate buf->error to userspace + - staging: media: imx: fix OF node leak in imx_media_add_of_subdevs() + - scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1 + - scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails + - ocfs2: mark dquot as inactive if failed to start trans while releasing dquot + - module: Extend the preempt disabled section in + dereference_symbol_descriptor(). + - dmaengine: ti: edma: fix OF node reference leaks in edma_driver + - net: fec: implement TSO descriptor cleanup + - PM: hibernate: Add error handling for syscore_suspend() + - perf trace: Fix runtime error of index out of bounds + - vsock: Allow retrying on connect() failure + - net: sh_eth: Fix missing rtnl lock in suspend/resume path + - genksyms: fix memory leak when the same symbol is added from source + - genksyms: fix memory leak when the same symbol is read from *.symref file + - hexagon: fix using plain integer as NULL pointer warning in cmpxchg + - hexagon: Fix unbalanced spinlock in die() + - NFSD: Reset cb_seq_status after NFS4ERR_DELAY + - ktest.pl: Check kernelrelease return in get_version + - drivers/card_reader/rtsx_usb: Restore interrupt based detection + - usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to PD_T_SENDER_RESPONSE + - btrfs: output the reason for open_ctree() failure + - btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling + - sched: Don't try to catch up excess steal time. + - x86/amd_nb: Restrict init function to AMD-based systems + - tun: fix group permission check + - mmc: core: Respect quirk_max_rate for non-UHS SDIO card + - mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id + - HID: Wacom: Add PCI Wacom device support + - APEI: GHES: Have GHES honor the panic= setting + - x86/mm: Don't disable PCID when INVLPG has been fixed by microcode + - spi-mxs: Fix chipselect glitch + - nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link + - nilfs2: eliminate staggered calls to kunmap in nilfs_rename + - media: uvcvideo: Only save async fh if success + - kbuild: userprogs: use correct lld when linking through clang + - tasklet: Introduce new initialization API + - net: usb: rtl8150: use new tasklet API + - usb: xhci: Add timeout argument in address_device USB HCD callback + - nvme: handle connectivity loss in nvme_set_queue_count + - firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry + - gpu: drm_dp_cec: fix broken CEC adapter properties check + - tg3: Disable tg3 PCIe AER on system reboot + - udp: gso: do not drop small packets when PMTU reduces + - tun: revert fix group permission check + - cpufreq: s3c64xx: Fix compilation warning + - leds: lp8860: Write full EEPROM, not only half of it + - s390/futex: Fix FUTEX_OP_ANDN implementation + - m68k: vga: Fix I/O defines + - arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma + - KVM: s390: vsie: fix some corner-cases when grabbing vsie pages + - drm/komeda: Add check for komeda_get_layer_fourcc_list() + - clk: qcom: clk-alpha-pll: fix alpha mode configuration + - clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate + - perf bench: Fix undefined behavior in cmpworker() + - of: Correct child specifier used as input of the 2nd nexus node + - of: Fix of_find_node_opts_by_path() handling of alias+path+options + - of: reserved-memory: Fix using wrong number of cells to get property + 'alignment' + - HID: hid-sensor-hub: don't use stale platform-data on remove + - usb: gadget: f_tcm: Translate error to sense + - usb: gadget: f_tcm: Decrement command ref count on cleanup + - usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint + - usb: gadget: f_tcm: Don't prepare BOT write request twice + - serial: sh-sci: Drop __initdata macro for port_cfg + - serial: sh-sci: Do not probe the serial port if its slot in sci_ports[] is + in use + - powerpc/pseries/eeh: Fix get PE state translation + - kbuild: Move -Wenum-enum-conversion to W=2 + - soc: qcom: smem_state: fix missing of_node_put in error path + - media: ov5640: fix get_light_freq on auto + - media: uvcvideo: Fix event flags in uvc_ctrl_send_events + - media: uvcvideo: Remove redundant NULL assignment + - crypto: qce - fix goto jump in error path + - crypto: qce - unregister previously registered algos in error path + - nvmem: core: improve range check for nvmem_cell_write() + - vfio/platform: check the bounds of read/write syscalls + - ocfs2: fix incorrect CPU endianness conversion causing mount failure + - mtd: onenand: Fix uninitialized retlen in do_otp_read() + - misc: fastrpc: Fix registered buffer page address + - net/ncsi: wait for the last response to Deselect Package before configuring + channel + - MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static + - ocfs2: check dir i_size in ocfs2_find_entry + - ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu() + - gpio: bcm-kona: Fix GPIO lock/unlock for banks above bank 0 + - gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ + - gpio: bcm-kona: Add missing newline to dev_err format string + - xen: remove a confusing comment on auto-translated guest I/O + - x86/xen: allow larger contiguous memory regions in PV guests + - media: cxd2841er: fix 64-bit division on gcc-9 + - vfio/pci: Enable iowrite64 and ioread64 for vfio pci + - Grab mm lock before grabbing pt lock + - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V + - usb: roles: set switch registered flag early on + - usb: gadget: udc: renesas_usb3: Fix compiler warning + - usb: dwc2: gadget: remove of_node reference upon udc_stop + - USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI + - USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist + - USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone + - USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk + - usb: cdc-acm: Fix handling of oversized fragments + - USB: serial: option: add MeiG Smart SLM828 + - USB: serial: option: add Telit Cinterion FN990B compositions + - USB: serial: option: fix Telit Cinterion FN990A name + - USB: serial: option: drop MeiG Smart defines + - can: c_can: fix unbalanced runtime PM disable in error path + - can: j1939: j1939_sk_send_loop(): fix unable to send messages with data + length zero + - alpha: make stack 16-byte aligned (most cases) + - serial: 8250: Fix fifo underflow on flush + - alpha: align stack for page fault and user unaligned trap handlers + - gpio: stmpe: Check return value of stmpe_reg_read in + stmpe_gpio_irq_sync_unlock + - regmap-irq: Add missing kfree() + - net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu() + - net: add dev_net_rcu() helper + - ipv4: use RCU protection in rt_is_expired() + - ipv4: use RCU protection in inet_select_addr() + - neighbour: delete redundant judgment statements + - alpha: replace hardcoded stack offsets with autogenerated ones + - nilfs2: do not output warnings when clearing dirty buffers + - can: ems_pci: move ASIX AX99100 ids to pci_ids.h + - serial: 8250_pci: add support for ASIX AX99100 + - parport_pc: add support for ASIX AX99100 + - x86/i8253: Disable PIT timer 0 when not in use + - Revert "btrfs: avoid monopolizing a core when activating a swap file" + - btrfs: avoid monopolizing a core when activating a swap file + - vlan: introduce vlan_dev_free_egress_priority + - vlan: move dev_put into vlan_dev_uninit + - scsi: storvsc: Set correct data length for sending SCSI command without + payload + - crypto: testmgr - fix wrong key length for pkcs1pad + - crypto: testmgr - Fix wrong test case of RSA + - crypto: testmgr - fix version number of RSA tests + - crypto: testmgr - populate RSA CRT parameters in RSA test vectors + - crypto: testmgr - some more fixes to RSA test vectors + - mm: update mark_victim tracepoints fields + - usb: dwc3: Increase DWC3 controller halt timeout + - usb: dwc3: Fix timeout issue during controller enter/exit from halt state + - usb/gadget: f_midi: convert tasklets to use new tasklet_setup() API + - usb/gadget: f_midi: Replace tasklet with work + - powerpc/64s/mm: Move __real_pte stubs into hash-4k.h + - powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline + - ALSA: hda/realtek - Add type for ALC287 + - ALSA: hda/realtek: Fixup ALC225 depop procedure + - geneve: Suppress list corruption splat in geneve_destroy_tunnels(). + - net: extract port range fields from fl_flow_key + - flow_dissector: Fix handling of mixed port and port-range keys + - flow_dissector: Fix port range key handling in BPF conversion + - power: supply: da9150-fg: fix potential overflow + - ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED + - acct: block access to kernel internal filesystems + - batman-adv: Ignore neighbor throughput metrics in error case + - sunrpc: suppress warnings for unused procfs functions + - net: loopback: Avoid sending IP packets without an Ethernet header + - net: cadence: macb: Synchronize stats calculations + - ASoC: es8328: fix route from DAC to output + - ipvs: Always clear ipvs_property flag in skb_scrub_packet() + - net: mvpp2: cls: Fixed Non IP flow, with vlan tag flow defination. + - x86/CPU: Fix warm boot hang regression on AMD SC1100 SoC systems + - ftrace: Avoid potential division by zero in function_stat_show() + - perf/core: Fix low freq setting via IOC_PERIOD + - phy: tegra: xusb: reset VBUS & ID OVERRIDE + - phy: exynos5-usbdrd: fix MPLL_MULTIPLIER and SSC_REFCLKSEL masks in refclk + - kernel/acct.c: use #elif instead of #end and #elif + - kernel/acct.c: use dedicated helper to access rlimit values + - drm/amdgpu: skip BAR resizing if the bios already did it + - drm/amdgpu: Check extended configuration space register when system uses + large bar + - drm/amdgpu: disable BAR resize on Dell G5 SE + - Revert "of: reserved-memory: Fix using wrong number of cells to get property + 'alignment'" + - HID: appleir: Fix potential NULL dereference at raw event handle + - ALSA: hda: intel: Add Dell ALC3271 to power_save denylist + - ALSA: hda/realtek: update ALC222 depop optimize + - drm/radeon: Fix rs400_gpu_init for ATI mobility radeon Xpress 200M + - platform/x86: thinkpad_acpi: Add battery quirk for ThinkPad X131e + - x86/cacheinfo: Validate CPUID leaf 0x2 EDX output + - x86/cpu: Validate CPUID leaf 0x2 EDX output + - x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63 + - wifi: cfg80211: regulatory: improve invalid hints checking + - wifi: nl80211: reject cooked mode if it is set along with other flags + - rapidio: add check for rio_add_net() in rio_scan_alloc_net() + - rapidio: fix an API misues when rio_add_net() fails + - mm/page_alloc: fix uninitialized variable + - wifi: iwlwifi: limit printed string from FW file + - HID: google: fix unused variable warning under !CONFIG_ACPI + - HID: intel-ish-hid: Fix use-after-free issue in ishtp_hid_remove() + - net: gso: fix ownership in __udp_gso_segment + - caif_virtio: fix wrong pointer check in cfv_probe() + - hwmon: (pmbus) Initialise page count in pmbus_identify() + - hwmon: (ntc_thermistor) Fix the ncpXXxh103 sensor table + - hwmon: (ad7314) Validate leading zero bits and return error + - llc: do not use skb_get() before dev_queue_xmit() + - hwmon: fix a NULL vs IS_ERR_OR_NULL() check in xgene_hwmon_probe() + - drm/sched: Fix preprocessor guard + - be2net: fix sleeping while atomic bugs in be_ndo_bridge_getlink + - ppp: Fix KMSAN uninit-value warning with bpf + - vlan: enforce underlying device type + - net-timestamp: support TCP GSO case for a few missing flags + - net: ipv6: fix dst ref loop in ila lwtunnel + - net: ipv6: fix missing dst ref drop in ila lwtunnel + - gpio: rcar: Fix missing of_node_put() call + - Revert "drivers/card_reader/rtsx_usb: Restore interrupt based detection" + - usb: renesas_usbhs: Call clk_put() + - usb: renesas_usbhs: Use devm_usb_get_phy() + - usb: quirks: Add DELAY_INIT and NO_LPM for Prolific Mass Storage Card Reader + - usb: renesas_usbhs: Flush the notify_hotplug_work + - usb: atm: cxacru: fix a flaw in existing endpoint checks + - usb: typec: ucsi: increase timeout for PPM reset operations + - usb: typec: tcpci_rt1711h: Unmask alert interrupts to fix functionality + - usb: gadget: Set self-powered based on MaxPower and bmAttributes + - usb: gadget: Fix setting self-powered state on suspend + - usb: gadget: Check bmAttributes only if configuration is valid + - xhci: pci: Fix indentation in the PCI device ID definitions + - intel_th: pci: Add Arrow Lake support + - intel_th: pci: Add Panther Lake-H support + - intel_th: pci: Add Panther Lake-P/U support + - slimbus: messaging: Free transaction ID in delayed interrupt scenario + - eeprom: digsy_mtc: Make GPIO lookup table match the device + - Linux 5.4.291 + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-26982 + - Squashfs: check the inode number is not the invalid value of zero + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21846 + - acct: perform last write from workqueue + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21862 + - drop_monitor: fix incorrect initialization order + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58090 + - sched/core: Prevent rescheduling when interrupts are disabled + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21877 + - usbnet: gl620a: fix endpoint checking in genelink_bind() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21823 + - batman-adv: Drop unmanaged ELP metric worker + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21848 + - nfp: bpf: Add check for nfp_app_ctrl_msg_alloc() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21871 + - tee: optee: Fix supplicant wait loop + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21865 + - gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl(). + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21858 + - geneve: Fix use-after-free in geneve_find_dev(). + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21866 + - powerpc/code-patching: Fix KASAN hit by not flagging text patching area as + VM_ALLOC + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21859 + - USB: gadget: f_midi: f_midi_complete to call queue_work + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57977 + - memcg: fix soft lockup in the OOM process + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-50055 + - driver core: bus: Fix double free in driver API bus_register() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57979 + - pps: Fix a use-after-free + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21811 + - nilfs2: protect access to buffers with no active references + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21722 + - nilfs2: do not force clear folio if buffer is referenced + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21760 + - ndisc: extend RCU protection in ndisc_send_skb() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21761 + - openvswitch: use RCU protection in ovs_vport_cmd_fill_info() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21762 + - arp: use RCU protection in arp_xmit() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21763 + - neighbour: use RCU protection in __neigh_notify() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21764 + - ndisc: use RCU protection in ndisc_alloc_skb() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21765 + - ipv6: use RCU protection in ip6_default_advmss() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21772 + - partitions: mac: fix handling of bogus partition table + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21704 + - usb: cdc-acm: Check control transfer buffer size before access + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21776 + - USB: hub: Ignore non-compliant devices with too many configs or interfaces + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21835 + - usb: gadget: f_midi: fix MIDI Streaming descriptor lengths + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21781 + - batman-adv: fix panic during interface removal + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21782 + - orangefs: fix a oob in orangefs_debug_write + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21785 + - arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21787 + - team: better TEAM_OPTION_TYPE_STRING validation + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21791 + - vrf: use RCU protection in l3mdev_l3_out() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58020 + - HID: multitouch: Add NULL check in mt_input_configured + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21814 + - ptp: Ensure info->enable callback is always set + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21735 + - NFC: nci: Add bounds checking in nci_hci_create_pipe() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21736 + - nilfs2: fix possible int overflows in nilfs_fiemap() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58001 + - ocfs2: handle a symlink read error correctly + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58007 + - soc: qcom: socinfo: Avoid out of bounds read of serial number + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21744 + - wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58009 + - Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58083 + - KVM: Explicitly verify target vCPU is online in kvm_get_vcpu() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58010 + - binfmt_flat: Fix integer overflow bug on 32 bit systems + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21749 + - net: rose: lock the socket in rose_bind() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57981 + - usb: xhci: Fix NULL pointer dereference on certain command aborts + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21708 + - net: usb: rtl8150: enable basic endpoint checking + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21647 + - sched: sch_cake: add bounds checks to host bulk flow fairness counts + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58002 + - media: uvcvideo: Remove dangling pointers + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21721 + - nilfs2: handle errors that nilfs_prepare_chunk() may return + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58085 + - tomoyo: don't emit warning in tomoyo_write_control() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58014 + - wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58017 + - printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21753 + - btrfs: fix use-after-free when attempting to join an aborted transaction + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58055 + - usb: gadget: f_tcm: Don't free command immediately + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57980 + - media: uvcvideo: Fix double free in error path + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57986 + - HID: core: Fix assumption that Resolution Multipliers must be in Logical + Collections + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21715 + - net: davicom: fix UAF in dm9000_drv_remove + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21718 + - net: rose: fix timer races against user threads + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21719 + - ipmr: do not call mr_mfc_uses_dev() for unres entries + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58058 + - ubifs: skip dumping tnc tree when zroot is null + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58069 + - rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57973 + - rdma/cxgb4: Prevent potential integer overflow on 32bit + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21728 + - bpf: Send signals asynchronously if !preemptible + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21806 + - net: let net.core.dev_weight always be non-zero + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58071 + - team: prevent adding a device which is already a team device lower + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58063 + - wifi: rtlwifi: fix memory leaks and invalid access at probe error path + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58072 + - wifi: rtlwifi: remove unused check_buddy_priv + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58051 + - ipmi: ipmb: Add check devm_kasprintf() returned value + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58052 + - drm/amdgpu: Fix potential NULL pointer dereference in + atomctrl_get_smc_sclk_range_table + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21731 + - nbd: don't allow reconnect after disconnect + * CVE-2024-26996 + - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport + error + * CVE-2023-52664 + - net: atlantic: eliminate double free in error handling logic + * CVE-2024-26689 + - ceph: prevent use-after-free in encode_cap_msg() + * CVE-2023-52927 + - netfilter: allow exp not to be removed in nf_ct_find_expectation + + -- Benjamin Wheeler Thu, 08 May 2025 08:32:42 -0400 + +linux-oracle (5.4.0-1143.153) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1143.153 -proposed tracker (LP: #2106913) + + [ Ubuntu: 5.4.0-215.235 ] + + * focal/linux: 5.4.0-215.235 -proposed tracker (LP: #2106919) + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + * CVE-2023-52664 + - net: atlantic: eliminate double free in error handling logic + * CVE-2024-26689 + - ceph: prevent use-after-free in encode_cap_msg() + * CVE-2023-52927 + - netfilter: allow exp not to be removed in nf_ct_find_expectation + + -- Philip Cox Tue, 22 Apr 2025 12:16:04 -0400 + +linux-oracle (5.4.0-1142.152) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1142.152 -proposed tracker (LP: #2102630) + + [ Ubuntu: 5.4.0-214.234 ] + + * focal/linux: 5.4.0-214.234 -proposed tracker (LP: #2102635) + * CVE-2024-50256 + - netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6() + * CVE-2025-21702 + - pfifo_tail_enqueue: Drop new packet when sch->limit == 0 + * CVE-2025-21703 + - netem: Update sch->q.qlen before qdisc_tree_reduce_backlog() + * CVE-2024-26915 + - drm/amdgpu: Reset IH OVERFLOW_CLEAR bit + * CVE-2025-21700 + - net: sched: Disallow replacing of child qdisc from one parent to another + * CVE-2024-46826 + - ELF: fix kernel.randomize_va_space double read + * CVE-2024-56651 + - can: hi311x: hi3110_can_ist(): fix potential use-after-free + * CVE-2024-53237 + - driver core: Introduce device_find_any_child() helper + - Bluetooth: fix use-after-free in device_for_each_child() + * CVE-2024-35958 + - net: ena: Fix incorrect descriptor free behavior + * CVE-2024-49974 + - NFSD: Limit the number of concurrent async COPY operations + * CVE-2021-47119 + - ext4: fix memory leak in ext4_fill_super + * CVE-2024-56658 + - net: defer final 'struct net' free in netns dismantle + * CVE-2024-35864 + - smb: client: fix potential UAF in smb2_is_valid_lease_break() + * CVE-2024-35864/CVE-2024-26928 + - smb: client: fix potential UAF in cifs_debug_files_proc_show() + + -- Philip Cox Thu, 27 Mar 2025 12:27:52 -0400 + +linux-oracle (5.4.0-1141.151) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1141.151 -proposed tracker (LP: #2102362) + + [ Ubuntu: 5.4.0-212.232 ] + + * focal/linux: 5.4.0-212.232 -proposed tracker (LP: #2102367) + * CVE-2024-56658 + - net: defer final 'struct net' free in netns dismantle + * CVE-2024-35864 + - smb: client: fix potential UAF in smb2_is_valid_lease_break() + * CVE-2024-35864/CVE-2024-26928 + - smb: client: fix potential UAF in cifs_debug_files_proc_show() + + -- Philip Cox Tue, 25 Mar 2025 07:07:25 -0400 + +linux-oracle (5.4.0-1140.150) focal; urgency=medium + + -- Philip Cox Fri, 21 Mar 2025 11:18:39 -0400 + +linux-oracle (5.4.0-1140.149) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1140.149 -proposed tracker (LP: #2101991) + + [ Ubuntu: 5.4.0-211.231 ] + + * focal/linux: 5.4.0-211.231 -proposed tracker (LP: #2101996) + * cve-2018-5803 kernel panic (LP: #2101091) + - SAUCE: sctp: sysctl: pass right argument to container_of + + -- Philip Cox Fri, 14 Mar 2025 09:22:44 -0400 + +linux-oracle (5.4.0-1139.148) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1139.148 -proposed tracker (LP: #2098348) + + [ Ubuntu: 5.4.0-210.230 ] + + * focal/linux: 5.4.0-210.230 -proposed tracker (LP: #2098353) + * Focal update: v5.4.290 upstream stable release (LP: #2098439) + - jbd2: flush filesystem device before updating tail sequence + - dm array: fix releasing a faulty array block twice in dm_array_cursor_end + - dm array: fix unreleased btree blocks on closing a faulty array cursor + - dm array: fix cursor index when skipping across block boundaries + - ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe() + - net: 802: LLC+SNAP OID:PID lookup on start of skb data + - tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog + - tcp/dccp: allow a connection when sk_max_ack_backlog is zero + - net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute + - tls: Fix tls_sw_sendmsg error handling + - dm thin: make get_first_thin use rcu-safe list first function + - sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy + - sctp: sysctl: auth_enable: avoid using current->nsproxy + - drm/amd/display: Add check for granularity in dml ceil/floor helpers + - ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[] + - ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[] + - drm/amd/display: increase MAX_SURFACES to the value supported by hw + - USB: serial: option: add MeiG Smart SRM815 + - USB: serial: option: add Neoway N723-EA support + - staging: iio: ad9834: Correct phase range check + - staging: iio: ad9832: Correct phase range check + - usb-storage: Add max sectors quirk for Nokia 208 + - USB: serial: cp210x: add Phoenix Contact UPS Device + - usb: gadget: u_serial: Disable ep before setting port to null to fix the + crash caused by port being null + - USB: usblp: return error when setting unsupported protocol + - USB: core: Disable LPM only for non-suspended ports + - usb: fix reference leak in usb_new_device() + - usb: gadget: f_fs: Remove WARN_ON in functionfs_bind + - iio: pressure: zpa2326: fix information leak in triggered buffer + - iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered + buffer + - iio: light: vcnl4035: fix information leak in triggered buffer + - iio: imu: kmx61: fix information leak in triggered buffer + - iio: adc: ti-ads8688: fix information leak in triggered buffer + - iio: gyro: fxas21002c: Fix missing data update in trigger handler + - iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep() + - iio: adc: at91: call input_free_device() on allocated iio_dev + - iio: inkern: call iio_device_put() only on mapped devices + - arm64: dts: rockchip: fix defines in pd_vio node for rk3399 + - arm64: dts: rockchip: fix pd_tcpc0 and pd_tcpc1 node position on rk3399 + - arm64: dts: rockchip: add #power-domain-cells to power domain nodes + - arm64: dts: rockchip: add hevc power domain clock to rk3328 + - phy: core: fix code style in devm_of_phy_provider_unregister + - phy: core: Fix that API devm_of_phy_provider_unregister() fails to + unregister the phy provider + - ocfs2: correct return value of ocfs2_local_free_info() + - ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv + - sctp: sysctl: rto_min/max: avoid using current->nsproxy + - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field() + - net: net_namespace: Optimize the code + - net: add exit_batch_rtnl() method + - gtp: use exit_batch_rtnl() method + - gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp(). + - gtp: Destroy device along with udp socket's netns dismantle. + - nfp: bpf: prevent integer overflow in nfp_bpf_event_output() + - drm/v3d: Ensure job pointer is set to NULL after job completion + - i2c: mux: demux-pinctrl: check initial mux selection, too + - mac802154: check local interfaces before deleting sdata list + - hfs: Sanity check the root record + - kheaders: Ignore silly-rename files + - poll_wait: add mb() to fix theoretical race between waitqueue_active() and + .poll() + - nvmet: propagate npwg topology + - net: ethernet: xgbe: re-add aneg to supported features in PHY quirks + - fs/proc: fix softlockup in __read_vmcore (part 2) + - irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly + - hrtimers: Handle CPU state correctly on hotplug + - ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev() + - scsi: sg: Fix slab-use-after-free read in sg_release() + - net: fix data-races around sk->sk_forward_alloc + - ASoC: wm8994: Add depends on MFD core + - scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request + - irqchip/sunxi-nmi: Add missing SKIP_WAKE flag + - gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag + - m68k: Update ->thread.esp0 before calling syscall_trace() in ret_from_signal + - m68k: Add missing mmap_read_lock() to sys_cacheflush() + - signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die + - net: xen-netback: hash.c: Use built-in RCU list checking + - net/xen-netback: prevent UAF in xenvif_flush_hash() + - vfio/platform: check the bounds of read/write syscalls + - ext4: avoid ext4_error()'s caused by ENOMEM in the truncate path + - ext4: fix slab-use-after-free in ext4_split_extent_at() + - USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb() + - Revert "usb: gadget: u_serial: Disable ep before setting port to null to fix + the crash caused by port being null" + - Input: atkbd - map F23 key to support default copilot shortcut + - Input: xpad - add unofficial Xbox 360 wireless receiver clone + - Input: xpad - add support for wooting two he (arm) + - drm/v3d: Assign job pointer to NULL before signaling the fence + - xhci: use pm_ptr() instead of #ifdef for CONFIG_PM conditionals + - Partial revert of xhci: use pm_ptr() instead #ifdef for CONFIG_PM + conditionals + - Linux 5.4.290 + * CVE-2021-47219 + - scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs() + * CVE-2024-49925 + - fbdev: efifb: Register sysfs groups through driver core + * CVE-2024-56614 + - xsk: fix OOB map writes when deleting elements + * net: stmmac: kernel continually prints wol unbalance irq warning + (LP: #2095376) + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + * CVE-2024-44938 + - jfs: Fix shift-out-of-bounds in dbDiscardAG + * CVE-2024-43900 + - media: xc2028: avoid use-after-free in load_firmware_cb() + * Focal update: v5.4.289 upstream stable release (LP: #2095437) + - usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with + iommu enabled + - PCI/AER: Disable AER service on suspend + - ALSA: usb: Fix UBSAN warning in parse_audio_unit() + - PCI: Add ACS quirk for Broadcom BCM5760X NIC + - i2c: pnx: Fix timeout in wait functions + - drm/i915: Fix memory leak by correcting cache object name in error handler + - erofs: fix order >= MAX_ORDER warning due to crafted negative i_size + - erofs: fix incorrect symlink detection in fast symlink + - net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll + - ionic: use ee->offset when returning sprom data + - net: hinic: Fix cleanup in create_rxqs/txqs() + - net: ethernet: bgmac-platform: fix an OF node reference leak + - netfilter: ipset: Fix for recursive locking warning + - mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk + - chelsio/chtls: prevent potential integer overflow on 32bit + - i2c: riic: Always round-up when calculating bus period + - efivarfs: Fix error on non-existent file + - USB: serial: option: add TCL IK512 MBIM & ECM + - USB: serial: option: add MeiG Smart SLM770A + - USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready + - USB: serial: option: add MediaTek T7XX compositions + - USB: serial: option: add Telit FE910C04 rmnet compositions + - sh: clk: Fix clk_enable() to return 0 on NULL clk + - zram: refuse to use zero sized block device as backing device + - btrfs: tree-checker: reject inline extent items with 0 ref count + - NFS/pnfs: Fix a live lock between recalled layouts and layoutget + - of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one() + - nilfs2: prevent use of deleted inode + - udmabuf: also check for F_SEAL_FUTURE_WRITE + - of: Fix error path in of_parse_phandle_with_args_map() + - of: Fix refcount leakage for OF node returned by __of_get_dma_parent() + - media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg + - bpf: Check negative offsets in __bpf_skb_min_len() + - nfsd: restore callback functionality for NFSv4.0 + - mtd: diskonchip: Cast an operand to prevent potential overflow + - phy: core: Fix an OF node refcount leakage in _of_phy_get() + - phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() + - phy: core: Fix that API devm_phy_put() fails to release the phy + - phy: core: Fix that API devm_phy_destroy() fails to destroy the phy + - dmaengine: mv_xor: fix child node refcount handling in early exit + - dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset + - mtd: rawnand: fix double free in atmel_pmecc_create_user() + - tracing/kprobe: Make trace_kprobe's module callback called after jump_label + update + - scsi: qla1280: Fix hw revision numbering for ISP1020/1040 + - scsi: megaraid_sas: Fix for a potential deadlock + - regmap: Use correct format specifier for logging range errors + - platform/x86: asus-nb-wmi: Ignore unknown event 0xCF + - scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load + time + - virtio-blk: don't keep queue frozen during system suspend + - epoll: Add synchronous wakeup support for ep_poll_callback + - MIPS: Probe toolchain support of -msym32 + - ipv6: use skb_expand_head in ip6_finish_output2 + - ipv6: use skb_expand_head in ip6_xmit + - ipv6: fix possible UAF in ip6_finish_output2() + - bpf: fix recursive lock when verdict program return SK_PASS + - tracing: Constify string literal data member in struct trace_event_call + - btrfs: avoid monopolizing a core when activating a swap file + - ipv6: prevent possible UAF in ip6_xmit() + - selinux: ignore unknown extended permissions + - Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet + - IB/mlx5: Introduce and use mlx5_core_is_vf() + - net/mlx5: Make API mlx5_core_is_ecpf accept const pointer + - RDMA/mlx5: Enforce same type port association for multiport RoCE + - RDMA/bnxt_re: Add check for path mtu in modify_qp + - RDMA/bnxt_re: Fix reporting hw_ver in query_device + - RDMA/bnxt_re: Fix max_qp_wrs reported + - drm: bridge: adv7511: Enable SPDIF DAI + - drm/bridge: adv7511_audio: Update Audio InfoFrame properly + - netrom: check buffer length before accessing it + - netfilter: Replace zero-length array with flexible-array member + - netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext + - net: llc: reset skb->transport_header + - ALSA: usb-audio: US16x08: Initialize array before use + - af_packet: fix vlan_get_tci() vs MSG_PEEK + - af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK + - ila: serialize calls to nf_register_net_hooks() + - wifi: mac80211: wake the queues in case of failure in resume + - sound: usb: format: don't warn that raw DSD is unsupported + - bpf: fix potential error return + - net: usb: qmi_wwan: add Telit FE910C04 compositions + - irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base + - ARC: build: Try to guess GCC variant of cross compiler + - modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host + - modpost: fix the missed iteration for the max bit in do_input() + - RDMA/uverbs: Prevent integer overflow issue + - pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking + - sky2: Add device ID 11ab:4373 for Marvell 88E8075 + - net/sctp: Prevent autoclose integer overflow in sctp_association_init() + - drm: adv7511: Drop dsi single lane support + - mm: vmscan: account for free pages to prevent infinite Loop in + throttle_direct_reclaim() + - ftrace: use preempt_enable/disable notrace macros to avoid double fault + - Linux 5.4.289 + * Focal update: v5.4.289 upstream stable release (LP: #2095437) // + CVE-2024-38588 + - ftrace: Fix possible use-after-free issue in ftrace_location() + * Focal update: v5.4.288 upstream stable release (LP: #2095199) + - usb: host: max3421-hcd: Correctly abort a USB request. + - ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys() + - usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature + - usb: ehci-hcd: fix call balance of clocks handling routines + - usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to + accessing null pointer + - xfs: don't drop errno values when we fail to ficlone the entire range + - bpf, sockmap: Fix update element with same + - batman-adv: Do not send uninitialized TT changes + - batman-adv: Remove uninitialized data in full table TT response + - batman-adv: Do not let TT changes list grows indefinitely + - tipc: fix NULL deref in cleanup_bearer() + - net: lapb: increase LAPB_HEADER_LEN + - ACPI: resource: Fix memory resource type union access + - qca_spi: Fix clock speed for multiple QCA7000 + - qca_spi: Make driver probing reliable + - net/sched: netem: account for backlog updates from child qdisc + - ACPICA: events/evxfregn: don't release the ContextMutex that was never + acquired + - blk-iocost: clamp inuse and skip noops in __propagate_weights() + - blk-iocost: fix weight updates of inner active iocgs + - blk-iocost: Avoid using clamp() on inuse in __propagate_weights() + - KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status + - tracing/kprobes: Skip symbol counting logic for module symbols in + create_local_trace_kprobe() + - xen/netfront: fix crash when removing device + - ALSA: usb-audio: Fix a DMA to stack memory bug + - Linux 5.4.288 + * Focal update: v5.4.287 upstream stable release (LP: #2095145) + - netlink: terminate outstanding dump on socket close + - net/mlx5: fs, lock FTE when checking if active + - net/mlx5e: kTLS, Fix incorrect page refcounting + - ocfs2: uncache inode which has failed entering the group + - KVM: VMX: Bury Intel PT virtualization (guest/host mode) behind + CONFIG_BROKEN + - nilfs2: fix null-ptr-deref in block_touch_buffer tracepoint + - ocfs2: fix UBSAN warning in ocfs2_verify_volume() + - nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint + - Revert "mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K" + - media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set + - kbuild: Use uname for LINUX_COMPILE_HOST detection + - mm: revert "mm: shmem: fix data-race in shmem_getattr()" + - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet + - mac80211: fix user-power when emulating chanctx + - selftests/watchdog-test: Fix system accidentally reset after watchdog-test + - ALSA: hda/realtek: Add subwoofer quirk for Infinix ZERO BOOK 13 + - x86/amd_nb: Fix compile-testing without CONFIG_AMD_NB + - net: usb: qmi_wwan: add Quectel RG650V + - soc: qcom: Add check devm_kasprintf() returned value + - regulator: rk808: Add apply_bit for BUCK3 on RK809 + - ASoC: stm: Prevent potential division by zero in stm32_sai_mclk_round_rate() + - ASoC: stm: Prevent potential division by zero in stm32_sai_get_clk_div() + - proc/softirqs: replace seq_printf with seq_put_decimal_ull_width + - ipmr: Fix access to mfc_cache_list without lock held + - cifs: Fix buffer overflow when parsing NFS reparse points + - NFSD: Force all NFSv4.2 COPY requests to be synchronous + - nvme: fix metadata handling in nvme-passthrough + - mips: asm: fix warning when disabling MIPS_FP_SUPPORT + - initramfs: avoid filename buffer overrun + - nvme-pci: fix freeing of the HMB descriptor table + - m68k: mvme147: Fix SCSI controller IRQ numbers + - m68k: mvme16x: Add and use "mvme16x.h" + - m68k: mvme147: Reinstate early console + - acpi/arm64: Adjust error handling procedure in gtdt_parse_timer_block() + - s390/syscalls: Avoid creation of arch/arch/ directory + - hfsplus: don't query the device logical block size multiple times + - firmware: google: Unregister driver_info on failure and exit in gsmi + - firmware: google: Unregister driver_info on failure + - EDAC/bluefield: Fix potential integer overflow + - EDAC/fsl_ddr: Fix bad bit shift operations + - crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return + -EBUSY + - crypto: cavium - Fix the if condition to exit loop after timeout + - crypto: bcm - add error check in the ahash_hmac_init function + - crypto: cavium - Fix an error handling path in cpt_ucode_load_fw() + - time: Fix references to _msecs_to_jiffies() handling of values + - soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq() + - soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get() + - mmc: mmc_spi: drop buggy snprintf() + - efi/tpm: Pass correct address to memblock_reserve + - tpm: fix signed/unsigned bug when checking event logs + - ARM: dts: cubieboard4: Fix DCDC5 regulator constraints + - regmap: irq: Set lockdep class for hierarchical IRQ domains + - firmware: arm_scpi: Check the DVFS OPP count returned by the firmware + - drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused + - wifi: ath9k: add range check for conn_rsp_epid in htc_connect_service() + - drm/omap: Fix locking in omap_gem_new_dmabuf() + - wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq() + - wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq() + - drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq() + - dt-bindings: vendor-prefixes: Add NeoFidelity, Inc + - ASoC: fsl_micfil: Drop unnecessary register read + - ASoC: fsl_micfil: do not define SHIFT/MASK for single bits + - ASoC: fsl_micfil: use GENMASK to define register bit fields + - ASoC: fsl_micfil: fix regmap_write_bits usage + - bpf: Fix the xdp_adjust_tail sample prog issue + - wifi: mwifiex: Fix memcpy() field-spanning write warning in + mwifiex_config_scan() + - drm/panfrost: Remove unused id_mask from struct panfrost_model + - drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq() + - drm/etnaviv: dump: fix sparse warnings + - drm/etnaviv: fix power register offset on GC300 + - drm/etnaviv: hold GPU lock across perfmon sampling + - bpf, sockmap: Several fixes to bpf_msg_push_data + - bpf, sockmap: Several fixes to bpf_msg_pop_data + - bpf, sockmap: Fix sk_msg_reset_curr + - selftests: net: really check for bg process completion + - net: rfkill: gpio: Add check for clk_enable() + - ALSA: us122l: Use snd_card_free_when_closed() at disconnection + - ALSA: caiaq: Use snd_card_free_when_closed() at disconnection + - ALSA: 6fire: Release resources at card release + - netpoll: Use rcu_access_pointer() in netpoll_poll_lock + - trace/trace_event_perf: remove duplicate samples on the first tracepoint + event + - powerpc/vdso: Flag VDSO64 entry points as functions + - mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race + - mfd: da9052-spi: Change read-mask to write-mask + - mfd: intel_soc_pmic_bxtwc: Use dev_err_probe() + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices + - cpufreq: loongson2: Unregister platform_driver on failure + - mtd: rawnand: atmel: Fix possible memory leak + - RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey + - mfd: rt5033: Fix missing regmap_del_irq_chip() + - scsi: bfa: Fix use-after-free in bfad_im_module_exit() + - scsi: fusion: Remove unused variable 'rc' + - scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb() + - scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb() + - ocfs2: fix uninitialized value in ocfs2_file_read_iter() + - powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static + - fbdev/sh7760fb: Alloc DMA memory from hardware device + - fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem() + - dt-bindings: clock: adi,axi-clkgen: convert old binding to yaml format + - dt-bindings: clock: axi-clkgen: include AXI clk + - clk: axi-clkgen: use devm_platform_ioremap_resource() short-hand + - clk: clk-axi-clkgen: make sure to enable the AXI bus clock + - perf cs-etm: Don't flush when packet_queue fills up + - perf probe: Correct demangled symbols in C++ program + - PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads + - PCI: cpqphp: Fix PCIBIOS_* return value confusion + - m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x + - m68k: coldfire/device.c: only build FEC when HW macros are defined + - perf trace: Do not lose last events in a race + - perf trace: Avoid garbage when not printing a syscall's arguments + - rpmsg: glink: Add TX_DATA_CONT command while sending + - rpmsg: glink: Send READ_NOTIFY command in FIFO full case + - rpmsg: glink: Fix GLINK command prefix + - rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length + - NFSD: Prevent NULL dereference in nfsd4_process_cb_update() + - NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir() + - NFSD: Fix nfsd4_shutdown_copy() + - vfio/pci: Properly hide first-in-list PCIe extended capability + - power: supply: core: Remove might_sleep() from power_supply_put() + - net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device + - tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets + - net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL + configuration + - marvell: pxa168_eth: fix call balance of pep->clk handling routines + - net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken + - ipmr: convert /proc handlers to rcu_read_lock() + - ipmr: fix tables suspicious RCU usage + - usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read() + - usb: yurex: make waiting on yurex_write interruptible + - USB: chaoskey: fail open after removal + - USB: chaoskey: Fix possible deadlock chaoskey_list_lock + - misc: apds990x: Fix missing pm_runtime_disable() + - staging: greybus: uart: clean up TIOCGSERIAL + - apparmor: fix 'Do simple duplicate message elimination' + - usb: ehci-spear: fix call balance of sehci clk handling routines + - cgroup: Make operations on the cgroup root_list RCU safe + - cgroup: Move rcu_head up near the top of cgroup_root + - soc: qcom: socinfo: fix revision check in qcom_socinfo_probe() + - ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox + devices + - ext4: supress data-race warnings in ext4_free_inodes_{count,set}() + - ext4: fix FS_IOC_GETFSMAP handling + - jfs: xattr: check invalid xattr size more strictly + - ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata() + - PCI: Fix use-after-free of slot->bus on hot remove + - comedi: Flush partial mappings in error case + - tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler + - Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}() + - Revert "usb: gadget: composite: fix OS descriptors w_value logic" + - serial: sh-sci: Clean sci_ports[0] after at earlycon exit + - Revert "serial: sh-sci: Clean sci_ports[0] after at earlycon exit" + - spi: Fix acpi deferred irq probe + - ubi: wl: Put source PEB into correct list if trying locking LEB failed + - um: ubd: Do not use drvdata in release + - um: net: Do not use drvdata in release + - serial: 8250: omap: Move pm_runtime_get_sync + - um: vector: Do not use drvdata in release + - sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled + - block: fix ordering between checking BLK_MQ_S_STOPPED request adding + - HID: wacom: Interpret tilt data from Intuos Pro BT as signed values + - media: wl128x: Fix atomicity violation in fmc_send_cmd() + - ALSA: hda/realtek: Update ALC225 depop procedure + - ALSA: hda/realtek: Set PCBeep to default value for ALC274 + - ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max + - ALSA: hda/realtek: Apply quirk for Medion E15433 + - usb: dwc3: gadget: Fix checking for number of TRBs left + - lib: string_helpers: silence snprintf() output truncation warning + - NFSD: Prevent a potential integer overflow + - SUNRPC: make sure cache entry active before cache_show + - rpmsg: glink: Propagate TX failures in intentless mode as well + - um: Fix potential integer overflow during physmem setup + - um: Fix the return value of elf_core_copy_task_fpregs + - um/sysrq: remove needless variable sp + - um: add show_stack_loglvl() + - um: Clean up stacktrace dump + - um: Always dump trace for specified task in show_stack + - NFSv4.0: Fix a use-after-free problem in the asynchronous open() + - rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq() + - rtc: abx80x: Fix WDT bit position of the status register + - rtc: check if __rtc_read_time was successful in rtc_timer_do_work() + - ubifs: Correct the total block count by deducting journal reservation + - ubi: fastmap: Fix duplicate slab cache names while attaching + - ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit + - jffs2: fix use of uninitialized variable + - block: return unsigned int from bdev_io_min + - 9p/xen: fix init sequence + - 9p/xen: fix release of IRQ + - rtc: ab-eoz9: don't fail temperature reads on undervoltage notification + - modpost: remove incorrect code in do_eisa_entry() + - SUNRPC: correct error code comment in xs_tcp_setup_socket() + - SUNRPC: Replace internal use of SOCKWQ_ASYNC_NOSPACE + - sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport + - sh: intc: Fix use-after-free bug in register_intc_controller() + - ASoC: fsl_micfil: fix the naming style for mask definition + - quota: flush quota_release_work upon quota writeback + - btrfs: ref-verify: fix use-after-free after invalid ref action + - media: i2c: tc358743: Fix crash in the probe error path when using polling + - media: ts2020: fix null-ptr-deref in ts2020_probe() + - media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled + - media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate() + - media: platform: allegro-dvt: Fix possible memory leak in + allocate_buffers_internal() + - ovl: Filter invalid inodes with missing lookup function + - ftrace: Fix regression with module command in stack_trace_filter + - clk: qcom: gcc-qcs404: fix initial rate of GPLL3 + - ad7780: fix division by zero in ad7780_write_raw() + - util_macros.h: fix/rework find_closest() macros + - i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs() + - dm thin: Add missing destroy_work_on_stack() + - nfsd: make sure exp active before svc_export_show + - nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur + - drm/etnaviv: flush shader L1 cache after user commandstream + - iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call + - watchdog: mediatek: Make sure system reset gets asserted in + mtk_wdt_restart() + - can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL + - can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics + - ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init() + - netfilter: x_tables: fix LED ID check in led_tg_check() + - net/sched: tbf: correct backlog statistic for GSO packets + - can: j1939: j1939_session_new(): fix skb reference counting + - net/ipv6: release expired exception dst cached in socket + - dccp: Fix memory leak in dccp_feat_change_recv + - tipc: add reference counter to bearer + - tipc: enable creating a "preliminary" node + - tipc: add new AEAD key structure for user API + - tipc: Fix use-after-free of kernel socket in cleanup_bearer(). + - net/qed: allow old cards not supporting "num_images" to work + - igb: Fix potential invalid memory access in igb_init_module() + - netfilter: ipset: Hold module reference while requesting a module + - netfilter: nft_set_hash: skip duplicated elements pending gc run + - xen/xenbus: reference count registered modules + - xenbus/backend: Add memory pressure handler callback + - xenbus/backend: Protect xenbus callback with lock + - xen/xenbus: fix locking + - xen: Fix the issue of resource not being properly released in + xenbus_dev_probe() + - x86/asm: Reorder early variables + - crypto: x86/aegis128 - access 32-bit arguments as 32-bit + - gpio: grgpio: use a helper variable to store the address of ofdev->dev + - gpio: grgpio: Add NULL check in grgpio_probe + - drm/sti: Add __iomem for mixer_dbg_mxn's parameter + - tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg + - spi: mpc52xx: Add cancel_work_sync before module remove + - ocfs2: free inode when ocfs2_get_init_inode() fails + - bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie + - bpf: Fix exact match conditions in trie_get_next_key() + - HID: wacom: fix when get product name maybe null pointer + - tracing: Fix cmp_entries_dup() to respect sort() comparison rules + - ocfs2: update seq_file index in ocfs2_dlm_seq_next + - scsi: qla2xxx: Fix NVMe and NPIV connect issue + - scsi: qla2xxx: Supported speed displayed incorrectly for VPorts + - scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt + - nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry() + - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again + - dma-buf: fix dma_fence_array_signaled v4 + - regmap: detach regmap from dev on regmap_exit + - mmc: core: Further prevent card detect during shutdown + - s390/cpum_sf: Handle CPU hotplug remove during sampling + - media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera + - media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108 + - drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model + - drm/mcde: Enable module autoloading + - drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check() + - samples/bpf: Fix a resource leak + - net: fec_mpc52xx_phy: Use %pa to format resource_size_t + - net: ethernet: fs_enet: Use %pa to format resource_size_t + - net/sched: cbs: Fix integer overflow in cbs_set_port_rate() + - af_packet: avoid erroring out after sock_init_data() in packet_create() + - Bluetooth: L2CAP: do not leave dangling sk pointer on error in + l2cap_sock_create() + - net: af_can: do not leave a dangling sk pointer in can_create() + - net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() + - net: inet: do not leave a dangling sk pointer in inet_create() + - net: inet6: do not leave a dangling sk pointer in inet6_create() + - wifi: ath5k: add PCI ID for SX76X + - wifi: ath5k: add PCI ID for Arcadyan devices + - jfs: array-index-out-of-bounds fix in dtReadFirst + - jfs: fix shift-out-of-bounds in dbSplit + - jfs: fix array-index-out-of-bounds in jfs_readdir + - jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree + - drm/amdgpu: set the right AMDGPU sg segment limitation + - wifi: ipw2x00: libipw_rx_any(): fix bad alignment + - wifi: brcmfmac: Fix oops due to NULL pointer dereference in + brcmf_sdiod_sglist_rw() + - Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables + - ASoC: hdmi-codec: reorder channel allocation list + - rocker: fix link status detection in rocker_carrier_init() + - net/neighbor: clear error in case strict check is not set + - netpoll: Use rcu_access_pointer() in __netpoll_setup + - tracing: Use atomic64_inc_return() in trace_clock_counter() + - leds: class: Protect brightness_show() with led_cdev->led_access mutex + - scsi: st: Don't modify unknown block number in MTIOCGET + - scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset + - pinctrl: qcom-pmic-gpio: add support for PM8937 + - nvdimm: rectify the illogical code within nd_dax_probe() + - f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode. + - PCI: Add 'reset_subordinate' to reset hierarchy below bridge + - PCI: Add ACS quirk for Wangxun FF5xxx NICs + - i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to + avoid deadlock + - usb: chipidea: udc: handle USB Error Interrupt if IOC not set + - powerpc/prom_init: Fixup missing powermac #size-cells + - misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle + - xdp: Simplify devmap cleanup + - bpf: fix OOB devmap writes when deleting elements + - Revert "unicode: Don't special case ignorable code points" + - perf/x86/intel/pt: Fix buffer full but size is 0 case + - KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* + - KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device + - KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE + - jffs2: Prevent rtime decompress memory corruption + - jffs2: Fix rtime decompressor + - ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume" + - modpost: Add .irqentry.text to OTHER_SECTIONS + - Revert "drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()" + - PCI: rockchip-ep: Fix address translation unit programming + - ALSA: usb-audio: Fix out of bounds reads when finding clock sources + - bpf, xdp: Update devmap comments to reflect napi/rcu usage + - Linux 5.4.287 + * CVE-2024-23848 + - media: cec: abort if the current transmit was canceled + - media: cec: core: avoid recursive cec_claim_log_addrs + - media: cec: core: avoid confusing "transmit timed out" message + + [ Ubuntu: 5.4.0-208.228 ] + + * CVE-2025-0927 + - SAUCE: fs: hfs/hfsplus: add key_len boundary check to hfs_bnode_read_key + + -- Philip Cox Thu, 20 Feb 2025 08:46:16 -0500 + +linux-oracle (5.4.0-1138.147) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1138.147 -proposed tracker (LP: #2093780) + + * Add list of source files to linux-buildinfo (LP: #2086606) + - [Packaging] Add dwarfdump package to Build-Depends + + * Focal update: v5.4.285 upstream stable release (LP: #2089233) + - [Config] Disable SND_MESON_CARD_UTILS + + [ Ubuntu: 5.4.0-207.227 ] + + * focal/linux: 5.4.0-207.227 -proposed tracker (LP: #2095347) + * Remove "ftrace: Fix possible use-after-free issue in ftrace_location()" bad + commit from focal (LP: #2095348) + - Revert "ftrace: Fix possible use-after-free issue in ftrace_location()" + + [ Ubuntu: 5.4.0-206.226 ] + + * focal/linux: 5.4.0-206.226 -proposed tracker (LP: #2093785) + * nouveau keeps showing `disp: ctrl 00000080` and crippling the system + (LP: #2078011) + - drm/nouveau/disp/gv100-: halt NV_PDISP_FE_RM_INTR_STAT_CTRL_DISP_ERROR + storms + - drm/nouveau/kms/gv100-: move window ownership setup into modesetting path + - drm/nouveau/kms/gv100-: avoid sending a core update until the first modeset + * CVE-2024-43863 + - drm/vmwgfx: Fix a deadlock in dma buf fence polling + * CVE-2024-40911 + - wifi: cfg80211: Lock wiphy in cfg80211_get_station + * CVE-2024-35896 + - netfilter: validate user input for expected length + - netfilter: complete validation of user input + * CVE-2023-52458 + - block: add check that partition length needs to be aligned with block size + * kernel:nft "Could not process rule: Device or resource busy" on unreferenced + chain (LP: #2089699) + - SAUCE: netfilter: nf_tables: Fix EBUSY on deleting unreferenced chain + * CVE-2024-35887 + - lockdep: Add preemption enabled/disabled assertion APIs + - timers: Don't block on ->expiry_lock for TIMER_IRQSAFE timers + - Documentation: Remove bogus claim about del_timer_sync() + - ARM: spear: Do not use timer namespace for timer_shutdown() function + - clocksource/drivers/arm_arch_timer: Do not use timer namespace for + timer_shutdown() function + - clocksource/drivers/sp804: Do not use timer namespace for timer_shutdown() + function + - timers: Get rid of del_singleshot_timer_sync() + - timers: Replace BUG_ON()s + - timers: Rename del_timer() to timer_delete() + - Documentation: Replace del_timer/del_timer_sync() + - timers: Silently ignore timers with a NULL function + - timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown mode + - timers: Add shutdown mechanism to the internal functions + - timers: Provide timer_shutdown[_sync]() + - timers: Update the documentation to reflect on the new timer_shutdown() API + - ax25: fix use-after-free bugs caused by ax25_ds_del_timer + * CVE-2024-40965 + - clk: Add a devm variant of clk_rate_exclusive_get() + - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get() + - i2c: lpi2c: Avoid calling clk_get_rate during transfer + * CVE-2024-40982 + - ssb: Fix potential NULL pointer dereference in ssb_device_uevent() + * CVE-2024-41066 + - ibmvnic: Add tx check to prevent skb leak + * CVE-2024-42252 + - closures: Change BUG_ON() to WARN_ON() + * CVE-2024-46731 + - drm/amd/pm: fix the Out-of-bounds read warning + * Focal update: v5.4.286 upstream stable release (LP: #2089558) + - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire- + excavator + - arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328 + - arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards + - arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion + - ARM: dts: rockchip: fix rk3036 acodec node + - ARM: dts: rockchip: drop grf reference from rk3036 hdmi + - ARM: dts: rockchip: Fix the spi controller on rk3036 + - ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin + - enetc: simplify the return expression of enetc_vf_set_mac_addr() + - net: enetc: set MAC address to the VF net_device + - can: c_can: fix {rx,tx}_errors statistics + - media: stb0899_algo: initialize cfr before using it + - media: dvb_frontend: don't play tricks with underflow values + - media: adv7604: prevent underflow condition when reporting colorspace + - ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init() + - pwm: imx-tpm: Use correct MODULO value for EPWM mode + - drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported + - dm cache: correct the number of origin blocks to match the target length + - dm cache: optimize dirty bit checking with find_next_bit when resizing + - dm-unstriped: cast an operand to sector_t to prevent potential uint32_t + overflow + - mtd: rawnand: protect access to rawnand devices while in suspend + - spi: fix use-after-free of the add_lock mutex + - media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in + uvc_parse_format + - fs/proc: fix compile warning about variable 'vmcore_mmap_ops' + - USB: serial: qcserial: add support for Sierra Wireless EM86xx + - USB: serial: option: add Fibocom FG132 0x0112 composition + - USB: serial: option: add Quectel RG650V + - irqchip/gic-v3: Force propagation of the active state with a read-back + - ALSA: usb-audio: Support jack detection on Dell dock + - ALSA: usb-audio: Add quirks for Dell WD19 dock + - NFSD: Fix NFSv4's PUTPUBFH operation + - ALSA: usb-audio: Add endianness annotations + - 9p: Avoid creating multiple slab caches with the same name + - HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad + - bpf: use kvzmalloc to allocate BPF verifier environment + - sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML + - powerpc/powernv: Free name on error in opal_event_init() + - fs: Fix uninitialized value issue in from_kuid and from_kgid + - net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition + - md/raid10: improve code of mrdev in raid10_sync_request + - mm: clarify a confusing comment for remap_pfn_range() + - mm: fix ambiguous comments for better code readability + - mm/memory.c: make remap_pfn_range() reject unaligned addr + - mm: add remap_pfn_range_notrack + - 9p: fix slab cache name creation for real + - Linux 5.4.286 + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-47674 + - mm: avoid leaving partial pfn mappings around in error case + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-38588 + - ftrace: Fix possible use-after-free issue in ftrace_location() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50265 + - ocfs2: remove entry once instead of null-ptr-dereference in + ocfs2_xa_remove() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50267 + - USB: serial: io_edgeport: fix use after free in debug printk + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50269 + - usb: musb: sunxi: Fix accessing an released usb phy + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2021-47469 + - spi: Fix deadlock when adding SPI controllers on SPI buses + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50273 + - btrfs: reinitialize delayed ref list after deleting it from the list + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53066 + - nfs: Fix KMSAN warning in decode_getfattr_attrs() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50278 + - dm cache: fix potential out-of-bounds access on the first resume + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50279 + - dm cache: fix out-of-bounds access to the dirty bitset when resizing + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50282 + - drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50287 + - media: v4l2-tpg: prevent the risk of a division by zero + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50290 + - media: cx24116: prevent overflows on SNR calculus + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53061 + - media: s5p-jpeg: prevent buffer overflows + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53063 + - media: dvbdev: prevent the risk of out of memory access + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50296 + - net: hns3: fix kernel crash when uninstalling driver + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50299 + - sctp: properly validate chunk size in sctp_sf_ootb() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50301 + - security/keys: fix slab-out-of-bounds in key_task_permission + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50302 + - HID: core: zero-initialize the report buffer + * Add list of source files to linux-buildinfo (LP: #2086606) + - [Packaging] Sort build dependencies alphabetically + - [Packaging] Add list of used source files to buildinfo package + * Focal update: v5.4.285 upstream stable release (LP: #2089233) + - usbnet: ipheth: fix carrier detection in modes 1 and 4 + - net: ethernet: use ip_hdrlen() instead of bit shift + - net: phy: vitesse: repair vsc73xx autonegotiation + - scripts: kconfig: merge_config: config files: add a trailing newline + - arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399 + Puma + - ice: fix accounting for filters shared by multiple VSIs + - net/mlx5e: Add missing link modes to ptys2ethtool_map + - net: ftgmac100: Enable TX interrupt to avoid TX timeout + - soundwire: stream: Revert "soundwire: stream: fix programming slave ports + for non-continous port maps" + - selftests: breakpoints: Fix a typo of function name + - ASoC: allow module autoloading for table db1200_pids + - ALSA: hda/realtek - Fixed ALC256 headphone no sound + - ALSA: hda/realtek - FIxed ALC285 headphone no sound + - pinctrl: at91: make it work with current gpiolib + - microblaze: don't treat zero reserved memory regions as error + - net: ftgmac100: Ensure tx descriptor updates are visible + - wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room() + - ASoC: tda7419: fix module autoloading + - drm: komeda: Fix an issue related to normalized zpos + - spi: bcm63xx: Enable module autoloading + - x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency + - USB: serial: pl2303: add device id for Macrosilicon MS3020 + - ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe() + - wifi: ath9k: fix parameter check in ath9k_init_debug() + - wifi: ath9k: Remove error checks when creating debugfs entries + - fs: explicitly unregister per-superblock BDIs + - mount: warn only once about timestamp range expiration + - fs/namespace: fnic: Switch to use %ptTd + - mount: handle OOM on mnt_warn_timestamp_expiry + - can: j1939: use correct function name in comment + - netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire + - netfilter: nf_tables: reject element expiration with no timeout + - netfilter: nf_tables: reject expiration higher than timeout + - wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan() + - wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors + - mac80211: parse radiotap header when selecting Tx queue + - Bluetooth: btusb: Fix not handling ZPL/short-transfer + - net: tipc: avoid possible garbage value + - block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator() + - block, bfq: don't break merge chain in bfq_split_bfqq() + - spi: ppc4xx: handle irq_of_parse_and_map() errors + - spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ + - ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property + - ARM: versatile: fix OF node leak in CPUs prepare + - reset: berlin: fix OF node leak in probe() error path + - clocksource/drivers/qcom: Add missing iounmap() on errors in + msm_dt_timer_init() + - hwmon: (max16065) Fix overflows seen when writing limits + - mtd: slram: insert break after errors in parsing the map + - hwmon: (ntc_thermistor) fix module autoloading + - power: supply: axp20x_battery: allow disabling battery charging + - power: supply: axp20x_battery: Remove design from min and max voltage + - power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense + - fbdev: hpfb: Fix an error handling path in hpfb_dio_probe() + - mtd: powernv: Add check devm_kasprintf() returned value + - drm/stm: Fix an error handling path in stm_drm_platform_probe() + - drm/amdgpu: Replace one-element array with flexible-array member + - drm/amdgpu: properly handle vbios fake edid sizing + - drm/radeon: Replace one-element array with flexible-array member + - drm/radeon: properly handle vbios fake edid sizing + - drm/rockchip: vop: Allow 4096px width scaling + - drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode + - drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets + - drm/msm: Fix incorrect file name output in adreno_request_fw() + - drm/msm/a5xx: disable preemption in submits by default + - drm/msm/a5xx: properly clear preemption records on resume + - drm/msm/a5xx: fix races in preemption evaluation stage + - ipmi: docs: don't advertise deprecated sysfs entries + - drm/msm: fix %s null argument error + - drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind() + - xen: use correct end address of kernel for conflict checking + - xen/swiotlb: add alignment check for dma buffers + - selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c + - selftests/bpf: Fix compiling flow_dissector.c with musl-libc + - selftests/bpf: Fix compiling tcp_rtt.c with musl-libc + - selftests/bpf: Fix error compiling test_lru_map.c + - xz: cleanup CRC32 edits from 2018 + - kthread: add kthread_work tracepoints + - kthread: fix task state in kthread worker if being frozen + - ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard + - smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso + - ext4: avoid negative min_clusters in find_group_orlov() + - ext4: return error on ext4_find_inline_entry + - nilfs2: determine empty node blocks as corrupted + - bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit + - perf sched timehist: Fix missing free of session in perf_sched__timehist() + - perf sched timehist: Fixed timestamp error when unable to confirm event + sched_in time + - perf time-utils: Fix 32-bit nsec parsing + - clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228 + - PCI: xilinx-nwl: Fix register misspelling + - pinctrl: single: fix missing error code in pcs_probe() + - clk: ti: dra7-atl: Fix leak of of_nodes + - pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function + - watchdog: imx_sc_wdt: Don't disable WDT in suspend + - RDMA/hns: Optimize hem allocation performance + - riscv: Fix fp alignment bug in perf_callchain_user() + - f2fs: enhance to update i_mode and acl atomically in f2fs_setattr() + - f2fs: fix typo + - f2fs: fix to update i_ctime in __f2fs_setxattr() + - f2fs: remove unneeded check condition in __f2fs_setxattr() + - f2fs: reduce expensive checkpoint trigger frequency + - iio: adc: ad7606: fix oversampling gpio array + - iio: adc: ad7606: fix standby gpio state to match the documentation + - coresight: tmc: sg: Do not leak sg_table + - net: qrtr: Update packets cloning when broadcasting + - netfilter: ctnetlink: compile ctnetlink_label_size with + CONFIG_NF_CONNTRACK_EVENTS + - Remove *.orig pattern from .gitignore + - soc: versatile: integrator: fix OF node leak in probe() error path + - drm/amd/display: Round calculated vtotal + - USB: appledisplay: close race between probe and completion handler + - USB: misc: cypress_cy7c63: check for short transfer + - USB: class: CDC-ACM: fix race between get_serial and set_serial + - tty: rp2: Fix reset with non forgiving PCIe host bridges + - drbd: Fix atomicity violation in drbd_uuid_set_bm() + - drbd: Add NULL check for net_conf to prevent dereference in state validation + - ACPI: resource: Add another DMI match for the TongFang GMxXGxx + - wifi: rtw88: 8822c: Fix reported RX band width + - debugobjects: Fix conditions in fill_pool() + - f2fs: prevent possible int overflow in dir_block_index() + - f2fs: avoid potential int overflow in sanity_check_area_boundary() + - hwrng: mtk - Use devm_pm_runtime_enable + - fs: Fix file_set_fowner LSM hook inconsistencies + - nfs: fix memory leak in error path of nfs4_do_reclaim + - ASoC: meson: axg: extract sound card utils + - [Config] updateconfigs for SND_MESON_CARD_UTILS + - PCI: xilinx-nwl: Use irq_data_get_irq_chip_data() + - PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler + - soc: versatile: realview: fix memory leak during device remove + - soc: versatile: realview: fix soc_dev leak during device remove + - usb: yurex: Replace snprintf() with the safer scnprintf() variant + - USB: misc: yurex: fix race between read and write + - pps: remove usage of the deprecated ida_simple_xx() API + - pps: add an error check in parport_attach + - mm: only enforce minimum stack gap size if it's sensible + - i2c: aspeed: Update the stop sw state when the bus recovery occurs + - i2c: isch: Add missed 'else' + - usb: yurex: Fix inconsistent locking bug in yurex_read() + - mailbox: rockchip: fix a typo in module autoloading + - Minor fixes to the CAIF Transport drivers Kconfig file + - drivers: net: Fix Kconfig indentation, continued + - ieee802154: Fix build error + - net/mlx5: Added cond_resched() to crdump collection + - netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED + - net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq() + - Bluetooth: btmrvl_sdio: Refactor irq wakeup + - Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq() + - ipv4: ip_gre: Fix drops of small packets in ipgre_xmit + - ALSA: hda/realtek: Fix the push button function for the ALC257 + - ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs + - ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin + - wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats() + - ice: Adjust over allocation of memory in ice_sched_add_root_node() and + ice_sched_add_node() + - net: hisilicon: hip04: fix OF node leak in probe() + - net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info() + - net: hisilicon: hns_mdio: fix OF node leak in probe() + - ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails + - ACPICA: Fix memory leak if acpi_ps_get_next_field() fails + - net: sched: consistently use rcu_replace_pointer() in taprio_change() + - wifi: rtw88: select WANT_DEV_COREDUMP + - ACPI: EC: Do not release locks during operation region accesses + - net: mvpp2: Increase size of queue_name buffer + - ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR). + - ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family + - tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process + - ACPICA: iasl: handle empty connection_node + - proc: add config & param to block forcing mem writes + - [Config] updateconfigs to select PROC_MEM_ALWAYS_FORCE + - nfp: Use IRQF_NO_AUTOEN flag in request_irq() + - signal: Replace BUG_ON()s + - ALSA: hdsp: Break infinite MIDI input flush loop + - x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments() + - power: reset: brcmstb: Do not go into infinite loop if reset fails + - ata: sata_sil: Rename sil_blacklist to sil_quirks + - jfs: UBSAN: shift-out-of-bounds in dbFindBits + - drm/printer: Allow NULL data in devcoredump printer + - scsi: aacraid: Rearrange order of struct aac_srb_unit + - drm/radeon/r100: Handle unknown family in r100_cp_init_microcode() + - of/irq: Refer to actual buffer size in of_irq_parse_one() + - ext4: ext4_search_dir should return a proper error + - spi: s3c64xx: fix timeout counters in flush_fifo + - selftests: breakpoints: use remaining time to check if suspend succeed + - selftests: vDSO: fix vDSO symbols lookup for powerpc64 + - i2c: xiic: Wait for TX empty to avoid missed TX NAKs + - firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp() + - spi: bcm63xx: Fix module autoloading + - perf/core: Fix small negative period being ignored + - parisc: Fix itlb miss handler for 64-bit programs + - drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS + - ALSA: core: add isascii() check to card ID generator + - ext4: propagate errors from ext4_find_extent() in ext4_insert_range() + - ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space() + - ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit() + - parisc: Fix 64-bit userspace syscall path + - parisc: Fix stack start for ADDR_NO_RANDOMIZE personality + - of/irq: Support #msi-cells=<0> in of_msi_get_domain + - mm: krealloc: consider spare memory for __GFP_ZERO + - ocfs2: fix the la space leak when unmounting an ocfs2 volume + - ocfs2: fix uninit-value in ocfs2_get_block() + - riscv: define ILLEGAL_POINTER_VALUE for 64bit + - clk: rockchip: fix error for unknown clocks + - media: sun4i_csi: Implement link validate for sun4i_csi subdev + - media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags + - iio: magnetometer: ak8975: Fix reading for ak099xx sensors + - tomoyo: fallback to realpath if symlink's pathname does not exist + - rtc: at91sam9: fix OF node leak in probe() error path + - Input: adp5589-keys - fix adp5589_gpio_get_value() + - ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[] + - ACPI: resource: Add Asus ExpertBook B2502CVA to + irq1_level_low_skip_override[] + - gpio: davinci: fix lazy disable + - i2c: qcom-geni: Let firmware specify irq trigger flags + - i2c: qcom-geni: Grow a dev pointer to simplify code + - i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq() + - arm64: Add Cortex-715 CPU part definition + - arm64: cputype: Add Neoverse-N3 definitions + - arm64: errata: Expand speculative SSBS workaround once more + - nfsd: use ktime_get_seconds() for timestamps + - nfsd: fix delegation_blocked() to block correctly for at least 30 seconds + - clk: qcom: rpmh: Simplify clk_rpmh_bcm_send_cmd() + - clk: qcom: clk-rpmh: Fix overflow in BCM vote + - r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun" + - ACPI: battery: Simplify battery hook locking + - ext4: fix inode tree inconsistency caused by ENOMEM + - net: ethernet: cortina: Drop TSO support + - tracing: Remove precision vsnprintf() check from print event + - drm/crtc: fix uninitialized variable use even harder + - tracing: Have saved_cmdlines arrays all in one allocation + - virtio_console: fix misc probe bugs + - Input: synaptics-rmi4 - fix UAF of IRQ domain on driver removal + - bpf: Check percpu map value size first + - s390/facility: Disable compile time optimization for decompressor code + - s390/mm: Add cond_resched() to cmm_alloc/free_pages() + - ext4: nested locking for xattr inode + - s390/cpum_sf: Remove WARN_ON_ONCE statements + - ktest.pl: Avoid false positives with grub2 skip regex + - clk: bcm: bcm53573: fix OF node leak in init + - PCI: Add ACS quirk for Qualcomm SA8775P + - i2c: i801: Use a different adapter-name for IDF adapters + - PCI: Mark Creative Labs EMU20k2 INTx masking as broken + - media: videobuf2-core: clear memory related fields in + __vb2_plane_dmabuf_put() + - usb: chipidea: udc: enable suspend interrupt after usb reset + - usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the + Crashkernel Scenario + - tools/iio: Add memory allocation failure check for trigger_name + - driver core: bus: Return -EIO instead of 0 when show/store invalid bus + attribute + - ice: fix VLAN replay after reset + - SUNRPC: Fix integer overflow in decode_rc_list() + - tcp: fix to allow timestamp undo if no retransmits were sent + - tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe + - gpio: aspeed: Add the flush write to ensure the write complete. + - gpio: aspeed: Use devm_clk api to manage clock source + - net: ibm: emac: mal: fix wrong goto + - net: annotate lockless accesses to sk->sk_ack_backlog + - net: annotate lockless accesses to sk->sk_max_ack_backlog + - sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start + - locking/lockdep: Fix bad recursion pattern + - locking/lockdep: Rework lockdep_lock + - locking/lockdep: Avoid potential access of invalid memory in lock_class + - lockdep: fix deadlock issue between lockdep and rcu + - HID: plantronics: Workaround for an unexcepted opposite volume key + - Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant" + - usb: dwc3: core: Stop processing of pending events if controller is halted + - usb: xhci: Fix problem with xhci resume from suspend + - usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip + - hid: intel-ish-hid: Fix uninitialized variable 'rv' in + ish_fw_xfer_direct_dma + - arm64: probes: Fix simulate_ldr*_literal() + - tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols + - tracing/kprobes: Fix symbol counting logic by looking at modules as well + - PCI: Add function 0 DMA alias quirk for Glenfly Arise chip + - fat: fix uninitialized variable + - s390/sclp_vt220: Convert newlines to CRLF instead of LFCR + - KVM: s390: Change virtual to physical address access in diag 0x258 handler + - x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET + - drm/vmwgfx: Handle surface check failure correctly + - iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig + - iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig + - iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - iio: hid-sensors: Fix an error handling path in + _hid_sensor_set_report_latency() + - iio: light: opt3001: add missing full-scale range value + - iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - Bluetooth: Remove debugfs directory on module init failure + - Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001 + - xhci: Fix incorrect stream context type macro + - USB: serial: option: add support for Quectel EG916Q-GL + - USB: serial: option: add Telit FN920C04 MBIM compositions + - x86/resctrl: Annotate get_mem_config() functions as __init + - x86/apic: Always explicitly disarm TSC-deadline timer + - mac80211: Fix NULL ptr deref for injected rate info + - RDMA/bnxt_re: Fix incorrect AVID type in WQE structure + - ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin + - RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP + - ipv4: give an IPv4 dev to blackhole_netdev + - RDMA/bnxt_re: Return more meaningful error + - drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation + - macsec: don't increment counters for an unrelated SA + - net: ethernet: aeroflex: fix potential memory leak in + greth_start_xmit_gbit() + - genetlink: hold RCU in genlmsg_mcast() + - arm64:uprobe fix the uprobe SWBP_INSN in big-endian + - KVM: s390: gaccess: Check if guest address is in memslot + - jfs: Fix sanity check in dbMount + - net: usb: usbnet: fix name regression + - r8169: avoid unsolicited interrupts + - posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime() + - ALSA: hda/realtek: Update default depop procedure + - ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[] + - ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid + detection issue + - ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593 + - hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event + - selinux: improve error checking in sel_write_load() + - arm64/uprobes: change the uprobe_opcode_t typedef to fix the sparse warning + - cgroup: Fix potential overflow issue when checking max_depth + - wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys + - mac80211: do drv_reconfig_complete() before restarting all + - mac80211: Add support to trigger sta disconnect on hardware restart + - wifi: iwlwifi: mvm: disconnect station vifs if recovery failed + - ASoC: cs42l51: Fix some error handling paths in cs42l51_probe() + - dt-bindings: gpu: Convert Samsung Image Rotator to dt-schema + - gtp: simplify error handling code in 'gtp_encap_enable()' + - gtp: allow -1 to be specified as file description from userspace + - net: support ip generic csum processing in skb_csum_hwoffload_help + - net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension + - drivers/misc: ti-st: Remove unneeded variable in st_tty_open + - firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state() + - net: amd: mvme147: Fix probe banner message + - misc: sgi-gru: Don't disable preemption in GRU driver + - usbip: tools: Fix detach_port() invalid port error path + - usb: phy: Fix API devm_usb_put_phy() can not release the phy + - xhci: Fix Link TRB DMA in command ring stopped completion event + - Revert "driver core: Fix uevent_show() vs driver detach race" + - riscv: Remove unused GENERATING_ASM_OFFSETS + - Revert "drm/mipi-dsi: Set the fwnode for mipi_dsi_device" + - vt: prevent kernel-infoleak in con_font_get() + - mac80211: always have ieee80211_sta_restart() + - mm: krealloc: Fix MTE false alarm in __do_krealloc + - Linux 5.4.285 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50228 + - mm: shmem: fix data-race in shmem_getattr() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50230 + - nilfs2: fix kernel bug due to missing clearing of checked flag + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50218 + - ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50229 + - nilfs2: fix potential deadlock with newly created symlinks + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50233 + - staging: iio: frequency: ad9832: fix division by zero in + ad9832_calc_freqreg() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50234 + - wifi: iwlegacy: Clear stale interrupts before resuming device + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50236 + - wifi: ath10k: Fix memory leak in management tx + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50237 + - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50251 + - netfilter: nft_payload: sanitize offset and length before calling + skb_checksum() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50262 + - bpf: Fix out-of-bounds write in trie_get_next_key() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-53059 + - wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50142 + - xfrm: validate new SA's prefixlen using SA family when sel.family is unset + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50116 + - nilfs2: fix kernel bug due to missing clearing of buffer delay flag + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50117 + - drm/amd: Guard against bad data for ATIF ACPI method + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50205 + - ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50127 + - net: sched: fix use-after-free in taprio_change() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50167 + - be2net: fix potential memory leak in be_xmit() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50168 + - net/sun3_82586: fix potential memory leak in sun3_82586_send_packet() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50131 + - tracing: Consider the NULL character when validating the event length + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50143 + - udf: fix uninit-value use in udf_get_fileshortad + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50134 + - drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real + VLA + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50194 + - arm64: probes: Fix uprobes for big-endian kernels + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50148 + - Bluetooth: bnep: fix wild-memory-access in proto_unregister + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50150 + - usb: typec: altmode should keep reference to parent + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50151 + - smb: client: fix OOBs when building SMB2_IOCTL request + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50171 + - net: systemport: fix potential memory leak in bcm_sysport_xmit() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50202 + - nilfs2: propagate directory read errors from nilfs_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50074 + - parport: Proper fix for array out-of-bounds access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50082 + - blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-40953 + - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50199 + - mm/swapfile: skip HugeTLB pages for unuse_vma + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50099 + - arm64: probes: Remove broken LDR (literal) uprobe support + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50195 + - posix-clock: Fix missing timespec64 check in pc_clock_settime() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50096 + - nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50024 + - net: Fix an unsafe loop on the list + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49878 + - resource: fix region_intersects() vs add_memory_driver_managed() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50033 + - slip: make slhc_remember() more robust against malicious packets + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50035 + - ppp: fix ppp_async_encode() illegal access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50039 + - net/sched: accept TCA_STAB only for root qdisc + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50040 + - igb: Do not bring the device up after non-fatal error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50044 + - Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50045 + - netfilter: br_netfilter: fix panic with metadata_dst skb + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-38544 + - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50180 + - fbdev: sisfb: Fix strbuf array overflow + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50184 + - virtio_pmem: Check device status before requesting flush + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50059 + - ntb: ntb_hw_switchtec: Fix use after free vulnerability in + switchtec_ntb_remove due to race condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50089 + - unicode: Don't special case ignorable code points + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49955 + - ACPI: battery: Fix possible crash when unregistering a battery hook + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49973 + - r8169: add tally counter fields added with RTL8125 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49975 + - uprobes: fix kernel info leak via "[uprobes]" vma + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49867 + - btrfs: wait for fixup workers before stopping cleaner kthread during umount + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49868 + - btrfs: fix a NULL pointer dereference when failed to start a new trasacntion + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49981 + - media: venus: fix use after free bug in venus_remove due to race condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49982 + - aoe: fix the potential use-after-free problem in more places + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49877 + - ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49957 + - ocfs2: fix null-ptr-deref when journal load failed. + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49965 + - ocfs2: remove unreasonable unlock in ocfs2_read_blocks + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49966 + - ocfs2: cancel dqi_sync_work before freeing oinfo + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49958 + - ocfs2: reserve space for inline xattr before attaching reflink tree + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49959 + - jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49879 + - drm: omapdrm: Add missing check for alloc_ordered_workqueue + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49882 + - ext4: fix double brelse() the buffer of the extents path + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49883 + - ext4: aovid use-after-free in ext4_ext_insert_extent() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49985 + - i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50006 + - ext4: fix i_data_sem unlock order in ext4_ind_migrate() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49892 + - drm/amd/display: Initialize get_bytes_per_element's default to 1 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49894 + - drm/amd/display: Fix index out of bounds in degamma hardware format + translation + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49896 + - drm/amd/display: Check stream before comparing them + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49900 + - jfs: Fix uninit-value access of new_ea in ea_buffer + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49902 + - jfs: check if leafidx greater than num leaves per dmap tree + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49903 + - jfs: Fix uaf in dbFreeBits + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49924 + - fbdev: pxafb: Fix possible use after free in pxafb_task() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50007 + - ALSA: asihpi: Fix potential OOB array access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50008 + - wifi: mwifiex: Fix memcpy() field-spanning write warning in + mwifiex_cmd_802_11_scan_ext() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49995 + - tipc: guard against string buffer overrun + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49962 + - ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in + acpi_db_convert_to_package() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49938 + - wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47740 + - f2fs: Require FMODE_WRITE for atomic write ioctls + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49944 + - sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49948 + - net: add more sanity checks to qdisc_pkt_len_init() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49949 + - net: avoid potential underflow in qdisc_pkt_len_init() with UFO + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49997 + - net: ethernet: lantiq_etop: fix memory disclosure + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49952 + - netfilter: nf_tables: prevent nf_skb_duplicated corruption + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50179 + - ceph: remove the incorrect Fw reference check when dirtying pages + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49963 + - mailbox: bcm2835: Fix timeout during suspend mode + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46849 + - ASoC: meson: axg-card: fix 'use-after-free' + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47679 + - vfs: fix race between evice_inodes() and find_inode()&iput() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49860 + - ACPI: sysfs: validate return type of _STR method + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47742 + - firmware_loader: Block path traversal + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47684 + - tcp: check skb is non-NULL in tcp_rto_delta_us() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47747 + - net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race + Condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47685 + - netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47692 + - nfsd: return -EINVAL when namelen is 0 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47737 + - nfsd: call cache_put if xdr_reserve_space returns NULL + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2023-52917 + - ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47749 + - RDMA/cxgb4: Added NULL check for lookup_atid + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47696 + - RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47756 + - PCI: keystone: Fix if-statement expression in ks_pcie_quirk() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47697 + - drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47698 + - drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47757 + - nilfs2: fix potential oob read in nilfs_btree_check_delete() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47699 + - nilfs2: fix potential null-ptr-deref in nilfs_btree_insert() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47701 + - ext4: avoid OOB when system.data xattr changes underneath the filesystem + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49851 + - tpm: Clean up TPM space after command failure + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47723 + - jfs: fix out-of-bounds in dbNextAG() and diAlloc() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47706 + - block, bfq: fix possible UAF for bfqq->bic with merge chain + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47709 + - can: bcm: Clear bo->bcm_proc_read after remove_proc_entry(). + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47710 + - sock_map: Add a cond_resched() in sock_hash_free() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47712 + - wifi: wilc1000: fix potential RCU dereference issue in + wilc_parse_join_bss_param + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47713 + - wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47671 + - USB: usbtmc: prevent kernel-usb-infoleak + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-44931 + - gpio: prevent potential speculation leaks in gpio_device_get_desc() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-41016 + - ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47670 + - ocfs2: add bounds checking to ocfs2_xattr_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47672 + - wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46853 + - spi: nxp-fspi: fix the KASAN report out-of-bounds bug + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46854 + - net: dpaa: Pad packets to ETH_ZLEN + + -- Vinicius Peixoto Mon, 27 Jan 2025 11:56:28 -0300 + +linux-oracle (5.4.0-1137.146) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1137.146 -proposed tracker (LP: #2093616) + + [ Ubuntu: 5.4.0-205.225 ] + + * focal/linux: 5.4.0-205.225 -proposed tracker (LP: #2093621) + * Hold IOPOLL locks when triggering io_uring's deferred work (LP: #2078659) // + CVE-2023-21400 + - io_uring: remove extra check in __io_commit_cqring + - io_uring: dont kill fasync under completion_lock + - io_uring: ensure IOPOLL locks around deferred work + * CVE-2024-40967 + - iopoll: introduce read_poll_timeout macro + - iopoll: Introduce read_poll_timeout_atomic macro + - serial: imx: Introduce timeout when waiting on transmitter empty + * CVE-2024-53164 + - net: sched: fix ordering of qlen adjustment + * CVE-2024-53141 + - netfilter: ipset: add missing range check in bitmap_ip_uadt + * CVE-2024-53103 + - hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer + + -- Philip Cox Fri, 17 Jan 2025 14:19:39 -0500 + +linux-oracle (5.4.0-1136.145) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1136.145 -proposed tracker (LP: #2090081) + + [ Ubuntu: 5.4.0-204.224 ] + + * focal/linux: 5.4.0-204.224 -proposed tracker (LP: #2091090) + * CVE-2024-50264 + - vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans + * CVE-2024-53057 + - net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT + * CVE-2024-49967 + - ext4: no need to continue when the number of entries is 1 + * CVE-2024-43892 + - memcg: protect concurrent access to mem_cgroup_idr + * CVE-2024-38553 + - net: fec: remove .ndo_poll_controller to avoid deadlocks + * CVE-2024-38597 + - eth: sungem: remove .ndo_poll_controller to avoid deadlocks + * CVE-2023-52821 + - drm/panel: fix a possible null pointer dereference + * CVE-2024-36952 + - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up + * CVE-2024-40910 + - ax25: Fix refcount imbalance on inbound connections + * CVE-2024-35963 + - Bluetooth: hci_sock: Fix not validating setsockopt user input + * CVE-2024-35965 + - Bluetooth: L2CAP: uninitialized variables in l2cap_sock_setsockopt() + - Bluetooth: L2CAP: Fix not validating setsockopt user input + * CVE-2024-35966 + - Bluetooth: RFCOMM: Fix not validating setsockopt user input + * CVE-2024-35967 + - Bluetooth: SCO: Fix not validating setsockopt user input + * CVE-2021-47101 + - net: asix: fix uninit value bugs + - asix: fix wrong return value in asix_check_host_enable() + - asix: fix uninit-value in asix_mdio_read() + * CVE-2022-38096 + - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts + * CVE-2021-47001 + - xprtrdma: Fix cwnd update ordering + + -- Philip Cox Fri, 06 Dec 2024 08:16:15 -0500 + +linux-oracle (5.4.0-1135.144) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1135.144 -proposed tracker (LP: #2086446) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + [ Ubuntu: 5.4.0-202.222 ] + + * focal/linux: 5.4.0-202.222 -proposed tracker (LP: #2086451) + - [Packaging] resync git-ubuntu-log + * CVE-2021-47501 + - i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc + * CVE-2024-46724 + - drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number + * CVE-2024-42240 + - x86/bhi: Avoid warning in #DB handler due to BHI mitigation + * CVE-2024-42077 + - ocfs2: fix DIO failure due to insufficient transaction credits + * CVE-2024-42068 + - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro() + * CVE-2024-36968 + - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() + * CVE-2024-35904 + - selinux: avoid dereference of garbage after mount failure + * CVE-2023-52498 + - PM: sleep: Avoid calling put_device() under dpm_list_mtx + - PM: sleep: Fix error handling in dpm_prepare() + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - PM: sleep: Fix possible deadlocks in core system-wide PM code + * CVE-2023-52488 + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + * CVE-2022-48938 + - CDC-NCM: avoid overflow in sanity checking + * CVE-2024-42156 + - s390/pkey: Wipe copies of clear-key structures on failure + * CVE-2024-44942 + - f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC + * CVE-2024-38538 + - net: bridge: xmit: make sure we have at least eth header len bytes + * CVE-2021-47076 + - RDMA/rxe: Return CQE error if invalid lkey was supplied + * CVE-2024-36938 + - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue + * CVE-2024-44940 + - fou: remove warn in gue_gro_receive on unsupported protocol + * CVE-2024-35951 + - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + * CVE-2023-52497 + - erofs: fix lz4 inplace decompression + * CVE-2024-36953 + - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr() + * CVE-2022-48943 + - KVM: x86/mmu: make apf token non-zero to fix bug + * CVE-2024-26947 + - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses + * CVE-2022-48733 + - btrfs: fix use-after-free after failure to create a snapshot + * CVE-2023-52639 + - KVM: s390: vsie: fix race during shadow creation + + -- Philip Cox Tue, 12 Nov 2024 13:42:03 -0500 + +linux-oracle (5.4.0-1134.143) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1134.143 -proposed tracker (LP: #2082931) + + [ Ubuntu: 5.4.0-200.220 ] + + * focal/linux: 5.4.0-200.220 -proposed tracker (LP: #2082937) + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/2024.09.30) + * CVE-2024-26800 + - tls: rx: coalesce exit paths in tls_decrypt_sg() + - tls: separate no-async decryption request handling from async + - tls: fix use-after-free on failed backlog decryption + * CVE-2024-26641 + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + * CVE-2021-47212 + - net/mlx5: Update error handler for UCTX and UMEM + * wbt:wbt_* trace event NULL pointer dereference with GENHD_FL_HIDDEN disks + (LP: #2081085) + - bdi: use bdi_dev_name() to get device name + * Focal update: v5.4.284 upstream stable release (LP: #2081278) + - drm: panel-orientation-quirks: Add quirk for OrangePi Neo + - i2c: Fix conditional for substituting empty ACPI functions + - net: usb: qmi_wwan: add MeiG Smart SRM825L + - drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr + - drm/amdgpu: fix overflowed array index read warning + - drm/amd/display: Check gpio_id before used as array index + - drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6 + - drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[] + - drm/amd/display: Fix Coverity INTEGER_OVERFLOW within + dal_gpio_service_create + - drm/amdgpu: fix ucode out-of-bounds read warning + - drm/amdgpu: fix mc_data out-of-bounds read warning + - drm/amdkfd: Reconcile the definition and use of oem_id in struct + kfd_topology_device + - apparmor: fix possible NULL pointer dereference + - ionic: fix potential irq name truncation + - usbip: Don't submit special requests twice + - usb: typec: ucsi: Fix null pointer dereference in trace + - smack: tcp: ipv4, fix incorrect labeling + - wifi: cfg80211: make hash table duplicates more survivable + - drm/amd/display: Skip wbscl_set_scaler_filter if filter is null + - media: uvcvideo: Enforce alignment of frame and interval + - block: initialize integrity buffer to zero before writing it to media + - net: set SOCK_RCU_FREE before inserting socket into hashtable + - virtio_net: Fix napi_skb_cache_put warning + - udf: Limit file size to 4TB + - i2c: Use IS_REACHABLE() for substituting empty ACPI functions + - sch/netem: fix use after free in netem_dequeue + - ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object + - ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius + devices + - ata: libata: Fix memory leak for error path in ata_host_alloc() + - irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init() + - mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K + - mmc: sdhci-of-aspeed: fix module autoloading + - fuse: update stats for pages in dropped aux writeback list + - fuse: use unsigned type for getxattr/listxattr size truncation + - reset: hi6220: Add support for AO reset controller + - clk: hi6220: use CLK_OF_DECLARE_DRIVER + - clk: qcom: clk-alpha-pll: Fix the pll post div mask + - clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API + - ila: call nf_unregister_net_hooks() sooner + - sched: sch_cake: fix bulk flow accounting logic for host fairness + - nilfs2: fix missing cleanup on rollforward recovery error + - nilfs2: fix state management in error path of log writing function + - ALSA: hda: Add input value sanity checks to HDMI channel map controls + - smack: unix sockets: fix accept()ed socket label + - irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1 + - af_unix: Remove put_pid()/put_cred() in copy_peercred(). + - netfilter: nf_conncount: fix wrong variable type + - udf: Avoid excessive partition lengths + - wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3 + - usb: uas: set host status byte on data completion error + - PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0) + - media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse + - pcmcia: Use resource_size function on resource object + - can: bcm: Remove proc entry when dev is unregistered. + - igb: Fix not clearing TimeSync interrupts for 82580 + - platform/x86: dell-smbios: Fix error path in dell_smbios_init() + - tcp_bpf: fix return value of tcp_bpf_sendmsg() + - cx82310_eth: re-enable ethernet mode after router reboot + - drivers/net/usb: Remove all strcpy() uses + - net: usb: don't write directly to netdev->dev_addr + - usbnet: modern method to get random MAC + - net: bridge: fdb: convert is_local to bitops + - net: bridge: fdb: convert is_static to bitops + - net: bridge: fdb: convert is_sticky to bitops + - net: bridge: fdb: convert added_by_user to bitops + - net: bridge: fdb: convert added_by_external_learn to use bitops + - net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN + - net: dsa: vsc73xx: fix possible subblocks range of CAPT block + - ASoC: topology: Properly initialize soc_enum values + - dm init: Handle minors larger than 255 + - iommu/vt-d: Handle volatile descriptor status read + - cgroup: Protect css->cgroup write under css_set_lock + - um: line: always fill *error_out in setup_one_line() + - devres: Initialize an uninitialized struct member + - pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv + - hwmon: (adc128d818) Fix underflows seen when writing limit attributes + - hwmon: (lm95234) Fix underflows seen when writing limit attributes + - hwmon: (nct6775-core) Fix underflows seen when writing limit attributes + - hwmon: (w83627ehf) Fix underflows seen when writing limit attributes + - libbpf: Add NULL checks to bpf_object__{prev_map,next_map} + - wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id() + - smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu() + - btrfs: replace BUG_ON with ASSERT in walk_down_proc() + - btrfs: clean up our handling of refs == 0 in snapshot delete + - PCI: Add missing bridge lock to pci_bus_lock() + - btrfs: initialize location to fix -Wmaybe-uninitialized in + btrfs_lookup_dentry() + - HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup + - Input: uinput - reject requests with unreasonable number of slots + - usbnet: ipheth: race between ipheth_close and error handling + - Squashfs: sanity check symbolic link size + - of/irq: Prevent device address out-of-bounds read in interrupt map walk + - lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc() + - ata: pata_macio: Use WARN instead of BUG + - NFSv4: Add missing rescheduling points in + nfs_client_return_marked_delegations + - staging: iio: frequency: ad9834: Validate frequency parameter value + - iio: buffer-dmaengine: fix releasing dma channel on error + - iio: fix scale application in iio_convert_raw_to_processed_unlocked + - binder: fix UAF caused by offsets overwrite + - nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc + - uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind + - Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic + - VMCI: Fix use-after-free when removing resource in vmci_resource_remove() + - clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX + - clocksource/drivers/imx-tpm: Fix next event not taking effect sometime + - clocksource/drivers/timer-of: Remove percpu irq related code + - uprobes: Use kzalloc to allocate xol area + - ring-buffer: Rename ring_buffer_read() to read_buffer_iter_advance() + - tracing: Avoid possible softlockup in tracing_iter_reset() + - nilfs2: replace snprintf in show functions with sysfs_emit + - nilfs2: protect references to superblock parameters exposed in sysfs + - ACPI: processor: Return an error if acpi_processor_get_info() fails in + processor_add() + - ACPI: processor: Fix memory leaks in error paths of processor_add() + - arm64: acpi: Move get_cpu_for_acpi_id() to a header + - arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry + - nvmet-tcp: fix kernel crash if commands allocation fails + - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused + - drm/i915/fence: Mark debug_fence_free() with __maybe_unused + - rtmutex: Drop rt_mutex::wait_lock before scheduling + - net, sunrpc: Remap EPERM in case of connection failure in + xs_tcp_setup_socket + - cx82310_eth: fix error return code in cx82310_bind() + - Linux 5.4.284 + * CVE-2024-42244 + - USB: serial: mos7840: fix crash on resume + * CVE-2024-40929 + - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids + * CVE-2024-41073 + - nvme: avoid double free special payload + * CVE-2024-41071 + - wifi: mac80211: Avoid address calculations via out of bounds array indexing + * CVE-2024-42229 + - crypto: aead, cipher - zeroize key buffer after use + * CVE-2024-38611 + - media: i2c: et8ek8: Don't strip remove function when driver is builtin + * CVE-2024-38602 + - ax25: Fix reference count leak issues of ax25_dev + * CVE-2024-35848 + - misc: eeprom: at24: fix regulator underflow + - misc: eeprom: at24: register nvmem only after eeprom is ready to use + - eeprom: at24: fix memory corruption race condition + * CVE-2024-26669 + - net/sched: flower: Fix chain template offload + * CVE-2024-26668 + - netfilter: nft_limit: rename stateful structure + - netfilter: nft_limit: reject configurations that cause integer overflow + * CVE-2024-26640 + - net-zerocopy: Refactor frag-is-remappable test. + - tcp: add sanity checks to rx zerocopy + * CVE-2024-26607 + - drm/bridge: sii902x: Fix probing race issue + * CVE-2023-52614 + - PM / devfreq: Fix buffer overflow in trans_stat_show + * CVE-2023-52531 + - wifi: iwlwifi: mvm: Fix a memory corruption issue + * CVE-2022-36402 + - drm/vmwgfx: Use enum to represent graphics context capabilities + - drm/vmwgfx: Fix shader stage validation + * Focal update: v5.4.283 upstream stable release (LP: #2080595) + - fuse: Initialize beyond-EOF page contents before setting uptodate + - ALSA: usb-audio: Support Yamaha P-125 quirk entry + - xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration + - s390/dasd: fix error recovery leading to data corruption on ESE devices + - arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to + NUMA_NO_NODE + - dm resume: don't return EINVAL when signalled + - dm persistent data: fix memory allocation failure + - vfs: Don't evict inode under the inode lru traversing context + - bitmap: introduce generic optimized bitmap_size() + - fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE + - selinux: fix potential counting error in avc_add_xperms_decision() + - drm/amdgpu: Actually check flags for all context ops. + - memcg_write_event_control(): fix a user-triggerable oops + - overflow.h: Add flex_array_size() helper + - overflow: Implement size_t saturating arithmetic helpers + - s390/cio: rename bitmap_size() -> idset_bitmap_size() + - btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits() + - s390/uv: Panic for set and remove shared access UVC errors + - net/mlx5e: Correctly report errors for ethtool rx flows + - atm: idt77252: prevent use after free in dequeue_rx() + - net: axienet: Fix DMA descriptor cleanup path + - net: axienet: Improve DMA error handling + - net: axienet: Factor out TX descriptor chain cleanup + - net: axienet: Check for DMA mapping errors + - net: axienet: Drop MDIO interrupt registers from ethtools dump + - net: axienet: Wrap DMA pointer writes to prepare for 64 bit + - net: axienet: Upgrade descriptors to hold 64-bit addresses + - net: axienet: Autodetect 64-bit DMA capability + - net: axienet: Fix register defines comment description + - net: dsa: vsc73xx: pass value in phy_write operation + - net: hns3: fix a deadlock problem when config TC during resetting + - ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7 + - ssb: Fix division by zero issue in ssb_calc_clock_rate + - wifi: cw1200: Avoid processing an invalid TIM IE + - i2c: riic: avoid potential division by zero + - media: radio-isa: use dev_name to fill in bus_info + - staging: ks7010: disable bh on tx_dev_lock + - binfmt_misc: cleanup on filesystem umount + - scsi: spi: Fix sshdr use + - gfs2: setattr_chown: Add missing initialization + - wifi: iwlwifi: abort scan when rfkill on but device enabled + - IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock + - powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu + - nvmet-trace: avoid dereferencing pointer too early + - ext4: do not trim the group with corrupted block bitmap + - quota: Remove BUG_ON from dqget() + - media: pci: cx23885: check cx23885_vdev_init() return + - fs: binfmt_elf_efpic: don't use missing interpreter's properties + - scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list() + - net/sun3_82586: Avoid reading past buffer in debug output + - drm/lima: set gp bus_stop bit before hard reset + - virtiofs: forbid newlines in tags + - md: clean up invalid BUG_ON in md_ioctl + - x86: Increase brk randomness entropy for 64-bit systems + - powerpc/boot: Handle allocation failure in simple_realloc() + - powerpc/boot: Only free if realloc() succeeds + - btrfs: change BUG_ON to assertion when checking for delayed_node root + - btrfs: handle invalid root reference found in may_destroy_subvol() + - btrfs: send: handle unexpected data in header buffer in begin_cmd() + - btrfs: delete pointless BUG_ON check on quota root in + btrfs_qgroup_account_extent() + - f2fs: fix to do sanity check in update_sit_entry + - usb: gadget: fsl: Increase size of name buffer for endpoints + - nvme: clear caller pointer on identify failure + - Bluetooth: bnep: Fix out-of-bound access + - nvmet-tcp: do not continue for invalid icreq + - NFS: avoid infinite loop in pnfs_update_layout. + - openrisc: Call setup_memory() earlier in the init sequence + - s390/iucv: fix receive buffer virtual vs physical address confusion + - usb: dwc3: core: Skip setting event buffers for host only controllers + - irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc + - ext4: set the type of max_zeroout to unsigned int to avoid overflow + - nvmet-rdma: fix possible bad dereference when freeing rsps + - hrtimer: Prevent queuing of hrtimer without a function callback + - gtp: pull network headers in gtp_dev_xmit() + - block: use "unsigned long" for blk_validate_block_size(). + - media: solo6x10: replace max(a, min(b, c)) by clamp(b, a, c) + - dm mpath: pass IO start time to path selector + - dm: do not use waitqueue for request-based DM + - dm suspend: return -ERESTARTSYS instead of -EINTR + - Bluetooth: Make use of __check_timeout on hci_sched_le + - Bluetooth: hci_core: Fix not handling link timeouts propertly + - Bluetooth: hci_core: Fix LE quote calculation + - tc-testing: don't access non-existent variable on exception + - kcm: Serialise kcm_sendmsg() for the same socket. + - netfilter: nft_counter: Synchronize nft_counter_reset() against reader. + - net: dsa: mv88e6xxx: global2: Expose ATU stats register + - net: dsa: mv88e6xxx: global1_atu: Add helper for get next + - net: dsa: mv88e6xxx: read FID when handling ATU violations + - net: dsa: mv88e6xxx: replace ATU violation prints with trace points + - net: dsa: mv88e6xxx: Fix out-of-bound access + - ipv6: prevent UAF in ip6_send_skb() + - net: xilinx: axienet: Always disable promiscuous mode + - net: xilinx: axienet: Fix dangling multicast addresses + - drm/msm: use drm_debug_enabled() to check for debug categories + - drm/msm/dpu: don't play tricks with debug macros + - mmc: mmc_test: Fix NULL dereference on allocation failure + - Bluetooth: MGMT: Add error handling to pair_device() + - HID: wacom: Defer calculation of resolution until resolution_code is known + - HID: microsoft: Add rumble support to latest xbox controllers + - cxgb4: add forgotten u64 ivlan cast before shift + - mmc: dw_mmc: allow biu and ciu clocks to defer + - ALSA: timer: Relax start tick time check for slave timer elements + - Input: MT - limit max slots + - tools: move alignment-related macros to new + - pinctrl: single: fix potential NULL dereference in pcs_get_function() + - wifi: mwifiex: duplicate static structs used in driver instances + - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages + - filelock: Correct the filelock owner in fcntl_setlk/fcntl_setlk64 + - media: uvcvideo: Fix integer overflow calculating timestamp + - ata: libata-core: Fix null pointer dereference on error + - cgroup/cpuset: Prevent UAF in proc_cpuset_show() + - net:rds: Fix possible deadlock in rds_message_put + - soundwire: stream: fix programming slave ports for non-continous port maps + - r8152: Factor out OOB link list waits + - ethtool: check device is present when getting link settings + - gtp: fix a potential NULL pointer dereference + - net: busy-poll: use ktime_get_ns() instead of local_clock() + - nfc: pn533: Add dev_up/dev_down hooks to phy_ops + - nfc: pn533: Add autopoll capability + - nfc: pn533: Add poll mod list filling check + - soc: qcom: cmd-db: Map shared memory as WC, not WB + - cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller + - USB: serial: option: add MeiG Smart SRM825L + - usb: dwc3: omap: add missing depopulate in probe error path + - usb: dwc3: core: Prevent USB core invalid event buffer address access + - usb: dwc3: st: fix probed platform device ref count on probe error path + - usb: dwc3: st: add missing depopulate in probe error path + - usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in + remove_power_attributes() + - net: dsa: mv8e6xxx: Fix stub function parameters + - scsi: aacraid: Fix double-free on probe failure + - Linux 5.4.283 + * CVE-2024-27051 + - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value + - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations + * CVE-2024-26891 + - PCI: Make pci_dev_is_disconnected() helper public for other drivers + - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected + * Focal update: v5.4.282 upstream stable release (LP: #2078388) + - EDAC, skx_common: Refactor so that we initialize "dev" in result of adxl + decode. + - EDAC, skx: Retrieve and print retry_rd_err_log registers + - EDAC/skx_common: Add new ADXL components for 2-level memory + - EDAC, i10nm: make skx_common.o a separate module + - platform/chrome: cros_ec_debugfs: fix wrong EC message version + - hfsplus: fix to avoid false alarm of circular locking + - x86/of: Return consistent error type from x86_of_pci_irq_enable() + - x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling + - x86/pci/xen: Fix PCIBIOS_* return code handling + - x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos + - hwmon: (adt7475) Fix default duty on fan is disabled + - pwm: stm32: Always do lazy disabling + - hwmon: (max6697) Fix underflow when writing limit attributes + - hwmon: (max6697) Fix swapped temp{1,8} critical alarms + - arm64: dts: qcom: sdm845: add power-domain to UFS PHY + - arm64: dts: qcom: msm8996: specify UFS core_clk frequencies + - arm64: dts: rockchip: Increase VOP clk rate on RK3328 + - ARM: dts: imx6qdl-kontron-samx6i: move phy reset into phy-node + - ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset + - ARM: dts: imx6qdl-kontron-samx6i: fix board reset + - ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity + - arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux + - arm64: dts: amlogic: gx: correct hdmi clocks + - m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages + - x86/xen: Convert comma to semicolon + - m68k: cmpxchg: Fix return value for default case in __arch_xchg() + - firmware: turris-mox-rwtm: Fix checking return value of + wait_for_completion_timeout() + - firmware: turris-mox-rwtm: Initialize completion before mailbox + - wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device + - net/smc: Allow SMC-D 1MB DMB allocations + - net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when + CONFIG_ARCH_NO_SG_CHAIN is defined + - selftests/bpf: Check length of recv in test_sockmap + - lib: objagg: Fix general protection fault + - mlxsw: spectrum_acl_erp: Fix object nesting warning + - wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he() + - wifi: cfg80211: handle 2x996 RU allocation in + cfg80211_calculate_bitrate_he() + - net: fec: Refactor: #define magic constants + - net: fec: Fix FEC_ECR_EN1588 being cleared on link-down + - ipvs: Avoid unnecessary calls to skb_is_gso_sctp + - netfilter: nf_tables: rise cap on SELinux secmark context + - perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation + - perf: Fix perf_aux_size() for greater-than 32-bit size + - perf: Prevent passing zero nr_pages to rb_alloc_aux() + - qed: Improve the stack space of filter_config() + - wifi: virt_wifi: avoid reporting connection success with wrong SSID + - gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey + - wifi: virt_wifi: don't use strlen() in const context + - bna: adjust 'name' buf size of bna_tcb and bna_ccb structures + - selftests: forwarding: devlink_lib: Wait for udev events after reloading + - media: dvb-usb: Fix unexpected infinite loop in + dvb_usb_read_remote_control() + - media: imon: Fix race getting ictx->lock + - saa7134: Unchecked i2c_transfer function result fixed + - media: uvcvideo: Allow entity-defined get_info and get_cur + - media: uvcvideo: Override default flags + - media: renesas: vsp1: Fix _irqsave and _irq mix + - media: renesas: vsp1: Store RPF partition configuration per RPF instance + - leds: trigger: Unregister sysfs attributes before calling deactivate() + - perf report: Fix condition in sort__sym_cmp() + - drm/etnaviv: fix DMA direction handling for cached RW buffers + - drm/qxl: Add check for drm_cvt_mode + - mfd: omap-usb-tll: Use struct_size to allocate tll + - SUNRPC: avoid soft lockup when transmitting UDP to reachable server. + - ext4: avoid writing unitialized memory to disk in EA inodes + - sparc64: Fix incorrect function signature and add prototype for + prom_cif_init + - SUNRPC: Fixup gss_status tracepoint error output + - PCI: Fix resource double counting on remove & rescan + - Input: qt1050 - handle CHIP_ID reading error + - RDMA/mlx4: Fix truncated output warning in mad.c + - RDMA/mlx4: Fix truncated output warning in alias_GUID.c + - RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs + - ASoC: max98088: Check for clk_prepare_enable() error + - mtd: make mtd_test.c a separate module + - RDMA/device: Return error earlier if port in not valid + - Input: elan_i2c - do not leave interrupt disabled on suspend failure + - MIPS: Octeron: remove source file executable bit + - powerpc/xmon: Fix disassembly CPU feature checks + - macintosh/therm_windtunnel: fix module unload. + - bnxt_re: Fix imm_data endianness + - netfilter: ctnetlink: use helper function to calculate expect ID + - pinctrl: core: fix possible memory leak when pinctrl_enable() fails + - pinctrl: single: fix possible memory leak when pinctrl_enable() fails + - pinctrl: ti: ti-iodelay: Drop if block with always false condition + - pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable() + fails + - pinctrl: freescale: mxs: Fix refcount of child + - fs/nilfs2: remove some unused macros to tame gcc + - nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro + - rtc: interface: Add RTC offset to alarm after fix-up + - tick/broadcast: Make takeover of broadcast hrtimer reliable + - net: netconsole: Disable target before netpoll cleanup + - af_packet: Handle outgoing VLAN packets without hardware offloading + - ipv6: take care of scope when choosing the src addr + - char: tpm: Fix possible memory leak in tpm_bios_measurements_open() + - media: venus: fix use after free in vdec_close + - hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode() + - drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes + - drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes + - drm/amd/display: Check for NULL pointer + - udf: Avoid using corrupted block bitmap buffer + - m68k: amiga: Turn off Warp1260 interrupts during boot + - ext4: check dot and dotdot of dx_root before making dir indexed + - ext4: make sure the first directory block is not a hole + - wifi: mwifiex: Fix interface type change + - leds: ss4200: Convert PCIBIOS_* return codes to errnos + - tools/memory-model: Fix bug in lock.cat + - hwrng: amd - Convert PCIBIOS_* return codes to errnos + - PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN + - binder: fix hang of unregistered readers + - scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds + - f2fs: fix to don't dirty inode for readonly filesystem + - clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use + - ubi: eba: properly rollback inside self_check_eba + - decompress_bunzip2: fix rare decompression failure + - kobject_uevent: Fix OOB access within zap_modalias_env() + - rtc: cmos: Fix return value of nvmem callbacks + - scsi: qla2xxx: During vport delete send async logout explicitly + - scsi: qla2xxx: Fix for possible memory corruption + - scsi: qla2xxx: Complete command early within lock + - scsi: qla2xxx: validate nvme_local_port correctly + - perf/x86/intel/pt: Fix topa_entry base length + - perf/x86/intel/pt: Fix a topa_entry base address calculation + - rtc: isl1208: Fix return value of nvmem callbacks + - watchdog/perf: properly initialize the turbo mode timestamp and rearm + counter + - platform: mips: cpu_hwmon: Disable driver on unsupported hardware + - RDMA/iwcm: Fix a use-after-free related to destroying CM IDs + - selftests/sigaltstack: Fix ppc64 GCC build + - rbd: don't assume rbd_is_lock_owner() for exclusive mappings + - drm/panfrost: Mark simple_ondemand governor as softdep + - rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait + - rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings + - Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591 + - nilfs2: handle inconsistent state in nilfs_btnode_create_block() + - kdb: address -Wformat-security warnings + - kdb: Use the passed prompt in kdb_position_cursor() + - jfs: Fix array-index-out-of-bounds in diFree + - um: time-travel: fix time-travel-start option + - libbpf: Fix no-args func prototype BTF dumping syntax + - dma: fix call order in dmam_free_coherent + - MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later + - ipv4: Fix incorrect source address in Record Route option + - net: bonding: correctly annotate RCU in bond_should_notify_peers() + - tipc: Return non-zero value from tipc_udp_addr2str() on error + - net: nexthop: Initialize all fields in dumped nexthops + - bpf: Fix a segment issue when downgrading gso_size + - mISDN: Fix a use after free in hfcmulti_tx() + - powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap() + - ASoC: Intel: Convert to new X86 CPU match macros + - ASoC: Intel: Move soc_intel_is_foo() helpers to a generic header + - ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable + - nvme-pci: add missing condition check for existence of mapped data + - mm: avoid overflows in dirty throttling logic + - PCI: rockchip: Make 'ep-gpios' DT property optional + - PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio + - parport: Convert printk(KERN_ to pr_( + - parport: Standardize use of printmode + - dev/parport: fix the array out-of-bounds risk + - driver core: Cast to (void *) with __force for __percpu pointer + - devres: Fix memory leakage caused by driver API devm_free_percpu() + - genirq: Allow the PM device to originate from irq domain + - irqchip/imx-irqsteer: Constify irq_chip struct + - irqchip/imx-irqsteer: Add runtime PM support + - irqchip/imx-irqsteer: Handle runtime power management correctly + - remoteproc: imx_rproc: ignore mapping vdev regions + - remoteproc: imx_rproc: Fix ignoring mapping vdev regions + - remoteproc: imx_rproc: Skip over memory region when node value is NULL + - drm/nouveau: prime: fix refcount underflow + - drm/vmwgfx: Fix overlay when using Screen Targets + - net/iucv: fix use after free in iucv_sock_close() + - net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys + - ipv6: fix ndisc_is_useropt() handling for PIO + - HID: wacom: Modify pen IDs + - protect the fetch of ->fd[fd] in do_dup2() from mispredictions + - ALSA: usb-audio: Correct surround channels in UAC1 channel map + - net: usb: sr9700: fix uninitialized variable use in sr_mdio_read + - netfilter: ipset: Add list flush to cancel_gc + - genirq: Allow irq_chip registration functions to take a const irq_chip + - irqchip/mbigen: Fix mbigen node address layout + - x86/mm: Fix pti_clone_pgtable() alignment assumption + - sctp: move hlist_node and hashent out of sctp_ep_common + - sctp: Fix null-ptr-deref in reuseport_add_sock(). + - net: usb: qmi_wwan: fix memory leak for not ip packets + - net: linkwatch: use system_unbound_wq + - Bluetooth: l2cap: always unlock channel in l2cap_conless_channel() + - net: fec: Stop PPS on driver remove + - md/raid5: avoid BUG_ON() while continue reshape after reassembling + - clocksource/drivers/sh_cmt: Address race condition for clock events + - ACPI: battery: create alarm sysfs attribute atomically + - ACPI: SBS: manage alarm sysfs attribute through psy core + - selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT + - PCI: Add Edimax Vendor ID to pci_ids.h + - udf: prevent integer overflow in udf_bitmap_free_blocks() + - wifi: nl80211: don't give key data to userspace + - btrfs: fix bitmap leak when loading free space cache on duplicate entry + - drm/amdgpu: Fix the null pointer dereference to ras_manager + - media: uvcvideo: Ignore empty TS packets + - media: uvcvideo: Fix the bandwdith quirk on USB 3.x + - jbd2: avoid memleak in jbd2_journal_write_metadata_buffer + - s390/sclp: Prevent release of buffer in I/O + - SUNRPC: Fix a race to wake a sync task + - ext4: fix wrong unit use in ext4_mb_find_by_goal + - arm64: cpufeature: Force HWCAP to be based on the sysreg visible to user- + space + - arm64: Add Neoverse-V2 part + - arm64: cputype: Add Cortex-X4 definitions + - arm64: cputype: Add Neoverse-V3 definitions + - arm64: errata: Add workaround for Arm errata 3194386 and 3312417 + - [Config] Set ARM64_ERRATUM_3194386=y + - arm64: cputype: Add Cortex-X3 definitions + - arm64: cputype: Add Cortex-A720 definitions + - arm64: cputype: Add Cortex-X925 definitions + - arm64: errata: Unify speculative SSBS errata logic + - arm64: errata: Expand speculative SSBS workaround + - arm64: cputype: Add Cortex-X1C definitions + - arm64: cputype: Add Cortex-A725 definitions + - arm64: errata: Expand speculative SSBS workaround (again) + - i2c: smbus: Don't filter out duplicate alerts + - i2c: smbus: Improve handling of stuck alerts + - i2c: smbus: Send alert notifications to all devices if source not found + - bpf: kprobe: remove unused declaring of bpf_kprobe_override + - spi: fsl-lpspi: remove unneeded array + - spi: spi-fsl-lpspi: Fix scldiv calculation + - drm/client: fix null pointer dereference in drm_client_modeset_probe + - ALSA: line6: Fix racy access to midibuf + - ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list + - ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4 + - usb: vhci-hcd: Do not drop references before new references are gained + - USB: serial: debug: do not echo input by default + - usb: gadget: core: Check for unset descriptor + - scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic + - tick/broadcast: Move per CPU pointer access into the atomic section + - ntp: Clamp maxerror and esterror to operating range + - driver core: Fix uevent_show() vs driver detach race + - ntp: Safeguard against time_constant overflow + - scsi: mpt3sas: Remove scsi_dma_map() error messages + - scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES + - serial: core: check uartclk for zero to avoid divide by zero + - genirq/irqdesc: Honor caller provided affinity in alloc_desc() + - power: supply: axp288_charger: Fix constant_charge_voltage writes + - power: supply: axp288_charger: Round constant_charge_voltage writes down + - tracing: Fix overflow in get_free_elt() + - x86/mtrr: Check if fixed MTRRs exist before saving them + - drm/bridge: analogix_dp: properly handle zero sized AUX transactions + - drm/mgag200: Set DDC timeout in milliseconds + - Fix gcc 4.9 build issue in 5.4.y + - kbuild: Fix '-S -c' in x86 stack protector scripts + - netfilter: nf_tables: set element extended ACK reporting support + - netfilter: nf_tables: prefer nft_chain_validate + - drm/i915/gem: Fix Virtual Memory mapping boundaries calculation + - arm64: cpufeature: Fix the visibility of compat hwcaps + - media: uvcvideo: Use entity get_cur in uvc_ctrl_set + - exec: Fix ToCToU between perm check and set-uid/gid usage + - nvme/pci: Add APST quirk for Lenovo N60z laptop + - ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode + - media: Revert "media: dvb-usb: Fix unexpected infinite loop in + dvb_usb_read_remote_control()" + - Linux 5.4.282 + * CVE-2024-26885 + - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches + * Focal update: v5.4.281 upstream stable release (LP: #2076097) + - gcc-plugins: Rename last_stmt() for GCC 14+ + - filelock: Remove locks reliably when fcntl/close race is detected + - scsi: qedf: Set qed_slowpath_params to zero before use + - ACPI: EC: Abort address space access upon error + - ACPI: EC: Avoid returning AE_OK on errors in address space handler + - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata + - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan() + - Input: silead - Always support 10 fingers + - ila: block BH in ila_output() + - kconfig: gconf: give a proper initial state to the Save button + - kconfig: remove wrong expr_trans_bool() + - fs/file: fix the check in find_next_fd() + - mei: demote client disconnect warning on suspend to debug + - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check + - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group() + - ALSA: hda/realtek: Add more codec ID to no shutup pins list + - mips: fix compat_sys_lseek syscall + - Input: elantech - fix touchpad state on resume for Lenovo N24 + - bytcr_rt5640 : inverse jack detect for Archos 101 cesium + - ASoC: ti: davinci-mcasp: Set min period size using FIFO config + - ASoC: ti: omap-hdmi: Fix too long driver name + - can: kvaser_usb: fix return value for hif_usb_send_regout + - s390/sclp: Fix sclp_init() cleanup on failure + - ALSA: dmaengine_pcm: terminate dmaengine before synchronize + - net: usb: qmi_wwan: add Telit FN912 compositions + - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and + DEV_STATS_ADD() + - powerpc/pseries: Whitelist dtl slub object for copying to userspace + - powerpc/eeh: avoid possible crash when edev->pdev changes + - scsi: libsas: Fix exp-attached device scan after probe failure scanned in + again after probe failed + - Bluetooth: hci_core: cancel all works upon hci_unregister_dev() + - fs: better handle deep ancestor chains in is_subdir() + - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices + - selftests/vDSO: fix clang build errors and warnings + - hfsplus: fix uninit-value in copy_name + - ARM: 9324/1: fix get_user() broken with veneer + - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency + - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq() + - net: relax socket state check at accept time. + - ocfs2: add bounds checking to ocfs2_check_dir_entry() + - jfs: don't walk off the end of ealist + - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400 + - filelock: Fix fcntl/close race recovery compat path + - tun: add missing verification for short frame + - tap: add missing verification for short frame + - Linux 5.4.281 + * Focal update: v5.4.283 upstream stable release (LP: #2080595) // + CVE-2024-45016 + - netem: fix return value if duplicate enqueue fails + * CVE-2024-38630 + - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger + * CVE-2024-27397 + - netfilter: nf_tables: use timestamp to check for set element timeout + * CVE-2024-26960 + - mm: swap: fix race between free_swap_and_cache() and swapoff() + + -- Philip Cox Mon, 07 Oct 2024 09:30:00 -0400 + +linux-oracle (5.4.0-1133.142) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1133.142 -proposed tracker (LP: #2082227) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.oracle/dkms-versions -- update from kernel-versions + (main/s2024.09.02) + + [ Ubuntu: 5.4.0-198.218 ] + + * focal/linux: 5.4.0-198.218 -proposed tracker (LP: #2082232) + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/s2024.09.02) + * CVE-2024-45016 + - netem: fix return value if duplicate enqueue fails + * CVE-2024-38630 + - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger + * CVE-2024-27397 + - netfilter: nf_tables: use timestamp to check for set element timeout + * CVE-2024-26960 + - mm: swap: fix race between free_swap_and_cache() and swapoff() + + -- Philip Cox Thu, 03 Oct 2024 13:23:05 -0400 + +linux-oracle (5.4.0-1132.141) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1132.141 -proposed tracker (LP: #2078200) + + [ Ubuntu: 5.4.0-196.216 ] + + * focal/linux: 5.4.0-196.216 -proposed tracker (LP: #2078205) + * CVE-2024-39494 + - ima: Fix use-after-free on a dentry's dname.name + * CVE-2024-42160 + - f2fs: check validation of fault attrs in f2fs_build_fault_attr() + - f2fs: Add inline to f2fs_build_fault_attr() stub + * CVE-2024-38570 + - gfs2: Rename sd_{ glock => kill }_wait + - gfs2: Fix potential glock use-after-free on unmount + * CVE-2024-42228 + - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc + * CVE-2022-48791 + - scsi: pm80xx: Fix TMF task completion race condition + - scsi: pm8001: Fix use-after-free for aborted TMF sas_task + * CVE-2024-26787 + - mmc: mmci_sdmmc: Rename sdmmc_priv struct to sdmmc_idma + - mmc: mmci: stm32: use a buffer for unaligned DMA requests + - mmc: mmci: stm32: fix DMA API overlapping mappings warning + * CVE-2024-27012 + - netfilter: nf_tables: restore set elements when delete set fails + * CVE-2022-48863 + - mISDN: Fix memory leak in dsp_pipeline_build() + * CVE-2021-47188 + - scsi: ufs: core: Improve SCSI abort handling + * CVE-2024-26677 + - rxrpc: Fix delayed ACKs to not set the reference serial number + + -- Manuel Diewald Mon, 02 Sep 2024 12:23:09 +0200 + +linux-oracle (5.4.0-1131.140) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1131.140 -proposed tracker (LP: #2075949) + + [ Ubuntu: 5.4.0-195.215 ] + + * focal/linux: 5.4.0-195.215 -proposed tracker (LP: #2075954) + * Focal update: v5.4.280 upstream stable release (LP: #2075175) + - Compiler Attributes: Add __uninitialized macro + - drm/lima: fix shared irq handling on driver remove + - media: dvb: as102-fe: Fix as10x_register_addr packing + - media: dvb-usb: dib0700_devices: Add missing release_firmware() + - IB/core: Implement a limit on UMAD receive List + - scsi: qedf: Make qedf_execute_tmf() non-preemptible + - drm/amdgpu: Initialize timestamp for some legacy SOCs + - drm/amd/display: Skip finding free audio for unknown engine_id + - media: dw2102: Don't translate i2c read into write + - sctp: prefer struct_size over open coded arithmetic + - firmware: dmi: Stop decoding on broken entry + - Input: ff-core - prefer struct_size over open coded arithmetic + - net: dsa: mv88e6xxx: Correct check for empty list + - media: dvb-frontends: tda18271c2dd: Remove casting during div + - media: s2255: Use refcount_t instead of atomic_t for num_channels + - media: dvb-frontends: tda10048: Fix integer overflow + - i2c: i801: Annotate apanel_addr as __ro_after_init + - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n + - orangefs: fix out-of-bounds fsid access + - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#" + - jffs2: Fix potential illegal address access in jffs2_free_inode + - s390/pkey: Wipe sensitive data on failure + - tcp: tcp_mark_head_lost is only valid for sack-tcp + - tcp: add ece_ack flag to reno sack functions + - net: tcp better handling of reordering then loss cases + - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open() + - tcp_metrics: validate source addr length + - wifi: wilc1000: fix ies_len type in connect path + - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() + - selftests: fix OOM in msg_zerocopy selftest + - selftests: make order checking verbose in msg_zerocopy selftest + - inet_diag: Initialize pad field in struct inet_diag_req_v2 + - nilfs2: fix inode number range checks + - nilfs2: add missing check for inode numbers on directory entries + - mm: optimize the redundant loop of mm_update_owner_next() + - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct + - fsnotify: Do not generate events for O_PATH file descriptors + - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), + again" + - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes + - drm/amdgpu/atomfirmware: silence UBSAN warning + - media: dw2102: fix a potential buffer overflow + - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr + - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 + - nvme-multipath: find NUMA path only for online numa-node + - nilfs2: fix incorrect inode allocation from reserved inodes + - filelock: fix potential use-after-free in posix_lock_inode + - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading + - vfs: don't mod negative dentry count when on shrinker list + - tcp: add TCP_INFO status for failed client TFO + - tcp: fix incorrect undo caused by DSACK of TLP retransmit + - octeontx2-af: Fix incorrect value output on error path in + rvu_check_rsrc_availability() + - net: lantiq_etop: add blank line after declaration + - net: ethernet: lantiq_etop: fix double free in detach + - ppp: reject claimed-as-LCP but actually malformed packets + - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). + - s390: Mark psw in __load_psw_mask() as __unitialized + - ARM: davinci: Convert comma to semicolon + - octeontx2-af: fix detection of IP layer + - USB: serial: option: add Telit generic core-dump composition + - USB: serial: option: add Telit FN912 rmnet compositions + - USB: serial: option: add Fibocom FM350-GL + - USB: serial: option: add support for Foxconn T99W651 + - USB: serial: option: add Netprisma LCUK54 series modules + - USB: serial: option: add Rolling RW350-GL variants + - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k + - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy() + - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the + descriptor + - hpet: Support 32-bit userspace + - nvmem: meson-efuse: Fix return value of nvmem callbacks + - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX + - libceph: fix race between delayed_work() and ceph_monc_stop() + - SUNRPC: Fix RPC client cleaned up the freed pipefs dentries + - tcp: refactor tcp_retransmit_timer() + - net: tcp: fix unexcepted socket die when snd_wnd is 0 + - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out() + - tcp: avoid too many retransmit packets + - nilfs2: fix kernel bug on rename operation of broken directory + - i2c: rcar: bring hardware to known state when probing + - Linux 5.4.280 + * [SRU] UBSAN warnings in bnx2x kernel driver (LP: #2074215) // Focal update: + v5.4.280 upstream stable release (LP: #2075175) + - bnx2x: Fix multiple UBSAN array-index-out-of-bounds + * Focal update: v5.4.279 upstream stable release (LP: #2073621) + - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects + - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() + - wifi: cfg80211: pmsr: use correct nla_get_uX functions + - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 + - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef + - wifi: iwlwifi: mvm: don't read past the mfuart notifcation + - ipv6: sr: block BH in seg6_output_core() and seg6_input_core() + - net: sched: sch_multiq: fix possible OOB write in multiq_tune() + - vxlan: Fix regression when dropping packets due to invalid src addresses + - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB + - net/mlx5: Stop waiting for PCI if pci channel is offline + - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP + - ptp: Fix error message on failed pin verification + - af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). + - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and + poll(). + - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg(). + - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. + - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. + - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). + - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). + - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). + - ipv6: fix possible race in __fib6_drop_pcpu_from() + - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete + - ASoC: ti: davinci-mcasp: remove redundant assignment to variable ret + - ASoC: ti: davinci-mcasp: remove always zero of davinci_mcasp_get_dt_params + - ASoC: ti: davinci-mcasp: Use platform_get_irq_byname_optional + - ASoC: ti: davinci-mcasp: Remove legacy dma_request parsing + - ASoC: ti: davinci-mcasp: Simplify the configuration parameter handling + - ASoC: ti: davinci-mcasp: Handle missing required DT properties + - ASoC: ti: davinci-mcasp: Fix race condition during probe + - drm/amd/display: Handle Y carry-over in VCP X.Y calculation + - serial: sc16is7xx: replace hardcoded divisor value with BIT() macro + - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler + - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages + - selftests/mm: conform test to TAP format output + - selftests/mm: compaction_test: fix bogus test success on Aarch64 + - nilfs2: Remove check for PageError + - nilfs2: return the mapped address from nilfs_get_page() + - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors + - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages + - mei: me: release irq in mei_me_pci_resume error path + - jfs: xattr: fix buffer overflow for invalid xattr + - xhci: Set correct transferred length for cancelled bulk transfers + - xhci: Apply reset resume quirk to Etron EJ188 xHCI host + - xhci: Apply broken streams quirk to Etron EJ188 xHCI host + - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory + - Input: try trimming too long modalias strings + - SUNRPC: return proper error from gss_wrap_req_priv + - gpio: tqmx86: fix typo in Kconfig label + - HID: core: remove unnecessary WARN_ON() in implement() + - iommu/amd: Fix sysfs leak in iommu init + - iommu: Return right value in iommu_sva_bind_device() + - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode() + - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet + - drm/komeda: check for error-valued pointer + - drm/bridge/panel: Fix runtime warning on panel bridge release + - tcp: fix race in tcp_v6_syn_recv_sock() + - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) + packets + - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ + - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set + type + - net/ipv6: Fix the RT cache flush via sysctl using a previous delay + - ionic: fix use after netif_napi_del() + - drivers: core: synchronize really_probe() and dev_uevent() + - drm/exynos/vidi: fix memory leak in .get_modes() + - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found + - tracing/selftests: Fix kprobe event name test for .isra. functions + - vmci: prevent speculation leaks by sanitizing event in event_deliver() + - fs/proc: fix softlockup in __read_vmcore + - ocfs2: use coarse time for new created files + - ocfs2: fix races between hole punching and AIO+DIO + - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id + - dmaengine: axi-dmac: fix possible race in remove() + - intel_th: pci: Add Granite Rapids support + - intel_th: pci: Add Granite Rapids SOC support + - intel_th: pci: Add Sapphire Rapids SOC support + - intel_th: pci: Add Meteor Lake-S support + - intel_th: pci: Add Lunar Lake support + - nilfs2: fix potential kernel bug due to lack of writeback flag waiting + - tick/nohz_full: Don't abuse smp_call_function_single() in + tick_setup_device() + - hv_utils: drain the timesync packets on onchannelcallback + - hugetlb_encode.h: fix undefined behaviour (34 << 26) + - greybus: Fix use-after-free bug in gb_interface_release due to race + condition. + - usb-storage: alauda: Check whether the media is initialized + - i2c: at91: Fix the functionality flags of the slave-only interface + - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment + - selftests/bpf: Prevent client connect before server bind in + test_tc_tunnel.sh + - batman-adv: bypass empty buckets in batadv_purge_orig_ref() + - drop_monitor: replace spin_lock by raw_spin_lock + - scsi: qedi: Fix crash while reading debugfs attribute + - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl + - powerpc/pseries: Enforce hcall result buffer validity and size + - powerpc/io: Avoid clang null pointer arithmetic warnings + - usb: misc: uss720: check for incompatible versions of the Belkin F5U002 + - udf: udftime: prevent overflow in udf_disk_stamp_to_time() + - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports + - MIPS: Octeon: Add PCIe link status check + - MIPS: Routerboard 532: Fix vendor retry check code + - mips: bmips: BCM6358: make sure CBR is correctly set + - cipso: fix total option length computation + - netrom: Fix a memory leak in nr_heartbeat_expiry() + - ipv6: prevent possible NULL deref in fib6_nh_init() + - ipv6: prevent possible NULL dereference in rt6_probe() + - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr() + - netns: Make get_net_ns() handle zero refcount net + - net/sched: act_api: rely on rcu in tcf_idr_check_alloc + - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc() + - virtio_net: checksum offloading handling fix + - netfilter: ipset: Fix suspicious rcu_dereference_protected() + - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings + - regulator: core: Fix modpost error "regulator_get_regmap" undefined + - dmaengine: ioatdma: Fix missing kmem_cache_destroy() + - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is + fine." + - drm/radeon: fix UBSAN warning in kv_dpm.c + - gcov: add support for GCC 14 + - i2c: ocores: set IACK bit after core is enabled + - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat + - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat + - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat + - arm64: dts: qcom: qcs404: fix bluetooth device address + - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test + - Revert "kheaders: substituting --sort in archive creation" + - kheaders: explicitly define file modes for archived headers + - perf/core: Fix missing wakeup when waiting for context reference + - PCI: Add PCI_ERROR_RESPONSE and related definitions + - x86/amd_nb: Check for invalid SMN reads + - iio: dac: ad5592r-base: Replace indio_dev->mlock with own device lock + - iio: dac: ad5592r: un-indent code-block for scale read + - iio: dac: ad5592r: fix temperature channel scaling value + - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins + - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set + - drm/amdgpu: fix UBSAN warning in kv_dpm.c + - netfilter: nf_tables: validate family when identifying table via handle + - ASoC: fsl-asoc-card: set priv->pdev before using it + - net: dsa: microchip: fix initial port flush problem + - net: phy: mchp: Add support for LAN8814 QUAD PHY + - net: phy: micrel: add Microchip KSZ 9477 to the device table + - sparc: fix old compat_sys_select() + - parisc: use correct compat recv/recvfrom syscalls + - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data + registers + - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep + - mtd: partitions: redboot: Added conversion of operands to a larger type + - net/iucv: Avoid explicit cpumask var allocation on stack + - net/dpaa2: Avoid explicit cpumask var allocation on stack + - ALSA: emux: improve patch ioctl data validation + - media: dvbdev: Initialize sbuf + - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message + - nvme: fixup comment for nvme RDMA Provider Type + - gpio: davinci: Validate the obtained number of IRQs + - x86: stop playing stack games in profile_pc() + - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos + - mmc: sdhci: Do not invert write-protect twice + - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() + - iio: adc: ad7266: Fix variable checking bug + - iio: chemical: bme680: Fix pressure value output + - iio: chemical: bme680: Fix calibration data variable + - iio: chemical: bme680: Fix overflows in compensate() functions + - iio: chemical: bme680: Fix sensor data read operation + - net: usb: ax88179_178a: improve link status logs + - usb: gadget: printer: SS+ support + - usb: musb: da8xx: fix a resource leak in probe() + - usb: atm: cxacru: fix endpoint checking in cxacru_bind() + - tty: mcf: MCF54418 has 10 UARTS + - net: can: j1939: Initialize unused data in j1939_send_one() + - net: can: j1939: recover socket queue on CAN bus error during BAM + transmission + - net: can: j1939: enhanced error handling for tightly received RTS messages + in xtp_rx_rts_session_new + - csky, hexagon: fix broken sys_sync_file_range + - hexagon: fix fadvise64_64 calling conventions + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes + - batman-adv: Don't accept TT entries for out-of-spec VIDs + - ata: libata-core: Fix double free on error + - ftruncate: pass a signed offset + - mtd: spinand: macronix: Add support for serial NAND flash + - pwm: stm32: Refuse too small period requests + - nfs: Leave pages in the pagecache if readpage failed + - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node + - arm64: dts: rockchip: Add sound-dai-cells for RK3368 + - Linux 5.4.279 + * CVE-2024-26921 + - skbuff: introduce skb_expand_head() + - skb_expand_head() adjust skb->truesize incorrectly + - inet: inet_defrag: prevent sk release while still in use + * CVE-2024-26929 + - scsi: qla2xxx: Fix double free of fcport + * CVE-2024-39484 + - mmc: davinci: Don't strip remove function when driver is builtin + * CVE-2024-36901 + - ipv6: prevent NULL dereference in ip6_output() + * CVE-2024-26830 + - i40e: Refactoring VF MAC filters counting to make more reliable + - i40e: Fix MAC address setting for a VF via Host/VM + - i40e: Do not allow untrusted VF to remove administratively set MAC + * CVE-2024-24860 + - Bluetooth: Fix atomicity violation in {min, max}_key_size_set + * CVE-2023-52760 + - gfs2: Fix slab-use-after-free in gfs2_qd_dealloc + * CVE-2024-2201 + - [Config] Set SPECTRE_BHI_ON=y + * CVE-2023-52629 + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + * CVE-2021-46926 + - ALSA: hda: intel-sdw-acpi: harden detection of controller + + -- Philip Cox Fri, 16 Aug 2024 15:20:27 -0400 + +linux-oracle (5.4.0-1130.139) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1130.139 -proposed tracker (LP: #2075799) + + [ Ubuntu: 5.4.0-193.213 ] + + * focal/linux: 5.4.0-193.213 -proposed tracker (LP: #2075804) + * CVE-2024-26921 + - skbuff: introduce skb_expand_head() + - skb_expand_head() adjust skb->truesize incorrectly + - inet: inet_defrag: prevent sk release while still in use + * CVE-2024-26929 + - scsi: qla2xxx: Fix double free of fcport + * CVE-2024-39484 + - mmc: davinci: Don't strip remove function when driver is builtin + * CVE-2024-36901 + - ipv6: prevent NULL dereference in ip6_output() + * CVE-2024-26830 + - i40e: Refactoring VF MAC filters counting to make more reliable + - i40e: Fix MAC address setting for a VF via Host/VM + - i40e: Do not allow untrusted VF to remove administratively set MAC + * CVE-2024-24860 + - Bluetooth: Fix atomicity violation in {min, max}_key_size_set + * CVE-2023-52760 + - gfs2: Fix slab-use-after-free in gfs2_qd_dealloc + * CVE-2024-2201 + - [Config] Set SPECTRE_BHI_ON=y + * CVE-2023-52629 + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + * CVE-2021-46926 + - ALSA: hda: intel-sdw-acpi: harden detection of controller + + -- Philip Cox Wed, 07 Aug 2024 10:01:27 -0400 + +linux-oracle (5.4.0-1129.138) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1129.138 -proposed tracker (LP: #2072300) + + [ Ubuntu: 5.4.0-192.212 ] + + * focal/linux: 5.4.0-192.212 -proposed tracker (LP: #2072305) + * Focal update: v5.4.278 upstream stable release (LP: #2071668) + - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs + - speakup: Fix sizeof() vs ARRAY_SIZE() bug + - ring-buffer: Fix a race between readers and resize checks + - net: smc91x: Fix m68k kernel compilation for ColdFire CPU + - nilfs2: fix unexpected freezing of nilfs_segctor_sync() + - nilfs2: fix potential hang in nilfs_detach_log_writer() + - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt + class + - net: usb: qmi_wwan: add Telit FN920C04 compositions + - drm/amd/display: Set color_mgmt_changed to true on unsuspend + - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating + - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property + - ASoC: da7219-aad: fix usage of device_get_named_child_node() + - drm/amdkfd: Flush the process wq before creating a kfd_process + - nvme: find numa distance only if controller has valid numa id + - openpromfs: finish conversion to the new mount API + - crypto: bcm - Fix pointer arithmetic + - firmware: raspberrypi: Use correct device for DMA mappings + - ecryptfs: Fix buffer size for tag 66 packet + - nilfs2: fix out-of-range warning + - parisc: add missing export of __cmpxchg_u8() + - crypto: ccp - drop platform ifdef checks + - s390/cio: fix tracepoint subchannel type field + - jffs2: prevent xattr node from overflowing the eraseblock + - null_blk: Fix missing mutex_destroy() at module removal + - md: fix resync softlockup when bitmap size is less than array size + - wifi: ath10k: poll service ready message before failing + - x86/boot: Ignore relocations in .notes sections in walk_relocs() too + - qed: avoid truncating work queue length + - scsi: ufs: qcom: Perform read back after writing reset bit + - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV + - scsi: ufs: core: Perform read back after disabling interrupts + - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL + - irqchip/alpine-msi: Fix off-by-one in allocation error path + - ACPI: disable -Wstringop-truncation + - cpufreq: Reorganize checks in cpufreq_offline() + - cpufreq: Split cpufreq_offline() + - cpufreq: Rearrange locking in cpufreq_remove_dev() + - cpufreq: exit() callback is optional + - scsi: libsas: Fix the failure of adding phy with zero-address to port + - scsi: hpsa: Fix allocation size for Scsi_Host private data + - x86/purgatory: Switch to the position-independent small code model + - wifi: ath10k: Fix an error code problem in + ath10k_dbg_sta_write_peer_debug_trigger() + - wifi: ath10k: populate board data for WCN3990 + - tcp: minor optimization in tcp_add_backlog() + - tcp: fix a signed-integer-overflow bug in tcp_add_backlog() + - tcp: avoid premature drops in tcp_add_backlog() + - macintosh/via-macii: Fix "BUG: sleeping function called from invalid + context" + - wifi: carl9170: add a proper sanity check for endpoints + - wifi: ar5523: enable proper endpoint verification + - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe() + - Revert "sh: Handle calling csum_partial with misaligned data" + - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors + - scsi: bfa: Ensure the copied buf is NUL terminated + - scsi: qedf: Ensure the copied buf is NUL terminated + - wifi: mwl8k: initialize cmd->addr[] properly + - usb: aqc111: stop lying about skb->truesize + - net: usb: sr9700: stop lying about skb->truesize + - m68k: Fix spinlock race in kernel thread creation + - m68k: mac: Fix reboot hang on Mac IIci + - net: ethernet: cortina: Locking fixes + - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg + - net: usb: smsc95xx: stop lying about skb->truesize + - net: openvswitch: fix overwriting ct original tuple for ICMPv6 + - ipv6: sr: add missing seg6_local_exit + - ipv6: sr: fix incorrect unregister order + - ipv6: sr: fix invalid unregister error path + - drm/amd/display: Fix potential index out of bounds in color transformation + function + - mtd: rawnand: hynix: fixed typo + - fbdev: shmobile: fix snprintf truncation + - drm/mediatek: Add 0 size check to mtk_drm_gem_obj + - powerpc/fsl-soc: hide unused const variable + - fbdev: sisfb: hide unused variables + - media: ngene: Add dvb_ca_en50221_init return value check + - media: radio-shark2: Avoid led_names truncations + - platform/x86: wmi: Make two functions static + - fbdev: sh7760fb: allow modular build + - drm/arm/malidp: fix a possible null pointer dereference + - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value + - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector + - RDMA/hns: Use complete parentheses in macros + - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map + - ext4: avoid excessive credit estimate in ext4_tmpfile() + - sunrpc: removed redundant procp check + - SUNRPC: Fix gss_free_in_token_pages() + - selftests/kcmp: Make the test output consistent and clear + - selftests/kcmp: remove unused open mode + - RDMA/IPoIB: Fix format truncation compilation errors + - netrom: fix possible dead-lock in nr_rt_ioctl() + - af_packet: do not call packet_read_pending() from tpacket_destruct_skb() + - sched/topology: Don't set SD_BALANCE_WAKE on cpuset domain relax + - sched/fair: Allow disabling sched_balance_newidle with + sched_relax_domain_level + - greybus: lights: check return of get_channel_from_mode + - soundwire: cadence/intel: simplify PDI/port mapping + - soundwire: intel: don't filter out PDI0/1 + - soundwire: cadence_master: improve PDI allocation + - soundwire: cadence: fix invalid PDI offset + - dmaengine: idma64: Add check for dma_set_max_seg_size + - firmware: dmi-id: add a release callback function + - serial: max3100: Lock port->lock when calling uart_handle_cts_change() + - serial: max3100: Update uart_driver_registered on driver removal + - serial: max3100: Fix bitwise types + - greybus: arche-ctrl: move device table to its right location + - iio: pressure: dps310: support negative temperature values + - microblaze: Remove gcc flag for non existing early_printk.c file + - microblaze: Remove early printk call from cpuinfo-static.c + - usb: gadget: u_audio: Clear uac pointer when freed. + - stm class: Fix a double free in stm_register_device() + - ppdev: Remove usage of the deprecated ida_simple_xx() API + - ppdev: Add an error check in register_device + - extcon: max8997: select IRQ_DOMAIN instead of depending on it + - f2fs: fix to release node block count in error path of f2fs_new_node_page() + - serial: sh-sci: protect invalidating RXDMA on shutdown + - libsubcmd: Fix parse-options memory leak + - Input: ims-pcu - fix printf string overflow + - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation + - drm/msm/dpu: Always flush the slave INTF on the CTL + - um: Fix return value in ubd_init() + - um: Add winch to winch_handlers before registering winch IRQ + - media: stk1160: fix bounds checking in stk1160_copy_video() + - scsi: qla2xxx: Replace all non-returning strlcpy() with strscpy() + - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp + - um: Fix the -Wmissing-prototypes warning for __switch_mm + - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh + - media: cec: cec-api: add locking in cec_release() + - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION() + - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when + UNWINDER_FRAME_POINTER=y + - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS + - nfc: nci: Fix uninit-value in nci_rx_work + - sunrpc: fix NFSACL RPC retry on soft mount + - ipv6: sr: fix memleak in seg6_hmac_init_algo + - params: lift param_set_uint_minmax to common code + - tcp: Fix shift-out-of-bounds in dctcp_update_alpha(). + - openvswitch: Set the skbuff pkt_type for proper pmtud support. + - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY + - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails + - net: fec: avoid lock evasion when reading pps_enable + - nfc: nci: Fix kcov check in nci_rx_work() + - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work() + - netfilter: nfnetlink_queue: acquire rcu_read_lock() in + instance_destroy_rcu() + - spi: Don't mark message DMA mapped when no transfer in it is + - nvmet: fix ns enable/disable possible hang + - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer + exhaustion + - dma-buf/sw-sync: don't enable IRQ from sync_print_obj() + - enic: Validate length of nl attributes in enic_set_vf_port + - smsc95xx: remove redundant function arguments + - smsc95xx: use usbnet->driver_priv + - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM + - net:fec: Add fec_enet_deinit() + - netfilter: tproxy: bail out if IP has been disabled on the device + - kconfig: fix comparison to constant symbols, 'm', 'n' + - spi: stm32: Don't warn about spurious interrupts + - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound + - ALSA: timer: Set lower bound of start tick time + - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline + - SUNRPC: Fix loop termination condition in gss_free_in_token_pages() + - binder: fix max_thread type inconsistency + - mmc: core: Do not force a retune before RPMB switch + - io_uring: fail NOP if non-zero op flags is passed in + - afs: Don't cross .backup mountpoint from backup volume + - nilfs2: fix use-after-free of timer for log writer thread + - vxlan: Fix regression when dropping packets due to invalid src addresses + - x86/mm: Remove broken vsyscall emulation code from the page fault code + - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() + - media: lgdt3306a: Add a check against null-pointer-def + - drm/amdgpu: add error handle to avoid out-of-bounds + - ata: pata_legacy: make legacy_exit() work again + - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx + - arm64: tegra: Correct Tegra132 I2C alias + - md/raid5: fix deadlock that raid5d() wait for itself to clear + MD_SB_CHANGE_PENDING + - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU + - arm64: dts: hi3798cv200: fix the size of GICR + - media: mc: mark the media devnode as registered from the, start + - media: mxl5xx: Move xpt structures off stack + - media: v4l2-core: hold videodev_lock until dev reg, finishes + - fbdev: savage: Handle err return when savagefb_check_var failed + - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode + - crypto: ecrdsa - Fix module auto-load on add_key + - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak + - net/ipv6: Fix route deleting failure when metric equals 0 + - net/9p: fix uninit-value in p9_client_rpc() + - intel_th: pci: Add Meteor Lake-S CPU support + - sparc64: Fix number of online CPUs + - kdb: Fix buffer overflow during tab-complete + - kdb: Use format-strings rather than '\0' injection in kdb_read() + - kdb: Fix console handling when editing and tab-completing commands + - kdb: Merge identical case statements in kdb_read() + - kdb: Use format-specifiers rather than memset() for padding in kdb_read() + - net: fix __dst_negative_advice() race + - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING + - sparc: move struct termio to asm/termios.h + - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find() + - s390/ap: Fix crash in AP internal function modify_bitmap() + - nfs: fix undefined behavior in nfs_block_bits() + - Linux 5.4.278 + * CVE-2024-27019 + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get() + * CVE-2024-26886 + - Bluetooth: af_bluetooth: Fix deadlock + * CVE-2023-52752 + - smb: client: fix use-after-free bug in cifs_debug_data_proc_show() + * CVE-2022-48674 + - erofs: fix pcluster use-after-free on UP platforms + * Focal update: v5.4.277 upstream stable release (LP: #2070179) + - pinctrl: core: handle radix_tree_insert() errors in + pinctrl_register_one_pin() + - ext4: fix bug_on in __es_tree_search + - Revert "selftests: mm: fix map_hugetlb failure on 64K page size systems" + - Revert "net: bcmgenet: use RGMII loopback for MAC reset" + - net: bcmgenet: keep MAC in reset until PHY is up + - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access + - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode() + - net: bcmgenet: synchronize UMAC_CMD access + - smb: client: fix potential OOBs in smb2_parse_contexts() + - arm64: dts: qcom: Fix 'interrupt-map' parent address cells + - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks() + - drm/amdgpu: Fix possible NULL dereference in + amdgpu_ras_query_error_status_helper() + - usb: typec: ucsi: displayport: Fix potential deadlock + - serial: kgdboc: Fix NMI-safety problems from keyboard reset code + - docs: kernel_include.py: Cope with docutils 0.21 + - Linux 5.4.277 + * Focal update: v5.4.276 upstream stable release (LP: #2069758) + - dmaengine: pl330: issue_pending waits until WFP state + - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state" + - wifi: nl80211: don't free NULL coalescing rule + - pinctrl: core: delete incorrect free in pinctrl_enable() + - pinctrl: mediatek: Check gpio pin number and use binary search in + mtk_hw_pin_field_lookup() + - pinctrl: mediatek: Supporting driving setting without mapping current to + register value + - pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set() + - pinctrl: mediatek: Refine mtk_pinconf_get() + - pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull + usage + - pinctrl: mediatek: remove shadow variable declaration + - pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback + - pinctrl: mediatek: paris: Rework mtk_pinconf_{get,set} switch/case logic + - pinctrl: mediatek: paris: Rework support for + PIN_CONFIG_{INPUT,OUTPUT}_ENABLE + - sunrpc: add a struct rpc_stats arg to rpc_create_args + - nfs: expose /proc/net/sunrpc/nfs in net namespaces + - nfs: make the rpc_stat per net namespace + - nfs: Handle error of rpc_proc_register() in nfs_net_init(). + - power: rt9455: hide unused rt9455_boost_voltage_values + - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() + - s390/mm: Fix storage key clearing for guest huge pages + - s390/mm: Fix clearing storage keys for huge pages + - bna: ensure the copied buf is NUL terminated + - nsh: Restore skb->{protocol,data,mac_header} for outer header in + nsh_gso_segment(). + - net l2tp: drop flow hash on forward + - net: qede: use return from qede_parse_flow_attr() for flow_spec + - net: dsa: mv88e6xxx: Add number of MACs in the ATU + - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341 + - net: bridge: fix multicast-to-unicast with fraglist GSO + - tipc: fix a possible memleak in tipc_buf_append + - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change + - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic + - gfs2: Fix invalid metadata access in punch_hole + - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc + - wifi: cfg80211: fix rdev_dump_mpp() arguments order + - net: mark racy access on sk->sk_rcvbuf + - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload + - ALSA: line6: Zero-initialize message buffers + - net: bcmgenet: Reset RBUF on first open + - ata: sata_gemini: Check clk_enable() result + - firewire: ohci: mask bus reset interrupts between ISR and bottom half + - tools/power turbostat: Fix added raw MSR output + - tools/power turbostat: Fix Bzy_MHz documentation typo + - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve + - btrfs: always clear PERTRANS metadata during commit + - scsi: target: Fix SELinux error when systemd-modules loads the target module + - gpu: host1x: Do not setup DMA for virtual devices + - MIPS: scall: Save thread_info.syscall unconditionally on entry + - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior + - fs/9p: only translate RWX permissions for plain 9P2000 + - fs/9p: translate O_TRUNC into OTRUNC + - 9p: explicitly deny setlease attempts + - gpio: wcove: Use -ENOTSUPP consistently + - gpio: crystalcove: Use -ENOTSUPP consistently + - clk: Don't hold prepare_lock when calling kref_put() + - fs/9p: drop inodes immediately on non-.L too + - net:usb:qmi_wwan: support Rolling modules + - pinctrl: mediatek: Fix fallback call path + - xfrm: Preserve vlan tags for transport mode software GRO + - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets + - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique(). + - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout + - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout + - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation + - phonet: fix rtm_phonet_notify() skb allocation + - net: bridge: fix corrupted ethernet header on multicast-to-unicast + - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action() + - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() + - net: qede: use return from qede_parse_flow_attr() for flower + - firewire: nosy: ensure user_length is taken into account when fetching + packet contents + - usb: gadget: composite: fix OS descriptors w_value logic + - usb: gadget: f_fs: Fix a race condition when processing setup packets. + - tipc: fix UAF in error path + - dyndbg: fix old BUG_ON in >control parser + - drm/vmwgfx: Fix invalid reads in fence signaled events + - net: fix out-of-bounds access in ops_init + - regulator: core: fix debugfs creation regression + - pinctrl: mediatek: Fix fallback behavior for bias_set_combo + - pinctrl: mediatek: Fix some off by one bugs + - pinctrl: mediatek: remove set but not used variable 'e' + - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback + - Linux 5.4.276 + * Freezing user space processes failed after 20.008 seconds (1 tasks refusing + to freeze, wq_busy=0) (LP: #2061091) + - ALSA: Fix deadlocks with kctl removals at disconnection + * CVE-2024-36016 + - tty: n_gsm: fix possible out-of-bounds in gsm0_receive() + * CVE-2022-48655 + - firmware: arm_scmi: Harden accesses to the reset domains + * CVE-2024-26907 + - RDMA/mlx5: Fix fortify source warning while accessing Eth segment + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26583 + - net/tls: Replace TLS_RX_SYNC_RUNNING with RCU + - net/tls: Fix use-after-free after the TLS device goes down and up + - tls: splice_read: fix record type check + - tls splice: remove inappropriate flags checking for MSG_PEEK + - tls: splice_read: fix accessing pre-processed records + - tls: Fix context leak on tls_device_down + - net/tls: Check for errors in tls_device_init + - net/tls: Remove the context from the list in tls_device_down + - net/tls: pass context to tls_device_decrypted() + - net/tls: Perform immediate device ctx cleanup when possible + - net/tls: Multi-threaded calls to TX tls_dev_del + - net: tls: avoid discarding data on record close + - tls: rx: don't store the record type in socket context + - tls: rx: don't store the decryption status in socket context + - tls: rx: don't issue wake ups when data is decrypted + - tls: rx: refactor decrypt_skb_update() + - tls: hw: rx: use return value of tls_device_decrypted() to carry status + - tls: rx: drop unnecessary arguments from tls_setup_from_iter() + - tls: rx: don't report text length from the bowels of decrypt + - tls: rx: wrap decryption arguments in a structure + - tls: rx: factor out writing ContentType to cmsg + - tls: rx: don't track the async count + - tls: rx: assume crypto always calls our callback + - tls: rx: use async as an in-out argument + - tls: decrement decrypt_pending if no async completion will be called + - net: tls: fix async vs NIC crypto offload + - tls: rx: simplify async wait + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + + -- Philip Cox Wed, 24 Jul 2024 10:47:04 +0300 + +linux-oracle (5.4.0-1128.137) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1128.137 -proposed tracker (LP: #2072103) + + [ Ubuntu: 5.4.0-190.210 ] + + * focal/linux: 5.4.0-190.210 -proposed tracker (LP: #2072108) + * CVE-2024-36016 + - tty: n_gsm: fix possible out-of-bounds in gsm0_receive() + * CVE-2022-48655 + - firmware: arm_scmi: Harden accesses to the reset domains + * CVE-2024-26907 + - RDMA/mlx5: Fix fortify source warning while accessing Eth segment + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26583 + - net/tls: Replace TLS_RX_SYNC_RUNNING with RCU + - net/tls: Fix use-after-free after the TLS device goes down and up + - tls: splice_read: fix record type check + - tls splice: remove inappropriate flags checking for MSG_PEEK + - tls: splice_read: fix accessing pre-processed records + - tls: Fix context leak on tls_device_down + - net/tls: Check for errors in tls_device_init + - net/tls: Remove the context from the list in tls_device_down + - net/tls: pass context to tls_device_decrypted() + - net/tls: Perform immediate device ctx cleanup when possible + - net/tls: Multi-threaded calls to TX tls_dev_del + - net: tls: avoid discarding data on record close + - tls: rx: don't store the record type in socket context + - tls: rx: don't store the decryption status in socket context + - tls: rx: don't issue wake ups when data is decrypted + - tls: rx: refactor decrypt_skb_update() + - tls: hw: rx: use return value of tls_device_decrypted() to carry status + - tls: rx: drop unnecessary arguments from tls_setup_from_iter() + - tls: rx: don't report text length from the bowels of decrypt + - tls: rx: wrap decryption arguments in a structure + - tls: rx: factor out writing ContentType to cmsg + - tls: rx: don't track the async count + - tls: rx: assume crypto always calls our callback + - tls: rx: use async as an in-out argument + - tls: decrement decrypt_pending if no async completion will be called + - net: tls: fix async vs NIC crypto offload + - tls: rx: simplify async wait + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + + -- Philip Cox Thu, 18 Jul 2024 11:45:44 +0300 + +linux-oracle (5.4.0-1127.136) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1127.136 -proposed tracker (LP: #2068448) + + [ Ubuntu: 5.4.0-189.209 ] + + * focal/linux: 5.4.0-189.209 -proposed tracker (LP: #2068454) + * Focal update: v5.4.275 upstream stable release (LP: #2067865) + - batman-adv: Avoid infinite loop trying to resize local TT + - Bluetooth: Fix memory leak in hci_req_sync_complete() + - nouveau: fix function cast warning + - net: openvswitch: fix unwanted error log on timeout policy probing + - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file + - geneve: fix header validation in geneve[6]_xmit_skb + - ipv6: fib: hide unused 'pn' variable + - ipv4/route: avoid unused-but-set-variable warning + - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr + - net/mlx5: Properly link new fs rules into the tree + - net: ena: Fix potential sign extension issue + - btrfs: qgroup: correctly model root qgroup rsv in convert + - drm/client: Fully protect modes[] with dev->mode_config.mutex + - vhost: Add smp_rmb() in vhost_vq_avail_empty() + - selftests: timers: Fix abs() warning in posix_timers test + - x86/apic: Force native_apic_mem_read() to use the MOV instruction + - btrfs: record delayed inode root in transaction + - selftests/ftrace: Limit length in subsystem-enable tests + - kprobes: Fix possible use-after-free issue on kprobe registration + - Revert "tracing/trigger: Fix to return error if failed to alloc snapshot" + - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get() + - tun: limit printing rate when illegal packet received by tun dev + - RDMA/rxe: Fix the problem "mutex_destroy missing" + - RDMA/mlx5: Fix port number for counter query in multi-port configuration + - drm: nv04: Fix out of bounds access + - clk: Remove prepare_lock hold assertion in __clk_release() + - clk: Mark 'all_lists' as const + - clk: remove extra empty line + - clk: Print an info line before disabling unused clocks + - clk: Initialize struct clk_core kref earlier + - clk: Get runtime PM before walking tree during disable_unused + - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ + - comedi: vmk80xx: fix incomplete endpoint checking + - serial/pmac_zilog: Remove flawed mitigation for rx irq flood + - USB: serial: option: add Fibocom FM135-GL variants + - USB: serial: option: add support for Fibocom FM650/FG650 + - USB: serial: option: add Lonsung U8300/U9300 product + - USB: serial: option: support Quectel EM060K sub-models + - USB: serial: option: add Rolling RW101-GL and RW135-GL support + - USB: serial: option: add Telit FN920C04 rmnet compositions + - usb: dwc2: host: Fix dereference issue in DDMA completion flow. + - speakup: Avoid crash on very long word + - fs: sysfs: Fix reference leak in sysfs_break_active_protection() + - nouveau: fix instmem race condition around ptr stores + - nilfs2: fix OOB in nilfs_set_de_type + - KVM: async_pf: Cleanup kvm_setup_async_pf() + - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma + - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma + - arm64: dts: mediatek: mt7622: fix IR nodename + - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible" + - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block + - arm64: dts: mt2712: add ethernet device node + - arm64: dts: mediatek: mt2712: fix validation errors + - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property + - vxlan: drop packets from invalid src-address + - mlxsw: core: Unregister EMAD trap using FORWARD action + - NFC: trf7970a: disable all regulators on removal + - net: usb: ax88179_178a: stop lying about skb->truesize + - net: gtp: Fix Use-After-Free in gtp_dellink + - ipvs: Fix checksumming on GSO of SCTP packets + - net: openvswitch: Fix Use-After-Free in ovs_ct_exit + - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash + - mlxsw: spectrum_acl_tcam: Rate limit error message + - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash + - mlxsw: spectrum_acl_tcam: Fix warning during rehash + - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage + - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work + - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue + - iavf: Fix TC config comparison with existing adapter TC config + - af_unix: Suppress false-positive lockdep splat for spin_lock() in + __unix_gc(). + - serial: core: Provide port lock wrappers + - serial: mxs-auart: add spinlock around changing cts state + - Revert "crypto: api - Disallow identical driver names" + - net/mlx5e: Fix a race in command alloc flow + - tracing: Show size of requested perf buffer + - tracing: Increase PERF_MAX_TRACE_SIZE to handle Sentinel1 and docker + together + - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old() + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853 + - btrfs: fix information leak in btrfs_ioctl_logical_to_ino() + - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma + - drm/amdgpu: Fix leak when GPU memory allocation fails + - irqchip/gic-v3-its: Prevent double free on error + - ethernet: Add helper for assigning packet type when dest address does not + match device address + - net: b44: set pause params only when interface is up + - stackdepot: respect __GFP_NOLOCKDEP allocation flag + - mtd: diskonchip: work around ubsan link failure + - tcp: Clean up kernel listener's reqsk in inet_twsk_purge() + - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge() + - dmaengine: owl: fix register access functions + - idma64: Don't try to serve interrupts when device is powered off + - i2c: smbus: fix NULL function pointer dereference + - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up + - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS + - udp: preserve the connected status if only UDP cmsg + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - Linux 5.4.275 + * Focal update: v5.4.274 upstream stable release (LP: #2067857) + - amdkfd: use calloc instead of kzalloc to avoid integer overflow + - Documentation/hw-vuln: Update spectre doc + - x86/cpu: Support AMD Automatic IBRS + - x86/bugs: Use sysfs_emit() + - timers: Update kernel-doc for various functions + - timers: Use del_timer_sync() even on UP + - timers: Rename del_timer_sync() to timer_delete_sync() + - media: staging: ipu3-imgu: Set fields before media_entity_pads_init() + - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd + - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr() + - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity() + - ARM: dts: mmp2-brownstone: Don't redeclare phandle references + - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts + - serial: max310x: fix NULL pointer dereference in I2C instantiation + - KVM: Always flush async #PF workqueue when vCPU is being destroyed + - sparc64: NMI watchdog: fix return value of __setup handler + - sparc: vDSO: fix return value of __setup handler + - crypto: qat - fix double free during reset + - crypto: qat - resolve race condition during AER recovery + - selftests/mqueue: Set timeout to 180 seconds + - ext4: correct best extent lstart adjustment logic + - fat: fix uninitialized field in nostale filehandles + - ubifs: Set page uptodate in the correct place + - ubi: Check for too small LEB size in VTBL code + - ubi: correct the calculation of fastmap size + - mtd: rawnand: meson: fix scrambling mode value in command macro + - parisc: Do not hardcode registers in checksum functions + - parisc: Fix ip_fast_csum + - parisc: Fix csum_ipv6_magic on 32-bit systems + - parisc: Fix csum_ipv6_magic on 64-bit systems + - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds + - PM: suspend: Set mem_sleep_current during kernel command line setup + - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays + - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays + - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays + - powerpc/fsl: Fix mfpmr build errors with newer binutils + - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB + - USB: serial: add device ID for VeriFone adapter + - USB: serial: cp210x: add ID for MGP Instruments PDS100 + - USB: serial: option: add MeiG Smart SLM320 product + - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M + - PM: sleep: wakeirq: fix wake irq warning in system suspend + - mmc: tmio: avoid concurrent runs of mmc_request_done() + - fuse: don't unhash root + - btrfs: fix off-by-one chunk length calculation at contains_pending_extent() + - PCI: Drop pci_device_remove() test of pci_dev->driver + - PCI/PM: Drain runtime-idle callbacks before driver removal + - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"" + - dm-raid: fix lockdep waring in "pers->hot_add_disk" + - mmc: core: Fix switch on gp3 partition + - hwmon: (amc6821) add of_match table + - ext4: fix corruption during on-line resize + - firmware: meson_sm: Rework driver as a proper platform driver + - nvmem: meson-efuse: fix function pointer type mismatch + - slimbus: core: Remove usage of the deprecated ida_simple_xx() API + - speakup: Fix 8bit characters from direct synth + - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1 + - vfio/platform: Disable virqfds on cleanup + - ring-buffer: Fix resetting of shortest_full + - ring-buffer: Fix full_waiters_pending in poll + - soc: fsl: qbman: Always disable interrupts when taking cgr_lock + - soc: fsl: qbman: Add helper for sanity checking cgr ops + - soc: fsl: qbman: Add CGR update function + - soc: fsl: qbman: Use raw spinlock for cgr_lock + - s390/zcrypt: fix reference counting on zcrypt card objects + - drm/exynos: do not return negative values from .get_modes() + - drm/imx/ipuv3: do not return negative values from .get_modes() + - drm/vc4: hdmi: do not return negative values from .get_modes() + - memtest: use {READ,WRITE}_ONCE in memory scanning + - nilfs2: fix failure to detect DAT corruption in btree and direct mappings + - nilfs2: use a more common logging style + - nilfs2: prevent kernel bug at submit_bh_wbc() + - x86/CPU/AMD: Update the Zenbleed microcode revisions + - ahci: asm1064: correct count of reported ports + - ahci: asm1064: asm1166: don't limit reported ports + - dm snapshot: fix lockup in dm_exception_table_exit + - comedi: comedi_test: Prevent timers rescheduling during deletion + - netfilter: nf_tables: reject constant set with timeout + - xfrm: Avoid clang fortify warning in copy_to_user_tmpl() + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + - USB: usb-storage: Prevent divide-by-0 error in isd200_ata_command + - usb: gadget: ncm: Fix handling of zero block length packets + - usb: port: Don't try to peer unused USB ports based on location + - tty: serial: fsl_lpuart: avoid idle preamble pending if CTS is enabled + - vt: fix unicode buffer corruption when deleting characters + - fs/aio: Check IOCB_AIO_RW before the struct aio_kiocb conversion + - objtool: is_fentry_call() crashes if call has no destination + - objtool: Add support for intra-function calls + - x86/speculation: Support intra-function call validation + - xen/events: close evtchn after mapping cleanup + - printk: Update @console_may_schedule in console_trylock_spinning() + - btrfs: allocate btrfs_ioctl_defrag_range_args on stack + - Revert "loop: Check for overflow while configuring loop" + - loop: Call loop_config_discard() only after new config is applied + - loop: Remove sector_t truncation checks + - loop: Factor out setting loop device size + - loop: Refactor loop_set_status() size calculation + - loop: Factor out configuring loop from status + - loop: Check for overflow while configuring loop + - loop: loop_set_status_from_info() check before assignment + - perf/core: Fix reentry problem in perf_output_read_group() + - efivarfs: Request at most 512 bytes for variable names + - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS + - bounds: support non-power-of-two CONFIG_NR_CPUS + - vt: fix memory overlapping when deleting chars in the buffer + - mm/memory-failure: fix an incorrect use of tail pages + - mm/migrate: set swap entry values of THP tail pages properly. + - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes + - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack() + - mmc: core: Initialize mmc_blk_ioc_data + - mmc: core: Avoid negative index with array access + - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs + - scsi: core: Fix unremoved procfs host directory regression + - usb: dwc2: host: Fix remote wakeup from hibernation + - usb: dwc2: host: Fix hibernation flow + - usb: dwc2: host: Fix ISOC flow in DDMA mode + - usb: dwc2: gadget: LPM flow fix + - usb: udc: remove warning when queue disabled ep + - scsi: qla2xxx: Fix command flush on cable pull + - x86/cpu: Enable STIBP on AMD if Automatic IBRS is enabled + - scsi: lpfc: Correct size for wqe for memset() + - USB: core: Fix deadlock in usb_deauthorize_interface() + - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet + - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa() + - tcp: properly terminate timers for kernel sockets + - dm integrity: fix out-of-range warning + - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d + - Bluetooth: hci_event: set the conn encrypted before conn establishes + - Bluetooth: Fix TOCTOU in HCI debugfs implementation + - netfilter: nf_tables: disallow timeout for anonymous sets + - net/rds: fix possible cp null dereference + - vfio/pci: Disable auto-enable of exclusive INTx IRQ + - vfio/pci: Lock external INTx masking ops + - vfio: Introduce interface to flush virqfd inject workqueue + - vfio/pci: Create persistent INTx handler + - vfio/platform: Create persistent IRQ handlers + - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be + mapped." + - mm, vmscan: prevent infinite loop for costly GFP_NOIO | __GFP_RETRY_MAYFAIL + allocations + - netfilter: nf_tables: flush pending destroy work before exit_net release + - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get() + - bpf, sockmap: Prevent lock inversion deadlock in map delete elem + - net/sched: act_skbmod: prevent kernel-infoleak + - net: stmmac: fix rx queue priority assignment + - selftests: reuseaddr_conflict: add missing new line at the end of the output + - ipv6: Fix infinite recursion in fib6_dump_done(). + - i40e: fix vf may be used uninitialized in this function warning + - staging: mmal-vchiq: Allocate and free components as required + - staging: mmal-vchiq: Fix client_component for 64 bit kernel + - staging: vc04_services: changen strncpy() to strscpy_pad() + - staging: vc04_services: fix information leak in create_component() + - fs: add a vfs_fchown helper + - fs: add a vfs_fchmod helper + - initramfs: switch initramfs unpacking to struct file based APIs + - init: open /initrd.image with O_LARGEFILE + - erspan: Add type I version 0 support. + - erspan: make sure erspan_base_hdr is present in skb->head + - net: ravb: Always process TX descriptor ring + - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw + - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit + - scsi: mylex: Fix sysfs buffer lengths + - ata: sata_mv: Fix PCI device ID table declaration compilation warning + - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with + microphone + - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank() + - s390/entry: align system call table on 8 bytes + - wifi: ath9k: fix LNA selection in ath_ant_try_scan() + - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host() + - panic: Flush kernel log buffer at the end + - arm64: dts: rockchip: fix rk3328 hdmi ports node + - arm64: dts: rockchip: fix rk3399 hdmi ports node + - ionic: set adminq irq affinity + - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num() + - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks() + - btrfs: export: handle invalid inode or root reference in btrfs_get_parent() + - btrfs: send: handle path ref underflow in header iterate_inode_ref() + - Bluetooth: btintel: Fix null ptr deref in btintel_read_version + - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails + - sysv: don't call sb_bread() with pointers_lock held + - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc() + - isofs: handle CDs with bad root inode but good Joliet root directory + - media: sta2x11: fix irq handler cast + - drm/amd/display: Fix nanosec stat overflow + - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned + int + - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default" + - block: prevent division by zero in blk_rq_stat_sum() + - Input: allocate keycode for Display refresh rate toggle + - ktest: force $buildonly = 1 for 'make_warnings_file' test type + - tools: iio: replace seekdir() in iio_generic_buffer + - usb: typec: tcpci: add generic tcpci fallback compatible + - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined + - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2 + - fbmon: prevent division by zero in fb_videomode_from_videomode() + - netfilter: nf_tables: reject new basechain after table flag update + - netfilter: nf_tables: discard table flag update with pending basechain + deletion + - tty: n_gsm: require CAP_NET_ADMIN to attach N_GSM0710 ldisc + - drm/vkms: call drm_atomic_helper_shutdown before drm_dev_put() + - virtio: reenable config if freezing device failed + - x86/mm/pat: fix VM_PAT handling in COW mappings + - drm/i915/gt: Reset queue_priority_hint on parking + - x86/alternative: Don't call text_poke() in lazy TLB mode + - Bluetooth: btintel: Fixe build regression + - VMCI: Fix possible memcpy() run-time warning in + vmci_datagram_invoke_guest_handler() + - erspan: Check IFLA_GRE_ERSPAN_VER is set. + - ip_gre: do not report erspan version on GRE interface + - firmware: meson_sm: fix to avoid potential NULL pointer dereference + - Linux 5.4.274 + * CVE-2024-26586 + - mlxsw: spectrum_acl_tcam: Fix stack corruption + * CVE-2024-26923 + - af_unix: Do not use atomic ops for unix_sk(sk)->inflight. + - af_unix: Fix garbage collector racing against connect() + * Focal update: v5.4.273 upstream stable release (LP: #2064561) + - io_uring/unix: drop usage of io_uring socket + - io_uring: drop any code related to SCM_RIGHTS + - selftests: tls: use exact comparison in recv_partial + - ASoC: rt5645: Make LattePanda board DMI match more precise + - x86/xen: Add some null pointer checking to smp.c + - MIPS: Clear Cause.BD in instruction_pointer_set + - HID: multitouch: Add required quirk for Synaptics 0xcddc device + - RDMA/mlx5: Relax DEVX access upon modify commands + - net/iucv: fix the allocation size of iucv_path_table array + - parisc/ftrace: add missing CONFIG_DYNAMIC_FTRACE check + - block: sed-opal: handle empty atoms when parsing response + - dm-verity, dm-crypt: align "struct bvec_iter" correctly + - btrfs: fix data race at btrfs_use_block_rsv() when accessing block reserve + - scsi: mpt3sas: Prevent sending diag_reset when the controller is ready + - Bluetooth: rfcomm: Fix null-ptr-deref in rfcomm_check_security + - firewire: core: use long bus reset on gap count error + - ASoC: Intel: bytcr_rt5640: Add an extra entry for the Chuwi Vi8 tablet + - Input: gpio_keys_polled - suppress deferred probe error for gpio + - ASoC: wm8962: Enable oscillator if selecting WM8962_FLL_OSC + - ASoC: wm8962: Enable both SPKOUTR_ENA and SPKOUTL_ENA in mono mode + - ASoC: wm8962: Fix up incorrect error message in wm8962_set_fll + - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak + - fs/select: rework stack allocation hack for clang + - timekeeping: Fix cross-timestamp interpolation on counter wrap + - timekeeping: Fix cross-timestamp interpolation corner case decision + - timekeeping: Fix cross-timestamp interpolation for non-x86 + - wifi: ath10k: fix NULL pointer dereference in + ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev() + - b43: dma: Fix use true/false for bool type variable + - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled + - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled + - b43: main: Fix use true/false for bool type + - wifi: b43: Stop correct queue in DMA worker when QoS is disabled + - wifi: b43: Disable QoS for bcm4331 + - wifi: wilc1000: fix declarations ordering + - wifi: wilc1000: fix RCU usage in connect path + - wifi: mwifiex: debugfs: Drop unnecessary error check for + debugfs_create_dir() + - sock_diag: annotate data-races around sock_diag_handlers[family] + - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc(). + - net: blackhole_dev: fix build warning for ethh set but not used + - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer() + - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes + - bpf: Add typecast to bpf helpers to help BTF generation + - bpf: Factor out bpf_spin_lock into helpers. + - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly + - arm64: dts: qcom: db820c: Move non-soc entries out of /soc + - arm64: dts: qcom: msm8996: Use node references in db820c + - arm64: dts: qcom: msm8996: Move regulator consumers to db820c + - arm64: dts: qcom: msm8996: Pad addresses + - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit() + - bus: tegra-aconnect: Update dependency to ARCH_TEGRA + - [Config]: Update tegra configs + - iommu/amd: Mark interrupt as managed + - wifi: brcmsmac: avoid function pointer casts + - net: ena: Remove ena_select_queue + - ARM: dts: arm: realview: Fix development chip ROM compatible value + - ARM: dts: imx6dl-yapp4: Move phy reset into switch node + - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address + - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node + - ACPI: scan: Fix device check notification handling + - x86, relocs: Ignore relocations in .notes section + - SUNRPC: fix some memleaks in gssx_dec_option_array + - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove + function + - igb: move PEROUT and EXTTS isr logic to separate functions + - igb: Fix missing time sync events + - Bluetooth: Remove superfluous call to hci_conn_check_pending() + - sr9800: Add check for usbnet_get_endpoints + - bpf: Fix hashtab overflow check on 32-bit arches + - bpf: Fix stackmap overflow check on 32-bit arches + - ipv6: fib6_rules: flush route cache when rule is changed + - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv() + - net: hns3: fix port duplex configure error in IMP reset + - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function + - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt() + function + - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function + - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function + - net/x25: fix incorrect parameter validation in the x25_getsockopt() function + - nfp: flower: handle acti_netdevs allocation failure + - dm raid: fix false positive for requeue needed during reshape + - dm: call the resume method on internal suspend + - drm/tegra: dsi: Add missing check for of_find_device_by_node + - gpu: host1x: mipi: Update tegra_mipi_request() to be node based + - drm/tegra: dsi: Make use of the helper function dev_err_probe() + - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe() + - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path + of tegra_dsi_probe() + - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths + of tegra_output_probe() + - drm/rockchip: inno_hdmi: Fix video timing + - drm: Don't treat 0 as -1 in drm_fixp2int_ceil + - drm/rockchip: lvds: do not overwrite error code + - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA + - media: tc358743: register v4l2 async device only after successful setup + - PCI/DPC: Print all TLP Prefixes, not just the first + - perf record: Fix possible incorrect free in record__switch_output() + - drm/amd/display: Fix potential NULL pointer dereferences in + 'dcn10_set_output_transfer_func()' + - perf evsel: Fix duplicate initialization of data->id in + evsel__parse_sample() + - media: em28xx: annotate unchecked call to media_device_register() + - media: v4l2-tpg: fix some memleaks in tpg_alloc + - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity + - media: edia: dvbdev: fix a use-after-free + - clk: qcom: reset: Allow specifying custom reset delay + - clk: qcom: reset: support resetting multiple bits + - clk: qcom: reset: Commonize the de/assert functions + - clk: qcom: reset: Ensure write completion on reset de/assertion + - quota: simplify drop_dquot_ref() + - quota: Fix potential NULL pointer dereference + - quota: Fix rcu annotations of inode dquot pointers + - PCI: switchtec: Fix an error handling path in switchtec_pci_probe() + - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str() + - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode() + - ALSA: seq: fix function cast warnings + - perf stat: Avoid metric-only segv + - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak + - media: go7007: add check of return value of go7007_read_addr() + - media: pvrusb2: remove redundant NULL check + - media: pvrusb2: fix pvr2_stream_callback casts + - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times + - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions + - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken + - clk: hisilicon: hi3519: Release the correct number of gates in + hi3519_clk_unregister() + - drm/tegra: put drm_gem_object ref on error in tegra_fb_create + - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref + - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a + ref + - crypto: arm/sha - fix function cast warnings + - mtd: maps: physmap-core: fix flash size larger than 32-bit + - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype + - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs + - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int() + - media: pvrusb2: fix uaf in pvr2_context_set_notify + - media: dvb-frontends: avoid stack overflow warnings with clang + - media: go7007: fix a memleak in go7007_load_encoder + - media: v4l2-core: correctly validate video and metadata ioctls + - media: rename VFL_TYPE_GRABBER to _VIDEO + - media: media/pci: rename VFL_TYPE_GRABBER to _VIDEO + - media: ttpci: fix two memleaks in budget_av_attach + - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip + - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks + - drm/msm/dpu: add division of drm_display_mode's hskew parameter + - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc. + - backlight: lm3630a: Initialize backlight_properties on init + - backlight: lm3630a: Don't set bl->props.brightness in get_brightness + - backlight: da9052: Fully initialize backlight_properties during probe + - backlight: lm3639: Fully initialize backlight_properties during probe + - backlight: lp8788: Fully initialize backlight_properties during probe + - sparc32: Fix section mismatch in leon_pci_grpci + - clk: Fix clk_core_get NULL dereference + - ALSA: usb-audio: Stop parsing channels bits when all channels are found. + - scsi: csiostor: Avoid function pointer casts + - RDMA/device: Fix a race between mad_client and cm_client init + - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn + - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr() + - watchdog: stm32_iwdg: initialize default timeout + - NFS: Fix an off by one in root_nfs_cat() + - afs: Revert "afs: Hide silly-rename files from userspace" + - tty: vt: fix 20 vs 0x20 typo in EScsiignore + - serial: max310x: fix syntax error in IRQ error message + - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT + - kconfig: fix infinite loop when expanding a macro at the end of file + - rtc: mt6397: select IRQ_DOMAIN instead of depending on it + - serial: 8250_exar: Don't remove GPIO device on suspend + - staging: greybus: fix get_channel_from_mode() failure path + - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin + - octeontx2-af: Use matching wake_up API variant in CGX command interface + - s390/vtime: fix average steal time calculation + - hsr: Fix uninit-value access in hsr_get_node() + - packet: annotate data-races around ignore_outgoing + - rds: introduce acquire/release ordering in acquire/release_in_xmit() + - hsr: Handle failures in module init + - net/bnx2x: Prevent access to a freed page in page_pool + - octeontx2-af: Use separate handlers for interrupts + - ARM: dts: sun8i-h2-plus-bananapi-m2-zero: add regulator nodes vcc-dram and + vcc1v2 + - netfilter: nf_tables: do not compare internal table flags on updates + - rcu: add a helper to report consolidated flavor QS + - bpf: report RCU QS in cpumap kthread + - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler + - regmap: Add missing map->bus check + - Linux 5.4.273 + * Focal update: v5.4.272 upstream stable release (LP: #2064555) + - lan78xx: Fix white space and style issues + - lan78xx: Add missing return code checks + - lan78xx: Fix partial packet errors on suspend/resume + - lan78xx: Fix race conditions in suspend/resume handling + - net: lan78xx: fix runtime PM count underflow on link stop + - ixgbe: {dis, en}able irqs in ixgbe_txrx_ring_{dis, en}able + - geneve: make sure to pull inner header in geneve_rx() + - net: ice: Fix potential NULL pointer dereference in ice_bridge_setlink() + - net/ipv6: avoid possible UAF in ip6_route_mpath_notify() + - net/rds: fix WARNING in rds_conn_connect_if_down + - netfilter: nft_ct: fix l3num expectations with inet pseudo family + - netfilter: nf_conntrack_h323: Add protection for bmp length out of range + - netrom: Fix a data-race around sysctl_netrom_default_path_quality + - netrom: Fix a data-race around sysctl_netrom_obsolescence_count_initialiser + - netrom: Fix data-races around sysctl_netrom_network_ttl_initialiser + - netrom: Fix a data-race around sysctl_netrom_transport_timeout + - netrom: Fix a data-race around sysctl_netrom_transport_maximum_tries + - netrom: Fix a data-race around sysctl_netrom_transport_acknowledge_delay + - netrom: Fix a data-race around sysctl_netrom_transport_busy_delay + - netrom: Fix a data-race around sysctl_netrom_transport_requested_window_size + - netrom: Fix a data-race around sysctl_netrom_transport_no_activity_timeout + - netrom: Fix a data-race around sysctl_netrom_routing_control + - netrom: Fix a data-race around sysctl_netrom_link_fails_count + - netrom: Fix data-races around sysctl_net_busy_read + - selftests: mm: fix map_hugetlb failure on 64K page size systems + - um: allow not setting extra rpaths in the linux binary + - serial: max310x: Use devm_clk_get_optional() to get the input clock + - serial: max310x: Try to get crystal clock rate from property + - serial: max310x: fail probe if clock crystal is unstable + - serial: max310x: Make use of device properties + - serial: max310x: use regmap methods for SPI batch operations + - serial: max310x: use a separate regmap for each port + - serial: max310x: prevent infinite while() loop in port startup + - Input: i8042 - fix strange behavior of touchpad on Clevo NS70PU + - hv_netvsc: Make netvsc/VF binding check both MAC and serial number + - hv_netvsc: use netif_is_bond_master() instead of open code + - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed + - y2038: rusage: use __kernel_old_timeval + - getrusage: add the "signal_struct *sig" local variable + - getrusage: move thread_group_cputime_adjusted() outside of + lock_task_sighand() + - getrusage: use __for_each_thread() + - getrusage: use sig->stats_lock rather than lock_task_sighand() + - serial: max310x: Unprepare and disable clock in error path + - regmap: allow to define reg_update_bits for no bus configuration + - regmap: Add bulk read/write callbacks into regmap_config + - serial: max310x: make accessing revision id interface-agnostic + - serial: max310x: implement I2C support + - serial: max310x: fix IO data corruption in batched operations + - arm64: dts: qcom: add PDC interrupt controller for SDM845 + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - Linux 5.4.272 + * CVE-2024-23307 + - md/raid5: fix atomicity violation in raid5_cache_count + * CVE-2024-26889 + - Bluetooth: hci_core: Fix possible buffer overflow + * CVE-2024-26828 + - cifs: fix underflow in parse_server_interfaces() + * CVE-2024-24861 + - media: xc4000: Fix atomicity violation in xc4000_get_frequency + * CVE-2023-6270 + - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts + * CVE-2024-26642 + - netfilter: nf_tables: disallow anonymous set with timeout flag + * CVE-2024-26926 + - binder: check offset alignment in binder_get_object() + * CVE-2024-26922 + - drm/amdgpu: validate the parameters of bo mapping operations more clearly + * CVE-2024-26925 + - netfilter: Cleanup nft_net->module_list from nf_tables_exit_net() + - netfilter: nf_tables: release batch on table validation from abort path + - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path + * CVE-2024-26643 + - netfilter: nf_tables: mark set as dead when unbinding anonymous set with + timeout + * CVE-2024-2201 + - x86/cpufeatures: Add new word for scattered features + - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - [Config] updateconfigs for CONFIG_BHI_{AUTO|ON|OFF} + - x86/bugs: Fix BHI documentation + - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES + - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' + - x86/bugs: Fix BHI handling of RRSBA + - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation + - x86/bugs: Fix BHI retpoline check + + -- Philip Cox Fri, 21 Jun 2024 13:34:32 -0400 + +linux-oracle (5.4.0-1126.135) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1126.135 -proposed tracker (LP: #2068286) + + [ Ubuntu: 5.4.0-187.207 ] + + * focal/linux: 5.4.0-187.207 -proposed tracker (LP: #2068291) + * CVE-2024-26925 + - netfilter: Cleanup nft_net->module_list from nf_tables_exit_net() + - netfilter: nf_tables: release batch on table validation from abort path + - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path + * CVE-2024-26643 + - netfilter: nf_tables: mark set as dead when unbinding anonymous set with + timeout + * CVE-2024-2201 + - x86/cpufeatures: Add new word for scattered features + - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - [Config] updateconfigs for CONFIG_BHI_{AUTO|ON|OFF} + - x86/bugs: Fix BHI documentation + - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES + - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' + - x86/bugs: Fix BHI handling of RRSBA + - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation + - x86/bugs: Fix BHI retpoline check + + -- Philip Cox Thu, 13 Jun 2024 13:13:09 -0400 + +linux-oracle (5.4.0-1125.134) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1125.134 -proposed tracker (LP: #2063806) + + [ Ubuntu: 5.4.0-186.206 ] + + * focal/linux: 5.4.0-186.206 -proposed tracker (LP: #2063812) + * Mount CIFS fails with Permission denied (LP: #2061986) + - cifs: fix ntlmssp auth when there is no key exchange + * USB stick can't be detected (LP: #2040948) + - usb: Disable USB3 LPM at shutdown + * CVE-2024-26733 + - net: dev: Convert sa_data to flexible array in struct sockaddr + - arp: Prevent overflow in arp_req_get(). + - stddef: Introduce DECLARE_FLEX_ARRAY() helper + * CVE-2024-26712 + - powerpc/kasan: Fix addr error caused by page alignment + * CVE-2023-52530 + - wifi: mac80211: fix potential key use-after-free + * CVE-2021-47063 + - drm: bridge/panel: Cleanup connector on bridge detach + * [Ubuntu 22.04.4/linux-image-6.5.0-26-generic] Kernel output "UBSAN: array- + index-out-of-bounds in /build/linux-hwe-6.5-34pCLi/linux- + hwe-6.5-6.5.0/drivers/net/hyperv/netvsc.c:1445:41" multiple times, + especially during boot. (LP: #2058477) + - hv: hyperv.h: Replace one-element array with flexible-array member + * CVE-2024-26614 + - tcp: make sure init the accept_queue's spinlocks once + - ipv6: init the accept_queue's spinlocks in inet6_create + * Focal update: v5.4.271 upstream stable release (LP: #2060216) + - netlink: Fix kernel-infoleak-after-free in __skb_datagram_iter + - net: ip_tunnel: prevent perpetual headroom growth + - tun: Fix xdp_rxq_info's queue_index when detaching + - ipv6: fix potential "struct net" leak in inet6_rtm_getaddr() + - lan78xx: enable auto speed configuration for LAN7850 if no EEPROM is + detected + - net: usb: dm9601: fix wrong return value in dm9601_mdio_read + - Bluetooth: Avoid potential use-after-free in hci_error_reset + - Bluetooth: hci_event: Fix handling of HCI_EV_IO_CAPA_REQUEST + - Bluetooth: Enforce validation on max value of connection interval + - netfilter: nf_tables: allow NFPROTO_INET in nft_(match/target)_validate() + - rtnetlink: fix error logic of IFLA_BRIDGE_FLAGS writing back + - efi/capsule-loader: fix incorrect allocation size + - power: supply: bq27xxx-i2c: Do not free non existing IRQ + - ALSA: Drop leftover snd-rtctimer stuff from Makefile + - afs: Fix endless loop in directory parsing + - gtp: fix use-after-free and null-ptr-deref in gtp_newlink() + - wifi: nl80211: reject iftype change with mesh ID change + - btrfs: dev-replace: properly validate device names + - dmaengine: fsl-qdma: fix SoC may hang on 16 byte unaligned read + - dmaengine: fsl-qdma: init irq after reg initialization + - mmc: core: Fix eMMC initialization with 1-bit bus connection + - x86/cpu/intel: Detect TME keyid bits before setting MTRR mask registers + - cachefiles: fix memory leak in cachefiles_add_cache() + - fs,hugetlb: fix NULL pointer dereference in hugetlbs_fill_super + - gpio: 74x164: Enable output pins after registers are reset + - Linux 5.4.271 + * Focal update: v5.4.270 upstream stable release (LP: #2060019) + - KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table() + - KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler + - net/sched: Retire CBQ qdisc + - [Config] updateconfigs for NET_SCH_CBQ + - net/sched: Retire ATM qdisc + - [Config] updateconfigs for NET_SCH_ATM + - net/sched: Retire dsmark qdisc + - [Config] updateconfigs for NET_SCH_DSMARK + - sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset + - memcg: add refcnt for pcpu stock to avoid UAF problem in drain_all_stock() + - nilfs2: replace WARN_ONs for invalid DAT metadata block requests + - userfaultfd: fix mmap_changing checking in mfill_atomic_hugetlb + - sched/rt: Fix sysctl_sched_rr_timeslice intial value + - sched/rt: Disallow writing invalid values to sched_rt_period_us + - scsi: target: core: Add TMF to tmr_list handling + - dmaengine: shdma: increase size of 'dev_id' + - dmaengine: fsl-qdma: increase size of 'irq_name' + - wifi: cfg80211: fix missing interfaces when dumping + - wifi: mac80211: fix race condition on enabling fast-xmit + - fbdev: savage: Error out if pixclock equals zero + - fbdev: sis: Error out if pixclock equals zero + - ahci: asm1166: correct count of reported ports + - ahci: add 43-bit DMA address quirk for ASMedia ASM1061 controllers + - ext4: avoid allocating blocks from corrupted group in + ext4_mb_try_best_found() + - ext4: avoid allocating blocks from corrupted group in ext4_mb_find_by_goal() + - regulator: pwm-regulator: Add validity checks in continuous .get_voltage + - nvmet-tcp: fix nvme tcp ida memory leak + - ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616 + - netfilter: conntrack: check SCTP_CID_SHUTDOWN_ACK for vtag setting in + sctp_new + - nvmet-fc: abort command when there is no binding + - hwmon: (coretemp) Enlarge per package core count limit + - scsi: lpfc: Use unsigned type for num_sge + - firewire: core: send bus reset promptly on gap count error + - virtio-blk: Ensure no requests in virtqueues before deleting vqs. + - s390/qeth: Fix potential loss of L3-IP@ in case of network issues + - pmdomain: renesas: r8a77980-sysc: CR7 must be always on + - tcp: factor out __tcp_close() helper + - tcp: return EPOLLOUT from tcp_poll only when notsent_bytes is half the limit + - tcp: add annotations around sk->sk_shutdown accesses + - pinctrl: pinctrl-rockchip: Fix a bunch of kerneldoc misdemeanours + - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups + - spi: mt7621: Fix an error message in mt7621_spi_probe() + - net: bridge: clear bridge's private skb space on xmit + - selftests/bpf: Avoid running unprivileged tests with alignment requirements + - Revert "drm/sun4i: dsi: Change the start delay calculation" + - drm/amdgpu: Check for valid number of registers to read + - x86/alternatives: Disable KASAN in apply_alternatives() + - dm-integrity: don't modify bio's immutable bio_vec in integrity_metadata() + - iomap: Set all uptodate bits for an Uptodate page + - drm/amdgpu: Fix type of second parameter in trans_msg() callback + - arm64: dts: qcom: msm8916: Fix typo in pronto remoteproc node + - PCI: tegra: Fix reporting GPIO error value + - PCI: tegra: Fix OF node reference leak + - IB/hfi1: Fix sdma.h tx->num_descs off-by-one error + - dm-crypt: don't modify the data when using authenticated encryption + - gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() + - PCI/MSI: Prevent MSI hardware interrupt number truncation + - l2tp: pass correct message length to ip6_append_data + - ARM: ep93xx: Add terminator to gpiod_lookup_table + - usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable() + - usb: cdns3: fix memory double free when handle zero packet + - usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs + - usb: roles: don't get/set_role() when usb_role_switch is unregistered + - IB/hfi1: Fix a memleak in init_credit_return + - RDMA/bnxt_re: Return error for SRQ resize + - RDMA/srpt: Make debug output more detailed + - RDMA/srpt: fix function pointer cast warnings + - scripts/bpf: teach bpf_helpers_doc.py to dump BPF helper definitions + - bpf, scripts: Correct GPL license name + - scsi: jazz_esp: Only build if SCSI core is builtin + - nouveau: fix function cast warnings + - ipv4: properly combine dev_base_seq and ipv4.dev_addr_genid + - ipv6: properly combine dev_base_seq and ipv6.dev_addr_genid + - afs: Increase buffer size in afs_update_volume_status() + - ipv6: sr: fix possible use-after-free and null-ptr-deref + - packet: move from strlcpy with unused retval to strscpy + - s390: use the correct count for __iowrite64_copy() + - tls: rx: jump to a more appropriate label + - tls: rx: drop pointless else after goto + - tls: stop recv() if initial process_rx_list gave us non-DATA + - netfilter: nf_tables: set dormant flag on hook register failure + - drm/syncobj: make lockdep complain on WAIT_FOR_SUBMIT v3 + - drm/syncobj: call drm_syncobj_fence_add_wait when WAIT_AVAILABLE flag is set + - fs/aio: Restrict kiocb_set_cancel_fn() to I/O submitted via libaio + - scripts/bpf: Fix xdp_md forward declaration typo + - Linux 5.4.270 + * CVE-2023-47233 + - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach + * CVE-2021-47070 + - uio: uio_hv_generic: use devm_kzalloc() for private data alloc + - uio_hv_generic: Fix another memory leak in error handling paths + * CVE-2024-26622 + - tomoyo: fix UAF write bug in tomoyo_write_control() + + -- Philip Cox Fri, 24 May 2024 15:34:31 -0400 + +linux-oracle (5.4.0-1124.133) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1124.133 -proposed tracker (LP: #2063680) + + [ Ubuntu: 5.4.0-182.202 ] + + * focal/linux: 5.4.0-182.202 -proposed tracker (LP: #2063685) + * CVE-2023-52530 + - wifi: mac80211: fix potential key use-after-free + * CVE-2024-26622 + - tomoyo: fix UAF write bug in tomoyo_write_control() + * CVE-2024-26614 + - tcp: make sure init the accept_queue's spinlocks once + - ipv6: init the accept_queue's spinlocks in inet6_create + * CVE-2023-47233 + - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach + + -- Philip Cox Wed, 01 May 2024 07:17:48 -0400 + +linux-oracle (5.4.0-1123.132) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1123.132 -proposed tracker (LP: #2059544) + + * Focal update: v5.4.269 upstream stable release (LP: #2058948) + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + + [ Ubuntu: 5.4.0-181.201 ] + + * focal/linux: 5.4.0-181.201 -proposed tracker (LP: #2059549) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * Focal update: v5.4.269 upstream stable release (LP: #2058948) + - PCI: mediatek: Clear interrupt status before dispatching handler + - include/linux/units.h: add helpers for kelvin to/from Celsius conversion + - units: Add Watt units + - units: change from 'L' to 'UL' + - units: add the HZ macros + - serial: sc16is7xx: set safe default SPI clock frequency + - spi: introduce SPI_MODE_X_MASK macro + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - ext4: allow for the last group to be marked as trimmed + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - parisc/firmware: Fix F-extend for PDC addresses + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - mmc: core: Use mrq.sbc in close-ended ffu + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - rename(): fix the locking of subdirectories + - block: Remove special-casing of compound pages + - mtd: spinand: macronix: Fix MX35LFxGE4AD page size + - fs: add mode_strip_sgid() helper + - fs: move S_ISGID stripping into the vfs_*() helpers + - powerpc: Use always instead of always-y in for crtsavres.o + - x86/CPU/AMD: Fix disabling XSAVES on AMD family 0x17 due to erratum + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: Use kfree(ft->g) in arfs_create_groups() + - net/mlx5e: fix a double-free in arfs_create_groups + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - rbd: don't move requests to the running list on errors + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: ddbridge: fix an error code problem in ddb_probe + - drm/msm/dpu: Ratelimit framedone timeout msgs + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - usb: hub: Replace hardcoded quirk value with BIT() macro + - fs/kernfs/dir: obey S_ISGID + - PCI/AER: Decode Requester ID when no error info found + - libsubcmd: Fix memory leak in uniq() + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: fix deadlock or deadcode of misusing dget() + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - scsi: isci: Fix an error code problem in isci_io_request_build() + - net: remove unneeded break + - ixgbe: Remove non-inclusive language + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - net: sysfs: Fix /sys/class/net/ path + - HID: apple: Add support for the 2021 Magic Keyboard + - HID: apple: Swap the Fn and Left Control keys on Apple keyboards + - HID: apple: Add 2021 magic keyboard FN key mapping + - bonding: remove print in bond_verify_device_path + - dmaengine: fsl-qdma: Fix a memory leak related to the status queue DMA + - dmaengine: fsl-qdma: Fix a memory leak related to the queue command DMA + - phy: renesas: rcar-gen3-usb2: Fix returning wrong error code + - dmaengine: fix is_slave_direction() return false when DMA_DEV_TO_DEV + - phy: ti: phy-omap-usb2: Fix NULL pointer dereference for SRP + - net: stmmac: xgmac: fix handling of DPP safety error for DMA channels + - selftests: net: avoid just another constant wait + - atm: idt77252: fix a memleak in open_card_ubr0 + - hwmon: (aspeed-pwm-tacho) mutex for tach reading + - hwmon: (coretemp) Fix out-of-bounds memory access + - hwmon: (coretemp) Fix bogus core_id to attr name mapping + - inet: read sk->sk_family once in inet_recv_error() + - rxrpc: Fix response to PING RESPONSE ACKs to a dead call + - tipc: Check the bearer type before calling tipc_udp_nl_bearer_add() + - ppp_async: limit MRU to 64K + - netfilter: nft_compat: reject unused compat flag + - netfilter: nft_compat: restrict match/target protocol to u16 + - netfilter: nft_ct: reject direction for ct id + - net/af_iucv: clean up a try_then_request_module() + - USB: serial: qcserial: add new usb-id for Dell Wireless DW5826e + - USB: serial: option: add Fibocom FM101-GL variant + - USB: serial: cp210x: add ID for IMST iM871A-USB + - hrtimer: Report offline hrtimer enqueue + - Input: atkbd - skip ATKBD_CMD_SETLEDS when skipping ATKBD_CMD_GETID + - net: stmmac: xgmac: use #define for string constants + - net: stmmac: xgmac: fix a typo of register name in DPP safety handling + - btrfs: forbid creating subvol qgroups + - btrfs: forbid deleting live subvol qgroup + - btrfs: send: return EOPNOTSUPP on unknown flags + - of: unittest: add overlay gpio test to catch gpio hog problem + - of: unittest: Fix compile in the non-dynamic case + - spi: ppc4xx: Drop write-only variable + - ASoC: rt5645: Fix deadlock in rt5645_jack_detect_work() + - MIPS: Add 'memory' clobber to csum_ipv6_magic() inline assembler + - i40e: Fix waiting for queues of all VSIs to be disabled + - tracing/trigger: Fix to return error if failed to alloc snapshot + - mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), again + - HID: wacom: generic: Avoid reporting a serial of '0' to userspace + - HID: wacom: Do not register input devices until after hid_hw_start + - USB: hub: check for alternate port before enabling A_ALT_HNP_SUPPORT + - usb: f_mass_storage: forbid async queue when shutdown happen + - i2c: i801: Remove i801_set_block_buffer_mode + - i2c: i801: Fix block process call transactions + - scsi: Revert "scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock" + - firewire: core: correct documentation of fw_csr_string() kernel API + - kbuild: Fix changing ELF file type for output of gen_btf for big endian + - nfc: nci: free rx_data_reassembly skb on NCI device cleanup + - xen-netback: properly sync TX responses + - ALSA: hda/realtek: Enable headset mic on Vaio VJFE-ADL + - binder: signal epoll threads of self-work + - misc: fastrpc: Mark all sessions as invalid in cb_remove + - ext4: fix double-free of blocks due to wrong extents moved_len + - tracing: Fix wasted memory in saved_cmdlines logic + - staging: iio: ad5933: fix type mismatch regression + - iio: magnetometer: rm3100: add boundary check for the value read from + RM3100_REG_TMRC + - ring-buffer: Clean ring_buffer_poll_wait() error return + - serial: max310x: set default value when reading clock ready bit + - serial: max310x: improve crystal stable clock detection + - x86/Kconfig: Transmeta Crusoe is CPU family 5, not 6 + - x86/mm/ident_map: Use gbpages only where full GB page should be mapped. + - mmc: slot-gpio: Allow non-sleeping GPIO ro + - ALSA: hda/conexant: Add quirk for SWS JS201D + - nilfs2: fix data corruption in dsync block recovery for small block sizes + - nilfs2: fix hang in nilfs_lookup_dirty_data_buffers() + - nfp: use correct macro for LengthSelect in BAR config + - nfp: flower: prevent re-adding mac index for bonded port + - irqchip/irq-brcmstb-l2: Add write memory barrier before exit + - can: j1939: Fix UAF in j1939_sk_match_filter during + setsockopt(SO_J1939_FILTER) + - pmdomain: core: Move the unused cleanup to a _sync initcall + - tracing: Inform kmemleak of saved_cmdlines allocation + - Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d" + - bus: moxtet: Add spi device table + - arch, mm: remove stale mentions of DISCONIGMEM + - mips: Fix max_mapnr being uninitialized on early stages + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - netfilter: ipset: fix performance regression in swap operation + - netfilter: ipset: Missing gc cancellations fixed + - net: prevent mss overflow in skb_segment() + - sched/membarrier: reduce the ability to hammer on sys_membarrier + - nilfs2: fix potential bug in end_buffer_async_write + - PM: runtime: add devm_pm_runtime_enable helper + - PM: runtime: Have devm_pm_runtime_enable() handle + pm_runtime_dont_use_autosuspend() + - drm/msm/dsi: Enable runtime PM + - lsm: new security_file_ioctl_compat() hook + - Revert "Revert "mtd: rawnand: gpmi: Fix setting busy timeout setting"" + - net: bcmgenet: Fix EEE implementation + - of: unittest: fix EXPECT text for gpio hog errors + - of: gpio unittest kfree() wrong object + - Linux 5.4.269 + * Focal update: v5.4.269 upstream stable release (LP: #2058948) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * CVE-2023-24023 + - Bluetooth: Add more enc key size check + * CVE-2024-26581 + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - netfilter: nft_set_rbtree: skip end interval element from gc + * CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + + -- Philip Cox Wed, 10 Apr 2024 08:54:23 -0400 + +linux-oracle (5.4.0-1122.131) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1122.131 -proposed tracker (LP: #2059628) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + [ Ubuntu: 5.4.0-177.197 ] + + * focal/linux: 5.4.0-177.197 -proposed tracker (LP: #2059633) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * CVE-2023-24023 + - Bluetooth: Add more enc key size check + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Focal update: v5.4.269 upstream stable release (LP: #2058948) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2024-26581 + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - netfilter: nft_set_rbtree: skip end interval element from gc + * CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + + [ Ubuntu: 5.4.0-176.196 ] + + * focal/linux: 5.4.0-176.196 -proposed tracker (LP: #2058756) + * Problems with HVCS and hotplugging (LP: #2056373) + - powerpc/pseries: Fix bad drc_index_start value parsing of drc-info entry + - powerpc/pseries: Fix of_read_drc_info_cell() to point at next record + - hvcs: Fix hvcs port reference counting + - hvcs: Use dev_groups to manage hvcs device attributes + - hvcs: Use driver groups to manage driver attributes + - hvcs: Get reference to tty in remove + - hvcs: Use vhangup in hotplug remove + - hvcs: Synchronize hotplug remove with port free + + -- Joseph Salisbury Tue, 02 Apr 2024 13:18:04 -0400 + +linux-oracle (5.4.0-1121.130) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1121.130 -proposed tracker (LP: #2055679) + + * Packaging resync (LP: #1786013) + - [Packaging] drop ABI data + - debian.oracle/dkms-versions -- update from kernel-versions (main/2024.03.04) + + [ Ubuntu: 5.4.0-175.195 ] + + * focal/linux: 5.4.0-175.195 -proposed tracker (LP: #2055684) + * Packaging resync (LP: #1786013) + - [Packaging] drop ABI data + - [Packaging] update annotations scripts + - debian.master/dkms-versions -- update from kernel-versions (main/2024.03.04) + * Drop ABI checks from kernel build (LP: #2055686) + - [Packaging] Remove in-tree abi checks + - [Packaging] Bring back install- prerequisite for checks- + - [Packaging] Remove abi-check from final-checks + * Cranky update-dkms-versions rollout (LP: #2055685) + - [Packaging] remove update-dkms-versions + - Move debian/dkms-versions to debian.master/dkms-versions + - [Packaging] Replace debian/dkms-versions with $(DEBIAN)/dkms-versions + - [Packaging] remove update-version-dkms + * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094) + - [Packaging] rules: Put usbip manpages in the correct directory + * CVE-2024-23851 + - dm ioctl: log an error if the ioctl structure is corrupted + - dm: limit the number of targets and parameter size area + * Focal update: v5.4.268 upstream stable release (LP: #2055075) + - f2fs: explicitly null-terminate the xattr list + - pinctrl: lochnagar: Don't build on MIPS + - ALSA: hda - Fix speaker and headset mic pin config for CHUWI CoreBook XPro + - ASoC: Intel: Skylake: Fix mem leak in few functions + - ASoC: nau8822: Fix incorrect type in assignment and cast to restricted + __be16 + - ASoC: Intel: Skylake: mem leak in skl register function + - ASoC: cs43130: Fix the position of const qualifier + - ASoC: cs43130: Fix incorrect frame delay configuration + - ASoC: rt5650: add mutex to avoid the jack detection failure + - nouveau/tu102: flush all pdbs on vmm flush + - net/tg3: fix race condition in tg3_reset_task() + - ASoC: da7219: Support low DC impedance headset + - nvme: introduce helper function to get ctrl state + - drm/exynos: fix a potential error pointer dereference + - drm/exynos: fix a wrong error checking + - clk: rockchip: rk3128: Fix HCLK_OTG gate register + - jbd2: correct the printing of write_flags in jbd2_write_superblock() + - drm/crtc: Fix uninit-value bug in drm_mode_setcrtc + - neighbour: Don't let neigh_forced_gc() disable preemption for long + - tracing: Have large events show up as '[LINE TOO BIG]' instead of nothing + - tracing: Add size check when printing trace_marker output + - ring-buffer: Do not record in NMI if the arch does not support cmpxchg in + NMI + - reset: hisilicon: hi6220: fix Wvoid-pointer-to-enum-cast warning + - Input: atkbd - skip ATKBD_CMD_GETID in translated mode + - Input: i8042 - add nomux quirk for Acer P459-G2-M + - s390/scm: fix virtual vs physical address confusion + - ARC: fix spare error + - Input: xpad - add Razer Wolverine V2 support + - ARM: sun9i: smp: fix return code check of of_property_match_string + - drm/crtc: fix uninitialized variable use + - ACPI: resource: Add another DMI match for the TongFang GMxXGxx + - binder: use EPOLLERR from eventpoll.h + - binder: fix trivial typo of binder_free_buf_locked() + - binder: fix comment on binder_alloc_new_buf() return value + - uio: Fix use-after-free in uio_open + - parport: parport_serial: Add Brainboxes BAR details + - parport: parport_serial: Add Brainboxes device IDs and geometry + - coresight: etm4x: Fix width of CCITMIN field + - x86/lib: Fix overflow when counting digits + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhotplug: Quieten some DLPAR operations + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - net: netlabel: Fix kerneldoc warnings + - netlabel: remove unused parameter in netlbl_netlink_auditinfo() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: virtio - don't use 'default m' + - virtio_crypto: Introduce VIRTIO_CRYPTO_NOSPC + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - ncsi: internal.h: Fix a spello + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - rtlwifi: Use ffs in _phy_calculate_bit_shift + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - scsi: hisi_sas: Replace with standard error code return value + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - rtlwifi: rtl8192de: make arrays static const, makes object smaller + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - media: pvrusb2: fix use after free on context disconnection + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - media: dvbdev: drop refcount on error path in dvb_device_open() + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drivers: clk: zynqmp: calculate closest mux rate + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update annotations for CONFIG_MMC_SDHCI_OMAP + - [Config] remove sdhci-omap module for arm64/ppc64el + - of: Fix double free in of_parse_phandle_with_args_map + - of: unittest: Fix of_count_phandle_with_args() expected value message + - binder: fix async space check for 0-sized buffers + - binder: fix use-after-free in shinker's callback + - Input: atkbd - use ab83 as id when skipping the getid command + - Revert "ASoC: atmel: Remove system clock tree configuration for + at91sam9g20ek" + - binder: fix race between mmput() and do_exit() + - binder: fix unused alloc->free_async_space + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - ALSA: oxygen: Fix right channel of capture volume mixer + - fbdev: flush deferred work in fb_deferred_io_fsync() + - rootfs: Fix support for rootfstype= when root= is given + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - HID: wacom: Correct behavior when processing some confidence == false + touches + - mips: Fix incorrect max_low_pfn adjustment + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - perf genelf: Set ELF program header addresses properly + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Add perf_env__numa_node() + - perf record: Move sb_evlist to 'struct record' + - perf top: Move sb_evlist to 'struct perf_top' + - perf bpf: Decouple creating the evlist from adding the SB event + - perf env: Avoid recursively taking env->bpf_progs.lock + - apparmor: avoid crash when parsed profile name is empty + - serial: imx: Correct clock error message in function probe() + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: qualcomm: rmnet: fix global oob in rmnet_policy + - net: phy: micrel: populate .soft_reset for KSZ9131 + - net: ravb: Fix dma_addr_t truncation in error case + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - netfilter: nf_tables: skip dead set elements in netlink dump + - ipvs: avoid stat macros calls from preemptible context + - kdb: Censor attempts to set PROMPT without ENABLE_MEM_READ + - kdb: Fix a potential buffer overflow in kdb_local() + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - perf top: Skip side-band event setup if HAVE_LIBBPF_SUPPORT is not set + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - Linux 5.4.268 + * CVE-2024-24855 + - scsi: lpfc: Fix a possible data race in lpfc_unregister_fcf_rescan() + * Focal update: v5.4.267 upstream stable release (LP: #2054406) + - nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to + llcp_local + - i40e: Fix filter input checks to prevent config with invalid values + - net: sched: em_text: fix possible memory leak in em_text_destroy() + - can: raw: add support for SO_TXTIME/SCM_TXTIME + - can: raw: add support for SO_MARK + - net-timestamp: extend SOF_TIMESTAMPING_OPT_ID to HW timestamps + - ARM: sun9i: smp: Fix array-index-out-of-bounds read in sunxi_mc_smp_init + - net: bcmgenet: Fix FCS generation for fragmented skbuffs + - net: Save and restore msg_namelen in sock_sendmsg + - i40e: fix use-after-free in i40e_aqc_add_filters() + - ASoC: meson: g12a: extract codec-to-codec utils + - [Config] Update annotations for CONFIG_SND_MESON_CODEC_GLUE + - ASoC: meson: g12a-tohdmitx: Validate written enum values + - ASoC: meson: g12a-tohdmitx: Fix event generation for S/PDIF mux + - i40e: Restore VF MSI-X state during PCI reset + - net/qla3xxx: switch from 'pci_' to 'dma_' API + - net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues + - asix: Add check for usbnet_get_endpoints + - bnxt_en: Remove mis-applied code from bnxt_cfg_ntp_filters() + - net: Implement missing SO_TIMESTAMPING_NEW cmsg support + - mm/memory-failure: check the mapcount of the precise page + - firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and + ASM108x/VT630x PCIe cards + - i2c: core: Fix atomic xfer check for non-preempt config + - mm: fix unmap_mapping_range high bits shift bug + - mmc: rpmb: fixes pause retune on all RPMB partitions. + - mmc: core: Cancel delayed work before releasing host + - mmc: sdhci-sprd: Fix eMMC init failure after hw reset + - ath10k: Wait until copy complete is actually done before completing + - ath10k: Add interrupt summary based CE processing + - ath10k: Keep track of which interrupts fired, don't poll them + - ath10k: Get rid of "per_ce_irq" hw param + - PCI: Extract ATS disabling to a helper function + - PCI: Disable ATS for specific Intel IPU E2000 devices + - net/dst: use a smaller percpu_counter batch for dst entries accounting + - ipv6: make ip6_rt_gc_expire an atomic_t + - ipv6: remove max_size check inline with ipv4 + - ASoC: meson: codec-glue: fix pcm format cast warning + - Linux 5.4.267 + * CVE-2023-23000 + - phy: tegra: xusb: Fix return value of tegra_xusb_find_port_node function + * CVE-2023-23004 + - malidp: Fix NULL vs IS_ERR() checking + * CVE-2023-46838 + - xen-netback: don't produce zero-size SKB frags + * CVE-2024-1086 + - netfilter: nf_tables: reject QUEUE/DROP verdict parameters + * Focal update: v5.4.266 upstream stable release (LP: #2051655) + - ALSA: hda/realtek: Enable headset on Lenovo M90 Gen5 + - ksmbd: fix wrong name of SMB2_CREATE_ALLOCATION_SIZE + - ARM: OMAP2+: Fix null pointer dereference and memory leak in + omap_soc_device_init + - reset: Fix crash when freeing non-existent optional resets + - s390/vx: fix save/restore of fpu kernel context + - wifi: mac80211: mesh_plink: fix matches_local logic + - net/mlx5: improve some comments + - net/mlx5: Fix fw tracer first block check + - net/mlx5e: Correct snprintf truncation handling for fw_version buffer used + by representors + - net: sched: ife: fix potential use-after-free + - ethernet: atheros: fix a memleak in atl1e_setup_ring_resources + - net/rose: fix races in rose_kill_by_device() + - net: check vlan filter feature in vlan_vids_add_by_dev() and + vlan_vids_del_by_dev() + - afs: Fix the dynamic root's d_delete to always delete unused dentries + - afs: Fix dynamic root lookup DNS check + - net: warn if gso_type isn't set for a GSO SKB + - net: check dev->gso_max_size in gso_features_check() + - afs: Fix overwriting of result of DNS query + - i2c: aspeed: Handle the coalesced stop conditions with the start conditions. + - pinctrl: at91-pio4: use dedicated lock class for IRQ + - ALSA: hda/hdmi: Add quirk to force pin connectivity on NUC10 + - ALSA: hda/hdmi: add force-connect quirk for NUC5CPYB + - smb: client: fix NULL deref in asn1_ber_decoder() + - btrfs: do not allow non subvolume root targets for snapshot + - interconnect: Treat xlate() returning NULL node as an error + - iio: imu: inv_mpu6050: fix an error code problem in inv_mpu6050_read_raw + - Input: ipaq-micro-keys - add error handling for devm_kmemdup + - scsi: bnx2fc: Fix skb double free in bnx2fc_rcv() + - iio: common: ms_sensors: ms_sensors_i2c: fix humidity conversion time table + - iio: adc: ti_am335x_adc: Fix return value check of tiadc_request_dma() + - wifi: cfg80211: Add my certificate + - wifi: cfg80211: fix certs build to not depend on file order + - USB: serial: ftdi_sio: update Actisense PIDs constant names + - USB: serial: option: add Quectel EG912Y module support + - USB: serial: option: add Foxconn T99W265 with new baseline + - USB: serial: option: add Quectel RM500Q R13 firmware support + - Bluetooth: hci_event: Fix not checking if HCI_OP_INQUIRY has been sent + - net: 9p: avoid freeing uninit memory in p9pdu_vreadf + - net: rfkill: gpio: set GPIO direction + - x86/alternatives: Sync core before enabling interrupts + - usb: fotg210-hcd: delete an incorrect bounds test + - ring-buffer: Fix wake ups when buffer_percent is set to 100 + - block: Don't invalidate pagecache for invalid falloc modes + - Linux 5.4.266 + * CVE-2024-0607 + - netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval() + + -- Joseph Salisbury Wed, 13 Mar 2024 11:14:52 -0400 + +linux-oracle (5.4.0-1120.129) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1120.129 -proposed tracker (LP: #2055972) + + [ Ubuntu: 5.4.0-174.193 ] + + * focal/linux: 5.4.0-174.193 -proposed tracker (LP: #2055978) + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/s2024.02.05) + * CVE-2024-24855 + - scsi: lpfc: Fix a possible data race in lpfc_unregister_fcf_rescan() + * CVE-2024-1086 + - netfilter: nf_tables: reject QUEUE/DROP verdict parameters + * CVE-2023-23004 + - malidp: Fix NULL vs IS_ERR() checking + * CVE-2023-23000 + - phy: tegra: xusb: Fix return value of tegra_xusb_find_port_node function + + -- Joseph Salisbury Mon, 11 Mar 2024 13:56:48 -0400 + +linux-oracle (5.4.0-1119.128) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1119.128 -proposed tracker (LP: #2052130) + + * Focal update: v5.4.260 upstream stable release (LP: #2049024) + - [Config] remove CONFIG_BLK_DEV_SX8 + + [ Ubuntu: 5.4.0-173.191 ] + + * focal/linux: 5.4.0-173.191 -proposed tracker (LP: #2052135) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2024.02.05) + * CVE-2023-0340 + - vhost: use kzalloc() instead of kmalloc() followed by memset() + * CVE-2023-6915 + - ida: Fix crash in ida_free when the bitmap is empty + * Focal update: v5.4.265 upstream stable release (LP: #2051644) + - afs: Fix refcount underflow from error handling race + - net: ipv6: support reporting otherwise unknown prefix flags in RTM_NEWPREFIX + - qca_debug: Prevent crash on TX ring changes + - qca_debug: Fix ethtool -G iface tx behavior + - qca_spi: Fix reset behavior + - atm: solos-pci: Fix potential deadlock on &cli_queue_lock + - atm: solos-pci: Fix potential deadlock on &tx_queue_lock + - atm: Fix Use-After-Free in do_vcc_ioctl + - qed: Fix a potential use-after-free in qed_cxt_tables_alloc + - net: Remove acked SYN flag from packet in the transmit queue correctly + - sign-file: Fix incorrect return values check + - vsock/virtio: Fix unsigned integer wrap around in + virtio_transport_has_space() + - net: stmmac: use dev_err_probe() for reporting mdio bus registration failure + - net: stmmac: Handle disabled MDIO busses from devicetree + - cred: switch to using atomic_long_t + - ALSA: hda/hdmi: add force-connect quirks for ASUSTeK Z170 variants + - usb: aqc111: check packet for fixup for true limit + - blk-throttle: fix lockdep warning of "cgroup_mutex or RCU read lock + required!" + - bcache: avoid oversize memory allocation by small stripe_size + - bcache: add code comments for bch_btree_node_get() and + __bch_btree_node_alloc() + - bcache: avoid NULL checking to c->root in run_cache_set() + - platform/x86: intel_telemetry: Fix kernel doc descriptions + - HID: add ALWAYS_POLL quirk for Apple kb + - HID: hid-asus: reset the backlight brightness level on resume + - HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad + - asm-generic: qspinlock: fix queued_spin_value_unlocked() implementation + - net: usb: qmi_wwan: claim interface 4 for ZTE MF290 + - HID: hid-asus: add const to read-only outgoing usb buffer + - soundwire: stream: fix NULL pointer dereference for multi_link + - ext4: prevent the normalized size from exceeding EXT_MAX_BLOCKS + - arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify + - team: Fix use-after-free when an option instance allocation fails + - ring-buffer: Fix memory leak of free page + - mmc: block: Be sure to wait while busy in CQE error recovery + - powerpc/ftrace: Create a dummy stackframe to fix stack unwind + - powerpc/ftrace: Fix stack teardown in ftrace_no_trace + - Linux 5.4.265 + * Focal update: v5.4.264 upstream stable release (LP: #2049935) + - hrtimers: Push pending hrtimers away from outgoing CPU earlier + - netfilter: ipset: fix race condition between swap/destroy and kernel side + add/del/test + - tg3: Move the [rt]x_dropped counters to tg3_napi + - tg3: Increment tx_dropped in tg3_tso_bug() + - kconfig: fix memory leak from range properties + - drm/amdgpu: correct chunk_ptr to a pointer to chunk. + - of: base: Add of_get_cpu_state_node() to get idle states for a CPU node + - ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic + - ACPI/IORT: Make iort_msi_map_rid() PCI agnostic + - of/iommu: Make of_map_rid() PCI agnostic + - of/irq: make of_msi_map_get_device_domain() bus agnostic + - of/irq: Make of_msi_map_rid() PCI bus agnostic + - of: base: Fix some formatting issues and provide missing descriptions + - of: Fix kerneldoc output formatting + - of: Add missing 'Return' section in kerneldoc comments + - of: dynamic: Fix of_reconfig_get_state_change() return value documentation + - ipv6: fix potential NULL deref in fib6_add() + - hv_netvsc: rndis_filter needs to select NLS + - net: arcnet: Fix RESET flag handling + - net: arcnet: com20020 fix error handling + - arcnet: restoring support for multiple Sohard Arcnet cards + - ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit() + - net: hns: fix fake link up on xge port + - netfilter: xt_owner: Fix for unsafe access of sk->sk_socket + - tcp: do not accept ACK of bytes we never sent + - bpf: sockmap, updating the sg structure should also update curr + - RDMA/bnxt_re: Correct module description string + - hwmon: (acpi_power_meter) Fix 4.29 MW bug + - ASoC: wm_adsp: fix memleak in wm_adsp_buffer_populate + - tracing: Fix a warning when allocating buffered events fails + - scsi: be2iscsi: Fix a memleak in beiscsi_init_wrb_handle() + - ARM: imx: Check return value of devm_kasprintf in imx_mmdc_perf_init + - ARM: dts: imx: make gpt node name generic + - ARM: dts: imx7: Declare timers compatible with fsl,imx6dl-gpt + - ALSA: pcm: fix out-of-bounds in snd_pcm_state_names + - nilfs2: prevent WARNING in nilfs_sufile_set_segment_usage() + - tracing: Always update snapshot buffer size + - tracing: Fix incomplete locking when disabling buffered events + - tracing: Fix a possible race when disabling buffered events + - packet: Move reference count in packet_sock to atomic_long_t + - arm64: dts: mediatek: mt7622: fix memory node warning check + - arm64: dts: mediatek: mt8173-evb: Fix regulator-fixed node names + - gpiolib: sysfs: Fix error handling on failed export + - mmc: core: add helpers mmc_regulator_enable/disable_vqmmc + - mmc: sdhci-sprd: Fix vqmmc not shutting down after the card was pulled + - usb: gadget: f_hid: fix report descriptor allocation + - parport: Add support for Brainboxes IX/UC/PX parallel cards + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - ARM: PL011: Fix DMA support + - serial: sc16is7xx: address RX timeout interrupt errata + - serial: 8250_omap: Add earlycon support for the AM654 UART controller + - x86/CPU/AMD: Check vendor in the AMD microcode callback + - KVM: s390/mm: Properly reset no-dat + - nilfs2: fix missing error check for sb_set_blocksize call + - io_uring/af_unix: disable sending io_uring over sockets + - netlink: don't call ->netlink_bind with table lock held + - genetlink: add CAP_NET_ADMIN test for multicast bind + - psample: Require 'CAP_NET_ADMIN' when joining "packets" group + - drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group + - tools headers UAPI: Sync linux/perf_event.h with the kernel sources + - cifs: Fix non-availability of dedup breaking generic/304 + - smb: client: fix potential NULL deref in parse_dfs_referrals() + - devcoredump : Serialize devcd_del work + - devcoredump: Send uevent once devcd is ready + - Linux 5.4.264 + * CVE-2024-0646 + - net: tls, update curr on splice as well + * CVE-2024-0565 + - smb: client: fix OOB in receive_encrypted_standard() + * CVE-2023-51781 + - appletalk: Fix Use-After-Free in atalk_ioctl + * CVE-2023-51782 + - net/rose: Fix Use-After-Free in rose_ioctl + * Focal update: v5.4.263 upstream stable release (LP: #2049084) + - driver core: Release all resources during unbind before updating device + links + - RDMA/irdma: Prevent zero-length STAG registration + - PCI: keystone: Drop __init from ks_pcie_add_pcie_{ep,port}() + - afs: Make error on cell lookup failure consistent with OpenAFS + - drm/panel: simple: Fix Innolux G101ICE-L01 bus flags + - drm/panel: simple: Fix Innolux G101ICE-L01 timings + - ata: pata_isapnp: Add missing error check for devm_ioport_map() + - drm/rockchip: vop: Fix color for RGB888/BGR888 format on VOP full + - HID: core: store the unique system identifier in hid_device + - HID: fix HID device resource race between HID core and debugging support + - ipv4: Correct/silence an endian warning in __ip_do_redirect + - net: usb: ax88179_178a: fix failed operations during ax88179_reset + - arm/xen: fix xen_vcpu_info allocation alignment + - amd-xgbe: handle corner-case during sfp hotplug + - amd-xgbe: handle the corner-case during tx completion + - amd-xgbe: propagate the correct speed and duplex status + - net: axienet: Fix check for partial TX checksum + - afs: Return ENOENT if no cell DNS record can be found + - afs: Fix file locking on R/O volumes to operate in local mode + - nvmet: remove unnecessary ctrl parameter + - nvmet: nul-terminate the NQNs passed in the connect command + - MIPS: KVM: Fix a build warning about variable set but not used + - ext4: add a new helper to check if es must be kept + - ext4: factor out __es_alloc_extent() and __es_free_extent() + - ext4: use pre-allocated es in __es_insert_extent() + - ext4: use pre-allocated es in __es_remove_extent() + - ext4: using nofail preallocation in ext4_es_remove_extent() + - ext4: using nofail preallocation in ext4_es_insert_delayed_block() + - ext4: using nofail preallocation in ext4_es_insert_extent() + - ext4: fix slab-use-after-free in ext4_es_insert_extent() + - ext4: make sure allocate pending entry not fail + - arm64: cpufeature: Extract capped perfmon fields + - KVM: arm64: limit PMU version to PMUv3 for ARMv8.1 + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1402CVA + - bcache: replace a mistaken IS_ERR() by IS_ERR_OR_NULL() in + btree_gc_coalesce() + - s390/dasd: protect device queue against concurrent access + - USB: serial: option: add Luat Air72*U series products + - hv_netvsc: Fix race of register_netdevice_notifier and VF register + - hv_netvsc: Mark VF as slave before exposing it to user-mode + - dm-delay: fix a race between delay_presuspend and delay_bio + - bcache: check return value from btree_node_alloc_replacement() + - bcache: prevent potential division by zero error + - USB: serial: option: add Fibocom L7xx modules + - USB: serial: option: fix FM101R-GL defines + - USB: serial: option: don't claim interface 4 for ZTE MF290 + - USB: dwc2: write HCINT with INTMASK applied + - usb: dwc3: set the dma max_seg_size + - USB: dwc3: qcom: fix resource leaks on probe deferral + - USB: dwc3: qcom: fix wakeup after probe deferral + - io_uring: fix off-by one bvec index + - pinctrl: avoid reload of p state in list iteration + - firewire: core: fix possible memory leak in create_units() + - mmc: block: Do not lose cache flush during CQE error recovery + - ALSA: hda: Disable power-save on KONTRON SinglePC + - ALSA: hda/realtek: Headset Mic VREF to 100% + - ALSA: hda/realtek: Add supported ALC257 for ChromeOS + - dm-verity: align struct dm_verity_fec_io properly + - dm verity: don't perform FEC for failed readahead IO + - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR + - powerpc: Don't clobber f0/vs0 during fp|altivec register save + - btrfs: fix off-by-one when checking chunk map includes logical address + - btrfs: send: ensure send_fd is writable + - btrfs: make error messages more clear when getting a chunk map + - Input: xpad - add HyperX Clutch Gladiate Support + - net: stmmac: xgmac: Disable FPE MMC interrupts + - ravb: Fix races between ravb_tx_timeout_work() and net related ops + - net: ravb: Use pm_runtime_resume_and_get() + - net: ravb: Start TX queues after HW initialization succeeded + - smb3: fix touch -h of symlink + - s390/mm: fix phys vs virt confusion in mark_kernel_pXd() functions family + - s390/cmma: fix detection of DAT pages + - mtd: cfi_cmdset_0001: Support the absence of protection registers + - mtd: cfi_cmdset_0001: Byte swap OTP info + - fbdev: stifb: Make the STI next font pointer a 32-bit signed offset + - ima: annotate iint mutex to avoid lockdep false positive warnings + - ovl: skip overlayfs superblocks at global sync + - ima: detect changes to the backing overlay file + - scsi: qla2xxx: Simplify the code for aborting SCSI commands + - scsi: core: Introduce the scsi_cmd_to_rq() function + - scsi: qla2xxx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request + - scsi: qla2xxx: Fix system crash due to bad pointer access + - cpufreq: imx6q: don't warn for disabling a non-existing frequency + - cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily + - mmc: cqhci: Increase recovery halt timeout + - mmc: cqhci: Warn of halt or task clear failure + - mmc: cqhci: Fix task clearing in CQE error recovery + - mmc: core: convert comma to semicolon + - mmc: block: Retry commands in CQE error recovery + - Linux 5.4.263 + * Focal update: v5.4.262 upstream stable release (LP: #2049069) + - locking/ww_mutex/test: Fix potential workqueue corruption + - perf/core: Bail out early if the request AUX area is out of bound + - clocksource/drivers/timer-imx-gpt: Fix potential memory leak + - clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 hardware + - x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size + - wifi: mac80211_hwsim: fix clang-specific fortify warning + - wifi: mac80211: don't return unset power in ieee80211_get_tx_power() + - wifi: ath9k: fix clang-specific fortify warnings + - wifi: ath10k: fix clang-specific fortify warning + - net: annotate data-races around sk->sk_tx_queue_mapping + - net: annotate data-races around sk->sk_dst_pending_confirm + - wifi: ath10k: Don't touch the CE interrupt registers after power up + - Bluetooth: Fix double free in hci_conn_cleanup + - platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e + - drm/komeda: drop all currently held locks if deadlock happens + - drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7 + - drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga + - drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is NULL + - selftests/efivarfs: create-read: fix a resource leak + - crypto: pcrypt - Fix hungtask for PADATA_RESET + - RDMA/hfi1: Use FIELD_GET() to extract Link Width + - fs/jfs: Add check for negative db_l2nbperpage + - fs/jfs: Add validity check for db_maxag and db_agpref + - jfs: fix array-index-out-of-bounds in dbFindLeaf + - jfs: fix array-index-out-of-bounds in diAlloc + - ARM: 9320/1: fix stack depot IRQ stack filter + - ALSA: hda: Fix possible null-ptr-deref when assigning a stream + - PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields + - atm: iphase: Do PCI error checks on own line + - scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup() + - HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W + - tty: vcc: Add check for kstrdup() in vcc_probe() + - usb: gadget: f_ncm: Always set current gadget in ncm_bind() + - i2c: sun6i-p2wi: Prevent potential division by zero + - media: gspca: cpia1: shift-out-of-bounds in set_flicker + - media: vivid: avoid integer overflow + - gfs2: ignore negated quota changes + - media: cobalt: Use FIELD_GET() to extract Link Width + - drm/amd/display: Avoid NULL dereference of timing generator + - kgdb: Flush console before entering kgdb on panic + - ASoC: ti: omap-mcbsp: Fix runtime PM underflow warnings + - pwm: Fix double shift bug + - wifi: iwlwifi: Use FW rate for non-data frames + - NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO + - ipvlan: add ipvlan_route_v6_outbound() helper + - tty: Fix uninit-value access in ppp_sync_receive() + - net: hns3: fix variable may not initialized problem in hns3_init_mac_addr() + - tipc: Fix kernel-infoleak due to uninitialized TLV value + - ppp: limit MRU to 64K + - xen/events: fix delayed eoi list handling + - ptp: annotate data-race around q->head and q->tail + - bonding: stop the device in bond_setup_by_slave() + - net: ethernet: cortina: Fix max RX frame define + - net: ethernet: cortina: Handle large frames + - net: ethernet: cortina: Fix MTU max setting + - netfilter: nf_conntrack_bridge: initialize err to 0 + - net: stmmac: Rework stmmac_rx() + - net: stmmac: fix rx budget limit check + - net/mlx5_core: Clean driver version and name + - net/mlx5e: Check return value of snprintf writing to fw_version buffer for + representors + - macvlan: Don't propagate promisc change to lower dev in passthru + - tools/power/turbostat: Fix a knl bug + - cifs: spnego: add ';' in HOST_KEY_LEN + - media: venus: hfi: add checks to perform sanity on queue pointers + - randstruct: Fix gcc-plugin performance mode to stay in group + - bpf: Fix precision tracking for BPF_ALU | BPF_TO_BE | BPF_END + - scsi: megaraid_sas: Increase register read retry rount from 3 to 30 for + selected registers + - x86/cpu/hygon: Fix the CPU topology evaluation for real + - KVM: x86: hyper-v: Don't auto-enable stimer on write from user-space + - KVM: x86: Ignore MSR_AMD64_TW_CFG access + - audit: don't take task_lock() in audit_exe_compare() code path + - audit: don't WARN_ON_ONCE(!current->mm) in audit_exe_compare() + - hvc/xen: fix error path in xen_hvc_init() to always register frontend driver + - PCI/sysfs: Protect driver's D3cold preference from user space + - ACPI: resource: Do IRQ override on TongFang GMxXGxx + - mmc: meson-gx: Remove setting of CMD_CFG_ERROR + - genirq/generic_chip: Make irq_remove_generic_chip() irqdomain aware + - PCI: keystone: Don't discard .remove() callback + - PCI: keystone: Don't discard .probe() callback + - parisc/pdc: Add width field to struct pdc_model + - clk: qcom: ipq8074: drop the CLK_SET_RATE_PARENT flag from PLL clocks + - mmc: vub300: fix an error code + - PM: hibernate: Use __get_safe_page() rather than touching the list + - PM: hibernate: Clean up sync_read handling in snapshot_write_next() + - btrfs: don't arbitrarily slow down delalloc if we're committing + - jbd2: fix potential data lost in recovering journal raced with synchronizing + fs bdev + - quota: explicitly forbid quota files from being encrypted + - kernel/reboot: emergency_restart: Set correct system_state + - i2c: core: Run atomic i2c xfer when !preemptible + - mcb: fix error handling for different scenarios when parsing + - dmaengine: stm32-mdma: correct desc prep when channel running + - mm/cma: use nth_page() in place of direct struct page manipulation + - i3c: master: cdns: Fix reading status register + - parisc: Prevent booting 64-bit kernels on PA1.x machines + - parisc/pgtable: Do not drop upper 5 address bits of physical address + - ALSA: info: Fix potential deadlock at disconnection + - ALSA: hda/realtek - Enable internal speaker of ASUS K6500ZC + - serial: meson: remove redundant initialization of variable id + - tty: serial: meson: retrieve port FIFO size from DT + - serial: meson: Use platform_get_irq() to get the interrupt + - tty: serial: meson: fix hard LOCKUP on crtscts mode + - Bluetooth: btusb: add Realtek 8822CE to usb_device_id table + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0cb8:0xc559 + - bluetooth: Add device 0bda:887b to device tables + - bluetooth: Add device 13d3:3571 to device tables + - Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables + - Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE + - Revert ncsi: Propagate carrier gain/loss events to the NCSI controller + - net: dsa: lan9303: consequently nested-lock physical MDIO + - i2c: i801: fix potential race in i801_block_transaction_byte_by_byte + - media: lirc: drop trailing space from scancode transmit + - media: sharp: fix sharp encoding + - media: venus: hfi_parser: Add check to keep the number of codecs within + range + - media: venus: hfi: fix the check to handle session buffer requirement + - media: venus: hfi: add checks to handle capabilities from firmware + - nfsd: fix file memleak on client_opens_release + - ext4: apply umask if ACL support is disabled + - ext4: correct offset of gdb backup in non meta_bg group to update_backups + - ext4: correct return value of ext4_convert_meta_bg + - ext4: correct the start block of counting reserved clusters + - ext4: remove gdb backup copy for meta bg in setup_new_flex_group_blocks + - drm/amdgpu: fix error handling in amdgpu_bo_list_get() + - tracing: Have trace_event_file have ref counters + - netfilter: nf_tables: pass context to nft_set_destroy() + - netfilter: nftables: rename set element data activation/deactivation + functions + - netfilter: nf_tables: drop map element references from preparation phase + - netfilter: nft_set_rbtree: Switch to node list walk for overlap detection + - netfilter: nft_set_rbtree: fix null deref on element insertion + - netfilter: nft_set_rbtree: fix overlap expiration walk + - netfilter: nf_tables: don't skip expired elements during walk + - netfilter: nf_tables: GC transaction API to avoid race with control plane + - netfilter: nf_tables: adapt set backend to use GC transaction API + - netfilter: nft_set_hash: mark set element as dead when deleting from packet + path + - netfilter: nf_tables: remove busy mark and gc batch API + - netfilter: nf_tables: fix GC transaction races with netns and netlink event + exit path + - netfilter: nf_tables: GC transaction race with netns dismantle + - netfilter: nf_tables: GC transaction race with abort path + - netfilter: nf_tables: use correct lock to protect gc_list + - netfilter: nf_tables: defer gc run if previous batch is still pending + - netfilter: nft_set_rbtree: skip sync GC for new elements in this transaction + - netfilter: nft_set_rbtree: use read spinlock to avoid datapath contention + - netfilter: nft_set_hash: try later when GC hits EAGAIN on iteration + - netfilter: nf_tables: fix memleak when more than 255 elements expired + - netfilter: nf_tables: unregister flowtable hooks on netns exit + - netfilter: nf_tables: double hook unregistration in netns path + - netfilter: nftables: update table flags from the commit phase + - netfilter: nf_tables: fix table flag updates + - netfilter: nf_tables: disable toggling dormant table state more than once + - netfilter: nf_tables: bogus EBUSY when deleting flowtable after flush (for + 5.4) + - Linux 5.4.262 + * Focal update: v5.4.261 upstream stable release (LP: #2049049) + - vfs: fix readahead(2) on block devices + - genirq/matrix: Exclude managed interrupts in irq_matrix_allocated() + - i40e: fix potential memory leaks in i40e_remove() + - tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed + - wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for debugfs_create_file() + - wifi: mt76: mt7603: rework/fix rx pse hang check + - tcp_metrics: add missing barriers on delete + - tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics() + - tcp_metrics: do not create an entry from tcp_init_metrics() + - wifi: rtlwifi: fix EDCA limit set by BT coexistence + - can: dev: can_restart(): don't crash kernel if carrier is OK + - can: dev: can_restart(): fix race condition between controller restart and + netif_carrier_on() + - thermal: core: prevent potential string overflow + - r8169: use tp_to_dev instead of open code + - r8169: fix rare issue with broken rx after link-down on RTL8125 + - chtls: fix tp->rcv_tstamp initialization + - tcp: Remove one extra ktime_get_ns() from cookie_init_timestamp + - tcp: fix cookie_init_timestamp() overflows + - ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias() + - ipv6: avoid atomic fragment on GSO packets + - net: add DEV_STATS_READ() helper + - ipvlan: properly track tx_errors + - regmap: debugfs: Fix a erroneous check after snprintf() + - clk: qcom: clk-rcg2: Fix clock rate overflow for high parent frequencies + - clk: qcom: gcc-sm8150: use ARRAY_SIZE instead of specifying num_parents + - clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src + - clk: imx: Select MXC_CLK for CLK_IMX8QXP + - clk: keystone: pll: fix a couple NULL vs IS_ERR() checks + - clk: npcm7xx: Fix incorrect kfree + - clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data + - platform/x86: wmi: Fix probe failure when failing to register WMI devices + - platform/x86: wmi: remove unnecessary initializations + - platform/x86: wmi: Fix opening of char device + - hwmon: (coretemp) Fix potentially truncated sysfs attribute name + - drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs + - drm/rockchip: vop: Fix call to crtc reset helper + - drm/radeon: possible buffer overflow + - drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe() + - arm64: dts: qcom: sdm845-mtp: fix WiFi configuration + - ARM: dts: qcom: mdm9615: populate vsdcc fixed regulator + - soc: qcom: llcc cleanup to get rid of sdm845 specific driver file + - [Config] remove CONFIG_QCOM_SDM845_LLCC + - soc: qcom: Rename llcc-slice to llcc-qcom + - [Config] remove llcc-slice module + - soc: qcom: llcc: Handle a second device without data corruption + - firmware: ti_sci: Replace HTTP links with HTTPS ones + - firmware: ti_sci: Mark driver as non removable + - clk: scmi: Free scmi_clk allocated when the clocks with invalid info are + skipped + - hwrng: geode - fix accessing registers + - libnvdimm/of_pmem: Use devm_kstrdup instead of kstrdup and check its return + value + - sched/rt: Provide migrate_disable/enable() inlines + - nd_btt: Make BTT lanes preemptible + - crypto: caam/qi2 - fix Chacha20 + Poly1305 self test failure + - crypto: caam/jr - fix Chacha20 + Poly1305 self test failure + - HID: cp2112: Use irqchip template + - hid: cp2112: Fix duplicate workqueue initialization + - ARM: 9321/1: memset: cast the constant byte to unsigned char + - ext4: move 'ix' sanity check to corrent position + - scsi: ufs: core: Leave space for '\0' in utf8 desc string + - RDMA/hfi1: Workaround truncation compilation error + - sh: bios: Revive earlyprintk support + - ASoC: Intel: Skylake: Fix mem leak when parsing UUIDs fails + - ASoC: ams-delta.c: use component after check + - mfd: dln2: Fix double put in dln2_probe + - leds: pwm: simplify if condition + - leds: pwm: convert to atomic PWM API + - leds: pwm: Don't disable the PWM when the LED should be off + - ledtrig-cpu: Limit to 8 CPUs + - leds: trigger: ledtrig-cpu:: Fix 'output may be truncated' issue for 'cpu' + - tty: tty_jobctrl: fix pid memleak in disassociate_ctty() + - usb: dwc2: fix possible NULL pointer dereference caused by driver + concurrency + - dmaengine: ti: edma: handle irq_of_parse_and_map() errors + - misc: st_core: Do not call kfree_skb() under spin_lock_irqsave() + - tools: iio: privatize globals and functions in iio_generic_buffer.c file + - tools: iio: iio_generic_buffer: Fix some integer type and calculation + - tools: iio: iio_generic_buffer ensure alignment + - USB: usbip: fix stub_dev hub disconnect + - dmaengine: pxa_dma: Remove an erroneous BUG_ON() in pxad_free_desc() + - f2fs: fix to initialize map.m_pblk in f2fs_precache_extents() + - modpost: fix tee MODULE_DEVICE_TABLE built on big-endian host + - powerpc/xive: Fix endian conversion size + - powerpc/imc-pmu: Use the correct spinlock initializer. + - powerpc/pseries: fix potential memory leak in init_cpu_associativity() + - i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs + - rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits call + - pcmcia: cs: fix possible hung task and memory leak pccardd() + - pcmcia: ds: fix refcount leak in pcmcia_device_add() + - pcmcia: ds: fix possible name leak in error path in pcmcia_device_add() + - media: bttv: fix use after free error due to btv->timeout timer + - media: s3c-camif: Avoid inappropriate kfree() + - media: dvb-usb-v2: af9035: fix missing unlock + - regmap: prevent noinc writes from clobbering cache + - pwm: sti: Avoid conditional gotos + - pwm: sti: Reduce number of allocations and drop usage of chip_data + - pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume + - Input: synaptics-rmi4 - fix use after free in rmi_unregister_function() + - llc: verify mac len before reading mac header + - tipc: Change nla_policy for bearer-related names to NLA_NUL_STRING + - inet: shrink struct flowi_common + - dccp: Call security_inet_conn_request() after setting IPv4 addresses. + - dccp/tcp: Call security_inet_conn_request() after setting IPv6 addresses. + - Fix termination state for idr_for_each_entry_ul() + - net: stmmac: xgmac: Enable support for multiple Flexible PPS outputs + - net/smc: fix dangling sock under state SMC_APPFINCLOSEWAIT + - tg3: power down device only on SYSTEM_POWER_OFF + - r8169: respect userspace disabling IFF_MULTICAST + - netfilter: xt_recent: fix (increase) ipv6 literal buffer length + - netfilter: nft_redir: use `struct nf_nat_range2` throughout and deduplicate + eval call-backs + - netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses + - drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE + - spi: spi-zynq-qspi: add spi-mem to driver kconfig dependencies + - fbdev: imsttfb: Fix error path of imsttfb_probe() + - fbdev: imsttfb: fix a resource leak in probe + - fbdev: fsl-diu-fb: mark wr_reg_wa() static + - Revert "mmc: core: Capture correct oemid-bits for eMMC cards" + - btrfs: use u64 for buffer sizes in the tree search ioctls + - Linux 5.4.261 + * Focal update: v5.4.260 upstream stable release (LP: #2049024) + - mtd: rawnand: marvell: Ensure program page operations are successful + - selftests/ftrace: Add new test case which checks non unique symbol + - mcb: Return actual parsed size when reading chameleon table + - mcb-lpc: Reallocate memory region to avoid memory overlapping + - virtio_balloon: Fix endless deflation and inflation on arm64 + - virtio-mmio: fix memory leak of vm_dev + - r8169: fix the KCSAN reported data-race in rtl_tx while reading + TxDescArray[entry].opts1 + - r8169: fix the KCSAN reported data race in rtl_rx while reading desc->opts1 + - treewide: Spelling fix in comment + - igb: Fix potential memory leak in igb_add_ethtool_nfc_entry + - neighbour: fix various data-races + - igc: Fix ambiguity in the ethtool advertising + - net: ieee802154: adf7242: Fix some potential buffer overflow in + adf7242_stats_show() + - r8152: Increase USB control msg timeout to 5000ms as per spec + - r8152: Run the unload routine if we have errors during probe + - r8152: Cancel hw_phy_work if we have an error in probe + - tcp: fix wrong RTO timeout when received SACK reneging + - gtp: uapi: fix GTPA_MAX + - gtp: fix fragmentation needed check with gso + - iio: exynos-adc: request second interupt only when touchscreen mode is used + - i2c: muxes: i2c-mux-pinctrl: Use of_get_i2c_adapter_by_node() + - i2c: muxes: i2c-mux-gpmux: Use of_get_i2c_adapter_by_node() + - i2c: muxes: i2c-demux-pinctrl: Use of_get_i2c_adapter_by_node() + - i2c: stm32f7: Fix PEC handling in case of SMBUS transfers + - i2c: aspeed: Fix i2c bus hang in slave read + - nvmem: imx: correct nregs for i.MX6ULL + - nvmem: imx: correct nregs for i.MX6SLL + - nvmem: imx: correct nregs for i.MX6UL + - perf/core: Fix potential NULL deref + - clk: Sanitize possible_parent_show to Handle Return Value of + of_clk_get_parent_name + - i40e: Fix wrong check for I40E_TXR_FLAGS_WB_ON_ITR + - x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility + - drm/dp_mst: Fix NULL deref in get_mst_branch_device_by_guid_helper() + - arm64: fix a concurrency issue in emulation_proc_handler() + - smbdirect: missing rc checks while waiting for rdma events + - f2fs: fix to do sanity check on inode type during garbage collection + - nfsd: lock_rename() needs both directories to live on the same fs + - x86/mm: Simplify RESERVE_BRK() + - x86/mm: Fix RESERVE_BRK() for older binutils + - ext4: add two helper functions extent_logical_end() and pa_logical_end() + - ext4: avoid overlapping preallocations due to overflow + - ext4: fix BUG in ext4_mb_new_inode_pa() due to overflow + - driver: platform: Add helper for safer setting of driver_override + - rpmsg: Constify local variable in field store macro + - rpmsg: Fix kfree() of static memory on setting driver_override + - rpmsg: Fix calling device_lock() on non-initialized device + - rpmsg: glink: Release driver_override + - rpmsg: Fix possible refcount leak in rpmsg_register_device_override() + - x86: Fix .brk attribute in linker script + - Input: i8042 - add Fujitsu Lifebook E5411 to i8042 quirk table + - irqchip/stm32-exti: add missing DT IRQ flag translation + - dmaengine: ste_dma40: Fix PM disable depth imbalance in d40_probe + - Input: synaptics-rmi4 - handle reset delay when using SMBus trsnsport + - fbdev: atyfb: only use ioremap_uc() on i386 and ia64 + - spi: npcm-fiu: Fix UMA reads when dummy.nbytes == 0 + - netfilter: nfnetlink_log: silence bogus compiler warning + - ASoC: rt5650: fix the wrong result of key button + - fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit() + - scsi: mpt3sas: Fix in error path + - platform/x86: asus-wmi: Change ASUS_WMI_BRN_DOWN code from 0x20 to 0x2e + - platform/mellanox: mlxbf-tmfifo: Fix a warning message + - net: chelsio: cxgb4: add an error code check in t4_load_phy_fw + - ata: ahci: fix enum constants for gcc-13 + - remove the sx8 block driver + - [Config] remove CONFIG_BLK_DEV_SX8 + - Revert "ARM: dts: Move am33xx and am43xx mmc nodes to sdhci-omap driver" + - PCI: Prevent xHCI driver from claiming AMD VanGogh USB3 DRD device + - usb: storage: set 1.50 as the lower bcdDevice for older "Super Top" + compatibility + - tty: 8250: Remove UC-257 and UC-431 + - tty: 8250: Add support for additional Brainboxes UC cards + - tty: 8250: Add support for Brainboxes UP cards + - tty: 8250: Add support for Intashield IS-100 + - Linux 5.4.260 + * CVE-2023-51779 + - Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg + * CVE-2023-22995 + - usb: dwc3: dwc3-qcom: Add missing platform_device_put() in + dwc3_qcom_acpi_register_core + + -- Joseph Salisbury Thu, 15 Feb 2024 12:22:11 -0500 + +linux-oracle (5.4.0-1118.127) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1118.127 -proposed tracker (LP: #2052215) + + [ Ubuntu: 5.4.0-172.190 ] + + * focal/linux: 5.4.0-172.190 -proposed tracker (LP: #2052220) + * CVE-2023-51781 + - appletalk: Fix Use-After-Free in atalk_ioctl + * CVE-2023-6915 + - ida: Fix crash in ida_free when the bitmap is empty + * CVE-2024-0565 + - smb: client: fix OOB in receive_encrypted_standard() + * CVE-2024-0646 + - net: tls, update curr on splice as well + + -- Joseph Salisbury Thu, 08 Feb 2024 12:20:23 -0500 + +linux-oracle (5.4.0-1117.126) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1117.126 -proposed tracker (LP: #2048277) + + [ Ubuntu: 5.4.0-171.189 ] + + * focal/linux: 5.4.0-171.189 -proposed tracker (LP: #2048282) + * Packaging resync (LP: #1786013) + - [Packaging] remove helper scripts + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/2024.01.08) + * Page fault in RDMA ODP triggers BUG_ON during MMU notifier registration + (LP: #2046534) + - RDMA/odp: Ensure the mm is still alive before creating an implicit child + * Hotplugging SCSI disk in QEMU VM fails (LP: #2047382) + - Revert "PCI: acpiphp: Reassign resources on bridge if necessary" + * CVE-2023-6040 + - netfilter: nf_tables: Reject tables of unsupported family + * kernel_selftests failures on kernel-P10d-LPAR10.ppc64el.10 + (LP: #2032641) + - selftests: Skip TM tests on synthetic TM implementations + * [Debian] autoreconstruct - Do not generate chmod -x for deleted files + (LP: #2045562) + - [Debian] autoreconstruct - Do not generate chmod -x for deleted files + * CVE-2023-6931 + - perf/core: Add a new read format to get a number of lost samples + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + * CVE-2023-45863 + - kobject: Fix slab-out-of-bounds in fill_kobj_path() + * Focal update: v5.4.259 upstream stable release (LP: #2043724) + - RDMA/cxgb4: Check skb value for failure to allocate + - lib/test_meminit: fix off-by-one error in test_pages() + - pwm: hibvt: Explicitly set .polarity in .get_state() + - HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect + - quota: Fix slow quotaoff + - net: prevent address rewrite in kernel_bind() + - drm: etvnaviv: fix bad backport leading to warning + - drm/msm/dsi: skip the wait for video mode done if not applicable + - ravb: Fix up dma_free_coherent() call in ravb_remove() + - ieee802154: ca8210: Fix a potential UAF in ca8210_probe + - mlxsw: fix mlxsw_sp2_nve_vxlan_learning_set() return type + - xen-netback: use default TX queue size for vifs + - drm/vmwgfx: fix typo of sizeof argument + - ixgbe: fix crash with empty VF macvlan list + - net: nfc: fix races in nfc_llcp_sock_get() and nfc_llcp_sock_get_sn() + - nfc: nci: assert requested protocol is valid + - workqueue: Override implicit ordered attribute in + workqueue_apply_unbound_cpumask() + - dmaengine: stm32-mdma: abort resume if no ongoing transfer + - usb: xhci: xhci-ring: Use sysdev for mapping bounce buffer + - net: usb: dm9601: fix uninitialized variable use in dm9601_mdio_read + - usb: dwc3: Soft reset phy on probe for host + - usb: musb: Get the musb_qh poniter after musb_giveback + - usb: musb: Modify the "HWVers" register address + - iio: pressure: bmp280: Fix NULL pointer exception + - iio: pressure: dps310: Adjust Timeout Settings + - iio: pressure: ms5611: ms5611_prom_is_valid false negative bug + - mcb: remove is_added flag from mcb_device struct + - libceph: use kernel_connect() + - ceph: fix incorrect revoked caps assert in ceph_fill_file_size() + - Input: powermate - fix use-after-free in powermate_config_complete + - Input: psmouse - fix fast_reconnect function for PS/2 mode + - Input: xpad - add PXN V900 support + - cgroup: Remove duplicates in cgroup v1 tasks file + - pinctrl: avoid unsafe code pattern in find_pinctrl() + - usb: gadget: udc-xilinx: replace memcpy with memcpy_toio + - usb: gadget: ncm: Handle decoding of multiple NTB's in unwrap call + - x86/cpu: Fix AMD erratum #1485 on Zen4-based CPUs + - dmaengine: mediatek: Fix deadlock caused by synchronize_irq() + - powerpc/8xx: Fix pte_access_permitted() for PAGE_NONE + - powerpc/64e: Fix wrong test in __ptep_test_and_clear_young() + - ravb: Fix use-after-free issue in ravb_tx_timeout_work() + - Documentation: sysctl: align cells in second content column + - usb: hub: Guard against accesses to uninitialized BOS descriptors + - Bluetooth: hci_event: Ignore NULL link key + - Bluetooth: Reject connection with the device which has same BD_ADDR + - Bluetooth: Fix a refcnt underflow problem for hci_conn + - Bluetooth: vhci: Fix race when opening vhci device + - Bluetooth: hci_event: Fix coding style + - Bluetooth: avoid memcmp() out of bounds warning + - ice: fix over-shifted variable + - nfc: nci: fix possible NULL pointer dereference in send_acknowledge() + - regmap: fix NULL deref on lookup + - KVM: x86: Mask LVTPC when handling a PMI + - netfilter: nft_payload: fix wrong mac header matching + - qed: fix LL2 RX buffer allocation + - xfrm: fix a data-race in xfrm_gen_index() + - xfrm: interface: use DEV_STATS_INC() + - net: ipv4: fix return value check in esp_remove_trailer + - net: ipv6: fix return value check in esp_remove_trailer + - net: rfkill: gpio: prevent value glitch during probe + - tcp: fix excessive TLP and RACK timeouts from HZ rounding + - tcp: tsq: relax tcp_small_queue_check() when rtx queue contains a single skb + - tun: prevent negative ifindex + - ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr + - net: usb: smsc95xx: Fix an error code in smsc95xx_reset() + - i40e: prevent crash on probe if hw registers have invalid values + - net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve + - neighbor: tracing: Move pin6 inside CONFIG_IPV6=y section + - netfilter: nft_set_rbtree: .deactivate fails if element has expired + - net: pktgen: Fix interface flags printing + - resource: Add irqresource_disabled() + - ACPI: Drop acpi_dev_irqresource_disabled() + - ACPI: resource: Skip IRQ override on Asus Vivobook S5602ZA + - ACPI: resource: Add Asus ExpertBook B2502 to Asus quirks + - ACPI: resource: Skip IRQ override on Asus Expertbook B2402CBA + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1502CBA + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1402CBA + - ARM: dts: ti: omap: Fix noisy serial with overrun-throttle-ms for mapphone + - btrfs: return -EUCLEAN for delayed tree ref with a ref count not equals to 1 + - btrfs: initialize start_slot in btrfs_log_prealloc_extents + - i2c: mux: Avoid potential false error message in i2c_mux_add_adapter + - overlayfs: set ctime when setting mtime and atime + - gpio: timberdale: Fix potential deadlock on &tgpio->lock + - ata: libata-eh: Fix compilation warning in ata_eh_link_report() + - tracing: relax trace_event_eval_update() execution with cond_resched() + - HID: holtek: fix slab-out-of-bounds Write in holtek_kbd_input_event + - Bluetooth: Avoid redundant authentication + - Bluetooth: hci_core: Fix build warnings + - wifi: mac80211: allow transmitting EAPOL frames with tainted key + - wifi: cfg80211: avoid leaking stack data into trace + - regulator/core: Revert "fix kobject release warning and memory leak in + regulator_register()" + - sky2: Make sure there is at least one frag_addr available + - drm: panel-orientation-quirks: Add quirk for One Mix 2S + - btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c + - HID: multitouch: Add required quirk for Synaptics 0xcd7e device + - Bluetooth: hci_event: Fix using memcmp when comparing keys + - mtd: rawnand: qcom: Unmap the right resource upon probe failure + - mtd: spinand: micron: correct bitmask for ecc status + - mtd: physmap-core: Restore map_rom fallback + - mmc: core: sdio: hold retuning if sdio in 1-bit mode + - mmc: core: Capture correct oemid-bits for eMMC cards + - Revert "pinctrl: avoid unsafe code pattern in find_pinctrl()" + - ACPI: irq: Fix incorrect return value in acpi_register_gsi() + - USB: serial: option: add Telit LE910C4-WWX 0x1035 composition + - USB: serial: option: add entry for Sierra EM9191 with new firmware + - USB: serial: option: add Fibocom to DELL custom modem FM101R-GL + - s390/pci: fix iommu bitmap allocation + - gpio: vf610: set value before the direction to avoid a glitch + - ASoC: pxa: fix a memory leak in probe() + - phy: mapphone-mdm6600: Fix runtime disable on probe + - phy: mapphone-mdm6600: Fix runtime PM for remove + - phy: mapphone-mdm6600: Fix pinctrl_pm handling for sleep pins + - Bluetooth: hci_sock: fix slab oob read in create_monitor_event + - Bluetooth: hci_sock: Correctly bounds check and pad HCI_MON_NEW_INDEX name + - xfrm6: fix inet6_dev refcount underflow problem + - Linux 5.4.259 + * Focal update: v5.4.258 upstream stable release (LP: #2042107) + - NFS/pNFS: Report EINVAL errors from connect() to the server + - SUNRPC: Mark the cred for revalidation if the server rejects it + - tracing: Increase trace array ref count on enable and filter files + - ata: libahci: clear pending interrupt status + - ext4: remove the 'group' parameter of ext4_trim_extent + - ext4: add new helper interface ext4_try_to_trim_range() + - ext4: scope ret locally in ext4_try_to_trim_range() + - ext4: change s_last_trim_minblks type to unsigned long + - ext4: mark group as trimmed only if it was fully scanned + - ext4: replace the traditional ternary conditional operator with with + max()/min() + - ext4: move setting of trimmed bit into ext4_try_to_trim_range() + - ext4: do not let fstrim block system suspend + - ASoC: meson: spdifin: start hw on dai probe + - netfilter: nf_tables: disallow element removal on anonymous sets + - bpf: Avoid deadlock when using queue and stack maps from NMI + - selftests/tls: Add {} to avoid static checker warning + - selftests: tls: swap the TX and RX sockets in some tests + - ASoC: imx-audmix: Fix return error with devm_clk_get() + - i40e: Fix for persistent lldp support + - SAUCE: Revert "UBUNTU: SAUCE: i40e Fix GPF when deleting VMs" + - i40e: Remove scheduling while atomic possibility + - i40e: Fix warning message and call stack during rmmod i40e driver + - i40e: Fix VF VLAN offloading when port VLAN is configured + - powerpc/perf/hv-24x7: Update domain value check + - dccp: fix dccp_v4_err()/dccp_v6_err() again + - net: hns3: add 5ms delay before clear firmware reset irq source + - net: bridge: use DEV_STATS_INC() + - team: fix null-ptr-deref when team device type is changed + - net: rds: Fix possible NULL-pointer dereference + - gpio: tb10x: Fix an error handling path in tb10x_gpio_probe() + - i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() + - Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN + - scsi: qla2xxx: Fix update_fcport for current_topology + - scsi: qla2xxx: Fix deletion race condition + - drm/amd/display: Reinstate LFC optimization + - drm/amd/display: Fix LFC multiplier changing erratically + - drm/amd/display: prevent potential division by zero errors + - ata: libata: disallow dev-initiated LPM transitions to unsupported states + - MIPS: Alchemy: only build mmc support helpers if au1xmmc is enabled + - clk: tegra: fix error return case for recalc_rate + - ARM: dts: ti: omap: motorola-mapphone: Fix abe_clkctrl warning on boot + - bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up + - xtensa: add default definition for XCHAL_HAVE_DIV32 + - xtensa: iss/network: make functions static + - xtensa: boot: don't add include-dirs + - xtensa: boot/lib: fix function prototypes + - gpio: pmic-eic-sprd: Add can_sleep flag for PMIC EIC chip + - parisc: sba: Fix compile warning wrt list of SBA devices + - parisc: iosapic.c: Fix sparse warnings + - parisc: drivers: Fix sparse warning + - parisc: irq: Make irq_stack_union static to avoid sparse warning + - selftests/ftrace: Correctly enable event in instance-event.tc + - ring-buffer: Avoid softlockup in ring_buffer_resize() + - ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() + - spi: nxp-fspi: reset the FLSHxCR1 registers + - bpf: Clarify error expectations from bpf_clone_redirect + - powerpc/watchpoints: Annotate atomic context in more places + - ncsi: Propagate carrier gain/loss events to the NCSI controller + - fbdev/sh7760fb: Depend on FB=y + - nvme-pci: do not set the NUMA node of device if it has none + - watchdog: iTCO_wdt: No need to stop the timer in probe + - watchdog: iTCO_wdt: Set NO_REBOOT if the watchdog is not already running + - i40e: improve locking of mac_filter_hash + - i40e: always propagate error value in i40e_set_vsi_promisc() + - i40e: fix return of uninitialized aq_ret in i40e_set_vsi_promisc + - smack: Record transmuting in smk_transmuted + - smack: Retrieve transmuting information in smack_inode_getsecurity() + - Smack:- Use overlay inode label in smack_inode_copy_up() + - serial: 8250_port: Check IRQ data before use + - nilfs2: fix potential use after free in nilfs_gccache_submit_read_data() + - ALSA: hda: Disable power save for solving pop issue on Lenovo ThinkCentre + M70q + - ata: libata-scsi: ignore reserved bits for REPORT SUPPORTED OPERATION CODES + - i2c: i801: unregister tco_pdev in i801_probe() error path + - ring-buffer: Update "shortest_full" in polling + - btrfs: properly report 0 avail for very full file systems + - net: thunderbolt: Fix TCPv6 GSO checksum calculation + - ata: libata-core: Fix ata_port_request_pm() locking + - ata: libata-core: Fix port and device removal + - ata: libata-core: Do not register PM operations for SAS ports + - ata: libata-sata: increase PMP SRST timeout to 10s + - fs: binfmt_elf_efpic: fix personality for ELF-FDPIC + - rbd: move rbd_dev_refresh() definition + - rbd: decouple header read-in from updating rbd_dev->header + - rbd: decouple parent info read-in from updating rbd_dev + - rbd: take header_rwsem in rbd_dev_refresh() only when updating + - Revert "PCI: qcom: Disable write access to read only registers for IP + v2.3.3" + - scsi: zfcp: Fix a double put in zfcp_port_enqueue() + - qed/red_ll2: Fix undefined behavior bug in struct qed_ll2_info + - wifi: mwifiex: Fix tlv_buf_left calculation + - net: replace calls to sock->ops->connect() with kernel_connect() + - net: prevent rewrite of msg_name in sock_sendmsg() + - wifi: iwlwifi: dbg_ini: fix structure packing + - wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet + - drivers/net: process the result of hdlc_open() and add call of hdlc_close() + in uhdlc_close() + - wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling + - regmap: rbtree: Fix wrong register marked as in-cache when creating new node + - ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig + - scsi: target: core: Fix deadlock due to recursive locking + - NFS4: Trace state recovery operation + - NFS: Add a helper nfs_client_for_each_server() + - NFSv4: Fix a nfs4_state_manager() race + - modpost: add missing else to the "of" check + - net: fix possible store tearing in neigh_periodic_work() + - ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data() + - net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent + - net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg + - net: nfc: llcp: Add lock when modifying device list + - netfilter: handle the connecting collision properly in + nf_conntrack_proto_sctp + - net: stmmac: dwmac-stm32: fix resume on STM32 MCU + - tcp: fix quick-ack counting to count actual ACKs of new data + - tcp: fix delayed ACKs for MSS boundary condition + - sctp: update transport state when processing a dupcook packet + - sctp: update hb timer immediately after users change hb_interval + - cpupower: add Makefile dependencies for install targets + - RDMA/core: Require admin capabilities to set system parameters + - IB/mlx4: Fix the size of a buffer in add_port_entries() + - gpio: aspeed: fix the GPIO number passed to pinctrl_gpio_set_config() + - gpio: pxa: disable pinctrl calls for MMP_GPIO + - RDMA/cma: Fix truncation compilation warning in make_cma_ports + - RDMA/uverbs: Fix typo of sizeof argument + - RDMA/siw: Fix connection failure handling + - RDMA/mlx5: Fix NULL string error + - parisc: Restore __ldcw_align for PA-RISC 2.0 processors + - NFS: Fix a race in __nfs_list_for_each_server() + - ima: rework CONFIG_IMA dependency block + - [Config] Update IMA_BLACKLIST_KEYRING and IMA_LOAD_X509 + - xen/events: replace evtchn_rwlock with RCU + - Linux 5.4.258 + + -- Joseph Salisbury Tue, 16 Jan 2024 11:16:10 -0500 + +linux-oracle (5.4.0-1116.125) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1116.125 -proposed tracker (LP: #2048649) + + * Packaging resync (LP: #1786013) + - [Packaging] remove helper scripts + + [ Ubuntu: 5.4.0-170.188 ] + + * focal/linux: 5.4.0-170.188 -proposed tracker (LP: #2048654) + * CVE-2023-6040 + - netfilter: nf_tables: Reject tables of unsupported family + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + * CVE-2023-6931 + - perf/core: Add a new read format to get a number of lost samples + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + + -- Joseph Salisbury Thu, 11 Jan 2024 11:29:21 -0500 + +linux-oracle (5.4.0-1115.124) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1115.124 -proposed tracker (LP: #2044801) + + [ Ubuntu: 5.4.0-169.187 ] + + * focal/linux: 5.4.0-169.187 -proposed tracker (LP: #2044375) + * USB bus error after upgrading to proposed kernel on lunar, jammy and focal + (LP: #2043197) + - USB: core: Fix oversight in SuperSpeed initialization + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + - [Packaging] update annotations scripts + + -- Joseph Salisbury Mon, 27 Nov 2023 15:22:35 -0500 + +linux-oracle (5.4.0-1114.123) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1114.123 -proposed tracker (LP: #2041646) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + + [ Ubuntu: 5.4.0-168.186 ] + + * focal/linux: 5.4.0-168.186 -proposed tracker (LP: #2041652) + * Focal update: v5.4.257 upstream stable release (LP: #2040284) + - erofs: ensure that the post-EOF tails are all zeroed + - ARM: pxa: remove use of symbol_get() + - mmc: au1xmmc: force non-modular build and remove symbol_get usage + - net: enetc: use EXPORT_SYMBOL_GPL for enetc_phc_index + - rtc: ds1685: use EXPORT_SYMBOL_GPL for ds1685_rtc_poweroff + - modules: only allow symbol_get of EXPORT_SYMBOL_GPL modules + - USB: serial: option: add Quectel EM05G variant (0x030e) + - USB: serial: option: add FOXCONN T99W368/T99W373 product + - HID: wacom: remove the battery when the EKR is off + - staging: rtl8712: fix race condition + - Bluetooth: btsdio: fix use after free bug in btsdio_remove due to race + condition + - serial: sc16is7xx: fix bug when first setting GPIO direction + - firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe + - fsi: master-ast-cf: Add MODULE_FIRMWARE macro + - nilfs2: fix general protection fault in nilfs_lookup_dirty_data_buffers() + - nilfs2: fix WARNING in mark_buffer_dirty due to discarded buffer reuse + - pinctrl: amd: Don't show `Invalid config param` errors + - 9p: virtio: make sure 'offs' is initialized in zc_request + - ASoC: da7219: Flush pending AAD IRQ when suspending + - ASoC: da7219: Check for failure reading AAD IRQ events + - ethernet: atheros: fix return value check in atl1c_tso_csum() + - vxlan: generalize vxlan_parse_gpe_hdr and remove unused args + - m68k: Fix invalid .section syntax + - s390/dasd: use correct number of retries for ERP requests + - s390/dasd: fix hanging device after request requeue + - fs/nls: make load_nls() take a const parameter + - ASoc: codecs: ES8316: Fix DMIC config + - ASoC: atmel: Fix the 8K sample parameter in I2SC master + - platform/x86: intel: hid: Always call BTNL ACPI method + - platform/x86: huawei-wmi: Silence ambient light sensor + - security: keys: perform capable check only on privileged operations + - clk: fixed-mmio: make COMMON_CLK_FIXED_MMIO depend on HAS_IOMEM + - net: usb: qmi_wwan: add Quectel EM05GV2 + - idmaengine: make FSL_EDMA and INTEL_IDMA64 depends on HAS_IOMEM + - scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock + - netlabel: fix shift wrapping bug in netlbl_catmap_setlong() + - bnx2x: fix page fault following EEH recovery + - sctp: handle invalid error codes without calling BUG() + - cifs: add a warning when the in-flight count goes negative + - scsi: storvsc: Always set no_report_opcodes + - ALSA: seq: oss: Fix racy open/close of MIDI devices + - platform/mellanox: Fix mlxbf-tmfifo not handling all virtio CONSOLE + notifications + - powerpc/32s: Fix assembler warning about r0 + - udf: Check consistency of Space Bitmap Descriptor + - udf: Handle error when adding extent to a file + - Revert "net: macsec: preserve ingress frame ordering" + - reiserfs: Check the return value from __getblk() + - eventfd: Export eventfd_ctx_do_read() + - eventfd: prevent underflow for eventfd semaphores + - new helper: lookup_positive_unlocked() + - fs: Fix error checking for d_hash_and_lookup() + - tmpfs: verify {g,u}id mount options correctly + - OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() + - x86/asm: Make more symbols local + - x86/boot: Annotate local functions + - x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved + - perf/imx_ddr: don't enable counter0 if none of 4 counters are used + - cpufreq: powernow-k8: Use related_cpus instead of cpus in driver.exit() + - bpf: Clear the probe_addr for uprobe + - tcp: tcp_enter_quickack_mode() should be static + - regmap: rbtree: Use alloc_flags for memory allocations + - spi: tegra20-sflash: fix to check return value of platform_get_irq() in + tegra_sflash_probe() + - can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors also + in case of OOM + - wifi: mwifiex: Fix OOB and integer underflow when rx packets + - mwifiex: switch from 'pci_' to 'dma_' API + - wifi: mwifiex: fix error recovery in PCIE buffer descriptor management + - crypto: stm32 - Properly handle pm_runtime_get failing + - Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe() + - crypto: caam - fix unchecked return value error + - hwrng: iproc-rng200 - use semicolons rather than commas to separate + statements + - hwrng: iproc-rng200 - Implement suspend and resume calls + - lwt: Fix return values of BPF xmit ops + - lwt: Check LWTUNNEL_XMIT_CONTINUE strictly + - fs: ocfs2: namei: check return value of ocfs2_add_entry() + - wifi: mwifiex: fix memory leak in mwifiex_histogram_read() + - wifi: mwifiex: Fix missed return in oob checks failed path + - wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx + - wifi: ath9k: protect WMI command response buffer replacement with a lock + - wifi: mwifiex: avoid possible NULL skb pointer dereference + - wifi: ath9k: use IS_ERR() with debugfs_create_dir() + - net: arcnet: Do not call kfree_skb() under local_irq_disable() + - mlxsw: i2c: Fix chunk size setting in output mailbox buffer + - mlxsw: i2c: Limit single transaction buffer size + - netrom: Deny concurrent connect(). + - drm/bridge: tc358764: Fix debug print parameter order + - quota: avoid increasing DQST_LOOKUPS when iterating over dirty/inuse list + - quota: factor out dquot_write_dquot() + - quota: rename dquot_active() to inode_quota_active() + - quota: add new helper dquot_active() + - quota: fix dqput() to follow the guarantees dquot_srcu should provide + - drm/amdgpu: avoid integer overflow warning in amdgpu_device_resize_fb_bar() + - ARM: dts: BCM53573: Drop nonexistent "default-off" LED trigger + - ARM: dts: BCM53573: Add cells sizes to PCIe node + - ARM: dts: BCM53573: Use updated "spi-gpio" binding properties + - drm/etnaviv: fix dumping of active MMU context + - ARM: dts: s3c6410: move fixed clocks under root node in Mini6410 + - ARM: dts: s3c6410: align node SROM bus node name with dtschema in Mini6410 + - ARM: dts: s3c64xx: align pinctrl with dtschema + - ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses (split) + - ARM: dts: s5pv210: add RTC 32 KHz clock in SMDKV210 + - ARM: dts: s5pv210: use defines for IRQ flags in SMDKV210 + - ARM: dts: s5pv210: correct ethernet unit address in SMDKV210 + - ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210 + - ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split) + - drm: adv7511: Fix low refresh rate register for ADV7533/5 + - ARM: dts: BCM53573: Fix Ethernet info for Luxul devices + - arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC + - drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl' + - md/bitmap: don't set max_write_behind if there is no write mostly device + - md/md-bitmap: hold 'reconfig_mutex' in backlog_store() + - drm/tegra: Remove superfluous error messages around platform_get_irq() + - drm/tegra: dpaux: Fix incorrect return value of platform_get_irq + - of: unittest: fix null pointer dereferencing in + of_unittest_find_node_by_name() + - drm/armada: Fix off-by-one error in armada_overlay_get_property() + - drm/panel: simple: Add missing connector type and pixel format for AUO + T215HVN01 + - ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig + - [Config] Update annotations after CONFIG_IMA_TRUSTED_KEYRING removal + - drm/msm/mdp5: Don't leak some plane state + - smackfs: Prevent underflow in smk_set_cipso() + - audit: fix possible soft lockup in __audit_inode_child() + - drm/mediatek: Fix potential memory leak if vmap() fail + - of: unittest: Fix overlay type in apply/revert check + - ALSA: ac97: Fix possible error value of *rac97 + - ipmi:ssif: Add check for kstrdup + - ipmi:ssif: Fix a memory leak when scanning for an adapter + - drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init() + - clk: sunxi-ng: Modify mismatched function name + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - PCI: pciehp: Use RMW accessors for changing LNKCTL + - PCI/ASPM: Use RMW accessors for changing LNKCTL + - clk: imx: composite-8m: fix clock pauses when set_rate would be a no-op + - powerpc/fadump: reset dump area size if fadump memory reserve fails + - PCI: Add #defines for Enter Compliance, Transmit Margin + - drm/amdgpu: Correct Transmit Margin masks + - drm/amdgpu: Replace numbers with PCI_EXP_LNKCTL2 definitions + - drm/amdgpu: Prefer pcie_capability_read_word() + - drm/amdgpu: Use RMW accessors for changing LNKCTL + - drm/radeon: Correct Transmit Margin masks + - drm/radeon: Replace numbers with PCI_EXP_LNKCTL2 definitions + - drm/radeon: Prefer pcie_capability_read_word() + - drm/radeon: Use RMW accessors for changing LNKCTL + - wifi: ath10k: Use RMW accessors for changing LNKCTL + - nfs/blocklayout: Use the passed in gfp flags + - powerpc/iommu: Fix notifiers being shared by PCI and VIO buses + - jfs: validate max amount of blocks before allocation. + - fs: lockd: avoid possible wrong NULL parameter + - NFSD: da_addr_body field missing in some GETDEVICEINFO replies + - NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN + - media: v4l2-fwnode: fix v4l2_fwnode_parse_link handling + - media: v4l2-fwnode: simplify v4l2_fwnode_parse_link + - media: v4l2-core: Fix a potential resource leak in v4l2_fwnode_parse_link() + - drivers: usb: smsusb: fix error handling code in smsusb_init_device + - media: dib7000p: Fix potential division by zero + - media: dvb-usb: m920x: Fix a potential memory leak in m920x_i2c_xfer() + - media: cx24120: Add retval check for cx24120_message_send() + - media: mediatek: vcodec: Return NULL if no vdec_fb is found + - usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host() + - scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param() + - scsi: be2iscsi: Add length check when parsing nlattrs + - scsi: qla4xxx: Add length check when parsing nlattrs + - serial: sprd: getting port index via serial aliases only + - serial: sprd: remove redundant sprd_port cleanup + - serial: sprd: Assign sprd_port after initialized to avoid wrong access + - serial: sprd: Fix DMA buffer leak issue + - x86/APM: drop the duplicate APM_MINOR_DEV macro + - scsi: qedf: Do not touch __user pointer in + qedf_dbg_stop_io_on_error_cmd_read() directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read() + directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read() + directly + - coresight: tmc: Explicit type conversions to prevent integer overflow + - dma-buf/sync_file: Fix docs syntax + - driver core: test_async: fix an error code + - IB/uverbs: Fix an potential error pointer dereference + - iommu/vt-d: Fix to flush cache of PASID directory table + - media: go7007: Remove redundant if statement + - USB: gadget: f_mass_storage: Fix unused variable warning + - media: i2c: ov5640: Configure HVP lines in s_power callback + - media: ov5640: Enable MIPI interface in ov5640_set_power_mipi() + - media: i2c: ov2680: Set V4L2_CTRL_FLAG_MODIFY_LAYOUT on flips + - media: ov2680: Remove auto-gain and auto-exposure controls + - media: ov2680: Fix ov2680_bayer_order() + - media: ov2680: Fix vflip / hflip set functions + - media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors + - scsi: core: Use 32-bit hostnum in scsi_host_lookup() + - scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock + - serial: tegra: handle clk prepare error in tegra_uart_hw_init() + - amba: bus: fix refcount leak + - Revert "IB/isert: Fix incorrect release of isert connection" + - RDMA/siw: Balance the reference of cep->kref in the error path + - RDMA/siw: Correct wrong debug message + - HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode() + - HID: multitouch: Correct devm device reference for hidinput input_dev name + - x86/speculation: Mark all Skylake CPUs as vulnerable to GDS + - tracing: Fix race issue between cpu buffer write and swap + - phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 + - phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate + - phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write + - rpmsg: glink: Add check for kstrdup + - mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume() + - um: Fix hostaudio build errors + - dmaengine: ste_dma40: Add missing IRQ check in d40_probe + - cpufreq: Fix the race condition while updating the transition_task of policy + - virtio_ring: fix avail_wrap_counter in virtqueue_add_packed + - skbuff: skb_segment, Call zero copy functions before using skbuff frags + - PM / devfreq: Fix leak in devfreq_dev_release() + - ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl + - ipmi_si: fix a memleak in try_smi_init() + - ARM: OMAP2+: Fix -Warray-bounds warning in _pwrdm_state_switch() + - backlight/gpio_backlight: Compare against struct fb_info.device + - backlight/bd6107: Compare against struct fb_info.device + - backlight/lv5207lp: Compare against struct fb_info.device + - xtensa: PMU: fix base address for the newer hardware + - media: dvb: symbol fixup for dvb_attach() + - ntb: Drop packets when qp link is down + - ntb: Clean up tx tail index on link down + - ntb: Fix calculation ntb_transport_tx_free_entry() + - Revert "PCI: Mark NVIDIA T4 GPUs to avoid bus reset" + - procfs: block chmod on /proc/thread-self/comm + - parisc: Fix /proc/cpuinfo output for lscpu + - dlm: fix plock lookup when using multiple lockspaces + - dccp: Fix out of bounds access in DCCP error handler + - X.509: if signature is unsupported skip validation + - net: handle ARPHRD_PPP in dev_is_mac_header_xmit() + - fsverity: skip PKCS#7 parser when keyring is empty + - pstore/ram: Check start of empty przs during init + - s390/ipl: add missing secure/has_secure file to ipl type 'unknown' + - crypto: stm32 - fix loop iterating through scatterlist for DMA + - cpufreq: brcmstb-avs-cpufreq: Fix -Warray-bounds bug + - sc16is7xx: Set iobase to device index + - serial: sc16is7xx: fix broken port 0 uart init + - usb: typec: tcpci: clear the fault status bit + - udf: initialize newblock to 0 + - drm: fix double free for gbo in drm_gem_vram_init and drm_gem_vram_create + - net/ipv6: SKB symmetric hash should incorporate transport ports + - scsi: qla2xxx: fix inconsistent TMF timeout + - scsi: qla2xxx: Fix erroneous link up failure + - scsi: qla2xxx: Turn off noisy message log + - scsi: qla2xxx: Remove unsupported ql2xenabledif option + - fbdev/ep93xx-fb: Do not assign to struct fb_info.dev + - drm/ast: Fix DRAM init on AST2200 + - lib/test_meminit: allocate pages up to order MAX_ORDER + - parisc: led: Fix LAN receive and transmit LEDs + - parisc: led: Reduce CPU overhead for disk & lan LED computation + - clk: qcom: gcc-mdm9615: use proper parent for pll0_vote clock + - soc: qcom: qmi_encdec: Restrict string length in decode + - NFSv4/pnfs: minor fix for cleanup path in nfs4_get_device_info + - kconfig: fix possible buffer overflow + - perf annotate bpf: Don't enclose non-debug code with an assert() + - x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() + - perf top: Don't pass an ERR_PTR() directly to perf_session__delete() + - watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load + - pwm: lpc32xx: Remove handling of PWM channels + - sctp: annotate data-races around sk->sk_wmem_queued + - ipv4: annotate data-races around fi->fib_dead + - net: read sk->sk_family once in sk_mc_loop() + - igb: disable virtualization features on 82580 + - veth: Fixing transmit return status for dropped packets + - net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr + - af_unix: Fix data-races around user->unix_inflight. + - af_unix: Fix data-race around unix_tot_inflight. + - af_unix: Fix data-races around sk->sk_shutdown. + - af_unix: Fix data race around sk->sk_err. + - kcm: Destroy mutex in kcm_exit_net() + - igc: Change IGC_MIN to allow set rx/tx value between 64 and 80 + - igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80 + - igb: Change IGB_MIN to allow set rx/tx value between 64 and 80 + - s390/zcrypt: don't leak memory if dev_set_name() fails + - idr: fix param name in idr_alloc_cyclic() doc + - ip_tunnels: use DEV_STATS_INC() + - net: hns3: fix the port information display when sfp is absent + - sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory() + - ata: sata_gemini: Add missing MODULE_DESCRIPTION + - ata: pata_ftide010: Add missing MODULE_DESCRIPTION + - fuse: nlookup missing decrement in fuse_direntplus_link + - btrfs: don't start transaction when joining with TRANS_JOIN_NOSTART + - btrfs: use the correct superblock to compare fsid in btrfs_validate_super + - mtd: rawnand: brcmnand: Fix crash during the panic_write + - mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write + - mtd: rawnand: brcmnand: Fix potential false time out warning + - perf hists browser: Fix hierarchy mode header + - perf tools: Handle old data in PERF_RECORD_ATTR + - usb: typec: tcpm: Refactor tcpm_handle_vdm_request payload handling + - usb: typec: tcpm: Refactor tcpm_handle_vdm_request + - usb: typec: bus: verify partner exists in typec_altmode_attention + - ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2 + - clk: imx8mm: Move 1443X/1416X PLL clock structure to common place + - net: ipv4: fix one memleak in __inet_del_ifa() + - net: ethernet: mvpp2_main: fix possible OOB write in + mvpp2_ethtool_get_rxnfc() + - net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in + mtk_hwlro_get_fdir_all() + - r8152: check budget for r8152_poll() + - kcm: Fix memory leak in error path of kcm_sendmsg() + - platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors + - mlxbf-tmfifo: sparse tags for config access + - platform/mellanox: mlxbf-tmfifo: Drop jumbo frames + - net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() + - ixgbe: fix timestamp configuration code + - kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). + - drm/amd/display: Fix a bug when searching for insert_above_mpcc + - parisc: Drop loops_per_jiffy from per_cpu struct + - autofs: fix memory leak of waitqueues in autofs_catatonic_mode + - btrfs: output extra debug info if we failed to find an inline backref + - locks: fix KASAN: use-after-free in trace_event_raw_event_filelock_lock + - ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer + - kernel/fork: beware of __put_task_struct() calling context + - ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470 + - perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09 + - hw_breakpoint: fix single-stepping when using bpf_overflow_handler + - devlink: remove reload failed checks in params get/set callbacks + - wifi: ath9k: fix printk specifier + - wifi: mwifiex: fix fortify warning + - crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui() + - tpm_tis: Resend command to recover from data transfer errors + - mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450 + - alx: fix OOB-read compiler warning + - wifi: mac80211_hwsim: drop short frames + - drm/exynos: fix a possible null-pointer dereference due to data race in + exynos_drm_crtc_atomic_disable() + - bus: ti-sysc: Configure uart quirks for k3 SoC + - md: raid1: fix potential OOB in raid1_remove_disk() + - ext2: fix datatype of block number in ext2_xattr_set2() + - fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount() + - jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount + - powerpc/pseries: fix possible memory leak in ibmebus_bus_init() + - media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer + - media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer() + - media: af9005: Fix null-ptr-deref in af9005_i2c_xfer + - media: anysee: fix null-ptr-deref in anysee_master_xfer + - media: az6007: Fix null-ptr-deref in az6007_i2c_xfer() + - media: tuners: qt1010: replace BUG_ON with a regular error + - media: pci: cx23885: replace BUG with error return + - usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc + - scsi: target: iscsi: Fix buffer overflow in lio_target_nacl_info_show() + - serial: cpm_uart: Avoid suspicious locking + - media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler warning + - kobject: Add sanity check for kset->kobj.ktype in kset_register() + - tools features: Add feature test to check if libbfd has buildid support + - perf jevents: Make build dependency on test JSONs + - perf tools: Add an option to build without libbfd + - btrfs: move btrfs_pinned_by_swapfile prototype into volumes.h + - btrfs: add a helper to read the superblock metadata_uuid + - btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super + - selftests: tracing: Fix to unmount tracefs for recovering environment + - md/raid1: fix error: ISO C90 forbids mixed declarations + - attr: block mode changes of symlinks + - btrfs: fix lockdep splat and potential deadlock after failure running + delayed items + - tracing: Have current_trace inc the trace array ref count + - tracing: Have option files inc the trace array ref count + - nfsd: fix change_info in NFSv4 RENAME replies + - tracefs: Add missing lockdown check to tracefs_create_dir() + - i2c: aspeed: Reset the i2c controller when timeout occurs + - scsi: megaraid_sas: Fix deadlock on firmware crashdump + - ext4: fix rec_len verify error + - mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller + - drm/amdgpu: fix amdgpu_cs_p1_user_fence + - Linux 5.4.257 + * Focal update: v5.4.257 upstream stable release (LP: #2040284) // + CVE-2023-39189 + - netfilter: nfnetlink_osf: avoid OOB read + * CVE-2023-45871 + - igb: set max size RX buffer when store bad packet is enabled + * CVE-2023-39193 + - netfilter: xt_sctp: validate the flag_info count + * CVE-2023-39192 + - netfilter: xt_u32: validate user space input + * CVE-2023-31085 + - ubi: Refuse attaching if mtd's erasesize is 0 + * CVE-2023-5717 + - perf: Disallow mis-matched inherited group reads + * CVE-2023-5178 + - nvmet-tcp: move send/recv error handling in the send/recv methods instead of + call-sites + - nvmet-tcp: Fix a possible UAF in queue intialization setup + * CVE-2023-42754 + - ipv4: fix null-deref in ipv4_link_failure + * Focal update: v5.4.256 upstream stable release (LP: #2039446) + - powerpc/pmac/smp: Avoid unused-variable warnings + - powerpc/pmac/smp: Drop unnecessary volatile qualifier + - Revert "MIPS: Alchemy: fix dbdma2" + - Linux 5.4.256 + * Focal update: v5.4.255 upstream stable release (LP: #2039440) + - mmc: sdhci_f_sdh30: convert to devm_platform_ioremap_resource + - mmc: sdhci-f-sdh30: Replace with sdhci_pltfm + - selftests: forwarding: tc_flower: Relax success criterion + - macsec: Fix traffic counters/statistics + - macsec: use DEV_STATS_INC() + - drm/radeon: Fix integer overflow in radeon_cs_parser_init + - ALSA: emu10k1: roll up loops in DSP setup code for Audigy + - quota: Properly disable quotas when add_dquot_ref() fails + - quota: fix warning in dqgrab() + - HID: add quirk for 03f0:464a HP Elite Presenter Mouse + - ovl: check type and offset of struct vfsmount in ovl_entry + - udf: Fix uninitialized array access for some pathnames + - fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev + - MIPS: dec: prom: Address -Warray-bounds warning + - FS: JFS: Fix null-ptr-deref Read in txBegin + - FS: JFS: Check for read-only mounted filesystem in txBegin + - media: v4l2-mem2mem: add lock to protect parameter num_rdy + - media: platform: mediatek: vpu: fix NULL ptr dereference + - usb: chipidea: imx: don't request QoS for imx8ulp + - gfs2: Fix possible data races in gfs2_show_options() + - pcmcia: rsrc_nonstatic: Fix memory leak in nonstatic_release_resource_db() + - Bluetooth: L2CAP: Fix use-after-free + - drm/amdgpu: Fix potential fence use-after-free v2 + - ALSA: hda/realtek: Add quirks for Unis H3C Desktop B760 & Q760 + - ALSA: hda: fix a possible null-pointer dereference due to data race in + snd_hdac_regmap_sync() + - powerpc/kasan: Disable KCOV in KASAN code + - IMA: allow/fix UML builds + - iio: add addac subdirectory + - iio: adc: stx104: Utilize iomap interface + - iio: adc: stx104: Implement and utilize register structures + - iio: stx104: Move to addac subdirectory + - iio: addac: stx104: Fix race condition for stx104_write_raw() + - iio: addac: stx104: Fix race condition when converting analog-to-digital + - iommu/amd: Fix "Guest Virtual APIC Table Root Pointer" configuration in IRTE + - PM-runtime: add tracepoints for usage_count changes + - PM: runtime: Add pm_runtime_get_if_active() + - ALSA: hda: Fix unhandled register update during auto-suspend period + - irqchip/mips-gic: Get rid of the reliance on irq_cpu_online() + - irqchip/mips-gic: Use raw spinlock for gic_lock + - interconnect: Move internal structs into a separate file + - interconnect: Add helpers for enabling/disabling a path + - usb: dwc3: qcom: Add helper functions to enable,disable wake irqs + - USB: dwc3: qcom: fix NULL-deref on suspend + - mmc: bcm2835: fix deferred probing + - mmc: sunxi: fix deferred probing + - leds: trigger: netdev: Recheck NETDEV_LED_MODE_LINKUP on dev rename + - tracing/probes: Have process_fetch_insn() take a void * instead of pt_regs + - tracing/probes: Fix to update dynamic data counter if fetcharg uses it + - net/ncsi: Fix gma flag setting after response + - nfsd4: kill warnings on testing stateids with mismatched clientids + - nfsd: Remove incorrect check in nfsd4_validate_stateid + - virtio-mmio: convert to devm_platform_ioremap_resource + - virtio-mmio: Use to_virtio_mmio_device() to simply code + - virtio-mmio: don't break lifecycle of vm_dev + - i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue + - fbdev: mmp: fix value check in mmphw_probe() + - powerpc/rtas_flash: allow user copy to flash block cache objects + - tty: serial: fsl_lpuart: Clear the error flags by writing 1 for lpuart32 + platforms + - btrfs: fix BUG_ON condition in btrfs_cancel_balance + - net: xfrm: Fix xfrm_address_filter OOB read + - net: af_key: fix sadb_x_filter validation + - xfrm: interface: rename xfrm_interface.c to xfrm_interface_core.c + - xfrm: fix slab-use-after-free in decode_session6 + - ip6_vti: fix slab-use-after-free in decode_session6 + - ip_vti: fix potential slab-use-after-free in decode_session6 + - selftests: mirror_gre_changes: Tighten up the TTL test match + - ipvs: fix racy memcpy in proc_do_sync_threshold + - netfilter: nft_dynset: disallow object maps + - team: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves + - i40e: fix misleading debug logs + - net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset + - sock: Fix misuse of sk_under_memory_pressure() + - net: do not allow gso_size to be set to GSO_BY_FRAGS + - bus: ti-sysc: Improve reset to work with modules with no sysconfig + - bus: ti-sysc: Flush posted write on enable before reset + - ARM: dts: imx7s: Drop dma-apb interrupt-names + - ARM: dts: imx: Adjust dma-apbh node name + - ARM: dts: imx: Set default tuning step for imx7d usdhc + - ARM: dts: imx: Set default tuning step for imx6sx usdhc + - ASoC: rt5665: add missed regulator_bulk_disable + - ASoC: meson: axg-tdm-formatter: fix channel slot allocation + - serial: 8250: Fix oops for port->pm on uart_change_pm() + - ALSA: usb-audio: Add support for Mythware XA001AU capture and playback + interfaces. + - cifs: Release folio lock on fscache read hit. + - mmc: wbsd: fix double mmc_free_host() in wbsd_init() + - mmc: block: Fix in_flight[issue_type] value error + - netfilter: set default timeout to 3 secs for sctp shutdown send and recv + state + - virtio-net: set queues after driver_ok + - net: fix the RTO timer retransmitting skb every 1ms if linear option is + enabled + - net: xfrm: Amend XFRMA_SEC_CTX nla_policy structure + - mmc: f-sdh30: fix order of function calls in sdhci_f_sdh30_remove + - net: phy: broadcom: stub c45 read/write for 54810 + - PCI: acpiphp: Reassign resources on bridge if necessary + - dlm: improve plock logging if interrupted + - dlm: replace usage of found with dedicated list iterator variable + - fs: dlm: add pid to debug log + - fs: dlm: change plock interrupted message to debug again + - fs: dlm: use dlm_plock_info for do_unlock_close + - fs: dlm: fix mismatch of plock results from userspace + - MIPS: cpu-features: Enable octeon_cache by cpu_type + - MIPS: cpu-features: Use boot_cpu_type for CPU type based features + - fbdev: Improve performance of sys_imageblit() + - fbdev: Fix sys_imageblit() for arbitrary image widths + - fbdev: fix potential OOB read in fast_imageblit() + - dm integrity: increase RECALC_SECTORS to improve recalculate speed + - dm integrity: reduce vmalloc space footprint on 32-bit architectures + - ALSA: pcm: Set per-card upper limit of PCM buffer allocations + - ALSA: pcm: Use SG-buffer only when direct DMA is available + - ALSA: pcm: Fix potential data race at PCM memory allocation helpers + - regmap: Account for register length in SMBus I/O limits + - ASoC: fsl_sai: Refine enable/disable TE/RE sequence in trigger() + - ASoC: fsl_sai: Add new added registers and new bit definition + - ASoC: fsl_sai: Disable bit clock with transmitter + - drm/amd/display: do not wait for mpc idle if tg is disabled + - drm/amd/display: check TG is non-null before checking if enabled + - tracing: Fix memleak due to race between current_tracer and trace + - octeontx2-af: SDP: fix receive link config + - sock: annotate data-races around prot->memory_pressure + - dccp: annotate data-races in dccp_poll() + - ipvlan: Fix a reference count leak warning in ipvlan_ns_exit() + - net: bgmac: Fix return value check for fixed_phy_register() + - net: bcmgenet: Fix return value check for fixed_phy_register() + - net: validate veth and vxcan peer ifindexes + - igb: Avoid starting unnecessary workqueues + - net/sched: fix a qdisc modification with ambiguous command request + - net: remove bond_slave_has_mac_rcu() + - bonding: fix macvlan over alb bond support + - ibmveth: Use dcbf rather than dcbfl + - NFSv4: Fix dropped lock for racing OPEN and delegation return + - clk: Fix slab-out-of-bounds error in devm_clk_release() + - nfsd: Fix race to FREE_STATEID and cl_revoked + - batman-adv: Trigger events for auto adjusted MTU + - batman-adv: Don't increase MTU when set by user + - batman-adv: Do not get eth header before batadv_check_management_packet + - batman-adv: Fix TT global entry leak when client roamed back + - batman-adv: Fix batadv_v_ogm_aggr_send memory leak + - batman-adv: Hold rtnl lock during MTU update via netlink + - lib/clz_ctz.c: Fix __clzdi2() and __ctzdi2() for 32-bit kernels + - radix tree: remove unused variable + - media: vcodec: Fix potential array out-of-bounds in encoder queue_setup + - PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root + bus + - drm/display/dp: Fix the DP DSC Receiver cap size + - mm: allow a controlled amount of unfairness in the page lock + - rtnetlink: Reject negative ifindexes in RTM_NEWLINK + - ALSA: pcm: Fix build error on m68k and others + - Revert "ALSA: pcm: Use SG-buffer only when direct DMA is available" + - interconnect: Do not skip aggregation for disabled paths + - ALSA: pcm: Check for null pointer of pointer substream before dereferencing + it + - Documentation/sysctl: document page_lock_unfairness + - irqchip/mips-gic: Don't touch vl_map if a local interrupt is not routable + - scsi: snic: Fix double free in snic_tgt_create() + - scsi: core: raid_class: Remove raid_component_add() + - clk: Fix undefined reference to `clk_rate_exclusive_{get,put}' + - pinctrl: renesas: rza2: Add lock around + pinctrl_generic{{add,remove}_group,{add,remove}_function} + - dma-buf/sw_sync: Avoid recursive lock during fence signal + - Linux 5.4.255 + * Focal update: v5.4.254 upstream stable release (LP: #2039291) + - mmc: moxart: read scr register without changing byte order + - ipv6: adjust ndisc_is_useropt() to also return true for PIO + - dmaengine: pl330: Return DMA_PAUSED when transaction is paused + - drm/nouveau/gr: enable memory loads on helper invocation on all channels + - radix tree test suite: fix incorrect allocation size for pthreads + - nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput + - iio: cros_ec: Fix the allocation size for cros_ec_command + - binder: fix memory leak in binder_init() + - usb-storage: alauda: Fix uninit-value in alauda_check_media() + - usb: dwc3: Properly handle processing of pending events + - usb: common: usb-conn-gpio: Prevent bailing out if initial role is none + - x86/cpu/amd: Enable Zenbleed fix for AMD Custom APU 0405 + - x86/mm: Fix VDSO and VVAR placement on 5-level paging machines + - x86: Move gds_ucode_mitigated() declaration to header + - drm/nouveau/disp: Revert a NULL check inside nouveau_connector_get_modes + - selftests/rseq: Fix build with undefined __weak + - mISDN: Update parameter type of dsp_cmx_send() + - net/packet: annotate data-races around tp->status + - bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves + - dccp: fix data-race around dp->dccps_mss_cache + - drivers: net: prevent tun_build_skb() to exceed the packet size limit + - IB/hfi1: Fix possible panic during hotplug remove + - wifi: cfg80211: fix sband iftype data lookup for AP_VLAN + - dmaengine: mcf-edma: Fix a potential un-allocated memory access + - net/mlx5: Allow 0 for total host VFs + - ibmvnic: Handle DMA unmapping of login buffs in release functions + - btrfs: don't stop integrity writeback too early + - btrfs: set cache_block_group_error if we find an error + - nvme-tcp: fix potential unbalanced freeze & unfreeze + - nvme-rdma: fix potential unbalanced freeze & unfreeze + - netfilter: nf_tables: report use refcount overflow + - scsi: core: Fix legacy /proc parsing buffer overflow + - scsi: storvsc: Fix handling of virtual Fibre Channel timeouts + - scsi: 53c700: Check that command slot is not NULL + - scsi: snic: Fix possible memory leak if device_add() fails + - scsi: core: Fix possible memory leak if device_add() fails + - alpha: remove __init annotation from exported page_is_ram() + - sch_netem: fix issues in netem_change() vs get_dist_table() + - Linux 5.4.254 + * Focal update: v5.4.253 upstream stable release (LP: #2038652) + - jbd2: fix incorrect code style + - jbd2: fix kernel-doc markups + - jbd2: remove redundant buffer io error checks + - jbd2: recheck chechpointing non-dirty buffer + - jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint + - gpio: tps68470: Make tps68470_gpio_output() always set the initial value + - bcache: remove 'int n' from parameter list of bch_bucket_alloc_set() + - bcache: Fix __bch_btree_node_alloc to make the failure behavior consistent + - btrfs: qgroup: catch reserved space leaks at unmount time + - btrfs: fix race between quota disable and relocation + - btrfs: fix extent buffer leak after tree mod log failure at split_node() + - ext4: rename journal_dev to s_journal_dev inside ext4_sb_info + - ext4: Fix reusing stale buffer heads from last failed mounting + - PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link() + - PCI/ASPM: Factor out pcie_wait_for_retrain() + - PCI/ASPM: Avoid link retraining race + - dlm: cleanup plock_op vs plock_xop + - dlm: rearrange async condition return + - fs: dlm: interrupt posix locks only when process is killed + - ftrace: Add information on number of page groups allocated + - ftrace: Check if pages were allocated before calling free_pages() + - ftrace: Store the order of pages allocated in ftrace_page + - ftrace: Fix possible warning on checking all pages used in + ftrace_process_locs() + - pwm: meson: Remove redundant assignment to variable fin_freq + - pwm: meson: Simplify duplicated per-channel tracking + - pwm: meson: fix handling of period/duty if greater than UINT_MAX + - scsi: qla2xxx: Fix inconsistent format argument type in qla_os.c + - scsi: qla2xxx: Array index may go out of bound + - uapi: General notification queue definitions + - keys: Fix linking a duplicate key to a keyring's assoc_array + - ext4: fix to check return value of freeze_bdev() in ext4_shutdown() + - i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir() + - vxlan: calculate correct header length for GPE + - phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe() + - ethernet: atheros: fix return value check in atl1e_tso_csum() + - ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new + temporary address + - bonding: reset bond's flags when down link is P2P device + - team: reset team's flags when down link is P2P device + - platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100 + - net/sched: mqprio: refactor nlattr parsing to a separate function + - net/sched: mqprio: add extack to mqprio_parse_nlattr() + - net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64 + - benet: fix return value check in be_lancer_xmit_workarounds() + - RDMA/mlx4: Make check for invalid flags stricter + - drm/msm/dpu: drop enum dpu_core_perf_data_bus_id + - drm/msm/adreno: Fix snapshot BINDLESS_DATA size + - drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb() + - ASoC: fsl_spdif: Silence output on stop + - block: Fix a source code comment in include/uapi/linux/blkzoned.h + - dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths + - ata: pata_ns87415: mark ns87560_tf_read static + - ring-buffer: Fix wrong stat of cpu_buffer->read + - tracing: Fix warning in trace_buffered_event_disable() + - serial: 8250_dw: Preserve original value of DLF register + - serial: sifive: Fix sifive_serial_console_setup() section + - USB: serial: option: support Quectel EM060K_128 + - USB: serial: option: add Quectel EC200A module support + - USB: serial: simple: add Kaufmann RKS+CAN VCP + - USB: serial: simple: sort driver entries + - can: gs_usb: gs_can_close(): add missing set of CAN state to + CAN_STATE_STOPPED + - Revert "usb: dwc3: core: Enable AutoRetry feature in the controller" + - usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy + - usb: dwc3: don't reset device side if dwc3 was configured as host-only + - usb: ohci-at91: Fix the unhandle interrupt when resume + - USB: quirks: add quirk for Focusrite Scarlett + - usb: xhci-mtk: set the dma max_seg_size + - Revert "usb: xhci: tegra: Fix error check" + - Documentation: security-bugs.rst: update preferences when dealing with the + linux-distros group + - Documentation: security-bugs.rst: clarify CVE handling + - staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext() + - hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled + - btrfs: check for commit error at btrfs_attach_transaction_barrier() + - tpm_tis: Explicitly check for error code + - irq-bcm6345-l1: Do not assume a fixed block to cpu mapping + - btrfs: check if the transaction was aborted at btrfs_wait_for_commit() + - virtio-net: fix race between set queues and probe + - s390/dasd: fix hanging device after quiesce/resume + - ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register + - dm cache policy smq: ensure IO doesn't prevent cleaner policy progress + - ACPI: processor: perflib: Use the "no limit" frequency QoS + - ACPI: processor: perflib: Avoid updating frequency QoS unnecessarily + - cpufreq: intel_pstate: Drop ACPI _PSS states table patching + - btrfs: qgroup: remove one-time use variables for quota_root checks + - btrfs: qgroup: return ENOTCONN instead of EINVAL when quotas are not enabled + - ASoC: cs42l51: fix driver to properly autoload with automatic module loading + - arm64: Add AMPERE1 to the Spectre-BHB affected list + - arm64: Fix bit-shifting UB in the MIDR_CPU_MODEL() macro + - perf: Fix function pointer case + - loop: Select I/O scheduler 'none' from inside add_disk() + - word-at-a-time: use the same return type for has_zero regardless of + endianness + - KVM: s390: fix sthyi error handling + - net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx + - net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer() + - rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length + - perf test uprobe_from_different_cu: Skip if there is no gcc + - net: sched: cls_u32: Fix match key mis-addressing + - mISDN: hfcpci: Fix potential deadlock on &hc->lock + - net: annotate data-races around sk->sk_max_pacing_rate + - net: add missing READ_ONCE(sk->sk_rcvlowat) annotation + - net: add missing READ_ONCE(sk->sk_sndbuf) annotation + - net: add missing READ_ONCE(sk->sk_rcvbuf) annotation + - net: add missing data-race annotations around sk->sk_peek_off + - net: add missing data-race annotation for sk_ll_usec + - bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire + - driver core: add device probe log helper + - net: ll_temac: Switch to use dev_err_probe() helper + - net: ll_temac: fix error checking of irq_of_parse_and_map() + - net: dcb: choose correct policy to parse DCB_ATTR_BCN + - ip6mr: Fix skb_under_panic in ip6mr_cache_report() + - tcp_metrics: fix addr_same() helper + - tcp_metrics: annotate data-races around tm->tcpm_stamp + - tcp_metrics: annotate data-races around tm->tcpm_lock + - tcp_metrics: annotate data-races around tm->tcpm_vals[] + - tcp_metrics: annotate data-races around tm->tcpm_net + - tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen + - scsi: zfcp: Defer fc_rport blocking until after ADISC response + - libceph: fix potential hang in ceph_osdc_notify() + - USB: zaurus: Add ID for A-300/B-500/C-700 + - mtd: spinand: toshiba: Fix ecc_get_status + - mtd: rawnand: meson: fix OOB available bytes for ECC + - fs/sysv: Null check to prevent null-ptr-deref bug + - net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb + - fs: Protect reconfiguration of sb read-write from racing writes + - ext2: Drop fragment support + - test_firmware: prevent race conditions by a correct implementation of + locking + - test_firmware: return ENOMEM instead of ENOSPC on failed memory allocation + - mtd: rawnand: omap_elm: Fix incorrect type in assignment + - powerpc/mm/altmap: Fix altmap boundary check + - selftests/rseq: check if libc rseq support is registered + - selftests/rseq: Play nice with binaries statically linked against glibc + 2.35+ + - PM / wakeirq: support enabling wake-up irq after runtime_suspend called + - PM: sleep: wakeirq: fix wake irq arming + - ceph: show tasks waiting on caps in debugfs caps file + - ceph: use kill_anon_super helper + - ceph: defer stopping mdsc delayed_work + - arm64: dts: stratix10: fix incorrect I2C property for SCL signal + - ARM: dts: imx6sll: Make ssi node name same as other platforms + - ARM: dts: imx: Align L2 cache-controller nodename with dtschema + - ARM: dts: imx: add usb alias + - ARM: dts: imx6sll: fixup of operating points + - ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node + - driver core: Annotate dev_err_probe() with __must_check + - driver code: print symbolic error code + - drivers: core: fix kernel-doc markup for dev_err_probe() + - Revert "driver core: Annotate dev_err_probe() with __must_check" + - Linux 5.4.253 + - Upstream stable to v5.4.253 + * CVE-2023-37453 + - USB: hub: Clean up use of port initialization schemes and retries + - USB: hub: Add Kconfig option to reduce number of port initialization retries + - USB: core: Unite old scheme and new scheme descriptor reads + - usb: hub: Check device descriptor before resusciation + - USB: core: Change usb_get_device_descriptor() API + - USB: core: Fix race by not overwriting udev->descriptor in hub_port_init() + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 16 Nov 2023 14:15:35 -0500 + +linux-oracle (5.4.0-1113.122) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1113.122 -proposed tracker (LP: #2041983) + + [ Ubuntu: 5.4.0-167.184 ] + + * focal/linux: 5.4.0-167.184 -proposed tracker (LP: #2041988) + * CVE-2023-45871 + - igb: set max size RX buffer when store bad packet is enabled + * CVE-2023-31085 + - ubi: Refuse attaching if mtd's erasesize is 0 + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 02 Nov 2023 12:01:25 -0400 + +linux-oracle (5.4.0-1112.121) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1112.121 -proposed tracker (LP: #2038002) + + * Use new annotations model (LP: #2019000) + - [Config] sanitize annotations + - [Config] migrate to the new annotations format + + [ Ubuntu: 5.4.0-166.183 ] + + * focal/linux: 5.4.0-166.183 -proposed tracker (LP: #2038010) + * Use new annotations model (LP: #2019000) + - [Packaging] new annotations model infrastructure + - [Packaging] config-check: Handle new annotations format 4 + - [Packaging] rules: Use old-kernelconfig for old configs + - [Config] sanitize annotations + - [Config] import generated configs into annotation file + - [Packaging] kernelconfig: add i386 as supported arch + - [Config] Remove all old configs files + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] update annotations scripts + * fix typo in config-checks invocation (LP: #2020413) + - [Packaging] fix typo when calling the old config-check + - [Packaging] fix typo in 4-checks.mk + * support python < 3.9 with annotations (LP: #2020531) + - [Packaging] kconfig/annotations.py: support older way of merging dicts + * CVE-2023-42756 + - netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP + * CVE-2023-4623 + - net/sched: sch_hfsc: Ensure inner classes have fsc curve + * Focal update: v5.4.252 upstream stable release (LP: #2036240) + - ia64/cpu: Switch to arch_cpu_finalize_init() + - m68k/cpu: Switch to arch_cpu_finalize_init() + - mips/cpu: Switch to arch_cpu_finalize_init() + - sh/cpu: Switch to arch_cpu_finalize_init() + - x86/cpufeatures: Add SEV-ES CPU feature + - x86/cpu: Add VM page flush MSR availablility as a CPUID feature + - x86/cpufeatures: Assign dedicated feature word for CPUID_0x8000001F[EAX] + - tools headers cpufeatures: Sync with the kernel sources + - x86/cpu, kvm: Add support for CPUID_80000021_EAX + - Linux 5.4.252 + - Upstream stable to v5.4.252 + * CVE-2023-42755 + - net/sched: Retire rsvp classifier + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + * CVE-2023-42753 + - netfilter: ipset: add the missing IP_SET_HASH_WITH_NET0 macro for + ip_set_hash_netportnet.c + * CVE-2023-34319 + - xen/netback: Fix buffer overrun triggered by unusual packet + * CVE-2023-4921 + - net: sched: sch_qfq: Fix UAF in qfq_dequeue() + * CVE-2023-42752 + - igmp: limit igmpv3_newpack() packet size to IP_MAX_MTU + * Avoid address overwrite in kernel_connect (LP: #2035163) + - net: Avoid address overwrite in kernel_connect + * [regression] Unable to initialize SGX enclaves with XFRM other than 3 + (LP: #2034745) + - x86/fpu: Set X86_FEATURE_OSXSAVE feature after enabling OSXSAVE in CR4 + * CVE-2023-4881 + - netfilter: nftables: exthdr: fix 4-byte stack OOB write + * CVE-2023-4622 + - af_unix: Fix null-ptr-deref in unix_stream_sendpage(). + * Focal update: v5.4.251 upstream stable release (LP: #2034918) + - x86/smp: Use dedicated cache-line for mwait_play_dead() + - video: imsttfb: check for ioremap() failures + - fbdev: imsttfb: Fix use after free bug in imsttfb_probe + - HID: wacom: Use ktime_t rather than int when dealing with timestamps + - drm/i915: Initialise outparam for error return from wait_for_register + - scripts/tags.sh: Resolve gtags empty index generation + - drm/amdgpu: Validate VM ioctl flags. + - bgmac: fix *initial* chip reset to support BCM5358 + - x86/resctrl: Use is_closid_match() in more places + - x86/resctrl: Only show tasks' pid in current pid namespace + - md/raid10: check slab-out-of-bounds in md_bitmap_get_counter + - md/raid10: fix overflow of md/safe_mode_delay + - md/raid10: fix wrong setting of max_corr_read_errors + - md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request + - md/raid10: fix io loss while replacement replace rdev + - irqchip/jcore-aic: Kill use of irq_create_strict_mappings() + - irqchip/jcore-aic: Fix missing allocation of IRQ descriptors + - tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode(). + - clocksource/drivers/cadence-ttc: Use ttc driver as platform driver + - clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe + - PM: domains: fix integer overflow issues in genpd_parse_state() + - powercap: RAPL: Fix CONFIG_IOSF_MBI dependency + - ARM: 9303/1: kprobes: avoid missing-declaration warnings + - evm: Complete description of evm_inode_setattr() + - pstore/ram: Add check for kstrdup + - ima: Fix build warnings + - wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation + - wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx + - samples/bpf: Fix buffer overflow in tcp_basertt + - spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG + - wifi: mwifiex: Fix the size of a memory allocation in + mwifiex_ret_802_11_scan() + - nfc: constify several pointers to u8, char and sk_buff + - nfc: llcp: fix possible use of uninitialized variable in + nfc_llcp_send_connect() + - regulator: core: Fix more error checking for debugfs_create_dir() + - regulator: core: Streamline debugfs operations + - wifi: orinoco: Fix an error handling path in spectrum_cs_probe() + - wifi: orinoco: Fix an error handling path in orinoco_cs_probe() + - wifi: atmel: Fix an error handling path in atmel_probe() + - wl3501_cs: Fix a bunch of formatting issues related to function docs + - wl3501_cs: Remove unnecessary NULL check + - wl3501_cs: Fix misspelling and provide missing documentation + - net: create netdev->dev_addr assignment helpers + - wl3501_cs: use eth_hw_addr_set() + - wifi: wl3501_cs: Fix an error handling path in wl3501_probe() + - wifi: ray_cs: Utilize strnlen() in parse_addr() + - wifi: ray_cs: Drop useless status variable in parse_addr() + - wifi: ray_cs: Fix an error handling path in ray_probe() + - wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes + - wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown + - watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct + config + - watchdog/perf: more properly prevent false positives with turbo modes + - kexec: fix a memory leak in crash_shrink_memory() + - memstick r592: make memstick_debug_get_tpc_name() static + - wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key() + - rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO + - wifi: iwlwifi: pull from TXQs with softirqs disabled + - wifi: cfg80211: rewrite merging of inherited elements + - wifi: ath9k: convert msecs to jiffies where needed + - netlink: fix potential deadlock in netlink_set_err() + - netlink: do not hard code device address lenth in fdb dumps + - selftests: rtnetlink: remove netdevsim device after ipsec offload test + - gtp: Fix use-after-free in __gtp_encap_destroy(). + - lib/ts_bm: reset initial match offset for every block of text + - netfilter: conntrack: dccp: copy entire header to stack buffer, not just + basic one + - netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return + value. + - ipvlan: Fix return value of ipvlan_queue_xmit() + - netlink: Add __sock_i_ino() for __netlink_diag_dump(). + - radeon: avoid double free in ci_dpm_init() + - Input: drv260x - sleep between polling GO bit + - ARM: dts: BCM5301X: Drop "clock-names" from the SPI node + - Input: adxl34x - do not hardcode interrupt trigger type + - drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks` + - RDMA/bnxt_re: Fix to remove an unnecessary log + - ARM: dts: gta04: Move model property out of pinctrl node + - arm64: dts: qcom: msm8916: correct camss unit address + - drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H + - ARM: ep93xx: fix missing-prototype warnings + - memory: brcmstb_dpfe: fix testing array offset after use + - ASoC: es8316: Increment max value for ALC Capture Target Volume control + - ASoC: es8316: Do not set rate constraints for unsupported MCLKs + - soc/fsl/qe: fix usb.c build errors + - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors + - arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1 + - fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe() + - drm/amdkfd: Fix potential deallocation of previously deallocated memory. + - drm/radeon: fix possible division-by-zero errors + - clk: tegra: tegra124-emc: Fix potential memory leak + - ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer + - clk: cdce925: check return value of kasprintf() + - clk: keystone: sci-clk: check return value of kasprintf() + - ASoC: imx-audmix: check return value of devm_kasprintf() + - scsi: qedf: Fix NULL dereference in error handling + - PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free + - scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe() + - PCI: pciehp: Cancel bringup sequence if card is not present + - PCI: ftpci100: Release the clock resources + - PCI: Add pci_clear_master() stub for non-CONFIG_PCI + - pinctrl: cherryview: Return correct value if pin in push-pull mode + - perf dwarf-aux: Fix off-by-one in die_get_varname() + - pinctrl: at91-pio4: check return value of devm_kasprintf() + - powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross- + boundary + - hwrng: virtio - add an internal buffer + - hwrng: virtio - don't wait on cleanup + - hwrng: virtio - don't waste entropy + - hwrng: virtio - always add a pending request + - hwrng: virtio - Fix race on data_avail and actual data + - crypto: nx - fix build warnings when DEBUG_FS is not enabled + - modpost: fix section mismatch message for R_ARM_ABS32 + - modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24} + - crypto: marvell/cesa - Fix type mismatch warning + - modpost: fix off by one in is_executable_section() + - ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard + - NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION + - hwrng: st - Fix W=1 unused variable warning + - hwrng: st - keep clock enabled while hwrng is registered + - USB: serial: option: add LARA-R6 01B PIDs + - usb: dwc3: gadget: Propagate core init errors to UDC during pullup + - block: fix signed int overflow in Amiga partition support + - block: change all __u32 annotations to __be32 in affs_hardblocks.h + - w1: fix loop in w1_fini() + - sh: j2: Use ioremap() to translate device tree address into kernel memory + - media: usb: Check az6007_read() return value + - media: videodev2.h: Fix struct v4l2_input tuner index comment + - usb: dwc3: qcom: Fix potential memory leak + - extcon: Fix kernel doc of property fields to avoid warnings + - extcon: Fix kernel doc of property capability fields to avoid warnings + - usb: phy: phy-tahvo: fix memory leak in tahvo_usb_probe() + - usb: hide unused usbfs_notify_suspend/resume functions + - mfd: rt5033: Drop rt5033-battery sub-device + - KVM: s390: fix KVM_S390_GET_CMMA_BITS for GFNs in memslot holes + - usb: dwc3: qcom: Release the correct resources in dwc3_qcom_remove() + - mfd: intel-lpss: Add missing check for platform_get_resource + - serial: 8250_omap: Use force_suspend and resume for system suspend + - mfd: stmfx: Fix error path in stmfx_chip_init + - KVM: s390: vsie: fix the length of APCB bitmap + - mfd: stmpe: Only disable the regulators if they are enabled + - pwm: imx-tpm: force 'real_period' to be zero in suspend + - pwm: sysfs: Do not apply state to already disabled PWMs + - rtc: st-lpc: Release some resources in st_rtc_probe() in case of error + - sctp: fix potential deadlock on &net->sctp.addr_wq_lock + - Add MODULE_FIRMWARE() for FIRMWARE_TG357766. + - spi: bcm-qspi: return error if neither hif_mspi nor mspi is available + - mailbox: ti-msgmgr: Fill non-message tx data fields with 0x0 + - f2fs: fix error path handling in truncate_dnode() + - powerpc: allow PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y + - net: bridge: keep ports without IFF_UNICAST_FLT in BR_PROMISC mode + - tcp: annotate data races in __tcp_oow_rate_limited() + - xsk: Improve documentation for AF_XDP + - xsk: Honor SO_BINDTODEVICE on bind + - net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX + - net: dsa: tag_sja1105: fix MAC DA patching from meta frames + - sh: dma: Fix DMA channel offset calculation + - i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process() + - i2c: xiic: Don't try to handle more interrupt events after error + - ALSA: jack: Fix mutex call in snd_jack_report() + - NFSD: add encoding of op_recall flag for write delegation + - mmc: core: disable TRIM on Kingston EMMC04G-M627 + - mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M + - mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is + used. + - bcache: Remove unnecessary NULL point check in node allocations + - integrity: Fix possible multiple allocation in integrity_inode_get() + - jffs2: reduce stack usage in jffs2_build_xattr_subsystem() + - fs: avoid empty option when generating legacy mount string + - ext4: Remove ext4 locking of moved directory + - Revert "f2fs: fix potential corruption when moving a directory" + - fs: Establish locking order for unrelated directories + - fs: Lock moved directories + - btrfs: fix race when deleting quota root from the dirty cow roots list + - ARM: orion5x: fix d2net gpio initialization + - fs: no need to check source + - fanotify: disallow mount/sb marks on kernel internal pseudo fs + - block: add overflow checks for Amiga partition support + - netfilter: nf_tables: fix nat hook table deletion + - netfilter: nftables: add helper function to set the base sequence number + - netfilter: add helper function to set up the nfnetlink header and use it + - netfilter: nf_tables: use net_generic infra for transaction data + - netfilter: nf_tables: add rescheduling points during loop detection walks + - netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound + set/chain + - netfilter: nf_tables: reject unbound anonymous set before commit phase + - netfilter: nf_tables: unbind non-anonymous set if rule construction fails + - netfilter: nf_tables: fix scheduling-while-atomic splat + - netfilter: conntrack: Avoid nf_ct_helper_hash uses after free + - tty: serial: fsl_lpuart: add earlycon for imx8ulp platform + - block/partition: fix signedness issue for Amiga partitions + - net: lan743x: Don't sleep in atomic context + - workqueue: clean up WORK_* constant types, clarify masking + - drm/panel: Initialise panel dev and funcs through drm_panel_init() + - drm/panel: Add and fill drm_panel type field + - drm/panel: simple: Add connector_type for innolux_at043tn24 + - igc: Remove delay during TX ring configuration + - igc: set TP bit in 'supported' and 'advertising' fields of + ethtool_link_ksettings + - scsi: qla2xxx: Fix error code in qla2x00_start_sp() + - net: mvneta: fix txq_map in case of txq_number==1 + - ionic: improve irq numa locality + - ionic: clean irq affinity on queue deinit + - ionic: move irq request to qcq alloc + - ionic: ionic_intr_free parameter change + - ionic: remove WARN_ON to prevent panic_on_warn + - icmp6: Fix null-ptr-deref of ip6_null_entry->rt6i_idev in icmp6_dev(). + - udp6: fix udp6_ehashfn() typo + - ntb: idt: Fix error handling in idt_pci_driver_init() + - NTB: amd: Fix error handling in amd_ntb_pci_driver_init() + - ntb: intel: Fix error handling in intel_ntb_pci_driver_init() + - NTB: ntb_transport: fix possible memory leak while device_register() fails + - NTB: ntb_tool: Add check for devm_kcalloc + - ipv6/addrconf: fix a potential refcount underflow for idev + - platform/x86: wmi: Replace UUID redefinitions by their originals + - platform/x86: wmi: Fix indentation in some cases + - platform/x86: wmi: remove unnecessary argument + - platform/x86: wmi: use guid_t and guid_equal() + - platform/x86: wmi: move variables + - platform/x86: wmi: Break possible infinite loop when parsing GUID + - erofs: avoid infinite loop in z_erofs_do_read_page() when reading beyond EOF + - wifi: airo: avoid uninitialized warning in airo_get_rate() + - cls_flower: Add extack support for src and dst port range options + - net/sched: flower: Ensure both minimum and maximum ports are specified + - net/sched: make psched_mtu() RTNL-less safe + - pinctrl: amd: Fix mistake in handling clearing pins at startup + - pinctrl: amd: Detect internal GPIO0 debounce handling + - pinctrl: amd: Only use special debounce behavior for GPIO 0 + - tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation + - mtd: rawnand: meson: fix unaligned DMA buffers handling + - net: bcmgenet: Ensure MDIO unregistration has clocks enabled + - powerpc: Fail build if using recordmcount with binutils v2.37 + - misc: fastrpc: Create fastrpc scalar with correct buffer count + - SUNRPC: Fix UAF in svc_tcp_listen_data_ready() + - erofs: fix compact 4B support for 16k block size + - ext4: fix wrong unit use in ext4_mb_clear_bb + - ext4: only update i_reserved_data_blocks on successful block allocation + - jfs: jfs_dmap: Validate db_l2nbperpage while mounting + - PCI/PM: Avoid putting EloPOS E2/S2/H2 PCIe Ports in D3cold + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9235 + - PCI: qcom: Disable write access to read only registers for IP v2.3.3 + - PCI: rockchip: Assert PCI Configuration Enable bit after probe + - PCI: rockchip: Write PCI Device ID to correct register + - PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked + - PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core + - PCI: rockchip: Use u32 variable to access 32-bit registers + - PCI: rockchip: Set address alignment for endpoint mode + - misc: pci_endpoint_test: Free IRQs before removing the device + - misc: pci_endpoint_test: Re-init completion for every test + - md/raid0: add discard support for the 'original' layout + - fs: dlm: return positive pid value for F_GETLK + - drm/atomic: Allow vblank-enabled + self-refresh "disable" + - drm/rockchip: vop: Leave vblank enabled in self-refresh + - serial: atmel: don't enable IRQs prematurely + - firmware: stratix10-svc: Fix a potential resource leak in + svc_create_memory_pool() + - hwrng: imx-rngc - fix the timeout for init and self check + - ceph: don't let check_caps skip sending responses for revoke msgs + - meson saradc: fix clock divider mask length + - Revert "8250: add support for ASIX devices with a FIFO bug" + - tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in + case of error + - tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when + iterating clk + - tracing/histograms: Add histograms to hist_vars if they have referenced + variables + - ring-buffer: Fix deadloop issue on reading trace_pipe + - xtensa: ISS: fix call to split_if_spec + - tracing: Fix null pointer dereference in tracing_err_log_open() + - tracing/probes: Fix not to count error code to total length + - scsi: qla2xxx: Wait for io return on terminate rport + - scsi: qla2xxx: Fix potential NULL pointer dereference + - scsi: qla2xxx: Check valid rport returned by fc_bsg_to_rport() + - scsi: qla2xxx: Correct the index of array + - scsi: qla2xxx: Pointer may be dereferenced + - scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue + - drm/atomic: Fix potential use-after-free in nonblocking commits + - perf probe: Add test for regression introduced by switch to + die_get_decl_file() + - btrfs: fix warning when putting transaction with qgroups enabled after abort + - fuse: revalidate: don't invalidate if interrupted + - selftests: tc: set timeout to 15 minutes + - can: bcm: Fix UAF in bcm_proc_show() + - drm/client: Fix memory leak in drm_client_target_cloned + - drm/client: Fix memory leak in drm_client_modeset_probe + - ext4: correct inline offset when handling xattrs in inode body + - debugobjects: Recheck debug_objects_enabled before reporting + - nbd: Add the maximum limit of allocated index in nbd_dev_add + - md: fix data corruption for raid456 when reshape restart while grow up + - md/raid10: prevent soft lockup while flush writes + - posix-timers: Ensure timer ID search-loop limit is valid + - arm64: mm: fix VA-range sanity check + - sched/fair: Don't balance task to its current running CPU + - bpf: Address KCSAN report on bpf_lru_list + - devlink: report devlink_port_type_warn source device + - wifi: wext-core: Fix -Wstringop-overflow warning in + ioctl_standard_iw_point() + - wifi: iwlwifi: mvm: avoid baid size integer overflow + - igb: Fix igb_down hung on surprise removal + - spi: bcm63xx: fix max prepend length + - fbdev: imxfb: warn about invalid left/right margin + - pinctrl: amd: Use amd_pinconf_set() for all config options + - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field() + - iavf: Fix use-after-free in free_netdev + - net:ipv6: check return value of pskb_trim() + - Revert "tcp: avoid the lookup process failing to get sk in ehash table" + - fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe + - llc: Don't drop packet from non-root netns. + - netfilter: nf_tables: fix spurious set element insertion failure + - netfilter: nf_tables: can't schedule in nft_chain_validate + - tcp: annotate data-races around tp->tcp_tx_delay + - net: Replace the limit of TCP_LINGER2 with TCP_FIN_TIMEOUT_MAX + - tcp: annotate data-races around tp->linger2 + - tcp: annotate data-races around rskq_defer_accept + - tcp: annotate data-races around tp->notsent_lowat + - tcp: annotate data-races around fastopenq.max_qlen + - tracing/histograms: Return an error if we fail to add histogram to hist_vars + list + - Linux 5.4.251 + * Focal update: v5.4.250 upstream stable release (LP: #2033297) + - x86/microcode/AMD: Load late on both threads too + - Linux 5.4.250 + * Focal update: v5.4.249 upstream stable release (LP: #2033278) + - nilfs2: reject devices with insufficient block count + - mm: rewrite wait_on_page_bit_common() logic + - list: add "list_del_init_careful()" to go with "list_empty_careful()" + - epoll: ep_autoremove_wake_function should use list_del_init_careful + - tracing: Add tracing_reset_all_online_cpus_unlocked() function + - x86/purgatory: remove PGO flags + - tick/common: Align tick period during sched_timer setup + - media: dvbdev: Fix memleak in dvb_register_device + - media: dvbdev: fix error logic at dvb_register_device() + - media: dvb-core: Fix use-after-free due to race at dvb_register_device() + - nilfs2: fix buffer corruption due to concurrent device reads + - Drivers: hv: vmbus: Fix vmbus_wait_for_unload() to scan present CPUs + - PCI: hv: Fix a race condition bug in hv_pci_query_relations() + - cgroup: Do not corrupt task iteration when rebinding subsystem + - mmc: meson-gx: remove redundant mmc_request_done() call from irq context + - ip_tunnels: allow VXLAN/GENEVE to inherit TOS/TTL from VLAN + - writeback: fix dereferencing NULL mapping->host on writeback_page_template + - nilfs2: prevent general protection fault in nilfs_clear_dirty_page() + - cifs: Clean up DFS referral cache + - cifs: Get rid of kstrdup_const()'d paths + - cifs: Introduce helpers for finding TCP connection + - cifs: Merge is_path_valid() into get_normalized_path() + - cifs: Fix potential deadlock when updating vol in cifs_reconnect() + - x86/mm: Avoid using set_pgd() outside of real PGD pages + - ieee802154: hwsim: Fix possible memory leaks + - xfrm: Linearize the skb after offloading if needed. + - net: qca_spi: Avoid high load if QCA7000 is not available + - mmc: mtk-sd: fix deferred probing + - mmc: mvsdio: convert to devm_platform_ioremap_resource + - mmc: mvsdio: fix deferred probing + - mmc: omap: fix deferred probing + - mmc: omap_hsmmc: fix deferred probing + - mmc: sdhci-acpi: fix deferred probing + - mmc: sh_mmcif: fix deferred probing + - mmc: usdhi60rol0: fix deferred probing + - ipvs: align inner_mac_header for encapsulation + - net: dsa: mt7530: fix trapping frames on non-MT7621 SoC MT7530 switch + - be2net: Extend xmit workaround to BE3 chip + - netfilter: nf_tables: disallow element updates of bound anonymous sets + - netfilter: nfnetlink_osf: fix module autoload + - Revert "net: phy: dp83867: perform soft reset and retain established link" + - sch_netem: acquire qdisc lock in netem_change() + - scsi: target: iscsi: Prevent login threads from racing between each other + - HID: wacom: Add error check to wacom_parse_and_register() + - arm64: Add missing Set/Way CMO encodings + - media: cec: core: don't set last_initiator if tx in progress + - nfcsim.c: Fix error checking for debugfs_create_dir + - usb: gadget: udc: fix NULL dereference in remove() + - s390/cio: unregister device when the only path is gone + - ASoC: nau8824: Add quirk to active-high jack-detect + - ARM: dts: Fix erroneous ADS touchscreen polarities + - drm/exynos: vidi: fix a wrong error return + - drm/exynos: fix race condition UAF in exynos_g2d_exec_ioctl + - drm/radeon: fix race condition UAF in radeon_gem_set_domain_ioctl + - x86/apic: Fix kernel panic when booting with intremap=off and x2apic_phys + - i2c: imx-lpi2c: fix type char overflow issue when calculating the clock + cycle + - mm: fix VM_BUG_ON(PageTail) and BUG_ON(PageWriteback) + - mm: make wait_on_page_writeback() wait for multiple pending writebacks + - Linux 5.4.249 + * allow io_uring to be disabled in runtime (LP: #2035116) + - io_uring: add a sysctl to disable io_uring system-wide + * CVE-2023-31083 + - Bluetooth: hci_ldisc: check HCI_UART_PROTO_READY flag in HCIUARTGETPROTO + * CVE-2023-4132 + - media: usb: siano: Fix warning due to null work_func_t function pointer + * CVE-2023-3772 + - xfrm: add NULL check in xfrm_update_ae_params + * CVE-2023-0597 + - random32: add noise from network and scheduling activity + - x86/kasan: Map shadow for percpu pages on demand + - x86/mm: Randomize per-cpu entry area + - x86/mm: Recompute physical address for every page of per-CPU CEA mapping + - x86/mm: Populate KASAN shadow for entire per-CPU range of CPU entry area + - x86/mm: Do not shuffle CPU entry areas without KASLR + + -- Joseph Salisbury Wed, 11 Oct 2023 15:19:36 -0400 + +linux-oracle (5.4.0-1111.120) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1111.120 -proposed tracker (LP: #2038155) + + * CVE-2023-42755 + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + + [ Ubuntu: 5.4.0-165.182 ] + + * focal/linux: 5.4.0-165.182 -proposed tracker (LP: #2038163) + * CVE-2023-42756 + - netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP + * CVE-2023-4623 + - net/sched: sch_hfsc: Ensure inner classes have fsc curve + * CVE-2023-42755 + - net/sched: Retire rsvp classifier + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + * CVE-2023-42753 + - netfilter: ipset: add the missing IP_SET_HASH_WITH_NET0 macro for + ip_set_hash_netportnet.c + * CVE-2023-34319 + - xen/netback: Fix buffer overrun triggered by unusual packet + * CVE-2023-4921 + - net: sched: sch_qfq: Fix UAF in qfq_dequeue() + * CVE-2023-42752 + - igmp: limit igmpv3_newpack() packet size to IP_MAX_MTU + * CVE-2023-4881 + - netfilter: nftables: exthdr: fix 4-byte stack OOB write + * CVE-2023-4622 + - af_unix: Fix null-ptr-deref in unix_stream_sendpage(). + + -- Joseph Salisbury Tue, 03 Oct 2023 11:14:36 -0400 + +linux-oracle (5.4.0-1110.119) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1110.119 -proposed tracker (LP: #2033859) + + * Focal update: v5.4.248 upstream stable release (LP: #2031121) + - [Config] updateconfigs for DECNET + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-164.181 ] + + * focal/linux: 5.4.0-164.181 -proposed tracker (LP: #2033867) + * Please enable Renesas RZ platform serial installer (LP: #2022361) + - [Config] enable hihope RZ/G2M serial console + * Azure: hv_netvsc: add support for vlans in AF_PACKET mode (LP: #2030872) + - hv_netvsc: add support for vlans in AF_PACKET mode + * systemd mount units fail during boot, while file system is correctly mounted + (LP: #1837227) + - list: introduce list_for_each_continue() + - proc/mounts: add cursor + * CVE-2023-40283 + - Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb + * CVE-2023-20588 + - x86/bugs: Increase the x86 bugs vector size to two u32s + - x86/CPU/AMD: Do not leak quotient data after a division by 0 + - x86/CPU/AMD: Fix the DIV(0) initial fix attempt + * CVE-2023-4194 + - net: tun_chr_open(): set sk_uid from current_fsuid() + - net: tap_open(): set sk_uid from current_fsuid() + * CVE-2023-1206 + - tcp: Reduce chance of collisions in inet6_hashfn(). + * CVE-2021-4001 + - bpf: Fix toctou on read-only map's constant scalar tracking + * Focal update: v5.4.248 upstream stable release (LP: #2031121) + - test_firmware: fix a memory leak with reqs buffer + - KEYS: asymmetric: Copy sig and digest in public_key_verify_signature() + - dasd: refactor dasd_ioctl_information + - s390/dasd: Use correct lock while counting channel queue length + - power: supply: ab8500: Fix external_power_changed race + - power: supply: sc27xx: Fix external_power_changed race + - power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + + schedule() + - ARM: dts: vexpress: add missing cache properties + - power: supply: Ratelimit no data debug output + - platform/x86: asus-wmi: Ignore WMI events with codes 0x7B, 0xC0 + - regulator: Fix error checking for debugfs_create_dir + - irqchip/meson-gpio: Mark OF related data as maybe unused + - power: supply: Fix logic checking if system is running from battery + - btrfs: handle memory allocation failure in btrfs_csum_one_bio + - parisc: Improve cache flushing for PCXL in arch_sync_dma_for_cpu() + - parisc: Flush gatt writes and adjust gatt mask in parisc_agp_mask_memory() + - MIPS: Alchemy: fix dbdma2 + - mips: Move initrd_start check after initrd address sanitisation. + - xen/blkfront: Only check REQ_FUA for writes + - drm:amd:amdgpu: Fix missing buffer object unlock in failure path + - ocfs2: fix use-after-free when unmounting read-only filesystem + - ocfs2: check new file size on fallocate call + - nios2: dts: Fix tse_mac "max-frame-size" property + - nilfs2: fix incomplete buffer cleanup in nilfs_btnode_abort_change_key() + - nilfs2: fix possible out-of-bounds segment allocation in resize ioctl + - kexec: support purgatories with .text.hot sections + - powerpc/purgatory: remove PGO flags + - nouveau: fix client work fence deletion race + - RDMA/uverbs: Restrict usage of privileged QKEYs + - net: usb: qmi_wwan: add support for Compal RXM-G1 + - ALSA: hda/realtek: Add a quirk for Compaq N14JP6 + - Remove DECnet support from kernel + - [Config] updateconfigs for DECNET + - USB: serial: option: add Quectel EM061KGL series + - serial: lantiq: add missing interrupt ack + - usb: dwc3: gadget: Reset num TRBs before giving back the request + - spi: spi-fsl-dspi: Remove unused chip->void_write_data + - spi: fsl-dspi: avoid SCK glitches with continuous transfers + - netfilter: nfnetlink: skip error delivery on batch in case of ENOMEM + - ping6: Fix send to link-local addresses with VRF. + - RDMA/rxe: Remove the unused variable obj + - RDMA/rxe: Removed unused name from rxe_task struct + - RDMA/rxe: Fix the use-before-initialization error of resp_pkts + - iavf: remove mask from iavf_irq_enable_queues() + - IB/uverbs: Fix to consider event queue closing also upon non-blocking mode + - IB/isert: Fix dead lock in ib_isert + - IB/isert: Fix possible list corruption in CMA handler + - IB/isert: Fix incorrect release of isert connection + - ipvlan: fix bound dev checking for IPv6 l3s mode + - sctp: fix an error code in sctp_sf_eat_auth() + - igb: fix nvm.ops.read() error handling + - drm/nouveau/dp: check for NULL nv_connector->native_mode + - drm/nouveau/kms: Don't change EDID when it hasn't actually changed + - drm/nouveau: add nv_encoder pointer check for NULL + - net/sched: cls_api: Fix lockup on flushing explicitly created chain + - net: lapbether: only support ethernet devices + - net: tipc: resize nlattr array to correct size + - selftests/ptp: Fix timestamp printf format for PTP_SYS_OFFSET + - afs: Fix vlserver probe RTT handling + - neighbour: Remove unused inline function neigh_key_eq16() + - net: Remove unused inline function dst_hold_and_use() + - neighbour: delete neigh_lookup_nodev as not used + - drm/nouveau/kms: Fix NULL pointer dereference in + nouveau_connector_detect_depth + - mmc: block: ensure error propagation for non-blk + - Linux 5.4.248 + * Focal update: v5.4.247 upstream stable release (LP: #2030818) + - blk-iocost: avoid 64-bit division in ioc_timer_fn + - block/blk-iocost (gcc13): keep large values in a new enum + - i40iw: fix build warning in i40iw_manage_apbvt() + - i40e: fix build warnings in i40e_alloc.h + - spi: qup: Request DMA before enabling clocks + - neighbour: Replace zero-length array with flexible-array member + - neighbour: fix unaligned access to pneigh_entry + - net: dsa: lan9303: allow vid != 0 in port_fdb_{add|del} methods + - Bluetooth: Fix l2cap_disconnect_req deadlock + - Bluetooth: L2CAP: Add missing checks for invalid DCID + - netfilter: conntrack: fix NULL pointer dereference in nf_confirm_cthelper + - netfilter: ipset: Add schedule point in call_ad(). + - rfs: annotate lockless accesses to sk->sk_rxhash + - rfs: annotate lockless accesses to RFS sock flow table + - net: sched: move rtm_tca_policy declaration to include file + - net: sched: fix possible refcount leak in tc_chain_tmplt_add() + - lib: cpu_rmap: Fix potential use-after-free in irq_cpu_rmap_release() + - bnxt_en: Query default VLAN before VNIC setup on a VF + - batman-adv: Broken sync while rescheduling delayed work + - Input: xpad - delete a Razer DeathAdder mouse VID/PID entry + - Input: psmouse - fix OOB access in Elantech protocol + - ALSA: hda/realtek: Add a quirk for HP Slim Desktop S01 + - ALSA: hda/realtek: Add Lenovo P3 Tower platform + - drm/amdgpu: fix xclk freq on CHIP_STONEY + - can: j1939: j1939_sk_send_loop_abort(): improved error queue handling in + J1939 Socket + - can: j1939: change j1939_netdev_lock type to mutex + - can: j1939: avoid possible use-after-free when j1939_can_rx_register fails + - ceph: fix use-after-free bug for inodes when flushing capsnaps + - Bluetooth: Fix use-after-free in hci_remove_ltk/hci_remove_irk + - rbd: move RBD_OBJ_FLAG_COPYUP_ENABLED flag setting + - pinctrl: meson-axg: add missing GPIOA_18 gpio group + - usb: usbfs: Enforce page requirements for mmap + - usb: usbfs: Use consistent mmap functions + - bonding (gcc13): synchronize bond_{a,t}lb_xmit() types + - i2c: sprd: Delete i2c adapter in .remove's error path + - eeprom: at24: also select REGMAP + - ext4: only check dquot_initialize_needed() when debugging + - drm/atomic: Don't pollute crtc_state->mode_blob with error pointers + - rbd: get snapshot context after exclusive lock is ensured to be held + - mtd: spinand: macronix: Add support for MX35LFxGE4AD + - Linux 5.4.247 + * CVE-2023-4128 + - net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_route: No longer copy tcf_result on update to avoid use- + after-free + * CVE-2023-3863 + - nfc: llcp: simplify llcp_sock_connect() error paths + - net: nfc: Fix use-after-free caused by nfc_llcp_find_local + * CVE-2023-3212 + - gfs2: Don't deref jdesc in evict + + -- Joseph Salisbury Mon, 11 Sep 2023 15:19:38 -0400 + +linux-oracle (5.4.0-1109.118) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1109.118 -proposed tracker (LP: #2034239) + + [ Ubuntu: 5.4.0-163.180 ] + + * focal/linux: 5.4.0-163.180 -proposed tracker (LP: #2034247) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * CVE-2023-40283 + - Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb + * CVE-2023-20588 + - x86/bugs: Increase the x86 bugs vector size to two u32s + - x86/CPU/AMD: Do not leak quotient data after a division by 0 + - x86/CPU/AMD: Fix the DIV(0) initial fix attempt + * CVE-2023-4128 + - net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_route: No longer copy tcf_result on update to avoid use- + after-free + + -- Joseph Salisbury Wed, 06 Sep 2023 13:35:09 -0400 + +linux-oracle (5.4.0-1108.117) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1108.117 -proposed tracker (LP: #2031009) + + [ Ubuntu: 5.4.0-162.179 ] + + * focal/linux: 5.4.0-162.179 -proposed tracker (LP: #2031128) + * libgnutls report "trap invalid opcode" when trying to install packages over + https (LP: #2031093) + - [Config]: disable CONFIG_GDS_FORCE_MITIGATION + + [ Ubuntu: 5.4.0-160.177 ] + + * focal/linux: 5.4.0-160.177 -proposed tracker (LP: #2031017) + * Fix boot test warning for log_check "CPU: 0 PID: 0 at + arch/x86/kernel/fpu/xstate.c:878 get_xsave_addr+0x98/0xb0" (LP: #2031022) + - x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") + + [ Ubuntu: 5.4.0-158.175 ] + + * focal/linux: 5.4.0-158.175 -proposed tracker (LP: #2030466) + * CVE-2022-40982 + - x86/mm: Initialize text poking earlier + - x86/mm: fix poking_init() for Xen PV guests + - x86/mm: Use mm_alloc() in poking_init() + - mm: Move mm_cachep initialization to mm_init() + - init: Provide arch_cpu_finalize_init() + - x86/cpu: Switch to arch_cpu_finalize_init() + - ARM: cpu: Switch to arch_cpu_finalize_init() + - sparc/cpu: Switch to arch_cpu_finalize_init() + - um/cpu: Switch to arch_cpu_finalize_init() + - init: Remove check_bugs() leftovers + - init: Invoke arch_cpu_finalize_init() earlier + - init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init() + - x86/fpu: Remove cpuinfo argument from init functions + - x86/fpu: Mark init functions __init + - x86/fpu: Move FPU initialization into arch_cpu_finalize_init() + - x86/xen: Fix secondary processors' FPU initialization + - x86/speculation: Add Gather Data Sampling mitigation + - x86/speculation: Add force option to GDS mitigation + - x86/speculation: Add Kconfig option for GDS + - KVM: Add GDS_NO support to KVM + - Documentation/x86: Fix backwards on/off logic about YMM support + - [Config]: Enable CONFIG_ARCH_HAS_CPU_FINALIZE_INIT and + CONFIG_GDS_FORCE_MITIGATION + * CVE-2023-3609 + - net/sched: cls_u32: Fix reference counter leak leading to overflow + * CVE-2023-20593 + - x86/cpu/amd: Move the errata checking functionality up + - x86/cpu/amd: Add a Zenbleed fix + * CVE-2023-3611 + - net/sched: sch_qfq: account for stab overhead in qfq_enqueue + * stacked overlay file system mounts that have chroot() called against them + appear to be getting locked (by the kernel most likely?) (LP: #2016398) + - SAUCE: overlayfs: fix reference count mismatch + * Focal update: v5.4.246 upstream stable release (LP: #2028981) + - RDMA/efa: Fix unsupported page sizes in device + - RDMA/bnxt_re: Enable SRIOV VF support on Broadcom's 57500 adapter series + - RDMA/bnxt_re: Refactor queue pair creation code + - RDMA/bnxt_re: Fix return value of bnxt_re_process_raw_qp_pkt_rx + - iommu/rockchip: Fix unwind goto issue + - iommu/amd: Don't block updates to GATag if guest mode is on + - dmaengine: pl330: rename _start to prevent build error + - net/mlx5: fw_tracer, Fix event handling + - netrom: fix info-leak in nr_write_internal() + - af_packet: Fix data-races of pkt_sk(sk)->num. + - amd-xgbe: fix the false linkup in xgbe_phy_status + - mtd: rawnand: ingenic: fix empty stub helper definitions + - af_packet: do not use READ_ONCE() in packet_bind() + - tcp: deny tcp_disconnect() when threads are waiting + - tcp: Return user_mss for TCP_MAXSEG in CLOSE/LISTEN state if user_mss set + - net/sched: sch_ingress: Only create under TC_H_INGRESS + - net/sched: sch_clsact: Only create under TC_H_CLSACT + - net/sched: Reserve TC_H_INGRESS (TC_H_CLSACT) for ingress (clsact) Qdiscs + - net/sched: Prohibit regrafting ingress or clsact Qdiscs + - net: sched: fix NULL pointer dereference in mq_attach + - ocfs2/dlm: move BITS_TO_BYTES() to bitops.h for wider use + - net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report + - udp6: Fix race condition in udp6_sendmsg & connect + - net: dsa: mv88e6xxx: Increase wait after reset deactivation + - mtd: rawnand: marvell: ensure timing values are written + - mtd: rawnand: marvell: don't set the NAND frequency select + - watchdog: menz069_wdt: fix watchdog initialisation + - mailbox: mailbox-test: Fix potential double-free in + mbox_test_message_write() + - ARM: 9295/1: unwind:fix unwind abort for uleb128 case + - media: rcar-vin: Select correct interrupt mode for V4L2_FIELD_ALTERNATE + - fbdev: modedb: Add 1920x1080 at 60 Hz video mode + - fbdev: stifb: Fix info entry in sti_struct on error path + - nbd: Fix debugfs_create_dir error checking + - ASoC: dwc: limit the number of overrun messages + - xfrm: Check if_id in inbound policy/secpath match + - ASoC: ssm2602: Add workaround for playback distortions + - media: dvb_demux: fix a bug for the continuity counter + - media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() + - media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() + - media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer() + - media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer + - media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() + - media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address + - media: netup_unidvb: fix irq init by register it at the end of probe + - media: dvb_ca_en50221: fix a size write bug + - media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() + - media: mn88443x: fix !CONFIG_OF error by drop of_match_ptr from ID table + - media: dvb-core: Fix use-after-free due on race condition at dvb_net + - media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 + - wifi: rtl8xxxu: fix authentication timeout due to incorrect RCR value + - ARM: dts: stm32: add pin map for CAN controller on stm32f7 + - arm64/mm: mark private VM_FAULT_X defines as vm_fault_t + - scsi: core: Decrease scsi_device's iorequest_cnt if dispatch failed + - wifi: b43: fix incorrect __packed annotation + - netfilter: conntrack: define variables exp_nat_nla_policy and any_addr with + CONFIG_NF_NAT + - ALSA: oss: avoid missing-prototype warnings + - atm: hide unused procfs functions + - mailbox: mailbox-test: fix a locking issue in mbox_test_message_write() + - iio: adc: mxs-lradc: fix the order of two cleanup operations + - HID: google: add jewel USB id + - HID: wacom: avoid integer overflow in wacom_intuos_inout() + - iio: light: vcnl4035: fixed chip ID check + - iio: dac: mcp4725: Fix i2c_master_send() return value handling + - iio: dac: build ad5758 driver when AD5758 is selected + - net: usb: qmi_wwan: Set DTR quirk for BroadMobi BM818 + - usb: gadget: f_fs: Add unbind event before functionfs_unbind + - misc: fastrpc: return -EPIPE to invocations on device removal + - misc: fastrpc: reject new invocations during device removal + - scsi: stex: Fix gcc 13 warnings + - ata: libata-scsi: Use correct device no in ata_find_dev() + - flow_dissector: work around stack frame size warning + - x86/boot: Wrap literal addresses in absolute_pointer() + - ACPI: thermal: drop an always true check + - gcc-12: disable '-Wdangling-pointer' warning for now + - eth: sun: cassini: remove dead code + - kernel/extable.c: use address-of operator on section symbols + - treewide: Remove uninitialized_var() usage + - lib/dynamic_debug.c: use address-of operator on section symbols + - wifi: rtlwifi: remove always-true condition pointed out by GCC 12 + - mmc: vub300: fix invalid response handling + - tty: serial: fsl_lpuart: use UARTCTRL_TXINV to send break instead of + UARTCTRL_SBK + - selinux: don't use make's grouped targets feature yet + - tracing/probe: trace_probe_primary_from_call(): checked list_first_entry + - ext4: add EA_INODE checking to ext4_iget() + - ext4: set lockdep subclass for the ea_inode in ext4_xattr_inode_cache_find() + - ext4: disallow ea_inodes with extended attributes + - ext4: add lockdep annotations for i_data_sem for ea_inode's + - fbcon: Fix null-ptr-deref in soft_cursor + - test_firmware: fix the memory leak of the allocated firmware buffer + - regmap: Account for register length when chunking + - scsi: dpt_i2o: Remove broken pass-through ioctl (I2OUSERCMD) + - scsi: dpt_i2o: Do not process completions with invalid addresses + - [Config] updateconfigs for SCSI_DPT_I2O + - RDMA/bnxt_re: Remove set but not used variable 'dev_attr' + - RDMA/bnxt_re: Remove the qp from list only if the qp destroy succeeds + - drm/edid: Fix uninitialized variable in drm_cvt_modes() + - wifi: rtlwifi: 8192de: correct checking of IQK reload + - drm/edid: fix objtool warning in drm_cvt_modes() + - Linux 5.4.246 + * Focal update: v5.4.245 upstream stable release (LP: #2028980) + - cdc_ncm: Implement the 32-bit version of NCM Transfer Block + - net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize + - power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to + stabilize + - power: supply: core: Refactor + power_supply_set_input_current_limit_from_supplier() + - power: supply: bq24190: Call power_supply_changed() after updating input + current + - fs: fix undefined behavior in bit shift for SB_NOUSER + - net/mlx5: devcom only supports 2 ports + - net/mlx5: Devcom, serialize devcom registration + - cdc_ncm: Fix the build warning + - io_uring: always grab lock in io_cancel_async_work() + - io_uring: don't drop completion lock before timer is fully initialized + - io_uring: have io_kill_timeout() honor the request references + - bluetooth: Add cmd validity checks at the start of hci_sock_ioctl() + - binder: fix UAF caused by faulty buffer cleanup + - ipv{4,6}/raw: fix output xfrm lookup wrt protocol + - netfilter: ctnetlink: Support offloaded conntrack entry deletion + - Linux 5.4.245 + * Focal update: v5.4.244 upstream stable release (LP: #2028697) + - driver core: add a helper to setup both the of_node and fwnode of a device + - drm/mipi-dsi: Set the fwnode for mipi_dsi_device + - ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings + - linux/dim: Do nothing if no time delta between samples + - net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs(). + - netfilter: conntrack: fix possible bug_on with enable_hooks=1 + - netlink: annotate accesses to nlk->cb_running + - net: annotate sk->sk_err write from do_recvmmsg() + - net: tap: check vlan with eth_type_vlan() method + - net: add vlan_get_protocol_and_depth() helper + - net: datagram: fix data-races in datagram_poll() + - af_unix: Fix a data race of sk->sk_receive_queue->qlen. + - af_unix: Fix data races around sk->sk_shutdown. + - fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode() + - drm/amd/display: Use DC_LOG_DC in the trasform pixel function + - regmap: cache: Return error in cache sync operations for REGCACHE_NONE + - firmware: arm_sdei: Fix sleep from invalid context BUG + - ACPI: EC: Fix oops when removing custom query handlers + - drm/tegra: Avoid potential 32-bit integer overflow + - ACPICA: Avoid undefined behavior: applying zero offset to null pointer + - ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in + acpi_db_display_objects + - wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex + - ext2: Check block size validity during mount + - scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow + - net: pasemi: Fix return type of pasemi_mac_start_tx() + - net: Catch invalid index in XPS mapping + - scsi: target: iscsit: Free cmds before session free + - lib: cpu_rmap: Avoid use after free on rmap->obj array entries + - scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race + condition + - gfs2: Fix inode height consistency check + - ext4: set goal start correctly in ext4_mb_normalize_request + - ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa() + - f2fs: fix to drop all dirty pages during umount() if cp_error is set + - samples/bpf: Fix fout leak in hbm's run_bpf_prog + - wifi: iwlwifi: pcie: fix possible NULL pointer dereference + - wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf + - wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace + - Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp + - HID: logitech-hidpp: Don't use the USB serial for USB devices + - HID: logitech-hidpp: Reconcile USB and Unifying serials + - spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3 + - HID: wacom: generic: Set battery quirk only when we see battery data + - usb: typec: tcpm: fix multiple times discover svids error + - serial: 8250: Reinit port->pm on port specific driver unbind + - mcb-pci: Reallocate memory region to avoid memory overlapping + - sched: Fix KCSAN noinstr violation + - recordmcount: Fix memory leaks in the uwrite function + - RDMA/core: Fix multiple -Warray-bounds warnings + - clk: tegra20: fix gcc-7 constant overflow warning + - iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any + - Input: xpad - add constants for GIP interface numbers + - phy: st: miphy28lp: use _poll_timeout functions for waits + - mfd: dln2: Fix memory leak in dln2_probe() + - btrfs: replace calls to btrfs_find_free_ino with btrfs_find_free_objectid + - btrfs: fix space cache inconsistency after error loading it from disk + - ASoC: fsl_micfil: register platform component before registering cpu dai + - cpupower: Make TSC read per CPU for Mperf monitor + - af_key: Reject optional tunnel/BEET mode templates in outbound policies + - net: fec: Better handle pm_runtime_get() failing in .remove() + - ALSA: firewire-digi00x: prevent potential use after free + - vsock: avoid to close connected socket after the timeout + - serial: arc_uart: fix of_iomap leak in `arc_serial_probe` + - ip6_gre: Fix skb_under_panic in __gre6_xmit() + - ip6_gre: Make o_seqno start from 0 in native mode + - ip_gre, ip6_gre: Fix race condition on o_seqno in collect_md mode + - erspan: get the proto with the md version for collect_md + - net: hns3: fix sending pfc frames after reset issue + - net: hns3: fix reset delay time to avoid configuration timeout + - media: netup_unidvb: fix use-after-free at del_timer() + - drm/exynos: fix g2d_open/close helper function definitions + - net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment() + - net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop() + - net: bcmgenet: Restore phy_stop() depending upon suspend/close + - wifi: iwlwifi: mvm: don't trust firmware n_channels + - cassini: Fix a memory leak in the error handling path of cas_init_one() + - igb: fix bit_shift to be in [1..8] range + - vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit() + - USB: usbtmc: Fix direction for 0-length ioctl control messages + - usb-storage: fix deadlock when a scsi command timeouts more than once + - USB: UHCI: adjust zhaoxin UHCI controllers OverCurrent bit value + - usb: dwc3: debugfs: Resume dwc3 before accessing registers + - usb: typec: altmodes/displayport: fix pin_assignment_show + - ALSA: hda: Fix Oops by 9.1 surround channel names + - ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table + - ALSA: hda/realtek: Add a quirk for HP EliteDesk 805 + - ALSA: hda/realtek: Add quirk for 2nd ASUS GU603 + - can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag + - can: kvaser_pciefd: Set CAN_STATE_STOPPED in kvaser_pciefd_stop() + - can: kvaser_pciefd: Call request_irq() before enabling interrupts + - can: kvaser_pciefd: Empty SRB buffer in probe + - can: kvaser_pciefd: Clear listen-only bit if not explicitly requested + - can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt + - can: kvaser_pciefd: Disable interrupts in probe error path + - KVM: x86: do not report a vCPU as preempted outside instruction boundaries + - statfs: enforce statfs[64] structure initialization + - serial: Add support for Advantech PCI-1611U card + - ceph: force updating the msg pointer in non-split case + - tpm/tpm_tis: Disable interrupts for more Lenovo devices + - powerpc/64s/radix: Fix soft dirty tracking + - nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode() + - netfilter: nftables: add nft_parse_register_load() and use it + - netfilter: nftables: add nft_parse_register_store() and use it + - netfilter: nftables: statify nft_parse_register() + - netfilter: nf_tables: validate registers coming from userspace. + - netfilter: nf_tables: add nft_setelem_parse_key() + - netfilter: nf_tables: allow up to 64 bytes in the set element data area + - netfilter: nf_tables: stricter validation of element data + - netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT + flag + - netfilter: nf_tables: hold mutex on netns pre_exit path + - HID: wacom: Force pen out of prox if no events have been received in a while + - HID: wacom: Add new Intuos Pro Small (PTH-460) device IDs + - HID: wacom: add three styli to wacom_intuos_get_tool_type + - lib/string_helpers: Introduce string_upper() and string_lower() helpers + - usb: gadget: u_ether: Convert prints to device prints + - usb: gadget: u_ether: Fix host MAC address case + - vc_screen: rewrite vcs_size to accept vc, not inode + - vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF + - s390/qdio: get rid of register asm + - s390/qdio: fix do_sqbs() inline assembly constraint + - watchdog: sp5100_tco: Immediately trigger upon starting. + - spi: fsl-spi: Re-organise transfer bits_per_word adaptation + - spi: fsl-cpm: Use 16 bit mode for large transfers with even size + - mt76: mt7615: Fix build with older compilers + - ALSA: hda/ca0132: add quirk for EVGA X299 DARK + - ALSA: hda/realtek: Enable headset onLenovo M70/M90 + - m68k: Move signal frame following exception on 68020/030 + - parisc: Handle kgdb breakpoints only in kernel context + - parisc: Allow to reboot machine after system halt + - gpio: mockup: Fix mode of debugfs files + - btrfs: use nofs when cleaning up aborted transactions + - selftests/memfd: Fix unknown type name build failure + - parisc: Fix flush_dcache_page() for usage from irq context + - x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms + - debugobjects: Don't wake up kswapd from fill_pool() + - fbdev: udlfb: Fix endpoint check + - net: fix stack overflow when LRO is disabled for virtual interfaces + - udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated(). + - USB: core: Add routines for endpoint checks in old drivers + - USB: sisusbvga: Add endpoint checks + - media: radio-shark: Add endpoint checks + - net: fix skb leak in __skb_tstamp_tx() + - selftests: fib_tests: mute cleanup error message + - bpf: Fix mask generation for 32-bit narrow loads of 64-bit fields + - ipv6: Fix out-of-bounds access in ipv6_find_tlv() + - power: supply: leds: Fix blink to LED on transition + - power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition + - power: supply: bq27xxx: Fix I2C IRQ race on remove + - power: supply: bq27xxx: Fix poll_interval handling and races on remove + - power: supply: sbs-charger: Fix INHIBITED bit for Status reg + - coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet() + - xen/pvcalls-back: fix double frees with pvcalls_new_active_socket() + - x86/show_trace_log_lvl: Ensure stack pointer is aligned, again + - ASoC: Intel: Skylake: Fix declaration of enum skl_ch_cfg + - forcedeth: Fix an error handling path in nv_probe() + - net/mlx5: Fix error message when failing to allocate device memory + - net/mlx5: Devcom, fix error flow in mlx5_devcom_register_device + - 3c589_cs: Fix an error handling path in tc589_probe() + - Linux 5.4.244 + * Focal update: v5.4.243 upstream stable release (LP: #2025387) + - counter: 104-quad-8: Fix race condition between FLAG and CNTR reads + - drm/fb-helper: set x/yres_virtual in drm_fb_helper_check_var + - bluetooth: Perform careful capability checks in hci_sock_ioctl() + - USB: serial: option: add UNISOC vendor and TOZED LT70C product + - iio: adc: palmas_gpadc: fix NULL dereference on rmmod + - ASoC: Intel: bytcr_rt5640: Add quirk for the Acer Iconia One 7 B1-750 + - asm-generic/io.h: suppress endianness warnings for readq() and writeq() + - USB: dwc3: fix runtime pm imbalance on probe errors + - USB: dwc3: fix runtime pm imbalance on unbind + - perf sched: Cast PTHREAD_STACK_MIN to int as it may turn into + sysconf(__SC_THREAD_STACK_MIN_VALUE) + - staging: iio: resolver: ads1210: fix config mode + - debugfs: regset32: Add Runtime PM support + - xhci: fix debugfs register accesses while suspended + - MIPS: fw: Allow firmware to pass a empty env + - ipmi:ssif: Add send_retries increment + - ipmi: fix SSIF not responding under certain cond. + - kheaders: Use array declaration instead of char + - pwm: meson: Fix axg ao mux parents + - pwm: meson: Fix g12a ao clk81 name + - ring-buffer: Sync IRQ works before buffer destruction + - reiserfs: Add security prefix to xattr name in reiserfs_security_write() + - KVM: nVMX: Emulate NOPs in L2, and PAUSE if it's not intercepted + - i2c: omap: Fix standard mode false ACK readings + - Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path" + - ubifs: Fix memleak when insert_old_idx() failed + - ubi: Fix return value overwrite issue in try_write_vid_and_data() + - ubifs: Free memory for tmpfile name + - selinux: fix Makefile dependencies of flask.h + - selinux: ensure av_permissions.h is built when needed + - tpm, tpm_tis: Do not skip reset of original interrupt vector + - erofs: stop parsing non-compact HEAD index if clusterofs is invalid + - erofs: fix potential overflow calculating xattr_isize + - drm/rockchip: Drop unbalanced obj unref + - drm/vgem: add missing mutex_destroy + - drm/probe-helper: Cancel previous job before starting new one + - arm64: dts: renesas: r8a77990: Remove bogus voltages from OPP table + - arm64: dts: renesas: r8a774c0: Remove bogus voltages from OPP table + - EDAC/skx: Fix overflows on the DRAM row address mapping arrays + - ARM: dts: qcom: ipq4019: Fix the PCI I/O port range + - ARM: dts: qcom: ipq8064: reduce pci IO size to 64K + - ARM: dts: qcom: ipq8064: Fix the PCI I/O port range + - media: bdisp: Add missing check for create_workqueue + - media: uapi: add MEDIA_BUS_FMT_METADATA_FIXED media bus format. + - media: av7110: prevent underflow in write_ts_to_decoder() + - firmware: qcom_scm: Clear download bit during reboot + - drm/msm: fix unbalanced pm_runtime_enable in adreno_gpu_{init, cleanup} + - drm/msm/adreno: Defer enabling runpm until hw_init() + - drm/msm/adreno: drop bogus pm_runtime_set_active() + - mmc: sdhci-of-esdhc: fix quirk to ignore command inhibit for data + - drm/lima/lima_drv: Add missing unwind goto in lima_pdev_probe() + - regulator: core: Consistently set mutex_owner when using + ww_mutex_lock_slow() + - regulator: core: Avoid lockdep reports when resolving supplies + - x86/apic: Fix atomic update of offset in reserve_eilvt_offset() + - media: dm1105: Fix use after free bug in dm1105_remove due to race condition + - media: saa7134: fix use after free bug in saa7134_finidev due to race + condition + - media: rcar_fdp1: simplify error check logic at fdp_open() + - media: rcar_fdp1: fix pm_runtime_get_sync() usage count + - media: rcar_fdp1: Make use of the helper function + devm_platform_ioremap_resource() + - media: rcar_fdp1: Fix the correct variable assignments + - media: rcar_fdp1: Fix refcount leak in probe and remove function + - media: rc: gpio-ir-recv: Fix support for wake-up + - regulator: stm32-pwr: fix of_iomap leak + - x86/ioapic: Don't return 0 from arch_dynirq_lower_bound() + - arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step + - debugobject: Prevent init race with static objects + - timekeeping: Split jiffies seqlock + - tick/sched: Use tick_next_period for lockless quick check + - tick/sched: Reduce seqcount held scope in tick_do_update_jiffies64() + - tick/sched: Optimize tick_do_update_jiffies64() further + - tick: Get rid of tick_period + - tick/common: Align tick period with the HZ tick. + - wifi: ath6kl: minor fix for allocation size + - wifi: ath9k: hif_usb: fix memory leak of remain_skbs + - wifi: ath5k: fix an off by one check in ath5k_eeprom_read_freq_list() + - wifi: ath6kl: reduce WARN to dev_dbg() in callback + - tools: bpftool: Remove invalid \' json escape + - wifi: rtw88: mac: Return the original error from rtw_pwr_seq_parser() + - wifi: rtw88: mac: Return the original error from rtw_mac_power_switch() + - scm: fix MSG_CTRUNC setting condition for SO_PASSSEC + - vlan: partially enable SIOCSHWTSTAMP in container + - net/packet: annotate accesses to po->xmit + - net/packet: convert po->origdev to an atomic flag + - net/packet: convert po->auxdata to an atomic flag + - scsi: target: iscsit: Fix TAS handling during conn cleanup + - scsi: megaraid: Fix mega_cmd_done() CMDID_INT_CMDS + - f2fs: handle dqget error in f2fs_transfer_project_quota() + - rtlwifi: Start changing RT_TRACE into rtl_dbg + - rtlwifi: Replace RT_TRACE with rtl_dbg + - wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg() + - wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_reg() + - bpftool: Fix bug for long instructions in program CFG dumps + - crypto: drbg - make drbg_prepare_hrng() handle jent instantiation errors + - crypto: drbg - Only fail when jent is unavailable in FIPS mode + - scsi: lpfc: Fix ioremap issues in lpfc_sli4_pci_mem_setup() + - bpf, sockmap: fix deadlocks in the sockhash and sockmap + - nvme: handle the persistent internal error AER + - nvme: fix async event trace event + - nvme-fcloop: fix "inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage" + - bpf, sockmap: Revert buggy deadlock fix in the sockhash and sockmap + - md/raid10: fix leak of 'r10bio->remaining' for recovery + - md/raid10: fix memleak for 'conf->bio_split' + - md: update the optimal I/O size on reshape + - md/raid10: fix memleak of md thread + - wifi: iwlwifi: make the loop for card preparation effective + - wifi: iwlwifi: mvm: check firmware response size + - ixgbe: Allow flow hash to be set via ethtool + - ixgbe: Enable setting RSS table to default values + - bpf: Don't EFAULT for getsockopt with optval=NULL + - netfilter: nf_tables: don't write table validation state without mutex + - ipv4: Fix potential uninit variable access bug in __ip_make_skb() + - netlink: Use copy_to_user() for optval in netlink_getsockopt(). + - net: amd: Fix link leak when verifying config failed + - tcp/udp: Fix memleaks of sk and zerocopy skbs with TX timestamp. + - pstore: Revert pmsg_lock back to a normal mutex + - usb: host: xhci-rcar: remove leftover quirk handling + - fpga: bridge: fix kernel-doc parameter description + - iio: light: max44009: add missing OF device matching + - usb: gadget: udc: renesas_usb3: Fix use after free bug in + renesas_usb3_remove due to race condition + - PCI: imx6: Install the fault handler only on compatible match + - genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() + - ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ + - ASoC: es8316: Handle optional IRQ assignment + - linux/vt_buffer.h: allow either builtin or modular for macros + - spi: qup: Don't skip cleanup in remove's error path + - spi: fsl-spi: Fix CPM/QE mode Litte Endian + - vmci_host: fix a race condition in vmci_host_poll() causing GPF + - of: Fix modalias string generation + - ia64: mm/contig: fix section mismatch warning/error + - ia64: salinfo: placate defined-but-not-used warning + - scripts/gdb: bail early if there are no clocks + - PM: domains: Fix up terminology with parent/child + - scripts/gdb: bail early if there are no generic PD + - mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry + - mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode + - mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure + - mtd: spi-nor: cadence-quadspi: Handle probe deferral while requesting DMA + channel + - spi: cadence-quadspi: fix suspend-resume implementations + - uapi/linux/const.h: prefer ISO-friendly __typeof__ + - sh: sq: Fix incorrect element size for allocating bitmap buffer + - usb: chipidea: fix missing goto in `ci_hdrc_probe` + - usb: mtu3: fix kernel panic at qmu transfer done irq handler + - firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe + - tty: serial: fsl_lpuart: adjust buffer length to the intended size + - serial: 8250: Add missing wakeup event reporting + - staging: rtl8192e: Fix W_DISABLE# does not work after stop/start + - spmi: Add a check for remove callback when removing a SPMI driver + - macintosh/windfarm_smu_sat: Add missing of_node_put() + - powerpc/mpc512x: fix resource printk format warning + - powerpc/wii: fix resource printk format warnings + - powerpc/sysdev/tsi108: fix resource printk format warnings + - macintosh: via-pmu-led: requires ATA to be set + - powerpc/rtas: use memmove for potentially overlapping buffer copy + - perf/core: Fix hardlockup failure caused by perf throttle + - RDMA/siw: Fix potential page_array out of range access + - RDMA/rdmavt: Delete unnecessary NULL check + - rtc: omap: include header for omap_rtc_power_off_program prototype + - RDMA/mlx4: Prevent shift wrapping in set_user_sq_size() + - rtc: meson-vrtc: Use ktime_get_real_ts64() to get the current time + - power: supply: generic-adc-battery: fix unit scaling + - clk: add missing of_node_put() in "assigned-clocks" property parsing + - RDMA/siw: Remove namespace check from siw_netdev_event() + - IB/hfi1: Fix SDMA mmu_rb_node not being evicted in LRU order + - NFSv4.1: Always send a RECLAIM_COMPLETE after establishing lease + - firmware: raspberrypi: Keep count of all consumers + - firmware: raspberrypi: Introduce devm_rpi_firmware_get() + - input: raspberrypi-ts: Release firmware handle when not needed + - Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe + - SUNRPC: remove the maximum number of retries in call_bind_status + - RDMA/mlx5: Use correct device num_ports when modify DC + - clocksource/drivers/davinci: Avoid trailing '\n' hidden in pr_fmt() + - clocksource: davinci: axe a pointless __GFP_NOFAIL + - clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when + init fails + - openrisc: Properly store r31 to pt_regs on unhandled exceptions + - ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline + - leds: TI_LMU_COMMON: select REGMAP instead of depending on it + - dmaengine: mv_xor_v2: Fix an error code. + - pwm: mtk-disp: Don't check the return code of pwmchip_remove() + - pwm: mtk-disp: Adjust the clocks to avoid them mismatch + - pwm: mtk-disp: Disable shadow registers before setting backlight values + - phy: tegra: xusb: Add missing tegra_xusb_port_unregister for usb2_port and + ulpi_port + - dmaengine: dw-edma: Fix to change for continuous transfer + - dmaengine: dw-edma: Fix to enable to issue dma request on DMA processing + - dmaengine: at_xdmac: do not enable all cyclic channels + - afs: Fix updating of i_size with dv jump from server + - parisc: Fix argument pointer in real64_call_asm() + - nilfs2: do not write dirty data after degenerating to read-only + - nilfs2: fix infinite loop in nilfs_mdt_get_block() + - md/raid10: fix null-ptr-deref in raid10_sync_request + - mailbox: zynqmp: Fix IPI isr handling + - mailbox: zynqmp: Fix typo in IPI documentation + - wifi: rtl8xxxu: RTL8192EU always needs full init + - clk: rockchip: rk3399: allow clk_cifout to force clk_cifout_src to reparent + - scripts/gdb: fix lx-timerlist for Python3 + - btrfs: scrub: reject unsupported scrub flags + - s390/dasd: fix hanging blockdevice after request requeue + - dm clone: call kmem_cache_destroy() in dm_clone_init() error path + - dm integrity: call kmem_cache_destroy() in dm_integrity_init() error path + - dm flakey: fix a crash with invalid table line + - perf auxtrace: Fix address filter entire kernel size + - perf intel-pt: Fix CYC timestamps after standalone CBR + - debugobject: Ensure pool refill (again) + - nohz: Add TICK_DEP_BIT_RCU + - tick/nohz: Fix cpu_is_hotpluggable() by checking with nohz subsystem + - mailbox: zynq: Switch to flexible array to simplify code + - mailbox: zynqmp: Fix counts of child nodes + - dm verity: skip redundant verity_handle_err() on I/O errors + - dm verity: fix error handling for check_at_most_once on FEC + - crypto: inside-secure - irq balance + - crypto: safexcel - Cleanup ring IRQ workqueues on load failure + - net/ncsi: clear Tx enable mode when handling a Config required AEN + - net/sched: cls_api: remove block_cb from driver_list before freeing + - sit: update dev->needed_headroom in ipip6_tunnel_bind_dev() + - net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu + - writeback: fix call of incorrect macro + - net/sched: act_mirred: Add carrier check + - rxrpc: Fix hard call timeout units + - ionic: remove noise from ethtool rxnfc error msg + - af_packet: Don't send zero-byte data in packet_sendmsg_spkt(). + - drm/amdgpu: add a missing lock for AMDGPU_SCHED + - ALSA: caiaq: input: Add error handling for unsupported input methods in + `snd_usb_caiaq_input_init` + - net: dsa: mt7530: fix corrupt frames using trgmii on 40 MHz XTAL MT7621 + - virtio_net: split free_unused_bufs() + - virtio_net: suppress cpu stall when free_unused_bufs + - perf vendor events power9: Remove UTF-8 characters from JSON files + - perf map: Delete two variable initialisations before null pointer checks in + sort__sym_from_cmp() + - perf symbols: Fix return incorrect build_id size in elf_read_build_id() + - btrfs: fix btrfs_prev_leaf() to not return the same key twice + - btrfs: don't free qgroup space unless specified + - btrfs: print-tree: parent bytenr must be aligned to sector size + - cifs: fix pcchunk length type in smb2_copychunk_range + - platform/x86: touchscreen_dmi: Add info for the Dexp Ursus KX210i + - inotify: Avoid reporting event with invalid wd + - sh: math-emu: fix macro redefined warning + - sh: init: use OF_EARLY_FLATTREE for early init + - sh: nmi_debug: fix return value of __setup handler + - remoteproc: stm32: Call of_node_put() on iteration error + - remoteproc: st: Call of_node_put() on iteration error + - ARM: dts: exynos: fix WM8960 clock name in Itop Elite + - ARM: dts: s5pv210: correct MIPI CSIS clock name + - f2fs: fix potential corruption when moving a directory + - drm/panel: otm8009a: Set backlight parent to panel device + - drm/amdgpu: fix an amdgpu_irq_put() issue in gmc_v9_0_hw_fini() + - drm/amdgpu/gfx: disable gfx9 cp_ecc_error_irq only when enabling legacy gfx + ras + - drm/amdgpu: disable sdma ecc irq only when sdma RAS is enabled in suspend + - HID: wacom: Set a default resolution for older tablets + - HID: wacom: insert timestamp to packed Bluetooth (BT) events + - ext4: fix WARNING in mb_find_extent + - ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum + - ext4: fix data races when using cached status extents + - ext4: improve error recovery code paths in __ext4_remount() + - ext4: fix deadlock when converting an inline directory in nojournal mode + - ext4: add bounds checking in get_max_inline_xattr_value_size() + - ext4: bail out of ext4_xattr_ibody_get() fails for any reason + - ext4: remove a BUG_ON in ext4_mb_release_group_pa() + - ext4: fix invalid free tracking in ext4_xattr_move_to_block() + - tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH + - serial: 8250: Fix serial8250_tx_empty() race with DMA Tx + - drbd: correctly submit flush bio on barrier + - PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors + - PCI: pciehp: Fix AB-BA deadlock between reset_lock and device_lock + - printk: declare printk_deferred_{enter,safe}() in include/linux/printk.h + - PM: domains: Restore comment indentation for generic_pm_domain.child_links + - drm/msm: Fix double pm_runtime_disable() call + - firmware: raspberrypi: fix possible memory leak in rpi_firmware_probe() + - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup() + - drm/exynos: move to use request_irq by IRQF_NO_AUTOEN flag + - mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock + - drm/amd/display: Fix hang when skipping modeset + - Linux 5.4.243 + - Upstream stable to v5.4.243 + * Focal update: v5.4.243 upstream stable release (LP: #2025387) // + CVE-2023-2269 + - dm ioctl: fix nested locking in table_clear() to remove deadlock concern + * Focal update: v5.4.242 upstream stable release (LP: #2025094) + - ARM: dts: rockchip: fix a typo error for rk3288 spdif node + - arm64: dts: meson-g12-common: specify full DMC range + - netfilter: br_netfilter: fix recent physdev match breakage + - regulator: fan53555: Explicitly include bits header + - virtio_net: bugfix overflow inside xdp_linearize_page() + - netfilter: nf_tables: fix ifdef to also consider nf_tables=m + - i40e: fix accessing vsi->active_filters without holding lock + - i40e: fix i40e_setup_misc_vector() error handling + - mlxfw: fix null-ptr-deref in mlxfw_mfa2_tlv_next() + - bpf: Fix incorrect verifier pruning due to missing register precision taints + - e1000e: Disable TSO on i219-LM card to increase speed + - f2fs: Fix f2fs_truncate_partial_nodes ftrace event + - Input: i8042 - add quirk for Fujitsu Lifebook A574/H + - selftests: sigaltstack: fix -Wuninitialized + - scsi: megaraid_sas: Fix fw_crash_buffer_show() + - scsi: core: Improve scsi_vpd_inquiry() checks + - net: dsa: b53: mmap: add phy ops + - s390/ptrace: fix PTRACE_GET_LAST_BREAK error handling + - nvme-tcp: fix a possible UAF when failing to allocate an io queue + - xen/netback: use same error messages for same errors + - iio: light: tsl2772: fix reading proximity-diodes from device tree + - nilfs2: initialize unused bytes in segment summary blocks + - memstick: fix memory leak if card device is never registered + - mmc: sdhci_am654: Set HIGH_SPEED_ENA for SDR12 and SDR25 + - MIPS: Define RUNTIME_DISCARD_EXIT in LD script + - x86/purgatory: Don't generate debug info for purgatory.ro + - Revert "ext4: fix use-after-free in ext4_xattr_set_entry" + - ext4: remove duplicate definition of ext4_xattr_ibody_inline_set() + - ext4: fix use-after-free in ext4_xattr_set_entry + - udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM). + - tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct(). + - inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy(). + - dccp: Call inet6_destroy_sock() via sk->sk_destruct(). + - sctp: Call inet6_destroy_sock() via sk->sk_destruct(). + - xfs: fix forkoff miscalculation related to XFS_LITINO(mp) + - pwm: meson: Explicitly set .polarity in .get_state() + - iio: adc: at91-sama5d2_adc: fix an error code in at91_adc_allocate_trigger() + - ASN.1: Fix check for strdup() success + - Linux 5.4.242 + - Upstream stable to v5.4.242 + * CVE-2023-31084 // CVE-2023-31084 was assigned to this bug. + - media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() + * CVE-2023-3776 + - net/sched: cls_fw: Fix improper refcount update leads to use-after-free + * CVE-2023-3268 + - kernel/relay.c: fix read_pos error when multiple readers + - relayfs: fix out-of-bounds access in relay_file_read + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] resync getabis + + -- Joseph Salisbury Fri, 18 Aug 2023 11:45:53 -0400 + +linux-oracle (5.4.0-1107.116) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1107.116 -proposed tracker (LP: #2030624) + + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] resync getabis + + * Miscellaneous Ubuntu changes + - [Config] oracle: updateconfigs + + [ Ubuntu: 5.4.0-159.176 ] + + * focal/linux: 5.4.0-159.176 -proposed tracker (LP: #2031149) + * libgnutls report "trap invalid opcode" when trying to install packages over + https (LP: #2031093) + - [Config]: disable CONFIG_GDS_FORCE_MITIGATION + * Fix boot test warning for log_check "CPU: 0 PID: 0 at + arch/x86/kernel/fpu/xstate.c:878 get_xsave_addr+0x98/0xb0" (LP: #2031022) + - x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") + + [ Ubuntu: 5.4.0-157.174 ] + + * focal/linux: 5.4.0-157.174 -proposed tracker (LP: #2030632) + * CVE-2022-40982 + - x86/mm: Initialize text poking earlier + - x86/mm: fix poking_init() for Xen PV guests + - x86/mm: Use mm_alloc() in poking_init() + - mm: Move mm_cachep initialization to mm_init() + - init: Provide arch_cpu_finalize_init() + - x86/cpu: Switch to arch_cpu_finalize_init() + - ARM: cpu: Switch to arch_cpu_finalize_init() + - sparc/cpu: Switch to arch_cpu_finalize_init() + - um/cpu: Switch to arch_cpu_finalize_init() + - init: Remove check_bugs() leftovers + - init: Invoke arch_cpu_finalize_init() earlier + - init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init() + - x86/fpu: Remove cpuinfo argument from init functions + - x86/fpu: Mark init functions __init + - x86/fpu: Move FPU initialization into arch_cpu_finalize_init() + - x86/xen: Fix secondary processors' FPU initialization + - x86/speculation: Add Gather Data Sampling mitigation + - x86/speculation: Add force option to GDS mitigation + - x86/speculation: Add Kconfig option for GDS + - KVM: Add GDS_NO support to KVM + - Documentation/x86: Fix backwards on/off logic about YMM support + - [Config]: Enable CONFIG_ARCH_HAS_CPU_FINALIZE_INIT and + CONFIG_GDS_FORCE_MITIGATION + * CVE-2023-20593 + - x86/cpu/amd: Move the errata checking functionality up + - x86/cpu/amd: Add a Zenbleed fix + * CVE-2023-3776 + - net/sched: cls_fw: Fix improper refcount update leads to use-after-free + * CVE-2023-3611 + - net/sched: sch_qfq: account for stab overhead in qfq_enqueue + * CVE-2023-3609 + - net/sched: cls_u32: Fix reference counter leak leading to overflow + + -- Joseph Salisbury Tue, 15 Aug 2023 11:43:23 -0400 + +linux-oracle (5.4.0-1106.115) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1106.115 -proposed tracker (LP: #2026576) + + [ Ubuntu: 5.4.0-156.173 ] + + * focal/linux: 5.4.0-156.173 -proposed tracker (LP: #2026585) + * CVE-2023-3390 + - netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE + * Focal update: v5.4.241 upstream stable release (LP: #2023930) + - scsi: ses: Handle enclosure with just a primary component gracefully + - x86/PCI: Add quirk for AMD XHCI controller that loses MSI-X state in D3hot + - cgroup/cpuset: Wake up cpuset_attach_wq tasks in cpuset_cancel_attach() + - treewide: Replace DECLARE_TASKLET() with DECLARE_TASKLET_OLD() + - smb3: fix problem with null cifs super block with previous patch + - pinctrl: amd: Use irqchip template + - pinctrl: amd: disable and mask interrupts on probe + - pinctrl: amd: Disable and mask interrupts on resume + - pwm: cros-ec: Explicitly set .polarity in .get_state() + - pwm: sprd: Explicitly set .polarity in .get_state() + - wifi: mac80211: fix invalid drv_sta_pre_rcu_remove calls for non-uploaded + sta + - icmp: guard against too small mtu + - net: don't let netpoll invoke NAPI if in xmit context + - sctp: check send stream number after wait_for_sndbuf + - ipv6: Fix an uninit variable access bug in __ip6_make_skb() + - gpio: davinci: Add irq chip flag to skip set wake + - sunrpc: only free unix grouplist after RCU settles + - NFSD: callback request does not use correct credential for AUTH_SYS + - xhci: also avoid the XHCI_ZERO_64B_REGS quirk with a passthrough iommu + - USB: serial: cp210x: add Silicon Labs IFS-USB-DATACABLE IDs + - usb: typec: altmodes/displayport: Fix configure initial pin assignment + - USB: serial: option: add Telit FE990 compositions + - USB: serial: option: add Quectel RM500U-CN modem + - iio: adc: ti-ads7950: Set `can_sleep` flag for GPIO chip + - iio: dac: cio-dac: Fix max DAC write value check for 12-bit + - tty: serial: sh-sci: Fix transmit end interrupt handler + - tty: serial: sh-sci: Fix Rx on RZ/G2L SCI + - tty: serial: fsl_lpuart: avoid checking for transfer complete when + UARTCTRL_SBK is asserted in lpuart32_tx_empty + - nilfs2: fix potential UAF of struct nilfs_sc_info in nilfs_segctor_thread() + - nilfs2: fix sysfs interface lifetime + - ALSA: hda/realtek: Add quirk for Clevo X370SNW + - perf/core: Fix the same task check in perf_event_set_output + - ftrace: Mark get_lock_parent_ip() __always_inline + - can: j1939: j1939_tp_tx_dat_new(): fix out-of-bounds memory access + - tracing: Free error logs of tracing instances + - net_sched: prevent NULL dereference if default qdisc setup failed + - drm/panfrost: Fix the panfrost_mmu_map_fault_addr() error path + - ring-buffer: Fix race while reader and writer are on the same page + - mm/swap: fix swap_info_struct race between swapoff and get_swap_pages() + - irqdomain: Look for existing mapping only once + - irqdomain: Refactor __irq_domain_alloc_irqs() + - irqdomain: Fix mapping-creation race + - Revert "pinctrl: amd: Disable and mask interrupts on resume" + - ALSA: emu10k1: fix capture interrupt handler unlinking + - ALSA: hda/sigmatel: add pin overrides for Intel DP45SG motherboard + - ALSA: i2c/cs8427: fix iec958 mixer control deactivation + - ALSA: firewire-tascam: add missing unwind goto in + snd_tscm_stream_start_duplex() + - ALSA: hda/sigmatel: fix S/PDIF out on Intel D*45* motherboards + - Bluetooth: L2CAP: Fix use-after-free in l2cap_disconnect_{req,rsp} + - Bluetooth: Fix race condition in hidp_session_thread + - btrfs: print checksum type and implementation at mount time + - btrfs: fix fast csum implementation detection + - mtdblock: tolerate corrected bit-flips + - mtd: rawnand: meson: fix bitmask for length in command word + - mtd: rawnand: stm32_fmc2: remove unsupported EDO mode + - niu: Fix missing unwind goto in niu_alloc_channels() + - qlcnic: check pci_reset_function result + - sctp: fix a potential overflow in sctp_ifwdtsn_skip + - RDMA/core: Fix GID entry ref leak when create_ah fails + - udp6: fix potential access to stale information + - net: macb: fix a memory corruption in extended buffer descriptor mode + - power: supply: cros_usbpd: reclassify "default case!" as debug + - i2c: imx-lpi2c: clean rx/tx buffers upon new message + - efi: sysfb_efi: Add quirk for Lenovo Yoga Book X91F/L + - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Book X90F + - verify_pefile: relax wrapper length check + - asymmetric_keys: log on fatal failures in PE/pkcs7 + - ubi: Fix failure attaching when vid_hdr offset equals to (sub)page size + - mtd: ubi: wl: Fix a couple of kernel-doc issues + - ubi: Fix deadlock caused by recursively holding work_sem + - i2c: ocores: generate stop condition after timeout in polling mode + - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits + - coresight-etm4: Fix for() loop drvdata->nr_addr_cmp range bug + - xfs: show the proper user quota options + - xfs: remove the kuid/kgid conversion wrappers + - xfs: add a new xfs_sb_version_has_v3inode helper + - xfs: only check the superblock version for dinode size calculation + - xfs: simplify di_flags2 inheritance in xfs_ialloc + - xfs: simplify a check in xfs_ioctl_setattr_check_cowextsize + - xfs: remove the di_version field from struct icdinode + - xfs: set inode size after creating symlink + - xfs: report corruption only as a regular error + - xfs: shut down the filesystem if we screw up quota reservation + - xfs: consider shutdown in bmapbt cursor delete assert + - xfs: don't reuse busy extents on extent trim + - xfs: force log and push AIL to clear pinned inodes when aborting mount + - Linux 5.4.241 + * [UBUNTU 20.04] [HPS] Kernel panic with "refcount_t: underflow" in mlx5 + driver (LP: #2019011) + - net/mlx5: cmdif, Avoid skipping reclaim pages if FW is not accessible + - net/mlx5: Fix handling of entry refcount when command is not issued to FW + * Disable hv-kvp-daemon if /dev/vmbus/hv_kvp is not present (LP: #2024900) + - [Packaging] disable hv-kvp-daemon if needed + * CVE-2023-35001 + - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval + * CVE-2023-32629 + - ovl: adhere to the vfs_ vs. ovl_do_ conventions for xattrs + * CVE-2023-3141 + - memstick: r592: Fix UAF bug in r592_remove due to race condition + * CVE-2023-3111 + - btrfs: check return value of btrfs_commit_transaction in relocation + - btrfs: unset reloc control if transaction commit fails in + prepare_to_relocate() + * CVE-2023-3090 + - ipvlan:Fix out-of-bounds caused by unclear skb->cb + * CVE-2023-1611 + - btrfs: fix race between quota disable and quota assign ioctls + * CVE-2022-0168 + - cifs: move some variables off the stack in smb2_ioctl_query_info + - cifs: prevent bad output lengths in smb2_ioctl_query_info() + - cifs: fix NULL ptr dereference in smb2_ioctl_query_info() + * CVE-2022-27672 + - x86/speculation: Identify processors vulnerable to SMT RSB predictions + - KVM: x86: Mitigate the cross-thread return address predictions bug + - Documentation/hw-vuln: Add documentation for Cross-Thread Return Predictions + * Severe NFS performance degradation after LP #2003053 (LP: #2022098) + - SAUCE: Make NFS file-access stale cache behaviour opt-in + * Encountering an issue with memcpy_fromio causing failed boot of SEV-enabled + guest (LP: #2020319) + - x86/sev: Unroll string mmio with CC_ATTR_GUEST_UNROLL_STRING_IO + * Focal update: v5.4.240 upstream stable release (LP: #2023601) + - net: tls: fix possible race condition between do_tls_getsockopt_conf() and + do_tls_setsockopt_conf() + - power: supply: da9150: Fix use after free bug in da9150_charger_remove due + to race condition + - iavf: fix inverted Rx hash condition leading to disabled hash + - iavf: fix non-tunneled IPv6 UDP packet type and hashing + - intel/igbvf: free irq on the error path in igbvf_request_msix() + - igbvf: Regard vf reset nack as success + - i2c: imx-lpi2c: check only for enabled interrupt flags + - scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate() + - net: usb: smsc95xx: Limit packet length to skb->len + - qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info + - net: qcom/emac: Fix use after free bug in emac_remove due to race condition + - net/ps3_gelic_net: Fix RX sk_buff length + - net/ps3_gelic_net: Use dma_mapping_error + - keys: Do not cache key in task struct if key is requested from kernel thread + - bpf: Adjust insufficient default bpf_jit_limit + - net/mlx5: Read the TC mapping of all priorities on ETS query + - atm: idt77252: fix kmemleak when rmmod idt77252 + - erspan: do not use skb_mac_header() in ndo_start_xmit() + - net/sonic: use dma_mapping_error() for error check + - nvme-tcp: fix nvme_tcp_term_pdu to match spec + - hvc/xen: prevent concurrent accesses to the shared ring + - net: mdio: thunder: Add missing fwnode_handle_put() + - Bluetooth: btqcomsmd: Fix command timeout after setting BD address + - platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl + - hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs + - scsi: qla2xxx: Perform lockless command completion in abort path + - uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2 + - thunderbolt: Use const qualifier for `ring_interrupt_index` + - riscv: Bump COMMAND_LINE_SIZE value to 1024 + - ca8210: fix mac_len negative array access + - m68k: Only force 030 bus error if PC not in exception table + - selftests/bpf: check that modifier resolves after pointer + - scsi: target: iscsi: Fix an error message in iscsi_check_key() + - scsi: ufs: core: Add soft dependency on governor_simpleondemand + - scsi: lpfc: Avoid usage of list iterator variable after loop + - net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990 + - net: usb: qmi_wwan: add Telit 0x1080 composition + - sh: sanitize the flags on sigreturn + - cifs: empty interface list when server doesn't support query interfaces + - scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR + - usb: gadget: u_audio: don't let userspace block driver unbind + - fsverity: Remove WQ_UNBOUND from fsverity read workqueue + - igb: revert rtnl_lock() that causes deadlock + - dm thin: fix deadlock when swapping to thin device + - usb: cdns3: Fix issue with using incorrect PCI device function + - usb: chipdea: core: fix return -EINVAL if request role is the same with + current role + - usb: chipidea: core: fix possible concurrent when switch role + - wifi: mac80211: fix qos on mesh interfaces + - nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy() + - i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer() + - dm stats: check for and propagate alloc_percpu failure + - dm crypt: add cond_resched() to dmcrypt_write() + - sched/fair: sanitize vruntime of entity being placed + - sched/fair: Sanitize vruntime of entity being migrated + - tun: avoid double free in tun_free_netdev + - ocfs2: fix data corruption after failed write + - fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY + - bus: imx-weim: fix branch condition evaluates to a garbage value + - md: avoid signed overflow in slot_store() + - ALSA: asihpi: check pao in control_message() + - ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set() + - fbdev: tgafb: Fix potential divide by zero + - sched_getaffinity: don't assume 'cpumask_size()' is fully initialized + - fbdev: nvidia: Fix potential divide by zero + - fbdev: intelfb: Fix potential divide by zero + - fbdev: lxfb: Fix potential divide by zero + - fbdev: au1200fb: Fix potential divide by zero + - ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx() + - dma-mapping: drop the dev argument to arch_sync_dma_for_* + - mips: bmips: BCM6358: disable RAC flush for TP1 + - mtd: rawnand: meson: invalidate cache on polling ECC bit + - scsi: megaraid_sas: Fix crash after a double completion + - ptp_qoriq: fix memory leak in probe() + - regulator: fix spelling mistake "Cant" -> "Can't" + - regulator: Handle deferred clk + - net/net_failover: fix txq exceeding warning + - can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write + - s390/vfio-ap: fix memory leak in vfio_ap device driver + - i40e: fix registers dump after run ethtool adapter self test + - bnxt_en: Fix typo in PCI id to device description string mapping + - net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only + - net: mvneta: make tx buffer array agnostic + - pinctrl: ocelot: Fix alt mode for ocelot + - Input: alps - fix compatibility with -funsigned-char + - Input: focaltech - use explicitly signed char type + - cifs: prevent infinite recursion in CIFSGetDFSRefer() + - cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL + - Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table + - xen/netback: don't do grant copy across page boundary + - pinctrl: at91-pio4: fix domain name assignment + - NFSv4: Fix hangs when recovering open state after a server reboot + - ALSA: hda/conexant: Partial revert of a quirk for Lenovo + - ALSA: usb-audio: Fix regression on detection of Roland VS-100 + - drm/etnaviv: fix reference leak when mmaping imported buffer + - btrfs: scan device in non-exclusive mode + - ext4: fix kernel BUG in 'ext4_write_inline_data_end()' + - net_sched: add __rcu annotation to netdev->qdisc + - net: sched: fix race condition in qdisc_graft() + - firmware: arm_scmi: Fix device node validation for mailbox transport + - gfs2: Always check inode size of inline inodes + - Linux 5.4.240 + * Focal update: v5.4.239 upstream stable release (LP: #2023600) + - Linux 5.4.239 + * CVE-2023-2124 + - xfs: verify buffer contents when we skip log replay + * CVE-2020-36691 + - netlink: limit recursion depth in policy validation + * CVE-2022-1184 + - ext4: check if directory block is within i_size + - ext4: fix check for block being out of directory size + * CVE-2022-4269 + - net: sched: extract qstats update code into functions + - net: sched: don't expose action qstats to skb_tc_reinsert() + - net/sched: act_mirred: refactor the handle of xmit + - net: sched: remove unused tcf_result extension + - net/sched: act_mirred: better wording on protection against excessive stack + growth + - act_mirred: use the backlog for nested calls to mirred ingress + * Focal update: v5.4.238 upstream stable release (LP: #2023427) + - ext4: fix cgroup writeback accounting with fs-layer encryption + - xfrm: Allow transport-mode states with AF_UNSPEC selector + - drm/panfrost: Don't sync rpm suspension after mmu flushing + - cifs: Move the in_send statistic to __smb_send_rqst() + - drm/meson: fix 1px pink line on GXM when scaling video overlay + - clk: HI655X: select REGMAP instead of depending on it + - docs: Correct missing "d_" prefix for dentry_operations member + d_weak_revalidate + - scsi: mpt3sas: Fix NULL pointer access in mpt3sas_transport_port_add() + - ALSA: hda - add Intel DG1 PCI and HDMI ids + - ALSA: hda - controller is in GPU on the DG1 + - ALSA: hda: Add Alderlake-S PCI ID and HDMI codec vid + - ALSA: hda: Add Intel DG2 PCI ID and HDMI codec vid + - ALSA: hda: Match only Intel devices with CONTROLLER_IN_GPU() + - netfilter: nft_redir: correct value of inet type `.maxattrs` + - scsi: core: Fix a comment in function scsi_host_dev_release() + - scsi: core: Fix a procfs host directory removal regression + - tcp: tcp_make_synack() can be called from process context + - nfc: pn533: initialize struct pn533_out_arg properly + - ipvlan: Make skb->skb_iif track skb->dev for l3s mode + - i40e: Fix kernel crash during reboot when adapter is in recovery mode + - qed/qed_dev: guard against a possible division by zero + - net: tunnels: annotate lockless accesses to dev->needed_headroom + - net: phy: smsc: bail out in lan87xx_read_status if genphy_read_status fails + - nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition + - net: usb: smsc75xx: Limit packet length to skb->len + - nvmet: avoid potential UAF in nvmet_req_complete() + - block: sunvdc: add check for mdesc_grab() returning NULL + - ipv4: Fix incorrect table ID in IOCTL path + - net: usb: smsc75xx: Move packet length check to prevent kernel panic in + skb_pull + - net/iucv: Fix size of interrupt data + - ethernet: sun: add check for the mdesc_grab() + - hwmon: (adt7475) Display smoothing attributes in correct order + - hwmon: (adt7475) Fix masking of hysteresis registers + - hwmon: (xgene) Fix use after free bug in xgene_hwmon_remove due to race + condition + - hwmon: (ina3221) return prober error code + - media: m5mols: fix off-by-one loop termination error + - mmc: atmel-mci: fix race between stop command and start of next command + - jffs2: correct logic when creating a hole in jffs2_write_begin + - ext4: fail ext4_iget if special inode unallocated + - ext4: fix task hung in ext4_xattr_delete_inode + - drm/amdkfd: Fix an illegal memory access + - sh: intc: Avoid spurious sizeof-pointer-div warning + - ext4: fix possible double unlock when moving a directory + - tty: serial: fsl_lpuart: skip waiting for transmission complete when + UARTCTRL_SBK is asserted + - interconnect: fix mem leak when freeing nodes + - tracing: Check field value in hist_field_name() + - tracing: Make tracepoint lockdep check actually test something + - ftrace: Fix invalid address access in lookup_rec() when index is 0 + - fbdev: stifb: Provide valid pixelclock and add fb_check_var() checks + - x86/mm: Fix use of uninitialized buffer in sme_enable() + - drm/i915: Don't use stolen memory for ring buffers with LLC + - serial: 8250_em: Fix UART port type + - s390/ipl: add missing intersection check to ipl_report handling + - PCI: Unify delay handling for reset and resume + - HID: core: Provide new max_buffer_size attribute to over-ride the default + - HID: uhid: Over-ride the default maximum data buffer value with our own + - Linux 5.4.238 + * Focal update: v5.4.237 upstream stable release (LP: #2023420) + - fs: prevent out-of-bounds array speculation when closing a file descriptor + - x86/CPU/AMD: Disable XSAVES on AMD family 0x17 + - drm/connector: print max_requested_bpc in state debugfs + - ext4: fix RENAME_WHITEOUT handling for inline directories + - ext4: fix another off-by-one fsmap error on 1k block filesystems + - ext4: move where set the MAY_INLINE_DATA flag is set + - ext4: fix WARNING in ext4_update_inline_data + - ext4: zero i_disksize when initializing the bootloader inode + - nfc: change order inside nfc_se_io error path + - iommu/amd: Add PCI segment support for ivrs_[ioapic/hpet/acpihid] commands + - iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options + - iommu/amd: Add a length limitation for the ivrs_acpihid command-line + parameter + - ipmi:ssif: make ssif_i2c_send() void + - ipmi:ssif: resend_msg() cannot fail + - ipmi:ssif: Remove rtc_us_timer + - ipmi:ssif: Increase the message retry time + - ipmi:ssif: Add a timer between request retries + - irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent + - irqdomain: Fix domain registration race + - iommu/vt-d: Fix PASID directory pointer coherency + - SMB3: Backup intent flag missing from some more ops + - cifs: Fix uninitialized memory read in smb3_qfs_tcon() + - scsi: core: Remove the /proc/scsi/${proc_name} directory earlier + - ext4: Fix possible corruption when moving a directory + - drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register + - nfc: fdp: add null check of devm_kmalloc_array in + fdp_nci_i2c_read_device_properties + - ila: do not generate empty messages in ila_xlat_nl_cmd_get_mapping() + - selftests: nft_nat: ensuring the listening side is up before starting the + client + - net: usb: lan78xx: Remove lots of set but unused 'ret' variables + - net: lan78xx: fix accessing the LAN7800's internal phy specific registers + from the MAC driver + - net: caif: Fix use-after-free in cfusbl_device_notify() + - bnxt_en: Avoid order-5 memory allocation for TPA data + - netfilter: tproxy: fix deadlock due to missing BH disable + - btf: fix resolving BTF_KIND_VAR after ARRAY, STRUCT, UNION, PTR + - scsi: megaraid_sas: Update max supported LD IDs to 240 + - net/smc: fix fallback failed while sendmsg with fastopen + - riscv: Use READ_ONCE_NOCHECK in imprecise unwinding stack mode + - ext4: Fix deadlock during directory rename + - MIPS: Fix a compilation issue + - alpha: fix R_ALPHA_LITERAL reloc for large modules + - macintosh: windfarm: Use unsigned type for 1-bit bitfields + - PCI: Add SolidRun vendor ID + - media: ov5640: Fix analogue gain control + - ipmi/watchdog: replace atomic_add() and atomic_sub() + - ipmi:watchdog: Set panic count to proper value on a panic + - drm/i915: Don't use BAR mappings for ring buffers with LLC + - x86, vmlinux.lds: Add RUNTIME_DISCARD_EXIT to generic DISCARDS + - arch: fix broken BuildID for arm64 and riscv + - powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT + - powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds + - s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36 + - sh: define RUNTIME_DISCARD_EXIT + - UML: define RUNTIME_DISCARD_EXIT + - s390/dasd: add missing discipline function + - Linux 5.4.237 + * Focal update: v5.4.236 upstream stable release (LP: #2020390) + - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script + - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh + - Linux 5.4.236 + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + + -- Joseph Salisbury Thu, 13 Jul 2023 17:00:29 -0400 + +linux-oracle (5.4.0-1105.114) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1105.114 -proposed tracker (LP: #2026392) + + [ Ubuntu: 5.4.0-155.172 ] + + * focal/linux: 5.4.0-155.172 -proposed tracker (LP: #2026401) + * CVE-2023-3390 + - netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE + * CVE-2023-35001 + - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval + * CVE-2023-32629 + - ovl: adhere to the vfs_ vs. ovl_do_ conventions for xattrs + * CVE-2023-3090 + - ipvlan:Fix out-of-bounds caused by unclear skb->cb + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + + -- Joseph Salisbury Tue, 11 Jul 2023 15:12:47 -0400 + +linux-oracle (5.4.0-1104.113) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1104.113 -proposed tracker (LP: #2024099) + + [ Ubuntu: 5.4.0-153.170 ] + + * focal/linux: 5.4.0-153.170 -proposed tracker (LP: #2024108) + * cls_flower: off-by-one in fl_set_geneve_opt (LP: #2023577) + - net/sched: flower: fix possible OOB write in fl_set_geneve_opt() + * Some INVLPG implementations can leave Global translations unflushed when + PCIDs are enabled (LP: #2023220) + - x86/mm: Avoid incomplete Global INVLPG flushes + + [ Ubuntu: 5.4.0-152.169 ] + + * focal/linux: 5.4.0-152.169 -proposed tracker (LP: #2023070) + * Focal update: v5.4.236 upstream stable release (LP: #2020390) + - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext" + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync getabis + + -- Joseph Salisbury Tue, 20 Jun 2023 14:48:46 -0400 + +linux-oracle (5.4.0-1103.112) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1103.112 -proposed tracker (LP: #2019365) + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.4.0-151.168 ] + + * focal/linux: 5.4.0-151.168 -proposed tracker (LP: #2019375) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - debian/dkms-versions -- update from kernel-versions (main/2023.05.15) + * CVE-2023-32233 + - netfilter: nf_tables: deactivate anonymous set from preparation phase + * CVE-2023-2612 + - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object() + * CVE-2023-31436 + - net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg + * CVE-2023-1380 + - wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies() + * Focal update: Focal update: v5.4.235 upstream stable release (LP: #2017706) + - HID: asus: Remove check for same LED brightness on set + - HID: asus: use spinlock to protect concurrent accesses + - HID: asus: use spinlock to safely schedule workers + - ARM: OMAP2+: Fix memory leak in realtime_counter_init() + - arm64: dts: qcom: qcs404: use symbol names for PCIe resets + - ARM: zynq: Fix refcount leak in zynq_early_slcr_init + - arm64: dts: meson-gx: Fix Ethernet MAC address unit name + - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name + - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address + - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards + - ARM: OMAP1: call platform_device_put() in error case in + omap1_dm_timer_init() + - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato + - ARM: imx: Call ida_simple_remove() for ida_simple_get + - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible + - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name + - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node + name + - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name + - ARM: dts: imx7s: correct iomuxc gpr mux controller cells + - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node + - Revert "scsi: core: run queue if SCSI device queue isn't ready and queue is + idle" + - block: Limit number of items taken from the I/O scheduler in one go + - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx + - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait + - blk-mq: correct stale comment of .get_budget + - s390/dasd: Prepare for additional path event handling + - s390/dasd: Fix potential memleak in dasd_eckd_init() + - sched/deadline,rt: Remove unused parameter from pick_next_[rt|dl]_entity() + - sched/rt: pick_next_rt_entity(): check list_entry + - block: bio-integrity: Copy flags when bio_integrity_payload is cloned + - wifi: rsi: Fix memory leak in rsi_coex_attach() + - net/wireless: Delete unnecessary checks before the macro call + “dev_kfree_skb” + - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: libertas: fix memory leak in lbs_init_adapter() + - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave() + - rtlwifi: fix -Wpointer-sign warning + - wifi: rtlwifi: Fix global-out-of-bounds bug in + _rtl8812ae_phy_set_txpower_limit() + - ipw2x00: switch from 'pci_' to 'dma_' API + - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: ipw2200: fix memory leak in ipw_wdev_init() + - wilc1000: let wilc_mac_xmit() return NETDEV_TX_OK + - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit() + - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit() + - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid() + - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave() + - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave() + - crypto: x86/ghash - fix unaligned access in ghash_setkey() + - ACPICA: Drop port I/O validation for some regions + - genirq: Fix the return type of kstat_cpu_irqs_sum() + - lib/mpi: Fix buffer overrun when SG is too long + - ACPICA: nsrepair: handle cases without a return value correctly + - wifi: orinoco: check return value of hermes_write_wordrec() + - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback + function + - ath9k: hif_usb: simplify if-if to if-else + - ath9k: htc: clean up statistics macros + - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails + - wifi: ath9k: Fix potential stack-out-of-bounds write in + ath9k_wmi_rsp_callback() + - ACPI: battery: Fix missing NUL-termination with large strings + - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename + - crypto: essiv - remove redundant null pointer check before kfree + - crypto: essiv - Handle EBUSY correctly + - crypto: seqiv - Handle EBUSY correctly + - powercap: fix possible name leak in powercap_register_zone() + - net/mlx5: Enhance debug print in page allocation failure + - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains + - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe + - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe + - mptcp: add sk_stop_timer_sync helper + - net: add sock_init_data_uid() + - tun: tun_chr_open(): correctly initialize socket uid + - tap: tap_open(): correctly initialize socket uid + - OPP: fix error checking in opp_migrate_dentry() + - Bluetooth: L2CAP: Fix potential user-after-free + - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg() + - rds: rds_rm_zerocopy_callback() correct order for list_add_tail() + - crypto: rsa-pkcs1pad - Use akcipher_request_complete + - m68k: /proc/hardware should depend on PROC_FS + - RISC-V: time: initialize hrtimer based broadcast clock event device + - usb: gadget: udc: Avoid tasklet passing a global + - wifi: iwl3945: Add missing check for create_singlethread_workqueue + - wifi: iwl4965: Add missing check for create_singlethread_workqueue() + - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize() + - crypto: crypto4xx - Call dma_unmap_page when done + - wifi: mac80211: make rate u32 in sta_set_rate_info_rx() + - thermal/drivers/hisi: Drop second sensor hi3660 + - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a + bus error + - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts + - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts + - selftests/net: Interpret UDP_GRO cmsg data as an int value + - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats + - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC + - drm/bridge: megachips: Fix error handling in i2c_register_driver() + - drm/vc4: dpi: Add option for inverting pixel clock and output enable + - drm/vc4: dpi: Fix format mapping for RGB565 + - gpu: ipu-v3: common: Add of_node_put() for reference returned by + of_graph_get_port_by_id() + - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue + - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain + - ASoC: fsl_sai: initialize is_dsp_mode flag + - ALSA: hda/ca0132: minor fix for allocation size + - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness + - drm/msm: use strscpy instead of strncpy + - drm/msm/dpu: Add check for cstate + - drm/msm/dpu: Add check for pstates + - drm/exynos: Don't reset bridge->next + - drm/bridge: Rename bridge helpers targeting a bridge chain + - drm/bridge: Introduce drm_bridge_get_next_bridge() + - drm: Initialize struct drm_crtc_state.no_vblank from device settings + - drm/msm/mdp5: Add check for kzalloc + - gpu: host1x: Don't skip assigning syncpoints to channels + - drm/mediatek: remove cast to pointers passed to kfree + - drm/mediatek: Use NULL instead of 0 for NULL pointer + - drm/mediatek: Drop unbalanced obj unref + - drm/mediatek: Clean dangling pointer on bind error path + - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress() + - gpio: vf610: connect GPIO label to dev name + - hwmon: (ltc2945) Handle error case in ltc2945_value_store + - scsi: aic94xx: Add missing check for dma_map_single() + - spi: bcm63xx-hsspi: fix pm_runtime + - spi: bcm63xx-hsspi: Fix multi-bit mode setting + - hwmon: (mlxreg-fan) Return zero speed for broken fan + - dm: remove flush_scheduled_work() during local_exit() + - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() + - ASoC: dapm: declare missing structure prototypes + - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared + - HID: bigben: use spinlock to protect concurrent accesses + - HID: bigben_worker() remove unneeded check on report_field + - HID: bigben: use spinlock to safely schedule workers + - HID: asus: Only set EV_REP if we are adding a mapping + - HID: asus: Add report_size to struct asus_touchpad_info + - HID: asus: Add support for multi-touch touchpad on Medion Akoya E1239T + - HID: asus: Fix mute and touchpad-toggle keys on Medion Akoya E1239T + - hid: bigben_probe(): validate report count + - nfsd: fix race to check ls_layouts + - cifs: Fix lost destroy smbd connection when MR allocate failed + - cifs: Fix warning and UAF when destroy the MR list + - gfs2: jdata writepage fix + - perf llvm: Fix inadvertent file creation + - perf tools: Fix auto-complete on aarch64 + - sparc: allow PM configs for sparc32 COMPILE_TEST + - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read() + - clk: qcom: gcc-qcs404: disable gpll[04]_out_aux parents + - clk: qcom: gcc-qcs404: fix names of the DSI clocks used as parents + - mtd: rawnand: sunxi: Fix the size of the last OOB region + - clk: renesas: cpg-mssr: Fix use after free if cpg_mssr_common_init() failed + - clk: renesas: cpg-mssr: Use enum clk_reg_layout instead of a boolean flag + - clk: renesas: cpg-mssr: Remove superfluous check in resume code + - Input: ads7846 - don't report pressure for ads7845 + - Input: ads7846 - don't check penirq immediately for 7845 + - clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX GDSC + - powerpc/powernv/ioda: Skip unallocated resources when mapping to PE + - clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled() + - powerpc/pseries/lpar: add missing RTAS retry status handling + - powerpc/pseries/lparcfg: add missing RTAS retry status handling + - powerpc/rtas: make all exports GPL + - powerpc/rtas: ensure 4KB alignment for rtas_data_buf + - powerpc/eeh: Small refactor of eeh_handle_normal_event() + - powerpc/eeh: Set channel state after notifying the drivers + - MIPS: SMP-CPS: fix build error when HOTPLUG_CPU not set + - MIPS: vpe-mt: drop physical_memsize + - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers + - media: platform: ti: Add missing check for devm_regulator_get + - powerpc: Remove linker flag from KBUILD_AFLAGS + - media: ov5675: Fix memleak in ov5675_init_controls() + - media: i2c: ov772x: Fix memleak in ov772x_probe() + - media: i2c: ov7670: 0 instead of -EINVAL was returned + - media: usb: siano: Fix use after free bugs caused by do_submit_urb + - rpmsg: glink: Avoid infinite loop on intent for missing channel + - udf: Define EFSCORRUPTED error code + - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy + - blk-iocost: fix divide by 0 error in calc_lcoefs() + - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds() + - rcu: Suppress smp_processor_id() complaint in + synchronize_rcu_expedited_wait() + - thermal: intel: Fix unsigned comparison with less than zero + - timers: Prevent union confusion from unexpected restart_syscall() + - x86/bugs: Reset speculation control settings on init + - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out- + of-bounds + - wifi: mt7601u: fix an integer underflow + - inet: fix fast path in __inet_hash_connect() + - ice: add missing checks for PF vsi type + - ACPI: Don't build ACPICA with '-Os' + - net: bcmgenet: Add a check for oversized packets + - m68k: Check syscall_trace_enter() return code + - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup + - ACPI: video: Fix Lenovo Ideapad Z570 DMI match + - net/mlx5: fw_tracer: Fix debug print + - coda: Avoid partial allocation of sig_inputArgs + - uaccess: Add minimum bounds check on kernel buffer size + - drm/amd/display: Fix potential null-deref in dm_resume + - drm/omap: dsi: Fix excessive stack usage + - HID: Add Mapping for System Microphone Mute + - drm/radeon: free iio for atombios when driver shutdown + - drm/msm/dsi: Add missing check for alloc_ordered_workqueue + - docs/scripts/gdb: add necessary make scripts_gdb step + - ASoC: kirkwood: Iterate over array indexes instead of using pointer math + - regulator: max77802: Bounds check regulator id against opmode + - regulator: s5m8767: Bounds check id indexing into arrays + - hwmon: (coretemp) Simplify platform device handling + - pinctrl: at91: use devm_kasprintf() to avoid potential leaks + - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 + - dm thin: add cond_resched() to various workqueue loops + - dm cache: add cond_resched() to various workqueue loops + - nfsd: zero out pointers after putting nfsd_files on COPY setup error + - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu + - firmware: coreboot: framebuffer: Ignore reserved pixel color bits + - rtc: pm8xxx: fix set-alarm race + - ipmi_ssif: Rename idle state and check + - s390: discard .interp section + - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler + - s390/kprobes: fix current_kprobe never cleared after kprobes reenter + - ARM: dts: exynos: correct HDMI phy compatible in Exynos4 + - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create + - fs: hfsplus: fix UAF issue in hfsplus_put_super + - f2fs: fix information leak in f2fs_move_inline_dirents() + - f2fs: fix cgroup writeback accounting with fs-layer encryption + - ocfs2: fix defrag path triggering jbd2 ASSERT + - ocfs2: fix non-auto defrag path not working issue + - udf: Truncate added extents on failed expansion + - udf: Do not bother merging very long extents + - udf: Do not update file length for failed writes to inline files + - udf: Preserve link count of system files + - udf: Detect system inodes linked into directory hierarchy + - udf: Fix file corruption when appending just after end of preallocated + extent + - KVM: Destroy target device if coalesced MMIO unregistration fails + - KVM: s390: disable migration mode when dirty tracking is disabled + - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows) + - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown + - x86/reboot: Disable virtualization in an emergency if SVM is supported + - x86/reboot: Disable SVM, not just VMX, when stopping CPUs + - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic + - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe + range + - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter + - x86/microcode/AMD: Add a @cpu parameter to the reloading functions + - x86/microcode/AMD: Fix mixed steppings support + - x86/speculation: Allow enabling STIBP with legacy IBRS + - Documentation/hw-vuln: Document the interaction between IBRS and STIBP + - ima: Align ima_file_mmap() parameters with mmap_file LSM hook + - irqdomain: Fix association race + - irqdomain: Fix disassociation race + - irqdomain: Drop bogus fwspec-mapping error handling + - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() + - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC + - ext4: optimize ea_inode block expansion + - ext4: refuse to create ea block when umounted + - wifi: rtl8xxxu: Use a longer retry limit of 48 + - wifi: cfg80211: Fix use after free for wext + - thermal: intel: powerclamp: Fix cur_state for multi package system + - dm flakey: fix logic when corrupting a bio + - dm flakey: don't corrupt the zero page + - ARM: dts: exynos: correct TMU phandle in Exynos4 + - ARM: dts: exynos: correct TMU phandle in Odroid XU + - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails + - alpha: fix FEN fault handling + - mips: fix syscall_get_nr + - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind + - mm: memcontrol: deprecate charge moving + - mm/thp: check and bail out if page in deferred queue already + - ktest.pl: Give back console on Ctrt^C on monitor + - ktest.pl: Fix missing "end_monitor" when machine check fails + - ktest.pl: Add RUN_TIMEOUT option with default unlimited + - scsi: qla2xxx: Fix link failure in NPIV environment + - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests + - scsi: qla2xxx: Fix erroneous link down + - scsi: ses: Don't attach if enclosure has no components + - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process() + - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses + - scsi: ses: Fix possible desc_ptr out-of-bounds accesses + - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove() + - PCI/PM: Observe reset delay irrespective of bridge_d3 + - PCI: hotplug: Allow marking devices as disconnected during bind/unbind + - PCI: Avoid FLR for AMD FCH AHCI adapters + - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv + - drm/radeon: Fix eDP for single-display iMac11,2 + - wifi: ath9k: use proper statements in conditionals + - kbuild: Port silent mode detection to future gnu make. + - fs/jfs: fix shift exponent db_agl2size negative + - pwm: sifive: Reduce time the controller lock is held + - pwm: sifive: Always let the first pwm_apply_state succeed + - pwm: stm32-lp: fix the check on arr and cmp registers update + - f2fs: use memcpy_{to,from}_page() where possible + - fs: f2fs: initialize fsdata in pagecache_write() + - um: vector: Fix memory leak in vector_config + - ubi: ensure that VID header offset + VID header size <= alloc, size + - ubifs: Fix build errors as symbol undefined + - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted + - ubifs: Rectify space budget for ubifs_xrename() + - ubifs: Fix wrong dirty space budget for dirty inode + - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1 + - ubifs: Reserve one leb for each journal head while doing budget + - ubi: Fix use-after-free when volume resizing failed + - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume() + - ubifs: Fix memory leak in alloc_wbufs() + - ubi: Fix possible null-ptr-deref in ubi_free_volume() + - ubifs: Re-statistic cleaned znode count if commit failed + - ubifs: dirty_cow_znode: Fix memleak in error handling path + - ubifs: ubifs_writepage: Mark page dirty after writing inode failed + - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show() + - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed + - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list + - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in + error path + - watchdog: Fix kmemleak in watchdog_cdev_register + - watchdog: pcwd_usb: Fix attempting to access uninitialized memory + - netfilter: ctnetlink: fix possible refcount leak in + ctnetlink_create_conntrack() + - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation + - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop + - net: fix __dev_kfree_skb_any() vs drop monitor + - 9p/xen: fix version parsing + - 9p/xen: fix connection sequence + - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv() + - net/mlx5: Geneve, Fix handling of Geneve object id as error code + - nfc: fix memory leak of se_io context in nfc_genl_se_io + - net/sched: act_sample: fix action bind logic + - ARM: dts: spear320-hmi: correct STMPE GPIO compatible + - tcp: tcp_check_req() can be called from process context + - vc_screen: modify vcs_size() handling in vcs_read() + - rtc: sun6i: Make external 32k oscillator optional + - rtc: sun6i: Always export the internal oscillator + - scsi: ipr: Work around fortify-string warning + - thermal: intel: quark_dts: fix error pointer dereference + - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it + - tracing: Add NULL checks for buffer in ring_buffer_free_read_page() + - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3 + - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak + - media: uvcvideo: Handle cameras with invalid descriptors + - media: uvcvideo: Handle errors from calls to usb_string + - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910 + - media: uvcvideo: Silence memcpy() run-time false positive warnings + - staging: emxx_udc: Add checks for dma_alloc_coherent() + - tty: fix out-of-bounds access in tty_driver_lookup_tty() + - tty: serial: fsl_lpuart: disable the CTS when send break signal + - mei: bus-fixup:upon error print return values of send and receive + - tools/iio/iio_utils:fix memory leak + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_status_word() + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_config_word() + - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer + math + - USB: ene_usb6250: Allocate enough memory for full object + - usb: uvc: Enumerate valid values for color matching + - kernel/fail_function: fix memory leak with using debugfs_lookup() + - PCI: Add ACS quirk for Wangxun NICs + - phy: rockchip-typec: Fix unsigned comparison with less than zero + - net: tls: avoid hanging tasks on the tx_lock + - x86/resctrl: Apply READ_ONCE/WRITE_ONCE to task_struct.{rmid,closid} + - x86/resctl: fix scheduler confusion with 'current' + - Bluetooth: hci_sock: purge socket queues in the destruct() callback + - SAUCE: Revert "UBUNTU: SAUCE: Fix inet_csk_listen_start after CVE-2023-0461" + - tcp: Fix listen() regression in 5.4.229. + - media: uvcvideo: Provide sync and async uvc_ctrl_status_event + - media: uvcvideo: Fix race condition with usb_kill_urb + - dt-bindings: rtc: sun6i-a31-rtc: Loosen the requirements on the clocks + - Linux 5.4.235 + - [Config] Drop mxsfb for armhf:generic-lpae + * Focal update: v5.4.234 upstream stable release (LP: #2017691) + - arm64: dts: rockchip: drop unused LED mode property from rk3328-roc-cc + - ARM: dts: rockchip: add power-domains property to dp node on rk3288 + - ACPI: NFIT: fix a potential deadlock during NFIT teardown + - btrfs: send: limit number of clones and allocated memory size + - IB/hfi1: Assign npages earlier + - neigh: make sure used and confirmed times are valid + - HID: core: Fix deadloop in hid_apply_multiplier. + - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state + - net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues(). + - vc_screen: don't clobber return value in vcs_read + - dmaengine: sh: rcar-dmac: Check for error num after dma_set_max_seg_size + - USB: serial: option: add support for VW/Skoda "Carstick LTE" + - USB: core: Don't hold device lock while reading the "descriptors" sysfs file + - Linux 5.4.234 + * CVE-2023-30456 + - KVM: nVMX: add missing consistency checks for CR0 and CR4 + * CVE-2023-1859 + - 9p/xen : Fix use after free bug in xen_9pfs_front_remove due to race + condition + * CVE-2023-1670 + - xirc2ps_cs: Fix use after free bug in xirc2ps_detach + + -- Joseph Salisbury Fri, 26 May 2023 12:39:58 -0400 + +linux-oracle (5.4.0-1102.111) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1102.111 -proposed tracker (LP: #2019672) + + [ Ubuntu: 5.4.0-150.167 ] + + * focal/linux: 5.4.0-150.167 -proposed tracker (LP: #2019682) + * CVE-2023-32233 + - netfilter: nf_tables: deactivate anonymous set from preparation phase + * CVE-2023-2612 + - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object() + * CVE-2023-31436 + - net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg + * CVE-2023-1380 + - wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies() + * CVE-2023-30456 + - KVM: nVMX: add missing consistency checks for CR0 and CR4 + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 18 May 2023 11:32:39 -0400 + +linux-oracle (5.4.0-1101.110) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1101.110 -proposed tracker (LP: #2016580) + + [ Ubuntu: 5.4.0-149.166 ] + + * focal/linux: 5.4.0-149.166 -proposed tracker (LP: #2016591) + * Focal update: v5.4.233 upstream stable release (LP: #2015909) + - dma-mapping: add generic helpers for mapping sgtable objects + - scatterlist: add generic wrappers for iterating over sgtable objects + - drm: etnaviv: fix common struct sg_table related issues + - drm/etnaviv: don't truncate physical page address + - wifi: rtl8xxxu: gen2: Turn on the rate control + - powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G + - random: always mix cycle counter in add_latent_entropy() + - KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception + - can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len + - powerpc: dts: t208x: Disable 10G on MAC1 and MAC2 + - alarmtimer: Prevent starvation by small intervals and SIG_IGN + - drm/i915/gvt: fix double free bug in split_2MB_gtt_entry + - mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh + - uaccess: Add speculation barrier to copy_from_user() + - wifi: mwifiex: Add missing compatible string for SD8787 + - ext4: Fix function prototype mismatch for ext4_feat_ktype + - Revert "net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo + child qdiscs" + - bpf: add missing header file include + - Linux 5.4.233 + * selftest: fib_tests: Always cleanup before exit (LP: #2015956) + - selftest: fib_tests: Always cleanup before exit + * fib_tests.sh in ubuntu_kernel_selftests was skipped silently on Focal + (LP: #2015440) + - selftests: Fix the executable permissions for fib_tests.sh + * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498) + - [Debian] autoreconstruct - fix restoration of execute permissions + * kernel: fix __clear_user() inline assembly constraints (LP: #2013088) + - s390/uaccess: add missing earlyclobber annotations to __clear_user() + * i/o error if next unused loop device is queried (LP: #1856871) + - loop: fix I/O error on fsync() in detached loop devices + * CVE-2023-1075 + - net/tls: tls_is_tx_ready() checked list_entry + * Focal update: v5.4.232 upstream stable release (LP: #2011625) + - firewire: fix memory leak for payload of request subaction to IEC 61883-1 + FCP region + - bus: sunxi-rsb: Fix error handling in sunxi_rsb_init() + - ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use + - ALSA: hda/via: Avoid potential array out-of-bound in add_secret_dac_path() + - arm64: dts: imx8mm: Fix pad control for UART1_DTE_RX + - scsi: Revert "scsi: core: map PQ=1, PDT=other values to + SCSI_SCAN_TARGET_PRESENT" + - WRITE is "data source", not destination... + - fix iov_iter_bvec() "direction" argument + - fix "direction" argument of iov_iter_kvec() + - netrom: Fix use-after-free caused by accept on already connected socket + - netfilter: br_netfilter: disable sabotage_in hook after first suppression + - squashfs: harden sanity check in squashfs_read_xattr_id_table + - net: phy: meson-gxl: Add generic dummy stubs for MMD register access + - can: j1939: fix errant WARN_ON_ONCE in j1939_session_deactivate + - ata: libata: Fix sata_down_spd_limit() when no link speed is reported + - selftests: net: udpgso_bench_rx: Fix 'used uninitialized' compiler warning + - selftests: net: udpgso_bench_rx/tx: Stop when wrong CLI args are provided + - selftests: net: udpgso_bench_tx: Cater for pending datagrams zerocopy + benchmarking + - virtio-net: Keep stop() to follow mirror sequence of open() + - net: openvswitch: fix flow memory leak in ovs_flow_cmd_new + - efi: fix potential NULL deref in efi_mem_reserve_persistent + - scsi: target: core: Fix warning on RT kernels + - scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress + - i2c: rk3x: fix a bunch of kernel-doc warnings + - net/x25: Fix to not accept on connected socket + - iio: adc: stm32-dfsdm: fill module aliases + - usb: dwc3: dwc3-qcom: Fix typo in the dwc3 vbus override API + - usb: dwc3: qcom: enable vbus override when in OTG dr-mode + - usb: gadget: f_fs: Fix unbalanced spinlock in __ffs_ep0_queue_wait + - vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF + - Input: i8042 - move __initconst to fix code styling warning + - Input: i8042 - merge quirk tables + - Input: i8042 - add TUXEDO devices to i8042 quirk tables + - Input: i8042 - add Clevo PCX0DX to i8042 quirk table + - fbcon: Check font dimension limits + - watchdog: diag288_wdt: do not use stack buffers for hardware data + - watchdog: diag288_wdt: fix __diag288() inline assembly + - efi: Accept version 2 of memory attributes table + - iio: hid: fix the retval in accel_3d_capture_sample + - iio: adc: berlin2-adc: Add missing of_node_put() in error path + - iio:adc:twl6030: Enable measurements of VUSB, VBAT and others + - parisc: Fix return code of pdc_iodc_print() + - parisc: Wire up PTRACE_GETREGS/PTRACE_SETREGS for compat case + - riscv: disable generation of unwind tables + - mm: hugetlb: proc: check for hugetlb shared PMD in /proc/PID/smaps + - fpga: stratix10-soc: Fix return value check in s10_ops_write_init() + - mm/swapfile: add cond_resched() in get_swap_pages() + - Squashfs: fix handling and sanity checking of xattr_ids count + - nvmem: core: fix cell removal on error + - mm: swap: properly update readahead statistics in unuse_pte_range() + - xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() + - serial: 8250_dma: Fix DMA Rx completion race + - serial: 8250_dma: Fix DMA Rx rearm race + - powerpc/imc-pmu: Revert nest_init_lock to being a mutex + - fbdev: smscufx: fix error handling code in ufx_usb_probe + - f2fs: fix to do sanity check on i_extra_isize in is_alive() + - wifi: brcmfmac: Check the count value of channel spec to prevent out-of- + bounds reads + - iio:adc:twl6030: Enable measurement of VAC + - btrfs: limit device extents to the device size + - btrfs: zlib: zero-initialize zlib workspace + - ALSA: emux: Avoid potential array out-of-bound in snd_emux_xg_control() + - tracing: Fix poll() and select() do not work on per_cpu trace_pipe and + trace_pipe_raw + - can: j1939: do not wait 250 ms if the same addr was already claimed + - IB/hfi1: Restore allocated resources on failed copyout + - IB/IPoIB: Fix legacy IPoIB due to wrong number of queues + - iommu: Add gfp parameter to iommu_ops::map + - RDMA/usnic: use iommu_map_atomic() under spin_lock() + - xfrm: fix bug with DSCP copy to v6 from v4 tunnel + - bonding: fix error checking in bond_debug_reregister() + - net: phy: meson-gxl: use MMD access dummy stubs for GXL, internal PHY + - ionic: clean interrupt before enabling queue to avoid credit race + - ice: Do not use WQ_MEM_RECLAIM flag for workqueue + - rds: rds_rm_zerocopy_callback() use list_first_entry() + - selftests: forwarding: lib: quote the sysctl values + - ALSA: pci: lx6464es: fix a debug loop + - pinctrl: aspeed: Fix confusing types in return value + - pinctrl: single: fix potential NULL dereference + - pinctrl: intel: Restore the pins that used to be in Direct IRQ mode + - net: USB: Fix wrong-direction WARNING in plusb.c + - usb: core: add quirk for Alcor Link AK9563 smartcard reader + - usb: typec: altmodes/displayport: Fix probe pin assign check + - ceph: flush cap releases when the session is flushed + - riscv: Fixup race condition on PG_dcache_clean in flush_icache_pte + - arm64: dts: meson-gx: Make mmc host controller interrupts level-sensitive + - arm64: dts: meson-g12-common: Make mmc host controller interrupts level- + sensitive + - arm64: dts: meson-axg: Make mmc host controller interrupts level-sensitive + - nvme-pci: Move enumeration by class to be last in the table + - bpf: Always return target ifindex in bpf_fib_lookup + - migrate: hugetlb: check for hugetlb shared PMD in node migration + - selftests/bpf: Verify copy_register_state() preserves parent/live fields + - ASoC: cs42l56: fix DT probe + - tools/virtio: fix the vringh test for virtio ring changes + - net/rose: Fix to not accept on connected socket + - net: stmmac: do not stop RX_CLK in Rx LPI state for qcs404 SoC + - net: sched: sch: Bounds check priority + - s390/decompressor: specify __decompress() buf len to avoid overflow + - nvme-fc: fix a missing queue put in nvmet_fc_ls_create_association + - aio: fix mremap after fork null-deref + - btrfs: free device in btrfs_close_devices for a single device filesystem + - netfilter: nft_tproxy: restrict to prerouting hook + - xfs: remove the xfs_efi_log_item_t typedef + - xfs: remove the xfs_efd_log_item_t typedef + - xfs: remove the xfs_inode_log_item_t typedef + - xfs: factor out a xfs_defer_create_intent helper + - xfs: merge the ->log_item defer op into ->create_intent + - xfs: merge the ->diff_items defer op into ->create_intent + - xfs: turn dfp_intent into a xfs_log_item + - xfs: refactor xfs_defer_finish_noroll + - xfs: log new intent items created as part of finishing recovered intent + items + - xfs: fix finobt btree block recovery ordering + - xfs: proper replay of deferred ops queued during log recovery + - xfs: xfs_defer_capture should absorb remaining block reservations + - xfs: xfs_defer_capture should absorb remaining transaction reservation + - xfs: clean up bmap intent item recovery checking + - xfs: clean up xfs_bui_item_recover iget/trans_alloc/ilock ordering + - xfs: fix an incore inode UAF in xfs_bui_recover + - xfs: change the order in which child and parent defer ops are finished + - xfs: periodically relog deferred intent items + - xfs: expose the log push threshold + - xfs: only relog deferred intent items if free space in the log gets low + - xfs: fix missing CoW blocks writeback conversion retry + - xfs: ensure inobt record walks always make forward progress + - xfs: fix the forward progress assertion in xfs_iwalk_run_callbacks + - xfs: prevent UAF in xfs_log_item_in_current_chkpt + - xfs: sync lazy sb accounting on quiesce of read-only mounts + - Revert "ipv4: Fix incorrect route flushing when source address is deleted" + - ipv4: Fix incorrect route flushing when source address is deleted + - mmc: sdio: fix possible resource leaks in some error paths + - mmc: mmc_spi: fix error handling in mmc_spi_probe() + - ALSA: hda/conexant: add a new hda codec SN6180 + - ALSA: hda/realtek - fixed wrong gpio assigned + - sched/psi: Fix use-after-free in ep_remove_wait_queue() + - hugetlb: check for undefined shift on 32 bit architectures + - Revert "mm: Always release pages to the buddy allocator in + memblock_free_late()." + - net: Fix unwanted sign extension in netdev_stats_to_stats64() + - revert "squashfs: harden sanity check in squashfs_read_xattr_id_table" + - ixgbe: allow to increase MTU to 3K with XDP enabled + - i40e: add double of VLAN header when computing the max MTU + - net: bgmac: fix BCM5358 support by setting correct flags + - sctp: sctp_sock_filter(): avoid list_entry() on possibly empty list + - dccp/tcp: Avoid negative sk_forward_alloc by ipv6_pinfo.pktoptions. + - net/usb: kalmia: Don't pass act_len in usb_bulk_msg error path + - net: stmmac: fix order of dwmac5 FlexPPS parametrization sequence + - bnxt_en: Fix mqprio and XDP ring checking logic + - net: stmmac: Restrict warning on disabling DMA store and fwd mode + - ixgbe: add double of VLAN header when computing the max MTU + - ipv6: Fix datagram socket connection with DSCP. + - ipv6: Fix tcp socket connection with DSCP. + - i40e: Add checking for null for nlmsg_find_attr() + - kvm: initialize all of the kvm_debugregs structure before sending it to + userspace + - nilfs2: fix underflow in second superblock position calculations + - ASoC: SOF: Intel: hda-dai: fix possible stream_tag leak + - net: sched: sch: Fix off by one in htb_activate_prios() + - iommu/amd: Pass gfp flags to iommu_map_page() in amd_iommu_map() + - Linux 5.4.232 + * CVE-2023-1118 + - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim() + + -- Joseph Salisbury Thu, 20 Apr 2023 14:54:45 -0400 + +linux-oracle (5.4.0-1100.109) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1100.109 -proposed tracker (LP: #2016766) + + * CVE-2023-1829 + - [Config]: Make sure CONFIG_NET_CLS_TCINDEX is not available + + [ Ubuntu: 5.4.0-148.165 ] + + * focal/linux: 5.4.0-148.165 -proposed tracker (LP: #2016777) + * CVE-2023-1829 + - net/sched: Retire tcindex classifier + - [Config]: Make sure CONFIG_NET_CLS_TCINDEX is not available + + -- Thadeu Lima de Souza Cascardo Wed, 19 Apr 2023 22:32:58 -0300 + +linux-oracle (5.4.0-1099.108) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1099.108 -proposed tracker (LP: #2011949) + + [ Ubuntu: 5.4.0-147.164 ] + + * focal/linux: 5.4.0-147.164 -proposed tracker (LP: #2011959) + * CVE-2023-26545 + - net: mpls: fix stale pointer if allocation fails during device rename + * CVE-2023-1281 + - rcu: Upgrade rcu_swap_protected() to rcu_replace_pointer() + - net/sched: tcindex: update imperfect hash filters respecting rcu + * Focal update: v5.4.231 upstream stable release (LP: #2011226) + - clk: generalize devm_clk_get() a bit + - clk: Provide new devm_clk helpers for prepared and enabled clocks + - memory: atmel-sdramc: Fix missing clk_disable_unprepare in + atmel_ramc_probe() + - memory: mvebu-devbus: Fix missing clk_disable_unprepare in + mvebu_devbus_probe() + - ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts' + - ARM: imx27: Retrieve the SYSCTRL base address from devicetree + - ARM: imx31: Retrieve the IIM base address from devicetree + - ARM: imx35: Retrieve the IIM base address from devicetree + - ARM: imx: add missing of_node_put() + - HID: intel_ish-hid: Add check for ishtp_dma_tx_map + - EDAC/highbank: Fix memory leak in highbank_mc_probe() + - tomoyo: fix broken dependency on *.conf.default + - RDMA/core: Fix ib block iterator counter overflow + - IB/hfi1: Reject a zero-length user expected buffer + - IB/hfi1: Reserve user expected TIDs + - IB/hfi1: Fix expected receive setup error exit issues + - affs: initialize fsdata in affs_truncate() + - amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent + - amd-xgbe: Delay AN timeout during KR training + - bpf: Fix pointer-leak due to insufficient speculative store bypass + mitigation + - phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in + rockchip_usb2phy_power_on() + - net: nfc: Fix use-after-free in local_cleanup() + - net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs + - gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode + - net/sched: sch_taprio: fix possible use-after-free + - net: fix a concurrency bug in l2tp_tunnel_register() + - l2tp: Serialize access to sk_user_data with sk_callback_lock + - l2tp: Don't sleep and disable BH under writer-side sk_callback_lock + - net: usb: sr9700: Handle negative len + - net: mdio: validate parameter addr in mdiobus_get_phy() + - HID: check empty report_list in hid_validate_values() + - HID: check empty report_list in bigben_probe() + - net: stmmac: fix invalid call to mdiobus_get_phy() + - HID: revert CHERRY_MOUSE_000C quirk + - usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait + - usb: gadget: f_fs: Ensure ep0req is dequeued before free_request + - net: mlx5: eliminate anonymous module_init & module_exit + - drm/panfrost: fix GENERIC_ATOMIC64 dependency + - dmaengine: Fix double increment of client_count in dma_chan_get() + - net: macb: fix PTP TX timestamp failure due to packet padding + - HID: betop: check shape of output reports + - dmaengine: xilinx_dma: use devm_platform_ioremap_resource() + - dmaengine: xilinx_dma: Fix devm_platform_ioremap_resource error handling + - dmaengine: xilinx_dma: call of_node_put() when breaking out of + for_each_child_of_node() + - tcp: avoid the lookup process failing to get sk in ehash table + - w1: fix deadloop in __w1_remove_master_device() + - w1: fix WARNING after calling w1_process() + - driver core: Fix test_async_probe_init saves device in wrong array + - net: dsa: microchip: ksz9477: port map correction in ALU table entry + register + - tcp: fix rate_app_limited to default to 1 + - cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist + - ASoC: fsl_micfil: Correct the number of steps on SX controls + - drm: Add orientation quirk for Lenovo ideapad D330-10IGL + - s390/debug: add _ASM_S390_ prefix to header guard + - cpufreq: armada-37xx: stop using 0 as NULL pointer + - ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97 CODEC + - ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets + - spi: spidev: remove debug messages that access spidev->spi without locking + - KVM: s390: interrupt: use READ_ONCE() before cmpxchg() + - scsi: hisi_sas: Set a port invalid only if there are no devices attached + when refreshing port id + - platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD + - platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK + - lockref: stop doing cpu_relax in the cmpxchg loop + - mmc: sdhci-esdhc-imx: clear pending interrupt and halt cqhci + - mmc: sdhci-esdhc-imx: disable the CMD CRC check for standard tuning + - mmc: sdhci-esdhc-imx: correct the tuning start tap and step setting + - netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state + - fs: reiserfs: remove useless new_opts in reiserfs_remount + - Bluetooth: hci_sync: cancel cmd_timer if hci_open failed + - scsi: hpsa: Fix allocation size for scsi_host_alloc() + - module: Don't wait for GOING modules + - tracing: Make sure trace_printk() can output as soon as it can be used + - trace_events_hist: add check for return value of 'create_hist_field' + - ftrace/scripts: Update the instructions for ftrace-bisect.sh + - cifs: Fix oops due to uncleared server->smbd_conn in reconnect + - KVM: x86/vmx: Do not skip segment attributes if unusable bit is set + - thermal: intel: int340x: Protect trip temperature from concurrent updates + - ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment + - EDAC/device: Respect any driver-supplied workqueue polling value + - EDAC/qcom: Do not pass llcc_driv_data as edac_device_ctl_info's pvt_info + - netlink: prevent potential spectre v1 gadgets + - net: fix UaF in netns ops registration error path + - netfilter: nft_set_rbtree: skip elements in transaction from garbage + collection + - netlink: annotate data races around nlk->portid + - netlink: annotate data races around dst_portid and dst_group + - netlink: annotate data races around sk_state + - ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() + - ipv4: prevent potential spectre v1 gadget in fib_metrics_match() + - netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE + - netrom: Fix use-after-free of a listening socket. + - net/sched: sch_taprio: do not schedule in taprio_reset() + - sctp: fail if no bound addresses can be used for a given scope + - net: ravb: Fix possible hang if RIS2_QFF1 happen + - thermal: intel: int340x: Add locking to int340x_thermal_get_trip_type() + - net/tg3: resolve deadlock in tg3_reset_task() during EEH + - net/phy/mdio-i2c: Move header file to include/linux/mdio + - net: xgene: Move shared header file into include/linux + - net: mdio-mux-meson-g12a: force internal PHY off on mux switch + - Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI + mode" + - nfsd: Ensure knfsd shuts down when the "nfsd" pseudofs is unmounted + - block: fix and cleanup bio_check_ro + - x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL + - netfilter: conntrack: unify established states for SCTP paths + - perf/x86/amd: fix potential integer overflow on shift of a int + - clk: Fix pointer casting to prevent oops in devm_clk_release() + - x86/asm: Fix an assembler warning with current binutils + - ARM: dts: imx: Fix pca9547 i2c-mux node name + - bpf: Skip task with pid=1 in send_signal_common() + - blk-cgroup: fix missing pd_online_fn() while activating policy + - dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init + - sysctl: add a new register_sysctl_init() interface + - panic: unset panic_on_warn inside panic() + - mm: kasan: do not panic if both panic_on_warn and kasan_multishot set + - exit: Add and use make_task_dead. + - objtool: Add a missing comma to avoid string concatenation + - hexagon: Fix function name in die() + - h8300: Fix build errors from do_exit() to make_task_dead() transition + - csky: Fix function name in csky_alignment() and die() + - ia64: make IA64_MCA_RECOVERY bool instead of tristate + - exit: Put an upper limit on how often we can oops + - exit: Expose "oops_count" to sysfs + - exit: Allow oops_limit to be disabled + - panic: Consolidate open-coded panic_on_warn checks + - panic: Introduce warn_limit + - panic: Expose "warn_count" to sysfs + - docs: Fix path paste-o for /sys/kernel/warn_count + - exit: Use READ_ONCE() for all oops/warn limit reads + - ipv6: ensure sane device mtu in tunnels + - Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt + - usb: host: xhci-plat: add wakeup entry at sysfs + - Revert "xprtrdma: Fix regbuf data not freed in rpcrdma_req_create()" + - Linux 5.4.231 + * CVE-2022-3903 + - USB: add usb_control_msg_send() and usb_control_msg_recv() + - USB: correct API of usb_control_msg_send/recv + - USB: move snd_usb_pipe_sanity_check into the USB core + - media: mceusb: Use new usb_control_msg_*() routines + * CVE-2022-3108 + - drm/amdkfd: Check for null pointer after calling kmemdup + * Focal update: v5.4.230 upstream stable release (LP: #2008946) + - pNFS/filelayout: Fix coalescing test for single DS + - net/ethtool/ioctl: return -EOPNOTSUPP if we have no phy stats + - RDMA/srp: Move large values to a new enum for gcc13 + - f2fs: let's avoid panic if extent_tree is not created + - wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices + - Add exception protection processing for vd in axi_chan_handle_err function + - nilfs2: fix general protection fault in nilfs_btree_insert() + - efi: fix userspace infinite retry read efivars after EFI runtime services + page fault + - drm/i915/gt: Reset twice + - ALSA: hda/realtek - Turn on power early + - xhci-pci: set the dma max_seg_size + - usb: xhci: Check endpoint is valid before dereferencing it + - xhci: Fix null pointer dereference when host dies + - xhci: Add update_hub_device override for PCI xHCI hosts + - xhci: Add a flag to disable USB3 lpm on a xhci root port level. + - usb: acpi: add helper to check port lpm capability using acpi _DSM + - xhci: Detect lpm incapable xHC USB3 roothub ports from ACPI tables + - prlimit: do_prlimit needs to have a speculation check + - USB: serial: option: add Quectel EM05-G (GR) modem + - USB: serial: option: add Quectel EM05-G (CS) modem + - USB: serial: option: add Quectel EM05-G (RS) modem + - USB: serial: option: add Quectel EC200U modem + - USB: serial: option: add Quectel EM05CN (SG) modem + - USB: serial: option: add Quectel EM05CN modem + - USB: misc: iowarrior: fix up header size for USB_DEVICE_ID_CODEMERCS_IOW100 + - misc: fastrpc: Don't remove map on creater_process and device_release + - misc: fastrpc: Fix use-after-free race condition for maps + - usb: core: hub: disable autosuspend for TI TUSB8041 + - comedi: adv_pci1760: Fix PWM instruction handling + - mmc: sunxi-mmc: Fix clock refcount imbalance during unbind + - btrfs: fix race between quota rescan and disable leading to NULL pointer + deref + - cifs: do not include page data when checking signature + - USB: serial: cp210x: add SCALANCE LPE-9000 device id + - usb: host: ehci-fsl: Fix module alias + - usb: typec: altmodes/displayport: Add pin assignment helper + - usb: typec: altmodes/displayport: Fix pin assignment calculation + - usb: gadget: g_webcam: Send color matching descriptor per frame + - usb: gadget: f_ncm: fix potential NULL ptr deref in ncm_bitrate() + - usb-storage: apply IGNORE_UAS only for HIKSEMI MD202 on RTL9210 + - dt-bindings: phy: g12a-usb3-pcie-phy: fix compatible string documentation + - serial: pch_uart: Pass correct sg to dma_unmap_sg() + - dmaengine: tegra210-adma: fix global intr clear + - serial: atmel: fix incorrect baudrate setup + - gsmi: fix null-deref in gsmi_get_variable + - drm/i915: re-disable RC6p on Sandy Bridge + - drm/amd/display: Fix set scaling doesn's work + - drm/amd/display: Fix COLOR_SPACE_YCBCR2020_TYPE matrix + - x86/fpu: Use _Alignof to avoid undefined behavior in TYPE_ALIGN + - mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma + - Linux 5.4.230 + + [ Ubuntu: 5.4.0-146.163 ] + + * focal/linux: 5.4.0-146.163 -proposed tracker (LP: #2012094) + * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325) + - NFS: Correct timing for assigning access cache timestamp + + -- Joseph Salisbury Wed, 29 Mar 2023 20:09:30 -0400 + +linux-oracle (5.4.0-1098.107) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1098.107 -proposed tracker (LP: #2009667) + + [ Ubuntu: 5.4.0-145.162 ] + + * focal/linux: 5.4.0-145.162 -proposed tracker (LP: #2008389) + * [SRU]Update ice driver to support E823 devices (LP: #1986717) + - ice: Add device ids for E822 devices + - ice: add support for E823 devices + * btrfs/154: rename fails with EOVERFLOW when calculating item size during + item key collision (LP: #2004132) + - btrfs: correctly calculate item size used when item key collision happens + * rtcpie in timers from ubuntu_kernel_selftests randomly failing + (LP: #1814234) + - SAUCE: selftest: rtcpie: Force passing unreliable subtest + * [UBUNTU 20.04] KVM: s390: pv: don't allow userspace to set the clock under + PV - kernel part (LP: #1999882) + - KVM: s390x: fix SCK locking + - KVM: s390: pv: don't allow userspace to set the clock under PV + * CVE-2021-3669 + - ipc: replace costly bailout check in sysvipc_find_ipc() + * net:fcnal-test.sh 'nettest' command not found on F/K (LP: #2006391) + - selftests/net: Find nettest in current directory + * xfs: Preallocated ioend transactions cause deadlock due to log buffer + exhaustion (LP: #2007219) + - xfs: drop submit side trans alloc for append ioends + * CVE-2022-4382 + - USB: gadgetfs: Fix race between mounting and unmounting + * CVE-2022-2196 + - KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS + * ubuntu_kernel_selftests: net:udpgso_bench.sh failed (LP: #1951447) + - selftests: net: udpgso_bench: Fix racing bug between the rx/tx programs + * net:fcnal-test.sh didn't return a non-zero value even with some sub-tests + failed (LP: #2006692) + - selftests: net/fcnal-test.sh: add exit code + * Fix selftests/ftracetests/Meta-selftests in Focal (LP: #2006453) + - SAUCE: Fix ftrace/Meta-selftests bashism check + * CVE-2023-23559 + - wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid + + -- Khalid Elmously Thu, 16 Mar 2023 22:28:03 -0400 + +linux-oracle (5.4.0-1097.106) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1097.106 -proposed tracker (LP: #2009337) + + * arm64 support (LP: #1925421) + - [config] Enable ARM_SMMU and ARM_SMMU_V3 + + -- Khalid Elmously Wed, 08 Mar 2023 00:29:07 -0500 + +linux-oracle (5.4.0-1094.103) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1094.103 -proposed tracker (LP: #2004376) + + [ Ubuntu: 5.4.0-144.161 ] + + * focal/linux: 5.4.0-144.161 -proposed tracker (LP: #2004653) + * CVE-2023-0461 + - SAUCE: Fix inet_csk_listen_start after CVE-2023-0461 + + [ Ubuntu: 5.4.0-143.160 ] + + * focal/linux: 5.4.0-143.160 -proposed tracker (LP: #2004385) + * NFS: client permission error after adding user to permissible group + (LP: #2003053) + - NFS: Clear the file access cache upon login + - NFS: Judge the file access cache's timestamp in rcu path + - NFS: Fix up a sparse warning + * Focal update: v5.4.229 upstream stable release (LP: #2003914) + - tracing/ring-buffer: Only do full wait when cpu != RING_BUFFER_ALL_CPUS + - udf: Discard preallocation before extending file with a hole + - udf: Fix preallocation discarding at indirect extent boundary + - udf: Do not bother looking for prealloc extents if i_lenExtents matches + i_size + - udf: Fix extending file within last block + - usb: gadget: uvc: Prevent buffer overflow in setup handler + - USB: serial: option: add Quectel EM05-G modem + - USB: serial: cp210x: add Kamstrup RF sniffer PIDs + - USB: serial: f81232: fix division by zero on line-speed change + - USB: serial: f81534: fix division by zero on line-speed change + - igb: Initialize mailbox message for VF reset + - xen-netback: move removal of "hotplug-status" to the right place + - HID: ite: Add support for Acer S1002 keyboard-dock + - HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch 10E + - HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch V 10 + - HID: uclogic: Add HID_QUIRK_HIDINPUT_FORCE quirk + - net: loopback: use NET_NAME_PREDICTABLE for name_assign_type + - usb: musb: remove extra check in musb_gadget_vbus_draw + - ARM: dts: qcom: apq8064: fix coresight compatible + - arm64: dts: qcom: sdm845-cheza: fix AP suspend pin bias + - drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static + - arm: dts: spear600: Fix clcd interrupt + - soc: ti: knav_qmss_queue: Use pm_runtime_resume_and_get instead of + pm_runtime_get_sync + - soc: ti: knav_qmss_queue: Fix PM disable depth imbalance in knav_queue_probe + - soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe + - perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init() + - perf/smmuv3: Fix hotplug callback leak in arm_smmu_pmu_init() + - arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators + - arm64: dts: mt2712e: Fix unit address for pinctrl node + - arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names + - arm64: dts: mt2712-evb: Fix usb vbus regulators unit names + - arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name + - ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: turris-omnia: Add ethernet aliases + - ARM: dts: turris-omnia: Add switch port 6 node + - arm64: dts: armada-3720-turris-mox: Add missing interrupt for RTC + - pstore/ram: Fix error return code in ramoops_probe() + - ARM: mmp: fix timer_read delay + - pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP + - tpm/tpm_crb: Fix error message in __crb_relinquish_locality() + - cpuidle: dt: Return the correct numbers of parsed idle states + - alpha: fix syscall entry in !AUDUT_SYSCALL case + - PM: hibernate: Fix mistake in kerneldoc comment + - fs: don't audit the capability check in simple_xattr_list() + - selftests/ftrace: event_triggers: wait longer for test_event_enable + - perf: Fix possible memleak in pmu_dev_alloc() + - timerqueue: Use rb_entry_safe() in timerqueue_getnext() + - proc: fixup uptime selftest + - lib/fonts: fix undefined behavior in bit shift for get_default_font + - ocfs2: fix memory leak in ocfs2_stack_glue_init() + - MIPS: vpe-mt: fix possible memory leak while module exiting + - MIPS: vpe-cmp: fix possible memory leak while module exiting + - selftests/efivarfs: Add checking of the test return value + - PNP: fix name memory leak in pnp_alloc_dev() + - perf/x86/intel/uncore: Fix reference count leak in hswep_has_limit_sbox() + - irqchip: gic-pm: Use pm_runtime_resume_and_get() in gic_probe() + - EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper() + - nfsd: don't call nfsd_file_put from client states seqfile display + - genirq/irqdesc: Don't try to remove non-existing sysfs files + - cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() + - libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value + - lib/notifier-error-inject: fix error when writing -errno to debugfs file + - docs: fault-injection: fix non-working usage of negative values + - debugfs: fix error when writing negative value to atomic_t debugfs file + - ocfs2: ocfs2_mount_volume does cleanup job before return error + - ocfs2: rewrite error handling of ocfs2_fill_super + - ocfs2: fix memory leak in ocfs2_mount_volume() + - rapidio: fix possible name leaks when rio_add_device() fails + - rapidio: rio: fix possible name leak in rio_register_mport() + - clocksource/drivers/sh_cmt: Make sure channel clock supply is enabled + - ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() + - uprobes/x86: Allow to probe a NOP instruction with 0x66 prefix + - xen/events: only register debug interrupt for 2-level events + - x86/xen: Fix memory leak in xen_smp_intr_init{_pv}() + - x86/xen: Fix memory leak in xen_init_lock_cpu() + - xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource() + - PM: runtime: Improve path in rpm_idle() when no callback + - PM: runtime: Do not call __rpm_callback() from rpm_idle() + - platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]() + - MIPS: BCM63xx: Add check for NULL for clk in clk_enable + - MIPS: OCTEON: warn only once if deprecated link status is being used + - fs: sysv: Fix sysv_nblocks() returns wrong value + - rapidio: fix possible UAF when kfifo_alloc() fails + - eventfd: change int to __u64 in eventfd_signal() ifndef CONFIG_EVENTFD + - relay: fix type mismatch when allocating memory in relay_create_buf() + - hfs: Fix OOB Write in hfs_asc2mac + - rapidio: devices: fix missing put_device in mport_cdev_open + - wifi: ath9k: hif_usb: fix memory leak of urbs in + ath9k_hif_usb_dealloc_tx_urbs() + - wifi: ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb() + - wifi: rtl8xxxu: Fix reading the vendor of combo chips + - pata_ipx4xx_cf: Fix unsigned comparison with less than zero + - media: i2c: ad5820: Fix error path + - can: kvaser_usb: do not increase tx statistics when sending error message + frames + - can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device + - can: kvaser_usb: kvaser_usb_leaf: Rename {leaf,usbcan}_cmd_error_event to + {leaf,usbcan}_cmd_can_error_event + - can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT + - can: kvaser_usb_leaf: Set Warning state even without bus errors + - can: kvaser_usb_leaf: Fix improved state not being reported + - can: kvaser_usb_leaf: Fix wrong CAN state after stopping + - can: kvaser_usb_leaf: Fix bogus restart events + - can: kvaser_usb: Add struct kvaser_usb_busparams + - can: kvaser_usb: Compare requested bittiming parameters with actual + parameters in do_set_{,data}_bittiming + - clk: renesas: r9a06g032: Repair grave increment error + - spi: Update reference to struct spi_controller + - drm/panel/panel-sitronix-st7701: Remove panel on DSI attach failure + - ima: Rename internal filter rule functions + - ima: Fix fall-through warnings for Clang + - ima: Handle -ESTALE returned by ima_filter_rule_match() + - media: vivid: fix compose size exceed boundary + - bpf: propagate precision in ALU/ALU64 operations + - mtd: Fix device name leak when register device failed in add_mtd_device() + - wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port + - media: camss: Clean up received buffers on failed start of streaming + - net, proc: Provide PROC_FS=n fallback for proc_create_net_single_write() + - rxrpc: Fix ack.bufferSize to be 0 when generating an ack + - drm/radeon: Add the missed acpi_put_table() to fix memory leak + - drm/mediatek: Modify dpi power on/off sequence. + - ASoC: pxa: fix null-pointer dereference in filter() + - regulator: core: fix unbalanced of node refcount in regulator_dev_lookup() + - amdgpu/pm: prevent array underflow in vega20_odn_edit_dpm_table() + - integrity: Fix memory leakage in keyring allocation error path + - ima: Fix misuse of dereference of pointer in template_desc_init_fields() + - wifi: ath10k: Fix return value in ath10k_pci_init() + - mtd: lpddr2_nvm: Fix possible null-ptr-deref + - Input: elants_i2c - properly handle the reset GPIO when power is off + - media: solo6x10: fix possible memory leak in solo_sysfs_init() + - media: platform: exynos4-is: Fix error handling in fimc_md_init() + - media: videobuf-dma-contig: use dma_mmap_coherent + - bpf: Move skb->len == 0 checks into __bpf_redirect + - HID: hid-sensor-custom: set fixed size for custom attributes + - ALSA: pcm: fix undefined behavior in bit shift for SNDRV_PCM_RATE_KNOT + - ALSA: seq: fix undefined behavior in bit shift for + SNDRV_SEQ_FILTER_USE_EVENT + - regulator: core: use kfree_const() to free space conditionally + - clk: rockchip: Fix memory leak in rockchip_clk_register_pll() + - bonding: Export skip slave logic to function + - bonding: Rename slave_arr to usable_slaves + - bonding: fix link recovery in mode 2 when updelay is nonzero + - mtd: maps: pxa2xx-flash: fix memory leak in probe + - media: imon: fix a race condition in send_packet() + - clk: imx8mn: correct the usb1_ctrl parent to be usb_bus + - clk: imx: replace osc_hdmi with dummy + - pinctrl: pinconf-generic: add missing of_node_put() + - media: dvb-core: Fix ignored return value in dvb_register_frontend() + - media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer() + - media: s5p-mfc: Add variant data for MFC v7 hardware for Exynos 3250 SoC + - drm/tegra: Add missing clk_disable_unprepare() in tegra_dc_probe() + - ASoC: dt-bindings: wcd9335: fix reset line polarity in example + - ASoC: mediatek: mtk-btcvsd: Add checks for write and read of mtk_btcvsd_snd + - NFSv4.2: Clear FATTR4_WORD2_SECURITY_LABEL when done decoding + - NFSv4.2: Fix a memory stomp in decode_attr_security_label + - NFSv4.2: Fix initialisation of struct nfs4_label + - NFSv4: Fix a deadlock between nfs4_open_recover_helper() and delegreturn + - ALSA: asihpi: fix missing pci_disable_device() + - wifi: iwlwifi: mvm: fix double free on tx path. + - ASoC: mediatek: mt8173: Enable IRQ when pdata is ready + - drm/radeon: Fix PCI device refcount leak in radeon_atrm_get_bios() + - drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios() + - ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe + - netfilter: conntrack: set icmpv6 redirects as RELATED + - bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data + - bpf, sockmap: Fix data loss caused by using apply_bytes on ingress redirect + - bonding: uninitialized variable in bond_miimon_inspect() + - spi: spidev: mask SPI_CS_HIGH in SPI_IOC_RD_MODE + - wifi: cfg80211: Fix not unregister reg_pdev when load_builtin_regdb_keys() + fails + - regulator: core: fix module refcount leak in set_supply() + - clk: qcom: clk-krait: fix wrong div2 functions + - hsr: Avoid double remove of a node. + - configfs: fix possible memory leak in configfs_create_dir() + - regulator: core: fix resource leak in regulator_register() + - bpf, sockmap: fix race in sock_map_free() + - media: saa7164: fix missing pci_disable_device() + - ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt + - xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() + - SUNRPC: Fix missing release socket in rpc_sockname() + - NFSv4.x: Fail client initialisation if state manager thread can't run + - mmc: alcor: fix return value check of mmc_add_host() + - mmc: moxart: fix return value check of mmc_add_host() + - mmc: mxcmmc: fix return value check of mmc_add_host() + - mmc: pxamci: fix return value check of mmc_add_host() + - mmc: rtsx_usb_sdmmc: fix return value check of mmc_add_host() + - mmc: toshsd: fix return value check of mmc_add_host() + - mmc: vub300: fix return value check of mmc_add_host() + - mmc: wmt-sdmmc: fix return value check of mmc_add_host() + - mmc: atmel-mci: fix return value check of mmc_add_host() + - mmc: omap_hsmmc: fix return value check of mmc_add_host() + - mmc: meson-gx: fix return value check of mmc_add_host() + - mmc: via-sdmmc: fix return value check of mmc_add_host() + - mmc: wbsd: fix return value check of mmc_add_host() + - mmc: mmci: fix return value check of mmc_add_host() + - media: c8sectpfe: Add of_node_put() when breaking out of loop + - media: coda: Add check for dcoda_iram_alloc + - media: coda: Add check for kmalloc + - clk: samsung: Fix memory leak in _samsung_clk_register_pll() + - spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode + - wifi: rtl8xxxu: Add __packed to struct rtl8723bu_c2h + - wifi: brcmfmac: Fix error return code in brcmf_sdio_download_firmware() + - blktrace: Fix output non-blktrace event when blk_classic option enabled + - clk: socfpga: clk-pll: Remove unused variable 'rc' + - clk: socfpga: use clk_hw_register for a5/c5 + - clk: socfpga: Fix memory leak in socfpga_gate_init() + - net: vmw_vsock: vmci: Check memcpy_from_msg() + - net: defxx: Fix missing err handling in dfx_init() + - net: stmmac: selftests: fix potential memleak in stmmac_test_arpoffload() + - drivers: net: qlcnic: Fix potential memory leak in qlcnic_sriov_init() + - of: overlay: fix null pointer dereferencing in find_dup_cset_node_entry() + and find_dup_cset_prop() + - ethernet: s2io: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: farsync: Fix kmemleak when rmmods farsync + - net/tunnel: wait until all sk_user_data reader finish before releasing the + sock + - net: apple: mace: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: apple: bmac: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: emaclite: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: ethernet: dnet: don't call dev_kfree_skb() under spin_lock_irqsave() + - hamradio: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: amd: lance: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: amd-xgbe: Fix logic around active and passive cables + - net: amd-xgbe: Check only the minimum speed for active/passive cables + - can: tcan4x5x: Remove invalid write in clear_interrupts + - net: lan9303: Fix read error execution path + - ntb_netdev: Use dev_kfree_skb_any() in interrupt context + - Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() + - stmmac: fix potential division by 0 + - apparmor: fix a memleak in multi_transaction_new() + - apparmor: fix lockdep warning when removing a namespace + - apparmor: Fix abi check to include v8 abi + - apparmor: Use pointer to struct aa_label for lbs_cred + - RDMA/core: Fix order of nldev_exit call + - f2fs: fix normal discard process + - RDMA/siw: Fix immediate work request flush to completion queue + - RDMA/nldev: Return "-EAGAIN" if the cm_id isn't from expected port + - RDMA/siw: Set defined status for work completion with undefined status + - scsi: scsi_debug: Fix a warning in resp_write_scat() + - crypto: ccree - swap SHA384 and SHA512 larval hashes at build time + - crypto: ccree - Remove debugfs when platform_driver_register failed + - PCI: Check for alloc failure in pci_request_irq() + - RDMA/hfi: Decrease PCI device reference count in error path + - crypto: ccree - Make cc_debugfs_global_fini() available for module init + function + - RDMA/rxe: Fix NULL-ptr-deref in rxe_qp_do_cleanup() when socket create + failed + - scsi: hpsa: Fix possible memory leak in hpsa_init_one() + - crypto: tcrypt - Fix multibuffer skcipher speed test mem leak + - scsi: mpt3sas: Fix possible resource leaks in mpt3sas_transport_port_add() + - scsi: hpsa: Fix error handling in hpsa_add_sas_host() + - scsi: hpsa: Fix possible memory leak in hpsa_add_sas_device() + - scsi: fcoe: Fix possible name leak when device_register() fails + - scsi: ipr: Fix WARNING in ipr_init() + - scsi: fcoe: Fix transport not deattached when fcoe_if_init() fails + - scsi: snic: Fix possible UAF in snic_tgt_create() + - RDMA/nldev: Add checks for nla_nest_start() in fill_stat_counter_qps() + - f2fs: avoid victim selection from previous victim section + - crypto: omap-sham - Use pm_runtime_resume_and_get() in omap_sham_probe() + - RDMA/hfi1: Fix error return code in parse_platform_config() + - orangefs: Fix sysfs not cleanup when dev init failed + - crypto: img-hash - Fix variable dereferenced before check 'hdev->req' + - hwrng: amd - Fix PCI device refcount leak + - hwrng: geode - Fix PCI device refcount leak + - IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces + - drivers: dio: fix possible memory leak in dio_init() + - tty: serial: tegra: Activate RX DMA transfer by request + - serial: tegra: Read DMA status before terminating + - class: fix possible memory leak in __class_register() + - vfio: platform: Do not pass return buffer to ACPI _RST method + - uio: uio_dmem_genirq: Fix missing unlock in irq configuration + - uio: uio_dmem_genirq: Fix deadlock between irq config and handling + - usb: fotg210-udc: Fix ages old endianness issues + - staging: vme_user: Fix possible UAF in tsi148_dma_list_add + - usb: typec: Check for ops->exit instead of ops->enter in altmode_exit + - usb: typec: tcpci: fix of node refcount leak in tcpci_register_port() + - serial: amba-pl011: avoid SBSA UART accessing DMACR register + - serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle. + - serial: pch: Fix PCI device refcount leak in pch_request_dma() + - tty: serial: clean up stop-tx part in altera_uart_tx_chars() + - tty: serial: altera_uart_{r,t}x_chars() need only uart_port + - serial: altera_uart: fix locking in polling mode + - serial: sunsab: Fix error handling in sunsab_init() + - test_firmware: fix memory leak in test_firmware_init() + - misc: ocxl: fix possible name leak in ocxl_file_register_afu() + - misc: tifm: fix possible memory leak in tifm_7xx1_switch_media() + - misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault + and gru_handle_user_call_os + - cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() + - cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() + - counter: stm32-lptimer-cnt: fix the check on arr and cmp registers update + - usb: roles: fix of node refcount leak in usb_role_switch_is_parent() + - usb: gadget: f_hid: optional SETUP/SET_REPORT mode + - usb: gadget: f_hid: fix f_hidg lifetime vs cdev + - usb: gadget: f_hid: fix refcount leak on error path + - drivers: mcb: fix resource leak in mcb_probe() + - mcb: mcb-parse: fix error handing in chameleon_parse_gdd() + - chardev: fix error handling in cdev_device_add() + - i2c: pxa-pci: fix missing pci_disable_device() on error in ce4100_i2c_probe + - staging: rtl8192u: Fix use after free in ieee80211_rx() + - staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() + - vme: Fix error not catched in fake_init() + - i2c: ismt: Fix an out-of-bounds bug in ismt_access() + - usb: storage: Add check for kcalloc + - tracing/hist: Fix issue of losting command info in error_log + - samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() + - fbdev: ssd1307fb: Drop optional dependency + - fbdev: pm2fb: fix missing pci_disable_device() + - fbdev: via: Fix error in via_core_init() + - fbdev: vermilion: decrease reference count in error path + - fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() + - HSI: omap_ssi_core: fix unbalanced pm_runtime_disable() + - HSI: omap_ssi_core: fix possible memory leak in ssi_probe() + - power: supply: fix residue sysfs file in error handle route of + __power_supply_register() + - perf trace: Return error if a system call doesn't exist + - perf trace: Separate 'struct syscall_fmt' definition from syscall_fmts + variable + - perf trace: Factor out the initialization of syscal_arg_fmt->scnprintf + - perf trace: Add the syscall_arg_fmt pointer to syscall_arg + - perf trace: Allow associating scnprintf routines with well known arg names + - perf trace: Add a strtoul() method to 'struct syscall_arg_fmt' + - perf trace: Use macro RAW_SYSCALL_ARGS_NUM to replace number + - perf trace: Handle failure when trace point folder is missed + - perf symbol: correction while adjusting symbol + - HSI: omap_ssi_core: Fix error handling in ssi_init() + - power: supply: fix null pointer dereferencing in + power_supply_get_battery_info + - RDMA/siw: Fix pointer cast warning + - include/uapi/linux/swab: Fix potentially missing __always_inline + - rtc: snvs: Allow a time difference on clock register read + - rtc: pcf85063: Fix reading alarm + - iommu/amd: Fix pci device refcount leak in ppr_notifier() + - iommu/fsl_pamu: Fix resource leak in fsl_pamu_probe() + - macintosh: fix possible memory leak in macio_add_one_device() + - macintosh/macio-adb: check the return value of ioremap() + - powerpc/52xx: Fix a resource leak in an error handling path + - cxl: Fix refcount leak in cxl_calc_capp_routing + - powerpc/xive: add missing iounmap() in error path in + xive_spapr_populate_irq_data() + - powerpc/perf: callchain validate kernel stack pointer bounds + - powerpc/83xx/mpc832x_rdb: call platform_device_put() in error case in + of_fsl_spi_probe() + - powerpc/hv-gpci: Fix hv_gpci event list + - selftests/powerpc: Fix resource leaks + - pwm: sifive: Call pwm_sifive_update_clock() while mutex is held + - remoteproc: sysmon: fix memory leak in qcom_add_sysmon_subdev() + - remoteproc: qcom_q6v5_pas: Fix missing of_node_put() in + adsp_alloc_memory_region() + - rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe() + - rtc: pic32: Move devm_rtc_allocate_device earlier in pic32_rtc_probe() + - nfsd: Define the file access mode enum for tracing + - NFSD: Add tracepoints to NFSD's duplicate reply cache + - nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure + - mISDN: hfcsusb: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - mISDN: hfcpci: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - nfc: pn533: Clear nfc_target before being used + - r6040: Fix kmemleak in probe and remove + - rtc: mxc_v2: Add missing clk_disable_unprepare() + - openvswitch: Fix flow lookup to use unmasked key + - skbuff: Account for tail adjustment during pull operations + - mailbox: zynq-ipi: fix error handling while device_register() fails + - net_sched: reject TCF_EM_SIMPLE case for complex ematch module + - rxrpc: Fix missing unlock in rxrpc_do_sendmsg() + - myri10ge: Fix an error handling path in myri10ge_probe() + - net: stream: purge sk_error_queue in sk_stream_kill_queues() + - rcu: Fix __this_cpu_read() lockdep warning in rcu_force_quiescent_state() + - binfmt_misc: fix shift-out-of-bounds in check_special_flags + - fs: jfs: fix shift-out-of-bounds in dbAllocAG + - udf: Avoid double brelse() in udf_rename() + - fs: jfs: fix shift-out-of-bounds in dbDiscardAG + - ACPICA: Fix error code path in acpi_ds_call_control_method() + - nilfs2: fix shift-out-of-bounds/overflow in nilfs_sb2_bad_offset() + - acct: fix potential integer overflow in encode_comp_t() + - hfs: fix OOB Read in __hfs_brec_find + - drm/etnaviv: add missing quirks for GC300 + - brcmfmac: return error when getting invalid max_flowrings from dongle + - wifi: ath9k: verify the expected usb_endpoints are present + - wifi: ar5523: Fix use-after-free on ar5523_cmd() timed out + - ASoC: codecs: rt298: Add quirk for KBL-R RVP platform + - ipmi: fix memleak when unload ipmi driver + - bpf: make sure skb->len != 0 when redirecting to a tunneling device + - net: ethernet: ti: Fix return type of netcp_ndo_start_xmit() + - hamradio: baycom_epp: Fix return type of baycom_send_packet() + - wifi: brcmfmac: Fix potential shift-out-of-bounds in + brcmf_fw_alloc_request() + - igb: Do not free q_vector unless new one was allocated + - s390/ctcm: Fix return type of ctc{mp,}m_tx() + - s390/netiucv: Fix return type of netiucv_tx() + - s390/lcs: Fix return type of lcs_start_xmit() + - drm/rockchip: Use drm_mode_copy() + - drm/sti: Use drm_mode_copy() + - drivers/md/md-bitmap: check the return value of md_bitmap_get_counter() + - md/raid1: stop mdx_raid1 thread when raid1 array run failed + - net: add atomic_long_t to net_device_stats fields + - mrp: introduce active flags to prevent UAF when applicant uninit + - ppp: associate skb with a device at tx + - bpf: Prevent decl_tag from being referenced in func_proto arg + - media: dvb-frontends: fix leak of memory fw + - media: dvbdev: adopts refcnt to avoid UAF + - media: dvb-usb: fix memory leak in dvb_usb_adapter_init() + - blk-mq: fix possible memleak when register 'hctx' failed + - regulator: core: fix use_count leakage when handling boot-on + - mmc: f-sdh30: Add quirks for broken timeout clock capability + - media: si470x: Fix use-after-free in si470x_int_in_callback() + - clk: st: Fix memory leak in st_of_quadfs_setup() + - hugetlbfs: fix null-ptr-deref in hugetlbfs_parse_param() + - drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() + - drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() + - orangefs: Fix kmemleak in orangefs_prepare_debugfs_help_string() + - orangefs: Fix kmemleak in orangefs_{kernel,client}_debug_init() + - ALSA/ASoC: hda: move/rename snd_hdac_ext_stop_streams to hdac_stream.c + - ALSA: hda: add snd_hdac_stop_streams() helper + - ASoC: Intel: Skylake: Fix driver hang during shutdown + - ASoC: mediatek: mt8173-rt5650-rt5514: fix refcount leak in + mt8173_rt5650_rt5514_dev_probe() + - ASoC: audio-graph-card: fix refcount leak of cpu_ep in + __graph_for_each_link() + - ASoC: rockchip: pdm: Add missing clk_disable_unprepare() in + rockchip_pdm_runtime_resume() + - ASoC: wm8994: Fix potential deadlock + - ASoC: rockchip: spdif: Add missing clk_disable_unprepare() in + rk_spdif_runtime_resume() + - ASoC: rt5670: Remove unbalanced pm_runtime_put() + - pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion + - pstore: Make sure CONFIG_PSTORE_PMSG selects CONFIG_RT_MUTEXES + - ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB + - ALSA: hda/hdmi: Add HP Device 0x8711 to force connect list + - usb: dwc3: core: defer probe on ulpi_read_id timeout + - HID: wacom: Ensure bootloader PID is usable in hidraw mode + - reiserfs: Add missing calls to reiserfs_security_free() + - iio: adc: ad_sigma_delta: do not use internal iio_dev lock + - iio: adc128s052: add proper .data members in adc128_of_match table + - regulator: core: fix deadlock on regulator enable + - gcov: add support for checksum field + - media: dvbdev: fix build warning due to comments + - media: dvbdev: fix refcnt bug + - cifs: fix oops during encryption + - nvme-pci: fix doorbell buffer value endianness + - ata: ahci: Fix PCS quirk application for suspend + - nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition + - objtool: Fix SEGFAULT + - powerpc/rtas: avoid device tree lookups in rtas_os_term() + - powerpc/rtas: avoid scheduling in rtas_os_term() + - HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint + - HID: plantronics: Additional PIDs for double volume key presses quirk + - hfsplus: fix bug causing custom uid and gid being unable to be assigned with + mount + - ovl: Use ovl mounter's fsuid and fsgid in ovl_link() + - ALSA: line6: correct midi status byte when receiving data from podxt + - ALSA: line6: fix stack overflow in line6_midi_transmit + - pnode: terminate at peers of source + - md: fix a crash in mempool_free + - mm, compaction: fix fast_isolate_around() to stay within boundaries + - f2fs: should put a page when checking the summary info + - mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING + - tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak + - tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak + - SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails + - net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO + - net/af_packet: make sure to pull mac header + - media: stv0288: use explicitly signed char + - soc: qcom: Select REMAP_MMIO for LLCC driver + - kest.pl: Fix grub2 menu handling for rebooting + - ktest.pl minconfig: Unset configs instead of just removing them + - mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K + - btrfs: fix resolving backrefs for inline extent followed by prealloc + - ARM: ux500: do not directly dereference __iomem + - arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength + - selftests: Use optional USERCFLAGS and USERLDFLAGS + - cpufreq: Init completion before kobject_init_and_add() + - binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf + - binfmt: Fix error return code in load_elf_fdpic_binary() + - dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort + - dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata + - dm thin: Use last transaction's pmd->root when commit failed + - dm thin: Fix UAF in run_timer_softirq() + - dm integrity: Fix UAF in dm_integrity_dtr() + - dm clone: Fix UAF in clone_dtr() + - dm cache: Fix UAF in destroy() + - dm cache: set needs_check flag after aborting metadata + - tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx' + - x86/microcode/intel: Do not retry microcode reloading on the APs + - tracing/hist: Fix wrong return value in parse_action_params() + - tracing: Fix infinite loop in tracing_read_pipe on overflowed + print_trace_line + - ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod + - media: dvb-core: Fix double free in dvb_register_device() + - cifs: fix confusing debug message + - cifs: fix missing display of three mount options + - md/bitmap: Fix bitmap chunk size overflow issues + - efi: Add iMac Pro 2017 to uefi skip cert quirk + - ipmi: fix long wait in unload when IPMI disconnect + - mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type() + - ima: Fix a potential NULL pointer access in ima_restore_measurement_list + - ipmi: fix use after free in _ipmi_destroy_user() + - PCI: Fix pci_device_is_present() for VFs by checking PF + - PCI/sysfs: Fix double free in error path + - crypto: n2 - add missing hash statesize + - iommu/amd: Fix ivrs_acpihid cmdline parsing code + - parisc: led: Fix potential null-ptr-deref in start_task() + - device_cgroup: Roll back to original exceptions after copy failure + - drm/connector: send hotplug uevent on connector cleanup + - drm/vmwgfx: Validate the box size for the snooped cursor + - ext4: add inode table check in __ext4_get_inode_loc to aovid possible + infinite loop + - ext4: fix undefined behavior in bit shift for ext4_check_flag_values + - ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode + - ext4: add helper to check quota inums + - ext4: fix reserved cluster accounting in __es_remove_extent() + - ext4: fix bug_on in __es_tree_search caused by bad boot loader inode + - ext4: init quota for 'old.inode' in 'ext4_rename' + - ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline + - ext4: fix corruption when online resizing a 1K bigalloc fs + - ext4: fix error code return to user-space in ext4_get_branch() + - ext4: avoid BUG_ON when creating xattrs + - ext4: fix inode leak in ext4_xattr_inode_create() on an error path + - ext4: initialize quota before expanding inode in setproject ioctl + - ext4: avoid unaccounted block allocation when expanding inode + - ext4: allocate extended attribute value in vmalloc area + - btrfs: replace strncpy() with strscpy() + - PM/devfreq: governor: Add a private governor_data for governor + - media: s5p-mfc: Fix to handle reference queue during finishing + - media: s5p-mfc: Clear workbit to handle error condition + - media: s5p-mfc: Fix in register read and write for H264 + - dm thin: resume even if in FAIL mode + - perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor + - perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged + data + - KVM: x86: optimize more exit handlers in vmx.c + - KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers + - KVM: VMX: Rename INTERRUPT_PENDING to INTERRUPT_WINDOW + - KVM: VMX: Rename NMI_PENDING to NMI_WINDOW + - KVM: VMX: Fix the spelling of CPU_BASED_USE_TSC_OFFSETTING + - KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1 + - ravb: Fix "failed to switch device to config mode" message during unbind + - ext4: goto right label 'failed_mount3a' + - ext4: correct inconsistent error msg in nojournal mode + - mm/highmem: Lift memcpy_[to|from]_page to core + - ext4: use memcpy_to_page() in pagecache_write() + - fs: ext4: initialize fsdata in pagecache_write() + - ext4: use kmemdup() to replace kmalloc + memcpy + - mbcache: don't reclaim used entries + - mbcache: add functions to delete entry if unused + - ext4: remove EA inode entry from mbcache on inode eviction + - ext4: unindent codeblock in ext4_xattr_block_set() + - ext4: fix race when reusing xattr blocks + - mbcache: automatically delete entries from cache on freeing + - ext4: fix deadlock due to mbcache entry corruption + - SUNRPC: ensure the matching upcall is in-flight upon downcall + - bpf: pull before calling skb_postpull_rcsum() + - nfsd: shut down the NFSv4 state objects before the filecache + - net: hns3: add interrupts re-initialization while doing VF FLR + - net: sched: fix memory leak in tcindex_set_parms + - qlcnic: prevent ->dcb use-after-free on qlcnic_dcb_enable() failure + - nfc: Fix potential resource leaks + - vhost: fix range used in translate_desc() + - net: amd-xgbe: add missed tasklet_kill + - net: phy: xgmiitorgmii: Fix refcount leak in xgmiitorgmii_probe + - RDMA/uverbs: Silence shiftTooManyBitsSigned warning + - RDMA/mlx5: Fix validation of max_rd_atomic caps for DC + - net: sched: atm: dont intepret cls results when asked to drop + - net: sched: cbq: dont intepret cls results when asked to drop + - perf tools: Fix resources leak in perf_data__open_dir() + - drivers/net/bonding/bond_3ad: return when there's no aggregator + - usb: rndis_host: Secure rndis_query check against int overflow + - drm/i915: unpin on error in intel_vgpu_shadow_mm_pin() + - caif: fix memory leak in cfctrl_linkup_request() + - udf: Fix extension of the last extent in the file + - ASoC: Intel: bytcr_rt5640: Add quirk for the Advantech MICA-071 tablet + - x86/bugs: Flush IBP in ib_prctl_set() + - nfsd: fix handling of readdir in v4root vs. mount upcall timeout + - riscv: uaccess: fix type of 0 variable on error in get_user() + - ext4: don't allow journal inode to have encrypt flag + - hfs/hfsplus: use WARN_ON for sanity check + - hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling + - mbcache: Avoid nesting of cache->c_list_lock under bit locks + - parisc: Align parisc MADV_XXX constants with all other architectures + - selftests: Fix kselftest O=objdir build from cluttering top level objdir + - selftests: set the BUILD variable to absolute path + - driver core: Fix bus_type.match() error handling in __driver_attach() + - net: sched: disallow noqueue for qdisc classes + - KVM: arm64: Fix S1PTW handling on RO memslots + - efi: tpm: Avoid READ_ONCE() for accessing the event log + - docs: Fix the docs build with Sphinx 6.0 + - perf auxtrace: Fix address filter duplicate symbol selection + - s390/kexec: fix ipl report address for kdump + - s390/percpu: add READ_ONCE() to arch_this_cpu_to_op_simple() + - net/ulp: prevent ULP without clone op from entering the LISTEN status + - ALSA: hda/hdmi: Add a HP device 0x8715 to force connect list + - cifs: Fix uninitialized memory read for smb311 posix symlink create + - drm/msm/adreno: Make adreno quirks not overwrite each other + - platform/x86: sony-laptop: Don't turn off 0x153 keyboard backlight during + probe + - ixgbe: fix pci device refcount leak + - ipv6: raw: Deduct extension header length in rawv6_push_pending_frames + - wifi: wilc1000: sdio: fix module autoloading + - usb: ulpi: defer ulpi_register on ulpi_read_id timeout + - jbd2: use the correct print format + - quota: Factor out setup of quota inode + - ext4: fix bug_on in __es_tree_search caused by bad quota inode + - ext4: lost matching-pair of trace in ext4_truncate + - ext4: fix use-after-free in ext4_orphan_cleanup + - ext4: fix uninititialized value in 'ext4_evict_inode' + - netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() + function. + - powerpc/imc-pmu: Fix use of mutex in IRQs disabled section + - x86/boot: Avoid using Intel mnemonics in AT&T syntax asm + - EDAC/device: Fix period calculation in edac_device_reset_delay_period() + - regulator: da9211: Use irq handler when ready + - tipc: improve throughput between nodes in netns + - tipc: eliminate checking netns if node established + - tipc: fix unexpected link reset due to discovery messages + - hvc/xen: lock console list traversal + - nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() + - net/sched: act_mpls: Fix warning during failed attribute validation + - net/mlx5: Rename ptp clock info + - net/mlx5: Fix ptp max frequency adjustment range + - iommu/mediatek-v1: Add error handle for mtk_iommu_probe + - iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() + - x86/resctrl: Use task_curr() instead of task_struct->on_cpu to prevent + unnecessary IPI + - x86/resctrl: Fix task CLOSID/RMID update race + - drm/virtio: Fix GEM handle creation UAF + - arm64: atomics: format whitespace consistently + - arm64: atomics: remove LL/SC trampolines + - arm64: cmpxchg_double*: hazard against entire exchange variable + - efi: fix NULL-deref in init error path + - mm: Always release pages to the buddy allocator in memblock_free_late(). + - Revert "usb: ulpi: defer ulpi_register on ulpi_read_id timeout" + - tipc: fix use-after-free in tipc_disc_rcv() + - tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started + - tipc: Add a missing case of TIPC_DIRECT_MSG type + - ocfs2: fix freeing uninitialized resource on ocfs2_dlm_shutdown + - tipc: call tipc_lxc_xmit without holding node_read_lock + - Linux 5.4.229 + * Focal update: v5.4.229 upstream stable release (LP: #2003914) // + CVE-2023-0266 was assigned for this issue. + - ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF + * Focal update: v5.4.229 upstream stable release (LP: #2003914) // + CVE-2022-41218 is assigned to those bugs above. + - media: dvb-core: Fix UAF due to refcount races at releasing + * Focal update: v5.4.228 upstream stable release (LP: #2003904) + - x86/smpboot: Move rcu_cpu_starting() earlier + - mm/hugetlb: fix races when looking up a CONT-PTE/PMD size hugetlb page + - block: unhash blkdev part inode when the part is deleted + - ASoC: ops: Check bounds for second channel in snd_soc_put_volsw_sx() + - pinctrl: meditatek: Startup with the IRQs disabled + - can: sja1000: fix size of OCR_MODE_MASK define + - can: mcba_usb: Fix termination command argument + - ASoC: ops: Correct bounds check for second channel on SX controls + - Linux 5.4.228 + * Focal update: v5.4.227 upstream stable release (LP: #2003901) + - arm64: dts: rockchip: keep I2S1 disabled for GPIO function on ROCK Pi 4 + series + - arm: dts: rockchip: fix node name for hym8563 rtc + - ARM: dts: rockchip: fix ir-receiver node names + - ARM: dts: rockchip: rk3188: fix lcdc1-rgb24 node name + - ARM: 9251/1: perf: Fix stacktraces for tracepoint events in THUMB2 kernels + - ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation + - ARM: dts: rockchip: disable arm_global_timer on rk3066 and rk3188 + - 9p/fd: Use P9_HDRSZ for header size + - regulator: slg51000: Wait after asserting CS pin + - ALSA: seq: Fix function prototype mismatch in snd_seq_expand_var_event + - btrfs: send: avoid unaligned encoded writes when attempting to clone range + - ASoC: soc-pcm: Add NULL check in BE reparenting + - regulator: twl6030: fix get status of twl6032 regulators + - fbcon: Use kzalloc() in fbcon_prepare_logo() + - 9p/xen: check logical size for buffer size + - net: usb: qmi_wwan: add u-blox 0x1342 composition + - mm/khugepaged: take the right locks for page table retraction + - mm/khugepaged: fix GUP-fast interaction by sending IPI + - mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths + - xen/netback: do some code cleanup + - xen/netback: don't call kfree_skb() with interrupts disabled + - Revert "net: dsa: b53: Fix valid setting for MDB entries" + - media: v4l2-dv-timings.c: fix too strict blanking sanity checks + - memcg: fix possible use-after-free in memcg_write_event_control() + - mm/gup: fix gup_pud_range() for dax + - KVM: s390: vsie: Fix the initialization of the epoch extension (epdx) field + - drm/shmem-helper: Remove errant put in error path + - HID: usbhid: Add ALWAYS_POLL quirk for some mice + - HID: hid-lg4ff: Add check for empty lbuf + - HID: core: fix shift-out-of-bounds in hid_report_raw_event + - can: af_can: fix NULL pointer dereference in can_rcv_filter + - ieee802154: cc2520: Fix error return code in cc2520_hw_init() + - ca8210: Fix crash by zero initializing data + - drm/bridge: ti-sn65dsi86: Fix output polarity setting bug + - gpio: amd8111: Fix PCI device reference count leak + - e1000e: Fix TX dispatch condition + - igb: Allocate MSI-X vector when testing + - af_unix: Get user_ns from in_skb in unix_diag_get_exact(). + - Bluetooth: 6LoWPAN: add missing hci_dev_put() in get_l2cap_conn() + - Bluetooth: Fix not cleanup led when bt_init fails + - net: dsa: ksz: Check return value + - selftests: rtnetlink: correct xfrm policy rule in kci_test_ipsec_offload + - mac802154: fix missing INIT_LIST_HEAD in ieee802154_if_add() + - net: encx24j600: Add parentheses to fix precedence + - net: encx24j600: Fix invalid logic in reading of MISTAT register + - xen-netfront: Fix NULL sring after live migration + - net: mvneta: Prevent out of bounds read in mvneta_config_rss() + - i40e: Fix not setting default xps_cpus after reset + - i40e: Fix for VF MAC address 0 + - i40e: Disallow ip4 and ip6 l4_4_bytes + - NFC: nci: Bounds check struct nfc_target arrays + - nvme initialize core quirks before calling nvme_init_subsystem + - net: stmmac: fix "snps,axi-config" node property parsing + - net: thunderx: Fix missing destroy_workqueue of nicvf_rx_mode_wq + - net: hisilicon: Fix potential use-after-free in hisi_femac_rx() + - net: hisilicon: Fix potential use-after-free in hix5hd2_rx() + - tipc: Fix potential OOB in tipc_link_proto_rcv() + - ipv4: Fix incorrect route flushing when source address is deleted + - ipv4: Fix incorrect route flushing when table ID 0 is used + - ethernet: aeroflex: fix potential skb leak in greth_init_rings() + - net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() + - ipv6: avoid use-after-free in ip6_fragment() + - net: mvneta: Fix an out of bounds check + - can: esd_usb: Allow REC and TEC to return to zero + - Linux 5.4.227 + * 5.15.0-58.64 breaks xen bridge networking (pvh domU) (LP: #2002889) // Focal + update: v5.4.227 upstream stable release (LP: #2003901) + - xen/netback: fix build warning + * Focal update: v5.4.226 upstream stable release (LP: #2003896) + - wifi: mac80211: fix memory free error when registering wiphy fail + - wifi: mac80211_hwsim: fix debugfs attribute ps with rc table support + - audit: fix undefined behavior in bit shift for AUDIT_BIT + - wifi: mac80211: Fix ack frame idr leak when mesh has no route + - spi: stm32: fix stm32_spi_prepare_mbr() that halves spi clk for every run + - drm: panel-orientation-quirks: Add quirk for Acer Switch V 10 (SW5-017) + - block, bfq: fix null pointer dereference in bfq_bio_bfqg() + - arm64/syscall: Include asm/ptrace.h in syscall_wrapper header. + - RISC-V: vdso: Do not add missing symbols to version section in linker script + - MIPS: pic32: treat port as signed integer + - af_key: Fix send_acquire race with pfkey_register + - ARM: dts: am335x-pcm-953: Define fixed regulators in root node + - ASoC: sgtl5000: Reset the CHIP_CLK_CTRL reg on remove + - regulator: core: fix kobject release warning and memory leak in + regulator_register() + - regulator: core: fix UAF in destroy_regulator() + - bus: sunxi-rsb: Support atomic transfers + - tee: optee: fix possible memory leak in optee_register_device() + - ARM: dts: at91: sam9g20ek: enable udc vbus gpio pinctrl + - net: liquidio: simplify if expression + - nfc/nci: fix race with opening and closing + - net: pch_gbe: fix potential memleak in pch_gbe_tx_queue() + - 9p/fd: fix issue of list_del corruption in p9_fd_cancel() + - ARM: mxs: fix memory leak in mxs_machine_init() + - net/mlx4: Check retval of mlx4_bitmap_init + - net/qla3xxx: fix potential memleak in ql3xxx_send() + - net: pch_gbe: fix pci device refcount leak while module exiting + - nfp: add port from netdev validation for EEPROM access + - Drivers: hv: vmbus: fix double free in the error path of + vmbus_add_channel_work() + - Drivers: hv: vmbus: fix possible memory leak in vmbus_device_register() + - net/mlx5: Fix FW tracer timestamp calculation + - tipc: set con sock in tipc_conn_alloc + - tipc: add an extra conn_get in tipc_conn_alloc + - tipc: check skb_linearize() return value in tipc_disc_rcv() + - xfrm: Fix ignored return value in xfrm6_init() + - NFC: nci: fix memory leak in nci_rx_data_packet() + - regulator: twl6030: re-add TWL6032_SUBCLASS + - bnx2x: fix pci device refcount leak in bnx2x_vf_is_pcie_pending() + - dccp/tcp: Reset saddr on failure after inet6?_hash_connect(). + - s390/dasd: fix no record found for raw_track_access + - nfc: st-nci: fix incorrect validating logic in EVT_TRANSACTION + - nfc: st-nci: fix memory leaks in EVT_TRANSACTION + - net: thunderx: Fix the ACPI memory leak + - s390/crashdump: fix TOD programmable field size + - lib/vdso: use "grep -E" instead of "egrep" + - usb: dwc3: exynos: Fix remove() function + - arm64: dts: rockchip: lower rk3399-puma-haikou SD controller clock frequency + - iio: light: apds9960: fix wrong register for gesture gain + - iio: core: Fix entry not deleted when iio_register_sw_trigger_type() fails + - init/Kconfig: fix CC_HAS_ASM_GOTO_TIED_OUTPUT test with dash + - nios2: add FORCE for vmlinuz.gz + - iio: ms5611: Simplify IO callback parameters + - iio: pressure: ms5611: fixed value compensation bug + - ceph: do not update snapshot context when there is no new snapshot + - ceph: avoid putting the realm twice when decoding snaps fails + - firmware: google: Release devices before unregistering the bus + - firmware: coreboot: Register bus in module init + - nilfs2: fix nilfs_sufile_mark_dirty() not set segment usage as dirty + - gcov: clang: fix the buffer overflow issue + - Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode + - ASoC: Intel: bytcht_es8316: Add quirk for the Nanote UMPC-01 + - serial: 8250: 8250_omap: Avoid RS485 RTS glitch on ->set_termios() + - xen/platform-pci: add missing free_irq() in error path + - platform/x86: asus-wmi: add missing pci_dev_put() in asus_wmi_set_xusb2pr() + - platform/x86: acer-wmi: Enable SW_TABLET_MODE on Switch V 10 (SW5-017) + - platform/x86: hp-wmi: Ignore Smart Experience App event + - [Config] updateconfigs for INET_TABLE_PERTURB_ORDER + - tcp: configurable source port perturb table size + - net: usb: qmi_wwan: add Telit 0x103a composition + - dm integrity: flush the journal on suspend + - binder: avoid potential data leakage when copying txn + - binder: read pre-translated fds from sender buffer + - binder: defer copies of pre-patched txn data + - binder: fix pointer cast warning + - binder: Address corner cases in deferred copy and fixup + - binder: Gracefully handle BINDER_TYPE_FDA objects with num_fds=0 + - btrfs: free btrfs_path before copying root refs to userspace + - btrfs: free btrfs_path before copying fspath to userspace + - btrfs: free btrfs_path before copying subvol info to userspace + - btrfs: sysfs: normalize the error handling branch in btrfs_init_sysfs() + - drm/amd/dc/dce120: Fix audio register mapping, stop triggering KASAN + - drm/amdgpu: always register an MMU notifier for userptr + - fuse: lock inode unconditionally in fuse_fallocate() + - btrfs: free btrfs_path before copying inodes to userspace + - spi: spi-imx: Fix spi_bus_clk if requested clock is higher than input clock + - btrfs: move QUOTA_ENABLED check to rescan_should_stop from + btrfs_qgroup_rescan_worker + - drm/amdgpu: update drm_display_info correctly when the edid is read + - drm/amdgpu: Partially revert "drm/amdgpu: update drm_display_info correctly + when the edid is read" + - btrfs: qgroup: fix sleep from invalid context bug in btrfs_qgroup_inherit() + - iio: health: afe4403: Fix oob read in afe4403_read_raw + - iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw + - iio: light: rpr0521: add missing Kconfig dependencies + - scripts/faddr2line: Fix regression in name resolution on ppc64le + - hwmon: (i5500_temp) fix missing pci_disable_device() + - hwmon: (ibmpex) Fix possible UAF when ibmpex_register_bmc() fails + - of: property: decrement node refcount in of_fwnode_get_reference_args() + - net/mlx5: Fix uninitialized variable bug in outlen_write() + - net/mlx5e: Fix use-after-free when reverting termination table + - can: sja1000_isa: sja1000_isa_probe(): add missing free_sja1000dev() + - can: cc770: cc770_isa_probe(): add missing free_cc770dev() + - qlcnic: fix sleep-in-atomic-context bugs caused by msleep + - wifi: cfg80211: fix buffer overflow in elem comparison + - net: phy: fix null-ptr-deref while probe() failed + - net: net_netdev: Fix error handling in ntb_netdev_init_module() + - net/9p: Fix a potential socket leak in p9_socket_open + - net: ethernet: nixge: fix NULL dereference + - dsa: lan9303: Correct stat name + - net: hsr: Fix potential use-after-free + - afs: Fix fileserver probe RTT handling + - net: tun: Fix use-after-free in tun_detach() + - packet: do not set TP_STATUS_CSUM_VALID on CHECKSUM_COMPLETE + - sctp: fix memory leak in sctp_stream_outq_migrate() + - net: ethernet: renesas: ravb: Fix promiscuous mode after system resumed + - hwmon: (coretemp) Check for null before removing sysfs attrs + - hwmon: (coretemp) fix pci device refcount leak in nv1a_ram_new() + - net/mlx5: DR, Fix uninitialized var warning + - error-injection: Add prompt for function error injection + - tools/vm/slabinfo-gnuplot: use "grep -E" instead of "egrep" + - nilfs2: fix NULL pointer dereference in nilfs_palloc_commit_free_entry() + - x86/bugs: Make sure MSR_SPEC_CTRL is updated properly upon resume from S3 + - pinctrl: intel: Save and restore pins in "direct IRQ" mode + - mmc: mmc_test: Fix removal of debugfs file + - mmc: core: Fix ambiguous TRIM and DISCARD arg + - mmc: sdhci-esdhc-imx: correct CQHCI exit halt state check + - mmc: sdhci-sprd: Fix no reset data and command after voltage switch + - tracing: Free buffers when a used dynamic event is removed + - arm64: Fix panic() when Spectre-v2 causes Spectre-BHB to re-allocate KVM + vectors + - arm64: errata: Fix KVM Spectre-v2 mitigation selection for Cortex-A57/A72 + - mm: Fix '.data.once' orphan section warning + - ASoC: ops: Fix bounds check for _sx controls + - pinctrl: single: Fix potential division by zero + - iommu/vt-d: Fix PCI device refcount leak in dmar_dev_scope_init() + - parisc: Increase size of gcc stack frame check + - xtensa: increase size of gcc stack frame check + - parisc: Increase FRAME_WARN to 2048 bytes on parisc + - Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is + enabled + - selftests: net: add delete nexthop route warning test + - selftests: net: fix nexthop warning cleanup double ip typo + - ipv4: Handle attempt to delete multipath route when fib_info contains an nh + reference + - ipv4: Fix route deletion when nexthop info is not specified + - tracing/ring-buffer: Have polling block on watermark + - nvme: restrict management ioctls to admin + - nvme: ensure subsystem reset is single threaded + - x86/tsx: Add a feature bit for TSX control MSR support + - x86/pm: Add enumeration check before spec MSRs save/restore setup + - x86/ioremap: Fix page aligned size calculation in __ioremap_caller() + - Revert "clocksource/drivers/riscv: Events are stopped during CPU suspend" + - char: tpm: Protect tpm_pm_suspend with locks + - mmc: sdhci: use FIELD_GET for preset value bit masks + - mmc: sdhci: Fix voltage switch delay + - proc: avoid integer type confusion in get_proc_long + - proc: proc_skip_spaces() shouldn't think it is working on C strings + - v4l2: don't fall back to follow_pfn() if pin_user_pages_fast() fails + - ipc/sem: Fix dangling sem_array access in semtimedop race + - Linux 5.4.226 + * CVE-2022-4139 + - drm/i915: fix TLB invalidation for Gen12 video and compute engines + * Focal update: v5.4.225 upstream stable release (LP: #2002347) + - xfs: preserve rmapbt swapext block reservation from freed blocks + - xfs: rename xfs_bmap_is_real_extent to is_written_extent + - xfs: redesign the reflink remap loop to fix blkres depletion crash + - xfs: use MMAPLOCK around filemap_map_pages() + - xfs: preserve inode versioning across remounts + - xfs: drain the buf delwri queue before xfsaild idles + - phy: stm32: fix an error code in probe + - wifi: cfg80211: silence a sparse RCU warning + - wifi: cfg80211: fix memory leak in query_regdb_file() + - bpf, sockmap: Fix the sk->sk_forward_alloc warning of sk_stream_kill_queues + - HID: hyperv: fix possible memory leak in mousevsc_probe() + - net: gso: fix panic on frag_list with mixed head alloc types + - net: tun: Fix memory leaks of napi_get_frags + - bnxt_en: Fix possible crash in bnxt_hwrm_set_coal() + - bnxt_en: fix potentially incorrect return value for ndo_rx_flow_steer + - net: fman: Unregister ethernet device on removal + - capabilities: fix undefined behavior in bit shift for CAP_TO_MASK + - net: lapbether: fix issue of dev reference count leakage in + lapbeth_device_event() + - hamradio: fix issue of dev reference count leakage in bpq_device_event() + - drm/vc4: Fix missing platform_unregister_drivers() call in + vc4_drm_register() + - ipv6: addrlabel: fix infoleak when sending struct ifaddrlblmsg to network + - can: af_can: fix NULL pointer dereference in can_rx_register() + - tipc: fix the msg->req tlv len check in + tipc_nl_compat_name_table_dump_header + - dmaengine: pxa_dma: use platform_get_irq_optional + - dmaengine: mv_xor_v2: Fix a resource leak in mv_xor_v2_remove() + - drivers: net: xgene: disable napi when register irq failed in + xgene_enet_open() + - perf stat: Fix printing os->prefix in CSV metrics output + - net: nixge: disable napi when enable interrupts failed in nixge_open() + - net/mlx5: Allow async trigger completion execution on single CPU systems + - net: cpsw: disable napi in cpsw_ndo_open() + - net: cxgb3_main: disable napi when bind qsets failed in cxgb_up() + - cxgb4vf: shut down the adapter when t4vf_update_port_info() failed in + cxgb4vf_open() + - ethernet: s2io: disable napi when start nic failed in s2io_card_up() + - net: mv643xx_eth: disable napi when init rxq or txq failed in + mv643xx_eth_open() + - ethernet: tundra: free irq when alloc ring failed in tsi108_open() + - net: macvlan: fix memory leaks of macvlan_common_newlink + - riscv: process: fix kernel info leakage + - arm64: efi: Fix handling of misaligned runtime regions and drop warning + - MIPS: jump_label: Fix compat branch range check + - mmc: cqhci: Provide helper for resetting both SDHCI and CQHCI + - mmc: sdhci-of-arasan: Fix SDHCI_RESET_ALL for CQHCI + - mmc: sdhci-tegra: Fix SDHCI_RESET_ALL for CQHCI + - ALSA: hda/ca0132: add quirk for EVGA Z390 DARK + - ALSA: hda: fix potential memleak in 'add_widget_node' + - ALSA: usb-audio: Add quirk entry for M-Audio Micro + - ALSA: usb-audio: Add DSD support for Accuphase DAC-60 + - vmlinux.lds.h: Fix placement of '.data..decrypted' section + - nilfs2: fix deadlock in nilfs_count_free_blocks() + - nilfs2: fix use-after-free bug of ns_writer on remount + - drm/i915/dmabuf: fix sg_table handling in map_dma_buf + - btrfs: selftests: fix wrong error check in btrfs_free_dummy_root() + - udf: Fix a slab-out-of-bounds write bug in udf_find_entry() + - can: j1939: j1939_send_one(): fix missing CAN header initialization + - cert host tools: Stop complaining about deprecated OpenSSL functions + - dmaengine: at_hdmac: Fix at_lli struct definition + - dmaengine: at_hdmac: Don't start transactions at tx_submit level + - dmaengine: at_hdmac: Fix completion of unissued descriptor in case of errors + - dmaengine: at_hdmac: Don't allow CPU to reorder channel enable + - dmaengine: at_hdmac: Fix impossible condition + - dmaengine: at_hdmac: Check return code of dma_async_device_register + - net: tun: call napi_schedule_prep() to ensure we own a napi + - x86/cpu: Restore AMD's DE_CFG MSR after resume + - ASoC: wm5102: Revert "ASoC: wm5102: Fix PM disable depth imbalance in + wm5102_probe" + - ASoC: wm5110: Revert "ASoC: wm5110: Fix PM disable depth imbalance in + wm5110_probe" + - ASoC: wm8997: Revert "ASoC: wm8997: Fix PM disable depth imbalance in + wm8997_probe" + - ASoC: wm8962: Add an event handler for TEMP_HP and TEMP_SPK + - spi: intel: Fix the offset to get the 64K erase opcode + - ASoC: codecs: jz4725b: add missed Line In power control bit + - ASoC: codecs: jz4725b: fix reported volume for Master ctl + - ASoC: codecs: jz4725b: use right control for Capture Volume + - ASoC: codecs: jz4725b: fix capture selector naming + - selftests/futex: fix build for clang + - selftests/intel_pstate: fix build for ARCH=x86_64 + - NFSv4: Retry LOCK on OLD_STATEID during delegation return + - i2c: i801: add lis3lv02d's I2C address for Vostro 5568 + - drm/imx: imx-tve: Fix return type of imx_tve_connector_mode_valid + - btrfs: remove pointless and double ulist frees in error paths of qgroup + tests + - ASoC: codecs: jz4725b: Fix spelling mistake "Sourc" -> "Source", "Routee" -> + "Route" + - spi: stm32: Print summary 'callbacks suppressed' message + - ASoC: core: Fix use-after-free in snd_soc_exit() + - serial: 8250_omap: remove wait loop from Errata i202 workaround + - serial: 8250: omap: Fix unpaired pm_runtime_put_sync() in omap8250_remove() + - serial: 8250: omap: Flush PM QOS work on remove + - serial: imx: Add missing .thaw_noirq hook + - tty: n_gsm: fix sleep-in-atomic-context bug in gsm_control_send + - ASoC: soc-utils: Remove __exit for snd_soc_util_exit() + - block: sed-opal: kmalloc the cmd/resp buffers + - siox: fix possible memory leak in siox_device_add() + - parport_pc: Avoid FIFO port location truncation + - pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map + - arm64: dts: imx8mm: Fix NAND controller size-cells + - arm64: dts: imx8mn: Fix NAND controller size-cells + - ata: libata-transport: fix double ata_host_put() in ata_tport_add() + - net: bgmac: Drop free_netdev() from bgmac_enet_remove() + - mISDN: fix possible memory leak in mISDN_dsp_element_register() + - net: liquidio: release resources when liquidio driver open failed + - mISDN: fix misuse of put_device() in mISDN_register_device() + - net: macvlan: Use built-in RCU list checking + - net: caif: fix double disconnect client in chnl_net_open() + - bnxt_en: Remove debugfs when pci_register_driver failed + - xen/pcpu: fix possible memory leak in register_pcpu() + - drbd: use after free in drbd_create_device() + - platform/x86/intel: pmc: Don't unconditionally attach Intel PMC when + virtualized + - net/x25: Fix skb leak in x25_lapb_receive_frame() + - cifs: Fix wrong return value checking when GETFLAGS + - net: thunderbolt: Fix error handling in tbnet_init() + - cifs: add check for returning value of SMB2_set_info_init + - ftrace: Fix the possible incorrect kernel message + - ftrace: Optimize the allocation for mcount entries + - ftrace: Fix null pointer dereference in ftrace_add_mod() + - ring_buffer: Do not deactivate non-existant pages + - ALSA: usb-audio: Drop snd_BUG_ON() from snd_usbmidi_output_open() + - Revert "usb: dwc3: disable USB core PHY management" + - slimbus: stream: correct presence rate frequencies + - speakup: fix a segfault caused by switching consoles + - USB: serial: option: add Sierra Wireless EM9191 + - USB: serial: option: remove old LARA-R6 PID + - USB: serial: option: add u-blox LARA-R6 00B modem + - USB: serial: option: add u-blox LARA-L6 modem + - USB: serial: option: add Fibocom FM160 0x0111 composition + - usb: add NO_LPM quirk for Realforce 87U Keyboard + - usb: chipidea: fix deadlock in ci_otg_del_timer + - iio: adc: at91_adc: fix possible memory leak in at91_adc_allocate_trigger() + - iio: trigger: sysfs: fix possible memory leak in iio_sysfs_trig_init() + - iio: pressure: ms5611: changed hardcoded SPI speed to value limited + - dm ioctl: fix misbehavior if list_versions races with module loading + - serial: 8250: Fall back to non-DMA Rx if IIR_RDI occurs + - serial: 8250_lpss: Configure DMA also w/o DMA filter + - Input: iforce - invert valid length check when fetching device IDs + - scsi: zfcp: Fix double free of FSF request when qdio send fails + - mmc: core: properly select voltage range without power cycle + - mmc: sdhci-pci-o2micro: fix card detect fail issue caused by CD# debounce + timeout + - mmc: sdhci-pci: Fix possible memory leak caused by missing pci_dev_put() + - docs: update mediator contact information in CoC doc + - misc/vmw_vmci: fix an infoleak in vmci_host_do_receive_datagram() + - serial: 8250: Flush DMA Rx on RLSI + - ring-buffer: Include dropped pages in counting dirty patches + - scsi: target: tcm_loop: Fix possible name leak in tcm_loop_setup_hba_bus() + - kprobes: Skip clearing aggrprobe's post_handler in kprobe-on-ftrace case + - Input: i8042 - fix leaking of platform device on module removal + - macvlan: enforce a consistent minimal mtu + - tcp: cdg: allow tcp_cdg_release() to be called multiple times + - kcm: avoid potential race in kcm_tx_work + - bpf, test_run: Fix alignment problem in bpf_prog_test_run_skb() + - kcm: close race conditions on sk_receive_queue + - 9p: trans_fd/p9_conn_cancel: drop client lock earlier + - gfs2: Check sb_bsize_shift after reading superblock + - gfs2: Switch from strlcpy to strscpy + - 9p/trans_fd: always use O_NONBLOCK read/write + - mm: fs: initialize fsdata passed to write_begin/write_end interface + - ntfs: fix use-after-free in ntfs_attr_find() + - ntfs: fix out-of-bounds read in ntfs_attr_find() + - ntfs: check overflow when iterating ATTR_RECORDs + - Linux 5.4.225 + * CVE-2022-47520 + - wifi: wilc1000: validate pairwise and authentication suite offsets + * CVE-2022-3545 + - nfp: fix use-after-free in area_cache_get() + + -- Joseph Salisbury Thu, 09 Feb 2023 13:55:27 -0500 + +linux-oracle (5.4.0-1093.102) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1093.102 -proposed tracker (LP: #2003480) + + * Focal update: v5.4.221 upstream stable release (LP: #1997993) + - [Config] oracle: updateconfigs for ARM64_ERRATUM_1742098 + + [ Ubuntu: 5.4.0-139.156 ] + + * focal/linux: 5.4.0-139.156 -proposed tracker (LP: #2003486) + * Revoke & rotate to new signing key (LP: #2002812) + - [Packaging] Revoke and rotate to new signing key + + [ Ubuntu: 5.4.0-138.155 ] + + * focal/linux: 5.4.0-138.155 -proposed tracker (LP: #2001845) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Focal update: v5.4.224 upstream stable release (LP: #1999273) + - RDMA/cma: Use output interface for net_dev check + - IB/hfi1: Correctly move list in sc_disable() + - NFSv4.1: Handle RECLAIM_COMPLETE trunking errors + - NFSv4.1: We must always send RECLAIM_COMPLETE after a reboot + - nfs4: Fix kmemleak when allocate slot failed + - net: dsa: Fix possible memory leaks in dsa_loop_init() + - RDMA/core: Fix null-ptr-deref in ib_core_cleanup() + - RDMA/qedr: clean up work queue on failure in qedr_alloc_resources() + - nfc: s3fwrn5: Fix potential memory leak in s3fwrn5_nci_send() + - nfc: nfcmrvl: Fix potential memory leak in nfcmrvl_i2c_nci_send() + - net: fec: fix improper use of NETDEV_TX_BUSY + - ata: pata_legacy: fix pdc20230_set_piomode() + - net: sched: Fix use after free in red_enqueue() + - net: tun: fix bugs for oversize packet when napi frags enabled + - netfilter: nf_tables: release flow rule object from commit path + - ipvs: use explicitly signed chars + - ipvs: fix WARNING in __ip_vs_cleanup_batch() + - ipvs: fix WARNING in ip_vs_app_net_cleanup() + - rose: Fix NULL pointer dereference in rose_send_frame() + - mISDN: fix possible memory leak in mISDN_register_device() + - isdn: mISDN: netjet: fix wrong check of device registration + - btrfs: fix inode list leak during backref walking at resolve_indirect_refs() + - btrfs: fix inode list leak during backref walking at find_parent_nodes() + - btrfs: fix ulist leaks in error paths of qgroup self tests + - Bluetooth: L2CAP: fix use-after-free in l2cap_conn_del() + - net: mdio: fix undefined behavior in bit shift for __mdiobus_register + - net, neigh: Fix null-ptr-deref in neigh_table_clear() + - ipv6: fix WARNING in ip6_route_net_exit_late() + - media: s5p_cec: limit msg.len to CEC_MAX_MSG_SIZE + - media: cros-ec-cec: limit msg.len to CEC_MAX_MSG_SIZE + - media: dvb-frontends/drxk: initialize err to 0 + - media: meson: vdec: fix possible refcount leak in vdec_probe() + - scsi: core: Restrict legal sdev_state transitions via sysfs + - HID: saitek: add madcatz variant of MMO7 mouse device ID + - i2c: xiic: Add platform module alias + - xfs: don't fail verifier on empty attr3 leaf block + - xfs: use ordered buffers to initialize dquot buffers during quotacheck + - xfs: gut error handling in xfs_trans_unreserve_and_mod_sb() + - xfs: group quota should return EDQUOT when prj quota enabled + - xfs: don't fail unwritten extent conversion on writeback due to edquot + - xfs: Add the missed xfs_perag_put() for xfs_ifree_cluster() + - Bluetooth: L2CAP: Fix attempting to access uninitialized memory + - block, bfq: protect 'bfqd->queued' by 'bfqd->lock' + - binder: fix UAF of alloc->vma in race with munmap() + - btrfs: fix type of parameter generation in btrfs_get_dentry + - tcp/udp: Make early_demux back namespacified. + - kprobe: reverse kp->flags when arm_kprobe failed + - tools/nolibc/string: Fix memcmp() implementation + - tracing/histogram: Update document for KEYS_MAX size + - capabilities: fix potential memleak on error path from vfs_getxattr_alloc() + - fuse: add file_modified() to fallocate + - efi: random: reduce seed size to 32 bytes + - perf/x86/intel: Fix pebs event constraints for ICL + - perf/x86/intel: Add Cooper Lake stepping to isolation_ucodes[] + - ALSA: usb-audio: Add quirks for MacroSilicon MS2100/MS2106 devices + - parisc: Make 8250_gsc driver dependend on CONFIG_PARISC + - parisc: Export iosapic_serial_irq() symbol for serial port driver + - parisc: Avoid printing the hardware path twice + - ext4: fix warning in 'ext4_da_release_space' + - ext4: fix BUG_ON() when directory entry has invalid rec_len + - KVM: x86: Mask off reserved bits in CPUID.8000001AH + - KVM: x86: Mask off reserved bits in CPUID.80000008H + - KVM: x86: emulator: em_sysexit should update ctxt->mode + - KVM: x86: emulator: introduce emulator_recalc_and_set_mode + - KVM: x86: emulator: update the emulation mode after CR0 write + - mtd: rawnand: gpmi: Set WAIT_FOR_READY timeout based on program/erase times + - drm/rockchip: dsi: Force synchronous probe + - drm/i915/sdvo: Filter out invalid outputs more sensibly + - drm/i915/sdvo: Setup DDC fully before output init + - wifi: brcmfmac: Fix potential buffer overflow in brcmf_fweh_event_worker() + - ipc: remove memcg accounting for sops objects in do_semtimedop() + - Linux 5.4.224 + * Focal update: v5.4.223 upstream stable release (LP: #1999179) + - can: j1939: transport: j1939_session_skb_drop_old(): + spin_unlock_irqrestore() before kfree_skb() + - can: kvaser_usb: Fix possible completions during init_completion + - ALSA: Use del_timer_sync() before freeing timer + - ALSA: au88x0: use explicitly signed char + - USB: add RESET_RESUME quirk for NVIDIA Jetson devices in RCM + - usb: dwc3: gadget: Stop processing more requests on IMI + - usb: dwc3: gadget: Don't set IMI for no_interrupt + - usb: bdc: change state when port disconnected + - usb: xhci: add XHCI_SPURIOUS_SUCCESS to ASM1042 despite being a V0.96 + controller + - mtd: rawnand: marvell: Use correct logic for nand-keep-config + - xhci: Remove device endpoints from bandwidth list when freeing the device + - tools: iio: iio_utils: fix digit calculation + - iio: light: tsl2583: Fix module unloading + - fbdev: smscufx: Fix several use-after-free bugs + - mac802154: Fix LQI recording + - drm/msm/dsi: fix memory corruption with too many bridges + - drm/msm/hdmi: fix memory corruption with too many bridges + - mmc: core: Fix kernel panic when remove non-standard SDIO card + - kernfs: fix use-after-free in __kernfs_remove + - perf auxtrace: Fix address filter symbol name match for modules + - s390/futex: add missing EX_TABLE entry to __futex_atomic_op() + - s390/pci: add missing EX_TABLE entries to + __pcistg_mio_inuser()/__pcilg_mio_inuser() + - xfs: finish dfops on every insert range shift iteration + - xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush + - xfs: force the log after remapping a synchronous-writes file + - Xen/gntdev: don't ignore kernel unmapping error + - xen/gntdev: Prevent leaking grants + - mm,hugetlb: take hugetlb_lock before decrementing h->resv_huge_pages + - net: ieee802154: fix error return code in dgram_bind() + - media: v4l2: Fix v4l2_i2c_subdev_set_name function documentation + - drm/msm: Fix return type of mdp4_lvds_connector_mode_valid + - arc: iounmap() arg is volatile + - ALSA: ac97: fix possible memory leak in snd_ac97_dev_register() + - tipc: fix a null-ptr-deref in tipc_topsrv_accept + - net: netsec: fix error handling in netsec_register_mdio() + - x86/unwind/orc: Fix unreliable stack dump with gcov + - amd-xgbe: fix the SFP compliance codes check for DAC cables + - amd-xgbe: add the bit rate quirk for Molex cables + - kcm: annotate data-races around kcm->rx_psock + - kcm: annotate data-races around kcm->rx_wait + - net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed + - net: lantiq_etop: don't free skb when returning NETDEV_TX_BUSY + - tcp: fix indefinite deferral of RTO with SACK reneging + - can: mscan: mpc5xxx: mpc5xxx_can_probe(): add missing put_clock() in error + path + - PM: hibernate: Allow hybrid sleep to work with s2idle + - media: vivid: s_fbuf: add more sanity checks + - media: vivid: dev->bitmap_cap wasn't freed in all cases + - media: v4l2-dv-timings: add sanity checks for blanking values + - media: videodev2.h: V4L2_DV_BT_BLANKING_HEIGHT should check 'interlaced' + - i40e: Fix ethtool rx-flow-hash setting for X722 + - i40e: Fix VF hang when reset is triggered on another VF + - i40e: Fix flow-type by setting GL_HASH_INSET registers + - net: ksz884x: fix missing pci_disable_device() on error in pcidev_init() + - PM: domains: Fix handling of unavailable/disabled idle states + - ALSA: aoa: i2sbus: fix possible memory leak in i2sbus_add_dev() + - ALSA: aoa: Fix I2S device accounting + - openvswitch: switch from WARN to pr_warn + - net: ehea: fix possible memory leak in ehea_register_port() + - nh: fix scope used to find saddr when adding non gw nh + - net/mlx5e: Do not increment ESN when updating IPsec ESN state + - net/mlx5: Fix possible use-after-free in async command interface + - net: enetc: survive memory pressure without crashing + - can: rcar_canfd: rcar_canfd_handle_global_receive(): fix IRQ storm on global + FIFO receive + - Linux 5.4.223 + * Focal update: v5.4.222 upstream stable release (LP: #1997994) + - once: fix section mismatch on clang builds + - Linux 5.4.222 + * Focal update: v5.4.221 upstream stable release (LP: #1997993) + - xfs: open code insert range extent split helper + - xfs: rework insert range into an atomic operation + - xfs: rework collapse range into an atomic operation + - xfs: add a function to deal with corrupt buffers post-verifiers + - xfs: xfs_buf_corruption_error should take __this_address + - xfs: fix buffer corruption reporting when xfs_dir3_free_header_check fails + - xfs: check owner of dir3 data blocks + - xfs: check owner of dir3 blocks + - xfs: Use scnprintf() for avoiding potential buffer overflow + - xfs: remove the xfs_disk_dquot_t and xfs_dquot_t + - xfs: remove the xfs_dq_logitem_t typedef + - xfs: remove the xfs_qoff_logitem_t typedef + - xfs: Replace function declaration by actual definition + - xfs: factor out quotaoff intent AIL removal and memory free + - xfs: fix unmount hang and memory leak on shutdown during quotaoff + - xfs: preserve default grace interval during quotacheck + - xfs: Lower CIL flush limit for large logs + - xfs: Throttle commits on delayed background CIL push + - xfs: factor common AIL item deletion code + - xfs: tail updates only need to occur when LSN changes + - xfs: don't write a corrupt unmount record to force summary counter recalc + - xfs: trylock underlying buffer on dquot flush + - xfs: factor out a new xfs_log_force_inode helper + - xfs: reflink should force the log out if mounted with wsync + - xfs: move inode flush to the sync workqueue + - xfs: fix use-after-free on CIL context on shutdown + - ocfs2: clear dinode links count in case of error + - ocfs2: fix BUG when iput after ocfs2_mknod fails + - x86/microcode/AMD: Apply the patch early on every logical thread + - hwmon/coretemp: Handle large core ID value + - ata: ahci-imx: Fix MODULE_ALIAS + - ata: ahci: Match EM_MAX_SLOTS with SATA_PMP_MAX_PORTS + - KVM: arm64: vgic: Fix exit condition in scan_its_table() + - media: venus: dec: Handle the case where find_format fails + - [Config] updateconfigs for ARM64_ERRATUM_1742098 + - arm64: errata: Remove AES hwcap for COMPAT tasks + - r8152: add PID for the Lenovo OneLink+ Dock + - btrfs: fix processing of delayed data refs during backref walking + - btrfs: fix processing of delayed tree block refs during backref walking + - ACPI: extlog: Handle multiple records + - tipc: Fix recognition of trial period + - tipc: fix an information leak in tipc_topsrv_kern_subscr + - HID: magicmouse: Do not set BTN_MOUSE on double report + - net/atm: fix proc_mpc_write incorrect return value + - net: phy: dp83867: Extend RX strap quirk for SGMII mode + - net: sched: cake: fix null pointer access issue when cake_init() fails + - net: hns: fix possible memory leak in hnae_ae_register() + - iommu/vt-d: Clean up si_domain in the init_dmars() error path + - arm64: topology: move store_cpu_topology() to shared code + - riscv: topology: fix default topology reporting + - ACPI: video: Force backlight native for more TongFang devices + - Makefile.debug: re-enable debug info for .S files + - hv_netvsc: Fix race between VF offering and VF association message from host + - mm: /proc/pid/smaps_rollup: fix no vma's null-deref + - Linux 5.4.221 + * Focal update: v5.4.220 upstream stable release (LP: #1996812) + - ALSA: oss: Fix potential deadlock at unregistration + - ALSA: rawmidi: Drop register_mutex in snd_rawmidi_free() + - ALSA: usb-audio: Fix potential memory leaks + - ALSA: usb-audio: Fix NULL dererence at error path + - ALSA: hda/realtek: remove ALC289_FIXUP_DUAL_SPK for Dell 5530 + - ALSA: hda/realtek: Correct pin configs for ASUS G533Z + - ALSA: hda/realtek: Add quirk for ASUS GV601R laptop + - ALSA: hda/realtek: Add Intel Reference SSID to support headset keys + - mtd: rawnand: atmel: Unmap streaming DMA mappings + - cifs: destage dirty pages before re-reading them for cache=none + - cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message + - iio: dac: ad5593r: Fix i2c read protocol requirements + - iio: pressure: dps310: Refactor startup procedure + - iio: pressure: dps310: Reset chip after timeout + - usb: add quirks for Lenovo OneLink+ Dock + - can: kvaser_usb: Fix use of uninitialized completion + - can: kvaser_usb_leaf: Fix overread with an invalid command + - can: kvaser_usb_leaf: Fix TX queue out of sync after restart + - can: kvaser_usb_leaf: Fix CAN state after restart + - mmc: sdhci-sprd: Fix minimum clock limit + - fs: dlm: fix race between test_bit() and queue_work() + - fs: dlm: handle -EBUSY first in lock arg validation + - HID: multitouch: Add memory barriers + - quota: Check next/prev free block number after reading from quota file + - ASoC: wcd9335: fix order of Slimbus unprepare/disable + - regulator: qcom_rpm: Fix circular deferral regression + - RISC-V: Make port I/O string accessors actually work + - parisc: fbdev/stifb: Align graphics memory size to 4MB + - riscv: Allow PROT_WRITE-only mmap() + - riscv: Pass -mno-relax only on lld < 15.0.0 + - UM: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge + - powerpc/boot: Explicitly disable usage of SPE instructions + - fbdev: smscufx: Fix use-after-free in ufx_ops_open() + - btrfs: fix race between quota enable and quota rescan ioctl + - f2fs: increase the limit for reserve_root + - f2fs: fix to do sanity check on destination blkaddr during recovery + - f2fs: fix to do sanity check on summary info + - nilfs2: fix use-after-free bug of struct nilfs_root + - jbd2: wake up journal waiters in FIFO order, not LIFO + - ext4: avoid crash when inline data creation follows DIO write + - ext4: fix null-ptr-deref in ext4_write_info + - ext4: make ext4_lazyinit_thread freezable + - ext4: place buffer head allocation before handle start + - livepatch: fix race between fork and KLP transition + - ftrace: Properly unset FTRACE_HASH_FL_MOD + - ring-buffer: Allow splice to read previous partially read pages + - ring-buffer: Have the shortest_full queue be the shortest not longest + - ring-buffer: Check pending waiters when doing wake ups as well + - ring-buffer: Fix race between reset page and reading page + - media: cedrus: Set the platform driver data earlier + - KVM: x86/emulator: Fix handing of POP SS to correctly set interruptibility + - KVM: nVMX: Unconditionally purge queued/injected events on nested "exit" + - KVM: VMX: Drop bits 31:16 when shoving exception error code into VMCS + - gcov: support GCC 12.1 and newer compilers + - drm/nouveau: fix a use-after-free in nouveau_gem_prime_import_sg_table() + - selinux: use "grep -E" instead of "egrep" + - tracing: Disable interrupt or preemption before acquiring arch_spinlock_t + - userfaultfd: open userfaultfds with O_RDONLY + - sh: machvec: Use char[] for section boundaries + - ARM: 9247/1: mm: set readonly for MT_MEMORY_RO with ARM_LPAE + - nfsd: Fix a memory leak in an error handling path + - wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state() + - wifi: mac80211: allow bw change during channel switch in mesh + - bpftool: Fix a wrong type cast in btf_dumper_int + - x86/resctrl: Fix to restore to original value when re-enabling hardware + prefetch register + - wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse() + - spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume() + - spi: qup: add missing clk_disable_unprepare on error in + spi_qup_pm_resume_runtime() + - wifi: rtl8xxxu: Fix skb misuse in TX queue selection + - bpf: btf: fix truncated last_member_type_id in btf_struct_resolve + - wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration + - net: fs_enet: Fix wrong check in do_pd_setup + - bpf: Ensure correct locking around vulnerable function find_vpid() + - x86/microcode/AMD: Track patch allocation size explicitly + - spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe + - netfilter: nft_fib: Fix for rpath check with VRF devices + - spi: s3c64xx: Fix large transfers with DMA + - vhost/vsock: Use kvmalloc/kvfree for larger packets. + - sctp: handle the error returned from sctp_auth_asoc_init_active_key + - tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited + - net: rds: don't hold sock lock when cancelling work from + rds_tcp_reset_callbacks() + - bnx2x: fix potential memory leak in bnx2x_tpa_stop() + - net/ieee802154: reject zero-sized raw_sendmsg() + - once: add DO_ONCE_SLOW() for sleepable contexts + - net: mvpp2: fix mvpp2 debugfs leak + - drm: bridge: adv7511: fix CEC power down control register offset + - drm/mipi-dsi: Detach devices when removing the host + - platform/chrome: fix double-free in chromeos_laptop_prepare() + - platform/chrome: fix memory corruption in ioctl + - platform/x86: msi-laptop: Fix old-ec check for backlight registering + - platform/x86: msi-laptop: Fix resource cleanup + - drm: fix drm_mipi_dbi build errors + - drm/bridge: megachips: Fix a null pointer dereference bug + - ASoC: rsnd: Add check for rsnd_mod_power_on + - ALSA: hda: beep: Simplify keep-power-at-enable behavior + - drm/omap: dss: Fix refcount leak bugs + - mmc: au1xmmc: Fix an error handling path in au1xmmc_probe() + - ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API + - drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx + - ALSA: dmaengine: increment buffer pointer atomically + - mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe() + - ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe + - ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe + - ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe + - ALSA: hda/hdmi: Don't skip notification handling during PM operation + - memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe() + - memory: of: Fix refcount leak bug in of_get_ddr_timings() + - soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe() + - soc: qcom: smem_state: Add refcounting for the 'state->of_node' + - ARM: dts: turris-omnia: Fix mpp26 pin name and comment + - ARM: dts: kirkwood: lsxl: fix serial line + - ARM: dts: kirkwood: lsxl: remove first ethernet port + - ARM: dts: exynos: correct s5k6a3 reset polarity on Midas family + - ARM: Drop CMDLINE_* dependency on ATAGS + - ARM: dts: exynos: fix polarity of VBUS GPIO of Origen + - iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX + - iio: adc: at91-sama5d2_adc: check return status for pressure and touch + - iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq + - iio: inkern: only release the device node when done with it + - iio: ABI: Fix wrong format of differential capacitance channel ABI. + - clk: meson: Hold reference returned by of_get_parent() + - clk: oxnas: Hold reference returned by of_get_parent() + - clk: berlin: Add of_node_put() for of_get_parent() + - clk: tegra: Fix refcount leak in tegra210_clock_init + - clk: tegra: Fix refcount leak in tegra114_clock_init + - clk: tegra20: Fix refcount leak in tegra20_clock_init + - HSI: omap_ssi: Fix refcount leak in ssi_probe + - HSI: omap_ssi_port: Fix dma_map_sg error check + - media: exynos4-is: fimc-is: Add of_node_put() when breaking out of loop + - tty: xilinx_uartps: Fix the ignore_status + - media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init + - RDMA/rxe: Fix "kernel NULL pointer dereference" error + - RDMA/rxe: Fix the error caused by qp->sk + - misc: ocxl: fix possible refcount leak in afu_ioctl() + - dyndbg: fix module.dyndbg handling + - dyndbg: let query-modname override actual module name + - mtd: devices: docg3: check the return value of devm_ioremap() in the probe + - RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall. + - ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() + - ata: fix ata_id_has_devslp() + - ata: fix ata_id_has_ncq_autosense() + - ata: fix ata_id_has_dipm() + - mtd: rawnand: meson: fix bit map use in meson_nfc_ecc_correct() + - md/raid5: Ensure stripe_fill happens on non-read IO with journal + - xhci: Don't show warning for reinit on known broken suspend + - usb: gadget: function: fix dangling pnp_string in f_printer.c + - drivers: serial: jsm: fix some leaks in probe + - tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown + - phy: qualcomm: call clk_disable_unprepare in the error handling + - staging: vt6655: fix some erroneous memory clean-up loops + - firmware: google: Test spinlock on panic path to avoid lockups + - serial: 8250: Fix restoring termios speed after suspend + - scsi: libsas: Fix use-after-free bug in smp_execute_task_sg() + - fsi: core: Check error number after calling ida_simple_get + - mfd: intel_soc_pmic: Fix an error handling path in + intel_soc_pmic_i2c_probe() + - mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq() + - mfd: lp8788: Fix an error handling path in lp8788_probe() + - mfd: lp8788: Fix an error handling path in lp8788_irq_init() and + lp8788_irq_init() + - mfd: fsl-imx25: Fix check for platform_get_irq() errors + - mfd: sm501: Add check for platform_driver_register() + - clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent + - dmaengine: ioat: stop mod_timer from resurrecting deleted timer in + __cleanup() + - spmi: pmic-arb: correct duplicate APID to PPID mapping logic + - clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration + - clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe + - clk: ast2600: BCLK comes from EPLL + - mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg + - powerpc/math_emu/efp: Include module.h + - powerpc/sysdev/fsl_msi: Add missing of_node_put() + - powerpc/pci_dn: Add missing of_node_put() + - powerpc/powernv: add missing of_node_put() in opal_export_attrs() + - x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition + - powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5 + - powerpc: Fix SPE Power ISA properties for e500v1 platforms + - cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset + - iommu/omap: Fix buffer overflow in debugfs + - crypto: akcipher - default implementation for setting a private key + - crypto: ccp - Release dma channels before dmaengine unrgister + - iommu/iova: Fix module config properly + - kbuild: remove the target in signal traps when interrupted + - crypto: cavium - prevent integer overflow loading firmware + - f2fs: fix race condition on setting FI_NO_EXTENT flag + - ACPI: video: Add Toshiba Satellite/Portege Z830 quirk + - MIPS: BCM47XX: Cast memcmp() of function to (void *) + - powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue + - thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to + avoid crash + - NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data + - wifi: brcmfmac: fix invalid address access when enabling SCAN log level + - bpftool: Clear errno after libcap's checks + - openvswitch: Fix double reporting of drops in dropwatch + - openvswitch: Fix overreporting of drops in dropwatch + - tcp: annotate data-race around tcp_md5sig_pool_populated + - wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg() + - xfrm: Update ipcomp_scratches with NULL when freed + - wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit() + - Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create() + - Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times + - can: bcm: check the result of can_send() in bcm_can_tx() + - wifi: rt2x00: don't run Rt5592 IQ calibration on MT7620 + - wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620 + - wifi: rt2x00: set VGC gain for both chains of MT7620 + - wifi: rt2x00: set SoC wmac clock register + - wifi: rt2x00: correctly set BBP register 86 for MT7620 + - net: If sock is dead don't access sock's sk_wq in sk_stream_wait_memory + - Bluetooth: L2CAP: Fix user-after-free + - drm/nouveau/nouveau_bo: fix potential memory leak in nouveau_bo_alloc() + - drm: Use size_t type for len variable in drm_copy_field() + - drm: Prevent drm_copy_field() to attempt copying a NULL pointer + - drm/amd/display: fix overflow on MIN_I64 definition + - drm/vc4: vec: Fix timings for VEC modes + - drm: panel-orientation-quirks: Add quirk for Anbernic Win600 + - platform/x86: msi-laptop: Change DMI match / alias strings to fix module + autoloading + - drm/amdgpu: fix initial connector audio value + - mmc: sdhci-msm: add compatible string check for sdm670 + - ARM: dts: imx7d-sdb: config the max pressure for tsc2046 + - ARM: dts: imx6q: add missing properties for sram + - ARM: dts: imx6dl: add missing properties for sram + - ARM: dts: imx6qp: add missing properties for sram + - ARM: dts: imx6sl: add missing properties for sram + - ARM: dts: imx6sll: add missing properties for sram + - ARM: dts: imx6sx: add missing properties for sram + - btrfs: scrub: try to fix super block errors + - clk: zynqmp: Fix stack-out-of-bounds in strncpy` + - media: cx88: Fix a null-ptr-deref bug in buffer_prepare() + - clk: zynqmp: pll: rectify rate rounding in zynqmp_pll_round_rate + - scsi: 3w-9xxx: Avoid disabling device if failing to enable it + - nbd: Fix hung when signal interrupts nbd_start_device_ioctl() + - power: supply: adp5061: fix out-of-bounds read in adp5061_get_chg_type() + - staging: vt6655: fix potential memory leak + - ata: libahci_platform: Sanity check the DT child nodes number + - bcache: fix set_at_max_writeback_rate() for multiple attached devices + - HID: roccat: Fix use-after-free in roccat_read() + - md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d + - usb: host: xhci: Fix potential memory leak in xhci_alloc_stream_info() + - usb: musb: Fix musb_gadget.c rxstate overflow bug + - Revert "usb: storage: Add quirk for Samsung Fit flash" + - staging: rtl8723bs: fix a potential memory leak in rtw_init_cmd_priv() + - nvme: copy firmware_rev on each init + - nvmet-tcp: add bounds check on Transfer Tag + - usb: idmouse: fix an uninit-value in idmouse_open + - clk: bcm2835: Make peripheral PLLC critical + - perf intel-pt: Fix segfault in intel_pt_print_info() with uClibc + - net: ieee802154: return -EINVAL for unknown addr type + - Revert "net/ieee802154: reject zero-sized raw_sendmsg()" + - net/ieee802154: don't warn zero-sized raw_sendmsg() + - ext4: continue to expand file system when the target size doesn't reach + - efi: libstub: drop pointless get_memory_map() call + - inet: fully convert sk->sk_rx_dst to RCU rules + - thermal: intel_powerclamp: Use first online CPU as control_cpu + - Linux 5.4.220 + * Focal update: v5.4.219 upstream stable release (LP: #1996804) + - Linux 5.4.219 + + -- Luke Nowakowski-Krijger Wed, 25 Jan 2023 10:56:48 -0800 + +linux-oracle (5.4.0-1092.101) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1092.101 -proposed tracker (LP: #2001959) + + [ Ubuntu: 5.4.0-137.154 ] + + * focal/linux: 5.4.0-137.154 -proposed tracker (LP: #2001969) + * CVE-2022-3643 + - xen/netback: Ensure protocol headers don't fall in the non-linear area + * CVE-2022-43945 + - NFSD: Cap rsize_bop result based on send buffer size + * CVE-2022-45934 + - Bluetooth: L2CAP: Fix u8 overflow + * CVE-2022-42896 + - Bluetooth: L2CAP: Fix accepting connection request for invalid SPSM + - Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm + + -- Thadeu Lima de Souza Cascardo Tue, 10 Jan 2023 11:19:33 -0300 + +linux-oracle (5.4.0-1091.100) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1091.100 -proposed tracker (LP: #1997824) + + [ Ubuntu: 5.4.0-136.153 ] + + * focal/linux: 5.4.0-136.153 -proposed tracker (LP: #1997835) + * Expose built-in trusted and revoked certificates (LP: #1996892) + - [Packaging] Expose built-in trusted and revoked certificates + * [UBUNTU 20.04] KVM: PV: ext call delivered twice when receiver in PSW wait + (LP: #1995941) + - KVM: s390: pv: don't present the ecall interrupt twice + * [UBUNTU 20.04] boot: Add s390x secure boot trailer (LP: #1996071) + - s390/boot: add secure boot trailer + * Fix rfkill causing soft blocked wifi (LP: #1996198) + - platform/x86: hp_wmi: Fix rfkill causing soft blocked wifi + * md: Replace snprintf with scnprintf (LP: #1993315) + - md: Replace snprintf with scnprintf + * input/keyboard: the keyboard on some Asus laptops can't work (LP: #1992266) + - ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA + - ACPI: resource: Add ASUS model S5402ZA to quirks + * Focal update: v5.4.218 upstream stable release (LP: #1995530) + - mm: pagewalk: Fix race between unmap and page walker + - perf tools: Fixup get_current_dir_name() compilation + - firmware: arm_scmi: Add SCMI PM driver remove routine + - dmaengine: xilinx_dma: cleanup for fetching xlnx,num-fstores property + - dmaengine: xilinx_dma: Report error in case of dma_set_mask_and_coherent API + failure + - ARM: dts: fix Moxa SDIO 'compatible', remove 'sdhci' misnomer + - scsi: qedf: Fix a UAF bug in __qedf_probe() + - net/ieee802154: fix uninit value bug in dgram_sendmsg + - um: Cleanup syscall_handler_t cast in syscalls_32.h + - um: Cleanup compiler warning in arch/x86/um/tls_32.c + - arch: um: Mark the stack non-executable to fix a binutils warning + - usb: mon: make mmapped memory read only + - USB: serial: ftdi_sio: fix 300 bps rate for SIO + - mmc: core: Replace with already defined values for readability + - mmc: core: Terminate infinite loop in SD-UHS voltage switch + - rpmsg: qcom: glink: replace strncpy() with strscpy_pad() + - nilfs2: fix leak of nilfs_root in case of writer thread creation failure + - nilfs2: replace WARN_ONs by nilfs_error for checkpoint acquisition failure + - ceph: don't truncate file in atomic_open + - random: clamp credited irq bits to maximum mixed + - ALSA: hda: Fix position reporting on Poulsbo + - efi: Correct Macmini DMI match in uefi cert quirk + - USB: serial: qcserial: add new usb-id for Dell branded EM7455 + - random: restore O_NONBLOCK support + - random: avoid reading two cache lines on irq randomness + - random: use expired timer rather than wq for mixing fast pool + - Input: xpad - add supported devices as contributed on github + - Input: xpad - fix wireless 360 controller breaking after suspend + - Linux 5.4.218 + * Focal update: v5.4.217 upstream stable release (LP: #1995528) + - xfs: fix misuse of the XFS_ATTR_INCOMPLETE flag + - xfs: introduce XFS_MAX_FILEOFF + - xfs: truncate should remove all blocks, not just to the end of the page + cache + - xfs: fix s_maxbytes computation on 32-bit kernels + - xfs: fix IOCB_NOWAIT handling in xfs_file_dio_aio_read + - xfs: refactor remote attr value buffer invalidation + - xfs: fix memory corruption during remote attr value buffer invalidation + - xfs: move incore structures out of xfs_da_format.h + - xfs: streamline xfs_attr3_leaf_inactive + - xfs: fix uninitialized variable in xfs_attr3_leaf_inactive + - xfs: remove unused variable 'done' + - Makefile.extrawarn: Move -Wcast-function-type-strict to W=1 + - docs: update mediator information in CoC docs + - Linux 5.4.217 + * Focal update: v5.4.216 upstream stable release (LP: #1995526) + - uas: add no-uas quirk for Hiksemi usb_disk + - usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS + - uas: ignore UAS for Thinkplus chips + - net: usb: qmi_wwan: Add new usb-id for Dell branded EM7455 + - clk: ingenic-tcu: Properly enable registers before accessing timers + - ARM: dts: integrator: Tag PCI host with device_type + - ntfs: fix BUG_ON in ntfs_lookup_inode_by_name() + - libata: add ATA_HORKAGE_NOLPM for Pioneer BDR-207M and BDR-205 + - mmc: moxart: fix 4-bit bus width and remove 8-bit bus width + - mm/page_alloc: fix race condition between build_all_zonelists and page + allocation + - mm: prevent page_frag_alloc() from corrupting the memory + - mm/migrate_device.c: flush TLB while holding PTL + - mm: fix madivse_pageout mishandling on non-LRU page + - media: dvb_vb2: fix possible out of bound access + - ARM: dts: Move am33xx and am43xx mmc nodes to sdhci-omap driver + - ARM: dts: am33xx: Fix MMCHS0 dma properties + - soc: sunxi: sram: Actually claim SRAM regions + - soc: sunxi: sram: Prevent the driver from being unbound + - soc: sunxi_sram: Make use of the helper function + devm_platform_ioremap_resource() + - soc: sunxi: sram: Fix probe function ordering issues + - soc: sunxi: sram: Fix debugfs info for A64 SRAM C + - Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in + suspend/resume time" + - Input: melfas_mip4 - fix return value check in mip4_probe() + - usbnet: Fix memory leak in usbnet_disconnect() + - nvme: add new line after variable declatation + - nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices + - selftests: Fix the if conditions of in test_extra_filter() + - clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks + - clk: iproc: Do not rely on node name for correct PLL setup + - Linux 5.4.216 + * Focal update: v5.4.215 upstream stable release (LP: #1993203) + - of: fdt: fix off-by-one error in unflatten_dt_nodes() + - NFSv4: Turn off open-by-filehandle and NFS re-export for NFSv4.0 + - gpio: mpc8xxx: Fix support for IRQ_TYPE_LEVEL_LOW flow_type in mpc85xx + - drm/meson: Correct OSD1 global alpha value + - drm/meson: Fix OSD1 RGB to YCbCr coefficient + - parisc: ccio-dma: Add missing iounmap in error path in ccio_probe() + - ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC + - task_stack, x86/cea: Force-inline stack helpers + - tracing: hold caller_addr to hardirq_{enable,disable}_ip + - cifs: revalidate mapping when doing direct writes + - cifs: don't send down the destination address to sendmsg for a SOCK_STREAM + - MAINTAINERS: add Chandan as xfs maintainer for 5.4.y + - iomap: iomap that extends beyond EOF should be marked dirty + - ASoC: nau8824: Fix semaphore unbalance at error paths + - regulator: pfuze100: Fix the global-out-of-bounds access in + pfuze100_regulator_probe() + - rxrpc: Fix local destruction being repeated + - rxrpc: Fix calc of resend age + - ALSA: hda/sigmatel: Keep power up while beep is enabled + - ALSA: hda/tegra: Align BDL entry to 4KB boundary + - net: usb: qmi_wwan: add Quectel RM520N + - afs: Return -EAGAIN, not -EREMOTEIO, when a file already locked + - MIPS: OCTEON: irq: Fix octeon_irq_force_ciu_mapping() + - mksysmap: Fix the mismatch of 'L0' symbols in System.map + - video: fbdev: pxa3xx-gcu: Fix integer overflow in pxa3xx_gcu_write + - cgroup: Add missing cpus_read_lock() to cgroup_attach_task_all() + - ALSA: hda/sigmatel: Fix unused variable warning for beep power change + - usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbind + - usb: dwc3: Issue core soft reset before enabling run/stop + - usb: dwc3: gadget: Prevent repeat pullup() + - usb: dwc3: gadget: Refactor pullup() + - usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup() + - usb: dwc3: gadget: Avoid duplicate requests to enable Run/Stop + - usb: xhci-mtk: get the microframe boundary for ESIT + - usb: xhci-mtk: add only one extra CS for FS/LS INTR + - usb: xhci-mtk: use @sch_tt to check whether need do TT schedule + - usb: xhci-mtk: add a function to (un)load bandwidth info + - usb: xhci-mtk: add some schedule error number + - usb: xhci-mtk: allow multiple Start-Split in a microframe + - usb: xhci-mtk: relax TT periodic bandwidth allocation + - wifi: mac80211: Fix UAF in ieee80211_scan_rx() + - tty/serial: atmel: RS485 & ISO7816: wait for TXRDY before sending data + - serial: atmel: remove redundant assignment in rs485_config + - tty: serial: atmel: Preserve previous USART mode if RS485 disabled + - usb: add quirks for Lenovo OneLink+ Dock + - usb: gadget: udc-xilinx: replace memcpy with memcpy_toio + - usb: cdns3: fix issue with rearming ISO OUT endpoint + - Revert "usb: add quirks for Lenovo OneLink+ Dock" + - Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio" + - USB: core: Fix RST error in hub.c + - USB: serial: option: add Quectel BG95 0x0203 composition + - USB: serial: option: add Quectel RM520N + - ALSA: hda/tegra: set depop delay for tegra + - ALSA: hda: add Intel 5 Series / 3400 PCI DID + - ALSA: hda/realtek: Add quirk for Huawei WRT-WX9 + - ALSA: hda/realtek: Re-arrange quirk table entries + - ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack + - ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack + - ALSA: hda/realtek: Add quirk for ASUS GA503R laptop + - ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop + - efi: libstub: check Shim mode using MokSBStateRT + - mm/slub: fix to return errno if kmalloc() fails + - arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob + - arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz + - arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma + - netfilter: nf_conntrack_sip: fix ct_sip_walk_headers + - netfilter: nf_conntrack_irc: Tighten matching on DCC message + - netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find() + - iavf: Fix cached head and tail value for iavf_get_tx_pending + - ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header + - net: team: Unsync device addresses on ndo_stop + - MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko + - MIPS: Loongson32: Fix PHY-mode being left unspecified + - iavf: Fix bad page state + - i40e: Fix set max_tx_rate when it is lower than 1 Mbps + - of: mdio: Add of_node_put() when breaking out of for_each_xx + - net/sched: taprio: avoid disabling offload when it was never enabled + - net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child + qdiscs + - netfilter: ebtables: fix memory leak when blob is malformed + - can: gs_usb: gs_can_open(): fix race dev->can.state condition + - perf jit: Include program header in ELF files + - perf kcore_copy: Do not check /proc/modules is unchanged + - net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD + - net: sched: fix possible refcount leak in tc_new_tfilter() + - serial: Create uart_xmit_advance() + - serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting + - serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting + - s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup + - usb: xhci-mtk: fix issue of out-of-bounds array access + - cifs: always initialize struct msghdr smb_msg completely + - Drivers: hv: Never allocate anything besides framebuffer from framebuffer + memory region + - drm/amd/display: Limit user regamma to a valid value + - drm/rockchip: Fix return type of cdn_dp_connector_mode_valid + - workqueue: don't skip lockdep work dependency in cancel_work_sync() + - ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0 + - xfs: replace -EIO with -EFSCORRUPTED for corrupt metadata + - xfs: slightly tweak an assert in xfs_fs_map_blocks + - xfs: add missing assert in xfs_fsmap_owner_from_rmap + - xfs: range check ri_cnt when recovering log items + - xfs: attach dquots and reserve quota blocks during unwritten conversion + - xfs: convert EIO to EFSCORRUPTED when log contents are invalid + - xfs: constify the buffer pointer arguments to error functions + - xfs: always log corruption errors + - xfs: fix some memory leaks in log recovery + - xfs: stabilize insert range start boundary to avoid COW writeback race + - xfs: use bitops interface for buf log item AIL flag check + - xfs: refactor agfl length computation function + - xfs: split the sunit parameter update into two parts + - xfs: don't commit sunit/swidth updates to disk if that would cause repair + failures + - xfs: fix an ABBA deadlock in xfs_rename + - xfs: fix use-after-free when aborting corrupt attr inactivation + - ext4: make directory inode spreading reflect flexbg size + - Linux 5.4.215 + * Focal update: v5.4.214 upstream stable release (LP: #1993196) + - drm/msm/rd: Fix FIFO-full deadlock + - HID: ishtp-hid-clientHID: ishtp-hid-client: Fix comment typo + - hid: intel-ish-hid: ishtp: Fix ishtp client sending disordered message + - tg3: Disable tg3 device on system reboot to avoid triggering AER + - ieee802154: cc2520: add rc code in cc2520_tx() + - Input: iforce - add support for Boeder Force Feedback Wheel + - nvmet-tcp: fix unhandled tcp states in nvmet_tcp_state_change() + - perf/arm_pmu_platform: fix tests for platform_get_irq() failure + - platform/x86: acer-wmi: Acer Aspire One AOD270/Packard Bell Dot keymap fixes + - usb: storage: Add ASUS <0x0b05:0x1932> to IGNORE_UAS + - mm: Fix TLB flush for not-first PFNMAP mappings in unmap_region() + - net: dp83822: disable rx error interrupt + - soc: fsl: select FSL_GUTS driver for DPIO + - tracefs: Only clobber mode/uid/gid on remount if asked + - Linux 5.4.214 + * Focal update: v5.4.213 upstream stable release (LP: #1992211) + - efi: capsule-loader: Fix use-after-free in efi_capsule_write + - wifi: iwlegacy: 4965: corrected fix for potential off-by-one overflow in + il4965_rs_fill_link_cmd() + - fs: only do a memory barrier for the first set_buffer_uptodate() + - Revert "mm: kmemleak: take a full lowmem check in kmemleak_*_phys()" + - net: dp83822: disable false carrier interrupt + - drm/msm/dsi: fix the inconsistent indenting + - drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg + - platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask + - iio: adc: mcp3911: make use of the sign bit + - ieee802154/adf7242: defer destroy_workqueue call + - wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() + - Revert "xhci: turn off port power in shutdown" + - net: sched: tbf: don't call qdisc_put() while holding tree lock + - ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler + - kcm: fix strp_init() order and cleanup + - sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb + - tcp: annotate data-race around challenge_timestamp + - Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb" + - net/smc: Remove redundant refcount increase + - serial: fsl_lpuart: RS485 RTS polariy is inverse + - staging: rtl8712: fix use after free bugs + - powerpc: align syscall table for ppc32 + - vt: Clear selection before changing the font + - tty: serial: lpuart: disable flow control while waiting for the transmit + engine to complete + - Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag + - iio: adc: mcp3911: use correct formula for AD conversion + - misc: fastrpc: fix memory corruption on probe + - misc: fastrpc: fix memory corruption on open + - USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id + - binder: fix UAF of ref->proc caused by race condition + - usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup + - drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" + - clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops + - Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops" + - clk: core: Fix runtime PM sequence in clk_core_unprepare() + - Input: rk805-pwrkey - fix module autoloading + - clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate + - hwmon: (gpio-fan) Fix array out of bounds access + - gpio: pca953x: Add mutex_lock for regcache sync in PM + - thunderbolt: Use the actual buffer in tb_async_error() + - xhci: Add grace period after xHC start to prevent premature runtime suspend. + - USB: serial: cp210x: add Decagon UCA device id + - USB: serial: option: add support for OPPO R11 diag port + - USB: serial: option: add Quectel EM060K modem + - USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode + - usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles + - usb: dwc2: fix wrong order of phy_power_on and phy_init + - USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) + - usb-storage: Add ignore-residue quirk for NXP PN7462AU + - s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages + - s390: fix nospec table alignments + - USB: core: Prevent nested device-reset calls + - usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS + - driver core: Don't probe devices after bus_type.match() probe deferral + - wifi: mac80211: Don't finalize CSA in IBSS mode if state is disconnected + - net: mac802154: Fix a condition in the receive path + - ALSA: seq: oss: Fix data-race for max_midi_devs access + - ALSA: seq: Fix data-race at module auto-loading + - drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk + - btrfs: harden identification of a stale device + - usb: dwc3: fix PHY disable sequence + - usb: dwc3: disable USB core PHY management + - USB: serial: ch341: fix lost character on LCR updates + - USB: serial: ch341: fix disabled rx timer on older devices + - scsi: megaraid_sas: Fix double kfree() + - drm/gem: Fix GEM handle release errors + - drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. + - drm/radeon: add a force flush to delay work when radeon + - parisc: ccio-dma: Handle kmalloc failure in ccio_init_resources() + - parisc: Add runtime check to prevent PA2.0 kernels on PA1.x machines + - arm64: cacheinfo: Fix incorrect assignment of signed error value to unsigned + fw_level + - fbdev: chipsfb: Add missing pci_disable_device() in chipsfb_pci_init() + - drm/amdgpu: mmVM_L2_CNTL3 register not initialized correctly + - ALSA: emu10k1: Fix out of bounds access in snd_emu10k1_pcm_channel_alloc() + - ALSA: aloop: Fix random zeros in capture data when using jiffies timer + - ALSA: usb-audio: Fix an out-of-bounds bug in + __snd_usb_parse_audio_interface() + - kprobes: Prohibit probes in gate area + - debugfs: add debugfs_lookup_and_remove() + - nvmet: fix a use-after-free + - scsi: mpt3sas: Fix use-after-free warning + - scsi: lpfc: Add missing destroy_workqueue() in error path + - cgroup: Optimize single thread migration + - cgroup: Elide write-locking threadgroup_rwsem when updating csses on an + empty subtree + - cgroup: Fix threadgroup_rwsem <-> cpus_read_lock() deadlock + - smb3: missing inode locks in punch hole + - ARM: dts: imx6qdl-kontron-samx6i: remove duplicated node + - regulator: core: Clean up on enable failure + - RDMA/cma: Fix arguments order in net device validation + - soc: brcmstb: pm-arm: Fix refcount leak and __iomem leak bugs + - RDMA/hns: Fix supported page size + - netfilter: br_netfilter: Drop dst references before setting. + - rxrpc: Fix an insufficiently large sglist in rxkad_verify_packet_2() + - afs: Use the operation issue time instead of the reply time for callbacks + - sch_sfb: Don't assume the skb is still around after enqueueing to child + - tipc: fix shift wrapping bug in map_get() + - i40e: Fix kernel crash during module removal + - RDMA/siw: Pass a pointer to virt_to_page() + - ipv6: sr: fix out-of-bounds read when setting HMAC data. + - RDMA/mlx5: Set local port to one when accessing counters + - nvme-tcp: fix UAF when detecting digest errors + - tcp: fix early ETIMEDOUT after spurious non-SACK RTO + - sch_sfb: Also store skb len before calling child enqueue + - x86/nospec: Fix i386 RSB stuffing + - MIPS: loongson32: ls1c: Fix hang during startup + - Linux 5.4.213 + * CVE-2022-2663 + - netfilter: nf_conntrack_irc: Fix forged IP logic + * CVE-2022-3061 + - video: fbdev: i740fb: Error out if 'pixclock' equals zero + + -- Joseph Salisbury Wed, 30 Nov 2022 11:57:19 -0500 + +linux-oracle (5.4.0-1090.99) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1090.99 -proposed tracker (LP: #1997402) + + [ Ubuntu: 5.4.0-135.152 ] + + * focal/linux: 5.4.0-135.152 -proposed tracker (LP: #1997412) + * containerd sporadic timeouts (LP: #1996678) + - epoll: call final ep_events_available() check under the lock + - epoll: check for events when removing a timed out thread from the wait queue + - Revert "fs: check FMODE_LSEEK to control internal pipe splicing" + * CVE-2022-3621 + - nilfs2: fix NULL pointer dereference at nilfs_bmap_lookup_at_level() + * CVE-2022-3565 + - mISDN: fix use-after-free bugs in l1oip timer handlers + * CVE-2022-3566 + - tcp: Fix data races around icsk->icsk_af_ops. + * CVE-2022-3567 + - ipv6: annotate some data-races around sk->sk_prot + - ipv6: Fix data races around sk->sk_prot. + * CVE-2022-3564 + - Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu + * CVE-2022-3524 + - tcp/udp: Fix memory leak in ipv6_renew_options(). + * CVE-2022-3594 + - r8152: Rate limit overflow messages + * CVE-2022-42703 + - mm/rmap.c: don't reuse anon_vma if we just want a copy + + -- Thadeu Lima de Souza Cascardo Thu, 24 Nov 2022 23:26:26 -0300 + +linux-oracle (5.4.0-1087.96) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1087.96 -proposed tracker (LP: #1992054) + + [ Ubuntu: 5.4.0-132.148 ] + + * CVE-2022-42719 + - mac80211: mlme: find auth challenge directly + - wifi: mac80211: don't parse mbssid in assoc response + - wifi: mac80211: fix MBSSID parsing use-after-free + * iavf: SR-IOV VFs error with no traffic flow when MTU greater than 1500 + (LP: #1983656) + - iavf: Fix set max MTU size with port VLAN and jumbo frames + - i40e: Fix VF set max MTU size + * fib_nexthop_nongw.sh from ubuntu_kernel_selftests failed on B-5.4 + (LP: #1990800) + - SAUCE: selftests/net: skipping tests for older ip command releases + * CVE-2022-29901 + - Revert "x86/speculation: Add RSB VM Exit protections" + - Revert "x86/cpu: Add a steppings field to struct x86_cpu_id" + - x86/devicetable: Move x86 specific macro out of generic code + - x86/cpu: Add consistent CPU match macros + - x86/cpu: Add a steppings field to struct x86_cpu_id + - x86/kvm/vmx: Make noinstr clean + - x86/cpufeatures: Move RETPOLINE flags to word 11 + - x86/bugs: Report AMD retbleed vulnerability + - x86/bugs: Add AMD retbleed= boot parameter + - x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value + - x86/entry: Remove skip_r11rcx + - x86/entry: Add kernel IBRS implementation + - x86/bugs: Optimize SPEC_CTRL MSR writes + - x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS + - x86/bugs: Split spectre_v2_select_mitigation() and + spectre_v2_user_select_mitigation() + - x86/bugs: Report Intel retbleed vulnerability + - intel_idle: Disable IBRS during long idle + - x86/speculation: Change FILL_RETURN_BUFFER to work with objtool + - x86/speculation: Fix RSB filling with CONFIG_RETPOLINE=n + - x86/speculation: Fix firmware entry SPEC_CTRL handling + - x86/speculation: Fix SPEC_CTRL write on SMT state change + - x86/speculation: Use cached host SPEC_CTRL value for guest entry/exit + - x86/speculation: Remove x86_spec_ctrl_mask + - KVM/VMX: Use TEST %REG,%REG instead of CMP $0,%REG in vmenter.S + - KVM/nVMX: Use __vmx_vcpu_run in nested_vmx_check_vmentry_hw + - KVM: VMX: Flatten __vmx_vcpu_run() + - KVM: VMX: Convert launched argument to flags + - KVM: VMX: Prevent guest RSB poisoning attacks with eIBRS + - KVM: VMX: Fix IBRS handling after vmexit + - x86/speculation: Fill RSB on vmexit for IBRS + - x86/common: Stamp out the stepping madness + - x86/cpu/amd: Enumerate BTC_NO + - x86/bugs: Add Cannon lake to RETBleed affected CPU list + - x86/speculation: Disable RRSBA behavior + - x86/speculation: Use DECLARE_PER_CPU for x86_spec_ctrl_current + - x86/bugs: Warn when "ibrs" mitigation is selected on Enhanced IBRS parts + - x86/speculation: Add RSB VM Exit protections + * ACPI: processor idle: Practically limit "Dummy wait" workaround to old Intel + systems (LP: #1990985) + - ACPI: processor_idle: Skip dummy wait if kernel is in guest + - ACPI: processor idle: Practically limit "Dummy wait" workaround to old Intel + systems + * cgroup: all controllers mounted when using 'cgroup_no_v1=' (LP: #1988584) + - cgroup-v1: add disabled controller check in cgroup1_parse_param() + * Focal update: v5.4.212 upstream stable release (LP: #1991156) + - audit: fix potential double free on error path from fsnotify_add_inode_mark + - parisc: Fix exception handler for fldw and fstw instructions + - kernel/sys_ni: add compat entry for fadvise64_64 + - usb: cdns3: Fix issue for clear halt endpoint + - pinctrl: amd: Don't save/restore interrupt status and wake status bits + - sched/deadline: Unthrottle PI boosted threads while enqueuing + - sched/deadline: Fix stale throttling on de-/boosted tasks + - sched/deadline: Fix priority inheritance with multiple scheduling classes + - kernel/sched: Remove dl_boosted flag comment + - xfrm: fix refcount leak in __xfrm_policy_check() + - SUNRPC: RPC level errors should set task->tk_rpc_status + - rose: check NULL rose_loopback_neigh->loopback + - net/mlx5e: Properly disable vlan strip on non-UL reps + - net: moxa: get rid of asymmetry in DMA mapping/unmapping + - bonding: 802.3ad: fix no transmission of LACPDUs + - net: ipvtap - add __init/__exit annotations to module init/exit funcs + - netfilter: ebtables: reject blobs that don't provide all entry points + - bnxt_en: fix NQ resource accounting during vf creation on 57500 chips + - netfilter: nft_payload: report ERANGE for too long offset and length + - netfilter: nft_payload: do not truncate csum_offset and csum_type + - netfilter: nft_osf: restrict osf to ipv4, ipv6 and inet families + - netfilter: nft_tunnel: restrict it to netdev family + - net: Fix data-races around weight_p and dev_weight_[rt]x_bias. + - net: Fix data-races around netdev_tstamp_prequeue. + - ratelimit: Fix data-races in ___ratelimit(). + - net: Fix a data-race around sysctl_tstamp_allow_data. + - net: Fix a data-race around sysctl_net_busy_poll. + - net: Fix a data-race around sysctl_net_busy_read. + - net: Fix a data-race around netdev_budget. + - net: Fix a data-race around netdev_budget_usecs. + - net: Fix a data-race around sysctl_somaxconn. + - ixgbe: stop resetting SYSTIME in ixgbe_ptp_start_cyclecounter + - btrfs: fix silent failure when deleting root reference + - btrfs: replace: drop assert for suspended replace + - btrfs: add info when mount fails due to stale replace target + - btrfs: check if root is readonly while setting security xattr + - x86/unwind/orc: Unwind ftrace trampolines with correct ORC entry + - loop: Check for overflow while configuring loop + - asm-generic: sections: refactor memory_intersects + - s390: fix double free of GS and RI CBs on fork() failure + - ACPI: processor: Remove freq Qos request for all CPUs + - mm/hugetlb: fix hugetlb not supporting softdirty tracking + - md: call __md_stop_writes in md_stop + - perf/x86/intel/uncore: Fix broken read_counter() for SNB IMC PMU + - scsi: storvsc: Remove WQ_MEM_RECLAIM from storvsc_error_wq + - mm: Force TLB flush for PFNMAP mappings before unlink_file_vma() + - s390/mm: do not trigger write fault when vma does not allow VM_WRITE + - x86/bugs: Add "unknown" reporting for MMIO Stale Data + - kbuild: Fix include path in scripts/Makefile.modpost + - Bluetooth: L2CAP: Fix build errors in some archs + - HID: steam: Prevent NULL pointer dereference in steam_{recv,send}_report + - udmabuf: Set the DMA mask for the udmabuf device (v2) + - media: pvrusb2: fix memory leak in pvr_probe + - HID: hidraw: fix memory leak in hidraw_release() + - fbdev: fb_pm2fb: Avoid potential divide by zero error + - ftrace: Fix NULL pointer dereference in is_ftrace_trampoline when ftrace is + dead + - bpf: Don't redirect packets with invalid pkt_len + - mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse + - btrfs: introduce btrfs_lookup_match_dir + - btrfs: do not pin logs too early during renames + - btrfs: unify lookup return value when dir entry is missing + - drm/amd/display: Avoid MPC infinite loop + - drm/amd/display: clear optc underflow before turn off odm clock + - neigh: fix possible DoS due to net iface start/stop loop + - s390/hypfs: avoid error message under KVM + - drm/amd/display: Fix pixel clock programming + - netfilter: conntrack: NF_CONNTRACK_PROCFS should no longer default to y + - btrfs: tree-checker: check for overlapping extent items + - lib/vdso: Let do_coarse() return 0 to simplify the callsite + - lib/vdso: Mark do_hres() and do_coarse() as __always_inline + - kprobes: don't call disarm_kprobe() for disabled kprobes + - net/af_packet: check len when min_header_len equals to 0 + - net: neigh: don't call kfree_skb() under spin_lock_irqsave() + - Linux 5.4.212 + * Focal update: v5.4.211 upstream stable release (LP: #1990190) + - Makefile: link with -z noexecstack --no-warn-rwx-segments + - x86: link vdso and boot with -z noexecstack --no-warn-rwx-segments + - scsi: Revert "scsi: qla2xxx: Fix disk failure to rediscover" + - ALSA: bcd2000: Fix a UAF bug on the error path of probing + - igc: Remove _I_PHY_ID checking + - wifi: mac80211_hwsim: fix race condition in pending packet + - wifi: mac80211_hwsim: add back erroneously removed cast + - wifi: mac80211_hwsim: use 32-bit skb cookie + - add barriers to buffer_uptodate and set_buffer_uptodate + - HID: wacom: Only report rotation for art pen + - HID: wacom: Don't register pad_input for touch switch + - KVM: nVMX: Snapshot pre-VM-Enter BNDCFGS for !nested_run_pending case + - KVM: nVMX: Snapshot pre-VM-Enter DEBUGCTL for !nested_run_pending case + - KVM: SVM: Don't BUG if userspace injects an interrupt with GIF=0 + - KVM: nVMX: Let userspace set nVMX MSR to any _host_ supported value + - KVM: x86: Mark TSS busy during LTR emulation _after_ all fault checks + - KVM: x86: Set error code to segment selector on LLDT/LTR non-canonical #GP + - mm/mremap: hold the rmap lock in write mode when moving page table entries. + - ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model + - ALSA: hda/cirrus - support for iMac 12,1 model + - ALSA: hda/realtek: Add quirk for another Asus K42JZ model + - tty: vt: initialize unicode screen buffer + - vfs: Check the truncate maximum size in inode_newsize_ok() + - fs: Add missing umask strip in vfs_tmpfile + - thermal: sysfs: Fix cooling_device_stats_setup() error code path + - fbcon: Fix boundary checks for fbcon=vc:n1-n2 parameters + - usbnet: Fix linkwatch use-after-free on disconnect + - ovl: drop WARN_ON() dentry is NULL in ovl_encode_fh() + - parisc: Fix device names in /proc/iomem + - parisc: io_pgetevents_time64() needs compat syscall in 32-bit compat mode + - drm/gem: Properly annotate WW context on drm_gem_lock_reservations() error + - drm/nouveau: fix another off-by-one in nvbios_addr + - drm/amdgpu: Check BO's requested pinning domains against its + preferred_domains + - iio: light: isl29028: Fix the warning in isl29028_remove() + - fuse: limit nsec + - serial: mvebu-uart: uart2 error bits clearing + - md-raid10: fix KASAN warning + - ia64, processor: fix -Wincompatible-pointer-types in ia64_get_irr() + - PCI: Add defines for normal and subtractive PCI bridges + - powerpc/fsl-pci: Fix Class Code of PCIe Root Port + - powerpc/ptdump: Fix display of RW pages on FSL_BOOK3E + - powerpc/powernv: Avoid crashing if rng is NULL + - MIPS: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - coresight: Clear the connection field properly + - USB: HCD: Fix URB giveback issue in tasklet function + - ARM: dts: uniphier: Fix USB interrupts for PXs2 SoC + - arm64: dts: uniphier: Fix USB interrupts for PXs3 SoC + - netfilter: nf_tables: fix null deref due to zeroed list head + - epoll: autoremove wakers even more aggressively + - x86: Handle idle=nomwait cmdline properly for x86_idle + - arm64: Do not forget syscall when starting a new thread. + - arm64: fix oops in concurrently setting insn_emulation sysctls + - ext2: Add more validity checks for inode counts + - genirq: Don't return error on missing optional irq_request_resources() + - wait: Fix __wait_event_hrtimeout for RT/DL tasks + - ARM: dts: imx6ul: add missing properties for sram + - ARM: dts: imx6ul: change operating-points to uint32-matrix + - ARM: dts: imx6ul: fix csi node compatible + - ARM: dts: imx6ul: fix lcdif node compatible + - ARM: dts: imx6ul: fix qspi node compatible + - spi: synquacer: Add missing clk_disable_unprepare() + - ARM: OMAP2+: display: Fix refcount leak bug + - ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI quirks + - ACPI: PM: save NVS memory for Lenovo G40-45 + - ACPI: LPSS: Fix missing check in register_device_clock() + - arm64: dts: qcom: ipq8074: fix NAND node name + - arm64: dts: allwinner: a64: orangepi-win: Fix LED node name + - ARM: shmobile: rcar-gen2: Increase refcount for new reference + - PM: hibernate: defer device probing when resuming from hibernation + - selinux: Add boundary check in put_entry() + - spi: spi-rspi: Fix PIO fallback on RZ platforms + - ARM: findbit: fix overflowing offset + - meson-mx-socinfo: Fix refcount leak in meson_mx_socinfo_init + - ARM: bcm: Fix refcount leak in bcm_kona_smc_init + - x86/pmem: Fix platform-device leak in error path + - ARM: dts: ast2500-evb: fix board compatible + - ARM: dts: ast2600-evb: fix board compatible + - soc: fsl: guts: machine variable might be unset + - ARM: dts: qcom: mdm9615: add missing PMIC GPIO reg + - ARM: OMAP2+: Fix refcount leak in omapdss_init_of + - ARM: OMAP2+: Fix refcount leak in omap3xxx_prm_late_init + - cpufreq: zynq: Fix refcount leak in zynq_get_revision + - soc: qcom: aoss: Fix refcount leak in qmp_cooling_devices_register + - ARM: dts: qcom: pm8841: add required thermal-sensor-cells + - bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe() + - arm64: dts: mt7622: fix BPI-R64 WPS button + - erofs: avoid consecutive detection for Highmem memory + - blk-mq: don't create hctx debugfs dir until q->debugfs_dir is created + - regulator: of: Fix refcount leak bug in of_get_regulation_constraints() + - nohz/full, sched/rt: Fix missed tick-reenabling bug in dequeue_task_rt() + - thermal/tools/tmon: Include pthread and time headers in tmon.h + - dm: return early from dm_pr_call() if DM device is suspended + - ath10k: do not enforce interrupt trigger type + - wifi: rtlwifi: fix error codes in rtl_debugfs_set_write_h2c() + - drm/mipi-dbi: align max_chunk to 2 in spi_transfer + - drm/radeon: fix potential buffer overflow in ni_set_mc_special_registers() + - drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff function + - drm: adv7511: override i2c address of cec before accessing it + - i2c: Fix a potential use after free + - media: tw686x: Register the irq at the end of probe + - wifi: iwlegacy: 4965: fix potential off-by-one overflow in + il4965_rs_fill_link_cmd() + - drm: bridge: adv7511: Add check for mipi_dsi_driver_register + - drm/mcde: Fix refcount leak in mcde_dsi_bind + - media: hdpvr: fix error value returns in hdpvr_read + - drm/vc4: plane: Remove subpixel positioning check + - drm/vc4: plane: Fix margin calculations for the right/bottom edges + - drm/vc4: dsi: Correct DSI divider calculations + - crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE + - drm/rockchip: vop: Don't crash for invalid duplicate_state() + - drm/rockchip: Fix an error handling path rockchip_dp_probe() + - drm/mediatek: dpi: Remove output format of YUV + - drm/mediatek: dpi: Only enable dpi after the bridge is enabled + - drm: bridge: sii8620: fix possible off-by-one + - drm/msm/mdp5: Fix global state lock backoff + - crypto: hisilicon - Kunpeng916 crypto driver don't sleep when in softirq + - media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment + - mediatek: mt76: mac80211: Fix missing of_node_put() in mt76_led_init() + - drm/exynos/exynos7_drm_decon: free resources when clk_set_parent() failed. + - tcp: make retransmitted SKB fit into the send window + - libbpf: Fix the name of a reused map + - selftests: timers: valid-adjtimex: build fix for newer toolchains + - selftests: timers: clocksource-switch: fix passing errors from child + - fs: check FMODE_LSEEK to control internal pipe splicing + - wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi() + - wifi: p54: Fix an error handling path in p54spi_probe() + - wifi: p54: add missing parentheses in p54_flush() + - selftests/bpf: fix a test for snprintf() overflow + - can: pch_can: do not report txerr and rxerr during bus-off + - can: rcar_can: do not report txerr and rxerr during bus-off + - can: sja1000: do not report txerr and rxerr during bus-off + - can: hi311x: do not report txerr and rxerr during bus-off + - can: sun4i_can: do not report txerr and rxerr during bus-off + - can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off + - can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off + - can: usb_8dev: do not report txerr and rxerr during bus-off + - can: error: specify the values of data[5..7] of CAN error frames + - can: pch_can: pch_can_error(): initialize errc before using it + - Bluetooth: hci_intel: Add check for platform_driver_register + - i2c: cadence: Support PEC for SMBus block read + - i2c: mux-gpmux: Add of_node_put() when breaking out of loop + - wifi: wil6210: debugfs: fix uninitialized variable use in + `wil_write_file_wmi()` + - wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue + - wifi: libertas: Fix possible refcount leak in if_usb_probe() + - net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS + - crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of + - iavf: Fix max_rate limiting + - netdevsim: Avoid allocation warnings triggered from user space + - net: rose: fix netdev reference changes + - dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same lock + - clk: renesas: r9a06g032: Fix UART clkgrp bitsel + - mtd: maps: Fix refcount leak in of_flash_probe_versatile + - mtd: maps: Fix refcount leak in ap_flash_init + - mtd: rawnand: meson: Fix a potential double free issue + - HID: cp2112: prevent a buffer overflow in cp2112_xfer() + - mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release + - mtd: partitions: Fix refcount leak in parse_redboot_of + - mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()'s error path + - fpga: altera-pr-ip: fix unsigned comparison with less than zero + - usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe + - usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe + - usb: xhci: tegra: Fix error check + - clk: mediatek: reset: Fix written reset bit offset + - misc: rtsx: Fix an error handling path in rtsx_pci_probe() + - driver core: fix potential deadlock in __driver_attach + - clk: qcom: clk-krait: unlock spin after mux completion + - usb: host: xhci: use snprintf() in xhci_decode_trb() + - clk: qcom: ipq8074: fix NSS port frequency tables + - clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks + - clk: qcom: camcc-sdm845: Fix topology around titan_top power domain + - soundwire: bus_type: fix remove and shutdown support + - intel_th: Fix a resource leak in an error handling path + - intel_th: msu-sink: Potential dereference of null pointer + - intel_th: msu: Fix vmalloced buffers + - staging: rtl8192u: Fix sleep in atomic context bug in + dm_fsync_timer_callback + - mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch + - memstick/ms_block: Fix some incorrect memory allocation + - memstick/ms_block: Fix a memory leak + - mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R + - scsi: smartpqi: Fix DMA direction for RAID requests + - usb: gadget: udc: amd5536 depends on HAS_DMA + - RDMA/hns: Fix incorrect clearing of interrupt status register + - RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event + - RDMA/hfi1: fix potential memory leak in setup_base_ctxt() + - gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data() + - mmc: cavium-octeon: Add of_node_put() when breaking out of loop + - mmc: cavium-thunderx: Add of_node_put() when breaking out of loop + - HID: alps: Declare U1_UNICORN_LEGACY support + - PCI: tegra194: Fix Root Port interrupt handling + - PCI: tegra194: Fix link up retry sequence + - USB: serial: fix tty-port initialized comments + - platform/olpc: Fix uninitialized data in debugfs write + - mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region + - RDMA/rxe: Fix error unwind in rxe_create_qp() + - null_blk: fix ida error handling in null_add_dev() + - jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction() + - ext4: recover csum seed of tmp_inode after migrating to extents + - jbd2: fix assertion 'jh->b_frozen_data == NULL' failure when journal aborted + - opp: Fix error check in dev_pm_opp_attach_genpd() + - ASoC: mediatek: mt8173: Fix refcount leak in mt8173_rt5650_rt5676_dev_probe + - ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe + - ASoC: codecs: da7210: add check for i2c_add_driver + - ASoC: mediatek: mt8173-rt5650: Fix refcount leak in mt8173_rt5650_dev_probe + - serial: 8250_dw: Store LSR into lsr_saved_flags in dw8250_tx_wait_empty() + - ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV + - ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV + - profiling: fix shift too large makes kernel panic + - tty: n_gsm: fix non flow control frames during mux flow off + - tty: n_gsm: fix packet re-transmission without open control channel + - tty: n_gsm: fix race condition in gsmld_write() + - remoteproc: qcom: wcnss: Fix handling of IRQs + - vfio/ccw: Do not change FSM state in subchannel event + - tty: n_gsm: fix wrong T1 retry count handling + - tty: n_gsm: fix DM command + - tty: n_gsm: fix missing corner cases in gsmld_poll() + - iommu/exynos: Handle failed IOMMU device registration properly + - rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge + - kfifo: fix kfifo_to_user() return type + - mfd: t7l66xb: Drop platform disable callback + - mfd: max77620: Fix refcount leak in max77620_initialise_fps + - iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of loop + - s390/zcore: fix race when reading from hardware system area + - ASoC: qcom: q6dsp: Fix an off-by-one in q6adm_alloc_copp() + - fuse: Remove the control interface for virtio-fs + - ASoC: audio-graph-card: Add of_node_put() in fail path + - watchdog: armada_37xx_wdt: check the return value of devm_ioremap() in + armada_37xx_wdt_probe() + - video: fbdev: amba-clcd: Fix refcount leak bugs + - video: fbdev: sis: fix typos in SiS_GetModeID() + - powerpc/32: Do not allow selection of e5500 or e6500 CPUs on PPC32 + - powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain' and + alias + - powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader + - powerpc/xive: Fix refcount leak in xive_get_max_prio + - powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address + - perf symbol: Fail to read phdr workaround + - kprobes: Forbid probing on trampoline and BPF code areas + - powerpc/pci: Fix PHB numbering when using opal-phbid + - genelf: Use HAVE_LIBCRYPTO_SUPPORT, not the never defined HAVE_LIBCRYPTO + - scripts/faddr2line: Fix vmlinux detection on arm64 + - x86/numa: Use cpumask_available instead of hardcoded NULL check + - video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock() + - tools/thermal: Fix possible path truncations + - video: fbdev: vt8623fb: Check the size of screen before memset_io() + - video: fbdev: arkfb: Check the size of screen before memset_io() + - video: fbdev: s3fb: Check the size of screen before memset_io() + - scsi: zfcp: Fix missing auto port scan and thus missing target ports + - scsi: qla2xxx: Fix discovery issues in FC-AL topology + - scsi: qla2xxx: Turn off multi-queue for 8G adapters + - scsi: qla2xxx: Fix erroneous mailbox timeout after PCI error injection + - x86/olpc: fix 'logical not is only applied to the left hand side' + - spmi: trace: fix stack-out-of-bound access in SPMI tracing functions + - kexec, KEYS, s390: Make use of built-in and secondary keyring for signature + verification + - tpm: eventlog: Fix section mismatch for DEBUG_SECTION_MISMATCH + - btrfs: reset block group chunk force if we have to wait + - ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h + - ext4: make sure ext4_append() always allocates new block + - ext4: fix use-after-free in ext4_xattr_set_entry + - ext4: update s_overhead_clusters in the superblock during an on-line resize + - ext4: fix extent status tree race in writeback error recovery path + - ext4: correct max_inline_xattr_value_size computing + - ext4: correct the misjudgment in ext4_iget_extra_inode + - intel_th: pci: Add Raptor Lake-S CPU support + - intel_th: pci: Add Raptor Lake-S PCH support + - intel_th: pci: Add Meteor Lake-P support + - dm raid: fix address sanitizer warning in raid_resume + - dm raid: fix address sanitizer warning in raid_status + - dm thin: fix use-after-free crash in dm_sm_register_threshold_callback + - dm writecache: set a default MAX_WRITEBACK_JOBS + - ACPI: CPPC: Do not prevent CPPC from working in the future + - timekeeping: contribute wall clock to rng on time change + - firmware: arm_scpi: Ensure scpi_info is not assigned if the probe fails + - iommu/vt-d: avoid invalid memory access via node_online(NUMA_NO_NODE) + - btrfs: reject log replay if there is unsupported RO compat flag + - KVM: Add infrastructure and macro to mark VM as bugged + - KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq + - KVM: x86: Avoid theoretical NULL pointer dereference in + kvm_irq_delivery_to_apic_fast() + - tcp: fix over estimation in sk_forced_mem_schedule() + - scsi: sg: Allow waiting for commands to complete on removed device + - Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression + - net/9p: Initialize the iounit field during fid creation + - net_sched: cls_route: disallow handle of 0 + - ALSA: info: Fix llseek return value when using callback + - rds: add missing barrier to release_refill + - ata: libata-eh: Add missing command name + - mmc: pxamci: Fix another error handling path in pxamci_probe() + - mmc: pxamci: Fix an error handling path in pxamci_probe() + - btrfs: fix lost error handling when looking up extended ref on log replay + - tracing: Have filter accept "common_cpu" to be consistent + - can: ems_usb: fix clang's -Wunaligned-access warning + - apparmor: fix quiet_denied for file rules + - apparmor: fix absroot causing audited secids to begin with = + - apparmor: Fix failed mount permission check error message + - apparmor: fix aa_label_asxprint return check + - apparmor: fix overlapping attachment computation + - apparmor: fix reference count leak in aa_pivotroot() + - apparmor: Fix memleak in aa_simple_write_to_buffer() + - Documentation: ACPI: EINJ: Fix obsolete example + - NFSv4.1: Don't decrease the value of seq_nr_highest_sent + - NFSv4.1: Handle NFS4ERR_DELAY replies to OP_SEQUENCE correctly + - NFSv4: Fix races in the legacy idmapper upcall + - NFSv4.1: RECLAIM_COMPLETE must handle EACCES + - NFSv4/pnfs: Fix a use-after-free bug in open + - can: mcp251x: Fix race condition on receive interrupt + - sunrpc: fix expiry of auth creds + - SUNRPC: Reinitialise the backchannel request buffers before reuse + - devlink: Fix use-after-free after a failed reload + - net: bgmac: Fix a BUG triggered by wrong bytes_compl + - pinctrl: nomadik: Fix refcount leak in nmk_pinctrl_dt_subnode_to_map + - pinctrl: qcom: msm8916: Allow CAMSS GP clocks to be muxed + - pinctrl: sunxi: Add I/O bias setting for H6 R-PIO + - ACPI: property: Return type of acpi_add_nondev_subnodes() should be bool + - geneve: do not use RT_TOS for IPv6 flowlabel + - plip: avoid rcu debug splat + - vsock: Fix memory leak in vsock_connect() + - vsock: Set socket state back to SS_UNCONNECTED in vsock_connect_timeout() + - dt-bindings: arm: qcom: fix MSM8916 MTP compatibles + - tools/vm/slabinfo: use alphabetic order when two values are equal + - tools build: Switch to new openssl API for test-libcrypto + - NTB: ntb_tool: uninitialized heap data in tool_fn_write() + - nfp: ethtool: fix the display error of `ethtool -m DEVNAME` + - xen/xenbus: fix return type in xenbus_file_read() + - atm: idt77252: fix use-after-free bugs caused by tst_timer + - dpaa2-eth: trace the allocated address instead of page struct + - tee: add overflow check in register_shm_helper() + - nios2: page fault et.al. are *not* restartable syscalls... + - nios2: don't leave NULLs in sys_call_table[] + - nios2: traced syscall does need to check the syscall number + - nios2: fix syscall restart checks + - nios2: restarts apply only to the first sigframe we build... + - nios2: add force_successful_syscall_return() + - iavf: Fix adminq error handling + - clk: rockchip: add sclk_mac_lbtest to rk3188_critical_clocks + - netfilter: nf_tables: really skip inactive sets when allocating name + - powerpc/pci: Fix get_phb_number() locking + - net: dsa: mv88e6060: prevent crash on an unused port + - net: moxa: pass pdev instead of ndev to DMA functions + - net: dsa: microchip: ksz9477: fix fdb_dump last invalid entry + - ice: Ignore EEXIST when setting promisc mode + - i40e: Fix to stop tx_timeout recovery if GLOBR fails + - fec: Fix timer capture timing in `fec_ptp_enable_pps()` + - igb: Add lock to avoid data race + - gcc-plugins: Undefine LATENT_ENTROPY_PLUGIN when plugin disabled for a file + - locking/atomic: Make test_and_*_bit() ordered on failure + - drm/meson: Fix refcount bugs in meson_vpu_has_available_connectors() + - PCI: Add ACS quirk for Broadcom BCM5750x NICs + - usb: cdns3 fix use-after-free at workaround 2 + - usb: gadget: uvc: call uvc uvcg_warn on completed status instead of + uvcg_info + - irqchip/tegra: Fix overflow implicit truncation warnings + - drm/meson: Fix overflow implicit truncation warnings + - usb: host: ohci-ppc-of: Fix refcount leak bug + - usb: renesas: Fix refcount leak bug + - vboxguest: Do not use devm for irq + - clk: qcom: ipq8074: dont disable gcc_sleep_clk_src + - scsi: lpfc: Prevent buffer overflow crashes in debugfs with malformed user + input + - gadgetfs: ep_io - wait until IRQ finishes + - cxl: Fix a memory leak in an error handling path + - PCI/ACPI: Guard ARM64-specific mcfg_quirks + - um: add "noreboot" command line option for PANIC_TIMEOUT=-1 setups + - selftests/kprobe: Do not test for GRP/ without event failures + - dmaengine: sprd: Cleanup in .remove() after pm_runtime_get_sync() failed + - nvmet-tcp: fix lockdep complaint on nvmet_tcp_wq flush during queue teardown + - drivers:md:fix a potential use-after-free bug + - ext4: avoid remove directory when directory is corrupted + - ext4: avoid resizing to a partial cluster size + - lib/list_debug.c: Detect uninitialized lists + - tty: serial: Fix refcount leak bug in ucc_uart.c + - vfio: Clear the caps->buf to NULL after free + - mips: cavium-octeon: Fix missing of_node_put() in octeon2_usb_clocks_start + - riscv: mmap with PROT_WRITE but no PROT_READ is invalid + - RISC-V: Add fast call path of crash_kexec() + - watchdog: export lockup_detector_reconfigure + - powerpc/32: Don't always pass -mcpu=powerpc to the compiler + - ALSA: core: Add async signal helpers + - ALSA: timer: Use deferred fasync helper + - f2fs: fix to avoid use f2fs_bug_on() in f2fs_new_node_page() + - smb3: check xattr value length earlier + - powerpc/64: Init jump labels before parse_early_param() + - video: fbdev: i740fb: Check the argument of i740_calc_vclk() + - MIPS: tlbex: Explicitly compare _PAGE_NO_EXEC against 0 + - tracing/probes: Have kprobes and uprobes use $COMM too + - can: j1939: j1939_sk_queue_activate_next_locked(): replace WARN_ON_ONCE with + netdev_warn_once() + - can: j1939: j1939_session_destroy(): fix memory leak of skbs + - btrfs: only write the sectors in the vertical stripe which has data stripes + - btrfs: raid56: don't trust any cached sector in __raid56_parity_recover() + - Linux 5.4.211 + * CVE-2022-3028 + - af_key: Do not call xfrm_probe_algs in parallel + * CVE-2022-2978 + - fs: fix UAF/GPF bug in nilfs_mdt_destroy + * CVE-2022-40768 + - scsi: stex: Properly zero out the passthrough command structure + + -- Joseph Salisbury Wed, 19 Oct 2022 14:20:00 -0400 + +linux-oracle (5.4.0-1086.95) focal; urgency=medium + + [ Ubuntu: 5.4.0-131.147 ] + + * CVE-2022-2602 + - SAUCE: io_uring/af_unix: defer registered files gc to io_uring release + - SAUCE: io_uring/af_unix: fix memleak during unix GC + * CVE-2022-41674 + - SAUCE: wifi: cfg80211: fix u8 overflow in + cfg80211_update_notlisted_nontrans() + - SAUCE: wifi: cfg80211/mac80211: reject bad MBSSID elements + - SAUCE: wifi: cfg80211: ensure length byte is present before access + - SAUCE: wifi: mac80211_hwsim: avoid mac80211 warning on bad rate + - SAUCE: wifi: cfg80211: update hidden BSSes to avoid WARN_ON + * CVE-2022-42721 + - SAUCE: wifi: cfg80211: avoid nontransmitted BSS list corruption + * CVE-2022-42720 + - SAUCE: wifi: cfg80211: fix BSS refcounting bugs + + -- Thadeu Lima de Souza Cascardo Mon, 17 Oct 2022 00:32:23 -0300 + +linux-oracle (5.4.0-1084.92) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1084.92 -proposed tracker (LP: #1989882) + + [ Ubuntu: 5.4.0-128.144 ] + + * focal/linux: 5.4.0-128.144 -proposed tracker (LP: #1990152) + * CVE-2022-3176 + - io_uring: disable polling pollfree files + * ip/nexthop: fix default address selection for connected nexthop + (LP: #1988809) + - selftests/net: test nexthop without gw + * ip/nexthop: fix default address selection for connected nexthop + (LP: #1988809) // icmp_redirect.sh in ubuntu_kernel_selftests failed on + Jammy 5.15.0-49.55 (LP: #1990124) + - ip: fix triggering of 'icmp redirect' + + [ Ubuntu: 5.4.0-127.143 ] + + * focal/linux: 5.4.0-127.143 -proposed tracker (LP: #1989892) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.09.19) + * [UBUNTU 20.04] mlx5 driver crashes on accessing device attributes during + recovery (LP: #1987287) + - net/mlx5: Avoid processing commands before cmdif is ready + * Focal update: v5.4.210 upstream stable release (LP: #1989230) + - thermal: Fix NULL pointer dereferences in of_thermal_ functions + - ACPI: video: Force backlight native for some TongFang devices + - ACPI: video: Shortening quirk list by identifying Clevo by board_name only + - ACPI: APEI: Better fix to avoid spamming the console with old error logs + - bpf: Verifer, adjust_scalar_min_max_vals to always call update_reg_bounds() + - selftests/bpf: Extend verifier and bpf_sock tests for dst_port loads + - bpf: Test_verifier, #70 error message updates for 32-bit right shift + - KVM: Don't null dereference ops->destroy + - selftests: KVM: Handle compiler optimizations in ucall + - media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls + - macintosh/adb: fix oob read in do_adb_query() function + - x86/speculation: Add RSB VM Exit protections + - x86/speculation: Add LFENCE to RSB fill sequence + - Linux 5.4.210 + * Focal update: v5.4.209 upstream stable release (LP: #1989228) + - Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put + - ntfs: fix use-after-free in ntfs_ucsncmp() + - s390/archrandom: prevent CPACF trng invocations in interrupt context + - tcp: Fix data-races around sysctl_tcp_dsack. + - tcp: Fix a data-race around sysctl_tcp_app_win. + - tcp: Fix a data-race around sysctl_tcp_adv_win_scale. + - tcp: Fix a data-race around sysctl_tcp_frto. + - tcp: Fix a data-race around sysctl_tcp_nometrics_save. + - ice: check (DD | EOF) bits on Rx descriptor rather than (EOP | RS) + - ice: do not setup vlan for loopback VSI + - scsi: ufs: host: Hold reference returned by of_parse_phandle() + - tcp: Fix a data-race around sysctl_tcp_limit_output_bytes. + - tcp: Fix a data-race around sysctl_tcp_challenge_ack_limit. + - net: ping6: Fix memleak in ipv6_renew_options(). + - ipv6/addrconf: fix a null-ptr-deref bug for ip6_ptr + - igmp: Fix data-races around sysctl_igmp_qrv. + - net: sungem_phy: Add of_node_put() for reference returned by of_get_parent() + - tcp: Fix a data-race around sysctl_tcp_min_tso_segs. + - tcp: Fix a data-race around sysctl_tcp_min_rtt_wlen. + - tcp: Fix a data-race around sysctl_tcp_autocorking. + - tcp: Fix a data-race around sysctl_tcp_invalid_ratelimit. + - Documentation: fix sctp_wmem in ip-sysctl.rst + - tcp: Fix a data-race around sysctl_tcp_comp_sack_delay_ns. + - tcp: Fix a data-race around sysctl_tcp_comp_sack_nr. + - i40e: Fix interface init with MSI interrupts (no MSI-X) + - sctp: fix sleep in atomic context bug in timer handlers + - virtio-net: fix the race between refill work and close + - perf symbol: Correct address for bss symbols + - sfc: disable softirqs for ptp TX + - sctp: leave the err path free in sctp_stream_init to sctp_stream_free + - ARM: crypto: comment out gcc warning that breaks clang builds + - mt7601u: add USB device ID for some versions of XiaoDu WiFi Dongle. + - scsi: core: Fix race between handling STS_RESOURCE and completion + - Linux 5.4.209 + * Focal update: v5.4.208 upstream stable release (LP: #1988225) + - pinctrl: stm32: fix optional IRQ support to gpios + - riscv: add as-options for modules with assembly compontents + - mlxsw: spectrum_router: Fix IPv4 nexthop gateway indication + - lockdown: Fix kexec lockdown bypass with ima policy + - xen/gntdev: Ignore failure to unmap INVALID_GRANT_HANDLE + - PCI: hv: Fix multi-MSI to allow more than one MSI vector + - PCI: hv: Fix hv_arch_irq_unmask() for multi-MSI + - PCI: hv: Reuse existing IRTE allocation in compose_msi_msg() + - PCI: hv: Fix interrupt mapping for multi-MSI + - serial: mvebu-uart: correctly report configured baudrate value + - xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in + xfrm_bundle_lookup() + - power/reset: arm-versatile: Fix refcount leak in versatile_reboot_probe + - pinctrl: ralink: Check for null return of devm_kcalloc + - perf/core: Fix data race between perf_event_set_output() and + perf_mmap_close() + - igc: Reinstate IGC_REMOVED logic and implement it properly + - ip: Fix data-races around sysctl_ip_no_pmtu_disc. + - ip: Fix data-races around sysctl_ip_fwd_use_pmtu. + - ip: Fix data-races around sysctl_ip_nonlocal_bind. + - ip: Fix a data-race around sysctl_fwmark_reflect. + - tcp/dccp: Fix a data-race around sysctl_tcp_fwmark_accept. + - tcp: Fix data-races around sysctl_tcp_mtu_probing. + - tcp: Fix data-races around sysctl_tcp_base_mss. + - tcp: Fix data-races around sysctl_tcp_min_snd_mss. + - tcp: Fix a data-race around sysctl_tcp_mtu_probe_floor. + - tcp: Fix a data-race around sysctl_tcp_probe_threshold. + - tcp: Fix a data-race around sysctl_tcp_probe_interval. + - i2c: cadence: Change large transfer count reset logic to be unconditional + - net: stmmac: fix dma queue left shift overflow issue + - net/tls: Fix race in TLS device down flow + - igmp: Fix data-races around sysctl_igmp_llm_reports. + - igmp: Fix a data-race around sysctl_igmp_max_memberships. + - tcp: Fix data-races around sysctl_tcp_syncookies. + - tcp: Fix data-races around sysctl_tcp_reordering. + - tcp: Fix data-races around some timeout sysctl knobs. + - tcp: Fix a data-race around sysctl_tcp_notsent_lowat. + - tcp: Fix a data-race around sysctl_tcp_tw_reuse. + - tcp: Fix data-races around sysctl_max_syn_backlog. + - tcp: Fix data-races around sysctl_tcp_fastopen. + - iavf: Fix handling of dummy receive descriptors + - i40e: Fix erroneous adapter reinitialization during recovery process + - ixgbe: Add locking to prevent panic when setting sriov_numvfs to zero + - gpio: pca953x: only use single read/write for No AI mode + - be2net: Fix buffer overflow in be_get_module_eeprom + - ipv4: Fix a data-race around sysctl_fib_multipath_use_neigh. + - udp: Fix a data-race around sysctl_udp_l3mdev_accept. + - tcp: Fix data-races around sysctl knobs related to SYN option. + - tcp: Fix a data-race around sysctl_tcp_early_retrans. + - tcp: Fix data-races around sysctl_tcp_recovery. + - tcp: Fix a data-race around sysctl_tcp_thin_linear_timeouts. + - tcp: Fix data-races around sysctl_tcp_slow_start_after_idle. + - tcp: Fix a data-race around sysctl_tcp_retrans_collapse. + - tcp: Fix a data-race around sysctl_tcp_stdurg. + - tcp: Fix a data-race around sysctl_tcp_rfc1337. + - tcp: Fix data-races around sysctl_tcp_max_reordering. + - spi: bcm2835: bcm2835_spi_handle_err(): fix NULL pointer deref for non DMA + transfers + - mm/mempolicy: fix uninit-value in mpol_rebind_policy() + - bpf: Make sure mac_header was set before using it + - dlm: fix pending remove if msg allocation fails + - ima: remove the IMA_TEMPLATE Kconfig option + - [Config] updateconfigs for IMA_TEMPLATE + - locking/refcount: Define constants for saturation and max refcount values + - locking/refcount: Ensure integer operands are treated as signed + - locking/refcount: Remove unused refcount_*_checked() variants + - locking/refcount: Move the bulk of the REFCOUNT_FULL implementation into the + header + - locking/refcount: Improve performance of generic REFCOUNT_FULL code + - locking/refcount: Move saturation warnings out of line + - locking/refcount: Consolidate REFCOUNT_{MAX,SATURATED} definitions + - locking/refcount: Consolidate implementations of refcount_t + - [Config] updateconfigs for REFCOUNT_FULL + - x86: get rid of small constant size cases in raw_copy_{to,from}_user() + - x86/uaccess: Implement macros for CMPXCHG on user addresses + - mmap locking API: initial implementation as rwsem wrappers + - x86/mce: Deduplicate exception handling + - bitfield.h: Fix "type of reg too small for mask" test + - ALSA: memalloc: Align buffer allocations in page size + - Bluetooth: Add bt_skb_sendmsg helper + - Bluetooth: Add bt_skb_sendmmsg helper + - Bluetooth: SCO: Replace use of memcpy_from_msg with bt_skb_sendmsg + - Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg + - Bluetooth: Fix passing NULL to PTR_ERR + - Bluetooth: SCO: Fix sco_send_frame returning skb->len + - Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks + - tty: drivers/tty/, stop using tty_schedule_flip() + - tty: the rest, stop using tty_schedule_flip() + - tty: drop tty_schedule_flip() + - tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push() + - tty: use new tty_insert_flip_string_and_push_buffer() in pty_write() + - x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm() + - Linux 5.4.208 + * Focal update: v5.4.207 upstream stable release (LP: #1988219) + - ALSA: hda - Add fixup for Dell Latitidue E5430 + - ALSA: hda/conexant: Apply quirk for another HP ProDesk 600 G3 model + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671 + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc221 + - ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop + - xen/netback: avoid entering xenvif_rx_next_skb() with an empty rx queue + - tracing/histograms: Fix memory leak problem + - net: sock: tracing: Fix sock_exceed_buf_limit not to dereference stale + pointer + - ip: fix dflt addr selection for connected nexthop + - ARM: 9213/1: Print message about disabled Spectre workarounds only once + - ARM: 9214/1: alignment: advance IT state after emulating Thumb instruction + - wifi: mac80211: fix queue selection for mesh/OCB interfaces + - cgroup: Use separate src/dst nodes when preloading css_sets for migration + - drm/panfrost: Fix shrinker list corruption by madvise IOCTL + - nilfs2: fix incorrect masking of permission flags for symlinks + - Revert "evm: Fix memleak in init_desc" + - sched/rt: Disable RT_RUNTIME_SHARE by default + - ext4: fix race condition between ext4_write and ext4_convert_inline_data + - ARM: dts: imx6qdl-ts7970: Fix ngpio typo and count + - ARM: 9209/1: Spectre-BHB: avoid pr_info() every time a CPU comes out of idle + - ARM: 9210/1: Mark the FDT_FIXED sections as shareable + - drm/i915: fix a possible refcount leak in intel_dp_add_mst_connector() + - ima: Fix a potential integer overflow in ima_appraise_measurement + - ASoC: sgtl5000: Fix noise on shutdown/remove + - net: stmmac: dwc-qos: Disable split header for Tegra194 + - inetpeer: Fix data-races around sysctl. + - net: Fix data-races around sysctl_mem. + - cipso: Fix data-races around sysctl. + - icmp: Fix data-races around sysctl. + - ipv4: Fix a data-race around sysctl_fib_sync_mem. + - ARM: dts: at91: sama5d2: Fix typo in i2s1 node + - ARM: dts: sunxi: Fix SPI NOR campatible on Orange Pi Zero + - drm/i915/gt: Serialize TLB invalidates with GT resets + - icmp: Fix a data-race around sysctl_icmp_ratelimit. + - icmp: Fix a data-race around sysctl_icmp_ratemask. + - raw: Fix a data-race around sysctl_raw_l3mdev_accept. + - ipv4: Fix data-races around sysctl_ip_dynaddr. + - net: ftgmac100: Hold reference returned by of_get_child_by_name() + - sfc: fix use after free when disabling sriov + - seg6: fix skb checksum evaluation in SRH encapsulation/insertion + - seg6: fix skb checksum in SRv6 End.B6 and End.B6.Encaps behaviors + - seg6: bpf: fix skb checksum in bpf_push_seg6_encap() + - sfc: fix kernel panic when creating VF + - mm: sysctl: fix missing numa_stat when !CONFIG_HUGETLB_PAGE + - virtio_mmio: Add missing PM calls to freeze/restore + - virtio_mmio: Restore guest page size on resume + - netfilter: br_netfilter: do not skip all hooks with 0 priority + - cpufreq: pmac32-cpufreq: Fix refcount leak bug + - platform/x86: hp-wmi: Ignore Sanitization Mode event + - net: tipc: fix possible refcount leak in tipc_sk_create() + - NFC: nxp-nci: don't print header length mismatch on i2c error + - nvme: fix regression when disconnect a recovering ctrl + - net: sfp: fix memory leak in sfp_probe() + - ASoC: ops: Fix off by one in range control validation + - ASoC: wm5110: Fix DRE control + - ASoC: cs47l15: Fix event generation for low power mux control + - ASoC: madera: Fix event generation for OUT1 demux + - ASoC: madera: Fix event generation for rate controls + - irqchip: or1k-pic: Undefine mask_ack for level triggered hardware + - x86: Clear .brk area at early boot + - soc: ixp4xx/npe: Fix unused match warning + - ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 + - signal handling: don't use BUG_ON() for debugging + - USB: serial: ftdi_sio: add Belimo device ids + - usb: typec: add missing uevent when partner support PD + - usb: dwc3: gadget: Fix event pending check + - tty: serial: samsung_tty: set dma burst_size to 1 + - serial: 8250: fix return error code in serial8250_request_std_resource() + - serial: stm32: Clear prev values before setting RTS delays + - serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle + - can: m_can: m_can_tx_handler(): fix use after free of skb + - Linux 5.4.207 + * Focal update: v5.4.206 upstream stable release (LP: #1988215) + - Linux 5.4.206 + * Focal update: v5.4.205 upstream stable release (LP: #1988214) + - esp: limit skb_page_frag_refill use to a single page + - mm/slub: add missing TID updates on slab deactivation + - can: bcm: use call_rcu() instead of costly synchronize_rcu() + - can: grcan: grcan_probe(): remove extra of_node_get() + - can: gs_usb: gs_usb_open/close(): fix memory leak + - usbnet: fix memory leak in error case + - net: rose: fix UAF bug caused by rose_t0timer_expiry + - iommu/vt-d: Fix PCI bus rescan device hot add + - fbdev: fbmem: Fix logo center image dx issue + - video: of_display_timing.h: include errno.h + - powerpc/powernv: delay rng platform device creation until later in boot + - can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info + - can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression + - can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits + - xfs: remove incorrect ASSERT in xfs_rename + - ARM: meson: Fix refcount leak in meson_smp_prepare_cpus + - pinctrl: sunxi: a83t: Fix NAND function name for some pins + - pinctrl: sunxi: sunxi_pconf_set: use correct offset + - ARM: at91: pm: use proper compatible for sama5d2's rtc + - ARM: at91: pm: use proper compatibles for sam9x60's rtc and rtt + - ibmvnic: Properly dispose of all skbs during a failover. + - selftests: forwarding: fix flood_unicast_test when h2 supports + IFF_UNICAST_FLT + - selftests: forwarding: fix learning_test when h1 supports IFF_UNICAST_FLT + - selftests: forwarding: fix error message in learning_test + - i2c: cadence: Unregister the clk notifier in error path + - dmaengine: imx-sdma: Allow imx8m for imx7 FW revs + - misc: rtsx_usb: fix use of dma mapped buffer for usb bulk transfer + - misc: rtsx_usb: use separate command and response buffers + - misc: rtsx_usb: set return value in rsp_buf alloc err path + - dt-bindings: dma: allwinner,sun50i-a64-dma: Fix min/max typo + - ida: don't use BUG_ON() for debugging + - dmaengine: pl330: Fix lockdep warning about non-static key + - dmaengine: at_xdma: handle errors of at_xdmac_alloc_desc() correctly + - dmaengine: ti: Fix refcount leak in ti_dra7_xbar_route_allocate + - dmaengine: ti: Add missing put_device in ti_dra7_xbar_route_allocate + - Linux 5.4.205 + * Focal update: v5.4.204 upstream stable release (LP: #1988212) + - ipv6: take care of disable_policy when restoring routes + - nvdimm: Fix badblocks clear off-by-one error + - powerpc/prom_init: Fix kernel config grep + - powerpc/bpf: Fix use of user_pt_regs in uapi + - dm raid: fix accesses beyond end of raid member array + - dm raid: fix KASAN warning in raid5_add_disks + - s390/archrandom: simplify back to earlier design and initialize earlier + - SUNRPC: Fix READ_PLUS crasher + - net: rose: fix UAF bugs caused by timer handler + - net: usb: ax88179_178a: Fix packet receiving + - virtio-net: fix race between ndo_open() and virtio_device_ready() + - selftests/net: pass ipv6_args to udpgso_bench's IPv6 TCP test + - net: tun: unlink NAPI from device on destruction + - net: tun: stop NAPI when detaching queues + - RDMA/qedr: Fix reporting QP timeout attribute + - linux/dim: Fix divide by 0 in RDMA DIM + - usbnet: fix memory allocation in helpers + - net: ipv6: unexport __init-annotated seg6_hmac_net_init() + - caif_virtio: fix race between virtio_device_ready() and ndo_open() + - PM / devfreq: exynos-ppmu: Fix refcount leak in of_get_devfreq_events + - s390: remove unneeded 'select BUILD_BIN2C' + - netfilter: nft_dynset: restore set element counter when failing to update + - net/sched: act_api: Notify user space if any actions were flushed before + error + - net: bonding: fix possible NULL deref in rlb code + - net: bonding: fix use-after-free after 802.3ad slave unbind + - nfc: nfcmrvl: Fix irq_of_parse_and_map() return value + - NFC: nxp-nci: Don't issue a zero length i2c_master_read() + - net: tun: avoid disabling NAPI twice + - xen/gntdev: Avoid blocking in unmap_grant_pages() + - hwmon: (ibmaem) don't call platform_device_del() if platform_device_add() + fails + - net: dsa: bcm_sf2: force pause link settings + - sit: use min + - ipv6/sit: fix ipip6_tunnel_get_prl return value + - rseq/selftests,x86_64: Add rseq_offset_deref_addv() + - selftests/rseq: remove ARRAY_SIZE define from individual tests + - selftests/rseq: introduce own copy of rseq uapi header + - selftests/rseq: Remove useless assignment to cpu variable + - selftests/rseq: Remove volatile from __rseq_abi + - selftests/rseq: Introduce rseq_get_abi() helper + - selftests/rseq: Introduce thread pointer getters + - selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35 + - selftests/rseq: Fix ppc32: wrong rseq_cs 32-bit field pointer on big endian + - selftests/rseq: Fix ppc32 missing instruction selection "u" and "x" for + load/store + - selftests/rseq: Fix ppc32 offsets by using long rather than off_t + - selftests/rseq: Fix warnings about #if checks of undefined tokens + - selftests/rseq: Remove arm/mips asm goto compiler work-around + - selftests/rseq: Fix: work-around asm goto compiler bugs + - selftests/rseq: x86-64: use %fs segment selector for accessing rseq thread + area + - selftests/rseq: x86-32: use %gs segment selector for accessing rseq thread + area + - selftests/rseq: Change type of rseq_offset to ptrdiff_t + - xen/blkfront: fix leaking data in shared pages + - xen/netfront: fix leaking data in shared pages + - xen/netfront: force data bouncing when backend is untrusted + - xen/blkfront: force data bouncing when backend is untrusted + - xen/arm: Fix race in RB-tree based P2M accounting + - net: usb: qmi_wwan: add Telit 0x1060 composition + - net: usb: qmi_wwan: add Telit 0x1070 composition + - clocksource/drivers/ixp4xx: remove EXPORT_SYMBOL_GPL from + ixp4xx_timer_setup() + - Linux 5.4.204 + + -- Joseph Salisbury Wed, 21 Sep 2022 14:35:10 -0400 + +linux-oracle (5.4.0-1083.91) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1083.91 -proposed tracker (LP: #1987809) + + [ Ubuntu: 5.4.0-126.142 ] + + * focal/linux: 5.4.0-126.142 -proposed tracker (LP: #1987819) + * [SRU] fnic driver on needs to be updated to 1.6.0.53 on Focal (LP: #1984011) + - scsi: fnic: Change shost_printk() to FNIC_FCS_DBG() + - scsi: fnic: Avoid looping in TRANS ETH on unload + - scsi: fnic: Change shost_printk() to FNIC_MAIN_DBG() + - scsi: fnic: Set scsi_set_resid() only for underflow + - scsi: fnic: Validate io_req before others + * Focal update: v5.4.203 upstream stable release (LP: #1986999) + - drm: remove drm_fb_helper_modinit + - powerpc/ftrace: Remove ftrace init tramp once kernel init is complete + - kexec_file: drop weak attribute from arch_kexec_apply_relocations[_add] + - net: mscc: ocelot: allow unregistered IP multicast flooding + - ARM: 8989/1: use .fpu assembler directives instead of assembler arguments + - ARM: 8990/1: use VFP assembler mnemonics in register load/store macros + - ARM: 8971/1: replace the sole use of a symbol with its definition + - crypto: arm/sha256-neon - avoid ADRL pseudo instruction + - crypto: arm/sha512-neon - avoid ADRL pseudo instruction + - ARM: 8933/1: replace Sun/Solaris style flag on section directive + - ARM: 8929/1: use APSR_nzcv instead of r15 as mrc operand + - ARM: OMAP2+: drop unnecessary adrl + - ARM: 9029/1: Make iwmmxt.S support Clang's integrated assembler + - crypto: arm - use Kconfig based compiler checks for crypto opcodes + - crypto: arm/ghash-ce - define fpu before fpu registers are referenced + - Linux 5.4.203 + * Focal update: v5.4.202 upstream stable release (LP: #1986995) + - random: schedule mix_interrupt_randomness() less often + - ALSA: hda/via: Fix missing beep setup + - ALSA: hda/conexant: Fix missing beep setup + - ALSA: hda/realtek - ALC897 headset MIC no sound + - ALSA: hda/realtek: Add quirk for Clevo PD70PNT + - net: openvswitch: fix parsing of nw_proto for IPv6 fragments + - mmc: sdhci-pci-o2micro: Fix card detect by dealing with debouncing + - ata: libata: add qc->flags in ata_qc_complete_template tracepoint + - dm era: commit metadata in postsuspend after worker stops + - dm mirror log: clear log bits up to BITS_PER_LONG boundary + - random: quiet urandom warning ratelimit suppression message + - USB: serial: option: add Telit LE910Cx 0x1250 composition + - USB: serial: option: add Quectel EM05-G modem + - USB: serial: option: add Quectel RM500K module support + - bpf: Fix request_sock leak in sk lookup helpers + - phy: aquantia: Fix AN when higher speeds than 1G are not advertised + - bonding: ARP monitor spams NETDEV_NOTIFY_PEERS notifiers + - net/sched: sch_netem: Fix arithmetic in netem_dump() for 32-bit platforms + - drm/msm/mdp4: Fix refcount leak in mdp4_modeset_init_intf + - erspan: do not assume transport header is always set + - net/tls: fix tls_sk_proto_close executed repeatedly + - udmabuf: add back sanity check + - x86/xen: Remove undefined behavior in setup_features() + - MIPS: Remove repetitive increase irq_err_count + - afs: Fix dynamic root getattr + - ice: ethtool: advertise 1000M speeds properly + - regmap-irq: Fix a bug in regmap_irq_enable() for type_in_mask chips + - igb: Make DMA faster when CPU is active on the PCIe link + - virtio_net: fix xdp_rxq_info bug after suspend/resume + - Revert "net/tls: fix tls_sk_proto_close executed repeatedly" + - gpio: winbond: Fix error code in winbond_gpio_get() + - s390/cpumf: Handle events cycles and instructions identical + - iio: adc: vf610: fix conversion mode sysfs node name + - xhci: turn off port power in shutdown + - usb: chipidea: udc: check request status before setting device address + - iio:chemical:ccs811: rearrange iio trigger get and register + - iio:accel:bma180: rearrange iio trigger get and register + - iio:accel:mxc4005: rearrange iio trigger get and register + - iio: accel: mma8452: ignore the return value of reset operation + - iio: gyro: mpu3050: Fix the error handling in mpu3050_power_up() + - iio: trigger: sysfs: fix use-after-free on remove + - iio: adc: stm32: fix maximum clock rate for stm32mp15x + - iio: adc: axp288: Override TS pin bias current for some models + - xtensa: xtfpga: Fix refcount leak bug in setup + - xtensa: Fix refcount leak bug in time.c + - parisc: Enable ARCH_HAS_STRICT_MODULE_RWX + - powerpc: Enable execve syscall exit tracepoint + - powerpc/rtas: Allow ibm,platform-dump RTAS call with null buffer address + - powerpc/powernv: wire up rng during setup_arch + - ARM: dts: imx6qdl: correct PU regulator ramp delay + - ARM: exynos: Fix refcount leak in exynos_map_pmu + - soc: bcm: brcmstb: pm: pm-arm: Fix refcount leak in brcmstb_pm_probe + - ARM: Fix refcount leak in axxia_boot_secondary + - ARM: cns3xxx: Fix refcount leak in cns3xxx_init + - modpost: fix section mismatch check for exported init/exit sections + - random: update comment from copy_to_user() -> copy_to_iter() + - kbuild: link vmlinux only once for CONFIG_TRIM_UNUSED_KSYMS (2nd attempt) + - powerpc/pseries: wire up rng during setup_arch() + - Linux 5.4.202 + * Focal update: v5.4.201 upstream stable release (LP: #1986993) + - dm: remove special-casing of bio-based immutable singleton target on NVMe + - usb: gadget: u_ether: fix regression in setting fixed MAC address + - tcp: add some entropy in __inet_hash_connect() + - tcp: use different parts of the port_offset for index and offset + - tcp: add small random increments to the source port + - tcp: dynamically allocate the perturb table used by source ports + - tcp: increase source port perturb table to 2^16 + - tcp: drop the hash_32() part from the index calculation + - arm64: mm: Don't invalidate FROM_DEVICE buffers at start of DMA transfer + - Linux 5.4.201 + * Focal update: v5.4.200 upstream stable release (LP: #1983152) + - Revert "UBUNTU: SAUCE: random: Make getrandom() ready earlier" + - 9p: missing chunk of "fs/9p: Don't update file type when updating file + attributes" + - bpf: Fix incorrect memory charge cost calculation in stack_map_alloc() + - nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION + - crypto: blake2s - generic C library implementation and selftest + - lib/crypto: blake2s: move hmac construction into wireguard + - lib/crypto: sha1: re-roll loops to reduce code size + - compat_ioctl: remove /dev/random commands + - random: don't forget compat_ioctl on urandom + - random: Don't wake crng_init_wait when crng_init == 1 + - random: Add a urandom_read_nowait() for random APIs that don't warn + - random: add GRND_INSECURE to return best-effort non-cryptographic bytes + - random: ignore GRND_RANDOM in getentropy(2) + - random: make /dev/random be almost like /dev/urandom + - random: remove the blocking pool + - random: delete code to pull data into pools + - random: remove kernel.random.read_wakeup_threshold + - random: remove unnecessary unlikely() + - random: convert to ENTROPY_BITS for better code readability + - random: Add and use pr_fmt() + - random: fix typo in add_timer_randomness() + - random: remove some dead code of poolinfo + - random: split primary/secondary crng init paths + - random: avoid warnings for !CONFIG_NUMA builds + - x86: Remove arch_has_random, arch_has_random_seed + - powerpc: Remove arch_has_random, arch_has_random_seed + - s390: Remove arch_has_random, arch_has_random_seed + - linux/random.h: Remove arch_has_random, arch_has_random_seed + - linux/random.h: Use false with bool + - linux/random.h: Mark CONFIG_ARCH_RANDOM functions __must_check + - powerpc: Use bool in archrandom.h + - random: add arch_get_random_*long_early() + - random: avoid arch_get_random_seed_long() when collecting IRQ randomness + - random: remove dead code left over from blocking pool + - MAINTAINERS: co-maintain random.c + - crypto: blake2s - include instead of + - crypto: blake2s - adjust include guard naming + - random: document add_hwgenerator_randomness() with other input functions + - random: remove unused irq_flags argument from add_interrupt_randomness() + - random: use BLAKE2s instead of SHA1 in extraction + - random: do not sign extend bytes for rotation when mixing + - random: do not re-init if crng_reseed completes before primary init + - random: mix bootloader randomness into pool + - random: harmonize "crng init done" messages + - random: use IS_ENABLED(CONFIG_NUMA) instead of ifdefs + - random: initialize ChaCha20 constants with correct endianness + - random: early initialization of ChaCha constants + - random: avoid superfluous call to RDRAND in CRNG extraction + - random: don't reset crng_init_cnt on urandom_read() + - random: fix typo in comments + - random: cleanup poolinfo abstraction + - random: cleanup integer types + - random: remove incomplete last_data logic + - random: remove unused extract_entropy() reserved argument + - random: rather than entropy_store abstraction, use global + - random: remove unused OUTPUT_POOL constants + - random: de-duplicate INPUT_POOL constants + - random: prepend remaining pool constants with POOL_ + - random: cleanup fractional entropy shift constants + - random: access input_pool_data directly rather than through pointer + - random: selectively clang-format where it makes sense + - random: simplify arithmetic function flow in account() + - random: continually use hwgenerator randomness + - random: access primary_pool directly rather than through pointer + - random: only call crng_finalize_init() for primary_crng + - random: use computational hash for entropy extraction + - random: simplify entropy debiting + - random: use linear min-entropy accumulation crediting + - random: always wake up entropy writers after extraction + - random: make credit_entropy_bits() always safe + - random: remove use_input_pool parameter from crng_reseed() + - random: remove batched entropy locking + - random: fix locking in crng_fast_load() + - random: use RDSEED instead of RDRAND in entropy extraction + - random: get rid of secondary crngs + - random: inline leaves of rand_initialize() + - random: ensure early RDSEED goes through mixer on init + - random: do not xor RDRAND when writing into /dev/random + - random: absorb fast pool into input pool after fast load + - random: use simpler fast key erasure flow on per-cpu keys + - random: use hash function for crng_slow_load() + - random: make more consistent use of integer types + - random: remove outdated INT_MAX >> 6 check in urandom_read() + - random: zero buffer after reading entropy from userspace + - random: fix locking for crng_init in crng_reseed() + - random: tie batched entropy generation to base_crng generation + - random: remove ifdef'd out interrupt bench + - random: remove unused tracepoints + - random: add proper SPDX header + - random: deobfuscate irq u32/u64 contributions + - random: introduce drain_entropy() helper to declutter crng_reseed() + - random: remove useless header comment + - random: remove whitespace and reorder includes + - random: group initialization wait functions + - random: group crng functions + - random: group entropy extraction functions + - random: group entropy collection functions + - random: group userspace read/write functions + - random: group sysctl functions + - random: rewrite header introductory comment + - random: defer fast pool mixing to worker + - random: do not take pool spinlock at boot + - random: unify early init crng load accounting + - random: check for crng_init == 0 in add_device_randomness() + - random: pull add_hwgenerator_randomness() declaration into random.h + - random: clear fast pool, crng, and batches in cpuhp bring up + - random: round-robin registers as ulong, not u32 + - random: only wake up writers after zap if threshold was passed + - random: cleanup UUID handling + - random: unify cycles_t and jiffies usage and types + - random: do crng pre-init loading in worker rather than irq + - random: give sysctl_random_min_urandom_seed a more sensible value + - random: don't let 644 read-only sysctls be written to + - random: replace custom notifier chain with standard one + - random: use SipHash as interrupt entropy accumulator + - random: make consistent usage of crng_ready() + - random: reseed more often immediately after booting + - random: check for signal and try earlier when generating entropy + - random: skip fast_init if hwrng provides large chunk of entropy + - random: treat bootloader trust toggle the same way as cpu trust toggle + - random: re-add removed comment about get_random_{u32,u64} reseeding + - random: mix build-time latent entropy into pool at init + - random: do not split fast init input in add_hwgenerator_randomness() + - random: do not allow user to keep crng key around on stack + - random: check for signal_pending() outside of need_resched() check + - random: check for signals every PAGE_SIZE chunk of /dev/[u]random + - random: allow partial reads if later user copies fail + - random: make random_get_entropy() return an unsigned long + - random: document crng_fast_key_erasure() destination possibility + - random: fix sysctl documentation nits + - init: call time_init() before rand_initialize() + - ia64: define get_cycles macro for arch-override + - s390: define get_cycles macro for arch-override + - parisc: define get_cycles macro for arch-override + - alpha: define get_cycles macro for arch-override + - powerpc: define get_cycles macro for arch-override + - timekeeping: Add raw clock fallback for random_get_entropy() + - m68k: use fallback for random_get_entropy() instead of zero + - mips: use fallback for random_get_entropy() instead of just c0 random + - arm: use fallback for random_get_entropy() instead of zero + - nios2: use fallback for random_get_entropy() instead of zero + - x86/tsc: Use fallback for random_get_entropy() instead of zero + - um: use fallback for random_get_entropy() instead of zero + - sparc: use fallback for random_get_entropy() instead of zero + - xtensa: use fallback for random_get_entropy() instead of zero + - random: insist on random_get_entropy() existing in order to simplify + - random: do not use batches when !crng_ready() + - random: use first 128 bits of input as fast init + - random: do not pretend to handle premature next security model + - random: order timer entropy functions below interrupt functions + - random: do not use input pool from hard IRQs + - random: help compiler out with fast_mix() by using simpler arguments + - siphash: use one source of truth for siphash permutations + - random: use symbolic constants for crng_init states + - random: avoid initializing twice in credit race + - random: move initialization out of reseeding hot path + - random: remove ratelimiting for in-kernel unseeded randomness + - random: use proper jiffies comparison macro + - random: handle latent entropy and command line from random_init() + - random: credit architectural init the exact amount + - random: use static branch for crng_ready() + - random: remove extern from functions in header + - random: use proper return types on get_random_{int,long}_wait() + - random: make consistent use of buf and len + - random: move initialization functions out of hot pages + - random: move randomize_page() into mm where it belongs + - random: unify batched entropy implementations + - random: convert to using fops->read_iter() + - random: convert to using fops->write_iter() + - random: wire up fops->splice_{read,write}_iter() + - random: check for signals after page of pool writes + - Revert "random: use static branch for crng_ready()" + - crypto: drbg - always seeded with SP800-90B compliant noise source + - crypto: drbg - prepare for more fine-grained tracking of seeding state + - crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() + - crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() + - crypto: drbg - always try to free Jitter RNG instance + - crypto: drbg - make reseeding from get_random_bytes() synchronous + - random: avoid checking crng_ready() twice in random_init() + - random: mark bootloader randomness code as __init + - random: account for arch randomness in bits + - powerpc/kasan: Silence KASAN warnings in __get_wchan() + - ASoC: nau8822: Add operation for internal PLL off and on + - dma-debug: make things less spammy under memory pressure + - ASoC: cs42l52: Fix TLV scales for mixer controls + - ASoC: cs35l36: Update digital volume TLV + - ASoC: cs53l30: Correct number of volume levels on SX controls + - ASoC: cs42l52: Correct TLV for Bypass Volume + - ASoC: cs42l56: Correct typo in minimum level for SX volume controls + - ata: libata-core: fix NULL pointer deref in ata_host_alloc_pinfo() + - ASoC: wm8962: Fix suspend while playing music + - ASoC: es8328: Fix event generation for deemphasis control + - ASoC: wm_adsp: Fix event generation for wm_adsp_fw_put() + - scsi: vmw_pvscsi: Expand vcpuHint to 16 bits + - scsi: lpfc: Fix port stuck in bypassed state after LIP in PT2PT topology + - scsi: lpfc: Allow reduced polling rate for nvme_admin_async_event cmd + completion + - scsi: ipr: Fix missing/incorrect resource cleanup in error case + - scsi: pmcraid: Fix missing resource cleanup in error case + - ALSA: hda/realtek - Add HW8326 support + - virtio-mmio: fix missing put_device() when vm_cmdline_parent registration + failed + - nfc: nfcmrvl: Fix memory leak in nfcmrvl_play_deferred + - ipv6: Fix signed integer overflow in l2tp_ip6_sendmsg + - net: ethernet: mtk_eth_soc: fix misuse of mem alloc interface + netdev[napi]_alloc_frag + - random: credit cpu and bootloader seeds by default + - pNFS: Don't keep retrying if the server replied NFS4ERR_LAYOUTUNAVAILABLE + - clocksource: hyper-v: unexport __init-annotated hv_init_clocksource() + - i40e: Fix adding ADQ filter to TC0 + - i40e: Fix calculating the number of queue pairs + - i40e: Fix call trace in setup_tx_descriptors + - tty: goldfish: Fix free_irq() on remove + - misc: atmel-ssc: Fix IRQ check in ssc_probe + - mlxsw: spectrum_cnt: Reorder counter pools + - net: bgmac: Fix an erroneous kfree() in bgmac_remove() + - arm64: ftrace: fix branch range checks + - certs/blacklist_hashes.c: fix const confusion in certs blacklist + - faddr2line: Fix overlapping text section failures, the sequel + - irqchip/gic/realview: Fix refcount leak in realview_gic_of_init + - irqchip/gic-v3: Fix error handling in gic_populate_ppi_partitions + - irqchip/gic-v3: Fix refcount leak in gic_populate_ppi_partitions + - i2c: designware: Use standard optional ref clock implementation + - comedi: vmk80xx: fix expression for tx buffer size + - USB: serial: option: add support for Cinterion MV31 with new baseline + - USB: serial: io_ti: add Agilent E5805A support + - usb: dwc2: Fix memory leak in dwc2_hcd_init + - usb: gadget: lpc32xx_udc: Fix refcount leak in lpc32xx_udc_probe + - serial: 8250: Store to lsr_save_flags after lsr read + - dm mirror log: round up region bitmap size to BITS_PER_LONG + - ext4: fix bug_on ext4_mb_use_inode_pa + - ext4: make variable "count" signed + - ext4: add reserved GDT blocks check + - ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP machine + - virtio-pci: Remove wrong address verification in vp_del_vqs() + - net/sched: act_police: more accurate MTU policing + - net: openvswitch: fix leak of nested actions + - arm64: kprobes: Use BRK instead of single-step when executing instructions + out-of-line + - RISC-V: fix barrier() use in + - riscv: Less inefficient gcc tishift helpers (and export their symbols) + - powerpc/mm: Switch obsolete dssall to .long + - Linux 5.4.200 + * Focal update: v5.4.199 upstream stable release (LP: #1983150) + - Linux 5.4.199 + * Focal update: v5.4.198 upstream stable release (LP: #1982409) + - binfmt_flat: do not stop relocating GOT entries prematurely on riscv + - ALSA: hda/realtek - Fix microphone noise on ASUS TUF B550M-PLUS + - USB: serial: option: add Quectel BG95 modem + - USB: new quirk for Dell Gen 2 devices + - perf/x86/intel: Fix event constraints for ICL + - ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP + - ptrace/xtensa: Replace PT_SINGLESTEP with TIF_SINGLESTEP + - ptrace: Reimplement PTRACE_KILL by always sending SIGKILL + - btrfs: add "0x" prefix for unsupported optional features + - btrfs: repair super block num_devices automatically + - drm/virtio: fix NULL pointer dereference in virtio_gpu_conn_get_modes + - mwifiex: add mutex lock for call in mwifiex_dfs_chan_sw_work_queue + - b43legacy: Fix assigning negative value to unsigned variable + - b43: Fix assigning negative value to unsigned variable + - ipw2x00: Fix potential NULL dereference in libipw_xmit() + - ipv6: fix locking issues with loops over idev->addr_list + - fbcon: Consistently protect deferred_takeover with console_lock() + - ACPICA: Avoid cache flush inside virtual machines + - drm/komeda: return early if drm_universal_plane_init() fails. + - ALSA: jack: Access input_dev under mutex + - spi: spi-rspi: Remove setting {src,dst}_{addr,addr_width} based on DMA + direction + - tools/power turbostat: fix ICX DRAM power numbers + - drm/amd/pm: fix double free in si_parse_power_table() + - ath9k: fix QCA9561 PA bias level + - media: venus: hfi: avoid null dereference in deinit + - media: pci: cx23885: Fix the error handling in cx23885_initdev() + - media: cx25821: Fix the warning when removing the module + - md/bitmap: don't set sb values if can't pass sanity check + - mmc: jz4740: Apply DMA engine limits to maximum segment size + - scsi: megaraid: Fix error check return value of register_chrdev() + - drm/plane: Move range check for format_count earlier + - drm/amd/pm: fix the compile warning + - arm64: compat: Do not treat syscall number as ESR_ELx for a bad syscall + - drm: msm: fix error check return value of irq_of_parse_and_map() + - ipv6: Don't send rs packets to the interface of ARPHRD_TUNNEL + - net/mlx5: fs, delete the FTE when there are no rules attached to it + - ASoC: dapm: Don't fold register value changes into notifications + - mlxsw: spectrum_dcb: Do not warn about priority changes + - drm/amdgpu/ucode: Remove firmware load type check in amdgpu_ucode_free_bo + - HID: bigben: fix slab-out-of-bounds Write in bigben_probe + - ASoC: tscs454: Add endianness flag in snd_soc_component_driver + - s390/preempt: disable __preempt_count_add() optimization for + PROFILE_ALL_BRANCHES + - spi: stm32-qspi: Fix wait_cmd timeout in APM mode + - dma-debug: change allocation mode from GFP_NOWAIT to GFP_ATIOMIC + - ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default + - ipmi:ssif: Check for NULL msg when handling events and messages + - ipmi: Fix pr_fmt to avoid compilation issues + - rtlwifi: Use pr_warn instead of WARN_ONCE + - media: coda: limit frame interval enumeration to supported encoder frame + sizes + - media: cec-adap.c: fix is_configuring state + - openrisc: start CPU timer early in boot + - nvme-pci: fix a NULL pointer dereference in nvme_alloc_admin_tags + - ASoC: rt5645: Fix errorenous cleanup order + - nbd: Fix hung on disconnect request if socket is closed before + - net: phy: micrel: Allow probing without .driver_data + - media: exynos4-is: Fix compile warning + - ASoC: max98357a: remove dependency on GPIOLIB + - rxrpc: Return an error to sendmsg if call failed + - eth: tg3: silence the GCC 12 array-bounds warning + - selftests/bpf: fix btf_dump/btf_dump due to recent clang change + - IB/rdmavt: add missing locks in rvt_ruc_loopback + - ARM: dts: ox820: align interrupt controller node name with dtschema + - PM / devfreq: rk3399_dmc: Disable edev on remove() + - fs: jfs: fix possible NULL pointer dereference in dbFree() + - ARM: OMAP1: clock: Fix UART rate reporting algorithm + - powerpc/fadump: Fix fadump to work with a different endian capture kernel + - fat: add ratelimit to fat*_ent_bread() + - ARM: versatile: Add missing of_node_put in dcscb_init + - ARM: dts: exynos: add atmel,24c128 fallback to Samsung EEPROM + - ARM: hisi: Add missing of_node_put after of_find_compatible_node + - PCI: Avoid pci_dev_lock() AB/BA deadlock with sriov_numvfs_store() + - tracing: incorrect isolate_mote_t cast in mm_vmscan_lru_isolate + - powerpc/xics: fix refcount leak in icp_opal_init() + - powerpc/powernv: fix missing of_node_put in uv_init() + - macintosh/via-pmu: Fix build failure when CONFIG_INPUT is disabled + - powerpc/iommu: Add missing of_node_put in iommu_init_early_dart + - RDMA/hfi1: Prevent panic when SDMA is disabled + - drm: fix EDID struct for old ARM OABI format + - ath9k: fix ar9003_get_eepmisc + - drm/edid: fix invalid EDID extension block filtering + - drm/bridge: adv7511: clean up CEC adapter when probe fails + - ASoC: mediatek: Fix error handling in mt8173_max98090_dev_probe + - ASoC: mediatek: Fix missing of_node_put in mt2701_wm8960_machine_probe + - x86/delay: Fix the wrong asm constraint in delay_loop() + - drm/mediatek: Fix mtk_cec_mask() + - drm/vc4: txp: Don't set TXP_VSTART_AT_EOF + - drm/vc4: txp: Force alpha to be 0xff if it's disabled + - bpf: Fix excessive memory allocation in stack_map_alloc() + - nl80211: show SSID for P2P_GO interfaces + - drm/komeda: Fix an undefined behavior bug in komeda_plane_add() + - drm: mali-dp: potential dereference of null pointer + - spi: spi-ti-qspi: Fix return value handling of wait_for_completion_timeout + - NFC: NULL out the dev->rfkill to prevent UAF + - efi: Add missing prototype for efi_capsule_setup_info + - drbd: fix duplicate array initializer + - HID: hid-led: fix maximum brightness for Dream Cheeky + - HID: elan: Fix potential double free in elan_input_configured + - drm/bridge: Fix error handling in analogix_dp_probe + - sched/fair: Fix cfs_rq_clock_pelt() for throttled cfs_rq + - spi: img-spfi: Fix pm_runtime_get_sync() error checking + - cpufreq: Fix possible race in cpufreq online error path + - ath9k_htc: fix potential out of bounds access with invalid + rxstatus->rs_keyix + - inotify: show inotify mask flags in proc fdinfo + - fsnotify: fix wrong lockdep annotations + - of: overlay: do not break notify on NOTIFY_{OK|STOP} + - scsi: ufs: core: Exclude UECxx from SFR dump list + - x86/pm: Fix false positive kmemleak report in msr_build_context() + - x86/speculation: Add missing prototype for unpriv_ebpf_notify() + - ASoC: rk3328: fix disabling mclk on pclk probe failure + - perf tools: Add missing headers needed by util/data.h + - drm/msm/disp/dpu1: set vbif hw config to NULL to avoid use after memory free + during pm runtime resume + - drm/msm/dsi: fix error checks and return values for DSI xmit functions + - drm/msm/hdmi: check return value after calling + platform_get_resource_byname() + - drm/msm/hdmi: fix error check return value of irq_of_parse_and_map() + - drm/rockchip: vop: fix possible null-ptr-deref in vop_bind() + - virtio_blk: fix the discard_granularity and discard_alignment queue limits + - x86: Fix return value of __setup handlers + - irqchip/exiu: Fix acknowledgment of edge triggered interrupts + - irqchip/aspeed-i2c-ic: Fix irq_of_parse_and_map() return value + - x86/mm: Cleanup the control_va_addr_alignment() __setup handler + - regulator: core: Fix enable_count imbalance with EXCLUSIVE_GET + - drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is + detected + - drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is + detected + - drm/msm: return an error pointer in msm_gem_prime_get_sg_table() + - media: uvcvideo: Fix missing check to determine if element is found in list + - iomap: iomap_write_failed fix + - Revert "cpufreq: Fix possible race in cpufreq online error path" + - perf/amd/ibs: Use interrupt regs ip for stack unwinding + - ASoC: fsl: Fix refcount leak in imx_sgtl5000_probe + - ASoC: mxs-saif: Fix refcount leak in mxs_saif_probe + - regulator: pfuze100: Fix refcount leak in pfuze_parse_regulators_dt + - scripts/faddr2line: Fix overlapping text section failures + - media: aspeed: Fix an error handling path in aspeed_video_probe() + - media: st-delta: Fix PM disable depth imbalance in delta_probe + - media: exynos4-is: Change clk_disable to clk_disable_unprepare + - media: pvrusb2: fix array-index-out-of-bounds in pvr2_i2c_core_init + - media: vsp1: Fix offset calculation for plane cropping + - Bluetooth: fix dangling sco_conn and use-after-free in sco_sock_timeout + - m68k: math-emu: Fix dependencies of math emulation support + - sctp: read sk->sk_bound_dev_if once in sctp_rcv() + - media: ov7670: remove ov7670_power_off from ov7670_remove + - ext4: reject the 'commit' option on ext2 filesystems + - drm/msm/a6xx: Fix refcount leak in a6xx_gpu_init + - drm: msm: fix possible memory leak in mdp5_crtc_cursor_set() + - thermal/drivers/broadcom: Fix potential NULL dereference in sr_thermal_probe + - ASoC: wm2000: fix missing clk_disable_unprepare() on error in + wm2000_anc_transition() + - NFC: hci: fix sleep in atomic context bugs in nfc_hci_hcp_message_tx + - rxrpc: Fix listen() setting the bar too high for the prealloc rings + - rxrpc: Don't try to resend the request if we're receiving the reply + - rxrpc: Fix overlapping ACK accounting + - rxrpc: Don't let ack.previousPacket regress + - rxrpc: Fix decision on when to generate an IDLE ACK + - net/smc: postpone sk_refcnt increment in connect() + - arm64: dts: rockchip: Move drive-impedance-ohm to emmc phy on rk3399 + - ARM: dts: suniv: F1C100: fix watchdog compatible + - soc: qcom: smp2p: Fix missing of_node_put() in smp2p_parse_ipc + - soc: qcom: smsm: Fix missing of_node_put() in smsm_parse_ipc + - PCI: cadence: Fix find_first_zero_bit() limit + - PCI: rockchip: Fix find_first_zero_bit() limit + - KVM: nVMX: Leave most VM-Exit info fields unmodified on failed VM-Entry + - can: xilinx_can: mark bit timing constants as const + - ARM: dts: bcm2835-rpi-zero-w: Fix GPIO line name for Wifi/BT + - ARM: dts: bcm2837-rpi-cm3-io3: Fix GPIO line names for SMPS I2C + - ARM: dts: bcm2837-rpi-3-b-plus: Fix GPIO line name of power LED + - ARM: dts: bcm2835-rpi-b: Fix GPIO line names + - misc: ocxl: fix possible double free in ocxl_file_register_afu + - crypto: marvell/cesa - ECB does not IV + - arm: mediatek: select arch timer for mt7629 + - powerpc/fadump: fix PT_LOAD segment for boot memory area + - mfd: ipaq-micro: Fix error check return value of platform_get_irq() + - scsi: fcoe: Fix Wstringop-overflow warnings in fcoe_wwn_from_mac() + - firmware: arm_scmi: Fix list protocols enumeration in the base protocol + - nvdimm: Allow overwrite in the presence of disabled dimms + - pinctrl: mvebu: Fix irq_of_parse_and_map() return value + - drivers/base/node.c: fix compaction sysfs file leak + - dax: fix cache flush on PMD-mapped pages + - powerpc/8xx: export 'cpm_setbrg' for modules + - powerpc/idle: Fix return value of __setup() handler + - powerpc/4xx/cpm: Fix return value of __setup() handler + - proc: fix dentry/inode overinstantiating under /proc/${pid}/net + - ipc/mqueue: use get_tree_nodev() in mqueue_get_tree() + - PCI: imx6: Fix PERST# start-up sequence + - tty: fix deadlock caused by calling printk() under tty_port->lock + - crypto: cryptd - Protect per-CPU resource by disabling BH. + - Input: sparcspkr - fix refcount leak in bbc_beep_probe + - powerpc/64: Only WARN if __pa()/__va() called with bad addresses + - powerpc/perf: Fix the threshold compare group constraint for power9 + - macintosh: via-pmu and via-cuda need RTC_LIB + - powerpc/fsl_rio: Fix refcount leak in fsl_rio_setup + - mfd: davinci_voicecodec: Fix possible null-ptr-deref davinci_vc_probe() + - mailbox: forward the hrtimer if not queued and under a lock + - RDMA/hfi1: Prevent use of lock before it is initialized + - Input: stmfts - do not leave device disabled in stmfts_input_open + - f2fs: fix dereference of stale list iterator after loop body + - iommu/mediatek: Add list_del in mtk_iommu_remove + - i2c: at91: use dma safe buffers + - i2c: at91: Initialize dma_buf in at91_twi_xfer() + - NFS: Do not report EINTR/ERESTARTSYS as mapping errors + - NFS: Do not report flush errors in nfs_write_end() + - NFS: Don't report errors from nfs_pageio_complete() more than once + - NFSv4/pNFS: Do not fail I/O when we fail to allocate the pNFS layout + - video: fbdev: clcdfb: Fix refcount leak in clcdfb_of_vram_setup + - dmaengine: stm32-mdma: remove GISR1 register + - iommu/amd: Increase timeout waiting for GA log enablement + - perf c2c: Use stdio interface if slang is not supported + - perf jevents: Fix event syntax error caused by ExtSel + - f2fs: fix to avoid f2fs_bug_on() in dec_valid_node_count() + - f2fs: fix to do sanity check on block address in f2fs_do_zero_range() + - f2fs: fix to clear dirty inode in f2fs_evict_inode() + - f2fs: fix deadloop in foreground GC + - f2fs: don't need inode lock for system hidden quota + - f2fs: fix fallocate to use file_modified to update permissions consistently + - wifi: mac80211: fix use-after-free in chanctx code + - iwlwifi: mvm: fix assert 1F04 upon reconfig + - fs-writeback: writeback_sb_inodes:Recalculate 'wrote' according skipped + pages + - efi: Do not import certificates from UEFI Secure Boot for T2 Macs + - bfq: Split shared queues on move between cgroups + - bfq: Update cgroup information before merging bio + - bfq: Track whether bfq_group is still online + - ext4: fix use-after-free in ext4_rename_dir_prepare + - ext4: fix warning in ext4_handle_inode_extension + - ext4: fix bug_on in ext4_writepages + - ext4: verify dir block before splitting it + - ext4: avoid cycles in directory h-tree + - ACPI: property: Release subnode properties with data nodes + - tracing: Fix potential double free in create_var_ref() + - PCI/PM: Fix bridge_d3_blacklist[] Elo i2 overwrite of Gigabyte X299 + - PCI: qcom: Fix runtime PM imbalance on probe errors + - PCI: qcom: Fix unbalanced PHY init on probe errors + - mm, compaction: fast_find_migrateblock() should return pfn in the target + zone + - dlm: fix plock invalid read + - dlm: fix missing lkb refcount handling + - ocfs2: dlmfs: fix error handling of user_dlm_destroy_lock + - scsi: dc395x: Fix a missing check on list iterator + - scsi: ufs: qcom: Add a readl() to make sure ref_clk gets enabled + - drm/amdgpu/cs: make commands with 0 chunks illegal behaviour. + - drm/etnaviv: check for reaped mapping in etnaviv_iommu_unmap_gem + - drm/nouveau/clk: Fix an incorrect NULL check on list iterator + - drm/bridge: analogix_dp: Grab runtime PM reference for DP-AUX + - md: fix an incorrect NULL check in does_sb_need_changing + - md: fix an incorrect NULL check in md_reload_sb + - mtd: cfi_cmdset_0002: Move and rename + chip_check/chip_ready/chip_good_for_write + - media: coda: Fix reported H264 profile + - media: coda: Add more H264 levels for CODA960 + - Kconfig: Add option for asm goto w/ tied outputs to workaround clang-13 bug + - RDMA/hfi1: Fix potential integer multiplication overflow errors + - irqchip/armada-370-xp: Do not touch Performance Counter Overflow on A375, + A38x, A39x + - irqchip: irq-xtensa-mx: fix initial IRQ affinity + - mac80211: upgrade passive scan to active scan on DFS channels after beacon + rx + - um: chan_user: Fix winch_tramp() return value + - um: Fix out-of-bounds read in LDT setup + - iommu/msm: Fix an incorrect NULL check on list iterator + - nodemask.h: fix compilation error with GCC12 + - hugetlb: fix huge_pmd_unshare address update + - rtl818x: Prevent using not initialized queues + - ASoC: rt5514: Fix event generation for "DSP Voice Wake Up" control + - carl9170: tx: fix an incorrect use of list iterator + - serial: pch: don't overwrite xmit->buf[0] by x_char + - tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator + - gma500: fix an incorrect NULL check on list iterator + - arm64: dts: qcom: ipq8074: fix the sleep clock frequency + - phy: qcom-qmp: fix struct clk leak on probe errors + - ARM: pxa: maybe fix gpio lookup tables + - docs/conf.py: Cope with removal of language=None in Sphinx 5.0.0 + - dt-bindings: gpio: altera: correct interrupt-cells + - blk-iolatency: Fix inflight count imbalances and IO hangs on offline + - phy: qcom-qmp: fix reset-controller leak on probe errors + - Kconfig: add config option for asm goto w/ outputs + - RDMA/rxe: Generate a completion for unsupported/invalid opcode + - MIPS: IP27: Remove incorrect `cpu_has_fpu' override + - bfq: Avoid merging queues with different parents + - bfq: Drop pointless unlock-lock pair + - bfq: Remove pointless bfq_init_rq() calls + - bfq: Get rid of __bio_blkcg() usage + - bfq: Make sure bfqg for which we are queueing requests is online + - block: fix bio_clone_blkg_association() to associate with proper blkcg_gq + - md: bcache: check the return value of kzalloc() in detached_dev_do_request() + - pcmcia: db1xxx_ss: restrict to MIPS_DB1XXX boards + - staging: greybus: codecs: fix type confusion of list iterator variable + - iio: adc: ad7124: Remove shift from scan_type + - tty: goldfish: Use tty_port_destroy() to destroy port + - tty: serial: owl: Fix missing clk_disable_unprepare() in owl_uart_probe + - tty: serial: fsl_lpuart: fix potential bug when using both of_alias_get_id + and ida_simple_get + - usb: usbip: fix a refcount leak in stub_probe() + - usb: usbip: add missing device lock on tweak configuration cmd + - USB: storage: karma: fix rio_karma_init return + - usb: musb: Fix missing of_node_put() in omap2430_probe + - staging: fieldbus: Fix the error handling path in + anybuss_host_common_probe() + - pwm: lp3943: Fix duty calculation in case period was clamped + - rpmsg: qcom_smd: Fix irq_of_parse_and_map() return value + - usb: dwc3: pci: Fix pm_runtime_get_sync() error checking + - firmware: stratix10-svc: fix a missing check on list iterator + - iio: adc: stmpe-adc: Fix wait_for_completion_timeout return value check + - iio: adc: sc27xx: fix read big scale voltage not right + - iio: adc: sc27xx: Fine tune the scale calibration values + - rpmsg: qcom_smd: Fix returning 0 if irq_of_parse_and_map() fails + - phy: qcom-qmp: fix pipe-clock imbalance on power-on failure + - serial: sifive: Report actual baud base rather than fixed 115200 + - coresight: cpu-debug: Replace mutex with mutex_trylock on panic notifier + - soc: rockchip: Fix refcount leak in rockchip_grf_init + - clocksource/drivers/riscv: Events are stopped during CPU suspend + - rtc: mt6397: check return value after calling platform_get_resource() + - serial: meson: acquire port->lock in startup() + - serial: 8250_fintek: Check SER_RS485_RTS_* only with RS485 + - serial: digicolor-usart: Don't allow CS5-6 + - serial: rda-uart: Don't allow CS5-6 + - serial: txx9: Don't allow CS5-6 + - serial: sh-sci: Don't allow CS5-6 + - serial: sifive: Sanitize CSIZE and c_iflag + - serial: st-asc: Sanitize CSIZE and correct PARENB for CS7 + - serial: stm32-usart: Correct CSIZE, bits, and parity + - firmware: dmi-sysfs: Fix memory leak in dmi_sysfs_register_handle + - bus: ti-sysc: Fix warnings for unbind for serial + - driver: base: fix UAF when driver_attach failed + - driver core: fix deadlock in __device_attach + - watchdog: ts4800_wdt: Fix refcount leak in ts4800_wdt_probe + - ASoC: fsl_sai: Fix FSL_SAI_xDR/xFR definition + - clocksource/drivers/oxnas-rps: Fix irq_of_parse_and_map() return value + - s390/crypto: fix scatterwalk_unmap() callers in AES-GCM + - net: sched: fixed barrier to prevent skbuff sticking in qdisc backlog + - net: ethernet: mtk_eth_soc: out of bounds read in mtk_hwlro_get_fdir_entry() + - net: dsa: mv88e6xxx: Fix refcount leak in mv88e6xxx_mdios_register + - modpost: fix removing numeric suffixes + - jffs2: fix memory leak in jffs2_do_fill_super + - ubi: ubi_create_volume: Fix use-after-free when volume creation failed + - nfp: only report pause frame configuration for physical device + - net/mlx5: Don't use already freed action pointer + - net/mlx5e: Update netdev features after changing XDP state + - net: sched: add barrier to fix packet stuck problem for lockless qdisc + - tcp: tcp_rtx_synack() can be called from process context + - afs: Fix infinite loop found by xfstest generic/676 + - tipc: check attribute length for bearer name + - perf c2c: Fix sorting in percent_rmt_hitm_cmp() + - mips: cpc: Fix refcount leak in mips_cpc_default_phys_base + - tracing: Fix sleeping function called from invalid context on RT kernel + - tracing: Avoid adding tracer option before update_tracer_options + - f2fs: remove WARN_ON in f2fs_is_valid_blkaddr + - i2c: cadence: Increase timeout per message if necessary + - m68knommu: set ZERO_PAGE() to the allocated zeroed page + - m68knommu: fix undefined reference to `_init_sp' + - dmaengine: zynqmp_dma: In struct zynqmp_dma_chan fix desc_size data type + - NFSv4: Don't hold the layoutget locks across multiple RPC calls + - video: fbdev: pxa3xx-gcu: release the resources correctly in + pxa3xx_gcu_probe/remove() + - xprtrdma: treat all calls not a bcall when bc_serv is NULL + - netfilter: nat: really support inet nat without l3 address + - ata: pata_octeon_cf: Fix refcount leak in octeon_cf_probe + - netfilter: nf_tables: memleak flow rule from commit path + - xen: unexport __init-annotated xen_xlate_map_ballooned_pages() + - af_unix: Fix a data-race in unix_dgram_peer_wake_me(). + - bpf, arm64: Clear prog->jited_len along prog->jited + - net: dsa: lantiq_gswip: Fix refcount leak in gswip_gphy_fw_list + - net/mlx4_en: Fix wrong return value on ioctl EEPROM query failure + - SUNRPC: Fix the calculation of xdr->end in xdr_get_next_encode_buffer() + - net: mdio: unexport __init-annotated mdio_bus_init() + - net: xfrm: unexport __init-annotated xfrm4_protocol_init() + - net: ipv6: unexport __init-annotated seg6_hmac_init() + - net/mlx5: Rearm the FW tracer after each tracer event + - net/mlx5: fs, fail conflicting actions + - ip_gre: test csum_start instead of transport header + - net: altera: Fix refcount leak in altera_tse_mdio_create + - drm: imx: fix compiler warning with gcc-12 + - iio: dummy: iio_simple_dummy: check the return value of kstrdup() + - iio: st_sensors: Add a local lock for protecting odr + - lkdtm/usercopy: Expand size of "out of frame" object + - tty: synclink_gt: Fix null-pointer-dereference in slgt_clean() + - tty: Fix a possible resource leak in icom_probe + - drivers: staging: rtl8192u: Fix deadlock in ieee80211_beacons_stop() + - drivers: staging: rtl8192e: Fix deadlock in rtllib_beacons_stop() + - USB: host: isp116x: check return value after calling platform_get_resource() + - drivers: tty: serial: Fix deadlock in sa1100_set_termios() + - drivers: usb: host: Fix deadlock in oxu_bus_suspend() + - USB: hcd-pci: Fully suspend across freeze/thaw cycle + - usb: dwc2: gadget: don't reset gadget's driver->bus + - misc: rtsx: set NULL intfdata when probe fails + - extcon: Modify extcon device to be created after driver data is set + - clocksource/drivers/sp804: Avoid error on multiple instances + - staging: rtl8712: fix uninit-value in usb_read8() and friends + - staging: rtl8712: fix uninit-value in r871xu_drv_init() + - serial: msm_serial: disable interrupts in __msm_console_write() + - kernfs: Separate kernfs_pr_cont_buf and rename_lock. + - watchdog: wdat_wdt: Stop watchdog when rebooting the system + - md: protect md_unregister_thread from reentrancy + - scsi: myrb: Fix up null pointer access on myrb_cleanup() + - ceph: allow ceph.dir.rctime xattr to be updatable + - drm/radeon: fix a possible null pointer dereference + - modpost: fix undefined behavior of is_arm_mapping_symbol() + - x86/cpu: Elide KCSAN for cpu_has() and friends + - nbd: call genl_unregister_family() first in nbd_cleanup() + - nbd: fix race between nbd_alloc_config() and module removal + - cifs: version operations for smb20 unneeded when legacy support disabled + - nodemask: Fix return values to be unsigned + - vringh: Fix loop descriptors check in the indirect cases + - scripts/gdb: change kernel config dumping method + - ALSA: hda/conexant - Fix loopback issue with CX20632 + - cifs: return errors during session setup during reconnects + - ata: libata-transport: fix {dma|pio|xfer}_mode sysfs files + - mmc: block: Fix CQE recovery reset success + - nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION + - nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling + - ixgbe: fix bcast packets Rx on VF after promisc removal + - ixgbe: fix unexpected VLAN Rx in promisc mode on VF + - Input: bcm5974 - set missing URB_NO_TRANSFER_DMA_MAP urb flag + - powerpc/32: Fix overread/overwrite of thread_struct via ptrace + - md/raid0: Ignore RAID0 layout if the second zone has only one device + - mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N + - tcp: fix tcp_mtup_probe_success vs wrong snd_cwnd + - Linux 5.4.198 + * Focal update: v5.4.197 upstream stable release (LP: #1981758) + - x86/pci/xen: Disable PCI/MSI[-X] masking for XEN_HVM guests + - staging: rtl8723bs: prevent ->Ssid overflow in rtw_wx_set_scan() + - Input: goodix - fix spurious key release events + - tcp: change source port randomizarion at connect() time + - secure_seq: use the 64 bits of the siphash for port offset calculation + - media: vim2m: Register video device after setting up internals + - media: vim2m: initialize the media device earlier + - ACPI: sysfs: Make sparse happy about address space in use + - ACPI: sysfs: Fix BERT error region memory mapping + - pinctrl: sunxi: fix f1c100s uart2 function + - net: af_key: check encryption module availability consistency + - net: ftgmac100: Disable hardware checksum on AST2600 + - i2c: ismt: Provide a DMA buffer for Interrupt Cause Logging + - drivers: i2c: thunderx: Allow driver to work with ACPI defined TWSI + controllers + - assoc_array: Fix BUG_ON during garbage collect + - cfg80211: set custom regdomain after wiphy registration + - drm/i915: Fix -Wstringop-overflow warning in call to intel_read_wm_latency() + - exec: Force single empty string when argv is empty + - netfilter: conntrack: re-fetch conntrack after insertion + - crypto: ecrdsa - Fix incorrect use of vli_cmp + - zsmalloc: fix races between asynchronous zspage free and page migration + - dm integrity: fix error code in dm_integrity_ctr() + - dm crypt: make printing of the key constant-time + - dm stats: add cond_resched when looping over entries + - dm verity: set DM_TARGET_IMMUTABLE feature flag + - raid5: introduce MD_BROKEN + - HID: multitouch: Add support for Google Whiskers Touchpad + - tpm: Fix buffer access in tpm2_get_tpm_pt() + - tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe() + - docs: submitting-patches: Fix crossref to 'The canonical patch format' + - NFS: Memory allocation failures are not server fatal errors + - NFSD: Fix possible sleep during nfsd4_release_lockowner() + - bpf: Enlarge offset check value to INT_MAX in bpf_skb_{load,store}_bytes + - Linux 5.4.197 + * Focal update: v5.4.196 upstream stable release (LP: #1981111) + - x86/xen: Make the boot CPU idle task reliable + - x86/xen: Make the secondary CPU idle tasks reliable + - rtc: fix use-after-free on device removal + - um: Cleanup syscall_handler_t definition/cast, fix warning + - Input: add bounds checking to input_set_capability() + - Input: stmfts - fix reference leak in stmfts_input_open + - crypto: stm32 - fix reference leak in stm32_crc_remove + - crypto: x86/chacha20 - Avoid spurious jumps to other functions + - ALSA: hda/realtek: Enable headset mic on Lenovo P360 + - nvme-multipath: fix hang when disk goes live over reconnect + - rtc: mc146818-lib: Fix the AltCentury for AMD platforms + - MIPS: lantiq: check the return value of kzalloc() + - drbd: remove usage of list iterator variable after loop + - platform/chrome: cros_ec_debugfs: detach log reader wq from devm + - ARM: 9191/1: arm/stacktrace, kasan: Silence KASAN warnings in unwind_frame() + - nilfs2: fix lockdep warnings in page operations for btree nodes + - nilfs2: fix lockdep warnings during disk space reclamation + - mmc: core: Specify timeouts for BKOPS and CACHE_FLUSH for eMMC + - mmc: block: Use generic_cmd6_time when modifying INAND_CMD38_ARG_EXT_CSD + - mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch() + - SUNRPC: Clean up scheduling of autoclose + - SUNRPC: Prevent immediate close+reconnect + - SUNRPC: Don't call connect() more than once on a TCP socket + - ALSA: wavefront: Proper check of get_user() error + - perf: Fix sys_perf_event_open() race against self + - Fix double fget() in vhost_net_set_backend() + - PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold + - KVM: x86/mmu: Update number of zapped pages even if page list is stable + - crypto: qcom-rng - fix infinite loop on requests not multiple of WORD_SZ + - drm/dp/mst: fix a possible memory leak in fetch_monitor_name() + - dma-buf: fix use of DMA_BUF_SET_NAME_{A,B} in userspace + - ARM: dts: aspeed-g6: remove FWQSPID group in pinctrl dtsi + - ARM: dts: aspeed-g6: fix SPI1/SPI2 quad pin group + - net: macb: Increment rx bd head after allocating skb and buffer + - net/sched: act_pedit: sanitize shift argument before usage + - net: vmxnet3: fix possible use-after-free bugs in vmxnet3_rq_alloc_rx_buf() + - net: vmxnet3: fix possible NULL pointer dereference in vmxnet3_rq_cleanup() + - ice: fix possible under reporting of ethtool Tx and Rx statistics + - clk: at91: generated: consider range when calculating best rate + - net/qla3xxx: Fix a test in ql_reset_work() + - NFC: nci: fix sleep in atomic context bugs caused by nci_skb_alloc + - net/mlx5e: Properly block LRO when XDP is enabled + - ARM: 9196/1: spectre-bhb: enable for Cortex-A15 + - ARM: 9197/1: spectre-bhb: fix loop8 sequence for Thumb2 + - igb: skip phy status check where unavailable + - net: bridge: Clear offload_fwd_mark when passing frame up bridge interface. + - gpio: gpio-vf610: do not touch other bits when set the target bit + - gpio: mvebu/pwm: Refuse requests with inverted polarity + - perf bench numa: Address compiler error on s390 + - scsi: qla2xxx: Fix missed DMA unmap for aborted commands + - mac80211: fix rx reordering with non explicit / psmp ack policy + - selftests: add ping test with ping_group_range tuned + - ethernet: tulip: fix missing pci_disable_device() on error in + tulip_init_one() + - net: stmmac: fix missing pci_disable_device() on error in stmmac_pci_probe() + - net: atlantic: verify hw_head_ lies within TX buffer ring + - Input: ili210x - fix reset timing + - block: return ELEVATOR_DISCARD_MERGE if possible + - net: stmmac: disable Split Header (SPH) for Intel platforms + - firmware_loader: use kernel credentials when reading firmware + - ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk + - Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE"" + - x86/xen: fix booting 32-bit pv guest + - x86/xen: Mark cpu_bringup_and_idle() as dead_end_function + - i2c: mt7621: fix missing clk_disable_unprepare() on error in mtk_i2c_probe() + - afs: Fix afs_getattr() to refetch file status if callback break occurred + - Linux 5.4.196 + * CVE-2022-36946 + - netfilter: nf_queue: do not allow packet truncation below transport header + offset + * CVE-2021-33655 + - fbcon: Disallow setting font bigger than screen size + - fbcon: Prevent that screen size is smaller than font size + - fbmem: Check virtual screen sizes in fb_set_var() + + -- Joseph Salisbury Tue, 30 Aug 2022 12:38:02 -0400 + +linux-oracle (5.4.0-1082.90) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1082.90 -proposed tracker (LP: #1983937) + + [ Ubuntu: 5.4.0-125.141 ] + + * focal/linux: 5.4.0-125.141 -proposed tracker (LP: #1983947) + * nbd: requests can become stuck when disconnecting from server with qemu-nbd + (LP: #1896350) + - blk-mq: blk-mq: provide forced completion method + - blk-mq: move failure injection out of blk_mq_complete_request + - nbd: don't handle response without a corresponding request message + - nbd: make sure request completion won't concurrent + - nbd: don't clear 'NBD_CMD_INFLIGHT' flag if request is not completed + - nbd: fix io hung while disconnecting device + * CVE-2021-33656 + - vt: drop old FONT ioctls + * CVE-2021-33061 + - ixgbe: add the ability for the PF to disable VF link state + - ixgbe: add improvement for MDD response functionality + - ixgbevf: add disable link state + + -- Joseph Salisbury Fri, 12 Aug 2022 10:17:46 -0400 + +linux-oracle (5.4.0-1081.89) focal; urgency=medium + + [ Ubuntu: 5.4.0-124.140 ] + + * CVE-2022-2586 + - SAUCE: netfilter: nf_tables: do not allow SET_ID to refer to another table + - SAUCE: netfilter: nf_tables: do not allow RULE_ID to refer to another chain + * CVE-2022-2588 + - SAUCE: net_sched: cls_route: remove from list when handle is 0 + * CVE-2022-34918 + - netfilter: nf_tables: stricter validation of element data + + -- Thadeu Lima de Souza Cascardo Mon, 08 Aug 2022 03:41:31 -0300 + +linux-oracle (5.4.0-1080.88) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1080.88 -proposed tracker (LP: #1981274) + + * ARM64_SW_TTBR0_PAN Should Be Enabled For Oracle Kernels (LP: #1968902) + - [config] oracle: Enable CONFIG_ARM64_SW_TTBR0_PAN + + [ Ubuntu: 5.4.0-123.139 ] + + * focal/linux: 5.4.0-123.139 -proposed tracker (LP: #1981284) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.07.11) + * Hairpin traffic does not work with centralized NAT gw (LP: #1967856) + - net: openvswitch: fix misuse of the cached connection on tuple changes + * [UBUNTU 20.04] Include patches to avoid self-detected stall with Secure + Execution (LP: #1979296) + - KVM: s390: pv: add macros for UVC CC values + - KVM: s390: pv: avoid stalls when making pages secure + - KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm + * Focal update: v5.4.195 upstream stable release (LP: #1980407) + - batman-adv: Don't skb_split skbuffs with frag_list + - hwmon: (tmp401) Add OF device ID table + - mac80211: Reset MBSSID parameters upon connection + - net: Fix features skip in for_each_netdev_feature() + - ipv4: drop dst in multicast routing path + - drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name() + - netlink: do not reset transport header in netlink_recvmsg() + - mac80211_hwsim: call ieee80211_tx_prepare_skb under RCU protection + - dim: initialize all struct fields + - hwmon: (ltq-cputemp) restrict it to SOC_XWAY + - s390/ctcm: fix variable dereferenced before check + - s390/ctcm: fix potential memory leak + - s390/lcs: fix variable dereferenced before check + - net/sched: act_pedit: really ensure the skb is writable + - net/smc: non blocking recvmsg() return -EAGAIN when no data and + signal_pending + - net: sfc: ef10: fix memory leak in efx_ef10_mtd_probe() + - gfs2: Fix filesystem block deallocation for short writes + - hwmon: (f71882fg) Fix negative temperature + - ASoC: max98090: Reject invalid values in custom control put() + - ASoC: max98090: Generate notifications on changes for custom control + - ASoC: ops: Validate input values in snd_soc_put_volsw_range() + - s390: disable -Warray-bounds + - net: emaclite: Don't advertise 1000BASE-T and do auto negotiation + - tcp: resalt the secret every 10 seconds + - tty: n_gsm: fix mux activation issues in gsm_config() + - usb: cdc-wdm: fix reading stuck on device close + - usb: typec: tcpci: Don't skip cleanup in .remove() on error + - USB: serial: pl2303: add device id for HP LM930 Display + - USB: serial: qcserial: add support for Sierra Wireless EM7590 + - USB: serial: option: add Fibocom L610 modem + - USB: serial: option: add Fibocom MA510 modem + - slimbus: qcom: Fix IRQ check in qcom_slim_probe + - serial: 8250_mtk: Fix UART_EFR register address + - serial: 8250_mtk: Fix register address for XON/XOFF character + - drm/nouveau/tegra: Stop using iommu_present() + - i40e: i40e_main: fix a missing check on list iterator + - cgroup/cpuset: Remove cpus_allowed/mems_allowed setup in cpuset_init_smp() + - drm/vmwgfx: Initialize drm_mode_fb_cmd2 + - MIPS: fix build with gcc-12 + - net: phy: Fix race condition on link status change + - arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map + - ping: fix address binding wrt vrf + - tty/serial: digicolor: fix possible null-ptr-deref in digicolor_uart_probe() + - Linux 5.4.195 + * Focal update: v5.4.194 upstream stable release (LP: #1980399) + - MIPS: Use address-of operator on section symbols + - block: drbd: drbd_nl: Make conversion to 'enum drbd_ret_code' explicit + - drm/amd/display/dc/gpio/gpio_service: Pass around correct dce_{version, + environment} types + - drm/i915: Cast remain to unsigned long in eb_relocate_vma + - nfp: bpf: silence bitwise vs. logical OR warning + - can: grcan: grcan_probe(): fix broken system id check for errata workaround + needs + - can: grcan: only use the NAPI poll budget for RX + - arm: remove CONFIG_ARCH_HAS_HOLES_MEMORYMODEL + - [Config] updateconfigs for ARCH_HAS_HOLES_MEMORYMODEL + - KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id() + - x86/asm: Allow to pass macros to __ASM_FORM() + - x86: xen: kvm: Gather the definition of emulate prefixes + - x86: xen: insn: Decode Xen and KVM emulate-prefix signature + - x86: kprobes: Prohibit probing on instruction which has emulate prefix + - KVM: x86/svm: Account for family 17h event renumberings in + amd_pmc_perf_hw_id + - Bluetooth: Fix the creation of hdev->name + - mm: fix missing cache flush for all tail pages of compound page + - mm: hugetlb: fix missing cache flush in copy_huge_page_from_user() + - mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and + __mcopy_atomic() + - Linux 5.4.194 + * Focal update: v5.4.193 upstream stable release (LP: #1979566) + - MIPS: Fix CP0 counter erratum detection for R4k CPUs + - parisc: Merge model and model name into one line in /proc/cpuinfo + - ALSA: fireworks: fix wrong return count shorter than expected by 4 bytes + - gpiolib: of: fix bounds check for 'gpio-reserved-ranges' + - Revert "SUNRPC: attempt AF_LOCAL connect on setup" + - firewire: fix potential uaf in outbound_phy_packet_callback() + - firewire: remove check of list iterator against head past the loop body + - firewire: core: extend card->lock in fw_core_handle_bus_reset + - ACPICA: Always create namespace nodes using acpi_ns_create_node() + - genirq: Synchronize interrupt thread startup + - ASoC: da7219: Fix change notifications for tone generator frequency + - ASoC: wm8958: Fix change notifications for DSP controls + - ASoC: meson: Fix event generation for G12A tohdmi mux + - s390/dasd: fix data corruption for ESE devices + - s390/dasd: prevent double format of tracks for ESE devices + - s390/dasd: Fix read for ESE with blksize < 4k + - s390/dasd: Fix read inconsistency for ESE DASD devices + - can: grcan: grcan_close(): fix deadlock + - can: grcan: use ofdev->dev when allocating DMA memory + - nfc: replace improper check device_is_registered() in netlink related + functions + - NFC: netlink: fix sleep in atomic bug when firmware download timeout + - hwmon: (adt7470) Fix warning on module removal + - ASoC: dmaengine: Restore NULL prepare_slave_config() callback + - RDMA/siw: Fix a condition race issue in MPA request processing + - net: ethernet: mediatek: add missing of_node_put() in mtk_sgmii_init() + - net: stmmac: dwmac-sun8i: add missing of_node_put() in + sun8i_dwmac_register_mdio_mux() + - net: emaclite: Add error handling for of_address_to_resource() + - selftests: mirror_gre_bridge_1q: Avoid changing PVID while interface is + operational + - bnxt_en: Fix possible bnxt_open() failure caused by wrong RFS flag + - smsc911x: allow using IRQ0 + - btrfs: always log symlinks in full mode + - net: igmp: respect RCU rules in ip_mc_source() and ip_mc_msfilter() + - drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu + - NFSv4: Don't invalidate inode attributes on delegation return + - kvm: x86/cpuid: Only provide CPUID leaf 0xA if host has architectural PMU + - x86/kvm: Preserve BSP MSR_KVM_POLL_CONTROL across suspend/resume + - KVM: LAPIC: Enable timer posted-interrupt only when mwait/hlt is advertised + - net: ipv6: ensure we call ipv6_mc_down() at most once + - block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern + - mm: fix unexpected zeroed page mapping with zram swap + - ALSA: pcm: Fix races among concurrent hw_params and hw_free calls + - ALSA: pcm: Fix races among concurrent read/write and buffer changes + - ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls + - ALSA: pcm: Fix races among concurrent prealloc proc writes + - ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock + - tcp: make sure treq->af_specific is initialized + - dm: fix mempool NULL pointer race when completing IO + - dm: interlock pending dm_io and dm_wait_for_bios_completion + - PCI: aardvark: Clear all MSIs at setup + - PCI: aardvark: Fix reading MSI interrupt number + - mmc: rtsx: add 74 Clocks in power on flow + - Linux 5.4.193 + * CVE-2022-1679 + - SAUCE: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb + * CVE-2022-28893 + - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free() + - SUNRPC: Don't leak sockets in xs_local_connect() + * CVE-2022-1734 + - nfc: nfcmrvl: main: reorder destructive operations in + nfcmrvl_nci_unregister_dev to avoid bugs + * CVE-2022-1652 + - floppy: use a statically allocated error counter + + -- Joseph Salisbury Thu, 14 Jul 2022 13:26:00 -0400 + +linux-oracle (5.4.0-1079.87) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1079.87 -proposed tracker (LP: #1979479) + + * Focal update: upstream stable patchset v5.4.192 (LP: #1979014) + - [Config] updateconfigs for BLK_DEV_FD_RAWCMD + - [Config] updateconfigs for NVM, NVM_PBLK + + [ Ubuntu: 5.4.0-122.138 ] + + * focal/linux: 5.4.0-122.138 -proposed tracker (LP: #1979489) + * Remove SAUCE patches from test_vxlan_under_vrf.sh in net of + ubuntu_kernel_selftests (LP: #1975691) + - Revert "UBUNTU: SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on + xfail" + - Revert "UBUNTU: SAUCE: selftests: net: Make test for VXLAN underlay in non- + default VRF an expected failure" + * Enable Asus USB-BT500 Bluetooth dongle(0b05:190e) (LP: #1976613) + - Bluetooth: btusb: Add flag to define wideband speech capability + - Bluetooth: btrtl: Add support for RTL8761B + - Bluetooth: btusb: Add 0x0b05:0x190e Realtek 8761BU (ASUS BT500) device. + * [UBUNTU 20.04] rcu stalls with many storage key guests (LP: #1975582) + - s390/gmap: voluntarily schedule during key setting + - s390/mm: use non-quiescing sske for KVM switch to keyed guest + * Ubuntu 5.4.0-117.132-generic 5.4.189 has BUG: kernel NULL pointer + dereference, address: 0000000000000034 (LP: #1978719) + - mm: rmap: explicitly reset vma->anon_vma in unlink_anon_vmas() + * Focal update: upstream stable patchset v5.4.192 (LP: #1979014) + - floppy: disable FDRAWCMD by default + - [Config] updateconfigs for BLK_DEV_FD_RAWCMD + - hamradio: defer 6pack kfree after unregister_netdev + - hamradio: remove needs_free_netdev to avoid UAF + - lightnvm: disable the subsystem + - [Config] updateconfigs for NVM, NVM_PBLK + - usb: mtu3: fix USB 3.0 dual-role-switch from device to host + - USB: quirks: add a Realtek card reader + - USB: quirks: add STRING quirk for VCOM device + - USB: serial: whiteheat: fix heap overflow in WHITEHEAT_GET_DTR_RTS + - USB: serial: cp210x: add PIDs for Kamstrup USB Meter Reader + - USB: serial: option: add support for Cinterion MV32-WA/MV32-WB + - USB: serial: option: add Telit 0x1057, 0x1058, 0x1075 compositions + - xhci: stop polling roothubs after shutdown + - xhci: increase usb U3 -> U0 link resume timeout from 100ms to 500ms + - iio: dac: ad5592r: Fix the missing return value. + - iio: dac: ad5446: Fix read_raw not returning set value + - iio: magnetometer: ak8975: Fix the error handling in ak8975_power_on() + - usb: misc: fix improper handling of refcount in uss720_probe() + - usb: typec: ucsi: Fix role swapping + - usb: gadget: uvc: Fix crash when encoding data for usb request + - usb: gadget: configfs: clear deactivation flag in + configfs_composite_unbind() + - usb: dwc3: core: Fix tx/rx threshold settings + - usb: dwc3: gadget: Return proper request status + - serial: imx: fix overrun interrupts in DMA mode + - serial: 8250: Also set sticky MCR bits in console restoration + - serial: 8250: Correct the clock for EndRun PTP/1588 PCIe device + - arch_topology: Do not set llc_sibling if llc_id is invalid + - hex2bin: make the function hex_to_bin constant-time + - hex2bin: fix access beyond string end + - video: fbdev: udlfb: properly check endpoint type + - arm64: dts: meson: remove CPU opps below 1GHz for G12B boards + - arm64: dts: meson: remove CPU opps below 1GHz for SM1 boards + - mtd: rawnand: fix ecc parameters for mt7622 + - USB: Fix xhci event ring dequeue pointer ERDP update issue + - ARM: dts: imx6qdl-apalis: Fix sgtl5000 detection issue + - phy: samsung: Fix missing of_node_put() in exynos_sata_phy_probe + - phy: samsung: exynos5250-sata: fix missing device put in probe error paths + - ARM: OMAP2+: Fix refcount leak in omap_gic_of_init + - phy: ti: omap-usb2: Fix error handling in omap_usb2_enable_clocks + - ARM: dts: at91: Map MCLK for wm8731 on at91sam9g20ek + - phy: mapphone-mdm6600: Fix PM error handling in phy_mdm6600_probe + - phy: ti: Add missing pm_runtime_disable() in serdes_am654_probe + - ARM: dts: Fix mmc order for omap3-gta04 + - ARM: dts: am3517-evm: Fix misc pinmuxing + - ARM: dts: logicpd-som-lv: Fix wrong pinmuxing on OMAP35 + - ipvs: correctly print the memory size of ip_vs_conn_tab + - mtd: rawnand: Fix return value check of wait_for_completion_timeout + - bpf, lwt: Fix crash when using bpf_skb_set_tunnel_key() from bpf_xmit lwt + hook + - tcp: md5: incorrect tcp_header_len for incoming connections + - tcp: ensure to use the most recently sent skb when filling the rate sample + - sctp: check asoc strreset_chunk in sctp_generate_reconf_event + - ARM: dts: imx6ull-colibri: fix vqmmc regulator + - arm64: dts: imx8mn-ddr4-evk: Describe the 32.768 kHz PMIC clock + - pinctrl: pistachio: fix use of irq_of_parse_and_map() + - cpufreq: fix memory leak in sun50i_cpufreq_nvmem_probe + - net: hns3: add validity check for message data length + - net/smc: sync err code when tcp connection was refused + - ip_gre: Make o_seqno start from 0 in native mode + - tcp: fix potential xmit stalls caused by TCP_NOTSENT_LOWAT + - bus: sunxi-rsb: Fix the return value of sunxi_rsb_device_create() + - clk: sunxi: sun9i-mmc: check return value after calling + platform_get_resource() + - net: bcmgenet: hide status block before TX timestamping + - net: dsa: lantiq_gswip: Don't set GSWIP_MII_CFG_RMII_CLK + - drm/amd/display: Fix memory leak in dcn21_clock_source_create + - tls: Skip tls_append_frag on zero copy size + - bnx2x: fix napi API usage sequence + - ixgbe: ensure IPsec VF<->PF compatibility + - tcp: fix F-RTO may not work correctly when receiving DSACK + - ASoC: wm8731: Disable the regulator when probing fails + - ip6_gre: Avoid updating tunnel->tun_hlen in __gre6_xmit() + - x86: __memcpy_flushcache: fix wrong alignment if size > 2^32 + - cifs: destage any unwritten data to the server before calling + copychunk_write + - drivers: net: hippi: Fix deadlock in rr_close() + - net: ethernet: stmmac: fix write to sgmii_adapter_base + - x86/cpu: Load microcode during restore_processor_state() + - tty: n_gsm: fix wrong signal octet encoding in convergence layer type 2 + - tty: n_gsm: fix malformed counter for out of frame data + - netfilter: nft_socket: only do sk lookups when indev is available + - tty: n_gsm: fix insufficient txframe size + - tty: n_gsm: fix missing explicit ldisc flush + - tty: n_gsm: fix wrong command retry handling + - tty: n_gsm: fix wrong command frame length field encoding + - tty: n_gsm: fix incorrect UA handling + - hugetlbfs: get unmapped area below TASK_UNMAPPED_BASE for hugetlbfs + - mm, hugetlb: allow for "high" userspace addresses + - Linux 5.4.192 + * CVE-2022-1789 + - KVM: x86/mmu: fix NULL pointer dereference on guest INVPCID + * Focal update: v5.4.191 upstream stable release (LP: #1976116) + - etherdevice: Adjust ether_addr* prototypes to silence -Wstringop-overead + - mm: page_alloc: fix building error on -Werror=array-compare + - tracing: Dump stacktrace trigger to the corresponding instance + - gfs2: assign rgrp glock before compute_bitstructs + - tcp: fix race condition when creating child sockets from syncookies + - tcp: Fix potential use-after-free due to double kfree() + - ALSA: usb-audio: Clear MIDI port active flag after draining + - ASoC: atmel: Remove system clock tree configuration for at91sam9g20ek + - ASoC: msm8916-wcd-digital: Check failure for devm_snd_soc_register_component + - dmaengine: imx-sdma: Fix error checking in sdma_event_remap + - dmaengine: mediatek:Fix PM usage reference leak of + mtk_uart_apdma_alloc_chan_resources + - igc: Fix infinite loop in release_swfw_sync + - igc: Fix BUG: scheduling while atomic + - rxrpc: Restore removed timer deletion + - net/smc: Fix sock leak when release after smc_shutdown() + - net/packet: fix packet_sock xmit return value checking + - net/sched: cls_u32: fix possible leak in u32_init_knode() + - l3mdev: l3mdev_master_upper_ifindex_by_index_rcu should be using + netdev_master_upper_dev_get_rcu + - netlink: reset network and mac headers in netlink_dump() + - selftests: mlxsw: vxlan_flooding: Prevent flooding of unwanted packets + - ARM: vexpress/spc: Avoid negative array index when !SMP + - reset: tegra-bpmp: Restore Handle errors in BPMP response + - platform/x86: samsung-laptop: Fix an unsigned comparison which can never be + negative + - ALSA: usb-audio: Fix undefined behavior due to shift overflowing the + constant + - vxlan: fix error return code in vxlan_fdb_append + - cifs: Check the IOCB_DIRECT flag, not O_DIRECT + - mt76: Fix undefined behavior due to shift overflowing the constant + - brcmfmac: sdio: Fix undefined behavior due to shift overflowing the constant + - dpaa_eth: Fix missing of_node_put in dpaa_get_ts_info() + - drm/msm/mdp5: check the return of kzalloc() + - net: macb: Restart tx only if queue pointer is lagging + - scsi: qedi: Fix failed disconnect handling + - stat: fix inconsistency between struct stat and struct compat_stat + - EDAC/synopsys: Read the error count from the correct register + - oom_kill.c: futex: delay the OOM reaper to allow time for proper futex + cleanup + - ata: pata_marvell: Check the 'bmdma_addr' beforing reading + - dma: at_xdmac: fix a missing check on list iterator + - drm/panel/raspberrypi-touchscreen: Avoid NULL deref if not initialised + - drm/panel/raspberrypi-touchscreen: Initialise the bridge in prepare + - KVM: PPC: Fix TCE handling for VFIO + - drm/vc4: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage + - powerpc/perf: Fix power9 event alternatives + - xtensa: patch_text: Fixup last cpu should be master + - xtensa: fix a7 clobbering in coprocessor context load/store + - openvswitch: fix OOB access in reserve_sfa_size() + - ASoC: soc-dapm: fix two incorrect uses of list iterator + - e1000e: Fix possible overflow in LTR decoding + - ARC: entry: fix syscall_trace_exit argument + - arm_pmu: Validate single/group leader events + - ext4: fix symlink file size not match to file content + - ext4: fix use-after-free in ext4_search_dir + - ext4, doc: fix incorrect h_reserved size + - ext4: fix overhead calculation to account for the reserved gdt blocks + - ext4: force overhead calculation if the s_overhead_cluster makes no sense + - jbd2: fix a potential race while discarding reserved buffers after an abort + - spi: atmel-quadspi: Fix the buswidth adjustment between spi-mem and + controller + - staging: ion: Prevent incorrect reference counting behavour + - block/compat_ioctl: fix range check in BLKGETSIZE + - Linux 5.4.191 + * Focal update: v5.4.190 upstream stable release (LP: #1973085) + - memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe + - net/sched: flower: fix parsing of ethertype following VLAN header + - veth: Ensure eth header is in skb's linear part + - gpiolib: acpi: use correct format characters + - mlxsw: i2c: Fix initialization error flow + - net/sched: fix initialization order when updating chain 0 head + - net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link + - net/sched: taprio: Check if socket flags are valid + - cfg80211: hold bss_lock while updating nontrans_list + - drm/msm/dsi: Use connector directly in msm_dsi_manager_connector_init() + - net/smc: Fix NULL pointer dereference in smc_pnet_find_ib() + - sctp: Initialize daddr on peeled off socket + - testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu set + - nfc: nci: add flush_workqueue to prevent uaf + - cifs: potential buffer overflow in handling symlinks + - drm/amd: Add USBC connector ID + - drm/amd/display: fix audio format not updated after edid updated + - drm/amd/display: Update VTEM Infopacket definition + - drm/amdkfd: Fix Incorrect VMIDs passed to HWS + - drm/amdkfd: Check for potential null return of kmalloc_array() + - Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer + - scsi: target: tcmu: Fix possible page UAF + - scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024 + - ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs + - gpu: ipu-v3: Fix dev_dbg frequency output + - regulator: wm8994: Add an off-on delay for WM8994 variant + - arm64: alternatives: mark patch_alternative() as `noinstr` + - tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry + - net: usb: aqc111: Fix out-of-bounds accesses in RX fixup + - drm/amd/display: Fix allocate_mst_payload assert on resume + - powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit + - scsi: mvsas: Add PCI ID of RocketRaid 2640 + - scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan + - drivers: net: slip: fix NPD bug in sl_tx_timeout() + - perf/imx_ddr: Fix undefined behavior due to shift overflowing the constant + - mm, page_alloc: fix build_zonerefs_node() + - mm: kmemleak: take a full lowmem check in kmemleak_*_phys() + - gcc-plugins: latent_entropy: use /dev/urandom + - ath9k: Properly clear TX status area before reporting to mac80211 + - ath9k: Fix usage of driver-private space in tx_info + - btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups() + - btrfs: mark resumed async balance as writing + - ALSA: hda/realtek: Add quirk for Clevo PD50PNT + - ALSA: pcm: Test for "silence" field in struct "pcm_format_data" + - ipv6: fix panic when forwarding a pkt with no in6 dev + - drm/amd/display: don't ignore alpha property on pre-multiplied mode + - genirq/affinity: Consider that CPUs on nodes can be unbalanced + - tick/nohz: Use WARN_ON_ONCE() to prevent console saturation + - ARM: davinci: da850-evm: Avoid NULL pointer dereference + - dm integrity: fix memory corruption when tag_size is less than digest size + - smp: Fix offline cpu check in flush_smp_call_function_queue() + - i2c: pasemi: Wait for write xfers to finish + - dma-direct: avoid redundant memory sync for swiotlb + - ax25: add refcount in ax25_dev to avoid UAF bugs + - ax25: fix reference count leaks of ax25_dev + - ax25: fix UAF bugs of net_device caused by rebinding operation + - ax25: Fix refcount leaks caused by ax25_cb_del() + - ax25: fix UAF bug in ax25_send_control() + - ax25: fix NPD bug in ax25_disconnect + - ax25: Fix NULL pointer dereferences in ax25 timers + - ax25: Fix UAF bugs in ax25 timers + - Linux 5.4.190 + + [ Ubuntu: 5.4.0-121.137 ] + + * focal/linux: 5.4.0-121.137 -proposed tracker (LP: #1978666) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.05.30) + * CVE-2022-28388 + - can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error + path + * test_vxlan_under_vrf.sh in net from ubuntu_kernel_selftests failed (Check VM + connectivity through VXLAN (underlay in the default VRF) [FAIL]) + (LP: #1871015) + - selftests: net: test_vxlan_under_vrf: fix HV connectivity test + * [UBUNTU 20.04] CPU-MF: add extended counter set definitions for new IBM z16 + (LP: #1974433) + - s390/cpumf: add new extended counter set for IBM z16 + * [UBUNTU 20.04] KVM nesting support leaks too much memory, might result in + stalls during cleanup (LP: #1974017) + - KVM: s390: vsie/gmap: reduce gmap_rmap overhead + * [UBUNTU 20.04] Null Pointer issue in nfs code running Ubuntu on IBM Z + (LP: #1968096) + - NFS: Fix up nfs_ctx_key_to_expire() + + -- Joseph Salisbury Wed, 22 Jun 2022 14:29:37 -0400 + +linux-oracle (5.4.0-1078.86) focal; urgency=medium + + [ Ubuntu: 5.4.0-120.136 ] + + * CVE-2022-21123 // CVE-2022-21125 // CVE-2022-21166 + - cpu/speculation: Add prototype for cpu_show_srbds() + - x86/cpu: Add Jasper Lake to Intel family + - x86/cpu: Add Lakefield, Alder Lake and Rocket Lake models to the to Intel + CPU family + - x86/cpu: Add another Alder Lake CPU to the Intel family + - Documentation: Add documentation for Processor MMIO Stale Data + - x86/speculation/mmio: Enumerate Processor MMIO Stale Data bug + - x86/speculation: Add a common function for MD_CLEAR mitigation update + - x86/speculation/mmio: Add mitigation for Processor MMIO Stale Data + - x86/bugs: Group MDS, TAA & Processor MMIO Stale Data mitigations + - x86/speculation/mmio: Enable CPU Fill buffer clearing on idle + - x86/speculation/mmio: Add sysfs reporting for Processor MMIO Stale Data + - x86/speculation/srbds: Update SRBDS mitigation selection + - x86/speculation/mmio: Reuse SRBDS mitigation for SBDS + - KVM: x86/speculation: Disable Fill buffer clear within guests + - x86/speculation/mmio: Print SMT warning + + -- Thadeu Lima de Souza Cascardo Fri, 10 Jun 2022 12:44:31 -0300 + +linux-oracle (5.4.0-1076.83) focal; urgency=medium + + [ Ubuntu: 5.4.0-117.132 ] + + * CVE-2022-1966 + - netfilter: nf_tables: add nft_set_elem_expr_alloc() + - netfilter: nf_tables: disallow non-stateful expression in sets earlier + + -- Thadeu Lima de Souza Cascardo Wed, 01 Jun 2022 22:23:06 -0300 + +linux-oracle (5.4.0-1074.80) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1074.80 -proposed tracker (LP: #1974380) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.05.09) + + [ Ubuntu: 5.4.0-115.129 ] + + * CVE-2022-21499 + - SAUCE: debug: Lock down kgdb + + [ Ubuntu: 5.4.0-114.128 ] + + * focal/linux: 5.4.0-114.128 -proposed tracker (LP: #1974391) + * 32 GT/s PCI link speeds reporting "Unknown speed" in sysfs (LP: #1970798) + - PCI: Add 32 GT/s decoding in some macros + - PCI: Add pci_speed_string() + - PCI: Use pci_speed_string() for all PCI/PCI-X/PCIe strings + - PCI: Add PCIE_LNKCAP2_SLS2SPEED() macro + * issuing invalid ioctl to /dev/vsock may spam dmesg (LP: #1971480) + - vsock: remove ratelimit unknown ioctl message + * config CONFIG_HISI_PMU for kunpeng920 (LP: #1956086) + - drivers/perf: hisi: Permit modular builds of HiSilicon uncore drivers + - [Config] CONFIG_HISI_PMU=m + * Focal update: v5.4.189 upstream stable release (LP: #1971497) + - swiotlb: fix info leak with DMA_FROM_DEVICE + - USB: serial: pl2303: add IBM device IDs + - USB: serial: simple: add Nokia phone driver + - netdevice: add the case if dev is NULL + - HID: logitech-dj: add new lightspeed receiver id + - xfrm: fix tunnel model fragmentation behavior + - virtio_console: break out of buf poll on remove + - ethernet: sun: Free the coherent when failing in probing + - spi: Fix invalid sgs value + - net:mcf8390: Use platform_get_irq() to get the interrupt + - spi: Fix erroneous sgs value with min_t() + - af_key: add __GFP_ZERO flag for compose_sadb_supported in function + pfkey_register + - net: dsa: microchip: add spi_device_id tables + - iommu/iova: Improve 32-bit free space estimate + - tpm: fix reference counting for struct tpm_chip + - block: Add a helper to validate the block size + - virtio-blk: Use blk_validate_block_size() to validate block size + - USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c + - xhci: fix runtime PM imbalance in USB2 resume + - xhci: make xhci_handshake timeout for xhci_reset() adjustable + - xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx() + - coresight: Fix TRCCONFIGR.QE sysfs interface + - iio: afe: rescale: use s64 for temporary scale calculations + - iio: inkern: apply consumer scale on IIO_VAL_INT cases + - iio: inkern: apply consumer scale when no channel scale is available + - iio: inkern: make a best effort on offset calculation + - greybus: svc: fix an error handling bug in gb_svc_hello() + - clk: uniphier: Fix fixed-rate initialization + - KEYS: fix length validation in keyctl_pkey_params_get_2() + - Documentation: add link to stable release candidate tree + - Documentation: update stable tree link + - HID: intel-ish-hid: Use dma_alloc_coherent for firmware update + - SUNRPC: avoid race between mod_timer() and del_timer_sync() + - NFSD: prevent underflow in nfssvc_decode_writeargs() + - NFSD: prevent integer overflow on 32 bit systems + - f2fs: fix to unlock page correctly in error path of is_alive() + - f2fs: quota: fix loop condition at f2fs_quota_sync() + - f2fs: fix to do sanity check on .cp_pack_total_block_count + - pinctrl: samsung: drop pin banks references on error paths + - spi: mxic: Fix the transmit path + - jffs2: fix use-after-free in jffs2_clear_xattr_subsystem + - jffs2: fix memory leak in jffs2_do_mount_fs + - jffs2: fix memory leak in jffs2_scan_medium + - mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node + - mm: invalidate hwpoison page cache page in fault path + - mempolicy: mbind_range() set_policy() after vma_merge() + - scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands + - qed: display VF trust config + - qed: validate and restrict untrusted VFs vlan promisc mode + - riscv: Fix fill_callchain return value + - Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads" + - ALSA: cs4236: fix an incorrect NULL check on list iterator + - ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020 + - mm,hwpoison: unmap poisoned page before invalidation + - mm/kmemleak: reset tag when compare object pointer + - drbd: fix potential silent data corruption + - powerpc/kvm: Fix kvm_use_magic_page + - udp: call udp_encap_enable for v6 sockets when enabling encap + - ACPI: properties: Consistently return -ENOENT if there are no more + references + - drivers: hamradio: 6pack: fix UAF bug caused by mod_timer() + - mailbox: tegra-hsp: Flush whole channel + - block: don't merge across cgroup boundaries if blkcg is enabled + - drm/edid: check basic audio support on CEA extension block + - video: fbdev: sm712fb: Fix crash in smtcfb_read() + - video: fbdev: atari: Atari 2 bpp (STe) palette bugfix + - ARM: dts: at91: sama5d2: Fix PMERRLOC resource size + - ARM: dts: exynos: fix UART3 pins configuration in Exynos5250 + - ARM: dts: exynos: add missing HDMI supplies on SMDK5250 + - ARM: dts: exynos: add missing HDMI supplies on SMDK5420 + - carl9170: fix missing bit-wise or operator for tx_params + - thermal: int340x: Increase bitmap size + - lib/raid6/test: fix multiple definition linking error + - crypto: rsa-pkcs1pad - correctly get hash from source scatterlist + - crypto: rsa-pkcs1pad - restore signature length check + - crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete() + - DEC: Limit PMAX memory probing to R3k systems + - media: davinci: vpif: fix unbalanced runtime PM get + - xtensa: fix stop_machine_cpuslocked call in patch_text + - xtensa: fix xtensa_wsr always writing 0 + - brcmfmac: firmware: Allocate space for default boardrev in nvram + - brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path + - brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio + - brcmfmac: pcie: Fix crashes due to early IRQs + - PCI: pciehp: Clear cmd_busy bit in polling mode + - regulator: qcom_smd: fix for_each_child.cocci warnings + - crypto: authenc - Fix sleep in atomic context in decrypt_tail + - crypto: mxs-dcp - Fix scatterlist processing + - spi: tegra114: Add missing IRQ check in tegra_spi_probe + - selftests/x86: Add validity check and allow field splitting + - audit: log AUDIT_TIME_* records only from rules + - crypto: ccree - don't attempt 0 len DMA mappings + - spi: pxa2xx-pci: Balance reference count for PCI DMA device + - hwmon: (pmbus) Add mutex to regulator ops + - hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING + - block: don't delete queue kobject before its children + - PM: hibernate: fix __setup handler error handling + - PM: suspend: fix return value of __setup handler + - hwrng: atmel - disable trng on failure path + - crypto: vmx - add missing dependencies + - clocksource/drivers/timer-of: Check return value of of_iomap in + timer_of_base_init() + - ACPI: APEI: fix return value of __setup handlers + - crypto: ccp - ccp_dmaengine_unregister release dma channels + - hwmon: (pmbus) Add Vin unit off handling + - clocksource: acpi_pm: fix return value of __setup handler + - sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa + - perf/core: Fix address filter parser for multiple filters + - perf/x86/intel/pt: Fix address filter config for 32-bit kernel + - f2fs: fix missing free nid in f2fs_handle_failed_inode + - f2fs: fix to avoid potential deadlock + - media: bttv: fix WARNING regression on tunerless devices + - media: coda: Fix missing put_device() call in coda_get_vdoa_data + - media: hantro: Fix overfill bottom register field name + - media: aspeed: Correct value for h-total-pixels + - video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe() + - video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe() + - video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name() + - ARM: dts: qcom: ipq4019: fix sleep clock + - soc: qcom: rpmpd: Check for null return of devm_kcalloc + - soc: qcom: aoss: remove spurious IRQF_ONESHOT flags + - arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc + - soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe + - ARM: dts: imx: Add missing LVDS decoder on M53Menlo + - media: video/hdmi: handle short reads of hdmi info frame. + - media: em28xx: initialize refcount before kref_get + - media: usb: go7007: s2250-board: fix leak in probe() + - uaccess: fix nios2 and microblaze get_user_8() + - ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp() + - ASoC: ti: davinci-i2s: Add check for clk_enable() + - ALSA: spi: Add check for clk_enable() + - arm64: dts: ns2: Fix spi-cpol and spi-cpha property + - arm64: dts: broadcom: Fix sata nodename + - printk: fix return value of printk.devkmsg __setup handler + - ASoC: mxs-saif: Handle errors for clk_enable + - ASoC: atmel_ssc_dai: Handle errors for clk_enable + - ASoC: soc-compress: prevent the potentially use of null pointer + - memory: emif: Add check for setup_interrupts + - memory: emif: check the pointer temp in get_device_details() + - ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction + - arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly + - media: stk1160: If start stream fails, return buffers with + VB2_BUF_STATE_QUEUED + - ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe + - ASoC: wm8350: Handle error for wm8350_register_irq + - ASoC: fsi: Add check for clk_enable + - video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of + - ivtv: fix incorrect device_caps for ivtvfb + - ASoC: dmaengine: do not use a NULL prepare_slave_config() callback + - ASoC: mxs: Fix error handling in mxs_sgtl5000_probe + - ASoC: imx-es8328: Fix error return code in imx_es8328_probe() + - ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in + msm8916_wcd_digital_probe + - mmc: davinci_mmc: Handle error for clk_enable + - ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe + - drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev + - drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe + - ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern + - udmabuf: validate ubuf->pagecount + - Bluetooth: hci_serdev: call init_rwsem() before p->open() + - mtd: onenand: Check for error irq + - mtd: rawnand: gpmi: fix controller timings setting + - drm/edid: Don't clear formats if using deep color + - drm/amd/display: Fix a NULL pointer dereference in + amdgpu_dm_connector_add_common_modes() + - ath9k_htc: fix uninit value bugs + - KVM: PPC: Fix vmx/vsx mixup in mmio emulation + - i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb + - power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe + - ray_cs: Check ioremap return value + - powerpc/perf: Don't use perf_hw_context for trace IMC PMU + - mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update + - mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update + - net: dsa: mv88e6xxx: Enable port policy support on 6097 + - PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge + - power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init + - HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports + - iommu/ipmmu-vmsa: Check for error num after setting mask + - drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug + - IB/cma: Allow XRC INI QPs to set their local ACK timeout + - dax: make sure inodes are flushed before destroy cache + - iwlwifi: Fix -EIO error code that is never returned + - iwlwifi: mvm: Fix an error code in iwl_mvm_up() + - dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS + - scsi: pm8001: Fix command initialization in pm80XX_send_read_log() + - scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() + - scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() + - scsi: pm8001: Fix abort all task initialization + - drm/amd/display: Remove vupdate_int_entry definition + - TOMOYO: fix __setup handlers return values + - ext2: correct max file size computing + - drm/tegra: Fix reference leak in tegra_dsi_ganged_probe + - power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false + return + - scsi: hisi_sas: Change permission of parameter prot_mask + - drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt + - bpf, arm64: Call build_prologue() first in first JIT pass + - bpf, arm64: Feed byte-offset into bpf line info + - libbpf: Skip forward declaration when counting duplicated type names + - powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit + - KVM: x86: Fix emulation in writing cr8 + - KVM: x86/emulator: Defer not-present segment check in + __load_segment_descriptor() + - hv_balloon: rate-limit "Unhandled message" warning + - i2c: xiic: Make bus names unique + - power: supply: wm8350-power: Handle error for wm8350_register_irq + - power: supply: wm8350-power: Add missing free in free_charger_irq + - PCI: Reduce warnings on possible RW1C corruption + - mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n + - powerpc/sysdev: fix incorrect use to determine if list is empty + - mfd: mc13xxx: Add check for mc13xxx_irq_request + - selftests/bpf: Make test_lwt_ip_encap more stable and faster + - powerpc: 8xx: fix a return value error in mpc8xx_pic_init + - vxcan: enable local echo for sent CAN frames + - MIPS: RB532: fix return value of __setup handler + - mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init + - RDMA/mlx5: Fix memory leak in error flow for subscribe event routine + - bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full + - bpf, sockmap: Fix more uncharged while msg has more_data + - bpf, sockmap: Fix double uncharge the mem of sk_msg + - USB: storage: ums-realtek: fix error code in rts51x_read_mem() + - Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt + - af_netlink: Fix shift out of bounds in group mask calculation + - i2c: mux: demux-pinctrl: do not deactivate a master that is not active + - selftests/bpf/test_lirc_mode2.sh: Exit with proper code + - tcp: ensure PMTU updates are processed during fastopen + - openvswitch: always update flow key after nat + - tipc: fix the timer expires after interval 100ms + - mfd: asic3: Add missing iounmap() on error asic3_mfd_probe + - mxser: fix xmit_buf leak in activate when LSR == 0xff + - pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add() + - misc: alcor_pci: Fix an error handling path + - staging:iio:adc:ad7280a: Fix handing of device address bit reversing. + - pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel + - clk: qcom: ipq8074: Use floor ops for SDCC1 clock + - phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure}) + - serial: 8250_mid: Balance reference count for PCI DMA device + - serial: 8250: Fix race condition in RTS-after-send handling + - iio: adc: Add check for devm_request_threaded_irq + - NFS: Return valid errors from nfs2/3_decode_dirent() + - dma-debug: fix return value of __setup handlers + - clk: imx7d: Remove audio_mclk_root_clk + - clk: qcom: clk-rcg2: Update logic to calculate D value for RCG + - clk: qcom: clk-rcg2: Update the frac table for pixel clock + - remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region + - remoteproc: qcom_wcnss: Add missing of_node_put() in + wcnss_alloc_memory_region + - clk: actions: Terminate clk_div_table with sentinel element + - clk: loongson1: Terminate clk_div_table with sentinel element + - clk: clps711x: Terminate clk_div_table with sentinel element + - clk: tegra: tegra124-emc: Fix missing put_device() call in + emc_ensure_emc_driver + - NFS: remove unneeded check in decode_devicenotify_args() + - staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree + - pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init + - pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get() + - pinctrl: mediatek: paris: Fix pingroup pin config state readback + - pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe + - pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe + - tty: hvc: fix return value of __setup handler + - kgdboc: fix return value of __setup handler + - kgdbts: fix return value of __setup handler + - firmware: google: Properly state IOMEM dependency + - driver core: dd: fix return value of __setup handler + - jfs: fix divide error in dbNextAG + - netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options + - NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error + - clk: qcom: gcc-msm8994: Fix gpll4 width + - clk: Initialize orphan req_rate + - xen: fix is_xen_pmu() + - net: phy: broadcom: Fix brcm_fet_config_init() + - selftests: test_vxlan_under_vrf: Fix broken test case + - qlcnic: dcb: default to returning -EOPNOTSUPP + - net/x25: Fix null-ptr-deref caused by x25_disconnect + - NFSv4/pNFS: Fix another issue with a list iterator pointing to the head + - net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator + - lib/test: use after free in register_test_dev_kmod() + - LSM: general protection fault in legacy_parse_param + - gcc-plugins/stackleak: Exactly match strings instead of prefixes + - pinctrl: npcm: Fix broken references to chip->parent_device + - block, bfq: don't move oom_bfqq + - selinux: use correct type for context length + - loop: use sysfs_emit() in the sysfs xxx show() + - Fix incorrect type in assignment of ipv6 port for audit + - irqchip/qcom-pdc: Fix broken locking + - irqchip/nvic: Release nvic_base upon failure + - bfq: fix use-after-free in bfq_dispatch_request + - ACPICA: Avoid walking the ACPI Namespace if it is not there + - lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3 + - Revert "Revert "block, bfq: honor already-setup queue merges"" + - ACPI/APEI: Limit printable size of BERT table data + - PM: core: keep irq flags in device_pm_check_callbacks() + - spi: tegra20: Use of_device_get_match_data() + - ext4: don't BUG if someone dirty pages without asking ext4 first + - ntfs: add sanity check on allocation size + - video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow + - video: fbdev: w100fb: Reset global state + - video: fbdev: cirrusfb: check pixclock to avoid divide by zero + - video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit + - ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960 + - ARM: dts: bcm2837: Add the missing L1/L2 cache information + - ASoC: madera: Add dependencies on MFD + - video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf() + - video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of + snprintf() + - video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit + - ASoC: soc-core: skip zero num_dai component in searching dai name + - media: cx88-mpeg: clear interrupt status register before streaming video + - ARM: tegra: tamonten: Fix I2C3 pad setting + - ARM: mmp: Fix failure to remove sram device + - video: fbdev: sm712fb: Fix crash in smtcfb_write() + - media: Revert "media: em28xx: add missing em28xx_close_extension" + - media: hdpvr: initialize dev->worker at hdpvr_register_videodev + - mmc: host: Return an error when ->enable_sdio_irq() ops is missing + - ALSA: hda/realtek: Add alc256-samsung-headphone fixup + - powerpc/lib/sstep: Fix 'sthcx' instruction + - powerpc/lib/sstep: Fix build errors with newer binutils + - powerpc: Fix build errors with newer binutils + - scsi: qla2xxx: Fix stuck session in gpdb + - scsi: qla2xxx: Fix wrong FDMI data for 64G adapter + - scsi: qla2xxx: Fix warning for missing error code + - scsi: qla2xxx: Fix device reconnect in loop topology + - scsi: qla2xxx: Add devids and conditionals for 28xx + - scsi: qla2xxx: Check for firmware dump already collected + - scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair() + - scsi: qla2xxx: Fix disk failure to rediscover + - scsi: qla2xxx: Fix incorrect reporting of task management failure + - scsi: qla2xxx: Fix hang due to session stuck + - scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests + - scsi: qla2xxx: Fix N2N inconsistent PLOGI + - scsi: qla2xxx: Reduce false trigger to login + - scsi: qla2xxx: Use correct feature type field during RFF_ID processing + - KVM: Prevent module exit until all VMs are freed + - KVM: x86: fix sending PV IPI + - ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM + - ubifs: rename_whiteout: Fix double free for whiteout_ui->data + - ubifs: Fix deadlock in concurrent rename whiteout and inode writeback + - ubifs: Add missing iput if do_tmpfile() failed in rename whiteout + - ubifs: setflags: Make dirtied_ino_d 8 bytes aligned + - ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock() + - ubifs: rename_whiteout: correct old_dir size computing + - XArray: Fix xas_create_range() when multi-order entry present + - can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path + - can: mcba_usb: properly check endpoint type + - XArray: Update the LRU list in xas_split() + - rtc: check if __rtc_read_time was successful + - gfs2: Make sure FITRIM minlen is rounded up to fs block size + - net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware + - pinctrl: pinconf-generic: Print arguments for bias-pull-* + - pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR() + - pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE() + - ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs + - ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl + - ARM: iop32x: offset IRQ numbers by 1 + - ACPI: CPPC: Avoid out of bounds access when parsing _CPC data + - powerpc/kasan: Fix early region not updated correctly + - ASoC: soc-compress: Change the check for codec_dai + - mm/mmap: return 1 from stack_guard_gap __setup() handler + - mm/memcontrol: return 1 from cgroup.memory __setup() handler + - mm/usercopy: return 1 from hardened_usercopy __setup() handler + - bpf: Fix comment for helper bpf_current_task_under_cgroup() + - dt-bindings: mtd: nand-controller: Fix the reg property description + - dt-bindings: mtd: nand-controller: Fix a comment in the examples + - dt-bindings: spi: mxic: The interrupt property is not mandatory + - ubi: fastmap: Return error code if memory allocation fails in add_aeb() + - ASoC: topology: Allow TLV control to be either read or write + - ARM: dts: spear1340: Update serial node properties + - ARM: dts: spear13xx: Update SPI dma properties + - um: Fix uml_mconsole stop/go + - openvswitch: Fixed nd target mask field in the flow dump. + - KVM: x86/mmu: do compare-and-exchange of gPTE via the user address + - KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated + - ubifs: Rectify space amount budget for mkdir/tmpfile operations + - rtc: wm8350: Handle error for wm8350_register_irq + - riscv module: remove (NOLOAD) + - ARM: 9187/1: JIVE: fix return value of __setup handler + - KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs + - drm: Add orientation quirk for GPD Win Max + - ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111 + - drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj + - ptp: replace snprintf with sysfs_emit + - powerpc: dts: t104xrdb: fix phy type for FMAN 4/5 + - bpf: Make dst_port field in struct bpf_sock 16-bit wide + - scsi: mvsas: Replace snprintf() with sysfs_emit() + - scsi: bfa: Replace snprintf() with sysfs_emit() + - power: supply: axp20x_battery: properly report current when discharging + - ipv6: make mc_forwarding atomic + - powerpc: Set crashkernel offset to mid of RMA region + - drm/amdgpu: Fix recursive locking warning + - PCI: aardvark: Fix support for MSI interrupts + - iommu/arm-smmu-v3: fix event handling soft lockup + - usb: ehci: add pci device support for Aspeed platforms + - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum + - power: supply: axp288-charger: Set Vhold to 4.4V + - ipv4: Invalidate neighbour for broadcast address upon address addition + - dm ioctl: prevent potential spectre v1 gadget + - drm/amdkfd: make CRAT table missing message informational only + - scsi: pm8001: Fix pm8001_mpi_task_abort_resp() + - scsi: aha152x: Fix aha152x_setup() __setup handler return value + - net/smc: correct settings of RMB window update limit + - mips: ralink: fix a refcount leak in ill_acc_of_setup() + - macvtap: advertise link netns via netlink + - tuntap: add sanity checks about msg_controllen in sendmsg + - bnxt_en: Eliminate unintended link toggle during FW reset + - MIPS: fix fortify panic when copying asm exception handlers + - scsi: libfc: Fix use after free in fc_exch_abts_resp() + - usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm + - xtensa: fix DTC warning unit_address_format + - Bluetooth: Fix use after free in hci_send_acl + - netlabel: fix out-of-bounds memory accesses + - init/main.c: return 1 from handled __setup() functions + - minix: fix bug when opening a file with O_DIRECT + - clk: si5341: fix reported clk_rate when output divider is 2 + - w1: w1_therm: fixes w1_seq for ds28ea00 sensors + - NFSv4: Protect the state recovery thread against direct reclaim + - xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32 + - clk: Enforce that disjoints limits are invalid + - SUNRPC/call_alloc: async tasks mustn't block waiting for memory + - NFS: swap IO handling is slightly different for O_DIRECT IO + - NFS: swap-out must always use STABLE writes. + - serial: samsung_tty: do not unlock port->lock for uart_write_wakeup() + - virtio_console: eliminate anonymous module_init & module_exit + - jfs: prevent NULL deref in diFree + - SUNRPC: Fix socket waits for write buffer space + - parisc: Fix CPU affinity for Lasi, WAX and Dino chips + - parisc: Fix patch code locking and flushing + - mm: fix race between MADV_FREE reclaim and blkdev direct IO read + - KVM: arm64: Check arm64_get_bp_hardening_data() didn't return NULL + - drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire() + - Drivers: hv: vmbus: Fix potential crash on module unload + - scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one() + - net/tls: fix slab-out-of-bounds bug in decrypt_internal + - net: ipv4: fix route with nexthop object delete warning + - net: stmmac: Fix unset max_speed difference between DT and non-DT platforms + - drm/imx: Fix memory leak in imx_pd_connector_get_modes + - bnxt_en: reserve space inside receive page for skb_shared_info + - IB/rdmavt: add lock to call to rvt_error_qp to prevent a race condition + - dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe + - ipv6: Fix stats accounting in ip6_pkt_drop + - net: openvswitch: don't send internal clone attribute to the userspace. + - rxrpc: fix a race in rxrpc_exit_net() + - qede: confirm skb is allocated before using + - spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op() + - bpf: Support dual-stack sockets in bpf_tcp_check_syncookie + - drbd: Fix five use after free bugs in get_initial_state + - SUNRPC: Handle ENOMEM in call_transmit_status() + - SUNRPC: Handle low memory situations in call_status() + - perf tools: Fix perf's libperf_print callback + - perf session: Remap buf if there is no space for event + - Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning" + - mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is + complete + - lz4: fix LZ4_decompress_safe_partial read out of bound + - mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0) + - mm/mempolicy: fix mpol_new leak in shared_policy_replace + - x86/pm: Save the MSR validity status at context setup + - x86/speculation: Restore speculation related MSRs during S3 resume + - btrfs: fix qgroup reserve overflow the qgroup limit + - arm64: patch_text: Fixup last cpu should be master + - ata: sata_dwc_460ex: Fix crash due to OOB write + - perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator + - irqchip/gic-v3: Fix GICR_CTLR.RWP polling + - tools build: Filter out options and warnings not supported by clang + - tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts + - dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error" + - mmc: mmci_sdmmc: Replace sg_dma_xxx macros + - mmc: mmci: stm32: correctly check all elements of sg list + - mm: don't skip swap entry even if zap_details specified + - arm64: module: remove (NOLOAD) from linker script + - mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning + - drm/amdkfd: add missing void argument to function kgd2kfd_init + - drm/amdkfd: Fix -Wstrict-prototypes from + amdgpu_amdkfd_gfx_10_0_get_functions() + - cgroup: Use open-time credentials for process migraton perm checks + - cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv + - cgroup: Use open-time cgroup namespace for process migration perm checks + - selftests: cgroup: Make cg_create() use 0755 for permission instead of 0644 + - selftests: cgroup: Test open-time credential usage for migration checks + - selftests: cgroup: Test open-time cgroup namespace usage for migration + checks + - cpuidle: PSCI: Move the `has_lpi` check to the beginning of the function + - ACPI: processor idle: Check for architectural support for LPI + - Linux 5.4.189 + * Focal update: v5.4.188 upstream stable release (LP: #1971496) + - nfsd: cleanup nfsd_file_lru_dispose() + - nfsd: Containerise filecache laundrette + - net: ipv6: fix skb_over_panic in __ip6_append_data + - tpm: Fix error handling in async work + - staging: fbtft: fb_st7789v: reset display before initialization + - thermal: int340x: fix memory leak in int3400_notify() + - llc: fix netdevice reference leaks in llc_ui_bind() + - ALSA: pcm: Add stream lock during PCM reset ioctl operations + - ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB + - ALSA: cmipci: Restore aux vol on suspend/resume + - ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec + - drivers: net: xgene: Fix regression in CRC stripping + - ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call + - ALSA: oss: Fix PCM OSS buffer allocation overflow + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671 + - ALSA: hda/realtek: Add quirk for ASUS GA402 + - ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board + - ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3 + - ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU + - crypto: qat - disable registration of algorithms + - rcu: Don't deboost before reporting expedited quiescent state + - mac80211: fix potential double free on mesh join + - tpm: use try_get_ops() in tpm-space.c + - nds32: fix access_ok() checks in get/put_user + - llc: only change llc->dev when bind() succeeds + - Linux 5.4.188 + * Focal update: v5.4.187 upstream stable release (LP: #1971493) + - crypto: qcom-rng - ensure buffer for generate is completely filled + - ocfs2: fix crash when initialize filecheck kobj fails + - efi: fix return value of __setup handlers + - net: phy: marvell: Fix invalid comparison in the resume and suspend + functions + - net/packet: fix slab-out-of-bounds access in packet_recvmsg() + - atm: eni: Add check for dma_map_single + - hv_netvsc: Add check for kvmalloc_array + - drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings + - net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit() + - net: dsa: Add missing of_node_put() in dsa_port_parse_of + - arm64: fix clang warning about TRAMP_VALIAS + - usb: gadget: rndis: prevent integer overflow in rndis_set_response() + - usb: gadget: Fix use-after-free bug by not setting udc->dev.driver + - usb: usbtmc: Fix bug in pipe direction for control transfers + - Input: aiptek - properly check endpoint type + - perf symbols: Fix symbol size calculation condition + - Linux 5.4.187 + * Focal update: v5.4.186 upstream stable release (LP: #1969678) + - Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0" + - sctp: fix the processing for INIT chunk + - xfrm: Check if_id in xfrm_migrate + - xfrm: Fix xfrm migrate issues when address family changes + - arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity + - arm64: dts: rockchip: reorder rk3399 hdmi clocks + - arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg" + - ARM: dts: rockchip: reorder rk322x hmdi clocks + - ARM: dts: rockchip: fix a typo on rk3288 crypto-controller + - mac80211: refuse aggregations sessions before authorized + - MIPS: smp: fill in sibling and core maps earlier + - ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE + - can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when + fully ready + - atm: firestream: check the return value of ioremap() in fs_init() + - iwlwifi: don't advertise TWT support + - drm/vrr: Set VRR capable prop only if it is attached to connector + - nl80211: Update bss channel on channel switch for P2P_CLIENT + - tcp: make tcp_read_sock() more robust + - sfc: extend the locking on mcdi->seqno + - kselftest/vm: fix tests build with old libc + - fixup for "arm64 entry: Add macro for reading symbol address from the + trampoline" + - Linux 5.4.186 + * Focal update: v5.4.185 upstream stable release (LP: #1969672) + - clk: qcom: gdsc: Add support to update GDSC transition delay + - arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias + - virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero + - net: qlogic: check the return value of dma_alloc_coherent() in + qed_vf_hw_prepare() + - qed: return status of qed_iov_get_link + - drm/sun4i: mixer: Fix P010 and P210 format numbers + - ARM: dts: aspeed: Fix AST2600 quad spi group + - ethernet: Fix error handling in xemaclite_of_probe + - net: ethernet: ti: cpts: Handle error for clk_enable + - net: ethernet: lpc_eth: Handle error for clk_enable + - ax25: Fix NULL pointer dereference in ax25_kill_by_device + - net/mlx5: Fix size field in bufferx_reg struct + - net/mlx5: Fix a race on command flush flow + - NFC: port100: fix use-after-free in port100_send_complete + - selftests: pmtu.sh: Kill tcpdump processes launched by subshell. + - gpio: ts4900: Do not set DAT and OE together + - gianfar: ethtool: Fix refcount leak in gfar_get_ts_info + - net: phy: DP83822: clear MISR2 register to disable interrupts + - sctp: fix kernel-infoleak for SCTP sockets + - net: bcmgenet: Don't claim WOL when its not available + - net-sysfs: add check for netdevice being present to speed_show + - Revert "xen-netback: remove 'hotplug-status' once it has served its purpose" + - Revert "xen-netback: Check for hotplug-status existence before watching" + - ipv6: prevent a possible race condition with lifetimes + - tracing: Ensure trace buffer is at least 4096 bytes large + - selftest/vm: fix map_fixed_noreplace test failure + - selftests/memfd: clean up mapping in mfd_fail_write + - ARM: Spectre-BHB: provide empty stub for non-config + - fuse: fix pipe buffer lifetime for direct_io + - staging: gdm724x: fix use after free in gdm_lte_rx() + - net: macb: Fix lost RX packet wakeup race in NAPI receive + - mmc: meson: Fix usage of meson_mmc_post_req() + - riscv: Fix auipc+jalr relocation range checks + - arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0 + - virtio: unexport virtio_finalize_features + - virtio: acknowledge all features before access + - ARM: fix Thumb2 regression with Spectre BHB + - ext4: add check to prevent attempting to resize an fs with sparse_super2 + - x86/cpufeatures: Mark two free bits in word 3 + - x86/cpu: Add hardware-enforced cache coherency as a CPUID feature + - x86/mm/pat: Don't flush cache if hardware enforces cache coherency across + encryption domnains + - KVM: SVM: Don't flush cache if hardware enforces cache coherency across + encryption domains + - Linux 5.4.185 + * Focal update: v5.4.184 upstream stable release (LP: #1969242) + - arm/arm64: Provide a wrapper for SMCCC 1.1 calls + - arm/arm64: smccc/psci: add arm_smccc_1_1_get_conduit() + - ARM: report Spectre v2 status through sysfs + - ARM: early traps initialisation + - ARM: use LOADADDR() to get load address of sections + - [Config] updateconfigs for HARDEN_BRANCH_HISTORY + - ARM: Spectre-BHB workaround + - ARM: include unprivileged BPF status in Spectre V2 reporting + - ARM: fix build error when BPF_SYSCALL is disabled + - ARM: fix co-processor register typo + - ARM: Do not use NOCROSSREFS directive with ld.lld + - ARM: fix build warning in proc-v7-bugs.c + - xen/xenbus: don't let xenbus_grant_ring() remove grants in error case + - xen/grant-table: add gnttab_try_end_foreign_access() + - xen/blkfront: don't use gnttab_query_foreign_access() for mapped status + - xen/netfront: don't use gnttab_query_foreign_access() for mapped status + - xen/scsifront: don't use gnttab_query_foreign_access() for mapped status + - xen/gntalloc: don't use gnttab_query_foreign_access() + - xen: remove gnttab_query_foreign_access() + - xen/9p: use alloc/free_pages_exact() + - xen/pvcalls: use alloc/free_pages_exact() + - xen/gnttab: fix gnttab_end_foreign_access() without page specified + - xen/netfront: react properly to failing gnttab_end_foreign_access_ref() + - Linux 5.4.184 + * Focal update: v5.4.183 upstream stable release (LP: #1969239) + - mac80211_hwsim: report NOACK frames in tx_status + - mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work + - i2c: bcm2835: Avoid clock stretching timeouts + - ASoC: rt5668: do not block workqueue if card is unbound + - ASoC: rt5682: do not block workqueue if card is unbound + - Input: clear BTN_RIGHT/MIDDLE on buttonpads + - cifs: fix double free race when mount fails in cifs_get_root() + - dmaengine: shdma: Fix runtime PM imbalance on error + - i2c: cadence: allow COMPILE_TEST + - i2c: qup: allow COMPILE_TEST + - net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990 + - usb: gadget: don't release an existing dev->buf + - usb: gadget: clear related members when goto fail + - ata: pata_hpt37x: fix PCI clock detection + - ALSA: intel_hdmi: Fix reference to PCM buffer address + - ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min + - xfrm: fix MTU regression + - netfilter: fix use-after-free in __nf_register_net_hook() + - xfrm: enforce validity of offload input flags + - netfilter: nf_queue: don't assume sk is full socket + - netfilter: nf_queue: fix possible use-after-free + - batman-adv: Request iflink once in batadv-on-batadv check + - batman-adv: Request iflink once in batadv_get_real_netdevice + - batman-adv: Don't expect inter-netns unique iflink indices + - net: dcb: flush lingering app table entries for unregistered devices + - net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client + - net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server + - block: Fix fsync always failed if once failed + - xen/netfront: destroy queues before real_num_tx_queues is zeroed + - sched/topology: Make sched_init_numa() use a set for the deduplicating sort + - sched/topology: Fix sched_domain_topology_level alloc in sched_init_numa() + - ia64: ensure proper NUMA distance and possible map initialization + - mac80211: fix forwarded mesh frames AC & queue selection + - net: stmmac: fix return value of __setup handler + - iavf: Fix missing check for running netdev + - net: sxgbe: fix return value of __setup handler + - net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe() + - ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc() + - efivars: Respect "block" flag in efivar_entry_set_safe() + - firmware: arm_scmi: Remove space in MODULE_ALIAS name + - ASoC: cs4265: Fix the duplicated control name + - can: gs_usb: change active_channels's type from atomic_t to u8 + - arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output + - igc: igc_read_phy_reg_gpy: drop premature return + - ARM: Fix kgdb breakpoint for Thumb2 + - ARM: 9182/1: mmu: fix returns from early_param() and __setup() functions + - igc: igc_write_phy_reg_gpy: drop premature return + - ibmvnic: free reset-work-item when flushing + - memfd: fix F_SEAL_WRITE after shmem huge page allocated + - soc: fsl: qe: Check of ioremap return value + - net: chelsio: cxgb3: check the return value of pci_find_capability() + - nl80211: Handle nla_memdup failures in handle_nan_filter + - Input: elan_i2c - move regulator_[en|dis]able() out of + elan_[en|dis]able_power() + - Input: elan_i2c - fix regulator enable count imbalance after suspend/resume + - HID: add mapping for KEY_DICTATE + - HID: add mapping for KEY_ALL_APPLICATIONS + - tracing/histogram: Fix sorting on old "cpu" value + - tracing: Fix return value of __setup handlers + - btrfs: fix lost prealloc extents beyond eof after full fsync + - btrfs: qgroup: fix deadlock between rescan worker and remove qgroup + - btrfs: add missing run of delayed items after unlink during log replay + - Revert "xfrm: xfrm_state_mtu should return at least 1280 for ipv6" + - net: dcb: disable softirqs in dcbnl_flush_dev() + - hamradio: fix macro redefine warning + - Linux 5.4.183 + * Focal update: v5.4.182 upstream stable release (LP: #1969236) + - cgroup/cpuset: Fix a race between cpuset_attach() and cpu hotplug + - clk: jz4725b: fix mmc0 clock gating + - vhost/vsock: don't check owner in vhost_vsock_stop() while releasing + - parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel + - parisc/unaligned: Fix ldw() and stw() unalignment handlers + - drm/amdgpu: disable MMHUB PG for Picasso + - sr9700: sanity check for packet length + - USB: zaurus: support another broken Zaurus + - x86/fpu: Correct pkru/xstate inconsistency + - tee: export teedev_open() and teedev_close_context() + - optee: use driver internal tee_context for some rpc + - lan743x: fix deadlock in lan743x_phy_link_status_change() + - ping: remove pr_err from ping_lookup + - perf data: Fix double free in perf_session__delete() + - bpf: Do not try bpf_msg_push_data with len 0 + - net: __pskb_pull_tail() & pskb_carve_frag_list() drop_monitor friends + - tipc: Fix end of loop tests for list_for_each_entry() + - gso: do not skip outer ip header in case of ipip and net_failover + - openvswitch: Fix setting ipv6 fields causing hw csum failure + - drm/edid: Always set RGB444 + - net/mlx5e: Fix wrong return value on ioctl EEPROM query failure + - net: ll_temac: check the return value of devm_kmalloc() + - net: Force inlining of checksum functions in net/checksum.h + - nfp: flower: Fix a potential leak in nfp_tunnel_add_shared_mac() + - netfilter: nf_tables: fix memory leak during stateful obj update + - net/mlx5: Fix possible deadlock on rule deletion + - net/mlx5: Fix wrong limitation of metadata match on ecpf + - spi: spi-zynq-qspi: Fix a NULL pointer dereference in + zynq_qspi_exec_mem_op() + - configfs: fix a race in configfs_{,un}register_subsystem() + - RDMA/ib_srp: Fix a deadlock + - tracing: Have traceon and traceoff trigger honor the instance + - iio: adc: men_z188_adc: Fix a resource leak in an error handling path + - iio: adc: ad7124: fix mask used for setting AIN_BUFP & AIN_BUFM bits + - iio: Fix error handling for PM + - ata: pata_hpt37x: disable primary channel on HPT371 + - Revert "USB: serial: ch341: add new Product ID for CH341A" + - usb: gadget: rndis: add spinlock for rndis response list + - tracefs: Set the group ownership in apply_options() not parse_options() + - USB: serial: option: add support for DW5829e + - USB: serial: option: add Telit LE910R1 compositions + - usb: dwc3: pci: Fix Bay Trail phy GPIO mappings + - usb: dwc3: gadget: Let the interrupt handler disable bottom halves. + - xhci: re-initialize the HC during resume if HCE was set + - xhci: Prevent futile URB re-submissions due to incorrect return value. + - tty: n_gsm: fix encoding of control signal octet bit DV + - tty: n_gsm: fix proper link termination after failed open + - tty: n_gsm: fix NULL pointer access due to DLCI release + - gpio: tegra186: Fix chip_data type confusion + - Revert "drm/nouveau/pmu/gm200-: avoid touching PMU outside of + DEVINIT/PREOS/ACR" + - memblock: use kfree() to release kmalloced memblock regions + - fget: clarify and improve __fget_files() implementation + - Linux 5.4.182 + * CVE-2022-28390 + - can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path + + -- Joseph Salisbury Fri, 27 May 2022 13:23:49 -0400 + +linux-oracle (5.4.0-1073.79) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1073.79 -proposed tracker (LP: #1973970) + + [ Ubuntu: 5.4.0-113.127 ] + + * focal/linux: 5.4.0-113.127 -proposed tracker (LP: #1973980) + * CVE-2022-29581 + - net/sched: cls_u32: fix netns refcount changes in u32_change() + * CVE-2022-1116 + - io_uring: fix fs->users overflow + * ext4: limit length to bitmap_maxbytes (LP: #1972281) + - ext4: limit length to bitmap_maxbytes - blocksize in punch_hole + * Unprivileged users may use PTRACE_SEIZE to set PTRACE_O_SUSPEND_SECCOMP + option (LP: #1972740) + - ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE + + -- Joseph Salisbury Tue, 24 May 2022 15:07:36 -0400 + +linux-oracle (5.4.0-1071.77) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1071.77 -proposed tracker (LP: #1969043) + + [ Ubuntu: 5.4.0-110.124 ] + + * focal/linux: 5.4.0-110.124 -proposed tracker (LP: #1969053) + * net/mlx5e: Fix page DMA map/unmap attributes (LP: #1967292) + - net/mlx5e: Fix page DMA map/unmap attributes + * xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename() + (LP: #1966803) + - xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename() + * LRMv6: add multi-architecture support (LP: #1968774) + - [Packaging] resync dkms-build{,--nvidia-N} + * xfrm interface cannot be changed anymore (LP: #1968591) + - xfrm: fix the if_id check in changelink + * Use kernel-testing repo from launchpad for ADT tests (LP: #1968016) + - [Debian] Use kernel-testing repo from launchpad + * vmx_ldtr_test in ubuntu_kvm_unit_tests failed (FAIL: Expected 0 for L1 LDTR + selector (got 50)) (LP: #1956315) + - KVM: nVMX: Set LDTR to its architecturally defined value on nested VM-Exit + * [SRU][Regression] Revert "PM: ACPI: reboot: Use S5 for reboot" which causes + Bus Fatal Error when rebooting system with BCM5720 NIC (LP: #1917471) + - Revert "PM: ACPI: reboot: Use S5 for reboot" + * Focal update: v5.4.181 upstream stable release (LP: #1967582) + - Makefile.extrawarn: Move -Wunaligned-access to W=1 + - HID:Add support for UGTABLET WP5540 + - Revert "svm: Add warning message for AVIC IPI invalid target" + - serial: parisc: GSC: fix build when IOSAPIC is not set + - parisc: Drop __init from map_pages declaration + - parisc: Fix data TLB miss in sba_unmap_sg + - parisc: Fix sglist access in ccio-dma.c + - btrfs: send: in case of IO error log it + - platform/x86: ISST: Fix possible circular locking dependency detected + - selftests: rtc: Increase test timeout so that all tests run + - net: ieee802154: at86rf230: Stop leaking skb's + - selftests/zram: Skip max_comp_streams interface on newer kernel + - selftests/zram01.sh: Fix compression ratio calculation + - selftests/zram: Adapt the situation that /dev/zram0 is being used + - ax25: improve the incomplete fix to avoid UAF and NPD bugs + - vfs: make freeze_super abort when sync_filesystem returns error + - quota: make dquot_quota_sync return errors from ->sync_fs + - nvme: fix a possible use-after-free in controller reset during load + - nvme-tcp: fix possible use-after-free in transport error_recovery work + - nvme-rdma: fix possible use-after-free in transport error_recovery work + - drm/amdgpu: fix logic inversion in check + - Revert "module, async: async_synchronize_full() on module init iff async is + used" + - ftrace: add ftrace_init_nop() + - module/ftrace: handle patchable-function-entry + - arm64: module: rework special section handling + - arm64: module/ftrace: intialize PLT at load time + - iwlwifi: fix use-after-free + - drm/radeon: Fix backlight control on iMac 12,1 + - ext4: check for out-of-order index extents in ext4_valid_extent_entries() + - ext4: check for inconsistent extents between index and leaf block + - ext4: prevent partial update of the extent blocks + - taskstats: Cleanup the use of task->exit_code + - dmaengine: at_xdmac: Start transfer for cyclic channels in issue_pending + - vsock: remove vsock from connected table when connect is interrupted by a + signal + - mmc: block: fix read single on recovery logic + - iwlwifi: pcie: fix locking when "HW not ready" + - iwlwifi: pcie: gen2: fix locking when "HW not ready" + - netfilter: nft_synproxy: unregister hooks on init error path + - net: dsa: lan9303: fix reset on probe + - net: ieee802154: ca8210: Fix lifs/sifs periods + - ping: fix the dif and sdif check in ping_lookup + - bonding: force carrier update when releasing slave + - drop_monitor: fix data-race in dropmon_net_event / trace_napi_poll_hit + - bonding: fix data-races around agg_select_timer + - libsubcmd: Fix use-after-free for realloc(..., 0) + - ALSA: hda: Fix regression on forced probe mask option + - ALSA: hda: Fix missing codec probe on Shenker Dock 15 + - ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw() + - ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw_range() + - powerpc/lib/sstep: fix 'ptesync' build error + - mtd: rawnand: gpmi: don't leak PM reference in error path + - block/wbt: fix negative inflight counter when remove scsi device + - NFS: LOOKUP_DIRECTORY is also ok with symlinks + - NFS: Do not report writeback errors in nfs_getattr() + - mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe() + - mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status + - scsi: lpfc: Fix pt2pt NVMe PRLI reject LOGO loop + - EDAC: Fix calculation of returned address and next offset in + edac_align_ptr() + - net: sched: limit TC_ACT_REPEAT loops + - dmaengine: sh: rcar-dmac: Check for error num after setting mask + - copy_process(): Move fd_install() out of sighand->siglock critical section + - i2c: brcmstb: fix support for DSL and CM variants + - Drivers: hv: vmbus: Fix memory leak in vmbus_add_channel_kobj + - KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW + - ARM: OMAP2+: hwmod: Add of_node_put() before break + - ARM: OMAP2+: adjust the location of put_device() call in omapdss_init_of + - irqchip/sifive-plic: Add missing thead,c900-plic match string + - netfilter: conntrack: don't refresh sctp entries in closed state + - arm64: dts: meson-gx: add ATF BL32 reserved-memory region + - arm64: dts: meson-g12: add ATF BL32 reserved-memory region + - arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610 + - kconfig: let 'shell' return enough output for deep path names + - ata: libata-core: Disable TRIM on M88V29 + - drm/rockchip: dw_hdmi: Do not leave clock enabled in error case + - tracing: Fix tp_printk option related with tp_printk_stop_on_boot + - net: usb: qmi_wwan: Add support for Dell DW5829e + - net: macb: Align the dma and coherent dma masks + - kconfig: fix failing to generate auto.conf + - Linux 5.4.181 + * Focal update: v5.4.180 upstream stable release (LP: #1966118) + - integrity: check the return value of audit_log_start() + - ima: Remove ima_policy file before directory + - ima: Allow template selection with ima_template[_fmt]= after ima_hash= + - ima: Do not print policy rule with inactive LSM labels + - mmc: sdhci-of-esdhc: Check for error num after setting mask + - net: phy: marvell: Fix RGMII Tx/Rx delays setting in 88e1121-compatible PHYs + - net: phy: marvell: Fix MDI-x polarity setting in 88e1118-compatible PHYs + - NFS: Fix initialisation of nfs_client cl_flags field + - NFSD: Clamp WRITE offsets + - NFSD: Fix offset type in I/O trace points + - NFSv4 only print the label when its queried + - nfs: nfs4clinet: check the return value of kstrdup() + - NFSv4.1: Fix uninitialised variable in devicenotify + - NFSv4 remove zero number of fs_locations entries error check + - NFSv4 expose nfs_parse_server_name function + - drm: panel-orientation-quirks: Add quirk for the 1Netbook OneXPlayer + - net: sched: Clarify error message when qdisc kind is unknown + - scsi: target: iscsi: Make sure the np under each tpg is unique + - scsi: qedf: Fix refcount issue when LOGO is received during TMF + - scsi: myrs: Fix crash in error case + - PM: hibernate: Remove register_nosave_region_late() + - usb: dwc2: gadget: don't try to disable ep0 in dwc2_hsotg_suspend + - net: stmmac: dwmac-sun8i: use return val of readl_poll_timeout() + - KVM: nVMX: eVMCS: Filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER + - riscv: fix build with binutils 2.38 + - ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from hog group + - ARM: socfpga: fix missing RESET_CONTROLLER + - nvme-tcp: fix bogus request completion when failing to send AER + - ACPI/IORT: Check node revision for PMCG resources + - PM: s2idle: ACPI: Fix wakeup interrupts handling + - net: bridge: fix stale eth hdr pointer in br_dev_xmit + - perf probe: Fix ppc64 'perf probe add events failed' case + - ARM: dts: meson: Fix the UART compatible strings + - staging: fbtft: Fix error path in fbtft_driver_module_init() + - ARM: dts: imx6qdl-udoo: Properly describe the SD card detect + - usb: f_fs: Fix use-after-free for epfile + - misc: fastrpc: avoid double fput() on failed usercopy + - ixgbevf: Require large buffers for build_skb on 82599VF + - bonding: pair enable_port with slave_arr_updates + - ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on failure path + - nfp: flower: fix ida_idx not being released + - net: do not keep the dst cache when uncloning an skb dst and its metadata + - net: fix a memleak when uncloning an skb dst and its metadata + - veth: fix races around rq->rx_notify_masked + - net: mdio: aspeed: Add missing MODULE_DEVICE_TABLE + - tipc: rate limit warning for received illegal binding update + - net: amd-xgbe: disable interrupts during pci removal + - vt_ioctl: fix array_index_nospec in vt_setactivate + - vt_ioctl: add array_index_nospec to VT_ACTIVATE + - n_tty: wake up poll(POLLRDNORM) on receiving data + - eeprom: ee1004: limit i2c reads to I2C_SMBUS_BLOCK_MAX + - net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup + - usb: ulpi: Move of_node_put to ulpi_dev_release + - usb: ulpi: Call of_node_put correctly + - usb: dwc3: gadget: Prevent core from processing stale TRBs + - usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition + - USB: gadget: validate interface OS descriptor requests + - usb: gadget: rndis: check size of RNDIS_MSG_SET command + - usb: gadget: f_uac2: Define specific wTerminalType + - USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320 + - USB: serial: option: add ZTE MF286D modem + - USB: serial: ch341: add support for GW Instek USB2.0-Serial devices + - USB: serial: cp210x: add NCR Retail IO box id + - USB: serial: cp210x: add CPI Bulk Coin Recycler id + - seccomp: Invalidate seccomp mode to catch death failures + - hwmon: (dell-smm) Speed up setting of fan speed + - scsi: lpfc: Remove NVMe support if kernel has NVME_FC disabled + - perf: Fix list corruption in perf_cgroup_switch() + - Linux 5.4.180 + * Focal update: v5.4.179 upstream stable release (LP: #1965591) + - moxart: fix potential use-after-free on remove path + - Linux 5.4.179 + * CVE-2020-27820 + - drm/nouveau: Add a dedicated mutex for the clients list + - drm/nouveau: clean up all clients on device removal + * CVE-2022-1016 + - netfilter: nf_tables: initialize registers in nft_do_chain() + * CVE-2022-27223 + - USB: gadget: validate endpoint index for xilinx udc + * CVE-2022-26490 + - nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION + * CVE-2021-26401 + - x86/speculation: Use generic retpoline by default on AMD + - x86/speculation: Update link to AMD speculation whitepaper + - x86/speculation: Warn about Spectre v2 LFENCE mitigation + - x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT + * CVE-2022-0001 + - x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation + reporting + + [ Ubuntu: 5.4.0-109.123 ] + + * focal/linux: 5.4.0-109.123 -proposed tracker (LP: #1968290) + * USB devices not detected during boot on USB 3.0 hubs (LP: #1968210) + - SAUCE: Revert "Revert "xhci: Set HCD flag to defer primary roothub + registration"" + - SAUCE: Revert "Revert "usb: core: hcd: Add support for deferring roothub + registration"" + + -- Joseph Salisbury Tue, 19 Apr 2022 12:47:36 -0400 + +linux-oracle (5.4.0-1070.76) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1070.76 -proposed tracker (LP: #1967385) + + [ Ubuntu: 5.4.0-108.122 ] + + * focal/linux: 5.4.0-108.122 -proposed tracker (LP: #1966740) + * Packaging resync (LP: #1786013) + - [Packaging] resync dkms-build{,--nvidia-N} from LRMv5 + - debian/dkms-versions -- update from kernel-versions (main/2022.03.21) + * Low RX performance for 40G Solarflare NICs (LP: #1964512) + - SAUCE: sfc: The size of the RX recycle ring should be more flexible + * [UBUNTU 20.04] KVM: Enable storage key checking for intercepted instruction + (LP: #1962831) + - selftests: kvm: add _vm_ioctl + - selftests: kvm: Introduce the TEST_FAIL macro + - KVM: selftests: Add GUEST_ASSERT variants to pass values to host + - KVM: s390: gaccess: Refactor gpa and length calculation + - KVM: s390: gaccess: Refactor access address range check + - KVM: s390: gaccess: Cleanup access to guest pages + - s390/uaccess: introduce bit field for OAC specifier + - s390/uaccess: fix compile error + - s390/uaccess: Add copy_from/to_user_key functions + - KVM: s390: Honor storage keys when accessing guest memory + - KVM: s390: handle_tprot: Honor storage keys + - KVM: s390: selftests: Test TEST PROTECTION emulation + - KVM: s390: Add optional storage key checking to MEMOP IOCTL + - KVM: s390: Add vm IOCTL for key checked guest absolute memory access + - KVM: s390: Rename existing vcpu memop functions + - KVM: s390: Add capability for storage key extension of MEM_OP IOCTL + - KVM: s390: Update api documentation for memop ioctl + - KVM: s390: Clarify key argument for MEM_OP in api docs + - KVM: s390: Add missing vm MEM_OP size check + * 【sec-0911】 fail to reset sec module (LP: #1943301) + - crypto: hisilicon/sec2 - Add workqueue for SEC driver. + - crypto: hisilicon/sec2 - update SEC initialization and reset + * Lots of hisi_qm zombie task slow down system after stress test + (LP: #1932117) + - crypto: hisilicon - Use one workqueue per qm instead of per qp + * Lots of hisi_qm zombie task slow down system after stress test + (LP: #1932117) // 【sec-0911】 fail to reset sec module (LP: #1943301) + - crypto: hisilicon - Unify hardware error init/uninit into QM + * [UBUNTU 20.04] Fix SIGP processing on KVM/s390 (LP: #1962578) + - KVM: s390: Simplify SIGP Set Arch handling + - KVM: s390: Add a routine for setting userspace CPU state + * Move virtual graphics drivers from linux-modules-extra to linux-modules + (LP: #1960633) + - [Packaging] Move VM DRM drivers into modules + * Focal update: v5.4.178 upstream stable release (LP: #1964634) + - audit: improve audit queue handling when "audit=1" on cmdline + - ASoC: ops: Reject out of bounds values in snd_soc_put_volsw() + - ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx() + - ASoC: ops: Reject out of bounds values in snd_soc_put_xr_sx() + - ALSA: usb-audio: Simplify quirk entries with a macro + - ALSA: hda/realtek: Add quirk for ASUS GU603 + - ALSA: hda/realtek: Add missing fixup-model entry for Gigabyte X570 ALC1220 + quirks + - ALSA: hda/realtek: Fix silent output on Gigabyte X570S Aorus Master (newer + chipset) + - ALSA: hda/realtek: Fix silent output on Gigabyte X570 Aorus Xtreme after + reboot from Windows + - btrfs: fix deadlock between quota disable and qgroup rescan worker + - drm/nouveau: fix off by one in BIOS boundary checking + - mm/kmemleak: avoid scanning potential huge holes + - block: bio-integrity: Advance seed correctly for larger interval sizes + - memcg: charge fs_context and legacy_fs_context + - IB/rdmavt: Validate remote_addr during loopback atomic tests + - RDMA/siw: Fix broken RDMA Read Fence/Resume logic. + - RDMA/mlx4: Don't continue event handler after memory allocation failure + - iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping() + - iommu/amd: Fix loop timeout issue in iommu_ga_log_enable() + - spi: bcm-qspi: check for valid cs before applying chip select + - spi: mediatek: Avoid NULL pointer crash in interrupt + - spi: meson-spicc: add IRQ check in meson_spicc_probe + - net: ieee802154: hwsim: Ensure proper channel selection at probe time + - net: ieee802154: mcr20a: Fix lifs/sifs periods + - net: ieee802154: ca8210: Stop leaking skb's + - net: ieee802154: Return meaningful error codes from the netlink helpers + - net: macsec: Verify that send_sci is on when setting Tx sci explicitly + - net: stmmac: dump gmac4 DMA registers correctly + - net: stmmac: ensure PTP time register reads are consistent + - drm/i915/overlay: Prevent divide by zero bugs in scaling + - ASoC: fsl: Add missing error handling in pcm030_fabric_probe + - ASoC: xilinx: xlnx_formatter_pcm: Make buffer bytes multiple of period bytes + - ASoC: cpcap: Check for NULL pointer after calling of_get_child_by_name + - ASoC: max9759: fix underflow in speaker_gain_control_put() + - pinctrl: bcm2835: Fix a few error paths + - scsi: bnx2fc: Make bnx2fc_recv_frame() mp safe + - nfsd: nfsd4_setclientid_confirm mistakenly expires confirmed client. + - selftests: futex: Use variable MAKE instead of make + - rtc: cmos: Evaluate century appropriate + - EDAC/altera: Fix deferred probing + - EDAC/xgene: Fix deferred probing + - ext4: fix error handling in ext4_restore_inline_data() + - cgroup/cpuset: Fix "suspicious RCU usage" lockdep warning + - Linux 5.4.178 + * Focal update: v5.4.177 upstream stable release (LP: #1964628) + - PCI: pciehp: Fix infinite loop in IRQ handler upon power fault + - psi: Fix uaf issue when psi trigger is destroyed while being polled + - ipheth: fix EOVERFLOW in ipheth_rcvbulk_callback + - net: amd-xgbe: ensure to reset the tx_timer_active flag + - net: amd-xgbe: Fix skb data length underflow + - rtnetlink: make sure to refresh master_dev/m_ops in __rtnl_newlink() + - cpuset: Fix the bug that subpart_cpus updated wrongly in update_cpumask() + - af_packet: fix data-race in packet_setsockopt / packet_setsockopt + - Linux 5.4.177 + * Focal update: v5.4.176 upstream stable release (LP: #1962345) + - s390/hypfs: include z/VM guests with access control group set + - scsi: zfcp: Fix failed recovery on gone remote port with non-NPIV FCP + devices + - udf: Restore i_lenAlloc when inode expansion fails + - udf: Fix NULL ptr deref when converting from inline format + - PM: wakeup: simplify the output logic of pm_show_wakelocks() + - tracing/histogram: Fix a potential memory leak for kstrdup() + - tracing: Don't inc err_log entry count if entry allocation fails + - fsnotify: fix fsnotify hooks in pseudo filesystems + - drm/etnaviv: relax submit size limits + - arm64: errata: Fix exec handling in erratum 1418040 workaround + - netfilter: nft_payload: do not update layer 4 checksum when mangling + fragments + - serial: 8250: of: Fix mapped region size when using reg-offset property + - serial: stm32: fix software flow control transfer + - tty: n_gsm: fix SW flow control encoding/handling + - tty: Add support for Brainboxes UC cards. + - usb-storage: Add unusual-devs entry for VL817 USB-SATA bridge + - usb: common: ulpi: Fix crash in ulpi_match() + - usb: gadget: f_sourcesink: Fix isoc transfer for USB_SPEED_SUPER_PLUS + - USB: core: Fix hang in usb_kill_urb by adding memory barriers + - usb: typec: tcpm: Do not disconnect while receiving VBUS off + - ucsi_ccg: Check DEV_INT bit only when starting CCG4 + - net: sfp: ignore disabled SFP node + - powerpc/32: Fix boot failure with GCC latent entropy plugin + - i40e: Increase delay to 1 s after global EMP reset + - i40e: Fix issue when maximum queues is exceeded + - i40e: Fix queues reservation for XDP + - i40e: fix unsigned stat widths + - rpmsg: char: Fix race between the release of rpmsg_ctrldev and cdev + - rpmsg: char: Fix race between the release of rpmsg_eptdev and cdev + - scsi: bnx2fc: Flush destroy_work queue before calling bnx2fc_interface_put() + - ipv6_tunnel: Rate limit warning messages + - net: fix information leakage in /proc/net/ptype + - hwmon: (lm90) Mark alert as broken for MAX6646/6647/6649 + - hwmon: (lm90) Mark alert as broken for MAX6680 + - ping: fix the sk_bound_dev_if match in ping_lookup + - ipv4: avoid using shared IP generator for connected sockets + - hwmon: (lm90) Reduce maximum conversion rate for G781 + - NFSv4: Handle case where the lookup of a directory fails + - NFSv4: nfs_atomic_open() can race when looking up a non-regular file + - net-procfs: show net devices bound packet types + - drm/msm: Fix wrong size calculation + - drm/msm/dsi: Fix missing put_device() call in dsi_get_phy + - drm/msm/dsi: invalid parameter check in msm_dsi_phy_enable + - ipv6: annotate accesses to fn->fn_sernum + - NFS: Ensure the server has an up to date ctime before hardlinking + - NFS: Ensure the server has an up to date ctime before renaming + - netfilter: conntrack: don't increment invalid counter on NF_REPEAT + - net: phy: broadcom: hook up soft_reset for BCM54616S + - phylib: fix potential use-after-free + - rxrpc: Adjust retransmission backoff + - hwmon: (lm90) Mark alert as broken for MAX6654 + - ibmvnic: init ->running_cap_crqs early + - ibmvnic: don't spin in tasklet + - drm/msm/hdmi: Fix missing put_device() call in msm_hdmi_get_phy + - yam: fix a memory leak in yam_siocdevprivate() + - net: hns3: handle empty unknown interrupt for VF + - ipv4: raw: lock the socket in raw_bind() + - ipv4: tcp: send zero IPID in SYNACK messages + - ipv4: remove sparse error in ip_neigh_gw4() + - dt-bindings: can: tcan4x5x: fix mram-cfg RX FIFO config + - fsnotify: invalidate dcache before IN_DELETE event + - block: Fix wrong offset in bio_truncate() + - mtd: rawnand: mpc5121: Remove unused variable in ads5121_select_chip() + - Linux 5.4.176 + * Focal update: v5.4.175 upstream stable release (LP: #1962330) + - rcu: Tighten rcu_advance_cbs_nowake() checks + - pinctrl: bcm2835: Drop unused define + - pinctrl: bcm2835: Refactor platform data + - pinctrl: bcm2835: Add support for all GPIOs on BCM2711 + - pinctrl: bcm2835: Match BCM7211 compatible string + - pinctrl: bcm2835: Add support for wake-up interrupts + - pinctrl: bcm2835: Change init order for gpio hogs + - ARM: dts: gpio-ranges property is now required + - mmc: sdhci-esdhc-imx: disable CMDQ support + - select: Fix indefinitely sleeping task in poll_schedule_timeout() + - Linux 5.4.175 + + -- Ian May Tue, 05 Apr 2022 08:55:53 -0500 + +linux-oracle (5.4.0-1069.75) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1069.75 -proposed tracker (LP: #1966265) + + [ Ubuntu: 5.4.0-107.121 ] + + * focal/linux: 5.4.0-107.121 -proposed tracker (LP: #1966275) + * CVE-2022-27666 + - esp: Fix possible buffer overflow in ESP transformation + * CVE-2022-1055 + - net: sched: fix use-after-free in tc_new_tfilter() + * Pick fixup from v5.4.176 upstream stable release to address cert + failure with clock jitter test in NUC7i3DNHE (LP: #1964204) + - Bluetooth: refactor malicious adv data check + + -- Tim Gardner Fri, 25 Mar 2022 06:34:29 -0600 + +linux-oracle (5.4.0-1067.72) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1067.72 -proposed tracker (LP: #1964198) + + * Miscellaneous Ubuntu changes + - [Config]: oracle: Update gcc version used for build to 90400 + + [ Ubuntu: 5.4.0-105.119 ] + + * CVE-2022-0847 + - lib/iov_iter: initialize "flags" in new pipe_buffer + * Broken network on some AWS instances with focal/impish kernels + (LP: #1961968) + - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success" + * [UBUNTU 20.04] kernel: Add support for CPU-MF counter second version 7 + (LP: #1960182) + - s390/cpumf: Support for CPU Measurement Facility CSVN 7 + - s390/cpumf: Support for CPU Measurement Sampling Facility LS bit + * Hipersocket page allocation failure on Ubuntu 20.04 based SSC environments + (LP: #1959529) + - s390/qeth: use memory reserves to back RX buffers + * CVE-2022-0516 + - KVM: s390: Return error on SIDA memop on normal guest + * CVE-2022-0435 + - tipc: improve size validations for received domain records + * CVE-2022-0492 + - cgroup-v1: Require capabilities to set release_agent + * Recalled NFSv4 files delegations overwhelm server (LP: #1957986) + - NFSv4: Fix delegation handling in update_open_stateid() + - NFSv4: nfs4_callback_getattr() should ignore revoked delegations + - NFSv4: Delegation recalls should not find revoked delegations + - NFSv4: fail nfs4_refresh_delegation_stateid() when the delegation was + revoked + - NFS: Rename nfs_inode_return_delegation_noreclaim() + - NFSv4: Don't remove the delegation from the super_list more than once + - NFSv4: Hold the delegation spinlock when updating the seqid + - NFSv4: Clear the NFS_DELEGATION_REVOKED flag in + nfs_update_inplace_delegation() + - NFSv4: Update the stateid seqid in nfs_revoke_delegation() + - NFSv4: Revoke the delegation on success in nfs4_delegreturn_done() + - NFSv4: Ignore requests to return the delegation if it was revoked + - NFSv4: Don't reclaim delegations that have been returned or revoked + - NFSv4: nfs4_return_incompatible_delegation() should check delegation + validity + - NFSv4: Fix nfs4_inode_make_writeable() + - NFS: nfs_inode_find_state_and_recover() fix stateid matching + - NFSv4: Fix races between open and delegreturn + - NFSv4: Handle NFS4ERR_OLD_STATEID in delegreturn + - NFSv4: Don't retry the GETATTR on old stateid in nfs4_delegreturn_done() + - NFSv4: nfs_inode_evict_delegation() should set NFS_DELEGATION_RETURNING + - NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returned + - NFSv4: Try to return the delegation immediately when marked for return on + close + - NFSv4: Add accounting for the number of active delegations held + - NFSv4: Limit the total number of cached delegations + - NFSv4: Ensure the delegation is pinned in nfs_do_return_delegation() + - NFSv4: Ensure the delegation cred is pinned when we call delegreturn + * Focal update: v5.4.174 upstream stable release (LP: #1960566) + - HID: uhid: Fix worker destroying device without any protection + - HID: wacom: Reset expected and received contact counts at the same time + - HID: wacom: Ignore the confidence flag when a touch is removed + - HID: wacom: Avoid using stale array indicies to read contact count + - f2fs: fix to do sanity check in is_alive() + - nfc: llcp: fix NULL error pointer dereference on sendmsg() after failed + bind() + - mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings + - mtd: rawnand: gpmi: Remove explicit default gpmi clock setting for i.MX6 + - x86/gpu: Reserve stolen memory for first integrated Intel GPU + - tools/nolibc: x86-64: Fix startup code bug + - tools/nolibc: i386: fix initial stack alignment + - tools/nolibc: fix incorrect truncation of exit code + - rtc: cmos: take rtc_lock while reading from CMOS + - media: v4l2-ioctl.c: readbuffers depends on V4L2_CAP_READWRITE + - media: flexcop-usb: fix control-message timeouts + - media: mceusb: fix control-message timeouts + - media: em28xx: fix control-message timeouts + - media: cpia2: fix control-message timeouts + - media: s2255: fix control-message timeouts + - media: dib0700: fix undefined behavior in tuner shutdown + - media: redrat3: fix control-message timeouts + - media: pvrusb2: fix control-message timeouts + - media: stk1160: fix control-message timeouts + - can: softing_cs: softingcs_probe(): fix memleak on registration failure + - lkdtm: Fix content of section containing lkdtm_rodata_do_nothing() + - iommu/io-pgtable-arm-v7s: Add error handle for page table allocation failure + - dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled() + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9125 SATA controller + - mm_zone: add function to check if managed dma zone exists + - mm/page_alloc.c: do not warn allocation failure on zone DMA if no managed + pages + - shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode + - drm/rockchip: dsi: Hold pm-runtime across bind/unbind + - drm/rockchip: dsi: Reconfigure hardware on resume() + - drm/panel: kingdisplay-kd097d04: Delete panel on attach() failure + - drm/panel: innolux-p079zca: Delete panel on attach() failure + - drm/rockchip: dsi: Fix unbalanced clock on probe error + - Bluetooth: cmtp: fix possible panic when cmtp_init_sockets() fails + - clk: bcm-2835: Pick the closest clock rate + - clk: bcm-2835: Remove rounding up the dividers + - wcn36xx: Indicate beacon not connection loss on MISSED_BEACON_IND + - wcn36xx: Release DMA channel descriptor allocations + - media: videobuf2: Fix the size printk format + - media: aspeed: fix mode-detect always time out at 2nd run + - media: em28xx: fix memory leak in em28xx_init_dev + - media: aspeed: Update signal status immediately to ensure sane hw state + - arm64: dts: meson-gxbb-wetek: fix HDMI in early boot + - arm64: dts: meson-gxbb-wetek: fix missing GPIO binding + - Bluetooth: stop proccessing malicious adv data + - tee: fix put order in teedev_close_context() + - media: dmxdev: fix UAF when dvb_register_device() fails + - crypto: qce - fix uaf on qce_ahash_register_one + - arm64: dts: ti: k3-j721e: correct cache-sets info + - tty: serial: atmel: Check return code of dmaengine_submit() + - tty: serial: atmel: Call dma_async_issue_pending() + - media: rcar-csi2: Correct the selection of hsfreqrange + - media: imx-pxp: Initialize the spinlock prior to using it + - media: si470x-i2c: fix possible memory leak in si470x_i2c_probe() + - media: mtk-vcodec: call v4l2_m2m_ctx_release first when file is released + - media: venus: core: Fix a resource leak in the error handling path of + 'venus_probe()' + - netfilter: bridge: add support for pppoe filtering + - arm64: dts: qcom: msm8916: fix MMC controller aliases + - ACPI: EC: Rework flushing of EC work while suspended to idle + - drm/amdgpu: Fix a NULL pointer dereference in + amdgpu_connector_lcd_native_mode() + - drm/radeon/radeon_kms: Fix a NULL pointer dereference in + radeon_driver_open_kms() + - arm64: dts: ti: k3-j721e: Fix the L2 cache sets + - tty: serial: uartlite: allow 64 bit address + - serial: amba-pl011: do not request memory region twice + - floppy: Fix hang in watchdog when disk is ejected + - staging: rtl8192e: return error code from rtllib_softmac_init() + - staging: rtl8192e: rtllib_module: fix error handle case in alloc_rtllib() + - Bluetooth: btmtksdio: fix resume failure + - media: dib8000: Fix a memleak in dib8000_init() + - media: saa7146: mxb: Fix a NULL pointer dereference in mxb_attach() + - media: si2157: Fix "warm" tuner state detection + - sched/rt: Try to restart rt period timer when rt runtime exceeded + - rcu/exp: Mark current CPU as exp-QS in IPI loop second pass + - mwifiex: Fix possible ABBA deadlock + - xfrm: fix a small bug in xfrm_sa_len() + - crypto: stm32/cryp - fix xts and race condition in crypto_engine requests + - crypto: stm32/cryp - fix double pm exit + - crypto: stm32/cryp - fix lrw chaining mode + - ARM: dts: gemini: NAS4220-B: fis-index-block with 128 KiB sectors + - media: dw2102: Fix use after free + - media: msi001: fix possible null-ptr-deref in msi001_probe() + - media: coda/imx-vdoa: Handle dma_set_coherent_mask error codes + - drm/msm/dpu: fix safe status debugfs file + - drm/bridge: ti-sn65dsi86: Set max register for regmap + - media: hantro: Fix probe func error path + - xfrm: interface with if_id 0 should return error + - xfrm: state and policy should fail if XFRMA_IF_ID 0 + - ARM: 9159/1: decompressor: Avoid UNPREDICTABLE NOP encoding + - usb: ftdi-elan: fix memory leak on device disconnect + - ARM: dts: armada-38x: Add generic compatible to UART nodes + - mmc: meson-mx-sdio: add IRQ check + - selinux: fix potential memleak in selinux_add_opt() + - bpftool: Enable line buffering for stdout + - x86/mce/inject: Avoid out-of-bounds write when setting flags + - ACPI: scan: Create platform device for BCM4752 and LNV4752 ACPI nodes + - pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in + __nonstatic_find_io_region() + - pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in + nonstatic_find_mem_region() + - netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check() + - bpf: Fix SO_RCVBUF/SO_SNDBUF handling in _bpf_setsockopt(). + - ppp: ensure minimum packet size in ppp_write() + - rocker: fix a sleeping in atomic bug + - staging: greybus: audio: Check null pointer + - fsl/fman: Check for null pointer after calling devm_ioremap + - Bluetooth: hci_bcm: Check for error irq + - HID: hid-uclogic-params: Invalid parameter check in uclogic_params_init + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_get_str_desc + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_huion_init + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_frame_init_v1_buttonpad + - debugfs: lockdown: Allow reading debugfs files that are not world readable + - net/mlx5e: Don't block routes with nexthop objects in SW + - Revert "net/mlx5e: Block offload of outer header csum for UDP tunnels" + - net/mlx5: Set command entry semaphore up once got index free + - spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe + - tpm: add request_locality before write TPM_INT_ENABLE + - can: softing: softing_startstop(): fix set but not used variable warning + - can: xilinx_can: xcan_probe(): check for error irq + - pcmcia: fix setting of kthread task states + - net: mcs7830: handle usb read errors properly + - ext4: avoid trim error on fs with small groups + - ALSA: jack: Add missing rwsem around snd_ctl_remove() calls + - ALSA: PCM: Add missing rwsem around snd_ctl_remove() calls + - ALSA: hda: Add missing rwsem around snd_ctl_remove() calls + - RDMA/hns: Validate the pkey index + - clk: imx8mn: Fix imx8mn_clko1_sels + - powerpc/prom_init: Fix improper check of prom_getprop() + - ASoC: uniphier: drop selecting non-existing SND_SOC_UNIPHIER_AIO_DMA + - ALSA: oss: fix compile error when OSS_DEBUG is enabled + - char/mwave: Adjust io port register size + - binder: fix handling of error during copy + - iommu/io-pgtable-arm: Fix table descriptor paddr formatting + - scsi: ufs: Fix race conditions related to driver data + - PCI/MSI: Fix pci_irq_vector()/pci_irq_get_affinity() + - powerpc/powermac: Add additional missing lockdep_register_key() + - RDMA/core: Let ib_find_gid() continue search even after empty entry + - RDMA/cma: Let cma_resolve_ib_dev() continue search even after empty entry + - ASoC: rt5663: Handle device_property_read_u32_array error codes + - clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after system + enter shell + - dmaengine: pxa/mmp: stop referencing config->slave_id + - iommu/iova: Fix race between FQ timeout and teardown + - phy: uniphier-usb3ss: fix unintended writing zeros to PHY register + - ASoC: samsung: idma: Check of ioremap return value + - misc: lattice-ecp3-config: Fix task hung when firmware load failed + - mips: lantiq: add support for clk_set_parent() + - mips: bcm63xx: add support for clk_set_parent() + - RDMA/cxgb4: Set queue pair state when being queried + - of: base: Fix phandle argument length mismatch error message + - Bluetooth: Fix debugfs entry leak in hci_register_dev() + - fs: dlm: filter user dlm messages for kernel locks + - drm/lima: fix warning when CONFIG_DEBUG_SG=y & CONFIG_DMA_API_DEBUG=y + - ar5523: Fix null-ptr-deref with unexpected WDCMSG_TARGET_START reply + - drm/nouveau/pmu/gm200-: avoid touching PMU outside of DEVINIT/PREOS/ACR + - ARM: shmobile: rcar-gen2: Add missing of_node_put() + - batman-adv: allow netlink usage in unprivileged containers + - usb: gadget: f_fs: Use stream_open() for endpoint files + - drm: panel-orientation-quirks: Add quirk for the Lenovo Yoga Book X91F/L + - HID: apple: Do not reset quirks when the Fn key is not found + - media: b2c2: Add missing check in flexcop_pci_isr: + - EDAC/synopsys: Use the quirk for version instead of ddr version + - mlxsw: pci: Add shutdown method in PCI driver + - drm/bridge: megachips: Ensure both bridges are probed before registration + - gpiolib: acpi: Do not set the IRQ type if the IRQ is already in use + - HSI: core: Fix return freed object in hsi_new_client + - mwifiex: Fix skb_over_panic in mwifiex_usb_recv() + - rsi: Fix use-after-free in rsi_rx_done_handler() + - rsi: Fix out-of-bounds read in rsi_read_pkt() + - usb: uhci: add aspeed ast2600 uhci support + - floppy: Add max size check for user space request + - x86/mm: Flush global TLB when switching to trampoline page-table + - media: uvcvideo: Increase UVC_CTRL_CONTROL_TIMEOUT to 5 seconds. + - media: saa7146: hexium_orion: Fix a NULL pointer dereference in + hexium_attach() + - media: m920x: don't use stack on USB reads + - iwlwifi: mvm: synchronize with FW after multicast commands + - ath10k: Fix tx hanging + - net-sysfs: update the queue counts in the unregistration path + - net: phy: prefer 1000baseT over 1000baseKX + - gpio: aspeed: Convert aspeed_gpio.lock to raw_spinlock + - x86/mce: Mark mce_panic() noinstr + - x86/mce: Mark mce_end() noinstr + - x86/mce: Mark mce_read_aux() noinstr + - net: bonding: debug: avoid printing debug logs when bond is not notifying + peers + - bpf: Do not WARN in bpf_warn_invalid_xdp_action() + - HID: quirks: Allow inverting the absolute X/Y values + - media: igorplugusb: receiver overflow should be reported + - media: saa7146: hexium_gemini: Fix a NULL pointer dereference in + hexium_attach() + - mmc: core: Fixup storing of OCR for MMC_QUIRK_NONSTD_SDIO + - audit: ensure userspace is penalized the same as the kernel when under + pressure + - arm64: dts: ls1028a-qds: move rtc node to the correct i2c bus + - arm64: tegra: Adjust length of CCPLEX cluster MMIO region + - cpufreq: Fix initialization of min and max frequency QoS requests + - usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0 + - ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream + - iwlwifi: fix leaks/bad data after failed firmware load + - iwlwifi: remove module loading failure message + - iwlwifi: mvm: Fix calculation of frame length + - um: registers: Rename function names to avoid conflicts and build problems + - jffs2: GC deadlock reading a page that is used in jffs2_write_begin() + - ACPICA: actypes.h: Expand the ACPI_ACCESS_ definitions + - ACPICA: Utilities: Avoid deleting the same object twice in a row + - ACPICA: Executer: Fix the REFCLASS_REFOF case in acpi_ex_opcode_1A_0T_1R() + - ACPICA: Fix wrong interpretation of PCC address + - ACPICA: Hardware: Do not flush CPU cache when entering S4 and S5 + - drm/amdgpu: fixup bad vram size on gmc v8 + - ACPI: battery: Add the ThinkPad "Not Charging" quirk + - btrfs: remove BUG_ON() in find_parent_nodes() + - btrfs: remove BUG_ON(!eie) in find_parent_nodes + - net: mdio: Demote probed message to debug print + - mac80211: allow non-standard VHT MCS-10/11 + - dm btree: add a defensive bounds check to insert_at() + - dm space map common: add bounds check to sm_ll_lookup_bitmap() + - net: phy: marvell: configure RGMII delays for 88E1118 + - net: gemini: allow any RGMII interface mode + - regulator: qcom_smd: Align probe function with rpmh-regulator + - serial: pl010: Drop CR register reset on set_termios + - serial: core: Keep mctrl register state and cached copy in sync + - random: do not throw away excess input to crng_fast_load + - parisc: Avoid calling faulthandler_disabled() twice + - powerpc/6xx: add missing of_node_put + - powerpc/powernv: add missing of_node_put + - powerpc/cell: add missing of_node_put + - powerpc/btext: add missing of_node_put + - powerpc/watchdog: Fix missed watchdog reset due to memory ordering race + - i2c: i801: Don't silently correct invalid transfer size + - powerpc/smp: Move setup_profiling_timer() under CONFIG_PROFILING + - i2c: mpc: Correct I2C reset procedure + - clk: meson: gxbb: Fix the SDM_EN bit for MPLL0 on GXBB + - powerpc/powermac: Add missing lockdep_register_key() + - KVM: PPC: Book3S: Suppress failed alloc warning in H_COPY_TOFROM_GUEST + - w1: Misuse of get_user()/put_user() reported by sparse + - scsi: lpfc: Trigger SLI4 firmware dump before doing driver cleanup + - ALSA: seq: Set upper limit of processed events + - powerpc: handle kdump appropriately with crash_kexec_post_notifiers option + - MIPS: OCTEON: add put_device() after of_find_device_by_node() + - i2c: designware-pci: Fix to change data types of hcnt and lcnt parameters + - MIPS: Octeon: Fix build errors using clang + - scsi: sr: Don't use GFP_DMA + - ASoC: mediatek: mt8173: fix device_node leak + - power: bq25890: Enable continuous conversion for ADC at charging + - rpmsg: core: Clean up resources on announce_create failure. + - crypto: omap-aes - Fix broken pm_runtime_and_get() usage + - crypto: stm32/crc32 - Fix kernel BUG triggered in probe() + - crypto: caam - replace this_cpu_ptr with raw_cpu_ptr + - ubifs: Error path in ubifs_remount_rw() seems to wrongly free write buffers + - fuse: Pass correct lend value to filemap_write_and_wait_range() + - serial: Fix incorrect rs485 polarity on uart open + - cputime, cpuacct: Include guest time in user time in cpuacct.stat + - tracing/kprobes: 'nmissed' not showed correctly for kretprobe + - iwlwifi: mvm: Increase the scan timeout guard to 30 seconds + - s390/mm: fix 2KB pgtable release race + - drm/etnaviv: limit submit sizes + - drm/nouveau/kms/nv04: use vzalloc for nv04_display + - drm/bridge: analogix_dp: Make PSR-exit block less + - PCI: pci-bridge-emul: Properly mark reserved PCIe bits in PCI config space + - PCI: pci-bridge-emul: Correctly set PCIe capabilities + - PCI: pci-bridge-emul: Set PCI_STATUS_CAP_LIST for PCIe device + - xfrm: fix policy lookup for ipv6 gre packets + - btrfs: fix deadlock between quota enable and other quota operations + - btrfs: check the root node for uptodate before returning it + - btrfs: respect the max size in the header when activating swap file + - ext4: make sure to reset inode lockdep class when quota enabling fails + - ext4: make sure quota gets properly shutdown on error + - ext4: set csum seed in tmp inode while migrating to extents + - ext4: Fix BUG_ON in ext4_bread when write quota data + - ext4: don't use the orphan list when migrating an inode + - drm/radeon: fix error handling in radeon_driver_open_kms + - of: base: Improve argument length mismatch error + - firmware: Update Kconfig help text for Google firmware + - media: rcar-csi2: Optimize the selection PHTW register + - Documentation: dmaengine: Correctly describe dmatest with channel unset + - Documentation: ACPI: Fix data node reference documentation + - Documentation: refer to config RANDOMIZE_BASE for kernel address-space + randomization + - Documentation: fix firewire.rst ABI file path error + - scsi: core: Show SCMD_LAST in text form + - RDMA/hns: Modify the mapping attribute of doorbell to device + - RDMA/rxe: Fix a typo in opcode name + - dmaengine: stm32-mdma: fix STM32_MDMA_CTBR_TSEL_MASK + - Revert "net/mlx5: Add retry mechanism to the command entry index allocation" + - powerpc/cell: Fix clang -Wimplicit-fallthrough warning + - powerpc/fsl/dts: Enable WA for erratum A-009885 on fman3l MDIO buses + - bpftool: Remove inclusion of utilities.mak from Makefiles + - ipv4: avoid quadratic behavior in netns dismantle + - net/fsl: xgmac_mdio: Fix incorrect iounmap when removing module + - parisc: pdc_stable: Fix memory leak in pdcs_register_pathentries + - f2fs: fix to reserve space for IO align feature + - af_unix: annote lockless accesses to unix_tot_inflight & gc_in_progress + - clk: si5341: Fix clock HW provider cleanup + - net: axienet: limit minimum TX ring size + - net: axienet: fix number of TX ring slots for available check + - net: axienet: increase default TX ring size to 128 + - rtc: pxa: fix null pointer dereference + - inet: frags: annotate races around fqdir->dead and fqdir->high_thresh + - netns: add schedule point in ops_exit_list() + - xfrm: Don't accidentally set RTO_ONLINK in decode_session4() + - gre: Don't accidentally set RTO_ONLINK in gre_fill_metadata_dst() + - libcxgb: Don't accidentally set RTO_ONLINK in cxgb_find_route() + - perf script: Fix hex dump character output + - dmaengine: at_xdmac: Don't start transactions at tx_submit level + - dmaengine: at_xdmac: Print debug message after realeasing the lock + - dmaengine: at_xdmac: Fix concurrency over xfers_list + - dmaengine: at_xdmac: Fix lld view setting + - dmaengine: at_xdmac: Fix at_xdmac_lld struct definition + - arm64: dts: qcom: msm8996: drop not documented adreno properties + - net_sched: restore "mpu xxx" handling + - bcmgenet: add WOL IRQ check + - net: ethernet: mtk_eth_soc: fix error checking in mtk_mac_config() + - dt-bindings: display: meson-dw-hdmi: add missing sound-name-prefix property + - dt-bindings: display: meson-vpu: Add missing amlogic,canvas property + - scripts/dtc: dtx_diff: remove broken example from help text + - lib82596: Fix IRQ check in sni_82596_probe + - lib/test_meminit: destroy cache in kmem_cache_alloc_bulk() test + - mtd: nand: bbt: Fix corner case in bad block table handling + - Revert "ia64: kprobes: Use generic kretprobe trampoline handler" + - Linux 5.4.174 + * Focal update: v5.4.173 upstream stable release (LP: #1959701) + - kbuild: Add $(KBUILD_HOSTLDFLAGS) to 'has_libelf' test + - devtmpfs regression fix: reconfigure on each mount + - orangefs: Fix the size of a memory allocation in orangefs_bufmap_alloc() + - perf: Protect perf_guest_cbs with RCU + - KVM: s390: Clarify SIGP orders versus STOP/RESTART + - media: uvcvideo: fix division by zero at stream start + - rtlwifi: rtl8192cu: Fix WARNING when calling local_irq_restore() with + interrupts enabled + - firmware: qemu_fw_cfg: fix sysfs information leak + - firmware: qemu_fw_cfg: fix NULL-pointer deref on duplicate entries + - firmware: qemu_fw_cfg: fix kobject leak in probe error path + - KVM: x86: remove PMU FIXED_CTR3 from msrs_to_save_all + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master after + reboot from Windows + - mtd: fixup CFI on ixp4xx + - ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD + - Linux 5.4.173 + * Focal update: v5.4.172 upstream stable release (LP: #1959698) + - workqueue: Fix unbind_workers() VS wq_worker_running() race + - Bluetooth: btusb: fix memory leak in btusb_mtk_submit_wmt_recv_urb() + - Bluetooth: bfusb: fix division by zero in send path + - USB: core: Fix bug in resuming hub's handling of wakeup requests + - USB: Fix "slab-out-of-bounds Write" bug in usb_hcd_poll_rh_status + - mmc: sdhci-pci: Add PCI ID for Intel ADL + - veth: Do not record rx queue hint in veth_xmit + - mfd: intel-lpss: Fix too early PM enablement in the ACPI ->probe() + - drivers core: Use sysfs_emit and sysfs_emit_at for show(device *...) + functions + - can: gs_usb: fix use of uninitialized variable, detach device on reception + of invalid USB data + - can: gs_usb: gs_can_start_xmit(): zero-initialize hf->{flags,reserved} + - random: fix data race on crng_node_pool + - random: fix data race on crng init time + - random: fix crash on multiple early calls to add_bootloader_randomness() + - media: Revert "media: uvcvideo: Set unique vdev name based in type" + - staging: wlan-ng: Avoid bitwise vs logical OR warning in + hfa384x_usb_throttlefn() + - drm/i915: Avoid bitwise vs logical OR warning in snb_wm_latency_quirk() + - staging: greybus: fix stack size warning with UBSAN + - Linux 5.4.172 + * Focal update: v5.4.171 upstream stable release (LP: #1959437) + - f2fs: quota: fix potential deadlock + - Input: touchscreen - Fix backport of + a02dcde595f7cbd240ccd64de96034ad91cffc40 + - selftests: x86: fix [-Wstringop-overread] warn in test_process_vm_readv() + - tracing: Fix check for trace_percpu_buffer validity in get_trace_buf() + - tracing: Tag trace_percpu_buffer as a percpu pointer + - ieee802154: atusb: fix uninit value in atusb_set_extended_addr + - iavf: Fix limit of total number of queues to active queues of VF + - RDMA/core: Don't infoleak GRH fields + - RDMA/uverbs: Check for null return of kmalloc_array + - mac80211: initialize variable have_higher_than_11mbit + - i40e: fix use-after-free in i40e_sync_filters_subtask() + - i40e: Fix for displaying message regarding NVM version + - i40e: Fix incorrect netdev's real number of RX/TX queues + - ipv4: Check attribute length for RTA_GATEWAY in multipath route + - ipv4: Check attribute length for RTA_FLOW in multipath route + - ipv6: Check attribute length for RTA_GATEWAY in multipath route + - ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route + - lwtunnel: Validate RTA_ENCAP_TYPE attribute length + - batman-adv: mcast: don't send link-local multicast to mcast routers + - sch_qfq: prevent shift-out-of-bounds in qfq_init_qdisc + - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8081 + - power: supply: core: Break capacity loop + - power: reset: ltc2952: Fix use of floating point literals + - rndis_host: support Hytera digital radios + - phonet: refcount leak in pep_sock_accep + - ipv6: Continue processing multipath route even if gateway attribute is + invalid + - ipv6: Do cleanup if attribute validation fails in multipath route + - usb: mtu3: fix interval value for intr and isoc + - scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown() + - ip6_vti: initialize __ip6_tnl_parm struct in vti6_siocdevprivate + - net: udp: fix alignment problem in udp4_seq_show() + - atlantic: Fix buff_ring OOB in aq_ring_rx_clean + - mISDN: change function names to avoid conflicts + - Linux 5.4.171 + * Focal update: v5.4.170 upstream stable release (LP: #1958898) + - tee: handle lookup of shm with reference count 0 + - Input: i8042 - add deferred probe support + - Input: i8042 - enable deferred probe quirk for ASUS UM325UA + - tomoyo: Check exceeded quota early in tomoyo_domain_quota_is_ok(). + - platform/x86: apple-gmux: use resource_size() with res + - memblock: fix memblock_phys_alloc() section mismatch error + - recordmcount.pl: fix typo in s390 mcount regex + - selinux: initialize proto variable in selinux_ip_postroute_compat() + - scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write() + - net/mlx5: DR, Fix NULL vs IS_ERR checking in dr_domain_init_resources + - sctp: use call_rcu to free endpoint + - net: usb: pegasus: Do not drop long Ethernet frames + - net: lantiq_xrx200: fix statistics of received bytes + - NFC: st21nfca: Fix memory leak in device probe and remove + - ionic: Initialize the 'lif->dbid_inuse' bitmap + - net/mlx5e: Fix wrong features assignment in case of error + - selftests/net: udpgso_bench_tx: fix dst ip argument + - net/ncsi: check for error return from call to nla_put_u32 + - fsl/fman: Fix missing put_device() call in fman_port_probe + - i2c: validate user data in compat ioctl + - nfc: uapi: use kernel size_t to fix user-space builds + - uapi: fix linux/nfc.h userspace compilation errors + - xhci: Fresco FL1100 controller should not have BROKEN_MSI quirk set. + - usb: gadget: f_fs: Clear ffs_eventfd in ffs_data_clear. + - usb: mtu3: add memory barrier before set GPD's HWO + - usb: mtu3: fix list_head check warning + - usb: mtu3: set interval of FS intr and isoc endpoint + - binder: fix async_free_space accounting for empty parcels + - scsi: vmw_pvscsi: Set residual data length conditionally + - Input: appletouch - initialize work before device registration + - Input: spaceball - fix parsing of movement data packets + - net: fix use-after-free in tw_timer_handler + - perf script: Fix CPU filtering of a script's switch events + - Linux 5.4.170 + * Focal update: v5.4.170 upstream stable release (LP: #1958898) // HID_ASUS + should depend on USB_HID in stable v4.15 backports (LP: #1959762) + - HID: asus: Add depends on USB_HID to HID_ASUS Kconfig option + * Focal update: v5.4.169 upstream stable release (LP: #1958557) + - net: usb: lan78xx: add Allied Telesis AT29M2-AF + - serial: 8250_fintek: Fix garbled text for console + - arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode + - spi: change clk_disable_unprepare to clk_unprepare + - IB/qib: Fix memory leak in qib_user_sdma_queue_pkts() + - netfilter: fix regression in looped (broad|multi)cast's MAC handling + - qlcnic: potential dereference null pointer of rx_queue->page_ring + - net: accept UFOv6 packages in virtio_net_hdr_to_skb + - net: skip virtio_net_hdr_set_proto if protocol already set + - ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module + - bonding: fix ad_actor_system option setting to default + - fjes: Check for error irq + - drivers: net: smc911x: Check for error irq + - sfc: falcon: Check null pointer of rx_queue->page_ring + - Input: elantech - fix stack out of bound access in + elantech_change_report_id() + - hwmon: (lm90) Fix usage of CONFIG2 register in detect function + - hwmon: (lm90) Add max6654 support to lm90 driver + - hwmon: (lm90) Add basic support for TI TMP461 + - hwmon: (lm90) Introduce flag indicating extended temperature support + - hwmon: (lm90) Drop critical attribute support for MAX6654 + - ALSA: jack: Check the return value of kstrdup() + - ALSA: drivers: opl3: Fix incorrect use of vp->state + - ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6 + - Input: atmel_mxt_ts - fix double free in mxt_read_info_block + - ipmi: bail out if init_srcu_struct fails + - ipmi: ssif: initialize ssif_info->client early + - ipmi: fix initialization when workqueue allocation fails + - parisc: Correct completer in lws start + - x86/pkey: Fix undefined behaviour with PKRU_WD_BIT + - pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines + - mmc: sdhci-tegra: Fix switch to HS400ES mode + - mmc: core: Disable card detect during shutdown + - ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling + - tee: optee: Fix incorrect page free bug + - f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() + - usb: gadget: u_ether: fix race in setting MAC address in setup phase + - KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state + - mm: mempolicy: fix THP allocations escaping mempolicy restrictions + - pinctrl: mediatek: fix global-out-of-bounds issue + - hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681 + - hwmon: (lm90) Do not report 'busy' status bit as alarm + - ax25: NPD bug when detaching AX25 device + - hamradio: defer ax25 kfree after unregister_netdev + - hamradio: improve the incomplete fix to avoid NPD + - phonet/pep: refuse to enable an unbound pipe + - Linux 5.4.169 + * Focal update: v5.4.168 upstream stable release (LP: #1957991) + - KVM: selftests: Make sure kvm_create_max_vcpus test won't hit RLIMIT_NOFILE + - mac80211: mark TX-during-stop for TX in in_reconfig + - mac80211: send ADDBA requests using the tid/queue of the aggregation session + - firmware: arm_scpi: Fix string overflow in SCPI genpd driver + - virtio_ring: Fix querying of maximum DMA mapping size for virtio device + - recordmcount.pl: look for jgnop instruction as well as bcrl on s390 + - dm btree remove: fix use after free in rebalance_children() + - audit: improve robustness of the audit queue handling + - iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda + - nfsd: fix use-after-free due to delegation race + - arm64: dts: rockchip: remove mmc-hs400-enhanced-strobe from rk3399-khadas- + edge + - arm64: dts: rockchip: fix rk3399-leez-p710 vcc3v3-lan supply + - arm64: dts: rockchip: fix audio-supply for Rock Pi 4 + - mac80211: track only QoS data frames for admission control + - ARM: socfpga: dts: fix qspi node compatible + - clk: Don't parent clks until the parent is fully registered + - selftests: net: Correct ping6 expected rc from 2 to 1 + - s390/kexec_file: fix error handling when applying relocations + - sch_cake: do not call cake_destroy() from cake_init() + - inet_diag: use jiffies_delta_to_msecs() + - inet_diag: fix kernel-infoleak for UDP sockets + - selftests: Fix raw socket bind tests with VRF + - selftests: Fix IPv6 address bind tests + - dmaengine: st_fdma: fix MODULE_ALIAS + - selftest/net/forwarding: declare NETIFS p9 p10 + - mac80211: agg-tx: refactor sending addba + - mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock + - mac80211: accept aggregation sessions on 6 GHz + - mac80211: fix lookup when adding AddBA extension element + - net: sched: lock action when translating it to flow_action infra + - flow_offload: return EOPNOTSUPP for the unsupported mpls action type + - rds: memory leak in __rds_conn_create() + - soc/tegra: fuse: Fix bitwise vs. logical OR warning + - igb: Fix removal of unicast MAC filters of VFs + - igbvf: fix double free in `igbvf_probe` + - ixgbe: set X550 MDIO speed before talking to PHY + - netdevsim: Zero-initialize memory for new map's value in function + nsim_bpf_map_alloc + - net: Fix double 0x prefix print in SKB dump + - net/smc: Prevent smc_release() from long blocking + - net: systemport: Add global locking for descriptor lifecycle + - sit: do not call ipip6_dev_free() from sit_init_net() + - USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04) + - PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error + - PCI/MSI: Mask MSI-X vectors only on success + - usb: xhci: Extend support for runtime power management for AMD's Yellow + carp. + - USB: serial: cp210x: fix CP2105 GPIO registration + - USB: serial: option: add Telit FN990 compositions + - timekeeping: Really make sure wall_to_monotonic isn't positive + - libata: if T_LENGTH is zero, dma direction should be DMA_NONE + - drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE + - mac80211: validate extended element ID is present + - mwifiex: Remove unnecessary braces from HostCmd_SET_SEQ_NO_BSS_INFO + - Input: touchscreen - avoid bitwise vs logical OR warning + - ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name + - xsk: Do not sleep in poll() when need_wakeup set + - media: mxl111sf: change mutex_init() location + - fuse: annotate lock in fuse_reverse_inval_entry() + - ovl: fix warning in ovl_create_real() + - scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select() + - rcu: Mark accesses to rcu_state.n_force_qs + - mac80211: fix regression in SSN handling of addba tx + - net: sched: Fix suspicious RCU usage while accessing tcf_tunnel_info + - Revert "xsk: Do not sleep in poll() when need_wakeup set" + - xen/blkfront: harden blkfront against event channel storms + - xen/netfront: harden netfront against event channel storms + - xen/console: harden hvc_xen against event channel storms + - xen/netback: fix rx queue stall detection + - xen/netback: don't queue unlimited number of packages + - Linux 5.4.168 + * Focal update: v5.4.167 upstream stable release (LP: #1957987) + - nfc: fix segfault in nfc_genl_dump_devices_done + - drm/msm/dsi: set default num_data_lanes + - net/mlx4_en: Update reported link modes for 1/10G + - parisc/agp: Annotate parisc agp init functions with __init + - i2c: rk3x: Handle a spurious start completion interrupt flag + - net: netlink: af_netlink: Prevent empty skb by adding a check on len. + - drm/amd/display: Fix for the no Audio bug with Tiled Displays + - drm/amd/display: add connector type check for CRC source set + - tracing: Fix a kmemleak false positive in tracing_map + - KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req + - selinux: fix race condition when computing ocontext SIDs + - bpf: Fix integer overflow in argument calculation for bpf_map_area_alloc + - hwmon: (dell-smm) Fix warning on /proc/i8k creation error + - memblock: free_unused_memmap: use pageblock units instead of MAX_ORDER + - memblock: align freed memory map on pageblock boundaries with SPARSEMEM + - memblock: ensure there is no overflow in memblock_overlaps_region() + - arm: extend pfn_valid to take into account freed memory map alignment + - arm: ioremap: don't abuse pfn_valid() to check if pfn is in RAM + - Linux 5.4.167 + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.4.0-104.118 ] + + * CVE-2022-23960 + - SAUCE: kvm: arm: fix build on 32-bit + + -- Tim Gardner Mon, 14 Mar 2022 07:15:47 -0600 + +linux-oracle (5.4.0-1066.71) focal; urgency=medium + + * CVE-2022-23960 + - [Config] bluefield: Set CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + + * Disable unprivileged BPF by default (LP: #1961338) + - [Config] azure: Enable CONFIG_BPF_UNPRIV_DEFAULT_OFF + + [ Ubuntu: 5.4.0-103.117 ] + + * CVE-2022-23960 + - arm64: Add part number for Arm Cortex-A77 + - arm64: Add Neoverse-N2, Cortex-A710 CPU part definition + - arm64: Add Cortex-X2 CPU part definition + - arm64: add ID_AA64ISAR2_EL1 sys register + - SAUCE: arm64: entry.S: Add ventry overflow sanity checks + - SAUCE: arm64: entry: Make the trampoline cleanup optional + - SAUCE: arm64: entry: Free up another register on kpti's tramp_exit path + - SAUCE: arm64: entry: Move the trampoline data page before the text page + - SAUCE: arm64: entry: Allow tramp_alias to access symbols after the 4K + boundary + - SAUCE: arm64: entry: Don't assume tramp_vectors is the start of the vectors + - SAUCE: arm64: entry: Move trampoline macros out of ifdef'd section + - SAUCE: arm64: entry: Make the kpti trampoline's kpti sequence optional + - SAUCE: arm64: entry: Allow the trampoline text to occupy multiple pages + - SAUCE: arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations + - SAUCE: arm64: entry: Add vectors that have the bhb mitigation sequences + - SAUCE: arm64: entry: Add macro for reading symbol addresses from the + trampoline + - SAUCE: arm64: Add percpu vectors for EL1 + - SAUCE: arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of + Spectre-v2 + - SAUCE: KVM: arm64: Add templates for BHB mitigation sequences + - SAUCE: arm64: Mitigate spectre style branch history side channels + - SAUCE: KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and + migrated + - SAUCE: arm64: Use the clearbhb instruction in mitigations + - [Config]: set CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y + * CVE-2022-25636 + - netfilter: nf_tables_offload: incorrect flow offload action array size + * CVE-2022-0001 + - x86/speculation: Merge one test in spectre_v2_user_select_mitigation() + - x86,bugs: Unconditionally allow spectre_v2=retpoline,amd + - SAUCE: x86/speculation: Rename RETPOLINE_AMD to RETPOLINE_LFENCE + - SAUCE: x86/speculation: Add eIBRS + Retpoline options + - SAUCE: Documentation/hw-vuln: Update spectre doc + * Disable unprivileged BPF by default (LP: #1961338) + - bpf: Add kconfig knob for disabling unpriv bpf by default + - [Config] set CONFIG_BPF_UNPRIV_DEFAULT_OFF=y + + -- Thadeu Lima de Souza Cascardo Wed, 02 Mar 2022 08:49:20 -0300 + +linux-oracle (5.4.0-1064.68) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1064.68 -proposed tracker (LP: #1959267) + + [ Ubuntu: 5.4.0-100.113 ] + + * focal/linux: 5.4.0-100.113 -proposed tracker (LP: #1959900) + * CVE-2022-22942 + - SAUCE: drm/vmwgfx: Fix stale file descriptors on failed usercopy + * CVE-2022-0330 + - drm/i915: Flush TLBs before releasing backing store + * Focal update: v5.4.166 upstream stable release (LP: #1957008) + - netfilter: selftest: conntrack_vrf.sh: fix file permission + - Linux 5.4.166 + - net/packet: rx_owner_map depends on pg_vec + - USB: gadget: bRequestType is a bitfield, not a enum + - HID: holtek: fix mouse probing + - udp: using datalen to cap ipv6 udp max gso segments + - selftests: Calculate udpgso segment count without header adjustment + * Focal update: v5.4.165 upstream stable release (LP: #1957007) + - serial: tegra: Change lower tolerance baud rate limit for tegra20 and + tegra30 + - ntfs: fix ntfs_test_inode and ntfs_init_locked_inode function type + - HID: quirks: Add quirk for the Microsoft Surface 3 type-cover + - HID: google: add eel USB id + - HID: add hid_is_usb() function to make it simpler for USB detection + - HID: add USB_HID dependancy to hid-prodikeys + - HID: add USB_HID dependancy to hid-chicony + - HID: add USB_HID dependancy on some USB HID drivers + - HID: bigbenff: prevent null pointer dereference + - HID: wacom: fix problems when device is not a valid USB device + - HID: check for valid USB device for many HID drivers + - can: kvaser_usb: get CAN clock frequency from device + - can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct + stats->{rx,tx}_errors counter + - can: sja1000: fix use after free in ems_pcmcia_add_card() + - nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done + - selftests: netfilter: add a vrf+conntrack testcase + - vrf: don't run conntrack on vrf with !dflt qdisc + - bpf: Fix the off-by-two error in range markings + - ice: ignore dropped packets during init + - bonding: make tx_rebalance_counter an atomic + - nfp: Fix memory leak in nfp_cpp_area_cache_add() + - seg6: fix the iif in the IPv6 socket control block + - udp: using datalen to cap max gso segments + - iavf: restore MSI state on reset + - iavf: Fix reporting when setting descriptor count + - IB/hfi1: Correct guard on eager buffer deallocation + - mm: bdi: initialize bdi_min_ratio when bdi is unregistered + - ALSA: ctl: Fix copy of updated id with element read/write + - ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform + - ALSA: pcm: oss: Fix negative period/buffer sizes + - ALSA: pcm: oss: Limit the period size to 16MB + - ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*() + - btrfs: clear extent buffer uptodate when we fail to write it + - btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling + - nfsd: Fix nsfd startup race (again) + - tracefs: Have new files inherit the ownership of their parent + - clk: qcom: regmap-mux: fix parent clock lookup + - drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence. + - can: pch_can: pch_can_rx_normal: fix use after free + - can: m_can: Disable and ignore ELO interrupt + - x86/sme: Explicitly map new EFI memmap table as encrypted + - libata: add horkage for ASMedia 1092 + - wait: add wake_up_pollfree() + - SAUCE: binder: export __wake_up_pollfree for binder module + - binder: use wake_up_pollfree() + - signalfd: use wake_up_pollfree() + - aio: keep poll requests on waitqueue until completed + - aio: fix use-after-free due to missing POLLFREE handling + - tracefs: Set all files to the same group ownership as the mount option + - block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2) + - qede: validate non LSO skb length + - ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer + - i40e: Fix failed opcode appearing if handling messages from VF + - i40e: Fix pre-set max number of queues for VF + - mtd: rawnand: fsmc: Take instruction delay into account + - mtd: rawnand: fsmc: Fix timing computation + - dt-bindings: net: Reintroduce PHY no lane swap binding + - tools build: Remove needless libpython-version feature check that breaks + test-all fast path + - net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero + - net: altera: set a couple error code in probe() + - net: fec: only clear interrupt of handling queue in fec_enet_rx_queue() + - net, neigh: clear whole pneigh_entry at alloc time + - net/qla3xxx: fix an error code in ql_adapter_up() + - Revert "UBUNTU: SAUCE: selftests: fib_tests: assign address to dummy1 for + rp_filter tests" + - selftests/fib_tests: Rework fib_rp_filter_test() + - USB: gadget: detect too-big endpoint 0 requests + - USB: gadget: zero allocate endpoint 0 buffers + - usb: core: config: fix validation of wMaxPacketValue entries + - xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime + suspending + - usb: core: config: using bit mask instead of individual bits + - xhci: avoid race between disable slot command and host runtime suspend + - iio: trigger: Fix reference counting + - iio: trigger: stm32-timer: fix MODULE_ALIAS + - iio: stk3310: Don't return error code in interrupt handler + - iio: mma8452: Fix trigger reference couting + - iio: ltr501: Don't return error code in trigger handler + - iio: kxsd9: Don't return error code in trigger handler + - iio: itg3200: Call iio_trigger_notify_done() on error + - iio: dln2-adc: Fix lockdep complaint + - iio: dln2: Check return value of devm_iio_trigger_register() + - iio: at91-sama5d2: Fix incorrect sign extension + - iio: adc: axp20x_adc: fix charging current reporting on AXP22x + - iio: ad7768-1: Call iio_trigger_notify_done() on error + - iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove + - irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc() + - irqchip/armada-370-xp: Fix support for Multi-MSI interrupts + - irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL + - irqchip: nvic: Fix offset for Interrupt Priority Offsets + - misc: fastrpc: fix improper packet size calculation + - bpf: Add selftests to cover packet access corner cases + - Linux 5.4.165 + * Focal update: v5.4.164 upstream stable release (LP: #1956381) + - NFSv42: Fix pagecache invalidation after COPY/CLONE + - of: clk: Make self-contained + - arm64: dts: mcbin: support 2W SFP modules + - can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM + - gfs2: Fix length of holes reported at end-of-file + - drm/sun4i: fix unmet dependency on RESET_CONTROLLER for PHY_SUN6I_MIPI_DPHY + - mac80211: do not access the IV when it was stripped + - net/smc: Transfer remaining wait queue entries during fallback + - atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait + - net: return correct error code + - platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep + - s390/setup: avoid using memblock_enforce_memory_limit + - btrfs: check-integrity: fix a warning on write caching disabled disk + - thermal: core: Reset previous low and high trip during thermal zone init + - scsi: iscsi: Unblock session then wake up error handler + - ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile + - ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in + hns_dsaf_ge_srst_by_port() + - net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of + bound + - net: ethernet: dec: tulip: de4x5: fix possible array overflows in + type3_infoblock() + - perf hist: Fix memory leak of a perf_hpp_fmt + - perf report: Fix memory leaks around perf_tip() + - net/smc: Avoid warning of possible recursive locking + - vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit + - kprobes: Limit max data_size of the kretprobe instances + - rt2x00: do not mark device gone on EPROTO errors during start + - cpufreq: Fix get_cpu_device() failure in add_cpu_dev_symlink() + - s390/pci: move pseudo-MMIO to prevent MIO overlap + - sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl + - sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl + - i2c: stm32f7: flush TX FIFO upon transfer errors + - i2c: stm32f7: recover the bus on access timeout + - i2c: stm32f7: stop dma transfer in case of NACK + - i2c: cbus-gpio: set atomic transfer callback + - natsemi: xtensa: fix section mismatch warnings + - net: qlogic: qlcnic: Fix a NULL pointer dereference in + qlcnic_83xx_add_rings() + - net: mpls: Fix notifications when deleting a device + - siphash: use _unaligned version by default + - net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources() + - selftests: net: Correct case name + - rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer() + - net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ + is available + - net: marvell: mvpp2: Fix the computation of shared CPUs + - net: annotate data-races on txq->xmit_lock_owner + - ipv4: convert fib_num_tclassid_users to atomic_t + - net/rds: correct socket tunable error in rds_tcp_tune() + - net/smc: Keep smc_close_final rc during active close + - drm/msm: Do hw_init() before capturing GPU state + - ipv6: fix memory leak in fib6_rule_suppress + - KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register + - sched/uclamp: Fix rq->uclamp_max not set on first enqueue + - parisc: Fix KBUILD_IMAGE for self-extracting kernel + - parisc: Fix "make install" on newer debian releases + - vgacon: Propagate console boot parameters before calling `vc_resize' + - xhci: Fix commad ring abort, write all 64 bits to CRCR register. + - USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub + - usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect + - x86/tsc: Add a timer to make sure TSC_adjust is always checked + - x86/tsc: Disable clocksource watchdog for TSC on qualified platorms + - x86/64/mm: Map all kernel memory into trampoline_pgd + - tty: serial: msm_serial: Deactivate RX DMA for polling support + - serial: pl011: Add ACPI SBSA UART match id + - serial: core: fix transmit-buffer reset and memleak + - serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array + - serial: 8250_pci: rewrite pericom_do_set_divisor() + - iwlwifi: mvm: retry init flow if failed + - parisc: Mark cr16 CPU clocksource unstable on all SMP machines + - net/tls: Fix authentication failure in CCM mode + - Linux 5.4.164 + * Focal update: v5.4.163 upstream stable release (LP: #1956380) + - USB: serial: option: add Telit LE910S1 0x9200 composition + - USB: serial: option: add Fibocom FM101-GL variants + - usb: dwc2: gadget: Fix ISOC flow for elapsed frames + - usb: dwc2: hcd_queue: Fix use of floating point literal + - net: nexthop: fix null pointer dereference when IPv6 is not enabled + - usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts + - usb: hub: Fix usb enumeration issue due to address0 race + - usb: hub: Fix locking issues with address0_mutex + - binder: fix test regression due to sender_euid change + - ALSA: ctxfi: Fix out-of-range access + - media: cec: copy sequence field for the reply + - HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts + - staging/fbtft: Fix backlight + - staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect() + - xen: don't continue xenstore initialization in case of errors + - xen: detect uninitialized xenbus in xenbus_init + - KVM: PPC: Book3S HV: Prevent POWER7/8 TLB flush flushing SLB + - tracing/uprobe: Fix uprobe_perf_open probes iteration + - tracing: Fix pid filtering when triggers are attached + - mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB + - mdio: aspeed: Fix "Link is Down" issue + - PCI: aardvark: Deduplicate code in advk_pcie_rd_conf() + - PCI: aardvark: Wait for endpoint to be ready before training link + - PCI: aardvark: Fix big endian support + - PCI: aardvark: Train link immediately after enabling training + - PCI: aardvark: Improve link training + - PCI: aardvark: Issue PERST via GPIO + - PCI: aardvark: Replace custom macros by standard linux/pci_regs.h macros + - PCI: aardvark: Don't touch PCIe registers if no card connected + - PCI: aardvark: Fix compilation on s390 + - PCI: aardvark: Move PCIe reset card code to advk_pcie_train_link() + - PCI: aardvark: Update comment about disabling link training + - PCI: pci-bridge-emul: Fix array overruns, improve safety + - PCI: aardvark: Configure PCIe resources from 'ranges' DT property + - PCI: aardvark: Fix PCIe Max Payload Size setting + - PCI: aardvark: Implement re-issuing config requests on CRS response + - PCI: aardvark: Simplify initialization of rootcap on virtual bridge + - PCI: aardvark: Fix link training + - PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated + bridge + - PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge + - PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge + - pinctrl: armada-37xx: Correct PWM pins definitions + - arm64: dts: marvell: armada-37xx: Set pcie_reset_pin to gpio function + - proc/vmcore: fix clearing user buffer by properly using clear_user() + - netfilter: ipvs: Fix reuse connection if RS weight is 0 + - ARM: dts: BCM5301X: Fix I2C controller interrupt + - ARM: dts: BCM5301X: Add interrupt properties to GPIO node + - ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer + - ASoC: topology: Add missing rwsem around snd_ctl_remove() calls + - net: ieee802154: handle iftypes as u32 + - firmware: arm_scmi: pm: Propagate return value to caller + - NFSv42: Don't fail clone() unless the OP_CLONE operation failed + - ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE + - scsi: mpt3sas: Fix kernel panic during drive powercycle test + - drm/vc4: fix error code in vc4_create_object() + - iavf: Prevent changing static ITR values if adaptive moderation is on + - ipv6: fix typos in __ip6_finish_output() + - nfp: checking parameter process for rx-usecs/tx-usecs is invalid + - net: ipv6: add fib6_nh_release_dsts stub + - net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group + - scsi: core: sysfs: Fix setting device state to SDEV_RUNNING + - net/smc: Ensure the active closing peer first closes clcsock + - nvmet-tcp: fix incomplete data digest send + - net/ncsi : Add payload to be 32-bit aligned to fix dropped packets + - PM: hibernate: use correct mode for swsusp_close() + - tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited + flows + - nvmet: use IOCB_NOWAIT only if the filesystem supports it + - igb: fix netpoll exit with traffic + - MIPS: use 3-level pgtable for 64KB page size on MIPS_VA_BITS_48 + - net: vlan: fix underflow for the real_dev refcnt + - net/smc: Don't call clcsock shutdown twice when smc shutdown + - net: hns3: fix VF RSS failed problem after PF enable multi-TCs + - net: mscc: ocelot: don't downgrade timestamping RX filters in SIOCSHWTSTAMP + - net: mscc: ocelot: correctly report the timestamping RX filters in ethtool + - f2fs: set SBI_NEED_FSCK flag when inconsistent node block found + - smb3: do not error on fsync when readonly + - vhost/vsock: fix incorrect used length reported to the guest + - tracing: Check pid filtering when creating events + - s390/mm: validate VMA in PGSTE manipulation functions + - shm: extend forced shm destroy to support objects from several IPC nses + - NFC: add NCI_UNREG flag to eliminate the race + - fuse: release pipe buf after last use + - xen: sync include/xen/interface/io/ring.h with Xen's newest version + - xen/blkfront: read response from backend only once + - xen/blkfront: don't take local copy of a request from the ring page + - xen/blkfront: don't trust the backend response data blindly + - xen/netfront: read response from backend only once + - xen/netfront: don't read data from request on the ring page + - xen/netfront: disentangle tx_skb_freelist + - xen/netfront: don't trust the backend response data blindly + - tty: hvc: replace BUG_ON() with negative return value + - Linux 5.4.163 + * net/mlx5e: EPERM on vlan 0 programming (LP: #1957753) + - net/mlx5e: Unblock setting vid 0 for VF in case PF isn't eswitch manager + * CVE-2021-4083 + - fget: check that the fd still exists after getting a ref to it + * CVE-2021-4155 + - xfs: map unwritten blocks in XFS_IOC_{ALLOC, FREE}SP just like fallocate + + -- Tim Gardner Wed, 09 Feb 2022 05:36:10 -0700 + +linux-oracle (5.4.0-1063.67) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1063.67 -proposed tracker (LP: #1959807) + + [ Ubuntu: 5.4.0-99.112 ] + + * focal/linux: 5.4.0-99.112 -proposed tracker (LP: #1959817) + * linux-image-5.4.0-97.110 freezes by accessing cifs shares (LP: #1959665) + - Revert "cifs: To match file servers, make sure the server hostname matches" + - Revert "cifs: set a minimum of 120s for next dns resolution" + - Revert "cifs: use the expiry output of dns_query to schedule next + resolution" + + -- Tim Gardner Thu, 03 Feb 2022 07:51:50 -0700 + +linux-oracle (5.4.0-1062.66) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1062.66 -proposed tracker (LP: #1955235) + + [ Ubuntu: 5.4.0-97.110 ] + + * icmp_redirect from selftests fails on F/kvm (unary operator expected) + (LP: #1938964) + - selftests: icmp_redirect: pass xfail=0 to log_test() + * Focal: CIFS stable updates (LP: #1954926) + - cifs: use the expiry output of dns_query to schedule next resolution + - cifs: set a minimum of 120s for next dns resolution + - cifs: To match file servers, make sure the server hostname matches + * seccomp_bpf in seccomp from ubuntu_kernel_selftests failed to build on B-5.4 + (LP: #1896420) + - SAUCE: selftests/seccomp: fix "storage size of 'md' isn't known" build issue + - SAUCE: selftests/seccomp: Fix s390x regs not defined issue + * system crash when removing ipmi_msghandler module (LP: #1950666) + - ipmi: Move remove_work to dedicated workqueue + - ipmi: msghandler: Make symbol 'remove_work_wq' static + * zcrypt DD: Toleration for new IBM Z Crypto Hardware - (Backport to Ubuntu + 20.04) (LP: #1954680) + - s390/AP: support new dynamic AP bus size limit + * [UBUNTU 20.04] KVM hardware diagnose data improvements for guest kernel - + kernel part (LP: #1953334) + - s390/setup: diag 318: refactor struct + - s390/kvm: diagnose 0x318 sync and reset + - KVM: s390: remove diag318 reset code + - KVM: s390: add debug statement for diag 318 CPNC data + * Updates to ib_peer_memory requested by Nvidia (LP: #1947206) + - SAUCE: RDMA/core: Updated ib_peer_memory + * Include Infiniband Peer Memory interface (LP: #1923104) + - IB: Allow calls to ib_umem_get from kernel ULPs + - SAUCE: RDMA/core: Introduce peer memory interface + * Focal update: v5.4.162 upstream stable release (LP: #1954834) + - arm64: zynqmp: Do not duplicate flash partition label property + - arm64: zynqmp: Fix serial compatible string + - ARM: dts: NSP: Fix mpcore, mmc node names + - scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq() + - arm64: dts: hisilicon: fix arm,sp805 compatible string + - RDMA/bnxt_re: Check if the vlan is valid before reporting + - usb: musb: tusb6010: check return value after calling + platform_get_resource() + - usb: typec: tipd: Remove WARN_ON in tps6598x_block_read + - arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency + - arm64: dts: freescale: fix arm,sp805 compatible string + - ASoC: SOF: Intel: hda-dai: fix potential locking issue + - clk: imx: imx6ul: Move csi_sel mux to correct base register + - ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect + - scsi: advansys: Fix kernel pointer leak + - firmware_loader: fix pre-allocated buf built-in firmware use + - ARM: dts: omap: fix gpmc,mux-add-data type + - usb: host: ohci-tmio: check return value after calling + platform_get_resource() + - ARM: dts: ls1021a: move thermal-zones node out of soc/ + - ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash + - ALSA: ISA: not for M68K + - tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc + - MIPS: sni: Fix the build + - scsi: target: Fix ordered tag handling + - scsi: target: Fix alua_tg_pt_gps_count tracking + - iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr() + - powerpc/5200: dts: fix memory node unit name + - ALSA: gus: fix null pointer dereference on pointer block + - powerpc/dcr: Use cmplwi instead of 3-argument cmpli + - sh: check return code of request_irq + - maple: fix wrong return value of maple_bus_init(). + - f2fs: fix up f2fs_lookup tracepoints + - sh: fix kconfig unmet dependency warning for FRAME_POINTER + - sh: math-emu: drop unused functions + - sh: define __BIG_ENDIAN for math-emu + - clk: ingenic: Fix bugs with divided dividers + - clk/ast2600: Fix soc revision for AHB + - clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk + - mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set + - sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain() + - tracing: Save normal string variables + - tracing/histogram: Do not copy the fixed-size char array field over the + field size + - RDMA/netlink: Add __maybe_unused to static inline in C file + - perf bpf: Avoid memory leak from perf_env__insert_btf() + - perf bench futex: Fix memory leak of perf_cpu_map__new() + - perf tests: Remove bash construct from record+zstd_comp_decomp.sh + - net: bnx2x: fix variable dereferenced before check + - iavf: check for null in iavf_fix_features + - iavf: free q_vectors before queues in iavf_disable_vf + - iavf: Fix failure to exit out from last all-multicast mode + - iavf: prevent accidental free of filter structure + - iavf: validate pointers + - iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset + - MIPS: generic/yamon-dt: fix uninitialized variable error + - mips: bcm63xx: add support for clk_get_parent() + - mips: lantiq: add support for clk_get_parent() + - platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()' + - scsi: core: sysfs: Fix hang when device state is set via sysfs + - net: sched: act_mirred: drop dst for the direction from egress to ingress + - net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove + - net: virtio_net_hdr_to_skb: count transport header in UFO + - i40e: Fix correct max_pkt_size on VF RX queue + - i40e: Fix NULL ptr dereference on VSI filter sync + - i40e: Fix changing previously set num_queue_pairs for PFs + - i40e: Fix ping is lost after configuring ADq on VF + - i40e: Fix creation of first queue by omitting it if is not power of two + - i40e: Fix display error code in dmesg + - NFC: reorganize the functions in nci_request + - drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame + - NFC: reorder the logic in nfc_{un,}register_device + - KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr() + - perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server + - perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server + - s390/kexec: fix return code handling + - arm64: vdso32: suppress error message for 'make mrproper' + - tun: fix bonding active backup with arp monitoring + - hexagon: export raw I/O routines for modules + - ipc: WARN if trying to remove ipc object which is absent + - mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag + - x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails + - s390/kexec: fix memory leak of ipl report buffer + - udf: Fix crash after seekdir + - btrfs: fix memory ordering between normal and ordered work functions + - parisc/sticon: fix reverse colors + - cfg80211: call cfg80211_stop_ap when switch from P2P_GO type + - drm/udl: fix control-message timeout + - drm/nouveau: use drm_dev_unplug() during device removal + - drm/i915/dp: Ensure sink rate values are always valid + - drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga + and dvi connectors + - Revert "net: mvpp2: disable force link UP during port init procedure" + - perf/core: Avoid put_page() when GUP fails + - batman-adv: Consider fragmentation for needed_headroom + - batman-adv: Reserve needed_*room for fragments + - batman-adv: Don't always reallocate the fragmentation skb head + - ASoC: DAPM: Cover regression by kctl change notification fix + - usb: max-3421: Use driver data instead of maintaining a list of bound + devices + - ice: Delete always true check of PF pointer + - ALSA: hda: hdac_ext_stream: fix potential locking issues + - ALSA: hda: hdac_stream: fix potential locking issue in + snd_hdac_stream_assign() + - Linux 5.4.162 + * Focal update: v5.4.161 upstream stable release (LP: #1954828) + - scsi: ufs: Fix interrupt error message for shared interrupts + - MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL + - ext4: fix lazy initialization next schedule time computation in more + granular unit + - scsi: ufs: Fix tm request when non-fatal error happens + - fortify: Explicitly disable Clang support + - parisc/entry: fix trace test in syscall exit path + - PCI/MSI: Destroy sysfs before freeing entries + - PCI/MSI: Deal with devices lying about their MSI mask capability + - PCI: Add MSI masking quirk for Nvidia ION AHCI + - erofs: remove the occupied parameter from z_erofs_pagevec_enqueue() + - erofs: fix unsafe pagevec reuse of hooked pclusters + - Linux 5.4.161 + * Focal update: v5.4.160 upstream stable release (LP: #1953387) + - xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good + delay + - usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform + - binder: use euid from cred instead of using task + - binder: use cred instead of task for selinux checks + - binder: use cred instead of task for getsecid + - Input: iforce - fix control-message timeout + - Input: elantench - fix misreporting trackpoint coordinates + - Input: i8042 - Add quirk for Fujitsu Lifebook T725 + - libata: fix read log timeout value + - ocfs2: fix data corruption on truncate + - scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file + - scsi: qla2xxx: Fix use after free in eh_abort path + - mmc: dw_mmc: Dont wait for DRTO on Write RSP error + - parisc: Fix ptrace check on syscall return + - tpm: Check for integer overflow in tpm2_map_response_body() + - firmware/psci: fix application of sizeof to pointer + - crypto: s5p-sss - Add error handling in s5p_aes_probe() + - media: ite-cir: IR receiver stop working after receive overflow + - media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers + - media: v4l2-ioctl: Fix check_ext_ctrls + - ALSA: hda/realtek: Add quirk for Clevo PC70HS + - ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N + - ALSA: hda/realtek: Add quirk for ASUS UX550VE + - ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED + - ALSA: ua101: fix division by zero at probe + - ALSA: 6fire: fix control and bulk message timeouts + - ALSA: line6: fix control and interrupt message timeouts + - ALSA: usb-audio: Add registration quirk for JBL Quantum 400 + - ALSA: synth: missing check for possible NULL after the call to kstrdup + - ALSA: timer: Fix use-after-free problem + - ALSA: timer: Unconditionally unlink slave instances, too + - fuse: fix page stealing + - x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c + - x86/cpu: Fix migration safety with X86_BUG_NULL_SEL + - x86/irq: Ensure PI wakeup handler is unregistered before module unload + - cavium: Return negative value when pci_alloc_irq_vectors() fails + - scsi: qla2xxx: Return -ENOMEM if kzalloc() fails + - scsi: qla2xxx: Fix unmap of already freed sgl + - cavium: Fix return values of the probe function + - sfc: Don't use netif_info before net_device setup + - hyperv/vmbus: include linux/bitops.h + - ARM: dts: sun7i: A20-olinuxino-lime2: Fix ethernet phy-mode + - reset: socfpga: add empty driver allowing consumers to probe + - mmc: winbond: don't build on M68K + - drm: panel-orientation-quirks: Add quirk for Aya Neo 2021 + - bpf: Define bpf_jit_alloc_exec_limit for arm64 JIT + - bpf: Prevent increasing bpf_jit_limit above max + - xen/netfront: stop tx queues during live migration + - nvmet-tcp: fix a memory leak when releasing a queue + - spi: spl022: fix Microwire full duplex mode + - net: multicast: calculate csum of looped-back and forwarded packets + - watchdog: Fix OMAP watchdog early handling + - drm: panel-orientation-quirks: Add quirk for GPD Win3 + - nvmet-tcp: fix header digest verification + - r8169: Add device 10ec:8162 to driver r8169 + - vmxnet3: do not stop tx queues after netif_device_detach() + - nfp: bpf: relax prog rejection for mtu check through max_pkt_offset + - net/smc: Correct spelling mistake to TCPF_SYN_RECV + - btrfs: clear MISSING device status bit in btrfs_close_one_device + - btrfs: fix lost error handling when replaying directory deletes + - btrfs: call btrfs_check_rw_degradable only if there is a missing device + - ia64: kprobes: Fix to pass correct trampoline address to the handler + - hwmon: (pmbus/lm25066) Add offset coefficients + - regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is + disabled + - regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default- + dvs-idx property + - EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell + - mwifiex: fix division by zero in fw download path + - ath6kl: fix division by zero in send path + - ath6kl: fix control-message timeout + - ath10k: fix control-message timeout + - ath10k: fix division by zero in send path + - PCI: Mark Atheros QCA6174 to avoid bus reset + - rtl8187: fix control-message timeouts + - evm: mark evm_fixmode as __ro_after_init + - wcn36xx: Fix HT40 capability for 2Ghz band + - mwifiex: Read a PCI register after writing the TX ring write pointer + - libata: fix checking of DMA state + - wcn36xx: handle connection loss indication + - rsi: fix occasional initialisation failure with BT coex + - rsi: fix key enabled check causing unwanted encryption for vap_id > 0 + - rsi: fix rate mask set leading to P2P failure + - rsi: Fix module dev_oper_mode parameter description + - RDMA/qedr: Fix NULL deref for query_qp on the GSI QP + - signal: Remove the bogus sigkill_pending in ptrace_stop + - signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT + - power: supply: max17042_battery: Prevent int underflow in set_soc_threshold + - power: supply: max17042_battery: use VFSOC for capacity when no rsns + - KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use + - can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport + - can: j1939: j1939_can_recv(): ignore messages with invalid source address + - powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found + - serial: core: Fix initializing and restoring termios speed + - ALSA: mixer: oss: Fix racy access to slots + - ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume + - xen/balloon: add late_initcall_sync() for initial ballooning done + - PCI: pci-bridge-emul: Fix emulation of W1C bits + - PCI: aardvark: Do not clear status bits of masked interrupts + - PCI: aardvark: Fix checking for link up via LTSSM state + - PCI: aardvark: Do not unmask unused interrupts + - PCI: aardvark: Fix reporting Data Link Layer Link Active + - PCI: aardvark: Fix return value of MSI domain .alloc() method + - PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG + - quota: check block number when reading the block in quota file + - quota: correct error number in free_dqentry() + - pinctrl: core: fix possible memory leak in pinctrl_enable() + - iio: dac: ad5446: Fix ad5622_write() return value + - USB: serial: keyspan: fix memleak on probe errors + - USB: iowarrior: fix control-message timeouts + - USB: chipidea: fix interrupt deadlock + - dma-buf: WARN on dmabuf release with pending attachments + - drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2) + - drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1 + - drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6 + - Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg() + - Bluetooth: fix use-after-free error in lock_sock_nested() + - drm/panel-orientation-quirks: add Valve Steam Deck + - platform/x86: wmi: do not fail if disabling fails + - MIPS: lantiq: dma: add small delay after reset + - MIPS: lantiq: dma: reset correct number of channel + - locking/lockdep: Avoid RCU-induced noinstr fail + - net: sched: update default qdisc visibility after Tx queue cnt changes + - smackfs: Fix use-after-free in netlbl_catmap_walk() + - x86: Increase exception stack sizes + - mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type + - mwifiex: Properly initialize private structure on interface type changes + - ath10k: high latency fixes for beacon buffer + - media: mt9p031: Fix corrupted frame after restarting stream + - media: netup_unidvb: handle interrupt properly according to the firmware + - media: stm32: Potential NULL pointer dereference in dcmi_irq_thread() + - media: uvcvideo: Set capability in s_param + - media: uvcvideo: Return -EIO for control errors + - media: uvcvideo: Set unique vdev name based in type + - media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe() + - media: s5p-mfc: Add checking to s5p_mfc_probe(). + - media: imx: set a media_device bus_info string + - media: mceusb: return without resubmitting URB in case of -EPROTO error. + - ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK + - brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet + - media: rcar-csi2: Add checking to rcsi2_start_receiver() + - ipmi: Disable some operations during a panic + - ACPICA: Avoid evaluating methods too early during system resume + - media: ipu3-imgu: imgu_fmt: Handle properly try + - media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info + - media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte() + - net-sysfs: try not to restart the syscall if it will fail eventually + - tracefs: Have tracefs directories not set OTH permission bits by default + - ath: dfs_pattern_detector: Fix possible null-pointer dereference in + channel_detector_create() + - iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value + - ACPI: battery: Accept charges over the design capacity as full + - leaking_addresses: Always print a trailing newline + - memstick: r592: Fix a UAF bug when removing the driver + - lib/xz: Avoid overlapping memcpy() with invalid input with in-place + decompression + - lib/xz: Validate the value before assigning it to an enum variable + - workqueue: make sysfs of unbound kworker cpumask more clever + - tracing/cfi: Fix cmp_entries_* functions signature mismatch + - mwl8k: Fix use-after-free in mwl8k_fw_state_machine() + - block: remove inaccurate requeue check + - nvmet: fix use-after-free when a port is removed + - nvmet-tcp: fix use-after-free when a port is removed + - nvme: drop scan_lock and always kick requeue list when removing namespaces + - PM: hibernate: Get block device exclusively in swsusp_check() + - selftests: kvm: fix mismatched fclose() after popen() + - iwlwifi: mvm: disable RX-diversity in powersave + - smackfs: use __GFP_NOFAIL for smk_cipso_doi() + - ARM: clang: Do not rely on lr register for stacktrace + - gre/sit: Don't generate link-local addr if addr_gen_mode is + IN6_ADDR_GEN_MODE_NONE + - ARM: 9136/1: ARMv7-M uses BE-8, not BE-32 + - vrf: run conntrack only in context of lower/physdev for locally generated + packets + - net: annotate data-race in neigh_output() + - btrfs: do not take the uuid_mutex in btrfs_rm_device + - spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in + bcm_qspi_probe() + - x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted + - parisc: fix warning in flush_tlb_all + - task_stack: Fix end_of_stack() for architectures with upwards-growing stack + - parisc/unwind: fix unwinder when CONFIG_64BIT is enabled + - parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling + - netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream + state + - selftests/bpf: Fix strobemeta selftest regression + - Bluetooth: fix init and cleanup of sco_conn.timeout_work + - rcu: Fix existing exp request check in sync_sched_exp_online_cleanup() + - drm/v3d: fix wait for TMU write combiner flush + - virtio-gpu: fix possible memory allocation failure + - net: net_namespace: Fix undefined member in key_remove_domain() + - cgroup: Make rebind_subsystems() disable v2 controllers all at once + - wilc1000: fix possible memory leak in cfg_scan_result() + - Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync + - crypto: caam - disable pkc for non-E SoCs + - rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies() + - net: dsa: rtl8366rb: Fix off-by-one bug + - ath10k: Fix missing frame timestamp for beacon/probe-resp + - drm/amdgpu: fix warning for overflow check + - media: em28xx: add missing em28xx_close_extension + - media: cxd2880-spi: Fix a null pointer dereference on error handling path + - media: dvb-usb: fix ununit-value in az6027_rc_query + - media: TDA1997x: handle short reads of hdmi info frame. + - media: mtk-vpu: Fix a resource leak in the error handling path of + 'mtk_vpu_probe()' + - media: radio-wl1273: Avoid card name truncation + - media: si470x: Avoid card name truncation + - media: tm6000: Avoid card name truncation + - media: cx23885: Fix snd_card_free call on null card pointer + - kprobes: Do not use local variable when creating debugfs file + - crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency + - cpuidle: Fix kobject memory leaks in error paths + - media: em28xx: Don't use ops->suspend if it is NULL + - ath9k: Fix potential interrupt storm on queue reset + - EDAC/amd64: Handle three rank interleaving mode + - netfilter: nft_dynset: relax superfluous check on set updates + - media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable() + - crypto: qat - detect PFVF collision after ACK + - crypto: qat - disregard spurious PFVF interrupts + - hwrng: mtk - Force runtime pm ops for sleep ops + - b43legacy: fix a lower bounds test + - b43: fix a lower bounds test + - mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured + - memstick: avoid out-of-range warning + - memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host() + - net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE + - hwmon: Fix possible memleak in __hwmon_device_register() + - hwmon: (pmbus/lm25066) Let compiler determine outer dimension of + lm25066_coeff + - ath10k: fix max antenna gain unit + - drm/msm: uninitialized variable in msm_gem_import() + - net: stream: don't purge sk_error_queue in sk_stream_kill_queues() + - mmc: mxs-mmc: disable regulator on error and in the remove function + - block: ataflop: fix breakage introduced at blk-mq refactoring + - platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning + - mt76: mt76x02: fix endianness warnings in mt76x02_mac.c + - rsi: stop thread firstly in rsi_91x_init() error handling + - mwifiex: Send DELBA requests according to spec + - phy: micrel: ksz8041nl: do not use power down mode + - nvme-rdma: fix error code in nvme_rdma_setup_ctrl + - PM: hibernate: fix sparse warnings + - clocksource/drivers/timer-ti-dm: Select TIMER_OF + - drm/msm: Fix potential NULL dereference in DPU SSPP + - smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi + - libbpf: Fix BTF data layout checks and allow empty BTF + - s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap() + - irq: mips: avoid nested irq_enter() + - tcp: don't free a FIN sk_buff in tcp_remove_empty_skb() + - samples/kretprobes: Fix return value if register_kretprobe() failed + - KVM: s390: Fix handle_sske page fault handling + - libertas_tf: Fix possible memory leak in probe and disconnect + - libertas: Fix possible memory leak in probe and disconnect + - wcn36xx: add proper DMA memory barriers in rx path + - drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits + - net: amd-xgbe: Toggle PLL settings during rate change + - net: phylink: avoid mvneta warning when setting pause parameters + - crypto: pcrypt - Delay write to padata->info + - selftests/bpf: Fix fclose/pclose mismatch in test_progs + - udp6: allow SO_MARK ctrl msg to affect routing + - ibmvnic: don't stop queue in xmit + - ibmvnic: Process crqs after enabling interrupts + - RDMA/rxe: Fix wrong port_cap_flags + - clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths + - ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc() + - arm64: dts: rockchip: Fix GPU register width for RK3328 + - ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY + - RDMA/bnxt_re: Fix query SRQ failure + - arm64: dts: meson-g12a: Fix the pwm regulator supply properties + - ARM: dts: at91: tse850: the emac<->phy interface is rmii + - scsi: dc395: Fix error case unwinding + - MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT + - JFS: fix memleak in jfs_mount + - ALSA: hda: Reduce udelay() at SKL+ position reporting + - arm: dts: omap3-gta04a4: accelerometer irq fix + - soc/tegra: Fix an error handling path in tegra_powergate_power_up() + - memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe + - clk: at91: check pmc node status before registering syscore ops + - video: fbdev: chipsfb: use memset_io() instead of memset() + - serial: 8250_dw: Drop wrong use of ACPI_PTR() + - usb: gadget: hid: fix error code in do_config() + - power: supply: rt5033_battery: Change voltage values to µV + - scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn() + - RDMA/mlx4: Return missed an error if device doesn't support steering + - staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC + - ARM: dts: stm32: fix SAI sub nodes register range + - ASoC: cs42l42: Correct some register default values + - ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER + - phy: qcom-qusb2: Fix a memory leak on probe + - serial: xilinx_uartps: Fix race condition causing stuck TX + - HID: u2fzero: clarify error check and length calculations + - HID: u2fzero: properly handle timeouts in usb_submit_urb + - powerpc/44x/fsp2: add missing of_node_put + - mips: cm: Convert to bitfield API to fix out-of-bounds access + - power: supply: bq27xxx: Fix kernel crash on IRQ handler register error + - apparmor: fix error check + - rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined + - pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds + - drm/plane-helper: fix uninitialized variable reference + - PCI: aardvark: Don't spam about PIO Response Status + - PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge + - opp: Fix return in _opp_add_static_v2() + - NFS: Fix deadlocks in nfs_scan_commit_list() + - fs: orangefs: fix error return code of orangefs_revalidate_lookup() + - mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare() + - mtd: core: don't remove debugfs directory if device is in use + - dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro + - auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string + - auxdisplay: ht16k33: Connect backlight to fbdev + - auxdisplay: ht16k33: Fix frame buffer device blanking + - soc: fsl: dpaa2-console: free buffer before returning from + dpaa2_console_read + - netfilter: nfnetlink_queue: fix OOB when mac header was cleared + - dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result` + - signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL) + - m68k: set a default value for MEMORY_RESERVE + - watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT + - ar7: fix kernel builds for compiler test + - scsi: qla2xxx: Fix gnl list corruption + - scsi: qla2xxx: Turn off target reset during issue_lip + - NFSv4: Fix a regression in nfs_set_open_stateid_locked() + - i2c: xlr: Fix a resource leak in the error handling path of + 'xlr_i2c_probe()' + - xen-pciback: Fix return in pm_ctrl_init() + - net: davinci_emac: Fix interrupt pacing disable + - net: vlan: fix a UAF in vlan_dev_real_dev() + - ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses + - bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed + - mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and + zs_unregister_migration() + - zram: off by one in read_block_state() + - perf bpf: Add missing free to bpf_event__print_bpf_prog_info() + - llc: fix out-of-bound array index in llc_sk_dev_hash() + - nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails + - arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions + - bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding + - net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any + - net: hns3: allow configure ETS bandwidth of all TCs + - vsock: prevent unnecessary refcnt inc for nonblocking connect + - net/smc: fix sk_refcnt underflow on linkdown and fallback + - cxgb4: fix eeprom len when diagnostics not implemented + - selftests/net: udpgso_bench_rx: fix port argument + - ARM: 9155/1: fix early early_iounmap() + - ARM: 9156/1: drop cc-option fallbacks for architecture selection + - parisc: Fix set_fixmap() on PA1.x CPUs + - irqchip/sifive-plic: Fixup EOI failed when masked + - f2fs: should use GFP_NOFS for directory inodes + - net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE + - 9p/net: fix missing error check in p9_check_errors + - ovl: fix deadlock in splice write + - powerpc/lib: Add helper to check if offset is within conditional branch + range + - powerpc/bpf: Validate branch ranges + - powerpc/bpf: Fix BPF_SUB when imm == 0x80000000 + - powerpc/security: Add a helper to query stf_barrier type + - powerpc/bpf: Emit stf barrier instruction sequences for BPF_NOSPEC + - mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks + - mm, oom: do not trigger out_of_memory from the #PF + - video: backlight: Drop maximum brightness override for brightness zero + - s390/cio: check the subchannel validity for dev_busid + - s390/tape: fix timer initialization in tape_std_assign() + - s390/cio: make ccw_device_dma_* more robust + - powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload + - PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros + - SUNRPC: Partial revert of commit 6f9f17287e78 + - ath10k: fix invalid dma_addr_t token assignment + - selftests/bpf: Fix also no-alu32 strobemeta selftest + - Linux 5.4.160 + - soc/tegra: pmc: Fix imbalanced clock disabling in error code path + * Focal update: v5.4.159 upstream stable release (LP: #1953071) + - Revert "x86/kvm: fix vcpu-id indexed array sizes" + - usb: ehci: handshake CMD_RUN instead of STS_HALT + - usb: gadget: Mark USB_FSL_QE broken on 64-bit + - usb: musb: Balance list entry in musb_gadget_queue + - usb-storage: Add compatibility quirk flags for iODD 2531/2541 + - binder: don't detect sender/target during buffer cleanup + - printk/console: Allow to disable console output by using console="" or + console=null + - isofs: Fix out of bound access for corrupted isofs image + - comedi: dt9812: fix DMA buffers on stack + - comedi: ni_usb6501: fix NULL-deref in command paths + - comedi: vmk80xx: fix transfer-buffer overflows + - comedi: vmk80xx: fix bulk-buffer overflow + - comedi: vmk80xx: fix bulk and interrupt message timeouts + - staging: r8712u: fix control-message timeout + - staging: rtl8192u: fix control-message timeouts + - media: staging/intel-ipu3: css: Fix wrong size comparison imgu_css_fw_init + - rsi: fix control-message timeout + - Linux 5.4.159 + * Focal update: v5.4.158 upstream stable release (LP: #1953066) + - scsi: core: Put LLD module refcnt after SCSI device is released + - vrf: Revert "Reset skb conntrack connection..." + - net: ethernet: microchip: lan743x: Fix skb allocation failure + - media: firewire: firedtv-avc: fix a buffer overflow in avc_ca_pmt() + - Revert "xhci: Set HCD flag to defer primary roothub registration" + - Revert "usb: core: hcd: Add support for deferring roothub registration" + - sfc: Fix reading non-legacy supported link modes + - ARM: 9120/1: Revert "amba: make use of -1 IRQs warn" + - Linux 5.4.158 + * [Ubuntu 20.04] Problem leading IUCV service down (on s390x) (LP: #1913442) + - usercopy: mark dma-kmalloc caches as usercopy caches + + -- Tim Gardner Wed, 19 Jan 2022 05:59:07 -0700 + +linux-oracle (5.4.0-1061.65) focal; urgency=medium + + [ Ubuntu: 5.4.0-96.109 ] + + * Support builtin revoked certificates (LP: #1932029) + - [Config]: add i386 to CONFIG_SYSTEM_REVOCATION_KEYS annotation + * CVE-2022-0185 + - SAUCE: vfs: Out-of-bounds write of heap buffer in fs_context.c + - SAUCE: vfs: test that one given mount param is not larger than PAGE_SIZE + + [ Ubuntu: 5.4.0-94.106 ] + + * focal/linux: 5.4.0-94.106 -proposed tracker (LP: #1956628) + * [Regression] Focal kernel 5.4.0-92.103 fails to boot when Secure Encrypted + Virtualization(SEV) is enabled (LP: #1956575) + - x86/ioremap: Map EFI-reserved memory as encrypted for SEV + + -- Stefan Bader Thu, 13 Jan 2022 15:25:18 +0100 + +linux-oracle (5.4.0-1059.63) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1059.63 -proposed tracker (LP: #1952306) + + * Re-enable DEBUG_INFO_BTF where it was disabled (LP: #1945632) + - [Config] oracle: Enable CONFIG_DEBUG_INFO_BTF on all arches + + * Support builtin revoked certificates (LP: #1932029) + - [Config] oracle: Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys + + [ Ubuntu: 5.4.0-92.103 ] + + * focal/linux: 5.4.0-92.103 -proposed tracker (LP: #1952316) + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - debian/dkms-versions -- update from kernel-versions (main/2021.11.29) + * CVE-2021-4002 + - tlb: mmu_gather: add tlb_flush_*_range APIs + - hugetlbfs: flush TLBs correctly after huge_pmd_unshare + * Re-enable DEBUG_INFO_BTF where it was disabled (LP: #1945632) + - [Config] Enable CONFIG_DEBUG_INFO_BTF on all arches + * Focal linux-azure: Vm crash on Dv5/Ev5 (LP: #1950462) + - KVM: VMX: eVMCS: make evmcs_sanitize_exec_ctrls() work again + - jump_label: Fix usage in module __init + * Support builtin revoked certificates (LP: #1932029) + - Revert "UBUNTU: SAUCE: (lockdown) Make get_cert_list() not complain about + cert lists that aren't present." + - integrity: Move import of MokListRT certs to a separate routine + - integrity: Load certs from the EFI MOK config table + - certs: Add ability to preload revocation certs + - integrity: Load mokx variables into the blacklist keyring + - certs: add 'x509_revocation_list' to gitignore + - SAUCE: Dump stack when X.509 certificates cannot be loaded + - [Packaging] build canonical-revoked-certs.pem from branch/arch certs + - [Packaging] Revoke 2012 UEFI signing certificate as built-in + - [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys + * Support importing mokx keys into revocation list from the mok table + (LP: #1928679) + - efi: Support for MOK variable config table + - efi: mokvar-table: fix some issues in new code + - efi: mokvar: add missing include of asm/early_ioremap.h + - efi/mokvar: Reserve the table only if it is in boot services data + - SAUCE: integrity: add informational messages when revoking certs + * Support importing mokx keys into revocation list from the mok table + (LP: #1928679) // CVE-2020-26541 when certificates are revoked via + MokListXRT. + - SAUCE: integrity: Load mokx certs from the EFI MOK config table + * Focal update: v5.4.157 upstream stable release (LP: #1951883) + - ARM: 9133/1: mm: proc-macros: ensure *_tlb_fns are 4B aligned + - ARM: 9134/1: remove duplicate memcpy() definition + - ARM: 9139/1: kprobes: fix arch_init_kprobes() prototype + - ARM: 9141/1: only warn about XIP address when not compile testing + - ipv6: use siphash in rt6_exception_hash() + - ipv4: use siphash instead of Jenkins in fnhe_hashfun() + - usbnet: sanity check for maxpacket + - usbnet: fix error return code in usbnet_probe() + - Revert "pinctrl: bcm: ns: support updated DT binding as syscon subnode" + - ata: sata_mv: Fix the error handling of mv_chip_id() + - nfc: port100: fix using -ERRNO as command type mask + - net/tls: Fix flipped sign in tls_err_abort() calls + - mmc: vub300: fix control-message timeouts + - mmc: cqhci: clear HALT state after CQE enable + - mmc: dw_mmc: exynos: fix the finding clock sample value + - mmc: sdhci: Map more voltage level to SDHCI_POWER_330 + - mmc: sdhci-esdhc-imx: clear the buffer_read_ready to reset standard tuning + circuit + - cfg80211: scan: fix RCU in cfg80211_add_nontrans_list() + - net: lan78xx: fix division by zero in send path + - tcp_bpf: Fix one concurrency problem in the tcp_bpf_send_verdict function + - IB/qib: Protect from buffer overflow in struct qib_user_sdma_pkt fields + - IB/hfi1: Fix abba locking issue with sc_disable() + - nvmet-tcp: fix data digest pointer calculation + - nvme-tcp: fix data digest pointer calculation + - RDMA/mlx5: Set user priority for DCT + - arm64: dts: allwinner: h5: NanoPI Neo 2: Fix ethernet node + - regmap: Fix possible double-free in regcache_rbtree_exit() + - net: batman-adv: fix error handling + - net: Prevent infinite while loop in skb_tx_hash() + - RDMA/sa_query: Use strscpy_pad instead of memcpy to copy a string + - nios2: Make NIOS2_DTB_SOURCE_BOOL depend on !COMPILE_TEST + - net: ethernet: microchip: lan743x: Fix driver crash when lan743x_pm_resume + fails + - net: ethernet: microchip: lan743x: Fix dma allocation failure by using + dma_set_mask_and_coherent + - net: nxp: lpc_eth.c: avoid hang when bringing interface down + - net/tls: Fix flipped sign in async_wait.err assignment + - phy: phy_ethtool_ksettings_get: Lock the phy for consistency + - phy: phy_start_aneg: Add an unlocked version + - sctp: use init_tag from inithdr for ABORT chunk + - sctp: fix the processing for INIT_ACK chunk + - sctp: fix the processing for COOKIE_ECHO chunk + - sctp: add vtag check in sctp_sf_violation + - sctp: add vtag check in sctp_sf_do_8_5_1_E_sa + - sctp: add vtag check in sctp_sf_ootb + - net: use netif_is_bridge_port() to check for IFF_BRIDGE_PORT + - cfg80211: correct bridge/4addr mode check + - KVM: s390: clear kicked_mask before sleeping again + - KVM: s390: preserve deliverable_mask in __airqs_kick_single_vcpu + - perf script: Check session->header.env.arch before using it + - Linux 5.4.157 + * keyboard not working on Medion notebook s17 series (LP: #1950536) + - ACPI: resources: Add one more Medion model in IRQ override quirk + * creat09 from ubuntu_ltp_syscalls and cve-2018-13405 from ubuntu_ltp/cve + failed with XFS (LP: #1950239) + - xfs: ensure that the inode uid/gid match values match the icdinode ones + - xfs: merge the projid fields in struct xfs_icdinode + - xfs: remove the icdinode di_uid/di_gid members + - xfs: fix up non-directory creation in SGID directories + * reuseport_bpf_numa in net from ubuntu_kernel_selftests fails on ppc64le + (LP: #1867570) + - selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes + * Focal update: v5.4.156 upstream stable release (LP: #1951295) + - parisc: math-emu: Fix fall-through warnings + - net: switchdev: do not propagate bridge updates across bridges + - tee: optee: Fix missing devices unregister during optee_remove + - ARM: dts: at91: sama5d2_som1_ek: disable ISC node by default + - xtensa: xtfpga: use CONFIG_USE_OF instead of CONFIG_OF + - xtensa: xtfpga: Try software restart before simulating CPU reset + - NFSD: Keep existing listeners on portlist error + - dma-debug: fix sg checks in debug_dma_map_sg() + - ASoC: wm8960: Fix clock configuration on slave mode + - netfilter: ipvs: make global sysctl readonly in non-init netns + - lan78xx: select CRC32 + - net: dsa: lantiq_gswip: fix register definition + - NIOS2: irqflags: rename a redefined register name + - net: hns3: reset DWRR of unused tc to zero + - net: hns3: add limit ets dwrr bandwidth cannot be 0 + - net: hns3: disable sriov before unload hclge layer + - net: stmmac: Fix E2E delay mechanism + - net: enetc: fix ethtool counter name for PM0_TERR + - can: rcar_can: fix suspend/resume + - can: peak_usb: pcan_usb_fd_decode_status(): fix back to ERROR_ACTIVE state + notification + - can: peak_pci: peak_pci_remove(): fix UAF + - can: j1939: j1939_tp_rxtimer(): fix errant alert in j1939_tp_rxtimer + - can: j1939: j1939_netdev_start(): fix UAF for rx_kref of j1939_priv + - can: j1939: j1939_xtp_rx_dat_one(): cancel session if receive TP.DT with + error length + - can: j1939: j1939_xtp_rx_rts_session_new(): abort TP less than 9 bytes + - ceph: fix handling of "meta" errors + - ocfs2: fix data corruption after conversion from inline format + - ocfs2: mount fails with buffer overflow in strlen + - elfcore: correct reference to CONFIG_UML + - ALSA: usb-audio: Provide quirk for Sennheiser GSP670 Headset + - ALSA: hda/realtek: Add quirk for Clevo PC50HS + - ASoC: DAPM: Fix missing kctl change notifications + - audit: fix possible null-pointer dereference in audit_filter_rules + - powerpc64/idle: Fix SP offsets when saving GPRs + - KVM: PPC: Book3S HV: Fix stack handling in idle_kvm_start_guest() + - KVM: PPC: Book3S HV: Make idle_kvm_start_guest() return 0 if it went to + guest + - powerpc/idle: Don't corrupt back chain when going idle + - mm, slub: fix mismatch between reconstructed freelist depth and cnt + - mm, slub: fix potential memoryleak in kmem_cache_open() + - nfc: nci: fix the UAF of rf_conn_info object + - isdn: cpai: check ctr->cnr to avoid array index out of bound + - netfilter: Kconfig: use 'default y' instead of 'm' for bool config option + - selftests: netfilter: remove stray bash debug line + - gcc-plugins/structleak: add makefile var for disabling structleak + - btrfs: deal with errors when checking if a dir entry exists during log + replay + - net: stmmac: add support for dwmac 3.40a + - ARM: dts: spear3xx: Fix gmac node + - isdn: mISDN: Fix sleeping function called from invalid context + - platform/x86: intel_scu_ipc: Update timeout value in comment + - ALSA: hda: avoid write to STATESTS if controller is in reset + - Input: snvs_pwrkey - add clk handling + - scsi: core: Fix shost->cmd_per_lun calculation in scsi_add_host_with_dma() + - tracing: Have all levels of checks prevent recursion + - ARM: 9122/1: select HAVE_FUTEX_CMPXCHG + - pinctrl: stm32: use valid pin identifier in stm32_pinctrl_resume() + - Linux 5.4.156 + * ubuntu_ltp / finit_module02 fails on v4.15 and other kernels + (LP: #1950644) // Focal update: v5.4.156 upstream stable release + (LP: #1951295) + - vfs: check fd has read access in kernel_read_file_from_fd() + * Focal update: v5.4.155 upstream stable release (LP: #1951291) + - ovl: simplify file splice + - ALSA: usb-audio: Add quirk for VF0770 + - ALSA: seq: Fix a potential UAF by wrong private_free call order + - ALSA: hda/realtek: Complete partial device name to avoid ambiguity + - ALSA: hda/realtek: Add quirk for Clevo X170KM-G + - ALSA: hda/realtek - ALC236 headset MIC recording issue + - ALSA: hda/realtek: Fix the mic type detection issue for ASUS G551JW + - nds32/ftrace: Fix Error: invalid operands (*UND* and *UND* sections) for `^' + - s390: fix strrchr() implementation + - csky: don't let sigreturn play with priveleged bits of status register + - csky: Fixup regs.sr broken in ptrace + - btrfs: unlock newly allocated extent buffer after error + - btrfs: deal with errors when replaying dir entry during log replay + - btrfs: deal with errors when adding inode reference during log replay + - btrfs: check for error when looking up inode during dir entry replay + - watchdog: orion: use 0 for unset heartbeat + - x86/resctrl: Free the ctrlval arrays when domain_setup_mon_state() fails + - mei: me: add Ice Lake-N device id. + - xhci: guard accesses to ep_state in xhci_endpoint_reset() + - xhci: Fix command ring pointer corruption while aborting a command + - xhci: Enable trust tx length quirk for Fresco FL11 USB controller + - cb710: avoid NULL pointer subtraction + - efi/cper: use stack buffer for error record decoding + - efi: Change down_interruptible() in virt_efi_reset_system() to + down_trylock() + - usb: musb: dsps: Fix the probe error path + - Input: xpad - add support for another USB ID of Nacon GC-100 + - USB: serial: qcserial: add EM9191 QDL support + - USB: serial: option: add Quectel EC200S-CN module support + - USB: serial: option: add Telit LE910Cx composition 0x1204 + - USB: serial: option: add prod. id for Quectel EG91 + - EDAC/armada-xp: Fix output of uncorrectable error counter + - nvmem: Fix shift-out-of-bound (UBSAN) with byte size cells + - x86/Kconfig: Do not enable AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT automatically + - powerpc/xive: Discard disabled interrupts in get_irqchip_state() + - iio: adc: aspeed: set driver data when adc probe. + - iio: adc128s052: Fix the error handling path of 'adc128_probe()' + - iio: mtk-auxadc: fix case IIO_CHAN_INFO_PROCESSED + - iio: light: opt3001: Fixed timeout error when 0 lux + - iio: ssp_sensors: add more range checking in ssp_parse_dataframe() + - iio: ssp_sensors: fix error code in ssp_print_mcu_debug() + - iio: dac: ti-dac5571: fix an error code in probe() + - sctp: account stream padding length for reconf chunk + - gpio: pca953x: Improve bias setting + - net: arc: select CRC32 + - net: korina: select CRC32 + - net/mlx5e: Mutually exclude RX-FCS and RX-port-timestamp + - net: stmmac: fix get_hw_feature() on old hardware + - net: encx24j600: check error in devm_regmap_init_encx24j600 + - ethernet: s2io: fix setting mac address during resume + - nfc: fix error handling of nfc_proto_register() + - NFC: digital: fix possible memory leak in digital_tg_listen_mdaa() + - NFC: digital: fix possible memory leak in digital_in_send_sdd_req() + - pata_legacy: fix a couple uninitialized variable bugs + - ata: ahci_platform: fix null-ptr-deref in ahci_platform_enable_regulators() + - mlxsw: thermal: Fix out-of-bounds memory accesses + - platform/mellanox: mlxreg-io: Fix argument base in kstrtou32() call + - drm/panel: olimex-lcd-olinuxino: select CRC32 + - drm/msm: Fix null pointer dereference on pointer edp + - drm/msm/dsi: Fix an error code in msm_dsi_modeset_init() + - drm/msm/dsi: fix off by one in dsi_bus_clk_enable error handling + - acpi/arm64: fix next_platform_timer() section mismatch error + - mqprio: Correct stats in mqprio_dump_class_stats(). + - qed: Fix missing error code in qed_slowpath_start() + - r8152: select CRC32 and CRYPTO/CRYPTO_HASH/CRYPTO_SHA256 + - ionic: don't remove netdev->dev_addr when syncing uc list + - Linux 5.4.155 + * [UBUNTU 20.04] kernel: unable to read partitions on virtio-block dasd (kvm) + (LP: #1950144) // Focal update: v5.4.155 upstream stable release + (LP: #1951291) + - virtio: write back F_VERSION_1 before validate + * Focal update: v5.4.154 upstream stable release (LP: #1951288) + - net: phy: bcm7xxx: Fixed indirect MMD operations + - ext4: correct the error path of ext4_write_inline_data_end() + - HID: apple: Fix logical maximum and usage maximum of Magic Keyboard JIS + - netfilter: ip6_tables: zero-initialize fragment offset + - HID: wacom: Add new Intuos BT (CTL-4100WL/CTL-6100WL) device IDs + - netfilter: nf_nat_masquerade: make async masq_inet6_event handling generic + - netfilter: nf_nat_masquerade: defer conntrack walk to work queue + - mac80211: Drop frames from invalid MAC address in ad-hoc mode + - m68k: Handle arrivals of multiple signals correctly + - net: prevent user from passing illegal stab size + - mac80211: check return value of rhashtable_init + - net: sun: SUNVNET_COMMON should depend on INET + - drm/amdgpu: fix gart.bo pin_count leak + - scsi: ses: Fix unsigned comparison with less than zero + - scsi: virtio_scsi: Fix spelling mistake "Unsupport" -> "Unsupported" + - sched: Always inline is_percpu_thread() + - Linux 5.4.154 + * Focal update: v5.4.153 upstream stable release (LP: #1950014) + - Partially revert "usb: Kconfig: using select for USB_COMMON dependency" + - USB: cdc-acm: fix racy tty buffer accesses + - USB: cdc-acm: fix break reporting + - usb: typec: tcpm: handle SRC_STARTUP state if cc changes + - xen/privcmd: fix error handling in mmap-resource processing + - mmc: meson-gx: do not use memcpy_to/fromio for dram-access-quirk + - ovl: fix missing negative dentry check in ovl_rename() + - nfsd: fix error handling of register_pernet_subsys() in init_nfsd() + - nfsd4: Handle the NFSv4 READDIR 'dircount' hint being zero + - xen/balloon: fix cancelled balloon action + - ARM: dts: omap3430-sdp: Fix NAND device node + - ARM: dts: qcom: apq8064: use compatible which contains chipid + - MIPS: BPF: Restore MIPS32 cBPF JIT + - bpf, mips: Validate conditional branch offsets + - soc: qcom: socinfo: Fixed argument passed to platform_set_data() + - ARM: dts: qcom: apq8064: Use 27MHz PXO clock as DSI PLL reference + - soc: qcom: mdt_loader: Drop PT_LOAD check on hash segment + - ARM: dts: imx: Add missing pinctrl-names for panel on M53Menlo + - ARM: dts: imx: Fix USB host power regulator polarity on M53Menlo + - arm64: dts: qcom: pm8150: use qcom,pm8998-pon binding + - xtensa: move XCHAL_KIO_* definitions to kmem_layout.h + - xtensa: use CONFIG_USE_OF instead of CONFIG_OF + - xtensa: call irqchip_init only when CONFIG_USE_OF is selected + - bpf, arm: Fix register clobbering in div/mod implementation + - bpf: Fix integer overflow in prealloc_elems_and_freelist() + - phy: mdio: fix memory leak + - net_sched: fix NULL deref in fifo_set_limit() + - powerpc/fsl/dts: Fix phy-connection-type for fm1mac3 + - ptp_pch: Load module automatically if ID matches + - arm64: dts: freescale: Fix SP805 clock-names + - arm64: dts: ls1028a: add missing CAN nodes + - ARM: imx6: disable the GIC CPU interface before calling stby-poweroff + sequence + - net: bridge: use nla_total_size_64bit() in br_get_linkxstats_size() + - net/sched: sch_taprio: properly cancel timer from taprio_destroy() + - net: sfp: Fix typo in state machine debug string + - netlink: annotate data races around nlk->bound + - bus: ti-sysc: Use CLKDM_NOAUTO for dra7 dcan1 for errata i893 + - video: fbdev: gbefb: Only instantiate device when built for IP32 + - drm/nouveau/debugfs: fix file release memory leak + - gve: Correct available tx qpl check + - rtnetlink: fix if_nlmsg_stats_size() under estimation + - gve: fix gve_get_stats() + - i40e: fix endless loop under rtnl + - i40e: Fix freeing of uninitialized misc IRQ vector + - net: prefer socket bound to interface when not in VRF + - i2c: acpi: fix resource leak in reconfiguration device addition + - bpf, s390: Fix potential memory leak about jit_data + - RISC-V: Include clone3() on rv32 + - x86/platform/olpc: Correct ifdef symbol to intended CONFIG_OLPC_XO15_SCI + - x86/hpet: Use another crystalball to evaluate HPET usability + - x86/Kconfig: Correct reference to MWINCHIP3D + - Linux 5.4.153 + * Focal update: v5.4.152 upstream stable release (LP: #1950009) + - net: mdio: introduce a shutdown method to mdio device drivers + - xen-netback: correct success/error reporting for the SKB-with-fraglist case + - sparc64: fix pci_iounmap() when CONFIG_PCI is not set + - ext2: fix sleeping in atomic bugs on error + - scsi: sd: Free scsi_disk device via put_device() + - usb: testusb: Fix for showing the connection speed + - usb: dwc2: check return value after calling platform_get_resource() + - selftests: be sure to make khdr before other targets + - selftests:kvm: fix get_warnings_count() ignoring fscanf() return warn + - scsi: ses: Retry failed Send/Receive Diagnostic commands + - tools/vm/page-types: remove dependency on opt_file for idle page tracking + - KVM: do not shrink halt_poll_ns below grow_start + - kvm: x86: Add AMD PMU MSRs to msrs_to_save_all[] + - perf/x86: Reset destroy callback on event init failure + - silence nfscache allocation warnings with kvzalloc + - libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD. + - Linux 5.4.152 + * linux-aws: Fix backport of RDMA/efa: Expose maximum TX doorbell batch + (LP: #1949882) + - SAUCE: aws: Fix backport of RDMA/efa: Expose maximum TX doorbell batch + + -- Tim Gardner Wed, 01 Dec 2021 07:22:40 -0700 + +linux-oracle (5.4.0-1058.62) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1058.62 -proposed tracker (LP: #1949831) + + [ Ubuntu: 5.4.0-91.102 ] + + * focal/linux: 5.4.0-91.102 -proposed tracker (LP: #1949840) + * Packaging resync (LP: #1786013) + - [Packaging] update Ubuntu.md + - debian/dkms-versions -- update from kernel-versions (main/2021.11.08) + * KVM emulation failure when booting into VM crash kernel with multiple CPUs + (LP: #1948862) + - KVM: x86: Properly reset MMU context at vCPU RESET/INIT + * aufs: kernel bug with apparmor and fuseblk (LP: #1948470) + - SAUCE: aufs: bugfix, stop omitting path->mnt + * ebpf: bpf_redirect fails with ip6 gre interfaces (LP: #1947164) + - net: handle ARPHRD_IP6GRE in dev_is_mac_header_xmit() + * require CAP_NET_ADMIN to attach N_HCI ldisc (LP: #1949516) + - Bluetooth: hci_ldisc: require CAP_NET_ADMIN to attach N_HCI ldisc + * ACL updates on OCFS2 are not revalidated (LP: #1947161) + - ocfs2: fix remounting needed after setfacl command + * ppc64 BPF JIT mod by 1 will not return 0 (LP: #1948351) + - powerpc/bpf: Fix BPF_MOD when imm == 1 + * Drop "UBUNTU: SAUCE: cachefiles: Page leaking in + cachefiles_read_backing_file while vmscan is active" (LP: #1947709) + - Revert "UBUNTU: SAUCE: cachefiles: Page leaking in + cachefiles_read_backing_file while vmscan is active" + * Reassign I/O Path of ConnectX-5 Port 1 before Port 2 causes NULL dereference + (LP: #1943464) + - s390/pci: fix leak of PCI device structure + - s390/pci: fix use after free of zpci_dev + - s390/pci: fix zpci_zdev_put() on reserve + * [SRU][F] USB: serial: pl2303: add support for PL2303HXN (LP: #1948377) + - USB: serial: pl2303: add support for PL2303HXN + - USB: serial: pl2303: fix line-speed handling on newer chips + * Focal update: v5.4.151 upstream stable release (LP: #1947888) + - tty: Fix out-of-bound vmalloc access in imageblit + - cpufreq: schedutil: Use kobject release() method to free sugov_tunables + - cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory + - usb: cdns3: fix race condition before setting doorbell + - fs-verity: fix signed integer overflow with i_size near S64_MAX + - hwmon: (w83793) Fix NULL pointer dereference by removing unnecessary + structure field + - hwmon: (w83792d) Fix NULL pointer dereference by removing unnecessary + structure field + - hwmon: (w83791d) Fix NULL pointer dereference by removing unnecessary + structure field + - scsi: ufs: Fix illegal offset in UPIU event trace + - mac80211: fix use-after-free in CCMP/GCMP RX + - x86/kvmclock: Move this_cpu_pvti into kvmclock.h + - drm/amd/display: Pass PCI deviceid into DC + - ipvs: check that ip_vs_conn_tab_bits is between 8 and 20 + - hwmon: (mlxreg-fan) Return non-zero value when fan current state is enforced + from sysfs + - mac80211: Fix ieee80211_amsdu_aggregate frag_tail bug + - mac80211: limit injected vht mcs/nss in ieee80211_parse_tx_radiotap + - mac80211: mesh: fix potentially unaligned access + - mac80211-hwsim: fix late beacon hrtimer handling + - sctp: break out if skb_header_pointer returns NULL in sctp_rcv_ootb + - hwmon: (tmp421) report /PVLD condition as fault + - hwmon: (tmp421) fix rounding for negative values + - net: ipv4: Fix rtnexthop len when RTA_FLOW is present + - e100: fix length calculation in e100_get_regs_len + - e100: fix buffer overrun in e100_get_regs + - selftests, bpf: test_lwt_ip_encap: Really disable rp_filter + - scsi: csiostor: Add module softdep on cxgb4 + - net: hns3: do not allow call hns3_nic_net_open repeatedly + - net: sched: flower: protect fl_walk() with rcu + - af_unix: fix races in sk_peer_pid and sk_peer_cred accesses + - perf/x86/intel: Update event constraints for ICX + - elf: don't use MAP_FIXED_NOREPLACE for elf interpreter mappings + - debugfs: debugfs_create_file_size(): use IS_ERR to check for error + - ipack: ipoctal: fix stack information leak + - ipack: ipoctal: fix tty registration race + - ipack: ipoctal: fix tty-registration error handling + - ipack: ipoctal: fix missing allocation-failure check + - ipack: ipoctal: fix module reference leak + - ext4: fix loff_t overflow in ext4_max_bitmap_size() + - ext4: fix reserved space counter leakage + - ext4: fix potential infinite loop in ext4_dx_readdir() + - HID: u2fzero: ignore incomplete packets without data + - net: udp: annotate data race around udp_sk(sk)->corkflag + - net: stmmac: don't attach interface until resume finishes + - PCI: Fix pci_host_bridge struct device release/free handling + - libnvdimm/pmem: Fix crash triggered when I/O in-flight during unbind + - hso: fix bailout in error case of probe + - usb: hso: fix error handling code of hso_create_net_device + - usb: hso: remove the bailout parameter + - crypto: ccp - fix resource leaks in ccp_run_aes_gcm_cmd() + - HID: betop: fix slab-out-of-bounds Write in betop_probe + - netfilter: ipset: Fix oversized kvmalloc() calls + - HID: usbhid: free raw_report buffers in usbhid_stop + - Linux 5.4.151 + * Focal update: v5.4.150 upstream stable release (LP: #1947886) + - usb: gadget: r8a66597: fix a loop in set_feature() + - usb: dwc2: gadget: Fix ISOC flow for BDMA and Slave + - usb: dwc2: gadget: Fix ISOC transfer complete handling for DDMA + - usb: musb: tusb6010: uninitialized data in tusb_fifo_write_unaligned() + - cifs: fix incorrect check for null pointer in header_assemble + - xen/x86: fix PV trap handling on secondary processors + - usb-storage: Add quirk for ScanLogic SL11R-IDE older than 2.6c + - USB: serial: cp210x: add ID for GW Instek GDM-834x Digital Multimeter + - USB: cdc-acm: fix minor-number release + - binder: make sure fd closes complete + - staging: greybus: uart: fix tty use after free + - Re-enable UAS for LaCie Rugged USB3-FW with fk quirk + - USB: serial: mos7840: remove duplicated 0xac24 device ID + - USB: serial: option: add Telit LN920 compositions + - USB: serial: option: remove duplicate USB device ID + - USB: serial: option: add device id for Foxconn T99W265 + - mcb: fix error handling in mcb_alloc_bus() + - erofs: fix up erofs_lookup tracepoint + - btrfs: prevent __btrfs_dump_space_info() to underflow its free space + - serial: mvebu-uart: fix driver's tx_empty callback + - net: hso: fix muxed tty registration + - afs: Fix incorrect triggering of sillyrename on 3rd-party invalidation + - platform/x86/intel: punit_ipc: Drop wrong use of ACPI_PTR() + - enetc: Fix illegal access when reading affinity_hint + - bnxt_en: Fix TX timeout when TX ring size is set to the smallest + - net/smc: add missing error check in smc_clc_prfx_set() + - gpio: uniphier: Fix void functions to remove return value + - qed: rdma - don't wait for resources under hw error recovery flow + - net/mlx4_en: Don't allow aRFS for encapsulated packets + - scsi: iscsi: Adjust iface sysfs attr detection + - tty: synclink_gt, drop unneeded forward declarations + - tty: synclink_gt: rename a conflicting function name + - fpga: machxo2-spi: Return an error on failure + - fpga: machxo2-spi: Fix missing error code in machxo2_write_complete() + - thermal/core: Potential buffer overflow in thermal_build_list_of_policies() + - cifs: fix a sign extension bug + - scsi: qla2xxx: Restore initiator in dual mode + - scsi: lpfc: Use correct scnprintf() limit + - irqchip/goldfish-pic: Select GENERIC_IRQ_CHIP to fix build + - irqchip/gic-v3-its: Fix potential VPE leak on error + - md: fix a lock order reversal in md_alloc + - blktrace: Fix uaf in blk_trace access after removing by sysfs + - net: macb: fix use after free on rmmod + - net: stmmac: allow CSR clock of 300MHz + - m68k: Double cast io functions to unsigned long + - ipv6: delay fib6_sernum increase in fib6_add + - bpf: Add oversize check before call kvcalloc() + - xen/balloon: use a kernel thread instead a workqueue + - nvme-multipath: fix ANA state updates when a namespace is not present + - sparc32: page align size in arch_dma_alloc + - blk-cgroup: fix UAF by grabbing blkcg lock before destroying blkg pd + - compiler.h: Introduce absolute_pointer macro + - net: i825xx: Use absolute_pointer for memcpy from fixed memory location + - sparc: avoid stringop-overread errors + - qnx4: avoid stringop-overread errors + - parisc: Use absolute_pointer() to define PAGE0 + - arm64: Mark __stack_chk_guard as __ro_after_init + - alpha: Declare virt_to_phys and virt_to_bus parameter as pointer to volatile + - net: 6pack: Fix tx timeout and slot time + - spi: Fix tegra20 build with CONFIG_PM=n + - EDAC/synopsys: Fix wrong value type assignment for edac_mode + - thermal/drivers/int340x: Do not set a wrong tcc offset on resume + - arm64: dts: marvell: armada-37xx: Extend PCIe MEM space + - xen/balloon: fix balloon kthread freezing + - qnx4: work around gcc false positive warning bug + - Linux 5.4.150 + * ACL updates on OCFS2 are not revalidated (LP: #1947161) // Focal update: + v5.4.150 upstream stable release (LP: #1947886) + - ocfs2: drop acl cache for directories too + * Focal update: v5.4.149 upstream stable release (LP: #1947885) + - PCI: pci-bridge-emul: Fix big-endian support + - PCI: aardvark: Indicate error in 'val' when config read fails + - PCI: pci-bridge-emul: Add PCIe Root Capabilities Register + - PCI: aardvark: Fix reporting CRS value + - PCI/ACPI: Add Ampere Altra SOC MCFG quirk + - KVM: remember position in kvm->vcpus array + - console: consume APC, DM, DCS + - s390/pci_mmio: fully validate the VMA before calling follow_pte() + - ARM: Qualify enabling of swiotlb_init() + - apparmor: remove duplicate macro list_entry_is_head() + - ARM: 9077/1: PLT: Move struct plt_entries definition to header + - ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link() + - ARM: 9079/1: ftrace: Add MODULE_PLTS support + - ARM: 9098/1: ftrace: MODULE_PLT: Fix build problem without DYNAMIC_FTRACE + - sctp: validate chunk size in __rcv_asconf_lookup + - sctp: add param size validation for SCTP_PARAM_SET_PRIMARY + - staging: rtl8192u: Fix bitwise vs logical operator in + TranslateRxSignalStuff819xUsb() + - um: virtio_uml: fix memory leak on init failures + - dmaengine: acpi: Avoid comparison GSI with Linux vIRQ + - thermal/drivers/exynos: Fix an error code in exynos_tmu_probe() + - 9p/trans_virtio: Remove sysfs file on probe failure + - prctl: allow to setup brk for et_dyn executables + - nilfs2: use refcount_dec_and_lock() to fix potential UAF + - profiling: fix shift-out-of-bounds bugs + - pwm: lpc32xx: Don't modify HW state in .probe() after the PWM chip was + registered + - phy: avoid unnecessary link-up delay in polling mode + - net: stmmac: reset Tx desc base address before restarting Tx + - Kconfig.debug: drop selecting non-existing HARDLOCKUP_DETECTOR_ARCH + - thermal/core: Fix thermal_cooling_device_register() prototype + - drivers: base: cacheinfo: Get rid of DEFINE_SMP_CALL_CACHE_FUNCTION() + - parisc: Move pci_dev_is_behind_card_dino to where it is used + - dmaengine: sprd: Add missing MODULE_DEVICE_TABLE + - dmaengine: ioat: depends on !UML + - dmaengine: xilinx_dma: Set DMA mask for coherent APIs + - ceph: request Fw caps before updating the mtime in ceph_write_iter + - ceph: lockdep annotations for try_nonblocking_invalidate + - btrfs: fix lockdep warning while mounting sprout fs + - nilfs2: fix memory leak in nilfs_sysfs_create_device_group + - nilfs2: fix NULL pointer in nilfs_##name##_attr_release + - nilfs2: fix memory leak in nilfs_sysfs_create_##name##_group + - nilfs2: fix memory leak in nilfs_sysfs_delete_##name##_group + - nilfs2: fix memory leak in nilfs_sysfs_create_snapshot_group + - nilfs2: fix memory leak in nilfs_sysfs_delete_snapshot_group + - pwm: img: Don't modify HW state in .remove() callback + - pwm: rockchip: Don't modify HW state in .remove() callback + - pwm: stm32-lp: Don't modify HW state in .remove() callback + - blk-throttle: fix UAF by deleteing timer in blk_throtl_exit() + - rtc: rx8010: select REGMAP_I2C + - drm/nouveau/nvkm: Replace -ENOSYS with -ENODEV + - Linux 5.4.149 + + -- Tim Gardner Tue, 09 Nov 2021 09:39:20 -0700 + +linux-oracle (5.4.0-1057.61) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1057.61 -proposed tracker (LP: #1947250) + + * Packaging resync (LP: #1786013) + - [Packaging] update Ubuntu.md + + [ Ubuntu: 5.4.0-90.101 ] + + * focal/linux: 5.4.0-90.101 -proposed tracker (LP: #1947260) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.10.18) + * Add final-checks to check certificates (LP: #1947174) + - [Packaging] Add system trusted and revocation keys final check + * No sound on Lenovo laptop models Legion 15IMHG05, Yoga 7 14ITL5, and 13s + Gen2 (LP: #1939052) + - ALSA: hda/realtek: Quirks to enable speaker output for Lenovo Legion 7i + 15IMHG05, Yoga 7i 14ITL5/15ITL5, and 13s Gen2 laptops. + - ALSA: hda/realtek: Fix for quirk to enable speaker output on the Lenovo 13s + Gen2 + * CVE-2020-36385 + - RDMA/cma: Add missing locking to rdma_accept() + - RDMA/ucma: Fix the locking of ctx->file + - RDMA/ucma: Rework ucma_migrate_id() to avoid races with destroy + * Focal update: v5.4.148 upstream stable release (LP: #1946802) + - rtc: tps65910: Correct driver module alias + - btrfs: wake up async_delalloc_pages waiters after submit + - btrfs: reset replace target device to allocation state on close + - blk-zoned: allow zone management send operations without CAP_SYS_ADMIN + - blk-zoned: allow BLKREPORTZONE without CAP_SYS_ADMIN + - PCI/MSI: Skip masking MSI-X on Xen PV + - powerpc/perf/hv-gpci: Fix counter value parsing + - xen: fix setting of max_pfn in shared_info + - include/linux/list.h: add a macro to test if entry is pointing to the head + - 9p/xen: Fix end of loop tests for list_for_each_entry + - tools/thermal/tmon: Add cross compiling support + - pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast + - pinctrl: ingenic: Fix incorrect pull up/down info + - soc: qcom: aoss: Fix the out of bound usage of cooling_devs + - soc: aspeed: lpc-ctrl: Fix boundary check for mmap + - soc: aspeed: p2a-ctrl: Fix boundary check for mmap + - arm64: head: avoid over-mapping in map_memory + - crypto: public_key: fix overflow during implicit conversion + - block: bfq: fix bfq_set_next_ioprio_data() + - power: supply: max17042: handle fails of reading status register + - dm crypt: Avoid percpu_counter spinlock contention in crypt_page_alloc() + - VMCI: fix NULL pointer dereference when unmapping queue pair + - media: uvc: don't do DMA on stack + - media: rc-loopback: return number of emitters rather than error + - Revert "dmaengine: imx-sdma: refine to load context only once" + - dmaengine: imx-sdma: remove duplicated sdma_load_context + - libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs + - ARM: 9105/1: atags_to_fdt: don't warn about stack size + - PCI/portdrv: Enable Bandwidth Notification only if port supports it + - PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported + - PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure + - PCI: xilinx-nwl: Enable the clock through CCF + - PCI: aardvark: Fix checking for PIO status + - PCI: aardvark: Increase polling delay to 1.5s while waiting for PIO response + - PCI: aardvark: Fix masking and unmasking legacy INTx interrupts + - HID: input: do not report stylus battery state as "full" + - f2fs: quota: fix potential deadlock + - scsi: bsg: Remove support for SCSI_IOCTL_SEND_COMMAND + - IB/hfi1: Adjust pkey entry in index 0 + - RDMA/iwcm: Release resources if iw_cm module initialization fails + - docs: Fix infiniband uverbs minor number + - pinctrl: samsung: Fix pinctrl bank pin count + - vfio: Use config not menuconfig for VFIO_NOIOMMU + - powerpc/stacktrace: Include linux/delay.h + - RDMA/efa: Remove double QP type assignment + - f2fs: show f2fs instance in printk_ratelimited + - f2fs: reduce the scope of setting fsck tag when de->name_len is zero + - openrisc: don't printk() unconditionally + - dma-debug: fix debugfs initialization order + - SUNRPC: Fix potential memory corruption + - scsi: fdomain: Fix error return code in fdomain_probe() + - pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry() + - scsi: smartpqi: Fix an error code in pqi_get_raid_map() + - scsi: qedi: Fix error codes in qedi_alloc_global_queues() + - scsi: qedf: Fix error codes in qedf_alloc_global_queues() + - powerpc/config: Renable MTD_PHYSMAP_OF + - scsi: target: avoid per-loop XCOPY buffer allocations + - HID: i2c-hid: Fix Elan touchpad regression + - KVM: PPC: Book3S HV Nested: Reflect guest PMU in-use to L0 when guest SPRs + are live + - platform/x86: dell-smbios-wmi: Add missing kfree in error-exit from + run_smbios_call + - fscache: Fix cookie key hashing + - clk: at91: sam9x60: Don't use audio PLL + - clk: at91: clk-generated: pass the id of changeable parent at registration + - clk: at91: clk-generated: Limit the requested rate to our range + - KVM: PPC: Fix clearing never mapped TCEs in realmode + - f2fs: fix to account missing .skipped_gc_rwsem + - f2fs: fix unexpected ENOENT comes from f2fs_map_blocks() + - f2fs: fix to unmap pages from userspace process in punch_hole() + - MIPS: Malta: fix alignment of the devicetree buffer + - kbuild: Fix 'no symbols' warning when CONFIG_TRIM_UNUSD_KSYMS=y + - userfaultfd: prevent concurrent API initialization + - drm/amdgpu: Fix amdgpu_ras_eeprom_init() + - ASoC: atmel: ATMEL drivers don't need HAS_DMA + - media: dib8000: rewrite the init prbs logic + - crypto: mxs-dcp - Use sg_mapping_iter to copy data + - PCI: Use pci_update_current_state() in pci_enable_device_flags() + - tipc: keep the skb in rcv queue until the whole data is read + - iio: dac: ad5624r: Fix incorrect handling of an optional regulator. + - iavf: do not override the adapter state in the watchdog task + - iavf: fix locking of critical sections + - ARM: dts: qcom: apq8064: correct clock names + - video: fbdev: kyro: fix a DoS bug by restricting user input + - netlink: Deal with ESRCH error in nlmsg_notify() + - Smack: Fix wrong semantics in smk_access_entry() + - drm: avoid blocking in drm_clients_info's rcu section + - igc: Check if num of q_vectors is smaller than max before array access + - usb: host: fotg210: fix the endpoint's transactional opportunities + calculation + - usb: host: fotg210: fix the actual_length of an iso packet + - usb: gadget: u_ether: fix a potential null pointer dereference + - USB: EHCI: ehci-mv: improve error handling in mv_ehci_enable() + - usb: gadget: composite: Allow bMaxPower=0 if self-powered + - staging: board: Fix uninitialized spinlock when attaching genpd + - tty: serial: jsm: hold port lock when reporting modem line changes + - drm/amd/display: Fix timer_per_pixel unit error + - drm/amd/amdgpu: Update debugfs link_settings output link_rate field in hex + - bpf/tests: Fix copy-and-paste error in double word test + - bpf/tests: Do not PASS tests without actually testing the result + - video: fbdev: asiliantfb: Error out if 'pixclock' equals zero + - video: fbdev: kyro: Error out if 'pixclock' equals zero + - video: fbdev: riva: Error out if 'pixclock' equals zero + - ipv4: ip_output.c: Fix out-of-bounds warning in ip_copy_addrs() + - flow_dissector: Fix out-of-bounds warnings + - s390/jump_label: print real address in a case of a jump label bug + - s390: make PCI mio support a machine flag + - serial: 8250: Define RX trigger levels for OxSemi 950 devices + - xtensa: ISS: don't panic in rs_init + - hvsi: don't panic on tty_register_driver failure + - serial: 8250_pci: make setup_port() parameters explicitly unsigned + - staging: ks7010: Fix the initialization of the 'sleep_status' structure + - samples: bpf: Fix tracex7 error raised on the missing argument + - ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init() + - Bluetooth: skip invalid hci_sync_conn_complete_evt + - workqueue: Fix possible memory leaks in wq_numa_init() + - bonding: 3ad: fix the concurrency between __bond_release_one() and + bond_3ad_state_machine_handler() + - arm64: tegra: Fix Tegra194 PCIe EP compatible string + - ASoC: Intel: bytcr_rt5640: Move "Platform Clock" routes to the maps for the + matching in-/output + - media: imx258: Rectify mismatch of VTS value + - media: imx258: Limit the max analogue gain to 480 + - media: v4l2-dv-timings.c: fix wrong condition in two for-loops + - media: TDA1997x: fix tda1997x_query_dv_timings() return value + - media: tegra-cec: Handle errors of clk_prepare_enable() + - ARM: dts: imx53-ppd: Fix ACHC entry + - arm64: dts: qcom: sdm660: use reg value for memory node + - net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe() + - drm/msm: mdp4: drop vblank get/put from prepare/complete_commit + - selftests/bpf: Fix xdp_tx.c prog section name + - Bluetooth: schedule SCO timeouts with delayed_work + - Bluetooth: avoid circular locks in sco_sock_connect + - net/mlx5: Fix variable type to match 64bit + - gpu: drm: amd: amdgpu: amdgpu_i2c: fix possible uninitialized-variable + access in amdgpu_i2c_router_select_ddc_port() + - drm/display: fix possible null-pointer dereference in dcn10_set_clock() + - mac80211: Fix monitor MTU limit so that A-MSDUs get through + - ARM: tegra: tamonten: Fix UART pad setting + - arm64: tegra: Fix compatible string for Tegra132 CPUs + - arm64: dts: ls1046a: fix eeprom entries + - nvme-tcp: don't check blk_mq_tag_to_rq when receiving pdu data + - Bluetooth: Fix handling of LE Enhanced Connection Complete + - opp: Don't print an error if required-opps is missing + - serial: sh-sci: fix break handling for sysrq + - tcp: enable data-less, empty-cookie SYN with TFO_SERVER_COOKIE_NOT_REQD + - rpc: fix gss_svc_init cleanup on failure + - staging: rts5208: Fix get_ms_information() heap buffer size + - gfs2: Don't call dlm after protocol is unmounted + - usb: chipidea: host: fix port index underflow and UBSAN complains + - lockd: lockd server-side shouldn't set fl_ops + - drm/exynos: Always initialize mapping in exynos_drm_register_dma() + - m68knommu: only set CONFIG_ISA_DMA_API for ColdFire sub-arch + - btrfs: tree-log: check btrfs_lookup_data_extent return value + - ASoC: Intel: Skylake: Fix module configuration for KPB and MIXER + - ASoC: Intel: Skylake: Fix passing loadable flag for module + - of: Don't allow __of_attached_node_sysfs() without CONFIG_SYSFS + - mmc: sdhci-of-arasan: Check return value of non-void funtions + - mmc: rtsx_pci: Fix long reads when clock is prescaled + - selftests/bpf: Enlarge select() timeout for test_maps + - mmc: core: Return correct emmc response in case of ioctl error + - cifs: fix wrong release in sess_alloc_buffer() failed path + - Revert "USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST + quirk set" + - usb: musb: musb_dsps: request_irq() after initializing musb + - usbip: give back URBs for unsent unlink requests during cleanup + - usbip:vhci_hcd USB port can get stuck in the disabled state + - ASoC: rockchip: i2s: Fix regmap_ops hang + - ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B + - drm/amdkfd: Account for SH/SE count when setting up cu masks. + - iwlwifi: mvm: fix a memory leak in iwl_mvm_mac_ctxt_beacon_changed + - iwlwifi: mvm: avoid static queue number aliasing + - iwlwifi: mvm: fix access to BSS elements + - net/mlx5: DR, Enable QP retransmission + - parport: remove non-zero check on count + - ath9k: fix OOB read ar9300_eeprom_restore_internal + - ath9k: fix sleeping in atomic context + - net: fix NULL pointer reference in cipso_v4_doi_free + - fix array-index-out-of-bounds in taprio_change + - net: w5100: check return value after calling platform_get_resource() + - parisc: fix crash with signals and alloca + - ovl: fix BUG_ON() in may_delete() when called from ovl_cleanup() + - scsi: BusLogic: Fix missing pr_cont() use + - scsi: qla2xxx: Changes to support kdump kernel + - scsi: qla2xxx: Sync queue idx with queue_pair_map idx + - cpufreq: powernv: Fix init_chip_info initialization in numa=off + - s390/pv: fix the forcing of the swiotlb + - mm/hugetlb: initialize hugetlb_usage in mm_init + - mm,vmscan: fix divide by zero in get_scan_count + - memcg: enable accounting for pids in nested pid namespaces + - platform/chrome: cros_ec_proto: Send command again when timeout occurs + - lib/test_stackinit: Fix static initializer test + - net: dsa: lantiq_gswip: fix maximum frame length + - drm/msi/mdp4: populate priv->kms in mdp4_kms_init + - drm/amdgpu: Fix BUG_ON assert + - drm/panfrost: Simplify lock_region calculation + - drm/panfrost: Use u64 for size in lock_region + - drm/panfrost: Clamp lock region to Bifrost minimum + - btrfs: fix upper limit for max_inline for page size 64K + - xen: reset legacy rtc flag for PV domU + - bnx2x: Fix enabling network interfaces without VFs + - arm64/sve: Use correct size when reinitialising SVE state + - PM: base: power: don't try to use non-existing RTC for storing data + - PCI: Add AMD GPU multi-function power dependencies + - drm/amd/amdgpu: Increase HWIP_MAX_INSTANCE to 10 + - drm/etnaviv: return context from etnaviv_iommu_context_get + - drm/etnaviv: put submit prev MMU context when it exists + - drm/etnaviv: stop abusing mmu_context as FE running marker + - drm/etnaviv: keep MMU context across runtime suspend/resume + - drm/etnaviv: exec and MMU state is lost when resetting the GPU + - drm/etnaviv: fix MMU context leak on GPU reset + - drm/etnaviv: reference MMU context when setting up hardware state + - drm/etnaviv: add missing MMU context put when reaping MMU mapping + - s390/sclp: fix Secure-IPL facility detection + - x86/mm: Fix kern_addr_valid() to cope with existing but not present entries + - tipc: fix an use-after-free issue in tipc_recvmsg + - net-caif: avoid user-triggerable WARN_ON(1) + - ptp: dp83640: don't define PAGE0 + - net/l2tp: Fix reference count leak in l2tp_udp_recv_core + - r6040: Restore MDIO clock frequency after MAC reset + - tipc: increase timeout in tipc_sk_enqueue() + - perf machine: Initialize srcline string member in add_location struct + - net/mlx5: FWTrace, cancel work on alloc pd error flow + - net/mlx5: Fix potential sleeping in atomic context + - events: Reuse value read using READ_ONCE instead of re-reading it + - vhost_net: fix OoB on sendmsg() failure. + - net/af_unix: fix a data-race in unix_dgram_poll + - net: dsa: destroy the phylink instance on any error in dsa_slave_phy_setup + - tcp: fix tp->undo_retrans accounting in tcp_sacktag_one() + - qed: Handle management FW error + - dt-bindings: arm: Fix Toradex compatible typo + - ibmvnic: check failover_pending in login response + - KVM: PPC: Book3S HV: Tolerate treclaim. in fake-suspend mode changing + registers + - net: hns3: pad the short tunnel frame before sending to hardware + - net: hns3: change affinity_mask to numa node range + - net: hns3: disable mac in flr process + - net: hns3: fix the timing issue of VF clearing interrupt sources + - mm/memory_hotplug: use "unsigned long" for PFN in zone_for_pfn_range() + - dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation + - mfd: db8500-prcmu: Adjust map to reality + - PCI: Add ACS quirks for NXP LX2xx0 and LX2xx2 platforms + - fuse: fix use after free in fuse_read_interrupt() + - mfd: Don't use irq_create_mapping() to resolve a mapping + - tracing/probes: Reject events which have the same name of existing one + - PCI: Add ACS quirks for Cavium multi-function devices + - Set fc_nlinfo in nh_create_ipv4, nh_create_ipv6 + - net: usb: cdc_mbim: avoid altsetting toggling for Telit LN920 + - PCI: ibmphp: Fix double unmap of io_mem + - ethtool: Fix an error code in cxgb2.c + - NTB: Fix an error code in ntb_msit_probe() + - NTB: perf: Fix an error code in perf_setup_inbuf() + - mfd: axp20x: Update AXP288 volatile ranges + - PCI: Fix pci_dev_str_match_path() alloc while atomic bug + - mfd: tqmx86: Clear GPIO IRQ resource when no IRQ is set + - KVM: arm64: Handle PSCI resets before userspace touches vCPU state + - PCI: Sync __pci_register_driver() stub for CONFIG_PCI=n + - mtd: rawnand: cafe: Fix a resource leak in the error handling path of + 'cafe_nand_probe()' + - ARC: export clear_user_page() for modules + - perf unwind: Do not overwrite FEATURE_CHECK_LDFLAGS-libunwind-{x86,aarch64} + - net: dsa: b53: Fix calculating number of switch ports + - netfilter: socket: icmp6: fix use-after-scope + - fq_codel: reject silly quantum parameters + - qlcnic: Remove redundant unlock in qlcnic_pinit_from_rom + - ip_gre: validate csum_start only on pull + - net: renesas: sh_eth: Fix freeing wrong tx descriptor + - Linux 5.4.148 + * Focal update: v5.4.147 upstream stable release (LP: #1946795) + - Linux 5.4.147 + - upstream stable to v5.4.147 + * CVE-2021-3428 + - ext4: save the error code which triggered an ext4_error() in the superblock + - ext4: simulate various I/O and checksum errors when reading metadata + - ext4: save all error info in save_error_info() and drop ext4_set_errno() + - ext4: check journal inode extents more carefully + * ip6gretap / erspan / ip6erspan in rtnetlink.sh from net of + ubuntu_kernel_selftests failed on B-5.4-aws / B-5.4-gke / B-5.4-oracle / + B-5.4-azure / B-5.4 (LP: #1896448) + - SAUCE: selftests: rtnetlink: fixes for older iproute2 + * CVE-2019-19449 + - f2fs: fix wrong total_sections check and fsmeta check + - f2fs: fix to do sanity check on segment/section count + * kernel bug found when disconnecting one fiber channel interface on Cisco + Chassis with fnic DRV_VERSION "1.6.0.47" (LP: #1944586) + - scsi: fnic: Do not call 'scsi_done()' for unhandled commands + * memfd from ubuntu_kernel_selftests failed to build on B-5.4 (unknown type + name ‘__u64’) (LP: #1944613) + - SAUCE: selftests/memfd: fix __u64 not defined build issue + * Medion Notebook Keyboard not working (LP: #1909814) + - ACPI: resources: Add DMI-based legacy IRQ override quirk + * vrf: fix refcnt leak with vxlan slaves (LP: #1945180) + - ipv4: Fix device used for dst_alloc with local routes + * Check for changes relevant for security certifications (LP: #1945989) + - [Packaging] Add a new fips-checks script + - [Packaging] Add fips-checks as part of finalchecks + * Fix cold plugged USB device on certain PCIe USB cards (LP: #1945211) + - Revert "UBUNTU: SAUCE: Revert "usb: core: reduce power-on-good delay time of + root hub"" + - usb: core: hcd: Add support for deferring roothub registration + - xhci: Set HCD flag to defer primary roothub registration + - usb: core: hcd: Modularize HCD stop configuration in usb_stop_hcd() + * CVE-2021-3759 + - memcg: enable accounting of ipc resources + * Focal update: v5.4.146 upstream stable release (LP: #1946024) + - locking/mutex: Fix HANDOFF condition + - regmap: fix the offset of register error log + - crypto: mxs-dcp - Check for DMA mapping errors + - sched/deadline: Fix reset_on_fork reporting of DL tasks + - power: supply: axp288_fuel_gauge: Report register-address on readb / writeb + errors + - crypto: omap-sham - clear dma flags only after omap_sham_update_dma_stop() + - sched/deadline: Fix missing clock update in migrate_task_rq_dl() + - rcu/tree: Handle VM stoppage in stall detection + - hrtimer: Avoid double reprogramming in __hrtimer_start_range_ns() + - hrtimer: Ensure timerfd notification for HIGHRES=n + - udf: Check LVID earlier + - udf: Fix iocharset=utf8 mount option + - isofs: joliet: Fix iocharset=utf8 mount option + - bcache: add proper error unwinding in bcache_device_init + - nvme-tcp: don't update queue count when failing to set io queues + - nvme-rdma: don't update queue count when failing to set io queues + - nvmet: pass back cntlid on successful completion + - power: supply: max17042_battery: fix typo in MAx17042_TOFF + - s390/cio: add dev_busid sysfs entry for each subchannel + - libata: fix ata_host_start() + - crypto: qat - do not ignore errors from enable_vf2pf_comms() + - crypto: qat - handle both source of interrupt in VF ISR + - crypto: qat - fix reuse of completion variable + - crypto: qat - fix naming for init/shutdown VF to PF notifications + - crypto: qat - do not export adf_iov_putmsg() + - fcntl: fix potential deadlock for &fasync_struct.fa_lock + - udf_get_extendedattr() had no boundary checks. + - s390/kasan: fix large PMD pages address alignment check + - s390/debug: fix debug area life cycle + - m68k: emu: Fix invalid free in nfeth_cleanup() + - sched: Fix UCLAMP_FLAG_IDLE setting + - spi: spi-fsl-dspi: Fix issue with uninitialized dma_slave_config + - spi: spi-pic32: Fix issue with uninitialized dma_slave_config + - genirq/timings: Fix error return code in irq_timings_test_irqs() + - lib/mpi: use kcalloc in mpi_resize + - clocksource/drivers/sh_cmt: Fix wrong setting if don't request IRQ for clock + source channel + - crypto: qat - use proper type for vf_mask + - certs: Trigger creation of RSA module signing key if it's not an RSA key + - regulator: vctrl: Use locked regulator_get_voltage in probe path + - regulator: vctrl: Avoid lockdep warning in enable/disable ops + - spi: sprd: Fix the wrong WDG_LOAD_VAL + - spi: spi-zynq-qspi: use wait_for_completion_timeout to make + zynq_qspi_exec_mem_op not interruptible + - EDAC/i10nm: Fix NVDIMM detection + - drm/panfrost: Fix missing clk_disable_unprepare() on error in + panfrost_clk_init() + - media: TDA1997x: enable EDID support + - soc: rockchip: ROCKCHIP_GRF should not default to y, unconditionally + - media: cxd2880-spi: Fix an error handling path + - bpf: Fix a typo of reuseport map in bpf.h. + - bpf: Fix potential memleak and UAF in the verifier. + - ARM: dts: aspeed-g6: Fix HVI3C function-group in pinctrl dtsi + - arm64: dts: renesas: r8a77995: draak: Remove bogus adv7511w properties + - soc: qcom: rpmhpd: Use corner in power_off + - media: dvb-usb: fix uninit-value in dvb_usb_adapter_dvb_init + - media: dvb-usb: fix uninit-value in vp702x_read_mac_addr + - media: dvb-usb: Fix error handling in dvb_usb_i2c_init + - media: go7007: remove redundant initialization + - media: coda: fix frame_mem_ctrl for YUV420 and YVU420 formats + - Bluetooth: sco: prevent information leak in sco_conn_defer_accept() + - 6lowpan: iphc: Fix an off-by-one check of array index + - netns: protect netns ID lookups with RCU + - tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos + - ARM: dts: meson8: Use a higher default GPU clock frequency + - ARM: dts: meson8b: odroidc1: Fix the pwm regulator supply properties + - ARM: dts: meson8b: mxq: Fix the pwm regulator supply properties + - ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties + - net/mlx5e: Prohibit inner indir TIRs in IPoIB + - cgroup/cpuset: Fix a partition bug with hotplug + - net: cipso: fix warnings in netlbl_cipsov4_add_std + - i2c: highlander: add IRQ check + - leds: lt3593: Put fwnode in any case during ->probe() + - leds: trigger: audio: Add an activate callback to ensure the initial + brightness is set + - media: em28xx-input: fix refcount bug in em28xx_usb_disconnect + - media: venus: venc: Fix potential null pointer dereference on pointer fmt + - PCI: PM: Avoid forcing PCI_D0 for wakeup reasons inconsistently + - PCI: PM: Enable PME if it can be signaled from D3cold + - soc: qcom: smsm: Fix missed interrupts if state changes while masked + - debugfs: Return error during {full/open}_proxy_open() on rmmod + - Bluetooth: increase BTNAMSIZ to 21 chars to fix potential buffer overflow + - PM: EM: Increase energy calculation precision + - drm/msm/dpu: make dpu_hw_ctl_clear_all_blendstages clear necessary LMs + - arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 + - counter: 104-quad-8: Return error when invalid mode during ceiling_write + - Bluetooth: fix repeated calls to sco_sock_kill + - drm/msm/dsi: Fix some reference counted resource leaks + - usb: gadget: udc: at91: add IRQ check + - usb: phy: fsl-usb: add IRQ check + - usb: phy: twl6030: add IRQ checks + - usb: gadget: udc: renesas_usb3: Fix soc_device_match() abuse + - usb: host: ohci-tmio: add IRQ check + - usb: phy: tahvo: add IRQ check + - mac80211: Fix insufficient headroom issue for AMSDU + - lockd: Fix invalid lockowner cast after vfs_test_lock + - nfsd4: Fix forced-expiry locking + - usb: gadget: mv_u3d: request_irq() after initializing UDC + - mm/swap: consider max pages in iomap_swapfile_add_extent + - Bluetooth: add timeout sanity check to hci_inquiry + - i2c: iop3xx: fix deferred probing + - i2c: s3c2410: fix IRQ check + - rsi: fix error code in rsi_load_9116_firmware() + - rsi: fix an error code in rsi_probe() + - ASoC: Intel: Skylake: Leave data as is when invoking TLV IPCs + - ASoC: Intel: Skylake: Fix module resource and format selection + - mmc: dw_mmc: Fix issue with uninitialized dma_slave_config + - mmc: moxart: Fix issue with uninitialized dma_slave_config + - bpf: Fix possible out of bound write in narrow load handling + - CIFS: Fix a potencially linear read overflow + - i2c: mt65xx: fix IRQ check + - usb: ehci-orion: Handle errors of clk_prepare_enable() in probe + - usb: bdc: Fix an error handling path in 'bdc_probe()' when no suitable DMA + config is available + - tty: serial: fsl_lpuart: fix the wrong mapbase value + - ASoC: wcd9335: Fix a double irq free in the remove function + - ASoC: wcd9335: Fix a memory leak in the error handling path of the probe + function + - ASoC: wcd9335: Disable irq on slave ports in the remove function + - ath6kl: wmi: fix an error code in ath6kl_wmi_sync_point() + - bcma: Fix memory leak for internally-handled cores + - brcmfmac: pcie: fix oops on failure to resume and reprobe + - ipv6: make exception cache less predictible + - ipv4: make exception cache less predictible + - net: sched: Fix qdisc_rate_table refcount leak when get tcf_block failed + - net: qualcomm: fix QCA7000 checksum handling + - octeontx2-af: Fix loop in free and unmap counter + - ipv4: fix endianness issue in inet_rtm_getroute_build_skb() + - bpf: Introduce BPF nospec instruction for mitigating Spectre v4 + - bpf: Fix leakage due to insufficient speculative store bypass mitigation + - bpf: verifier: Allocate idmap scratch in verifier env + - bpf: Fix pointer arithmetic mask tightening under state pruning + - tty: Fix data race between tiocsti() and flush_to_ldisc() + - perf/x86/amd/ibs: Extend PERF_PMU_CAP_NO_EXCLUDE to IBS Op + - x86/resctrl: Fix a maybe-uninitialized build warning treated as error + - KVM: s390: index kvm->arch.idle_mask by vcpu_idx + - KVM: x86: Update vCPU's hv_clock before back to guest when tsc_offset is + adjusted + - KVM: nVMX: Unconditionally clear nested.pi_pending on nested VM-Enter + - fuse: truncate pagecache on atomic_o_trunc + - fuse: flush extending writes + - IMA: remove -Wmissing-prototypes warning + - IMA: remove the dependency on CRYPTO_MD5 + - fbmem: don't allow too huge resolutions + - backlight: pwm_bl: Improve bootloader/kernel device handover + - clk: kirkwood: Fix a clocking boot regression + - Linux 5.4.146 + * AMD A8-7680 (amdgpu): broken Xorg acceleration and hibernation + (LP: #1920674) // Focal update: v5.4.146 upstream stable release + (LP: #1946024) + - drm/amdgpu/acp: Make PM domain really work + * Focal update: v5.4.145 upstream stable release (LP: #1945517) + - fscrypt: add fscrypt_symlink_getattr() for computing st_size + - ext4: report correct st_size for encrypted symlinks + - f2fs: report correct st_size for encrypted symlinks + - ubifs: report correct st_size for encrypted symlinks + - kthread: Fix PF_KTHREAD vs to_kthread() race + - xtensa: fix kconfig unmet dependency warning for HAVE_FUTEX_CMPXCHG + - gpu: ipu-v3: Fix i.MX IPU-v3 offset calculations for (semi)planar U/V + formats + - reset: reset-zynqmp: Fixed the argument data type + - qed: Fix the VF msix vectors flow + - net: macb: Add a NULL check on desc_ptp + - qede: Fix memset corruption + - perf/x86/intel/pt: Fix mask of num_address_ranges + - perf/x86/amd/ibs: Work around erratum #1197 + - perf/x86/amd/power: Assign pmu.module + - cryptoloop: add a deprecation warning + - ARM: 8918/2: only build return_address() if needed + - ALSA: hda/realtek: Workaround for conflicting SSID on ASUS ROG Strix G17 + - ALSA: pcm: fix divide error in snd_pcm_lib_ioctl + - ARC: wireup clone3 syscall + - media: stkwebcam: fix memory leak in stk_camera_probe + - igmp: Add ip_mc_list lock in ip_check_mc_rcu + - USB: serial: mos7720: improve OOM-handling in read_mos_reg() + - ipv4/icmp: l3mdev: Perform icmp error route lookup on source device routing + table (v2) + - powerpc/boot: Delete unneeded .globl _zimage_start + - net: ll_temac: Remove left-over debug message + - mm/page_alloc: speed up the iteration of max_order + - Revert "r8169: avoid link-up interrupt issue on RTL8106e if user enables + ASPM" + - x86/events/amd/iommu: Fix invalid Perf result due to IOMMU PMC power-gating + - Revert "btrfs: compression: don't try to compress if we don't have enough + pages" + - ALSA: usb-audio: Add registration quirk for JBL Quantum 800 + - usb: host: xhci-rcar: Don't reload firmware after the completion + - usb: mtu3: use @mult for HS isoc or intr + - usb: mtu3: fix the wrong HS mult value + - xhci: fix unsafe memory usage in xhci tracing + - x86/reboot: Limit Dell Optiplex 990 quirk to early BIOS versions + - PCI: Call Max Payload Size-related fixup quirks early + - Linux 5.4.145 + * Focal update: v5.4.144 upstream stable release (LP: #1944756) + - net: qrtr: fix another OOB Read in qrtr_endpoint_post + - ARC: Fix CONFIG_STACKDEPOT + - netfilter: conntrack: collect all entries in one cycle + - once: Fix panic when module unload + - ovl: fix uninitialized pointer read in ovl_lookup_real_one() + - mmc: sdhci-msm: Update the software timeout value for sdhc + - mm, oom: make the calculation of oom badness more accurate + - can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX + and TX error counters + - Revert "USB: serial: ch341: fix character loss at high transfer rates" + - USB: serial: option: add new VID/PID to support Fibocom FG150 + - usb: dwc3: gadget: Fix dwc3_calc_trbs_left() + - usb: dwc3: gadget: Stop EP0 transfers during pullup disable + - scsi: core: Fix hang of freezing queue between blocking and running device + - RDMA/bnxt_re: Add missing spin lock initialization + - IB/hfi1: Fix possible null-pointer dereference in _extend_sdma_tx_descs() + - e1000e: Fix the max snoop/no-snoop latency for 10M + - RDMA/efa: Free IRQ vectors on error flow + - ip_gre: add validation for csum_start + - xgene-v2: Fix a resource leak in the error handling path of 'xge_probe()' + - net: marvell: fix MVNETA_TX_IN_PRGRS bit number + - rtnetlink: Return correct error on changing device netns + - net: hns3: clear hardware resource when loading driver + - net: hns3: fix duplicate node in VLAN list + - net: hns3: fix get wrong pfc_en when query PFC configuration + - drm/i915: Fix syncmap memory leak + - usb: gadget: u_audio: fix race condition on endpoint stop + - perf/x86/intel/uncore: Fix integer overflow on 23 bit left shift of a u32 + - opp: remove WARN when no valid OPPs remain + - virtio: Improve vq->broken access to avoid any compiler optimization + - virtio_pci: Support surprise removal of virtio pci device + - vringh: Use wiov->used to check for read/write desc order + - qed: qed ll2 race condition fixes + - qed: Fix null-pointer dereference in qed_rdma_create_qp() + - drm: Copy drm_wait_vblank to user before returning + - drm/nouveau/disp: power down unused DP links during init + - net/rds: dma_map_sg is entitled to merge entries + - btrfs: fix race between marking inode needs to be logged and log syncing + - vt_kdsetmode: extend console locking + - bpf: Track contents of read-only maps as scalars + - bpf: Fix cast to pointer from integer of different size warning + - net: dsa: mt7530: fix VLAN traffic leaks again + - KVM: x86/mmu: Treat NX as used (not reserved) for all !TDP shadow MMUs + - arm64: dts: qcom: msm8994-angler: Fix gpio-reserved-ranges 85-88 + - btrfs: fix NULL pointer dereference when deleting device by invalid id + - Revert "floppy: reintroduce O_NDELAY fix" + - Revert "parisc: Add assembly implementations for memset, strlen, strcpy, + strncpy and strcat" + - net: don't unconditionally copy_from_user a struct ifreq for socket ioctls + - audit: move put_tree() to avoid trim_trees refcount underflow and UAF + - Linux 5.4.144 + + -- Tim Gardner Thu, 21 Oct 2021 13:08:00 -0600 + +linux-oracle (5.4.0-1056.60) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1056.60 -proposed tracker (LP: #1944892) + + [ Ubuntu: 5.4.0-89.100 ] + + * focal/linux: 5.4.0-89.100 -proposed tracker (LP: #1944901) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.27) + * ext4 journal recovery fails w/ data=journal + mmap (LP: #1847340) + - jbd2: introduce/export functions + jbd2_journal_submit|finish_inode_data_buffers() + - jbd2, ext4, ocfs2: introduce/use journal callbacks + j_submit|finish_inode_data_buffers() + - ext4: data=journal: fixes for ext4_page_mkwrite() + - ext4: data=journal: write-protect pages on j_submit_inode_data_buffers() + - ext4: fix mmap write protection for data=journal mode + * CVE-2021-40490 + - ext4: fix race writing to an inline_data file while its xattrs are changing + * Obsolete patch "UBUNTU: SAUCE: ext4: fix directory index node split + corruption" (LP: #1942902) + - Revert "UBUNTU: SAUCE: ext4: fix directory index node split corruption" + * psock_snd.sh in net from ubuntu_kernel_selftests ADT failure with + focal/groovy/hirsute/impish (LP: #1892213) + - selftests/net: remove min gso test in packet_snd + * Focal update: v5.4.143 upstream stable release (LP: #1944212) + - ext4: fix EXT4_MAX_LOGICAL_BLOCK macro + - x86/fpu: Make init_fpstate correct with optimized XSAVE + - ath: Use safer key clearing with key cache entries + - ath9k: Clear key cache explicitly on disabling hardware + - ath: Export ath_hw_keysetmac() + - ath: Modify ath_key_delete() to not need full key entry + - ath9k: Postpone key cache entry deletion for TXQ frames reference it + - mtd: cfi_cmdset_0002: fix crash when erasing/writing AMD cards + - media: zr364xx: propagate errors from zr364xx_start_readpipe() + - media: zr364xx: fix memory leaks in probe() + - media: drivers/media/usb: fix memory leak in zr364xx_probe + - USB: core: Avoid WARNings for 0-length descriptor requests + - dmaengine: xilinx_dma: Fix read-after-free bug when terminating transfers + - dmaengine: usb-dmac: Fix PM reference leak in usb_dmac_probe() + - ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218 + - dmaengine: of-dma: router_xlate to return -EPROBE_DEFER if controller is not + yet available + - scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry() + - scsi: scsi_dh_rdac: Avoid crash during rdac_bus_attach() + - scsi: core: Avoid printing an error if target_alloc() returns -ENXIO + - scsi: core: Fix capacity set to zero after offlinining device + - ARM: dts: nomadik: Fix up interrupt controller node names + - net: usb: lan78xx: don't modify phy_device state concurrently + - drm/amd/display: Fix Dynamic bpp issue with 8K30 with Navi 1X + - Bluetooth: hidp: use correct wait queue when removing ctrl_wait + - iommu: Check if group is NULL before remove device + - cpufreq: armada-37xx: forbid cpufreq for 1.2 GHz variant + - dccp: add do-while-0 stubs for dccp_pr_debug macros + - virtio: Protect vqs list access + - vhost: Fix the calculation in vhost_overflow() + - bpf: Clear zext_dst of dead insns + - bnxt: don't lock the tx queue from napi poll + - bnxt: disable napi before canceling DIM + - net: 6pack: fix slab-out-of-bounds in decode_data + - ptp_pch: Restore dependency on PCI + - bnxt_en: Add missing DMA memory barriers + - vrf: Reset skb conntrack connection on VRF rcv + - virtio-net: support XDP when not more queues + - virtio-net: use NETIF_F_GRO_HW instead of NETIF_F_LRO + - net: qlcnic: add missed unlock in qlcnic_83xx_flash_read32 + - net: mdio-mux: Don't ignore memory allocation errors + - net: mdio-mux: Handle -EPROBE_DEFER correctly + - ovs: clear skb->tstamp in forwarding path + - i40e: Fix ATR queue selection + - iavf: Fix ping is lost after untrusted VF had tried to change MAC + - ovl: add splice file read write helper + - mmc: dw_mmc: Fix hang on data CRC error + - ALSA: hda - fix the 'Capture Switch' value change notifications + - tracing / histogram: Fix NULL pointer dereference on strcmp() on NULL event + name + - slimbus: messaging: start transaction ids from 1 instead of zero + - slimbus: messaging: check for valid transaction id + - slimbus: ngd: reset dma setup during runtime pm + - ipack: tpci200: fix many double free issues in tpci200_pci_probe + - ipack: tpci200: fix memory leak in the tpci200_register + - btrfs: prevent rename2 from exchanging a subvol with a directory from + different parents + - PCI: Increase D3 delay for AMD Renoir/Cezanne XHCI + - ASoC: intel: atom: Fix breakage for PCM buffer address setup + - mm, memcg: avoid stale protection values when cgroup is above protection + - mm: memcontrol: fix occasional OOMs due to proportional memory.low reclaim + - fs: warn about impending deprecation of mandatory locks + - netfilter: nft_exthdr: fix endianness of tcp option cast + - Linux 5.4.143 + * Focal update: v5.4.142 upstream stable release (LP: #1944202) + - iio: adc: ti-ads7950: Ensure CS is deasserted after reading channels + - iio: humidity: hdc100x: Add margin to the conversion time + - iio: adc: Fix incorrect exit of for-loop + - ASoC: xilinx: Fix reference to PCM buffer address + - ASoC: intel: atom: Fix reference to PCM buffer address + - i2c: dev: zero out array used for i2c reads from userspace + - ceph: reduce contention in ceph_check_delayed_caps() + - ACPI: NFIT: Fix support for virtual SPA ranges + - libnvdimm/region: Fix label activation vs errors + - ieee802154: hwsim: fix GPF in hwsim_set_edge_lqi + - ieee802154: hwsim: fix GPF in hwsim_new_edge_nl + - ASoC: cs42l42: Correct definition of ADC Volume control + - ASoC: cs42l42: Don't allow SND_SOC_DAIFMT_LEFT_J + - ASoC: cs42l42: Fix inversion of ADC Notch Switch control + - ASoC: cs42l42: Remove duplicate control for WNF filter frequency + - netfilter: nf_conntrack_bridge: Fix memory leak when error + - ASoC: cs42l42: Fix LRCLK frame start edge + - net: dsa: mt7530: add the missing RxUnicast MIB counter + - platform/x86: pcengines-apuv2: revert wiring up simswitch GPIO as LED + - platform/x86: pcengines-apuv2: Add missing terminating entries to gpio- + lookup tables + - net: phy: micrel: Fix link detection on ksz87xx switch" + - ppp: Fix generating ifname when empty IFLA_IFNAME is specified + - net: sched: act_mirred: Reset ct info when mirror/redirect skb + - iavf: Set RSS LUT and key in reset handle path + - psample: Add a fwd declaration for skbuff + - net/mlx5: Fix return value from tracer initialization + - drm/meson: fix colour distortion from HDR set during vendor u-boot + - net: dsa: microchip: Fix ksz_read64() + - net: Fix memory leak in ieee802154_raw_deliver + - net: igmp: fix data-race in igmp_ifc_timer_expire() + - net: dsa: lan9303: fix broken backpressure in .port_fdb_dump + - net: dsa: lantiq: fix broken backpressure in .port_fdb_dump + - net: dsa: sja1105: fix broken backpressure in .port_fdb_dump + - net: bridge: fix memleak in br_add_if() + - net: linkwatch: fix failure to restore device state across suspend/resume + - tcp_bbr: fix u32 wrap bug in round logic if bbr_init() called after 2B + packets + - net: igmp: increase size of mr_ifc_count + - xen/events: Fix race in set_evtchn_to_irq + - vsock/virtio: avoid potential deadlock when vsock device remove + - nbd: Aovid double completion of a request + - powerpc/kprobes: Fix kprobe Oops happens in booke + - x86/tools: Fix objdump version check again + - genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP + - x86/msi: Force affinity setup before startup + - x86/ioapic: Force affinity setup before startup + - x86/resctrl: Fix default monitoring groups reporting + - genirq/msi: Ensure deactivation on teardown + - genirq/timings: Prevent potential array overflow in __irq_timings_store() + - PCI/MSI: Enable and mask MSI-X early + - PCI/MSI: Mask all unused MSI-X entries + - PCI/MSI: Enforce that MSI-X table entry is masked for update + - PCI/MSI: Enforce MSI[X] entry updates to be visible + - PCI/MSI: Do not set invalid bits in MSI mask + - PCI/MSI: Correct misleading comments + - PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown() + - PCI/MSI: Protect msi_desc::masked for multi-MSI + - KVM: VMX: Use current VMCS to query WAITPKG support for MSR emulation + - ceph: add some lockdep assertions around snaprealm handling + - ceph: clean up locking annotation for ceph_get_snap_realm and + __lookup_snap_realm + - ceph: take snap_empty_lock atomically with snaprealm refcount change + - vmlinux.lds.h: Handle clang's module.{c,d}tor sections + - iommu/vt-d: Fix agaw for a supported 48 bit guest address width + - Linux 5.4.142 + * Focal update: v5.4.141 upstream stable release (LP: #1943484) + - KVM: SVM: Fix off-by-one indexing when nullifying last used SEV VMCB + - tee: Correct inappropriate usage of TEE_SHM_DMA_BUF flag + - media: v4l2-mem2mem: always consider OUTPUT queue during poll + - tracing: Reject string operand in the histogram expression + - usb: dwc3: Stop active transfers before halting the controller + - usb: dwc3: gadget: Allow runtime suspend if UDC unbinded + - usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup + - usb: dwc3: gadget: Prevent EP queuing while stopping transfers + - usb: dwc3: gadget: Clear DEP flags after stop transfers in ep disable + - usb: dwc3: gadget: Disable gadget IRQ during pullup disable + - usb: dwc3: gadget: Avoid runtime resume if disabling pullup + - KVM: X86: MMU: Use the correct inherited permissions to get shadow page + - USB:ehci:fix Kunpeng920 ehci hardware problem + - ALSA: hda: Add quirk for ASUS Flow x13 + - ppp: Fix generating ppp unit id when ifname is not specified + - ovl: prevent private clone if bind mount is not allowed + - btrfs: make qgroup_free_reserved_data take btrfs_inode + - btrfs: make btrfs_qgroup_reserve_data take btrfs_inode + - btrfs: qgroup: allow to unreserve range without releasing other ranges + - btrfs: qgroup: try to flush qgroup space when we get -EDQUOT + - btrfs: transaction: Cleanup unused TRANS_STATE_BLOCKED + - btrfs: qgroup: remove ASYNC_COMMIT mechanism in favor of reserve retry- + after-EDQUOT + - btrfs: fix lockdep splat when enabling and disabling qgroups + - net: xilinx_emaclite: Do not print real IOMEM pointer + - btrfs: qgroup: don't commit transaction when we already hold the handle + - btrfs: export and rename qgroup_reserve_meta + - btrfs: don't flush from btrfs_delayed_inode_reserve_metadata + - Linux 5.4.141 + + [ Ubuntu: 5.4.0-88.99 ] + + * focal/linux: 5.4.0-88.99 -proposed tracker (LP: #1944747) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.06) + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - Revert "UBUNTU: [Config] Disable virtualbox dkms build" + + [ Ubuntu: 5.4.0-86.97 ] + + * s390x BPF JIT vulnerabilities (LP: #1943960) + - SAUCE: s390/bpf: Fix 64-bit subtraction of the -0x80000000 constant + - SAUCE: s390/bpf: Fix optimizing out zero-extensions + + -- Tim Gardner Wed, 29 Sep 2021 06:48:56 -0600 + +linux-oracle (5.4.0-1055.59) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1055.59 -proposed tracker (LP: #1942548) + + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - [Config] oracle: Disable virtualbox dkms build + + [ Ubuntu: 5.4.0-85.95 ] + + * focal/linux: 5.4.0-85.95 -proposed tracker (LP: #1942557) + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - [Config] Disable virtualbox dkms build + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.06) + * LRMv5: switch primary version handling to kernel-versions data set + (LP: #1928921) + - [Packaging] switch to kernel-versions + * disable “CONFIG_HISI_DMA” config for ubuntu version (LP: #1936771) + - Disable CONFIG_HISI_DMA + - [Config] Record hisi_dma no longer built for arm64 + * memory leaking when removing a profile (LP: #1939915) + - apparmor: Fix memory leak of profile proxy + * CryptoExpress EP11 cards are going offline (LP: #1939618) + - s390/zcrypt: Support for CCA protected key block version 2 + - s390: Replace zero-length array with flexible-array member + - s390/zcrypt: Use scnprintf() for avoiding potential buffer overflow + - s390/zcrypt: replace snprintf/sprintf with scnprintf + - s390/ap: Remove ap device suspend and resume callbacks + - s390/zcrypt: use fallthrough; + - s390/zcrypt: use kvmalloc instead of kmalloc for 256k alloc + - s390/ap: remove power management code from ap bus and drivers + - s390/ap: introduce new ap function ap_get_qdev() + - s390/zcrypt: use kzalloc + - s390/zcrypt: fix smatch warnings + - s390/zcrypt: code beautification and struct field renames + - s390/zcrypt: split ioctl function into smaller code units + - s390/ap: rename and clarify ap state machine related stuff + - s390/zcrypt: provide cex4 cca sysfs attributes for cex3 + - s390/ap: rework crypto config info and default domain code + - s390/zcrypt: simplify cca_findcard2 loop code + - s390/zcrypt: remove set_fs() invocation in zcrypt device driver + - s390/ap: remove unnecessary spin_lock_init() + - s390/zcrypt: Support for CCA APKA master keys + - s390/zcrypt: introduce msg tracking in zcrypt functions + - s390/ap: split ap queue state machine state from device state + - s390/ap: add error response code field for ap queue devices + - s390/ap: add card/queue deconfig state + - s390/sclp: Add support for SCLP AP adapter config/deconfig + - s390/ap: Support AP card SCLP config and deconfig operations + - s390/ap/zcrypt: revisit ap and zcrypt error handling + - s390/zcrypt: move ap_msg param one level up the call chain + - s390/zcrypt: Introduce Failure Injection feature + - s390/zcrypt: fix wrong format specifications + - s390/ap: fix ap devices reference counting + - s390/zcrypt: return EIO when msg retry limit reached + - s390/zcrypt: fix zcard and zqueue hot-unplug memleak + - s390/ap: Fix hanging ioctl caused by wrong msg counter + * memfd from ubuntu_kernel_selftests failed to build on B-5.4 (LP: #1926142) + - SAUCE: selftests/memfd: fix build when F_SEAL_FUTURE_WRITE is not defined + * [SRU] Ice driver causes the kernel to crash with Ubuntu 20.04.2 with ethtool + specific register commands (LP: #1939855) + - ice: Fix bad register reads + * ubunut_kernel_selftests: memory-hotplug: avoid spamming logs with + dump_page() (LP: #1941829) + - selftests: memory-hotplug: avoid spamming logs with dump_page(), ratio limit + hot-remove error test + * e1000e blocks the boot process when it tried to write checksum to its NVM + (LP: #1936998) + - e1000e: Do not take care about recovery NVM checksum + * Focal update: v5.4.140 upstream stable release (LP: #1941798) + - Revert "ACPICA: Fix memory leak caused by _CID repair function" + - ALSA: seq: Fix racy deletion of subscriber + - arm64: dts: ls1028a: fix node name for the sysclk + - ARM: imx: add missing iounmap() + - ARM: imx: add missing clk_disable_unprepare() + - ARM: dts: imx6qdl-sr-som: Increase the PHY reset duration to 10ms + - ARM: dts: colibri-imx6ull: limit SDIO clock to 25MHz + - ARM: imx: fix missing 3rd argument in macro imx_mmdc_perf_init + - ARM: dts: imx: Swap M53Menlo pinctrl_power_button/pinctrl_power_out pins + - arm64: dts: armada-3720-turris-mox: remove mrvl,i2c-fast-mode + - ALSA: usb-audio: fix incorrect clock source setting + - clk: stm32f4: fix post divisor setup for I2S/SAI PLLs + - ARM: dts: am437x-l4: fix typo in can@0 node + - omap5-board-common: remove not physically existing vdds_1v8_main fixed- + regulator + - spi: imx: mx51-ecspi: Reinstate low-speed CONFIGREG delay + - spi: imx: mx51-ecspi: Fix low-speed CONFIGREG delay calculation + - scsi: sr: Return correct event when media event code is 3 + - media: videobuf2-core: dequeue if start_streaming fails + - dmaengine: imx-dma: configure the generic DMA type to make it work + - net, gro: Set inner transport header offset in tcp/udp GRO hook + - net: dsa: sja1105: overwrite dynamic FDB entries with static ones in + .port_fdb_add + - net: dsa: sja1105: invalidate dynamic FDB entries learned concurrently with + statically added ones + - net: phy: micrel: Fix detection of ksz87xx switch + - net: natsemi: Fix missing pci_disable_device() in probe and remove + - gpio: tqmx86: really make IRQ optional + - sctp: move the active_key update after sh_keys is added + - nfp: update ethtool reporting of pauseframe control + - net: ipv6: fix returned variable type in ip6_skb_dst_mtu + - mips: Fix non-POSIX regexp + - bnx2x: fix an error code in bnx2x_nic_load() + - net: pegasus: fix uninit-value in get_interrupt_interval + - net: fec: fix use-after-free in fec_drv_remove + - net: vxge: fix use-after-free in vxge_device_unregister + - blk-iolatency: error out if blk_get_queue() failed in iolatency_set_limit() + - Bluetooth: defer cleanup of resources in hci_unregister_dev() + - USB: usbtmc: Fix RCU stall warning + - USB: serial: option: add Telit FD980 composition 0x1056 + - USB: serial: ch341: fix character loss at high transfer rates + - USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2 + - firmware_loader: use -ETIMEDOUT instead of -EAGAIN in fw_load_sysfs_fallback + - firmware_loader: fix use-after-free in firmware_fallback_sysfs + - ALSA: hda/realtek: add mic quirk for Acer SF314-42 + - ALSA: usb-audio: Add registration quirk for JBL Quantum 600 + - usb: cdns3: Fixed incorrect gadget state + - usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers + - usb: gadget: f_hid: fixed NULL pointer dereference + - usb: gadget: f_hid: idle uses the highest byte for duration + - usb: otg-fsm: Fix hrtimer list corruption + - clk: fix leak on devm_clk_bulk_get_all() unwind + - scripts/tracing: fix the bug that can't parse raw_trace_func + - tracing / histogram: Give calculation hist_fields a size + - optee: Clear stale cache entries during initialization + - tee: add tee_shm_alloc_kernel_buf() + - optee: Fix memory leak when failing to register shm pages + - tpm_ftpm_tee: Free and unregister TEE shared memory during kexec + - staging: rtl8723bs: Fix a resource leak in sd_int_dpc + - staging: rtl8712: get rid of flush_scheduled_work + - media: rtl28xxu: fix zero-length control request + - pipe: increase minimum default pipe size to 2 pages + - ext4: fix potential htree corruption when growing large_dir directories + - serial: tegra: Only print FIFO error message when an error occurs + - serial: 8250_mtk: fix uart corruption issue when rx power off + - serial: 8250: Mask out floating 16/32-bit bus bits + - MIPS: Malta: Do not byte-swap accesses to the CBUS UART + - serial: 8250_pci: Enumerate Elkhart Lake UARTs via dedicated driver + - serial: 8250_pci: Avoid irq sharing for MSI(-X) interrupts. + - timers: Move clearing of base::timer_running under base:: Lock + - pcmcia: i82092: fix a null pointer dereference bug + - md/raid10: properly indicate failure when ending a failed write request + - KVM: x86: accept userspace interrupt only if no event is injected + - KVM: Do not leak memory for duplicate debugfs directories + - KVM: x86/mmu: Fix per-cpu counter corruption on 32-bit builds + - arm64: vdso: Avoid ISB after reading from cntvct_el0 + - soc: ixp4xx: fix printing resources + - spi: meson-spicc: fix memory leak in meson_spicc_remove + - soc: ixp4xx/qmgr: fix invalid __iomem access + - perf/x86/amd: Don't touch the AMD64_EVENTSEL_HOSTONLY bit inside the guest + - bpf, selftests: Adjust few selftest result_unpriv outcomes + - libata: fix ata_pio_sector for CONFIG_HIGHMEM + - reiserfs: add check for root_inode in reiserfs_fill_super + - reiserfs: check directory items on read from disk + - virt_wifi: fix error on connect + - alpha: Send stop IPI to send to online CPUs + - net/qla3xxx: fix schedule while atomic in ql_wait_for_drvr_lock and + ql_adapter_reset + - arm64: fix compat syscall return truncation + - Linux 5.4.140 + * Focal update: v5.4.139 upstream stable release (LP: #1941796) + - btrfs: delete duplicated words + other fixes in comments + - btrfs: do not commit logs and transactions during link and rename operations + - btrfs: fix race causing unnecessary inode logging during link and rename + - btrfs: fix lost inode on log replay after mix of fsync, rename and inode + eviction + - regulator: rt5033: Fix n_voltages settings for BUCK and LDO + - spi: stm32h7: fix full duplex irq handler handling + - ASoC: tlv320aic31xx: fix reversed bclk/wclk master bits + - r8152: Fix potential PM refcount imbalance + - qed: fix possible unpaired spin_{un}lock_bh in _qed_mcp_cmd_and_union() + - net: Fix zero-copy head len calculation. + - nvme: fix nvme_setup_command metadata trace event + - ACPI: fix NULL pointer dereference + - Revert "Bluetooth: Shutdown controller after workqueues are flushed or + cancelled" + - firmware: arm_scmi: Ensure drivers provide a probe function + - firmware: arm_scmi: Add delayed response status check + - bpf: Inherit expanded/patched seen count from old aux data + - bpf: Do not mark insn as seen under speculative path verification + - bpf: Fix leakage under speculation on mispredicted branches + - bpf: Test_verifier, add alu32 bounds tracking tests + - bpf, selftests: Add a verifier test for assigning 32bit reg states to 64bit + ones + - bpf, selftests: Adjust few selftest outcomes wrt unreachable code + - spi: mediatek: Fix fifo transfer + - Linux 5.4.139 + * Focal update: v5.4.138 upstream stable release (LP: #1940559) + - net_sched: check error pointer in tcf_dump_walker() + - x86/asm: Ensure asm/proto.h can be included stand-alone + - btrfs: fix rw device counting in __btrfs_free_extra_devids + - btrfs: mark compressed range uptodate only if all bio succeed + - x86/kvm: fix vcpu-id indexed array sizes + - KVM: add missing compat KVM_CLEAR_DIRTY_LOG + - ocfs2: fix zero out valid data + - ocfs2: issue zeroout to EOF blocks + - can: j1939: j1939_xtp_rx_dat_one(): fix rxtimer value between consecutive + TP.DT to 750ms + - can: raw: raw_setsockopt(): fix raw_rcv panic for sock UAF + - can: mcba_usb_start(): add missing urb->transfer_dma initialization + - can: usb_8dev: fix memory leak + - can: ems_usb: fix memory leak + - can: esd_usb2: fix memory leak + - HID: wacom: Re-enable touch by default for Cintiq 24HDT / 27QHDT + - NIU: fix incorrect error return, missed in previous revert + - nfc: nfcsim: fix use after free during module unload + - cfg80211: Fix possible memory leak in function cfg80211_bss_update + - netfilter: conntrack: adjust stop timestamp to real expiry value + - netfilter: nft_nat: allow to specify layer 4 protocol NAT only + - i40e: Fix logic of disabling queues + - i40e: Fix firmware LLDP agent related warning + - i40e: Fix queue-to-TC mapping on Tx + - i40e: Fix log TC creation failure when max num of queues is exceeded + - tipc: fix sleeping in tipc accept routine + - net: Set true network header for ECN decapsulation + - mlx4: Fix missing error code in mlx4_load_one() + - net: llc: fix skb_over_panic + - net/mlx5: Fix flow table chaining + - net/mlx5e: Fix nullptr in mlx5e_hairpin_get_mdev() + - sctp: fix return value check in __sctp_rcv_asconf_lookup + - tulip: windbond-840: Fix missing pci_disable_device() in probe and remove + - sis900: Fix missing pci_disable_device() in probe and remove + - can: hi311x: fix a signedness bug in hi3110_cmd() + - PCI: mvebu: Setup BAR0 in order to fix MSI + - powerpc/pseries: Fix regression while building external modules + - i40e: Add additional info to PHY type error + - can: j1939: j1939_session_deactivate(): clarify lifetime of session object + - Linux 5.4.138 + * Focal update: v5.4.137 upstream stable release (LP: #1940557) + - selftest: fix build error in tools/testing/selftests/vm/userfaultfd.c + - tools: Allow proper CC/CXX/... override with LLVM=1 in Makefile.include + - KVM: x86: determine if an exception has an error code only when injecting + it. + - af_unix: fix garbage collect vs MSG_PEEK + - workqueue: fix UAF in pwq_unbound_release_workfn() + - cgroup1: fix leaked context root causing sporadic NULL deref in LTP + - net/802/mrp: fix memleak in mrp_request_join() + - net/802/garp: fix memleak in garp_request_join() + - net: annotate data race around sk_ll_usec + - sctp: move 198 addresses from unusable to private scope + - ipv6: allocate enough headroom in ip6_finish_output2() + - hfs: add missing clean-up in hfs_fill_super + - hfs: fix high memory mapping in hfs_bnode_read + - hfs: add lock nesting notation to hfs_find_init + - firmware: arm_scmi: Fix possible scmi_linux_errmap buffer overflow + - firmware: arm_scmi: Fix range check for the maximum number of pending + messages + - cifs: fix the out of range assignment to bit fields in + parse_server_interfaces + - iomap: remove the length variable in iomap_seek_data + - iomap: remove the length variable in iomap_seek_hole + - ARM: dts: versatile: Fix up interrupt controller node names + - ipv6: ip6_finish_output2: set sk into newly allocated nskb + - Linux 5.4.137 + * Focal update: v5.4.136 upstream stable release (LP: #1939899) + - igc: Fix use-after-free error during reset + - igb: Fix use-after-free error during reset + - igc: change default return of igc_read_phy_reg() + - ixgbe: Fix an error handling path in 'ixgbe_probe()' + - igc: Prefer to use the pci_release_mem_regions method + - igc: Fix an error handling path in 'igc_probe()' + - igb: Fix an error handling path in 'igb_probe()' + - fm10k: Fix an error handling path in 'fm10k_probe()' + - e1000e: Fix an error handling path in 'e1000_probe()' + - iavf: Fix an error handling path in 'iavf_probe()' + - igb: Check if num of q_vectors is smaller than max before array access + - igb: Fix position of assignment to *ring + - gve: Fix an error handling path in 'gve_probe()' + - ipv6: fix 'disable_policy' for fwd packets + - selftests: icmp_redirect: remove from checking for IPv6 route get + - selftests: icmp_redirect: IPv6 PMTU info should be cleared after redirect + - pwm: sprd: Ensure configuring period and duty_cycle isn't wrongly skipped + - cxgb4: fix IRQ free race during driver unload + - nvme-pci: do not call nvme_dev_remove_admin from nvme_remove + - perf probe: Fix dso->nsinfo refcounting + - perf env: Fix sibling_dies memory leak + - perf test session_topology: Delete session->evlist + - perf test event_update: Fix memory leak of evlist + - perf dso: Fix memory leak in dso__new_map() + - perf script: Fix memory 'threads' and 'cpus' leaks on exit + - perf lzma: Close lzma stream on exit + - perf probe-file: Delete namelist in del_events() on the error path + - perf data: Close all files in close_dir() + - spi: imx: add a check for speed_hz before calculating the clock + - spi: stm32: Use dma_request_chan() instead dma_request_slave_channel() + - spi: stm32: fixes pm_runtime calls in probe/remove + - regulator: hi6421: Use correct variable type for regmap api val argument + - regulator: hi6421: Fix getting wrong drvdata + - spi: mediatek: fix fifo rx mode + - ASoC: rt5631: Fix regcache sync errors on resume + - liquidio: Fix unintentional sign extension issue on left shift of u16 + - s390/bpf: Perform r1 range checking before accessing jit->seen_reg[r1] + - bpf, sockmap, tcp: sk_prot needs inuse_idx set for proc stats + - bpftool: Check malloc return value in mount_bpffs_for_pin + - net: fix uninit-value in caif_seqpkt_sendmsg + - efi/tpm: Differentiate missing and invalid final event log table. + - net: decnet: Fix sleeping inside in af_decnet + - KVM: PPC: Book3S: Fix CONFIG_TRANSACTIONAL_MEM=n crash + - KVM: PPC: Fix kvm_arch_vcpu_ioctl vcpu_load leak + - net: sched: fix memory leak in tcindex_partial_destroy_work + - netrom: Decrease sock refcount when sock timers expire + - scsi: iscsi: Fix iface sysfs attr detection + - scsi: target: Fix protect handling in WRITE SAME(32) + - spi: cadence: Correct initialisation of runtime PM again + - bnxt_en: Improve bnxt_ulp_stop()/bnxt_ulp_start() call sequence. + - bnxt_en: Refresh RoCE capabilities in bnxt_ulp_probe() + - bnxt_en: Add missing check for BNXT_STATE_ABORT_ERR in bnxt_fw_rset_task() + - bnxt_en: Check abort error state in bnxt_half_open_nic() + - net: hisilicon: rename CACHE_LINE_MASK to avoid redefinition + - net/tcp_fastopen: fix data races around tfo_active_disable_stamp + - net: hns3: fix rx VLAN offload state inconsistent issue + - net/sched: act_skbmod: Skip non-Ethernet packets + - ipv6: fix another slab-out-of-bounds in fib6_nh_flush_exceptions + - nvme-pci: don't WARN_ON in nvme_reset_work if ctrl.state is not RESETTING + - Revert "USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem" + - afs: Fix tracepoint string placement with built-in AFS + - r8169: Avoid duplicate sysfs entry creation error + - nvme: set the PRACT bit when using Write Zeroes with T10 PI + - sctp: update active_key for asoc when old key is being replaced + - net: sched: cls_api: Fix the the wrong parameter + - drm/panel: raspberrypi-touchscreen: Prevent double-free + - proc: Avoid mixing integer types in mem_rw() + - s390/ftrace: fix ftrace_update_ftrace_func implementation + - s390/boot: fix use of expolines in the DMA code + - ALSA: usb-audio: Add missing proc text entry for BESPOKEN type + - ALSA: usb-audio: Add registration quirk for JBL Quantum headsets + - ALSA: sb: Fix potential ABBA deadlock in CSP driver + - ALSA: hdmi: Expose all pins on MSI MS-7C94 board + - xhci: Fix lost USB 2 remote wake + - KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow + - KVM: PPC: Book3S HV Nested: Sanitise H_ENTER_NESTED TM state + - usb: hub: Disable USB 3 device initiated lpm if exit latency is too high + - usb: hub: Fix link power management max exit latency (MEL) calculations + - USB: usb-storage: Add LaCie Rugged USB3-FW to IGNORE_UAS + - usb: max-3421: Prevent corruption of freed memory + - usb: renesas_usbhs: Fix superfluous irqs happen after usb_pkt_pop() + - USB: serial: option: add support for u-blox LARA-R6 family + - USB: serial: cp210x: fix comments for GE CS1000 + - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + - usb: dwc2: gadget: Fix sending zero length packet in DDMA mode. + - firmware/efi: Tell memblock about EFI iomem reservations + - tracing/histogram: Rename "cpu" to "common_cpu" + - tracing: Fix bug in rb_per_cpu_empty() that might cause deadloop. + - btrfs: check for missing device in btrfs_trim_fs + - media: ngene: Fix out-of-bounds bug in ngene_command_config_free_buf() + - ixgbe: Fix packet corruption due to missing DMA sync + - selftest: use mmap instead of posix_memalign to allocate memory + - userfaultfd: do not untag user pointers + - hugetlbfs: fix mount mode command line processing + - rbd: don't hold lock_rwsem while running_list is being drained + - rbd: always kick acquire on "acquired" and "released" notifications + - nds32: fix up stack guard gap + - drm: Return -ENOTTY for non-drm ioctls + - net: dsa: mv88e6xxx: use correct .stats_set_histogram() on Topaz + - net: bcmgenet: ensure EXT_ENERGY_DET_MASK is clear + - iio: accel: bma180: Use explicit member assignment + - iio: accel: bma180: Fix BMA25x bandwidth register values + - btrfs: compression: don't try to compress if we don't have enough pages + - PCI: Mark AMD Navi14 GPU ATS as broken + - perf inject: Close inject.output on exit + - xhci: add xhci_get_virt_ep() helper + - Linux 5.4.136 + * Focal update: v5.4.135 upstream stable release (LP: #1939442) + - ARM: dts: gemini: rename mdio to the right name + - ARM: dts: gemini: add device_type on pci + - ARM: dts: rockchip: fix pinctrl sleep nodename for rk3036-kylin and rk3288 + - arm64: dts: rockchip: fix pinctrl sleep nodename for rk3399.dtsi + - ARM: dts: rockchip: Fix the timer clocks order + - ARM: dts: rockchip: Fix IOMMU nodes properties on rk322x + - ARM: dts: rockchip: Fix power-controller node names for rk3066a + - ARM: dts: rockchip: Fix power-controller node names for rk3188 + - ARM: dts: rockchip: Fix power-controller node names for rk3288 + - arm64: dts: rockchip: Fix power-controller node names for px30 + - arm64: dts: rockchip: Fix power-controller node names for rk3328 + - reset: ti-syscon: fix to_ti_syscon_reset_data macro + - ARM: brcmstb: dts: fix NAND nodes names + - ARM: Cygnus: dts: fix NAND nodes names + - ARM: NSP: dts: fix NAND nodes names + - ARM: dts: BCM63xx: Fix NAND nodes names + - ARM: dts: Hurricane 2: Fix NAND nodes names + - ARM: dts: imx6: phyFLEX: Fix UART hardware flow control + - ARM: imx: pm-imx5: Fix references to imx5_cpu_suspend_info + - rtc: mxc_v2: add missing MODULE_DEVICE_TABLE + - kbuild: sink stdout from cmd for silent build + - ARM: dts: am57xx-cl-som-am57x: fix ti,no-reset-on-init flag for gpios + - ARM: dts: am437x-gp-evm: fix ti,no-reset-on-init flag for gpios + - ARM: dts: stm32: fix gpio-keys node on STM32 MCU boards + - ARM: dts: stm32: fix RCC node name on stm32f429 MCU + - ARM: dts: stm32: fix timer nodes on STM32 MCU to prevent warnings + - arm64: dts: juno: Update SCPI nodes as per the YAML schema + - ARM: dts: rockchip: fix supply properties in io-domains nodes + - ARM: dts: stm32: fix i2c node name on stm32f746 to prevent warnings + - ARM: dts: stm32: move stmmac axi config in ethernet node on stm32mp15 + - soc/tegra: fuse: Fix Tegra234-only builds + - firmware: tegra: bpmp: Fix Tegra234-only builds + - arm64: dts: ls208xa: remove bus-num from dspi node + - arm64: dts: imx8mq: assign PCIe clocks + - thermal/core: Correct function name thermal_zone_device_unregister() + - kbuild: mkcompile_h: consider timestamp if KBUILD_BUILD_TIMESTAMP is set + - rtc: max77686: Do not enforce (incorrect) interrupt trigger type + - scsi: aic7xxx: Fix unintentional sign extension issue on left shift of u8 + - scsi: libsas: Add LUN number check in .slave_alloc callback + - scsi: libfc: Fix array index out of bound exception + - scsi: qedf: Add check to synchronize abort and flush + - sched/fair: Fix CFS bandwidth hrtimer expiry type + - s390: introduce proper type handling call_on_stack() macro + - cifs: prevent NULL deref in cifs_compose_mount_options() + - arm64: dts: armada-3720-turris-mox: add firmware node + - firmware: turris-mox-rwtm: add marvell,armada-3700-rwtm-firmware compatible + string + - arm64: dts: marvell: armada-37xx: move firmware node to generic dtsi file + - f2fs: Show casefolding support only when supported + - usb: cdns3: Enable TDL_CHK only for OUT ep + - Revert "UBUNTU: SAUCE: Revert "mm: memcg/slab: fix memory leak at non-root + kmem_cache destroy"" + - mm: slab: fix kmem_cache_create failed when sysfs node not destroyed + - dm writecache: return the exact table values that were set + - net: dsa: mv88e6xxx: enable .port_set_policy() on Topaz + - net: dsa: mv88e6xxx: enable .rmu_disable() on Topaz + - net: ipv6: fix return value of ip6_skb_dst_mtu + - netfilter: ctnetlink: suspicious RCU usage in ctnetlink_dump_helpinfo + - net/sched: act_ct: fix err check for nf_conntrack_confirm + - net: bridge: sync fdb to new unicast-filtering ports + - net: bcmgenet: Ensure all TX/RX queues DMAs are disabled + - net: ip_tunnel: fix mtu calculation for ETHER tunnel devices + - net: moxa: fix UAF in moxart_mac_probe + - net: qcom/emac: fix UAF in emac_remove + - net: ti: fix UAF in tlan_remove_one + - net: send SYNACK packet with accepted fwmark + - net: validate lwtstate->data before returning from skb_tunnel_info() + - net: fddi: fix UAF in fza_probe + - dma-buf/sync_file: Don't leak fences on merge failure + - tcp: annotate data races around tp->mtu_info + - ipv6: tcp: drop silly ICMPv6 packet too big messages + - bpftool: Properly close va_list 'ap' by va_end() on error + - perf test bpf: Free obj_buf + - udp: annotate data races around unix_sk(sk)->gso_size + - Linux 5.4.135 + * Focal update: v5.4.134 upstream stable release (LP: #1939440) + - KVM: mmio: Fix use-after-free Read in kvm_vm_ioctl_unregister_coalesced_mmio + - KVM: x86: Use guest MAXPHYADDR from CPUID.0x8000_0008 iff TDP is enabled + - KVM: X86: Disable hardware breakpoints unconditionally before kvm_x86->run() + - scsi: core: Fix bad pointer dereference when ehandler kthread is invalid + - tracing: Do not reference char * as a string in histograms + - cgroup: verify that source is a string + - fbmem: Do not delete the mode that is still in use + - net: moxa: Use devm_platform_get_and_ioremap_resource() + - dmaengine: fsl-qdma: check dma_set_mask return value + - srcu: Fix broken node geometry after early ssp init + - tty: serial: fsl_lpuart: fix the potential risk of division or modulo by + zero + - misc/libmasm/module: Fix two use after free in ibmasm_init_one + - misc: alcor_pci: fix null-ptr-deref when there is no PCI bridge + - iio: gyro: fxa21002c: Balance runtime pm + use pm_runtime_resume_and_get(). + - iio: magn: bmc150: Balance runtime pm + use pm_runtime_resume_and_get() + - ALSA: usx2y: Don't call free_pages_exact() with NULL address + - Revert "ALSA: bebob/oxfw: fix Kconfig entry for Mackie d.2 Pro" + - w1: ds2438: fixing bug that would always get page0 + - scsi: hisi_sas: Propagate errors in interrupt_init_v1_hw() + - scsi: lpfc: Fix "Unexpected timeout" error in direct attach topology + - scsi: lpfc: Fix crash when lpfc_sli4_hba_setup() fails to initialize the + SGLs + - scsi: core: Cap scsi_host cmd_per_lun at can_queue + - ALSA: ac97: fix PM reference leak in ac97_bus_remove() + - tty: serial: 8250: serial_cs: Fix a memory leak in error handling path + - scsi: scsi_dh_alua: Check for negative result value + - fs/jfs: Fix missing error code in lmLogInit() + - scsi: megaraid_sas: Fix resource leak in case of probe failure + - scsi: megaraid_sas: Early detection of VD deletion through RaidMap update + - scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs + - scsi: iscsi: Add iscsi_cls_conn refcount helpers + - scsi: iscsi: Fix conn use after free during resets + - scsi: iscsi: Fix shost->max_id use + - scsi: qedi: Fix null ref during abort handling + - mfd: da9052/stmpe: Add and modify MODULE_DEVICE_TABLE + - mfd: cpcap: Fix cpcap dmamask not set warnings + - ASoC: img: Fix PM reference leak in img_i2s_in_probe() + - serial: tty: uartlite: fix console setup + - s390/sclp_vt220: fix console name to match device + - ALSA: sb: Fix potential double-free of CSP mixer elements + - powerpc/ps3: Add dma_mask to ps3_dma_region + - iommu/arm-smmu: Fix arm_smmu_device refcount leak when arm_smmu_rpm_get + fails + - iommu/arm-smmu: Fix arm_smmu_device refcount leak in address translation + - gpio: zynq: Check return value of pm_runtime_get_sync + - ALSA: ppc: fix error return code in snd_pmac_probe() + - selftests/powerpc: Fix "no_handler" EBB selftest + - gpio: pca953x: Add support for the On Semi pca9655 + - ASoC: soc-core: Fix the error return code in + snd_soc_of_parse_audio_routing() + - s390/processor: always inline stap() and __load_psw_mask() + - s390/ipl_parm: fix program check new psw handling + - s390/mem_detect: fix diag260() program check new psw handling + - s390/mem_detect: fix tprot() program check new psw handling + - Input: hideep - fix the uninitialized use in hideep_nvm_unlock() + - ALSA: bebob: add support for ToneWeal FW66 + - ALSA: usb-audio: scarlett2: Fix 18i8 Gen 2 PCM Input count + - ALSA: usb-audio: scarlett2: Fix data_mutex lock + - ALSA: usb-audio: scarlett2: Fix scarlett2_*_ctl_put() return values + - usb: gadget: f_hid: fix endianness issue with descriptors + - usb: gadget: hid: fix error return code in hid_bind() + - powerpc/boot: Fixup device-tree on little endian + - ASoC: Intel: kbl_da7219_max98357a: shrink platform_id below 20 characters + - backlight: lm3630a: Fix return code of .update_status() callback + - ALSA: hda: Add IRQ check for platform_get_irq() + - ALSA: usb-audio: scarlett2: Fix 6i6 Gen 2 line out descriptions + - staging: rtl8723bs: fix macro value for 2.4Ghz only device + - intel_th: Wait until port is in reset before programming it + - i2c: core: Disable client irq on reboot/shutdown + - power: supply: sc27xx: Add missing MODULE_DEVICE_TABLE + - power: supply: sc2731_charger: Add missing MODULE_DEVICE_TABLE + - pwm: spear: Don't modify HW state in .remove callback + - power: supply: ab8500: Avoid NULL pointers + - power: supply: max17042: Do not enforce (incorrect) interrupt trigger type + - power: reset: gpio-poweroff: add missing MODULE_DEVICE_TABLE + - ARM: 9087/1: kprobes: test-thumb: fix for LLVM_IAS=1 + - PCI/P2PDMA: Avoid pci_get_slot(), which may sleep + - watchdog: Fix possible use-after-free in wdt_startup() + - watchdog: sc520_wdt: Fix possible use-after-free in wdt_turnoff() + - watchdog: Fix possible use-after-free by calling del_timer_sync() + - watchdog: imx_sc_wdt: fix pretimeout + - x86/fpu: Return proper error codes from user access functions + - PCI: tegra: Add missing MODULE_DEVICE_TABLE + - orangefs: fix orangefs df output. + - ceph: remove bogus checks and WARN_ONs from ceph_set_page_dirty + - NFS: nfs_find_open_context() may only select open files + - power: supply: charger-manager: add missing MODULE_DEVICE_TABLE + - power: supply: ab8500: add missing MODULE_DEVICE_TABLE + - pwm: img: Fix PM reference leak in img_pwm_enable() + - pwm: tegra: Don't modify HW state in .remove callback + - ACPI: AMBA: Fix resource name in /proc/iomem + - ACPI: video: Add quirk for the Dell Vostro 3350 + - virtio-blk: Fix memory leak among suspend/resume procedure + - virtio_net: Fix error handling in virtnet_restore() + - virtio_console: Assure used length from device is limited + - x86/signal: Detect and prevent an alternate signal stack overflow + - f2fs: add MODULE_SOFTDEP to ensure crc32 is included in the initramfs + - PCI/sysfs: Fix dsm_label_utf16s_to_utf8s() buffer overrun + - power: supply: rt5033_battery: Fix device tree enumeration + - NFSv4: Initialise connection to the server in nfs4_alloc_client() + - um: fix error return code in slip_open() + - um: fix error return code in winch_tramp() + - watchdog: aspeed: fix hardware timeout calculation + - nfs: fix acl memory leak of posix_acl_create() + - ubifs: Set/Clear I_LINKABLE under i_lock for whiteout inode + - PCI: iproc: Fix multi-MSI base vector number allocation + - PCI: iproc: Support multi-MSI only on uniprocessor kernel + - x86/fpu: Limit xstate copy size in xstateregs_set() + - pwm: imx1: Don't disable clocks at device remove time + - virtio_net: move tx vq operation under tx queue lock + - nvme-tcp: can't set sk_user_data without write_lock + - ALSA: isa: Fix error return code in snd_cmi8330_probe() + - NFSv4/pNFS: Don't call _nfs4_pnfs_v3_ds_connect multiple times + - hexagon: use common DISCARDS macro + - ARM: dts: gemini-rut1xx: remove duplicate ethernet node + - reset: a10sr: add missing of_match_table reference + - ARM: exynos: add missing of_node_put for loop iteration + - ARM: dts: exynos: fix PWM LED max brightness on Odroid XU/XU3 + - ARM: dts: exynos: fix PWM LED max brightness on Odroid HC1 + - ARM: dts: exynos: fix PWM LED max brightness on Odroid XU4 + - memory: atmel-ebi: add missing of_node_put for loop iteration + - reset: brcmstb: Add missing MODULE_DEVICE_TABLE + - memory: pl353: Fix error return code in pl353_smc_probe() + - rtc: fix snprintf() checking in is_rtc_hctosys() + - arm64: dts: renesas: v3msk: Fix memory size + - ARM: dts: r8a7779, marzen: Fix DU clock names + - firmware: tegra: Fix error return code in tegra210_bpmp_init() + - firmware: arm_scmi: Reset Rx buffer to max size during async commands + - ARM: dts: BCM5301X: Fixup SPI binding + - reset: bail if try_module_get() fails + - memory: fsl_ifc: fix leak of IO mapping on probe failure + - memory: fsl_ifc: fix leak of private memory on probe failure + - ARM: dts: am335x: align ti,pindir-d0-out-d1-in property with dt-shema + - ARM: dts: am437x: align ti,pindir-d0-out-d1-in property with dt-shema + - ARM: dts: imx6q-dhcom: Fix ethernet reset time properties + - ARM: dts: imx6q-dhcom: Fix ethernet plugin detection problems + - ARM: dts: imx6q-dhcom: Add gpios pinctrl for i2c bus recovery + - thermal/drivers/rcar_gen3_thermal: Fix coefficient calculations + - firmware: turris-mox-rwtm: fix reply status decoding function + - firmware: turris-mox-rwtm: report failures better + - firmware: turris-mox-rwtm: fail probing when firmware does not support hwrng + - scsi: be2iscsi: Fix an error handling path in beiscsi_dev_probe() + - mips: always link byteswap helpers into decompressor + - mips: disable branch profiling in boot/decompress.o + - MIPS: vdso: Invalid GIC access through VDSO + - scsi: scsi_dh_alua: Fix signedness bug in alua_rtpg() + - misc: alcor_pci: fix inverted branch condition + - Linux 5.4.134 + + [ Ubuntu: 5.4.0-84.94 ] + + * focal/linux: 5.4.0-84.94 -proposed tracker (LP: #1941767) + * Server boot failure after adding checks for ACPI IRQ override (LP: #1941657) + - Revert "ACPI: resources: Add checks for ACPI IRQ override" + + -- Luke Nowakowski-Krijger Wed, 08 Sep 2021 10:52:18 -0700 + +linux-oracle (5.4.0-1054.58) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1054.58 -proposed tracker (LP: #1939790) + + * Focal update: v5.4.129 upstream stable release (LP: #1936242) + - [Config] oracle: enable CONFIG_SYSTEM_REVOCATION_LIST + + [ Ubuntu: 5.4.0-83.93 ] + + * focal/linux: 5.4.0-83.93 -proposed tracker (LP: #1940159) + * fails to launch linux L2 guests on AMD (LP: #1940134) // CVE-2021-3653 + - KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl + (CVE-2021-3653) + * fails to launch linux L2 guests on AMD (LP: #1940134) + - SAUCE: Revert "UBUNTU: SAUCE: KVM: nSVM: avoid picking up unsupported bits + from L2 in int_ctl" + + [ Ubuntu: 5.4.0-82.92 ] + + * focal/linux: 5.4.0-82.92 -proposed tracker (LP: #1939799) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.08.16) + * CVE-2021-3656 + - SAUCE: KVM: nSVM: always intercept VMLOAD/VMSAVE when nested + * CVE-2021-3653 + - SAUCE: KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl + * [regression] USB device is not detected during boot (LP: #1939638) + - SAUCE: Revert "usb: core: reduce power-on-good delay time of root hub" + * dev_forward_skb: do not scrub skb mark within the same name space + (LP: #1935040) + - dev_forward_skb: do not scrub skb mark within the same name space + * XPS 9510 (TGL) Screen Brightness could not be changed (LP: #1933566) + - SAUCE: drm/i915: Force DPCD backlight mode for Dell XPS 9510(TGL) + * Acer Aspire 5 sound driver issues (LP: #1930188) + - ALSA: hda/realtek: headphone and mic don't work on an Acer laptop + * Sony Dualshock 4 usb dongle crashes the whole system (LP: #1935846) + - HID: sony: Workaround for DS4 dongle hotplug kernel crash. + * [21.10 FEAT] KVM: Provide a secure guest indication (LP: #1933173) + - s390/uv: add prot virt guest/host indication files + - s390/uv: fix prot virt host indication compilation + * Skip rtcpie test in kselftests/timers if the default RTC device does not + exist (LP: #1937991) + - selftests: timers: rtcpie: skip test if default RTC device does not exist + * Focal update: v5.4.133 upstream stable release (LP: #1938713) + - drm/mxsfb: Don't select DRM_KMS_FB_HELPER + - drm/zte: Don't select DRM_KMS_FB_HELPER + - drm/amd/amdgpu/sriov disable all ip hw status by default + - drm/vc4: fix argument ordering in vc4_crtc_get_margins() + - net: pch_gbe: Use proper accessors to BE data in pch_ptp_match() + - drm/amd/display: fix use_max_lb flag for 420 pixel formats + - hugetlb: clear huge pte during flush function on mips platform + - atm: iphase: fix possible use-after-free in ia_module_exit() + - mISDN: fix possible use-after-free in HFC_cleanup() + - atm: nicstar: Fix possible use-after-free in nicstar_cleanup() + - net: Treat __napi_schedule_irqoff() as __napi_schedule() on PREEMPT_RT + - drm/mediatek: Fix PM reference leak in mtk_crtc_ddp_hw_init() + - reiserfs: add check for invalid 1st journal block + - drm/virtio: Fix double free on probe failure + - drm/sched: Avoid data corruptions + - udf: Fix NULL pointer dereference in udf_symlink function + - e100: handle eeprom as little endian + - igb: handle vlan types with checker enabled + - drm/bridge: cdns: Fix PM reference leak in cdns_dsi_transfer() + - clk: renesas: r8a77995: Add ZA2 clock + - clk: tegra: Ensure that PLLU configuration is applied properly + - ipv6: use prandom_u32() for ID generation + - RDMA/cxgb4: Fix missing error code in create_qp() + - dm space maps: don't reset space map allocation cursor when committing + - pinctrl: mcp23s08: fix race condition in irq handler + - ice: set the value of global config lock timeout longer + - virtio_net: Remove BUG() to avoid machine dead + - net: bcmgenet: check return value after calling platform_get_resource() + - net: mvpp2: check return value after calling platform_get_resource() + - net: micrel: check return value after calling platform_get_resource() + - drm/amd/display: Update scaling settings on modeset + - drm/amd/display: Release MST resources on switch from MST to SST + - drm/amd/display: Set DISPCLK_MAX_ERRDET_CYCLES to 7 + - drm/amdkfd: use allowed domain for vmbo validation + - fjes: check return value after calling platform_get_resource() + - selinux: use __GFP_NOWARN with GFP_NOWAIT in the AVC + - r8169: avoid link-up interrupt issue on RTL8106e if user enables ASPM + - drm/amd/display: Verify Gamma & Degamma LUT sizes in amdgpu_dm_atomic_check + - xfrm: Fix error reporting in xfrm_state_construct. + - wlcore/wl12xx: Fix wl12xx get_mac error if device is in ELP + - wl1251: Fix possible buffer overflow in wl1251_cmd_scan + - cw1200: add missing MODULE_DEVICE_TABLE + - bpf: Fix up register-based shifts in interpreter to silence KUBSAN + - mt76: mt7615: fix fixed-rate tx status reporting + - net: fix mistake path for netdev_features_strings + - net: sched: fix error return code in tcf_del_walker() + - drm/amdkfd: Walk through list with dqm lock hold + - rtl8xxxu: Fix device info for RTL8192EU devices + - atm: nicstar: use 'dma_free_coherent' instead of 'kfree' + - atm: nicstar: register the interrupt handler in the right place + - vsock: notify server to shutdown when client has pending signal + - RDMA/rxe: Don't overwrite errno from ib_umem_get() + - iwlwifi: mvm: don't change band on bound PHY contexts + - iwlwifi: pcie: free IML DMA memory allocation + - iwlwifi: pcie: fix context info freeing + - sfc: avoid double pci_remove of VFs + - sfc: error code if SRIOV cannot be disabled + - wireless: wext-spy: Fix out-of-bounds warning + - media, bpf: Do not copy more entries than user space requested + - net: ip: avoid OOM kills with large UDP sends over loopback + - RDMA/cma: Fix rdma_resolve_route() memory leak + - Bluetooth: btusb: Fixed too many in-token issue for Mediatek Chip. + - Bluetooth: Fix the HCI to MGMT status conversion table + - Bluetooth: Shutdown controller after workqueues are flushed or cancelled + - Bluetooth: btusb: fix bt fiwmare downloading failure issue for qca btsoc. + - sctp: validate from_addr_param return + - sctp: add size validation when walking chunks + - MIPS: loongsoon64: Reserve memory below starting pfn to prevent Oops + - MIPS: set mips32r5 for virt extensions + - fscrypt: don't ignore minor_hash when hash is 0 + - crypto: ccp - Annotate SEV Firmware file names + - perf bench: Fix 2 memory sanitizer warnings + - powerpc/mm: Fix lockup on kernel exec fault + - powerpc/barrier: Avoid collision with clang's __lwsync macro + - drm/amdgpu: Update NV SIMD-per-CU to 2 + - drm/radeon: Add the missed drm_gem_object_put() in + radeon_user_framebuffer_create() + - drm/rockchip: dsi: remove extra component_del() call + - drm/amd/display: fix incorrrect valid irq check + - pinctrl/amd: Add device HID for new AMD GPIO controller + - drm/tegra: Don't set allow_fb_modifiers explicitly + - drm/msm/mdp4: Fix modifier support enabling + - drm/arm/malidp: Always list modifiers + - mmc: sdhci: Fix warning message when accessing RPMB in HS400 mode + - mmc: core: clear flags before allowing to retune + - mmc: core: Allow UHS-I voltage switch for SDSC cards if supported + - ata: ahci_sunxi: Disable DIPM + - cpu/hotplug: Cure the cpusets trainwreck + - clocksource/arm_arch_timer: Improve Allwinner A64 timer workaround + - fpga: stratix10-soc: Add missing fpga_mgr_free() call + - MIPS: fix "mipsel-linux-ld: decompress.c:undefined reference to `memmove'" + - ASoC: tegra: Set driver_name=tegra for all machine drivers + - qemu_fw_cfg: Make fw_cfg_rev_attr a proper kobj_attribute + - ipmi/watchdog: Stop watchdog timer when the current action is 'none' + - thermal/drivers/int340x/processor_thermal: Fix tcc setting + - ubifs: Fix races between xattr_{set|get} and listxattr operations + - power: supply: ab8500: Fix an old bug + - nvmem: core: add a missing of_node_put + - extcon: intel-mrfld: Sync hardware and software state on init + - seq_buf: Fix overflow in seq_buf_putmem_hex() + - rq-qos: fix missed wake-ups in rq_qos_throttle try two + - tracing: Simplify & fix saved_tgids logic + - tracing: Resize tgid_map to pid_max, not PID_MAX_DEFAULT + - ipack/carriers/tpci200: Fix a double free in tpci200_pci_probe + - coresight: tmc-etf: Fix global-out-of-bounds in tmc_update_etf_buffer() + - dm btree remove: assign new_root only when removal succeeds + - PCI: Leave Apple Thunderbolt controllers on for s2idle or standby + - PCI: aardvark: Fix checking for PIO Non-posted Request + - PCI: aardvark: Implement workaround for the readback value of VEND_ID + - media: subdev: disallow ioctl for saa6588/davinci + - media: dtv5100: fix control-request directions + - media: zr364xx: fix memory leak in zr364xx_start_readpipe + - media: gspca/sq905: fix control-request direction + - media: gspca/sunplus: fix zero-length control requests + - pinctrl: mcp23s08: Fix missing unlock on error in mcp23s08_irq() + - jfs: fix GPF in diFree + - smackfs: restrict bytes count in smk_set_cipso() + - Linux 5.4.133 + * Focal update: v5.4.132 upstream stable release (LP: #1938199) + - ALSA: usb-audio: fix rate on Ozone Z90 USB headset + - ALSA: usb-audio: Fix OOB access at proc output + - ALSA: usb-audio: scarlett2: Fix wrong resume call + - ALSA: intel8x0: Fix breakage at ac97 clock measurement + - ALSA: hda/realtek: Add another ALC236 variant support + - ALSA: hda/realtek: Improve fixup for HP Spectre x360 15-df0xxx + - ALSA: hda/realtek: Fix bass speaker DAC mapping for Asus UM431D + - ALSA: hda/realtek: Apply LED fixup for HP Dragonfly G1, too + - media: dvb-usb: fix wrong definition + - Input: usbtouchscreen - fix control-request directions + - net: can: ems_usb: fix use-after-free in ems_usb_disconnect() + - usb: gadget: eem: fix echo command packet response issue + - USB: cdc-acm: blacklist Heimann USB Appset device + - usb: dwc3: Fix debugfs creation flow + - usb: typec: Add the missed altmode_id_remove() in typec_register_altmode() + - xhci: solve a double free problem while doing s4 + - ntfs: fix validity check for file name attribute + - copy_page_to_iter(): fix ITER_DISCARD case + - iov_iter_fault_in_readable() should do nothing in xarray case + - Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl + - arm_pmu: Fix write counter incorrect in ARMv7 big-endian mode + - ARM: dts: at91: sama5d4: fix pinctrl muxing + - btrfs: send: fix invalid path for unlink operations after parent + orphanization + - btrfs: clear defrag status of a root if starting transaction fails + - ext4: cleanup in-core orphan list if ext4_truncate() failed to get a + transaction handle + - ext4: fix kernel infoleak via ext4_extent_header + - ext4: return error code when ext4_fill_flex_info() fails + - ext4: correct the cache_nr in tracepoint ext4_es_shrink_exit + - ext4: remove check for zero nr_to_scan in ext4_es_scan() + - ext4: fix avefreec in find_group_orlov + - ext4: use ext4_grp_locked_error in mb_find_extent + - can: gw: synchronize rcu operations before removing gw job entry + - can: j1939: j1939_sk_init(): set SOCK_RCU_FREE to call sk_destruct() after + RCU is done + - can: peak_pciefd: pucan_handle_status(): fix a potential starvation issue in + TX path + - mac80211: remove iwlwifi specific workaround that broke sta NDP tx + - SUNRPC: Fix the batch tasks count wraparound. + - SUNRPC: Should wake up the privileged task firstly. + - perf/smmuv3: Don't trample existing events with global filter + - KVM: PPC: Book3S HV: Workaround high stack usage with clang + - s390/cio: dont call css_wait_for_slow_path() inside a lock + - rtc: stm32: Fix unbalanced clk_disable_unprepare() on probe error path + - iio: light: tcs3472: do not free unallocated IRQ + - iio: ltr501: mark register holding upper 8 bits of ALS_DATA{0,1} and PS_DATA + as volatile, too + - iio: ltr501: ltr559: fix initialization of LTR501_ALS_CONTR + - iio: ltr501: ltr501_read_ps(): add missing endianness conversion + - serial: mvebu-uart: fix calculation of clock divisor + - serial: sh-sci: Stop dmaengine transfer in sci_stop_tx() + - serial_cs: Add Option International GSM-Ready 56K/ISDN modem + - serial_cs: remove wrong GLOBETROTTER.cis entry + - ath9k: Fix kernel NULL pointer dereference during ath_reset_internal() + - ssb: sdio: Don't overwrite const buffer if block_write fails + - rsi: Assign beacon rate settings to the correct rate_info descriptor field + - rsi: fix AP mode with WPA failure due to encrypted EAPOL + - tracing/histograms: Fix parsing of "sym-offset" modifier + - tracepoint: Add tracepoint_probe_register_may_exist() for BPF tracing + - seq_buf: Make trace_seq_putmem_hex() support data longer than 8 + - powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi() + - evm: Execute evm_inode_init_security() only when an HMAC key is loaded + - evm: Refuse EVM_ALLOW_METADATA_WRITES only if an HMAC key is loaded + - fuse: ignore PG_workingset after stealing + - fuse: check connected before queueing on fpq->io + - fuse: reject internal errno + - spi: Make of_register_spi_device also set the fwnode + - media: mdk-mdp: fix pm_runtime_get_sync() usage count + - media: s5p: fix pm_runtime_get_sync() usage count + - media: sh_vou: fix pm_runtime_get_sync() usage count + - media: mtk-vcodec: fix PM runtime get logic + - media: s5p-jpeg: fix pm_runtime_get_sync() usage count + - media: sti/bdisp: fix pm_runtime_get_sync() usage count + - media: exynos-gsc: fix pm_runtime_get_sync() usage count + - spi: spi-loopback-test: Fix 'tx_buf' might be 'rx_buf' + - spi: spi-topcliff-pch: Fix potential double free in + pch_spi_process_messages() + - spi: omap-100k: Fix the length judgment problem + - regulator: uniphier: Add missing MODULE_DEVICE_TABLE + - hwrng: exynos - Fix runtime PM imbalance on error + - crypto: nx - add missing MODULE_DEVICE_TABLE + - media: sti: fix obj-$(config) targets + - media: cpia2: fix memory leak in cpia2_usb_probe + - media: cobalt: fix race condition in setting HPD + - media: pvrusb2: fix warning in pvr2_i2c_core_done + - media: imx: imx7_mipi_csis: Fix logging of only error event counters + - crypto: qat - check return code of qat_hal_rd_rel_reg() + - crypto: qat - remove unused macro in FW loader + - sched/fair: Fix ascii art by relpacing tabs + - media: em28xx: Fix possible memory leak of em28xx struct + - media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release + - media: bt8xx: Fix a missing check bug in bt878_probe + - media: st-hva: Fix potential NULL pointer dereferences + - Makefile: fix GDB warning with CONFIG_RELR + - media: dvd_usb: memory leak in cinergyt2_fe_attach + - memstick: rtsx_usb_ms: fix UAF + - mmc: sdhci-sprd: use sdhci_sprd_writew + - mmc: via-sdmmc: add a check against NULL pointer dereference + - crypto: shash - avoid comparing pointers to exported functions under CFI + - media: dvb_net: avoid speculation from net slot + - media: siano: fix device register error path + - media: imx-csi: Skip first few frames from a BT.656 source + - hwmon: (max31790) Report correct current pwm duty cycles + - hwmon: (max31790) Fix pwmX_enable attributes + - drivers/perf: fix the missed ida_simple_remove() in ddr_perf_probe() + - KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10 + processors + - btrfs: fix error handling in __btrfs_update_delayed_inode + - btrfs: abort transaction if we fail to update the delayed inode + - btrfs: disable build on platforms having page size 256K + - locking/lockdep: Fix the dep path printing for backwards BFS + - lockding/lockdep: Avoid to find wrong lock dep path in check_irq_usage() + - KVM: s390: get rid of register asm usage + - regulator: mt6358: Fix vdram2 .vsel_mask + - regulator: da9052: Ensure enough delay time for .set_voltage_time_sel + - media: Fix Media Controller API config checks + - HID: do not use down_interruptible() when unbinding devices + - EDAC/ti: Add missing MODULE_DEVICE_TABLE + - ACPI: processor idle: Fix up C-state latency if not ordered + - hv_utils: Fix passing zero to 'PTR_ERR' warning + - lib: vsprintf: Fix handling of number field widths in vsscanf + - ACPI: EC: Make more Asus laptops use ECDT _GPE + - block_dump: remove block_dump feature in mark_inode_dirty() + - fs: dlm: cancel work sync othercon + - random32: Fix implicit truncation warning in prandom_seed_state() + - fs: dlm: fix memory leak when fenced + - ACPICA: Fix memory leak caused by _CID repair function + - ACPI: bus: Call kobject_put() in acpi_init() error path + - block: fix race between adding/removing rq qos and normal IO + - platform/x86: toshiba_acpi: Fix missing error code in + toshiba_acpi_setup_keyboard() + - nvmet-fc: do not check for invalid target port in nvmet_fc_handle_fcp_rqst() + - EDAC/Intel: Do not load EDAC driver when running as a guest + - PCI: hv: Add check for hyperv_initialized in init_hv_pci_drv() + - clocksource: Retry clock read if long delays detected + - ACPI: tables: Add custom DSDT file as makefile prerequisite + - HID: wacom: Correct base usage for capacitive ExpressKey status bits + - cifs: fix missing spinlock around update to ses->status + - block: fix discard request merge + - kthread_worker: fix return value when kthread_mod_delayed_work() races with + kthread_cancel_delayed_work_sync() + - ia64: mca_drv: fix incorrect array size calculation + - writeback, cgroup: increment isw_nr_in_flight before grabbing an inode + - media: s5p_cec: decrement usage count if disabled + - crypto: ixp4xx - dma_unmap the correct address + - crypto: ux500 - Fix error return code in hash_hw_final() + - sata_highbank: fix deferred probing + - pata_rb532_cf: fix deferred probing + - media: I2C: change 'RST' to "RSET" to fix multiple build errors + - sched/uclamp: Fix wrong implementation of cpu.uclamp.min + - sched/uclamp: Fix locking around cpu_util_update_eff() + - kbuild: run the checker after the compiler + - kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_ := n' + - pata_octeon_cf: avoid WARN_ON() in ata_host_activate() + - evm: fix writing /evm overflow + - crypto: ccp - Fix a resource leak in an error handling path + - media: rc: i2c: Fix an error message + - pata_ep93xx: fix deferred probing + - media: exynos4-is: Fix a use after free in isp_video_release + - media: au0828: fix a NULL vs IS_ERR() check + - media: tc358743: Fix error return code in tc358743_probe_of() + - media: gspca/gl860: fix zero-length control requests + - m68k: atari: Fix ATARI_KBD_CORE kconfig unmet dependency warning + - media: siano: Fix out-of-bounds warnings in smscore_load_firmware_family2() + - crypto: nitrox - fix unchecked variable in nitrox_register_interrupts + - crypto: omap-sham - Fix PM reference leak in omap sham ops + - mmc: usdhi6rol0: fix error return code in usdhi6_probe() + - arm64: consistently use reserved_pg_dir + - arm64/mm: Fix ttbr0 values stored in struct thread_info for software-pan + - media: s5p-g2d: Fix a memory leak on ctx->fh.m2m_ctx + - hwmon: (max31722) Remove non-standard ACPI device IDs + - hwmon: (max31790) Fix fan speed reporting for fan7..12 + - KVM: nVMX: Ensure 64-bit shift when checking VMFUNC bitmap + - regulator: hi655x: Fix pass wrong pointer to config.driver_data + - btrfs: clear log tree recovering status if starting transaction fails + - sched/rt: Fix RT utilization tracking during policy change + - sched/rt: Fix Deadline utilization tracking during policy change + - sched/uclamp: Fix uclamp_tg_restrict() + - spi: spi-sun6i: Fix chipselect/clock bug + - crypto: nx - Fix RCU warning in nx842_OF_upd_status + - ACPI: sysfs: Fix a buffer overrun problem with description_show() + - extcon: extcon-max8997: Fix IRQ freeing at error path + - blk-wbt: introduce a new disable state to prevent false positive by + rwb_enabled() + - blk-wbt: make sure throttle is enabled properly + - ACPI: Use DEVICE_ATTR_ macros + - ACPI: bgrt: Fix CFI violation + - cpufreq: Make cpufreq_online() call driver->offline() on errors + - ocfs2: fix snprintf() checking + - dax: fix ENOMEM handling in grab_mapping_entry() + - xfrm: xfrm_state_mtu should return at least 1280 for ipv6 + - video: fbdev: imxfb: Fix an error message + - net: mvpp2: Put fwnode in error case during ->probe() + - net: pch_gbe: Propagate error from devm_gpio_request_one() + - pinctrl: renesas: r8a7796: Add missing bias for PRESET# pin + - pinctrl: renesas: r8a77990: JTAG pins do not have pull-down capabilities + - clk: meson: g12a: fix gp0 and hifi ranges + - net: ftgmac100: add missing error return code in ftgmac100_probe() + - drm/rockchip: cdn-dp-core: add missing clk_disable_unprepare() on error in + cdn_dp_grf_write() + - drm/rockchip: dsi: move all lane config except LCDC mux to bind() + - ehea: fix error return code in ehea_restart_qps() + - net/sched: act_vlan: Fix modify to allow 0 + - RDMA/core: Sanitize WQ state received from the userspace + - RDMA/rxe: Fix failure during driver load + - drm: qxl: ensure surf.data is ininitialized + - tools/bpftool: Fix error return code in do_batch() + - ath10k: go to path err_unsupported when chip id is not supported + - ath10k: add missing error return code in ath10k_pci_probe() + - wireless: carl9170: fix LEDS build errors & warnings + - ieee802154: hwsim: Fix possible memory leak in hwsim_subscribe_all_others + - wcn36xx: Move hal_buf allocation to devm_kmalloc in probe + - ssb: Fix error return code in ssb_bus_scan() + - brcmfmac: fix setting of station info chains bitmask + - brcmfmac: correctly report average RSSI in station info + - brcmsmac: mac80211_if: Fix a resource leak in an error handling path + - ath10k: Fix an error code in ath10k_add_interface() + - netlabel: Fix memory leak in netlbl_mgmt_add_common + - RDMA/mlx5: Don't add slave port to unaffiliated list + - netfilter: nft_exthdr: check for IPv6 packet before further processing + - netfilter: nft_osf: check for TCP packet before further processing + - netfilter: nft_tproxy: restrict support to TCP and UDP transport protocols + - RDMA/rxe: Fix qp reference counting for atomic ops + - samples/bpf: Fix the error return code of xdp_redirect's main() + - net: ethernet: aeroflex: fix UAF in greth_of_remove + - net: ethernet: ezchip: fix UAF in nps_enet_remove + - net: ethernet: ezchip: fix error handling + - vrf: do not push non-ND strict packets with a source LLA through packet taps + again + - net: sched: add barrier to ensure correct ordering for lockless qdisc + - tls: prevent oversized sendfile() hangs by ignoring MSG_MORE + - pkt_sched: sch_qfq: fix qfq_change_class() error path + - vxlan: add missing rcu_read_lock() in neigh_reduce() + - net/ipv4: swap flow ports when validating source + - tc-testing: fix list handling + - ieee802154: hwsim: Fix memory leak in hwsim_add_one + - ieee802154: hwsim: avoid possible crash in hwsim_del_edge_nl() + - mac80211: remove iwlwifi specific workaround NDPs of null_response + - net: bcmgenet: Fix attaching to PYH failed on RPi 4B + - ipv6: exthdrs: do not blindly use init_net + - bpf: Do not change gso_size during bpf_skb_change_proto() + - i40e: Fix error handling in i40e_vsi_open + - i40e: Fix autoneg disabling for non-10GBaseT links + - Revert "ibmvnic: remove duplicate napi_schedule call in open function" + - ibmvnic: free tx_pool if tso_pool alloc fails + - ipv6: fix out-of-bound access in ip6_parse_tlv() + - e1000e: Check the PCIm state + - bpfilter: Specify the log level for the kmsg message + - gve: Fix swapped vars when fetching max queues + - Revert "be2net: disable bh with spin_lock in be_process_mcc" + - Bluetooth: mgmt: Fix slab-out-of-bounds in tlv_data_is_valid + - Bluetooth: Fix handling of HCI_LE_Advertising_Set_Terminated event + - clk: actions: Fix UART clock dividers on Owl S500 SoC + - clk: actions: Fix SD clocks factor table on Owl S500 SoC + - clk: actions: Fix bisp_factor_table based clocks on Owl S500 SoC + - clk: si5341: Avoid divide errors due to bogus register contents + - clk: si5341: Update initialization magic + - writeback: fix obtain a reference to a freeing memcg css + - net: lwtunnel: handle MTU calculation in forwading + - net: sched: fix warning in tcindex_alloc_perfect_hash + - RDMA/mlx5: Don't access NULL-cleared mpi pointer + - MIPS: Fix PKMAP with 32-bit MIPS huge page support + - staging: fbtft: Rectify GPIO handling + - rcu: Invoke rcu_spawn_core_kthreads() from rcu_spawn_gp_kthread() + - tty: nozomi: Fix a resource leak in an error handling function + - mwifiex: re-fix for unaligned accesses + - iio: adis_buffer: do not return ints in irq handlers + - iio: adis16400: do not return ints in irq handlers + - iio: accel: bma180: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: bma220: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: hid: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: kxcjk-1013: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio:accel:mxc4005: Drop unnecessary explicit casts in regmap_bulk_read calls + - iio: accel: mxc4005: Fix overread of data and alignment issue. + - iio: accel: stk8312: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: stk8ba50: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: ti-ads1015: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: vf610: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: gyro: bmg160: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: humidity: am2315: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: srf08: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: pulsed-light: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: as3935: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: magn: hmc5843: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: magn: bmc150: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: isl29125: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: tcs3414: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: tcs3472: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: cros_ec_sensors: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - iio: potentiostat: lmp91000: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - ASoC: rk3328: fix missing clk_disable_unprepare() on error in + rk3328_platform_probe() + - ASoC: hisilicon: fix missing clk_disable_unprepare() on error in + hi6210_i2s_startup() + - backlight: lm3630a_bl: Put fwnode in error case during ->probe() + - ASoC: rsnd: tidyup loop on rsnd_adg_clk_query() + - Input: hil_kbd - fix error return code in hil_dev_connect() + - mtd: partitions: redboot: seek fis-index-block in the right node + - char: pcmcia: error out if 'num_bytes_read' is greater than 4 in + set_protocol() + - firmware: stratix10-svc: Fix a resource leak in an error handling path + - tty: nozomi: Fix the error handling path of 'nozomi_card_init()' + - leds: lm3532: select regmap I2C API + - leds: lm36274: cosmetic: rename lm36274_data to chip + - leds: lm3692x: Put fwnode in any case during ->probe() + - scsi: FlashPoint: Rename si_flags field + - fsi: core: Fix return of error values on failures + - fsi: scom: Reset the FSI2PIB engine for any error + - fsi: occ: Don't accept response from un-initialized OCC + - fsi/sbefifo: Clean up correct FIFO when receiving reset request from SBE + - fsi/sbefifo: Fix reset timeout + - visorbus: fix error return code in visorchipset_init() + - s390: appldata depends on PROC_SYSCTL + - iommu/dma: Fix IOVA reserve dma ranges + - ASoC: mediatek: mtk-btcvsd: Fix an error handling path in + 'mtk_btcvsd_snd_probe()' + - usb: gadget: f_fs: Fix setting of device and driver data cross-references + - usb: dwc2: Don't reset the core after setting turnaround time + - eeprom: idt_89hpesx: Put fwnode in matching case during ->probe() + - eeprom: idt_89hpesx: Restore printing the unsupported fwnode name + - iio: at91-sama5d2_adc: remove usage of iio_priv_to_dev() helper + - iio: adc: at91-sama5d2: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: hx711: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: mxs-lradc: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: ti-ads8688: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - iio: magn: rm3100: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - staging: gdm724x: check for buffer overflow in gdm_lte_multi_sdu_pkt() + - staging: gdm724x: check for overflow in gdm_lte_netif_rx() + - staging: rtl8712: remove redundant check in r871xu_drv_init + - staging: rtl8712: fix memory leak in rtl871x_load_fw_cb + - staging: mt7621-dts: fix pci address for PCI memory range + - serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates + - iio: light: vcnl4035: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: isl29501: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - ASoC: cs42l42: Correct definition of CS42L42_ADC_PDN_MASK + - of: Fix truncation of memory sizes on 32-bit platforms + - mtd: rawnand: marvell: add missing clk_disable_unprepare() on error in + marvell_nfc_resume() + - scsi: mpt3sas: Fix error return value in _scsih_expander_add() + - soundwire: stream: Fix test for DP prepare complete + - phy: uniphier-pcie: Fix updating phy parameters + - phy: ti: dm816x: Fix the error handling path in 'dm816x_usb_phy_probe() + - extcon: sm5502: Drop invalid register write in sm5502_reg_data + - extcon: max8997: Add missing modalias string + - ASoC: atmel-i2s: Fix usage of capture and playback at the same time + - configfs: fix memleak in configfs_release_bin_file + - leds: as3645a: Fix error return code in as3645a_parse_node() + - leds: ktd2692: Fix an error handling path + - powerpc: Offline CPU in stop_this_cpu() + - serial: mvebu-uart: do not allow changing baudrate when uartclk is not + available + - serial: mvebu-uart: correctly calculate minimal possible baudrate + - arm64: dts: marvell: armada-37xx: Fix reg for standard variant of UART + - vfio/pci: Handle concurrent vma faults + - mm/huge_memory.c: don't discard hugepage if other processes are mapping it + - mm/z3fold: fix potential memory leak in z3fold_destroy_pool() + - selftests/vm/pkeys: fix alloc_random_pkey() to make it really, really random + - perf llvm: Return -ENOMEM when asprintf() fails + - scsi: target: cxgbit: Unmap DMA buffer before calling target_execute_cmd() + - mmc: block: Disable CMDQ on the ioctl path + - mmc: vub3000: fix control-request direction + - scsi: core: Retry I/O for Notify (Enable Spinup) Required error + - iommu/dma: Fix compile warning in 32-bit builds + - Linux 5.4.132 + * Keyboard not working (LP: #1909814) // Focal update: v5.4.132 upstream + stable release (LP: #1938199) + - ACPI: resources: Add checks for ACPI IRQ override + * Focal update: v5.4.131 upstream stable release (LP: #1936245) + - KVM: SVM: Periodically schedule when unregistering regions on destroy + - s390/stack: fix possible register corruption with stack switch helper + - KVM: SVM: Call SEV Guest Decommission if ASID binding fails + - xen/events: reset active flag for lateeoi events later + - Linux 5.4.131 + * Focal update: v5.4.130 upstream stable release (LP: #1936244) + - scsi: sr: Return appropriate error code when disk is ejected + - drm/nouveau: fix dma_address check for CPU/GPU sync + - gpio: AMD8111 and TQMX86 require HAS_IOPORT_MAP + - RDMA/mlx5: Block FDB rules when not in switchdev mode + - Linux 5.4.130 + * Focal update: v5.4.129 upstream stable release (LP: #1936242) + - module: limit enabling module.sig_enforce + - drm/nouveau: wait for moving fence after pinning v2 + - drm/radeon: wait for moving fence after pinning + - ARM: 9081/1: fix gcc-10 thumb2-kernel regression + - mmc: meson-gx: use memcpy_to/fromio for dram-access-quirk + - kbuild: add CONFIG_LD_IS_LLD + - arm64: link with -z norelro for LLD or aarch64-elf + - MIPS: generic: Update node names to avoid unit addresses + - spi: spi-nxp-fspi: move the register operation after the clock enable + - Revert "PCI: PM: Do not read power state in pci_enable_device_flags()" + - dmaengine: zynqmp_dma: Fix PM reference leak in + zynqmp_dma_alloc_chan_resourc() + - mac80211: remove warning in ieee80211_get_sband() + - mac80211_hwsim: drop pending frames on stop + - cfg80211: call cfg80211_leave_ocb when switching away from OCB + - dmaengine: rcar-dmac: Fix PM reference leak in rcar_dmac_probe() + - dmaengine: mediatek: free the proper desc in desc_free handler + - dmaengine: mediatek: do not issue a new desc if one is still current + - dmaengine: mediatek: use GFP_NOWAIT instead of GFP_ATOMIC in prep_dma + - net: ipv4: Remove unneed BUG() function + - mac80211: drop multicast fragments + - net: ethtool: clear heap allocations for ethtool function + - ping: Check return value of function 'ping_queue_rcv_skb' + - inet: annotate date races around sk->sk_txhash + - net: phy: dp83867: perform soft reset and retain established link + - net: caif: fix memory leak in ldisc_open + - net/packet: annotate accesses to po->bind + - net/packet: annotate accesses to po->ifindex + - r8152: Avoid memcpy() over-reading of ETH_SS_STATS + - sh_eth: Avoid memcpy() over-reading of ETH_SS_STATS + - r8169: Avoid memcpy() over-reading of ETH_SS_STATS + - KVM: selftests: Fix kvm_check_cap() assertion + - net: qed: Fix memcpy() overflow of qed_dcbx_params() + - recordmcount: Correct st_shndx handling + - PCI: Add AMD RS690 quirk to enable 64-bit DMA + - net: ll_temac: Add memory-barriers for TX BD access + - net: ll_temac: Avoid ndo_start_xmit returning NETDEV_TX_BUSY + - pinctrl: stm32: fix the reported number of GPIO lines per bank + - nilfs2: fix memory leak in nilfs_sysfs_delete_device_group + - KVM: do not allow mapping valid but non-reference-counted pages + - i2c: robotfuzz-osif: fix control-request directions + - kthread_worker: split code for canceling the delayed work timer + - kthread: prevent deadlock when kthread_mod_delayed_work() races with + kthread_cancel_delayed_work_sync() + - mm: add VM_WARN_ON_ONCE_PAGE() macro + - mm/rmap: remove unneeded semicolon in page_not_mapped() + - mm/rmap: use page_not_mapped in try_to_unmap() + - mm, thp: use head page in __migration_entry_wait() + - mm/thp: fix __split_huge_pmd_locked() on shmem migration entry + - mm/thp: make is_huge_zero_pmd() safe and quicker + - mm/thp: try_to_unmap() use TTU_SYNC for safe splitting + - mm/thp: fix vma_address() if virtual address below file offset + - mm/thp: fix page_address_in_vma() on file THP tails + - mm/thp: unmap_mapping_page() to fix THP truncate_cleanup_page() + - mm: thp: replace DEBUG_VM BUG with VM_WARN when unmap fails for split + - mm: page_vma_mapped_walk(): use page for pvmw->page + - mm: page_vma_mapped_walk(): settle PageHuge on entry + - mm: page_vma_mapped_walk(): use pmde for *pvmw->pmd + - mm: page_vma_mapped_walk(): prettify PVMW_MIGRATION block + - mm: page_vma_mapped_walk(): crossing page table boundary + - mm: page_vma_mapped_walk(): add a level of indentation + - mm: page_vma_mapped_walk(): use goto instead of while (1) + - mm: page_vma_mapped_walk(): get vma_address_end() earlier + - mm/thp: fix page_vma_mapped_walk() if THP mapped by ptes + - mm/thp: another PVMW_SYNC fix in page_vma_mapped_walk() + - mm, futex: fix shared futex pgoff on shmem huge page + - [Config] enable CONFIG_SYSTEM_REVOCATION_LIST + - certs: Add EFI_CERT_X509_GUID support for dbx entries + - certs: Move load_system_certificate_list to a common function + - Linux 5.4.129 + * Patch To Fix Bug in the Linux Block Layer Responsible For Merging BIOs + (LP: #1931497) + - block: return the correct bvec when checking for gaps + + -- Luke Nowakowski-Krijger Fri, 20 Aug 2021 09:31:09 -0700 + +linux-oracle (5.4.0-1053.57) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1053.57 -proposed tracker (LP: #1936529) + + [ Ubuntu: 5.4.0-81.91 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + * large_dir in ext4 broken (LP: #1933074) + - SAUCE: ext4: fix directory index node split corruption + * Some test in kselftest/net on focal source tree were not tested at all + (LP: #1934282) + - selftests/net: add missing tests to Makefile + * curtin: install flash-kernel in arm64 UEFI unexpected (LP: #1918427) + - [Packaging] Allow grub-efi-arm* to satisfy recommends on ARM + * Add l2tp.sh in net from ubuntu_kernel_selftests back (LP: #1934293) + - Revert "UBUNTU: SAUCE: selftests/net -- disable l2tp.sh test" + * icmp_redirect.sh in net from ubuntu_kernel_selftests failed on F-OEM-5.6 / + F-OEM-5.10 / F-OEM-5.13 / F / G / H (LP: #1880645) + - selftests: icmp_redirect: support expected failures + * Focal update: v5.4.128 upstream stable release (LP: #1934179) + - dmaengine: ALTERA_MSGDMA depends on HAS_IOMEM + - dmaengine: QCOM_HIDMA_MGMT depends on HAS_IOMEM + - dmaengine: stedma40: add missing iounmap() on error in d40_probe() + - afs: Fix an IS_ERR() vs NULL check + - mm/memory-failure: make sure wait for page writeback in memory_failure + - kvm: LAPIC: Restore guard to prevent illegal APIC register access + - batman-adv: Avoid WARN_ON timing related checks + - net: ipv4: fix memory leak in netlbl_cipsov4_add_std + - vrf: fix maximum MTU + - net: rds: fix memory leak in rds_recvmsg + - net: lantiq: disable interrupt before sheduling NAPI + - udp: fix race between close() and udp_abort() + - rtnetlink: Fix regression in bridge VLAN configuration + - net/sched: act_ct: handle DNAT tuple collision + - net/mlx5e: Remove dependency in IPsec initialization flows + - net/mlx5e: Fix page reclaim for dead peer hairpin + - net/mlx5: Consider RoCE cap before init RDMA resources + - net/mlx5e: allow TSO on VXLAN over VLAN topologies + - net/mlx5e: Block offload of outer header csum for UDP tunnels + - netfilter: synproxy: Fix out of bounds when parsing TCP options + - sch_cake: Fix out of bounds when parsing TCP options and header + - alx: Fix an error handling path in 'alx_probe()' + - net: stmmac: dwmac1000: Fix extended MAC address registers definition + - net: make get_net_ns return error if NET_NS is disabled + - qlcnic: Fix an error handling path in 'qlcnic_probe()' + - netxen_nic: Fix an error handling path in 'netxen_nic_probe()' + - net: qrtr: fix OOB Read in qrtr_endpoint_post + - ptp: improve max_adj check against unreasonable values + - net: cdc_ncm: switch to eth%d interface naming + - lantiq: net: fix duplicated skb in rx descriptor ring + - net: usb: fix possible use-after-free in smsc75xx_bind + - net: fec_ptp: fix issue caused by refactor the fec_devtype + - net: ipv4: fix memory leak in ip_mc_add1_src + - net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock + - be2net: Fix an error handling path in 'be_probe()' + - net: hamradio: fix memory leak in mkiss_close + - net: cdc_eem: fix tx fixup skb leak + - cxgb4: fix wrong shift. + - bnxt_en: Rediscover PHY capabilities after firmware reset + - bnxt_en: Call bnxt_ethtool_free() in bnxt_init_one() error path + - icmp: don't send out ICMP messages with a source address of 0.0.0.0 + - net: ethernet: fix potential use-after-free in ec_bhf_remove + - regulator: bd70528: Fix off-by-one for buck123 .n_voltages setting + - ASoC: rt5659: Fix the lost powers for the HDA header + - spi: stm32-qspi: Always wait BUSY bit to be cleared in stm32_qspi_wait_cmd() + - pinctrl: ralink: rt2880: avoid to error in calls is pin is already enabled + - radeon: use memcpy_to/fromio for UVD fw upload + - hwmon: (scpi-hwmon) shows the negative temperature properly + - can: bcm: fix infoleak in struct bcm_msg_head + - can: bcm/raw/isotp: use per module netdevice notifier + - can: j1939: fix Use-after-Free, hold skb ref while in use + - can: mcba_usb: fix memory leak in mcba_usb + - usb: core: hub: Disable autosuspend for Cypress CY7C65632 + - tracing: Do not stop recording cmdlines when tracing is off + - tracing: Do not stop recording comms if the trace file is being read + - tracing: Do no increment trace_clock_global() by one + - PCI: Mark TI C667X to avoid bus reset + - PCI: Mark some NVIDIA GPUs to avoid bus reset + - PCI: aardvark: Don't rely on jiffies while holding spinlock + - PCI: aardvark: Fix kernel panic during PIO transfer + - PCI: Add ACS quirk for Broadcom BCM57414 NIC + - PCI: Work around Huawei Intelligent NIC VF FLR erratum + - KVM: x86: Immediately reset the MMU context when the SMM flag is cleared + - ARCv2: save ABI registers across signal handling + - x86/process: Check PF_KTHREAD and not current->mm for kernel threads + - x86/pkru: Write hardware init value to PKRU when xstate is init + - x86/fpu: Reset state for all signal restore failures + - dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc + - cfg80211: make certificate generation more robust + - cfg80211: avoid double free of PMSR request + - net: ll_temac: Make sure to free skb when it is completely used + - net: ll_temac: Fix TX BD buffer overwrite + - net: bridge: fix vlan tunnel dst null pointer dereference + - net: bridge: fix vlan tunnel dst refcnt when egressing + - mm/slub: clarify verification reporting + - mm/slub: fix redzoning for small allocations + - mm/slub.c: include swab.h + - net: stmmac: disable clocks in stmmac_remove_config_dt() + - net: fec_ptp: add clock rate zero check + - tools headers UAPI: Sync linux/in.h copy with the kernel sources + - KVM: arm/arm64: Fix KVM_VGIC_V3_ADDR_TYPE_REDIST read + - ARM: OMAP: replace setup_irq() by request_irq() + - clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support + - clocksource/drivers/timer-ti-dm: Prepare to handle dra7 timer wrap issue + - clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940 + - usb: dwc3: debugfs: Add and remove endpoint dirs dynamically + - usb: dwc3: core: fix kernel panic when do reboot + - Linux 5.4.128 + * linux-azure CIFS DFS oops (LP: #1935833) + - cifs: get rid of unused parameter in reconn_setup_dfs_targets() + - cifs: handle empty list of targets in cifs_reconnect() + * pmtu.sh from net in ubuntu_kernel_selftests failed with no error message + (LP: #1887661) + - selftests: pmtu.sh: improve the test result processing + * cifs: On cifs_reconnect, resolve the hostname again (LP: #1929831) + - cifs: rename reconn_inval_dfs_target() + - cifs: Simplify reconnect code when dfs upcall is enabled + - cifs: Avoid error pointer dereference + - cifs: On cifs_reconnect, resolve the hostname again. + * Pixel format change broken for Elgato Cam Link 4K (LP: #1932367) + - (upstream) media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K + * Focal update: v5.4.127 upstream stable release (LP: #1933851) + - net: ieee802154: fix null deref in parse dev addr + - HID: quirks: Set INCREMENT_USAGE_ON_DUPLICATE for Saitek X65 + - HID: hid-input: add mapping for emoji picker key + - HID: hid-sensor-hub: Return error for hid_set_field() failure + - HID: quirks: Add quirk for Lenovo optical mouse + - HID: multitouch: set Stylus suffix for Stylus-application devices, too + - HID: Add BUS_VIRTUAL to hid_connect logging + - HID: usbhid: fix info leak in hid_submit_ctrl + - drm/tegra: sor: Do not leak runtime PM reference + - ARM: OMAP2+: Fix build warning when mmc_omap is not built + - gfs2: Prevent direct-I/O write fallback errors from getting lost + - HID: gt683r: add missing MODULE_DEVICE_TABLE + - riscv: Use -mno-relax when using lld linker + - gfs2: Fix use-after-free in gfs2_glock_shrink_scan + - scsi: target: core: Fix warning on realtime kernels + - ethernet: myri10ge: Fix missing error code in myri10ge_probe() + - scsi: qedf: Do not put host in qedf_vport_create() unconditionally + - scsi: scsi_devinfo: Add blacklist entry for HPE OPEN-V + - nvme-loop: reset queue count to 1 in nvme_loop_destroy_io_queues() + - nvme-loop: clear NVME_LOOP_Q_LIVE when nvme_loop_configure_admin_queue() + fails + - nvme-loop: check for NVME_LOOP_Q_LIVE in nvme_loop_destroy_admin_queue() + - net: ipconfig: Don't override command-line hostnames or domains + - drm/amd/display: Allow bandwidth validation for 0 streams. + - rtnetlink: Fix missing error code in rtnl_bridge_notify() + - net/x25: Return the correct errno code + - net: Return the correct errno code + - fib: Return the correct errno code + - Linux 5.4.127 + * Focal update: v5.4.126 upstream stable release (LP: #1933369) + - proc: Check /proc/$pid/attr/ writes against file opener + - proc: Track /proc/$pid/attr/ opener mm_struct + - ASoC: max98088: fix ni clock divider calculation + - spi: Fix spi device unregister flow + - net/nfc/rawsock.c: fix a permission check bug + - usb: cdns3: Fix runtime PM imbalance on error + - ASoC: Intel: bytcr_rt5640: Add quirk for the Glavey TM800A550L tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Lenovo Miix 3-830 tablet + - vfio-ccw: Serialize FSM IDLE state with I/O completion + - ASoC: sti-sas: add missing MODULE_DEVICE_TABLE + - spi: sprd: Add missing MODULE_DEVICE_TABLE + - isdn: mISDN: netjet: Fix crash in nj_probe: + - bonding: init notify_work earlier to avoid uninitialized use + - netlink: disable IRQs for netlink_lock_table() + - net: mdiobus: get rid of a BUG_ON() + - cgroup: disable controllers at parse time + - wq: handle VM suspension in stall detection + - net/qla3xxx: fix schedule while atomic in ql_sem_spinlock + - RDS tcp loopback connection can hang + - scsi: bnx2fc: Return failure if io_req is already in ABTS processing + - scsi: vmw_pvscsi: Set correct residual data length + - scsi: hisi_sas: Drop free_irq() of devm_request_irq() allocated irq + - scsi: target: qla2xxx: Wait for stop_phase1 at WWN removal + - net: macb: ensure the device is available before accessing GEMGXL control + registers + - net: appletalk: cops: Fix data race in cops_probe1 + - net: dsa: microchip: enable phy errata workaround on 9567 + - nvme-fabrics: decode host pathing error for connect + - MIPS: Fix kernel hang under FUNCTION_GRAPH_TRACER and PREEMPT_TRACER + - dm verity: fix require_signatures module_param permissions + - bnx2x: Fix missing error code in bnx2x_iov_init_one() + - nvme-tcp: remove incorrect Kconfig dep in BLK_DEV_NVME + - powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P2041 i2c controllers + - powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P1010 i2c controllers + - spi: Don't have controller clean up spi device before driver unbind + - spi: Cleanup on failure of initial setup + - i2c: mpc: Make use of i2c_recover_bus() + - i2c: mpc: implement erratum A-004447 workaround + - x86/boot: Add .text.* to setup.ld + - spi: bcm2835: Fix out-of-bounds access with more than 4 slaves + - drm: Fix use-after-free read in drm_getunique() + - drm: Lock pointer access in drm_master_release() + - kvm: avoid speculation-based attacks from out-of-range memslot accesses + - staging: rtl8723bs: Fix uninitialized variables + - btrfs: return value from btrfs_mark_extent_written() in case of error + - btrfs: promote debugging asserts to full-fledged checks in validate_super + - cgroup1: don't allow '\n' in renaming + - USB: f_ncm: ncm_bitrate (speed) is unsigned + - usb: f_ncm: only first packet of aggregate needs to start timer + - usb: pd: Set PD_T_SINK_WAIT_CAP to 310ms + - usb: dwc3: ep0: fix NULL pointer exception + - usb: musb: fix MUSB_QUIRK_B_DISCONNECT_99 handling + - usb: typec: wcove: Use LE to CPU conversion when accessing msg->header + - usb: typec: ucsi: Clear PPM capability data in ucsi_init() error path + - usb: gadget: f_fs: Ensure io_completion_wq is idle during unbind + - USB: serial: ftdi_sio: add NovaTech OrionMX product ID + - USB: serial: omninet: add device id for Zyxel Omni 56K Plus + - USB: serial: quatech2: fix control-request directions + - USB: serial: cp210x: fix alternate function for CP2102N QFN20 + - usb: gadget: eem: fix wrong eem header operation + - usb: fix various gadgets null ptr deref on 10gbps cabling. + - usb: fix various gadget panics on 10gbps cabling + - regulator: core: resolve supply for boot-on/always-on regulators + - regulator: max77620: Use device_set_of_node_from_dev() + - usb: typec: mux: Fix copy-paste mistake in typec_mux_match + - RDMA/ipoib: Fix warning caused by destroying non-initial netns + - RDMA/mlx4: Do not map the core_clock page to user space unless enabled + - vmlinux.lds.h: Avoid orphan section with !SMP + - perf: Fix data race between pin_count increment/decrement + - sched/fair: Make sure to update tg contrib for blocked load + - KVM: x86: Ensure liveliness of nested VM-Enter fail tracepoint message + - IB/mlx5: Fix initializing CQ fragments buffer + - NFS: Fix a potential NULL dereference in nfs_get_client() + - NFSv4: Fix deadlock between nfs4_evict_inode() and nfs4_opendata_get_inode() + - perf session: Correct buffer copying when peeking events + - kvm: fix previous commit for 32-bit builds + - NFS: Fix use-after-free in nfs4_init_client() + - NFSv4: Fix second deadlock in nfs4_evict_inode() + - NFSv4: nfs4_proc_set_acl needs to restore NFS_CAP_UIDGID_NOMAP on error. + - scsi: core: Fix error handling of scsi_host_alloc() + - scsi: core: Fix failure handling of scsi_add_host_with_dma() + - scsi: core: Put .shost_dev in failure path if host state changes to RUNNING + - scsi: core: Only put parent device if host state differs from SHOST_CREATED + - ftrace: Do not blindly read the ip address in ftrace_bug() + - tracing: Correct the length check which causes memory corruption + - proc: only require mm_struct for writing + - Linux 5.4.126 + * Focal update: v5.4.125 upstream stable release (LP: #1932957) + - btrfs: tree-checker: do not error out if extent ref hash doesn't match + - net: usb: cdc_ncm: don't spew notifications + - ALSA: usb: update old-style static const declaration + - nl80211: validate key indexes for cfg80211_registered_device + - hwmon: (dell-smm-hwmon) Fix index values + - netfilter: conntrack: unregister ipv4 sockopts on error unwind + - efi: Allow EFI_MEMORY_XP and EFI_MEMORY_RO both to be cleared + - efi: cper: fix snprintf() use in cper_dimm_err_location() + - vfio/pci: Fix error return code in vfio_ecap_init() + - vfio/pci: zap_vma_ptes() needs MMU + - samples: vfio-mdev: fix error handing in mdpy_fb_probe() + - vfio/platform: fix module_put call in error flow + - ipvs: ignore IP_VS_SVC_F_HASHED flag when adding service + - HID: pidff: fix error return code in hid_pidff_init() + - HID: i2c-hid: fix format string mismatch + - net/sched: act_ct: Fix ct template allocation for zone 0 + - ACPICA: Clean up context mutex during object deletion + - netfilter: nft_ct: skip expectations for confirmed conntrack + - netfilter: nfnetlink_cthelper: hit EBUSY on updates if size mismatches + - ieee802154: fix error return code in ieee802154_add_iface() + - ieee802154: fix error return code in ieee802154_llsec_getparams() + - ixgbevf: add correct exception tracing for XDP + - ipv6: Fix KASAN: slab-out-of-bounds Read in fib6_nh_flush_exceptions + - ice: write register with correct offset + - ice: Fix VFR issues for AVF drivers that expect ATQLEN cleared + - ice: Allow all LLDP packets from PF to Tx + - i2c: qcom-geni: Add shutdown callback for i2c + - i40e: optimize for XDP_REDIRECT in xsk path + - i40e: add correct exception tracing for XDP + - arm64: dts: ls1028a: fix memory node + - arm64: dts: zii-ultra: fix 12V_MAIN voltage + - ARM: dts: imx7d-meerkat96: Fix the 'tuning-step' property + - ARM: dts: imx7d-pico: Fix the 'tuning-step' property + - ARM: dts: imx: emcon-avari: Fix nxp,pca8574 #gpio-cells + - bus: ti-sysc: Fix flakey idling of uarts and stop using swsup_sidle_act + - tipc: add extack messages for bearer/media failure + - tipc: fix unique bearer names sanity check + - Bluetooth: fix the erroneous flush_work() order + - Bluetooth: use correct lock to prevent UAF of hdev object + - net: caif: added cfserl_release function + - net: caif: add proper error handling + - net: caif: fix memory leak in caif_device_notify + - net: caif: fix memory leak in cfusbl_device_notify + - HID: i2c-hid: Skip ELAN power-on command after reset + - HID: magicmouse: fix NULL-deref on disconnect + - HID: multitouch: require Finger field to mark Win8 reports as MT + - ALSA: timer: Fix master timer notification + - ALSA: hda: Fix for mute key LED for HP Pavilion 15-CK0xx + - ARM: dts: imx6dl-yapp4: Fix RGMII connection to QCA8334 switch + - ARM: dts: imx6q-dhcom: Add PU,VDD1P1,VDD2P5 regulators + - ext4: fix bug on in ext4_es_cache_extent as ext4_split_extent_at failed + - usb: dwc2: Fix build in periphal-only mode + - pid: take a reference when initializing `cad_pid` + - ocfs2: fix data corruption by fallocate + - nfc: fix NULL ptr dereference in llcp_sock_getname() after failed connect + - drm/amdgpu: Don't query CE and UE errors + - drm/amdgpu: make sure we unpin the UVD BO + - x86/apic: Mark _all_ legacy interrupts when IO/APIC is missing + - btrfs: mark ordered extent and inode with error if we fail to finish + - btrfs: fix error handling in btrfs_del_csums + - btrfs: return errors from btrfs_del_csums in cleanup_ref_head + - btrfs: fixup error handling in fixup_inode_link_counts + - mm, hugetlb: fix simple resv_huge_pages underflow on UFFDIO_COPY + - bnxt_en: Remove the setting of dev_port. + - mm: add thp_order + - XArray: add xa_get_order + - XArray: add xas_split + - mm/filemap: fix storing to a THP shadow entry + - btrfs: fix unmountable seed device after fstrim + - KVM: SVM: Truncate GPR value for DR and CR accesses in !64-bit mode + - KVM: arm64: Fix debug register indexing + - lib/lz4: explicitly support in-place decompression + - xen-pciback: redo VF placement in the virtual topology + - i2c: qcom-geni: Suspend and resume the bus during SYSTEM_SLEEP_PM ops + - neighbour: allow NUD_NOARP entries to be forced GCed + - Linux 5.4.125 + + -- Tim Gardner Fri, 23 Jul 2021 10:02:32 -0600 + +linux-oracle (5.4.0-1052.56) focal; urgency=medium + + [ Ubuntu: 5.4.0-80.90 ] + + * CVE-2021-33909 + - SAUCE: seq_file: Disallow extremely large seq buffer allocations + + -- Kleber Sacilotto de Souza Wed, 14 Jul 2021 19:34:46 +0200 + +linux-oracle (5.4.0-1051.55) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1051.55 -proposed tracker (LP: #1934335) + + [ Ubuntu: 5.4.0-79.88 ] + + * focal/linux: 5.4.0-79.88 -proposed tracker (LP: #1934343) + * lxd exec fails (LP: #1934187) + - SAUCE: Revert "proc: Check /proc/$pid/attr/ writes against file opener" + + -- Kelsey Skunberg Fri, 02 Jul 2021 09:59:31 -0600 + +linux-oracle (5.4.0-1050.54) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1050.54 -proposed tracker (LP: #1932470) + + [ Ubuntu: 5.4.0-78.87 ] + + * focal/linux: 5.4.0-78.87 -proposed tracker (LP: #1932478) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + - update dkms package versions + * Disable hv-kvp-daemon.service on certain instance types (LP: #1932081) + - [Packaging]: Add kernel command line condition to hv-kvp-daemon service + * QLogic Direct-Connect host can't discover SCSI-FC or NVMe/FC devices + (LP: #1860724) + - scsi: qla2xxx: Serialize fc_port alloc in N2N + - scsi: qla2xxx: Set Nport ID for N2N + - scsi: qla2xxx: Fix point-to-point (N2N) device discovery issue + - scsi: qla2xxx: Fix N2N and NVMe connect retry failure + * [SRU] Add support for E810 NIC to Ice Driver in Focal (LP: #1912511) + - ice: add additional E810 device id + * Focal update: v5.4.124 upstream stable release (LP: #1931166) + - ALSA: hda/realtek: Headphone volume is controlled by Front mixer + - ALSA: usb-audio: scarlett2: Fix device hang with ehci-pci + - ALSA: usb-audio: scarlett2: Improve driver startup messages + - cifs: set server->cipher_type to AES-128-CCM for SMB3.0 + - NFSv4: Fix a NULL pointer dereference in pnfs_mark_matching_lsegs_return() + - iommu/vt-d: Fix sysfs leak in alloc_iommu() + - perf intel-pt: Fix sample instruction bytes + - perf intel-pt: Fix transaction abort handling + - perf scripts python: exported-sql-viewer.py: Fix copy to clipboard from Top + Calls by elapsed Time report + - perf scripts python: exported-sql-viewer.py: Fix Array TypeError + - perf scripts python: exported-sql-viewer.py: Fix warning display + - proc: Check /proc/$pid/attr/ writes against file opener + - net: hso: fix control-request directions + - ath10k: Validate first subframe of A-MSDU before processing the list + - dm snapshot: properly fix a crash when an origin has no snapshots + - drm/amdgpu/vcn1: add cancel_delayed_work_sync before power gate + - drm/amdgpu/vcn2.0: add cancel_delayed_work_sync before power gate + - drm/amdgpu/vcn2.5: add cancel_delayed_work_sync before power gate + - selftests/gpio: Use TEST_GEN_PROGS_EXTENDED + - selftests/gpio: Move include of lib.mk up + - selftests/gpio: Fix build when source tree is read only + - kgdb: fix gcc-11 warnings harder + - Documentation: seccomp: Fix user notification documentation + - serial: core: fix suspicious security_locked_down() call + - misc/uss720: fix memory leak in uss720_probe + - thunderbolt: dma_port: Fix NVM read buffer bounds and offset issue + - mei: request autosuspend after sending rx flow control + - staging: iio: cdc: ad7746: avoid overwrite of num_channels + - iio: gyro: fxas21002c: balance runtime power in error path + - iio: adc: ad7768-1: Fix too small buffer passed to + iio_push_to_buffers_with_timestamp() + - iio: adc: ad7124: Fix missbalanced regulator enable / disable on error. + - iio: adc: ad7124: Fix potential overflow due to non sequential channel + numbers + - iio: adc: ad7793: Add missing error code in ad7793_setup() + - serial: 8250_pci: Add support for new HPE serial device + - serial: 8250_pci: handle FL_NOIRQ board flag + - USB: trancevibrator: fix control-request direction + - USB: usbfs: Don't WARN about excessively large memory allocations + - serial: tegra: Fix a mask operation that is always true + - serial: sh-sci: Fix off-by-one error in FIFO threshold register setting + - serial: rp2: use 'request_firmware' instead of 'request_firmware_nowait' + - USB: serial: ti_usb_3410_5052: add startech.com device id + - USB: serial: option: add Telit LE910-S1 compositions 0x7010, 0x7011 + - USB: serial: ftdi_sio: add IDs for IDS GmbH Products + - USB: serial: pl2303: add device id for ADLINK ND-6530 GC + - thermal/drivers/intel: Initialize RW trip to THERMAL_TEMP_INVALID + - usb: dwc3: gadget: Properly track pending and queued SG + - usb: gadget: udc: renesas_usb3: Fix a race in usb3_start_pipen() + - net: usb: fix memory leak in smsc75xx_bind + - spi: spi-geni-qcom: Fix use-after-free on unbind + - Bluetooth: cmtp: fix file refcount when cmtp_attach_device fails + - fs/nfs: Use fatal_signal_pending instead of signal_pending + - NFS: fix an incorrect limit in filelayout_decode_layout() + - NFS: Fix an Oopsable condition in __nfs_pageio_add_request() + - NFS: Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() + - NFSv4: Fix v4.0/v4.1 SEEK_DATA return -ENOTSUPP when set NFS_V4_2 config + - drm/meson: fix shutdown crash when component not probed + - net/mlx5e: Fix multipath lag activation + - net/mlx5e: Fix nullptr in add_vlan_push_action() + - net/mlx4: Fix EEPROM dump support + - Revert "net:tipc: Fix a double free in tipc_sk_mcast_rcv" + - tipc: wait and exit until all work queues are done + - tipc: skb_linearize the head skb when reassembling msgs + - spi: spi-fsl-dspi: Fix a resource leak in an error handling path + - net: dsa: mt7530: fix VLAN traffic leaks + - net: dsa: fix a crash if ->get_sset_count() fails + - net: dsa: sja1105: error out on unsupported PHY mode + - i2c: s3c2410: fix possible NULL pointer deref on read message after write + - i2c: i801: Don't generate an interrupt on bus reset + - i2c: sh_mobile: Use new clock calculation formulas for RZ/G2E + - perf jevents: Fix getting maximum number of fds + - platform/x86: hp_accel: Avoid invoking _INI to speed up resume + - gpio: cadence: Add missing MODULE_DEVICE_TABLE + - Revert "media: usb: gspca: add a missed check for goto_low_power" + - Revert "ALSA: sb: fix a missing check of snd_ctl_add" + - Revert "serial: max310x: pass return value of spi_register_driver" + - serial: max310x: unregister uart driver in case of failure and abort + - Revert "net: fujitsu: fix a potential NULL pointer dereference" + - net: fujitsu: fix potential null-ptr-deref + - Revert "net/smc: fix a NULL pointer dereference" + - net: caif: remove BUG_ON(dev == NULL) in caif_xmit + - Revert "char: hpet: fix a missing check of ioremap" + - char: hpet: add checks after calling ioremap + - Revert "ALSA: gus: add a check of the status of snd_ctl_add" + - Revert "ALSA: usx2y: Fix potential NULL pointer dereference" + - Revert "isdn: mISDNinfineon: fix potential NULL pointer dereference" + - isdn: mISDNinfineon: check/cleanup ioremap failure correctly in setup_io + - Revert "ath6kl: return error code in ath6kl_wmi_set_roam_lrssi_cmd()" + - ath6kl: return error code in ath6kl_wmi_set_roam_lrssi_cmd() + - Revert "isdn: mISDN: Fix potential NULL pointer dereference of kzalloc" + - isdn: mISDN: correctly handle ph_info allocation failure in hfcsusb_ph_info + - Revert "dmaengine: qcom_hidma: Check for driver register failure" + - dmaengine: qcom_hidma: comment platform_driver_register call + - Revert "libertas: add checks for the return value of sysfs_create_group" + - libertas: register sysfs groups properly + - Revert "ASoC: cs43130: fix a NULL pointer dereference" + - ASoC: cs43130: handle errors in cs43130_probe() properly + - Revert "media: dvb: Add check on sp8870_readreg" + - media: dvb: Add check on sp8870_readreg return + - Revert "media: gspca: mt9m111: Check write_bridge for timeout" + - media: gspca: mt9m111: Check write_bridge for timeout + - Revert "media: gspca: Check the return value of write_bridge for timeout" + - media: gspca: properly check for errors in po1030_probe() + - Revert "net: liquidio: fix a NULL pointer dereference" + - net: liquidio: Add missing null pointer checks + - Revert "brcmfmac: add a check for the status of usb_register" + - brcmfmac: properly check for bus register errors + - btrfs: return whole extents in fiemap + - scsi: BusLogic: Fix 64-bit system enumeration error for Buslogic + - openrisc: Define memory barrier mb + - btrfs: do not BUG_ON in link_to_fixup_dir + - platform/x86: hp-wireless: add AMD's hardware id to the supported list + - platform/x86: intel_punit_ipc: Append MODULE_DEVICE_TABLE for ACPI + - platform/x86: touchscreen_dmi: Add info for the Mediacom Winpad 7.0 W700 + tablet + - SMB3: incorrect file id in requests compounded with open + - drm/amd/display: Disconnect non-DP with no EDID + - drm/amd/amdgpu: fix refcount leak + - drm/amdgpu: Fix a use-after-free + - drm/amd/amdgpu: fix a potential deadlock in gpu reset + - net: netcp: Fix an error message + - net: dsa: fix error code getting shifted with 4 in dsa_slave_get_sset_count + - ASoC: cs42l42: Regmap must use_single_read/write + - vfio-ccw: Check initialized flag in cp_init() + - net: really orphan skbs tied to closing sk + - net: fec: fix the potential memory leak in fec_enet_init() + - net: mdio: thunder: Fix a double free issue in the .remove function + - net: mdio: octeon: Fix some double free issues + - openvswitch: meter: fix race when getting now_ms. + - tls splice: check SPLICE_F_NONBLOCK instead of MSG_DONTWAIT + - net: sched: fix packet stuck problem for lockless qdisc + - net: sched: fix tx action rescheduling issue during deactivation + - net: sched: fix tx action reschedule issue with stopped queue + - net: hso: check for allocation failure in hso_create_bulk_serial_device() + - net: bnx2: Fix error return code in bnx2_init_board() + - bnxt_en: Include new P5 HV definition in VF check. + - mld: fix panic in mld_newpack() + - gve: Check TX QPL was actually assigned + - gve: Update mgmt_msix_idx if num_ntfy changes + - gve: Add NULL pointer checks when freeing irqs. + - gve: Upgrade memory barrier in poll routine + - gve: Correct SKB queue index validation. + - cxgb4: avoid accessing registers when clearing filters + - staging: emxx_udc: fix loop in _nbu2ss_nuke() + - ASoC: cs35l33: fix an error code in probe() + - bpf: Set mac_len in bpf_skb_change_head + - ixgbe: fix large MTU request from VF + - scsi: libsas: Use _safe() loop in sas_resume_port() + - net: lantiq: fix memory corruption in RX ring + - ipv6: record frag_max_size in atomic fragments in input path + - ALSA: usb-audio: scarlett2: snd_scarlett_gen2_controls_create() can be + static + - net: ethernet: mtk_eth_soc: Fix packet statistics support for MT7628/88 + - sch_dsmark: fix a NULL deref in qdisc_reset() + - MIPS: alchemy: xxs1500: add gpio-au1000.h header file + - MIPS: ralink: export rt_sysc_membase for rt2880_wdt.c + - drm/i915/display: fix compiler warning about array overrun + - i915: fix build warning in intel_dp_get_link_status() + - drivers/net/ethernet: clean up unused assignments + - net: hns3: check the return of skb_checksum_help() + - Revert "Revert "ALSA: usx2y: Fix potential NULL pointer dereference"" + - net: hso: bail out on interrupt URB allocation failure + - neighbour: Prevent Race condition in neighbour subsytem + - usb: core: reduce power-on-good delay time of root hub + - Linux 5.4.124 + * Focal update: v5.4.123 upstream stable release (LP: #1931160) + - usb: dwc3: gadget: Enable suspend events + - perf unwind: Fix separate debug info files when using elfutils' libdw's + unwinder + - perf unwind: Set userdata for all __report_module() paths + - NFC: nci: fix memory leak in nci_allocate_device + - Linux 5.4.123 + * Focal update: v5.4.122 upstream stable release (LP: #1931159) + - firmware: arm_scpi: Prevent the ternary sign expansion bug + - openrisc: Fix a memory leak + - RDMA/siw: Properly check send and receive CQ pointers + - RDMA/siw: Release xarray entry + - RDMA/rxe: Clear all QP fields if creation failed + - scsi: ufs: core: Increase the usable queue depth + - scsi: qla2xxx: Fix error return code in qla82xx_write_flash_dword() + - RDMA/mlx5: Recover from fatal event in dual port mode + - RDMA/core: Don't access cm_id after its destruction + - platform/mellanox: mlxbf-tmfifo: Fix a memory barrier issue + - platform/x86: dell-smbios-wmi: Fix oops on rmmod dell_smbios + - RDMA/uverbs: Fix a NULL vs IS_ERR() bug + - ptrace: make ptrace() fail if the tracee changed its pid unexpectedly + - nvmet: seset ns->file when open fails + - locking/mutex: clear MUTEX_FLAGS if wait_list is empty due to signal + - btrfs: avoid RCU stalls while running delayed iputs + - cifs: fix memory leak in smb2_copychunk_range + - ALSA: dice: fix stream format for TC Electronic Konnekt Live at high + sampling transfer frequency + - ALSA: intel8x0: Don't update period unless prepared + - ALSA: line6: Fix racy initialization of LINE6 MIDI + - ALSA: dice: fix stream format at middle sampling rate for Alesis iO 26 + - ALSA: firewire-lib: fix calculation for size of IR context payload + - ALSA: usb-audio: Validate MS endpoint descriptors + - ALSA: bebob/oxfw: fix Kconfig entry for Mackie d.2 Pro + - ALSA: hda: fixup headset for ASUS GU502 laptop + - Revert "ALSA: sb8: add a check for request_region" + - ALSA: firewire-lib: fix check for the size of isochronous packet payload + - ALSA: hda/realtek: reset eapd coeff to default value for alc287 + - ALSA: hda/realtek: Add some CLOVE SSIDs of ALC293 + - ALSA: hda/realtek: Fix silent headphone output on ASUS UX430UA + - ALSA: hda/realtek: Add fixup for HP OMEN laptop + - ALSA: hda/realtek: Add fixup for HP Spectre x360 15-df0xxx + - uio_hv_generic: Fix a memory leak in error handling paths + - Revert "rapidio: fix a NULL pointer dereference when create_workqueue() + fails" + - rapidio: handle create_workqueue() failure + - Revert "serial: mvebu-uart: Fix to avoid a potential NULL pointer + dereference" + - drm/amdgpu: disable 3DCGCG on picasso/raven1 to avoid compute hang + - drm/amdgpu: update gc golden setting for Navi12 + - drm/amdgpu: update sdma golden setting for Navi12 + - mmc: sdhci-pci-gli: increase 1.8V regulator wait + - xen-pciback: reconfigure also from backend watch handler + - dm snapshot: fix crash with transient storage and zero chunk size + - Revert "video: hgafb: fix potential NULL pointer dereference" + - Revert "net: stmicro: fix a missing check of clk_prepare" + - Revert "leds: lp5523: fix a missing check of return value of lp55xx_read" + - Revert "hwmon: (lm80) fix a missing check of bus read in lm80 probe" + - Revert "video: imsttfb: fix potential NULL pointer dereferences" + - Revert "ecryptfs: replace BUG_ON with error handling code" + - Revert "scsi: ufs: fix a missing check of devm_reset_control_get" + - Revert "gdrom: fix a memory leak bug" + - cdrom: gdrom: deallocate struct gdrom_unit fields in remove_gdrom + - cdrom: gdrom: initialize global variable at init time + - Revert "media: rcar_drif: fix a memory disclosure" + - Revert "rtlwifi: fix a potential NULL pointer dereference" + - Revert "qlcnic: Avoid potential NULL pointer dereference" + - Revert "niu: fix missing checks of niu_pci_eeprom_read" + - ethernet: sun: niu: fix missing checks of niu_pci_eeprom_read() + - net: stmicro: handle clk_prepare() failure during init + - scsi: ufs: handle cleanup correctly on devm_reset_control_get error + - net: rtlwifi: properly check for alloc_workqueue() failure + - ics932s401: fix broken handling of errors when word reading fails + - leds: lp5523: check return value of lp5xx_read and jump to cleanup code + - qlcnic: Add null check after calling netdev_alloc_skb + - video: hgafb: fix potential NULL pointer dereference + - vgacon: Record video mode changes with VT_RESIZEX + - vt: Fix character height handling with VT_RESIZEX + - tty: vt: always invoke vc->vc_sw->con_resize callback + - nvme-multipath: fix double initialization of ANA state + - ext4: fix error handling in ext4_end_enable_verity() + - Bluetooth: L2CAP: Fix handling LE modes by L2CAP_OPTIONS + - nvmet: use new ana_log_size instead the old one + - video: hgafb: correctly handle card detect failure during probe + - Bluetooth: SMP: Fail if remote and local public keys are identical + - Linux 5.4.122 + * Focal update: v5.4.121 upstream stable release (LP: #1931158) + - x86/msr: Fix wr/rdmsr_safe_regs_on_cpu() prototypes + - kgdb: fix gcc-11 warning on indentation + - usb: sl811-hcd: improve misleading indentation + - cxgb4: Fix the -Wmisleading-indentation warning + - isdn: capi: fix mismatched prototypes + - pinctrl: ingenic: Improve unreachable code generation + - xsk: Simplify detection of empty and full rings + - virtio_net: Do not pull payload in skb->head + - PCI: thunder: Fix compile testing + - dmaengine: dw-edma: Fix crash on loading/unloading driver + - ARM: 9066/1: ftrace: pause/unpause function graph tracer in cpu_suspend() + - ACPI / hotplug / PCI: Fix reference count leak in enable_slot() + - Input: elants_i2c - do not bind to i2c-hid compatible ACPI instantiated + devices + - Input: silead - add workaround for x86 BIOS-es which bring the chip up in a + stuck state + - um: Mark all kernel symbols as local + - um: Disable CONFIG_GCOV with MODULES + - ARM: 9075/1: kernel: Fix interrupted SMC calls + - scripts/recordmcount.pl: Fix RISC-V regex for clang + - riscv: Workaround mcount name prior to clang-13 + - scsi: lpfc: Fix illegal memory access on Abort IOCBs + - ceph: fix fscache invalidation + - scsi: target: tcmu: Return from tcmu_handle_completions() if cmd_id not + found + - bridge: Fix possible races between assigning rx_handler_data and setting + IFF_BRIDGE_PORT bit + - drm/amd/display: Fix two cursor duplication when using overlay + - gpiolib: acpi: Add quirk to ignore EC wakeups on Dell Venue 10 Pro 5055 + - ALSA: hda: generic: change the DAC ctl name for LO+SPK or LO+HP + - block: reexpand iov_iter after read/write + - lib: stackdepot: turn depot_lock spinlock to raw_spinlock + - net: stmmac: Do not enable RX FIFO overflow interrupts + - ip6_gre: proper dev_{hold|put} in ndo_[un]init methods + - sit: proper dev_{hold|put} in ndo_[un]init methods + - ip6_tunnel: sit: proper dev_{hold|put} in ndo_[un]init methods + - ipv6: remove extra dev_hold() for fallback tunnels + - KVM: arm64: Initialize VCPU mdcr_el2 before loading it + - tweewide: Fix most Shebang lines + - scripts: switch explicitly to Python 3 + - Linux 5.4.121 + * Focal update: v5.4.120 upstream stable release (LP: #1930474) + - tpm: fix error return code in tpm2_get_cc_attrs_tbl() + - tpm, tpm_tis: Extend locality handling to TPM2 in tpm_tis_gen_interrupt() + - tpm, tpm_tis: Reserve locality in tpm_tis_resume() + - KVM: x86/mmu: Remove the defunct update_pte() paging hook + - PM: runtime: Fix unpaired parent child_count for force_resume + - fs: dlm: fix debugfs dump + - tipc: convert dest node's address to network order + - ASoC: Intel: bytcr_rt5640: Enable jack-detect support on Asus T100TAF + - net: stmmac: Set FIFO sizes for ipq806x + - ASoC: rsnd: core: Check convert rate in rsnd_hw_params + - i2c: bail out early when RDWR parameters are wrong + - ALSA: hdsp: don't disable if not enabled + - ALSA: hdspm: don't disable if not enabled + - ALSA: rme9652: don't disable if not enabled + - ALSA: bebob: enable to deliver MIDI messages for multiple ports + - Bluetooth: Set CONF_NOT_COMPLETE as l2cap_chan default + - Bluetooth: initialize skb_queue_head at l2cap_chan_create() + - net: bridge: when suppression is enabled exclude RARP packets + - Bluetooth: check for zapped sk before connecting + - ip6_vti: proper dev_{hold|put} in ndo_[un]init methods + - ASoC: Intel: bytcr_rt5640: Add quirk for the Chuwi Hi8 tablet + - i2c: Add I2C_AQ_NO_REP_START adapter quirk + - mac80211: clear the beacon's CRC after channel switch + - pinctrl: samsung: use 'int' for register masks in Exynos + - mt76: mt76x0: disable GTK offloading + - cuse: prevent clone + - ASoC: rsnd: call rsnd_ssi_master_clk_start() from rsnd_ssi_init() + - Revert "iommu/amd: Fix performance counter initialization" + - iommu/amd: Remove performance counter pre-initialization test + - drm/amd/display: Force vsync flip when reconfiguring MPCC + - selftests: Set CC to clang in lib.mk if LLVM is set + - kconfig: nconf: stop endless search loops + - ALSA: hda/hdmi: fix race in handling acomp ELD notification at resume + - sctp: Fix out-of-bounds warning in sctp_process_asconf_param() + - flow_dissector: Fix out-of-bounds warning in __skb_flow_bpf_to_target() + - powerpc/smp: Set numa node before updating mask + - ASoC: rt286: Generalize support for ALC3263 codec + - ethtool: ioctl: Fix out-of-bounds warning in store_link_ksettings_for_user() + - net: sched: tapr: prevent cycle_time == 0 in parse_taprio_schedule + - samples/bpf: Fix broken tracex1 due to kprobe argument change + - powerpc/pseries: Stop calling printk in rtas_stop_self() + - drm/amd/display: fixed divide by zero kernel crash during dsc enablement + - wl3501_cs: Fix out-of-bounds warnings in wl3501_send_pkt + - wl3501_cs: Fix out-of-bounds warnings in wl3501_mgmt_join + - qtnfmac: Fix possible buffer overflow in qtnf_event_handle_external_auth + - powerpc/iommu: Annotate nested lock for lockdep + - iavf: remove duplicate free resources calls + - net: ethernet: mtk_eth_soc: fix RX VLAN offload + - bnxt_en: Add PCI IDs for Hyper-V VF devices. + - ia64: module: fix symbolizer crash on fdescr + - ASoC: rt286: Make RT286_SET_GPIO_* readable and writable + - thermal: thermal_of: Fix error return code of + thermal_of_populate_bind_params() + - f2fs: fix a redundant call to f2fs_balance_fs if an error occurs + - PCI: iproc: Fix return value of iproc_msi_irq_domain_alloc() + - PCI: Release OF node in pci_scan_device()'s error path + - ARM: 9064/1: hw_breakpoint: Do not directly check the event's + overflow_handler hook + - rpmsg: qcom_glink_native: fix error return code of qcom_glink_rx_data() + - NFSv4.2: Always flush out writes in nfs42_proc_fallocate() + - NFS: Deal correctly with attribute generation counter overflow + - PCI: endpoint: Fix missing destroy_workqueue() + - pNFS/flexfiles: fix incorrect size check in decode_nfs_fh() + - NFSv4.2 fix handling of sr_eof in SEEK's reply + - rtc: fsl-ftm-alarm: add MODULE_TABLE() + - ceph: fix inode leak on getattr error in __fh_to_dentry + - rtc: ds1307: Fix wday settings for rx8130 + - net: hns3: fix incorrect configuration for igu_egu_hw_err + - net: hns3: initialize the message content in hclge_get_link_mode() + - net: hns3: add check for HNS3_NIC_STATE_INITED in + hns3_reset_notify_up_enet() + - net: hns3: fix for vxlan gpe tx checksum bug + - net: hns3: use netif_tx_disable to stop the transmit queue + - net: hns3: disable phy loopback setting in hclge_mac_start_phy + - sctp: do asoc update earlier in sctp_sf_do_dupcook_a + - RISC-V: Fix error code returned by riscv_hartid_to_cpuid() + - sunrpc: Fix misplaced barrier in call_decode + - ethernet:enic: Fix a use after free bug in enic_hard_start_xmit + - sctp: fix a SCTP_MIB_CURRESTAB leak in sctp_sf_do_dupcook_b + - netfilter: xt_SECMARK: add new revision to fix structure layout + - drm/radeon: Fix off-by-one power_state index heap overwrite + - drm/radeon: Avoid power table parsing memory leaks + - khugepaged: fix wrong result value for trace_mm_collapse_huge_page_isolate() + - mm/hugeltb: handle the error case in hugetlb_fix_reserve_counts() + - mm/migrate.c: fix potential indeterminate pte entry in + migrate_vma_insert_page() + - ksm: fix potential missing rmap_item for stable_node + - net: fix nla_strcmp to handle more then one trailing null character + - smc: disallow TCP_ULP in smc_setsockopt() + - netfilter: nfnetlink_osf: Fix a missing skb_header_pointer() NULL check + - can: m_can: m_can_tx_work_queue(): fix tx_skb race condition + - sched: Fix out-of-bound access in uclamp + - sched/fair: Fix unfairness caused by missing load decay + - kernel: kexec_file: fix error return code of kexec_calculate_store_digests() + - netfilter: nftables: avoid overflows in nft_hash_buckets() + - i40e: Fix use-after-free in i40e_client_subtask() + - i40e: fix the restart auto-negotiation after FEC modified + - i40e: Fix PHY type identifiers for 2.5G and 5G adapters + - ARC: entry: fix off-by-one error in syscall number validation + - ARC: mm: PAE: use 40-bit physical page mask + - powerpc/64s: Fix crashes when toggling stf barrier + - powerpc/64s: Fix crashes when toggling entry flush barrier + - hfsplus: prevent corruption in shrinking truncate + - squashfs: fix divide error in calculate_skip() + - userfaultfd: release page in error path to avoid BUG_ON + - mm/hugetlb: fix F_SEAL_FUTURE_WRITE + - drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors + are connected + - drm/i915: Avoid div-by-zero on gen2 + - iio: proximity: pulsedlight: Fix rumtime PM imbalance on error + - usb: fotg210-hcd: Fix an error message + - hwmon: (occ) Fix poll rate limiting + - ACPI: scan: Fix a memory leak in an error handling path + - kyber: fix out of bounds access when preempted + - nbd: Fix NULL pointer in flush_workqueue + - blk-mq: Swap two calls in blk_mq_exit_queue() + - iomap: fix sub-page uptodate handling + - usb: dwc3: omap: improve extcon initialization + - usb: dwc3: pci: Enable usb2-gadget-lpm-disable for Intel Merrifield + - usb: xhci: Increase timeout for HC halt + - usb: dwc2: Fix gadget DMA unmap direction + - usb: core: hub: fix race condition about TRSMRCY of resume + - usb: dwc3: gadget: Return success always for kick transfer in ep queue + - xhci: Do not use GFP_KERNEL in (potentially) atomic context + - xhci: Add reset resume quirk for AMD xhci controller. + - iio: gyro: mpu3050: Fix reported temperature value + - iio: tsl2583: Fix division by a zero lux_val + - cdc-wdm: untangle a circular dependency between callback and softint + - KVM: x86: Cancel pvclock_gtod_work on module removal + - mm: fix struct page layout on 32-bit systems + - FDDI: defxx: Make MMIO the configuration default except for EISA + - MIPS: Reinstate platform `__div64_32' handler + - MIPS: Avoid DIVU in `__div64_32' is result would be zero + - MIPS: Avoid handcoded DIVU in `__div64_32' altogether + - thermal/core/fair share: Lock the thermal zone while looping over instances + - f2fs: fix error handling in f2fs_end_enable_verity() + - ARM: 9011/1: centralize phys-to-virt conversion of DT/ATAGS address + - ARM: 9012/1: move device tree mapping out of linear region + - ARM: 9020/1: mm: use correct section size macro to describe the FDT virtual + address + - ARM: 9027/1: head.S: explicitly map DT even if it lives in the first + physical section + - usb: typec: tcpm: Fix error while calculating PPS out values + - kobject_uevent: remove warning in init_uevent_argv() + - netfilter: conntrack: Make global sysctls readonly in non-init netns + - clk: exynos7: Mark aclk_fsys1_200 as critical + - nvme: do not try to reconfigure APST when the controller is not live + - ASoC: rsnd: check all BUSIF status when error + - Linux 5.4.120 + * scsi: storvsc: Parameterize number hardware queues (LP: #1930626) + - scsi: storvsc: Parameterize number hardware queues + + -- Dimitri John Ledkov Wed, 30 Jun 2021 10:58:18 +0100 + +linux-oracle (5.4.0-1049.53) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1049.53 -proposed tracker (LP: #1933407) + + * iscsi-related backports requested for Oracle-cloud (LP: #1931959) + - scsi: core: Add limitless cmd retry support + - scsi: sd: Allow user to configure command retries + + * Oracle kernel has Android related config options disabled (LP: #1928686) + - [config] oracle: Enable Android options for anbox + + -- Khalid Elmously Thu, 24 Jun 2021 00:22:51 -0400 + +linux-oracle (5.4.0-1048.52) focal; urgency=medium + + [ Ubuntu: 5.4.0-77.86 ] + + * UAF on CAN J1939 j1939_can_recv (LP: #1932209) + - SAUCE: can: j1939: delay release of j1939_priv after synchronize_rcu + * UAF on CAN BCM bcm_rx_handler (LP: #1931855) + - SAUCE: can: bcm: delay release of struct bcm_op after synchronize_rcu + + [ Ubuntu: 5.4.0-76.85 ] + + * focal/linux: 5.4.0-76.85 -proposed tracker (LP: #1932123) + * Upstream v5.9 introduced 'module' patches that removed exported symbols + (LP: #1932065) + - SAUCE: Revert "modules: inherit TAINT_PROPRIETARY_MODULE" + - SAUCE: Revert "modules: return licensing information from find_symbol" + - SAUCE: Revert "modules: rename the licence field in struct symsearch to + license" + - SAUCE: Revert "modules: unexport __module_address" + - SAUCE: Revert "modules: unexport __module_text_address" + - SAUCE: Revert "modules: mark each_symbol_section static" + - SAUCE: Revert "modules: mark find_symbol static" + - SAUCE: Revert "modules: mark ref_module static" + + -- Stefan Bader Thu, 17 Jun 2021 21:27:15 +0200 + +linux-oracle (5.4.0-1047.51) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1047.51 -proposed tracker (LP: #1930024) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-75.84 ] + + * focal/linux: 5.4.0-75.84 -proposed tracker (LP: #1930032) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CVE-2021-33200 + - bpf: Wrap aux data inside bpf_sanitize_info container + - bpf: Fix mask direction swap upon off reg sign change + - bpf: No need to simulate speculative domain for immediates + * Realtek USB hubs in Dell WD19SC/DC/TB fail to work after exiting s2idle + (LP: #1928242) + - USB: Verify the port status when timeout happens during port suspend + * CVE-2020-26145 + - ath10k: drop fragments with multicast DA for SDIO + - ath10k: add CCMP PN replay protection for fragmented frames for PCIe + - ath10k: drop fragments with multicast DA for PCIe + * CVE-2020-26141 + - ath10k: Fix TKIP Michael MIC verification for PCIe + * CVE-2020-24588 + - mac80211: properly handle A-MSDUs that start with an RFC 1042 header + - cfg80211: mitigate A-MSDU aggregation attacks + - mac80211: drop A-MSDUs on old ciphers + - ath10k: drop MPDU which has discard flag set by firmware for SDIO + * CVE-2020-26139 + - mac80211: do not accept/forward invalid EAPOL frames + * CVE-2020-24586 // CVE-2020-24587 // CVE-2020-24587 for such cases. + - mac80211: extend protection against mixed key and fragment cache attacks + * CVE-2020-24586 // CVE-2020-24587 + - mac80211: prevent mixed key and fragment cache attacks + - mac80211: add fragment cache to sta_info + - mac80211: check defrag PN against current frame + - mac80211: prevent attacks on TKIP/WEP as well + * CVE-2020-26147 + - mac80211: assure all fragments are encrypted + * raid10: Block discard is very slow, causing severe delays for mkfs and + fstrim operations (LP: #1896578) + - md: add md_submit_discard_bio() for submitting discard bio + - md/raid10: extend r10bio devs to raid disks + - md/raid10: pull the code that wait for blocked dev into one function + - md/raid10: improve raid10 discard request + - md/raid10: improve discard request for far layout + - dm raid: remove unnecessary discard limits for raid0 and raid10 + * [SRU] mpt3sas: only one vSES is handy even IOC has multi vSES (LP: #1926517) + - scsi: mpt3sas: Only one vSES is present even when IOC has multi vSES + * kvm: properly tear down PV features on hibernate (LP: #1920944) + - x86/kvm: Fix pr_info() for async PF setup/teardown + - x86/kvm: Teardown PV features on boot CPU as well + - x86/kvm: Disable kvmclock on all CPUs on shutdown + - x86/kvm: Disable all PV features on crash + - x86/kvm: Unify kvm_pv_guest_cpu_reboot() with kvm_guest_cpu_offline() + * Focal update: v5.4.119 upstream stable release (LP: #1929615) + - Bluetooth: verify AMP hci_chan before amp_destroy + - hsr: use netdev_err() instead of WARN_ONCE() + - bluetooth: eliminate the potential race condition when removing the HCI + controller + - net/nfc: fix use-after-free llcp_sock_bind/connect + - Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL" + - tty: moxa: fix TIOCSSERIAL jiffies conversions + - tty: amiserial: fix TIOCSSERIAL permission check + - USB: serial: usb_wwan: fix TIOCSSERIAL jiffies conversions + - staging: greybus: uart: fix TIOCSSERIAL jiffies conversions + - USB: serial: ti_usb_3410_5052: fix TIOCSSERIAL permission check + - staging: fwserial: fix TIOCSSERIAL jiffies conversions + - tty: moxa: fix TIOCSSERIAL permission check + - staging: fwserial: fix TIOCSSERIAL permission check + - usb: typec: tcpm: Address incorrect values of tcpm psy for fixed supply + - usb: typec: tcpm: Address incorrect values of tcpm psy for pps supply + - usb: typec: tcpm: update power supply once partner accepts + - usb: xhci-mtk: remove or operator for setting schedule parameters + - usb: xhci-mtk: improve bandwidth scheduling with TT + - ASoC: samsung: tm2_wm5110: check of of_parse return value + - ASoC: Intel: kbl_da7219_max98927: Fix kabylake_ssp_fixup function + - MIPS: pci-mt7620: fix PLL lock check + - MIPS: pci-rt2880: fix slot 0 configuration + - FDDI: defxx: Bail out gracefully with unassigned PCI resource for CSR + - PCI: Allow VPD access for QLogic ISP2722 + - iio:accel:adis16201: Fix wrong axis assignment that prevents loading + - misc: lis3lv02d: Fix false-positive WARN on various HP models + - misc: vmw_vmci: explicitly initialize vmci_notify_bm_set_msg struct + - misc: vmw_vmci: explicitly initialize vmci_datagram payload + - md/bitmap: wait for external bitmap writes to complete during tear down + - md-cluster: fix use-after-free issue when removing rdev + - md: split mddev_find + - md: factor out a mddev_find_locked helper from mddev_find + - md: md_open returns -EBUSY when entering racing area + - md: Fix missing unused status line of /proc/mdstat + - ipw2x00: potential buffer overflow in libipw_wx_set_encodeext() + - cfg80211: scan: drop entry from hidden_list on overflow + - rtw88: Fix array overrun in rtw_get_tx_power_params() + - drm/panfrost: Clear MMU irqs before handling the fault + - drm/panfrost: Don't try to map pages that are already mapped + - drm/radeon: fix copy of uninitialized variable back to userspace + - drm/amd/display: Reject non-zero src_y and src_x for video planes + - ALSA: hda/realtek: Re-order ALC882 Acer quirk table entries + - ALSA: hda/realtek: Re-order ALC882 Sony quirk table entries + - ALSA: hda/realtek: Re-order ALC882 Clevo quirk table entries + - ALSA: hda/realtek: Re-order ALC269 HP quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Acer quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Dell quirk table entries + - ALSA: hda/realtek: Re-order ALC269 ASUS quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Sony quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Lenovo quirk table entries + - ALSA: hda/realtek: Re-order remaining ALC269 quirk table entries + - ALSA: hda/realtek: Re-order ALC662 quirk table entries + - ALSA: hda/realtek: Remove redundant entry for ALC861 Haier/Uniwill devices + - ALSA: hda/realtek: ALC285 Thinkpad jack pin quirk is unreachable + - KVM: s390: split kvm_s390_logical_to_effective + - KVM: s390: fix guarded storage control register handling + - s390: fix detection of vector enhancements facility 1 vs. vector packed + decimal facility + - KVM: s390: split kvm_s390_real_to_abs + - KVM: nVMX: Truncate bits 63:32 of VMCS field on nested check in !64-bit + - KVM: Stop looking for coalesced MMIO zones if the bus is destroyed + - Revert "i3c master: fix missing destroy_workqueue() on error in + i3c_master_register" + - ovl: fix missing revert_creds() on error path + - usb: gadget: pch_udc: Revert d3cb25a12138 completely + - memory: gpmc: fix out of bounds read and dereference on gpmc_cs[] + - ARM: dts: exynos: correct fuel gauge interrupt trigger level on Midas family + - ARM: dts: exynos: correct MUIC interrupt trigger level on Midas family + - ARM: dts: exynos: correct PMIC interrupt trigger level on Midas family + - ARM: dts: exynos: correct PMIC interrupt trigger level on Odroid X/U3 family + - ARM: dts: exynos: correct PMIC interrupt trigger level on SMDK5250 + - ARM: dts: exynos: correct PMIC interrupt trigger level on Snow + - serial: stm32: fix incorrect characters on console + - serial: stm32: fix tx_empty condition + - usb: typec: tcpci: Check ROLE_CONTROL while interpreting CC_STATUS + - regmap: set debugfs_name to NULL after it is freed + - mtd: rawnand: fsmc: Fix error code in fsmc_nand_probe() + - mtd: rawnand: brcmnand: fix OOB R/W with Hamming ECC + - mtd: Handle possible -EPROBE_DEFER from parse_mtd_partitions() + - mtd: rawnand: qcom: Return actual error code instead of -ENODEV + - arm64: dts: qcom: sm8150: fix number of pins in 'gpio-ranges' + - spi: stm32: drop devres version of spi_register_master + - arm64: dts: renesas: r8a77980: Fix vin4-7 endpoint binding + - x86/microcode: Check for offline CPUs before requesting new microcode + - usb: gadget: pch_udc: Replace cpu_to_le32() by lower_32_bits() + - usb: gadget: pch_udc: Check if driver is present before calling ->setup() + - usb: gadget: pch_udc: Check for DMA mapping error + - crypto: qat - don't release uninitialized resources + - crypto: qat - ADF_STATUS_PF_RUNNING should be set after adf_dev_init + - fotg210-udc: Fix DMA on EP0 for length > max packet size + - fotg210-udc: Fix EP0 IN requests bigger than two packets + - fotg210-udc: Remove a dubious condition leading to fotg210_done + - fotg210-udc: Mask GRP2 interrupts we don't handle + - fotg210-udc: Don't DMA more than the buffer can take + - fotg210-udc: Complete OUT requests on short packets + - mtd: require write permissions for locking and badblock ioctls + - bus: qcom: Put child node before return + - soundwire: bus: Fix device found flag correctly + - phy: marvell: ARMADA375_USBCLUSTER_PHY should not default to y, + unconditionally + - crypto: qat - fix error path in adf_isr_resource_alloc() + - usb: gadget: aspeed: fix dma map failure + - USB: gadget: udc: fix wrong pointer passed to IS_ERR() and PTR_ERR() + - memory: pl353: fix mask of ECC page_size config register + - soundwire: stream: fix memory leak in stream config error path + - m68k: mvme147,mvme16x: Don't wipe PCC timer config bits + - mtd: rawnand: gpmi: Fix a double free in gpmi_nand_init + - irqchip/gic-v3: Fix OF_BAD_ADDR error handling + - staging: rtl8192u: Fix potential infinite loop + - staging: greybus: uart: fix unprivileged TIOCCSERIAL + - PM / devfreq: Use more accurate returned new_freq as resume_freq + - spi: Fix use-after-free with devm_spi_alloc_* + - soc: qcom: mdt_loader: Validate that p_filesz < p_memsz + - soc: qcom: mdt_loader: Detect truncated read of segments + - ACPI: CPPC: Replace cppc_attr with kobj_attribute + - crypto: qat - Fix a double free in adf_create_ring + - cpufreq: armada-37xx: Fix setting TBG parent for load levels + - clk: mvebu: armada-37xx-periph: remove .set_parent method for CPU PM clock + - cpufreq: armada-37xx: Fix the AVS value for load L1 + - clk: mvebu: armada-37xx-periph: Fix switching CPU freq from 250 Mhz to 1 GHz + - clk: mvebu: armada-37xx-periph: Fix workaround for switching from L1 to L0 + - cpufreq: armada-37xx: Fix driver cleanup when registration failed + - cpufreq: armada-37xx: Fix determining base CPU frequency + - spi: fsl-lpspi: Fix PM reference leak in lpspi_prepare_xfer_hardware() + - usb: gadget: r8a66597: Add missing null check on return from + platform_get_resource + - USB: cdc-acm: fix unprivileged TIOCCSERIAL + - USB: cdc-acm: fix TIOCGSERIAL implementation + - tty: fix return value for unsupported ioctls + - serial: core: return early on unsupported ioctls + - firmware: qcom-scm: Fix QCOM_SCM configuration + - node: fix device cleanups in error handling code + - usbip: vudc: fix missing unlock on error in usbip_sockfd_store() + - platform/x86: pmc_atom: Match all Beckhoff Automation baytrail boards with + critclk_systems DMI table + - x86/platform/uv: Fix !KEXEC build failure + - usb: dwc2: Fix host mode hibernation exit with remote wakeup flow. + - usb: dwc2: Fix hibernation between host and device modes. + - ttyprintk: Add TTY hangup callback. + - xen-blkback: fix compatibility bug with single page rings + - soc: aspeed: fix a ternary sign expansion bug + - media: vivid: fix assignment of dev->fbuf_out_flags + - media: omap4iss: return error code when omap4iss_get() failed + - media: aspeed: fix clock handling logic + - media: platform: sunxi: sun6i-csi: fix error return code of + sun6i_video_start_streaming() + - media: m88rs6000t: avoid potential out-of-bounds reads on arrays + - drm/amdkfd: fix build error with AMD_IOMMU_V2=m + - x86/kprobes: Fix to check non boostable prefixes correctly + - pata_arasan_cf: fix IRQ check + - pata_ipx4xx_cf: fix IRQ check + - sata_mv: add IRQ checks + - ata: libahci_platform: fix IRQ check + - nvme-tcp: block BH in sk state_change sk callback + - nvmet-tcp: fix incorrect locking in state_change sk callback + - nvme: retrigger ANA log update if group descriptor isn't found + - media: v4l2-ctrls.c: fix race condition in hdl->requests list + - vfio/mdev: Do not allow a mdev_type to have a NULL parent pointer + - clk: zynqmp: move zynqmp_pll_set_mode out of round_rate callback + - clk: qcom: a53-pll: Add missing MODULE_DEVICE_TABLE + - clk: uniphier: Fix potential infinite loop + - scsi: hisi_sas: Fix IRQ checks + - scsi: jazz_esp: Add IRQ check + - scsi: sun3x_esp: Add IRQ check + - scsi: sni_53c710: Add IRQ check + - scsi: ibmvfc: Fix invalid state machine BUG_ON() + - mfd: stm32-timers: Avoid clearing auto reload register + - nvme-pci: don't simple map sgl when sgls are disabled + - HSI: core: fix resource leaks in hsi_add_client_from_dt() + - x86/events/amd/iommu: Fix sysfs type mismatch + - sched/debug: Fix cgroup_path[] serialization + - drivers/block/null_blk/main: Fix a double free in null_init. + - HID: plantronics: Workaround for double volume key presses + - perf symbols: Fix dso__fprintf_symbols_by_name() to return the number of + printed chars + - net: lapbether: Prevent racing when checking whether the netif is running + - powerpc/fadump: Mark fadump_calculate_reserve_size as __init + - powerpc/prom: Mark identical_pvr_fixup as __init + - inet: use bigger hash table for IP ID generation + - powerpc: Fix HAVE_HARDLOCKUP_DETECTOR_ARCH build configuration + - ALSA: core: remove redundant spin_lock pair in snd_card_disconnect + - bug: Remove redundant condition check in report_bug + - nfc: pn533: prevent potential memory corruption + - net: hns3: Limiting the scope of vector_ring_chain variable + - mips: bmips: fix syscon-reboot nodes + - ALSA: usb-audio: Add error checks for usb_driver_claim_interface() calls + - ASoC: simple-card: fix possible uninitialized single_cpu local variable + - liquidio: Fix unintented sign extension of a left shift of a u16 + - powerpc/64s: Fix pte update for kernel memory on radix + - powerpc/perf: Fix PMU constraint check for EBB events + - powerpc: iommu: fix build when neither PCI or IBMVIO is set + - mac80211: bail out if cipher schemes are invalid + - mt7601u: fix always true expression + - KVM: PPC: Book3S HV P9: Restore host CTRL SPR after guest exit + - RDMA/qedr: Fix error return code in qedr_iw_connect() + - IB/hfi1: Fix error return code in parse_platform_config() + - cxgb4: Fix unintentional sign extension issues + - net: thunderx: Fix unintentional sign extension issue + - RDMA/srpt: Fix error return code in srpt_cm_req_recv() + - i2c: img-scb: fix reference leak when pm_runtime_get_sync fails + - i2c: imx-lpi2c: fix reference leak when pm_runtime_get_sync fails + - i2c: omap: fix reference leak when pm_runtime_get_sync fails + - i2c: sprd: fix reference leak when pm_runtime_get_sync fails + - i2c: cadence: add IRQ check + - i2c: emev2: add IRQ check + - i2c: jz4780: add IRQ check + - i2c: sh7760: add IRQ check + - powerpc/xive: Fix xmon command "dxi" + - ASoC: ak5558: correct reset polarity + - drm/i915/gvt: Fix error code in intel_gvt_init_device() + - perf beauty: Fix fsconfig generator + - MIPS: pci-legacy: stop using of_pci_range_to_resource + - powerpc/pseries: extract host bridge from pci_bus prior to bus removal + - rtlwifi: 8821ae: upgrade PHY and RF parameters + - i2c: sh7760: fix IRQ error path + - mwl8k: Fix a double Free in mwl8k_probe_hw + - vsock/vmci: log once the failed queue pair allocation + - gro: fix napi_gro_frags() Fast GRO breakage due to IP alignment check + - RDMA/cxgb4: add missing qpid increment + - RDMA/i40iw: Fix error unwinding when i40iw_hmc_sd_one fails + - ALSA: usb: midi: don't return -ENOMEM when usb_urb_ep_type_check fails + - net: davinci_emac: Fix incorrect masking of tx and rx error channel + - net: renesas: ravb: Fix a stuck issue when a lot of frames are received + - net: phy: intel-xway: enable integrated led functions + - ath9k: Fix error check in ath9k_hw_read_revisions() for PCI devices + - ath10k: Fix ath10k_wmi_tlv_op_pull_peer_stats_info() unlock without lock + - powerpc/52xx: Fix an invalid ASM expression ('addi' used instead of 'add') + - bnxt_en: fix ternary sign extension bug in bnxt_show_temp() + - ARM: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins for + RTL8211E + - arm64: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins for + RTL8211E + - net: geneve: modify IP header check in geneve6_xmit_skb and geneve_xmit_skb + - selftests: net: mirror_gre_vlan_bridge_1q: Make an FDB entry static + - bnxt_en: Fix RX consumer index logic in the error path. + - net:emac/emac-mac: Fix a use after free in emac_mac_tx_buf_send + - RDMA/siw: Fix a use after free in siw_alloc_mr + - RDMA/bnxt_re: Fix a double free in bnxt_qplib_alloc_res + - net: bridge: mcast: fix broken length + header check for MRDv6 Adv. + - net:nfc:digital: Fix a double free in digital_tg_recv_dep_req + - kfifo: fix ternary sign extension bugs + - mm/sparse: add the missing sparse_buffer_fini() in error branch + - mm/memory-failure: unnecessary amount of unmapping + - net: Only allow init netns to set default tcp cong to a restricted algo + - smp: Fix smp_call_function_single_async prototype + - Revert "net/sctp: fix race condition in sctp_destroy_sock" + - sctp: delay auto_asconf init until binding the first addr + - Revert "of/fdt: Make sure no-map does not remove already reserved regions" + - Revert "fdt: Properly handle "no-map" field in the memory region" + - Linux 5.4.119 + * seccomp_bpf:syscall_faked from kselftests fail on s390x (LP: #1928522) + - selftests/seccomp: s390 shares the syscall and return value register + * Can't detect intel wifi 6235 (LP: #1920180) + - SAUCE: iwlwifi: add new pci id for 6235 + * Mark kprobe_args_user.tc in kselftest/ftrace as unsupported (LP: #1929527) + - selftests/ftrace: Return unsupported for the unconfigured features + * pmtu.sh from net in ubuntu_kernel_selftests failed with no error message + (LP: #1887661) + - selftests: pmtu.sh: use $ksft_skip for skipped return code + * alsa/sof: make sof driver work in the case of without i915 (focal kernel) + (LP: #1927672) + - SAUCE: ASoC: SOF: Intel: hda: move the probe_bus ahead of creation of mach + device + * Fix kdump failures (LP: #1927518) + - video: hyperv_fb: Add ratelimit on error message + - Drivers: hv: vmbus: Increase wait time for VMbus unload + - Drivers: hv: vmbus: Initialize unload_event statically + * Ubuntu 20.04 - 'Support flow counters offset for bulk counters' + (LP: #1922494) + - IB/mlx5: Support flow counters offset for bulk counters + * Focal update: v5.4.118 upstream stable release (LP: #1928825) + - s390/disassembler: increase ebpf disasm buffer size + - ACPI: custom_method: fix potential use-after-free issue + - ACPI: custom_method: fix a possible memory leak + - ftrace: Handle commands when closing set_ftrace_filter file + - ARM: 9056/1: decompressor: fix BSS size calculation for LLVM ld.lld + - arm64: dts: marvell: armada-37xx: add syscon compatible to NB clk node + - arm64: dts: mt8173: fix property typo of 'phys' in dsi node + - ecryptfs: fix kernel panic with null dev_name + - mtd: spinand: core: add missing MODULE_DEVICE_TABLE() + - mtd: rawnand: atmel: Update ecc_stats.corrected counter + - erofs: add unsupported inode i_format check + - spi: spi-ti-qspi: Free DMA resources + - scsi: qla2xxx: Fix crash in qla2xxx_mqueuecommand() + - scsi: mpt3sas: Block PCI config access from userspace during reset + - mmc: uniphier-sd: Fix an error handling path in uniphier_sd_probe() + - mmc: uniphier-sd: Fix a resource leak in the remove function + - mmc: sdhci: Check for reset prior to DMA address unmap + - mmc: sdhci-pci: Fix initialization of some SD cards for Intel BYT-based + controllers + - mmc: block: Update ext_csd.cache_ctrl if it was written + - mmc: block: Issue a cache flush only when it's enabled + - mmc: core: Do a power cycle when the CMD11 fails + - mmc: core: Set read only for SD cards with permanent write protect bit + - mmc: core: Fix hanging on I/O during system suspend for removable cards + - modules: mark ref_module static + - modules: mark find_symbol static + - modules: mark each_symbol_section static + - modules: unexport __module_text_address + - modules: unexport __module_address + - modules: rename the licence field in struct symsearch to license + - modules: return licensing information from find_symbol + - modules: inherit TAINT_PROPRIETARY_MODULE + - irqchip/gic-v3: Do not enable irqs when handling spurious interrups + - cifs: Return correct error code from smb2_get_enc_key + - btrfs: fix metadata extent leak after failure to create subvolume + - intel_th: pci: Add Rocket Lake CPU support + - posix-timers: Preserve return value in clock_adjtime32() + - fbdev: zero-fill colormap in fbcmap.c + - bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first + - staging: wimax/i2400m: fix byte-order issue + - spi: ath79: always call chipselect function + - spi: ath79: remove spi-master setup and cleanup assignment + - crypto: api - check for ERR pointers in crypto_destroy_tfm() + - crypto: qat - fix unmap invalid dma address + - usb: gadget: uvc: add bInterval checking for HS mode + - usb: webcam: Invalid size of Processing Unit Descriptor + - genirq/matrix: Prevent allocation counter corruption + - usb: gadget: f_uac2: validate input parameters + - usb: gadget: f_uac1: validate input parameters + - usb: dwc3: gadget: Ignore EP queue requests during bus reset + - usb: xhci: Fix port minor revision + - PCI: PM: Do not read power state in pci_enable_device_flags() + - x86/build: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS) + - tee: optee: do not check memref size on return from Secure World + - perf/arm_pmu_platform: Fix error handling + - usb: xhci-mtk: support quirk to disable usb2 lpm + - xhci: check control context is valid before dereferencing it. + - xhci: fix potential array out of bounds with several interrupters + - spi: dln2: Fix reference leak to master + - spi: omap-100k: Fix reference leak to master + - spi: qup: fix PM reference leak in spi_qup_remove() + - usb: musb: fix PM reference leak in musb_irq_work() + - usb: core: hub: Fix PM reference leak in usb_port_resume() + - tty: n_gsm: check error while registering tty devices + - intel_th: Consistency and off-by-one fix + - phy: phy-twl4030-usb: Fix possible use-after-free in twl4030_usb_remove() + - crypto: stm32/hash - Fix PM reference leak on stm32-hash.c + - crypto: stm32/cryp - Fix PM reference leak on stm32-cryp.c + - crypto: omap-aes - Fix PM reference leak on omap-aes.c + - platform/x86: intel_pmc_core: Don't use global pmcdev in quirks + - btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s + - drm: Added orientation quirk for OneGX1 Pro + - drm/qxl: release shadow on shutdown + - drm/amd/display: Check for DSC support instead of ASIC revision + - drm/amd/display: Don't optimize bandwidth before disabling planes + - scsi: lpfc: Fix incorrect dbde assignment when building target abts wqe + - scsi: lpfc: Fix pt2pt connection does not recover after LOGO + - scsi: target: pscsi: Fix warning in pscsi_complete_cmd() + - media: ite-cir: check for receive overflow + - media: drivers: media: pci: sta2x11: fix Kconfig dependency on GPIOLIB + - media: imx: capture: Return -EPIPE from __capture_legacy_try_fmt() + - power: supply: bq27xxx: fix power_avg for newer ICs + - extcon: arizona: Fix some issues when HPDET IRQ fires after the jack has + been unplugged + - extcon: arizona: Fix various races on driver unbind + - media: media/saa7164: fix saa7164_encoder_register() memory leak bugs + - media: gspca/sq905.c: fix uninitialized variable + - power: supply: Use IRQF_ONESHOT + - drm/amdgpu: mask the xgmi number of hops reported from psp to kfd + - drm/amdkfd: Fix UBSAN shift-out-of-bounds warning + - drm/amdgpu : Fix asic reset regression issue introduce by 8f211fe8ac7c4f + - drm/amd/display: Fix UBSAN warning for not a valid value for type '_Bool' + - drm/amd/display: fix dml prefetch validation + - scsi: qla2xxx: Always check the return value of qla24xx_get_isp_stats() + - drm/vkms: fix misuse of WARN_ON + - scsi: qla2xxx: Fix use after free in bsg + - mmc: sdhci-pci: Add PCI IDs for Intel LKF + - ata: ahci: Disable SXS for Hisilicon Kunpeng920 + - scsi: smartpqi: Correct request leakage during reset operations + - scsi: smartpqi: Add new PCI IDs + - scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg() + - media: em28xx: fix memory leak + - media: vivid: update EDID + - clk: socfpga: arria10: Fix memory leak of socfpga_clk on error return + - power: supply: generic-adc-battery: fix possible use-after-free in + gab_remove() + - power: supply: s3c_adc_battery: fix possible use-after-free in + s3c_adc_bat_remove() + - media: tc358743: fix possible use-after-free in tc358743_remove() + - media: adv7604: fix possible use-after-free in adv76xx_remove() + - media: i2c: adv7511-v4l2: fix possible use-after-free in adv7511_remove() + - media: i2c: tda1997: Fix possible use-after-free in tda1997x_remove() + - media: i2c: adv7842: fix possible use-after-free in adv7842_remove() + - media: platform: sti: Fix runtime PM imbalance in regs_show + - media: dvb-usb: fix memory leak in dvb_usb_adapter_init + - media: gscpa/stv06xx: fix memory leak + - sched/fair: Ignore percpu threads for imbalance pulls + - drm/msm/mdp5: Configure PP_SYNC_HEIGHT to double the vtotal + - drm/msm/mdp5: Do not multiply vclk line count by 100 + - drm/amdkfd: Fix cat debugfs hang_hws file causes system crash bug + - amdgpu: avoid incorrect %hu format string + - drm/amdgpu: fix NULL pointer dereference + - scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO + response + - scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL mode + - scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic + - mfd: arizona: Fix rumtime PM imbalance on error + - scsi: libfc: Fix a format specifier + - s390/archrandom: add parameter check for s390_arch_random_generate + - ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer + - ALSA: hda/conexant: Re-order CX5066 quirk table entries + - ALSA: sb: Fix two use after free in snd_sb_qsound_build + - ALSA: usb-audio: Explicitly set up the clock selector + - ALSA: usb-audio: More constifications + - ALSA: usb-audio: Add dB range mapping for Sennheiser Communications Headset + PC 8 + - ALSA: hda/realtek: GA503 use same quirks as GA401 + - ALSA: hda/realtek: fix mic boost on Intel NUC 8 + - ALSA: hda/realtek: fix static noise on ALC285 Lenovo laptops + - ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx + - btrfs: fix race when picking most recent mod log operation for an old root + - arm64/vdso: Discard .note.gnu.property sections in vDSO + - Makefile: Move -Wno-unused-but-set-variable out of GCC only block + - virtiofs: fix memory leak in virtio_fs_probe() + - ubifs: Only check replay with inode type to judge if inode linked + - f2fs: fix to avoid out-of-bounds memory access + - mlxsw: spectrum_mr: Update egress RIF list before route's action + - openvswitch: fix stack OOB read while fragmenting IPv4 packets + - ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure + - NFS: Don't discard pNFS layout segments that are marked for return + - NFSv4: Don't discard segments marked for return in _pnfs_return_layout() + - Input: ili210x - add missing negation for touch indication on ili210x + - jffs2: Fix kasan slab-out-of-bounds problem + - powerpc/eeh: Fix EEH handling for hugepages in ioremap space. + - powerpc: fix EDEADLOCK redefinition error in uapi/asm/errno.h + - intel_th: pci: Add Alder Lake-M support + - tpm: efi: Use local variable for calculating final log size + - tpm: vtpm_proxy: Avoid reading host log when using a virtual device + - crypto: rng - fix crypto_rng_reset() refcounting when !CRYPTO_STATS + - md/raid1: properly indicate failure when ending a failed write request + - dm raid: fix inconclusive reshape layout on fast raid4/5/6 table reload + sequences + - fuse: fix write deadlock + - security: commoncap: fix -Wstringop-overread warning + - Fix misc new gcc warnings + - jffs2: check the validity of dstlen in jffs2_zlib_compress() + - Revert 337f13046ff0 ("futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op") + - x86/cpu: Initialize MSR_TSC_AUX if RDTSCP *or* RDPID is supported + - kbuild: update config_data.gz only when the content of .config is changed + - ext4: fix check to prevent false positive report of incorrect used inodes + - ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() + - ext4: fix error code in ext4_commit_super + - media: dvbdev: Fix memory leak in dvb_media_device_free() + - media: dvb-usb: Fix use-after-free access + - media: dvb-usb: Fix memory leak at error in dvb_usb_device_init() + - media: staging/intel-ipu3: Fix memory leak in imu_fmt + - media: staging/intel-ipu3: Fix set_fmt error handling + - media: staging/intel-ipu3: Fix race condition during set_fmt + - usb: gadget: dummy_hcd: fix gpf in gadget_setup + - usb: gadget: Fix double free of device descriptor pointers + - usb: gadget/function/f_fs string table fix for multiple languages + - usb: dwc3: gadget: Fix START_TRANSFER link state check + - usb: dwc2: Fix session request interrupt handler + - tty: fix memory leak in vc_deallocate + - rsi: Use resume_noirq for SDIO + - tracing: Map all PIDs to command lines + - tracing: Restructure trace_clock_global() to never block + - dm persistent data: packed struct should have an aligned() attribute too + - dm space map common: fix division bug in sm_ll_find_free_block() + - dm integrity: fix missing goto in bitmap_flush_interval error handling + - dm rq: fix double free of blk_mq_tag_set in dev remove after table load + fails + - Linux 5.4.118 + * Focal update: v5.4.117 upstream stable release (LP: #1928823) + - mips: Do not include hi and lo in clobber list for R6 + - ACPI: tables: x86: Reserve memory occupied by ACPI tables + - ACPI: x86: Call acpi_boot_table_init() after acpi_table_upgrade() + - net: usb: ax88179_178a: initialize local variables before use + - igb: Enable RSS for Intel I211 Ethernet Controller + - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_enqueue_hcmd() + - bpf: Fix masking negation logic upon negative dst register + - bpf: Fix leakage of uninitialized bpf stack under speculation + - avoid __memcat_p link failure + - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd() + - perf data: Fix error return code in perf_data__create_dir() + - perf ftrace: Fix access to pid in array when setting a pid filter + - ALSA: usb-audio: Add MIDI quirk for Vox ToneLab EX + - USB: Add reset-resume quirk for WD19's Realtek Hub + - platform/x86: thinkpad_acpi: Correct thermal sensor allocation + - scsi: ufs: Unlock on a couple error paths + - ovl: allow upperdir inside lowerdir + - perf/core: Fix unconditional security_locked_down() call + - vfio: Depend on MMU + - Linux 5.4.117 + * r8152 tx status -71 (LP: #1922651) // Focal update: v5.4.117 upstream stable + release (LP: #1928823) + - USB: Add LPM quirk for Lenovo ThinkPad USB-C Dock Gen2 Ethernet + * Focal update: v5.4.116 upstream stable release (LP: #1928821) + - bpf: Move off_reg into sanitize_ptr_alu + - bpf: Ensure off_reg has no mixed signed bounds for all types + - bpf: Rework ptr_limit into alu_limit and add common error path + - bpf: Improve verifier error messages for users + - bpf: Refactor and streamline bounds check into helper + - bpf: Move sanitize_val_alu out of op switch + - bpf: Tighten speculative pointer arithmetic mask + - bpf: Update selftests to reflect new error states + - Linux 5.4.116 + * Focal update: v5.4.115 upstream stable release (LP: #1927997) + - gpio: omap: Save and restore sysconfig + - pinctrl: lewisburg: Update number of pins in community + - arm64: dts: allwinner: Revert SD card CD GPIO for Pine64-LTS + - perf/x86/intel/uncore: Remove uncore extra PCI dev HSWEP_PCI_PCU_3 + - perf/x86/kvm: Fix Broadwell Xeon stepping in isolation_ucodes[] + - perf auxtrace: Fix potential NULL pointer dereference + - HID: google: add don USB id + - HID: alps: fix error return code in alps_input_configured() + - HID: wacom: Assign boolean values to a bool variable + - ARM: dts: Fix swapped mmc order for omap3 + - net: geneve: check skb is large enough for IPv4/IPv6 header + - s390/entry: save the caller of psw_idle + - xen-netback: Check for hotplug-status existence before watching + - cavium/liquidio: Fix duplicate argument + - csky: change a Kconfig symbol name to fix e1000 build error + - ia64: fix discontig.c section mismatches + - ia64: tools: remove duplicate definition of ia64_mf() on ia64 + - x86/crash: Fix crash_setup_memmap_entries() out-of-bounds access + - net: hso: fix NULL-deref on disconnect regression + - USB: CDC-ACM: fix poison/unpoison imbalance + - Linux 5.4.115 + + -- Tim Gardner Fri, 11 Jun 2021 10:58:51 -0600 + +linux-oracle (5.4.0-1046.50) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1046.50 -proposed tracker (LP: #1927611) + + * Packaging resync (LP: #1786013) + - update dkms package versions + + [ Ubuntu: 5.4.0-74.83 ] + + * focal/linux: 5.4.0-74.83 -proposed tracker (LP: #1927619) + * Introduce the 465 driver series, fabric-manager, and libnvidia-nscq + (LP: #1925522) + - debian/dkms-versions -- add NVIDIA 465 and migrate 450 to 460 + * linux-image-5.0.0-35-generic breaks checkpointing of container + (LP: #1857257) + - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files + * Enable CIFS GCM256 (LP: #1921916) + - smb3: add defines for new crypto algorithms + - smb3.1.1: add new module load parm require_gcm_256 + - smb3.1.1: add new module load parm enable_gcm_256 + - smb3.1.1: print warning if server does not support requested encryption type + - smb3.1.1: rename nonces used for GCM and CCM encryption + - smb3.1.1: set gcm256 when requested + - cifs: Adjust key sizes and key generation routines for AES256 encryption + * locking/qrwlock: Fix ordering in queued_write_lock_slowpath() (LP: #1926184) + - locking/qrwlock: Fix ordering in queued_write_lock_slowpath() + * [Ubuntu 21.04] net/mlx5: Fix HW spec violation configuring uplink + (LP: #1925452) + - net/mlx5: Fix HW spec violation configuring uplink + * Focal update: v5.4.114 upstream stable release (LP: #1926493) + - Revert "scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure" + - Revert "scsi: qla2xxx: Fix stuck login session using prli_pend_timer" + - scsi: qla2xxx: Dual FCP-NVMe target port support + - scsi: qla2xxx: Fix device connect issues in P2P configuration + - scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure + - scsi: qla2xxx: Add a shadow variable to hold disc_state history of fcport + - scsi: qla2xxx: Fix stuck login session using prli_pend_timer + - scsi: qla2xxx: Fix fabric scan hang + - net/sctp: fix race condition in sctp_destroy_sock + - Input: nspire-keypad - enable interrupts only when opened + - gpio: sysfs: Obey valid_mask + - dmaengine: dw: Make it dependent to HAS_IOMEM + - ARM: dts: Drop duplicate sha2md5_fck to fix clk_disable race + - ARM: dts: Fix moving mmc devices with aliases for omap4 & 5 + - lockdep: Add a missing initialization hint to the "INFO: Trying to register + non-static key" message + - arc: kernel: Return -EFAULT if copy_to_user() fails + - ASoC: max98373: Added 30ms turn on/off time delay + - neighbour: Disregard DEAD dst in neigh_update + - ARM: keystone: fix integer overflow warning + - ARM: omap1: fix building with clang IAS + - drm/msm: Fix a5xx/a6xx timestamps + - ASoC: fsl_esai: Fix TDM slot setup for I2S mode + - scsi: scsi_transport_srp: Don't block target in SRP_PORT_LOST state + - net: ieee802154: stop dump llsec keys for monitors + - net: ieee802154: forbid monitor for add llsec key + - net: ieee802154: forbid monitor for del llsec key + - net: ieee802154: stop dump llsec devs for monitors + - net: ieee802154: forbid monitor for add llsec dev + - net: ieee802154: forbid monitor for del llsec dev + - net: ieee802154: stop dump llsec devkeys for monitors + - net: ieee802154: forbid monitor for add llsec devkey + - net: ieee802154: forbid monitor for del llsec devkey + - net: ieee802154: stop dump llsec seclevels for monitors + - net: ieee802154: forbid monitor for add llsec seclevel + - pcnet32: Use pci_resource_len to validate PCI resource + - mac80211: clear sta->fast_rx when STA removed from 4-addr VLAN + - virt_wifi: Return micros for BSS TSF values + - Input: s6sy761 - fix coordinate read bit shift + - Input: i8042 - fix Pegatron C15B ID entry + - HID: wacom: set EV_KEY and EV_ABS only for non-HID_GENERIC type of devices + - dm verity fec: fix misaligned RS roots IO + - readdir: make sure to verify directory entry for legacy interfaces too + - arm64: fix inline asm in load_unaligned_zeropad() + - arm64: alternatives: Move length validation in alternative_{insn, endif} + - vfio/pci: Add missing range check in vfio_pci_mmap + - riscv: Fix spelling mistake "SPARSEMEM" to "SPARSMEM" + - scsi: libsas: Reset num_scatter if libata marks qc as NODATA + - netfilter: conntrack: do not print icmpv6 as unknown via /proc + - libnvdimm/region: Fix nvdimm_has_flush() to handle ND_REGION_ASYNC + - netfilter: bridge: add pre_exit hooks for ebtable unregistration + - netfilter: arp_tables: add pre_exit hook for table unregister + - net: macb: fix the restore of cmp registers + - netfilter: nft_limit: avoid possible divide error in nft_limit_init + - net: davicom: Fix regulator not turned off on failed probe + - net: sit: Unregister catch-all devices + - net: ip6_tunnel: Unregister catch-all devices + - i40e: fix the panic when running bpf in xdpdrv mode + - ibmvnic: avoid calling napi_disable() twice + - ibmvnic: remove duplicate napi_schedule call in do_reset function + - ibmvnic: remove duplicate napi_schedule call in open function + - gro: ensure frag0 meets IP header alignment + - ARM: footbridge: fix PCI interrupt mapping + - arm64: dts: allwinner: Fix SD card CD GPIO for SOPine systems + - r8169: remove fiddling with the PCIe max read request size + - r8169: simplify setting PCI_EXP_DEVCTL_NOSNOOP_EN + - r8169: fix performance regression related to PCIe max read request size + - r8169: improve rtl_jumbo_config + - r8169: tweak max read request size for newer chips also in jumbo mtu mode + - r8169: don't advertise pause in jumbo mode + - ARM: 9071/1: uprobes: Don't hook on thumb instructions + - net: phy: marvell: fix detection of PHY on Topaz switches + - Linux 5.4.114 + * Focal update: v5.4.113 upstream stable release (LP: #1926490) + - interconnect: core: fix error return code of icc_link_destroy() + - KVM: arm64: Hide system instruction access to Trace registers + - KVM: arm64: Disable guest access to trace filter controls + - drm/imx: imx-ldb: fix out of bounds array access warning + - gfs2: report "already frozen/thawed" errors + - drm/tegra: dc: Don't set PLL clock to 0Hz + - block: only update parent bi_status when bio fail + - radix tree test suite: Register the main thread with the RCU library + - idr test suite: Take RCU read lock in idr_find_test_1 + - idr test suite: Create anchor before launching throbber + - riscv,entry: fix misaligned base for excp_vect_table + - block: don't ignore REQ_NOWAIT for direct IO + - netfilter: x_tables: fix compat match/target pad out-of-bound write + - driver core: Fix locking bug in deferred_probe_timeout_work_func() + - perf tools: Use %define api.pure full instead of %pure-parser + - perf tools: Use %zd for size_t printf formats on 32-bit + - perf map: Tighten snprintf() string precision to pass gcc check on some + 32-bit arches + - xen/events: fix setting irq affinity + - Linux 5.4.113 + * Focal update: v5.4.112 upstream stable release (LP: #1926489) + - counter: stm32-timer-cnt: fix ceiling miss-alignment with reload register + - ALSA: aloop: Fix initialization of controls + - ALSA: hda/realtek: Fix speaker amp setup on Acer Aspire E1 + - ASoC: intel: atom: Stop advertising non working S24LE support + - nfc: fix refcount leak in llcp_sock_bind() + - nfc: fix refcount leak in llcp_sock_connect() + - nfc: fix memory leak in llcp_sock_connect() + - nfc: Avoid endless loops caused by repeated llcp_sock_connect() + - xen/evtchn: Change irq_info lock to raw_spinlock_t + - net: ipv6: check for validity before dereferencing cfg->fc_nlinfo.nlh + - net: dsa: lantiq_gswip: Let GSWIP automatically set the xMII clock + - drm/i915: Fix invalid access to ACPI _DSM objects + - gcov: re-fix clang-11+ support + - ia64: fix user_stack_pointer() for ptrace() + - nds32: flush_dcache_page: use page_mapping_file to avoid races with swapoff + - ocfs2: fix deadlock between setattr and dio_end_io_write + - fs: direct-io: fix missing sdio->boundary + - parisc: parisc-agp requires SBA IOMMU driver + - parisc: avoid a warning on u8 cast for cmpxchg on u8 pointers + - ARM: dts: turris-omnia: configure LED[2]/INTn pin as interrupt pin + - batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field + - ice: Increase control queue timeout + - ice: Fix for dereference of NULL pointer + - ice: Cleanup fltr list in case of allocation issues + - net: hso: fix null-ptr-deref during tty device unregistration + - ethernet/netronome/nfp: Fix a use after free in nfp_bpf_ctrl_msg_rx + - bpf, sockmap: Fix sk->prot unhash op reset + - net: ensure mac header is set in virtio_net_hdr_to_skb() + - i40e: Fix sparse warning: missing error code 'err' + - i40e: Fix sparse error: 'vsi->netdev' could be null + - net: sched: sch_teql: fix null-pointer dereference + - mac80211: fix TXQ AC confusion + - net: hsr: Reset MAC header for Tx path + - net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind() + - net: let skb_orphan_partial wake-up waiters. + - usbip: add sysfs_lock to synchronize sysfs code paths + - usbip: stub-dev synchronize sysfs code paths + - usbip: vudc synchronize sysfs code paths + - usbip: synchronize event handler with sysfs code paths + - i2c: turn recovery error on init to debug + - virtio_net: Add XDP meta data support + - net: dsa: lantiq_gswip: Don't use PHY auto polling + - net: dsa: lantiq_gswip: Configure all remaining GSWIP_MII_CFG bits + - xfrm: interface: fix ipv4 pmtu check to honor ip header df + - regulator: bd9571mwv: Fix AVS and DVFS voltage range + - net: xfrm: Localize sequence counter per network namespace + - esp: delete NETIF_F_SCTP_CRC bit from features for esp offload + - ASoC: SOF: Intel: hda: remove unnecessary parentheses + - ASoC: SOF: Intel: HDA: fix core status verification + - ASoC: wm8960: Fix wrong bclk and lrclk with pll enabled for some chips + - xfrm: Fix NULL pointer dereference on policy lookup + - i40e: Added Asym_Pause to supported link modes + - i40e: Fix kernel oops when i40e driver removes VF's + - hostfs: Use kasprintf() instead of fixed buffer formatting + - hostfs: fix memory handling in follow_link() + - amd-xgbe: Update DMA coherency values + - sch_red: fix off-by-one checks in red_check_params() + - arm64: dts: imx8mm/q: Fix pad control of SD1_DATA0 + - can: bcm/raw: fix msg_namelen values depending on CAN_REQUIRED_SIZE + - gianfar: Handle error code at MAC address change + - cxgb4: avoid collecting SGE_QBASE regs during traffic + - net:tipc: Fix a double free in tipc_sk_mcast_rcv + - ARM: dts: imx6: pbab01: Set vmmc supply for both SD interfaces + - net/ncsi: Avoid channel_monitor hrtimer deadlock + - nfp: flower: ignore duplicate merge hints from FW + - net: phy: broadcom: Only advertise EEE for supported modes + - ASoC: sunxi: sun4i-codec: fill ASoC card owner + - net/mlx5e: Fix ethtool indication of connector type + - net/mlx5: Don't request more than supported EQs + - net/rds: Fix a use after free in rds_message_map_pages + - soc/fsl: qbman: fix conflicting alignment attributes + - i40e: Fix display statistics for veb_tc + - drm/msm: Set drvdata to NULL when msm_drm_init() fails + - net: udp: Add support for getsockopt(..., ..., UDP_GRO, ..., ...); + - scsi: ufs: Fix irq return code + - scsi: ufs: Avoid busy-waiting by eliminating tag conflicts + - scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs + - scsi: ufs: core: Fix task management request completion timeout + - scsi: ufs: core: Fix wrong Task Tag used in task management request UPIUs + - net: macb: restore cmp registers on resume path + - clk: fix invalid usage of list cursor in register + - clk: fix invalid usage of list cursor in unregister + - workqueue: Move the position of debug_work_activate() in __queue_work() + - s390/cpcmd: fix inline assembly register clobbering + - perf inject: Fix repipe usage + - net: openvswitch: conntrack: simplify the return expression of + ovs_ct_limit_get_default_limit() + - openvswitch: fix send of uninitialized stack memory in ct limit reply + - net: hns3: clear VF down state bit before request link status + - net/mlx5: Fix placement of log_max_flow_counter + - net/mlx5: Fix PBMC register mapping + - RDMA/cxgb4: check for ipv6 address properly while destroying listener + - RDMA/addr: Be strict with gid size + - RAS/CEC: Correct ce_add_elem()'s returned values + - clk: socfpga: fix iomem pointer cast on 64-bit + - dt-bindings: net: ethernet-controller: fix typo in NVMEM + - net: sched: bump refcount for new action in ACT replace mode + - cfg80211: remove WARN_ON() in cfg80211_sme_connect + - net: tun: set tun->dev->addr_len during TUNSETLINK processing + - drivers: net: fix memory leak in atusb_probe + - drivers: net: fix memory leak in peak_usb_create_dev + - net: mac802154: Fix general protection fault + - net: ieee802154: nl-mac: fix check on panid + - net: ieee802154: fix nl802154 del llsec key + - net: ieee802154: fix nl802154 del llsec dev + - net: ieee802154: fix nl802154 add llsec key + - net: ieee802154: fix nl802154 del llsec devkey + - net: ieee802154: forbid monitor for set llsec params + - net: ieee802154: forbid monitor for del llsec seclevel + - net: ieee802154: stop dump llsec params for monitors + - Linux 5.4.112 + * crash utility fails on arm64 with cannot determine VA_BITS_ACTUAL + (LP: #1919275) + - arm64/crash_core: Export TCR_EL1.T1SZ in vmcoreinfo + * Focal update: v5.4.111 upstream stable release (LP: #1923874) + - ARM: dts: am33xx: add aliases for mmc interfaces + - bus: ti-sysc: Fix warning on unbind if reset is not deasserted + - platform/x86: intel-hid: Support Lenovo ThinkPad X1 Tablet Gen 2 + - bpf, x86: Use kvmalloc_array instead kmalloc_array in bpf_jit_comp + - net/mlx5e: Enforce minimum value check for ICOSQ size + - net: pxa168_eth: Fix a potential data race in pxa168_eth_remove + - mISDN: fix crash in fritzpci + - mac80211: choose first enabled channel for monitor + - drm/msm/adreno: a5xx_power: Don't apply A540 lm_setup to other GPUs + - drm/msm: Ratelimit invalid-fence message + - netfilter: conntrack: Fix gre tunneling over ipv6 + - platform/x86: thinkpad_acpi: Allow the FnLock LED to change state + - x86/build: Turn off -fcf-protection for realmode targets + - scsi: target: pscsi: Clean up after failure in pscsi_map_sg() + - ia64: mca: allocate early mca with GFP_ATOMIC + - ia64: fix format strings for err_inject + - cifs: revalidate mapping when we open files for SMB1 POSIX + - cifs: Silently ignore unknown oplock break handle + - nvme-mpath: replace direct_make_request with generic_make_request + - init/Kconfig: make COMPILE_TEST depend on !S390 + - init/Kconfig: make COMPILE_TEST depend on HAS_IOMEM + - Linux 5.4.111 + * Focal update: v5.4.110 upstream stable release (LP: #1923869) + - selinux: vsock: Set SID for socket returned by accept() + - ipv6: weaken the v4mapped source check + - modsign: print module name along with error message + - module: merge repetitive strings in module_sig_check() + - module: avoid *goto*s in module_sig_check() + - module: harden ELF info handling + - ext4: shrink race window in ext4_should_retry_alloc() + - ext4: fix bh ref count on error paths + - fs: nfsd: fix kconfig dependency warning for NFSD_V4 + - rpc: fix NULL dereference on kmalloc failure + - iomap: Fix negative assignment to unsigned sis->pages in + iomap_swapfile_activate + - ASoC: rt5640: Fix dac- and adc- vol-tlv values being off by a factor of 10 + - ASoC: rt5651: Fix dac- and adc- vol-tlv values being off by a factor of 10 + - ASoC: sgtl5000: set DAP_AVC_CTRL register to correct default value on probe + - ASoC: es8316: Simplify adc_pga_gain_tlv table + - ASoC: cs42l42: Fix Bitclock polarity inversion + - ASoC: cs42l42: Fix channel width support + - ASoC: cs42l42: Fix mixer volume control + - ASoC: cs42l42: Always wait at least 3ms after reset + - NFSD: fix error handling in NFSv4.0 callbacks + - powerpc: Force inlining of cpu_has_feature() to avoid build failure + - vhost: Fix vhost_vq_reset() + - scsi: st: Fix a use after free in st_open() + - scsi: qla2xxx: Fix broken #endif placement + - staging: comedi: cb_pcidas: fix request_irq() warn + - staging: comedi: cb_pcidas64: fix request_irq() warn + - ASoC: rt5659: Update MCLK rate in set_sysclk() + - thermal/core: Add NULL pointer check before using cooling device stats + - locking/ww_mutex: Simplify use_ww_ctx & ww_ctx handling + - ext4: do not iput inode under running transaction in ext4_rename() + - net: mvpp2: fix interrupt mask/unmask skip condition + - flow_dissector: fix TTL and TOS dissection on IPv4 fragments + - can: dev: move driver related infrastructure into separate subdir + - net: introduce CAN specific pointer in the struct net_device + - can: tcan4x5x: fix max register value + - brcmfmac: clear EAP/association status bits on linkdown events + - ath10k: hold RCU lock when calling ieee80211_find_sta_by_ifaddr() + - net: ethernet: aquantia: Handle error cleanup of start on open + - appletalk: Fix skb allocation size in loopback case + - net: wan/lmc: unregister device when no matching device is found + - bpf: Remove MTU check in __bpf_skb_max_len + - ALSA: usb-audio: Apply sample rate quirk to Logitech Connect + - ALSA: hda: Re-add dropped snd_poewr_change_state() calls + - ALSA: hda: Add missing sanity checks in PM prepare/complete callbacks + - ALSA: hda/realtek: fix a determine_headset_type issue for a Dell AIO + - ALSA: hda/realtek: call alc_update_headset_mode() in hp_automute_hook + - xtensa: move coprocessor_flush to the .text section + - PM: runtime: Fix race getting/putting suppliers at probe + - PM: runtime: Fix ordering in pm_runtime_get_suppliers() + - tracing: Fix stack trace event size + - mm: fix race by making init_zero_pfn() early_initcall + - drm/amdgpu: fix offset calculation in amdgpu_vm_bo_clear_mappings() + - drm/amdgpu: check alignment on CPU page for bo map + - reiserfs: update reiserfs_xattrs_initialized() condition + - vfio/nvlink: Add missing SPAPR_TCE_IOMMU depends + - pinctrl: rockchip: fix restore error in resume + - extcon: Add stubs for extcon_register_notifier_all() functions + - extcon: Fix error handling in extcon_dev_register + - firewire: nosy: Fix a use-after-free bug in nosy_ioctl() + - usbip: vhci_hcd fix shift out-of-bounds in vhci_hub_control() + - USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem + - usb: musb: Fix suspend with devices connected for a64 + - usb: xhci-mtk: fix broken streams issue on 0.96 xHCI + - cdc-acm: fix BREAK rx code path adding necessary calls + - USB: cdc-acm: untangle a circular dependency between callback and softint + - USB: cdc-acm: downgrade message to debug + - USB: cdc-acm: fix double free on probe failure + - USB: cdc-acm: fix use-after-free after probe failure + - usb: gadget: udc: amd5536udc_pci fix null-ptr-dereference + - usb: dwc2: Fix HPRT0.PrtSusp bit setting for HiKey 960 board. + - usb: dwc2: Prevent core suspend when port connection flag is 0 + - staging: rtl8192e: Fix incorrect source in memcpy() + - staging: rtl8192e: Change state information from u16 to u8 + - drivers: video: fbcon: fix NULL dereference in fbcon_cursor() + - Linux 5.4.110 + * Focal update: v5.4.109 upstream stable release (LP: #1923220) + - hugetlbfs: hugetlb_fault_mutex_hash() cleanup + - net: fec: ptp: avoid register access when ipg clock is disabled + - powerpc/4xx: Fix build errors from mfdcr() + - atm: eni: dont release is never initialized + - atm: lanai: dont run lanai_dev_close if not open + - Revert "r8152: adjust the settings about MAC clock speed down for RTL8153" + - ALSA: hda: ignore invalid NHLT table + - ixgbe: Fix memleak in ixgbe_configure_clsu32 + - net: tehuti: fix error return code in bdx_probe() + - net: intel: iavf: fix error return code of iavf_init_get_resources() + - sun/niu: fix wrong RXMAC_BC_FRM_CNT_COUNT count + - gianfar: fix jumbo packets+napi+rx overrun crash + - cifs: ask for more credit on async read/write code paths + - cpufreq: blacklist Arm Vexpress platforms in cpufreq-dt-platdev + - gpiolib: acpi: Add missing IRQF_ONESHOT + - nfs: fix PNFS_FLEXFILE_LAYOUT Kconfig default + - NFS: Correct size calculation for create reply length + - net: hisilicon: hns: fix error return code of hns_nic_clear_all_rx_fetch() + - net: wan: fix error return code of uhdlc_init() + - net: davicom: Use platform_get_irq_optional() + - atm: uPD98402: fix incorrect allocation + - atm: idt77252: fix null-ptr-dereference + - cifs: change noisy error message to FYI + - irqchip/ingenic: Add support for the JZ4760 + - sparc64: Fix opcode filtering in handling of no fault loads + - habanalabs: Call put_pid() when releasing control device + - u64_stats,lockdep: Fix u64_stats_init() vs lockdep + - regulator: qcom-rpmh: Correct the pmic5_hfsmps515 buck + - drm/amd/display: Revert dram_clock_change_latency for DCN2.1 + - drm/amdgpu: fb BO should be ttm_bo_type_device + - drm/radeon: fix AGP dependency + - nvme: add NVME_REQ_CANCELLED flag in nvme_cancel_request() + - nvme-fc: return NVME_SC_HOST_ABORTED_CMD when a command has been aborted + - nvme-pci: add the DISABLE_WRITE_ZEROES quirk for a Samsung PM1725a + - nfs: we don't support removing system.nfs4_acl + - block: Suppress uevent for hidden device when removed + - ia64: fix ia64_syscall_get_set_arguments() for break-based syscalls + - ia64: fix ptrace(PTRACE_SYSCALL_INFO_EXIT) sign + - netsec: restore phy power state after controller reset + - platform/x86: intel-vbtn: Stop reporting SW_DOCK events + - squashfs: fix inode lookup sanity checks + - squashfs: fix xattr id and id lookup sanity checks + - kasan: fix per-page tags for non-page_alloc pages + - gcov: fix clang-11+ support + - ACPI: video: Add missing callback back for Sony VPCEH3U1E + - arm64: dts: ls1046a: mark crypto engine dma coherent + - arm64: dts: ls1012a: mark crypto engine dma coherent + - arm64: dts: ls1043a: mark crypto engine dma coherent + - ARM: dts: at91-sama5d27_som1: fix phy address to 7 + - integrity: double check iint_cache was initialized + - dm verity: fix DM_VERITY_OPTS_MAX value + - dm ioctl: fix out of bounds array access when no devices + - bus: omap_l3_noc: mark l3 irqs as IRQF_NO_THREAD + - veth: Store queue_mapping independently of XDP prog presence + - libbpf: Fix INSTALL flag order + - net/mlx5e: Don't match on Geneve options in case option masks are all zero + - ipv6: fix suspecious RCU usage warning + - macvlan: macvlan_count_rx() needs to be aware of preemption + - net: sched: validate stab values + - net: dsa: bcm_sf2: Qualify phydev->dev_flags based on port + - igc: Fix Pause Frame Advertising + - igc: Fix Supported Pause Frame Link Setting + - e1000e: add rtnl_lock() to e1000_reset_task + - e1000e: Fix error handling in e1000_set_d0_lplu_state_82571 + - net/qlcnic: Fix a use after free in qlcnic_83xx_get_minidump_template + - ftgmac100: Restart MAC HW once + - selftests/bpf: Set gopt opt_class to 0 if get tunnel opt failed + - netfilter: ctnetlink: fix dump of the expect mask attribute + - tcp: relookup sock for RST+ACK packets handled by obsolete req sock + - can: peak_usb: add forgotten supported devices + - can: flexcan: flexcan_chip_freeze(): fix chip freeze for missing bitrate + - can: kvaser_pciefd: Always disable bus load reporting + - can: c_can_pci: c_can_pci_remove(): fix use-after-free + - can: c_can: move runtime PM enable/disable to c_can_platform + - can: m_can: m_can_do_rx_poll(): fix extraneous msg loss warning + - can: m_can: m_can_rx_peripheral(): fix RX being blocked by errors + - mac80211: fix rate mask reset + - nfp: flower: fix pre_tun mask id allocation + - libbpf: Use SOCK_CLOEXEC when opening the netlink socket + - octeontx2-af: Fix irq free in rvu teardown + - octeontx2-af: fix infinite loop in unmapping NPC counter + - net: cdc-phonet: fix data-interface release on probe failure + - r8152: limit the RX buffer size of RTL8153A for USB 2.0 + - net: stmmac: dwmac-sun8i: Provide TX and RX fifo sizes + - selftests: forwarding: vxlan_bridge_1d: Fix vxlan ecn decapsulate value + - libbpf: Fix BTF dump of pointer-to-array-of-struct + - drm/msm: fix shutdown hook in case GPU components failed to bind + - arm64: kdump: update ppos when reading elfcorehdr + - PM: runtime: Defer suspending suppliers + - net/mlx5e: Fix error path for ethtool set-priv-flag + - PM: EM: postpone creating the debugfs dir till fs_initcall + - RDMA/cxgb4: Fix adapter LE hash errors while destroying ipv6 listening + server + - bpf: Don't do bpf_cgroup_storage_set() for kuprobe/tp programs + - ACPI: scan: Rearrange memory allocation in acpi_device_add() + - ACPI: scan: Use unique number for instance_no + - perf auxtrace: Fix auxtrace queue conflict + - block: recalculate segment count for multi-segment discards correctly + - scsi: Revert "qla2xxx: Make sure that aborted commands are freed" + - scsi: qedi: Fix error return code of qedi_alloc_global_queues() + - scsi: mpt3sas: Fix error return code of mpt3sas_base_attach() + - locking/mutex: Fix non debug version of mutex_lock_io_nested() + - x86/mem_encrypt: Correct physical address calculation in __set_clr_pte_enc() + - can: dev: Move device back to init netns on owning netns delete + - net: dsa: b53: VLAN filtering is global to all users + - net: qrtr: fix a kernel-infoleak in qrtr_recvmsg() + - mac80211: fix double free in ibss_leave + - ext4: add reclaim checks to xattr code + - can: peak_usb: Revert "can: peak_usb: add forgotten supported devices" + - xen-blkback: don't leak persistent grants from xen_blkbk_map() + - Linux 5.4.109 + * Focal update: v5.4.108 upstream stable release (LP: #1923214) + - ASoC: ak4458: Add MODULE_DEVICE_TABLE + - ASoC: ak5558: Add MODULE_DEVICE_TABLE + - ALSA: dice: fix null pointer dereference when node is disconnected + - ALSA: hda/realtek: apply pin quirk for XiaomiNotebook Pro + - ALSA: hda: generic: Fix the micmute led init state + - ALSA: hda/realtek: Apply headset-mic quirks for Xiaomi Redmibook Air + - Revert "PM: runtime: Update device status before letting suppliers suspend" + - ARM: 9030/1: entry: omit FP emulation for UND exceptions taken in kernel + mode + - ARM: 9044/1: vfp: use undef hook for VFP support detection + - btrfs: fix race when cloning extent buffer during rewind of an old root + - btrfs: fix slab cache flags for free space tree bitmap + - ASoC: fsl_ssi: Fix TDM slot setup for I2S mode + - ASoC: SOF: Intel: unregister DMIC device on probe error + - ASoC: SOF: intel: fix wrong poll bits in dsp power down + - ASoC: simple-card-utils: Do not handle device clock + - afs: Stop listxattr() from listing "afs.*" attributes + - nvme: fix Write Zeroes limitations + - nvme-tcp: fix possible hang when failing to set io queues + - nvme-tcp: fix a NULL deref when receiving a 0-length r2t PDU + - nvmet: don't check iosqes,iocqes for discovery controllers + - nfsd: Don't keep looking up unhashed files in the nfsd file cache + - NFSD: Repair misuse of sv_lock in 5.10.16-rt30. + - svcrdma: disable timeouts on rdma backchannel + - vfio: IOMMU_API should be selected + - sunrpc: fix refcount leak for rpc auth modules + - net/qrtr: fix __netdev_alloc_skb call + - kbuild: Fix for empty SUBLEVEL or PATCHLEVEL again + - riscv: Correct SPARSEMEM configuration + - scsi: lpfc: Fix some error codes in debugfs + - scsi: myrs: Fix a double free in myrs_cleanup() + - counter: stm32-timer-cnt: Report count function when SLAVE_MODE_DISABLED + - nvme-rdma: fix possible hang when failing to set io queues + - usb-storage: Add quirk to defeat Kindle's automatic unload + - usbip: Fix incorrect double assignment to udc->ud.tcp_rx + - USB: replace hardcode maximum usb string length by definition + - usb: gadget: configfs: Fix KASAN use-after-free + - usb: typec: tcpm: Invoke power_supply_changed for tcpm-source-psy- + - iio:adc:stm32-adc: Add HAS_IOMEM dependency + - iio:adc:qcom-spmi-vadc: add default scale to LR_MUX2_BAT_ID channel + - iio: adis16400: Fix an error code in adis16400_initial_setup() + - iio: gyro: mpu3050: Fix error handling in mpu3050_trigger_handler + - iio: adc: ad7949: fix wrong ADC result due to incorrect bit mask + - iio: hid-sensor-humidity: Fix alignment issue of timestamp channel + - iio: hid-sensor-prox: Fix scale not correct issue + - iio: hid-sensor-temperature: Fix issues of timestamp channel + - counter: stm32-timer-cnt: fix ceiling write max value + - PCI: rpadlpar: Fix potential drc_name corruption in store functions + - perf/x86/intel: Fix a crash caused by zero PEBS status + - x86/ioapic: Ignore IRQ2 again + - kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data() + - x86: Move TS_COMPAT back to asm/thread_info.h + - x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall() + - ext4: find old entry again if failed to rename whiteout + - ext4: do not try to set xattr into ea_inode if value is empty + - ext4: fix potential error in ext4_do_update_inode + - efi: use 32-bit alignment for efi_guid_t literals + - firmware/efi: Fix a use after bug in efi_mem_reserve_persistent + - genirq: Disable interrupts for force threaded handlers + - x86/apic/of: Fix CPU devicetree-node lookups + - cifs: Fix preauth hash corruption + - Linux 5.4.108 + * Focal update: v5.4.107 upstream stable release (LP: #1923210) + - KVM: arm64: nvhe: Save the SPE context early + - btrfs: scrub: Don't check free space before marking a block group RO + - drm/i915/gvt: Set SNOOP for PAT3 on BXT/APL to workaround GPU BB hang + - drm/i915/gvt: Fix mmio handler break on BXT/APL. + - drm/i915/gvt: Fix virtual display setup for BXT/APL + - drm/i915/gvt: Fix port number for BDW on EDID region setup + - drm/i915/gvt: Fix vfio_edid issue for BXT/APL + - fuse: fix live lock in fuse_iget() + - crypto: x86 - Regularize glue function prototypes + - crypto: aesni - Use TEST %reg,%reg instead of CMP $0,%reg + - crypto: x86/aes-ni-xts - use direct calls to and 4-way stride + - net: dsa: tag_mtk: fix 802.1ad VLAN egress + - net: dsa: b53: Support setting learning on port + - Linux 5.4.107 + + -- Tim Gardner Tue, 11 May 2021 12:38:29 -0600 + +linux-oracle (5.4.0-1045.49) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1045.49 -proposed tracker (LP: #1926814) + + * arm64 support (LP: #1925421) + - [config] oracle: Bring-up for arm64 support + - SAUCE: perf/smmuv3: Allow sharing MMIO registers with the SMMU driver + - SAUCE: arm64: Split the old READ_IMPLIES_EXEC workaround from executable + - mm/memory-failure: Add memory_failure_queue_kick() + - ACPI: APEI: Kick the memory_failure() queue for synchronous errors + - perf: Add Arm CMN-600 PMU driver + - perf: Add Arm CMN-600 DT binding + - PCI/ACPI: Add Ampere Altra SOC MCFG quirk + - mm: memblock: replace dereferences of memblock_region.nid with API calls + - mm: make early_pfn_to_nid() and related defintions close to each other + - mm: remove CONFIG_HAVE_MEMBLOCK_NODE_MAP option + - mm: free_area_init: use maximal zone PFNs rather than zone sizes + - mm: use free_area_init() instead of free_area_init_nodes() + - alpha: simplify detection of memory zone boundaries + - arm: simplify detection of memory zone boundaries + - arm64: simplify detection of memory zone boundaries for UMA configs + - csky: simplify detection of memory zone boundaries + - m68k: mm: simplify detection of memory zone boundaries + - parisc: simplify detection of memory zone boundaries + - sparc32: simplify detection of memory zone boundaries + - unicore32: simplify detection of memory zone boundaries + - xtensa: simplify detection of memory zone boundaries + - mm: memmap_init: iterate over memblock regions rather that check each PFN + - mm/page_alloc.c: initialize memmap of unavailable memory directly + - mm: pass migratetype into memmap_init_zone() and move_pfn_range_to_zone() + - mm: rename memmap_init() and memmap_init_zone() + - mm: simplify parater of function memmap_init_zone() + - mm/page_alloc.c: refactor initialization of struct page for holes in memory + layout + - mm: remove early_pfn_in_nid() and CONFIG_NODES_SPAN_OTHER_NODES + - mm: free_area_init: allow defining max_zone_pfn in descending order + - arc: fix memory initialization for systems with two memory banks + - mm: rename free_area_init_node() to free_area_init_memoryless_node() + - mm: clean up free_area_init_node() and its helpers + - mm: simplify find_min_pfn_with_active_regions() + - docs/vm: update memory-models documentation + - SAUCE: hwmon: Add Ampere Altra HW monitor driver + - arm64: NUMA: Kconfig: Increase NODES_SHIFT to 4 + - driver/perf: Add PMU driver for the ARM DMC-620 memory controller + - perf/arm_dmc620_pmu: Fix error return code in dmc620_pmu_device_probe() + - perf: arm_dsu: Support DSU ACPI devices + - SAUCE: perf: arm_dsu: Allow IRQ to be shared among devices. + - Perf: arm-cmn: Allow irq to be shared. + - perf: arm-cmn: Fix unsigned comparison to less than zero + - perf/arm-cmn: Fix PMU instance naming + - perf/arm-cmn: Move IRQs when migrating context + - [config] Disable vbox dkms for arm64 + + -- Khalid Elmously Sun, 02 May 2021 23:45:42 -0400 + +linux-oracle (5.4.0-1044.47) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1044.47 -proposed tracker (LP: #1923773) + + * Focal update: v5.4.106 upstream stable release (LP: #1920246) + - [Config] oracle: update abi for rc-cec + + * Disable Atari partition support for cloud kernels (LP: #1908264) + - [Config]: Disable ATARI_PARTITION + + [ Ubuntu: 5.4.0-73.82 ] + + * focal/linux: 5.4.0-73.82 -proposed tracker (LP: #1923781) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CIFS DFS entries not accessible with 5.4.0-71.74-generic (LP: #1923670) + - Revert "cifs: Set CIFS_MOUNT_USE_PREFIX_PATH flag on setting + cifs_sb->prepath." + * CVE-2021-29650 + - Revert "netfilter: x_tables: Update remaining dereference to RCU" + - Revert "netfilter: x_tables: Switch synchronization to RCU" + - netfilter: x_tables: Use correct memory barriers. + * LRMv4: switch to signing nvidia modules via the Ubuntu Modules signing key + (LP: #1918134) + - [Packaging] dkms-build{,--nvidia-N} sync back from LRMv4 + * 5.4 kernel: when iommu is on crashdump fails (LP: #1922738) + - iommu/vt-d: Refactor find_domain() helper + - iommu/vt-d: Add attach_deferred() helper + - iommu/vt-d: Move deferred device attachment into helper function + - iommu/vt-d: Do deferred attachment in iommu_need_mapping() + - iommu/vt-d: Remove deferred_attach_domain() + - iommu/vt-d: Simplify check in identity_mapping() + * Backport mlx5e fix for tunnel offload (LP: #1921769) + - net/mlx5e: Check tunnel offload is required before setting SWP + * Bcache bypasse writeback on caching device with fragmentation (LP: #1900438) + - bcache: consider the fragmentation when update the writeback rate + * Fix implicit declaration warnings for kselftests/memfd test on newer + releases (LP: #1910323) + - selftests/memfd: Fix implicit declaration warnings + * net/mlx5e: Add missing capability check for uplink follow (LP: #1921104) + - net/mlx5e: Add missing capability check for uplink follow + * [UBUNUT 21.04] s390/vtime: fix increased steal time accounting + (LP: #1921498) + - s390/vtime: fix increased steal time accounting + * Mute/Mic-mute LEDs are not work on HP 850/840/440 G8 Laptops (LP: #1920030) + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 840 G8 + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 440 G8 + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 850 G8 + * Focal update: v5.4.106 upstream stable release (LP: #1920246) + - uapi: nfnetlink_cthelper.h: fix userspace compilation error + - powerpc/pseries: Don't enforce MSI affinity with kdump + - ath9k: fix transmitting to stations in dynamic SMPS mode + - net: Fix gro aggregation for udp encaps with zero csum + - net: check if protocol extracted by virtio_net_hdr_set_proto is correct + - net: avoid infinite loop in mpls_gso_segment when mpls_hlen == 0 + - sh_eth: fix TRSCER mask for SH771x + - can: skb: can_skb_set_owner(): fix ref counting if socket was closed before + setting skb ownership + - can: flexcan: assert FRZ bit in flexcan_chip_freeze() + - can: flexcan: enable RX FIFO after FRZ/HALT valid + - can: flexcan: invoke flexcan_chip_freeze() to enter freeze mode + - can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before + entering Normal Mode + - tcp: add sanity tests to TCP_QUEUE_SEQ + - netfilter: nf_nat: undo erroneous tcp edemux lookup + - netfilter: x_tables: gpf inside xt_find_revision() + - selftests/bpf: No need to drop the packet when there is no geneve opt + - selftests/bpf: Mask bpf_csum_diff() return value to 16 bits in test_verifier + - samples, bpf: Add missing munmap in xdpsock + - ibmvnic: always store valid MAC address + - mt76: dma: do not report truncated frames to mac80211 + - powerpc/603: Fix protection of user pages mapped with PROT_NONE + - mount: fix mounting of detached mounts onto targets that reside on shared + mounts + - cifs: return proper error code in statfs(2) + - Revert "mm, slub: consider rest of partial list if acquire_slab() fails" + - net: enetc: don't overwrite the RSS indirection table when initializing + - net/mlx4_en: update moderation when config reset + - net: stmmac: fix incorrect DMA channel intr enable setting of EQoS v4.10 + - nexthop: Do not flush blackhole nexthops when loopback goes down + - net: sched: avoid duplicates in classes dump + - net: usb: qmi_wwan: allow qmimux add/del with master up + - netdevsim: init u64 stats for 32bit hardware + - cipso,calipso: resolve a number of problems with the DOI refcounts + - net: lapbether: Remove netif_start_queue / netif_stop_queue + - net: davicom: Fix regulator not turned off on failed probe + - net: davicom: Fix regulator not turned off on driver removal + - net: qrtr: fix error return code of qrtr_sendmsg() + - ixgbe: fail to create xfrm offload of IPsec tunnel mode SA + - net: stmmac: stop each tx channel independently + - net: stmmac: fix watchdog timeout during suspend/resume stress test + - selftests: forwarding: Fix race condition in mirror installation + - perf traceevent: Ensure read cmdlines are null terminated. + - net: hns3: fix query vlan mask value error for flow director + - net: hns3: fix bug when calculating the TCAM table info + - s390/cio: return -EFAULT if copy_to_user() fails again + - bnxt_en: reliably allocate IRQ table on reset to avoid crash + - drm/compat: Clear bounce structures + - drm/shmem-helper: Check for purged buffers in fault handler + - drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff + - drm: meson_drv add shutdown function + - s390/cio: return -EFAULT if copy_to_user() fails + - s390/crypto: return -EFAULT if copy_to_user() fails + - qxl: Fix uninitialised struct field head.surface_id + - sh_eth: fix TRSCER mask for R7S9210 + - media: usbtv: Fix deadlock on suspend + - media: v4l: vsp1: Fix uif null pointer access + - media: v4l: vsp1: Fix bru null pointer access + - media: rc: compile rc-cec.c into rc-core + - [Config] update abi for rc-cec + - net: hns3: fix error mask definition of flow director + - net: enetc: initialize RFS/RSS memories for unused ports too + - net: phy: fix save wrong speed and duplex problem if autoneg is on + - i2c: rcar: faster irq code to minimize HW race condition + - i2c: rcar: optimize cacheline to minimize HW race condition + - udf: fix silent AED tagLocation corruption + - mmc: mxs-mmc: Fix a resource leak in an error handling path in + 'mxs_mmc_probe()' + - mmc: mediatek: fix race condition between msdc_request_timeout and irq + - Platform: OLPC: Fix probe error handling + - powerpc/pci: Add ppc_md.discover_phbs() + - spi: stm32: make spurious and overrun interrupts visible + - powerpc: improve handling of unrecoverable system reset + - powerpc/perf: Record counter overflow always if SAMPLE_IP is unset + - HID: logitech-dj: add support for the new lightspeed connection iteration + - powerpc/64: Fix stack trace not displaying final frame + - iommu/amd: Fix performance counter initialization + - sparc32: Limit memblock allocation to low memory + - sparc64: Use arch_validate_flags() to validate ADI flag + - Input: applespi - don't wait for responses to commands indefinitely. + - PCI: xgene-msi: Fix race in installing chained irq handler + - PCI: mediatek: Add missing of_node_put() to fix reference leak + - kbuild: clamp SUBLEVEL to 255 + - PCI: Fix pci_register_io_range() memory leak + - i40e: Fix memory leak in i40e_probe + - s390/smp: __smp_rescan_cpus() - move cpumask away from stack + - sysctl.c: fix underflow value setting risk in vm_table + - scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling + - scsi: target: core: Add cmd length set before cmd complete + - scsi: target: core: Prevent underflow for service actions + - ALSA: usb: Add Plantronics C320-M USB ctrl msg delay quirk + - ALSA: hda/hdmi: Cancel pending works before suspend + - ALSA: hda/ca0132: Add Sound BlasterX AE-5 Plus support + - ALSA: hda: Drop the BATCH workaround for AMD controllers + - ALSA: hda: Flush pending unsolicited events before suspend + - ALSA: hda: Avoid spurious unsol event handling during S3/S4 + - ALSA: usb-audio: Fix "cannot get freq eq" errors on Dell AE515 sound bar + - ALSA: usb-audio: Apply the control quirk to Plantronics headsets + - Revert 95ebabde382c ("capabilities: Don't allow writing ambiguous v3 file + capabilities") + - arm64: kasan: fix page_alloc tagging with DEBUG_VIRTUAL + - s390/dasd: fix hanging DASD driver unbind + - s390/dasd: fix hanging IO request during DASD driver unbind + - software node: Fix node registration + - mmc: core: Fix partition switch time for eMMC + - mmc: cqhci: Fix random crash when remove mmc module/card + - Goodix Fingerprint device is not a modem + - USB: gadget: u_ether: Fix a configfs return code + - usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio + slot + - usb: gadget: f_uac1: stop playback on function disable + - usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement + - usb: dwc3: qcom: Honor wakeup enabled/disabled state + - USB: usblp: fix a hang in poll() if disconnected + - usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM + - usb: xhci: do not perform Soft Retry for some xHCI hosts + - xhci: Improve detection of device initiated wake signal. + - usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing + - xhci: Fix repeated xhci wake after suspend due to uncleared internal wake + state + - USB: serial: io_edgeport: fix memory leak in edge_startup + - USB: serial: ch341: add new Product ID + - USB: serial: cp210x: add ID for Acuity Brands nLight Air Adapter + - USB: serial: cp210x: add some more GE USB IDs + - usbip: fix stub_dev to check for stream socket + - usbip: fix vhci_hcd to check for stream socket + - usbip: fix vudc to check for stream socket + - usbip: fix stub_dev usbip_sockfd_store() races leading to gpf + - usbip: fix vhci_hcd attach_store() races leading to gpf + - usbip: fix vudc usbip_sockfd_store races leading to gpf + - misc/pvpanic: Export module FDT device table + - misc: fastrpc: restrict user apps from sending kernel RPC messages + - staging: rtl8192u: fix ->ssid overflow in r8192_wx_set_scan() + - staging: rtl8188eu: prevent ->ssid overflow in rtw_wx_set_scan() + - staging: rtl8712: unterminated string leads to read overflow + - staging: rtl8188eu: fix potential memory corruption in + rtw_check_beacon_data() + - staging: ks7010: prevent buffer overflow in ks_wlan_set_scan() + - staging: rtl8712: Fix possible buffer overflow in r8712_sitesurvey_cmd + - staging: rtl8192e: Fix possible buffer overflow in _rtl92e_wx_set_scan + - staging: comedi: addi_apci_1032: Fix endian problem for COS sample + - staging: comedi: addi_apci_1500: Fix endian problem for command sample + - staging: comedi: adv_pci1710: Fix endian problem for AI command data + - staging: comedi: das6402: Fix endian problem for AI command data + - staging: comedi: das800: Fix endian problem for AI command data + - staging: comedi: dmm32at: Fix endian problem for AI command data + - staging: comedi: me4000: Fix endian problem for AI command data + - staging: comedi: pcl711: Fix endian problem for AI command data + - staging: comedi: pcl818: Fix endian problem for AI command data + - sh_eth: fix TRSCER mask for R7S72100 + - arm64/mm: Fix pfn_valid() for ZONE_DEVICE based memory + - SUNRPC: Set memalloc_nofs_save() for sync tasks + - NFS: Don't revalidate the directory permissions on a lookup failure + - NFS: Don't gratuitously clear the inode cache when lookup failed + - NFSv4.2: fix return value of _nfs4_get_security_label() + - block: rsxx: fix error return code of rsxx_pci_probe() + - configfs: fix a use-after-free in __configfs_open_file + - arm64: mm: use a 48-bit ID map when possible on 52-bit VA builds + - hrtimer: Update softirq_expires_next correctly after + __hrtimer_get_next_event() + - stop_machine: mark helpers __always_inline + - include/linux/sched/mm.h: use rcu_dereference in in_vfork() + - zram: fix return value on writeback_store + - sched/membarrier: fix missing local execution of ipi_sync_rq_state() + - powerpc/64s: Fix instruction encoding for lis in ppc_function_entry() + - binfmt_misc: fix possible deadlock in bm_register_write + - x86/unwind/orc: Disable KASAN checking in the ORC unwinder, part 2 + - KVM: arm64: Fix exclusive limit for IPA size + - nvme: unlink head after removing last namespace + - nvme: release namespace head reference on error + - KVM: arm64: Ensure I-cache isolation between vcpus of a same VM + - KVM: arm64: Reject VM creation when the default IPA size is unsupported + - xen/events: reset affinity of 2-level event when tearing it down + - xen/events: don't unmask an event channel when an eoi is pending + - xen/events: avoid handling the same event on two cpus at the same time + - Linux 5.4.106 + * Focal update: v5.4.105 upstream stable release (LP: #1920244) + - net: dsa: add GRO support via gro_cells + - dm table: fix iterate_devices based device capability checks + - dm table: fix DAX iterate_devices based device capability checks + - dm table: fix zoned iterate_devices based device capability checks + - ACPICA: Fix race in generic_serial_bus (I2C) and GPIO op_region parameter + handling + - iommu/amd: Fix sleeping in atomic in increase_address_space() + - mwifiex: pcie: skip cancel_work_sync() on reset failure path + - platform/x86: acer-wmi: Cleanup ACER_CAP_FOO defines + - platform/x86: acer-wmi: Cleanup accelerometer device handling + - platform/x86: acer-wmi: Add new force_caps module parameter + - platform/x86: acer-wmi: Add ACER_CAP_SET_FUNCTION_MODE capability flag + - platform/x86: acer-wmi: Add support for SW_TABLET_MODE on Switch devices + - platform/x86: acer-wmi: Add ACER_CAP_KBD_DOCK quirk for the Aspire Switch + 10E SW3-016 + - HID: mf: add support for 0079:1846 Mayflash/Dragonrise USB Gamecube Adapter + - media: cx23885: add more quirks for reset DMA on some AMD IOMMU + - ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 + - ASoC: Intel: bytcr_rt5640: Add quirk for ARCHOS Cesium 140 + - PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller + - misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom + - drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register + - mmc: sdhci-of-dwcmshc: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN + - HID: i2c-hid: Add I2C_HID_QUIRK_NO_IRQ_AFTER_RESET for ITE8568 EC on Voyo + Winpad A15 + - nvme-pci: mark Seagate Nytro XM1440 as QUIRK_NO_NS_DESC_LIST. + - nvme-pci: add quirks for Lexar 256GB SSD + - Linux 5.4.105 + * Focal update: v5.4.104 upstream stable release (LP: #1920238) + - tpm, tpm_tis: Decorate tpm_tis_gen_interrupt() with request_locality() + - tpm, tpm_tis: Decorate tpm_get_timeouts() with request_locality() + - btrfs: raid56: simplify tracking of Q stripe presence + - btrfs: fix raid6 qstripe kmap + - btrfs: validate qgroup inherit for SNAP_CREATE_V2 ioctl + - btrfs: free correct amount of space in btrfs_delayed_inode_reserve_metadata + - btrfs: unlock extents in btrfs_zero_range in case of quota reservation + errors + - btrfs: fix warning when creating a directory with smack enabled + - PM: runtime: Update device status before letting suppliers suspend + - dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size + - dm verity: fix FEC for RS roots unaligned to block size + - drm/amdgpu: fix parameter error of RREG32_PCIE() in amdgpu_regs_pcie + - arm64: ptrace: Fix seccomp of traced syscall -1 (NO_SYSCALL) + - crypto - shash: reduce minimum alignment of shash_desc structure + - usbip: tools: fix build error for multiple definition + - ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits + - RDMA/rxe: Fix missing kconfig dependency on CRYPTO + - IB/mlx5: Add missing error code + - ALSA: hda: intel-nhlt: verify config type + - ftrace: Have recordmcount use w8 to read relp->r_info in + arm64_is_fake_mcount + - rsxx: Return -EFAULT if copy_to_user() fails + - r8169: fix resuming from suspend on RTL8105e if machine runs on battery + - Linux 5.4.104 + * Focal update: v5.4.103 upstream stable release (LP: #1920235) + - net: usb: qmi_wwan: support ZTE P685M modem + - nvme-pci: refactor nvme_unmap_data + - nvme-pci: fix error unwind in nvme_map_data + - arm64 module: set plt* section addresses to 0x0 + - MIPS: VDSO: Use CLANG_FLAGS instead of filtering out '--target=' + - JFS: more checks for invalid superblock + - udlfb: Fix memory leak in dlfb_usb_probe + - media: mceusb: sanity check for prescaler value + - erofs: fix shift-out-of-bounds of blkszbits + - media: v4l2-ctrls.c: fix shift-out-of-bounds in std_validate + - xfs: Fix assert failure in xfs_setattr_size() + - net/af_iucv: remove WARN_ONCE on malformed RX packets + - smackfs: restrict bytes count in smackfs write functions + - net: fix up truesize of cloned skb in skb_prepare_for_shift() + - nbd: handle device refs for DESTROY_ON_DISCONNECT properly + - mm/hugetlb.c: fix unnecessary address expansion of pmd sharing + - net: bridge: use switchdev for port flags set through sysfs too + - net: ag71xx: remove unnecessary MTU reservation + - net: fix dev_ifsioc_locked() race condition + - dt-bindings: ethernet-controller: fix fixed-link specification + - dt-bindings: net: btusb: DT fix s/interrupt-name/interrupt-names/ + - MIPS: Drop 32-bit asm string functions + - drm/virtio: use kvmalloc for large allocations + - rsi: Fix TX EAPOL packet handling against iwlwifi AP + - rsi: Move card interrupt handling to RX thread + - staging: fwserial: Fix error handling in fwserial_create + - x86/reboot: Add Zotac ZBOX CI327 nano PCI reboot quirk + - vt/consolemap: do font sum unsigned + - wlcore: Fix command execute failure 19 for wl12xx + - Bluetooth: hci_h5: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for btrtl + - pktgen: fix misuse of BUG_ON() in pktgen_thread_worker() + - ath10k: fix wmi mgmt tx queue full due to race condition + - x86/build: Treat R_386_PLT32 relocation as R_386_PC32 + - Bluetooth: Fix null pointer dereference in amp_read_loc_assoc_final_data + - staging: most: sound: add sanity check for function argument + - staging: bcm2835-audio: Replace unsafe strcpy() with strscpy() + - brcmfmac: Add DMI nvram filename quirk for Predia Basic tablet + - brcmfmac: Add DMI nvram filename quirk for Voyo winpad A15 tablet + - drm/hisilicon: Fix use-after-free + - crypto: tcrypt - avoid signed overflow in byte count + - drm/amdgpu: Add check to prevent IH overflow + - PCI: Add a REBAR size quirk for Sapphire RX 5600 XT Pulse + - drm/amd/display: Guard against NULL pointer deref when get_i2c_info fails + - media: uvcvideo: Allow entities with no pads + - f2fs: handle unallocated section and zone on pinned/atgc + - f2fs: fix to set/clear I_LINKABLE under i_lock + - nvme-core: add cancel tagset helpers + - nvme-rdma: add clean action for failed reconnection + - nvme-tcp: add clean action for failed reconnection + - ASoC: Intel: Add DMI quirk table to soc_intel_is_byt_cr() + - btrfs: fix error handling in commit_fs_roots + - perf/x86/kvm: Add Cascade Lake Xeon steppings to isolation_ucodes[] + - parisc: Bump 64-bit IRQ stack size to 64 KB + - sched/features: Fix hrtick reprogramming + - ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R + tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet + - ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet + - Xen/gnttab: handle p2m update errors on a per-slot basis + - xen-netback: respect gnttab_map_refs()'s return value + - zsmalloc: account the number of compacted pages correctly + - swap: fix swapfile read/write offset + - media: v4l: ioctl: Fix memory leak in video_usercopy + - ALSA: hda/realtek: Add quirk for Clevo NH55RZQ + - ALSA: hda/realtek: Add quirk for Intel NUC 10 + - ALSA: hda/realtek: Apply dual codec quirks for MSI Godlike X570 board + - Linux 5.4.103 + * Focal update: v5.4.102 upstream stable release (LP: #1918974) + - vmlinux.lds.h: add DWARF v5 sections + - kvm: x86: replace kvm_spec_ctrl_test_value with runtime test on the host + - debugfs: be more robust at handling improper input in debugfs_lookup() + - debugfs: do not attempt to create a new file before the filesystem is + initalized + - kdb: Make memory allocations more robust + - PCI: qcom: Use PHY_REFCLK_USE_PAD only for ipq8064 + - PCI: Decline to resize resources if boot config must be preserved + - virt: vbox: Do not use wait_event_interruptible when called from kernel + context + - bfq: Avoid false bfq queue merging + - ALSA: usb-audio: Fix PCM buffer allocation in non-vmalloc mode + - MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section + - random: fix the RNDRESEEDCRNG ioctl + - ath10k: Fix error handling in case of CE pipe init failure + - Bluetooth: btqcomsmd: Fix a resource leak in error handling paths in the + probe function + - Bluetooth: hci_uart: Fix a race for write_work scheduling + - Bluetooth: Fix initializing response id after clearing struct + - ARM: dts: exynos: correct PMIC interrupt trigger level on Artik 5 + - ARM: dts: exynos: correct PMIC interrupt trigger level on Monk + - ARM: dts: exynos: correct PMIC interrupt trigger level on Rinato + - ARM: dts: exynos: correct PMIC interrupt trigger level on Spring + - ARM: dts: exynos: correct PMIC interrupt trigger level on Arndale Octa + - ARM: dts: exynos: correct PMIC interrupt trigger level on Odroid XU3 family + - arm64: dts: exynos: correct PMIC interrupt trigger level on TM2 + - arm64: dts: exynos: correct PMIC interrupt trigger level on Espresso + - memory: mtk-smi: Fix PM usage counter unbalance in mtk_smi ops + - bpf: Add bpf_patch_call_args prototype to include/linux/bpf.h + - bpf: Avoid warning when re-casting __bpf_call_base into __bpf_call_base_args + - arm64: dts: allwinner: A64: properly connect USB PHY to port 0 + - arm64: dts: allwinner: H6: properly connect USB PHY to port 0 + - arm64: dts: allwinner: Drop non-removable from SoPine/LTS SD card + - arm64: dts: allwinner: H6: Allow up to 150 MHz MMC bus frequency + - arm64: dts: allwinner: A64: Limit MMC2 bus frequency to 150 MHz + - cpufreq: brcmstb-avs-cpufreq: Free resources in error path + - cpufreq: brcmstb-avs-cpufreq: Fix resource leaks in ->remove() + - ACPICA: Fix exception code class checks + - usb: gadget: u_audio: Free requests only after callback + - Bluetooth: drop HCI device reference before return + - Bluetooth: Put HCI device if inquiry procedure interrupts + - memory: ti-aemif: Drop child node when jumping out loop + - ARM: dts: Configure missing thermal interrupt for 4430 + - usb: dwc2: Do not update data length if it is 0 on inbound transfers + - usb: dwc2: Abort transaction after errors with unknown reason + - usb: dwc2: Make "trimming xfer length" a debug message + - staging: rtl8723bs: wifi_regd.c: Fix incorrect number of regulatory rules + - ARM: dts: armada388-helios4: assign pinctrl to LEDs + - ARM: dts: armada388-helios4: assign pinctrl to each fan + - arm64: dts: armada-3720-turris-mox: rename u-boot mtd partition to + a53-firmware + - Bluetooth: btusb: Fix memory leak in btusb_mtk_wmt_recv + - arm64: dts: msm8916: Fix reserved and rfsa nodes unit address + - ARM: s3c: fix fiq for clang IAS + - soc: aspeed: snoop: Add clock control logic + - bpf_lru_list: Read double-checked variable once without lock + - ath9k: fix data bus crash when setting nf_override via debugfs + - ibmvnic: Set to CLOSED state even on error + - bnxt_en: reverse order of TX disable and carrier off + - xen/netback: fix spurious event detection for common event case + - mac80211: fix potential overflow when multiplying to u32 integers + - bpf: Fix bpf_fib_lookup helper MTU check for SKB ctx + - tcp: fix SO_RCVLOWAT related hangs under mem pressure + - net: axienet: Handle deferred probe on clock properly + - cxgb4/chtls/cxgbit: Keeping the max ofld immediate data size same in cxgb4 + and ulds + - b43: N-PHY: Fix the update of coef for the PHY revision >= 3case + - ibmvnic: add memory barrier to protect long term buffer + - ibmvnic: skip send_request_unmap for timeout reset + - net: amd-xgbe: Reset the PHY rx data path when mailbox command timeout + - net: amd-xgbe: Fix NETDEV WATCHDOG transmit queue timeout warning + - net: amd-xgbe: Reset link when the link never comes back + - net: amd-xgbe: Fix network fluctuations when using 1G BELFUSE SFP + - net: mvneta: Remove per-cpu queue mapping for Armada 3700 + - fbdev: aty: SPARC64 requires FB_ATY_CT + - drm/gma500: Fix error return code in psb_driver_load() + - gma500: clean up error handling in init + - drm/fb-helper: Add missed unlocks in setcmap_legacy() + - crypto: sun4i-ss - linearize buffers content must be kept + - crypto: sun4i-ss - fix kmap usage + - crypto: arm64/aes-ce - really hide slower algos when faster ones are enabled + - drm/amdgpu: Fix macro name _AMDGPU_TRACE_H_ in preprocessor if condition + - MIPS: c-r4k: Fix section mismatch for loongson2_sc_init + - MIPS: lantiq: Explicitly compare LTQ_EBU_PCC_ISTAT against 0 + - media: i2c: ov5670: Fix PIXEL_RATE minimum value + - media: imx: Unregister csc/scaler only if registered + - media: imx: Fix csc/scaler unregister + - media: camss: missing error code in msm_video_register() + - media: vsp1: Fix an error handling path in the probe function + - media: em28xx: Fix use-after-free in em28xx_alloc_urbs + - media: media/pci: Fix memleak in empress_init + - media: tm6000: Fix memleak in tm6000_start_stream + - media: aspeed: fix error return code in aspeed_video_setup_video() + - ASoC: cs42l56: fix up error handling in probe + - evm: Fix memleak in init_desc + - crypto: bcm - Rename struct device_private to bcm_device_private + - drm/sun4i: tcon: fix inverted DCLK polarity + - MIPS: properly stop .eh_frame generation + - bsg: free the request before return error code + - drm/amd/display: Fix 10/12 bpc setup in DCE output bit depth reduction. + - drm/amd/display: Fix HDMI deep color output for DCE 6-11. + - media: software_node: Fix refcounts in software_node_get_next_child() + - media: lmedm04: Fix misuse of comma + - media: qm1d1c0042: fix error return code in qm1d1c0042_init() + - media: cx25821: Fix a bug when reallocating some dma memory + - media: pxa_camera: declare variable when DEBUG is defined + - media: uvcvideo: Accept invalid bFormatIndex and bFrameIndex values + - sched/eas: Don't update misfit status if the task is pinned + - mtd: parser: imagetag: fix error codes in + bcm963xx_parse_imagetag_partitions() + - crypto: talitos - Work around SEC6 ERRATA (AES-CTR mode data size error) + - drm/nouveau: bail out of nouveau_channel_new if channel init fails + - ata: ahci_brcm: Add back regulators management + - ASoC: cpcap: fix microphone timeslot mask + - mtd: parsers: afs: Fix freeing the part name memory in failure + - f2fs: fix to avoid inconsistent quota data + - drm/amdgpu: Prevent shift wrapping in amdgpu_read_mask() + - f2fs: fix a wrong condition in __submit_bio + - Drivers: hv: vmbus: Avoid use-after-free in vmbus_onoffer_rescind() + - ASoC: SOF: debug: Fix a potential issue on string buffer termination + - btrfs: clarify error returns values in __load_free_space_cache + - hwrng: timeriomem - Fix cooldown period calculation + - crypto: ecdh_helper - Ensure 'len >= secret.len' in decode_key() + - ima: Free IMA measurement buffer on error + - ima: Free IMA measurement buffer after kexec syscall + - ASoC: simple-card-utils: Fix device module clock + - fs/jfs: fix potential integer overflow on shift of a int + - jffs2: fix use after free in jffs2_sum_write_data() + - ubifs: Fix memleak in ubifs_init_authentication + - ubifs: Fix error return code in alloc_wbufs() + - capabilities: Don't allow writing ambiguous v3 file capabilities + - HSI: Fix PM usage counter unbalance in ssi_hw_init + - clk: meson: clk-pll: fix initializing the old rate (fallback) for a PLL + - clk: meson: clk-pll: make "ret" a signed integer + - clk: meson: clk-pll: propagate the error from meson_clk_pll_set_rate() + - quota: Fix memory leak when handling corrupted quota file + - i2c: iproc: handle only slave interrupts which are enabled + - i2c: iproc: update slave isr mask (ISR_MASK_SLAVE) + - i2c: iproc: handle master read request + - spi: cadence-quadspi: Abort read if dummy cycles required are too many + - clk: sunxi-ng: h6: Fix CEC clock + - HID: core: detect and skip invalid inputs to snto32() + - RDMA/siw: Fix handling of zero-sized Read and Receive Queues. + - dmaengine: fsldma: Fix a resource leak in the remove function + - dmaengine: fsldma: Fix a resource leak in an error handling path of the + probe function + - dmaengine: owl-dma: Fix a resource leak in the remove function + - dmaengine: hsu: disable spurious interrupt + - mfd: bd9571mwv: Use devm_mfd_add_devices() + - fdt: Properly handle "no-map" field in the memory region + - of/fdt: Make sure no-map does not remove already reserved regions + - power: reset: at91-sama5d2_shdwc: fix wkupdbc mask + - rtc: s5m: select REGMAP_I2C + - clocksource/drivers/ixp4xx: Select TIMER_OF when needed + - clocksource/drivers/mxs_timer: Add missing semicolon when DEBUG is defined + - RDMA/mlx5: Use the correct obj_id upon DEVX TIR creation + - clk: sunxi-ng: h6: Fix clock divider range on some clocks + - regulator: axp20x: Fix reference cout leak + - certs: Fix blacklist flag type confusion + - regulator: s5m8767: Fix reference count leak + - spi: atmel: Put allocated master before return + - regulator: s5m8767: Drop regulators OF node reference + - regulator: core: Avoid debugfs: Directory ... already present! error + - isofs: release buffer head before return + - auxdisplay: ht16k33: Fix refresh rate handling + - objtool: Fix error handling for STD/CLD warnings + - objtool: Fix ".cold" section suffix check for newer versions of GCC + - IB/umad: Return EIO in case of when device disassociated + - IB/umad: Return EPOLLERR in case of when device disassociated + - KVM: PPC: Make the VMX instruction emulation routines static + - powerpc/47x: Disable 256k page size + - mmc: sdhci-sprd: Fix some resource leaks in the remove function + - mmc: usdhi6rol0: Fix a resource leak in the error handling path of the probe + - mmc: renesas_sdhi_internal_dmac: Fix DMA buffer alignment from 8 to + 128-bytes + - ARM: 9046/1: decompressor: Do not clear SCTLR.nTLSMD for ARMv7+ cores + - i2c: qcom-geni: Store DMA mapping data in geni_i2c_dev struct + - amba: Fix resource leak for drivers without .remove + - IB/mlx5: Return appropriate error code instead of ENOMEM + - IB/cm: Avoid a loop when device has 255 ports + - tracepoint: Do not fail unregistering a probe due to memory failure + - perf tools: Fix DSO filtering when not finding a map for a sampled address + - perf vendor events arm64: Fix Ampere eMag event typo + - RDMA/rxe: Fix coding error in rxe_recv.c + - RDMA/rxe: Fix coding error in rxe_rcv_mcast_pkt + - RDMA/rxe: Correct skb on loopback path + - spi: stm32: properly handle 0 byte transfer + - mfd: wm831x-auxadc: Prevent use after free in wm831x_auxadc_read_irq() + - powerpc/pseries/dlpar: handle ibm, configure-connector delay status + - powerpc/8xx: Fix software emulation interrupt + - clk: qcom: gcc-msm8998: Fix Alpha PLL type for all GPLLs + - RDMA/hns: Fixed wrong judgments in the goto branch + - RDMA/siw: Fix calculation of tx_valid_cpus size + - RDMA/hns: Fix type of sq_signal_bits + - spi: pxa2xx: Fix the controller numbering for Wildcat Point + - regulator: qcom-rpmh: fix pm8009 ldo7 + - clk: aspeed: Fix APLL calculate formula from ast2600-A2 + - nfsd: register pernet ops last, unregister first + - RDMA/hns: Fixes missing error code of CMDQ + - Input: sur40 - fix an error code in sur40_probe() + - perf intel-pt: Fix missing CYC processing in PSB + - perf intel-pt: Fix premature IPC + - perf test: Fix unaligned access in sample parsing test + - Input: elo - fix an error code in elo_connect() + - sparc64: only select COMPAT_BINFMT_ELF if BINFMT_ELF is set + - misc: eeprom_93xx46: Fix module alias to enable module autoprobe + - phy: rockchip-emmc: emmc_phy_init() always return 0 + - misc: eeprom_93xx46: Add module alias to avoid breaking support for non + device tree users + - soundwire: cadence: fix ACK/NAK handling + - pwm: rockchip: rockchip_pwm_probe(): Remove superfluous clk_unprepare() + - VMCI: Use set_page_dirty_lock() when unregistering guest memory + - PCI: Align checking of syscall user config accessors + - mei: hbm: call mei_set_devstate() on hbm stop response + - drm/msm/dsi: Correct io_start for MSM8994 (20nm PHY) + - drm/msm/mdp5: Fix wait-for-commit for cmd panels + - vfio/iommu_type1: Fix some sanity checks in detach group + - ext4: fix potential htree index checksum corruption + - nvmem: core: Fix a resource leak on error in nvmem_add_cells_from_of() + - nvmem: core: skip child nodes not matching binding + - regmap: sdw: use _no_pm functions in regmap_read/write + - i40e: Fix flow for IPv6 next header (extension header) + - i40e: Add zero-initialization of AQ command structures + - i40e: Fix overwriting flow control settings during driver loading + - i40e: Fix addition of RX filters after enabling FW LLDP agent + - i40e: Fix VFs not created + - i40e: Fix add TC filter for IPv6 + - vfio/type1: Use follow_pte() + - net/mlx4_core: Add missed mlx4_free_cmd_mailbox() + - vxlan: move debug check after netdev unregister + - ocfs2: fix a use after free on error + - mm/memory.c: fix potential pte_unmap_unlock pte error + - mm/hugetlb: fix potential double free in hugetlb_register_node() error path + - mm/compaction: fix misbehaviors of fast_find_migrateblock() + - r8169: fix jumbo packet handling on RTL8168e + - arm64: Add missing ISB after invalidating TLB in __primary_switch + - i2c: brcmstb: Fix brcmstd_send_i2c_cmd condition + - mm/rmap: fix potential pte_unmap on an not mapped pte + - scsi: bnx2fc: Fix Kconfig warning & CNIC build errors + - blk-settings: align max_sectors on "logical_block_size" boundary + - ACPI: property: Fix fwnode string properties matching + - ACPI: configfs: add missing check after configfs_register_default_group() + - HID: logitech-dj: add support for keyboard events in eQUAD step 4 Gaming + - HID: wacom: Ignore attempts to overwrite the touch_max value from HID + - Input: raydium_ts_i2c - do not send zero length + - Input: xpad - add support for PowerA Enhanced Wired Controller for Xbox + Series X|S + - Input: joydev - prevent potential read overflow in ioctl + - Input: i8042 - add ASUS Zenbook Flip to noselftest list + - media: mceusb: Fix potential out-of-bounds shift + - USB: serial: option: update interface mapping for ZTE P685M + - usb: musb: Fix runtime PM race in musb_queue_resume_work + - usb: dwc3: gadget: Fix setting of DEPCFG.bInterval_m1 + - usb: dwc3: gadget: Fix dep->interval for fullspeed interrupt + - USB: serial: ftdi_sio: fix FTX sub-integer prescaler + - USB: serial: mos7840: fix error code in mos7840_write() + - USB: serial: mos7720: fix error code in mos7720_write() + - ALSA: hda: Add another CometLake-H PCI ID + - ALSA: hda/realtek: modify EAPD in the ALC886 + - Revert "bcache: Kill btree_io_wq" + - bcache: Give btree_io_wq correct semantics again + - bcache: Move journal work to new flush wq + - drm/amd/display: Add vupdate_no_lock interrupts for DCN2.1 + - drm/amdgpu: Set reference clock to 100Mhz on Renoir (v2) + - drm/nouveau/kms: handle mDP connectors + - drm/sched: Cancel and flush all outstanding jobs before finish. + - erofs: initialized fields can only be observed after bit is set + - tpm_tis: Fix check_locality for correct locality acquisition + - tpm_tis: Clean up locality release + - KEYS: trusted: Fix migratable=1 failing + - btrfs: abort the transaction if we fail to inc ref in btrfs_copy_root + - btrfs: fix reloc root leak with 0 ref reloc roots on recovery + - btrfs: splice remaining dirty_bg's onto the transaction dirty bg list + - btrfs: fix extent buffer leak on failure to copy root + - crypto: arm64/sha - add missing module aliases + - crypto: aesni - prevent misaligned buffers on the stack + - crypto: sun4i-ss - checking sg length is not sufficient + - crypto: sun4i-ss - handle BigEndian for cipher + - crypto: sun4i-ss - initialize need_fallback + - seccomp: Add missing return in non-void function + - misc: rtsx: init of rts522a add OCP power off when no card is present + - drivers/misc/vmw_vmci: restrict too big queue size in qp_host_alloc_queue + - pstore: Fix typo in compression option name + - dts64: mt7622: fix slow sd card access + - staging/mt7621-dma: mtk-hsdma.c->hsdma-mt7621.c + - staging: gdm724x: Fix DMA from stack + - staging: rtl8188eu: Add Edimax EW-7811UN V2 to device table + - media: ipu3-cio2: Fix mbus_code processing in cio2_subdev_set_fmt() + - x86/virt: Eat faults on VMXOFF in reboot flows + - x86/reboot: Force all cpus to exit VMX root if VMX is supported + - powerpc/prom: Fix "ibm,arch-vec-5-platform-support" scan + - rcu: Pull deferred rcuog wake up to rcu_eqs_enter() callers + - rcu/nocb: Perform deferred wake up before last idle's need_resched() check + - floppy: reintroduce O_NDELAY fix + - arm64: kexec_file: fix memory leakage in create_dtb() when fdt_open_into() + fails + - arm64: uprobe: Return EOPNOTSUPP for AARCH32 instruction probing + - watchdog: qcom: Remove incorrect usage of QCOM_WDT_ENABLE_IRQ + - watchdog: mei_wdt: request stop on unregister + - mtd: spi-nor: sfdp: Fix last erase region marking + - mtd: spi-nor: sfdp: Fix wrong erase type bitmask for overlaid region + - mtd: spi-nor: core: Fix erase type discovery for overlaid region + - mtd: spi-nor: core: Add erase size check for erase command initialization + - mtd: spi-nor: hisi-sfc: Put child node np on error path + - fs/affs: release old buffer head on error path + - seq_file: document how per-entry resources are managed. + - x86: fix seq_file iteration for pat/memtype.c + - hugetlb: fix update_and_free_page contig page struct assumption + - hugetlb: fix copy_huge_page_from_user contig page struct assumption + - arm64: Extend workaround for erratum 1024718 to all versions of Cortex-A55 + - media: smipcie: fix interrupt handling and IR timeout + - module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols + - mmc: sdhci-esdhc-imx: fix kernel panic when remove module + - powerpc/32s: Add missing call to kuep_lock on syscall entry + - spmi: spmi-pmic-arb: Fix hw_irq overflow + - gpio: pcf857x: Fix missing first interrupt + - printk: fix deadlock when kernel panic + - cpufreq: intel_pstate: Get per-CPU max freq via MSR_HWP_CAPABILITIES if + available + - s390/vtime: fix inline assembly clobber list + - virtio/s390: implement virtio-ccw revision 2 correctly + - um: mm: check more comprehensively for stub changes + - f2fs: fix out-of-repair __setattr_copy() + - sparc32: fix a user-triggerable oops in clear_user() + - spi: spi-synquacer: fix set_cs handling + - gfs2: Don't skip dlm unlock if glock has an lvb + - gfs2: Recursive gfs2_quota_hold in gfs2_iomap_end + - dm: fix deadlock when swapping to encrypted device + - dm writecache: fix writing beyond end of underlying device when shrinking + - dm era: Recover committed writeset after crash + - dm era: Verify the data block size hasn't changed + - dm era: Fix bitset memory leaks + - dm era: Use correct value size in equality function of writeset tree + - dm era: Reinitialize bitset cache before digesting a new writeset + - dm era: only resize metadata in preresume + - drm/i915: Reject 446-480MHz HDMI clock on GLK + - icmp: introduce helper for nat'd source address in network device context + - icmp: allow icmpv6_ndo_send to work with CONFIG_IPV6=n + - gtp: use icmp_ndo_send helper + - sunvnet: use icmp_ndo_send helper + - xfrm: interface: use icmp_ndo_send helper + - ipv6: icmp6: avoid indirect call for icmpv6_send() + - ipv6: silence compilation warning for non-IPV6 builds + - net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending + - net: sched: fix police ext initialization + - dm era: Update in-core bitset after committing the metadata + - net: qrtr: Fix memory leak in qrtr_tun_open + - ARM: dts: aspeed: Add LCLK to lpc-snoop + - Linux 5.4.102 + * eeh-basic.sh from powerpc in ubuntu_kernel_selftests failed with unexpected + operator on F-5.8 (LP: #1909428) + - selftests/powerpc: Make the test check in eeh-basic.sh posix compliant + + -- Tim Gardner Mon, 19 Apr 2021 11:18:24 -0600 + +linux-oracle (5.4.0-1043.46) focal; urgency=medium + + [ Ubuntu: 5.4.0-72.80 ] + + * overlayfs calls vfs_setxattr without cap_convert_nscap + - vfs: move cap_convert_nscap() call into vfs_setxattr() + * CVE-2021-3492 + - SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace() + error paths + - SAUCE: shiftfs: handle copy_to_user() return values correctly + * CVE-2021-29154 + - SAUCE: bpf, x86: Validate computation of branch displacements for x86-64 + - SAUCE: bpf, x86: Validate computation of branch displacements for x86-32 + + -- Kleber Sacilotto de Souza Tue, 13 Apr 2021 10:28:47 +0200 + +linux-oracle (5.4.0-1042.45) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1042.45 -proposed tracker (LP: #1921032) + + * Enforce CONFIG_DRM_BOCHS=m (LP: #1916290) + - [Config] [oracle] updateconfigs for CONFIG_DRM_BOCHS + + [ Ubuntu: 5.4.0-71.79 ] + + * focal/linux: 5.4.0-71.79 -proposed tracker (LP: #1921040) + * selftests: bpf verifier fails after sanitize_ptr_alu fixes (LP: #1920995) + - bpf: Simplify alu_limit masking for pointer arithmetic + - bpf: Add sanity check for upper ptr_limit + - bpf, selftests: Fix up some test_verifier cases for unprivileged + * Packaging resync (LP: #1786013) + - update dkms package versions + * Fix missing HDMI/DP audio on NVidia card after S3 (LP: #1918228) + - ALSA: hda/hdmi: Reduce hda_jack_tbl lookup at unsol event handling + - ALSA: hda/hdmi: Don't use standard hda_jack for generic HDMI jacks + - ALSA: hda/hdmi: Move runtime PM resume into hdmi_present_sense_via_verbs() + - ALSA: hda/hdmi: Move ELD parse and jack reporting into update_eld() + * Focal update: v5.4.101 upstream stable release (LP: #1918170) + - HID: make arrays usage and value to be the same + - USB: quirks: sort quirk entries + - usb: quirks: add quirk to start video capture on ELMO L-12F document camera + reliable + - ntfs: check for valid standard information attribute + - arm64: tegra: Add power-domain for Tegra210 HDA + - scripts: use pkg-config to locate libcrypto + - scripts: set proper OpenSSL include dir also for sign-file + - mm: unexport follow_pte_pmd + - mm: simplify follow_pte{,pmd} + - KVM: do not assume PTE is writable after follow_pfn + - mm: provide a saner PTE walking API for modules + - KVM: Use kvm_pfn_t for local PFN variable in hva_to_pfn_remapped() + - NET: usb: qmi_wwan: Adding support for Cinterion MV31 + - cxgb4: Add new T6 PCI device id 0x6092 + - cifs: Set CIFS_MOUNT_USE_PREFIX_PATH flag on setting cifs_sb->prepath. + - scripts/recordmcount.pl: support big endian for ARCH sh + - Linux 5.4.101 + * Focal update: v5.4.100 upstream stable release (LP: #1918168) + - KVM: SEV: fix double locking due to incorrect backport + - net: qrtr: Fix port ID for control messages + - net: bridge: Fix a warning when del bridge sysfs + - Xen/x86: don't bail early from clear_foreign_p2m_mapping() + - Xen/x86: also check kernel mapping in set_foreign_p2m_mapping() + - Xen/gntdev: correct dev_bus_addr handling in gntdev_map_grant_pages() + - Xen/gntdev: correct error checking in gntdev_map_grant_pages() + - xen/arm: don't ignore return errors from set_phys_to_machine + - xen-blkback: don't "handle" error by BUG() + - xen-netback: don't "handle" error by BUG() + - xen-scsiback: don't "handle" error by BUG() + - xen-blkback: fix error handling in xen_blkbk_map() + - media: pwc: Use correct device for DMA + - btrfs: fix backport of 2175bf57dc952 in 5.4.95 + - Linux 5.4.100 + * Focal update: v5.4.99 upstream stable release (LP: #1918167) + - gpio: ep93xx: fix BUG_ON port F usage + - gpio: ep93xx: Fix single irqchip with multi gpiochips + - tracing: Do not count ftrace events in top level enable output + - tracing: Check length before giving out the filter buffer + - arm/xen: Don't probe xenbus as part of an early initcall + - cgroup: fix psi monitor for root cgroup + - arm64: dts: rockchip: Fix PCIe DT properties on rk3399 + - arm64: dts: qcom: sdm845: Reserve LPASS clocks in gcc + - ARM: OMAP2+: Fix suspcious RCU usage splats for omap_enter_idle_coupled + - platform/x86: hp-wmi: Disable tablet-mode reporting by default + - ovl: perform vfs_getxattr() with mounter creds + - cap: fix conversions on getxattr + - ovl: skip getxattr of security labels + - nvme-pci: ignore the subsysem NQN on Phison E16 + - drm/amd/display: Add more Clock Sources to DCN2.1 + - drm/amd/display: Fix dc_sink kref count in emulated_link_detect + - drm/amd/display: Free atomic state after drm_atomic_commit + - drm/amd/display: Decrement refcount of dc_sink before reassignment + - riscv: virt_addr_valid must check the address belongs to linear mapping + - bfq-iosched: Revert "bfq: Fix computation of shallow depth" + - ARM: dts: lpc32xx: Revert set default clock rate of HCLK PLL + - ARM: ensure the signal page contains defined contents + - ARM: kexec: fix oops after TLB are invalidated + - vmlinux.lds.h: Create section for protection against instrumentation + - lkdtm: don't move ctors to .rodata + - mt76: dma: fix a possible memory leak in mt76_add_fragment() + - drm/vc4: hvs: Fix buffer overflow with the dlist handling + - bpf: Check for integer overflow when using roundup_pow_of_two() + - netfilter: xt_recent: Fix attempt to update deleted entry + - netfilter: nftables: fix possible UAF over chains from packet path in netns + - netfilter: flowtable: fix tcp and udp header checksum update + - xen/netback: avoid race in xenvif_rx_ring_slots_available() + - net: enetc: initialize the RFS and RSS memories + - selftests: txtimestamp: fix compilation issue + - net: stmmac: set TxQ mode back to DCB after disabling CBS + - ibmvnic: Clear failover_pending if unable to schedule + - netfilter: conntrack: skip identical origin tuple in same zone only + - x86/build: Disable CET instrumentation in the kernel for 32-bit too + - net: hns3: add a check for queue_id in hclge_reset_vf_queue() + - firmware_loader: align .builtin_fw to 8 + - drm/sun4i: tcon: set sync polarity for tcon1 channel + - drm/sun4i: Fix H6 HDMI PHY configuration + - drm/sun4i: dw-hdmi: Fix max. frequency for H6 + - clk: sunxi-ng: mp: fix parent rate change flag check + - i2c: stm32f7: fix configuration of the digital filter + - h8300: fix PREEMPTION build, TI_PRE_COUNT undefined + - usb: dwc3: ulpi: fix checkpatch warning + - usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one + - rxrpc: Fix clearance of Tx/Rx ring when releasing a call + - udp: fix skb_copy_and_csum_datagram with odd segment sizes + - net: dsa: call teardown method on probe failure + - net: gro: do not keep too many GRO packets in napi->rx_list + - net: fix iteration for sctp transport seq_files + - net/vmw_vsock: improve locking in vsock_connect_timeout() + - net: watchdog: hold device global xmit lock during tx disable + - vsock/virtio: update credit only if socket is not closed + - vsock: fix locking in vsock_shutdown() + - net/rds: restrict iovecs length for RDS_CMSG_RDMA_ARGS + - net/qrtr: restrict user-controlled length in qrtr_tun_write_iter() + - ovl: expand warning in ovl_d_real() + - Linux 5.4.99 + * Focal update: v5.4.98 upstream stable release (LP: #1918158) + - tracing/kprobe: Fix to support kretprobe events on unloaded modules + - af_key: relax availability checks for skb size calculation + - regulator: core: avoid regulator_resolve_supply() race condition + - mac80211: 160MHz with extended NSS BW in CSA + - ASoC: Intel: Skylake: Zero snd_ctl_elem_value + - chtls: Fix potential resource leak + - pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process() + - ASoC: ak4458: correct reset polarity + - iwlwifi: mvm: skip power command when unbinding vif during CSA + - iwlwifi: mvm: take mutex for calling iwl_mvm_get_sync_time() + - iwlwifi: pcie: add a NULL check in iwl_pcie_txq_unmap + - iwlwifi: pcie: fix context info memory leak + - iwlwifi: mvm: invalidate IDs of internal stations at mvm start + - iwlwifi: mvm: guard against device removal in reprobe + - SUNRPC: Move simple_get_bytes and simple_get_netobj into private header + - SUNRPC: Handle 0 length opaque XDR object data properly + - i2c: mediatek: Move suspend and resume handling to NOIRQ phase + - blk-cgroup: Use cond_resched() when destroy blkgs + - regulator: Fix lockdep warning resolving supplies + - Fix unsynchronized access to sev members through svm_register_enc_region + - squashfs: add more sanity checks in id lookup + - squashfs: add more sanity checks in inode lookup + - squashfs: add more sanity checks in xattr id lookup + - Linux 5.4.98 + * Enforce CONFIG_DRM_BOCHS=m (LP: #1916290) + - [Config] Enforce CONFIG_DRM_BOCHS=m + * powerpc/eeh-basic.sh in kselftest make P8 node stopped working + (LP: #1916468) + - selftests/eeh: Skip ahci adapters + * Focal update: v5.4.97 upstream stable release (LP: #1916066) + - USB: serial: cp210x: add pid/vid for WSDA-200-USB + - USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000 + - USB: serial: option: Adding support for Cinterion MV31 + - arm64: dts: qcom: c630: keep both touchpad devices enabled + - arm64: dts: amlogic: meson-g12: Set FL-adj property value + - arm64: dts: rockchip: fix vopl iommu irq on px30 + - bpf, cgroup: Fix optlen WARN_ON_ONCE toctou + - bpf, cgroup: Fix problematic bounds check + - um: virtio: free vu_dev only with the contained struct device + - rxrpc: Fix deadlock around release of dst cached on udp tunnel + - arm64: dts: ls1046a: fix dcfg address range + - igc: set the default return value to -IGC_ERR_NVM in igc_write_nvm_srwr + - igc: check return value of ret_val in igc_config_fc_after_link_up + - i40e: Revert "i40e: don't report link up for a VF who hasn't enabled queues" + - net/mlx5: Fix leak upon failure of rule creation + - net: lapb: Copy the skb before sending a packet + - net: mvpp2: TCAM entry enable should be written after SRAM data + - r8169: fix WoL on shutdown if CONFIG_DEBUG_SHIRQ is set + - ARM: dts: sun7i: a20: bananapro: Fix ethernet phy-mode + - nvmet-tcp: fix out-of-bounds access when receiving multiple h2cdata PDUs + - memblock: do not start bottom-up allocations with kernel_end + - USB: gadget: legacy: fix an error code in eth_bind() + - USB: usblp: don't call usb_set_interface if there's a single alt + - usb: renesas_usbhs: Clear pipe running flag in usbhs_pkt_pop() + - usb: dwc2: Fix endpoint direction check in ep_from_windex + - usb: dwc3: fix clock issue during resume in OTG mode + - usb: xhci-mtk: fix unreleased bandwidth data + - usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints + - usb: xhci-mtk: break loop when find the endpoint to drop + - usb: host: xhci-plat: add priv quirk for skip PHY initialization + - ovl: fix dentry leak in ovl_get_redirect + - mac80211: fix station rate table updates on assoc + - fgraph: Initialize tracing_graph_pause at task creation + - kretprobe: Avoid re-registration of the same kretprobe earlier + - libnvdimm/dimm: Avoid race between probe and available_slots_show() + - genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set + - xhci: fix bounce buffer usage for non-sg list case + - cifs: report error instead of invalid when revalidating a dentry fails + - smb3: Fix out-of-bounds bug in SMB2_negotiate() + - smb3: fix crediting for compounding when only one request in flight + - mmc: core: Limit retries when analyse of SDIO tuples fails + - drm/amd/display: Revert "Fix EDID parsing after resume from suspend" + - nvme-pci: avoid the deepest sleep state on Kingston A2000 SSDs + - KVM: SVM: Treat SVM as unsupported when running as an SEV guest + - KVM: x86: Update emulator context mode if SYSENTER xfers to 64-bit mode + - ARM: footbridge: fix dc21285 PCI configuration accessors + - mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page + - mm: hugetlb: fix a race between freeing and dissolving the page + - mm: hugetlb: fix a race between isolating and freeing page + - mm: hugetlb: remove VM_BUG_ON_PAGE from page_huge_active + - mm, compaction: move high_pfn to the for loop scope + - mm: thp: fix MADV_REMOVE deadlock on shmem THP + - x86/build: Disable CET instrumentation in the kernel + - x86/apic: Add extra serialization for non-serializing MSRs + - iwlwifi: mvm: don't send RFH_QUEUE_CONFIG_CMD with no queues + - Input: xpad - sync supported devices with fork on GitHub + - iommu/vt-d: Do not use flush-queue when caching-mode is on + - md: Set prev_flush_start and flush_bio in an atomic way + - neighbour: Prevent a dead entry from updating gc_list + - net: ip_tunnel: fix mtu calculation + - net: dsa: mv88e6xxx: override existent unicast portvec in port_fdb_add + - net: sched: replaced invalid qdisc tree flush helper in qdisc_replace + - usb: host: xhci: mvebu: make USB 3.0 PHY optional for Armada 3720 + - Linux 5.4.97 + * Focal update: v5.4.96 upstream stable release (LP: #1916061) + - net: dsa: bcm_sf2: put device node before return + - net: switchdev: don't set port_obj_info->handled true when -EOPNOTSUPP + - ibmvnic: Ensure that CRQ entry read are correctly ordered + - Revert "Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and + REQ_NOWAIT"" + - ACPI: thermal: Do not call acpi_thermal_check() directly + - arm64: Fix kernel address detection of __is_lm_address() + - arm64: Do not pass tagged addresses to __is_lm_address() + - tcp: make TCP_USER_TIMEOUT accurate for zero window probes + - btrfs: backref, only collect file extent items matching backref offset + - btrfs: backref, don't add refs from shared block when resolving normal + backref + - btrfs: backref, only search backref entries from leaves of the same root + - btrfs: backref, use correct count to resolve normal data refs + - net_sched: gen_estimator: support large ewma log + - phy: cpcap-usb: Fix warning for missing regulator_disable + - platform/x86: touchscreen_dmi: Add swap-x-y quirk for Goodix touchscreen on + Estar Beauty HD tablet + - platform/x86: intel-vbtn: Support for tablet mode on Dell Inspiron 7352 + - x86: __always_inline __{rd,wr}msr() + - scsi: scsi_transport_srp: Don't block target in failfast state + - scsi: libfc: Avoid invoking response handler twice if ep is already + completed + - scsi: fnic: Fix memleak in vnic_dev_init_devcmd2 + - ASoC: SOF: Intel: hda: Resume codec to do jack detection + - mac80211: fix fast-rx encryption check + - scsi: ibmvfc: Set default timeout to avoid crash during migration + - udf: fix the problem that the disc content is not displayed + - nvme: check the PRINFO bit before deciding the host buffer length + - selftests/powerpc: Only test lwm/stmw on big endian + - drm/amd/display: Update dram_clock_change_latency for DCN2.1 + - drm/amd/display: Change function decide_dp_link_settings to avoid infinite + looping + - objtool: Don't fail on missing symbol table + - kthread: Extract KTHREAD_IS_PER_CPU + - workqueue: Restrict affinity change to rescuer + - Linux 5.4.96 + * Focal update: v5.4.95 upstream stable release (LP: #1916056) + - ICMPv6: Add ICMPv6 Parameter Problem, code 3 definition + - IPv6: reply ICMP error if the first fragment don't include all headers + - nbd: freeze the queue while we're adding connections + - ACPI: sysfs: Prefer "compatible" modalias + - kernel: kexec: remove the lock operation of system_transition_mutex + - ALSA: hda/realtek: Enable headset of ASUS B1400CEPE with ALC256 + - ALSA: hda/via: Apply the workaround generically for Clevo machines + - media: rc: ensure that uevent can be read directly after rc device register + - ARM: dts: imx6qdl-gw52xx: fix duplicate regulator naming + - wext: fix NULL-ptr-dereference with cfg80211's lack of commit() + - net: usb: qmi_wwan: added support for Thales Cinterion PLSx3 modem family + - s390/vfio-ap: No need to disable IRQ after queue reset + - PM: hibernate: flush swap writer after marking + - drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs + - drivers: soc: atmel: add null entry at the end of at91_soc_allowed_list[] + - btrfs: fix possible free space tree corruption with online conversion + - KVM: x86/pmu: Fix HW_REF_CPU_CYCLES event pseudo-encoding in + intel_arch_events[] + - KVM: x86/pmu: Fix UBSAN shift-out-of-bounds warning in intel_pmu_refresh() + - KVM: nVMX: Sync unsync'd vmcs02 state to vmcs12 on migration + - KVM: x86: get smi pending status correctly + - KVM: Forbid the use of tagged userspace addresses for memslots + - xen: Fix XenStore initialisation for XS_LOCAL + - leds: trigger: fix potential deadlock with libata + - arm64: dts: broadcom: Fix USB DMA address translation for Stingray + - mt7601u: fix kernel crash unplugging the device + - mt7601u: fix rx buffer refcounting + - drm/nouveau/svm: fail NOUVEAU_SVM_INIT ioctl on unsupported devices + - drm/i915: Check for all subplatform bits + - tee: optee: replace might_sleep with cond_resched + - xen-blkfront: allow discard-* nodes to be optional + - ARM: imx: build suspend-imx6.S with arm instruction set + - netfilter: nft_dynset: add timeout extension to template + - xfrm: Fix oops in xfrm_replay_advance_bmp + - xfrm: fix disable_xfrm sysctl when used on xfrm interfaces + - selftests: xfrm: fix test return value override issue in xfrm_policy.sh + - xfrm: Fix wraparound in xfrm_policy_addr_delta() + - arm64: dts: ls1028a: fix the offset of the reset register + - ARM: dts: imx6qdl-kontron-samx6i: fix i2c_lcd/cam default status + - firmware: imx: select SOC_BUS to fix firmware build + - RDMA/cxgb4: Fix the reported max_recv_sge value + - ASoC: Intel: Skylake: skl-topology: Fix OOPs ib skl_tplg_complete + - pNFS/NFSv4: Fix a layout segment leak in pnfs_layout_process() + - iwlwifi: pcie: use jiffies for memory read spin time limit + - iwlwifi: pcie: reschedule in long-running memory reads + - mac80211: pause TX while changing interface type + - i40e: acquire VSI pointer only after VF is initialized + - igc: fix link speed advertising + - net/mlx5: Fix memory leak on flow table creation error flow + - net/mlx5e: E-switch, Fix rate calculation for overflow + - net/mlx5e: Reduce tc unsupported key print level + - can: dev: prevent potential information leak in can_fill_info() + - nvme-multipath: Early exit if no path is available + - selftests: forwarding: Specify interface when invoking mausezahn + - iommu/vt-d: Gracefully handle DMAR units with no supported address widths + - iommu/vt-d: Don't dereference iommu_device if IOMMU_API is not built + - rxrpc: Fix memory leak in rxrpc_lookup_local + - NFC: fix resource leak when target index is invalid + - NFC: fix possible resource leak + - ASoC: topology: Fix memory corruption in soc_tplg_denum_create_values() + - team: protect features update by RCU to avoid deadlock + - tcp: fix TLP timer not set when CA_STATE changes from DISORDER to OPEN + - Linux 5.4.95 + + -- Ian May Thu, 25 Mar 2021 14:59:44 -0500 + +linux-oracle (5.4.0-1041.44) focal; urgency=medium + + [ Ubuntu: 5.4.0-70.78 ] + + * CVE-2020-27170 + - bpf: Fix off-by-one for area size in creating mask to left + * CVE-2020-27171 + - bpf: Prohibit alu ops for pointer types not defining ptr_limit + * binary assembly failures with CONFIG_MODVERSIONS present (LP: #1919315) + - [Packaging] quiet (nomially) benign errors in BUILD script + + -- Kleber Sacilotto de Souza Fri, 19 Mar 2021 18:40:26 +0100 + +linux-oracle (5.4.0-1040.43) focal; urgency=medium + + * binary assembly failures with CONFIG_MODVERSIONS present (LP: #1919315) + - [Packaging] quiet (nomially) benign errors in BUILD script + + [ Ubuntu: 5.4.0-69.77 ] + + * CVE-2021-3444 + - bpf: Fix 32 bit src register truncation on div/mod + - bpf: Fix truncation handling for mod32 dst reg wrt zero + * CVE-2021-27365 + - scsi: iscsi: Verify lengths on passthrough PDUs + - sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output + - scsi: iscsi: Ensure sysfs attributes are limited to PAGE_SIZE + * CVE-2021-27363 // CVE-2021-27364 + - scsi: iscsi: Restrict sessions and handles to admin capabilities + + -- Kleber Sacilotto de Souza Wed, 17 Mar 2021 17:55:33 +0100 + +linux-oracle (5.4.0-1039.42) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1039.42 -proposed tracker (LP: #1916161) + + * Focal update: v5.4.93 upstream stable release (LP: #1915195) + - oracle: [Config] updateconfigs for USB_BDC_PCI + + * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716) + - oracle: [Config] Enable MODVERSIONS, ASM_MODVERSIONS and set + SYSTEM_TRUSTED_KEYS + + [ Ubuntu: 5.4.0-67.75 ] + + * focal/linux: 5.4.0-67.75 -proposed tracker (LP: #1916169) + * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716) + - [Config] enable CONFIG_MODVERSIONS=y + - [Packaging] build canonical-certs.pem from branch/arch certs + - [Config] add Canonical Livepatch Service key to SYSTEM_TRUSTED_KEYS + - [Config] add ubuntu-drivers key to SYSTEM_TRUSTED_KEYS + - [Config] Allow ASM_MODVERSIONS and MODULE_REL_CRCS + * geneve overlay network on vlan interface broken with offload enabled + (LP: #1914447) + - net/mlx5e: Fix SWP offsets when vlan inserted by driver + * Add support for selective build of special drivers (LP: #1912789) + - [Packaging] Fix ODM support in actual build + * devlink: don't do reporter recovery if the state is healthy (LP: #1915403) + - devlink: don't do reporter recovery if the state is healthy + * Missing device id for Intel TGL-H ISH [8086:43fc] in intel-ish-hid driver + (LP: #1914543) + - HID: intel-ish-hid: ipc: Add Tiger Lake H PCI device ID + * Focal update: v5.4.94 upstream stable release (LP: #1915200) + - gpio: mvebu: fix pwm .get_state period calculation + - futex: Ensure the correct return value from futex_lock_pi() + - futex: Replace pointless printk in fixup_owner() + - futex: Provide and use pi_state_update_owner() + - rtmutex: Remove unused argument from rt_mutex_proxy_unlock() + - futex: Use pi_state_update_owner() in put_pi_state() + - futex: Simplify fixup_pi_state_owner() + - futex: Handle faults correctly for PI futexes + - HID: wacom: Correct NULL dereference on AES pen proximity + - io_uring: Fix current->fs handling in io_sq_wq_submit_work() + - tracing: Fix race in trace_open and buffer resize call + - arm64: mm: use single quantity to represent the PA to VA translation + - SMB3.1.1: do not log warning message if server doesn't populate salt + - tools: Factor HOSTCC, HOSTLD, HOSTAR definitions + - dm integrity: conditionally disable "recalculate" feature + - writeback: Drop I_DIRTY_TIME_EXPIRE + - fs: fix lazytime expiration handling in __writeback_single_inode() + - Linux 5.4.94 + * Focal update: v5.4.93 upstream stable release (LP: #1915195) + - i2c: bpmp-tegra: Ignore unknown I2C_M flags + - platform/x86: ideapad-laptop: Disable touchpad_switch for ELAN0634 + - ALSA: seq: oss: Fix missing error check in snd_seq_oss_synth_make_info() + - ALSA: hda/via: Add minimum mute flag + - ACPI: scan: Make acpi_bus_get_device() clear return pointer on error + - btrfs: don't get an EINTR during drop_snapshot for reloc + - btrfs: fix lockdep splat in btrfs_recover_relocation + - btrfs: don't clear ret in btrfs_start_dirty_block_groups + - btrfs: send: fix invalid clone operations when cloning from the same file + and root + - mmc: core: don't initialize block size from ext_csd if not present + - mmc: sdhci-xenon: fix 1.8v regulator stabilization + - dm: avoid filesystem lookup in dm_get_dev_t() + - dm integrity: fix a crash if "recalculate" used without "internal_hash" + - drm/atomic: put state on error path + - drm/syncobj: Fix use-after-free + - drm/i915/gt: Prevent use of engine->wa_ctx after error + - ASoC: Intel: haswell: Add missing pm_ops + - dm integrity: select CRYPTO_SKCIPHER + - scsi: ufs: Correct the LUN used in eh_device_reset_handler() callback + - scsi: qedi: Correct max length of CHAP secret + - scsi: sd: Suppress spurious errors when WRITE SAME is being disabled + - riscv: Fix kernel time_init() + - riscv: Fix sifive serial driver + - HID: logitech-dj: add the G602 receiver + - HID: Ignore battery for Elan touchscreen on ASUS UX550 + - clk: tegra30: Add hda clock default rates to clock driver + - arm64: make atomic helpers __always_inline + - xen: Fix event channel callback via INTX/GSI + - x86/xen: Add xen_no_vector_callback option to test PCI INTX delivery + - dts: phy: fix missing mdio device and probe failure of vsc8541-01 device + - riscv: defconfig: enable gpio support for HiFive Unleashed + - drm/amdgpu/psp: fix psp gfx ctrl cmds + - drm/amd/display: Fix to be able to stop crc calculation + - drm/nouveau/bios: fix issue shadowing expansion ROMs + - drm/nouveau/privring: ack interrupts the same way as RM + - drm/nouveau/i2c/gm200: increase width of aux semaphore owner fields + - drm/nouveau/mmu: fix vram heap sizing + - drm/nouveau/kms/nv50-: fix case where notifier buffer is at offset 0 + - powerpc: Use the common INIT_DATA_SECTION macro in vmlinux.lds.S + - pinctrl: aspeed: g6: Fix PWMG0 pinctrl setting + - scsi: megaraid_sas: Fix MEGASAS_IOC_FIRMWARE regression + - powerpc: Fix alignment bug within the init sections + - i2c: octeon: check correct size of maximum RECV_LEN packet + - platform/x86: intel-vbtn: Drop HP Stream x360 Convertible PC 11 from allow- + list + - selftests: net: fib_tests: remove duplicate log test + - can: dev: can_restart: fix use after free bug + - can: vxcan: vxcan_xmit: fix use after free bug + - can: peak_usb: fix use after free bugs + - iio: ad5504: Fix setting power-down state + - cifs: do not fail __smb_send_rqst if non-fatal signals are pending + - irqchip/mips-cpu: Set IPI domain parent chip + - x86/fpu: Add kernel_fpu_begin_mask() to selectively initialize state + - x86/topology: Make __max_die_per_package available unconditionally + - x86/mmx: Use KFPU_387 for MMX string operations + - intel_th: pci: Add Alder Lake-P support + - stm class: Fix module init return on allocation failure + - serial: mvebu-uart: fix tx lost characters at power off + - ehci: fix EHCI host controller initialization sequence + - USB: ehci: fix an interrupt calltrace error + - usb: gadget: aspeed: fix stop dma register setting. + - usb: udc: core: Use lock when write to soft_connect + - [Config] updateconfigs for USB_BDC_PCI + - usb: bdc: Make bdc pci driver depend on BROKEN + - xhci: make sure TRB is fully written before giving it to the controller + - xhci: tegra: Delay for disabling LFPS detector + - driver core: Extend device_is_dependent() + - pinctrl: ingenic: Fix JZ4760 support + - x86/cpu/amd: Set __max_die_per_package on AMD + - netfilter: rpfilter: mask ecn bits before fib lookup + - sh: dma: fix kconfig dependency for G2_DMA + - net: dsa: mv88e6xxx: also read STU state in mv88e6250_g1_vtu_getnext + - sh_eth: Fix power down vs. is_opened flag ordering + - lightnvm: fix memory leak when submit fails + - skbuff: back tiny skbs with kmalloc() in __netdev_alloc_skb() too + - kasan: fix unaligned address is unhandled in kasan_remove_zero_shadow + - kasan: fix incorrect arguments passing in kasan_add_zero_shadow + - udp: mask TOS bits in udp_v4_early_demux() + - ipv6: create multicast route with RTPROT_KERNEL + - net_sched: avoid shift-out-of-bounds in tcindex_set_parms() + - net_sched: reject silly cell_log in qdisc_get_rtab() + - ipv6: set multicast flag on the multicast route + - net: mscc: ocelot: allow offloading of bridge on top of LAG + - net: Disable NETIF_F_HW_TLS_RX when RXCSUM is disabled + - net: dsa: b53: fix an off by one in checking "vlan->vid" + - tcp: do not mess with cloned skbs in tcp_add_backlog() + - tcp: fix TCP_USER_TIMEOUT with zero window + - Linux 5.4.93 + * High load from process irq/65-i2c-INT3 - kernel module tps6598x + (LP: #1883511) // Focal update: v5.4.93 upstream stable release + (LP: #1915195) + - platform/x86: i2c-multi-instantiate: Don't create platform device for + INT3515 ACPI nodes + * Focal update: v5.4.92 upstream stable release (LP: #1915186) + - usb: ohci: Make distrust_firmware param default to false + - compiler.h: Raise minimum version of GCC to 5.1 for arm64 + - xen/privcmd: allow fetching resource sizes + - elfcore: fix building with clang + - scsi: lpfc: Make lpfc_defer_acc_rsp static + - spi: npcm-fiu: simplify the return expression of npcm_fiu_probe() + - spi: npcm-fiu: Disable clock in probe error path + - nfsd4: readdirplus shouldn't return parent of export + - bpf: Don't leak memory in bpf getsockopt when optlen == 0 + - bpf: Fix helper bpf_map_peek_elem_proto pointing to wrong callback + - udp: Prevent reuseport_select_sock from reading uninitialized socks + - netxen_nic: fix MSI/MSI-x interrupts + - net: introduce skb_list_walk_safe for skb segment walking + - net: skbuff: disambiguate argument and member for skb_list_walk_safe helper + - net: ipv6: Validate GSO SKB before finish IPv6 processing + - mlxsw: core: Add validation of transceiver temperature thresholds + - mlxsw: core: Increase critical threshold for ASIC thermal zone + - net: mvpp2: Remove Pause and Asym_Pause support + - rndis_host: set proper input size for OID_GEN_PHYSICAL_MEDIUM request + - esp: avoid unneeded kmap_atomic call + - net: dcb: Validate netlink message in DCB handler + - net: dcb: Accept RTM_GETDCB messages carrying set-like DCB commands + - rxrpc: Call state should be read with READ_ONCE() under some circumstances + - net: stmmac: Fixed mtu channged by cache aligned + - net: sit: unregister_netdevice on newlink's error path + - net: avoid 32 x truesize under-estimation for tiny skbs + - rxrpc: Fix handling of an unsupported token type in rxrpc_read() + - net, sctp, filter: remap copy_from_user failure error + - tipc: fix NULL deref in tipc_link_xmit() + - mac80211: do not drop tx nulldata packets on encrypted links + - mac80211: check if atf has been disabled in __ieee80211_schedule_txq + - spi: cadence: cache reference clock rate during probe + - Linux 5.4.92 + * intel-hid is not loaded on new Intel platform (LP: #1907160) + - platform/x86: intel-hid: Add Tiger Lake ACPI device ID + - platform/x86: intel-hid: fix: Update Tiger Lake ACPI device ID + - platform/x86: intel-hid: Move MODULE_DEVICE_TABLE() closer to the table + - platform/x86: intel-hid: add Rocket Lake ACPI device ID + * Support Advantech UNO-420 platform (LP: #1902672) + - ODM: MAINTAINERS: Add Advantech AHC1EC0 embedded controller entry + - ODM: mfd: ahc1ec0: Add Advantech EC include file used by dt-bindings + - ODM: dt-bindings: mfd: ahc1ec0.yaml: Add Advantech embedded controller - + AHC1EC0 + - ODM: mfd: ahc1ec0: Add support for Advantech embedded controller + - ODM: hwmon: ahc1ec0-hwmon: Add sub-device hwmon for Advantech embedded + controller + - ODM: watchdog: ahc1ec0-wdt: Add sub-device watchdog for Advantech embedded + controller + - ODM: [Config] update config for Advantech devices + * Remove scary stack trace from Realtek WiFi driver (LP: #1913263) + - rtw88: reduce the log level for failure of tx report + * Focal update: v5.4.91 upstream stable release (LP: #1914654) + - kbuild: enforce -Werror=return-type + - btrfs: prevent NULL pointer dereference in extent_io_tree_panic + - ASoC: dapm: remove widget from dirty list on free + - x86/hyperv: check cpu mask after interrupt has been disabled + - tracing/kprobes: Do the notrace functions check without kprobes on ftrace + - [Config] update annotations for KPROBE_EVENTS_ON_NOTRACE + - mips: fix Section mismatch in reference + - mips: lib: uncached: fix non-standard usage of variable 'sp' + - MIPS: boot: Fix unaligned access with CONFIG_MIPS_RAW_APPENDED_DTB + - MIPS: relocatable: fix possible boot hangup with KASLR enabled + - RDMA/ocrdma: Fix use after free in ocrdma_dealloc_ucontext_pd() + - ACPI: scan: Harden acpi_device_add() against device ID overflows + - mm/hugetlb: fix potential missing huge page size info + - dm raid: fix discard limits for raid1 + - dm snapshot: flush merged data before committing metadata + - dm integrity: fix the maximum number of arguments + - r8152: Add Lenovo Powered USB-C Travel Hub + - btrfs: tree-checker: check if chunk item end overflows + - drm/i915/backlight: fix CPU mode backlight takeover on LPT + - ext4: fix bug for rename with RENAME_WHITEOUT + - ext4: don't leak old mountpoint samples + - cifs: fix interrupted close commands + - dm integrity: fix flush with external metadata device + - ARC: build: remove non-existing bootpImage from KBUILD_IMAGE + - ARC: build: add uImage.lzma to the top-level target + - ARC: build: add boot_targets to PHONY + - ARC: build: move symlink creation to arch/arc/Makefile to avoid race + - netfilter: ipset: fixes possible oops in mtype_resize + - btrfs: fix transaction leak and crash after RO remount caused by qgroup + rescan + - regulator: bd718x7: Add enable times + - ethernet: ucc_geth: fix definition and size of ucc_geth_tx_global_pram + - habanalabs: register to pci shutdown callback + - habanalabs: Fix memleak in hl_device_reset + - hwmon: (pwm-fan) Ensure that calculation doesn't discard big period values + - lib/raid6: Let $(UNROLL) rules work with macOS userland + - bfq: Fix computation of shallow depth + - arch/arc: add copy_user_page() to to fix build error on ARC + - misdn: dsp: select CONFIG_BITREVERSE + - net: ethernet: fs_enet: Add missing MODULE_LICENSE + - nvme-pci: mark Samsung PM1725a as IGNORE_DEV_SUBNQN + - nvmet-rdma: Fix list_del corruption on queue establishment failure + - drm/amdgpu: fix a GPU hang issue when remove device + - usb: typec: Fix copy paste error for NVIDIA alt-mode description + - ACPI: scan: add stub acpi_create_platform_device() for !CONFIG_ACPI + - drm/msm: Call msm_init_vram before binding the gpu + - ARM: picoxcell: fix missing interrupt-parent properties + - perf intel-pt: Fix 'CPU too large' error + - dump_common_audit_data(): fix racy accesses to ->d_name + - ASoC: meson: axg-tdm-interface: fix loopback + - ASoC: meson: axg-tdmin: fix axg skew offset + - ASoC: Intel: fix error code cnl_set_dsp_D0() + - nvme-tcp: fix possible data corruption with bio merges + - NFS4: Fix use-after-free in trace_event_raw_event_nfs4_set_lock + - pNFS: We want return-on-close to complete when evicting the inode + - pNFS: Mark layout for return if return-on-close was not sent + - pNFS: Stricter ordering of layoutget and layoutreturn + - NFS/pNFS: Fix a leak of the layout 'plh_outstanding' counter + - NFS: nfs_igrab_and_active must first reference the superblock + - ext4: fix superblock checksum failure when setting password salt + - RDMA/restrack: Don't treat as an error allocation ID wrapping + - RDMA/usnic: Fix memleak in find_free_vf_and_create_qp_grp + - bnxt_en: Improve stats context resource accounting with RDMA driver loaded. + - RDMA/mlx5: Fix wrong free of blue flame register on error + - IB/mlx5: Fix error unwinding when set_has_smi_cap fails + - drm/i915/dsi: Use unconditional msleep for the panel_on_delay when there is + no reset-deassert MIPI-sequence + - mm, slub: consider rest of partial list if acquire_slab() fails + - iommu/vt-d: Fix unaligned addresses for intel_flush_svm_range_dev() + - net: sunrpc: interpret the return value of kstrtou32 correctly + - dm: eliminate potential source of excessive kernel log noise + - ALSA: fireface: Fix integer overflow in transmit_midi_msg() + - ALSA: firewire-tascam: Fix integer overflow in midi_port_work() + - netfilter: conntrack: fix reading nf_conntrack_buckets + - netfilter: nf_nat: Fix memleak in nf_nat_init + - netfilter: nft_compat: remove flush counter optimization + - Linux 5.4.91 + * Focal update: v5.4.90 upstream stable release (LP: #1913487) + - x86/asm/32: Add ENDs to some functions and relabel with SYM_CODE_* + - vfio iommu: Add dma available capability + - net: cdc_ncm: correct overhead in delayed_ndp_size + - net: hns3: fix the number of queues actually used by ARQ + - net: hns3: fix a phy loopback fail issue + - net: stmmac: dwmac-sun8i: Balance internal PHY resource references + - net: stmmac: dwmac-sun8i: Balance internal PHY power + - net: vlan: avoid leaks on register_vlan_dev() failures + - net/sonic: Fix some resource leaks in error handling paths + - net: ipv6: fib: flush exceptions when purging route + - tools: selftests: add test for changing routes with PTMU exceptions + - net: fix pmtu check in nopmtudisc mode + - net: ip: always refragment ip defragmented packets + - octeontx2-af: fix memory leak of lmac and lmac->name + - nexthop: Fix off-by-one error in error path + - nexthop: Unlink nexthop group entry in error path + - s390/qeth: fix L2 header access in qeth_l3_osa_features_check() + - net: dsa: lantiq_gswip: Exclude RMII from modes that report 1 GbE + - net/mlx5: Use port_num 1 instead of 0 when delete a RoCE address + - net/mlx5e: ethtool, Fix restriction of autoneg with 56G + - chtls: Fix hardware tid leak + - chtls: Remove invalid set_tcb call + - chtls: Fix panic when route to peer not configured + - chtls: Replace skb_dequeue with skb_peek + - chtls: Added a check to avoid NULL pointer dereference + - chtls: Fix chtls resources release sequence + - x86/resctrl: Use an IPI instead of task_work_add() to update PQR_ASSOC MSR + - x86/resctrl: Don't move a task to the same resource group + - exfat: Month timestamp metadata accidentally incremented + - vmlinux.lds.h: Add PGO and AutoFDO input sections + - iio: imu: st_lsm6dsx: fix edge-trigger interrupts + - HID: wacom: Fix memory leakage caused by kfifo_alloc + - ARM: OMAP2+: omap_device: fix idling of devices during probe + - i2c: sprd: use a specific timeout to avoid system hang up issue + - dmaengine: dw-edma: Fix use after free in dw_edma_alloc_chunk() + - can: tcan4x5x: fix bittiming const, use common bittiming from m_can driver + - can: m_can: m_can_class_unregister(): remove erroneous m_can_clk_stop() + - can: kvaser_pciefd: select CONFIG_CRC32 + - cpufreq: powernow-k8: pass policy rather than use cpufreq_cpu_get() + - spi: stm32: FIFO threshold level - fix align packet size + - i2c: i801: Fix the i2c-mux gpiod_lookup_table not being properly terminated + - dmaengine: mediatek: mtk-hsdma: Fix a resource leak in the error handling + path of the probe function + - dmaengine: xilinx_dma: check dma_async_device_register return value + - dmaengine: xilinx_dma: fix incompatible param warning in _child_probe() + - dmaengine: xilinx_dma: fix mixed_enum_type coverity warning + - qed: select CONFIG_CRC32 + - wil6210: select CONFIG_CRC32 + - block: rsxx: select CONFIG_CRC32 + - lightnvm: select CONFIG_CRC32 + - iommu/intel: Fix memleak in intel_irq_remapping_alloc + - bpftool: Fix compilation failure for net.o with older glibc + - net/mlx5e: Fix memleak in mlx5e_create_l2_table_groups + - net/mlx5e: Fix two double free cases + - regmap: debugfs: Fix a memory leak when calling regmap_attach_dev + - wan: ds26522: select CONFIG_BITREVERSE + - regulator: qcom-rpmh-regulator: correct hfsmps515 definition + - net: mvpp2: disable force link UP during port init procedure + - KVM: arm64: Don't access PMCR_EL0 when no PMU is available + - block: fix use-after-free in disk_part_iter_next + - net: drop bogus skb with CHECKSUM_PARTIAL and offset beyond end of trimmed + packet + - regmap: debugfs: Fix a reversed if statement in regmap_debugfs_init() + - Linux 5.4.90 + * Focal update: v5.4.89 upstream stable release (LP: #1913486) + - workqueue: Kick a worker based on the actual activation of delayed works + - scsi: ufs: Fix wrong print message in dev_err() + - scsi: ufs-pci: Ensure UFS device is in PowerDown mode for suspend-to-disk + ->poweroff() + - scsi: ide: Do not set the RQF_PREEMPT flag for sense requests + - scsi: scsi_transport_spi: Set RQF_PM for domain validation commands + - lib/genalloc: fix the overflow when size is too big + - depmod: handle the case of /sbin/depmod without /sbin in PATH + - proc: change ->nlink under proc_subdir_lock + - proc: fix lookup in /proc/net subdirectories after setns(2) + - i40e: Fix Error I40E_AQ_RC_EINVAL when removing VFs + - iavf: fix double-release of rtnl_lock + - net: mvpp2: Add TCAM entry to drop flow control pause frames + - net: mvpp2: prs: fix PPPoE with ipv6 packet parse + - net: systemport: set dev->max_mtu to UMAC_MAX_MTU_SIZE + - ethernet: ucc_geth: fix use-after-free in ucc_geth_remove() + - ethernet: ucc_geth: set dev->max_mtu to 1518 + - atm: idt77252: call pci_disable_device() on error path + - net: mvpp2: Fix GoP port 3 Networking Complex Control configurations + - ibmvnic: continue fatal error reset after passive init + - net: ethernet: mvneta: Fix error handling in mvneta_probe + - virtio_net: Fix recursive call to cpus_read_lock() + - net/ncsi: Use real net-device for response handler + - net: ethernet: Fix memleak in ethoc_probe + - net-sysfs: take the rtnl lock when storing xps_cpus + - net-sysfs: take the rtnl lock when accessing xps_cpus_map and num_tc + - net-sysfs: take the rtnl lock when storing xps_rxqs + - net-sysfs: take the rtnl lock when accessing xps_rxqs_map and num_tc + - net: ethernet: ti: cpts: fix ethtool output when no ptp_clock registered + - tun: fix return value when the number of iovs exceeds MAX_SKB_FRAGS + - net: mvpp2: fix pkt coalescing int-threshold configuration + - ipv4: Ignore ECN bits for fib lookups in fib_compute_spec_dst() + - net: sched: prevent invalid Scell_log shift count + - net: hns: fix return value check in __lb_other_process() + - erspan: fix version 1 check in gre_parse_header() + - net: hdlc_ppp: Fix issues when mod_timer is called while timer is running + - r8169: work around power-saving bug on some chip versions + - net: dsa: lantiq_gswip: Enable GSWIP_MII_CFG_EN also for internal PHYs + - net: dsa: lantiq_gswip: Fix GSWIP_MII_CFG(p) register access + - CDC-NCM: remove "connected" log message + - net: usb: qmi_wwan: add Quectel EM160R-GL + - vhost_net: fix ubuf refcount incorrectly when sendmsg fails + - ionic: account for vlan tag len in rx buffer len + - net/sched: sch_taprio: ensure to reset/destroy all child qdiscs + - kbuild: don't hardcode depmod path + - Bluetooth: revert: hci_h5: close serdev device and free hu in h5_close + - video: hyperv_fb: Fix the mmap() regression for v5.4.y and older + - crypto: ecdh - avoid buffer overflow in ecdh_set_secret() + - crypto: asym_tpm: correct zero out potential secrets + - powerpc: Handle .text.{hot,unlikely}.* in linker script + - staging: mt7621-dma: Fix a resource leak in an error handling path + - usb: gadget: enable super speed plus + - USB: cdc-acm: blacklist another IR Droid device + - USB: cdc-wdm: Fix use after free in service_outstanding_interrupt(). + - usb: dwc3: ulpi: Use VStsDone to detect PHY regs access completion + - usb: chipidea: ci_hdrc_imx: add missing put_device() call in + usbmisc_get_init_data() + - USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set + - usb: usbip: vhci_hcd: protect shift size + - usb: uas: Add PNY USB Portable SSD to unusual_uas + - USB: serial: iuu_phoenix: fix DMA from stack + - USB: serial: option: add LongSung M5710 module support + - USB: serial: option: add Quectel EM160R-GL + - USB: yurex: fix control-URB timeout handling + - USB: usblp: fix DMA to stack + - ALSA: usb-audio: Fix UBSAN warnings for MIDI jacks + - usb: gadget: select CONFIG_CRC32 + - usb: gadget: f_uac2: reset wMaxPacketSize + - usb: gadget: function: printer: Fix a memory leak for interface descriptor + - usb: gadget: u_ether: Fix MTU size mismatch with RX packet size + - USB: gadget: legacy: fix return error code in acm_ms_bind() + - usb: gadget: Fix spinlock lockup on usb_function_deactivate + - usb: gadget: configfs: Preserve function ordering after bind failure + - usb: gadget: configfs: Fix use-after-free issue with udc_name + - USB: serial: keyspan_pda: remove unused variable + - x86/mm: Fix leak of pmd ptlock + - kvm: check tlbs_dirty directly + - ALSA: hda/via: Fix runtime PM for Clevo W35xSS + - ALSA: hda/conexant: add a new hda codec CX11970 + - ALSA: hda/realtek - Fix speaker volume control on Lenovo C940 + - ALSA: hda/realtek: Add two "Intel Reference board" SSID in the ALC256. + - btrfs: send: fix wrong file path when there is an inode with a pending rmdir + - Revert "device property: Keep secondary firmware node secondary by type" + - dmabuf: fix use-after-free of dmabuf's file->f_inode + - drm/i915: clear the gpu reloc batch + - netfilter: x_tables: Update remaining dereference to RCU + - netfilter: ipset: fix shift-out-of-bounds in htable_bits() + - netfilter: xt_RATEEST: reject non-null terminated string from userspace + - netfilter: nft_dynset: report EOPNOTSUPP on missing set feature + - x86/mtrr: Correct the range check before performing MTRR type lookups + - KVM: x86: fix shift out of bounds reported by UBSAN + - Linux 5.4.89 + * Focal update: v5.4.88 upstream stable release (LP: #1913223) + - Revert "drm/amd/display: Fix memory leaks in S3 resume" + - Revert "mtd: spinand: Fix OOB read" + - dmaengine: at_hdmac: Substitute kzalloc with kmalloc + - dmaengine: at_hdmac: add missing put_device() call in at_dma_xlate() + - dmaengine: at_hdmac: add missing kfree() call in at_dma_xlate() + - kdev_t: always inline major/minor helper functions + - iio:imu:bmi160: Fix alignment and data leak issues + - fuse: fix bad inode + - perf: Break deadlock involving exec_update_mutex + - rwsem: Implement down_read_killable_nested + - rwsem: Implement down_read_interruptible + - exec: Transform exec_update_mutex into a rw_semaphore + - mwifiex: Fix possible buffer overflows in mwifiex_cmd_802_11_ad_hoc_start + - Linux 5.4.88 + * Focal update: v5.4.87 upstream stable release (LP: #1912681) + - net/sched: sch_taprio: reset child qdiscs before freeing them + - md/raid10: initialize r10_bio->read_slot before use. + - thermal/drivers/cpufreq_cooling: Update cpufreq_state only if state has + changed + - ext4: prevent creating duplicate encrypted filenames + - ubifs: prevent creating duplicate encrypted filenames + - f2fs: prevent creating duplicate encrypted filenames + - fscrypt: add fscrypt_is_nokey_name() + - fscrypt: remove kernel-internal constants from UAPI header + - vfio/pci: Move dummy_resources_list init in vfio_pci_probe() + - btrfs: fix race when defragmenting leads to unnecessary IO + - ext4: don't remount read-only with errors=continue on reboot + - KVM: x86: avoid incorrect writes to host MSR_IA32_SPEC_CTRL + - KVM: SVM: relax conditions for allowing MSR_IA32_SPEC_CTRL accesses + - KVM: x86: reinstate vendor-agnostic check on SPEC_CTRL cpuid bits + - powerpc/bitops: Fix possible undefined behaviour with fls() and fls64() + - jffs2: Allow setting rp_size to zero during remounting + - jffs2: Fix NULL pointer dereference in rp_size fs option parsing + - scsi: block: Fix a race in the runtime power management code + - uapi: move constants from to + - tools headers UAPI: Sync linux/const.h with the kernel headers + - null_blk: Fix zone size initialization + - of: fix linker-section match-table corruption + - cgroup: Fix memory leak when parsing multiple source parameters + - scsi: cxgb4i: Fix TLS dependency + - Bluetooth: hci_h5: close serdev device and free hu in h5_close + - reiserfs: add check for an invalid ih_entry_count + - misc: vmw_vmci: fix kernel info-leak by initializing dbells in + vmci_ctx_get_chkpt_doorbells() + - media: gp8psk: initialize stats at power control logic + - f2fs: fix shift-out-of-bounds in sanity_check_raw_super() + - ALSA: seq: Use bool for snd_seq_queue internal flags + - ALSA: rawmidi: Access runtime->avail always in spinlock + - bfs: don't use WARNING: string when it's just info. + - fcntl: Fix potential deadlock in send_sig{io, urg}() + - rtc: sun6i: Fix memleak in sun6i_rtc_clk_init + - module: set MODULE_STATE_GOING state when a module fails to load + - quota: Don't overflow quota file offsets + - rtc: pl031: fix resource leak in pl031_probe + - powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe() + - i3c master: fix missing destroy_workqueue() on error in i3c_master_register + - NFSv4: Fix a pNFS layout related use-after-free race when freeing the inode + - f2fs: avoid race condition for shrinker count + - module: delay kobject uevent until after module init call + - fs/namespace.c: WARN if mnt_count has become negative + - um: ubd: Submit all data segments atomically + - tick/sched: Remove bogus boot "safety" check + - ALSA: pcm: Clear the full allocated memory at hw_params + - dm verity: skip verity work if I/O error when system is shutting down + - Linux 5.4.87 + + -- Guilherme G. Piccoli Thu, 25 Feb 2021 16:41:54 -0300 + +linux-oracle (5.4.0-1038.41) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1038.41 -proposed tracker (LP: #1913149) + + * Focal update: v5.4.85 upstream stable release (LP: #1910817) + - [Config] [oracle] updateconfigs for USB_SISUSBVGA_CON + + * Focal update: v5.4.84 upstream stable release (LP: #1910816) + - [Config] [oracle] updateconfigs for PGTABLE_MAPPING + + * Focal update: v5.4.80 upstream stable release (LP: #1908561) + - [Config] [oracle] updateconfigs for INFINIBAND_VIRT_DMA + + [ Ubuntu: 5.4.0-66.74 ] + + * focal/linux: 5.4.0-66.74 -proposed tracker (LP: #1913152) + * Add support for selective build of special drivers (LP: #1912789) + - [Packaging] Add support for ODM drivers + - [Packaging] Turn on ODM support for amd64 + * Packaging resync (LP: #1786013) + - update dkms package versions + - update dkms package versions + * Introduce the new NVIDIA 460-server series and update the 460 series + (LP: #1913200) + - [Config] dkms-versions -- drop NVIDIA 435 455 and 440-server + - [Config] dkms-versions -- add the 460-server nvidia driver + * Enable mute and micmute LED on HP EliteBook 850 G7 (LP: #1910102) + - ALSA: hda/realtek: Enable mute and micmute LED on HP EliteBook 850 G7 + * SYNA30B4:00 06CB:CE09 Mouse on HP EliteBook 850 G7 not working at all + (LP: #1908992) + - HID: multitouch: Enable multi-input for Synaptics pointstick/touchpad device + * HD Audio Device PCI ID for the Intel Cometlake-R platform (LP: #1912427) + - SAUCE: ALSA: hda: Add Cometlake-R PCI ID + * switch to an autogenerated nvidia series based core via dkms-versions + (LP: #1912803) + - [Packaging] nvidia -- use dkms-versions to define versions built + - [Packaging] update-version-dkms -- maintain flags fields + - [Config] dkms-versions -- add transitional/skip information for nvidia + packages + * udpgro.sh in net from ubuntu_kernel_selftests seems not reflecting sub-test + result (LP: #1908499) + - selftests: fix the return value for UDP GRO test + * qede: Kubernetes Internal DNS Failure due to QL41xxx NIC not supporting IPIP + tx csum offload (LP: #1909062) + - qede: fix offload for IPIP tunnel packets + * Use DCPD to control HP DreamColor panel (LP: #1911001) + - SAUCE: drm/dp: Another HP DreamColor panel brigntness fix + * kvm: Windows 2k19 with Hyper-v role gets stuck on pending hypervisor + requests on cascadelake based kvm hosts (LP: #1911848) + - KVM: x86: Set KVM_REQ_EVENT if run is canceled with req_immediate_exit set + * Ubuntu 20.10 four needed fixes to 'Add driver for Mellanox Connect-IB + adapters' (LP: #1905574) + - net/mlx5: Fix a race when moving command interface to polling mode + * Fix right sounds and mute/micmute LEDs for HP ZBook Fury 15/17 G7 Mobile + Workstation (LP: #1910561) + - ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP machines + * Ubuntu 20.04 - multicast counter is not increased in ip -s (LP: #1901842) + - net/mlx5e: Fix multicast counter not up-to-date in "ip -s" + * eeh-basic.sh in powerpc from ubuntu_kernel_selftests timeout with 5.4 P8 / + P9 (LP: #1882503) + - selftests/powerpc/eeh: disable kselftest timeout setting for eeh-basic + * DMI entry syntax fix for Pegatron / ByteSpeed C15B (LP: #1910639) + - Input: i8042 - unbreak Pegatron C15B + * CVE-2020-29372 + - mm: check that mm is still valid in madvise() + * update ENA driver, incl. new ethtool stats (LP: #1910291) + - net: ena: Change WARN_ON expression in ena_del_napi_in_range() + - net: ena: ethtool: convert stat_offset to 64 bit resolution + - net: ena: ethtool: Add new device statistics + - net: ena: ethtool: add stats printing to XDP queues + - net: ena: xdp: add queue counters for xdp actions + - net: ena: Change license into format to SPDX in all files + - net: ena: Change log message to netif/dev function + - net: ena: Capitalize all log strings and improve code readability + - net: ena: Remove redundant print of placement policy + - net: ena: Change RSS related macros and variables names + - net: ena: Fix all static chekers' warnings + - drivers/net/ethernet: remove incorrectly formatted doc + - net: ena: handle bad request id in ena_netdev + - net: ena: fix packet's addresses for rx_offset feature + * s390x broken with unknown syscall number on kernels < 5.8 (LP: #1895132) + - s390/ptrace: return -ENOSYS when invalid syscall is supplied + * Focal update: v5.4.86 upstream stable release (LP: #1910822) + - ARM: dts: sun7i: bananapi: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun8i: r40: bananapi-m2-berry: Fix dcdc1 regulator + - ARM: dts: sun8i: v40: bananapi-m2-berry: Fix ethernet node + - pinctrl: merrifield: Set default bias in case no particular value given + - pinctrl: baytrail: Avoid clearing debounce value when turning it off + - ARM: dts: sun8i: v3s: fix GIC node memory range + - ARM: dts: sun7i: pcduino3-nano: enable RGMII RX/TX delay on PHY + - ARM: dts: imx6qdl-wandboard-revd1: Remove PAD_GPIO_6 from enetgrp + - ARM: dts: imx6qdl-kontron-samx6i: fix I2C_PM scl pin + - PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter + - gpio: zynq: fix reference leak in zynq_gpio functions + - gpio: mvebu: fix potential user-after-free on probe + - scsi: bnx2i: Requires MMU + - xsk: Fix xsk_poll()'s return type + - xsk: Replace datagram_poll by sock_poll_wait + - can: softing: softing_netdev_open(): fix error handling + - clk: renesas: r9a06g032: Drop __packed for portability + - block: Simplify REQ_OP_ZONE_RESET_ALL handling + - block: factor out requeue handling from dispatch code + - blk-mq: In blk_mq_dispatch_rq_list() "no budget" is a reason to kick + - pinctrl: aspeed: Fix GPIO requests on pass-through banks + - netfilter: x_tables: Switch synchronization to RCU + - netfilter: nft_compat: make sure xtables destructors have run + - netfilter: nft_dynset: fix timeouts later than 23 days + - afs: Fix memory leak when mounting with multiple source parameters + - Revert "gpio: eic-sprd: Use devm_platform_ioremap_resource()" + - gpio: eic-sprd: break loop when getting NULL device resource + - netfilter: nft_ct: Remove confirmation check for NFT_CT_ID + - selftests/bpf/test_offload.py: Reset ethtool features after failed setting + - RDMA/cm: Fix an attempt to use non-valid pointer when cleaning timewait + - i40e: Refactor rx_bi accesses + - i40e: optimise prefetch page refcount + - i40e: avoid premature Rx buffer reuse + - ixgbe: avoid premature Rx buffer reuse + - selftests: fix poll error in udpgro.sh + - net: mvpp2: add mvpp2_phylink_to_port() helper + - drm/tegra: replace idr_init() by idr_init_base() + - kernel/cpu: add arch override for clear_tasks_mm_cpumask() mm handling + - drm/tegra: sor: Disable clocks on error in tegra_sor_init() + - habanalabs: put devices before driver removal + - arm64: syscall: exit userspace before unmasking exceptions + - vxlan: Add needed_headroom for lower device + - vxlan: Copy needed_tailroom from lowerdev + - scsi: mpt3sas: Increase IOCInit request timeout to 30s + - dm table: Remove BUG_ON(in_interrupt()) + - iwlwifi: pcie: add one missing entry for AX210 + - drm/amd/display: Init clock value by current vbios CLKs + - perf/x86/intel: Check PEBS status correctly + - kbuild: avoid split lines in .mod files + - soc/tegra: fuse: Fix index bug in get_process_id + - usb: mtu3: fix memory corruption in mtu3_debugfs_regset() + - USB: serial: option: add interface-number sanity check to flag handling + - USB: gadget: f_acm: add support for SuperSpeed Plus + - USB: gadget: f_midi: setup SuperSpeed Plus descriptors + - usb: gadget: f_fs: Re-use SS descriptors for SuperSpeedPlus + - USB: gadget: f_rndis: fix bitrate for SuperSpeed and above + - usb: chipidea: ci_hdrc_imx: Pass DISABLE_DEVICE_STREAMING flag to imx6ul + - ARM: dts: exynos: fix roles of USB 3.0 ports on Odroid XU + - ARM: dts: exynos: fix USB 3.0 VBUS control and over-current pins on + Exynos5410 + - ARM: dts: exynos: fix USB 3.0 pins supply being turned off on Odroid XU + - coresight: tmc-etf: Fix NULL ptr dereference in tmc_enable_etf_sink_perf() + - coresight: tmc-etr: Check if page is valid before dma_map_page() + - coresight: tmc-etr: Fix barrier packet insertion for perf buffer + - coresight: etb10: Fix possible NULL ptr dereference in etb_enable_perf() + - scsi: megaraid_sas: Check user-provided offsets + - HID: i2c-hid: add Vero K147 to descriptor override + - serial_core: Check for port state when tty is in error state + - Bluetooth: Fix slab-out-of-bounds read in hci_le_direct_adv_report_evt() + - quota: Sanity-check quota file headers on load + - media: msi2500: assign SPI bus number dynamically + - crypto: af_alg - avoid undefined behavior accessing salg_name + - md: fix a warning caused by a race between concurrent md_ioctl()s + - drm/gma500: fix double free of gma_connector + - drm/aspeed: Fix Kconfig warning & subsequent build errors + - drm/mcde: Fix handling of platform_get_irq() error + - drm/tve200: Fix handling of platform_get_irq() error + - arm64: dts: renesas: hihope-rzg2-ex: Drop rxc-skew-ps from ethernet-phy node + - arm64: dts: renesas: cat875: Remove rxc-skew-ps from ethernet-phy node + - soc: renesas: rmobile-sysc: Fix some leaks in rmobile_init_pm_domains() + - soc: mediatek: Check if power domains can be powered on at boot time + - soc: qcom: geni: More properly switch to DMA mode + - Revert "i2c: i2c-qcom-geni: Fix DMA transfer race" + - RDMA/bnxt_re: Set queue pair state when being queried + - rtc: pcf2127: fix pcf2127_nvmem_read/write() returns + - selinux: fix error initialization in inode_doinit_with_dentry() + - ARM: dts: aspeed: s2600wf: Fix VGA memory region location + - RDMA/rxe: Compute PSN windows correctly + - x86/mm/ident_map: Check for errors from ident_pud_init() + - ARM: p2v: fix handling of LPAE translation in BE mode + - x86/apic: Fix x2apic enablement without interrupt remapping + - sched/deadline: Fix sched_dl_global_validate() + - sched: Reenable interrupts in do_sched_yield() + - drm/amdgpu: fix incorrect enum type + - crypto: talitos - Endianess in current_desc_hdr() + - crypto: talitos - Fix return type of current_desc_hdr() + - crypto: inside-secure - Fix sizeof() mismatch + - ASoC: sun4i-i2s: Fix lrck_period computation for I2S justified mode + - ARM: dts: aspeed: tiogapass: Remove vuart + - drm/amdgpu: fix build_coefficients() argument + - powerpc/64: Set up a kernel stack for secondaries before cpu_restore() + - spi: img-spfi: fix reference leak in img_spfi_resume + - f2fs: call f2fs_get_meta_page_retry for nat page + - drm/msm/dsi_pll_10nm: restore VCO rate during restore_state + - spi: spi-mem: fix reference leak in spi_mem_access_start + - ASoC: pcm: DRAIN support reactivation + - selinux: fix inode_doinit_with_dentry() LABEL_INVALID error handling + - spi: stm32: fix reference leak in stm32_spi_resume + - brcmfmac: Fix memory leak for unpaired brcmf_{alloc/free} + - arm64: dts: exynos: Include common syscon restart/poweroff for Exynos7 + - arm64: dts: exynos: Correct psci compatible used on Exynos7 + - Bluetooth: Fix null pointer dereference in hci_event_packet() + - Bluetooth: hci_h5: fix memory leak in h5_close + - spi: spi-ti-qspi: fix reference leak in ti_qspi_setup + - spi: mt7621: fix missing clk_disable_unprepare() on error in + mt7621_spi_probe + - spi: tegra20-slink: fix reference leak in slink ops of tegra20 + - spi: tegra20-sflash: fix reference leak in tegra_sflash_resume + - spi: tegra114: fix reference leak in tegra spi ops + - spi: bcm63xx-hsspi: fix missing clk_disable_unprepare() on error in + bcm63xx_hsspi_resume + - mwifiex: fix mwifiex_shutdown_sw() causing sw reset failure + - selftest/bpf: Add missed ip6ip6 test back + - ASoC: wm8998: Fix PM disable depth imbalance on error + - spi: sprd: fix reference leak in sprd_spi_remove + - ASoC: arizona: Fix a wrong free in wm8997_probe + - RDMa/mthca: Work around -Wenum-conversion warning + - MIPS: BCM47XX: fix kconfig dependency bug for BCM47XX_BCMA + - crypto: qat - fix status check in qat_hal_put_rel_rd_xfer() + - staging: greybus: codecs: Fix reference counter leak in error handling + - staging: gasket: interrupt: fix the missed eventfd_ctx_put() in + gasket_interrupt.c + - media: tm6000: Fix sizeof() mismatches + - media: mtk-vcodec: add missing put_device() call in mtk_vcodec_init_dec_pm() + - media: mtk-vcodec: add missing put_device() call in + mtk_vcodec_release_dec_pm() + - media: mtk-vcodec: add missing put_device() call in mtk_vcodec_init_enc_pm() + - media: v4l2-fwnode: Return -EINVAL for invalid bus-type + - ASoC: meson: fix COMPILE_TEST error + - scsi: core: Fix VPD LUN ID designator priorities + - media: solo6x10: fix missing snd_card_free in error handling case + - video: fbdev: atmel_lcdfb: fix return error code in atmel_lcdfb_of_init() + - drm/omap: dmm_tiler: fix return error code in omap_dmm_probe() + - Input: ads7846 - fix race that causes missing releases + - Input: ads7846 - fix integer overflow on Rt calculation + - Input: ads7846 - fix unaligned access on 7845 + - usb/max3421: fix return error code in max3421_probe() + - spi: mxs: fix reference leak in mxs_spi_probe + - selftests/bpf: Fix broken riscv build + - powerpc: Avoid broken GCC __attribute__((optimize)) + - powerpc/feature: Fix CPU_FTRS_ALWAYS by removing CPU_FTRS_GENERIC_32 + - EDAC/mce_amd: Use struct cpuinfo_x86.cpu_die_id for AMD NodeId + - crypto: crypto4xx - Replace bitwise OR with logical OR in crypto4xx_build_pd + - crypto: omap-aes - Fix PM disable depth imbalance in omap_aes_probe + - spi: fix resource leak for drivers without .remove callback + - soc: ti: knav_qmss: fix reference leak in knav_queue_probe + - soc: ti: Fix reference imbalance in knav_dma_probe + - drivers: soc: ti: knav_qmss_queue: Fix error return code in knav_queue_probe + - Input: omap4-keypad - fix runtime PM error handling + - clk: meson: Kconfig: fix dependency for G12A + - RDMA/cxgb4: Validate the number of CQEs + - memstick: fix a double-free bug in memstick_check + - ARM: dts: at91: sama5d4_xplained: add pincontrol for USB Host + - ARM: dts: at91: sama5d3_xplained: add pincontrol for USB Host + - mmc: pxamci: Fix error return code in pxamci_probe + - orinoco: Move context allocation after processing the skb + - qtnfmac: fix error return code in qtnf_pcie_probe() + - rsi: fix error return code in rsi_reset_card() + - cw1200: fix missing destroy_workqueue() on error in cw1200_init_common + - dmaengine: mv_xor_v2: Fix error return code in mv_xor_v2_probe() + - arm64: tegra: Fix DT binding for IO High Voltage entry + - media: siano: fix memory leak of debugfs members in smsdvb_hotplug + - platform/x86: mlx-platform: Remove PSU EEPROM from default platform + configuration + - platform/x86: mlx-platform: Remove PSU EEPROM from MSN274x platform + configuration + - samples: bpf: Fix lwt_len_hist reusing previous BPF map + - media: imx214: Fix stop streaming + - mips: cdmm: fix use-after-free in mips_cdmm_bus_discover + - media: max2175: fix max2175_set_csm_mode() error code + - slimbus: qcom-ngd-ctrl: Avoid sending power requests without QMI + - HSI: omap_ssi: Don't jump to free ID in ssi_add_controller() + - ARM: dts: Remove non-existent i2c1 from 98dx3236 + - arm64: dts: armada-3720-turris-mox: update ethernet-phy handle name + - arm64: dts: rockchip: Set dr_mode to "host" for OTG on rk3328-roc-cc + - power: supply: axp288_charger: Fix HP Pavilion x2 10 DMI matching + - power: supply: bq24190_charger: fix reference leak + - genirq/irqdomain: Don't try to free an interrupt that has no mapping + - arm64: dts: ls1028a: fix ENETC PTP clock input + - arm64: dts: qcom: c630: Polish i2c-hid devices + - PCI: Bounds-check command-line resource alignment requests + - PCI: Fix overflow in command-line resource alignment requests + - PCI: iproc: Fix out-of-bound array accesses + - arm64: dts: meson: fix spi-max-frequency on Khadas VIM2 + - arm64: dts: meson-sm1: fix typo in opp table + - soc: amlogic: canvas: add missing put_device() call in meson_canvas_get() + - ARM: dts: at91: at91sam9rl: fix ADC triggers + - platform/x86: dell-smbios-base: Fix error return code in dell_smbios_init + - ath10k: Fix the parsing error in service available event + - ath10k: Fix an error handling path + - ath10k: Release some resources in an error handling path + - SUNRPC: rpc_wake_up() should wake up tasks in the correct order + - NFSv4.2: condition READDIR's mask for security label based on LSM state + - SUNRPC: xprt_load_transport() needs to support the netid "rdma6" + - NFSv4: Fix the alignment of page data in the getdeviceinfo reply + - net: sunrpc: Fix 'snprintf' return value check in 'do_xprt_debugfs' + - lockd: don't use interval-based rebinding over TCP + - NFS: switch nfsiod to be an UNBOUND workqueue. + - selftests/seccomp: Update kernel config + - vfio-pci: Use io_remap_pfn_range() for PCI IO memory + - hwmon: (ina3221) Fix PM usage counter unbalance in ina3221_write_enable + - media: saa7146: fix array overflow in vidioc_s_audio() + - powerpc/perf: Fix crash with is_sier_available when pmu is not set + - powerpc/64: Fix an EMIT_BUG_ENTRY in head_64.S + - clocksource/drivers/orion: Add missing clk_disable_unprepare() on error path + - clocksource/drivers/cadence_ttc: Fix memory leak in ttc_setup_clockevent() + - iio: hrtimer-trigger: Mark hrtimer to expire in hard interrupt context + - ARM: dts: at91: sama5d2: map securam as device + - bpf: Fix bpf_put_raw_tracepoint()'s use of __module_address() + - pinctrl: falcon: add missing put_device() call in pinctrl_falcon_probe() + - arm64: dts: rockchip: Fix UART pull-ups on rk3328 + - memstick: r592: Fix error return in r592_probe() + - MIPS: Don't round up kernel sections size for memblock_add() + - net/mlx5: Properly convey driver version to firmware + - ASoC: jz4740-i2s: add missed checks for clk_get() + - dm ioctl: fix error return code in target_message + - phy: renesas: rcar-gen3-usb2: disable runtime pm in case of failure + - clocksource/drivers/arm_arch_timer: Use stable count reader in erratum sne + - clocksource/drivers/arm_arch_timer: Correct fault programming of + CNTKCTL_EL1.EVNTI + - cpufreq: ap806: Add missing MODULE_DEVICE_TABLE + - cpufreq: highbank: Add missing MODULE_DEVICE_TABLE + - cpufreq: mediatek: Add missing MODULE_DEVICE_TABLE + - cpufreq: qcom: Add missing MODULE_DEVICE_TABLE + - cpufreq: st: Add missing MODULE_DEVICE_TABLE + - cpufreq: sun50i: Add missing MODULE_DEVICE_TABLE + - cpufreq: loongson1: Add missing MODULE_ALIAS + - cpufreq: scpi: Add missing MODULE_ALIAS + - Bluetooth: btusb: Add the missed release_firmware() in + btusb_mtk_setup_firmware() + - Bluetooth: btmtksdio: Add the missed release_firmware() in + mtk_setup_firmware() + - arm64: dts: meson: fix PHY deassert timing requirements + - ARM: dts: meson: fix PHY deassert timing requirements + - arm64: dts: meson: g12a: x96-max: fix PHY deassert timing requirements + - scsi: qedi: Fix missing destroy_workqueue() on error in __qedi_probe + - scsi: pm80xx: Fix error return in pm8001_pci_probe() + - seq_buf: Avoid type mismatch for seq_buf_init + - scsi: fnic: Fix error return code in fnic_probe() + - platform/x86: mlx-platform: Fix item counter assignment for MSN2700, MSN24xx + systems + - powerpc/pseries/hibernation: drop pseries_suspend_begin() from suspend ops + - powerpc/pseries/hibernation: remove redundant cacheinfo update + - drm/mediatek: avoid dereferencing a null hdmi_phy on an error message + - ASoC: amd: change clk_get() to devm_clk_get() and add missed checks + - powerpc/mm: sanity_check_fault() should work for all, not only BOOK3S + - usb: ehci-omap: Fix PM disable depth umbalance in ehci_hcd_omap_probe + - usb: oxu210hp-hcd: Fix memory leak in oxu_create + - speakup: fix uninitialized flush_lock + - nfsd: Fix message level for normal termination + - nfs_common: need lock during iterate through the list + - x86/kprobes: Restore BTF if the single-stepping is cancelled + - platform/chrome: cros_ec_spi: Don't overwrite spi::mode + - bus: fsl-mc: fix error return code in fsl_mc_object_allocate() + - s390/cio: fix use-after-free in ccw_device_destroy_console + - iwlwifi: mvm: hook up missing RX handlers + - erofs: avoid using generic_block_bmap + - can: m_can: m_can_config_endisable(): remove double clearing of clock stop + request bit + - RDMA/core: Do not indicate device ready when device enablement fails + - remoteproc: q6v5-mss: fix error handling in q6v5_pds_enable + - remoteproc: qcom: fix reference leak in adsp_start + - remoteproc: qcom: Fix potential NULL dereference in adsp_init_mmio() + - clk: tegra: Fix duplicated SE clock entry + - mtd: rawnand: gpmi: fix reference count leak in gpmi ops + - mtd: rawnand: meson: Fix a resource leak in init + - mtd: rawnand: gpmi: Fix the random DMA timeout issue + - extcon: max77693: Fix modalias string + - crypto: atmel-i2c - select CONFIG_BITREVERSE + - mac80211: don't set set TDLS STA bandwidth wider than possible + - ASoC: wm_adsp: remove "ctl" from list on error in wm_adsp_create_control() + - irqchip/alpine-msi: Fix freeing of interrupts on allocation error path + - watchdog: armada_37xx: Add missing dependency on HAS_IOMEM + - watchdog: sirfsoc: Add missing dependency on HAS_IOMEM + - watchdog: sprd: remove watchdog disable from resume fail path + - watchdog: sprd: check busy bit before new loading rather than after that + - watchdog: Fix potential dereferencing of null pointer + - ubifs: Fix error return code in ubifs_init_authentication() + - um: Monitor error events in IRQ controller + - um: tty: Fix handling of close in tty lines + - um: chan_xterm: Fix fd leak + - sunrpc: fix xs_read_xdr_buf for partial pages receive + - RDMA/cma: Don't overwrite sgid_attr after device is released + - nfc: s3fwrn5: Release the nfc firmware + - powerpc/ps3: use dma_mapping_error() + - sparc: fix handling of page table constructor failure + - mm: don't wake kswapd prematurely when watermark boosting is disabled + - checkpatch: fix unescaped left brace + - lan743x: fix rx_napi_poll/interrupt ping-pong + - net: bcmgenet: Fix a resource leak in an error handling path in the probe + functin + - net: allwinner: Fix some resources leak in the error handling path of the + probe and in the remove function + - net: korina: fix return value + - libnvdimm/label: Return -ENXIO for no slot in __blk_label_update + - watchdog: qcom: Avoid context switch in restart handler + - watchdog: coh901327: add COMMON_CLK dependency + - clk: ti: Fix memleak in ti_fapll_synth_setup + - pwm: zx: Add missing cleanup in error path + - pwm: lp3943: Dynamically allocate PWM chip base + - perf record: Fix memory leak when using '--user-regs=?' to list registers + - qlcnic: Fix error code in probe + - virtio_ring: Cut and paste bugs in vring_create_virtqueue_packed() + - virtio_net: Fix error code in probe() + - virtio_ring: Fix two use after free bugs + - clk: at91: sam9x60: remove atmel,osc-bypass support + - clk: s2mps11: Fix a resource leak in error handling paths in the probe + function + - clk: sunxi-ng: Make sure divider tables have sentinel + - kconfig: fix return value of do_error_if() + - perf probe: Fix memory leak when synthesizing SDT probes + - ARM: sunxi: Add machine match for the Allwinner V3 SoC + - cfg80211: initialize rekey_data + - fix namespaced fscaps when !CONFIG_SECURITY + - lwt: Disable BH too in run_lwt_bpf() + - drm/amd/display: Prevent bandwidth overflow + - drm/amdkfd: Fix leak in dmabuf import + - Input: cros_ec_keyb - send 'scancodes' in addition to key events + - initramfs: fix clang build failure + - Input: goodix - add upside-down quirk for Teclast X98 Pro tablet + - vfio/pci/nvlink2: Do not attempt NPU2 setup on POWER8NVL NPU + - media: gspca: Fix memory leak in probe + - media: sunxi-cir: ensure IR is handled when it is continuous + - media: netup_unidvb: Don't leak SPI master in probe error path + - media: ipu3-cio2: Remove traces of returned buffers + - media: ipu3-cio2: Return actual subdev format + - media: ipu3-cio2: Serialise access to pad format + - media: ipu3-cio2: Validate mbus format in setting subdev format + - media: ipu3-cio2: Make the field on subdev format V4L2_FIELD_NONE + - Input: cyapa_gen6 - fix out-of-bounds stack access + - ALSA: hda/ca0132 - Change Input Source enum strings. + - Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources + walks" + - ACPI: PNP: compare the string length in the matching_id() + - ALSA: hda: Fix regressions on clear and reconfig sysfs + - ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg. + - ALSA: hda/realtek: make bass spk volume adjustable on a yoga laptop + - ALSA: hda/realtek - Enable headset mic of ASUS X430UN with ALC256 + - ALSA: hda/realtek - Enable headset mic of ASUS Q524UQK with ALC255 + - ALSA: hda/realtek - Add supported for more Lenovo ALC285 Headset Button + - ALSA: pcm: oss: Fix a few more UBSAN fixes + - ALSA/hda: apply jack fixup for the Acer Veriton N4640G/N6640G/N2510G + - ALSA: hda/realtek: Add quirk for MSI-GP73 + - ALSA: hda/realtek: Apply jack fixup for Quanta NL3 + - ALSA: usb-audio: Add VID to support native DSD reproduction on FiiO devices + - ALSA: usb-audio: Disable sample read check if firmware doesn't give back + - ALSA: core: memalloc: add page alignment for iram + - s390/smp: perform initial CPU reset also for SMT siblings + - s390/kexec_file: fix diag308 subcode when loading crash kernel + - s390/dasd: fix hanging device offline processing + - s390/dasd: prevent inconsistent LCU device data + - s390/dasd: fix list corruption of pavgroup group list + - s390/dasd: fix list corruption of lcu list + - binder: add flag to clear buffer on txn complete + - ASoC: cx2072x: Fix doubly definitions of Playback and Capture streams + - staging: comedi: mf6x4: Fix AI end-of-conversion detection + - perf/x86/intel: Add event constraint for CYCLE_ACTIVITY.STALLS_MEM_ANY + - perf/x86/intel: Fix rtm_abort_event encoding on Ice Lake + - powerpc/perf: Exclude kernel samples while counting events in user space. + - crypto: ecdh - avoid unaligned accesses in ecdh_set_secret() + - crypto: arm/aes-ce - work around Cortex-A57/A72 silion errata + - EDAC/i10nm: Use readl() to access MMIO registers + - EDAC/amd64: Fix PCI component registration + - cpuset: fix race between hotplug work and later CPU offline + - USB: serial: mos7720: fix parallel-port state restore + - USB: serial: digi_acceleport: fix write-wakeup deadlocks + - USB: serial: keyspan_pda: fix dropped unthrottle interrupts + - USB: serial: keyspan_pda: fix write deadlock + - USB: serial: keyspan_pda: fix stalled writes + - USB: serial: keyspan_pda: fix write-wakeup use-after-free + - USB: serial: keyspan_pda: fix tx-unthrottle use-after-free + - USB: serial: keyspan_pda: fix write unthrottling + - btrfs: do not shorten unpin len for caching block groups + - ext4: fix a memory leak of ext4_free_data + - ext4: fix deadlock with fs freezing and EA inodes + - KVM: arm64: Introduce handling of AArch32 TTBCR2 traps + - ARM: dts: pandaboard: fix pinmux for gpio user button of Pandaboard ES + - ARM: dts: at91: sama5d2: fix CAN message ram offset and size + - xprtrdma: Fix XDRBUF_SPARSE_PAGES support + - powerpc: Fix incorrect stw{, ux, u, x} instructions in __set_pte_at + - powerpc/rtas: Fix typo of ibm,open-errinjct in RTAS filter + - powerpc/feature: Add CPU_FTR_NOEXECUTE to G2_LE + - powerpc/xmon: Change printk() to pr_cont() + - powerpc/8xx: Fix early debug when SMC1 is relocated + - powerpc/mm: Fix verification of MMU_FTR_TYPE_44x + - powerpc/powernv/npu: Do not attempt NPU2 setup on POWER8NVL NPU + - powerpc/powernv/memtrace: Don't leak kernel memory to user space + - powerpc/powernv/memtrace: Fix crashing the kernel when enabling concurrently + - ima: Don't modify file descriptor mode on the fly + - um: Remove use of asprinf in umid.c + - ceph: fix race in concurrent __ceph_remove_cap invocations + - SMB3: avoid confusing warning message on mount to Azure + - ubifs: wbuf: Don't leak kernel memory to flash + - jffs2: Fix GC exit abnormally + - jffs2: Fix ignoring mounting options problem during remounting + - jfs: Fix array index bounds check in dbAdjTree + - platform/x86: mlx-platform: remove an unused variable + - drm/amd/display: Fix memory leaks in S3 resume + - drm/dp_aux_dev: check aux_dev before use in drm_dp_aux_dev_get_by_minor() + - drm/i915: Fix mismatch between misplaced vma check and vma insert + - spi: pxa2xx: Fix use-after-free on unbind + - spi: spi-sh: Fix use-after-free on unbind + - spi: atmel-quadspi: Fix use-after-free on unbind + - spi: davinci: Fix use-after-free on unbind + - spi: fsl: fix use of spisel_boot signal on MPC8309 + - spi: gpio: Don't leak SPI master in probe error path + - spi: mxic: Don't leak SPI master in probe error path + - spi: pic32: Don't leak DMA channels in probe error path + - spi: rb4xx: Don't leak SPI master in probe error path + - spi: sc18is602: Don't leak SPI master in probe error path + - spi: st-ssc4: Fix unbalanced pm_runtime_disable() in probe error path + - spi: synquacer: Disable clock in probe error path + - spi: mt7621: Disable clock in probe error path + - spi: mt7621: Don't leak SPI master in probe error path + - spi: atmel-quadspi: Disable clock in probe error path + - spi: atmel-quadspi: Fix AHB memory accesses + - soc: qcom: smp2p: Safely acquire spinlock without IRQs + - mtd: spinand: Fix OOB read + - mtd: parser: cmdline: Fix parsing of part-names with colons + - mtd: rawnand: qcom: Fix DMA sync on FLASH_STATUS register read + - mtd: rawnand: meson: fix meson_nfc_dma_buffer_release() arguments + - scsi: qla2xxx: Fix crash during driver load on big endian machines + - scsi: lpfc: Fix invalid sleeping context in lpfc_sli4_nvmet_alloc() + - scsi: lpfc: Re-fix use after free in lpfc_rq_buf_free() + - iio: buffer: Fix demux update + - iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in + rockchip_saradc_resume + - iio:light:rpr0521: Fix timestamp alignment and prevent data leak. + - iio:light:st_uvis25: Fix timestamp alignment and prevent data leak. + - iio:magnetometer:mag3110: Fix alignment and data leak issues. + - iio:pressure:mpl3115: Force alignment of buffer + - iio:imu:bmi160: Fix too large a buffer. + - iio:adc:ti-ads124s08: Fix buffer being too long. + - iio:adc:ti-ads124s08: Fix alignment and data leak issues. + - md/cluster: block reshape with remote resync job + - md/cluster: fix deadlock when node is doing resync job + - pinctrl: sunxi: Always call chained_irq_{enter, exit} in + sunxi_pinctrl_irq_handler + - clk: ingenic: Fix divider calculation with div tables + - clk: mvebu: a3700: fix the XTAL MODE pin to MPP1_9 + - clk: tegra: Do not return 0 on failure + - device-dax/core: Fix memory leak when rmmod dax.ko + - dma-buf/dma-resv: Respect num_fences when initializing the shared fence + list. + - xen-blkback: set ring->xenblkd to NULL after kthread_stop() + - xen/xenbus: Allow watches discard events before queueing + - xen/xenbus: Add 'will_handle' callback support in xenbus_watch_path() + - xen/xenbus/xen_bus_type: Support will_handle watch callback + - xen/xenbus: Count pending messages for each watch + - xenbus/xenbus_backend: Disallow pending watch messages + - libnvdimm/namespace: Fix reaping of invalidated block-window-namespace + labels + - platform/x86: intel-vbtn: Allow switch events on Acer Switch Alpha 12 + - PCI: Fix pci_slot_release() NULL pointer dereference + - regulator: axp20x: Fix DLDO2 voltage control register mask for AXP22x + - rtc: ep93xx: Fix NULL pointer dereference in ep93xx_rtc_read_time + - Revert: "ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS" + - x86/CPU/AMD: Save AMD NodeId as cpu_die_id + - Linux 5.4.86 + * Focal update: v5.4.85 upstream stable release (LP: #1910817) + - ptrace: Prevent kernel-infoleak in ptrace_get_syscall_info() + - ipv4: fix error return code in rtm_to_fib_config() + - mac80211: mesh: fix mesh_pathtbl_init() error path + - net: bridge: vlan: fix error return code in __vlan_add() + - vrf: packets with lladdr src needs dst at input with orig_iif when needs + strict + - net: hns3: remove a misused pragma packed + - udp: fix the proto value passed to ip_protocol_deliver_rcu for the segments + - enetc: Fix reporting of h/w packet counters + - bridge: Fix a deadlock when enabling multicast snooping + - net: stmmac: free tx skb buffer in stmmac_resume() + - tcp: select sane initial rcvq_space.space for big MSS + - tcp: fix cwnd-limited bug for TSO deferral where we send nothing + - net/mlx4_en: Avoid scheduling restart task if it is already running + - lan743x: fix for potential NULL pointer dereference with bare card + - net/mlx4_en: Handle TX error CQE + - net: ll_temac: Fix potential NULL dereference in temac_probe() + - net: stmmac: dwmac-meson8b: fix mask definition of the m250_sel mux + - net: stmmac: delete the eee_ctrl_timer after napi disabled + - ktest.pl: If size of log is too big to email, email error message + - USB: dummy-hcd: Fix uninitialized array use in init() + - USB: add RESET_RESUME quirk for Snapscan 1212 + - ALSA: usb-audio: Fix potential out-of-bounds shift + - ALSA: usb-audio: Fix control 'access overflow' errors from chmap + - xhci: Give USB2 ports time to enter U3 in bus suspend + - xhci-pci: Allow host runtime PM as default for Intel Alpine Ridge LP + - USB: UAS: introduce a quirk to set no_write_same + - USB: sisusbvga: Make console support depend on BROKEN + - [Config] updateconfigs for USB_SISUSBVGA_CON + - ALSA: pcm: oss: Fix potential out-of-bounds shift + - serial: 8250_omap: Avoid FIFO corruption caused by MDR1 access + - KVM: mmu: Fix SPTE encoding of MMIO generation upper half + - membarrier: Explicitly sync remote cores when SYNC_CORE is requested + - x86/resctrl: Remove unused struct mbm_state::chunks_bw + - x86/resctrl: Fix incorrect local bandwidth when mba_sc is enabled + - Linux 5.4.85 + * Focal update: v5.4.84 upstream stable release (LP: #1910816) + - Kbuild: do not emit debug info for assembly with LLVM_IAS=1 + - x86/lib: Change .weak to SYM_FUNC_START_WEAK for arch/x86/lib/mem*_64.S + - iwlwifi: pcie: limit memory read spin time + - arm64: dts: rockchip: Assign a fixed index to mmc devices on rk3399 boards. + - iwlwifi: pcie: set LTR to avoid completion timeout + - iwlwifi: mvm: fix kernel panic in case of assert during CSA + - powerpc: Drop -me200 addition to build flags + - arm64: dts: broadcom: clear the warnings caused by empty dma-ranges + - ARC: stack unwinding: don't assume non-current task is sleeping + - scsi: ufs: Make sure clk scaling happens only when HBA is runtime ACTIVE + - interconnect: qcom: qcs404: Remove GPU and display RPM IDs + - ibmvnic: skip tx timeout reset while in resetting + - irqchip/gic-v3-its: Unconditionally save/restore the ITS state on suspend + - spi: spi-nxp-fspi: fix fspi panic by unexpected interrupts + - soc: fsl: dpio: Get the cpumask through cpumask_of(cpu) + - arm64: tegra: Disable the ACONNECT for Jetson TX2 + - platform/x86: thinkpad_acpi: Do not report SW_TABLET_MODE on Yoga 11e + - platform/x86: thinkpad_acpi: Add BAT1 is primary battery quirk for Thinkpad + Yoga 11e 4th gen + - platform/x86: acer-wmi: add automatic keyboard background light toggle key + as KEY_LIGHTS_TOGGLE + - platform/x86: intel-vbtn: Support for tablet mode on HP Pavilion 13 x360 PC + - platform/x86: touchscreen_dmi: Add info for the Irbis TW118 tablet + - can: m_can: m_can_dev_setup(): add support for bosch mcan version 3.3.0 + - ktest.pl: Fix incorrect reboot for grub2bls + - Input: cm109 - do not stomp on control URB + - Input: i8042 - add Acer laptops to the i8042 reset list + - mmc: block: Fixup condition for CMD13 polling for RPMB requests + - drm/i915/display/dp: Compute the correct slice count for VDSC on DP + - kbuild: avoid static_assert for genksyms + - proc: use untagged_addr() for pagemap_read addresses + - scsi: be2iscsi: Revert "Fix a theoretical leak in beiscsi_create_eqs()" + - x86/mm/mem_encrypt: Fix definition of PMD_FLAGS_DEC_WP + - x86/membarrier: Get rid of a dubious optimization + - x86/apic/vector: Fix ordering in vector assignment + - mm/zsmalloc.c: drop ZSMALLOC_PGTABLE_MAPPING + - [Config] updateconfigs for PGTABLE_MAPPING + - compiler.h: fix barrier_data() on clang + - Linux 5.4.84 + * MSFT Touchpad not working on Lenovo Legion-5 15ARH05 (LP: #1887190) // Focal + update: v5.4.84 upstream stable release (LP: #1910816) + - pinctrl: amd: remove debounce filter setting in IRQ type setting + * Focal update: v5.4.83 upstream stable release (LP: #1910784) + - pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq + pin to output + - pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., + GPIOD_OUT_HIGH) + - usb: gadget: f_fs: Use local copy of descriptors for userspace copy + - USB: serial: kl5kusb105: fix memleak on open + - USB: serial: ch341: add new Product ID for CH341A + - USB: serial: ch341: sort device-id entries + - USB: serial: option: add Fibocom NL668 variants + - USB: serial: option: add support for Thales Cinterion EXS82 + - USB: serial: option: fix Quectel BG96 matching + - tty: Fix ->pgrp locking in tiocspgrp() + - tty: Fix ->session locking + - ALSA: hda/realtek: Fix bass speaker DAC assignment on Asus Zephyrus G14 + - ALSA: hda/realtek: Add mute LED quirk to yet another HP x360 model + - ALSA: hda/realtek: Enable headset of ASUS UX482EG & B9400CEA with ALC294 + - ALSA: hda/realtek - Add new codec supported for ALC897 + - ALSA: hda/generic: Add option to enforce preferred_dacs pairs + - ftrace: Fix updating FTRACE_FL_TRAMP + - cifs: allow syscalls to be restarted in __smb_send_rqst() + - cifs: fix potential use-after-free in cifs_echo_request() + - i2c: imx: Don't generate STOP condition if arbitration has been lost + - thunderbolt: Fix use-after-free in remove_unplugged_switch() + - drm/i915/gt: Program mocs:63 for cache eviction on gen9 + - scsi: mpt3sas: Fix ioctl timeout + - dm writecache: fix the maximum number of arguments + - powerpc/64s/powernv: Fix memory corruption when saving SLB entries on MCE + - genirq/irqdomain: Add an irq_create_mapping_affinity() function + - powerpc/pseries: Pass MSI affinity to irq_create_mapping() + - dm: fix bug with RCU locking in dm_blk_report_zones + - dm: remove invalid sparse __acquires and __releases annotations + - x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes + - coredump: fix core_pattern parse error + - mm: list_lru: set shrinker map bit when child nr_items is not zero + - mm/swapfile: do not sleep with a spin lock held + - speakup: Reject setting the speakup line discipline outside of speakup + - i2c: imx: Fix reset of I2SR_IAL flag + - i2c: imx: Check for I2SR_IAL after every byte + - spi: bcm2835: Release the DMA channel if probe fails after dma_init + - iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs + - tracing: Fix userstacktrace option for instances + - lib/syscall: fix syscall registers retrieval on 32-bit platforms + - can: af_can: can_rx_unregister(): remove WARN() statement from list + operation sanity check + - gfs2: check for empty rgrp tree in gfs2_ri_update + - netfilter: ipset: prevent uninit-value in hash_ip6_add + - tipc: fix a deadlock when flushing scheduled work + - ASoC: wm_adsp: fix error return code in wm_adsp_load() + - rtw88: debug: Fix uninitialized memory in debugfs code + - i2c: qup: Fix error return code in qup_i2c_bam_schedule_desc() + - dm writecache: remove BUG() and fail gracefully instead + - Input: i8042 - fix error return code in i8042_setup_aux() + - netfilter: nf_tables: avoid false-postive lockdep splat + - netfilter: nftables_offload: set address type in control dissector + - x86/insn-eval: Use new for_each_insn_prefix() macro to loop over prefixes + bytes + - Linux 5.4.83 + * dep-8 ubuntu-regression-suite tests are not run for all linux-hwe-* kernels + (LP: #1908529) + - [dep-8] Allow all hwe kernels + * failing ftrace self tests from 5.7+ onwards (LP: #1893024) + - SAUCE: Revert "selftests/ftrace: check for do_sys_openat2 in user-memory + test" + * selftests: test_vxlan_under_vrf: mute unnecessary error message + (LP: #1908342) + - selftests: test_vxlan_under_vrf: mute unnecessary error message + * Focal update: v5.4.82 upstream stable release (LP: #1908564) + - devlink: Hold rtnl lock while reading netdev attributes + - ipv6: addrlabel: fix possible memory leak in ip6addrlbl_net_init + - net/af_iucv: set correct sk_protocol for child sockets + - net/tls: missing received data after fast remote close + - net/tls: Protect from calling tls_dev_del for TLS RX twice + - rose: Fix Null pointer dereference in rose_send_frame() + - sock: set sk_err to ee_errno on dequeue from errq + - tcp: Set INET_ECN_xmit configuration in tcp_reinit_congestion_control + - tun: honor IOCB_NOWAIT flag + - usbnet: ipheth: fix connectivity with iOS 14 + - bonding: wait for sysfs kobject destruction before freeing struct slave + - staging/octeon: fix up merge error + - ima: extend boot_aggregate with kernel measurements + - sched/fair: Fix unthrottle_cfs_rq() for leaf_cfs_rq list + - netfilter: bridge: reset skb->pkt_type after NF_INET_POST_ROUTING traversal + - ipv4: Fix tos mask in inet_rtm_getroute() + - dt-bindings: net: correct interrupt flags in examples + - chelsio/chtls: fix panic during unload reload chtls + - ibmvnic: Ensure that SCRQ entry reads are correctly ordered + - ibmvnic: Fix TX completion error handling + - inet_ecn: Fix endianness of checksum update when setting ECT(1) + - net: ip6_gre: set dev->hard_header_len when using header_ops + - net/x25: prevent a couple of overflows + - cxgb3: fix error return code in t3_sge_alloc_qset() + - net: pasemi: fix error return code in pasemi_mac_open() + - vxlan: fix error return code in __vxlan_dev_create() + - chelsio/chtls: fix a double free in chtls_setkey() + - net: mvpp2: Fix error return code in mvpp2_open() + - net: skbuff: ensure LSE is pullable before decrementing the MPLS ttl + - net: openvswitch: ensure LSE is pullable before reading it + - net/sched: act_mpls: ensure LSE is pullable before reading it + - net/mlx5: DR, Proper handling of unsupported Connect-X6DX SW steering + - net/mlx5: Fix wrong address reclaim when command interface is down + - ALSA: usb-audio: US16x08: fix value count for level meters + - Input: xpad - support Ardwiino Controllers + - tracing: Remove WARN_ON in start_thread() + - RDMA/i40iw: Address an mmap handler exploit in i40iw + - Linux 5.4.82 + * Focal update: v5.4.81 upstream stable release (LP: #1908562) + - spi: bcm-qspi: Fix use-after-free on unbind + - spi: bcm2835: Fix use-after-free on unbind + - ipv4: use IS_ENABLED instead of ifdef + - netfilter: clear skb->next in NF_HOOK_LIST() + - btrfs: tree-checker: add missing return after error in root_item + - btrfs: tree-checker: add missing returns after data_ref alignment checks + - btrfs: don't access possibly stale fs_info data for printing duplicate + device + - btrfs: fix lockdep splat when reading qgroup config on mount + - wireless: Use linux/stddef.h instead of stddef.h + - smb3: Call cifs reconnect from demultiplex thread + - smb3: Avoid Mid pending list corruption + - smb3: Handle error case during offload read path + - cifs: fix a memleak with modefromsid + - KVM: PPC: Book3S HV: XIVE: Fix possible oops when accessing ESB page + - KVM: arm64: vgic-v3: Drop the reporting of GICR_TYPER.Last for userspace + - KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint + - KVM: x86: Fix split-irqchip vs interrupt injection window request + - trace: fix potenial dangerous pointer + - arm64: pgtable: Fix pte_accessible() + - arm64: pgtable: Ensure dirty bit is preserved across pte_wrprotect() + - HID: uclogic: Add ID for Trust Flex Design Tablet + - HID: ite: Replace ABS_MISC 120/121 events with touchpad on/off keypresses + - HID: cypress: Support Varmilo Keyboards' media hotkeys + - HID: add support for Sega Saturn + - Input: i8042 - allow insmod to succeed on devices without an i8042 + controller + - HID: hid-sensor-hub: Fix issue with devices with no report ID + - staging: ralink-gdma: fix kconfig dependency bug for DMA_RALINK + - HID: add HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE for Gamevice devices + - dmaengine: xilinx_dma: use readl_poll_timeout_atomic variant + - x86/xen: don't unbind uninitialized lock_kicker_irq + - HID: logitech-hidpp: Add HIDPP_CONSUMER_VENDOR_KEYS quirk for the Dinovo + Edge + - HID: Add Logitech Dinovo Edge battery quirk + - proc: don't allow async path resolution of /proc/self components + - nvme: free sq/cq dbbuf pointers when dbbuf set fails + - vhost scsi: fix cmd completion race + - dmaengine: pl330: _prep_dma_memcpy: Fix wrong burst size + - scsi: libiscsi: Fix NOP race condition + - scsi: target: iscsi: Fix cmd abort fabric stop race + - perf/x86: fix sysfs type mismatches + - xtensa: uaccess: Add missing __user to strncpy_from_user() prototype + - net: dsa: mv88e6xxx: Wait for EEPROM done after HW reset + - bus: ti-sysc: Fix bogus resetdone warning on enable for cpsw + - ARM: OMAP2+: Manage MPU state properly for omap_enter_idle_coupled() + - phy: tegra: xusb: Fix dangling pointer on probe failure + - iwlwifi: mvm: write queue_sync_state only for sync + - batman-adv: set .owner to THIS_MODULE + - arch: pgtable: define MAX_POSSIBLE_PHYSMEM_BITS where needed + - ARM: dts: dra76x: m_can: fix order of clocks + - scsi: ufs: Fix race between shutdown and runtime resume flow + - bnxt_en: fix error return code in bnxt_init_one() + - bnxt_en: fix error return code in bnxt_init_board() + - video: hyperv_fb: Fix the cache type when mapping the VRAM + - bnxt_en: Release PCI regions when DMA mask setup fails during probe. + - cxgb4: fix the panic caused by non smac rewrite + - s390/qeth: make af_iucv TX notification call more robust + - s390/qeth: fix af_iucv notification race + - s390/qeth: fix tear down of async TX buffers + - ibmvnic: fix call_netdevice_notifiers in do_reset + - ibmvnic: notify peers when failover and migration happen + - powerpc/64s: Fix allnoconfig build since uaccess flush + - IB/mthca: fix return value of error branch in mthca_init_cq() + - i40e: Fix removing driver while bare-metal VFs pass traffic + - nfc: s3fwrn5: use signed integer for parsing GPIO numbers + - net: ena: set initial DMA width to avoid intel iommu issue + - ibmvnic: fix NULL pointer dereference in reset_sub_crq_queues + - ibmvnic: fix NULL pointer dereference in ibmvic_reset_crq + - optee: add writeback to valid memory type + - arm64: tegra: Wrong AON HSP reg property size + - efivarfs: revert "fix memory leak in efivarfs_create()" + - efi: EFI_EARLYCON should depend on EFI + - can: gs_usb: fix endianess problem with candleLight firmware + - platform/x86: thinkpad_acpi: Send tablet mode switch at wakeup time + - platform/x86: toshiba_acpi: Fix the wrong variable assignment + - RDMA/hns: Fix retry_cnt and rnr_cnt when querying QP + - RDMA/hns: Bugfix for memory window mtpt configuration + - can: m_can: m_can_open(): remove IRQF_TRIGGER_FALLING from + request_threaded_irq()'s flags + - can: m_can: fix nominal bitiming tseg2 min for version >= 3.1 + - perf stat: Use proper cpu for shadow stats + - perf probe: Fix to die_entrypc() returns error correctly + - spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe + - USB: core: Change %pK for __user pointers to %px + - usb: gadget: f_midi: Fix memleak in f_midi_alloc + - USB: quirks: Add USB_QUIRK_DISCONNECT_SUSPEND quirk for Lenovo A630Z TIO + built-in usb-audio card + - usb: gadget: Fix memleak in gadgetfs_fill_super + - irqchip/exiu: Fix the index of fwspec for IRQ type + - x86/mce: Do not overwrite no_way_out if mce_end() fails + - x86/speculation: Fix prctl() when spectre_v2_user={seccomp,prctl},ibpb + - x86/resctrl: Remove superfluous kernfs_get() calls to prevent refcount leak + - x86/resctrl: Add necessary kernfs_put() calls to prevent refcount leak + - USB: core: Fix regression in Hercules audio card + - ASoC: Intel: Skylake: Remove superfluous chip initialization + - ASoC: Intel: Skylake: Select hda configuration permissively + - ASoC: Intel: Skylake: Enable codec wakeup during chip init + - ASoC: Intel: Skylake: Shield against no-NHLT configurations + - ASoC: Intel: Allow for ROM init retry on CNL platforms + - ASoC: Intel: Skylake: Await purge request ack on CNL + - ASoC: Intel: Multiple I/O PCM format support for pipe + - ASoC: Intel: Skylake: Automatic DMIC format configuration according to + information from NHLT + - Linux 5.4.81 + * Focal update: v5.4.80 upstream stable release (LP: #1908561) + - ah6: fix error return code in ah6_input() + - atm: nicstar: Unmap DMA on send error + - bnxt_en: read EEPROM A2h address using page 0 + - devlink: Add missing genlmsg_cancel() in devlink_nl_sb_port_pool_fill() + - Exempt multicast addresses from five-second neighbor lifetime + - inet_diag: Fix error path to cancel the meseage in inet_req_diag_fill() + - ipv6: Fix error path to cancel the meseage + - lan743x: fix issue causing intermittent kernel log warnings + - lan743x: prevent entire kernel HANG on open, for some platforms + - mlxsw: core: Use variable timeout for EMAD retries + - net: b44: fix error return code in b44_init_one() + - net: bridge: add missing counters to ndo_get_stats64 callback + - net: dsa: mv88e6xxx: Avoid VTU corruption on 6097 + - net: ethernet: ti: cpsw: fix error return code in cpsw_probe() + - net: Have netpoll bring-up DSA management interface + - netlabel: fix our progress tracking in netlbl_unlabel_staticlist() + - netlabel: fix an uninitialized warning in netlbl_unlabel_staticlist() + - net: lantiq: Wait for the GPHY firmware to be ready + - net/mlx4_core: Fix init_hca fields offset + - net: qualcomm: rmnet: Fix incorrect receive packet handling during cleanup + - net/smc: fix direct access to ib_gid_addr->ndev in smc_ib_determine_gid() + - net/tls: fix corrupted data in recvmsg + - net: x25: Increase refcnt of "struct x25_neigh" in x25_rx_call_request + - page_frag: Recover from memory pressure + - qed: fix error return code in qed_iwarp_ll2_start() + - qlcnic: fix error return code in qlcnic_83xx_restart_hw() + - sctp: change to hold/put transport for proto_unreach_timer + - tcp: only postpone PROBE_RTT if RTT is < current min_rtt estimate + - net/mlx5: Add handling of port type in rule deletion + - net/mlx5: Disable QoS when min_rates on all VFs are zero + - net: usb: qmi_wwan: Set DTR quirk for MR400 + - net/ncsi: Fix netlink registration + - net: ftgmac100: Fix crash when removing driver + - pinctrl: rockchip: enable gpio pclk for rockchip_gpio_to_irq + - scsi: ufs: Fix unbalanced scsi_block_reqs_cnt caused by ufshcd_hold() + - selftests: kvm: Fix the segment descriptor layout to match the actual layout + - ACPI: button: Add DMI quirk for Medion Akoya E2228T + - arm64: errata: Fix handling of 1418040 with late CPU onlining + - arm64: psci: Avoid printing in cpu_psci_cpu_die() + - arm64: smp: Tell RCU about CPUs that fail to come online + - vfs: remove lockdep bogosity in __sb_start_write + - gfs2: fix possible reference leak in gfs2_check_blk_type + - hwmon: (pwm-fan) Fix RPM calculation + - arm64: dts: allwinner: beelink-gs1: Enable both RGMII RX/TX delay + - arm64: dts: allwinner: Pine H64: Enable both RGMII RX/TX delay + - arm64: dts: allwinner: a64: OrangePi Win: Fix ethernet node + - arm64: dts: allwinner: a64: Pine64 Plus: Fix ethernet node + - arm64: dts: allwinner: h5: OrangePi PC2: Fix ethernet node + - ARM: dts: sun8i: r40: bananapi-m2-ultra: Fix ethernet node + - Revert "arm: sun8i: orangepi-pc-plus: Set EMAC activity LEDs to active high" + - ARM: dts: sun6i: a31-hummingbird: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun7i: cubietruck: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun7i: bananapi-m1-plus: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun8i: h3: orangepi-plus2e: Enable RGMII RX/TX delay on Ethernet + PHY + - ARM: dts: sun8i: a83t: Enable both RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun9i: Enable both RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sunxi: bananapi-m2-plus: Enable RGMII RX/TX delay on Ethernet PHY + - arm64: dts: allwinner: a64: bananapi-m64: Enable RGMII RX/TX delay on PHY + - Input: adxl34x - clean up a data type in adxl34x_probe() + - MIPS: export has_transparent_hugepage() for modules + - arm64: dts: allwinner: h5: OrangePi Prime: Fix ethernet node + - arm64: dts imx8mn: Remove non-existent USB OTG2 + - arm: dts: imx6qdl-udoo: fix rgmii phy-mode for ksz9031 phy + - swiotlb: using SIZE_MAX needs limits.h included + - arm64: dts: imx8mm: fix voltage for 1.6GHz CPU operating point + - ARM: dts: imx50-evk: Fix the chip select 1 IOMUX + - Input: resistive-adc-touch - fix kconfig dependency on IIO_BUFFER + - rfkill: Fix use-after-free in rfkill_resume() + - RDMA/pvrdma: Fix missing kfree() in pvrdma_register_device() + - [Config] updateconfigs for INFINIBAND_VIRT_DMA + - RMDA/sw: Don't allow drivers using dma_virt_ops on highmem configs + - perf lock: Don't free "lock_seq_stat" if read_count isn't zero + - tools, bpftool: Add missing close before bpftool net attach exit + - ip_tunnels: Set tunnel option flag when tunnel metadata is present + - can: af_can: prevent potential access of uninitialized member in can_rcv() + - can: af_can: prevent potential access of uninitialized member in canfd_rcv() + - can: dev: can_restart(): post buffer from the right context + - can: ti_hecc: Fix memleak in ti_hecc_probe + - can: mcba_usb: mcba_usb_start_xmit(): first fill skb, then pass to + can_put_echo_skb() + - can: peak_usb: fix potential integer overflow on shift of a int + - can: flexcan: fix failure handling of pm_runtime_get_sync() + - can: tcan4x5x: replace depends on REGMAP_SPI with depends on SPI + - can: tcan4x5x: tcan4x5x_can_probe(): add missing error checking for + devm_regmap_init() + - can: tcan4x5x: tcan4x5x_can_remove(): fix order of deregistration + - can: m_can: m_can_handle_state_change(): fix state change + - can: m_can: m_can_class_free_dev(): introduce new function + - can: m_can: m_can_stop(): set device to software init mode before closing + - ASoC: qcom: lpass-platform: Fix memory leak + - selftests/bpf: Fix error return code in run_getsockopt_test() + - MIPS: Alchemy: Fix memleak in alchemy_clk_setup_cpu + - drm/sun4i: dw-hdmi: fix error return code in sun8i_dw_hdmi_bind() + - net/mlx5: E-Switch, Fail mlx5_esw_modify_vport_rate if qos disabled + - bpf, sockmap: Fix partial copy_page_to_iter so progress can still be made + - bpf, sockmap: Ensure SO_RCVBUF memory is observed on ingress redirect + - can: kvaser_pciefd: Fix KCAN bittiming limits + - can: kvaser_usb: kvaser_usb_hydra: Fix KCAN bittiming limits + - iommu/vt-d: Move intel_iommu_gfx_mapped to Intel IOMMU header + - iommu/vt-d: Avoid panic if iommu init fails in tboot system + - can: flexcan: flexcan_chip_start(): fix erroneous + flexcan_transceiver_enable() during bus-off recovery + - can: m_can: process interrupt only when not runtime suspended + - xfs: fix the minrecs logic when dealing with inode root child blocks + - xfs: strengthen rmap record flags checking + - xfs: return corresponding errcode if xfs_initialize_perag() fail + - regulator: ti-abb: Fix array out of bound read access on the first + transition + - fail_function: Remove a redundant mutex unlock + - xfs: revert "xfs: fix rmap key and record comparison functions" + - bpf, sockmap: Skb verdict SK_PASS to self already checked rmem limits + - bpf, sockmap: On receive programs try to fast track SK_PASS ingress + - bpf, sockmap: Use truesize with sk_rmem_schedule() + - bpf, sockmap: Avoid returning unneeded EAGAIN when redirecting to self + - efi/x86: Free efi_pgd with free_pages() + - libfs: fix error cast of negative value in simple_attr_write() + - HID: logitech-hidpp: Add PID for MX Anywhere 2 + - HID: logitech-dj: Handle quad/bluetooth keyboards with a builtin trackpad + - HID: logitech-dj: Fix Dinovo Mini when paired with a MX5x00 receiver + - speakup: Do not let the line discipline be used several times + - ALSA: firewire: Clean up a locking issue in copy_resp_to_buf() + - ALSA: usb-audio: Add delay quirk for all Logitech USB devices + - ALSA: ctl: fix error path at adding user-defined element set + - ALSA: mixart: Fix mutex deadlock + - ALSA: hda/realtek - Add supported for Lenovo ThinkPad Headset Button + - ALSA: hda/realtek: Add some Clove SSID in the ALC293(ALC1220) + - tty: serial: imx: fix potential deadlock + - tty: serial: imx: keep console clocks always on + - HID: logitech-dj: Fix an error in mse_bluetooth_descriptor + - efivarfs: fix memory leak in efivarfs_create() + - staging: rtl8723bs: Add 024c:0627 to the list of SDIO device-ids + - iio: light: fix kconfig dependency bug for VCNL4035 + - ext4: fix bogus warning in ext4_update_dx_flag() + - iio: accel: kxcjk1013: Replace is_smo8500_device with an acpi_type enum + - iio: accel: kxcjk1013: Add support for KIOX010A ACPI DSM for setting tablet- + mode + - iio: adc: mediatek: fix unset field + - spi: lpspi: Fix use-after-free on unbind + - spi: Introduce device-managed SPI controller allocation + - spi: npcm-fiu: Don't leak SPI master in probe error path + - spi: bcm2835aux: Fix use-after-free on unbind + - regulator: pfuze100: limit pfuze-support-disable-sw to pfuze{100,200} + - regulator: fix memory leak with repeated set_machine_constraints() + - regulator: avoid resolve_supply() infinite recursion + - regulator: workaround self-referent regulators + - xtensa: fix TLBTEMP area placement + - xtensa: disable preemption around cache alias management calls + - mac80211: minstrel: remove deferred sampling code + - mac80211: minstrel: fix tx status processing corner case + - mac80211: free sta in sta_info_insert_finish() on errors + - s390/cpum_sf.c: fix file permission for cpum_sfb_size + - s390/dasd: fix null pointer dereference for ERP requests + - Drivers: hv: vmbus: Allow cleanup of VMBUS_CONNECT_CPU if disconnected + - drm/amd/display: Add missing pflip irq for dcn2.0 + - drm/i915: Handle max_bpc==16 + - mmc: sdhci-pci: Prefer SDR25 timing for High Speed mode for BYT-based Intel + controllers + - ptrace: Set PF_SUPERPRIV when checking capability + - seccomp: Set PF_SUPERPRIV when checking capability + - x86/microcode/intel: Check patch signature before saving microcode for early + loading + - mm: memcg/slab: fix root memcg vmstats + - mm/userfaultfd: do not access vma->vm_mm after calling handle_userfault() + - mm, page_alloc: skip ->waternark_boost for atomic order-0 allocations + - sched/fair: Fix overutilized update in enqueue_task_fair() + - Linux 5.4.80 + * [SRU][F/G/H/U/OEM-5.6] Fix i2c report error on elan trackpoint + (LP: #1908335) + - Input: elan_i2c - add support for high resolution reports + - Input: elan_i2c - add new trackpoint report type 0x5F + - Input: elantech - fix protocol errors for some trackpoints in SMBus mode + * rtwpci driver blocks the system to enter PC10, stuck at PC3 (LP: #1907200) + - SAUCE: rtw88: 8723de: let cpu enter c10 + * [UBUNTU 21.04] s390/pci: vfio-pci mmio being disabled erroneously + (LP: #1907265) + - s390/pci: Mark all VFs as not implementing PCI_COMMAND_MEMORY + * Touchpad not detected on ByteSpeed C15B laptop (LP: #1906128) + - Input: i8042 - add ByteSpeed touchpad to noloop table + * Fix reading speed and duplex sysfs on igc device (LP: #1906851) + - SAUCE: igc: Report speed and duplex as unknown when device is runtime + suspended + * stack trace in kernel (LP: #1903596) + - net: napi: remove useless stack trace + * Refresh ACPI wakeup power to make Thunderbolt hotplug detection work + (LP: #1906229) + - PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup() + - PM: ACPI: Refresh wakeup device power configuration every time + * CVE-2020-27777 + - [Config]: Set CONFIG_PPC_RTAS_FILTER + * Add dpcd backlight control for 0x4c83 0x4f41 (LP: #1905663) + - SAUCE: drm/dp: Add dpcd backlight control for 0x4c83 0x4f41 + * Focal update: v5.4.79 upstream stable release (LP: #1907151) + - powerpc: Only include kup-radix.h for 64-bit Book3S + - MIPS: PCI: Fix MIPS build + - powerpc/8xx: Always fault when _PAGE_ACCESSED is not set + - net: lantiq: Add locking for TX DMA channel + - Input: sunkbd - avoid use-after-free in teardown paths + - mac80211: always wind down STA state + - can: proc: can_remove_proc(): silence remove_proc_entry warning + - KVM: x86: clflushopt should be treated as a no-op by emulation + - ACPI: GED: fix -Wformat + - Linux 5.4.79 + + [ Ubuntu: 5.4.0-65.73 ] + + * focal/linux: 5.4.0-65.73 -proposed tracker (LP: #1912220) + * initramfs unpacking failed (LP: #1835660) + - SAUCE: lib/decompress_unlz4.c: correctly handle zero-padding around initrds. + + [ Ubuntu: 5.4.0-64.72 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Fri, 05 Feb 2021 15:35:18 +0100 + +linux-oracle (5.4.0-1037.40) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1037.40 -proposed tracker (LP: #1911328) + + [ Ubuntu: 5.4.0-63.71 ] + + * focal/linux: 5.4.0-63.71 -proposed tracker (LP: #1911333) + * overlay: permission regression in 5.4.0-51.56 due to patches related to + CVE-2020-16120 (LP: #1900141) + - ovl: do not fail because of O_NOATIME + * Focal update: v5.4.79 upstream stable release (LP: #1907151) + - net/mlx5: Use async EQ setup cleanup helpers for multiple EQs + - net/mlx5: poll cmd EQ in case of command timeout + - net/mlx5: Fix a race when moving command interface to events mode + - net/mlx5: Add retry mechanism to the command entry index allocation + * Kernel 5.4.0-56 Wi-Fi does not connect (LP: #1906770) + - mt76: fix fix ampdu locking + * [Ubuntu 21.04 FEAT] mpt3sas: Request to include the patch set which supports + topology where zoning is enabled in expander (LP: #1899802) + - scsi: mpt3sas: Define hba_port structure + - scsi: mpt3sas: Allocate memory for hba_port objects + - scsi: mpt3sas: Rearrange _scsih_mark_responding_sas_device() + - scsi: mpt3sas: Update hba_port's sas_address & phy_mask + - scsi: mpt3sas: Get device objects using sas_address & portID + - scsi: mpt3sas: Rename transport_del_phy_from_an_existing_port() + - scsi: mpt3sas: Get sas_device objects using device's rphy + - scsi: mpt3sas: Update hba_port objects after host reset + - scsi: mpt3sas: Set valid PhysicalPort in SMPPassThrough + - scsi: mpt3sas: Handling HBA vSES device + - scsi: mpt3sas: Add bypass_dirty_port_flag parameter + - scsi: mpt3sas: Handle vSES vphy object during HBA reset + - scsi: mpt3sas: Add module parameter multipath_on_hba + - scsi: mpt3sas: Bump driver version to 35.101.00.00 + + [ Ubuntu: 5.4.0-62.70 ] + + * focal/linux: 5.4.0-62.70 -proposed tracker (LP: #1911144) + * CVE-2020-28374 + - SAUCE: target: fix XCOPY NAA identifier lookup + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- William Breathitt Gray Thu, 14 Jan 2021 03:13:44 -0500 + +linux-oracle (5.4.0-1035.38) focal; urgency=medium + + [ Ubuntu: 5.4.0-60.67 ] + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - update dkms package versions + * CVE-2021-1052 // CVE-2021-1053 + - [Packaging] NVIDIA -- Add the NVIDIA 460 driver + + -- Thadeu Lima de Souza Cascardo Wed, 06 Jan 2021 16:30:54 -0300 + +linux-oracle (5.4.0-1034.36) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1033.35 -proposed tracker (LP: #1907600) + + [ Ubuntu: 5.4.0-59.65 ] + + * focal/linux: 5.4.0-59.65 -proposed tracker (LP: #1907604) + * focal: selftests/bpf build broken: test_map_init.skel.h: No such file or + directory (LP: #1906866) + - SAUCE: Revert selftests/ "bpf: Zero-fill re-used per-cpu map element" + * Packaging resync (LP: #1786013) + - update dkms package versions + * memory is leaked when tasks are moved to net_prio (LP: #1886859) + - netprio_cgroup: Fix unlimited memory leak of v2 cgroups + * Focal update: v5.4.78 upstream stable release (LP: #1905618) + - drm/i915/gem: Flush coherency domains on first set-domain-ioctl + - time: Prevent undefined behaviour in timespec64_to_ns() + - nbd: don't update block size after device is started + - KVM: arm64: Force PTE mapping on fault resulting in a device mapping + - PCI: qcom: Make sure PCIe is reset before init for rev 2.1.0 + - usb: dwc3: gadget: Continue to process pending requests + - usb: dwc3: gadget: Reclaim extra TRBs after request completion + - btrfs: tracepoints: output proper root owner for trace_find_free_extent() + - btrfs: sysfs: init devices outside of the chunk_mutex + - btrfs: reschedule when cloning lots of extents + - ASoC: Intel: kbl_rt5663_max98927: Fix kabylake_ssp_fixup function + - genirq: Let GENERIC_IRQ_IPI select IRQ_DOMAIN_HIERARCHY + - hv_balloon: disable warning when floor reached + - net: xfrm: fix a race condition during allocing spi + - ASoC: codecs: wcd9335: Set digital gain range correctly + - xfs: set xefi_discard when creating a deferred agfl free log intent item + - netfilter: use actual socket sk rather than skb sk when routing harder + - netfilter: nf_tables: missing validation from the abort path + - netfilter: ipset: Update byte and packet counters regardless of whether they + match + - powerpc/eeh_cache: Fix a possible debugfs deadlock + - perf trace: Fix segfault when trying to trace events by cgroup + - perf tools: Add missing swap for ino_generation + - ALSA: hda: prevent undefined shift in snd_hdac_ext_bus_get_link() + - iommu/vt-d: Fix a bug for PDP check in prq_event_thread + - afs: Fix warning due to unadvanced marshalling pointer + - can: rx-offload: don't call kfree_skb() from IRQ context + - can: dev: can_get_echo_skb(): prevent call to kfree_skb() in hard IRQ + context + - can: dev: __can_get_echo_skb(): fix real payload length return value for RTR + frames + - can: can_create_echo_skb(): fix echo skb generation: always use skb_clone() + - can: j1939: swap addr and pgn in the send example + - can: j1939: j1939_sk_bind(): return failure if netdev is down + - can: ti_hecc: ti_hecc_probe(): add missed clk_disable_unprepare() in error + path + - can: xilinx_can: handle failure cases of pm_runtime_get_sync + - can: peak_usb: add range checking in decode operations + - can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping + - can: peak_canfd: pucan_handle_can_rx(): fix echo management when loopback is + on + - can: flexcan: remove FLEXCAN_QUIRK_DISABLE_MECR quirk for LS1021A + - can: flexcan: flexcan_remove(): disable wakeup completely + - xfs: flush new eof page on truncate to avoid post-eof corruption + - xfs: fix scrub flagging rtinherit even if there is no rt device + - tpm: efi: Don't create binary_bios_measurements file for an empty log + - random32: make prandom_u32() output unpredictable + - KVM: arm64: ARM_SMCCC_ARCH_WORKAROUND_1 doesn't return + SMCCC_RET_NOT_REQUIRED + - KVM: x86: don't expose MSR_IA32_UMWAIT_CONTROL unconditionally + - ath9k_htc: Use appropriate rs_datalen type + - ASoC: qcom: sdm845: set driver name correctly + - ASoC: cs42l51: manage mclk shutdown delay + - usb: dwc3: pci: add support for the Intel Alder Lake-S + - opp: Reduce the size of critical section in _opp_table_kref_release() + - usb: gadget: goku_udc: fix potential crashes in probe + - selftests/ftrace: check for do_sys_openat2 in user-memory test + - selftests: pidfd: fix compilation errors due to wait.h + - ALSA: hda: Separate runtime and system suspend + - ALSA: hda: Reinstate runtime_allow() for all hda controllers + - gfs2: Free rd_bits later in gfs2_clear_rgrpd to fix use-after-free + - gfs2: Add missing truncate_inode_pages_final for sd_aspace + - gfs2: check for live vs. read-only file system in gfs2_fitrim + - scsi: hpsa: Fix memory leak in hpsa_init_one() + - drm/amdgpu: perform srbm soft reset always on SDMA resume + - drm/amd/pm: perform SMC reset on suspend/hibernation + - drm/amd/pm: do not use ixFEATURE_STATUS for checking smc running + - mac80211: fix use of skb payload instead of header + - cfg80211: initialize wdev data earlier + - cfg80211: regulatory: Fix inconsistent format argument + - tracing: Fix the checking of stackidx in __ftrace_trace_stack + - scsi: scsi_dh_alua: Avoid crash during alua_bus_detach() + - scsi: mpt3sas: Fix timeouts observed while reenabling IRQ + - nvme: introduce nvme_sync_io_queues + - nvme-rdma: avoid race between time out and tear down + - nvme-tcp: avoid race between time out and tear down + - nvme-rdma: avoid repeated request completion + - nvme-tcp: avoid repeated request completion + - iommu/amd: Increase interrupt remapping table limit to 512 entries + - s390/smp: move rcu_cpu_starting() earlier + - vfio: platform: fix reference leak in vfio_platform_open + - vfio/pci: Bypass IGD init in case of -ENODEV + - i2c: mediatek: move dma reset before i2c reset + - amd/amdgpu: Disable VCN DPG mode for Picasso + - selftests: proc: fix warning: _GNU_SOURCE redefined + - riscv: Set text_offset correctly for M-Mode + - i2c: sh_mobile: implement atomic transfers + - tpm_tis: Disable interrupts on ThinkPad T490s + - spi: bcm2835: remove use of uninitialized gpio flags variable + - tick/common: Touch watchdog in tick_unfreeze() on all CPUs + - mfd: sprd: Add wakeup capability for PMIC IRQ + - pinctrl: intel: Set default bias in case no particular value given + - ARM: 9019/1: kprobes: Avoid fortify_panic() when copying optprobe template + - bpf: Don't rely on GCC __attribute__((optimize)) to disable GCSE + - pinctrl: aspeed: Fix GPI only function problem. + - net/mlx5: Fix deletion of duplicate rules + - SUNRPC: Fix general protection fault in trace_rpc_xdr_overflow() + - bpf: Zero-fill re-used per-cpu map element + - nbd: fix a block_device refcount leak in nbd_release + - igc: Fix returning wrong statistics + - xfs: fix flags argument to rmap lookup when converting shared file rmaps + - xfs: set the unwritten bit in rmap lookup flags in xchk_bmap_get_rmapextents + - xfs: fix rmap key and record comparison functions + - xfs: fix brainos in the refcount scrubber's rmap fragment processor + - lan743x: fix "BUG: invalid wait context" when setting rx mode + - xfs: fix a missing unlock on error in xfs_fs_map_blocks + - of/address: Fix of_node memory leak in of_dma_is_coherent + - cosa: Add missing kfree in error path of cosa_write + - vrf: Fix fast path output packet handling with async Netfilter rules + - perf: Fix get_recursion_context() + - erofs: derive atime instead of leaving it empty + - ext4: correctly report "not supported" for {usr,grp}jquota when + !CONFIG_QUOTA + - ext4: unlock xattr_sem properly in ext4_inline_data_truncate() + - btrfs: ref-verify: fix memory leak in btrfs_ref_tree_mod + - btrfs: fix min reserved size calculation in merge_reloc_root + - btrfs: dev-replace: fail mount if we don't have replace item with target + device + - KVM: arm64: Don't hide ID registers from userspace + - thunderbolt: Fix memory leak if ida_simple_get() fails in + enumerate_services() + - thunderbolt: Add the missed ida_simple_remove() in ring_request_msix() + - uio: Fix use-after-free in uio_unregister_device() + - usb: cdc-acm: Add DISABLE_ECHO for Renesas USB Download mode + - xhci: hisilicon: fix refercence leak in xhci_histb_probe + - virtio: virtio_console: fix DMA memory allocation for rproc serial + - mei: protect mei_cl_mtu from null dereference + - futex: Don't enable IRQs unconditionally in put_pi_state() + - jbd2: fix up sparse warnings in checkpoint code + - mm/slub: fix panic in slab_alloc_node() + - Revert "kernel/reboot.c: convert simple_strtoul to kstrtoint" + - reboot: fix overflow parsing reboot cpu number + - ocfs2: initialize ip_next_orphan + - btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch + - selinux: Fix error return code in sel_ib_pkey_sid_slow() + - gpio: pcie-idio-24: Fix irq mask when masking + - gpio: pcie-idio-24: Fix IRQ Enable Register value + - gpio: pcie-idio-24: Enable PEX8311 interrupts + - mmc: sdhci-of-esdhc: Handle pulse width detection erratum for more SoCs + - mmc: renesas_sdhi_core: Add missing tmio_mmc_host_free() at remove + - don't dump the threads that had been already exiting when zapped. + - drm/gma500: Fix out-of-bounds access to struct drm_device.vblank[] + - pinctrl: amd: use higher precision for 512 RtcClk + - pinctrl: amd: fix incorrect way to disable debounce filter + - swiotlb: fix "x86: Don't panic if can not alloc buffer for swiotlb" + - IPv6: Set SIT tunnel hard_header_len to zero + - net/af_iucv: fix null pointer dereference on shutdown + - net: udp: fix UDP header access on Fast/frag0 UDP GRO + - net: Update window_clamp if SOCK_RCVBUF is set + - net/x25: Fix null-ptr-deref in x25_connect + - tipc: fix memory leak in tipc_topsrv_start() + - r8169: fix potential skb double free in an error path + - drm/i915: Correctly set SFC capability for video engines + - powerpc/603: Always fault when _PAGE_ACCESSED is not set + - x86/speculation: Allow IBPB to be conditionally enabled on CPUs with always- + on STIBP + - perf scripting python: Avoid declaring function pointers with a visibility + attribute + - net: sch_generic: fix the missing new qdisc assignment bug + - Convert trailing spaces and periods in path components + - Linux 5.4.78 + * Focal update: v5.4.77 upstream stable release (LP: #1905614) + - Linux 5.4.77 + * Focal update: v5.4.76 upstream stable release (LP: #1905612) + - drm/i915: Break up error capture compression loops with cond_resched() + - drm/i915/gt: Delay execlist processing for tgl + - drm/i915: Drop runtime-pm assert from vgpu io accessors + - ASoC: Intel: Skylake: Add alternative topology binary name + - update dkms package versions + - linkage: Introduce new macros for assembler symbols + - arm64: asm: Add new-style position independent function annotations + - arm64: lib: Use modern annotations for assembly functions + - arm64: Change .weak to SYM_FUNC_START_WEAK_PI for arch/arm64/lib/mem*.S + - tipc: fix use-after-free in tipc_bcast_get_mode + - ptrace: fix task_join_group_stop() for the case when current is traced + - cadence: force nonlinear buffers to be cloned + - chelsio/chtls: fix memory leaks caused by a race + - chelsio/chtls: fix always leaking ctrl_skb + - gianfar: Replace skb_realloc_headroom with skb_cow_head for PTP + - gianfar: Account for Tx PTP timestamp in the skb headroom + - ionic: check port ptr before use + - ip_tunnel: fix over-mtu packet send fail without TUNNEL_DONT_FRAGMENT flags + - net: usb: qmi_wwan: add Telit LE910Cx 0x1230 composition + - powerpc/vnic: Extend "failover pending" window + - sctp: Fix COMM_LOST/CANT_STR_ASSOC err reporting on big-endian platforms + - sfp: Fix error handing in sfp_probe() + - Fonts: Replace discarded const qualifier + - ALSA: hda/realtek - Fixed HP headset Mic can't be detected + - ALSA: hda/realtek - Enable headphone for ASUS TM420 + - ALSA: usb-audio: Add implicit feedback quirk for Zoom UAC-2 + - ALSA: usb-audio: add usb vendor id as DSD-capable for Khadas devices + - ALSA: usb-audio: Add implicit feedback quirk for Qu-16 + - ALSA: usb-audio: Add implicit feedback quirk for MODX + - mm: mempolicy: fix potential pte_unmap_unlock pte error + - lib/crc32test: remove extra local_irq_disable/enable + - kthread_worker: prevent queuing delayed work from timer_fn when it is being + canceled + - mm: always have io_remap_pfn_range() set pgprot_decrypted() + - gfs2: Wake up when sd_glock_disposal becomes zero + - ring-buffer: Fix recursion protection transitions between interrupt context + - mtd: spi-nor: Don't copy self-pointing struct around + - ftrace: Fix recursion check for NMI test + - ftrace: Handle tracing when switching between context + - regulator: defer probe when trying to get voltage from unresolved supply + - spi: bcm2835: fix gpio cs level inversion + - tracing: Fix out of bounds write in get_trace_buf + - futex: Handle transient "ownerless" rtmutex state correctly + - ARM: dts: sun4i-a10: fix cpu_alert temperature + - arm64: dts: meson: add missing g12 rng clock + - x86/kexec: Use up-to-dated screen_info copy to fill boot params + - of: Fix reserved-memory overlap detection + - drm/sun4i: frontend: Rework a bit the phase data + - drm/sun4i: frontend: Reuse the ch0 phase for RGB formats + - drm/sun4i: frontend: Fix the scaler phase on A33 + - blk-cgroup: Fix memleak on error path + - blk-cgroup: Pre-allocate tree node on blkg_conf_prep + - scsi: core: Don't start concurrent async scan on same host + - drm/amdgpu: add DID for navi10 blockchain SKU + - scsi: ibmvscsi: Fix potential race after loss of transport + - vsock: use ns_capable_noaudit() on socket create + - nvme-rdma: handle unexpected nvme completion data length + - nvmet: fix a NULL pointer dereference when tracing the flush command + - drm/vc4: drv: Add error handding for bind + - ACPI: NFIT: Fix comparison to '-ENXIO' + - usb: cdns3: gadget: suspicious implicit sign extension + - drm/nouveau/nouveau: fix the start/end range for migration + - drm/nouveau/gem: fix "refcount_t: underflow; use-after-free" + - arm64/smp: Move rcu_cpu_starting() earlier + - vt: Disable KD_FONT_OP_COPY + - fork: fix copy_process(CLONE_PARENT) race with the exiting ->real_parent + - s390/pkey: fix paes selftest failure with paes and pkey static build + - serial: 8250_mtk: Fix uart_get_baud_rate warning + - serial: txx9: add missing platform_driver_unregister() on error in + serial_txx9_init + - USB: serial: cyberjack: fix write-URB completion race + - USB: serial: option: add Quectel EC200T module support + - USB: serial: option: add LE910Cx compositions 0x1203, 0x1230, 0x1231 + - USB: serial: option: add Telit FN980 composition 0x1055 + - tty: serial: fsl_lpuart: add LS1028A support + - tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A + - usb: dwc3: ep0: Fix delay status handling + - USB: Add NO_LPM quirk for Kingston flash drive + - usb: mtu3: fix panic in mtu3_gadget_stop() + - drm/panfrost: Fix a deadlock between the shrinker and madvise path + - ARC: stack unwinding: avoid indefinite looping + - PM: runtime: Drop runtime PM references to supplier on link removal + - PM: runtime: Drop pm_runtime_clean_up_links() + - PM: runtime: Resume the device earlier in __device_release_driver() + - xfs: flush for older, xfs specific ioctls + - perf/core: Fix a memory leak in perf_event_parse_addr_filter() + - arm64: dts: marvell: espressobin: Add ethernet switch aliases + - Linux 5.4.76 + * s390: dbginfo.sh triggers kernel panic, reading from + /sys/kernel/mm/page_idle/bitmap (LP: #1904884) + - mm/page_idle.c: skip offline pages + * Ask 8821C Bluetooth controller to drop old firmware (LP: #1904221) + - Bluetooth: btrtl: Ask 8821C to drop old firmware + - Bluetooth: btrtl: fix incorrect skb allocation failure check + * Use ACPI S5 for reboot (LP: #1904225) + - PM: ACPI: reboot: Use S5 for reboot + * Focal update: v5.4.75 upstream stable release (LP: #1904450) + - xen/events: avoid removing an event channel while handling it + - xen/events: add a proper barrier to 2-level uevent unmasking + - xen/events: fix race in evtchn_fifo_unmask() + - xen/events: add a new "late EOI" evtchn framework + - xen/blkback: use lateeoi irq binding + - xen/netback: use lateeoi irq binding + - xen/scsiback: use lateeoi irq binding + - xen/pvcallsback: use lateeoi irq binding + - xen/pciback: use lateeoi irq binding + - xen/events: switch user event channels to lateeoi model + - xen/events: use a common cpu hotplug hook for event channels + - xen/events: defer eoi in case of excessive number of events + - xen/events: block rogue events for some time + - firmware: arm_scmi: Fix ARCH_COLD_RESET + - firmware: arm_scmi: Add missing Rx size re-initialisation + - x86/unwind/orc: Fix inactive tasks with stack pointer in %sp on GCC 10 + compiled kernels + - mlxsw: core: Fix use-after-free in mlxsw_emad_trans_finish() + - RDMA/qedr: Fix memory leak in iWARP CM + - ata: sata_nv: Fix retrieving of active qcs + - futex: Fix incorrect should_fail_futex() handling + - powerpc/powernv/smp: Fix spurious DBG() warning + - [Config] update config for ARCH_WANT_IRQS_OFF_ACTIVATE_MM + - mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race + - powerpc: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM + - sparc64: remove mm_cpumask clearing to fix kthread_use_mm race + - f2fs: add trace exit in exception path + - f2fs: fix uninit-value in f2fs_lookup + - f2fs: fix to check segment boundary during SIT page readahead + - s390/startup: avoid save_area_sync overflow + - um: change sigio_spinlock to a mutex + - f2fs: handle errors of f2fs_get_meta_page_nofail + - ARM: 8997/2: hw_breakpoint: Handle inexact watchpoint addresses + - NFS4: Fix oops when copy_file_range is attempted with NFS4.0 source + - power: supply: bq27xxx: report "not charging" on all types + - xfs: fix realtime bitmap/summary file truncation when growing rt volume + - video: fbdev: pvr2fb: initialize variables + - ath10k: start recovery process when payload length exceeds max htc length + for sdio + - ath10k: fix VHT NSS calculation when STBC is enabled + - drm/brige/megachips: Add checking if ge_b850v3_lvds_init() is working + correctly + - selftests/x86/fsgsbase: Reap a forgotten child + - media: videodev2.h: RGB BT2020 and HSV are always full range + - media: platform: Improve queue set up flow for bug fixing + - usb: typec: tcpm: During PR_SWAP, source caps should be sent only after + tSwapSourceStart + - media: tw5864: check status of tw5864_frameinterval_get + - media: imx274: fix frame interval handling + - mmc: via-sdmmc: Fix data race bug + - drm/bridge/synopsys: dsi: add support for non-continuous HS clock + - arm64: topology: Stop using MPIDR for topology information + - printk: reduce LOG_BUF_SHIFT range for H8300 + - ia64: kprobes: Use generic kretprobe trampoline handler + - kgdb: Make "kgdbcon" work properly with "kgdb_earlycon" + - bpf: Permit map_ptr arithmetic with opcode add and offset 0 + - media: uvcvideo: Fix dereference of out-of-bound list iterator + - selftests/bpf: Define string const as global for test_sysctl_prog.c + - samples/bpf: Fix possible deadlock in xdpsock + - riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO + - cpufreq: sti-cpufreq: add stih418 support + - USB: adutux: fix debugging + - uio: free uio id after uio file node is freed + - usb: xhci: omit duplicate actions when suspending a runtime suspended host. + - SUNRPC: Mitigate cond_resched() in xprt_transmit() + - arm64/mm: return cpu_all_mask when node is NUMA_NO_NODE + - can: flexcan: disable clocks during stop mode + - xfs: don't free rt blocks when we're doing a REMAP bunmapi call + - ACPI: Add out of bounds and numa_off protections to pxm_to_node() + - brcmfmac: Fix warning message after dongle setup failed + - drivers/net/wan/hdlc_fr: Correctly handle special skb->protocol values + - bus/fsl_mc: Do not rely on caller to provide non NULL mc_io + - ACPI: HMAT: Fix handling of changes from ACPI 6.2 to ACPI 6.3 + - power: supply: test_power: add missing newlines when printing parameters by + sysfs + - drm/amd/display: HDMI remote sink need mode validation for Linux + - ARC: [dts] fix the errors detected by dtbs_check + - btrfs: fix replace of seed device + - md/bitmap: md_bitmap_get_counter returns wrong blocks + - bnxt_en: Log unknown link speed appropriately. + - rpmsg: glink: Use complete_all for open states + - clk: ti: clockdomain: fix static checker warning + - net: 9p: initialize sun_server.sun_path to have addr's value only when addr + is valid + - drivers: watchdog: rdc321x_wdt: Fix race condition bugs + - ext4: Detect already used quota file early + - KVM: PPC: Book3S HV: Do not allocate HPT for a nested guest + - gfs2: use-after-free in sysfs deregistration + - gfs2: add validation checks for size of superblock + - cifs: handle -EINTR in cifs_setattr + - arm64: dts: renesas: ulcb: add full-pwr-cycle-in-suspend into eMMC nodes + - ARM: dts: omap4: Fix sgx clock rate for 4430 + - memory: emif: Remove bogus debugfs error handling + - ARM: dts: s5pv210: remove DMA controller bus node name to fix dtschema + warnings + - ARM: dts: s5pv210: move fixed clocks under root node + - ARM: dts: s5pv210: move PMU node out of clock controller + - ARM: dts: s5pv210: remove dedicated 'audio-subsystem' node + - nbd: make the config put is called before the notifying the waiter + - sgl_alloc_order: fix memory leak + - nvme-rdma: fix crash when connect rejected + - md/raid5: fix oops during stripe resizing + - mmc: sdhci: Add LTR support for some Intel BYT based controllers + - mmc: sdhci-acpi: AMDI0040: Set SDHCI_QUIRK2_PRESET_VALUE_BROKEN + - seccomp: Make duplicate listener detection non-racy + - selftests/x86/fsgsbase: Test PTRACE_PEEKUSER for GSBASE with invalid LDT GS + - perf/x86/intel: Fix Ice Lake event constraint table + - perf/x86/amd/ibs: Don't include randomized bits in get_ibs_op_count() + - perf/x86/amd/ibs: Fix raw sample data accumulation + - spi: sprd: Release DMA channel also on probe deferral + - extcon: ptn5150: Fix usage of atomic GPIO with sleeping GPIO chips + - leds: bcm6328, bcm6358: use devres LED registering function + - media: uvcvideo: Fix uvc_ctrl_fixup_xu_info() not having any effect + - fs: Don't invalidate page buffers in block_write_full_page() + - NFS: fix nfs_path in case of a rename retry + - ACPI: button: fix handling lid state changes when input device closed + - ACPI / extlog: Check for RDMSR failure + - ACPI: debug: don't allow debugging when ACPI is disabled + - PCI/ACPI: Whitelist hotplug ports for D3 if power managed by ACPI + - ACPI: EC: PM: Flush EC work unconditionally after wakeup + - ACPI: EC: PM: Drop ec_no_wakeup check from acpi_ec_dispatch_gpe() + - acpi-cpufreq: Honor _PSD table setting on new AMD CPUs + - w1: mxc_w1: Fix timeout resolution problem leading to bus error + - scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove() + - scsi: qla2xxx: Fix crash on session cleanup with unload + - PM: runtime: Remove link state checks in rpm_get/put_supplier() + - btrfs: qgroup: fix wrong qgroup metadata reserve for delayed inode + - btrfs: improve device scanning messages + - btrfs: reschedule if necessary when logging directory items + - btrfs: send, orphanize first all conflicting inodes when processing + references + - btrfs: send, recompute reference path after orphanization of a directory + - btrfs: use kvzalloc() to allocate clone_roots in btrfs_ioctl_send() + - btrfs: tree-checker: fix false alert caused by legacy btrfs root item + - btrfs: cleanup cow block on error + - btrfs: tree-checker: validate number of chunk stripes and parity + - btrfs: fix use-after-free on readahead extent after failure to create it + - btrfs: fix readahead hang and use-after-free after removing a device + - Revert "UBUNTU: SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC" + - usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC + - usb: dwc3: pci: Allow Elkhart Lake to utilize DSM method for PM + functionality + - usb: dwc3: ep0: Fix ZLP for OUT ep0 requests + - usb: dwc3: gadget: Check MPS of the request length + - usb: dwc3: core: add phy cleanup for probe error handling + - usb: dwc3: core: don't trigger runtime pm when remove driver + - usb: dwc3: gadget: Resume pending requests after CLEAR_STALL + - usb: dwc3: gadget: END_TRANSFER before CLEAR_STALL command + - usb: cdc-acm: fix cooldown mechanism + - usb: typec: tcpm: reset hard_reset_count for any disconnect + - usb: host: fsl-mph-dr-of: check return of dma_set_mask() + - drm/i915: Force VT'd workarounds when running as a guest OS + - vt: keyboard, simplify vt_kdgkbsent + - vt: keyboard, extend func_buf_lock to readers + - HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery + - udf: Fix memory leak when mounting + - dmaengine: dma-jz4780: Fix race in jz4780_dma_tx_status + - iio:light:si1145: Fix timestamp alignment and prevent data leak. + - iio: adc: gyroadc: fix leak of device node iterator + - iio:adc:ti-adc0832 Fix alignment issue with timestamp + - iio:adc:ti-adc12138 Fix alignment issue with timestamp + - iio:gyro:itg3200: Fix timestamp alignment and prevent data leak. + - powerpc/drmem: Make lmb_size 64 bit + - MIPS: DEC: Restore bootmem reservation for firmware working memory area + - s390/stp: add locking to sysfs functions + - [Config] update config for PPC_RTAS_FILTER + - powerpc/rtas: Restrict RTAS requests from userspace + - powerpc: Warn about use of smt_snooze_delay + - powerpc/memhotplug: Make lmb size 64bit + - powerpc/powernv/elog: Fix race while processing OPAL error log event. + - powerpc/powermac: Fix low_sleep_handler with KUAP and KUEP + - NFSv4: Wait for stateid updates after CLOSE/OPEN_DOWNGRADE + - NFSv4.2: support EXCHGID4_FLAG_SUPP_FENCE_OPS 4.2 EXCHANGE_ID flag + - NFSD: Add missing NFSv2 .pc_func methods + - ubifs: dent: Fix some potential memory leaks while iterating entries + - ubifs: xattr: Fix some potential memory leaks while iterating entries + - ubifs: journal: Make sure to not dirty twice for auth nodes + - ubifs: Fix a memleak after dumping authentication mount options + - ubifs: Don't parse authentication mount options in remount process + - ubifs: mount_ubifs: Release authentication resource in error handling path + - perf python scripting: Fix printable strings in python3 scripts + - ARC: perf: redo the pct irq missing in device-tree handling + - ubi: check kthread_should_stop() after the setting of task state + - ia64: fix build error with !COREDUMP + - rtc: rx8010: don't modify the global rtc ops + - i2c: imx: Fix external abort on interrupt in exit paths + - drm/amdgpu: don't map BO in reserved region + - drm/amd/display: Increase timeout for DP Disable + - drm/amdgpu: correct the gpu reset handling for job != NULL case + - drm/amdkfd: Use same SQ prefetch setting as amdgpu + - drm/amd/display: Avoid MST manager resource leak. + - drm/amdgpu: increase the reserved VM size to 2MB + - drm/amd/display: Don't invoke kgdb_breakpoint() unconditionally + - drm/amd/display: Fix kernel panic by dal_gpio_open() error + - ceph: promote to unsigned long long before shifting + - libceph: clear con->out_msg on Policy::stateful_server faults + - 9P: Cast to loff_t before multiplying + - ring-buffer: Return 0 on success from ring_buffer_resize() + - vringh: fix __vringh_iov() when riov and wiov are different + - ext4: fix leaking sysfs kobject after failed mount + - ext4: fix error handling code in add_new_gdb + - ext4: fix invalid inode checksum + - drm/ttm: fix eviction valuable range check. + - mmc: sdhci-of-esdhc: set timeout to max before tuning + - mmc: sdhci: Use Auto CMD Auto Select only when v4_mode is true + - drm/amd/pm: increase mclk switch threshold to 200 us + - tty: make FONTX ioctl use the tty pointer they were actually passed + - arm64: berlin: Select DW_APB_TIMER_OF + - [Config] update annotations for DW_APB_TIMER + - cachefiles: Handle readpage error correctly + - hil/parisc: Disable HIL driver when it gets stuck + - arm: dts: mt7623: add missing pause for switchport + - ARM: samsung: fix PM debug build with DEBUG_LL but !MMU + - ARM: s3c24xx: fix missing system reset + - device property: Keep secondary firmware node secondary by type + - device property: Don't clear secondary pointer for shared primary firmware + node + - KVM: arm64: Fix AArch32 handling of DBGD{CCINT,SCRext} and DBGVCR + - staging: fieldbus: anybuss: jump to correct label in an error path + - staging: comedi: cb_pcidas: Allow 2-channel commands for AO subdevice + - staging: octeon: repair "fixed-link" support + - staging: octeon: Drop on uncorrectable alignment or FCS error + - Linux 5.4.75 + * [HP 635] Radeon 6310 brightness control does not work (LP: #1894667) // + Focal update: v5.4.75 upstream stable release (LP: #1904450) + - ACPI: video: use ACPI backlight for HP 635 Notebook + * Focal update: v5.4.74 upstream stable release (LP: #1904445) + - netfilter: nftables_offload: KASAN slab-out-of-bounds Read in + nft_flow_rule_create + - socket: don't clear SOCK_TSTAMP_NEW when SO_TIMESTAMPNS is disabled + - objtool: Support Clang non-section symbols in ORC generation + - scripts/setlocalversion: make git describe output more reliable + - arm64: Run ARCH_WORKAROUND_1 enabling code on all CPUs + - arm64: Run ARCH_WORKAROUND_2 enabling code on all CPUs + - arm64: link with -z norelro regardless of CONFIG_RELOCATABLE + - x86/PCI: Fix intel_mid_pci.c build error when ACPI is not enabled + - bnxt_en: Check abort error state in bnxt_open_nic(). + - bnxt_en: Send HWRM_FUNC_RESET fw command unconditionally. + - chelsio/chtls: fix deadlock issue + - chelsio/chtls: fix memory leaks in CPL handlers + - chelsio/chtls: fix tls record info to user + - cxgb4: set up filter action after rewrites + - gtp: fix an use-before-init in gtp_newlink() + - ibmvnic: fix ibmvnic_set_mac + - mlxsw: core: Fix memory leak on module removal + - netem: fix zero division in tabledist + - net/sched: act_mpls: Add softdep on mpls_gso.ko + - r8169: fix issue with forced threading in combination with shared interrupts + - ravb: Fix bit fields checking in ravb_hwtstamp_get() + - tcp: Prevent low rmem stalls with SO_RCVLOWAT. + - tipc: fix memory leak caused by tipc_buf_append() + - net: hns3: Clear the CMDQ registers before unmapping BAR region + - bnxt_en: Re-write PCI BARs after PCI fatal error. + - bnxt_en: Fix regression in workqueue cleanup logic in bnxt_remove_one(). + - bnxt_en: Invoke cancel_delayed_work_sync() for PFs also. + - erofs: avoid duplicated permission check for "trusted." xattrs + - arch/x86/amd/ibs: Fix re-arming IBS Fetch + - x86/xen: disable Firmware First mode for correctable memory errors + - ata: ahci: mvebu: Make SATA PHY optional for Armada 3720 + - fuse: fix page dereference after free + - bpf: Fix comment for helper bpf_current_task_under_cgroup() + - evm: Check size of security.evm before using it + - p54: avoid accessing the data mapped to streaming DMA + - cxl: Rework error message for incompatible slots + - RDMA/addr: Fix race with netevent_callback()/rdma_addr_cancel() + - mtd: lpddr: Fix bad logic in print_drs_error + - serial: qcom_geni_serial: To correct QUP Version detection logic + - serial: pl011: Fix lockdep splat when handling magic-sysrq interrupt + - PM: runtime: Fix timer_expires data type on 32-bit arches + - ata: sata_rcar: Fix DMA boundary mask + - xen/gntdev.c: Mark pages as dirty + - crypto: x86/crc32c - fix building with clang ias + - openrisc: Fix issue with get_user for 64-bit values + - misc: rtsx: do not setting OC_POWER_DOWN reg in rtsx_pci_init_ocp() + - phy: marvell: comphy: Convert internal SMCC firmware return codes to errno + - Linux 5.4.74 + * Bionic: btrfs: kernel BUG at /build/linux- + eTBZpZ/linux-4.15.0/fs/btrfs/ctree.c:3233! (LP: #1902254) + - btrfs: tree-checker: fix incorrect printk format + * NULL pointer dereference when configuring multi-function with devfn != 0 + before devfn == 0 (LP: #1903682) + - s390/pci: fix hot-plug of PCI function missing bus + + -- Ian May Mon, 14 Dec 2020 09:14:09 -0600 + +linux-oracle (5.4.0-1032.34) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1032.34 -proposed tracker (LP: #1907386) + + [ Ubuntu: 5.4.0-58.64 ] + + * focal/linux: 5.4.0-58.64 -proposed tracker (LP: #1907390) + * Packaging resync (LP: #1786013) + - update dkms package versions + * raid10: discard leads to corrupted file system (LP: #1907262) + - Revert "dm raid: remove unnecessary discard limits for raid10" + - Revert "dm raid: fix discard limits for raid1 and raid10" + - Revert "md/raid10: improve discard request for far layout" + - Revert "md/raid10: improve raid10 discard request" + - Revert "md/raid10: pull codes that wait for blocked dev into one function" + - Revert "md/raid10: extend r10bio devs to raid disks" + - Revert "md: add md_submit_discard_bio() for submitting discard bio" + + [ Ubuntu: 5.4.0-56.62 ] + + * focal/linux: 5.4.0-56.62 -proposed tracker (LP: #1905300) + * CVE-2020-4788 + - selftests/powerpc: rfi_flush: disable entry flush if present + - powerpc/64s: flush L1D on kernel entry + - powerpc/64s: flush L1D after user accesses + - selftests/powerpc: entry flush test + + -- Kleber Sacilotto de Souza Wed, 09 Dec 2020 14:52:13 +0100 + +linux-oracle (5.4.0-1030.32) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1030.32 -proposed tracker (LP: #1903170) + + * Focal update: v5.4.66 upstream stable release (LP: #1896824) + - [Config] [oracle] updateconfigs for VGACON_SOFT_SCROLLBACK + + [ Ubuntu: 5.4.0-55.61 ] + + * focal/linux: 5.4.0-55.61 -proposed tracker (LP: #1903175) + * Update kernel packaging to support forward porting kernels (LP: #1902957) + - [Debian] Update for leader included in BACKPORT_SUFFIX + * Avoid double newline when running insertchanges (LP: #1903293) + - [Packaging] insertchanges: avoid double newline + * EFI: Fails when BootCurrent entry does not exist (LP: #1899993) + - efivarfs: Replace invalid slashes with exclamation marks in dentries. + * CVE-2020-14351 + - perf/core: Fix race in the perf_mmap_close() function + * raid10: Block discard is very slow, causing severe delays for mkfs and + fstrim operations (LP: #1896578) + - md: add md_submit_discard_bio() for submitting discard bio + - md/raid10: extend r10bio devs to raid disks + - md/raid10: pull codes that wait for blocked dev into one function + - md/raid10: improve raid10 discard request + - md/raid10: improve discard request for far layout + - dm raid: fix discard limits for raid1 and raid10 + - dm raid: remove unnecessary discard limits for raid10 + * Bionic: btrfs: kernel BUG at /build/linux- + eTBZpZ/linux-4.15.0/fs/btrfs/ctree.c:3233! (LP: #1902254) + - btrfs: drop unnecessary offset_in_page in extent buffer helpers + - btrfs: extent_io: do extra check for extent buffer read write functions + - btrfs: extent-tree: kill BUG_ON() in __btrfs_free_extent() + - btrfs: extent-tree: kill the BUG_ON() in insert_inline_extent_backref() + - btrfs: ctree: check key order before merging tree blocks + * Ethernet no link lights after reboot (Intel i225-v 2.5G) (LP: #1902578) + - igc: Add PHY power management control + * Undetected Data corruption in MPI workloads that use VSX for reductions on + POWER9 DD2.1 systems (LP: #1902694) + - powerpc: Fix undetected data corruption with P9N DD2.1 VSX CI load emulation + - selftests/powerpc: Make alignment handler test P9N DD2.1 vector CI load + workaround + * [20.04 FEAT] Support/enhancement of NVMe IPL (LP: #1902179) + - s390: nvme ipl + - s390: nvme reipl + - s390/ipl: support NVMe IPL kernel parameters + * uvcvideo: add mapping for HEVC payloads (LP: #1895803) + - media: uvcvideo: Add mapping for HEVC payloads + * Focal update: v5.4.73 upstream stable release (LP: #1902115) + - ibmveth: Switch order of ibmveth_helper calls. + - ibmveth: Identify ingress large send packets. + - ipv4: Restore flowi4_oif update before call to xfrm_lookup_route + - mlx4: handle non-napi callers to napi_poll + - net: fec: Fix phy_device lookup for phy_reset_after_clk_enable() + - net: fec: Fix PHY init after phy_reset_after_clk_enable() + - net: fix pos incrementment in ipv6_route_seq_next + - net/smc: fix valid DMBE buffer sizes + - net/tls: sendfile fails with ktls offload + - net: usb: qmi_wwan: add Cellient MPL200 card + - tipc: fix the skb_unshare() in tipc_buf_append() + - socket: fix option SO_TIMESTAMPING_NEW + - can: m_can_platform: don't call m_can_class_suspend in runtime suspend + - can: j1935: j1939_tp_tx_dat_new(): fix missing initialization of skbcnt + - net: j1939: j1939_session_fresh_new(): fix missing initialization of skbcnt + - net/ipv4: always honour route mtu during forwarding + - net_sched: remove a redundant goto chain check + - r8169: fix data corruption issue on RTL8402 + - cxgb4: handle 4-tuple PEDIT to NAT mode translation + - binder: fix UAF when releasing todo list + - ALSA: bebob: potential info leak in hwdep_read() + - ALSA: hda/hdmi: fix incorrect locking in hdmi_pcm_close + - nvme-pci: disable the write zeros command for Intel 600P/P3100 + - chelsio/chtls: fix socket lock + - chelsio/chtls: correct netdevice for vlan interface + - chelsio/chtls: correct function return and return type + - ibmvnic: save changed mac address to adapter->mac_addr + - net: ftgmac100: Fix Aspeed ast2600 TX hang issue + - net: hdlc: In hdlc_rcv, check to make sure dev is an HDLC device + - net: hdlc_raw_eth: Clear the IFF_TX_SKB_SHARING flag after calling + ether_setup + - net: Properly typecast int values to set sk_max_pacing_rate + - net/sched: act_tunnel_key: fix OOB write in case of IPv6 ERSPAN tunnels + - nexthop: Fix performance regression in nexthop deletion + - nfc: Ensure presence of NFC_ATTR_FIRMWARE_NAME attribute in + nfc_genl_fw_download() + - r8169: fix operation under forced interrupt threading + - selftests: forwarding: Add missing 'rp_filter' configuration + - tcp: fix to update snd_wl1 in bulk receiver fast path + - icmp: randomize the global rate limiter + - ALSA: hda/realtek - set mic to auto detect on a HP AIO machine + - ALSA: hda/realtek - Add mute Led support for HP Elitebook 845 G7 + - ALSA: hda/realtek: Enable audio jacks of ASUS D700SA with ALC887 + - cifs: remove bogus debug code + - cifs: Return the error from crypt_message when enc/dec key not found. + - SMB3: Resolve data corruption of TCP server info fields + - KVM: nVMX: Reset the segment cache when stuffing guest segs + - KVM: nVMX: Reload vmcs01 if getting vmcs12's pages fails + - KVM: x86/mmu: Commit zap of remaining invalid pages when recovering lpages + - KVM: SVM: Initialize prev_ga_tag before use + - ima: Don't ignore errors from crypto_shash_update() + - crypto: algif_aead - Do not set MAY_BACKLOG on the async path + - crypto: caam/qi - add fallback for XTS with more than 8B IV + - EDAC/i5100: Fix error handling order in i5100_init_one() + - EDAC/aspeed: Fix handling of platform_get_irq() error + - EDAC/ti: Fix handling of platform_get_irq() error + - perf/x86/intel/ds: Fix x86_pmu_stop warning for large PEBS + - x86/fpu: Allow multiple bits in clearcpuid= parameter + - drivers/perf: xgene_pmu: Fix uninitialized resource struct + - drivers/perf: thunderx2_pmu: Fix memory resource error handling + - sched/fair: Fix wrong cpu selecting from isolated domain + - perf/x86/intel/uncore: Update Ice Lake uncore units + - perf/x86/intel/uncore: Reduce the number of CBOX counters + - x86/nmi: Fix nmi_handle() duration miscalculation + - x86/events/amd/iommu: Fix sizeof mismatch + - crypto: algif_skcipher - EBUSY on aio should be an error + - crypto: mediatek - Fix wrong return value in mtk_desc_ring_alloc() + - crypto: ixp4xx - Fix the size used in a 'dma_free_coherent()' call + - crypto: picoxcell - Fix potential race condition bug + - media: tuner-simple: fix regression in simple_set_radio_freq + - media: Revert "media: exynos4-is: Add missed check for + pinctrl_lookup_state()" + - media: ov5640: Correct Bit Div register in clock tree diagram + - media: m5mols: Check function pointer in m5mols_sensor_power + - media: uvcvideo: Set media controller entity functions + - media: uvcvideo: Silence shift-out-of-bounds warning + - media: staging/intel-ipu3: css: Correctly reset some memory + - media: omap3isp: Fix memleak in isp_probe + - media: i2c: ov5640: Remain in power down for DVP mode unless streaming + - media: i2c: ov5640: Separate out mipi configuration from s_power + - media: i2c: ov5640: Enable data pins on poweron for DVP mode + - media: rcar_drif: Fix fwnode reference leak when parsing DT + - media: rcar_drif: Allocate v4l2_async_subdev dynamically + - media: rcar-csi2: Allocate v4l2_async_subdev dynamically + - crypto: omap-sham - fix digcnt register handling with export/import + - hwmon: (pmbus/max34440) Fix status register reads for MAX344{51,60,61} + - cypto: mediatek - fix leaks in mtk_desc_ring_alloc + - media: mx2_emmaprp: Fix memleak in emmaprp_probe + - media: tc358743: initialize variable + - media: tc358743: cleanup tc358743_cec_isr + - media: rcar-vin: Fix a reference count leak. + - media: rockchip/rga: Fix a reference count leak. + - media: platform: fcp: Fix a reference count leak. + - media: camss: Fix a reference count leak. + - media: s5p-mfc: Fix a reference count leak + - media: stm32-dcmi: Fix a reference count leak + - media: ti-vpe: Fix a missing check and reference count leak + - regulator: resolve supply after creating regulator + - pinctrl: bcm: fix kconfig dependency warning when !GPIOLIB + - spi: spi-s3c64xx: swap s3c64xx_spi_set_cs() and s3c64xx_enable_datapath() + - spi: spi-s3c64xx: Check return values + - blk-mq: move cancel of hctx->run_work to the front of blk_exit_queue + - ath10k: provide survey info as accumulated data + - drm/vkms: fix xrgb on compute crc + - Bluetooth: hci_uart: Cancel init work before unregistering + - drm/amd/display: Fix wrong return value in dm_update_plane_state() + - drm: panel: Fix bus format for OrtusTech COM43H4M85ULC panel + - ath6kl: prevent potential array overflow in ath6kl_add_new_sta() + - ath9k: Fix potential out of bounds in ath9k_htc_txcompletion_cb() + - ath10k: Fix the size used in a 'dma_free_coherent()' call in an error + handling path + - wcn36xx: Fix reported 802.11n rx_highest rate wcn3660/wcn3680 + - ASoC: qcom: lpass-platform: fix memory leak + - ASoC: qcom: lpass-cpu: fix concurrency issue + - brcmfmac: check ndev pointer + - mwifiex: Do not use GFP_KERNEL in atomic context + - staging: rtl8192u: Do not use GFP_KERNEL in atomic context + - drm/gma500: fix error check + - scsi: qla4xxx: Fix an error handling path in 'qla4xxx_get_host_stats()' + - scsi: qla2xxx: Fix wrong return value in qlt_chk_unresolv_exchg() + - scsi: qla2xxx: Fix wrong return value in qla_nvme_register_hba() + - scsi: csiostor: Fix wrong return value in csio_hw_prep_fw() + - backlight: sky81452-backlight: Fix refcount imbalance on error + - staging: emxx_udc: Fix passing of NULL to dma_alloc_coherent() + - VMCI: check return value of get_user_pages_fast() for errors + - mm/error_inject: Fix allow_error_inject function signatures. + - drm: panel: Fix bpc for OrtusTech COM43H4M85ULC panel + - drm/crc-debugfs: Fix memleak in crc_control_write + - binder: Remove bogus warning on failed same-process transaction + - tty: serial: earlycon dependency + - pty: do tty_flip_buffer_push without port->lock in pty_write + - pwm: lpss: Fix off by one error in base_unit math in pwm_lpss_prepare() + - pwm: lpss: Add range limit check for the base_unit register value + - drivers/virt/fsl_hypervisor: Fix error handling path + - video: fbdev: vga16fb: fix setting of pixclock because a pass-by-value error + - video: fbdev: sis: fix null ptr dereference + - video: fbdev: radeon: Fix memleak in radeonfb_pci_register + - ASoC: fsl: imx-es8328: add missing put_device() call in imx_es8328_probe() + - HID: roccat: add bounds checking in kone_sysfs_write_settings() + - drm/msm: Avoid div-by-zero in dpu_crtc_atomic_check() + - drm/panfrost: Ensure GPU quirks are always initialised + - iomap: Clear page error before beginning a write + - pinctrl: mcp23s08: Fix mcp23x17_regmap initialiser + - pinctrl: mcp23s08: Fix mcp23x17 precious range + - net/mlx5: Don't call timecounter cyc2time directly from 1PPS flow + - scsi: mpt3sas: Fix sync irqs + - net: stmmac: use netif_tx_start|stop_all_queues() function + - cpufreq: armada-37xx: Add missing MODULE_DEVICE_TABLE + - drm: mxsfb: check framebuffer pitch + - coresight: etm4x: Handle unreachable sink in perf mode + - xhci: don't create endpoint debugfs entry before ring buffer is set. + - net: dsa: rtl8366: Check validity of passed VLANs + - net: dsa: rtl8366: Refactor VLAN/PVID init + - net: dsa: rtl8366: Skip PVID setting if not requested + - net: wilc1000: clean up resource in error path of init mon interface + - ASoC: tlv320aic32x4: Fix bdiv clock rate derivation + - net: dsa: rtl8366rb: Support all 4096 VLANs + - spi: omap2-mcspi: Improve performance waiting for CHSTAT + - ath6kl: wmi: prevent a shift wrapping bug in ath6kl_wmi_delete_pstream_cmd() + - dmaengine: dmatest: Check list for emptiness before access its last entry + - misc: mic: scif: Fix error handling path + - ALSA: seq: oss: Avoid mutex lock for a long-time ioctl + - usb: dwc2: Fix parameter type in function pointer prototype + - quota: clear padding in v2r1_mem2diskdqb() + - slimbus: core: check get_addr before removing laddr ida + - slimbus: core: do not enter to clock pause mode in core + - slimbus: qcom-ngd-ctrl: disable ngd in qmi server down callback + - ASoC: fsl_sai: Instantiate snd_soc_dai_driver + - HID: hid-input: fix stylus battery reporting + - nvmem: core: fix possibly memleak when use nvmem_cell_info_to_nvmem_cell() + - nl80211: fix OBSS PD min and max offset validation + - coresight: etm: perf: Fix warning caused by etm_setup_aux failure + - ibmvnic: set up 200GBPS speed + - qtnfmac: fix resource leaks on unsupported iftype error return path + - iio: adc: stm32-adc: fix runtime autosuspend delay when slow polling + - net: enic: Cure the enic api locking trainwreck + - mfd: sm501: Fix leaks in probe() + - iwlwifi: mvm: split a print to avoid a WARNING in ROC + - usb: gadget: f_ncm: fix ncm_bitrate for SuperSpeed and above. + - usb: gadget: u_ether: enable qmult on SuperSpeed Plus as well + - nl80211: fix non-split wiphy information + - usb: dwc2: Fix INTR OUT transfers in DDMA mode. + - scsi: target: tcmu: Fix warning: 'page' may be used uninitialized + - scsi: be2iscsi: Fix a theoretical leak in beiscsi_create_eqs() + - ipmi_si: Fix wrong return value in try_smi_init() + - platform/x86: mlx-platform: Remove PSU EEPROM configuration + - mwifiex: fix double free + - ipvs: clear skb->tstamp in forwarding path + - net: korina: fix kfree of rx/tx descriptor array + - netfilter: nf_log: missing vlan offload tag and proto + - mm/swapfile.c: fix potential memory leak in sys_swapon + - mm/memcg: fix device private memcg accounting + - mm, oom_adj: don't loop through tasks in __set_oom_adj when not necessary + - fs: fix NULL dereference due to data race in prepend_path() + - selftests/ftrace: Change synthetic event name for inter-event-combined test + - i3c: master add i3c_master_attach_boardinfo to preserve boardinfo + - IB/mlx4: Fix starvation in paravirt mux/demux + - IB/mlx4: Adjust delayed work when a dup is observed + - powerpc/pseries: Fix missing of_node_put() in rng_init() + - powerpc/icp-hv: Fix missing of_node_put() in success path + - RDMA/ucma: Fix locking for ctx->events_reported + - RDMA/ucma: Add missing locking around rdma_leave_multicast() + - mtd: lpddr: fix excessive stack usage with clang + - RDMA/hns: Add a check for current state before modifying QP + - RDMA/umem: Fix signature of stub ib_umem_find_best_pgsz() + - powerpc/pseries: explicitly reschedule during drmem_lmb list traversal + - pseries/drmem: don't cache node id in drmem_lmb struct + - RDMA/mlx5: Fix potential race between destroy and CQE poll + - mtd: mtdoops: Don't write panic data twice + - ARM: 9007/1: l2c: fix prefetch bits init in L2X0_AUX_CTRL using DT values + - arc: plat-hsdk: fix kconfig dependency warning when !RESET_CONTROLLER + - ida: Free allocated bitmap in error path + - xfs: limit entries returned when counting fsmap records + - xfs: fix deadlock and streamline xfs_getfsmap performance + - xfs: fix high key handling in the rt allocator's query_range function + - RDMA/umem: Fix ib_umem_find_best_pgsz() for mappings that cross a page + boundary + - RDMA/umem: Prevent small pages from being returned by + ib_umem_find_best_pgsz() + - RDMA/qedr: Fix qp structure memory leak + - RDMA/qedr: Fix use of uninitialized field + - RDMA/qedr: Fix return code if accept is called on a destroyed qp + - RDMA/qedr: Fix inline size returned for iWARP + - powerpc/book3s64/hash/4k: Support large linear mapping range with 4K + - powerpc/tau: Use appropriate temperature sample interval + - powerpc/tau: Convert from timer to workqueue + - powerpc/tau: Remove duplicated set_thresholds() call + - powerpc/tau: Check processor type before enabling TAU interrupt + - powerpc/tau: Disable TAU between measurements + - powerpc/64s/radix: Fix mm_cpumask trimming race vs kthread_use_mm + - RDMA/cma: Remove dead code for kernel rdmacm multicast + - RDMA/cma: Consolidate the destruction of a cma_multicast in one place + - perf intel-pt: Fix "context_switch event has no tid" error + - RDMA/hns: Set the unsupported wr opcode + - RDMA/mlx5: Disable IB_DEVICE_MEM_MGT_EXTENSIONS if IB_WR_REG_MR can't work + - i40iw: Add support to make destroy QP synchronous + - perf stat: Skip duration_time in setup_system_wide + - RDMA/hns: Fix the wrong value of rnr_retry when querying qp + - RDMA/hns: Fix missing sq_sig_type when querying QP + - mtd: rawnand: vf610: disable clk on error handling path in probe + - mtd: spinand: gigadevice: Only one dummy byte in QUADIO + - mtd: spinand: gigadevice: Add QE Bit + - kdb: Fix pager search for multi-line strings + - overflow: Include header file with SIZE_MAX declaration + - RDMA/ipoib: Set rtnl_link_ops for ipoib interfaces + - powerpc/perf: Exclude pmc5/6 from the irrelevant PMU group constraints + - powerpc/perf/hv-gpci: Fix starting index value + - i3c: master: Fix error return in cdns_i3c_master_probe() + - cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_reboot_notifier + - IB/rdmavt: Fix sizeof mismatch + - RDMA/rxe: Fix skb lifetime in rxe_rcv_mcast_pkt() + - maiblox: mediatek: Fix handling of platform_get_irq() error + - selftests/powerpc: Fix eeh-basic.sh exit codes + - f2fs: wait for sysfs kobject removal before freeing f2fs_sb_info + - RDMA/rxe: Handle skb_clone() failure in rxe_recv.c + - mm/page_owner: change split_page_owner to take a count + - lib/crc32.c: fix trivial typo in preprocessor condition + - ramfs: fix nommu mmap with gaps in the page cache + - rapidio: fix error handling path + - rapidio: fix the missed put_device() for rio_mport_add_riodev + - mailbox: avoid timer start from callback + - i2c: rcar: Auto select RESET_CONTROLLER + - clk: meson: g12a: mark fclk_div2 as critical + - PCI: aardvark: Check for errors from pci_bridge_emul_init() call + - PCI: iproc: Set affinity mask on MSI interrupts + - rpmsg: smd: Fix a kobj leak in in qcom_smd_parse_edge() + - PCI/IOV: Mark VFs as not implementing PCI_COMMAND_MEMORY + - vfio/pci: Decouple PCI_COMMAND_MEMORY bit checks from is_virtfn + - clk: qcom: gcc-sdm660: Fix wrong parent_map + - clk: keystone: sci-clk: fix parsing assigned-clock data during probe + - pwm: img: Fix null pointer access in probe + - clk: rockchip: Initialize hw to error to avoid undefined behavior + - clk: mediatek: add UART0 clock support + - module: statically initialize init section freeing data + - clk: at91: clk-main: update key before writing AT91_CKGR_MOR + - clk: bcm2835: add missing release if devm_clk_hw_register fails + - watchdog: Fix memleak in watchdog_cdev_register + - watchdog: Use put_device on error + - watchdog: sp5100: Fix definition of EFCH_PM_DECODEEN3 + - svcrdma: fix bounce buffers for unaligned offsets and multiple pages + - ext4: limit entries returned when counting fsmap records + - vfio/pci: Clear token on bypass registration failure + - vfio iommu type1: Fix memory leak in vfio_iommu_type1_pin_pages + - clk: imx8mq: Fix usdhc parents order + - SUNRPC: fix copying of multiple pages in gss_read_proxy_verf() + - Input: imx6ul_tsc - clean up some errors in imx6ul_tsc_resume() + - Input: stmfts - fix a & vs && typo + - Input: ep93xx_keypad - fix handling of platform_get_irq() error + - Input: omap4-keypad - fix handling of platform_get_irq() error + - Input: twl4030_keypad - fix handling of platform_get_irq() error + - Input: sun4i-ps2 - fix handling of platform_get_irq() error + - KVM: x86: emulating RDPID failure shall return #UD rather than #GP + - scsi: bfa: Fix error return in bfad_pci_init() + - netfilter: conntrack: connection timeout after re-register + - netfilter: ebtables: Fixes dropping of small packets in bridge nat + - netfilter: nf_fwd_netdev: clear timestamp in forwarding path + - arm64: dts: meson: vim3: correct led polarity + - ARM: dts: imx6sl: fix rng node + - ARM: at91: pm: of_node_put() after its usage + - ARM: s3c24xx: fix mmc gpio lookup tables + - ARM: dts: sun8i: r40: bananapi-m2-ultra: Fix dcdc1 regulator + - arm64: dts: allwinner: h5: remove Mali GPU PMU module + - memory: omap-gpmc: Fix a couple off by ones + - memory: omap-gpmc: Fix build error without CONFIG_OF + - memory: fsl-corenet-cf: Fix handling of platform_get_irq() error + - arm64: dts: imx8mq: Add missing interrupts to GPC + - arm64: dts: qcom: msm8916: Remove one more thermal trip point unit name + - arm64: dts: qcom: pm8916: Remove invalid reg size from wcd_codec + - arm64: dts: qcom: msm8916: Fix MDP/DSI interrupts + - arm64: dts: renesas: r8a77990: Fix MSIOF1 DMA channels + - arm64: dts: renesas: r8a774c0: Fix MSIOF1 DMA channels + - arm64: dts: actions: limit address range for pinctrl node + - ARM: dts: owl-s500: Fix incorrect PPI interrupt specifiers + - soc: fsl: qbman: Fix return value on success + - ARM: OMAP2+: Restore MPU power domain if cpu_cluster_pm_enter() fails + - arm64: dts: zynqmp: Remove additional compatible string for i2c IPs + - ARM: dts: meson8: remove two invalid interrupt lines from the GPU node + - lightnvm: fix out-of-bounds write to array devices->info[] + - powerpc/powernv/dump: Fix race while processing OPAL dump + - powerpc/pseries: Avoid using addr_to_pfn in real mode + - nvmet: fix uninitialized work for zero kato + - NTB: hw: amd: fix an issue about leak system resources + - sched/features: Fix !CONFIG_JUMP_LABEL case + - perf: correct SNOOPX field offset + - i2c: core: Restore acpi_walk_dep_device_list() getting called after + registering the ACPI i2c devs + - md/bitmap: fix memory leak of temporary bitmap + - block: ratelimit handle_bad_sector() message + - crypto: ccp - fix error handling + - x86/asm: Replace __force_order with a memory clobber + - x86/mce: Add Skylake quirk for patrol scrub reported errors + - media: firewire: fix memory leak + - media: ati_remote: sanity check for both endpoints + - media: st-delta: Fix reference count leak in delta_run_work + - media: sti: Fix reference count leaks + - media: exynos4-is: Fix several reference count leaks due to + pm_runtime_get_sync + - media: exynos4-is: Fix a reference count leak due to pm_runtime_get_sync + - media: exynos4-is: Fix a reference count leak + - media: vsp1: Fix runtime PM imbalance on error + - media: platform: s3c-camif: Fix runtime PM imbalance on error + - media: platform: sti: hva: Fix runtime PM imbalance on error + - media: bdisp: Fix runtime PM imbalance on error + - media: media/pci: prevent memory leak in bttv_probe + - x86/mce: Make mce_rdmsrl() panic on an inaccessible MSR + - media: uvcvideo: Ensure all probed info is returned to v4l2 + - mmc: sdio: Check for CISTPL_VERS_1 buffer size + - media: saa7134: avoid a shift overflow + - media: venus: fixes for list corruption + - fs: dlm: fix configfs memory leak + - media: venus: core: Fix runtime PM imbalance in venus_probe + - ntfs: add check for mft record size in superblock + - ip_gre: set dev->hard_header_len and dev->needed_headroom properly + - mac80211: handle lack of sband->bitrates in rates + - PM: hibernate: remove the bogus call to get_gendisk() in software_resume() + - scsi: mvumi: Fix error return in mvumi_io_attach() + - scsi: target: core: Add CONTROL field for trace events + - mic: vop: copy data to kernel space then write to io memory + - misc: vop: add round_up(x,4) for vring_size to avoid kernel panic + - usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc + - usb: gadget: function: printer: fix use-after-free in __lock_acquire + - udf: Limit sparing table size + - udf: Avoid accessing uninitialized data on failed inode read + - rtw88: increse the size of rx buffer size + - USB: cdc-acm: handle broken union descriptors + - usb: dwc3: simple: add support for Hikey 970 + - can: flexcan: flexcan_chip_stop(): add error handling and propagate error + value + - ath9k: hif_usb: fix race condition between usb_get_urb() and + usb_kill_anchored_urbs() + - drm/panfrost: add amlogic reset quirk callback + - bpf: Limit caller's stack depth 256 for subprogs with tailcalls + - misc: rtsx: Fix memory leak in rtsx_pci_probe + - reiserfs: only call unlock_new_inode() if I_NEW + - opp: Prevent memory leak in dev_pm_opp_attach_genpd() + - xfs: make sure the rt allocator doesn't run off the end + - usb: ohci: Default to per-port over-current protection + - Bluetooth: Only mark socket zapped after unlocking + - drm/msm/a6xx: fix a potential overflow issue + - iomap: fix WARN_ON_ONCE() from unprivileged users + - scsi: ibmvfc: Fix error return in ibmvfc_probe() + - scsi: qla2xxx: Warn if done() or free() are called on an already freed srb + - selftests/bpf: Fix test_sysctl_loop{1, 2} failure due to clang change + - brcmsmac: fix memory leak in wlc_phy_attach_lcnphy + - rtl8xxxu: prevent potential memory leak + - Fix use after free in get_capset_info callback. + - HID: ite: Add USB id match for Acer One S1003 keyboard dock + - scsi: qedf: Return SUCCESS if stale rport is encountered + - scsi: qedi: Protect active command list to avoid list corruption + - scsi: qedi: Fix list_del corruption while removing active I/O + - fbmem: add margin check to fb_check_caps() + - tty: ipwireless: fix error handling + - Bluetooth: btusb: Fix memleak in btusb_mtk_submit_wmt_recv_urb + - ipvs: Fix uninit-value in do_ip_vs_set_ctl() + - reiserfs: Fix memory leak in reiserfs_parse_options() + - mwifiex: don't call del_timer_sync() on uninitialized timer + - ALSA: hda/ca0132 - Add AE-7 microphone selection commands. + - ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7. + - scsi: smartpqi: Avoid crashing kernel for controller issues + - brcm80211: fix possible memleak in brcmf_proto_msgbuf_attach + - usb: core: Solve race condition in anchor cleanup functions + - scsi: ufs: ufs-qcom: Fix race conditions caused by ufs_qcom_testbus_config() + - dmaengine: dw: Add DMA-channels mask cell support + - dmaengine: dw: Activate FIFO-mode for memory peripherals only + - ath10k: check idx validity in __ath10k_htt_rx_ring_fill_n() + - net: korina: cast KSEG0 address to pointer in kfree + - s390/qeth: don't let HW override the configured port role + - tty: serial: lpuart: fix lpuart32_write usage + - tty: serial: fsl_lpuart: fix lpuart32_poll_get_char + - usb: cdc-acm: add quirk to blacklist ETAS ES58X devices + - USB: cdc-wdm: Make wdm_flush() interruptible and add wdm_fsync(). + - usb: cdns3: gadget: free interrupt after gadget has deleted + - eeprom: at25: set minimum read/write access stride to 1 + - usb: gadget: f_ncm: allow using NCM in SuperSpeed Plus gadgets. + - Linux 5.4.73 + * Focal update: v5.4.72 upstream stable release (LP: #1902111) + - perf cs-etm: Move definition of 'traceid_list' global variable from header + file + - btrfs: don't pass system_chunk into can_overcommit + - btrfs: take overcommit into account in inc_block_group_ro + - ARM: 8939/1: kbuild: use correct nm executable + - ACPI: Always build evged in + - Bluetooth: Consolidate encryption handling in hci_encrypt_cfm + - Bluetooth: Fix update of connection state in `hci_encrypt_cfm` + - Bluetooth: Disconnect if E0 is used for Level 4 + - media: usbtv: Fix refcounting mixup + - USB: serial: option: add Cellient MPL200 card + - USB: serial: option: Add Telit FT980-KS composition + - staging: comedi: check validity of wMaxPacketSize of usb endpoints found + - USB: serial: pl2303: add device-id for HP GC device + - USB: serial: ftdi_sio: add support for FreeCalypso JTAG+UART adapters + - reiserfs: Initialize inode keys properly + - reiserfs: Fix oops during mount + - xen/events: don't use chip_data for legacy IRQs + - crypto: bcm - Verify GCM/CCM key length in setkey + - crypto: qat - check cipher length for aead AES-CBC-HMAC-SHA + - Linux 5.4.72 + * Focal update: v5.4.71 upstream stable release (LP: #1902110) + - fbdev, newport_con: Move FONT_EXTRA_WORDS macros into linux/font.h + - Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts + - fbcon: Fix global-out-of-bounds read in fbcon_get_font() + - Revert "ravb: Fixed to be able to unload modules" + - io_uring: Fix resource leaking when kill the process + - io_uring: Fix missing smp_mb() in io_cancel_async_work() + - io_uring: Fix remove irrelevant req from the task_list + - io_uring: Fix double list add in io_queue_async_work() + - net: wireless: nl80211: fix out-of-bounds access in nl80211_del_key() + - drm/nouveau/mem: guard against NULL pointer access in mem_del + - vhost: Don't call access_ok() when using IOTLB + - vhost: Use vhost_get_used_size() in vhost_vring_set_addr() + - usermodehelper: reset umask to default before executing user process + - Platform: OLPC: Fix memleak in olpc_ec_probe + - platform/x86: intel-vbtn: Fix SW_TABLET_MODE always reporting 1 on the HP + Pavilion 11 x360 + - platform/x86: thinkpad_acpi: initialize tp_nvram_state variable + - bpf: Fix sysfs export of empty BTF section + - bpf: Prevent .BTF section elimination + - platform/x86: intel-vbtn: Switch to an allow-list for SW_TABLET_MODE + reporting + - platform/x86: thinkpad_acpi: re-initialize ACPI buffer size when reuse + - driver core: Fix probe_count imbalance in really_probe() + - perf test session topology: Fix data path + - perf top: Fix stdio interface input handling with glibc 2.28+ + - i2c: i801: Exclude device from suspend direct complete optimization + - arm64: dts: stratix10: add status to qspi dts node + - Btrfs: send, allow clone operations within the same file + - Btrfs: send, fix emission of invalid clone operations within the same file + - btrfs: volumes: Use more straightforward way to calculate map length + - btrfs: Ensure we trim ranges across block group boundary + - btrfs: fix RWF_NOWAIT write not failling when we need to cow + - btrfs: allow btrfs_truncate_block() to fallback to nocow for data space + reservation + - nvme-core: put ctrl ref when module ref get fail + - macsec: avoid use-after-free in macsec_handle_frame() + - mm/khugepaged: fix filemap page_to_pgoff(page) != offset + - net: introduce helper sendpage_ok() in include/linux/net.h + - tcp: use sendpage_ok() to detect misused .sendpage + - nvme-tcp: check page by sendpage_ok() before calling kernel_sendpage() + - xfrmi: drop ignore_df check before updating pmtu + - cifs: Fix incomplete memory allocation on setxattr path + - i2c: meson: fix clock setting overwrite + - i2c: meson: fixup rate calculation with filter delay + - i2c: owl: Clear NACK and BUS error bits + - sctp: fix sctp_auth_init_hmacs() error path + - team: set dev->needed_headroom in team_setup_by_port() + - net: team: fix memory leak in __team_options_register + - openvswitch: handle DNAT tuple collision + - drm/amdgpu: prevent double kfree ttm->sg + - iommu/vt-d: Fix lockdep splat in iommu_flush_dev_iotlb() + - xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate + - xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate + - xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate + - xfrm: clone whole liftime_cur structure in xfrm_do_migrate + - net: stmmac: removed enabling eee in EEE set callback + - platform/x86: fix kconfig dependency warning for FUJITSU_LAPTOP + - xfrm: Use correct address family in xfrm_state_find + - iavf: use generic power management + - iavf: Fix incorrect adapter get in iavf_resume + - net: ethernet: cavium: octeon_mgmt: use phy_start and phy_stop + - bonding: set dev->needed_headroom in bond_setup_by_slave() + - mdio: fix mdio-thunder.c dependency & build error + - mlxsw: spectrum_acl: Fix mlxsw_sp_acl_tcam_group_add()'s error path + - r8169: fix RTL8168f/RTL8411 EPHY config + - net: usb: ax88179_178a: fix missing stop entry in driver_info + - virtio-net: don't disable guest csum when disable LRO + - net/mlx5: Avoid possible free of command entry while timeout comp handler + - net/mlx5: Fix request_irqs error flow + - net/mlx5e: Add resiliency in Striding RQ mode for packets larger than MTU + - net/mlx5e: Fix VLAN cleanup flow + - net/mlx5e: Fix VLAN create flow + - rxrpc: Fix rxkad token xdr encoding + - rxrpc: Downgrade the BUG() for unsupported token type in rxrpc_read() + - rxrpc: Fix some missing _bh annotations on locking conn->state_lock + - rxrpc: The server keyring isn't network-namespaced + - rxrpc: Fix server keyring leak + - perf: Fix task_function_call() error handling + - mmc: core: don't set limits.discard_granularity as 0 + - mm: khugepaged: recalculate min_free_kbytes after memory hotplug as expected + by khugepaged + - tcp: fix receive window update in tcp_add_backlog() + - net/core: check length before updating Ethertype in skb_mpls_{push,pop} + - net/tls: race causes kernel panic + - net/mlx5e: Fix driver's declaration to support GRE offload + - Input: ati_remote2 - add missing newlines when printing module parameters + - net: usb: rtl8150: set random MAC address when set_ethernet_addr() fails + - net_sched: defer tcf_idr_insert() in tcf_action_init_1() + - net_sched: commit action insertions together + - Linux 5.4.71 + * kci_test_encap_fou() in rtnetlink.sh from kselftests/net failed with "FAIL: + can't add fou port 7777, skipping test" (LP: #1891421) + - selftests: rtnetlink: load fou module for kci_test_encap_fou() test + * alsa/hda/realtek - The front Mic on a HP machine doesn't work (LP: #1899508) + - ALSA: hda/realtek - The front Mic on a HP machine doesn't work + * Enable brightness control on HP DreamColor panel (LP: #1898865) + - drm/i915/dpcd_bl: Unbreak enable_dpcd_backlight modparam + - SAUCE: drm/i915/dpcd_bl: Skip testing control capability with force DPCD + quirk + - SAUCE: drm/dp: HP DreamColor panel brigntness fix + * Fix non-working Intel NVMe after S3 (LP: #1900847) + - SAUCE: PCI: Enable ACS quirk on all CML root ports + * bcache: Issues with large IO wait in bch_mca_scan() when shrinker is enabled + (LP: #1898786) + - bcache: remove member accessed from struct btree + - bcache: reap c->btree_cache_freeable from the tail in bch_mca_scan() + - bcache: reap from tail of c->btree_cache in bch_mca_scan() + * Improve descriptions for XFAIL cases in kselftests/net/psock_snd + (LP: #1900088) + - selftests/net: improve descriptions for XFAIL cases in psock_snd.sh + * ceph: fix inode number handling on arches with 32-bit ino_t (LP: #1899582) + - ceph: fix inode number handling on arches with 32-bit ino_t + * Fix system reboot when disconnecting WiFi (LP: #1899726) + - iwlwifi: msix: limit max RX queues for 9000 family + * Fix broken MSI interrupt after HDA controller was suspended (LP: #1899586) + - ALSA: hda: fix jack detection with Realtek codecs when in D3 + * Focal update: v5.4.70 upstream stable release (LP: #1900632) + - btrfs: fix filesystem corruption after a device replace + - mmc: sdhci: Workaround broken command queuing on Intel GLK based IRBIS + models + - USB: gadget: f_ncm: Fix NDP16 datagram validation + - gpio: siox: explicitly support only threaded irqs + - gpio: mockup: fix resource leak in error path + - gpio: tc35894: fix up tc35894 interrupt configuration + - clk: socfpga: stratix10: fix the divider for the emac_ptp_free_clk + - vsock/virtio: add transport parameter to the + virtio_transport_reset_no_sock() + - net: virtio_vsock: Enhance connection semantics + - xfs: trim IO to found COW extent limit + - Input: i8042 - add nopnp quirk for Acer Aspire 5 A515 + - iio: adc: qcom-spmi-adc5: fix driver name + - ftrace: Move RCU is watching check after recursion check + - memstick: Skip allocating card when removing host + - drm/amdgpu: restore proper ref count in amdgpu_display_crtc_set_config + - clocksource/drivers/timer-gx6605s: Fixup counter reload + - libbpf: Remove arch-specific include path in Makefile + - drivers/net/wan/hdlc_fr: Add needed_headroom for PVC devices + - drm/sun4i: mixer: Extend regmap max_register + - net: dec: de2104x: Increase receive ring size for Tulip + - rndis_host: increase sleep time in the query-response loop + - nvme-core: get/put ctrl and transport module in nvme_dev_open/release() + - fuse: fix the ->direct_IO() treatment of iov_iter + - drivers/net/wan/lapbether: Make skb->protocol consistent with the header + - drivers/net/wan/hdlc: Set skb->protocol before transmitting + - mac80211: Fix radiotap header channel flag for 6GHz band + - mac80211: do not allow bigger VHT MPDUs than the hardware supports + - tracing: Make the space reserved for the pid wider + - tools/io_uring: fix compile breakage + - spi: fsl-espi: Only process interrupts for expected events + - nvme-pci: fix NULL req in completion handler + - nvme-fc: fail new connections to a deleted host or remote port + - gpio: sprd: Clear interrupt when setting the type as edge + - phy: ti: am654: Fix a leak in serdes_am654_probe() + - pinctrl: mvebu: Fix i2c sda definition for 98DX3236 + - nfs: Fix security label length not being reset + - clk: tegra: Always program PLL_E when enabled + - clk: samsung: exynos4: mark 'chipid' clock as CLK_IGNORE_UNUSED + - iommu/exynos: add missing put_device() call in exynos_iommu_of_xlate() + - gpio/aspeed-sgpio: enable access to all 80 input & output sgpios + - gpio/aspeed-sgpio: don't enable all interrupts by default + - gpio: aspeed: fix ast2600 bank properties + - i2c: cpm: Fix i2c_ram structure + - Input: trackpoint - enable Synaptics trackpoints + - scripts/dtc: only append to HOST_EXTRACFLAGS instead of overwriting + - random32: Restore __latent_entropy attribute on net_rand_state + - block/diskstats: more accurate approximation of io_ticks for slow disks + - mm: replace memmap_context by meminit_context + - mm: don't rely on system state to detect hot-plug operations + - nvme: Cleanup and rename nvme_block_nr() + - nvme: Introduce nvme_lba_to_sect() + - nvme: consolidate chunk_sectors settings + - epoll: do not insert into poll queues until all sanity checks are done + - epoll: replace ->visited/visited_list with generation count + - epoll: EPOLL_CTL_ADD: close the race in decision to take fast path + - ep_create_wakeup_source(): dentry name can change under you... + - netfilter: ctnetlink: add a range check for l3/l4 protonum + - Linux 5.4.70 + * Focal update: v5.4.69 upstream stable release (LP: #1900624) + - kernel/sysctl-test: Add null pointer test for sysctl.c:proc_dointvec() + - selinux: allow labeling before policy is loaded + - media: mc-device.c: fix memleak in media_device_register_entity + - drm/amd/display: Do not double-buffer DTO adjustments + - drm/amdkfd: Fix race in gfx10 context restore handler + - dma-fence: Serialise signal enabling (dma_fence_enable_sw_signaling) + - scsi: qla2xxx: Add error handling for PLOGI ELS passthrough + - ath10k: fix array out-of-bounds access + - ath10k: fix memory leak for tpc_stats_final + - PCI/IOV: Serialize sysfs sriov_numvfs reads vs writes + - mm: fix double page fault on arm64 if PTE_AF is cleared + - scsi: aacraid: fix illegal IO beyond last LBA + - m68k: q40: Fix info-leak in rtc_ioctl + - xfs: fix inode fork extent count overflow + - gma/gma500: fix a memory disclosure bug due to uninitialized bytes + - ASoC: kirkwood: fix IRQ error handling + - soundwire: intel/cadence: fix startup sequence + - media: smiapp: Fix error handling at NVM reading + - drm/amd/display: Free gamma after calculating legacy transfer function + - xfs: properly serialise fallocate against AIO+DIO + - leds: mlxreg: Fix possible buffer overflow + - dm table: do not allow request-based DM to stack on partitions + - PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out + - scsi: fnic: fix use after free + - powerpc/64s: Always disable branch profiling for prom_init.o + - net: silence data-races on sk_backlog.tail + - dax: Fix alloc_dax_region() compile warning + - iomap: Fix overflow in iomap_page_mkwrite + - f2fs: avoid kernel panic on corruption test + - clk/ti/adpll: allocate room for terminating null + - drm/amdgpu/powerplay: fix AVFS handling with custom powerplay table + - ice: Fix to change Rx/Tx ring descriptor size via ethtool with DCBx + - mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of + cfi_amdstd_setup() + - mfd: mfd-core: Protect against NULL call-back function pointer + - drm/amdgpu/powerplay/smu7: fix AVFS handling with custom powerplay table + - tpm_crb: fix fTPM on AMD Zen+ CPUs + - tracing: Verify if trace array exists before destroying it. + - tracing: Adding NULL checks for trace_array descriptor pointer + - bcache: fix a lost wake-up problem caused by mca_cannibalize_lock + - dmaengine: mediatek: hsdma_probe: fixed a memory leak when devm_request_irq + fails + - x86/kdump: Always reserve the low 1M when the crashkernel option is + specified + - RDMA/qedr: Fix potential use after free + - RDMA/i40iw: Fix potential use after free + - PCI: Avoid double hpmemsize MMIO window assignment + - fix dget_parent() fastpath race + - xfs: fix attr leaf header freemap.size underflow + - RDMA/iw_cgxb4: Fix an error handling path in 'c4iw_connect()' + - ubi: Fix producing anchor PEBs + - mmc: core: Fix size overflow for mmc partitions + - gfs2: clean up iopen glock mess in gfs2_create_inode + - scsi: pm80xx: Cleanup command when a reset times out + - mt76: do not use devm API for led classdev + - mt76: add missing locking around ampdu action + - debugfs: Fix !DEBUG_FS debugfs_create_automount + - SUNRPC: Capture completion of all RPC tasks + - CIFS: Use common error handling code in smb2_ioctl_query_info() + - CIFS: Properly process SMB3 lease breaks + - f2fs: stop GC when the victim becomes fully valid + - ASoC: max98090: remove msleep in PLL unlocked workaround + - xtensa: fix system_call interaction with ptrace + - s390: avoid misusing CALL_ON_STACK for task stack setup + - xfs: fix realtime file data space leak + - drm/amdgpu: fix calltrace during kmd unload(v3) + - arm64: insn: consistently handle exit text + - selftests/bpf: De-flake test_tcpbpf + - kernel/notifier.c: intercept duplicate registrations to avoid infinite loops + - kernel/sys.c: avoid copying possible padding bytes in copy_to_user + - KVM: arm/arm64: vgic: Fix potential double free dist->spis in + __kvm_vgic_destroy() + - module: Remove accidental change of module_enable_x() + - xfs: fix log reservation overflows when allocating large rt extents + - ALSA: hda: enable regmap internal locking + - tipc: fix link overflow issue at socket shutdown + - vcc_seq_next should increase position index + - neigh_stat_seq_next() should increase position index + - rt_cpu_seq_next should increase position index + - ipv6_route_seq_next should increase position index + - drm/mcde: Handle pending vblank while disabling display + - seqlock: Require WRITE_ONCE surrounding raw_seqcount_barrier + - drm/scheduler: Avoid accessing freed bad job. + - media: ti-vpe: cal: Restrict DMA to avoid memory corruption + - opp: Replace list_kref with a local counter + - scsi: qla2xxx: Fix stuck session in GNL + - sctp: move trace_sctp_probe_path into sctp_outq_sack + - ACPI: EC: Reference count query handlers under lock + - scsi: ufs: Make ufshcd_add_command_trace() easier to read + - scsi: ufs: Fix a race condition in the tracing code + - drm/amd/display: Initialize DSC PPS variables to 0 + - i2c: tegra: Prevent interrupt triggering after transfer timeout + - btrfs: tree-checker: Check leaf chunk item size + - dmaengine: zynqmp_dma: fix burst length configuration + - s390/cpum_sf: Use kzalloc and minor changes + - nfsd: Fix a soft lockup race in nfsd_file_mark_find_or_create() + - powerpc/eeh: Only dump stack once if an MMIO loop is detected + - Bluetooth: btrtl: Use kvmalloc for FW allocations + - tracing: Set kernel_stack's caller size properly + - ARM: 8948/1: Prevent OOB access in stacktrace + - ar5523: Add USB ID of SMCWUSBT-G2 wireless adapter + - ceph: ensure we have a new cap before continuing in fill_inode + - selftests/ftrace: fix glob selftest + - tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility + - Bluetooth: Fix refcount use-after-free issue + - mm/swapfile.c: swap_next should increase position index + - mm: pagewalk: fix termination condition in walk_pte_range() + - Bluetooth: prefetch channel before killing sock + - ALSA: hda: Clear RIRB status before reading WP + - skbuff: fix a data race in skb_queue_len() + - nfsd: Fix a perf warning + - drm/amd/display: fix workaround for incorrect double buffer register for DLG + ADL and TTU + - audit: CONFIG_CHANGE don't log internal bookkeeping as an event + - selinux: sel_avc_get_stat_idx should increase position index + - drm/omap: fix possible object reference leak + - locking/lockdep: Decrement IRQ context counters when removing lock chain + - clk: stratix10: use do_div() for 64-bit calculation + - crypto: chelsio - This fixes the kernel panic which occurs during a libkcapi + test + - mt76: clear skb pointers from rx aggregation reorder buffer during cleanup + - mt76: fix handling full tx queues in mt76_dma_tx_queue_skb_raw + - ALSA: usb-audio: Don't create a mixer element with bogus volume range + - perf test: Fix test trace+probe_vfs_getname.sh on s390 + - RDMA/rxe: Fix configuration of atomic queue pair attributes + - KVM: x86: fix incorrect comparison in trace event + - KVM: nVMX: Hold KVM's srcu lock when syncing vmcs12->shadow + - dmaengine: stm32-mdma: use vchan_terminate_vdesc() in .terminate_all + - media: staging/imx: Missing assignment in + imx_media_capture_device_register() + - x86/pkeys: Add check for pkey "overflow" + - bpf: Remove recursion prevention from rcu free callback + - dmaengine: stm32-dma: use vchan_terminate_vdesc() in .terminate_all + - dmaengine: tegra-apb: Prevent race conditions on channel's freeing + - soundwire: bus: disable pm_runtime in sdw_slave_delete + - drm/amd/display: dal_ddc_i2c_payloads_create can fail causing panic + - drm/omap: dss: Cleanup DSS ports on initialisation failure + - iavf: use tc_cls_can_offload_and_chain0() instead of chain check + - firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhp + - random: fix data races at timer_rand_state + - bus: hisi_lpc: Fixup IO ports addresses to avoid use-after-free in host + removal + - ASoC: SOF: ipc: check ipc return value before data copy + - media: go7007: Fix URB type for interrupt handling + - Bluetooth: guard against controllers sending zero'd events + - timekeeping: Prevent 32bit truncation in scale64_check_overflow() + - powerpc/book3s64: Fix error handling in mm_iommu_do_alloc() + - drm/amd/display: fix image corruption with ODM 2:1 DSC 2 slice + - ext4: fix a data race at inode->i_disksize + - perf jevents: Fix leak of mapfile memory + - mm: avoid data corruption on CoW fault into PFN-mapped VMA + - drm/amdgpu: increase atombios cmd timeout + - ARM: OMAP2+: Handle errors for cpu_pm + - clk: imx: Fix division by zero warning on pfdv2 + - cpu-topology: Fix the potential data corruption + - s390/irq: replace setup_irq() by request_irq() + - perf cs-etm: Swap packets for instruction samples + - perf cs-etm: Correct synthesizing instruction samples + - ath10k: use kzalloc to read for ath10k_sdio_hif_diag_read + - scsi: aacraid: Disabling TM path and only processing IOP reset + - Bluetooth: L2CAP: handle l2cap config request during open state + - media: tda10071: fix unsigned sign extension overflow + - tty: sifive: Finish transmission before changing the clock + - xfs: don't ever return a stale pointer from __xfs_dir3_free_read + - xfs: mark dir corrupt when lookup-by-hash fails + - ext4: mark block bitmap corrupted when found instead of BUGON + - tpm: ibmvtpm: Wait for buffer to be set before proceeding + - rtc: sa1100: fix possible race condition + - rtc: ds1374: fix possible race condition + - nfsd: Don't add locks to closed or closing open stateids + - RDMA/cm: Remove a race freeing timewait_info + - intel_th: Disallow multi mode on devices where it's broken + - KVM: PPC: Book3S HV: Treat TM-related invalid form instructions on P9 like + the valid ones + - drm/msm: fix leaks if initialization fails + - drm/msm/a5xx: Always set an OPP supported hardware value + - tracing: Use address-of operator on section symbols + - thermal: rcar_thermal: Handle probe error gracefully + - KVM: LAPIC: Mark hrtimer for period or oneshot mode to expire in hard + interrupt context + - perf parse-events: Fix 3 use after frees found with clang ASAN + - btrfs: do not init a reloc root if we aren't relocating + - btrfs: free the reloc_control in a consistent way + - r8169: improve RTL8168b FIFO overflow workaround + - serial: 8250_port: Don't service RX FIFO if throttled + - serial: 8250_omap: Fix sleeping function called from invalid context during + probe + - serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout + - perf cpumap: Fix snprintf overflow check + - net: axienet: Convert DMA error handler to a work queue + - net: axienet: Propagate failure of DMA descriptor setup + - cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_work_fn + - tools: gpio-hammer: Avoid potential overflow in main + - exec: Add exec_update_mutex to replace cred_guard_mutex + - exec: Fix a deadlock in strace + - selftests/ptrace: add test cases for dead-locks + - kernel/kcmp.c: Use new infrastructure to fix deadlocks in execve + - proc: Use new infrastructure to fix deadlocks in execve + - proc: io_accounting: Use new infrastructure to fix deadlocks in execve + - perf: Use new infrastructure to fix deadlocks in execve + - nvme-multipath: do not reset on unknown status + - nvme: Fix ctrl use-after-free during sysfs deletion + - nvme: Fix controller creation races with teardown flow + - brcmfmac: Fix double freeing in the fmac usb data path + - xfs: prohibit fs freezing when using empty transactions + - RDMA/rxe: Set sys_image_guid to be aligned with HW IB devices + - IB/iser: Always check sig MR before putting it to the free pool + - scsi: hpsa: correct race condition in offload enabled + - SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' + - svcrdma: Fix leak of transport addresses + - netfilter: nf_tables: silence a RCU-list warning in nft_table_lookup() + - PCI: Use ioremap(), not phys_to_virt() for platform ROM + - ubifs: ubifs_jnl_write_inode: Fix a memory leak bug + - ubifs: ubifs_add_orphan: Fix a memory leak bug + - ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len + - ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra + endpoint descriptor + - PCI: pciehp: Fix MSI interrupt race + - NFS: Fix races nfs_page_group_destroy() vs + nfs_destroy_unlinked_subrequests() + - drm/amdgpu/vcn2.0: stall DPG when WPTR/RPTR reset + - powerpc/perf: Implement a global lock to avoid races between trace, core and + thread imc events. + - mm/kmemleak.c: use address-of operator on section symbols + - mm/filemap.c: clear page error before actual read + - mm/swapfile: fix data races in try_to_unuse() + - mm/vmscan.c: fix data races using kswapd_classzone_idx + - SUNRPC: Don't start a timer on an already queued rpc task + - nvmet-rdma: fix double free of rdma queue + - workqueue: Remove the warning in wq_worker_sleeping() + - drm/amdgpu/sriov add amdgpu_amdkfd_pre_reset in gpu reset + - mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area + - ALSA: hda: Skip controller resume if not needed + - scsi: qedi: Fix termination timeouts in session logout + - serial: uartps: Wait for tx_empty in console setup + - btrfs: fix setting last_trans for reloc roots + - KVM: Remove CREATE_IRQCHIP/SET_PIT2 race + - perf stat: Force error in fallback on :k events + - bdev: Reduce time holding bd_mutex in sync in blkdev_close() + - drivers: char: tlclk.c: Avoid data race between init and interrupt handler + - KVM: arm64: vgic-v3: Retire all pending LPIs on vcpu destroy + - KVM: arm64: vgic-its: Fix memory leak on the error path of vgic_add_lpi() + - net: openvswitch: use u64 for meter bucket + - scsi: aacraid: Fix error handling paths in aac_probe_one() + - staging:r8188eu: avoid skb_clone for amsdu to msdu conversion + - sparc64: vcc: Fix error return code in vcc_probe() + - arm64: cpufeature: Relax checks for AArch32 support at EL[0-2] + - sched/fair: Eliminate bandwidth race between throttling and distribution + - dpaa2-eth: fix error return code in setup_dpni() + - dt-bindings: sound: wm8994: Correct required supplies based on actual + implementaion + - devlink: Fix reporter's recovery condition + - atm: fix a memory leak of vcc->user_back + - media: venus: vdec: Init registered list unconditionally + - perf mem2node: Avoid double free related to realloc + - mm/slub: fix incorrect interpretation of s->offset + - i2c: tegra: Restore pinmux on system resume + - power: supply: max17040: Correct voltage reading + - phy: samsung: s5pv210-usb2: Add delay after reset + - Bluetooth: Handle Inquiry Cancel error after Inquiry Complete + - USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() + - KVM: x86: handle wrap around 32-bit address space + - tipc: fix memory leak in service subscripting + - tty: serial: samsung: Correct clock selection logic + - ALSA: hda: Fix potential race in unsol event handler + - drm/exynos: dsi: Remove bridge node reference in error handling path in + probe function + - ipmi:bt-bmc: Fix error handling and status check + - powerpc/traps: Make unrecoverable NMIs die instead of panic + - svcrdma: Fix backchannel return code + - fuse: don't check refcount after stealing page + - fuse: update attr_version counter on fuse_notify_inval_inode() + - USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int + - coresight: etm4x: Fix use-after-free of per-cpu etm drvdata + - arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work + - scsi: cxlflash: Fix error return code in cxlflash_probe() + - arm64/cpufeature: Drop TraceFilt feature exposure from ID_DFR0 register + - drm/amdkfd: fix restore worker race condition + - e1000: Do not perform reset in reset_task if we are already down + - drm/nouveau/debugfs: fix runtime pm imbalance on error + - drm/nouveau: fix runtime pm imbalance on error + - drm/nouveau/dispnv50: fix runtime pm imbalance on error + - printk: handle blank console arguments passed in. + - usb: dwc3: Increase timeout for CmdAct cleared by device controller + - btrfs: don't force read-only after error in drop snapshot + - btrfs: fix double __endio_write_update_ordered in direct I/O + - gpio: rcar: Fix runtime PM imbalance on error + - vfio/pci: fix memory leaks of eventfd ctx + - KVM: PPC: Book3S HV: Close race with page faults around memslot flushes + - perf evsel: Fix 2 memory leaks + - perf trace: Fix the selection for architectures to generate the errno name + tables + - perf stat: Fix duration_time value for higher intervals + - perf util: Fix memory leak of prefix_if_not_in + - perf metricgroup: Free metric_events on error + - perf kcore_copy: Fix module map when there are no modules loaded + - PCI: tegra194: Fix runtime PM imbalance on error + - ASoC: img-i2s-out: Fix runtime PM imbalance on error + - wlcore: fix runtime pm imbalance in wl1271_tx_work + - wlcore: fix runtime pm imbalance in wlcore_regdomain_config + - mtd: rawnand: gpmi: Fix runtime PM imbalance on error + - mtd: rawnand: omap_elm: Fix runtime PM imbalance on error + - PCI: tegra: Fix runtime PM imbalance on error + - ceph: fix potential race in ceph_check_caps + - mm/swap_state: fix a data race in swapin_nr_pages + - mm: memcontrol: fix stat-corrupting race in charge moving + - rapidio: avoid data race between file operation callbacks and + mport_cdev_add(). + - mtd: parser: cmdline: Support MTD names containing one or more colons + - x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline + - NFS: nfs_xdr_status should record the procedure name + - vfio/pci: Clear error and request eventfd ctx after releasing + - cifs: Fix double add page to memcg when cifs_readpages + - nvme: fix possible deadlock when I/O is blocked + - mac80211: skip mpath lookup also for control port tx + - scsi: libfc: Handling of extra kref + - scsi: libfc: Skip additional kref updating work event + - selftests/x86/syscall_nt: Clear weird flags after each test + - vfio/pci: fix racy on error and request eventfd ctx + - btrfs: qgroup: fix data leak caused by race between writeback and truncate + - perf tests: Fix test 68 zstd compression for s390 + - scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure + - ubi: fastmap: Free unused fastmap anchor peb during detach + - mt76: fix LED link time failure + - opp: Increase parsed_static_opps in _of_add_opp_table_v1() + - perf parse-events: Use strcmp() to compare the PMU name + - ALSA: hda: Always use jackpoll helper for jack update after resume + - ALSA: hda: Workaround for spurious wakeups on some Intel platforms + - net: openvswitch: use div_u64() for 64-by-32 divisions + - nvme: explicitly update mpath disk capacity on revalidation + - device_cgroup: Fix RCU list debugging warning + - ASoC: pcm3168a: ignore 0 Hz settings + - ASoC: wm8994: Skip setting of the WM8994_MICBIAS register for WM1811 + - ASoC: wm8994: Ensure the device is resumed in wm89xx_mic_detect functions + - ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN Converter9 2-in-1 + - RISC-V: Take text_mutex in ftrace_init_nop() + - i2c: aspeed: Mask IRQ status to relevant bits + - s390/init: add missing __init annotations + - lockdep: fix order in trace_hardirqs_off_caller() + - EDAC/ghes: Check whether the driver is on the safe list correctly + - drm/amdkfd: fix a memory leak issue + - drm/amd/display: update nv1x stutter latencies + - drm/amdgpu/dc: Require primary plane to be enabled whenever the CRTC is + - objtool: Fix noreturn detection for ignored functions + - ieee802154: fix one possible memleak in ca8210_dev_com_init + - ieee802154/adf7242: check status of adf7242_read_reg + - clocksource/drivers/h8300_timer8: Fix wrong return value in + h8300_8timer_init() + - batman-adv: bla: fix type misuse for backbone_gw hash indexing + - atm: eni: fix the missed pci_disable_device() for eni_init_one() + - batman-adv: mcast/TT: fix wrongly dropped or rerouted packets + - netfilter: conntrack: nf_conncount_init is failing with IPv6 disabled + - mac802154: tx: fix use-after-free + - bpf: Fix clobbering of r2 in bpf_gen_ld_abs + - drm/vc4/vc4_hdmi: fill ASoC card owner + - net: qed: Disable aRFS for NPAR and 100G + - net: qede: Disable aRFS for NPAR and 100G + - net: qed: RDMA personality shouldn't fail VF load + - drm/sun4i: sun8i-csc: Secondary CSC register correction + - batman-adv: Add missing include for in_interrupt() + - nvme-tcp: fix kconfig dependency warning when !CRYPTO + - batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN + - batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh + - batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh + - bpf: Fix a rcu warning for bpffs map pretty-print + - lib80211: fix unmet direct dependendices config warning when !CRYPTO + - ALSA: asihpi: fix iounmap in error handler + - regmap: fix page selection for noinc reads + - regmap: fix page selection for noinc writes + - MIPS: Add the missing 'CPU_1074K' into __get_cpu_type() + - regulator: axp20x: fix LDO2/4 description + - KVM: x86: Reset MMU context if guest toggles CR4.SMAP or CR4.PKE + - KVM: SVM: Add a dedicated INVD intercept routine + - mm: validate pmd after splitting + - arch/x86/lib/usercopy_64.c: fix __copy_user_flushcache() cache writeback + - x86/ioapic: Unbreak check_timer() + - scsi: lpfc: Fix initial FLOGI failure due to BBSCN not supported + - ALSA: usb-audio: Add delay quirk for H570e USB headsets + - ALSA: hda/realtek - Couldn't detect Mic if booting with headset plugged + - ALSA: hda/realtek: Enable front panel headset LED on Lenovo ThinkStation + P520 + - lib/string.c: implement stpcpy + - tracing: fix double free + - s390/dasd: Fix zero write for FBA devices + - kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() + - kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot + - btrfs: fix overflow when copying corrupt csums for a message + - dmabuf: fix NULL pointer dereference in dma_buf_release() + - mm, THP, swap: fix allocating cluster for swapfile by mistake + - mm/gup: fix gup_fast with dynamic page table folding + - s390/zcrypt: Fix ZCRYPT_PERDEV_REQCNT ioctl + - KVM: arm64: Assume write fault on S1PTW permission fault on instruction + fetch + - dm: fix bio splitting and its bio completion order for regular IO + - ata: define AC_ERR_OK + - ata: make qc_prep return ata_completion_errors + - ata: sata_mv, avoid trigerrable BUG_ON + - Linux 5.4.69 + * Focal update: v5.4.68 upstream stable release (LP: #1899511) + - af_key: pfkey_dump needs parameter validation + - ibmvnic fix NULL tx_pools and rx_tools issue at do_reset + - ibmvnic: add missing parenthesis in do_reset() + - kprobes: fix kill kprobe which has been marked as gone + - mm/thp: fix __split_huge_pmd_locked() for migration PMD + - act_ife: load meta modules before tcf_idr_check_alloc() + - bnxt_en: Avoid sending firmware messages when AER error is detected. + - bnxt_en: Fix NULL ptr dereference crash in bnxt_fw_reset_task() + - cxgb4: fix memory leak during module unload + - cxgb4: Fix offset when clearing filter byte counters + - geneve: add transport ports in route lookup for geneve + - hdlc_ppp: add range checks in ppp_cp_parse_cr() + - ip: fix tos reflection in ack and reset packets + - ipv4: Initialize flowi4_multipath_hash in data path + - ipv4: Update exception handling for multipath routes via same device + - ipv6: avoid lockdep issue in fib6_del() + - net: bridge: br_vlan_get_pvid_rcu() should dereference the VLAN group under + RCU + - net: DCB: Validate DCB_ATTR_DCB_BUFFER argument + - net: dsa: rtl8366: Properly clear member config + - net: Fix bridge enslavement failure + - net: ipv6: fix kconfig dependency warning for IPV6_SEG6_HMAC + - net/mlx5: Fix FTE cleanup + - net: sch_generic: aviod concurrent reset and enqueue op for lockless qdisc + - net: sctp: Fix IPv6 ancestor_size calc in sctp_copy_descendant + - nfp: use correct define to return NONE fec + - taprio: Fix allowing too small intervals + - tipc: Fix memory leak in tipc_group_create_member() + - tipc: fix shutdown() of connection oriented socket + - tipc: use skb_unshare() instead in tipc_buf_append() + - net/mlx5e: Enable adding peer miss rules only if merged eswitch is supported + - net/mlx5e: TLS, Do not expose FPGA TLS counter if not supported + - bnxt_en: return proper error codes in bnxt_show_temp + - bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. + - net: lantiq: Wake TX queue again + - net: lantiq: use netif_tx_napi_add() for TX NAPI + - net: lantiq: Use napi_complete_done() + - net: lantiq: Disable IRQs only if NAPI gets scheduled + - net: phy: Avoid NPD upon phy_detach() when driver is unbound + - net: phy: Do not warn in phy_stop() on PHY_DOWN + - net: qrtr: check skb_put_padto() return value + - net: add __must_check to skb_put_padto() + - mm: memcg: fix memcg reclaim soft lockup + - iommu/amd: Use cmpxchg_double() when updating 128-bit IRTE + - Linux 5.4.68 + * *-tools-common packages descriptions have typo "PGKVER" (LP: #1898903) + - [Packaging] Fix typo in -tools template s/PGKVER/PKGVER/ + * tc/ebpf: unable to use BPF_FUNC_skb_change_head (LP: #1896504) + - net: bpf: Allow TC programs to call BPF_FUNC_skb_change_head + * HP Zbook Studio G7 boots into corrupted screen with PSR featured panel + (LP: #1897501) + - SAUCE: drm/i915/psr: allow overriding PSR disable param by quirk + - SAUCE: drm/dp: add DP_QUIRK_FORCE_PSR_CHIP_DEFAULT quirk to CMN prod-ID + 19-15 + * Fix broken e1000e device after S3 (LP: #1897755) + - SAUCE: e1000e: Increase polling timeout on MDIC ready bit + * debian/rules editconfigs does not work on s390x to change s390x only configs + (LP: #1863116) + - [Packaging] kernelconfig -- only update/edit configurations on architectures + we have compiler support + * acpi event detection crashes (LP: #1896482) + - ACPI: EC: tweak naming in preparation for GpioInt support + - ACPI: EC: add support for hardware-reduced systems + - ACPI: EC: Avoid passing redundant argument to functions + - ACPI: EC: Consolidate event handler installation code + * mwifiex stops working after kernel upgrade (LP: #1897299) + - mwifiex: Increase AES key storage size to 256 bits + * Remove NVMe suspend-to-idle workaround (LP: #1897227) + - Revert "UBUTU: SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3" + - Revert "UBUNTU: SAUCE: pci: prevent sk hynix nvme from entering D3" + * Request for CIFS patches to be available in 5.4 kernel (LP: #1896642) + - smb3: remove unused flag passed into close functions + - smb3: query attributes on file close + * Lenovo ThinkBook 14-IML Touchpad not showing up in /proc/bus/input/devices + (LP: #1853277) + - i2c: core: Call i2c_acpi_install_space_handler() before + i2c_acpi_register_devices() + * [Ubuntu 20.10] zPCI DMA tables and bitmap leak on hard unplug (PCI Event + 0x0304) (LP: #1896216) + - s390/pci: fix leak of DMA tables on hard unplug + * Thunderbolt3 daisy chain sometimes doesn't work (LP: #1895606) + - thunderbolt: Retry DROM read once if parsing fails + * btrfs: trimming a btrfs device which has been shrunk previously fails and + fills root disk with garbage data (LP: #1896154) + - btrfs: trim: fix underflow in trim length to prevent access beyond device + boundary + * EFA: add support for 0xefa1 devices (LP: #1896791) + - RDMA/efa: Expose maximum TX doorbell batch + - RDMA/efa: Expose minimum SQ size + - RDMA/efa: User/kernel compatibility handshake mechanism + - RDMA/efa: Add EFA 0xefa1 PCI ID + * Focal update: v5.4.67 upstream stable release (LP: #1896828) + - gfs2: initialize transaction tr_ailX_lists earlier + - RDMA/bnxt_re: Restrict the max_gids to 256 + - dsa: Allow forwarding of redirected IGMP traffic + - net: handle the return value of pskb_carve_frag_list() correctly + - hv_netvsc: Remove "unlikely" from netvsc_select_queue + - firmware_loader: fix memory leak for paged buffer + - NFSv4.1 handle ERR_DELAY error reclaiming locking state on delegation recall + - scsi: pm8001: Fix memleak in pm8001_exec_internal_task_abort + - scsi: libfc: Fix for double free() + - scsi: lpfc: Fix FLOGI/PLOGI receive race condition in pt2pt discovery + - regulator: pwm: Fix machine constraints application + - spi: spi-loopback-test: Fix out-of-bounds read + - NFS: Zero-stateid SETATTR should first return delegation + - SUNRPC: stop printk reading past end of string + - rapidio: Replace 'select' DMAENGINES 'with depends on' + - cifs: fix DFS mount with cifsacl/modefromsid + - openrisc: Fix cache API compile issue when not inlining + - nvme-fc: cancel async events before freeing event struct + - nvme-rdma: cancel async events before freeing event struct + - nvme-tcp: cancel async events before freeing event struct + - block: only call sched requeue_request() for scheduled requests + - f2fs: fix indefinite loop scanning for free nid + - f2fs: Return EOF on unaligned end of file DIO read + - i2c: algo: pca: Reapply i2c bus settings after reset + - spi: Fix memory leak on splited transfers + - KVM: MIPS: Change the definition of kvm type + - clk: davinci: Use the correct size when allocating memory + - clk: rockchip: Fix initialization of mux_pll_src_4plls_p + - ASoC: qcom: Set card->owner to avoid warnings + - ASoC: qcom: common: Fix refcount imbalance on error + - powerpc/book3s64/radix: Fix boot failure with large amount of guest memory + - ASoC: meson: axg-toddr: fix channel order on g12 platforms + - Drivers: hv: vmbus: hibernation: do not hang forever in vmbus_bus_resume() + - scsi: libsas: Fix error path in sas_notify_lldd_dev_found() + - arm64: Allow CPUs unffected by ARM erratum 1418040 to come in late + - Drivers: hv: vmbus: Add timeout to vmbus_wait_for_unload + - perf test: Fix the "signal" test inline assembly + - MIPS: SNI: Fix MIPS_L1_CACHE_SHIFT + - perf evlist: Fix cpu/thread map leak + - perf parse-event: Fix memory leak in evsel->unit + - perf test: Free formats for perf pmu parse test + - fbcon: Fix user font detection test at fbcon_resize(). + - MIPS: SNI: Fix spurious interrupts + - drm/mediatek: Add exception handing in mtk_drm_probe() if component init + fail + - drm/mediatek: Add missing put_device() call in mtk_hdmi_dt_parse_pdata() + - arm64: bpf: Fix branch offset in JIT + - iommu/amd: Fix potential @entry null deref + - i2c: mxs: use MXS_DMA_CTRL_WAIT4END instead of DMA_CTRL_ACK + - riscv: Add sfence.vma after early page table changes + - drm/i915: Filter wake_flags passed to default_wake_function + - USB: quirks: Add USB_QUIRK_IGNORE_REMOTE_WAKEUP quirk for BYD zhaoxin + notebook + - USB: UAS: fix disconnect by unplugging a hub + - usblp: fix race between disconnect() and read() + - i2c: i801: Fix resume bug + - Revert "ALSA: hda - Fix silent audio output and corrupted input on MSI + X570-A PRO" + - ALSA: hda: fixup headset for ASUS GX502 laptop + - ALSA: hda/realtek - The Mic on a RedmiBook doesn't work + - percpu: fix first chunk size calculation for populated bitmap + - Input: trackpoint - add new trackpoint variant IDs + - Input: i8042 - add Entroware Proteus EL07R4 to nomux and reset lists + - serial: 8250_pci: Add Realtek 816a and 816b + - x86/boot/compressed: Disable relocation relaxation + - s390/zcrypt: fix kmalloc 256k failure + - ehci-hcd: Move include to keep CRC stable + - powerpc/dma: Fix dma_map_ops::get_required_mask + - selftests/vm: fix display of page size in map_hugetlb + - dm/dax: Fix table reference counts + - mm/memory_hotplug: drain per-cpu pages again during memory offline + - dm: Call proper helper to determine dax support + - dax: Fix compilation for CONFIG_DAX && !CONFIG_FS_DAX + - Linux 5.4.67 + * Focal update: v5.4.67 upstream stable release (LP: #1896828) // Cherry Pick + needed for Critical upstream patch for Kernel null pointer dereference - + usb-c altmode (LP: #1897963) + - usb: typec: ucsi: Prevent mode overrun + * Focal update: v5.4.66 upstream stable release (LP: #1896824) + - ARM: dts: logicpd-torpedo-baseboard: Fix broken audio + - ARM: dts: logicpd-som-lv-baseboard: Fix broken audio + - ARM: dts: logicpd-som-lv-baseboard: Fix missing video + - regulator: push allocation in regulator_ena_gpio_request() out of lock + - regulator: remove superfluous lock in regulator_resolve_coupling() + - ARM: dts: socfpga: fix register entry for timer3 on Arria10 + - ARM: dts: ls1021a: fix QuadSPI-memory reg range + - ARM: dts: imx7ulp: Correct gpio ranges + - RDMA/rxe: Fix memleak in rxe_mem_init_user + - RDMA/rxe: Drop pointless checks in rxe_init_ports + - RDMA/rxe: Fix panic when calling kmem_cache_create() + - RDMA/bnxt_re: Do not report transparent vlan from QP1 + - drm/sun4i: add missing put_device() call in sun8i_r40_tcon_tv_set_mux() + - arm64: dts: imx8mq: Fix TMU interrupt property + - drm/sun4i: Fix dsi dcs long write function + - iio: adc: mcp3422: fix locking on error path + - iio: adc: mcp3422: fix locking scope + - scsi: libsas: Set data_dir as DMA_NONE if libata marks qc as NODATA + - RDMA/core: Fix reported speed and width + - scsi: megaraid_sas: Don't call disable_irq from process IRQ poll + - scsi: mpt3sas: Don't call disable_irq from IRQ poll handler + - soundwire: fix double free of dangling pointer + - drm/sun4i: backend: Support alpha property on lowest plane + - drm/sun4i: backend: Disable alpha on the lowest plane on the A20 + - mmc: sdhci-acpi: Clear amd_sdhci_host on reset + - mmc: sdhci-msm: Add retries when all tuning phases are found valid + - spi: stm32: Rate-limit the 'Communication suspended' message + - nvme-fabrics: allow to queue requests for live queues + - spi: stm32: fix pm_runtime_get_sync() error checking + - block: Set same_page to false in __bio_try_merge_page if ret is false + - IB/isert: Fix unaligned immediate-data handling + - ARM: dts: bcm: HR2: Fixed QSPI compatible string + - ARM: dts: NSP: Fixed QSPI compatible string + - ARM: dts: BCM5301X: Fixed QSPI compatible string + - arm64: dts: ns2: Fixed QSPI compatible string + - ARC: HSDK: wireup perf irq + - dmaengine: acpi: Put the CSRT table after using it + - netfilter: conntrack: allow sctp hearbeat after connection re-use + - drivers/net/wan/lapbether: Added needed_tailroom + - NFC: st95hf: Fix memleak in st95hf_in_send_cmd + - firestream: Fix memleak in fs_open + - ALSA: hda: Fix 2 channel swapping for Tegra + - ALSA: hda/tegra: Program WAKEEN register for Tegra + - drivers/dma/dma-jz4780: Fix race condition between probe and irq handler + - net: hns3: Fix for geneve tx checksum bug + - xfs: fix off-by-one in inode alloc block reservation calculation + - drivers/net/wan/lapbether: Set network_header before transmitting + - cfg80211: Adjust 6 GHz frequency to channel conversion + - xfs: initialize the shortform attr header padding entry + - irqchip/eznps: Fix build error for !ARC700 builds + - nvmet-tcp: Fix NULL dereference when a connect data comes in h2cdata pdu + - nvme-fabrics: don't check state NVME_CTRL_NEW for request acceptance + - nvme: have nvme_wait_freeze_timeout return if it timed out + - nvme-tcp: serialize controller teardown sequences + - nvme-tcp: fix timeout handler + - nvme-tcp: fix reset hang if controller died in the middle of a reset + - nvme-rdma: serialize controller teardown sequences + - nvme-rdma: fix timeout handler + - nvme-rdma: fix reset hang if controller died in the middle of a reset + - nvme-pci: cancel nvme device request before disabling + - HID: quirks: Set INCREMENT_USAGE_ON_DUPLICATE for all Saitek X52 devices + - HID: microsoft: Add rumble support for the 8bitdo SN30 Pro+ controller + - drivers/net/wan/hdlc_cisco: Add hard_header_len + - HID: elan: Fix memleak in elan_input_configured + - ARC: [plat-hsdk]: Switch ethernet phy-mode to rgmii-id + - cpufreq: intel_pstate: Refuse to turn off with HWP enabled + - cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled + - arm64/module: set trampoline section flags regardless of + CONFIG_DYNAMIC_FTRACE + - ALSA: hda: hdmi - add Rocketlake support + - ALSA: hda: fix a runtime pm issue in SOF when integrated GPU is disabled + - drm/amdgpu: Fix bug in reporting voltage for CIK + - iommu/amd: Do not use IOMMUv2 functionality when SME is active + - gcov: Disable gcov build with GCC 10 + - iio: adc: ti-ads1015: fix conversion when CONFIG_PM is not set + - iio: cros_ec: Set Gyroscope default frequency to 25Hz + - iio:light:ltr501 Fix timestamp alignment issue. + - iio:proximity:mb1232: Fix timestamp alignment and prevent data leak. + - iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak. + - iio:adc:ti-adc084s021 Fix alignment and data leak issues. + - iio:adc:ina2xx Fix timestamp alignment issue. + - iio:adc:max1118 Fix alignment of timestamp and data leak issues + - iio:adc:ti-adc081c Fix alignment and data leak issues + - iio:magnetometer:ak8975 Fix alignment and data leak issues. + - iio:light:max44000 Fix timestamp alignment and prevent data leak. + - iio:chemical:ccs811: Fix timestamp alignment and prevent data leak. + - iio: accel: kxsd9: Fix alignment of local buffer. + - iio:accel:mma7455: Fix timestamp alignment and prevent data leak. + - iio:accel:mma8452: Fix timestamp alignment and prevent data leak. + - staging: wlan-ng: fix out of bounds read in prism2sta_probe_usb() + - btrfs: require only sector size alignment for parent eb bytenr + - btrfs: fix lockdep splat in add_missing_dev + - btrfs: fix wrong address when faulting in pages in the search ioctl + - kobject: Restore old behaviour of kobject_del(NULL) + - regulator: push allocation in regulator_init_coupling() outside of lock + - regulator: push allocations in create_regulator() outside of lock + - regulator: push allocation in set_consumer_device_supply() out of lock + - regulator: plug of_node leak in regulator_register()'s error path + - regulator: core: Fix slab-out-of-bounds in regulator_unlock_recursive() + - scsi: target: iscsi: Fix data digest calculation + - scsi: target: iscsi: Fix hang in iscsit_access_np() when getting + tpg->np_login_sem + - drm/i915/gvt: do not check len & max_len for lri + - drm/tve200: Stabilize enable/disable + - drm/msm: Disable preemption on all 5xx targets + - mmc: sdio: Use mmc_pre_req() / mmc_post_req() + - mmc: sdhci-of-esdhc: Don't walk device-tree on every interrupt + - rbd: require global CAP_SYS_ADMIN for mapping and unmapping + - RDMA/rxe: Fix the parent sysfs read when the interface has 15 chars + - RDMA/mlx4: Read pkey table length instead of hardcoded value + - fbcon: remove soft scrollback code + - fbcon: remove now unusued 'softback_lines' cursor() argument + - vgacon: remove software scrollback support + - [Config] updateconfigs for VGACON_SOFT_SCROLLBACK + - KVM: VMX: Don't freeze guest when event delivery causes an APIC-access exit + - KVM: arm64: Do not try to map PUDs when they are folded into PMD + - KVM: fix memory leak in kvm_io_bus_unregister_dev() + - debugfs: Fix module state check condition + - ARM: dts: vfxxx: Add syscon compatible with OCOTP + - video: fbdev: fix OOB read in vga_8planes_imageblit() + - staging: greybus: audio: fix uninitialized value issue + - phy: qcom-qmp: Use correct values for ipq8074 PCIe Gen2 PHY init + - usb: core: fix slab-out-of-bounds Read in read_descriptors + - USB: serial: ftdi_sio: add IDs for Xsens Mti USB converter + - USB: serial: option: support dynamic Quectel USB compositions + - USB: serial: option: add support for SIM7070/SIM7080/SIM7090 modules + - usb: Fix out of sync data toggle if a configured device is reconfigured + - usb: typec: ucsi: acpi: Check the _DEP dependencies + - drm/msm/gpu: make ringbuffer readonly + - drm/msm: Disable the RPTR shadow + - gcov: add support for GCC 10.1 + - Linux 5.4.66 + + [ Ubuntu: 5.4.0-54.60 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + * Introduce the new NVIDIA 455 series (LP: #1902093) + - [Packaging] NVIDIA -- Add the NVIDIA 455 driver + + -- Kleber Sacilotto de Souza Fri, 13 Nov 2020 13:15:32 +0100 + +linux-oracle (5.4.0-1029.31) focal; urgency=medium + + * CVE-2020-12351 // CVE-2020-12352 // CVE-2020-24490 + - [Config] oracle: Disable BlueZ highspeed support + + [ Ubuntu: 5.4.0-53.59 ] + + * CVE-2020-8694 + - powercap: make attributes only readable by root + + [ Ubuntu: 5.4.0-52.57 ] + + * focal/linux: 5.4.0-52.57 -proposed tracker (LP: #1899920) + * CVE-2020-12351 // CVE-2020-12352 // CVE-2020-24490 + - Bluetooth: Disable High Speed by default + - Bluetooth: MGMT: Fix not checking if BT_HS is enabled + - [Config] Disable BlueZ highspeed support + * CVE-2020-12351 + - Bluetooth: L2CAP: Fix calling sk_filter on non-socket based channel + * CVE-2020-12352 + - Bluetooth: A2MP: Fix not initializing all members + + -- Kleber Sacilotto de Souza Wed, 21 Oct 2020 14:51:22 +0200 + +linux-oracle (5.4.0-1028.29) focal; urgency=medium + + [ Ubuntu: 5.4.0-51.56 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Tue, 06 Oct 2020 11:52:22 +0200 + +linux-oracle (5.4.0-1027.28) focal; urgency=medium + + [ Ubuntu: 5.4.0-50.55 ] + + * CVE-2020-16119 + - SAUCE: dccp: avoid double free of ccid on child socket + * CVE-2020-16120 + - Revert "UBUNTU: SAUCE: overlayfs: ensure mounter privileges when reading + directories" + - ovl: pass correct flags for opening real directory + - ovl: switch to mounter creds in readdir + - ovl: verify permissions in ovl_path_open() + - ovl: call secutiry hook in ovl_real_ioctl() + - ovl: check permission to open real file + + -- Kleber Sacilotto de Souza Thu, 01 Oct 2020 11:14:15 +0200 + +linux-oracle (5.4.0-1026.26) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1026.26 -proposed tracker (LP: #1896002) + + * Focal update: v5.4.61 upstream stable release (LP: #1893115) + - oracle: [Config] update config for SPI_DYNAMIC + + [ Ubuntu: 5.4.0-49.53 ] + + * focal/linux: 5.4.0-49.53 -proposed tracker (LP: #1896007) + * Comet Lake PCH-H RAID not support on Ubuntu20.04 (LP: #1892288) + - ahci: Add Intel Comet Lake PCH-H PCI ID + * Novalink (mkvterm command failure) (LP: #1892546) + - tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup() + * Oops and hang when starting LVM snapshots on 5.4.0-47 (LP: #1894780) + - SAUCE: Revert "mm: memcg/slab: fix memory leak at non-root kmem_cache + destroy" + * Intel x710 LOMs do not work on Focal (LP: #1893956) + - i40e: Fix LED blinking flow for X710T*L devices + - i40e: enable X710 support + * Add/Backport EPYC-v3 and EPYC-Rome CPU model (LP: #1887490) + - kvm: svm: Update svm_xsaves_supported + * Fix non-working NVMe after S3 (LP: #1895718) + - SAUCE: PCI: Enable ACS quirk on CML root port + * Focal update: v5.4.65 upstream stable release (LP: #1895881) + - ipv4: Silence suspicious RCU usage warning + - ipv6: Fix sysctl max for fib_multipath_hash_policy + - netlabel: fix problems with mapping removal + - net: usb: dm9601: Add USB ID of Keenetic Plus DSL + - sctp: not disable bh in the whole sctp_get_port_local() + - taprio: Fix using wrong queues in gate mask + - tipc: fix shutdown() of connectionless socket + - net: disable netpoll on fresh napis + - Linux 5.4.65 + * Focal update: v5.4.64 upstream stable release (LP: #1895880) + - HID: quirks: Always poll three more Lenovo PixArt mice + - drm/msm/dpu: Fix scale params in plane validation + - tty: serial: qcom_geni_serial: Drop __init from qcom_geni_console_setup + - drm/msm: add shutdown support for display platform_driver + - hwmon: (applesmc) check status earlier. + - nvmet: Disable keep-alive timer when kato is cleared to 0h + - drm/msm: enable vblank during atomic commits + - habanalabs: validate FW file size + - habanalabs: check correct vmalloc return code + - drm/msm/a6xx: fix gmu start on newer firmware + - ceph: don't allow setlease on cephfs + - drm/omap: fix incorrect lock state + - cpuidle: Fixup IRQ state + - nbd: restore default timeout when setting it to zero + - s390: don't trace preemption in percpu macros + - drm/amd/display: Reject overlay plane configurations in multi-display + scenarios + - drivers: gpu: amd: Initialize amdgpu_dm_backlight_caps object to 0 in + amdgpu_dm_update_backlight_caps + - drm/amd/display: Retry AUX write when fail occurs + - drm/amd/display: Fix memleak in amdgpu_dm_mode_config_init + - xen/xenbus: Fix granting of vmalloc'd memory + - fsldma: fix very broken 32-bit ppc ioread64 functionality + - dmaengine: of-dma: Fix of_dma_router_xlate's of_dma_xlate handling + - batman-adv: Avoid uninitialized chaddr when handling DHCP + - batman-adv: Fix own OGM check in aggregated OGMs + - batman-adv: bla: use netif_rx_ni when not in interrupt context + - dmaengine: at_hdmac: check return value of of_find_device_by_node() in + at_dma_xlate() + - rxrpc: Keep the ACK serial in a var in rxrpc_input_ack() + - rxrpc: Make rxrpc_kernel_get_srtt() indicate validity + - MIPS: mm: BMIPS5000 has inclusive physical caches + - MIPS: BMIPS: Also call bmips_cpu_setup() for secondary cores + - mmc: sdhci-acpi: Fix HS400 tuning for AMDI0040 + - netfilter: nf_tables: add NFTA_SET_USERDATA if not null + - netfilter: nf_tables: incorrect enum nft_list_attributes definition + - netfilter: nf_tables: fix destination register zeroing + - net: hns: Fix memleak in hns_nic_dev_probe + - net: systemport: Fix memleak in bcm_sysport_probe + - ravb: Fixed to be able to unload modules + - net: arc_emac: Fix memleak in arc_mdio_probe + - dmaengine: pl330: Fix burst length if burst size is smaller than bus width + - gtp: add GTPA_LINK info to msg sent to userspace + - net: ethernet: ti: cpsw: fix clean up of vlan mc entries for host port + - bnxt_en: Don't query FW when netif_running() is false. + - bnxt_en: Check for zero dir entries in NVRAM. + - bnxt_en: Fix PCI AER error recovery flow + - bnxt_en: Fix possible crash in bnxt_fw_reset_task(). + - bnxt_en: fix HWRM error when querying VF temperature + - xfs: fix boundary test in xfs_attr_shortform_verify + - bnxt: don't enable NAPI until rings are ready + - media: vicodec: add missing v4l2_ctrl_request_hdl_put() + - media: cedrus: Add missing v4l2_ctrl_request_hdl_put() + - selftests/bpf: Fix massive output from test_maps + - net: dsa: mt7530: fix advertising unsupported 1000baseT_Half + - netfilter: nfnetlink: nfnetlink_unicast() reports EAGAIN instead of ENOBUFS + - nvmet-fc: Fix a missed _irqsave version of spin_lock in + 'nvmet_fc_fod_op_done()' + - nvme: fix controller instance leak + - cxgb4: fix thermal zone device registration + - perf tools: Correct SNOOPX field offset + - net: ethernet: mlx4: Fix memory allocation in mlx4_buddy_init() + - fix regression in "epoll: Keep a reference on files added to the check list" + - net: gemini: Fix another missing clk_disable_unprepare() in probe + - MIPS: add missing MSACSR and upper MSA initialization + - xfs: fix xfs_bmap_validate_extent_raw when checking attr fork of rt files + - perf jevents: Fix suspicious code in fixregex() + - tg3: Fix soft lockup when tg3_reset_task() fails. + - x86, fakenuma: Fix invalid starting node ID + - iommu/vt-d: Serialize IOMMU GCMD register modifications + - thermal: ti-soc-thermal: Fix bogus thermal shutdowns for omap4430 + - thermal: qcom-spmi-temp-alarm: Don't suppress negative temp + - iommu/amd: Restore IRTE.RemapEn bit after programming IRTE + - include/linux/log2.h: add missing () around n in roundup_pow_of_two() + - iommu/vt-d: Handle 36bit addressing for x86-32 + - tracing/kprobes, x86/ptrace: Fix regs argument order for i386 + - ext2: don't update mtime on COW faults + - xfs: don't update mtime on COW faults + - ARC: perf: don't bail setup if pct irq missing in device-tree + - btrfs: drop path before adding new uuid tree entry + - btrfs: allocate scrub workqueues outside of locks + - btrfs: set the correct lockdep class for new nodes + - btrfs: set the lockdep class for log tree extent buffers + - btrfs: tree-checker: fix the error message for transid error + - net: core: use listified Rx for GRO_NORMAL in napi_gro_receive() + - btrfs: fix potential deadlock in the search ioctl + - ALSA: ca0106: fix error code handling + - ALSA: usb-audio: Add implicit feedback quirk for UR22C + - ALSA: pcm: oss: Remove superfluous WARN_ON() for mulaw sanity check + - ALSA: hda/hdmi: always check pin power status in i915 pin fixup + - ALSA: firewire-digi00x: exclude Avid Adrenaline from detection + - ALSA: hda - Fix silent audio output and corrupted input on MSI X570-A PRO + - ALSA; firewire-tascam: exclude Tascam FE-8 from detection + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Book Ion NT950XCJ-X716A + - ALSA: hda/realtek - Improved routing for Thinkpad X1 7th/8th Gen + - arm64: dts: mt7622: add reset node for mmc device + - mmc: mediatek: add optional module reset property + - mmc: dt-bindings: Add resets/reset-names for Mediatek MMC bindings + - mmc: cqhci: Add cqhci_deactivate() + - mmc: sdhci-pci: Fix SDHCI_RESET_ALL for CQHCI for Intel GLK-based + controllers + - media: rc: do not access device via sysfs after rc_unregister_device() + - media: rc: uevent sysfs file races with rc_unregister_device() + - affs: fix basic permission bits to actually work + - block: allow for_each_bvec to support zero len bvec + - block: ensure bdi->io_pages is always initialized + - libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks + - blk-iocost: ioc_pd_free() shouldn't assume irq disabled + - dmaengine: dw-edma: Fix scatter-gather address calculation + - drm/amd/pm: avoid false alarm due to confusing softwareshutdowntemp setting + - dm writecache: handle DAX to partitions on persistent memory correctly + - dm mpath: fix racey management of PG initialization + - dm integrity: fix error reporting in bitmap mode after creation + - dm crypt: Initialize crypto wait structures + - dm cache metadata: Avoid returning cmd->bm wild pointer on error + - dm thin metadata: Avoid returning cmd->bm wild pointer on error + - dm thin metadata: Fix use-after-free in dm_bm_set_read_only + - mm: slub: fix conversion of freelist_corrupted() + - mm: madvise: fix vma user-after-free + - vfio/pci: Fix SR-IOV VF handling with MMIO blocking + - perf record: Correct the help info of option "--no-bpf-event" + - sdhci: tegra: Add missing TMCLK for data timeout + - checkpatch: fix the usage of capture group ( ... ) + - mm/hugetlb: fix a race between hugetlb sysctl handlers + - mm/khugepaged.c: fix khugepaged's request size in collapse_file + - cfg80211: regulatory: reject invalid hints + - net: usb: Fix uninit-was-stored issue in asix_read_phy_addr() + - Linux 5.4.64 + * Focal update: v5.4.63 upstream stable release (LP: #1895879) + - HID: core: Correctly handle ReportSize being zero + - HID: core: Sanitize event code and type when mapping input + - perf record/stat: Explicitly call out event modifiers in the documentation + - drm/sched: Fix passing zero to 'PTR_ERR' warning v2 + - drm/etnaviv: fix TS cache flushing on GPUs with BLT engine + - KVM: arm64: Add kvm_extable for vaxorcism code + - KVM: arm64: Survive synchronous exceptions caused by AT instructions + - KVM: arm64: Set HCR_EL2.PTW to prevent AT taking synchronous exception + - dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later + - arm64: tegra: Add missing timeout clock to Tegra194 SDMMC nodes + - arm64: tegra: Add missing timeout clock to Tegra186 SDMMC nodes + - arm64: tegra: Add missing timeout clock to Tegra210 SDMMC + - sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210 + - sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186 + - scsi: target: tcmu: Fix size in calls to tcmu_flush_dcache_range + - scsi: target: tcmu: Optimize use of flush_dcache_page + - Linux 5.4.63 + * Focal update: v5.4.62 upstream stable release (LP: #1895174) + - binfmt_flat: revert "binfmt_flat: don't offset the data start" + - gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY + - net: Fix potential wrong skb->protocol in skb_vlan_untag() + - net: nexthop: don't allow empty NHA_GROUP + - net: qrtr: fix usage of idr in port assignment to socket + - net: sctp: Fix negotiation of the number of data streams. + - net/smc: Prevent kernel-infoleak in __smc_diag_dump() + - tipc: fix uninit skb->data in tipc_nl_compat_dumpit() + - net: ena: Make missed_tx stat incremental + - net/sched: act_ct: Fix skb double-free in tcf_ct_handle_fragments() error + flow + - ipvlan: fix device features + - ALSA: pci: delete repeated words in comments + - ASoC: img: Fix a reference count leak in img_i2s_in_set_fmt + - ASoC: img-parallel-out: Fix a reference count leak + - ASoC: tegra: Fix reference count leaks. + - mfd: intel-lpss: Add Intel Emmitsburg PCH PCI IDs + - arm64: dts: qcom: msm8916: Pull down PDM GPIOs during sleep + - powerpc/xive: Ignore kmemleak false positives + - media: pci: ttpci: av7110: fix possible buffer overflow caused by bad DMA + value in debiirq() + - blktrace: ensure our debugfs dir exists + - scsi: target: tcmu: Fix crash on ARM during cmd completion + - mfd: intel-lpss: Add Intel Tiger Lake PCH-H PCI IDs + - iommu/iova: Don't BUG on invalid PFNs + - drm/amdkfd: Fix reference count leaks. + - drm/radeon: fix multiple reference count leak + - drm/amdgpu: fix ref count leak in amdgpu_driver_open_kms + - drm/amd/display: fix ref count leak in amdgpu_drm_ioctl + - drm/amdgpu: fix ref count leak in amdgpu_display_crtc_set_config + - drm/amdgpu/display: fix ref count leak when pm_runtime_get_sync fails + - scsi: lpfc: Fix shost refcount mismatch when deleting vport + - xfs: Don't allow logging of XFS_ISTALE inodes + - scsi: target: Fix xcopy sess release leak + - selftests/powerpc: Purge extra count_pmc() calls of ebb selftests + - f2fs: fix error path in do_recover_data() + - omapfb: fix multiple reference count leaks due to pm_runtime_get_sync + - PCI: Fix pci_create_slot() reference count leak + - ARM: dts: ls1021a: output PPS signal on FIPER2 + - rtlwifi: rtl8192cu: Prevent leaking urb + - mips/vdso: Fix resource leaks in genvdso.c + - cec-api: prevent leaking memory through hole in structure + - HID: quirks: add NOGET quirk for Logitech GROUP + - f2fs: fix use-after-free issue + - drm/nouveau/drm/noveau: fix reference count leak in nouveau_fbcon_open + - drm/nouveau: fix reference count leak in nv50_disp_atomic_commit + - drm/nouveau: Fix reference count leak in nouveau_connector_detect + - locking/lockdep: Fix overflow in presentation of average lock-time + - btrfs: file: reserve qgroup space after the hole punch range is locked + - btrfs: make btrfs_qgroup_check_reserved_leak take btrfs_inode + - scsi: iscsi: Do not put host in iscsi_set_flashnode_param() + - ceph: fix potential mdsc use-after-free crash + - ceph: do not access the kiocb after aio requests + - scsi: fcoe: Memory leak fix in fcoe_sysfs_fcf_del() + - EDAC/ie31200: Fallback if host bridge device is already initialized + - hugetlbfs: prevent filesystem stacking of hugetlbfs + - media: davinci: vpif_capture: fix potential double free + - KVM: arm64: Fix symbol dependency in __hyp_call_panic_nvhe + - powerpc/spufs: add CONFIG_COREDUMP dependency + - USB: sisusbvga: Fix a potential UB casued by left shifting a negative value + - brcmfmac: Set timeout value when configuring power save + - efi: provide empty efi_enter_virtual_mode implementation + - arm64: Fix __cpu_logical_map undefined issue + - Revert "ath10k: fix DMA related firmware crashes on multiple devices" + - sched/uclamp: Protect uclamp fast path code with static key + - sched/uclamp: Fix a deadlock when enabling uclamp static key + - usb: cdns3: gadget: always zeroed TRB buffer when enable endpoint + - PM / devfreq: rk3399_dmc: Add missing of_node_put() + - PM / devfreq: rk3399_dmc: Disable devfreq-event device when fails + - PM / devfreq: rk3399_dmc: Fix kernel oops when rockchip,pmu is absent + - drm/xen: fix passing zero to 'PTR_ERR' warning + - drm/xen-front: Fix misused IS_ERR_OR_NULL checks + - s390/numa: set node distance to LOCAL_DISTANCE + - btrfs: factor out inode items copy loop from btrfs_log_inode() + - btrfs: only commit the delayed inode when doing a full fsync + - btrfs: only commit delayed items at fsync if we are logging a directory + - mm/shuffle: don't move pages between zones and don't read garbage memmaps + - mm: fix kthread_use_mm() vs TLB invalidate + - mm/cma.c: switch to bitmap_zalloc() for cma bitmap allocation + - cma: don't quit at first error when activating reserved areas + - gpu/drm: ingenic: Use the plane's src_[x,y] to configure DMA length + - drm/ingenic: Fix incorrect assumption about plane->index + - drm/amd/display: Trigger modesets on MST DSC connectors + - drm/amd/display: Add additional config guards for DCN + - drm/amd/display: Fix dmesg warning from setting abm level + - mm/vunmap: add cond_resched() in vunmap_pmd_range + - EDAC: sb_edac: get rid of unused vars + - EDAC: skx_common: get rid of unused type var + - EDAC/{i7core,sb,pnd2,skx}: Fix error event severity + - PCI: qcom: Add missing ipq806x clocks in PCIe driver + - PCI: qcom: Change duplicate PCI reset to phy reset + - PCI: qcom: Add missing reset for ipq806x + - cpufreq: intel_pstate: Fix EPP setting via sysfs in active mode + - ALSA: usb-audio: Add capture support for Saffire 6 (USB 1.1) + - media: gpio-ir-tx: improve precision of transmitted signal due to scheduling + - block: respect queue limit of max discard segment + - block: virtio_blk: fix handling single range discard request + - drm/msm/adreno: fix updating ring fence + - block: Fix page_is_mergeable() for compound pages + - bfq: fix blkio cgroup leakage v4 + - hwmon: (nct7904) Correct divide by 0 + - blk-mq: insert request not through ->queue_rq into sw/scheduler queue + - blkcg: fix memleak for iolatency + - nvme-fc: Fix wrong return value in __nvme_fc_init_request() + - nvme: multipath: round-robin: fix single non-optimized path case + - null_blk: fix passing of REQ_FUA flag in null_handle_rq + - i2c: core: Don't fail PRP0001 enumeration when no ID table exist + - i2c: rcar: in slave mode, clear NACK earlier + - usb: gadget: f_tcm: Fix some resource leaks in some error paths + - spi: stm32: clear only asserted irq flags on interrupt + - jbd2: make sure jh have b_transaction set in refile/unfile_buffer + - ext4: don't BUG on inconsistent journal feature + - ext4: handle read only external journal device + - jbd2: abort journal if free a async write error metadata buffer + - ext4: handle option set by mount flags correctly + - ext4: handle error of ext4_setup_system_zone() on remount + - ext4: correctly restore system zone info when remount fails + - fs: prevent BUG_ON in submit_bh_wbc() + - spi: stm32h7: fix race condition at end of transfer + - spi: stm32: fix fifo threshold level in case of short transfer + - spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate + - spi: stm32: always perform registers configuration prior to transfer + - drm/amd/powerplay: correct Vega20 cached smu feature state + - drm/amd/powerplay: correct UVD/VCE PG state on custom pptable uploading + - drm/amd/display: Switch to immediate mode for updating infopackets + - netfilter: avoid ipv6 -> nf_defrag_ipv6 module dependency + - can: j1939: transport: j1939_xtp_rx_dat_one(): compare own packets to detect + corruptions + - ALSA: hda/realtek: Add model alc298-samsung-headphone + - s390/cio: add cond_resched() in the slow_eval_known_fn() loop + - ASoC: wm8994: Avoid attempts to read unreadable registers + - selftests: disable rp_filter for icmp_redirect.sh + - scsi: fcoe: Fix I/O path allocation + - scsi: ufs: Fix possible infinite loop in ufshcd_hold + - scsi: ufs: Improve interrupt handling for shared interrupts + - scsi: ufs: Clean up completed request without interrupt notification + - scsi: qla2xxx: Fix login timeout + - scsi: qla2xxx: Check if FW supports MQ before enabling + - scsi: qla2xxx: Fix null pointer access during disconnect from subsystem + - Revert "scsi: qla2xxx: Fix crash on qla2x00_mailbox_command" + - macvlan: validate setting of multiple remote source MAC addresses + - net: gianfar: Add of_node_put() before goto statement + - powerpc/perf: Fix soft lockups due to missed interrupt accounting + - arm64: Move handling of erratum 1418040 into C code + - arm64: Allow booting of late CPUs affected by erratum 1418040 + - block: fix get_max_io_size() + - block: loop: set discard granularity and alignment for block device backed + loop + - HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands + - blk-mq: order adding requests to hctx->dispatch and checking SCHED_RESTART + - btrfs: reset compression level for lzo on remount + - btrfs: check the right error variable in btrfs_del_dir_entries_in_log + - btrfs: fix space cache memory leak after transaction abort + - btrfs: detect nocow for swap after snapshot delete + - fbcon: prevent user font height or width change from causing potential out- + of-bounds access + - USB: lvtest: return proper error code in probe + - vt: defer kfree() of vc_screenbuf in vc_do_resize() + - vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize() + - serial: samsung: Removes the IRQ not found warning + - serial: pl011: Fix oops on -EPROBE_DEFER + - serial: pl011: Don't leak amba_ports entry on driver register error + - serial: stm32: avoid kernel warning on absence of optional IRQ + - serial: 8250_exar: Fix number of ports for Commtech PCIe cards + - serial: 8250: change lock order in serial8250_do_startup() + - writeback: Protect inode->i_io_list with inode->i_lock + - writeback: Avoid skipping inode writeback + - writeback: Fix sync livelock due to b_dirty_time processing + - XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN + data pointer which contains XEN specific information. + - usb: host: xhci: fix ep context print mismatch in debugfs + - xhci: Do warm-reset when both CAS and XDEV_RESUME are set + - xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed + - ARM64: vdso32: Install vdso32 from vdso_install + - arm64: vdso32: make vdso32 install conditional + - PM: sleep: core: Fix the handling of pending runtime resume requests + - powerpc/perf: Fix crashes with generic_compat_pmu & BHRB + - device property: Fix the secondary firmware node handling in + set_primary_fwnode() + - crypto: af_alg - Work around empty control messages without MSG_MORE + - genirq/matrix: Deal with the sillyness of for_each_cpu() on UP + - irqchip/stm32-exti: Avoid losing interrupts due to clearing pending bits by + mistake + - x86/hotplug: Silence APIC only after all interrupts are migrated + - drm/amdgpu: Fix buffer overflow in INFO ioctl + - drm/amdgpu/gfx10: refine mgcg setting + - drm/amd/powerplay: Fix hardmins not being sent to SMU for RV + - drm/amd/pm: correct Vega10 swctf limit setting + - drm/amd/pm: correct Vega12 swctf limit setting + - drm/amd/pm: correct Vega20 swctf limit setting + - drm/amd/pm: correct the thermal alert temperature limit settings + - USB: yurex: Fix bad gfp argument + - usb: uas: Add quirk for PNY Pro Elite + - USB: quirks: Ignore duplicate endpoint on Sound Devices MixPre-D + - USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge + - usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe() + - USB: gadget: u_f: add overflow checks to VLA macros + - USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb() + - USB: gadget: u_f: Unbreak offset calculation in VLAs + - USB: cdc-acm: rework notification_buffer resizing + - usb: storage: Add unusual_uas entry for Sony PSZ drives + - drm/i915: Fix cmd parser desc matching with masks + - usb: dwc3: gadget: Don't setup more than requested + - usb: dwc3: gadget: Fix handling ZLP + - usb: dwc3: gadget: Handle ZLP for sg requests + - fbmem: pull fbcon_update_vcs() out of fb_set_var() + - kheaders: remove unneeded 'cat' command piped to 'head' / 'tail' + - kheaders: optimize md5sum calculation for in-tree builds + - kheaders: optimize header copy for in-tree builds + - kheaders: remove the last bashism to allow sh to run it + - kheaders: explain why include/config/autoconf.h is excluded from md5sum + - kbuild: add variables for compression tools + - kbuild: fix broken builds because of GZIP,BZIP2,LZOP variables + - HID: hiddev: Fix slab-out-of-bounds write in hiddev_ioctl_usage() + - ALSA: usb-audio: Update documentation comment for MS2109 quirk + - io_uring: Fix NULL pointer dereference in io_sq_wq_submit_work() + - Linux 5.4.62 + * DELL LATITUDE 5491 touchscreen doesn't work (LP: #1889446) // Focal update: + v5.4.62 upstream stable release (LP: #1895174) + - USB: quirks: Add no-lpm quirk for another Raydium touchscreen + * [NUC8CCHK][HDA-Intel - HDA Intel PCH, playback] No sound at all + (LP: #1875199) // Focal update: v5.4.62 upstream stable release + (LP: #1895174) + - ALSA: hda/realtek: Fix pin default on Intel NUC 8 Rugged + * Focal update: v5.4.61 upstream stable release (LP: #1893115) + - Documentation/llvm: add documentation on building w/ Clang/LLVM + - Documentation/llvm: fix the name of llvm-size + - net: wan: wanxl: use allow to pass CROSS_COMPILE_M68k for rebuilding + firmware + - net: wan: wanxl: use $(M68KCC) instead of $(M68KAS) for rebuilding firmware + - x86/boot: kbuild: allow readelf executable to be specified + - kbuild: remove PYTHON2 variable + - kbuild: remove AS variable + - kbuild: replace AS=clang with LLVM_IAS=1 + - kbuild: support LLVM=1 to switch the default tools to Clang/LLVM + - drm/vgem: Replace opencoded version of drm_gem_dumb_map_offset() + - gfs2: Improve mmap write vs. punch_hole consistency + - gfs2: Never call gfs2_block_zero_range with an open transaction + - perf probe: Fix memory leakage when the probe point is not found + - khugepaged: khugepaged_test_exit() check mmget_still_valid() + - khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter() + - bcache: avoid nr_stripes overflow in bcache_device_init() + - btrfs: export helpers for subvolume name/id resolution + - btrfs: don't show full path of bind mounts in subvol= + - btrfs: return EROFS for BTRFS_FS_STATE_ERROR cases + - btrfs: add wrapper for transaction abort predicate + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Flex Book + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Book Ion + - can: j1939: transport: j1939_session_tx_dat(): fix use-after-free read in + j1939_tp_txtimer() + - can: j1939: socket: j1939_sk_bind(): make sure ml_priv is allocated + - [Config] update config for SPI_DYNAMIC + - spi: Prevent adding devices below an unregistering controller + - romfs: fix uninitialized memory leak in romfs_dev_read() + - kernel/relay.c: fix memleak on destroy relay channel + - uprobes: __replace_page() avoid BUG in munlock_vma_page() + - mm: include CMA pages in lowmem_reserve at boot + - mm, page_alloc: fix core hung in free_pcppages_bulk() + - RDMA/hfi1: Correct an interlock issue for TID RDMA WRITE request + - ext4: fix checking of directory entry validity for inline directories + - jbd2: add the missing unlock_buffer() in the error path of + jbd2_write_superblock() + - scsi: zfcp: Fix use-after-free in request timeout handlers + - drm/amdgpu/display: use GFP_ATOMIC in dcn20_validate_bandwidth_internal + - drm/amd/display: Fix EDID parsing after resume from suspend + - drm/amd/display: fix pow() crashing when given base 0 + - kthread: Do not preempt current task if it is going to call schedule() + - opp: Enable resources again if they were disabled earlier + - scsi: ufs: Add DELAY_BEFORE_LPM quirk for Micron devices + - scsi: target: tcmu: Fix crash in tcmu_flush_dcache_range on ARM + - media: budget-core: Improve exception handling in budget_register() + - rtc: goldfish: Enable interrupt in set_alarm() when necessary + - media: vpss: clean up resources in init + - Input: psmouse - add a newline when printing 'proto' by sysfs + - MIPS: Fix unable to reserve memory for Crash kernel + - m68knommu: fix overwriting of bits in ColdFire V3 cache control + - svcrdma: Fix another Receive buffer leak + - xfs: fix inode quota reservation checks + - drm/ttm: fix offset in VMAs with a pg_offs in ttm_bo_vm_access + - jffs2: fix UAF problem + - ceph: fix use-after-free for fsc->mdsc + - swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses + - cpufreq: intel_pstate: Fix cpuinfo_max_freq when MSR_TURBO_RATIO_LIMIT is 0 + - scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases + - virtio_ring: Avoid loop when vq is broken in virtqueue_poll + - media: camss: fix memory leaks on error handling paths in probe + - tools/testing/selftests/cgroup/cgroup_util.c: cg_read_strcmp: fix null + pointer dereference + - xfs: Fix UBSAN null-ptr-deref in xfs_sysfs_init + - alpha: fix annotation of io{read,write}{16,32}be() + - fs/signalfd.c: fix inconsistent return codes for signalfd4 + - ext4: fix potential negative array index in do_split() + - ext4: don't allow overlapping system zones + - netfilter: nf_tables: nft_exthdr: the presence return value should be + little-endian + - spi: stm32: fixes suspend/resume management + - ASoC: q6afe-dai: mark all widgets registers as SND_SOC_NOPM + - ASoC: q6routing: add dummy register read/write function + - bpf: sock_ops sk access may stomp registers when dst_reg = src_reg + - can: j1939: fix kernel-infoleak in j1939_sk_sock2sockaddr_can() + - can: j1939: transport: j1939_simple_recv(): ignore local J1939 messages send + not by J1939 stack + - can: j1939: transport: add j1939_session_skb_find_by_offset() function + - i40e: Set RX_ONLY mode for unicast promiscuous on VLAN + - i40e: Fix crash during removing i40e driver + - net: fec: correct the error path for regulator disable in probe + - bonding: show saner speed for broadcast mode + - can: j1939: fix support for multipacket broadcast message + - can: j1939: cancel rxtimer on multipacket broadcast session complete + - can: j1939: abort multipacket broadcast session when timeout occurs + - can: j1939: add rxtimer for multipacket broadcast session + - bonding: fix a potential double-unregister + - s390/runtime_instrumentation: fix storage key handling + - s390/ptrace: fix storage key handling + - ASoC: msm8916-wcd-analog: fix register Interrupt offset + - ASoC: intel: Fix memleak in sst_media_open + - vfio/type1: Add proper error unwind for vfio_iommu_replay() + - kvm: x86: Toggling CR4.SMAP does not load PDPTEs in PAE mode + - kvm: x86: Toggling CR4.PKE does not load PDPTEs in PAE mode + - Revert "scsi: qla2xxx: Disable T10-DIF feature with FC-NVMe during probe" + - kconfig: qconf: do not limit the pop-up menu to the first row + - kconfig: qconf: fix signal connection to invalid slots + - efi: avoid error message when booting under Xen + - Fix build error when CONFIG_ACPI is not set/enabled: + - RDMA/bnxt_re: Do not add user qps to flushlist + - afs: Fix NULL deref in afs_dynroot_depopulate() + - bonding: fix active-backup failover for current ARP slave + - net: ena: Prevent reset after device destruction + - net: gemini: Fix missing free_netdev() in error path of + gemini_ethernet_port_probe() + - hv_netvsc: Fix the queue_mapping in netvsc_vf_xmit() + - net: dsa: b53: check for timeout + - powerpc/pseries: Do not initiate shutdown when system is running on UPS + - efi: add missed destroy_workqueue when efisubsys_init fails + - epoll: Keep a reference on files added to the check list + - do_epoll_ctl(): clean the failure exits up a bit + - mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible + - xen: don't reschedule in preemption off sections + - KVM: Pass MMU notifier range flags to kvm_unmap_hva_range() + - KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set + - Linux 5.4.61 + * [UBUNTU 20.04] zPCI device hot-plug during boot may result in unusable + device (LP: #1893778) + - s390/pci: ignore stale configuration request event + * [SRU] [Focal/OEM-5.6/Groovy]Fix AMD usb host controller lost after stress S3 + (LP: #1893914) + - SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC + + -- William Breathitt Gray Mon, 21 Sep 2020 08:28:57 -0400 + +linux-oracle (5.4.0-1025.25) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1025.25 -proposed tracker (LP: #1894649) + + [ Ubuntu: 5.4.0-48.52 ] + + * focal/linux: 5.4.0-48.52 -proposed tracker (LP: #1894654) + * mm/slub kernel oops on focal kernel 5.4.0-45 (LP: #1895109) + - SAUCE: Revert "mm/slub: fix a memory leak in sysfs_slab_add()" + * Packaging resync (LP: #1786013) + - update dkms package versions + - update dkms package versions + * Introduce the new NVIDIA 450-server and the 450 UDA series (LP: #1887674) + - [packaging] add signed modules for nvidia 450 and 450-server + * [UBUNTU 20.04] zPCI attach/detach issues with PF/VF linking support + (LP: #1892849) + - s390/pci: fix zpci_bus_link_virtfn() + - s390/pci: re-introduce zpci_remove_device() + - s390/pci: fix PF/VF linking on hot plug + * [UBUNTU 20.04] kernel: s390/cpum_cf,perf: changeDFLT_CCERROR counter name + (LP: #1891454) + - s390/cpum_cf, perf: change DFLT_CCERROR counter name + * [UBUNTU 20.04] zPCI: Enabling of a reserved PCI function regression + introduced by multi-function support (LP: #1891437) + - s390/pci: fix enabling a reserved PCI function + * CVE-2020-12888 + - vfio/type1: Support faulting PFNMAP vmas + - vfio-pci: Fault mmaps to enable vma tracking + - vfio-pci: Invalidate mmaps and block MMIO access on disabled memory + * [Hyper-V] VSS and File Copy daemons intermittently fails to start + (LP: #1891224) + - [Packaging] Bind hv_vss_daemon startup to hv_vss device + - [Packaging] bind hv_fcopy_daemon startup to hv_fcopy device + * alsa/hdmi: support nvidia mst hdmi/dp audio (LP: #1867704) + - ALSA: hda - Rename snd_hda_pin_sense to snd_hda_jack_pin_sense + - ALSA: hda - Add DP-MST jack support + - ALSA: hda - Add DP-MST support for non-acomp codecs + - ALSA: hda - Add DP-MST support for NVIDIA codecs + - ALSA: hda: hdmi - fix regression in connect list handling + - ALSA: hda: hdmi - fix kernel oops caused by invalid PCM idx + - ALSA: hda: hdmi - preserve non-MST PCM routing for Intel platforms + - ALSA: hda: hdmi - Keep old slot assignment behavior for Intel platforms + - ALSA: hda - Fix DP-MST support for NVIDIA codecs + * Focal update: v5.4.60 upstream stable release (LP: #1892899) + - smb3: warn on confusing error scenario with sec=krb5 + - genirq/affinity: Make affinity setting if activated opt-in + - genirq/PM: Always unlock IRQ descriptor in rearm_wake_irq() + - PCI: hotplug: ACPI: Fix context refcounting in acpiphp_grab_context() + - PCI: Add device even if driver attach failed + - PCI: qcom: Define some PARF params needed for ipq8064 SoC + - PCI: qcom: Add support for tx term offset for rev 2.1.0 + - btrfs: allow use of global block reserve for balance item deletion + - btrfs: free anon block device right after subvolume deletion + - btrfs: don't allocate anonymous block device for user invisible roots + - btrfs: ref-verify: fix memory leak in add_block_entry + - btrfs: stop incremening log_batch for the log root tree when syncing log + - btrfs: remove no longer needed use of log_writers for the log root tree + - btrfs: don't traverse into the seed devices in show_devname + - btrfs: open device without device_list_mutex + - btrfs: move the chunk_mutex in btrfs_read_chunk_tree + - btrfs: relocation: review the call sites which can be interrupted by signal + - btrfs: add missing check for nocow and compression inode flags + - btrfs: avoid possible signal interruption of btrfs_drop_snapshot() on + relocation tree + - btrfs: sysfs: use NOFS for device creation + - btrfs: don't WARN if we abort a transaction with EROFS + - btrfs: fix race between page release and a fast fsync + - btrfs: fix messages after changing compression level by remount + - btrfs: only search for left_info if there is no right_info in + try_merge_free_space + - btrfs: inode: fix NULL pointer dereference if inode doesn't need compression + - btrfs: fix memory leaks after failure to lookup checksums during inode + logging + - btrfs: make sure SB_I_VERSION doesn't get unset by remount + - btrfs: fix return value mixup in btrfs_get_extent + - arm64: perf: Correct the event index in sysfs + - dt-bindings: iio: io-channel-mux: Fix compatible string in example code + - iio: dac: ad5592r: fix unbalanced mutex unlocks in ad5592r_read_raw() + - xtensa: add missing exclusive access state management + - xtensa: fix xtensa_pmu_setup prototype + - cifs: Fix leak when handling lease break for cached root fid + - powerpc/ptdump: Fix build failure in hashpagetable.c + - powerpc: Allow 4224 bytes of stack expansion for the signal frame + - powerpc: Fix circular dependency between percpu.h and mmu.h + - pinctrl: ingenic: Enhance support for IRQ_TYPE_EDGE_BOTH + - media: vsp1: dl: Fix NULL pointer dereference on unbind + - net: ethernet: stmmac: Disable hardware multicast filter + - net: stmmac: dwmac1000: provide multicast filter fallback + - net/compat: Add missing sock updates for SCM_RIGHTS + - md/raid5: Fix Force reconstruct-write io stuck in degraded raid5 + - bcache: allocate meta data pages as compound pages + - bcache: fix overflow in offset_to_stripe() + - mac80211: fix misplaced while instead of if + - driver core: Avoid binding drivers to dead devices + - MIPS: CPU#0 is not hotpluggable + - MIPS: qi_lb60: Fix routing to audio amplifier + - ext2: fix missing percpu_counter_inc + - khugepaged: collapse_pte_mapped_thp() flush the right range + - khugepaged: collapse_pte_mapped_thp() protect the pmd lock + - ocfs2: change slot number type s16 to u16 + - mm/page_counter.c: fix protection usage propagation + - mm/memory_hotplug: fix unpaired mem_hotplug_begin/done + - ftrace: Setup correct FTRACE_FL_REGS flags for module + - kprobes: Fix NULL pointer dereference at kprobe_ftrace_handler + - tracing/hwlat: Honor the tracing_cpumask + - tracing: Use trace_sched_process_free() instead of exit() for pid tracing + - tracing: Move pipe reference to trace array instead of current_tracer + - watchdog: f71808e_wdt: indicate WDIOF_CARDRESET support in + watchdog_info.options + - watchdog: f71808e_wdt: remove use of wrong watchdog_info option + - watchdog: f71808e_wdt: clear watchdog timeout occurred flag + - ceph: set sec_context xattr on symlink creation + - ceph: handle zero-length feature mask in session messages + - pseries: Fix 64 bit logical memory block panic + - module: Correctly truncate sysfs sections output + - perf intel-pt: Fix FUP packet state + - perf intel-pt: Fix duplicate branch after CBR + - remoteproc: qcom: q6v5: Update running state before requesting stop + - remoteproc: qcom_q6v5_mss: Validate MBA firmware size before load + - remoteproc: qcom_q6v5_mss: Validate modem blob firmware size before load + - drm/imx: imx-ldb: Disable both channels for split mode in enc->disable() + - orangefs: get rid of knob code... + - pinctrl: ingenic: Properly detect GPIO direction when configured for IRQ + - crypto: algif_aead - Only wake up when ctx->more is zero + - mfd: arizona: Ensure 32k clock is put on driver unbind and error + - octeontx2-af: change (struct qmem)->entry_sz from u8 to u16 + - mtd: rawnand: fsl_upm: Remove unused mtd var + - platform/chrome: cros_ec_ishtp: Fix a double-unlock issue + - RDMA/ipoib: Return void from ipoib_ib_dev_stop() + - RDMA/ipoib: Fix ABBA deadlock with ipoib_reap_ah() + - media: rockchip: rga: Introduce color fmt macros and refactor CSC mode logic + - media: rockchip: rga: Only set output CSC mode for RGB input + - IB/uverbs: Set IOVA on IB MR in uverbs layer + - selftests/bpf: Test_progs indicate to shell on non-actions + - selftests/bpf: test_progs use another shell exit on non-actions + - USB: serial: ftdi_sio: make process-packet buffer unsigned + - USB: serial: ftdi_sio: clean up receive processing + - crypto: af_alg - Fix regression on empty requests + - devres: keep both device name and resource name in pretty name + - RDMA/counter: Only bind user QPs in auto mode + - RDMA/counter: Allow manually bind QPs with different pids to same counter + - mmc: renesas_sdhi_internal_dmac: clean up the code for dma complete + - crypto: caam - Remove broken arc4 support + - gpu: ipu-v3: image-convert: Combine rotate/no-rotate irq handlers + - gpu: ipu-v3: image-convert: Wait for all EOFs before completing a tile + - dm rq: don't call blk_mq_queue_stopped() in dm_stop_queue() + - clk: actions: Fix h_clk for Actions S500 SoC + - selftests/powerpc: ptrace-pkey: Rename variables to make it easier to follow + code + - selftests/powerpc: ptrace-pkey: Update the test to mark an invalid pkey + correctly + - selftests/powerpc: ptrace-pkey: Don't update expected UAMOR value + - iommu/omap: Check for failure of a call to omap_iommu_dump_ctx + - clk: qcom: gcc: fix sm8150 GPU and NPU clocks + - clk: qcom: clk-alpha-pll: remove unused/incorrect PLL_CAL_VAL + - iommu/vt-d: Enforce PASID devTLB field mask + - i2c: rcar: slave: only send STOP event when we have been addressed + - clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk + - clk: clk-atlas6: fix return value check in atlas6_clk_init() + - pwm: bcm-iproc: handle clk_get_rate() return + - tools build feature: Use CC and CXX from parent + - i2c: rcar: avoid race when unregistering slave + - nfs: ensure correct writeback errors are returned on close() + - ubifs: Fix wrong orphan node deletion in ubifs_jnl_update|rename + - clk: bcm2835: Do not use prediv with bcm2711's PLLs + - libnvdimm/security: fix a typo + - libnvdimm/security: ensure sysfs poll thread woke up and fetch updated attr + - openrisc: Fix oops caused when dumping stack + - scsi: lpfc: nvmet: Avoid hang / use-after-free again when destroying + targetport + - nfs: nfs_file_write() should check for writeback errors + - watchdog: initialize device before misc_register + - md-cluster: Fix potential error pointer dereference in resize_bitmaps() + - x86/tsr: Fix tsc frequency enumeration bug on Lightning Mountain SoC + - Input: sentelic - fix error return when fsp_reg_write fails + - recordmcount: Fix build failure on non arm64 + - drm/vmwgfx: Use correct vmw_legacy_display_unit pointer + - drm/vmwgfx: Fix two list_for_each loop exit tests + - net: qcom/emac: add missed clk_disable_unprepare in error path of + emac_clks_phase1_init + - nfs: Fix getxattr kernel panic and memory overflow + - fs/minix: set s_maxbytes correctly + - fs/minix: fix block limit check for V1 filesystems + - fs/minix: remove expected error message in block_to_path() + - fs/ufs: avoid potential u32 multiplication overflow + - test_kmod: avoid potential double free in trigger_config_run_type() + - i2c: iproc: fix race between client unreg and isr + - mfd: dln2: Run event handler loop under spinlock + - crypto: algif_aead - fix uninitialized ctx->init + - ALSA: echoaudio: Fix potential Oops in snd_echo_resume() + - perf bench mem: Always memset source before memcpy + - tools build feature: Quote CC and CXX for their arguments + - perf/x86/rapl: Fix missing psys sysfs attributes + - sh: landisk: Add missing initialization of sh_io_port_base + - khugepaged: retract_page_tables() remember to test exit + - arm64: dts: marvell: espressobin: add ethernet alias + - drm/panfrost: Use kvfree() to free bo->sgts + - drm: Added orientation quirk for ASUS tablet model T103HAF + - drm: fix drm_dp_mst_port refcount leaks in drm_dp_mst_allocate_vcpi + - drm/amdgpu: Fix bug where DPM is not enabled after hibernate and resume + - drm/amd/display: dchubbub p-state warning during surface planes switch + - Linux 5.4.60 + - kprobes: Fix compiler warning for !CONFIG_KPROBES_ON_FTRACE + * Focal update: v5.4.59 upstream stable release (LP: #1892417) + - tracepoint: Mark __tracepoint_string's __used + - HID: input: Fix devices that return multiple bytes in battery report + - nvme: add a Identify Namespace Identification Descriptor list quirk + - fs/io_uring.c: Fix uninitialized variable is referenced in io_submit_sqe + - clk: qcom: clk-rpmh: Wait for completion when enabling clocks + - x86/mce/inject: Fix a wrong assignment of i_mce.status + - sched/fair: Fix NOHZ next idle balance + - sched: correct SD_flags returned by tl->sd_flags() + - arm64: dts: rockchip: fix rk3368-lion gmac reset gpio + - arm64: dts: rockchip: fix rk3399-puma vcc5v0-host gpio + - arm64: dts: rockchip: fix rk3399-puma gmac reset gpio + - EDAC: Fix reference count leaks + - crc-t10dif: Fix potential crypto notify dead-lock + - arm64: dts: qcom: msm8916: Replace invalid bias-pull-none property + - crypto: ccree - fix resource leak on error path + - ARM: exynos: MCPM: Restore big.LITTLE cpuidle support + - firmware: arm_scmi: Fix SCMI genpd domain probing + - arm64: dts: exynos: Fix silent hang after boot on Espresso + - sched/uclamp: Fix initialization of struct uclamp_rq + - clk: scmi: Fix min and max rate when registering clocks with discrete rates + - m68k: mac: Don't send IOP message until channel is idle + - m68k: mac: Fix IOP status/control register writes + - platform/x86: intel-hid: Fix return value check in check_acpi_dev() + - platform/x86: intel-vbtn: Fix return value check in check_acpi_dev() + - ARM: dts: gose: Fix ports node name for adv7180 + - ARM: dts: gose: Fix ports node name for adv7612 + - ARM: at91: pm: add missing put_device() call in at91_pm_sram_init() + - ARM: dts: sunxi: bananapi-m2-plus-v1.2: Add regulator supply to all CPU + cores + - ARM: dts: sunxi: bananapi-m2-plus-v1.2: Fix CPU supply voltages + - spi: lantiq: fix: Rx overflow error in full duplex mode + - tpm: Require that all digests are present in TCG_PCR_EVENT2 structures + - recordmcount: only record relocation of type R_AARCH64_CALL26 on arm64. + - regulator: fix memory leak on error path of regulator_register() + - io_uring: fix sq array offset calculation + - spi: rockchip: Fix error in SPI slave pio read + - ARM: socfpga: PM: add missing put_device() call in + socfpga_setup_ocram_self_refresh() + - iocost: Fix check condition of iocg abs_vdebt + - irqchip/ti-sci-inta: Fix return value about devm_ioremap_resource() + - seccomp: Fix ioctl number for SECCOMP_IOCTL_NOTIF_ID_VALID + - md: raid0/linear: fix dereference before null check on pointer mddev + - nvme-tcp: fix controller reset hang during traffic + - nvme-rdma: fix controller reset hang during traffic + - nvme-multipath: fix logic for non-optimized paths + - nvme-multipath: do not fall back to __nvme_find_path() for non-optimized + paths + - drm/tilcdc: fix leak & null ref in panel_connector_get_modes + - soc: qcom: rpmh-rsc: Set suppress_bind_attrs flag + - Bluetooth: add a mutex lock to avoid UAF in do_enale_set + - loop: be paranoid on exit and prevent new additions / removals + - fs/btrfs: Add cond_resched() for try_release_extent_mapping() stalls + - drm/amdgpu: avoid dereferencing a NULL pointer + - drm/radeon: Fix reference count leaks caused by pm_runtime_get_sync + - crypto: aesni - Fix build with LLVM_IAS=1 + - video: fbdev: savage: fix memory leak on error handling path in probe + - video: fbdev: neofb: fix memory leak in neo_scan_monitor() + - bus: ti-sysc: Add missing quirk flags for usb_host_hs + - md-cluster: fix wild pointer of unlock_all_bitmaps() + - drm/nouveau/kms/nv50-: Fix disabling dithering + - arm64: dts: hisilicon: hikey: fixes to comply with adi, adv7533 DT binding + - drm/etnaviv: fix ref count leak via pm_runtime_get_sync + - drm/nouveau: fix reference count leak in nouveau_debugfs_strap_peek + - drm/nouveau: fix multiple instances of reference count leaks + - mmc: sdhci-cadence: do not use hardware tuning for SD mode + - btrfs: fix lockdep splat from btrfs_dump_space_info + - usb: mtu3: clear dual mode of u3port when disable device + - drm: msm: a6xx: fix gpu failure after system resume + - drm/msm: Fix a null pointer access in msm_gem_shrinker_count() + - drm/debugfs: fix plain echo to connector "force" attribute + - drm/radeon: disable AGP by default + - irqchip/irq-mtk-sysirq: Replace spinlock with raw_spinlock + - mm/mmap.c: Add cond_resched() for exit_mmap() CPU stalls + - drm/amdgpu/display bail early in dm_pp_get_static_clocks + - drm/amd/powerplay: fix compile error with ARCH=arc + - bpf: Fix fds_example SIGSEGV error + - brcmfmac: keep SDIO watchdog running when console_interval is non-zero + - brcmfmac: To fix Bss Info flag definition Bug + - brcmfmac: set state of hanger slot to FREE when flushing PSQ + - platform/x86: asus-nb-wmi: add support for ASUS ROG Zephyrus G14 and G15 + - iwlegacy: Check the return value of pcie_capability_read_*() + - gpu: host1x: debug: Fix multiple channels emitting messages simultaneously + - ionic: update eid test for overflow + - mmc: sdhci-pci-o2micro: Bug fix for O2 host controller Seabird1 + - usb: gadget: net2280: fix memory leak on probe error handling paths + - bdc: Fix bug causing crash after multiple disconnects + - usb: bdc: Halt controller on suspend + - dyndbg: fix a BUG_ON in ddebug_describe_flags + - bcache: fix super block seq numbers comparision in register_cache_set() + - ACPICA: Do not increment operation_region reference counts for field units + - drm/msm: ratelimit crtc event overflow error + - drm/gem: Fix a leak in drm_gem_objects_lookup() + - drm/bridge: ti-sn65dsi86: Clear old error bits before AUX transfers + - agp/intel: Fix a memory leak on module initialisation failure + - mwifiex: Fix firmware filename for sd8977 chipset + - mwifiex: Fix firmware filename for sd8997 chipset + - btmrvl: Fix firmware filename for sd8977 chipset + - btmrvl: Fix firmware filename for sd8997 chipset + - video: fbdev: sm712fb: fix an issue about iounmap for a wrong address + - console: newport_con: fix an issue about leak related system resources + - video: pxafb: Fix the function used to balance a 'dma_alloc_coherent()' call + - ath10k: Acquire tx_lock in tx error paths + - iio: improve IIO_CONCENTRATION channel type description + - drm/etnaviv: Fix error path on failure to enable bus clk + - drm/arm: fix unintentional integer overflow on left shift + - clk: bcm63xx-gate: fix last clock availability + - leds: lm355x: avoid enum conversion warning + - Bluetooth: btusb: fix up firmware download sequence + - Bluetooth: btmtksdio: fix up firmware download sequence + - media: cxusb-analog: fix V4L2 dependency + - media: marvell-ccic: Add missed v4l2_async_notifier_cleanup() + - media: omap3isp: Add missed v4l2_ctrl_handler_free() for + preview_init_entities() + - ASoC: SOF: nocodec: add missing .owner field + - ASoC: Intel: bxt_rt298: add missing .owner field + - scsi: cumana_2: Fix different dev_id between request_irq() and free_irq() + - drm/mipi: use dcs write for mipi_dsi_dcs_set_tear_scanline + - cxl: Fix kobject memleak + - drm/radeon: fix array out-of-bounds read and write issues + - staging: vchiq_arm: Add a matching unregister call + - iavf: fix error return code in iavf_init_get_resources() + - iavf: Fix updating statistics + - RDMA/core: Fix bogus WARN_ON during ib_unregister_device_queued() + - scsi: powertec: Fix different dev_id between request_irq() and free_irq() + - scsi: eesox: Fix different dev_id between request_irq() and free_irq() + - ipvs: allow connection reuse for unconfirmed conntrack + - media: firewire: Using uninitialized values in node_probe() + - media: exynos4-is: Add missed check for pinctrl_lookup_state() + - media: cros-ec-cec: do not bail on device_init_wakeup failure + - xfs: don't eat an EIO/ENOSPC writeback error when scrubbing data fork + - xfs: fix reflink quota reservation accounting error + - RDMA/rxe: Skip dgid check in loopback mode + - PCI: Fix pci_cfg_wait queue locking problem + - drm/stm: repair runtime power management + - kobject: Avoid premature parent object freeing in kobject_cleanup() + - leds: core: Flush scheduled work for system suspend + - drm: panel: simple: Fix bpc for LG LB070WV8 panel + - phy: exynos5-usbdrd: Calibrating makes sense only for USB2.0 PHY + - drm/bridge: sil_sii8620: initialize return of sii8620_readb + - scsi: scsi_debug: Add check for sdebug_max_queue during module init + - mwifiex: Prevent memory corruption handling keys + - kernfs: do not call fsnotify() with name without a parent + - powerpc/rtas: don't online CPUs for partition suspend + - powerpc/vdso: Fix vdso cpu truncation + - RDMA/qedr: SRQ's bug fixes + - RDMA/rxe: Prevent access to wr->next ptr afrer wr is posted to send queue + - ima: Have the LSM free its audit rule + - staging: rtl8192u: fix a dubious looking mask before a shift + - ASoC: meson: fixes the missed kfree() for axg_card_add_tdm_loopback + - PCI/ASPM: Add missing newline in sysfs 'policy' + - phy: renesas: rcar-gen3-usb2: move irq registration to init + - powerpc/book3s64/pkeys: Use PVR check instead of cpu feature + - drm/imx: fix use after free + - drm/imx: tve: fix regulator_disable error path + - gpu: ipu-v3: Restore RGB32, BGR32 + - spi: lantiq-ssc: Fix warning by using WQ_MEM_RECLAIM + - USB: serial: iuu_phoenix: fix led-activity helpers + - usb: core: fix quirks_param_set() writing to a const pointer + - thermal: ti-soc-thermal: Fix reversed condition in + ti_thermal_expose_sensor() + - coresight: tmc: Fix TMC mode read in tmc_read_unprepare_etb() + - powerpc/perf: Fix missing is_sier_aviable() during build + - mt76: mt7615: fix potential memory leak in mcu message handler + - phy: armada-38x: fix NETA lockup when repeatedly switching speeds + - MIPS: OCTEON: add missing put_device() call in dwc3_octeon_device_init() + - usb: dwc2: Fix error path in gadget registration + - usb: gadget: f_uac2: fix AC Interface Header Descriptor wTotalLength + - scsi: megaraid_sas: Clear affinity hint + - scsi: mesh: Fix panic after host or bus reset + - net: dsa: mv88e6xxx: MV88E6097 does not support jumbo configuration + - macintosh/via-macii: Access autopoll_devs when inside lock + - PCI: cadence: Fix updating Vendor ID and Subsystem Vendor ID register + - RDMA/core: Fix return error value in _ib_modify_qp() to negative + - Smack: fix another vsscanf out of bounds + - Smack: prevent underflow in smk_set_cipso() + - power: supply: check if calc_soc succeeded in pm860x_init_battery + - Bluetooth: hci_h5: Set HCI_UART_RESET_ON_INIT to correct flags + - Bluetooth: hci_serdev: Only unregister device if it was registered + - net: dsa: rtl8366: Fix VLAN semantics + - net: dsa: rtl8366: Fix VLAN set-up + - xfs: fix inode allocation block res calculation precedence + - selftests/powerpc: Squash spurious errors due to device removal + - powerpc/32s: Fix CONFIG_BOOK3S_601 uses + - powerpc/boot: Fix CONFIG_PPC_MPC52XX references + - selftests/powerpc: Fix CPU affinity for child process + - RDMA/netlink: Remove CAP_NET_RAW check when dump a raw QP + - PCI: Release IVRS table in AMD ACS quirk + - [Config] update config for ARMADA_AP_CPU_CLK + - cpufreq: ap806: fix cpufreq driver needs ap cpu clk + - selftests/powerpc: Fix online CPU selection + - ASoC: meson: axg-tdm-interface: fix link fmt setup + - ASoC: meson: axg-tdmin: fix g12a skew + - ASoC: meson: axg-tdm-formatters: fix sclk inversion + - ASoC: fsl_sai: Fix value of FSL_SAI_CR1_RFW_MASK + - s390/qeth: don't process empty bridge port events + - ice: Graceful error handling in HW table calloc failure + - rtw88: fix LDPC field for RA info + - rtw88: fix short GI capability based on current bandwidth + - rtw88: coex: only skip coex triggered by BT info + - wl1251: fix always return 0 error + - tools, build: Propagate build failures from tools/build/Makefile.build + - tools, bpftool: Fix wrong return value in do_dump() + - net/mlx5: DR, Change push vlan action sequence + - net/mlx5: Delete extra dump stack that gives nothing + - net: ethernet: aquantia: Fix wrong return value + - liquidio: Fix wrong return value in cn23xx_get_pf_num() + - net: spider_net: Fix the size used in a 'dma_free_coherent()' call + - fsl/fman: use 32-bit unsigned integer + - fsl/fman: fix dereference null return value + - fsl/fman: fix unreachable code + - fsl/fman: check dereferencing null pointer + - fsl/fman: fix eth hash table allocation + - net: thunderx: initialize VF's mailbox mutex before first usage + - dlm: Fix kobject memleak + - ocfs2: fix unbalanced locking + - pinctrl-single: fix pcs_parse_pinconf() return value + - svcrdma: Fix page leak in svc_rdma_recv_read_chunk() + - x86/fsgsbase/64: Fix NULL deref in 86_fsgsbase_read_task + - crypto: aesni - add compatibility with IAS + - af_packet: TPACKET_V3: fix fill status rwlock imbalance + - drivers/net/wan/lapbether: Added needed_headroom and a skb->len check + - net: Fix potential memory leak in proto_register() + - net/nfc/rawsock.c: add CAP_NET_RAW check. + - net: phy: fix memory leak in device-create error path + - net: Set fput_needed iff FDPUT_FPUT is set + - net/tls: Fix kmap usage + - vmxnet3: use correct tcp hdr length when packet is encapsulated + - net: refactor bind_bucket fastreuse into helper + - net: initialize fastreuse on inet_inherit_port + - USB: serial: cp210x: re-enable auto-RTS on open + - USB: serial: cp210x: enable usb generic throttle/unthrottle + - ALSA: hda - fix the micmute led status for Lenovo ThinkCentre AIO + - ALSA: usb-audio: Creative USB X-Fi Pro SB1095 volume knob support + - ALSA: usb-audio: fix overeager device match for MacroSilicon MS2109 + - ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109 + - 9p: Fix memory leak in v9fs_mount + - media: media-request: Fix crash if memory allocation fails + - drm/ttm/nouveau: don't call tt destroy callback on alloc failure. + - io_uring: set ctx sq/cq entry count earlier + - NFS: Don't move layouts to plh_return_segs list while in use + - NFS: Don't return layout segments that are in use + - cpufreq: Fix locking issues with governors + - cpufreq: dt: fix oops on armada37xx + - include/asm-generic/vmlinux.lds.h: align ro_after_init + - spi: spidev: Align buffers for DMA + - mtd: rawnand: qcom: avoid write to unavailable register + - erofs: fix extended inode could cross boundary + - Revert "parisc: Drop LDCW barrier in CAS code when running UP" + - Revert "parisc: Use ldcw instruction for SMP spinlock release barrier" + - Revert "parisc: Revert "Release spinlocks using ordered store"" + - parisc: Do not use an ordered store in pa_tlb_lock() + - parisc: Implement __smp_store_release and __smp_load_acquire barriers + - parisc: mask out enable and reserved bits from sba imask + - ARM: 8992/1: Fix unwind_frame for clang-built kernels + - irqdomain/treewide: Free firmware node after domain removal + - ALSA: usb-audio: add quirk for Pioneer DDJ-RB + - tpm: Unify the mismatching TPM space buffer sizes + - pstore: Fix linking when crypto API disabled + - crypto: hisilicon - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not + specified + - crypto: qat - fix double free in qat_uclo_create_batch_init_list + - crypto: ccp - Fix use of merged scatterlists + - crypto: cpt - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified + - bitfield.h: don't compile-time validate _val in FIELD_FIT + - fs/minix: check return value of sb_getblk() + - fs/minix: don't allow getting deleted inodes + - fs/minix: reject too-large maximum file size + - xen/balloon: fix accounting in alloc_xenballooned_pages error path + - xen/balloon: make the balloon wait interruptible + - xen/gntdev: Fix dmabuf import with non-zero sgt offset + - s390/dasd: fix inability to use DASD with DIAG driver + - s390/gmap: improve THP splitting + - io_uring: Fix NULL pointer dereference in loop_rw_iter() + - Linux 5.4.59 + * Regression on NFS: unable to handle page fault in mempool_alloc_slab + (LP: #1886277) // Focal update: v5.4.59 upstream stable release + (LP: #1892417) + - SUNRPC: Fix ("SUNRPC: Add "@len" parameter to gss_unwrap()") + * Focal update: v5.4.59 upstream stable release (LP: #1892417) // + CVE-2019-19770 which shows this issue is not a core debugfs issue, but + - blktrace: fix debugfs use after free + * update ENA driver for LLQ acceleration mode, new hw support (LP: #1890845) + - net: ena: change num_queues to num_io_queues for clarity and consistency + - net: ena: multiple queue creation related cleanups + - net: ena: ethtool: get_channels: use combined only + - net: ena: make ethtool -l show correct max number of queues + - net: ena: remove redundant print of number of queues + - net: ena: ethtool: support set_channels callback + - net: ena: implement XDP drop support + - net: ena: Implement XDP_TX action + - net: ena: Add first_interrupt field to napi struct + - net: ena: fix default tx interrupt moderation interval + - net: ena: remove set but not used variable 'rx_ring' + - net: ena: remove set but not used variable 'hash_key' + - net: ena: ethtool: remove redundant non-zero check on rc + - net/amazon: Ensure that driver version is aligned to the linux kernel + - net: ena: fix broken interface between ENA driver and FW + - net: ena: ethtool: clean up minor indentation issue + - net: ena: fix incorrect setting of the number of msix vectors + - net: ena: fix request of incorrect number of IRQ vectors + - net: ena: avoid memory access violation by validating req_id properly + - net: ena: fix continuous keep-alive resets + - net: ena: Make some functions static + - net: ena: avoid unnecessary admin command when RSS function set fails + - net: ena: allow setting the hash function without changing the key + - net: ena: change default RSS hash function to Toeplitz + - net: ena: changes to RSS hash key allocation + - net: ena: remove code that does nothing + - net: ena: add unmask interrupts statistics to ethtool + - net: ena: add support for reporting of packet drops + - net: ena: drop superfluous prototype + - net: ena: use SHUTDOWN as reset reason when closing interface + - net: ena: cosmetic: remove unnecessary spaces and tabs in ena_com.h macros + - net: ena: cosmetic: extract code to ena_indirection_table_set() + - net: ena: add support for the rx offset feature + - net: ena: rename ena_com_free_desc to make API more uniform + - net: ena: use explicit variable size for clarity + - net: ena: fix ena_com_comp_status_to_errno() return value + - net: ena: simplify ena_com_update_intr_delay_resolution() + - net: ena: cosmetic: set queue sizes to u32 for consistency + - net: ena: cosmetic: fix spelling and grammar mistakes in comments + - net: ena: cosmetic: fix line break issues + - net: ena: cosmetic: remove unnecessary code + - net: ena: cosmetic: code reorderings + - net: ena: cosmetic: fix spacing issues + - net: ena: cosmetic: minor code changes + - net: ena: reduce driver load time + - net: ena: xdp: XDP_TX: fix memory leak + - net: ena: xdp: update napi budget for DROP and ABORTED + - ena_netdev: use generic power management + - net: ena: Fix using plain integer as NULL pointer in ena_init_napi_in_range + - net: ena: avoid unnecessary rearming of interrupt vector when busy-polling + - net: ena: add reserved PCI device ID + - net: ena: cosmetic: satisfy gcc warning + - net: ena: cosmetic: change ena_com_stats_admin stats to u64 + - net: ena: add support for traffic mirroring + - net: ena: enable support of rss hash key and function changes + - net: ena: move llq configuration from ena_probe to ena_device_init() + - net: ena: support new LLQ acceleration mode + * [SRU] Fix acpi backlight issue on some thinkpads (LP: #1892010) + - platform/x86: thinkpad_acpi: not loading brightness_init when _BCL invalid + * [SRU][F/OEM-5.6] add a new OLED panel support for brightness control + (LP: #1887909) + - drm/dp: Lenovo X13 Yoga OLED panel brightness fix + * Realtek [10ec:c82f] Subsystem [17aa:c02f] Wifi adapter not found + (LP: #1886247) + - SAUCE: rtw88: 8822ce: add support for device ID 0xc82f + * KVM: Fix zero_page reference counter overflow when using KSM on KVM compute + host (LP: #1837810) + - KVM: fix overflow of zero page refcount with ksm running + * Fix missing HDMI Audio on another HP Desktop (LP: #1891617) + - ALSA: hda/hdmi: Use force connectivity quirk on another HP desktop + * alsa/sof: support 1 and 3 dmics (LP: #1891585) + - SAUCE: ASoC: SOF: intel: hda: support also devices with 1 and 3 dmics + * tcp_fastopen_backup_key.sh from net in ubuntu_kernel_selftests failed on + Eoan LPAR (LP: #1869134) + - tcp: correct read of TFO keys on big endian systems + * Fix false-negative return value for rtnetlink.sh in kselftests/net + (LP: #1890136) + - selftests: rtnetlink: correct the final return value for the test + - selftests: rtnetlink: make kci_test_encap() return sub-test result + * Focal update: v5.4.58 upstream stable release (LP: #1891387) + - USB: serial: qcserial: add EM7305 QDL product ID + - perf/core: Fix endless multiplex timer + - USB: iowarrior: fix up report size handling for some devices + - usb: xhci: define IDs for various ASMedia host controllers + - usb: xhci: Fix ASMedia ASM1142 DMA addressing + - io_uring: prevent re-read of sqe->opcode + - io_uring: Fix use-after-free in io_sq_wq_submit_work() + - Revert "ALSA: hda: call runtime_allow() for all hda controllers" + - ALSA: hda/realtek: Add alc269/alc662 pin-tables for Loongson-3 laptops + - ALSA: hda/ca0132 - Add new quirk ID for Recon3D. + - ALSA: hda/ca0132 - Fix ZxR Headphone gain control get value. + - ALSA: hda/ca0132 - Fix AE-5 microphone selection commands. + - ALSA: seq: oss: Serialize ioctls + - staging: android: ashmem: Fix lockdep warning for write operation + - staging: rtl8712: handle firmware load failure + - Staging: rtl8188eu: rtw_mlme: Fix uninitialized variable authmode + - Bluetooth: Fix slab-out-of-bounds read in hci_extended_inquiry_result_evt() + - Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_evt() + - Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_with_rssi_evt() + - omapfb: dss: Fix max fclk divider for omap36xx + - binder: Prevent context manager from incrementing ref 0 + - Smack: fix use-after-free in smk_write_relabel_self() + - scripts: add dummy report mode to add_namespace.cocci + - vgacon: Fix for missing check in scrollback handling + - mtd: properly check all write ioctls for permissions + - leds: wm831x-status: fix use-after-free on unbind + - leds: lm36274: fix use-after-free on unbind + - leds: da903x: fix use-after-free on unbind + - leds: lm3533: fix use-after-free on unbind + - leds: 88pm860x: fix use-after-free on unbind + - net/9p: validate fds in p9_fd_open + - drm/nouveau/fbcon: fix module unload when fbcon init has failed for some + reason + - drm/nouveau/fbcon: zero-initialise the mode_cmd2 structure + - drm/drm_fb_helper: fix fbdev with sparc64 + - i2c: slave: improve sanity check when registering + - i2c: slave: add sanity check when unregistering + - usb: hso: check for return value in hso_serial_common_create() + - net: ethernet: mtk_eth_soc: Always call mtk_gmac0_rgmii_adjust() for mt7623 + - ALSA: hda: fix NULL pointer dereference during suspend + - firmware: Fix a reference count leak. + - cfg80211: check vendor command doit pointer before use + - igb: reinit_locked() should be called with rtnl_lock + - atm: fix atm_dev refcnt leaks in atmtcp_remove_persistent + - tools lib traceevent: Fix memory leak in process_dynamic_array_len + - Drivers: hv: vmbus: Ignore CHANNELMSG_TL_CONNECT_RESULT(23) + - xattr: break delegations in {set,remove}xattr + - Revert "powerpc/kasan: Fix shadow pages allocation failure" + - PCI: tegra: Revert tegra124 raw_violation_fixup + - ipv4: Silence suspicious RCU usage warning + - ipv6: fix memory leaks on IPV6_ADDRFORM path + - ipv6: Fix nexthop refcnt leak when creating ipv6 route info + - net: ethernet: mtk_eth_soc: fix MTU warnings + - rxrpc: Fix race between recvmsg and sendmsg on immediate call failure + - vxlan: Ensure FDB dump is performed under RCU + - net: lan78xx: replace bogus endpoint lookup + - appletalk: Fix atalk_proc_init() return path + - dpaa2-eth: Fix passing zero to 'PTR_ERR' warning + - hv_netvsc: do not use VF device if link is down + - net: gre: recompute gre csum for sctp over gre tunnels + - net: thunderx: use spin_lock_bh in nicvf_set_rx_mode_task() + - openvswitch: Prevent kernel-infoleak in ovs_ct_put_key() + - Revert "vxlan: fix tos value before xmit" + - tcp: apply a floor of 1 for RTT samples from TCP timestamps + - ima: move APPRAISE_BOOTPARAM dependency on ARCH_POLICY to runtime + - [Config] update annotations for IMA_APPRAISE_BOOTPARAM + - nfsd: Fix NFSv4 READ on RDMA when using readv + - Linux 5.4.58 + * Focal update: v5.4.57 upstream stable release (LP: #1891064) + - random32: update the net random state on interrupt and activity + - ARM: percpu.h: fix build error + - random: fix circular include dependency on arm64 after addition of percpu.h + - random32: remove net_rand_state from the latent entropy gcc plugin + - random32: move the pseudo-random 32-bit definitions to prandom.h + - arm64: Workaround circular dependency in pointer_auth.h + - ext4: fix direct I/O read error + - selftests: bpf: Fix detach from sockmap tests + - bpf: sockmap: Require attach_bpf_fd when detaching a program + - Linux 5.4.57 + * Focal update: v5.4.56 upstream stable release (LP: #1891063) + - crypto: ccp - Release all allocated memory if sha type is invalid + - media: rc: prevent memory leak in cx23888_ir_probe + - sunrpc: check that domain table is empty at module unload. + - ath10k: enable transmit data ack RSSI for QCA9884 + - PCI/ASPM: Disable ASPM on ASMedia ASM1083/1085 PCIe-to-PCI bridge + - mm/filemap.c: don't bother dropping mmap_sem for zero size readahead + - ALSA: usb-audio: Add implicit feedback quirk for SSL2 + - ALSA: hda/realtek: enable headset mic of ASUS ROG Zephyrus G15(GA502) series + with ALC289 + - ALSA: hda/realtek: typo_fix: enable headset mic of ASUS ROG Zephyrus + G14(GA401) series with ALC289 + - ALSA: hda/realtek: Fix add a "ultra_low_power" function for intel reference + board (alc256) + - ALSA: hda/hdmi: Fix keep_power assignment for non-component devices + - IB/rdmavt: Fix RQ counting issues causing use of an invalid RWQE + - vhost/scsi: fix up req type endian-ness + - 9p/trans_fd: Fix concurrency del of req_list in p9_fd_cancelled/p9_read_work + - wireless: Use offsetof instead of custom macro. + - ARM: 8986/1: hw_breakpoint: Don't invoke overflow handler on uaccess + watchpoints + - ARM: dts: imx6sx-sabreauto: Fix the phy-mode on fec2 + - ARM: dts: imx6sx-sdb: Fix the phy-mode on fec2 + - ARM: dts: imx6qdl-icore: Fix OTG_ID pin and sdcard detect + - virtio_balloon: fix up endian-ness for free cmd id + - Revert "drm/amdgpu: Fix NULL dereference in dpm sysfs handlers" + - drm/amd/display: Clear dm_state for fast updates + - drm/amdgpu: Prevent kernel-infoleak in amdgpu_info_ioctl() + - drm/dbi: Fix SPI Type 1 (9-bit) transfer + - drm: hold gem reference until object is no longer accessed + - rds: Prevent kernel-infoleak in rds_notify_queue_get() + - libtraceevent: Fix build with binutils 2.35 + - net/x25: Fix x25_neigh refcnt leak when x25 disconnect + - net/x25: Fix null-ptr-deref in x25_disconnect + - ARM: dts sunxi: Relax a bit the CMA pool allocation range + - xfrm: Fix crash when the hold queue is used. + - ARM: dts: armada-38x: fix NETA lockup when repeatedly switching speeds + - nvme-tcp: fix possible hang waiting for icresp response + - selftests/net: rxtimestamp: fix clang issues for target arch PowerPC + - selftests/net: psock_fanout: fix clang issues for target arch PowerPC + - selftests/net: so_txtime: fix clang issues for target arch PowerPC + - sh/tlb: Fix PGTABLE_LEVELS > 2 + - sh: Fix validation of system call number + - net: hns3: fix a TX timeout issue + - net: hns3: fix aRFS FD rules leftover after add a user FD rule + - net/mlx5: E-switch, Destroy TSAR when fail to enable the mode + - net/mlx5e: Fix error path of device attach + - net/mlx5: Verify Hardware supports requested ptp function on a given pin + - net/mlx5e: Modify uplink state on interface up/down + - net/mlx5e: Fix kernel crash when setting vf VLANID on a VF dev + - net: lan78xx: add missing endpoint sanity check + - net: lan78xx: fix transfer-buffer memory leak + - rhashtable: Fix unprotected RCU dereference in __rht_ptr + - mlx4: disable device on shutdown + - mlxsw: core: Increase scope of RCU read-side critical section + - mlxsw: core: Free EMAD transactions using kfree_rcu() + - ibmvnic: Fix IRQ mapping disposal in error path + - bpf: Fix map leak in HASH_OF_MAPS map + - mac80211: mesh: Free ie data when leaving mesh + - mac80211: mesh: Free pending skb when destroying a mpath + - arm64/alternatives: move length validation inside the subsection + - arm64: csum: Fix handling of bad packets + - Bluetooth: fix kernel oops in store_pending_adv_report + - net: nixge: fix potential memory leak in nixge_probe() + - net: gemini: Fix missing clk_disable_unprepare() in error path of + gemini_ethernet_port_probe() + - net/mlx5e: fix bpf_prog reference count leaks in mlx5e_alloc_rq + - perf tools: Fix record failure when mixed with ARM SPE event + - vxlan: fix memleak of fdb + - usb: hso: Fix debug compile warning on sparc32 + - selftests: fib_nexthop_multiprefix: fix cleanup() netns deletion + - qed: Disable "MFW indication via attention" SPAM every 5 minutes + - selftests: net: ip_defrag: modprobe missing nf_defrag_ipv6 support + - nfc: s3fwrn5: add missing release on skb in s3fwrn5_recv_frame + - scsi: core: Run queue in case of I/O resource contention failure + - parisc: add support for cmpxchg on u8 pointers + - net: ethernet: ravb: exit if re-initialization fails in tx timeout + - Revert "i2c: cadence: Fix the hold bit setting" + - x86/unwind/orc: Fix ORC for newly forked tasks + - x86/stacktrace: Fix reliable check for empty user task stacks + - cxgb4: add missing release on skb in uld_send() + - xen-netfront: fix potential deadlock in xennet_remove() + - RISC-V: Set maximum number of mapped pages correctly + - drivers/net/wan: lapb: Corrected the usage of skb_cow + - KVM: arm64: Don't inherit exec permission across page-table levels + - KVM: LAPIC: Prevent setting the tscdeadline timer if the lapic is hw + disabled + - x86/i8259: Use printk_deferred() to prevent deadlock + - perf tests bp_account: Make global variable static + - perf env: Do not return pointers to local variables + - perf bench: Share some global variables to fix build with gcc 10 + - Linux 5.4.56 + + -- William Breathitt Gray Fri, 11 Sep 2020 08:36:45 -0400 + +linux-oracle (5.4.0-1024.24) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1024.24 -proposed tracker (LP: #1894311) + + [ Ubuntu: 5.4.0-47.51 ] + + * focal/linux: 5.4.0-47.51 -proposed tracker (LP: #1894315) + * CVE-2020-14386 + - SAUCE: net/packet: fix overflow in tpacket_rcv + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-45.49 ] + + * focal/linux: 5.4.0-45.49 -proposed tracker (LP: #1893050) + * [Potential Regression] dscr_inherit_exec_test from powerpc in + ubuntu_kernel_selftests failed on B/E/F (LP: #1888332) + - powerpc/64s: Don't init FSCR_DSCR in __init_FSCR() + + -- Khalid Elmously Sat, 05 Sep 2020 02:59:35 -0400 + +linux-oracle (5.4.0-1022.22) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1022.22 -proposed tracker (LP: #1890742) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update update.conf + + * soc/amd/renoir: change the module name to make it work with ucm3 + (LP: #1888166) + - [config] Remove (rename) acp3x-rn + + * Focal update: v5.4.52 upstream stable release (LP: #1887853) + - [config] Remove (rename) intel-rapl-perf + + * Fix statistics on Broadcom Ethernet driver (LP: #1892397) + - bnxt_en: Store the running firmware version code. + - bnxt_en: Do not enable legacy TX push on older firmware. + - bnxt_en: Fix statistics counters issue during ifdown with older firmware. + + * Focal update: v5.4.51 upstream stable release (LP: #1886995) + - [config] updateconfigs for EFI_CUSTOM_SSDT_OVERLAYS + + [ Ubuntu: 5.4.0-44.48 ] + + * focal/linux: 5.4.0-44.48 -proposed tracker (LP: #1891049) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * ipsec: policy priority management is broken (LP: #1890796) + - xfrm: policy: match with both mark and mask on user interfaces + + [ Ubuntu: 5.4.0-43.47 ] + + * focal/linux: 5.4.0-43.47 -proposed tracker (LP: #1890746) + * Packaging resync (LP: #1786013) + - update dkms package versions + * Devlink - add RoCE disable kernel support (LP: #1877270) + - devlink: Add new "enable_roce" generic device param + - net/mlx5: Document flow_steering_mode devlink param + - net/mlx5: Handle "enable_roce" devlink param + - IB/mlx5: Rename profile and init methods + - IB/mlx5: Load profile according to RoCE enablement state + - net/mlx5: Remove unneeded variable in mlx5_unload_one + - net/mlx5: Add devlink reload + - IB/mlx5: Do reverse sequence during device removal + * msg_zerocopy.sh in net from ubuntu_kernel_selftests failed (LP: #1812620) + - selftests/net: relax cpu affinity requirement in msg_zerocopy test + * Enlarge hisi_sec2 capability (LP: #1890222) + - Revert "UBUNTU: [Config] Disable hisi_sec2 temporarily" + - crypto: hisilicon - update SEC driver module parameter + * Fix missing HDMI/DP Audio on an HP Desktop (LP: #1890441) + - ALSA: hda/hdmi: Add quirk to force connectivity + * Fix IOMMU error on AMD Radeon Pro W5700 (LP: #1890306) + - PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken + * ASoC:amd:renoir: the dmic can't record sound after suspend and resume + (LP: #1890220) + - SAUCE: ASoC: amd: renoir: restore two more registers during resume + * No sound, Dummy output on Acer Swift 3 SF314-57G with Ice Lake core-i7 CPU + (LP: #1877757) + - ASoC: SOF: Intel: hda: fix generic hda codec support + * Fix right speaker of HP laptop (LP: #1889375) + - SAUCE: hda/realtek: Fix right speaker of HP laptop + * blk_update_request error when mount nvme partition (LP: #1872383) + - SAUCE: nvme-pci: prevent SK hynix PC400 from using Write Zeroes command + * soc/amd/renoir: detect dmic from acpi table (LP: #1887734) + - ASoC: amd: add logic to check dmic hardware runtime + - ASoC: amd: add ACPI dependency check + - ASoC: amd: fixed kernel warnings + * soc/amd/renoir: change the module name to make it work with ucm3 + (LP: #1888166) + - AsoC: amd: add missing snd- module prefix to the acp3x-rn driver kernel + module + - SAUCE: remove a kernel module since its name is changed + * Focal update: v5.4.55 upstream stable release (LP: #1890343) + - AX.25: Fix out-of-bounds read in ax25_connect() + - AX.25: Prevent out-of-bounds read in ax25_sendmsg() + - dev: Defer free of skbs in flush_backlog + - drivers/net/wan/x25_asy: Fix to make it work + - ip6_gre: fix null-ptr-deref in ip6gre_init_net() + - net-sysfs: add a newline when printing 'tx_timeout' by sysfs + - net: udp: Fix wrong clean up for IS_UDPLITE macro + - qrtr: orphan socket in qrtr_release() + - rtnetlink: Fix memory(net_device) leak when ->newlink fails + - rxrpc: Fix sendmsg() returning EPIPE due to recvmsg() returning ENODATA + - tcp: allow at most one TLP probe per flight + - AX.25: Prevent integer overflows in connect and sendmsg + - sctp: shrink stream outq only when new outcnt < old outcnt + - sctp: shrink stream outq when fails to do addstream reconf + - udp: Copy has_conns in reuseport_grow(). + - udp: Improve load balancing for SO_REUSEPORT. + - regmap: debugfs: check count when read regmap file + - PM: wakeup: Show statistics for deleted wakeup sources again + - Revert "dpaa_eth: fix usage as DSA master, try 3" + - Linux 5.4.55 + * Add support for Atlantic NIC firmware v4 (LP: #1886908) + - net: atlantic: simplify hw_get_fw_version() usage + - net: atlantic: align return value of ver_match function with function name + - net: atlantic: add support for FW 4.x + * perf vendor events s390: Add new deflate counters for IBM z15 (LP: #1888551) + - perf vendor events s390: Add new deflate counters for IBM z15 + * Focal update: v5.4.54 upstream stable release (LP: #1889669) + - soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner + - gpio: arizona: handle pm_runtime_get_sync failure case + - gpio: arizona: put pm_runtime in case of failure + - pinctrl: amd: fix npins for uart0 in kerncz_groups + - mac80211: allow rx of mesh eapol frames with default rx key + - scsi: scsi_transport_spi: Fix function pointer check + - xtensa: fix __sync_fetch_and_{and,or}_4 declarations + - xtensa: update *pos in cpuinfo_op.next + - scsi: mpt3sas: Fix unlock imbalance + - drivers/net/wan/lapbether: Fixed the value of hard_header_len + - ALSA: hda/hdmi: fix failures at PCM open on Intel ICL and later + - net: sky2: initialize return of gm_phy_read + - drm/nouveau/i2c/g94-: increase NV_PMGR_DP_AUXCTL_TRANSACTREQ timeout + - scsi: mpt3sas: Fix error returns in BRM_status_show + - scsi: dh: Add Fujitsu device to devinfo and dh lists + - dm: use bio_uninit instead of bio_disassociate_blkg + - drivers/firmware/psci: Fix memory leakage in alloc_init_cpu_groups() + - fuse: fix weird page warning + - irqdomain/treewide: Keep firmware node unconditionally allocated + - ARM: dts: imx6qdl-gw551x: Do not use 'simple-audio-card,dai-link' + - ARM: dts: imx6qdl-gw551x: fix audio SSI + - dmabuf: use spinlock to access dmabuf->name + - drm/amd/display: Check DMCU Exists Before Loading + - SUNRPC reverting d03727b248d0 ("NFSv4 fix CLOSE not waiting for direct IO + compeletion") + - btrfs: reloc: fix reloc root leak and NULL pointer dereference + - btrfs: reloc: clear DEAD_RELOC_TREE bit for orphan roots to prevent runaway + balance + - uprobes: Change handle_swbp() to send SIGTRAP with si_code=SI_KERNEL, to fix + GDB regression + - ALSA: hda/realtek: Fixed ALC298 sound bug by adding quirk for Samsung + Notebook Pen S + - ALSA: info: Drop WARN_ON() from buffer NULL sanity check + - ASoC: rt5670: Correct RT5670_LDO_SEL_MASK + - btrfs: fix double free on ulist after backref resolution failure + - btrfs: fix mount failure caused by race with umount + - btrfs: fix page leaks after failure to lock page for delalloc + - bnxt_en: Fix race when modifying pause settings. + - bnxt_en: Fix completion ring sizing with TPA enabled. + - fpga: dfl: pci: reduce the scope of variable 'ret' + - fpga: dfl: fix bug in port reset handshake + - hippi: Fix a size used in a 'pci_free_consistent()' in an error handling + path + - vsock/virtio: annotate 'the_virtio_vsock' RCU pointer + - ax88172a: fix ax88172a_unbind() failures + - RDMA/mlx5: Use xa_lock_irq when access to SRQ table + - ASoC: Intel: bytcht_es8316: Add missed put_device() + - net: dp83640: fix SIOCSHWTSTAMP to update the struct with actual + configuration + - ieee802154: fix one possible memleak in adf7242_probe + - drm: sun4i: hdmi: Fix inverted HPD result + - net: smc91x: Fix possible memory leak in smc_drv_probe() + - bonding: check error value of register_netdevice() immediately + - mlxsw: destroy workqueue when trap_register in mlxsw_emad_init + - ionic: use offset for ethtool regs data + - ionic: fix up filter locks and debug msgs + - net: ag71xx: add missed clk_disable_unprepare in error path of probe + - net: hns3: fix error handling for desc filling + - net: dsa: microchip: call phy_remove_link_mode during probe + - netdevsim: fix unbalaced locking in nsim_create() + - qed: suppress "don't support RoCE & iWARP" flooding on HW init + - qed: suppress false-positives interrupt error messages on HW init + - ipvs: fix the connection sync failed in some cases + - net: ethernet: ave: Fix error returns in ave_init + - Revert "PCI/PM: Assume ports without DLL Link Active train links in 100 ms" + - nfsd4: fix NULL dereference in nfsd/clients display code + - enetc: Remove the mdio bus on PF probe bailout + - i2c: rcar: always clear ICSAR to avoid side effects + - i2c: i2c-qcom-geni: Fix DMA transfer race + - bonding: check return value of register_netdevice() in bond_newlink() + - geneve: fix an uninitialized value in geneve_changelink() + - serial: exar: Fix GPIO configuration for Sealevel cards based on XR17V35X + - scripts/decode_stacktrace: strip basepath from all paths + - scripts/gdb: fix lx-symbols 'gdb.error' while loading modules + - HID: i2c-hid: add Mediacom FlexBook edge13 to descriptor override + - HID: alps: support devices with report id 2 + - HID: steam: fixes race in handling device list. + - HID: apple: Disable Fn-key key-re-mapping on clone keyboards + - dmaengine: tegra210-adma: Fix runtime PM imbalance on error + - Input: add `SW_MACHINE_COVER` + - ARM: dts: n900: remove mmc1 card detect gpio + - spi: mediatek: use correct SPI_CFG2_REG MACRO + - regmap: dev_get_regmap_match(): fix string comparison + - hwmon: (aspeed-pwm-tacho) Avoid possible buffer overflow + - dmaengine: fsl-edma: fix wrong tcd endianness for big-endian cpu + - dmaengine: ioat setting ioat timeout as module parameter + - Input: synaptics - enable InterTouch for ThinkPad X1E 1st gen + - Input: elan_i2c - only increment wakeup count on touch + - usb: dwc3: pci: add support for the Intel Tiger Lake PCH -H variant + - usb: dwc3: pci: add support for the Intel Jasper Lake + - usb: gadget: udc: gr_udc: fix memleak on error handling path in gr_ep_init() + - usb: cdns3: ep0: fix some endian issues + - usb: cdns3: trace: fix some endian issues + - hwmon: (adm1275) Make sure we are reading enough data for different chips + - drm/amdgpu/gfx10: fix race condition for kiq + - drm/amdgpu: fix preemption unit test + - hwmon: (nct6775) Accept PECI Calibration as temperature source for NCT6798D + - platform/x86: ISST: Add new PCI device ids + - platform/x86: asus-wmi: allow BAT1 battery name + - hwmon: (scmi) Fix potential buffer overflow in scmi_hwmon_probe() + - ALSA: hda/realtek - fixup for yet another Intel reference board + - drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling + - arm64: Use test_tsk_thread_flag() for checking TIF_SINGLESTEP + - x86: math-emu: Fix up 'cmp' insn for clang ias + - asm-generic/mmiowb: Allow mmiowb_set_pending() when preemptible() + - drivers/perf: Prevent forced unbinding of PMU drivers + - RISC-V: Upgrade smp_mb__after_spinlock() to iorw,iorw + - binder: Don't use mmput() from shrinker function. + - usb: xhci-mtk: fix the failure of bandwidth allocation + - usb: xhci: Fix ASM2142/ASM3142 DMA addressing + - Revert "cifs: Fix the target file was deleted when rename failed." + - iwlwifi: mvm: don't call iwl_mvm_free_inactive_queue() under RCU + - tty: xilinx_uartps: Really fix id assignment + - staging: wlan-ng: properly check endpoint types + - staging: comedi: addi_apci_1032: check INSN_CONFIG_DIGITAL_TRIG shift + - staging: comedi: ni_6527: fix INSN_CONFIG_DIGITAL_TRIG support + - staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift + - staging: comedi: addi_apci_1564: check INSN_CONFIG_DIGITAL_TRIG shift + - serial: tegra: fix CREAD handling for PIO + - serial: 8250: fix null-ptr-deref in serial8250_start_tx() + - serial: 8250_mtk: Fix high-speed baud rates clamping + - /dev/mem: Add missing memory barriers for devmem_inode + - fbdev: Detect integer underflow at "struct fbcon_ops"->clear_margins. + - vt: Reject zero-sized screen buffer size. + - Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation + - mm/mmap.c: close race between munmap() and expand_upwards()/downwards() + - mm/memcg: fix refcount error while moving and swapping + - mm: memcg/slab: fix memory leak at non-root kmem_cache destroy + - khugepaged: fix null-pointer dereference due to race + - io-mapping: indicate mapping failure + - mmc: sdhci-of-aspeed: Fix clock divider calculation + - drm/amdgpu: Fix NULL dereference in dpm sysfs handlers + - drm/amd/powerplay: fix a crash when overclocking Vega M + - parisc: Add atomic64_set_release() define to avoid CPU soft lockups + - x86, vmlinux.lds: Page-align end of ..page_aligned sections + - ASoC: rt5670: Add new gpio1_is_ext_spk_en quirk and enable it on the Lenovo + Miix 2 10 + - ASoC: qcom: Drop HAS_DMA dependency to fix link failure + - ASoC: topology: fix kernel oops on route addition error + - ASoC: topology: fix tlvs in error handling for widget_dmixer + - dm integrity: fix integrity recalculation that is improperly skipped + - ath9k: Fix regression with Atheros 9271 + - Linux 5.4.54 + * Focal update: v5.4.53 upstream stable release (LP: #1888560) + - crypto: atmel - Fix selection of CRYPTO_AUTHENC + - crypto: atmel - Fix build error of CRYPTO_AUTHENC + - net: atlantic: fix ip dst and ipv6 address filters + - net: rmnet: fix lower interface leak + - bridge: mcast: Fix MLD2 Report IPv6 payload length check + - genetlink: remove genl_bind + - ipv4: fill fl4_icmp_{type,code} in ping_v4_sendmsg + - ipv6: fib6_select_path can not use out path for nexthop objects + - ipv6: Fix use of anycast address with loopback + - l2tp: remove skb_dst_set() from l2tp_xmit_skb() + - llc: make sure applications use ARPHRD_ETHER + - net: Added pointer check for dst->ops->neigh_lookup in dst_neigh_lookup_skb + - net_sched: fix a memory leak in atm_tc_init() + - sched: consistently handle layer3 header accesses in the presence of VLANs + - tcp: fix SO_RCVLOWAT possible hangs under high mem pressure + - tcp: make sure listeners don't initialize congestion-control state + - tcp: md5: add missing memory barriers in tcp_md5_do_add()/tcp_md5_hash_key() + - tcp: md5: do not send silly options in SYNCOOKIES + - vlan: consolidate VLAN parsing code and limit max parsing depth + - tcp: md5: refine tcp_md5_do_add()/tcp_md5_hash_key() barriers + - tcp: md5: allow changing MD5 keys in all socket states + - cgroup: fix cgroup_sk_alloc() for sk_clone_lock() + - cgroup: Fix sock_cgroup_data on big-endian. + - ip: Fix SO_MARK in RST, ACK and ICMP packets + - arm64: Introduce a way to disable the 32bit vdso + - arm64: arch_timer: Allow an workaround descriptor to disable compat vdso + - arm64: arch_timer: Disable the compat vdso for cores affected by + ARM64_WORKAROUND_1418040 + - drm/msm: fix potential memleak in error branch + - drm/msm/dpu: allow initialization of encoder locks during encoder init + - drm/exynos: Properly propagate return value in drm_iommu_attach_device() + - drm/exynos: fix ref count leak in mic_pre_enable + - x86/fpu: Reset MXCSR to default in kernel_fpu_begin() + - thermal/drivers: imx: Fix missing of_node_put() at probe time + - blk-mq-debugfs: update blk_queue_flag_name[] accordingly for new flags + - m68k: nommu: register start of the memory with memblock + - m68k: mm: fix node memblock init + - dt-bindings: mailbox: zynqmp_ipi: fix unit address + - cifs: prevent truncation from long to int in wait_for_free_credits + - arm64/alternatives: use subsections for replacement sequences + - tpm_tis: extra chip->ops check on error path in tpm_tis_core_init + - gfs2: read-only mounts should grab the sd_freeze_gl glock + - i2c: eg20t: Load module automatically if ID matches + - arm64/alternatives: don't patch up internal branches + - iio:magnetometer:ak8974: Fix alignment and data leak issues + - iio:humidity:hdc100x Fix alignment and data leak issues + - iio: magnetometer: ak8974: Fix runtime PM imbalance on error + - iio: core: add missing IIO_MOD_H2/ETHANOL string identifiers + - iio: mma8452: Add missed iio_device_unregister() call in mma8452_probe() + - iio: pressure: zpa2326: handle pm_runtime_get_sync failure + - iio:humidity:hts221 Fix alignment and data leak issues + - iio:pressure:ms5611 Fix buffer element alignment + - iio:health:afe4403 Fix timestamp alignment and prevent data leak. + - spi: spi-fsl-dspi: Fix lockup if device is shutdown during SPI transfer + - net: dsa: bcm_sf2: Fix node reference count + - of: of_mdio: Correct loop scanning logic + - net: macb: call pm_runtime_put_sync on failure path + - net: ethernet: mvneta: Do not error out in non serdes modes + - net: ethernet: mvneta: Add back interface mode validation + - Revert "usb/ohci-platform: Fix a warning when hibernating" + - Revert "usb/ehci-platform: Set PM runtime as active on resume" + - Revert "usb/xhci-plat: Set PM runtime as active on resume" + - net: sfp: add support for module quirks + - net: sfp: add some quirks for GPON modules + - ARM: OMAP4+: remove pdata quirks for omap4+ iommus + - ARM: OMAP2+: Add workaround for DRA7 DSP MStandby errata i879 + - ARM: OMAP2+: use separate IOMMU pdata to fix DRA7 IPU1 boot + - mmc: mmci: Support any block sizes for ux500v2 and qcom variant + - HID: quirks: Remove ITE 8595 entry from hid_have_special_driver + - ARM: at91: pm: add quirk for sam9x60's ulp1 + - drm/sun4i: tcon: Separate quirks for tcon0 and tcon1 on A20 + - scsi: sr: remove references to BLK_DEV_SR_VENDOR, leave it enabled + - [Config] updateconfigs for BLK_DEV_SR_VENDOR + - bus: ti-sysc: Rename clk related quirks to pre_reset and post_reset quirks + - bus: ti-sysc: Consider non-existing registers too when matching quirks + - bus: ti-sysc: Handle module unlock quirk needed for some RTC + - bus: ti-sysc: Detect display subsystem related devices + - arm64: dts: g12-common: add parkmode_disable_ss_quirk on DWC3 controller + - bus: ti-sysc: Detect EDMA and set quirk flags for tptc + - ALSA: usb-audio: Add support for MOTU MicroBook IIc + - Input: goodix - fix touch coordinates on Cube I15-TC + - ALSA: usb-audio: Create a registration quirk for Kingston HyperX Amp + (0951:16d8) + - doc: dt: bindings: usb: dwc3: Update entries for disabling SS instances in + park mode + - mmc: sdhci: do not enable card detect interrupt for gpio cd type + - ALSA: usb-audio: Rewrite registration quirk handling + - ACPI: video: Use native backlight on Acer Aspire 5783z + - ALSA: usb-audio: Add registration quirk for Kingston HyperX Cloud Alpha S + - ALSA: usb-audio: Add quirk for Focusrite Scarlett 2i2 + - Input: mms114 - add extra compatible for mms345l + - ACPI: video: Use native backlight on Acer TravelMate 5735Z + - bus: ti-sysc: Use optional clocks on for enable and wait for softreset bit + - ALSA: usb-audio: Add registration quirk for Kingston HyperX Cloud Flight S + - iio:health:afe4404 Fix timestamp alignment and prevent data leak. + - soundwire: intel: fix memory leak with devm_kasprintf + - dmaengine: sh: usb-dmac: set tx_result parameters + - phy: sun4i-usb: fix dereference of pointer phy0 before it is null checked + - arm64: dts: meson: add missing gxl rng clock + - arm64: dts: meson-gxl-s805x: reduce initial Mali450 core frequency + - bus: ti-sysc: Fix wakeirq sleeping function called from invalid context + - bus: ti-sysc: Fix sleeping function called from invalid context for RTC + quirk + - bus: ti-sysc: Do not disable on suspend for no-idle + - iio: adc: ad7780: Fix a resource handling path in 'ad7780_probe()' + - dmaengine: dw: Initialize channel before each transfer + - dmaengine: dmatest: stop completed threads when running without set channel + - spi: spi-sun6i: sun6i_spi_transfer_one(): fix setting of clock rate + - usb: gadget: udc: atmel: fix uninitialized read in debug printk + - staging: comedi: verify array index is correct before using it + - clk: mvebu: ARMADA_AP_CPU_CLK needs to select ARMADA_AP_CP_HELPER + - clk: AST2600: Add mux for EMMC clock + - NFS: Fix interrupted slots by sending a solo SEQUENCE operation + - fuse: don't ignore errors from fuse_writepages_fill() + - ARM: dts: Fix dcan driver probe failed on am437x platform + - Revert "thermal: mediatek: fix register index error" + - xprtrdma: fix incorrect header size calculations + - ARM: dts: socfpga: Align L2 cache-controller nodename with dtschema + - arm64: dts: spcfpga: Align GIC, NAND and UART nodenames with dtschema + - keys: asymmetric: fix error return code in software_key_query() + - regmap: debugfs: Don't sleep while atomic for fast_io regmaps + - copy_xstate_to_kernel: Fix typo which caused GDB regression + - arm: dts: mt7623: add phy-mode property for gmac2 + - soc: qcom: socinfo: add missing soc_id sysfs entry + - habanalabs: Align protection bits configuration of all TPCs + - PCI/PM: Call .bridge_d3() hook only if non-NULL + - perf stat: Zero all the 'ena' and 'run' array slot stats for interval mode + - soc: qcom: rpmh: Update dirty flag only when data changes + - soc: qcom: rpmh: Invalidate SLEEP and WAKE TCSes before flushing new data + - soc: qcom: rpmh-rsc: Clear active mode configuration for wake TCS + - soc: qcom: rpmh-rsc: Allow using free WAKE TCS for active request + - RDMA/mlx5: Verify that QP is created with RQ or SQ + - mtd: rawnand: marvell: Fix the condition on a return code + - mtd: rawnand: marvell: Use nand_cleanup() when the device is not yet + registered + - mtd: rawnand: marvell: Fix probe error path + - mtd: rawnand: timings: Fix default tR_max and tCCS_min timings + - mtd: rawnand: brcmnand: correctly verify erased pages + - mtd: rawnand: brcmnand: fix CS0 layout + - mtd: rawnand: oxnas: Keep track of registered devices + - mtd: rawnand: oxnas: Unregister all devices on error + - mtd: rawnand: oxnas: Release all devices in the _remove() path + - clk: qcom: gcc: Add GPU and NPU clocks for SM8150 + - clk: qcom: gcc: Add missing UFS clocks for SM8150 + - slimbus: core: Fix mismatch in of_node_get/put + - HID: logitech-hidpp: avoid repeated "multiplier = " log messages + - HID: magicmouse: do not set up autorepeat + - HID: quirks: Always poll Obins Anne Pro 2 keyboard + - HID: quirks: Ignore Simply Automated UPB PIM + - ALSA: line6: Perform sanity check for each URB creation + - ALSA: line6: Sync the pending work cancel at disconnection + - ALSA: usb-audio: Fix race against the error recovery URB submission + - ALSA: hda/realtek - change to suitable link model for ASUS platform + - ALSA: hda/realtek: enable headset mic of ASUS ROG Zephyrus G14(G401) series + with ALC289 + - ALSA: hda/realtek: Enable headset mic of Acer TravelMate B311R-31 with + ALC256 + - ALSA: hda/realtek - Enable Speaker for ASUS UX533 and UX534 + - ALSA: hda/realtek - Enable Speaker for ASUS UX563 + - USB: c67x00: fix use after free in c67x00_giveback_urb + - usb: dwc2: Fix shutdown callback in platform + - usb: chipidea: core: add wakeup support for extcon + - usb: gadget: function: fix missing spinlock in f_uac1_legacy + - USB: serial: iuu_phoenix: fix memory corruption + - USB: serial: cypress_m8: enable Simply Automated UPB PIM + - USB: serial: ch341: add new Product ID for CH340 + - USB: serial: option: add GosunCn GM500 series + - virt: vbox: Fix VBGL_IOCTL_VMMDEV_REQUEST_BIG and _LOG req numbers to match + upstream + - virt: vbox: Fix guest capabilities mask check + - Revert "tty: xilinx_uartps: Fix missing id assignment to the console" + - virtio: virtio_console: add missing MODULE_DEVICE_TABLE() for rproc serial + - serial: mxs-auart: add missed iounmap() in probe failure and remove + - ovl: fix regression with re-formatted lower squashfs + - ovl: inode reference leak in ovl_is_inuse true case. + - ovl: relax WARN_ON() when decoding lower directory file handle + - ovl: fix unneeded call to ovl_change_flags() + - fuse: ignore 'data' argument of mount(..., MS_REMOUNT) + - fuse: use ->reconfigure() instead of ->remount_fs() + - fuse: Fix parameter for FS_IOC_{GET,SET}FLAGS + - Revert "zram: convert remaining CLASS_ATTR() to CLASS_ATTR_RO()" + - mei: bus: don't clean driver pointer + - Input: i8042 - add Lenovo XiaoXin Air 12 to i8042 nomux list + - uio_pdrv_genirq: Remove warning when irq is not specified + - uio_pdrv_genirq: fix use without device tree and no interrupt + - scsi: megaraid_sas: Remove undefined ENABLE_IRQ_POLL macro + - timer: Prevent base->clk from moving backward + - timer: Fix wheel index calculation on last level + - riscv: use 16KB kernel stack on 64-bit + - hwmon: (emc2103) fix unable to change fan pwm1_enable attribute + - powerpc/book3s64/pkeys: Fix pkey_access_permitted() for execute disable pkey + - powerpc/pseries/svm: Fix incorrect check for shared_lppaca_size + - intel_th: pci: Add Jasper Lake CPU support + - intel_th: pci: Add Tiger Lake PCH-H support + - intel_th: pci: Add Emmitsburg PCH support + - intel_th: Fix a NULL dereference when hub driver is not loaded + - dmaengine: fsl-edma: Fix NULL pointer exception in fsl_edma_tx_handler + - dmaengine: mcf-edma: Fix NULL pointer exception in mcf_edma_tx_handler + - dmaengine: fsl-edma-common: correct DSIZE_32BYTE + - misc: atmel-ssc: lock with mutex instead of spinlock + - thermal: int3403_thermal: Downgrade error message + - thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power + - arm64: ptrace: Override SPSR.SS when single-stepping is enabled + - arm64: ptrace: Consistently use pseudo-singlestep exceptions + - arm64: compat: Ensure upper 32 bits of x0 are zero on syscall return + - sched: Fix unreliable rseq cpu_id for new tasks + - sched/fair: handle case of task_h_load() returning 0 + - genirq/affinity: Handle affinity setting on inactive interrupts correctly + - drm/amdgpu/sdma5: fix wptr overwritten in ->get_wptr() + - drm/i915/gt: Ignore irq enabling on the virtual engines + - block: fix splitting segments on boundary masks + - block: fix get_max_segment_size() overflow on 32bit arch + - libceph: don't omit recovery_deletes in target_copy() + - rxrpc: Fix trace string + - spi: sprd: switch the sequence of setting WDG_LOAD_LOW and _HIGH + - ionic: export features for vlans to use + - iommu/vt-d: Make Intel SVM code 64-bit only + - drm/i915/gvt: Fix two CFL MMIO handling caused by regression. + - gpio: pca953x: disable regmap locking for automatic address incrementing + - Linux 5.4.53 + * linux-libc-dev broken for crossbuilding, Multi-Arch:same violation + (LP: #1886188) + - [Packaging] Produce linux-libc-dev package for riscv64 + - [Debian] Disallow building linux-libc-dev from linux-riscv + * [UBUNTU 20.04] DIF and DIX support in zfcp (s390x) is broken and the kernel + crashes unconditionally (LP: #1887124) + - scsi: zfcp: signal incomplete or error for sync exchange config/port data + - scsi: zfcp: diagnostics buffer caching and use for exchange port data + - scsi: zfcp: add diagnostics buffer for exchange config data + - scsi: zfcp: support retrieval of SFP Data via Exchange Port Data + - scsi: zfcp: introduce sysfs interface for diagnostics of local SFP + transceiver + - scsi: zfcp: implicitly refresh port-data diagnostics when reading sysfs + - scsi: zfcp: introduce sysfs interface to read the local B2B-Credit + - scsi: zfcp: implicitly refresh config-data diagnostics when reading sysfs + - scsi: zfcp: move maximum age of diagnostic buffers into a per-adapter + variable + - scsi: zfcp: proper indentation to reduce confusion in zfcp_erp_required_act + - scsi: zfcp: fix wrong data and display format of SFP+ temperature + - scsi: zfcp: expose fabric name as common fc_host sysfs attribute + - scsi: zfcp: wire previously driver-specific sysfs attributes also to fc_host + - scsi: zfcp: fix fc_host attributes that should be unknown on local link down + - scsi: zfcp: auto variables for dereferenced structs in open port handler + - scsi: zfcp: report FC Endpoint Security in sysfs + - scsi: zfcp: log FC Endpoint Security of connections + - scsi: zfcp: trace FC Endpoint Security of FCP devices and connections + - scsi: zfcp: enhance handling of FC Endpoint Security errors + - scsi: zfcp: log FC Endpoint Security errors + - scsi: zfcp: use fallthrough; + - scsi: zfcp: Move shost modification after QDIO (re-)open into fenced + function + - scsi: zfcp: Move shost updates during xconfig data handling into fenced + function + - scsi: zfcp: Move fc_host updates during xport data handling into fenced + function + - scsi: zfcp: Fence fc_host updates during link-down handling + - scsi: zfcp: Move p-t-p port allocation to after xport data + - scsi: zfcp: Fence adapter status propagation for common statuses + - scsi: zfcp: Fence early sysfs interfaces for accesses of shost objects + - scsi: zfcp: Move allocation of the shost object to after xconf- and xport- + data + * Enable Quectel EG95 LTE modem [2c7c:0195] (LP: #1886744) + - net: usb: qmi_wwan: add support for Quectel EG95 LTE modem + - USB: serial: option: add Quectel EG95 LTE modem + * Kernel Regression between 5.4.0-26 and 5.4.0-40 causes laptop internal audio + devices to fail to load w/o unacceptable workaround (Lenovo IdeaPad 5 + 15IIL05) (LP: #1886341) + - ASoC: SOF: intel: hda: Modify signature for hda_codec_probe_bus() + - ASoC: SOF: Intel: drop HDA codec upon probe failure + - ASoC: SOF: Intel: hda: move i915 init earlier + * [UBUNTU 20.04] smc: SMC connections hang with later-level implementations + (LP: #1882088) + - net/smc: tolerate future SMCD versions + * zfs: backport AES-GCM performance accelleration (LP: #1881107) + - debian/dkms-versions: update ZFS dkms package version (LP: #1881107) + * Regression in kernel 4.15.0-91 causes kernel panic with Bcache + (LP: #1867916) + - bcache: check and adjust logical block size for backing devices + * [SRU][OEM-5.6/U] Fix r8117 firmware base issue (LP: #1885072) + - r8169: add helper r8168g_phy_param + - r8169: add support for RTL8117 + - r8169: load firmware for RTL8168fp/RTL8117 + - r8169: fix OCP access on RTL8117 + - r8169: fix firmware not resetting tp->ocp_base + * [UBUNTU 20.04] Deflate counters reported by lscpumf are not valid or + available with perf (LP: #1881096) + - s390/cpum_cf: Add new extended counters for IBM z15 + * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757) + - SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups + * shiftfs: fix btrfs regression (LP: #1884767) + - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation" + * Focal update: v5.4.52 upstream stable release (LP: #1887853) + - KVM: s390: reduce number of IO pins to 1 + - spi: spi-fsl-dspi: Adding shutdown hook + - spi: spi-fsl-dspi: Fix lockup if device is removed during SPI transfer + - regmap: fix alignment issue + - perf/x86/rapl: Move RAPL support to common x86 code + - perf/x86/rapl: Fix RAPL config variable bug + - [Packaging] module intel-rapl-perf rename + - ARM: dts: omap4-droid4: Fix spi configuration and increase rate + - drm/ttm: Fix dma_fence refcnt leak when adding move fence + - drm/tegra: hub: Do not enable orphaned window group + - gpu: host1x: Detach driver on unregister + - drm: mcde: Fix display initialization problem + - ASoC: SOF: Intel: add PCI ID for CometLake-S + - ALSA: hda: Intel: add missing PCI IDs for ICL-H, TGL-H and EKL + - spi: spidev: fix a race between spidev_release and spidev_remove + - spi: spidev: fix a potential use-after-free in spidev_release() + - net: ethernet: mvneta: Fix Serdes configuration for SoCs without comphy + - net: ethernet: mvneta: Add 2500BaseX support for SoCs without comphy + - ixgbe: protect ring accesses with READ- and WRITE_ONCE + - i40e: protect ring accesses with READ- and WRITE_ONCE + - ibmvnic: continue to init in CRQ reset returns H_CLOSED + - powerpc/kvm/book3s64: Fix kernel crash with nested kvm & DEBUG_VIRTUAL + - iommu/vt-d: Don't apply gfx quirks to untrusted devices + - drm: panel-orientation-quirks: Add quirk for Asus T101HA panel + - drm: panel-orientation-quirks: Use generic orientation-data for Acer S1003 + - s390/kasan: fix early pgm check handler execution + - cifs: update ctime and mtime during truncate + - ARM: imx6: add missing put_device() call in imx6q_suspend_init() + - scsi: mptscsih: Fix read sense data size + - usb: dwc3: pci: Fix reference count leak in dwc3_pci_resume_work + - block: release bip in a right way in error path + - nvme-rdma: assign completion vector correctly + - x86/entry: Increase entry_stack size to a full page + - sched/core: Check cpus_mask, not cpus_ptr in __set_cpus_allowed_ptr(), to + fix mask corruption + - net: qrtr: Fix an out of bounds read qrtr_endpoint_post() + - gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2 + - gpio: pca953x: Fix GPIO resource leak on Intel Galileo Gen 2 + - nl80211: don't return err unconditionally in nl80211_start_ap() + - drm/mediatek: Check plane visibility in atomic_update + - bpf, sockmap: RCU splat with redirect and strparser error or TLS + - bpf, sockmap: RCU dereferenced psock may be used outside RCU block + - netfilter: ipset: call ip_set_free() instead of kfree() + - net: mvneta: fix use of state->speed + - net: cxgb4: fix return error value in t4_prep_fw + - IB/sa: Resolv use-after-free in ib_nl_make_request() + - net: dsa: microchip: set the correct number of ports + - netfilter: conntrack: refetch conntrack after nf_conntrack_update() + - perf report TUI: Fix segmentation fault in perf_evsel__hists_browse() + - perf intel-pt: Fix recording PEBS-via-PT with registers + - perf intel-pt: Fix PEBS sample for XMM registers + - smsc95xx: check return value of smsc95xx_reset + - smsc95xx: avoid memory leak in smsc95xx_bind + - net: hns3: add a missing uninit debugfs when unload driver + - net: hns3: fix use-after-free when doing self test + - ALSA: compress: fix partial_drain completion state + - RDMA/siw: Fix reporting vendor_part_id + - arm64: kgdb: Fix single-step exception handling oops + - nbd: Fix memory leak in nbd_add_socket + - cxgb4: fix all-mask IP address comparison + - IB/mlx5: Fix 50G per lane indication + - qed: Populate nvm-file attributes while reading nvm config partition. + - net/mlx5: Fix eeprom support for SFP module + - net/mlx5e: Fix 50G per lane indication + - bnxt_en: fix NULL dereference in case SR-IOV configuration fails + - net: macb: fix wakeup test in runtime suspend/resume routines + - net: macb: mark device wake capable when "magic-packet" property present + - net: macb: fix call to pm_runtime in the suspend/resume functions + - mlxsw: spectrum_router: Remove inappropriate usage of WARN_ON() + - mlxsw: pci: Fix use-after-free in case of failed devlink reload + - IB/hfi1: Do not destroy hfi1_wq when the device is shut down + - IB/hfi1: Do not destroy link_wq when the device is shut down + - ALSA: opl3: fix infoleak in opl3 + - ALSA: hda - let hs_mic be picked ahead of hp_mic + - ALSA: usb-audio: add quirk for MacroSilicon MS2109 + - ALSA: usb-audio: Add implicit feedback quirk for RTX6001 + - ALSA: hda/realtek - Fix Lenovo Thinkpad X1 Carbon 7th quirk subdevice id + - ALSA: hda/realtek - Enable audio jacks of Acer vCopperbox with ALC269VC + - ALSA: hda/realtek: Enable headset mic of Acer C20-820 with ALC269VC + - ALSA: hda/realtek: Enable headset mic of Acer Veriton N4660G with ALC269VC + - KVM: arm64: Fix definition of PAGE_HYP_DEVICE + - KVM: arm64: Stop clobbering x0 for HVC_SOFT_RESTART + - KVM: arm64: Annotate hyp NMI-related functions as __always_inline + - KVM: x86: bit 8 of non-leaf PDPEs is not reserved + - KVM: x86: Inject #GP if guest attempts to toggle CR4.LA57 in 64-bit mode + - KVM: x86: Mark CR4.TSD as being possibly owned by the guest + - KVM: arm64: Fix kvm_reset_vcpu() return code being incorrect with SVE + - kallsyms: Refactor kallsyms_show_value() to take cred + - module: Refactor section attr into bin attribute + - module: Do not expose section addresses to non-CAP_SYSLOG + - kprobes: Do not expose probe addresses to non-CAP_SYSLOG + - bpf: Check correct cred for CAP_SYSLOG in bpf_dump_raw_ok() + - btrfs: fix fatal extent_buffer readahead vs releasepage race + - btrfs: fix double put of block group with nocow + - drm/radeon: fix double free + - drm/amdgpu: don't do soft recovery if gpu_recovery=0 + - dm: use noio when sending kobject event + - mmc: meson-gx: limit segments to 1 when dram-access-quirk is needed + - ARC: entry: fix potential EFA clobber when TIF_SYSCALL_TRACE + - ARC: elf: use right ELF_ARCH + - s390/setup: init jump labels before command line parsing + - s390/mm: fix huge pte soft dirty copying + - blk-mq: consider non-idle request as "inflight" in blk_mq_rq_inflight() + - dm writecache: reject asynchronous pmem devices + - perf scripts python: export-to-postgresql.py: Fix struct.pack() int argument + - perf scripts python: exported-sql-viewer.py: Fix zero id in call graph + 'Find' result + - perf scripts python: exported-sql-viewer.py: Fix zero id in call tree 'Find' + result + - perf scripts python: exported-sql-viewer.py: Fix unexpanded 'Find' result + - pwm: jz4740: Fix build failure + - s390: Change s390_kernel_write() return type to match memcpy() + - s390/maccess: add no DAT mode to kernel_write + - Linux 5.4.52 + * Focal update: v5.4.45 upstream stable release (LP: #1882802) // Focal + update: v5.4.52 upstream stable release (LP: #1887853) + - Revert "cgroup: Add memory barriers to plug cgroup_rstat_updated() race + window" + * Focal update: v5.4.51 upstream stable release (LP: #1886995) + - io_uring: make sure async workqueue is canceled on exit + - mm: fix swap cache node allocation mask + - EDAC/amd64: Read back the scrub rate PCI register on F15h + - usbnet: smsc95xx: Fix use-after-free after removal + - sched/debug: Make sd->flags sysctl read-only + - mm/slub.c: fix corrupted freechain in deactivate_slab() + - mm/slub: fix stack overruns with SLUB_STATS + - rxrpc: Fix race between incoming ACK parser and retransmitter + - usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect + - tools lib traceevent: Add append() function helper for appending strings + - tools lib traceevent: Handle __attribute__((user)) in field names + - s390/debug: avoid kernel warning on too large number of pages + - nvme-multipath: set bdi capabilities once + - nvme-multipath: fix deadlock between ana_work and scan_work + - nvme-multipath: fix deadlock due to head->lock + - nvme-multipath: fix bogus request queue reference put + - kgdb: Avoid suspicious RCU usage warning + - selftests: tpm: Use /bin/sh instead of /bin/bash + - crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock() + - drm/msm/dpu: fix error return code in dpu_encoder_init + - rxrpc: Fix afs large storage transmission performance drop + - RDMA/counter: Query a counter before release + - cxgb4: use unaligned conversion for fetching timestamp + - cxgb4: parse TC-U32 key values and masks natively + - cxgb4: fix endian conversions for L4 ports in filters + - cxgb4: use correct type for all-mask IP address comparison + - cxgb4: fix SGE queue dump destination buffer context + - hwmon: (max6697) Make sure the OVERT mask is set correctly + - hwmon: (acpi_power_meter) Fix potential memory leak in + acpi_power_meter_add() + - thermal/drivers/mediatek: Fix bank number settings on mt8183 + - thermal/drivers/rcar_gen3: Fix undefined temperature if negative + - nfsd4: fix nfsdfs reference count loop + - nfsd: fix nfsdfs inode reference count leak + - drm: sun4i: hdmi: Remove extra HPD polling + - virtio-blk: free vblk-vqs in error path of virtblk_probe() + - SMB3: Honor 'posix' flag for multiuser mounts + - nvme: fix identify error status silent ignore + - nvme: fix a crash in nvme_mpath_add_disk + - samples/vfs: avoid warning in statx override + - i2c: algo-pca: Add 0x78 as SCL stuck low status for PCA9665 + - i2c: mlxcpld: check correct size of maximum RECV_LEN packet + - spi: spi-fsl-dspi: Fix external abort on interrupt in resume or exit paths + - nfsd: apply umask on fs without ACL support + - Revert "ALSA: usb-audio: Improve frames size computation" + - SMB3: Honor 'seal' flag for multiuser mounts + - SMB3: Honor persistent/resilient handle flags for multiuser mounts + - SMB3: Honor lease disabling for multiuser mounts + - SMB3: Honor 'handletimeout' flag for multiuser mounts + - cifs: Fix the target file was deleted when rename failed. + - MIPS: lantiq: xway: sysctrl: fix the GPHY clock alias names + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen + - drm/amd/display: Only revalidate bandwidth on medium and fast updates + - drm/amdgpu: use %u rather than %d for sclk/mclk + - drm/amdgpu/atomfirmware: fix vram_info fetching for renoir + - dma-buf: Move dma_buf_release() from fops to dentry_ops + - irqchip/gic: Atomically update affinity + - mm, compaction: fully assume capture is not NULL in compact_zone_order() + - mm, compaction: make capture control handling safe wrt interrupts + - x86/resctrl: Fix memory bandwidth counter width for AMD + - dm zoned: assign max_io_len correctly + - [Config] updateconfigs for EFI_CUSTOM_SSDT_OVERLAYS + - efi: Make it possible to disable efivar_ssdt entirely + - Linux 5.4.51 + * Focal update: v5.4.50 upstream stable release (LP: #1885942) + - block/bio-integrity: don't free 'buf' if bio_integrity_add_page() failed + - enetc: Fix tx rings bitmap iteration range, irq handling + - geneve: allow changing DF behavior after creation + - ibmveth: Fix max MTU limit + - mld: fix memory leak in ipv6_mc_destroy_dev() + - mvpp2: ethtool rxtx stats fix + - net: bridge: enfore alignment for ethernet address + - net: core: reduce recursion limit value + - net: Do not clear the sock TX queue in sk_set_socket() + - net: fix memleak in register_netdevice() + - net: Fix the arp error in some cases + - net: increment xmit_recursion level in dev_direct_xmit() + - net: usb: ax88179_178a: fix packet alignment padding + - openvswitch: take into account de-fragmentation/gso_size in + execute_check_pkt_len + - rocker: fix incorrect error handling in dma_rings_init + - rxrpc: Fix notification call on completion of discarded calls + - sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket + - tcp: don't ignore ECN CWR on pure ACK + - tcp: grow window for OOO packets only for SACK flows + - tg3: driver sleeps indefinitely when EEH errors exceed eeh_max_freezes + - ip6_gre: fix use-after-free in ip6gre_tunnel_lookup() + - net: phy: Check harder for errors in get_phy_id() + - ip_tunnel: fix use-after-free in ip_tunnel_lookup() + - sch_cake: don't try to reallocate or unshare skb unconditionally + - sch_cake: don't call diffserv parsing code when it is not needed + - sch_cake: fix a few style nits + - tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT + - Revert "i2c: tegra: Fix suspending in active runtime PM state" + - btrfs: fix a block group ref counter leak after failure to remove block + group + - net: sched: export __netdev_watchdog_up() + - fix a braino in "sparc32: fix register window handling in + genregs32_[gs]et()" + - ALSA: usb-audio: Fix potential use-after-free of streams + - binder: fix null deref of proc->context + - USB: ohci-sm501: Add missed iounmap() in remove + - usb: dwc2: Postponed gadget registration to the udc class driver + - usb: add USB_QUIRK_DELAY_INIT for Logitech C922 + - USB: ehci: reopen solution for Synopsys HC bug + - usb: host: xhci-mtk: avoid runtime suspend when removing hcd + - xhci: Poll for U0 after disabling USB2 LPM + - usb: host: ehci-exynos: Fix error check in exynos_ehci_probe() + - usb: typec: tcpci_rt1711h: avoid screaming irq causing boot hangs + - ALSA: usb-audio: Add implicit feedback quirk for SSL2+. + - ALSA: usb-audio: add quirk for Denon DCD-1500RE + - ALSA: usb-audio: add quirk for Samsung USBC Headset (AKG) + - ALSA: usb-audio: Fix OOB access of mixer element list + - usb: cdns3: trace: using correct dir value + - usb: cdns3: ep0: fix the test mode set incorrectly + - usb: cdns3: ep0: add spinlock for cdns3_check_new_setup + - scsi: qla2xxx: Keep initiator ports after RSCN + - scsi: zfcp: Fix panic on ERP timeout for previously dismissed ERP action + - cifs: Fix cached_fid refcnt leak in open_shroot + - cifs/smb3: Fix data inconsistent when punch hole + - cifs/smb3: Fix data inconsistent when zero file range + - xhci: Fix incorrect EP_STATE_MASK + - xhci: Fix enumeration issue when setting max packet size for FS devices. + - xhci: Return if xHCI doesn't support LPM + - cdc-acm: Add DISABLE_ECHO quirk for Microchip/SMSC chip + - loop: replace kill_bdev with invalidate_bdev + - IB/mad: Fix use after free when destroying MAD agent + - IB/hfi1: Fix module use count flaw due to leftover module put calls + - bus: ti-sysc: Flush posted write on enable and disable + - bus: ti-sysc: Ignore clockactivity unless specified as a quirk + - ARM: OMAP2+: Fix legacy mode dss_reset + - xfrm: Fix double ESP trailer insertion in IPsec crypto offload. + - ASoC: q6asm: handle EOS correctly + - efi/tpm: Verify event log header before parsing + - efi/esrt: Fix reference count leak in esre_create_sysfs_entry. + - ASoc: q6afe: add support to get port direction + - ASoC: qcom: common: set correct directions for dailinks + - regualtor: pfuze100: correct sw1a/sw2 on pfuze3000 + - RDMA/siw: Fix pointer-to-int-cast warning in siw_rx_pbl() + - ASoC: fsl_ssi: Fix bclk calculation for mono channel + - samples/bpf: xdp_redirect_cpu: Set MAX_CPUS according to NR_CPUS + - bpf, xdp, samples: Fix null pointer dereference in *_user code + - ARM: dts: am335x-pocketbeagle: Fix mmc0 Write Protect + - ARM: dts: Fix duovero smsc interrupt for suspend + - x86/resctrl: Fix a NULL vs IS_ERR() static checker warning in + rdt_cdp_peer_get() + - regmap: Fix memory leak from regmap_register_patch + - devmap: Use bpf_map_area_alloc() for allocating hash buckets + - bpf: Don't return EINVAL from {get,set}sockopt when optlen > PAGE_SIZE + - ARM: dts: NSP: Correct FA2 mailbox node + - rxrpc: Fix handling of rwind from an ACK packet + - RDMA/rvt: Fix potential memory leak caused by rvt_alloc_rq + - RDMA/qedr: Fix KASAN: use-after-free in ucma_event_handler+0x532 + - RDMA/cma: Protect bind_list and listen_list while finding matching cm id + - ASoC: rockchip: Fix a reference count leak. + - s390/qeth: fix error handling for isolation mode cmds + - RDMA/mad: Fix possible memory leak in ib_mad_post_receive_mads() + - selftests/net: report etf errors correctly + - iommu/vt-d: Enable PCI ACS for platform opt in hint + - iommu/vt-d: Update scalable mode paging structure coherency + - net: qed: fix left elements count calculation + - net: qed: fix async event callbacks unregistering + - net: qede: stop adding events on an already destroyed workqueue + - net: qed: fix NVMe login fails over VFs + - net: qed: fix excessive QM ILT lines consumption + - net: qede: fix PTP initialization on recovery + - net: qede: fix use-after-free on recovery and AER handling + - cxgb4: move handling L2T ARP failures to caller + - ARM: imx5: add missing put_device() call in imx_suspend_alloc_ocram() + - scsi: lpfc: Avoid another null dereference in lpfc_sli4_hba_unset() + - usb: gadget: udc: Potential Oops in error handling code + - usb: renesas_usbhs: getting residue from callback_result + - nvme: don't protect ns mutation with ns->head->lock + - netfilter: ipset: fix unaligned atomic access + - net: bcmgenet: use hardware padding of runt frames + - clk: sifive: allocate sufficient memory for struct __prci_data + - i2c: fsi: Fix the port number field in status register + - i2c: core: check returned size of emulated smbus block read + - afs: Fix storage of cell names + - sched/deadline: Initialize ->dl_boosted + - sched/core: Fix PI boosting between RT and DEADLINE tasks + - sata_rcar: handle pm_runtime_get_sync failure cases + - ata/libata: Fix usage of page address by page_address in + ata_scsi_mode_select_xlat function + - drm/amd/display: Use kfree() to free rgb_user in + calculate_user_regamma_ramp() + - riscv/atomic: Fix sign extension for RV64I + - hwrng: ks-sa - Fix runtime PM imbalance on error + - ibmvnic: Harden device login requests + - net: alx: fix race condition in alx_remove + - test_objagg: Fix potential memory leak in error handling + - pinctrl: qcom: spmi-gpio: fix warning about irq chip reusage + - pinctrl: tegra: Use noirq suspend/resume callbacks + - s390/ptrace: pass invalid syscall numbers to tracing + - s390/ptrace: fix setting syscall number + - s390/vdso: Use $(LD) instead of $(CC) to link vDSO + - s390/vdso: fix vDSO clock_getres() + - arm64: sve: Fix build failure when ARM64_SVE=y and SYSCTL=n + - kbuild: improve cc-option to clean up all temporary files + - recordmcount: support >64k sections + - kprobes: Suppress the suspicious RCU warning on kprobes + - blktrace: break out of blktrace setup on concurrent calls + - block: update hctx map when use multiple maps + - RISC-V: Don't allow write+exec only page mapping request in mmap + - ALSA: hda: Add NVIDIA codec IDs 9a & 9d through a0 to patch table + - ALSA: hda/realtek - Add quirk for MSI GE63 laptop + - ACPI: sysfs: Fix pm_profile_attr type + - erofs: fix partially uninitialized misuse in z_erofs_onlinepage_fixup + - KVM: X86: Fix MSR range of APIC registers in X2APIC mode + - KVM: nVMX: Plumb L2 GPA through to PML emulation + - KVM: VMX: Stop context switching MSR_IA32_UMWAIT_CONTROL + - x86/cpu: Use pinning mask for CR4 bits needing to be 0 + - x86/asm/64: Align start of __clear_user() loop to 16-bytes + - btrfs: fix bytes_may_use underflow when running balance and scrub in + parallel + - btrfs: fix data block group relocation failure due to concurrent scrub + - btrfs: check if a log root exists before locking the log_mutex on unlink + - btrfs: fix failure of RWF_NOWAIT write into prealloc extent beyond eof + - mm/slab: use memzero_explicit() in kzfree() + - ocfs2: avoid inode removal while nfsd is accessing it + - ocfs2: load global_inode_alloc + - ocfs2: fix value of OCFS2_INVALID_SLOT + - ocfs2: fix panic on nfs server over ocfs2 + - mm/memcontrol.c: add missed css_put() + - arm64: perf: Report the PC value in REGS_ABI_32 mode + - arm64: dts: imx8mm-evk: correct ldo1/ldo2 voltage range + - arm64: dts: imx8mn-ddr4-evk: correct ldo1/ldo2 voltage range + - tracing: Fix event trigger to accept redundant spaces + - ring-buffer: Zero out time extend if it is nested and not absolute + - drm/amd: fix potential memleak in err branch + - drm: rcar-du: Fix build error + - drm/radeon: fix fb_div check in ni_init_smc_spll_table() + - drm/amdgpu: add fw release for sdma v5_0 + - Staging: rtl8723bs: prevent buffer overflow in update_sta_support_rate() + - sunrpc: fixed rollback in rpc_gssd_dummy_populate() + - SUNRPC: Properly set the @subbuf parameter of xdr_buf_subsegment() + - pNFS/flexfiles: Fix list corruption if the mirror count changes + - NFSv4 fix CLOSE not waiting for direct IO compeletion + - xprtrdma: Fix handling of RDMA_ERROR replies + - dm writecache: correct uncommitted_block when discarding uncommitted entry + - dm writecache: add cond_resched to loop in persistent_memory_claim() + - xfs: add agf freeblocks verify in xfs_agf_verify + - Revert "tty: hvc: Fix data abort due to race in hvc_open" + - Linux 5.4.50 + * Focal update: v5.4.49 upstream stable release (LP: #1885322) + - power: supply: bq24257_charger: Replace depends on REGMAP_I2C with select + - clk: sunxi: Fix incorrect usage of round_down() + - ASoC: tegra: tegra_wm8903: Support nvidia, headset property + - i2c: piix4: Detect secondary SMBus controller on AMD AM4 chipsets + - ASoC: SOF: imx8: Fix randbuild error + - iio: pressure: bmp280: Tolerate IRQ before registering + - remoteproc: Fix IDR initialisation in rproc_alloc() + - clk: qcom: msm8916: Fix the address location of pll->config_reg + - ASoC: fsl_esai: Disable exception interrupt before scheduling tasklet + - backlight: lp855x: Ensure regulators are disabled on probe failure + - ARM: dts: renesas: Fix IOMMU device node names + - ASoC: davinci-mcasp: Fix dma_chan refcnt leak when getting dma type + - ARM: integrator: Add some Kconfig selections + - ARM: dts: stm32: Add missing ethernet PHY reset on AV96 + - scsi: core: free sgtables in case command setup fails + - scsi: qedi: Check for buffer overflow in qedi_set_path() + - arm64: dts: meson: fixup SCP sram nodes + - ALSA: isa/wavefront: prevent out of bounds write in ioctl + - PCI: Allow pci_resize_resource() for devices on root bus + - scsi: qla2xxx: Fix issue with adapter's stopping state + - Input: edt-ft5x06 - fix get_default register write access + - powerpc/kasan: Fix stack overflow by increasing THREAD_SHIFT + - rtc: mc13xxx: fix a double-unlock issue + - iio: bmp280: fix compensation of humidity + - f2fs: report delalloc reserve as non-free in statfs for project quota + - i2c: pxa: clear all master action bits in i2c_pxa_stop_message() + - remoteproc: qcom_q6v5_mss: map/unmap mpss segments before/after use + - clk: samsung: Mark top ISP and CAM clocks on Exynos542x as critical + - usblp: poison URBs upon disconnect + - serial: 8250: Fix max baud limit in generic 8250 port + - misc: fastrpc: Fix an incomplete memory release in fastrpc_rpmsg_probe() + - misc: fastrpc: fix potential fastrpc_invoke_ctx leak + - dm mpath: switch paths in dm_blk_ioctl() code path + - arm64: dts: armada-3720-turris-mox: forbid SDR104 on SDIO for FCC purposes + - arm64: dts: armada-3720-turris-mox: fix SFP binding + - arm64: dts: juno: Fix GIC child nodes + - pinctrl: ocelot: Fix GPIO interrupt decoding on Jaguar2 + - clk: renesas: cpg-mssr: Fix STBCR suspend/resume handling + - ASoC: SOF: Do nothing when DSP PM callbacks are not set + - arm64: dts: fvp: Fix GIC child nodes + - PCI: aardvark: Don't blindly enable ASPM L0s and don't write to read-only + register + - ps3disk: use the default segment boundary + - arm64: dts: fvp/juno: Fix node address fields + - vfio/pci: fix memory leaks in alloc_perm_bits() + - coresight: tmc: Fix TMC mode read in tmc_read_prepare_etb() + - RDMA/mlx5: Add init2init as a modify command + - scsi: hisi_sas: Do not reset phy timer to wait for stray phy up + - PCI: pci-bridge-emul: Fix PCIe bit conflicts + - m68k/PCI: Fix a memory leak in an error handling path + - gpio: dwapb: Call acpi_gpiochip_free_interrupts() on GPIO chip de- + registration + - usb: gadget: core: sync interrupt before unbind the udc + - powerpc/ptdump: Add _PAGE_COHERENT flag + - mfd: wm8994: Fix driver operation if loaded as modules + - scsi: cxgb3i: Fix some leaks in init_act_open() + - clk: zynqmp: fix memory leak in zynqmp_register_clocks + - scsi: lpfc: Fix lpfc_nodelist leak when processing unsolicited event + - scsi: vhost: Notify TCM about the maximum sg entries supported per command + - clk: clk-flexgen: fix clock-critical handling + - IB/mlx5: Fix DEVX support for MLX5_CMD_OP_INIT2INIT_QP command + - powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 + events run + - nfsd: Fix svc_xprt refcnt leak when setup callback client failed + - PCI: vmd: Filter resource type bits from shadow register + - RDMA/core: Fix several reference count leaks. + - cifs: set up next DFS target before generic_ip_connect() + - ASoC: qcom: q6asm-dai: kCFI fix + - powerpc/crashkernel: Take "mem=" option into account + - pwm: img: Call pm_runtime_put() in pm_runtime_get_sync() failed case + - sparc32: mm: Don't try to free page-table pages if ctor() fails + - yam: fix possible memory leak in yam_init_driver + - NTB: ntb_pingpong: Choose doorbells based on port number + - NTB: Fix the default port and peer numbers for legacy drivers + - mksysmap: Fix the mismatch of '.L' symbols in System.map + - apparmor: fix introspection of of task mode for unconfined tasks + - net: dsa: lantiq_gswip: fix and improve the unsupported interface error + - f2fs: handle readonly filesystem in f2fs_ioc_shutdown() + - ASoC: meson: add missing free_irq() in error path + - bpf, sockhash: Fix memory leak when unlinking sockets in sock_hash_free + - scsi: sr: Fix sr_probe() missing deallocate of device minor + - scsi: ibmvscsi: Don't send host info in adapter info MAD after LPM + - x86/purgatory: Disable various profiling and sanitizing options + - staging: greybus: fix a missing-check bug in gb_lights_light_config() + - arm64: dts: mt8173: fix unit name warnings + - scsi: qedi: Do not flush offload work if ARP not resolved + - arm64: dts: qcom: msm8916: remove unit name for thermal trip points + - ARM: dts: sun8i-h2-plus-bananapi-m2-zero: Fix led polarity + - RDMA/mlx5: Fix udata response upon SRQ creation + - gpio: dwapb: Append MODULE_ALIAS for platform driver + - scsi: qedf: Fix crash when MFW calls for protocol stats while function is + still probing + - pinctrl: rza1: Fix wrong array assignment of rza1l_swio_entries + - virtiofs: schedule blocking async replies in separate worker + - arm64: dts: qcom: fix pm8150 gpio interrupts + - firmware: qcom_scm: fix bogous abuse of dma-direct internals + - staging: gasket: Fix mapping refcnt leak when put attribute fails + - staging: gasket: Fix mapping refcnt leak when register/store fails + - ALSA: usb-audio: Improve frames size computation + - ALSA: usb-audio: Fix racy list management in output queue + - s390/qdio: put thinint indicator after early error + - tty: hvc: Fix data abort due to race in hvc_open + - slimbus: ngd: get drvdata from correct device + - clk: meson: meson8b: Fix the first parent of vid_pll_in_sel + - clk: meson: meson8b: Fix the polarity of the RESET_N lines + - clk: meson: meson8b: Fix the vclk_div{1, 2, 4, 6, 12}_en gate bits + - gpio: pca953x: fix handling of automatic address incrementing + - thermal/drivers/ti-soc-thermal: Avoid dereferencing ERR_PTR + - clk: meson: meson8b: Don't rely on u-boot to init all GP_PLL registers + - ASoC: max98373: reorder max98373_reset() in resume + - soundwire: slave: don't init debugfs on device registration error + - HID: intel-ish-hid: avoid bogus uninitialized-variable warning + - usb: dwc3: gadget: Properly handle ClearFeature(halt) + - usb: dwc3: gadget: Properly handle failed kick_transfer + - staging: wilc1000: Increase the size of wid_list array + - staging: sm750fb: add missing case while setting FB_VISUAL + - PCI: v3-semi: Fix a memory leak in v3_pci_probe() error handling paths + - i2c: pxa: fix i2c_pxa_scream_blue_murder() debug output + - serial: amba-pl011: Make sure we initialize the port.lock spinlock + - drivers: base: Fix NULL pointer exception in __platform_driver_probe() if a + driver developer is foolish + - PCI: rcar: Fix incorrect programming of OB windows + - PCI/ASPM: Allow ASPM on links to PCIe-to-PCI/PCI-X Bridges + - scsi: qla2xxx: Fix warning after FC target reset + - ALSA: firewire-lib: fix invalid assignment to union data for directional + parameter + - power: supply: lp8788: Fix an error handling path in + 'lp8788_charger_probe()' + - power: supply: smb347-charger: IRQSTAT_D is volatile + - ASoC: SOF: core: fix error return code in sof_probe_continue() + - arm64: dts: msm8996: Fix CSI IRQ types + - scsi: target: loopback: Fix READ with data and sensebytes + - scsi: mpt3sas: Fix double free warnings + - SoC: rsnd: add interrupt support for SSI BUSIF buffer + - ASoC: ux500: mop500: Fix some refcounted resources issues + - ASoC: ti: omap-mcbsp: Fix an error handling path in 'asoc_mcbsp_probe()' + - pinctrl: rockchip: fix memleak in rockchip_dt_node_to_map + - dlm: remove BUG() before panic() + - USB: ohci-sm501: fix error return code in ohci_hcd_sm501_drv_probe() + - clk: ti: composite: fix memory leak + - PCI: Fix pci_register_host_bridge() device_register() error handling + - powerpc/64: Don't initialise init_task->thread.regs + - tty: n_gsm: Fix SOF skipping + - tty: n_gsm: Fix waking up upper tty layer when room available + - ALSA: usb-audio: Add duplex sound support for USB devices using implicit + feedback + - HID: Add quirks for Trust Panora Graphic Tablet + - PCI/PM: Assume ports without DLL Link Active train links in 100 ms + - habanalabs: increase timeout during reset + - ipmi: use vzalloc instead of kmalloc for user creation + - powerpc/64s/exception: Fix machine check no-loss idle wakeup + - powerpc/pseries/ras: Fix FWNMI_VALID off by one + - drivers: phy: sr-usb: do not use internal fsm for USB2 phy init + - powerpc/ps3: Fix kexec shutdown hang + - vfio-pci: Mask cap zero + - usb/ohci-platform: Fix a warning when hibernating + - drm/msm/mdp5: Fix mdp5_init error path for failed mdp5_kms allocation + - ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT8-A tablet + - USB: host: ehci-mxc: Add error handling in ehci_mxc_drv_probe() + - tty: n_gsm: Fix bogus i++ in gsm_data_kick + - fpga: dfl: afu: Corrected error handling levels + - clk: samsung: exynos5433: Add IGNORE_UNUSED flag to sclk_i2s1 + - RDMA/hns: Bugfix for querying qkey + - RDMA/hns: Fix cmdq parameter of querying pf timer resource + - scsi: target: tcmu: Userspace must not complete queued commands + - firmware: imx: scu: Fix possible memory leak in imx_scu_probe() + - fuse: fix copy_file_range cache issues + - fuse: copy_file_range should truncate cache + - arm64: tegra: Fix ethernet phy-mode for Jetson Xavier + - arm64: tegra: Fix flag for 64-bit resources in 'ranges' property + - powerpc/64s/pgtable: fix an undefined behaviour + - dm zoned: return NULL if dmz_get_zone_for_reclaim() fails to find a zone + - PCI/PTM: Inherit Switch Downstream Port PTM settings from Upstream Port + - PCI: dwc: Fix inner MSI IRQ domain registration + - PCI: amlogic: meson: Don't use FAST_LINK_MODE to set up link + - IB/cma: Fix ports memory leak in cma_configfs + - watchdog: da9062: No need to ping manually before setting timeout + - usb: dwc2: gadget: move gadget resume after the core is in L0 state + - USB: gadget: udc: s3c2410_udc: Remove pointless NULL check in + s3c2410_udc_nuke + - usb: gadget: lpc32xx_udc: don't dereference ep pointer before null check + - usb: gadget: fix potential double-free in m66592_probe. + - usb: gadget: Fix issue with config_ep_by_speed function + - scripts: headers_install: Exit with error on config leak + - RDMA/iw_cxgb4: cleanup device debugfs entries on ULD remove + - x86/apic: Make TSC deadline timer detection message visible + - mfd: stmfx: Reset chip on resume as supply was disabled + - mfd: stmfx: Fix stmfx_irq_init error path + - mfd: stmfx: Disable IRQ in suspend to avoid spurious interrupt + - powerpc/32s: Don't warn when mapping RO data ROX. + - ASoC: fix incomplete error-handling in img_i2s_in_probe. + - scsi: target: tcmu: Fix a use after free in tcmu_check_expired_queue_cmd() + - clk: bcm2835: Fix return type of bcm2835_register_gate + - scsi: ufs-qcom: Fix scheduling while atomic issue + - KVM: PPC: Book3S HV: Ignore kmemleak false positives + - KVM: PPC: Book3S: Fix some RCU-list locks + - clk: sprd: return correct type of value for _sprd_pll_recalc_rate + - clk: ast2600: Fix AHB clock divider for A1 + - misc: xilinx-sdfec: improve get_user_pages_fast() error handling + - /dev/mem: Revoke mappings when a driver claims the region + - net: sunrpc: Fix off-by-one issues in 'rpc_ntop6' + - NFSv4.1 fix rpc_call_done assignment for BIND_CONN_TO_SESSION + - of: Fix a refcounting bug in __of_attach_node_sysfs() + - input: i8042 - Remove special PowerPC handling + - powerpc/4xx: Don't unmap NULL mbase + - extcon: adc-jack: Fix an error handling path in 'adc_jack_probe()' + - ASoC: fsl_asrc_dma: Fix dma_chan leak when config DMA channel failed + - vfio/mdev: Fix reference count leak in add_mdev_supported_type + - rtc: rv3028: Add missed check for devm_regmap_init_i2c() + - mailbox: zynqmp-ipi: Fix NULL vs IS_ERR() check in zynqmp_ipi_mbox_probe() + - rxrpc: Adjust /proc/net/rxrpc/calls to display call->debug_id not user_ID + - openrisc: Fix issue with argument clobbering for clone/fork + - drm/nouveau/disp/gm200-: fix NV_PDISP_SOR_HDMI2_CTRL(n) selection + - ceph: don't return -ESTALE if there's still an open file + - nfsd4: make drc_slab global, not per-net + - gfs2: Allow lock_nolock mount to specify jid=X + - scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj + - scsi: ufs: Don't update urgent bkops level when toggling auto bkops + - pinctrl: imxl: Fix an error handling path in 'imx1_pinctrl_core_probe()' + - pinctrl: freescale: imx: Fix an error handling path in 'imx_pinctrl_probe()' + - nfsd: safer handling of corrupted c_type + - drm/amd/display: Revalidate bandwidth before commiting DC updates + - crypto: omap-sham - add proper load balancing support for multicore + - geneve: change from tx_error to tx_dropped on missing metadata + - lib/zlib: remove outdated and incorrect pre-increment optimization + - include/linux/bitops.h: avoid clang shift-count-overflow warnings + - selftests/vm/pkeys: fix alloc_random_pkey() to make it really random + - blktrace: use errno instead of bi_status + - blktrace: fix endianness in get_pdu_int() + - blktrace: fix endianness for blk_log_remap() + - gfs2: fix use-after-free on transaction ail lists + - net: marvell: Fix OF_MDIO config check + - ntb_perf: pass correct struct device to dma_alloc_coherent + - ntb_tool: pass correct struct device to dma_alloc_coherent + - NTB: ntb_tool: reading the link file should not end in a NULL byte + - NTB: Revert the change to use the NTB device dev for DMA allocations + - NTB: perf: Don't require one more memory window than number of peers + - NTB: perf: Fix support for hardware that doesn't have port numbers + - NTB: perf: Fix race condition when run with ntb_test + - NTB: ntb_test: Fix bug when counting remote files + - i2c: icy: Fix build with CONFIG_AMIGA_PCMCIA=n + - drivers/perf: hisi: Fix wrong value for all counters enable + - selftests/net: in timestamping, strncpy needs to preserve null byte + - f2fs: don't return vmalloc() memory from f2fs_kmalloc() + - afs: Fix memory leak in afs_put_sysnames() + - ASoC: core: only convert non DPCM link to DPCM link + - ASoC: SOF: nocodec: conditionally set dpcm_capture/dpcm_playback flags + - ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT10-A tablet + - ASoC: rt5645: Add platform-data for Asus T101HA + - bpf/sockmap: Fix kernel panic at __tcp_bpf_recvmsg + - bpf, sockhash: Synchronize delete from bucket list on map free + - tracing/probe: Fix bpf_task_fd_query() for kprobes and uprobes + - drm/sun4i: hdmi ddc clk: Fix size of m divider + - libbpf: Handle GCC noreturn-turned-volatile quirk + - scsi: acornscsi: Fix an error handling path in acornscsi_probe() + - x86/idt: Keep spurious entries unset in system_vectors + - net/filter: Permit reading NET in load_bytes_relative when MAC not set + - nvme-pci: use simple suspend when a HMB is enabled + - nfs: set invalid blocks after NFSv4 writes + - xdp: Fix xsk_generic_xmit errno + - iavf: fix speed reporting over virtchnl + - bpf: Fix memlock accounting for sock_hash + - usb/xhci-plat: Set PM runtime as active on resume + - usb: host: ehci-platform: add a quirk to avoid stuck + - usb/ehci-platform: Set PM runtime as active on resume + - perf report: Fix NULL pointer dereference in + hists__fprintf_nr_sample_events() + - perf stat: Fix NULL pointer dereference + - ext4: stop overwrite the errcode in ext4_setup_super + - bcache: fix potential deadlock problem in btree_gc_coalesce + - powerpc: Fix kernel crash in show_instructions() w/DEBUG_VIRTUAL + - afs: Fix non-setting of mtime when writing into mmap + - afs: afs_write_end() should change i_size under the right lock + - afs: Fix EOF corruption + - afs: Always include dir in bulk status fetch from afs_do_lookup() + - afs: Set error flag rather than return error from file status decode + - afs: Fix the mapping of the UAEOVERFLOW abort code + - bnxt_en: Return from timer if interface is not in open state. + - scsi: ufs-bsg: Fix runtime PM imbalance on error + - block: Fix use-after-free in blkdev_get() + - mvpp2: remove module bugfix + - arm64: hw_breakpoint: Don't invoke overflow handler on uaccess watchpoints + - drm: encoder_slave: fix refcouting error for modules + - ext4: fix partial cluster initialization when splitting extent + - ext4: avoid utf8_strncasecmp() with unstable name + - drm/dp_mst: Reformat drm_dp_check_act_status() a bit + - drm/qxl: Use correct notify port address when creating cursor ring + - drm/amdgpu: Replace invalid device ID with a valid device ID + - selinux: fix double free + - jbd2: clean __jbd2_journal_abort_hard() and __journal_abort_soft() + - ext4: avoid race conditions when remounting with options that change dax + - drm/dp_mst: Increase ACT retry timeout to 3s + - drm/amd/display: Use swap() where appropriate + - x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld + - block: nr_sects_write(): Disable preemption on seqcount write + - net/mlx5: DR, Fix freeing in dr_create_rc_qp() + - f2fs: split f2fs_d_compare() from f2fs_match_name() + - f2fs: avoid utf8_strncasecmp() with unstable name + - s390: fix syscall_get_error for compat processes + - drm/i915: Fix AUX power domain toggling across TypeC mode resets + - drm/msm: Check for powered down HW in the devfreq callbacks + - drm/i915/gem: Avoid iterating an empty list + - drm/i915: Whitelist context-local timestamp in the gen9 cmdparser + - drm/connector: notify userspace on hotplug after register complete + - drm/amd/display: Use kvfree() to free coeff in build_regamma() + - drm/i915/icl+: Fix hotplug interrupt disabling after storm detection + - Revert "drm/amd/display: disable dcn20 abm feature for bring up" + - crypto: algif_skcipher - Cap recv SG list at ctx->used + - crypto: algboss - don't wait during notifier callback + - tracing/probe: Fix memleak in fetch_op_data operations + - kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex + - kretprobe: Prevent triggering kretprobe from within kprobe_flush_task + - e1000e: Do not wake up the system via WOL if device wakeup is disabled + - net: octeon: mgmt: Repair filling of RX ring + - pwm: jz4740: Enhance precision in calculation of duty cycle + - sched/rt, net: Use CONFIG_PREEMPTION.patch + - net: core: device_rename: Use rwsem instead of a seqcount + - Linux 5.4.49 + * Computer is frozen after suspend (LP: #1867983) // Focal update: v5.4.49 + upstream stable release (LP: #1885322) + - libata: Use per port sync for detach + * Focal update: v5.4.48 upstream stable release (LP: #1885023) + - ACPI: GED: use correct trigger type field in _Exx / _Lxx handling + - drm/amdgpu: fix and cleanup amdgpu_gem_object_close v4 + - ath10k: Fix the race condition in firmware dump work queue + - drm: bridge: adv7511: Extend list of audio sample rates + - media: staging: imgu: do not hold spinlock during freeing mmu page table + - media: imx: imx7-mipi-csis: Cleanup and fix subdev pad format handling + - crypto: ccp -- don't "select" CONFIG_DMADEVICES + - media: vicodec: Fix error codes in probe function + - media: si2157: Better check for running tuner in init + - objtool: Ignore empty alternatives + - spi: spi-mem: Fix Dual/Quad modes on Octal-capable devices + - drm/amdgpu: Init data to avoid oops while reading pp_num_states. + - arm64/kernel: Fix range on invalidating dcache for boot page tables + - libbpf: Fix memory leak and possible double-free in hashmap__clear + - spi: pxa2xx: Apply CS clk quirk to BXT + - x86,smap: Fix smap_{save,restore}() alternatives + - sched/fair: Refill bandwidth before scaling + - net: atlantic: make hw_get_regs optional + - net: ena: fix error returning in ena_com_get_hash_function() + - efi/libstub/x86: Work around LLVM ELF quirk build regression + - ath10k: remove the max_sched_scan_reqs value + - arm64: cacheflush: Fix KGDB trap detection + - media: staging: ipu3: Fix stale list entries on parameter queue failure + - rtw88: fix an issue about leak system resources + - spi: dw: Zero DMA Tx and Rx configurations on stack + - ACPICA: Dispatcher: add status checks + - block: alloc map and request for new hardware queue + - arm64: insn: Fix two bugs in encoding 32-bit logical immediates + - block: reset mapping if failed to update hardware queue count + - drm: rcar-du: Set primary plane zpos immutably at initializing + - lockdown: Allow unprivileged users to see lockdown status + - ixgbe: Fix XDP redirect on archs with PAGE_SIZE above 4K + - platform/x86: dell-laptop: don't register micmute LED if there is no token + - MIPS: Loongson: Build ATI Radeon GPU driver as module + - Bluetooth: Add SCO fallback for invalid LMP parameters error + - kgdb: Disable WARN_CONSOLE_UNLOCKED for all kgdb + - kgdb: Prevent infinite recursive entries to the debugger + - pmu/smmuv3: Clear IRQ affinity hint on device removal + - ACPI/IORT: Fix PMCG node single ID mapping handling + - mips: Fix cpu_has_mips64r1/2 activation for MIPS32 CPUs + - spi: dw: Enable interrupts in accordance with DMA xfer mode + - clocksource: dw_apb_timer: Make CPU-affiliation being optional + - clocksource: dw_apb_timer_of: Fix missing clockevent timers + - media: dvbdev: Fix tuner->demod media controller link + - btrfs: account for trans_block_rsv in may_commit_transaction + - btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums + - ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE + - batman-adv: Revert "disable ethtool link speed detection when auto + negotiation off" + - ice: Fix memory leak + - ice: Fix for memory leaks and modify ICE_FREE_CQ_BUFS + - mmc: meson-mx-sdio: trigger a soft reset after a timeout or CRC error + - Bluetooth: btmtkuart: Improve exception handling in btmtuart_probe() + - spi: dw: Fix Rx-only DMA transfers + - x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit + - net: vmxnet3: fix possible buffer overflow caused by bad DMA value in + vmxnet3_get_rss() + - x86: fix vmap arguments in map_irq_stack + - staging: android: ion: use vmap instead of vm_map_ram + - ath10k: fix kernel null pointer dereference + - media: staging/intel-ipu3: Implement lock for stream on/off operations + - spi: Respect DataBitLength field of SpiSerialBusV2() ACPI resource + - brcmfmac: fix wrong location to get firmware feature + - regulator: qcom-rpmh: Fix typos in pm8150 and pm8150l + - tools api fs: Make xxx__mountpoint() more scalable + - e1000: Distribute switch variables for initialization + - dt-bindings: display: mediatek: control dpi pins mode to avoid leakage + - drm/mediatek: set dpi pin mode to gpio low to avoid leakage current + - audit: fix a net reference leak in audit_send_reply() + - media: dvb: return -EREMOTEIO on i2c transfer failure. + - media: platform: fcp: Set appropriate DMA parameters + - MIPS: Make sparse_init() using top-down allocation + - ath10k: add flush tx packets for SDIO chip + - Bluetooth: btbcm: Add 2 missing models to subver tables + - audit: fix a net reference leak in audit_list_rules_send() + - Drivers: hv: vmbus: Always handle the VMBus messages on CPU0 + - dpaa2-eth: fix return codes used in ndo_setup_tc + - netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported + - selftests/bpf: Fix memory leak in extract_build_id() + - net: bcmgenet: set Rx mode before starting netif + - net: bcmgenet: Fix WoL with password after deep sleep + - lib/mpi: Fix 64-bit MIPS build with Clang + - exit: Move preemption fixup up, move blocking operations down + - sched/core: Fix illegal RCU from offline CPUs + - drivers/perf: hisi: Fix typo in events attribute array + - iocost_monitor: drop string wrap around numbers when outputting json + - net: lpc-enet: fix error return code in lpc_mii_init() + - selinux: fix error return code in policydb_read() + - drivers: net: davinci_mdio: fix potential NULL dereference in + davinci_mdio_probe() + - media: cec: silence shift wrapping warning in __cec_s_log_addrs() + - net: allwinner: Fix use correct return type for ndo_start_xmit() + - powerpc/spufs: fix copy_to_user while atomic + - libertas_tf: avoid a null dereference in pointer priv + - xfs: clean up the error handling in xfs_swap_extents + - Crypto/chcr: fix for ccm(aes) failed test + - MIPS: Truncate link address into 32bit for 32bit kernel + - mips: cm: Fix an invalid error code of INTVN_*_ERR + - kgdb: Fix spurious true from in_dbg_master() + - xfs: reset buffer write failure state on successful completion + - xfs: fix duplicate verification from xfs_qm_dqflush() + - platform/x86: intel-vbtn: Use acpi_evaluate_integer() + - platform/x86: intel-vbtn: Split keymap into buttons and switches parts + - platform/x86: intel-vbtn: Do not advertise switches to userspace if they are + not there + - platform/x86: intel-vbtn: Also handle tablet-mode switch on "Detachable" and + "Portable" chassis-types + - iwlwifi: avoid debug max amsdu config overwriting itself + - nvme: refine the Qemu Identify CNS quirk + - nvme-pci: align io queue count with allocted nvme_queue in nvme_probe + - nvme-tcp: use bh_lock in data_ready + - ath10k: Remove msdu from idr when management pkt send fails + - wcn36xx: Fix error handling path in 'wcn36xx_probe()' + - net: qed*: Reduce RX and TX default ring count when running inside kdump + kernel + - drm/mcde: dsi: Fix return value check in mcde_dsi_bind() + - mt76: avoid rx reorder buffer overflow + - md: don't flush workqueue unconditionally in md_open + - raid5: remove gfp flags from scribble_alloc() + - iocost: don't let vrate run wild while there's no saturation signal + - veth: Adjust hard_start offset on redirect XDP frames + - net/mlx5e: IPoIB, Drop multicast packets that this interface sent + - rtlwifi: Fix a double free in _rtl_usb_tx_urb_setup() + - mwifiex: Fix memory corruption in dump_station + - kgdboc: Use a platform device to handle tty drivers showing up late + - x86/boot: Correct relocation destination on old linkers + - sched: Defend cfs and rt bandwidth quota against overflow + - mips: MAAR: Use more precise address mask + - mips: Add udelay lpj numbers adjustment + - crypto: stm32/crc32 - fix ext4 chksum BUG_ON() + - crypto: stm32/crc32 - fix run-time self test issue. + - crypto: stm32/crc32 - fix multi-instance + - drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and + raven + - drm/amdgpu: Sync with VM root BO when switching VM to CPU update mode + - selftests/bpf: CONFIG_IPV6_SEG6_BPF required for test_seg6_loop.o + - x86/mm: Stop printing BRK addresses + - MIPS: tools: Fix resource leak in elf-entry.c + - m68k: mac: Don't call via_flush_cache() on Mac IIfx + - btrfs: improve global reserve stealing logic + - btrfs: qgroup: mark qgroup inconsistent if we're inherting snapshot to a new + qgroup + - macvlan: Skip loopback packets in RX handler + - PCI: Don't disable decoding when mmio_always_on is set + - MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe() + - bcache: fix refcount underflow in bcache_device_free() + - mmc: sdhci-msm: Set SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 quirk + - staging: greybus: sdio: Respect the cmd->busy_timeout from the mmc core + - mmc: via-sdmmc: Respect the cmd->busy_timeout from the mmc core + - ice: fix potential double free in probe unrolling + - ixgbe: fix signed-integer-overflow warning + - iwlwifi: mvm: fix aux station leak + - mmc: sdhci-esdhc-imx: fix the mask for tuning start point + - spi: dw: Return any value retrieved from the dma_transfer callback + - cpuidle: Fix three reference count leaks + - platform/x86: hp-wmi: Convert simple_strtoul() to kstrtou32() + - platform/x86: intel-hid: Add a quirk to support HP Spectre X2 (2015) + - platform/x86: intel-vbtn: Only blacklist SW_TABLET_MODE on the 9 / "Laptop" + chasis-type + - platform/x86: asus_wmi: Reserve more space for struct bias_args + - libbpf: Fix perf_buffer__free() API for sparse allocs + - bpf: Fix map permissions check + - bpf: Refactor sockmap redirect code so its easy to reuse + - bpf: Fix running sk_skb program types with ktls + - selftests/bpf, flow_dissector: Close TAP device FD after the test + - kasan: stop tests being eliminated as dead code with FORTIFY_SOURCE + - string.h: fix incompatibility between FORTIFY_SOURCE and KASAN + - btrfs: free alien device after device add + - btrfs: include non-missing as a qualifier for the latest_bdev + - btrfs: send: emit file capabilities after chown + - btrfs: force chunk allocation if our global rsv is larger than metadata + - btrfs: fix error handling when submitting direct I/O bio + - btrfs: fix wrong file range cleanup after an error filling dealloc range + - btrfs: fix space_info bytes_may_use underflow after nocow buffered write + - btrfs: fix space_info bytes_may_use underflow during space cache writeout + - powerpc/mm: Fix conditions to perform MMU specific management by blocks on + PPC32. + - mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked() + - mm: initialize deferred pages with interrupts enabled + - mm/pagealloc.c: call touch_nmi_watchdog() on max order boundaries in + deferred init + - mm: call cond_resched() from deferred_init_memmap() + - ima: Fix ima digest hash table key calculation + - ima: Switch to ima_hash_algo for boot aggregate + - ima: Evaluate error in init_ima() + - ima: Directly assign the ima_default_policy pointer to ima_rules + - ima: Call ima_calc_boot_aggregate() in ima_eventdigest_init() + - ima: Remove __init annotation from ima_pcrread() + - evm: Fix possible memory leak in evm_calc_hmac_or_hash() + - ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max + - ext4: fix error pointer dereference + - ext4: fix race between ext4_sync_parent() and rename() + - PCI: Add ACS quirk for Intel Root Complex Integrated Endpoints + - PCI: Add Loongson vendor ID + - x86/amd_nb: Add AMD family 17h model 60h PCI IDs + - ima: Remove redundant policy rule set in add_rules() + - ima: Set again build_ima_appraise variable + - PCI: Program MPS for RCiEP devices + - e1000e: Relax condition to trigger reset for ME workaround + - carl9170: remove P2P_GO support + - media: go7007: fix a miss of snd_card_free + - media: cedrus: Program output format during each run + - serial: 8250: Avoid error message on reprobe + - Bluetooth: hci_bcm: fix freeing not-requested IRQ + - b43legacy: Fix case where channel status is corrupted + - b43: Fix connection problem with WPA3 + - b43_legacy: Fix connection problem with WPA3 + - media: ov5640: fix use of destroyed mutex + - clk: mediatek: assign the initial value to clk_init_data of mtk_mux + - hwmon: (k10temp) Add AMD family 17h model 60h PCI match + - EDAC/amd64: Add AMD family 17h model 60h PCI IDs + - power: vexpress: add suppress_bind_attrs to true + - power: supply: core: fix HWMON temperature labels + - power: supply: core: fix memory leak in HWMON error path + - pinctrl: samsung: Correct setting of eint wakeup mask on s5pv210 + - pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs + - gnss: sirf: fix error return code in sirf_probe() + - sparc32: fix register window handling in genregs32_[gs]et() + - sparc64: fix misuses of access_process_vm() in genregs32_[sg]et() + - dm crypt: avoid truncating the logical block size + - alpha: fix memory barriers so that they conform to the specification + - powerpc/fadump: use static allocation for reserved memory ranges + - powerpc/fadump: consider reserved ranges while reserving memory + - powerpc/fadump: Account for memory_limit while reserving memory + - kernel/cpu_pm: Fix uninitted local in cpu_pm + - ARM: tegra: Correct PL310 Auxiliary Control Register initialization + - soc/tegra: pmc: Select GENERIC_PINCONF + - ARM: dts: exynos: Fix GPIO polarity for thr GalaxyS3 CM36651 sensor's bus + - ARM: dts: at91: sama5d2_ptc_ek: fix vbus pin + - ARM: dts: s5pv210: Set keep-power-in-suspend for SDHCI1 on Aries + - drivers/macintosh: Fix memleak in windfarm_pm112 driver + - powerpc/32s: Fix another build failure with CONFIG_PPC_KUAP_DEBUG + - powerpc/kasan: Fix issues by lowering KASAN_SHADOW_END + - powerpc/kasan: Fix shadow pages allocation failure + - powerpc/32: Disable KASAN with pages bigger than 16k + - powerpc/64s: Don't let DT CPU features set FSCR_DSCR + - powerpc/64s: Save FSCR to init_task.thread.fscr after feature init + - kbuild: force to build vmlinux if CONFIG_MODVERSION=y + - sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate + registrations. + - sunrpc: clean up properly in gss_mech_unregister() + - mtd: rawnand: Fix nand_gpio_waitrdy() + - mtd: rawnand: onfi: Fix redundancy detection check + - mtd: rawnand: brcmnand: fix hamming oob layout + - mtd: rawnand: diskonchip: Fix the probe error path + - mtd: rawnand: sharpsl: Fix the probe error path + - mtd: rawnand: ingenic: Fix the probe error path + - mtd: rawnand: xway: Fix the probe error path + - mtd: rawnand: orion: Fix the probe error path + - mtd: rawnand: socrates: Fix the probe error path + - mtd: rawnand: oxnas: Fix the probe error path + - mtd: rawnand: sunxi: Fix the probe error path + - mtd: rawnand: plat_nand: Fix the probe error path + - mtd: rawnand: pasemi: Fix the probe error path + - mtd: rawnand: mtk: Fix the probe error path + - mtd: rawnand: tmio: Fix the probe error path + - w1: omap-hdq: cleanup to add missing newline for some dev_dbg + - f2fs: fix checkpoint=disable:%u%% + - perf probe: Do not show the skipped events + - perf probe: Fix to check blacklist address correctly + - perf probe: Check address correctness by map instead of _etext + - perf symbols: Fix debuginfo search for Ubuntu + - perf symbols: Fix kernel maps for kcore and eBPF + - Linux 5.4.48 + * The thread level parallelism would be a bottleneck when searching for the + shared pmd by using hugetlbfs (LP: #1882039) + - hugetlbfs: take read_lock on i_mmap for PMD sharing + * Support Audio Mute LED for two new HP laptops (LP: #1884251) + - ALSA: hda/realtek: Add mute LED and micmute LED support for HP systems + * Focal update: v5.4.47 upstream stable release (LP: #1884089) + - ipv6: fix IPV6_ADDRFORM operation logic + - mlxsw: core: Use different get_trend() callbacks for different thermal zones + - net_failover: fixed rollback in net_failover_open() + - tun: correct header offsets in napi frags mode + - bridge: Avoid infinite loop when suppressing NS messages with invalid + options + - vxlan: Avoid infinite loop when suppressing NS messages with invalid options + - bpf: Support llvm-objcopy for vmlinux BTF + - elfnote: mark all .note sections SHF_ALLOC + - Input: mms114 - fix handling of mms345l + - ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook + - sched/fair: Don't NUMA balance for kthreads + - Input: synaptics - add a second working PNP_ID for Lenovo T470s + - csky: Fixup abiv2 syscall_trace break a4 & a5 + - gfs2: Even more gfs2_find_jhead fixes + - drivers/net/ibmvnic: Update VNIC protocol version reporting + - powerpc/xive: Clear the page tables for the ESB IO mapping + - spi: dw: Fix native CS being unset + - ath9k_htc: Silence undersized packet warnings + - smack: avoid unused 'sip' variable warning + - RDMA/uverbs: Make the event_queue fds return POLLERR when disassociated + - padata: add separate cpuhp node for CPUHP_PADATA_DEAD + - s390/pci: Log new handle in clp_disable_fh() + - x86/cpu/amd: Make erratum #1054 a legacy erratum + - KVM: x86: only do L1TF workaround on affected processors + - PCI/PM: Adjust pcie_wait_for_link_delay() for caller delay + - perf probe: Accept the instance number of kretprobe event + - mm: add kvfree_sensitive() for freeing sensitive data objects + - selftests: fix flower parent qdisc + - fanotify: fix ignore mask logic for events on child and on dir + - aio: fix async fsync creds + - ipv4: fix a RCU-list lock in fib_triestat_seq_show + - iwlwifi: mvm: fix NVM check for 3168 devices + - sctp: fix possibly using a bad saddr with a given dst + - sctp: fix refcount bug in sctp_wfree + - x86_64: Fix jiffies ODR violation + - x86/PCI: Mark Intel C620 MROMs as having non-compliant BARs + - x86/speculation: Prevent rogue cross-process SSBD shutdown + - x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced + IBRS. + - x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches. + - x86/reboot/quirks: Add MacBook6,1 reboot quirk + - perf/x86/intel: Add more available bits for OFFCORE_RESPONSE of Intel + Tremont + - KVM: x86/mmu: Set mmio_value to '0' if reserved #PF can't be generated + - KVM: x86: respect singlestep when emulating instruction + - KVM: x86: Fix APIC page invalidation race + - powerpc/ptdump: Properly handle non standard page size + - ASoC: max9867: fix volume controls + - io_uring: use kvfree() in io_sqe_buffer_register() + - efi/efivars: Add missing kobject_put() in sysfs entry creation error path + - smb3: fix incorrect number of credits when ioctl MaxOutputResponse > 64K + - smb3: add indatalen that can be a non-zero value to calculation of credit + charge in smb2 ioctl + - watchdog: imx_sc_wdt: Fix reboot on crash + - ALSA: es1688: Add the missed snd_card_free() + - ALSA: fireface: fix configuration error for nominal sampling transfer + frequency + - ALSA: hda/realtek - add a pintbl quirk for several Lenovo machines + - ALSA: pcm: disallow linking stream to itself + - ALSA: pcm: fix snd_pcm_link() lockdep splat + - ALSA: usb-audio: Fix inconsistent card PM state after resume + - ALSA: usb-audio: Add vendor, product and profile name for HP Thunderbolt + Dock + - ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() + - ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() + - ACPI: GED: add support for _Exx / _Lxx handler methods + - ACPI: PM: Avoid using power resources if there are none for D0 + - arm64: acpi: fix UBSAN warning + - lib/lzo: fix ambiguous encoding bug in lzo-rle + - nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() + - spi: dw: Fix controller unregister order + - spi: Fix controller unregister order + - spi: pxa2xx: Fix controller unregister order + - spi: pxa2xx: Fix runtime PM ref imbalance on probe error + - spi: bcm2835: Fix controller unregister order + - spi: bcm2835aux: Fix controller unregister order + - spi: bcm-qspi: Handle clock probe deferral + - spi: bcm-qspi: when tx/rx buffer is NULL set to 0 + - PM: runtime: clk: Fix clk_pm_runtime_get() error path + - gup: document and work around "COW can break either way" issue + - crypto: cavium/nitrox - Fix 'nitrox_get_first_device()' when ndevlist is + fully iterated + - crypto: algapi - Avoid spurious modprobe on LOADED + - crypto: drbg - fix error return code in drbg_alloc_state() + - x86/{mce,mm}: Unmap the entire page if the whole page is affected and + poisoned + - firmware: imx: warn on unexpected RX + - firmware: imx-scu: Support one TX and one RX + - firmware: imx: scu: Fix corruption of header + - crypto: virtio: Fix use-after-free in virtio_crypto_skcipher_finalize_req() + - crypto: virtio: Fix src/dst scatterlist calculation in + __virtio_crypto_skcipher_do_req() + - crypto: virtio: Fix dest length calculation in + __virtio_crypto_skcipher_do_req() + - dccp: Fix possible memleak in dccp_init and dccp_fini + - selftests/net: in rxtimestamp getopt_long needs terminating null entry + - net/mlx5: drain health workqueue in case of driver load error + - net/mlx5: Fix fatal error handling during device load + - net/mlx5e: Fix repeated XSK usage on one channel + - ovl: initialize error in ovl_copy_xattr + - proc: Use new_inode not new_inode_pseudo + - remoteproc: Fall back to using parent memory pool if no dedicated available + - remoteproc: Fix and restore the parenting hierarchy for vdev + - cpufreq: Fix up cpufreq_boost_set_sw() + - EDAC/skx: Use the mcmtr register to retrieve close_pg/bank_xor_enable + - video: vt8500lcdfb: fix fallthrough warning + - video: fbdev: w100fb: Fix a potential double free. + - KVM: nVMX: Skip IBPB when switching between vmcs01 and vmcs02 + - KVM: nSVM: fix condition for filtering async PF + - KVM: nSVM: leave ASID aside in copy_vmcb_control_area + - KVM: nVMX: Consult only the "basic" exit reason when routing nested exit + - KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data) + - KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits + - KVM: arm64: Stop writing aarch32's CSSELR into ACTLR + - KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts + - scsi: megaraid_sas: TM command refire leads to controller firmware crash + - scsi: lpfc: Fix negation of else clause in lpfc_prep_node_fc4type + - selftests/ftrace: Return unsupported if no error_log file + - ath9k: Fix use-after-free Read in htc_connect_service + - ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx + - ath9k: Fix use-after-free Write in ath9k_htc_rx_msg + - ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb + - ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb + - Smack: slab-out-of-bounds in vsscanf + - drm/vkms: Hold gem object while still in-use + - mm/slub: fix a memory leak in sysfs_slab_add() + - fat: don't allow to mount if the FAT length == 0 + - perf: Add cond_resched() to task_function_call() + - agp/intel: Reinforce the barrier after GTT updates + - mmc: sdhci-msm: Clear tuning done flag while hs400 tuning + - mmc: mmci_sdmmc: fix DMA API warning overlapping mappings + - mmc: tmio: Further fixup runtime PM management at remove + - mmc: uniphier-sd: call devm_request_irq() after tmio_mmc_host_probe() + - ARM: dts: at91: sama5d2_ptc_ek: fix sdmmc0 node description + - mmc: sdio: Fix potential NULL pointer error in mmc_sdio_init_card() + - mmc: sdio: Fix several potential memory leaks in mmc_sdio_init_card() + - block/floppy: fix contended case in floppy_queue_rq() + - xen/pvcalls-back: test for errors when calling backend_connect() + - KVM: arm64: Synchronize sysreg state on injecting an AArch32 exception + - KVM: arm64: Save the host's PtrAuth keys in non-preemptible context + - Linux 5.4.47 + * apparmor reference leak causes refcount_t overflow with af_alg_accept() + (LP: #1883962) + - apparmor: check/put label on apparmor_sk_clone_security() + * Focal update: v5.4.46 upstream stable release (LP: #1883184) + - devinet: fix memleak in inetdev_init() + - l2tp: add sk_family checks to l2tp_validate_socket + - l2tp: do not use inet_hash()/inet_unhash() + - net/mlx5: Fix crash upon suspend/resume + - net: stmmac: enable timestamp snapshot for required PTP packets in dwmac + v5.10a + - net: usb: qmi_wwan: add Telit LE910C1-EUX composition + - NFC: st21nfca: add missed kfree_skb() in an error path + - nfp: flower: fix used time of merge flow statistics + - vsock: fix timeout in vsock_accept() + - net: check untrusted gso_size at kernel entry + - net: be more gentle about silly gso requests coming from user + - USB: serial: qcserial: add DW5816e QDL support + - USB: serial: usb_wwan: do not resubmit rx urb on fatal errors + - USB: serial: option: add Telit LE910C1-EUX compositions + - USB: serial: ch341: add basis for quirk detection + - iio:chemical:sps30: Fix timestamp alignment + - iio: vcnl4000: Fix i2c swapped word reading. + - iio:chemical:pms7003: Fix timestamp alignment and prevent data leak. + - iio: adc: stm32-adc: fix a wrong error message when probing interrupts + - usb: musb: start session in resume for host port + - usb: musb: Fix runtime PM imbalance on error + - vt: keyboard: avoid signed integer overflow in k_ascii + - tty: hvc_console, fix crashes on parallel open/close + - staging: rtl8712: Fix IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK + - CDC-ACM: heed quirk also in error handling + - nvmem: qfprom: remove incorrect write support + - uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly + aligned + - Revert "net/mlx5: Annotate mutex destroy for root ns" + - Linux 5.4.46 + * Focal update: v5.4.45 upstream stable release (LP: #1882802) + - mm: Fix mremap not considering huge pmd devmap + - HID: sony: Fix for broken buttons on DS3 USB dongles + - HID: multitouch: enable multi-input as a quirk for some devices + - HID: i2c-hid: add Schneider SCL142ALM to descriptor override + - p54usb: add AirVasT USB stick device-id + - mt76: mt76x02u: Add support for newer versions of the XBox One wifi adapter + - mmc: fix compilation of user API + - media: Revert "staging: imgu: Address a compiler warning on alignment" + - media: staging: ipu3-imgu: Move alignment attribute to field + - scsi: ufs: Release clock if DMA map fails + - net: dsa: mt7530: set CPU port to fallback mode + - airo: Fix read overflows sending packets + - RDMA/qedr: Fix qpids xarray api used + - RDMA/qedr: Fix synchronization methods and memory leaks in qedr + - ARC: Fix ICCM & DCCM runtime size checks + - ARC: [plat-eznps]: Restrict to CONFIG_ISA_ARCOMPACT + - evm: Fix RCU list related warnings + - scsi: pm: Balance pm_only counter of request queue during system resume + - i2c: altera: Fix race between xfer_msg and isr thread + - io_uring: initialize ctx->sqo_wait earlier + - x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables + - net: bmac: Fix read of MAC address from ROM + - drm/edid: Add Oculus Rift S to non-desktop list + - s390/mm: fix set_huge_pte_at() for empty ptes + - null_blk: return error for invalid zone size + - net/ethernet/freescale: rework quiesce/activate for ucc_geth + - net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x + - selftests: mlxsw: qos_mc_aware: Specify arping timeout as an integer + - net: smsc911x: Fix runtime PM imbalance on error + - Linux 5.4.45 + + -- Khalid Elmously Sat, 22 Aug 2020 01:06:16 -0400 + +linux-oracle (5.4.0-1021.21) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1021.21 -proposed tracker (LP: #1887065) + + [ Ubuntu: 5.4.0-42.46 ] + + * focal/linux: 5.4.0-42.46 -proposed tracker (LP: #1887069) + * linux 4.15.0-109-generic network DoS regression vs -108 (LP: #1886668) + - SAUCE: Revert "netprio_cgroup: Fix unlimited memory leak of v2 cgroups" + + -- Khalid Elmously Fri, 10 Jul 2020 02:11:06 -0400 + +linux-oracle (5.4.0-1020.20) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1020.20 -proposed tracker (LP: #1885851) + + [ Ubuntu: 5.4.0-41.45 ] + + * focal/linux: 5.4.0-41.45 -proposed tracker (LP: #1885855) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CVE-2019-19642 + - kernel/relay.c: handle alloc_percpu returning NULL in relay_open + * CVE-2019-16089 + - SAUCE: nbd_genl_status: null check for nla_nest_start + * CVE-2020-11935 + - aufs: do not call i_readcount_inc() + * ip_defrag.sh in net from ubuntu_kernel_selftests failed with 5.0 / 5.3 / 5.4 + kernel (LP: #1826848) + - selftests: net: ip_defrag: ignore EPERM + * Update lockdown patches (LP: #1884159) + - SAUCE: acpi: disallow loading configfs acpi tables when locked down + * seccomp_bpf fails on powerpc (LP: #1885757) + - SAUCE: selftests/seccomp: fix ptrace tests on powerpc + * Introduce the new NVIDIA 418-server and 440-server series, and update the + current NVIDIA drivers (LP: #1881137) + - [packaging] add signed modules for the 418-server and the 440-server + flavours + + -- Ian May Mon, 06 Jul 2020 15:48:40 -0500 + +linux-oracle (5.4.0-1019.19) focal; urgency=medium + + * Focal update: v5.4.42 upstream stable release (LP: #1879759) + - [Config] oracle: Record CC_HAS_WARN_MAYBE_UNINITIALIZED drop + + * ASoC/amd: add audio driver for amd renoir (LP: #1881046) + - [Config] oracle: match amd renoir config with master + + [ Ubuntu: 5.4.0-40.44 ] + + * linux-oem-5.6-tools-common and -tools-host should be dropped (LP: #1881120) + - [Packaging] Add Conflicts/Replaces to remove linux-oem-5.6-tools-common and + -tools-host + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Slow send speed with Intel I219-V on Ubuntu 18.04.1 (LP: #1802691) + - e1000e: Disable TSO for buffer overrun workaround + * CVE-2020-0543 + - UBUNTU/SAUCE: x86/speculation/srbds: do not try to turn mitigation off when + not supported + * Realtek 8723DE [10ec:d723] subsystem [10ec:d738] disconnects unsolicitedly + when Bluetooth is paired: Reason: 23=IEEE8021X_FAILED (LP: #1878147) + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: Move driver IQK to set channel before + association for 11N chip" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: fix rate for a while after being + connected" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: No retry and report for auth and assoc" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: 8723d: Add coex support" + - rtw88: add a debugfs entry to dump coex's info + - rtw88: add a debugfs entry to enable/disable coex mechanism + - rtw88: 8723d: Add coex support + - SAUCE: rtw88: coex: 8723d: set antanna control owner + - SAUCE: rtw88: coex: 8723d: handle BT inquiry cases + - SAUCE: rtw88: fix EAPOL 4-way failure by finish IQK earlier + * CPU stress test fails with focal kernel (LP: #1867900) + - [Config] Disable hisi_sec2 temporarily + * Enforce all config annotations (LP: #1879327) + - [Config]: do not enforce CONFIG_VERSION_SIGNATURE + - [Config]: prepare to enforce all + - [Config]: enforce all config options + * Focal update: v5.4.44 upstream stable release (LP: #1881927) + - ax25: fix setsockopt(SO_BINDTODEVICE) + - dpaa_eth: fix usage as DSA master, try 3 + - net: don't return invalid table id error when we fall back to PF_UNSPEC + - net: dsa: mt7530: fix roaming from DSA user ports + - net: ethernet: ti: cpsw: fix ASSERT_RTNL() warning during suspend + - __netif_receive_skb_core: pass skb by reference + - net: inet_csk: Fix so_reuseport bind-address cache in tb->fast* + - net: ipip: fix wrong address family in init error path + - net/mlx5: Add command entry handling completion + - net: mvpp2: fix RX hashing for non-10G ports + - net: nlmsg_cancel() if put fails for nhmsg + - net: qrtr: Fix passing invalid reference to qrtr_local_enqueue() + - net: revert "net: get rid of an signed integer overflow in + ip_idents_reserve()" + - net sched: fix reporting the first-time use timestamp + - net/tls: fix race condition causing kernel panic + - nexthop: Fix attribute checking for groups + - r8152: support additional Microsoft Surface Ethernet Adapter variant + - sctp: Don't add the shutdown timer if its already been added + - sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and + socket is closed + - tipc: block BH before using dst_cache + - net/mlx5e: kTLS, Destroy key object after destroying the TIS + - net/mlx5e: Fix inner tirs handling + - net/mlx5: Fix memory leak in mlx5_events_init + - net/mlx5e: Update netdev txq on completions during closure + - net/mlx5: Fix error flow in case of function_setup failure + - net/mlx5: Annotate mutex destroy for root ns + - net/tls: fix encryption error checking + - net/tls: free record only on encryption error + - net: sun: fix missing release regions in cas_init_one(). + - net/mlx4_core: fix a memory leak bug. + - mlxsw: spectrum: Fix use-after-free of split/unsplit/type_set in case reload + fails + - ARM: dts: rockchip: fix phy nodename for rk3228-evb + - ARM: dts: rockchip: fix phy nodename for rk3229-xms6 + - arm64: dts: rockchip: fix status for &gmac2phy in rk3328-evb.dts + - arm64: dts: rockchip: swap interrupts interrupt-names rk3399 gpu node + - ARM: dts: rockchip: swap clock-names of gpu nodes + - ARM: dts: rockchip: fix pinctrl sub nodename for spi in rk322x.dtsi + - gpio: tegra: mask GPIO IRQs during IRQ shutdown + - ALSA: usb-audio: add mapping for ASRock TRX40 Creator + - net: microchip: encx24j600: add missed kthread_stop + - gfs2: move privileged user check to gfs2_quota_lock_check + - gfs2: Grab glock reference sooner in gfs2_add_revoke + - drm/amdgpu: drop unnecessary cancel_delayed_work_sync on PG ungate + - drm/amd/powerplay: perform PG ungate prior to CG ungate + - drm/amdgpu: Use GEM obj reference for KFD BOs + - cachefiles: Fix race between read_waiter and read_copier involving op->to_do + - usb: dwc3: pci: Enable extcon driver for Intel Merrifield + - usb: phy: twl6030-usb: Fix a resource leak in an error handling path in + 'twl6030_usb_probe()' + - usb: gadget: legacy: fix redundant initialization warnings + - net: freescale: select CONFIG_FIXED_PHY where needed + - IB/i40iw: Remove bogus call to netdev_master_upper_dev_get() + - riscv: stacktrace: Fix undefined reference to `walk_stackframe' + - clk: ti: am33xx: fix RTC clock parent + - csky: Fixup msa highest 3 bits mask + - csky: Fixup perf callchain unwind + - csky: Fixup remove duplicate irq_disable + - hwmon: (nct7904) Fix incorrect range of temperature limit registers + - cifs: Fix null pointer check in cifs_read + - csky: Fixup raw_copy_from_user() + - samples: bpf: Fix build error + - drivers: net: hamradio: Fix suspicious RCU usage warning in bpqether.c + - Input: usbtouchscreen - add support for BonXeon TP + - Input: evdev - call input_flush_device() on release(), not flush() + - Input: xpad - add custom init packet for Xbox One S controllers + - Input: dlink-dir685-touchkeys - fix a typo in driver name + - Input: i8042 - add ThinkPad S230u to i8042 reset list + - Input: synaptics-rmi4 - really fix attn_data use-after-free + - Input: synaptics-rmi4 - fix error return code in rmi_driver_probe() + - ARM: 8970/1: decompressor: increase tag size + - ARM: uaccess: consolidate uaccess asm to asm/uaccess-asm.h + - ARM: uaccess: integrate uaccess_save and uaccess_restore + - ARM: uaccess: fix DACR mismatch with nested exceptions + - gpio: exar: Fix bad handling for ida_simple_get error path + - arm64: dts: mt8173: fix vcodec-enc clock + - soc: mediatek: cmdq: return send msg error code + - gpu/drm: Ingenic: Fix opaque pointer casted to wrong type + - IB/qib: Call kobject_put() when kobject_init_and_add() fails + - ARM: dts/imx6q-bx50v3: Set display interface clock parents + - ARM: dts: bcm2835-rpi-zero-w: Fix led polarity + - ARM: dts: bcm: HR2: Fix PPI interrupt types + - mmc: block: Fix use-after-free issue for rpmb + - gpio: pxa: Fix return value of pxa_gpio_probe() + - gpio: bcm-kona: Fix return value of bcm_kona_gpio_probe() + - RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe() + - ALSA: hwdep: fix a left shifting 1 by 31 UB bug + - ALSA: hda/realtek - Add a model for Thinkpad T570 without DAC workaround + - ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC + - exec: Always set cap_ambient in cap_bprm_set_creds + - clk: qcom: gcc: Fix parent for gpll0_out_even + - ALSA: usb-audio: Quirks for Gigabyte TRX40 Aorus Master onboard audio + - ALSA: hda/realtek - Add new codec supported for ALC287 + - libceph: ignore pool overlay and cache logic on redirects + - ceph: flush release queue when handling caps for unknown inode + - RDMA/core: Fix double destruction of uobject + - drm/amd/display: drop cursor position check in atomic test + - IB/ipoib: Fix double free of skb in case of multicast traffic in CM mode + - mm,thp: stop leaking unreleased file pages + - mm: remove VM_BUG_ON(PageSlab()) from page_mapcount() + - fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() + - include/asm-generic/topology.h: guard cpumask_of_node() macro argument + - Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and + REQ_NOWAIT" + - gpio: fix locking open drain IRQ lines + - iommu: Fix reference count leak in iommu_group_alloc. + - parisc: Fix kernel panic in mem_init() + - cfg80211: fix debugfs rename crash + - x86/syscalls: Revert "x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long" + - mac80211: mesh: fix discovery timer re-arming issue / crash + - x86/dma: Fix max PFN arithmetic overflow on 32 bit systems + - copy_xstate_to_kernel(): don't leave parts of destination uninitialized + - xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input + - xfrm: do pskb_pull properly in __xfrm_transport_prep + - xfrm: remove the xfrm_state_put call becofe going to out_reset + - xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output + - xfrm interface: fix oops when deleting a x-netns interface + - xfrm: fix a warning in xfrm_policy_insert_list + - xfrm: fix a NULL-ptr deref in xfrm_local_error + - xfrm: fix error in comment + - ip_vti: receive ipip packet by calling ip_tunnel_rcv + - netfilter: nft_reject_bridge: enable reject with bridge vlan + - netfilter: ipset: Fix subcounter update skip + - netfilter: conntrack: make conntrack userspace helpers work again + - netfilter: nfnetlink_cthelper: unbreak userspace helper support + - netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code + - esp6: get the right proto for transport mode in esp6_gso_encap + - bnxt_en: Fix accumulation of bp->net_stats_prev. + - ieee80211: Fix incorrect mask for default PE duration + - xsk: Add overflow check for u64 division, stored into u32 + - qlcnic: fix missing release in qlcnic_83xx_interrupt_test. + - crypto: chelsio/chtls: properly set tp->lsndtime + - nexthops: Move code from remove_nexthop_from_groups to remove_nh_grp_entry + - nexthops: don't modify published nexthop groups + - nexthop: Expand nexthop_is_multipath in a few places + - ipv4: nexthop version of fib_info_nh_uses_dev + - net: dsa: declare lockless TX feature for slave ports + - bonding: Fix reference count leak in bond_sysfs_slave_add. + - netfilter: conntrack: comparison of unsigned in cthelper confirmation + - netfilter: conntrack: Pass value of ctinfo to __nf_conntrack_update + - netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build + - perf: Make perf able to build with latest libbfd + - Linux 5.4.44 + * Focal update: v5.4.43 upstream stable release (LP: #1881178) + - i2c: dev: Fix the race between the release of i2c_dev and cdev + - KVM: SVM: Fix potential memory leak in svm_cpu_init() + - ima: Set file->f_mode instead of file->f_flags in ima_calc_file_hash() + - evm: Check also if *tfm is an error pointer in init_desc() + - ima: Fix return value of ima_write_policy() + - ubifs: fix wrong use of crypto_shash_descsize() + - ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactive + - mtd: spinand: Propagate ECC information to the MTD structure + - fix multiplication overflow in copy_fdtable() + - ubifs: remove broken lazytime support + - i2c: fix missing pm_runtime_put_sync in i2c_device_probe + - iommu/amd: Fix over-read of ACPI UID from IVRS table + - evm: Fix a small race in init_desc() + - i2c: mux: demux-pinctrl: Fix an error handling path in + 'i2c_demux_pinctrl_probe()' + - ubi: Fix seq_file usage in detailed_erase_block_info debugfs file + - afs: Don't unlock fetched data pages until the op completes successfully + - mtd: Fix mtd not registered due to nvmem name collision + - kbuild: avoid concurrency issue in parallel building dtbs and dtbs_check + - net: drop_monitor: use IS_REACHABLE() to guard net_dm_hw_report() + - gcc-common.h: Update for GCC 10 + - HID: multitouch: add eGalaxTouch P80H84 support + - HID: alps: Add AUI1657 device ID + - HID: alps: ALPS_1657 is too specific; use U1_UNICORN_LEGACY instead + - scsi: qla2xxx: Fix hang when issuing nvme disconnect-all in NPIV + - scsi: qla2xxx: Delete all sessions before unregister local nvme port + - configfs: fix config_item refcnt leak in configfs_rmdir() + - vhost/vsock: fix packet delivery order to monitoring devices + - aquantia: Fix the media type of AQC100 ethernet controller in the driver + - component: Silence bind error on -EPROBE_DEFER + - net/ena: Fix build warning in ena_xdp_set() + - scsi: ibmvscsi: Fix WARN_ON during event pool release + - HID: i2c-hid: reset Synaptics SYNA2393 on resume + - x86/mm/cpa: Flush direct map alias during cpa + - ibmvnic: Skip fatal error reset after passive init + - x86/apic: Move TSC deadline timer debug printk + - gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp() + - HID: quirks: Add HID_QUIRK_NO_INIT_REPORTS quirk for Dell K12A keyboard-dock + - ceph: fix double unlock in handle_cap_export() + - stmmac: fix pointer check after utilization in stmmac_interrupt + - USB: core: Fix misleading driver bug report + - platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA + - iommu/amd: Call domain_flush_complete() in update_domain() + - drm/amd/display: Prevent dpcd reads with passive dongles + - KVM: selftests: Fix build for evmcs.h + - ARM: futex: Address build warning + - scripts/gdb: repair rb_first() and rb_last() + - ALSA: hda - constify and cleanup static NodeID tables + - ALSA: hda: patch_realtek: fix empty macro usage in if block + - ALSA: hda: Manage concurrent reg access more properly + - ALSA: hda/realtek - Add supported new mute Led for HP + - ALSA: hda/realtek - Add HP new mute led supported for ALC236 + - ALSA: hda/realtek: Add quirk for Samsung Notebook + - ALSA: hda/realtek - Enable headset mic of ASUS GL503VM with ALC295 + - ALSA: hda/realtek - Enable headset mic of ASUS UX550GE with ALC295 + - ALSA: hda/realtek: Enable headset mic of ASUS UX581LV with ALC295 + - KVM: x86: Fix pkru save/restore when guest CR4.PKE=0, move it to x86.c + - ALSA: iec1712: Initialize STDSP24 properly when using the model=staudio + option + - ALSA: pcm: fix incorrect hw_base increase + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Xtreme + - ALSA: hda/realtek - Add more fixup entries for Clevo machines + - scsi: qla2xxx: Do not log message when reading port speed via sysfs + - scsi: target: Put lun_ref at end of tmr processing + - arm64: Fix PTRACE_SYSEMU semantics + - drm/etnaviv: fix perfmon domain interation + - apparmor: Fix aa_label refcnt leak in policy_update + - dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()' + - drm/etnaviv: Fix a leak in submit_pin_objects() + - dmaengine: dmatest: Restore default for channel + - dmaengine: owl: Use correct lock in owl_dma_get_pchan() + - vsprintf: don't obfuscate NULL and error pointers + - drm/i915/gvt: Init DPLL/DDI vreg for virtual display instead of inheritance. + - drm/i915: Propagate error from completed fences + - powerpc: Remove STRICT_KERNEL_RWX incompatibility with RELOCATABLE + - powerpc/64s: Disable STRICT_KERNEL_RWX + - bpf: Avoid setting bpf insns pages read-only when prog is jited + - kbuild: Remove debug info from kallsyms linking + - Revert "gfs2: Don't demote a glock until its revokes are written" + - media: fdp1: Fix R-Car M3-N naming in debug message + - staging: iio: ad2s1210: Fix SPI reading + - staging: kpc2000: fix error return code in kp2000_pcie_probe() + - staging: greybus: Fix uninitialized scalar variable + - iio: sca3000: Remove an erroneous 'get_device()' + - iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()' + - iio: adc: ti-ads8344: Fix channel selection + - misc: rtsx: Add short delay after exit from ASPM + - tty: serial: add missing spin_lock_init for SiFive serial console + - mei: release me_cl object reference + - ipack: tpci200: fix error return code in tpci200_register() + - s390/kaslr: add support for R_390_JMP_SLOT relocation type + - device-dax: don't leak kernel memory to user space after unloading kmem + - rapidio: fix an error in get_user_pages_fast() error handling + - kasan: disable branch tracing for core runtime + - rxrpc: Fix the excessive initial retransmission timeout + - rxrpc: Fix a memory leak in rxkad_verify_response() + - s390/kexec_file: fix initrd location for kdump kernel + - flow_dissector: Drop BPF flow dissector prog ref on netns cleanup + - x86/unwind/orc: Fix unwind_get_return_address_ptr() for inactive tasks + - iio: adc: stm32-adc: Use dma_request_chan() instead + dma_request_slave_channel() + - iio: adc: stm32-adc: fix device used to request dma + - iio: adc: stm32-dfsdm: Use dma_request_chan() instead + dma_request_slave_channel() + - iio: adc: stm32-dfsdm: fix device used to request dma + - rxrpc: Trace discarded ACKs + - rxrpc: Fix ack discard + - tpm: check event log version before reading final events + - sched/fair: Reorder enqueue/dequeue_task_fair path + - sched/fair: Fix reordering of enqueue/dequeue_task_fair() + - sched/fair: Fix enqueue_task_fair() warning some more + - Linux 5.4.43 + * Focal update: v5.4.42 upstream stable release (LP: #1879759) + - net: dsa: Do not make user port errors fatal + - shmem: fix possible deadlocks on shmlock_user_lock + - net: phy: microchip_t1: add lan87xx_phy_init to initialize the lan87xx phy. + - KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read + - gpio: pca953x: Fix pca953x_gpio_set_config + - SUNRPC: Add "@len" parameter to gss_unwrap() + - SUNRPC: Fix GSS privacy computation of auth->au_ralign + - net/sonic: Fix a resource leak in an error handling path in + 'jazz_sonic_probe()' + - net: moxa: Fix a potential double 'free_irq()' + - ftrace/selftests: workaround cgroup RT scheduling issues + - drop_monitor: work around gcc-10 stringop-overflow warning + - virtio-blk: handle block_device_operations callbacks after hot unplug + - sun6i: dsi: fix gcc-4.8 + - net_sched: fix tcm_parent in tc filter dump + - scsi: sg: add sg_remove_request in sg_write + - mmc: sdhci-acpi: Add SDHCI_QUIRK2_BROKEN_64_BIT_DMA for AMDI0040 + - dpaa2-eth: properly handle buffer size restrictions + - net: fix a potential recursive NETDEV_FEAT_CHANGE + - netlabel: cope with NULL catmap + - net: phy: fix aneg restart in phy_ethtool_set_eee + - net: stmmac: fix num_por initialization + - pppoe: only process PADT targeted at local interfaces + - Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu" + - tcp: fix error recovery in tcp_zerocopy_receive() + - tcp: fix SO_RCVLOWAT hangs with fat skbs + - virtio_net: fix lockdep warning on 32 bit + - dpaa2-eth: prevent array underflow in update_cls_rule() + - hinic: fix a bug of ndo_stop + - net: dsa: loop: Add module soft dependency + - net: ipv4: really enforce backoff for redirects + - netprio_cgroup: Fix unlimited memory leak of v2 cgroups + - net: tcp: fix rx timestamp behavior for tcp_recvmsg + - nfp: abm: fix error return code in nfp_abm_vnic_alloc() + - r8169: re-establish support for RTL8401 chip version + - umh: fix memory leak on execve failure + - riscv: fix vdso build with lld + - dmaengine: pch_dma.c: Avoid data race between probe and irq handler + - dmaengine: mmp_tdma: Do not ignore slave config validation errors + - dmaengine: mmp_tdma: Reset channel error on release + - selftests/ftrace: Check the first record for kprobe_args_type.tc + - cpufreq: intel_pstate: Only mention the BIOS disabling turbo mode once + - ALSA: hda/hdmi: fix race in monitor detection during probe + - drm/amd/powerplay: avoid using pm_en before it is initialized revised + - drm/amd/display: check if REFCLK_CNTL register is present + - drm/amd/display: Update downspread percent to match spreadsheet for DCN2.1 + - drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper() + - drm/amdgpu: simplify padding calculations (v2) + - drm/amdgpu: invalidate L2 before SDMA IBs (v2) + - ipc/util.c: sysvipc_find_ipc() incorrectly updates position index + - gfs2: Another gfs2_walk_metadata fix + - mmc: sdhci-pci-gli: Fix no irq handler from suspend + - IB/hfi1: Fix another case where pq is left on waitlist + - ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake() + - pinctrl: sunrisepoint: Fix PAD lock register offset for SPT-H + - pinctrl: baytrail: Enable pin configuration setting for GPIO chip + - pinctrl: qcom: fix wrong write in update_dual_edge + - pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler + - bpf: Fix error return code in map_lookup_and_delete_elem() + - ALSA: firewire-lib: fix 'function sizeof not defined' error of tracepoints + format + - i40iw: Fix error handling in i40iw_manage_arp_cache() + - drm/i915: Don't enable WaIncreaseLatencyIPCEnabled when IPC is disabled + - bpf, sockmap: msg_pop_data can incorrecty set an sge length + - bpf, sockmap: bpf_tcp_ingress needs to subtract bytes from sg.size + - mmc: alcor: Fix a resource leak in the error path for ->probe() + - mmc: sdhci-pci-gli: Fix can not access GL9750 after reboot from Windows 10 + - mmc: core: Check request type before completing the request + - mmc: core: Fix recursive locking issue in CQE recovery path + - mmc: block: Fix request completion in the CQE timeout path + - gfs2: More gfs2_find_jhead fixes + - fork: prevent accidental access to clone3 features + - drm/amdgpu: force fbdev into vram + - NFS: Fix fscache super_cookie index_key from changing after umount + - nfs: fscache: use timespec64 in inode auxdata + - NFSv4: Fix fscache cookie aux_data to ensure change_attr is included + - netfilter: conntrack: avoid gcc-10 zero-length-bounds warning + - drm/i915/gvt: Fix kernel oops for 3-level ppgtt guest + - arm64: fix the flush_icache_range arguments in machine_kexec + - nfs: fix NULL deference in nfs4_get_valid_delegation + - SUNRPC: Signalled ASYNC tasks need to exit + - netfilter: nft_set_rbtree: Introduce and use nft_rbtree_interval_start() + - netfilter: nft_set_rbtree: Add missing expired checks + - RDMA/rxe: Always return ERR_PTR from rxe_create_mmap_info() + - IB/mlx4: Test return value of calls to ib_get_cached_pkey + - IB/core: Fix potential NULL pointer dereference in pkey cache + - RDMA/core: Fix double put of resource + - RDMA/iw_cxgb4: Fix incorrect function parameters + - hwmon: (da9052) Synchronize access with mfd + - s390/ism: fix error return code in ism_probe() + - mm, memcg: fix inconsistent oom event behavior + - NFSv3: fix rpc receive buffer size for MOUNT call + - pnp: Use list_for_each_entry() instead of open coding + - net/rds: Use ERR_PTR for rds_message_alloc_sgs() + - Stop the ad-hoc games with -Wno-maybe-initialized + - [Config] updateconfigs for CC_HAS_WARN_MAYBE_UNINITIALIZED + - gcc-10: disable 'zero-length-bounds' warning for now + - gcc-10: disable 'array-bounds' warning for now + - gcc-10: disable 'stringop-overflow' warning for now + - gcc-10: disable 'restrict' warning for now + - gcc-10 warnings: fix low-hanging fruit + - gcc-10: mark more functions __init to avoid section mismatch warnings + - gcc-10: avoid shadowing standard library 'free()' in crypto + - usb: usbfs: correct kernel->user page attribute mismatch + - USB: usbfs: fix mmap dma mismatch + - ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 + - ALSA: hda/realtek - Add COEF workaround for ASUS ZenBook UX431DA + - ALSA: rawmidi: Fix racy buffer resize under concurrent accesses + - ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset + - usb: core: hub: limit HUB_QUIRK_DISABLE_AUTOSUSPEND to USB5534B + - usb: host: xhci-plat: keep runtime active when removing host + - usb: cdns3: gadget: prev_req->trb is NULL for ep0 + - usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list + - Make the "Reducing compressed framebufer size" message be DRM_INFO_ONCE() + - ARM: dts: dra7: Fix bus_dma_limit for PCIe + - ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries + - ARM: dts: imx6dl-yapp4: Fix Ursa board Ethernet connection + - drm/amd/display: add basic atomic check for cursor plane + - powerpc/32s: Fix build failure with CONFIG_PPC_KUAP_DEBUG + - cifs: fix leaked reference on requeued write + - x86: Fix early boot crash on gcc-10, third try + - x86/unwind/orc: Fix error handling in __unwind_start() + - exec: Move would_dump into flush_old_exec + - clk: rockchip: fix incorrect configuration of rk3228 aclk_gpu* clocks + - dwc3: Remove check for HWO flag in dwc3_gadget_ep_reclaim_trb_sg() + - fanotify: fix merging marks masks with FAN_ONDIR + - usb: gadget: net2272: Fix a memory leak in an error handling path in + 'net2272_plat_probe()' + - usb: gadget: audio: Fix a missing error return value in audio_bind() + - usb: gadget: legacy: fix error return code in gncm_bind() + - usb: gadget: legacy: fix error return code in cdc_bind() + - clk: Unlink clock if failed to prepare or enable + - arm64: dts: meson-g12b-khadas-vim3: add missing frddr_a status property + - arm64: dts: meson-g12-common: fix dwc2 clock names + - arm64: dts: rockchip: Replace RK805 PMIC node name with "pmic" on rk3328 + boards + - arm64: dts: rockchip: Rename dwc3 device nodes on rk3399 to make dtc happy + - arm64: dts: imx8mn: Change SDMA1 ahb clock for imx8mn + - ARM: dts: r8a73a4: Add missing CMT1 interrupts + - arm64: dts: renesas: r8a77980: Fix IPMMU VIP[01] nodes + - ARM: dts: r8a7740: Add missing extal2 to CPG node + - SUNRPC: Revert 241b1f419f0e ("SUNRPC: Remove xdr_buf_trim()") + - bpf: Fix sk_psock refcnt leak when receiving message + - KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce + - Makefile: disallow data races on gcc-10 as well + - Linux 5.4.42 + * upgrading to 4.15.0-99-generic breaks the sound and the trackpad + (LP: #1875916) // Focal update: v5.4.42 upstream stable release + (LP: #1879759) + - Revert "ALSA: hda/realtek: Fix pop noise on ALC225" + * Pop sound from build-in speaker during cold boot and resume from S3 + (LP: #1866357) // Focal update: v5.4.42 upstream stable release + (LP: #1879759) + - ALSA: hda/realtek - Fix S3 pop noise on Dell Wyse + * tpm: fix TIS locality timeout problems (LP: #1881710) + - SAUCE: tpm: fix TIS locality timeout problems + * [UBUNTU 20.04] s390x/pci: fix linking between PF and VF for multifunction + devices (LP: #1879704) + - PCI/IOV: Introduce pci_iov_sysfs_link() function + - s390/pci: create links between PFs and VFs + * Performing function level reset of AMD onboard USB and audio devices causes + system lockup (LP: #1865988) + - SAUCE: PCI: Avoid FLR for AMD Matisse HD Audio & USB 3.0 + - SAUCE: PCI: Avoid FLR for AMD Starship USB 3.0 + * seccomp_benchmark times out on eoan (LP: #1881576) + - SAUCE: selftests/seccomp: use 90s as timeout + * ASoC/amd: add audio driver for amd renoir (LP: #1881046) + - ASoC: amd: add Renoir ACP3x IP register header + - ASoC: amd: add Renoir ACP PCI driver + - ASoC: amd: add acp init/de-init functions + - ASoC: amd: create acp3x pdm platform device + - ASoC: amd: add ACP3x PDM platform driver + - ASoC: amd: irq handler changes for ACP3x PDM dma driver + - ASoC: amd: add acp3x pdm driver dma ops + - ASoC: amd: add ACP PDM DMA driver dai ops + - ASoC: amd: add Renoir ACP PCI driver PM ops + - ASoC: amd: add ACP PDM DMA driver pm ops + - ASoC: amd: enable Renoir acp3x drivers build + - ASoC: amd: create platform devices for Renoir + - ASoC: amd: RN machine driver using dmic + - ASoC: amd: enable build for RN machine driver + - ASoC: amd: fix kernel warning + - ASoC: amd: refactoring dai_hw_params() callback + - ASoC: amd: return error when acp de-init fails + - [Config]: enable amd renoir ASoC audio + * Fix for secure boot rules in IMA arch policy on powerpc (LP: #1877955) + - powerpc/ima: Fix secure boot rules in ima arch policy + * [UBUNTU 20.04] s390x/pci: s390_pci_mmio_write/read fail when MIO + instructions are available (LP: #1874055) + - s390/pci: Fix s390_mmio_read/write with MIO + * security: lockdown: remove trailing semicolon before function body + (LP: #1880660) + - SAUCE: (lockdown) security: lockdown: remove trailing semicolon before + function body + * Fix incorrect speed/duplex when I210 device is runtime suspended + (LP: #1880656) + - igb: Report speed and duplex as unknown when device is runtime suspended + * [OMEN by HP Laptop 15-dh0xxx, Realtek ALC285, Black Mic, Left] Recording + problem (LP: #1874698) + - ASoC: SOF: Intel: hda: allow operation without i915 gfx + - ASoC: intel/skl/hda - add no-HDMI cases to generic HDA driver + * CVE-2020-13143 + - USB: gadget: fix illegal array access in binding with UDC + * rtl8723bu wifi issue after being turned off (LP: #1878296) + - rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver + - rtl8xxxu: add bluetooth co-existence support for single antenna + - rtl8xxxu: remove set but not used variable 'rate_mask' + - rtl8xxxu: Remove set but not used variable 'vif', 'dev', 'len' + * Fix Pericom USB controller OHCI/EHCI PME# defect (LP: #1879321) + - serial: 8250_pci: Move Pericom IDs to pci_ids.h + - PCI: Avoid Pericom USB controller OHCI/EHCI PME# defect + * shiftfs: fix btrfs snapshot deletion (LP: #1879688) + - SAUCE: shiftfs: let userns root destroy subvolumes from other users + * [UBUNTU 20.04] s390x/pci: enumerate pci functions per physical adapter + (LP: #1874056) + - s390/pci: Improve handling of unset UID + - s390/pci: embedding hotplug_slot in zdev + - s390/pci: Expose new port attribute for PCIe functions + - s390/pci: adaptation of iommu to multifunction + - s390/pci: define kernel parameters for PCI multifunction + - s390/pci: define RID and RID available + - s390/pci: create zPCI bus + - s390/pci: adapt events for zbus + - s390/pci: Handling multifunctions + - s390/pci: Do not disable PF when VFs exist + - s390/pci: Documentation for zPCI + - s390/pci: removes wrong PCI multifunction assignment + * update-initramfs complains of missing amdgpu firmware files (LP: #1873325) + - SAUCE: drm/amdgpu: Remove unreleased arcturus and navi12 firmware from + modinfo + + -- Kleber Sacilotto de Souza Tue, 23 Jun 2020 17:34:33 +0200 + +linux-oracle (5.4.0-1018.18) focal; urgency=medium + + + [ Ubuntu: 5.4.0-39.43 ] + + * dkms-build: downloads fail in private PPAs (LP: #1883874) + - dkms-build: apt-cache policy elides username:password information + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Mon, 22 Jun 2020 12:05:44 +0200 + +linux-oracle (5.4.0-1015.15) focal; urgency=medium + + + [ Ubuntu: 5.4.0-37.41 ] + + * CVE-2020-0543 + - SAUCE: x86/speculation/spectre_v2: Exclude Zhaoxin CPUs from SPECTRE_V2 + - SAUCE: x86/cpu: Add a steppings field to struct x86_cpu_id + - SAUCE: x86/cpu: Add 'table' argument to cpu_matches() + - SAUCE: x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) + mitigation + - SAUCE: x86/speculation: Add SRBDS vulnerability and mitigation documentation + - SAUCE: x86/speculation: Add Ivy Bridge to affected list + + -- Thadeu Lima de Souza Cascardo Thu, 04 Jun 2020 21:51:32 -0300 + +linux-oracle (5.4.0-1012.12) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1012.12 -proposed tracker (LP: #1878796) + + * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after + upgrade to 20.04 (LP: #1875665) + - [Config] Turn off CONFIG_RT_GROUP_SCHED + + [ Ubuntu: 5.4.0-34.38 ] + + * focal/linux: 5.4.0-34.38 -proposed tracker (LP: #1880118) + * debian/scripts/file-downloader does not handle positive failures correctly + (LP: #1878897) + - [Packaging] file-downloader not handling positive failures correctly + * Focal update: v5.4.41 upstream stable release (LP: #1878649) + - USB: serial: qcserial: Add DW5816e support + - nvme: refactor nvme_identify_ns_descs error handling + - nvme: fix possible hang when ns scanning fails during error recovery + - tracing/kprobes: Fix a double initialization typo + - net: macb: Fix runtime PM refcounting + - drm/amdgpu: move kfd suspend after ip_suspend_phase1 + - drm/amdgpu: drop redundant cg/pg ungate on runpm enter + - vt: fix unicode console freeing with a common interface + - tty: xilinx_uartps: Fix missing id assignment to the console + - devlink: fix return value after hitting end in region read + - dp83640: reverse arguments to list_add_tail + - fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks + - ipv6: Use global sernum for dst validation with nexthop objects + - mlxsw: spectrum_acl_tcam: Position vchunk in a vregion list properly + - neigh: send protocol value in neighbor create notification + - net: dsa: Do not leave DSA master with NULL netdev_ops + - net: macb: fix an issue about leak related system resources + - net: macsec: preserve ingress frame ordering + - net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() + - net_sched: sch_skbprio: add message validation to skbprio_change() + - net: stricter validation of untrusted gso packets + - net: tc35815: Fix phydev supported/advertising mask + - net/tls: Fix sk_psock refcnt leak in bpf_exec_tx_verdict() + - net/tls: Fix sk_psock refcnt leak when in tls_data_ready() + - net: usb: qmi_wwan: add support for DW5816e + - nfp: abm: fix a memory leak bug + - sch_choke: avoid potential panic in choke_reset() + - sch_sfq: validate silly quantum values + - tipc: fix partial topology connection closure + - tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 + - bnxt_en: Fix VF anti-spoof filter setup. + - bnxt_en: Reduce BNXT_MSIX_VEC_MAX value to supported CQs per PF. + - bnxt_en: Improve AER slot reset. + - bnxt_en: Return error when allocating zero size context memory. + - bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features(). + - net/mlx5: DR, On creation set CQ's arm_db member to right value + - net/mlx5: Fix forced completion access non initialized command entry + - net/mlx5: Fix command entry leak in Internal Error State + - net: mvpp2: prevent buffer overflow in mvpp22_rss_ctx() + - net: mvpp2: cls: Prevent buffer overflow in mvpp2_ethtool_cls_rule_del() + - HID: wacom: Read HID_DG_CONTACTMAX directly for non-generic devices + - sctp: Fix bundling of SHUTDOWN with COOKIE-ACK + - Revert "HID: wacom: generic: read the number of expected touches on a per + collection basis" + - HID: usbhid: Fix race between usbhid_close() and usbhid_stop() + - HID: wacom: Report 2nd-gen Intuos Pro S center button status over BT + - USB: uas: add quirk for LaCie 2Big Quadra + - usb: chipidea: msm: Ensure proper controller reset using role switch API + - USB: serial: garmin_gps: add sanity checking for data length + - tracing: Add a vmalloc_sync_mappings() for safe measure + - crypto: arch/nhpoly1305 - process in explicit 4k chunks + - KVM: s390: Remove false WARN_ON_ONCE for the PQAP instruction + - KVM: VMX: Explicitly clear RFLAGS.CF and RFLAGS.ZF in VM-Exit RSB path + - KVM: arm: vgic: Fix limit condition when writing to GICD_I[CS]ACTIVER + - KVM: arm64: Fix 32bit PC wrap-around + - arm64: hugetlb: avoid potential NULL dereference + - drm: ingenic-drm: add MODULE_DEVICE_TABLE + - ipc/mqueue.c: change __do_notify() to bypass check_kill_permission() + - epoll: atomically remove wait entry on wake up + - eventpoll: fix missing wakeup for ovflist in ep_poll_callback + - mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous() + - mm: limit boost_watermark on small zones + - ceph: demote quotarealm lookup warning to a debug message + - staging: gasket: Check the return value of gasket_get_bar_index() + - coredump: fix crash when umh is disabled + - iocost: protect iocg->abs_vdebt with iocg->waitq.lock + - batman-adv: fix batadv_nc_random_weight_tq + - batman-adv: Fix refcnt leak in batadv_show_throughput_override + - batman-adv: Fix refcnt leak in batadv_store_throughput_override + - batman-adv: Fix refcnt leak in batadv_v_ogm_process + - x86/entry/64: Fix unwind hints in register clearing code + - x86/entry/64: Fix unwind hints in kernel exit path + - x86/entry/64: Fix unwind hints in rewind_stack_do_exit() + - x86/unwind/orc: Don't skip the first frame for inactive tasks + - x86/unwind/orc: Prevent unwinding before ORC initialization + - x86/unwind/orc: Fix error path for bad ORC entry type + - x86/unwind/orc: Fix premature unwind stoppage due to IRET frames + - KVM: x86: Fixes posted interrupt check for IRQs delivery modes + - arch/x86/kvm/svm/sev.c: change flag passed to GUP fast in sev_pin_memory() + - netfilter: nat: never update the UDP checksum when it's 0 + - netfilter: nf_osf: avoid passing pointer to local var + - objtool: Fix stack offset tracking for indirect CFAs + - iommu/virtio: Reverse arguments to list_add + - scripts/decodecode: fix trapping instruction formatting + - mm, memcg: fix error return value of mem_cgroup_css_alloc() + - bdi: move bdi_dev_name out of line + - bdi: add a ->dev_name field to struct backing_dev_info + - fsnotify: replace inode pointer with an object id + - fanotify: merge duplicate events on parent and child + - Linux 5.4.41 + * Intel GPU Hangs : random screen freezing w/ Ubuntu 20.04 (Linux 5.4) + i915_active_acquire (LP: #1868551) + - drm/i915: Hold reference to intel_frontbuffer as we track activity + - drm/i915: fix uninitialized pointer reads on pointers to and from + * Kernel panic due to NULL ringbuffer vaddr dereference in i915 (LP: #1877394) + - Revert "UBUNTU: SAUCE: drm/i915: Synchronize active and retire callbacks" + - drm/i915/gt: Make intel_ring_unpin() safe for concurrent pint + * add 16-bit width registers support for EEPROM at24 device (LP: #1876699) + - regmap-i2c: add 16-bit width registers support + * [UBUNTU 20.04] PSI generates overhead on s390x (LP: #1876044) + - Ubuntu: [Config] Set CONFIG_PSI_DEFAULT_DISABLED=y on s390x + * Focal update: v5.4.40 upstream stable release (LP: #1878040) + - vhost: vsock: kick send_pkt worker once device is started + - drm/bridge: analogix_dp: Split bind() into probe() and real bind() + - ASoC: topology: Check return value of soc_tplg_create_tlv + - ASoC: topology: Check return value of soc_tplg_*_create + - ASoC: topology: Check soc_tplg_add_route return value + - ASoC: topology: Check return value of pcm_new_ver + - ASoC: topology: Check return value of soc_tplg_dai_config + - selftests/ipc: Fix test failure seen after initial test run + - ASoC: sgtl5000: Fix VAG power-on handling + - ASoC: topology: Fix endianness issue + - usb: dwc3: gadget: Properly set maxpacket limit + - ASoC: rsnd: Fix parent SSI start/stop in multi-SSI mode + - ASoC: rsnd: Fix HDMI channel mapping for multi-SSI mode + - ASoC: codecs: hdac_hdmi: Fix incorrect use of list_for_each_entry + - remoteproc: qcom_q6v5_mss: fix a bug in q6v5_probe() + - drm/amdgpu: Correctly initialize thermal controller for GPUs with Powerplay + table v0 (e.g Hawaii) + - wimax/i2400m: Fix potential urb refcnt leak + - net: stmmac: fix enabling socfpga's ptp_ref_clock + - net: stmmac: Fix sub-second increment + - ASoC: rsnd: Don't treat master SSI in multi SSI setup as parent + - ASoC: rsnd: Fix "status check failed" spam for multi-SSI + - cifs: protect updating server->dstaddr with a spinlock + - scripts/config: allow colons in option strings for sed + - cifs: do not share tcons with DFS + - tracing: Fix memory leaks in trace_events_hist.c + - lib/mpi: Fix building for powerpc with clang + - mac80211: sta_info: Add lockdep condition for RCU list usage + - net: bcmgenet: suppress warnings on failed Rx SKB allocations + - net: systemport: suppress warnings on failed Rx SKB allocations + - drm/i915: Extend WaDisableDARBFClkGating to icl,ehl,tgl + - sctp: Fix SHUTDOWN CTSN Ack in the peer restart case + - Revert "software node: Simplify software_node_release() function" + - hexagon: clean up ioremap + - hexagon: define ioremap_uc + - ALSA: hda: Match both PCI ID and SSID for driver blacklist + - x86/kvm: fix a missing-prototypes "vmread_error" + - platform/x86: GPD pocket fan: Fix error message when temp-limits are out of + range + - ACPI: PM: s2idle: Fix comment in acpi_s2idle_prepare_late() + - mac80211: add ieee80211_is_any_nullfunc() + - cgroup, netclassid: remove double cond_resched + - libbpf: Fix readelf output parsing for Fedora + - mm/mremap: Add comment explaining the untagging behaviour of mremap() + - Revert "drm/amd/display: setting the DIG_MODE to the correct value." + - tools headers UAPI: Sync copy of arm64's asm/unistd.h with the kernel + sources + - udp: document udp_rcv_segment special case for looped packets + - PM / devfreq: Add missing locking while setting suspend_freq + - Linux 5.4.40 + * Focal update: v5.4.39 upstream stable release (LP: #1877592) + - dma-buf: Fix SET_NAME ioctl uapi + - drm/edid: Fix off-by-one in DispID DTD pixel clock + - drm/amd/display: Fix green screen issue after suspend + - drm/qxl: qxl_release leak in qxl_draw_dirty_fb() + - drm/qxl: qxl_release leak in qxl_hw_surface_alloc() + - drm/qxl: qxl_release use after free + - NFSv4.1: fix handling of backchannel binding in BIND_CONN_TO_SESSION + - btrfs: fix transaction leak in btrfs_recover_relocation + - btrfs: fix block group leak when removing fails + - btrfs: fix partial loss of prealloc extent past i_size after fsync + - btrfs: transaction: Avoid deadlock due to bad initialization timing of + fs_info::journal_info + - mmc: cqhci: Avoid false "cqhci: CQE stuck on" by not open-coding timeout + loop + - mmc: sdhci-xenon: fix annoying 1.8V regulator warning + - mmc: sdhci-pci: Fix eMMC driver strength for BYT-based controllers + - mmc: sdhci-msm: Enable host capabilities pertains to R1b response + - mmc: meson-mx-sdio: Set MMC_CAP_WAIT_WHILE_BUSY + - mmc: meson-mx-sdio: remove the broken ->card_busy() op + - crypto: caam - fix the address of the last entry of S/G + - ALSA: hda/realtek - Two front mics on a Lenovo ThinkCenter + - ALSA: usb-audio: Correct a typo of NuPrime DAC-10 USB ID + - ALSA: hda/hdmi: fix without unlocked before return + - ALSA: line6: Fix POD HD500 audio playback + - ALSA: pcm: oss: Place the plugin buffer overflow checks correctly + - i2c: amd-mp2-pci: Fix Oops in amd_mp2_pci_init() error handling + - Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM + - dlmfs_file_write(): fix the bogosity in handling non-zero *ppos + - IB/rdmavt: Always return ERR_PTR from rvt_create_mmap_info() + - PM: ACPI: Output correct message on target power state + - PM: hibernate: Freeze kernel threads in software_resume() + - dm verity fec: fix hash block number in verity_fec_decode + - dm writecache: fix data corruption when reloading the target + - dm multipath: use updated MPATHF_QUEUE_IO on mapping for bio-based mpath + - ARM: dts: imx6qdl-sr-som-ti: indicate powering off wifi is safe + - scsi: qla2xxx: set UNLOADING before waiting for session deletion + - scsi: qla2xxx: check UNLOADING before posting async work + - RDMA/mlx5: Set GRH fields in query QP on RoCE + - RDMA/mlx4: Initialize ib_spec on the stack + - RDMA/siw: Fix potential siw_mem refcnt leak in siw_fastreg_mr() + - RDMA/core: Prevent mixed use of FDs between shared ufiles + - RDMA/core: Fix race between destroy and release FD object + - RDMA/cm: Fix ordering of xa_alloc_cyclic() in ib_create_cm_id() + - RDMA/cm: Fix an error check in cm_alloc_id_priv() + - i2c: iproc: generate stop event for slave writes + - vfio: avoid possible overflow in vfio_iommu_type1_pin_pages + - vfio/type1: Fix VA->PA translation for PFNMAP VMAs in vaddr_get_pfn() + - iommu/qcom: Fix local_base status check + - scsi: target/iblock: fix WRITE SAME zeroing + - iommu/amd: Fix legacy interrupt remapping for x2APIC-enabled system + - i2c: aspeed: Avoid i2c interrupt status clear race condition. + - ALSA: opti9xx: shut up gcc-10 range warning + - Fix use after free in get_tree_bdev() + - nvme: prevent double free in nvme_alloc_ns() error handling + - nfs: Fix potential posix_acl refcnt leak in nfs3_set_acl + - dmaengine: dmatest: Fix iteration non-stop logic + - dmaengine: dmatest: Fix process hang when reading 'wait' parameter + - arm64: vdso: Add -fasynchronous-unwind-tables to cflags + - selinux: properly handle multiple messages in selinux_netlink_send() + - Linux 5.4.39 + * Focal update: v5.4.38 upstream stable release (LP: #1876767) + - Linux 5.4.38 + * Focal update: v5.4.37 upstream stable release (LP: #1876765) + - remoteproc: Fix wrong rvring index computation + - ubifs: Fix ubifs_tnc_lookup() usage in do_kill_orphans() + - printk: queue wake_up_klogd irq_work only if per-CPU areas are ready + - ASoC: stm32: sai: fix sai probe + - usb: dwc3: gadget: Do link recovery for SS and SSP + - kbuild: fix DT binding schema rule again to avoid needless rebuilds + - usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete + - usb: gadget: udc: atmel: Fix vbus disconnect handling + - afs: Make record checking use TASK_UNINTERRUPTIBLE when appropriate + - afs: Fix to actually set AFS_SERVER_FL_HAVE_EPOCH + - iio:ad7797: Use correct attribute_group + - propagate_one(): mnt_set_mountpoint() needs mount_lock + - counter: 104-quad-8: Add lock guards - generic interface + - s390/ftrace: fix potential crashes when switching tracers + - ASoC: q6dsp6: q6afe-dai: add missing channels to MI2S DAIs + - ASoC: tas571x: disable regulators on failed probe + - ASoC: wm8960: Fix wrong clock after suspend & resume + - drivers: soc: xilinx: fix firmware driver Kconfig dependency + - nfsd: memory corruption in nfsd4_lock() + - bpf: Forbid XADD on spilled pointers for unprivileged users + - i2c: altera: use proper variable to hold errno + - rxrpc: Fix DATA Tx to disable nofrag for UDP on AF_INET6 socket + - net/cxgb4: Check the return from t4_query_params properly + - xfs: acquire superblock freeze protection on eofblocks scans + - svcrdma: Fix trace point use-after-free race + - svcrdma: Fix leak of svc_rdma_recv_ctxt objects + - net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ + overruns + - net/mlx5e: Get the latest values from counters in switchdev mode + - PCI: Add ACS quirk for Zhaoxin multi-function devices + - PCI: Make ACS quirk implementations more uniform + - PCI: Unify ACS quirk desired vs provided checking + - PCI: Add Zhaoxin Vendor ID + - PCI: Add ACS quirk for Zhaoxin Root/Downstream Ports + - PCI: Move Apex Edge TPU class quirk to fix BAR assignment + - ARM: dts: bcm283x: Disable dsi0 node + - cpumap: Avoid warning when CONFIG_DEBUG_PER_CPU_MAPS is enabled + - s390/pci: do not set affinity for floating irqs + - net/mlx5: Fix failing fw tracer allocation on s390 + - sched/core: Fix reset-on-fork from RT with uclamp + - perf/core: fix parent pid/tid in task exit events + - netfilter: nat: fix error handling upon registering inet hook + - PM: sleep: core: Switch back to async_schedule_dev() + - blk-iocost: Fix error on iocost_ioc_vrate_adj + - um: ensure `make ARCH=um mrproper` removes + arch/$(SUBARCH)/include/generated/ + - bpf, x86_32: Fix incorrect encoding in BPF_LDX zero-extension + - bpf, x86_32: Fix clobbering of dst for BPF_JSET + - bpf, x86_32: Fix logic error in BPF_LDX zero-extension + - mm: shmem: disable interrupt when acquiring info->lock in userfaultfd_copy + path + - xfs: clear PF_MEMALLOC before exiting xfsaild thread + - bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B + - libbpf: Initialize *nl_pid so gcc 10 is happy + - net: fec: set GPR bit on suspend by DT configuration. + - x86: hyperv: report value of misc_features + - signal: check sig before setting info in kill_pid_usb_asyncio + - afs: Fix length of dump of bad YFSFetchStatus record + - xfs: fix partially uninitialized structure in xfs_reflink_remap_extent + - ALSA: hda: Release resources at error in delayed probe + - ALSA: hda: Keep the controller initialization even if no codecs found + - ALSA: hda: Explicitly permit using autosuspend if runtime PM is supported + - scsi: target: fix PR IN / READ FULL STATUS for FC + - scsi: target: tcmu: reset_ring should reset TCMU_DEV_BIT_BROKEN + - objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings + - objtool: Support Clang non-section symbols in ORC dump + - xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status + - ALSA: hda: call runtime_allow() for all hda controllers + - net: stmmac: socfpga: Allow all RGMII modes + - mac80211: fix channel switch trigger from unknown mesh peer + - arm64: Delete the space separator in __emit_inst + - ext4: use matching invalidatepage in ext4_writepage + - ext4: increase wait time needed before reuse of deleted inode numbers + - ext4: convert BUG_ON's to WARN_ON's in mballoc.c + - blk-mq: Put driver tag in blk_mq_dispatch_rq_list() when no budget + - hwmon: (jc42) Fix name to have no illegal characters + - taprio: do not use BIT() in TCA_TAPRIO_ATTR_FLAG_* definitions + - qed: Fix race condition between scheduling and destroying the slowpath + workqueue + - Crypto: chelsio - Fixes a hang issue during driver registration + - net: use indirect call wrappers for skb_copy_datagram_iter() + - qed: Fix use after free in qed_chain_free + - ext4: check for non-zero journal inum in ext4_calculate_overhead + - ASoC: soc-core: disable route checks for legacy devices + - ASoC: stm32: spdifrx: fix regmap status check + - Linux 5.4.37 + * Focal update: v5.4.36 upstream stable release (LP: #1876361) + - ext4: fix extent_status fragmentation for plain files + - f2fs: fix to avoid memory leakage in f2fs_listxattr + - net, ip_tunnel: fix interface lookup with no key + - [Config] updateconfigs for ARM64_ERRATUM_1542419 + - arm64: errata: Hide CTR_EL0.DIC on systems affected by Neoverse-N1 #1542419 + - arm64: Fake the IminLine size on systems affected by Neoverse-N1 #1542419 + - arm64: compat: Workaround Neoverse-N1 #1542419 for compat user-space + - arm64: Silence clang warning on mismatched value/register sizes + - tools/testing/nvdimm: Fix compilation failure without + CONFIG_DEV_DAX_PMEM_COMPAT + - watchdog: reset last_hw_keepalive time at start + - scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login + - scsi: lpfc: Fix crash after handling a pci error + - scsi: lpfc: Fix crash in target side cable pulls hitting WAIT_FOR_UNREG + - scsi: libfc: If PRLI rejected, move rport to PLOGI state + - ceph: return ceph_mdsc_do_request() errors from __get_parent() + - ceph: don't skip updating wanted caps when cap is stale + - pwm: rcar: Fix late Runtime PM enablement + - nvme-tcp: fix possible crash in write_zeroes processing + - scsi: iscsi: Report unbind session event when the target has been removed + - tools/test/nvdimm: Fix out of tree build + - ASoC: Intel: atom: Take the drv->lock mutex before calling + sst_send_slot_map() + - nvme: fix deadlock caused by ANA update wrong locking + - drm/amd/display: Update stream adjust in dc_stream_adjust_vmin_vmax + - dma-direct: fix data truncation in dma_direct_get_required_mask() + - kernel/gcov/fs.c: gcov_seq_next() should increase position index + - selftests: kmod: fix handling test numbers above 9 + - ipc/util.c: sysvipc_find_ipc() should increase position index + - kconfig: qconf: Fix a few alignment issues + - lib/raid6/test: fix build on distros whose /bin/sh is not bash + - s390/cio: generate delayed uevent for vfio-ccw subchannels + - s390/cio: avoid duplicated 'ADD' uevents + - loop: Better discard support for block devices + - Revert "powerpc/64: irq_work avoid interrupt when called with hardware irqs + enabled" + - powerpc/pseries: Fix MCE handling on pseries + - nvme: fix compat address handling in several ioctls + - pwm: renesas-tpu: Fix late Runtime PM enablement + - pwm: bcm2835: Dynamically allocate base + - perf/core: Disable page faults when getting phys address + - drm/amd/display: Calculate scaling ratios on every medium/full update + - ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet + - ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk + - drm/amd/display: Not doing optimize bandwidth if flip pending. + - cxgb4: fix adapter crash due to wrong MC size + - cxgb4: fix large delays in PTP synchronization + - ipv4: Update fib_select_default to handle nexthop objects + - ipv6: fix restrict IPV6_ADDRFORM operation + - macsec: avoid to set wrong mtu + - macvlan: fix null dereference in macvlan_device_event() + - mlxsw: Fix some IS_ERR() vs NULL bugs + - net: bcmgenet: correct per TX/RX ring statistics + - net/mlx4_en: avoid indirect call in TX completion + - net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node + - net: openvswitch: ovs_ct_exit to be done under ovs_lock + - net: stmmac: dwmac-meson8b: Add missing boundary to RGMII TX clock array + - net/x25: Fix x25_neigh refcnt leak when receiving frame + - sched: etf: do not assume all sockets are full blown + - selftests: Fix suppress test in fib_tests.sh + - tcp: cache line align MAX_TCP_HEADER + - team: fix hang in team_mode_get() + - vrf: Fix IPv6 with qdisc and xfrm + - net: dsa: b53: Lookup VID in ARL searches when VLAN is enabled + - net: dsa: b53: Fix valid setting for MDB entries + - net: dsa: b53: Fix ARL register definitions + - net: dsa: b53: Rework ARL bin logic + - net: dsa: b53: b53_arl_rw_op() needs to select IVL or SVL + - vxlan: use the correct nlattr array in NL_SET_ERR_MSG_ATTR + - geneve: use the correct nlattr array in NL_SET_ERR_MSG_ATTR + - xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish + - vrf: Check skb for XFRM_TRANSFORMED flag + - KEYS: Avoid false positive ENOMEM error on key read + - ALSA: hda: Remove ASUS ROG Zenith from the blacklist + - ALSA: usb-audio: Add static mapping table for ALC1220-VB-based mobos + - ALSA: usb-audio: Add connector notifier delegation + - iio: core: remove extra semi-colon from devm_iio_device_register() macro + - iio: st_sensors: rely on odr mask to know if odr can be set + - iio: adc: stm32-adc: fix sleep in atomic context + - iio: adc: ti-ads8344: properly byte swap value + - iio: xilinx-xadc: Fix ADC-B powerdown + - iio: xilinx-xadc: Fix clearing interrupt when enabling trigger + - iio: xilinx-xadc: Fix sequencer configuration for aux channels in + simultaneous mode + - iio: xilinx-xadc: Make sure not exceed maximum samplerate + - USB: sisusbvga: Change port variable from signed to unsigned + - USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 + RGB RAPIDFIRE + - USB: early: Handle AMD's spec-compliant identifiers, too + - USB: core: Fix free-while-in-use bug in the USB S-Glibrary + - USB: hub: Fix handling of connect changes during sleep + - USB: hub: Revert commit bd0e6c9614b9 ("usb: hub: try old enumeration scheme + first for high speed devices") + - tty: serial: owl: add "much needed" clk_prepare_enable() + - vmalloc: fix remap_vmalloc_range() bounds checks + - staging: gasket: Fix incongruency in handling of sysfs entries creation + - coredump: fix null pointer dereference on coredump + - mm/hugetlb: fix a addressing exception caused by huge_pte_offset + - mm/ksm: fix NULL pointer dereference when KSM zero page is enabled + - tools/vm: fix cross-compile build + - ALSA: usx2y: Fix potential NULL dereference + - ALSA: hda/realtek - Fix unexpected init_amp override + - ALSA: hda/realtek - Add new codec supported for ALC245 + - ALSA: hda/hdmi: Add module option to disable audio component binding + - ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif + - ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices + - tpm/tpm_tis: Free IRQ if probing fails + - tpm: fix wrong return value in tpm_pcr_extend + - tpm: ibmvtpm: retry on H_CLOSED in tpm_ibmvtpm_send() + - KVM: s390: Return last valid slot if approx index is out-of-bounds + - KVM: Check validity of resolved slot when searching memslots + - KVM: VMX: Enable machine check support for 32bit targets + - tty: hvc: fix buffer overflow during hvc_alloc(). + - tty: rocket, avoid OOB access + - usb-storage: Add unusual_devs entry for JMicron JMS566 + - signal: Avoid corrupting si_pid and si_uid in do_notify_parent + - audit: check the length of userspace generated audit records + - ASoC: dapm: fixup dapm kcontrol widget + - mac80211: populate debugfs only after cfg80211 init + - SUNRPC: Fix backchannel RPC soft lockups + - iwlwifi: pcie: actually release queue memory in TVQM + - iwlwifi: mvm: beacon statistics shouldn't go backwards + - iwlwifi: mvm: limit maximum queue appropriately + - iwlwifi: mvm: Do not declare support for ACK Enabled Aggregation + - iwlwifi: mvm: fix inactive TID removal return value usage + - cifs: fix uninitialised lease_key in open_shroot() + - ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y + - powerpc/setup_64: Set cache-line-size based on cache-block-size + - staging: comedi: dt2815: fix writing hi byte of analog output + - staging: comedi: Fix comedi_device refcnt leak in comedi_open + - vt: don't hardcode the mem allocation upper bound + - vt: don't use kmalloc() for the unicode screen buffer + - staging: vt6656: Don't set RCR_MULTICAST or RCR_BROADCAST by default. + - staging: vt6656: Fix calling conditions of vnt_set_bss_mode + - staging: vt6656: Fix drivers TBTT timing counter. + - staging: vt6656: Fix pairwise key entry save. + - staging: vt6656: Power save stop wake_up_count wrap around. + - cdc-acm: close race betrween suspend() and acm_softint + - cdc-acm: introduce a cool down + - UAS: no use logging any details in case of ENODEV + - UAS: fix deadlock in error handling and PM flushing work + - fpga: dfl: pci: fix return value of cci_pci_sriov_configure + - usb: dwc3: gadget: Fix request completion check + - usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset() + - usb: typec: tcpm: Ignore CC and vbus changes in PORT_RESET change + - usb: typec: altmode: Fix typec_altmode_get_partner sometimes returning an + invalid pointer + - xhci: Fix handling halted endpoint even if endpoint ring appears empty + - xhci: prevent bus suspend if a roothub port detected a over-current + condition + - xhci: Don't clear hub TT buffer on ep0 protocol stall + - serial: sh-sci: Make sure status register SCxSR is read in correct sequence + - Revert "serial: uartps: Fix uartps_major handling" + - Revert "serial: uartps: Use the same dynamic major number for all ports" + - Revert "serial: uartps: Fix error path when alloc failed" + - Revert "serial: uartps: Do not allow use aliases >= MAX_UART_INSTANCES" + - Revert "serial: uartps: Change uart ID port allocation" + - Revert "serial: uartps: Move Port ID to device data structure" + - Revert "serial: uartps: Register own uart console and driver structures" + - powerpc/kuap: PPC_KUAP_DEBUG should depend on PPC_KUAP + - powerpc/mm: Fix CONFIG_PPC_KUAP_DEBUG on PPC32 + - compat: ARM64: always include asm-generic/compat.h + - Linux 5.4.36 + * Focal update: v5.4.35 upstream stable release (LP: #1875660) + - ext4: use non-movable memory for superblock readahead + - watchdog: sp805: fix restart handler + - xsk: Fix out of boundary write in __xsk_rcv_memcpy + - arm, bpf: Fix bugs with ALU64 {RSH, ARSH} BPF_K shift by 0 + - arm, bpf: Fix offset overflow for BPF_MEM BPF_DW + - objtool: Fix switch table detection in .text.unlikely + - scsi: sg: add sg_remove_request in sg_common_write + - ALSA: hda: Honor PM disablement in PM freeze and thaw_noirq ops + - ARM: dts: imx6: Use gpc for FEC interrupt controller to fix wake on LAN. + - kbuild, btf: Fix dependencies for DEBUG_INFO_BTF + - netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type + - irqchip/mbigen: Free msi_desc on device teardown + - ALSA: hda: Don't release card at firmware loading error + - xsk: Add missing check on user supplied headroom size + - of: unittest: kmemleak on changeset destroy + - of: unittest: kmemleak in of_unittest_platform_populate() + - of: unittest: kmemleak in of_unittest_overlay_high_level() + - of: overlay: kmemleak in dup_and_fixup_symbol_prop() + - x86/Hyper-V: Unload vmbus channel in hv panic callback + - x86/Hyper-V: Trigger crash enlightenment only once during system crash. + - x86/Hyper-V: Report crash register data or kmsg before running crash kernel + - x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not + set + - x86/Hyper-V: Report crash data in die() when panic_on_oops is set + - afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus() + - afs: Fix decoding of inline abort codes from version 1 status records + - afs: Fix rename operation status delivery + - afs: Fix afs_d_validate() to set the right directory version + - afs: Fix race between post-modification dir edit and readdir/d_revalidate + - block, bfq: turn put_queue into release_process_ref in + __bfq_bic_change_cgroup + - block, bfq: make reparent_leaf_entity actually work only on leaf entities + - block, bfq: invoke flush_idle_tree after reparent_active_queues in + pd_offline + - rbd: avoid a deadlock on header_rwsem when flushing notifies + - rbd: call rbd_dev_unprobe() after unwatching and flushing notifies + - x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump + - drm/ttm: flush the fence on the bo after we individualize the reservation + object + - clk: Don't cache errors from clk_ops::get_phase() + - clk: at91: usb: continue if clk_hw_round_rate() return zero + - net/mlx5e: Enforce setting of a single FEC mode + - f2fs: fix the panic in do_checkpoint() + - ARM: dts: rockchip: fix vqmmc-supply property name for rk3188-bqedison2qc + - arm64: dts: allwinner: a64: Fix display clock register range + - power: supply: bq27xxx_battery: Silence deferred-probe error + - clk: tegra: Fix Tegra PMC clock out parents + - arm64: tegra: Add PCIe endpoint controllers nodes for Tegra194 + - arm64: tegra: Fix Tegra194 PCIe compatible string + - arm64: dts: clearfog-gt-8k: set gigabit PHY reset deassert delay + - soc: imx: gpc: fix power up sequencing + - dma-coherent: fix integer overflow in the reserved-memory dma allocation + - rtc: 88pm860x: fix possible race condition + - NFS: alloc_nfs_open_context() must use the file cred when available + - NFSv4/pnfs: Return valid stateids in nfs_layout_find_inode_by_stateid() + - NFSv4.2: error out when relink swapfile + - ARM: dts: rockchip: fix lvds-encoder ports subnode for rk3188-bqedison2qc + - KVM: PPC: Book3S HV: Fix H_CEDE return code for nested guests + - f2fs: fix to show norecovery mount option + - phy: uniphier-usb3ss: Add Pro5 support + - NFS: direct.c: Fix memory leak of dreq when nfs_get_lock_context fails + - f2fs: Fix mount failure due to SPO after a successful online resize FS + - f2fs: Add a new CP flag to help fsck fix resize SPO issues + - s390/cpuinfo: fix wrong output when CPU0 is offline + - hibernate: Allow uswsusp to write to swap + - btrfs: add RCU locks around block group initialization + - powerpc/prom_init: Pass the "os-term" message to hypervisor + - powerpc/maple: Fix declaration made after definition + - s390/cpum_sf: Fix wrong page count in error message + - ext4: do not commit super on read-only bdev + - um: ubd: Prevent buffer overrun on command completion + - cifs: Allocate encryption header through kmalloc + - mm/hugetlb: fix build failure with HUGETLB_PAGE but not HUGEBTLBFS + - drm/nouveau/svm: check for SVM initialized before migrating + - drm/nouveau/svm: fix vma range check for migration + - include/linux/swapops.h: correct guards for non_swap_entry() + - percpu_counter: fix a data race at vm_committed_as + - compiler.h: fix error in BUILD_BUG_ON() reporting + - KVM: s390: vsie: Fix possible race when shadowing region 3 tables + - drm/nouveau: workaround runpm fail by disabling PCI power management on + certain intel bridges + - leds: core: Fix warning message when init_data + - x86: ACPI: fix CPU hotplug deadlock + - csky: Fixup cpu speculative execution to IO area + - drm/amdkfd: kfree the wrong pointer + - NFS: Fix memory leaks in nfs_pageio_stop_mirroring() + - csky: Fixup get wrong psr value from phyical reg + - f2fs: fix NULL pointer dereference in f2fs_write_begin() + - ACPICA: Fixes for acpiExec namespace init file + - um: falloc.h needs to be directly included for older libc + - drm/vc4: Fix HDMI mode validation + - iommu/virtio: Fix freeing of incomplete domains + - iommu/vt-d: Fix mm reference leak + - ext2: fix empty body warnings when -Wextra is used + - iommu/vt-d: Silence RCU-list debugging warning in dmar_find_atsr() + - iommu/vt-d: Fix page request descriptor size + - ext2: fix debug reference to ext2_xattr_cache + - sunrpc: Fix gss_unwrap_resp_integ() again + - csky: Fixup init_fpu compile warning with __init + - power: supply: axp288_fuel_gauge: Broaden vendor check for Intel Compute + Sticks. + - libnvdimm: Out of bounds read in __nd_ioctl() + - iommu/amd: Fix the configuration of GCR3 table root pointer + - f2fs: fix to wait all node page writeback + - drm/nouveau/gr/gp107,gp108: implement workaround for HW hanging during init + - net: dsa: bcm_sf2: Fix overflow checks + - dma-debug: fix displaying of dma allocation type + - fbdev: potential information leak in do_fb_ioctl() + - ARM: dts: sunxi: Fix DE2 clocks register range + - iio: si1133: read 24-bit signed integer for measurement + - fbmem: Adjust indentation in fb_prepare_logo and fb_blank + - tty: evh_bytechan: Fix out of bounds accesses + - locktorture: Print ratio of acquisitions, not failures + - mtd: rawnand: free the nand_device object + - mtd: spinand: Explicitly use MTD_OPS_RAW to write the bad block marker to + OOB + - docs: Fix path to MTD command line partition parser + - mtd: lpddr: Fix a double free in probe() + - mtd: phram: fix a double free issue in error path + - KEYS: Don't write out to userspace while holding key semaphore + - bpf: fix buggy r0 retval refinement for tracing helpers + - bpf: Test_verifier, bpf_get_stack return value add <0 + - bpf: Test_progs, add test to catch retval refine error handling + - SAUCE: bpf: Test_progs, fix test_get_stack_rawtp_err.c build + - bpf, test_verifier: switch bpf_get_stack's 0 s> r8 test + - Linux 5.4.35 + * Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW), + REV=0x354 [8086:a0f0] subsystem id [1a56:1651] wireless adapter not found + due to firmware crash (LP: #1874685) + - iwlwifi: pcie: handle QuZ configs with killer NICs as well + * Support DMIC micmute LED on HP platforms (LP: #1876859) + - ALSA: hda/realtek - Introduce polarity for micmute LED GPIO + - ALSA: hda/realtek - Enable micmute LED on and HP system + - ALSA: hda/realtek - Add LED class support for micmute LED + - ALSA: hda/realtek - Fix unused variable warning w/o + CONFIG_LEDS_TRIGGER_AUDIO + - ASoC: SOF: Update correct LED status at the first time usage of + update_mute_led() + * linux: riscv: set max_pfn to the PFN of the last page (LP: #1876885) + - riscv: set max_pfn to the PFN of the last page + * Dell XPS 13 9300 mirror mode doesn't work sometimes with WD19TB + (LP: #1877013) + - drm/i915/perf: Do not clear pollin for small user read buffers + * [UBUNTU 20.04] s390x/pci: do not allow to create more pci functions than + configured via CONFIG_PCI_NR_FUNCTIONS (LP: #1874057) + - s390/pci: Fix zpci_alloc_domain() over allocation + * [Ubuntu 20.04] net/mlx5e: Fix endianness handling in pedit mask + (LP: #1872726) + - net/mlx5e: Fix endianness handling in pedit mask + * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after + upgrade to 20.04 (LP: #1875665) + - [Config] Turn off CONFIG_RT_GROUP_SCHED everywhere + * ceph -- Unable to mount ceph volume on s390x (LP: #1875863) + - ceph: fix endianness bug when handling MDS session feature bits + * Do not treat unresolved test case in ftrace from ubuntu_kernel_selftests as + failure (LP: #1877958) + - ftrace/selftest: make unresolved cases cause failure if --fail-unresolved + set + * Add support for Ambiq micro AM1805 RTC chip (LP: #1876667) + - SAUCE: rtc: add am-1805 RTC driver + * alsa/sof: kernel oops on the machine without Intel hdmi audio codec (a + regression in the asoc machine driver) (LP: #1874359) + - SAUCE: ASoC: intel/skl/hda - fix oops on systems without i915 audio codec + * 'Elan touchpad' not detected on 'Lenovo ThinkBook 15 IIL' (LP: #1861610) + - SAUCE: Input: elan_i2c - add more hardware ID for Lenovo laptop + + [ Ubuntu: 5.4.0-33.37 ] + + * focal/linux: 5.4.0-33.37 -proposed tracker (LP: #1879926) + * Docker registry doesn't stay up and keeps restarting (LP: #1879690) + - Revert "UBUNTU: SAUCE: overlayfs: fix shitfs special-casing" + - Revert "UBUNTU: SAUCE: overlayfs: use shiftfs hacks only with shiftfs as + underlay" + + -- Kleber Sacilotto de Souza Tue, 26 May 2020 16:00:59 +0200 + +linux-oracle (5.4.0-1011.11) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1011.11 -proposed tracker (LP: #1878001) + + [ Ubuntu: 5.4.0-31.35 ] + + * focal/linux: 5.4.0-31.35 -proposed tracker (LP: #1877253) + * Intermittent display blackouts on event (LP: #1875254) + - drm/i915: Limit audio CDCLK>=2*BCLK constraint back to GLK only + * Unable to handle kernel pointer dereference in virtual kernel address space + on Eoan (LP: #1876645) + - SAUCE: overlayfs: fix shitfs special-casing + + -- Ian May Mon, 11 May 2020 08:56:57 -0500 + +linux-oracle (5.4.0-1010.10) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1010.10 -proposed tracker (LP: #1875383) + + * bionic/oracle-5.3: Move bnxt_en driver from -modules-extras to -modules + (LP: #1874553) + - [Config] Move bnxt_en driver from modules-extra to modules + + * Packaging resync (LP: #1786013) + - [Packaging] add libcap-dev dependency + + [ Ubuntu: 5.4.0-30.34 ] + + * focal/linux: 5.4.0-30.34 -proposed tracker (LP: #1875385) + * ubuntu/focal64 fails to mount Vagrant shared folders (LP: #1873506) + - [Packaging] Move virtualbox modules to linux-modules + - [Packaging] Remove vbox and zfs modules from generic.inclusion-list + * linux-image-5.0.0-35-generic breaks checkpointing of container + (LP: #1857257) + - SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay + * shiftfs: broken shiftfs nesting (LP: #1872094) + - SAUCE: shiftfs: record correct creator credentials + * Add debian/rules targets to compile/run kernel selftests (LP: #1874286) + - [Packaging] add support to compile/run selftests + * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757) + - SAUCE: shiftfs: fix dentry revalidation + * LIO hanging in iscsit_free_session and iscsit_stop_session (LP: #1871688) + - scsi: target: iscsi: calling iscsit_stop_session() inside + iscsit_close_session() has no effect + * [ICL] TC port in legacy/static mode can't be detected due TCCOLD + (LP: #1868936) + - SAUCE: drm/i915: Align power domain names with port names + - SAUCE: drm/i915/display: Move out code to return the digital_port of the aux + ch + - SAUCE: drm/i915/display: Add intel_legacy_aux_to_power_domain() + - SAUCE: drm/i915/display: Split hsw_power_well_enable() into two + - SAUCE: drm/i915/tc/icl: Implement TC cold sequences + - SAUCE: drm/i915/tc: Skip ref held check for TC legacy aux power wells + - SAUCE: drm/i915/tc/tgl: Implement TC cold sequences + - SAUCE: drm/i915/tc: Catch TC users accessing FIA registers without enable + aux + - SAUCE: drm/i915/tc: Do not warn when aux power well of static TC ports + timeout + * alsa/sof: external mic can't be deteced on Lenovo and HP laptops + (LP: #1872569) + - SAUCE: ASoC: intel/skl/hda - set autosuspend timeout for hda codecs + * amdgpu kernel errors in Linux 5.4 (LP: #1871248) + - drm/amd/display: Stop if retimer is not available + * Focal update: v5.4.34 upstream stable release (LP: #1874111) + - amd-xgbe: Use __napi_schedule() in BH context + - hsr: check protocol version in hsr_newlink() + - l2tp: Allow management of tunnels and session in user namespace + - net: dsa: mt7530: fix tagged frames pass-through in VLAN-unaware mode + - net: ipv4: devinet: Fix crash when add/del multicast IP with autojoin + - net: ipv6: do not consider routes via gateways for anycast address check + - net: phy: micrel: use genphy_read_status for KSZ9131 + - net: qrtr: send msgs from local of same id as broadcast + - net: revert default NAPI poll timeout to 2 jiffies + - net: tun: record RX queue in skb before do_xdp_generic() + - net: dsa: mt7530: move mt7623 settings out off the mt7530 + - net: ethernet: mediatek: move mt7623 settings out off the mt7530 + - net/mlx5: Fix frequent ioread PCI access during recovery + - net/mlx5e: Add missing release firmware call + - net/mlx5e: Fix nest_level for vlan pop action + - net/mlx5e: Fix pfnum in devlink port attribute + - net: stmmac: dwmac-sunxi: Provide TX and RX fifo sizes + - ovl: fix value of i_ino for lower hardlink corner case + - scsi: ufs: Fix ufshcd_hold() caused scheduling while atomic + - platform/chrome: cros_ec_rpmsg: Fix race with host event + - jbd2: improve comments about freeing data buffers whose page mapping is NULL + - acpi/nfit: improve bounds checking for 'func' + - perf report: Fix no branch type statistics report issue + - pwm: pca9685: Fix PWM/GPIO inter-operation + - ext4: fix incorrect group count in ext4_fill_super error message + - ext4: fix incorrect inodes per group in error message + - clk: at91: sam9x60: fix usb clock parents + - clk: at91: usb: use proper usbs_mask + - ARM: dts: imx7-colibri: fix muxing of usbc_det pin + - arm64: dts: librem5-devkit: add a vbus supply to usb0 + - usb: dwc3: gadget: Don't clear flags before transfer ended + - ASoC: Intel: mrfld: fix incorrect check on p->sink + - ASoC: Intel: mrfld: return error codes when an error occurs + - ALSA: hda/realtek - Enable the headset mic on Asus FX505DT + - ALSA: usb-audio: Filter error from connector kctl ops, too + - ALSA: usb-audio: Don't override ignore_ctl_error value from the map + - ALSA: usb-audio: Don't create jack controls for PCM terminals + - ALSA: usb-audio: Check mapping at creating connector controls, too + - arm64: vdso: don't free unallocated pages + - keys: Fix proc_keys_next to increase position index + - tracing: Fix the race between registering 'snapshot' event trigger and + triggering 'snapshot' operation + - btrfs: check commit root generation in should_ignore_root + - nl80211: fix NL80211_ATTR_FTM_RESPONDER policy + - mac80211: fix race in ieee80211_register_hw() + - mac80211_hwsim: Use kstrndup() in place of kasprintf() + - net/mlx5e: Encapsulate updating netdev queues into a function + - net/mlx5e: Rename hw_modify to preactivate + - net/mlx5e: Use preactivate hook to set the indirection table + - drm/amd/powerplay: force the trim of the mclk dpm_levels if OD is enabled + - drm/amdgpu: fix the hw hang during perform system reboot and reset + - i2c: designware: platdrv: Remove DPM_FLAG_SMART_SUSPEND flag on BYT and CHT + - ext4: do not zeroout extents beyond i_disksize + - irqchip/ti-sci-inta: Fix processing of masked irqs + - x86/resctrl: Preserve CDP enable over CPU hotplug + - x86/resctrl: Fix invalid attempt at removing the default resource group + - scsi: target: remove boilerplate code + - scsi: target: fix hang when multiple threads try to destroy the same iscsi + session + - x86/microcode/AMD: Increase microcode PATCH_MAX_SIZE + - Linux 5.4.34 + * Focal update: v5.4.33 upstream stable release (LP: #1873481) + - ARM: dts: sun8i-a83t-tbs-a711: HM5065 doesn't like such a high voltage + - bus: sunxi-rsb: Return correct data when mixing 16-bit and 8-bit reads + - ARM: dts: Fix dm814x Ethernet by changing to use rgmii-id mode + - bpf: Fix deadlock with rq_lock in bpf_send_signal() + - iwlwifi: mvm: Fix rate scale NSS configuration + - Input: tm2-touchkey - add support for Coreriver TC360 variant + - soc: fsl: dpio: register dpio irq handlers after dpio create + - rxrpc: Abstract out the calculation of whether there's Tx space + - rxrpc: Fix call interruptibility handling + - net: stmmac: platform: Fix misleading interrupt error msg + - net: vxge: fix wrong __VA_ARGS__ usage + - hinic: fix a bug of waitting for IO stopped + - hinic: fix the bug of clearing event queue + - hinic: fix out-of-order excution in arm cpu + - hinic: fix wrong para of wait_for_completion_timeout + - hinic: fix wrong value of MIN_SKB_LEN + - selftests/net: add definition for SOL_DCCP to fix compilation errors for old + libc + - cxgb4/ptp: pass the sign of offset delta in FW CMD + - drm/scheduler: fix rare NULL ptr race + - cfg80211: Do not warn on same channel at the end of CSA + - qlcnic: Fix bad kzalloc null test + - i2c: st: fix missing struct parameter description + - i2c: pca-platform: Use platform_irq_get_optional + - media: rc: add keymap for Videostrong KII Pro + - cpufreq: imx6q: Fixes unwanted cpu overclocking on i.MX6ULL + - staging: wilc1000: avoid double unlocking of 'wilc->hif_cs' mutex + - media: venus: hfi_parser: Ignore HEVC encoding for V1 + - firmware: arm_sdei: fix double-lock on hibernate with shared events + - null_blk: Fix the null_add_dev() error path + - null_blk: Handle null_add_dev() failures properly + - null_blk: fix spurious IO errors after failed past-wp access + - media: imx: imx7_mipi_csis: Power off the source when stopping streaming + - media: imx: imx7-media-csi: Fix video field handling + - xhci: bail out early if driver can't accress host in resume + - x86: Don't let pgprot_modify() change the page encryption bit + - dma-mapping: Fix dma_pgprot() for unencrypted coherent pages + - block: keep bdi->io_pages in sync with max_sectors_kb for stacked devices + - debugfs: Check module state before warning in {full/open}_proxy_open() + - irqchip/versatile-fpga: Handle chained IRQs properly + - time/sched_clock: Expire timer in hardirq context + - media: allegro: fix type of gop_length in channel_create message + - sched: Avoid scale real weight down to zero + - selftests/x86/ptrace_syscall_32: Fix no-vDSO segfault + - PCI/switchtec: Fix init_completion race condition with poll_wait() + - block, bfq: move forward the getting of an extra ref in bfq_bfqq_move + - media: i2c: video-i2c: fix build errors due to 'imply hwmon' + - libata: Remove extra scsi_host_put() in ata_scsi_add_hosts() + - pstore/platform: fix potential mem leak if pstore_init_fs failed + - gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty + - gfs2: Don't demote a glock until its revokes are written + - cpufreq: imx6q: fix error handling + - x86/boot: Use unsigned comparison for addresses + - efi/x86: Ignore the memory attributes table on i386 + - genirq/irqdomain: Check pointer in irq_domain_alloc_irqs_hierarchy() + - block: Fix use-after-free issue accessing struct io_cq + - media: i2c: ov5695: Fix power on and off sequences + - usb: dwc3: core: add support for disabling SS instances in park mode + - irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency + - md: check arrays is suspended in mddev_detach before call quiesce operations + - firmware: fix a double abort case with fw_load_sysfs_fallback + - spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion + - locking/lockdep: Avoid recursion in lockdep_count_{for,back}ward_deps() + - block, bfq: fix use-after-free in bfq_idle_slice_timer_body + - btrfs: qgroup: ensure qgroup_rescan_running is only set when the worker is + at least queued + - btrfs: remove a BUG_ON() from merge_reloc_roots() + - btrfs: restart relocate_tree_blocks properly + - btrfs: track reloc roots based on their commit root bytenr + - ASoC: fix regwmask + - ASoC: dapm: connect virtual mux with default value + - ASoC: dpcm: allow start or stop during pause for backend + - ASoC: topology: use name_prefix for new kcontrol + - usb: gadget: f_fs: Fix use after free issue as part of queue failure + - usb: gadget: composite: Inform controller driver of self-powered + - ALSA: usb-audio: Add mixer workaround for TRX40 and co + - ALSA: hda: Add driver blacklist + - ALSA: hda: Fix potential access overflow in beep helper + - ALSA: ice1724: Fix invalid access for enumerated ctl items + - ALSA: pcm: oss: Fix regression by buffer overflow fix + - ALSA: hda/realtek - a fake key event is triggered by running shutup + - ALSA: doc: Document PC Beep Hidden Register on Realtek ALC256 + - ALSA: hda/realtek - Set principled PC Beep configuration for ALC256 + - ALSA: hda/realtek - Remove now-unnecessary XPS 13 headphone noise fixups + - ALSA: hda/realtek - Add quirk for Lenovo Carbon X1 8th gen + - ALSA: hda/realtek - Add quirk for MSI GL63 + - media: venus: firmware: Ignore secure call error on first resume + - media: hantro: Read be32 words starting at every fourth byte + - media: ti-vpe: cal: fix disable_irqs to only the intended target + - media: ti-vpe: cal: fix a kernel oops when unloading module + - seccomp: Add missing compat_ioctl for notify + - acpi/x86: ignore unspecified bit positions in the ACPI global lock field + - ACPICA: Allow acpi_any_gpe_status_set() to skip one GPE + - ACPI: PM: s2idle: Refine active GPEs check + - thermal: devfreq_cooling: inline all stubs for CONFIG_DEVFREQ_THERMAL=n + - nvmet-tcp: fix maxh2cdata icresp parameter + - efi/x86: Add TPM related EFI tables to unencrypted mapping checks + - PCI: pciehp: Fix indefinite wait on sysfs requests + - PCI/ASPM: Clear the correct bits when enabling L1 substates + - PCI: Add boot interrupt quirk mechanism for Xeon chipsets + - PCI: qcom: Fix the fixup of PCI_VENDOR_ID_QCOM + - PCI: endpoint: Fix for concurrent memory allocation in OB address region + - sched/fair: Fix enqueue_task_fair warning + - tpm: Don't make log failures fatal + - tpm: tpm1_bios_measurements_next should increase position index + - tpm: tpm2_bios_measurements_next should increase position index + - cpu/hotplug: Ignore pm_wakeup_pending() for disable_nonboot_cpus() + - genirq/debugfs: Add missing sanity checks to interrupt injection + - irqchip/versatile-fpga: Apply clear-mask earlier + - io_uring: remove bogus RLIMIT_NOFILE check in file registration + - pstore: pstore_ftrace_seq_next should increase position index + - MIPS/tlbex: Fix LDDIR usage in setup_pw() for Loongson-3 + - MIPS: OCTEON: irq: Fix potential NULL pointer dereference + - PM / Domains: Allow no domain-idle-states DT property in genpd when parsing + - PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there + - ath9k: Handle txpower changes even when TPC is disabled + - signal: Extend exec_id to 64bits + - x86/tsc_msr: Use named struct initializers + - x86/tsc_msr: Fix MSR_FSB_FREQ mask for Cherry Trail devices + - x86/tsc_msr: Make MSR derived TSC frequency more accurate + - x86/entry/32: Add missing ASM_CLAC to general_protection entry + - platform/x86: asus-wmi: Support laptops where the first battery is named + BATT + - KVM: nVMX: Properly handle userspace interrupt window request + - KVM: s390: vsie: Fix region 1 ASCE sanity shadow address checks + - KVM: s390: vsie: Fix delivery of addressing exceptions + - KVM: x86: Allocate new rmap and large page tracking when moving memslot + - KVM: VMX: Always VMCLEAR in-use VMCSes during crash with kexec support + - KVM: x86: Gracefully handle __vmalloc() failure during VM allocation + - KVM: VMX: Add a trampoline to fix VMREAD error handling + - KVM: VMX: fix crash cleanup when KVM wasn't used + - smb3: fix performance regression with setting mtime + - CIFS: Fix bug which the return value by asynchronous read is error + - mtd: spinand: Stop using spinand->oobbuf for buffering bad block markers + - mtd: spinand: Do not erase the block before writing a bad block marker + - btrfs: Don't submit any btree write bio if the fs has errors + - Btrfs: fix crash during unmount due to race with delayed inode workers + - btrfs: reloc: clean dirty subvols if we fail to start a transaction + - btrfs: set update the uuid generation as soon as possible + - btrfs: drop block from cache on error in relocation + - btrfs: fix missing file extent item for hole after ranged fsync + - btrfs: unset reloc control if we fail to recover + - btrfs: fix missing semaphore unlock in btrfs_sync_file + - btrfs: use nofs allocations for running delayed items + - remoteproc: qcom_q6v5_mss: Don't reassign mpss region on shutdown + - remoteproc: qcom_q6v5_mss: Reload the mba region on coredump + - remoteproc: Fix NULL pointer dereference in rproc_virtio_notify + - crypto: rng - Fix a refcounting bug in crypto_rng_reset() + - crypto: mxs-dcp - fix scatterlist linearization for hash + - erofs: correct the remaining shrink objects + - io_uring: honor original task RLIMIT_FSIZE + - mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions + - powerpc/pseries: Drop pointless static qualifier in vpa_debugfs_init() + - tools: gpio: Fix out-of-tree build regression + - net: qualcomm: rmnet: Allow configuration updates to existing devices + - arm64: dts: allwinner: h6: Fix PMU compatible + - sched/core: Remove duplicate assignment in sched_tick_remote() + - arm64: dts: allwinner: h5: Fix PMU compatible + - mm, memcg: do not high throttle allocators based on wraparound + - dm writecache: add cond_resched to avoid CPU hangs + - dm integrity: fix a crash with unusually large tag size + - dm verity fec: fix memory leak in verity_fec_dtr + - dm clone: Add overflow check for number of regions + - dm clone metadata: Fix return type of dm_clone_nr_of_hydrated_regions() + - XArray: Fix xas_pause for large multi-index entries + - xarray: Fix early termination of xas_for_each_marked + - crypto: caam/qi2 - fix chacha20 data size error + - crypto: caam - update xts sector size for large input length + - crypto: ccree - protect against empty or NULL scatterlists + - crypto: ccree - only try to map auth tag if needed + - crypto: ccree - dec auth tag size from cryptlen map + - scsi: zfcp: fix missing erp_lock in port recovery trigger for point-to-point + - scsi: ufs: fix Auto-Hibern8 error detection + - ARM: dts: exynos: Fix polarity of the LCD SPI bus on UniversalC210 board + - arm64: dts: ti: k3-am65: Add clocks to dwc3 nodes + - arm64: armv8_deprecated: Fix undef_hook mask for thumb setend + - selftests: vm: drop dependencies on page flags from mlock2 tests + - selftests/vm: fix map_hugetlb length used for testing read and write + - selftests/powerpc: Add tlbie_test in .gitignore + - vfio: platform: Switch to platform_get_irq_optional() + - drm/i915/gem: Flush all the reloc_gpu batch + - drm/etnaviv: rework perfmon query infrastructure + - drm: Remove PageReserved manipulation from drm_pci_alloc + - drm/amdgpu/powerplay: using the FCLK DPM table to set the MCLK + - drm/amdgpu: unify fw_write_wait for new gfx9 asics + - powerpc/pseries: Avoid NULL pointer dereference when drmem is unavailable + - nfsd: fsnotify on rmdir under nfsd/clients/ + - NFS: Fix use-after-free issues in nfs_pageio_add_request() + - NFS: Fix a page leak in nfs_destroy_unlinked_subrequests() + - ext4: fix a data race at inode->i_blocks + - fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once() + - ocfs2: no need try to truncate file beyond i_size + - perf tools: Support Python 3.8+ in Makefile + - s390/diag: fix display of diagnose call statistics + - Input: i8042 - add Acer Aspire 5738z to nomux list + - ftrace/kprobe: Show the maxactive number on kprobe_events + - clk: ingenic/jz4770: Exit with error if CGU init failed + - clk: ingenic/TCU: Fix round_rate returning error + - kmod: make request_module() return an error when autoloading is disabled + - cpufreq: powernv: Fix use-after-free + - hfsplus: fix crash and filesystem corruption when deleting files + - ipmi: fix hung processes in __get_guid() + - xen/blkfront: fix memory allocation flags in blkfront_setup_indirect() + - powerpc/64/tm: Don't let userspace set regs->trap via sigreturn + - powerpc/fsl_booke: Avoid creating duplicate tlb1 entry + - powerpc/hash64/devmap: Use H_PAGE_THP_HUGE when setting up huge devmap PTE + entries + - powerpc/xive: Use XIVE_BAD_IRQ instead of zero to catch non configured IPIs + - powerpc/64: Setup a paca before parsing device tree etc. + - powerpc/xive: Fix xmon support on the PowerNV platform + - powerpc/kprobes: Ignore traps that happened in real mode + - powerpc/64: Prevent stack protection in early boot + - scsi: mpt3sas: Fix kernel panic observed on soft HBA unplug + - powerpc: Make setjmp/longjmp signature standard + - arm64: Always force a branch protection mode when the compiler has one + - dm zoned: remove duplicate nr_rnd_zones increase in dmz_init_zone() + - dm clone: replace spin_lock_irqsave with spin_lock_irq + - dm clone: Fix handling of partial region discards + - dm clone: Add missing casts to prevent overflows and data corruption + - Revert "drm/dp_mst: Remove VCPI while disabling topology mgr" + - drm/dp_mst: Fix clearing payload state on topology disable + - drm/amdgpu: fix gfx hang during suspend with video playback (v2) + - drm/i915/icl+: Don't enable DDI IO power on a TypeC port in TBT mode + - powerpc/kasan: Fix kasan_remap_early_shadow_ro() + - mmc: sdhci: Convert sdhci_set_timeout_irq() to non-static + - mmc: sdhci: Refactor sdhci_set_timeout() + - bpf: Fix tnum constraints for 32-bit comparisons + - mfd: dln2: Fix sanity checking for endpoints + - efi/x86: Fix the deletion of variables in mixed mode + - ASoC: stm32: sai: Add missing cleanup + - Linux 5.4.33 + - SUNRPC: fix krb5p mount to provide large enough buffer in rq_rcvsize + * Panic on suspend/resume Kernel panic - not syncing: stack-protector: Kernel + stack is corrupted in: sata_pmp_eh_recover+0xa2b/0xa40 (LP: #1821434) // + Focal update: v5.4.33 upstream stable release (LP: #1873481) + - libata: Return correct status in sata_pmp_eh_recover_pm() when + ATA_DFLAG_DETACH is set + * Focal update: v5.4.32 upstream stable release (LP: #1873292) + - cxgb4: fix MPS index overwrite when setting MAC address + - ipv6: don't auto-add link-local address to lag ports + - net: dsa: bcm_sf2: Do not register slave MDIO bus with OF + - net: dsa: bcm_sf2: Ensure correct sub-node is parsed + - net: dsa: mt7530: fix null pointer dereferencing in port5 setup + - net: phy: micrel: kszphy_resume(): add delay after genphy_resume() before + accessing PHY registers + - net_sched: add a temporary refcnt for struct tcindex_data + - net_sched: fix a missing refcnt in tcindex_init() + - net: stmmac: dwmac1000: fix out-of-bounds mac address reg setting + - tun: Don't put_page() for all negative return values from XDP program + - mlxsw: spectrum_flower: Do not stop at FLOW_ACTION_VLAN_MANGLE + - r8169: change back SG and TSO to be disabled by default + - s390: prevent leaking kernel address in BEAR + - random: always use batched entropy for get_random_u{32,64} + - usb: dwc3: gadget: Wrap around when skip TRBs + - uapi: rename ext2_swab() to swab() and share globally in swab.h + - slub: improve bit diffusion for freelist ptr obfuscation + - tools/accounting/getdelays.c: fix netlink attribute length + - hwrng: imx-rngc - fix an error path + - ACPI: PM: Add acpi_[un]register_wakeup_handler() + - platform/x86: intel_int0002_vgpio: Use acpi_register_wakeup_handler() + - ASoC: jz4740-i2s: Fix divider written at incorrect offset in register + - IB/hfi1: Call kobject_put() when kobject_init_and_add() fails + - IB/hfi1: Fix memory leaks in sysfs registration and unregistration + - IB/mlx5: Replace tunnel mpls capability bits for tunnel_offloads + - ARM: imx: Enable ARM_ERRATA_814220 for i.MX6UL and i.MX7D + - ARM: imx: only select ARM_ERRATA_814220 for ARMv7-A + - ceph: remove the extra slashes in the server path + - ceph: canonicalize server path in place + - include/uapi/linux/swab.h: fix userspace breakage, use __BITS_PER_LONG for + swap + - RDMA/ucma: Put a lock around every call to the rdma_cm layer + - RDMA/cma: Teach lockdep about the order of rtnl and lock + - RDMA/siw: Fix passive connection establishment + - Bluetooth: RFCOMM: fix ODEBUG bug in rfcomm_dev_ioctl + - RDMA/cm: Update num_paths in cma_resolve_iboe_route error flow + - blk-mq: Keep set->nr_hw_queues and set->map[].nr_queues in sync + - fbcon: fix null-ptr-deref in fbcon_switch + - iommu/vt-d: Allow devices with RMRRs to use identity domain + - Linux 5.4.32 + * Focal update: v5.4.31 upstream stable release (LP: #1871651) + - nvme-rdma: Avoid double freeing of async event data + - kconfig: introduce m32-flag and m64-flag + - drm/amd/display: Add link_rate quirk for Apple 15" MBP 2017 + - drm/bochs: downgrade pci_request_region failure from error to warning + - initramfs: restore default compression behavior + - drm/amdgpu: fix typo for vcn1 idle check + - [Packaging] add libcap-dev dependency + - tools/power turbostat: Fix gcc build warnings + - tools/power turbostat: Fix missing SYS_LPI counter on some Chromebooks + - tools/power turbostat: Fix 32-bit capabilities warning + - net/mlx5e: kTLS, Fix TCP seq off-by-1 issue in TX resync flow + - XArray: Fix xa_find_next for large multi-index entries + - padata: fix uninitialized return value in padata_replace() + - brcmfmac: abort and release host after error + - misc: rtsx: set correct pcr_ops for rts522A + - misc: pci_endpoint_test: Fix to support > 10 pci-endpoint-test devices + - misc: pci_endpoint_test: Avoid using module parameter to determine irqtype + - PCI: sysfs: Revert "rescan" file renames + - coresight: do not use the BIT() macro in the UAPI header + - mei: me: add cedar fork device ids + - nvmem: check for NULL reg_read and reg_write before dereferencing + - extcon: axp288: Add wakeup support + - power: supply: axp288_charger: Add special handling for HP Pavilion x2 10 + - Revert "dm: always call blk_queue_split() in dm_process_bio()" + - ALSA: hda/ca0132 - Add Recon3Di quirk to handle integrated sound on EVGA X99 + Classified motherboard + - soc: mediatek: knows_txdone needs to be set in Mediatek CMDQ helper + - net/mlx5e: kTLS, Fix wrong value in record tracker enum + - iwlwifi: consider HE capability when setting LDPC + - iwlwifi: yoyo: don't add TLV offset when reading FIFOs + - iwlwifi: dbg: don't abort if sending DBGC_SUSPEND_RESUME fails + - rxrpc: Fix sendmsg(MSG_WAITALL) handling + - IB/hfi1: Ensure pq is not left on waitlist + - tcp: fix TFO SYNACK undo to avoid double-timestamp-undo + - watchdog: iTCO_wdt: Export vendorsupport + - watchdog: iTCO_wdt: Make ICH_RES_IO_SMI optional + - i2c: i801: Do not add ICH_RES_IO_SMI for the iTCO_wdt device + - net: Fix Tx hash bound checking + - padata: always acquire cpu_hotplug_lock before pinst->lock + - mm: mempolicy: require at least one nodeid for MPOL_PREFERRED + - Linux 5.4.31 + * Add hw timestamps to received skbs in peak_canfd (LP: #1874124) + - can: peak_canfd: provide hw timestamps in rx skbs + * kselftest: seccomp kill_after_ptrace() timeout (LP: #1872047) + - SAUCE: kselftest/runner: allow to properly deliver signals to tests + + [ Ubuntu: 5.4.0-29.33 ] + + * focal/linux: 5.4.0-29.33 -proposed tracker (LP: #1875858) + * Packaging resync (LP: #1786013) + - update dkms package versions + * Add signed modules for the 435 NVIDIA driver (LP: #1875888) + - [Packaging] NVIDIA -- add signed modules for the 435 NVIDIA driver + * built-using constraints preventing uploads (LP: #1875601) + - temporarily drop Built-Using data + + [ Ubuntu: 5.4.0-28.32 ] + + * CVE-2020-11884 + - SAUCE: s390/mm: fix page table upgrade vs 2ndary address mode accesses + + [ Ubuntu: 5.4.0-26.30 ] + + * focal/linux: 5.4.0-26.30 -proposed tracker (LP: #1873882) + * Packaging resync (LP: #1786013) + - update dkms package versions + * swap storms kills interactive use (LP: #1861359) + - SAUCE: drm/i915: prevent direct writeback from the shrinker + * 5.4.0-24.28 does not seem to apply rtprio, whereas -21 does. (LP: #1873315) + - [Config] lowlatency: turn off RT_GROUP_SCHED + * [RTL810xE] No ethernet connection (LP: #1871182) + - net: phy: realtek: fix handling of RTL8105e-integrated PHY + + [ Ubuntu: 5.4.0-25.29 ] + + * focal/linux: 5.4.0-25.29 -proposed tracker (LP: #1873459) + * [TGL] VMD support in TGL (LP: #1855954) + - PCI: vmd: Add bus 224-255 restriction decode + - PCI: vmd: Add device id for VMD device 8086:9A0B + * Can not see the storage with Intel RAID On mode enabled on Intel Comet Lake + (LP: #1871812) + - ahci: Add Intel Comet Lake PCH RAID PCI ID + + -- Stefan Bader Tue, 05 May 2020 17:10:19 +0200 + +linux-oracle (5.4.0-1009.9) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1009.9 -proposed tracker (LP: #1871937) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to 5.4.0-24.28 + - [Config] CONFIG_RT_GROUP_SCHED=y + + [ Ubuntu: 5.4.0-24.28 ] + + * focal/linux: 5.4.0-24.28 -proposed tracker (LP: #1871939) + * getitimer returns it_value=0 erroneously (LP: #1349028) + - [Config] CONTEXT_TRACKING_FORCE policy should be unset + * 12d1:1038 Dual-Role OTG device on non-HNP port - unable to enumerate USB + device on port 1 (LP: #1047527) + - [Config] USB_OTG_FSM policy not needed + * Add DCPD backlight support for HP CML system (LP: #1871589) + - SAUCE: drm/i915: Force DPCD backlight mode for HP CML 2020 system + * Backlight brightness cannot be adjusted using keys (LP: #1860303) + - SAUCE drm/i915: Force DPCD backlight mode for HP Spectre x360 Convertible + 13t-aw100 + * CVE-2020-11494 + - slcan: Don't transmit uninitialized stack data in padding + * Ubuntu Kernel Support for OpenPOWER NV Secure & Trusted Boot (LP: #1866909) + - powerpc: Detect the secure boot mode of the system + - powerpc/ima: Add support to initialize ima policy rules + - powerpc: Detect the trusted boot state of the system + - powerpc/ima: Define trusted boot policy + - ima: Make process_buffer_measurement() generic + - certs: Add wrapper function to check blacklisted binary hash + - ima: Check against blacklisted hashes for files with modsig + - powerpc/ima: Update ima arch policy to check for blacklist + - powerpc/ima: Indicate kernel modules appended signatures are enforced + - powerpc/powernv: Add OPAL API interface to access secure variable + - powerpc: expose secure variables to userspace via sysfs + - x86/efi: move common keyring handler functions to new file + - powerpc: Load firmware trusted keys/hashes into kernel keyring + - x86/efi: remove unused variables + * [roce-0227]sync mainline kernel 5.6rc3 roce patchset into ubuntu HWE kernel + branch (LP: #1864950) + - RDMA/hns: Cleanups of magic numbers + - RDMA/hns: Optimize eqe buffer allocation flow + - RDMA/hns: Add the workqueue framework for flush cqe handler + - RDMA/hns: Delayed flush cqe process with workqueue + - RDMA/hns: fix spelling mistake: "attatch" -> "attach" + - RDMA/hns: Initialize all fields of doorbells to zero + - RDMA/hns: Treat revision HIP08_A as a special case + - RDMA/hns: Use flush framework for the case in aeq + - RDMA/hns: Stop doorbell update while qp state error + - RDMA/hns: Optimize qp destroy flow + - RDMA/hns: Optimize qp context create and destroy flow + - RDMA/hns: Optimize qp number assign flow + - RDMA/hns: Optimize qp buffer allocation flow + - RDMA/hns: Optimize qp param setup flow + - RDMA/hns: Optimize kernel qp wrid allocation flow + - RDMA/hns: Optimize qp doorbell allocation flow + - RDMA/hns: Check if depth of qp is 0 before configure + * [hns3-0316]sync mainline kernel 5.6rc4 hns3 patchset into ubuntu HWE kernel + branch (LP: #1867586) + - net: hns3: modify an unsuitable print when setting unknown duplex to fibre + - net: hns3: add enabled TC numbers and DWRR weight info in debugfs + - net: hns3: add support for dump MAC ID and loopback status in debugfs + - net: hns3: add missing help info for QS shaper in debugfs + - net: hns3: fix some mixed type assignment + - net: hns3: rename macro HCLGE_MAX_NCL_CONFIG_LENGTH + - net: hns3: remove an unnecessary resetting check in + hclge_handle_hw_ras_error() + - net: hns3: delete some reduandant code + - net: hns3: add a check before PF inform VF to reset + - net: hns3: print out status register when VF receives unknown source + interrupt + - net: hns3: print out command code when dump fails in debugfs + - net: hns3: synchronize some print relating to reset issue + - net: hns3: delete unnecessary logs after kzalloc fails + * [SRU][F/U/OEM-5.6] UBUNTU: SAUCE: Fix amdgpu hang during acpi event + (LP: #1871316) + - SAUCE: drm/amdgpu: Fix oops when pp_funcs is unset in ACPI event + * alsa: make the dmic detection align to the mainline kernel-5.6 + (LP: #1871284) + - ALSA: hda: add Intel DSP configuration / probe code + - ALSA: hda: fix intel DSP config + - ALSA: hda: Allow non-Intel device probe gracefully + - ALSA: hda: More constifications + - ALSA: hda: Rename back to dmic_detect option + - [Config] SND_INTEL_DSP_CONFIG=m + * add_key05 from ubuntu_ltp_syscalls failed (LP: #1869644) + - KEYS: reaching the keys quotas correctly + * Fix authentication fail on Realtek WiFi 8723de (LP: #1871300) + - SAUCE: rtw88: No retry and report for auth and assoc + - SAUCE: rtw88: fix rate for a while after being connected + - SAUCE: rtw88: Move driver IQK to set channel before association for 11N chip + * Add Mute LED support for an HP laptop (LP: #1871090) + - ALSA: hda/realtek: Enable mute LED on an HP system + * dscr_sysfs_test / futex_bench / tm-unavailable in powerpc from + ubuntu_kernel_selftests timeout on PowerPC nodes with B-5.3 (LP: #1864642) + - Revert "UBUNTU: SAUCE: selftests/powerpc -- Disable timeout for benchmark + and tm tests" + - selftests/powerpc: Turn off timeout setting for benchmarks, dscr, signal, tm + * Update 20.0.4 NVMe Core, NVMe FC Transport and nvme-cli for Broadcom Emulex + lpfc driver 12.6.0.x dependencies (LP: #1856340) + - nvme-fc: Sync nvme-fc header to FC-NVME-2 + - nvme-fc and nvmet-fc: sync with FC-NVME-2 header changes + - nvme-fc: Set new cmd set indicator in nvme-fc cmnd iu + - nvme-fc: clarify error messages + - nvme-fc: ensure association_id is cleared regardless of a Disconnect LS + - nvme: resync include/linux/nvme.h with nvmecli + - nvme: Fix parsing of ANA log page + * Update Broadcom Emulex lpfc driver in 5.4 to 12.6.0.x from 5.5 + (LP: #1855303) + - scsi: lpfc: Fix pt2pt discovery on SLI3 HBAs + - scsi: lpfc: Fix premature re-enabling of interrupts in lpfc_sli_host_down + - scsi: lpfc: Fix miss of register read failure check + - scsi: lpfc: Fix NVME io abort failures causing hangs + - scsi: lpfc: Fix device recovery errors after PLOGI failures + - scsi: lpfc: Fix GPF on scsi command completion + - scsi: lpfc: Fix NVMe ABTS in response to receiving an ABTS + - scsi: lpfc: Fix coverity errors on NULL pointer checks + - scsi: lpfc: Fix host hang at boot or slow boot + - scsi: lpfc: Update async event logging + - scsi: lpfc: Complete removal of FCoE T10 PI support on SLI-4 adapters + - scsi: lpfc: cleanup: remove unused fcp_txcmlpq_cnt + - scsi: lpfc: Update lpfc version to 12.4.0.1 + - scsi: lpfc: Make function lpfc_defer_pt2pt_acc static + - scsi: lpfc: fix lpfc_nvmet_mrq to be bound by hdw queue count + - scsi: lpfc: Fix reporting of read-only fw error errors + - scsi: lpfc: Fix lockdep errors in sli_ringtx_put + - scsi: lpfc: fix coverity error of dereference after null check + - scsi: lpfc: Slight fast-path performance optimizations + - scsi: lpfc: Remove lock contention target write path + - scsi: lpfc: Revise interrupt coalescing for missing scenarios + - scsi: lpfc: Make FW logging dynamically configurable + - scsi: lpfc: Add log macros to allow print by serverity or verbosity setting + - scsi: lpfc: Add FA-WWN Async Event reporting + - scsi: lpfc: Add FC-AL support to lpe32000 models + - scsi: lpfc: Add additional discovery log messages + - scsi: lpfc: Update lpfc version to 12.6.0.0 + - scsi: lpfc: lpfc_attr: Fix Use plain integer as NULL pointer + - scsi: lpfc: lpfc_nvmet: Fix Use plain integer as NULL pointer + - scsi: lpfc: fix build error of lpfc_debugfs.c for vfree/vmalloc + - scsi: lpfc: fix spelling error in MAGIC_NUMER_xxx + - scsi: lpfc: Fix NULL check before mempool_destroy is not needed + - scsi: lpfc: Make lpfc_debugfs_ras_log_data static + - scsi: lpfc: Fix configuration of BB credit recovery in service parameters + - scsi: lpfc: Fix kernel crash at lpfc_nvme_info_show during remote port + bounce + - scsi: lpfc: Fix dynamic fw log enablement check + - scsi: lpfc: Sync with FC-NVMe-2 SLER change to require Conf with SLER + - scsi: lpfc: Clarify FAWNN error message + - scsi: lpfc: Add registration for CPU Offline/Online events + - scsi: lpfc: Change default IRQ model on AMD architectures + - scsi: lpfc: Add enablement of multiple adapter dumps + - scsi: lpfc: Update lpfc version to 12.6.0.1 + - scsi: lpfc: Fix a kernel warning triggered by lpfc_sli4_enable_intr() + - scsi: lpfc: Fix lpfc_cpumask_of_node_init() + - scsi: lpfc: fix inlining of lpfc_sli4_cleanup_poll_list() + - scsi: lpfc: Initialize cpu_map for not present cpus + - scsi: lpfc: revise nvme max queues to be hdwq count + - scsi: lpfc: Update lpfc version to 12.6.0.2 + - scsi: lpfc: size cpu map by last cpu id set + - scsi: lpfc: Fix incomplete NVME discovery when target + - scsi: lpfc: Fix missing check for CSF in Write Object Mbox Rsp + - scsi: lpfc: Fix Fabric hostname registration if system hostname changes + - scsi: lpfc: Fix ras_log via debugfs + - scsi: lpfc: Fix disablement of FC-AL on lpe35000 models + - scsi: lpfc: Fix unmap of dpp bars affecting next driver load + - scsi: lpfc: Fix MDS Latency Diagnostics Err-drop rates + - scsi: lpfc: Fix improper flag check for IO type + - scsi: lpfc: Update lpfc version to 12.6.0.3 + - scsi: lpfc: Fix RQ buffer leakage when no IOCBs available + - scsi: lpfc: Fix lpfc_io_buf resource leak in lpfc_get_scsi_buf_s4 error path + - scsi: lpfc: Fix broken Credit Recovery after driver load + - scsi: lpfc: Fix registration of ELS type support in fdmi + - scsi: lpfc: Fix release of hwq to clear the eq relationship + - scsi: lpfc: Fix compiler warning on frame size + - scsi: lpfc: Fix coverity errors in fmdi attribute handling + - scsi: lpfc: Remove handler for obsolete ELS - Read Port Status (RPS) + - scsi: lpfc: Clean up hba max_lun_queue_depth checks + - scsi: lpfc: Update lpfc version to 12.6.0.4 + - scsi: lpfc: Copyright updates for 12.6.0.4 patches + - scsi: fc: Update Descriptor definition and add RDF and Link Integrity FPINs + - scsi: lpfc: add RDF registration and Link Integrity FPIN logging + * lockdown on power (LP: #1855668) // Ubuntu Kernel Support for OpenPOWER NV + Secure & Trusted Boot (LP: #1866909) + - [Config] Enable configs for OpenPOWER NV Secure & Trusted Boot + * lockdown on power (LP: #1855668) + - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode + * Focal update: v5.4.30 upstream stable release (LP: #1870571) + - mac80211: Check port authorization in the ieee80211_tx_dequeue() case + - mac80211: fix authentication with iwlwifi/mvm + - serial: sprd: Fix a dereference warning + - vt: selection, introduce vc_is_sel + - vt: ioctl, switch VT_IS_IN_USE and VT_BUSY to inlines + - vt: switch vt_dont_switch to bool + - vt: vt_ioctl: remove unnecessary console allocation checks + - vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console + - vt: vt_ioctl: fix use-after-free in vt_in_use() + - platform/x86: pmc_atom: Add Lex 2I385SW to critclk_systems DMI table + - bpf: Explicitly memset the bpf_attr structure + - bpf: Explicitly memset some bpf info structures declared on the stack + - gpiolib: acpi: Add quirk to ignore EC wakeups on HP x2 10 CHT + AXP288 model + - net: ks8851-ml: Fix IO operations, again + - clk: imx: Align imx sc clock msg structs to 4 + - clk: imx: Align imx sc clock parent msg structs to 4 + - clk: ti: am43xx: Fix clock parent for RTC clock + - libceph: fix alloc_msg_with_page_vector() memory leaks + - arm64: alternative: fix build with clang integrated assembler + - perf map: Fix off by one in strncpy() size argument + - ARM: dts: oxnas: Fix clear-mask property + - ARM: bcm2835-rpi-zero-w: Add missing pinctrl name + - ARM: dts: imx6: phycore-som: fix arm and soc minimum voltage + - ARM: dts: N900: fix onenand timings + - ARM: dts: sun8i: r40: Move AHCI device node based on address order + - arm64: dts: ls1043a-rdb: correct RGMII delay mode to rgmii-id + - arm64: dts: ls1046ardb: set RGMII interfaces to RGMII_ID mode + - Linux 5.4.30 + * Miscellaneous Ubuntu changes + - [Config] CONFIG_RT_GROUP_SCHED=y + - SAUCE: powerpc/ima: require IMA module signatures only if MODULE_SIG is not + enabled + - SAUCE: Update aufs to 5.4.3 20200302 + - SAUCE: drm/amdgpu: Remove missing firmware files from modinfo + - SAUCE: drm/i915: Fix ref->mutex deadlock in i915_active_wait() + - SAUCE: drm/i915: Synchronize active and retire callbacks + - SAUCE: apparmor: add a valid state flags check + - SAUCE: aapparmor: add consistency check between state and dfa diff encode + flags + - SAUCE: aapparmor: remove useless aafs_create_symlink + - SAUCE: aapparmor: fail unpack if profile mode is unknown + - SAUCE: apparmor: ensure that dfa state tables have entries + - SAUCE: apparmor: fix potential label refcnt leak in aa_change_profile + - SAUCE: security/apparmor/label.c: Clean code by removing redundant + instructions + - [Config] Remove PCIEASPM_DEBUG from annotations + - [Config] Remove HEADER_TEST from annotations + - SAUCE: selftests/seccomp: allow clock_nanosleep instead of nanosleep + - [Debian] Allow building linux-libc-dev from linux-riscv + - [Packaging] Remove riscv64 packaging from master kernel + - [Config] Remove CONFIG_SND_HDA_INTEL_DETECT_DMIC from annotations + * Miscellaneous upstream changes + - net/bpfilter: remove superfluous testing message + - apparmor: increase left match history buffer size + + [ Ubuntu: 5.4.0-23.27 ] + + * Miscellaneous Ubuntu changes + - [Packaging] Enable riscv64 build + + -- Seth Forshee Fri, 10 Apr 2020 14:58:55 -0500 + +linux-oracle (5.4.0-1008.8) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1008.8 -proposed tracker (LP: #1870501) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to 5.4.0-22.26 + + [ Ubuntu: 5.4.0-22.26 ] + + * focal/linux: 5.4.0-22.26 -proposed tracker (LP: #1870502) + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update helper scripts + - update dkms package versions + * [SFC-0316]sync mainline kernel 5.7rc1 SFC patchset into ubuntu HWE kernel + branch (LP: #1867588) + - spi: Allow SPI controller override device buswidth + - spi: HiSilicon v3xx: Properly set CMD_CONFIG for Dual/Quad modes + - spi: HiSilicon v3xx: Use DMI quirk to set controller buswidth override bits + * [hns3-0316]sync mainline kernel 5.6rc4 hns3 patchset into ubuntu HWE kernel + branch (LP: #1867586) + - net: hns3: fix VF VLAN table entries inconsistent issue + - net: hns3: fix RMW issue for VLAN filter switch + - net: hns3: clear port base VLAN when unload PF + * [sas-0316]sync mainline kernel 5.6rc1 roce patchset into ubuntu HWE kernel + branch (LP: #1867587) + - scsi: hisi_sas: use threaded irq to process CQ interrupts + - scsi: hisi_sas: replace spin_lock_irqsave/spin_unlock_restore with + spin_lock/spin_unlock + - scsi: hisi_sas: Replace magic number when handle channel interrupt + - scsi: hisi_sas: Modify the file permissions of trigger_dump to write only + - scsi: hisi_sas: Add prints for v3 hw interrupt converge and automatic + affinity + - scsi: hisi_sas: Rename hisi_sas_cq.pci_irq_mask + * Revert "nvme_fc: add module to ops template to allow module references" + (LP: #1869947) + - SAUCE: Revert "nvme_fc: add module to ops template to allow module + references" + * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570) + - Revert "UBUNTU: SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th" + - SAUCE: e1000e: bump up timeout to wait when ME un-configure ULP mode + * Focal update: v5.4.29 upstream stable release (LP: #1870142) + - mmc: core: Allow host controllers to require R1B for CMD6 + - mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard + - mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command + - mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY + - mmc: sdhci-tegra: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY + - ACPI: PM: s2idle: Rework ACPI events synchronization + - cxgb4: fix throughput drop during Tx backpressure + - cxgb4: fix Txq restart check during backpressure + - geneve: move debug check after netdev unregister + - hsr: fix general protection fault in hsr_addr_is_self() + - ipv4: fix a RCU-list lock in inet_dump_fib() + - macsec: restrict to ethernet devices + - mlxsw: pci: Only issue reset when system is ready + - mlxsw: spectrum_mr: Fix list iteration in error path + - net/bpfilter: fix dprintf usage for /dev/kmsg + - net: cbs: Fix software cbs to consider packet sending time + - net: dsa: Fix duplicate frames flooded by learning + - net: dsa: mt7530: Change the LINK bit to reflect the link status + - net: dsa: tag_8021q: replace dsa_8021q_remove_header with __skb_vlan_pop + - net: ena: Add PCI shutdown handler to allow safe kexec + - net: mvneta: Fix the case where the last poll did not process all rx + - net/packet: tpacket_rcv: avoid a producer race condition + - net: phy: dp83867: w/a for fld detect threshold bootstrapping issue + - net: phy: mdio-bcm-unimac: Fix clock handling + - net: phy: mdio-mux-bcm-iproc: check clk_prepare_enable() return value + - net: qmi_wwan: add support for ASKEY WWHC050 + - net/sched: act_ct: Fix leak of ct zone template on replace + - net_sched: cls_route: remove the right filter from hashtable + - net_sched: hold rtnl lock in tcindex_partial_destroy_work() + - net_sched: keep alloc_hash updated after hash allocation + - net: stmmac: dwmac-rk: fix error path in rk_gmac_probe + - NFC: fdp: Fix a signedness bug in fdp_nci_send_patch() + - r8169: re-enable MSI on RTL8168c + - slcan: not call free_netdev before rtnl_unlock in slcan_open + - tcp: also NULL skb->dev when copy was needed + - tcp: ensure skb->dev is NULL before leaving TCP stack + - tcp: repair: fix TCP_QUEUE_SEQ implementation + - vxlan: check return value of gro_cells_init() + - bnxt_en: Fix Priority Bytes and Packets counters in ethtool -S. + - bnxt_en: fix memory leaks in bnxt_dcbnl_ieee_getets() + - bnxt_en: Return error if bnxt_alloc_ctx_mem() fails. + - bnxt_en: Free context memory after disabling PCI in probe error path. + - bnxt_en: Reset rings if ring reservation fails during open() + - net: ip_gre: Separate ERSPAN newlink / changelink callbacks + - net: ip_gre: Accept IFLA_INFO_DATA-less configuration + - hsr: use rcu_read_lock() in hsr_get_node_{list/status}() + - hsr: add restart routine into hsr_get_node_list() + - hsr: set .netnsok flag + - net/mlx5: DR, Fix postsend actions write length + - net/mlx5e: Enhance ICOSQ WQE info fields + - net/mlx5e: Fix missing reset of SW metadata in Striding RQ reset + - net/mlx5e: Fix ICOSQ recovery flow with Striding RQ + - net/mlx5e: Do not recover from a non-fatal syndrome + - cgroup-v1: cgroup_pidlist_next should update position index + - nfs: add minor version to nfs_server_key for fscache + - cpupower: avoid multiple definition with gcc -fno-common + - drivers/of/of_mdio.c:fix of_mdiobus_register() + - cgroup1: don't call release_agent when it is "" + - [Config] updateconfigs for DPAA_ERRATUM_A050385 + - dt-bindings: net: FMan erratum A050385 + - arm64: dts: ls1043a: FMan erratum A050385 + - fsl/fman: detect FMan erratum A050385 + - drm/amd/display: update soc bb for nv14 + - drm/amdgpu: correct ROM_INDEX/DATA offset for VEGA20 + - drm/exynos: Fix cleanup of IOMMU related objects + - iommu/vt-d: Silence RCU-list debugging warnings + - s390/qeth: don't reset default_out_queue + - s390/qeth: handle error when backing RX buffer + - scsi: ipr: Fix softlockup when rescanning devices in petitboot + - mac80211: Do not send mesh HWMP PREQ if HWMP is disabled + - dpaa_eth: Remove unnecessary boolean expression in dpaa_get_headroom + - sxgbe: Fix off by one in samsung driver strncpy size arg + - net: hns3: fix "tc qdisc del" failed issue + - iommu/vt-d: Fix debugfs register reads + - iommu/vt-d: Populate debugfs if IOMMUs are detected + - iwlwifi: mvm: fix non-ACPI function + - i2c: hix5hd2: add missed clk_disable_unprepare in remove + - Input: raydium_i2c_ts - fix error codes in raydium_i2c_boot_trigger() + - Input: fix stale timestamp on key autorepeat events + - Input: synaptics - enable RMI on HP Envy 13-ad105ng + - Input: avoid BIT() macro usage in the serio.h UAPI header + - IB/rdmavt: Free kernel completion queue when done + - RDMA/core: Fix missing error check on dev_set_name() + - gpiolib: Fix irq_disable() semantics + - RDMA/nl: Do not permit empty devices names during RDMA_NLDEV_CMD_NEWLINK/SET + - RDMA/mad: Do not crash if the rdma device does not have a umad interface + - ceph: check POOL_FLAG_FULL/NEARFULL in addition to OSDMAP_FULL/NEARFULL + - ceph: fix memory leak in ceph_cleanup_snapid_map() + - ARM: dts: dra7: Add bus_dma_limit for L3 bus + - ARM: dts: omap5: Add bus_dma_limit for L3 bus + - x86/ioremap: Fix CONFIG_EFI=n build + - perf probe: Fix to delete multiple probe event + - perf probe: Do not depend on dwfl_module_addrsym() + - rtlwifi: rtl8188ee: Fix regression due to commit d1d1a96bdb44 + - tools: Let O= makes handle a relative path with -C option + - scripts/dtc: Remove redundant YYLOC global declaration + - scsi: sd: Fix optimal I/O size for devices that change reported values + - nl80211: fix NL80211_ATTR_CHANNEL_WIDTH attribute type + - mac80211: drop data frames without key on encrypted links + - mac80211: mark station unauthorized before key removal + - mm/swapfile.c: move inode_lock out of claim_swapfile + - drivers/base/memory.c: indicate all memory blocks as removable + - mm/sparse: fix kernel crash with pfn_section_valid check + - mm: fork: fix kernel_stack memcg stats for various stack implementations + - gpiolib: acpi: Correct comment for HP x2 10 honor_wakeup quirk + - gpiolib: acpi: Rework honor_wakeup option into an ignore_wake option + - gpiolib: acpi: Add quirk to ignore EC wakeups on HP x2 10 BYT + AXP288 model + - bpf: Fix cgroup ref leak in cgroup_bpf_inherit on out-of-memory + - RDMA/core: Ensure security pkey modify is not lost + - afs: Fix handling of an abort from a service handler + - genirq: Fix reference leaks on irq affinity notifiers + - xfrm: handle NETDEV_UNREGISTER for xfrm device + - vti[6]: fix packet tx through bpf_redirect() in XinY cases + - RDMA/mlx5: Fix the number of hwcounters of a dynamic counter + - RDMA/mlx5: Fix access to wrong pointer while performing flush due to error + - RDMA/mlx5: Block delay drop to unprivileged users + - xfrm: fix uctx len check in verify_sec_ctx_len + - xfrm: add the missing verify_sec_ctx_len check in xfrm_add_acquire + - xfrm: policy: Fix doulbe free in xfrm_policy_timer + - afs: Fix client call Rx-phase signal handling + - afs: Fix some tracing details + - afs: Fix unpinned address list during probing + - ieee80211: fix HE SPR size calculation + - mac80211: set IEEE80211_TX_CTRL_PORT_CTRL_PROTO for nl80211 TX + - netfilter: flowtable: reload ip{v6}h in nf_flow_tuple_ip{v6} + - netfilter: nft_fwd_netdev: validate family and chain type + - netfilter: nft_fwd_netdev: allow to redirect to ifb via ingress + - i2c: nvidia-gpu: Handle timeout correctly in gpu_i2c_check_status() + - bpf, x32: Fix bug with JMP32 JSET BPF_X checking upper bits + - bpf: Initialize storage pointers to NULL to prevent freeing garbage pointer + - bpf/btf: Fix BTF verification of enum members in struct/union + - bpf, sockmap: Remove bucket->lock from sock_{hash|map}_free + - ARM: dts: sun8i-a83t-tbs-a711: Fix USB OTG mode detection + - vti6: Fix memory leak of skb if input policy check fails + - r8169: fix PHY driver check on platforms w/o module softdeps + - clocksource/drivers/hyper-v: Untangle stimers and timesync from clocksources + - USB: serial: option: add support for ASKEY WWHC050 + - USB: serial: option: add BroadMobi BM806U + - USB: serial: option: add Wistron Neweb D19Q1 + - USB: cdc-acm: restore capability check order + - USB: serial: io_edgeport: fix slab-out-of-bounds read in + edge_interrupt_callback + - usb: musb: fix crash with highmen PIO and usbmon + - media: flexcop-usb: fix endpoint sanity check + - media: usbtv: fix control-message timeouts + - staging: kpc2000: prevent underflow in cpld_reconfigure() + - staging: rtl8188eu: Add ASUS USB-N10 Nano B1 to device table + - staging: wlan-ng: fix ODEBUG bug in prism2sta_disconnect_usb + - staging: wlan-ng: fix use-after-free Read in hfa384x_usbin_callback + - ahci: Add Intel Comet Lake H RAID PCI ID + - libfs: fix infoleak in simple_attr_read() + - media: ov519: add missing endpoint sanity checks + - media: dib0700: fix rc endpoint lookup + - media: stv06xx: add missing descriptor sanity checks + - media: xirlink_cit: add missing descriptor sanity checks + - media: v4l2-core: fix a use-after-free bug of sd->devnode + - update wireguard dkms package version + - [Config] updateconfigs for NET_REDIRECT + - net: Fix CONFIG_NET_CLS_ACT=n and CONFIG_NFT_FWD_NETDEV={y, m} build + - Linux 5.4.29 + * Restore kernel control of PCIe DPC via option (LP: #1869423) + - PCI/DPC: Add "pcie_ports=dpc-native" to allow DPC without AER control + * swap storms kills interactive use (LP: #1861359) + - SAUCE: mm/page_alloc.c: disable memory reclaim watermark boosting by default + * sysfs: incorrect network device permissions on network namespace change + (LP: #1865359) + - sysfs: add sysfs_file_change_owner() + - sysfs: add sysfs_link_change_owner() + - sysfs: add sysfs_group{s}_change_owner() + - sysfs: add sysfs_change_owner() + - device: add device_change_owner() + - drivers/base/power: add dpm_sysfs_change_owner() + - net-sysfs: add netdev_change_owner() + - net-sysfs: add queue_change_owner() + - net: fix sysfs permssions when device changes network namespace + - sysfs: fix static inline declaration of sysfs_groups_change_owner() + * Kernel Oops - general protection fault: 0000 [#1] SMP PTI after + disconnecting thunderbolt docking station (LP: #1864754) + - SAUCE: ptp: free ptp clock properly + * [Selftests] Apply various fixes and improvements (LP: #1870543) + - SAUCE: selftests: net: ip_defrag: limit packet to 1000 fragments + - SAUCE: kselftest/runner: avoid using timeout if timeout is disabled + - SAUCE: selftests/seccomp -- Disable timeout for seccomp tests + * Focal update: v5.4.28 upstream stable release (LP: #1869061) + - locks: fix a potential use-after-free problem when wakeup a waiter + - locks: reinstate locks_delete_block optimization + - spi: spi-omap2-mcspi: Support probe deferral for DMA channels + - drm/mediatek: Find the cursor plane instead of hard coding it + - phy: ti: gmii-sel: fix set of copy-paste errors + - phy: ti: gmii-sel: do not fail in case of gmii + - ARM: dts: dra7-l4: mark timer13-16 as pwm capable + - spi: qup: call spi_qup_pm_resume_runtime before suspending + - powerpc: Include .BTF section + - cifs: fix potential mismatch of UNC paths + - cifs: add missing mount option to /proc/mounts + - ARM: dts: dra7: Add "dma-ranges" property to PCIe RC DT nodes + - spi: pxa2xx: Add CS control clock quirk + - spi/zynqmp: remove entry that causes a cs glitch + - drm/exynos: dsi: propagate error value and silence meaningless warning + - drm/exynos: dsi: fix workaround for the legacy clock name + - drm/exynos: hdmi: don't leak enable HDMI_EN regulator if probe fails + - drivers/perf: fsl_imx8_ddr: Correct the CLEAR bit definition + - drivers/perf: arm_pmu_acpi: Fix incorrect checking of gicc pointer + - altera-stapl: altera_get_note: prevent write beyond end of 'key' + - dm bio record: save/restore bi_end_io and bi_integrity + - dm integrity: use dm_bio_record and dm_bio_restore + - riscv: avoid the PIC offset of static percpu data in module beyond 2G limits + - ASoC: stm32: sai: manage rebind issue + - spi: spi_register_controller(): free bus id on error paths + - riscv: Force flat memory model with no-mmu + - riscv: Fix range looking for kernel image memblock + - drm/amdgpu: clean wptr on wb when gpu recovery + - drm/amd/display: Clear link settings on MST disable connector + - drm/amd/display: fix dcc swath size calculations on dcn1 + - xenbus: req->body should be updated before req->state + - xenbus: req->err should be updated before req->state + - block, bfq: fix overwrite of bfq_group pointer in bfq_find_set_group() + - parse-maintainers: Mark as executable + - binderfs: use refcount for binder control devices too + - Revert "drm/fbdev: Fallback to non tiled mode if all tiles not present" + - usb: quirks: add NO_LPM quirk for RTL8153 based ethernet adapters + - USB: serial: option: add ME910G1 ECM composition 0x110b + - usb: host: xhci-plat: add a shutdown + - USB: serial: pl2303: add device-id for HP LD381 + - usb: xhci: apply XHCI_SUSPEND_DELAY to AMD XHCI controller 1022:145c + - usb: typec: ucsi: displayport: Fix NULL pointer dereference + - usb: typec: ucsi: displayport: Fix a potential race during registration + - USB: cdc-acm: fix close_delay and closing_wait units in TIOCSSERIAL + - USB: cdc-acm: fix rounding error in TIOCSSERIAL + - ALSA: line6: Fix endless MIDI read loop + - ALSA: hda/realtek - Enable headset mic of Acer X2660G with ALC662 + - ALSA: hda/realtek - Enable the headset of Acer N50-600 with ALC662 + - ALSA: seq: virmidi: Fix running status after receiving sysex + - ALSA: seq: oss: Fix running status after receiving sysex + - ALSA: pcm: oss: Avoid plugin buffer overflow + - ALSA: pcm: oss: Remove WARNING from snd_pcm_plug_alloc() checks + - tty: fix compat TIOCGSERIAL leaking uninitialized memory + - tty: fix compat TIOCGSERIAL checking wrong function ptr + - iio: chemical: sps30: fix missing triggered buffer dependency + - iio: st_sensors: remap SMO8840 to LIS2DH12 + - iio: trigger: stm32-timer: disable master mode when stopping + - iio: accel: adxl372: Set iio_chan BE + - iio: magnetometer: ak8974: Fix negative raw values in sysfs + - iio: adc: stm32-dfsdm: fix sleep in atomic context + - iio: adc: at91-sama5d2_adc: fix differential channels in triggered mode + - iio: light: vcnl4000: update sampling periods for vcnl4200 + - iio: light: vcnl4000: update sampling periods for vcnl4040 + - mmc: rtsx_pci: Fix support for speed-modes that relies on tuning + - mmc: sdhci-of-at91: fix cd-gpios for SAMA5D2 + - mmc: sdhci-cadence: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN for UniPhier + - CIFS: fiemap: do not return EINVAL if get nothing + - kbuild: Disable -Wpointer-to-enum-cast + - staging: rtl8188eu: Add device id for MERCUSYS MW150US v2 + - staging: greybus: loopback_test: fix poll-mask build breakage + - staging/speakup: fix get_word non-space look-ahead + - intel_th: msu: Fix the unexpected state warning + - intel_th: Fix user-visible error codes + - intel_th: pci: Add Elkhart Lake CPU support + - modpost: move the namespace field in Module.symvers last + - rtc: max8907: add missing select REGMAP_IRQ + - arm64: compat: Fix syscall number of compat_clock_getres + - xhci: Do not open code __print_symbolic() in xhci trace events + - btrfs: fix log context list corruption after rename whiteout error + - drm/amd/amdgpu: Fix GPR read from debugfs (v2) + - drm/lease: fix WARNING in idr_destroy + - stm class: sys-t: Fix the use of time_after() + - memcg: fix NULL pointer dereference in __mem_cgroup_usage_unregister_event + - mm, memcg: fix corruption on 64-bit divisor in memory.high throttling + - mm, memcg: throttle allocators based on ancestral memory.high + - mm/hotplug: fix hot remove failure in SPARSEMEM|!VMEMMAP case + - mm: do not allow MADV_PAGEOUT for CoW pages + - epoll: fix possible lost wakeup on epoll_ctl() path + - mm: slub: be more careful about the double cmpxchg of freelist + - mm, slub: prevent kmalloc_node crashes and memory leaks + - page-flags: fix a crash at SetPageError(THP_SWAP) + - x86/mm: split vmalloc_sync_all() + - futex: Fix inode life-time issue + - futex: Unbreak futex hashing + - arm64: smp: fix smp_send_stop() behaviour + - arm64: smp: fix crash_smp_send_stop() behaviour + - nvmet-tcp: set MSG_MORE only if we actually have more to send + - drm/bridge: dw-hdmi: fix AVI frame colorimetry + - staging: greybus: loopback_test: fix potential path truncation + - staging: greybus: loopback_test: fix potential path truncations + - Linux 5.4.28 + * Pop sound from build-in speaker during cold boot and resume from S3 + (LP: #1866357) // Focal update: v5.4.28 upstream stable release + (LP: #1869061) + - ALSA: hda/realtek: Fix pop noise on ALC225 + * Focal update: v5.4.28 upstream stable release (LP: #1869061) + - perf/x86/amd: Add support for Large Increment per Cycle Events + - EDAC/amd64: Add family ops for Family 19h Models 00h-0Fh + - x86/MCE/AMD, EDAC/mce_amd: Add new Load Store unit McaType + - EDAC/mce_amd: Always load on SMCA systems + - x86/amd_nb: Add Family 19h PCI IDs + - EDAC/amd64: Drop some family checks for newer systems + * Update mpt3sas Driver to 33.100.00.00 for Ubuntu 20.04 (LP: #1863574) + - scsi: mpt3sas: Register trace buffer based on NVDATA settings + - scsi: mpt3sas: Display message before releasing diag buffer + - scsi: mpt3sas: Free diag buffer without any status check + - scsi: mpt3sas: Maintain owner of buffer through UniqueID + - scsi: mpt3sas: clear release bit when buffer reregistered + - scsi: mpt3sas: Reuse diag buffer allocated at load time + - scsi: mpt3sas: Add app owned flag support for diag buffer + - scsi: mpt3sas: Fail release cmnd if diag buffer is released + - scsi: mpt3sas: Use Component img header to get Package ver + - scsi: mpt3sas: Fix module parameter max_msix_vectors + - scsi: mpt3sas: Bump mpt3sas driver version to 32.100.00.00 + - scsi: mpt3sas: Clean up some indenting + - scsi: mpt3sas: change allocation option + - scsi: mpt3sas: Update MPI Headers to v02.00.57 + - scsi: mpt3sas: Add support for NVMe shutdown + - scsi: mpt3sas: renamed _base_after_reset_handler function + - scsi: mpt3sas: Add support IOCs new state named COREDUMP + - scsi: mpt3sas: Handle CoreDump state from watchdog thread + - scsi: mpt3sas: print in which path firmware fault occurred + - scsi: mpt3sas: Optimize mpt3sas driver logging + - scsi: mpt3sas: Print function name in which cmd timed out + - scsi: mpt3sas: Remove usage of device_busy counter + - scsi: mpt3sas: Update drive version to 33.100.00.00 + * Ubuntu 20.04: megaraid_sas driver update to version 07.713.01.00-rc1 + (LP: #1863581) + - scsi: megaraid_sas: Unique names for MSI-X vectors + - scsi: megaraid_sas: remove unused variables 'debugBlk','fusion' + - compat_ioctl: use correct compat_ptr() translation in drivers + - scsi: megaraid_sas: Make poll_aen_lock static + - scsi: megaraid_sas: Reset adapter if FW is not in READY state after device + resume + - scsi: megaraid_sas: Set no_write_same only for Virtual Disk + - scsi: megaraid_sas: Update optimal queue depth for SAS and NVMe devices + - scsi: megaraid_sas: Do not kill host bus adapter, if adapter is already dead + - scsi: megaraid_sas: Do not kill HBA if JBOD Seqence map or RAID map is + disabled + - scsi: megaraid_sas: Do not set HBA Operational if FW is not in operational + state + - scsi: megaraid_sas: Re-Define enum DCMD_RETURN_STATUS + - scsi: megaraid_sas: Limit the number of retries for the IOCTLs causing + firmware fault + - scsi: megaraid_sas: Use Block layer API to check SCSI device in-flight IO + requests + - scsi: megaraid_sas: Update driver version to 07.713.01.00-rc1 + - scsi: megaraid_sas: fixup MSIx interrupt setup during resume + + -- Seth Forshee Fri, 03 Apr 2020 22:05:52 -0500 + +linux-oracle (5.4.0-1007.7) focal; urgency=medium + + + [ Ubuntu: 5.4.0-21.25 ] + + * CVE-2020-8835 + - SAUCE: bpf: undo incorrect __reg_bound_offset32 handling + + -- Thadeu Lima de Souza Cascardo Fri, 27 Mar 2020 20:07:28 -0300 + +linux-oracle (5.4.0-1006.6) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1006.6 -proposed tracker (LP: #1868346) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following Ubuntu-5.4.0-19.23 rebase + + [ Ubuntu: 5.4.0-20.24 ] + + * Miscellaneous Ubuntu changes + - SAUCE: (lockdown) Reduce lockdown level to INTEGRITY for secure boot + + [ Ubuntu: 5.4.0-19.23 ] + + * focal/linux: 5.4.0-19.23 -proposed tracker (LP: #1868347) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - update dkms package versions + * Focal update: v5.4.27 upstream stable release (LP: #1868538) + - netfilter: hashlimit: do not use indirect calls during gc + - netfilter: xt_hashlimit: unregister proc file before releasing mutex + - drm/amdgpu: Fix TLB invalidation request when using semaphore + - ACPI: watchdog: Allow disabling WDAT at boot + - HID: apple: Add support for recent firmware on Magic Keyboards + - ACPI: watchdog: Set default timeout in probe + - HID: hid-bigbenff: fix general protection fault caused by double kfree + - HID: hid-bigbenff: call hid_hw_stop() in case of error + - HID: hid-bigbenff: fix race condition for scheduled work during removal + - selftests/rseq: Fix out-of-tree compilation + - tracing: Fix number printing bug in print_synth_event() + - cfg80211: check reg_rule for NULL in handle_channel_custom() + - scsi: libfc: free response frame from GPN_ID + - net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch + - net: ks8851-ml: Fix IRQ handling and locking + - mac80211: rx: avoid RCU list traversal under mutex + - net: ll_temac: Fix race condition causing TX hang + - net: ll_temac: Add more error handling of dma_map_single() calls + - net: ll_temac: Fix RX buffer descriptor handling on GFP_ATOMIC pressure + - net: ll_temac: Handle DMA halt condition caused by buffer underrun + - blk-mq: insert passthrough request into hctx->dispatch directly + - drm/amdgpu: fix memory leak during TDR test(v2) + - kbuild: add dtbs_check to PHONY + - kbuild: add dt_binding_check to PHONY in a correct place + - signal: avoid double atomic counter increments for user accounting + - slip: not call free_netdev before rtnl_unlock in slip_open + - net: phy: mscc: fix firmware paths + - hinic: fix a irq affinity bug + - hinic: fix a bug of setting hw_ioctxt + - hinic: fix a bug of rss configuration + - net: rmnet: fix NULL pointer dereference in rmnet_newlink() + - net: rmnet: fix NULL pointer dereference in rmnet_changelink() + - net: rmnet: fix suspicious RCU usage + - net: rmnet: remove rcu_read_lock in rmnet_force_unassociate_device() + - net: rmnet: do not allow to change mux id if mux id is duplicated + - net: rmnet: use upper/lower device infrastructure + - net: rmnet: fix bridge mode bugs + - net: rmnet: fix packet forwarding in rmnet bridge mode + - sfc: fix timestamp reconstruction at 16-bit rollover points + - jbd2: fix data races at struct journal_head + - blk-mq: insert flush request to the front of dispatch queue + - net: qrtr: fix len of skb_put_padto in qrtr_node_enqueue + - ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional() + - ARM: 8958/1: rename missed uaccess .fixup section + - mm: slub: add missing TID bump in kmem_cache_alloc_bulk() + - HID: google: add moonball USB id + - HID: add ALWAYS_POLL quirk to lenovo pixart mouse + - ARM: 8961/2: Fix Kbuild issue caused by per-task stack protector GCC plugin + - ipv4: ensure rcu_read_lock() in cipso_v4_error() + - Linux 5.4.27 + * This laptop contains a touchpadwhich is not recognized. (LP: #1858299) // + Focal update: v5.4.27 upstream stable release (LP: #1868538) + - HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override + * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570) + - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th + * Make Dell WD19 dock more reliable after suspend (LP: #1868217) + - xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3 + - xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0 + - xhci: Finetune host initiated USB3 rootport link suspend and resume + - USB: Disable LPM on WD19's Realtek Hub + * update-version-dkms doesn't add a BugLink (LP: #1867790) + - [Packaging] Add BugLink to update-version-dkms commit + * enable realtek ethernet device ASPM function (LP: #1836030) + - PCI/ASPM: Add L1 PM substate support to pci_disable_link_state() + - PCI/ASPM: Allow re-enabling Clock PM + - PCI/ASPM: Remove pcie_aspm_enabled() unnecessary locking + - PCI/ASPM: Add pcie_aspm_get_link() + - PCI/ASPM: Add sysfs attributes for controlling ASPM link states + * Update SmartPQI driver in Focal to 1.2.10-025 (LP: #1864484) + - scsi: smartpqi: clean up indentation of a statement + - scsi: smartpqi: remove set but not used variable 'ctrl_info' + - scsi: smartpqi: clean up an indentation issue + - scsi: smartpqi: fix controller lockup observed during force reboot + - scsi: smartpqi: fix call trace in device discovery + - scsi: smartpqi: add inquiry timeouts + - scsi: smartpqi: fix LUN reset when fw bkgnd thread is hung + - scsi: smartpqi: change TMF timeout from 60 to 30 seconds + - scsi: smartpqi: correct syntax issue + - scsi: smartpqi: fix problem with unique ID for physical device + - scsi: smartpqi: remove unused manifest constants + - scsi: smartpqi: Align driver syntax with oob + - scsi: smartpqi: bump version + * [roce-0111]sync mainline kernel 5.5rc6 roce patchset into ubuntu HWE kernel + branch (LP: #1859269) + - RDMA/hns: Modify variable/field name from vlan to vlan_id + - RDMA/hns: Fix a spelling mistake in a macro + - RDMA/hns: Delete BITS_PER_BYTE redefinition + - RDMA/core: Move core content from ib_uverbs to ib_core + - RDMA/core: Create mmap database and cookie helper functions + - RDMA: Connect between the mmap entry and the umap_priv structure + - RDMA/hns: Remove unsupported modify_port callback + - RDMA/hns: Delete unnecessary variable max_post + - RDMA/hns: Remove unnecessary structure hns_roce_sqp + - RDMA/hns: Delete unnecessary uar from hns_roce_cq + - RDMA/hns: Modify fields of struct hns_roce_srq + - RDMA/hns: Replace not intuitive function/macro names + - RDMA/hns: Simplify doorbell initialization code + - RDMA/hns: Modify hns_roce_hw_v2_get_cfg to simplify the code + - RDMA/hns: Fix non-standard error codes + - RDMA/hns: Modify appropriate printings + - dma-mapping: remove the DMA_ATTR_WRITE_BARRIER flag + - IB/umem: remove the dmasync argument to ib_umem_get + - RDMA/hns: Redefine interfaces used in creating cq + - RDMA/hns: Redefine the member of hns_roce_cq struct + - RDMA/hns: Rename the functions used inside creating cq + - RDMA/hns: Delete unnecessary callback functions for cq + - RDMA/hns: Remove unused function hns_roce_init_eq_table() + - RDMA/hns: Update the value of qp type + - RDMA/hns: Delete unnessary parameters in hns_roce_v2_qp_modify() + - RDMA/hns: Remove redundant print information + - RDMA/hns: Replace custom macros HNS_ROCE_ALIGN_UP + - RDMA/hns: Fix coding style issues + - RDMA/hns: Add support for reporting wc as software mode + - RDMA/hns: Remove some redundant variables related to capabilities + - RDMA/hns: Add interfaces to get pf capabilities from firmware + - RDMA/hns: Get pf capabilities from firmware + - RDMA/hns: Add support for extended atomic in userspace + * dmaengine: hisilicon: Add Kunpeng DMA engine support (LP: #1864442) + - dmaengine: hisilicon: Add Kunpeng DMA engine support + - [Config] CONFIG_HISI_DMA=m + * Add support for Realtek 8723DE wireless adapter (LP: #1780590) + - rtw88: 8822c: fix boolreturn.cocci warnings + - rtw88: remove redundant flag check helper function + - rtw88: pci: reset H2C queue indexes in a single write + - rtw88: not to enter or leave PS under IRQ + - rtw88: not to control LPS by each vif + - rtw88: remove unused lps state check helper + - rtw88: LPS enter/leave should be protected by lock + - rtw88: leave PS state for dynamic mechanism + - rtw88: add deep power save support + - rtw88: not to enter LPS by coex strategy + - rtw88: select deep PS mode when module is inserted + - rtw88: add deep PS PG mode for 8822c + - rtw88: remove misleading module parameter rtw_fw_support_lps + - mac80211: simplify TX aggregation start + - rtw88: check firmware leave lps successfully + - rtw88: allows to set RTS in TX descriptor + - rtw88: add driver TX queue support + - rtw88: take over rate control from mac80211 + - rtw88: report tx rate to mac80211 stack + - rtw88: add TX-AMSDU support + - rtw88: flush hardware tx queues + - rtw88: Don't set RX_FLAG_DECRYPTED if packet has no encryption + - rtw88: configure TX queue EDCA parameters + - rtw88: raise firmware version debug level + - rtw88: use struct rtw_fw_hdr to access firmware header + - rtw88: Fix an error message + - rtw88: config 8822c multicast address in MAC init flow + - rtw88: add NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 support + - rtw88: Use rtw_write8_set to set SYS_FUNC + - rtw88: pci: config phy after chip info is setup + - rtw88: use a for loop in rtw_power_mode_change(), not goto + - rtw88: include interrupt.h for tasklet_struct + - rtw88: mark rtw_fw_hdr __packed + - rtw88: use macro to check the current band + - rtw88: add power tracking support + - rtw88: Enable 802.11ac beamformee support + - rtw88: add set_bitrate_mask support + - rtw88: add phy_info debugfs to show Tx/Rx physical status + - rtw88: fix GENMASK_ULL for u64 + - rtw88: fix sparse warnings for DPK + - rtw88: fix sparse warnings for power tracking + - rtw88: 8822b: add RFE type 3 support + - rtw88: use rtw_phy_pg_cfg_pair struct, not arrays + - rtw88: rearrange if..else statements for rx rate indexes + - rtw88: avoid FW info flood + - rtw88: remove redundant null pointer check on arrays + - rtw88: raise LPS threshold to 50, for less power consumption + - rtw88: fix potential NULL pointer access for firmware + - rtw88: signal completion even on firmware-request failure + - rtw88: remove duplicated include from ps.c + - rtw88: pci: use macros to access PCI DBI/MDIO registers + - rtw88: pci: use for loop instead of while loop for DBI/MDIO + - rtw88: pci: enable CLKREQ function if host supports it + - rtw88: allows to enable/disable HCI link PS mechanism + - rtw88: pci: reset ring index when release skbs in tx ring + - rtw88: pci: reset dma when reset pci trx ring + - rtw88: add interface config for 8822c + - rtw88: load wowlan firmware if wowlan is supported + - rtw88: support wowlan feature for 8822c + - rtw88: Add wowlan pattern match support + - rtw88: Add wowlan net-detect support + - rtw88: fix TX secondary channel offset of 40M if current bw is 20M or 40M + - rtw88: 8822c: update power sequence to v15 + - rtw88: remove unused spinlock + - rtw88: remove unused variable 'in_lps' + - rtw88: remove unused vif pointer in struct rtw_vif + - rtw88: use rtw_hci_stop() instead of rtwdev->hci.ops->stop() + - rtw88: assign NULL to skb after being kfree()'ed + - rtw88: change max_num_of_tx_queue() definition to inline in pci.h + - rtw88: use true,false for bool variable + - rtw88: use shorter delay time to poll PS state + - rtw88: Fix return value of rtw_wow_check_fw_status + - SAUCE: rtw88: add regulatory process strategy for different chipset + - SAUCE: rtw88: support dynamic user regulatory setting + - SAUCE: rtw88: Use secondary channel offset enumeration + - SAUCE: rtw88: 8822c: modify rf protection setting + - SAUCE: rtw88: disable TX-AMSDU on 2.4G band + - SAUCE: Revert "rtw88: disable TX-AMSDU on 2.4G band" + - SAUCE: rtw88: disable TX-AMSDU on 2.4G band + - SAUCE: rtw88: remove unused parameter vif in rtw_lps_pg_info_get() + - SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask + - SAUCE: rtw88: pci: 8822c should set clock delay to zero + - SAUCE: rtw88: move rtw_enter_ips() to the last when config + - SAUCE: rtw88: avoid holding mutex for cancel_delayed_work_sync() + - SAUCE: rtw88: add ciphers to suppress error message + - SAUCE: rtw88: 8822c: update power sequence to v16 + - SAUCE: rtw88: Fix incorrect beamformee role setting + - SAUCE: rtw88: don't hold all IRQs disabled for PS operations + - SAUCE: rtw88: extract alloc rsvd_page and h2c skb routines + - SAUCE: rtw88: associate reserved pages with each vif + - SAUCE: rtw88: add adaptivity support for EU/JP regulatory + - SAUCE: rtw88: 8723d: Add basic chip capabilities + - SAUCE: rtw88: 8723d: add beamform wrapper functions + - SAUCE: rtw88: 8723d: Add power sequence + - SAUCE: rtw88: 8723d: Add RF read/write ops + - SAUCE: rtw88: 8723d: Add mac/bb/rf/agc/power_limit tables + - SAUCE: rtw88: 8723d: Add cfg_ldo25 to control LDO25 + - SAUCE: rtw88: 8723d: Add new chip op efuse_grant() to control efuse access + - SAUCE: rtw88: 8723d: Add read_efuse to recognize efuse info from map + - SAUCE: rtw88: add legacy firmware download for 8723D devices + - SAUCE: rtw88: no need to send additional information to legacy firmware + - SAUCE: rtw88: 8723d: Add mac power-on/-off function + - SAUCE: rtw88: decompose while(1) loop of power sequence polling command + - SAUCE: rtw88: 8723d: 11N chips don't support H2C queue + - SAUCE: rtw88: 8723d: implement set_tx_power_index ops + - SAUCE: rtw88: 8723d: Organize chip TX/RX FIFO + - SAUCE: rtw88: 8723d: initialize mac/bb/rf basic functions + - SAUCE: rtw88: 8723d: Add DIG parameter + - SAUCE: rtw88: 8723d: Add query_rx_desc + - SAUCE: rtw88: 8723d: Add set_channel + - SAUCE: rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully + - SAUCE: rtw88: 8723d: 11N chips don't support LDPC + - SAUCE: rtw88: set default port to firmware + - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets + - SAUCE: rtw88: sar: add SAR of TX power limit + - SAUCE: rtw88: sar: Load static SAR table from ACPI WRDS method + - SAUCE: rtw88: sar: Load dynamic SAR table from ACPI methods + - SAUCE: rtw88: sar: apply dynamic SAR table to tx power limit + - SAUCE: rtw88: sar: add sar_work to poll if dynamic SAR table is changed + - SAUCE: rtw88: sar: dump sar information via debugfs + - SAUCE: rtw88: 8723d: Add chip_ops::false_alarm_statistics + - SAUCE: rtw88: 8723d: Set IG register for CCK rate + - SAUCE: rtw88: 8723d: add interface configurations table + - SAUCE: rtw88: 8723d: Add LC calibration + - SAUCE: rtw88: 8723d: add IQ calibration + - SAUCE: rtw88: 8723d: Add power tracking + - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend + - SAUCE: rtw88: 8723d: implement flush queue + - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info + - SAUCE: rtw88: 8723d: Add coex support + - SAUCE: rtw88: fill zeros to words 0x06 and 0x07 of security cam entry + - SAUCE: rtw88: 8723d: Add 8723DE to Kconfig and Makefile + - [Config] CONFIG_RTW88_8723DE=y + * [Ubuntu 20.04] Unset HIBERNATION and PM kernel config options for focal + (LP: #1867753) + - [Config] CONFIG_HIBERNATION=n and CONFIG_PM=n for s390x + * [20.04 FEAT] Base KVM setup for secure guests - kernel part (LP: #1835531) + - KVM: s390: Cleanup kvm_arch_init error path + - KVM: s390: Cleanup initial cpu reset + - KVM: s390: Add new reset vcpu API + - s390/protvirt: introduce host side setup + - s390/protvirt: add ultravisor initialization + - s390/mm: provide memory management functions for protected KVM guests + - s390/mm: add (non)secure page access exceptions handlers + - s390/protvirt: Add sysfs firmware interface for Ultravisor information + - KVM: s390/interrupt: do not pin adapter interrupt pages + - KVM: s390: protvirt: Add UV debug trace + - KVM: s390: add new variants of UV CALL + - KVM: s390: protvirt: Add initial vm and cpu lifecycle handling + - KVM: s390: protvirt: Secure memory is not mergeable + - KVM: s390/mm: Make pages accessible before destroying the guest + - KVM: s390: protvirt: Handle SE notification interceptions + - KVM: s390: protvirt: Instruction emulation + - KVM: s390: protvirt: Implement interrupt injection + - KVM: s390: protvirt: Add SCLP interrupt handling + - KVM: s390: protvirt: Handle spec exception loops + - KVM: s390: protvirt: Add new gprs location handling + - KVM: S390: protvirt: Introduce instruction data area bounce buffer + - KVM: s390: protvirt: handle secure guest prefix pages + - KVM: s390/mm: handle guest unpin events + - KVM: s390: protvirt: Write sthyi data to instruction data area + - KVM: s390: protvirt: STSI handling + - KVM: s390: protvirt: disallow one_reg + - KVM: s390: protvirt: Do only reset registers that are accessible + - KVM: s390: protvirt: Only sync fmt4 registers + - KVM: s390: protvirt: Add program exception injection + - KVM: s390: protvirt: UV calls in support of diag308 0, 1 + - KVM: s390: protvirt: Report CPU state to Ultravisor + - KVM: s390: protvirt: Support cmd 5 operation state + - KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112 + - KVM: s390: protvirt: do not inject interrupts after start + - KVM: s390: protvirt: Add UV cpu reset calls + - DOCUMENTATION: Protected virtual machine introduction and IPL + - KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED + - KVM: s390: protvirt: Add KVM api documentation + - mm/gup/writeback: add callbacks for inaccessible pages + * Sys oopsed with sysfs test in ubuntu_stress_smoke_test on X-hwe ARM64 + (LP: #1866772) + - ACPI: sysfs: copy ACPI data using io memory copying + * Focal update: v5.4.26 upstream stable release (LP: #1867903) + - virtio_balloon: Adjust label in virtballoon_probe + - ALSA: hda/realtek - More constifications + - cgroup, netclassid: periodically release file_lock on classid updating + - gre: fix uninit-value in __iptunnel_pull_header + - inet_diag: return classid for all socket types + - ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface + - ipvlan: add cond_resched_rcu() while processing muticast backlog + - ipvlan: do not add hardware address of master to its unicast filter list + - ipvlan: do not use cond_resched_rcu() in ipvlan_process_multicast() + - ipvlan: don't deref eth hdr before checking it's set + - macvlan: add cond_resched() during multicast processing + - net: dsa: fix phylink_start()/phylink_stop() calls + - net: dsa: mv88e6xxx: fix lockup on warm boot + - net: fec: validate the new settings in fec_enet_set_coalesce() + - net: hns3: fix a not link up issue when fibre port supports autoneg + - net/ipv6: use configured metric when add peer route + - netlink: Use netlink header as base to calculate bad attribute offset + - net: macsec: update SCI upon MAC address change. + - net: nfc: fix bounds checking bugs on "pipe" + - net/packet: tpacket_rcv: do not increment ring index on drop + - net: phy: bcm63xx: fix OOPS due to missing driver name + - net: stmmac: dwmac1000: Disable ACS if enhanced descs are not used + - net: systemport: fix index check to avoid an array out of bounds access + - sfc: detach from cb_page in efx_copy_channel() + - slip: make slhc_compress() more robust against malicious packets + - taprio: Fix sending packets without dequeueing them + - bonding/alb: make sure arp header is pulled before accessing it + - bnxt_en: reinitialize IRQs when MTU is modified + - bnxt_en: fix error handling when flashing from file + - cgroup: memcg: net: do not associate sock with unrelated cgroup + - net: memcg: late association of sock to memcg + - net: memcg: fix lockdep splat in inet_csk_accept() + - devlink: validate length of param values + - devlink: validate length of region addr/len + - fib: add missing attribute validation for tun_id + - nl802154: add missing attribute validation + - nl802154: add missing attribute validation for dev_type + - can: add missing attribute validation for termination + - macsec: add missing attribute validation for port + - net: fq: add missing attribute validation for orphan mask + - net: taprio: add missing attribute validation for txtime delay + - team: add missing attribute validation for port ifindex + - team: add missing attribute validation for array index + - tipc: add missing attribute validation for MTU property + - nfc: add missing attribute validation for SE API + - nfc: add missing attribute validation for deactivate target + - nfc: add missing attribute validation for vendor subcommand + - net: phy: avoid clearing PHY interrupts twice in irq handler + - net: phy: fix MDIO bus PM PHY resuming + - net/ipv6: need update peer route when modify metric + - net/ipv6: remove the old peer route if change it to a new one + - selftests/net/fib_tests: update addr_metric_test for peer route testing + - net: dsa: Don't instantiate phylink for CPU/DSA ports unless needed + - net: phy: Avoid multiple suspends + - cgroup: cgroup_procs_next should increase position index + - cgroup: Iterate tasks that did not finish do_exit() + - netfilter: nf_tables: fix infinite loop when expr is not available + - iwlwifi: mvm: Do not require PHY_SKU NVM section for 3168 devices + - iommu/vt-d: quirk_ioat_snb_local_iommu: replace WARN_TAINT with pr_warn + + add_taint + - netfilter: nf_conntrack: ct_cpu_seq_next should increase position index + - netfilter: synproxy: synproxy_cpu_seq_next should increase position index + - netfilter: xt_recent: recent_seq_next should increase position index + - netfilter: x_tables: xt_mttg_seq_next should increase position index + - workqueue: don't use wq_select_unbound_cpu() for bound works + - drm/amd/display: remove duplicated assignment to grph_obj_type + - drm/i915: be more solid in checking the alignment + - drm/i915: Defer semaphore priority bumping to a workqueue + - mmc: sdhci-pci-gli: Enable MSI interrupt for GL975x + - pinctrl: falcon: fix syntax error + - ktest: Add timeout for ssh sync testing + - cifs_atomic_open(): fix double-put on late allocation failure + - gfs2_atomic_open(): fix O_EXCL|O_CREAT handling on cold dcache + - KVM: x86: clear stale x86_emulate_ctxt->intercept value + - KVM: nVMX: avoid NULL pointer dereference with incorrect EVMCS GPAs + - ARC: define __ALIGN_STR and __ALIGN symbols for ARC + - fuse: fix stack use after return + - s390/dasd: fix data corruption for thin provisioned devices + - ipmi_si: Avoid spurious errors for optional IRQs + - blk-iocost: fix incorrect vtime comparison in iocg_is_idle() + - fscrypt: don't evict dirty inodes after removing key + - macintosh: windfarm: fix MODINFO regression + - x86/ioremap: Map EFI runtime services data as encrypted for SEV + - efi: Fix a race and a buffer overflow while reading efivars via sysfs + - efi: Add a sanity check to efivar_store_raw() + - i2c: designware-pci: Fix BUG_ON during device removal + - mt76: fix array overflow on receiving too many fragments for a packet + - perf/amd/uncore: Replace manual sampling check with CAP_NO_INTERRUPT flag + - x86/mce: Fix logic and comments around MSR_PPIN_CTL + - iommu/dma: Fix MSI reservation allocation + - iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint + - iommu/vt-d: Fix RCU list debugging warnings + - iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page + - batman-adv: Don't schedule OGM for disabled interface + - clk: imx8mn: Fix incorrect clock defines + - pinctrl: meson-gxl: fix GPIOX sdio pins + - pinctrl: imx: scu: Align imx sc msg structs to 4 + - virtio_ring: Fix mem leak with vring_new_virtqueue() + - drm/i915/gvt: Fix dma-buf display blur issue on CFL + - pinctrl: core: Remove extra kref_get which blocks hogs being freed + - drm/i915/gvt: Fix unnecessary schedule timer when no vGPU exits + - driver code: clarify and fix platform device DMA mask allocation + - iommu/vt-d: Fix RCU-list bugs in intel_iommu_init() + - i2c: gpio: suppress error on probe defer + - nl80211: add missing attribute validation for critical protocol indication + - nl80211: add missing attribute validation for beacon report scanning + - nl80211: add missing attribute validation for channel switch + - perf bench futex-wake: Restore thread count default to online CPU count + - netfilter: cthelper: add missing attribute validation for cthelper + - netfilter: nft_payload: add missing attribute validation for payload csum + flags + - netfilter: nft_tunnel: add missing attribute validation for tunnels + - netfilter: nf_tables: dump NFTA_CHAIN_FLAGS attribute + - netfilter: nft_chain_nat: inet family is missing module ownership + - iommu/vt-d: Fix the wrong printing in RHSA parsing + - iommu/vt-d: Ignore devices with out-of-spec domain number + - i2c: acpi: put device when verifying client fails + - iommu/amd: Fix IOMMU AVIC not properly update the is_run bit in IRTE + - ipv6: restrict IPV6_ADDRFORM operation + - net/smc: check for valid ib_client_data + - net/smc: cancel event worker during device removal + - Linux 5.4.26 + * please help enable CONFIG_EROFS_FS_ZIP (LP: #1867099) + - [Config] CONFIG_EROFS_FS_ZIP=y + - [Config] CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1 + * All PS/2 ports on PS/2 Serial add-in bracket are not working after S3 + (LP: #1866734) + - SAUCE: Input: i8042 - fix the selftest retry logic + * [UBUNTU 20.04] virtio-blk disks can go dissfunctional when swiotlb fills up + (LP: #1867109) + - virtio-blk: fix hw_queue stopped on arbitrary error + - virtio-blk: improve virtqueue error to BLK_STS + * Focal update: v5.4.25 upstream stable release (LP: #1867178) + - block, bfq: get extra ref to prevent a queue from being freed during a group + move + - block, bfq: do not insert oom queue into position tree + - net: dsa: bcm_sf2: Forcibly configure IMP port for 1Gb/sec + - net: stmmac: fix notifier registration + - dm thin metadata: fix lockdep complaint + - RDMA/core: Fix pkey and port assignment in get_new_pps + - RDMA/core: Fix use of logical OR in get_new_pps + - kbuild: fix 'No such file or directory' warning when cleaning + - kprobes: Fix optimize_kprobe()/unoptimize_kprobe() cancellation logic + - blktrace: fix dereference after null check + - ALSA: hda: do not override bus codec_mask in link_get() + - serial: ar933x_uart: set UART_CS_{RX,TX}_READY_ORIDE + - selftests: fix too long argument + - usb: gadget: composite: Support more than 500mA MaxPower + - usb: gadget: ffs: ffs_aio_cancel(): Save/restore IRQ flags + - usb: gadget: serial: fix Tx stall after buffer overflow + - habanalabs: halt the engines before hard-reset + - habanalabs: do not halt CoreSight during hard reset + - habanalabs: patched cb equals user cb in device memset + - drm/msm/mdp5: rate limit pp done timeout warnings + - drm: msm: Fix return type of dsi_mgr_connector_mode_valid for kCFI + - drm/modes: Make sure to parse valid rotation value from cmdline + - drm/modes: Allow DRM_MODE_ROTATE_0 when applying video mode parameters + - scsi: megaraid_sas: silence a warning + - drm/msm/dsi: save pll state before dsi host is powered off + - drm/msm/dsi/pll: call vco set rate explicitly + - selftests: forwarding: use proto icmp for {gretap, ip6gretap}_mac testing + - selftests: forwarding: vxlan_bridge_1d: fix tos value + - net: atlantic: check rpc result and wait for rpc address + - net: ks8851-ml: Remove 8-bit bus accessors + - net: ks8851-ml: Fix 16-bit data access + - net: ks8851-ml: Fix 16-bit IO operation + - net: ethernet: dm9000: Handle -EPROBE_DEFER in dm9000_parse_dt() + - watchdog: da9062: do not ping the hw during stop() + - s390/cio: cio_ignore_proc_seq_next should increase position index + - s390: make 'install' not depend on vmlinux + - efi: Only print errors about failing to get certs if EFI vars are found + - net/mlx5: DR, Fix matching on vport gvmi + - nvme/pci: Add sleep quirk for Samsung and Toshiba drives + - nvme-pci: Use single IRQ vector for old Apple models + - x86/boot/compressed: Don't declare __force_order in kaslr_64.c + - s390/qdio: fill SL with absolute addresses + - nvme: Fix uninitialized-variable warning + - ice: Don't tell the OS that link is going down + - x86/xen: Distribute switch variables for initialization + - net: thunderx: workaround BGX TX Underflow issue + - csky/mm: Fixup export invalid_pte_table symbol + - csky: Set regs->usp to kernel sp, when the exception is from kernel + - csky/smp: Fixup boot failed when CONFIG_SMP + - csky: Fixup ftrace modify panic + - csky: Fixup compile warning for three unimplemented syscalls + - arch/csky: fix some Kconfig typos + - selftests: forwarding: vxlan_bridge_1d: use more proper tos value + - firmware: imx: scu: Ensure sequential TX + - binder: prevent UAF for binderfs devices + - binder: prevent UAF for binderfs devices II + - ALSA: hda/realtek - Add Headset Mic supported + - ALSA: hda/realtek - Add Headset Button supported for ThinkPad X1 + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master + - ALSA: hda/realtek - Enable the headset of ASUS B9450FA with ALC294 + - cifs: don't leak -EAGAIN for stat() during reconnect + - cifs: fix rename() by ensuring source handle opened with DELETE bit + - usb: storage: Add quirk for Samsung Fit flash + - usb: quirks: add NO_LPM quirk for Logitech Screen Share + - usb: dwc3: gadget: Update chain bit correctly when using sg list + - usb: cdns3: gadget: link trb should point to next request + - usb: cdns3: gadget: toggle cycle bit before reset endpoint + - usb: core: hub: fix unhandled return by employing a void function + - usb: core: hub: do error out if usb_autopm_get_interface() fails + - usb: core: port: do error out if usb_autopm_get_interface() fails + - vgacon: Fix a UAF in vgacon_invert_region + - mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking + page tables prot_numa + - mm: fix possible PMD dirty bit lost in set_pmd_migration_entry() + - mm, hotplug: fix page online with DEBUG_PAGEALLOC compiled but not enabled + - fat: fix uninit-memory access for partial initialized inode + - btrfs: fix RAID direct I/O reads with alternate csums + - arm64: dts: socfpga: agilex: Fix gmac compatible + - arm: dts: dra76x: Fix mmc3 max-frequency + - tty:serial:mvebu-uart:fix a wrong return + - tty: serial: fsl_lpuart: free IDs allocated by IDA + - serial: 8250_exar: add support for ACCES cards + - vt: selection, close sel_buffer race + - vt: selection, push console lock down + - vt: selection, push sel_lock up + - media: hantro: Fix broken media controller links + - media: mc-entity.c: use & to check pad flags, not == + - media: vicodec: process all 4 components for RGB32 formats + - media: v4l2-mem2mem.c: fix broken links + - perf intel-pt: Fix endless record after being terminated + - perf intel-bts: Fix endless record after being terminated + - perf cs-etm: Fix endless record after being terminated + - perf arm-spe: Fix endless record after being terminated + - spi: spidev: Fix CS polarity if GPIO descriptors are used + - x86/pkeys: Manually set X86_FEATURE_OSPKE to preserve existing changes + - s390/pci: Fix unexpected write combine on resource + - s390/mm: fix panic in gup_fast on large pud + - dmaengine: imx-sdma: fix context cache + - dmaengine: imx-sdma: Fix the event id check to include RX event for UART6 + - dmaengine: tegra-apb: Fix use-after-free + - dmaengine: tegra-apb: Prevent race conditions of tasklet vs free list + - dm integrity: fix recalculation when moving from journal mode to bitmap mode + - dm integrity: fix a deadlock due to offloading to an incorrect workqueue + - dm integrity: fix invalid table returned due to argument count mismatch + - dm cache: fix a crash due to incorrect work item cancelling + - dm: report suspended device during destroy + - dm writecache: verify watermark during resume + - dm zoned: Fix reference counter initial value of chunk works + - dm: fix congested_fn for request-based device + - arm64: dts: meson-sm1-sei610: add missing interrupt-names + - ARM: dts: ls1021a: Restore MDIO compatible to gianfar + - spi: bcm63xx-hsspi: Really keep pll clk enabled + - drm/virtio: make resource id workaround runtime switchable. + - drm/virtio: fix resource id creation race + - ASoC: topology: Fix memleak in soc_tplg_link_elems_load() + - ASoC: topology: Fix memleak in soc_tplg_manifest_load() + - ASoC: SOF: Fix snd_sof_ipc_stream_posn() + - ASoC: intel: skl: Fix pin debug prints + - ASoC: intel: skl: Fix possible buffer overflow in debug outputs + - powerpc: define helpers to get L1 icache sizes + - powerpc: Convert flush_icache_range & friends to C + - powerpc/mm: Fix missing KUAP disable in flush_coherent_icache() + - ASoC: pcm: Fix possible buffer overflow in dpcm state sysfs output + - ASoC: pcm512x: Fix unbalanced regulator enable call in probe error path + - ASoC: Intel: Skylake: Fix available clock counter incrementation + - ASoC: dapm: Correct DAPM handling of active widgets during shutdown + - spi: atmel-quadspi: fix possible MMIO window size overrun + - drm/panfrost: Don't try to map on error faults + - drm: kirin: Revert "Fix for hikey620 display offset problem" + - drm/sun4i: Add separate DE3 VI layer formats + - drm/sun4i: Fix DE2 VI layer format support + - drm/sun4i: de2/de3: Remove unsupported VI layer formats + - drm/i915: Program MBUS with rmw during initialization + - drm/i915/selftests: Fix return in assert_mmap_offset() + - phy: mapphone-mdm6600: Fix timeouts by adding wake-up handling + - phy: mapphone-mdm6600: Fix write timeouts with shorter GPIO toggle interval + - ARM: dts: imx6: phycore-som: fix emmc supply + - arm64: dts: imx8qxp-mek: Remove unexisting Ethernet PHY + - firmware: imx: misc: Align imx sc msg structs to 4 + - firmware: imx: scu-pd: Align imx sc msg structs to 4 + - firmware: imx: Align imx_sc_msg_req_cpu_start to 4 + - soc: imx-scu: Align imx sc msg structs to 4 + - Revert "RDMA/cma: Simplify rdma_resolve_addr() error flow" + - RDMA/rw: Fix error flow during RDMA context initialization + - RDMA/nldev: Fix crash when set a QP to a new counter but QPN is missing + - RDMA/siw: Fix failure handling during device creation + - RDMA/iwcm: Fix iwcm work deallocation + - RDMA/core: Fix protection fault in ib_mr_pool_destroy + - regulator: stm32-vrefbuf: fix a possible overshoot when re-enabling + - RMDA/cm: Fix missing ib_cm_destroy_id() in ib_cm_insert_listen() + - IB/hfi1, qib: Ensure RCU is locked when accessing list + - ARM: imx: build v7_cpu_resume() unconditionally + - ARM: dts: am437x-idk-evm: Fix incorrect OPP node names + - ARM: dts: dra7xx-clocks: Fixup IPU1 mux clock parent source + - ARM: dts: imx7-colibri: Fix frequency for sd/mmc + - hwmon: (adt7462) Fix an error return in ADT7462_REG_VOLT() + - dma-buf: free dmabuf->name in dma_buf_release() + - dmaengine: coh901318: Fix a double lock bug in dma_tc_handle() + - arm64: dts: meson: fix gxm-khadas-vim2 wifi + - bus: ti-sysc: Fix 1-wire reset quirk + - EDAC/synopsys: Do not print an error with back-to-back snprintf() calls + - powerpc: fix hardware PMU exception bug on PowerVM compatibility mode + systems + - efi/x86: Align GUIDs to their size in the mixed mode runtime wrapper + - efi/x86: Handle by-ref arguments covering multiple pages in mixed mode + - efi: READ_ONCE rng seed size before munmap + - block, bfq: get a ref to a group when adding it to a service tree + - block, bfq: remove ifdefs from around gets/puts of bfq groups + - csky: Implement copy_thread_tls + - drm/virtio: module_param_named() requires linux/moduleparam.h + - Linux 5.4.25 + * Miscellaneous Ubuntu changes + - hio -- remove duplicated MODULE_DEVICE_TABLE declaration + - [Config] Add initial riscv64 config + - [Config] Bring riscv64 in line with other arches + - [Packaging] Add riscv64 arch support + - [Packaging] Add initial riscv64 abi + - [Config] updateconfigs for riscv64 + - [Config] Update annotations for riscv64 + - SAUCE: r8169: disable ASPM L1.1 + - update wireguard dkms package version + - [Config] garbage collect PCIEASPM_DEBUG + - [Config] gcc version updateconfigs + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: platform/x86: dell-uart-backlight: move retry block" + - RISC-V: Do not invoke SBI call if cpumask is empty + - RISC-V: Issue a local tlbflush if possible. + - RISC-V: Issue a tlb page flush if possible + - riscv: add support for SECCOMP and SECCOMP_FILTER + - riscv: reject invalid syscalls below -1 + - mtd: spi-nor: Add support for is25wp256 + - PCI/ASPM: Remove PCIEASPM_DEBUG Kconfig option and related code + + -- Paolo Pisati Tue, 24 Mar 2020 11:40:50 +0100 + +linux-oracle (5.4.0-1005.5) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1005.5 -proposed tracker (LP: #1866487) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following Ubuntu-5.4.0-18.22 rebase + + [ Ubuntu: 5.4.0-18.22 ] + + * focal/linux: 5.4.0-18.22 -proposed tracker (LP: #1866488) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + * Add sysfs attribute to show remapped NVMe (LP: #1863621) + - SAUCE: ata: ahci: Add sysfs attribute to show remapped NVMe device count + * [20.04 FEAT] Compression improvements in Linux kernel (LP: #1830208) + - lib/zlib: add s390 hardware support for kernel zlib_deflate + - s390/boot: rename HEAP_SIZE due to name collision + - lib/zlib: add s390 hardware support for kernel zlib_inflate + - s390/boot: add dfltcc= kernel command line parameter + - lib/zlib: add zlib_deflate_dfltcc_enabled() function + - btrfs: use larger zlib buffer for s390 hardware compression + - [Config] Introducing s390x specific kernel config option CONFIG_ZLIB_DFLTCC + * [UBUNTU 20.04] s390x/pci: increase CONFIG_PCI_NR_FUNCTIONS to 512 in kernel + config (LP: #1866056) + - [Config] Increase CONFIG_PCI_NR_FUNCTIONS from 64 to 512 starting with focal + on s390x + * CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set (LP: #1865332) + - [Config] CONFIG_IP_MROUTE_MULTIPLE_TABLES=y + * Dell XPS 13 9300 Intel 1650S wifi [34f0:1651] fails to load firmware + (LP: #1865962) + - iwlwifi: remove IWL_DEVICE_22560/IWL_DEVICE_FAMILY_22560 + - iwlwifi: 22000: fix some indentation + - iwlwifi: pcie: rx: use rxq queue_size instead of constant + - iwlwifi: allocate more receive buffers for HE devices + - iwlwifi: remove some outdated iwl22000 configurations + - iwlwifi: assume the driver_data is a trans_cfg, but allow full cfg + * [FOCAL][REGRESSION] Intel Gen 9 brightness cannot be controlled + (LP: #1861521) + - Revert "USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision + 4K sku" + - Revert "UBUNTU: SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd + Gen 4K AMOLED panel" + - SAUCE: drm/dp: Introduce EDID-based quirks + - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED + panel + - SAUCE: drm/i915: Force DPCD backlight mode for some Dell CML 2020 panels + * [20.04 FEAT] Enable proper kprobes on ftrace support (LP: #1865858) + - s390/ftrace: save traced function caller + - s390: support KPROBES_ON_FTRACE + * alsa/sof: load different firmware on different platforms (LP: #1857409) + - ASoC: SOF: Intel: hda: use fallback for firmware name + - ASoC: Intel: acpi-match: split CNL tables in three + - ASoC: SOF: Intel: Fix CFL and CML FW nocodec binary names. + * [UBUNTU 20.04] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x + starting with focal (LP: #1865452) + - [Config] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x starting + with focal + * Focal update: v5.4.24 upstream stable release (LP: #1866333) + - io_uring: grab ->fs as part of async offload + - EDAC: skx_common: downgrade message importance on missing PCI device + - net: dsa: b53: Ensure the default VID is untagged + - net: fib_rules: Correctly set table field when table number exceeds 8 bits + - net: macb: ensure interface is not suspended on at91rm9200 + - net: mscc: fix in frame extraction + - net: phy: restore mdio regs in the iproc mdio driver + - net: sched: correct flower port blocking + - net/tls: Fix to avoid gettig invalid tls record + - nfc: pn544: Fix occasional HW initialization failure + - qede: Fix race between rdma destroy workqueue and link change event + - Revert "net: dev: introduce support for sch BYPASS for lockless qdisc" + - udp: rehash on disconnect + - sctp: move the format error check out of __sctp_sf_do_9_1_abort + - bnxt_en: Improve device shutdown method. + - bnxt_en: Issue PCIe FLR in kdump kernel to cleanup pending DMAs. + - bonding: add missing netdev_update_lockdep_key() + - net: export netdev_next_lower_dev_rcu() + - bonding: fix lockdep warning in bond_get_stats() + - ipv6: Fix route replacement with dev-only route + - ipv6: Fix nlmsg_flags when splitting a multipath route + - ipmi:ssif: Handle a possible NULL pointer reference + - drm/msm: Set dma maximum segment size for mdss + - sched/core: Don't skip remote tick for idle CPUs + - timers/nohz: Update NOHZ load in remote tick + - sched/fair: Prevent unlimited runtime on throttled group + - dax: pass NOWAIT flag to iomap_apply + - mac80211: consider more elements in parsing CRC + - cfg80211: check wiphy driver existence for drvinfo report + - s390/zcrypt: fix card and queue total counter wrap + - qmi_wwan: re-add DW5821e pre-production variant + - qmi_wwan: unconditionally reject 2 ep interfaces + - NFSv4: Fix races between open and dentry revalidation + - perf/smmuv3: Use platform_get_irq_optional() for wired interrupt + - perf/x86/intel: Add Elkhart Lake support + - perf/x86/cstate: Add Tremont support + - perf/x86/msr: Add Tremont support + - ceph: do not execute direct write in parallel if O_APPEND is specified + - ARM: dts: sti: fixup sound frame-inversion for stihxxx-b2120.dtsi + - drm/amd/display: Do not set optimized_require to false after plane disable + - RDMA/siw: Remove unwanted WARN_ON in siw_cm_llp_data_ready() + - drm/amd/display: Check engine is not NULL before acquiring + - drm/amd/display: Limit minimum DPPCLK to 100MHz. + - drm/amd/display: Add initialitions for PLL2 clock source + - amdgpu: Prevent build errors regarding soft/hard-float FP ABI tags + - soc/tegra: fuse: Fix build with Tegra194 configuration + - i40e: Fix the conditional for i40e_vc_validate_vqs_bitmaps + - net: ena: fix potential crash when rxfh key is NULL + - net: ena: fix uses of round_jiffies() + - net: ena: add missing ethtool TX timestamping indication + - net: ena: fix incorrect default RSS key + - net: ena: rss: do not allocate key when not supported + - net: ena: rss: fix failure to get indirection table + - net: ena: rss: store hash function as values and not bits + - net: ena: fix incorrectly saving queue numbers when setting RSS indirection + table + - net: ena: fix corruption of dev_idx_to_host_tbl + - net: ena: ethtool: use correct value for crc32 hash + - net: ena: ena-com.c: prevent NULL pointer dereference + - ice: update Unit Load Status bitmask to check after reset + - cifs: Fix mode output in debugging statements + - cfg80211: add missing policy for NL80211_ATTR_STATUS_CODE + - mac80211: fix wrong 160/80+80 MHz setting + - nvme/tcp: fix bug on double requeue when send fails + - nvme: prevent warning triggered by nvme_stop_keep_alive + - nvme/pci: move cqe check after device shutdown + - ext4: potential crash on allocation error in ext4_alloc_flex_bg_array() + - audit: fix error handling in audit_data_to_entry() + - audit: always check the netlink payload length in audit_receive_msg() + - ACPICA: Introduce ACPI_ACCESS_BYTE_WIDTH() macro + - ACPI: watchdog: Fix gas->access_width usage + - KVM: VMX: check descriptor table exits on instruction emulation + - HID: ite: Only bind to keyboard USB interface on Acer SW5-012 keyboard dock + - HID: core: fix off-by-one memset in hid_report_raw_event() + - HID: core: increase HID report buffer size to 8KiB + - drm/amdgpu: Drop DRIVER_USE_AGP + - drm/radeon: Inline drm_get_pci_dev + - macintosh: therm_windtunnel: fix regression when instantiating devices + - tracing: Disable trace_printk() on post poned tests + - Revert "PM / devfreq: Modify the device name as devfreq(X) for sysfs" + - amdgpu/gmc_v9: save/restore sdpif regs during S3 + - cpufreq: Fix policy initialization for internal governor drivers + - io_uring: fix 32-bit compatability with sendmsg/recvmsg + - netfilter: ipset: Fix "INFO: rcu detected stall in hash_xxx" reports + - net/smc: transfer fasync_list in case of fallback + - vhost: Check docket sk_family instead of call getname + - netfilter: ipset: Fix forceadd evaluation path + - netfilter: xt_hashlimit: reduce hashlimit_mutex scope for htable_put() + - HID: alps: Fix an error handling path in 'alps_input_configured()' + - HID: hiddev: Fix race in in hiddev_disconnect() + - MIPS: VPE: Fix a double free and a memory leak in 'release_vpe()' + - i2c: altera: Fix potential integer overflow + - i2c: jz4780: silence log flood on txabrt + - drm/i915/gvt: Fix orphan vgpu dmabuf_objs' lifetime + - drm/i915/gvt: Separate display reset from ALL_ENGINES reset + - nl80211: fix potential leak in AP start + - mac80211: Remove a redundant mutex unlock + - kbuild: fix DT binding schema rule to detect command line changes + - hv_netvsc: Fix unwanted wakeup in netvsc_attach() + - usb: charger: assign specific number for enum value + - nvme-pci: Hold cq_poll_lock while completing CQEs + - s390/qeth: vnicc Fix EOPNOTSUPP precedence + - net: netlink: cap max groups which will be considered in netlink_bind() + - net: atlantic: fix use after free kasan warn + - net: atlantic: fix potential error handling + - net: atlantic: fix out of range usage of active_vlans array + - net/smc: no peer ID in CLC decline for SMCD + - net: ena: make ena rxfh support ETH_RSS_HASH_NO_CHANGE + - selftests: Install settings files to fix TIMEOUT failures + - kbuild: remove header compile test + - kbuild: move headers_check rule to usr/include/Makefile + - kbuild: remove unneeded variable, single-all + - kbuild: make single target builds even faster + - namei: only return -ECHILD from follow_dotdot_rcu() + - mwifiex: drop most magic numbers from mwifiex_process_tdls_action_frame() + - mwifiex: delete unused mwifiex_get_intf_num() + - KVM: SVM: Override default MMIO mask if memory encryption is enabled + - KVM: Check for a bad hva before dropping into the ghc slow path + - sched/fair: Optimize select_idle_cpu + - f2fs: fix to add swap extent correctly + - RDMA/hns: Simplify the calculation and usage of wqe idx for post verbs + - RDMA/hns: Bugfix for posting a wqe with sge + - drivers: net: xgene: Fix the order of the arguments of + 'alloc_etherdev_mqs()' + - ima: ima/lsm policy rule loading logic bug fixes + - kprobes: Set unoptimized flag after unoptimizing code + - lib/vdso: Make __arch_update_vdso_data() logic understandable + - lib/vdso: Update coarse timekeeper unconditionally + - pwm: omap-dmtimer: put_device() after of_find_device_by_node() + - perf hists browser: Restore ESC as "Zoom out" of DSO/thread/etc + - perf ui gtk: Add missing zalloc object + - x86/resctrl: Check monitoring static key in the MBM overflow handler + - KVM: x86: Remove spurious kvm_mmu_unload() from vcpu destruction path + - KVM: x86: Remove spurious clearing of async #PF MSR + - rcu: Allow only one expedited GP to run concurrently with wakeups + - ubifs: Fix ino_t format warnings in orphan_delete() + - thermal: db8500: Depromote debug print + - thermal: brcmstb_thermal: Do not use DT coefficients + - netfilter: nft_tunnel: no need to call htons() when dumping ports + - netfilter: nf_flowtable: fix documentation + - bus: tegra-aconnect: Remove PM_CLK dependency + - xfs: clear kernel only flags in XFS_IOC_ATTRMULTI_BY_HANDLE + - locking/lockdep: Fix lockdep_stats indentation problem + - mm/debug.c: always print flags in dump_page() + - mm/gup: allow FOLL_FORCE for get_user_pages_fast() + - mm/huge_memory.c: use head to check huge zero page + - mm, thp: fix defrag setting if newline is not used + - kvm: nVMX: VMWRITE checks VMCS-link pointer before VMCS field + - kvm: nVMX: VMWRITE checks unsupported field before read-only field + - blktrace: Protect q->blk_trace with RCU + - Linux 5.4.24 + * Focal update: v5.4.23 upstream stable release (LP: #1866165) + - iommu/qcom: Fix bogus detach logic + - ALSA: hda: Use scnprintf() for printing texts for sysfs/procfs + - ALSA: hda/realtek - Apply quirk for MSI GP63, too + - ALSA: hda/realtek - Apply quirk for yet another MSI laptop + - ASoC: codec2codec: avoid invalid/double-free of pcm runtime + - ASoC: sun8i-codec: Fix setting DAI data format + - tpm: Initialize crypto_id of allocated_banks to HASH_ALGO__LAST + - ecryptfs: fix a memory leak bug in parse_tag_1_packet() + - ecryptfs: fix a memory leak bug in ecryptfs_init_messaging() + - btrfs: handle logged extent failure properly + - thunderbolt: Prevent crash if non-active NVMem file is read + - USB: misc: iowarrior: add support for 2 OEMed devices + - USB: misc: iowarrior: add support for the 28 and 28L devices + - USB: misc: iowarrior: add support for the 100 device + - e1000e: Use rtnl_lock to prevent race conditions between net and pci/pm + - floppy: check FDC index for errors before assigning it + - vt: fix scrollback flushing on background consoles + - vt: selection, handle pending signals in paste_selection + - vt: vt_ioctl: fix race in VT_RESIZEX + - staging: android: ashmem: Disallow ashmem memory from being remapped + - staging: vt6656: fix sign of rx_dbm to bb_pre_ed_rssi. + - xhci: Force Maximum Packet size for Full-speed bulk devices to valid range. + - xhci: fix runtime pm enabling for quirky Intel hosts + - xhci: apply XHCI_PME_STUCK_QUIRK to Intel Comet Lake platforms + - xhci: Fix memory leak when caching protocol extended capability PSI tables - + take 2 + - usb: host: xhci: update event ring dequeue pointer on purpose + - USB: core: add endpoint-blacklist quirk + - USB: quirks: blacklist duplicate ep on Sound Devices USBPre2 + - usb: uas: fix a plug & unplug racing + - USB: Fix novation SourceControl XL after suspend + - USB: hub: Don't record a connect-change event during reset-resume + - USB: hub: Fix the broken detection of USB3 device in SMSC hub + - usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows + - usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields + - usb: dwc3: debug: fix string position formatting mixup with ret and len + - scsi: Revert "target/core: Inline transport_lun_remove_cmd()" + - staging: rtl8188eu: Fix potential security hole + - staging: rtl8188eu: Fix potential overuse of kernel memory + - staging: rtl8723bs: Fix potential security hole + - staging: rtl8723bs: Fix potential overuse of kernel memory + - drm/panfrost: perfcnt: Reserve/use the AS attached to the perfcnt MMU + context + - powerpc/8xx: Fix clearing of bits 20-23 in ITLB miss + - powerpc/eeh: Fix deadlock handling dead PHB + - powerpc/tm: Fix clearing MSR[TS] in current when reclaiming on signal + delivery + - powerpc/entry: Fix an #if which should be an #ifdef in entry_32.S + - powerpc/hugetlb: Fix 512k hugepages on 8xx with 16k page size + - powerpc/hugetlb: Fix 8M hugepages on 8xx + - arm64: memory: Add missing brackets to untagged_addr() macro + - jbd2: fix ocfs2 corrupt when clearing block group bits + - x86/ima: use correct identifier for SetupMode variable + - x86/mce/amd: Publish the bank pointer only after setup has succeeded + - x86/mce/amd: Fix kobject lifetime + - x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF + - serial: 8250: Check UPF_IRQ_SHARED in advance + - tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode + - tty: serial: imx: setup the correct sg entry for tx dma + - tty: serial: qcom_geni_serial: Fix RX cancel command failure + - serdev: ttyport: restore client ops on deregistration + - MAINTAINERS: Update drm/i915 bug filing URL + - ACPI: PM: s2idle: Check fixed wakeup events in acpi_s2idle_wake() + - mm/memcontrol.c: lost css_put in memcg_expand_shrinker_maps() + - nvme-multipath: Fix memory leak with ana_log_buf + - genirq/irqdomain: Make sure all irq domain flags are distinct + - mm/vmscan.c: don't round up scan size for online memory cgroup + - mm/sparsemem: pfn_to_page is not valid yet on SPARSEMEM + - lib/stackdepot.c: fix global out-of-bounds in stack_slabs + - mm: Avoid creating virtual address aliases in brk()/mmap()/mremap() + - drm/amdgpu/soc15: fix xclk for raven + - drm/amdgpu/gfx9: disable gfxoff when reading rlc clock + - drm/amdgpu/gfx10: disable gfxoff when reading rlc clock + - drm/nouveau/kms/gv100-: Re-set LUT after clearing for modesets + - drm/i915: Wean off drm_pci_alloc/drm_pci_free + - drm/i915: Update drm/i915 bug filing URL + - sched/psi: Fix OOB write when writing 0 bytes to PSI files + - KVM: nVMX: Don't emulate instructions in guest mode + - KVM: x86: don't notify userspace IOAPIC on edge-triggered interrupt EOI + - ext4: fix a data race in EXT4_I(inode)->i_disksize + - ext4: add cond_resched() to __ext4_find_entry() + - ext4: fix potential race between online resizing and write operations + - ext4: fix potential race between s_group_info online resizing and access + - ext4: fix potential race between s_flex_groups online resizing and access + - ext4: fix mount failure with quota configured as module + - ext4: rename s_journal_flag_rwsem to s_writepages_rwsem + - ext4: fix race between writepages and enabling EXT4_EXTENTS_FL + - KVM: nVMX: Refactor IO bitmap checks into helper function + - KVM: nVMX: Check IO instruction VM-exit conditions + - KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when + apicv is globally disabled + - KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1 + - KVM: apic: avoid calculating pending eoi from an uninitialized val + - btrfs: destroy qgroup extent records on transaction abort + - btrfs: fix bytes_may_use underflow in prealloc error condtition + - btrfs: reset fs_root to NULL on error in open_ctree + - btrfs: do not check delayed items are empty for single transaction cleanup + - Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered + extents + - Btrfs: fix race between shrinking truncate and fiemap + - btrfs: don't set path->leave_spinning for truncate + - Btrfs: fix deadlock during fast fsync when logging prealloc extents beyond + eof + - Revert "dmaengine: imx-sdma: Fix memory leak" + - drm/i915/gvt: more locking for ppgtt mm LRU list + - drm/bridge: tc358767: fix poll timeouts + - drm/i915/gt: Protect defer_request() from new waiters + - drm/msm/dpu: fix BGR565 vs RGB565 confusion + - scsi: Revert "RDMA/isert: Fix a recently introduced regression related to + logout" + - scsi: Revert "target: iscsi: Wait for all commands to finish before freeing + a session" + - usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus + - usb: dwc2: Fix in ISOC request length checking + - staging: rtl8723bs: fix copy of overlapping memory + - staging: greybus: use after free in gb_audio_manager_remove_all() + - ASoC: atmel: fix atmel_ssc_set_audio link failure + - ASoC: fsl_sai: Fix exiting path on probing failure + - ecryptfs: replace BUG_ON with error handling code + - iommu/vt-d: Fix compile warning from intel-svm.h + - crypto: rename sm3-256 to sm3 in hash_algo_name + - genirq/proc: Reject invalid affinity masks (again) + - bpf, offload: Replace bitwise AND by logical AND in + bpf_prog_offload_info_fill + - arm64: lse: Fix LSE atomics with LLVM + - io_uring: fix __io_iopoll_check deadlock in io_sq_thread + - ALSA: rawmidi: Avoid bit fields for state flags + - ALSA: seq: Avoid concurrent access to queue flags + - ALSA: seq: Fix concurrent access to queue current tick/time + - netfilter: xt_hashlimit: limit the max size of hashtable + - rxrpc: Fix call RCU cleanup using non-bh-safe locks + - io_uring: prevent sq_thread from spinning when it should stop + - ata: ahci: Add shutdown to freeze hardware resources of ahci + - xen: Enable interrupts when calling _cond_resched() + - net/mlx5e: Reset RQ doorbell counter before moving RQ state from RST to RDY + - net/mlx5: Fix sleep while atomic in mlx5_eswitch_get_vepa + - net/mlx5e: Fix crash in recovery flow without devlink reporter + - s390/kaslr: Fix casts in get_random + - s390/mm: Explicitly compare PAGE_DEFAULT_KEY against zero in + storage_key_init_range + - bpf: Selftests build error in sockmap_basic.c + - ASoC: SOF: Intel: hda: Add iDisp4 DAI + - Linux 5.4.23 + * Miscellaneous Ubuntu changes + - SAUCE: selftests/net -- disable timeout + - SAUCE: selftests/net -- disable l2tp.sh test + - SAUCE: selftests/ftrace: Use printf instead of echo in kprobe syntax error + tests + - SAUCE: selftests/powerpc -- Disable timeout for benchmark and tm tests + - SAUCE: selftests/ftrace: Escape additional strings in kprobe syntax error + tests + - SAUCE: Revert "UBUNTU: SAUCE: blk/core: Gracefully handle unset + make_request_fn" + - [Packaging] prevent duplicated entries in modules.ignore + - update dkms package versions + + -- Paolo Pisati Mon, 09 Mar 2020 12:16:41 +0100 + +linux-oracle (5.4.0-1004.4) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1004.4 -proposed tracker (LP: #1865024) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.4.0-17.21 ] + + * focal/linux: 5.4.0-17.20 -proposed tracker (LP: #1865025) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Miscellaneous Ubuntu changes + - SAUCE: drm/i915/execlists: fix off by one in execlists_update_context() + + [ Ubuntu: 5.4.0-16.19 ] + + * focal/linux: 5.4.0-16.19 -proposed tracker (LP: #1864889) + * system hang: i915 Resetting rcs0 for hang on rcs0 (LP: #1861395) + - drm/i915/execlists: Always force a context reload when rewinding RING_TAIL + * nsleep-lat / set-timer-lat / inconsistency-check / raw_skew from timer in + ubuntu_kernel_selftests timeout on 5.3 / 5.4 (LP: #1864626) + - selftests/timers: Turn off timeout setting + * [sfc-0121]enable the HiSilicon v3xx SFC driver (LP: #1860401) + - spi: Add HiSilicon v3xx SPI NOR flash controller driver + - MAINTAINERS: Add a maintainer for the HiSilicon v3xx SFC driver + - [Config] CONFIG_SPI_HISI_SFC_V3XX=m + * [hns3-0217]sync mainline kernel 5.6rc1 hns3 patchset into ubuntu HWE kernel + branch (LP: #1863575) + - net: hns3: add management table after IMP reset + - net: hns3: fix VF bandwidth does not take effect in some case + - net: hns3: fix a copying IPv6 address error in hclge_fd_get_flow_tuples() + * [hns3-0111]sync mainline kernel 5.5rc6 hns3 patchset into ubuntu HWE kernel + branch Edit (LP: #1859261) + - net: hns3: schedule hclgevf_service by using delayed workqueue + - net: hns3: remove mailbox and reset work in hclge_main + - net: hns3: remove unnecessary work in hclgevf_main + - net: hns3: allocate WQ with WQ_MEM_RECLAIM flag + - net: hns3: do not schedule the periodic task when reset fail + - net: hns3: check FE bit before calling hns3_add_frag() + - net: hns3: remove useless mutex vport_cfg_mutex in the struct hclge_dev + - net: hns3: optimization for CMDQ uninitialization + - net: hns3: get FD rules location before dump in debugfs + - net: hns3: implement ndo_features_check ops for hns3 driver + - net: hns3: add some VF VLAN information for command "ip link show" + - net: hns3: add a log for getting chain failure in + hns3_nic_uninit_vector_data() + - net: hns3: only print misc interrupt status when handling fails + - net: hns3: add trace event support for HNS3 driver + - net: hns3: re-organize vector handle + - net: hns3: modify the IRQ name of TQP vector + - net: hns3: modify an unsuitable log in hclge_map_ring_to_vector() + - net: hns3: modify the IRQ name of misc vectors + - net: hns3: add protection when get SFP speed as 0 + - net: hns3: replace an unsuitable variable type in + hclge_inform_reset_assert_to_vf() + - net: hns3: modify an unsuitable reset level for hardware error + - net: hns3: split hclge_reset() into preparing and rebuilding part + - net: hns3: split hclgevf_reset() into preparing and rebuilding part + - net: hns3: refactor the precedure of PF FLR + - net: hns3: refactor the procedure of VF FLR + - net: hns3: enlarge HCLGE_RESET_WAIT_CNT + - net: hns3: modify hclge_func_reset_sync_vf()'s return type to void + - net: hns3: refactor the notification scheme of PF reset + * alsa/hda/realtek: fix a mute led regression on Lenovo X1 Carbon + (LP: #1864576) + - SAUCE: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1 + * ipc/sem.c : process loops infinitely in exit_sem() (LP: #1858834) + - Revert "ipc, sem: remove uneeded sem_undo_list lock usage in exit_sem()" + * r8152 init may take up to 40 seconds at initialization with Dell WD19/WD19DC + during hotplug (LP: #1864284) + - UBUNTU SAUCE: r8151: check disconnect status after long sleep + * Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU for focal + (LP: #1864198) + - Ubuntu: [Config] Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU + * ftrace test in ubuntu_kernel_selftests will timeout randomly (LP: #1864172) + - tracing/selftests: Turn off timeout setting + * Another Dell AIO backlight issue (LP: #1863880) + - SAUCE: platform/x86: dell-uart-backlight: move retry block + * Backport GetFB2 ioctl (LP: #1863874) + - SAUCE: drm: Add getfb2 ioctl + * [20.04] Allow to reset an opencapi adapter (LP: #1862121) + - powerpc/powernv/ioda: Fix ref count for devices with their own PE + - powerpc/powernv/ioda: Protect PE list + - powerpc/powernv/ioda: set up PE on opencapi device when enabling + - powerpc/powernv/ioda: Release opencapi device + - powerpc/powernv/ioda: Find opencapi slot for a device node + - pci/hotplug/pnv-php: Remove erroneous warning + - pci/hotplug/pnv-php: Improve error msg on power state change failure + - pci/hotplug/pnv-php: Register opencapi slots + - pci/hotplug/pnv-php: Relax check when disabling slot + - pci/hotplug/pnv-php: Wrap warnings in macro + - ocxl: Add PCI hotplug dependency to Kconfig + * alsa/asoc: export the number of dmic to userspace to work with the latest + ucm2 (focal) (LP: #1864400) + - ASoC: add control components management + - ASoC: intel/skl/hda - export number of digital microphones via control + components + * alsa/sof: let sof driver work with topology with volume and led control + (focal) (LP: #1864398) + - ASoC: SOF: enable dual control for pga + - AsoC: SOF: refactor control load code + - ASoC: SOF: acpi led support for switch controls + - ASoC: SOF: topology: check errors when parsing LED tokens + * machine doesn't come up after suspend and re-opening the lid (LP: #1861837) + - ASoC: SOF: trace: fix unconditional free in trace release + * 5.3.0-23-generic causes fans to spin when idle (LP: #1853044) + - drm/i915/gt: Close race between engine_park and intel_gt_retire_requests + - drm/i915/gt: Adapt engine_park synchronisation rules for engine_retire + - drm/i915/gt: Schedule request retirement when timeline idles + * Focal update: 5.4.22 upstream stable release (LP: #1864488) + - core: Don't skip generic XDP program execution for cloned SKBs + - enic: prevent waking up stopped tx queues over watchdog reset + - net/smc: fix leak of kernel memory to user space + - net: dsa: tag_qca: Make sure there is headroom for tag + - net/sched: matchall: add missing validation of TCA_MATCHALL_FLAGS + - net/sched: flower: add missing validation of TCA_FLOWER_FLAGS + - drm/gma500: Fixup fbdev stolen size usage evaluation + - ath10k: Fix qmi init error handling + - wil6210: fix break that is never reached because of zero'ing of a retry + counter + - drm/qxl: Complete exception handling in qxl_device_init() + - rcu/nocb: Fix dump_tree hierarchy print always active + - rcu: Fix missed wakeup of exp_wq waiters + - rcu: Fix data-race due to atomic_t copy-by-value + - f2fs: preallocate DIO blocks when forcing buffered_io + - f2fs: call f2fs_balance_fs outside of locked page + - media: meson: add missing allocation failure check on new_buf + - clk: meson: pll: Fix by 0 division in __pll_params_to_rate() + - cpu/hotplug, stop_machine: Fix stop_machine vs hotplug order + - brcmfmac: Fix memory leak in brcmf_p2p_create_p2pdev() + - brcmfmac: Fix use after free in brcmf_sdio_readframes() + - PCI: Fix pci_add_dma_alias() bitmask size + - drm/amd/display: Map ODM memory correctly when doing ODM combine + - leds: pca963x: Fix open-drain initialization + - ext4: fix ext4_dax_read/write inode locking sequence for IOCB_NOWAIT + - ALSA: ctl: allow TLV read operation for callback type of element in locked + case + - gianfar: Fix TX timestamping with a stacked DSA driver + - pinctrl: sh-pfc: sh7264: Fix CAN function GPIOs + - printk: fix exclusive_console replaying + - drm/mipi_dbi: Fix off-by-one bugs in mipi_dbi_blank() + - drm/msm/adreno: fix zap vs no-zap handling + - pxa168fb: Fix the function used to release some memory in an error handling + path + - media: ov5640: Fix check for PLL1 exceeding max allowed rate + - media: i2c: mt9v032: fix enum mbus codes and frame sizes + - media: sun4i-csi: Deal with DRAM offset + - media: sun4i-csi: Fix data sampling polarity handling + - media: sun4i-csi: Fix [HV]sync polarity handling + - clk: at91: sam9x60: fix programmable clock prescaler + - powerpc/powernv/iov: Ensure the pdn for VFs always contains a valid PE + number + - clk: meson: meson8b: make the CCF use the glitch-free mali mux + - gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in + grgpio_irq_map/unmap() + - iommu/vt-d: Fix off-by-one in PASID allocation + - x86/fpu: Deactivate FPU state after failure during state load + - char/random: silence a lockdep splat with printk() + - media: sti: bdisp: fix a possible sleep-in-atomic-context bug in + bdisp_device_run() + - kernel/module: Fix memleak in module_add_modinfo_attrs() + - IB/core: Let IB core distribute cache update events + - pinctrl: baytrail: Do not clear IRQ flags on direct-irq enabled pins + - efi/x86: Map the entire EFI vendor string before copying it + - MIPS: Loongson: Fix potential NULL dereference in loongson3_platform_init() + - sparc: Add .exit.data section. + - net: ethernet: ixp4xx: Standard module init + - raid6/test: fix a compilation error + - uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol() + - drm/amdgpu/sriov: workaround on rev_id for Navi12 under sriov + - spi: fsl-lpspi: fix only one cs-gpio working + - drm/nouveau/nouveau: fix incorrect sizeof on args.src an args.dst + - usb: gadget: udc: fix possible sleep-in-atomic-context bugs in gr_probe() + - usb: dwc2: Fix IN FIFO allocation + - clocksource/drivers/bcm2835_timer: Fix memory leak of timer + - drm/amd/display: Clear state after exiting fixed active VRR state + - kselftest: Minimise dependency of get_size on C library interfaces + - jbd2: clear JBD2_ABORT flag before journal_reset to update log tail info + when load journal + - ext4: fix deadlock allocating bio_post_read_ctx from mempool + - clk: ti: dra7: fix parent for gmac_clkctrl + - x86/sysfb: Fix check for bad VRAM size + - pwm: omap-dmtimer: Simplify error handling + - udf: Allow writing to 'Rewritable' partitions + - dmaengine: fsl-qdma: fix duplicated argument to && + - wan/hdlc_x25: fix skb handling + - powerpc/iov: Move VF pdev fixup into pcibios_fixup_iov() + - tracing: Fix tracing_stat return values in error handling paths + - tracing: Fix very unlikely race of registering two stat tracers + - ARM: 8952/1: Disable kmemleak on XIP kernels + - ext4, jbd2: ensure panic when aborting with zero errno + - ath10k: Correct the DMA direction for management tx buffers + - rtw88: fix rate mask for 1SS chip + - brcmfmac: sdio: Fix OOB interrupt initialization on brcm43362 + - selftests: settings: tests can be in subsubdirs + - rtc: i2c/spi: Avoid inclusion of REGMAP support when not needed + - drm/amd/display: Retrain dongles when SINK_COUNT becomes non-zero + - tracing: Simplify assignment parsing for hist triggers + - nbd: add a flush_workqueue in nbd_start_device + - KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups + - Btrfs: keep pages dirty when using btrfs_writepage_fixup_worker + - drivers/block/zram/zram_drv.c: fix error return codes not being returned in + writeback_store + - block, bfq: do not plug I/O for bfq_queues with no proc refs + - kconfig: fix broken dependency in randconfig-generated .config + - clk: qcom: Don't overwrite 'cfg' in clk_rcg2_dfs_populate_freq() + - clk: qcom: rcg2: Don't crash if our parent can't be found; return an error + - drm/amdkfd: Fix a bug in SDMA RLC queue counting under HWS mode + - bpf, sockhash: Synchronize_rcu before free'ing map + - drm/amdgpu: remove 4 set but not used variable in + amdgpu_atombios_get_connector_info_from_object_table + - ath10k: correct the tlv len of ath10k_wmi_tlv_op_gen_config_pno_start + - drm/amdgpu: Ensure ret is always initialized when using SOC15_WAIT_ON_RREG + - drm/panel: simple: Add Logic PD Type 28 display support + - arm64: dts: rockchip: Fix NanoPC-T4 cooling maps + - modules: lockdep: Suppress suspicious RCU usage warning + - ASoC: intel: sof_rt5682: Add quirk for number of HDMI DAI's + - ASoC: intel: sof_rt5682: Add support for tgl-max98357a-rt5682 + - regulator: rk808: Lower log level on optional GPIOs being not available + - net/wan/fsl_ucc_hdlc: reject muram offsets above 64K + - NFC: port100: Convert cpu_to_le16(le16_to_cpu(E1) + E2) to use + le16_add_cpu(). + - arm64: dts: allwinner: H6: Add PMU mode + - arm64: dts: allwinner: H5: Add PMU node + - arm: dts: allwinner: H3: Add PMU node + - opp: Free static OPPs on errors while adding them + - selinux: ensure we cleanup the internal AVC counters on error in + avc_insert() + - arm64: dts: qcom: msm8996: Disable USB2 PHY suspend by core + - padata: validate cpumask without removed CPU during offline + - clk: imx: Add correct failure handling for clk based helpers + - ARM: exynos_defconfig: Bring back explicitly wanted options + - ARM: dts: imx6: rdu2: Disable WP for USDHC2 and USDHC3 + - ARM: dts: imx6: rdu2: Limit USBH1 to Full Speed + - bus: ti-sysc: Implement quirk handling for CLKDM_NOAUTO + - PCI: iproc: Apply quirk_paxc_bridge() for module as well as built-in + - media: cx23885: Add support for AVerMedia CE310B + - PCI: Add generic quirk for increasing D3hot delay + - PCI: Increase D3 delay for AMD Ryzen5/7 XHCI controllers + - gpu/drm: ingenic: Avoid null pointer deference in plane atomic update + - selftests/net: make so_txtime more robust to timer variance + - media: v4l2-device.h: Explicitly compare grp{id,mask} to zero in v4l2_device + macros + - reiserfs: Fix spurious unlock in reiserfs_fill_super() error handling + - samples/bpf: Set -fno-stack-protector when building BPF programs + - r8169: check that Realtek PHY driver module is loaded + - fore200e: Fix incorrect checks of NULL pointer dereference + - netfilter: nft_tunnel: add the missing ERSPAN_VERSION nla_policy + - ALSA: usx2y: Adjust indentation in snd_usX2Y_hwdep_dsp_status + - PCI: Add nr_devfns parameter to pci_add_dma_alias() + - PCI: Add DMA alias quirk for PLX PEX NTB + - b43legacy: Fix -Wcast-function-type + - ipw2x00: Fix -Wcast-function-type + - iwlegacy: Fix -Wcast-function-type + - rtlwifi: rtl_pci: Fix -Wcast-function-type + - orinoco: avoid assertion in case of NULL pointer + - drm/amdgpu: fix KIQ ring test fail in TDR of SRIOV + - clk: qcom: smd: Add missing bimc clock + - ACPICA: Disassembler: create buffer fields in ACPI_PARSE_LOAD_PASS1 + - nfsd: Clone should commit src file metadata too + - scsi: ufs: Complete pending requests in host reset and restore path + - scsi: aic7xxx: Adjust indentation in ahc_find_syncrate + - crypto: inside-secure - add unspecified HAS_IOMEM dependency + - drm/mediatek: handle events when enabling/disabling crtc + - clk: renesas: rcar-gen3: Allow changing the RPC[D2] clocks + - ARM: dts: r8a7779: Add device node for ARM global timer + - selinux: ensure we cleanup the internal AVC counters on error in + avc_update() + - scsi: lpfc: Fix: Rework setting of fdmi symbolic node name registration + - arm64: dts: qcom: db845c: Enable ath10k 8bit host-cap quirk + - iommu/amd: Check feature support bit before accessing MSI capability + registers + - iommu/amd: Only support x2APIC with IVHD type 11h/40h + - iommu/iova: Silence warnings under memory pressure + - clk: actually call the clock init before any other callback of the clock + - dmaengine: Store module owner in dma_device struct + - dmaengine: imx-sdma: Fix memory leak + - bpf: Print error message for bpftool cgroup show + - net: phy: realtek: add logging for the RGMII TX delay configuration + - crypto: chtls - Fixed memory leak + - x86/vdso: Provide missing include file + - PM / devfreq: exynos-ppmu: Fix excessive stack usage + - PM / devfreq: rk3399_dmc: Add COMPILE_TEST and HAVE_ARM_SMCCC dependency + - drm/fbdev: Fallback to non tiled mode if all tiles not present + - pinctrl: sh-pfc: sh7269: Fix CAN function GPIOs + - reset: uniphier: Add SCSSI reset control for each channel + - ASoC: soc-topology: fix endianness issues + - fbdev: fix numbering of fbcon options + - RDMA/rxe: Fix error type of mmap_offset + - clk: sunxi-ng: add mux and pll notifiers for A64 CPU clock + - ALSA: sh: Fix unused variable warnings + - clk: Use parent node pointer during registration if necessary + - clk: uniphier: Add SCSSI clock gate for each channel + - ALSA: hda/realtek - Apply mic mute LED quirk for Dell E7xx laptops, too + - ALSA: sh: Fix compile warning wrt const + - net: phy: fixed_phy: fix use-after-free when checking link GPIO + - tools lib api fs: Fix gcc9 stringop-truncation compilation error + - vfio/spapr/nvlink2: Skip unpinning pages on error exit + - ASoC: Intel: sof_rt5682: Ignore the speaker amp when there isn't one. + - ACPI: button: Add DMI quirk for Razer Blade Stealth 13 late 2019 lid switch + - iommu/vt-d: Match CPU and IOMMU paging mode + - iommu/vt-d: Avoid sending invalid page response + - drm/amdkfd: Fix permissions of hang_hws + - mlx5: work around high stack usage with gcc + - RDMA/hns: Avoid printing address of mtt page + - drm: remove the newline for CRC source name. + - usb: dwc3: use proper initializers for property entries + - ARM: dts: stm32: Add power-supply for DSI panel on stm32f469-disco + - usbip: Fix unsafe unaligned pointer usage + - udf: Fix free space reporting for metadata and virtual partitions + - drm/mediatek: Add gamma property according to hardware capability + - staging: rtl8188: avoid excessive stack usage + - IB/hfi1: Add software counter for ctxt0 seq drop + - IB/hfi1: Add RcvShortLengthErrCnt to hfi1stats + - soc/tegra: fuse: Correct straps' address for older Tegra124 device trees + - efi/x86: Don't panic or BUG() on non-critical error conditions + - rcu: Use WRITE_ONCE() for assignments to ->pprev for hlist_nulls + - Input: edt-ft5x06 - work around first register access error + - bnxt: Detach page from page pool before sending up the stack + - x86/nmi: Remove irq_work from the long duration NMI handler + - wan: ixp4xx_hss: fix compile-testing on 64-bit + - clocksource: davinci: only enable clockevents once tim34 is initialized + - arm64: dts: rockchip: fix dwmmc clock name for px30 + - arm64: dts: rockchip: add reg property to brcmf sub-nodes + - ARM: dts: rockchip: add reg property to brcmf sub node for + rk3188-bqedison2qc + - ALSA: usb-audio: Add boot quirk for MOTU M Series + - ASoC: atmel: fix build error with CONFIG_SND_ATMEL_SOC_DMA=m + - raid6/test: fix a compilation warning + - tty: synclinkmp: Adjust indentation in several functions + - tty: synclink_gt: Adjust indentation in several functions + - misc: xilinx_sdfec: fix xsdfec_poll()'s return type + - visorbus: fix uninitialized variable access + - driver core: platform: Prevent resouce overflow from causing infinite loops + - driver core: Print device when resources present in really_probe() + - ASoC: SOF: Intel: hda-dai: fix compilation warning in pcm_prepare + - bpf: Return -EBADRQC for invalid map type in __bpf_tx_xdp_map + - vme: bridges: reduce stack usage + - drm/nouveau/secboot/gm20b: initialize pointer in gm20b_secboot_new() + - drm/nouveau/gr/gk20a,gm200-: add terminators to method lists read from fw + - drm/nouveau: Fix copy-paste error in nouveau_fence_wait_uevent_handler + - drm/nouveau/drm/ttm: Remove set but not used variable 'mem' + - drm/nouveau/fault/gv100-: fix memory leak on module unload + - dm thin: don't allow changing data device during thin-pool reload + - gpiolib: Set lockdep class for hierarchical irq domains + - drm/vmwgfx: prevent memory leak in vmw_cmdbuf_res_add + - perf/imx_ddr: Fix cpu hotplug state cleanup + - usb: musb: omap2430: Get rid of musb .set_vbus for omap2430 glue + - kbuild: remove *.tmp file when filechk fails + - iommu/arm-smmu-v3: Use WRITE_ONCE() when changing validity of an STE + - ALSA: usb-audio: unlock on error in probe + - f2fs: set I_LINKABLE early to avoid wrong access by vfs + - f2fs: free sysfs kobject + - scsi: ufs: pass device information to apply_dev_quirks + - scsi: ufs-mediatek: add apply_dev_quirks variant operation + - scsi: iscsi: Don't destroy session if there are outstanding connections + - crypto: essiv - fix AEAD capitalization and preposition use in help text + - ALSA: usb-audio: add implicit fb quirk for MOTU M Series + - RDMA/mlx5: Don't fake udata for kernel path + - arm64: lse: fix LSE atomics with LLVM's integrated assembler + - arm64: fix alternatives with LLVM's integrated assembler + - drm/amd/display: fixup DML dependencies + - EDAC/sifive: Fix return value check in ecc_register() + - KVM: PPC: Remove set but not used variable 'ra', 'rs', 'rt' + - arm64: dts: ti: k3-j721e-main: Add missing power-domains for smmu + - sched/core: Fix size of rq::uclamp initialization + - sched/topology: Assert non-NUMA topology masks don't (partially) overlap + - perf/x86/amd: Constrain Large Increment per Cycle events + - watchdog/softlockup: Enforce that timestamp is valid on boot + - debugobjects: Fix various data races + - ASoC: SOF: Intel: hda: Fix SKL dai count + - regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage + - f2fs: fix memleak of kobject + - x86/mm: Fix NX bit clearing issue in kernel_map_pages_in_pgd + - pwm: omap-dmtimer: Remove PWM chip in .remove before making it unfunctional + - cmd64x: potential buffer overflow in cmd64x_program_timings() + - ide: serverworks: potential overflow in svwks_set_pio_mode() + - pwm: Remove set but not set variable 'pwm' + - btrfs: fix possible NULL-pointer dereference in integrity checks + - btrfs: safely advance counter when looking up bio csums + - btrfs: device stats, log when stats are zeroed + - module: avoid setting info->name early in case we can fall back to + info->mod->name + - remoteproc: Initialize rproc_class before use + - regulator: core: Fix exported symbols to the exported GPL version + - irqchip/mbigen: Set driver .suppress_bind_attrs to avoid remove problems + - ALSA: hda/hdmi - add retry logic to parse_intel_hdmi() + - spi: spi-fsl-qspi: Ensure width is respected in spi-mem operations + - kbuild: use -S instead of -E for precise cc-option test in Kconfig + - objtool: Fix ARCH=x86_64 build error + - x86/decoder: Add TEST opcode to Group3-2 + - s390: adjust -mpacked-stack support check for clang 10 + - s390/ftrace: generate traced function stack frame + - driver core: platform: fix u32 greater or equal to zero comparison + - bpf, btf: Always output invariant hit in pahole DWARF to BTF transform + - ALSA: hda - Add docking station support for Lenovo Thinkpad T420s + - sunrpc: Fix potential leaks in sunrpc_cache_unhash() + - drm/nouveau/mmu: fix comptag memory leak + - powerpc/sriov: Remove VF eeh_dev state when disabling SR-IOV + - media: uvcvideo: Add a quirk to force GEO GC6500 Camera bits-per-pixel value + - btrfs: separate definition of assertion failure handlers + - btrfs: Fix split-brain handling when changing FSID to metadata uuid + - bcache: cached_dev_free needs to put the sb page + - bcache: rework error unwinding in register_bcache + - bcache: fix use-after-free in register_bcache() + - iommu/vt-d: Remove unnecessary WARN_ON_ONCE() + - alarmtimer: Make alarmtimer platform device child of RTC device + - selftests: bpf: Reset global state between reuseport test runs + - jbd2: switch to use jbd2_journal_abort() when failed to submit the commit + record + - jbd2: make sure ESHUTDOWN to be recorded in the journal superblock + - powerpc/pseries/lparcfg: Fix display of Maximum Memory + - selftests/eeh: Bump EEH wait time to 60s + - ARM: 8951/1: Fix Kexec compilation issue. + - ALSA: usb-audio: add quirks for Line6 Helix devices fw>=2.82 + - hostap: Adjust indentation in prism2_hostapd_add_sta + - rtw88: fix potential NULL skb access in TX ISR + - iwlegacy: ensure loop counter addr does not wrap and cause an infinite loop + - cifs: fix unitialized variable poential problem with network I/O cache lock + patch + - cifs: Fix mount options set in automount + - cifs: fix NULL dereference in match_prepath + - bpf: map_seq_next should always increase position index + - powerpc/mm: Don't log user reads to 0xffffffff + - ceph: check availability of mds cluster on mount after wait timeout + - rbd: work around -Wuninitialized warning + - drm/amd/display: do not allocate display_mode_lib unnecessarily + - irqchip/gic-v3: Only provision redistributors that are enabled in ACPI + - drm/nouveau/disp/nv50-: prevent oops when no channel method map provided + - char: hpet: Fix out-of-bounds read bug + - ftrace: fpid_next() should increase position index + - trigger_next should increase position index + - radeon: insert 10ms sleep in dce5_crtc_load_lut + - powerpc: Do not consider weak unresolved symbol relocations as bad + - btrfs: do not do delalloc reservation under page lock + - ocfs2: make local header paths relative to C files + - ocfs2: fix a NULL pointer dereference when call + ocfs2_update_inode_fsync_trans() + - lib/scatterlist.c: adjust indentation in __sg_alloc_table + - reiserfs: prevent NULL pointer dereference in reiserfs_insert_item() + - bcache: fix memory corruption in bch_cache_accounting_clear() + - bcache: explicity type cast in bset_bkey_last() + - bcache: fix incorrect data type usage in btree_flush_write() + - irqchip/gic-v3-its: Reference to its_invall_cmd descriptor when building + INVALL + - nvmet: Pass lockdep expression to RCU lists + - nvme-pci: remove nvmeq->tags + - iwlwifi: mvm: Fix thermal zone registration + - iwlwifi: mvm: Check the sta is not NULL in iwl_mvm_cfg_he_sta() + - asm-generic/tlb: add missing CONFIG symbol + - microblaze: Prevent the overflow of the start + - brd: check and limit max_part par + - drm/amdgpu/smu10: fix smu10_get_clock_by_type_with_latency + - drm/amdgpu/smu10: fix smu10_get_clock_by_type_with_voltage + - NFS: Fix memory leaks + - help_next should increase position index + - i40e: Relax i40e_xsk_wakeup's return value when PF is busy + - cifs: log warning message (once) if out of disk space + - virtio_balloon: prevent pfn array overflow + - fuse: don't overflow LLONG_MAX with end offset + - mlxsw: spectrum_dpipe: Add missing error path + - drm/amdgpu/display: handle multiple numbers of fclks in dcn_calcs.c (v2) + - bcache: properly initialize 'path' and 'err' in register_bcache() + - rtc: Kconfig: select REGMAP_I2C when necessary + - Linux 5.4.22 + * Focal update: 5.4.22 upstream stable release (LP: #1864488) // + CVE-2019-19076. + - Revert "nfp: abm: fix memory leak in nfp_abm_u32_knode_replace" + * Miscellaneous Ubuntu changes + - [Debian] Revert "UBUNTU: [Debian] Update linux source package name in + debian/tests/*" + - SAUCE: selftests: fix undefined lable cleanup build error + - SAUCE: selftests: fix undefined macro RET_IF() build error + - [Packaging] Include modules.builtin.modinfo in linux-modules + - update dkms package versions + - Revert "UBUNTU: [Debian] Update package name in getabis repo list" + * Miscellaneous upstream changes + - libbpf: Extract and generalize CPU mask parsing logic + + -- Paolo Pisati Mon, 02 Mar 2020 11:33:37 +0100 + +linux-oracle (5.4.0-1003.3) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1003.3 -proposed tracker (LP: #1864084) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following rebase to 5.4.0-15.18 + + [ Ubuntu: 5.4.0-15.18 ] + + * focal/linux: 5.4.0-15.18 -proposed tracker (LP: #1864085) + * Focal update: v5.4.21 upstream stable release (LP: #1864046) + - Input: synaptics - switch T470s to RMI4 by default + - Input: synaptics - enable SMBus on ThinkPad L470 + - Input: synaptics - remove the LEN0049 dmi id from topbuttonpad list + - ALSA: usb-audio: Fix UAC2/3 effect unit parsing + - ALSA: hda/realtek - Add more codec supported Headset Button + - ALSA: hda/realtek - Fix silent output on MSI-GL73 + - ALSA: usb-audio: Apply sample rate quirk for Audioengine D1 + - ACPI: EC: Fix flushing of pending work + - ACPI: PM: s2idle: Avoid possible race related to the EC GPE + - ACPICA: Introduce acpi_any_gpe_status_set() + - ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system + - ALSA: usb-audio: sound: usb: usb true/false for bool return type + - ALSA: usb-audio: Add clock validity quirk for Denon MC7000/MCX8000 + - ext4: don't assume that mmp_nodename/bdevname have NUL + - ext4: fix support for inode sizes > 1024 bytes + - ext4: fix checksum errors with indexed dirs + - ext4: add cond_resched() to ext4_protect_reserved_inode + - ext4: improve explanation of a mount failure caused by a misconfigured + kernel + - Btrfs: fix race between using extent maps and merging them + - btrfs: ref-verify: fix memory leaks + - btrfs: print message when tree-log replay starts + - btrfs: log message when rw remount is attempted with unclean tree-log + - ARM: npcm: Bring back GPIOLIB support + - gpio: xilinx: Fix bug where the wrong GPIO register is written to + - arm64: ssbs: Fix context-switch when SSBS is present on all CPUs + - xprtrdma: Fix DMA scatter-gather list mapping imbalance + - cifs: make sure we do not overflow the max EA buffer size + - EDAC/sysfs: Remove csrow objects on errors + - EDAC/mc: Fix use-after-free and memleaks during device removal + - KVM: nVMX: Use correct root level for nested EPT shadow page tables + - perf/x86/amd: Add missing L2 misses event spec to AMD Family 17h's event map + - s390/pkey: fix missing length of protected key on return + - s390/uv: Fix handling of length extensions + - drm/vgem: Close use-after-free race in vgem_gem_create + - drm/panfrost: Make sure the shrinker does not reclaim referenced BOs + - bus: moxtet: fix potential stack buffer overflow + - nvme: fix the parameter order for nvme_get_log in nvme_get_fw_slot_info + - drivers: ipmi: fix off-by-one bounds check that leads to a out-of-bounds + write + - IB/mlx5: Return failure when rts2rts_qp_counters_set_id is not supported + - IB/hfi1: Acquire lock to release TID entries when user file is closed + - IB/hfi1: Close window for pq and request coliding + - IB/rdmavt: Reset all QPs when the device is shut down + - IB/umad: Fix kernel crash while unloading ib_umad + - RDMA/core: Fix invalid memory access in spec_filter_size + - RDMA/iw_cxgb4: initiate CLOSE when entering TERM + - RDMA/hfi1: Fix memory leak in _dev_comp_vect_mappings_create + - RDMA/rxe: Fix soft lockup problem due to using tasklets in softirq + - RDMA/core: Fix protection fault in get_pkey_idx_qp_list + - s390/time: Fix clk type in get_tod_clock + - sched/uclamp: Reject negative values in cpu_uclamp_write() + - spmi: pmic-arb: Set lockdep class for hierarchical irq domains + - perf/x86/intel: Fix inaccurate period in context switch for auto-reload + - hwmon: (pmbus/ltc2978) Fix PMBus polling of MFR_COMMON definitions. + - mac80211: fix quiet mode activation in action frames + - cifs: fix mount option display for sec=krb5i + - arm64: dts: fast models: Fix FVP PCI interrupt-map property + - KVM: x86: Mask off reserved bit from #DB exception payload + - perf stat: Don't report a null stalled cycles per insn metric + - NFSv4.1 make cachethis=no for writes + - Revert "drm/sun4i: drv: Allow framebuffer modifiers in mode config" + - jbd2: move the clearing of b_modified flag to the journal_unmap_buffer() + - jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer + - ext4: choose hardlimit when softlimit is larger than hardlimit in + ext4_statfs_project() + - KVM: x86/mmu: Fix struct guest_walker arrays for 5-level paging + - gpio: add gpiod_toggle_active_low() + - mmc: core: Rework wp-gpio handling + - Linux 5.4.21 + * Fix AMD Stoney Ridge screen flickering under 4K resolution (LP: #1864005) + - iommu/amd: Disable IOMMU on Stoney Ridge systems + * Focal Fossa (20.04) feature request - Enable CONFIG_X86_UV (LP: #1863810) + - [Config] CONFIG_X86_UV=y + * [UBUNTU 20.04] Enable proper reset/recovery of s390x/pci functions in error + state (LP: #1863768) + - s390/pci: Recover handle in clp_set_pci_fn() + - s390/pci: Fix possible deadlock in recover_store() + * [20.04 FEAT] Enhanced handling of secure keys and protected keys + (LP: #1853303) + - s390/zcrypt: enable card/domain autoselect on ep11 cprbs + - s390/zcrypt: ep11 structs rework, export zcrypt_send_ep11_cprb + - s390/zcrypt: add new low level ep11 functions support file + - s390/zcrypt: extend EP11 card and queue sysfs attributes + - s390/pkey/zcrypt: Support EP11 AES secure keys + * [20.04 FEAT] paes self test (LP: #1854948) + - s390/pkey: use memdup_user() to simplify code + - s390/pkey: Add support for key blob with clear key value + - s390/crypto: Rework on paes implementation + - s390/crypto: enable clear key values for paes ciphers + - crypto/testmgr: enable selftests for paes-s390 ciphers + * Sometimes can't adjust brightness on Dell AIO (LP: #1862885) + - SAUCE: platform/x86: dell-uart-backlight: increase retry times + * change the ASoC card name and card longname to meet the requirement of alsa- + lib-1.2.1 (Focal) (LP: #1862712) + - ASoC: improve the DMI long card code in asoc-core + - ASoC: DMI long name - avoid to add board name if matches with product name + - ASoC: intel - fix the card names + * Support Headset Mic on HP cPC (LP: #1862313) + - ALSA: hda/realtek - Add Headset Mic supported for HP cPC + - ALSA: hda/realtek - Fixed one of HP ALC671 platform Headset Mic supported + * [hns3-0205]sync mainline kernel 5.5rc7 hns3 patchset into ubuntu HWE kernel + branch (LP: #1861972) + - net: hns3: replace snprintf with scnprintf in hns3_dbg_cmd_read + - net: hns3: replace snprintf with scnprintf in hns3_update_strings + - net: hns3: limit the error logging in the hns3_clean_tx_ring() + - net: hns3: do not reuse pfmemalloc pages + - net: hns3: set VF's default reset_type to HNAE3_NONE_RESET + - net: hns3: move duplicated macro definition into header + - net: hns3: refine the input parameter 'size' for snprintf() + - net: hns3: rewrite a log in hclge_put_vector() + - net: hns3: delete unnecessary blank line and space for cleanup + - net: hns3: remove redundant print on ENOMEM + * [acc-0205]sync mainline kernel 5.5rc6 acc patchset into ubuntu HWE kernel + branch (LP: #1861976) + - crypto: hisilicon/sec2 - Use atomics instead of __sync + - crypto: hisilicon - still no need to check return value of debugfs_create + functions + - crypto: hisilicon - Update debugfs usage of SEC V2 + - crypto: hisilicon - fix print/comment of SEC V2 + - crypto: hisilicon - Update some names on SEC V2 + - crypto: hisilicon - Update QP resources of SEC V2 + - crypto: hisilicon - Adjust some inner logic + - crypto: hisilicon - Add callback error check + - crypto: hisilicon - Add branch prediction macro + - crypto: hisilicon - redefine skcipher initiation + - crypto: hisilicon - Add aead support on SEC2 + - crypto: hisilicon - Bugfixed tfm leak + - crypto: hisilicon - Fixed some tiny bugs of HPRE + - crypto: hisilicon - adjust hpre_crt_para_get + - crypto: hisilicon - add branch prediction macro + - crypto: hisilicon - fix spelling mistake "disgest" -> "digest" + * [spi-0115]spi: dw: use "smp_mb()" to avoid sending spi data error + (LP: #1859744) + - spi: dw: use "smp_mb()" to avoid sending spi data error + * [tpm-0115]EFI/stub: tpm: enable tpm eventlog function for ARM64 platform + (LP: #1859743) + - efi: libstub/tpm: enable tpm eventlog function for ARM platforms + * Restrict xmon to read-only-mode if kernel is locked down (LP: #1863562) + - powerpc/xmon: Restrict when kernel is locked down + * [CML-H] Add intel_thermal_pch driver support Comet Lake -H (LP: #1853219) + - thermal: intel: intel_pch_thermal: Add Comet Lake (CML) platform support + * Root can lift kernel lockdown via USB/IP (LP: #1861238) + - Revert "UBUNTU: SAUCE: (lockdown) Add a SysRq option to lift kernel + lockdown" + * Dell XPS 13 (7390) Display Flickering - 19.10 (LP: #1849947) + - SAUCE: drm/i915: Disable PSR by default on all platforms + * Focal update: v5.4.20 upstream stable release (LP: #1863589) + - ASoC: pcm: update FE/BE trigger order based on the command + - hv_sock: Remove the accept port restriction + - IB/mlx4: Fix memory leak in add_gid error flow + - IB/srp: Never use immediate data if it is disabled by a user + - IB/mlx4: Fix leak in id_map_find_del + - RDMA/netlink: Do not always generate an ACK for some netlink operations + - RDMA/i40iw: fix a potential NULL pointer dereference + - RDMA/core: Fix locking in ib_uverbs_event_read + - RDMA/uverbs: Verify MR access flags + - RDMA/cma: Fix unbalanced cm_id reference count during address resolve + - RDMA/umem: Fix ib_umem_find_best_pgsz() + - scsi: ufs: Fix ufshcd_probe_hba() reture value in case + ufshcd_scsi_add_wlus() fails + - PCI/IOV: Fix memory leak in pci_iov_add_virtfn() + - ath10k: pci: Only dump ATH10K_MEM_REGION_TYPE_IOREG when safe + - PCI/switchtec: Use dma_set_mask_and_coherent() + - PCI/switchtec: Fix vep_vector_number ioread width + - PCI: tegra: Fix afi_pex2_ctrl reg offset for Tegra30 + - PCI: Don't disable bridge BARs when assigning bus resources + - PCI/AER: Initialize aer_fifo + - iwlwifi: mvm: avoid use after free for pmsr request + - bpftool: Don't crash on missing xlated program instructions + - bpf, sockmap: Don't sleep while holding RCU lock on tear-down + - bpf, sockhash: Synchronize_rcu before free'ing map + - selftests/bpf: Test freeing sockmap/sockhash with a socket in it + - bpf: Improve bucket_log calculation logic + - bpf, sockmap: Check update requirements after locking + - nfs: NFS_SWAP should depend on SWAP + - NFS: Revalidate the file size on a fatal write error + - NFS/pnfs: Fix pnfs_generic_prepare_to_resend_writes() + - NFS: Fix fix of show_nfs_errors + - NFSv4: pnfs_roc() must use cred_fscmp() to compare creds + - NFSv4: try lease recovery on NFS4ERR_EXPIRED + - NFSv4.0: nfs4_do_fsinfo() should not do implicit lease renewals + - x86/boot: Handle malformed SRAT tables during early ACPI parsing + - rtc: hym8563: Return -EINVAL if the time is known to be invalid + - rtc: cmos: Stop using shared IRQ + - watchdog: qcom: Use platform_get_irq_optional() for bark irq + - ARC: [plat-axs10x]: Add missing multicast filter number to GMAC node + - platform/x86: intel_mid_powerbtn: Take a copy of ddata + - arm64: dts: qcom: msm8998: Fix tcsr syscon size + - arm64: dts: uDPU: fix broken ethernet + - ARM: dts: at91: Reenable UART TX pull-ups + - ARM: dts: am43xx: add support for clkout1 clock + - arm64: dts: renesas: r8a77990: ebisu: Remove clkout-lr-synchronous from + sound + - arm64: dts: marvell: clearfog-gt-8k: fix switch cpu port node + - ARM: dts: meson8: use the actual frequency for the GPU's 182.1MHz OPP + - ARM: dts: meson8b: use the actual frequency for the GPU's 364MHz OPP + - ARM: dts: at91: sama5d3: fix maximum peripheral clock rates + - ARM: dts: at91: sama5d3: define clock rate range for tcb1 + - tools/power/acpi: fix compilation error + - soc: qcom: rpmhpd: Set 'active_only' for active only power domains + - Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" + - powerpc/ptdump: Fix W+X verification call in mark_rodata_ro() + - powerpc/ptdump: Only enable PPC_CHECK_WX with STRICT_KERNEL_RWX + - powerpc/papr_scm: Fix leaking 'bus_desc.provider_name' in some paths + - powerpc/pseries/vio: Fix iommu_table use-after-free refcount warning + - powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce + for DDW + - iommu/arm-smmu-v3: Populate VMID field for CMDQ_OP_TLBI_NH_VA + - ARM: at91: pm: use SAM9X60 PMC's compatible + - ARM: at91: pm: use of_device_id array to find the proper shdwc node + - KVM: arm/arm64: vgic-its: Fix restoration of unmapped collections + - ARM: 8949/1: mm: mark free_memmap as __init + - sched/uclamp: Fix a bug in propagating uclamp value in new cgroups + - arm64: cpufeature: Fix the type of no FP/SIMD capability + - arm64: cpufeature: Set the FP/SIMD compat HWCAP bits properly + - arm64: ptrace: nofpsimd: Fail FP/SIMD regset operations + - KVM: arm/arm64: Fix young bit from mmu notifier + - KVM: arm: Fix DFSR setting for non-LPAE aarch32 guests + - KVM: arm: Make inject_abt32() inject an external abort instead + - KVM: arm64: pmu: Don't increment SW_INCR if PMCR.E is unset + - KVM: arm64: pmu: Fix chained SW_INCR counters + - KVM: arm64: Treat emulated TVAL TimerValue as a signed 32-bit integer + - arm64: nofpsmid: Handle TIF_FOREIGN_FPSTATE flag cleanly + - mtd: onenand_base: Adjust indentation in onenand_read_ops_nolock + - mtd: sharpslpart: Fix unsigned comparison to zero + - crypto: testmgr - don't try to decrypt uninitialized buffers + - crypto: artpec6 - return correct error code for failed setkey() + - crypto: atmel-sha - fix error handling when setting hmac key + - crypto: caam/qi2 - fix typo in algorithm's driver name + - drivers: watchdog: stm32_iwdg: set WDOG_HW_RUNNING at probe + - media: i2c: adv748x: Fix unsafe macros + - dt-bindings: iio: adc: ad7606: Fix wrong maxItems value + - bcache: avoid unnecessary btree nodes flushing in btree_flush_write() + - selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" + - selinux: fix regression introduced by move_mount(2) syscall + - pinctrl: sh-pfc: r8a77965: Fix DU_DOTCLKIN3 drive/bias control + - pinctrl: sh-pfc: r8a7778: Fix duplicate SDSELF_B and SD1_CLK_B + - regmap: fix writes to non incrementing registers + - mfd: max77650: Select REGMAP_IRQ in Kconfig + - clk: meson: g12a: fix missing uart2 in regmap table + - dmaengine: axi-dmac: add a check for devm_regmap_init_mmio + - mwifiex: Fix possible buffer overflows in mwifiex_ret_wmm_get_status() + - mwifiex: Fix possible buffer overflows in mwifiex_cmd_append_vsie_tlv() + - libertas: don't exit from lbs_ibss_join_existing() with RCU read lock held + - libertas: make lbs_ibss_join_existing() return error code on rates overflow + - selinux: fall back to ref-walk if audit is required + - Linux 5.4.20 + * Focal update: v5.4.19 upstream stable release (LP: #1863588) + - sparc32: fix struct ipc64_perm type definition + - bnxt_en: Move devlink_register before registering netdev + - cls_rsvp: fix rsvp_policy + - gtp: use __GFP_NOWARN to avoid memalloc warning + - l2tp: Allow duplicate session creation with UDP + - net: hsr: fix possible NULL deref in hsr_handle_frame() + - net_sched: fix an OOB access in cls_tcindex + - net: stmmac: Delete txtimer in suspend() + - bnxt_en: Fix TC queue mapping. + - rxrpc: Fix use-after-free in rxrpc_put_local() + - rxrpc: Fix insufficient receive notification generation + - rxrpc: Fix missing active use pinning of rxrpc_local object + - rxrpc: Fix NULL pointer deref due to call->conn being cleared on disconnect + - tcp: clear tp->total_retrans in tcp_disconnect() + - tcp: clear tp->delivered in tcp_disconnect() + - tcp: clear tp->data_segs{in|out} in tcp_disconnect() + - tcp: clear tp->segs_{in|out} in tcp_disconnect() + - ionic: fix rxq comp packet type mask + - MAINTAINERS: correct entries for ISDN/mISDN section + - netdevsim: fix stack-out-of-bounds in nsim_dev_debugfs_init() + - bnxt_en: Fix logic that disables Bus Master during firmware reset. + - media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors + - mfd: dln2: More sanity checking for endpoints + - netfilter: ipset: fix suspicious RCU usage in find_set_and_id + - ipc/msg.c: consolidate all xxxctl_down() functions + - tracing/kprobes: Have uname use __get_str() in print_fmt + - tracing: Fix sched switch start/stop refcount racy updates + - rcu: Use *_ONCE() to protect lockless ->expmask accesses + - rcu: Avoid data-race in rcu_gp_fqs_check_wake() + - srcu: Apply *_ONCE() to ->srcu_last_gp_end + - rcu: Use READ_ONCE() for ->expmask in rcu_read_unlock_special() + - nvmet: Fix error print message at nvmet_install_queue function + - nvmet: Fix controller use after free + - Bluetooth: btusb: fix memory leak on fw + - Bluetooth: btusb: Disable runtime suspend on Realtek devices + - brcmfmac: Fix memory leak in brcmf_usbdev_qinit + - usb: dwc3: gadget: Check END_TRANSFER completion + - usb: dwc3: gadget: Delay starting transfer + - usb: typec: tcpci: mask event interrupts when remove driver + - objtool: Silence build output + - usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer + - usb: gadget: legacy: set max_speed to super-speed + - usb: gadget: f_ncm: Use atomic_t to track in-flight request + - usb: gadget: f_ecm: Use atomic_t to track in-flight request + - ALSA: usb-audio: Fix endianess in descriptor validation + - ALSA: usb-audio: Annotate endianess in Scarlett gen2 quirk + - ALSA: dummy: Fix PCM format loop in proc output + - memcg: fix a crash in wb_workfn when a device disappears + - mm/sparse.c: reset section's mem_map when fully deactivated + - mmc: sdhci-pci: Make function amd_sdhci_reset static + - utimes: Clamp the timestamps in notify_change() + - mm/memory_hotplug: fix remove_memory() lockdep splat + - mm: thp: don't need care deferred split queue in memcg charge move path + - mm: move_pages: report the number of non-attempted pages + - media/v4l2-core: set pages dirty upon releasing DMA buffers + - media: v4l2-core: compat: ignore native command codes + - media: v4l2-rect.h: fix v4l2_rect_map_inside() top/left adjustments + - lib/test_kasan.c: fix memory leak in kmalloc_oob_krealloc_more() + - irqdomain: Fix a memory leak in irq_domain_push_irq() + - x86/cpu: Update cached HLE state on write to TSX_CTRL_CPUID_CLEAR + - platform/x86: intel_scu_ipc: Fix interrupt support + - ALSA: hda: Apply aligned MMIO access only conditionally + - ALSA: hda: Add Clevo W65_67SB the power_save blacklist + - ALSA: hda: Add JasperLake PCI ID and codec vid + - arm64: acpi: fix DAIF manipulation with pNMI + - KVM: arm64: Correct PSTATE on exception entry + - KVM: arm/arm64: Correct CPSR on exception entry + - KVM: arm/arm64: Correct AArch32 SPSR on exception entry + - KVM: arm64: Only sign-extend MMIO up to register width + - MIPS: syscalls: fix indentation of the 'SYSNR' message + - MIPS: fix indentation of the 'RELOCS' message + - MIPS: boot: fix typo in 'vmlinux.lzma.its' target + - s390/mm: fix dynamic pagetable upgrade for hugetlbfs + - powerpc/mmu_gather: enable RCU_TABLE_FREE even for !SMP case + - powerpc/ptdump: Fix W+X verification + - powerpc/xmon: don't access ASDR in VMs + - powerpc/pseries: Advance pfn if section is not present in lmb_is_removable() + - powerpc/32s: Fix bad_kuap_fault() + - powerpc/32s: Fix CPU wake-up from sleep mode + - tracing: Fix now invalid var_ref_vals assumption in trace action + - PCI: tegra: Fix return value check of pm_runtime_get_sync() + - PCI: keystone: Fix outbound region mapping + - PCI: keystone: Fix link training retries initiation + - PCI: keystone: Fix error handling when "num-viewport" DT property is not + populated + - mmc: spi: Toggle SPI polarity, do not hardcode it + - ACPI: video: Do not export a non working backlight interface on MSI MS-7721 + boards + - ACPI / battery: Deal with design or full capacity being reported as -1 + - ACPI / battery: Use design-cap for capacity calculations if full-cap is not + available + - ACPI / battery: Deal better with neither design nor full capacity not being + reported + - alarmtimer: Unregister wakeup source when module get fails + - fscrypt: don't print name of busy file when removing key + - ubifs: don't trigger assertion on invalid no-key filename + - ubifs: Fix wrong memory allocation + - ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag + - ubifs: Fix deadlock in concurrent bulk-read and writepage + - mmc: sdhci-of-at91: fix memleak on clk_get failure + - ASoC: SOF: core: free trace on errors + - hv_balloon: Balloon up according to request page number + - mfd: axp20x: Mark AXP20X_VBUS_IPSOUT_MGMT as volatile + - nvmem: core: fix memory abort in cleanup path + - crypto: api - Check spawn->alg under lock in crypto_drop_spawn + - crypto: ccree - fix backlog memory leak + - crypto: ccree - fix AEAD decrypt auth fail + - crypto: ccree - fix pm wrongful error reporting + - crypto: ccree - fix FDE descriptor sequence + - crypto: ccree - fix PM race condition + - padata: Remove broken queue flushing + - fs: allow deduplication of eof block into the end of the destination file + - scripts/find-unused-docs: Fix massive false positives + - erofs: fix out-of-bound read for shifted uncompressed block + - scsi: megaraid_sas: Do not initiate OCR if controller is not in ready state + - scsi: qla2xxx: Fix mtcp dump collection failure + - cpupower: Revert library ABI changes from commit ae2917093fb60bdc1ed3e + - power: supply: axp20x_ac_power: Fix reporting online status + - power: supply: ltc2941-battery-gauge: fix use-after-free + - ovl: fix wrong WARN_ON() in ovl_cache_update_ino() + - ovl: fix lseek overflow on 32bit + - f2fs: choose hardlimit when softlimit is larger than hardlimit in + f2fs_statfs_project() + - f2fs: fix miscounted block limit in f2fs_statfs_project() + - f2fs: code cleanup for f2fs_statfs_project() + - f2fs: fix dcache lookup of !casefolded directories + - f2fs: fix race conditions in ->d_compare() and ->d_hash() + - PM: core: Fix handling of devices deleted during system-wide resume + - cpufreq: Avoid creating excessively large stack frames + - of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc + - ARM: dma-api: fix max_pfn off-by-one error in __dma_supported() + - dm zoned: support zone sizes smaller than 128MiB + - dm space map common: fix to ensure new block isn't already in use + - dm writecache: fix incorrect flush sequence when doing SSD mode commit + - dm crypt: fix GFP flags passed to skcipher_request_alloc() + - dm crypt: fix benbi IV constructor crash if used in authenticated mode + - dm thin metadata: use pool locking at end of dm_pool_metadata_close + - scsi: qla2xxx: Fix stuck login session using prli_pend_timer + - ASoC: SOF: Introduce state machine for FW boot + - ASoC: SOF: core: release resources on errors in probe_continue + - tracing: Annotate ftrace_graph_hash pointer with __rcu + - tracing: Annotate ftrace_graph_notrace_hash pointer with __rcu + - ftrace: Add comment to why rcu_dereference_sched() is open coded + - ftrace: Protect ftrace_graph_hash with ftrace_sync + - crypto: pcrypt - Avoid deadlock by using per-instance padata queues + - btrfs: fix improper setting of scanned for range cyclic write cache pages + - btrfs: Handle another split brain scenario with metadata uuid feature + - riscv, bpf: Fix broken BPF tail calls + - selftests/bpf: Fix perf_buffer test on systems w/ offline CPUs + - bpf, devmap: Pass lockdep expression to RCU lists + - libbpf: Fix realloc usage in bpf_core_find_cands + - tc-testing: fix eBPF tests failure on linux fresh clones + - samples/bpf: Don't try to remove user's homedir on clean + - samples/bpf: Xdp_redirect_cpu fix missing tracepoint attach + - selftests/bpf: Fix test_attach_probe + - selftests/bpf: Skip perf hw events test if the setup disabled it + - selftests: bpf: Use a temporary file in test_sockmap + - selftests: bpf: Ignore FIN packets for reuseport tests + - crypto: api - fix unexpectedly getting generic implementation + - crypto: hisilicon - Use the offset fields in sqe to avoid need to split + scatterlists + - crypto: ccp - set max RSA modulus size for v3 platform devices as well + - crypto: arm64/ghash-neon - bump priority to 150 + - crypto: pcrypt - Do not clear MAY_SLEEP flag in original request + - crypto: atmel-aes - Fix counter overflow in CTR mode + - crypto: api - Fix race condition in crypto_spawn_alg + - crypto: picoxcell - adjust the position of tasklet_init and fix missed + tasklet_kill + - powerpc/futex: Fix incorrect user access blocking + - scsi: qla2xxx: Fix unbound NVME response length + - NFS: Fix memory leaks and corruption in readdir + - NFS: Directory page cache pages need to be locked when read + - nfsd: fix filecache lookup + - jbd2_seq_info_next should increase position index + - ext4: fix deadlock allocating crypto bounce page from mempool + - ext4: fix race conditions in ->d_compare() and ->d_hash() + - Btrfs: fix missing hole after hole punching and fsync when using NO_HOLES + - Btrfs: make deduplication with range including the last block work + - Btrfs: fix infinite loop during fsync after rename operations + - btrfs: set trans->drity in btrfs_commit_transaction + - btrfs: drop log root for dropped roots + - Btrfs: fix race between adding and putting tree mod seq elements and nodes + - btrfs: flush write bio if we loop in extent_write_cache_pages + - btrfs: Correctly handle empty trees in find_first_clear_extent_bit + - ARM: tegra: Enable PLLP bypass during Tegra124 LP1 + - iwlwifi: don't throw error when trying to remove IGTK + - mwifiex: fix unbalanced locking in mwifiex_process_country_ie() + - sunrpc: expiry_time should be seconds not timeval + - gfs2: fix gfs2_find_jhead that returns uninitialized jhead with seq 0 + - gfs2: move setting current->backing_dev_info + - gfs2: fix O_SYNC write handling + - drm: atmel-hlcdc: use double rate for pixel clock only if supported + - drm: atmel-hlcdc: enable clock before configuring timing engine + - drm: atmel-hlcdc: prefer a lower pixel-clock than requested + - drm/rect: Avoid division by zero + - media: iguanair: fix endpoint sanity check + - media: rc: ensure lirc is initialized before registering input device + - tools/kvm_stat: Fix kvm_exit filter name + - xen/balloon: Support xend-based toolstack take two + - watchdog: fix UAF in reboot notifier handling in watchdog core code + - bcache: add readahead cache policy options via sysfs interface + - eventfd: track eventfd_signal() recursion depth + - aio: prevent potential eventfd recursion on poll + - KVM: x86: Refactor picdev_write() to prevent Spectre-v1/L1TF attacks + - KVM: x86: Refactor prefix decoding to prevent Spectre-v1/L1TF attacks + - KVM: x86: Protect pmu_intel.c from Spectre-v1/L1TF attacks + - KVM: x86: Protect DR-based index computations from Spectre-v1/L1TF attacks + - KVM: x86: Protect kvm_lapic_reg_write() from Spectre-v1/L1TF attacks + - KVM: x86: Protect kvm_hv_msr_[get|set]_crash_data() from Spectre-v1/L1TF + attacks + - KVM: x86: Protect ioapic_write_indirect() from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations in pmu.h from Spectre-v1/L1TF + attacks + - KVM: x86: Protect ioapic_read_indirect() from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations from Spectre-v1/L1TF attacks + in x86.c + - KVM: x86: Protect x86_decode_insn from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations in fixed_msr_to_seg_unit() + from Spectre-v1/L1TF attacks + - KVM: x86: Fix potential put_fpu() w/o load_fpu() on MPX platform + - KVM: PPC: Book3S HV: Uninit vCPU if vcore creation fails + - KVM: PPC: Book3S PR: Free shared page if mmu initialization fails + - kvm/svm: PKU not currently supported + - KVM: VMX: Add non-canonical check on writes to RTIT address MSRs + - KVM: x86: Don't let userspace set host-reserved cr4 bits + - KVM: x86: Free wbinvd_dirty_mask if vCPU creation fails + - KVM: x86: Handle TIF_NEED_FPU_LOAD in kvm_{load,put}_guest_fpu() + - KVM: x86: Ensure guest's FPU state is loaded when accessing for emulation + - KVM: x86: Revert "KVM: X86: Fix fpu state crash in kvm guest" + - KVM: s390: do not clobber registers during guest reset/store status + - ocfs2: fix oops when writing cloned file + - mm/page_alloc.c: fix uninitialized memmaps on a partially populated last + section + - arm64: dts: qcom: qcs404-evb: Set vdd_apc regulator in high power mode + - mm/mmu_gather: invalidate TLB correctly on batch allocation failure and + flush + - clk: tegra: Mark fuse clock as critical + - drm/amd/dm/mst: Ignore payload update failures + - virtio-balloon: initialize all vq callbacks + - virtio-pci: check name when counting MSI-X vectors + - fix up iter on short count in fuse_direct_io() + - broken ping to ipv6 linklocal addresses on debian buster + - percpu: Separate decrypted varaibles anytime encryption can be enabled + - ASoC: meson: axg-fifo: fix fifo threshold setup + - scsi: qla2xxx: Fix the endianness of the qla82xx_get_fw_size() return type + - scsi: csiostor: Adjust indentation in csio_device_reset + - scsi: qla4xxx: Adjust indentation in qla4xxx_mem_free + - scsi: ufs: Recheck bkops level if bkops is disabled + - mtd: spi-nor: Split mt25qu512a (n25q512a) entry into two + - phy: qualcomm: Adjust indentation in read_poll_timeout + - ext2: Adjust indentation in ext2_fill_super + - powerpc/44x: Adjust indentation in ibm4xx_denali_fixup_memsize + - drm: msm: mdp4: Adjust indentation in mdp4_dsi_encoder_enable + - NFC: pn544: Adjust indentation in pn544_hci_check_presence + - ppp: Adjust indentation into ppp_async_input + - net: smc911x: Adjust indentation in smc911x_phy_configure + - net: tulip: Adjust indentation in {dmfe, uli526x}_init_module + - IB/mlx5: Fix outstanding_pi index for GSI qps + - IB/core: Fix ODP get user pages flow + - nfsd: fix delay timer on 32-bit architectures + - nfsd: fix jiffies/time_t mixup in LRU list + - nfsd: Return the correct number of bytes written to the file + - virtio-balloon: Fix memory leak when unloading while hinting is in progress + - virtio_balloon: Fix memory leaks on errors in virtballoon_probe() + - ubi: fastmap: Fix inverted logic in seen selfcheck + - ubi: Fix an error pointer dereference in error handling code + - ubifs: Fix memory leak from c->sup_node + - regulator: core: Add regulator_is_equal() helper + - ASoC: sgtl5000: Fix VDDA and VDDIO comparison + - bonding/alb: properly access headers in bond_alb_xmit() + - devlink: report 0 after hitting end in region read + - dpaa_eth: support all modes with rate adapting PHYs + - net: dsa: b53: Always use dev->vlan_enabled in b53_configure_vlan() + - net: dsa: bcm_sf2: Only 7278 supports 2Gb/sec IMP port + - net: dsa: microchip: enable module autoprobe + - net: mvneta: move rx_dropped and rx_errors in per-cpu stats + - net_sched: fix a resource leak in tcindex_set_parms() + - net: stmmac: fix a possible endless loop + - net: systemport: Avoid RBUF stuck in Wake-on-LAN mode + - net/mlx5: IPsec, Fix esp modify function attribute + - net/mlx5: IPsec, fix memory leak at mlx5_fpga_ipsec_delete_sa_ctx + - net: macb: Remove unnecessary alignment check for TSO + - net: macb: Limit maximum GEM TX length in TSO + - taprio: Fix enabling offload with wrong number of traffic classes + - taprio: Fix still allowing changing the flags during runtime + - taprio: Add missing policy validation for flags + - taprio: Use taprio_reset_tc() to reset Traffic Classes configuration + - taprio: Fix dropping packets when using taprio + ETF offloading + - ipv6/addrconf: fix potential NULL deref in inet6_set_link_af() + - qed: Fix timestamping issue for L2 unicast ptp packets. + - drop_monitor: Do not cancel uninitialized work item + - net/mlx5: Fix deadlock in fs_core + - net/mlx5: Deprecate usage of generic TLS HW capability bit + - ASoC: Intel: skl_hda_dsp_common: Fix global-out-of-bounds bug + - mfd: da9062: Fix watchdog compatible string + - mfd: rn5t618: Mark ADC control register volatile + - mfd: bd70528: Fix hour register mask + - x86/timer: Don't skip PIT setup when APIC is disabled or in legacy mode + - btrfs: use bool argument in free_root_pointers() + - btrfs: free block groups after free'ing fs trees + - drm/dp_mst: Remove VCPI while disabling topology mgr + - KVM: x86/mmu: Apply max PA check for MMIO sptes to 32-bit KVM + - KVM: x86: use CPUID to locate host page table reserved bits + - KVM: x86: Use gpa_t for cr2/gpa to fix TDP support on 32-bit KVM + - KVM: x86: fix overlap between SPTE_MMIO_MASK and generation + - KVM: nVMX: vmread should not set rflags to specify success in case of #PF + - KVM: Use vcpu-specific gva->hva translation when querying host page size + - KVM: Play nice with read-only memslots when querying host page size + - cifs: fail i/o on soft mounts if sessionsetup errors out + - x86/apic/msi: Plug non-maskable MSI affinity race + - clocksource: Prevent double add_timer_on() for watchdog_timer + - perf/core: Fix mlock accounting in perf_mmap() + - rxrpc: Fix service call disconnection + - regulator fix for "regulator: core: Add regulator_is_equal() helper" + - powerpc/kuap: Fix set direction in allow/prevent_user_access() + - Linux 5.4.19 + - [Config] updateconfigs following v5.4.19 stable update + * 5.4.0-11 crash on cryptsetup open (LP: #1860231) // Focal update: v5.4.19 + upstream stable release (LP: #1863588) + - dm: fix potential for q->make_request_fn NULL pointer + * Miscellaneous Ubuntu changes + - update dkms package versions + - [debian] ignore missing wireguard module + - debian: remove snapdragon config, rules and flavour + - [Config] updateconfigs following snapdragon removal + - remove snapdragon abi files + + -- Seth Forshee Fri, 21 Feb 2020 14:16:44 -0600 + +linux-oracle (5.4.0-1002.2) focal; urgency=medium + + * Change source package name to linux-oracle. + + -- Seth Forshee Fri, 21 Feb 2020 13:06:41 -0600 + +linux-oracle-5.4 (5.4.0-1002.2) focal; urgency=medium + + * focal/linux-oracle-5.4: 5.4.0-1002.2 -proposed tracker (LP: #1862254) + + * installing linux-modules-nvidia does not remove nvidia-dkms, and the kernel + prioritizes the wrong version of the module from disk (LP: #1856414) + - Revert "UBUNTU: [Packaging] dkms -- add Provides: specifiers" + + [ Ubuntu: 5.4.0-14.17 ] + + * focal/linux-5.4: 5.4.0-14.17 -proposed tracker (LP: #1862255) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Boot log is swamped with "debugfs: Directory 'imc' with parent 'powerpc' + already present" messages on kernel 5.4 (LP: #1861379) + - powerpc/powernv: Avoid re-registration of imc debugfs directory + * CVE-2019-3016 + - SAUCE: x86/kvm: Be careful not to clear KVM_VCPU_FLUSH_TLB bit + - SAUCE: x86/kvm: Introduce kvm_(un)map_gfn() + - SAUCE: x86/kvm: Cache gfn to pfn translation + - SAUCE: x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed + - SAUCE: x86/KVM: Clean up host's steal time structure + * installing linux-modules-nvidia does not remove nvidia-dkms, and the kernel + prioritizes the wrong version of the module from disk (LP: #1856414) + - Revert "UBUNTU: [Packaging] dkms -- switch basic provides to *-modules" + - Revert "UBUNTU: [Packaging] dkms -- add Provides: specifiers for existing + zfs/nvidia/vbox" + - Revert "UBUNTU: [packaging] dkms-build -- include versioned provides" + - [Packaging] wireguard -- drop provides + * Focal update: v5.4.18 upstream stable release (LP: #1862203) + - vfs: fix do_last() regression + - cifs: fix soft mounts hanging in the reconnect code + - x86/resctrl: Fix a deadlock due to inaccurate reference + - x86/resctrl: Fix use-after-free when deleting resource groups + - x86/resctrl: Fix use-after-free due to inaccurate refcount of rdtgroup + - e1000e: Drop unnecessary __E1000_DOWN bit twiddling + - e1000e: Revert "e1000e: Make watchdog use delayed work" + - gfs2: Another gfs2_find_jhead fix + - perf c2c: Fix return type for histogram sorting comparision functions + - PM / devfreq: Add new name attribute for sysfs + - tools lib: Fix builds when glibc contains strlcpy() + - arm64: kbuild: remove compressed images on 'make ARCH=arm64 (dist)clean' + - mm/mempolicy.c: fix out of bounds write in mpol_parse_str() + - reiserfs: Fix memory leak of journal device string + - media: digitv: don't continue if remote control state can't be read + - media: af9005: uninitialized variable printked + - media: vp7045: do not read uninitialized values if usb transfer fails + - media: gspca: zero usb_buf + - media: dvb-usb/dvb-usb-urb.c: initialize actlen to 0 + - tomoyo: Use atomic_t for statistics counter + - ttyprintk: fix a potential deadlock in interrupt context issue + - Bluetooth: Fix race condition in hci_release_sock() + - cgroup: Prevent double killing of css when enabling threaded cgroup + - clk: sunxi-ng: v3s: Fix incorrect number of hw_clks. + - arm64: dts: meson-sm1-sei610: add gpio bluetooth interrupt + - ARM: dts: sun8i: a83t: Correct USB3503 GPIOs polarity + - ARM: dts: am57xx-beagle-x15/am57xx-idk: Remove "gpios" for endpoint dt nodes + - ARM: dts: beagle-x15-common: Model 5V0 regulator + - soc: ti: wkup_m3_ipc: Fix race condition with rproc_boot + - tools lib traceevent: Fix memory leakage in filter_event + - rseq: Unregister rseq for clone CLONE_VM + - clk: sunxi-ng: sun8i-r: Fix divider on APB0 clock + - clk: sunxi-ng: h6-r: Fix AR100/R_APB2 parent order + - mac80211: mesh: restrict airtime metric to peered established plinks + - clk: mmp2: Fix the order of timer mux parents + - ASoC: rt5640: Fix NULL dereference on module unload + - s390/zcrypt: move ap device reset from bus to driver code + - i40e: Fix virtchnl_queue_select bitmap validation + - ixgbevf: Remove limit of 10 entries for unicast filter list + - ixgbe: Fix calculation of queue with VFs and flow director on interface flap + - igb: Fix SGMII SFP module discovery for 100FX/LX. + - iavf: remove current MAC address filter on VF reset + - platform/x86: GPD pocket fan: Allow somewhat lower/higher temperature limits + - platform/x86: intel_pmc_core: update Comet Lake platform driver + - ASoC: hdac_hda: Fix error in driver removal after failed probe + - ASoC: sti: fix possible sleep-in-atomic + - qmi_wwan: Add support for Quectel RM500Q + - parisc: Use proper printk format for resource_size_t + - lkdtm/bugs: fix build error in lkdtm_UNSET_SMEP + - wireless: fix enabling channel 12 for custom regulatory domain + - cfg80211: Fix radar event during another phy CAC + - mac80211: Fix TKIP replay protection immediately after key setup + - wireless: wext: avoid gcc -O3 warning + - perf/x86/intel/uncore: Add PCI ID of IMC for Xeon E3 V5 Family + - perf/x86/intel/uncore: Remove PCIe3 unit for SNR + - riscv: delete temporary files + - XArray: Fix xas_pause at ULONG_MAX + - iwlwifi: pcie: allocate smaller dev_cmd for TX headers + - iwlwifi: Don't ignore the cap field upon mcc update + - iwlwifi: dbg: force stop the debug monitor HW + - Input: evdev - convert kzalloc()/vzalloc() to kvzalloc() + - ARM: dts: am335x-boneblack-common: fix memory size + - xfrm: interface: do not confirm neighbor when do pmtu update + - Input: max77650-onkey - add of_match table + - scsi: fnic: do not queue commands during fwreset + - ARM: 8955/1: virt: Relax arch timer version check during early boot + - led: max77650: add of_match table + - tee: optee: Fix compilation issue with nommu + - r8152: get default setting of WOL before initializing + - r8152: disable U2P3 for RTL8153B + - r8152: Disable PLA MCU clock speed down + - r8152: disable test IO for RTL8153B + - r8152: avoid the MCU to clear the lanwake + - r8152: disable DelayPhyPwrChg + - ARM: dts: am43x-epos-evm: set data pin directions for spi0 and spi1 + - qlcnic: Fix CPU soft lockup while collecting firmware dump + - powerpc/fsl/dts: add fsl,erratum-a011043 + - net/fsl: treat fsl,erratum-a011043 + - net: fsl/fman: rename IF_MODE_XGMII to IF_MODE_10G + - seq_tab_next() should increase position index + - l2t_seq_next should increase position index + - netfilter: conntrack: sctp: use distinct states for new SCTP connections + - netfilter: nf_tables_offload: fix check the chain offload flag + - net: Fix skb->csum update in inet_proto_csum_replace16(). + - btrfs: do not zero f_bavail if we have available space + - cpuidle: teo: Avoid using "early hits" incorrectly + - flow_dissector: Fix to use new variables for port ranges in bpf hook + - dm thin: fix use-after-free in metadata_pre_commit_callback + - perf report: Fix no libunwind compiled warning break s390 issue + - mm/migrate.c: also overwrite error when it is bigger than zero + - ASoC: topology: fix soc_tplg_fe_link_create() - link->dobj initialization + order + - Revert "rsi: fix potential null dereference in rsi_probe()" + - tracing/uprobe: Fix to make trace_uprobe_filter alignment safe + - Linux 5.4.18 + * Integrate Intel SGX driver into linux-azure (LP: #1844245) + - [Packaging] Add systemd service to load intel_sgx + * Focal update: v5.4.17 upstream stable release (LP: #1861784) + - Bluetooth: btusb: fix non-atomic allocation in completion handler + - orinoco_usb: fix interface sanity check + - rsi_91x_usb: fix interface sanity check + - usb: dwc3: pci: add ID for the Intel Comet Lake -V variant + - usb: host: xhci-tegra: set MODULE_FIRMWARE for tegra186 + - USB: serial: ir-usb: add missing endpoint sanity check + - USB: serial: ir-usb: fix link-speed handling + - USB: serial: ir-usb: fix IrLAP framing + - usb: dwc3: turn off VBUS when leaving host mode + - usb: typec: wcove: fix "op-sink-microwatt" default that was in mW + - usb: typec: fusb302: fix "op-sink-microwatt" default that was in mW + - staging: most: net: fix buffer overflow + - staging: wlan-ng: ensure error return is actually returned + - staging: vt6656: correct packet types for CTS protect, mode. + - staging: vt6656: use NULLFUCTION stack on mac80211 + - staging: vt6656: Fix false Tx excessive retries reporting. + - serial: 8250_bcm2835aux: Fix line mismatch on driver unbind + - serial: imx: fix a race condition in receive path + - debugfs: Return -EPERM when locked down + - component: do not dereference opaque pointer in debugfs + - binder: fix log spam for existing debugfs file creation. + - mei: hdcp: bind only with i915 on the same PCH + - mei: me: add comet point (lake) H device ids + - iio: adc: stm32-dfsdm: fix single conversion + - iio: st_gyro: Correct data for LSM9DS0 gyro + - driver core: Fix test_async_driver_probe if NUMA is disabled + - crypto: chelsio - fix writing tfm flags to wrong place + - CIFS: Fix task struct use-after-free on reconnect + - cifs: set correct max-buffer-size for smb2_ioctl_init() + - cifs: Fix memory allocation in __smb2_handle_cancelled_cmd() + - ath9k: fix storage endpoint lookup + - brcmfmac: fix interface sanity check + - rtl8xxxu: fix interface sanity check + - zd1211rw: fix storage endpoint lookup + - net_sched: ematch: reject invalid TCF_EM_SIMPLE + - net_sched: fix ops->bind_class() implementations + - net_sched: walk through all child classes in tc_bind_tclass() + - net: socionext: fix possible user-after-free in netsec_process_rx + - net: socionext: fix xdp_result initialization in netsec_process_rx + - udp: segment looped gso packets correctly + - mlxsw: minimal: Fix an error handling path in 'mlxsw_m_port_create()' + - net: include struct nhmsg size in nh nlmsg size + - rxrpc: Fix use-after-free in rxrpc_receive_data() + - arc: eznps: fix allmodconfig kconfig warning + - HID: Add quirk for Xin-Mo Dual Controller + - HID: ite: Add USB id match for Acer SW5-012 keyboard dock + - HID: asus: Ignore Asus vendor-page usage-code 0xff events + - HID: Add quirk for incorrect input length on Lenovo Y720 + - HID: intel-ish-hid: ipc: add CMP device id + - HID: wacom: Recognize new MobileStudio Pro PID + - ASoC: SOF: fix fault at driver unload after failed probe + - ASoC: SOF: Intel: hda: hda-dai: fix oops on hda_link .hw_free + - drivers/hid/hid-multitouch.c: fix a possible null pointer access. + - phy: qcom-qmp: Increase PHY ready timeout + - ASoC: fsl_audmix: add missed pm_runtime_disable + - ASoC: topology: Prevent use-after-free in snd_soc_get_pcm_runtime() + - phy: cpcap-usb: Prevent USB line glitches from waking up modem + - HID: intel-ish-hid: ipc: Add Tiger Lake PCI device ID + - watchdog: max77620_wdt: fix potential build errors + - watchdog: rn5t618_wdt: fix module aliases + - watchdog: orion: fix platform_get_irq() complaints + - usb: musb: jz4740: Silence error if code is -EPROBE_DEFER + - can: tcan4x5x: tcan4x5x_parse_config(): reset device before register access + - spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls + - net: Google gve: Remove dma_wmb() before ringing doorbell + - drivers/net/b44: Change to non-atomic bit operations on pwol_mask + - net: wan: sdla: Fix cast from pointer to integer of different size + - gpio: max77620: Add missing dependency on GPIOLIB_IRQCHIP + - iommu/dma: fix variable 'cookie' set but not used + - drm/amd/display: Reduce HDMI pixel encoding if max clock is exceeded + - stmmac: debugfs entry name is not be changed when udev rename device name. + - atm: eni: fix uninitialized variable warning + - HID: steam: Fix input device disappearing + - extcon-intel-cht-wc: Don't reset USB data connection at probe + - ASoC: Intel: cht_bsw_rt5645: Add quirk for boards using pmc_plt_clk_0 + - drm/amdgpu/SRIOV: add navi12 pci id for SRIOV (v2) + - libbpf: Fix BTF-defined map's __type macro handling of arrays + - staging: mt7621-pci: add quirks for 'E2' revision using + 'soc_device_attribute' + - platform/x86: dell-laptop: disable kbd backlight on Inspiron 10xx + - PCI: Add DMA alias quirk for Intel VCA NTB + - media: dvbsky: add support for eyeTV Geniatech T2 lite + - bus: ti-sysc: Handle mstandby quirk and use it for musb + - bus: ti-sysc: Use swsup quirks also for am335x musb + - spi: pxa2xx: Add support for Intel Comet Lake-H + - iommu/amd: Support multiple PCI DMA aliases in device table + - iommu/amd: Support multiple PCI DMA aliases in IRQ Remapping + - perf/imx_ddr: Add enhanced AXI ID filter support + - ARM: config: aspeed-g5: Enable 8250_DW quirks + - ARM: OMAP2+: SmartReflex: add omap_sr_pdata definition + - mmc: sdhci-pci: Quirk for AMD SDHC Device 0x7906 + - mmc: sdhci-pci: Add support for Intel JSL + - bus: ti-sysc: Add module enable quirk for audio AESS + - usb-storage: Disable UAS on JMicron SATA enclosure + - ALSA: hda/realtek - Move some alc236 pintbls to fallback table + - Bluetooth: Allow combination of BDADDR_PROPERTY and INVALID_BDADDR quirks + - Bluetooth: btbcm: Use the BDADDR_PROPERTY quirk + - bus: ti-sysc: Fix missing force mstandby quirk handling + - rsi: fix use-after-free on failed probe and unbind + - rsi: fix use-after-free on probe errors + - rsi: fix memory leak on failed URB submission + - rsi: fix non-atomic allocation in completion handler + - crypto: af_alg - Use bh_lock_sock in sk_destruct + - crypto: vmx - reject xts inputs that are too short + - crypto: caam - do not reset pointer size from MCFGR register + - crypto: pcrypt - Fix user-after-free on module unload + - KVM: arm64: Write arch.mdcr_el2 changes since last vcpu_load on VHE + - Revert "um: Enable CONFIG_CONSTRUCTORS" + - power/supply: ingenic-battery: Don't change scale if there's only one + - Linux 5.4.17 + * Miscellaneous Ubuntu changes + - [Packaging] dkms -- switch basic provides to *-modules + - update dkms package versions + + -- Seth Forshee Sat, 15 Feb 2020 15:41:40 -0600 + +linux-oracle-5.4 (5.4.0-1001.1) focal; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] update update.conf + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] Change package name to linux-oracle-5.4 + - [Packaging] Remove i386 and x32 arches from control vars + - [Packaging] Regenerate reconstruct + - [Packaging] Remove python-dev build-depends + - [Packaging] dkms -- add Provides: specifiers + - [Packaging] Replace wget with curl in build-depends + - [Config] Enable wireguard dkms build + - [Debian] Add upstream version to packagenames in getabis + - [Config] Update configs and annotations for 5.4 + + -- Seth Forshee Wed, 05 Feb 2020 15:02:31 -0600 + +linux-oracle-5.4 (5.4.0-1000.0) focal; urgency=medium + + * Empty entry. + + -- Seth Forshee Wed, 05 Feb 2020 14:12:59 -0600 + +linux-oracle (5.3.0-1009.10) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1009.10 -proposed tracker (LP: #1861208) + + [ Ubuntu: 5.3.0-40.32 ] + + * eoan/linux: 5.3.0-40.32 -proposed tracker (LP: #1861214) + * No sof soundcard for 'ASoC: CODEC DAI intel-hdmi-hifi1 not registered' after + modprobe sof (LP: #1860248) + - ASoC: SOF: Intel: fix HDA codec driver probe with multiple controllers + * ocfs2-tools is causing kernel panics in Ubuntu Focal (Ubuntu-5.4.0-9.12) + (LP: #1852122) + - ocfs2: fix the crash due to call ocfs2_get_dlm_debug once less + * QAT drivers for C3XXX and C62X not included as modules (LP: #1845959) + - [Config] CRYPTO_DEV_QAT_C3XXX=m, CRYPTO_DEV_QAT_C62X=m and + CRYPTO_DEV_QAT_DH895xCC=m + * Eoan update: upstream stable patchset 2020-01-24 (LP: #1860816) + - scsi: lpfc: Fix discovery failures when target device connectivity bounces + - scsi: mpt3sas: Fix clear pending bit in ioctl status + - scsi: lpfc: Fix locking on mailbox command completion + - Input: atmel_mxt_ts - disable IRQ across suspend + - f2fs: fix to update time in lazytime mode + - iommu: rockchip: Free domain on .domain_free + - iommu/tegra-smmu: Fix page tables in > 4 GiB memory + - dmaengine: xilinx_dma: Clear desc_pendingcount in xilinx_dma_reset + - scsi: target: compare full CHAP_A Algorithm strings + - scsi: lpfc: Fix SLI3 hba in loop mode not discovering devices + - scsi: csiostor: Don't enable IRQs too early + - scsi: hisi_sas: Replace in_softirq() check in hisi_sas_task_exec() + - powerpc/pseries: Mark accumulate_stolen_time() as notrace + - powerpc/pseries: Don't fail hash page table insert for bolted mapping + - powerpc/tools: Don't quote $objdump in scripts + - dma-debug: add a schedule point in debug_dma_dump_mappings() + - leds: lm3692x: Handle failure to probe the regulator + - clocksource/drivers/asm9260: Add a check for of_clk_get + - clocksource/drivers/timer-of: Use unique device name instead of timer + - powerpc/security/book3s64: Report L1TF status in sysfs + - powerpc/book3s64/hash: Add cond_resched to avoid soft lockup warning + - ext4: update direct I/O read lock pattern for IOCB_NOWAIT + - ext4: iomap that extends beyond EOF should be marked dirty + - jbd2: Fix statistics for the number of logged blocks + - scsi: tracing: Fix handling of TRANSFER LENGTH == 0 for READ(6) and WRITE(6) + - scsi: lpfc: Fix duplicate unreg_rpi error in port offline flow + - f2fs: fix to update dir's i_pino during cross_rename + - clk: qcom: Allow constant ratio freq tables for rcg + - clk: clk-gpio: propagate rate change to parent + - irqchip/irq-bcm7038-l1: Enable parent IRQ if necessary + - irqchip: ingenic: Error out if IRQ domain creation failed + - fs/quota: handle overflows of sysctl fs.quota.* and report as unsigned long + - scsi: lpfc: fix: Coverity: lpfc_cmpl_els_rsp(): Null pointer dereferences + - PCI: rpaphp: Fix up pointer to first drc-info entry + - scsi: ufs: fix potential bug which ends in system hang + - powerpc/pseries/cmm: Implement release() function for sysfs device + - PCI: rpaphp: Don't rely on firmware feature to imply drc-info support + - PCI: rpaphp: Annotate and correctly byte swap DRC properties + - PCI: rpaphp: Correctly match ibm, my-drc-index to drc-name when using drc- + info + - powerpc/security: Fix wrong message when RFI Flush is disable + - scsi: atari_scsi: sun3_scsi: Set sg_tablesize to 1 instead of SG_NONE + - clk: pxa: fix one of the pxa RTC clocks + - bcache: at least try to shrink 1 node in bch_mca_scan() + - HID: quirks: Add quirk for HP MSU1465 PIXART OEM mouse + - HID: logitech-hidpp: Silence intermittent get_battery_capacity errors + - ARM: 8937/1: spectre-v2: remove Brahma-B53 from hardening + - libnvdimm/btt: fix variable 'rc' set but not used + - HID: Improve Windows Precision Touchpad detection. + - HID: rmi: Check that the RMI_STARTED bit is set before unregistering the RMI + transport device + - watchdog: Fix the race between the release of watchdog_core_data and cdev + - scsi: pm80xx: Fix for SATA device discovery + - scsi: ufs: Fix error handing during hibern8 enter + - scsi: scsi_debug: num_tgts must be >= 0 + - scsi: NCR5380: Add disconnect_mask module parameter + - scsi: iscsi: Don't send data to unbound connection + - scsi: target: iscsi: Wait for all commands to finish before freeing a + session + - gpio: mpc8xxx: Don't overwrite default irq_set_type callback + - apparmor: fix unsigned len comparison with less than zero + - scripts/kallsyms: fix definitely-lost memory leak + - powerpc: Don't add -mabi= flags when building with Clang + - cdrom: respect device capabilities during opening action + - perf script: Fix brstackinsn for AUXTRACE + - perf regs: Make perf_reg_name() return "unknown" instead of NULL + - s390/zcrypt: handle new reply code FILTERED_BY_HYPERVISOR + - libfdt: define INT32_MAX and UINT32_MAX in libfdt_env.h + - s390/cpum_sf: Check for SDBT and SDB consistency + - ocfs2: fix passing zero to 'PTR_ERR' warning + - mailbox: imx: Fix Tx doorbell shutdown path + - kernel: sysctl: make drop_caches write-only + - userfaultfd: require CAP_SYS_PTRACE for UFFD_FEATURE_EVENT_FORK + - net, sysctl: Fix compiler warning when only cBPF is present + - netfilter: nf_queue: enqueue skbs with NULL dst + - ALSA: hda - Downgrade error message for single-cmd fallback + - bonding: fix active-backup transition after link failure + - netfilter: ebtables: compat: reject all padding in matches/watchers + - 6pack,mkiss: fix possible deadlock + - netfilter: bridge: make sure to pull arp header in br_nf_forward_arp() + - inetpeer: fix data-race in inet_putpeer / inet_putpeer + - net: add a READ_ONCE() in skb_peek_tail() + - net: icmp: fix data-race in cmp_global_allow() + - hrtimer: Annotate lockless access to timer->state + - net: ena: fix napi handler misbehavior when the napi budget is zero + - net/mlxfw: Fix out-of-memory error in mfa2 flash burning + - net: stmmac: dwmac-meson8b: Fix the RGMII TX delay on Meson8b/8m2 SoCs + - ptp: fix the race between the release of ptp_clock and cdev + - tcp: Fix highest_sack and highest_sack_seq + - udp: fix integer overflow while computing available space in sk_rcvbuf + - vhost/vsock: accept only packets with the right dst_cid + - net: add bool confirm_neigh parameter for dst_ops.update_pmtu + - ip6_gre: do not confirm neighbor when do pmtu update + - gtp: do not confirm neighbor when do pmtu update + - net/dst: add new function skb_dst_update_pmtu_no_confirm + - tunnel: do not confirm neighbor when do pmtu update + - vti: do not confirm neighbor when do pmtu update + - sit: do not confirm neighbor when do pmtu update + - net/dst: do not confirm neighbor for vxlan and geneve pmtu update + - gtp: do not allow adding duplicate tid and ms_addr pdp context + - net: marvell: mvpp2: phylink requires the link interrupt + - tcp/dccp: fix possible race __inet_lookup_established() + - tcp: do not send empty skb from tcp_write_xmit() + - gtp: fix wrong condition in gtp_genl_dump_pdp() + - gtp: fix an use-after-free in ipv4_pdp_find() + - gtp: avoid zero size hashtable + - scsi: lpfc: Fix spinlock_irq issues in lpfc_els_flush_cmd() + - scsi: mpt3sas: Reject NVMe Encap cmnds to unsupported HBA + - gpio: mxc: Only get the second IRQ when there is more than one IRQ + - powerpc/papr_scm: Fix an off-by-one check in papr_scm_meta_{get, set} + - scsi: lpfc: Fix hardlockup in lpfc_abort_handler + - scsi: hisi_sas: Delete the debugfs folder of hisi_sas when the probe fails + - Input: st1232 - do not reset the chip too early + - selftests/powerpc: Fixup clobbers for TM tests + - dma-mapping: Add vmap checks to dma_map_single() + - dma-mapping: fix handling of dma-ranges for reserved memory (again) + - dmaengine: fsl-qdma: Handle invalid qdma-queue0 IRQ + - leds: an30259a: add a check for devm_regmap_init_i2c + - leds: trigger: netdev: fix handling on interface rename + - dtc: Use pkg-config to locate libyaml + - selftests/powerpc: Skip tm-signal-sigreturn-nt if TM not available + - scsi: lpfc: Fix unexpected error messages during RSCN handling + - clk: qcom: smd: Add missing pnoc clock + - dma-direct: check for overflows on 32 bit DMA addresses + - i2c: stm32f7: fix & reorder remove & probe error handling + - iomap: fix return value of iomap_dio_bio_actor on 32bit systems + - Input: ili210x - handle errors from input_mt_init_slots() + - scsi: zorro_esp: Limit DMA transfers to 65536 bytes (except on Fastlane) + - powerpc/book3s/mm: Update Oops message to print the correct translation in + use + - powerpc/fixmap: Use __fix_to_virt() instead of fix_to_virt() + - scsi: target: core: Release SPC-2 reservations when closing a session + - scsi: ufs: Fix up auto hibern8 enablement + - habanalabs: skip VA block list update in reset flow + - platform/x86: intel_pmc_core: Fix the SoC naming inconsistency + - gpio: lynxpoint: Setup correct IRQ handlers + - tools/power/x86/intel-speed-select: Ignore missing config level + - cifs: Fix use-after-free bug in cifs_reconnect() + - of: unittest: fix memory leak in attach_node_and_children + - mailbox: imx: Clear the right interrupts at shutdown + - s390/unwind: filter out unreliable bogus %r14 + - s390: disable preemption when switching to nodat stack with CALL_ON_STACK + - selftests: vm: add fragment CONFIG_TEST_VMALLOC + - mm/hugetlbfs: fix error handling when setting up mounts + - sctp: fix err handling of stream initialization + - Revert "iwlwifi: assign directly to iwl_trans->cfg in QuZ detection" + - powerpc: Fix __clear_user() with KUAP enabled + - net/smc: add fallback check to connect() + - tomoyo: Don't use nifty names on sockets. + - uaccess: disallow > INT_MAX copy sizes + - drm: limit to INT_MAX in create_blob ioctl + - xfs: fix mount failure crash on invalid iclog memory access + - cxgb4/cxgb4vf: fix flow control display for auto negotiation + - net: dsa: bcm_sf2: Fix IP fragment location and behavior + - net: phy: aquantia: add suspend / resume ops for AQR105 + - net/sched: act_mirred: Pull mac prior redir to non mac_header_xmit device + - net/sched: add delete_empty() to filters and use it in cls_flower + - net_sched: sch_fq: properly set sk->sk_pacing_status + - bnxt_en: Fix MSIX request logic for RDMA driver. + - bnxt_en: Return error if FW returns more data than dump length + - mlxsw: spectrum_router: Skip loopback RIFs during MAC validation + - mlxsw: spectrum: Use dedicated policer for VRRP packets + - net: dsa: sja1105: Reconcile the meaning of TPID and TPID2 for E/T and + P/Q/R/S + - hv_netvsc: Fix tx_table init in rndis_set_subchannel() + - bnxt: apply computed clamp value for coalece parameter + - ipv6/addrconf: only check invalid header values when NETLINK_F_STRICT_CHK is + set + - net: phylink: fix interface passed to mac_link_up + - mmc: sdhci-of-esdhc: fix up erratum A-008171 workaround + - mmc: sdhci-of-esdhc: re-implement erratum A-009204 workaround + - mm/hugetlbfs: fix for_each_hstate() loop in init_hugetlbfs_fs() + - md: make sure desc_nr less than MD_SB_DISKS + * Eoan update: upstream stable patchset 2020-01-21 (LP: #1860490) + - af_packet: set defaule value for tmo + - fjes: fix missed check in fjes_acpi_add + - mod_devicetable: fix PHY module format + - net: dst: Force 4-byte alignment of dst_metrics + - net: gemini: Fix memory leak in gmac_setup_txqs + - net: hisilicon: Fix a BUG trigered by wrong bytes_compl + - net: nfc: nci: fix a possible sleep-in-atomic-context bug in + nci_uart_tty_receive() + - net: qlogic: Fix error paths in ql_alloc_large_buffers() + - net: usb: lan78xx: Fix suspend/resume PHY register access error + - qede: Disable hardware gro when xdp prog is installed + - qede: Fix multicast mac configuration + - sctp: fully initialize v4 addr in some functions + - selftests: forwarding: Delete IPv6 address at the end + - btrfs: don't double lock the subvol_sem for rename exchange + - btrfs: do not call synchronize_srcu() in inode_tree_del + - Btrfs: fix missing data checksums after replaying a log tree + - btrfs: send: remove WARN_ON for readonly mount + - btrfs: abort transaction after failed inode updates in create_subvol + - btrfs: skip log replay on orphaned roots + - btrfs: do not leak reloc root if we fail to read the fs root + - btrfs: handle ENOENT in btrfs_uuid_tree_iterate + - Btrfs: fix removal logic of the tree mod log that leads to use-after-free + issues + - ALSA: pcm: Avoid possible info leaks from PCM stream buffers + - ALSA: hda/ca0132 - Keep power on during processing DSP response + - ALSA: hda/ca0132 - Avoid endless loop + - ALSA: hda/ca0132 - Fix work handling in delayed HP detection + - drm: mst: Fix query_payload ack reply struct + - drm/panel: Add missing drm_panel_init() in panel drivers + - drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings + - iio: light: bh1750: Resolve compiler warning and make code more readable + - drm/amdgpu: grab the id mgr lock while accessing passid_mapping + - spi: Add call to spi_slave_abort() function when spidev driver is released + - staging: rtl8192u: fix multiple memory leaks on error path + - staging: rtl8188eu: fix possible null dereference + - rtlwifi: prevent memory leak in rtl_usb_probe + - libertas: fix a potential NULL pointer dereference + - ath10k: fix backtrace on coredump + - IB/iser: bound protection_sg size by data_sg size + - media: am437x-vpfe: Setting STD to current value is not an error + - media: i2c: ov2659: fix s_stream return value + - media: ov6650: Fix crop rectangle alignment not passed back + - media: i2c: ov2659: Fix missing 720p register config + - media: ov6650: Fix stored frame format not in sync with hardware + - media: ov6650: Fix stored crop rectangle not in sync with hardware + - tools/power/cpupower: Fix initializer override in hsw_ext_cstates + - media: venus: core: Fix msm8996 frequency table + - ath10k: fix offchannel tx failure when no ath10k_mac_tx_frm_has_freq + - pinctrl: devicetree: Avoid taking direct reference to device name string + - drm/amdkfd: fix a potential NULL pointer dereference (v2) + - selftests/bpf: Correct path to include msg + path + - media: venus: Fix occasionally failures to suspend + - usb: renesas_usbhs: add suspend event support in gadget mode + - hwrng: omap3-rom - Call clk_disable_unprepare() on exit only if not idled + - regulator: max8907: Fix the usage of uninitialized variable in + max8907_regulator_probe() + - media: flexcop-usb: fix NULL-ptr deref in flexcop_usb_transfer_init() + - media: cec-funcs.h: add status_req checks + - drm/bridge: dw-hdmi: Refuse DDC/CI transfers on the internal I2C controller + - samples: pktgen: fix proc_cmd command result check logic + - block: Fix writeback throttling W=1 compiler warnings + - mwifiex: pcie: Fix memory leak in mwifiex_pcie_init_evt_ring + - drm/drm_vblank: Change EINVAL by the correct errno + - media: cx88: Fix some error handling path in 'cx8800_initdev()' + - media: ti-vpe: vpe: Fix Motion Vector vpdma stride + - media: ti-vpe: vpe: fix a v4l2-compliance warning about invalid pixel format + - media: ti-vpe: vpe: fix a v4l2-compliance failure about frame sequence + number + - media: ti-vpe: vpe: Make sure YUYV is set as default format + - media: ti-vpe: vpe: fix a v4l2-compliance failure causing a kernel panic + - media: ti-vpe: vpe: ensure buffers are cleaned up properly in abort cases + - media: ti-vpe: vpe: fix a v4l2-compliance failure about invalid sizeimage + - syscalls/x86: Use the correct function type in SYSCALL_DEFINE0 + - drm/amd/display: Fix dongle_caps containing stale information. + - extcon: sm5502: Reset registers during initialization + - x86/mm: Use the correct function type for native_set_fixmap() + - ath10k: Correct error handling of dma_map_single() + - drm/bridge: dw-hdmi: Restore audio when setting a mode + - perf test: Report failure for mmap events + - perf report: Add warning when libunwind not compiled in + - usb: usbfs: Suppress problematic bind and unbind uevents. + - iio: adc: max1027: Reset the device at probe time + - Bluetooth: missed cpu_to_le16 conversion in hci_init4_req + - Bluetooth: Workaround directed advertising bug in Broadcom controllers + - Bluetooth: hci_core: fix init for HCI_USER_CHANNEL + - bpf/stackmap: Fix deadlock with rq_lock in bpf_get_stack() + - x86/mce: Lower throttling MCE messages' priority to warning + - perf tests: Disable bp_signal testing for arm64 + - drm/gma500: fix memory disclosures due to uninitialized bytes + - rtl8xxxu: fix RTL8723BU connection failure issue after warm reboot + - ipmi: Don't allow device module unload when in use + - x86/ioapic: Prevent inconsistent state when moving an interrupt + - media: smiapp: Register sensor after enabling runtime PM on the device + - md/bitmap: avoid race window between md_bitmap_resize and + bitmap_file_clear_bit + - arm64: psci: Reduce the waiting time for cpu_psci_cpu_kill() + - i40e: initialize ITRN registers with correct values + - net: phy: dp83867: enable robust auto-mdix + - drm/tegra: sor: Use correct SOR index on Tegra210 + - spi: sprd: adi: Add missing lock protection when rebooting + - ACPI: button: Add DMI quirk for Medion Akoya E2215T + - RDMA/qedr: Fix memory leak in user qp and mr + - gpu: host1x: Allocate gather copy for host1x + - net: dsa: LAN9303: select REGMAP when LAN9303 enable + - phy: qcom-usb-hs: Fix extcon double register after power cycle + - s390/time: ensure get_clock_monotonic() returns monotonic values + - s390/mm: add mm_pxd_folded() checks to pxd_free() + - net: hns3: add struct netdev_queue debug info for TX timeout + - libata: Ensure ata_port probe has completed before detach + - loop: fix no-unmap write-zeroes request behavior + - pinctrl: sh-pfc: sh7734: Fix duplicate TCLK1_B + - iio: dln2-adc: fix iio_triggered_buffer_postenable() position + - libbpf: Fix error handling in bpf_map__reuse_fd() + - Bluetooth: Fix advertising duplicated flags + - pinctrl: amd: fix __iomem annotation in amd_gpio_irq_handler() + - ixgbe: protect TX timestamping from API misuse + - media: rcar_drif: fix a memory disclosure + - media: v4l2-core: fix touch support in v4l_g_fmt + - nvmem: imx-ocotp: reset error status on probe + - rfkill: allocate static minor + - bnx2x: Fix PF-VF communication over multi-cos queues. + - spi: img-spfi: fix potential double release + - ALSA: timer: Limit max amount of slave instances + - rtlwifi: fix memory leak in rtl92c_set_fw_rsvdpagepkt() + - perf probe: Fix to find range-only function instance + - perf probe: Fix to list probe event with correct line number + - perf jevents: Fix resource leak in process_mapfile() and main() + - perf probe: Walk function lines in lexical blocks + - perf probe: Fix to probe an inline function which has no entry pc + - perf probe: Fix to show ranges of variables in functions without entry_pc + - perf probe: Fix to show inlined function callsite without entry_pc + - libsubcmd: Use -O0 with DEBUG=1 + - perf probe: Fix to probe a function which has no entry pc + - perf tools: Splice events onto evlist even on error + - drm/amdgpu: disallow direct upload save restore list from gfx driver + - drm/amdgpu: fix potential double drop fence reference + - xen/gntdev: Use select for DMA_SHARED_BUFFER + - perf parse: If pmu configuration fails free terms + - perf probe: Skip overlapped location on searching variables + - perf probe: Return a better scope DIE if there is no best scope + - perf probe: Fix to show calling lines of inlined functions + - perf probe: Skip end-of-sequence and non statement lines + - perf probe: Filter out instances except for inlined subroutine and + subprogram + - ath10k: fix get invalid tx rate for Mesh metric + - fsi: core: Fix small accesses and unaligned offsets via sysfs + - media: pvrusb2: Fix oops on tear-down when radio support is not present + - soundwire: intel: fix PDI/stream mapping for Bulk + - crypto: atmel - Fix authenc support when it is set to m + - ice: delay less + - media: si470x-i2c: add missed operations in remove + - EDAC/ghes: Fix grain calculation + - spi: pxa2xx: Add missed security checks + - ASoC: rt5677: Mark reg RT5677_PWR_ANLG2 as volatile + - iio: dac: ad5446: Add support for new AD5600 DAC + - ASoC: Intel: kbl_rt5663_rt5514_max98927: Add dmic format constraint + - s390/disassembler: don't hide instruction addresses + - parport: load lowlevel driver if ports not found + - bcache: fix static checker warning in bcache_device_free() + - cpufreq: Register drivers only after CPU devices have been registered + - x86/crash: Add a forward declaration of struct kimage + - tracing: use kvcalloc for tgid_map array allocation + - tracing/kprobe: Check whether the non-suffixed symbol is notrace + - iwlwifi: mvm: fix unaligned read of rx_pkt_status + - ASoC: wm8904: fix regcache handling + - spi: tegra20-slink: add missed clk_unprepare + - tun: fix data-race in gro_normal_list() + - crypto: virtio - deal with unsupported input sizes + - mmc: tmio: Add MMC_CAP_ERASE to allow erase/discard/trim requests + - btrfs: don't prematurely free work in end_workqueue_fn() + - btrfs: don't prematurely free work in run_ordered_work() + - ASoC: wm2200: add missed operations in remove and probe failure + - spi: st-ssc4: add missed pm_runtime_disable + - ASoC: wm5100: add missed pm_runtime_disable + - ASoC: Intel: bytcr_rt5640: Update quirk for Acer Switch 10 SW5-012 2-in-1 + - x86/insn: Add some Intel instructions to the opcode map + - brcmfmac: remove monitor interface when detaching + - iwlwifi: check kasprintf() return value + - fbtft: Make sure string is NULL terminated + - net: ethernet: ti: ale: clean ale tbl on init and intf restart + - crypto: sun4i-ss - Fix 64-bit size_t warnings + - crypto: sun4i-ss - Fix 64-bit size_t warnings on sun4i-ss-hash.c + - mac80211: consider QoS Null frames for STA_NULLFUNC_ACKED + - crypto: vmx - Avoid weird build failures + - libtraceevent: Fix memory leakage in copy_filter_type + - mips: fix build when "48 bits virtual memory" is enabled + - drm/amdgpu: fix bad DMA from INTERRUPT_CNTL2 + - net: phy: initialise phydev speed and duplex sanely + - btrfs: don't prematurely free work in reada_start_machine_worker() + - btrfs: don't prematurely free work in scrub_missing_raid56_worker() + - Revert "mmc: sdhci: Fix incorrect switch to HS mode" + - mmc: mediatek: fix CMD_TA to 2 for MT8173 HS200/HS400 mode + - can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices + - usb: xhci: Fix build warning seen with CONFIG_PM=n + - drm/amdgpu: fix uninitialized variable pasid_mapping_needed + - s390/ftrace: fix endless recursion in function_graph tracer + - btrfs: return error pointer from alloc_test_extent_buffer + - usbip: Fix receive error in vhci-hcd when using scatter-gather + - usbip: Fix error path of vhci_recv_ret_submit() + - cpufreq: Avoid leaving stale IRQ work items during CPU offline + - USB: EHCI: Do not return -EPIPE when hub is disconnected + - intel_th: pci: Add Comet Lake PCH-V support + - intel_th: pci: Add Elkhart Lake SOC support + - platform/x86: hp-wmi: Make buffer for HPWMI_FEATURE2_QUERY 128 bytes + - staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value + - ext4: fix ext4_empty_dir() for directories with holes + - ext4: check for directory entries too close to block end + - ext4: unlock on error in ext4_expand_extra_isize() + - KVM: arm64: Ensure 'params' is initialised when looking up sys register + - x86/MCE/AMD: Do not use rdmsr_safe_on_cpu() in smca_configure() + - x86/MCE/AMD: Allow Reserved types to be overwritten in smca_banks[] + - powerpc/irq: fix stack overflow verification + - mmc: sdhci-msm: Correct the offset and value for DDR_CONFIG register + - mmc: sdhci-of-esdhc: Revert "mmc: sdhci-of-esdhc: add erratum A-009204 + support" + - mmc: sdhci: Update the tuning failed messages to pr_debug level + - mmc: sdhci-of-esdhc: fix P2020 errata handling + - mmc: sdhci: Workaround broken command queuing on Intel GLK + - mmc: sdhci: Add a quirk for broken command queuing + - nbd: fix shutdown and recv work deadlock v2 + - perf probe: Fix to show function entry line as probe-able + - net: phy: ensure that phy IDs are correctly typed + - nfp: flower: fix stats id allocation + - sctp: fix memleak on err handling of stream initialization + - neighbour: remove neigh_cleanup() method + - bonding: fix bond_neigh_init() + - net: ena: fix default tx interrupt moderation interval + - dpaa2-ptp: fix double free of the ptp_qoriq IRQ + - mlxsw: spectrum_router: Remove unlikely user-triggerable warning + - net: ethernet: ti: davinci_cpdma: fix warning "device driver frees DMA + memory with different size" + - net: stmmac: platform: Fix MDIO init for platforms without PHY + - Btrfs: make tree checker detect checksum items with overlapping ranges + - drm/vc4/vc4_hdmi: fill in connector info + - drm/mipi-dbi: fix a loop in debugfs code + - drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register + - drm: Use EOPNOTSUPP, not ENOTSUPP + - drm/amd/display: verify stream link before link test + - iio: max31856: add missing of_node and parent references to iio_dev + - drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 code + - ath10k: add cleanup in ath10k_sta_state() + - drm/amd/display: Handle virtual signal type in disable_link() + - ath10k: Check if station exists before forwarding tx airtime report + - Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit30 when using SSI_SCK2 + and SSI_WS2" + - Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit31 when using SIM0_D" + - drm/komeda: Workaround for broken FLIP_COMPLETE timestamps + - spi: gpio: prevent memory leak in spi_gpio_probe + - media: cedrus: fill in bus_info for media device + - media: seco-cec: Add a missing 'release_region()' in an error handling path + - media: vim2m: Fix abort issue + - media: vim2m: Fix BUG_ON in vim2m_device_release() + - media: max2175: Fix build error without CONFIG_REGMAP_I2C + - media: ov6650: Fix control handler not freed on init error + - media: vimc: Fix gpf in rmmod path when stream is active + - drm/amd/display: Set number of pipes to 1 if the second pipe was disabled + - drm/sun4i: dsi: Fix TCON DRQ set bits + - x86/math-emu: Check __copy_from_user() result + - drm/amd/powerplay: A workaround to GPU RESET on APU + - rtw88: fix NSS of hw_cap + - drm/amd/display: fix struct init in update_bounding_box + - tools/memory-model: Fix data race detection for unordered store and load + - drm/amdkfd: Fix MQD size calculation + - selftests/bpf: Fix btf_dump padding test case + - libbpf: Fix struct end padding in btf_dump + - libbpf: Fix passing uninitialized bytes to setsockopt + - net/smc: increase device refcount for added link group + - team: call RCU read lock when walking the port_list + - misc: fastrpc: fix memory leak from miscdev->name + - drm/amd/display: Properly round nominal frequency for SPD + - drm/amd/display: wait for set pipe mcp command completion + - drm/amd/display: Program DWB watermarks from correct state + - rtw88: coex: Set 4 slot mode for A2DP + - perf test: Avoid infinite loop for task exit case + - perf vendor events arm64: Fix Hisi hip08 DDRC PMU eventname + - drm/amd/powerplay: avoid disabling ECC if RAS is enabled for VEGA20 + - Bluetooth: btusb: avoid unused function warning + - drm/amdgpu: fix amdgpu trace event print string format error + - staging: iio: ad9834: add a check for devm_clk_get + - power: supply: cpcap-battery: Check voltage before orderly_poweroff + - net: hns3: log and clear hardware error after reset complete + - ASoC: soc-pcm: fixup dpcm_prune_paths() loop continue + - RDMA/siw: Fix SQ/RQ drain logic + - media: cedrus: Fix undefined shift with a SHIFT_AND_MASK_BITS macro + - media: aspeed: set hsync and vsync polarities to normal before starting mode + detection + - drm/nouveau: Don't grab runtime PM refs for HPD IRQs + - media: ov6650: Fix stored frame interval not in sync with hardware + - media: ad5820: Define entity function + - media: ov5640: Make 2592x1944 mode only available at 15 fps + - media: st-mipid02: add a check for devm_gpiod_get_optional + - media: imx7-mipi-csis: Add a check for devm_regulator_get + - media: aspeed: clear garbage interrupts + - staging: wilc1000: potential corruption in wilc_parse_join_bss_param() + - drm: Don't free jobs in wait_event_interruptible() + - EDAC/amd64: Set grain per DIMM + - drm/amd/display: setting the DIG_MODE to the correct value. + - drm/amd/display: correctly populate dpp refclk in fpga + - regulator: core: Release coupled_rdevs on regulator_init_coupling() error + - ubsan, x86: Annotate and allow __ubsan_handle_shift_out_of_bounds() in + uaccess regions + - RDMA/hns: Fix memory leak on 'context' on error return path + - RDMA/qedr: Fix srqs xarray initialization + - RDMA/core: Set DMA parameters correctly + - phy: renesas: phy-rcar-gen2: Fix the array off by one warning + - s390: add error handling to perf_callchain_kernel + - net/mlx5e: Verify that rule has at least one fwd/drop action + - ALSA: bebob: expand sleep just after breaking connections for protocol + version 1 + - ALSA: pcm: Fix missing check of the new non-cached buffer type + - spi: sifive: disable clk when probe fails and remove + - media: staging/imx: Use a shorter name for driver + - nvmem: core: fix nvmem_cell_write inline function + - ASoC: SOF: topology: set trigger order for FE DAI link + - media: vivid: media_device_cleanup was called too early + - spi: dw: Fix Designware SPI loopback + - RDMA/core: Fix return code when modify_port isn't supported + - drm: msm: a6xx: fix debug bus register configuration + - perf cs-etm: Fix definition of macro TO_CS_QUEUE_NR + - ice: Check for null pointer dereference when setting rings + - net: avoid potential false sharing in neighbor related code + - libbpf: Fix negative FD close() in xsk_setup_xdp_prog() + - s390/bpf: Use kvcalloc for addrs array + - cgroup: freezer: don't change task and cgroups status unnecessarily + - selftests: proc: Make va_max 1MB + - drm/amdgpu: Avoid accidental thread reactivation. + - media: exynos4-is: fix wrong mdev and v4l2 dev order in error path + - selftests: net: Fix printf format warnings on arm + - media: v4l2-ctrl: Lock main_hdl on operations of requests_queued. + - media: vicodec: media_device_cleanup was called too early + - media: vim2m: media_device_cleanup was called too early + - bpf, testing: Workaround a verifier failure for test_progs + - net: dsa: sja1105: Disallow management xmit during switch reset + - net: ethernet: ti: Add dependency for TI_DAVINCI_EMAC + - qtnfmac: fix debugfs support for multiple cards + - qtnfmac: fix invalid channel information output + - qtnfmac: fix using skb after free + - RDMA/efa: Clear the admin command buffer prior to its submission + - regulator: core: Let boot-on regulators be powered off + - xhci-pci: Allow host runtime PM as default also for Intel Ice Lake xHCI + - perf/core: Fix the mlock accounting, again + - selftests, bpf: Fix test_tc_tunnel hanging + - selftests, bpf: Workaround an alu32 sub-register spilling issue + - net: phy: avoid matching all-ones clause 45 PHY IDs + - firmware_loader: Fix labels with comma for builtin firmware + - net-af_xdp: Use correct number of channels from ethtool + - s390/kasan: support memcpy_real with TRACE_IRQFLAGS + - ASoC: soc-pcm: check symmetry before hw_params + - s390/cpumf: Adjust registration of s390 PMU device drivers + - ice: Only disable VF state when freeing each VF resources + - RDMA/bnxt_re: Fix missing le16_to_cpu + - bpf: Provide better register bounds after jmp32 instructions + - RDMA/bnxt_re: Fix chip number validation Broadcom's Gen P5 series + - tpm: fix invalid locking in NONBLOCKING mode + - iommu: set group default domain before creating direct mappings + - iommu/vt-d: Fix dmar pte read access not set error + - iommu/vt-d: Set ISA bridge reserved region as relaxable + - iommu/vt-d: Allocate reserved region for ISA with correct permission + - can: xilinx_can: Fix missing Rx can packets on CANFD2.0 + - can: flexcan: fix possible deadlock and out-of-order reception after wakeup + - can: flexcan: poll MCR_LPM_ACK instead of GPR ACK for stop mode + acknowledgment + - selftests: net: tls: remove recv_rcvbuf test + - spi: dw: Correct handling of native chipselect + - spi: cadence: Correct handling of native chipselect + - ath10k: Revert "ath10k: add cleanup in ath10k_sta_state()" + - RDMA/siw: Fix post_recv QP state locking + - ARM: dts: Fix vcsi regulator to be always-on for droid4 to prevent hangs + - can: flexcan: add low power enter/exit acknowledgment helper + - spi: fsl: don't map irq during probe + - spi: fsl: use platform_get_irq() instead of of_irq_to_resource() + - efi/memreserve: Register reservations as 'reserved' in /proc/iomem + - KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails + - mm: vmscan: protect shrinker idr replace with CONFIG_MEMCG + - intel_th: Fix freeing IRQs + - intel_th: msu: Fix window switching without windows + - tty/serial: atmel: fix out of range clock divider handling + - serial: sprd: Add clearing break interrupt operation + - pinctrl: baytrail: Really serialize all register accesses + - clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table + - clk: imx: clk-composite-8m: add lock to gate/mux + - clk: imx: pll14xx: fix clk_pll14xx_wait_lock + - KVM: arm/arm64: Properly handle faulting of device mappings + - x86/mce: Fix possibly incorrect severity calculation on AMD + - ocxl: Fix concurrent AFU open and device removal + - md: no longer compare spare disk superblock events in super_load + - md: avoid invalid memory access for array sb->dev_roles + * CVE-2019-19965 + - scsi: libsas: stop discovering if oob mode is disconnected + * Eoan update: upstream stable patchset 2020-01-17 (LP: #1860179) + - mmc: block: Make card_busy_detect() a bit more generic + - mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response + - mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() + - mmc: core: Re-work HW reset for SDIO cards + - PCI/switchtec: Read all 64 bits of part_event_bitmap + - PCI/PM: Always return devices to D0 when thawing + - PCI: pciehp: Avoid returning prematurely from sysfs requests + - PCI: Fix Intel ACS quirk UPDCR register address + - PCI/MSI: Fix incorrect MSI-X masking on resume + - PCI: Do not use bus number zero from EA capability + - PCI: rcar: Fix missing MACCTLR register setting in initialization sequence + - PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3 + - xtensa: use MEMBLOCK_ALLOC_ANYWHERE for KASAN shadow map + - gfs2: Multi-block allocations in gfs2_page_mkwrite + - gfs2: fix glock reference problem in gfs2_trans_remove_revoke + - xtensa: fix TLB sanity checker + - xtensa: fix syscall_set_return_value + - rpmsg: glink: Set tail pointer to 0 at end of FIFO + - rpmsg: glink: Fix reuse intents memory leak issue + - rpmsg: glink: Fix use after free in open_ack TIMEOUT case + - rpmsg: glink: Put an extra reference during cleanup + - rpmsg: glink: Fix rpmsg_register_device err handling + - rpmsg: glink: Don't send pending rx_done during remove + - rpmsg: glink: Free pending deferred work on remove + - cifs: smbd: Return -EAGAIN when transport is reconnecting + - cifs: smbd: Only queue work for error recovery on memory registration + - cifs: smbd: Add messages on RDMA session destroy and reconnection + - cifs: smbd: Return -EINVAL when the number of iovs exceeds SMBDIRECT_MAX_SGE + - cifs: smbd: Return -ECONNABORTED when trasnport is not in connected state + - cifs: Don't display RDMA transport on reconnect + - CIFS: Respect O_SYNC and O_DIRECT flags during reconnect + - CIFS: Close open handle after interrupted close + - CIFS: Do not miss cancelled OPEN responses + - CIFS: Fix NULL pointer dereference in mid callback + - ARM: dts: s3c64xx: Fix init order of clock providers + - ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume() + - vfio/pci: call irq_bypass_unregister_producer() before freeing irq + - dma-buf: Fix memory leak in sync_file_merge() + - drm/mgag200: Extract device type from flags + - drm/mgag200: Store flags from PCI driver data in device structure + - drm/mgag200: Add workaround for HW that does not support 'startadd' + - drm/mgag200: Flag all G200 SE A machines as broken wrt + - drm: meson: venc: cvbs: fix CVBS mode matching + - dm mpath: remove harmful bio-based optimization + - dm btree: increase rebalance threshold in __rebalance2() + - dm thin metadata: Add support for a pre-commit callback + - dm thin: Flush data device before committing metadata + - scsi: ufs: Disable autohibern8 feature in Cadence UFS + - scsi: iscsi: Fix a potential deadlock in the timeout handler + - scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd + - scsi: qla2xxx: Initialize free_work before flushing it + - scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX + - scsi: qla2xxx: Correctly retrieve and interpret active flash region + - scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd + - drm/nouveau/kms/nv50-: Call outp_atomic_check_view() before handling PBN + - drm/nouveau/kms/nv50-: Store the bpc we're using in nv50_head_atom + - drm/nouveau/kms/nv50-: Limit MST BPC to 8 + - drm/i915/fbc: Disable fbc by default on all glk+ + - drm/radeon: fix r1xx/r2xx register checker for POT textures + - drm/dp_mst: Correct the bug in drm_dp_update_payload_part1() + - drm/amd/display: re-enable wait in pipelock, but add timeout + - drm/amd/display: add default clocks if not able to fetch them + - drm/amdgpu/gfx10: explicitly wait for cp idle after halt/unhalt + - drm/amdgpu/gfx10: re-init clear state buffer after gpu reset + - ALSA: hda: Fix regression by strip mask fix + * fstrim on nvme / AMD CPU fails and produces kernel error messages + (LP: #1856603) + - nvme: Discard workaround for non-conformant devices + * multi-zone raid0 corruption (LP: #1850540) + - md/raid0: avoid RAID0 data corruption due to layout confusion. + - md: add feature flag MD_FEATURE_RAID0_LAYOUT + - md/raid0: fix warning message for parameter default_layout + - md/raid0: Fix an error message in raid0_make_request() + - SAUCE: md/raid0: Link to wiki with guidance on multi-zone RAID0 layout + migration + - SAUCE: md/raid0: Use kernel specific layout + * Dell AIO can't adjust brightness (LP: #1858761) + - SAUCE: platform/x86: dell-uart-backlight: add retry for get scalar status + * [SRU][B/OEM-B/OEM-OSP1/D/E/Unstable] UBUNTU: SAUCE: Use native backlight on + Lenovo E41-25/45 (LP: #1859561) + - SAUCE: ACPI: video: Use native backlight on Lenovo E41-25/45 + * debian/tests/corosync: gfs2_jadd fails with ENOTTY for i386 package on amd64 + kernel (LP: #1859827) + - gfs2: add compat_ioctl support + * Smartpqi updates for 18.04.4 (LP: #1860690) + - scsi: smartpqi: add module param for exposure order + - scsi: smartpqi: add pci ids for fiberhome controller + - scsi: smartpqi: add module param to hide vsep + - scsi: smartpqi: add sysfs entries + - scsi: smartpqi: add bay identifier + - scsi: smartpqi: correct hang when deleting 32 lds + - scsi: smartpqi: add gigabyte controller + - scsi: smartpqi: correct REGNEWD return status + - scsi: smartpqi: add new pci ids + - scsi: smartpqi: update copyright + - scsi: smartpqi: bump version + * Fix misleading error message: Configuring the VNIC characteristics failed + (LP: #1860523) + - (upstream) s390/qeth: fix false reporting of VNIC CHAR config failure + * Disable ECKD Thin Provisioning to prevent data loss (LP: #1860535) + - SAUCE: s390/dasd: disable ese support due to possible data corruption + * alsa/sof: change to use hda hdmi codec driver to make hdmi audio on the + docking station work (LP: #1855666) + - ALSA: hda/hdmi - implement mst_no_extra_pcms flag + - ASoC: hdac_hda: add support for HDMI/DP as a HDA codec + - ASoC: Intel: skl-hda-dsp-generic: use snd-hda-codec-hdmi + - ASoC: Intel: skl-hda-dsp-generic: fix include guard name + - ASoC: SOF: Intel: add support for snd-hda-codec-hdmi + - ASoC: Intel: bxt-da7219-max98357a: common hdmi codec support + - ASoC: Intel: glk_rt5682_max98357a: common hdmi codec support + - ASoC: intel: sof_rt5682: common hdmi codec support + - ASoC: Intel: bxt_rt298: common hdmi codec support + - ASoC: SOF: enable sync_write in hdac_bus + - [config]: SND_SOC_SOF_HDA_COMMON_HDMI_CODEC=y + * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312) + - SAUCE: USB: core: Make port power cycle a seperate helper function + - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state + * [sas-1126]scsi: hisi_sas: Fix out of bound at debug_I_T_nexus_reset() + (LP: #1853992) + - scsi: hisi_sas: Fix out of bound at debug_I_T_nexus_reset() + * [sas-1126]scsi: hisi_sas: Assign NCQ tag for all NCQ commands (LP: #1853995) + - scsi: hisi_sas: Assign NCQ tag for all NCQ commands + * [sas-1126]scsi: hisi_sas: Fix the conflict between device gone and host + reset (LP: #1853997) + - scsi: hisi_sas: Fix the conflict between device gone and host reset + * scsi: hisi_sas: Check sas_port before using it (LP: #1855952) + - scsi: hisi_sas: Check sas_port before using it + * The system cannot resume from S3 if user unplugs the TB16 during suspend + state (LP: #1849269) + - PCI: pciehp: Do not disable interrupt twice on suspend + - PCI: pciehp: Prevent deadlock on disconnect + * [SRU][B/OEM-B/OEM-OSP1/D/E/F] Add LG I2C touchscreen multitouch support + (LP: #1857541) + - SAUCE: HID: multitouch: Add LG MELF0410 I2C touchscreen support + * cifs: DFS Caching feature causing problems traversing multi-tier DFS setups + (LP: #1854887) + - cifs: Fix retrieval of DFS referrals in cifs_mount() + * Fix Realtek Bluetooth firmware download (LP: #1856079) + - Bluetooth: btrtl: Fix an issue that failing to download the FW which size is + over 32K bytes + * usb-audio: the mic can't record any sound after resume on Dell Dock WD19 + (LP: #1857496) + - ALSA: usb-audio: set the interface format after resume on Dell WD19 + * [mgag200] Ubuntu 19.10 upgrade results in invisible mouse cursor on Matrox + G200eR2 (LP: #1851340) + - drm/mgag200: add in missing { } around if block + - drm/mgag200: Don't unpin the current cursor image's buffer. + - drm/mgag200: Set cursor scanout address to correct BO + - drm/mgag200: Pin displayed cursor BO to video memory + * [roce-1126]RDMA/hns: bugfix for slab-out-of-bounds when loading hip08 driver + (LP: #1853989) + - RDMA/hns: Bugfix for slab-out-of-bounds when unloading hip08 driver + - RDMA/hns: bugfix for slab-out-of-bounds when loading hip08 driver + * [hns-1126]net: hns3: revert to old channel when setting new channel num fail + (LP: #1853983) + - net: hns3: revert to old channel when setting new channel num fail + * [hns-1126]net: hns3: fix port setting handle for fibre port + (LP: #1853984) + - net: hns3: fix port setting handle for fibre port + * alsa/hda/realtek: the line-out jack doens't work on a dell AIO + (LP: #1855999) + - ALSA: hda/realtek - Line-out jack doesn't work on a Dell AIO + * change kconfig of the soundwire bus driver from y to m (LP: #1855685) + - [config]: SOUNDWIRE=m + * CVE-2019-19082 + - drm/amd/display: prevent memory leak + * Eoan update: 5.3.18 upstream stable release (LP: #1856870) + - inet: protect against too small mtu values. + - mqprio: Fix out-of-bounds access in mqprio_dump + - net: bridge: deny dev_set_mac_address() when unregistering + - net: dsa: fix flow dissection on Tx path + - net: ethernet: ti: cpsw: fix extra rx interrupt + - net: sched: fix dump qlen for sch_mq/sch_mqprio with NOLOCK subqueues + - net: thunderx: start phy before starting autonegotiation + - net/tls: Fix return values to avoid ENOTSUPP + - openvswitch: support asymmetric conntrack + - tcp: md5: fix potential overestimation of TCP option space + - tipc: fix ordering of tipc module init and exit routine + - net/mlx5e: Query global pause state before setting prio2buffer + - net: ipv6: add net argument to ip6_dst_lookup_flow + - net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup + - tcp: fix rejected syncookies due to stale timestamps + - tcp: tighten acceptance of ACKs not matching a child socket + - tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE() + - gre: refetch erspan header from skb->data after pskb_may_pull() + - Fixed updating of ethertype in function skb_mpls_pop + - hsr: fix a NULL pointer dereference in hsr_dev_xmit() + - net: Fixed updating of ethertype in skb_mpls_push() + - net/mlx5e: Fix TXQ indices to be sequential + - page_pool: do not release pool until inflight == 0. + - xdp: obtain the mem_id mutex before trying to remove an entry. + - Linux 5.3.18 + * Eoan update: 5.3.17 upstream stable release (LP: #1856869) + - usb: gadget: configfs: Fix missing spin_lock_init() + - usb: gadget: pch_udc: fix use after free + - Revert "nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T" + - scsi: zfcp: trace channel log even for FCP command responses + - scsi: qla2xxx: Fix driver unload hang + - scsi: qla2xxx: Fix memory leak when sending I/O fails + - media: venus: remove invalid compat_ioctl32 handler + - USB: uas: honor flag to avoid CAPACITY16 + - USB: uas: heed CAPACITY_HEURISTICS + - USB: documentation: flags on usb-storage versus UAS + - usb: Allow USB device to be warm reset in suspended state + - usb: host: xhci-tegra: Correct phy enable sequence + - binder: fix incorrect calculation for num_valid + - staging: rtl8188eu: fix interface sanity check + - staging: rtl8712: fix interface sanity check + - staging: vchiq: call unregister_chrdev_region() when driver registration + fails + - staging: gigaset: fix general protection fault on probe + - staging: gigaset: fix illegal free on probe errors + - staging: gigaset: add endpoint-type sanity check + - usb: xhci: only set D3hot for pci device + - xhci: Fix memory leak in xhci_add_in_port() + - xhci: fix USB3 device initiated resume race with roothub autosuspend + - xhci: Increase STS_HALT timeout in xhci_suspend() + - xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default behaviour. + - xhci: make sure interrupts are restored to correct state + - interconnect: qcom: sdm845: Walk the list safely on node removal + - ARM: dts: pandora-common: define wl1251 as child node of mmc3 + - iio: adis16480: Add debugfs_reg_access entry + - iio: adis16480: Fix scales factors + - iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting + - iio: imu: inv_mpu6050: fix temperature reporting using bad unit + - iio: adc: ad7606: fix reading unnecessary data from device + - iio: adc: ad7124: Enable internal reference + - USB: atm: ueagle-atm: add missing endpoint check + - USB: idmouse: fix interface sanity checks + - USB: serial: io_edgeport: fix epic endpoint lookup + - usb: roles: fix a potential use after free + - USB: adutux: fix interface sanity check + - usb: core: urb: fix URB structure initialization function + - usb: mon: Fix a deadlock in usbmon between mmap and read + - tpm: add check after commands attribs tab allocation + - EDAC/altera: Use fast register IO for S10 IRQs + - brcmfmac: disable PCIe interrupts before bus reset + - mtd: spear_smi: Fix Write Burst mode + - mtd: rawnand: Change calculating of position page containing BBM + - virt_wifi: fix use-after-free in virt_wifi_newlink() + - virtio-balloon: fix managed page counts when migrating pages between zones + - usb: dwc3: gadget: Fix logical condition + - usb: dwc3: gadget: Clear started flag for non-IOC + - usb: dwc3: ep0: Clear started flag on completion + - phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role" + - usb: typec: fix use after free in typec_register_port() + - iwlwifi: pcie: fix support for transmitting SKBs with fraglist + - btrfs: check page->mapping when loading free space cache + - btrfs: use refcount_inc_not_zero in kill_all_nodes + - Btrfs: fix metadata space leak on fixup worker failure to set range as + delalloc + - Btrfs: fix negative subv_writers counter and data space leak after buffered + write + - btrfs: Avoid getting stuck during cyclic writebacks + - btrfs: Remove btrfs_bio::flags member + - Btrfs: send, skip backreference walking for extents with many references + - btrfs: record all roots for rename exchange on a subvol + - rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address + - rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer + - rtlwifi: rtl8192de: Fix missing enable interrupt flag + - lib: raid6: fix awk build warnings + - Revert "UBUNTU: SAUCE: ovl: fix lookup failure on multi lower squashfs" + - ovl: fix lookup failure on multi lower squashfs + - ovl: fix corner case of non-unique st_dev;st_ino + - ovl: relax WARN_ON() on rename to self + - hwrng: omap - Fix RNG wait loop timeout + - dm writecache: handle REQ_FUA + - dm zoned: reduce overhead of backing device checks + - workqueue: Fix spurious sanity check failures in destroy_workqueue() + - workqueue: Fix pwq ref leak in rescuer_thread() + - ASoC: rt5645: Fixed buddy jack support. + - ASoC: rt5645: Fixed typo for buddy jack support. + - ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report + - ASoC: fsl_audmix: Add spin lock to protect tdms + - md: improve handling of bio with REQ_PREFLUSH in md_flush_request() + - blk-mq: avoid sysfs buffer overflow with too many CPU cores + - cgroup: pids: use atomic64_t for pids->limit + - wil6210: check len before memcpy() calls + - ar5523: check NULL before memcpy() in ar5523_cmd() + - s390/mm: properly clear _PAGE_NOEXEC bit when it is not supported + - media: hantro: Fix s_fmt for dynamic resolution changes + - media: bdisp: fix memleak on release + - media: radio: wl1273: fix interrupt masking on release + - media: cec.h: CEC_OP_REC_FLAG_ values were swapped + - cpuidle: Do not unset the driver if it is there already + - cpuidle: teo: Ignore disabled idle states that are too deep + - cpuidle: teo: Rename local variable in teo_select() + - cpuidle: teo: Consider hits and misses metrics of disabled states + - cpuidle: teo: Fix "early hits" handling for disabled idle states + - erofs: zero out when listxattr is called with no xattr + - powerpc/perf: Disable trace_imc pmu + - intel_th: Fix a double put_device() in error path + - intel_th: pci: Add Ice Lake CPU support + - intel_th: pci: Add Tiger Lake CPU support + - PM / devfreq: Lock devfreq in trans_stat_show + - cpufreq: powernv: fix stack bloat and hard limit on number of CPUs + - ALSA: fireface: fix return value in error path of isochronous resources + reservation + - ALSA: oxfw: fix return value in error path of isochronous resources + reservation + - ACPI / utils: Move acpi_dev_get_first_match_dev() under CONFIG_ACPI + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C7 to lpss_device_links + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C1 to lpss_device_links + - ACPI: LPSS: Add dmi quirk for skipping _DEP check for some device-links + - ACPI / hotplug / PCI: Allocate resources directly under the non-hotplug + bridge + - ACPI: OSL: only free map once in osl.c + - ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data() + - ACPI: PM: Avoid attaching ACPI PM domain to certain devices + - pinctrl: rza2: Fix gpio name typos + - pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type() + - pinctrl: samsung: Add of_node_put() before return in error path + - pinctrl: samsung: Fix device node refcount leaks in Exynos wakeup controller + init + - pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup + controller init + - pinctrl: samsung: Fix device node refcount leaks in init code + - pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup + controller init + - mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of + pandora_wl1251_init_card + - ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity + - RDMA/core: Fix ib_dma_max_seg_size() + - ppdev: fix PPGETTIME/PPSETTIME ioctls + - stm class: Lose the protocol driver when dropping its reference + - coresight: Serialize enabling/disabling a link device. + - powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB + - powerpc/xive: Prevent page fault issues in the machine crash handler + - powerpc: Allow flush_icache_range to work across ranges >4GB + - powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts + - video/hdmi: Fix AVI bar unpack + - quota: Check that quota is not dirty before release + - ext2: check err when partial != NULL + - Revert "UBUNTU: SAUCE: seccomp: avoid overflow in implicit constant + conversion" + - seccomp: avoid overflow in implicit constant conversion + - quota: fix livelock in dquot_writeback_dquots + - ext4: Fix credit estimate for final inode freeing + - reiserfs: fix extended attributes on the root directory + - scsi: lpfc: Fix bad ndlp ptr in xri aborted handling + - scsi: qla2xxx: Fix abort timeout race condition. + - scsi: qla2xxx: Do command completion on abort timeout + - scsi: qla2xxx: Fix premature timer expiration + - scsi: qla2xxx: Fix DMA unmap leak + - scsi: qla2xxx: Fix different size DMA Alloc/Unmap + - scsi: qla2xxx: Fix NVMe port discovery after a short device port loss + - scsi: qla2xxx: Fix hang in fcport delete path + - scsi: qla2xxx: Make qla2x00_abort_srb() again decrease the sp reference + count + - scsi: qla2xxx: Really fix qla2xxx_eh_abort() + - scsi: qla2xxx: Fix session lookup in qlt_abort_work() + - scsi: qla2xxx: Fix qla24xx_process_bidir_cmd() + - scsi: qla2xxx: Always check the qla2x00_wait_for_hba_online() return value + - scsi: qla2xxx: Check secondary image if reading the primary image fails + - scsi: qla2xxx: Make sure that aborted commands are freed + - scsi: qla2xxx: qla2x00_alloc_fw_dump: set ha->eft + - scsi: qla2xxx: Fix message indicating vectors used by driver + - scsi: qla2xxx: Fix flash read for Qlogic ISPs + - scsi: qla2xxx: Fix driver reload for ISP82xx + - scsi: qla2xxx: Fix stuck login session + - scsi: qla2xxx: Fix stale session + - scsi: qla2xxx: Fix SRB leak on switch command timeout + - scsi: qla2xxx: Fix a dma_pool_free() call + - Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails" + - scsi: qla2xxx: Fix a race condition between aborting and completing a SCSI + command + - scsi: qla2xxx: Fix double scsi_done for abort path + - scsi: qla2xxx: Introduce the function qla2xxx_init_sp() + - iio: imu: st_lsm6dsx: move odr_table in st_lsm6dsx_sensor_settings + - iio: imu: st_lsm6dsx: fix ODR check in st_lsm6dsx_write_raw + - iio: ad7949: kill pointless "readback"-handling code + - iio: ad7949: fix channels mixups + - omap: pdata-quirks: revert pandora specific gpiod additions + - omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251 + - powerpc: Avoid clang warnings around setjmp and longjmp + - powerpc: Fix vDSO clock_getres() + - mm, memfd: fix COW issue on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings + - Revert "UBUNTU: SAUCE: mfd: rk808: Fix RK818 ID template" + - mfd: rk808: Fix RK818 ID template + - mm: memcg/slab: wait for !root kmem_cache refcnt killing on root kmem_cache + destruction + - ext4: work around deleting a file with i_nlink == 0 safely + - firmware: qcom: scm: Ensure 'a0' status code is treated as signed + - s390/smp,vdso: fix ASCE handling + - s390/kaslr: store KASLR offset for early dumps + - mm/shmem.c: cast the type of unmap_start to u64 + - rtc: disable uie before setting time and enable after + - splice: only read in as much information as there is pipe buffer space + - ext4: fix a bug in ext4_wait_for_tail_page_commit + - blk-mq: make sure that line break can be printed + - workqueue: Fix missing kfree(rescuer) in destroy_workqueue() + - raid5: need to set STRIPE_HANDLE for batch head + - scsi: qla2xxx: Change discovery state before PLOGI + - SUNRPC: Fix another issue with MIC buffer space + - net_sched: validate TCA_KIND attribute in tc_chain_tmplt_add() + - arm64: dts: allwinner: a64: Re-add PMU node + - block: fix "check bi_size overflow before merge" + - EDAC/ghes: Do not warn when incrementing refcount on 0 + - Linux 5.3.17 + * Add new PCH ID for the Intel Comet Lake -H variant (LP: #1856642) + - usb: dwc3: pci: add ID for the Intel Comet Lake -H variant + * CVE-2019-19078 + - ath10k: fix memory leak + * CVE-2019-19077 + - RDMA: Fix goto target to release the allocated memory + * Eoan update: 5.3.16 upstream stable release (LP: #1856334) + - rsi: release skb if rsi_prepare_beacon fails + - arm64: tegra: Fix 'active-low' warning for Jetson TX1 regulator + - perf scripts python: exported-sql-viewer.py: Fix use of TRUE with SQLite + - sparc64: implement ioremap_uc + - lp: fix sparc64 LPSETTIMEOUT ioctl + - time: Zero the upper 32-bits in __kernel_timespec on 32-bit + - usb: gadget: u_serial: add missing port entry locking + - tty: serial: fsl_lpuart: use the sg count from dma_map_sg + - tty: serial: msm_serial: Fix flow control + - serial: pl011: Fix DMA ->flush_buffer() + - serial: serial_core: Perform NULL checks for break_ctl ops + - serial: stm32: fix clearing interrupt error flags + - serial: ifx6x60: add missed pm_runtime_disable + - aio: Fix io_pgetevents() struct __compat_aio_sigset layout + - autofs: fix a leak in autofs_expire_indirect() + - MIPS: SGI-IP27: fix exception handler replication + - RDMA/hns: Correct the value of HNS_ROCE_HEM_CHUNK_LEN + - RDMA/hns: Correct the value of srq_desc_size + - iwlwifi: pcie: don't consider IV len in A-MSDU + - cgroup: don't put ERR_PTR() into fc->root + - exportfs_decode_fh(): negative pinned may become positive without the parent + locked + - audit_get_nd(): don't unlock parent too early + - ecryptfs: fix unlink and rmdir in face of underlying fs modifications + - Revert "UBUNTU: SAUCE: ALSA: hda: Add Cometlake-S PCI ID" + - ALSA: hda: Add Cometlake-S PCI ID + - NFC: nxp-nci: Fix NULL pointer dereference after I2C communication error + - xfrm: release device reference for invalid state + - block: check bi_size overflow before merge + - Input: cyttsp4_core - fix use after free bug + - sched/core: Avoid spurious lock dependencies + - sched/pelt: Fix update of blocked PELT ordering + - perf/core: Consistently fail fork on allocation failures + - ALSA: pcm: Fix stream lock usage in snd_pcm_period_elapsed() + - x86/resctrl: Fix potential lockdep warning + - drm/sun4i: tcon: Set min division of TCON0_DCLK to 1. + - selftests: kvm: fix build with glibc >= 2.30 + - rbd: silence bogus uninitialized warning in rbd_object_map_update_finish() + - rsxx: add missed destroy_workqueue calls in remove + - ravb: implement MTU change while device is up + - net: hns3: reallocate SSU' buffer size when pfc_en changes + - net: hns3: fix ETS bandwidth validation bug + - afs: Fix race in commit bulk status fetch + - net: ep93xx_eth: fix mismatch of request_mem_region in remove + - i2c: core: fix use after free in of_i2c_notify + - io_uring: transform send/recvmsg() -ERESTARTSYS to -EINTR + - fuse: verify nlink + - fuse: verify attributes + - io_uring: ensure req->submit is copied when req is deferred + - SUNRPC: Avoid RPC delays when exiting suspend + - ALSA: hda/realtek - Enable internal speaker of ASUS UX431FLC + - Revert "UBUNTU: SAUCE: ALSA: hda/realtek - Dell headphone has noise on + unmute for ALC236" + - ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236 + - ALSA: pcm: oss: Avoid potential buffer overflows + - ALSA: hda - Add mute led support for HP ProBook 645 G4 + - ALSA: hda: Modify stream stripe mask only when needed + - Input: synaptics - switch another X1 Carbon 6 to RMI/SMbus + - Input: synaptics-rmi4 - re-enable IRQs in f34v7_do_reflash + - Input: synaptics-rmi4 - don't increment rmiaddr for SMBus transfers + - Input: goodix - add upside-down quirk for Teclast X89 tablet + - coresight: etm4x: Fix input validation for sysfs. + - Input: Fix memory leak in psxpad_spi_probe + - media: rc: mark input device as pointing stick + - x86/mm/32: Sync only to VMALLOC_END in vmalloc_sync_all() + - CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks + - CIFS: Fix SMB2 oplock break processing + - tty: vt: keyboard: reject invalid keycodes + - can: slcan: Fix use-after-free Read in slcan_open + - nfsd: Ensure CLONE persists data and metadata changes to the target file + - nfsd: restore NFSv3 ACL support + - kernfs: fix ino wrap-around detection + - jbd2: Fix possible overflow in jbd2_log_space_left() + - drm/msm: fix memleak on release + - drm: damage_helper: Fix race checking plane->state->fb + - drm/i810: Prevent underflow in ioctl + - arm64: dts: exynos: Revert "Remove unneeded address space mapping for soc + node" + - KVM: PPC: Book3S HV: XIVE: Free previous EQ page when setting up a new one + - KVM: PPC: Book3S HV: XIVE: Fix potential page leak on error path + - KVM: PPC: Book3S HV: XIVE: Set kvm->arch.xive when VPs are allocated + - KVM: nVMX: Always write vmcs02.GUEST_CR3 during nested VM-Enter + - KVM: arm/arm64: vgic: Don't rely on the wrong pending table + - KVM: x86: do not modify masked bits of shared MSRs + - KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES + - KVM: x86: Remove a spurious export of a static function + - KVM: x86: Grab KVM's srcu lock when setting nested state + - crypto: crypto4xx - fix double-free in crypto4xx_destroy_sdr + - crypto: atmel-aes - Fix IV handling when req->nbytes < ivsize + - crypto: af_alg - cast ki_complete ternary op to int + - crypto: geode-aes - switch to skcipher for cbc(aes) fallback + - crypto: ccp - fix uninitialized list head + - crypto: ecdh - fix big endian bug in ECC library + - crypto: user - fix memory leak in crypto_report + - spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register + - spi: stm32-qspi: Fix kernel oops when unbinding driver + - spi: atmel: Fix CS high support + - spi: Fix SPI_CS_HIGH setting when using native and GPIO CS + - spi: Fix NULL pointer when setting SPI_CS_HIGH for GPIO CS + - can: ucan: fix non-atomic allocation in completion handler + - RDMA/qib: Validate ->show()/store() callbacks before calling them + - iomap: Fix pipe page leakage during splicing + - thermal: Fix deadlock in thermal thermal_zone_device_check + - vcs: prevent write access to vcsu devices + - binder: Fix race between mmap() and binder_alloc_print_pages() + - binder: Prevent repeated use of ->mmap() via NULL mapping + - binder: Handle start==NULL in binder_update_page_range() + - KVM: x86: fix out-of-bounds write in KVM_GET_EMULATED_CPUID (CVE-2019-19332) + - ALSA: hda - Fix pending unsol events at shutdown + - cpufreq: imx-cpufreq-dt: Correct i.MX8MN's default speed grade value + - drm/mcde: Fix an error handling path in 'mcde_probe()' + - watchdog: aspeed: Fix clock behaviour for ast2600 + - EDAC/ghes: Fix locking and memory barrier issues + - perf script: Fix invalid LBR/binary mismatch error + - kselftest: Fix NULL INSTALL_PATH for TARGETS runlist + - ALSA: hda: hdmi - fix pin setup on Tigerlake + - Linux 5.3.16 + * Realtek ALC256M with DTS Audio Processing internal microphone doesn't work + on Redmi Book 14 2019 (LP: #1846148) // Eoan update: 5.3.16 upstream stable + release (LP: #1856334) + - ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop + * CVE-2019-19050 + - crypto: user - fix memory leak in crypto_reportstat + * Fix MST support on Ice Lake (LP: #1854432) + - drm/i915: fix port checks for MST support on gen >= 11 + * headphone has noise as not mute on dell machines with alc236/256 + (LP: #1854401) + - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236 + * Eoan update: 5.3.15 upstream stable release (LP: #1855306) + - io_uring: async workers should inherit the user creds + - net: separate out the msghdr copy from ___sys_{send,recv}msg() + - net: disallow ancillary data for __sys_{send,recv}msg_file() + - XArray: Fix xas_next() with a single entry at 0 + - clk: meson: gxbb: let sar_adc_clk_div set the parent clock rate + - clk: at91: sam9x60: fix programmable clock + - thunderbolt: Read DP IN adapter first two dwords in one go + - thunderbolt: Fix lockdep circular locking depedency warning + - clocksource/drivers/mediatek: Fix error handling + - soundwire: intel: fix intel_register_dai PDI offsets and numbers + - ASoC: msm8916-wcd-analog: Fix RX1 selection in RDAC2 MUX + - ASoC: compress: fix unsigned integer overflow check + - reset: Fix memory leak in reset_control_array_put() + - clk: samsung: exynos5433: Fix error paths + - clk: samsung: exynos542x: Move G3D subsystem clocks to its sub-CMU + - ASoC: kirkwood: fix external clock probe defer + - ASoC: kirkwood: fix device remove ordering + - arm64: dts: ls1028a: fix a compatible issue + - clk: samsung: exynos5420: Preserve PLL configuration during suspend/resume + - pinctrl: cherryview: Allocate IRQ chip dynamic + - ARM: dts: imx6qdl-sabreauto: Fix storm of accelerometer interrupts + - soc: imx: gpc: fix initialiser format + - reset: fix reset_control_ops kerneldoc comment + - arm64: dts: imx8mm: fix compatible string for sdma + - ASoC: SOF: ipc: Fix memory leak in sof_set_get_large_ctrl_data + - ASoC: ti: sdma-pcm: Add back the flags parameter for non standard dma names + - ASoC: rockchip: rockchip_max98090: Enable SHDN to fix headset detection + - clk: at91: avoid sleeping early + - clk: sunxi: Fix operator precedence in sunxi_divs_clk_setup + - clk: sunxi-ng: a80: fix the zero'ing of bits 16 and 18 + - ARM: dts: sun8i-a83t-tbs-a711: Fix WiFi resume from suspend + - bpf: Allow narrow loads of bpf_sysctl fields with offset > 0 + - samples/bpf: fix build by setting HAVE_ATTR_TEST to zero + - bpf: Change size to u64 for bpf_map_{area_alloc, charge_init}() + - powerpc/bpf: Fix tail call implementation + - idr: Fix idr_get_next_ul race with idr_remove + - idr: Fix integer overflow in idr_for_each_entry + - idr: Fix idr_alloc_u32 on 32-bit systems + - x86/resctrl: Prevent NULL pointer dereference when reading mondata + - arm64: dts: zii-ultra: fix ARM regulator GPIO handle + - fbdev: c2p: Fix link failure on non-inlining + - ASoC: hdac_hda: fix race in device removal + - clk: ti: dra7-atl-clock: Remove ti_clk_add_alias call + - clk: ti: clkctrl: Fix failed to enable error with double udelay timeout + - net: fec: add missed clk_disable_unprepare in remove + - netfilter: ipset: Fix nla_policies to fully support NL_VALIDATE_STRICT + - bridge: ebtables: don't crash when using dnat target in output chains + - netfilter: nf_tables: bogus EOPNOTSUPP on basechain update + - netfilter: nf_tables_offload: skip EBUSY on chain update + - stacktrace: Don't skip first entry on noncurrent tasks + - can: peak_usb: report bus recovery as well + - can: c_can: D_CAN: c_can_chip_config(): perform a sofware reset on open + - can: rx-offload: can_rx_offload_queue_tail(): fix error handling, avoid skb + mem leak + - can: rx-offload: can_rx_offload_offload_one(): do not increase the skb_queue + beyond skb_queue_len_max + - can: rx-offload: can_rx_offload_offload_one(): increment rx_fifo_errors on + queue overflow or OOM + - can: rx-offload: can_rx_offload_offload_one(): use ERR_PTR() to propagate + error value in case of errors + - can: rx-offload: can_rx_offload_irq_offload_timestamp(): continue on error + - can: rx-offload: can_rx_offload_irq_offload_fifo(): continue on error + - can: flexcan: increase error counters if skb enqueueing via + can_rx_offload_queue_sorted() fails + - x86/tsc: Respect tsc command line paraemeter for clocksource_tsc_early + - perf scripting engines: Iterate on tep event arrays directly + - can: mcp251x: mcp251x_restart_work_handler(): Fix potential force_quit race + condition + - nvme-rdma: fix a segmentation fault during module unload + - nvme-multipath: fix crash in nvme_mpath_clear_ctrl_paths + - watchdog: pm8916_wdt: fix pretimeout registration flow + - watchdog: meson: Fix the wrong value of left time + - watchdog: imx_sc_wdt: Pretimeout should follow SCU firmware format + - watchdog: bd70528: Add MODULE_ALIAS to allow module auto loading + - ASoC: stm32: sai: add restriction on mmap support + - ALSA: hda: hdmi - add Tigerlake support + - ARM: dts: stm32: Fix CAN RAM mapping on stm32mp157c + - ASoC: SOF: topology: Fix bytes control size checks + - mm/gup_benchmark: fix MAP_HUGETLB case + - scripts/gdb: fix debugging modules compiled with hot/cold partitioning + - net: bcmgenet: use RGMII loopback for MAC reset + - net: bcmgenet: reapply manual settings to the PHY + - drm/amdgpu: dont schedule jobs while in reset + - net/mlx5e: Fix eswitch debug print of max fdb flow + - net/mlx5e: Use correct enum to determine uplink port + - net: mscc: ocelot: fix __ocelot_rmw_ix prototype + - drm/amd/swSMU: fix smu workload bit map error + - drm/amdgpu: register gpu instance before fan boost feature enablment + - drm/amdgpu: add warning for GRBM 1-cycle delay issue in gfx9 + - net: stmmac: gmac4: bitrev32 returns u32 + - net: stmmac: xgmac: bitrev32 returns u32 + - net: stmmac: xgmac: Fix TSA selection + - net: stmmac: xgmac: Disable Flow Control when 1 or more queues are in AV + - ceph: return -EINVAL if given fsc mount option on kernel w/o support + - mac80211: fix ieee80211_txq_setup_flows() failure path + - net/fq_impl: Switch to kvmalloc() for memory allocation + - mac80211: fix station inactive_time shortly after boot + - block: drbd: remove a stray unlock in __drbd_send_protocol() + - pwm: bcm-iproc: Prevent unloading the driver module while in use + - ice: fix potential infinite loop because loop counter being too small + - iavf: initialize ITRN registers with correct values + - i40e: Fix for ethtool -m issue on X722 NIC + - clk: at91: fix update bit maps on CFG_MOR write + - usb: dwc2: use a longer core rest timeout in dwc2_core_reset() + - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param() + - staging: rtl8192e: fix potential use after free + - staging: rtl8723bs: Drop ACPI device ids + - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids + - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P + - mei: bus: prefix device names on bus with the bus name + - mei: me: add comet point V device id + - thunderbolt: Power cycle the router if NVM authentication fails + - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx + - gve: Fix the queue page list allocated pages count + - macvlan: schedule bc_work even if error + - mdio_bus: don't use managed reset-controller + - net: dsa: sja1105: fix sja1105_parse_rgmii_delays() + - net: macb: add missed tasklet_kill + - net: psample: fix skb_over_panic + - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues + - openvswitch: fix flow command message size + - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook + - slip: Fix use-after-free Read in slip_open + - sctp: cache netns in sctp_ep_common + - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info() + - openvswitch: remove another BUG_ON() + - net/tls: take into account that bpf_exec_tx_verdict() may free the record + - net/tls: free the record on encryption error + - net: skmsg: fix TLS 1.3 crash with full sk_msg + - selftests/tls: add a test for fragmented messages + - net/tls: remove the dead inplace_crypto code + - net/tls: use sg_next() to walk sg entries + - selftests: bpf: test_sockmap: handle file creation failures gracefully + - selftests: bpf: correct perror strings + - tipc: fix link name length check + - selftests: pmtu: use -oneline for ip route list cache + - ext4: add more paranoia checking in ext4_expand_extra_isize handling + - HID: core: check whether Usage Page item is after Usage ID items + - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer + - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size + - net: fec: fix clock count mis-match + - Linux 5.3.15 + * Eoan update: 5.3.14 upstream stable release (LP: #1854861) + - mlxsw: spectrum_router: Fix determining underlay for a GRE tunnel + - net/mlx4_en: fix mlx4 ethtool -N insertion + - net/mlx4_en: Fix wrong limitation for number of TX rings + - net: rtnetlink: prevent underflows in do_setvfinfo() + - net/sched: act_pedit: fix WARN() in the traffic path + - net: sched: ensure opts_len <= IP_TUNNEL_OPTS_MAX in act_tunnel_key + - sfc: Only cancel the PPS workqueue if it exists + - net/mlxfw: Verify FSM error code translation doesn't exceed array size + - net/mlx5e: Fix set vf link state error flow + - net/mlx5: Fix auto group size calculation + - net/tls: enable sk_msg redirect to tls socket egress + - ipv6/route: return if there is no fib_nh_gw_family + - taprio: don't reject same mqprio settings + - net/ipv4: fix sysctl max for fib_multipath_hash_policy + - net/mlx5e: Fix error flow cleanup in mlx5e_tc_tun_create_header_ipv4/6 + - net/mlx5e: Do not use non-EXT link modes in EXT mode + - net/mlx5: Update the list of the PCI supported devices + - vhost/vsock: split packets to send using multiple buffers + - gpio: max77620: Fixup debounce delays + - gpio: bd70528: Use correct unit for debounce times + - tools: gpio: Correctly add make dependencies for gpio_utils + - fork: fix pidfd_poll()'s return type + - nbd:fix memory leak in nbd_get_socket() + - virtio_console: allocate inbufs in add_port() only if it is needed + - virtio_ring: fix return code on DMA mapping fails + - virtio_balloon: fix shrinker count + - Revert "fs: ocfs2: fix possible null-pointer dereferences in + ocfs2_xa_prepare_entry()" + - mm/memory_hotplug: don't access uninitialized memmaps in shrink_zone_span() + - mm/ksm.c: don't WARN if page is still mapped in remove_stable_node() + - drm/amdgpu: disable gfxoff when using register read interface + - drm/amdgpu: disable gfxoff on original raven + - drm/amd/powerplay: issue no PPSMC_MSG_GetCurrPkgPwr on unsupported ASICs + - drm/i915: Don't oops in dumb_create ioctl if we have no crtcs + - drm/i915/pmu: "Frequency" is reported as accumulated cycles + - drm/i915/userptr: Try to acquire the page lock around set_page_dirty() + - Bluetooth: Fix invalid-free in bcsp_close() + - ath10k: restore QCA9880-AR1A (v1) detection + - ath10k: Fix HOST capability QMI incompatibility + - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe + - ath9k_hw: fix uninitialized variable data + - Revert "Bluetooth: hci_ll: set operational frequency earlier" + - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues" + - md/raid10: prevent access of uninitialized resync_pages offset + - mdio_bus: Fix init if CONFIG_RESET_CONTROLLER=n + - ARM: 8904/1: skip nomap memblocks while finding the lowmem/highmem boundary + - x86/insn: Fix awk regexp warnings + - x86/speculation: Fix incorrect MDS/TAA mitigation status + - x86/speculation: Fix redundant MDS mitigation message + - nbd: prevent memory leak + - gve: fix dma sync bug where not all pages synced + - x86/stackframe/32: Repair 32-bit Xen PV + - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout + - x86/xen/32: Simplify ring check in xen_iret_crit_fixup() + - x86/doublefault/32: Fix stack canaries in the double fault handler + - x86/pti/32: Size initial_page_table correctly + - x86/cpu_entry_area: Add guard page for entry stack on 32bit + - x86/entry/32: Fix IRET exception + - x86/entry/32: Use %ss segment where required + - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL + - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry + - x86/entry/32: Fix NMI vs ESPFIX + - selftests/x86/mov_ss_trap: Fix the SYSENTER test + - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel + - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make + the CPU_ENTRY_AREA_PAGES assert precise + - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3 + - futex: Prevent robust futex exit race + - ALSA: usb-audio: Fix NULL dereference at parsing BADD + - nfc: port100: handle command failure cleanly + - media: vivid: Set vid_cap_streaming and vid_out_streaming to true + - media: vivid: Fix wrong locking that causes race conditions on streaming + stop + - media: usbvision: Fix invalid accesses after device disconnect + - media: usbvision: Fix races among open, close, and disconnect + - cpufreq: Add NULL checks to show() and store() methods of cpufreq + - media: uvcvideo: Fix error path in control parsing failure + - media: b2c2-flexcop-usb: add sanity checking + - media: cxusb: detect cxusb_ctrl_msg error in query + - media: imon: invalid dereference in imon_touch_event + - media: mceusb: fix out of bounds read in MCE receiver buffer + - mm/slub.c: init_on_free=1 should wipe freelist ptr for bulk allocations + - USBIP: add config dependency for SGL_ALLOC + - usbip: tools: fix fd leakage in the function of read_attr_usbip_status + - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit() + - usb-serial: cp201x: support Mark-10 digital force gauge + - USB: chaoskey: fix error case of a timeout + - appledisplay: fix error handling in the scheduled work + - USB: serial: mos7840: add USB ID to support Moxa UPort 2210 + - USB: serial: mos7720: fix remote wakeup + - USB: serial: mos7840: fix remote wakeup + - USB: serial: option: add support for DW5821e with eSIM support + - USB: serial: option: add support for Foxconn T77W968 LTE modules + - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error + - Linux 5.3.14 + + [ Ubuntu: 5.3.0-29.31 ] + + * eoan/linux: 5.3.0-29.31 -proposed tracker (LP: #1860119) + * Integrate Intel SGX driver into linux-azure (LP: #1844245) + - [Packaging] Add systemd service to load intel_sgx + + [ Ubuntu: 5.3.0-28.30 ] + + * eoan/linux: 5.3.0-28.30 -proposed tracker (LP: #1859694) + * CVE-2019-14615 + - drm/i915/gen9: Clear residual context state on context switch + * PAN is broken for execute-only user mappings on ARMv8 (LP: #1858815) + - arm64: Revert support for execute-only user mappings + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-27.29 ] + + * eoan/linux: 5.3.0-27.29 -proposed tracker (LP: #1858943) + * [Regression] usb usb2-port2: Cannot enable. Maybe the USB cable is bad? + (LP: #1856608) + - SAUCE: Revert "usb: handle warm-reset port requests on hub resume" + + [ Ubuntu: 5.3.0-26.28 ] + + * eoan/linux: 5.3.0-26.28 -proposed tracker (LP: #1856807) + * nvidia-435 is in eoan, linux-restricted-modules only builds against 430, + ubiquity gives me the self-signed modules experience instead of using the + Canonical-signed modules (LP: #1856407) + - Add nvidia-435 dkms build + + -- Khalid Elmously Mon, 03 Feb 2020 02:05:35 -0500 + +linux-oracle (5.3.0-1008.9) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1008.9 -proposed tracker (LP: #1854755) + + [ Ubuntu: 5.3.0-25.27 ] + + * eoan/linux: 5.3.0-25.27 -proposed tracker (LP: #1854762) + * CVE-2019-14901 + - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() + * CVE-2019-14896 // CVE-2019-14897 + - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor + * CVE-2019-14895 + - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie() + * [CML] New device id's for CMP-H (LP: #1846335) + - mmc: sdhci-pci: Add another Id for Intel CML + - i2c: i801: Add support for Intel Comet Lake PCH-H + - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash + - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs + * i915: Display flickers (monitor loses signal briefly) during "flickerfree" + boot, while showing the BIOS logo on a black background (LP: #1836858) + - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y + * Please add patch fixing RK818 ID detection (LP: #1853192) + - SAUCE: mfd: rk808: Fix RK818 ID template + * Kernel build log filled with "/bin/bash: line 5: warning: command + substitution: ignored null byte in input" (LP: #1853843) + - [Debian] Fix warnings when checking for modules signatures + * Lenovo dock MAC Address pass through doesn't work in Ubuntu (LP: #1827961) + - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2 + * Dell XPS 13 9350/9360 headphone audio hiss (LP: #1654448) // [XPS 13 9360, + Realtek ALC3246, Black Headphone Out, Front] High noise floor (LP: #1845810) + - ALSA: hda/realtek: Reduce the Headphone static noise on XPS 9350/9360 + * no HDMI video output since GDM greeter after linux-oem-osp1 version + 5.0.0-1026 (LP: #1852386) + - drm/i915: Add new CNL PCH ID seen on a CML platform + - SAUCE: drm/i915: Fix detection for a CMP-V PCH + * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer + works on Dell Venue 11 Pro 7140 (LP: #1846539) + - [Config] Drop snd-sof-intel-bdw build + - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy + driver + * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2 + (LP: #1847451) + - SAUCE: tools/power turbostat: Add Cometlake support + * External microphone can't work on some dell machines with the codec alc256 + or alc236 (LP: #1853791) + - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table + - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table + * Memory leak in net/xfrm/xfrm_state.c - 8 pages per ipsec connection + (LP: #1853197) + - xfrm: Fix memleak on xfrm state destroy + * CVE-2019-18660: patches for Ubuntu (LP: #1853142) // CVE-2019-18660 + - powerpc/64s: support nospectre_v2 cmdline option + - powerpc/book3s64: Fix link stack flush on context switch + - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel + * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721) + - HID: i2c-hid: fix no irq after reset on raydium 3118 + * Make Goodix I2C touchpads work (LP: #1853842) + - HID: i2c-hid: Remove runtime power management + - HID: i2c-hid: Send power-on command after reset + * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901) + - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 + 2-in-1" + - lib: devres: add a helper function for ioremap_uc + - mfd: intel-lpss: Use devm_ioremap_uc for MMIO + * CVE-2019-19055 + - nl80211: fix memory leak in nl80211_get_ftm_responder_stats + * CML: perf enabling for core (LP: #1848978) + - perf/x86/intel: Add Comet Lake CPU support + - perf/x86/msr: Add Comet Lake CPU support + - perf/x86/cstate: Add Comet Lake CPU support + - perf/x86/msr: Add new CPU model numbers for Ice Lake + - perf/x86/cstate: Update C-state counters for Ice Lake + * Boot hangs after "Loading initial ramdisk ..." (LP: #1852586) + - SAUCE: Revert "tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for + interrupts" + - SAUCE: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's" + * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2 + (LP: #1847454) + - powercap/intel_rapl: add support for CometLake Mobile + - powercap/intel_rapl: add support for Cometlake desktop + * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2 + (LP: #1847450) + - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support + to intel_pmc_core driver + * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180) + - net: ena: add intr_moder_rx_interval to struct ena_com_dev and use it + - net: ena: switch to dim algorithm for rx adaptive interrupt moderation + - net: ena: reimplement set/get_coalesce() + - net: ena: enable the interrupt_moderation in driver_supported_features + - net: ena: remove code duplication in + ena_com_update_nonadaptive_moderation_interval _*() + - net: ena: remove old adaptive interrupt moderation code from ena_netdev + - net: ena: remove ena_restore_ethtool_params() and relevant fields + - net: ena: remove all old adaptive rx interrupt moderation code from ena_com + - net: ena: fix update of interrupt moderation register + - net: ena: fix retrieval of nonadaptive interrupt moderation intervals + - net: ena: fix incorrect update of intr_delay_resolution + - net: ena: Select DIMLIB for ENA_ETHERNET + - SAUCE: net: ena: fix issues in setting interrupt moderation params in + ethtool + - SAUCE: net: ena: fix too long default tx interrupt moderation interval + * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222) + - [Config] Enable ROCKCHIP support for arm64 + * remount of multilower moved pivoted-root overlayfs root, results in I/O + errors on some modified files (LP: #1824407) + - SAUCE: ovl: fix lookup failure on multi lower squashfs + * Eoan update: 5.3.13 upstream stable release (LP: #1853882) + - net: cdc_ncm: Signedness bug in cdc_ncm_set_dgram_size() + - block, bfq: deschedule empty bfq_queues not referred by any process + - mm/memory_hotplug: don't access uninitialized memmaps in shrink_pgdat_span() + - mm/memory_hotplug: fix updating the node span + - arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault + - fbdev: Ditch fb_edid_add_monspecs + - Linux 5.3.13 + * Eoan update: 5.3.12 upstream stable release (LP: #1853475) + - scsi: core: Handle drivers which set sg_tablesize to zero + - ax88172a: fix information leak on short answers + - devlink: disallow reload operation during device cleanup + - ipmr: Fix skb headroom in ipmr_get_route(). + - mlxsw: core: Enable devlink reload only on probe + - net: gemini: add missed free_netdev + - net/smc: fix fastopen for non-blocking connect() + - net: usb: qmi_wwan: add support for Foxconn T77W968 LTE modules + - slip: Fix memory leak in slip_open error path + - tcp: remove redundant new line from tcp_event_sk_skb + - dpaa2-eth: free already allocated channels on probe defer + - devlink: Add method for time-stamp on reporter's dump + - net/smc: fix refcount non-blocking connect() -part 2 + - ALSA: usb-audio: Fix missing error check at mixer resolution test + - ALSA: usb-audio: not submit urb for stopped endpoint + - ALSA: usb-audio: Fix incorrect NULL check in create_yamaha_midi_quirk() + - ALSA: usb-audio: Fix incorrect size check for processing/extension units + - Btrfs: fix log context list corruption after rename exchange operation + - cgroup: freezer: call cgroup_enter_frozen() with preemption disabled in + ptrace_stop() + - Input: ff-memless - kill timer in destroy() + - Input: synaptics-rmi4 - fix video buffer size + - Input: synaptics-rmi4 - disable the relative position IRQ in the F12 driver + - Input: synaptics-rmi4 - do not consume more data than we have (F11, F12) + - Input: synaptics-rmi4 - clear IRQ enables for F54 + - Input: synaptics-rmi4 - destroy F54 poller workqueue when removing + - KVM: MMU: Do not treat ZONE_DEVICE pages as being reserved + - IB/hfi1: Ensure r_tid_ack is valid before building TID RDMA ACK packet + - IB/hfi1: Calculate flow weight based on QP MTU for TID RDMA + - IB/hfi1: TID RDMA WRITE should not return IB_WC_RNR_RETRY_EXC_ERR + - IB/hfi1: Ensure full Gen3 speed in a Gen4 system + - IB/hfi1: Use a common pad buffer for 9B and 16B packets + - i2c: acpi: Force bus speed to 400KHz if a Silead touchscreen is present + - SAUCE: Revert "UBUNTU: SAUCE: x86/intel: Disable HPET on Intel Coffe Lake + platforms" + - x86/quirks: Disable HPET on Intel Coffe Lake platforms + - ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable + - ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable either + - io_uring: ensure registered buffer import returns the IO length + - drm/i915: update rawclk also on resume + - Revert "drm/i915/ehl: Update MOCS table for EHL" + - ntp/y2038: Remove incorrect time_t truncation + - net: ethernet: dwmac-sun8i: Use the correct function in exit path + - iommu/vt-d: Fix QI_DEV_IOTLB_PFSID and QI_DEV_EIOTLB_PFSID macros + - mm: mempolicy: fix the wrong return value and potential pages leak of mbind + - mm: memcg: switch to css_tryget() in get_mem_cgroup_from_mm() + - mm: hugetlb: switch to css_tryget() in hugetlb_cgroup_charge_cgroup() + - mm: slub: really fix slab walking for init_on_free + - mm/memory_hotplug: fix try_offline_node() + - mm/page_io.c: do not free shared swap slots + - mmc: sdhci-of-at91: fix quirk2 overwrite + - slcan: Fix memory leak in error path + - Linux 5.3.12 + * Eoan update: 5.3.11 upstream stable release (LP: #1852338) + - bonding: fix state transition issue in link monitoring + - CDC-NCM: handle incomplete transfer of MTU + - ipv4: Fix table id reference in fib_sync_down_addr + - net: ethernet: octeon_mgmt: Account for second possible VLAN header + - net: fix data-race in neigh_event_send() + - net: qualcomm: rmnet: Fix potential UAF when unregistering + - net/tls: fix sk_msg trim on fallback to copy mode + - net: usb: qmi_wwan: add support for DW5821e with eSIM support + - NFC: fdp: fix incorrect free object + - nfc: netlink: fix double device reference drop + - NFC: st21nfca: fix double free + - qede: fix NULL pointer deref in __qede_remove() + - net: mscc: ocelot: don't handle netdev events for other netdevs + - net: mscc: ocelot: fix NULL pointer on LAG slave removal + - net/tls: don't pay attention to sk_write_pending when pushing partial + records + - net/tls: add a TX lock + - selftests/tls: add test for concurrent recv and send + - ipv6: fixes rt6_probe() and fib6_nh->last_probe init + - net: hns: Fix the stray netpoll locks causing deadlock in NAPI path + - net: prevent load/store tearing on sk->sk_stamp + - net: sched: prevent duplicate flower rules from tcf_proto destroy race + - net/smc: fix ethernet interface refcounting + - vsock/virtio: fix sock refcnt holding during the shutdown + - r8169: fix page read in r8168g_mdio_read + - ALSA: timer: Fix incorrectly assigned timer instance + - ALSA: bebob: fix to detect configured source of sampling clock for Focusrite + Saffire Pro i/o series + - ALSA: hda/ca0132 - Fix possible workqueue stall + - mm: memcontrol: fix NULL-ptr deref in percpu stats flush + - mm: memcontrol: fix network errors from failing __GFP_ATOMIC charges + - mm, meminit: recalculate pcpu batch and high limits after init completes + - mm: thp: handle page cache THP correctly in PageTransCompoundMap + - mm, vmstat: hide /proc/pagetypeinfo from normal users + - dump_stack: avoid the livelock of the dump_lock + - mm: slab: make page_cgroup_ino() to recognize non-compound slab pages + properly + - btrfs: Consider system chunk array size for new SYSTEM chunks + - btrfs: tree-checker: Fix wrong check on max devid + - btrfs: save i_size to avoid double evaluation of i_size_read in + compress_file_range + - tools: gpio: Use !building_out_of_srctree to determine srctree + - pinctrl: intel: Avoid potential glitches if pin is in GPIO mode + - perf tools: Fix time sorting + - perf map: Use zalloc for map_groups + - drm/radeon: fix si_enable_smc_cac() failed issue + - HID: wacom: generic: Treat serial number and related fields as unsigned + - mm/khugepaged: fix might_sleep() warn with CONFIG_HIGHPTE=y + - soundwire: depend on ACPI + - soundwire: depend on ACPI || OF + - soundwire: bus: set initial value to port_status + - blkcg: make blkcg_print_stat() print stats only for online blkgs + - arm64: Do not mask out PTE_RDONLY in pte_same() + - ASoC: rsnd: dma: fix SSI9 4/5/6/7 busif dma address + - ceph: fix use-after-free in __ceph_remove_cap() + - ceph: fix RCU case handling in ceph_d_revalidate() + - ceph: add missing check in d_revalidate snapdir handling + - ceph: don't try to handle hashed dentries in non-O_CREAT atomic_open + - ceph: don't allow copy_file_range when stripe_count != 1 + - iio: adc: stm32-adc: fix stopping dma + - iio: imu: adis16480: make sure provided frequency is positive + - iio: imu: inv_mpu6050: fix no data on MPU6050 + - iio: srf04: fix wrong limitation in distance measuring + - ARM: sunxi: Fix CPU powerdown on A83T + - ARM: dts: imx6-logicpd: Re-enable SNVS power key + - cpufreq: intel_pstate: Fix invalid EPB setting + - clone3: validate stack arguments + - netfilter: nf_tables: Align nft_expr private data to 64-bit + - netfilter: ipset: Fix an error code in ip_set_sockfn_get() + - intel_th: gth: Fix the window switching sequence + - intel_th: pci: Add Comet Lake PCH support + - intel_th: pci: Add Jasper Lake PCH support + - x86/dumpstack/64: Don't evaluate exception stacks before setup + - x86/apic/32: Avoid bogus LDR warnings + - SMB3: Fix persistent handles reconnect + - can: usb_8dev: fix use-after-free on disconnect + - can: flexcan: disable completely the ECC mechanism + - can: c_can: c_can_poll(): only read status register after status IRQ + - can: peak_usb: fix a potential out-of-sync while decoding packets + - can: rx-offload: can_rx_offload_queue_sorted(): fix error handling, avoid + skb mem leak + - can: gs_usb: gs_can_open(): prevent memory leak + - can: dev: add missing of_node_put() after calling of_get_child_by_name() + - can: mcba_usb: fix use-after-free on disconnect + - can: peak_usb: fix slab info leak + - configfs: fix a deadlock in configfs_symlink() + - ALSA: usb-audio: More validations of descriptor units + - ALSA: usb-audio: Simplify parse_audio_unit() + - ALSA: usb-audio: Unify the release of usb_mixer_elem_info objects + - ALSA: usb-audio: Remove superfluous bLength checks + - ALSA: usb-audio: Clean up check_input_term() + - ALSA: usb-audio: Fix possible NULL dereference at create_yamaha_midi_quirk() + - ALSA: usb-audio: remove some dead code + - ALSA: usb-audio: Fix copy&paste error in the validator + - usbip: Implement SG support to vhci-hcd and stub driver + - HID: google: add magnemite/masterball USB ids + - dmaengine: sprd: Fix the link-list pointer register configuration issue + - bpf: lwtunnel: Fix reroute supplying invalid dst + - dmaengine: xilinx_dma: Fix 64-bit simple AXIDMA transfer + - dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config + - dmaengine: sprd: Fix the possible memory leak issue + - HID: intel-ish-hid: fix wrong error handling in ishtp_cl_alloc_tx_ring() + - powerpc/32s: fix allow/prevent_user_access() when crossing segment + boundaries. + - RDMA/mlx5: Clear old rate limit when closing QP + - iw_cxgb4: fix ECN check on the passive accept + - RDMA/siw: free siw_base_qp in kref release routine + - RDMA/qedr: Fix reported firmware version + - IB/core: Use rdma_read_gid_l2_fields to compare GID L2 fields + - net/mlx5e: Tx, Fix assumption of single WQEBB of NOP in cleanup flow + - net/mlx5e: kTLS, Release reference on DUMPed fragments in shutdown flow + - net/mlx5e: TX, Fix consumer index of error cqe dump + - net/mlx5: prevent memory leak in mlx5_fpga_conn_create_cq + - net/mlx5: fix memory leak in mlx5_fw_fatal_reporter_dump + - selftests/bpf: More compatible nc options in test_tc_edt + - scsi: qla2xxx: fixup incorrect usage of host_byte + - scsi: lpfc: Check queue pointer before use + - scsi: ufs-bsg: Wake the device before sending raw upiu commands + - ARC: [plat-hsdk]: Enable on-board SPI NOR flash IC + - RDMA/uverbs: Prevent potential underflow + - bpf: Fix use after free in subprog's jited symbol removal + - net: stmmac: Fix the problem of tso_xmit + - net: openvswitch: free vport unless register_netdevice() succeeds + - scsi: lpfc: Honor module parameter lpfc_use_adisc + - scsi: qla2xxx: Initialized mailbox to prevent driver load failure + - bpf: Fix use after free in bpf_get_prog_name + - iwlwifi: pcie: fix PCI ID 0x2720 configs that should be soc + - iwlwifi: pcie: fix all 9460 entries for qnj + - iwlwifi: pcie: 0x2720 is qu and 0x30DC is not + - netfilter: nf_flow_table: set timeout before insertion into hashes + - drm/v3d: Fix memory leak in v3d_submit_cl_ioctl + - xsk: Fix registration of Rx-only sockets + - net: phy: smsc: LAN8740: add PHY_RST_AFTER_CLK_EN flag + - ipvs: don't ignore errors in case refcounting ip_vs module fails + - ipvs: move old_secure_tcp into struct netns_ipvs + - netfilter: nft_payload: fix missing check for matching length in offloads + - RDMA/nldev: Skip counter if port doesn't match + - bonding: fix unexpected IFF_BONDING bit unset + - bonding: use dynamic lockdep key instead of subclass + - macsec: fix refcnt leak in module exit routine + - virt_wifi: fix refcnt leak in module exit routine + - scsi: sd: define variable dif as unsigned int instead of bool + - usb: dwc3: select CONFIG_REGMAP_MMIO + - usb: fsl: Check memory resource before releasing it + - usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode. + - usb: gadget: composite: Fix possible double free memory bug + - usb: dwc3: pci: prevent memory leak in dwc3_pci_probe + - usb: gadget: configfs: fix concurrent issue between composite APIs + - usb: dwc3: remove the call trace of USBx_GFLADJ + - perf/x86/amd/ibs: Fix reading of the IBS OpData register and thus precise + RIP validity + - perf/x86/amd/ibs: Handle erratum #420 only on the affected CPU family (10h) + - perf/x86/uncore: Fix event group support + - USB: Skip endpoints with 0 maxpacket length + - USB: ldusb: use unsigned size format specifiers + - usbip: tools: Fix read_usb_vudc_device() error path handling + - RDMA/iw_cxgb4: Avoid freeing skb twice in arp failure case + - RDMA/hns: Prevent memory leaks of eq->buf_list + - hwmon: (ina3221) Fix read timeout issue + - scsi: qla2xxx: stop timer in shutdown path + - sched/topology: Don't try to build empty sched domains + - sched/topology: Allow sched_asym_cpucapacity to be disabled + - nvme-multipath: fix possible io hang after ctrl reconnect + - fjes: Handle workqueue allocation failure + - net: hisilicon: Fix "Trying to free already-free IRQ" + - wimax: i2400: Fix memory leak in i2400m_op_rfkill_sw_toggle + - net: mscc: ocelot: fix vlan_filtering when enslaving to bridge before link + is up + - net: mscc: ocelot: refuse to overwrite the port's native vlan + - iommu/amd: Apply the same IVRS IOAPIC workaround to Acer Aspire A315-41 + - mt76: dma: fix buffer unmap with non-linear skbs + - drm/amdgpu/sdma5: do not execute 0-sized IBs (v2) + - drm/sched: Set error to s_fence if HW job submission failed. + - drm/amdgpu: If amdgpu_ib_schedule fails return back the error. + - drm/amd/display: do not synchronize "drr" displays + - drm/amd/display: add 50us buffer as WA for pstate switch in active + - drm/amd/display: Passive DP->HDMI dongle detection fix + - dc.c:use kzalloc without test + - SUNRPC: The TCP back channel mustn't disappear while requests are + outstanding + - SUNRPC: The RDMA back channel mustn't disappear while requests are + outstanding + - SUNRPC: Destroy the back channel when we destroy the host transport + - hv_netvsc: Fix error handling in netvsc_attach() + - efi/tpm: Return -EINVAL when determining tpm final events log size fails + - efi: libstub/arm: Account for firmware reserved memory at the base of RAM + - x86, efi: Never relocate kernel below lowest acceptable address + - arm64: cpufeature: Enable Qualcomm Falkor errata 1009 for Kryo + - usb: dwc3: gadget: fix race when disabling ep with cancelled xfers + - arm64: apply ARM64_ERRATUM_845719 workaround for Brahma-B53 core + - arm64: Brahma-B53 is SSB and spectre v2 safe + - arm64: apply ARM64_ERRATUM_843419 workaround for Brahma-B53 core + - NFSv4: Don't allow a cached open with a revoked delegation + - net: ethernet: arc: add the missed clk_disable_unprepare + - igb: Fix constant media auto sense switching when no cable is connected + - e1000: fix memory leaks + - gve: Fixes DMA synchronization. + - ocfs2: protect extent tree in ocfs2_prepare_inode_for_write() + - pinctrl: cherryview: Fix irq_valid_mask calculation + - clk: imx8m: Use SYS_PLL1_800M as intermediate parent of CLK_ARM + - timekeeping/vsyscall: Update VDSO data unconditionally + - mm/filemap.c: don't initiate writeback if mapping has no dirty pages + - cgroup,writeback: don't switch wbs immediately on dead wbs if the memcg is + dead + - ARM: dts: stm32: change joystick pinctrl definition on stm32mp157c-ev1 + - ASoC: SOF: Intel: hda-stream: fix the CONFIG_ prefix missing + - usbip: Fix free of unallocated memory in vhci tx + - bonding: fix using uninitialized mode_lock + - netfilter: ipset: Copy the right MAC address in hash:ip,mac IPv6 sets + - arm64: errata: Update stale comment + - net/ibmvnic: unlock rtnl_lock in reset so linkwatch_event can run + - SAUCE: Revert "UBUNTU: SAUCE: kvm: x86: mmu: Recovery of shattered NX large + pages" + - SAUCE: Revert "UBUNTU: SAUCE: kvm: Add helper function for creating VM + worker threads" + - SAUCE: Revert "UBUNTU: SAUCE: kvm: mmu: ITLB_MULTIHIT mitigation" + - SAUCE: Revert "kvm: x86, powerpc: do not allow clearing largepages debugfs + entry" + - SAUCE: Revert "UBUNTU: SAUCE: cpu/speculation: Uninline and export CPU + mitigations helpers" + - SAUCE: Revert "UBUNTU: SAUCE: x86: Add ITLB_MULTIHIT bug infrastructure" + - SAUCE: Revert "x86/tsx: Add config options to set tsx=on|off|auto" + - SAUCE: Revert "x86/speculation/taa: Add documentation for TSX Async Abort" + - SAUCE: Revert "x86/tsx: Add "auto" option to the tsx= cmdline parameter" + - SAUCE: Revert "kvm/x86: Export MDS_NO=0 to guests when TSX is enabled" + - SAUCE: Revert "x86/speculation/taa: Add sysfs reporting for TSX Async Abort" + - SAUCE: Revert "x86/speculation/taa: Add mitigation for TSX Async Abort" + - SAUCE: Revert "x86/cpu: Add a "tsx=" cmdline option with TSX disabled by + default" + - SAUCE: Revert "x86/cpu: Add a helper function x86_read_arch_cap_msr()" + - SAUCE: Revert "x86/msr: Add the IA32_TSX_CTRL MSR" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Fix jump whitelist + clearing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/gen8+: Add RC6 CTX corruption WA" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Lower RM timeout to avoid DSI hard + hangs" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Ignore Length operands + during command matching" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Add support for backward + jumps" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Use explicit goto for + error paths" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Add gen9 BCS cmdparsing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Allow parsing of unsized batches" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Support ro ppgtt mapped cmdparser + shadow buffers" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Add support for mandatory + cmdparsing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Remove Master tables from cmdparser" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Disable Secure Batches for gen6+" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Rename gen7 cmdparser tables" + - drm/i915: Rename gen7 cmdparser tables + - drm/i915: Disable Secure Batches for gen6+ + - drm/i915: Remove Master tables from cmdparser + - drm/i915: Add support for mandatory cmdparsing + - drm/i915: Support ro ppgtt mapped cmdparser shadow buffers + - drm/i915: Allow parsing of unsized batches + - drm/i915: Add gen9 BCS cmdparsing + - drm/i915/cmdparser: Use explicit goto for error paths + - drm/i915/cmdparser: Add support for backward jumps + - drm/i915/cmdparser: Ignore Length operands during command matching + - drm/i915: Lower RM timeout to avoid DSI hard hangs + - drm/i915/gen8+: Add RC6 CTX corruption WA + - drm/i915/cmdparser: Fix jump whitelist clearing + - x86/msr: Add the IA32_TSX_CTRL MSR + - x86/cpu: Add a helper function x86_read_arch_cap_msr() + - x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default + - x86/speculation/taa: Add mitigation for TSX Async Abort + - x86/speculation/taa: Add sysfs reporting for TSX Async Abort + - kvm/x86: Export MDS_NO=0 to guests when TSX is enabled + - x86/tsx: Add "auto" option to the tsx= cmdline parameter + - x86/speculation/taa: Add documentation for TSX Async Abort + - x86/tsx: Add config options to set tsx=on|off|auto + - x86/speculation/taa: Fix printing of TAA_MSG_SMT on IBRS_ALL CPUs + - x86/bugs: Add ITLB_MULTIHIT bug infrastructure + - x86/cpu: Add Tremont to the cpu vulnerability whitelist + - cpu/speculation: Uninline and export CPU mitigations helpers + - Documentation: Add ITLB_MULTIHIT documentation + - kvm: x86, powerpc: do not allow clearing largepages debugfs entry + - kvm: mmu: ITLB_MULTIHIT mitigation + - kvm: Add helper function for creating VM worker threads + - kvm: x86: mmu: Recovery of shattered NX large pages + - Linux 5.3.11 + * The alsa hda driver is not loaded due to the missing of PCIID for Comet + Lake-S [8086:a3f0] (LP: #1852070) + - SAUCE: ALSA: hda: Add Cometlake-S PCI ID + * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877) + - SAUCE: platform/x86: dell-uart-backlight: add missing status command + - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status + - SAUCE: platform/x86: dell-uart-backlight: add force parameter + - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms + * Disable unreliable HPET on CFL-H system (LP: #1852216) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms + * i40e: Setting VF MAC address causes General Protection Fault (LP: #1852432) + - i40e: Fix crash caused by stress setting of VF MAC addresses + * CVE-2019-19072 + - tracing: Have error path in predicate_parse() free its allocated memory + * i40e: general protection fault in i40e_config_vf_promiscuous_mode + (LP: #1852663) + - SAUCE: i40e Fix GPF when deleting VMs + * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO + (LP: #1852581) + - [Packaging] Fix module signing with older modinfo + + -- Manoj Iyer Thu, 05 Dec 2019 09:10:06 -0600 + +linux-oracle (5.3.0-1007.8) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1007.8 -proposed tracker (LP: #1852230) + + * Eoan update: 5.3.10 upstream stable release (LP: #1852111) + - [Config] SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1=n + + [ Ubuntu: 5.3.0-24.26 ] + + * eoan/linux: 5.3.0-24.26 -proposed tracker (LP: #1852232) + * Eoan update: 5.3.9 upstream stable release (LP: #1851550) + - io_uring: fix up O_NONBLOCK handling for sockets + - dm snapshot: introduce account_start_copy() and account_end_copy() + - dm snapshot: rework COW throttling to fix deadlock + - Btrfs: fix inode cache block reserve leak on failure to allocate data space + - btrfs: qgroup: Always free PREALLOC META reserve in + btrfs_delalloc_release_extents() + - iio: adc: meson_saradc: Fix memory allocation order + - iio: fix center temperature of bmc150-accel-core + - libsubcmd: Make _FORTIFY_SOURCE defines dependent on the feature + - perf tests: Avoid raising SEGV using an obvious NULL dereference + - perf map: Fix overlapped map handling + - perf script brstackinsn: Fix recovery from LBR/binary mismatch + - perf jevents: Fix period for Intel fixed counters + - perf tools: Propagate get_cpuid() error + - perf annotate: Propagate perf_env__arch() error + - perf annotate: Fix the signedness of failure returns + - perf annotate: Propagate the symbol__annotate() error return + - perf annotate: Fix arch specific ->init() failure errors + - perf annotate: Return appropriate error code for allocation failures + - perf annotate: Don't return -1 for error when doing BPF disassembly + - staging: rtl8188eu: fix null dereference when kzalloc fails + - RDMA/siw: Fix serialization issue in write_space() + - RDMA/hfi1: Prevent memory leak in sdma_init + - RDMA/iw_cxgb4: fix SRQ access from dump_qp() + - RDMA/iwcm: Fix a lock inversion issue + - HID: hyperv: Use in-place iterator API in the channel callback + - kselftest: exclude failed TARGETS from runlist + - selftests/kselftest/runner.sh: Add 45 second timeout per test + - nfs: Fix nfsi->nrequests count error on nfs_inode_remove_request + - arm64: cpufeature: Effectively expose FRINT capability to userspace + - arm64: Fix incorrect irqflag restore for priority masking for compat + - arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1 #1542419 + - tty: serial: owl: Fix the link time qualifier of 'owl_uart_exit()' + - tty: serial: rda: Fix the link time qualifier of 'rda_uart_exit()' + - serial/sifive: select SERIAL_EARLYCON + - tty: n_hdlc: fix build on SPARC + - misc: fastrpc: prevent memory leak in fastrpc_dma_buf_attach + - RDMA/core: Fix an error handling path in 'res_get_common_doit()' + - RDMA/cm: Fix memory leak in cm_add/remove_one + - RDMA/nldev: Reshuffle the code to avoid need to rebind QP in error path + - RDMA/mlx5: Do not allow rereg of a ODP MR + - RDMA/mlx5: Order num_pending_prefetch properly with synchronize_srcu + - RDMA/mlx5: Add missing synchronize_srcu() for MW cases + - gpio: max77620: Use correct unit for debounce times + - fs: cifs: mute -Wunused-const-variable message + - arm64: vdso32: Fix broken compat vDSO build warnings + - arm64: vdso32: Detect binutils support for dmb ishld + - serial: mctrl_gpio: Check for NULL pointer + - serial: 8250_omap: Fix gpio check for auto RTS/CTS + - arm64: Default to building compat vDSO with clang when CONFIG_CC_IS_CLANG + - arm64: vdso32: Don't use KBUILD_CPPFLAGS unconditionally + - efi/cper: Fix endianness of PCIe class code + - efi/x86: Do not clean dummy variable in kexec path + - MIPS: include: Mark __cmpxchg as __always_inline + - riscv: avoid kernel hangs when trapped in BUG() + - riscv: avoid sending a SIGTRAP to a user thread trapped in WARN() + - riscv: Correct the handling of unexpected ebreak in do_trap_break() + - x86/xen: Return from panic notifier + - ocfs2: clear zero in unaligned direct IO + - fs: ocfs2: fix possible null-pointer dereferences in + ocfs2_xa_prepare_entry() + - fs: ocfs2: fix a possible null-pointer dereference in + ocfs2_write_end_nolock() + - fs: ocfs2: fix a possible null-pointer dereference in + ocfs2_info_scan_inode_alloc() + - btrfs: silence maybe-uninitialized warning in clone_range + - arm64: armv8_deprecated: Checking return value for memory allocation + - sched/fair: Scale bandwidth quota and period without losing quota/period + ratio precision + - sched/vtime: Fix guest/system mis-accounting on task switch + - perf/core: Rework memory accounting in perf_mmap() + - perf/core: Fix corner case in perf_rotate_context() + - perf/x86/amd: Change/fix NMI latency mitigation to use a timestamp + - drm/amdgpu: fix memory leak + - iio: imu: adis16400: release allocated memory on failure + - iio: imu: adis16400: fix memory leak + - iio: imu: st_lsm6dsx: fix waitime for st_lsm6dsx i2c controller + - MIPS: include: Mark __xchg as __always_inline + - MIPS: fw: sni: Fix out of bounds init of o32 stack + - s390/cio: fix virtio-ccw DMA without PV + - virt: vbox: fix memory leak in hgcm_call_preprocess_linaddr + - nbd: fix possible sysfs duplicate warning + - NFSv4: Fix leak of clp->cl_acceptor string + - SUNRPC: fix race to sk_err after xs_error_report + - s390/uaccess: avoid (false positive) compiler warnings + - tracing: Initialize iter->seq after zeroing in tracing_read_pipe() + - perf annotate: Fix multiple memory and file descriptor leaks + - perf/aux: Fix tracking of auxiliary trace buffer allocation + - USB: legousbtower: fix a signedness bug in tower_probe() + - nbd: verify socket is supported during setup + - fuse: flush dirty data/metadata before non-truncate setattr + - fuse: truncate pending writes on O_TRUNC + - ALSA: bebob: Fix prototype of helper function to return negative value + - ALSA: timer: Fix mutex deadlock at releasing card + - ath10k: fix latency issue for QCA988x + - UAS: Revert commit 3ae62a42090f ("UAS: fix alignment of scatter/gather + segments") + - nl80211: fix validation of mesh path nexthop + - USB: gadget: Reject endpoints with 0 maxpacket value + - usb-storage: Revert commit 747668dbc061 ("usb-storage: Set + virt_boundary_mask to avoid SG overflows") + - USB: ldusb: fix ring-buffer locking + - USB: ldusb: fix control-message timeout + - usb: xhci: fix Immediate Data Transfer endianness + - usb: xhci: fix __le32/__le64 accessors in debugfs code + - USB: serial: whiteheat: fix potential slab corruption + - USB: serial: whiteheat: fix line-speed endianness + - xhci: Fix use-after-free regression in xhci clear hub TT implementation + - scsi: qla2xxx: Fix partial flash write of MBI + - scsi: target: cxgbit: Fix cxgbit_fw4_ack() + - HID: i2c-hid: add Trekstor Primebook C11B to descriptor override + - HID: Fix assumption that devices have inputs + - HID: fix error message in hid_open_report() + - HID: logitech-hidpp: split g920_get_config() + - HID: logitech-hidpp: rework device validation + - HID: logitech-hidpp: do all FF cleanup in hidpp_ff_destroy() + - um-ubd: Entrust re-queue to the upper layers + - s390/unwind: fix mixing regs and sp + - s390/cmm: fix information leak in cmm_timeout_handler() + - s390/idle: fix cpu idle time calculation + - ARC: perf: Accommodate big-endian CPU + - IB/hfi1: Avoid excessive retry for TID RDMA READ request + - arm64: Ensure VM_WRITE|VM_SHARED ptes are clean by default + - arm64: cpufeature: Enable Qualcomm Falkor/Kryo errata 1003 + - virtio_ring: fix stalls for packed rings + - rtlwifi: rtl_pci: Fix problem of too small skb->len + - dmaengine: qcom: bam_dma: Fix resource leak + - dmaengine: tegra210-adma: fix transfer failure + - dmaengine: imx-sdma: fix size check for sdma script_number + - dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle + - drm/amdgpu/gmc10: properly set BANK_SELECT and FRAGMENT_SIZE + - drm/i915: Fix PCH reference clock for FDI on HSW/BDW + - drm/amdgpu/gfx10: update gfx golden settings + - drm/amdgpu/powerplay/vega10: allow undervolting in p7 + - drm/amdgpu: Fix SDMA hang when performing VKexample test + - NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid() + - io_uring: ensure we clear io_kiocb->result before each issue + - iommu/vt-d: Fix panic after kexec -p for kdump + - batman-adv: Avoid free/alloc race when handling OGM buffer + - llc: fix sk_buff leak in llc_sap_state_process() + - llc: fix sk_buff leak in llc_conn_service() + - rxrpc: Fix call ref leak + - rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record + - rxrpc: Fix trace-after-put looking at the put peer record + - NFC: pn533: fix use-after-free and memleaks + - bonding: fix potential NULL deref in bond_update_slave_arr + - netfilter: conntrack: avoid possible false sharing + - net: usb: sr9800: fix uninitialized local variable + - sch_netem: fix rcu splat in netem_enqueue() + - net: sched: sch_sfb: don't call qdisc_put() while holding tree lock + - iwlwifi: exclude GEO SAR support for 3168 + - sched/fair: Fix low cpu usage with high throttling by removing expiration of + cpu-local slices + - ALSA: usb-audio: DSD auto-detection for Playback Designs + - ALSA: usb-audio: Update DSD support quirks for Oppo and Rotel + - ALSA: usb-audio: Add DSD support for Gustard U16/X26 USB Interface + - RDMA/mlx5: Use irq xarray locking for mkey_table + - sched/fair: Fix -Wunused-but-set-variable warnings + - powerpc/powernv: Fix CPU idle to be called with IRQs disabled + - Revert "nvme: allow 64-bit results in passthru commands" + - Revert "ALSA: hda: Flush interrupts on disabling" + - Linux 5.3.9 + - [Config] Remove CONFIG_GENERIC_COMPAT_VDSO and + CONFIG_CROSS_COMPILE_COMPAT_VDSO + * Eoan update: v5.3.8 upstream stable release (LP: #1850456) + - drm: Free the writeback_job when it with an empty fb + - drm: Clear the fence pointer when writeback job signaled + - clk: ti: dra7: Fix mcasp8 clock bits + - ARM: dts: Fix wrong clocks for dra7 mcasp + - nvme-pci: Fix a race in controller removal + - scsi: ufs: skip shutdown if hba is not powered + - scsi: megaraid: disable device when probe failed after enabled device + - scsi: qla2xxx: Silence fwdump template message + - scsi: qla2xxx: Fix unbound sleep in fcport delete path. + - scsi: qla2xxx: Fix stale mem access on driver unload + - scsi: qla2xxx: Fix N2N link reset + - scsi: qla2xxx: Fix N2N link up fail + - ARM: dts: Fix gpio0 flags for am335x-icev2 + - ARM: OMAP2+: Fix missing reset done flag for am3 and am43 + - ARM: OMAP2+: Add missing LCDC midlemode for am335x + - ARM: OMAP2+: Fix warnings with broken omap2_set_init_voltage() + - nvme-tcp: fix wrong stop condition in io_work + - nvme-pci: Save PCI state before putting drive into deepest state + - nvme: fix an error code in nvme_init_subsystem() + - nvme-rdma: Fix max_hw_sectors calculation + - Added QUIRKs for ADATA XPG SX8200 Pro 512GB + - nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T + - nvme: allow 64-bit results in passthru commands + - drm/komeda: prevent memory leak in komeda_wb_connector_add + - nvme-rdma: fix possible use-after-free in connect timeout + - blk-mq: honor IO scheduler for multiqueue devices + - ieee802154: ca8210: prevent memory leak + - ARM: dts: am4372: Set memory bandwidth limit for DISPC + - net: dsa: qca8k: Use up to 7 ports for all operations + - MIPS: dts: ar9331: fix interrupt-controller size + - xen/efi: Set nonblocking callbacks + - loop: change queue block size to match when using DIO + - nl80211: fix null pointer dereference + - mac80211: fix txq null pointer dereference + - netfilter: nft_connlimit: disable bh on garbage collection + - net: mscc: ocelot: add missing of_node_put after calling + of_get_child_by_name + - net: dsa: rtl8366rb: add missing of_node_put after calling + of_get_child_by_name + - net: stmmac: xgmac: Not all Unicast addresses may be available + - net: stmmac: dwmac4: Always update the MAC Hash Filter + - net: stmmac: Correctly take timestamp for PTPv2 + - net: stmmac: Do not stop PHY if WoL is enabled + - net: ag71xx: fix mdio subnode support + - RISC-V: Clear load reservations while restoring hart contexts + - riscv: Fix memblock reservation for device tree blob + - drm/amdgpu: fix multiple memory leaks in acp_hw_init + - drm/amd/display: memory leak + - mips: Loongson: Fix the link time qualifier of 'serial_exit()' + - net: hisilicon: Fix usage of uninitialized variable in function + mdio_sc_cfg_reg_write() + - net: stmmac: Avoid deadlock on suspend/resume + - selftests: kvm: Fix libkvm build error + - lib: textsearch: fix escapes in example code + - s390/mm: fix -Wunused-but-set-variable warnings + - net: phy: allow for reset line to be tied to a sleepy GPIO controller + - net: phy: fix write to mii-ctrl1000 register + - namespace: fix namespace.pl script to support relative paths + - Convert filldir[64]() from __put_user() to unsafe_put_user() + - elf: don't use MAP_FIXED_NOREPLACE for elf executable mappings + - Make filldir[64]() verify the directory entry filename is valid + - uaccess: implement a proper unsafe_copy_to_user() and switch filldir over to + it + - filldir[64]: remove WARN_ON_ONCE() for bad directory entries + - net_sched: fix backward compatibility for TCA_KIND + - net_sched: fix backward compatibility for TCA_ACT_KIND + - libata/ahci: Fix PCS quirk application + - Revert "drm/radeon: Fix EEH during kexec" + - ocfs2: fix panic due to ocfs2_wq is null + - nvme-pci: Set the prp2 correctly when using more than 4k page + - ipv4: fix race condition between route lookup and invalidation + - ipv4: Return -ENETUNREACH if we can't create route but saddr is valid + - net: avoid potential infinite loop in tc_ctl_action() + - net: bcmgenet: Fix RGMII_MODE_EN value for GENET v1/2/3 + - net: bcmgenet: Set phydev->dev_flags only for internal PHYs + - net: i82596: fix dma_alloc_attr for sni_82596 + - net/ibmvnic: Fix EOI when running in XIVE mode. + - net: ipv6: fix listify ip6_rcv_finish in case of forwarding + - net: stmmac: disable/enable ptp_ref_clk in suspend/resume flow + - rxrpc: Fix possible NULL pointer access in ICMP handling + - sched: etf: Fix ordering of packets with same txtime + - sctp: change sctp_prot .no_autobind with true + - net: aquantia: temperature retrieval fix + - net: aquantia: when cleaning hw cache it should be toggled + - net: aquantia: do not pass lro session with invalid tcp checksum + - net: aquantia: correctly handle macvlan and multicast coexistence + - net: phy: micrel: Discern KSZ8051 and KSZ8795 PHYs + - net: phy: micrel: Update KSZ87xx PHY name + - net: avoid errors when trying to pop MLPS header on non-MPLS packets + - net/sched: fix corrupted L2 header with MPLS 'push' and 'pop' actions + - netdevsim: Fix error handling in nsim_fib_init and nsim_fib_exit + - net: ethernet: broadcom: have drivers select DIMLIB as needed + - net: phy: Fix "link partner" information disappear issue + - rxrpc: use rcu protection while reading sk->sk_user_data + - io_uring: fix bad inflight accounting for SETUP_IOPOLL|SETUP_SQTHREAD + - io_uring: Fix corrupted user_data + - USB: legousbtower: fix memleak on disconnect + - ALSA: hda/realtek - Add support for ALC711 + - ALSA: hda/realtek - Enable headset mic on Asus MJ401TA + - ALSA: usb-audio: Disable quirks for BOSS Katana amplifiers + - ALSA: hda - Force runtime PM on Nvidia HDMI codecs + - usb: udc: lpc32xx: fix bad bit shift operation + - USB: serial: ti_usb_3410_5052: fix port-close races + - USB: ldusb: fix memleak on disconnect + - USB: usblp: fix use-after-free on disconnect + - USB: ldusb: fix read info leaks + - binder: Don't modify VMA bounds in ->mmap handler + - MIPS: tlbex: Fix build_restore_pagemask KScratch restore + - staging: wlan-ng: fix exit return when sme->key_idx >= NUM_WEPKEYS + - scsi: zfcp: fix reaction on bit error threshold notification + - scsi: sd: Ignore a failure to sync cache due to lack of authorization + - scsi: core: save/restore command resid for error handling + - scsi: core: try to get module before removing device + - scsi: ch: Make it possible to open a ch device multiple times again + - Revert "Input: elantech - enable SMBus on new (2018+) systems" + - Input: da9063 - fix capability and drop KEY_SLEEP + - Input: synaptics-rmi4 - avoid processing unknown IRQs + - Input: st1232 - fix reporting multitouch coordinates + - ASoC: rsnd: Reinitialize bit clock inversion flag for every format setting + - ACPI: CPPC: Set pcc_data[pcc_ss_id] to NULL in acpi_cppc_processor_exit() + - ACPI: NFIT: Fix unlock on error in scrub_show() + - iwlwifi: pcie: change qu with jf devices to use qu configuration + - cfg80211: wext: avoid copying malformed SSIDs + - mac80211: Reject malformed SSID elements + - drm/ttm: Restore ttm prefaulting + - drm/panfrost: Handle resetting on timeout better + - drm/amdgpu: Bail earlier when amdgpu.cik_/si_support is not set to 1 + - drm/amdgpu/sdma5: fix mask value of POLL_REGMEM packet for pipe sync + - drm/i915/userptr: Never allow userptr into the mappable GGTT + - drm/i915: Favor last VBT child device with conflicting AUX ch/DDC pin + - drm/amdgpu/vce: fix allocation size in enc ring test + - drm/amdgpu/vcn: fix allocation size in enc ring test + - drm/amdgpu/uvd6: fix allocation size in enc ring test (v2) + - drm/amdgpu/uvd7: fix allocation size in enc ring test (v2) + - drm/amdgpu: user pages array memory leak fix + - drivers/base/memory.c: don't access uninitialized memmaps in + soft_offline_page_store() + - fs/proc/page.c: don't access uninitialized memmaps in fs/proc/page.c + - io_uring: Fix broken links with offloading + - io_uring: Fix race for sqes with userspace + - io_uring: used cached copies of sq->dropped and cq->overflow + - mmc: mxs: fix flags passed to dmaengine_prep_slave_sg + - mmc: cqhci: Commit descriptors before setting the doorbell + - mmc: sdhci-omap: Fix Tuning procedure for temperatures < -20C + - mm/memory-failure.c: don't access uninitialized memmaps in memory_failure() + - mm/slub: fix a deadlock in show_slab_objects() + - mm/page_owner: don't access uninitialized memmaps when reading + /proc/pagetypeinfo + - mm/memunmap: don't access uninitialized memmap in memunmap_pages() + - mm: memcg/slab: fix panic in __free_slab() caused by premature memcg pointer + release + - mm, compaction: fix wrong pfn handling in __reset_isolation_pfn() + - mm: memcg: get number of pages on the LRU list in memcgroup base on + lru_zone_size + - mm: memblock: do not enforce current limit for memblock_phys* family + - hugetlbfs: don't access uninitialized memmaps in pfn_range_valid_gigantic() + - mm/memory-failure: poison read receives SIGKILL instead of SIGBUS if mmaped + more than once + - zram: fix race between backing_dev_show and backing_dev_store + - xtensa: drop EXPORT_SYMBOL for outs*/ins* + - xtensa: fix change_bit in exclusive access option + - s390/zcrypt: fix memleak at release + - s390/kaslr: add support for R_390_GLOB_DAT relocation type + - lib/vdso: Make clock_getres() POSIX compliant again + - parisc: Fix vmap memory leak in ioremap()/iounmap() + - EDAC/ghes: Fix Use after free in ghes_edac remove path + - arm64: KVM: Trap VM ops when ARM64_WORKAROUND_CAVIUM_TX2_219_TVM is set + - arm64: Avoid Cavium TX2 erratum 219 when switching TTBR + - arm64: Enable workaround for Cavium TX2 erratum 219 when running SMT + - arm64: Allow CAVIUM_TX2_ERRATUM_219 to be selected + - CIFS: avoid using MID 0xFFFF + - cifs: Fix missed free operations + - CIFS: Fix use after free of file info structures + - perf/aux: Fix AUX output stopping + - tracing: Fix race in perf_trace_buf initialization + - fs/dax: Fix pmd vs pte conflict detection + - dm cache: fix bugs when a GFP_NOWAIT allocation fails + - irqchip/sifive-plic: Switch to fasteoi flow + - x86/boot/64: Make level2_kernel_pgt pages invalid outside kernel area + - x86/apic/x2apic: Fix a NULL pointer deref when handling a dying cpu + - x86/hyperv: Make vapic support x2apic mode + - pinctrl: cherryview: restore Strago DMI workaround for all versions + - pinctrl: armada-37xx: fix control of pins 32 and up + - pinctrl: armada-37xx: swap polarity on LED group + - btrfs: block-group: Fix a memory leak due to missing btrfs_put_block_group() + - Btrfs: add missing extents release on file extent cluster relocation error + - btrfs: don't needlessly create extent-refs kernel thread + - Btrfs: fix qgroup double free after failure to reserve metadata for delalloc + - Btrfs: check for the full sync flag while holding the inode lock during + fsync + - btrfs: tracepoints: Fix wrong parameter order for qgroup events + - btrfs: tracepoints: Fix bad entry members of qgroup events + - KVM: PPC: Book3S HV: XIVE: Ensure VP isn't already in use + - memstick: jmb38x_ms: Fix an error handling path in 'jmb38x_ms_probe()' + - cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown + - ceph: just skip unrecognized info in ceph_reply_info_extra + - xen/netback: fix error path of xenvif_connect_data() + - PCI: PM: Fix pci_power_up() + - opp: of: drop incorrect lockdep_assert_held() + - of: reserved_mem: add missing of_node_put() for proper ref-counting + - blk-rq-qos: fix first node deletion of rq_qos_del() + - RDMA/cxgb4: Do not dma memory off of the stack + - Linux 5.3.8 + - [Config] CONFIG_CAVIUM_TX2_ERRATUM_219=y + * Eoan update: 5.3.10 upstream stable release (LP: #1852111) + - regulator: of: fix suspend-min/max-voltage parsing + - ASoC: samsung: arndale: Add missing OF node dereferencing + - ASoC: wm8994: Do not register inapplicable controls for WM1811 + - regulator: da9062: fix suspend_enable/disable preparation + - ASoC: topology: Fix a signedness bug in soc_tplg_dapm_widget_create() + - arm64: dts: allwinner: a64: pine64-plus: Add PHY regulator delay + - arm64: dts: allwinner: a64: Drop PMU node + - arm64: dts: allwinner: a64: sopine-baseboard: Add PHY regulator delay + - arm64: dts: Fix gpio to pinmux mapping + - regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone + - pinctrl: intel: Allocate IRQ chip dynamic + - ASoC: SOF: loader: fix kernel oops on firmware boot failure + - ASoC: SOF: topology: fix parse fail issue for byte/bool tuple types + - ASoC: SOF: Intel: hda: fix warnings during FW load + - ASoC: SOF: Intel: initialise and verify FW crash dump data. + - ASoC: SOF: Intel: hda: Disable DMI L1 entry during capture + - ASoC: rt5682: add NULL handler to set_jack function + - ASoC: intel: sof_rt5682: add remove function to disable jack + - ASoC: intel: bytcr_rt5651: add null check to support_button_press + - regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() + could be uninitialized + - ASoC: wm_adsp: Don't generate kcontrols without READ flags + - ASoc: rockchip: i2s: Fix RPM imbalance + - arm64: dts: rockchip: fix Rockpro64 RK808 interrupt line + - ARM: dts: logicpd-torpedo-som: Remove twl_keypad + - arm64: dts: rockchip: fix RockPro64 vdd-log regulator settings + - arm64: dts: rockchip: fix RockPro64 sdhci settings + - pinctrl: ns2: Fix off by one bugs in ns2_pinmux_enable() + - pinctrl: stmfx: fix null pointer on remove + - arm64: dts: zii-ultra: fix ARM regulator states + - ARM: dts: am3874-iceboard: Fix 'i2c-mux-idle-disconnect' usage + - ASoC: msm8916-wcd-digital: add missing MIX2 path for RX1/2 + - ASoC: simple_card_utils.h: Fix potential multiple redefinition error + - ARM: dts: Use level interrupt for omap4 & 5 wlcore + - ARM: mm: fix alignment handler faults under memory pressure + - scsi: qla2xxx: fix a potential NULL pointer dereference + - scsi: scsi_dh_alua: handle RTPG sense code correctly during state + transitions + - scsi: sni_53c710: fix compilation error + - scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE + - ARM: 8908/1: add __always_inline to functions called from __get_user_check() + - ARM: 8914/1: NOMMU: Fix exc_ret for XIP + - arm64: dts: rockchip: fix RockPro64 sdmmc settings + - arm64: dts: rockchip: Fix usb-c on Hugsun X99 TV Box + - arm64: dts: lx2160a: Correct CPU core idle state name + - ARM: dts: imx6q-logicpd: Re-Enable SNVS power key + - ARM: dts: vf610-zii-scu4-aib: Specify 'i2c-mux-idle-disconnect' + - ARM: dts: imx7s: Correct GPT's ipg clock source + - arm64: dts: imx8mq: Use correct clock for usdhc's ipg clk + - arm64: dts: imx8mm: Use correct clock for usdhc's ipg clk + - perf tools: Fix resource leak of closedir() on the error paths + - perf c2c: Fix memory leak in build_cl_output() + - 8250-men-mcb: fix error checking when get_num_ports returns -ENODEV + - perf kmem: Fix memory leak in compact_gfp_flags() + - ARM: davinci: dm365: Fix McBSP dma_slave_map entry + - drm/amdgpu: fix potential VM faults + - drm/amdgpu: fix error handling in amdgpu_bo_list_create + - scsi: target: core: Do not overwrite CDB byte 1 + - scsi: hpsa: add missing hunks in reset-patch + - ASoC: Intel: sof-rt5682: add a check for devm_clk_get + - ASoC: SOF: control: return true when kcontrol values change + - tracing: Fix "gfp_t" format for synthetic events + - ARM: dts: bcm2837-rpi-cm3: Avoid leds-gpio probing issue + - i2c: aspeed: fix master pending state handling + - drm/komeda: Don't flush inactive pipes + - ARM: 8926/1: v7m: remove register save to stack before svc + - selftests: kvm: vmx_set_nested_state_test: don't check for VMX support twice + - selftests: kvm: fix sync_regs_test with newer gccs + - ALSA: hda: Add Tigerlake/Jasperlake PCI ID + - of: unittest: fix memory leak in unittest_data_add + - MIPS: bmips: mark exception vectors as char arrays + - irqchip/gic-v3-its: Use the exact ITSList for VMOVP + - i2c: mt65xx: fix NULL ptr dereference + - i2c: stm32f7: fix first byte to send in slave mode + - i2c: stm32f7: fix a race in slave mode with arbitration loss irq + - i2c: stm32f7: remove warning when compiling with W=1 + - cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs + - irqchip/sifive-plic: Skip contexts except supervisor in plic_init() + - nbd: protect cmd->status with cmd->lock + - nbd: handle racing with error'ed out commands + - cxgb4: fix panic when attaching to ULD fail + - cxgb4: request the TX CIDX updates to status page + - dccp: do not leak jiffies on the wire + - erspan: fix the tun_info options_len check for erspan + - inet: stop leaking jiffies on the wire + - net: annotate accesses to sk->sk_incoming_cpu + - net: annotate lockless accesses to sk->sk_napi_id + - net: dsa: bcm_sf2: Fix IMP setup for port different than 8 + - net: ethernet: ftgmac100: Fix DMA coherency issue with SW checksum + - net: fix sk_page_frag() recursion from memory reclaim + - net: hisilicon: Fix ping latency when deal with high throughput + - net/mlx4_core: Dynamically set guaranteed amount of counters per VF + - netns: fix GFP flags in rtnl_net_notifyid() + - net: rtnetlink: fix a typo fbd -> fdb + - net: usb: lan78xx: Disable interrupts before calling generic_handle_irq() + - SAUCE: Revert "UBUNTU: SAUCE: (no-up) net: Zeroing the structure + ethtool_wolinfo in ethtool_get_wol()" + - net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() + - selftests: net: reuseport_dualstack: fix uninitalized parameter + - udp: fix data-race in udp_set_dev_scratch() + - vxlan: check tun_info options_len properly + - net: add skb_queue_empty_lockless() + - udp: use skb_queue_empty_lockless() + - net: use skb_queue_empty_lockless() in poll() handlers + - net: use skb_queue_empty_lockless() in busy poll contexts + - net: add READ_ONCE() annotation in __skb_wait_for_more_packets() + - ipv4: fix route update on metric change. + - selftests: fib_tests: add more tests for metric update + - net/smc: fix closing of fallback SMC sockets + - net/smc: keep vlan_id for SMC-R in smc_listen_work() + - keys: Fix memory leak in copy_net_ns + - net: phylink: Fix phylink_dbg() macro + - rxrpc: Fix handling of last subpacket of jumbo packet + - net/mlx5e: Determine source port properly for vlan push action + - net/mlx5e: Remove incorrect match criteria assignment line + - net/mlx5e: Initialize on stack link modes bitmap + - net/mlx5: Fix flow counter list auto bits struct + - net/smc: fix refcounting for non-blocking connect() + - net/mlx5: Fix rtable reference leak + - mlxsw: core: Unpublish devlink parameters during reload + - r8169: fix wrong PHY ID issue with RTL8168dp + - net/mlx5e: Fix ethtool self test: link speed + - net/mlx5e: Fix handling of compressed CQEs in case of low NAPI budget + - ipv4: fix IPSKB_FRAG_PMTU handling with fragmentation + - net: bcmgenet: don't set phydev->link from MAC + - net: dsa: b53: Do not clear existing mirrored port mask + - net: dsa: fix switch tree list + - net: ensure correct skb->tstamp in various fragmenters + - net: hns3: fix mis-counting IRQ vector numbers issue + - net: netem: fix error path for corrupted GSO frames + - net: reorder 'struct net' fields to avoid false sharing + - net: usb: lan78xx: Connect PHY before registering MAC + - r8152: add device id for Lenovo ThinkPad USB-C Dock Gen 2 + - net: netem: correct the parent's backlog when corrupted packet was dropped + - net: phy: bcm7xxx: define soft_reset for 40nm EPHY + - net: bcmgenet: reset 40nm EPHY on energy detect + - net/flow_dissector: switch to siphash + - platform/x86: pmc_atom: Add Siemens SIMATIC IPC227E to critclk_systems DMI + table + - CIFS: Fix retry mid list corruption on reconnects + - selftests/powerpc: Add test case for tlbie vs mtpidr ordering issue + - selftests/powerpc: Fix compile error on tlbie_test due to newer gcc + - ASoC: pcm3168a: The codec does not support S32_LE + - arm64: dts: ti: k3-am65-main: Fix gic-its node unit-address + - usb: gadget: udc: core: Fix segfault if udc_bind_to_driver() for pending + driver fails + - Linux 5.3.10 + - [Config] SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1=n + * Some EFI systems fail to boot in efi_init() when booted via maas + (LP: #1851810) + - efi: efi_get_memory_map -- increase map headroom + * dkms artifacts may expire from the pool (LP: #1850958) + - [Packaging] dkms -- try launchpad librarian for pool downloads + - [Packaging] dkms -- dkms-build quieten wget verbiage + * update ENA driver to version 2.1.0 (LP: #1850175) + - net: ena: don't wake up tx queue when down + - net: ena: clean up indentation issue + * drm/i915: Add support for another CMP-H PCH (LP: #1848491) + - drm/i915/cml: Add second PCH ID for CMP + * Add Intel Comet Lake ethernet support (LP: #1848555) + - SAUCE: e1000e: Add support for Comet Lake + * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281) + - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: avoid overflow in implicit constant conversion + - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test + * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms + - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms + * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled + cloud (LP: #1848481) + - [Packaging] include iavf/i40evf in generic + * High power consumption using 5.0.0-25-generic (LP: #1840835) + - PCI: Add a helper to check Power Resource Requirements _PR3 existence + - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a + driver + - PCI: Fix missing inline for pci_pr3_present() + * CML CPUIDs (LP: #1843794) + - x86/cpu: Add Comet Lake to the Intel CPU models header + * shiftfs: prevent exceeding project quotas (LP: #1849483) + - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities + * shiftfs: fix fallocate() (LP: #1849482) + - SAUCE: shiftfs: setup correct s_maxbytes limit + * Bluetooth: hidp: Fix assumptions on the return value of hidp_send_message + (LP: #1850443) + - Bluetooth: hidp: Fix assumptions on the return value of hidp_send_message + * [SRU][B/OEM-B/OEM-OSP1/D/E] UBUNTU: SAUCE: add rtl623 codec support and fix + mic issues (LP: #1850599) + - SAUCE: ALSA: hda/realtek - Add support for ALC623 + - SAUCE: ALSA: hda/realtek - Fix 2 front mics of codec 0x623 + * Suppress "hid_field_extract() called with n (192) > 32!" message floods + (LP: #1850600) + - HID: core: reformat and reduce hid_printk macros + - HID: core: Add printk_once variants to hid_warn() etc + - HID: core: fix dmesg flooding if report field larger than 32bit + * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs + error path (LP: #1850994) // CVE-2019-15794 + - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails + - SAUCE: ovl: Restore vm_file value when lower fs mmap fails + * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677) + - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags + * root can lift kernel lockdown (LP: #1851380) + - SAUCE: (efi-lockdown) Really don't allow lifting lockdown from userspace + * Colour banding in Lenovo G50-80 laptop display (i915) (LP: #1819968) // Eoan + update: v5.3.8 upstream stable release (LP: #1850456) + - drm/edid: Add 6 bpc quirk for SDC panel in Lenovo G50 + + [ Ubuntu: 5.3.0-23.25 ] + + * Incomplete i915 fix for 64-bit x86 kernels (LP: #1852141) // CVE-2019-0155 + - SAUCE: drm/i915/cmdparser: Fix jump whitelist clearing + + -- Khalid Elmously Sun, 17 Nov 2019 21:10:05 -0500 + +linux-oracle (5.3.0-1006.7) eoan; urgency=medium + + * CVE-2019-11135 + - [Config] Disable TSX by default when possible + + [ Ubuntu: 5.3.0-22.24 ] + + * [REGRESSION] md/raid0: cannot assemble multi-zone RAID0 with default_layout + setting (LP: #1849682) + - Revert "md/raid0: avoid RAID0 data corruption due to layout confusion." + * refcount underflow and type confusion in shiftfs (LP: #1850867) // CVE-2019-15793 + - SAUCE: shiftfs: Correct id translation for lower fs operations + - SAUCE: shiftfs: prevent type confusion + - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling + * CVE-2018-12207 + - kvm: x86, powerpc: do not allow clearing largepages debugfs entry + - SAUCE: KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is + active + - SAUCE: x86: Add ITLB_MULTIHIT bug infrastructure + - SAUCE: kvm: mmu: ITLB_MULTIHIT mitigation + - SAUCE: kvm: Add helper function for creating VM worker threads + - SAUCE: kvm: x86: mmu: Recovery of shattered NX large pages + - SAUCE: cpu/speculation: Uninline and export CPU mitigations helpers + - SAUCE: kvm: x86: mmu: Apply global mitigations knob to ITLB_MULTIHIT + * CVE-2019-11135 + - x86/msr: Add the IA32_TSX_CTRL MSR + - x86/cpu: Add a helper function x86_read_arch_cap_msr() + - x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default + - x86/speculation/taa: Add mitigation for TSX Async Abort + - x86/speculation/taa: Add sysfs reporting for TSX Async Abort + - kvm/x86: Export MDS_NO=0 to guests when TSX is enabled + - x86/tsx: Add "auto" option to the tsx= cmdline parameter + - x86/speculation/taa: Add documentation for TSX Async Abort + - x86/tsx: Add config options to set tsx=on|off|auto + - [Config] Disable TSX by default when possible + * CVE-2019-0154 + - SAUCE: drm/i915: Lower RM timeout to avoid DSI hard hangs + - SAUCE: drm/i915/gen8+: Add RC6 CTX corruption WA + * CVE-2019-0155 + - SAUCE: drm/i915: Rename gen7 cmdparser tables + - SAUCE: drm/i915: Disable Secure Batches for gen6+ + - SAUCE: drm/i915: Remove Master tables from cmdparser + - SAUCE: drm/i915: Add support for mandatory cmdparsing + - SAUCE: drm/i915: Support ro ppgtt mapped cmdparser shadow buffers + - SAUCE: drm/i915: Allow parsing of unsized batches + - SAUCE: drm/i915: Add gen9 BCS cmdparsing + - SAUCE: drm/i915/cmdparser: Use explicit goto for error paths + - SAUCE: drm/i915/cmdparser: Add support for backward jumps + - SAUCE: drm/i915/cmdparser: Ignore Length operands during command matching + + -- Andrea Righi Mon, 11 Nov 2019 14:54:13 +0100 + +linux-oracle (5.3.0-1005.5) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1005.5 -proposed tracker (LP: #1850483) + + [ Ubuntu: 5.3.0-21.22 ] + + * eoan/linux: 5.3.0-21.22 -proposed tracker (LP: #1850486) + * Fix signing of staging modules in eoan (LP: #1850234) + - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink + + -- Khalid Elmously Tue, 29 Oct 2019 20:59:22 -0400 + +linux-oracle (5.3.0-1004.4) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1004.4 -proposed tracker (LP: #1849062) + + * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490) + - [Config] oracle: Enable SOF_HDA link and codec + + * Eoan update: v5.3.5 upstream stable release (LP: #1848047) + - [Config] oracle: disable rtc-bd70528 module + + * Eoan update: 5.3.7 upstream stable release (LP: #1848750) + - [Config] oracle: disable staging/fbtft driver + - [Config] oracle: disable Rio 500 driver + + [ Ubuntu: 5.3.0-20.21 ] + + * eoan/linux: 5.3.0-20.21 -proposed tracker (LP: #1849064) + * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490) + - [Config] Enable SOF_HDA link and codec + * Eoan update: 5.3.7 upstream stable release (LP: #1848750) + - panic: ensure preemption is disabled during panic() + - [Config] updateconfigs for USB_RIO500 + - USB: rio500: Remove Rio 500 kernel driver + - USB: yurex: Don't retry on unexpected errors + - USB: yurex: fix NULL-derefs on disconnect + - USB: usb-skeleton: fix runtime PM after driver unbind + - USB: usb-skeleton: fix NULL-deref on disconnect + - xhci: Fix false warning message about wrong bounce buffer write length + - xhci: Prevent device initiated U1/U2 link pm if exit latency is too long + - xhci: Check all endpoints for LPM timeout + - xhci: Fix USB 3.1 capability detection on early xHCI 1.1 spec based hosts + - usb: xhci: wait for CNR controller not ready bit in xhci resume + - xhci: Prevent deadlock when xhci adapter breaks during init + - xhci: Fix NULL pointer dereference in xhci_clear_tt_buffer_complete() + - USB: adutux: fix use-after-free on disconnect + - USB: adutux: fix NULL-derefs on disconnect + - USB: adutux: fix use-after-free on release + - USB: iowarrior: fix use-after-free on disconnect + - USB: iowarrior: fix use-after-free on release + - USB: iowarrior: fix use-after-free after driver unbind + - USB: usblp: fix runtime PM after driver unbind + - USB: chaoskey: fix use-after-free on release + - USB: ldusb: fix NULL-derefs on driver unbind + - serial: uartlite: fix exit path null pointer + - serial: uartps: Fix uartps_major handling + - USB: serial: keyspan: fix NULL-derefs on open() and write() + - USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20 + - USB: serial: option: add Telit FN980 compositions + - USB: serial: option: add support for Cinterion CLS8 devices + - USB: serial: fix runtime PM after driver unbind + - USB: usblcd: fix I/O after disconnect + - USB: microtek: fix info-leak at probe + - USB: dummy-hcd: fix power budget for SuperSpeed mode + - usb: renesas_usbhs: gadget: Do not discard queues in + usb_ep_set_{halt,wedge}() + - usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior + - usb: typec: tcpm: usb: typec: tcpm: Fix a signedness bug in + tcpm_fw_get_caps() + - usb: typec: ucsi: ccg: Remove run_isr flag + - usb: typec: ucsi: displayport: Fix for the mode entering routine + - USB: legousbtower: fix slab info leak at probe + - USB: legousbtower: fix deadlock on disconnect + - USB: legousbtower: fix potential NULL-deref on disconnect + - USB: legousbtower: fix open after failed reset request + - USB: legousbtower: fix use-after-free on release + - mei: me: add comet point (lake) LP device ids + - mei: avoid FW version request on Ibex Peak and earlier + - gpio: eic: sprd: Fix the incorrect EIC offset when toggling + - staging/fbtft: Depend on OF + - staging: bcm2835-audio: Fix draining behavior regression + - Staging: fbtft: fix memory leak in fbtft_framebuffer_alloc + - staging: rtl8188eu: fix HighestRate check in odm_ARFBRefresh_8188E() + - staging: vt6655: Fix memory leak in vt6655_probe + - iio: adc: hx711: fix bug in sampling of data + - iio: adc: ad799x: fix probe error handling + - iio: adc: axp288: Override TS pin bias current for some models + - iio: adc: stm32-adc: move registers definitions + - iio: adc: stm32-adc: fix a race when using several adcs with dma and irq + - iio: light: opt3001: fix mutex unlock race + - iio: light: add missing vcnl4040 of_compatible + - iio: accel: adxl372: Fix/remove limitation for FIFO samples + - iio: accel: adxl372: Fix push to buffers lost samples + - iio: accel: adxl372: Perform a reset at start up + - efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified + - perf llvm: Don't access out-of-scope array + - perf inject jit: Fix JIT_CODE_MOVE filename + - drm/i915: Perform GGTT restore much earlier during resume + - selinux: fix context string corruption in convert_context() + - CIFS: Gracefully handle QueryInfo errors during open + - CIFS: Force revalidate inode when dentry is stale + - CIFS: Force reval dentry if LOOKUP_REVAL flag is set + - cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic + - kernel/sysctl.c: do not override max_threads provided by userspace + - mm/z3fold.c: claim page in the beginning of free + - mm/page_alloc.c: fix a crash in free_pages_prepare() + - mm/vmpressure.c: fix a signedness bug in vmpressure_register_event() + - IB/core: Fix wrong iterating on ports + - firmware: google: increment VPD key_len properly + - gpio: fix getting nonexclusive gpiods from DT + - gpiolib: don't clear FLAG_IS_OUT when emulating open-drain/open-source + - btrfs: relocation: fix use-after-free on dead relocation roots + - btrfs: allocate new inode in NOFS context + - btrfs: fix balance convert to single on 32-bit host CPUs + - Btrfs: fix memory leak due to concurrent append writes with fiemap + - btrfs: fix incorrect updating of log root tree + - btrfs: fix uninitialized ret in ref-verify + - NFS: Fix O_DIRECT accounting of number of bytes read/written + - MIPS: Disable Loongson MMI instructions for kernel build + - MIPS: elf_hwcap: Export userspace ASEs + - RDMA/vmw_pvrdma: Free SRQ only once + - ACPI/PPTT: Add support for ACPI 6.3 thread flag + - arm64: topology: Use PPTT to determine if PE is a thread + - iio: light: fix vcnl4000 devicetree hooks + - Fix the locking in dcache_readdir() and friends + - drm/i915: Bump skl+ max plane width to 5k for linear/x-tiled + - drm/i915: Whitelist COMMON_SLICE_CHICKEN2 + - drm/i915: Mark contents as dirty on a write fault + - drm/msm: Use the correct dma_sync calls harder + - media: stkwebcam: fix runtime PM after driver unbind + - arm64/sve: Fix wrong free for task->thread.sve_state + - tracing/hwlat: Report total time spent in all NMIs during the sample + - tracing/hwlat: Don't ignore outer-loop duration when calculating max_latency + - ftrace: Get a reference counter for the trace_array on filter files + - tracing: Get trace_array reference for available_tracers files + - hwmon: Fix HWMON_P_MIN_ALARM mask + - mtd: rawnand: au1550nd: Fix au_read_buf16() prototype + - x86/asm: Fix MWAITX C-state hint value + - io_uring: only flush workqueues on fileset removal + - efi/tpm: Fix sanity check of unsigned tbl_size being less than zero + - Linux 5.3.7 + - [Packaging] Remove now un-used modules for amd64 + - [Config] Remove Rio500 + - [Config] Remove deselected modules + * Eoan update: v5.3.5 upstream stable release (LP: #1848047) + - drm/vkms: Fix crc worker races + - drm/mcde: Fix uninitialized variable + - drm/bridge: tc358767: Increase AUX transfer length limit + - drm/vkms: Avoid assigning 0 for possible_crtc + - drm/panel: simple: fix AUO g185han01 horizontal blanking + - drm/amd/display: add monitor patch to add T7 delay + - drm/amd/display: Power-gate all DSCs at driver init time + - drm/amd/display: fix not calling ppsmu to trigger PME + - drm/amd/display: Clear FEC_READY shadow register if DPCD write fails + - drm/amd/display: Copy GSL groups when committing a new context + - video: ssd1307fb: Start page range at page_offset + - drm/tinydrm/Kconfig: drivers: Select BACKLIGHT_CLASS_DEVICE + - drm/stm: attach gem fence to atomic state + - drm/bridge: sii902x: fix missing reference to mclk clock + - drm/panel: check failure cases in the probe func + - drm/rockchip: Check for fast link training before enabling psr + - drm/amdgpu: Fix hard hang for S/G display BOs. + - drm/amd/display: Use proper enum conversion functions + - drm/radeon: Fix EEH during kexec + - gpu: drm: radeon: Fix a possible null-pointer dereference in + radeon_connector_set_property() + - clk: imx8mq: Mark AHB clock as critical + - PCI: rpaphp: Avoid a sometimes-uninitialized warning + - pinctrl: stmfx: update pinconf settings + - ipmi_si: Only schedule continuously in the thread in maintenance mode + - clk: qoriq: Fix -Wunused-const-variable + - clk: ingenic/jz4740: Fix "pll half" divider not read/written properly + - clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks + - drm/amd/display: fix issue where 252-255 values are clipped + - drm/amd/display: Fix frames_to_insert math + - drm/amd/display: reprogram VM config when system resume + - drm/amd/display: Register VUPDATE_NO_LOCK interrupts for DCN2 + - powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA + window + - clk: actions: Don't reference clk_init_data after registration + - clk: sirf: Don't reference clk_init_data after registration + - clk: meson: axg-audio: Don't reference clk_init_data after registration + - clk: sprd: Don't reference clk_init_data after registration + - clk: zx296718: Don't reference clk_init_data after registration + - clk: sunxi: Don't call clk_hw_get_name() on a hw that isn't registered + - powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL + - powerpc/rtas: use device model APIs and serialization during LPM + - powerpc/ptdump: fix walk_pagetables() address mismatch + - powerpc/futex: Fix warning: 'oldval' may be used uninitialized in this + function + - powerpc/64s/radix: Fix memory hotplug section page table creation + - powerpc/pseries/mobility: use cond_resched when updating device tree + - powerpc/perf: fix imc allocation failure handling + - pinctrl: tegra: Fix write barrier placement in pmx_writel + - powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag + - vfio_pci: Restore original state on release + - drm/amdgpu/sdma5: fix number of sdma5 trap irq types for navi1x + - drm/nouveau/kms/tu102-: disable input lut when input is already FP16 + - drm/nouveau/volt: Fix for some cards having 0 maximum voltage + - pinctrl: amd: disable spurious-firing GPIO IRQs + - clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain + - clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain + - drm/amd/display: support spdif + - drm/amd/powerpaly: fix navi series custom peak level value error + - drm/amd/display: fix MPO HUBP underflow with Scatter Gather + - drm/amd/display: fix trigger not generated for freesync + - selftests/powerpc: Retry on host facility unavailable + - kbuild: Do not enable -Wimplicit-fallthrough for clang for now + - drm/amdgpu/si: fix ASIC tests + - powerpc/64s/exception: machine check use correct cfar for late handler + - pstore: fs superblock limits + - powerpc/eeh: Clean up EEH PEs after recovery finishes + - clk: qcom: gcc-sdm845: Use floor ops for sdcc clks + - powerpc/pseries: correctly track irq state in default idle + - pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c + - mailbox: mediatek: cmdq: clear the event in cmdq initial flow + - ARM: dts: dir685: Drop spi-cpol from the display + - arm64: fix unreachable code issue with cmpxchg + - clk: at91: select parent if main oscillator or bypass is enabled + - clk: imx: pll14xx: avoid glitch when set rate + - clk: imx: clk-pll14xx: unbypass PLL by default + - clk: Make clk_bulk_get_all() return a valid "id" + - powerpc: dump kernel log before carrying out fadump or kdump + - mbox: qcom: add APCS child device for QCS404 + - clk: sprd: add missing kfree + - scsi: core: Reduce memory required for SCSI logging + - dma-buf/sw_sync: Synchronize signal vs syncpt free + - f2fs: fix to drop meta/node pages during umount + - ext4: fix potential use after free after remounting with noblock_validity + - MIPS: Ingenic: Disable broken BTB lookup optimization. + - MIPS: Don't use bc_false uninitialized in __mm_isBranchInstr + - MIPS: tlbex: Explicitly cast _PAGE_NO_EXEC to a boolean + - i2c-cht-wc: Fix lockdep warning + - PCI: tegra: Fix OF node reference leak + - HID: wacom: Fix several minor compiler warnings + - rtc: bd70528: fix driver dependencies + - mips/atomic: Fix loongson_llsc_mb() wreckage + - PCI: pci-hyperv: Fix build errors on non-SYSFS config + - PCI: layerscape: Add the bar_fixed_64bit property to the endpoint driver + - livepatch: Nullify obj->mod in klp_module_coming()'s error path + - mips/atomic: Fix smp_mb__{before,after}_atomic() + - ARM: 8898/1: mm: Don't treat faults reported from cache maintenance as + writes + - soundwire: intel: fix channel number reported by hardware + - PCI: mobiveil: Fix the CPU base address setup in inbound window + - ARM: 8875/1: Kconfig: default to AEABI w/ Clang + - rtc: snvs: fix possible race condition + - rtc: pcf85363/pcf85263: fix regmap error in set_time + - power: supply: register HWMON devices with valid names + - selinux: fix residual uses of current_security() for the SELinux blob + - PCI: Add pci_info_ratelimited() to ratelimit PCI separately + - HID: apple: Fix stuck function keys when using FN + - PCI: rockchip: Propagate errors for optional regulators + - PCI: histb: Propagate errors for optional regulators + - PCI: imx6: Propagate errors for optional regulators + - PCI: exynos: Propagate errors for optional PHYs + - security: smack: Fix possible null-pointer dereferences in + smack_socket_sock_rcv_skb() + - PCI: Use static const struct, not const static struct + - ARM: 8905/1: Emit __gnu_mcount_nc when using Clang 10.0.0 or newer + - ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned + address + - i2c: tegra: Move suspend handling to NOIRQ phase + - block, bfq: push up injection only after setting service time + - fat: work around race with userspace's read via blockdev while mounting + - pktcdvd: remove warning on attempting to register non-passthrough dev + - hypfs: Fix error number left in struct pointer member + - tools/power/x86/intel-speed-select: Fix high priority core mask over count + - crypto: hisilicon - Fix double free in sec_free_hw_sgl() + - mm: add dummy can_do_mlock() helper + - kbuild: clean compressed initramfs image + - ocfs2: wait for recovering done after direct unlock request + - kmemleak: increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE default to 16K + - arm64: consider stack randomization for mmap base only when necessary + - mips: properly account for stack randomization and stack guard gap + - arm: properly account for stack randomization and stack guard gap + - arm: use STACK_TOP when computing mmap base address + - cxgb4:Fix out-of-bounds MSI-X info array access + - erspan: remove the incorrect mtu limit for erspan + - hso: fix NULL-deref on tty open + - ipv6: drop incoming packets having a v4mapped source address + - ipv6: Handle missing host route in __ipv6_ifa_notify + - net: ipv4: avoid mixed n_redirects and rate_tokens usage + - net: qlogic: Fix memory leak in ql_alloc_large_buffers + - net: sched: taprio: Fix potential integer overflow in + taprio_set_picos_per_byte + - net: Unpublish sk from sk_reuseport_cb before call_rcu + - nfc: fix memory leak in llcp_sock_bind() + - qmi_wwan: add support for Cinterion CLS8 devices + - rxrpc: Fix rxrpc_recvmsg tracepoint + - sch_cbq: validate TCA_CBQ_WRROPT to avoid crash + - sch_dsmark: fix potential NULL deref in dsmark_init() + - tipc: fix unlimited bundling of small messages + - udp: fix gso_segs calculations + - vsock: Fix a lockdep warning in __vsock_release() + - net: dsa: rtl8366: Check VLAN ID and not ports + - tcp: adjust rto_base in retransmits_timed_out() + - udp: only do GSO if # of segs > 1 + - net/rds: Fix error handling in rds_ib_add_one() + - net: dsa: sja1105: Initialize the meta_lock + - xen-netfront: do not use ~0U as error return value for xennet_fill_frags() + - net: dsa: sja1105: Fix sleeping while atomic in .port_hwtstamp_set + - ptp_qoriq: Initialize the registers' spinlock before calling + ptp_qoriq_settime + - net: dsa: sja1105: Ensure PTP time for rxtstamp reconstruction is not in the + past + - net: dsa: sja1105: Prevent leaking memory + - net: socionext: netsec: always grab descriptor lock + - net: sched: cbs: Avoid division by zero when calculating the port rate + - net: sched: taprio: Avoid division by zero on invalid link speed + - Smack: Don't ignore other bprm->unsafe flags if LSM_UNSAFE_PTRACE is set + - smack: use GFP_NOFS while holding inode_smack::smk_lock + - dm raid: fix updating of max_discard_sectors limit + - dm zoned: fix invalid memory access + - NFC: fix attrs checks in netlink interface + - kexec: bail out upon SIGKILL when allocating memory. + - KVM: hyperv: Fix Direct Synthetic timers assert an interrupt w/o + lapic_in_kernel + - 9p/cache.c: Fix memory leak in v9fs_cache_session_get_cookie + - vfs: set fs_context::user_ns for reconfigure + - Linux 5.3.5 + - [Config] add rtc-bd70528 to modules.ignore + - [Packaging] remove rtc-bd70528 from modules + * Suspend stopped working from 4.4.0-157 onwards (LP: #1844021) // Eoan + update: 5.3.7 upstream stable release (LP: #1848750) + - xhci: Increase STS_SAVE timeout in xhci_suspend() + * CVE-2019-17666 + - SAUCE: rtlwifi: Fix potential overflow on P2P code + * md raid0/linear doesn't show error state if an array member is removed and + allows successful writes (LP: #1847773) + - md raid0/linear: Mark array as 'broken' and fail BIOs if a member is gone + * linux won't build when new virtualbox version is present on the archive + (LP: #1848788) + - [Packaging]: download virtualbox from sources + * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE (LP: #1847744) + - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE + * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes + to no (LP: #1848492) + - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x + from yes to no + * shiftfs: rework how shiftfs opens files (LP: #1846265) + - SAUCE: shiftfs: rework how shiftfs opens files + * fdatasync performance regression on 5.0 kernels (LP: #1847641) + - blk-wbt: fix performance regression in wbt scale_up/scale_down + * bcache: Performance degradation when querying priority_stats (LP: #1840043) + - bcache: add cond_resched() in __bch_cache_cmp() + * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL + platforms (LP: #1847192) + - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display + - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms + * Add installer support for iwlmvm adapters (LP: #1848236) + - d-i: Add iwlmvm to nic-modules + * Eoan update: v5.3.6 upstream stable release (LP: #1848039) + - s390/process: avoid potential reading of freed stack + - KVM: s390: Test for bad access register and size at the start of S390_MEM_OP + - s390/topology: avoid firing events before kobjs are created + - s390/cio: avoid calling strlen on null pointer + - s390/cio: exclude subchannels with no parent from pseudo check + - KVM: s390: fix __insn32_query() inline assembly + - KVM: PPC: Book3S: Enable XIVE native capability only if OPAL has required + functions + - KVM: PPC: Book3S HV: XIVE: Free escalation interrupts before disabling the + VP + - KVM: PPC: Book3S HV: Don't push XIVE context when not using XIVE device + - KVM: PPC: Book3S HV: Fix race in re-enabling XIVE escalation interrupts + - KVM: PPC: Book3S HV: Check for MMU ready on piggybacked virtual cores + - KVM: PPC: Book3S HV: Don't lose pending doorbell request on migration on P9 + - KVM: X86: Fix userspace set invalid CR4 + - nbd: fix max number of supported devs + - PM / devfreq: tegra: Fix kHz to Hz conversion + - ASoC: Define a set of DAPM pre/post-up events + - ASoC: sgtl5000: Improve VAG power and mute control + - powerpc/xive: Implement get_irqchip_state method for XIVE to fix shutdown + race + - powerpc/mce: Fix MCE handling for huge pages + - powerpc/mce: Schedule work from irq_work + - powerpc/603: Fix handling of the DIRTY flag + - powerpc/32s: Fix boot failure with DEBUG_PAGEALLOC without KASAN. + - powerpc/ptdump: Fix addresses display on PPC32 + - powerpc/powernv: Restrict OPAL symbol map to only be readable by root + - powerpc/pseries: Fix cpu_hotplug_lock acquisition in resize_hpt() + - powerpc/powernv/ioda: Fix race in TCE level allocation + - powerpc/kasan: Fix parallel loading of modules. + - powerpc/kasan: Fix shadow area set up for modules. + - powerpc/book3s64/mm: Don't do tlbie fixup for some hardware revisions + - powerpc/book3s64/radix: Rename CPU_FTR_P9_TLBIE_BUG feature flag + - powerpc/mm: Add a helper to select PAGE_KERNEL_RO or PAGE_READONLY + - powerpc/mm: Fix an Oops in kasan_mmu_init() + - powerpc/mm: Fixup tlbie vs mtpidr/mtlpidr ordering issue on POWER9 + - can: mcp251x: mcp251x_hw_reset(): allow more time after a reset + - tools lib traceevent: Fix "robust" test of do_generate_dynamic_list_file + - tools lib traceevent: Do not free tep->cmdlines in add_new_comm() on failure + - crypto: qat - Silence smp_processor_id() warning + - crypto: skcipher - Unmap pages after an external error + - crypto: cavium/zip - Add missing single_release() + - crypto: caam/qi - fix error handling in ERN handler + - crypto: caam - fix concurrency issue in givencrypt descriptor + - crypto: ccree - account for TEE not ready to report + - crypto: ccree - use the full crypt length value + - MIPS: Treat Loongson Extensions as ASEs + - power: supply: sbs-battery: use correct flags field + - power: supply: sbs-battery: only return health when battery present + - tracing: Make sure variable reference alias has correct var_ref_idx + - usercopy: Avoid HIGHMEM pfn warning + - timer: Read jiffies once when forwarding base clk + - PCI: vmd: Fix config addressing when using bus offsets + - PCI: hv: Avoid use of hv_pci_dev->pci_slot after freeing it + - PCI: vmd: Fix shadow offsets to reflect spec changes + - selftests/tpm2: Add the missing TEST_FILES assignment + - selftests: pidfd: Fix undefined reference to pthread_create() + - watchdog: imx2_wdt: fix min() calculation in imx2_wdt_set_timeout + - perf tools: Fix segfault in cpu_cache_level__read() + - perf stat: Fix a segmentation fault when using repeat forever + - drm/i915/dp: Fix dsc bpp calculations, v5. + - drm/atomic: Reject FLIP_ASYNC unconditionally + - drm/atomic: Take the atomic toys away from X + - drm: mali-dp: Mark expected switch fall-through + - drm/omap: fix max fclk divider for omap36xx + - drm/msm/dsi: Fix return value check for clk_get_parent + - drm/nouveau/kms/nv50-: Don't create MSTMs for eDP connectors + - drm/amd/powerplay: change metrics update period from 1ms to 100ms + - drm/i915/gvt: update vgpu workload head pointer correctly + - drm/i915: to make vgpu ppgtt notificaiton as atomic operation + - mac80211: keep BHs disabled while calling drv_tx_wake_queue() + - mmc: tegra: Implement ->set_dma_mask() + - mmc: sdhci: improve ADMA error reporting + - mmc: sdhci-of-esdhc: set DMA snooping based on DMA coherence + - mmc: sdhci: Let drivers define their DMA mask + - Revert "locking/pvqspinlock: Don't wait if vCPU is preempted" + - libnvdimm/altmap: Track namespace boundaries in altmap + - DTS: ARM: gta04: introduce legacy spi-cs-high to make display work again + - xen/balloon: Set pages PageOffline() in balloon_add_region() + - xen/xenbus: fix self-deadlock after killing user process + - ieee802154: atusb: fix use-after-free at disconnect + - nl80211: validate beacon head + - cfg80211: validate SSID/MBSSID element ordering assumption + - cfg80211: initialize on-stack chandefs + - drivers: thermal: qcom: tsens: Fix memory leak from qfprom read + - ima: always return negative code for error + - ima: fix freeing ongoing ahash_request + - fs: nfs: Fix possible null-pointer dereferences in encode_attrs() + - xprtrdma: Toggle XPRT_CONGESTED in xprtrdma's slot methods + - xprtrdma: Send Queue size grows after a reconnect + - 9p: Transport error uninitialized + - 9p: avoid attaching writeback_fid on mmap with type PRIVATE + - xen/pci: reserve MCFG areas earlier + - fuse: fix request limit + - ceph: fix directories inode i_blkbits initialization + - ceph: fetch cap_gen under spinlock in ceph_add_cap + - ceph: reconnect connection if session hang in opening state + - SUNRPC: RPC level errors should always set task->tk_rpc_status + - watchdog: aspeed: Add support for AST2600 + - netfilter: nf_tables: allow lookups in dynamic sets + - drm/amdgpu: Fix KFD-related kernel oops on Hawaii + - drm/amdgpu: Check for valid number of registers to read + - perf probe: Fix to clear tev->nargs in clear_probe_trace_event() + - pNFS: Ensure we do clear the return-on-close layout stateid on fatal errors + - SUNRPC: Don't try to parse incomplete RPC messages + - pwm: stm32-lp: Add check in case requested period cannot be achieved + - selftests/seccomp: fix build on older kernels + - x86/purgatory: Disable the stackleak GCC plugin for the purgatory + - ntb: point to right memory window index + - thermal: Fix use-after-free when unregistering thermal zone device + - thermal_hwmon: Sanitize thermal_zone type + - iommu/amd: Fix downgrading default page-sizes in alloc_pte() + - libnvdimm/region: Initialize bad block for volatile namespaces + - libnvdimm: Fix endian conversion issues + - fuse: fix memleak in cuse_channel_open + - libnvdimm/nfit_test: Fix acpi_handle redefinition + - sched/membarrier: Call sync_core only before usermode for same mm + - sched/membarrier: Fix private expedited registration check + - sched/core: Fix migration to invalid CPU in __set_cpus_allowed_ptr() + - perf build: Add detection of java-11-openjdk-devel package + - include/trace/events/writeback.h: fix -Wstringop-truncation warnings + - selftests/bpf: adjust strobemeta loop to satisfy latest clang + - kernel/elfcore.c: include proper prototypes + - libbpf: fix false uninitialized variable warning + - blk-mq: move lockdep_assert_held() into elevator_exit + - bpf: Fix bpf_event_output re-entry issue + - net: dsa: microchip: Always set regmap stride to 1 + - perf unwind: Fix libunwind build failure on i386 systems + - mlxsw: spectrum_flower: Fail in case user specifies multiple mirror actions + - nfp: abm: fix memory leak in nfp_abm_u32_knode_replace + - drm/radeon: Bail earlier when radeon.cik_/si_support=0 is passed + - Btrfs: fix selftests failure due to uninitialized i_mode in test inodes + - KVM: nVMX: Fix consistency check on injected exception error code + - tick: broadcast-hrtimer: Fix a race in bc_set_next + - perf stat: Reset previous counts on repeat with interval + - riscv: Avoid interrupts being erroneously enabled in handle_exception() + - vfs: Fix EOVERFLOW testing in put_compat_statfs64 + - coresight: etm4x: Use explicit barriers on enable/disable + - staging: erofs: fix an error handling in erofs_readdir() + - staging: erofs: some compressed cluster should be submitted for corrupted + images + - staging: erofs: add two missing erofs_workgroup_put for corrupted images + - staging: erofs: avoid endless loop of invalid lookback distance 0 + - staging: erofs: detect potential multiref due to corrupted images + - libnvdimm: prevent nvdimm from requesting key when security is disabled + - Linux 5.3.6 + * Eoan update: v5.3.4 upstream stable release (LP: #1848046) + - arcnet: provide a buffer big enough to actually receive packets + - cdc_ncm: fix divide-by-zero caused by invalid wMaxPacketSize + - macsec: drop skb sk before calling gro_cells_receive + - net/phy: fix DP83865 10 Mbps HDX loopback disable function + - net: qrtr: Stop rx_worker before freeing node + - net/sched: act_sample: don't push mac header on ip6gre ingress + - net_sched: add max len check for TCA_KIND + - net: stmmac: Fix page pool size + - nfp: flower: fix memory leak in nfp_flower_spawn_vnic_reprs + - nfp: flower: prevent memory leak in nfp_flower_spawn_phy_reprs + - openvswitch: change type of UPCALL_PID attribute to NLA_UNSPEC + - ppp: Fix memory leak in ppp_write + - sch_netem: fix a divide by zero in tabledist() + - selftests: Update fib_tests to handle missing ping6 + - skge: fix checksum byte order + - tcp_bbr: fix quantization code to not raise cwnd if not probing bandwidth + - usbnet: ignore endpoints with invalid wMaxPacketSize + - usbnet: sanity checking of packet sizes and device mtu + - net/rds: Check laddr_check before calling it + - net/mlx5e: Fix matching on tunnel addresses type + - ipv6: fix a typo in fib6_rule_lookup() + - selftests: Update fib_nexthop_multiprefix to handle missing ping6 + - net: phy: micrel: add Asym Pause workaround for KSZ9021 + - net/sched: cbs: Fix not adding cbs instance to list + - ipv4: Revert removal of rt_uses_gateway + - net_sched: add policy validation for action attributes + - vrf: Do not attempt to create IPv6 mcast rule if IPv6 is disabled + - net/mlx5e: Fix traffic duplication in ethtool steering + - net: sched: fix possible crash in tcf_action_destroy() + - tcp: better handle TCP_USER_TIMEOUT in SYN_SENT state + - net/mlx5: Add device ID of upcoming BlueField-2 + - ALSA: hda: Flush interrupts on disabling + - ASoC: SOF: Intel: hda: Make hdac_device device-managed + - cpufreq: ap806: Add NULL check after kcalloc + - ALSA: hda/hdmi - Don't report spurious jack state changes + - regulator: lm363x: Fix off-by-one n_voltages for lm3632 ldo_vpos/ldo_vneg + - regulator: lm363x: Fix n_voltages setting for lm36274 + - spi: dw-mmio: Clock should be shut when error occurs + - ASoC: tlv320aic31xx: suppress error message for EPROBE_DEFER + - ASoC: sgtl5000: Fix of unmute outputs on probe + - ASoC: sgtl5000: Fix charge pump source assignment + - firmware: qcom_scm: Use proper types for dma mappings + - dmaengine: bcm2835: Print error in case setting DMA mask fails + - leds: leds-lp5562 allow firmware files up to the maximum length + - ASoC: SOF: reset DMA state in prepare + - media: dib0700: fix link error for dibx000_i2c_set_speed + - media: mtk-cir: lower de-glitch counter for rc-mm protocol + - ASoC: SOF: pci: mark last_busy value at runtime PM init + - media: exynos4-is: fix leaked of_node references + - media: vivid:add sanity check to avoid divide error and set value to 1 if 0. + - media: vb2: reorder checks in vb2_poll() + - media: vivid: work around high stack usage with clang + - media: hdpvr: Add device num check and handling + - media: i2c: ov5640: Check for devm_gpiod_get_optional() error + - time/tick-broadcast: Fix tick_broadcast_offline() lockdep complaint + - sched/fair: Fix imbalance due to CPU affinity + - sched/core: Fix CPU controller for !RT_GROUP_SCHED + - x86/apic: Make apic_pending_intr_clear() more robust + - sched/deadline: Fix bandwidth accounting at all levels after offline + migration + - x86/reboot: Always use NMI fallback when shutdown via reboot vector IPI + fails + - rcu/tree: Call setschedule() gp ktread to SCHED_FIFO outside of atomic + region + - x86/apic: Soft disable APIC before initializing it + - ALSA: hda - Show the fatal CORB/RIRB error more clearly + - ALSA: i2c: ak4xxx-adda: Fix a possible null pointer dereference in + build_adc_controls() + - rcu: Add destroy_work_on_stack() to match INIT_WORK_ONSTACK() + - EDAC/mc: Fix grain_bits calculation + - arm64: dts: imx8mq: Correct OPP table according to latest datasheet + - media: iguanair: add sanity checks + - cpuidle: teo: Allow tick to be stopped if PM QoS is used + - gpio: madera: Add support for Cirrus Logic CS47L15 + - gpio: madera: Add support for Cirrus Logic CS47L92 + - arm64: mm: free the initrd reserved memblock in a aligned manner + - soc: amlogic: meson-clk-measure: protect measure with a mutex + - base: soc: Export soc_device_register/unregister APIs + - ALSA: usb-audio: Skip bSynchAddress endpoint check if it is invalid + - ia64:unwind: fix double free for mod->arch.init_unw_table + - EDAC/altera: Use the proper type for the IRQ status bits + - ASoC: rsnd: don't call clk_get_rate() under atomic context + - arm64/prefetch: fix a -Wtype-limits warning + - md/raid1: end bio when the device faulty + - md: don't call spare_active in md_reap_sync_thread if all member devices + can't work + - md: don't set In_sync if array is frozen + - media: media/platform: fsl-viu.c: fix build for MICROBLAZE + - media: staging: tegra-vde: Fix build error + - RAS: Build debugfs.o only when enabled in Kconfig + - ASoC: hdac_hda: fix page fault issue by removing race + - ACPI / processor: don't print errors for processorIDs == 0xff + - loop: Add LOOP_SET_DIRECT_IO to compat ioctl + - perf tools: Fix paths in include statements + - EDAC, pnd2: Fix ioremap() size in dnv_rd_reg() + - efi: cper: print AER info of PCIe fatal error + - firmware: arm_scmi: Check if platform has released shmem before using + - sched/fair: Use rq_lock/unlock in online_fair_sched_group + - idle: Prevent late-arriving interrupts from disrupting offline + - blk-mq: Fix memory leak in blk_mq_init_allocated_queue error handling + - media: gspca: zero usb_buf on error + - perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig + - perf test vfs_getname: Disable ~/.perfconfig to get default output + - media: mtk-mdp: fix reference count on old device tree + - media: i2c: tda1997x: prevent potential NULL pointer access + - media: fdp1: Reduce FCP not found message level to debug + - media: em28xx: modules workqueue not inited for 2nd device + - arm64/efi: Move variable assignments after SECTIONS + - perf unwind: Fix libunwind when tid != pid + - media: rc: imon: Allow iMON RC protocol for ffdc 7e device + - dmaengine: iop-adma: use correct printk format strings + - ARM: xscale: fix multi-cpu compilation + - perf record: Support aarch64 random socket_id assignment + - media: vsp1: fix memory leak of dl on error return path + - media: i2c: ov5645: Fix power sequence + - media: omap3isp: Don't set streaming state on random subdevs + - media: imx: mipi csi-2: Don't fail if initial state times-out + - kasan/arm64: fix CONFIG_KASAN_SW_TAGS && KASAN_INLINE + - net: lpc-enet: fix printk format strings + - m68k: Prevent some compiler warnings in Coldfire builds + - ARM: dts: imx7d: cl-som-imx7: make ethernet work again + - arm64: dts: qcom: qcs404-evb: Mark WCSS clocks protected + - ARM: dts: imx7-colibri: disable HS400 + - x86/platform/intel/iosf_mbi Rewrite locking + - media: radio/si470x: kill urb on error + - media: hdpvr: add terminating 0 at end of string + - ASoC: uniphier: Fix double reset assersion when transitioning to suspend + state + - powerpc/Makefile: Always pass --synthetic to nm if supported + - tools headers: Fixup bitsperlong per arch includes + - ASoC: sun4i-i2s: Don't use the oversample to calculate BCLK + - ASoC: mchp-i2s-mcc: Wait for RX/TX RDY only if controller is running + - led: triggers: Fix a memory leak bug + - ASoC: mchp-i2s-mcc: Fix unprepare of GCLK + - nbd: add missing config put + - ACPI / APEI: Release resources if gen_pool_add() fails + - arm64: entry: Move ct_user_exit before any other exception + - s390/kasan: provide uninstrumented __strlen + - media: mceusb: fix (eliminate) TX IR signal length limit + - media: dvb-frontends: use ida for pll number + - posix-cpu-timers: Sanitize bogus WARNONS + - media: dvb-core: fix a memory leak bug + - EDAC/amd64: Support more than two controllers for chip selects handling + - cpufreq: imx-cpufreq-dt: Add i.MX8MN support + - libperf: Fix alignment trap with xyarray contents in 'perf stat' + - EDAC/amd64: Recognize DRAM device type ECC capability + - EDAC/amd64: Decode syndrome before translating address + - ARM: at91: move platform-specific asm-offset.h to arch/arm/mach-at91 + - soc: renesas: rmobile-sysc: Set GENPD_FLAG_ALWAYS_ON for always-on domain + - soc: renesas: Enable ARM_ERRATA_754322 for affected Cortex-A9 + - PM / devfreq: Fix kernel oops on governor module load + - ARM: OMAP2+: move platform-specific asm-offset.h to arch/arm/mach-omap2 + - PM / devfreq: passive: Use non-devm notifiers + - PM / devfreq: exynos-bus: Correct clock enable sequence + - media: cec-notifier: clear cec_adap in cec_notifier_unregister + - media: saa7146: add cleanup in hexium_attach() + - media: cpia2_usb: fix memory leaks + - media: saa7134: fix terminology around saa7134_i2c_eeprom_md7134_gate() + - perf trace beauty ioctl: Fix off-by-one error in cmd->string table + - perf report: Fix --ns time sort key output + - perf script: Fix memory leaks in list_scripts() + - media: aspeed-video: address a protential usage of an unitialized var + - media: ov9650: add a sanity check + - leds: lm3532: Fixes for the driver for stability + - ASoC: es8316: fix headphone mixer volume table + - ACPI / CPPC: do not require the _PSD method + - sched/cpufreq: Align trace event behavior of fast switching + - arm64: dts: meson: fix boards regulators states format + - x86/apic/vector: Warn when vector space exhaustion breaks affinity + - arm64: kpti: ensure patched kernel text is fetched from PoU + - perf evlist: Use unshare(CLONE_FS) in sb threads to let setns(CLONE_NEWNS) + work + - arm64: Use correct ll/sc atomic constraints + - jump_label: Don't warn on __exit jump entries + - x86/mm/pti: Do not invoke PTI functions when PTI is disabled + - ASoC: fsl_ssi: Fix clock control issue in master mode + - x86/mm/pti: Handle unaligned address gracefully in pti_clone_pagetable() + - nvmet: fix data units read and written counters in SMART log + - nvme-multipath: fix ana log nsid lookup when nsid is not found + - ALSA: firewire-motu: add support for MOTU 4pre + - iommu/amd: Silence warnings under memory pressure + - ASoC: Intel: Haswell: Adjust machine device private context + - libata/ahci: Drop PCS quirk for Denverton and beyond + - iommu/iova: Avoid false sharing on fq_timer_on + - libtraceevent: Change users plugin directory + - ASoC: dt-bindings: sun4i-spdif: Fix dma-names warning + - ARM: dts: exynos: Mark LDO10 as always-on on Peach Pit/Pi Chromebooks + - x86/amd_nb: Add PCI device IDs for family 17h, model 70h + - ACPI: custom_method: fix memory leaks + - ACPI / PCI: fix acpi_pci_irq_enable() memory leak + - closures: fix a race on wakeup from closure_sync + - hwmon: (k10temp) Add support for AMD family 17h, model 70h CPUs + - hwmon: (acpi_power_meter) Change log level for 'unsafe software power cap' + - md/raid1: fail run raid1 array when active disk less than one + - dmaengine: ti: edma: Do not reset reserved paRAM slots + - kprobes: Prohibit probing on BUG() and WARN() address + - x86/mm: Fix cpumask_of_node() error condition + - irqchip/sifive-plic: set max threshold for ignored handlers + - s390/crypto: xts-aes-s390 fix extra run-time crypto self tests finding + - irqchip/gic-v3-its: Fix LPI release for Multi-MSI devices + - x86/cpu: Add Tiger Lake to Intel family + - platform/x86: intel_pmc_core: Do not ioremap RAM + - platform/x86: intel_pmc_core_pltdrv: Module removal warning fix + - ASoC: dmaengine: Make the pcm->name equal to pcm->id if the name is not set + - tools/power/x86/intel-speed-select: Fix memory leak + - spi: bcm2835: Work around DONE bit erratum + - io_uring: fix wrong sequence setting logic + - block: make rq sector size accessible for block stats + - raid5: don't set STRIPE_HANDLE to stripe which is in batch list + - mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD + - sched/psi: Correct overly pessimistic size calculation + - mmc: sdhci: Fix incorrect switch to HS mode + - mmc: core: Add helper function to indicate if SDIO IRQs is enabled + - mmc: dw_mmc: Re-store SDIO IRQs mask at system resume + - raid5: don't increment read_errors on EILSEQ return + - mmc: mtk-sd: Re-store SDIO IRQs mask at system resume + - libertas: Add missing sentinel at end of if_usb.c fw_table + - ALSA: hda - Add a quirk model for fixing Huawei Matebook X right speaker + - ALSA: hda - Drop unsol event handler for Intel HDMI codecs + - drm/amd/powerplay/smu7: enforce minimal VBITimeout (v2) + - media: ttusb-dec: Fix info-leak in ttusb_dec_send_command() + - drm: fix module name in edid_firmware log message + - ALSA: hda/realtek - Blacklist PC beep for Lenovo ThinkCentre M73/93 + - zd1211rw: remove false assertion from zd_mac_clear() + - btrfs: delayed-inode: Kill the BUG_ON() in btrfs_delete_delayed_dir_index() + - btrfs: extent-tree: Make sure we only allocate extents from block groups + with the same type + - btrfs: tree-checker: Add ROOT_ITEM check + - btrfs: Detect unbalanced tree with empty leaf before crashing btree + operations + - kvm: Nested KVM MMUs need PAE root too + - media: omap3isp: Set device on omap3isp subdevs + - PM / devfreq: passive: fix compiler warning + - ARM: dts: logicpd-torpedo-baseboard: Fix missing video + - ARM: omap2plus_defconfig: Fix missing video + - iwlwifi: fw: don't send GEO_TX_POWER_LIMIT command to FW version 36 + - ALSA: firewire-tascam: handle error code when getting current source of + clock + - ALSA: firewire-tascam: check intermediate state of clock status and retry + - scsi: scsi_dh_rdac: zero cdb in send_mode_select() + - scsi: qla2xxx: Fix Relogin to prevent modifying scan_state flag + - printk: Do not lose last line in kmsg buffer dump + - IB/mlx5: Free mpi in mp_slave mode + - IB/hfi1: Define variables as unsigned long to fix KASAN warning + - IB/hfi1: Do not update hcrc for a KDETH packet during fault injection + - RDMA: Fix double-free in srq creation error flow + - randstruct: Check member structs in is_pure_ops_struct() + - ARM: dts: am3517-evm: Fix missing video + - rcu/tree: Fix SCHED_FIFO params + - ALSA: hda/realtek - PCI quirk for Medion E4254 + - blk-mq: add callback of .cleanup_rq + - scsi: implement .cleanup_rq callback + - powerpc/imc: Dont create debugfs files for cpu-less nodes + - tpm_tis_core: Turn on the TPM before probing IRQ's + - tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for interrupts + - tpm: Wrap the buffer from the caller to tpm_buf in tpm_send() + - fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock + - fuse: fix missing unlock_page in fuse_writepage() + - fuse: fix beyond-end-of-page access in fuse_parse_cache() + - parisc: Disable HP HSC-PCI Cards to prevent kernel crash + - platform/x86: intel_int0002_vgpio: Fix wakeups not working on Cherry Trail + - KVM: x86: always stop emulation on page fault + - KVM: x86: set ctxt->have_exception in x86_decode_insn() + - KVM: x86: Manually calculate reserved bits when loading PDPTRS + - KVM: x86: Disable posted interrupts for non-standard IRQs delivery modes + - kvm: x86: Add "significant index" flag to a few CPUID leaves + - KVM: x86/mmu: Use fast invalidate mechanism to zap MMIO sptes + - media: videobuf-core.c: poll_wait needs a non-NULL buf pointer + - media: sn9c20x: Add MSI MS-1039 laptop to flip_dmi_table + - media: hantro: Set DMA max segment size + - media: don't drop front-end reference count for ->detach + - media: vivid: fix device init when no_error_inj=1 and fb disabled + - spi: ep93xx: Repair SPI CS lookup tables + - spi: spi-fsl-dspi: Exit the ISR with IRQ_NONE when it's not ours + - binfmt_elf: Do not move brk for INTERP-less ET_EXEC + - ASoC: Intel: NHLT: Fix debug print format + - ASoC: Intel: Skylake: Use correct function to access iomem space + - ASoC: Intel: Fix use of potentially uninitialized variable + - staging: erofs: cannot set EROFS_V_Z_INITED_BIT if fill_inode_lazy fails + - ARM: samsung: Fix system restart on S3C6410 + - ARM: zynq: Use memcpy_toio instead of memcpy on smp bring-up + - arm64: tlb: Ensure we execute an ISB following walk cache invalidation + - arm64: dts: rockchip: limit clock rate of MMC controllers for RK3328 + - iommu/arm-smmu-v3: Disable detection of ATS and PRI + - alarmtimer: Use EOPNOTSUPP instead of ENOTSUPP + - iommu/vt-d: Fix wrong analysis whether devices share the same bus + - regulator: Defer init completion for a while after late_initcall + - efifb: BGRT: Improve efifb_bgrt_sanity_check + - gfs2: clear buf_in_tr when ending a transaction in sweep_bh_for_rgrps + - z3fold: fix retry mechanism in page reclaim + - z3fold: fix memory leak in kmem cache + - mm/compaction.c: clear total_{migrate,free}_scanned before scanning a new + zone + - memcg, oom: don't require __GFP_FS when invoking memcg OOM killer + - memcg, kmem: do not fail __GFP_NOFAIL charges + - lib/lzo/lzo1x_compress.c: fix alignment bug in lzo-rle + - mt76: round up length on mt76_wr_copy + - KEYS: trusted: correctly initialize digests and fix locking issue + - ath10k: fix channel info parsing for non tlv target + - i40e: check __I40E_VF_DISABLE bit in i40e_sync_filters_subtask + - block: mq-deadline: Fix queue restart handling + - block: fix null pointer dereference in blk_mq_rq_timed_out() + - smb3: allow disabling requesting leases + - smb3: fix unmount hang in open_shroot + - smb3: fix leak in "open on server" perf counter + - ovl: Fix dereferencing possible ERR_PTR() + - ovl: filter of trusted xattr results in audit + - btrfs: fix allocation of free space cache v1 bitmap pages + - Btrfs: fix use-after-free when using the tree modification log + - btrfs: Relinquish CPUs in btrfs_compare_trees + - btrfs: adjust dirty_metadata_bytes after writeback failure of extent buffer + - btrfs: qgroup: Fix the wrong target io_tree when freeing reserved data space + - btrfs: qgroup: Fix reserved data space leak if we have multiple reserve + calls + - Btrfs: fix race setting up and completing qgroup rescan workers + - btrfs: Fix a regression which we can't convert to SINGLE profile + - SUNRPC: Dequeue the request from the receive queue while we're re-encoding + - SUNRPC: Fix buffer handling of GSS MIC without slack + - ACPI / LPSS: Save/restore LPSS private registers also on Lynxpoint + - md/raid6: Set R5_ReadError when there is read failure on parity disk + - md: don't report active array_state until after revalidate_disk() completes. + - md: only call set_in_sync() when it is expected to succeed. + - cfg80211: Purge frame registrations on iftype change + - /dev/mem: Bail out upon SIGKILL. + - fs: Export generic_fadvise() + - mm: Handle MADV_WILLNEED through vfs_fadvise() + - xfs: Fix stale data exposure when readahead races with hole punch + - ipmi: move message error checking to avoid deadlock + - mtd: rawnand: stm32_fmc2: avoid warnings when building with W=1 option + - ext4: fix warning inside ext4_convert_unwritten_extents_endio + - ext4: fix punch hole for inline_data file systems + - quota: fix wrong condition in is_quota_modification() + - hwrng: core - don't wait on add_early_randomness() + - i2c: riic: Clear NACK in tend isr + - CIFS: fix max ea value size + - CIFS: Fix oplock handling for SMB 2.1+ protocols + - drm/amd/display: Restore backlight brightness after system resume + - drm/amd/display: dce11.x /dce12 update formula input + - drm/amd/display: Add missing HBM support and raise Vega20's uclk. + - drm/amdgpu/display: fix 64 bit divide + - md/raid0: avoid RAID0 data corruption due to layout confusion. + - mt76: mt7615: always release sem in mt7615_load_patch + - mt76: mt7615: fix mt7615 firmware path definitions + - platform/chrome: cros_ec_rpmsg: Fix race with host command when probe failed + - Linux 5.3.4 + * ELAN469D touch pad not working (LP: #1795292) // Ubuntu won't boot on Dell + Inspiron 7375 (LP: #1837688) // Eoan update: v5.3.4 upstream stable release + (LP: #1848046) + - iommu/amd: Override wrong IVRS IOAPIC on Raven Ridge systems + * Eoan update: v5.3.3 upstream stable release (LP: #1848045) + - Linux 5.3.2 + - Revert "Linux 5.3.2" + - Linux 5.3.3 + * Eoan update: v5.3.2 upstream stable release (LP: #1848042) + - netfilter: add missing IS_ENABLED(CONFIG_NF_TABLES) check to header-file. + - clocksource/drivers/timer-of: Do not warn on deferred probe + - clocksource/drivers: Do not warn on probe defer + - drm/amd/display: Allow cursor async updates for framebuffer swaps + - drm/amd/display: Skip determining update type for async updates + - drm/amd/display: Don't replace the dc_state for fast updates + - drm/amd/display: readd -msse2 to prevent Clang from emitting libcalls to + undefined SW FP routines + - powerpc/xive: Fix bogus error code returned by OPAL + - HID: prodikeys: Fix general protection fault during probe + - HID: sony: Fix memory corruption issue on cleanup. + - HID: logitech: Fix general protection fault caused by Logitech driver + - HID: logitech-dj: Fix crash when initial logi_dj_recv_query_paired_devices + fails + - HID: hidraw: Fix invalid read in hidraw_ioctl + - HID: Add quirk for HP X500 PIXART OEM mouse + - mtd: cfi_cmdset_0002: Use chip_good() to retry in do_write_oneword() + - crypto: talitos - fix missing break in switch statement + - clk: imx: imx8mm: fix audio pll setting + - Revert "mm/z3fold.c: fix race between migration and destruction" + - ALSA: usb-audio: Add Hiby device family to quirks for native DSD support + - ALSA: usb-audio: Add DSD support for EVGA NU Audio + - ALSA: dice: fix wrong packet parameter for Alesis iO26 + - ALSA: hda - Add laptop imic fixup for ASUS M9V laptop + - ALSA: hda - Apply AMD controller workaround for Raven platform + - platform/x86: i2c-multi-instantiate: Derive the device name from parent + - objtool: Clobber user CFLAGS variable + - Linux 5.3.2 + * Check for CPU Measurement sampling (LP: #1847590) + - s390/cpumsf: Check for CPU Measurement sampling + * revert the revert of ext4: make __ext4_get_inode_loc plug (LP: #1846486) + - random: try to actively add entropy rather than passively wait for it + - Revert "Revert "ext4: make __ext4_get_inode_loc plug"" + * Fix non-working Realtek USB ethernet after system resume (LP: #1847063) + - r8152: Set macpassthru in reset_resume callback + * overlayfs: allow with shiftfs as underlay (LP: #1846272) + - SAUCE: overlayfs: allow with shiftfs as underlay + * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186) + - SAUCE: apparmor: fix nnp subset test for unconfined + * PM / hibernate: fix potential memory corruption (LP: #1847118) + - PM / hibernate: memory_bm_find_bit(): Tighten node optimisation + * Miscellaneous Ubuntu changes + - update dkms package versions + + -- Kleber Sacilotto de Souza Thu, 24 Oct 2019 14:07:37 +0200 + +linux-oracle (5.3.0-1003.3) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1003.3 -proposed tracker (LP: #1848644) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-19.20 ] + + * eoan/linux: 5.3.0-19.20 -proposed tracker (LP: #1848648) + * eoan kernel does not contain "ipv6: do not free rt if FIB_LOOKUP_NOREF is + set on suppress rule" (LP: #1847478) + - ipv6: do not free rt if FIB_LOOKUP_NOREF is set on suppress rule + + -- Marcelo Henrique Cerri Fri, 18 Oct 2019 16:14:50 -0300 + +linux-oracle (5.3.0-1002.2) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1002.2 -proposed tracker (LP: #1847295) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-18.19 ] + + * eoan/linux: 5.3.0-18.19 -proposed tracker (LP: #1847298) + * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704) + - [Packaging] arm64: snapdragon: introduce a snapdragon flavour + - [Packaging] arm64: snapdragon: switch kernel format to Image + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y + - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y + - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y + - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y + - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y + - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y + - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y + - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y + - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y + - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y + - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y + - [Config] arm64: snapdragon: CONFIG_USB_OTG=y + - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y + - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y + - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y + - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y + - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y + - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y + + [ Ubuntu: 5.3.0-17.18 ] + + * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641) + * CVE-2019-17056 + - nfc: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17055 + - mISDN: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17054 + - appletalk: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17053 + - ieee802154: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17052 + - ax25: enforce CAP_NET_RAW for raw sockets + * CVE-2019-15098 + - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe() + * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices. + (LP: #1846470) + - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect + * Re-enable linux-libc-dev build on i386 (LP: #1846508) + - [Packaging] Build only linux-libc-dev for i386 + - [Debian] final-checks -- ignore archtictures with no binaries + * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic- + proposed (LP: #1845820) + - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT + * Revert ESE DASD discard support (LP: #1846219) + - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes" + * Miscellaneous Ubuntu changes + - update dkms package versions + + -- Andrea Righi Thu, 10 Oct 2019 14:37:44 +0200 + +linux-oracle (5.3.0-1001.1) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1001.1 -proposed tracker (LP: #1845724) + + * Packaging resync (LP: #1786013) + - [Packaging] update update.conf + + * Change kernel compression method to improve boot speed (LP: #1840934) + - UBUNTU [Config] Change kernel compression to LZ4 + + * Miscellaneous Ubuntu changes + - [Config] update configs after rebase to 5.3 + - [Packaging] Update packaging for rebase to 5.3 + + [ Ubuntu: 5.3.0-16.17 ] + + * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204) + * zfs fails to build on s390x with debug symbols enabled (LP: #1846143) + - SAUCE: s390: Mark atomic const ops always inline + + -- Seth Forshee Wed, 02 Oct 2019 09:25:24 -0500 + +linux-oracle (5.3.0-1000.0) eoan; urgency=medium + + * Emtpy entry + + -- Seth Forshee Wed, 02 Oct 2019 08:22:09 -0500 + +linux-oracle (5.0.0-1004.7) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1004.7 -proposed tracker (LP: #1846019) + + * 5.0-based linux-oracle kernels can't run ADT (LP: #1845434) + - [config] CONFIG_VIRTIO=y + + [ Ubuntu: 5.0.0-31.33 ] + + * disco/linux: 5.0.0-31.33 -proposed tracker (LP: #1846026) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * /proc/self/maps paths missing on live session (was vlc won't start; eoan + 19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies) + (LP: #1842382) + - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs" + + -- Khalid Elmously Mon, 30 Sep 2019 20:23:48 -0400 + +linux-oracle (5.0.0-1003.4) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1003.4 -proposed tracker (LP: #1844358) + + * Disco update: upstream stable patchset 2019-08-13 (LP: #1840076) + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + + [ Ubuntu: 5.0.0-30.32 ] + + * disco/linux: 5.0.0-30.32 -proposed tracker (LP: #1844362) + * Disco update: upstream stable patchset 2019-08-20 (LP: #1840846) + - Revert "e1000e: fix cyclic resets at link up with active tx" + - e1000e: start network tx queue only when link is up + - Input: synaptics - enable SMBUS on T480 thinkpad trackpad + - nilfs2: do not use unexported cpu_to_le32()/le32_to_cpu() in uapi header + - drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT + - firmware: improve LSM/IMA security behaviour + - irqchip/gic-v3-its: Fix command queue pointer comparison bug + - clk: ti: clkctrl: Fix returning uninitialized data + - efi/bgrt: Drop BGRT status field reserved bits check + - perf/core: Fix perf_sample_regs_user() mm check + - ARM: dts: gemini Fix up DNS-313 compatible string + - ARM: omap2: remove incorrect __init annotation + - afs: Fix uninitialised spinlock afs_volume::cb_break_lock + - x86/apic: Fix integer overflow on 10 bit left shift of cpu_khz + - be2net: fix link failure after ethtool offline test + - ppp: mppe: Add softdep to arc4 + - sis900: fix TX completion + - ARM: dts: imx6ul: fix PWM[1-4] interrupts + - pinctrl: mcp23s08: Fix add_data and irqchip_add_nested call order + - dm table: don't copy from a NULL pointer in realloc_argv() + - dm verity: use message limit for data block corruption message + - x86/boot/64: Fix crash if kernel image crosses page table boundary + - x86/boot/64: Add missing fixup_pointer() for next_early_pgt access + - HID: chicony: add another quirk for PixArt mouse + - pinctrl: mediatek: Ignore interrupts that are wake only during resume + - cpu/hotplug: Fix out-of-bounds read when setting fail state + - pinctrl: mediatek: Update cur_mask in mask/mask ops + - linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL + - genirq: Delay deactivation in free_irq() + - genirq: Fix misleading synchronize_irq() documentation + - genirq: Add optional hardware synchronization for shutdown + - x86/ioapic: Implement irq_get_irqchip_state() callback + - x86/irq: Handle spurious interrupt after shutdown gracefully + - x86/irq: Seperate unused system vectors from spurious entry again + - ARC: hide unused function unw_hdr_alloc + - s390: fix stfle zero padding + - s390/qdio: (re-)initialize tiqdio list entries + - s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + - crypto: talitos - move struct talitos_edesc into talitos.h + - crypto: talitos - fix hash on SEC1. + - crypto/NX: Set receive window credits to max number of CRBs in RxFIFO + - drm/udl: introduce a macro to convert dev to udl. + - drm/udl: move to embedding drm device inside udl device. + - x86/entry/32: Fix ENDPROC of common_spurious + - irqchip/irq-csky-mpintc: Support auto irq deliver to all cpus + - arm64: dts: ls1028a: Fix CPU idle fail. + - selftests/powerpc: Add test of fork with mapping above 512TB + - x86/efi: fix a -Wtype-limits compilation warning + - pinctrl: ocelot: fix gpio direction for pins after 31 + - pinctrl: ocelot: fix pinmuxing for pins after 31 + - mm/oom_kill.c: fix uninitialized oc->constraint + - fork,memcg: alloc_thread_stack_node needs to set tsk->stack + - MIPS: ath79: fix ar933x uart parity mode + - MIPS: fix build on non-linux hosts + - arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly + - scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported + - dmaengine: imx-sdma: fix use-after-free on probe error path + - wil6210: fix potential out-of-bounds read + - ath10k: Do not send probe response template for mesh + - ath9k: Check for errors when reading SREV register + - ath6kl: add some bounds checking + - ath10k: add peer id check in ath10k_peer_find_by_id + - wil6210: fix spurious interrupts in 3-msi + - ath: DFS JP domain W56 fixed pulse type 3 RADAR detection + - regmap: debugfs: Fix memory leak in regmap_debugfs_init + - batman-adv: fix for leaked TVLV handler. + - media: dvb: usb: fix use after free in dvb_usb_device_exit + - media: spi: IR LED: add missing of table registration + - crypto: talitos - fix skcipher failure due to wrong output IV + - media: ov7740: avoid invalid framesize setting + - media: marvell-ccic: fix DMA s/g desc number calculation + - media: vpss: fix a potential NULL pointer dereference + - media: media_device_enum_links32: clean a reserved field + - net: stmmac: dwmac1000: Clear unused address entries + - net: stmmac: dwmac4/5: Clear unused address entries + - qed: Set the doorbell address correctly + - signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig + - af_key: fix leaks in key_pol_get_resp and dump_sp. + - xfrm: Fix xfrm sel prefix length validation + - fscrypt: clean up some BUG_ON()s in block encryption/decryption + - perf annotate TUI browser: Do not use member from variable within its own + initialization + - media: mc-device.c: don't memset __user pointer contents + - media: saa7164: fix remove_proc_entry warning + - media: staging: media: davinci_vpfe: - Fix for memory leak if decoder + initialization fails. + - net: phy: Check against net_device being NULL + - crypto: talitos - properly handle split ICV. + - crypto: talitos - Align SEC1 accesses to 32 bits boundaries. + - tua6100: Avoid build warnings. + - batman-adv: Fix duplicated OGMs on NETDEV_UP + - locking/lockdep: Fix merging of hlocks with non-zero references + - media: wl128x: Fix some error handling in fm_v4l2_init_video_device() + - cpupower : frequency-set -r option misses the last cpu in related cpu list + - arm64: mm: make CONFIG_ZONE_DMA32 configurable + - perf jvmti: Address gcc string overflow warning for strncpy() + - net: stmmac: dwmac4: fix flow control issue + - net: stmmac: modify default value of tx-frames + - crypto: inside-secure - do not rely on the hardware last bit for result + descriptors + - net: fec: Do not use netdev messages too early + - net: axienet: Fix race condition causing TX hang + - s390/qdio: handle PENDING state for QEBSM devices + - RAS/CEC: Fix pfn insertion + - net: sfp: add mutex to prevent concurrent state checks + - ipset: Fix memory accounting for hash types on resize + - perf cs-etm: Properly set the value of 'old' and 'head' in snapshot mode + - perf test 6: Fix missing kvm module load for s390 + - perf report: Fix OOM error in TUI mode on s390 + - irqchip/meson-gpio: Add support for Meson-G12A SoC + - media: uvcvideo: Fix access to uninitialized fields on probe error + - media: fdp1: Support M3N and E3 platforms + - iommu: Fix a leak in iommu_insert_resv_region + - gpio: omap: fix lack of irqstatus_raw0 for OMAP4 + - gpio: omap: ensure irq is enabled before wakeup + - regmap: fix bulk writes on paged registers + - bpf: silence warning messages in core + - media: s5p-mfc: fix reading min scratch buffer size on MFC v6/v7 + - selinux: fix empty write to keycreate file + - x86/cpu: Add Ice Lake NNPI to Intel family + - ASoC: meson: axg-tdm: fix sample clock inversion + - rcu: Force inlining of rcu_read_lock() + - x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS + - qed: iWARP - Fix tc for MPA ll2 connection + - block: null_blk: fix race condition for null_del_dev + - blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership + arbitration + - xfrm: fix sa selector validation + - sched/core: Add __sched tag for io_schedule() + - sched/fair: Fix "runnable_avg_yN_inv" not used warnings + - perf/x86/intel/uncore: Handle invalid event coding for free-running counter + - x86/atomic: Fix smp_mb__{before,after}_atomic() + - perf evsel: Make perf_evsel__name() accept a NULL argument + - vhost_net: disable zerocopy by default + - ipoib: correcly show a VF hardware address + - x86/cacheinfo: Fix a -Wtype-limits warning + - blk-iolatency: only account submitted bios + - ACPICA: Clear status of GPEs on first direct enable + - EDAC/sysfs: Fix memory leak when creating a csrow object + - nvme: fix possible io failures when removing multipathed ns + - nvme-pci: properly report state change failure in nvme_reset_work + - nvme-pci: set the errno on ctrl state change error + - lightnvm: pblk: fix freeing of merged pages + - arm64: Do not enable IRQs for ct_user_exit + - ipsec: select crypto ciphers for xfrm_algo + - ipvs: defer hook registration to avoid leaks + - media: s5p-mfc: Make additional clocks optional + - media: i2c: fix warning same module names + - [Config] rename module adv7511 + - ntp: Limit TAI-UTC offset + - timer_list: Guard procfs specific code + - acpi/arm64: ignore 5.1 FADTs that are reported as 5.0 + - media: coda: fix mpeg2 sequence number handling + - media: coda: fix last buffer handling in V4L2_ENC_CMD_STOP + - media: coda: increment sequence offset for the last returned frame + - media: vimc: cap: check v4l2_fill_pixfmt return value + - media: hdpvr: fix locking and a missing msleep + - net: stmmac: sun8i: force select external PHY when no internal one + - rtlwifi: rtl8192cu: fix error handle when usb probe failed + - mt7601u: do not schedule rx_tasklet when the device has been disconnected + - x86/build: Add 'set -e' to mkcapflags.sh to delete broken capflags.c + - mt7601u: fix possible memory leak when the device is disconnected + - ipvs: fix tinfo memory leak in start_sync_thread + - ath10k: add missing error handling + - ath10k: fix PCIE device wake up failed + - perf tools: Increase MAX_NR_CPUS and MAX_CACHES + - ASoC: Intel: hdac_hdmi: Set ops to NULL on remove + - libata: don't request sense data on !ZAC ATA devices + - clocksource/drivers/exynos_mct: Increase priority over ARM arch timer + - xsk: Properly terminate assignment in xskq_produce_flush_desc + - rslib: Fix decoding of shortened codes + - rslib: Fix handling of of caller provided syndrome + - ixgbe: Check DDM existence in transceiver before access + - crypto: serpent - mark __serpent_setkey_sbox noinline + - crypto: asymmetric_keys - select CRYPTO_HASH where needed + - wil6210: drop old event after wmi_call timeout + - EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec + - bcache: check CACHE_SET_IO_DISABLE in allocator code + - bcache: check CACHE_SET_IO_DISABLE bit in bch_journal() + - bcache: acquire bch_register_lock later in cached_dev_free() + - bcache: check c->gc_thread by IS_ERR_OR_NULL in cache_set_flush() + - bcache: fix potential deadlock in cached_def_free() + - net: hns3: fix a -Wformat-nonliteral compile warning + - net: hns3: add some error checking in hclge_tm module + - ath10k: destroy sdio workqueue while remove sdio module + - net: mvpp2: prs: Don't override the sign bit in SRAM parser shift + - igb: clear out skb->tstamp after reading the txtime + - iwlwifi: mvm: Drop large non sta frames + - bpf: fix uapi bpf_prog_info fields alignment + - perf stat: Make metric event lookup more robust + - perf stat: Fix group lookup for metric group + - net: usb: asix: init MAC address buffers + - rxrpc: Fix oops in tracepoint + - bpf, libbpf, smatch: Fix potential NULL pointer dereference + - selftests: bpf: fix inlines in test_lwt_seg6local + - bonding: validate ip header before check IPPROTO_IGMP + - gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants + - tools: bpftool: Fix json dump crash on powerpc + - Bluetooth: hci_bcsp: Fix memory leak in rx_skb + - Bluetooth: Add new 13d3:3491 QCA_ROME device + - Bluetooth: Add new 13d3:3501 QCA_ROME device + - Bluetooth: 6lowpan: search for destination address in all peers + - perf tests: Fix record+probe_libc_inet_pton.sh for powerpc64 + - Bluetooth: Check state in l2cap_disconnect_rsp + - gtp: add missing gtp_encap_disable_sock() in gtp_encap_enable() + - Bluetooth: validate BLE connection interval updates + - gtp: fix suspicious RCU usage + - gtp: fix Illegal context switch in RCU read-side critical section. + - gtp: fix use-after-free in gtp_encap_destroy() + - gtp: fix use-after-free in gtp_newlink() + - net: mvmdio: defer probe of orion-mdio if a clock is not ready + - iavf: fix dereference of null rx_buffer pointer + - floppy: fix out-of-bounds read in next_valid_format + - floppy: fix invalid pointer dereference in drive_name + - xen: let alloc_xenballooned_pages() fail if not enough memory free + - scsi: NCR5380: Always re-enable reselection interrupt + - Revert "scsi: ncr5380: Increase register polling limit" + - scsi: core: Fix race on creating sense cache + - scsi: megaraid_sas: Fix calculation of target ID + - scsi: mac_scsi: Increase PIO/PDMA transfer length threshold + - scsi: mac_scsi: Fix pseudo DMA implementation, take 2 + - crypto: ghash - fix unaligned memory access in ghash_setkey() + - crypto: ccp - Validate the the error value used to index error messages + - crypto: arm64/sha1-ce - correct digest for empty data in finup + - crypto: arm64/sha2-ce - correct digest for empty data in finup + - crypto: chacha20poly1305 - fix atomic sleep when using async algorithm + - crypto: crypto4xx - fix AES CTR blocksize value + - crypto: crypto4xx - fix blocksize for cfb and ofb + - crypto: crypto4xx - block ciphers should only accept complete blocks + - crypto: ccp - memset structure fields to zero before reuse + - crypto: ccp/gcm - use const time tag comparison. + - crypto: crypto4xx - fix a potential double free in ppc4xx_trng_probe + - bcache: Revert "bcache: fix high CPU occupancy during journal" + - bcache: Revert "bcache: free heap cache_set->flush_btree in + bch_journal_free" + - bcache: ignore read-ahead request failure on backing device + - bcache: fix mistaken sysfs entry for io_error counter + - bcache: destroy dc->writeback_write_wq if failed to create + dc->writeback_thread + - Input: gtco - bounds check collection indent level + - Input: synaptics - whitelist Lenovo T580 SMBus intertouch + - regulator: s2mps11: Fix buck7 and buck8 wrong voltages + - arm64: tegra: Update Jetson TX1 GPU regulator timings + - iwlwifi: pcie: don't service an interrupt that was masked + - iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X + - iwlwifi: don't WARN when calling iwl_get_shared_mem_conf with RF-Kill + - iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices + - NFSv4: Handle the special Linux file open access mode + - pnfs/flexfiles: Fix PTR_ERR() dereferences in ff_layout_track_ds_error + - pNFS: Fix a typo in pnfs_update_layout + - pnfs: Fix a problem where we gratuitously start doing I/O through the MDS + - lib/scatterlist: Fix mapping iterator when sg->offset is greater than + PAGE_SIZE + - ASoC: dapm: Adapt for debugfs API change + - raid5-cache: Need to do start() part job after adding journal device + - ALSA: seq: Break too long mutex context in the write loop + - ALSA: hda/realtek - Fixed Headphone Mic can't record on Dell platform + - media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() + - media: coda: Remove unbalanced and unneeded mutex unlock + - media: videobuf2-core: Prevent size alignment wrapping buffer size to 0 + - media: videobuf2-dma-sg: Prevent size from overflowing + - KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed + - arm64: tegra: Fix AGIC register range + - fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys + inodes. + - kconfig: fix missing choice values in auto.conf + - drm/nouveau/i2c: Enable i2c pads & busses during preinit + - padata: use smp_mb in padata_reorder to avoid orphaned padata jobs + - dm zoned: fix zone state management race + - xen/events: fix binding user event channels to cpus + - 9p/xen: Add cleanup path in p9_trans_xen_init + - 9p/virtio: Add cleanup path in p9_virtio_init + - x86/boot: Fix memory leak in default_get_smp_config() + - perf/x86/intel: Fix spurious NMI on fixed counter + - perf/x86/amd/uncore: Do not set 'ThreadMask' and 'SliceMask' for non-L3 PMCs + - perf/x86/amd/uncore: Set the thread mask for F17h L3 PMCs + - drm/edid: parse CEA blocks embedded in DisplayID + - intel_th: pci: Add Ice Lake NNPI support + - PCI: hv: Fix a use-after-free bug in hv_eject_device_work() + - PCI: Do not poll for PME if the device is in D3cold + - PCI: qcom: Ensure that PERST is asserted for at least 100 ms + - Btrfs: fix data loss after inode eviction, renaming it, and fsync it + - Btrfs: fix fsync not persisting dentry deletions due to inode evictions + - Btrfs: add missing inode version, ctime and mtime updates when punching hole + - IB/mlx5: Report correctly tag matching rendezvous capability + - HID: wacom: generic: only switch the mode on devices with LEDs + - HID: wacom: generic: Correct pad syncing + - HID: wacom: correct touch resolution x/y typo + - libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields + - coda: pass the host file in vma->vm_file on mmap + - include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT + architectures + - xfs: don't overflow xattr listent buffer + - xfs: rename m_inotbt_nores to m_finobt_nores + - xfs: don't ever put nlink > 0 inodes on the unlinked list + - xfs: reserve blocks for ifree transaction during log recovery + - xfs: fix reporting supported extra file attributes for statx() + - xfs: serialize unaligned dio writes against all other dio writes + - xfs: abort unaligned nowait directio early + - gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM + - crypto: caam - limit output IV to CBC to work around CTR mode DMA issue + - parisc: Ensure userspace privilege for ptraced processes in regset functions + - parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 + - powerpc/32s: fix suspend/resume when IBATs 4-7 are used + - powerpc/watchpoint: Restore NV GPRs while returning from exception + - powerpc/powernv/npu: Fix reference leak + - powerpc/pseries: Fix oops in hotplug memory notifier + - mmc: sdhci-msm: fix mutex while in spinlock + - eCryptfs: fix a couple type promotion bugs + - mtd: rawnand: mtk: Correct low level time calculation of r/w cycle + - mtd: spinand: read returns badly if the last page has bitflips + - intel_th: msu: Fix single mode with disabled IOMMU + - Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug + - usb: Handle USB3 remote wakeup for LPM enabled devices correctly + - blk-throttle: fix zero wait time for iops throttled group + - blk-iolatency: clear use_delay when io.latency is set to zero + - blkcg: update blkcg_print_stat() to handle larger outputs + - net: mvmdio: allow up to four clocks to be specified for orion-mdio + - dt-bindings: allow up to four clocks for orion-mdio + - dm bufio: fix deadlock with loop device + - ath10k: Check tx_stats before use it + - ath10k: fix incorrect multicast/broadcast rate setting + - spi: rockchip: turn down tx dma bursts + - ath10k: Fix encoding for protected management frames + - media: v4l2-core: fix use-after-free error + - media: usb:zr364xx:Fix KASAN:null-ptr-deref Read in zr364xx_vidioc_querycap + - locking/lockdep: Fix OOO unlock when hlocks need merging + - media: aspeed: change irq to threaded irq + - gpio: omap: Fix lost edge wake-up interrupts + - media: davinci: vpif_capture: fix memory leak in vpif_probe() + - perf/x86/intel: Disable check_msr for real HW + - integrity: Fix __integrity_init_keyring() section mismatch + - iavf: allow null RX descriptors + - ASoC: rsnd: fixup mod ID calculation in rsnd_ctu_probe_ + - bpf: fix callees pruning callers + - net: netsec: initialize tx ring on ndo_open + - EDAC/sysfs: Drop device references properly + - nvme-pci: adjust irq max_vector using num_possible_cpus() + - media: mt9m111: fix fw-node refactoring + - ASoC: soc-core: call snd_soc_unbind_card() under mutex_lock; + - ath10k: fix fw crash by moving chip reset after napi disabled + - netfilter: ctnetlink: Fix regression in conntrack entry deletion + - bpf: fix BPF_ALU32 | BPF_ARSH on BE arches + - gpio: Fix return value mismatch of function gpiod_get_from_of_node() + - ath9k: correctly handle short radar pulses + - ath10k: Fix memory leak in qmi + - net: hns3: add Asym Pause support to fix autoneg problem + - iwlwifi: dbg: fix debug monitor stop and restart delays + - bnxt_en: Disable bus master during PCI shutdown and driver unload. + - bnxt_en: Fix statistics context reservation logic for RDMA driver. + - perf stat: Fix metrics with --no-merge + - perf stat: Don't merge events in the same PMU + - net: hns3: enable broadcast promisc mode when initializing VF + - Bluetooth: hidp: NUL terminate a string in the compat ioctl + - xdp: fix race on generic receive path + - net: hns3: fix __QUEUE_STATE_STACK_XOFF not cleared issue + - blk-iolatency: fix STS_AGAIN handling + - scsi: NCR5380: Handle PDMA failure reliably + - scsi: sd_zbc: Fix compilation warning + - scsi: zfcp: fix request object use-after-free in send path causing seqno + errors + - scsi: zfcp: fix request object use-after-free in send path causing wrong + traces + - cifs: fix crash in smb2_compound_op()/smb2_set_next_command() + - cifs: Properly handle auto disabling of serverino option + - regulator: s2mps11: Fix ERR_PTR dereference on GPIO lookup failure + - iwlwifi: mvm: delay GTK setting in FW in AP mode + - iwlwifi: mvm: clear rfkill_safe_init_done when we start the firmware + - opp: Don't use IS_ERR on invalid supplies + - ASoC: core: Adapt for debugfs API change + - ceph: fix end offset in truncate_inode_pages_range call + - KVM: nVMX: Always sync GUEST_BNDCFGS when it comes from vmcs01 + - KVM: VMX: Fix handling of #MC that occurs during VM-Entry + - KVM: VMX: check CPUID before allowing read/write of IA32_XSS + - KVM: PPC: Book3S HV: Signed extend decrementer value if not using large + decrementer + - KVM: PPC: Book3S HV: Clear pending decrementer exceptions on nested guest + entry + - KVM: PPC: Book3S HV: Fix CR0 setting in TM emulation + - signal/usb: Replace kill_pid_info_as_cred with kill_pid_usb_asyncio + - signal: Correct namespace fixups of si_pid and si_uid + - i3c: fix i2c and i3c scl rate by bus mode + - ARM: dts: gemini: Set DIR-685 SPI CS as active low + - rt2x00usb: fix rx queue hang + - block: Allow mapping of vmalloc-ed buffers + - block: Fix potential overflow in blk_report_zones() + - RDMA/srp: Accept again source addresses that do not have a port number + - mm/nvdimm: add is_ioremap_addr and use that to check ioremap address + - resource: fix locking in find_next_iomem_res() + - powerpc/powernv: Fix stale iommu table base after VFIO + - dax: Fix missed wakeup with PMD faults + - pstore: Fix double-free in pstore_mkfile() failure path + - [Config] rename module adv7511 + * ACPI support for the ARMv8.2 Statistical Profiling Extension (LP: #1841490) + - ACPICA: ACPI 6.3: MADT: add support for statistical profiling in GICC + - ACPICA: ACPI 6.3: PPTT add additional fields in Processor Structure Flags + - ACPI/PPTT: Modify node flag detection to find last IDENTICAL + - ACPI/PPTT: Add function to return ACPI 6.3 Identical tokens + - arm_pmu: acpi: spe: Add initial MADT/SPE probing + - perf: arm_spe: Enable ACPI/Platform automatic module loading + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // QEMU - count cache flush + Spectre v2 mitigation (CVE) (required for POWER9 DD2.3) (LP: #1832622) + - KVM: PPC: Book3S: Add count cache flush parameters to kvmppc_get_cpu_char() + * Additional regression in CMA allocation rework (LP: #1841483) + - dma-direct: fix zone selection after an unaddressable CMA allocation + * [SRU][B-OEM-OSP1/D/E] reduce s2idle power consumption when BIOS uses shared + power resources (LP: #1840882) + - PCI / ACPI: Use cached ACPI device state to get PCI device power state + - ACPI / PM: Introduce concept of a _PR0 dependent device + - PCI / ACPI: Add _PR0 dependent devices + * ipv6: fix neighbour resolution with raw socket (LP: #1834465) + - ipv6: constify rt6_nexthop() + - ipv6: fix neighbour resolution with raw socket + * realtek r8822be kernel module fails after update to linux kernel-headers + 5.0.0-21 (LP: #1838133) + - build_bug.h: add wrapper for _Static_assert + - lib/vsprintf.c: move sizeof(struct printf_spec) next to its definition + - linux/fs.h: move member alignment check next to definition of struct + filename + - rtw88: add license for Makefile + - rtw88: fix subscript above array bounds compiler warning + - rtw88: fix unassigned rssi_level in rtw_sta_info + - rtw88: avoid circular locking between local->iflist_mtx and rtwdev->mutex + - rtw88: Make some symbols static + - rtw88: pci: use ieee80211_ac_numbers instead of 0-3 + - rtw88: pci: check if queue mapping exceeds size of ac_to_hwq + - rtw88: more descriptions about LPS + - rtw88: add fast xmit support + - rtw88: add support for random mac scan + - rtw88: add beacon function setting + - rtw88: 8822c: add rf write protection when switching channel + - rtw88: 8822c: update channel and bandwidth BB setting + - rtw88: 8822c: disable rx clock gating before counter reset + - rtw88: 8822c: use more accurate ofdm fa counting + - rtw88: power on again if it was already on + - rtw88: restore DACK results to save time + - rtw88: rsvd page should go though management queue + - rtw88: fix typo rtw_writ16_set + - rtw88: resolve order of tx power setting routines + - rtw88: do not use (void *) as argument + - rtw88: unify prefixes for tx power setting routine + - rtw88: remove unused variable + - rtw88: fix incorrect tx power limit at 5G + - rtw88: choose the lowest as world-wide power limit + - rtw88: correct power limit selection + - rtw88: update tx power limit table to RF v20 + - rtw88: remove all RTW_MAX_POWER_INDEX macro + - rtw88: refine flow to get tx power index + - rtw88: Fix misuse of GENMASK macro + - rtw88: pci: Rearrange the memory usage for skb in RX ISR + - rtw88: pci: Use DMA sync instead of remapping in RX ISR + - rtw88: debug: dump tx power indexes in use + - rtw88: use txpwr_lmt_cfg_pair struct, not arrays + - rtw88: pci: remove set but not used variable 'ip_sel' + - rtw88: allow c2h operation in irq context + - rtw88: enclose c2h cmd handle with mutex + - rtw88: add BT co-existence support + - SAUCE: rtw88: pci: enable MSI interrupt + * Disco update: upstream stable patchset 2019-08-30 (LP: #1842128) + - selftests/bpf: fix sendmsg6_prog on s390 + - net: mvpp2: Don't check for 3 consecutive Idle frames for 10G links + - selftests: forwarding: gre_multipath: Enable IPv4 forwarding + - selftests: forwarding: gre_multipath: Fix flower filters + - can: mcp251x: add error check when wq alloc failed + - can: gw: Fix error path of cgw_module_init + - ASoC: rockchip: Fix mono capture + - mac80211_hwsim: Fix possible null-pointer dereferences in + hwsim_dump_radio_nl() + - netfilter: ipset: Actually allow destination MAC address for hash:ip,mac + sets too + - netfilter: ipset: Copy the right MAC address in bitmap:ip,mac and + hash:ip,mac sets + - rxrpc: Fix potential deadlock + - rxrpc: Fix the lack of notification when sendmsg() fails on a DATA packet + - net: phy: phy_led_triggers: Fix a possible null-pointer dereference in + phy_led_trigger_change_speed() + - NFS: Fix regression whereby fscache errors are appearing on 'nofsc' mounts + - HID: quirks: Set the INCREMENT_USAGE_ON_DUPLICATE quirk on Saitek X52 + - drm/rockchip: Suspend DP late + - SMB3: Fix potential memory leak when processing compound chain + - s390: put _stext and _etext into .text section + - net: stmmac: Fix issues when number of Queues >= 4 + - net: stmmac: tc: Do not return a fragment entry + - block, bfq: handle NULL return value by bfq_init_rq() + - KVM: arm64: Don't write junk to sysregs on reset + - KVM: arm: Don't write junk to CP15 registers on reset + - clk: socfpga: stratix10: fix rate caclulationg for cnt_clks + - ceph: clear page dirty before invalidate page + - Drivers: hv: vmbus: Fix virt_to_hvpfn() for X86_PAE + - dm integrity: fix a crash due to BUG_ON in __journal_read_write() + - dm raid: add missing cleanup in raid_ctr() + - xfs: don't trip over uninitialized buffer on extent read of corrupted inode + - xfs: always rejoin held resources during defer roll + - rxrpc: Fix local endpoint refcounting + - rxrpc: Fix read-after-free in rxrpc_queue_local() + - rxrpc: Fix local endpoint replacement + - rxrpc: Fix local refcounting + - regulator: axp20x: fix DCDCA and DCDCD for AXP806 + - regulator: axp20x: fix DCDC5 and DCDC6 for AXP803 + - HID: Add 044f:b320 ThrustMaster, Inc. 2 in 1 DT + - MIPS: kernel: only use i8253 clocksource with periodic clockevent + - mips: fix cacheinfo + - netfilter: ebtables: fix a memory leak bug in compat + - ASoC: dapm: Fix handling of custom_stop_condition on DAPM graph walks + - spi: pxa2xx: Balance runtime PM enable/disable on error + - bpf: sockmap, sock_map_delete needs to use xchg + - bpf: sockmap, synchronize_rcu before free'ing map + - bpf: sockmap, only create entry if ulp is not already enabled + - ASoC: dapm: fix a memory leak bug + - bonding: Force slave speed check after link state recovery for 802.3ad + - can: dev: call netif_carrier_off() in register_candev() + - ASoC: Fail card instantiation if DAI format setup fails + - st21nfca_connectivity_event_received: null check the allocation + - st_nci_hci_connectivity_event_received: null check the allocation + - {nl,mac}80211: fix interface combinations on crypto controlled devices + - ASoC: ti: davinci-mcasp: Fix clk PDIR handling for i2s master mode + - ASoC: ti: davinci-mcasp: Correct slot_width posed constraint + - net: usb: qmi_wwan: Add the BroadMobi BM818 card + - qed: RDMA - Fix the hw_ver returned in device attributes + - isdn: mISDN: hfcsusb: Fix possible null-pointer dereferences in + start_isoc_chain() + - net: stmmac: manage errors returned by of_get_mac_address() + - netfilter: ipset: Fix rename concurrency with listing + - nvmem: Use the same permissions for eeprom as for nvmem + - iwlwifi: mvm: avoid races in rate init and rate perform + - iwlwifi: dbg_ini: move iwl_dbg_tlv_load_bin out of debug override ifdef + - iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef + - iwlwifi: fix locking in delayed GTK setting + - iwlwifi: mvm: send LQ command always ASYNC + - isdn: hfcsusb: Fix mISDN driver crash caused by transfer buffer on the stack + - perf bench numa: Fix cpu0 binding + - spi: pxa2xx: Add support for Intel Comet Lake + - spi: pxa2xx: Add support for Intel Tiger Lake + - can: sja1000: force the string buffer NULL-terminated + - can: peak_usb: force the string buffer NULL-terminated + - net/ethernet/qlogic/qed: force the string buffer NULL-terminated + - NFSv4: Fix a credential refcount leak in nfs41_check_delegation_stateid + - NFSv4: When recovering state fails with EAGAIN, retry the same recovery + - NFSv4.1: Fix open stateid recovery + - NFSv4.1: Only reap expired delegations + - NFSv4: Fix a potential sleep while atomic in nfs4_do_reclaim() + - HID: input: fix a4tech horizontal wheel custom usage + - SMB3: Kernel oops mounting a encryptData share with CONFIG_DEBUG_VIRTUAL + - sched/deadline: Fix double accounting of rq/running bw in push & pull + - s390/mm: fix dump_pagetables top level page table walking + - ata: rb532_cf: Fix unused variable warning in rb532_pata_driver_probe + - net: cxgb3_main: Fix a resource leak in a error path in 'init_one()' + - drm/amdgpu: pin the csb buffer on hw init for gfx v8 + - net: hisilicon: make hip04_tx_reclaim non-reentrant + - net: hisilicon: fix hip04-xmit never return TX_BUSY + - net: hisilicon: Fix dma_map_single failed on arm64 + - NFSv4: Ensure state recovery handles ETIMEDOUT correctly + - libata: have ata_scsi_rw_xlat() fail invalid passthrough requests + - libata: add SG safety checks in SFF pio transfers + - x86/lib/cpu: Address missing prototypes warning + - drm/vmwgfx: fix memory leak when too many retries have occurred + - block: aoe: Fix kernel crash due to atomic sleep when exiting + - perf ftrace: Fix failure to set cpumask when only one cpu is present + - perf cpumap: Fix writing to illegal memory in handling cpumap mask + - perf pmu-events: Fix missing "cpu_clk_unhalted.core" event + - selftests: kvm: Adding config fragments + - HID: wacom: correct misreported EKR ring values + - HID: wacom: Correct distance scale for 2nd-gen Intuos devices + - Revert "dm bufio: fix deadlock with loop device" + - ceph: don't try fill file_lock on unsuccessful GETFILELOCK reply + - libceph: fix PG split vs OSD (re)connect race + - drm/nouveau: Don't retry infinitely when receiving no data on i2c over AUX + - gpiolib: never report open-drain/source lines as 'input' to user-space + - userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx + - x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386 + - x86/apic: Handle missing global clockevent gracefully + - x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h + - x86/boot: Save fields explicitly, zero out everything else + - x86/boot: Fix boot regression caused by bootparam sanitizing + - dm kcopyd: always complete failed jobs + - dm btree: fix order of block initialization in btree_split_beneath + - dm space map metadata: fix missing store of apply_bops() return value + - dm table: fix invalid memory accesses with too high sector number + - dm zoned: improve error handling in reclaim + - dm zoned: improve error handling in i/o map code + - dm zoned: properly handle backing device failure + - genirq: Properly pair kobject_del() with kobject_add() + - mm, page_alloc: move_freepages should not examine struct page of reserved + memory + - mm, page_owner: handle THP splits correctly + - mm/zsmalloc.c: migration can leave pages in ZS_EMPTY indefinitely + - mm/zsmalloc.c: fix race condition in zs_destroy_pool + - mm/kasan: fix false positive invalid-free reports with + CONFIG_KASAN_SW_TAGS=y + - xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT + - dm zoned: fix potential NULL dereference in dmz_do_reclaim() + - powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB + * Disco update: upstream stable patchset 2019-08-29 (LP: #1841994) + - scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure + - gcc-9: don't warn about uninitialized variable + - driver core: Establish order of operations for device_add and device_del via + bitflag + - drivers/base: Introduce kill_device() + - libnvdimm/bus: Prevent duplicate device_unregister() calls + - libnvdimm/bus: Prepare the nd_ioctl() path to be re-entrant + - libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA deadlock + - HID: wacom: fix bit shift for Cintiq Companion 2 + - HID: Add quirk for HP X1200 PIXART OEM mouse + - atm: iphase: Fix Spectre v1 vulnerability + - bnx2x: Disable multi-cos feature. + - ife: error out when nla attributes are empty + - ip6_gre: reload ipv6h in prepare_ip6gre_xmit_ipv6 + - ip6_tunnel: fix possible use-after-free on xmit + - ipip: validate header length in ipip_tunnel_xmit + - mlxsw: spectrum: Fix error path in mlxsw_sp_module_init() + - mvpp2: fix panic on module removal + - mvpp2: refactor MTU change code + - net: bridge: delete local fdb on device init failure + - net: bridge: mcast: don't delete permanent entries when fast leave is + enabled + - net: fix ifindex collision during namespace removal + - net/mlx5e: always initialize frag->last_in_page + - net/mlx5: Use reversed order when unregister devices + - net: phylink: Fix flow control for fixed-link + - net: qualcomm: rmnet: Fix incorrect UL checksum offload logic + - net: sched: Fix a possible null-pointer dereference in dequeue_func() + - net sched: update vlan action for batched events operations + - net: sched: use temporary variable for actions indexes + - net/smc: do not schedule tx_work in SMC_CLOSED state + - NFC: nfcmrvl: fix gpio-handling regression + - ocelot: Cancel delayed work before wq destruction + - tipc: compat: allow tipc commands without arguments + - tun: mark small packets as owned by the tap sock + - net/mlx5: Fix modify_cq_in alignment + - net/mlx5e: Prevent encap flow counter update async to user query + - r8169: don't use MSI before RTL8168d + - compat_ioctl: pppoe: fix PPPOEIOCSFWD handling + - cgroup: Call cgroup_release() before __exit_signal() + - cgroup: Implement css_task_iter_skip() + - cgroup: Include dying leaders with live threads in PROCS iterations + - cgroup: css_task_iter_skip()'d iterators must be advanced before accessed + - cgroup: Fix css_task_iter_advance_css_set() cset skip condition + - spi: bcm2835: Fix 3-wire mode if DMA is enabled + - ALSA: usb-audio: Sanity checks for each pipe and EP types + - ALSA: usb-audio: Fix gpf in snd_usb_pipe_sanity_check + - drivers/net/ethernet/marvell/mvmdio.c: Fix non OF case + - net: phylink: don't start and stop SGMII PHYs in SFP modules twice + - net: phy: mscc: initialize stats array + - bpf: fix XDP vlan selftests test_xdp_vlan.sh + - selftests/bpf: add wrapper scripts for test_xdp_vlan.sh + - selftests/bpf: reduce time to execute test_xdp_vlan.sh + - net: fix bpf_xdp_adjust_head regression for generic-XDP + - hv_sock: Fix hang when a connection is closed + - iio: cros_ec_accel_legacy: Fix incorrect channel setting + - iio: adc: max9611: Fix misuse of GENMASK macro + - staging: gasket: apex: fix copy-paste typo + - staging: android: ion: Bail out upon SIGKILL when allocating memory. + - crypto: ccp - Fix oops by properly managing allocated structures + - crypto: ccp - Add support for valid authsize values less than 16 + - crypto: ccp - Ignore tag length when decrypting GCM ciphertext + - usb: usbfs: fix double-free of usb memory upon submiturb error + - usb: iowarrior: fix deadlock on disconnect + - sound: fix a memory leak bug + - mmc: cavium: Set the correct dma max segment size for mmc_host + - mmc: cavium: Add the missing dma unmap when the dma has finished. + - loop: set PF_MEMALLOC_NOIO for the worker thread + - Input: usbtouchscreen - initialize PM mutex before using it + - Input: elantech - enable SMBus on new (2018+) systems + - Input: synaptics - enable RMI mode for HP Spectre X360 + - perf annotate: Fix s390 gap between kernel end and module start + - perf db-export: Fix thread__exec_comm() + - perf record: Fix module size on s390 + - x86/purgatory: Use CFLAGS_REMOVE rather than reset KBUILD_CFLAGS + - gfs2: gfs2_walk_metadata fix + - usb: host: xhci-rcar: Fix timeout in xhci_suspend() + - usb: yurex: Fix use-after-free in yurex_delete + - usb: typec: tcpm: free log buf memory when remove debug file + - usb: typec: tcpm: remove tcpm dir if no children + - usb: typec: tcpm: Add NULL check before dereferencing config + - usb: typec: tcpm: Ignore unsupported/unknown alternate mode requests + - can: rcar_canfd: fix possible IRQ storm on high load + - can: peak_usb: fix potential double kfree_skb() + - netfilter: nfnetlink: avoid deadlock due to synchronous request_module + - vfio-ccw: Set pa_nr to 0 if memory allocation fails for pa_iova_pfn + - netfilter: Fix rpfilter dropping vrf packets by mistake + - netfilter: conntrack: always store window size un-scaled + - netfilter: nft_hash: fix symhash with modulus one + - scripts/sphinx-pre-install: fix script for RHEL/CentOS + - drm/amd/display: Wait for backlight programming completion in set backlight + level + - drm/amd/display: use encoder's engine id to find matched free audio device + - drm/amd/display: Fix dc_create failure handling and 666 color depths + - drm/amd/display: Only enable audio if speaker allocation exists + - drm/amd/display: Increase size of audios array + - iscsi_ibft: make ISCSI_IBFT dependson ACPI instead of ISCSI_IBFT_FIND + - nl80211: fix NL80211_HE_MAX_CAPABILITY_LEN + - mac80211: don't warn about CW params when not using them + - allocate_flower_entry: should check for null deref + - hwmon: (nct6775) Fix register address and added missed tolerance for nct6106 + - drm: silence variable 'conn' set but not used + - cpufreq/pasemi: fix use-after-free in pas_cpufreq_cpu_init() + - s390/qdio: add sanity checks to the fast-requeue path + - ALSA: compress: Fix regression on compressed capture streams + - ALSA: compress: Prevent bypasses of set_params + - ALSA: compress: Don't allow paritial drain operations on capture streams + - ALSA: compress: Be more restrictive about when a drain is allowed + - perf tools: Fix proper buffer size for feature processing + - perf probe: Avoid calling freeing routine multiple times for same pointer + - drbd: dynamically allocate shash descriptor + - ACPI/IORT: Fix off-by-one check in iort_dev_find_its_id() + - ARM: davinci: fix sleep.S build error on ARMv4 + - ARM: dts: bcm: bcm47094: add missing #cells for mdio-bus-mux + - scsi: megaraid_sas: fix panic on loading firmware crashdump + - scsi: ibmvfc: fix WARN_ON during event pool release + - scsi: scsi_dh_alua: always use a 2 second delay before retrying RTPG + - test_firmware: fix a memory leak bug + - tty/ldsem, locking/rwsem: Add missing ACQUIRE to read_failed sleep loop + - perf/core: Fix creating kernel counters for PMUs that override event->cpu + - s390/dma: provide proper ARCH_ZONE_DMA_BITS value + - HID: sony: Fix race condition between rumble and device remove. + - x86/purgatory: Do not use __builtin_memcpy and __builtin_memset + - ALSA: usb-audio: fix a memory leak bug + - can: peak_usb: pcan_usb_pro: Fix info-leaks to USB devices + - can: peak_usb: pcan_usb_fd: Fix info-leaks to USB devices + - hwmon: (nct7802) Fix wrong detection of in4 presence + - drm/i915: Fix wrong escape clock divisor init for GLK + - ALSA: firewire: fix a memory leak bug + - ALSA: hiface: fix multiple memory leak bugs + - ALSA: hda - Don't override global PCM hw info flag + - ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457) + - mac80211: don't WARN on short WMM parameters from AP + - dax: dax_layout_busy_page() should not unmap cow pages + - SMB3: Fix deadlock in validate negotiate hits reconnect + - smb3: send CAP_DFS capability during session setup + - NFSv4: Fix an Oops in nfs4_do_setattr + - KVM: Fix leak vCPU's VMCS value into other pCPU + - mwifiex: fix 802.11n/WPA detection + - iwlwifi: don't unmap as page memory that was mapped as single + - iwlwifi: mvm: fix an out-of-bound access + - iwlwifi: mvm: don't send GEO_TX_POWER_LIMIT on version < 41 + - iwlwifi: mvm: fix version check for GEO_TX_POWER_LIMIT support + - iio: adc: gyroadc: fix uninitialized return code + - staging: wilc1000: flush the workqueue before deinit the host + - can: flexcan: fix stop mode acknowledgment + - can: flexcan: fix an use-after-free in flexcan_setup_stop_mode() + - powerpc: fix off by one in max_zone_pfn initialization for ZONE_DMA + - scripts/sphinx-pre-install: don't use LaTeX with CentOS 7 + - rq-qos: don't reset has_sleepers on spurious wakeups + - rq-qos: set ourself TASK_UNINTERRUPTIBLE after we schedule + - rq-qos: use a mb for got_token + - drm/amd/display: Clock does not lower in Updateplanes + - drm/amd/display: fix DMCU hang when going into Modern Standby + - drm/amd/display: allocate 4 ddc engines for RV2 + - mac80211: fix possible memory leak in ieee80211_assign_beacon + - hwmon: (occ) Fix division by zero issue + - ARM: dts: imx6ul: fix clock frequency property name of I2C buses + - powerpc/papr_scm: Force a scm-unbind if initial scm-bind fails + - arm64: Force SSBS on context switch + - arm64: entry: SP Alignment Fault doesn't write to FAR_EL1 + - drm/msm/dpu: Correct dpu encoder spinlock initialization + - perf script: Fix off by one in brstackinsn IPC computation + - perf stat: Fix segfault for event group in repeat mode + - nvme: ignore subnqn for ADATA SX6000LNP + - nvme: fix memory leak caused by incorrect subsystem free + - perf/x86: Apply more accurate check on hypervisor platform + - gen_compile_commands: lower the entry count threshold + - NFSv4: Fix delegation state recovery + - NFSv4: Check the return value of update_open_stateid() + - KVM: arm/arm64: Sync ICH_VMCR_EL2 back when about to block + - iwlwifi: mvm: fix a use-after-free bug in iwl_mvm_tx_tso_segment + - sh: kernel: hw_breakpoint: Fix missing break in switch statement + - seq_file: fix problem when seeking mid-record + - mm/hmm: fix bad subpage pointer in try_to_unmap_one + - mm: mempolicy: make the behavior consistent when MPOL_MF_MOVE* and + MPOL_MF_STRICT were specified + - mm: mempolicy: handle vma with unmovable pages mapped correctly in mbind + - mm/memcontrol.c: fix use after free in mem_cgroup_iter() + - mm/usercopy: use memory range to be accessed for wraparound check + - cpufreq: schedutil: Don't skip freq update when limits change + - xtensa: add missing isync to the cpu_reset TLB code + - ALSA: hda/realtek - Add quirk for HP Envy x360 + - ALSA: usb-audio: Fix a stack buffer overflow bug in check_input_term + - ALSA: usb-audio: Fix an OOB bug in parse_audio_mixer_unit + - ALSA: hda - Apply workaround for another AMD chip 1022:1487 + - ALSA: hda - Fix a memory leak bug + - HID: holtek: test for sanity of intfdata + - HID: hiddev: avoid opening a disconnected device + - HID: hiddev: do cleanup in failure of opening a device + - Input: kbtab - sanity check for endpoint type + - Input: iforce - add sanity checks + - net: usb: pegasus: fix improper read if get_registers() fail + - netfilter: ebtables: also count base chain policies + - riscv: Make __fstate_clean() work correctly. + - clk: at91: generated: Truncate divisor to GENERATED_MAX_DIV + 1 + - clk: sprd: Select REGMAP_MMIO to avoid compile errors + - clk: renesas: cpg-mssr: Fix reset control race condition + - xen/pciback: remove set but not used variable 'old_state' + - irqchip/gic-v3-its: Free unused vpt_page when alloc vpe table fail + - irqchip/irq-imx-gpcv2: Forward irq type to parent + - perf header: Fix divide by zero error if f_header.attr_size==0 + - perf header: Fix use of unitialized value warning + - libata: zpodd: Fix small read overflow in zpodd_get_mech_type() + - drm/bridge: lvds-encoder: Fix build error while CONFIG_DRM_KMS_HELPER=m + - Btrfs: fix deadlock between fiemap and transaction commits + - scsi: hpsa: correct scsi command status issue after reset + - scsi: qla2xxx: Fix possible fcport null-pointer dereferences + - drm/amdgpu: fix a potential information leaking bug + - ata: libahci: do not complain in case of deferred probe + - kbuild: modpost: handle KBUILD_EXTRA_SYMBOLS only for external modules + - kbuild: Check for unknown options with cc-option usage in Kconfig and clang + - arm64/efi: fix variable 'si' set but not used + - arm64: unwind: Prohibit probing on return_address() + - arm64/mm: fix variable 'pud' set but not used + - IB/core: Add mitigation for Spectre V1 + - IB/mlx5: Fix MR registration flow to use UMR properly + - IB/mad: Fix use-after-free in ib mad completion handling + - drm: msm: Fix add_gpu_components + - drm/exynos: fix missing decrement of retry counter + - Revert "kmemleak: allow to coexist with fault injection" + - ocfs2: remove set but not used variable 'last_hash' + - asm-generic: fix -Wtype-limits compiler warnings + - arm64: KVM: regmap: Fix unexpected switch fall-through + - staging: comedi: dt3000: Fix signed integer overflow 'divider * base' + - staging: comedi: dt3000: Fix rounding up of timer divisor + - iio: adc: max9611: Fix temperature reading in probe + - USB: core: Fix races in character device registration and deregistraion + - usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role" + - usb: cdc-acm: make sure a refcount is taken early enough + - USB: CDC: fix sanity checks in CDC union parser + - USB: serial: option: add D-Link DWM-222 device ID + - USB: serial: option: Add support for ZTE MF871A + - USB: serial: option: add the BroadMobi BM818 card + - USB: serial: option: Add Motorola modem UARTs + - arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side + - netfilter: conntrack: Use consistent ct id hash calculation + - Input: psmouse - fix build error of multiple definition + - bnx2x: Fix VF's VLAN reconfiguration in reload. + - bonding: Add vlan tx offload to hw_enc_features + - net: dsa: Check existence of .port_mdb_add callback before calling it + - net/mlx4_en: fix a memory leak bug + - net/packet: fix race in tpacket_snd() + - sctp: fix memleak in sctp_send_reset_streams + - sctp: fix the transport error_count check + - team: Add vlan tx offload to hw_enc_features + - tipc: initialise addr_trail_end when setting node addresses + - xen/netback: Reset nr_frags before freeing skb + - net/mlx5e: Only support tx/rx pause setting for port owner + - net/mlx5e: Use flow keys dissector to parse packets for ARFS + - mm/z3fold.c: fix z3fold_destroy_pool() ordering + - mm, vmscan: do not special-case slab reclaim when watermarks are boosted + - drm/amdgpu: fix gfx9 soft recovery + - riscv: Correct the initialized flow of FP register + - blk-mq: move cancel of requeue_work to the front of blk_exit_queue + - IB/mlx5: Replace kfree with kvfree + - dma-mapping: check pfn validity in dma_common_{mmap,get_sgtable} + - f2fs: fix to read source block before invalidating it + - tools perf beauty: Fix usbdevfs_ioctl table generator to handle _IOC() + - ALSA: pcm: fix lost wakeup event scenarios in snd_pcm_drain + - drm/bridge: tc358764: Fix build error + - tracing: Fix header include guards in trace event headers + - drm/amdkfd: Fix byte align on VegaM + - RDMA/restrack: Track driver QP types in resource tracker + - RDMA/mlx5: Release locks during notifier unregister + - arm64: kprobes: Recover pstate.D in single-step exception handler + - arm64: Make debug exception handlers visible from RCU + - page flags: prioritize kasan bits over last-cpuid + - bnxt_en: Fix VNIC clearing logic for 57500 chips. + - bnxt_en: Improve RX doorbell sequence. + - bnxt_en: Fix handling FRAG_ERR when NVM_INSTALL_UPDATE cmd fails + - bnxt_en: Suppress HWRM errors for HWRM_NVM_GET_VARIABLE command + - bnxt_en: Use correct src_fid to determine direction of the flow + - bnxt_en: Fix to include flow direction in L2 key + - net sched: update skbedit action for batched events operations + - tc-testing: updated skbedit action tests with batch create/delete + * Disco update: upstream stable patchset 2019-08-27 (LP: #1841681) + - hv_sock: Add support for delayed close + - vsock: correct removal of socket from the list + - ISDN: hfcsusb: checking idx of ep configuration + - media: au0828: fix null dereference in error path + - ath10k: Change the warning message string + - media: cpia2_usb: first wake up, then free in disconnect + - media: pvrusb2: use a different format for warnings + - NFS: Cleanup if nfs_match_client is interrupted + - media: radio-raremono: change devm_k*alloc to k*alloc + - Bluetooth: hci_uart: check for missing tty operations + - sched/fair: Don't free p->numa_faults with concurrent readers + - sched/fair: Use RCU accessors consistently for ->numa_group + - /proc//cmdline: remove all the special cases + - /proc//cmdline: add back the setproctitle() special case + - drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl + - Fix allyesconfig output. + - ceph: hold i_ceph_lock when removing caps for freeing inode + - ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL + - xfrm: policy: fix bydst hlist corruption on hash rebuild + - nvme: fix multipath crash when ANA is deactivated + - ARM: riscpc: fix DMA + - ARM: dts: rockchip: Make rk3288-veyron-minnie run at hs200 + - ARM: dts: rockchip: Make rk3288-veyron-mickey's emmc work again + - ARM: dts: rockchip: Mark that the rk3288 timer might stop in suspend + - ftrace: Enable trampoline when rec count returns back to one + - dmaengine: tegra-apb: Error out if DMA_PREP_INTERRUPT flag is unset + - arm64: dts: rockchip: fix isp iommu clocks and power domain + - kernel/module.c: Only return -EEXIST for modules that have finished loading + - firmware/psci: psci_checker: Park kthreads before stopping them + - MIPS: lantiq: Fix bitfield masking + - dmaengine: rcar-dmac: Reject zero-length slave DMA requests + - clk: tegra210: fix PLLU and PLLU_OUT1 + - fs/adfs: super: fix use-after-free bug + - clk: sprd: Add check for return value of sprd_clk_regmap_init() + - btrfs: fix minimum number of chunk errors for DUP + - btrfs: qgroup: Don't hold qgroup_ioctl_lock in btrfs_qgroup_inherit() + - cifs: Fix a race condition with cifs_echo_request + - ceph: fix improper use of smp_mb__before_atomic() + - ceph: return -ERANGE if virtual xattr value didn't fit in buffer + - ACPI: blacklist: fix clang warning for unused DMI table + - scsi: zfcp: fix GCC compiler warning emitted with -Wmaybe-uninitialized + - perf version: Fix segfault due to missing OPT_END() + - x86: kvm: avoid constant-conversion warning + - ACPI: fix false-positive -Wuninitialized warning + - be2net: Signal that the device cannot transmit during reconfiguration + - x86/apic: Silence -Wtype-limits compiler warnings + - x86: math-emu: Hide clang warnings for 16-bit overflow + - mm/cma.c: fail if fixed declaration can't be honored + - lib/test_overflow.c: avoid tainting the kernel and fix wrap size + - lib/test_string.c: avoid masking memset16/32/64 failures + - coda: add error handling for fget + - coda: fix build using bare-metal toolchain + - uapi linux/coda_psdev.h: move upc_req definition from uapi to kernel side + headers + - drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings + - ipc/mqueue.c: only perform resource calculation if user valid + - xen/pv: Fix a boot up hang revealed by int3 self test + - x86/kvm: Don't call kvm_spurious_fault() from .fixup + - x86/paravirt: Fix callee-saved function ELF sizes + - x86, boot: Remove multiple copy of static function sanitize_boot_params() + - drm/nouveau: fix memory leak in nouveau_conn_reset() + - kconfig: Clear "written" flag to avoid data loss + - kbuild: initialize CLANG_FLAGS correctly in the top Makefile + - Btrfs: fix incremental send failure after deduplication + - Btrfs: fix race leading to fs corruption after transaction abort + - mmc: dw_mmc: Fix occasional hang after tuning on eMMC + - mmc: meson-mx-sdio: Fix misuse of GENMASK macro + - gpiolib: fix incorrect IRQ requesting of an active-low lineevent + - IB/hfi1: Fix Spectre v1 vulnerability + - mtd: rawnand: micron: handle on-die "ECC-off" devices correctly + - selinux: fix memory leak in policydb_init() + - ALSA: hda: Fix 1-minute detection delay when i915 module is not available + - mm: vmscan: check if mem cgroup is disabled or not before calling memcg slab + shrinker + - s390/dasd: fix endless loop after read unit address configuration + - cgroup: kselftest: relax fs_spec checks + - parisc: Fix build of compressed kernel even with debug enabled + - drivers/perf: arm_pmu: Fix failure path in PM notifier + - arm64: compat: Allow single-byte watchpoints on all addresses + - arm64: cpufeature: Fix feature comparison for CTR_EL0.{CWG,ERG} + - nbd: replace kill_bdev() with __invalidate_device() again + - xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() + - IB/mlx5: Fix unreg_umr to ignore the mkey state + - IB/mlx5: Use direct mkey destroy command upon UMR unreg failure + - IB/mlx5: Move MRs to a kernel PD when freeing them to the MR cache + - IB/mlx5: Fix clean_mr() to work in the expected order + - IB/mlx5: Fix RSS Toeplitz setup to be aligned with the HW specification + - IB/hfi1: Check for error on call to alloc_rsm_map_table + - drm/i915/gvt: fix incorrect cache entry for guest page mapping + - eeprom: at24: make spd world-readable again + - gcc-9: properly declare the {pv,hv}clock_page storage + - scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA + - Documentation: Add swapgs description to the Spectre v1 documentation + - arm64: dts: marvell: mcbin: enlarge PCI memory window + - PCI: OF: Initialize dev->fwnode appropriately + - arm64: qcom: qcs404: Add reset-cells to GCC node + - swiotlb: fix phys_addr_t overflow warning + - arm64: dts: rockchip: Fix USB3 Type-C on rk3399-sapphire + - btrfs: Flush before reflinking any extent to prevent NOCOW write falling + back to COW without data reservation + - virtio-mmio: add error check for platform_get_irq + - cifs: fix crash in cifs_dfs_do_automount + - KVM: nVMX: Ignore segment base for VMX memory operand when segment not FS or + GS + - bpf: fix BTF verifier size resolution logic + - mm/slab_common.c: work around clang bug #42570 + - mm/ioremap: check virtual address alignment while creating huge mappings + - nds32: fix asm/syscall.h + - mm/hotplug: make remove_memory() interface usable + - crypto: ccp - Fix SEV_VERSION_GREATER_OR_EQUAL + - bpf: Disable GCC -fgcse optimization for ___bpf_prog_run() + - kbuild: modpost: include .*.cmd files only when targets exist + - dax: Fix missed wakeup in put_unlocked_entry() + - fgraph: Remove redundant ftrace_graph_notrace_addr() test + - mmc: host: sdhci-sprd: Fix the missing pm_runtime_put_noidle() + - mmc: mmc_spi: Enable stable writes + - gpiolib: Preserve desc->flags when setting state + - gpio: don't WARN() on NULL descs if gpiolib is disabled + - i2c: at91: disable TXRDY interrupt after sending data + - i2c: at91: fix clk_offset for sama5d2 + - mm: migrate: fix reference check race between __find_get_block() and + migration + - mm/migrate.c: initialize pud_entry in migrate_vma() + - parisc: Add archclean Makefile target + - parisc: Strip debug info from kernel before creating compressed vmlinuz + - RDMA/bnxt_re: Honor vlan_id in GID entry comparison + - drm/i915/perf: fix ICL perf register offsets + * Disco update: upstream stable patchset 2019-08-22 (LP: #1841121) + - hvsock: fix epollout hang from race condition + - drm/panel: simple: Fix panel_simple_dsi_probe + - iio: adc: stm32-dfsdm: manage the get_irq error case + - iio: adc: stm32-dfsdm: missing error case during probe + - staging: vt6656: use meaningful error code during buffer allocation + - usb: core: hub: Disable hub-initiated U1/U2 + - tty: max310x: Fix invalid baudrate divisors calculator + - pinctrl: rockchip: fix leaked of_node references + - tty: serial: cpm_uart - fix init when SMC is relocated + - drm/amd/display: Fill prescale_params->scale for RGB565 + - drm/amdgpu/sriov: Need to initialize the HDP_NONSURFACE_BAStE + - drm/amd/display: Disable ABM before destroy ABM struct + - drm/amdkfd: Fix a potential memory leak + - drm/amdkfd: Fix sdma queue map issue + - drm/edid: Fix a missing-check bug in drm_load_edid_firmware() + - PCI: Return error if cannot probe VF + - drm/bridge: tc358767: read display_props in get_modes() + - drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz + - gpu: host1x: Increase maximum DMA segment size + - drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry + - drm/crc-debugfs: Also sprinkle irqrestore over early exits + - memstick: Fix error cleanup path of memstick_init + - tty/serial: digicolor: Fix digicolor-usart already registered warning + - tty: serial: msm_serial: avoid system lockup condition + - serial: 8250: Fix TX interrupt handling condition + - drm/amd/display: Always allocate initial connector state state + - drm/virtio: Add memory barriers for capset cache. + - phy: renesas: rcar-gen2: Fix memory leak at error paths + - drm/amd/display: fix compilation error + - powerpc/pseries/mobility: prevent cpu hotplug during DT update + - drm/rockchip: Properly adjust to a true clock in adjusted_mode + - serial: imx: fix locking in set_termios() + - tty: serial_core: Set port active bit in uart_port_activate + - usb: gadget: Zero ffs_io_data + - mmc: sdhci: sdhci-pci-o2micro: Check if controller supports 8-bit width + - powerpc/pci/of: Fix OF flags parsing for 64bit BARs + - drm/msm: Depopulate platform on probe failure + - serial: mctrl_gpio: Check if GPIO property exisits before requesting it + - PCI: sysfs: Ignore lockdep for remove attribute + - i2c: stm32f7: fix the get_irq error cases + - kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS + - genksyms: Teach parser about 128-bit built-in types + - PCI: xilinx-nwl: Fix Multi MSI data programming + - iio: iio-utils: Fix possible incorrect mask calculation + - powerpc/cacheflush: fix variable set but not used + - powerpc/xmon: Fix disabling tracing while in xmon + - recordmcount: Fix spurious mcount entries on powerpc + - mfd: madera: Add missing of table registration + - mfd: core: Set fwnode for created devices + - mfd: arizona: Fix undefined behavior + - mfd: hi655x-pmic: Fix missing return value check for + devm_regmap_init_mmio_clk + - mm/swap: fix release_pages() when releasing devmap pages + - um: Silence lockdep complaint about mmap_sem + - powerpc/4xx/uic: clear pending interrupt after irq type/pol change + - RDMA/i40iw: Set queue pair state when being queried + - serial: sh-sci: Terminate TX DMA during buffer flushing + - serial: sh-sci: Fix TX DMA buffer flushing and workqueue races + - IB/mlx5: Fixed reporting counters on 2nd port for Dual port RoCE + - powerpc/mm: Handle page table allocation failures + - IB/ipoib: Add child to parent list only if device initialized + - arm64: assembler: Switch ESB-instruction with a vanilla nop if + !ARM64_HAS_RAS + - PCI: mobiveil: Fix PCI base address in MEM/IO outbound windows + - PCI: mobiveil: Fix the Class Code field + - kallsyms: exclude kasan local symbols on s390 + - PCI: mobiveil: Initialize Primary/Secondary/Subordinate bus numbers + - PCI: mobiveil: Use the 1st inbound window for MEM inbound transactions + - perf test mmap-thread-lookup: Initialize variable to suppress memory + sanitizer warning + - perf stat: Fix use-after-freed pointer detected by the smatch tool + - perf top: Fix potential NULL pointer dereference detected by the smatch tool + - perf session: Fix potential NULL pointer dereference found by the smatch + tool + - perf annotate: Fix dereferencing freed memory found by the smatch tool + - perf hists browser: Fix potential NULL pointer dereference found by the + smatch tool + - RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM + - PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB + - powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h + - block: init flush rq ref count to 1 + - f2fs: avoid out-of-range memory access + - mailbox: handle failed named mailbox channel request + - dlm: check if workqueues are NULL before flushing/destroying + - powerpc/eeh: Handle hugepages in ioremap space + - block/bio-integrity: fix a memory leak bug + - sh: prevent warnings when using iounmap + - mm/kmemleak.c: fix check for softirq context + - 9p: pass the correct prototype to read_cache_page + - mm/gup.c: mark undo_dev_pagemap as __maybe_unused + - mm/gup.c: remove some BUG_ONs from get_gate_page() + - memcg, fsnotify: no oom-kill for remote memcg charging + - mm/mmu_notifier: use hlist_add_head_rcu() + - proc: use down_read_killable mmap_sem for /proc/pid/smaps_rollup + - proc: use down_read_killable mmap_sem for /proc/pid/pagemap + - proc: use down_read_killable mmap_sem for /proc/pid/clear_refs + - proc: use down_read_killable mmap_sem for /proc/pid/map_files + - cxgb4: reduce kernel stack usage in cudbg_collect_mem_region() + - proc: use down_read_killable mmap_sem for /proc/pid/maps + - locking/lockdep: Fix lock used or unused stats error + - mm: use down_read_killable for locking mmap_sem in access_remote_vm + - locking/lockdep: Hide unused 'class' variable + - usb: wusbcore: fix unbalanced get/put cluster_id + - usb: pci-quirks: Correct AMD PLL quirk detection + - btrfs: inode: Don't compress if NODATASUM or NODATACOW set + - x86/sysfb_efi: Add quirks for some devices with swapped width and height + - x86/speculation/mds: Apply more accurate check on hypervisor platform + - binder: prevent transactions to context manager from its own process. + - fpga-manager: altera-ps-spi: Fix build error + - mei: me: add mule creek canyon (EHL) device ids + - hpet: Fix division by zero in hpet_time_div() + - ALSA: ac97: Fix double free of ac97_codec_device + - powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask() + - libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl() + - access: avoid the RCU grace period for the temporary subjective credentials + - regulator: 88pm800: fix warning same module names + - media: drivers: media: coda: fix warning same module names + - btrfs: shut up bogus -Wmaybe-uninitialized warning + - drm/virtio: set seqno for dma-fence + - ipmi_si: fix unexpected driver unregister warning + - drm/bochs: Fix connector leak during driver unload + - drm/msm/a6xx: Check for ERR or NULL before iounmap + - ipmi:ssif: Only unregister the platform driver if it was registered + - ipmi_ssif: fix unexpected driver unregister warning + - drm/amd/display: Disable cursor when offscreen in negative direction + - drm/amdgpu: Reserve shared fence for eviction fence + - f2fs: fix to avoid deadloop if data_flush is on + - tools: PCI: Fix broken pcitest compilation + - drm/amd/display: Increase Backlight Gain Step Size + - f2fs: Fix accounting for unusable blocks + - f2fs: Lower threshold for disable_cp_again + - drm/vkms: Forward timer right after drm_crtc_handle_vblank + - i2c: nvidia-gpu: resume ccgx i2c client + - PCI: endpoint: Allocate enough space for fixed size BAR + - dma-remap: Avoid de-referencing NULL atomic_pool + - platform/x86: asus-wmi: Increase input buffer size of WMI methods + - iio: adxl372: fix iio_triggered_buffer_{pre,post}enable positions + - serial: uartps: Use the same dynamic major number for all ports + - kvm: vmx: fix limit checking in get_vmx_mem_address() + - KVM: nVMX: Intercept VMWRITEs to GUEST_{CS,SS}_AR_BYTES + - kvm: vmx: segment limit check: use access length + - powerpc/rtas: retry when cpu offline races with suspend/migration + - fixdep: check return value of printf() and putchar() + - KVM: nVMX: Stash L1's CR3 in vmcs01.GUEST_CR3 on nested entry w/o EPT + - perf trace: Fix potential NULL pointer dereference found by the smatch tool + - perf map: Fix potential NULL pointer dereference found by smatch tool + - perf intel-bts: Fix potential NULL pointer dereference found by the smatch + tool + - RDMA/core: Fix race when resolving IP address + - nvme-pci: check for NULL return from pci_alloc_p2pmem() + - nvme-pci: limit max_hw_sectors based on the DMA max mapping size + - nvme-tcp: don't use sendpage for SLAB pages + - nvme-tcp: set the STABLE_WRITES flag when data digests are enabled + - powerpc/irq: Don't WARN continuously in arch_local_irq_restore() + - nvme: fix NULL deref for fabrics options + - mm/mincore.c: fix race between swapoff and mincore + - mm, swap: fix race between swapoff and some swap operations + - usb-storage: Add a limitation for blk_queue_max_hw_sectors() + - KVM: PPC: Book3S HV: Always save guest pmu for guest capable of nesting + - KVM: PPC: Book3S HV: Save and restore guest visible PSSCR bits on pseries + - selinux: check sidtab limit before adding a new entry + - x86/stacktrace: Prevent access_ok() warnings in arch_stack_walk_user() + - eeprom: make older eeprom drivers select NVMEM_SYSFS + - drm/panel: Add support for Armadeus ST0700 Adapt + - ALSA: hda - Fix intermittent CORB/RIRB stall on Intel chips + - powerpc/mm: Limit rma_size to 1TB when running without HV mode + - powerpc/pmu: Set pmcregs_in_use in paca when running as LPAR + - iommu/vt-d: Don't queue_iova() if there is no flush queue + - iommu/iova: Remove stale cached32_node + - iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA + - libnvdimm/region: Register badblocks before namespaces + * Line 6 POD HD500 driver fault (LP: #1790595) // Disco update: upstream + stable patchset 2019-08-22 (LP: #1841121) + - ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1 + * Disco update: upstream stable patchset 2019-08-21 (LP: #1840961) + - bnx2x: Prevent load reordering in tx completion processing + - caif-hsi: fix possible deadlock in cfhsi_exit_module() + - hv_netvsc: Fix extra rcu_read_unlock in netvsc_recv_callback() + - igmp: fix memory leak in igmpv3_del_delrec() + - ipv4: don't set IPv6 only flags to IPv4 addresses + - ipv6: rt6_check should return NULL if 'from' is NULL + - ipv6: Unlink sibling route in case of failure + - net: bcmgenet: use promisc for unsupported filters + - net: dsa: mv88e6xxx: wait after reset deactivation + - net: make skb_dst_force return true when dst is refcounted + - net: neigh: fix multiple neigh timer scheduling + - net: openvswitch: fix csum updates for MPLS actions + - net: phy: sfp: hwmon: Fix scaling of RX power + - net: stmmac: Re-work the queue selection for TSO packets + - nfc: fix potential illegal memory access + - r8169: fix issue with confused RX unit after PHY power-down on RTL8411b + - rxrpc: Fix send on a connected, but unbound socket + - sctp: fix error handling on stream scheduler initialization + - sky2: Disable MSI on ASUS P6T + - tcp: be more careful in tcp_fragment() + - tcp: fix tcp_set_congestion_control() use from bpf hook + - tcp: Reset bytes_acked and bytes_received when disconnecting + - vrf: make sure skb->data contains ip header to make routing + - net/mlx5e: IPoIB, Add error path in mlx5_rdma_setup_rn + - macsec: fix use-after-free of skb during RX + - macsec: fix checksumming after decryption + - netrom: fix a memory leak in nr_rx_frame() + - netrom: hold sock when setting skb->destructor + - net_sched: unset TCQ_F_CAN_BYPASS when adding filters + - net/tls: make sure offload also gets the keys wiped + - sctp: not bind the socket in sctp_connect + - net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling + - net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query + - net: bridge: don't cache ether dest pointer on input + - net: bridge: stp: don't cache eth dest pointer before skb pull + - dma-buf: balance refcount inbalance + - dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc + - gpio: davinci: silence error prints in case of EPROBE_DEFER + - MIPS: lb60: Fix pin mappings + - perf/core: Fix exclusive events' grouping + - perf/core: Fix race between close() and fork() + - ext4: don't allow any modifications to an immutable file + - ext4: enforce the immutable flag on open files + - mm: add filemap_fdatawait_range_keep_errors() + - jbd2: introduce jbd2_inode dirty range scoping + - ext4: use jbd2_inode dirty range scoping + - ext4: allow directory holes + - KVM: nVMX: do not use dangling shadow VMCS after guest reset + - KVM: nVMX: Clear pending KVM_REQ_GET_VMCS12_PAGES when leaving nested + - mm: vmscan: scan anonymous pages on file refaults + - net: sched: verify that q!=NULL before setting q->flags + - selftests: txring_overwrite: fix incorrect test of mmap() return value + - net/tls: reject offload of TLS 1.3 + - net/mlx5e: Rx, Fix checksum calculation for new hardware + - gpiolib: of: fix a memory leak in of_gpio_flags_quirks() + - sd_zbc: Fix report zones buffer allocation + - block: Limit zone array allocation size + - bnxt_en: Fix VNIC accounting when enabling aRFS on 57500 chips. + - mlxsw: spectrum_dcb: Configure DSCP map as the last rule is removed + - mlxsw: spectrum: Do not process learned records with a dummy FID + - Revert "kvm: x86: Use task structs fpu field for user" + * Disco update: upstream stable patchset 2019-08-19 (LP: #1840718) + - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections + - Bluetooth: Fix regression with minimum encryption key size alignment + - Bluetooth: Fix faulty expression for minimum encryption key size check + - netfilter: nf_flow_table: ignore DF bit setting + - netfilter: nft_flow_offload: set liberal tracking mode for tcp + - netfilter: nft_flow_offload: don't offload when sequence numbers need + adjustment + - netfilter: nft_flow_offload: IPCB is only valid for ipv4 family + - ASoC : cs4265 : readable register too low + - ASoC: ak4458: add return value for ak4458_probe + - ASoC: soc-pcm: BE dai needs prepare when pause release after resume + - ASoC: ak4458: rstn_control - return a non-zero on error only + - spi: bitbang: Fix NULL pointer dereference in spi_unregister_master + - drm/mediatek: fix unbind functions + - drm/mediatek: unbind components in mtk_drm_unbind() + - drm/mediatek: call drm_atomic_helper_shutdown() when unbinding driver + - drm/mediatek: clear num_pipes when unbind driver + - drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() + - ASoC: max98090: remove 24-bit format support if RJ is 0 + - ASoC: sun4i-i2s: Fix sun8i tx channel offset mask + - ASoC: sun4i-i2s: Add offset to RX channel select + - x86/CPU: Add more Icelake model numbers + - usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i] + - usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC + - ALSA: hdac: fix memory release for SST and SOF drivers + - SoC: rt274: Fix internal jack assignment in set_jack callback + - scsi: hpsa: correct ioaccel2 chaining + - drm: panel-orientation-quirks: Add quirk for GPD pocket2 + - drm: panel-orientation-quirks: Add quirk for GPD MicroPC + - platform/x86: intel-vbtn: Report switch events when event wakes device + - platform/x86: mlx-platform: Fix parent device in i2c-mux-reg device + registration + - platform/mellanox: mlxreg-hotplug: Add devm_free_irq call to remove flow + - i2c: pca-platform: Fix GPIO lookup code + - cpuset: restore sanity to cpuset_cpus_allowed_fallback() + - scripts/decode_stacktrace.sh: prefix addr2line with $CROSS_COMPILE + - mm/mlock.c: change count_mm_mlocked_page_nr return type + - tracing: avoid build warning with HAVE_NOP_MCOUNT + - module: Fix livepatch/ftrace module text permissions race + - ftrace: Fix NULL pointer dereference in free_ftrace_func_mapper() + - crypto: user - prevent operating on larval algorithms + - crypto: cryptd - Fix skcipher instance memory leak + - ALSA: seq: fix incorrect order of dest_client/dest_ports arguments + - ALSA: firewire-lib/fireworks: fix miss detection of received MIDI messages + - ALSA: line6: Fix write on zero-sized buffer + - ALSA: usb-audio: fix sign unintended sign extension on left shifts + - ALSA: hda/realtek: Add quirks for several Clevo notebook barebones + - ALSA: hda/realtek - Change front mic location for Lenovo M710q + - lib/mpi: Fix karactx leak in mpi_powm + - fs/userfaultfd.c: disable irqs for fault_pending and event locks + - tracing/snapshot: Resize spare buffer if size changed + - ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node + - arm64: kaslr: keep modules inside module region when KASAN is enabled + - drm/amd/powerplay: use hardware fan control if no powerplay fan table + - drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE + - drm/etnaviv: add missing failure path to destroy suballoc + - drm/imx: notify drm core before sending event during crtc disable + - drm/imx: only send event on crtc disable if kept disabled + - ftrace/x86: Remove possible deadlock between register_kprobe() and + ftrace_run_update_code() + - mm/vmscan.c: prevent useless kswapd loops + - btrfs: Ensure replaced device doesn't have pending chunk allocation + - tty: rocket: fix incorrect forward declaration of 'rp_init()' + - net/smc: move unhash before release of clcsock + - media: s5p-mfc: fix incorrect bus assignment in virtual child device + - drm/fb-helper: generic: Don't take module ref for fbcon + - f2fs: don't access node/meta inode mapping after iput + - ALSA: hda: Initialize power_state field properly + - ip6: fix skb leak in ip6frag_expire_frag_queue() + - net: IP defrag: encapsulate rbtree defrag code into callable functions + - net: IP6 defrag: use rbtrees for IPv6 defrag + - net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c + - netfilter: ipv6: nf_defrag: fix leakage of unqueued fragments + - sc16is7xx: move label 'err_spi' to correct section + - netfilter: ipv6: nf_defrag: accept duplicate fragments again + - KVM: x86: degrade WARN to pr_warn_ratelimited + - KVM: LAPIC: Fix pending interrupt in IRR blocked by software disable LAPIC + - nfsd: Fix overflow causing non-working mounts on 1 TB machines + - svcrdma: Ignore source port when computing DRC hash + - MIPS: Fix bounds check virt_addr_valid + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence. + - MIPS: have "plain" make calls build dtbs for selected platforms + - dmaengine: qcom: bam_dma: Fix completed descriptors count + - dmaengine: imx-sdma: remove BD_INTR for channel0 + - signal: remove the wrong signal_pending() check in restore_user_sigmask() + - idr: Fix idr_get_next race with idr_remove + - ASoC: core: lock client_mutex while removing link components + - iommu/vt-d: Set the right field for Page Walk Snoop + - HID: a4tech: fix horizontal scrolling + - ASoC: hda: fix unbalanced codec dev refcount for HDA_DEV_ASOC + - gpio: pca953x: hack to fix 24 bit gpio expanders + - ASoC: Intel: sst: fix kmalloc call with wrong flags + - arm64: tlbflush: Ensure start/end of address range are aligned to stride + - dax: Fix xarray entry association for mixed mappings + - swap_readpage(): avoid blk_wake_io_task() if !synchronous + - drm/virtio: move drm_connector_update_edid_property() call + - s390/mm: fix pxd_bad with folded page tables + - dmaengine: jz4780: Fix an endian bug in IRQ handler + - scsi: target/iblock: Fix overrun in WRITE SAME emulation + - crypto: talitos - rename alternative AEAD algos. + - soc: brcmstb: Fix error path for unsupported CPUs + - soc: bcm: brcmstb: biuctrl: Register writes require a barrier + - samples, bpf: fix to change the buffer size for read() + - samples, bpf: suppress compiler warning + - mac80211: fix rate reporting inside cfg80211_calculate_bitrate_he() + - bpf: sockmap, fix use after free from sleep in psock backlog workqueue + - soundwire: stream: fix out of boundary access on port properties + - staging:iio:ad7150: fix threshold mode config bit + - mac80211: mesh: fix RCU warning + - mac80211: free peer keys before vif down in mesh + - iwlwifi: Fix double-free problems in iwl_req_fw_callback() + - soundwire: intel: set dai min and max channels correctly + - dt-bindings: can: mcp251x: add mcp25625 support + - can: mcp251x: add support for mcp25625 + - can: m_can: implement errata "Needless activation of MRAF irq" + - can: af_can: Fix error path of can_init() + - ibmvnic: Do not close unopened driver during reset + - ibmvnic: Refresh device multicast list after reset + - ibmvnic: Fix unchecked return codes of memory allocations + - ARM: dts: am335x phytec boards: Fix cd-gpios active level + - s390/boot: disable address-of-packed-member warning + - drm/vmwgfx: Honor the sg list segment size limitation + - drm/vmwgfx: fix a warning due to missing dma_parms + - riscv: Fix udelay in RV32. + - Input: imx_keypad - make sure keyboard can always wake up system + - KVM: arm/arm64: vgic: Fix kvm_device leak in vgic_its_destroy + - mlxsw: spectrum: Disallow prio-tagged packets when PVID is removed + - ARM: davinci: da850-evm: call regulator_has_full_constraints() + - ARM: davinci: da8xx: specify dma_coherent_mask for lcdc + - mac80211: only warn once on chanctx_conf being NULL + - mac80211: do not start any work during reconfigure flow + - bpf, devmap: Fix premature entry free on destroying map + - bpf, devmap: Add missing bulk queue free + - bpf, devmap: Add missing RCU read lock on flush + - bpf, x64: fix stack layout of JITed bpf code + - qmi_wwan: add support for QMAP padding in the RX path + - qmi_wwan: avoid RCU stalls on device disconnect when in QMAP mode + - qmi_wwan: extend permitted QMAP mux_id value range + - mmc: core: complete HS400 before checking status + - md: fix for divide error in status_resync + - bnx2x: Check if transceiver implements DDM before access + - drm: return -EFAULT if copy_to_user() fails + - ip6_tunnel: allow not to count pkts on tstats by passing dev as NULL + - net: lio_core: fix potential sign-extension overflow on large shift + - scsi: qedi: Check targetname while finding boot target information + - quota: fix a problem about transfer quota + - net: dsa: mv88e6xxx: fix shift of FID bits in mv88e6185_g1_vtu_loadpurge() + - NFS4: Only set creation opendata if O_CREAT + - net :sunrpc :clnt :Fix xps refcount imbalance on the error path + - fscrypt: don't set policy for a dead directory + - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + - media: stv0297: fix frequency range limit + - ALSA: usb-audio: Fix parse of UAC2 Extension Units + - ALSA: hda/realtek - Headphone Mic can't record after S3 + - block, bfq: NULL out the bic when it's no longer valid + - perf pmu: Fix uncore PMU alias list for ARM64 + - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + - x86/tls: Fix possible spectre-v1 in do_get_thread_area() + - Documentation: Add section about CPU vulnerabilities for Spectre + - Documentation/admin: Remove the vsyscall=native documentation + - mwifiex: Abort at too short BSS descriptor element + - mwifiex: Don't abort on small, spec-compliant vendor IEs + - USB: serial: ftdi_sio: add ID for isodebug v1 + - USB: serial: option: add support for GosunCn ME3630 RNDIS mode + - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled" + - p54usb: Fix race between disconnect and firmware loading + - usb: gadget: ether: Fix race between gether_disconnect and rx_submit + - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset() + - usb: renesas_usbhs: add a workaround for a race condition of workqueue + - drivers/usb/typec/tps6598x.c: fix portinfo width + - drivers/usb/typec/tps6598x.c: fix 4CC cmd write + - staging: comedi: dt282x: fix a null pointer deref on interrupt + - staging: comedi: amplc_pci230: fix null pointer deref on interrupt + - HID: Add another Primax PIXART OEM mouse quirk + - lkdtm: support llvm-objcopy + - binder: fix memory leak in error path + - carl9170: fix misuse of device driver API + - VMCI: Fix integer overflow in VMCI handle arrays + - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work + - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex + - staging: bcm2835-camera: Ensure all buffers are returned on disable + - staging: bcm2835-camera: Remove check of the number of buffers supplied + - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming + - staging: rtl8712: reduce stack usage, again + - crypto: lrw - use correct alignmask + - bpf: sockmap, restore sk_write_space when psock gets dropped + - ARM: dts: Drop bogus CLKSEL for timer12 on dra7 + - iwlwifi: fix load in rfkill flow for unified firmware + - tools: bpftool: Fix JSON output when lookup fails + - soundwire: stream: fix bad unlock balance + - can: flexcan: Remove unneeded registration message + - RISC-V: defconfig: enable clocks, serial console + - xdp: check device pointer before clearing + - KVM: nVMX: use correct clean fields when copying from eVMCS + - gpu: ipu-v3: image-convert: Fix input bytesperline width/height align + - gpu: ipu-v3: image-convert: Fix input bytesperline for packed formats + - gpu: ipu-v3: image-convert: Fix image downsize coefficients + - cfg80211: util: fix bit count off by one + - cfg80211: report measurement start TSF correctly + - IB/hfi1: Create inline to get extended headers + - IB/hfi1: Wakeup QPs orphaned on wait list after flush + - IB/hfi1: Handle wakeup of orphaned QPs for pio + - IB/hfi1: Handle port down properly in pio + - powerpc: enable a 30-bit ZONE_DMA for 32-bit pmac + - tpm: Actually fail on TPM errors during "get random" + - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations + - perf intel-pt: Fix itrace defaults for perf script + - perf auxtrace: Fix itrace defaults for perf script + - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation + - perf header: Assign proper ff->ph in perf_event__synthesize_features() + - usb: gadget: f_fs: data_len used before properly set + - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize() + - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro + - iio: adc: stm32-adc: add missing vdda-supply + - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()" + - staging: vchiq: revert "switch to wait_for_completion_killable" + - staging: vchiq: make wait events interruptible + * Touchpad not detecting in Linux (LP: #1825718) // Disco update: upstream + stable patchset 2019-08-19 (LP: #1840718) + - HID: i2c-hid: add iBall Aer3 to descriptor override + * Disco update: upstream stable patchset 2019-08-16 (LP: #1840521) + - arm64: Don't unconditionally add -Wno-psabi to KBUILD_CFLAGS + - Revert "x86/uaccess, ftrace: Fix ftrace_likely_update() vs. SMAP" + - qmi_wwan: Fix out-of-bounds read + - fs/proc/array.c: allow reporting eip/esp for all coredumping threads + - mm/mempolicy.c: fix an incorrect rebind node in mpol_rebind_nodemask + - fs/binfmt_flat.c: make load_flat_shared_library() work + - clk: socfpga: stratix10: fix divider entry for the emac clocks + - mm: soft-offline: return -EBUSY if set_hwpoison_free_buddy_page() fails + - mm: hugetlb: soft-offline: dissolve_free_huge_page() return zero on + !PageHuge + - dm log writes: make sure super sector log updates are written in order + - scsi: vmw_pscsi: Fix use-after-free in pvscsi_queue_lck() + - x86/speculation: Allow guests to use SSBD even if host does not + - x86/microcode: Fix the microcode load on CPU hotplug for real + - x86/resctrl: Prevent possible overrun during bitmap operations + - NFS/flexfiles: Use the correct TCP timeout for flexfiles I/O + - cpu/speculation: Warn on unsupported mitigations= parameter + - irqchip/mips-gic: Use the correct local interrupt map registers + - af_packet: Block execution of tasks waiting for transmit to complete in + AF_PACKET + - bonding: Always enable vlan tx offload + - ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop + - net/packet: fix memory leak in packet_set_ring() + - net: remove duplicate fetch in sock_getsockopt + - net: stmmac: fixed new system time seconds value calculation + - net: stmmac: set IC bit when transmitting frames with HW timestamp + - sctp: change to hold sk after auth shkey is created successfully + - team: Always enable vlan tx offload + - tipc: change to use register_pernet_device + - tipc: check msg->req data len in tipc_nl_compat_bearer_disable + - tun: wake up waitqueues after IFF_UP is set + - bpf: simplify definition of BPF_FIB_LOOKUP related flags + - bpf: lpm_trie: check left child of last leftmost node for NULL + - bpf: fix nested bpf tracepoints with per-cpu data + - bpf: fix unconnected udp hooks + - bpf: udp: Avoid calling reuseport's bpf_prog from udp_gro + - bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err + - arm64: futex: Avoid copying out uninitialised stack in failed cmpxchg() + - bpf, arm64: use more scalable stadd over ldxr / stxr loop in xadd + - futex: Update comments and docs about return values of arch futex code + - RDMA: Directly cast the sockaddr union to sockaddr + - tipc: pass tunnel dev as NULL to udp_tunnel(6)_xmit_skb + - arm64: insn: Fix ldadd instruction encoding + - clk: tegra210: Fix default rates for HDA clocks + - mm, swap: fix THP swap out + - mm: fix page cache convergence regression + - efi/memreserve: deal with memreserve entries in unmapped memory + - net: aquantia: fix vlans not working over bridged network + * Disco update: upstream stable patchset 2019-08-15 (LP: #1840373) + - tracing: Silence GCC 9 array bounds warning + - gcc-9: silence 'address-of-packed-member' warning + - ovl: support the FS_IOC_FS[SG]ETXATTR ioctls + - ovl: fix wrong flags check in FS_IOC_FS[SG]ETXATTR ioctls + - ovl: make i_ino consistent with st_ino in more cases + - ovl: detect overlapping layers + - ovl: don't fail with disconnected lower NFS + - ovl: fix bogus -Wmaybe-unitialized warning + - mmc: sdhci: sdhci-pci-o2micro: Correctly set bus width when tuning + - mmc: core: API to temporarily disable retuning for SDIO CRC errors + - mmc: core: Add sdio_retune_hold_now() and sdio_retune_release() + - mmc: core: Prevent processing SDIO IRQs when the card is suspended + - scsi: ufs: Avoid runtime suspend possibly being blocked forever + - usb: chipidea: udc: workaround for endpoint conflict issue + - xhci: detect USB 3.2 capable host controllers correctly + - usb: xhci: Don't try to recover an endpoint if port is in error state. + - IB/hfi1: Validate fault injection opcode user input + - IB/hfi1: Silence txreq allocation warnings + - iio: temperature: mlx90632 Relax the compatibility check + - Input: synaptics - enable SMBus on ThinkPad E480 and E580 + - Input: uinput - add compat ioctl number translation for UI_*_FF_UPLOAD + - Input: silead - add MSSL0017 to acpi_device_id + - apparmor: enforce nullbyte at end of tag string + - brcmfmac: sdio: Disable auto-tuning around commands expected to fail + - brcmfmac: sdio: Don't tune while the card is off + - ARC: fix build warnings + - dmaengine: dw-axi-dmac: fix null dereference when pointer first is null + - dmaengine: sprd: Fix block length overflow + - ARC: [plat-hsdk]: Add missing multicast filter bins number to GMAC node + - ARC: [plat-hsdk]: Add missing FIFO size entry in GMAC node + - fpga: dfl: afu: Pass the correct device to dma_mapping_error() + - fpga: dfl: Add lockdep classes for pdata->lock + - parport: Fix mem leak in parport_register_dev_model + - parisc: Fix compiler warnings in float emulation code + - IB/rdmavt: Fix alloc_qpn() WARN_ON() + - IB/hfi1: Insure freeze_work work_struct is canceled on shutdown + - IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value + - IB/hfi1: Validate page aligned for a given virtual address + - MIPS: uprobes: remove set but not used variable 'epc' + - xtensa: Fix section mismatch between memblock_reserve and mem_reserve + - kselftest/cgroup: fix unexpected testing failure on test_memcontrol + - kselftest/cgroup: fix unexpected testing failure on test_core + - kselftest/cgroup: fix incorrect test_core skip + - selftests: vm: install test_vmalloc.sh for run_vmtests + - net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0 + - mdesc: fix a missing-check bug in get_vdev_port_node_info() + - sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD + - net: ethernet: mediatek: Use hw_feature to judge if HWLRO is supported + - net: ethernet: mediatek: Use NET_IP_ALIGN to judge if HW RX_2BYTE_OFFSET is + enabled + - drm/arm/mali-dp: Add a loop around the second set CVAL and try 5 times + - drm/arm/hdlcd: Actually validate CRTC modes + - drm/arm/hdlcd: Allow a bit of clock tolerance + - nvmet: fix data_len to 0 for bdev-backed write_zeroes + - scripts/checkstack.pl: Fix arm64 wrong or unknown architecture + - scsi: ufs: Check that space was properly alloced in copy_query_response + - scsi: smartpqi: unlock on error in pqi_submit_raid_request_synchronous() + - net: ipvlan: Fix ipvlan device tso disabled while NETIF_F_IP_CSUM is set + - s390/qeth: fix VLAN attribute in bridge_hostnotify udev event + - hwmon: (core) add thermal sensors only if dev->of_node is present + - hwmon: (pmbus/core) Treat parameters as paged if on multiple pages + - arm64: Silence gcc warnings about arch ABI drift + - nvme: Fix u32 overflow in the number of namespace list calculation + - btrfs: start readahead also in seed devices + - can: xilinx_can: use correct bittiming_const for CAN FD core + - can: flexcan: fix timeout when set small bitrate + - can: purge socket error queue on sock destruct + - riscv: mm: synchronize MMU after pte change + - powerpc/bpf: use unsigned division instruction for 64-bit operations + - ARM: imx: cpuidle-imx6sx: Restrict the SW2ISO increase to i.MX6SX + - ARM: dts: dra76x: Update MMC2_HS200_MANUAL1 iodelay values + - ARM: dts: am57xx-idk: Remove support for voltage switching for SD card + - arm64/sve: should not depend on + - arm64: ssbd: explicitly depend on + - drm/vmwgfx: Use the backdoor port if the HB port is not available + - staging: erofs: add requirements field in superblock + - SMB3: retry on STATUS_INSUFFICIENT_RESOURCES instead of failing write + - cfg80211: fix memory leak of wiphy device name + - mac80211: drop robust management frames from unknown TA + - {nl,mac}80211: allow 4addr AP operation on crypto controlled devices + - mac80211: handle deauthentication/disassociation from TDLS peer + - nl80211: fix station_info pertid memory leak + - mac80211: Do not use stack memory with scatterlist for GMAC + - x86/resctrl: Don't stop walking closids when a locksetup group is found + - mmc: sdhi: disallow HS400 for M3-W ES1.2, RZ/G2M, and V3H + - mmc: mediatek: fix SDIO IRQ interrupt handle flow + - mmc: mediatek: fix SDIO IRQ detection issue + - cifs: fix GlobalMid_Lock bug in cifs_reconnect + - IB/hfi1: Close PSM sdma_progress sleep window + - IB/hfi1: Avoid hardlockup with flushlist_lock + - IB/hfi1: Correct tid qp rcd to match verbs context + - iio: imu: st_lsm6dsx: fix PM support for st_lsm6dsx i2c controller + - apparmor: reset pos on failure to unpack for various functions + - Revert "brcmfmac: disable command decode in sdio_aos" + - lkdtm/usercopy: Moves the KERNEL_DS test to non-canonical + - dmaengine: jz4780: Fix transfers being ACKed too soon + - dmaengine: mediatek-cqdma: sleeping in atomic context + - dmaengine: sprd: Fix the possible crash when getting descriptor status + - dmaengine: sprd: Add validation of current descriptor in irq handler + - dmaengine: sprd: Fix the incorrect start for 2-stage destination channels + - dmaengine: sprd: Fix the right place to configure 2-stage transfer + - fpga: stratix10-soc: fix use-after-free on s10_init() + - crypto: hmac - fix memory leak in hmac_init_tfm() + - userfaultfd: selftest: fix compiler warning + - selftests: set sysctl bc_forwarding properly in router_broadcast.sh + - kbuild: tar-pkg: enable communication with jobserver + - net: phylink: avoid reducing support mask + - udmabuf: actually unmap the scatterlist + - s390/qeth: handle limited IPv4 broadcast in L3 TX path + - s390/qeth: check dst entry before use + - ARM: mvebu_v7_defconfig: fix Ethernet on Clearfog + - KVM: x86/mmu: Allocate PAE root array when using SVM's 32-bit NPT + - binder: fix possible UAF when freeing buffer + - x86/vdso: Prevent segfaults due to hoisted vclock reads + * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482) + - [Config] Enable VIMC module + * reboot will introduce an alarm 'beep ...' during BIOS phase (LP: #1840395) + - ALSA: hda - Let all conexant codec enter D3 when rebooting + - ALSA: hda - Add a generic reboot_notify + * Include Sunix serial/parallel driver (LP: #1826716) + - serial: 8250_pci: Add support for Sunix serial boards + - parport: parport_serial: Add support for Sunix Multi I/O boards + * Intel HDMI audio print "Unable to sync register" errors (LP: #1840394) + - ALSA: hda - Don't resume forcibly i915 HDMI/DP codec + * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231) + - SAUCE: shiftfs: pass correct point down + * shiftfs: add O_DIRECT support (LP: #1837223) + - SAUCE: shiftfs: add O_DIRECT support + * p54usb module in linux-modules-extra-5.0.0-23-generic does not work + (LP: #1839693) + - p54: fix crash during initialization + * Goodix touchpad may drop first input event (LP: #1840075) + - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c + quirk" + - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk" + - mfd: intel-lpss: Remove D3cold delay + * NULL pointer dereference when Inserting the VIMC module (LP: #1840028) + - media: vimc: fix component match compare + * Fix touchpad IRQ storm after S3 (LP: #1841396) + - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin + * [SRU][B/OEM-B/OEM-OSP1/D] UBUNTU: SAUCE: enable middle button for one more + ThinkPad (LP: #1841722) + - SAUCE: Input: elantech - enable middle button for one more ThinkPad + * Disco update: upstream stable patchset 2019-08-13 (LP: #1840076) + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + - drm/nouveau: add kconfig option to turn off nouveau legacy contexts. (v3) + - nouveau: Fix build with CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT disabled + - HID: multitouch: handle faulty Elo touch device + - HID: wacom: Don't set tool type until we're in range + - HID: wacom: Don't report anything prior to the tool entering range + - HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact + - HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth + - HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary + - ALSA: oxfw: allow PCM capture for Stanton SCS.1m + - ALSA: hda/realtek - Update headset mode for ALC256 + - ALSA: firewire-motu: fix destruction of data for isochronous resources + - libata: Extend quirks for the ST1000LM024 drives with NOLPM quirk + - mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node + - fs/ocfs2: fix race in ocfs2_dentry_attach_lock() + - mm/vmscan.c: fix trying to reclaim unevictable LRU page + - signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO + - ptrace: restore smp_rmb() in __ptrace_may_access() + - iommu/arm-smmu: Avoid constant zero in TLBI writes + - i2c: acorn: fix i2c warning + - bcache: fix stack corruption by PRECEDING_KEY() + - cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() + - ASoC: cs42xx8: Add regcache mask dirty + - ASoC: fsl_asrc: Fix the issue about unsupported rate + - drm/i915/sdvo: Implement proper HDMI audio support for SDVO + - x86/uaccess, kcov: Disable stack protector + - ALSA: seq: Protect in-kernel ioctl calls with mutex + - ALSA: seq: Fix race of get-subscription call vs port-delete ioctls + - Revert "ALSA: seq: Protect in-kernel ioctl calls with mutex" + - s390/kasan: fix strncpy_from_user kasan checks + - Drivers: misc: fix out-of-bounds access in function param_set_kgdbts_var + - f2fs: fix to avoid accessing xattr across the boundary + - scsi: qedi: remove memset/memcpy to nfunc and use func instead + - scsi: qedi: remove set but not used variables 'cdev' and 'udev' + - scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show + - scsi: lpfc: add check for loss of ndlp when sending RRQ + - arm64/mm: Inhibit huge-vmap with ptdump + - nvme: fix srcu locking on error return in nvme_get_ns_from_disk + - nvme: remove the ifdef around nvme_nvm_ioctl + - nvme: merge nvme_ns_ioctl into nvme_ioctl + - nvme: release namespace SRCU protection before performing controller ioctls + - nvme: fix memory leak for power latency tolerance + - platform/x86: pmc_atom: Add Lex 3I380D industrial PC to critclk_systems DMI + table + - platform/x86: pmc_atom: Add several Beckhoff Automation boards to + critclk_systems DMI table + - scsi: bnx2fc: fix incorrect cast to u64 on shift operation + - libnvdimm: Fix compilation warnings with W=1 + - selftests/timers: Add missing fflush(stdout) calls + - tracing: Prevent hist_field_var_ref() from accessing NULL tracing_map_elts + - usbnet: ipheth: fix racing condition + - KVM: arm/arm64: Move cc/it checks under hyp's Makefile to avoid + instrumentation + - KVM: x86/pmu: mask the result of rdpmc according to the width of the + counters + - KVM: x86/pmu: do not mask the value that is written to fixed PMUs + - KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION + - tools/kvm_stat: fix fields filter for child events + - drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an + invalid read + - drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define() + - usb: dwc2: Fix DMA cache alignment issues + - usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression) + - USB: Fix chipmunk-like voice when using Logitech C270 for recording audio. + - USB: serial: pl2303: add Allied Telesis VT-Kit3 + - USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode + - USB: serial: option: add Telit 0x1260 and 0x1261 compositions + - timekeeping: Repair ktime_get_coarse*() granularity + - RAS/CEC: Convert the timer callback to a workqueue + - RAS/CEC: Fix binary search function + - x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback + - x86/kasan: Fix boot with 5-level paging and KASAN + - x86/mm/KASLR: Compute the size of the vmemmap section properly + - x86/resctrl: Prevent NULL pointer dereference when local MBM is disabled + - drm/edid: abstract override/firmware EDID retrieval + - drm: add fallback override/firmware EDID modes workaround + - HID: input: make sure the wheel high resolution multiplier is set + - HID: input: fix assignment of .value + - Revert "HID: Increase maximum report size allowed by hid_field_extract()" + - selinux: fix a missing-check bug in selinux_add_mnt_opt( ) + - selinux: fix a missing-check bug in selinux_sb_eat_lsm_opts() + - media: dvb: warning about dvb frequency limits produces too much noise + - drm/amdgpu/{uvd,vcn}: fetch ring's read_ptr after alloc + - drm/i915/dsi: Use a fuzzy check for burst mode clock check + - drm/i915: Fix per-pixel alpha with CCS + - drm/i915/dmc: protect against reading random memory + - drivers/perf: arm_spe: Don't error on high-order pages for aux buf + - bpf: sockmap, only stop/flush strp if it was enabled at some point + - bpf: sockmap remove duplicate queue free + - bpf: sockmap fix msg->sg.size account on ingress skb + - scsi: qla2xxx: Add cleanup for PCI EEH recovery + - scsi: lpfc: resolve lockdep warnings + - arm64: Print physical address of page table base in show_pte() + - net: macb: fix error format in dev_err() + - bpf, tcp: correctly handle DONT_WAIT flags and timeo == 0 + - tools/bpftool: move set_max_rlimit() before __bpf_object__open_xattr() + - nvme-pci: Fix controller freeze wait disabling + - scsi: myrs: Fix uninitialized variable + - nvme-pci: use blk-mq mapping for unmanaged irqs + - KVM: nVMX: really fix the size checks on KVM_SET_NESTED_STATE + - KVM: selftests: Fix a condition in test_hv_cpuid() + - kvm: vmx: Fix -Wmissing-prototypes warnings + - KVM: LAPIC: Fix lapic_timer_advance_ns parameter overflow + - KVM: x86: do not spam dmesg with VMCS/VMCB dumps + - kvm: selftests: aarch64: dirty_log_test: fix unaligned memslot size + - kvm: selftests: aarch64: fix default vm mode + - tracing/uprobe: Fix NULL pointer dereference in trace_uprobe_create() + - powerpc: Fix kexec failure on book3s/32 + - powerpc/64s: Fix THP PMD collapse serialisation + - ax25: fix inconsistent lock state in ax25_destroy_timer + - be2net: Fix number of Rx queues used for flow hashing + - hv_netvsc: Set probe mode to sync + - ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero + - lapb: fixed leak of control-blocks. + - neigh: fix use-after-free read in pneigh_get_next + - net: dsa: rtl8366: Fix up VLAN filtering + - net: openvswitch: do not free vport if register_netdevice() is failed. + - sctp: Free cookie before we memdup a new one + - sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg + - tipc: purge deferredq list for each grp member in tipc_group_delete + - vsock/virtio: set SOCK_DONE on peer shutdown + - net/mlx5: Avoid reloading already removed devices + - net: mvpp2: prs: Fix parser range for VID filtering + - net: mvpp2: prs: Use the correct helpers when removing all VID filters + - Staging: vc04_services: Fix a couple error codes + - perf/x86/intel/ds: Fix EVENT vs. UEVENT PEBS constraints + - netfilter: nf_queue: fix reinject verdict handling + - ipvs: Fix use-after-free in ip_vs_in + - selftests: netfilter: missing error check when setting up veth interface + - clk: ti: clkctrl: Fix clkdm_clk handling + - powerpc/powernv: Return for invalid IMC domain + - usb: xhci: Fix a potential null pointer dereference in + xhci_debugfs_create_endpoint() + - mISDN: make sure device name is NUL terminated + - x86/CPU/AMD: Don't force the CPB cap when running under a hypervisor + - perf/ring_buffer: Fix exposing a temporarily decreased data_head + - perf/ring_buffer: Add ordering to rb->nest increment + - perf/ring-buffer: Always use {READ,WRITE}_ONCE() for rb->user_page data + - gpio: fix gpio-adp5588 build errors + - net: stmmac: update rx tail pointer register to fix rx dma hang issue. + - net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() + - ACPI/PCI: PM: Add missing wakeup.flags.valid checks + - drm/etnaviv: lock MMU while dumping core + - net: aquantia: tx clean budget logic error + - net: aquantia: fix LRO with FCS error + - i2c: dev: fix potential memory leak in i2cdev_ioctl_rdwr + - ALSA: hda - Force polling mode on CNL for fixing codec communication + - configfs: Fix use-after-free when accessing sd->s_dentry + - perf data: Fix 'strncat may truncate' build failure with recent gcc + - perf namespace: Protect reading thread's namespace + - perf record: Fix s390 missing module symbol and warning for non-root users + - ia64: fix build errors by exporting paddr_to_nid() + - xen/pvcalls: Remove set but not used variable + - xenbus: Avoid deadlock during suspend due to open transactions + - KVM: PPC: Book3S: Use new mutex to synchronize access to rtas token list + - KVM: PPC: Book3S HV: Don't take kvm->lock around kvm_for_each_vcpu + - arm64: fix syscall_fn_t type + - arm64: use the correct function type in SYSCALL_DEFINE0 + - arm64: use the correct function type for __arm64_sys_ni_syscall + - net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs + - net: phylink: ensure consistent phy interface mode + - net: phy: dp83867: Set up RGMII TX delay + - scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() + - scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask + - scsi: scsi_dh_alua: Fix possible null-ptr-deref + - mlxsw: spectrum: Prevent force of 56G + - ocfs2: fix error path kobject memory leak + - coredump: fix race condition between collapse_huge_page() and core dumping + - Abort file_remove_privs() for non-reg. files + - net: tls, correctly account for copied bytes with multiple sk_msgs + - vxlan: Don't assume linear buffers in error handler + - geneve: Don't assume linear buffers in error handler + - net/mlx5: Update pci error handler entries and command translation + - mlxsw: spectrum_router: Refresh nexthop neighbour when it becomes dead + - net/mlx5e: Add ndo_set_feature for uplink representor + - mlxsw: spectrum_flower: Fix TOS matching + - net/mlx5e: Support tagged tunnel over bond + - net: correct udp zerocopy refcnt also when zerocopy only on append + - net/mlx5e: Avoid detaching non-existing netdev under switchdev mode + - staging: erofs: set sb->s_root to NULL when failing from __getname() + - staging: wilc1000: Fix some double unlock bugs in wilc_wlan_cleanup() + - pinctrl: intel: Clear interrupt status in mask/unmask callback + - netfilter: nf_tables: fix oops during rule dump + - netfilter: nft_fib: Fix existence check support + - net: stmmac: dwmac-mediatek: modify csr_clk value to fix mdio read/write + fail + - dpaa2-eth: Fix potential spectre issue + - dpaa2-eth: Use PTR_ERR_OR_ZERO where appropriate + - dpaa_eth: use only online CPU portals + - dfs_cache: fix a wrong use of kfree in flush_cache_ent() + - KVM: PPC: Book3S HV: Use new mutex to synchronize MMU setup + - blk-mq: Fix memory leak in error handling + - mm: mmu_gather: remove __tlb_reset_range() for force flush + - nvme-tcp: rename function to have nvme_tcp prefix + - nvme-tcp: fix possible null deref on a timed out io queue connect + - nvme-tcp: fix queue mapping when queue count is limited + * Disco update: upstream stable patchset 2019-08-12 (LP: #1839887) + - selftests/tls: test for lowat overshoot with multiple records + - selftests/tls: add test for sleeping even though there is data + - sparc64: Fix regression in non-hypervisor TLB flush xcall + - include/linux/bitops.h: sanitize rotate primitives + - xhci: update bounce buffer with correct sg num + - xhci: Use %zu for printing size_t type + - xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() + - usb: xhci: avoid null pointer deref when bos field is NULL + - usbip: usbip_host: fix BUG: sleeping function called from invalid context + - usbip: usbip_host: fix stub_dev lock context imbalance regression + - USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor + - USB: sisusbvga: fix oops in error path of sisusb_probe + - USB: Add LPM quirk for Surface Dock GigE adapter + - USB: rio500: refuse more than one device at a time + - USB: rio500: fix memory leak in close after disconnect + - media: usb: siano: Fix general protection fault in smsusb + - media: usb: siano: Fix false-positive "uninitialized variable" warning + - media: smsusb: better handle optional alignment + - brcmfmac: fix NULL pointer derefence during USB disconnect + - scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove + - scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) + - tracing: Avoid memory leak in predicate_parse() + - Btrfs: fix wrong ctime and mtime of a directory after log replay + - Btrfs: fix race updating log root item during fsync + - Btrfs: fix fsync not persisting changed attributes of a directory + - Btrfs: incremental send, fix file corruption when no-holes feature is + enabled + - iio: dac: ds4422/ds4424 fix chip verification + - iio: adc: ti-ads8688: fix timestamp is not updated in buffer + - s390/crypto: fix possible sleep during spinlock aquired + - KVM: PPC: Book3S HV: XIVE: Do not clear IRQ data of passthrough interrupts + - powerpc/perf: Fix MMCRA corruption by bhrb_filter + - ALSA: line6: Assure canceling delayed work at disconnection + - ALSA: hda/realtek - Set default power save node to 0 + - KVM: s390: Do not report unusabled IDs via KVM_CAP_MAX_VCPU_ID + - drm/nouveau/i2c: Disable i2c bus access after ->fini() + - i2c: mlxcpld: Fix wrong initialization order in probe + - i2c: synquacer: fix synquacer_i2c_doxfer() return value + - tty: serial: msm_serial: Fix XON/XOFF + - tty: max310x: Fix external crystal register setup + - memcg: make it work on sparse non-0-node systems + - kernel/signal.c: trace_signal_deliver when signal_group_exit + - arm64: Fix the arm64_personality() syscall wrapper redirection + - docs: Fix conf.py for Sphinx 2.0 + - doc: Cope with the deprecation of AutoReporter + - doc: Cope with Sphinx logging deprecations + - ima: show rules with IMA_INMASK correctly + - evm: check hash algorithm passed to init_desc() + - vt/fbcon: deinitialize resources in visual_init() after failed memory + allocation + - serial: sh-sci: disable DMA for uart_console + - staging: vc04_services: prevent integer overflow in create_pagelist() + - staging: wlan-ng: fix adapter initialization failure + - cifs: fix memory leak of pneg_inbuf on -EOPNOTSUPP ioctl case + - CIFS: cifs_read_allocate_pages: don't iterate through whole page array on + ENOMEM + - Revert "lockd: Show pid of lockd for remote locks" + - gcc-plugins: Fix build failures under Darwin host + - drm/tegra: gem: Fix CPU-cache maintenance for BO's allocated using + get_pages() + - drm/vmwgfx: Don't send drm sysfs hotplug events on initial master set + - drm/sun4i: Fix sun8i HDMI PHY clock initialization + - drm/sun4i: Fix sun8i HDMI PHY configuration for > 148.5 MHz + - drm/rockchip: shutdown drm subsystem on shutdown + - drm/lease: Make sure implicit planes are leased + - Revert "x86/build: Move _etext to actual end of .text" + - scsi: lpfc: Fix backport of faf5a744f4f8 ("scsi: lpfc: avoid uninitialized + variable warning") + - KVM: PPC: Book3S HV: Fix lockdep warning when entering guest on POWER9 + - KVM: PPC: Book3S HV: Restore SPRG3 in kvmhv_p9_guest_entry() + - powerpc/kexec: Fix loading of kernel + initramfs with kexec_file_load() + - kasan: initialize tag to 0xff in __kasan_kmalloc + - signal/arm64: Use force_sig not force_sig_fault for SIGKILL + - x86/ima: Check EFI_RUNTIME_SERVICES before using + - ima: fix wrong signed policy requirement when not appraising + - drm/vmwgfx: Fix user space handle equal to zero + - drm/vmwgfx: Fix compat mode shader operation + - drm/atomic: Wire file_priv through for property changes + - drm: Expose "FB_DAMAGE_CLIPS" property to atomic aware user-space only + - drm/cma-helper: Fix drm_gem_cma_free_object() + - ethtool: fix potential userspace buffer overflow + - Fix memory leak in sctp_process_init + - ipv4: not do cache for local delivery if bc_forwarding is enabled + - ipv6: fix the check before getting the cookie in rt6_get_cookie + - neighbor: Call __ipv4_neigh_lookup_noref in neigh_xmit + - net: ethernet: ti: cpsw_ethtool: fix ethtool ring param set + - net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query + - net: mvpp2: Use strscpy to handle stat strings + - net: rds: fix memory leak in rds_ib_flush_mr_pool + - net: sfp: read eeprom in maximum 16 byte increments + - net/tls: replace the sleeping lock around RX resync with a bit lock + - packet: unconditionally free po->rollover + - pktgen: do not sleep with the thread lock held. + - Revert "fib_rules: return 0 directly if an exactly same rule exists when + NLM_F_EXCL not supplied" + - ipv6: use READ_ONCE() for inet->hdrincl as in ipv4 + - ipv6: fix EFAULT on sendto with icmpv6 and hdrincl + - mtd: spinand: macronix: Fix ECC Status Read + - rcu: locking and unlocking need to always be at least barriers + - parisc: Use implicit space register selection for loading the coherence + index of I/O pdirs + - NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter + - NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled + - fuse: fallocate: fix return with locked inode + - pstore: Set tfm to NULL on free_buf_for_compression + - pstore/ram: Run without kernel crash dump region + - x86/power: Fix 'nosmt' vs hibernation triple fault during resume + - i2c: xiic: Add max_read_len quirk + - s390/mm: fix address space detection in exception handling + - xen-blkfront: switch kcalloc to kvcalloc for large array allocation + - MIPS: Bounds check virt_addr_valid + - MIPS: pistachio: Build uImage.gz by default + - Revert "MIPS: perf: ath79: Fix perfcount IRQ assignment" + - genwqe: Prevent an integer overflow in the ioctl + - test_firmware: Use correct snprintf() limit + - drm/gma500/cdv: Check vbt config bits when detecting lvds panels + - drm/msm: fix fb references in async update + - drm: add non-desktop quirk for Valve HMDs + - drm: add non-desktop quirks to Sensics and OSVR headsets. + - drm/amdgpu/psp: move psp version specific function pointers to early_init + - drm/amdgpu: remove ATPX_DGPU_REQ_POWER_FOR_DISPLAYS check when hotplug-in + - drm/i915: Fix I915_EXEC_RING_MASK + - drm/i915/fbc: disable framebuffer compression on GeminiLake + - drm/i915: Maintain consistent documentation subsection ordering + - drm: don't block fb changes for async plane updates + - drm/i915/gvt: Initialize intel_gvt_gtt_entry in stack + - TTY: serial_core, add ->install + - ipv4: Define __ipv4_neigh_lookup_noref when CONFIG_INET is disabled + - udp: only choose unbound UDP socket for multicast when not in a VRF + - neighbor: Reset gc_entries counter if new entry is released before insert + - cls_matchall: avoid panic when receiving a packet before filter set + - ipmr_base: Do not reset index in mr_table_dump + - ARC: mm: SIGSEGV userspace trying to access kernel virtual memory + - parisc: Fix crash due alternative coding for NP iopdir_fdc bit + - SUNRPC fix regression in umount of a secure mount + - fuse: fix copy_file_range() in the writeback case + - memstick: mspro_block: Fix an error code in mspro_block_issue_req() + - mmc: tmio: fix SCC error handling to avoid false positive CRC error + - mmc: sdhci_am654: Fix SLOTTYPE write + - nvme-rdma: fix queue mapping when queue count is limited + - drm/vc4: fix fb references in async update + - drm: Fix timestamp docs for variable refresh properties. + - drm/amd/display: Add ASICREV_IS_PICASSO + - drm/amdgpu: fix ring test failure issue during s3 in vce 3.0 (V2) + - drm/amd: fix fb references in async update + - rapidio: fix a NULL pointer dereference when create_workqueue() fails + - fs/fat/file.c: issue flush after the writeback of FAT + - sysctl: return -EINVAL if val violates minmax + - ipc: prevent lockup on alloc_msg and free_msg + - drm/pl111: Initialize clock spinlock early + - ARM: prevent tracing IPI_CPU_BACKTRACE + - mm/hmm: select mmu notifier when selecting HMM + - hugetlbfs: on restore reserve error path retain subpool reservation + - mem-hotplug: fix node spanned pages when we have a node with only + ZONE_MOVABLE + - mm/cma.c: fix crash on CMA allocation if bitmap allocation fails + - initramfs: free initrd memory if opening /initrd.image fails + - mm/cma.c: fix the bitmap status to show failed allocation reason + - mm: page_mkclean vs MADV_DONTNEED race + - mm/cma_debug.c: fix the break condition in cma_maxchunk_get() + - mm/slab.c: fix an infinite loop in leaks_show() + - kernel/sys.c: prctl: fix false positive in validate_prctl_map() + - thermal: rcar_gen3_thermal: disable interrupt in .remove + - drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER + - mfd: tps65912-spi: Add missing of table registration + - mfd: intel-lpss: Set the device in reset state when init + - drm/nouveau/disp/dp: respect sink limits when selecting failsafe link + configuration + - mfd: twl6040: Fix device init errors for ACCCTL register + - perf/x86/intel: Allow PEBS multi-entry in watermark mode + - drm/nouveau/kms/gf119-gp10x: push HeadSetControlOutputResource() mthd when + encoders change + - drm/bridge: adv7511: Fix low refresh rate selection + - objtool: Don't use ignore flag for fake jumps + - drm/nouveau/kms/gv100-: fix spurious window immediate interlocks + - bpf: fix undefined behavior in narrow load handling + - EDAC/mpc85xx: Prevent building as a module + - pwm: meson: Use the spin-lock only to protect register modifications + - mailbox: stm32-ipcc: check invalid irq + - ntp: Allow TAI-UTC offset to be set to zero + - f2fs: fix to avoid panic in do_recover_data() + - f2fs: fix to avoid panic in f2fs_inplace_write_data() + - f2fs: fix to avoid panic in f2fs_remove_inode_page() + - f2fs: fix to do sanity check on free nid + - f2fs: fix to clear dirty inode in error path of f2fs_iget() + - f2fs: fix to avoid panic in dec_valid_block_count() + - f2fs: fix to use inline space only if inline_xattr is enable + - f2fs: fix to do sanity check on valid block count of segment + - f2fs: fix to do checksum even if inode page is uptodate + - percpu: remove spurious lock dependency between percpu and sched + - configfs: fix possible use-after-free in configfs_register_group + - uml: fix a boot splat wrt use of cpu_all_mask + - PCI: dwc: Free MSI in dw_pcie_host_init() error path + - PCI: dwc: Free MSI IRQ page in dw_pcie_free_msi() + - mmc: mmci: Prevent polling for busy detection in IRQ context + - netfilter: nf_flow_table: fix missing error check for rhashtable_insert_fast + - netfilter: nf_conntrack_h323: restore boundary check correctness + - mips: Make sure dt memory regions are valid + - netfilter: nf_tables: fix base chain stat rcu_dereference usage + - watchdog: imx2_wdt: Fix set_timeout for big timeout values + - watchdog: fix compile time error of pretimeout governors + - blk-mq: move cancel of requeue_work into blk_mq_release + - iommu/vt-d: Set intel_iommu_gfx_mapped correctly + - misc: pci_endpoint_test: Fix test_reg_bar to be updated in pci_endpoint_test + - PCI: designware-ep: Use aligned ATU window for raising MSI interrupts + - nvme-pci: unquiesce admin queue on shutdown + - nvme-pci: shutdown on timeout during deletion + - netfilter: nf_flow_table: check ttl value in flow offload data path + - netfilter: nf_flow_table: fix netdev refcnt leak + - ALSA: hda - Register irq handler after the chip initialization + - nvmem: core: fix read buffer in place + - nvmem: sunxi_sid: Support SID on A83T and H5 + - fuse: retrieve: cap requested size to negotiated max_write + - nfsd: allow fh_want_write to be called twice + - nfsd: avoid uninitialized variable warning + - vfio: Fix WARNING "do not call blocking ops when !TASK_RUNNING" + - switchtec: Fix unintended mask of MRPC event + - net: thunderbolt: Unregister ThunderboltIP protocol handler when suspending + - x86/PCI: Fix PCI IRQ routing table memory leak + - i40e: Queues are reserved despite "Invalid argument" error + - platform/chrome: cros_ec_proto: check for NULL transfer function + - PCI: keystone: Prevent ARM32 specific code to be compiled for ARM64 + - soc: mediatek: pwrap: Zero initialize rdata in pwrap_init_cipher + - clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 + - soc: rockchip: Set the proper PWM for rk3288 + - ARM: dts: imx51: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx50: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx53: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sll: Specify IMX6SLL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx7d: Specify IMX7D_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6ul: Specify IMX6UL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6qdl: Specify IMX6QDL_CLK_IPG as "ipg" clock to SDMA + - PCI: rpadlpar: Fix leaked device_node references in add/remove paths + - drm/amd/display: Use plane->color_space for dpp if specified + - ARM: OMAP2+: pm33xx-core: Do not Turn OFF CEFUSE as PPA may be using it + - platform/x86: intel_pmc_ipc: adding error handling + - power: supply: max14656: fix potential use-before-alloc + - PCI: rcar: Fix a potential NULL pointer dereference + - PCI: rcar: Fix 64bit MSI message address handling + - scsi: qla2xxx: Reset the FCF_ASYNC_{SENT|ACTIVE} flags + - video: hgafb: fix potential NULL pointer dereference + - video: imsttfb: fix potential NULL pointer dereferences + - block, bfq: increase idling for weight-raised queues + - PCI: xilinx: Check for __get_free_pages() failure + - gpio: gpio-omap: add check for off wake capable gpios + - ice: Add missing case in print_link_msg for printing flow control + - dmaengine: idma64: Use actual device for DMA transfers + - pwm: tiehrpwm: Update shadow register for disabling PWMs + - ARM: dts: exynos: Always enable necessary APIO_1V8 and ABB_1V8 regulators on + Arndale Octa + - pwm: Fix deadlock warning when removing PWM device + - ARM: exynos: Fix undefined instruction during Exynos5422 resume + - usb: typec: fusb302: Check vconn is off when we start toggling + - soc: renesas: Identify R-Car M3-W ES1.3 + - gpio: vf610: Do not share irq_chip + - percpu: do not search past bitmap when allocating an area + - ovl: check the capability before cred overridden + - ovl: support stacked SEEK_HOLE/SEEK_DATA + - ALSA: seq: Cover unsubscribe_port() in list_mutex + - media: rockchip/vpu: Fix/re-order probe-error/remove path + - media: rockchip/vpu: Add missing dont_use_autosuspend() calls + - drm/msm: correct attempted NULL pointer dereference in debugfs + - mm/memory_hotplug: release memory resource after arch_remove_memory() + - mm/memory_hotplug.c: fix the wrong usage of N_HIGH_MEMORY + - drm/nouveau: fix duplication of nv50_head_atom struct + - f2fs: fix error path of recovery + - f2fs: fix to avoid panic in dec_valid_node_count() + - f2fs: fix to avoid deadloop in foreground GC + - f2fs: fix to retrieve inline xattr space + - media: atmel: atmel-isc: fix asd memory allocation + - vfio-pci/nvlink2: Fix potential VMA leak + - powerpc/pseries: Track LMB nid instead of using device tree + - arm64: defconfig: Update UFSHCD for Hi3660 soc + - iommu/vt-d: Don't request page request irq under dmar_global_lock + - soc/tegra: pmc: Remove reset sysfs entries on error + - power: supply: cpcap-battery: Fix signed counter sample register + - PCI: keystone: Invoke phy_reset() API before enabling PHY + - iommu/vt-d: Flush IOTLB for untrusted device in time + - arm64: dts: imx8mq: Mark iomuxc_gpr as i.MX6Q compatible + - pinctrl: pinctrl-intel: move gpio suspend/resume to noirq phase + - f2fs: fix potential recursive call when enabling data_flush + - arm64: dts: qcom: qcs404: Fix regulator supply names + - gpio: gpio-omap: limit errata 1.101 handling to wkup domain gpios only + - media: v4l2-ctrl: v4l2_ctrl_request_setup returns with error upon failure + - batman-adv: Adjust name for batadv_dat_send_data + - ice: Enable LAN_EN for the right recipes + - ice: Do not set LB_EN for prune switch rules + - media: v4l2-fwnode: Defaults may not override endpoint configuration in + firmware + - ARM: shmobile: porter: enable R-Car Gen2 regulator quirk + + [ Ubuntu: 5.0.0-29.31 ] + + * powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts + (CVE-2019-15031) / powerpc/tm: Fix FP/VMX unavailable exceptions inside a + transaction (CVE-2019-15030) (LP: #1843533) // CVE-2019-15031 + - powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction + - powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts + * CVE-2019-14835 + - vhost: fix dirty log buffer overflow + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.0.0-27.28 ] + + * disco/linux: 5.0.0-27.28 -proposed tracker (LP: #1840816) + * [Potential Regression] System crashes when running ftrace test in + ubuntu_kernel_selftests (LP: #1840750) + - x86/kprobes: Set instruction page as executable + + -- Marcelo Henrique Cerri Wed, 18 Sep 2019 06:52:12 -0300 + +linux-oracle (5.0.0-1002.3) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1002.3 -proposed tracker (LP: #1842155) + + * Packaging resync (LP: #1786013) + - [Packaging] fix Vcs-Git: package + + * Miscellaneous Ubuntu changes + - [config] Update annotations format to version 3 + - [config] CONFIG_PAGE_POISONING=y + - [config] CONFIG_NETWORK_PHY_TIMESTAMPING=y + - [config] Un-escaping string literal in CONFIG_LSM + + -- Khalid Elmously Fri, 30 Aug 2019 17:55:51 -0400 + +linux-oracle (5.0.0-1001.2) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1001.2 -proposed tracker (LP: #1840811) + + * disco: unable to use iptables/enable ufw under -virtual kernel + (LP: #1823862) + - [Packaging] add bpfilter to linux-modules + + * tcm_loop.ko: move from modules-extra into main modules package + (LP: #1817786) + - [Packaging] move tcm_loop.lo to main linux-modules package + + * autofs kernel module missing (LP: #1824333) + - [Config] Update autofs4 path in inclusion list + + * [Packaging] Improve config annotations check on custom kernels + (LP: #1820075) + - [Config] linux-oracle: Include custom annotations files + + * Miscellaneous Ubuntu changes + - [Packaging] update update.conf + - [Config] update configs following rebase to 5.0.0-26.27 + - [Packaging] sync packaging updates from master + - [Config] Update getabis to use linux-buildinfo + - [Config] Include shiftfs in generic inclusion list. + + -- Khalid Elmously Mon, 26 Aug 2019 21:52:36 -0400 + +linux-oracle (5.0.0-1000.0) disco; urgency=medium + + * Emtpy entry + + -- Khalid Elmously Fri, 23 Aug 2019 01:00:54 -0400 + +linux-oracle (4.15.0-1022.25) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1022.25 -proposed tracker (LP: #1839997) + + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] oracle: enable build and signing nvidia + + * Bionic update: upstream stable patchset 2019-08-05 (LP: #1839036) + - [Packaging] oracle: adv7511 to adv7511-v4l2 rename + + * Bionic update: upstream stable patchset 2019-08-02 (LP: #1838824) + - [Config] oracle: Add CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y + + * Bionic update: upstream stable patchset 2019-07-29 (LP: #1838349) + - [Config] oracle: include CONFIG_INTEL_ATOMISP2_PM + + * Bionic update: upstream stable patchset 2019-07-26 (LP: #1838116) + - [Config] oracle: Drop CONFIG_R3964 + - [Config] oracle: Add CONFIG_LDISC_AUTOLOAD=y + + * Bionic update: upstream stable patchset 2019-07-22 (LP: #1837477) + - [Config] oracle: Add CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y + + [ Ubuntu: 4.15.0-59.66 ] + + * bionic/linux: 4.15.0-59.66 -proposed tracker (LP: #1840006) + * zfs not completely removed from bionic tree (LP: #1840051) + - SAUCE: (noup) remove completely the zfs code + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * [18.04 FEAT] Enhanced hardware support (LP: #1836857) + - s390: report new CPU capabilities + - s390: add alignment hints to vector load and store + * [18.04 FEAT] Enhanced CPU-MF hardware counters - kernel part (LP: #1836860) + - s390/cpum_cf: Add support for CPU-MF SVN 6 + - s390/cpumf: Add extended counter set definitions for model 8561 and 8562 + * ideapad_laptop disables WiFi/BT radios on Lenovo Y540 (LP: #1837136) + - platform/x86: ideapad-laptop: Remove no_hw_rfkill_list + * Stacked onexec transitions fail when under NO NEW PRIVS restrictions + (LP: #1839037) + - SAUCE: apparmor: fix nnp subset check failure when, stacking + * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight + timeout for bcache removal causes spurious failures (LP: #1796292) + - SAUCE: bcache: fix deadlock in bcache_allocator + * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) + - bcache: never writeback a discard operation + - bcache: improve bcache_reboot() + - bcache: fix writeback target calc on large devices + - bcache: add journal statistic + - bcache: fix high CPU occupancy during journal + - bcache: use pr_info() to inform duplicated CACHE_SET_IO_DISABLE set + - bcache: fix incorrect sysfs output value of strip size + - bcache: fix error return value in memory shrink + - bcache: fix using of loop variable in memory shrink + - bcache: Fix indentation + - bcache: Add __printf annotation to __bch_check_keys() + - bcache: Annotate switch fall-through + - bcache: Fix kernel-doc warnings + - bcache: Remove an unused variable + - bcache: Suppress more warnings about set-but-not-used variables + - bcache: Reduce the number of sparse complaints about lock imbalances + - bcache: Fix a compiler warning in bcache_device_init() + - bcache: Move couple of string arrays to sysfs.c + - bcache: Move couple of functions to sysfs.c + - bcache: Replace bch_read_string_list() by __sysfs_match_string() + * linux hwe i386 kernel 5.0.0-21.22~18.04.1 crashes on Lenovo x220 + (LP: #1838115) + - x86/mm: Check for pfn instead of page in vmalloc_sync_one() + - x86/mm: Sync also unmappings in vmalloc_sync_all() + - mm/vmalloc.c: add priority threshold to __purge_vmap_area_lazy() + - mm/vmalloc: Sync unmappings in __purge_vmap_area_lazy() + * [bionic] drm/i915: softpin broken, needs to be fixed for 32bit mesa + (LP: #1815172) + - drm/i915: Mark up GTT sizes as u64 + - drm/i915/gvt: Use I915_GTT_PAGE_SIZE + - drm/i915: Compare user's 64b GTT offset even on 32b + * Bionic update: upstream stable patchset 2019-08-07 (LP: #1839376) + - ARM: riscpc: fix DMA + - ARM: dts: rockchip: Make rk3288-veyron-minnie run at hs200 + - ARM: dts: rockchip: Make rk3288-veyron-mickey's emmc work again + - ARM: dts: rockchip: Mark that the rk3288 timer might stop in suspend + - ftrace: Enable trampoline when rec count returns back to one + - kernel/module.c: Only return -EEXIST for modules that have finished loading + - MIPS: lantiq: Fix bitfield masking + - dmaengine: rcar-dmac: Reject zero-length slave DMA requests + - clk: tegra210: fix PLLU and PLLU_OUT1 + - fs/adfs: super: fix use-after-free bug + - btrfs: fix minimum number of chunk errors for DUP + - cifs: Fix a race condition with cifs_echo_request + - ceph: fix improper use of smp_mb__before_atomic() + - ceph: return -ERANGE if virtual xattr value didn't fit in buffer + - ACPI: blacklist: fix clang warning for unused DMI table + - scsi: zfcp: fix GCC compiler warning emitted with -Wmaybe-uninitialized + - x86: kvm: avoid constant-conversion warning + - ACPI: fix false-positive -Wuninitialized warning + - be2net: Signal that the device cannot transmit during reconfiguration + - x86/apic: Silence -Wtype-limits compiler warnings + - x86: math-emu: Hide clang warnings for 16-bit overflow + - mm/cma.c: fail if fixed declaration can't be honored + - coda: add error handling for fget + - coda: fix build using bare-metal toolchain + - uapi linux/coda_psdev.h: move upc_req definition from uapi to kernel side + headers + - drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings + - ipc/mqueue.c: only perform resource calculation if user valid + - xen/pv: Fix a boot up hang revealed by int3 self test + - x86/kvm: Don't call kvm_spurious_fault() from .fixup + - x86/paravirt: Fix callee-saved function ELF sizes + - x86, boot: Remove multiple copy of static function sanitize_boot_params() + - drm/nouveau: fix memory leak in nouveau_conn_reset() + - kbuild: initialize CLANG_FLAGS correctly in the top Makefile + - Btrfs: fix incremental send failure after deduplication + - Btrfs: fix race leading to fs corruption after transaction abort + - mmc: dw_mmc: Fix occasional hang after tuning on eMMC + - gpiolib: fix incorrect IRQ requesting of an active-low lineevent + - IB/hfi1: Fix Spectre v1 vulnerability + - selinux: fix memory leak in policydb_init() + - s390/dasd: fix endless loop after read unit address configuration + - parisc: Fix build of compressed kernel even with debug enabled + - drivers/perf: arm_pmu: Fix failure path in PM notifier + - nbd: replace kill_bdev() with __invalidate_device() again + - xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() + - IB/mlx5: Fix unreg_umr to ignore the mkey state + - IB/mlx5: Use direct mkey destroy command upon UMR unreg failure + - IB/mlx5: Move MRs to a kernel PD when freeing them to the MR cache + - IB/mlx5: Fix RSS Toeplitz setup to be aligned with the HW specification + - IB/hfi1: Check for error on call to alloc_rsm_map_table + - eeprom: at24: make spd world-readable again + - objtool: Support GCC 9 cold subfunction naming scheme + - gcc-9: properly declare the {pv,hv}clock_page storage + - x86/vdso: Prevent segfaults due to hoisted vclock reads + - Documentation: Add swapgs description to the Spectre v1 documentation + - firmware/psci: psci_checker: Park kthreads before stopping them + - btrfs: qgroup: Don't hold qgroup_ioctl_lock in btrfs_qgroup_inherit() + - lib/test_string.c: avoid masking memset16/32/64 failures + - mmc: meson-mx-sdio: Fix misuse of GENMASK macro + - arm64: compat: Allow single-byte watchpoints on all addresses + - arm64: cpufeature: Fix feature comparison for CTR_EL0.{CWG,ERG} + - IB/mlx5: Fix clean_mr() to work in the expected order + - ARC: enable uboot support unconditionally + - scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA + * Bionic update: upstream stable patchset 2019-08-06 (LP: #1839213) + - staging: vt6656: use meaningful error code during buffer allocation + - drm/amd/display: Fill prescale_params->scale for RGB565 + - drm/amd/display: Disable ABM before destroy ABM struct + - gpu: host1x: Increase maximum DMA segment size + - drm/amd/display: Always allocate initial connector state state + - drm/amd/display: fix compilation error + - mmc: sdhci: sdhci-pci-o2micro: Check if controller supports 8-bit width + - i2c: stm32f7: fix the get_irq error cases + - genksyms: Teach parser about 128-bit built-in types + - powerpc/mm: Handle page table allocation failures + - arm64: assembler: Switch ESB-instruction with a vanilla nop if + !ARM64_HAS_RAS + - dlm: check if workqueues are NULL before flushing/destroying + - proc: use down_read_killable mmap_sem for /proc/pid/pagemap + - proc: use down_read_killable mmap_sem for /proc/pid/clear_refs + - proc: use down_read_killable mmap_sem for /proc/pid/map_files + - proc: use down_read_killable mmap_sem for /proc/pid/maps + - mm: use down_read_killable for locking mmap_sem in access_remote_vm + - ALSA: ac97: Fix double free of ac97_codec_device + - libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl() + - vsock: correct removal of socket from the list + - NFS: Fix dentry revalidation on NFSv4 lookup + - NFS: Refactor nfs_lookup_revalidate() + - NFSv4: Fix lookup revalidate of regular files + - i2c: qup: fixed releasing dma without flush operation completion + - arm64: compat: Provide definition for COMPAT_SIGMINSTKSZ + - binder: fix possible UAF when freeing buffer + - ISDN: hfcsusb: checking idx of ep configuration + - media: au0828: fix null dereference in error path + - ath10k: Change the warning message string + - media: cpia2_usb: first wake up, then free in disconnect + - media: pvrusb2: use a different format for warnings + - NFS: Cleanup if nfs_match_client is interrupted + - media: radio-raremono: change devm_k*alloc to k*alloc + - iommu/vt-d: Don't queue_iova() if there is no flush queue + - iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA + - hv_sock: Add support for delayed close + - Bluetooth: hci_uart: check for missing tty operations + - sched/fair: Don't free p->numa_faults with concurrent readers + - drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl + - Fix allyesconfig output. + - ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL + * Bionic update: upstream stable patchset 2019-08-05 (LP: #1839036) + - e1000e: start network tx queue only when link is up + - Input: synaptics - enable SMBUS on T480 thinkpad trackpad + - nilfs2: do not use unexported cpu_to_le32()/le32_to_cpu() in uapi header + - drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT + - crypto: talitos - rename alternative AEAD algos. + - samples, bpf: fix to change the buffer size for read() + - bpf: sockmap, fix use after free from sleep in psock backlog workqueue + - staging:iio:ad7150: fix threshold mode config bit + - mac80211: mesh: fix RCU warning + - mac80211: free peer keys before vif down in mesh + - iwlwifi: Fix double-free problems in iwl_req_fw_callback() + - dt-bindings: can: mcp251x: add mcp25625 support + - can: mcp251x: add support for mcp25625 + - can: m_can: implement errata "Needless activation of MRAF irq" + - can: af_can: Fix error path of can_init() + - ibmvnic: Refresh device multicast list after reset + - ARM: dts: am335x phytec boards: Fix cd-gpios active level + - Input: imx_keypad - make sure keyboard can always wake up system + - KVM: arm/arm64: vgic: Fix kvm_device leak in vgic_its_destroy + - mlxsw: spectrum: Disallow prio-tagged packets when PVID is removed + - ARM: davinci: da850-evm: call regulator_has_full_constraints() + - ARM: davinci: da8xx: specify dma_coherent_mask for lcdc + - mac80211: only warn once on chanctx_conf being NULL + - qmi_wwan: add support for QMAP padding in the RX path + - qmi_wwan: avoid RCU stalls on device disconnect when in QMAP mode + - qmi_wwan: extend permitted QMAP mux_id value range + - md: fix for divide error in status_resync + - bnx2x: Check if transceiver implements DDM before access + - drm: return -EFAULT if copy_to_user() fails + - ip6_tunnel: allow not to count pkts on tstats by passing dev as NULL + - net: lio_core: fix potential sign-extension overflow on large shift + - quota: fix a problem about transfer quota + - net: dsa: mv88e6xxx: fix shift of FID bits in mv88e6185_g1_vtu_loadpurge() + - net :sunrpc :clnt :Fix xps refcount imbalance on the error path + - fscrypt: don't set policy for a dead directory + - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + - ALSA: hda/realtek - Headphone Mic can't record after S3 + - block, bfq: NULL out the bic when it's no longer valid + - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + - x86/tls: Fix possible spectre-v1 in do_get_thread_area() + - Documentation: Add section about CPU vulnerabilities for Spectre + - mwifiex: Abort at too short BSS descriptor element + - mwifiex: Don't abort on small, spec-compliant vendor IEs + - USB: serial: ftdi_sio: add ID for isodebug v1 + - USB: serial: option: add support for GosunCn ME3630 RNDIS mode + - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled" + - p54usb: Fix race between disconnect and firmware loading + - usb: gadget: ether: Fix race between gether_disconnect and rx_submit + - usb: renesas_usbhs: add a workaround for a race condition of workqueue + - staging: comedi: dt282x: fix a null pointer deref on interrupt + - staging: comedi: amplc_pci230: fix null pointer deref on interrupt + - binder: fix memory leak in error path + - carl9170: fix misuse of device driver API + - VMCI: Fix integer overflow in VMCI handle arrays + - MIPS: Remove superfluous check for __linux__ + - clk: ti: clkctrl: Fix returning uninitialized data + - efi/bgrt: Drop BGRT status field reserved bits check + - perf/core: Fix perf_sample_regs_user() mm check + - ARM: omap2: remove incorrect __init annotation + - be2net: fix link failure after ethtool offline test + - ppp: mppe: Add softdep to arc4 + - sis900: fix TX completion + - ARM: dts: imx6ul: fix PWM[1-4] interrupts + - dm verity: use message limit for data block corruption message + - x86/boot/64: Fix crash if kernel image crosses page table boundary + - cpu/hotplug: Fix out-of-bounds read when setting fail state + - linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL + - ARC: hide unused function unw_hdr_alloc + - s390: fix stfle zero padding + - s390/qdio: (re-)initialize tiqdio list entries + - s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + - crypto/NX: Set receive window credits to max number of CRBs in RxFIFO + - drm/udl: introduce a macro to convert dev to udl. + - drm/udl: move to embedding drm device inside udl device. + - drm/vmwgfx: fix a warning due to missing dma_parms + - riscv: Fix udelay in RV32. + - mac80211: do not start any work during reconfigure flow + - bpf, devmap: Fix premature entry free on destroying map + - NFS4: Only set creation opendata if O_CREAT + - perf pmu: Fix uncore PMU alias list for ARM64 + - Documentation/admin: Remove the vsyscall=native documentation + - drivers/usb/typec/tps6598x.c: fix portinfo width + - staging: bcm2835-camera: Ensure all buffers are returned on disable + - staging: bcm2835-camera: Remove check of the number of buffers supplied + - staging: rtl8712: reduce stack usage, again + - irqchip/gic-v3-its: Fix command queue pointer comparison bug + - x86/apic: Fix integer overflow on 10 bit left shift of cpu_khz + - pinctrl: mcp23s08: Fix add_data and irqchip_add_nested call order + - x86/boot/64: Add missing fixup_pointer() for next_early_pgt access + - genirq: Delay deactivation in free_irq() + - genirq: Fix misleading synchronize_irq() documentation + - genirq: Update code comments wrt recycled thread_mask + - genirq: Synchronize only with single thread on free_irq() + - genirq: Add optional hardware synchronization for shutdown + - x86/ioapic: Implement irq_get_irqchip_state() callback + - x86/irq: Handle spurious interrupt after shutdown gracefully + - crypto: talitos - move struct talitos_edesc into talitos.h + - crypto: talitos - fix hash on SEC1. + - regmap-irq: do not write mask register if mask_base is zero + - MIPS: ath79: fix ar933x uart parity mode + - MIPS: fix build on non-linux hosts + - arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly + - scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported + - dmaengine: imx-sdma: fix use-after-free on probe error path + - wil6210: fix potential out-of-bounds read + - ath10k: Do not send probe response template for mesh + - ath9k: Check for errors when reading SREV register + - ath6kl: add some bounds checking + - ath: DFS JP domain W56 fixed pulse type 3 RADAR detection + - batman-adv: fix for leaked TVLV handler. + - media: dvb: usb: fix use after free in dvb_usb_device_exit + - media: spi: IR LED: add missing of table registration + - crypto: talitos - fix skcipher failure due to wrong output IV + - media: marvell-ccic: fix DMA s/g desc number calculation + - media: vpss: fix a potential NULL pointer dereference + - media: media_device_enum_links32: clean a reserved field + - net: stmmac: dwmac1000: Clear unused address entries + - net: stmmac: dwmac4/5: Clear unused address entries + - qed: Set the doorbell address correctly + - signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig + - af_key: fix leaks in key_pol_get_resp and dump_sp. + - xfrm: Fix xfrm sel prefix length validation + - fscrypt: clean up some BUG_ON()s in block encryption/decryption + - media: mc-device.c: don't memset __user pointer contents + - media: staging: media: davinci_vpfe: - Fix for memory leak if decoder + initialization fails. + - net: phy: Check against net_device being NULL + - crypto: talitos - properly handle split ICV. + - crypto: talitos - Align SEC1 accesses to 32 bits boundaries. + - tua6100: Avoid build warnings. + - locking/lockdep: Fix merging of hlocks with non-zero references + - media: wl128x: Fix some error handling in fm_v4l2_init_video_device() + - cpupower : frequency-set -r option misses the last cpu in related cpu list + - net: stmmac: dwmac4: fix flow control issue + - net: fec: Do not use netdev messages too early + - net: axienet: Fix race condition causing TX hang + - s390/qdio: handle PENDING state for QEBSM devices + - RAS/CEC: Fix pfn insertion + - net: sfp: add mutex to prevent concurrent state checks + - ipset: Fix memory accounting for hash types on resize + - perf cs-etm: Properly set the value of 'old' and 'head' in snapshot mode + - perf tests: Add valid callback for parse-events test + - perf test 6: Fix missing kvm module load for s390 + - media: fdp1: Support M3N and E3 platforms + - iommu: Fix a leak in iommu_insert_resv_region + - gpio: omap: fix lack of irqstatus_raw0 for OMAP4 + - gpio: omap: ensure irq is enabled before wakeup + - regmap: fix bulk writes on paged registers + - bpf: silence warning messages in core + - rcu: Force inlining of rcu_read_lock() + - x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS + - blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership + arbitration + - xfrm: fix sa selector validation + - sched/core: Add __sched tag for io_schedule() + - x86/atomic: Fix smp_mb__{before,after}_atomic() + - perf evsel: Make perf_evsel__name() accept a NULL argument + - vhost_net: disable zerocopy by default + - ipoib: correcly show a VF hardware address + - EDAC/sysfs: Fix memory leak when creating a csrow object + - ipsec: select crypto ciphers for xfrm_algo + - ipvs: defer hook registration to avoid leaks + - media: s5p-mfc: Make additional clocks optional + - media: i2c: fix warning same module names + - ntp: Limit TAI-UTC offset + - timer_list: Guard procfs specific code + - acpi/arm64: ignore 5.1 FADTs that are reported as 5.0 + - media: coda: fix mpeg2 sequence number handling + - media: coda: fix last buffer handling in V4L2_ENC_CMD_STOP + - media: coda: increment sequence offset for the last returned frame + - media: vimc: cap: check v4l2_fill_pixfmt return value + - media: hdpvr: fix locking and a missing msleep + - rtlwifi: rtl8192cu: fix error handle when usb probe failed + - mt7601u: do not schedule rx_tasklet when the device has been disconnected + - x86/build: Add 'set -e' to mkcapflags.sh to delete broken capflags.c + - mt7601u: fix possible memory leak when the device is disconnected + - ipvs: fix tinfo memory leak in start_sync_thread + - ath10k: add missing error handling + - ath10k: fix PCIE device wake up failed + - perf tools: Increase MAX_NR_CPUS and MAX_CACHES + - libata: don't request sense data on !ZAC ATA devices + - clocksource/drivers/exynos_mct: Increase priority over ARM arch timer + - rslib: Fix decoding of shortened codes + - rslib: Fix handling of of caller provided syndrome + - ixgbe: Check DDM existence in transceiver before access + - crypto: serpent - mark __serpent_setkey_sbox noinline + - crypto: asymmetric_keys - select CRYPTO_HASH where needed + - EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec + - bcache: check c->gc_thread by IS_ERR_OR_NULL in cache_set_flush() + - net: hns3: fix a -Wformat-nonliteral compile warning + - net: hns3: add some error checking in hclge_tm module + - ath10k: destroy sdio workqueue while remove sdio module + - iwlwifi: mvm: Drop large non sta frames + - perf stat: Make metric event lookup more robust + - net: usb: asix: init MAC address buffers + - gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants + - Bluetooth: hci_bcsp: Fix memory leak in rx_skb + - Bluetooth: 6lowpan: search for destination address in all peers + - Bluetooth: Check state in l2cap_disconnect_rsp + - gtp: add missing gtp_encap_disable_sock() in gtp_encap_enable() + - Bluetooth: validate BLE connection interval updates + - gtp: fix suspicious RCU usage + - gtp: fix Illegal context switch in RCU read-side critical section. + - gtp: fix use-after-free in gtp_encap_destroy() + - gtp: fix use-after-free in gtp_newlink() + - net: mvmdio: defer probe of orion-mdio if a clock is not ready + - iavf: fix dereference of null rx_buffer pointer + - floppy: fix out-of-bounds read in next_valid_format + - floppy: fix invalid pointer dereference in drive_name + - xen: let alloc_xenballooned_pages() fail if not enough memory free + - scsi: NCR5380: Reduce goto statements in NCR5380_select() + - scsi: NCR5380: Always re-enable reselection interrupt + - Revert "scsi: ncr5380: Increase register polling limit" + - scsi: core: Fix race on creating sense cache + - scsi: megaraid_sas: Fix calculation of target ID + - scsi: mac_scsi: Increase PIO/PDMA transfer length threshold + - scsi: mac_scsi: Fix pseudo DMA implementation, take 2 + - crypto: ghash - fix unaligned memory access in ghash_setkey() + - crypto: ccp - Validate the the error value used to index error messages + - crypto: arm64/sha1-ce - correct digest for empty data in finup + - crypto: arm64/sha2-ce - correct digest for empty data in finup + - crypto: chacha20poly1305 - fix atomic sleep when using async algorithm + - crypto: ccp - memset structure fields to zero before reuse + - crypto: ccp/gcm - use const time tag comparison. + - crypto: crypto4xx - fix a potential double free in ppc4xx_trng_probe + - Input: gtco - bounds check collection indent level + - Input: alps - don't handle ALPS cs19 trackpoint-only device + - Input: synaptics - whitelist Lenovo T580 SMBus intertouch + - Input: alps - fix a mismatch between a condition check and its comment + - regulator: s2mps11: Fix buck7 and buck8 wrong voltages + - arm64: tegra: Update Jetson TX1 GPU regulator timings + - iwlwifi: pcie: don't service an interrupt that was masked + - iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X + - NFSv4: Handle the special Linux file open access mode + - pnfs/flexfiles: Fix PTR_ERR() dereferences in ff_layout_track_ds_error + - lib/scatterlist: Fix mapping iterator when sg->offset is greater than + PAGE_SIZE + - ASoC: dapm: Adapt for debugfs API change + - ALSA: seq: Break too long mutex context in the write loop + - media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() + - media: coda: Remove unbalanced and unneeded mutex unlock + - KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed + - arm64: tegra: Fix AGIC register range + - fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys + inodes. + - drm/nouveau/i2c: Enable i2c pads & busses during preinit + - padata: use smp_mb in padata_reorder to avoid orphaned padata jobs + - dm zoned: fix zone state management race + - xen/events: fix binding user event channels to cpus + - 9p/xen: Add cleanup path in p9_trans_xen_init + - 9p/virtio: Add cleanup path in p9_virtio_init + - x86/boot: Fix memory leak in default_get_smp_config() + - perf/x86/amd/uncore: Do not set 'ThreadMask' and 'SliceMask' for non-L3 PMCs + - perf/x86/amd/uncore: Set the thread mask for F17h L3 PMCs + - intel_th: pci: Add Ice Lake NNPI support + - PCI: Do not poll for PME if the device is in D3cold + - Btrfs: fix data loss after inode eviction, renaming it, and fsync it + - Btrfs: fix fsync not persisting dentry deletions due to inode evictions + - Btrfs: add missing inode version, ctime and mtime updates when punching hole + - HID: wacom: generic: only switch the mode on devices with LEDs + - HID: wacom: correct touch resolution x/y typo + - libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields + - coda: pass the host file in vma->vm_file on mmap + - gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM + - PCI: hv: Fix a use-after-free bug in hv_eject_device_work() + - crypto: caam - limit output IV to CBC to work around CTR mode DMA issue + - parisc: Ensure userspace privilege for ptraced processes in regset functions + - parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 + - powerpc/32s: fix suspend/resume when IBATs 4-7 are used + - powerpc/watchpoint: Restore NV GPRs while returning from exception + - eCryptfs: fix a couple type promotion bugs + - intel_th: msu: Fix single mode with disabled IOMMU + - Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug + - usb: Handle USB3 remote wakeup for LPM enabled devices correctly + - net: mvmdio: allow up to four clocks to be specified for orion-mdio + - dt-bindings: allow up to four clocks for orion-mdio + - dm bufio: fix deadlock with loop device + - compiler.h, kasan: Avoid duplicating __read_once_size_nocheck() + - compiler.h: Add read_word_at_a_time() function. + - lib/strscpy: Shut up KASAN false-positives in strscpy() + - bnx2x: Prevent load reordering in tx completion processing + - caif-hsi: fix possible deadlock in cfhsi_exit_module() + - igmp: fix memory leak in igmpv3_del_delrec() + - ipv4: don't set IPv6 only flags to IPv4 addresses + - net: bcmgenet: use promisc for unsupported filters + - net: dsa: mv88e6xxx: wait after reset deactivation + - net: neigh: fix multiple neigh timer scheduling + - net: openvswitch: fix csum updates for MPLS actions + - nfc: fix potential illegal memory access + - rxrpc: Fix send on a connected, but unbound socket + - sky2: Disable MSI on ASUS P6T + - vrf: make sure skb->data contains ip header to make routing + - macsec: fix use-after-free of skb during RX + - macsec: fix checksumming after decryption + - netrom: fix a memory leak in nr_rx_frame() + - netrom: hold sock when setting skb->destructor + - bonding: validate ip header before check IPPROTO_IGMP + - net: make skb_dst_force return true when dst is refcounted + - tcp: fix tcp_set_congestion_control() use from bpf hook + - tcp: Reset bytes_acked and bytes_received when disconnecting + - net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling + - net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query + - net: bridge: stp: don't cache eth dest pointer before skb pull + - dma-buf: balance refcount inbalance + - dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc + - MIPS: lb60: Fix pin mappings + - ext4: don't allow any modifications to an immutable file + - ext4: enforce the immutable flag on open files + - mm: add filemap_fdatawait_range_keep_errors() + - jbd2: introduce jbd2_inode dirty range scoping + - ext4: use jbd2_inode dirty range scoping + - ext4: allow directory holes + - mm: vmscan: scan anonymous pages on file refaults + - hvsock: fix epollout hang from race condition + - drm/panel: simple: Fix panel_simple_dsi_probe + - usb: core: hub: Disable hub-initiated U1/U2 + - tty: max310x: Fix invalid baudrate divisors calculator + - pinctrl: rockchip: fix leaked of_node references + - tty: serial: cpm_uart - fix init when SMC is relocated + - drm/edid: Fix a missing-check bug in drm_load_edid_firmware() + - PCI: Return error if cannot probe VF + - drm/bridge: tc358767: read display_props in get_modes() + - drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz + - drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry + - memstick: Fix error cleanup path of memstick_init + - tty/serial: digicolor: Fix digicolor-usart already registered warning + - tty: serial: msm_serial: avoid system lockup condition + - serial: 8250: Fix TX interrupt handling condition + - drm/virtio: Add memory barriers for capset cache. + - phy: renesas: rcar-gen2: Fix memory leak at error paths + - powerpc/pseries/mobility: prevent cpu hotplug during DT update + - drm/rockchip: Properly adjust to a true clock in adjusted_mode + - tty: serial_core: Set port active bit in uart_port_activate + - usb: gadget: Zero ffs_io_data + - powerpc/pci/of: Fix OF flags parsing for 64bit BARs + - drm/msm: Depopulate platform on probe failure + - serial: mctrl_gpio: Check if GPIO property exisits before requesting it + - PCI: sysfs: Ignore lockdep for remove attribute + - kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS + - PCI: xilinx-nwl: Fix Multi MSI data programming + - iio: iio-utils: Fix possible incorrect mask calculation + - powerpc/xmon: Fix disabling tracing while in xmon + - recordmcount: Fix spurious mcount entries on powerpc + - mfd: core: Set fwnode for created devices + - mfd: arizona: Fix undefined behavior + - mfd: hi655x-pmic: Fix missing return value check for + devm_regmap_init_mmio_clk + - um: Silence lockdep complaint about mmap_sem + - powerpc/4xx/uic: clear pending interrupt after irq type/pol change + - RDMA/i40iw: Set queue pair state when being queried + - serial: sh-sci: Terminate TX DMA during buffer flushing + - serial: sh-sci: Fix TX DMA buffer flushing and workqueue races + - kallsyms: exclude kasan local symbols on s390 + - perf test mmap-thread-lookup: Initialize variable to suppress memory + sanitizer warning + - perf session: Fix potential NULL pointer dereference found by the smatch + tool + - perf annotate: Fix dereferencing freed memory found by the smatch tool + - RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM + - PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB + - powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h + - f2fs: avoid out-of-range memory access + - mailbox: handle failed named mailbox channel request + - powerpc/eeh: Handle hugepages in ioremap space + - block/bio-integrity: fix a memory leak bug + - sh: prevent warnings when using iounmap + - mm/kmemleak.c: fix check for softirq context + - 9p: pass the correct prototype to read_cache_page + - mm/gup.c: mark undo_dev_pagemap as __maybe_unused + - mm/gup.c: remove some BUG_ONs from get_gate_page() + - mm/mmu_notifier: use hlist_add_head_rcu() + - locking/lockdep: Fix lock used or unused stats error + - locking/lockdep: Hide unused 'class' variable + - drm/crc: Only report a single overflow when a CRC fd is opened + - drm/crc-debugfs: Also sprinkle irqrestore over early exits + - usb: wusbcore: fix unbalanced get/put cluster_id + - usb: pci-quirks: Correct AMD PLL quirk detection + - KVM: nVMX: do not use dangling shadow VMCS after guest reset + - btrfs: inode: Don't compress if NODATASUM or NODATACOW set + - x86/sysfb_efi: Add quirks for some devices with swapped width and height + - x86/speculation/mds: Apply more accurate check on hypervisor platform + - binder: prevent transactions to context manager from its own process. + - fpga-manager: altera-ps-spi: Fix build error + - hpet: Fix division by zero in hpet_time_div() + - powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask() + - powerpc/tm: Fix oops on sigreturn on systems without TM + - access: avoid the RCU grace period for the temporary subjective credentials + - batman-adv: Fix duplicated OGMs on NETDEV_UP + - net: hns3: set ops to null when unregister ad_dev + - x86/cpu: Add Ice Lake NNPI to Intel family + - qed: iWARP - Fix tc for MPA ll2 connection + - net: hns3: fix for skb leak when doing selftest + - sched/fair: Fix "runnable_avg_yN_inv" not used warnings + - x86/cacheinfo: Fix a -Wtype-limits warning + - nvme-pci: properly report state change failure in nvme_reset_work + - nvme-pci: set the errno on ctrl state change error + - arm64: Do not enable IRQs for ct_user_exit + - net: stmmac: sun8i: force select external PHY when no internal one + - bcache: check CACHE_SET_IO_DISABLE in allocator code + - bcache: check CACHE_SET_IO_DISABLE bit in bch_journal() + - bcache: acquire bch_register_lock later in cached_dev_free() + - bcache: fix potential deadlock in cached_def_free() + - perf stat: Fix group lookup for metric group + - tools: bpftool: Fix json dump crash on powerpc + - Bluetooth: Add a new 13d3:3496 QCA_ROME device + - Bluetooth: Add new 13d3:3491 QCA_ROME device + - Bluetooth: Add new 13d3:3501 QCA_ROME device + - bcache: ignore read-ahead request failure on backing device + - bcache: fix mistaken sysfs entry for io_error counter + - bcache: destroy dc->writeback_write_wq if failed to create + dc->writeback_thread + - iwlwifi: don't WARN when calling iwl_get_shared_mem_conf with RF-Kill + - iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices + - ALSA: hda/realtek - Fixed Headphone Mic can't record on Dell platform + - media: videobuf2-core: Prevent size alignment wrapping buffer size to 0 + - media: videobuf2-dma-sg: Prevent size from overflowing + - perf/x86/intel: Fix spurious NMI on fixed counter + - drm/edid: parse CEA blocks embedded in DisplayID + - PCI: qcom: Ensure that PERST is asserted for at least 100 ms + - IB/mlx5: Report correctly tag matching rendezvous capability + - include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT + architectures + - xfs: fix pagecache truncation prior to reflink + - xfs: flush removing page cache in xfs_reflink_remap_prep + - xfs: don't overflow xattr listent buffer + - xfs: don't ever put nlink > 0 inodes on the unlinked list + - xfs: fix reporting supported extra file attributes for statx() + - xfs: serialize unaligned dio writes against all other dio writes + - xfs: abort unaligned nowait directio early + - powerpc/powernv/npu: Fix reference leak + - powerpc/pseries: Fix oops in hotplug memory notifier + - mmc: sdhci-msm: fix mutex while in spinlock + - mtd: rawnand: mtk: Correct low level time calculation of r/w cycle + - blk-throttle: fix zero wait time for iops throttled group + - tcp: be more careful in tcp_fragment() + - net/mlx5e: IPoIB, Add error path in mlx5_rdma_setup_rn + - net_sched: unset TCQ_F_CAN_BYPASS when adding filters + - net: bridge: don't cache ether dest pointer on input + - net: sched: verify that q!=NULL before setting q->flags + * Line 6 POD HD500 driver fault (LP: #1790595) // Bionic update: upstream + stable patchset 2019-08-05 (LP: #1839036) + - ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1 + * Bionic update: upstream stable patchset 2019-08-02 (LP: #1838824) + - rapidio: fix a NULL pointer dereference when create_workqueue() fails + - fs/fat/file.c: issue flush after the writeback of FAT + - sysctl: return -EINVAL if val violates minmax + - ipc: prevent lockup on alloc_msg and free_msg + - ARM: prevent tracing IPI_CPU_BACKTRACE + - mm/hmm: select mmu notifier when selecting HMM + - hugetlbfs: on restore reserve error path retain subpool reservation + - mem-hotplug: fix node spanned pages when we have a node with only + ZONE_MOVABLE + - mm/cma.c: fix crash on CMA allocation if bitmap allocation fails + - mm/cma.c: fix the bitmap status to show failed allocation reason + - mm/cma_debug.c: fix the break condition in cma_maxchunk_get() + - mm/slab.c: fix an infinite loop in leaks_show() + - kernel/sys.c: prctl: fix false positive in validate_prctl_map() + - thermal: rcar_gen3_thermal: disable interrupt in .remove + - drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER + - mfd: tps65912-spi: Add missing of table registration + - mfd: intel-lpss: Set the device in reset state when init + - drm/nouveau/disp/dp: respect sink limits when selecting failsafe link + configuration + - mfd: twl6040: Fix device init errors for ACCCTL register + - perf/x86/intel: Allow PEBS multi-entry in watermark mode + - drm/bridge: adv7511: Fix low refresh rate selection + - objtool: Don't use ignore flag for fake jumps + - EDAC/mpc85xx: Prevent building as a module + - pwm: meson: Use the spin-lock only to protect register modifications + - ntp: Allow TAI-UTC offset to be set to zero + - f2fs: fix to avoid panic in do_recover_data() + - f2fs: fix to clear dirty inode in error path of f2fs_iget() + - f2fs: fix to avoid panic in dec_valid_block_count() + - f2fs: fix to do sanity check on valid block count of segment + - percpu: remove spurious lock dependency between percpu and sched + - configfs: fix possible use-after-free in configfs_register_group + - uml: fix a boot splat wrt use of cpu_all_mask + - mmc: mmci: Prevent polling for busy detection in IRQ context + - watchdog: imx2_wdt: Fix set_timeout for big timeout values + - watchdog: fix compile time error of pretimeout governors + - blk-mq: move cancel of requeue_work into blk_mq_release + - iommu/vt-d: Set intel_iommu_gfx_mapped correctly + - misc: pci_endpoint_test: Fix test_reg_bar to be updated in pci_endpoint_test + - nvme-pci: unquiesce admin queue on shutdown + - ALSA: hda - Register irq handler after the chip initialization + - nvmem: core: fix read buffer in place + - fuse: retrieve: cap requested size to negotiated max_write + - nfsd: allow fh_want_write to be called twice + - vfio: Fix WARNING "do not call blocking ops when !TASK_RUNNING" + - x86/PCI: Fix PCI IRQ routing table memory leak + - platform/chrome: cros_ec_proto: check for NULL transfer function + - PCI: keystone: Prevent ARM32 specific code to be compiled for ARM64 + - soc: mediatek: pwrap: Zero initialize rdata in pwrap_init_cipher + - clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 + - soc: rockchip: Set the proper PWM for rk3288 + - ARM: dts: imx51: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx50: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx53: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx7d: Specify IMX7D_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6ul: Specify IMX6UL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6qdl: Specify IMX6QDL_CLK_IPG as "ipg" clock to SDMA + - PCI: rpadlpar: Fix leaked device_node references in add/remove paths + - platform/x86: intel_pmc_ipc: adding error handling + - power: supply: max14656: fix potential use-before-alloc + - PCI: rcar: Fix a potential NULL pointer dereference + - PCI: rcar: Fix 64bit MSI message address handling + - video: hgafb: fix potential NULL pointer dereference + - video: imsttfb: fix potential NULL pointer dereferences + - block, bfq: increase idling for weight-raised queues + - PCI: xilinx: Check for __get_free_pages() failure + - gpio: gpio-omap: add check for off wake capable gpios + - dmaengine: idma64: Use actual device for DMA transfers + - pwm: tiehrpwm: Update shadow register for disabling PWMs + - ARM: dts: exynos: Always enable necessary APIO_1V8 and ABB_1V8 regulators on + Arndale Octa + - pwm: Fix deadlock warning when removing PWM device + - ARM: exynos: Fix undefined instruction during Exynos5422 resume + - usb: typec: fusb302: Check vconn is off when we start toggling + - gpio: vf610: Do not share irq_chip + - percpu: do not search past bitmap when allocating an area + - drm: don't block fb changes for async plane updates + - ALSA: seq: Cover unsubscribe_port() in list_mutex + - initramfs: free initrd memory if opening /initrd.image fails + - bpf: fix undefined behavior in narrow load handling + - f2fs: fix to avoid panic in f2fs_remove_inode_page() + - f2fs: fix to use inline space only if inline_xattr is enable + - netfilter: nf_conntrack_h323: restore boundary check correctness + - mips: Make sure dt memory regions are valid + - nvmem: sunxi_sid: Support SID on A83T and H5 + - nfsd: avoid uninitialized variable warning + - switchtec: Fix unintended mask of MRPC event + - net: thunderbolt: Unregister ThunderboltIP protocol handler when suspending + - i40e: Queues are reserved despite "Invalid argument" error + - net: hns3: return 0 and print warning when hit duplicate MAC + - soc: renesas: Identify R-Car M3-W ES1.1 + - soc: renesas: Identify R-Car M3-W ES1.3 + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + - drm/nouveau: add kconfig option to turn off nouveau legacy contexts. (v3) + - nouveau: Fix build with CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT disabled + - HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth + - HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary + - ALSA: oxfw: allow PCM capture for Stanton SCS.1m + - ALSA: hda/realtek - Update headset mode for ALC256 + - ALSA: firewire-motu: fix destruction of data for isochronous resources + - libata: Extend quirks for the ST1000LM024 drives with NOLPM quirk + - mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node + - fs/ocfs2: fix race in ocfs2_dentry_attach_lock() + - mm/vmscan.c: fix trying to reclaim unevictable LRU page + - signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO + - ptrace: restore smp_rmb() in __ptrace_may_access() + - media: v4l2-ioctl: clear fields in s_parm + - iommu/arm-smmu: Avoid constant zero in TLBI writes + - i2c: acorn: fix i2c warning + - bcache: fix stack corruption by PRECEDING_KEY() + - cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() + - ASoC: cs42xx8: Add regcache mask dirty + - ASoC: fsl_asrc: Fix the issue about unsupported rate + - drm/i915/sdvo: Implement proper HDMI audio support for SDVO + - x86/uaccess, kcov: Disable stack protector + - ALSA: seq: Protect in-kernel ioctl calls with mutex + - ALSA: seq: Fix race of get-subscription call vs port-delete ioctls + - Revert "ALSA: seq: Protect in-kernel ioctl calls with mutex" + - s390/kasan: fix strncpy_from_user kasan checks + - Drivers: misc: fix out-of-bounds access in function param_set_kgdbts_var + - scsi: qedi: remove memset/memcpy to nfunc and use func instead + - scsi: qedi: remove set but not used variables 'cdev' and 'udev' + - scsi: lpfc: add check for loss of ndlp when sending RRQ + - arm64/mm: Inhibit huge-vmap with ptdump + - nvme: remove the ifdef around nvme_nvm_ioctl + - platform/x86: pmc_atom: Add Lex 3I380D industrial PC to critclk_systems DMI + table + - platform/x86: pmc_atom: Add several Beckhoff Automation boards to + critclk_systems DMI table + - scsi: bnx2fc: fix incorrect cast to u64 on shift operation + - libnvdimm: Fix compilation warnings with W=1 + - selftests/timers: Add missing fflush(stdout) calls + - usbnet: ipheth: fix racing condition + - KVM: x86/pmu: do not mask the value that is written to fixed PMUs + - KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION + - drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an + invalid read + - drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define() + - usb: dwc2: Fix DMA cache alignment issues + - usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression) + - USB: Fix chipmunk-like voice when using Logitech C270 for recording audio. + - USB: serial: pl2303: add Allied Telesis VT-Kit3 + - USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode + - USB: serial: option: add Telit 0x1260 and 0x1261 compositions + - RAS/CEC: Fix binary search function + - x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback + - x86/kasan: Fix boot with 5-level paging and KASAN + - rtc: pcf8523: don't return invalid date when battery is low + - HID: wacom: Don't set tool type until we're in range + - HID: wacom: Don't report anything prior to the tool entering range + - HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact + - bcache: only set BCACHE_DEV_WB_RUNNING when cached device attached + - f2fs: fix to avoid accessing xattr across the boundary + - nvme: fix srcu locking on error return in nvme_get_ns_from_disk + - nvme: merge nvme_ns_ioctl into nvme_ioctl + - nvme: release namespace SRCU protection before performing controller ioctls + - nvme: fix memory leak for power latency tolerance + - KVM: x86/pmu: mask the result of rdpmc according to the width of the + counters + - tools/kvm_stat: fix fields filter for child events + - RAS/CEC: Convert the timer callback to a workqueue + - x86/mm/KASLR: Compute the size of the vmemmap section properly + - ax25: fix inconsistent lock state in ax25_destroy_timer + - be2net: Fix number of Rx queues used for flow hashing + - ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero + - lapb: fixed leak of control-blocks. + - neigh: fix use-after-free read in pneigh_get_next + - net: openvswitch: do not free vport if register_netdevice() is failed. + - sctp: Free cookie before we memdup a new one + - sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg + - Staging: vc04_services: Fix a couple error codes + - perf/x86/intel/ds: Fix EVENT vs. UEVENT PEBS constraints + - netfilter: nf_queue: fix reinject verdict handling + - ipvs: Fix use-after-free in ip_vs_in + - selftests: netfilter: missing error check when setting up veth interface + - clk: ti: clkctrl: Fix clkdm_clk handling + - powerpc/powernv: Return for invalid IMC domain + - mISDN: make sure device name is NUL terminated + - x86/CPU/AMD: Don't force the CPB cap when running under a hypervisor + - perf/ring_buffer: Fix exposing a temporarily decreased data_head + - perf/ring_buffer: Add ordering to rb->nest increment + - perf/ring-buffer: Always use {READ,WRITE}_ONCE() for rb->user_page data + - gpio: fix gpio-adp5588 build errors + - net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() + - net: aquantia: fix LRO with FCS error + - i2c: dev: fix potential memory leak in i2cdev_ioctl_rdwr + - ALSA: hda - Force polling mode on CNL for fixing codec communication + - configfs: Fix use-after-free when accessing sd->s_dentry + - perf data: Fix 'strncat may truncate' build failure with recent gcc + - perf record: Fix s390 missing module symbol and warning for non-root users + - ia64: fix build errors by exporting paddr_to_nid() + - KVM: PPC: Book3S: Use new mutex to synchronize access to rtas token list + - KVM: PPC: Book3S HV: Don't take kvm->lock around kvm_for_each_vcpu + - net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs + - net: phy: dp83867: Set up RGMII TX delay + - scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() + - scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask + - scsi: scsi_dh_alua: Fix possible null-ptr-deref + - scsi: libsas: delete sas port if expander discover failed + - mlxsw: spectrum: Prevent force of 56G + - coredump: fix race condition between collapse_huge_page() and core dumping + - infiniband: fix race condition between infiniband mlx4, mlx5 driver and core + dumping + - Abort file_remove_privs() for non-reg. files + - tipc: purge deferredq list for each grp member in tipc_group_delete + - vsock/virtio: set SOCK_DONE on peer shutdown + - usb: xhci: Fix a potential null pointer dereference in + xhci_debugfs_create_endpoint() + - ACPI/PCI: PM: Add missing wakeup.flags.valid checks + - drm/etnaviv: lock MMU while dumping core + - net: aquantia: tx clean budget logic error + - perf namespace: Protect reading thread's namespace + - xen/pvcalls: Remove set but not used variable + - xen: xenbus: Catch closing of non existent transactions + - xen: xenbus_dev_frontend: Verify body of XS_TRANSACTION_END + - xenbus: Avoid deadlock during suspend due to open transactions + - tracing: Silence GCC 9 array bounds warning + - objtool: Support per-function rodata sections + - gcc-9: silence 'address-of-packed-member' warning + - net: phy: broadcom: Use strlcpy() for ethtool::get_strings + - mmc: core: Prevent processing SDIO IRQs when the card is suspended + - scsi: ufs: Avoid runtime suspend possibly being blocked forever + - usb: chipidea: udc: workaround for endpoint conflict issue + - IB/hfi1: Silence txreq allocation warnings + - Input: synaptics - enable SMBus on ThinkPad E480 and E580 + - Input: uinput - add compat ioctl number translation for UI_*_FF_UPLOAD + - apparmor: enforce nullbyte at end of tag string + - ARC: fix build warnings + - ARC: [plat-hsdk]: Add missing multicast filter bins number to GMAC node + - ARC: [plat-hsdk]: Add missing FIFO size entry in GMAC node + - parport: Fix mem leak in parport_register_dev_model + - parisc: Fix compiler warnings in float emulation code + - IB/rdmavt: Fix alloc_qpn() WARN_ON() + - IB/hfi1: Insure freeze_work work_struct is canceled on shutdown + - IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value + - IB/hfi1: Validate page aligned for a given virtual address + - MIPS: uprobes: remove set but not used variable 'epc' + - xtensa: Fix section mismatch between memblock_reserve and mem_reserve + - net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0 + - net: hns: Fix loopback test failed at copper ports + - mdesc: fix a missing-check bug in get_vdev_port_node_info() + - sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD + - net: ethernet: mediatek: Use hw_feature to judge if HWLRO is supported + - net: ethernet: mediatek: Use NET_IP_ALIGN to judge if HW RX_2BYTE_OFFSET is + enabled + - drm/arm/hdlcd: Actually validate CRTC modes + - drm/arm/hdlcd: Allow a bit of clock tolerance + - scripts/checkstack.pl: Fix arm64 wrong or unknown architecture + - scsi: ufs: Check that space was properly alloced in copy_query_response + - scsi: smartpqi: unlock on error in pqi_submit_raid_request_synchronous() + - net: ipvlan: Fix ipvlan device tso disabled while NETIF_F_IP_CSUM is set + - s390/qeth: fix VLAN attribute in bridge_hostnotify udev event + - hwmon: (core) add thermal sensors only if dev->of_node is present + - hwmon: (pmbus/core) Treat parameters as paged if on multiple pages + - nvme: Fix u32 overflow in the number of namespace list calculation + - btrfs: start readahead also in seed devices + - can: flexcan: fix timeout when set small bitrate + - can: purge socket error queue on sock destruct + - powerpc/bpf: use unsigned division instruction for 64-bit operations + - ARM: imx: cpuidle-imx6sx: Restrict the SW2ISO increase to i.MX6SX + - ARM: dts: am57xx-idk: Remove support for voltage switching for SD card + - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections + - Bluetooth: Fix regression with minimum encryption key size alignment + - SMB3: retry on STATUS_INSUFFICIENT_RESOURCES instead of failing write + - cfg80211: fix memory leak of wiphy device name + - mac80211: drop robust management frames from unknown TA + - mac80211: handle deauthentication/disassociation from TDLS peer + - mac80211: Do not use stack memory with scatterlist for GMAC + - s390/jump_label: Use "jdd" constraint on gcc9 + - s390/ap: rework assembler functions to use unions for in/out register + variables + - mmc: core: API to temporarily disable retuning for SDIO CRC errors + - mmc: core: Add sdio_retune_hold_now() and sdio_retune_release() + - Input: silead - add MSSL0017 to acpi_device_id + - selftests: vm: install test_vmalloc.sh for run_vmtests + - arm64: Silence gcc warnings about arch ABI drift + - riscv: mm: synchronize MMU after pte change + - arm64/sve: should not depend on + - drm/vmwgfx: Use the backdoor port if the HB port is not available + - {nl,mac}80211: allow 4addr AP operation on crypto controlled devices + - perf ui helpline: Use strlcpy() as a shorter form of strncpy() + explicit + set nul + - perf help: Remove needless use of strncpy() + - perf header: Fix unchecked usage of strncpy() + - IB/hfi1: Close PSM sdma_progress sleep window + - 9p/xen: fix check for xenbus_read error in front_probe + - 9p/rdma: do not disconnect on down_interruptible EAGAIN + - 9p: acl: fix uninitialized iattr access + - 9p/rdma: remove useless check in cm_event_handler + - 9p: p9dirent_read: check network-provided name length + - net/9p: include trans_common.h to fix missing prototype warning. + - qmi_wwan: Fix out-of-bounds read + - fs/proc/array.c: allow reporting eip/esp for all coredumping threads + - mm/mempolicy.c: fix an incorrect rebind node in mpol_rebind_nodemask + - fs/binfmt_flat.c: make load_flat_shared_library() work + - dm log writes: make sure super sector log updates are written in order + - scsi: vmw_pscsi: Fix use-after-free in pvscsi_queue_lck() + - x86/speculation: Allow guests to use SSBD even if host does not + - x86/microcode: Fix the microcode load on CPU hotplug for real + - NFS/flexfiles: Use the correct TCP timeout for flexfiles I/O + - cpu/speculation: Warn on unsupported mitigations= parameter + - eeprom: at24: fix unexpected timeout under high load + - af_packet: Block execution of tasks waiting for transmit to complete in + AF_PACKET + - ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop + - net/packet: fix memory leak in packet_set_ring() + - net: remove duplicate fetch in sock_getsockopt + - net: stmmac: fixed new system time seconds value calculation + - sctp: change to hold sk after auth shkey is created successfully + - tipc: change to use register_pernet_device + - tipc: check msg->req data len in tipc_nl_compat_bearer_disable + - tun: wake up waitqueues after IFF_UP is set + - team: Always enable vlan tx offload + - bonding: Always enable vlan tx offload + - bpf: udp: Avoid calling reuseport's bpf_prog from udp_gro + - bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err + - arm64: futex: Avoid copying out uninitialised stack in failed cmpxchg() + - bpf, arm64: use more scalable stadd over ldxr / stxr loop in xadd + - futex: Update comments and docs about return values of arch futex code + - tipc: pass tunnel dev as NULL to udp_tunnel(6)_xmit_skb + - arm64: insn: Fix ldadd instruction encoding + - arm64: Don't unconditionally add -Wno-psabi to KBUILD_CFLAGS + - irqchip/mips-gic: Use the correct local interrupt map registers + - Bluetooth: Fix faulty expression for minimum encryption key size check + - ASoC : cs4265 : readable register too low + - ASoC: soc-pcm: BE dai needs prepare when pause release after resume + - spi: bitbang: Fix NULL pointer dereference in spi_unregister_master + - drm/mediatek: fix unbind functions + - drm/mediatek: call drm_atomic_helper_shutdown() when unbinding driver + - drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() + - ASoC: max98090: remove 24-bit format support if RJ is 0 + - ASoC: sun4i-i2s: Fix sun8i tx channel offset mask + - ASoC: sun4i-i2s: Add offset to RX channel select + - usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i] + - usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC + - SoC: rt274: Fix internal jack assignment in set_jack callback + - scsi: hpsa: correct ioaccel2 chaining + - platform/x86: mlx-platform: Fix parent device in i2c-mux-reg device + registration + - cpuset: restore sanity to cpuset_cpus_allowed_fallback() + - scripts/decode_stacktrace.sh: prefix addr2line with $CROSS_COMPILE + - mm/mlock.c: change count_mm_mlocked_page_nr return type + - module: Fix livepatch/ftrace module text permissions race + - ftrace: Fix NULL pointer dereference in free_ftrace_func_mapper() + - MIPS: netlogic: xlr: Remove erroneous check in nlm_fmn_send() + - drm/i915/dmc: protect against reading random memory + - crypto: user - prevent operating on larval algorithms + - crypto: cryptd - Fix skcipher instance memory leak + - ALSA: seq: fix incorrect order of dest_client/dest_ports arguments + - ALSA: firewire-lib/fireworks: fix miss detection of received MIDI messages + - ALSA: line6: Fix write on zero-sized buffer + - ALSA: usb-audio: fix sign unintended sign extension on left shifts + - ALSA: hda/realtek - Change front mic location for Lenovo M710q + - lib/mpi: Fix karactx leak in mpi_powm + - tracing/snapshot: Resize spare buffer if size changed + - arm64: kaslr: keep modules inside module region when KASAN is enabled + - drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE + - drm/imx: notify drm core before sending event during crtc disable + - drm/imx: only send event on crtc disable if kept disabled + - ftrace/x86: Remove possible deadlock between register_kprobe() and + ftrace_run_update_code() + - mm/vmscan.c: prevent useless kswapd loops + - btrfs: Ensure replaced device doesn't have pending chunk allocation + - vhost-net: set packet weight of tx polling to 2 * vq size + - vhost_net: use packet weight for rx handler, too + - vhost_net: introduce vhost_exceeds_weight() + - vhost: introduce vhost_exceeds_weight() + - vhost_net: fix possible infinite loop + - vhost: vsock: add weight support + - vhost: scsi: add weight support + - tty: rocket: fix incorrect forward declaration of 'rp_init()' + - KVM: x86: degrade WARN to pr_warn_ratelimited + - KVM: LAPIC: Fix pending interrupt in IRR blocked by software disable LAPIC + - svcrdma: Ignore source port when computing DRC hash + - MIPS: Fix bounds check virt_addr_valid + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence. + - dmaengine: imx-sdma: remove BD_INTR for channel0 + - drm/mediatek: unbind components in mtk_drm_unbind() + - drm/mediatek: clear num_pipes when unbind driver + - x86/CPU: Add more Icelake model numbers + - platform/x86: asus-wmi: Only Tell EC the OS will handle display hotkeys from + asus_nb_wmi + - platform/x86: intel-vbtn: Report switch events when event wakes device + - i2c: pca-platform: Fix GPIO lookup code + - ALSA: hda/realtek: Add quirks for several Clevo notebook barebones + - ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node + - drm/amd/powerplay: use hardware fan control if no powerplay fan table + - drm/etnaviv: add missing failure path to destroy suballoc + - mlxsw: spectrum: Handle VLAN device unlinking + - media: s5p-mfc: fix incorrect bus assignment in virtual child device + - net: hns: Fixes the missing put_device in positive leg for roce reset + - ALSA: hda: Initialize power_state field properly + - rds: Fix warning. + - ip6: fix skb leak in ip6frag_expire_frag_queue() + - netfilter: ipv6: nf_defrag: fix leakage of unqueued fragments + - sc16is7xx: move label 'err_spi' to correct section + - netfilter: ipv6: nf_defrag: accept duplicate fragments again + - nfsd: Fix overflow causing non-working mounts on 1 TB machines + - MIPS: have "plain" make calls build dtbs for selected platforms + - dmaengine: qcom: bam_dma: Fix completed descriptors count + * Bionic update: upstream stable patchset 2019-08-01 (LP: #1838700) + - x86: Hide the int3_emulate_call/jmp functions from UML + - ext4: do not delete unlinked inode from orphan list on failed truncate + - f2fs: Fix use of number of devices + - KVM: x86: fix return value for reserved EFER + - bio: fix improper use of smp_mb__before_atomic() + - sbitmap: fix improper use of smp_mb__before_atomic() + - Revert "scsi: sd: Keep disk read-only when re-reading partition" + - crypto: vmx - CTR: always increment IV as quadword + - mmc: sdhci-iproc: cygnus: Set NO_HISPD bit to fix HS50 data hold time + problem + - mmc: sdhci-iproc: Set NO_HISPD bit to fix HS50 data hold time problem + - kvm: svm/avic: fix off-by-one in checking host APIC ID + - libnvdimm/pmem: Bypass CONFIG_HARDENED_USERCOPY overhead + - arm64/iommu: handle non-remapped addresses in ->mmap and ->get_sgtable + - gfs2: Fix sign extension bug in gfs2_update_stats + - Btrfs: do not abort transaction at btrfs_update_root() after failure to COW + path + - Btrfs: avoid fallback to transaction commit during fsync of files with holes + - Btrfs: fix race between ranged fsync and writeback of adjacent ranges + - btrfs: sysfs: Fix error path kobject memory leak + - btrfs: sysfs: don't leak memory when failing add fsid + - fbdev: fix divide error in fb_var_to_videomode + - btrfs: honor path->skip_locking in backref code + - fbdev: fix WARNING in __alloc_pages_nodemask bug + - media: cpia2: Fix use-after-free in cpia2_exit + - media: serial_ir: Fix use-after-free in serial_ir_init_module + - media: vivid: use vfree() instead of kfree() for dev->bitmap_cap + - ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit + - bpf: devmap: fix use-after-free Read in __dev_map_entry_free + - batman-adv: mcast: fix multicast tt/tvlv worker locking + - at76c50x-usb: Don't register led_trigger if usb_register_driver failed + - net: erspan: fix use-after-free + - gfs2: Fix lru_count going negative + - cxgb4: Fix error path in cxgb4_init_module + - NFS: make nfs_match_client killable + - IB/hfi1: Fix WQ_MEM_RECLAIM warning + - gfs2: Fix occasional glock use-after-free + - mmc: core: Verify SD bus width + - tools/bpf: fix perf build error with uClibc (seen on ARC) + - dmaengine: tegra210-dma: free dma controller in remove() + - net: ena: gcc 8: fix compilation warning + - pinctrl: zte: fix leaked of_node references + - ASoC: hdmi-codec: unlock the device on startup errors + - powerpc/perf: Return accordingly on invalid chip-id in + - powerpc/boot: Fix missing check of lseek() return value + - ASoC: imx: fix fiq dependencies + - spi: pxa2xx: fix SCR (divisor) calculation + - brcm80211: potential NULL dereference in + brcmf_cfg80211_vndr_cmds_dcmd_handler() + - ACPI / property: fix handling of data_nodes in acpi_get_next_subnode() + - ARM: vdso: Remove dependency with the arch_timer driver internals + - arm64: Fix compiler warning from pte_unmap() with -Wunused-but-set-variable + - sched/cpufreq: Fix kobject memleak + - scsi: qla2xxx: Fix a qla24xx_enable_msix() error path + - scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() + - scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in + tcm_qla2xxx_close_session() + - Btrfs: fix data bytes_may_use underflow with fallocate due to failed quota + reserve + - btrfs: fix panic during relocation after ENOSPC before writeback happens + - btrfs: Don't panic when we can't find a root key + - iwlwifi: pcie: don't crash on invalid RX interrupt + - rtc: 88pm860x: prevent use-after-free on device remove + - scsi: qedi: Abort ep termination if offload not scheduled + - w1: fix the resume command API + - dmaengine: pl330: _stop: clear interrupt status + - mac80211/cfg80211: update bss channel on channel switch + - libbpf: fix samples/bpf build failure due to undefined UINT32_MAX + - ASoC: fsl_sai: Update is_slave_mode with correct value + - mwifiex: prevent an array overflow + - net: cw1200: fix a NULL pointer dereference + - crypto: sun4i-ss - Fix invalid calculation of hash end + - bcache: return error immediately in bch_journal_replay() + - bcache: fix failure in journal relplay + - bcache: add failure check to run_cache_set() for journal replay + - bcache: avoid clang -Wunintialized warning + - vfio-ccw: Do not call flush_workqueue while holding the spinlock + - vfio-ccw: Release any channel program when releasing/removing vfio-ccw mdev + - smpboot: Place the __percpu annotation correctly + - x86/mm: Remove in_nmi() warning from 64-bit implementation of + vmalloc_fault() + - mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC + versions + - HID: logitech-hidpp: use RAP instead of FAP to get the protocol version + - pinctrl: pistachio: fix leaked of_node references + - pinctrl: samsung: fix leaked of_node references + - clk: rockchip: undo several noc and special clocks as critical on rk3288 + - dmaengine: at_xdmac: remove BUG_ON macro in tasklet + - media: coda: clear error return value before picture run + - media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper + - media: au0828: stop video streaming only when last user stops + - media: ov2659: make S_FMT succeed even if requested format doesn't match + - audit: fix a memory leak bug + - media: stm32-dcmi: fix crash when subdev do not expose any formats + - media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable() + - media: pvrusb2: Prevent a buffer overflow + - powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX + - random: add a spinlock_t to struct batched_entropy + - cgroup: protect cgroup->nr_(dying_)descendants by css_set_lock + - sched/core: Check quota and period overflow at usec to nsec conversion + - sched/rt: Check integer overflow at usec to nsec conversion + - sched/core: Handle overflow in cpu_shares_write_u64 + - drm/msm: a5xx: fix possible object reference leak + - USB: core: Don't unbind interfaces following device reset failure + - x86/irq/64: Limit IST stack overflow check to #DB stack + - phy: sun4i-usb: Make sure to disable PHY0 passby for peripheral mode + - i40e: Able to add up to 16 MAC filters on an untrusted VF + - i40e: don't allow changes to HW VLAN stripping on active port VLANs + - arm64: vdso: Fix clock_getres() for CLOCK_REALTIME + - RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure + - hwmon: (vt1211) Use request_muxed_region for Super-IO accesses + - hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses + - hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses + - hwmon: (pc87427) Use request_muxed_region for Super-IO accesses + - hwmon: (f71805f) Use request_muxed_region for Super-IO accesses + - scsi: libsas: Do discovery on empty PHY to update PHY info + - mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers + - mmc_spi: add a status check for spi_sync_locked + - mmc: sdhci-of-esdhc: add erratum eSDHC5 support + - mmc: sdhci-of-esdhc: add erratum A-009204 support + - mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support + - drm/amdgpu: fix old fence check in amdgpu_fence_emit + - PM / core: Propagate dev->power.wakeup_path when no callbacks + - clk: rockchip: Fix video codec clocks on rk3288 + - extcon: arizona: Disable mic detect if running when driver is removed + - clk: rockchip: Make rkpwm a critical clock on rk3288 + - s390: zcrypt: initialize variables before_use + - x86/microcode: Fix the ancient deprecated microcode loading method + - s390: cio: fix cio_irb declaration + - cpufreq: ppc_cbe: fix possible object reference leak + - cpufreq/pasemi: fix possible object reference leak + - cpufreq: pmac32: fix possible object reference leak + - cpufreq: kirkwood: fix possible object reference leak + - block: sed-opal: fix IOC_OPAL_ENABLE_DISABLE_MBR + - x86/build: Keep local relocations with ld.lld + - iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion + - iio: hmc5843: fix potential NULL pointer dereferences + - iio: common: ssp_sensors: Initialize calculated_time in + ssp_common_process_data + - rtlwifi: fix a potential NULL pointer dereference + - mwifiex: Fix mem leak in mwifiex_tm_cmd + - brcmfmac: fix missing checks for kmemdup + - b43: shut up clang -Wuninitialized variable warning + - brcmfmac: convert dev_init_lock mutex to completion + - brcmfmac: fix WARNING during USB disconnect in case of unempty psq + - brcmfmac: fix race during disconnect when USB completion is in progress + - brcmfmac: fix Oops when bringing up interface during USB disconnect + - rtc: xgene: fix possible race condition + - rtlwifi: fix potential NULL pointer dereference + - scsi: ufs: Fix regulator load and icc-level configuration + - scsi: ufs: Avoid configuring regulator with undefined voltage range + - arm64: cpu_ops: fix a leaked reference by adding missing of_node_put + - x86/uaccess, signal: Fix AC=1 bloat + - x86/ia32: Fix ia32_restore_sigcontext() AC leak + - chardev: add additional check for minor range overlap + - RDMA/hns: Fix bad endianess of port_pd variable + - HID: core: move Usage Page concatenation to Main item + - ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put + - ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put + - cxgb3/l2t: Fix undefined behaviour + - HID: logitech-hidpp: change low battery level threshold from 31 to 30 + percent + - spi: tegra114: reset controller on probe + - kobject: Don't trigger kobject_uevent(KOBJ_REMOVE) twice. + - media: video-mux: fix null pointer dereferences + - media: wl128x: prevent two potential buffer overflows + - scsi: qedf: Add missing return in qedf_post_io_req() in the fcport offload + check + - virtio_console: initialize vtermno value for ports + - tty: ipwireless: fix missing checks for ioremap + - x86/mce: Fix machine_check_poll() tests for error types + - rcutorture: Fix cleanup path for invalid torture_type strings + - rcuperf: Fix cleanup path for invalid perf_type strings + - usb: core: Add PM runtime calls to usb_hcd_platform_shutdown + - scsi: qla4xxx: avoid freeing unallocated dma memory + - batman-adv: allow updating DAT entry timeouts on incoming ARP Replies + - dmaengine: tegra210-adma: use devm_clk_*() helpers + - hwrng: omap - Set default quality + - thunderbolt: Fix to check for kmemdup failure + - media: m88ds3103: serialize reset messages in m88ds3103_set_frontend + - media: vimc: stream: fix thread state before sleep + - media: go7007: avoid clang frame overflow warning with KASAN + - media: vimc: zero the media_device on probe + - scsi: lpfc: Fix FDMI manufacturer attribute value + - scsi: lpfc: Fix fc4type information for FDMI + - media: saa7146: avoid high stack usage with clang + - scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices + - spi : spi-topcliff-pch: Fix to handle empty DMA buffers + - spi: rspi: Fix sequencer reset during initialization + - spi: Fix zero length xfer bug + - ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM + - drm/drv: Hold ref on parent device during drm_device lifetime + - drm: Wake up next in drm_read() chain if we are forced to putback the event + - vfio-ccw: Prevent quiesce function going into an infinite loop + - NFS: Fix a double unlock from nfs_match,get_client + - ext4: wait for outstanding dio during truncate in nojournal mode + - NFSv4.1 fix incorrect return value in copy_file_range + - media: vb2: add waiting_in_dqbuf flag + - acct_on(): don't mess with freeze protection + - hv_netvsc: fix race that may miss tx queue wakeup + - Bluetooth: Ignore CC events not matching the last HCI command + - powerpc/perf: Fix loop exit condition in nest_imc_event_init + - drm/nouveau/bar/nv50: ensure BAR is mapped + - media: stm32-dcmi: return appropriate error codes during probe + - powerpc/watchdog: Use hrtimers for per-CPU heartbeat + - scsi: qla2xxx: Fix hardirq-unsafe locking + - x86/modules: Avoid breaking W^X while loading modules + - sched/nohz: Run NOHZ idle load balancer on HK_FLAG_MISC CPUs + - s390: qeth: address type mismatch warning + - rsi: Fix NULL pointer dereference in kmalloc + - nvme: set 0 capacity if namespace block size exceeds PAGE_SIZE + - bcache: avoid potential memleak of list of journal_replay(s) in the + CACHE_SYNC branch of run_cache_set + - RDMA/cma: Consider scope_id while binding to ipv6 ll address + - block: fix use-after-free on gendisk + - staging: vc04_services: handle kzalloc failure + - irq_work: Do not raise an IPI when queueing work on the local CPU + - thunderbolt: Take domain lock in switch sysfs attribute callbacks + - drm: etnaviv: avoid DMA API warning when importing buffers + - ACPI/IORT: Reject platform device creation on NUMA node mapping failure + - perf/x86/msr: Add Icelake support + - perf/x86/intel/rapl: Add Icelake support + - perf/x86/intel/cstate: Add Icelake support + - drm/panel: otm8009a: Add delay at the end of initialization + - thunderbolt: property: Fix a missing check of kzalloc + - thunderbolt: Fix to check the return value of kmemdup + - x86/mce: Handle varying MCA bank counts + - scsi: lpfc: avoid uninitialized variable warning + - thunderbolt: Fix to check return value of ida_simple_get + - drm/amd/display: fix releasing planes when exiting odm + - thunderbolt: property: Fix a NULL pointer dereference + - e1000e: Disable runtime PM on CNP+ + - igb: Exclude device from suspend direct complete optimization + - media: si2165: fix a missing check of return value + - drm/amd/display: Fix Divide by 0 in memory calculations + - spi: imx: stop buffer overflow in RX FIFO flush + - bonding/802.3ad: fix slave link initialization transition states + - cxgb4: offload VLAN flows regardless of VLAN ethtype + - inet: switch IP ID generator to siphash + - ipv4/igmp: fix another memory leak in igmpv3_del_delrec() + - ipv4/igmp: fix build error if !CONFIG_IP_MULTICAST + - ipv6: Consider sk_bound_dev_if when binding a raw socket to an address + - llc: fix skb leak in llc_build_and_send_ui_pkt() + - net: dsa: mv88e6xxx: fix handling of upper half of STATS_TYPE_PORT + - net: fec: fix the clk mismatch in failed_reset path + - net-gro: fix use-after-free read in napi_gro_frags() + - net: mvneta: Fix err code path of probe + - net: mvpp2: fix bad MVPP2_TXQ_SCHED_TOKEN_CNTR_REG queue value + - net: phy: marvell10g: report if the PHY fails to boot firmware + - net: stmmac: fix reset gpio free missing + - usbnet: fix kernel crash after disconnect + - tipc: Avoid copying bytes beyond the supplied data + - net/mlx5: Allocate root ns memory using kzalloc to match kfree + - bnxt_en: Fix aggregation buffer leak under OOM condition. + - crypto: vmx - ghash: do nosimd fallback manually + - include/linux/compiler*.h: define asm_volatile_goto + - compiler.h: give up __compiletime_assert_fallback() + - xen/pciback: Don't disable PCI_COMMAND on PCI device reset. + - tipc: fix modprobe tipc failed after switch order of device registration + - sparc64: Fix regression in non-hypervisor TLB flush xcall + - include/linux/bitops.h: sanitize rotate primitives + - xhci: update bounce buffer with correct sg num + - xhci: Use %zu for printing size_t type + - xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() + - usb: xhci: avoid null pointer deref when bos field is NULL + - usbip: usbip_host: fix BUG: sleeping function called from invalid context + - usbip: usbip_host: fix stub_dev lock context imbalance regression + - USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor + - USB: sisusbvga: fix oops in error path of sisusb_probe + - USB: Add LPM quirk for Surface Dock GigE adapter + - USB: rio500: refuse more than one device at a time + - USB: rio500: fix memory leak in close after disconnect + - media: usb: siano: Fix general protection fault in smsusb + - media: usb: siano: Fix false-positive "uninitialized variable" warning + - media: smsusb: better handle optional alignment + - scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove + - scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) + - Btrfs: fix wrong ctime and mtime of a directory after log replay + - Btrfs: fix race updating log root item during fsync + - Btrfs: fix fsync not persisting changed attributes of a directory + - Btrfs: incremental send, fix file corruption when no-holes feature is + enabled + - KVM: PPC: Book3S HV: XIVE: Do not clear IRQ data of passthrough interrupts + - powerpc/perf: Fix MMCRA corruption by bhrb_filter + - ALSA: hda/realtek - Set default power save node to 0 + - KVM: s390: Do not report unusabled IDs via KVM_CAP_MAX_VCPU_ID + - drm/nouveau/i2c: Disable i2c bus access after ->fini() + - tty: serial: msm_serial: Fix XON/XOFF + - tty: max310x: Fix external crystal register setup + - memcg: make it work on sparse non-0-node systems + - kernel/signal.c: trace_signal_deliver when signal_group_exit + - docs: Fix conf.py for Sphinx 2.0 + - doc: Cope with the deprecation of AutoReporter + - doc: Cope with Sphinx logging deprecations + - ima: show rules with IMA_INMASK correctly + - serial: sh-sci: disable DMA for uart_console + - staging: vc04_services: prevent integer overflow in create_pagelist() + - staging: wlan-ng: fix adapter initialization failure + - CIFS: cifs_read_allocate_pages: don't iterate through whole page array on + ENOMEM + - gcc-plugins: Fix build failures under Darwin host + - drm/vmwgfx: Don't send drm sysfs hotplug events on initial master set + - drm/rockchip: shutdown drm subsystem on shutdown + - Compiler Attributes: add support for __copy (gcc >= 9) + - include/linux/module.h: copy __init/__exit attrs to init/cleanup_module + - binder: fix race between munmap() and direct reclaim + - media: uvcvideo: Fix uvc_alloc_entity() allocation alignment + - brcmfmac: fix NULL pointer derefence during USB disconnect + - iio: dac: ds4422/ds4424 fix chip verification + - s390/crypto: fix possible sleep during spinlock aquired + - ALSA: line6: Assure canceling delayed work at disconnection + - vt/fbcon: deinitialize resources in visual_init() after failed memory + allocation + - cifs: fix memory leak of pneg_inbuf on -EOPNOTSUPP ioctl case + - x86/ftrace: Do not call function graph from dynamic trampolines + - x86/ftrace: Set trampoline pages as executable + - x86/kprobes: Set instruction page as executable + - of: overlay: validate overlay properties #address-cells and #size-cells + - of: overlay: set node fields from properties when add new overlay node + - ethtool: fix potential userspace buffer overflow + - Fix memory leak in sctp_process_init + - neighbor: Call __ipv4_neigh_lookup_noref in neigh_xmit + - net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query + - net: rds: fix memory leak in rds_ib_flush_mr_pool + - pktgen: do not sleep with the thread lock held. + - ipv6: fix EFAULT on sendto with icmpv6 and hdrincl + - ipv6: use READ_ONCE() for inet->hdrincl as in ipv4 + - net: sfp: read eeprom in maximum 16 byte increments + - ipv6: fix the check before getting the cookie in rt6_get_cookie + - rcu: locking and unlocking need to always be at least barriers + - parisc: Use implicit space register selection for loading the coherence + index of I/O pdirs + - fuse: fallocate: fix return with locked inode + - pstore: Remove needless lock during console writes + - pstore: Convert buf_lock to semaphore + - pstore/ram: Run without kernel crash dump region + - x86/power: Fix 'nosmt' vs hibernation triple fault during resume + - i2c: xiic: Add max_read_len quirk + - MIPS: Bounds check virt_addr_valid + - MIPS: pistachio: Build uImage.gz by default + - genwqe: Prevent an integer overflow in the ioctl + - test_firmware: Use correct snprintf() limit + - drm/gma500/cdv: Check vbt config bits when detecting lvds panels + - drm/amdgpu/psp: move psp version specific function pointers to early_init + - drm/i915: Fix I915_EXEC_RING_MASK + - drm/i915/fbc: disable framebuffer compression on GeminiLake + - TTY: serial_core, add ->install + - qmi_wwan: Add quirk for Quectel dynamic config + - ipv4: Define __ipv4_neigh_lookup_noref when CONFIG_INET is disabled + - ethtool: check the return value of get_regs_len + - net: ethernet: ti: cpsw_ethtool: fix ethtool ring param set + - net: mvpp2: Use strscpy to handle stat strings + - packet: unconditionally free po->rollover + - NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter + - NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled + - s390/mm: fix address space detection in exception handling + - drm/msm: fix fb references in async update + - drm: add non-desktop quirk for Valve HMDs + - drm: add non-desktop quirks to Sensics and OSVR headsets. + - drm/amdgpu: remove ATPX_DGPU_REQ_POWER_FOR_DISPLAYS check when hotplug-in + * CVE-2019-14283 + - floppy: fix out-of-bounds read in copy_buffer + * CVE-2019-14284 + - floppy: fix div-by-zero in setup_format_params + * Bionic linux 4.15.0-56.62 fails to build with CONFIG_NVM disabled + (LP: #1838533) + - Revert "nvme: warn when finding multi-port subsystems without multipathing + enabled" + * Bionic update: upstream stable patchset 2019-07-31 (LP: #1838576) + - netfilter: compat: initialize all fields in xt_init + - platform/x86: sony-laptop: Fix unintentional fall-through + - platform/x86: thinkpad_acpi: Disable Bluetooth for some machines + - hwmon: (pwm-fan) Disable PWM if fetching cooling data fails + - kernfs: fix barrier usage in __kernfs_new_node() + - USB: serial: fix unthrottle races + - iio: adc: xilinx: fix potential use-after-free on remove + - libnvdimm/namespace: Fix a potential NULL pointer dereference + - HID: input: add mapping for Expose/Overview key + - HID: input: add mapping for keyboard Brightness Up/Down/Toggle keys + - HID: input: add mapping for "Toggle Display" key + - libnvdimm/btt: Fix a kmemdup failure check + - s390/dasd: Fix capacity calculation for large volumes + - mac80211: fix unaligned access in mesh table hash function + - mac80211: Increase MAX_MSG_LEN + - mac80211: fix memory accounting with A-MSDU aggregation + - nl80211: Add NL80211_FLAG_CLEAR_SKB flag for other NL commands + - s390/3270: fix lockdep false positive on view->lock + - clocksource/drivers/oxnas: Fix OX820 compatible + - mISDN: Check address length before reading address family + - s390/pkey: add one more argument space for debug feature entry + - x86/reboot, efi: Use EFI reboot for Acer TravelMate X514-51T + - KVM: fix spectrev1 gadgets + - KVM: x86: avoid misreporting level-triggered irqs as edge-triggered in + tracing + - tools lib traceevent: Fix missing equality check for strcmp + - mm: fix inactive list balancing between NUMA nodes and cgroups + - init: initialize jump labels before command line option parsing + - selftests: netfilter: check icmp pkttoobig errors are set as related + - ipvs: do not schedule icmp errors from tunnels + - netfilter: ctnetlink: don't use conntrack/expect object addresses as id + - s390: ctcm: fix ctcm_new_device error return code + - drm/sun4i: Set device driver data at bind time for use in unbind + - gpu: ipu-v3: dp: fix CSC handling + - drm/imx: don't skip DP channel disable for background plane + - spi: Micrel eth switch: declare missing of table + - spi: ST ST95HF NFC: declare missing of table + - Input: synaptics-rmi4 - fix possible double free + - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit + - ima: open a new file instance if no read permissions + - drm/i915: Disable LP3 watermarks on all SNB machines + - net: stmmac: Move debugfs init/exit to ->probe()/->remove() + - x86/vdso: Pass --eh-frame-hdr to the linker + - mm/memory.c: fix modifying of page protection by insert_pfn() + - net: fec: manage ahb clock in runtime pm + - mlxsw: spectrum_switchdev: Add MDB entries in prepare phase + - mlxsw: core: Do not use WQ_MEM_RECLAIM for EMAD workqueue + - mlxsw: core: Do not use WQ_MEM_RECLAIM for mlxsw ordered workqueue + - mlxsw: core: Do not use WQ_MEM_RECLAIM for mlxsw workqueue + - NFC: nci: Add some bounds checking in nci_hci_cmd_received() + - nfc: nci: Potential off by one in ->pipes[] array + - x86/kprobes: Avoid kretprobe recursion bug + - cw1200: fix missing unlock on error in cw1200_hw_scan() + - mwl8k: Fix rate_idx underflow + - rtlwifi: rtl8723ae: Fix missing break in switch statement + - bonding: fix arp_validate toggling in active-backup mode + - bridge: Fix error path for kobject_init_and_add() + - dpaa_eth: fix SG frame cleanup + - ipv4: Fix raw socket lookup for local traffic + - net: dsa: Fix error cleanup path in dsa_init_module + - net: ethernet: stmmac: dwmac-sun8i: enable support of unicast filtering + - net: seeq: fix crash caused by not set dev.parent + - net: ucc_geth - fix Oops when changing number of buffers in the ring + - packet: Fix error path in packet_init + - vlan: disable SIOCSHWTSTAMP in container + - vrf: sit mtu should not be updated when vrf netdev is the link + - tipc: fix hanging clients using poll with EPOLLOUT flag + - drivers/virt/fsl_hypervisor.c: dereferencing error pointers in ioctl + - drivers/virt/fsl_hypervisor.c: prevent integer overflow in ioctl + - powerpc/powernv/idle: Restore IAMR after idle + - powerpc/booke64: set RI in default MSR + - platform/x86: dell-laptop: fix rfkill functionality + - iio: adc: xilinx: fix potential use-after-free on probe + - iio: adc: xilinx: prevent touching unclocked h/w on remove + - acpi/nfit: Always dump _DSM output payload + - libnvdimm/pmem: fix a possible OOB access when read and write pmem + - vxge: fix return of a free'd memblock on a failed dma mapping + - qede: fix write to free'd pointer error and double free of ptp + - afs: Unlock pages for __pagevec_release() + - ipmi: ipmi_si_hardcode.c: init si_type array to fix a crash + - scsi: aic7xxx: fix EISA support + - drm/sun4i: Fix component unbinding and component master deletion + - netfilter: fix nf_l4proto_log_invalid to log invalid packets + - drm/sun4i: Unbind components before releasing DRM and memory + - usb: typec: Fix unchecked return value + - netfilter: nf_tables: use-after-free in dynamic operations + - um: Don't hardcode path as it is architecture dependent + - powerpc/book3s/64: check for NULL pointer in pgd_alloc() + - PCI: hv: Add hv_pci_remove_slots() when we unload the driver + - PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), if necessary + - net: core: another layer of lists, around PF_MEMALLOC skb handling + - locking/rwsem: Prevent decrement of reader count before increment + - PCI: hv: Fix a memory leak in hv_eject_device_work() + - x86/speculation/mds: Revert CPU buffer clear on double fault exit + - x86/speculation/mds: Improve CPU buffer clear documentation + - objtool: Fix function fallthrough detection + - ARM: dts: exynos: Fix interrupt for shared EINTs on Exynos5260 + - ARM: dts: exynos: Fix audio (microphone) routing on Odroid XU3 + - ARM: exynos: Fix a leaked reference by adding missing of_node_put + - power: supply: axp288_charger: Fix unchecked return value + - arm64: compat: Reduce address limit + - arm64: Clear OSDLR_EL1 on CPU boot + - arm64: Save and restore OSDLR_EL1 across suspend/resume + - sched/x86: Save [ER]FLAGS on context switch + - crypto: chacha20poly1305 - set cra_name correctly + - crypto: vmx - fix copy-paste error in CTR mode + - crypto: skcipher - don't WARN on unprocessed data after slow walk step + - crypto: crct10dif-generic - fix use via crypto_shash_digest() + - crypto: x86/crct10dif-pcl - fix use via crypto_shash_digest() + - crypto: gcm - fix incompatibility between "gcm" and "gcm_base" + - crypto: rockchip - update IV buffer to contain the next IV + - crypto: arm/aes-neonbs - don't access already-freed walk.iv + - ALSA: usb-audio: Fix a memory leak bug + - ALSA: hda/realtek - EAPD turn on later + - ASoC: max98090: Fix restore of DAPM Muxes + - ASoC: RT5677-SPI: Disable 16Bit SPI Transfers + - bpf, arm64: remove prefetch insn in xadd mapping + - mm/mincore.c: make mincore() more conservative + - ocfs2: fix ocfs2 read inode data panic in ocfs2_iget + - userfaultfd: use RCU to free the task struct when fork fails + - mfd: da9063: Fix OTP control register names to match datasheets for + DA9063/63L + - mfd: max77620: Fix swapped FPS_PERIOD_MAX_US values + - mtd: spi-nor: intel-spi: Avoid crossing 4K address boundary on read/write + - tty: vt.c: Fix TIOCL_BLANKSCREEN console blanking if blankinterval == 0 + - tty/vt: fix write/write race in ioctl(KDSKBSENT) handler + - jbd2: check superblock mapped prior to committing + - ext4: make sanity check in mballoc more strict + - ext4: ignore e_value_offs for xattrs with value-in-ea-inode + - ext4: avoid drop reference to iloc.bh twice + - Btrfs: do not start a transaction during fiemap + - Btrfs: do not start a transaction at iterate_extent_inodes() + - bcache: fix a race between cache register and cacheset unregister + - bcache: never set KEY_PTRS of journal key to 0 in journal_reclaim() + - ext4: fix use-after-free race with debug_want_extra_isize + - ext4: actually request zeroing of inode table after grow + - ext4: fix ext4_show_options for file systems w/o journal + - ipmi:ssif: compare block number correctly for multi-part return messages + - crypto: arm64/aes-neonbs - don't access already-freed walk.iv + - crypto: salsa20 - don't access already-freed walk.iv + - crypto: ccm - fix incompatibility between "ccm" and "ccm_base" + - fs/writeback.c: use rcu_barrier() to wait for inflight wb switches going + into workqueue when umount + - ext4: fix data corruption caused by overlapping unaligned and aligned IO + - ext4: fix use-after-free in dx_release() + - ALSA: hda/realtek - Fix for Lenovo B50-70 inverted internal microphone bug + - KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes + - iov_iter: optimize page_copy_sane() + - ext4: fix compile error when using BUFFER_TRACE + - arm64: dts: rockchip: Disable DCMDs on RK3399's eMMC controller. + - arm64: mmap: Ensure file offset is treated as unsigned + - arm64: arch_timer: Ensure counter register reads occur with seqlock held + - crypto: crypto4xx - fix ctr-aes missing output IV + - crypto: crypto4xx - fix cfb and ofb "overran dst buffer" issues + - ALSA: line6: toneport: Fix broken usage of timer for delayed execution + - ASoC: fsl_esai: Fix missing break in switch statement + - mm/huge_memory: fix vmf_insert_pfn_{pmd, pud}() crash, handle unaligned + addresses + - hugetlb: use same fault hash key for shared and private mappings + - ACPI: PM: Set enable_for_wake for wakeup GPEs during suspend-to-idle + - btrfs: Correctly free extent buffer in case btree_read_extent_buffer_pages + fails + - ext4: avoid panic during forced reboot due to aborted journal + - libnvdimm/namespace: Fix label tracking error + - ext4: don't update s_rev_level if not required + - net: avoid weird emergency message + - net/mlx4_core: Change the error print to info print + - net: test nouarg before dereferencing zerocopy pointers + - net: usb: qmi_wwan: add Telit 0x1260 and 0x1261 compositions + - ppp: deflate: Fix possible crash in deflate_init + - tipc: switch order of device registration to fix a crash + - vsock/virtio: free packets during the socket release + - vsock/virtio: Initialize core virtio vsock before registering the driver + - net: Always descend into dsa/ + - parisc: Export running_on_qemu symbol for modules + - parisc: Skip registering LED when running in QEMU + - parisc: Use PA_ASM_LEVEL in boot code + - parisc: Rename LEVEL to PA_ASM_LEVEL to avoid name clash with DRBD code + - stm class: Fix channel free in stm output free path + - md: add mddev->pers to avoid potential NULL pointer dereference + - intel_th: msu: Fix single mode with IOMMU + - p54: drop device reference count if fails to enable device + - of: fix clang -Wunsequenced for be32_to_cpu() + - media: ov6650: Fix sensor possibly not detected on probe + - NFS4: Fix v4.0 client state corruption when mount + - PNFS fallback to MDS if no deviceid found + - clk: hi3660: Mark clk_gate_ufs_subsys as critical + - clk: tegra: Fix PLLM programming on Tegra124+ when PMC overrides divider + - clk: rockchip: fix wrong clock definitions for rk3328 + - fuse: fix writepages on 32bit + - fuse: honor RLIMIT_FSIZE in fuse_file_fallocate + - iommu/tegra-smmu: Fix invalid ASID bits on Tegra30/114 + - ceph: flush dirty inodes before proceeding with remount + - x86_64: Add gap to int3 to allow for call emulation + - x86_64: Allow breakpoints to emulate call instructions + - ftrace/x86_64: Emulate call function while updating in breakpoint handler + - tracing: Fix partial reading of trace event's id file + - memory: tegra: Fix integer overflow on tick value calculation + - perf intel-pt: Fix instructions sampling rate + - perf intel-pt: Fix improved sample timestamp + - perf intel-pt: Fix sample timestamp wrt non-taken branches + - objtool: Allow AR to be overridden with HOSTAR + - fbdev: sm712fb: fix brightness control on reboot, don't set SR30 + - fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75 + - fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F + - fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA + - fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping + VRAM + - fbdev: sm712fb: fix support for 1024x768-16 mode + - fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display + - fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting + - PCI: Mark AMD Stoney Radeon R7 GPU ATS as broken + - PCI: Mark Atheros AR9462 to avoid bus reset + - PCI: Factor out pcie_retrain_link() function + - PCI: Work around Pericom PCIe-to-PCI bridge Retrain Link erratum + - dm cache metadata: Fix loading discard bitset + - dm zoned: Fix zone report handling + - dm delay: fix a crash when invalid device is specified + - xfrm: policy: Fix out-of-bound array accesses in __xfrm_policy_unlink + - xfrm6_tunnel: Fix potential panic when unloading xfrm6_tunnel module + - vti4: ipip tunnel deregistration fixes. + - esp4: add length check for UDP encapsulation + - xfrm4: Fix uninitialized memory read in _decode_session4 + - power: supply: cpcap-battery: Fix division by zero + - securityfs: fix use-after-free on symlink traversal + - apparmorfs: fix use-after-free on symlink traversal + - mac80211: Fix kernel panic due to use of txq after free + - KVM: arm/arm64: Ensure vcpu target is unset on reset failure + - power: supply: sysfs: prevent endless uevent loop with + CONFIG_POWER_SUPPLY_DEBUG + - iwlwifi: mvm: check for length correctness in iwl_mvm_create_skb() + - sched/cpufreq: Fix kobject memleak + - x86/mm/mem_encrypt: Disable all instrumentation for early SME setup + - ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour + - perf bench numa: Add define for RUSAGE_THREAD if not present + - md/raid: raid5 preserve the writeback action after the parity check + - driver core: Postpone DMA tear-down until after devres release for probe + failure + - bpf: add map_lookup_elem_sys_only for lookups from syscall side + - bpf, lru: avoid messing with eviction heuristics upon syscall lookup + - fbdev: sm712fb: fix memory frequency by avoiding a switch/case fallthrough + - nfp: flower: add rcu locks when accessing netdev for tunnels + - rtnetlink: always put IFLA_LINK for links with a link-netnsid + - brd: re-enable __GFP_HIGHMEM in brd_insert_page() + - proc: prevent changes to overridden credentials + - md: batch flush requests. + - phy: ti-pipe3: fix missing bit-wise or operator when assigning val + - clk: mediatek: Disable tuner_en before change PLL rate + - PCI: rcar: Add the initialization of PCIe link in resume_noirq() + - fuse: Add FOPEN_STREAM to use stream_open() + - qmi_wwan: new Wistron, ZTE and D-Link devices + - bpf: relax inode permission check for retrieving bpf program + * Bionic update: upstream stable patchset 2019-07-30 (LP: #1838459) + - kbuild: simplify ld-option implementation + - cifs: do not attempt cifs operation on smb2+ rename error + - tracing: Fix a memory leak by early error exit in trace_pid_write() + - tracing: Fix buffer_ref pipe ops + - zram: pass down the bvec we need to read into in the work struct + - lib/Kconfig.debug: fix build error without CONFIG_BLOCK + - MIPS: scall64-o32: Fix indirect syscall number load + - trace: Fix preempt_enable_no_resched() abuse + - IB/rdmavt: Fix frwr memory registration + - sched/numa: Fix a possible divide-by-zero + - ceph: only use d_name directly when parent is locked + - ceph: ensure d_name stability in ceph_dentry_hash() + - ceph: fix ci->i_head_snapc leak + - nfsd: Don't release the callback slot unless it was actually held + - sunrpc: don't mark uninitialised items as VALID. + - Input: synaptics-rmi4 - write config register values to the right offset + - dmaengine: sh: rcar-dmac: With cyclic DMA residue 0 is valid + - ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache + - drm/vc4: Fix memory leak during gpu reset. + - drm/vc4: Fix compilation error reported by kbuild test bot + - ext4: fix some error pointer dereferences + - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock + - tipc: handle the err returned from cmd header function + - slip: make slhc_free() silently accept an error pointer + - intel_th: gth: Fix an off-by-one in output unassigning + - fs/proc/proc_sysctl.c: Fix a NULL pointer dereference + - ipvs: fix warning on unused variable + - sched/deadline: Correctly handle active 0-lag timers + - NFS: Forbid setting AF_INET6 to "struct sockaddr_in"->sin_family. + - netfilter: ebtables: CONFIG_COMPAT: drop a bogus WARN_ON + - fm10k: Fix a potential NULL pointer dereference + - tipc: check bearer name with right length in tipc_nl_compat_bearer_enable + - tipc: check link name with right length in tipc_nl_compat_link_set + - x86, retpolines: Raise limit for generating indirect calls from switch-case + - x86/retpolines: Disable switch jump tables when retpolines are enabled + - mm: Fix warning in insert_pfn() + - ipv4: add sanity checks in ipv4_link_failure() + - mlxsw: spectrum: Fix autoneg status in ethtool + - net/mlx5e: ethtool, Remove unsupported SFP EEPROM high pages query + - net: rds: exchange of 8K and 1M pool + - net: stmmac: move stmmac_check_ether_addr() to driver probe + - stmmac: pci: Adjust IOT2000 matching + - team: fix possible recursive locking when add slaves + - net/rose: fix unbound loop in rose_loopback_timer() + - ipv4: set the tcp_min_rtt_wlen range from 0 to one day + - powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2 boot arg + - Documentation: Add nospectre_v1 parameter + - netfilter: nf_tables: warn when expr implements only one of + activate/deactivate + - net/ibmvnic: Fix RTNL deadlock during device reset + - drm/rockchip: fix for mailbox read validation. + - powerpc/vdso32: fix CLOCK_MONOTONIC on PPC64 + - perf/x86/intel: Enable C-state residency events for Cannon Lake + - perf/x86/intel: Update KBL Package C-state events to also include + PC8/PC9/PC10 counters + - powerpc/mm/radix: Make Radix require HUGETLB_PAGE + - workqueue: Try to catch flush_work() without INIT_WORK(). + - mlxsw: pci: Reincrease PCI reset timeout + - mm: make page ref count overflow check tighter and more explicit + - mm: add 'try_get_page()' helper function + - mm: prevent get_user_pages() from overflowing page refcount + - fs: prevent page refcount overflow in pipe_buf_get + - ARM: dts: bcm283x: Fix hdmi hpd gpio pull + - s390: limit brk randomization to 32MB + - qlcnic: Avoid potential NULL pointer dereference + - netfilter: nft_set_rbtree: check for inactive element after flag mismatch + - netfilter: bridge: set skb transport_header before entering + NF_INET_PRE_ROUTING + - s390/qeth: fix race when initializing the IP address table + - sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() + - serial: ar933x_uart: Fix build failure with disabled console + - KVM: arm/arm64: vgic-its: Take the srcu lock when parsing the memslots + - usb: gadget: net2280: Fix overrun of OUT messages + - usb: gadget: net2280: Fix net2280_dequeue() + - usb: gadget: net2272: Fix net2272_dequeue() + - ARM: dts: pfla02: increase phy reset duration + - net: ks8851: Dequeue RX packets explicitly + - net: ks8851: Reassert reset pin if chip ID check fails + - net: ks8851: Delay requesting IRQ until opened + - net: ks8851: Set initial carrier state to down + - staging: rtl8188eu: Fix potential NULL pointer dereference of kcalloc + - staging: rtlwifi: rtl8822b: fix to avoid potential NULL pointer dereference + - staging: rtl8712: uninitialized memory in read_bbreg_hdl() + - staging: rtlwifi: Fix potential NULL pointer dereference of kzalloc + - net: macb: Add null check for PCLK and HCLK + - net/sched: don't dereference a->goto_chain to read the chain index + - ARM: dts: imx6qdl: Fix typo in imx6qdl-icore-rqs.dtsi + - NFS: Fix a typo in nfs_init_timeout_values() + - net: xilinx: fix possible object reference leak + - net: ibm: fix possible object reference leak + - net: ethernet: ti: fix possible object reference leak + - gpio: aspeed: fix a potential NULL pointer dereference + - drm/meson: Fix invalid pointer in meson_drv_unbind() + - drm/meson: Uninstall IRQ handler + - scsi: qla4xxx: fix a potential NULL pointer dereference + - usb: usb251xb: fix to avoid potential NULL pointer dereference + - usb: u132-hcd: fix resource leak + - ceph: fix use-after-free on symlink traversal + - scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN + - libata: fix using DMA buffers on stack + - gpio: of: Fix of_gpiochip_add() error path + - kconfig/[mn]conf: handle backspace (^H) key + - ptrace: take into account saved_sigmask in PTRACE{GET,SET}SIGMASK + - leds: pca9532: fix a potential NULL pointer dereference + - KVM: arm64: Reset the PMU in preemptible context + - KVM: arm/arm64: vgic-its: Take the srcu lock when writing to guest memory + - scsi: aacraid: Insure we don't access PCIe space during AER/EEH + - x86/realmode: Don't leak the trampoline kernel address + - x86/mm: Don't exceed the valid physical address space + - ipv4: ip_do_fragment: Preserve skb_iif during fragmentation + - ipv6/flowlabel: wait rcu grace period before put_pid() + - ipv6: invert flowlabel sharing check in process and user mode + - l2ip: fix possible use-after-free + - l2tp: use rcu_dereference_sk_user_data() in l2tp_udp_encap_recv() + - net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc + - net: phy: marvell: Fix buffer overrun with stats counters + - sctp: avoid running the sctp state machine recursively + - packet: validate msg_namelen in send directly + - bnxt_en: Improve multicast address setup logic. + - bnxt_en: Free short FW command HWRM memory in error path in bnxt_init_one() + - ALSA: line6: use dynamic buffers + - rxrpc: Fix net namespace cleanup + - kasan: remove redundant initialization of variable 'real_size' + - kasan: prevent compiler from optimizing away memset in tests + - caif: reduce stack size with KASAN + - ALSA: hda/realtek - Add new Dell platform for headset mode + - USB: yurex: Fix protection fault after device removal + - USB: w1 ds2490: Fix bug caused by improper use of altsetting array + - usb: usbip: fix isoc packet num validation in get_pipe + - USB: core: Fix unterminated string returned by usb_string() + - USB: core: Fix bug caused by duplicate interface PM usage counter + - nvme-loop: init nvmet_ctrl fatal_err_work when allocate + - HID: logitech: check the return value of create_singlethread_workqueue + - HID: debug: fix race condition with between rdesc_show() and device removal + - rtc: sh: Fix invalid alarm warning for non-enabled alarm + - batman-adv: Reduce claim hash refcnt only for removed entry + - batman-adv: Reduce tt_local hash refcnt only for removed entry + - batman-adv: Reduce tt_global hash refcnt only for removed entry + - ARM: dts: rockchip: Fix gpu opp node names for rk3288 + - net/mlx5: E-Switch, Fix esw manager vport indication for more vport commands + - bonding: show full hw address in sysfs for slave entries + - net: stmmac: ratelimit RX error logs + - net: stmmac: don't overwrite discard_frame status + - net: stmmac: fix dropping of multi-descriptor RX frames + - net: stmmac: don't log oversized frames + - jffs2: fix use-after-free on symlink traversal + - debugfs: fix use-after-free on symlink traversal + - rtc: da9063: set uie_unsupported when relevant + - HID: input: add mapping for Assistant key + - vfio/pci: use correct format characters + - scsi: core: add new RDAC LENOVO/DE_Series device + - scsi: storvsc: Fix calculation of sub-channel count + - net: hns: Fix WARNING when remove HNS driver with SMMU enabled + - kmemleak: powerpc: skip scanning holes in the .bss section + - hugetlbfs: fix memory leak for resv_map + - sh: fix multiple function definition build errors + - xsysace: Fix error handling in ace_setup + - ARM: orion: don't use using 64-bit DMA masks + - ARM: iop: don't use using 64-bit DMA masks + - perf/x86/amd: Update generic hardware cache events for Family 17h + - Bluetooth: btusb: request wake pin with NOAUTOEN + - staging: iio: adt7316: allow adt751x to use internal vref for all dacs + - staging: iio: adt7316: fix the dac read calculation + - staging: iio: adt7316: fix the dac write calculation + - scsi: RDMA/srpt: Fix a credit leak for aborted commands + - ASoC: stm32: fix sai driver name initialisation + - IB/core: Unregister notifier before freeing MAD security + - IB/core: Fix potential memory leak while creating MAD agents + - IB/core: Destroy QP if XRC QP fails + - Input: snvs_pwrkey - initialize necessary driver data before enabling IRQ + - Input: stmfts - acknowledge that setting brightness is a blocking call + - selinux: never allow relabeling on context mounts + - powerpc/mm/hash: Handle mmap_min_addr correctly in get_unmapped_area topdown + search + - x86/mce: Improve error message when kernel cannot recover, p2 + - clk: x86: Add system specific quirk to mark clocks as critical + - i2c: i2c-stm32f7: Fix SDADEL minimum formula + - media: v4l2: i2c: ov7670: Fix PLL bypass register values + - mm/kmemleak.c: fix unused-function warning + - mac80211: don't attempt to rename ERR_PTR() debugfs dirs + - i2c: Remove unnecessary call to irq_find_mapping + - i2c: Clear client->irq in i2c_device_remove + - i2c: Allow recovery of the initial IRQ by an I2C client device. + - i2c: Prevent runtime suspend of adapter when Host Notify is required + - USB: dummy-hcd: Fix failure to give back unlinked URBs + - batman-adv: fix warning in function batadv_v_elp_get_throughput + - riscv: fix accessing 8-byte variable from RV32 + - net: stmmac: don't stop NAPI processing when dropping a packet + - mfd: twl-core: Disable IRQ while suspended + - block: use blk_free_flush_queue() to free hctx->fq in blk_mq_init_hctx + - arm/mach-at91/pm : fix possible object reference leak + - fs: stream_open - opener for stream-like files so that read and write can + run simultaneously without deadlock + - block: pass no-op callback to INIT_WORK(). + - platform/x86: intel_pmc_core: Fix PCH IP name + - platform/x86: intel_pmc_core: Handle CFL regmap properly + - x86/mm: Fix a crash with kmemleak_scan() + - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup() + - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings + - staging: greybus: power_supply: fix prop-descriptor request size + - ASoC: hdmi-codec: fix S/PDIF DAI + - ASoC:soc-pcm:fix a codec fixup issue in TDM case + - ASoC: nau8824: fix the issue of the widget with prefix name + - ASoC: nau8810: fix the issue of widget with prefixed name + - ASoC: samsung: odroid: Fix clock configuration for 44100 sample rate + - ASoC: wm_adsp: Add locking to wm_adsp2_bus_error + - ASoC: cs4270: Set auto-increment bit for register writes + - IB/hfi1: Eliminate opcode tests on mr deref + - MIPS: KGDB: fix kgdb support for SMP platforms. + - ASoC: tlv320aic32x4: Fix Common Pins + - drm/mediatek: Fix an error code in mtk_hdmi_dt_parse_pdata() + - perf/x86/intel: Fix handling of wakeup_events for multi-entry PEBS + - perf/x86/intel: Initialize TFA MSR + - linux/kernel.h: Use parentheses around argument in u64_to_user_ptr() + - ASoC: rockchip: pdm: fix regmap_ops hang issue + - slab: fix a crash by reading /proc/slab_allocators + - virtio_pci: fix a NULL pointer reference in vp_del_vqs + - RDMA/vmw_pvrdma: Fix memory leak on pvrdma_pci_remove + - scsi: csiostor: fix missing data copy in csio_scsi_err_handler() + - drm/mediatek: fix possible object reference leak + - ASoC: Intel: kbl: fix wrong number of channels + - virtio-blk: limit number of hw queues by nr_cpu_ids + - platform/x86: pmc_atom: Drop __initconst on dmi table + - genirq: Prevent use-after-free and work list corruption + - usb: dwc3: Fix default lpm_nyet_threshold value + - USB: serial: f81232: fix interrupt worker not stop + - USB: cdc-acm: fix unthrottle races + - usb-storage: Set virt_boundary_mask to avoid SG overflows + - intel_th: pci: Add Comet Lake support + - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines + - UAS: fix alignment of scatter/gather segments + - ASoC: Intel: avoid Oops if DMA setup fails + - locking/futex: Allow low-level atomic operations to return -EAGAIN + - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP + - ASoC: tlv320aic3x: fix reset gpio reference counting + - ASoC: stm32: sai: fix exposed capabilities in spdif mode + - ASoC:intel:skl:fix a simultaneous playback & capture issue on hda platform + - ASoC: dapm: Fix NULL pointer dereference in snd_soc_dapm_free_kcontrol + - drm/omap: hdmi4_cec: Fix CEC clock handling for PM + - IB/hfi1: Fix the allocation of RSM table + - drm/amd/display: fix cursor black issue + - objtool: Add machine_real_restart() to the noreturn list + - objtool: Add rewind_stack_do_exit() to the noreturn list + - RDMA/hns: Fix bug that caused srq creation to fail + - perf/core: Fix perf_event_disable_inatomic() race + - soc: sunxi: Fix missing dependency on REGMAP_MMIO + - scsi: lpfc: change snprintf to scnprintf for possible overflow + * [ZenBook S UX391UA, Realtek ALC294, Mic, Internal] No sound at all + (LP: #1784485) // Bionic update: upstream stable patchset 2019-07-30 + (LP: #1838459) + - ALSA: hda/realtek - Apply the fixup for ASUS Q325UAR + * Bionic update: upstream stable patchset 2019-07-29 (LP: #1838349) + - ARC: u-boot args: check that magic number is correct + - arc: hsdk_defconfig: Enable CONFIG_BLK_DEV_RAM + - perf/core: Restore mmap record type correctly + - ext4: add missing brelse() in add_new_gdb_meta_bg() + - ext4: report real fs size after failed resize + - ALSA: echoaudio: add a check for ioremap_nocache + - ALSA: sb8: add a check for request_region + - auxdisplay: hd44780: Fix memory leak on ->remove() + - IB/mlx4: Fix race condition between catas error reset and aliasguid flows + - mmc: davinci: remove extraneous __init annotation + - ALSA: opl3: fix mismatch between snd_opl3_drum_switch definition and + declaration + - thermal/intel_powerclamp: fix __percpu declaration of worker_data + - thermal: bcm2835: Fix crash in bcm2835_thermal_debugfs + - thermal/int340x_thermal: Add additional UUIDs + - thermal/int340x_thermal: fix mode setting + - thermal/intel_powerclamp: fix truncated kthread name + - scsi: iscsi: flush running unbind operations when removing a session + - x86/mm: Don't leak kernel addresses + - tools/power turbostat: return the exit status of a command + - perf list: Don't forget to drop the reference to the allocated thread_map + - perf config: Fix an error in the config template documentation + - perf config: Fix a memory leak in collect_config() + - perf build-id: Fix memory leak in print_sdt_events() + - perf top: Fix error handling in cmd_top() + - perf hist: Add missing map__put() in error case + - perf evsel: Free evsel->counts in perf_evsel__exit() + - perf tests: Fix a memory leak of cpu_map object in the + openat_syscall_event_on_all_cpus test + - perf tests: Fix memory leak by expr__find_other() in test__expr() + - perf tests: Fix a memory leak in test__perf_evsel__tp_sched_test() + - irqchip/mbigen: Don't clear eventid when freeing an MSI + - x86/hpet: Prevent potential NULL pointer dereference + - x86/cpu/cyrix: Use correct macros for Cyrix calls on Geode processors + - drm/nouveau/debugfs: Fix check of pm_runtime_get_sync failure + - iommu/vt-d: Check capability before disabling protected memory + - x86/hw_breakpoints: Make default case in hw_breakpoint_arch_parse() return + an error + - fix incorrect error code mapping for OBJECTID_NOT_FOUND + - ext4: prohibit fstrim in norecovery mode + - gpio: pxa: handle corner case of unprobed device + - rsi: improve kernel thread handling to fix kernel panic + - 9p: do not trust pdu content for stat item size + - 9p locks: add mount option for lock retry interval + - f2fs: fix to do sanity check with current segment number + - netfilter: xt_cgroup: shrink size of v2 path + - serial: uartps: console_setup() can't be placed to init section + - powerpc/pseries: Remove prrn_work workqueue + - media: au0828: cannot kfree dev before usb disconnect + - HID: i2c-hid: override HID descriptors for certain devices + - ARM: samsung: Limit SAMSUNG_PM_CHECK config option to non-Exynos platforms + - [Config] updateconfigs for CONFIG_SAMSUNG_PM_CHECK + - usbip: fix vhci_hcd controller counting + - ACPI / SBS: Fix GPE storm on recent MacBookPro's + - KVM: nVMX: restore host state in nested_vmx_vmexit for VMFail + - cifs: fallback to older infolevels on findfirst queryinfo retry + - kernel: hung_task.c: disable on suspend + - crypto: sha256/arm - fix crash bug in Thumb2 build + - crypto: sha512/arm - fix crash bug in Thumb2 build + - iommu/dmar: Fix buffer overflow during PCI bus notification + - soc/tegra: pmc: Drop locking from tegra_powergate_is_powered() + - lkdtm: Print real addresses + - lkdtm: Add tests for NULL pointer dereference + - drm/panel: panel-innolux: set display off in innolux_panel_unprepare + - crypto: axis - fix for recursive locking from bottom half + - Revert "ACPI / EC: Remove old CLEAR_ON_RESUME quirk" + - coresight: cpu-debug: Support for CA73 CPUs + - drm/nouveau/volt/gf117: fix speedo readout register + - ARM: 8839/1: kprobe: make patch_lock a raw_spinlock_t + - drm/amdkfd: use init_mqd function to allocate object for hid_mqd (CI) + - appletalk: Fix use-after-free in atalk_proc_exit + - lib/div64.c: off by one in shift + - include/linux/swap.h: use offsetof() instead of custom __swapoffset macro + - bpf: fix use after free in bpf_evict_inode + - dm: disable CRYPTO_TFM_REQ_MAY_SLEEP to fix a GFP_KERNEL recursion deadlock + - net: stmmac: Set dma ring length before enabling the DMA + - mm: hide incomplete nr_indirectly_reclaimable in sysfs + - appletalk: Fix compile regression + - ext4: avoid panic during forced reboot + - i40iw: Avoid panic when handling the inetdev event + - sched/core: Fix buffer overflow in cgroup2 property cpu.max + - ACPI / utils: Drop reference in test for device presence + - PM / Domains: Avoid a potential deadlock + - drm/exynos/mixer: fix MIXER shadow registry synchronisation code + - Bluetooth: Fix debugfs NULL pointer dereference + - f2fs: cleanup dirty pages if recover failed + - [Config] updateconfigs for CONFIG_INTEL_ATOMISP2_PM + - platform/x86: Add Intel AtomISP2 dummy / power-management driver + - drm/ttm: Fix bo_global and mem_global kfree error + - ALSA: hda: fix front speakers on Huawei MBXP + - ACPI: EC / PM: Disable non-wakeup GPEs for suspend-to-idle + - net/rds: fix warn in rds_message_alloc_sgs + - scsi: core: Avoid that system resume triggers a kernel warning + - PCI: Blacklist power management of Gigabyte X299 DESIGNARE EX PCIe ports + - rxrpc: Fix client call connect/disconnect race + - f2fs: fix to dirty inode for i_mode recovery + - bonding: fix event handling for stacked bonds + - net: atm: Fix potential Spectre v1 vulnerabilities + - net: bridge: fix per-port af_packet sockets + - net: bridge: multicast: use rcu to access port list from + br_multicast_start_querier + - net: fou: do not use guehdr after iptunnel_pull_offloads in gue_udp_recv + - tcp: tcp_grow_window() needs to respect tcp_space() + - team: set slave to promisc if team is already in promisc mode + - vhost: reject zero size iova range + - ipv4: recompile ip options in ipv4_link_failure + - ipv4: ensure rcu_read_lock() in ipv4_link_failure() + - net: thunderx: raise XDP MTU to 1508 + - net: thunderx: don't allow jumbo frames with XDP + - KVM: x86: Don't clear EFER during SMM transitions for 32-bit vCPU + - KVM: x86: svm: make sure NMI is injected after nmi_singlestep + - Staging: iio: meter: fixed typo + - staging: iio: ad7192: Fix ad7193 channel address + - iio: gyro: mpu3050: fix chip ID reading + - iio/gyro/bmg160: Use millidegrees for temperature scale + - iio: cros_ec: Fix the maths for gyro scale calculation + - iio: ad_sigma_delta: select channel when reading register + - iio: dac: mcp4725: add missing powerdown bits in store eeprom + - iio: Fix scan mask selection + - iio: adc: at91: disable adc channel interrupt in timeout case + - iio: core: fix a possible circular locking dependency + - io: accel: kxcjk1013: restore the range after resume. + - staging: comedi: vmk80xx: Fix use of uninitialized semaphore + - staging: comedi: vmk80xx: Fix possible double-free of ->usb_rx_buf + - staging: comedi: ni_usb6501: Fix use of uninitialized mutex + - staging: comedi: ni_usb6501: Fix possible double-free of ->usb_rx_buf + - ALSA: core: Fix card races between register and disconnect + - scsi: core: set result when the command cannot be dispatched + - coredump: fix race condition between mmget_not_zero()/get_task_mm() and core + dumping + - crypto: x86/poly1305 - fix overflow during partial reduction + - arm64: futex: Restore oldval initialization to work around buggy compilers + - x86/kprobes: Verify stack frame on kretprobe + - kprobes: Mark ftrace mcount handler functions nokprobe + - kprobes: Fix error check when reusing optimized probes + - rt2x00: do not increment sequence number while re-transmitting + - mac80211: do not call driver wake_tx_queue op during reconfig + - perf/x86/amd: Add event map for AMD Family 17h + - x86/cpu/bugs: Use __initconst for 'const' init data + - perf/x86: Fix incorrect PEBS_REGS + - x86/speculation: Prevent deadlock on ssb_state::lock + - crypto: crypto4xx - properly set IV after de- and encrypt + - mmc: sdhci: Fix data command CRC error handling + - mmc: sdhci: Rename SDHCI_ACMD12_ERR and SDHCI_INT_ACMD12ERR + - mmc: sdhci: Handle auto-command errors + - modpost: file2alias: go back to simple devtable lookup + - modpost: file2alias: check prototype of handler + - tpm/tpm_i2c_atmel: Return -E2BIG when the transfer is incomplete + - ipv6: frags: fix a lockdep false positive + - Revert "kbuild: use -Oz instead of -Os when using clang" + - device_cgroup: fix RCU imbalance in error case + - mm/vmstat.c: fix /proc/vmstat format for CONFIG_DEBUG_TLBFLUSH=y + CONFIG_SMP=n + - ALSA: info: Fix racy addition/deletion of nodes + - percpu: stop printing kernel addresses + - iomap: report collisions between directio and buffered writes to userspace + - i2c-hid: properly terminate i2c_hid_dmi_desc_override_table[] array + - net: Fix missing meta data in skb with vlan packet + - nfp: flower: replace CFI with vlan present + - nfp: flower: remove vlan CFI bit from push vlan action + - ip: add helpers to process in-order fragments faster. + - net: IP defrag: encapsulate rbtree defrag code into callable functions + - ip: process in-order fragments efficiently + - ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module + - net: IP6 defrag: use rbtrees for IPv6 defrag + - net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c + - cifs: fix handle leak in smb2_query_symlink() + - Input: elan_i2c - add hardware ID for multiple Lenovo laptops + - drm/ttm: fix out-of-bounds read in ttm_put_pages() v2 + - timers/sched_clock: Prevent generic sched_clock wrap caused by tick_freeze() + - tpm: Fix the type of the return value in calc_tpm2_event_size() + * Bionic update: upstream stable patchset 2019-07-26 (LP: #1838116) + - mmc: pxamci: fix enum type confusion + - drm/vmwgfx: Don't double-free the mode stored in par->set_mode + - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE + - libceph: wait for latest osdmap in ceph_monc_blacklist_add() + - udf: Fix crash on IO error during truncate + - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction. + - MIPS: Ensure ELF appended dtb is relocated + - MIPS: Fix kernel crash for R6 in jump label branch function + - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton + - scsi: ibmvscsi: Fix empty event pool access during host removal + - futex: Ensure that futex address is aligned in handle_futex_death() + - perf probe: Fix getting the kernel map + - objtool: Move objtool_file struct off the stack + - ALSA: x86: Fix runtime PM for hdmi-lpe-audio + - ext4: fix NULL pointer dereference while journal is aborted + - ext4: fix data corruption caused by unaligned direct AIO + - ext4: brelse all indirect buffer in ext4_ind_remove_space() + - media: v4l2-ctrls.c/uvc: zero v4l2_event + - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf() + - Bluetooth: Fix decrementing reference count twice in releasing socket + - Bluetooth: hci_ldisc: Initialize hci_dev before open() + - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in + hci_uart_set_proto() + - drm: Reorder set_property_atomic to avoid returning with an active ww_ctx + - netfilter: ebtables: remove BUGPRINT messages + - x86/unwind: Handle NULL pointer calls better in frame unwinder + - x86/unwind: Add hardcoded ORC entry for NULL + - locking/lockdep: Add debug_locks check in __lock_downgrade() + - ALSA: hda - Record the current power state before suspend/resume calls + - PCI: designware-ep: dw_pcie_ep_set_msi() should only set MMC bits + - PCI: designware-ep: Read-only registers need DBI_RO_WR_EN to be writable + - PCI: endpoint: Use EPC's device in dma_alloc_coherent()/dma_free_coherent() + - rtc: Fix overflow when converting time64_t to rtc_time + - sched/cpufreq/schedutil: Fix error path mutex unlock + - pwm-backlight: Enable/disable the PWM before/after LCD enable toggle. + - power: supply: charger-manager: Fix incorrect return value + - ath10k: avoid possible string overflow + - mmc: renesas_sdhi: limit block count to 16 bit for old revisions + - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038 + - RDMA/cma: Rollback source IP address if failing to acquire device + - f2fs: fix to avoid deadlock of atomic file operations + - loop: access lo_backing_file only when the loop device is Lo_bound + - video: fbdev: Set pixclock = 0 in goldfishfb + - dccp: do not use ipv6 header for ipv4 flow + - genetlink: Fix a memory leak on error path + - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S + - net: datagram: fix unbounded loop in __skb_try_recv_datagram() + - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec + - net: rose: fix a possible stack overflow + - net: stmmac: fix memory corruption with large MTUs + - net-sysfs: call dev_hold if kobject_init_and_add success + - packets: Always register packet sk in the same order + - rhashtable: Still do rehash when we get EEXIST + - tcp: do not use ipv6 header for ipv4 flow + - thunderx: enable page recycling for non-XDP case + - thunderx: eliminate extra calls to put_page() for pages held for recycling + - vxlan: Don't call gro_cells_destroy() before device is unregistered + - sctp: get sctphdr by offset in sctp_compute_cksum + - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6 + - mac8390: Fix mmio access size probe + - tun: properly test for IFF_UP + - tun: add a missing rcu_read_unlock() in error path + - powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E + - powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit platforms + - powerpc/fsl: Add infrastructure to fixup branch predictor flush + - powerpc/fsl: Add macro to flush the branch predictor + - powerpc/fsl: Emulate SPRN_BUCSR register + - powerpc/fsl: Flush the branch predictor at each kernel entry (64bit) + - powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit) + - powerpc/fsl: Flush branch predictor when entering KVM + - powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used + - powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup' + - powerpc/fsl: Fix the flush of branch predictor. + - Btrfs: fix incorrect file size after shrinking truncate and fsync + - btrfs: remove WARN_ON in log_dir_items + - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time + - powerpc: bpf: Fix generation of load/store DW instructions + - NFSv4.1 don't free interrupted slot on open + - net: dsa: qca8k: remove leftover phy accessors + - ALSA: pcm: Fix possible OOB access in PCM oss plugins + - ALSA: pcm: Don't suspend stream in unrecoverable PCM state + - kbuild: modversions: Fix relative CRC byte order interpretation + - fs/open.c: allow opening only regular files during execve() + - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock + - scsi: sd: Fix a race between closing an sd device and sd I/O + - scsi: sd: Quiesce warning if device does not report optimal I/O size + - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host + - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP + devices + - tty: atmel_serial: fix a potential NULL pointer dereference + - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest + - staging: vt6655: Remove vif check from vnt_interrupt + - staging: vt6655: Fix interrupt race condition on device start up. + - serial: max310x: Fix to avoid potential NULL pointer dereference + - serial: sh-sci: Fix setting SCSCR_TIE while transferring data + - USB: serial: cp210x: add new device id + - USB: serial: ftdi_sio: add additional NovaTech products + - USB: serial: mos7720: fix mos_parport refcount imbalance on error path + - USB: serial: option: set driver_info for SIM5218 and compatibles + - USB: serial: option: add support for Quectel EM12 + - USB: serial: option: add Olicard 600 + - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc + - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links + - drm/vgem: fix use-after-free when drm_gem_handle_create() fails + - gpio: exar: add a check for the return value of ida_simple_get fails + - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input + - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs + - usb: mtu3: fix EXTCON dependency + - USB: gadget: f_hid: fix deadlock in f_hidg_write() + - usb: common: Consider only available nodes for dr_mode + - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk + - xhci: Fix port resume done detection for SS ports with LPM enabled + - usb: cdc-acm: fix race during wakeup blocking TX traffic + - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate + - perf intel-pt: Fix TSC slip + - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n + - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y + - KVM: Reject device ioctls from processes other than the VM's creator + - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts + - vfio: ccw: only free cp on final interrupt + - ipmi_si: Fix crash when using hard-coded device + - gtp: change NET_UDP_TUNNEL dependency to select + - Btrfs: fix assertion failure on fsync with NO_HOLES enabled + - NFS: fix mount/umount race in nlmclnt. + - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286 + - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286 + - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic + - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256 + - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256 + - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256 + - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops + - drm/rockchip: Do not use memcpy for MMIO addresses + - drm/rockchip: vop: reset scale mode when win is disabled + - tty: mxs-auart: fix a potential NULL pointer dereference + - staging: speakup_soft: Fix alternate speech with other synths + - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference + - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check + - usb: xhci: dbc: Don't free all memory with spinlock held + - xhci: Don't let USB3 ports stuck in polling state prevent suspend + - mm: add support for kmem caches in DMA32 zone + - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging + - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified + - perf pmu: Fix parser error for uncore event alias + - objtool: Query pkg-config for libelf location + - bpf: do not restore dst_reg when cur_state is freed + - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals + - ext4: cleanup bh release code in ext4_ind_remove_space() + - tty/serial: atmel: Add is_half_duplex helper + - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped + - CIFS: fix POSIX lock leak and invalid ptr deref + - h8300: use cc-cross-prefix instead of hardcoding h8300-unknown-linux- + - f2fs: fix to avoid deadlock in f2fs_read_inline_dir() + - tracing: kdb: Fix ftdump to not sleep + - net/mlx5: Avoid panic when setting vport rate + - net/mlx5: Avoid panic when setting vport mac, getting vport config + - gpio: gpio-omap: fix level interrupt idling + - include/linux/relay.h: fix percpu annotation in struct rchan + - enic: fix build warning without CONFIG_CPUMASK_OFFSTACK + - scsi: hisi_sas: Set PHY linkrate when disconnected + - iio: adc: fix warning in Qualcomm PM8xxx HK/XOADC driver + - perf c2c: Fix c2c report for empty numa node + - mm/cma.c: cma_declare_contiguous: correct err handling + - mm/page_ext.c: fix an imbalance with kmemleak + - mm, mempolicy: fix uninit memory access + - mm/vmalloc.c: fix kernel BUG at mm/vmalloc.c:512! + - mm/slab.c: kmemleak no scan alien caches + - ocfs2: fix a panic problem caused by o2cb_ctl + - f2fs: do not use mutex lock in atomic context + - fs/file.c: initialize init_files.resize_wait + - page_poison: play nicely with KASAN + - cifs: use correct format characters + - dm thin: add sanity checks to thin-pool and external snapshot creation + - cifs: Fix NULL pointer dereference of devname + - jbd2: fix invalid descriptor block checksum + - fs: fix guard_bio_eod to check for real EOD errors + - tools lib traceevent: Fix buffer overflow in arg_eval + - PCI/PME: Fix hotplug/sysfs remove deadlock in pcie_pme_remove() + - wil6210: check null pointer in _wil_cfg80211_merge_extra_ies + - crypto: crypto4xx - add missing of_node_put after of_device_is_available + - crypto: cavium/zip - fix collision with generic cra_driver_name + - usb: chipidea: Grab the (legacy) USB PHY by phandle first + - scsi: core: replace GFP_ATOMIC with GFP_KERNEL in scsi_scan.c + - powerpc/xmon: Fix opcode being uninitialized in print_insn_powerpc + - coresight: etm4x: Add support to enable ETMv4.2 + - serial: 8250_pxa: honor the port number from devicetree + - ARM: 8840/1: use a raw_spinlock_t in unwind + - iommu/io-pgtable-arm-v7s: Only kmemleak_ignore L2 tables + - powerpc/hugetlb: Handle mmap_min_addr correctly in get_unmapped_area + callback + - mmc: omap: fix the maximum timeout setting + - e1000e: Fix -Wformat-truncation warnings + - mlxsw: spectrum: Avoid -Wformat-truncation warnings + - IB/mlx4: Increase the timeout for CM cache + - clk: fractional-divider: check parent rate only if flag is set + - cpufreq: acpi-cpufreq: Report if CPU doesn't support boost technologies + - efi: cper: Fix possible out-of-bounds access + - scsi: megaraid_sas: return error when create DMA pool failed + - scsi: fcoe: make use of fip_mode enum complete + - perf test: Fix failure of 'evsel-tp-sched' test on s390 + - SoC: imx-sgtl5000: add missing put_device() + - media: sh_veu: Correct return type for mem2mem buffer helpers + - media: s5p-jpeg: Correct return type for mem2mem buffer helpers + - media: s5p-g2d: Correct return type for mem2mem buffer helpers + - media: mx2_emmaprp: Correct return type for mem2mem buffer helpers + - media: mtk-jpeg: Correct return type for mem2mem buffer helpers + - vfs: fix preadv64v2 and pwritev64v2 compat syscalls with offset == -1 + - HID: intel-ish-hid: avoid binding wrong ishtp_cl_device + - jbd2: fix race when writing superblock + - leds: lp55xx: fix null deref on firmware load failure + - iwlwifi: pcie: fix emergency path + - ACPI / video: Refactor and fix dmi_is_desktop() + - kprobes: Prohibit probing on bsearch() + - netfilter: conntrack: fix cloned unconfirmed skb->_nfct race in + __nf_conntrack_confirm + - ARM: 8833/1: Ensure that NEON code always compiles with Clang + - ALSA: PCM: check if ops are defined before suspending PCM + - usb: f_fs: Avoid crash due to out-of-scope stack ptr access + - sched/topology: Fix percpu data types in struct sd_data & struct s_data + - bcache: fix input overflow to cache set sysfs file io_error_halflife + - bcache: fix input overflow to sequential_cutoff + - bcache: improve sysfs_strtoul_clamp() + - genirq: Avoid summation loops for /proc/stat + - iw_cxgb4: fix srqidx leak during connection abort + - fbdev: fbmem: fix memory access if logo is bigger than the screen + - cdrom: Fix race condition in cdrom_sysctl_register + - platform/x86: intel_pmc_core: Fix PCH IP sts reading + - ASoC: fsl-asoc-card: fix object reference leaks in fsl_asoc_card_probe + - sched/debug: Initialize sd_sysctl_cpus if !CONFIG_CPUMASK_OFFSTACK + - efi/memattr: Don't bail on zero VA if it equals the region's PA + - ARM: dts: lpc32xx: Remove leading 0x and 0s from bindings notation + - soc: qcom: gsbi: Fix error handling in gsbi_probe() + - mt7601u: bump supported EEPROM version + - ARM: 8830/1: NOMMU: Toggle only bits in EXC_RETURN we are really care of + - ARM: avoid Cortex-A9 livelock on tight dmb loops + - bpf: fix missing prototype warnings + - cgroup/pids: turn cgroup_subsys->free() into cgroup_subsys->release() to fix + the accounting + - backlight: pwm_bl: Use gpiod_get_value_cansleep() to get initial state + - tty: increase the default flip buffer limit to 2*640K + - powerpc/pseries: Perform full re-add of CPU for topology update post- + migration + - usb: dwc3: gadget: Fix OTG events when gadget driver isn't loaded + - media: mt9m111: set initial frame size other than 0x0 + - hwrng: virtio - Avoid repeated init of completion + - soc/tegra: fuse: Fix illegal free of IO base address + - HID: intel-ish: ipc: handle PIMR before ish_wakeup also clear PISR + busy_clear bit + - hpet: Fix missing '=' character in the __setup() code of hpet_mmap_enable + - cpu/hotplug: Mute hotplug lockdep during init + - dmaengine: imx-dma: fix warning comparison of distinct pointer types + - dmaengine: qcom_hidma: assign channel cookie correctly + - dmaengine: qcom_hidma: initialize tx flags in hidma_prep_dma_* + - netfilter: physdev: relax br_netfilter dependency + - media: s5p-jpeg: Check for fmt_ver_flag when doing fmt enumeration + - regulator: act8865: Fix act8600_sudcdc_voltage_ranges setting + - drm: Auto-set allow_fb_modifiers when given modifiers at plane init + - drm/nouveau: Stop using drm_crtc_force_disable + - x86/build: Specify elf_i386 linker emulation explicitly for i386 objects + - selinux: do not override context on context mounts + - wlcore: Fix memory leak in case wl12xx_fetch_firmware failure + - x86/build: Mark per-CPU symbols as absolute explicitly for LLD + - clk: rockchip: fix frac settings of GPLL clock for rk3328 + - dmaengine: tegra: avoid overflow of byte tracking + - drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers + - ACPI / video: Extend chassis-type detection with a "Lunch Box" check + - f2fs: fix to adapt small inline xattr space in __find_inline_xattr() + - net: stmmac: Avoid sometimes uninitialized Clang warnings + - libbpf: force fixdep compilation at the start of the build + - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO + - x86/hyperv: Fix kernel panic when kexec on HyperV + - mm/sparse: fix a bad comparison + - mm, swap: bounds check swap_info array accesses to avoid NULL derefs + - memcg: killed threads should not invoke memcg OOM killer + - cifs: Accept validate negotiate if server return NT_STATUS_NOT_SUPPORTED + - netfilter: nf_tables: check the result of dereferencing base_chain->stats + - netfilter: conntrack: tcp: only close if RST matches exact sequence + - kbuild: invoke syncconfig if include/config/auto.conf.cmd is missing + - mwifiex: don't advertise IBSS features without FW support + - perf report: Don't shadow inlined symbol with different addr range + - media: rockchip/rga: Correct return type for mem2mem buffer helpers + - selftests: skip seccomp get_metadata test if not real root + - kprobes: Prohibit probing on RCU debug routine + - bcache: fix potential div-zero error of writeback_rate_i_term_inverse + - drm: rcar-du: add missing of_node_put + - perf/aux: Make perf_event accessible to setup_aux() + - e1000e: Exclude device from suspend direct complete optimization + - i2c: of: Try to find an I2C adapter matching the parent + - sched/core: Use READ_ONCE()/WRITE_ONCE() in + move_queued_task()/task_rq_lock() + - powerpc/64s: Clear on-stack exception marker upon exception return + - platform/x86: intel-hid: Missing power button release on some Dell models + - pinctrl: meson: meson8b: add the eth_rxd2 and eth_rxd3 pins + - net: stmmac: Avoid one more sometimes uninitialized Clang warning + - bcache: fix potential div-zero error of writeback_rate_p_term_inverse + - net: sfp: move sfp_register_socket call from sfp_remove to sfp_probe + - drm/i915/gvt: do not let pin count of shadow mm go negative + - powerpc/tm: Limit TM code inside PPC_TRANSACTIONAL_MEM + - kbuild: clang: choose GCC_TOOLCHAIN_DIR not on LD + - x86: vdso: Use $LD instead of $CC to link + - x86/vdso: Drop implicit common-page-size linker flag + - lib/string.c: implement a basic bcmp + - stating: ccree: revert "staging: ccree: fix leak of import() after init()" + - arm64: kaslr: Reserve size of ARM64_MEMSTART_ALIGN in linear region + - tty: mark Siemens R3964 line discipline as BROKEN + - [Config] updateconfigs for CONFIG_R3964 (BROKEN) + - [Config] updateconfigs for CONFIG_LDISC_AUTOLOAD + - tty: ldisc: add sysctl to prevent autoloading of ldiscs + - ipv6: Fix dangling pointer when ipv6 fragment + - ipv6: sit: reset ip header pointer in ipip6_rcv + - kcm: switch order of device registration to fix a crash + - net-gro: Fix GRO flush when receiving a GSO packet. + - net/mlx5: Decrease default mr cache size + - net/sched: fix ->get helper of the matchall cls + - qmi_wwan: add Olicard 600 + - sctp: initialize _pad of sockaddr_in before copying to user memory + - tcp: Ensure DCTCP reacts to losses + - vrf: check accept_source_route on the original netdevice + - net/mlx5e: Fix error handling when refreshing TIRs + - net/mlx5e: Add a lock on tir list + - nfp: validate the return code from dev_queue_xmit() + - bnxt_en: Improve RX consumer index validity check. + - bnxt_en: Reset device on RX buffer errors. + - net/sched: act_sample: fix divide by zero in the traffic path + - netns: provide pure entropy for net_hash_mix() + - net: ethtool: not call vzalloc for zero sized memory request + - ALSA: seq: Fix OOB-reads from strlcpy + - ip6_tunnel: Match to ARPHRD_TUNNEL6 for dev type + - hv_netvsc: Fix unwanted wakeup after tx_disable + - arm64: dts: rockchip: fix rk3328 sdmmc0 write errors + - parisc: Detect QEMU earlier in boot process + - parisc: regs_return_value() should return gpr28 + - alarmtimer: Return correct remaining time + - drm/udl: add a release method and delay modeset teardown + - include/linux/bitrev.h: fix constant bitrev + - ASoC: fsl_esai: fix channel swap issue when stream starts + - Btrfs: do not allow trimming when a fs is mounted with the nologreplay + option + - btrfs: prop: fix zstd compression parameter validation + - btrfs: prop: fix vanished compression property after failed set + - block: do not leak memory in bio_copy_user_iov() + - block: fix the return errno for direct IO + - genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() + - genirq: Initialize request_mutex if CONFIG_SPARSE_IRQ=n + - virtio: Honour 'may_reduce_num' in vring_create_virtqueue + - ARM: dts: am335x-evmsk: Correct the regulators for the audio codec + - ARM: dts: am335x-evm: Correct the regulators for the audio codec + - ARM: dts: at91: Fix typo in ISC_D0 on PC9 + - arm64: futex: Fix FUTEX_WAKE_OP atomic ops with non-zero result value + - arm64: dts: rockchip: fix rk3328 rgmii high tx error rate + - arm64: backtrace: Don't bother trying to unwind the userspace stack + - xen: Prevent buffer overflow in privcmd ioctl + - sched/fair: Do not re-read ->h_load_next during hierarchical load + calculation + - xtensa: fix return_address + - x86/perf/amd: Resolve race condition when disabling PMC + - x86/perf/amd: Resolve NMI latency issues for active PMCs + - x86/perf/amd: Remove need to check "running" bit in NMI handler + - PCI: Add function 1 DMA alias quirk for Marvell 9170 SATA controller + - dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors + - arm64: dts: rockchip: fix vcc_host1_5v pin assign on rk3328-rock64 + - arm64: dts: rockchip: Fix vcc_host1_5v GPIO polarity on rk3328-rock64 + - tcp: fix a potential NULL pointer dereference in tcp_sk_exit + - nfp: disable netpoll on representors + - r8169: disable default rx interrupt coalescing on RTL8168 + - kbuild: deb-pkg: fix bindeb-pkg breakage when O= is used + - ACPICA: Namespace: remove address node from global list after method + termination + - ALSA: hda/realtek - Add quirk for Tuxedo XC 1509 + - mm/huge_memory.c: fix modifying of page protection by insert_pfn_pmd() + - riscv: Fix syscall_get_arguments() and syscall_set_arguments() + - x86/asm: Remove dead __GNUC__ conditionals + - dm integrity: change memcmp to strncmp in dm_integrity_ctr + * Bionic update: upstream stable patchset 2019-07-25 (LP: #1837952) + - ACPICA: Reference Counts: increase max to 0x4000 for large servers + - gro_cells: make sure device is up in gro_cells_receive() + - ipv4/route: fail early when inet dev is missing + - l2tp: fix infoleak in l2tp_ip6_recvmsg() + - net: hsr: fix memory leak in hsr_dev_finalize() + - net/hsr: fix possible crash in add_timer() + - net: sit: fix UBSAN Undefined behaviour in check_6rd + - net/x25: fix use-after-free in x25_device_event() + - net/x25: reset state in x25_connect() + - pptp: dst_release sk_dst_cache in pptp_sock_destruct + - ravb: Decrease TxFIFO depth of Q3 and Q2 to one + - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race + - rxrpc: Fix client call queueing, waiting for channel + - tcp: Don't access TCP_SKB_CB before initializing it + - tcp: handle inet_csk_reqsk_queue_add() failures + - vxlan: Fix GRO cells race condition between receive and link delete + - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() + - net/mlx4_core: Fix reset flow when in command polling mode + - net/mlx4_core: Fix locking in SRIOV mode when switching between events and + polling + - net/mlx4_core: Fix qp mtt size calculation + - net/x25: fix a race in x25_bind() + - net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 + - bonding: fix PACKET_ORIGDEV regression + - missing barriers in some of unix_sock ->addr and ->path accesses + - ipvlan: disallow userns cap_net_admin to change global mode/flags + - perf/x86: Fixup typo in stub functions + - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against + Liquid Saffire 56 + - ALSA: firewire-motu: fix construction of PCM frame for capture direction + - perf/x86/intel: Fix memory corruption + - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static + - It's wrong to add len to sector_nr in raid10 reshape twice + - sctp: remove sched init from sctp_stream_init + - team: use operstate consistently for linkup + - ipv6: route: enforce RCU protection in rt6_update_exception_stamp_rt() + - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240 + - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294 + - i40e: report correct statistics when XDP is enabled + - 9p: use inode->i_lock to protect i_size_write() under 32-bit + - 9p/net: fix memory leak in p9_client_create + - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode + - iio: adc: exynos-adc: Fix NULL pointer exception on unbind + - stm class: Fix an endless loop in channel allocation + - crypto: caam - fixed handling of sg list + - crypto: ahash - fix another early termination in hash walk + - crypto: rockchip - fix scatterlist nents error + - crypto: rockchip - update new iv to device in multiple operations + - drm/imx: ignore plane updates on disabled crtcs + - gpu: ipu-v3: Fix i.MX51 CSI control registers offset + - drm/imx: imx-ldb: add missing of_node_puts + - gpu: ipu-v3: Fix CSI offsets for imx53 + - s390/dasd: fix using offset into zero size array error + - Input: pwm-vibra - prevent unbalanced regulator + - Input: pwm-vibra - stop regulator after disabling pwm, not before + - ARM: OMAP2+: Variable "reg" in function omap4_dsi_mux_pads() could be + uninitialized + - ASoC: dapm: fix out-of-bounds accesses to DAPM lookup tables + - ASoC: rsnd: fixup rsnd_ssi_master_clk_start() user count check + - KVM: arm/arm64: Reset the VCPU without preemption and vcpu state loaded + - ARM: OMAP2+: fix lack of timer interrupts on CPU1 after hotplug + - Input: cap11xx - switch to using set_brightness_blocking() + - Input: ps2-gpio - flush TX work when closing port + - Input: matrix_keypad - use flush_delayed_work() + - mac80211: Fix Tx aggregation session tear down with ITXQs + - ipvs: fix dependency on nf_defrag_ipv6 + - floppy: check_events callback should not return a negative number + - NFS: Don't use page_file_mapping after removing the page + - mm/gup: fix gup_pmd_range() for dax + - Revert "mm: use early_pfn_to_nid in page_ext_init" + - mm: page_alloc: fix ref bias in page_frag_alloc() for 1-byte allocs + - net: hns: Fix object reference leaks in hns_dsaf_roce_reset() + - i2c: cadence: Fix the hold bit setting + - i2c: bcm2835: Clear current buffer pointers and counts after a transfer + - auxdisplay: ht16k33: fix potential user-after-free on module unload + - Input: st-keyscan - fix potential zalloc NULL dereference + - clk: sunxi-ng: v3s: Fix TCON reset de-assert bit + - clk: sunxi: A31: Fix wrong AHB gate number + - esp: Skip TX bytes accounting when sending from a request socket + - ARM: 8824/1: fix a migrating irq bug when hotplug cpu + - af_key: unconditionally clone on broadcast + - assoc_array: Fix shortcut creation + - keys: Fix dependency loop between construction record and auth key + - scsi: libiscsi: Fix race between iscsi_xmit_task and iscsi_complete_task + - net: systemport: Fix reception of BPDUs + - pinctrl: meson: meson8b: fix the sdxc_a data 1..3 pins + - qmi_wwan: apply SET_DTR quirk to Sierra WP7607 + - net: mv643xx_eth: disable clk on error path in mv643xx_eth_shared_probe() + - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush timeout issue + - ASoC: topology: free created components in tplg load error + - qed: Fix iWARP syn packet mac address validation. + - arm64: Relax GIC version check during early boot + - net: marvell: mvneta: fix DMA debug warning + - tmpfs: fix link accounting when a tmpfile is linked in + - ixgbe: fix older devices that do not support IXGBE_MRQC_L3L4TXSWEN + - ARCv2: lib: memcpy: fix doing prefetchw outside of buffer + - ARC: uacces: remove lp_start, lp_end from clobber list + - ARCv2: support manual regfile save on interrupts + - phonet: fix building with clang + - mac80211_hwsim: propagate genlmsg_reply return code + - net: thunderx: make CFG_DONE message to run through generic send-ack + sequence + - nfp: bpf: fix code-gen bug on BPF_ALU | BPF_XOR | BPF_K + - nfp: bpf: fix ALU32 high bits clearance bug + - net: set static variable an initial value in atl2_probe() + - tmpfs: fix uninitialized return value in shmem_link + - media: videobuf2-v4l2: drop WARN_ON in vb2_warn_zero_bytesused() + - stm class: Prevent division by zero + - libnvdimm/label: Clear 'updating' flag after label-set update + - libnvdimm, pfn: Fix over-trim in trim_pfn_device() + - libnvdimm/pmem: Honor force_raw for legacy pmem regions + - libnvdimm: Fix altmap reservation size calculation + - fix cgroup_do_mount() handling of failure exits + - crypto: arm/crct10dif - revert to C code for short inputs + - crypto: arm64/crct10dif - revert to C code for short inputs + - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails + - crypto: testmgr - skip crc32c context test for ahash algorithms + - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling + - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine + - CIFS: Do not reset lease state to NONE on lease break + - CIFS: Fix read after write for files with read caching + - tracing: Use strncpy instead of memcpy for string keys in hist triggers + - tracing: Do not free iter->trace in fail path of tracing_open_pipe() + - xen: fix dom0 boot on huge systems + - ACPI / device_sysfs: Avoid OF modalias creation for removed device + - mmc: sdhci-esdhc-imx: fix HS400 timing issue + - spi: ti-qspi: Fix mmap read when more than one CS in use + - spi: pxa2xx: Setup maximum supported DMA transfer length + - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35 + - regulator: max77620: Initialize values for DT properties + - regulator: s2mpa01: Fix step values for some LDOs + - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR + - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown + - s390/setup: fix early warning messages + - s390/virtio: handle find on invalid queue gracefully + - scsi: virtio_scsi: don't send sc payload with tmfs + - scsi: aacraid: Fix performance issue on logical drives + - scsi: sd: Optimal I/O size should be a multiple of physical block size + - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock + - fs/devpts: always delete dcache dentry-s in dput() + - splice: don't merge into linked buffers + - m68k: Add -ffreestanding to CFLAGS + - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl + - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes + - Btrfs: fix corruption reading shared and compressed extents after hole + punching + - crypto: pcbc - remove bogus memcpy()s with src == dest + - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer + - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table + - x86/kprobes: Prohibit probing on optprobe template code + - cpufreq: tegra124: add missing of_node_put() + - cpufreq: pxa2xx: remove incorrect __init annotation + - ext4: add mask of ext4 flags to swap + - ext4: fix crash during online resizing + - IB/hfi1: Close race condition on user context disable and close + - cxl: Wrap iterations over afu slices inside 'afu_list_lock' + - ext2: Fix underflow in ext2_max_size() + - clk: uniphier: Fix update register for CPU-gear + - clk: clk-twl6040: Fix imprecise external abort for pdmclk + - clk: ingenic: Fix round_rate misbehaving with non-integer dividers + - clk: ingenic: Fix doc of ingenic_cgu_div_info + - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() + - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place + - mm: hwpoison: fix thp split handing in soft_offline_in_use_page() + - mm/vmalloc: fix size check for remap_vmalloc_range_partial() + - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv + - device property: Fix the length used in PROPERTY_ENTRY_STRING() + - intel_th: Don't reference unassigned outputs + - parport_pc: fix find_superio io compare code, should use equal test. + - i2c: tegra: fix maximum transfer size + - crypto: arm64/aes-neonbs - fix returning final keystream block + - drm/i915: Relax mmap VMA check + - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO + - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart + - serial: 8250_pci: Fix number of ports for ACCES serial cards + - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954 + chip use the pci_pericom_setup() + - jbd2: clear dirty flag when revoking a buffer from an older transaction + - jbd2: fix compile warning when using JBUFFER_TRACE + - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock + - powerpc/32: Clear on-stack exception marker upon exception return + - powerpc/wii: properly disable use of BATs when requested. + - powerpc/powernv: Make opal log only readable by root + - powerpc/83xx: Also save/restore SPRG4-7 during suspend + - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest + - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning + - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR + configuration + - powerpc/traps: fix recoverability of machine check handling on book3s/32 + - powerpc/traps: Fix the message printed when stack overflows + - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify + - arm64: Fix HCR.TGE status for NMI contexts + - arm64: debug: Ensure debug handlers check triggering exception level + - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2 + - dm: fix to_sector() for 32bit + - dm integrity: limit the rate of error messages + - cpcap-charger: generate events for userspace + - NFS: Fix I/O request leakages + - NFS: Fix an I/O request leakage in nfs_do_recoalesce + - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror() + - nfsd: fix memory corruption caused by readdir + - nfsd: fix wrong check in write_v4_end_grace() + - NFSv4.1: Reinitialise sequence results before retransmitting a request + - PM / wakeup: Rework wakeup source timer cancellation + - x86/unwind/orc: Fix ORC unwind table alignment + - perf intel-pt: Fix CYC timestamp calculation after OVF + - perf auxtrace: Define auxtrace record alignment + - perf intel-pt: Fix overlap detection to identify consecutive buffers + correctly + - perf intel-pt: Fix overlap calculation for padding + - perf intel-pt: Fix divide by zero when TSC is not available + - md: Fix failed allocation of md_register_thread + - tpm/tpm_crb: Avoid unaligned reads in crb_recv() + - tpm: Unify the send callback behaviour + - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt + - media: imx: prpencvf: Stop upstream before disabling IDMA channel + - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming + - media: vimc: Add vimc-streamer for stream control + - media: imx: csi: Disable CSI immediately after last EOF + - media: imx: csi: Stop upstream before disabling IDMA channel + - drm/radeon/evergreen_cs: fix missing break in switch statement + - KVM: Call kvm_arch_memslots_updated() before updating memslots + - KVM: x86/mmu: Detect MMIO generation wrap in any address space + - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux + - KVM: nVMX: Sign extend displacements of VMX instr's mem operands + - KVM: nVMX: Apply addr size mask to effective address for VMX instructions + - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments + - s390/setup: fix boot crash for machine without EDAT-1 + - crypto: caam - fix hash context DMA unmap size + - crypto: caam - fix DMA mapping of stack memory + - KVM: arm/arm64: vgic: Make vgic_dist->lpi_list_lock a raw_spinlock + - arm/arm64: KVM: Allow a VCPU to fully reset itself + - arm/arm64: KVM: Don't panic on failure to properly reset system registers + - ASoC: samsung: Prevent clk_get_rate() calls in atomic context + - mac80211: call drv_ibss_join() on restart + - blk-mq: insert rq with DONTPREP to hctx dispatch list when requeue + - xprtrdma: Make sure Send CQ is allocated on an existing compvec + - net: dsa: bcm_sf2: potential array overflow in bcm_sf2_sw_suspend() + - x86/CPU: Add Icelake model number + - kallsyms: Handle too long symbols in kallsyms.c + - ARM: 8835/1: dma-mapping: Clear DMA ops on teardown + - net: dsa: bcm_sf2: Do not assume DSA master supports WoL + - qed: Fix iWARP buffer size provided for syn packet processing. + - mm: handle lru_add_drain_all for UP properly + - ARCv2: don't assume core 0x54 has dual issue + - bpf, lpm: fix lookup bug in map_delete_elem + - acpi/nfit: Fix bus command validation + - mmc:fix a bug when max_discard is 0 + - netfilter: ipt_CLUSTERIP: fix warning unused variable cn + - [Config] updateconfigs for CONFIG_SUN50I_ERRATUM_UNKNOWN1 + - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer + instability + - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code + - ext4: fix check of inode in swap_inode_boot_loader + - ext4: cleanup pagecache before swap i_data + - ext4: update quota information while swapping boot loader inode + - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit + - mm/memory.c: do_fault: avoid usage of stale vm_area_struct + - media: i2c: ov5640: Fix post-reset delay + - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit + - mfd: sm501: Fix potential NULL pointer dereference + - nfsd: fix performance-limiting session calculation + - svcrpc: fix UDP on servers with lots of threads + - stable-kernel-rules.rst: add link to networking patch queue + - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata + * Bionic update: upstream stable patchset 2019-07-24 (LP: #1837813) + - dt-bindings: eeprom: at24: add "atmel,24c2048" compatible string + - eeprom: at24: add support for 24c2048 + - blk-mq: fix a hung issue when fsync + - ARM: 8789/1: signal: copy registers using __copy_to_user() + - ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context + - ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state + - ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user() + - ARM: 8793/1: signal: replace __put_user_error with __put_user + - ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit + - ARM: 8795/1: spectre-v1.1: use put_user() for __put_user() + - ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization + - ARM: 8797/1: spectre-v1.1: harden __copy_to_user + - ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc + - ARM: make lookup_processor_type() non-__init + - ARM: split out processor lookup + - ARM: clean up per-processor check_bugs method call + - ARM: add PROC_VTABLE and PROC_TABLE macros + - ARM: spectre-v2: per-CPU vtables to work around big.Little systems + - ARM: ensure that processor vtables is not lost after boot + - ARM: fix the cockup in the previous patch + - ACPI: NUMA: Use correct type for printing addresses on i386-PAE + - perf test shell: Use a fallback to get the pathname in vfs_getname + - cpufreq: check if policy is inactive early in __cpufreq_get() + - drm/bridge: tc358767: add defines for DP1_SRCCTRL & PHY_2LANE + - drm/bridge: tc358767: fix single lane configuration + - drm/bridge: tc358767: fix initial DP0/1_SRCCTRL value + - drm/bridge: tc358767: reject modes which require too much BW + - drm/bridge: tc358767: fix output H/V syncs + - nvme-pci: use the same attributes when freeing host_mem_desc_bufs. + - ARM: dts: da850-evm: Correct the sound card name + - ARM: dts: da850-lcdk: Correct the sound card name + - ARM: dts: kirkwood: Fix polarity of GPIO fan lines + - gpio: pl061: handle failed allocations + - drm/nouveau: Don't disable polling in fallback mode + - drm/nouveau/falcon: avoid touching registers if engine is off + - cifs: Limit memory used by lock request calls to a page + - Revert "Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G" + - Input: elan_i2c - add ACPI ID for touchpad in Lenovo V330-15ISK + - perf/core: Fix impossible ring-buffer sizes warning + - perf/x86: Add check_period PMU callback + - ALSA: hda - Add quirk for HP EliteBook 840 G5 + - ALSA: usb-audio: Fix implicit fb endpoint setup by quirk + - kvm: vmx: Fix entry number check for add_atomic_switch_msr() + - Input: bma150 - register input device after setting private data + - Input: elantech - enable 3rd button support on Fujitsu CELSIUS H780 + - mm: proc: smaps_rollup: fix pss_locked calculation + - alpha: fix page fault handling for r16-r18 targets + - alpha: Fix Eiger NR_IRQS to 128 + - tracing/uprobes: Fix output for multiple string arguments + - x86/platform/UV: Use efi_runtime_lock to serialise BIOS calls + - signal: Restore the stop PTRACE_EVENT_EXIT + - md/raid1: don't clear bitmap bits on interrupted recovery. + - x86/a.out: Clear the dump structure initially + - dm crypt: don't overallocate the integrity tag space + - dm thin: fix bug where bio that overwrites thin block ignores FUA + - drm/i915: Prevent a race during I915_GEM_MMAP ioctl with WC set + - perf report: Fix wrong iteration count in --branch-history + - riscv: fix trace_sys_exit hook + - ARM: dts: da850-lcdk: Correct the audio codec regulators + - ARM: OMAP5+: Fix inverted nirq pin interrupts with irq_set_type + - ASoC: hdmi-codec: fix oops on re-probe + - riscv: Add pte bit to distinguish swap from invalid + - mmc: sunxi: Filter out unsupported modes declared in the device tree + - s390/zcrypt: fix specification exception on z196 during ap probe + - drm/i915: Block fbdev HPD processing during suspend + - dsa: mv88e6xxx: Ensure all pending interrupts are handled prior to exit + - net: fix IPv6 prefix route residue + - net: ipv4: use a dedicated counter for icmp_v4 redirect packets + - vsock: cope with memory allocation failure at socket creation time + - vxlan: test dev->flags & IFF_UP before calling netif_rx() + - hwmon: (lm80) Fix missing unlock on error in set_fan_div() + - mlxsw: __mlxsw_sp_port_headroom_set(): Fix a use of local variable + - net: Fix for_each_netdev_feature on Big endian + - net: phy: xgmiitorgmii: Support generic PHY status read + - net: stmmac: Fix a race in EEE enable callback + - net: stmmac: handle endianness in dwmac4_get_timestamp + - vhost: correctly check the return value of translate_desc() in log_used() + - net: Add header for usage of fls64() + - net: Do not allocate page fragments that are not skb aligned + - tcp: clear icsk_backoff in tcp_write_queue_purge() + - sunrpc: fix 4 more call sites that were using stack memory with a + scatterlist + - net/x25: do not hold the cpu too long in x25_new_lci() + - mISDN: fix a race in dev_expire_timer() + - ax25: fix possible use-after-free + - af_packet: fix raw sockets over 6in4 tunnel + - tcp: tcp_v4_err() should be more careful + - mmc: meson-gx: fix interrupt name + - ARM: 8834/1: Fix: kprobes: optimized kprobes illegal instruction + - tracing: Fix number of entries in trace header + - MIPS: eBPF: Always return sign extended 32b values + - mac80211: Restore vif beacon interval if start ap fails + - mac80211: Free mpath object when rhashtable insertion fails + - libceph: handle an empty authorize reply + - ceph: avoid repeatedly adding inode to mdsc->snap_flush_list + - numa: change get_mempolicy() to use nr_node_ids instead of MAX_NUMNODES + - proc, oom: do not report alien mms when setting oom_score_adj + - KEYS: allow reaching the keys quotas exactly + - mfd: ti_am335x_tscadc: Use PLATFORM_DEVID_AUTO while registering mfd cells + - pvcalls-back: set -ENOTCONN in pvcalls_conn_back_read + - mfd: twl-core: Fix section annotations on {,un}protect_pm_master + - mfd: db8500-prcmu: Fix some section annotations + - mfd: mt6397: Do not call irq_domain_remove if PMIC unsupported + - mfd: ab8500-core: Return zero in get_register_interruptible() + - mfd: bd9571mwv: Add volatile register to make DVFS work + - mfd: qcom_rpm: write fw_version to CTRL_REG + - mfd: wm5110: Add missing ASRC rate register + - mfd: tps65218: Use devm_regmap_add_irq_chip and clean up error path in + probe() + - mfd: mc13xxx: Fix a missing check of a register-read failure + - xen/pvcalls: remove set but not used variable 'intf' + - qed: Fix qed_chain_set_prod() for PBL chains with non power of 2 page count + - qed: Fix qed_ll2_post_rx_buffer_notify_fw() by adding a write memory barrier + - net: hns: Fix use after free identified by SLUB debug + - MIPS: ath79: Enable OF serial ports in the default config + - netfilter: nf_tables: fix leaking object reference count + - scsi: qla4xxx: check return code of qla4xxx_copy_from_fwddb_param + - scsi: isci: initialize shost fully before calling scsi_add_host() + - MIPS: jazz: fix 64bit build + - bpf: correctly set initial window on active Fast Open sender + - net: stmmac: Fix PCI module removal leak + - isdn: i4l: isdn_tty: Fix some concurrency double-free bugs + - scsi: ufs: Fix system suspend status + - scsi: qedi: Add ep_state for login completion on un-reachable targets + - always clear the X2APIC_ENABLE bit for PV guest + - drm/meson: add missing of_node_put + - atm: he: fix sign-extension overflow on large shift + - hwmon: (tmp421) Correct the misspelling of the tmp442 compatible attribute + in OF device ID table + - leds: lp5523: fix a missing check of return value of lp55xx_read + - bpf: bpf_setsockopt: reset sock dst on SO_MARK changes + - mlxsw: spectrum_switchdev: Do not treat static FDB entries as sticky + - net/mlx5e: Fix wrong (zero) TX drop counter indication for representor + - isdn: avm: Fix string plus integer warning from Clang + - batman-adv: fix uninit-value in batadv_interface_tx() + - ipv6: propagate genlmsg_reply return code + - net/mlx5e: Don't overwrite pedit action when multiple pedit used + - net/packet: fix 4gb buffer limit due to overflow check + - net: sfp: do not probe SFP module before we're attached + - sctp: call gso_reset_checksum when computing checksum in sctp_gso_segment + - team: avoid complex list operations in team_nl_cmd_options_set() + - sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach() + - net/mlx4_en: Force CHECKSUM_NONE for short ethernet frames + - inet_diag: fix reporting cgroup classid and fallback to priority + - RDMA/srp: Rework SCSI device reset handling + - KEYS: user: Align the payload buffer + - KEYS: always initialize keyring_index_key::desc_len + - parisc: Fix ptrace syscall number modification + - ARCv2: Enable unaligned access in early ASM code + - ARC: U-boot: check arguments paranoidly + - ARC: define ARCH_SLAB_MINALIGN = 8 + - net: validate untrusted gso packets without csum offload + - net: avoid false positives in untrusted gso validation + - Revert "bridge: do not add port to router list when receives query with + source 0.0.0.0" + - netfilter: nf_tables: fix flush after rule deletion in the same batch + - netfilter: nft_compat: use-after-free when deleting targets + - netfilter: ipv6: Don't preserve original oif for loopback address + - pinctrl: max77620: Use define directive for max77620_pinconf_param values + - phy: tegra: remove redundant self assignment of 'map' + - net: phylink: avoid resolving link state too early + - gpio: pxa: avoid attempting to set pin direction via pinctrl on MMP2 + - pvcalls-front: read all data before closing the connection + - pvcalls-front: don't try to free unallocated rings + - pvcalls-front: properly allocate sk + - mfd: cros_ec_dev: Add missing mfd_remove_devices() call in remove + - bpf: Fix [::] -> [::1] rewrite in sys_sendmsg + - watchdog: mt7621_wdt/rt2880_wdt: Fix compilation problem + - net/mlx4: Get rid of page operation after dma_alloc_coherent + - xprtrdma: Double free in rpcrdma_sendctxs_create() + - RDMA/mthca: Clear QP objects during their allocation + - powerpc/8xx: fix setting of pagetable for Abatron BDI debug tool. + - net: stmmac: Fix the logic of checking if RX Watchdog must be enabled + - scsi: ufs: Fix geometry descriptor size + - scsi: cxgb4i: add wait_for_completion() + - afs: Fix key refcounting in file locking code + - dpaa_eth: NETIF_F_LLTX requires to do our own update of trans_start + - mlxsw: pci: Return error on PCI reset timeout + - sctp: set stream ext to NULL after freeing it in sctp_stream_outq_migrate + - drm/amdgpu: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime + - gpu: drm: radeon: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime + - drm/amd/display: Fix MST reboot/poweroff sequence + - mac80211: allocate tailroom for forwarded mesh packets + - netfilter: ipt_CLUSTERIP: fix sleep-in-atomic bug in + clusterip_config_entry_put() + - net: stmmac: Fix reception of Broadcom switches tags + - drm/msm: Unblock writer if reader closes file + - ASoC: Intel: Haswell/Broadwell: fix setting for .dynamic field + - ALSA: compress: prevent potential divide by zero bugs + - ASoC: Variable "val" in function rt274_i2c_probe() could be uninitialized + - clk: vc5: Abort clock configuration without upstream clock + - thermal: int340x_thermal: Fix a NULL vs IS_ERR() check + - usb: dwc3: gadget: synchronize_irq dwc irq in suspend + - usb: dwc3: gadget: Fix the uninitialized link_state when udc starts + - usb: gadget: Potential NULL dereference on allocation error + - genirq: Make sure the initial affinity is not empty + - ASoC: dapm: change snprintf to scnprintf for possible overflow + - ASoC: imx-audmux: change snprintf to scnprintf for possible overflow + - selftests: seccomp: use LDLIBS instead of LDFLAGS + - selftests: gpio-mockup-chardev: Check asprintf() for error + - ARC: fix __ffs return value to avoid build warnings + - drivers: thermal: int340x_thermal: Fix sysfs race condition + - staging: rtl8723bs: Fix build error with Clang when inlining is disabled + - mac80211: fix miscounting of ttl-dropped frames + - sched/wait: Fix rcuwait_wake_up() ordering + - futex: Fix (possible) missed wakeup + - locking/rwsem: Fix (possible) missed wakeup + - drm/amd/powerplay: OD setting fix on Vega10 + - serial: fsl_lpuart: fix maximum acceptable baud rate with over-sampling + - staging: android: ion: Support cpu access during dma_buf_detach + - direct-io: allow direct writes to empty inodes + - writeback: synchronize sync(2) against cgroup writeback membership switches + - scsi: csiostor: fix NULL pointer dereference in csio_vport_set_state() + - net: altera_tse: fix connect_local_phy error path + - hv_netvsc: Fix ethtool change hash key error + - net: usb: asix: ax88772_bind return error when hw_reset fail + - net: dev_is_mac_header_xmit() true for ARPHRD_RAWIP + - ibmveth: Do not process frames after calling napi_reschedule + - mac80211: don't initiate TDLS connection if station is not associated to AP + - mac80211: Add attribute aligned(2) to struct 'action' + - cfg80211: extend range deviation for DMG + - KVM: nSVM: clear events pending from svm_complete_interrupts() when exiting + to L1 + - mmc: spi: Fix card detection during probe + - mmc: tmio_mmc_core: don't claim spurious interrupts + - mmc: tmio: fix access width of Block Count Register + - mmc: sdhci-esdhc-imx: correct the fix of ERR004536 + - MIPS: fix truncation in __cmpxchg_small for short values + - MIPS: eBPF: Fix icache flush end address + - x86/uaccess: Don't leak the AC flag into __put_user() value evaluation + - irq/matrix: Split out the CPU selection code into a helper + - irq/matrix: Spread managed interrupts on allocation + - genirq/matrix: Improve target CPU selection for managed interrupts. + - clk: tegra: dfll: Fix a potential Oop in remove() + - selftests/vm/gup_benchmark.c: match gup struct to kernel + - ARC: show_regs: lockdep: avoid page allocator... + - sched/wake_q: Fix wakeup ordering for wake_q + - drm/sun4i: hdmi: Fix usage of TMDS clock + - scsi: lpfc: nvme: avoid hang / use-after-free when destroying localport + - scsi: lpfc: nvmet: avoid hang / use-after-free when destroying targetport + - mmc: core: Fix NULL ptr crash from mmc_should_fail_request + - drm: Block fb changes for async plane updates + - hugetlbfs: fix races and page leaks during migration + - MIPS: BCM63XX: provide DMA masks for ethernet devices + - cpufreq: Use struct kobj_attribute instead of struct global_attr + - USB: serial: option: add Telit ME910 ECM composition + - USB: serial: cp210x: add ID for Ingenico 3070 + - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485 + - staging: comedi: ni_660x: fix missing break in switch statement + - staging: wilc1000: fix to set correct value for 'vif_num' + - staging: android: ion: fix sys heap pool's gfp_flags + - ip6mr: Do not call __IP6_INC_STATS() from preemptible context + - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in + mv88e6xxx_port_set_duplex + - net-sysfs: Fix mem leak in netdev_register_kobject + - team: Free BPF filter when unregistering netdev + - tipc: fix RDM/DGRAM connect() regression + - bnxt_en: Drop oversize TX packets to prevent errors. + - hv_netvsc: Fix IP header checksum for coalesced packets + - net: dsa: mv88e6xxx: Fix statistics on mv88e6161 + - net: dsa: mv88e6xxx: Fix u64 statistics + - netlabel: fix out-of-bounds memory accesses + - net: netem: fix skb length BUG_ON in __skb_to_sgvec + - net: phy: Micrel KSZ8061: link failure after cable connect + - net: phy: phylink: fix uninitialized variable in phylink_get_mac_state + - net: sit: fix memory leak in sit_init_net() + - tipc: fix race condition causing hung sendto + - tun: fix blocking read + - xen-netback: don't populate the hash cache on XenBus disconnect + - xen-netback: fix occasional leak of grant ref mappings under memory pressure + - tun: remove unnecessary memory barrier + - net: Add __icmp_send helper. + - net: avoid use IPCB in cipso_v4_error + - ipv4: Return error for RTA_VIA attribute + - ipv6: Return error for RTA_VIA attribute + - mpls: Return error for RTA_GATEWAY attribute + - net/sched: act_ipt: fix refcount leak when replace fails + - x86/CPU/AMD: Set the CPB bit unconditionally on F17h + - MIPS: irq: Allocate accurate order pages for irq stack + - xtensa: fix get_wchan + - Bluetooth: Fix locking in bt_accept_enqueue() for BH context + - scsi: core: reset host byte in DID_NEXUS_FAILURE case + - bpf: fix sanitation rewrite in case of non-pointers + - vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel + - perf core: Fix perf_proc_update_handler() bug + - perf tools: Handle TOPOLOGY headers with no CPU + - IB/{hfi1, qib}: Fix WC.byte_len calculation for UD_SEND_WITH_IMM + - iommu/amd: Call free_iova_fast with pfn in map_sg + - iommu/amd: Unmap all mapped pages in error path of map_sg + - ipvs: Fix signed integer overflow when setsockopt timeout + - iommu/amd: Fix IOMMU page flush when detach device from a domain + - xtensa: SMP: fix ccount_timer_shutdown + - selftests: cpu-hotplug: fix case where CPUs offline > CPUs present + - xtensa: SMP: fix secondary CPU initialization + - xtensa: smp_lx200_defconfig: fix vectors clash + - xtensa: SMP: mark each possible CPU as present + - xtensa: SMP: limit number of possible CPUs by NR_CPUS + - net: altera_tse: fix msgdma_tx_completion on non-zero fill_level case + - net: hns: Fix for missing of_node_put() after of_parse_phandle() + - net: hns: Fix wrong read accesses via Clause 45 MDIO protocol + - net: stmmac: dwmac-rk: fix error handling in rk_gmac_powerup() + - netfilter: ebtables: compat: un-break 32bit setsockopt when no rules are + present + - gpio: vf610: Mask all GPIO interrupts + - selftests: timers: use LDLIBS instead of LDFLAGS + - nfs: Fix NULL pointer dereference of dev_name + - qed: Fix bug in tx promiscuous mode settings + - qed: Fix LACP pdu drops for VFs + - qed: Fix VF probe failure while FLR + - qed: Fix system crash in ll2 xmit + - qed: Fix stack out of bounds bug + - scsi: libfc: free skb when receiving invalid flogi resp + - scsi: 53c700: pass correct "dev" to dma_alloc_attrs() + - platform/x86: Fix unmet dependency warning for SAMSUNG_Q10 + - cifs: fix computation for MAX_SMB2_HDR_SIZE + - x86/microcode/amd: Don't falsely trick the late loading mechanism + - arm64: kprobe: Always blacklist the KVM world-switch code + - apparmor: Fix aa_label_build() error handling for failed merges + - x86/kexec: Don't setup EFI info if EFI runtime is not enabled + - x86_64: increase stack size for KASAN_EXTRA + - mm, memory_hotplug: is_mem_section_removable do not pass the end of a zone + - mm, memory_hotplug: test_pages_in_a_zone do not pass the end of zone + - lib/test_kmod.c: potential double free in error handling + - fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() + - autofs: drop dentry reference only when it is never used + - autofs: fix error return in autofs_fill_super() + - ARM: dts: omap4-droid4: Fix typo in cpcap IRQ flags + - arm64: dts: renesas: r8a7796: Enable DMA for SCIF2 + - soc: fsl: qbman: avoid race in clearing QMan interrupt + - bpf: sock recvbuff must be limited by rmem_max in bpf_setsockopt() + - ARM: pxa: ssp: unneeded to free devm_ allocated data + - arm64: dts: add msm8996 compatible to gicv3 + - DTS: CI20: Fix bugs in ci20's device tree. + - usb: phy: fix link errors + - irqchip/mmp: Only touch the PJ4 IRQ & FIQ bits on enable/disable + - net: stmmac: Fallback to Platform Data clock in Watchdog conversion + - net: stmmac: Send TSO packets always from Queue 0 + - net: stmmac: Disable EEE mode earlier in XMIT callback + - irqchip/gic-v3-its: Fix ITT_entry_size accessor + - relay: check return of create_buf_file() properly + - bpf, selftests: fix handling of sparse CPU allocations + - bpf: fix lockdep false positive in percpu_freelist + - drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init + - dmaengine: at_xdmac: Fix wrongfull report of a channel as in use + - vsock/virtio: fix kernel panic after device hot-unplug + - vsock/virtio: reset connected sockets on device removal + - dmaengine: dmatest: Abort test in case of mapping error + - selftests: netfilter: fix config fragment CONFIG_NF_TABLES_INET + - selftests: netfilter: add simple masq/redirect test cases + - s390/qeth: fix use-after-free in error path + - perf symbols: Filter out hidden symbols from labels + - perf trace: Support multiple "vfs_getname" probes + - MIPS: Remove function size check in get_frame_info() + - i2c: omap: Use noirq system sleep pm ops to idle device for suspend + - fs: ratelimit __find_get_block_slow() failure message. + - qed: Fix EQ full firmware assert. + - qed: Consider TX tcs while deriving the max num_queues for PF. + - Input: wacom_serial4 - add support for Wacom ArtPad II tablet + - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20 + - iscsi_ibft: Fix missing break in switch statement + - scsi: aacraid: Fix missing break in switch statement + - arm64: dts: hikey: Give wifi some time after power-on + - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3 + - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU + - drm: disable uncached DMA optimization for ARM and arm64 + - ARM: 8781/1: Fix Thumb-2 syscall return for binutils 2.29+ + - gfs2: Fix missed wakeups in find_insert_glock + - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom + - perf/x86/intel: Make cpuc allocations consistent + - perf/x86/intel: Generalize dynamic constraint creation + - x86: Add TSX Force Abort CPUID/MSR + - perf/x86/intel: Implement support for TSX Force Abort + - perf script: Fix crash with printing mixed trace point and other events + - clk: ti: Fix error handling in ti_clk_parse_divider_data() + - riscv: Adjust mmap base address at a third of task size + - IB/ipoib: Fix for use-after-free in ipoib_cm_tx_start + - iomap: fix a use after free in iomap_dio_rw + - selftests: net: use LDLIBS instead of LDFLAGS + - scsi: scsi_debug: fix write_same with virtual_gb problem + - scsi: bnx2fc: Fix error handling in probe() + - ARM: OMAP: dts: N950/N9: fix onenand timings + - ARM: dts: sun8i: h3: Add ethernet0 alias to Beelink X2 + - ARM: dts: imx6sx: correct backward compatible of gpt + - pinctrl: mcp23s08: spi: Fix regmap allocation for mcp23s18 + - bpftool: Fix prog dump by tag + - bpftool: fix percpu maps updating + - batman-adv: release station info tidstats + - irqchip/gic-v4: Fix occasional VLPI drop + - s390/qeth: release cmd buffer in error paths + - nvme-pci: add missing unlock for reset error + - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub + - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4 + * Bionic update: upstream stable patchset 2019-07-23 (LP: #1837664) + - amd-xgbe: Fix mdio access for non-zero ports and clause 45 PHYs + - net: bridge: Fix ethernet header pointer before check skb forwardable + - net: Fix usage of pskb_trim_rcsum + - net: phy: mdio_bus: add missing device_del() in mdiobus_register() error + handling + - net_sched: refetch skb protocol for each filter + - openvswitch: Avoid OOB read when parsing flow nlattrs + - vhost: log dirty page correctly + - net: ipv4: Fix memory leak in network namespace dismantle + - tcp: allow MSG_ZEROCOPY transmission also in CLOSE_WAIT state + - mei: me: add denverton innovation engine device IDs + - USB: serial: simple: add Motorola Tetra TPG2200 device id + - USB: serial: pl2303: add new PID to support PL2303TB + - ASoC: atom: fix a missing check of snd_pcm_lib_malloc_pages + - ASoC: rt5514-spi: Fix potential NULL pointer dereference + - ARCv2: lib: memeset: fix doing prefetchw outside of buffer + - ARC: adjust memblock_reserve of kernel memory + - ARC: perf: map generic branches to correct hardware condition + - s390/smp: fix CPU hotplug deadlock with CPU rescan + - staging: rtl8188eu: Add device code for D-Link DWA-121 rev B1 + - tty: Handle problem if line discipline does not have receive_buf + - uart: Fix crash in uart_write and uart_put_char + - tty/n_hdlc: fix __might_sleep warning + - hv_balloon: avoid touching uninitialized struct page during tail onlining + - Drivers: hv: vmbus: Check for ring when getting debug info + - CIFS: Fix possible hang during async MTU reads and writes + - CIFS: Fix credits calculations for reads with errors + - CIFS: Fix credit calculation for encrypted reads with errors + - CIFS: Do not reconnect TCP session in add_credits() + - Input: xpad - add support for SteelSeries Stratus Duo + - compiler.h: enable builtin overflow checkers and add fallback code + - Input: uinput - fix undefined behavior in uinput_validate_absinfo() + - acpi/nfit: Block function zero DSMs + - acpi/nfit: Fix command-supported detection + - dm thin: fix passdown_double_checking_shared_status() + - dm crypt: fix parsing of extended IV arguments + - KVM: x86: Fix single-step debugging + - x86/pkeys: Properly copy pkey state at fork() + - x86/selftests/pkeys: Fork() to check for state being preserved + - x86/kaslr: Fix incorrect i8254 outb() parameters + - posix-cpu-timers: Unbreak timer rearming + - irqchip/gic-v3-its: Align PCI Multi-MSI allocation on their size + - can: dev: __can_get_echo_skb(): fix bogous check for non-existing skb by + removing it + - can: bcm: check timer values before ktime conversion + - vt: invoke notifier on screen size change + - Revert "seccomp: add a selftest for get_metadata" + - s390/smp: Fix calling smp_call_ipl_cpu() from ipl CPU + - nvmet-rdma: Add unlikely for response allocated check + - nvmet-rdma: fix null dereference under heavy load + - usb: dwc3: gadget: Clear req->needs_extra_trb flag on cleanup + - x86/xen/time: Output xen sched_clock time from 0 + - xen: Fix x86 sched_clock() interface for xen + - mlxsw: pci: Increase PCI SW reset timeout + - mlxsw: spectrum_fid: Update dummy FID index + - ASoC: tlv320aic32x4: Kernel OOPS while entering DAPM standby mode + - s390/mm: always force a load of the primary ASCE on context switch + - mmc: meson-gx: Free irq in release() callback + - vgacon: unconfuse vc_origin when using soft scrollback + - drm/amdgpu: Add APTX quirk for Lenovo laptop + - vt: always call notifier with the console lock held + - drm/meson: Fix atomic mode switching regression + - bpf: improve verifier branch analysis + - bpf: add per-insn complexity limit + - ipv6: Consider sk_bound_dev_if when binding a socket to an address + - ipv6: sr: clear IP6CB(skb) on SRH ip4ip6 encapsulation + - l2tp: copy 4 more bytes to linear part if necessary + - net/mlx4_core: Add masking for a few queries on HCA caps + - netrom: switch to sock timer API + - net/rose: fix NULL ax25_cb kernel panic + - net: set default network namespace in init_dummy_netdev() + - net/mlx5e: Allow MAC invalidation while spoofchk is ON + - Revert "net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager" + - virtio_net: Don't enable NAPI when interface is down + - virtio_net: Don't call free_old_xmit_skbs for xdp_frames + - virtio_net: Fix not restoring real_num_rx_queues + - sctp: improve the events for sctp stream adding + - sctp: improve the events for sctp stream reset + - l2tp: remove l2specific_len dependency in l2tp_core + - l2tp: fix reading optional fields of L2TPv3 + - ipvlan, l3mdev: fix broken l3s mode wrt local routes + - CIFS: Do not count -ENODATA as failure for query directory + - fs/dcache: Fix incorrect nr_dentry_unused accounting in shrink_dcache_sb() + - iommu/vt-d: Fix memory leak in intel_iommu_put_resv_regions() + - NFS: Fix up return value on fatal errors in nfs_page_async_flush() + - ARM: cns3xxx: Fix writing to wrong PCI config registers after alignment + - arm64: kaslr: ensure randomized quantities are clean also when kaslr is off + - arm64: hyp-stub: Forbid kprobing of the hyp-stub + - arm64: hibernate: Clean the __hyp_text to PoC after resume + - gpio: altera-a10sr: Set proper output level for direction_output + - gpio: pcf857x: Fix interrupts on multiple instances + - mmc: bcm2835: Fix DMA channel leak on probe error + - IB/hfi1: Remove overly conservative VM_EXEC flag check + - platform/x86: asus-nb-wmi: Map 0x35 to KEY_SCREENLOCK + - platform/x86: asus-nb-wmi: Drop mapping of 0x33 and 0x34 scan codes + - mmc: sdhci-iproc: handle mmc_of_parse() errors during probe + - kernel/exit.c: release ptraced tasks before zap_pid_ns_processes + - oom, oom_reaper: do not enqueue same task twice + - mm, oom: fix use-after-free in oom_kill_process + - mm: hwpoison: use do_send_sig_info() instead of force_sig() + - mm: migrate: don't rely on __PageMovable() of newpage after unlocking it + - md/raid5: fix 'out of memory' during raid cache recovery + - cifs: Always resolve hostname before reconnecting + - drivers: core: Remove glue dirs from sysfs earlier + - fanotify: fix handling of events on child sub-directory + - drm/msm/gpu: fix building without debugfs + - ravb: expand rx descriptor data to accommodate hw checksum + - tun: move the call to tun_set_real_num_queues + - sctp: set chunk transport correctly when it's a new asoc + - sctp: set flow sport from saddr only when it's 0 + - virtio_net: Don't process redirected XDP frames when XDP is disabled + - CIFS: Do not consider -ENODATA as stat failure for reads + - mmc: mediatek: fix incorrect register setting of hs400_cmd_int_delay + - ALSA: usb-audio: Add Opus #3 to quirks for native DSD support + - Btrfs: fix deadlock when allocating tree block during leaf/node split + - mm/hugetlb.c: teach follow_hugetlb_page() to handle FOLL_NOWAIT + - mm,memory_hotplug: fix scan_movable_pages() for gigantic hugepages + - of: Convert to using %pOFn instead of device_node.name + - of: overlay: add tests to validate kfrees from overlay removal + - of: overlay: add missing of_node_get() in __of_attach_node_sysfs + - of: overlay: use prop add changeset entry for property in new nodes + - ucc_geth: Reset BQL queue when stopping device + - staging: iio: adc: ad7280a: handle error from __ad7280_read32() + - drm/vgem: Fix vgem_init to get drm device available. + - pinctrl: bcm2835: Use raw spinlock for RT compatibility + - ASoC: Intel: mrfld: fix uninitialized variable access + - gpu: ipu-v3: image-convert: Prevent race between run and unprepare + - ath9k: dynack: use authentication messages for 'late' ack + - scsi: lpfc: Correct LCB RJT handling + - scsi: mpt3sas: Call sas_remove_host before removing the target devices + - scsi: lpfc: Fix LOGO/PLOGI handling when triggerd by ABTS Timeout event + - ARM: 8808/1: kexec:offline panic_smp_self_stop CPU + - clk: boston: fix possible memory leak in clk_boston_setup() + - dlm: Don't swamp the CPU with callbacks queued during recovery + - x86/PCI: Fix Broadcom CNB20LE unintended sign extension (redux) + - powerpc/pseries: add of_node_put() in dlpar_detach_node() + - crypto: aes_ti - disable interrupts while accessing S-box + - drm/vc4: ->x_scaling[1] should never be set to VC4_SCALING_NONE + - serial: fsl_lpuart: clear parity enable bit when disable parity + - ptp: check gettime64 return code in PTP_SYS_OFFSET ioctl + - MIPS: Boston: Disable EG20T prefetch + - staging:iio:ad2s90: Make probe handle spi_setup failure + - fpga: altera-cvp: Fix registration for CvP incapable devices + - Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1 + - platform/chrome: don't report EC_MKBP_EVENT_SENSOR_FIFO as wakeup + - staging: iio: ad7780: update voltage on read + - usbnet: smsc95xx: fix rx packet alignment + - drm/rockchip: fix for mailbox read size + - ARM: OMAP2+: hwmod: Fix some section annotations + - net/mlx5: EQ, Use the right place to store/read IRQ affinity hint + - modpost: validate symbol names also in find_elf_symbol + - perf tools: Add Hygon Dhyana support + - soc/tegra: Don't leak device tree node reference + - media: mtk-vcodec: Release device nodes in mtk_vcodec_init_enc_pm() + - ptp: Fix pass zero to ERR_PTR() in ptp_clock_register + - dmaengine: xilinx_dma: Remove __aligned attribute on zynqmp_dma_desc_ll + - iio: adc: meson-saradc: check for devm_kasprintf failure + - iio: adc: meson-saradc: fix internal clock names + - iio: accel: kxcjk1013: Add KIOX010A ACPI Hardware-ID + - media: adv*/tc358743/ths8200: fill in min width/height/pixelclock + - ACPI: SPCR: Consider baud rate 0 as preconfigured state + - staging: pi433: fix potential null dereference + - f2fs: move dir data flush to write checkpoint process + - f2fs: fix race between write_checkpoint and write_begin + - f2fs: fix wrong return value of f2fs_acl_create + - i2c: sh_mobile: add support for r8a77990 (R-Car E3) + - arm64: io: Ensure calls to delay routines are ordered against prior readX() + - sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN + - soc: bcm: brcmstb: Don't leak device tree node reference + - nfsd4: fix crash on writing v4_end_grace before nfsd startup + - drm: Clear state->acquire_ctx before leaving + drm_atomic_helper_commit_duplicated_state() + - arm64: io: Ensure value passed to __iormb() is held in a 64-bit register + - Thermal: do not clear passive state during system sleep + - firmware/efi: Add NULL pointer checks in efivars API functions + - s390/zcrypt: improve special ap message cmd handling + - arm64: ftrace: don't adjust the LR value + - ARM: dts: mmp2: fix TWSI2 + - x86/fpu: Add might_fault() to user_insn() + - media: DaVinci-VPBE: fix error handling in vpbe_initialize() + - smack: fix access permissions for keyring + - usb: dwc3: Correct the logic for checking TRB full in + __dwc3_prepare_one_trb() + - usb: hub: delay hub autosuspend if USB3 port is still link training + - timekeeping: Use proper seqcount initializer + - usb: mtu3: fix the issue about SetFeature(U1/U2_Enable) + - clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks + - driver core: Move async_synchronize_full call + - kobject: return error code if writing /sys/.../uevent fails + - IB/hfi1: Unreserve a reserved request when it is completed + - usb: dwc3: trace: add missing break statement to make compiler happy + - pinctrl: sx150x: handle failure case of devm_kstrdup + - iommu/amd: Fix amd_iommu=force_isolation + - ARM: dts: Fix OMAP4430 SDP Ethernet startup + - mips: bpf: fix encoding bug for mm_srlv32_op + - media: coda: fix H.264 deblocking filter controls + - ARM: dts: Fix up the D-Link DIR-685 MTD partition info + - watchdog: renesas_wdt: don't set divider while watchdog is running + - usb: dwc3: gadget: Disable CSP for stream OUT ep + - iommu/arm-smmu: Add support for qcom,smmu-v2 variant + - iommu/arm-smmu-v3: Use explicit mb() when moving cons pointer + - sata_rcar: fix deferred probing + - clk: imx6sl: ensure MMDC CH0 handshake is bypassed + - cpuidle: big.LITTLE: fix refcount leak + - OPP: Use opp_table->regulators to verify no regulator case + - i2c-axxia: check for error conditions first + - phy: sun4i-usb: add support for missing USB PHY index + - udf: Fix BUG on corrupted inode + - switchtec: Fix SWITCHTEC_IOCTL_EVENT_IDX_ALL flags overwrite + - selftests/bpf: use __bpf_constant_htons in test_prog.c + - ARM: pxa: avoid section mismatch warning + - ASoC: fsl: Fix SND_SOC_EUKREA_TLV320 build error on i.MX8M + - KVM: PPC: Book3S: Only report KVM_CAP_SPAPR_TCE_VFIO on powernv machines + - mmc: bcm2835: Recover from MMC_SEND_EXT_CSD + - mmc: bcm2835: reset host on timeout + - mmc: sdhci-of-esdhc: Fix timeout checks + - mmc: sdhci-xenon: Fix timeout checks + - tty: serial: samsung: Properly set flags in autoCTS mode + - perf test: Fix perf_event_attr test failure + - perf header: Fix unchecked usage of strncpy() + - perf probe: Fix unchecked usage of strncpy() + - arm64: KVM: Skip MMIO insn after emulation + - usb: musb: dsps: fix otg state machine + - percpu: convert spin_lock_irq to spin_lock_irqsave. + - powerpc/uaccess: fix warning/error with access_ok() + - mac80211: fix radiotap vendor presence bitmap handling + - xfrm6_tunnel: Fix spi check in __xfrm6_tunnel_alloc_spi + - mlxsw: spectrum: Properly cleanup LAG uppers when removing port from LAG + - scsi: smartpqi: correct host serial num for ssa + - scsi: smartpqi: correct volume status + - scsi: smartpqi: increase fw status register read timeout + - cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan() + - powerpc/perf: Fix thresholding counter data for unknown type + - drbd: narrow rcu_read_lock in drbd_sync_handshake + - drbd: disconnect, if the wrong UUIDs are attached on a connected peer + - drbd: skip spurious timeout (ping-timeo) when failing promote + - drbd: Avoid Clang warning about pointless switch statment + - video: clps711x-fb: release disp device node in probe() + - fbdev: fbmem: behave better with small rotated displays and many CPUs + - i40e: define proper net_device::neigh_priv_len + - ACPI/APEI: Clear GHES block_status before panic() + - fbdev: fbcon: Fix unregister crash when more than one framebuffer + - powerpc/mm: Fix reporting of kernel execute faults on the 8xx + - pinctrl: meson: meson8: fix the GPIO function for the GPIOAO pins + - pinctrl: meson: meson8b: fix the GPIO function for the GPIOAO pins + - KVM: x86: svm: report MSR_IA32_MCG_EXT_CTL as unsupported + - powerpc/fadump: Do not allow hot-remove memory from fadump reserved area. + - kvm: Change offset in kvm_write_guest_offset_cached to unsigned + - NFS: nfs_compare_mount_options always compare auth flavors. + - hwmon: (lm80) fix a missing check of the status of SMBus read + - hwmon: (lm80) fix a missing check of bus read in lm80 probe + - seq_buf: Make seq_buf_puts() null-terminate the buffer + - crypto: ux500 - Use proper enum in cryp_set_dma_transfer + - crypto: ux500 - Use proper enum in hash_set_dma_transfer + - MIPS: ralink: Select CONFIG_CPU_MIPSR2_IRQ_VI on MT7620/8 + - cifs: check ntwrk_buf_start for NULL before dereferencing it + - um: Avoid marking pages with "changed protection" + - niu: fix missing checks of niu_pci_eeprom_read + - f2fs: fix sbi->extent_list corruption issue + - cgroup: fix parsing empty mount option string + - scripts/decode_stacktrace: only strip base path when a prefix of the path + - ocfs2: don't clear bh uptodate for block read + - ocfs2: improve ocfs2 Makefile + - isdn: hisax: hfc_pci: Fix a possible concurrency use-after-free bug in + HFCPCI_l1hw() + - gdrom: fix a memory leak bug + - fsl/fman: Use GFP_ATOMIC in {memac,tgec}_add_hash_mac_address() + - block/swim3: Fix -EBUSY error when re-opening device after unmount + - thermal: bcm2835: enable hwmon explicitly + - kdb: Don't back trace on a cpu that didn't round up + - thermal: generic-adc: Fix adc to temp interpolation + - HID: lenovo: Add checks to fix of_led_classdev_register + - kernel/hung_task.c: break RCU locks based on jiffies + - proc/sysctl: fix return error for proc_doulongvec_minmax() + - kernel/hung_task.c: force console verbose before panic + - fs/epoll: drop ovflist branch prediction + - scripts/gdb: fix lx-version string output + - thermal: hwmon: inline helpers when CONFIG_THERMAL_HWMON is not set + - dccp: fool proof ccid_hc_[rt]x_parse_options() + - enic: fix checksum validation for IPv6 + - net: dp83640: expire old TX-skb + - rxrpc: bad unlock balance in rxrpc_recvmsg + - skge: potential memory corruption in skge_get_regs() + - rds: fix refcount bug in rds_sock_addref + - net: systemport: Fix WoL with password after deep sleep + - net/mlx5e: Force CHECKSUM_UNNECESSARY for short ethernet frames + - net: dsa: slave: Don't propagate flag changes on down slave interfaces + - ALSA: compress: Fix stop handling on compressed capture streams + - ALSA: hda - Serialize codec registrations + - dmaengine: bcm2835: Fix interrupt race on RT + - dmaengine: bcm2835: Fix abort of transactions + - dmaengine: imx-dma: fix wrong callback invoke + - futex: Handle early deadlock return correctly + - irqchip/gic-v3-its: Plug allocation race for devices sharing a DevID + - usb: phy: am335x: fix race condition in _probe + - usb: dwc3: gadget: Handle 0 xfer length for OUT EP + - usb: gadget: udc: net2272: Fix bitwise and boolean operations + - usb: gadget: musb: fix short isoc packets with inventra dma + - staging: speakup: fix tty-operation NULL derefs + - scsi: cxlflash: Prevent deadlock when adapter probe fails + - scsi: aic94xx: fix module loading + - cpu/hotplug: Fix "SMT disabled by BIOS" detection for KVM + - perf/x86/intel/uncore: Add Node ID mask + - x86/MCE: Initialize mce.bank in the case of a fatal error in + mce_no_way_out() + - perf/core: Don't WARN() for impossible ring-buffer sizes + - perf tests evsel-tp-sched: Fix bitwise operator + - serial: fix race between flush_to_ldisc and tty_open + - serial: 8250_pci: Make PCI class test non fatal + - IB/hfi1: Add limit test for RC/UC send via loopback + - perf/x86/intel: Delay memory deallocation until x86_pmu_dead_cpu() + - ath9k: dynack: make ewma estimation faster + - ath9k: dynack: check da->enabled first in sampling routines + - devres: Align data[] to ARCH_KMALLOC_MINALIGN + - genirq/affinity: Spread IRQs to all available NUMA nodes + - wil6210: fix memory leak in wil_find_tx_bcast_2 + - fpga: altera-cvp: fix 'bad IO access' on x86_64 + - drm/amd/display: calculate stream->phy_pix_clk before clock mapping + - net: aquantia: return 'err' if set MPI_DEINIT state fails + - perf: arm_spe: handle devm_kasprintf() failure + - xtensa: xtfpga.dtsi: fix dtc warnings about SPI + - media: imx274: select REGMAP_I2C + - drm/amdgpu/powerplay: fix clock stretcher limits on polaris (v2) + - tipc: fix node keep alive interval calculation + - mmc: meson-mx-sdio: check devm_kasprintf for failure + - mmc: sdhci-omap: Fix timeout checks + - mmc: jz4740: Get CD/WP GPIOs from descriptors + - usb: renesas_usbhs: add support for RZ/G2E + - i2c: sh_mobile: Add support for r8a774c0 (RZ/G2E) + - livepatch: check kzalloc return values + - usb: musb: dsps: fix runtime pm for peripheral mode + - perf header: Fix up argument to ctime() + - drm/amd/display: Add retry to read ddc_clock pin + - Bluetooth: hci_bcm: Handle deferred probing for the clock supply + - mlx5: update timecounter at least twice per counter overflow + - drm/amd/display: validate extended dongle caps + - perf build: Don't unconditionally link the libbfd feature test to -liberty + and -lz + - PCI: imx: Enable MSI from downstream components + - arm64/sve: ptrace: Fix SVE_PT_REGS_OFFSET definition + - kernel/kcov.c: mark write_comp_data() as notrace + - xfs: Fix xqmstats offsets in /proc/fs/xfs/xqmstat + - xfs: Fix error code in 'xfs_ioc_getbmap()' + - xfs: fix shared extent data corruption due to missing cow reservation + - xfs: fix transient reference count error in xfs_buf_resubmit_failed_buffers + - xfs: delalloc -> unwritten COW fork allocation can go wrong + - fs/xfs: fix f_ffree value for statfs when project quota is set + - lib/test_rhashtable: Make test_insert_dup() allocate its hash table + dynamically + - net: dsa: Fix lockdep false positive splat + - Revert "net: phy: marvell: avoid pause mode on SGMII-to-Copper for 88e151x" + - ALSA: hda/realtek - Fix lose hp_pins for disable auto mute + - serial: sh-sci: Do not free irqs that have already been freed + - mtd: rawnand: gpmi: fix MX28 bus master lockup problem + - iio: adc: axp288: Fix TS-pin handling + - iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius + - signal: Always notice exiting tasks + - signal: Better detection of synchronous signals + - misc: vexpress: Off by one in vexpress_syscfg_exec() + - samples: mei: use /dev/mei0 instead of /dev/mei + - debugfs: fix debugfs_rename parameter checking + - tracing: uprobes: Fix typo in pr_fmt string + - mips: cm: reprime error cause + - MIPS: OCTEON: don't set octeon_dma_bar_type if PCI is disabled + - MIPS: VDSO: Include $(ccflags-vdso) in o32,n32 .lds builds + - ARM: iop32x/n2100: fix PCI IRQ mapping + - ARM: tango: Improve ARCH_MULTIPLATFORM compatibility + - mac80211: ensure that mgmt tx skbs have tailroom for encryption + - drm/modes: Prevent division by zero htotal + - drm/vmwgfx: Fix setting of dma masks + - drm/vmwgfx: Return error code from vmw_execbuf_copy_fence_user + - HID: debug: fix the ring buffer implementation + - libceph: avoid KEEPALIVE_PENDING races in ceph_con_keepalive() + - xfrm: refine validation of template and selector families + - batman-adv: Avoid WARN on net_device without parent in netns + - batman-adv: Force mac header to start of data on xmit + - uio: Reduce return paths from uio_write() + - uio: Prevent device destruction while fds are open + - uio: change to use the mutex lock instead of the spin lock + - uio: fix crash after the device is unregistered + - uio: fix wrong return value from uio_mmap() + - uio: fix possible circular locking dependency + - mtd: Make sure mtd->erasesize is valid even if the partition is of size 0 + - libata: Add NOLPM quirk for SAMSUNG MZ7TE512HMHP-000L1 SSD + - mips: loongson64: remove unreachable(), fix loongson_poweroff(). + - SUNRPC: Always drop the XPRT_LOCK on XPRT_CLOSE_WAIT + * HP ProBook 470 G5, LED's in Hotkeys f5, f8 and f11 without function + (LP: #1811254) // Bionic update: upstream stable patchset 2019-07-23 + (LP: #1837664) + - ALSA: hda - Add mute LED support for HP ProBook 470 G5 + * Bionic update: upstream stable patchset 2019-07-22 (LP: #1837477) + - pinctrl: meson: fix pull enable register calculation + - powerpc: Fix COFF zImage booting on old powermacs + - powerpc/mm: Fix linux page tables build with some configs + - HID: ite: Add USB id match for another ITE based keyboard rfkill key quirk + - ARM: imx: update the cpu power up timing setting on i.mx6sx + - ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock + - Input: restore EV_ABS ABS_RESERVED + - checkstack.pl: fix for aarch64 + - xfrm: Fix error return code in xfrm_output_one() + - xfrm: Fix bucket count reported to userspace + - xfrm: Fix NULL pointer dereference in xfrm_input when skb_dst_force clears + the dst_entry. + - netfilter: seqadj: re-load tcp header pointer after possible head + reallocation + - scsi: bnx2fc: Fix NULL dereference in error handling + - Input: omap-keypad - fix idle configuration to not block SoC idle states + - Input: synaptics - enable RMI on ThinkPad T560 + - ibmvnic: Fix non-atomic memory allocation in IRQ context + - ieee802154: ca8210: fix possible u8 overflow in ca8210_rx_done + - i40e: fix mac filter delete when setting mac address + - netfilter: ipset: do not call ipset_nest_end after nla_nest_cancel + - netfilter: nat: can't use dst_hold on noref dst + - bnx2x: Clear fip MAC when fcoe offload support is disabled + - bnx2x: Remove configured vlans as part of unload sequence. + - bnx2x: Send update-svid ramrod with retry/poll flags enabled + - scsi: target: iscsi: cxgbit: add missing spin_lock_init() + - x86, hyperv: remove PCI dependency + - drivers: net: xgene: Remove unnecessary forward declarations + - w90p910_ether: remove incorrect __init annotation + - SUNRPC: Fix a race with XPRT_CONNECTING + - qed: Fix an error code qed_ll2_start_xmit() + - net: macb: fix random memory corruption on RX with 64-bit DMA + - net: macb: fix dropped RX frames due to a race + - lan78xx: Resolve issue with changing MAC address + - vxge: ensure data0 is initialized in when fetching firmware version + information + - mac80211: free skb fraglist before freeing the skb + - kbuild: fix false positive warning/error about missing libelf + - virtio: fix test build after uio.h change + - gpio: mvebu: only fail on missing clk if pwm is actually to be used + - Input: synaptics - enable SMBus for HP EliteBook 840 G4 + - net: netxen: fix a missing check and an uninitialized use + - qmi_wwan: Fix qmap header retrieval in qmimux_rx_fixup + - serial/sunsu: fix refcount leak + - scsi: zfcp: fix posting too many status read buffers leading to adapter + shutdown + - scsi: lpfc: do not set queue->page_count to 0 if pc_sli4_params.wqpcnt is + invalid + - tools: fix cross-compile var clobbering + - zram: fix double free backing device + - hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined + - mm, devm_memremap_pages: mark devm_memremap_pages() EXPORT_SYMBOL_GPL + - mm, devm_memremap_pages: kill mapping "System RAM" support + - mm, hmm: use devm semantics for hmm_devmem_{add, remove} + - mm, hmm: mark hmm_devmem_{add, add_resource} EXPORT_SYMBOL_GPL + - mm, swap: fix swapoff with KSM pages + - sunrpc: fix cache_head leak due to queued request + - powerpc: avoid -mno-sched-epilog on GCC 4.9 and newer + - powerpc: Disable -Wbuiltin-requires-header when setjmp is used + - ftrace: Build with CPPFLAGS to get -Qunused-arguments + - kbuild: add -no-integrated-as Clang option unconditionally + - kbuild: consolidate Clang compiler flags + - Makefile: Export clang toolchain variables + - powerpc/boot: Set target when cross-compiling for clang + - raid6/ppc: Fix build for clang + - ALSA: cs46xx: Potential NULL dereference in probe + - ALSA: usb-audio: Avoid access before bLength check in build_audio_procunit() + - ALSA: usb-audio: Fix an out-of-bound read in create_composite_quirks + - dlm: fixed memory leaks after failed ls_remove_names allocation + - dlm: possible memory leak on error path in create_lkb() + - dlm: lost put_lkb on error path in receive_convert() and receive_unlock() + - dlm: memory leaks on error path in dlm_user_request() + - gfs2: Get rid of potential double-freeing in gfs2_create_inode + - b43: Fix error in cordic routine + - selinux: policydb - fix byte order and alignment issues + - scripts/kallsyms: filter arm64's __efistub_ symbols + - arm64: drop linker script hack to hide __efistub_ symbols + - arm64: relocatable: fix inconsistencies in linker script and options + - powerpc/tm: Set MSR[TS] just prior to recheckpoint + - 9p/net: put a lower bound on msize + - rxe: fix error completion wr_id and qp_num + - iommu/vt-d: Handle domain agaw being less than iommu agaw + - sched/fair: Fix infinite loop in update_blocked_averages() by reverting + a9e7f6544b9c + - ceph: don't update importing cap's mseq when handing cap export + - genwqe: Fix size check + - intel_th: msu: Fix an off-by-one in attribute store + - power: supply: olpc_battery: correct the temperature units + - lib: fix build failure in CONFIG_DEBUG_VIRTUAL test + - drm/vc4: Set ->is_yuv to false when num_planes == 1 + - bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw + - tools: power/acpi, revert to LD = gcc + - ARM: dts: sun8i: a83t: bananapi-m3: increase vcc-pd voltage to 3.3V + - arm64: dts: mt7622: fix no more console output on rfb1 + - ibmvnic: Convert reset work item mutex to spin lock + - ixgbe: Fix race when the VF driver does a reset + - net: macb: add missing barriers when reading descriptors + - powerpc: remove old GCC version checks + - Fix failure path in alloc_pid() + - block: deactivate blk_stat timer in wbt_disable_default() + - PCI / PM: Allow runtime PM without callback functions + - leds: pwm: silently error out on EPROBE_DEFER + - Revert "powerpc/tm: Unset MSR[TS] if not recheckpointing" + - iio: dac: ad5686: fix bit shift read register + - video: fbdev: pxafb: Fix "WARNING: invalid free of devm_ allocated data" + - drivers/perf: hisi: Fixup one DDRC PMU register offset + - drm/nouveau/drm/nouveau: Check rc from drm_dp_mst_topology_mgr_resume() + - drm/rockchip: psr: do not dereference encoder before it is null checked. + - CIFS: Fix adjustment of credits for MTU requests + - CIFS: Do not hide EINTR after sending network packets + - cifs: Fix potential OOB access of lock element array + - usb: cdc-acm: send ZLP for Telit 3G Intel based modems + - USB: storage: don't insert sane sense for SPC3+ when bad sense specified + - USB: storage: add quirk for SMI SM3350 + - USB: Add USB_QUIRK_DELAY_CTRL_MSG quirk for Corsair K70 RGB + - slab: alien caches must not be initialized if the allocation of the alien + cache failed + - mm: page_mapped: don't assume compound page is huge or THP + - mm, memcg: fix reclaim deadlock with writeback + - ACPI: power: Skip duplicate power resource references in _PRx + - ACPI / PMIC: xpower: Fix TS-pin current-source handling + - i2c: dev: prevent adapter retries and timeout being set as minus value + - drm/fb-helper: Partially bring back workaround for bugs of SDL 1.2 + - rbd: don't return 0 on unmap if RBD_DEV_FLAG_REMOVING is set + - ext4: make sure enough credits are reserved for dioread_nolock writes + - ext4: fix a potential fiemap/page fault deadlock w/ inline_data + - ext4: avoid kernel warning when writing the superblock to a dead device + - ext4: track writeback errors using the generic tracking infrastructure + - KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less + - Btrfs: fix deadlock when using free space tree due to block group creation + - mm/usercopy.c: no check page span for stack objects + - vfio/type1: Fix unmap overflow off-by-one + - drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume() + - ext4: fix special inode number checks in __ext4_iget() + - Btrfs: fix access to available allocation bits when starting balance + - Btrfs: use nofs context when initializing security xattrs to avoid deadlock + - tty/ldsem: Wake up readers after timed out down_write() + - can: gw: ensure DLC boundaries after CAN frame modification + - mmc: sdhci-msm: Disable CDR function on TX + - media: em28xx: Fix misplaced reset of dev->v4l::field_count + - scsi: target: iscsi: cxgbit: fix csk leak + - scsi: target: iscsi: cxgbit: fix csk leak + - arm64/kvm: consistently handle host HCR_EL2 flags + - arm64: Don't trap host pointer auth use to EL2 + - ipv6: fix kernel-infoleak in ipv6_local_error() + - net: bridge: fix a bug on using a neighbour cache entry without checking its + state + - packet: Do not leak dev refcounts on error exit + - bonding: update nest level on unlink + - ip: on queued skb use skb_header_pointer instead of pskb_may_pull + - crypto: caam - fix zero-length buffer DMA mapping + - crypto: authencesn - Avoid twice completion call in decrypt path + - crypto: bcm - convert to use crypto_authenc_extractkeys() + - btrfs: wait on ordered extents on abort cleanup + - Yama: Check for pid death before checking ancestry + - scsi: core: Synchronize request queue PM status only on successful resume + - scsi: sd: Fix cache_type_store() + - crypto: talitos - reorder code in talitos_edesc_alloc() + - crypto: talitos - fix ablkcipher for CONFIG_VMAP_STACK + - mips: fix n32 compat_ipc_parse_version + - MIPS: lantiq: Fix IPI interrupt handling + - OF: properties: add missing of_node_put + - mfd: tps6586x: Handle interrupts on suspend + - media: v4l: ioctl: Validate num_planes for debug messages + - pstore/ram: Avoid allocation and leak of platform data + - arm64: kaslr: ensure randomized quantities are clean to the PoC + - Disable MSI also when pcie-octeon.pcie_disable on + - omap2fb: Fix stack memory disclosure + - media: vivid: fix error handling of kthread_run + - media: vivid: set min width/height to a value > 0 + - bpf: in __bpf_redirect_no_mac pull mac only if present + - LSM: Check for NULL cred-security on free + - media: vb2: vb2_mmap: move lock up + - sunrpc: handle ENOMEM in rpcb_getport_async + - netfilter: ebtables: account ebt_table_info to kmemcg + - selinux: fix GPF on invalid policy + - blockdev: Fix livelocks on loop device + - sctp: allocate sctp_sockaddr_entry with kzalloc + - tipc: fix uninit-value in tipc_nl_compat_link_reset_stats + - tipc: fix uninit-value in tipc_nl_compat_bearer_enable + - tipc: fix uninit-value in tipc_nl_compat_link_set + - tipc: fix uninit-value in tipc_nl_compat_name_table_dump + - tipc: fix uninit-value in tipc_nl_compat_doit + - block/loop: Don't grab "struct file" for vfs_getattr() operation. + - loop: drop caches if offset or block_size are changed + - drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock + - media: vb2: be sure to unlock mutex on errors + - nbd: Use set_blocksize() to set device blocksize + - tun: publish tfile after it's fully initialized + - crypto: sm3 - fix undefined shift by >= width of value + - MIPS: BCM47XX: Setup struct device for the SoC + - RDMA/vmw_pvrdma: Return the correct opcode when creating WR + - arm64: dts: marvell: armada-ap806: reserve PSCI area + - ipv6: make icmp6_send() robust against null skb->dev + - block: use rcu_work instead of call_rcu to avoid sleep in softirq + - selftests: Fix test errors related to lib.mk khdr target + - ipv6: Consider sk_bound_dev_if when binding a socket to a v4 mapped address + - mlxsw: spectrum: Disable lag port TX before removing it + - mlxsw: spectrum_switchdev: Set PVID correctly during VLAN deletion + - net, skbuff: do not prefer skb allocation fails early + - qmi_wwan: add MTU default to qmap network interface + - ipv6: Take rcu_read_lock in __inet6_bind for mapped addresses + - net: dsa: mv88x6xxx: mv88e6390 errata + - gpio: pl061: Move irq_chip definition inside struct pl061 + - platform/x86: asus-wmi: Tell the EC the OS will handle the display off + hotkey + - e1000e: allow non-monotonic SYSTIM readings + - writeback: don't decrement wb->refcnt if !wb->bdi + - serial: set suppress_bind_attrs flag only if builtin + - ALSA: oxfw: add support for APOGEE duet FireWire + - x86/mce: Fix -Wmissing-prototypes warnings + - MIPS: SiByte: Enable swiotlb for SWARM, LittleSur and BigSur + - arm64: perf: set suppress_bind_attrs flag to true + - usb: gadget: udc: renesas_usb3: add a safety connection way for + forced_b_device + - selinux: always allow mounting submounts + - rxe: IB_WR_REG_MR does not capture MR's iova field + - jffs2: Fix use of uninitialized delayed_work, lockdep breakage + - clk: imx: make mux parent strings const + - pstore/ram: Do not treat empty buffers as valid + - powerpc/xmon: Fix invocation inside lock region + - powerpc/pseries/cpuidle: Fix preempt warning + - media: firewire: Fix app_info parameter type in avc_ca{,_app}_info + - media: venus: core: Set dma maximum segment size + - net: call sk_dst_reset when set SO_DONTROUTE + - scsi: target: use consistent left-aligned ASCII INQUIRY data + - selftests: do not macro-expand failed assertion expressions + - clk: imx6q: reset exclusive gates on init + - arm64: Fix minor issues with the dcache_by_line_op macro + - kconfig: fix file name and line number of warn_ignored_character() + - kconfig: fix memory leak when EOF is encountered in quotation + - mmc: atmel-mci: do not assume idle after atmci_request_end + - btrfs: improve error handling of btrfs_add_link + - tty/serial: do not free trasnmit buffer page under port lock + - perf intel-pt: Fix error with config term "pt=0" + - perf svghelper: Fix unchecked usage of strncpy() + - perf parse-events: Fix unchecked usage of strncpy() + - netfilter: ipt_CLUSTERIP: check MAC address when duplicate config is set + - dm crypt: use u64 instead of sector_t to store iv_offset + - dm kcopyd: Fix bug causing workqueue stalls + - tools lib subcmd: Don't add the kernel sources to the include path + - dm snapshot: Fix excessive memory usage and workqueue stalls + - quota: Lock s_umount in exclusive mode for Q_XQUOTA{ON,OFF} quotactls. + - clocksource/drivers/integrator-ap: Add missing of_node_put() + - ALSA: bebob: fix model-id of unit for Apogee Ensemble + - sysfs: Disable lockdep for driver bind/unbind files + - IB/usnic: Fix potential deadlock + - scsi: smartpqi: correct lun reset issues + - scsi: smartpqi: call pqi_free_interrupts() in pqi_shutdown() + - scsi: megaraid: fix out-of-bound array accesses + - ocfs2: fix panic due to unrecovered local alloc + - mm/page-writeback.c: don't break integrity writeback on ->writepage() error + - mm/swap: use nr_node_ids for avail_lists in swap_info_struct + - mm, proc: be more verbose about unstable VMA flags in /proc//smaps + - cifs: allow disabling insecure dialects in the config + - cifs: In Kconfig CONFIG_CIFS_POSIX needs depends on legacy (insecure cifs) + - PCI: dwc: Move interrupt acking into the proper callback + - ipmi:ssif: Fix handling of multi-part return messages + - net: clear skb->tstamp in bridge forwarding path + - netfilter: ipset: Allow matching on destination MAC address for mac and + ipmac sets + - drm/amdkfd: fix interrupt spin lock + - of: overlay: add missing of_node_put() after add new node to changeset + - drm/atomic-helper: Complete fake_commit->flip_done potentially earlier + - ASoC: pcm3168a: Don't disable pcm3168a when CONFIG_PM defined + - efi/libstub: Disable some warnings for x86{,_64} + - media: uvcvideo: Refactor teardown of uvc on USB disconnect + - arm64: kasan: Increase stack size for KASAN_EXTRA + - bpf: relax verifier restriction on BPF_MOV | BPF_ALU + - perf vendor events intel: Fix Load_Miss_Real_Latency on SKL/SKX + - netfilter: ipt_CLUSTERIP: remove wrong WARN_ON_ONCE in netns exit routine + - netfilter: ipt_CLUSTERIP: fix deadlock in netns exit routine + - x86/topology: Use total_cpus for max logical packages calculation + - perf stat: Avoid segfaults caused by negated options + - perf tools: Add missing sigqueue() prototype for systems lacking it + - perf tools: Add missing open_memstream() prototype for systems lacking it + - dm: Check for device sector overflow if CONFIG_LBDAF is not set + - userfaultfd: clear flag if remap event not enabled + * Bionic update: upstream stable patchset 2019-07-19 (LP: #1837257) + - pinctrl: sunxi: a83t: Fix IRQ offset typo for PH11 + - userfaultfd: check VM_MAYWRITE was set after verifying the uffd is + registered + - arm64: dma-mapping: Fix FORCE_CONTIGUOUS buffer clearing + - MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310 + - mmc: sdhci: fix the timeout check window for clock and reset + - ARM: mmp/mmp2: fix cpu_is_mmp2() on mmp2-dt + - dm thin: send event about thin-pool state change _after_ making it + - dm cache metadata: verify cache has blocks in + blocks_are_clean_separate_dirty() + - tracing: Fix memory leak in set_trigger_filter() + - tracing: Fix memory leak of instance function hash filters + - powerpc/msi: Fix NULL pointer access in teardown code + - drm/nouveau/kms: Fix memory leak in nv50_mstm_del() + - drm/i915/execlists: Apply a full mb before execution for Braswell + - drm/amdgpu: update SMC firmware image for polaris10 variants + - x86/build: Fix compiler support check for CONFIG_RETPOLINE + - locking: Remove smp_read_barrier_depends() from queued_spin_lock_slowpath() + - locking/qspinlock: Ensure node is initialised before updating prev->next + - locking/qspinlock: Bound spinning on pending->locked transition in slowpath + - locking/qspinlock: Merge 'struct __qspinlock' into 'struct qspinlock' + - locking/qspinlock: Remove unbounded cmpxchg() loop from locking slowpath + - locking/qspinlock: Remove duplicate clear_pending() function from PV code + - locking/qspinlock: Kill cmpxchg() loop when claiming lock from head of queue + - locking/qspinlock: Re-order code + - locking/qspinlock/x86: Increase _Q_PENDING_LOOPS upper bound + - locking/qspinlock, x86: Provide liveness guarantee + - mac80211: don't WARN on bad WMM parameters from buggy APs + - mac80211: Fix condition validating WMM IE + - IB/hfi1: Remove race conditions in user_sdma send path + - locking/qspinlock: Fix build for anonymous union in older GCC compilers + - mac80211_hwsim: fix module init error paths for netlink + - Input: hyper-v - fix wakeup from suspend-to-idle + - scsi: libiscsi: Fix NULL pointer dereference in iscsi_eh_session_reset + - scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during + unload + - x86/earlyprintk/efi: Fix infinite loop on some screen widths + - drm/msm: Grab a vblank reference when waiting for commit_done + - ARC: io.h: Implement reads{x}()/writes{x}() + - bonding: fix 802.3ad state sent to partner when unbinding slave + - bpf: Fix verifier log string check for bad alignment. + - nfs: don't dirty kernel pages read by direct-io + - SUNRPC: Fix a potential race in xprt_connect() + - sbus: char: add of_node_put() + - drivers/sbus/char: add of_node_put() + - drivers/tty: add missing of_node_put() + - ide: pmac: add of_node_put() + - drm/msm: Fix error return checking + - clk: mvebu: Off by one bugs in cp110_of_clk_get() + - clk: mmp: Off by one in mmp_clk_add() + - Input: synaptics - enable SMBus for HP 15-ay000 + - Input: omap-keypad - fix keyboard debounce configuration + - libata: whitelist all SAMSUNG MZ7KM* solid-state disks + - mv88e6060: disable hardware level MAC learning + - net/mlx4_en: Fix build break when CONFIG_INET is off + - ARM: 8814/1: mm: improve/fix ARM v7_dma_inv_range() unaligned address + handling + - ARM: 8815/1: V7M: align v7m_dma_inv_range() with v7 counterpart + - ethernet: fman: fix wrong of_node_put() in probe function + - drm/ast: Fix connector leak during driver unload + - vhost/vsock: fix reset orphans race with close timeout + - mlxsw: spectrum_switchdev: Fix VLAN device deletion via ioctl + - i2c: axxia: properly handle master timeout + - i2c: scmi: Fix probe error on devices with an empty SMB0001 ACPI device node + - i2c: uniphier: fix violation of tLOW requirement for Fast-mode + - i2c: uniphier-f: fix violation of tLOW requirement for Fast-mode + - nvmet-rdma: fix response use after free + - rtc: snvs: Add timeouts to avoid kernel lockups + - bpf, arm: fix emit_ldx_r and emit_mov_i using TMP_REG_1 + - scsi: raid_attrs: fix unused variable warning + - staging: olpc_dcon: add a missing dependency + - ARM: dts: qcom-apq8064-arrow-sd-600eval fix graph_endpoint warning + - mmc: core: use mrq->sbc when sending CMD23 for RPMB + - dm: call blk_queue_split() to impose device limits on bios + - media: vb2: don't call __vb2_queue_cancel if vb2_start_streaming failed + - powerpc: Look for "stdout-path" when setting up legacy consoles + - dm zoned: Fix target BIO completion handling + - block: fix infinite loop if the device loses discard capability + - ASoC: sta32x: set ->component pointer in private struct + - perf record: Synthesize features before events in pipe mode + - USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data + - xhci: Don't prevent USB2 bus suspend in state check intended for USB3 only + - USB: xhci: fix 'broken_suspend' placement in struct xchi_hcd + - USB: serial: option: add GosunCn ZTE WeLink ME3630 + - USB: serial: option: add HP lt4132 + - USB: serial: option: add Simcom SIM7500/SIM7600 (MBIM mode) + - USB: serial: option: add Fibocom NL668 series + - USB: serial: option: add Telit LN940 series + - scsi: sd: use mempool for discard special page + - mmc: core: Reset HPI enabled state during re-init and in case of errors + - mmc: core: Allow BKOPS and CACHE ctrl even if no HPI support + - mmc: core: Use a minimum 1600ms timeout when enabling CACHE ctrl + - mmc: omap_hsmmc: fix DMA API warning + - gpio: max7301: fix driver for use with CONFIG_VMAP_STACK + - gpiolib-acpi: Only defer request_irq for GpioInt ACPI event handlers + - posix-timers: Fix division by zero bug + - kvm: x86: Add AMD's EX_CFG to the list of ignored MSRs + - Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels + - x86/mtrr: Don't copy uninitialized gentry fields back to userspace + - panic: avoid deadlocks in re-entrant console drivers + - iwlwifi: mvm: don't send GEO_TX_POWER_LIMIT to old firmwares + - iwlwifi: add new cards for 9560, 9462, 9461 and killer series + - ubifs: Handle re-linking of inodes correctly while recovery + - mm: don't miss the last page because of round-off error + - proc/sysctl: don't return ENOMEM on lookup when a table is unregistering + - i2c: rcar: check bus state before reinitializing + - drm/amd/display: Fix 6x4K displays light-up on Vega20 (v2) + - drm/msm: Fix task dump in gpu recovery + - drm/msm: fix handling of cmdstream offset + - net: aquantia: fix rx checksum offload bits + - liquidio: read sc->iq_no before release sc + - drm/msm/hdmi: Enable HPD after HDMI IRQ is set up + - macvlan: return correct error value + - bpf: check pending signals while verifying programs + - ARM: 8816/1: dma-mapping: fix potential uninitialized return + - tools/testing/nvdimm: Align test resources to 128M + - Btrfs: fix missing delayed iputs on unmount + - ax25: fix a use-after-free in ax25_fillin_cb() + - gro_cell: add napi_disable in gro_cells_destroy + - ibmveth: fix DMA unmap error in ibmveth_xmit_start error path + - ieee802154: lowpan_header_create check must check daddr + - ipv6: explicitly initialize udp6_addr in udp_sock_create6() + - ipv6: tunnels: fix two use-after-free + - isdn: fix kernel-infoleak in capi_unlocked_ioctl + - net: macb: restart tx after tx used bit read + - net: phy: Fix the issue that netif always links up after resuming + - netrom: fix locking in nr_find_socket() + - net/wan: fix a double free in x25_asy_open_tty() + - packet: validate address length + - packet: validate address length if non-zero + - ptr_ring: wrap back ->producer in __ptr_ring_swap_queue() + - qmi_wwan: Added support for Telit LN940 series + - sctp: initialize sin6_flowinfo for ipv6 addrs in sctp_inet6addr_event + - tcp: fix a race in inet_diag_dump_icsk() + - tipc: fix a double kfree_skb() + - vhost: make sure used idx is seen before log in vhost_add_used_n() + - VSOCK: Send reset control packet when socket is partially bound + - xen/netfront: tolerate frags with no data + - net/mlx5: Typo fix in del_sw_hw_rule + - net/mlx5e: RX, Fix wrong early return in receive queue poll + - mlxsw: core: Increase timeout during firmware flash process + - net/mlx5e: Remove the false indication of software timestamping support + - tipc: use lock_sock() in tipc_sk_reinit() + - tipc: compare remote and local protocols in tipc_udp_enable() + - qmi_wwan: Added support for Fibocom NL668 series + - qmi_wwan: Add support for Fibocom NL678 series + - net/smc: fix TCP fallback socket release + - sock: Make sock->sk_stamp thread-safe + - IB/hfi1: Incorrect sizing of sge for PIO will OOPs + - mtd: atmel-quadspi: disallow building on ebsa110 + - ALSA: hda: add mute LED support for HP EliteBook 840 G4 + - ALSA: fireface: fix for state to fetch PCM frames + - ALSA: firewire-lib: fix wrong handling payload_length as payload_quadlet + - ALSA: firewire-lib: fix wrong assignment for 'out_packet_without_header' + tracepoint + - ALSA: firewire-lib: use the same print format for 'without_header' + tracepoints + - ALSA: hda/tegra: clear pending irq handlers + - USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays + - USB: serial: option: add Fibocom NL678 series + - usb: r8a66597: Fix a possible concurrency use-after-free bug in + r8a66597_endpoint_disable() + - staging: wilc1000: fix missing read_write setting when reading data + - qmi_wwan: apply SET_DTR quirk to the SIMCOM shared device ID + - s390/pci: fix sleeping in atomic during hotplug + - x86/speculation/l1tf: Drop the swap storage limit restriction when l1tf=off + - KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup + - KVM: nVMX: Free the VMREAD/VMWRITE bitmaps if alloc_kvm_area() fails + - platform-msi: Free descriptors in platform_msi_domain_free() + - perf pmu: Suppress potential format-truncation warning + - ext4: add ext4_sb_bread() to disambiguate ENOMEM cases + - ext4: fix possible use after free in ext4_quota_enable + - ext4: missing unlock/put_page() in ext4_try_to_write_inline_data() + - ext4: fix EXT4_IOC_GROUP_ADD ioctl + - ext4: include terminating u32 in size of xattr entries when expanding inodes + - ext4: force inode writes when nfsd calls commit_metadata() + - ext4: check for shutdown and r/o file system in ext4_write_inode() + - spi: bcm2835: Fix race on DMA termination + - spi: bcm2835: Fix book-keeping of DMA termination + - spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode + - clk: rockchip: fix typo in rk3188 spdif_frac parent + - crypto: cavium/nitrox - fix a DMA pool free failure + - cgroup: fix CSS_TASK_ITER_PROCS + - cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader. + - Btrfs: fix fsync of files with multiple hard links in new directories + - f2fs: fix validation of the block count in sanity_check_raw_super + - serial: uartps: Fix interrupt mask issue to handle the RX interrupts + properly + - media: vivid: free bitmap_cap when updating std/timings/etc. + - media: v4l2-tpg: array index could become negative + - MIPS: math-emu: Write-protect delay slot emulation pages + - MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 + - MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() + - MIPS: Align kernel load address to 64KB + - MIPS: Expand MIPS32 ASIDs to 64 bits + - MIPS: OCTEON: mark RGMII interface disabled on OCTEON III + - CIFS: Fix error mapping for SMB2_LOCK command which caused OFD lock problem + - arm64: KVM: Avoid setting the upper 32 bits of VTCR_EL2 to 1 + - arm/arm64: KVM: vgic: Force VM halt when changing the active state of GICv3 + PPIs/SGIs + - rtc: m41t80: Correct alarm month range with RTC reads + - tpm: tpm_i2c_nuvoton: use correct command duration for TPM 2.x + - spi: bcm2835: Unbreak the build of esoteric configs + - MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y + - KVM: X86: Fix NULL deref in vcpu_scan_ioapic + - futex: Cure exit race + - x86/mm: Fix decoy address handling vs 32-bit builds + - x86/intel_rdt: Ensure a CPU remains online for the region's pseudo-locking + sequence + - mm: add mm_pxd_folded checks to pgtable_bytes accounting functions + - mm: make the __PAGETABLE_PxD_FOLDED defines non-empty + - mm: introduce mm_[p4d|pud|pmd]_folded + - ip: validate header length on virtual device xmit + - net: clear skb->tstamp in forwarding paths + - net/hamradio/6pack: use mod_timer() to rearm timers + - tipc: check tsk->group in tipc_wait_for_cond() + - tipc: check group dests after tipc_wait_for_cond() + - ipv6: frags: Fix bogus skb->sk in reassembled packets + - ALSA: hda/realtek: Enable audio jacks of ASUS UX391UA with ALC294 + - ALSA: hda/realtek: Enable the headset mic auto detection for ASUS laptops + - ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook + Clapper + - ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook + Gnawty + - Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G + - arm64: KVM: Make VHE Stage-2 TLB invalidation operations non-interruptible + - DRM: UDL: get rid of useless vblank initialization + - clocksource/drivers/arc_timer: Utilize generic sched_clock + - ocxl: Fix endiannes bug in ocxl_link_update_pe() + - ocxl: Fix endiannes bug in read_afu_name() + - ext4: add verifier check for symlink with append/immutable flags + - ext4: avoid declaring fs inconsistent due to invalid file handles + - clk: sunxi-ng: Use u64 for calculation of NM rate + - crypto: testmgr - add AES-CFB tests + - btrfs: dev-replace: go back to suspended state if target device is missing + - btrfs: run delayed items before dropping the snapshot + - powerpc/tm: Unset MSR[TS] if not recheckpointing + - f2fs: read page index before freeing + - f2fs: sanity check of xattr entry size + - media: cec: keep track of outstanding transmits + - media: imx274: fix stack corruption in imx274_read_reg + - media: vb2: check memory model for VIDIOC_CREATE_BUFS + - MIPS: Fix a R10000_LLSC_WAR logic in atomic.h + - KVM: arm/arm64: vgic: Do not cond_resched_lock() with IRQs disabled + - KVM: arm/arm64: vgic: Cap SPIs to the VM-defined maximum + * alsa/hda: neither mute led nor mic-mute led work on several Lenovo laptops + (LP: #1837963) + - SAUCE: ALSA: hda - Add a conexant codec entry to let mute led work + + -- Stefan Bader Thu, 15 Aug 2019 19:46:04 +0200 + +linux-oracle (4.15.0-1021.23) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1021.23 -proposed tracker (LP: #1839280) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 4.15.0-58.64 ] + + * unable to handle kernel NULL pointer dereference at 000000000000002c (IP: + iget5_locked+0x9e/0x1f0) (LP: #1838982) + - Revert "ovl: set I_CREATING on inode being created" + - Revert "new primitive: discard_new_inode()" + + -- Kleber Sacilotto de Souza Wed, 07 Aug 2019 17:41:57 +0200 + +linux-oracle (4.15.0-1020.22) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-57.63 ] + + * CVE-2019-1125 + - x86/cpufeatures: Carve out CQM features retrieval + - x86/cpufeatures: Combine word 11 and 12 into a new scattered features word + - x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations + - x86/speculation: Enable Spectre v1 swapgs mitigations + - x86/entry/64: Use JMP instead of JMPQ + - x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Fri, 02 Aug 2019 14:44:04 +0200 + +linux-oracle (4.15.0-1019.21) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1019.21 -proposed tracker (LP: #1837616) + + * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940) + - [Config] linux-oracle: remove CONFIG_DRM_HISI_HIBMC=m + + * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] linux-oracle: add build deps for building dkms + + [ Ubuntu: 4.15.0-56.62 ] + + * bionic/linux: 4.15.0-56.62 -proposed tracker (LP: #1837626) + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] update helper scripts + * CVE-2019-2101 + - media: uvcvideo: Fix 'type' check leading to overflow + * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940) + - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only + - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64 + * Bionic: support for Solarflare X2542 network adapter (sfc driver) + (LP: #1836635) + - sfc: make mem_bar a function rather than a constant + - sfc: support VI strides other than 8k + - sfc: add Medford2 (SFC9250) PCI Device IDs + - sfc: improve PTP error reporting + - sfc: update EF10 register definitions + - sfc: populate the timer reload field + - sfc: update MCDI protocol headers + - sfc: support variable number of MAC stats + - sfc: expose FEC stats on Medford2 + - sfc: expose CTPIO stats on NICs that support them + - sfc: basic MCDI mapping of 25/50/100G link speeds + - sfc: support the ethtool ksettings API properly so that 25/50/100G works + - sfc: add bits for 25/50/100G supported/advertised speeds + - sfc: remove tx and MCDI handling from NAPI budget consideration + - sfc: handle TX timestamps in the normal data path + - sfc: add function to determine which TX timestamping method to use + - sfc: use main datapath for HW timestamps if available + - sfc: only enable TX timestamping if the adapter is licensed for it + - sfc: MAC TX timestamp handling on the 8000 series + - sfc: on 8000 series use TX queues for TX timestamps + - sfc: only advertise TX timestamping if we have the license for it + - sfc: simplify RX datapath timestamping + - sfc: support separate PTP and general timestamping + - sfc: support second + quarter ns time format for receive datapath + - sfc: support Medford2 frequency adjustment format + - sfc: add suffix to large constant in ptp + - sfc: mark some unexported symbols as static + - sfc: update MCDI protocol headers + - sfc: support FEC configuration through ethtool + - sfc: remove ctpio_dmabuf_start from stats + - sfc: stop the TX queue before pushing new buffers + * [18.04 FEAT] zKVM: Add hardware CPU Model - kernel part (LP: #1836153) + - KVM: s390: add debug logging for cpu model subfunctions + - KVM: s390: implement subfunction processor calls + - KVM: s390: add vector enhancements facility 2 to cpumodel + - KVM: s390: add vector BCD enhancements facility to cpumodel + - KVM: s390: add MSA9 to cpumodel + - KVM: s390: provide query function for instructions returning 32 byte + - KVM: s390: add enhanced sort facilty to cpu model + - KVM: s390: add deflate conversion facilty to cpu model + - KVM: s390: enable MSA9 keywrapping functions depending on cpu model + * Intel ethernet I219 has slow RX speed (LP: #1836152) + - SAUCE: e1000e: add workaround for possible stalled packet + - SAUCE: e1000e: disable force K1-off feature + * Intel ethernet I219 may wrongly detect connection speed as 10Mbps + (LP: #1836177) + - SAUCE: e1000e: Make watchdog use delayed work + * Unhide Nvidia HDA audio controller (LP: #1836308) + - PCI: Enable NVIDIA HDA controllers + * selftests: Remove broken Power9 paste tests and fix compilation issue + (LP: #1836715) + - selftests/powerpc: Remove Power9 paste tests + - selftests/powerpc: Fix Makefiles for headers_install change + * ixgbe{vf} - Physical Function gets IRQ when VF checks link state + (LP: #1836760) + - ixgbevf: Use cached link state instead of re-reading the value for ethtool + * Fix nf_conntrack races when dealing with same origin requests in NAT + environments (LP: #1836816) + - netfilter: nf_conntrack: resolve clash for matching conntracks + - netfilter: nf_nat: skip nat clash resolution for same-origin entries + * CVE-2018-5383 + - crypto: ecdh - add public key verification test + * sched: Prevent CPU lockups when task groups take longer than the period + (LP: #1836971) + - sched/fair: Limit sched_cfs_period_timer() loop to avoid hard lockup + * depmod may prefer unsigned l-r-m nvidia modules to signed modules + (LP: #1834479) + - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files + - [Packaging] Add update-version-dkms + - update dkms package versions + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) // zfs/spl + build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] dkms-build--nvidia-* -- convert to generic -N form + * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] dkms -- dkms package build packaging support + - [Packaging] dkms -- build zfs/spl packages + - [Packaging] dkms -- drop zfs/spl source code from kernel + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] dkms -- introduce dkms package versions + - [Packaging] dkms -- add per package post-process step + - [Packaging] dkms -- switch to a consistent build prefix length and strip + - [Packaging] dkms-build -- support building against packages in PPAs + - [Packaging] dkms-build: do not redownload files on subsequent passes + - [Packaging] dkms-build -- add support for unversioned overrides + - [Packaging] dkms-build -- backport latest version from disco + - [Packaging] nvidia -- build and sign nvidia packages and ship signatures + - [Packaging] nvidia -- make nvidia package version explicit + * CVE-2019-13233 + - x86/insn-eval: Fix use-after-free access to LDT entry + * kernel panic using CIFS share in smb2_push_mandatory_locks() (LP: #1795659) + - CIFS: keep FileInfo handle live during oplock break + * cifs set_oplock buffer overflow in strcat (LP: #1824981) + - cifs: fix strcat buffer overflow and reduce raciness in + smb21_set_oplock_level() + * CVE-2019-13272 + - ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME + * Bionic update: upstream stable patchset 2019-07-18 (LP: #1837161) + - Kbuild: suppress packed-not-aligned warning for default setting only + - disable stringop truncation warnings for now + - test_hexdump: use memcpy instead of strncpy + - kobject: Replace strncpy with memcpy + - ALSA: intel_hdmi: Use strlcpy() instead of strncpy() + - unifdef: use memcpy instead of strncpy + - kernfs: Replace strncpy with memcpy + - ip_tunnel: Fix name string concatenate in __ip_tunnel_create() + - scsi: bfa: convert to strlcpy/strlcat + - kdb: use memmove instead of overlapping memcpy + - iser: set sector for ambiguous mr status errors + - uprobes: Fix handle_swbp() vs. unregister() + register() race once more + - MIPS: ralink: Fix mt7620 nd_sd pinmux + - mips: fix mips_get_syscall_arg o32 check + - IB/mlx5: Avoid load failure due to unknown link width + - drm/ast: Fix incorrect free on ioregs + - drm: set is_master to 0 upon drm_new_set_master() failure + - drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config + - drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut() + - ALSA: trident: Suppress gcc string warning + - kgdboc: Fix restrict error + - kgdboc: Fix warning with module build + - svm: Add mutex_lock to protect apic_access_page_done on AMD systems + - drm/msm: fix OF child-node lookup + - Input: xpad - quirk all PDP Xbox One gamepads + - Input: synaptics - add PNP ID for ThinkPad P50 to SMBus + - Input: matrix_keypad - check for errors from of_get_named_gpio() + - Input: cros_ec_keyb - fix button/switch capability reports + - Input: elan_i2c - add ELAN0620 to the ACPI table + - Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15ARR + - Input: elan_i2c - add support for ELAN0621 touchpad + - btrfs: tree-checker: Don't check max block group size as current max chunk + size limit is unreliable + - ARC: change defconfig defaults to ARCv2 + - arc: [devboards] Add support of NFSv3 ACL + - reset: make device_reset_optional() really optional + - reset: remove remaining WARN_ON() in + - mm: hide incomplete nr_indirectly_reclaimable in /proc/zoneinfo + - net: qed: use correct strncpy() size + - tipc: use destination length for copy string + - arm64: ftrace: Fix to enable syscall events on arm64 + - sched, trace: Fix prev_state output in sched_switch tracepoint + - tracing/fgraph: Fix set_graph_function from showing interrupts + - drm/meson: Fixes for drm_crtc_vblank_on/off support + - scsi: lpfc: fix block guard enablement on SLI3 adapters + - media: omap3isp: Unregister media device as first + - iommu/vt-d: Fix NULL pointer dereference in prq_event_thread() + - brcmutil: really fix decoding channel info for 160 MHz bandwidth + - iommu/ipmmu-vmsa: Fix crash on early domain free + - can: rcar_can: Fix erroneous registration + - test_firmware: fix error return getting clobbered + - HID: input: Ignore battery reported by Symbol DS4308 + - batman-adv: Use explicit tvlv padding for ELP packets + - batman-adv: Expand merged fragment buffer for full packet + - amd/iommu: Fix Guest Virtual APIC Log Tail Address Register + - bnx2x: Assign unique DMAE channel number for FW DMAE transactions. + - qed: Fix PTT leak in qed_drain() + - qed: Fix reading wrong value in loop condition + - net/mlx4_core: Zero out lkey field in SW2HW_MPT fw command + - net/mlx4_core: Fix uninitialized variable compilation warning + - net/mlx4: Fix UBSAN warning of signed integer overflow + - gpio: mockup: fix indicated direction + - mtd: rawnand: qcom: Namespace prefix some commands + - mtd: spi-nor: Fix Cadence QSPI page fault kernel panic + - qed: Fix bitmap_weight() check + - qed: Fix QM getters to always return a valid pq + - net: faraday: ftmac100: remove netif_running(netdev) check before disabling + interrupts + - iommu/vt-d: Use memunmap to free memremap + - flexfiles: use per-mirror specified stateid for IO + - ibmvnic: Fix RX queue buffer cleanup + - team: no need to do team_notify_peers or team_mcast_rejoin when disabling + port + - net: amd: add missing of_node_put() + - usb: quirk: add no-LPM quirk on SanDisk Ultra Flair device + - usb: appledisplay: Add 27" Apple Cinema Display + - USB: check usb_get_extra_descriptor for proper size + - ALSA: hda: Add support for AMD Stoney Ridge + - ALSA: pcm: Fix starvation on down_write_nonblock() + - ALSA: pcm: Call snd_pcm_unlink() conditionally at closing + - ALSA: pcm: Fix interval evaluation with openmin/max + - ALSA: hda/realtek - Fix speaker output regression on Thinkpad T570 + - SUNRPC: Fix leak of krb5p encode pages + - dmaengine: dw: Fix FIFO size for Intel Merrifield + - dmaengine: cppi41: delete channel from pending list when stop channel + - ARM: 8806/1: kprobes: Fix false positive with FORTIFY_SOURCE + - xhci: Prevent U1/U2 link pm states if exit latency is too long + - f2fs: fix to do sanity check with block address in main area v2 + - swiotlb: clean up reporting + - Staging: lustre: remove two build warnings + - staging: atomisp: remove "fun" strncpy warning + - cifs: Fix separator when building path from dentry + - staging: rtl8712: Fix possible buffer overrun + - Revert commit ef9209b642f "staging: rtl8723bs: Fix indenting errors and an + off-by-one mistake in core/rtw_mlme_ext.c" + - drm/amdgpu: update mc firmware image for polaris12 variants + - drm/amdgpu/gmc8: update MC firmware for polaris + - tty: serial: 8250_mtk: always resume the device in probe. + - kgdboc: fix KASAN global-out-of-bounds bug in param_set_kgdboc_var() + - libnvdimm, pfn: Pad pfn namespaces relative to other regions + - mac80211: Clear beacon_int in ieee80211_do_stop + - mac80211: ignore tx status for PS stations in ieee80211_tx_status_ext + - mac80211: fix reordering of buffered broadcast packets + - mac80211: ignore NullFunc frames in the duplicate detection + - qed: Fix rdma_info structure allocation + - drm/amdgpu: Add amdgpu "max bpc" connector property (v2) + - drivers/net/ethernet/qlogic/qed/qed_rdma.h: fix typo + - gpio: pxa: fix legacy non pinctrl aware builds again + - tc-testing: tdc.py: ignore errors when decoding stdout/stderr + - NFSv4: Fix a NFSv4 state manager deadlock + - USB: serial: console: fix reported terminal settings + - ALSA: usb-audio: Add SMSL D1 to quirks for native DSD support + - ALSA: hda/realtek: ALC286 mic and headset-mode fixups for Acer Aspire + U27-880 + - ALSA: hda/realtek - Add support for Acer Aspire C24-860 headset mic + - ALSA: hda/realtek: Fix mic issue on Acer AIO Veriton Z4660G + - ALSA: hda/realtek: Fix mic issue on Acer AIO Veriton Z4860G/Z6860G + - media: dvb-pll: don't re-validate tuner frequencies + - parisc: Enable -ffunction-sections for modules on 32-bit kernel + - Revert "x86/e820: put !E820_TYPE_RAM regions into memblock.reserved" + - drm/lease: Send a distinct uevent + - drm/msm: Move fence put to where failure occurs + - drm/amdgpu/gmc8: always load MC firmware in the driver + - drm/i915: Downgrade Gen9 Plane WM latency error + - x86/efi: Allocate e820 buffer before calling efi_exit_boot_service + - cfg80211: Fix busy loop regression in ieee80211_ie_split_ric() + - ipv4: ipv6: netfilter: Adjust the frag mem limit when truesize changes + - ipv6: Check available headroom in ip6_xmit() even without options + - neighbour: Avoid writing before skb->head in neigh_hh_output() + - ipv6: sr: properly initialize flowi6 prior passing to ip6_route_output + - net: 8139cp: fix a BUG triggered by changing mtu with network traffic + - net/mlx4_core: Correctly set PFC param if global pause is turned off. + - net/mlx4_en: Change min MTU size to ETH_MIN_MTU + - net: phy: don't allow __set_phy_supported to add unsupported modes + - net: Prevent invalid access to skb->prev in __qdisc_drop_all + - rtnetlink: ndo_dflt_fdb_dump() only work for ARPHRD_ETHER devices + - sctp: kfree_rcu asoc + - tcp: Do not underestimate rwnd_limited + - tcp: fix NULL ref in tail loss probe + - tun: forbid iface creation with rtnl ops + - virtio-net: keep vnet header zeroed after processing XDP + - ARM: OMAP2+: prm44xx: Fix section annotation on + omap44xx_prm_enable_io_wakeup + - ASoC: rsnd: fixup clock start checker + - staging: rtl8723bs: Fix the return value in case of error in + 'rtw_wx_read32()' + - ARM: dts: logicpd-somlv: Fix interrupt on mmc3_dat1 + - ARM: OMAP1: ams-delta: Fix possible use of uninitialized field + - sysv: return 'err' instead of 0 in __sysv_write_inode + - selftests: add script to stress-test nft packet path vs. control plane + - netfilter: nf_tables: fix use-after-free when deleting compat expressions + - hwmon (ina2xx) Fix NULL id pointer in probe() + - ASoC: wm_adsp: Fix dma-unsafe read of scratch registers + - s390/cpum_cf: Reject request for sampling in event initialization + - hwmon: (ina2xx) Fix current value calculation + - ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing + - ASoC: dapm: Recalculate audio map forcely when card instantiated + - netfilter: xt_hashlimit: fix a possible memory leak in htable_create() + - hwmon: (w83795) temp4_type has writable permission + - perf tools: Restore proper cwd on return from mnt namespace + - PCI: imx6: Fix link training status detection in link up check + - objtool: Fix double-free in .cold detection error path + - objtool: Fix segfault in .cold detection with -ffunction-sections + - ARM: dts: at91: sama5d2: use the divided clock for SMC + - Btrfs: send, fix infinite loop due to directory rename dependencies + - RDMA/mlx5: Fix fence type for IB_WR_LOCAL_INV WR + - RDMA/rdmavt: Fix rvt_create_ah function signature + - ASoC: omap-mcbsp: Fix latency value calculation for pm_qos + - ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE + - ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE + - exportfs: do not read dentry after free + - bpf: fix check of allowed specifiers in bpf_trace_printk + - ipvs: call ip_vs_dst_notifier earlier than ipv6_dev_notf + - USB: omap_udc: use devm_request_irq() + - USB: omap_udc: fix crashes on probe error and module removal + - USB: omap_udc: fix omap_udc_start() on 15xx machines + - USB: omap_udc: fix USB gadget functionality on Palm Tungsten E + - USB: omap_udc: fix rejection of out transfers when DMA is used + - drm/meson: add support for 1080p25 mode + - netfilter: ipv6: Preserve link scope traffic original oif + - IB/mlx5: Fix page fault handling for MW + - KVM: x86: fix empty-body warnings + - x86/kvm/vmx: fix old-style function declaration + - net: thunderx: fix NULL pointer dereference in nic_remove + - usb: gadget: u_ether: fix unsafe list iteration + - netfilter: nf_tables: deactivate expressions in rule replecement routine + - igb: fix uninitialized variables + - ixgbe: recognize 1000BaseLX SFP modules as 1Gbps + - net: hisilicon: remove unexpected free_netdev + - drm/amdgpu: Add delay after enable RLC ucode + - drm/ast: fixed reading monitor EDID not stable issue + - xen: xlate_mmu: add missing header to fix 'W=1' warning + - Revert "xen/balloon: Mark unallocated host memory as UNUSABLE" + - pstore/ram: Correctly calculate usable PRZ bytes + - fscache, cachefiles: remove redundant variable 'cache' + - nvme: flush namespace scanning work just before removing namespaces + - ACPI/IORT: Fix iort_get_platform_device_domain() uninitialized pointer value + - ocfs2: fix deadlock caused by ocfs2_defrag_extent() + - mm/page_alloc.c: fix calculation of pgdat->nr_zones + - hfs: do not free node before using + - hfsplus: do not free node before using + - debugobjects: avoid recursive calls with kmemleak + - ocfs2: fix potential use after free + - printk: Add console owner and waiter logic to load balance console writes + - printk: Hide console waiter logic into helpers + - printk: Never set console_may_schedule in console_trylock() + - printk: Wake klogd when passing console_lock owner + - flexfiles: enforce per-mirror stateid only for v4 DSes + - staging: speakup: Replace strncpy with memcpy + - ALSA: fireface: fix reference to wrong register for clock configuration + - IB/hfi1: Fix an out-of-bounds access in get_hw_stats + - tcp: lack of available data can also cause TSO defer + - Revert "net/ibm/emac: wrong bit is used for STA control" + - tools: bpftool: prevent infinite loop in get_fdinfo() + - ASoC: sun8i-codec: fix crash on module removal + - ASoC: acpi: fix: continue searching when machine is ignored + - RDMA/bnxt_re: Fix system hang when registration with L2 driver fails + - RDMA/bnxt_re: Avoid accessing the device structure after it is freed + - RDMA/hns: Bugfix pbl configuration for rereg mr + - thunderbolt: Prevent root port runtime suspend during NVM upgrade + - netfilter: add missing error handling code for register functions + - netfilter: nat: fix double register in masquerade modules + - cachefiles: Fix an assertion failure when trying to update a failed object + - fscache: Fix race in fscache_op_complete() due to split atomic_sub & read + - pvcalls-front: fixes incorrect error handling + - nvme: warn when finding multi-port subsystems without multipathing enabled + - kernel/kcov.c: mark funcs in __sanitizer_cov_trace_pc() as notrace + - ALSA: hda/realtek: ALC294 mic and headset-mode fixups for ASUS X542UN + - ALSA: hda/realtek: Enable audio jacks of ASUS UX533FD with ALC294 + - ALSA: hda/realtek: Enable audio jacks of ASUS UX433FN/UX333FA with ALC294 + * Bionic update: upstream stable patchset 2019-07-17 (LP: #1836968) + - flow_dissector: do not dissect l4 ports for fragments + - ibmvnic: fix accelerated VLAN handling + - ip_tunnel: don't force DF when MTU is locked + - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF + - net-gro: reset skb->pkt_type in napi_reuse_skb() + - sctp: not allow to set asoc prsctp_enable by sockopt + - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths + - tuntap: fix multiqueue rx + - net: systemport: Protect stop from timeout + - net: qualcomm: rmnet: Fix incorrect assignment of real_dev + - net: dsa: microchip: initialize mutex before use + - sctp: fix strchange_flags name for Stream Change Event + - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs + - sctp: not increase stream's incnt before sending addstrm_in request + - mlxsw: spectrum: Fix IP2ME CPU policer configuration + - net: smsc95xx: Fix MTU range + - usbnet: smsc95xx: disable carrier check while suspending + - inet: frags: better deal with smp races + - ARM: dts: r8a7791: Correct critical CPU temperature + - ARM: dts: r8a7793: Correct critical CPU temperature + - net: bcmgenet: protect stop from timeout + - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP + coalescing + - tipc: don't assume linear buffer when reading ancillary data + - tipc: fix link re-establish failure + - net/mlx5e: Claim TC hw offloads support only under a proper build config + - net/mlx5e: Adjust to max number of channles when re-attaching + - net/mlx5e: Fix selftest for small MTUs + - l2tp: fix a sock refcnt leak in l2tp_tunnel_register + - net/mlx5e: IPoIB, Reset QP after channels are closed + - net: dsa: mv88e6xxx: Fix clearing of stats counters + - net: phy: realtek: fix RTL8201F sysfs name + - sctp: define SCTP_SS_DEFAULT for Stream schedulers + - rxrpc: Fix lockup due to no error backoff after ack transmit error + - cifs: don't dereference smb_file_target before null check + - cifs: fix return value for cifs_listxattr + - arm64: kprobe: make page to RO mode when allocate it + - ixgbe: fix MAC anti-spoofing filter after VFLR + - reiserfs: propagate errors from fill_with_dentries() properly + - hfs: prevent btree data loss on root split + - hfsplus: prevent btree data loss on root split + - um: Give start_idle_thread() a return code + - drm/edid: Add 6 bpc quirk for BOE panel. + - platform/x86: intel_telemetry: report debugfs failure + - clk: fixed-rate: fix of_node_get-put imbalance + - perf symbols: Set PLT entry/header sizes properly on Sparc + - fs/exofs: fix potential memory leak in mount option parsing + - clk: samsung: exynos5420: Enable PERIS clocks for suspend + - apparmor: Fix uninitialized value in aa_split_fqname + - x86/earlyprintk: Add a force option for pciserial device + - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307 + - arm64: percpu: Initialize ret in the default case + - s390/vdso: add missing FORCE to build targets + - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and + replace + - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net + - s390/mm: Fix ERROR: "__node_distance" undefined! + - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment() + - netfilter: xt_IDLETIMER: add sysfs filename checking routine + - s390/qeth: fix HiperSockets sniffer + - hwmon: (ibmpowernv) Remove bogus __init annotations + - Revert "drm/exynos/decon5433: implement frame counter" + - clk: fixed-factor: fix of_node_get-put imbalance + - lib/raid6: Fix arm64 test build + - s390/perf: Change CPUM_CF return code in event init function + - sched/core: Take the hotplug lock in sched_init_smp() + - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features + - qed: Fix memory/entry leak in qed_init_sp_request() + - qed: Fix blocking/unlimited SPQ entries leak + - qed: Fix potential memory corruption + - net: stmmac: Fix RX packet size > 8191 + - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer() + - ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM + - perf machine: Add machine__is() to identify machine arch + - perf tools: Fix kernel_start for PTI on x86 + - perf machine: Add nr_cpus_avail() + - perf machine: Workaround missing maps for x86 PTI entry trampolines + - perf test code-reading: Fix perf_env setup for PTI entry trampolines + - media: v4l: event: Add subscription to list before calling "add" operation + - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver + - uio: Fix an Oops on load + - usb: cdc-acm: add entry for Hiro (Conexant) modem + - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB + - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data + - USB: misc: appledisplay: add 20" Apple Cinema Display + - ACPI / platform: Add SMB0001 HID to forbidden_id_list + - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges + - libceph: fall back to sendmsg for slab pages + - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE + - perf unwind: Take pgoff into account when reporting elf to libdwfl + - netfilter: bridge: define INT_MIN & INT_MAX in userspace + - s390/decompressor: add missing FORCE to build targets + - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS" + - HID: alps: allow incoming reports when only the trackstick is opened + - s390/mm: fix mis-accounting of pgtable_bytes + - drm/amd/display: Stop leaking planes + - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder() + - ceph: quota: fix null pointer dereference in quota check + - nvme: make sure ns head inherits underlying device limits + - i2c: omap: Enable for ARCH_K3 + - net: aquantia: fix potential IOMMU fault after driver unbind + - net: aquantia: fixed enable unicast on 32 macvlan + - net: aquantia: invalid checksumm offload implementation + - mtd: rawnand: atmel: fix OF child-node lookup + - efi/libstub: arm: support building with clang + - ARM: 8766/1: drop no-thumb-interwork in EABI mode + - ARM: 8767/1: add support for building ARM kernel with clang + - bus: arm-cci: remove unnecessary unreachable() + - ARM: trusted_foundations: do not use naked function + - usb: core: Fix hub port connection events lost + - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers + - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB + - usb: dwc3: core: Clean up ULPI device + - xhci: Add check for invalid byte size error when UAS devices are connected. + - ALSA: oss: Use kvzalloc() for local buffer allocations + - MAINTAINERS: Add Sasha as a stable branch maintainer + - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL + - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path + - iwlwifi: mvm: support sta_statistics() even on older firmware + - iwlwifi: mvm: fix regulatory domain update when the firmware starts + - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used + - brcmfmac: fix reporting support for 160 MHz channels + - tools/power/cpupower: fix compilation with STATIC=true + - v9fs_dir_readdir: fix double-free on p9stat_read error + - selinux: Add __GFP_NOWARN to allocation at str_read() + - Input: synaptics - avoid using uninitialized variable when probing + - bfs: add sanity check at bfs_fill_super() + - sctp: clear the transport of some out_chunk_list chunks in + sctp_assoc_rm_peer + - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd + - llc: do not use sk_eat_skb() + - mm: don't warn about large allocations for slab + - mm/memory.c: recheck page table entry with page table lock held + - IB/core: Perform modify QP on real one + - usb: xhci: Prevent bus suspend if a port connect change or polling state is + detected + - drm/ast: change resolution may cause screen blurred + - drm/ast: fixed cursor may disappear sometimes + - can: dev: can_get_echo_skb(): factor out non sending code to + __can_get_echo_skb() + - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to + access frame length + - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb + is accessed out of bounds + - can: dev: __can_get_echo_skb(): print error message, if trying to echo non + existing skb + - can: rx-offload: introduce can_rx_offload_get_echo_skb() and + can_rx_offload_queue_sorted() functions + - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to + can_rx_offload_queue_tail() + - can: raw: check for CAN FD capable netdev in raw_sendmsg() + - can: hi311x: Use level-triggered interrupt + - IB/hfi1: Eliminate races in the SDMA send error path + - pinctrl: meson: fix pinconf bias disable + - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE + - cpufreq: imx6q: add return value check for voltage scale + - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write + - crypto: simd - correctly take reqsize of wrapped skcipher into account + - floppy: fix race condition in __floppy_read_block_0() + - powerpc/io: Fix the IO workarounds code to work with Radix + - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs + - SUNRPC: Fix a bogus get/put in generic_key_to_expire() + - kdb: Use strscpy with destination buffer size + - powerpc/numa: Suppress "VPHN is not supported" messages + - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset + - mm, page_alloc: check for max order in hot path + - arm64: remove no-op -p linker flag + - ubi: fastmap: Check each mapping only once + - Input: xpad - add PDP device id 0x02a4 + - Input: xpad - fix some coding style issues + - Input: xpad - avoid using __set_bit() for capabilities + - Input: xpad - add support for Xbox1 PDP Camo series gamepad + - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE + - kbuild: allow to use GCC toolchain not in Clang search path + - PCI: endpoint: Populate func_no before calling pci_epc_add_epf() + - i40iw: Fix memory leak in error path of create QP + - clk: samsung: exynos5250: Add missing clocks for FIMC LITE SYSMMU devices + - ARM: dts: exynos: Fix invalid node referenced by i2c20 alias in Peach Pit + and Pi + - include/linux/pfn_t.h: force '~' to be parsed as an unary operator + - tty: wipe buffer. + - tty: wipe buffer if not echoing data + - lan78xx: Read MAC address from DT if present + - s390/mm: Check for valid vma before zapping in gmap_discard + - rcu: Make need_resched() respond to urgent RCU-QS needs + - net: ieee802154: 6lowpan: fix frag reassembly + - EVM: Add support for portable signature format + - ima: re-introduce own integrity cache lock + - ima: re-initialize iint->atomic_flags + - xhci: Fix leaking USB3 shared_hcd at xhci removal + - Documentation/security-bugs: Clarify treatment of embargoed information + - Documentation/security-bugs: Postpone fix publication in exceptional cases + - ACPICA: AML interpreter: add region addresses in global list during + initialization + - fsnotify: generalize handling of extra event flags + - pinctrl: meson: fix gxbb ao pull register bits + - pinctrl: meson: fix gxl ao pull register bits + - pinctrl: meson: fix meson8 ao pull register bits + - pinctrl: meson: fix meson8b ao pull register bits + - riscv: add missing vdso_install target + - media: ov5640: fix wrong binning value in exposure calculation + - media: ov5640: fix auto controls values when switching to manual mode + - mm/huge_memory: rename freeze_page() to unmap_page() + - mm/huge_memory.c: reorder operations in __split_huge_page_tail() + - mm/huge_memory: splitting set mapping+index before unfreeze + - mm/huge_memory: fix lockdep complaint on 32-bit i_size_read() + - mm/khugepaged: collapse_shmem() stop if punched or truncated + - mm/khugepaged: fix crashes due to misaccounted holes + - mm/khugepaged: collapse_shmem() remember to clear holes + - mm/khugepaged: minor reorderings in collapse_shmem() + - mm/khugepaged: collapse_shmem() without freezing new_page + - mm/khugepaged: collapse_shmem() do not crash on Compound + - media: em28xx: Fix use-after-free when disconnecting + - ubi: Initialize Fastmap checkmapping correctly + - libceph: store ceph_auth_handshake pointer in ceph_connection + - libceph: factor out __prepare_write_connect() + - libceph: factor out __ceph_x_decrypt() + - libceph: factor out encrypt_authorizer() + - libceph: add authorizer challenge + - libceph: implement CEPHX_V2 calculation mode + - net/tls: Fixed return value when tls_complete_pending_work() fails + - wil6210: missing length check in wmi_set_ie + - btrfs: validate type when reading a chunk + - btrfs: Verify that every chunk has corresponding block group at mount time + - btrfs: tree-checker: Add checker for dir item + - btrfs: tree-checker: use %zu format string for size_t + - btrfs: tree-check: reduce stack consumption in check_dir_item + - btrfs: tree-checker: Verify block_group_item + - btrfs: tree-checker: Detect invalid and empty essential trees + - btrfs: Check that each block group has corresponding chunk at mount time + - btrfs: tree-checker: Check level for leaves and nodes + - btrfs: tree-checker: Fix misleading group system information + - f2fs: check blkaddr more accuratly before issue a bio + - f2fs: enhance sanity_check_raw_super() to avoid potential overflow + - f2fs: clean up with is_valid_blkaddr() + - f2fs: introduce and spread verify_blkaddr + - f2fs: fix to do sanity check with secs_per_zone + - f2fs: fix to do sanity check with user_block_count + - f2fs: fix to do sanity check with node footer and iblocks + - f2fs: fix to do sanity check with block address in main area + - f2fs: fix to do sanity check with i_extra_isize + - f2fs: fix to do sanity check with cp_pack_start_sum + - net: skb_scrub_packet(): Scrub offload_fwd_mark + - net: thunderx: set xdp_prog to NULL if bpf_prog_add fails + - virtio-net: disable guest csum during XDP set + - virtio-net: fail XDP set if guest csum is negotiated + - net: thunderx: set tso_hdrs pointer to NULL in nicvf_free_snd_queue + - packet: copy user buffers before orphan or clone + - rapidio/rionet: do not free skb before reading its length + - usbnet: ipheth: fix potential recvmsg bug and recvmsg bug 2 + - kvm: mmu: Fix race in emulated page table writes + - KVM: x86: Fix kernel info-leak in KVM_HC_CLOCK_PAIRING hypercall + - xtensa: enable coprocessors that are being flushed + - xtensa: fix coprocessor context offset definitions + - xtensa: fix coprocessor part of ptrace_{get,set}xregs + - Btrfs: ensure path name is null terminated at btrfs_control_ioctl + - btrfs: relocation: set trans to be NULL after ending transaction + - PCI: layerscape: Fix wrong invocation of outbound window disable accessor + - arm64: dts: rockchip: Fix PCIe reset polarity for rk3399-puma-haikou. + - x86/fpu: Disable bottom halves while loading FPU registers + - perf/x86/intel: Move branch tracing setup to the Intel-specific source file + - perf/x86/intel: Add generic branch tracing check to intel_pmu_has_bts() + - fs: fix lost error code in dio_complete + - ALSA: wss: Fix invalid snd_free_pages() at error path + - ALSA: ac97: Fix incorrect bit shift at AC97-SPSA control write + - ALSA: control: Fix race between adding and removing a user element + - ALSA: sparc: Fix invalid snd_free_pages() at error path + - ALSA: hda/realtek - Support ALC300 + - ALSA: hda/realtek - fix headset mic detection for MSI MS-B171 + - ext2: fix potential use after free + - ARM: dts: rockchip: Remove @0 from the veyron memory node + - dmaengine: at_hdmac: fix memory leak in at_dma_xlate() + - dmaengine: at_hdmac: fix module unloading + - staging: vchiq_arm: fix compat VCHIQ_IOC_AWAIT_COMPLETION + - staging: rtl8723bs: Add missing return for cfg80211_rtw_get_station + - usb: core: quirks: add RESET_RESUME quirk for Cherry G230 Stream series + - Revert "usb: dwc3: gadget: skip Set/Clear Halt when invalid" + - iio:st_magn: Fix enable device after trigger + - lib/test_kmod.c: fix rmmod double free + - mm: use swp_offset as key in shmem_replace_page() + - misc: mic/scif: fix copy-paste error in scif_create_remote_lookup + - binder: fix race that allows malicious free of live buffer + - libceph: weaken sizeof check in ceph_x_verify_authorizer_reply() + - libceph: check authorizer reply/challenge length before reading + - f2fs: fix missing up_read + - net: don't keep lonely packets forever in the gro hash + - net: phy: add workaround for issue where PHY driver doesn't bind to the + device + - KVM: nVMX/nSVM: Fix bug which sets vcpu->arch.tsc_offset to L1 tsc_offset + - udf: Allow mounting volumes with incorrect identification strings + - btrfs: Always try all copies when reading extent buffers + - Btrfs: fix rare chances for data loss when doing a fast fsync + - Btrfs: fix race between enabling quotas and subvolume creation + - perf/x86/intel: Disallow precise_ip on BTS events + - ALSA: hda: Add ASRock H81M-HDS to the power_save blacklist + - ALSA: hda: Add ASRock N68C-S UCC the power_save blacklist + - function_graph: Create function_graph_enter() to consolidate architecture + code + - ARM: function_graph: Simplify with function_graph_enter() + - microblaze: function_graph: Simplify with function_graph_enter() + - x86/function_graph: Simplify with function_graph_enter() + - powerpc/function_graph: Simplify with function_graph_enter() + - sh/function_graph: Simplify with function_graph_enter() + - sparc/function_graph: Simplify with function_graph_enter() + - parisc: function_graph: Simplify with function_graph_enter() + - s390/function_graph: Simplify with function_graph_enter() + - arm64: function_graph: Simplify with function_graph_enter() + - MIPS: function_graph: Simplify with function_graph_enter() + - function_graph: Make ftrace_push_return_trace() static + - function_graph: Use new curr_ret_depth to manage depth instead of + curr_ret_stack + - function_graph: Have profiler use curr_ret_stack and not depth + - function_graph: Move return callback before update of curr_ret_stack + - function_graph: Reverse the order of pushing the ret_stack and the callback + - ext2: initialize opts.s_mount_opt as zero before using it + - ASoC: intel: cht_bsw_max98090_ti: Add quirk for boards using pmc_plt_clk_0 + - staging: most: use format specifier "%s" in snprintf + - iio/hid-sensors: Fix IIO_CHAN_INFO_RAW returning wrong values for signed + numbers + - mm: cleancache: fix corruption on missed inode invalidation + * Bionic update: upstream stable patchset 2019-07-17 (LP: #1836968) // + CVE-2000-1134 // CVE-2007-3852 // CVE-2008-0525 // CVE-2009-0416 // + CVE-2011-4834 // CVE-2015-1838 // CVE-2015-7442 // CVE-2016-7489 + - namei: allow restricted O_CREAT of FIFOs and regular files + * bcache: risk of data loss on I/O errors in backing or caching devices + (LP: #1829563) + - bcache: add CACHE_SET_IO_DISABLE to struct cache_set flags + - bcache: add stop_when_cache_set_failed option to backing device + - bcache: fix inaccurate io state for detached bcache devices + - bcache: add backing_request_endio() for bi_end_io + - bcache: add io_disable to struct cached_dev + - bcache: store disk name in struct cache and struct cached_dev + - bcache: count backing device I/O error for writeback I/O + - bcache: add wait_for_kthread_stop() in bch_allocator_thread() + - bcache: set dc->io_disable to true in conditional_stop_bcache_device() + - bcache: stop bcache device when backing device is offline + - bcache: fix ioctl in flash device + * Bionic update: upstream stable patchset 2019-07-16 (LP: #1836802) + - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB + - spi: bcm-qspi: switch back to reading flash using smaller chunks + - bcache: trace missed reading by cache_missed + - bcache: fix miss key refill->end in writeback + - hwmon: (pmbus) Fix page count auto-detection. + - jffs2: free jffs2_sb_info through jffs2_kill_sb() + - cpufreq: conservative: Take limits changes into account properly + - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges + - parisc: Fix address in HPMC IVA + - parisc: Fix map_pages() to not overwrite existing pte entries + - parisc: Fix exported address of os_hpmc handler + - ALSA: hda - Add quirk for ASUS G751 laptop + - ALSA: hda - Fix headphone pin config for ASUS G751 + - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905) + - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops + - x86/xen: Fix boot loader version reported for PVH guests + - x86/corruption-check: Fix panic in memory_corruption_check() when boot + option without value is provided + - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen + - bpf: do not blindly change rlimit in reuseport net selftest + - Revert "perf tools: Fix PMU term format max value calculation" + - xfrm: policy: use hlist rcu variants on insert + - perf vendor events intel: Fix wrong filter_band* values for uncore events + - sched/fair: Fix the min_vruntime update logic in dequeue_entity() + - perf tools: Fix use of alternatives to find JDIR + - perf cpu_map: Align cpu map synthesized events properly. + - x86/fpu: Remove second definition of fpu in __fpu__restore_sig() + - net: qla3xxx: Remove overflowing shift statement + - selftests: ftrace: Add synthetic event syntax testcase + - i2c: rcar: cleanup DMA for all kinds of failure + - locking/lockdep: Fix debug_locks off performance problem + - ataflop: fix error handling during setup + - swim: fix cleanup on setup error + - nfp: devlink port split support for 1x100G CXP NIC + - tun: Consistently configure generic netdev params via rtnetlink + - s390/sthyi: Fix machine name validity indication + - hwmon: (pwm-fan) Set fan speed to 0 on suspend + - lightnvm: pblk: fix two sleep-in-atomic-context bugs + - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare} + - perf tools: Free temporary 'sys' string in read_event_files() + - perf tools: Cleanup trace-event-info 'tdata' leak + - perf strbuf: Match va_{add,copy} with va_end + - cpupower: Fix coredump on VMWare + - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01 + - iwlwifi: pcie: avoid empty free RB queue + - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface + - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC + - ACPI / processor: Fix the return value of acpi_processor_ids_walk() + - cpufreq: dt: Try freeing static OPPs only if we have added them + - mtd: rawnand: atmel: Fix potential NULL pointer dereference + - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack + - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth + - x86: boot: Fix EFI stub alignment + - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux + - brcmfmac: fix for proper support of 160MHz bandwidth + - net: phy: phylink: ensure the carrier is off when starting phylink + - block, bfq: correctly charge and reset entity service in all cases + - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON() + - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers + - pinctrl: qcom: spmi-mpp: Fix drive strength setting + - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant + - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant + - net: dsa: mv88e6xxx: Fix writing to a PHY page. + - iwlwifi: mvm: fix BAR seq ctrl reporting + - ixgbevf: VF2VF TCP RSS + - ath10k: schedule hardware restart if WMI command times out + - thermal: da9062/61: Prevent hardware access during system suspend + - cgroup, netclassid: add a preemption point to write_classid + - scsi: esp_scsi: Track residual for PIO transfers + - UAPI: ndctl: Fix g++-unsupported initialisation in headers + - KVM: nVMX: Clear reserved bits of #DB exit qualification + - scsi: megaraid_sas: fix a missing-check bug + - RDMA/core: Do not expose unsupported counters + - IB/ipoib: Clear IPCB before icmp_send + - RDMA/bnxt_re: Fix recursive lock warning in debug kernel + - usb: host: ohci-at91: fix request of irq for optional gpio + - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic + - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated + - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask + - VMCI: Resource wildcard match fixed + - PCI / ACPI: Enable wake automatically for power managed bridges + - usb: gadget: udc: atmel: handle at91sam9rl PMC + - ext4: fix argument checking in EXT4_IOC_MOVE_EXT + - MD: fix invalid stored role for a disk + - f2fs: fix to recover inode's i_flags during POR + - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice + - coresight: etb10: Fix handling of perf mode + - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode + - crypto: caam - fix implicit casts in endianness helpers + - usb: chipidea: Prevent unbalanced IRQ disable + - driver/dma/ioat: Call del_timer_sync() without holding prep_lock + - uio: ensure class is registered before devices + - scsi: lpfc: Correct soft lockup when running mds diagnostics + - scsi: lpfc: Correct race with abort on completion path + - f2fs: report error if quota off error during umount + - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace + init + - mfd: menelaus: Fix possible race condition and leak + - dmaengine: dma-jz4780: Return error if not probed from DT + - IB/rxe: fix for duplicate request processing and ack psns + - ALSA: hda: Check the non-cached stream buffers more explicitly + - cpupower: Fix AMD Family 0x17 msr_pstate size + - f2fs: fix to account IO correctly + - ARM: dts: exynos: Remove "cooling-{min|max}-level" for CPU nodes + - arm: dts: exynos: Add missing cooling device properties for CPUs + - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings + - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250 + - xen-swiotlb: use actually allocated size on check physical continuous + - tpm: Restore functionality to xen vtpm driver. + - xen/blkfront: avoid NULL blkfront_info dereference on device removal + - xen/balloon: Support xend-based toolstack + - xen: fix race in xen_qlock_wait() + - xen: make xen_qlock_wait() nestable + - xen/pvh: increase early stack size + - xen/pvh: don't try to unplug emulated devices + - libertas: don't set URB_ZERO_PACKET on IN USB transfer + - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten + - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround" + - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate() + - net/ipv4: defensive cipso option parsing + - dmaengine: ppc4xx: fix off-by-one build failure + - dmaengine: stm32-dma: fix incomplete configuration in cyclic mode + - libnvdimm: Hold reference on parent while scheduling async init + - libnvdimm, region: Fail badblocks listing for inactive regions + - ASoC: intel: skylake: Add missing break in skl_tplg_get_token() + - IB/mlx5: Fix MR cache initialization + - jbd2: fix use after free in jbd2_log_do_checkpoint() + - gfs2_meta: ->mount() can get NULL dev_name + - ext4: initialize retries variable in ext4_da_write_inline_data_begin() + - ext4: fix setattr project check in fssetxattr ioctl + - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR + - ext4: fix use-after-free race in ext4_remount()'s error path + - EDAC, amd64: Add Family 17h, models 10h-2fh support + - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting + - EDAC, skx_edac: Fix logical channel intermediate decoding + - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP + - PCI/ASPM: Fix link_state teardown on device removal + - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk + - PCI: vmd: White list for fast interrupt handlers + - signal/GenWQE: Fix sending of SIGKILL + - signal: Guard against negative signal numbers in copy_siginfo_from_user32 + - crypto: lrw - Fix out-of bounds access on counter overflow + - crypto: tcrypt - fix ghash-generic speed test + - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range() + - ima: fix showing large 'violations' or 'runtime_measurements_count' + - hugetlbfs: dirty pages as they are added to pagecache + - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly + - KVM: arm64: Fix caching of host MDCR_EL2 value + - kbuild: fix kernel/bounds.c 'W=1' warning + - iio: ad5064: Fix regulator handling + - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs() + - iio: adc: at91: fix acking DRDY irq on simple conversions + - iio: adc: at91: fix wrong channel number in triggered buffer mode + - w1: omap-hdq: fix missing bus unregister at removal + - smb3: allow stats which track session and share reconnects to be reset + - smb3: do not attempt cifs operation in smb3 query info error path + - smb3: on kerberos mount if server doesn't specify auth type use krb5 + - printk: Fix panic caused by passing log_buf_len to command line + - genirq: Fix race on spurious interrupt detection + - NFSv4.1: Fix the r/wsize checking + - nfs: Fix a missed page unlock after pg_doio() + - nfsd: Fix an Oops in free_session() + - lockd: fix access beyond unterminated strings in prints + - dm ioctl: harden copy_params()'s copy_from_user() from malicious users + - dm zoned: fix metadata block ref counting + - dm zoned: fix various dmz_get_mblock() issues + - powerpc/msi: Fix compile error on mpc83xx + - MIPS: OCTEON: fix out of bounds array access on CN68XX + - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI + - TC: Set DMA masks for devices + - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD + - kgdboc: Passing ekgdboc to command line causes panic + - xen: fix xen_qlock_wait() + - xen-blkfront: fix kernel panic with negotiate_mq error path + - media: em28xx: use a default format if TRY_FMT fails + - media: tvp5150: avoid going past array on v4l2_querymenu() + - media: em28xx: fix input name for Terratec AV 350 + - media: em28xx: make v4l2-compliance happier by starting sequence on zero + - media: media colorspaces*.rst: rename AdobeRGB to opRGB + - arm64: lse: remove -fcall-used-x0 flag + - rpmsg: smd: fix memory leak on channel create + - Cramfs: fix abad comparison when wrap-arounds occur + - ARM: dts: socfpga: Fix SDRAM node address for Arria10 + - arm64: dts: stratix10: Correct System Manager register size + - soc/tegra: pmc: Fix child-node lookup + - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled + - btrfs: Handle owner mismatch gracefully when walking up tree + - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock + - btrfs: fix error handling in free_log_tree + - btrfs: Enhance btrfs_trim_fs function to handle error better + - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem + - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list + - btrfs: don't attempt to trim devices that don't support it + - btrfs: wait on caching when putting the bg cache + - btrfs: protect space cache inode alloc with GFP_NOFS + - btrfs: reset max_extent_size on clear in a bitmap + - btrfs: make sure we create all new block groups + - Btrfs: fix warning when replaying log after fsync of a tmpfile + - Btrfs: fix wrong dentries after fsync of file that got its parent replaced + - btrfs: qgroup: Dirty all qgroups before rescan + - Btrfs: fix null pointer dereference on compressed write path error + - Btrfs: fix assertion on fsync of regular file when using no-holes feature + - btrfs: set max_extent_size properly + - btrfs: don't use ctl->free_space for max_extent_size + - btrfs: only free reserved extent if we didn't insert it + - btrfs: don't run delayed_iputs in commit + - btrfs: move the dio_sem higher up the callchain + - Btrfs: fix use-after-free during inode eviction + - Btrfs: fix use-after-free when dumping free space + - Btrfs: fix fsync after hole punching when using no-holes feature + - net: sched: Remove TCA_OPTIONS from policy + - bpf: wait for running BPF programs when updating map-in-map + - MD: fix invalid stored role for a disk - try2 + - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash + - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus + - bcache: correct dirty data statistics + - block: don't deal with discard limit in blkdev_issue_discard() + - block: make sure discard bio is aligned with logical block size + - block: make sure writesame bio is aligned with logical block size + - dma-mapping: fix panic caused by passing empty cma command line argument + - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer() + - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended + opcodes + - kprobes/x86: Use preempt_enable() in optimized_callback() + - mailbox: PCC: handle parse error + - ALSA: hda: Add 2 more models to the power_save blacklist + - drm: fix use of freed memory in drm_mode_setcrtc + - nvme: remove ns sibling before clearing path + - nfp: flower: fix pedit set actions for multiple partial masks + - nfp: flower: use offsets provided by pedit instead of index for ipv6 + - perf report: Don't crash on invalid inline debug information + - drm: Get ref on CRTC commit object when waiting for flip_done + - net: socionext: Reset tx queue in ndo_stop + - lightnvm: pblk: fix race on sysfs line state + - lightnvm: pblk: fix race condition on metadata I/O + - bcache: Populate writeback_rate_minimum attribute + - sdhci: acpi: add free_slot callback + - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset + - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI + - ACPI/PPTT: Handle architecturally unknown cache types + - ACPI / PM: LPIT: Register sysfs attributes based on FADT + - pinctrl: sunxi: fix 'pctrl->functions' allocation in + sunxi_pinctrl_build_state + - arm64: entry: Allow handling of undefined instructions from EL1 + - bpf/verifier: fix verifier instability + - gpio: brcmstb: allow 0 width GPIO banks + - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9 + - thermal: rcar_thermal: Prevent doing work after unbind + - net: stmmac: dwmac-sun8i: fix OF child-node lookup + - f2fs: clear PageError on the read path + - xprtrdma: Reset credit grant properly after a disconnect + - nvmem: check the return value of nvmem_add_cells() + - f2fs: avoid sleeping under spin_lock + - f2fs: fix to recover cold bit of inode block during POR + - OPP: Free OPP table properly on performance state irregularities + - IB/rxe: Revise the ib_wr_opcode enum + - ext4: fix EXT4_IOC_SWAP_BOOT + - selinux: fix mounting of cgroup2 under older policies + - KVM: arm/arm64: Ensure only THP is candidate for adjustment + - NFC: nfcmrvl_uart: fix OF child-node lookup + - media: ov7670: make "xclk" clock optional + - powerpc/tm: Fix HFSCR bit for no suspend case + - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9 + - MIPS: memset: Fix CPU_DADDI_WORKAROUNDS `small_fixup' regression + - power: supply: twl4030-charger: fix OF sibling-node lookup + - ocxl: Fix access to the AFU Descriptor Data + - net: bcmgenet: fix OF child-node lookup + - media: cec: make cec_get_edid_spa_location() an inline function + - media: cec: integrate cec_validate_phys_addr() in cec-api.c + - media: adv7604: when the EDID is cleared, unconfigure CEC as well + - media: adv7842: when the EDID is cleared, unconfigure CEC as well + - drm/mediatek: fix OF sibling-node lookup + - media: replace ADOBERGB by OPRGB + - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC + - btrfs: fix error handling in btrfs_dev_replace_start + - btrfs: keep trim from interfering with transaction commits + - Btrfs: don't clean dirty pages during buffered writes + - btrfs: release metadata before running delayed refs + - Btrfs: fix deadlock when writing out free space caches + - btrfs: reset max_extent_size properly + - btrfs: fix insert_reserved error handling + - powerpc/traps: restore recoverability of machine_check interrupts + - powerpc/64/module: REL32 relocation range check + - powerpc/mm: Fix page table dump to work on Radix + - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log() + - tty: check name length in tty_find_polling_driver() + - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL + - powerpc/nohash: fix undefined behaviour when testing page size support + - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak + - drm/omap: fix memory barrier bug in DMM driver + - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer + - media: pci: cx23885: handle adding to list failure + - media: coda: don't overwrite h.264 profile_idc on decoder instance + - MIPS: kexec: Mark CPU offline before disabling local IRQ + - powerpc/boot: Ensure _zimage_start is a weak symbol + - powerpc/memtrace: Remove memory in chunks + - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS + - sc16is7xx: Fix for multi-channel stall + - media: tvp5150: fix width alignment during set_selection() + - powerpc/selftests: Wait all threads to join + - staging:iio:ad7606: fix voltage scales + - 9p locks: fix glock.client_id leak in do_lock + - 9p: clear dangling pointers in p9stat_free + - ovl: fix error handling in ovl_verify_set_fh() + - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters + - scsi: qla2xxx: Fix process response queue for ISP26XX and above + - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx + - scsi: qla2xxx: shutdown chip if reset fail + - scsi: qla2xxx: Fix re-using LoopID when handle is in use + - ovl: fix recursive oi->lock in ovl_link() + - MIPS: Loongson-3: Fix CPU UART irq delivery problem + - MIPS: Loongson-3: Fix BRIDGE irq delivery problem + - xtensa: add NOTES section to the linker script + - xtensa: make sure bFLT stack is 16 byte aligned + - xtensa: fix boot parameters address translation + - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP + - clk: s2mps11: Fix matching when built as module and DT node contains + compatible + - clk: at91: Fix division by zero in PLL recalc_rate() + - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call + - clk: mvebu: use correct bit for 98DX3236 NAND + - libceph: bump CEPH_MSG_MAX_DATA_LEN + - mach64: fix display corruption on big endian machines + - mach64: fix image corruption due to reading accelerator registers + - reset: hisilicon: fix potential NULL pointer dereference + - vhost/scsi: truncate T10 PI iov_iter to prot_bytes + - scsi: qla2xxx: Initialize port speed to avoid setting lower speed + - SCSI: fix queue cleanup race before queue initialization is done + - soc: ti: QMSS: Fix usage of irq_set_affinity_hint + - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry + - ocfs2: free up write context when direct IO failed + - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings + - netfilter: conntrack: fix calculation of next bucket number in early_drop + - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm + - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option + - of, numa: Validate some distance map rules + - x86/cpu/vmware: Do not trace vmware_sched_clock() + - x86/hyper-v: Enable PIT shutdown quirk + - termios, tty/tty_baudrate.c: fix buffer overrun + - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2 + - watchdog/core: Add missing prototypes for weak functions + - btrfs: fix pinned underflow after transaction aborted + - Btrfs: fix cur_offset in the error case for nocow + - Btrfs: fix infinite loop on inode eviction after deduplication of eof block + - Btrfs: fix data corruption due to cloning of eof block + - clockevents/drivers/i8253: Add support for PIT shutdown quirk + - ext4: add missing brelse() update_backups()'s error path + - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path + - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path + - ext4: avoid potential extra brelse in setup_new_flex_group_blocks() + - ext4: missing !bh check in ext4_xattr_inode_write() + - ext4: fix possible inode leak in the retry loop of ext4_resize_fs() + - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty() + - ext4: avoid buffer leak in ext4_orphan_add() after prior errors + - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing + - ext4: avoid possible double brelse() in add_new_gdb() on error path + - ext4: fix possible leak of sbi->s_group_desc_leak in error path + - ext4: fix possible leak of s_journal_flag_rwsem in error path + - ext4: fix buffer leak in ext4_xattr_get_block() on error path + - ext4: release bs.bh before re-using in ext4_xattr_block_find() + - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path + - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path + - ext4: fix buffer leak in __ext4_read_dirblock() on error path + - mount: Prevent MNT_DETACH from disconnecting locked mounts + - kdb: use correct pointer when 'btc' calls 'btt' + - kdb: print real address of pointers instead of hashed addresses + - sunrpc: correct the computation for page_ptr when truncating + - rtc: hctosys: Add missing range error reporting + - configfs: replace strncpy with memcpy + - gfs2: Put bitmap buffers in put_super + - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn + - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444! + - mm/swapfile.c: use kvzalloc for swap_info_struct allocation + - efi/arm/libstub: Pack FDT after populating it + - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type + - drm/nouveau: Check backlight IDs are >= 0, not > 0 + - drm/dp_mst: Check if primary mstb is null + - drm/i915: Restore vblank interrupts earlier + - drm/i915: Don't unset intel_connector->mst_port + - drm/i915: Skip vcpi allocation for MSTB ports that are gone + - drm/i915: Large page offsets for pread/pwrite + - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values + - drm/i915: Don't oops during modeset shutdown after lpe audio deinit + - drm/i915: Mark pin flags as u64 + - drm/i915/execlists: Force write serialisation into context image vs + execution + - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM + - ovl: check whiteout in ovl_create_over_whiteout() + - nvme-loop: fix kernel oops in case of unhandled command + - Input: wm97xx-ts - fix exit path + - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS + - tracing/kprobes: Check the probe on unloaded module correctly + - drm/amdgpu/powerplay: fix missing break in switch statements + - udf: Prevent write-unsupported filesystem to be remounted read-write + - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout + - zram: close udev startup race condition as default groups + - clk: rockchip: fix wrong mmc sample phase shift for rk3328 + - bonding/802.3ad: fix link_failure_count tracking + - hwmon: (core) Fix double-free in __hwmon_device_register() + - perf stat: Handle different PMU names with common prefix + - mnt: fix __detach_mounts infinite loop + - NFSv4: Don't exit the state manager without clearing + NFS4CLNT_MANAGER_RUNNING + - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD + - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit + panel's native mode + - drm/i915: Fix ilk+ watermarks when disabling pipes + - drm/i915: Fix possible race in intel_dp_add_mst_connector() + * [SRU][B/B-OEM]Fix resume failure on some TPM chips (LP: #1836031) + - tpm: tpm_try_transmit() refactor error flow. + * Linux md raid-10 freezes during resync (LP: #1767992) + - md: fix raid10 hang issue caused by barrier + * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755) + - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine + * CVE-2019-12614 + - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property() + * x86: mm: early boot problem on i386 with KPTI enabled (LP: #1827884) + - Revert "perf/core: Make sure the ring-buffer is mapped in all page-tables" + - x86/mm: Clarify hardware vs. software "error_code" + - x86/mm: Break out kernel address space handling + - x86/mm: Break out user address space handling + - x86/mm/fault: Allow stack access below %rsp + * bnx2x driver causes 100% CPU load (LP: #1832082) + - bnx2x: Prevent ptp_task to be rescheduled indefinitely + * Sometimes touchpad detected as mouse(i2c designware fails to get adapter + number) (LP: #1835150) + - i2c: i2c-designware-platdrv: Cleanup setting of the adapter number + - i2c: i2c-designware-platdrv: Always use a dynamic adapter number + * HP EliteBook 745 G5 (Ryzen 2500U) fails to boot unless `mce=off` is set on + command line (LP: #1796443) + - x86/MCE/AMD: Turn off MC4_MISC thresholding on all family 0x15 models + - x86/MCE/AMD: Carve out the MC4_MISC thresholding quirk + - x86/MCE: Add an MCE-record filtering function + - x86/MCE/AMD: Don't report L1 BTB MCA errors on some family 17h models + * Bionic update: upstream stable patchset 2019-07-15 (LP: #1836654) + - media: af9035: prevent buffer overflow on write + - batman-adv: Avoid probe ELP information leak + - batman-adv: Fix segfault when writing to throughput_override + - batman-adv: Fix segfault when writing to sysfs elp_interval + - batman-adv: Prevent duplicated gateway_node entry + - batman-adv: Prevent duplicated nc_node entry + - batman-adv: Prevent duplicated softif_vlan entry + - batman-adv: Prevent duplicated global TT entry + - batman-adv: Prevent duplicated tvlv handler + - batman-adv: fix backbone_gw refcount on queue_work() failure + - batman-adv: fix hardif_neigh refcount on queue_work() failure + - clocksource/drivers/ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non- + am43 SoCs + - scsi: ibmvscsis: Fix a stringop-overflow warning + - scsi: ibmvscsis: Ensure partition name is properly NUL terminated + - intel_th: pci: Add Ice Lake PCH support + - Input: atakbd - fix Atari keymap + - Input: atakbd - fix Atari CapsLock behaviour + - net: emac: fix fixed-link setup for the RTL8363SB switch + - ravb: do not write 1 to reserved bits + - PCI: dwc: Fix scheduling while atomic issues + - drm: mali-dp: Call drm_crtc_vblank_reset on device init + - scsi: ipr: System hung while dlpar adding primary ipr adapter back + - scsi: sd: don't crash the host on invalid commands + - net/mlx4: Use cpumask_available for eq->affinity_mask + - clocksource/drivers/fttmr010: Fix set_next_event handler + - powerpc/tm: Fix userspace r13 corruption + - powerpc/tm: Avoid possible userspace r1 corruption on reclaim + - iommu/amd: Return devid as alias for ACPI HID devices + - ARC: build: Get rid of toolchain check + - ARC: build: Don't set CROSS_COMPILE in arch's Makefile + - HID: quirks: fix support for Apple Magic Keyboards + - staging: ccree: check DMA pool buf !NULL before free + - net/smc: fix sizeof to int comparison + - qed: Fix populating the invalid stag value in multi function mode. + - RDMA/uverbs: Fix validity check for modify QP + - bpf: test_maps, only support ESTABLISHED socks + - RDMA/bnxt_re: Fix system crash during RDMA resource initialization + - RISC-V: include linux/ftrace.h in asm-prototypes.h + - powerpc/numa: Use associativity if VPHN hcall is successful + - x86/boot: Fix kexec booting failure in the SEV bit detection code + - xfrm: Validate address prefix lengths in the xfrm selector. + - xfrm6: call kfree_skb when skb is toobig + - xfrm: reset transport header back to network header after all input + transforms ahave been applied + - xfrm: reset crypto_done when iterating over multiple input xfrms + - mac80211: Always report TX status + - cfg80211: reg: Init wiphy_idx in regulatory_hint_core() + - mac80211: fix pending queue hang due to TX_DROP + - cfg80211: Address some corner cases in scan result channel updating + - mac80211: TDLS: fix skb queue/priority assignment + - mac80211: fix TX status reporting for ieee80211s + - ARM: 8799/1: mm: fix pci_ioremap_io() offset check + - xfrm: validate template mode + - netfilter: bridge: Don't sabotage nf_hook calls from an l3mdev + - arm64: hugetlb: Fix handling of young ptes + - ARM: dts: BCM63xx: Fix incorrect interrupt specifiers + - net: macb: Clean 64b dma addresses if they are not detected + - soc: fsl: qbman: qman: avoid allocating from non existing gen_pool + - soc: fsl: qe: Fix copy/paste bug in ucc_get_tdm_sync_shift() + - mac80211_hwsim: do not omit multicast announce of first added radio + - Bluetooth: SMP: fix crash in unpairing + - pxa168fb: prepare the clock + - qed: Avoid implicit enum conversion in qed_set_tunn_cls_info + - qed: Fix mask parameter in qed_vf_prep_tunn_req_tlv + - qed: Avoid implicit enum conversion in qed_roce_mode_to_flavor + - qed: Avoid constant logical operation warning in qed_vf_pf_acquire + - qed: Avoid implicit enum conversion in qed_iwarp_parse_rx_pkt + - asix: Check for supported Wake-on-LAN modes + - ax88179_178a: Check for supported Wake-on-LAN modes + - lan78xx: Check for supported Wake-on-LAN modes + - sr9800: Check for supported Wake-on-LAN modes + - r8152: Check for supported Wake-on-LAN Modes + - smsc75xx: Check for Wake-on-LAN modes + - smsc95xx: Check for Wake-on-LAN modes + - cfg80211: fix use-after-free in reg_process_hint() + - perf/core: Fix perf_pmu_unregister() locking + - perf/ring_buffer: Prevent concurent ring buffer access + - perf/x86/intel/uncore: Fix PCI BDF address of M3UPI on SKX + - perf/x86/amd/uncore: Set ThreadMask and SliceMask for L3 Cache perf events + - net: fec: fix rare tx timeout + - declance: Fix continuation with the adapter identification message + - locking/ww_mutex: Fix runtime warning in the WW mutex selftest + - be2net: don't flip hw_features when VXLANs are added/deleted + - net: cxgb3_main: fix a missing-check bug + - yam: fix a missing-check bug + - ocfs2: fix crash in ocfs2_duplicate_clusters_by_page() + - iwlwifi: mvm: check for short GI only for OFDM + - iwlwifi: dbg: allow wrt collection before ALIVE + - iwlwifi: fix the ALIVE notification layout + - usbip: vhci_hcd: update 'status' file header and format + - net/mlx5: Fix mlx5_get_vector_affinity function + - powerpc/pseries: Add empty update_numa_cpu_lookup_table() for NUMA=n + - dm integrity: fail early if required HMAC key is not available + - net: phy: realtek: Use the dummy stubs for MMD register access for rtl8211b + - net: phy: Add general dummy stubs for MMD register access + - scsi: qla2xxx: Avoid double completion of abort command + - kbuild: set no-integrated-as before incl. arch Makefile + - IB/mlx5: Avoid passing an invalid QP type to firmware + - l2tp: remove configurable payload offset + - cifs: Use ULL suffix for 64-bit constant + - KVM: x86: Update the exit_qualification access bits while walking an address + - sparc64: Fix regression in pmdp_invalidate(). + - tpm: move the delay_msec increment after sleep in tpm_transmit() + - bpf: sockmap, map_release does not hold refcnt for pinned maps + - tpm: tpm_crb: relinquish locality on error path. + - IB/usnic: Update with bug fixes from core code + - mmc: dw_mmc-rockchip: correct property names in debug + - MIPS: Workaround GCC __builtin_unreachable reordering bug + - iio: buffer: fix the function signature to match implementation + - selftests/powerpc: Add ptrace hw breakpoint test + - scsi: ibmvfc: Avoid unnecessary port relogin + - scsi: sd: Remember that READ CAPACITY(16) succeeded + - btrfs: quota: Set rescan progress to (u64)-1 if we hit last leaf + - net: phy: phylink: Don't release NULL GPIO + - x86/paravirt: Fix some warning messages + - net: stmmac: mark PM functions as __maybe_unused + - kconfig: fix the rule of mainmenu_stmt symbol + - libertas: call into generic suspend code before turning off power + - compiler.h: Allow arch-specific asm/compiler.h + - ARM: dts: imx53-qsb: disable 1.2GHz OPP + - perf python: Use -Wno-redundant-decls to build with PYTHON=python3 + - rxrpc: Don't check RXRPC_CALL_TX_LAST after calling rxrpc_rotate_tx_window() + - rxrpc: Only take the rwind and mtu values from latest ACK + - rxrpc: Fix connection-level abort handling + - selftests: rtnetlink.sh explicitly requires bash. + - fs/fat/fatent.c: add cond_resched() to fat_count_free_clusters() + - mtd: spi-nor: Add support for is25wp series chips + - ARM: dts: r8a7790: Correct critical CPU temperature + - media: uvcvideo: Fix driver reference counting + - Revert "netfilter: ipv6: nf_defrag: drop skb dst before queueing" + - perf tools: Disable parallelism for 'make clean' + - drm/i915/gvt: fix memory leak of a cmd_entry struct on error exit path + - bridge: do not add port to router list when receives query with source + 0.0.0.0 + - net: bridge: remove ipv6 zero address check in mcast queries + - ipv6: mcast: fix a use-after-free in inet6_mc_check + - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are + called + - llc: set SOCK_RCU_FREE in llc_sap_add_socket() + - net: fec: don't dump RX FIFO register when not available + - net/ipv6: Fix index counter for unicast addresses in in6_dump_addrs + - net: sched: gred: pass the right attribute to gred_change_table_def() + - net: socket: fix a missing-check bug + - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules + - net: udp: fix handling of CHECKSUM_COMPLETE packets + - r8169: fix NAPI handling under high load + - sctp: fix race on sctp_id2asoc + - udp6: fix encap return code for resubmitting + - virtio_net: avoid using netif_tx_disable() for serializing tx routine + - ethtool: fix a privilege escalation bug + - bonding: fix length of actor system + - ip6_tunnel: Fix encapsulation layout + - openvswitch: Fix push/pop ethernet validation + - net/mlx5: Take only bit 24-26 of wqe.pftype_wq for page fault type + - net: sched: Fix for duplicate class dump + - net: drop skb on failure in ip_check_defrag() + - net: fix pskb_trim_rcsum_slow() with odd trim offset + - net/mlx5e: fix csum adjustments caused by RXFCS + - rtnetlink: Disallow FDB configuration for non-Ethernet device + - net: ipmr: fix unresolved entry dumps + - net: bcmgenet: Poll internal PHY for GENETv5 + - net/sched: cls_api: add missing validation of netlink attributes + - net/mlx5: Fix build break when CONFIG_SMP=n + - mac80211_hwsim: fix locking when iterating radios during ns exit + - rxrpc: Fix checks as to whether we should set up a new call + - rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket + - thunderbolt: Do not handle ICM events after domain is stopped + - thunderbolt: Initialize after IOMMUs + - RISCV: Fix end PFN for low memory + - drm/amd/display: Signal hw_done() after waiting for flip_done() + - powerpc/numa: Skip onlining a offline node in kdump path + - mm/gup_benchmark: fix unsigned comparison to zero in __gup_benchmark_ioctl + - perf report: Don't try to map ip to invalid map + - perf record: Use unmapped IP for inline callchain cursors + - rxrpc: Carry call state out of locked section in rxrpc_rotate_tx_window() + - gpio: Assign gpio_irq_chip::parents to non-stack pointer + - IB/mlx5: Unmap DMA addr from HCA before IOMMU + - rds: RDS (tcp) hangs on sendto() to unresponding address + - sparc64: Export __node_distance. + - sparc64: Make corrupted user stacks more debuggable. + - sparc64: Make proc_id signed. + - sparc64: Set %l4 properly on trap return after handling signals. + - sparc: Fix single-pcr perf event counter management. + - sparc: Fix syscall fallback bugs in VDSO. + - sparc: Throttle perf events properly. + - eeprom: at24: Add support for address-width property + - vfs: swap names of {do,vfs}_clone_file_range() + - bpf: fix partial copy of map_ptr when dst is scalar + - gpio: mxs: Get rid of external API call + - xfs: truncate transaction does not modify the inobt + - cachefiles: fix the race between cachefiles_bury_object() and rmdir(2) + - drm/edid: VSDB yCBCr420 Deep Color mode bit definitions + - drm: fb-helper: Reject all pixel format changing requests + - cdc-acm: do not reset notification buffer index upon urb unlinking + - cdc-acm: correct counting of UART states in serial state notification + - cdc-acm: fix race between reset and control messaging + - usb: usbip: Fix BUG: KASAN: slab-out-of-bounds in vhci_hub_control() + - USB: fix the usbfs flag sanitization for control transfers + - Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15IGM + - sched/fair: Fix throttle_list starvation with low CFS quota + - x86/tsc: Force inlining of cyc2ns bits + - x86, hibernate: Fix nosave_regions setup for hibernation + - x86/percpu: Fix this_cpu_read() + - x86/time: Correct the attribute on jiffies' definition + - x86/fpu: Fix i486 + no387 boot crash by only saving FPU registers on context + switch if there is an FPU + - clk: sunxi-ng: sun4i: Set VCO and PLL bias current to lowest setting + - drm/sun4i: Fix an ulong overflow in the dotclock driver + - x86/swiotlb: Enable swiotlb for > 4GiG RAM on 32-bit kernels + * Colour banding in HP Pavilion 15-n233sl integrated display (LP: #1794387) // + Bionic update: upstream stable patchset 2019-07-15 (LP: #1836654) + - drm/edid: Add 6 bpc quirk for BOE panel in HP Pavilion 15-n233sl + * Bionic update: upstream stable patchset 2019-07-12 (LP: #1836426) + - drm/amd/pp: initialize result to before or'ing in data + - drm/amdgpu: add another ATPX quirk for TOPAZ + - tools/power turbostat: fix possible sprintf buffer overflow + - mac80211: Run TXQ teardown code before de-registering interfaces + - mac80211_hwsim: require at least one channel + - btrfs: btrfs_shrink_device should call commit transaction at the end + - scsi: csiostor: add a check for NULL pointer after kmalloc() + - mac80211: correct use of IEEE80211_VHT_CAP_RXSTBC_X + - mac80211_hwsim: correct use of IEEE80211_VHT_CAP_RXSTBC_X + - gpio: adp5588: Fix sleep-in-atomic-context bug + - mac80211: mesh: fix HWMP sequence numbering to follow standard + - mac80211: avoid kernel panic when building AMSDU from non-linear SKB + - gpiolib: acpi: Switch to cansleep version of GPIO library call + - gpiolib-acpi: Register GpioInt ACPI event handlers from a late_initcall + - cfg80211: nl80211_update_ft_ies() to validate NL80211_ATTR_IE + - mac80211: do not convert to A-MSDU if frag/subframe limited + - mac80211: always account for A-MSDU header changes + - tools/kvm_stat: fix handling of invalid paths in debugfs provider + - gpio: Fix crash due to registration race + - ARC: atomics: unbork atomic_fetch_##op() + - md/raid5-cache: disable reshape completely + - RAID10 BUG_ON in raise_barrier when force is true and conf->barrier is 0 + - i2c: uniphier: issue STOP only for last message or I2C_M_STOP + - i2c: uniphier-f: issue STOP only for last message or I2C_M_STOP + - net: cadence: Fix a sleep-in-atomic-context bug in macb_halt_tx() + - fs/cifs: don't translate SFM_SLASH (U+F026) to backslash + - mac80211: fix an off-by-one issue in A-MSDU max_subframe computation + - cfg80211: fix a type issue in ieee80211_chandef_to_operating_class() + - mac80211: fix a race between restart and CSA flows + - mac80211: Fix station bandwidth setting after channel switch + - mac80211: don't Tx a deauth frame if the AP forbade Tx + - mac80211: shorten the IBSS debug messages + - tools/vm/slabinfo.c: fix sign-compare warning + - tools/vm/page-types.c: fix "defined but not used" warning + - mm: madvise(MADV_DODUMP): allow hugetlbfs pages + - netfilter: xt_cluster: add dependency on conntrack module + - HID: add support for Apple Magic Keyboards + - usb: gadget: fotg210-udc: Fix memory leak of fotg210->ep[i] + - HID: hid-saitek: Add device ID for RAT 7 Contagion + - scsi: qedi: Add the CRC size within iSCSI NVM image + - perf evsel: Fix potential null pointer dereference in perf_evsel__new_idx() + - perf util: Fix bad memory access in trace info. + - perf probe powerpc: Ignore SyS symbols irrespective of endianness + - netfilter: nf_tables: release chain in flushing set + - Revert "iio: temperature: maxim_thermocouple: add MAX31856 part" + - RDMA/ucma: check fd type in ucma_migrate_id() + - HID: sensor-hub: Restore fixup for Lenovo ThinkPad Helix 2 sensor hub report + - USB: yurex: Check for truncation in yurex_read() + - nvmet-rdma: fix possible bogus dereference under heavy load + - net/mlx5: Consider PCI domain in search for next dev + - drm/nouveau/TBDdevinit: don't fail when PMU/PRE_OS is missing from VBIOS + - drm/nouveau/disp: fix DP disable race + - dm raid: fix rebuild of specific devices by updating superblock + - fs/cifs: suppress a string overflow warning + - perf/x86/intel: Add support/quirk for the MISPREDICT bit on Knights Landing + CPUs + - dm thin metadata: try to avoid ever aborting transactions + - arch/hexagon: fix kernel/dma.c build warning + - hexagon: modify ffs() and fls() to return int + - arm64: jump_label.h: use asm_volatile_goto macro instead of "asm goto" + - drm/amdgpu: fix error handling in amdgpu_cs_user_fence_chunk + - r8169: Clear RTL_FLAG_TASK_*_PENDING when clearing RTL_FLAG_TASK_ENABLED + - s390/qeth: don't dump past end of unknown HW header + - cifs: read overflow in is_valid_oplock_break() + - xen/manage: don't complain about an empty value in control/sysrq node + - xen: avoid crash in disable_hotplug_cpu + - xen: fix GCC warning and remove duplicate EVTCHN_ROW/EVTCHN_COL usage + - ovl: fix access beyond unterminated strings + - ovl: fix memory leak on unlink of indexed file + - ovl: fix format of setxattr debug + - sysfs: Do not return POSIX ACL xattrs via listxattr + - smb2: fix missing files in root share directory listing + - iommu/amd: Clear memory encryption mask from physical address + - crypto: qat - Fix KASAN stack-out-of-bounds bug in adf_probe() + - crypto: mxs-dcp - Fix wait logic on chan threads + - crypto: caam/jr - fix ablkcipher_edesc pointer arithmetic + - gpiolib: Free the last requested descriptor + - Drivers: hv: vmbus: Use get/put_cpu() in vmbus_connect() + - tools: hv: fcopy: set 'error' in case an unknown operation was requested + - ocfs2: fix locking for res->tracking and dlm->tracking_list + - ixgbe: check return value of napi_complete_done() + - dm thin metadata: fix __udivdi3 undefined on 32-bit + - Btrfs: fix unexpected failure of nocow buffered writes after snapshotting + when low on space + - scsi: aacraid: fix a signedness bug + - tipc: switch to rhashtable iterator + - net: mvpp2: initialize port of_node pointer + - tc-testing: add test-cases for numeric and invalid control action + - tools/kvm_stat: fix updates for dead guests + - ibmvnic: Include missing return code checks in reset function + - net/ibm/emac: wrong emac_calc_base call was used by typo + - ceph: avoid a use-after-free in ceph_destroy_options() + - afs: Fix cell specification to permit an empty address list + - netfilter: xt_checksum: ignore gso skbs + - HID: intel-ish-hid: Enable Sunrise Point-H ish driver + - iio: imu: st_lsm6dsx: take into account ts samples in wm configuration + - riscv: Do not overwrite initrd_start and initrd_end + - drm/nouveau: fix oops in client init failure path + - drm/nouveau/mmu: don't attempt to dereference vmm without valid instance + pointer + - drm/nouveau/disp/gm200-: enforce identity-mapped SOR assignment for LVDS/eDP + panels + - sched/topology: Set correct NUMA topology type + - drm/amdgpu: Fix SDMA hang in prt mode v2 + - asm-generic: io: Fix ioport_map() for !CONFIG_GENERIC_IOMAP && + CONFIG_INDIRECT_PIO + - x86/APM: Fix build warning when PROC_FS is not enabled + - new primitive: discard_new_inode() + - ovl: set I_CREATING on inode being created + - crypto: chelsio - Fix memory corruption in DMA Mapped buffers. + - perf/core: Add sanity check to deal with pinned event failure + - mm: migration: fix migration of huge PMD shared pages + - mm, thp: fix mlocking THP page with migration enabled + - mm/vmstat.c: skip NR_TLB_REMOTE_FLUSH* properly + - KVM: x86: fix L1TF's MMIO GFN calculation + - blk-mq: I/O and timer unplugs are inverted in blktrace + - clocksource/drivers/timer-atmel-pit: Properly handle error cases + - fbdev/omapfb: fix omapfb_memory_read infoleak + - drm/amdgpu: Fix vce work queue was not cancelled when suspend + - x86/vdso: Fix asm constraints on vDSO syscall fallbacks + - selftests/x86: Add clock_gettime() tests to test_vdso + - x86/vdso: Only enable vDSO retpolines when enabled and supported + - x86/vdso: Fix vDSO syscall fallback asm constraint regression + - mac80211: fix setting IEEE80211_KEY_FLAG_RX_MGMT for AP mode keys + - PM / core: Clear the direct_complete flag on errors + - dm cache metadata: ignore hints array being too small during resize + - dm cache: fix resize crash if user doesn't reload cache table + - xhci: Add missing CAS workaround for Intel Sunrise Point xHCI + - usb: xhci-mtk: resume USB3 roothub first + - USB: serial: simple: add Motorola Tetra MTP6550 id + - usb: cdc_acm: Do not leak URB buffers + - of: unittest: Disable interrupt node tests for old world MAC systems + - perf annotate: Use asprintf when formatting objdump command line + - perf tools: Fix python extension build for gcc 8 + - ath10k: fix use-after-free in ath10k_wmi_cmd_send_nowait + - ath10k: fix kernel panic issue during pci probe + - nvme_fc: fix ctrl create failures racing with workq items + - powerpc/lib: fix book3s/32 boot failure due to code patching + - ARC: clone syscall to setp r25 as thread pointer + - perf utils: Move is_directory() to path.h + - f2fs: fix invalid memory access + - ucma: fix a use-after-free in ucma_resolve_ip() + - ubifs: Check for name being NULL while mounting + - rds: rds_ib_recv_alloc_cache() should call alloc_percpu_gfp() instead + - ath10k: fix scan crash due to incorrect length calculation + - pstore/ram: Fix failure-path memory leak in ramoops_init + - mac80211: allocate TXQs for active monitor interfaces + - drm: fix use-after-free read in drm_mode_create_lease_ioctl() + - USB: serial: option: improve Quectel EP06 detection + - USB: serial: option: add two-endpoints device-id flag + - tipc: call start and done ops directly in __tipc_nl_compat_dumpit() + - bnxt_en: Fix TX timeout during netpoll. + - bnxt_en: free hwrm resources, if driver probe fails. + - bonding: avoid possible dead-lock + - ip6_tunnel: be careful when accessing the inner header + - ip_tunnel: be careful when accessing the inner header + - ipv4: fix use-after-free in ip_cmsg_recv_dstaddr() + - ipv6: take rcu lock in rawv6_send_hdrinc() + - net: dsa: bcm_sf2: Call setup during switch resume + - net: hns: fix for unmapping problem when SMMU is on + - net: ipv4: update fnhe_pmtu when first hop's MTU changes + - net/ipv6: Display all addresses in output of /proc/net/if_inet6 + - netlabel: check for IPV4MASK in addrinfo_get + - net: mvpp2: Extract the correct ethtype from the skb for tx csum offload + - net: mvpp2: fix a txq_done race condition + - net: sched: Add policy validation for tc attributes + - net: systemport: Fix wake-up interrupt race during resume + - net/usb: cancel pending work when unbinding smsc75xx + - qmi_wwan: Added support for Gemalto's Cinterion ALASxx WWAN interface + - rtnl: limit IFLA_NUM_TX_QUEUES and IFLA_NUM_RX_QUEUES to 4096 + - sctp: update dst pmtu with the correct daddr + - team: Forbid enslaving team device to itself + - tipc: fix flow control accounting for implicit connect + - udp: Unbreak modules that rely on external __skb_recv_udp() availability + - net: stmmac: Fixup the tail addr setting in xmit path + - net/packet: fix packet drop as of virtio gso + - net: dsa: bcm_sf2: Fix unbind ordering + - net/mlx5e: Set vlan masks for all offloaded TC rules + - net: aquantia: memory corruption on jumbo frames + - net/mlx5: E-Switch, Fix out of bound access when setting vport rate + - bonding: pass link-local packets to bonding master also. + - bonding: fix warning message + - nfp: avoid soft lockups under control message storm + - bnxt_en: don't try to offload VLAN 'modify' action + - net-ethtool: ETHTOOL_GUFO did not and should not require CAP_NET_ADMIN + - tcp/dccp: fix lockdep issue when SYN is backlogged + - inet: make sure to grab rcu_read_lock before using ireq->ireq_opt + - ASoC: rt5514: Fix the issue of the delay volume applied again + - ASoC: wm8804: Add ACPI support + - ASoC: sigmadsp: safeload should not have lower byte limit + - selftests/efivarfs: add required kernel configs + - selftests: memory-hotplug: add required configs + - ASoC: rsnd: adg: care clock-frequency size + - ASoC: rsnd: don't fallback to PIO mode when -EPROBE_DEFER + - Bluetooth: hci_ldisc: Free rw_semaphore on close + - mfd: omap-usb-host: Fix dts probe of children + - scsi: iscsi: target: Don't use stack buffer for scatterlist + - scsi: qla2xxx: Fix an endian bug in fcpcmd_is_corrupted() + - sound: enable interrupt after dma buffer initialization + - sound: don't call skl_init_chip() to reset intel skl soc + - stmmac: fix valid numbers of unicast filter entries + - net: macb: disable scatter-gather for macb on sama5d3 + - ARM: dts: at91: add new compatibility string for macb on sama5d3 + - PCI: hv: support reporting serial number as slot information + - clk: x86: add "ether_clk" alias for Bay Trail / Cherry Trail + - clk: x86: Stop marking clocks as CLK_IS_CRITICAL + - x86/kvm/lapic: always disable MMIO interface in x2APIC mode + - drm/amdgpu: Fix SDMA HQD destroy error on gfx_v7 + - mm/vmstat.c: fix outdated vmstat_text + - MIPS: VDSO: Always map near top of user memory + - mach64: detect the dot clock divider correctly on sparc + - percpu: stop leaking bitmap metadata blocks + - perf script python: Fix export-to-postgresql.py occasional failure + - perf script python: Fix export-to-sqlite.py sample columns + - s390/cio: Fix how vfio-ccw checks pinned pages + - dm cache: destroy migration_cache if cache target registration failed + - dm: fix report zone remapping to account for partition offset + - dm linear: eliminate linear_end_io call if CONFIG_DM_ZONED disabled + - dm linear: fix linear_end_io conditional definition + - cgroup: Fix dom_cgrp propagation when enabling threaded mode + - mmc: block: avoid multiblock reads for the last sector in SPI mode + - pinctrl: mcp23s08: fix irq and irqchip setup order + - arm64: perf: Reject stand-alone CHAIN events for PMUv3 + - mm/thp: fix call to mmu_notifier in set_pmd_migration_entry() v2 + - mm: Preserve _PAGE_DEVMAP across mprotect() calls + - i2c: i2c-scmi: fix for i2c_smbus_write_block_data + - xhci: Don't print a warning when setting link state for disabled ports + - mm: introduce NR_INDIRECTLY_RECLAIMABLE_BYTES + - mm: treat indirectly reclaimable memory as available in MemAvailable + - dcache: account external names as indirectly reclaimable memory + - mm: treat indirectly reclaimable memory as free in overcommit logic + - mm: don't show nr_indirectly_reclaimable in /proc/vmstat + - ARM: add more CPU part numbers for Cortex and Brahma B15 CPUs + - ARM: bugs: prepare processor bug infrastructure + - ARM: bugs: hook processor bug checking into SMP and suspend paths + - ARM: bugs: add support for per-processor bug checking + - [Config] updateconfigs for CPU_SPECTRE + - ARM: spectre: add Kconfig symbol for CPUs vulnerable to Spectre + - ARM: spectre-v2: harden branch predictor on context switches + - ARM: spectre-v2: add Cortex A8 and A15 validation of the IBE bit + - ARM: spectre-v2: harden user aborts in kernel space + - ARM: spectre-v2: add firmware based hardening + - ARM: spectre-v2: warn about incorrect context switching functions + - ARM: KVM: invalidate BTB on guest exit for Cortex-A12/A17 + - ARM: KVM: invalidate icache on guest exit for Cortex-A15 + - ARM: spectre-v2: KVM: invalidate icache on guest exit for Brahma B15 + - ARM: KVM: Add SMCCC_ARCH_WORKAROUND_1 fast handling + - ARM: KVM: report support for SMCCC_ARCH_WORKAROUND_1 + - ARM: spectre-v1: add speculation barrier (csdb) macros + - ARM: spectre-v1: add array_index_mask_nospec() implementation + - ARM: spectre-v1: fix syscall entry + - ARM: signal: copy registers using __copy_from_user() + - ARM: vfp: use __copy_from_user() when restoring VFP state + - ARM: oabi-compat: copy semops using __copy_from_user() + - ARM: use __inttype() in get_user() + - ARM: spectre-v1: use get_user() for __get_user() + - ARM: spectre-v1: mitigate user accesses + - perf tools: Fix snprint warnings for gcc 8 + - net: sched: cls_u32: fix hnode refcounting + - net: qualcomm: rmnet: Skip processing loopback packets + - net: qualcomm: rmnet: Fix incorrect allocation flag in transmit + - tun: remove unused parameters + - tun: initialize napi_mutex unconditionally + - tun: napi flags belong to tfile + - net: dsa: b53: Keep CPU port as tagged in all VLANs + - rtnetlink: Fail dump if target netnsid is invalid + - net: ipv4: don't let PMTU updates increase route MTU + - ASoC: dapm: Fix NULL pointer deference on CODEC to CODEC DAIs + - selftests: android: move config up a level + - selftests: add headers_install to lib.mk + - Bluetooth: SMP: Fix trying to use non-existent local OOB data + - Bluetooth: Use correct tfm to generate OOB data + - net: ethernet: ti: add missing GENERIC_ALLOCATOR dependency + - afs: Fix afs_server struct leak + - afs: Fix clearance of reply + * Volume control not working Dell XPS 27 (7760) (LP: #1775068) // Bionic + update: upstream stable patchset 2019-07-12 (LP: #1836426) + - ALSA: hda/realtek - Cannot adjust speaker's volume on Dell XPS 27 7760 + * Bionic update: upstream stable patchset 2019-07-11 (LP: #1836287) + - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so + - gso_segment: Reset skb->mac_len after modifying network header + - ipv6: fix possible use-after-free in ip6_xmit() + - net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT + - net: hp100: fix always-true check for link up state + - pppoe: fix reception of frames with no mac header + - qmi_wwan: set DTR for modems in forced USB2 mode + - udp4: fix IP_CMSG_CHECKSUM for connected sockets + - neighbour: confirm neigh entries when ARP packet is received + - udp6: add missing checks on edumux packet processing + - net/sched: act_sample: fix NULL dereference in the data path + - tls: don't copy the key out of tls12_crypto_info_aes_gcm_128 + - tls: zero the crypto information from tls_context before freeing + - tls: clear key material from kernel memory when do_tls_setsockopt_conf fails + - NFC: Fix possible memory corruption when handling SHDLC I-Frame commands + - NFC: Fix the number of pipes + - ASoC: cs4265: fix MMTLR Data switch control + - ASoC: rsnd: fixup not to call clk_get/set under non-atomic + - ALSA: bebob: fix memory leak for M-Audio FW1814 and ProjectMix I/O at error + path + - ALSA: bebob: use address returned by kmalloc() instead of kernel stack for + streaming DMA mapping + - ALSA: emu10k1: fix possible info leak to userspace on + SNDRV_EMU10K1_IOCTL_INFO + - ALSA: fireface: fix memory leak in ff400_switch_fetching_mode() + - ALSA: firewire-digi00x: fix memory leak of private data + - ALSA: firewire-tascam: fix memory leak of private data + - ALSA: fireworks: fix memory leak of response buffer at error path + - ALSA: oxfw: fix memory leak for model-dependent data at error path + - ALSA: oxfw: fix memory leak of discovered stream formats at error path + - ALSA: oxfw: fix memory leak of private data + - platform/x86: alienware-wmi: Correct a memory leak + - xen/netfront: don't bug in case of too many frags + - xen/x86/vpmu: Zero struct pt_regs before calling into sample handling code + - spi: fix IDR collision on systems with both fixed and dynamic SPI bus + numbers + - ring-buffer: Allow for rescheduling when removing pages + - mm: shmem.c: Correctly annotate new inodes for lockdep + - scsi: target: iscsi: Use bin2hex instead of a re-implementation + - ocfs2: fix ocfs2 read block panic + - drm/nouveau: Fix deadlocks in nouveau_connector_detect() + - drm/nouveau/drm/nouveau: Don't forget to cancel hpd_work on suspend/unload + - drm/nouveau/drm/nouveau: Fix bogus drm_kms_helper_poll_enable() placement + - drm/nouveau/drm/nouveau: Use pm_runtime_get_noresume() in connector_detect() + - drm/nouveau/drm/nouveau: Prevent handling ACPI HPD events too early + - drm/vc4: Fix the "no scaling" case on multi-planar YUV formats + - drm: udl: Destroy framebuffer only if it was initialized + - drm/amdgpu: add new polaris pci id + - ext4: check to make sure the rename(2)'s destination is not freed + - ext4: avoid divide by zero fault when deleting corrupted inline directories + - ext4: avoid arithemetic overflow that can trigger a BUG + - ext4: recalucate superblock checksum after updating free blocks/inodes + - ext4: fix online resize's handling of a too-small final block group + - ext4: fix online resizing for bigalloc file systems with a 1k block size + - ext4: don't mark mmp buffer head dirty + - ext4: show test_dummy_encryption mount option in /proc/mounts + - sched/fair: Fix vruntime_normalized() for remote non-migration wakeup + - PCI: aardvark: Size bridges before resources allocation + - vmw_balloon: include asm/io.h + - iw_cxgb4: only allow 1 flush on user qps + - tick/nohz: Prevent bogus softirq pending warning + - spi: Fix double IDR allocation with DT aliases + - hv_netvsc: fix schedule in RCU context + - bnxt_en: Fix VF mac address regression. + - net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags + - mtd: rawnand: denali: fix a race condition when DMA is kicked + - platform/x86: dell-smbios-wmi: Correct a memory leak + - fork: report pid exhaustion correctly + - mm: disable deferred struct page for 32-bit arches + - libata: mask swap internal and hardware tag + - drm/i915/bdw: Increase IPS disable timeout to 100ms + - drm/nouveau: Reset MST branching unit before enabling + - drm/nouveau: Only write DP_MSTM_CTRL when needed + - drm/nouveau: Remove duplicate poll_enable() in pmops_runtime_suspend() + - ext4, dax: set ext4_dax_aops for dax files + - crypto: skcipher - Fix -Wstringop-truncation warnings + - iio: adc: ina2xx: avoid kthread_stop() with stale task_struct + - tsl2550: fix lux1_input error in low light + - vmci: type promotion bug in qp_host_get_user_memory() + - x86/numa_emulation: Fix emulated-to-physical node mapping + - staging: rts5208: fix missing error check on call to rtsx_write_register + - power: supply: axp288_charger: Fix initial constant_charge_current value + - misc: sram: enable clock before registering regions + - serial: sh-sci: Stop RX FIFO timer during port shutdown + - uwb: hwa-rc: fix memory leak at probe + - power: vexpress: fix corruption in notifier registration + - iommu/amd: make sure TLB to be flushed before IOVA freed + - Bluetooth: Add a new Realtek 8723DE ID 0bda:b009 + - USB: serial: kobil_sct: fix modem-status error handling + - 6lowpan: iphc: reset mac_header after decompress to fix panic + - iommu/msm: Don't call iommu_device_{,un}link from atomic context + - s390/mm: correct allocate_pgste proc_handler callback + - power: remove possible deadlock when unregistering power_supply + - md-cluster: clear another node's suspend_area after the copy is finished + - RDMA/bnxt_re: Fix a couple off by one bugs + - RDMA/i40w: Hold read semaphore while looking after VMA + - IB/core: type promotion bug in rdma_rw_init_one_mr() + - media: exynos4-is: Prevent NULL pointer dereference in __isp_video_try_fmt() + - IB/mlx4: Test port number before querying type. + - powerpc/kdump: Handle crashkernel memory reservation failure + - media: fsl-viu: fix error handling in viu_of_probe() + - media: staging/imx: fill vb2_v4l2_buffer field entry + - x86/tsc: Add missing header to tsc_msr.c + - ARM: hwmod: RTC: Don't assume lock/unlock will be called with irq enabled + - x86/entry/64: Add two more instruction suffixes + - ARM: dts: ls1021a: Add missing cooling device properties for CPUs + - scsi: target/iscsi: Make iscsit_ta_authentication() respect the output + buffer size + - scsi: klist: Make it safe to use klists in atomic context + - scsi: ibmvscsi: Improve strings handling + - scsi: target: Avoid that EXTENDED COPY commands trigger lock inversion + - usb: wusbcore: security: cast sizeof to int for comparison + - ath10k: sdio: use same endpoint id for all packets in a bundle + - ath10k: sdio: set skb len for all rx packets + - powerpc/powernv/ioda2: Reduce upper limit for DMA window size + - s390/sysinfo: add missing #ifdef CONFIG_PROC_FS + - alarmtimer: Prevent overflow for relative nanosleep + - s390/dasd: correct numa_node in dasd_alloc_queue + - s390/scm_blk: correct numa_node in scm_blk_dev_setup + - s390/extmem: fix gcc 8 stringop-overflow warning + - mtd: rawnand: atmel: add module param to avoid using dma + - iio: accel: adxl345: convert address field usage in iio_chan_spec + - posix-timers: Make forward callback return s64 + - ALSA: snd-aoa: add of_node_put() in error path + - media: s3c-camif: ignore -ENOIOCTLCMD from v4l2_subdev_call for s_power + - media: soc_camera: ov772x: correct setting of banding filter + - media: omap3isp: zero-initialize the isp cam_xclk{a,b} initial data + - staging: android: ashmem: Fix mmap size validation + - drivers/tty: add error handling for pcmcia_loop_config + - media: tm6000: add error handling for dvb_register_adapter + - net: phy: xgmiitorgmii: Check read_status results + - ath10k: protect ath10k_htt_rx_ring_free with rx_ring.lock + - net: phy: xgmiitorgmii: Check phy_driver ready before accessing + - drm/sun4i: Fix releasing node when enumerating enpoints + - ath10k: transmit queued frames after processing rx packets + - rndis_wlan: potential buffer overflow in rndis_wlan_auth_indication() + - brcmsmac: fix wrap around in conversion from constant to s16 + - ARM: mvebu: declare asm symbols as character arrays in pmsu.c + - arm: dts: mediatek: Add missing cooling device properties for CPUs + - HID: hid-ntrig: add error handling for sysfs_create_group + - MIPS: boot: fix build rule of vmlinux.its.S + - perf/x86/intel/lbr: Fix incomplete LBR call stack + - scsi: bnx2i: add error handling for ioremap_nocache + - iomap: complete partial direct I/O writes synchronously + - scsi: megaraid_sas: Update controller info during resume + - EDAC, i7core: Fix memleaks and use-after-free on probe and remove + - ASoC: dapm: Fix potential DAI widget pointer deref when linking DAIs + - module: exclude SHN_UNDEF symbols from kallsyms api + - gpio: Fix wrong rounding in gpio-menz127 + - nfsd: fix corrupted reply to badly ordered compound + - EDAC: Fix memleak in module init error path + - fs/lock: skip lock owner pid translation in case we are in init_pid_ns + - Input: xen-kbdfront - fix multi-touch XenStore node's locations + - iio: 104-quad-8: Fix off-by-one error in register selection + - ARM: dts: dra7: fix DCAN node addresses + - x86/mm: Expand static page table for fixmap space + - tty: serial: lpuart: avoid leaking struct tty_struct + - serial: cpm_uart: return immediately from console poll + - intel_th: Fix device removal logic + - spi: tegra20-slink: explicitly enable/disable clock + - spi: sh-msiof: Fix invalid SPI use during system suspend + - spi: sh-msiof: Fix handling of write value for SISTR register + - spi: rspi: Fix invalid SPI use during system suspend + - spi: rspi: Fix interrupted DMA transfers + - regulator: fix crash caused by null driver data + - USB: fix error handling in usb_driver_claim_interface() + - USB: handle NULL config in usb_find_alt_setting() + - usb: musb: dsps: do not disable CPPI41 irq in driver teardown + - slub: make ->cpu_partial unsigned int + - USB: usbdevfs: sanitize flags more + - USB: usbdevfs: restore warning for nonsensical flags + - USB: remove LPM management from usb_driver_claim_interface() + - IB/srp: Avoid that sg_reset -d ${srp_device} triggers an infinite loop + - IB/hfi1: Fix SL array bounds check + - IB/hfi1: Invalid user input can result in crash + - IB/hfi1: Fix context recovery when PBC has an UnsupportedVL + - RDMA/uverbs: Atomically flush and mark closed the comp event queue + - ovl: hash non-dir by lower inode for fsnotify + - drm/i915: Remove vma from object on destroy, not close + - serial: imx: restore handshaking irq for imx1 + - qed: Wait for ready indication before rereading the shmem + - qed: Wait for MCP halt and resume commands to take place + - qed: Prevent a possible deadlock during driver load and unload + - qed: Avoid sending mailbox commands when MFW is not responsive + - thermal: of-thermal: disable passive polling when thermal zone is disabled + - isofs: reject hardware sector size > 2048 bytes + - tls: possible hang when do_tcp_sendpages hits sndbuf is full case + - bpf: sockmap: write_space events need to be passed to TCP handler + - net: hns: fix length and page_offset overflow when CONFIG_ARM64_64K_PAGES + - e1000: check on netif_running() before calling e1000_up() + - e1000: ensure to free old tx/rx rings in set_ringparam() + - crypto: cavium/nitrox - fix for command corruption in queue full case with + backlog submissions. + - hwmon: (ina2xx) fix sysfs shunt resistor read access + - hwmon: (adt7475) Make adt7475_read_word() return errors + - Revert "ARM: dts: imx7d: Invert legacy PCI irq mapping" + - drm/amdgpu: Enable/disable gfx PG feature in rlc safe mode + - drm/amdgpu: Update power state at the end of smu hw_init. + - ata: ftide010: Add a quirk for SQ201 + - nvme-fcloop: Fix dropped LS's to removed target port + - ARM: dts: omap4-droid4: Fix emmc errors seen on some devices + - arm/arm64: smccc-1.1: Make return values unsigned long + - arm/arm64: smccc-1.1: Handle function result as parameters + - i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus + - x86/pti: Fix section mismatch warning/error + - media: v4l: event: Prevent freeing event subscriptions while accessed + - drm/amd/display/dc/dce: Fix multiple potential integer overflows + - drm/amd/display: fix use of uninitialized memory + - RDMA/bnxt_re: Fix a bunch of off by one bugs in qplib_fp.c + - vhost_net: Avoid tx vring kicks during busyloop + - thermal: i.MX: Allow thermal probe to fail gracefully in case of bad + calibration. + - platform/x86: asus-wireless: Fix uninitialized symbol usage + - ACPI / button: increment wakeup count only when notified + - media: ov772x: add checks for register read errors + - media: ov772x: allow i2c controllers without I2C_FUNC_PROTOCOL_MANGLING + - drm/omap: gem: Fix mm_list locking + - ASoC: rsnd: SSI parent cares SWSP bit + - staging: pi433: fix race condition in pi433_ioctl + - perf tests: Fix indexing when invoking subtests + - gpio: tegra: Fix tegra_gpio_irq_set_type() + - block: fix deadline elevator drain for zoned block devices + - serial: mvebu-uart: Fix reporting of effective CSIZE to userspace + - intel_th: Fix resource handling for ACPI glue layer + - ext2, dax: set ext2_dax_aops for dax files + - IB/hfi1: Fix destroy_qp hang after a link down + - ARM: OMAP2+: Fix null hwmod for ti-sysc debug + - ARM: OMAP2+: Fix module address for modules using mpu_rt_idx + - bus: ti-sysc: Fix module register ioremap for larger offsets + - drm/amdgpu: fix preamble handling + - amdgpu: fix multi-process hang issue + - tcp_bbr: add bbr_check_probe_rtt_done() helper + - tcp_bbr: in restart from idle, see if we should exit PROBE_RTT + - net: hns3: fix page_offset overflow when CONFIG_ARM64_64K_PAGES + - ixgbe: fix driver behaviour after issuing VFLR + - powerpc/pseries: Fix unitialized timer reset on migration + * Kernel 4.15.0-50 or newer wont boot as Xen-DomU with PVH (LP: #1829378) + - SAUCE: ACPI / bus: Fix NULL pointer dereference in + acpi_quirk_matches_bios_ids() + * CVE-2019-10126 + - mwifiex: Fix heap overflow in mwifiex_uap_parse_tail_ies() + * CVE-2019-3846 + - mwifiex: Fix possible buffer overflows at parsing bss descriptor + * CVE-2019-12818 + - net: nfc: Fix NULL dereference on nfc_llcp_build_tlv fails + * CVE-2019-12984 + - nfc: Ensure presence of required attributes in the deactivate_target handler + * Bionic update: upstream stable patchset 2019-07-10 (LP: #1836117) + - i2c: xiic: Make the start and the byte count write atomic + - i2c: i801: fix DNV's SMBCTRL register offset + - scsi: lpfc: Correct MDS diag and nvmet configuration + - nbd: don't allow invalid blocksize settings + - block: bfq: swap puts in bfqg_and_blkg_put + - android: binder: fix the race mmap and alloc_new_buf_locked + - MIPS: VDSO: Match data page cache colouring when D$ aliases + - SMB3: Backup intent flag missing for directory opens with backupuid mounts + - smb3: check for and properly advertise directory lease support + - Btrfs: fix data corruption when deduplicating between different files + - KVM: s390: vsie: copy wrapping keys to right place + - KVM: VMX: Do not allow reexecute_instruction() when skipping MMIO instr + - ALSA: hda - Fix cancel_work_sync() stall from jackpoll work + - cpu/hotplug: Adjust misplaced smb() in cpuhp_thread_fun() + - cpu/hotplug: Prevent state corruption on error rollback + - x86/microcode: Make sure boot_cpu_data.microcode is up-to-date + - x86/microcode: Update the new microcode revision unconditionally + - crypto: aes-generic - fix aes-generic regression on powerpc + - tpm: separate cmd_ready/go_idle from runtime_pm + - ARC: [plat-axs*]: Enable SWAP + - misc: mic: SCIF Fix scif_get_new_port() error handling + - ethtool: Remove trailing semicolon for static inline + - i2c: aspeed: Add an explicit type casting for *get_clk_reg_val + - Bluetooth: h5: Fix missing dependency on BT_HCIUART_SERDEV + - gpio: tegra: Move driver registration to subsys_init level + - selftests/bpf: fix a typo in map in map test + - media: davinci: vpif_display: Mix memory leak on probe error path + - media: dw2102: Fix memleak on sequence of probes + - net: phy: Fix the register offsets in Broadcom iProc mdio mux driver + - blk-mq: fix updating tags depth + - scsi: target: fix __transport_register_session locking + - md/raid5: fix data corruption of replacements after originals dropped + - timers: Clear timer_base::must_forward_clk with timer_base::lock held + - media: camss: csid: Configure data type and decode format properly + - gpu: ipu-v3: default to id 0 on missing OF alias + - misc: ti-st: Fix memory leak in the error path of probe() + - uio: potential double frees if __uio_register_device() fails + - firmware: vpd: Fix section enabled flag on vpd_section_destroy + - Drivers: hv: vmbus: Cleanup synic memory free path + - tty: rocket: Fix possible buffer overwrite on register_PCI + - f2fs: fix to active page in lru list for read path + - f2fs: do not set free of current section + - f2fs: fix defined but not used build warnings + - perf tools: Allow overriding MAX_NR_CPUS at compile time + - NFSv4.0 fix client reference leak in callback + - perf c2c report: Fix crash for empty browser + - perf evlist: Fix error out while applying initial delay and LBR + - macintosh/via-pmu: Add missing mmio accessors + - ath9k: report tx status on EOSP + - ath9k_hw: fix channel maximum power level test + - ath10k: prevent active scans on potential unusable channels + - wlcore: Set rx_status boottime_ns field on rx + - MIPS: Fix ISA virt/bus conversion for non-zero PHYS_OFFSET + - scsi: 3ware: fix return 0 on the error path of probe + - tools/testing/nvdimm: kaddr and pfn can be NULL to ->direct_access() + - ath10k: disable bundle mgmt tx completion event support + - Bluetooth: hidp: Fix handling of strncpy for hid->name information + - pinctrl: imx: off by one in imx_pinconf_group_dbg_show() + - gpio: ml-ioh: Fix buffer underwrite on probe error path + - pinctrl/amd: only handle irq if it is pending and unmasked + - net: mvneta: fix mtu change on port without link + - f2fs: try grabbing node page lock aggressively in sync scenario + - f2fs: fix to skip GC if type in SSA and SIT is inconsistent + - tpm_tis_spi: Pass the SPI IRQ down to the driver + - tpm/tpm_i2c_infineon: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - f2fs: fix to do sanity check with reserved blkaddr of inline inode + - MIPS: Octeon: add missing of_node_put() + - MIPS: generic: fix missing of_node_put() + - net: dcb: For wild-card lookups, use priority -1, not 0 + - dm cache: only allow a single io_mode cache feature to be requested + - Input: atmel_mxt_ts - only use first T9 instance + - media: s5p-mfc: Fix buffer look up in s5p_mfc_handle_frame_{new, copy_time} + functions + - media: helene: fix xtal frequency setting at power on + - f2fs: fix to wait on page writeback before updating page + - f2fs: Fix uninitialized return in f2fs_ioc_shutdown() + - iommu/ipmmu-vmsa: Fix allocation in atomic context + - mfd: ti_am335x_tscadc: Fix struct clk memory leak + - f2fs: fix to do sanity check with {sit,nat}_ver_bitmap_bytesize + - NFSv4.1: Fix a potential layoutget/layoutrecall deadlock + - MIPS: WARN_ON invalid DMA cache maintenance, not BUG_ON + - RDMA/cma: Do not ignore net namespace for unbound cm_id + - inet: frags: change inet_frags_init_net() return value + - inet: frags: add a pointer to struct netns_frags + - inet: frags: refactor ipfrag_init() + - inet: frags: refactor ipv6_frag_init() + - inet: frags: refactor lowpan_net_frag_init() + - ipv6: export ip6 fragments sysctl to unprivileged users + - rhashtable: add schedule points + - inet: frags: use rhashtables for reassembly units + - inet: frags: remove some helpers + - inet: frags: get rif of inet_frag_evicting() + - inet: frags: remove inet_frag_maybe_warn_overflow() + - inet: frags: break the 2GB limit for frags storage + - inet: frags: do not clone skb in ip_expire() + - ipv6: frags: rewrite ip6_expire_frag_queue() + - rhashtable: reorganize struct rhashtable layout + - inet: frags: reorganize struct netns_frags + - inet: frags: get rid of ipfrag_skb_cb/FRAG_CB + - inet: frags: fix ip6frag_low_thresh boundary + - ip: discard IPv4 datagrams with overlapping segments. + - net: modify skb_rbtree_purge to return the truesize of all purged skbs. + - ipv6: defrag: drop non-last frags smaller than min mtu + - net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends + - mtd: ubi: wl: Fix error return code in ubi_wl_init() + - tun: fix use after free for ptr_ring + - tuntap: fix use after free during release + - autofs: fix autofs_sbi() does not check super block type + - KVM: PPC: Book3S HV: Use correct pagesize in kvm_unmap_radix() + - ARC: [plat-axs*/plat-hsdk]: Allow U-Boot to pass MAC-address to the kernel + - x86/apic/vector: Make error return value negative + - tc-testing: flush gact actions on test teardown + - pinctrl: berlin: fix 'pctrl->functions' allocation in + berlin_pinctrl_build_state + - powerpc/4xx: Fix error return path in ppc4xx_msi_probe() + - scsi: qla2xxx: Fix unintended Logout + - iwlwifi: pcie: don't access periphery registers when not available + - f2fs: Keep alloc_valid_block_count in sync + - f2fs: issue discard align to section in LFS mode + - device-dax: avoid hang on error before devm_memremap_pages() + - regulator: tps65217: Fix NULL pointer dereference on probe + - gpio: pxa: disable pinctrl calls for PXA3xx + - thermal_hwmon: Sanitize attribute name passed to hwmon + - f2fs: fix to do sanity check with extra_attr feature + - RDMA/hns: Add illegal hop_num judgement + - RDMA/hns: Update the data type of immediate data + - be2net: Fix memory leak in be_cmd_get_profile_config() + - net/mlx5: Fix use-after-free in self-healing flow + - net: qca_spi: Fix race condition in spi transfers + - rds: fix two RCU related problems + - net/mlx5: Check for error in mlx5_attach_interface + - net/mlx5: Fix debugfs cleanup in the device init/remove flow + - net/mlx5: E-Switch, Fix memory leak when creating switchdev mode FDB tables + - net/tls: Set count of SG entries if sk_alloc_sg returns -ENOSPC + - erspan: fix error handling for erspan tunnel + - erspan: return PACKET_REJECT when the appropriate tunnel is not found + - tcp: really ignore MSG_ZEROCOPY if no SO_ZEROCOPY + - usb: dwc3: change stream event enable bit back to 13 + - iommu/io-pgtable-arm-v7s: Abort allocation when table address overflows the + PTE + - ALSA: msnd: Fix the default sample sizes + - ALSA: usb-audio: Fix multiple definitions in AU0828_DEVICE() macro + - xfrm: fix 'passing zero to ERR_PTR()' warning + - amd-xgbe: use dma_mapping_error to check map errors + - gfs2: Special-case rindex for gfs2_grow + - clk: imx6ul: fix missing of_node_put() + - clk: core: Potentially free connection id + - clk: clk-fixed-factor: Clear OF_POPULATED flag in case of failure + - kbuild: add .DELETE_ON_ERROR special target + - media: tw686x: Fix oops on buffer alloc failure + - dmaengine: pl330: fix irq race with terminate_all + - MIPS: ath79: fix system restart + - media: videobuf2-core: check for q->error in vb2_core_qbuf() + - IB/rxe: Drop QP0 silently + - block: allow max_discard_segments to be stacked + - IB/ipoib: Fix error return code in ipoib_dev_init() + - mtd/maps: fix solutionengine.c printk format warnings + - media: ov5645: Supported external clock is 24MHz + - perf test: Fix subtest number when showing results + - gfs2: Don't reject a supposedly full bitmap if we have blocks reserved + - perf tools: Synthesize GROUP_DESC feature in pipe mode + - fbdev: omapfb: off by one in omapfb_register_client() + - perf tools: Fix struct comm_str removal crash + - video: goldfishfb: fix memory leak on driver remove + - fbdev/via: fix defined but not used warning + - perf powerpc: Fix callchain ip filtering when return address is in a + register + - video: fbdev: pxafb: clear allocated memory for video modes + - fbdev: Distinguish between interlaced and progressive modes + - ARM: exynos: Clear global variable on init error path + - perf powerpc: Fix callchain ip filtering + - nvme-rdma: unquiesce queues when deleting the controller + - powerpc/powernv: opal_put_chars partial write fix + - staging: bcm2835-camera: fix timeout handling in wait_for_completion_timeout + - staging: bcm2835-camera: handle wait_for_completion_timeout return properly + - ASoC: rt5514: Fix the issue of the delay volume applied + - MIPS: jz4740: Bump zload address + - mac80211: restrict delayed tailroom needed decrement + - Smack: Fix handling of IPv4 traffic received by PF_INET6 sockets + - wan/fsl_ucc_hdlc: use IS_ERR_VALUE() to check return value of qe_muram_alloc + - reset: imx7: Fix always writing bits as 0 + - nfp: avoid buffer leak when FW communication fails + - xen-netfront: fix queue name setting + - arm64: dts: qcom: db410c: Fix Bluetooth LED trigger + - ARM: dts: qcom: msm8974-hammerhead: increase load on l20 for sdhci + - s390/qeth: fix race in used-buffer accounting + - s390/qeth: reset layer2 attribute on layer switch + - platform/x86: toshiba_acpi: Fix defined but not used build warnings + - KVM: arm/arm64: Fix vgic init race + - drivers/base: stop new probing during shutdown + - i2c: aspeed: Fix initial values of master and slave state + - dmaengine: mv_xor_v2: kill the tasklets upon exit + - crypto: sharah - Unregister correct algorithms for SAHARA 3 + - xen-netfront: fix warn message as irq device name has '/' + - RDMA/cma: Protect cma dev list with lock + - pstore: Fix incorrect persistent ram buffer mapping + - xen/netfront: fix waiting for xenbus state change + - IB/ipoib: Avoid a race condition between start_xmit and cm_rep_handler + - mmc: omap_hsmmc: fix wakeirq handling on removal + - ipmi: Fix I2C client removal in the SSIF driver + - Tools: hv: Fix a bug in the key delete code + - xhci: Fix use after free for URB cancellation on a reallocated endpoint + - usb: Don't die twice if PCI xhci host is not responding in resume + - mei: ignore not found client in the enumeration + - mei: bus: need to unlink client before freeing + - USB: Add quirk to support DJI CineSSD + - usb: uas: add support for more quirk flags + - usb: Avoid use-after-free by flushing endpoints early in usb_set_interface() + - usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame() + - USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller + - usb: gadget: udc: renesas_usb3: fix maxpacket size of ep0 + - USB: net2280: Fix erroneous synchronization change + - USB: serial: io_ti: fix array underflow in completion handler + - usb: misc: uss720: Fix two sleep-in-atomic-context bugs + - USB: serial: ti_usb_3410_5052: fix array underflow in completion handler + - USB: yurex: Fix buffer over-read in yurex_write() + - Revert "cdc-acm: implement put_char() and flush_chars()" + - cifs: prevent integer overflow in nxt_dir_entry() + - CIFS: fix wrapping bugs in num_entries() + - xtensa: ISS: don't allocate memory in platform_setup + - perf/core: Force USER_DS when recording user stack data + - NFSv4.1 fix infinite loop on I/O. + - binfmt_elf: Respect error return from `regset->active' + - net/mlx5: Add missing SET_DRIVER_VERSION command translation + - arm64: dts: uniphier: Add missing cooling device properties for CPUs + - audit: fix use-after-free in audit_add_watch + - mtdchar: fix overflows in adjustment of `count` + - Bluetooth: Use lock_sock_nested in bt_accept_enqueue + - evm: Don't deadlock if a crypto algorithm is unavailable + - KVM: PPC: Book3S HV: Add of_node_put() in success path + - security: check for kstrdup() failure in lsm_append() + - MIPS: loongson64: cs5536: Fix PCI_OHCI_INT_REG reads + - configfs: fix registered group removal + - pinctrl: rza1: Fix selector use for groups and functions + - sched/core: Use smp_mb() in wake_woken_function() + - efi/esrt: Only call efi_mem_reserve() for boot services memory + - ARM: hisi: handle of_iomap and fix missing of_node_put + - ARM: hisi: fix error handling and missing of_node_put + - ARM: hisi: check of_iomap and fix missing of_node_put + - liquidio: fix hang when re-binding VF host drv after running DPDK VF driver + - gpu: ipu-v3: csi: pass back mbus_code_to_bus_cfg error codes + - tty: fix termios input-speed encoding when using BOTHER + - tty: fix termios input-speed encoding + - mmc: sdhci-of-esdhc: set proper dma mask for ls104x chips + - mmc: tegra: prevent HS200 on Tegra 3 + - mmc: sdhci: do not try to use 3.3V signaling if not supported + - drm/nouveau: Fix runtime PM leak in drm_open() + - drm/nouveau/debugfs: Wake up GPU before doing any reclocking + - drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping + - parport: sunbpp: fix error return code + - sched/fair: Fix util_avg of new tasks for asymmetric systems + - coresight: Handle errors in finding input/output ports + - coresight: tpiu: Fix disabling timeouts + - coresight: ETM: Add support for Arm Cortex-A73 and Cortex-A35 + - staging: bcm2835-audio: Don't leak workqueue if open fails + - gpio: pxa: Fix potential NULL dereference + - gpiolib: Mark gpio_suffixes array with __maybe_unused + - mfd: 88pm860x-i2c: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - input: rohm_bu21023: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - drm/amdkfd: Fix error codes in kfd_get_process + - rtc: bq4802: add error handling for devm_ioremap + - ALSA: pcm: Fix snd_interval_refine first/last with open min/max + - scsi: libfc: fixup 'sleeping function called from invalid context' + - drm/panel: type promotion bug in s6e8aa0_read_mtp_id() + - blk-mq: only attempt to merge bio if there is rq in sw queue + - blk-mq: avoid to synchronize rcu inside blk_cleanup_queue() + - pinctrl: msm: Fix msm_config_group_get() to be compliant + - pinctrl: qcom: spmi-gpio: Fix pmic_gpio_config_get() to be compliant + - clk: tegra: bpmp: Don't crash when a clock fails to register + - mei: bus: type promotion bug in mei_nfc_if_version() + - earlycon: Initialize port->uartclk based on clock-frequency property + - earlycon: Remove hardcoded port->uartclk initialization in of_setup_earlycon + - net/ipv6: prevent use after free in ip6_route_mpath_notify + - Partial revert "e1000e: Avoid receiver overrun interrupt bursts" + - e1000e: Fix queue interrupt re-raising in Other interrupt + - e1000e: Avoid missed interrupts following ICR read + - Revert "e1000e: Separate signaling for link check/link up" + - e1000e: Fix link check race condition + - e1000e: Fix check_for_link return value with autoneg off + - tipc: orphan sock in tipc_release() + - net/mlx5: Fix not releasing read lock when adding flow rules + - iommu/arm-smmu-v3: sync the OVACKFLG to PRIQ consumer register + - iwlwifi: cancel the injective function between hw pointers to tfd entry + index + - kbuild: do not update config when running install targets + - omapfb: rename omap2 module to omap2fb.ko + - [Config] Rename omapfb to omap2fb + - perf script: Show correct offsets for DWARF-based unwinding + - iommu/ipmmu-vmsa: IMUCTRn.TTSEL needs a special usage on R-Car Gen3 + - ipmi: Move BT capabilities detection to the detect call + - ovl: fix oopses in ovl_fill_super() failure paths + - usb: xhci: fix interrupt transfer error happened on MTK platforms + - usb: mtu3: fix error of xhci port id when enable U3 dual role + - dm verity: fix crash on bufio buffer that was allocated with vmalloc + - cifs: integer overflow in in SMB2_ioctl() + - perf tools: Fix maps__find_symbol_by_name() + - NFSv4: Fix a tracepoint Oops in initiate_file_draining() + - of: add helper to lookup compatible child node + - mmc: meson-mx-sdio: fix OF child-node lookup + - bpf: fix rcu annotations in compute_effective_progs() + - spi: dw: fix possible race condition + - PM / devfreq: use put_device() instead of kfree() + - ASoC: hdmi-codec: fix routing + - drm/amd/display: support access ddc for mst branch + - rcutorture: Use monotonic timestamp for stall detection + - selftests: vDSO - fix to return KSFT_SKIP when test couldn't be run + - selftests/android: initialize heap_type to avoid compiling warning + - scsi: lpfc: Fix NVME Target crash in defer rcv logic + - scsi: lpfc: Fix panic if driver unloaded when port is offline + - arm64: perf: Disable PMU while processing counter overflows + - staging: fsl-dpaa2/eth: Fix DMA mapping direction + - block/DAC960.c: fix defined but not used build warnings + - IB/mlx5: fix uaccess beyond "count" in debugfs read/write handlers + * Bionic update: upstream stable patchset 2019-07-09 (LP: #1835972) + - vti6: fix PMTU caching and reporting on xmit + - xfrm: fix missing dst_release() after policy blocking lbcast and multicast + - xfrm: free skb if nlsk pointer is NULL + - esp6: fix memleak on error path in esp6_input + - mac80211: add stations tied to AP_VLANs during hw reconfig + - ext4: clear mmp sequence number when remounting read-only + - nl80211: Add a missing break in parse_station_flags + - drm/bridge: adv7511: Reset registers on hotplug + - scsi: target: iscsi: cxgbit: fix max iso npdu calculation + - scsi: libiscsi: fix possible NULL pointer dereference in case of TMF + - drm/imx: imx-ldb: disable LDB on driver bind + - drm/imx: imx-ldb: check if channel is enabled before printing warning + - nbd: don't requeue the same request twice. + - nbd: handle unexpected replies better + - usb: gadget: r8a66597: Fix two possible sleep-in-atomic-context bugs in + init_controller() + - usb: gadget: r8a66597: Fix a possible sleep-in-atomic-context bugs in + r8a66597_queue() + - usb: gadget: f_uac2: fix error handling in afunc_bind (again) + - usb: gadget: u_audio: fix pcm/card naming in g_audio_setup() + - usb: gadget: u_audio: update hw_ptr in iso_complete after data copied + - usb: gadget: u_audio: remove caching of stream buffer parameters + - usb: gadget: u_audio: remove cached period bytes value + - usb: gadget: u_audio: protect stream runtime fields with stream spinlock + - usb/phy: fix PPC64 build errors in phy-fsl-usb.c + - tools: usb: ffs-test: Fix build on big endian systems + - usb: gadget: f_uac2: fix endianness of 'struct cntrl_*_lay3' + - netfilter: nft_set_hash: add rcu_barrier() in the nft_rhash_destroy() + - bpf, ppc64: fix unexpected r0=0 exit path inside bpf_xadd + - netfilter: nf_tables: fix memory leaks on chain rename + - netfilter: nf_tables: don't allow to rename to already-pending name + - KVM: vmx: use local variable for current_vmptr when emulating VMPTRST + - tools/power turbostat: fix -S on UP systems + - net: caif: Add a missing rcu_read_unlock() in caif_flow_cb + - qed: Fix link flap issue due to mismatching EEE capabilities. + - qed: Fix possible race for the link state value. + - qed: Correct Multicast API to reflect existence of 256 approximate buckets. + - atl1c: reserve min skb headroom + - net: prevent ISA drivers from building on PPC32 + - can: mpc5xxx_can: check of_iomap return before use + - can: m_can: Move accessing of message ram to after clocks are enabled + - i2c: davinci: Avoid zero value of CLKH + - perf/x86/amd/ibs: Don't access non-started event + - media: staging: omap4iss: Include asm/cacheflush.h after generic includes + - bnx2x: Fix invalid memory access in rss hash config path. + - net: axienet: Fix double deregister of mdio + - locking/rtmutex: Allow specifying a subclass for nested locking + - i2c/mux, locking/core: Annotate the nested rt_mutex usage + - sched/rt: Restore rt_runtime after disabling RT_RUNTIME_SHARE + - x86/boot: Fix if_changed build flip/flop bug + - selftests/ftrace: Add snapshot and tracing_on test case + - ipc/sem.c: prevent queue.status tearing in semop + - zswap: re-check zswap_is_full() after do zswap_shrink() + - tools/power turbostat: Read extended processor family from CPUID + - ARC: dma [non-IOC] setup SMP_CACHE_BYTES and cache_line_size + - bpf: use GFP_ATOMIC instead of GFP_KERNEL in bpf_parse_prog() + - nfp: flower: fix port metadata conversion bug + - enic: handle mtu change for vf properly + - ARC: [plat-eznps] Add missing struct nps_host_reg_aux_dpc + - arc: [plat-eznps] fix data type errors in platform headers + - arc: [plat-eznps] fix printk warning in arc/plat-eznps/mtm.c + - arc: fix build errors in arc/include/asm/delay.h + - arc: fix type warnings in arc/mm/cache.c + - sparc/time: Add missing __init to init_tick_ops() + - sparc: use asm-generic version of msi.h + - enic: do not call enic_change_mtu in enic_probe + - mm: delete historical BUG from zap_pmd_range() + - drivers: net: lmc: fix case value for target abort error + - memcg: remove memcg_cgroup::id from IDR on mem_cgroup_css_alloc() failure + - gpiolib-acpi: make sure we trigger edge events at least once on boot + - scsi: fcoe: fix use-after-free in fcoe_ctlr_els_send + - scsi: fcoe: drop frames in ELS LOGO error path + - scsi: vmw_pvscsi: Return DID_RESET for status SAM_STAT_COMMAND_TERMINATED + - mm/memory.c: check return value of ioremap_prot + - mei: don't update offset in write + - cifs: add missing debug entries for kconfig options + - cifs: check kmalloc before use + - smb3: enumerating snapshots was leaving part of the data off end + - smb3: Do not send SMB3 SET_INFO if nothing changed + - smb3: don't request leases in symlink creation and query + - smb3: fill in statfs fsid and correct namelen + - btrfs: use correct compare function of dirty_metadata_bytes + - btrfs: don't leak ret from do_chunk_alloc + - Btrfs: fix btrfs_write_inode vs delayed iput deadlock + - iommu/arm-smmu: Error out only if not enough context interrupts + - printk: Split the code for storing a message into the log buffer + - printk: Create helper function to queue deferred console handling + - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI + - kprobes/arm64: Fix %p uses in error messages + - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid() + - arm64: dts: rockchip: corrected uart1 clock-names for rk3328 + - KVM: arm/arm64: Skip updating PMD entry if no change + - KVM: arm/arm64: Skip updating PTE entry if no change + - stop_machine: Reflow cpu_stop_queue_two_works() + - ext4: check for NUL characters in extended attribute's name + - ext4: sysfs: print ext4_super_block fields as little-endian + - ext4: reset error code in ext4_find_entry in fallback + - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too + - x86/vdso: Fix vDSO build if a retpoline is emitted + - x86/process: Re-export start_thread() + - x86/kvm/vmx: Remove duplicate l1d flush definitions + - fuse: Add missed unlock_page() to fuse_readpages_fill() + - udl-kms: change down_interruptible to down + - udl-kms: handle allocation failure + - udl-kms: fix crash due to uninitialized memory + - udl-kms: avoid division + - b43legacy/leds: Ensure NUL-termination of LED name string + - b43/leds: Ensure NUL-termination of LED name string + - ASoC: dpcm: don't merge format from invalid codec dai + - ASoC: zte: Fix incorrect PCM format bit usages + - ASoC: sirf: Fix potential NULL pointer dereference + - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show() + - x86/vdso: Fix lsl operand order + - x86/irqflags: Mark native_restore_fl extern inline + - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit() + - s390/mm: fix addressing exception after suspend/resume + - s390/numa: move initial setup of node_to_cpumask_map + - kprobes/arm: Fix %p uses in error messages + - kprobes: Make list and blacklist root user read only + - MIPS: Correct the 64-bit DSP accumulator register size + - MIPS: Always use -march=, not - shortcuts + - MIPS: Change definition of cpu_relax() for Loongson-3 + - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7 + - tpm: Return the actual size when receiving an unsupported command + - scsi: mpt3sas: Fix _transport_smp_handler() error path + - scsi: sysfs: Introduce sysfs_{un,}break_active_protection() + - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock + - clk: rockchip: fix clk_i2sout parent selection bits on rk3399 + - PM / clk: signedness bug in of_pm_clk_add_clks() + - power: generic-adc-battery: fix out-of-bounds write when copying channel + properties + - power: generic-adc-battery: check for duplicate properties copied from iio + channels + - watchdog: Mark watchdog touch functions as notrace + - gcc-plugins: Add include required by GCC release 8 + - gcc-plugins: Use dynamic initializers + - Btrfs: fix send failure when root has deleted files still open + - Btrfs: send, fix incorrect file layout after hole punching beyond eof + - hwmon: (k10temp) 27C Offset needed for Threadripper2 + - KVM: arm/arm64: Fix potential loss of ptimer interrupts + - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked + - perf kvm: Fix subcommands on s390 + - ext4: use ext4_warning() for sb_getblk failure + - platform/x86: wmi: Do not mix pages and kmalloc + - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd + - lib/vsprintf: Do not handle %pO[^F] as %px + - soc: qcom: rmtfs-mem: fix memleak in probe error paths + - kprobes: Show blacklist addresses as same as kallsyms does + - kprobes: Replace %p with other pointer types + - MIPS: memset.S: Fix byte_fixup for MIPSr6 + - mtd: rawnand: qcom: wait for desc completion in all BAM channels + - net: 6lowpan: fix reserved space for single frames + - net: mac802154: tx: expand tailroom if necessary + - 9p/net: Fix zero-copy path in the 9p virtio transport + - spi: davinci: fix a NULL pointer dereference + - spi: pxa2xx: Add support for Intel Ice Lake + - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe + - spi: cadence: Change usleep_range() to udelay(), for atomic context + - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS + - readahead: stricter check for bdi io_pages + - block: blk_init_allocated_queue() set q->fq as NULL in the fail case + - block: really disable runtime-pm for blk-mq + - drm/i915/userptr: reject zero user_size + - libertas: fix suspend and resume for SDIO connected cards + - media: Revert "[media] tvp5150: fix pad format frame height" + - mailbox: xgene-slimpro: Fix potential NULL pointer dereference + - Replace magic for trusting the secondary keyring with #define + - powerpc/fadump: handle crash memory ranges array index overflow + - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler. + - PCI: Add wrappers for dev_printk() + - cxl: Fix wrong comparison in cxl_adapter_context_get() + - ib_srpt: Fix a use-after-free in srpt_close_ch() + - RDMA/rxe: Set wqe->status correctly if an unexpected response is received + - 9p: fix multiple NULL-pointer-dereferences + - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed + - 9p/virtio: fix off-by-one error in sg list bounds check + - net/9p/client.c: version pointer uninitialized + - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the + kfree() + - dm integrity: change 'suspending' variable from bool to int + - dm thin: stop no_space_timeout worker when switching to write-mode + - dm cache metadata: save in-core policy_hint_size to on-disk superblock + - dm cache metadata: set dirty on all cache blocks after a crash + - dm crypt: don't decrease device limits + - uart: fix race between uart_put_char() and uart_shutdown() + - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind() + - iio: sca3000: Fix missing return in switch + - iio: ad9523: Fix displayed phase + - iio: ad9523: Fix return value for ad952x_store() + - extcon: Release locking when sending the notification of connector state + - vmw_balloon: fix inflation of 64-bit GFNs + - vmw_balloon: do not use 2MB without batching + - vmw_balloon: VMCI_DOORBELL_SET does not check status + - vmw_balloon: fix VMCI use when balloon built into kernel + - rtc: omap: fix potential crash on power off + - tracing: Do not call start/stop() functions when tracing_on does not change + - tracing/blktrace: Fix to allow setting same value + - printk/tracing: Do not trace printk_nmi_enter() + - livepatch: Validate module/old func name length + - uprobes: Use synchronize_rcu() not synchronize_sched() + - mfd: hi655x: Fix regmap area declared size for hi655x + - ovl: fix wrong use of impure dir cache in ovl_iterate() + - drivers/block/zram/zram_drv.c: fix bug storing backing_dev + - cpufreq: governor: Avoid accessing invalid governor_data + - PM / sleep: wakeup: Fix build error caused by missing SRCU support + - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages + - xtensa: limit offsets in __loop_cache_{all,page} + - xtensa: increase ranges in ___invalidate_{i,d}cache_all + - block, bfq: return nbytes and not zero from struct cftype .write() method + - pnfs/blocklayout: off by one in bl_map_stripe() + - NFSv4 client live hangs after live data migration recovery + - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs + - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence() + - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset + - iommu/vt-d: Add definitions for PFSID + - iommu/vt-d: Fix dev iotlb pfsid use + - sys: don't hold uts_sem while accessing userspace memory + - userns: move user access out of the mutex + - ubifs: Fix memory leak in lprobs self-check + - ubifs: Check data node size before truncate + - ubifs: Fix synced_i_size calculation for xattr inodes + - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output + - pwm: tiehrpwm: Fix disabling of output of PWMs + - fb: fix lost console when the user unplugs a USB adapter + - udlfb: set optimal write delay + - libnvdimm: fix ars_status output length calculation + - bcache: release dc->writeback_lock properly in bch_writeback_thread() + - perf auxtrace: Fix queue resize + - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3 + - crypto: caam/jr - fix descriptor DMA unmapping + - crypto: caam/qi - fix error path in xts setkey + - arm64: mm: always enable CONFIG_HOLES_IN_ZONE + - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts + - blkcg: Introduce blkg_root_lookup() + - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls + - IB/mlx5: Fix leaking stack memory to userspace + - rtc: omap: fix resource leak in registration error path + - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure + - ALSA: ac97: fix device initialization in the compat layer + - ALSA: ac97: fix check of pm_runtime_get_sync failure + - ALSA: ac97: fix unbalanced pm_runtime_enable + - nfsd: fix leaked file lock with nfs exported overlayfs + - ubifs: Fix directory size calculation for symlinks + - mm, dev_pagemap: Do not clear ->mapping on final put + - act_ife: fix a potential use-after-free + - ipv4: tcp: send zero IPID for RST and ACK sent in SYN-RECV and TIME-WAIT + state + - net: bcmgenet: use MAC link status for fixed phy + - net: macb: do not disable MDIO bus at open/close time + - qlge: Fix netdev features configuration. + - r8169: add support for NCube 8168 network card + - tcp: do not restart timewait timer on rst reception + - vti6: remove !skb->ignore_df check from vti6_xmit() + - net/sched: act_pedit: fix dump of extended layered op + - tipc: fix a missing rhashtable_walk_exit() + - nfp: wait for posted reconfigs when disabling the device + - sctp: hold transport before accessing its asoc in sctp_transport_get_next + - mlxsw: spectrum_switchdev: Do not leak RIFs when removing bridge + - vhost: correctly check the iova range when waking virtqueue + - hv_netvsc: ignore devices that are not PCI + - act_ife: move tcfa_lock down to where necessary + - act_ife: fix a potential deadlock + - net: sched: action_ife: take reference to meta module + - cifs: check if SMB2 PDU size has been padded and suppress the warning + - hfsplus: don't return 0 when fill_super() failed + - hfs: prevent crash on exit from failed search + - sunrpc: Don't use stack buffer with scatterlist + - fork: don't copy inconsistent signal handler state to child + - reiserfs: change j_timestamp type to time64_t + - hfsplus: fix NULL dereference in hfsplus_lookup() + - fs/proc/kcore.c: use __pa_symbol() for KCORE_TEXT list entries + - fat: validate ->i_start before using + - scripts: modpost: check memory allocation results + - virtio: pci-legacy: Validate queue pfn + - x86/mce: Add notifier_block forward declaration + - IB/hfi1: Invalid NUMA node information can cause a divide by zero + - pwm: meson: Fix mux clock names + - mm/fadvise.c: fix signed overflow UBSAN complaint + - fs/dcache.c: fix kmemcheck splat at take_dentry_name_snapshot() + - platform/x86: intel_punit_ipc: fix build errors + - netfilter: ip6t_rpfilter: set F_IFACE for linklocal addresses + - s390/kdump: Fix memleak in nt_vmcoreinfo + - ipvs: fix race between ip_vs_conn_new() and ip_vs_del_dest() + - mfd: sm501: Set coherent_dma_mask when creating subdevices + - platform/x86: asus-nb-wmi: Add keymap entry for lid flip action on UX360 + - netfilter: fix memory leaks on netlink_dump_start error + - tcp, ulp: add alias for all ulp modules + - RDMA/hns: Fix usage of bitmap allocation functions return values + - net: hns3: Fix for command format parsing error in + hclge_is_all_function_id_zero + - perf tools: Check for null when copying nsinfo. + - irqchip/bcm7038-l1: Hide cpu offline callback when building for !SMP + - net/9p/trans_fd.c: fix race by holding the lock + - net/9p: fix error path of p9_virtio_probe + - powerpc/uaccess: Enable get_user(u64, *p) on 32-bit + - powerpc: Fix size calculation using resource_size() + - perf probe powerpc: Fix trace event post-processing + - block: bvec_nr_vecs() returns value for wrong slab + - s390/dasd: fix hanging offline processing due to canceled worker + - s390/dasd: fix panic for failed online processing + - ACPI / scan: Initialize status to ACPI_STA_DEFAULT + - scsi: aic94xx: fix an error code in aic94xx_init() + - NFSv4: Fix error handling in nfs4_sp4_select_mode() + - Input: do not use WARN() in input_alloc_absinfo() + - xen/balloon: fix balloon initialization for PVH Dom0 + - PCI: mvebu: Fix I/O space end address calculation + - dm kcopyd: avoid softlockup in run_complete_job + - staging: comedi: ni_mio_common: fix subdevice flags for PFI subdevice + - ASoC: rt5677: Fix initialization of rt5677_of_match.data + - iommu/omap: Fix cache flushes on L2 table entries + - selftests/powerpc: Kill child processes on SIGINT + - RDS: IB: fix 'passing zero to ERR_PTR()' warning + - cfq: Suppress compiler warnings about comparisons + - smb3: fix reset of bytes read and written stats + - SMB3: Number of requests sent should be displayed for SMB3 not just CIFS + - powerpc/platforms/85xx: fix t1042rdb_diu.c build errors & warning + - powerpc/64s: Make rfi_flush_fallback a little more robust + - powerpc/pseries: Avoid using the size greater than RTAS_ERROR_LOG_MAX. + - clk: rockchip: Add pclk_rkpwm_pmu to PMU critical clocks in rk3399 + - KVM: vmx: track host_state.loaded using a loaded_vmcs pointer + - kvm: nVMX: Fix fault vector for VMX operation at CPL > 0 + - btrfs: Exit gracefully when chunk map cannot be inserted to the tree + - btrfs: replace: Reset on-disk dev stats value after replace + - btrfs: relocation: Only remove reloc rb_trees if reloc control has been + initialized + - btrfs: Don't remove block group that still has pinned down bytes + - arm64: rockchip: Force CONFIG_PM on Rockchip systems + - ARM: rockchip: Force CONFIG_PM on Rockchip systems + - drm/i915/lpe: Mark LPE audio runtime pm as "no callbacks" + - drm/amdgpu: Fix RLC safe mode test in gfx_v9_0_enter_rlc_safe_mode + - drm/amd/pp/Polaris12: Fix a chunk of registers missed to program + - drm/amdgpu: update tmr mc address + - drm/amdgpu:add tmr mc address into amdgpu_firmware_info + - drm/amdgpu:add new firmware id for VCN + - drm/amdgpu:add VCN support in PSP driver + - drm/amdgpu:add VCN booting with firmware loaded by PSP + - debugobjects: Make stack check warning more informative + - mm: Fix devm_memremap_pages() collision handling + - HID: add quirk for another PIXART OEM mouse used by HP + - usb: dwc3: core: Fix ULPI PHYs and prevent phy_get/ulpi_init during + suspend/resume + - x86/pae: use 64 bit atomic xchg function in native_ptep_get_and_clear + - x86/xen: don't write ptes directly in 32-bit PV guests + - drm/i915: Increase LSPCON timeout + - kbuild: make missing $DEPMOD a Warning instead of an Error + - kvm: x86: Set highest physical address bits in non-present/reserved SPTEs + - x86: kvm: avoid unused variable warning + - arm64: cpu_errata: include required headers + - ASoC: wm8994: Fix missing break in switch + - arm64: Fix mismatched cache line size detection + - arm64: Handle mismatched cache type + - tipc: fix the big/little endian issue in tipc_dest + - ip6_vti: fix a null pointer deference when destroy vti6 tunnel + - workqueue: skip lockdep wq dependency in cancel_work_sync() + - workqueue: re-add lockdep dependencies for flushing + - apparmor: fix an error code in __aa_create_ns() + - tcp, ulp: fix leftover icsk_ulp_ops preventing sock from reattach + - netfilter: x_tables: do not fail xt_alloc_table_info too easilly + - ACPICA: ACPICA: add status check for acpi_hw_read before assigning return + value + - PCI: Match Root Port's MPS to endpoint's MPSS as necessary + - coccicheck: return proper error code on fail + - RISC-V: Use KBUILD_CFLAGS instead of KCFLAGS when building the vDSO + - blk-mq: count the hctx as active before allocating tag + - selinux: cleanup dentry and inodes on error in selinuxfs + - drm/amd/display: Read back max backlight value at boot + - btrfs: check-integrity: Fix NULL pointer dereference for degraded mount + - btrfs: lift uuid_mutex to callers of btrfs_open_devices + - btrfs: Fix a C compliance issue + - drm/i915: Nuke the LVDS lid notifier + - drm/edid: Quirk Vive Pro VR headset non-desktop. + - drm/amd/display: fix type of variable + - drm/amd/display: Don't share clk source between DP and HDMI + - drm/amd/display: update clk for various HDMI color depths + - drm/amd/display: Use requested HDMI aspect ratio + - drm/rockchip: lvds: add missing of_node_put + - drm/amd/display: Pass connector id when executing VBIOS CT + - drm/amd/display: Check if clock source in use before disabling + - drm/amdgpu: fix incorrect use of fcheck + - drm/amdgpu: fix incorrect use of drm_file->pid + - drm/i915: set DP Main Stream Attribute for color range on DDI platforms + - x86/tsc: Prevent result truncation on 32bit + * [Regression] Colour banding appears on Lenovo B50-80 integrated display + (LP: #1788308) // Bionic update: upstream stable patchset 2019-07-09 + (LP: #1835972) + - drm/edid: Add 6 bpc quirk for SDC panel in Lenovo B50-80 + * CVE-2019-12819 + - mdio_bus: Fix use-after-free on device_register fails + * proc_thermal flooding dmesg (LP: #1824690) + - drivers: thermal: processor_thermal: Downgrade error message + * Bionic update: upstream stable patchset 2019-07-08 (LP: #1835845) + - bonding: avoid lockdep confusion in bond_get_stats() + - inet: frag: enforce memory limits earlier + - ipv4: frags: handle possible skb truesize change + - net: dsa: Do not suspend/resume closed slave_dev + - net: stmmac: Fix WoL for PCI-based setups + - rxrpc: Fix user call ID check in rxrpc_service_prealloc_one + - can: ems_usb: Fix memory leak on ems_usb_disconnect() + - virtio_balloon: fix another race between migration and ballooning + - x86/apic: Future-proof the TSC_DEADLINE quirk for SKX + - kvm: x86: vmx: fix vpid leak + - audit: fix potential null dereference 'context->module.name' + - userfaultfd: remove uffd flags from vma->vm_flags if UFFD_EVENT_FORK fails + - RDMA/uverbs: Expand primary and alt AV port checks + - crypto: padlock-aes - Fix Nano workaround data corruption + - drm/vc4: Reset ->{x, y}_scaling[1] when dealing with uniplanar formats + - scsi: sg: fix minor memory leak in error path + - net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager + - net/mlx5e: Set port trust mode to PCP as default + - x86/efi: Access EFI MMIO data as unencrypted when SEV is active + - drm/atomic: Check old_plane_state->crtc in drm_atomic_helper_async_check() + - drm/atomic: Initialize variables in drm_atomic_helper_async_check() to make + gcc happy + - scsi: qla2xxx: Fix unintialized List head crash + - scsi: qla2xxx: Fix NPIV deletion by calling wait_for_sess_deletion + - scsi: qla2xxx: Fix ISP recovery on unload + - scsi: qla2xxx: Return error when TMF returns + - genirq: Make force irq threading setup more robust + - nohz: Fix local_timer_softirq_pending() + - nohz: Fix missing tick reprogram when interrupting an inline softirq + - ring_buffer: tracing: Inherit the tracing setting to next ring buffer + - i2c: imx: Fix reinit_completion() use + - Btrfs: fix file data corruption after cloning a range and fsync + - nvme-pci: allocate device queues storage space at probe + - nvme-pci: Fix queue double allocations + - xfs: catch inode allocation state mismatch corruption + - xfs: validate cached inodes are free when allocated + - perf/x86/intel/uncore: Fix hardcoded index of Broadwell extra PCI devices + - parisc: Enable CONFIG_MLONGCALLS by default + - parisc: Define mb() and add memory barriers to assembler unlock sequences + - kasan: add no_sanitize attribute for clang builds + - Mark HI and TASKLET softirq synchronous + - xen/netfront: don't cache skb_shinfo() + - scsi: sr: Avoid that opening a CD-ROM hangs with runtime power management + enabled + - scsi: qla2xxx: Fix memory leak for allocating abort IOCB + - init: rename and re-order boot_cpu_state_init() + - root dentries need RCU-delayed freeing + - make sure that __dentry_kill() always invalidates d_seq, unhashed or not + - fix mntput/mntput race + - fix __legitimize_mnt()/mntput() race + - mtd: nand: qcom: Add a NULL check for devm_kasprintf() + - phy: phy-mtk-tphy: use auto instead of force to bypass utmi signals + - ARM: dts: imx6sx: fix irq for pcie bridge + - kprobes/x86: Fix %p uses in error messages + - x86/irqflags: Provide a declaration for native_save_fl + - x86/apic: Ignore secondary threads if nosmt=force + - x86/mm/kmmio: Make the tracer robust against L1TF + - tools headers: Synchronise x86 cpufeatures.h for L1TF additions + - x86/microcode: Allow late microcode loading with SMT disabled + - x86/smp: fix non-SMP broken build due to redefinition of + apic_id_is_primary_thread + - cpu/hotplug: Non-SMP machines do not make use of booted_once + - sched/deadline: Update rq_clock of later_rq when pushing a task + - zram: remove BD_CAP_SYNCHRONOUS_IO with writeback feature + - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled + - x86: i8259: Add missing include file + - kbuild: verify that $DEPMOD is installed + - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2() + - crypto: vmac - require a block cipher with 128-bit block size + - crypto: vmac - separate tfm and request context + - crypto: blkcipher - fix crash flushing dcache in error path + - crypto: ablkcipher - fix crash flushing dcache in error path + - crypto: skcipher - fix aligning block size in skcipher_copy_iv() + - crypto: skcipher - fix crash flushing dcache in error path + - x86/platform/UV: Mark memblock related init code and data correctly + - dccp: fix undefined behavior with 'cwnd' shift in ccid2_cwnd_restart() + - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache + - llc: use refcount_inc_not_zero() for llc_sap_find() + - vsock: split dwork to avoid reinitializations + - net_sched: Fix missing res info when create new tc_index filter + - vhost: reset metadata cache when initializing new IOTLB + - ip6_tunnel: use the right value for ipv4 min mtu check in ip6_tnl_xmit + - net: aquantia: Fix IFF_ALLMULTI flag functionality + - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs + - ALSA: hda - Turn CX8200 into D3 as well upon reboot + - ALSA: vx222: Fix invalid endian conversions + - ALSA: virmidi: Fix too long output trigger loop + - ALSA: cs5535audio: Fix invalid endian conversion + - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry + - ALSA: memalloc: Don't exceed over the requested size + - ALSA: vxpocket: Fix invalid endian conversions + - USB: serial: sierra: fix potential deadlock at close + - USB: serial: pl2303: add a new device id for ATEN + - ACPI / PM: save NVS memory for ASUS 1025C laptop + - tty: serial: 8250: Revert NXP SC16C2552 workaround + - serial: 8250_exar: Read INT0 from slave device, too + - serial: 8250_dw: always set baud rate in dw8250_set_termios + - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC + - misc: sram: fix resource leaks in probe error path + - Bluetooth: avoid killing an already killed socket + - isdn: Disable IIOCDBGVAR + - cls_matchall: fix tcf_unbind_filter missing + - mlxsw: core_acl_flex_actions: Return error for conflicting actions + - ip_vti: fix a null pointer deferrence when create vti fallback tunnel + - net: ethernet: mvneta: Fix napi structure mixup on armada 3700 + - net: mvneta: fix mvneta_config_rss on armada 3700 + - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[] + - pty: fix O_CLOEXEC for TIOCGPTPEER + - arm: dts: armada: Fix "#cooling-cells" property's name + - vfio: ccw: fix error return in vfio_ccw_sch_event + - perf tools: Fix error index for pmu event parser + - Input: synaptics-rmi4 - fix axis-swap behavior + - IB/mlx4: Fix an error handling path in 'mlx4_ib_rereg_user_mr()' + - drm/bridge/sii8620: fix loops in EDID fetch logic + - drm/bridge/sii8620: fix potential buffer overflow + - ARC: Explicitly add -mmedium-calls to CFLAGS + - hwmon: (nct6775) Fix loop limit + - soc: imx: gpcv2: correct PGC offset + - usb: dwc3: pci: add support for Intel IceLake + - usb: dwc2: gadget: Fix issue in dwc2_gadget_start_isoc() + - usb: dwc3: of-simple: fix use-after-free on remove + - ACPI / EC: Use ec_no_wakeup on Thinkpad X1 Carbon 6th + - netfilter: ipv6: nf_defrag: reduce struct net memory waste + - netfilter: nf_ct_helper: Fix possible panic after + nf_conntrack_helper_unregister + - selftests: pstore: return Kselftest Skip code for skipped tests + - selftests: static_keys: return Kselftest Skip code for skipped tests + - selftests: sysctl: return Kselftest Skip code for skipped tests + - selftests: zram: return Kselftest Skip code for skipped tests + - selftests: vm: return Kselftest Skip code for skipped tests + - selftests: sync: add config fragment for testing sync framework + - ARM: dts: NSP: Fix i2c controller interrupt type + - ARM: dts: NSP: Fix PCIe controllers interrupt types + - ARM: dts: BCM5301x: Fix i2c controller interrupt type + - ARM: dts: Cygnus: Fix I2C controller interrupt type + - ARM: dts: Cygnus: Fix PCIe controller interrupt type + - arm64: dts: specify 1.8V EMMC capabilities for bcm958742k + - arm64: dts: specify 1.8V EMMC capabilities for bcm958742t + - arm64: dts: ns2: Fix I2C controller interrupt type + - arm64: dts: ns2: Fix PCIe controller interrupt type + - arm64: dts: Stingray: Fix I2C controller interrupt type + - drivers/perf: xgene_pmu: Fix IOB SLOW PMU parser error + - drm: mali-dp: Enable Global SE interrupts mask for DP500 + - drm/arm/malidp: Preserve LAYER_FORMAT contents when setting format + - IB/rxe: Fix missing completion for mem_reg work requests + - usb: dwc2: alloc dma aligned buffer for isoc split in + - usb: dwc2: fix isoc split in transfer with no data + - usb: gadget: composite: fix delayed_status race condition when set_interface + - usb: gadget: dwc2: fix memory leak in gadget_init() + - dwc2: gadget: Fix ISOC IN DDMA PID bitfield value calculation + - xen: add error handling for xenbus_printf + - pNFS: Always free the session slot on error in + nfs4_layoutget_handle_exception + - scsi: xen-scsifront: add error handling for xenbus_printf + - xen/scsiback: add error handling for xenbus_printf + - arm64: dma-mapping: clear buffers allocated with FORCE_CONTIGUOUS flag + - arm64: make secondary_start_kernel() notrace + - qed: Fix possible memory leak in Rx error path handling. + - qed: Add sanity check for SIMD fastpath handler. + - qed: Do not advertise DCBX_LLD_MANAGED capability. + - enic: initialize enic->rfs_h.lock in enic_probe + - net: hamradio: use eth_broadcast_addr + - net: propagate dev_get_valid_name return code + - net: stmmac: socfpga: add additional ocp reset line for Stratix10 + - nvmet: reset keep alive timer in controller enable + - block: sed-opal: Fix a couple off by one bugs + - ARC: Enable machine_desc->init_per_cpu for !CONFIG_SMP + - nbd: Add the nbd NBD_DISCONNECT_ON_CLOSE config flag. + - net: davinci_emac: match the mdio device against its compatible if possible + - sctp: fix erroneous inc of snmp SctpFragUsrMsgs + - KVM: arm/arm64: Drop resource size check for GICV window + - drm/bridge/sii8620: fix display of packed pixel modes in MHL2 + - locking/lockdep: Do not record IRQ state within lockdep code + - selftests: bpf: notification about privilege required to run test_kmod.sh + testing script + - mtd: dataflash: Use ULL suffix for 64-bit constants + - x86/microcode/intel: Fix memleak in save_microcode_patch() + - ipv6: mcast: fix unsolicited report interval after receiving querys + - Smack: Mark inode instant in smack_task_to_inode + - arm64: dts: msm8916: fix Coresight ETF graph connections + - batman-adv: Fix bat_ogm_iv best gw refcnt after netlink dump + - batman-adv: Fix bat_v best gw refcnt after netlink dump + - batman-adv: Avoid storing non-TT-sync flags on singular entries too + - batman-adv: Fix multicast TT issues with bogus ROAM flags + - cxgb4: when disabling dcb set txq dcb priority to 0 + - iio: pressure: bmp280: fix relative humidity unit + - brcmfmac: stop watchdog before detach and free everything + - ARM: dts: am437x: make edt-ft5x06 a wakeup source + - ALSA: seq: Fix UBSAN warning at SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT ioctl + - usb: xhci: remove the code build warning + - usb: xhci: increase CRS timeout value + - NFC: pn533: Fix wrong GFP flag usage + - typec: tcpm: Fix a msecs vs jiffies bug + - kconfig: fix line numbers for if-entries in menu tree + - perf record: Support s390 random socket_id assignment + - perf test session topology: Fix test on s390 + - perf report powerpc: Fix crash if callchain is empty + - perf tools: Fix a clang 7.0 compilation error + - perf bench: Fix numa report output code + - ARM: davinci: board-da850-evm: fix WP pin polarity for MMC/SD + - netfilter: nf_log: fix uninit read in nf_log_proc_dostring + - net/mlx5: E-Switch, Disallow vlan/spoofcheck setup if not being esw manager + - nfp: cast sizeof() to int when comparing with error code + - selftests/x86/sigreturn/64: Fix spurious failures on AMD CPUs + - selftests/x86/sigreturn: Do minor cleanups + - ARM: dts: da850: Fix interrups property for gpio + - ARM64: dts: meson-gxl: fix Mali GPU compatible string + - dmaengine: pl330: report BURST residue granularity + - dmaengine: k3dma: Off by one in k3_of_dma_simple_xlate() + - ath10k: update the phymode along with bandwidth change request + - md/raid10: fix that replacement cannot complete recovery after reassemble + - dev-dax: check_vma: ratelimit dev_info-s + - nl80211: relax ht operation checks for mesh + - nl80211: check nla_parse_nested() return values + - drm/exynos: gsc: Fix support for NV16/61, YUV420/YVU420 and YUV422 modes + - drm/exynos: decon5433: Fix per-plane global alpha for XRGB modes + - drm/exynos: decon5433: Fix WINCONx reset value + - drbd: Fix drbd_request_prepare() discard handling + - bpf, s390: fix potential memleak when later bpf_jit_prog fails + - PCI: xilinx: Add missing of_node_put() + - PCI: xilinx-nwl: Add missing of_node_put() + - PCI: faraday: Add missing of_node_put() + - bnx2x: Fix receiving tx-timeout in error or recovery state. + - fsl/fman: fix parser reporting bad checksum on short frames + - dpaa_eth: DPAA SGT needs to be 256B + - acpi/nfit: fix cmd_rc for acpi_nfit_ctl to always return a value + - openrisc: entry: Fix delay slot exception detection + - m68k: fix "bad page state" oops on ColdFire boot + - objtool: Support GCC 8 '-fnoreorder-functions' + - ipvlan: call dev_change_flags when ipvlan mode is reset + - drm/amdgpu: fix swapped emit_ib_size in vce3 + - x86/mm/32: Initialize the CR4 shadow before __flush_tlb_all() + - HID: wacom: Correct touch maximum XY of 2nd-gen Intuos + - ARM: imx_v4_v5_defconfig: Select ULPI support + - bpf: hash map: decrement counter on error + - tracing: Use __printf markup to silence compiler + - kasan: fix shadow_size calculation error in kasan_module_alloc + - smsc75xx: Add workaround for gigabit link up hardware errata. + - drm/bridge/sii8620: Fix display of packed pixel modes + - samples/bpf: add missing + - samples/bpf: Check the result of system() + - samples/bpf: Check the error of write() and read() + - ieee802154: 6lowpan: set IFLA_LINK + - netfilter: x_tables: set module owner for icmp(6) matches + - ipv6: make ipv6_renew_options() interrupt/kernel safe + - net: qrtr: Broadcast messages only from control port + - sh_eth: fix invalid context bug while calling auto-negotiation by ethtool + - sh_eth: fix invalid context bug while changing link options by ethtool + - ravb: fix invalid context bug while calling auto-negotiation by ethtool + - ravb: fix invalid context bug while changing link options by ethtool + - ARM: pxa: irq: fix handling of ICMR registers in suspend/resume + - net/sched: act_tunnel_key: fix NULL dereference when 'goto chain' is used + - nvmem: Don't let a NULL cell_id for nvmem_cell_get() crash us + - ieee802154: at86rf230: switch from BUG_ON() to WARN_ON() on problem + - ieee802154: at86rf230: use __func__ macro for debug messages + - ieee802154: fakelb: switch from BUG_ON() to WARN_ON() on problem + - gpu: host1x: Check whether size of unpin isn't 0 + - drm/tegra: Fix comparison operator for buffer size + - drm/armada: fix colorkey mode property + - drm/armada: fix irq handling + - netfilter: nft_compat: explicitly reject ERROR and standard target + - netfilter: nf_conntrack: Fix possible possible crash on module loading. + - ARC: Improve cmpxchg syscall implementation + - bnxt_en: Fix inconsistent BNXT_FLAG_AGG_RINGS logic. + - bnxt_en: Always set output parameters in bnxt_get_max_rings(). + - bnxt_en: Fix for system hang if request_irq fails + - scsi: qedf: Send the driver state to MFW + - scsi: qedi: Send driver state to MFW + - perf llvm-utils: Remove bashism from kernel include fetch script + - perf tools: Fix compilation errors on gcc8 + - perf script python: Fix dict reference counting + - nfit: fix unchecked dereference in acpi_nfit_ctl + - RDMA/mlx5: Fix memory leak in mlx5_ib_create_srq() error path + - ARM: 8780/1: ftrace: Only set kernel memory back to read-only after boot + - ARM: DRA7/OMAP5: Enable ACTLR[0] (Enable invalidates of BTB) for secondary + cores + - ARM: dts: am3517.dtsi: Disable reference to OMAP3 OTG controller + - ixgbe: Be more careful when modifying MAC filters + - tools: build: Use HOSTLDFLAGS with fixdep + - kbuild: suppress warnings from 'getconf LFS_*' + - packet: reset network header if packet shorter than ll reserved space + - qlogic: check kstrtoul() for errors + - tcp: remove DELAYED ACK events in DCTCP + - pinctrl: ingenic: Fix inverted direction for < JZ4770 + - pinctrl: nsp: off by ones in nsp_pinmux_enable() + - pinctrl: nsp: Fix potential NULL dereference + - drm/nouveau/gem: off by one bugs in nouveau_gem_pushbuf_reloc_apply() + - net/ethernet/freescale/fman: fix cross-build error + - ibmvnic: Fix error recovery on login failure + - btrfs: scrub: Don't use inode page cache in scrub_handle_errored_block() + - octeon_mgmt: Fix MIX registers configuration on MTU setup + - net: usb: rtl8150: demote allmulti message to dev_dbg() + - PCI: OF: Fix I/O space page leak + - PCI: versatile: Fix I/O space page leak + - net: qca_spi: Avoid packet drop during initial sync + - net: qca_spi: Make sure the QCA7000 reset is triggered + - net: qca_spi: Fix log level if probe fails + - tcp: identify cryptic messages as TCP seq # bugs + - soc: imx: gpc: restrict register range for regmap access + - ACPI / EC: Use ec_no_wakeup on more Thinkpad X1 Carbon 6th systems + - ARM: dts: imx6: RDU2: fix irq type for mv88e6xxx switch + - nvme: fix handling of metadata_len for NVME_IOCTL_IO_CMD + - parisc: Remove ordered stores from syscall.S + - xfrm_user: prevent leaking 2 bytes of kernel memory + - netfilter: conntrack: dccp: treat SYNC/SYNCACK as invalid if no prior state + - packet: refine ring v3 block size test to hold one frame + - net/smc: no shutdown in state SMC_LISTEN + - parisc: Remove unnecessary barriers from spinlock.h + - PCI: hotplug: Don't leak pci_slot on registration failure + - PCI: Skip MPS logic for Virtual Functions (VFs) + - PCI: pciehp: Fix use-after-free on unplug + - PCI: pciehp: Fix unprotected list iteration in IRQ handler + - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes + - i2c: imx: Fix race condition in dma read + - reiserfs: fix broken xattr handling (heap corruption, bad retval) + - updateconfigs for v4.14.67 + - IB/rxe: avoid double kfree skb + - RDMA/qedr: Fix NULL pointer dereference when running over iWARP without + RDMA-CM + - smb3: increase initial number of credits requested to allow write + - hwmon: (dell-smm) Disable fan support for Dell XPS13 9333 + - ARM: dts: HR2: Fix interrupt types for i2c and PCIe + - drm/arm/malidp: Ensure that the crtcs are shutdown before removing any + encoder/connector + - drm/mali-dp: Rectify the width and height passed to rotmem_required() + - dmaengine: ti: omap-dma: Fix OMAP1510 incorrect residue_granularity + - nvme-rdma: fix possible double free condition when failing to create a + controller + - nvme-rdma: Fix command completion race at error recovery + - nvme-pci: move nvme_kill_queues to nvme_remove_dead_ctrl + - clk: sunxi-ng: replace lib-y with obj-y + - batman-adv: Fix debugfs path for renamed hardif + - batman-adv: Fix debugfs path for renamed softif + - nfp: bpf: don't stop offload if replace failed + - perf tests: Add event parsing error handling to parse events test + - perf script: Fix crash because of missing evsel->priv + - perf tools: Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE] + - s390/qeth: consistently re-enable device features + - sched/fair: Fix bandwidth timer clock drift condition + - r8169: fix mac address change + - RISC-V: Don't include irq-riscv-intc.h + - RISC-V: Fix PTRACE_SETREGSET bug. + - net: qrtr: Reset the node and port ID of broadcast messages + - cxgb4: assume flash part size to be 4MB, if it can't be determined + - bpf: fix sk_skb programs without skb->dev assigned + - ipfrag: really prevent allocation on netns exit + - gpu: host1x: Skip IOMMU initialization if firewall is enabled + - ARC: [plat-hsdk]: Configure APB GPIO controller on ARC HSDK platform + - bnxt_en: Do not modify max IRQ count after RDMA driver requests/frees IRQs. + - scsi: hpsa: correct enclosure sas address + - perf tools: Use python-config --includes rather than --cflags + - sfp: ensure we clean up properly on bus registration failure + - amd/dc/dce100: On dce100, set clocks to 0 on suspend + - tools: build: Fixup host c flags + - kvm: nVMX: Restore exit qual for VM-entry failure due to MSR loading + - ibmvnic: Revise RX/TX queue error messages + - net/smc: reset recv timeout after clc handshake + - PCI: xgene: Fix I/O space page leak + - PCI: designware: Fix I/O space page leak + - PCI: aardvark: Fix I/O space page leak + - PCI: faraday: Fix I/O space page leak + - PCI: mediatek: Fix I/O space page leak + - PCI: v3-semi: Fix I/O space page leak + - platform/x86: dell-laptop: Fix backlight detection + - mm: use helper functions for allocating and freeing vm_area structs + - mm: make vm_area_dup() actually copy the old vma data + - mm: make vm_area_alloc() initialize core fields + - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM + + -- Kleber Sacilotto de Souza Thu, 25 Jul 2019 14:26:11 +0200 + +linux-oracle (4.15.0-1018.20) bionic; urgency=medium + + * linux-oracle: 4.15.0-1018.20 -proposed tracker (LP: #1834943) + + [ Ubuntu: 4.15.0-55.60 ] + + * linux: 4.15.0-55.60 -proposed tracker (LP: #1834954) + * Request backport of ceph commits into bionic (LP: #1834235) + - ceph: use atomic_t for ceph_inode_info::i_shared_gen + - ceph: define argument structure for handle_cap_grant + - ceph: flush pending works before shutdown super + - ceph: send cap releases more aggressively + - ceph: single workqueue for inode related works + - ceph: avoid dereferencing invalid pointer during cached readdir + - ceph: quota: add initial infrastructure to support cephfs quotas + - ceph: quota: support for ceph.quota.max_files + - ceph: quota: don't allow cross-quota renames + - ceph: fix root quota realm check + - ceph: quota: support for ceph.quota.max_bytes + - ceph: quota: update MDS when max_bytes is approaching + - ceph: quota: add counter for snaprealms with quota + - ceph: avoid iput_final() while holding mutex or in dispatch thread + * QCA9377 isn't being recognized sometimes (LP: #1757218) + - SAUCE: USB: Disable USB2 LPM at shutdown + * hns: fix ICMP6 neighbor solicitation messages discard problem (LP: #1833140) + - net: hns: fix ICMP6 neighbor solicitation messages discard problem + - net: hns: fix unsigned comparison to less than zero + * Fix occasional boot time crash in hns driver (LP: #1833138) + - net: hns: Fix probabilistic memory overwrite when HNS driver initialized + * use-after-free in hns_nic_net_xmit_hw (LP: #1833136) + - net: hns: fix KASAN: use-after-free in hns_nic_net_xmit_hw() + * hns: attempt to restart autoneg when disabled should report error + (LP: #1833147) + - net: hns: Restart autoneg need return failed when autoneg off + * systemd 237-3ubuntu10.14 ADT test failure on Bionic ppc64el (test-seccomp) + (LP: #1821625) + - powerpc: sys_pkey_alloc() and sys_pkey_free() system calls + - powerpc: sys_pkey_mprotect() system call + * [UBUNTU] pkey: Indicate old mkvp only if old and curr. mkvp are different + (LP: #1832625) + - pkey: Indicate old mkvp only if old and current mkvp are different + * [UBUNTU] kernel: Fix gcm-aes-s390 wrong scatter-gather list processing + (LP: #1832623) + - s390/crypto: fix gcm-aes-s390 selftest failures + * System crashes on hot adding a core with drmgr command (4.15.0-48-generic) + (LP: #1833716) + - powerpc/numa: improve control of topology updates + - powerpc/numa: document topology_updates_enabled, disable by default + * Kernel modules generated incorrectly when system is localized to a non- + English language (LP: #1828084) + - scripts: override locale from environment when running recordmcount.pl + * [UBUNTU] kernel: Fix wrong dispatching for control domain CPRBs + (LP: #1832624) + - s390/zcrypt: Fix wrong dispatching for control domain CPRBs + * CVE-2019-11815 + - net: rds: force to destroy connection if t_sock is NULL in + rds_tcp_kill_sock(). + * Sound device not detected after resume from hibernate (LP: #1826868) + - drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled + - drm/i915: Save the old CDCLK atomic state + - drm/i915: Remove redundant store of logical CDCLK state + - drm/i915: Skip modeset for cdclk changes if possible + * Handle overflow in proc_get_long of sysctl (LP: #1833935) + - sysctl: handle overflow in proc_get_long + * Dell XPS 13 (9370) defaults to s2idle sleep/suspend instead of deep, NVMe + drains lots of power under s2idle (LP: #1808957) + - Revert "UBUNTU: SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 + and being disabled" + - Revert "UBUNTU: SAUCE: nvme: add quirk to not call disable function when + suspending" + - Revert "UBUNTU: SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3" + - Revert "SAUCE: nvme: add quirk to not call disable function when suspending" + - Revert "SAUCE: pci: prevent sk hynix nvme from entering D3" + - PCI: PM: Avoid possible suspend-to-idle issue + - PCI: PM: Skip devices in D0 for suspend-to-idle + - nvme-pci: Sync queues on reset + - nvme: Export get and set features + - nvme-pci: Use host managed power state for suspend + * linux v4.15 ftbfs on a newer host kernel (e.g. hwe) (LP: #1823429) + - selinux: use kernel linux/socket.h for genheaders and mdp + * 32-bit x86 kernel 4.15.0-50 crash in vmalloc_sync_all (LP: #1830433) + - x86/mm/pat: Disable preemption around __flush_tlb_all() + - x86/mm: Drop usage of __flush_tlb_all() in kernel_physical_mapping_init() + - x86/mm: Disable ioremap free page handling on x86-PAE + - ioremap: Update pgtable free interfaces with addr + - x86/mm: Add TLB purge to free pmd/pte page interfaces + - x86/init: fix build with CONFIG_SWAP=n + - x86/mm: provide pmdp_establish() helper + - x86/mm: Use WRITE_ONCE() when setting PTEs + * hinic: fix oops due to race in set_rx_mode (LP: #1832048) + - hinic: fix a bug in set rx mode + * ubuntu 18.04 flickering screen with Radeon X1600 (LP: #1791312) + - drm/radeon: prefer lower reference dividers + * Login screen never appears on vmwgfx using bionic kernel 4.15 (LP: #1832138) + - drm/vmwgfx: use monotonic event timestamps + * [linux-azure] Block Layer Commits Requested in Azure Kernels (LP: #1834499) + - block: Clear kernel memory before copying to user + - block/bio: Do not zero user pages + * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864) + - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches + * Handle overflow for file-max (LP: #1834310) + - sysctl: handle overflow for file-max + - kernel/sysctl.c: fix out-of-bounds access when setting file-max + * [ALSA] [PATCH] Headset fixup for System76 Gazelle (gaze14) (LP: #1827555) + - ALSA: hda/realtek - Headset fixup for System76 Gazelle (gaze14) + - ALSA: hda/realtek - Corrected fixup for System76 Gazelle (gaze14) + * crashdump fails on HiSilicon D06 (LP: #1828868) + - iommu/arm-smmu-v3: Abort all transactions if SMMU is enabled in kdump kernel + - iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel + * CVE-2019-11833 + - ext4: zero out the unused memory region in the extent tree block + * zfs 0.7.9 fixes a bug (https://github.com/zfsonlinux/zfs/pull/7343) that + hangs the system completely (LP: #1772412) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.6 + * does not detect headphone when there is no other output devices + (LP: #1831065) + - ALSA: hda/realtek - Fixed hp_pin no value + - ALSA: hda/realtek - Use a common helper for hp pin reference + * kernel crash : net_sched race condition in tcindex_destroy() (LP: #1825942) + - net_sched: fix NULL pointer dereference when delete tcindex filter + - RCU, workqueue: Implement rcu_work + - net_sched: switch to rcu_work + - net_sched: fix a race condition in tcindex_destroy() + - net_sched: fix a memory leak in cls_tcindex + - net_sched: initialize net pointer inside tcf_exts_init() + - net_sched: fix two more memory leaks in cls_tcindex + * Support new ums-realtek device (LP: #1831840) + - USB: usb-storage: Add new ID to ums-realtek + * amd_iommu possible data corruption (LP: #1823037) + - iommu/amd: Reserve exclusion range in iova-domain + - iommu/amd: Set exclusion range correctly + * Add new sound card PCIID into the alsa driver (LP: #1832299) + - ALSA: hda: Add Icelake PCI ID + - ALSA: hda/intel: add CometLake PCI IDs + * sky2 ethernet card doesn't work after returning from suspend + (LP: #1807259) // sky2 ethernet card link not up after suspend + (LP: #1809843) + - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79 + * idle-page oopses when accessing page frames that are out of range + (LP: #1833410) + - mm/page_idle.c: fix oops because end_pfn is larger than max_pfn + * Add pointstick support on HP ZBook 17 G5 (LP: #1833387) + - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A" + - SAUCE: HID: multitouch: Add pointstick support for ALPS Touchpad + * [SRU][B/B-OEM/B-OEM-OSP-1/C/D/E] Add trackpoint middle button support of 2 + new thinpads (LP: #1833637) + - Input: elantech - enable middle button support on 2 ThinkPads + * CVE-2019-11085 + - drm/i915/gvt: Fix mmap range check + - drm/i915: make mappable struct resource centric + - drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on + * CVE-2019-11884 + - Bluetooth: hidp: fix buffer overflow + * af_alg06 test from crypto test suite in LTP failed with kernel oops on B/C + (LP: #1829725) + - crypto: authenc - fix parsing key with misaligned rta_len + * CVE-2018-12126 // CVE-2018-12127 // CVE-2018-12130 // CVE-2019-11091 + - SAUCE: Synchronize MDS mitigations with upstream + - Documentation: Correct the possible MDS sysfs values + - x86/speculation/mds: Fix documentation typo + * CVE-2019-11091 + - x86/mds: Add MDSUM variant to the MDS documentation + * alignment test in powerpc from ubuntu_kernel_selftests failed on B/C Power9 + (LP: #1813118) + - selftests/powerpc: Remove Power9 copy_unaligned test + * TRACE_syscall.ptrace_syscall_dropped in seccomp from ubuntu_kernel_selftests + failed on B/C PowerPC (LP: #1812796) + - selftests/seccomp: Enhance per-arch ptrace syscall skip tests + * Add powerpc/alignment_handler test for selftests (LP: #1828935) + - selftests/powerpc: Add alignment handler selftest + - selftests/powerpc: Fix to use ucontext_t instead of struct ucontext + * Cannot build kernel 4.15.0-48.51 due to an in-source-tree ZFS module. + (LP: #1828763) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.5 + * Eletrical noise occurred when external headset enter powersaving mode on a + DEll machine (LP: #1828798) + - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone + - ALSA: hda/realtek - Fixup headphone noise via runtime suspend + * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on + Ubuntu (LP: #1761379) + - [Packaging] Support building libperf-jvmti.so + * TCP : race condition on socket ownership in tcp_close() (LP: #1830813) + - tcp: do not release socket ownership in tcp_close() + * bionic: netlink: potential shift overflow in netlink_bind() (LP: #1831103) + - netlink: Don't shift on 64 for ngroups + * Add support to Comet Lake LPSS (LP: #1830175) + - mfd: intel-lpss: Add Intel Comet Lake PCI IDs + * Reduce NAPI weight in hns driver from 256 to 64 (LP: #1830587) + - net: hns: Use NAPI_POLL_WEIGHT for hns driver + * x86: add support for AMD Rome (LP: #1819485) + - x86: irq_remapping: Move irq remapping mode enum + - iommu/amd: Add support for higher 64-bit IOMMU Control Register + - iommu/amd: Add support for IOMMU XT mode + - hwmon/k10temp, x86/amd_nb: Consolidate shared device IDs + - hwmon/k10temp: Add support for AMD family 17h, model 30h CPUs + - x86/amd_nb: Add PCI device IDs for family 17h, model 30h + - x86/MCE/AMD: Fix the thresholding machinery initialization order + - x86/amd_nb: Add support for newer PCI topologies + * nx842 - CRB request time out (-110) when uninstall NX modules and initiate + NX request (LP: #1827755) + - crypto/nx: Initialize 842 high and normal RxFIFO control registers + * Require improved hypervisor detection patch in Ubuntu 18.04 (LP: #1829972) + - s390/early: improve machine detection + + -- Khalid Elmously Wed, 03 Jul 2019 02:12:27 -0400 + +linux-oracle (4.15.0-1017.19) bionic; urgency=medium + + * linux-oracle: 4.15.0-1017.19 -proposed tracker (LP: #1833979) + + [ Ubuntu: 4.15.0-54.58 ] + + * linux: 4.15.0-54.58 -proposed tracker (LP: #1833987) + * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard + manipulation (LP: #1831638) // CVE-2019-11478 + - tcp: refine memory limit test in tcp_fragment() + * CVE-2019-11479 + - SAUCE: tcp: add tcp_min_snd_mss sysctl + - SAUCE: tcp: enforce tcp_min_snd_mss in tcp_mtu_probing() + + -- Kleber Sacilotto de Souza Mon, 24 Jun 2019 17:48:50 +0200 + +linux-oracle (4.15.0-1015.17) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-52.56 ] + + * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard + manipulation (LP: #1831638) + - SAUCE: tcp: tcp_fragment() should apply sane memory limits + * Remote denial of service (system crash) caused by integer overflow in TCP + SACK handling (LP: #1831637) + - SAUCE: tcp: limit payload size of sacked skbs + + -- Marcelo Henrique Cerri Wed, 05 Jun 2019 14:48:40 -0300 + +linux-oracle (4.15.0-1014.16) bionic; urgency=medium + + * linux-oracle: 4.15.0-1014.16 -proposed tracker (LP: #1829210) + + [ Ubuntu: 4.15.0-51.55 ] + + * linux: 4.15.0-51.55 -proposed tracker (LP: #1829219) + * disable a.out support (LP: #1818552) + - [Config] Disable a.out support + * [UBUNTU] qdio: clear intparm during shutdown (LP: #1828394) + - s390/qdio: clear intparm during shutdown + * ftrace in ubuntu_kernel_selftests hang with Cosmic kernel (LP: #1826385) + - kprobes/x86: Fix instruction patching corruption when copying more than one + RIP-relative instruction + * touchpad not working on lenovo yoga 530 (LP: #1787775) + - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI" + - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base" + - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for + upcoming platform" + - i2c: add helpers to ease DMA handling + - i2c: add a message flag for DMA safe buffers + - i2c: add extra check to safe DMA buffer helper + - i2c: Add drivers for the AMD PCIe MP2 I2C controller + - [Config] Update config for AMD MP2 I2C driver + - [Config] Update I2C_AMD_MP2 annotations + * tm-unavailable in powerpc/tm failed on Bionic Power9 (LP: #1813129) + - selftests/powerpc: Check for pthread errors in tm-unavailable + - selftests/powerpc: Skip tm-unavailable if TM is not enabled + * cp_abort in powerpc/context_switch from ubunut_kernel_selftests failed on + Bionic P9 (LP: #1813134) + - selftests/powerpc: Remove redundant cp_abort test + * bionic/linux: completely remove snapdragon files from sources (LP: #1827880) + - [Packaging] remove snapdragon dead files + - [Config] update configs after snapdragon removal + * The noise keeps occurring when Headset is plugged in on a Dell machine + (LP: #1827972) + - ALSA: hda/realtek - Fixed Dell AIO speaker noise + * Geneve tunnels don't work when ipv6 is disabled (LP: #1794232) + - geneve: correctly handle ipv6.disable module parameter + * There are 4 HDMI/Displayport audio output listed in sound setting without + attach any HDMI/DP monitor (LP: #1827967) + - ALSA: hda/hdmi - Read the pin sense from register when repolling + - ALSA: hda/hdmi - Consider eld_valid when reporting jack event + * Headphone jack switch sense is inverted: plugging in headphones disables + headphone output (LP: #1824259) + - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board + * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error + Checking for all LINUX clients for devops4p10 (LP: #1766201) + - SAUCE: integrity: downgrade error to warning + * Screen freeze after resume from S3 when HDMI monitor plugged on Dell + Precision 7740 (LP: #1825958) + - PCI: Restore resized BAR state on resume + * potential memory corruption on arm64 on dev release (LP: #1827437) + - driver core: Postpone DMA tear-down until after devres release + * powerpc/pmu/ebb test in ubuntu_kernel_selftest failed with "error while + loading shared libraries" on Bionic/Cosmic PowerPC (LP: #1812805) + - selftests/powerpc/pmu: Link ebb tests with -no-pie + * unnecessary request_queue freeze (LP: #1815733) + - block: avoid setting nr_requests to current value + - block: avoid setting none scheduler if it's already none + * Kprobe event string type argument failed in ftrace from + ubuntu_kernel_selftests on B/C i386 (LP: #1825780) + - selftests/ftrace: Fix kprobe string testcase to not probe notrace function + * hns: fix socket accounting (LP: #1826911) + - net: hns: fix skb->truesize underestimation + * False positive test result in run_netsocktests from net in + ubuntu_kernel_selftest (LP: #1825777) + - selftests/net: correct the return value for run_netsocktests + + -- Kleber Sacilotto de Souza Mon, 20 May 2019 15:37:04 +0200 + +linux-oracle (4.15.0-1013.15) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-50.54 ] + + * CVE-2018-12126 // CVE-2018-12127 // CVE-2018-12130 + - Documentation/l1tf: Fix small spelling typo + - x86/cpu: Sanitize FAM6_ATOM naming + - kvm: x86: Report STIBP on GET_SUPPORTED_CPUID + - locking/atomics, asm-generic: Move some macros from to a + new file + - tools include: Adopt linux/bits.h + - x86/msr-index: Cleanup bit defines + - x86/speculation: Consolidate CPU whitelists + - x86/speculation/mds: Add basic bug infrastructure for MDS + - x86/speculation/mds: Add BUG_MSBDS_ONLY + - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests + - x86/speculation/mds: Add mds_clear_cpu_buffers() + - x86/speculation/mds: Clear CPU buffers on exit to user + - x86/kvm/vmx: Add MDS protection when L1D Flush is not active + - x86/speculation/mds: Conditionally clear CPU buffers on idle entry + - x86/speculation/mds: Add mitigation control for MDS + - x86/speculation/mds: Add sysfs reporting for MDS + - x86/speculation/mds: Add mitigation mode VMWERV + - Documentation: Move L1TF to separate directory + - Documentation: Add MDS vulnerability documentation + - x86/speculation/mds: Add mds=full,nosmt cmdline option + - x86/speculation: Move arch_smt_update() call to after mitigation decisions + - x86/speculation/mds: Add SMT warning message + - x86/speculation/mds: Fix comment + - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off + - x86/speculation/mds: Add 'mitigations=' support for MDS + * CVE-2017-5715 // CVE-2017-5753 + - s390/speculation: Support 'mitigations=' cmdline option + * CVE-2017-5715 // CVE-2017-5753 // CVE-2017-5754 // CVE-2018-3639 + - powerpc/speculation: Support 'mitigations=' cmdline option + * CVE-2017-5715 // CVE-2017-5754 // CVE-2018-3620 // CVE-2018-3639 // + CVE-2018-3646 + - cpu/speculation: Add 'mitigations=' cmdline option + - x86/speculation: Support 'mitigations=' cmdline option + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + -- Stefan Bader Wed, 08 May 2019 16:17:05 +0200 + +linux-oracle (4.15.0-1012.14) bionic; urgency=medium + + * linux-oracle: 4.15.0-1012.14 -proposed tracker (LP: #1826348) + + * linux-oracle: Use upstream approach to fix a race when hot adding a VF + (LP: #1825229) + - Revert "UBUNTU: SAUCE: net_failover: delay taking over primary device to + accommodate udevd renaming" + - ipvlan, l3mdev: fix broken l3s mode wrt local routes + - SAUCE: failover: allow name change on IFF_UP slave interfaces + + [ Ubuntu: 4.15.0-49.53 ] + + * linux: 4.15.0-49.53 -proposed tracker (LP: #1826358) + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) + - powerpc/64s: Add support for ori barrier_nospec patching + - powerpc/64s: Patch barrier_nospec in modules + - powerpc/64s: Enable barrier_nospec based on firmware settings + - powerpc: Use barrier_nospec in copy_from_user() + - powerpc/64: Use barrier_nospec in syscall entry + - powerpc/64s: Enhance the information in cpu_show_spectre_v1() + - powerpc/64: Disable the speculation barrier from the command line + - powerpc/64: Make stf barrier PPC_BOOK3S_64 specific. + - powerpc/64: Add CONFIG_PPC_BARRIER_NOSPEC + - powerpc/64: Call setup_barrier_nospec() from setup_arch() + - powerpc/64: Make meltdown reporting Book3S 64 specific + - powerpc/lib/code-patching: refactor patch_instruction() + - powerpc/lib/feature-fixups: use raw_patch_instruction() + - powerpc/asm: Add a patch_site macro & helpers for patching instructions + - powerpc/64s: Add new security feature flags for count cache flush + - powerpc/64s: Add support for software count cache flush + - powerpc/pseries: Query hypervisor for count cache flush settings + - powerpc/powernv: Query firmware for count cache flush settings + - powerpc/fsl: Add nospectre_v2 command line argument + - KVM: PPC: Book3S: Add count cache flush parameters to kvmppc_get_cpu_char() + - [Config] Add CONFIG_PPC_BARRIER_NOSPEC + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + * autopkgtests run too often, too much and don't skip enough (LP: #1823056) + - [Debian] Set +x on rebuild testcase. + - [Debian] Skip rebuild test, for regression-suite deps. + - [Debian] Make ubuntu-regression-suite skippable on unbootable kernels. + - [Debian] make rebuild use skippable error codes when skipping. + - [Debian] Only run regression-suite, if requested to. + * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868) + - [Packaging] remove arm64 snapdragon from getabis + - [Config] config changes for snapdragon split + - packaging: arm64: disable building the snapdragon flavour + - [Packaging] arm64: Drop snapdragon from kernel-versions + * CVE-2017-5753 + - KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq() + - media: dvb_ca_en50221: prevent using slot_info for Spectre attacs + - sysvipc/sem: mitigate semnum index against spectre v1 + - libahci: Fix possible Spectre-v1 pmp indexing in ahci_led_store() + - s390/keyboard: sanitize array index in do_kdsk_ioctl + - arm64: fix possible spectre-v1 write in ptrace_hbp_set_event() + - KVM: arm/arm64: vgic: Fix possible spectre-v1 write in vgic_mmio_write_apr() + - pktcdvd: Fix possible Spectre-v1 for pkt_devs + - net: socket: fix potential spectre v1 gadget in socketcall + - net: socket: Fix potential spectre v1 gadget in sock_is_registered + - drm/amdgpu/pm: Fix potential Spectre v1 + - netlink: Fix spectre v1 gadget in netlink_create() + - ext4: fix spectre gadget in ext4_mb_regular_allocator() + - drm/i915/kvmgt: Fix potential Spectre v1 + - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd() + - fs/quota: Fix spectre gadget in do_quotactl + - hwmon: (nct6775) Fix potential Spectre v1 + - mac80211_hwsim: Fix possible Spectre-v1 for hwsim_world_regdom_custom + - switchtec: Fix Spectre v1 vulnerability + - misc: hmc6352: fix potential Spectre v1 + - tty: vt_ioctl: fix potential Spectre v1 + - nl80211: Fix possible Spectre-v1 for NL80211_TXRATE_HT + - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds + - IB/ucm: Fix Spectre v1 vulnerability + - RDMA/ucma: Fix Spectre v1 vulnerability + - drm/bufs: Fix Spectre v1 vulnerability + - usb: gadget: storage: Fix Spectre v1 vulnerability + - ptp: fix Spectre v1 vulnerability + - HID: hiddev: fix potential Spectre v1 + - vhost: Fix Spectre V1 vulnerability + - drivers/misc/sgi-gru: fix Spectre v1 vulnerability + - ipv4: Fix potential Spectre v1 vulnerability + - aio: fix spectre gadget in lookup_ioctx + - ALSA: emux: Fix potential Spectre v1 vulnerabilities + - ALSA: pcm: Fix potential Spectre v1 vulnerability + - ip6mr: Fix potential Spectre v1 vulnerability + - ALSA: rme9652: Fix potential Spectre v1 vulnerability + - ALSA: emu10k1: Fix potential Spectre v1 vulnerabilities + - KVM: arm/arm64: vgic: Fix off-by-one bug in vgic_get_irq() + - drm/ioctl: Fix Spectre v1 vulnerabilities + - char/mwave: fix potential Spectre v1 vulnerability + - applicom: Fix potential Spectre v1 vulnerabilities + - ipmi: msghandler: Fix potential Spectre v1 vulnerabilities + - powerpc/ptrace: Mitigate potential Spectre v1 + - cfg80211: prevent speculation on cfg80211_classify8021d() return + - ALSA: rawmidi: Fix potential Spectre v1 vulnerability + - ALSA: seq: oss: Fix Spectre v1 vulnerability + * Bionic: Sync to Xenial (Spectre) (LP: #1822760) + - x86/speculation/l1tf: Suggest what to do on systems with too much RAM + - KVM: SVM: Add MSR-based feature support for serializing LFENCE + - KVM: VMX: fixes for vmentry_l1d_flush module parameter + - KVM: X86: Allow userspace to define the microcode version + - SAUCE: [Fix] x86/KVM/VMX: Add L1D flush logic + - SAUCE: [Fix] x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on + vmentry + * [SRU] [B/OEM] Fix ACPI bug that causes boot failure (LP: #1819921) + - SAUCE: ACPI / bus: Add some Lenovo laptops in list of acpi table term list + * Bionic update: upstream stable patchset for fuse 2019-04-12 (LP: #1824553) + - fuse: fix double request_end() + - fuse: fix unlocked access to processing queue + - fuse: umount should wait for all requests + - fuse: Fix oops at process_init_reply() + - fuse: Don't access pipe->buffers without pipe_lock() + - fuse: Fix use-after-free in fuse_dev_do_read() + - fuse: Fix use-after-free in fuse_dev_do_write() + - fuse: set FR_SENT while locked + - fuse: fix blocked_waitq wakeup + - fuse: fix leaked notify reply + - fuse: fix possibly missed wake-up after abort + - fuse: fix use-after-free in fuse_direct_IO() + - fuse: continue to send FUSE_RELEASEDIR when FUSE_OPEN returns ENOSYS + - fuse: handle zero sized retrieve correctly + - fuse: call pipe_buf_release() under pipe lock + - fuse: decrement NR_WRITEBACK_TEMP on the right page + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // Backport support for software + count cache flush Spectre v2 mitigation. (CVE) (required for POWER9 DD2.3) + (LP: #1822870) + - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2 + - powerpc/fsl: Fix spectre_v2 mitigations reporting + - powerpc: Avoid code patching freed init sections + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // Backport support for software + count cache flush Spectre v2 mitigation. (CVE) (required for POWER9 DD2.3) + (LP: #1822870) // Backport support for software count cache flush Spectre v2 + mitigation. (CVE) (required for POWER9 DD2.3) (LP: #1822870) + - powerpc/security: Fix spectre_v2 reporting + * CVE-2019-3874 + - sctp: use sk_wmem_queued to check for writable space + - sctp: implement memory accounting on tx path + - sctp: implement memory accounting on rx path + * NULL pointer dereference when using z3fold and zswap (LP: #1814874) + - z3fold: fix possible reclaim races + * Kprobe event argument syntax in ftrace from ubuntu_kernel_selftests failed + on B PowerPC (LP: #1812809) + - selftests/ftrace: Add ppc support for kprobe args tests + * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487) + - misc: rtsx: make various functions static + - misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260 + - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch + * headset-mic doesn't work on two Dell laptops. (LP: #1825272) + - ALSA: hda/realtek - add two more pin configuration sets to quirk table + * CVE-2018-16884 + - sunrpc: use SVC_NET() in svcauth_gss_* functions + - sunrpc: use-after-free in svc_process_common() + * sky2 ethernet card don't work after returning from suspension (LP: #1798921) + - sky2: Increase D3 delay again + * CVE-2019-9500 + - brcmfmac: assure SSID length from firmware is limited + * CVE-2019-9503 + - brcmfmac: add subtype check for event handling in data path + * CVE-2019-3882 + - vfio/type1: Limit DMA mappings per container + * Intel I210 Ethernet card not working after hotplug [8086:1533] + (LP: #1818490) + - igb: Fix WARN_ONCE on runtime suspend + * bionic, xenial/hwe: misses "fuse: fix initial parallel dirops" patch + (LP: #1823972) + - fuse: fix initial parallel dirops + * amdgpu resume failure: failed to allocate wb slot (LP: #1825074) + - drm/amdgpu: fix&cleanups for wb_clear + * Pop noise when headset is plugged in or removed from GHS/Line-out jack + (LP: #1821290) + - ALSA: hda/realtek - Add unplug function into unplug state of Headset Mode + for ALC225 + - ALSA: hda/realtek - Disable headset Mic VREF for headset mode of ALC225 + - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO + - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB + * mac80211_hwsim unable to handle kernel NULL pointer dereference + at0000000000000000 (LP: #1825058) + - mac80211_hwsim: Timer should be initialized before device registered + * [regression][snd_hda_codec_realtek] repeating crackling noise after 19.04 + upgrade (LP: #1821663) + - ALSA: hda: Add Intel NUC7i3BNB to the power_save blacklist + - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist + - ALSA: hda - Add two more machines to the power_save_blacklist + * ubuntu_nbd_smoke_test failed on P9 with Bionic kernel (LP: #1822247) + - nbd: fix how we set bd_invalidated + * TSC clocksource not available in nested guests (LP: #1822821) + - kvmclock: fix TSC calibration for nested guests + * 4.15 kernel ip_vs --ops causes performance and hang problem (LP: #1819786) + - ipvs: fix refcount usage for conns in ops mode + * systemd cause kernel trace "BUG: unable to handle kernel paging request at + 6db23a14" on Cosmic i386 (LP: #1813244) // systemd cause kernel trace "BUG: + unable to handle kernel paging request at 6db23a14" on Cosmic i386 + (LP: #1813244) + - openvswitch: fix flow actions reallocation + + -- Khalid Elmously Fri, 26 Apr 2019 02:39:11 -0400 + +linux-oracle (4.15.0-1011.13) bionic; urgency=medium + + * linux-oracle: 4.15.0-1011.13 -proposed tracker (LP: #1822812) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + [ Ubuntu: 4.15.0-48.51 ] + + * linux: 4.15.0-48.51 -proposed tracker (LP: #1822820) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] resync retpoline extraction + * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes + triggers system hang on i386 (LP: #1812845) + - btrfs: raid56: properly unmap parity page in finish_parity_scrub() + * [P9][LTCTest][Opal][FW910] cpupower monitor shows multiple stop Idle_Stats + (LP: #1719545) + - cpupower : Fix header name to read idle state name + * [amdgpu] screen corruption when using touchpad (LP: #1818617) + - drm/amdgpu/gmc: steal the appropriate amount of vram for fw hand-over (v3) + - drm/amdgpu: Free VGA stolen memory as soon as possible. + * [SRU][B/C/OEM]IOMMU: add kernel dma protection (LP: #1820153) + - ACPICA: AML parser: attempt to continue loading table after error + - ACPI / property: Allow multiple property compatible _DSD entries + - PCI / ACPI: Identify untrusted PCI devices + - iommu/vt-d: Force IOMMU on for platform opt in hint + - iommu/vt-d: Do not enable ATS for untrusted devices + - thunderbolt: Export IOMMU based DMA protection support to userspace + - iommu/vt-d: Disable ATS support on untrusted devices + * Add basic support to NVLink2 passthrough (LP: #1819989) + - powerpc/powernv/npu: Do not try invalidating 32bit table when 64bit table is + enabled + - powerpc/powernv: call OPAL_QUIESCE before OPAL_SIGNAL_SYSTEM_RESET + - powerpc/powernv: Export opal_check_token symbol + - powerpc/powernv: Make possible for user to force a full ipl cec reboot + - powerpc/powernv/idoa: Remove unnecessary pcidev from pci_dn + - powerpc/powernv: Move npu struct from pnv_phb to pci_controller + - powerpc/powernv/npu: Move OPAL calls away from context manipulation + - powerpc/pseries/iommu: Use memory@ nodes in max RAM address calculation + - powerpc/pseries/npu: Enable platform support + - powerpc/pseries: Remove IOMMU API support for non-LPAR systems + - powerpc/powernv/npu: Check mmio_atsd array bounds when populating + - powerpc/powernv/npu: Fault user page into the hypervisor's pagetable + * Huawei Hi1822 NIC has poor performance (LP: #1820187) + - net-next: hinic: fix a problem in free_tx_poll() + - hinic: remove ndo_poll_controller + - net-next/hinic: add checksum offload and TSO support + - hinic: Fix l4_type parameter in hinic_task_set_tunnel_l4 + - net-next/hinic:replace multiply and division operators + - net-next/hinic:add rx checksum offload for HiNIC + - net-next/hinic:fix a bug in set mac address + - net-next/hinic: fix a bug in rx data flow + - net: hinic: fix null pointer dereference on pointer hwdev + - hinic: optmize rx refill buffer mechanism + - net-next/hinic:add shutdown callback + - net-next/hinic: replace disable_irq_nosync/enable_irq + * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881) + - Fonts: New Terminus large console font + - [Config]: enable highdpi Terminus 16x32 font support + * [19.04 FEAT] qeth: Enhanced link speed - kernel part (LP: #1814892) + - s390/qeth: report 25Gbit link speed + * CVE-2017-5754 + - x86/nmi: Fix NMI uaccess race against CR3 switching + - x86/mm: Fix documentation of module mapping range with 4-level paging + - x86/pti: Enable global pages for shared areas + - x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image + - x86/pti: Leave kernel text global for !PCID + - x86/pti: Fix boot problems from Global-bit setting + - x86/pti: Fix boot warning from Global-bit setting + - x86/pti: Reduce amount of kernel text allowed to be Global + - x86/pti: Disallow global kernel text with RANDSTRUCT + - x86/entry/32: Add explicit 'l' instruction suffix + - x86/asm-offsets: Move TSS_sp0 and TSS_sp1 to asm-offsets.c + - x86/entry/32: Rename TSS_sysenter_sp0 to TSS_entry2task_stack + - x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler + - x86/entry/32: Put ESPFIX code into a macro + - x86/entry/32: Unshare NMI return path + - x86/entry/32: Split off return-to-kernel path + - x86/entry/32: Enter the kernel via trampoline stack + - x86/entry/32: Leave the kernel via trampoline stack + - x86/entry/32: Introduce SAVE_ALL_NMI and RESTORE_ALL_NMI + - x86/entry/32: Handle Entry from Kernel-Mode on Entry-Stack + - x86/entry/32: Simplify debug entry point + - x86/entry/32: Add PTI cr3 switch to non-NMI entry/exit points + - x86/entry/32: Add PTI CR3 switches to NMI handler code + - x86/entry: Rename update_sp0 to update_task_stack + - x86/pgtable: Rename pti_set_user_pgd() to pti_set_user_pgtbl() + - x86/pgtable/pae: Unshare kernel PMDs when PTI is enabled + - x86/pgtable/32: Allocate 8k page-tables when PTI is enabled + - x86/pgtable: Move pgdp kernel/user conversion functions to pgtable.h + - x86/pgtable: Move pti_set_user_pgtbl() to pgtable.h + - x86/pgtable: Move two more functions from pgtable_64.h to pgtable.h + - x86/mm/pae: Populate valid user PGD entries + - x86/mm/pae: Populate the user page-table with user pgd's + - x86/mm/pti: Add an overflow check to pti_clone_pmds() + - x86/mm/pti: Define X86_CR3_PTI_PCID_USER_BIT on x86_32 + - x86/mm/pti: Clone CPU_ENTRY_AREA on PMD level on x86_32 + - x86/mm/pti: Make pti_clone_kernel_text() compile on 32 bit + - x86/mm/pti: Keep permissions when cloning kernel text in + pti_clone_kernel_text() + - x86/mm/pti: Introduce pti_finalize() + - x86/mm/pti: Clone entry-text again in pti_finalize() + - x86/mm/dump_pagetables: Define INIT_PGD + - x86/pgtable/pae: Use separate kernel PMDs for user page-table + - x86/ldt: Reserve address-space range on 32 bit for the LDT + - x86/ldt: Define LDT_END_ADDR + - x86/ldt: Split out sanity check in map_ldt_struct() + - x86/ldt: Enable LDT user-mapping for PAE + - x86/pti: Allow CONFIG_PAGE_TABLE_ISOLATION for x86_32 + - [Config] Update PAGE_TABLE_ISOLATION annotations + - x86/mm/pti: Add Warning when booting on a PCID capable CPU + - x86/entry/32: Add debug code to check entry/exit CR3 + - x86/pti: Check the return value of pti_user_pagetable_walk_p4d() + - x86/pti: Check the return value of pti_user_pagetable_walk_pmd() + - perf/core: Make sure the ring-buffer is mapped in all page-tables + - x86/entry/32: Check for VM86 mode in slow-path check + - x86/mm: Remove in_nmi() warning from vmalloc_fault() + - x86/kexec: Allocate 8k PGDs for PTI + - x86/mm/pti: Clear Global bit more aggressively + - mm: Allow non-direct-map arguments to free_reserved_area() + - x86/mm/init: Pass unconverted symbol addresses to free_init_pages() + - x86/mm/init: Add helper for freeing kernel image pages + - x86/mm/init: Remove freed kernel image areas from alias mapping + - x86/mm/pti: Fix 32 bit PCID check + - x86/mm/pti: Don't clear permissions in pti_clone_pmd() + - x86/mm/pti: Clone kernel-image on PTE level for 32 bit + - x86/relocs: Add __end_rodata_aligned to S_REL + - x86/mm/pti: Move user W+X check into pti_finalize() + - x86/efi: Load fixmap GDT in efi_call_phys_epilog() + - x86/efi: Load fixmap GDT in efi_call_phys_epilog() before setting %cr3 + - x86/mm/doc: Clean up the x86-64 virtual memory layout descriptions + - x86/mm/doc: Enhance the x86-64 virtual memory layout descriptions + - x86/entry/32: Clear the CS high bits + - x86/mm: Move LDT remap out of KASLR region on 5-level paging + - x86/ldt: Unmap PTEs for the slot before freeing LDT pages + - x86/ldt: Remove unused variable in map_ldt_struct() + - x86/mm: Fix guard hole handling + - x86/dump_pagetables: Fix LDT remap address marker + * Avoid potential memory corruption on HiSilicon SoCs (LP: #1819546) + - iommu/arm-smmu-v3: Avoid memory corruption from Hisilicon MSI payloads + * Ubuntu18.04.01: [Power9] power8 Compat guest(RHEL7.6) crashes during guest + boot with > 256G of memory (kernel/kvm) (LP: #1818645) + - ]PATCH] KVM: PPC: Book3S HV: Don't truncate HPTE index in xlate function + * Fix for dual Intel NVMes (LP: #1821961) + - SAUCE: nvme: Merge two quirk entries into one for Intel 760p/Pro 7600p + * CVE-2017-5715 + - tools headers: Synchronize prctl.h ABI header + - x86/spectre: Add missing family 6 check to microcode check + - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation + - x86/speculation: Apply IBPB more strictly to avoid cross-process data leak + - x86/speculation: Propagate information about RSB filling mitigation to sysfs + - x86/speculation: Add RETPOLINE_AMD support to the inline asm CALL_NOSPEC + variant + - x86/retpoline: Make CONFIG_RETPOLINE depend on compiler support + - x86/retpoline: Remove minimal retpoline support + - x86/speculation: Update the TIF_SSBD comment + - x86/speculation: Clean up spectre_v2_parse_cmdline() + - x86/speculation: Remove unnecessary ret variable in cpu_show_common() + - x86/speculation: Move STIPB/IBPB string conditionals out of + cpu_show_common() + - x86/speculation: Disable STIBP when enhanced IBRS is in use + - x86/speculation: Rename SSBD update functions + - x86/speculation: Reorganize speculation control MSRs update + - sched/smt: Make sched_smt_present track topology + - x86/Kconfig: Select SCHED_SMT if SMP enabled + - sched/smt: Expose sched_smt_present static key + - x86/speculation: Rework SMT state change + - x86/l1tf: Show actual SMT state + - x86/speculation: Reorder the spec_v2 code + - x86/speculation: Mark string arrays const correctly + - x86/speculataion: Mark command line parser data __initdata + - x86/speculation: Unify conditional spectre v2 print functions + - x86/speculation: Add command line control for indirect branch speculation + - x86/speculation: Prepare for per task indirect branch speculation control + - x86/process: Consolidate and simplify switch_to_xtra() code + - x86/speculation: Avoid __switch_to_xtra() calls + - x86/speculation: Prepare for conditional IBPB in switch_mm() + - ptrace: Remove unused ptrace_may_access_sched() and MODE_IBRS + - x86/speculation: Split out TIF update + - x86/speculation: Prevent stale SPEC_CTRL msr content + - x86/speculation: Prepare arch_smt_update() for PRCTL mode + - x86/speculation: Add prctl() control for indirect branch speculation + - x86/speculation: Enable prctl mode for spectre_v2_user + - x86/speculation: Add seccomp Spectre v2 user space protection mode + - x86/speculation: Provide IBPB always command line options + - kvm: svm: Ensure an IBPB on all affected CPUs when freeing a vmcb + - x86/speculation: Change misspelled STIPB to STIBP + - x86/speculation: Add support for STIBP always-on preferred mode + - x86, modpost: Replace last remnants of RETPOLINE with CONFIG_RETPOLINE + - s390: remove closung punctuation from spectre messages + - x86/speculation: Simplify the CPU bug detection logic + * CVE-2018-3639 + - x86/bugs: Add AMD's variant of SSB_NO + - x86/bugs: Add AMD's SPEC_CTRL MSR usage + - x86/bugs: Switch the selection of mitigation from CPU vendor to CPU features + - x86/bugs: Update when to check for the LS_CFG SSBD mitigation + - x86/bugs: Fix the AMD SSBD usage of the SPEC_CTRL MSR + - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled + * [Ubuntu] vfio-ap: add subsystem to matrix device to avoid libudev failures + (LP: #1818854) + - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem + * Kernel regularly logs: Bluetooth: hci0: last event is not cmd complete + (0x0f) (LP: #1748565) + - Bluetooth: Fix unnecessary error message for HCI request completion + * HiSilicon HNS ethernet broken in 4.15.0-45 (LP: #1818294) + - net: hns: Fix WARNING when hns modules installed + * rtl8723be wifi does not work under linux-modules-extra-4.15.0-33-generic + (LP: #1788997) + - SAUCE: Revert "rtlwifi: cleanup 8723be ant_sel definition" + * Crash from :i915 module with 4.15.0-46-generic using multi-display + (LP: #1819486) + - SAUCE: Revert "drm/i915: Fix hotplug irq ack on i965/g4x" + * kernel linux-image-4.15.0-44 not booting on Hyperv Server 2008R2 + (LP: #1814069) + - hv/netvsc: fix handling of fallback to single queue mode + - hv/netvsc: Fix NULL dereference at single queue mode fallback + * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815) + - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill + * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204) + - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list + * fscache: jobs might hang when fscache disk is full (LP: #1821395) + - fscache: fix race between enablement and dropping of object + * hns3: fix oops in hns3_clean_rx_ring() (LP: #1821064) + - net: hns3: add dma_rmb() for rx description + * Hard lockup in 2 CPUs due to deadlock in cpu_stoppers (LP: #1821259) + - stop_machine: Disable preemption after queueing stopper threads + - stop_machine: Atomically queue and wake stopper threads + * tcm_loop.ko: move from modules-extra into main modules package + (LP: #1817786) + - [Packaging] move tcm_loop.lo to main linux-modules package + * tcmu user space crash results in kernel module hang. (LP: #1819504) + - scsi: tcmu: delete unused __wait + - scsi: tcmu: track nl commands + - scsi: tcmu: simplify nl interface + - scsi: tcmu: add module wide block/reset_netlink support + * Intel XL710 - i40e driver does not work with kernel 4.15 (Ubuntu 18.04) + (LP: #1779756) + - i40e: Fix for Tx timeouts when interface is brought up if DCB is enabled + - i40e: prevent overlapping tx_timeout recover + * some codecs stop working after S3 (LP: #1820930) + - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec + * i40e xps management broken when > 64 queues/cpus (LP: #1820948) + - i40e: Do not allow use more TC queue pairs than MSI-X vectors exist + - i40e: Fix the number of queues available to be mapped for use + * 4.15 s390x kernel BUG at /build/linux- + Gycr4Z/linux-4.15.0/drivers/block/virtio_blk.c:565! (LP: #1788432) + - virtio/s390: avoid race on vcdev->config + - virtio/s390: fix race in ccw_io_helper() + * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990) + - iommu/amd: Fix NULL dereference bug in match_hid_uid + * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu + system (LP: #1821271) + - iwlwifi: add new card for 9260 series + * Add support for MAC address pass through on RTL8153-BD (LP: #1821276) + - r8152: Add support for MAC address pass through on RTL8153-BD + - r8152: Fix an error on RTL8153-BD MAC Address Passthrough support + + -- Andrea Righi Thu, 04 Apr 2019 09:58:48 +0200 + +linux-oracle (4.15.0-1010.12) bionic; urgency=medium + + * linux-oracle: 4.15.0-1010.12 -proposed tracker (LP: #1819704) + + * hot add VF to net_failover - could not rename interface '8' from 'eth0' to + 'ens4': Device or resource busy (LP: #1815268) + - SAUCE: net_failover: delay taking over primary device to accommodate udevd + renaming + + [ Ubuntu: 4.15.0-47.50 ] + + * linux: 4.15.0-47.50 -proposed tracker (LP: #1819716) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + - [Packaging] resync retpoline extraction + * C++ demangling support missing from perf (LP: #1396654) + - [Packaging] fix a mistype + * arm-smmu-v3 arm-smmu-v3.3.auto: CMD_SYNC timeout (LP: #1818162) + - iommu/arm-smmu-v3: Fix unexpected CMD_SYNC timeout + * Crash in nvme_irq_check() when using threaded interrupts (LP: #1818747) + - nvme-pci: fix out of bounds access in nvme_cqe_pending + * CVE-2019-9213 + - mm: enforce min addr even if capable() in expand_downwards() + * CVE-2019-3460 + - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt + * amdgpu with mst WARNING on blanking (LP: #1814308) + - drm/amd/display: Don't use dc_link in link_encoder + - drm/amd/display: Move wait for hpd ready out from edp power control. + - drm/amd/display: eDP sequence BL off first then DP blank. + - drm/amd/display: Fix unused variable compilation error + - drm/amd/display: Fix warning about misaligned code + - drm/amd/display: Fix MST dp_blank REG_WAIT timeout + * tun/tap: unable to manage carrier state from userland (LP: #1806392) + - tun: implement carrier change + * CVE-2019-8980 + - exec: Fix mem leak in kernel_read_file + * raw_skew in timer from the ubuntu_kernel_selftests failed on Bionic + (LP: #1811194) + - selftest: timers: Tweak raw_skew to SKIP when ADJ_OFFSET/other clock + adjustments are in progress + * [Packaging] Allow overlay of config annotations (LP: #1752072) + - [Packaging] config-check: Add an include directive + * CVE-2019-7308 + - bpf: move {prev_,}insn_idx into verifier env + - bpf: move tmp variable into ax register in interpreter + - bpf: enable access to ax register also from verifier rewrite + - bpf: restrict map value pointer arithmetic for unprivileged + - bpf: restrict stack pointer arithmetic for unprivileged + - bpf: restrict unknown scalars of mixed signed bounds for unprivileged + - bpf: fix check_map_access smin_value test when pointer contains offset + - bpf: prevent out of bounds speculation on pointer arithmetic + - bpf: fix sanitation of alu op with pointer / scalar type from different + paths + - bpf: add various test cases to selftests + * CVE-2017-5753 + - bpf: properly enforce index mask to prevent out-of-bounds speculation + - bpf: fix inner map masking to prevent oob under speculation + * BPF: kernel pointer leak to unprivileged userspace (LP: #1815259) + - bpf/verifier: disallow pointer subtraction + * squashfs hardening (LP: #1816756) + - squashfs: more metadata hardening + - squashfs metadata 2: electric boogaloo + - squashfs: more metadata hardening + - Squashfs: Compute expected length from inode size rather than block length + * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982) + - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted + * Update ENA driver to version 2.0.3K (LP: #1816806) + - net: ena: update driver version from 2.0.2 to 2.0.3 + - net: ena: fix race between link up and device initalization + - net: ena: fix crash during failed resume from hibernation + * ipset kernel error: 4.15.0-43-generic (LP: #1811394) + - netfilter: ipset: Fix wraparound in hash:*net* types + * Silent "Unknown key" message when pressing keyboard backlight hotkey + (LP: #1817063) + - platform/x86: dell-wmi: Ignore new keyboard backlight change event + * CVE-2018-18021 + - arm64: KVM: Tighten guest core register access from userspace + - KVM: arm/arm64: Introduce vcpu_el1_is_32bit + - arm64: KVM: Sanitize PSTATE.M when being set from userspace + * CVE-2018-14678 + - x86/entry/64: Remove %ebx handling from error_entry/exit + * CVE-2018-19824 + - ALSA: usb-audio: Fix UAF decrement if card has no live interfaces in card.c + * CVE-2019-3459 + - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer + * Bionic update: upstream stable patchset 2019-02-08 (LP: #1815234) + - fork: unconditionally clear stack on fork + - spi: spi-s3c64xx: Fix system resume support + - Input: elan_i2c - add ACPI ID for lenovo ideapad 330 + - Input: i8042 - add Lenovo LaVie Z to the i8042 reset list + - Input: elan_i2c - add another ACPI ID for Lenovo Ideapad 330-15AST + - kvm, mm: account shadow page tables to kmemcg + - delayacct: fix crash in delayacct_blkio_end() after delayacct init failure + - tracing: Fix double free of event_trigger_data + - tracing: Fix possible double free in event_enable_trigger_func() + - kthread, tracing: Don't expose half-written comm when creating kthreads + - tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure + - tracing: Quiet gcc warning about maybe unused link variable + - arm64: fix vmemmap BUILD_BUG_ON() triggering on !vmemmap setups + - mlxsw: spectrum_switchdev: Fix port_vlan refcounting + - kcov: ensure irq code sees a valid area + - xen/netfront: raise max number of slots in xennet_get_responses() + - skip LAYOUTRETURN if layout is invalid + - ALSA: emu10k1: add error handling for snd_ctl_add + - ALSA: fm801: add error handling for snd_ctl_add + - NFSv4.1: Fix the client behaviour on NFS4ERR_SEQ_FALSE_RETRY + - nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo + - vfio: platform: Fix reset module leak in error path + - vfio/mdev: Check globally for duplicate devices + - vfio/type1: Fix task tracking for QEMU vCPU hotplug + - kernel/hung_task.c: show all hung tasks before panic + - mm: /proc/pid/pagemap: hide swap entries from unprivileged users + - mm: vmalloc: avoid racy handling of debugobjects in vunmap + - mm/slub.c: add __printf verification to slab_err() + - rtc: ensure rtc_set_alarm fails when alarms are not supported + - perf tools: Fix pmu events parsing rule + - netfilter: ipset: forbid family for hash:mac sets + - netfilter: ipset: List timing out entries with "timeout 1" instead of zero + - irqchip/ls-scfg-msi: Map MSIs in the iommu + - watchdog: da9063: Fix updating timeout value + - printk: drop in_nmi check from printk_safe_flush_on_panic() + - bpf, arm32: fix inconsistent naming about emit_a32_lsr_{r64,i64} + - ceph: fix alignment of rasize + - e1000e: Ignore TSYNCRXCTL when getting I219 clock attributes + - powerpc/lib: Adjust .balign inside string functions for PPC32 + - powerpc/64s: Add barrier_nospec + - powerpc/eeh: Fix use-after-release of EEH driver + - hvc_opal: don't set tb_ticks_per_usec in udbg_init_opal_common() + - powerpc/64s: Fix compiler store ordering to SLB shadow area + - RDMA/mad: Convert BUG_ONs to error flows + - lightnvm: pblk: warn in case of corrupted write buffer + - netfilter: nf_tables: check msg_type before nft_trans_set(trans) + - pnfs: Don't release the sequence slot until we've processed layoutget on + open + - disable loading f2fs module on PAGE_SIZE > 4KB + - f2fs: fix error path of move_data_page + - f2fs: fix to don't trigger writeback during recovery + - f2fs: fix to wait page writeback during revoking atomic write + - f2fs: Fix deadlock in shutdown ioctl + - f2fs: fix to detect failure of dquot_initialize + - f2fs: fix race in between GC and atomic open + - block, bfq: remove wrong lock in bfq_requests_merged + - usbip: usbip_detach: Fix memory, udev context and udev leak + - usbip: dynamically allocate idev by nports found in sysfs + - perf/x86/intel/uncore: Correct fixed counter index check in generic code + - perf/x86/intel/uncore: Correct fixed counter index check for NHM + - selftests/intel_pstate: Improve test, minor fixes + - selftests: memfd: return Kselftest Skip code for skipped tests + - selftests: intel_pstate: return Kselftest Skip code for skipped tests + - PCI: Fix devm_pci_alloc_host_bridge() memory leak + - iwlwifi: pcie: fix race in Rx buffer allocator + - Bluetooth: hci_qca: Fix "Sleep inside atomic section" warning + - Bluetooth: btusb: Add a new Realtek 8723DE ID 2ff8:b011 + - ASoC: dpcm: fix BE dai not hw_free and shutdown + - mfd: cros_ec: Fail early if we cannot identify the EC + - mwifiex: handle race during mwifiex_usb_disconnect + - wlcore: sdio: check for valid platform device data before suspend + - media: tw686x: Fix incorrect vb2_mem_ops GFP flags + - media: videobuf2-core: don't call memop 'finish' when queueing + - Btrfs: don't return ino to ino cache if inode item removal fails + - Btrfs: don't BUG_ON() in btrfs_truncate_inode_items() + - btrfs: add barriers to btrfs_sync_log before log_commit_wait wakeups + - btrfs: qgroup: Finish rescan when hit the last leaf of extent tree + - x86/microcode: Make the late update update_lock a raw lock for RT + - PM / wakeup: Make s2idle_lock a RAW_SPINLOCK + - PCI: Prevent sysfs disable of device while driver is attached + - nvme-rdma: stop admin queue before freeing it + - nvme-pci: Fix AER reset handling + - ath: Add regulatory mapping for FCC3_ETSIC + - ath: Add regulatory mapping for ETSI8_WORLD + - ath: Add regulatory mapping for APL13_WORLD + - ath: Add regulatory mapping for APL2_FCCA + - ath: Add regulatory mapping for Uganda + - ath: Add regulatory mapping for Tanzania + - ath: Add regulatory mapping for Serbia + - ath: Add regulatory mapping for Bermuda + - ath: Add regulatory mapping for Bahamas + - powerpc/32: Add a missing include header + - powerpc/chrp/time: Make some functions static, add missing header include + - powerpc/powermac: Add missing prototype for note_bootable_part() + - powerpc/powermac: Mark variable x as unused + - powerpc: Add __printf verification to prom_printf + - spi: sh-msiof: Fix setting SIRMDR1.SYNCAC to match SITMDR1.SYNCAC + - powerpc/8xx: fix invalid register expression in head_8xx.S + - pinctrl: at91-pio4: add missing of_node_put + - bpf: powerpc64: pad function address loads with NOPs + - PCI: pciehp: Request control of native hotplug only if supported + - net: dsa: qca8k: Add support for QCA8334 switch + - mwifiex: correct histogram data with appropriate index + - ima: based on policy verify firmware signatures (pre-allocated buffer) + - drivers/perf: arm-ccn: don't log to dmesg in event_init + - spi: Add missing pm_runtime_put_noidle() after failed get + - fscrypt: use unbound workqueue for decryption + - scsi: ufs: ufshcd: fix possible unclocked register access + - scsi: ufs: fix exception event handling + - scsi: zfcp: assert that the ERP lock is held when tracing a recovery trigger + - drm/nouveau/fifo/gk104-: poll for runlist update completion + - Bluetooth: btusb: add ID for LiteOn 04ca:301a + - rtc: tps6586x: fix possible race condition + - rtc: vr41xx: fix possible race condition + - rtc: tps65910: fix possible race condition + - ALSA: emu10k1: Rate-limit error messages about page errors + - regulator: pfuze100: add .is_enable() for pfuze100_swb_regulator_ops + - md/raid1: add error handling of read error from FailFast device + - md: fix NULL dereference of mddev->pers in remove_and_add_spares() + - ixgbevf: fix MAC address changes through ixgbevf_set_mac() + - media: smiapp: fix timeout checking in smiapp_read_nvm + - net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value + - ALSA: usb-audio: Apply rate limit to warning messages in URB complete + callback + - media: atomisp: ov2680: don't declare unused vars + - arm64: cmpwait: Clear event register before arming exclusive monitor + - HID: hid-plantronics: Re-resend Update to map button for PTT products + - arm64: dts: renesas: salvator-common: use audio-graph-card for Sound + - drm/radeon: fix mode_valid's return type + - drm/amdgpu: Remove VRAM from shared bo domains. + - powerpc/embedded6xx/hlwd-pic: Prevent interrupts from being handled by + Starlet + - HID: i2c-hid: check if device is there before really probing + - EDAC, altera: Fix ARM64 build warning + - ARM: dts: stih407-pinctrl: Fix complain about IRQ_TYPE_NONE usage + - ARM: dts: emev2: Add missing interrupt-affinity to PMU node + - ARM: dts: sh73a0: Add missing interrupt-affinity to PMU node + - nvmem: properly handle returned value nvmem_reg_read + - i40e: free the skb after clearing the bitlock + - tty: Fix data race in tty_insert_flip_string_fixed_flag + - dma-iommu: Fix compilation when !CONFIG_IOMMU_DMA + - net: phy: phylink: Release link GPIO + - media: rcar_jpu: Add missing clk_disable_unprepare() on error in jpu_open() + - libata: Fix command retry decision + - ACPI / LPSS: Only call pwm_add_table() for Bay Trail PWM if PMIC HRV is 2 + - media: media-device: fix ioctl function types + - media: saa7164: Fix driver name in debug output + - mtd: rawnand: fsl_ifc: fix FSL NAND driver to read all ONFI parameter pages + - brcmfmac: Add support for bcm43364 wireless chipset + - s390/cpum_sf: Add data entry sizes to sampling trailer entry + - perf: fix invalid bit in diagnostic entry + - bnxt_en: Check unsupported speeds in bnxt_update_link() on PF only. + - scsi: 3w-9xxx: fix a missing-check bug + - scsi: 3w-xxxx: fix a missing-check bug + - scsi: megaraid: silence a static checker bug + - scsi: qedf: Set the UNLOADING flag when removing a vport + - staging: lustre: o2iblnd: fix race at kiblnd_connect_peer + - staging: lustre: o2iblnd: Fix FastReg map/unmap for MLX5 + - thermal: exynos: fix setting rising_threshold for Exynos5433 + - bpf: fix references to free_bpf_prog_info() in comments + - f2fs: avoid fsync() failure caused by EAGAIN in writepage() + - media: siano: get rid of __le32/__le16 cast warnings + - drm/atomic: Handling the case when setting old crtc for plane + - ALSA: hda/ca0132: fix build failure when a local macro is defined + - mmc: dw_mmc: update actual clock for mmc debugfs + - mmc: pwrseq: Use kmalloc_array instead of stack VLA + - dt-bindings: pinctrl: meson: add support for the Meson8m2 SoC + - spi: meson-spicc: Fix error handling in meson_spicc_probe() + - dt-bindings: net: meson-dwmac: new compatible name for AXG SoC + - backlight: pwm_bl: Don't use GPIOF_* with gpiod_get_direction + - stop_machine: Use raw spinlocks + - delayacct: Use raw_spinlocks + - memory: tegra: Do not handle spurious interrupts + - memory: tegra: Apply interrupts mask per SoC + - nvme: lightnvm: add granby support + - arm64: defconfig: Enable Rockchip io-domain driver + - igb: Fix queue selection on MAC filters on i210 + - drm/gma500: fix psb_intel_lvds_mode_valid()'s return type + - ipconfig: Correctly initialise ic_nameservers + - rsi: Fix 'invalid vdd' warning in mmc + - rsi: fix nommu_map_sg overflow kernel panic + - audit: allow not equal op for audit by executable + - staging: vchiq_core: Fix missing semaphore release in error case + - staging: lustre: llite: correct removexattr detection + - staging: lustre: ldlm: free resource when ldlm_lock_create() fails. + - serial: core: Make sure compiler barfs for 16-byte earlycon names + - soc: imx: gpcv2: Do not pass static memory as platform data + - microblaze: Fix simpleImage format generation + - usb: hub: Don't wait for connect state at resume for powered-off ports + - crypto: authencesn - don't leak pointers to authenc keys + - crypto: authenc - don't leak pointers to authenc keys + - media: omap3isp: fix unbalanced dma_iommu_mapping + - regulator: Don't return or expect -errno from of_map_mode() + - scsi: scsi_dh: replace too broad "TP9" string with the exact models + - scsi: megaraid_sas: Increase timeout by 1 sec for non-RAID fastpath IOs + - media: atomisp: compat32: fix __user annotations + - media: si470x: fix __be16 annotations + - ASoC: topology: Fix bclk and fsync inversion in set_link_hw_format() + - ASoC: topology: Add missing clock gating parameter when parsing hw_configs + - drm: Add DP PSR2 sink enable bit + - drm/atomic-helper: Drop plane->fb references only for + drm_atomic_helper_shutdown() + - drm/dp/mst: Fix off-by-one typo when dump payload table + - block: reset bi_iter.bi_done after splitting bio + - random: mix rdrand with entropy sent in from userspace + - squashfs: be more careful about metadata corruption + - ext4: fix inline data updates with checksums enabled + - ext4: fix check to prevent initializing reserved inodes + - PCI: xgene: Remove leftover pci_scan_child_bus() call + - RDMA/uverbs: Protect from attempts to create flows on unsupported QP + - net: dsa: qca8k: Force CPU port to its highest bandwidth + - net: dsa: qca8k: Enable RXMAC when bringing up a port + - net: dsa: qca8k: Add QCA8334 binding documentation + - net: dsa: qca8k: Allow overwriting CPU port setting + - ipv4: remove BUG_ON() from fib_compute_spec_dst + - net: fix amd-xgbe flow-control issue + - net: lan78xx: fix rx handling before first packet is send + - net: mdio-mux: bcm-iproc: fix wrong getter and setter pair + - NET: stmmac: align DMA stuff to largest cache line length + - tcp_bbr: fix bw probing to raise in-flight data for very small BDPs + - xen-netfront: wait xenbus state change when load module manually + - netlink: Do not subscribe to non-existent groups + - netlink: Don't shift with UB on nlk->ngroups + - tcp: do not force quickack when receiving out-of-order packets + - tcp: add max_quickacks param to tcp_incr_quickack and + tcp_enter_quickack_mode + - tcp: do not aggressively quick ack after ECN events + - tcp: refactor tcp_ecn_check_ce to remove sk type cast + - tcp: add one more quick ack after after ECN events + - mm: disallow mappings that conflict for devm_memremap_pages() + - drm/i915/glk: Add Quirk for GLK NUC HDMI port issues. + - mm: check for SIGKILL inside dup_mmap() loop + - rxrpc: Fix terminal retransmission connection ID to include the channel + - ceph: fix use-after-free in ceph_statfs() + - lightnvm: proper error handling for pblk_bio_add_pages + - f2fs: don't drop dentry pages after fs shutdown + - selftests: filesystems: return Kselftest Skip code for skipped tests + - selftests/filesystems: devpts_pts included wrong header + - iwlwifi: mvm: open BA session only when sta is authorized + - drm/amd/display: Do not program interrupt status on disabled crtc + - soc: qcom: smem: fix qcom_smem_set_global_partition() + - soc: qcom: smem: byte swap values properly + - pinctrl: msm: fix gpio-hog related boot issues + - net: mvpp2: Add missing VLAN tag detection + - drm/nouveau: remove fence wait code from deferred client work handler + - drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl + - clocksource: Move inline keyword to the beginning of function declarations + - media: staging: atomisp: Comment out several unused sensor resolutions + - IB: Fix RDMA_RXE and INFINIBAND_RDMAVT dependencies for DMA_VIRT_OPS + - rsi: Add null check for virtual interfaces in wowlan config + - ARM: dts: stih410: Fix complain about IRQ_TYPE_NONE usage + - ARM: dts: imx53: Fix LDB OF graph warning + - soc/tegra: pmc: Don't allocate struct tegra_powergate on stack + - mlxsw: spectrum_router: Return an error for non-default FIB rules + - i40e: Add advertising 10G LR mode + - i40e: avoid overflow in i40e_ptp_adjfreq() + - ath10k: fix kernel panic while reading tpc_stats + - ASoC: fsl_ssi: Use u32 variable type when using regmap_read() + - platform/x86: dell-smbios: Match on www.dell.com in OEM strings too + - staging: ks7010: fix error handling in ks7010_upload_firmware + - media: rc: mce_kbd decoder: low timeout values cause double keydowns + - ath10k: search all IEs for variant before falling back + - PCI/ASPM: Disable ASPM L1.2 Substate if we don't have LTR + - ARM: dts: imx6qdl-wandboard: Let the codec control MCLK pinctrl + - drm/amdgpu: Avoid reclaim while holding locks taken in MMU notifier + - nvmet-fc: fix target sgl list on large transfers + - i2c: rcar: handle RXDMA HW behaviour on Gen3 + - gpio: uniphier: set legitimate irq trigger type in .to_irq hook + - tcp: ack immediately when a cwr packet arrives + - ACPICA: AML Parser: ignore control method status in module-level code + * Bionic update: upstream stable patchset 2019-02-05 (LP: #1814813) + - MIPS: ath79: fix register address in ath79_ddr_wb_flush() + - MIPS: Fix off-by-one in pci_resource_to_user() + - xen/PVH: Set up GS segment for stack canary + - drm/nouveau/drm/nouveau: Fix runtime PM leak in nv50_disp_atomic_commit() + - drm/nouveau: Set DRIVER_ATOMIC cap earlier to fix debugfs + - bonding: set default miimon value for non-arp modes if not set + - ip: hash fragments consistently + - ip: in cmsg IP(V6)_ORIGDSTADDR call pskb_may_pull + - net/mlx4_core: Save the qpn from the input modifier in RST2INIT wrapper + - net: skb_segment() should not return NULL + - net/mlx5: Adjust clock overflow work period + - net/mlx5e: Don't allow aRFS for encapsulated packets + - net/mlx5e: Fix quota counting in aRFS expire flow + - net/ipv6: Fix linklocal to global address with VRF + - multicast: do not restore deleted record source filter mode to new one + - net: phy: consider PHY_IGNORE_INTERRUPT in phy_start_aneg_priv + - sock: fix sg page frag coalescing in sk_alloc_sg + - rtnetlink: add rtnl_link_state check in rtnl_configure_link + - vxlan: add new fdb alloc and create helpers + - vxlan: make netlink notify in vxlan_fdb_destroy optional + - vxlan: fix default fdb entry netlink notify ordering during netdev create + - tcp: fix dctcp delayed ACK schedule + - tcp: helpers to send special DCTCP ack + - tcp: do not cancel delay-AcK on DCTCP special ACK + - tcp: do not delay ACK in DCTCP upon CE status change + - staging: speakup: fix wraparound in uaccess length check + - usb: cdc_acm: Add quirk for Castles VEGA3000 + - usb: core: handle hub C_PORT_OVER_CURRENT condition + - usb: dwc2: Fix DMA alignment to start at allocated boundary + - usb: gadget: f_fs: Only return delayed status when len is 0 + - driver core: Partially revert "driver core: correct device's shutdown order" + - can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK + - can: xilinx_can: fix power management handling + - can: xilinx_can: fix recovery from error states not being propagated + - can: xilinx_can: fix device dropping off bus on RX overrun + - can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting + - can: xilinx_can: fix incorrect clear of non-processed interrupts + - can: xilinx_can: fix RX overflow interrupt not being enabled + - can: peak_canfd: fix firmware < v3.3.0: limit allocation to 32-bit DMA addr + only + - can: m_can.c: fix setup of CCCR register: clear CCCR NISO bit before + checking can.ctrlmode + - turn off -Wattribute-alias + - net-next/hinic: fix a problem in hinic_xmit_frame() + - net/mlx5e: Refine ets validation function + - nfp: flower: ensure dead neighbour entries are not offloaded + - usb: gadget: Fix OS descriptors support + - ACPICA: AML Parser: ignore dispatcher error status during table load + * installer does not support iSCSI iBFT (LP: #1817321) + - d-i: add iscsi_ibft to scsi-modules + * CVE-2019-7222 + - KVM: x86: work around leak of uninitialized stack contents (CVE-2019-7222) + * CVE-2019-7221 + - KVM: nVMX: unconditionally cancel preemption timer in free_nested + (CVE-2019-7221) + * CVE-2019-6974 + - kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974) + * Regular D-state processes impacting LXD containers (LP: #1817628) + - mm: do not stall register_shrinker() + * hns3 nic speed may not match optical port speed (LP: #1817969) + - net: hns3: Config NIC port speed same as that of optical module + * [Hyper-V] srcu: Lock srcu_data structure in srcu_gp_start() (LP: #1802021) + - srcu: Prohibit call_srcu() use under raw spinlocks + - srcu: Lock srcu_data structure in srcu_gp_start() + * libsas disks can have non-unique by-path names (LP: #1817784) + - scsi: libsas: Fix rphy phy_identifier for PHYs with end devices attached + * Bluetooth not working (Intel CyclonePeak) (LP: #1817518) + - Bluetooth: btusb: Add support for Intel bluetooth device 8087:0029 + * CVE-2019-8912 + - net: crypto set sk to NULL when af_alg_release. + - net: socket: set sock->sk to NULL after calling proto_ops::release() + * Trackpad is not recognized. (LP: #1817200) + - pinctrl: cannonlake: Fix gpio base for GPP-E + * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831) + - ALSA: hda/realtek - Headset microphone support for System76 darp5 + - ALSA: hda/realtek - Headset microphone and internal speaker support for + System76 oryp5 + * Constant noise in the headphone on Lenovo X1 machines (LP: #1817263) + - ALSA: hda/realtek: Disable PC beep in passthrough on alc285 + * AC adapter status not detected on Asus ZenBook UX410UAK (LP: #1745032) + - Revert "ACPI / battery: Add quirk for Asus GL502VSK and UX305LA" + - ACPI / AC: Remove initializer for unused ident dmi_system_id + - ACPI / battery: Remove initializer for unused ident dmi_system_id + - ACPI / battery: Add handling for devices which wrongly report discharging + state + - ACPI / battery: Ignore AC state in handle_discharging on systems where it is + broken + * TPM intermittently fails after cold-boot (LP: #1762672) + - tpm: fix intermittent failure with self tests + * qlcnic: Firmware aborts/hangs in QLogic NIC (LP: #1815033) + - qlcnic: fix Tx descriptor corruption on 82xx devices + + -- Khalid Elmously Mon, 18 Mar 2019 00:16:01 -0400 + +linux-oracle (4.15.0-1009.11) bionic; urgency=medium + + * linux-oracle: 4.15.0-1009.11 -proposed tracker (LP: #1814738) + + [ Ubuntu: 4.15.0-46.49 ] + + * linux: 4.15.0-46.49 -proposed tracker (LP: #1814726) + * mprotect fails on ext4 with dax (LP: #1799237) + - x86/speculation/l1tf: Exempt zeroed PTEs from inversion + * kernel BUG at /build/linux-vxxS7y/linux-4.15.0/mm/slub.c:296! (LP: #1812086) + - iscsi target: fix session creation failure handling + - scsi: iscsi: target: Set conn->sess to NULL when iscsi_login_set_conn_values + fails + - scsi: iscsi: target: Fix conn_ops double free + * user_copy in user from ubuntu_kernel_selftests failed on KVM kernel + (LP: #1812198) + - selftests: user: return Kselftest Skip code for skipped tests + - selftests: kselftest: change KSFT_SKIP=4 instead of KSFT_PASS + - selftests: kselftest: Remove outdated comment + * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472) + - SAUCE: staging: rtlwifi: allow RTLWIFI_DEBUG_ST to be disabled + - [Config] CONFIG_RTLWIFI_DEBUG_ST=n + - SAUCE: Add r8822be to signature inclusion list + * kernel oops in bcache module (LP: #1793901) + - SAUCE: bcache: never writeback a discard operation + * CVE-2018-18397 + - userfaultfd: use ENOENT instead of EFAULT if the atomic copy user fails + - userfaultfd: shmem: allocate anonymous memory for MAP_PRIVATE shmem + - userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas + - userfaultfd: shmem: add i_size checks + - userfaultfd: shmem: UFFDIO_COPY: set the page dirty if VM_WRITE is not set + * Ignore "incomplete report" from Elan touchpanels (LP: #1813733) + - HID: i2c-hid: Ignore input report if there's no data present on Elan + touchpanels + * Vsock connect fails with ENODEV for large CID (LP: #1813934) + - vhost/vsock: fix vhost vsock cid hashing inconsistent + * SRU: Fix thinkpad 11e 3rd boot hang (LP: #1804604) + - ACPI / LPSS: Force LPSS quirks on boot + * Bionic update: upstream stable patchset 2019-01-17 (LP: #1812229) + - scsi: sd_zbc: Fix variable type and bogus comment + - KVM/Eventfd: Avoid crash when assign and deassign specific eventfd in + parallel. + - x86/apm: Don't access __preempt_count with zeroed fs + - x86/events/intel/ds: Fix bts_interrupt_threshold alignment + - x86/MCE: Remove min interval polling limitation + - fat: fix memory allocation failure handling of match_strdup() + - ALSA: hda/realtek - Add Panasonic CF-SZ6 headset jack quirk + - ARCv2: [plat-hsdk]: Save accl reg pair by default + - ARC: Fix CONFIG_SWAP + - ARC: configs: Remove CONFIG_INITRAMFS_SOURCE from defconfigs + - ARC: mm: allow mprotect to make stack mappings executable + - mm: memcg: fix use after free in mem_cgroup_iter() + - mm/huge_memory.c: fix data loss when splitting a file pmd + - cpufreq: intel_pstate: Register when ACPI PCCH is present + - vfio/pci: Fix potential Spectre v1 + - stop_machine: Disable preemption when waking two stopper threads + - drm/i915: Fix hotplug irq ack on i965/g4x + - drm/nouveau: Use drm_connector_list_iter_* for iterating connectors + - drm/nouveau: Avoid looping through fake MST connectors + - gen_stats: Fix netlink stats dumping in the presence of padding + - ipv4: Return EINVAL when ping_group_range sysctl doesn't map to user ns + - ipv6: fix useless rol32 call on hash + - ipv6: ila: select CONFIG_DST_CACHE + - lib/rhashtable: consider param->min_size when setting initial table size + - net: diag: Don't double-free TCP_NEW_SYN_RECV sockets in tcp_abort + - net: Don't copy pfmemalloc flag in __copy_skb_header() + - skbuff: Unconditionally copy pfmemalloc in __skb_clone() + - net/ipv4: Set oif in fib_compute_spec_dst + - net: phy: fix flag masking in __set_phy_supported + - ptp: fix missing break in switch + - qmi_wwan: add support for Quectel EG91 + - tg3: Add higher cpu clock for 5762. + - hv_netvsc: Fix napi reschedule while receive completion is busy + - net/mlx4_en: Don't reuse RX page when XDP is set + - net: systemport: Fix CRC forwarding check for SYSTEMPORT Lite + - ipv6: make DAD fail with enhanced DAD when nonce length differs + - net: usb: asix: replace mii_nway_restart in resume path + - alpha: fix osf_wait4() breakage + - cxl_getfile(): fix double-iput() on alloc_file() failures + - powerpc/powernv: Fix save/restore of SPRG3 on entry/exit from stop (idle) + - xhci: Fix perceived dead host due to runtime suspend race with event handler + - KVM: irqfd: fix race between EPOLLHUP and irq_bypass_register_consumer + - x86/kvmclock: set pvti_cpu0_va after enabling kvmclock + - ALSA: hda/realtek - Yet another Clevo P950 quirk entry + - drm/amdgpu: Reserve VM root shared fence slot for command submission (v3) + - rhashtable: add restart routine in rhashtable_free_and_destroy() + - sch_fq_codel: zero q->flows_cnt when fq_codel_init fails + - sctp: introduce sctp_dst_mtu + - sctp: fix the issue that pathmtu may be set lower than MINSEGMENT + - net: aquantia: vlan unicast address list correct handling + - drm_mode_create_lease_ioctl(): fix open-coded filp_clone_open() + * Bionic update: upstream stable patchset 2019-01-15 (LP: #1811877) + - compiler-gcc.h: Add __attribute__((gnu_inline)) to all inline declarations + - x86/asm: Add _ASM_ARG* constants for argument registers to + - x86/paravirt: Make native_save_fl() extern inline + - Btrfs: fix duplicate extents after fsync of file with prealloc extents + - cpufreq / CPPC: Set platform specific transition_delay_us + - PCI: exynos: Fix a potential init_clk_resources NULL pointer dereference + - alx: take rtnl before calling __alx_open from resume + - atm: Preserve value of skb->truesize when accounting to vcc + - atm: zatm: Fix potential Spectre v1 + - ipv6: sr: fix passing wrong flags to crypto_alloc_shash() + - ipvlan: fix IFLA_MTU ignored on NEWLINK + - ixgbe: split XDP_TX tail and XDP_REDIRECT map flushing + - net: dccp: avoid crash in ccid3_hc_rx_send_feedback() + - net: dccp: switch rx_tstamp_last_feedback to monotonic clock + - net: fix use-after-free in GRO with ESP + - net: macb: Fix ptp time adjustment for large negative delta + - net/mlx5e: Avoid dealing with vport representors if not being e-switch + manager + - net/mlx5: E-Switch, Avoid setup attempt if not being e-switch manager + - net/mlx5: Fix command interface race in polling mode + - net/mlx5: Fix incorrect raw command length parsing + - net/mlx5: Fix required capability for manipulating MPFS + - net/mlx5: Fix wrong size allocation for QoS ETC TC regitster + - net: mvneta: fix the Rx desc DMA address in the Rx path + - net/packet: fix use-after-free + - net_sched: blackhole: tell upper qdisc about dropped packets + - net: sungem: fix rx checksum support + - net/tcp: Fix socket lookups with SO_BINDTODEVICE + - qede: Adverstise software timestamp caps when PHC is not available. + - qed: Fix setting of incorrect eswitch mode. + - qed: Fix use of incorrect size in memcpy call. + - qed: Limit msix vectors in kdump kernel to the minimum required count. + - r8152: napi hangup fix after disconnect + - stmmac: fix DMA channel hang in half-duplex mode + - strparser: Remove early eaten to fix full tcp receive buffer stall + - tcp: fix Fast Open key endianness + - tcp: prevent bogus FRTO undos with non-SACK flows + - vhost_net: validate sock before trying to put its fd + - VSOCK: fix loopback on big-endian systems + - net: cxgb3_main: fix potential Spectre v1 + - rtlwifi: Fix kernel Oops "Fw download fail!!" + - rtlwifi: rtl8821ae: fix firmware is not ready to run + - net: lan78xx: Fix race in tx pending skb size calculation + - crypto: af_alg - Initialize sg_num_bytes in error code path + - mtd: rawnand: denali_dt: set clk_x_rate to 200 MHz unconditionally + - PCI: hv: Disable/enable IRQs rather than BH in hv_compose_msi_msg() + - netfilter: ebtables: reject non-bridge targets + - reiserfs: fix buffer overflow with long warning messages + - KEYS: DNS: fix parsing multiple options + - tls: Stricter error checking in zerocopy sendmsg path + - autofs: fix slab out of bounds read in getname_kernel() + - nsh: set mac len based on inner packet + - bdi: Fix another oops in wb_workfn() + - rds: avoid unenecessary cong_update in loop transport + - net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL. + - string: drop __must_check from strscpy() and restore strscpy() usages in + cgroup + - nfsd: COPY and CLONE operations require the saved filehandle to be set + - net/sched: act_ife: fix recursive lock and idr leak + - net/sched: act_ife: preserve the action control in case of error + - hinic: reset irq affinity before freeing irq + - nfp: flower: fix mpls ether type detection + - net: macb: initialize bp->queues[0].bp for at91rm9200 + - enic: do not overwrite error code + - virtio_net: fix memory leak in XDP_REDIRECT + - netfilter: ipv6: nf_defrag: drop skb dst before queueing + - ipvs: initialize tbl->entries after allocation + - ipvs: initialize tbl->entries in ip_vs_lblc_init_svc() + - bpf: enforce correct alignment for instructions + - bpf, arm32: fix to use bpf_jit_binary_lock_ro api + * Fix non-working pinctrl-intel (LP: #1811777) + - pinctrl: intel: Implement intel_gpio_get_direction callback + - pinctrl: intel: Do pin translation in other GPIO operations as well + * ip6_gre: fix tunnel list corruption for x-netns (LP: #1812875) + - ip6_gre: fix tunnel list corruption for x-netns + * Userspace break as a result of missing patch backport (LP: #1813873) + - tty: Don't hold ldisc lock in tty_reopen() if ldisc present + * kvm_stat : missing python dependency (LP: #1798776) + - tools/kvm_stat: fix python3 issues + - tools/kvm_stat: switch to python3 + * [SRU] Fix Xorg crash with nomodeset when BIOS enable 64-bit fb addr + (LP: #1812797) + - vgaarb: Add support for 64-bit frame buffer address + - vgaarb: Keep adding VGA device in queue + * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812) + - USB: Add new USB LPM helpers + - USB: Consolidate LPM checks to avoid enabling LPM twice + * ptrace-tm-spd-gpr in powerpc/ptrace from ubuntu_kerenl_selftests failed on + Bionic P8 (LP: #1813127) + - selftests/powerpc: Fix ptrace tm failure + * [SRU] IO's are issued with incorrect Scatter Gather Buffer (LP: #1795453) + - scsi: megaraid_sas: Use 63-bit DMA addressing + * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816) + - [Config] Enable timestamping in network PHY devices + * CVE-2018-19854 + - crypto: user - fix leaking uninitialized memory to userspace + * x86/mm: Found insecure W+X mapping at address (ptrval)/0xc00a0000 + (LP: #1813532) + - x86/mm: Do not warn about PCI BIOS W+X mappings + * CVE-2019-6133 + - fork: record start_time late + * Fix not working Goodix touchpad (LP: #1811929) + - HID: i2c-hid: Disable runtime PM on Goodix touchpad + * bluetooth controller not detected with 4.15 kernel (LP: #1810797) + - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK + - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y + * X1 Extreme: only one of the two SSDs is loaded (LP: #1811755) + - nvme-core: rework a NQN copying operation + - nvme: pad fake subsys NQN vid and ssvid with zeros + - nvme: introduce NVME_QUIRK_IGNORE_DEV_SUBNQN + * Crash on "ip link add foo type ipip" (LP: #1811803) + - SAUCE: fan: Fix NULL pointer dereference + + [ Ubuntu: 4.15.0-45.48 ] + + * linux: 4.15.0-45.48 -proposed tracker (LP: #1813779) + * External monitors does not work anymore 4.15.0-44 (LP: #1813663) + - SAUCE: Revert "drm/i915/dp: Send DPCD ON for MST before phy_up" + * kernel 4.15.0-44 cannot mount ext4 fs with meta_bg enabled (LP: #1813727) + - ext4: fix false negatives *and* false positives in ext4_check_descriptors() + + -- Kleber Sacilotto de Souza Wed, 06 Feb 2019 14:11:18 +0000 + +linux-oracle (4.15.0-1008.10) bionic; urgency=medium + + * linux-oracle: 4.15.0-1008.10 -proposed tracker (LP: #1811427) + + * SATA device is not going to DEVSLP (LP: #1781533) + - [Config] set CONFIG_SATA_MOBILE_LPM_POLICY=0 + + * Bionic update: upstream stable patchset 2019-01-04 (LP: #1810554) + - [config] x86 CRYPTO_SALSA20 deprecated + + [ Ubuntu: 4.15.0-44.47 ] + + * linux: 4.15.0-44.47 -proposed tracker (LP: #1811419) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * CPU hard lockup with rigorous writes to NVMe drive (LP: #1810998) + - blk-wbt: pass in enum wbt_flags to get_rq_wait() + - blk-wbt: Avoid lock contention and thundering herd issue in wbt_wait + - blk-wbt: move disable check into get_limit() + - blk-wbt: use wq_has_sleeper() for wq active check + - blk-wbt: fix has-sleeper queueing check + - blk-wbt: abstract out end IO completion handler + - blk-wbt: improve waking of tasks + * To reduce the Realtek USB cardreader power consumption (LP: #1811337) + - mmc: sdhci: Disable 1.8v modes (HS200/HS400/UHS) if controller can't support + 1.8v + - mmc: core: Introduce MMC_CAP_SYNC_RUNTIME_PM + - mmc: rtsx_usb_sdmmc: Don't runtime resume the device while changing led + - mmc: rtsx_usb: Use MMC_CAP2_NO_SDIO + - mmc: rtsx_usb: Enable MMC_CAP_ERASE to allow erase/discard/trim requests + - mmc: rtsx_usb_sdmmc: Re-work runtime PM support + - mmc: rtsx_usb_sdmmc: Re-work card detection/removal support + - memstick: rtsx_usb_ms: Add missing pm_runtime_disable() in probe function + - misc: rtsx_usb: Use USB remote wakeup signaling for card insertion detection + - memstick: Prevent memstick host from getting runtime suspended during card + detection + - memstick: rtsx_usb_ms: Use ms_dev() helper + - memstick: rtsx_usb_ms: Support runtime power management + * Support non-strict iommu mode on arm64 (LP: #1806488) + - iommu/io-pgtable-arm: Fix race handling in split_blk_unmap() + - iommu/arm-smmu-v3: Implement flush_iotlb_all hook + - iommu/dma: Add support for non-strict mode + - iommu: Add "iommu.strict" command line option + - iommu/io-pgtable-arm: Add support for non-strict mode + - iommu/arm-smmu-v3: Add support for non-strict mode + - iommu/io-pgtable-arm-v7s: Add support for non-strict mode + - iommu/arm-smmu: Support non-strict mode + * ELAN900C:00 04F3:2844 touchscreen doesn't work (LP: #1811335) + - pinctrl: cannonlake: Fix community ordering for H variant + - pinctrl: cannonlake: Fix HOSTSW_OWN register offset of H variant + * Add Cavium ThunderX2 SoC UNCORE PMU driver (LP: #1811200) + - perf: Export perf_event_update_userpage + - Documentation: perf: Add documentation for ThunderX2 PMU uncore driver + - drivers/perf: Add Cavium ThunderX2 SoC UNCORE PMU driver + - [Config] New config CONFIG_THUNDERX2_PMU=m + * Update hisilicon SoC-specific drivers (LP: #1810457) + - SAUCE: Revert "net: hns3: Updates RX packet info fetch in case of multi BD" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when + resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce + callback function" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback + function when link status change" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying + roce client" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE" + - scsi: hisi_sas: Remove depends on HAS_DMA in case of platform dependency + - ethernet: hisilicon: hns: hns_dsaf_mac: Use generic eth_broadcast_addr + - scsi: hisi_sas: consolidate command check in hisi_sas_get_ata_protocol() + - scsi: hisi_sas: remove some unneeded structure members + - scsi: hisi_sas: Introduce hisi_sas_phy_set_linkrate() + - net: hns: Fix the process of adding broadcast addresses to tcam + - net: hns3: remove redundant variable 'protocol' + - scsi: hisi_sas: Drop hisi_sas_slot_abort() + - net: hns: Make many functions static + - net: hns: make hns_dsaf_roce_reset non static + - net: hisilicon: hns: Replace mdelay() with msleep() + - net: hns3: fix return value error while hclge_cmd_csq_clean failed + - net: hns: remove redundant variables 'max_frm' and 'tmp_mac_key' + - net: hns: Mark expected switch fall-through + - net: hns3: Mark expected switch fall-through + - net: hns3: Remove tx ring BD len register in hns3_enet + - net: hns: modify variable type in hns_nic_reuse_page + - net: hns: use eth_get_headlen interface instead of hns_nic_get_headlen + - net: hns3: modify variable type in hns3_nic_reuse_page + - net: hns3: Fix for vf vlan delete failed problem + - net: hns3: Fix for multicast failure + - net: hns3: Fix error of checking used vlan id + - net: hns3: Implement shutdown ops in hns3 pci driver + - net: hns3: Fix for loopback selftest failed problem + - net: hns3: Fix ping exited problem when doing lp selftest + - net: hns3: Preserve vlan 0 in hardware table + - net: hns3: Only update mac configuation when necessary + - net: hns3: Change the dst mac addr of loopback packet + - net: hns3: Remove redundant codes of query advertised flow control abilitiy + - net: hns3: Refine hns3_get_link_ksettings() + - net: hns: make function hns_gmac_wait_fifo_clean() static + - net: hns3: Add default irq affinity + - net: hns3: Add unlikely for buf_num check + - net: hns3: Remove tx budget to clean more TX descriptors in a napi + - net: hns3: Remove packet statistics of public + - net: hns3: Add support for hns3_nic_netdev_ops.ndo_do_ioctl + - net: hns3: Set STATE_DOWN bit of hdev state when stopping net + - net: hns3: Check hdev state when getting link status + - net: hns3: Fix for setting speed for phy failed problem + - net: hns3: Fix cmdq registers initialization issue for vf + - net: hns3: Clear client pointer when initialize client failed or unintialize + finished + - net: hns3: Fix client initialize state issue when roce client initialize + failed + - net: hns3: Fix parameter type for q_id in hclge_tm_q_to_qs_map_cfg() + - net: hns3: Fix ets validate issue + - net: hns3: Unify the type convert for desc.data + - net: hns3: Adjust prefix of tx/rx statistic names + - net: hns3: Fix tqp array traversal condition for vf + - net: hns3: Unify the prefix of vf functions + - net: hns3: Add handle for default case + - net: hns3: Add nic state check before calling netif_tx_wake_queue + - net: hns3: Add unlikely for dma_mapping_error check + - net: hns3: Remove print messages for error packet + - net: hns3: Add get_media_type ops support for VF + - net: hns3: Fix speed/duplex information loss problem when executing ethtool + ethx cmd of VF + - net: hns3: Remove redundant hclge_get_port_type() + - net: hns3: Add support for sctp checksum offload + - net: hns3: Set extra mac address of pause param for HW + - net: hns3: Rename loop mode + - net: hns3: Rename mac loopback to app loopback + - net: hns3: Add serdes parallel inner loopback support + - net: hns3: Fix for packet buffer setting bug + - net: hns3: Fix for netdev not up problem when setting mtu + - net: hns3: Change return type of hclge_tm_schd_info_update() + - net: hns3: Modify hns3_get_max_available_channels + - net: hns3: Fix loss of coal configuration while doing reset + - net: hns: remove ndo_poll_controller + - hns3: Fix the build. + - hns3: Another build fix. + - net: hns3: Add flow director initialization + - net: hns3: Add input key and action config support for flow director + - net: hns3: Add support for rule add/delete for flow director + - net: hns3: Add support for rule query of flow director + - net: hns3: Add reset handle for flow director + - net: hns3: Remove all flow director rules when unload hns3 driver + - net: hns3: Add support for enable/disable flow director + - net: hns3: Remove the default mask configuration for mac vlan table + - net: hns3: Clear mac vlan table entries when unload driver or function reset + - net: hns3: Optimize for unicast mac vlan table + - net: hns3: Drop depricated mta table support + - net: hns3: Add egress/ingress vlan filter for revision 0x21 + - net: hns3: Fix for rx vlan id handle to support Rev 0x21 hardware + - net: hns3: Add new RSS hash algorithm support for PF + - net: hns3: Add RSS general configuration support for VF + - net: hns3: Add RSS tuples support for VF + - net: hns3: Add HW RSS hash information to RX skb + - net: hns3: Enable promisc mode when mac vlan table is full + - net: hns3: Resume promisc mode and vlan filter status after reset + - net: hns3: Resume promisc mode and vlan filter status after loopback test + - scsi: hisi_sas: Feed back linkrate(max/min) when re-attached + - scsi: hisi_sas: Move evaluation of hisi_hba in hisi_sas_task_prep() + - scsi: hisi_sas: Fix the race between IO completion and timeout for + SMP/internal IO + - scsi: hisi_sas: Free slot later in slot_complete_vx_hw() + - scsi: hisi_sas: unmask interrupts ent72 and ent74 + - scsi: hisi_sas: Use block layer tag instead for IPTT + - scsi: hisi_sas: Update v3 hw AIP_LIMIT and CFG_AGING_TIME register values + - net: hns3: remove hns3_fill_desc_tso + - net: hns3: move DMA map into hns3_fill_desc + - net: hns3: add handling for big TX fragment + - net: hns3: rename hns_nic_dma_unmap + - net: hns3: fix for multiple unmapping DMA problem + - scsi: hisi_sas: Fix spin lock management in slot_index_alloc_quirk_v2_hw() + - scsi: hisi_sas: Fix NULL pointer dereference + - net: hns3: Add PCIe AER callback error_detected + - net: hns3: Add PCIe AER error recovery + - net: hns3: Add support to enable and disable hw errors + - net: hns3: Add enable and process common ecc errors + - net: hns3: Add enable and process hw errors from IGU, EGU and NCSI + - net: hns3: Add enable and process hw errors from PPP + - net: hns3: Add enable and process hw errors of TM scheduler + - net: hns3: Fix for warning uninitialized symbol hw_err_lst3 + - net: hns3: fix spelling mistake "intrerrupt" -> "interrupt" + - net: hns3: add error handler for hns3_nic_init_vector_data() + - net: hns3: bugfix for buffer not free problem during resetting + - net: hns3: bugfix for reporting unknown vector0 interrupt repeatly problem + - net: hns3: bugfix for the initialization of command queue's spin lock + - net: hns3: remove unnecessary queue reset in the hns3_uninit_all_ring() + - net: hns3: bugfix for is_valid_csq_clean_head() + - net: hns3: bugfix for hclge_mdio_write and hclge_mdio_read + - net: hns3: fix incorrect return value/type of some functions + - net: hns3: bugfix for handling mailbox while the command queue reinitialized + - net: hns3: bugfix for rtnl_lock's range in the hclge_reset() + - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset() + - net: hns3: Fix for out-of-bounds access when setting pfc back pressure + - scsi: hisi_sas: Remove set but not used variable 'dq_list' + - net: hns3: bugfix for not checking return value + - net: hns: Incorrect offset address used for some registers. + - net: hns: All ports can not work when insmod hns ko after rmmod. + - net: hns: Some registers use wrong address according to the datasheet. + - net: hns: Fixed bug that netdev was opened twice + - net: hns: Clean rx fbd when ae stopped. + - net: hns: Free irq when exit from abnormal branch + - net: hns: Avoid net reset caused by pause frames storm + - net: hns: Fix ntuple-filters status error. + - net: hns: Add mac pcs config when enable|disable mac + - net: hns: Fix ping failed when use net bridge and send multicast + - net: hns3: use HNS3_NIC_STATE_INITED to indicate the initialization state of + enet + - net: hns3: add set_default_reset_request in the hnae3_ae_ops + - net: hns3: provide some interface & information for the client + - net: hns3: adjust the location of clearing the table when doing reset + - net: hns3: enable/disable ring in the enet while doing UP/DOWN + - net: hns3: use HNS3_NIC_STATE_RESETTING to indicate resetting + - net: hns3: ignore new coming low-level reset while doing high-level reset + - net: hns3: move some reset information from hnae3_handle into + hclge_dev/hclgevf_dev + - net: hns3: adjust the process of PF reset + - net: hns3: call roce's reset notify callback when resetting + - net: hns3: add error handler for hclge_reset() + - net: hns3: fix for cmd queue memory not freed problem during reset + - net: hns3: Remove set but not used variable 'reset_level' + - net: hns3: fix spelling mistake, "assertting" -> "asserting" + - net: hns3: add reset_hdev to reinit the hdev in VF's reset process + - net: hns3: adjust VF's reset process + - net: hns3: add reset handling for VF when doing PF reset + - net: hns3: add reset handling for VF when doing Core/Global/IMP reset + - net: hns3: stop handling command queue while resetting VF + - net: hns3: add error handler for hclgevf_reset() + - net: hns3: stop napi polling when HNS3_NIC_STATE_DOWN is set + - net: hns3: implement the IMP reset processing for PF + - net: hns3: add PCIe FLR support for PF + - net: hns3: do VF's pci re-initialization while PF doing FLR + - net: hns3: add PCIe FLR support for VF + - net: hns3: Enable HW GRO for Rev B(=0x21) HNS3 hardware + - net: hns3: Add handling of GRO Pkts not fully RX'ed in NAPI poll + - net: hns3: Add skb chain when num of RX buf exceeds MAX_SKB_FRAGS + - net: hns3: Adds GRO params to SKB for the stack + - scsi: hisi_sas: use dma_set_mask_and_coherent + - scsi: hisi_sas: Create separate host attributes per HBA + - scsi: hisi_sas: Add support for interrupt converge for v3 hw + - scsi: hisi_sas: Add support for interrupt coalescing for v3 hw + - scsi: hisi_sas: Relocate some codes to avoid an unused check + - scsi: hisi_sas: change the time of SAS SSP connection + - net: hns3: fix spelling mistake "failded" -> "failed" + - net: hns3: Support two vlan header when setting mtu + - net: hns3: Refactor mac mtu setting related functions + - net: hns3: Add vport alive state checking support + - net: hns3: Add mtu setting support for vf + - net: hns3: up/down netdev in hclge module when setting mtu + - net: hns3: add common validation in hclge_dcb + - net: hns3: Add debugfs framework registration + - net: hns3: Add "queue info" query function + - net: hns3: Add "FD flow table" info query function + - net: hns3: Add "tc config" info query function + - net: hns3: Add "tm config" info query function + - net: hns3: Add "qos pause" config info query function + - net: hns3: Add "qos prio map" info query function + - net: hns3: Add "qos buffer" config info query function + - net: hns3: Support "ethtool -d" for HNS3 VF driver + - net: hns3: Adds support to dump(using ethool-d) PCIe regs in HNS3 PF driver + - net: hns3: remove existing process error functions and reorder hw_blk table + - net: hns3: rename enable error interrupt functions + - net: hns3: re-enable error interrupts on hw reset + - net: hns3: deletes unnecessary settings of the descriptor data + - net: hns3: rename process_hw_error function + - net: hns3: add optimization in the hclge_hw_error_set_state + - net: hns3: add handling of hw ras errors using new set of commands + - net: hns3: deleted logging 1 bit errors + - net: hns3: add handling of hw errors reported through MSIX + - net: hns3: add handling of hw errors of MAC + - net: hns3: handle hw errors of PPP PF + - net: hns3: handle hw errors of PPU(RCB) + - net: hns3: handle hw errors of SSU + - net: hns3: add handling of RDMA RAS errors + - net: hns3: fix spelling mistake "offser" -> "offset" + - scsi: hisi_sas: Fix warnings detected by sparse + - scsi: hisi_sas: Relocate some code to reduce complexity + - scsi: hisi_sas: Make sg_tablesize consistent value + - hns3: prevent building without CONFIG_INET + - net: hns3: Add "bd info" query function + - net: hns3: Add "manager table" information query function + - net: hns3: Add "status register" information query function + - net: hns3: Add "dcb register" status information query function + - net: hns3: Add "queue map" information query function + - net: hns3: Add "tm map" status information query function + - net: hns3: fix error handling int the hns3_get_vector_ring_chain + - net: hns3: uninitialize pci in the hclgevf_uninit + - net: hns3: fix napi_disable not return problem + - net: hns3: update some variables while hclge_reset()/hclgevf_reset() done + - net: hns3: remove unnecessary configuration recapture while resetting + - net: hns3: fix incomplete uninitialization of IRQ in the + hns3_nic_uninit_vector_data() + - net: hns3: update coalesce param per second + - net: hns3: remove 1000M/half support of phy + - net: hns3: synchronize speed and duplex from phy when phy link up + - net: hns3: getting tx and dv buffer size through firmware + - net: hns3: aligning buffer size in SSU to 256 bytes + - net: hns3: fix a SSU buffer checking bug + - scsi: hisi_sas: Add support for DIF feature for v2 hw + - net: hns3: refine the handle for hns3_nic_net_open/stop() + - net: hns3: change default tc state to close + - net: hns3: fix a bug caused by udelay + - net: hns3: add max vector number check for pf + - net: hns3: reset tqp while doing DOWN operation + - net: hns3: fix vf id check issue when add flow director rule + - net: hns3: don't restore rules when flow director is disabled + - net: hns3: fix the descriptor index when get rss type + - net: hns3: remove redundant variable initialization + - net: hns3: call hns3_nic_net_open() while doing HNAE3_UP_CLIENT + * iptables connlimit allows more connections than the limit when using + multiple CPUs (LP: #1811094) + - SAUCE: netfilter: xt_connlimit: remove the 'addr' parameter in add_hlist() + - netfilter: nf_conncount: expose connection list interface + - netfilter: nf_conncount: Fix garbage collection with zones + - netfilter: nf_conncount: fix garbage collection confirm race + - netfilter: nf_conncount: don't skip eviction when age is negative + * CVE-2018-16882 + - KVM: Fix UAF in nested posted interrupt processing + * Cannot initialize ATA disk if IDENTIFY command fails (LP: #1809046) + - scsi: libsas: check the ata device status by ata_dev_enabled() + * scsi: libsas: fix a race condition when smp task timeout (LP: #1808912) + - scsi: libsas: fix a race condition when smp task timeout + * CVE-2018-14625 + - vhost/vsock: fix use-after-free in network stack callers + * Fix and issue that LG I2C touchscreen stops working after reboot + (LP: #1805085) + - HID: i2c-hid: Disable runtime PM for LG touchscreen + * powerpc/powernv/pci: Work around races in PCI bridge enabling (LP: #1805245) + - powerpc/powernv/pci: Work around races in PCI bridge enabling + * Drivers: hv: vmbus: Offload the handling of channels to two workqueues + (LP: #1807757) + - hv_netvsc: fix network namespace issues with VF support + - hv_netvsc: split sub-channel setup into async and sync + - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer() + - hv_netvsc: Fix a deadlock by getting rtnl lock earlier in netvsc_probe() + - vmbus: don't return values for uninitalized channels + - Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl() + - Drivers: hv: vmbus: Offload the handling of channels to two workqueues + * Disable LPM for Raydium Touchscreens (LP: #1802248) + - USB: quirks: Add no-lpm quirk for Raydium touchscreens + * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network + Adapter (LP: #1805607) + - SAUCE: ath10k: provide reset function for QCA9377 chip + * CVE-2018-17972 + - proc: restrict kernel stack dumps to root + * CVE-2018-19407 + - KVM: X86: Fix scan ioapic use-before-initialization + * CVE-2018-18281 + - mremap: properly flush TLB before releasing the page + * Fix USB2 device wrongly detected as USB1 (LP: #1806534) + - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc + * armhf guests fail to boot in EFI mode (LP: #1809488) + - efi/arm: Revert deferred unmap of early memmap mapping + * Bionic shows incorrect warning about number of pointers in TFD + (LP: #1801102) + - iwlwifi: pcie: don't warn if we use all the transmit pointers + * audio output has constant noise on a Dell machine (LP: #1810891) + - ALSA: hda/realtek - Fixed headphone issue for ALC700 + * ldisc crash on reopened tty (LP: #1791758) + - tty: Drop tty->count on tty_reopen() failure + - tty: Hold tty_ldisc_lock() during tty_reopen() + - tty: Don't block on IO when ldisc change is pending + - tty: Simplify tty->count math in tty_reopen() + * SATA device is not going to DEVSLP (LP: #1781533) + - ahci: Allow setting a default LPM policy for mobile chipsets + - ata: libahci: Correct setting of DEVSLP register + - ata: libahci: Allow reconfigure of DEVSLP register + - ata: ahci: Support state with min power but Partial low power state + - ata: ahci: Enable DEVSLP by default on x86 with SLP_S0 + - [Config] set CONFIG_SATA_MOBILE_LPM_POLICY=0 + * Console got stuck using serial tty after logout (LP: #1808097) + - tty: do not set TTY_IO_ERROR flag if console port + * fanotify10 in ubuntu_ltp_syscalls failed (LP: #1802454) + - fsnotify: fix ignore mask logic in fsnotify() + * SRU: Fix kernel xhci hang when resume from S3 (LP: #1805344) + - usb: xhci: fix uninitialized completion when USB3 port got wrong status + - usb: xhci: fix timeout for transition from RExit to U0 + * Add pointstick support for Cirque Touchpad (LP: #1805081) + - HID: multitouch: Add pointstick support for Cirque Touchpad + * Intel NVMe drives timeout when nvme format is attempted (LP: #1797587) + - nvme: Use admin command effects for admin commands + * lineout jack can't work on a Dell machine (LP: #1810892) + - ALSA: hda/realtek - Support Dell headset mode for New AIO platform + * Bionic update: upstream stable patchset 2019-01-04 (LP: #1810554) + - MIPS: Call dump_stack() from show_regs() + - MIPS: Use async IPIs for arch_trigger_cpumask_backtrace() + - MIPS: Fix ioremap() RAM check + - mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl states + - mmc: dw_mmc: fix card threshold control configuration + - ibmasm: don't write out of bounds in read handler + - staging: rtl8723bs: Prevent an underflow in rtw_check_beacon_data(). + - staging: r8822be: Fix RTL8822be can't find any wireless AP + - ata: Fix ZBC_OUT command block check + - ata: Fix ZBC_OUT all bit handling + - vmw_balloon: fix inflation with batching + - ahci: Disable LPM on Lenovo 50 series laptops with a too old BIOS + - USB: serial: ch341: fix type promotion bug in ch341_control_in() + - USB: serial: cp210x: add another USB ID for Qivicon ZigBee stick + - USB: serial: keyspan_pda: fix modem-status error handling + - USB: serial: mos7840: fix status-register error handling + - usb: quirks: add delay quirks for Corsair Strafe + - xhci: xhci-mem: off by one in xhci_stream_id_to_ring() + - ALSA: hda - Handle pm failure during hotplug + - fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps* + - fs, elf: make sure to page align bss in load_elf_library + - mm: do not bug_on on incorrect length in __mm_populate() + - tracing: Reorder display of TGID to be after PID + - kbuild: delete INSTALL_FW_PATH from kbuild documentation + - arm64: neon: Fix function may_use_simd() return error status + - tools build: fix # escaping in .cmd files for future Make + - IB/hfi1: Fix incorrect mixing of ERR_PTR and NULL return values + - i2c: tegra: Fix NACK error handling + - iw_cxgb4: correctly enforce the max reg_mr depth + - xen: setup pv irq ops vector earlier + - nvme-pci: Remap CMB SQ entries on every controller reset + - crypto: x86/salsa20 - remove x86 salsa20 implementations + - uprobes/x86: Remove incorrect WARN_ON() in uprobe_init_insn() + - netfilter: nf_queue: augment nfqa_cfg_policy + - netfilter: x_tables: initialise match/target check parameter struct + - loop: add recursion validation to LOOP_CHANGE_FD + - PM / hibernate: Fix oops at snapshot_write() + - RDMA/ucm: Mark UCM interface as BROKEN + - loop: remember whether sysfs_create_group() was done + - f2fs: give message and set need_fsck given broken node id + - mm: do not drop unused pages when userfaultd is running + - bpf: reject passing modified ctx to helper functions + - mei: discard messages from not connected client during power down. + - mm: zero unavailable pages before memmap init + - xen: remove global bit from __default_kernel_pte_mask for pv guests + - f2fs: return error during fill_super + - f2fs: avoid bug_on on corrupted inode + - f2fs: sanity check on sit entry + - f2fs: sanity check for total valid node blocks + - ARM: dts: armada-38x: use the new thermal binding + - mm: don't do zero_resv_unavail if memmap is not allocated + * Blacklist Realtek Virtual IPMI device (LP: #1808353) + - ipmi:pci: Blacklist a Realtek "IPMI" device + * Ethernet[10ec:8136] doesn't work after S3 with kernel 4.15.0.43.64 + (LP: #1809847) + - SAUCE: Revert "r8169: don't use MSI-X on RTL8106e" + - r8169: re-enable MSI-X on RTL8168g + * Killer 802.11ac 2x2 (1550 or 1550i) [8086:2526][1a56:1550] is not supported + (LP: #1809219) + - iwlwifi: add more card IDs for 9000 series + * Support new Realtek ethernet chips (LP: #1811055) + - r8169: Add support for new Realtek Ethernet + * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle + (LP: #1805775) + - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being + disabled + * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF) + (LP: #1804588) + - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + * mpt3sas - driver using the wrong register to update a queue index in FW + (LP: #1810781) + - scsi: mpt3sas: As per MPI-spec, use combined reply queue for SAS3.5 + controllers when HBA supports more than 16 MSI-x vectors. + * HP mobile workstations with hybrid graphics support, can not directly output + to external monitors by dGPU (LP: #1810702) + - ACPI / OSI: Add OEM _OSI string to enable dGPU direct output + * broken touchpad after i2c-i801 blacklist change (LP: #1802135) + - i2c: i801: Don't restore config registers on runtime PM + * Enable new Realtek card reader (LP: #1806335) + - USB: usb-storage: Add new IDs to ums-realtek + - SAUCE: (noup) USB: usb-storage: Make MMC support optional on ums-realtek + * The line-out on the Dell Dock station can't work (LP: #1806532) + - ALSA: usb-audio: Allow to override the longname string + - ALSA: usb-audio: Give proper vendor/product name for Dell WD15 Dock + - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] getabis -- handle all known package combinations + - [Packaging] getabis -- support parsing a simple version + * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818) + - igb: Fix an issue that PME is not enabled during runtime suspend + * Fix Terminus USB hub that may breaks connected USB devices after S3 + (LP: #1806850) + - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub + * Add support for Dell DW5821e WWAN/GPS module (LP: #1807342) + - qmi_wwan: add support for the Dell Wireless 5821e module + - qmi_wwan: fix interface number for DW5821e production firmware + - USB: option: add support for DW5821e + * Add support for 0cf3:535b QCA_ROME device (LP: #1807333) + - Bluetooth: btusb: Add support for 0cf3:535b QCA_ROME device + * The mute led can't work anymore on the lenovo x1 carbon (LP: #1808465) + - ALSA: hda/realtek - Fix the mute LED regresion on Lenovo X1 Carbon + * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) // + click/pop noise in the headphone on several lenovo laptops (LP: #1805079) + - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops + * Touchpad stops working after reboot on Apollo Lake (LP: #1728244) + - HID: i2c-hid: disable runtime PM operations on hantick touchpad + * MAC address pass through on RTL8153-BND for docking station (LP: #1808729) + - r8152: Add support for MAC address pass through on RTL8153-BND + * [Ubuntu] kernel: zcrypt: reinit ap queue state machine (LP: #1805414) + - s390/zcrypt: reinit ap queue state machine during device probe + * [UBUNTU] qeth: fix length check in SNMP processing (LP: #1805802) + - s390/qeth: fix length check in SNMP processing + * ASPEED server console output extremely slow after upgrade to 18.04 + (LP: #1808183) + - drm/ast: Remove existing framebuffers before loading driver + * Bionic update: upstream stable patchset 2018-12-13 (LP: #1808399) + - userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access + - mm: hugetlb: yield when prepping struct pages + - tracing: Fix missing return symbol in function_graph output + - scsi: target: Fix truncated PR-in ReadKeys response + - s390: Correct register corruption in critical section cleanup + - drbd: fix access after free + - vfio: Use get_user_pages_longterm correctly + - cifs: Fix use after free of a mid_q_entry + - cifs: Fix memory leak in smb2_set_ea() + - cifs: Fix infinite loop when using hard mount option + - drm: Use kvzalloc for allocating blob property memory + - drm/udl: fix display corruption of the last line + - jbd2: don't mark block as modified if the handle is out of credits + - ext4: add corruption check in ext4_xattr_set_entry() + - ext4: always verify the magic number in xattr blocks + - ext4: make sure bitmaps and the inode table don't overlap with bg + descriptors + - ext4: always check block group bounds in ext4_init_block_bitmap() + - ext4: only look at the bg_flags field if it is valid + - ext4: verify the depth of extent tree in ext4_find_extent() + - ext4: include the illegal physical block in the bad map ext4_error msg + - ext4: never move the system.data xattr out of the inode body + - ext4: avoid running out of journal credits when appending to an inline file + - ext4: add more inode number paranoia checks + - ext4: add more mount time checks of the superblock + - ext4: check superblock mapped prior to committing + - HID: i2c-hid: Fix "incomplete report" noise + - HID: hiddev: fix potential Spectre v1 + - HID: debug: check length before copy_to_user() + - media: vb2: core: Finish buffers at the end of the stream + - f2fs: truncate preallocated blocks in error case + - Revert "dpaa_eth: fix error in dpaa_remove()" + - Kbuild: fix # escaping in .cmd files for future Make + - media: cx25840: Use subdev host data for PLL override + - fs: allow per-device dax status checking for filesystems + - dax: change bdev_dax_supported() to support boolean returns + - dax: check for QUEUE_FLAG_DAX in bdev_dax_supported() + - dm: set QUEUE_FLAG_DAX accordingly in dm_table_set_restrictions() + - dm: prevent DAX mounts if not supported + - mtd: cfi_cmdset_0002: Change definition naming to retry write operation + - mtd: cfi_cmdset_0002: Change erase functions to retry for error + - mtd: cfi_cmdset_0002: Change erase functions to check chip good only + - netfilter: nf_log: don't hold nf_log_mutex during user access + - staging: comedi: quatech_daqp_cs: fix no-op loop daqp_ao_insn_write() + - sched, tracing: Fix trace_sched_pi_setprio() for deboosting + - PCI / ACPI / PM: Resume bridges w/o drivers on suspend-to-RAM + - drm/amdgpu: Make struct amdgpu_atif private to amdgpu_acpi.c + - scsi: aacraid: Fix PD performance regression over incorrect qd being set + - ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl + - drm/amdgpu: Add amdgpu_atpx_get_dhandle() + - drm/amdgpu: Dynamically probe for ATIF handle (v2) + - i2c: core: smbus: fix a potential missing-check bug + * Bionic update: upstream stable patchset 2018-12-12 (LP: #1808185) + - usb: cdc_acm: Add quirk for Uniden UBC125 scanner + - USB: serial: cp210x: add CESINEL device ids + - USB: serial: cp210x: add Silicon Labs IDs for Windows Update + - usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub + - acpi: Add helper for deactivating memory region + - usb: typec: ucsi: acpi: Workaround for cache mode issue + - usb: typec: ucsi: Fix for incorrect status data issue + - xhci: Fix kernel oops in trace_xhci_free_virt_device + - n_tty: Fix stall at n_tty_receive_char_special(). + - n_tty: Access echo_* variables carefully. + - staging: android: ion: Return an ERR_PTR in ion_map_kernel + - serial: 8250_pci: Remove stalled entries in blacklist + - serdev: fix memleak on module unload + - vt: prevent leaking uninitialized data to userspace via /dev/vcs* + - drm/amdgpu: Add APU support in vi_set_uvd_clocks + - drm/amdgpu: Add APU support in vi_set_vce_clocks + - drm/amdgpu: fix the missed vcn fw version report + - drm/qxl: Call qxl_bo_unref outside atomic context + - drm/atmel-hlcdc: check stride values in the first plane + - drm/amdgpu: Use kvmalloc_array for allocating VRAM manager nodes array + - drm/amdgpu: Refactor amdgpu_vram_mgr_bo_invisible_size helper + - drm/i915: Enable provoking vertex fix on Gen9 systems. + - netfilter: nf_tables: nft_compat: fix refcount leak on xt module + - netfilter: nft_compat: prepare for indirect info storage + - netfilter: nft_compat: fix handling of large matchinfo size + - netfilter: nf_tables: don't assume chain stats are set when jumplabel is set + - netfilter: nf_tables: bogus EBUSY in chain deletions + - netfilter: nft_meta: fix wrong value dereference in nft_meta_set_eval + - netfilter: nf_tables: disable preemption in nft_update_chain_stats() + - netfilter: nf_tables: increase nft_counters_enabled in + nft_chain_stats_replace() + - netfilter: nf_tables: fix memory leak on error exit return + - netfilter: nf_tables: add missing netlink attrs to policies + - netfilter: nf_tables: fix NULL-ptr in nf_tables_dump_obj() + - netfilter: don't set F_IFACE on ipv6 fib lookups + - netfilter: ip6t_rpfilter: provide input interface for route lookup + - netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain() + - ARM: dts: imx6q: Use correct SDMA script for SPI5 core + - xfrm6: avoid potential infinite loop in _decode_session6() + - afs: Fix directory permissions check + - netfilter: ebtables: handle string from userspace with care + - s390/dasd: use blk_mq_rq_from_pdu for per request data + - netfilter: nft_limit: fix packet ratelimiting + - ipvs: fix buffer overflow with sync daemon and service + - iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs + - atm: zatm: fix memcmp casting + - net: qmi_wwan: Add Netgear Aircard 779S + - perf test: "Session topology" dumps core on s390 + - perf bpf: Fix NULL return handling in bpf__prepare_load() + - fs: clear writeback errors in inode_init_always + - sched/core: Fix rules for running on online && !active CPUs + - sched/core: Require cpu_active() in select_task_rq(), for user tasks + - platform/x86: asus-wmi: Fix NULL pointer dereference + - net/sonic: Use dma_mapping_error() + - net: dsa: b53: Add BCM5389 support + - usb: typec: tcpm: fix logbuffer index is wrong if _tcpm_log is re-entered + - iio: mma8452: Fix ignoring MMA8452_INT_DRDY + - drm/amdgpu: fix clear_all and replace handling in the VM (v2) + - drm/amd/display: Clear connector's edid pointer + - drm/i915/dp: Send DPCD ON for MST before phy_up + - drm/amdgpu: remove DC special casing for KB/ML + - drm/amdgpu: Don't default to DC support for Kaveri and older + - drm/amdgpu: GPU vs CPU page size fixes in amdgpu_vm_bo_split_mapping + - drm/amd/display: release spinlock before committing updates to stream + - drm/i915: Fix PIPESTAT irq ack on i965/g4x + - ARM64: dts: meson-gxl-s905x-p212: Add phy-supply for usb0 + - x86/mm: Don't free P4D table when it is folded at runtime + * Bionic update: upstream stable patchset 2018-12-07 (LP: #1807469) + - x86/spectre_v1: Disable compiler optimizations over + array_index_mask_nospec() + - x86/mce: Improve error message when kernel cannot recover + - x86/mce: Check for alternate indication of machine check recovery on Skylake + - x86/mce: Fix incorrect "Machine check from unknown source" message + - x86/mce: Do not overwrite MCi_STATUS in mce_no_way_out() + - x86: Call fixup_exception() before notify_die() in math_error() + - m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap() + - m68k/mac: Fix SWIM memory resource end address + - serial: sh-sci: Use spin_{try}lock_irqsave instead of open coding version + - signal/xtensa: Consistenly use SIGBUS in do_unaligned_user + - PM / Domains: Fix error path during attach in genpd + - PM / core: Fix supplier device runtime PM usage counter imbalance + - PM / OPP: Update voltage in case freq == old_freq + - usb: do not reset if a low-speed or full-speed device timed out + - 1wire: family module autoload fails because of upper/lower case mismatch. + - ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it + - ASoC: cs35l35: Add use_single_rw to regmap config + - ASoC: cirrus: i2s: Fix LRCLK configuration + - ASoC: cirrus: i2s: Fix {TX|RX}LinCtrlData setup + - thermal: bcm2835: Stop using printk format %pCr + - clk: renesas: cpg-mssr: Stop using printk format %pCr + - lib/vsprintf: Remove atomic-unsafe support for %pCr + - ftrace/selftest: Have the reset_trigger code be a bit more careful + - mips: ftrace: fix static function graph tracing + - branch-check: fix long->int truncation when profiling branches + - ipmi:bt: Set the timeout before doing a capabilities check + - Bluetooth: hci_qca: Avoid missing rampatch failure with userspace fw loader + - printk: fix possible reuse of va_list variable + - fuse: fix congested state leak on aborted connections + - fuse: atomic_o_trunc should truncate pagecache + - fuse: don't keep dead fuse_conn at fuse_fill_super(). + - fuse: fix control dir setup and teardown + - powerpc/mm/hash: Add missing isync prior to kernel stack SLB switch + - powerpc/ptrace: Fix setting 512B aligned breakpoints with + PTRACE_SET_DEBUGREG + - powerpc/ptrace: Fix enforcement of DAWR constraints + - powerpc/powernv/ioda2: Remove redundant free of TCE pages + - powerpc/powernv: copy/paste - Mask SO bit in CR + - powerpc/fadump: Unregister fadump on kexec down path. + - soc: rockchip: power-domain: Fix wrong value when power up pd with writemask + - ARM: 8764/1: kgdb: fix NUMREGBYTES so that gdb_regs[] is the correct size + - ARM: dts: Fix SPI node for Arria10 + - ARM: dts: socfpga: Fix NAND controller node compatible + - ARM: dts: socfpga: Fix NAND controller clock supply + - ARM: dts: socfpga: Fix NAND controller node compatible for Arria10 + - arm64: Fix syscall restarting around signal suppressed by tracer + - arm64: kpti: Use early_param for kpti= command-line option + - arm64: mm: Ensure writes to swapper are ordered wrt subsequent cache + maintenance + - ARM64: dts: meson: disable sd-uhs modes on the libretech-cc + - of: overlay: validate offset from property fixups + - of: unittest: for strings, account for trailing \0 in property length field + - of: platform: stop accessing invalid dev in of_platform_device_destroy + - tpm: fix use after free in tpm2_load_context() + - tpm: fix race condition in tpm_common_write() + - IB/qib: Fix DMA api warning with debug kernel + - IB/{hfi1, qib}: Add handling of kernel restart + - IB/mlx4: Mark user MR as writable if actual virtual memory is writable + - IB/core: Make testing MR flags for writability a static inline function + - IB/mlx5: Fetch soft WQE's on fatal error state + - IB/isert: Fix for lib/dma_debug check_sync warning + - IB/isert: fix T10-pi check mask setting + - IB/hfi1: Fix fault injection init/exit issues + - IB/hfi1: Reorder incorrect send context disable + - IB/hfi1: Optimize kthread pointer locking when queuing CQ entries + - IB/hfi1: Fix user context tail allocation for DMA_RTAIL + - RDMA/mlx4: Discard unknown SQP work requests + - xprtrdma: Return -ENOBUFS when no pages are available + - mtd: cfi_cmdset_0002: Change write buffer to check correct value + - mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock() + - mtd: cfi_cmdset_0002: fix SEGV unlocking multiple chips + - mtd: cfi_cmdset_0002: Fix unlocking requests crossing a chip boudary + - mtd: cfi_cmdset_0002: Avoid walking all chips when unlocking. + - PCI: hv: Make sure the bus domain is really unique + - PCI: Add ACS quirk for Intel 7th & 8th Gen mobile + - PCI: pciehp: Clear Presence Detect and Data Link Layer Status Changed on + resume + - auxdisplay: fix broken menu + - pinctrl: samsung: Correct EINTG banks order + - pinctrl: devicetree: Fix pctldev pointer overwrite + - cpufreq: intel_pstate: Fix scaling max/min limits with Turbo 3.0 + - MIPS: io: Add barrier after register read in inX() + - time: Make sure jiffies_to_msecs() preserves non-zero time periods + - irqchip/gic-v3-its: Don't bind LPI to unavailable NUMA node + - X.509: unpack RSA signatureValue field from BIT STRING + - Btrfs: fix return value on rename exchange failure + - iio: adc: ad7791: remove sample freq sysfs attributes + - iio: sca3000: Fix an error handling path in 'sca3000_probe()' + - mm: fix __gup_device_huge vs unmap + - scsi: qla2xxx: Fix setting lower transfer speed if GPSC fails + - scsi: qla2xxx: Mask off Scope bits in retry delay + - scsi: zfcp: fix missing SCSI trace for result of eh_host_reset_handler + - scsi: zfcp: fix missing SCSI trace for retry of abort / scsi_eh TMF + - scsi: zfcp: fix misleading REC trigger trace where erp_action setup failed + - scsi: zfcp: fix missing REC trigger trace on terminate_rport_io early return + - scsi: zfcp: fix missing REC trigger trace on terminate_rport_io for + ERP_FAILED + - scsi: zfcp: fix missing REC trigger trace for all objects in ERP_FAILED + - scsi: zfcp: fix missing REC trigger trace on enqueue without ERP thread + - linvdimm, pmem: Preserve read-only setting for pmem devices + - clk: at91: PLL recalc_rate() now using cached MUL and DIV values + - rtc: sun6i: Fix bit_idx value for clk_register_gate + - md: fix two problems with setting the "re-add" device state. + - rpmsg: smd: do not use mananged resources for endpoints and channels + - ubi: fastmap: Cancel work upon detach + - ubi: fastmap: Correctly handle interrupted erasures in EBA + - backlight: as3711_bl: Fix Device Tree node lookup + - backlight: max8925_bl: Fix Device Tree node lookup + - backlight: tps65217_bl: Fix Device Tree node lookup + - mfd: intel-lpss: Program REMAP register in PIO mode + - arm: dts: mt7623: fix invalid memory node being generated + - perf tools: Fix symbol and object code resolution for vdso32 and vdsox32 + - perf intel-pt: Fix sync_switch INTEL_PT_SS_NOT_TRACING + - perf intel-pt: Fix decoding to accept CBR between FUP and corresponding TIP + - perf intel-pt: Fix MTC timing after overflow + - perf intel-pt: Fix "Unexpected indirect branch" error + - perf intel-pt: Fix packet decoding of CYC packets + - media: vsp1: Release buffers for each video node + - media: v4l2-compat-ioctl32: prevent go past max size + - media: dvb_frontend: fix locking issues at dvb_frontend_get_event() + - nfsd: restrict rd_maxcount to svc_max_payload in nfsd_encode_readdir + - NFSv4: Fix possible 1-byte stack overflow in + nfs_idmap_read_and_verify_message + - NFSv4: Revert commit 5f83d86cf531d ("NFSv4.x: Fix wraparound issues..") + - NFSv4: Fix a typo in nfs41_sequence_process + - ACPI / LPSS: Add missing prv_offset setting for byt/cht PWM devices + - Input: elan_i2c - add ELAN0618 (Lenovo v330 15IKB) ACPI ID + - pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume + - rbd: flush rbd_dev->watch_dwork after watch is unregistered + - mm/ksm.c: ignore STABLE_FLAG of rmap_item->address in rmap_walk_ksm() + - mm: fix devmem_is_allowed() for sub-page System RAM intersections + - xen: Remove unnecessary BUG_ON from __unbind_from_irq() + - udf: Detect incorrect directory size + - Input: xpad - fix GPD Win 2 controller name + - Input: elan_i2c_smbus - fix more potential stack buffer overflows + - ALSA: timer: Fix UBSAN warning at SNDRV_TIMER_IOCTL_NEXT_DEVICE ioctl + - ALSA: hda/realtek - Fix pop noise on Lenovo P50 & co + - ALSA: hda/realtek - Add a quirk for FSC ESPRIMO U9210 + - slub: fix failure when we delete and create a slab cache + - block: Fix transfer when chunk sectors exceeds max + - block: Fix cloning of requests with a special payload + - x86/efi: Fix efi_call_phys_epilog() with CONFIG_X86_5LEVEL=y + - dm zoned: avoid triggering reclaim from inside dmz_map() + - dm thin: handle running out of data space vs concurrent discard + - x86/platform/UV: Use new set memory block size function + - x86/platform/UV: Add kernel parameter to set memory block size + - platform/chrome: cros_ec_lpc: Register the driver if ACPI entry is missing. + - platform/chrome: cros_ec_lpc: do not try DMI match when ACPI device found + - hwmon: (k10temp) Add support for Stoney Ridge and Bristol Ridge CPUs + - spi-nor: intel-spi: Remove unused preopcodes field + - mtd: spi-nor: intel-spi: Fix atomic sequence handling + - PCI / PM: Do not clear state_saved for devices that remain suspended + - ASoC: mediatek: preallocate pages use platform device + - libnvdimm, pmem: Do not flush power-fail protected CPU caches + - powerpc/64s: Set assembler machine type to POWER4 + - powerpc/e500mc: Set assembler machine type to e500mc + - hwrng: core - Always drop the RNG in hwrng_unregister() + - softirq: Reorder trace_softirqs_on to prevent lockdep splat + - ARM64: dts: meson-gx: fix ATF reserved memory region + - mtd: rawnand: fix return value check for bad block status + - mtd: rawnand: mxc: set spare area size register explicitly + - PCI: Account for all bridges on bus when distributing bus numbers + - pinctrl: armada-37xx: Fix spurious irq management + - MIPS: pb44: Fix i2c-gpio GPIO descriptor table + - locking/rwsem: Fix up_read_non_owner() warning with DEBUG_RWSEMS + - scsi: scsi_debug: Fix memory leak on module unload + - scsi: qla2xxx: Spinlock recursion in qla_target + - libnvdimm, pmem: Unconditionally deep flush on *sync + - f2fs: don't use GFP_ZERO for page caches + - mfd: twl-core: Fix clock initialization + - remoteproc: Prevent incorrect rproc state on xfer mem ownership failure + - media: rc: mce_kbd decoder: fix stuck keys + - Input: silead - add Chuwi Hi8 support + - Input: silead - add MSSL0002 ACPI HID + - ALSA: hda - Force to link down at runtime suspend on ATI/AMD HDMI + - i2c: gpio: initialize SCL to HIGH again + - kasan: depend on CONFIG_SLUB_DEBUG + - dm: ensure bio submission follows a depth-first tree walk + - dm: rename 'bio' member of dm_io structure to 'orig_bio' + - dm: use bio_split() when splitting out the already processed bio + - x86/e820: put !E820_TYPE_RAM regions into memblock.reserved + * Support AverMedia DVD EZMaker 7 USB video capture dongle (LP: #1620762) // + Bionic update: upstream stable patchset 2018-12-07 (LP: #1807469) + - media: cx231xx: Add support for AverMedia DVD EZMaker 7 + + -- Kleber Sacilotto de Souza Tue, 15 Jan 2019 11:45:59 +0000 + +linux-oracle (4.15.0-1007.9) bionic; urgency=medium + + * linux-oracle: 4.15.0-1007.9 -proposed tracker (LP: #1807702) + + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Config] buildinfo -- add retpoline version markers + + * Skip enslaved devices during boot (LP: #1802591) + - [Packaging] initramfs-tools -- include custom hooks for a kernel + - [Packaging] linux-oracle: add initramfs hook to skip enslaved devices + - [Packaging] linux-oracle: Force initramfs-tools >= 0.130ubuntu3.6 + + * Packaging resync (LP: #1786013) + - [Packaging] update update.conf + + [ Ubuntu: 4.15.0-43.46 ] + + * linux: 4.15.0-43.46 -proposed tracker (LP: #1806659) + * System randomly hangs during suspend when mei_wdt is loaded (LP: #1803942) + - SAUCE: base/dd: limit release function changes to vfio driver only + * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838) + - xhci: Allow more than 32 quirks + - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] limit preparation to linux-libc-dev in headers + - [Packaging] commonise debhelper invocation + - [Packaging] ABI -- accumulate abi information at the end of the build + - [Packaging] buildinfo -- add basic build information + - [Packaging] buildinfo -- add firmware information to the flavour ABI + - [Packaging] buildinfo -- add compiler information to the flavour ABI + - [Packaging] buildinfo -- add buildinfo support to getabis + - [Config] buildinfo -- add retpoline version markers + * linux packages should own /usr/lib/linux/triggers (LP: #1770256) + - [Packaging] own /usr/lib/linux/triggers + * CVE-2018-12896 + - posix-timers: Sanitize overrun handling + * CVE-2018-16276 + - USB: yurex: fix out-of-bounds uaccess in read handler + * CVE-2018-10902 + - ALSA: rawmidi: Change resized buffers atomically + * CVE-2018-18710 + - cdrom: fix improper type cast, which can leat to information leak. + * CVE-2018-18690 + - xfs: don't fail when converting shortform attr to long form during + ATTR_REPLACE + * CVE-2018-14734 + - infiniband: fix a possible use-after-free bug + * CVE-2018-18445 + - bpf: 32-bit RSH verification must truncate input before the ALU op + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Marcelo Henrique Cerri Wed, 12 Dec 2018 16:48:11 -0200 + +linux-oracle (4.15.0-1006.6) bionic; urgency=medium + + * linux-oracle: 4.15.0-1006.6 -proposed tracker (LP: #1806098) + + [ Ubuntu: 4.15.0-42.45 ] + + * linux: 4.15.0-42.45 -proposed tracker (LP: #1803592) + * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405) + - KVM: s390: reset crypto attributes for all vcpus + - KVM: s390: vsie: simulate VCPU SIE entry/exit + - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART + - KVM: s390: refactor crypto initialization + - s390: vfio-ap: base implementation of VFIO AP device driver + - s390: vfio-ap: register matrix device with VFIO mdev framework + - s390: vfio-ap: sysfs interfaces to configure adapters + - s390: vfio-ap: sysfs interfaces to configure domains + - s390: vfio-ap: sysfs interfaces to configure control domains + - s390: vfio-ap: sysfs interface to view matrix mdev matrix + - KVM: s390: interface to clear CRYCB masks + - s390: vfio-ap: implement mediated device open callback + - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl + - s390: vfio-ap: zeroize the AP queues + - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl + - KVM: s390: Clear Crypto Control Block when using vSIE + - KVM: s390: vsie: Do the CRYCB validation first + - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear + - KVM: s390: vsie: Allow CRYCB FORMAT-2 + - KVM: s390: vsie: allow CRYCB FORMAT-1 + - KVM: s390: vsie: allow CRYCB FORMAT-0 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1 + - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2 + - KVM: s390: device attrs to enable/disable AP interpretation + - KVM: s390: CPU model support for AP virtualization + - s390: doc: detailed specifications for AP virtualization + - KVM: s390: fix locking for crypto setting error path + - KVM: s390: Tracing APCB changes + - s390: vfio-ap: setup APCB mask using KVM dedicated function + - s390/zcrypt: Add ZAPQ inline function. + - s390/zcrypt: Review inline assembler constraints. + - s390/zcrypt: Integrate ap_asm.h into include/asm/ap.h. + - s390/zcrypt: fix ap_instructions_available() returncodes + - s390/zcrypt: remove VLA usage from the AP bus + - s390/zcrypt: Remove deprecated ioctls. + - s390/zcrypt: Remove deprecated zcrypt proc interface. + - s390/zcrypt: Support up to 256 crypto adapters. + - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module. + * Bypass of mount visibility through userns + mount propagation (LP: #1789161) + - mount: Retest MNT_LOCKED in do_umount + - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts + * CVE-2018-18955: nested user namespaces with more than five extents + incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955 + - userns: also map extents in the reverse map to kernel IDs + * kdump fail due to an IRQ storm (LP: #1797990) + - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code + - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot + - SAUCE: x86/quirks: Scan all busses for early PCI quirks + + [ Ubuntu: 4.15.0-40.43 ] + + * linux: 4.15.0-40.43 -proposed tracker (LP: #1802554) + * crash in ENA driver on removing an interface (LP: #1802341) + - SAUCE: net: ena: fix crash during ena_remove() + * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding + (LP: #1797367) + - s390/qeth: don't keep track of MAC address's cast type + - s390/qeth: consolidate qeth MAC address helpers + - s390/qeth: avoid using is_multicast_ether_addr_64bits on (u8 *)[6] + - s390/qeth: remove outdated portname debug msg + - s390/qeth: reduce hard-coded access to ccw channels + - s390/qeth: sanitize strings in debug messages + * [18.04 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver + binding (LP: #1799184) + - s390/zcrypt: code beautify + - s390/zcrypt: AP bus support for alternate driver(s) + - s390/zcrypt: hex string mask improvements for apmask and aqmask. + - s390/zcrypt: remove unused functions and declarations + - s390/zcrypt: Show load of cards and queues in sysfs + * [GLK/CLX] Enhanced IBRS (LP: #1786139) + - x86/speculation: Remove SPECTRE_V2_IBRS in enum spectre_v2_mitigation + - x86/speculation: Support Enhanced IBRS on future CPUs + * Allow signed kernels to be kexec'ed under lockdown (LP: #1798441) + - Fix kexec forbidding kernels signed with keys in the secondary keyring to + boot + * Overlayfs in user namespace leaks directory content of inaccessible + directories (LP: #1793458) // CVE-2018-6559 + - SAUCE: overlayfs: ensure mounter privileges when reading directories + * Update ENA driver to version 2.0.1K (LP: #1798182) + - net: ena: remove ndo_poll_controller + - net: ena: fix warning in rmmod caused by double iounmap + - net: ena: fix rare bug when failed restart/resume is followed by driver + removal + - net: ena: fix NULL dereference due to untimely napi initialization + - net: ena: fix auto casting to boolean + - net: ena: minor performance improvement + - net: ena: complete host info to match latest ENA spec + - net: ena: introduce Low Latency Queues data structures according to ENA spec + - net: ena: add functions for handling Low Latency Queues in ena_com + - net: ena: add functions for handling Low Latency Queues in ena_netdev + - net: ena: use CSUM_CHECKED device indication to report skb's checksum status + - net: ena: explicit casting and initialization, and clearer error handling + - net: ena: limit refill Rx threshold to 256 to avoid latency issues + - net: ena: change rx copybreak default to reduce kernel memory pressure + - net: ena: remove redundant parameter in ena_com_admin_init() + - net: ena: update driver version to 2.0.1 + - net: ena: fix indentations in ena_defs for better readability + - net: ena: Fix Kconfig dependency on X86 + - net: ena: enable Low Latency Queues + - net: ena: fix compilation error in xtensa architecture + * Bionic update: upstream stable patchset 2018-10-29 (LP: #1800537) + - bonding: re-evaluate force_primary when the primary slave name changes + - cdc_ncm: avoid padding beyond end of skb + - ipv6: allow PMTU exceptions to local routes + - net: dsa: add error handling for pskb_trim_rcsum + - net/sched: act_simple: fix parsing of TCA_DEF_DATA + - tcp: verify the checksum of the first data segment in a new connection + - udp: fix rx queue len reported by diag and proc interface + - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds + vlan + - tls: fix use-after-free in tls_push_record + - ext4: fix hole length detection in ext4_ind_map_blocks() + - ext4: update mtime in ext4_punch_hole even if no blocks are released + - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget() + - ext4: fix fencepost error in check for inode count overflow during resize + - driver core: Don't ignore class_dir_create_and_add() failure. + - Btrfs: fix clone vs chattr NODATASUM race + - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2() + - btrfs: return error value if create_io_em failed in cow_file_range + - btrfs: scrub: Don't use inode pages for device replace + - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation + - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() + - ALSA: hda: add dock and led support for HP EliteBook 830 G5 + - ALSA: hda: add dock and led support for HP ProBook 640 G4 + - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read() + - smb3: fix various xid leaks + - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session + expiry + - cifs: For SMB2 security informaion query, check for minimum sized security + descriptor instead of sizeof FileAllInformation class + - nbd: fix nbd device deletion + - nbd: update size when connected + - nbd: use bd_set_size when updating disk size + - blk-mq: reinit q->tag_set_list entry only after grace period + - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue + - cpufreq: Fix new policy initialization during limits updates via sysfs + - cpufreq: governors: Fix long idle detection logic in load calculation + - libata: zpodd: small read overflow in eject_tray() + - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk + - w1: mxc_w1: Enable clock before calling clk_get_rate() on it + - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping + - iwlwifi: fw: harden page loading code + - orangefs: set i_size on new symlink + - orangefs: report attributes_mask and attributes for statx + - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation + - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large + - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset + - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620 + - cpufreq: ti-cpufreq: Fix an incorrect error return value + - x86/vector: Fix the args of vector_alloc tracepoint + - x86/apic/vector: Prevent hlist corruption and leaks + - x86/apic: Provide apic_ack_irq() + - x86/ioapic: Use apic_ack_irq() + - x86/platform/uv: Use apic_ack_irq() + - irq_remapping: Use apic_ack_irq() + - genirq/generic_pending: Do not lose pending affinity update + - genirq/affinity: Defer affinity setting if irq chip is busy + - genirq/migration: Avoid out of line call if pending is not set + * [bionic]mlx5: reading SW stats through ifstat cause kernel crash + (LP: #1799049) + - net/mlx5e: Don't attempt to dereference the ppriv struct if not being + eswitch manager + * [Bionic][Cosmic] ipmi: Fix timer race with module unload (LP: #1799281) + - ipmi: Fix timer race with module unload + * [Bionic] ipmi: Remove ACPI SPMI probing from the SSIF (I2C) driver + (LP: #1799276) + - ipmi: Remove ACPI SPMI probing from the SSIF (I2C) driver + * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729) + - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias() + * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater + than 255 bytes (LP: #1799794) + - ipmi:ssif: Add support for multi-part transmit messages > 2 parts + * libvirtd is unable to configure bridge devices inside of LXD containers + (LP: #1784501) + - kernfs: allow creating kernfs objects with arbitrary uid/gid + - sysfs, kobject: allow creating kobject belonging to arbitrary users + - kobject: kset_create_and_add() - fetch ownership info from parent + - driver core: set up ownership of class devices in sysfs + - net-sysfs: require net admin in the init ns for setting tx_maxrate + - net-sysfs: make sure objects belong to container's owner + - net: create reusable function for getting ownership info of sysfs inodes + - bridge: make sure objects belong to container's owner + - sysfs: Fix regression when adding a file to an existing group + * [Ubuntu] kvm: fix deadlock when killed by oom (LP: #1800849) + - s390/kvm: fix deadlock when killed by oom + * [Ubuntu] net/af_iucv: fix skb leaks for HiperTransport (LP: #1800639) + - net/af_iucv: drop inbound packets with invalid flags + - net/af_iucv: fix skb handling on HiperTransport xmit error + * Power consumption during s2idle is higher than long idle(sk hynix) + (LP: #1801875) + - SAUCE: pci: prevent sk hynix nvme from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + * Enable keyboard wakeup for S2Idle laptops (LP: #1798552) + - Input: i8042 - enable keyboard wakeups by default when s2idle is used + * NULL pointer dereference at 0000000000000020 when access + dst_orig->ops->family in function xfrm_lookup_with_ifid() (LP: #1801878) + - xfrm: Fix NULL pointer dereference when skb_dst_force clears the dst_entry. + * [Ubuntu] qdio: reset old sbal_state flags (LP: #1801686) + - s390/qdio: reset old sbal_state flags + * hns3: map tx ring to tc (LP: #1802023) + - net: hns3: Set tx ring' tc info when netdev is up + * [Ubuntu] qeth: Fix potential array overrun in cmd/rc lookup (LP: #1800641) + - s390: qeth_core_mpc: Use ARRAY_SIZE instead of reimplementing its function + - s390: qeth: Fix potential array overrun in cmd/rc lookup + * Vulkan applications cause permanent memory leak with Intel GPU + (LP: #1798165) + - drm/syncobj: Don't leak fences when WAIT_FOR_SUBMIT is set + * Mounting SOFS SMB shares fails (LP: #1792580) + - cifs: connect to servername instead of IP for IPC$ share + * Packaging resync (LP: #1786013) + - [Package] add support for specifying the primary makefile + + -- Marcelo Henrique Cerri Fri, 30 Nov 2018 15:33:38 -0200 + +linux-oracle (4.15.0-1005.5) bionic; urgency=medium + + * linux-oracle: 4.15.0-1005.5 -proposed tracker (LP: #1799800) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to Ubuntu-4.15.0-39.42 + + [ Ubuntu: 4.15.0-39.42 ] + + * linux: 4.15.0-39.42 -proposed tracker (LP: #1799411) + * Linux: insufficient shootdown for paging-structure caches (LP: #1798897) + - mm: move tlb_table_flush to tlb_flush_mmu_free + - mm/tlb: Remove tlb_remove_table() non-concurrent condition + - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE + - [Config] CONFIG_HAVE_RCU_TABLE_INVALIDATE=y + * Ubuntu18.04: GPU total memory is reduced (LP: #1792102) + - Revert "powerpc/powernv: Increase memory block size to 1GB on radix" + * arm64: snapdragon: reduce boot noise (LP: #1797154) + - [Config] arm64: snapdragon: DRM_MSM=m + - [Config] arm64: snapdragon: SND*=m + - [Config] arm64: snapdragon: disable ARM_SDE_INTERFACE + - [Config] arm64: snapdragon: disable DRM_I2C_ADV7511_CEC + - [Config] arm64: snapdragon: disable VIDEO_ADV7511, VIDEO_COBALT + * [Bionic] CPPC bug fixes (LP: #1796949) + - ACPI / CPPC: Update all pr_(debug/err) messages to log the susbspace id + - cpufreq: CPPC: Don't set transition_latency + - ACPI / CPPC: Fix invalid PCC channel status errors + * regression in 'ip --family bridge neigh' since linux v4.12 (LP: #1796748) + - rtnetlink: fix rtnl_fdb_dump() for ndmsg header + * screen displays abnormally on the lenovo M715 with the AMD GPU (Radeon Vega + 8 Mobile, rev ca, 1002:15dd) (LP: #1796786) + - drm/amd/display: Fix takover from VGA mode + - drm/amd/display: early return if not in vga mode in disable_vga + - drm/amd/display: Refine disable VGA + * arm64: snapdragon: WARNING: CPU: 0 PID: 1 arch/arm64/kernel/setup.c:271 + reserve_memblock_reserved_regions (LP: #1797139) + - SAUCE: arm64: Fix /proc/iomem for reserved but not memory regions + * The front MIC can't work on the Lenovo M715 (LP: #1797292) + - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715 + * Keyboard backlight sysfs sometimes is missing on Dell laptops (LP: #1797304) + - platform/x86: dell-smbios: Correct some style warnings + - platform/x86: dell-smbios: Rename dell-smbios source to dell-smbios-base + - platform/x86: dell-smbios: Link all dell-smbios-* modules together + - [Config] CONFIG_DELL_SMBIOS_SMM=y, CONFIG_DELL_SMBIOS_WMI=y + * rpi3b+: ethernet not working (LP: #1797406) + - lan78xx: Don't reset the interface on open + * 87cdf3148b11 was never backported to 4.15 (LP: #1795653) + - xfrm: Verify MAC header exists before overwriting eth_hdr(skb)->h_proto + * [Ubuntu18.04][Power9][DD2.2]package installation segfaults inside debian + chroot env in P9 KVM guest with HTM enabled (kvm) (LP: #1792501) + - KVM: PPC: Book3S HV: Fix guest r11 corruption with POWER9 TM workarounds + * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957) + - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same + VM + * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314) + - SAUCE: fscache: Fix race in decrementing refcount of op->npages + * CVE-2018-9363 + - Bluetooth: hidp: buffer overflow in hidp_process_report + * CVE-2017-13168 + - scsi: sg: mitigate read/write abuse + * [Bionic] ACPI / PPTT: use ACPI ID whenever ACPI_PPTT_ACPI_PROCESSOR_ID_VALID + is set (LP: #1797200) + - ACPI / PPTT: use ACPI ID whenever ACPI_PPTT_ACPI_PROCESSOR_ID_VALID is set + * [Bionic] arm64: topology: Avoid checking numa mask for scheduler MC + selection (LP: #1797202) + - arm64: topology: Avoid checking numa mask for scheduler MC selection + * crypto/vmx - Backport of Fix sleep-in-atomic bugs patch for 18.04 + (LP: #1790832) + - crypto: vmx - Fix sleep-in-atomic bugs + * hns3: autoneg settings get lost on down/up (LP: #1797654) + - net: hns3: Fix for information of phydev lost problem when down/up + * not able to unwind the stack from within __kernel_clock_gettime in the Linux + vDSO (LP: #1797963) + - powerpc/vdso: Correct call frame information + * Signal 7 error when running GPFS tracing in cluster (LP: #1792195) + - powerpc/mm/books3s: Add new pte bit to mark pte temporarily invalid. + - powerpc/mm/radix: Only need the Nest MMU workaround for R -> RW transition + * Support Edge Gateway's WIFI LED (LP: #1798330) + - SAUCE: mwifiex: Switch WiFi LED state according to the device status + * Support Edge Gateway's Bluetooth LED (LP: #1798332) + - SAUCE: Bluetooth: Support for LED on Edge Gateways + * USB cardreader (0bda:0328) make the system can't enter s3 or hang + (LP: #1798328) + - usb: Don't disable Latency tolerance Messaging (LTM) before port reset + * CVE-2018-15471 + - xen-netback: fix input validation in xenvif_set_hash_mapping() + * CVE-2018-16658 + - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status + * [Bionic] Update ThunderX2 implementation defined pmu core events + (LP: #1796904) + - perf vendor events arm64: Update ThunderX2 implementation defined pmu core + events + * the machine of lenovo M715 with the AMD GPU (Radeon Vega 8 Mobile, rev ca, + 1002:15dd) often hangs randomly (LP: #1796789) + - drm/amd: Add missing fields in atom_integrated_system_info_v1_11 + * [18.04] GLK hang after a while (LP: #1760545) + - drm/i915/glk: Add MODULE_FIRMWARE for Geminilake + * Fix usbcore.quirks when used at boot (LP: #1795784) + - usb: core: safely deal with the dynamic quirk lists + + -- Marcelo Henrique Cerri Wed, 24 Oct 2018 20:56:51 -0300 + +linux-oracle (4.15.0-1004.4) bionic; urgency=medium + + * linux-oracle: 4.15.0-1004.4 -proposed tracker (LP: #1799093) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to Ubuntu-4.15.0-38.41 + + [ Ubuntu: 4.15.0-38.41 ] + + * linux: 4.15.0-38.41 -proposed tracker (LP: #1797061) + * Silent data corruption in Linux kernel 4.15 (LP: #1796542) + - block: add a lower-level bio_add_page interface + - block: bio_iov_iter_get_pages: fix size of last iovec + - blkdev: __blkdev_direct_IO_simple: fix leak in error case + - block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs + + [ Ubuntu: 4.15.0-37.40 ] + + * linux: 4.15.0-37.40 -proposed tracker (LP: #1795564) + * hns3: enable ethtool rx-vlan-filter on supported hw (LP: #1793394) + - net: hns3: Add vlan filter setting by ethtool command -K + * hns3: Modifying channel parameters will reset ring parameters back to + defaults (LP: #1793404) + - net: hns3: Fix desc num set to default when setting channel + * hisi_sas: Add SATA FIX check for v3 hw (LP: #1794151) + - scsi: hisi_sas: Add SATA FIS check for v3 hw + * Fix potential corruption using SAS controller on HiSilicon arm64 boards + (LP: #1794156) + - scsi: hisi_sas: add memory barrier in task delivery function + * hisi_sas: Reduce unnecessary spin lock contention (LP: #1794165) + - scsi: hisi_sas: Tidy hisi_sas_task_prep() + * Add functional level reset support for the SAS controller on HiSilicon D06 + systems (LP: #1794166) + - scsi: hisi_sas: tidy host controller reset function a bit + - scsi: hisi_sas: relocate some common code for v3 hw + - scsi: hisi_sas: Implement handlers of PCIe FLR for v3 hw + * HiSilicon SAS controller doesn't recover from PHY STP link timeout + (LP: #1794172) + - scsi: hisi_sas: tidy channel interrupt handler for v3 hw + - scsi: hisi_sas: Fix the failure of recovering PHY from STP link timeout + * getxattr: always handle namespaced attributes (LP: #1789746) + - getxattr: use correct xattr length + * Fix unusable NVIDIA GPU after S3 (LP: #1793338) + - PCI: Reprogram bridge prefetch registers on resume + * Fails to boot under Xen PV: BUG: unable to handle kernel paging request at + edc21fd9 (LP: #1789118) + - x86/EISA: Don't probe EISA bus for Xen PV guests + * qeth: use vzalloc for QUERY OAT buffer (LP: #1793086) + - s390/qeth: use vzalloc for QUERY OAT buffer + * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463) + - Input: elantech - enable middle button of touchpad on ThinkPad P72 + * Dell new AIO requires a new uart backlight driver (LP: #1727235) + - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO + - updateconfigs for Dell UART backlight driver + * [Ubuntu] s390/crypto: Fix return code checking in cbc_paes_crypt. + (LP: #1794294) + - s390/crypto: Fix return code checking in cbc_paes_crypt() + * hns3: Retrieve RoCE MSI-X config from firmware (LP: #1793221) + - net: hns3: Fix MSIX allocation issue for VF + - net: hns3: Refine the MSIX allocation for PF + * net: hns: Avoid hang when link is changed while handling packets + (LP: #1792209) + - net: hns: add the code for cleaning pkt in chip + - net: hns: add netif_carrier_off before change speed and duplex + * Page leaking in cachefiles_read_backing_file while vmscan is active + (LP: #1793430) + - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan + is active + * some nvidia p1000 graphic cards hang during the boot (LP: #1791569) + - drm/nouveau/gr/gf100-: virtualise tpc_mask + apply fixes from traces + * Error reported when creating ZFS pool with "-t" option, despite successful + pool creation (LP: #1769937) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.4 + * Fix I2C touchpanels' interrupt storms after system suspend (LP: #1792309) + - HID: i2c-hid: Fix flooded incomplete report after S3 on Rayd touchscreen + - HID: i2c-hid: Don't reset device upon system resume + * ipmmu is always registered (LP: #1783746) + - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU- + VMSA + * Bionic update: upstream stable patchset 2018-09-27 (LP: #1794889) + - clocksource/drivers/imx-tpm: Correct some registers operation flow + - Input: synaptics-rmi4 - fix an unchecked out of memory error path + - KVM: X86: fix incorrect reference of trace_kvm_pi_irte_update + - x86: Add check for APIC access address for vmentry of L2 guests + - MIPS: io: Prevent compiler reordering writeX() + - nfp: ignore signals when communicating with management FW + - perf report: Fix switching to another perf.data file + - fsnotify: fix ignore mask logic in send_to_group() + - MIPS: io: Add barrier after register read in readX() + - s390/smsgiucv: disable SMSG on module unload + - isofs: fix potential memory leak in mount option parsing + - MIPS: dts: Boston: Fix PCI bus dtc warnings: + - spi: sh-msiof: Fix bit field overflow writes to TSCR/RSCR + - doc: Add vendor prefix for Kieback & Peter GmbH + - dt-bindings: pinctrl: sunxi: Fix reference to driver + - dt-bindings: serial: sh-sci: Add support for r8a77965 (H)SCIF + - dt-bindings: dmaengine: rcar-dmac: document R8A77965 support + - clk: honor CLK_MUX_ROUND_CLOSEST in generic clk mux + - ASoC: rt5514: Add the missing register in the readable table + - eCryptfs: don't pass up plaintext names when using filename encryption + - soc: bcm: raspberrypi-power: Fix use of __packed + - soc: bcm2835: Make !RASPBERRYPI_FIRMWARE dummies return failure + - PCI: kirin: Fix reset gpio name + - ASoC: topology: Fix bugs of freeing soc topology + - xen: xenbus_dev_frontend: Really return response string + - ASoC: topology: Check widget kcontrols before deref. + - spi: cadence: Add usleep_range() for cdns_spi_fill_tx_fifo() + - blkcg: don't hold blkcg lock when deactivating policy + - tipc: fix infinite loop when dumping link monitor summary + - scsi: iscsi: respond to netlink with unicast when appropriate + - scsi: megaraid_sas: Do not log an error if FW successfully initializes. + - scsi: target: fix crash with iscsi target and dvd + - netfilter: nf_tables: NAT chain and extensions require NF_TABLES + - netfilter: nf_tables: fix out-of-bounds in nft_chain_commit_update + - ASoC: msm8916-wcd-analog: use threaded context for mbhc events + - drm/msm: Fix possible null dereference on failure of get_pages() + - drm/msm/dsi: use correct enum in dsi_get_cmd_fmt + - drm/msm: don't deref error pointer in the msm_fbdev_create error path + - blkcg: init root blkcg_gq under lock + - vfs: Undo an overly zealous MS_RDONLY -> SB_RDONLY conversion + - parisc: time: Convert read_persistent_clock() to read_persistent_clock64() + - scsi: storvsc: Set up correct queue depth values for IDE devices + - scsi: isci: Fix infinite loop in while loop + - mm, pagemap: fix swap offset value for PMD migration entry + - proc: revalidate kernel thread inodes to root:root + - kexec_file: do not add extra alignment to efi memmap + - mm: memcg: add __GFP_NOWARN in __memcg_schedule_kmem_cache_create() + - usb: typec: ucsi: fix tracepoint related build error + - ACPI / PM: Blacklist Low Power S0 Idle _DSM for ThinkPad X1 Tablet(2016) + - dt-bindings: meson-uart: DT fix s/clocks-names/clock-names/ + - net: phy: marvell: clear wol event before setting it + - ARM: dts: da850: fix W=1 warnings with pinmux node + - ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70 + - drm/amdkfd: fix clock counter retrieval for node without GPU + - thermal: int3403_thermal: Fix NULL pointer deref on module load / probe + - net: ethtool: Add missing kernel doc for FEC parameters + - arm64: ptrace: remove addr_limit manipulation + - HID: lenovo: Add support for IBM/Lenovo Scrollpoint mice + - HID: wacom: Release device resource data obtained by devres_alloc() + - selftests: ftrace: Add a testcase for multiple actions on trigger + - rds: ib: Fix missing call to rds_ib_dev_put in rds_ib_setup_qp + - perf/x86/intel: Don't enable freeze-on-smi for PerfMon V1 + - remoteproc: qcom: Fix potential device node leaks + - rpmsg: added MODULE_ALIAS for rpmsg_char + - HID: intel-ish-hid: use put_device() instead of kfree() + - blk-mq: fix sysfs inflight counter + - arm64: fix possible spectre-v1 in ptrace_hbp_get_event() + - KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_mmio_read_apr() + - libahci: Allow drivers to override stop_engine + - ata: ahci: mvebu: override ahci_stop_engine for mvebu AHCI + - x86/cpu/intel: Add missing TLB cpuid values + - bpf: fix uninitialized variable in bpf tools + - i2c: sprd: Prevent i2c accesses after suspend is called + - i2c: sprd: Fix the i2c count issue + - tipc: fix bug in function tipc_nl_node_dump_monitor + - nvme: depend on INFINIBAND_ADDR_TRANS + - nvmet-rdma: depend on INFINIBAND_ADDR_TRANS + - ib_srpt: depend on INFINIBAND_ADDR_TRANS + - ib_srp: depend on INFINIBAND_ADDR_TRANS + - IB: make INFINIBAND_ADDR_TRANS configurable + - IB/uverbs: Fix validating mandatory attributes + - RDMA/cma: Fix use after destroy access to net namespace for IPoIB + - RDMA/iwpm: fix memory leak on map_info + - IB/rxe: add RXE_START_MASK for rxe_opcode IB_OPCODE_RC_SEND_ONLY_INV + - IB/rxe: avoid double kfree_skb + - : fix end_name_hash() for 64bit long + - IB/core: Make ib_mad_client_id atomic + - ARM: davinci: board-da830-evm: fix GPIO lookup for MMC/SD + - ARM: davinci: board-da850-evm: fix GPIO lookup for MMC/SD + - ARM: davinci: board-omapl138-hawk: fix GPIO numbers for MMC/SD lookup + - ARM: davinci: board-dm355-evm: fix broken networking + - dt-bindings: panel: lvds: Fix path to display timing bindings + - ARM: OMAP2+: powerdomain: use raw_smp_processor_id() for trace + - ARM: dts: logicpd-som-lv: Fix WL127x Startup Issues + - ARM: dts: logicpd-som-lv: Fix Audio Mute + - Input: atmel_mxt_ts - fix the firmware update + - hexagon: add memset_io() helper + - hexagon: export csum_partial_copy_nocheck + - scsi: vmw-pvscsi: return DID_BUS_BUSY for adapter-initated aborts + - bpf, x64: fix memleak when not converging after image + - parisc: drivers.c: Fix section mismatches + - stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock + - kthread, sched/wait: Fix kthread_parkme() wait-loop + - arm64: tegra: Make BCM89610 PHY interrupt as active low + - iommu/vt-d: fix shift-out-of-bounds in bug checking + - nvme: fix potential memory leak in option parsing + - nvme: Set integrity flag for user passthrough commands + - ARM: OMAP1: ams-delta: fix deferred_fiq handler + - smc: fix sendpage() call + - IB/hfi1 Use correct type for num_user_context + - IB/hfi1: Fix memory leak in exception path in get_irq_affinity() + - RDMA/cma: Do not query GID during QP state transition to RTR + - spi: bcm2835aux: ensure interrupts are enabled for shared handler + - sched/core: Introduce set_special_state() + - sh: fix build failure for J2 cpu with SMP disabled + - tee: check shm references are consistent in offset/size + - mac80211: Adjust SAE authentication timeout + - drm/omap: silence unititialized variable warning + - drm/omap: fix uninitialized ret variable + - drm/omap: fix possible NULL ref issue in tiler_reserve_2d + - drm/omap: check return value from soc_device_match + - drm/omap: handle alloc failures in omap_connector + - driver core: add __printf verification to __ata_ehi_pushv_desc + - ARM: dts: cygnus: fix irq type for arm global timer + - mac80211: use timeout from the AddBA response instead of the request + - net: aquantia: driver should correctly declare vlan_features bits + - can: dev: increase bus-off message severity + - arm64: Add MIDR encoding for NVIDIA CPUs + - cifs: smb2ops: Fix listxattr() when there are no EAs + - agp: uninorth: make two functions static + - tipc: eliminate KMSAN uninit-value in strcmp complaint + - qed: Fix l2 initializations over iWARP personality + - qede: Fix gfp flags sent to rdma event node allocation + - rxrpc: Fix error reception on AF_INET6 sockets + - rxrpc: Fix the min security level for kernel calls + - KVM: Extend MAX_IRQ_ROUTES to 4096 for all archs + - x86: Delay skip of emulated hypercall instruction + - ixgbe: return error on unsupported SFP module when resetting + - net sched actions: fix invalid pointer dereferencing if skbedit flags + missing + - proc/kcore: don't bounds check against address 0 + - ocfs2: take inode cluster lock before moving reflinked inode from orphan dir + - kprobes/x86: Prohibit probing on exception masking instructions + - uprobes/x86: Prohibit probing on MOV SS instruction + - objtool, kprobes/x86: Sync the latest header with + tools/objtool/arch/x86/include/asm/insn.h + - x86/pkeys/selftests: Adjust the self-test to fresh distros that export the + pkeys ABI + - x86/mpx/selftests: Adjust the self-test to fresh distros that export the MPX + ABI + - x86/selftests: Add mov_to_ss test + - x86/pkeys/selftests: Give better unexpected fault error messages + - x86/pkeys/selftests: Stop using assert() + - x86/pkeys/selftests: Remove dead debugging code, fix dprint_in_signal + - x86/pkeys/selftests: Allow faults on unknown keys + - x86/pkeys/selftests: Factor out "instruction page" + - x86/pkeys/selftests: Add PROT_EXEC test + - x86/pkeys/selftests: Fix pkey exhaustion test off-by-one + - x86/pkeys/selftests: Fix pointer math + - x86/pkeys/selftests: Save off 'prot' for allocations + - x86/pkeys/selftests: Add a test for pkey 0 + - mtd: Fix comparison in map_word_andequal() + - afs: Fix the non-encryption of calls + - usb: musb: fix remote wakeup racing with suspend + - ARM: keystone: fix platform_domain_notifier array overrun + - i2c: pmcmsp: return message count on master_xfer success + - i2c: pmcmsp: fix error return from master_xfer + - i2c: viperboard: return message count on master_xfer success + - ARM: davinci: dm646x: fix timer interrupt generation + - ARM: davinci: board-dm646x-evm: pass correct I2C adapter id for VPIF + - ARM: davinci: board-dm646x-evm: set VPIF capture card name + - clk: imx6ull: use OSC clock during AXI rate change + - locking/rwsem: Add a new RWSEM_ANONYMOUSLY_OWNED flag + - locking/percpu-rwsem: Annotate rwsem ownership transfer by setting + RWSEM_OWNER_UNKNOWN + - drm/dumb-buffers: Integer overflow in drm_mode_create_ioctl() + - sched/debug: Move the print_rt_rq() and print_dl_rq() declarations to + kernel/sched/sched.h + - sched/deadline: Make the grub_reclaim() function static + - parisc: Move setup_profiling_timer() out of init section + - efi/libstub/arm64: Handle randomized TEXT_OFFSET + - ARM: 8753/1: decompressor: add a missing parameter to the addruart macro + - ARM: 8758/1: decompressor: restore r1 and r2 just before jumping to the + kernel + - ARM: kexec: fix kdump register saving on panic() + - Revert "Btrfs: fix scrub to repair raid6 corruption" + - Btrfs: fix scrub to repair raid6 corruption + - Btrfs: make raid6 rebuild retry more + - tcp: do not overshoot window_clamp in tcp_rcv_space_adjust() + - ibmvnic: Do not notify peers on parameter change resets + - dt-bindings: net: ravb: Add support for r8a77965 SoC + - X86/KVM: Properly update 'tsc_offset' to represent the running guest + - kvm: x86: move MSR_IA32_TSC handling to x86.c + - ARM: dts: Fix cm2 and prm sizes for omap4 + - powerpc/64s: Default l1d_size to 64K in RFI fallback flush + - KVM: arm/arm64: vgic: Kick new VCPU on interrupt migration + - arm64: kasan: avoid pfn_to_nid() before page array is initialized + - ARM64: dts: meson-gxl: add USB host support + - ARM64: dts: meson-gxm: add GXM specific USB host configuration + - ARM64: dts: meson-gxl-s905x-p212: enable the USB controller + - ARM64: dts: meson-gx-p23x-q20x: enable the USB controller + - ARM64: dts: meson-gxl-s905x-libretech-cc: enable the USB controller + - ARM64: dts: meson-gxl-nexbox-a95x: enable the USB controller + - ARM64: dts: meson-gxm-khadas-vim2: enable the USB controller + - arm64: dts: correct SATA addresses for Stingray + - afs: Fix server record deletion + - proc: fix /proc/loadavg regression + - s390/qeth: fix request-side race during cmd IO timeout + - ACPI / scan: Initialize watchdog before PNP + - CIFS: set *resp_buf_type to NO_BUFFER on error + - arm64: dts: uniphier: fix input delay value for legacy mode of eMMC + - igb: Fix the transmission mode of queue 0 for Qav mode + - RISC-V: build vdso-dummy.o with -no-pie + - arm64: only advance singlestep for user instruction traps + - perf pmu: Fix core PMU alias list for X86 platform + - bpf, x64: fix JIT emission for dead code + - powerpc/kvm/booke: Fix altivec related build break + - reset: uniphier: fix USB clock line for LD20 + - nfp: don't depend on eth_tbl being available + - net: mvpp2: Fix clk error path in mvpp2_probe + - kvm: apic: Flush TLB after APIC mode/address change if VPIDs are in use + - IB/uverbs: Fix validating mandatory attributes + - RDMA/hns: Intercept illegal RDMA operation when use inline data + - pinctrl: cherryview: Associate IRQ descriptors to irqdomain + - kthread, sched/wait: Fix kthread_parkme() completion issue + - iommu/vt-d: Fix usage of force parameter in intel_ir_reconfigure_irte() + - nvme/multipath: Disable runtime writable enabling parameter + - ARM: dts: correct missing "compatible" entry for ti81xx SoCs + - usb: typec: tps6598x: handle block reads separately with plain-I2C adapters + - IB/mlx4: Fix integer overflow when calculating optimal MTT size + - bpf: add map_alloc_check callback + - bpf: fix possible spectre-v1 in find_and_alloc_map() + - drm/exynos/mixer: fix synchronization check in interlaced mode + - drm/exynos: mixer: avoid Oops in vp_video_buffer() + - bpf: use array_index_nospec in find_prog_type + - gcc-plugins: fix build condition of SANCOV plugin + - drm/vc4: Fix oops dereferencing DPI's connector since panel_bridge. + - nvme: fix use-after-free in nvme_free_ns_head + - powerpc/pseries: Fix CONFIG_NUMA=n build + - HID: i2c-hid: Add RESEND_REPORT_DESCR quirk for Toshiba Click Mini L9W-B + - cifs: Allocate validate negotiation request through kmalloc + - drm/amdgpu: Switch to interruptable wait to recover from ring hang. + - rxrpc: Fix missing start of call timeout + - ARM: dts: imx51-zii-rdu1: fix touchscreen bindings + - sh: switch to NO_BOOTMEM + - lib/find_bit_benchmark.c: avoid soft lockup in test_find_first_bit() + - x86/pkeys/selftests: Avoid printf-in-signal deadlocks + - afs: Fix address list parsing + - afs: Fix refcounting in callback registration + - afs: Fix server rotation's handling of fileserver probe failure + - afs: Fix VNOVOL handling in address rotation + - afs: Fix the handling of CB.InitCallBackState3 to find the server by UUID + - afs: Fix afs_find_server search loop + - KVM: X86: Lower the default timer frequency limit to 200us + - platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS + - ARM: replace unnecessary perl with sed and the shell $(( )) operator + * Improvements to the kernel source package preparation (LP: #1793461) + - [Packaging] startnewrelease: add support for backport kernels + * Kernel 4.15.0-35.38 fails to build with CONFIG_XFS_ONLINE_SCRUB enabled + (LP: #1792393) + - SAUCE: xfs: fix build error with CONFIG_XFS_ONLINE_SCRUB enabled + * update ENA driver to latest mainline version (LP: #1792044) + - net: ena: add detection and recovery mechanism for handling missed/misrouted + MSI-X + - net: ena: increase ena driver version to 1.5.0 + - net: ena: Eliminate duplicate barriers on weakly-ordered archs + - SAUCE: ena: devm_kzalloc() -> devm_kcalloc() + - net: ena: Fix use of uninitialized DMA address bits field + - net: ena: fix surprise unplug NULL dereference kernel crash + - net: ena: fix driver when PAGE_SIZE == 64kB + - net: ena: fix device destruction to gracefully free resources + - net: ena: fix potential double ena_destroy_device() + - net: ena: fix missing lock during device destruction + - net: ena: fix missing calls to READ_ONCE + - net: ena: fix incorrect usage of memory barriers + + [ Ubuntu: 4.15.0-36.39 ] + + * CVE-2018-14633 + - iscsi target: Use hex2bin instead of a re-implementation + * CVE-2018-17182 + - mm: get rid of vmacache_flush_all() entirely + + [ Ubuntu: 4.15.0-35.38 ] + + * linux: 4.15.0-35.38 -proposed tracker (LP: #1791719) + * device hotplug of vfio devices can lead to deadlock in vfio_pci_release + (LP: #1792099) + - SAUCE: vfio -- release device lock before userspace requests + * L1TF mitigation not effective in some CPU and RAM combinations + (LP: #1788563) + - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit + - x86/speculation/l1tf: Fix off-by-one error when warning that system has too + much RAM + - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+ + * CVE-2018-15594 + - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests + * CVE-2017-5715 (Spectre v2 s390x) + - KVM: s390: implement CPU model only facilities + - s390: detect etoken facility + - KVM: s390: add etoken support for guests + - s390/lib: use expoline for all bcr instructions + - s390: fix br_r1_trampoline for machines without exrl + - SAUCE: s390: use expoline thunks for all branches generated by the BPF JIT + * Ubuntu18.04.1: cpuidle: powernv: Fix promotion from snooze if next state + disabled (performance) (LP: #1790602) + - cpuidle: powernv: Fix promotion from snooze if next state disabled + * Watchdog CPU:19 Hard LOCKUP when kernel crash was triggered (LP: #1790636) + - powerpc: hard disable irqs in smp_send_stop loop + - powerpc: Fix deadlock with multiple calls to smp_send_stop + - powerpc: smp_send_stop do not offline stopped CPUs + - powerpc/powernv: Fix opal_event_shutdown() called with interrupts disabled + * Security fix: check if IOMMU page is contained in the pinned physical page + (LP: #1785675) + - vfio/spapr: Use IOMMU pageshift rather than pagesize + - KVM: PPC: Check if IOMMU page is contained in the pinned physical page + * Missing Intel GPU pci-id's (LP: #1789924) + - drm/i915/kbl: Add KBL GT2 sku + - drm/i915/whl: Introducing Whiskey Lake platform + - drm/i915/aml: Introducing Amber Lake platform + - drm/i915/cfl: Add a new CFL PCI ID. + * CVE-2018-15572 + - x86/speculation: Protect against userspace-userspace spectreRSB + * Support Power Management for Thunderbolt Controller (LP: #1789358) + - thunderbolt: Handle NULL boot ACL entries properly + - thunderbolt: Notify userspace when boot_acl is changed + - thunderbolt: Use 64-bit DMA mask if supported by the platform + - thunderbolt: Do not unnecessarily call ICM get route + - thunderbolt: No need to take tb->lock in domain suspend/complete + - thunderbolt: Use correct ICM commands in system suspend + - thunderbolt: Add support for runtime PM + * random oopses on s390 systems using NVMe devices (LP: #1790480) + - s390/pci: fix out of bounds access during irq setup + * [Bionic] Spectre v4 mitigation (Speculative Store Bypass Disable) support + for arm64 using SMC firmware call to set a hardware chicken bit + (LP: #1787993) // CVE-2018-3639 (arm64) + - arm64: alternatives: Add dynamic patching feature + - KVM: arm/arm64: Do not use kern_hyp_va() with kvm_vgic_global_state + - KVM: arm64: Avoid storing the vcpu pointer on the stack + - arm/arm64: smccc: Add SMCCC-specific return codes + - arm64: Call ARCH_WORKAROUND_2 on transitions between EL0 and EL1 + - arm64: Add per-cpu infrastructure to call ARCH_WORKAROUND_2 + - arm64: Add ARCH_WORKAROUND_2 probing + - arm64: Add 'ssbd' command-line option + - arm64: ssbd: Add global mitigation state accessor + - arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation + - arm64: ssbd: Restore mitigation status on CPU resume + - arm64: ssbd: Introduce thread flag to control userspace mitigation + - arm64: ssbd: Add prctl interface for per-thread mitigation + - arm64: KVM: Add HYP per-cpu accessors + - arm64: KVM: Add ARCH_WORKAROUND_2 support for guests + - arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests + - arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID + - [Config] ARM64_SSBD=y + * Reconcile hns3 SAUCE patches with upstream (LP: #1787477) + - Revert "UBUNTU: SAUCE: net: hns3: Optimize PF CMDQ interrupt switching + process" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for VF mailbox receiving unknown + message" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF + response" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for + hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and + shift in hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default + assignment probelm" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring + configuration operation while resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell + phy driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when + resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status + register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset + frequently" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing + command queue register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during + global or core reset" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear + reset cause" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in + hclgevf_main module" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp + selftest" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal + frame size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated + problem" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting + correctly" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in + pfc mode" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first + up" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and + definition" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return + value" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unused function warning in VF + driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead + of kzalloc/dma_map_single" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while + dependency HNS3 set" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of + some structures" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant + hclge_cmd_csq_done" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters + in hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in + hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused + hclge_ring_to_dma_dir" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and + upper_32_bits" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector + in hns3_client_uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error + information" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state + state init|uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in + hnae3.c" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4 + and ipv6" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before + free vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for + init_client_instance and uninit_client_instance" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index + from hclge_bind_ring_with_vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in + last BD except VLD bit and buffer size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback + selftest" + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: remove unused hclgevf_cfg_func_mta_filter + - net: hns3: Fix for VF mailbox cannot receiving PF response + - net: hns3: Fix for VF mailbox receiving unknown message + - net: hns3: Optimize PF CMDQ interrupt switching process + - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector + - net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - net: hns3: add vector status check before free vector + - net: hns3: add l4_type check for both ipv4 and ipv6 + - net: hns3: add unlikely for error check + - net: hns3: remove unused head file in hnae3.c + - net: hns3: extraction an interface for state init|uninit + - net: hns3: print the ret value in error information + - net: hns3: remove the Redundant put_vector in hns3_client_uninit + - net: hns3: remove back in struct hclge_hw + - net: hns3: use lower_32_bits and upper_32_bits + - net: hns3: remove unused hclge_ring_to_dma_dir + - net: hns3: remove useless code in hclge_cmd_send + - net: hns3: remove some redundant assignments + - net: hns3: simplify hclge_cmd_csq_clean + - net: hns3: remove a redundant hclge_cmd_csq_done + - net: hns3: remove some unused members of some structures + - net: hns3: give default option while dependency HNS3 set + - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single + - net: hns3: modify hnae_ to hnae3_ + - net: hns3: Fix tc setup when netdev is first up + - net: hns3: Fix for mac pause not disable in pfc mode + - net: hns3: Fix for waterline not setting correctly + - net: hns3: Fix for l4 checksum offload bug + - net: hns3: Fix for mailbox message truncated problem + - net: hns3: Add configure for mac minimal frame size + - net: hns3: Fix warning bug when doing lp selftest + - net: hns3: Fix get_vector ops in hclgevf_main module + - net: hns3: Remove the warning when clear reset cause + - net: hns3: Prevent sending command during global or core reset + - net: hns3: Modify the order of initializing command queue register + - net: hns3: Reset net device with rtnl_lock + - net: hns3: Prevent to request reset frequently + - net: hns3: Correct reset event status register + - net: hns3: Fix return value error in hns3_reset_notify_down_enet + - net: hns3: remove unnecessary ring configuration operation while resetting + - net: hns3: Fix for reset_level default assignment probelm + - net: hns3: Fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx + - net: hns3: Remove some redundant assignments + - net: hns3: Standardize the handle of return value + - net: hns3: Remove extra space and brackets + - net: hns3: Correct unreasonable code comments + - net: hns3: Use decimal for bit offset macros + - net: hns3: Modify inconsistent bit mask macros + - net: hns3: Fix misleading parameter name + - net: hns3: Remove unused struct member and definition + - net: hns3: Add SPDX tags to HNS3 PF driver + - net: hns3: Add support for serdes loopback selftest + - net: hns3: Fix for phy link issue when using marvell phy driver + - SAUCE: {topost} net: hns3: separate roce from nic when resetting + * CVE-2018-6555 + - SAUCE: irda: Only insert new objects into the global database via setsockopt + * CVE-2018-6554 + - SAUCE: irda: Fix memory leak caused by repeated binds of irda socket + * Bionic update: upstream stable patchset 2018-08-31 (LP: #1790188) + - netfilter: nf_tables: fix NULL pointer dereference on + nft_ct_helper_obj_dump() + - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers + - af_key: Always verify length of provided sadb_key + - gpio: No NULL owner + - KVM: X86: Fix reserved bits check for MOV to CR3 + - KVM: x86: introduce linear_{read,write}_system + - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and + kvm_write_guest_virt_system + - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy + - NFC: pn533: don't send USB data off of the stack + - usbip: vhci_sysfs: fix potential Spectre v1 + - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver + - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive + - Input: xpad - add GPD Win 2 Controller USB IDs + - phy: qcom-qusb2: Fix crash if nvmem cell not specified + - usb: gadget: function: printer: avoid wrong list handling in printer_write() + - usb: gadget: udc: renesas_usb3: disable the controller's irqs for + reconnecting + - serial: sh-sci: Stop using printk format %pCr + - tty/serial: atmel: use port->name as name in request_irq() + - serial: samsung: fix maxburst parameter for DMA transactions + - serial: 8250: omap: Fix idling of clocks for unused uarts + - vmw_balloon: fixing double free when batching mode is off + - tty: pl011: Avoid spuriously stuck-off interrupts + - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access + - Input: goodix - add new ACPI id for GPD Win 2 touch screen + - crypto: caam - strip input zeros from RSA input buffer + - crypto: caam - fix DMA mapping dir for generated IV + - crypto: caam - fix IV DMA mapping and updating + - crypto: caam/qi - fix IV DMA mapping and updating + - crypto: caam - fix size of RSA prime factor q + - crypto: vmx - Remove overly verbose printk from AES init routines + - crypto: vmx - Remove overly verbose printk from AES XTS init + - crypto: omap-sham - fix memleak + - usb: typec: wcove: Remove dependency on HW FSM + - usb: gadget: udc: renesas_usb3: fix double phy_put() + - usb: gadget: udc: renesas_usb3: should remove debugfs + - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add + udc + - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc + - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error + * Bionic update: upstream stable patchset 2018-08-29 (LP: #1789666) + - scsi: sd_zbc: Avoid that resetting a zone fails sporadically + - mmap: introduce sane default mmap limits + - mmap: relax file size limit for regular files + - btrfs: define SUPER_FLAG_METADUMP_V2 + - kconfig: Avoid format overflow warning from GCC 8.1 + - be2net: Fix error detection logic for BE3 + - bnx2x: use the right constant + - dccp: don't free ccid2_hc_tx_sock struct in dccp_disconnect() + - enic: set DMA mask to 47 bit + - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds + - ip6_tunnel: remove magic mtu value 0xFFF8 + - ipmr: properly check rhltable_init() return value + - ipv4: remove warning in ip_recv_error + - ipv6: omit traffic class when calculating flow hash + - isdn: eicon: fix a missing-check bug + - kcm: Fix use-after-free caused by clonned sockets + - netdev-FAQ: clarify DaveM's position for stable backports + - net: ipv4: add missing RTA_TABLE to rtm_ipv4_policy + - net: metrics: add proper netlink validation + - net/packet: refine check for priv area size + - net: phy: broadcom: Fix bcm_write_exp() + - net: usb: cdc_mbim: add flag FLAG_SEND_ZLP + - packet: fix reserve calculation + - qed: Fix mask for physical address in ILT entry + - sctp: not allow transport timeout value less than HZ/5 for hb_timer + - team: use netdev_features_t instead of u32 + - vhost: synchronize IOTLB message with dev cleanup + - vrf: check the original netdevice for generating redirect + - ipv6: sr: fix memory OOB access in seg6_do_srh_encap/inline + - net: phy: broadcom: Fix auxiliary control register reads + - net-sysfs: Fix memory leak in XPS configuration + - virtio-net: correctly transmit XDP buff after linearizing + - net/mlx4: Fix irq-unsafe spinlock usage + - tun: Fix NULL pointer dereference in XDP redirect + - virtio-net: correctly check num_buf during err path + - net/mlx5e: When RXFCS is set, add FCS data into checksum calculation + - virtio-net: fix leaking page for gso packet during mergeable XDP + - rtnetlink: validate attributes in do_setlink() + - cls_flower: Fix incorrect idr release when failing to modify rule + - PCI: hv: Do not wait forever on a device that has disappeared + - drm: set FMODE_UNSIGNED_OFFSET for drm files + - l2tp: fix refcount leakage on PPPoL2TP sockets + - mlxsw: spectrum: Forbid creation of VLAN 1 over port/LAG + - net: ethernet: ti: cpdma: correct error handling for chan create + - net: ethernet: davinci_emac: fix error handling in probe() + - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC + - net : sched: cls_api: deal with egdev path only if needed + * Bionic update: upstream stable patchset 2018-08-24 (LP: #1788897) + - fix io_destroy()/aio_complete() race + - mm: fix the NULL mapping case in __isolate_lru_page() + - objtool: Support GCC 8's cold subfunctions + - objtool: Support GCC 8 switch tables + - objtool: Detect RIP-relative switch table references + - objtool: Detect RIP-relative switch table references, part 2 + - objtool: Fix "noreturn" detection for recursive sibling calls + - xfs: convert XFS_AGFL_SIZE to a helper function + - xfs: detect agfl count corruption and reset agfl + - Input: synaptics - Lenovo Carbon X1 Gen5 (2017) devices should use RMI + - Input: synaptics - add Lenovo 80 series ids to SMBus + - Input: elan_i2c_smbus - fix corrupted stack + - tracing: Fix crash when freeing instances with event triggers + - tracing: Make the snapshot trigger work with instances + - selinux: KASAN: slab-out-of-bounds in xattr_getsecurity + - cfg80211: further limit wiphy names to 64 bytes + - drm/amd/powerplay: Fix enum mismatch + - rtlwifi: rtl8192cu: Remove variable self-assignment in rf.c + - platform/chrome: cros_ec_lpc: remove redundant pointer request + - kbuild: clang: disable unused variable warnings only when constant + - tcp: avoid integer overflows in tcp_rcv_space_adjust() + - iio: ad7793: implement IIO_CHAN_INFO_SAMP_FREQ + - iio:buffer: make length types match kfifo types + - iio:kfifo_buf: check for uint overflow + - iio: adc: select buffer for at91-sama5d2_adc + - MIPS: lantiq: gphy: Drop reboot/remove reset asserts + - MIPS: ptrace: Fix PTRACE_PEEKUSR requests for 64-bit FGRs + - MIPS: prctl: Disallow FRE without FR with PR_SET_FP_MODE requests + - scsi: scsi_transport_srp: Fix shost to rport translation + - stm class: Use vmalloc for the master map + - hwtracing: stm: fix build error on some arches + - IB/core: Fix error code for invalid GID entry + - mm/huge_memory.c: __split_huge_page() use atomic ClearPageDirty() + - Revert "rt2800: use TXOP_BACKOFF for probe frames" + - intel_th: Use correct device when freeing buffers + - drm/psr: Fix missed entry in PSR setup time table. + - drm/i915/lvds: Move acpi lid notification registration to registration phase + - drm/i915: Disable LVDS on Radiant P845 + - drm/vmwgfx: Use kasprintf + - drm/vmwgfx: Fix host logging / guestinfo reading error paths + - nvme: fix extended data LBA supported setting + - iio: hid-sensor-trigger: Fix sometimes not powering up the sensor after + resume + - x86/MCE/AMD: Define a function to get SMCA bank type + - x86/mce/AMD: Pass the bank number to smca_get_bank_type() + - x86/mce/AMD, EDAC/mce_amd: Enumerate Reserved SMCA bank type + - x86/mce/AMD: Carve out SMCA get_block_address() code + - x86/MCE/AMD: Cache SMCA MISC block addresses + * errors when scanning partition table of corrupted AIX disk (LP: #1787281) + - partitions/aix: fix usage of uninitialized lv_info and lvname structures + - partitions/aix: append null character to print data from disk + * tlbie master timeout checkstop (using NVidia/GPU) (LP: #1789772) + - powerpc/mm/hugetlb: Update huge_ptep_set_access_flags to call + __ptep_set_access_flags directly + - powerpc/mm/radix: Move function from radix.h to pgtable-radix.c + - powerpc/mm: Change function prototype + - powerpc/mm/radix: Change pte relax sequence to handle nest MMU hang + * performance drop with ATS enabled (LP: #1788097) + - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage + * [Regression] kernel crashdump fails on arm64 (LP: #1786878) + - arm64: export memblock_reserve()d regions via /proc/iomem + - drivers: acpi: add dependency of EFI for arm64 + - efi/arm: preserve early mapping of UEFI memory map longer for BGRT + - efi/arm: map UEFI memory map even w/o runtime services enabled + - arm64: acpi: fix alignment fault in accessing ACPI + - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y + - arm64: fix ACPI dependencies + - ACPI: fix menuconfig presentation of ACPI submenu + * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780) + - r8152: disable RX aggregation on new Dell TB16 dock + * dell_wmi: Unknown key codes (LP: #1762385) + - platform/x86: dell-wmi: Ignore new rfkill and fn-lock events + * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940) + - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform + - SAUCE: i2c:amd move out pointer in union i2c_event_base + - SAUCE: i2c:amd Depends on ACPI + - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86 + * r8169 no internet after suspending (LP: #1779817) + - r8169: restore previous behavior to accept BIOS WoL settings + - r8169: don't use MSI-X on RTL8168g + - r8169: don't use MSI-X on RTL8106e + * Fix Intel Cannon Lake LPSS I2C input clock (LP: #1789790) + - mfd: intel-lpss: Fix Intel Cannon Lake LPSS I2C input clock + * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4 + machine (LP: #1789145) + - ALSA: hda/realtek - Fix HP Headset Mic can't record + * Tango platform uses __initcall without further checks (LP: #1787945) + - [Config] disable ARCH_TANGO + * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898) + - [Config] CONFIG_SCLP_OFB=y for s390x + + -- Marcelo Henrique Cerri Sun, 21 Oct 2018 18:16:29 -0300 + +linux-oracle (4.15.0-1003.3) bionic; urgency=medium + + [ Ubuntu: 4.15.0-34.37 ] + + * linux: 4.15.0-34.37 -proposed tracker (LP: #1788744) + * Bionic update: upstream stable patchset 2018-08-09 (LP: #1786352) + - MIPS: c-r4k: Fix data corruption related to cache coherence + - MIPS: ptrace: Expose FIR register through FP regset + - MIPS: Fix ptrace(2) PTRACE_PEEKUSR and PTRACE_POKEUSR accesses to o32 FGRs + - KVM: Fix spelling mistake: "cop_unsuable" -> "cop_unusable" + - affs_lookup(): close a race with affs_remove_link() + - fs: don't scan the inode cache before SB_BORN is set + - aio: fix io_destroy(2) vs. lookup_ioctx() race + - ALSA: timer: Fix pause event notification + - do d_instantiate/unlock_new_inode combinations safely + - mmc: sdhci-iproc: remove hard coded mmc cap 1.8v + - mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register + - mmc: sdhci-iproc: add SDHCI_QUIRK2_HOST_OFF_CARD_ON for cygnus + - libata: Blacklist some Sandisk SSDs for NCQ + - libata: blacklist Micron 500IT SSD with MU01 firmware + - xen-swiotlb: fix the check condition for xen_swiotlb_free_coherent + - drm/vmwgfx: Fix 32-bit VMW_PORT_HB_[IN|OUT] macros + - arm64: lse: Add early clobbers to some input/output asm operands + - powerpc/64s: Clear PCR on boot + - IB/hfi1: Use after free race condition in send context error path + - IB/umem: Use the correct mm during ib_umem_release + - idr: fix invalid ptr dereference on item delete + - Revert "ipc/shm: Fix shmat mmap nil-page protection" + - ipc/shm: fix shmat() nil address after round-down when remapping + - mm/kasan: don't vfree() nonexistent vm_area + - kasan: free allocated shadow memory on MEM_CANCEL_ONLINE + - kasan: fix memory hotplug during boot + - kernel/sys.c: fix potential Spectre v1 issue + - KVM: s390: vsie: fix < 8k check for the itdba + - KVM: x86: Update cpuid properly when CR4.OSXAVE or CR4.PKE is changed + - kvm: x86: IA32_ARCH_CAPABILITIES is always supported + - powerpc/64s: Improve RFI L1-D cache flush fallback + - powerpc/pseries: Restore default security feature flags on setup + - powerpc/64s: Fix section mismatch warnings from setup_rfi_flush() + - MIPS: generic: Fix machine compatible matching + - mac80211: mesh: fix wrong mesh TTL offset calculation + - ARC: Fix malformed ARC_EMUL_UNALIGNED default + - ptr_ring: prevent integer overflow when calculating size + - arm64: dts: rockchip: fix rock64 gmac2io stability issues + - arm64: dts: rockchip: correct ep-gpios for rk3399-sapphire + - libata: Fix compile warning with ATA_DEBUG enabled + - selftests: sync: missing CFLAGS while compiling + - selftest/vDSO: fix O= + - selftests: pstore: Adding config fragment CONFIG_PSTORE_RAM=m + - selftests: memfd: add config fragment for fuse + - ARM: OMAP2+: timer: fix a kmemleak caused in omap_get_timer_dt + - ARM: OMAP3: Fix prm wake interrupt for resume + - ARM: OMAP2+: Fix sar_base inititalization for HS omaps + - ARM: OMAP1: clock: Fix debugfs_create_*() usage + - tls: retrun the correct IV in getsockopt + - xhci: workaround for AMD Promontory disabled ports wakeup + - IB/uverbs: Fix method merging in uverbs_ioctl_merge + - IB/uverbs: Fix possible oops with duplicate ioctl attributes + - IB/uverbs: Fix unbalanced unlock on error path for rdma_explicit_destroy + - arm64: dts: rockchip: Fix DWMMC clocks + - ARM: dts: rockchip: Fix DWMMC clocks + - iwlwifi: mvm: fix security bug in PN checking + - iwlwifi: mvm: fix IBSS for devices that support station type API + - iwlwifi: mvm: always init rs with 20mhz bandwidth rates + - NFC: llcp: Limit size of SDP URI + - rxrpc: Work around usercopy check + - MD: Free bioset when md_run fails + - md: fix md_write_start() deadlock w/o metadata devices + - s390/dasd: fix handling of internal requests + - xfrm: do not call rcu_read_unlock when afinfo is NULL in xfrm_get_tos + - mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4 + - mac80211: fix a possible leak of station stats + - mac80211: fix calling sleeping function in atomic context + - cfg80211: clear wep keys after disconnection + - mac80211: Do not disconnect on invalid operating class + - mac80211: Fix sending ADDBA response for an ongoing session + - gpu: ipu-v3: pre: fix device node leak in ipu_pre_lookup_by_phandle + - gpu: ipu-v3: prg: fix device node leak in ipu_prg_lookup_by_phandle + - md raid10: fix NULL deference in handle_write_completed() + - drm/exynos: g2d: use monotonic timestamps + - drm/exynos: fix comparison to bitshift when dealing with a mask + - drm/meson: fix vsync buffer update + - arm64: perf: correct PMUVer probing + - RDMA/bnxt_re: Unpin SQ and RQ memory if QP create fails + - RDMA/bnxt_re: Fix system crash during load/unload + - net/mlx5e: Return error if prio is specified when offloading eswitch vlan + push + - locking/xchg/alpha: Add unconditional memory barrier to cmpxchg() + - md: raid5: avoid string overflow warning + - virtio_net: fix XDP code path in receive_small() + - kernel/relay.c: limit kmalloc size to KMALLOC_MAX_SIZE + - bug.h: work around GCC PR82365 in BUG() + - selftests/memfd: add run_fuse_test.sh to TEST_FILES + - seccomp: add a selftest for get_metadata + - soc: imx: gpc: de-register power domains only if initialized + - powerpc/bpf/jit: Fix 32-bit JIT for seccomp_data access + - s390/cio: fix ccw_device_start_timeout API + - s390/cio: fix return code after missing interrupt + - s390/cio: clear timer when terminating driver I/O + - selftests/bpf/test_maps: exit child process without error in ENOMEM case + - PKCS#7: fix direct verification of SignerInfo signature + - arm64: dts: cavium: fix PCI bus dtc warnings + - nfs: system crashes after NFS4ERR_MOVED recovery + - ARM: OMAP: Fix dmtimer init for omap1 + - smsc75xx: fix smsc75xx_set_features() + - regulatory: add NUL to request alpha2 + - integrity/security: fix digsig.c build error with header file + - x86/intel_rdt: Fix incorrect returned value when creating rdgroup sub- + directory in resctrl file system + - locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs + - x86/topology: Update the 'cpu cores' field in /proc/cpuinfo correctly across + CPU hotplug operations + - mac80211: drop frames with unexpected DS bits from fast-rx to slow path + - arm64: fix unwind_frame() for filtered out fn for function graph tracing + - macvlan: fix use-after-free in macvlan_common_newlink() + - KVM: nVMX: Don't halt vcpu when L1 is injecting events to L2 + - kvm: fix warning for CONFIG_HAVE_KVM_EVENTFD builds + - ARM: dts: imx6dl: Include correct dtsi file for Engicam i.CoreM6 + DualLite/Solo RQS + - fs: dcache: Avoid livelock between d_alloc_parallel and __d_add + - fs: dcache: Use READ_ONCE when accessing i_dir_seq + - md: fix a potential deadlock of raid5/raid10 reshape + - md/raid1: fix NULL pointer dereference + - batman-adv: fix packet checksum in receive path + - batman-adv: invalidate checksum on fragment reassembly + - netfilter: ipt_CLUSTERIP: put config struct if we can't increment ct + refcount + - netfilter: ipt_CLUSTERIP: put config instead of freeing it + - netfilter: ebtables: convert BUG_ONs to WARN_ONs + - batman-adv: Ignore invalid batadv_iv_gw during netlink send + - batman-adv: Ignore invalid batadv_v_gw during netlink send + - batman-adv: Fix netlink dumping of BLA claims + - batman-adv: Fix netlink dumping of BLA backbones + - nvme-pci: Fix nvme queue cleanup if IRQ setup fails + - clocksource/drivers/fsl_ftm_timer: Fix error return checking + - libceph, ceph: avoid memory leak when specifying same option several times + - ceph: fix dentry leak when failing to init debugfs + - xen/pvcalls: fix null pointer dereference on map->sock + - ARM: orion5x: Revert commit 4904dbda41c8. + - qrtr: add MODULE_ALIAS macro to smd + - selftests/futex: Fix line continuation in Makefile + - r8152: fix tx packets accounting + - virtio-gpu: fix ioctl and expose the fixed status to userspace. + - dmaengine: rcar-dmac: fix max_chunk_size for R-Car Gen3 + - bcache: fix kcrashes with fio in RAID5 backend dev + - ip_gre: fix IFLA_MTU ignored on NEWLINK + - ip6_tunnel: fix IFLA_MTU ignored on NEWLINK + - sit: fix IFLA_MTU ignored on NEWLINK + - nbd: fix return value in error handling path + - ARM: dts: NSP: Fix amount of RAM on BCM958625HR + - ARM: dts: bcm283x: Fix unit address of local_intc + - powerpc/boot: Fix random libfdt related build errors + - clocksource/drivers/mips-gic-timer: Use correct shift count to extract data + - gianfar: Fix Rx byte accounting for ndev stats + - net/tcp/illinois: replace broken algorithm reference link + - nvmet: fix PSDT field check in command format + - net/smc: use link_id of server in confirm link reply + - mlxsw: core: Fix flex keys scratchpad offset conflict + - mlxsw: spectrum: Treat IPv6 unregistered multicast as broadcast + - spectrum: Reference count VLAN entries + - ARC: mcip: halt GFRC counter when ARC cores halt + - ARC: mcip: update MCIP debug mask when the new cpu came online + - ARC: setup cpu possible mask according to possible-cpus dts property + - ipvs: remove IPS_NAT_MASK check to fix passive FTP + - IB/mlx: Set slid to zero in Ethernet completion struct + - RDMA/bnxt_re: Unconditionly fence non wire memory operations + - RDMA/bnxt_re: Fix incorrect DB offset calculation + - RDMA/bnxt_re: Fix the ib_reg failure cleanup + - xen/pirq: fix error path cleanup when binding MSIs + - drm/amd/amdgpu: Correct VRAM width for APUs with GMC9 + - xfrm: Fix ESN sequence number handling for IPsec GSO packets. + - arm64: dts: rockchip: Fix rk3399-gru-* s2r (pinctrl hogs, wifi reset) + - drm/sun4i: Fix dclk_set_phase + - btrfs: use kvzalloc to allocate btrfs_fs_info + - Btrfs: send, fix issuing write op when processing hole in no data mode + - Btrfs: fix log replay failure after linking special file and fsync + - ceph: fix potential memory leak in init_caches() + - block: display the correct diskname for bio + - selftests/powerpc: Skip the subpage_prot tests if the syscall is unavailable + - net: ethtool: don't ignore return from driver get_fecparam method + - iwlwifi: mvm: fix TX of CCMP 256 + - iwlwifi: mvm: Fix channel switch for count 0 and 1 + - iwlwifi: mvm: fix assert 0x2B00 on older FWs + - iwlwifi: avoid collecting firmware dump if not loaded + - iwlwifi: mvm: Direct multicast frames to the correct station + - iwlwifi: mvm: Correctly set the tid for mcast queue + - rds: Incorrect reference counting in TCP socket creation + - watchdog: f71808e_wdt: Fix magic close handling + - batman-adv: Fix multicast packet loss with a single WANT_ALL_IPV4/6 flag + - hv_netvsc: use napi_schedule_irqoff + - hv_netvsc: filter multicast/broadcast + - hv_netvsc: propagate rx filters to VF + - ARM: dts: rockchip: Add missing #sound-dai-cells on rk3288 + - e1000e: Fix check_for_link return value with autoneg off + - e1000e: allocate ring descriptors with dma_zalloc_coherent + - ia64/err-inject: Use get_user_pages_fast() + - RDMA/qedr: Fix kernel panic when running fio over NFSoRDMA + - RDMA/qedr: Fix iWARP write and send with immediate + - IB/mlx4: Fix corruption of RoCEv2 IPv4 GIDs + - IB/mlx4: Include GID type when deleting GIDs from HW table under RoCE + - IB/mlx5: Fix an error code in __mlx5_ib_modify_qp() + - fbdev: Fixing arbitrary kernel leak in case FBIOGETCMAP_SPARC in + sbusfb_ioctl_helper(). + - fsl/fman: avoid sleeping in atomic context while adding an address + - qed: Free RoCE ILT Memory on rmmod qedr + - net: qcom/emac: Use proper free methods during TX + - net: smsc911x: Fix unload crash when link is up + - IB/core: Fix possible crash to access NULL netdev + - cxgb4: do not set needs_free_netdev for mgmt dev's + - xen-blkfront: move negotiate_mq to cover all cases of new VBDs + - xen: xenbus: use put_device() instead of kfree() + - hv_netvsc: fix filter flags + - hv_netvsc: fix locking for rx_mode + - hv_netvsc: fix locking during VF setup + - ARM: davinci: fix the GPIO lookup for omapl138-hawk + - arm64: Relax ARM_SMCCC_ARCH_WORKAROUND_1 discovery + - selftests/vm/run_vmtests: adjust hugetlb size according to nr_cpus + - lib/test_kmod.c: fix limit check on number of test devices created + - dmaengine: mv_xor_v2: Fix clock resource by adding a register clock + - netfilter: ebtables: fix erroneous reject of last rule + - can: m_can: change comparison to bitshift when dealing with a mask + - can: m_can: select pinctrl state in each suspend/resume function + - bnxt_en: Check valid VNIC ID in bnxt_hwrm_vnic_set_tpa(). + - workqueue: use put_device() instead of kfree() + - ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu + - sunvnet: does not support GSO for sctp + - KVM: arm/arm64: vgic: Add missing irq_lock to vgic_mmio_read_pending + - gpu: ipu-v3: prg: avoid possible array underflow + - drm/imx: move arming of the vblank event to atomic_flush + - drm/nouveau/bl: fix backlight regression + - xfrm: fix rcu_read_unlock usage in xfrm_local_error + - iwlwifi: mvm: set the correct tid when we flush the MCAST sta + - iwlwifi: mvm: Correctly set IGTK for AP + - iwlwifi: mvm: fix error checking for multi/broadcast sta + - net: Fix vlan untag for bridge and vlan_dev with reorder_hdr off + - vlan: Fix out of order vlan headers with reorder header off + - batman-adv: fix header size check in batadv_dbg_arp() + - batman-adv: Fix skbuff rcsum on packet reroute + - vti4: Don't count header length twice on tunnel setup + - ip_tunnel: Clamp MTU to bounds on new link + - vti6: Fix dev->max_mtu setting + - iwlwifi: mvm: Increase session protection time after CS + - iwlwifi: mvm: clear tx queue id when unreserving aggregation queue + - iwlwifi: mvm: make sure internal station has a valid id + - iwlwifi: mvm: fix array out of bounds reference + - drm/tegra: Shutdown on driver unbind + - perf/cgroup: Fix child event counting bug + - brcmfmac: Fix check for ISO3166 code + - kbuild: make scripts/adjust_autoksyms.sh robust against timestamp races + - RDMA/ucma: Correct option size check using optlen + - RDMA/qedr: fix QP's ack timeout configuration + - RDMA/qedr: Fix rc initialization on CNQ allocation failure + - RDMA/qedr: Fix QP state initialization race + - net/sched: fix idr leak on the error path of tcf_bpf_init() + - net/sched: fix idr leak in the error path of tcf_simp_init() + - net/sched: fix idr leak in the error path of tcf_act_police_init() + - net/sched: fix idr leak in the error path of tcp_pedit_init() + - net/sched: fix idr leak in the error path of __tcf_ipt_init() + - net/sched: fix idr leak in the error path of tcf_skbmod_init() + - net: dsa: Fix functional dsa-loop dependency on FIXED_PHY + - drm/ast: Fixed 1280x800 Display Issue + - mm/mempolicy.c: avoid use uninitialized preferred_node + - mm, thp: do not cause memcg oom for thp + - xfrm: Fix transport mode skb control buffer usage. + - selftests: ftrace: Add probe event argument syntax testcase + - selftests: ftrace: Add a testcase for string type with kprobe_event + - selftests: ftrace: Add a testcase for probepoint + - drm/amdkfd: Fix scratch memory with HWS enabled + - batman-adv: fix multicast-via-unicast transmission with AP isolation + - batman-adv: fix packet loss for broadcasted DHCP packets to a server + - ARM: 8748/1: mm: Define vdso_start, vdso_end as array + - lan78xx: Set ASD in MAC_CR when EEE is enabled. + - net: qmi_wwan: add BroadMobi BM806U 2020:2033 + - bonding: fix the err path for dev hwaddr sync in bond_enslave + - net: dsa: mt7530: fix module autoloading for OF platform drivers + - net/mlx5: Make eswitch support to depend on switchdev + - perf/x86/intel: Fix linear IP of PEBS real_ip on Haswell and later CPUs + - x86/alternatives: Fixup alternative_call_2 + - llc: properly handle dev_queue_xmit() return value + - builddeb: Fix header package regarding dtc source links + - qede: Fix barrier usage after tx doorbell write. + - mm, slab: memcg_link the SLAB's kmem_cache + - mm/page_owner: fix recursion bug after changing skip entries + - mm/kmemleak.c: wait for scan completion before disabling free + - hv_netvsc: enable multicast if necessary + - qede: Do not drop rx-checksum invalidated packets. + - net: Fix untag for vlan packets without ethernet header + - vlan: Fix vlan insertion for packets without ethernet header + - net: mvneta: fix enable of all initialized RXQs + - sh: fix debug trap failure to process signals before return to user + - firmware: dmi_scan: Fix UUID length safety check + - nvme: don't send keep-alives to the discovery controller + - Btrfs: clean up resources during umount after trans is aborted + - Btrfs: fix loss of prealloc extents past i_size after fsync log replay + - x86/pgtable: Don't set huge PUD/PMD on non-leaf entries + - fs/proc/proc_sysctl.c: fix potential page fault while unregistering sysctl + table + - swap: divide-by-zero when zero length swap file on ssd + - z3fold: fix memory leak + - sr: get/drop reference to device in revalidate and check_events + - Force log to disk before reading the AGF during a fstrim + - cpufreq: CPPC: Initialize shared perf capabilities of CPUs + - powerpc/fscr: Enable interrupts earlier before calling get_user() + - perf tools: Fix perf builds with clang support + - perf clang: Add support for recent clang versions + - dp83640: Ensure against premature access to PHY registers after reset + - ibmvnic: Zero used TX descriptor counter on reset + - mm/ksm: fix interaction with THP + - mm: fix races between address_space dereference and free in page_evicatable + - mm: thp: fix potential clearing to referenced flag in + page_idle_clear_pte_refs_one() + - Btrfs: bail out on error during replay_dir_deletes + - Btrfs: fix NULL pointer dereference in log_dir_items + - btrfs: Fix possible softlock on single core machines + - IB/rxe: Fix for oops in rxe_register_device on ppc64le arch + - ocfs2/dlm: don't handle migrate lockres if already in shutdown + - powerpc/64s/idle: Fix restore of AMOR on POWER9 after deep sleep + - sched/rt: Fix rq->clock_update_flags < RQCF_ACT_SKIP warning + - x86/mm: Fix bogus warning during EFI bootup, use boot_cpu_has() instead of + this_cpu_has() in build_cr3_noflush() + - KVM: VMX: raise internal error for exception during invalid protected mode + state + - lan78xx: Connect phy early + - sparc64: Make atomic_xchg() an inline function rather than a macro. + - net: bgmac: Fix endian access in bgmac_dma_tx_ring_free() + - net: bgmac: Correctly annotate register space + - btrfs: tests/qgroup: Fix wrong tree backref level + - Btrfs: fix copy_items() return value when logging an inode + - btrfs: fix lockdep splat in btrfs_alloc_subvolume_writers + - btrfs: qgroup: Fix root item corruption when multiple same source snapshots + are created with quota enabled + - rxrpc: Fix Tx ring annotation after initial Tx failure + - rxrpc: Don't treat call aborts as conn aborts + - xen/acpi: off by one in read_acpi_id() + - drivers: macintosh: rack-meter: really fix bogus memsets + - ACPI: acpi_pad: Fix memory leak in power saving threads + - powerpc/mpic: Check if cpu_possible() in mpic_physmask() + - ieee802154: ca8210: fix uninitialised data read + - ath10k: advertize beacon_int_min_gcd + - iommu/amd: Take into account that alloc_dev_data() may return NULL + - intel_th: Use correct method of finding hub + - m68k: set dma and coherent masks for platform FEC ethernets + - iwlwifi: mvm: check if mac80211_queue is valid in iwl_mvm_disable_txq + - parisc/pci: Switch LBA PCI bus from Hard Fail to Soft Fail mode + - hwmon: (nct6775) Fix writing pwmX_mode + - powerpc/perf: Prevent kernel address leak to userspace via BHRB buffer + - powerpc/perf: Fix kernel address leak via sampling registers + - rsi: fix kernel panic observed on 64bit machine + - tools/thermal: tmon: fix for segfault + - selftests: Print the test we're running to /dev/kmsg + - net/mlx5: Protect from command bit overflow + - watchdog: davinci_wdt: fix error handling in davinci_wdt_probe() + - ath10k: Fix kernel panic while using worker (ath10k_sta_rc_update_wk) + - nvme-pci: disable APST for Samsung NVMe SSD 960 EVO + ASUS PRIME Z370-A + - ath9k: fix crash in spectral scan + - cxgb4: Setup FW queues before registering netdev + - ima: Fix Kconfig to select TPM 2.0 CRB interface + - ima: Fallback to the builtin hash algorithm + - watchdog: aspeed: Allow configuring for alternate boot + - arm: dts: socfpga: fix GIC PPI warning + - ext4: don't complain about incorrect features when probing + - drm/vmwgfx: Unpin the screen object backup buffer when not used + - iommu/mediatek: Fix protect memory setting + - cpufreq: cppc_cpufreq: Fix cppc_cpufreq_init() failure path + - IB/mlx5: Set the default active rate and width to QDR and 4X + - zorro: Set up z->dev.dma_mask for the DMA API + - bcache: quit dc->writeback_thread when BCACHE_DEV_DETACHING is set + - remoteproc: imx_rproc: Fix an error handling path in 'imx_rproc_probe()' + - dt-bindings: add device tree binding for Allwinner H6 main CCU + - ACPICA: Events: add a return on failure from acpi_hw_register_read + - ACPICA: Fix memory leak on unusual memory leak + - ACPICA: acpi: acpica: fix acpi operand cache leak in nseval.c + - cxgb4: Fix queue free path of ULD drivers + - i2c: mv64xxx: Apply errata delay only in standard mode + - KVM: lapic: stop advertising DIRECTED_EOI when in-kernel IOAPIC is in use + - perf top: Fix top.call-graph config option reading + - perf stat: Fix core dump when flag T is used + - IB/core: Honor port_num while resolving GID for IB link layer + - drm/amdkfd: add missing include of mm.h + - coresight: Use %px to print pcsr instead of %p + - regulator: gpio: Fix some error handling paths in 'gpio_regulator_probe()' + - spi: bcm-qspi: fIX some error handling paths + - net/smc: pay attention to MAX_ORDER for CQ entries + - MIPS: ath79: Fix AR724X_PLL_REG_PCIE_CONFIG offset + - watchdog: dw: RMW the control register + - watchdog: aspeed: Fix translation of reset mode to ctrl register + - drm/meson: Fix some error handling paths in 'meson_drv_bind_master()' + - drm/meson: Fix an un-handled error path in 'meson_drv_bind_master()' + - powerpc: Add missing prototype for arch_irq_work_raise() + - f2fs: fix to set KEEP_SIZE bit in f2fs_zero_range + - f2fs: fix to clear CP_TRIMMED_FLAG + - f2fs: fix to check extent cache in f2fs_drop_extent_tree + - perf/core: Fix installing cgroup events on CPU + - max17042: propagate of_node to power supply device + - perf/core: Fix perf_output_read_group() + - drm/panel: simple: Fix the bus format for the Ontat panel + - hwmon: (pmbus/max8688) Accept negative page register values + - hwmon: (pmbus/adm1275) Accept negative page register values + - perf/x86/intel: Properly save/restore the PMU state in the NMI handler + - cdrom: do not call check_disk_change() inside cdrom_open() + - efi/arm*: Only register page tables when they exist + - perf/x86/intel: Fix large period handling on Broadwell CPUs + - perf/x86/intel: Fix event update for auto-reload + - arm64: dts: qcom: Fix SPI5 config on MSM8996 + - soc: qcom: wcnss_ctrl: Fix increment in NV upload + - gfs2: Fix fallocate chunk size + - x86/devicetree: Initialize device tree before using it + - x86/devicetree: Fix device IRQ settings in DT + - phy: rockchip-emmc: retry calpad busy trimming + - ALSA: vmaster: Propagate slave error + - phy: qcom-qmp: Fix phy pipe clock gating + - drm/bridge: sii902x: Retry status read after DDI I2C + - tools: hv: fix compiler warnings about major/target_fname + - block: null_blk: fix 'Invalid parameters' when loading module + - dmaengine: pl330: fix a race condition in case of threaded irqs + - dmaengine: rcar-dmac: Check the done lists in rcar_dmac_chan_get_residue() + - enic: enable rq before updating rq descriptors + - watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe() + - hwrng: stm32 - add reset during probe + - pinctrl: devicetree: Fix dt_to_map_one_config handling of hogs + - pinctrl: artpec6: dt: add missing pin group uart5nocts + - vfio-ccw: fence off transport mode + - dmaengine: qcom: bam_dma: get num-channels and num-ees from dt + - drm: omapdrm: dss: Move initialization code from component bind to probe + - ARM: dts: dra71-evm: Correct evm_sd regulator max voltage + - drm/amdgpu: disable GFX ring and disable PQ wptr in hw_fini + - drm/amdgpu: adjust timeout for ib_ring_tests(v2) + - net: stmmac: ensure that the device has released ownership before reading + data + - net: stmmac: ensure that the MSS desc is the last desc to set the own bit + - cpufreq: Reorder cpufreq_online() error code path + - dpaa_eth: fix SG mapping + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9220 + - udf: Provide saner default for invalid uid / gid + - ixgbe: prevent ptp_rx_hang from running when in FILTER_ALL mode + - sh_eth: fix TSU init on SH7734/R8A7740 + - power: supply: ltc2941-battery-gauge: Fix temperature units + - ARM: dts: bcm283x: Fix probing of bcm2835-i2s + - ARM: dts: bcm283x: Fix pin function of JTAG pins + - PCMCIA / PM: Avoid noirq suspend aborts during suspend-to-idle + - audit: return on memory error to avoid null pointer dereference + - net: stmmac: call correct function in stmmac_mac_config_rx_queues_routing() + - rcu: Call touch_nmi_watchdog() while printing stall warnings + - pinctrl: sh-pfc: r8a7796: Fix MOD_SEL register pin assignment for SSI pins + group + - dpaa_eth: fix pause capability advertisement logic + - MIPS: Octeon: Fix logging messages with spurious periods after newlines + - drm/rockchip: Respect page offset for PRIME mmap calls + - x86/apic: Set up through-local-APIC mode on the boot CPU if 'noapic' + specified + - perf test: Fix test case inet_pton to accept inlines. + - perf report: Fix wrong jump arrow + - perf tests: Use arch__compare_symbol_names to compare symbols + - perf report: Fix memory corruption in --branch-history mode --branch-history + - perf tests: Fix dwarf unwind for stripped binaries + - selftests/net: fixes psock_fanout eBPF test case + - netlabel: If PF_INET6, check sk_buff ip header version + - drm: rcar-du: lvds: Fix LVDS startup on R-Car Gen3 + - drm: rcar-du: lvds: Fix LVDS startup on R-Car Gen2 + - ARM: dts: at91: tse850: use the correct compatible for the eeprom + - regmap: Correct comparison in regmap_cached + - i40e: Add delay after EMP reset for firmware to recover + - ARM: dts: imx7d: cl-som-imx7: fix pinctrl_enet + - ARM: dts: porter: Fix HDMI output routing + - regulator: of: Add a missing 'of_node_put()' in an error handling path of + 'of_regulator_match()' + - pinctrl: mcp23s08: spi: Fix regmap debugfs entries + - kdb: make "mdr" command repeat + - drm/vmwgfx: Set dmabuf_size when vmw_dmabuf_init is successful + - perf tools: Add trace/beauty/generated/ into .gitignore + - tools: sync up .h files with the repective arch and uapi .h files + - MIPS: xilfpga: Stop generating useless dtb.o + - MIPS: xilfpga: Actually include FDT in fitImage + - MIPS: Fix build with DEBUG_ZBOOT and MACH_JZ4770 + - fix breakage caused by d_find_alias() semantics change + - Btrfs: fix error handling in btrfs_truncate() + - mmc: block: propagate correct returned value in mmc_rpmb_ioctl + - arm64: export tishift functions to modules + - bcma: fix buffer size caused crash in bcma_core_mips_print_irq() + - PM / core: Fix direct_complete handling for devices with no callbacks + - ARM: dts: sun4i: Fix incorrect clocks for displays + - bnxt_en: Ignore src port field in decap filter nodes + - kasan, slub: fix handling of kasan_slab_free hook + - riscv/spinlock: Strengthen implementations with fences + - platform/x86: dell-smbios: Fix memory leaks in build_tokens_sysfs() + - rxrpc: Fix resend event time calculation + - i40e: hold the RTNL lock while changing interrupt schemes + - hv_netvsc: Fix the return status in RX path + - firmware: fix checking for return values for fw_add_devm_name() + - bcache: set writeback_rate_update_seconds in range [1, 60] seconds + - bcache: fix cached_dev->count usage for bch_cache_set_error() + - bcache: stop dc->writeback_rate_update properly + - ibmvnic: Fix reset return from closed state + - powerpc/vas: Fix cleanup when VAS is not configured + - f2fs: flush cp pack except cp pack 2 page at first + - drm/amdgpu: Clean sdma wptr register when only enable wptr polling + - powerpc/mm/slice: Remove intermediate bitmap copy + - powerpc/mm/slice: create header files dedicated to slices + - powerpc/mm/slice: Enhance for supporting PPC32 + - powerpc/mm/slice: Fix hugepage allocation at hint address on 8xx + - ibmvnic: Allocate statistics buffers during probe + - dt-bindings: display: msm/dsi: Fix the PHY regulator supply props + - drm/amd/display: Set vsc pack revision when DPCD revision is >= 1.2 + - soc: renesas: r8a77970-sysc: fix power area parents + - drm/vblank: Data type fixes for 64-bit vblank sequences. + - selftests: Add FIB onlink tests + - soc: amlogic: meson-gx-pwrc-vpu: fix error on shutdown when domain is + powered off + * arm-smmu-v3 arm-smmu-v3.1.auto: failed to allocate MSIs (LP: #1785282) + - ACPICA: iasl: Add SMMUv3 device ID mapping index support + - ACPI/IORT: Remove temporary iort_get_id_mapping_index() ACPICA guard + * Driver iwlwifi for Intel Wireless-AC 9560 is slow and unreliable in kernel + 4.15.0-20-generic (LP: #1772467) + - scsi: hpsa: disable device during shutdown + * [Bionic] i2c: xlp9xx: Add SMBAlert support (LP: #1786981) + - i2c: xlp9xx: Add support for SMBAlert + * qeth: don't clobber buffer on async TX completion (LP: #1786057) + - s390/qeth: don't clobber buffer on async TX completion + * Linux 4.15.0-23 crashes during the boot process with a "Unable to handle + kernel NULL pointer dereference" message (LP: #1777338) + - x86/xen: Add call of speculative_store_bypass_ht_init() to PV paths + * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058) + - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio + * [Bionic] i2c: xlp9xx: Fix case where SSIF read transaction completes early + (LP: #1787240) + - i2c: xlp9xx: Fix case where SSIF read transaction completes early + * [Bionic] integrate upstream fix for Cavium zram driver (LP: #1787469) + - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from + CONFIG_VMAP_STACK" + - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK + - crypto: cavium - Limit result reading attempts + - crypto: cavium - Prevent division by zero + - crypto: cavium - Fix statistics pending request value + - crypto: cavium - Fix smp_processor_id() warnings + * Bugfix for handling of shadow doorbell buffer (LP: #1788222) + - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event + * nvme devices namespace assigned to the wrong controller (LP: #1789227) + - nvme/multipath: Fix multipath disabled naming collisions + * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before + walinuxagent.service (LP: #1739107) + - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before + walinuxagent.service + * hinic interfaces aren't getting predictable names (LP: #1783138) + - hinic: Link the logical network device to the pci device in sysfs + * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and + Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950) + - ACPI / LPSS: Avoid PM quirks on suspend and resume from S3 + - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation + * [Bionic] Bluetooth: Support RTL8723D and RTL8821C Devices (LP: #1784835) + - Bluetooth: btrtl: Add RTL8723D and RTL8821C devices + * CacheFiles: Error: Overlong wait for old active object to go away. + (LP: #1776254) + - cachefiles: Fix missing clear of the CACHEFILES_OBJECT_ACTIVE flag + - cachefiles: Wait rather than BUG'ing on "Unexpected object collision" + * fscache cookie refcount updated incorrectly during fscache object allocation + (LP: #1776277) // fscache cookie refcount updated incorrectly during fscache + object allocation (LP: #1776277) + - fscache: Fix reference overput in fscache_attach_object() error handling + * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336) + - Revert "UBUNTU: SAUCE: CacheFiles: fix a read_waiter/read_copier race" + - fscache: Allow cancelled operations to be enqueued + - cachefiles: Fix refcounting bug in backing-file read monitoring + * SMB3: Fix regression in server reconnect detection (LP: #1786110) + - smb3: on reconnect set PreviousSessionId field + * CVE-2018-1118 + - vhost: fix info leak due to uninitialized memory + + [ Ubuntu: 4.15.0-33.36 ] + + * linux: 4.15.0-33.36 -proposed tracker (LP: #1787149) + * RTNL assertion failure on ipvlan (LP: #1776927) + - ipvlan: drop ipv6 dependency + - ipvlan: use per device spinlock to protect addrs list updates + - SAUCE: fix warning from "ipvlan: drop ipv6 dependency" + * ubuntu_bpf_jit test failed on Bionic s390x systems (LP: #1753941) + - test_bpf: flag tests that cannot be jited on s390 + * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689) + - drm/nouveau: fix nouveau_dsm_get_client_id()'s return type + - drm/radeon: fix radeon_atpx_get_client_id()'s return type + - drm/amdgpu: fix amdgpu_atpx_get_client_id()'s return type + - platform/x86: apple-gmux: fix gmux_get_client_id()'s return type + - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA + - vga_switcheroo: set audio client id according to bound GPU id + * locking sockets broken due to missing AppArmor socket mediation patches + (LP: #1780227) + - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets + * Update2 for ocxl driver (LP: #1781436) + - ocxl: Fix page fault handler in case of fault on dying process + * netns: unable to follow an interface that moves to another netns + (LP: #1774225) + - net: core: Expose number of link up/down transitions + - dev: always advertise the new nsid when the netns iface changes + - dev: advertise the new ifindex when the netns iface changes + * [Bionic] Disk IO hangs when using BFQ as io scheduler (LP: #1780066) + - block, bfq: fix occurrences of request finish method's old name + - block, bfq: remove batches of confusing ifdefs + - block, bfq: add requeue-request hook + * HP ProBook 455 G5 needs mute-led-gpio fixup (LP: #1781763) + - ALSA: hda: add mute led support for HP ProBook 455 G5 + * [Bionic] bug fixes to improve stability of the ThunderX2 i2c driver + (LP: #1781476) + - i2c: xlp9xx: Fix issue seen when updating receive length + - i2c: xlp9xx: Make sure the transfer size is not more than + I2C_SMBUS_BLOCK_SIZE + * x86/kvm: fix LAPIC timer drift when guest uses periodic mode (LP: #1778486) + - x86/kvm: fix LAPIC timer drift when guest uses periodic mode + * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823) + - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules + * Nvidia fails after switching its mode (LP: #1778658) + - PCI: Restore config space on runtime resume despite being unbound + * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364) + - SAUCE: (noup) zfs to 0.7.5-1ubuntu16.3 + * CVE-2018-12232 + - PATCH 1/1] socket: close race condition between sock_close() and + sockfs_setattr() + * CVE-2018-10323 + - xfs: set format back to extents if xfs_bmap_extents_to_btree + * change front mic location for more lenovo m7/8/9xx machines (LP: #1781316) + - ALSA: hda/realtek - Fix the problem of two front mics on more machines + - ALSA: hda/realtek - two more lenovo models need fixup of MIC_LOCATION + * Cephfs + fscache: unable to handle kernel NULL pointer dereference at + 0000000000000000 IP: jbd2__journal_start+0x22/0x1f0 (LP: #1783246) + - ceph: track read contexts in ceph_file_info + * Touchpad of ThinkPad P52 failed to work with message "lost sync at byte" + (LP: #1779802) + - Input: elantech - fix V4 report decoding for module with middle key + - Input: elantech - enable middle button of touchpads on ThinkPad P52 + * xhci_hcd 0000:00:14.0: Root hub is not suspended (LP: #1779823) + - usb: xhci: dbc: Fix lockdep warning + - usb: xhci: dbc: Don't decrement runtime PM counter if DBC is not started + * CVE-2018-13406 + - video: uvesafb: Fix integer overflow in allocation + * CVE-2018-10840 + - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs + * CVE-2018-11412 + - ext4: do not allow external inodes for inline data + * CVE-2018-10881 + - ext4: clear i_data in ext4_inode_info when removing inline data + * CVE-2018-12233 + - jfs: Fix inconsistency between memory allocation and ea_buf->max_size + * CVE-2018-12904 + - kvm: nVMX: Enforce cpl=0 for VMX instructions + * Error parsing PCC subspaces from PCCT (LP: #1528684) + - mailbox: PCC: erroneous error message when parsing ACPI PCCT + * CVE-2018-13094 + - xfs: don't call xfs_da_shrink_inode with NULL bp + * other users' coredumps can be read via setgid directory and killpriv bypass + (LP: #1779923) // CVE-2018-13405 + - Fix up non-directory creation in SGID directories + * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166) + - snapcraft.yaml: stop invoking the obsolete (and non-existing) + 'firmware_install' target + * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build + (LP: #1782116) + - snapcraft.yaml: copy retpoline-extract-one to scripts before build + * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540) + - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge + * CVE-2018-11506 + - sr: pass down correctly sized SCSI sense buffer + * Bionic update: upstream stable patchset 2018-07-24 (LP: #1783418) + - net: Fix a bug in removing queues from XPS map + - net/mlx4_core: Fix error handling in mlx4_init_port_info. + - net/sched: fix refcnt leak in the error path of tcf_vlan_init() + - net: sched: red: avoid hashing NULL child + - net/smc: check for missing nlattrs in SMC_PNETID messages + - net: test tailroom before appending to linear skb + - packet: in packet_snd start writing at link layer allocation + - sock_diag: fix use-after-free read in __sk_free + - tcp: purge write queue in tcp_connect_init() + - vmxnet3: set the DMA mask before the first DMA map operation + - vmxnet3: use DMA memory barriers where required + - hv_netvsc: empty current transmit aggregation if flow blocked + - hv_netvsc: Use the num_online_cpus() for channel limit + - hv_netvsc: avoid retry on send during shutdown + - hv_netvsc: only wake transmit queue if link is up + - hv_netvsc: fix error unwind handling if vmbus_open fails + - hv_netvsc: cancel subchannel setup before halting device + - hv_netvsc: fix race in napi poll when rescheduling + - hv_netvsc: defer queue selection to VF + - hv_netvsc: disable NAPI before channel close + - hv_netvsc: use RCU to fix concurrent rx and queue changes + - hv_netvsc: change GPAD teardown order on older versions + - hv_netvsc: common detach logic + - hv_netvsc: Use Windows version instead of NVSP version on GPAD teardown + - hv_netvsc: Split netvsc_revoke_buf() and netvsc_teardown_gpadl() + - hv_netvsc: Ensure correct teardown message sequence order + - hv_netvsc: Fix a network regression after ifdown/ifup + - sparc: vio: use put_device() instead of kfree() + - ext2: fix a block leak + - s390: add assembler macros for CPU alternatives + - s390: move expoline assembler macros to a header + - s390/crc32-vx: use expoline for indirect branches + - s390/lib: use expoline for indirect branches + - s390/ftrace: use expoline for indirect branches + - s390/kernel: use expoline for indirect branches + - s390: move spectre sysfs attribute code + - s390: extend expoline to BC instructions + - s390: use expoline thunks in the BPF JIT + - scsi: sg: allocate with __GFP_ZERO in sg_build_indirect() + - scsi: zfcp: fix infinite iteration on ERP ready list + - loop: don't call into filesystem while holding lo_ctl_mutex + - loop: fix LOOP_GET_STATUS lock imbalance + - cfg80211: limit wiphy names to 128 bytes + - hfsplus: stop workqueue when fill_super() failed + - x86/kexec: Avoid double free_page() upon do_kexec_load() failure + - usb: gadget: f_uac2: fix bFirstInterface in composite gadget + - usb: dwc3: Undo PHY init if soft reset fails + - usb: dwc3: omap: don't miss events during suspend/resume + - usb: gadget: core: Fix use-after-free of usb_request + - usb: gadget: fsl_udc_core: fix ep valid checks + - usb: dwc2: Fix dwc2_hsotg_core_init_disconnected() + - usb: cdc_acm: prevent race at write to acm while system resumes + - net: usbnet: fix potential deadlock on 32bit hosts + - ARM: dts: imx7d-sdb: Fix regulator-usb-otg2-vbus node name + - usb: host: xhci-plat: revert "usb: host: xhci-plat: enable clk in resume + timing" + - USB: OHCI: Fix NULL dereference in HCDs using HCD_LOCAL_MEM + - net/usb/qmi_wwan.c: Add USB id for lt4120 modem + - net-usb: add qmi_wwan if on lte modem wistron neweb d18q1 + - Bluetooth: btusb: Add USB ID 7392:a611 for Edimax EW-7611ULB + - ALSA: usb-audio: Add native DSD support for Luxman DA-06 + - usb: dwc3: Add SoftReset PHY synchonization delay + - usb: dwc3: Update DWC_usb31 GTXFIFOSIZ reg fields + - usb: dwc3: Makefile: fix link error on randconfig + - xhci: zero usb device slot_id member when disabling and freeing a xhci slot + - usb: dwc2: Fix interval type issue + - usb: dwc2: hcd: Fix host channel halt flow + - usb: dwc2: host: Fix transaction errors in host mode + - usb: gadget: ffs: Let setup() return USB_GADGET_DELAYED_STATUS + - usb: gadget: ffs: Execute copy_to_user() with USER_DS set + - usbip: Correct maximum value of CONFIG_USBIP_VHCI_HC_PORTS + - usb: gadget: udc: change comparison to bitshift when dealing with a mask + - usb: gadget: composite: fix incorrect handling of OS desc requests + - media: lgdt3306a: Fix module count mismatch on usb unplug + - media: em28xx: USB bulk packet size fix + - Bluetooth: btusb: Add device ID for RTL8822BE + - xhci: Show what USB release number the xHC supports from protocol capablity + - staging: bcm2835-audio: Release resources on module_exit() + - staging: lustre: fix bug in osc_enter_cache_try + - staging: fsl-dpaa2/eth: Fix incorrect casts + - staging: rtl8192u: return -ENOMEM on failed allocation of priv->oldaddr + - staging: ks7010: Use constants from ieee80211_eid instead of literal ints. + - staging: lustre: lmv: correctly iput lmo_root + - crypto: inside-secure - wait for the request to complete if in the backlog + - crypto: atmel-aes - fix the keys zeroing on errors + - crypto: ccp - don't disable interrupts while setting up debugfs + - crypto: inside-secure - do not process request if no command was issued + - crypto: inside-secure - fix the cache_len computation + - crypto: inside-secure - fix the extra cache computation + - crypto: sunxi-ss - Add MODULE_ALIAS to sun4i-ss + - crypto: inside-secure - fix the invalidation step during cra_exit + - scsi: mpt3sas: fix an out of bound write + - scsi: ufs: Enable quirk to ignore sending WRITE_SAME command + - scsi: bnx2fc: Fix check in SCSI completion handler for timed out request + - scsi: sym53c8xx_2: iterator underflow in sym_getsync() + - scsi: mptfusion: Add bounds check in mptctl_hp_targetinfo() + - scsi: qla2xxx: Avoid triggering undefined behavior in + qla2x00_mbx_completion() + - scsi: storvsc: Increase cmd_per_lun for higher speed devices + - scsi: qedi: Fix truncation of CHAP name and secret + - scsi: aacraid: fix shutdown crash when init fails + - scsi: qla4xxx: skip error recovery in case of register disconnect. + - scsi: qedi: Fix kernel crash during port toggle + - scsi: mpt3sas: Do not mark fw_event workqueue as WQ_MEM_RECLAIM + - scsi: sd: Keep disk read-only when re-reading partition + - scsi: iscsi_tcp: set BDI_CAP_STABLE_WRITES when data digest enabled + - scsi: aacraid: Insure command thread is not recursively stopped + - scsi: core: Make SCSI Status CONDITION MET equivalent to GOOD + - scsi: mvsas: fix wrong endianness of sgpio api + - ASoC: hdmi-codec: Fix module unloading caused kernel crash + - ASoC: rockchip: rk3288-hdmi-analog: Select needed codecs + - ASoC: samsung: odroid: Fix 32000 sample rate handling + - ASoC: topology: create TLV data for dapm widgets + - ASoC: samsung: i2s: Ensure the RCLK rate is properly determined + - clk: rockchip: Fix wrong parent for SDMMC phase clock for rk3228 + - clk: Don't show the incorrect clock phase + - clk: hisilicon: mark wdt_mux_p[] as const + - clk: tegra: Fix pll_u rate configuration + - clk: rockchip: Prevent calculating mmc phase if clock rate is zero + - clk: samsung: s3c2410: Fix PLL rates + - clk: samsung: exynos7: Fix PLL rates + - clk: samsung: exynos5260: Fix PLL rates + - clk: samsung: exynos5433: Fix PLL rates + - clk: samsung: exynos5250: Fix PLL rates + - clk: samsung: exynos3250: Fix PLL rates + - media: dmxdev: fix error code for invalid ioctls + - media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array + - media: ov5645: add missing of_node_put() in error path + - media: cx23885: Override 888 ImpactVCBe crystal frequency + - media: cx23885: Set subdev host data to clk_freq pointer + - media: s3c-camif: fix out-of-bounds array access + - media: lgdt3306a: Fix a double kfree on i2c device remove + - media: em28xx: Add Hauppauge SoloHD/DualHD bulk models + - media: v4l: vsp1: Fix display stalls when requesting too many inputs + - media: i2c: adv748x: fix HDMI field heights + - media: vb2: Fix videobuf2 to map correct area + - media: vivid: fix incorrect capabilities for radio + - media: cx25821: prevent out-of-bounds read on array card + - serial: xuartps: Fix out-of-bounds access through DT alias + - serial: sh-sci: Fix out-of-bounds access through DT alias + - serial: samsung: Fix out-of-bounds access through serial port index + - serial: mxs-auart: Fix out-of-bounds access through serial port index + - serial: imx: Fix out-of-bounds access through serial port index + - serial: fsl_lpuart: Fix out-of-bounds access through DT alias + - serial: arc_uart: Fix out-of-bounds access through DT alias + - serial: 8250: Don't service RX FIFO if interrupts are disabled + - serial: altera: ensure port->regshift is honored consistently + - rtc: snvs: Fix usage of snvs_rtc_enable + - rtc: hctosys: Ensure system time doesn't overflow time_t + - rtc: rk808: fix possible race condition + - rtc: m41t80: fix race conditions + - rtc: tx4939: avoid unintended sign extension on a 24 bit shift + - rtc: rp5c01: fix possible race condition + - rtc: goldfish: Add missing MODULE_LICENSE + - cxgb4: Correct ntuple mask validation for hash filters + - net: dsa: bcm_sf2: Fix RX_CLS_LOC_ANY overwrite for last rule + - net: dsa: Do not register devlink for unused ports + - net: dsa: bcm_sf2: Fix IPv6 rules and chain ID + - net: dsa: bcm_sf2: Fix IPv6 rule half deletion + - 3c59x: convert to generic DMA API + - net: ip6_gre: Request headroom in __gre6_xmit() + - net: ip6_gre: Split up ip6gre_tnl_link_config() + - net: ip6_gre: Split up ip6gre_tnl_change() + - net: ip6_gre: Split up ip6gre_newlink() + - net: ip6_gre: Split up ip6gre_changelink() + - qed: LL2 flush isles when connection is closed + - qed: Fix possibility of list corruption during rmmod flows + - qed: Fix LL2 race during connection terminate + - powerpc: Move default security feature flags + - Bluetooth: btusb: Add support for Intel Bluetooth device 22560 [8087:0026] + - staging: fsl-dpaa2/eth: Fix incorrect kfree + - crypto: inside-secure - move the digest to the request context + - scsi: lpfc: Fix NVME Initiator FirstBurst + - serial: mvebu-uart: fix tx lost characters + * Bionic update: upstream stable patchset 2018-07-20 (LP: #1782846) + - usbip: usbip_host: refine probe and disconnect debug msgs to be useful + - usbip: usbip_host: delete device from busid_table after rebind + - usbip: usbip_host: run rebind from exit when module is removed + - usbip: usbip_host: fix NULL-ptr deref and use-after-free errors + - usbip: usbip_host: fix bad unlock balance during stub_probe() + - ALSA: usb: mixer: volume quirk for CM102-A+/102S+ + - ALSA: hda: Add Lenovo C50 All in one to the power_save blacklist + - ALSA: control: fix a redundant-copy issue + - spi: pxa2xx: Allow 64-bit DMA + - spi: bcm-qspi: Avoid setting MSPI_CDRAM_PCS for spi-nor master + - spi: bcm-qspi: Always read and set BSPI_MAST_N_BOOT_CTRL + - KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls + - KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock + - vfio: ccw: fix cleanup if cp_prefetch fails + - tracing/x86/xen: Remove zero data size trace events + trace_xen_mmu_flush_tlb{_all} + - tee: shm: fix use-after-free via temporarily dropped reference + - netfilter: nf_tables: free set name in error path + - netfilter: nf_tables: can't fail after linking rule into active rule list + - netfilter: nf_socket: Fix out of bounds access in nf_sk_lookup_slow_v{4,6} + - i2c: designware: fix poll-after-enable regression + - powerpc/powernv: Fix NVRAM sleep in invalid context when crashing + - drm: Match sysfs name in link removal to link creation + - lib/test_bitmap.c: fix bitmap optimisation tests to report errors correctly + - radix tree: fix multi-order iteration race + - mm: don't allow deferred pages with NEED_PER_CPU_KM + - drm/i915/gen9: Add WaClearHIZ_WM_CHICKEN3 for bxt and glk + - s390/qdio: fix access to uninitialized qdio_q fields + - s390/qdio: don't release memory in qdio_setup_irq() + - s390: remove indirect branch from do_softirq_own_stack + - x86/pkeys: Override pkey when moving away from PROT_EXEC + - x86/pkeys: Do not special case protection key 0 + - efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' + definition for mixed mode + - ARM: 8771/1: kprobes: Prohibit kprobes on do_undefinstr + - x86/mm: Drop TS_COMPAT on 64-bit exec() syscall + - tick/broadcast: Use for_each_cpu() specially on UP kernels + - ARM: 8769/1: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed + - ARM: 8770/1: kprobes: Prohibit probing on optimized_callback + - ARM: 8772/1: kprobes: Prohibit kprobes on get_user functions + - Btrfs: fix xattr loss after power failure + - Btrfs: send, fix invalid access to commit roots due to concurrent + snapshotting + - btrfs: property: Set incompat flag if lzo/zstd compression is set + - btrfs: fix crash when trying to resume balance without the resume flag + - btrfs: Split btrfs_del_delalloc_inode into 2 functions + - btrfs: Fix delalloc inodes invalidation during transaction abort + - btrfs: fix reading stale metadata blocks after degraded raid1 mounts + - xhci: Fix USB3 NULL pointer dereference at logical disconnect. + - KVM: arm/arm64: Properly protect VGIC locks from IRQs + - KVM: arm/arm64: VGIC/ITS: Promote irq_lock() in update_affinity + - hwmon: (k10temp) Fix reading critical temperature register + - hwmon: (k10temp) Use API function to access System Management Network + - vsprintf: Replace memory barrier with static_key for random_ptr_key update + - x86/amd_nb: Add support for Raven Ridge CPUs + - x86/apic/x2apic: Initialize cluster ID properly + * Bionic update: upstream stable patchset 2018-07-09 (LP: #1780858) + - 8139too: Use disable_irq_nosync() in rtl8139_poll_controller() + - bridge: check iface upper dev when setting master via ioctl + - dccp: fix tasklet usage + - ipv4: fix fnhe usage by non-cached routes + - ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg + - llc: better deal with too small mtu + - net: ethernet: sun: niu set correct packet size in skb + - net: ethernet: ti: cpsw: fix packet leaking in dual_mac mode + - net/mlx4_en: Fix an error handling path in 'mlx4_en_init_netdev()' + - net/mlx4_en: Verify coalescing parameters are in range + - net/mlx5e: Err if asked to offload TC match on frag being first + - net/mlx5: E-Switch, Include VF RDMA stats in vport statistics + - net sched actions: fix refcnt leak in skbmod + - net_sched: fq: take care of throttled flows before reuse + - net: support compat 64-bit time in {s,g}etsockopt + - net/tls: Don't recursively call push_record during tls_write_space callbacks + - net/tls: Fix connection stall on partial tls record + - openvswitch: Don't swap table in nlattr_set() after OVS_ATTR_NESTED is found + - qmi_wwan: do not steal interfaces from class drivers + - r8169: fix powering up RTL8168h + - rds: do not leak kernel memory to user land + - sctp: delay the authentication for the duplicated cookie-echo chunk + - sctp: fix the issue that the cookie-ack with auth can't get processed + - sctp: handle two v4 addrs comparison in sctp_inet6_cmp_addr + - sctp: remove sctp_chunk_put from fail_mark err path in + sctp_ulpevent_make_rcvmsg + - sctp: use the old asoc when making the cookie-ack chunk in dupcook_d + - tcp_bbr: fix to zero idle_restart only upon S/ACKed data + - tcp: ignore Fast Open on repair mode + - tg3: Fix vunmap() BUG_ON() triggered from tg3_free_consistent(). + - bonding: do not allow rlb updates to invalid mac + - bonding: send learning packets for vlans on slave + - net: sched: fix error path in tcf_proto_create() when modules are not + configured + - net/mlx5e: TX, Use correct counter in dma_map error flow + - net/mlx5: Avoid cleaning flow steering table twice during error flow + - hv_netvsc: set master device + - ipv6: fix uninit-value in ip6_multipath_l3_keys() + - net/mlx5e: Allow offloading ipv4 header re-write for icmp + - nsh: fix infinite loop + - udp: fix SO_BINDTODEVICE + - l2tp: revert "l2tp: fix missing print session offset info" + - proc: do not access cmdline nor environ from file-backed areas + - net/smc: restrict non-blocking connect finish + - mlxsw: spectrum_switchdev: Do not remove mrouter port from MDB's ports list + - net/mlx5e: DCBNL fix min inline header size for dscp + - net: systemport: Correclty disambiguate driver instances + - sctp: clear the new asoc's stream outcnt in sctp_stream_update + - tcp: restore autocorking + - tipc: fix one byte leak in tipc_sk_set_orig_addr() + - hv_netvsc: Fix net device attach on older Windows hosts + * Bionic update: upstream stable patchset 2018-07-06 (LP: #1780499) + - ext4: prevent right-shifting extents beyond EXT_MAX_BLOCKS + - ipvs: fix rtnl_lock lockups caused by start_sync_thread + - netfilter: ebtables: don't attempt to allocate 0-sized compat array + - kcm: Call strp_stop before strp_done in kcm_attach + - crypto: af_alg - fix possible uninit-value in alg_bind() + - netlink: fix uninit-value in netlink_sendmsg + - net: fix rtnh_ok() + - net: initialize skb->peeked when cloning + - net: fix uninit-value in __hw_addr_add_ex() + - dccp: initialize ireq->ir_mark + - ipv4: fix uninit-value in ip_route_output_key_hash_rcu() + - soreuseport: initialise timewait reuseport field + - inetpeer: fix uninit-value in inet_getpeer + - memcg: fix per_node_info cleanup + - perf: Remove superfluous allocation error check + - tcp: fix TCP_REPAIR_QUEUE bound checking + - bdi: wake up concurrent wb_shutdown() callers. + - bdi: Fix oops in wb_workfn() + - gpioib: do not free unrequested descriptors + - gpio: fix aspeed_gpio unmask irq + - gpio: fix error path in lineevent_create + - rfkill: gpio: fix memory leak in probe error path + - libata: Apply NOLPM quirk for SanDisk SD7UB3Q*G1001 SSDs + - dm integrity: use kvfree for kvmalloc'd memory + - tracing: Fix regex_match_front() to not over compare the test string + - z3fold: fix reclaim lock-ups + - mm: sections are not offlined during memory hotremove + - mm, oom: fix concurrent munlock and oom reaper unmap, v3 + - ceph: fix rsize/wsize capping in ceph_direct_read_write() + - can: kvaser_usb: Increase correct stats counter in kvaser_usb_rx_can_msg() + - can: hi311x: Acquire SPI lock on ->do_get_berr_counter + - can: hi311x: Work around TX complete interrupt erratum + - drm/vc4: Fix scaling of uni-planar formats + - drm/i915: Fix drm:intel_enable_lvds ERROR message in kernel log + - drm/atomic: Clean old_state/new_state in drm_atomic_state_default_clear() + - drm/atomic: Clean private obj old_state/new_state in + drm_atomic_state_default_clear() + - net: atm: Fix potential Spectre v1 + - atm: zatm: Fix potential Spectre v1 + - cpufreq: schedutil: Avoid using invalid next_freq + - Revert "Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174" + - Bluetooth: btusb: Only check needs_reset_resume DMI table for QCA rome + chipsets + - thermal: exynos: Reading temperature makes sense only when TMU is turned on + - thermal: exynos: Propagate error value from tmu_read() + - nvme: add quirk to force medium priority for SQ creation + - smb3: directory sync should not return an error + - sched/autogroup: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] + - tracing/uprobe_event: Fix strncpy corner case + - perf/x86: Fix possible Spectre-v1 indexing for hw_perf_event cache_* + - perf/x86/cstate: Fix possible Spectre-v1 indexing for pkg_msr + - perf/x86/msr: Fix possible Spectre-v1 indexing in the MSR driver + - perf/core: Fix possible Spectre-v1 indexing for ->aux_pages[] + - perf/x86: Fix possible Spectre-v1 indexing for x86_pmu::event_map() + - i2c: dev: prevent ZERO_SIZE_PTR deref in i2cdev_ioctl_rdwr() + - bdi: Fix use after free bug in debugfs_remove() + - drm/ttm: Use GFP_TRANSHUGE_LIGHT for allocating huge pages + - drm/i915: Adjust eDP's logical vco in a reliable place. + - drm/nouveau/ttm: don't dereference nvbo::cli, it can outlive client + - sched/core: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] + * Bionic update: upstream stable patchset 2018-06-26 (LP: #1778759) + - percpu: include linux/sched.h for cond_resched() + - ACPI / button: make module loadable when booted in non-ACPI mode + - USB: serial: option: Add support for Quectel EP06 + - ALSA: hda - Fix incorrect usage of IS_REACHABLE() + - ALSA: pcm: Check PCM state at xfern compat ioctl + - ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger() + - ALSA: dice: fix kernel NULL pointer dereference due to invalid calculation + for array index + - ALSA: aloop: Mark paused device as inactive + - ALSA: aloop: Add missing cable lock to ctl API callbacks + - tracepoint: Do not warn on ENOMEM + - scsi: target: Fix fortify_panic kernel exception + - Input: leds - fix out of bound access + - Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro + - rtlwifi: btcoex: Add power_on_setting routine + - rtlwifi: cleanup 8723be ant_sel definition + - xfs: prevent creating negative-sized file via INSERT_RANGE + - RDMA/cxgb4: release hw resources on device removal + - RDMA/ucma: Allow resolving address w/o specifying source address + - RDMA/mlx5: Fix multiple NULL-ptr deref errors in rereg_mr flow + - RDMA/mlx5: Protect from shift operand overflow + - NET: usb: qmi_wwan: add support for ublox R410M PID 0x90b2 + - IB/mlx5: Use unlimited rate when static rate is not supported + - IB/hfi1: Fix handling of FECN marked multicast packet + - IB/hfi1: Fix loss of BECN with AHG + - IB/hfi1: Fix NULL pointer dereference when invalid num_vls is used + - iw_cxgb4: Atomically flush per QP HW CQEs + - drm/vmwgfx: Fix a buffer object leak + - drm/bridge: vga-dac: Fix edid memory leak + - test_firmware: fix setting old custom fw path back on exit, second try + - errseq: Always report a writeback error once + - USB: serial: visor: handle potential invalid device configuration + - usb: dwc3: gadget: Fix list_del corruption in dwc3_ep_dequeue + - USB: Accept bulk endpoints with 1024-byte maxpacket + - USB: serial: option: reimplement interface masking + - USB: serial: option: adding support for ublox R410M + - usb: musb: host: fix potential NULL pointer dereference + - usb: musb: trace: fix NULL pointer dereference in musb_g_tx() + - platform/x86: asus-wireless: Fix NULL pointer dereference + - irqchip/qcom: Fix check for spurious interrupts + - tracing: Fix bad use of igrab in trace_uprobe.c + - [Config] CONFIG_ARM64_ERRATUM_1024718=y + - arm64: Add work around for Arm Cortex-A55 Erratum 1024718 + - Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro + - infiniband: mlx5: fix build errors when INFINIBAND_USER_ACCESS=m + - btrfs: Take trans lock before access running trans in check_delayed_ref + - drm/vc4: Make sure vc4_bo_{inc,dec}_usecnt() calls are balanced + - xhci: Fix use-after-free in xhci_free_virt_device + - platform/x86: Kconfig: Fix dell-laptop dependency chain. + - KVM: x86: remove APIC Timer periodic/oneshot spikes + - clocksource: Allow clocksource_mark_unstable() on unregistered clocksources + - clocksource: Initialize cs->wd_list + - clocksource: Consistent de-rate when marking unstable + * Bionic update: upstream stable patchset 2018-06-22 (LP: #1778265) + - ext4: set h_journal if there is a failure starting a reserved handle + - ext4: add MODULE_SOFTDEP to ensure crc32c is included in the initramfs + - ext4: add validity checks for bitmap block numbers + - ext4: fix bitmap position validation + - random: fix possible sleeping allocation from irq context + - random: rate limit unseeded randomness warnings + - usbip: usbip_event: fix to not print kernel pointer address + - usbip: usbip_host: fix to hold parent lock for device_attach() calls + - usbip: vhci_hcd: Fix usb device and sockfd leaks + - usbip: vhci_hcd: check rhport before using in vhci_hub_control() + - Revert "xhci: plat: Register shutdown for xhci_plat" + - USB: serial: simple: add libtransistor console + - USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster + - USB: serial: cp210x: add ID for NI USB serial console + - usb: core: Add quirk for HP v222w 16GB Mini + - USB: Increment wakeup count on remote wakeup. + - ALSA: usb-audio: Skip broken EU on Dell dock USB-audio + - virtio: add ability to iterate over vqs + - virtio_console: don't tie bufs to a vq + - virtio_console: free buffers after reset + - virtio_console: drop custom control queue cleanup + - virtio_console: move removal code + - virtio_console: reset on out of memory + - drm/virtio: fix vq wait_event condition + - tty: Don't call panic() at tty_ldisc_init() + - tty: n_gsm: Fix long delays with control frame timeouts in ADM mode + - tty: n_gsm: Fix DLCI handling for ADM mode if debug & 2 is not set + - tty: Avoid possible error pointer dereference at tty_ldisc_restore(). + - tty: Use __GFP_NOFAIL for tty_ldisc_get() + - ALSA: dice: fix OUI for TC group + - ALSA: dice: fix error path to destroy initialized stream data + - ALSA: hda - Skip jack and others for non-existing PCM streams + - ALSA: opl3: Hardening for potential Spectre v1 + - ALSA: asihpi: Hardening for potential Spectre v1 + - ALSA: hdspm: Hardening for potential Spectre v1 + - ALSA: rme9652: Hardening for potential Spectre v1 + - ALSA: control: Hardening for potential Spectre v1 + - ALSA: pcm: Return negative delays from SNDRV_PCM_IOCTL_DELAY. + - ALSA: core: Report audio_tstamp in snd_pcm_sync_ptr + - ALSA: seq: oss: Fix unbalanced use lock for synth MIDI device + - ALSA: seq: oss: Hardening for potential Spectre v1 + - ALSA: hda: Hardening for potential Spectre v1 + - ALSA: hda/realtek - Add some fixes for ALC233 + - ALSA: hda/realtek - Update ALC255 depop optimize + - ALSA: hda/realtek - change the location for one of two front mics + - mtd: spi-nor: cadence-quadspi: Fix page fault kernel panic + - mtd: cfi: cmdset_0001: Do not allow read/write to suspend erase block. + - mtd: cfi: cmdset_0001: Workaround Micron Erase suspend bug. + - mtd: cfi: cmdset_0002: Do not allow read/write to suspend erase block. + - mtd: rawnand: tango: Fix struct clk memory leak + - kobject: don't use WARN for registration failures + - scsi: sd: Defer spinning up drive while SANITIZE is in progress + - bfq-iosched: ensure to clear bic/bfqq pointers when preparing request + - vfio: ccw: process ssch with interrupts disabled + - ANDROID: binder: prevent transactions into own process. + - PCI: aardvark: Fix logic in advk_pcie_{rd,wr}_conf() + - PCI: aardvark: Set PIO_ADDR_LS correctly in advk_pcie_rd_conf() + - PCI: aardvark: Use ISR1 instead of ISR0 interrupt in legacy irq mode + - PCI: aardvark: Fix PCIe Max Read Request Size setting + - ARM: amba: Make driver_override output consistent with other buses + - ARM: amba: Fix race condition with driver_override + - ARM: amba: Don't read past the end of sysfs "driver_override" buffer + - ARM: socfpga_defconfig: Remove QSPI Sector 4K size force + - KVM: arm/arm64: Close VMID generation race + - crypto: drbg - set freed buffers to NULL + - ASoC: fsl_esai: Fix divisor calculation failure at lower ratio + - libceph: un-backoff on tick when we have a authenticated session + - libceph: reschedule a tick in finish_hunting() + - libceph: validate con->state at the top of try_write() + - fpga-manager: altera-ps-spi: preserve nCONFIG state + - earlycon: Use a pointer table to fix __earlycon_table stride + - drm/amdgpu: set COMPUTE_PGM_RSRC1 for SGPR/VGPR clearing shaders + - drm/i915: Enable display WA#1183 from its correct spot + - objtool, perf: Fix GCC 8 -Wrestrict error + - tools/lib/subcmd/pager.c: do not alias select() params + - x86/ipc: Fix x32 version of shmid64_ds and msqid64_ds + - x86/smpboot: Don't use mwait_play_dead() on AMD systems + - x86/microcode/intel: Save microcode patch unconditionally + - x86/microcode: Do not exit early from __reload_late() + - tick/sched: Do not mess with an enqueued hrtimer + - arm/arm64: KVM: Add PSCI version selection API + - powerpc/eeh: Fix race with driver un/bind + - serial: mvebu-uart: Fix local flags handling on termios update + - block: do not use interruptible wait anywhere + - ASoC: dmic: Fix clock parenting + - PCI / PM: Do not clear state_saved in pci_pm_freeze() when smart suspend is + set + - module: Fix display of wrong module .text address + - drm/edid: Reset more of the display info + - drm/i915/fbdev: Enable late fbdev initial configuration + - drm/i915/audio: set minimum CD clock to twice the BCLK + - drm/amd/display: Fix deadlock when flushing irq + - drm/amd/display: Disallow enabling CRTC without primary plane with FB + * Bionic update: upstream stable patchset 2018-06-22 (LP: #1778265) // + CVE-2018-1108. + - random: set up the NUMA crng instances after the CRNG is fully initialized + * Ryzen/Raven Ridge USB ports do not work (LP: #1756700) + - xhci: Fix USB ports for Dell Inspiron 5775 + * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux- + jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389) + - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device + * Need fix to aacraid driver to prevent panic (LP: #1770095) + - scsi: aacraid: Correct hba_send to include iu_type + * kernel: Fix arch random implementation (LP: #1775391) + - s390/archrandom: Rework arch random implementation. + * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390) + - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak. + * Various fixes for CXL kernel module (LP: #1774471) + - cxl: Remove function write_timebase_ctrl_psl9() for PSL9 + - cxl: Set the PBCQ Tunnel BAR register when enabling capi mode + - cxl: Report the tunneled operations status + - cxl: Configure PSL to not use APC virtual machines + - cxl: Disable prefault_mode in Radix mode + * Bluetooth not working (LP: #1764645) + - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models + * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491) + - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y + - SAUCE: wcn36xx: read MAC from file or randomly generate one + * fscache: Fix hanging wait on page discarded by writeback (LP: #1777029) + - fscache: Fix hanging wait on page discarded by writeback + + [ Ubuntu: 4.15.0-32.35 ] + + * CVE-2018-3620 // CVE-2018-3646 + - x86/Centaur: Initialize supported CPU features properly + - x86/Centaur: Report correct CPU/cache topology + - x86/CPU/AMD: Have smp_num_siblings and cpu_llc_id always be present + - perf/events/amd/uncore: Fix amd_uncore_llc ID to use pre-defined cpu_llc_id + - x86/CPU: Rename intel_cacheinfo.c to cacheinfo.c + - x86/CPU/AMD: Calculate last level cache ID from number of sharing threads + - x86/CPU: Modify detect_extended_topology() to return result + - x86/CPU/AMD: Derive CPU topology from CPUID function 0xB when available + - x86/CPU: Move cpu local function declarations to local header + - x86/CPU: Make intel_num_cpu_cores() generic + - x86/CPU: Move cpu_detect_cache_sizes() into init_intel_cacheinfo() + - x86/CPU: Move x86_cpuinfo::x86_max_cores assignment to + detect_num_cpu_cores() + - x86/CPU/AMD: Fix LLC ID bit-shift calculation + - x86/mm: Factor out pageattr _PAGE_GLOBAL setting + - x86/mm: Undo double _PAGE_PSE clearing + - x86/mm: Introduce "default" kernel PTE mask + - x86/espfix: Document use of _PAGE_GLOBAL + - x86/mm: Do not auto-massage page protections + - x86/mm: Remove extra filtering in pageattr code + - x86/mm: Comment _PAGE_GLOBAL mystery + - x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init + - x86/ldt: Fix support_pte_mask filtering in map_ldt_struct() + - x86/power/64: Fix page-table setup for temporary text mapping + - x86/pti: Filter at vma->vm_page_prot population + - x86/boot/64/clang: Use fixup_pointer() to access '__supported_pte_mask' + - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT + - x86/speculation/l1tf: Change order of offset/type in swap entry + - x86/speculation/l1tf: Protect swap entries against L1TF + - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation + - x86/speculation/l1tf: Make sure the first page is always reserved + - x86/speculation/l1tf: Add sysfs reporting for l1tf + - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings + - x86/speculation/l1tf: Limit swap file size to MAX_PA/2 + - x86/bugs: Move the l1tf function and define pr_fmt properly + - sched/smt: Update sched_smt_present at runtime + - x86/smp: Provide topology_is_primary_thread() + - x86/topology: Provide topology_smt_supported() + - cpu/hotplug: Make bringup/teardown of smp threads symmetric + - cpu/hotplug: Split do_cpu_down() + - cpu/hotplug: Provide knobs to control SMT + - x86/cpu: Remove the pointless CPU printout + - x86/cpu/AMD: Remove the pointless detect_ht() call + - x86/cpu/common: Provide detect_ht_early() + - x86/cpu/topology: Provide detect_extended_topology_early() + - x86/cpu/intel: Evaluate smp_num_siblings early + - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info + - x86/cpu/AMD: Evaluate smp_num_siblings early + - x86/apic: Ignore secondary threads if nosmt=force + - x86/speculation/l1tf: Extend 64bit swap file size limit + - x86/cpufeatures: Add detection of L1D cache flush support. + - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings + - x86/speculation/l1tf: Protect PAE swap entries against L1TF + - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE + - Revert "x86/apic: Ignore secondary threads if nosmt=force" + - cpu/hotplug: Boot HT siblings at least once + - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present + - x86/KVM/VMX: Add module argument for L1TF mitigation + - x86/KVM/VMX: Add L1D flush algorithm + - x86/KVM/VMX: Add L1D MSR based flush + - x86/KVM/VMX: Add L1D flush logic + - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers + - x86/KVM/VMX: Add find_msr() helper function + - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting + - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs + - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required + - cpu/hotplug: Online siblings when SMT control is turned on + - x86/litf: Introduce vmx status variable + - x86/kvm: Drop L1TF MSR list approach + - x86/l1tf: Handle EPT disabled state proper + - x86/kvm: Move l1tf setup function + - x86/kvm: Add static key for flush always + - x86/kvm: Serialize L1D flush parameter setter + - x86/kvm: Allow runtime control of L1D flush + - cpu/hotplug: Expose SMT control init function + - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early + - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations + - Documentation: Add section about CPU vulnerabilities + - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures + - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content + - Documentation/l1tf: Fix typos + - cpu/hotplug: detect SMT disabled by BIOS + - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush() + - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond' + - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush() + - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16 + - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d + - x86: Don't include linux/irq.h from asm/hardirq.h + - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d + - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr() + - Documentation/l1tf: Remove Yonah processors from not vulnerable list + - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability + - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry + - KVM: x86: Add a framework for supporting MSR-based features + - KVM: X86: Introduce kvm_get_msr_feature() + - KVM: VMX: support MSR_IA32_ARCH_CAPABILITIES as a feature MSR + - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry + - cpu/hotplug: Fix SMT supported evaluation + - x86/speculation/l1tf: Invert all not present mappings + - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert + - x86/mm/pat: Make set_memory_np() L1TF safe + - cpu: Fix per-cpu regression on ARM64 + * CVE-2018-5391 + - Revert "net: increase fragment memory usage limits" + + -- Marcelo Henrique Cerri Mon, 10 Sep 2018 10:32:26 -0300 + +linux-oracle (4.15.0-1002.2) bionic; urgency=medium + + * Miscellaneous Ubuntu changes + - [Packaging] linux-oracle: Only build the tools package for amd64 + - [Packaging] linux-oracle: Add ckt/oracle PPA to getabis + + -- Marcelo Henrique Cerri Mon, 13 Aug 2018 09:06:17 -0300 + +linux-oracle (4.15.0-1001.1) bionic; urgency=medium + + * Miscellaneous Ubuntu changes + - linux-oracle packaging + - [Config] linux-oracle: Update configs for the net_failover driver + + * Miscellaneous upstream changes + - virtio_net: propagate linkspeed/duplex settings from the hypervisor + - virtio_net: Introduce VIRTIO_NET_F_STANDBY feature bit + - net: unpollute priv_flags space + - net: introduce IFF_NO_RX_HANDLER + - page_pool: refurbish version of page_pool code + - net: Introduce generic failover module + - net: Introduce net_failover driver + - virtio_net: Extend virtio to use VF datapath when available + - net_failover: Use netdev_features_t instead of u32 + - net: net_failover: fix typo in net_failover_slave_register() + + -- Marcelo Henrique Cerri Thu, 09 Aug 2018 09:55:51 -0300 + +linux-oracle (4.15.0-1000.0) bionic; urgency=low + + [ Marcelo Henrique Cerri ] + + * empty entry + + -- Marcelo Henrique Cerri Mon, 06 Aug 2018 09:50:39 -0300 + +linux (4.15.0-29.31) bionic; urgency=medium + + * linux: 4.15.0-29.31 -proposed tracker (LP: #1782173) + + * [SRU Bionic][Cosmic] kernel panic in ipmi_ssif at msg_done_handler + (LP: #1777716) + - ipmi_ssif: Fix kernel panic at msg_done_handler + + * Update to ocxl driver for 18.04.1 (LP: #1775786) + - misc: ocxl: use put_device() instead of device_unregister() + - powerpc: Add TIDR CPU feature for POWER9 + - powerpc: Use TIDR CPU feature to control TIDR allocation + - powerpc: use task_pid_nr() for TID allocation + - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action + - ocxl: Expose the thread_id needed for wait on POWER9 + - ocxl: Add an IOCTL so userspace knows what OCXL features are available + - ocxl: Document new OCXL IOCTLs + - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait() + + * Critical upstream bugfix missing in Ubuntu 18.04 - frequent Xorg crash after + suspend (LP: #1776887) + - ocxl: Document the OCXL_IOCTL_GET_METADATA IOCTL + + * Hard LOCKUP observed on stressing Ubuntu 18 04 (LP: #1777194) + - powerpc: use NMI IPI for smp_send_stop + - powerpc: Fix smp_send_stop NMI IPI handling + + * IPL: ppc64_cpu --frequency hang with INFO: rcu_sched detected stalls on + CPUs/tasks on w34 and wsbmc016 with 920.1714.20170330n (LP: #1773964) + - rtc: opal: Fix OPAL RTC driver OPAL_BUSY loops + + * [Regression] EXT4-fs error (device sda2): ext4_validate_block_bitmap:383: + comm stress-ng: bg 4705: bad block bitmap checksum (LP: #1781709) + - SAUCE: Revert "UBUNTU: SAUCE: ext4: fix ext4_validate_inode_bitmap: comm + stress-ng: Corrupt inode bitmap" + - SAUCE: ext4: check for allocation block validity with block group locked + + -- Stefan Bader Tue, 17 Jul 2018 10:57:50 +0200 + +linux (4.15.0-28.30) bionic; urgency=medium + + * linux: 4.15.0-28.30 -proposed tracker (LP: #1781433) + + * Cannot set MTU higher than 1500 in Xen instance (LP: #1781413) + - xen-netfront: Fix mismatched rtnl_unlock + - xen-netfront: Update features after registering netdev + + -- Kamal Mostafa Thu, 12 Jul 2018 09:47:07 -0700 + +linux (4.15.0-27.29) bionic; urgency=medium + + * linux: 4.15.0-27.29 -proposed tracker (LP: #1781062) + + * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99: + comm stress-ng: Corrupt inode bitmap (LP: #1780137) + - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode + bitmap + + -- Khalid Elmously Tue, 10 Jul 2018 19:05:00 -0400 + +linux (4.15.0-26.28) bionic; urgency=medium + + * linux: 4.15.0-26.28 -proposed tracker (LP: #1780112) + + * failure to boot with linux-image-4.15.0-24-generic (LP: #1779827) // Cloud- + init causes potentially huge boot delays with 4.15 kernels (LP: #1780062) + - random: Make getrandom() ready earlier + + -- Stefan Bader Wed, 04 Jul 2018 17:52:52 +0200 + +linux (4.15.0-25.27) bionic; urgency=medium + + * linux: 4.15.0-25.27 -proposed tracker (LP: #1779354) + + * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736) + - scsi: hisi_sas: Update a couple of register settings for v3 hw + + * hisi_sas: Add missing PHY spinlock init (LP: #1777734) + - scsi: hisi_sas: Add missing PHY spinlock init + + * hisi_sas: improve read performance by pre-allocating slot DMA buffers + (LP: #1777727) + - scsi: hisi_sas: use dma_zalloc_coherent() + - scsi: hisi_sas: Use dmam_alloc_coherent() + - scsi: hisi_sas: Pre-allocate slot DMA buffers + + * hisi_sas: Failures during host reset (LP: #1777696) + - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw() + - scsi: hisi_sas: Fix the conflict between dev gone and host reset + - scsi: hisi_sas: Adjust task reject period during host reset + - scsi: hisi_sas: Add a flag to filter PHY events during reset + - scsi: hisi_sas: Release all remaining resources in clear nexus ha + + * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique + (LP: #1776750) + - scsi: hisi_sas: make SAS address of SATA disks unique + + * Vcs-Git header on bionic linux source package points to zesty git tree + (LP: #1766055) + - [Packaging]: Update Vcs-Git + + * large KVM instances run out of IRQ routes (LP: #1778261) + - SAUCE: kvm -- increase KVM_MAX_IRQ_ROUTES to 2048 on x86 + + -- Khalid Elmously Sun, 01 Jul 2018 23:10:18 +0000 + +linux (4.15.0-24.26) bionic; urgency=medium + + * linux: 4.15.0-24.26 -proposed tracker (LP: #1776338) + + * Bionic update: upstream stable patchset 2018-06-06 (LP: #1775483) + - drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs + - i40e: Fix attach VF to VM issue + - tpm: cmd_ready command can be issued only after granting locality + - tpm: tpm-interface: fix tpm_transmit/_cmd kdoc + - tpm: add retry logic + - Revert "ath10k: send (re)assoc peer command when NSS changed" + - bonding: do not set slave_dev npinfo before slave_enable_netpoll in + bond_enslave + - ipv6: add RTA_TABLE and RTA_PREFSRC to rtm_ipv6_policy + - ipv6: sr: fix NULL pointer dereference in seg6_do_srh_encap()- v4 pkts + - KEYS: DNS: limit the length of option strings + - l2tp: check sockaddr length in pppol2tp_connect() + - net: validate attribute sizes in neigh_dump_table() + - llc: delete timers synchronously in llc_sk_free() + - tcp: don't read out-of-bounds opsize + - net: af_packet: fix race in PACKET_{R|T}X_RING + - tcp: md5: reject TCP_MD5SIG or TCP_MD5SIG_EXT on established sockets + - net: fix deadlock while clearing neighbor proxy table + - team: avoid adding twice the same option to the event list + - net/smc: fix shutdown in state SMC_LISTEN + - team: fix netconsole setup over team + - packet: fix bitfield update race + - tipc: add policy for TIPC_NLA_NET_ADDR + - pppoe: check sockaddr length in pppoe_connect() + - vlan: Fix reading memory beyond skb->tail in skb_vlan_tagged_multi + - amd-xgbe: Add pre/post auto-negotiation phy hooks + - sctp: do not check port in sctp_inet6_cmp_addr + - amd-xgbe: Improve KR auto-negotiation and training + - strparser: Do not call mod_delayed_work with a timeout of LONG_MAX + - amd-xgbe: Only use the SFP supported transceiver signals + - strparser: Fix incorrect strp->need_bytes value. + - net: sched: ife: signal not finding metaid + - tcp: clear tp->packets_out when purging write queue + - net: sched: ife: handle malformed tlv length + - net: sched: ife: check on metadata length + - llc: hold llc_sap before release_sock() + - llc: fix NULL pointer deref for SOCK_ZAPPED + - net: ethernet: ti: cpsw: fix tx vlan priority mapping + - virtio_net: split out ctrl buffer + - virtio_net: fix adding vids on big-endian + - KVM: s390: force bp isolation for VSIE + - s390: correct module section names for expoline code revert + - microblaze: Setup dependencies for ASM optimized lib functions + - commoncap: Handle memory allocation failure. + - scsi: mptsas: Disable WRITE SAME + - cdrom: information leak in cdrom_ioctl_media_changed() + - m68k/mac: Don't remap SWIM MMIO region + - block/swim: Check drive type + - block/swim: Don't log an error message for an invalid ioctl + - block/swim: Remove extra put_disk() call from error path + - block/swim: Rename macros to avoid inconsistent inverted logic + - block/swim: Select appropriate drive on device open + - block/swim: Fix array bounds check + - block/swim: Fix IO error at end of medium + - tracing: Fix missing tab for hwlat_detector print format + - s390/cio: update chpid descriptor after resource accessibility event + - s390/dasd: fix IO error for newly defined devices + - s390/uprobes: implement arch_uretprobe_is_alive() + - ACPI / video: Only default only_lcd to true on Win8-ready _desktops_ + - docs: ip-sysctl.txt: fix name of some ipv6 variables + - net: mvpp2: Fix DMA address mask size + - net: stmmac: Disable ACS Feature for GMAC >= 4 + - l2tp: hold reference on tunnels in netlink dumps + - l2tp: hold reference on tunnels printed in pppol2tp proc file + - l2tp: hold reference on tunnels printed in l2tp/tunnels debugfs file + - l2tp: fix {pppol2tp, l2tp_dfs}_seq_stop() in case of seq_file overflow + - s390/qeth: fix error handling in adapter command callbacks + - s390/qeth: avoid control IO completion stalls + - s390/qeth: handle failure on workqueue creation + - bnxt_en: Fix memory fault in bnxt_ethtool_init() + - virtio-net: add missing virtqueue kick when flushing packets + - VSOCK: make af_vsock.ko removable again + - hwmon: (k10temp) Add temperature offset for Ryzen 2700X + - hwmon: (k10temp) Add support for AMD Ryzen w/ Vega graphics + - s390/cpum_cf: rename IBM z13/z14 counter names + - kprobes: Fix random address output of blacklist file + - Revert "pinctrl: intel: Initialize GPIO properly when used through irqchip" + + * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636) + - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist + + * bluetooth controller fail after suspend with USB autosuspend on XPS 13 9360 + (LP: #1775217) + - Bluetooth: btusb: Add Dell XPS 13 9360 to btusb_needs_reset_resume_table + + * [Hyper-V] PCI: hv: Fix 2 hang issues in hv_compose_msi_msg (LP: #1758378) + - PCI: hv: Only queue new work items in hv_pci_devices_present() if necessary + - PCI: hv: Remove the bogus test in hv_eject_device_work() + - PCI: hv: Fix a comment typo in _hv_pcifront_read_config() + + * register on binfmt_misc may overflow and crash the system (LP: #1775856) + - fs/binfmt_misc.c: do not allow offset overflow + + * CVE-2018-11508 + - compat: fix 4-byte infoleak via uninitialized struct field + + * Network installs fail on SocioNext board (LP: #1775884) + - net: netsec: reduce DMA mask to 40 bits + - net: socionext: reset hardware in ndo_stop + - net: netsec: enable tx-irq during open callback + + * r8169 ethernet card don't work after returning from suspension + (LP: #1752772) + - PCI: Add pcim_set_mwi(), a device-managed pci_set_mwi() + - r8169: switch to device-managed functions in probe + - r8169: remove netif_napi_del in probe error path + - r8169: remove some WOL-related dead code + - r8169: disable WOL per default + - r8169: improve interrupt handling + - r8169: fix interrupt number after adding support for MSI-X interrupts + + * ISST-LTE:KVM:Ubuntu18.04:BostonLC:boslcp3:boslcp3g3:Guest conosle hangs + after hotplug CPU add operation. (LP: #1759723) + - genirq/affinity: assign vectors to all possible CPUs + - genirq/affinity: Don't return with empty affinity masks on error + - genirq/affinity: Rename *node_to_possible_cpumask as *node_to_cpumask + - genirq/affinity: Move actual irq vector spreading into a helper function + - genirq/affinity: Allow irq spreading from a given starting point + - genirq/affinity: Spread irq vectors among present CPUs as far as possible + - blk-mq: simplify queue mapping & schedule with each possisble CPU + - blk-mq: make sure hctx->next_cpu is set correctly + - blk-mq: Avoid that blk_mq_delay_run_hw_queue() introduces unintended delays + - blk-mq: make sure that correct hctx->next_cpu is set + - blk-mq: avoid to write intermediate result to hctx->next_cpu + - blk-mq: introduce blk_mq_hw_queue_first_cpu() to figure out first cpu + - blk-mq: don't check queue mapped in __blk_mq_delay_run_hw_queue() + - nvme: pci: pass max vectors as num_possible_cpus() to pci_alloc_irq_vectors + - scsi: hpsa: fix selection of reply queue + - scsi: megaraid_sas: fix selection of reply queue + - scsi: core: introduce force_blk_mq + - scsi: virtio_scsi: fix IO hang caused by automatic irq vector affinity + - scsi: virtio_scsi: unify scsi_host_template + + * Fix several bugs in RDMA/hns driver (LP: #1770974) + - RDMA/hns: Use structs to describe the uABI instead of opencoding + - RDMA/hns: Remove unnecessary platform_get_resource() error check + - RDMA/hns: Remove unnecessary operator + - RDMA/hns: Add names to function arguments in function pointers + - RDMA/hns: Fix misplaced call to hns_roce_cleanup_hem_table + - RDMA/hns: Fix a bug with modifying mac address + - RDMA/hns: Use free_pages function instead of free_page + - RDMA/hns: Replace __raw_write*(cpu_to_le*()) with LE write*() + - RDMA/hns: Bugfix for init hem table + - RDMA/hns: Intercept illegal RDMA operation when use inline data + - RDMA/hns: Fix the qp context state diagram + - RDMA/hns: Only assign mtu if IB_QP_PATH_MTU bit is set + - RDMA/hns: Remove some unnecessary attr_mask judgement + - RDMA/hns: Only assign dqpn if IB_QP_PATH_DEST_QPN bit is set + - RDMA/hns: Adjust the order of cleanup hem table + - RDMA/hns: Update assignment method for owner field of send wqe + - RDMA/hns: Submit bad wr + - RDMA/hns: Fix a couple misspellings + - RDMA/hns: Add rq inline flags judgement + - RDMA/hns: Bugfix for rq record db for kernel + - RDMA/hns: Load the RoCE dirver automatically + - RDMA/hns: Update convert function of endian format + - RDMA/hns: Add return operation when configured global param fail + - RDMA/hns: Not support qp transition from reset to reset for hip06 + - RDMA/hns: Fix the bug with rq sge + - RDMA/hns: Set desc_dma_addr for zero when free cmq desc + - RDMA/hns: Enable inner_pa_vld filed of mpt + - RDMA/hns: Set NULL for __internal_mr + - RDMA/hns: Fix the bug with NULL pointer + - RDMA/hns: Bugfix for cq record db for kernel + - RDMA/hns: Move the location for initializing tmp_len + - RDMA/hns: Drop local zgid in favor of core defined variable + - RDMA/hns: Add 64KB page size support for hip08 + - RDMA/hns: Rename the idx field of db + - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust + - RDMA/hns: Increase checking CMQ status timeout value + - RDMA/hns: Add reset process for RoCE in hip08 + - RDMA/hns: Fix the illegal memory operation when cross page + - RDMA/hns: Implement the disassociate_ucontext API + + * powerpc/livepatch: Implement reliable stack tracing for the consistency + model (LP: #1771844) + - powerpc/livepatch: Implement reliable stack tracing for the consistency + model + + * vmxnet3: update to latest ToT (LP: #1768143) + - vmxnet3: avoid xmit reset due to a race in vmxnet3 + - vmxnet3: use correct flag to indicate LRO feature + - vmxnet3: fix incorrect dereference when rxvlan is disabled + + * 4.15.0-22-generic fails to boot on IBM S822LC (POWER8 (raw), altivec + supported) (LP: #1773162) + - Revert "powerpc/64s: Add support for a store forwarding barrier at kernel + entry/exit" + - powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit + + * Decode ARM CPER records in kernel (LP: #1770244) + - [Config] CONFIG_UEFI_CPER_ARM=y + - efi: Move ARM CPER code to new file + - efi: Parse ARM error information value + + * Adding back alx WoL feature (LP: #1772610) + - SAUCE: Revert "alx: remove WoL support" + - SAUCE: alx: add enable_wol paramenter + + * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103) + - scsi: lpfc: Fix WQ/CQ creation for older asic's. + - scsi: lpfc: Fix 16gb hbas failing cq create. + + * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5 + idle states when all CORES are guarded (LP: #1771780) + - SAUCE: cpuidle/powernv : init all present cpus for deep states + + * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970) + - net-next/hinic: add pci device ids for 25ge and 100ge card + + * [Ubuntu 18.04.1] POWER9 - Nvidia Volta - Kernel changes to enable Nvidia + driver on bare metal (LP: #1772991) + - powerpc/powernv/npu: Fix deadlock in mmio_invalidate() + - powerpc/powernv/mce: Don't silently restart the machine + - powerpc/npu-dma.c: Fix crash after __mmu_notifier_register failure + - powerpc/mm: Flush cache on memory hot(un)plug + - powerpc/powernv/memtrace: Let the arch hotunplug code flush cache + - powerpc/powernv/npu: Add lock to prevent race in concurrent context + init/destroy + - powerpc/powernv/npu: Prevent overwriting of pnv_npu2_init_contex() callback + parameters + - powerpc/powernv/npu: Do a PID GPU TLB flush when invalidating a large + address range + - powerpc/mce: Fix a bug where mce loops on memory UE. + + * cpum_sf: ensure sample freq is non-zero (LP: #1772593) + - s390/cpum_sf: ensure sample frequency of perf event attributes is non-zero + + * PCIe link speeds of 16 GT/s are shown as "Unknown speed" (LP: #1773243) + - PCI: Add decoding for 16 GT/s link speed + + * False positive ACPI _PRS error messages (LP: #1773295) + - ACPI / PCI: pci_link: Allow the absence of _PRS and change log level + + * Dell systems crash when disabling Nvidia dGPU (LP: #1773299) + - ACPI / OSI: Add OEM _OSI strings to disable NVidia RTD3 + + * wlp3s0: failed to remove key (1, ff:ff:ff:ff:ff:ff) from hardware (-22) + (LP: #1720930) + - iwlwifi: mvm: fix "failed to remove key" message + + * Expose arm64 CPU topology to userspace (LP: #1770231) + - ACPICA: ACPI 6.2: Additional PPTT flags + - drivers: base: cacheinfo: move cache_setup_of_node() + - drivers: base: cacheinfo: setup DT cache properties early + - cacheinfo: rename of_node to fw_token + - arm64/acpi: Create arch specific cpu to acpi id helper + - ACPI/PPTT: Add Processor Properties Topology Table parsing + - [Config] CONFIG_ACPI_PPTT=y + - ACPI: Enable PPTT support on ARM64 + - drivers: base cacheinfo: Add support for ACPI based firmware tables + - arm64: Add support for ACPI based firmware tables + - arm64: topology: rename cluster_id + - arm64: topology: enable ACPI/PPTT based CPU topology + - ACPI: Add PPTT to injectable table list + - arm64: topology: divorce MC scheduling domain from core_siblings + + * hisi_sas robustness fixes (LP: #1774466) + - scsi: hisi_sas: delete timer when removing hisi_sas driver + - scsi: hisi_sas: print device id for errors + - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice + - scsi: hisi_sas: check host frozen before calling "done" function + - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task() + - scsi: hisi_sas: stop controller timer for reset + - scsi: hisi_sas: update PHY linkrate after a controller reset + - scsi: hisi_sas: change slot index allocation mode + - scsi: hisi_sas: Change common allocation mode of device id + - scsi: hisi_sas: Reset disks when discovered + - scsi: hisi_sas: Create a scsi_host_template per HW module + - scsi: hisi_sas: Init disks after controller reset + - scsi: hisi_sas: Try wait commands before before controller reset + - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot + - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command + - scsi: hisi_sas: Terminate STP reject quickly for v2 hw + - scsi: hisi_sas: Fix return value when get_free_slot() failed + - scsi: hisi_sas: Mark PHY as in reset for nexus reset + + * hisi_sas: Support newer v3 hardware (LP: #1774467) + - scsi: hisi_sas: update RAS feature for later revision of v3 HW + - scsi: hisi_sas: check IPTT is valid before using it for v3 hw + - scsi: hisi_sas: fix PI memory size + - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw + - scsi: hisi_sas: remove redundant handling to event95 for v3 + - scsi: hisi_sas: add readl poll timeout helper wrappers + - scsi: hisi_sas: workaround a v3 hw hilink bug + - scsi: hisi_sas: Add LED feature for v3 hw + + * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472) + - scsi: hisi_sas: initialize dq spinlock before use + - scsi: hisi_sas: optimise the usage of DQ locking + - scsi: hisi_sas: relocate smp sg map + - scsi: hisi_sas: make return type of prep functions void + - scsi: hisi_sas: allocate slot buffer earlier + - scsi: hisi_sas: Don't lock DQ for complete task sending + - scsi: hisi_sas: Use device lock to protect slot alloc/free + - scsi: hisi_sas: add check of device in hisi_sas_task_exec() + - scsi: hisi_sas: fix a typo in hisi_sas_task_prep() + + * Request to revert SAUCE patches in the 18.04 SRU and update with upstream + version (LP: #1768431) + - scsi: cxlflash: Handle spurious interrupts + - scsi: cxlflash: Remove commmands from pending list on timeout + - scsi: cxlflash: Synchronize reset and remove ops + - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3 + + * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520) + - SAUCE: Revert "drm/i915/edp: Allow alternate fixed mode for eDP if + available." + + * ELANPAD ELAN0612 does not work, patch available (LP: #1773509) + - SAUCE: Input: elan_i2c - add ELAN0612 to the ACPI table + + * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336) + - SAUCE: CacheFiles: fix a read_waiter/read_copier race + + * hns3 driver updates (LP: #1768670) + - net: hns3: VF should get the real rss_size instead of rss_size_max + - net: hns3: set the cmdq out_vld bit to 0 after used + - net: hns3: fix endian issue when PF get mbx message flag + - net: hns3: fix the queue id for tqp enable&&reset + - net: hns3: set the max ring num when alloc netdev + - net: hns3: add support for VF driver inner interface + hclgevf_ops.get_tqps_and_rss_info + - net: hns3: refactor the hclge_get/set_rss function + - net: hns3: refactor the hclge_get/set_rss_tuple function + - net: hns3: fix for RSS configuration loss problem during reset + - net: hns3: fix for pause configuration lost during reset + - net: hns3: fix for use-after-free when setting ring parameter + - net: hns3: refactor the get/put_vector function + - net: hns3: fix for coalesce configuration lost during reset + - net: hns3: refactor the coalesce related struct + - net: hns3: fix for coal configuation lost when setting the channel + - net: hns3: add existence check when remove old uc mac address + - net: hns3: fix for netdev not running problem after calling net_stop and + net_open + - net: hns3: fix for ipv6 address loss problem after setting channels + - net: hns3: unify the pause params setup function + - net: hns3: fix rx path skb->truesize reporting bug + - net: hns3: add support for querying pfc puase packets statistic + - net: hns3: fix for loopback failure when vlan filter is enable + - net: hns3: fix for buffer overflow smatch warning + - net: hns3: fix error type definition of return value + - net: hns3: fix return value error of hclge_get_mac_vlan_cmd_status() + - net: hns3: add existence checking before adding unicast mac address + - net: hns3: add result checking for VF when modify unicast mac address + - net: hns3: reallocate tx/rx buffer after changing mtu + - net: hns3: fix the VF queue reset flow error + - net: hns3: fix for vlan table lost problem when resetting + - net: hns3: increase the max time for IMP handle command + - net: hns3: change GL update rate + - net: hns3: change the time interval of int_gl calculating + - net: hns3: fix for getting wrong link mode problem + - net: hns3: add get_link support to VF + - net: hns3: add querying speed and duplex support to VF + - net: hns3: fix for not returning problem in get_link_ksettings when phy + exists + - net: hns3: Changes to make enet watchdog timeout func common for PF/VF + - net: hns3: Add VF Reset Service Task to support event handling + - net: hns3: Add VF Reset device state and its handling + - net: hns3: Add support to request VF Reset to PF + - net: hns3: Add support to reset the enet/ring mgmt layer + - net: hns3: Add support to re-initialize the hclge device + - net: hns3: Changes to support ARQ(Asynchronous Receive Queue) + - net: hns3: Add *Asserting Reset* mailbox message & handling in VF + - net: hns3: Changes required in PF mailbox to support VF reset + - net: hns3: hclge_inform_reset_assert_to_vf() can be static + - net: hns3: fix for returning wrong value problem in hns3_get_rss_key_size + - net: hns3: fix for returning wrong value problem in hns3_get_rss_indir_size + - net: hns3: fix for the wrong shift problem in hns3_set_txbd_baseinfo + - net: hns3: fix for not initializing VF rss_hash_key problem + - net: hns3: never send command queue message to IMP when reset + - net: hns3: remove unnecessary pci_set_drvdata() and devm_kfree() + - net: hns3: fix length overflow when CONFIG_ARM64_64K_PAGES + - net: hns3: Remove error log when getting pfc stats fails + - net: hns3: fix to correctly fetch l4 protocol outer header + - net: hns3: Fixes the out of bounds access in hclge_map_tqp + - net: hns3: Fixes the error legs in hclge_init_ae_dev function + - net: hns3: fix for phy_addr error in hclge_mac_mdio_config + - net: hns3: Fix to support autoneg only for port attached with phy + - net: hns3: fix a dead loop in hclge_cmd_csq_clean + - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls + - net: hns3: Remove packet statistics in the range of 8192~12287 + - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver + - net: hns3: Fix for setting mac address when resetting + - net: hns3: remove add/del_tunnel_udp in hns3_enet module + - net: hns3: fix for cleaning ring problem + - net: hns3: refactor the loopback related function + - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo + - net: hns3: Fix for the null pointer problem occurring when initializing + ae_dev failed + - net: hns3: Add a check for client instance init state + - net: hns3: Change return type of hnae3_register_ae_dev + - net: hns3: Change return type of hnae3_register_ae_algo + - net: hns3: Change return value in hnae3_register_client + - net: hns3: Fixes the back pressure setting when sriov is enabled + - net: hns3: Fix for fiber link up problem + - net: hns3: Add support of .sriov_configure in HNS3 driver + - net: hns3: Fixes the missing PCI iounmap for various legs + - net: hns3: Fixes error reported by Kbuild and internal review + - net: hns3: Fixes API to fetch ethernet header length with kernel default + - net: hns3: cleanup of return values in hclge_init_client_instance() + - net: hns3: Fix the missing client list node initialization + - net: hns3: Fix for hns3 module is loaded multiple times problem + - net: hns3: Use enums instead of magic number in hclge_is_special_opcode + - net: hns3: Fix for netdev not running problem after calling net_stop and + net_open + - net: hns3: Fixes kernel panic issue during rmmod hns3 driver + - net: hns3: Fix for CMDQ and Misc. interrupt init order problem + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config + - net: hns3: Add STRP_TAGP field support for hardware revision 0x21 + - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21) + - net: hns3: Fix for PF mailbox receving unknown message + - net: hns3: Fixes the state to indicate client-type initialization + - net: hns3: Fixes the init of the VALID BD info in the descriptor + - net: hns3: Removes unnecessary check when clearing TX/RX rings + - net: hns3: Clear TX/RX rings when stopping port & un-initializing client + - net: hns3: Remove unused led control code + - net: hns3: Adds support for led locate command for copper port + - net: hns3: Fixes initalization of RoCE handle and makes it conditional + - net: hns3: Disable vf vlan filter when vf vlan table is full + - net: hns3: Add support for IFF_ALLMULTI flag + - net: hns3: Add repeat address checking for setting mac address + - net: hns3: Fix setting mac address error + - net: hns3: Fix for service_task not running problem after resetting + - net: hns3: Fix for hclge_reset running repeatly problem + - net: hns3: Fix for phy not link up problem after resetting + - net: hns3: Add missing break in misc_irq_handle + - net: hns3: Fix for vxlan tx checksum bug + - net: hns3: Optimize the PF's process of updating multicast MAC + - net: hns3: Optimize the VF's process of updating multicast MAC + - SAUCE: {topost} net: hns3: add support for serdes loopback selftest + - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except + VLD bit and buffer size + - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from + hclge_bind_ring_with_vector + - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - SAUCE: {topost} net: hns3: add vector status check before free vector + - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6 + - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c + - SAUCE: {topost} net: hns3: extraction an interface for state state + init|uninit + - SAUCE: {topost} net: hns3: print the ret value in error information + - SAUCE: {topost} net: hns3: remove the Redundant put_vector in + hns3_client_uninit + - SAUCE: {topost} net: hns3: add unlikely for error check + - SAUCE: {topost} net: hns3: remove back in struct hclge_hw + - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits + - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir + - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean + - SAUCE: {topost} net: hns3: using modulo for cyclic counters in + hclge_cmd_send + - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done + - SAUCE: {topost} net: hns3: remove some unused members of some structures + - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set + - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of + kzalloc/dma_map_single + - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_ + - SAUCE: {topost} net: hns3: fix unused function warning in VF driver + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: standardize the handle of return value + - SAUCE: {topost} net: hns3: remove extra space and brackets + - SAUCE: {topost} net: hns3: fix unreasonable code comments + - SAUCE: {topost} net: hns3: use decimal for bit offset macros + - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros + - SAUCE: {topost} net: hns3: fix mislead parameter name + - SAUCE: {topost} net: hns3: remove unused struct member and definition + - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver + - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE + - SAUCE: {topost} net: hns3: optimize the process of notifying roce client + - SAUCE: {topost} net: hns3: Add calling roce callback function when link + status change + - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up + - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode + - SAUCE: {topost} net: hns3: fix for waterline not setting correctly + - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug + - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem + - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size + - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest + - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module + - SAUCE: {topost} net: hns3: remove the warning when clear reset cause + - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback + function + - SAUCE: {topost} net: hns3: prevent sending command during global or core + reset + - SAUCE: {topost} net: hns3: modify the order of initializeing command queue + register + - SAUCE: {topost} net: hns3: reset net device with rtnl_lock + - SAUCE: {topost} net: hns3: prevent to request reset frequently + - SAUCE: {topost} net: hns3: correct reset event status register + - SAUCE: {topost} net: hns3: separate roce from nic when resetting + - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver + - SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet + - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation + while resetting + - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm + - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx + - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response + - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message + - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process + + * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306) + - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs + + * Bionic update: upstream stable patchset 2018-05-29 (LP: #1774063) + - cifs: do not allow creating sockets except with SMB1 posix exensions + - btrfs: fix unaligned access in readdir + - x86/acpi: Prevent X2APIC id 0xffffffff from being accounted + - clocksource/imx-tpm: Correct -ETIME return condition check + - x86/tsc: Prevent 32bit truncation in calc_hpet_ref() + - drm/vc4: Fix memory leak during BO teardown + - drm/i915/gvt: throw error on unhandled vfio ioctls + - drm/i915/audio: Fix audio detection issue on GLK + - drm/i915: Do no use kfree() to free a kmem_cache_alloc() return value + - drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state + - drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing + - usb: musb: fix enumeration after resume + - usb: musb: call pm_runtime_{get,put}_sync before reading vbus registers + - usb: musb: Fix external abort in musb_remove on omap2430 + - firewire-ohci: work around oversized DMA reads on JMicron controllers + - x86/tsc: Allow TSC calibration without PIT + - NFSv4: always set NFS_LOCK_LOST when a lock is lost. + - ACPI / LPSS: Do not instiate platform_dev for devs without MMIO resources + - ALSA: hda - Use IS_REACHABLE() for dependency on input + - ASoC: au1x: Fix timeout tests in au1xac97c_ac97_read() + - kvm: x86: fix KVM_XEN_HVM_CONFIG ioctl + - RDMA/core: Clarify rdma_ah_find_type + - KVM: PPC: Book3S HV: Enable migration of decrementer register + - netfilter: ipv6: nf_defrag: Pass on packets to stack per RFC2460 + - tracing/hrtimer: Fix tracing bugs by taking all clock bases and modes into + account + - KVM: s390: use created_vcpus in more places + - platform/x86: dell-laptop: Filter out spurious keyboard backlight change + events + - xprtrdma: Fix backchannel allocation of extra rpcrdma_reps + - selftest: ftrace: Fix to pick text symbols for kprobes + - PCI: Add function 1 DMA alias quirk for Marvell 9128 + - Input: psmouse - fix Synaptics detection when protocol is disabled + - libbpf: Makefile set specified permission mode + - Input: synaptics - reset the ABS_X/Y fuzz after initializing MT axes + - i40iw: Free IEQ resources + - i40iw: Zero-out consumer key on allocate stag for FMR + - perf unwind: Do not look just at the global callchain_param.record_mode + - tools lib traceevent: Simplify pointer print logic and fix %pF + - perf callchain: Fix attr.sample_max_stack setting + - tools lib traceevent: Fix get_field_str() for dynamic strings + - perf record: Fix failed memory allocation for get_cpuid_str + - iommu/exynos: Don't unconditionally steal bus ops + - powerpc: System reset avoid interleaving oops using die synchronisation + - iommu/vt-d: Use domain instead of cache fetching + - dm thin: fix documentation relative to low water mark threshold + - dm mpath: return DM_MAPIO_REQUEUE on blk-mq rq allocation failure + - ubifs: Fix uninitialized variable in search_dh_cookie() + - net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b + - net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock + - spi: a3700: Clear DATA_OUT when performing a read + - IB/cq: Don't force IB_POLL_DIRECT poll context for ib_process_cq_direct + - nfs: Do not convert nfs_idmap_cache_timeout to jiffies + - MIPS: Fix clean of vmlinuz.{32,ecoff,bin,srec} + - PCI: Add dummy pci_irqd_intx_xlate() for CONFIG_PCI=n build + - watchdog: sp5100_tco: Fix watchdog disable bit + - kconfig: Don't leak main menus during parsing + - kconfig: Fix automatic menu creation mem leak + - kconfig: Fix expr_free() E_NOT leak + - ipmi/powernv: Fix error return code in ipmi_powernv_probe() + - Btrfs: set plug for fsync + - btrfs: Fix out of bounds access in btrfs_search_slot + - Btrfs: fix scrub to repair raid6 corruption + - btrfs: fail mount when sb flag is not in BTRFS_SUPER_FLAG_SUPP + - Btrfs: fix unexpected EEXIST from btrfs_get_extent + - Btrfs: raid56: fix race between merge_bio and rbio_orig_end_io + - RDMA/cma: Check existence of netdevice during port validation + - f2fs: avoid hungtask when GC encrypted block if io_bits is set + - scsi: devinfo: fix format of the device list + - scsi: fas216: fix sense buffer initialization + - Input: stmfts - set IRQ_NOAUTOEN to the irq flag + - HID: roccat: prevent an out of bounds read in kovaplus_profile_activated() + - nfp: fix error return code in nfp_pci_probe() + - block: Set BIO_TRACE_COMPLETION on new bio during split + - bpf: test_maps: cleanup sockmaps when test ends + - i40evf: Don't schedule reset_task when device is being removed + - i40evf: ignore link up if not running + - platform/x86: thinkpad_acpi: suppress warning about palm detection + - KVM: s390: vsie: use READ_ONCE to access some SCB fields + - blk-mq-debugfs: don't allow write on attributes with seq_operations set + - ASoC: rockchip: Use dummy_dai for rt5514 dsp dailink + - igb: Allow to remove administratively set MAC on VFs + - igb: Clear TXSTMP when ptp_tx_work() is timeout + - fm10k: fix "failed to kill vid" message for VF + - x86/hyperv: Stop suppressing X86_FEATURE_PCID + - tty: serial: exar: Relocate sleep wake-up handling + - device property: Define type of PROPERTY_ENRTY_*() macros + - crypto: artpec6 - remove select on non-existing CRYPTO_SHA384 + - RDMA/uverbs: Use an unambiguous errno for method not supported + - jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path + - ixgbe: don't set RXDCTL.RLPML for 82599 + - i40e: program fragmented IPv4 filter input set + - i40e: fix reported mask for ntuple filters + - samples/bpf: Partially fixes the bpf.o build + - powerpc/numa: Use ibm,max-associativity-domains to discover possible nodes + - powerpc/numa: Ensure nodes initialized for hotplug + - RDMA/mlx5: Avoid memory leak in case of XRCD dealloc failure + - ntb_transport: Fix bug with max_mw_size parameter + - gianfar: prevent integer wrapping in the rx handler + - x86/hyperv: Check for required priviliges in hyperv_init() + - netfilter: x_tables: fix pointer leaks to userspace + - tcp_nv: fix potential integer overflow in tcpnv_acked + - kvm: Map PFN-type memory regions as writable (if possible) + - x86/kvm/vmx: do not use vm-exit instruction length for fast MMIO when + running nested + - fs/dax.c: release PMD lock even when there is no PMD support in DAX + - ocfs2: return -EROFS to mount.ocfs2 if inode block is invalid + - ocfs2/acl: use 'ip_xattr_sem' to protect getting extended attribute + - ocfs2: return error when we attempt to access a dirty bh in jbd2 + - mm/mempolicy: fix the check of nodemask from user + - mm/mempolicy: add nodes_empty check in SYSC_migrate_pages + - asm-generic: provide generic_pmdp_establish() + - sparc64: update pmdp_invalidate() to return old pmd value + - mm: thp: use down_read_trylock() in khugepaged to avoid long block + - mm: pin address_space before dereferencing it while isolating an LRU page + - mm/fadvise: discard partial page if endbyte is also EOF + - openvswitch: Remove padding from packet before L3+ conntrack processing + - blk-mq: fix discard merge with scheduler attached + - IB/hfi1: Re-order IRQ cleanup to address driver cleanup race + - IB/hfi1: Fix for potential refcount leak in hfi1_open_file() + - IB/ipoib: Fix for potential no-carrier state + - IB/core: Map iWarp AH type to undefined in rdma_ah_find_type + - drm/nouveau/pmu/fuc: don't use movw directly anymore + - s390/eadm: fix CONFIG_BLOCK include dependency + - netfilter: ipv6: nf_defrag: Kill frag queue on RFC2460 failure + - x86/power: Fix swsusp_arch_resume prototype + - x86/dumpstack: Avoid uninitlized variable + - firmware: dmi_scan: Fix handling of empty DMI strings + - ACPI: processor_perflib: Do not send _PPC change notification if not ready + - ACPI / bus: Do not call _STA on battery devices with unmet dependencies + - ACPI / scan: Use acpi_bus_get_status() to initialize ACPI_TYPE_DEVICE devs + - MIPS: TXx9: use IS_BUILTIN() for CONFIG_LEDS_CLASS + - perf record: Fix period option handling + - MIPS: Generic: Support GIC in EIC mode + - perf evsel: Fix period/freq terms setup + - xen-netfront: Fix race between device setup and open + - xen/grant-table: Use put_page instead of free_page + - bpf: sockmap, fix leaking maps with attached but not detached progs + - RDS: IB: Fix null pointer issue + - arm64: spinlock: Fix theoretical trylock() A-B-A with LSE atomics + - proc: fix /proc/*/map_files lookup + - PM / domains: Fix up domain-idle-states OF parsing + - cifs: silence compiler warnings showing up with gcc-8.0.0 + - bcache: properly set task state in bch_writeback_thread() + - bcache: fix for allocator and register thread race + - bcache: fix for data collapse after re-attaching an attached device + - bcache: return attach error when no cache set exist + - cpufreq: intel_pstate: Enable HWP during system resume on CPU0 + - selftests/ftrace: Add some missing glob checks + - rxrpc: Don't put crypto buffers on the stack + - svcrdma: Fix Read chunk round-up + - net: Extra '_get' in declaration of arch_get_platform_mac_address + - tools/libbpf: handle issues with bpf ELF objects containing .eh_frames + - SUNRPC: Don't call __UDPX_INC_STATS() from a preemptible context + - net: stmmac: discard disabled flags in interrupt status register + - bpf: fix rlimit in reuseport net selftest + - ACPI / EC: Restore polling during noirq suspend/resume phases + - PM / wakeirq: Fix unbalanced IRQ enable for wakeirq + - vfs/proc/kcore, x86/mm/kcore: Fix SMAP fault when dumping vsyscall user page + - powerpc/mm/hash64: Zero PGD pages on allocation + - x86/platform/UV: Fix GAM Range Table entries less than 1GB + - locking/qspinlock: Ensure node->count is updated before initialising node + - powerpc/powernv: IMC fix out of bounds memory access at shutdown + - perf test: Fix test trace+probe_libc_inet_pton.sh for s390x + - irqchip/gic-v3: Ignore disabled ITS nodes + - cpumask: Make for_each_cpu_wrap() available on UP as well + - irqchip/gic-v3: Change pr_debug message to pr_devel + - RDMA/core: Reduce poll batch for direct cq polling + - alarmtimer: Init nanosleep alarm timer on stack + - netfilter: x_tables: cap allocations at 512 mbyte + - netfilter: x_tables: add counters allocation wrapper + - netfilter: compat: prepare xt_compat_init_offsets to return errors + - netfilter: compat: reject huge allocation requests + - netfilter: x_tables: limit allocation requests for blob rule heads + - perf: Fix sample_max_stack maximum check + - perf: Return proper values for user stack errors + - RDMA/mlx5: Fix NULL dereference while accessing XRC_TGT QPs + - Revert "KVM: X86: Fix SMRAM accessing even if VM is shutdown" + - mac80211_hwsim: fix use-after-free bug in hwsim_exit_net + - btrfs: Fix race condition between delayed refs and blockgroup removal + - mm,vmscan: Allow preallocating memory for register_shrinker(). + + * Bionic update: upstream stable patchset 2018-05-24 (LP: #1773233) + - tty: make n_tty_read() always abort if hangup is in progress + - cpufreq: CPPC: Use transition_delay_us depending transition_latency + - ubifs: Check ubifs_wbuf_sync() return code + - ubi: fastmap: Don't flush fastmap work on detach + - ubi: Fix error for write access + - ubi: Reject MLC NAND + - mm/ksm.c: fix inconsistent accounting of zero pages + - mm/hmm: hmm_pfns_bad() was accessing wrong struct + - task_struct: only use anon struct under randstruct plugin + - fs/reiserfs/journal.c: add missing resierfs_warning() arg + - resource: fix integer overflow at reallocation + - ipc/shm: fix use-after-free of shm file via remap_file_pages() + - mm, slab: reschedule cache_reap() on the same CPU + - usb: musb: gadget: misplaced out of bounds check + - phy: allwinner: sun4i-usb: poll vbus changes on A23/A33 when driving VBUS + - usb: gadget: udc: core: update usb_ep_queue() documentation + - ARM64: dts: meson: reduce odroid-c2 eMMC maximum rate + - KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list + - ARM: EXYNOS: Fix coupled CPU idle freeze on Exynos4210 + - arm: dts: mt7623: fix USB initialization fails on bananapi-r2 + - ARM: dts: at91: at91sam9g25: fix mux-mask pinctrl property + - ARM: dts: exynos: Fix IOMMU support for GScaler devices on Exynos5250 + - ARM: dts: at91: sama5d4: fix pinctrl compatible string + - spi: atmel: init FIFOs before spi enable + - spi: Fix scatterlist elements size in spi_map_buf + - spi: Fix unregistration of controller with fixed SPI bus number + - media: atomisp_fops.c: disable atomisp_compat_ioctl32 + - media: vivid: check if the cec_adapter is valid + - media: vsp1: Fix BRx conditional path in WPF + - x86/xen: Delay get_cpu_cap until stack canary is established + - regmap: Fix reversed bounds check in regmap_raw_write() + - ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E + - ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status() + - USB: gadget: f_midi: fixing a possible double-free in f_midi + - USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw + - usb: dwc3: prevent setting PRTCAP to OTG from debugfs + - usb: dwc3: pci: Properly cleanup resource + - usb: dwc3: gadget: never call ->complete() from ->ep_queue() + - cifs: fix memory leak in SMB2_open() + - fix smb3-encryption breakage when CONFIG_DEBUG_SG=y + - smb3: Fix root directory when server returns inode number of zero + - HID: i2c-hid: fix size check and type usage + - i2c: i801: Save register SMBSLVCMD value only once + - i2c: i801: Restore configuration at shutdown + - CIFS: refactor crypto shash/sdesc allocation&free + - CIFS: add sha512 secmech + - CIFS: fix sha512 check in cifs_crypto_secmech_release + - powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits + - powerpc/64: Call H_REGISTER_PROC_TBL when running as a HPT guest on POWER9 + - powerpc/64: Fix smp_wmb barrier definition use use lwsync consistently + - powerpc/kprobes: Fix call trace due to incorrect preempt count + - powerpc/kexec_file: Fix error code when trying to load kdump kernel + - powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops + - powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops + - HID: Fix hid_report_len usage + - HID: core: Fix size as type u32 + - soc: mediatek: fix the mistaken pointer accessed when subdomains are added + - ASoC: ssm2602: Replace reg_default_raw with reg_default + - ASoC: topology: Fix kcontrol name string handling + - irqchip/gic: Take lock when updating irq type + - random: use a tighter cap in credit_entropy_bits_safe() + - extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO + - block: use 32-bit blk_status_t on Alpha + - jbd2: if the journal is aborted then don't allow update of the log tail + - ext4: shutdown should not prevent get_write_access + - ext4: eliminate sleep from shutdown ioctl + - ext4: pass -ESHUTDOWN code to jbd2 layer + - ext4: don't update checksum of new initialized bitmaps + - ext4: protect i_disksize update by i_data_sem in direct write path + - ext4: limit xattr size to INT_MAX + - ext4: always initialize the crc32c checksum driver + - ext4: don't allow r/w mounts if metadata blocks overlap the superblock + - ext4: move call to ext4_error() into ext4_xattr_check_block() + - ext4: add bounds checking to ext4_xattr_find_entry() + - ext4: add extra checks to ext4_xattr_block_get() + - dm crypt: limit the number of allocated pages + - RDMA/ucma: Don't allow setting RDMA_OPTION_IB_PATH without an RDMA device + - RDMA/mlx5: Protect from NULL pointer derefence + - RDMA/rxe: Fix an out-of-bounds read + - ALSA: pcm: Fix UAF at PCM release via PCM timer access + - IB/srp: Fix srp_abort() + - IB/srp: Fix completion vector assignment algorithm + - dmaengine: at_xdmac: fix rare residue corruption + - cxl: Fix possible deadlock when processing page faults from cxllib + - tpm: self test failure should not cause suspend to fail + - libnvdimm, dimm: fix dpa reservation vs uninitialized label area + - libnvdimm, namespace: use a safe lookup for dimm device name + - nfit, address-range-scrub: fix scrub in-progress reporting + - nfit: skip region registration for incomplete control regions + - ring-buffer: Check if memory is available before allocation + - um: Compile with modern headers + - um: Use POSIX ucontext_t instead of struct ucontext + - iommu/vt-d: Fix a potential memory leak + - mmc: jz4740: Fix race condition in IRQ mask update + - mmc: tmio: Fix error handling when issuing CMD23 + - PCI: Mark Broadcom HT1100 and HT2000 Root Port Extended Tags as broken + - clk: mvebu: armada-38x: add support for missing clocks + - clk: fix false-positive Wmaybe-uninitialized warning + - clk: mediatek: fix PWM clock source by adding a fixed-factor clock + - clk: bcm2835: De-assert/assert PLL reset signal when appropriate + - pwm: rcar: Fix a condition to prevent mismatch value setting to duty + - thermal: imx: Fix race condition in imx_thermal_probe() + - dt-bindings: clock: mediatek: add binding for fixed-factor clock axisel_d4 + - watchdog: f71808e_wdt: Fix WD_EN register read + - ALSA: pcm: Use ERESTARTSYS instead of EINTR in OSS emulation + - ALSA: pcm: Avoid potential races between OSS ioctls and read/write + - ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams + - ALSA: pcm: Fix mutex unbalance in OSS emulation ioctls + - ALSA: pcm: Fix endless loop for XRUN recovery in OSS emulation + - drm/amdgpu: Add an ATPX quirk for hybrid laptop + - drm/amdgpu: Fix always_valid bos multiple LRU insertions. + - drm/amdgpu/sdma: fix mask in emit_pipeline_sync + - drm/amdgpu: Fix PCIe lane width calculation + - drm/amdgpu/si: implement get/set pcie_lanes asic callback + - drm/rockchip: Clear all interrupts before requesting the IRQ + - drm/radeon: add PX quirk for Asus K73TK + - drm/radeon: Fix PCIe lane width calculation + - ALSA: line6: Use correct endpoint type for midi output + - ALSA: rawmidi: Fix missing input substream checks in compat ioctls + - ALSA: hda - New VIA controller suppor no-snoop path + - random: fix crng_ready() test + - random: use a different mixing algorithm for add_device_randomness() + - random: crng_reseed() should lock the crng instance that it is modifying + - random: add new ioctl RNDRESEEDCRNG + - HID: input: fix battery level reporting on BT mice + - HID: hidraw: Fix crash on HIDIOCGFEATURE with a destroyed device + - HID: wacom: bluetooth: send exit report for recent Bluetooth devices + - MIPS: uaccess: Add micromips clobbers to bzero invocation + - MIPS: memset.S: EVA & fault support for small_memset + - MIPS: memset.S: Fix return of __clear_user from Lpartial_fixup + - MIPS: memset.S: Fix clobber of v1 in last_fixup + - powerpc/eeh: Fix enabling bridge MMIO windows + - powerpc/lib: Fix off-by-one in alternate feature patching + - udf: Fix leak of UTF-16 surrogates into encoded strings + - fanotify: fix logic of events on child + - mmc: sdhci-pci: Only do AMD tuning for HS200 + - drm/i915: Correctly handle limited range YCbCr data on VLV/CHV + - jffs2_kill_sb(): deal with failed allocations + - hypfs_kill_super(): deal with failed allocations + - orangefs_kill_sb(): deal with allocation failures + - rpc_pipefs: fix double-dput() + - Don't leak MNT_INTERNAL away from internal mounts + - autofs: mount point create should honour passed in mode + - mm/filemap.c: fix NULL pointer in page_cache_tree_insert() + - Revert "media: lirc_zilog: driver only sends LIRCCODE" + - media: staging: lirc_zilog: incorrect reference counting + - writeback: safer lock nesting + - Bluetooth: hci_bcm: Add irq_polarity module option + - mm: hwpoison: disable memory error handling on 1GB hugepage + - media: rc: oops in ir_timer_keyup after device unplug + - acpi, nfit: rework NVDIMM leaf method detection + - ceph: always update atime/mtime/ctime for new inode + - ext4: fix offset overflow on 32-bit archs in ext4_iomap_begin() + - ext4: force revalidation of directory pointer after seekdir(2) + - RDMA/core: Avoid that ib_drain_qp() triggers an out-of-bounds stack access + - xprtrdma: Fix latency regression on NUMA NFS/RDMA clients + - xprtrdma: Fix corner cases when handling device removal + - IB/srpt: Fix an out-of-bounds stack access in srpt_zerolength_write() + - drivers/infiniband/core/verbs.c: fix build with gcc-4.4.4 + - drivers/infiniband/ulp/srpt/ib_srpt.c: fix build with gcc-4.4.4 + - mmc: core: Prevent bus reference leak in mmc_blk_init() + - drm/amd/display: HDMI has no sound after Panel power off/on + - trace_uprobe: Use %lx to display offset + - clk: tegra: Mark HCLK, SCLK and EMC as critical + - pwm: mediatek: Fix up PWM4 and PWM5 malfunction on MT7623 + - pwm: mediatek: Improve precision in rate calculation + - HID: i2c-hid: Fix resume issue on Raydium touchscreen device + - s390: add support for IBM z14 Model ZR1 + - drm/i915: Fix hibernation with ACPI S0 target state + - libnvdimm, dimm: handle EACCES failures from label reads + - device-dax: allow MAP_SYNC to succeed + - HID: i2c-hid: fix inverted return value from i2c_hid_command() + + * CVE-2018-7755 + - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl + + -- Kleber Sacilotto de Souza Tue, 12 Jun 2018 18:09:35 +0200 + +linux (4.15.0-23.25) bionic; urgency=medium + + * linux: 4.15.0-23.25 -proposed tracker (LP: #1772927) + + * arm64 SDEI support needs trampoline code for KPTI (LP: #1768630) + - arm64: mmu: add the entry trampolines start/end section markers into + sections.h + - arm64: sdei: Add trampoline code for remapping the kernel + + * Some PCIe errors not surfaced through rasdaemon (LP: #1769730) + - ACPI: APEI: handle PCIe AER errors in separate function + - ACPI: APEI: call into AER handling regardless of severity + + * qla2xxx: Fix page fault at kmem_cache_alloc_node() (LP: #1770003) + - scsi: qla2xxx: Fix session cleanup for N2N + - scsi: qla2xxx: Remove unused argument from qlt_schedule_sess_for_deletion() + - scsi: qla2xxx: Serialize session deletion by using work_lock + - scsi: qla2xxx: Serialize session free in qlt_free_session_done + - scsi: qla2xxx: Don't call dma_free_coherent with IRQ disabled. + - scsi: qla2xxx: Fix warning in qla2x00_async_iocb_timeout() + - scsi: qla2xxx: Prevent relogin trigger from sending too many commands + - scsi: qla2xxx: Fix double free bug after firmware timeout + - scsi: qla2xxx: Fixup locking for session deletion + + * Several hisi_sas bug fixes (LP: #1768974) + - scsi: hisi_sas: dt-bindings: add an property of signal attenuation + - scsi: hisi_sas: support the property of signal attenuation for v2 hw + - scsi: hisi_sas: fix the issue of link rate inconsistency + - scsi: hisi_sas: fix the issue of setting linkrate register + - scsi: hisi_sas: increase timer expire of internal abort task + - scsi: hisi_sas: remove unused variable hisi_sas_devices.running_req + - scsi: hisi_sas: fix return value of hisi_sas_task_prep() + - scsi: hisi_sas: Code cleanup and minor bug fixes + + * [bionic] machine stuck and bonding not working well when nvmet_rdma module + is loaded (LP: #1764982) + - nvmet-rdma: Don't flush system_wq by default during remove_one + - nvme-rdma: Don't flush delete_wq by default during remove_one + + * Warnings/hang during error handling of SATA disks on SAS controller + (LP: #1768971) + - scsi: libsas: defer ata device eh commands to libata + + * Hotplugging a SATA disk into a SAS controller may cause crash (LP: #1768948) + - ata: do not schedule hot plug if it is a sas host + + * ISST-LTE:pKVM:Ubuntu1804: rcu_sched self-detected stall on CPU follow by CPU + ATTEMPT TO RE-ENTER FIRMWARE! (LP: #1767927) + - powerpc/powernv: Handle unknown OPAL errors in opal_nvram_write() + - powerpc/64s: return more carefully from sreset NMI + - powerpc/64s: sreset panic if there is no debugger or crash dump handlers + + * fsnotify: Fix fsnotify_mark_connector race (LP: #1765564) + - fsnotify: Fix fsnotify_mark_connector race + + * Hang on network interface removal in Xen virtual machine (LP: #1771620) + - xen-netfront: Fix hang on device removal + + * HiSilicon HNS NIC names are truncated in /proc/interrupts (LP: #1765977) + - net: hns: Avoid action name truncation + + * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849) + - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on + num_possible_cpus() + + * Switch Build-Depends: transfig to fig2dev (LP: #1770770) + - [Config] update Build-Depends: transfig to fig2dev + + * smp_call_function_single/many core hangs with stop4 alone (LP: #1768898) + - cpufreq: powernv: Fix hardlockup due to synchronous smp_call in timer + interrupt + + * Add d-i support for Huawei NICs (LP: #1767490) + - d-i: add hinic to nic-modules udeb + + * unregister_netdevice: waiting for eth0 to become free. Usage count = 5 + (LP: #1746474) + - xfrm: reuse uncached_list to track xdsts + + * Include nfp driver in linux-modules (LP: #1768526) + - [Config] Add nfp.ko to generic inclusion list + + * Kernel panic on boot (m1.small in cn-north-1) (LP: #1771679) + - x86/xen: Reset VCPU0 info pointer after shared_info remap + + * CVE-2018-3639 (x86) + - x86/bugs: Fix the parameters alignment and missing void + - KVM: SVM: Move spec control call after restore of GS + - x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP + - x86/cpufeatures: Disentangle MSR_SPEC_CTRL enumeration from IBRS + - x86/cpufeatures: Disentangle SSBD enumeration + - x86/cpufeatures: Add FEATURE_ZEN + - x86/speculation: Handle HT correctly on AMD + - x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL + - x86/speculation: Add virtualized speculative store bypass disable support + - x86/speculation: Rework speculative_store_bypass_update() + - x86/bugs: Unify x86_spec_ctrl_{set_guest,restore_host} + - x86/bugs: Expose x86_spec_ctrl_base directly + - x86/bugs: Remove x86_spec_ctrl_set() + - x86/bugs: Rework spec_ctrl base and mask logic + - x86/speculation, KVM: Implement support for VIRT_SPEC_CTRL/LS_CFG + - KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD + - x86/bugs: Rename SSBD_NO to SSB_NO + - bpf: Prevent memory disambiguation attack + - KVM: VMX: Expose SSBD properly to guests. + + * Suspend to idle: Open lid didn't resume (LP: #1771542) + - ACPI / PM: Do not reconfigure GPEs for suspend-to-idle + + * Fix initialization failure detection in SDEI for device-tree based systems + (LP: #1768663) + - firmware: arm_sdei: Fix return value check in sdei_present_dt() + + * No driver for Huawei network adapters on arm64 (LP: #1769899) + - net-next/hinic: add arm64 support + + * CVE-2018-1092 + - ext4: fail ext4_iget for root directory if unallocated + + * kernel 4.15 breaks nouveau on Lenovo P50 (LP: #1763189) + - drm/nouveau: Fix deadlock in nv50_mstm_register_connector() + + * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails + to load (LP: #1728238) + - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for + unreleased firmware" + + * Battery drains when laptop is off (shutdown) (LP: #1745646) + - PCI / PM: Check device_may_wakeup() in pci_enable_wake() + + * Dell Latitude 5490/5590 BIOS update 1.1.9 causes black screen at boot + (LP: #1764194) + - drm/i915/bios: filter out invalid DDC pins from VBT child devices + + * Intel 9462 A370:42A4 doesn't work (LP: #1748853) + - iwlwifi: add shared clock PHY config flag for some devices + - iwlwifi: add a bunch of new 9000 PCI IDs + + * Fix an issue that some PCI devices get incorrectly suspended (LP: #1764684) + - PCI / PM: Always check PME wakeup capability for runtime wakeup support + + * [SRU][Bionic/Artful] fix false positives in W+X checking (LP: #1769696) + - init: fix false positives in W+X checking + + * Bionic update to v4.15.18 stable release (LP: #1769723) + - netfilter: ipset: Missing nfnl_lock()/nfnl_unlock() is added to + ip_set_net_exit() + - cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN + - rds: MP-RDS may use an invalid c_path + - slip: Check if rstate is initialized before uncompressing + - vhost: fix vhost_vq_access_ok() log check + - l2tp: fix races in tunnel creation + - l2tp: fix race in duplicate tunnel detection + - ip_gre: clear feature flags when incompatible o_flags are set + - vhost: Fix vhost_copy_to_user() + - lan78xx: Correctly indicate invalid OTP + - media: v4l2-compat-ioctl32: don't oops on overlay + - media: v4l: vsp1: Fix header display list status check in continuous mode + - ipmi: Fix some error cleanup issues + - parisc: Fix out of array access in match_pci_device() + - parisc: Fix HPMC handler by increasing size to multiple of 16 bytes + - Drivers: hv: vmbus: do not mark HV_PCIE as perf_device + - PCI: hv: Serialize the present and eject work items + - PCI: hv: Fix 2 hang issues in hv_compose_msi_msg() + - KVM: PPC: Book3S HV: trace_tlbie must not be called in realmode + - perf/core: Fix use-after-free in uprobe_perf_close() + - x86/mce/AMD: Get address from already initialized block + - hwmon: (ina2xx) Fix access to uninitialized mutex + - ath9k: Protect queue draining by rcu_read_lock() + - x86/apic: Fix signedness bug in APIC ID validity checks + - f2fs: fix heap mode to reset it back + - block: Change a rcu_read_{lock,unlock}_sched() pair into + rcu_read_{lock,unlock}() + - nvme: Skip checking heads without namespaces + - lib: fix stall in __bitmap_parselist() + - blk-mq: order getting budget and driver tag + - blk-mq: don't keep offline CPUs mapped to hctx 0 + - ovl: fix lookup with middle layer opaque dir and absolute path redirects + - xen: xenbus_dev_frontend: Fix XS_TRANSACTION_END handling + - hugetlbfs: fix bug in pgoff overflow checking + - nfsd: fix incorrect umasks + - scsi: qla2xxx: Fix small memory leak in qla2x00_probe_one on probe failure + - block/loop: fix deadlock after loop_set_status + - nfit: fix region registration vs block-data-window ranges + - s390/qdio: don't retry EQBS after CCQ 96 + - s390/qdio: don't merge ERROR output buffers + - s390/ipl: ensure loadparm valid flag is set + - get_user_pages_fast(): return -EFAULT on access_ok failure + - mm/gup_benchmark: handle gup failures + - getname_kernel() needs to make sure that ->name != ->iname in long case + - Bluetooth: Fix connection if directed advertising and privacy is used + - Bluetooth: hci_bcm: Treat Interrupt ACPI resources as always being active- + low + - rtl8187: Fix NULL pointer dereference in priv->conf_mutex + - ovl: set lower layer st_dev only if setting lower st_ino + - Linux 4.15.18 + + * Kernel bug when unplugging Thunderbolt 3 cable, leaves xHCI host controller + dead (LP: #1768852) + - xhci: Fix Kernel oops in xhci dbgtty + + * Incorrect blacklist of bcm2835_wdt (LP: #1766052) + - [Packaging] Fix missing watchdog for Raspberry Pi + + * CVE-2018-8087 + - mac80211_hwsim: fix possible memory leak in hwsim_new_radio_nl() + + * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in + DELL XPS 13 9370 with firmware 1.50 (LP: #1763748) + - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device + + * [ALSA] [PATCH] Clevo P950ER ALC1220 Fixup (LP: #1769721) + - SAUCE: ALSA: hda/realtek - Clevo P950ER ALC1220 Fixup + + * Bionic: Intermittently sent to Emergency Mode on boot with unhandled kernel + NULL pointer dereference at 0000000000000980 (LP: #1768292) + - thunderbolt: Prevent crash when ICM firmware is not running + + * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761) + - [Config] snapdragon: DRM_I2C_ADV7511=y + + * regression Aquantia Corp. AQC107 4.15.0-13-generic -> 4.15.0-20-generic ? + (LP: #1767088) + - net: aquantia: Regression on reset with 1.x firmware + - net: aquantia: oops when shutdown on already stopped device + + * e1000e msix interrupts broken in linux-image-4.15.0-15-generic + (LP: #1764892) + - e1000e: Remove Other from EIAC + + * Acer Swift sf314-52 power button not managed (LP: #1766054) + - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode + + * set PINCFG_HEADSET_MIC to parse_flags for Dell precision 3630 (LP: #1766398) + - ALSA: hda/realtek - set PINCFG_HEADSET_MIC to parse_flags + + * Change the location for one of two front mics on a lenovo thinkcentre + machine (LP: #1766477) + - ALSA: hda/realtek - adjust the location of one mic + + * SRU: bionic: apply 50 ZFS upstream bugfixes (LP: #1764690) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu15 (LP: #1764690) + + * [8086:3e92] display becomes blank after S3 (LP: #1763271) + - drm/i915/edp: Do not do link training fallback or prune modes on EDP + + -- Stefan Bader Wed, 23 May 2018 18:54:55 +0200 + +linux (4.15.0-22.24) bionic; urgency=medium + + * CVE-2018-3639 (powerpc) + - powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit + - stf-barrier: set eieio instruction bit 6 for future optimisations + + * CVE-2018-3639 (x86) + - x86/nospec: Simplify alternative_msr_write() + - x86/bugs: Concentrate bug detection into a separate function + - x86/bugs: Concentrate bug reporting into a separate function + - x86/bugs: Read SPEC_CTRL MSR during boot and re-use reserved bits + - x86/bugs, KVM: Support the combination of guest and host IBRS + - x86/bugs: Expose /sys/../spec_store_bypass + - x86/cpufeatures: Add X86_FEATURE_RDS + - x86/bugs: Provide boot parameters for the spec_store_bypass_disable + mitigation + - x86/bugs/intel: Set proper CPU features and setup RDS + - x86/bugs: Whitelist allowed SPEC_CTRL MSR values + - x86/bugs/AMD: Add support to disable RDS on Fam[15,16,17]h if requested + - x86/KVM/VMX: Expose SPEC_CTRL Bit(2) to the guest + - x86/speculation: Create spec-ctrl.h to avoid include hell + - prctl: Add speculation control prctls + - x86/process: Allow runtime control of Speculative Store Bypass + - x86/speculation: Add prctl for Speculative Store Bypass mitigation + - nospec: Allow getting/setting on non-current task + - proc: Provide details on speculation flaw mitigations + - seccomp: Enable speculation flaw mitigations + - x86/bugs: Make boot modes __ro_after_init + - prctl: Add force disable speculation + - seccomp: Use PR_SPEC_FORCE_DISABLE + - seccomp: Add filter flag to opt-out of SSB mitigation + - seccomp: Move speculation migitation control to arch code + - x86/speculation: Make "seccomp" the default mode for Speculative Store + Bypass + - x86/bugs: Rename _RDS to _SSBD + - proc: Use underscores for SSBD in 'status' + - Documentation/spec_ctrl: Do some minor cleanups + - x86/bugs: Fix __ssb_select_mitigation() return type + - x86/bugs: Make cpu_show_common() static + + * LSM Stacking prctl values should be redefined as to not collide with + upstream prctls (LP: #1769263) // CVE-2018-3639 + - SAUCE: LSM stacking: adjust prctl values + + -- Stefan Bader Tue, 15 May 2018 07:41:28 +0200 + +linux (4.15.0-21.22) bionic; urgency=medium + + * linux: 4.15.0-21.22 -proposed tracker (LP: #1767397) + + * initramfs-tools exception during pm.DoInstall with do-release-upgrade from + 16.04 to 18.04 (LP: #1766727) + - Add linux-image-* Breaks on s390-tools (<< 2.3.0-0ubuntu3) + + * linux-image-4.15.0-20-generic install after upgrade from xenial breaks + (LP: #1767133) + - Packaging: Depends on linux-base that provides the necessary tools + + * linux-image packages need to Breaks flash-kernel << 3.90ubuntu2 + (LP: #1766629) + - linux-image-* breaks on flash-kernel (<< 3.90ubuntu2) + + -- Thadeu Lima de Souza Cascardo Mon, 30 Apr 2018 14:58:35 -0300 + +linux (4.15.0-20.21) bionic; urgency=medium + + * linux: 4.15.0-20.21 -proposed tracker (LP: #1766452) + + * package shim-signed (not installed) failed to install/upgrade: installed + shim-signed package post-installation script subprocess returned error exit + status 5 (LP: #1766391) + - [Packaging] fix invocation of header postinst hooks + + -- Seth Forshee Mon, 23 Apr 2018 23:56:17 -0500 + +linux (4.15.0-19.20) bionic; urgency=medium + + * linux: 4.15.0-19.20 -proposed tracker (LP: #1766021) + + * Kernel 4.15.0-15 breaks Dell PowerEdge 12th Gen servers (LP: #1765232) + - Revert "blk-mq: simplify queue mapping & schedule with each possisble CPU" + - Revert "genirq/affinity: assign vectors to all possible CPUs" + + -- Seth Forshee Sat, 21 Apr 2018 17:19:00 -0500 + +linux (4.15.0-18.19) bionic; urgency=medium + + * linux: 4.15.0-18.19 -proposed tracker (LP: #1765490) + + * [regression] Ubuntu 18.04:[4.15.0-17-generic #18] KVM Guest Kernel: + meltdown: rfi/fallback displacement flush not enabled bydefault (kvm) + (LP: #1765429) + - powerpc/pseries: Fix clearing of security feature flags + + * signing: only install a signed kernel (LP: #1764794) + - [Packaging] update to Debian like control scripts + - [Packaging] switch to triggers for postinst.d postrm.d handling + - [Packaging] signing -- switch to raw-signing tarballs + - [Packaging] signing -- switch to linux-image as signed when available + - [Config] signing -- enable Opal signing for ppc64el + - [Packaging] printenv -- add signing options + + * [18.04 FEAT] Sign POWER host/NV kernels (LP: #1696154) + - [Packaging] signing -- add support for signing Opal kernel binaries + + * Please cherrypick s390 unwind fix (LP: #1765083) + - s390/compat: fix setup_frame32 + + * Ubuntu 18.04 installer does not detect any IPR based HDD/RAID array [S822L] + [ipr] (LP: #1751813) + - d-i: move ipr to storage-core-modules on ppc64el + + * drivers/gpu/drm/bridge/adv7511/adv7511.ko missing (LP: #1764816) + - SAUCE: (no-up) rename the adv7511 drm driver to adv7511_drm + + * Miscellaneous Ubuntu changes + - [Packaging] Add linux-oem to rebuild test blacklist. + + -- Thadeu Lima de Souza Cascardo Thu, 19 Apr 2018 18:06:46 -0300 + +linux (4.15.0-17.18) bionic; urgency=medium + + * linux: 4.15.0-17.18 -proposed tracker (LP: #1764498) + + * Eventual OOM with profile reloads (LP: #1750594) + - SAUCE: apparmor: fix memory leak when duplicate profile load + + -- Seth Forshee Mon, 16 Apr 2018 14:48:18 -0500 + +linux (4.15.0-16.17) bionic; urgency=medium + + * linux: 4.15.0-16.17 -proposed tracker (LP: #1763785) + + * [18.04] [bug] CFL-S(CNP)/CNL GPIO testing failed (LP: #1757346) + - [Config]: Set CONFIG_PINCTRL_CANNONLAKE=y + + * [Ubuntu 18.04] USB Type-C test failed on GLK (LP: #1758797) + - SAUCE: usb: typec: ucsi: Increase command completion timeout value + + * Fix trying to "push" an already active pool VP (LP: #1763386) + - SAUCE: powerpc/xive: Fix trying to "push" an already active pool VP + + * hisi_sas: Revert and replace SAUCE patches w/ upstream (LP: #1762824) + - Revert "UBUNTU: SAUCE: scsi: hisi_sas: export device table of v3 hw to + userspace" + - Revert "UBUNTU: SAUCE: scsi: hisi_sas: config for hip08 ES" + - scsi: hisi_sas: modify some register config for hip08 + - scsi: hisi_sas: add v3 hw MODULE_DEVICE_TABLE() + + * Realtek card reader - RTS5243 [VEN_10EC&DEV_5260] (LP: #1737673) + - misc: rtsx: Move Realtek Card Reader Driver to misc + - updateconfigs for Realtek Card Reader Driver + - misc: rtsx: Add support for RTS5260 + - misc: rtsx: Fix symbol clashes + + * Mellanox [mlx5] [bionic] UBSAN: Undefined behaviour in + ./include/linux/net_dim.h (LP: #1763269) + - net/mlx5e: Fix int overflow + + * apparmor bug fixes for bionic (LP: #1763427) + - apparmor: fix logging of the existence test for signals + - apparmor: make signal label match work when matching stacked labels + - apparmor: audit unknown signal numbers + - apparmor: fix memory leak on buffer on error exit path + - apparmor: fix mediation of prlimit + + * dangling symlinks to loaded apparmor policy (LP: #1755563) // apparmor bug + fixes for bionic (LP: #1763427) + - apparmor: fix dangling symlinks to policy rawdata after replacement + + * [OPAL] Assert fail: + core/mem_region.c:447:lock_held_by_me(®ion->free_list_lock) + (LP: #1762913) + - powerpc/watchdog: remove arch_trigger_cpumask_backtrace + + * [LTC Test] Ubuntu 18.04: tm_trap_test failed on P8 compat mode guest + (LP: #1762928) + - powerpc/tm: Fix endianness flip on trap + + * Add support for RT5660 codec based sound cards on Baytrail (LP: #1657674) + - SAUCE: (no-up) ASoC: Intel: Support machine driver for RT5660 on Baytrail + - SAUCE: (no-up) ASoC: rt5660: Add ACPI support + - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Add MCLK, quirks + - [Config] CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH=m, CONFIG_SND_SOC_RT5660=m + + * /dev/ipmi enumeration flaky on Cavium Sabre nodes (LP: #1762812) + - i2c: xlp9xx: return ENXIO on slave address NACK + - i2c: xlp9xx: Handle transactions with I2C_M_RECV_LEN properly + - i2c: xlp9xx: Check for Bus state before every transfer + - i2c: xlp9xx: Handle NACK on DATA properly + + * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130) + - tools/kvm_stat: simplify the sortkey function + - tools/kvm_stat: use a namedtuple for storing the values + - tools/kvm_stat: use a more pythonic way to iterate over dictionaries + - tools/kvm_stat: avoid 'is' for equality checks + - tools/kvm_stat: fix crash when filtering out all non-child trace events + - tools/kvm_stat: print error on invalid regex + - tools/kvm_stat: fix debugfs handling + - tools/kvm_stat: mark private methods as such + - tools/kvm_stat: eliminate extra guest/pid selection dialog + - tools/kvm_stat: separate drilldown and fields filtering + - tools/kvm_stat: group child events indented after parent + - tools/kvm_stat: print 'Total' line for multiple events only + - tools/kvm_stat: Fix python3 syntax + - tools/kvm_stat: Don't use deprecated file() + - tools/kvm_stat: Remove unused function + - [Packaging] Add linux-tools-host package for VM host tools + - [Config] do_tools_host=true for amd64 + + * Bionic update to v4.15.17 stable release (LP: #1763366) + - i40iw: Fix sequence number for the first partial FPDU + - i40iw: Correct Q1/XF object count equation + - i40iw: Validate correct IRD/ORD connection parameters + - clk: meson: mpll: use 64-bit maths in params_from_rate + - ARM: dts: ls1021a: add "fsl,ls1021a-esdhc" compatible string to esdhc node + - Bluetooth: Add a new 04ca:3015 QCA_ROME device + - ipv6: Reinject IPv6 packets if IPsec policy matches after SNAT + - thermal: power_allocator: fix one race condition issue for thermal_instances + list + - perf probe: Find versioned symbols from map + - perf probe: Add warning message if there is unexpected event name + - perf evsel: Fix swap for samples with raw data + - perf evsel: Enable ignore_missing_thread for pid option + - l2tp: fix missing print session offset info + - rds; Reset rs->rs_bound_addr in rds_add_bound() failure path + - ACPI / video: Default lcd_only to true on Win8-ready and newer machines + - IB/mlx5: Report inner RSS capability + - VFS: close race between getcwd() and d_move() + - watchdog: dw_wdt: add stop watchdog operation + - clk: divider: fix incorrect usage of container_of + - PM / devfreq: Fix potential NULL pointer dereference in governor_store + - gpiolib: don't dereference a desc before validation + - net_sch: red: Fix the new offload indication + - selftests/net: fix bugs in address and port initialization + - thermal/drivers/hisi: Remove bogus const from function return type + - RDMA/cma: Mark end of CMA ID messages + - hwmon: (ina2xx) Make calibration register value fixed + - f2fs: fix lock dependency in between dio_rwsem & i_mmap_sem + - clk: sunxi-ng: a83t: Add M divider to TCON1 clock + - media: videobuf2-core: don't go out of the buffer range + - ASoC: Intel: Skylake: Disable clock gating during firmware and library + download + - ASoC: Intel: cht_bsw_rt5645: Analog Mic support + - drm/msm: Fix NULL deref in adreno_load_gpu + - IB/ipoib: Fix for notify send CQ failure messages + - spi: sh-msiof: Fix timeout failures for TX-only DMA transfers + - scsi: mpt3sas: Proper handling of set/clear of "ATA command pending" flag. + - irqchip/ompic: fix return value check in ompic_of_init() + - irqchip/gic-v3: Fix the driver probe() fail due to disabled GICC entry + - ACPI: EC: Fix debugfs_create_*() usage + - mac80211: Fix setting TX power on monitor interfaces + - vfb: fix video mode and line_length being set when loaded + - crypto: crypto4xx - perform aead icv check in the driver + - gpio: label descriptors using the device name + - arm64: asid: Do not replace active_asids if already 0 + - powernv-cpufreq: Add helper to extract pstate from PMSR + - IB/rdmavt: Allocate CQ memory on the correct node + - blk-mq: avoid to map CPU into stale hw queue + - blk-mq: fix race between updating nr_hw_queues and switching io sched + - backlight: tdo24m: Fix the SPI CS between transfers + - nvme-fabrics: protect against module unload during create_ctrl + - nvme-fabrics: don't check for non-NULL module in nvmf_register_transport + - pinctrl: baytrail: Enable glitch filter for GPIOs used as interrupts + - nvme_fcloop: disassocate local port structs + - nvme_fcloop: fix abort race condition + - tpm: return a TPM_RC_COMMAND_CODE response if command is not implemented + - perf report: Fix a no annotate browser displayed issue + - staging: lustre: disable preempt while sampling processor id. + - ASoC: Intel: sst: Fix the return value of 'sst_send_byte_stream_mrfld()' + - power: supply: axp288_charger: Properly stop work on probe-error / remove + - rt2x00: do not pause queue unconditionally on error path + - wl1251: check return from call to wl1251_acx_arp_ip_filter + - net/mlx5: Fix race for multiple RoCE enable + - bcache: ret IOERR when read meets metadata error + - bcache: stop writeback thread after detaching + - bcache: segregate flash only volume write streams + - net: Fix netdev_WARN_ONCE macro + - net/mlx5e: IPoIB, Use correct timestamp in child receive flow + - blk-mq: fix kernel oops in blk_mq_tag_idle() + - tty: n_gsm: Allow ADM response in addition to UA for control dlci + - block, bfq: put async queues for root bfq groups too + - serdev: Fix serdev_uevent failure on ACPI enumerated serdev-controllers + - EDAC, mv64x60: Fix an error handling path + - uio_hv_generic: check that host supports monitor page + - Bluetooth: hci_bcm: Mandate presence of shutdown and device wake GPIO + - Bluetooth: hci_bcm: Validate IRQ before using it + - Bluetooth: hci_bcm: Make shutdown and device wake GPIO optional + - i40evf: don't rely on netif_running() outside rtnl_lock() + - drm/amd/powerplay: fix memory leakage when reload (v2) + - cxgb4vf: Fix SGE FL buffer initialization logic for 64K pages + - PM / domains: Don't skip driver's ->suspend|resume_noirq() callbacks + - scsi: megaraid_sas: Error handling for invalid ldcount provided by firmware + in RAID map + - scsi: megaraid_sas: unload flag should be set after scsi_remove_host is + called + - RDMA/cma: Fix rdma_cm path querying for RoCE + - gpio: thunderx: fix error return code in thunderx_gpio_probe() + - x86/gart: Exclude GART aperture from vmcore + - sdhci: Advertise 2.0v supply on SDIO host controller + - Input: goodix - disable IRQs while suspended + - mtd: mtd_oobtest: Handle bitflips during reads + - crypto: aes-generic - build with -Os on gcc-7+ + - perf tools: Fix copyfile_offset update of output offset + - tcmu: release blocks for partially setup cmds + - thermal: int3400_thermal: fix error handling in int3400_thermal_probe() + - drm/i915/cnp: Ignore VBT request for know invalid DDC pin. + - drm/i915/cnp: Properly handle VBT ddc pin out of bounds. + - x86/microcode: Propagate return value from updating functions + - x86/CPU: Add a microcode loader callback + - x86/CPU: Check CPU feature bits after microcode upgrade + - x86/microcode: Get rid of struct apply_microcode_ctx + - x86/microcode/intel: Check microcode revision before updating sibling + threads + - x86/microcode/intel: Writeback and invalidate caches before updating + microcode + - x86/microcode: Do not upload microcode if CPUs are offline + - x86/microcode/intel: Look into the patch cache first + - x86/microcode: Request microcode on the BSP + - x86/microcode: Synchronize late microcode loading + - x86/microcode: Attempt late loading only when new microcode is present + - x86/microcode: Fix CPU synchronization routine + - arp: fix arp_filter on l3slave devices + - ipv6: the entire IPv6 header chain must fit the first fragment + - lan78xx: Crash in lan78xx_writ_reg (Workqueue: events + lan78xx_deferred_multicast_write) + - net: dsa: Discard frames from unused ports + - net: fix possible out-of-bound read in skb_network_protocol() + - net/ipv6: Fix route leaking between VRFs + - net/ipv6: Increment OUTxxx counters after netfilter hook + - netlink: make sure nladdr has correct size in netlink_connect() + - net/mlx5e: Verify coalescing parameters in range + - net sched actions: fix dumping which requires several messages to user space + - net/sched: fix NULL dereference in the error path of tcf_bpf_init() + - pptp: remove a buggy dst release in pptp_connect() + - r8169: fix setting driver_data after register_netdev + - sctp: do not leak kernel memory to user space + - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6 + - vhost: correctly remove wait queue during poll failure + - vlan: also check phy_driver ts_info for vlan's real device + - vrf: Fix use after free and double free in vrf_finish_output + - bonding: fix the err path for dev hwaddr sync in bond_enslave + - bonding: move dev_mc_sync after master_upper_dev_link in bond_enslave + - bonding: process the err returned by dev_set_allmulti properly in + bond_enslave + - net: fool proof dev_valid_name() + - ip_tunnel: better validate user provided tunnel names + - ipv6: sit: better validate user provided tunnel names + - ip6_gre: better validate user provided tunnel names + - ip6_tunnel: better validate user provided tunnel names + - vti6: better validate user provided tunnel names + - net/mlx5e: Set EQE based as default TX interrupt moderation mode + - net_sched: fix a missing idr_remove() in u32_delete_key() + - net/sched: fix NULL dereference in the error path of tcf_vlan_init() + - net/mlx5e: Avoid using the ipv6 stub in the TC offload neigh update path + - net/mlx5e: Fix memory usage issues in offloading TC flows + - net/sched: fix NULL dereference in the error path of tcf_sample_init() + - nfp: use full 40 bits of the NSP buffer address + - ipv6: sr: fix seg6 encap performances with TSO enabled + - net/mlx5e: Don't override vport admin link state in switchdev mode + - net/mlx5e: Sync netdev vxlan ports at open + - net/sched: fix NULL dereference in the error path of tunnel_key_init() + - net/sched: fix NULL dereference on the error path of tcf_skbmod_init() + - strparser: Fix sign of err codes + - net/mlx4_en: Fix mixed PFC and Global pause user control requests + - net/mlx5e: Fix traffic being dropped on VF representor + - vhost: validate log when IOTLB is enabled + - route: check sysctl_fib_multipath_use_neigh earlier than hash + - team: move dev_mc_sync after master_upper_dev_link in team_port_add + - vhost_net: add missing lock nesting notation + - net/mlx4_core: Fix memory leak while delete slave's resources + - Linux 4.15.17 + + * sky2 gigabit ethernet driver sometimes stops working after lid-open resume + from sleep (88E8055) (LP: #1758507) // Bionic update to v4.15.17 stable + release (LP: #1763366) + - sky2: Increase D3 delay to sky2 stops working after suspend + + * [Featire] CNL: Enable RAPL support (LP: #1685712) + - powercap: RAPL: Add support for Cannon Lake + + * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719) + - s390: move nobp parameter functions to nospec-branch.c + - s390: add automatic detection of the spectre defense + - s390: report spectre mitigation via syslog + - s390: add sysfs attributes for spectre + - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390 + - s390: correct nospec auto detection init order + + * Merge the linux-snapdragon kernel into bionic master/snapdragon + (LP: #1763040) + - drm/msm: fix spelling mistake: "ringubffer" -> "ringbuffer" + - drm/msm: fix msm_rd_dump_submit prototype + - drm/msm: gpu: Only sync fences on rings that exist + - wcn36xx: set default BTLE coexistence config + - wcn36xx: Add hardware scan offload support + - wcn36xx: Reduce spinlock in indication handler + - wcn36xx: fix incorrect assignment to msg_body.min_ch_time + - wcn36xx: release DMA memory in case of error + - mailbox: qcom: Convert APCS IPC driver to use regmap + - mailbox: qcom: Create APCS child device for clock controller + - clk: qcom: Add A53 PLL support + - clk: qcom: Add regmap mux-div clocks support + - clk: qcom: Add APCS clock controller support + - clk: qcom: msm8916: Fix return value check in qcom_apcs_msm8916_clk_probe() + - media: venus: venc: set correctly GOP size and number of B-frames + - media: venus: venc: configure entropy mode + - media: venus: venc: Apply inloop deblocking filter + - media: venus: cleanup set_property controls + - arm64: defconfig: enable REMOTEPROC + - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c + - kernel: configs; add distro.config + - arm64: configs: enable WCN36xx + - kernel: distro.config: enable debug friendly USB network adpater + - arm64: configs: enable QCOM Venus + - arm64: defconfig: Enable a53/apcs and avs + - arm64: defconfig: enable ondemand governor as default + - arm64: defconfig: enable QCOM_TSENS + - arm64: defconfig: enable new trigger modes for leds + - kernel: configs: enable dm_mod and dm_crypt + - Force the SMD regulator driver to be compiled-in + - arm64: defconfig: enable CFG80211_DEFAULT_PS by default + - arm64: configs: enable BT_QCOMSMD + - kernel: configs: add more USB net drivers + - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV + - arm64: configs: Enable camera drivers + - kernel: configs: add freq stat to sysfs + - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default + - arm64: defconfig: Enable QRTR features + - kernel: configs: set USB_CONFIG_F_FS in distro.config + - kernel: distro.config: enable 'schedutil' CPUfreq governor + - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs + - kernel: distro.config: enable 'BBR' TCP congestion algorithm + - arm64: defconfig: enable LEDS_QCOM_LPG + - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap + - power: avs: Add support for CPR (Core Power Reduction) + - power: avs: cpr: Use raw mem access for qfprom + - power: avs: cpr: fix with new reg_sequence structures + - power: avs: cpr: Register with cpufreq-dt + - regulator: smd: Add floor and corner operations + - PM / OPP: Support adjusting OPP voltages at runtime + - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage() + - PM / OPP: HACK: Allow to set regulator without opp_list + - PM / OPP: Add a helper to get an opp regulator for device + - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist + - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m + - ov5645: I2C address change + - i2c: Add Qualcomm Camera Control Interface driver + - camss: vfe: Skip first four frames from sensor + - camss: Do not register if no cameras are present + - i2c-qcom-cci: Fix run queue completion timeout + - i2c-qcom-cci: Fix I2C address bug + - media: ov5645: Fix I2C address + - drm/bridge/adv7511: Delay clearing of HPD interrupt status + - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing + - leds: Add driver for Qualcomm LPG + - wcn36xx: Fix warning due to duplicate scan_completed notification + - arm64: dts: Add CPR DT node for msm8916 + - arm64: dts: add spmi-regulator nodes + - arm64: dts: msm8916: Add cpufreq support + - arm64: dts: msm8916: Add a shared CPU opp table + - arm64: dts: msm8916: Add cpu cooling maps + - arm64: dts: pm8916: Mark the s2 regulator as always-on + - dt-bindings: mailbox: qcom: Document the APCS clock binding + - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node + - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver + - arm64: dts: qcom: msm8916: Add clock properties to the APCS node + - arm64: dts: qcom: apq8016-sbc: Allow USR4 LED to notify kernel panic + - dt-bindings: media: Binding document for Qualcomm Camera Control Interface + driver + - MAINTAINERS: Add Qualcomm Camera Control Interface driver + - DT: leds: Add Qualcomm Light Pulse Generator binding + - arm64: dts: qcom: msm8996: Add mpp and lpg blocks + - arm64: dts: qcom: Add pwm node for pm8916 + - arm64: dts: qcom: Add user LEDs on db820c + - arm64: dts: qcom: Add WiFI/BT LEDs on db820c + - ARM: dts: qcom: Add LPG node to pm8941 + - ARM: dts: qcom: honami: Add LPG node and RGB LED + - arm64: dts: qcom: Add Camera Control Interface support + - arm64: dts: qcom: Add apps_iommu vfe child node + - arm64: dts: qcom: Add camss device node + - arm64: dts: qcom: Add ov5645 device nodes + - arm64: dts: msm8916: Fix camera sensors I2C addresses + - arm: dts: qcom: db410c: Enable PWM signal on MPP4 + - packaging: arm64: add a uboot flavour - part1 + - packaging: arm64: add a uboot flavour - part2 + - packaging: arm64: add a uboot flavour - part3 + - packaging: arm64: add a uboot flavour - part4 + - packaging: arm64: add a uboot flavour - part5 + - packaging: arm64: rename uboot flavour to snapdragon + - [Config] updateconfigs after qcomlt import + - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: MSM_GCC_8916=y + - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y + - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y + - [Config] arm64: snapdragon: QCOM_SMEM=y + - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: QCOM_CPR=y + - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y + - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y + - [Config] turn off DRM_MSM_REGISTER_LOGGING + - [Config] arm64: snapdragon: I2C_QUP=y + - [Config] arm64: snapdragon: SPI_QUP=y + - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y + - [Config] arm64: snapdragon: QCOM_SMSM=y + - [Config] arm64: snapdragon: QCOM_SMP2P=y + - [Config] arm64: snapdragon: DRM_MSM=y + - [Config] arm64: snapdragon: SND_SOC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m + - [Config] arm64: snapdragon: QCOM_A53PLL=y, QCOM_CLK_APCS_MSM8916=y + - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m + - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y + - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y, + SND_SOC_MSM8916_WCD_DIGITAL=y + - SAUCE: media: ov5645: skip address change if dt addr == default addr + - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS + #ifdefs + - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y + - packaging: snapdragon: fixup ABI paths + + * LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: Manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: Manage task security blobs + - SAUCE: LSM stacking: LSM: Manage remaining security blobs + - SAUCE: LSM stacking: LSM: General stacking + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: add apparmor and selinux proc dirs + - SAUCE: LSM stacking: remove procfs context interface + + * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14 + (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: check for invalid zero sized writes + + * RDMA/hns: ensure for-loop actually iterates and free's buffers + (LP: #1762757) + - RDMA/hns: ensure for-loop actually iterates and free's buffers + + * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems + (LP: #1762755) + - RDMA/hns: Fix the endian problem for hns + - RDMA/hns: Support rq record doorbell for the user space + - RDMA/hns: Support cq record doorbell for the user space + - RDMA/hns: Support rq record doorbell for kernel space + - RDMA/hns: Support cq record doorbell for kernel space + - RDMA/hns: Fix cqn type and init resp + - RDMA/hns: Fix init resp when alloc ucontext + - RDMA/hns: Fix cq record doorbell enable in kernel + + * Replace LPC patchset with upstream version (LP: #1762758) + - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver" + - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support" + - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host + children" + - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT + bindings" + - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO + devices" + - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO + hosts" + - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method" + - lib: Add generic PIO mapping method + - PCI: Remove __weak tag from pci_register_io_range() + - PCI: Add fwnode handler as input param of pci_register_io_range() + - PCI: Apply the new generic I/O management on PCI IO hosts + - of: Add missing I/O range exception for indirect-IO devices + - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use + - ACPI / scan: Do not enumerate Indirect IO host children + - HISI LPC: Add ACPI support + - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver + + * Enable Tunneled Operations on POWER9 (LP: #1762448) + - powerpc/powernv: Enable tunneled operations + - cxl: read PHB indications from the device tree + + * PSL traces reset after PERST for debug AFU image (LP: #1762462) + - cxl: Enable NORST bit in PSL_DEBUG register for PSL9 + + * NFS + sec=krb5 is broken (LP: #1759791) + - sunrpc: remove incorrect HMAC request initialization + + * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128) + - d-i: add bcm2835 to block-modules + + * Backport USB core quirks (LP: #1762695) + - usb: core: Add "quirks" parameter for usbcore + - usb: core: Copy parameter string correctly and remove superfluous null check + - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks + + * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on failed' when + setting up a second end-to-end encrypted disk (LP: #1762353) + - SAUCE: s390/crypto: Adjust s390 aes and paes cipher + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 + - powerpc/64s: Wire up cpu_show_spectre_v2() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753 + - powerpc/64s: Wire up cpu_show_spectre_v1() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754 + - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code + - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again + - powerpc/rfi-flush: Always enable fallback flush on pseries + - powerpc/rfi-flush: Differentiate enabled and patched flush types + - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration + - powerpc/64s: Move cpu_show_meltdown() + - powerpc/64s: Enhance the information in cpu_show_meltdown() + - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush() + - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 // + CVE-2017-5753 // CVE-2017-5754 + - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags + - powerpc: Add security feature flags for Spectre/Meltdown + - powerpc/pseries: Set or clear security feature flags + - powerpc/powernv: Set or clear security feature flags + + * Hisilicon network subsystem 3 support (LP: #1761610) + - net: hns3: export pci table of hclge and hclgevf to userspace + - d-i: Add hns3 drivers to nic-modules + + * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534) + - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS + + * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712) + - perf vendor events aarch64: Add JSON metrics for ARM Cortex-A53 Processor + - perf vendor events: Drop incomplete multiple mapfile support + - perf vendor events: Fix error code in json_events() + - perf vendor events: Drop support for unused topic directories + - perf vendor events: Add support for pmu events vendor subdirectory + - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory + - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory + - perf vendor events: Add support for arch standard events + - perf vendor events arm64: Add armv8-recommended.json + - perf vendor events arm64: Fixup ThunderX2 to use recommended events + - perf vendor events arm64: fixup A53 to use recommended events + - perf vendor events arm64: add HiSilicon hip08 JSON file + - perf vendor events arm64: Enable JSON events for ThunderX2 B0 + + * Warning "cache flush timed out!" seen when unloading the cxl driver + (LP: #1762367) + - cxl: Check if PSL data-cache is available before issue flush request + + * Bionic update to 4.15.16 stable release (LP: #1762370) + - ARM: OMAP: Fix SRAM W+X mapping + - ARM: 8746/1: vfp: Go back to clearing vfp_current_hw_state[] + - ARM: dts: sun6i: a31s: bpi-m2: improve pmic properties + - ARM: dts: sun6i: a31s: bpi-m2: add missing regulators + - mtd: jedec_probe: Fix crash in jedec_read_mfr() + - mtd: nand: atmel: Fix get_sectorsize() function + - ALSA: usb-audio: Add native DSD support for TEAC UD-301 + - ALSA: pcm: Use dma_bytes as size parameter in dma_mmap_coherent() + - ALSA: pcm: potential uninitialized return values + - x86/platform/uv/BAU: Add APIC idt entry + - perf/hwbp: Simplify the perf-hwbp code, fix documentation + - ceph: only dirty ITER_IOVEC pages for direct read + - ipc/shm.c: add split function to shm_vm_ops + - i2c: i2c-stm32f7: fix no check on returned setup + - powerpc/mm: Add tracking of the number of coprocessors using a context + - powerpc/mm: Workaround Nest MMU bug with TLB invalidations + - powerpc/64s: Fix i-side SLB miss bad address handler saving nonvolatile GPRs + - partitions/msdos: Unable to mount UFS 44bsd partitions + - xfrm_user: uncoditionally validate esn replay attribute struct + - RDMA/ucma: Check AF family prior resolving address + - RDMA/ucma: Fix use-after-free access in ucma_close + - RDMA/ucma: Ensure that CM_ID exists prior to access it + - RDMA/rdma_cm: Fix use after free race with process_one_req + - RDMA/ucma: Check that device is connected prior to access it + - RDMA/ucma: Check that device exists prior to accessing it + - RDMA/ucma: Introduce safer rdma_addr_size() variants + - ipv6: fix possible deadlock in rt6_age_examine_exception() + - net: xfrm: use preempt-safe this_cpu_read() in ipcomp_alloc_tfms() + - xfrm: Refuse to insert 32 bit userspace socket policies on 64 bit systems + - percpu: add __GFP_NORETRY semantics to the percpu balancing path + - netfilter: x_tables: make allocation less aggressive + - netfilter: bridge: ebt_among: add more missing match size checks + - l2tp: fix races with ipv4-mapped ipv6 addresses + - netfilter: drop template ct when conntrack is skipped. + - netfilter: x_tables: add and use xt_check_proc_name + - phy: qcom-ufs: add MODULE_LICENSE tag + - Bluetooth: Fix missing encryption refresh on Security Request + - drm/i915/dp: Write to SET_POWER dpcd to enable MST hub. + - bitmap: fix memset optimization on big-endian systems + - USB: serial: ftdi_sio: add RT Systems VX-8 cable + - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator + - USB: serial: cp210x: add ELDAT Easywave RX09 id + - serial: 8250: Add Nuvoton NPCM UART + - mei: remove dev_err message on an unsupported ioctl + - /dev/mem: Avoid overwriting "err" in read_mem() + - media: usbtv: prevent double free in error case + - parport_pc: Add support for WCH CH382L PCI-E single parallel port card. + - crypto: lrw - Free rctx->ext with kzfree + - crypto: talitos - don't persistently map req_ctx->hw_context and + req_ctx->buf + - crypto: inside-secure - fix clock management + - crypto: testmgr - Fix incorrect values in PKCS#1 test vector + - crypto: talitos - fix IPsec cipher in length + - crypto: ahash - Fix early termination in hash walk + - crypto: caam - Fix null dereference at error path + - crypto: ccp - return an actual key size from RSA max_size callback + - crypto: arm,arm64 - Fix random regeneration of S_shipped + - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one + - Btrfs: fix unexpected cow in run_delalloc_nocow + - staging: comedi: ni_mio_common: ack ai fifo error interrupts. + - Revert "base: arch_topology: fix section mismatch build warnings" + - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370 + - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list + - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad + - vt: change SGR 21 to follow the standards + - ARM: dts: DRA76-EVM: Set powerhold property for tps65917 + - net: hns: Fix ethtool private flags + - Fix slab name "biovec-(1<<(21-12))" + - Revert "ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin" + - Revert "ARM: dts: omap3-n900: Fix the audio CODEC's reset pin" + - Revert "cpufreq: Fix governor module removal race" + - Revert "ip6_vti: adjust vti mtu according to mtu of lower device" + - Linux 4.15.16 + + * [18.04][config] regression: nvme and nvme_core couldn't be built as modules + starting 4.15-rc2 (LP: #1759893) + - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for + build" + - [Config] CONFIG_BLK_DEV_NMVE=m + + * Miscellaneous Ubuntu changes + - [Packaging] Only install cloud init files when do_tools_common=true + + -- Thadeu Lima de Souza Cascardo Fri, 13 Apr 2018 14:40:52 -0300 + +linux (4.15.0-15.16) bionic; urgency=medium + + * linux: 4.15.0-15.16 -proposed tracker (LP: #1761177) + + * FFe: Enable configuring resume offset via sysfs (LP: #1760106) + - PM / hibernate: Make passing hibernate offsets more friendly + + * /dev/bcache/by-uuid links not created after reboot (LP: #1729145) + - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent + + * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine + type(pseries-bionic) complaining "KVM implementation does not support + Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026) + - powerpc: Use feature bit for RTC presence rather than timebase presence + - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit + - powerpc: Free up CPU feature bits on 64-bit machines + - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2 + - powerpc/powernv: Provide a way to force a core into SMT4 mode + - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9 + - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode + - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state + + * Important Kernel fixes to be backported for Power9 (kvm) (LP: #1758910) + - powerpc/mm: Fixup tlbie vs store ordering issue on POWER9 + + * Ubuntu 18.04 - IO Hang on some namespaces when running HTX with 16 + namespaces (Bolt / NVMe) (LP: #1757497) + - powerpc/64s: Fix lost pending interrupt due to race causing lost update to + irq_happened + + * fwts-efi-runtime-dkms 18.03.00-0ubuntu1: fwts-efi-runtime-dkms kernel module + failed to build (LP: #1760876) + - [Packaging] include the retpoline extractor in the headers + + -- Seth Forshee Wed, 04 Apr 2018 08:26:19 -0500 + +linux (4.15.0-14.15) bionic; urgency=medium + + * linux: 4.15.0-14.15 -proposed tracker (LP: #1760678) + + * [Bionic] mlx4 ETH - mlnx_qos failed when set some TC to vendor + (LP: #1758662) + - net/mlx4_en: Change default QoS settings + + * AT_BASE_PLATFORM in AUXV is absent on kernels available on Ubuntu 17.10 + (LP: #1759312) + - powerpc/64s: Fix NULL AT_BASE_PLATFORM when using DT CPU features + + * Bionic update to 4.15.15 stable release (LP: #1760585) + - net: dsa: Fix dsa_is_user_port() test inversion + - openvswitch: meter: fix the incorrect calculation of max delta_t + - qed: Fix MPA unalign flow in case header is split across two packets. + - tcp: purge write queue upon aborting the connection + - qed: Fix non TCP packets should be dropped on iWARP ll2 connection + - sysfs: symlink: export sysfs_create_link_nowarn() + - net: phy: relax error checking when creating sysfs link netdev->phydev + - devlink: Remove redundant free on error path + - macvlan: filter out unsupported feature flags + - net: ipv6: keep sk status consistent after datagram connect failure + - ipv6: old_dport should be a __be16 in __ip6_datagram_connect() + - ipv6: sr: fix NULL pointer dereference when setting encap source address + - ipv6: sr: fix scheduling in RCU when creating seg6 lwtunnel state + - mlxsw: spectrum_buffers: Set a minimum quota for CPU port traffic + - net: phy: Tell caller result of phy_change() + - ipv6: Reflect MTU changes on PMTU of exceptions for MTU-less routes + - net sched actions: return explicit error when tunnel_key mode is not + specified + - ppp: avoid loop in xmit recursion detection code + - rhashtable: Fix rhlist duplicates insertion + - test_rhashtable: add test case for rhltable with duplicate objects + - kcm: lock lower socket in kcm_attach + - sch_netem: fix skb leak in netem_enqueue() + - ieee802154: 6lowpan: fix possible NULL deref in lowpan_device_event() + - net: use skb_to_full_sk() in skb_update_prio() + - net: Fix hlist corruptions in inet_evict_bucket() + - s390/qeth: free netdevice when removing a card + - s390/qeth: when thread completes, wake up all waiters + - s390/qeth: lock read device while queueing next buffer + - s390/qeth: on channel error, reject further cmd requests + - soc/fsl/qbman: fix issue in qman_delete_cgr_safe() + - dpaa_eth: fix error in dpaa_remove() + - dpaa_eth: remove duplicate initialization + - dpaa_eth: increment the RX dropped counter when needed + - dpaa_eth: remove duplicate increment of the tx_errors counter + - dccp: check sk for closed state in dccp_sendmsg() + - ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option() + - l2tp: do not accept arbitrary sockets + - net: ethernet: arc: Fix a potential memory leak if an optional regulator is + deferred + - net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY + interface + - net: fec: Fix unbalanced PM runtime calls + - net/iucv: Free memory obtained by kzalloc + - netlink: avoid a double skb free in genlmsg_mcast() + - net: Only honor ifindex in IP_PKTINFO if non-0 + - net: systemport: Rewrite __bcm_sysport_tx_reclaim() + - qede: Fix qedr link update + - skbuff: Fix not waking applications when errors are enqueued + - team: Fix double free in error path + - Linux 4.15.15 + + * Ubuntu 18.04 [ WSP DD2.2 with stop4 and stop5 enabled ]: kdump fails to + capture dump when smt=2 or off. (LP: #1758206) + - powerpc/crash: Remove the test for cpu_online in the IPI callback + - powernv/kdump: Fix cases where the kdump kernel can get HMI's + - powerpc/kdump: Fix powernv build break when KEXEC_CORE=n + + * [Intel Ubuntu 18.04 Bug] Null pointer dereference, when disconnecting RAID + rebuild target (LP: #1759279) + - md: document lifetime of internal rdev pointer. + + * [Feature]Crystal Ridge:add support for the platform capabilities NFIT sub- + table in ACPI 6.2A (LP: #1730829) + - ACPICA: ACPI 6.0A: Changes to the NFIT ACPI table + - acpi: nfit: Add support for detect platform CPU cache flush on power loss + - acpi: nfit: add persistent memory control flag for nd_region + - libnvdimm: expose platform persistence attribute for nd_region + - libnvdimm: re-enable deep flush for pmem devices via fsync() + - libnvdimm, nfit: fix persistence domain reporting + + * Allow multiple mounts of zfs datasets (LP: #1759848) + - SAUCE: Allow mounting datasets more than once (LP: #1759848) + + * Update Aquantia driver to fix various issues (LP: #1759303) + - net: aquantia: Eliminate AQ_DIMOF, replace with ARRAY_SIZE + - net: aquantia: Cleanup status flags accesses + - net: aquantia: Cleanup hardware access modules + - net: aquantia: Remove duplicate hardware descriptors declarations + - net: aquantia: Add const qualifiers for hardware ops tables + - net: aquantia: Simplify dependencies between pci modules + - net: aquantia: Eliminate aq_nic structure abstraction + - net: aquantia: Fix register definitions to linux style + - net: aquantia: Prepend hw access functions declarations with prefix + - net: aquantia: Fix internal stats calculation on rx + - net: aquantia: Introduce new device ids and constants + - net: aquantia: Introduce new AQC devices and capabilities + - net: aquantia: Convert hw and caps structures to const static pointers + - net: aquantia: Cleanup pci functions module + - net: aquantia: Remove create/destroy from hw ops + - net: aquantia: Change confusing no_ff_addr to more meaningful name + - net: aquantia: Introduce firmware ops callbacks + - net: aquantia: Introduce support for new firmware on AQC cards + - net: aquantia: Introduce global AQC hardware reset sequence + - net: aquantia: Report correct mediatype via ethtool + - net: aquantia: bump driver version to match aquantia internal numbering + - net: aquantia: Fix hardware reset when SPI may rarely hangup + - net: aquantia: Fix a regression with reset on old firmware + - net: aquantia: Change inefficient wait loop on fw data reads + - net: aquantia: Add tx clean budget and valid budget handling logic + - net: aquantia: Allow live mac address changes + - net: aquantia: Implement pci shutdown callback + - net: aquantia: driver version bump + + * ISST-LTE:KVM:Ubuntu1804:BostonLC:boslcp3: cpu hotplug on boslcp3g4 guest + dumping call traces continuously. (LP: #1759722) + - blk-mq: turn WARN_ON in __blk_mq_run_hw_queue into printk + + * ISST-LTE:KVM:Ubuntu18.04:BostonLC:boslcp3:boslcp3g3:Guest conosle hangs + after hotplug CPU add operation. (LP: #1759723) + - genirq/affinity: assign vectors to all possible CPUs + - blk-mq: simplify queue mapping & schedule with each possisble CPU + + * test_bpf fails (LP: #1756150) + - test_bpf: Fix testing with CONFIG_BPF_JIT_ALWAYS_ON=y on other arches + + * Bionic update to v4.15.14 stable release (LP: #1759655) + - MIPS: ralink: Remove ralink_halt() + - MIPS: ralink: Fix booting on MT7621 + - MIPS: lantiq: Fix Danube USB clock + - MIPS: lantiq: Enable AHB Bus for USB + - MIPS: lantiq: ase: Enable MFD_SYSCON + - iio: chemical: ccs811: Corrected firmware boot/application mode transition + - iio: st_pressure: st_accel: pass correct platform data to init + - iio: adc: meson-saradc: unlock on error in meson_sar_adc_lock() + - ALSA: usb-audio: Fix parsing descriptor of UAC2 processing unit + - ALSA: aloop: Sync stale timer before release + - ALSA: aloop: Fix access to not-yet-ready substream via cable + - ALSA: hda - Force polling mode on CFL for fixing codec communication + - ALSA: hda/realtek - Fix speaker no sound after system resume + - ALSA: hda/realtek - Fix Dell headset Mic can't record + - ALSA: hda/realtek - Always immediately update mute LED with pin VREF + - mmc: core: Fix tracepoint print of blk_addr and blksz + - mmc: core: Disable HPI for certain Micron (Numonyx) eMMC cards + - mmc: block: fix updating ext_csd caches on ioctl call + - mmc: dw_mmc: Fix the DTO/CTO timeout overflow calculation for 32-bit systems + - mmc: dw_mmc: exynos: fix the suspend/resume issue for exynos5433 + - mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs + - PCI: Add function 1 DMA alias quirk for Highpoint RocketRAID 644L + - ahci: Add PCI-id for the Highpoint Rocketraid 644L card + - lockdep: fix fs_reclaim warning + - clk: bcm2835: Fix ana->maskX definitions + - clk: bcm2835: Protect sections updating shared registers + - clk: sunxi-ng: a31: Fix CLK_OUT_* clock ops + - RDMA/mlx5: Fix crash while accessing garbage pointer and freed memory + - Drivers: hv: vmbus: Fix ring buffer signaling + - pinctrl: samsung: Validate alias coming from DT + - Bluetooth: btusb: Remove Yoga 920 from the btusb_needs_reset_resume_table + - Bluetooth: btusb: Add Dell OptiPlex 3060 to btusb_needs_reset_resume_table + - Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174 + - libata: fix length validation of ATAPI-relayed SCSI commands + - libata: remove WARN() for DMA or PIO command without data + - libata: don't try to pass through NCQ commands to non-NCQ devices + - libata: Apply NOLPM quirk to Crucial MX100 512GB SSDs + - libata: Enable queued TRIM for Samsung SSD 860 + - libata: Apply NOLPM quirk to Crucial M500 480 and 960GB SSDs + - libata: Make Crucial BX100 500GB LPM quirk apply to all firmware versions + - libata: Modify quirks for MX100 to limit NCQ_TRIM quirk to MU01 version + - sched, cgroup: Don't reject lower cpu.max on ancestors + - cgroup: fix rule checking for threaded mode switching + - nfsd: remove blocked locks on client teardown + - media: tegra-cec: reset rx_buf_cnt when start bit detected + - hugetlbfs: check for pgoff value overflow + - h8300: remove extraneous __BIG_ENDIAN definition + - mm/vmalloc: add interfaces to free unmapped page table + - x86/mm: implement free pmd/pte page interfaces + - mm/khugepaged.c: convert VM_BUG_ON() to collapse fail + - mm/thp: do not wait for lock_page() in deferred_split_scan() + - mm/shmem: do not wait for lock_page() in shmem_unused_huge_shrink() + - Revert "mm: page_alloc: skip over regions of invalid pfns where possible" + - drm/vmwgfx: Fix black screen and device errors when running without fbdev + - drm/vmwgfx: Fix a destoy-while-held mutex problem. + - drm/radeon: Don't turn off DP sink when disconnected + - drm/amd/display: We shouldn't set format_default on plane as atomic driver + - drm/amd/display: Add one to EDID's audio channel count when passing to DC + - drm: Reject getfb for multi-plane framebuffers + - drm: udl: Properly check framebuffer mmap offsets + - mm/vmscan: wake up flushers for legacy cgroups too + - module: propagate error in modules_open() + - acpi, numa: fix pxm to online numa node associations + - ACPI / watchdog: Fix off-by-one error at resource assignment + - libnvdimm, {btt, blk}: do integrity setup before add_disk() + - brcmfmac: fix P2P_DEVICE ethernet address generation + - rtlwifi: rtl8723be: Fix loss of signal + - tracing: probeevent: Fix to support minus offset from symbol + - mtdchar: fix usage of mtd_ooblayout_ecc() + - mtd: nand: fsl_ifc: Fix nand waitfunc return value + - mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0 + - mtd: nand: fsl_ifc: Read ECCSTAT0 and ECCSTAT1 registers for IFC 2.0 + - staging: ncpfs: memory corruption in ncp_read_kernel() + - can: peak/pcie_fd: fix echo_skb is occupied! bug + - can: peak/pcie_fd: remove useless code when interface starts + - can: ifi: Repair the error handling + - can: ifi: Check core revision upon probe + - can: cc770: Fix stalls on rt-linux, remove redundant IRQ ack + - can: cc770: Fix queue stall & dropped RTR reply + - can: cc770: Fix use after free in cc770_tx_interrupt() + - tty: vt: fix up tabstops properly + - x86/entry/64: Don't use IST entry for #BP stack + - selftests/x86/ptrace_syscall: Fix for yet more glibc interference + - x86/vsyscall/64: Use proper accessor to update P4D entry + - x86/efi: Free efi_pgd with free_pages() + - posix-timers: Protect posix clock array access against speculation + - kvm/x86: fix icebp instruction handling + - x86/build/64: Force the linker to use 2MB page size + - x86/boot/64: Verify alignment of the LOAD segment + - hwmon: (k10temp) Only apply temperature offset if result is positive + - hwmon: (k10temp) Add temperature offset for Ryzen 1900X + - perf/x86/intel/uncore: Fix Skylake UPI event format + - perf stat: Fix CVS output format for non-supported counters + - perf/core: Fix ctx_event_type in ctx_resched() + - trace/bpf: remove helper bpf_perf_prog_read_value from tracepoint type + programs + - perf/x86/intel: Don't accidentally clear high bits in bdw_limit_period() + - perf/x86/intel/uncore: Fix multi-domain PCI CHA enumeration bug on Skylake + servers + - iio: ABI: Fix name of timestamp sysfs file + - iio: imu: st_lsm6dsx: fix endianness in st_lsm6dsx_read_oneshot() + - iio: imu: st_lsm6dsx: introduce conf_lock mutex + - staging: android: ion: Zero CMA allocated memory + - kbuild: disable clang's default use of -fmerge-all-constants + - bpf: skip unnecessary capability check + - bpf, x64: increase number of passes + - Linux 4.15.14 + + * System fails to start (boot) on battery due to read-only root file-system + (LP: #1726930) // Bionic update to v4.15.14 stable release (LP: #1759655) + - libata: disable LPM for Crucial BX100 SSD 500GB drive + + * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775) + - thunderbolt: Resume control channel after hibernation image is created + - thunderbolt: Serialize PCIe tunnel creation with PCI rescan + - thunderbolt: Handle connecting device in place of host properly + - thunderbolt: Do not overwrite error code when domain adding fails + - thunderbolt: Wait a bit longer for root switch config space + - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM + - thunderbolt: Handle rejected Thunderbolt devices + - thunderbolt: Factor common ICM add and update operations out + - thunderbolt: Correct function name in kernel-doc comment + - thunderbolt: Add tb_switch_get() + - thunderbolt: Add tb_switch_find_by_route() + - thunderbolt: Add tb_xdomain_find_by_route() + - thunderbolt: Add constant for approval timeout + - thunderbolt: Move driver ready handling to struct icm + - thunderbolt: Add 'boot' attribute for devices + - thunderbolt: Add support for preboot ACL + - Documentation/admin-guide: fixes for thunderbolt.rst + - thunderbolt: Introduce USB only (SL4) security level + - thunderbolt: Add support for Intel Titan Ridge + + * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345) + - ath10k: update the IRAM bank number for QCA9377 + + * nfp: fix disabling on hw-tc-offload in flower (LP: #1752828) + - nfp: bpf: require ETH table + - nfp: don't advertise hw-tc-offload on non-port netdevs + - nfp: forbid disabling hw-tc-offload on representors while offload active + + * Fix an issue that when system in S3, USB keyboard can't wake up the system. + (LP: #1759511) + - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW + + * retpoline hints: primary infrastructure and initial hints (LP: #1758856) + - [Packaging] retpoline -- add safe usage hint support + - [Packaging] retpoline-check -- only report additions + - [Packaging] retpoline -- widen indirect call/jmp detection + - [Packaging] retpoline -- elide %rip relative indirections + - [Packaging] retpoline -- clear hint information from packages + - SAUCE: apm -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: EFI -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: early/late -- annotate indirect calls in early/late initialisation + code + - SAUCE: vga_set_mode -- avoid jump tables + - [Config] retpoine -- switch to new format + + * zfs system process hung on container stop/delete (LP: #1754584) + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)" + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + + * Important KVM fixes for ppc64el (LP: #1759045) + - KVM: PPC: Book3S HV: Do SLB load/unload with guest LPCR value loaded + - KVM: PPC: Book3S HV: Fix handling of secondary HPTEG in HPT resizing code + - KVM: PPC: Book3S HV: Make HPT resizing work on POWER9 + - KVM: PPC: Book3S: Add MMIO emulation for VMX instructions + - KVM: PPC: Book3S: Fix compile error that occurs with some gcc versions + - KVM: PPC: Book3S HV: Fix trap number return from __kvmppc_vcore_entry + - KVM: PPC: Book3S HV: Fix duplication of host SLB entries + + * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64 + (LP: #1755073) + - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK + + * Update to ocxl driver (LP: #1755161) + - ocxl: fix signed comparison with less than zero + - ocxl: Fix potential bad errno on irq allocation + - ocxl: Add get_metadata IOCTL to share OCXL information to userspace + + * CAPI Flash (cxlflash) update (LP: #1752672) + - scsi: cxlflash: Update cxl-specific arguments to generic cookie + - scsi: cxlflash: Explicitly cache number of interrupts per context + - scsi: cxlflash: Remove embedded CXL work structures + - scsi: cxlflash: Adapter context init can return error + - scsi: cxlflash: Staging to support future accelerators + - SAUCE: cxlflash: Preserve number of interrupts for master contexts + - SAUCE: cxlflash: Avoid clobbering context control register value + - SAUCE: cxlflash: Add argument identifier names + - SAUCE: cxlflash: Introduce OCXL backend + - SAUCE: cxlflash: Hardware AFU for OCXL + - SAUCE: cxlflash: Read host function configuration + - SAUCE: cxlflash: Setup function acTag range + - SAUCE: cxlflash: Read host AFU configuration + - SAUCE: cxlflash: Setup AFU acTag range + - SAUCE: cxlflash: Setup AFU PASID + - SAUCE: cxlflash: Adapter context support for OCXL + - SAUCE: cxlflash: Use IDR to manage adapter contexts + - SAUCE: cxlflash: Support adapter file descriptors for OCXL + - SAUCE: cxlflash: Support adapter context discovery + - SAUCE: cxlflash: Support image reload policy modification + - SAUCE: cxlflash: MMIO map the AFU + - SAUCE: cxlflash: Support starting an adapter context + - SAUCE: cxlflash: Support process specific mappings + - SAUCE: cxlflash: Support AFU state toggling + - SAUCE: cxlflash: Support reading adapter VPD data + - SAUCE: cxlflash: Setup function OCXL link + - SAUCE: cxlflash: Setup OCXL transaction layer + - SAUCE: cxlflash: Support process element lifecycle + - SAUCE: cxlflash: Support AFU interrupt management + - SAUCE: cxlflash: Support AFU interrupt mapping and registration + - SAUCE: cxlflash: Support starting user contexts + - SAUCE: cxlflash: Support adapter context polling + - SAUCE: cxlflash: Support adapter context reading + - SAUCE: cxlflash: Support adapter context mmap and release + - SAUCE: cxlflash: Support file descriptor mapping + - SAUCE: cxlflash: Introduce object handle fop + - SAUCE: cxlflash: Setup LISNs for user contexts + - SAUCE: cxlflash: Setup LISNs for master contexts + - SAUCE: cxlflash: Update synchronous interrupt status bits + - SAUCE: cxlflash: Introduce OCXL context state machine + - SAUCE: cxlflash: Register for translation errors + - SAUCE: cxlflash: Support AFU reset + - SAUCE: cxlflash: Enable OCXL operations + + * [Feature][CFL] Enable pmc_core driver for H, S, and U SKUs (LP: #1730770) + - platform/x86: intel_pmc_core: Remove unused EXPORTED API + - platform/x86: intel_pmc_core: Change driver to a module + - platform/x86: intel_pmc_core: Fix file permission warnings + - platform/x86: intel_pmc_core: Refactor debugfs entries + - platform/x86: intel_pmc_core: Substitute PCI with CPUID enumeration + - platform/x86: intel_pmc_core: Convert to ICPU macro + - platform/x86: intel_pmc_core: Remove unused header file + - ACPI / LPIT: Export lpit_read_residency_count_address() + - platform/x86: intel_pmc_core: Read base address from LPIT + - x86/cpu: Add Cannonlake to Intel family + - platform/x86: intel_pmc_core: Add CannonLake PCH support + - platform/x86: intel_pmc_core: Special case for Coffeelake + + * Cpu utilization showing system time for kvm guests (performance) (sysstat) + (LP: #1755979) + - KVM: PPC: Book3S HV: Fix guest time accounting with VIRT_CPU_ACCOUNTING_GEN + + * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core + (LP: #1736393) + - SAUCE: drm/i915:Don't set chip specific data + - SAUCE: drm/i915: make previous commit affects Wyse 3040 only + + * [Bug] ISH support for CFL-H (LP: #1739522) + - HID: intel-ish-hid: Enable Cannon Lake and Coffee Lake laptop/desktop + + * ath9k can't connect to wifi AP (LP: #1727228) + - ath9k: add MSI support + - ath9k: add a quirk to set use_msi automatically + + * [P9,Power NV][Witherspoon][Ubuntu 18.04][Perf] : PMU events by name it is + not listed under perf list (LP: #1755470) + - iperf vendor events: Use more flexible pattern matching for CPU + identification for mapfile.csv + + * zed process consuming 100% cpu (LP: #1751796) + - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796) + + * Bionic update to 4.15.13 stable release (LP: #1758886) + - scsi: megaraid_sas: Do not use 32-bit atomic request descriptor for Ventura + controllers + - staging: android: ashmem: Fix possible deadlock in ashmem_ioctl + - drm/amdgpu: use polling mem to set SDMA3 wptr for VF + - Bluetooth: hci_qca: Avoid setup failure on missing rampatch + - Bluetooth: btqcomsmd: Fix skb double free corruption + - cpufreq: longhaul: Revert transition_delay_us to 200 ms + - media: c8sectpfe: fix potential NULL pointer dereference in + c8sectpfe_timer_interrupt + - drm/msm: fix leak in failed get_pages + - IB/ipoib: Warn when one port fails to initialize + - RDMA/iwpm: Fix uninitialized error code in iwpm_send_mapinfo() + - hv_netvsc: Fix the receive buffer size limit + - hv_netvsc: Fix the TX/RX buffer default sizes + - tcp: allow TLP in ECN CWR + - spi: sh-msiof: Avoid writing to registers from spi_master.setup() + - libbpf: prefer global symbols as bpf program name source + - rtlwifi: rtl_pci: Fix the bug when inactiveps is enabled. + - rtlwifi: always initialize variables given to RT_TRACE() + - media: bt8xx: Fix err 'bt878_probe()' + - ath10k: handling qos at STA side based on AP WMM enable/disable + - media: [RESEND] media: dvb-frontends: Add delay to Si2168 restart + - qmi_wwan: set FLAG_SEND_ZLP to avoid network initiated disconnect + - tty: goldfish: Enable 'earlycon' only if built-in + - serial: 8250_dw: Disable clock on error + - cros_ec: fix nul-termination for firmware build info + - watchdog: Fix potential kref imbalance when opening watchdog + - watchdog: Fix kref imbalance seen if handle_boot_enabled=0 + - platform/chrome: Use proper protocol transfer function + - dmaengine: zynqmp_dma: Fix race condition in the probe + - drm/tilcdc: ensure nonatomic iowrite64 is not used + - mmc: avoid removing non-removable hosts during suspend + - mmc: block: fix logical error to avoid memory leak + - /dev/mem: Add bounce buffer for copy-out + - net: phy: meson-gxl: check phy_write return value + - sfp: fix EEPROM reading in the case of non-SFF8472 SFPs + - sfp: fix non-detection of PHY + - media: s5p-mfc: Fix lock contention - request_firmware() once + - rtc: ac100: Fix multiple race conditions + - IB/ipoib: Avoid memory leak if the SA returns a different DGID + - RDMA/cma: Use correct size when writing netlink stats + - IB/umem: Fix use of npages/nmap fields + - iser-target: avoid reinitializing rdma contexts for isert commands + - bpf/cgroup: fix a verification error for a CGROUP_DEVICE type prog + - vgacon: Set VGA struct resource types + - omapdrm: panel: fix compatible vendor string for td028ttec1 + - mmc: sdhci-xenon: wait 5ms after set 1.8V signal enable + - drm/omap: DMM: Check for DMM readiness after successful transaction commit + - pty: cancel pty slave port buf's work in tty_release + - coresight: Fix disabling of CoreSight TPIU + - PCI: designware-ep: Fix ->get_msi() to check MSI_EN bit + - PCI: endpoint: Fix find_first_zero_bit() usage + - PCI: rcar: Handle rcar_pcie_parse_request_of_pci_ranges() failures + - media: davinci: fix a debug printk + - clk: check ops pointer on clock register + - dt-bindings: display: panel: Fix compatible string for Toshiba LT089AC29000 + - clk: use round rate to bail out early in set_rate + - pinctrl: Really force states during suspend/resume + - pinctrl: rockchip: enable clock when reading pin direction register + - iommu/vt-d: clean up pr_irq if request_threaded_irq fails + - ip6_vti: adjust vti mtu according to mtu of lower device + - ip_gre: fix error path when erspan_rcv failed + - ip_gre: fix potential memory leak in erspan_rcv + - soc: qcom: smsm: fix child-node lookup + - RDMA/ocrdma: Fix permissions for OCRDMA_RESET_STATS + - ARM: dts: aspeed-evb: Add unit name to memory node + - nfsd4: permit layoutget of executable-only files + - clk: at91: pmc: Wait for clocks when resuming + - clk: Don't touch hardware when reparenting during registration + - clk: axi-clkgen: Correctly handle nocount bit in recalc_rate() + - clk: si5351: Rename internal plls to avoid name collisions + - crypto: artpec6 - set correct iv size for gcm(aes) + - hwrng: core - Clean up RNG list when last hwrng is unregistered + - dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63 + - IB/mlx5: Fix integer overflows in mlx5_ib_create_srq + - IB/mlx5: Fix out-of-bounds read in create_raw_packet_qp_rq + - RDMA/vmw_pvrdma: Fix usage of user response structures in ABI file + - serial: 8250_pci: Don't fail on multiport card class + - RDMA/core: Do not use invalid destination in determining port reuse + - clk: migrate the count of orphaned clocks at init + - RDMA/ucma: Fix access to non-initialized CM_ID object + - RDMA/ucma: Don't allow join attempts for unsupported AF family + - Linux 4.15.13 + + * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to + "always" (LP: #1753708) + - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el + + * Bionic update to 4.15.12 stable release (LP: #1757465) + - x86/cpufeatures: Add Intel Total Memory Encryption cpufeature + - x86/cpufeatures: Add Intel PCONFIG cpufeature + - selftests/x86/entry_from_vm86: Exit with 1 if we fail + - selftests/x86/entry_from_vm86: Add test cases for POPF + - x86/vm86/32: Fix POPF emulation + - x86/speculation, objtool: Annotate indirect calls/jumps for objtool on + 32-bit kernels + - x86/speculation: Remove Skylake C2 from Speculation Control microcode + blacklist + - KVM: x86: Fix device passthrough when SME is active + - x86/mm: Fix vmalloc_fault to use pXd_large + - parisc: Handle case where flush_cache_range is called with no context + - ALSA: pcm: Fix UAF in snd_pcm_oss_get_formats() + - ALSA: hda - Revert power_save option default value + - ALSA: seq: Fix possible UAF in snd_seq_check_queue() + - ALSA: seq: Clear client entry before deleting else at closing + - drm/nouveau/bl: Fix oops on driver unbind + - drm/nouveau/mmu: ALIGN_DOWN correct variable + - drm/amdgpu: fix prime teardown order + - drm/radeon: fix prime teardown order + - drm/amdgpu/dce: Don't turn off DP sink when disconnected + - fs: Teach path_connected to handle nfs filesystems with multiple roots. + - KVM: arm/arm64: Reduce verbosity of KVM init log + - KVM: arm/arm64: Reset mapped IRQs on VM reset + - kvm: arm/arm64: vgic-v3: Tighten synchronization for guests using v2 on v3 + - KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid + - lock_parent() needs to recheck if dentry got __dentry_kill'ed under it + - fs/aio: Add explicit RCU grace period when freeing kioctx + - fs/aio: Use RCU accessors for kioctx_table->table[] + - RDMAVT: Fix synchronization around percpu_ref + - irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis + - nvme: fix subsystem multiple controllers support check + - xfs: preserve i_rdev when recycling a reclaimable inode + - btrfs: Fix NULL pointer exception in find_bio_stripe + - btrfs: add missing initialization in btrfs_check_shared + - btrfs: alloc_chunk: fix DUP stripe size handling + - btrfs: Fix use-after-free when cleaning up fs_devs with a single stale + device + - btrfs: remove spurious WARN_ON(ref->count < 0) in find_parent_nodes + - btrfs: Fix memory barriers usage with device stats counters + - scsi: qla2xxx: Fix smatch warning in qla25xx_delete_{rsp|req}_que + - scsi: qla2xxx: Fix NULL pointer access for fcport structure + - scsi: qla2xxx: Fix logo flag for qlt_free_session_done() + - scsi: qla2xxx: Fix crashes in qla2x00_probe_one on probe failure + - usb: dwc2: fix STM32F7 USB OTG HS compatible + - dt-bindings: usb: fix the STM32F7 DWC2 OTG HS core binding + - USB: gadget: udc: Add missing platform_device_put() on error in + bdc_pci_probe() + - usb: dwc3: Fix GDBGFIFOSPACE_TYPE values + - usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode + - usb: dwc3: of-simple: fix oops by unbalanced clk disable call + - usb: gadget: udc: renesas_usb3: fix oops in renesas_usb3_remove() + - phy: phy-brcm-usb: Fix two DT properties to match bindings doc + - phy: phy-brcm-usb-init: Some Low Speed keyboards fail on 7271 + - phy: phy-brcm-usb-init: DRD mode can cause crash on startup + - phy: phy-brcm-usb-init: Power down USB 3.0 PHY when XHCI disabled + - Linux 4.15.12 + + * cxl: Fix timebase synchronization status on POWER9 missing (CAPI) + (LP: #1757228) + - cxl: Fix timebase synchronization status on P9 + + * [Feature][GLK] Enable L2 CDP (Code and Data Prioritization) (LP: #1737873) + - x86/intel_rdt: Enumerate L2 Code and Data Prioritization (CDP) feature + - x86/intel_rdt: Add command line parameter to control L2_CDP + + * [Feature] Crystal Ridge-Restrict DAX to configurations with struct page + (LP: #1751724) + - mm, dax: introduce pfn_t_special() + - ext2: auto disable dax instead of failing mount + - ext4: auto disable dax instead of failing mount + - dax: require 'struct page' by default for filesystem dax + - Config: Enable CONFIG_FS_DAX_LIMITED + + * Bionic update to 4.15.11 stable release (LP: #1756978) + - x86: Treat R_X86_64_PLT32 as R_X86_64_PC32 + - ASoC: sun4i-i2s: Fix RX slot number of SUN8I + - ASoC: sgtl5000: Fix suspend/resume + - ASoC: wm_adsp: For TLV controls only register TLV get/set + - ASoC: rt5651: Fix regcache sync errors on resume + - usb: host: xhci-rcar: add support for r8a77965 + - xhci: Fix front USB ports on ASUS PRIME B350M-A + - xhci: fix endpoint context tracer output + - serial: sh-sci: prevent lockup on full TTY buffers + - tty/serial: atmel: add new version check for usart + - uas: fix comparison for error code + - staging: comedi: fix comedi_nsamples_left. + - staging: android: ashmem: Fix lockdep issue during llseek + - scsi: sd_zbc: Fix potential memory leak + - USB: storage: Add JMicron bridge 152d:2567 to unusual_devs.h + - usbip: vudc: fix null pointer dereference on udc->lock + - usb: quirks: add control message delay for 1b1c:1b20 + - usb: usbmon: Read text within supplied buffer size + - usb: gadget: f_fs: Fix use-after-free in ffs_fs_kill_sb() + - usb: dwc3: Fix lock-up on ID change during system suspend/resume + - serial: 8250_pci: Add Brainboxes UC-260 4 port serial device + - serial: core: mark port as initialized in autoconfig + - earlycon: add reg-offset to physical address before mapping + - dm mpath: fix passing integrity data + - Revert "btrfs: use proper endianness accessors for super_copy" + - gfs2: Clean up {lookup,fillup}_metapath + - gfs2: Fixes to "Implement iomap for block_map" (2) + - drm/panel: rpi-touchscreen: propagate errors in rpi_touchscreen_i2c_read() + - spi: imx: Fix failure path leak on GPIO request error correctly + - HID: multitouch: Only look at non touch fields in first packet of a frame + - KVM: PPC: Book3S HV: Avoid shifts by negative amounts + - drm/edid: set ELD connector type in drm_edid_to_eld() + - dma-buf/fence: Fix lock inversion within dma-fence-array + - video/hdmi: Allow "empty" HDMI infoframes + - KVM: PPC: Book3S HV: Fix typo in kvmppc_hv_get_dirty_log_radix() + - HID: elo: clear BTN_LEFT mapping + - iwlwifi: mvm: rs: don't override the rate history in the search cycle + - ARM: dts: koelsch: Move cec_clock to root node + - clk: meson: gxbb: fix wrong clock for SARADC/SANA + - ARM: dts: exynos: Correct Trats2 panel reset line + - drm/amdgpu: fix get_max_engine_clock_in_mhz + - staging: rtl8822be: fix missing null check on dev_alloc_skb return + - typec: tcpm: fusb302: Resolve out of order messaging events + - USB: ledtrig-usbport: fix of-node leak + - dt-bindings: serial: Add common rs485 binding for RTS polarity + - sched: Stop switched_to_rt() from sending IPIs to offline CPUs + - sched: Stop resched_cpu() from sending IPIs to offline CPUs + - crypto: chelsio - Fix an error code in chcr_hash_dma_map() + - crypto: ecc - Fix NULL pointer deref. on no default_rng + - crypto: keywrap - Add missing ULL suffixes for 64-bit constants + - crypto: cavium - fix memory leak on info + - test_firmware: fix setting old custom fw path back on exit + - drm/vblank: Fix vblank timestamp debugs + - net: ieee802154: adf7242: Fix bug if defined DEBUG + - rtc: brcmstb-waketimer: fix error handling in brcmstb_waketmr_probe() + - perf report: Fix -D output for user metadata events + - net: xfrm: allow clearing socket xfrm policies. + - gpiolib: don't allow OPEN_DRAIN & OPEN_SOURCE flags simultaneously + - mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]() + - net: thunderx: Set max queue count taking XDP_TX into account + - ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin + - ARM: dts: omap3-n900: Fix the audio CODEC's reset pin + - mtd: nand: ifc: update bufnum mask for ver >= 2.0.0 + - userns: Don't fail follow_automount based on s_user_ns + - xfrm: Fix xfrm_replay_overflow_offload_esn + - leds: pm8058: Silence pointer to integer size warning + - bpf: fix stack state printing in verifier log + - power: supply: sbs-message: double left shift bug in sbsm_select() + - power: supply: ab8500_charger: Fix an error handling path + - power: supply: ab8500_charger: Bail out in case of error in + 'ab8500_charger_init_hw_registers()' + - drm/etnaviv: make THERMAL selectable + - iio: adc: ina2xx: Shift bus voltage register to mask flag bits + - iio: health: max30102: Add power enable parameter to get_temp function + - ath10k: update tdls teardown state to target + - cpufreq: Fix governor module removal race + - KVM: X86: Restart the guest when insn_len is zero and SEV is enabled + - drm/amdgpu:fix random missing of FLR NOTIFY + - scsi: ses: don't ask for diagnostic pages repeatedly during probe + - pwm: stmpe: Fix wrong register offset for hwpwm=2 case + - drm/sun4i: Fix format mask in DE2 driver + - pinctrl: sh-pfc: r8a7791: Add can_clk function + - pinctrl: sh-pfc: r8a7795-es1: Fix MOD_SEL1 bit[25:24] to 0x3 when using + STP_ISEN_1_D + - perf annotate: Fix unnecessary memory allocation for s390x + - perf annotate: Fix objdump comment parsing for Intel mov dissassembly + - iwlwifi: mvm: avoid dumping assert log when device is stopped + - drm/amdgpu:fix virtual dce bug + - drm/amdgpu: fix amdgpu_sync_resv v2 + - bnxt_en: Uninitialized variable in bnxt_tc_parse_actions() + - clk: qcom: msm8916: fix mnd_width for codec_digcodec + - mwifiex: cfg80211: do not change virtual interface during scan processing + - ath10k: fix invalid STS_CAP_OFFSET_MASK + - tools/usbip: fixes build with musl libc toolchain + - spi: sun6i: disable/unprepare clocks on remove + - bnxt_en: Don't print "Link speed -1 no longer supported" messages. + - scsi: core: scsi_get_device_flags_keyed(): Always return device flags + - scsi: devinfo: apply to HP XP the same flags as Hitachi VSP + - scsi: dh: add new rdac devices + - clk: renesas: r8a77970: Add LVDS clock + - staging: fsl-dpaa2/eth: Fix access to FAS field + - media: vsp1: Prevent suspending and resuming DRM pipelines + - dm raid: fix raid set size revalidation + - media: cpia2: Fix a couple off by one bugs + - media: davinci: vpif_capture: add NULL check on devm_kzalloc return value + - virtio_net: Disable interrupts if napi_complete_done rescheduled napi + - net: sched: drop qdisc_reset from dev_graft_qdisc + - veth: set peer GSO values + - drm/amdkfd: Fix memory leaks in kfd topology + - powerpc/64: Don't trace irqs-off at interrupt return to soft-disabled + context + - arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset + - agp/intel: Flush all chipset writes after updating the GGTT + - mac80211_hwsim: enforce PS_MANUAL_POLL to be set after PS_ENABLED + - mac80211: remove BUG() when interface type is invalid + - crypto: caam/qi - use correct print specifier for size_t + - ASoC: nuc900: Fix a loop timeout test + - mmc: mmc_test: Ensure command queue is disabled for testing + - Fix misannotated out-of-line _copy_to_user() + - ipvlan: add L2 check for packets arriving via virtual devices + - rcutorture/configinit: Fix build directory error message + - locking/locktorture: Fix num reader/writer corner cases + - ima: relax requiring a file signature for new files with zero length + - IB/mlx5: revisit -Wmaybe-uninitialized warning + - dmaengine: qcom_hidma: check pending interrupts + - drm/i915/glk: Disable Guc and HuC on GLK + - Linux 4.15.11 + - Config: Enable CONFIG_DRM_ETNAVIV_THERMAL=y + + * [FFE][Feature] KVM CLX avx512_vnni (LP: #1739665) + - KVM: x86: add support for UMIP + - KVM: Expose new cpu features to guest + + * Ubuntu18.04[P9 DD2.2 Boston]:Unable to boot power8 compat mode + guests(ubuntu14.04.5) (kvm) (LP: #1756254) + - KVM: PPC: Book3S HV: Allow HPT and radix on the same core for POWER9 v2.2 + + * Allow hugepage backing for "p8compat" mode kvm guests (LP: #1754206) + - KVM: PPC: Book3S HV: Fix VRMA initialization with 2MB or 1GB memory backing + + * [Bug][KVM][Crystal Ridge] Terrible performance of vNVDIMM on QEMU with + device DAX backend (LP: #1745899) + - x86/mm: add a function to check if a pfn is UC/UC-/WC + - KVM: MMU: consider host cache mode in MMIO page check + + * nfp: read ME frequency from vNIC ctrl memory (LP: #1752818) + - nfp: add TLV capabilities to the BAR + - nfp: read ME frequency from vNIC ctrl memory + - nfp: fix TLV offset calculation + + * Miscellaneous Ubuntu changes + - [Packaging] skip cloud tools packaging when not building package + - [Packaging] final-checks -- remove check for empty retpoline files + + -- Thadeu Lima de Souza Cascardo Mon, 02 Apr 2018 15:43:20 -0300 + +linux (4.15.0-13.14) bionic; urgency=medium + + * linux: 4.15.0-13.14 -proposed tracker (LP: #1756408) + + * devpts: handle bind-mounts (LP: #1755857) + - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC + - SAUCE: devpts: resolve devpts bind-mounts + - SAUCE: devpts: comment devpts_mntget() + - SAUCE: selftests: add devpts selftests + + * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103) + - d-i: add hisi_sas_v3_hw to scsi-modules + + * [Bionic][ARM64] enable ROCE and HNS3 driver support for hip08 SoC + (LP: #1756097) + - RDMA/hns: Refactor eq code for hip06 + - RDMA/hns: Add eq support of hip08 + - RDMA/hns: Add detailed comments for mb() call + - RDMA/hns: Add rq inline data support for hip08 RoCE + - RDMA/hns: Update the usage of sr_max and rr_max field + - RDMA/hns: Set access flags of hip08 RoCE + - RDMA/hns: Filter for zero length of sge in hip08 kernel mode + - RDMA/hns: Fix QP state judgement before sending work requests + - RDMA/hns: Assign dest_qp when deregistering mr + - RDMA/hns: Fix endian problems around imm_data and rkey + - RDMA/hns: Assign the correct value for tx_cqn + - RDMA/hns: Create gsi qp in hip08 + - RDMA/hns: Add gsi qp support for modifying qp in hip08 + - RDMA/hns: Fill sq wqe context of ud type in hip08 + - RDMA/hns: Assign zero for pkey_index of wc in hip08 + - RDMA/hns: Update the verbs of polling for completion + - RDMA/hns: Set the guid for hip08 RoCE device + - net: hns3: Refactor of the reset interrupt handling logic + - net: hns3: Add reset service task for handling reset requests + - net: hns3: Refactors the requested reset & pending reset handling code + - net: hns3: Add HNS3 VF IMP(Integrated Management Proc) cmd interface + - net: hns3: Add mailbox support to VF driver + - net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support + - net: hns3: Add HNS3 VF driver to kernel build framework + - net: hns3: Unified HNS3 {VF|PF} Ethernet Driver for hip08 SoC + - net: hns3: Add mailbox support to PF driver + - net: hns3: Change PF to add ring-vect binding & resetQ to mailbox + - net: hns3: Add mailbox interrupt handling to PF driver + - net: hns3: add support to query tqps number + - net: hns3: add support to modify tqps number + - net: hns3: change the returned tqp number by ethtool -x + - net: hns3: free the ring_data structrue when change tqps + - net: hns3: get rss_size_max from configuration but not hardcode + - net: hns3: add a mask initialization for mac_vlan table + - net: hns3: add vlan offload config command + - net: hns3: add ethtool related offload command + - net: hns3: add handling vlan tag offload in bd + - net: hns3: cleanup mac auto-negotiation state query + - net: hns3: fix for getting auto-negotiation state in hclge_get_autoneg + - net: hns3: add support for set_pauseparam + - net: hns3: add support to update flow control settings after autoneg + - net: hns3: add Asym Pause support to phy default features + - net: hns3: add support for querying advertised pause frame by ethtool ethx + - net: hns3: Increase the default depth of bucket for TM shaper + - net: hns3: change TM sched mode to TC-based mode when SRIOV enabled + - net: hns3: hns3_get_channels() can be static + - net: hns3: Add ethtool interface for vlan filter + - net: hns3: Disable VFs change rxvlan offload status + - net: hns3: Unify the strings display of packet statistics + - net: hns3: Fix spelling errors + - net: hns3: Remove repeat statistic of rx_errors + - net: hns3: Modify the update period of packet statistics + - net: hns3: Mask the packet statistics query when NIC is down + - net: hns3: Fix an error of total drop packet statistics + - net: hns3: Fix a loop index error of tqp statistics query + - net: hns3: Fix an error macro definition of HNS3_TQP_STAT + - net: hns3: Remove a useless member of struct hns3_stats + - net: hns3: Add packet statistics of netdev + - net: hns3: Fix a response data read error of tqp statistics query + - net: hns3: fix for updating fc_mode_last_time + - net: hns3: fix for setting MTU + - net: hns3: fix for changing MTU + - net: hns3: add MTU initialization for hardware + - net: hns3: fix for not setting pause parameters + - net: hns3: remove redundant semicolon + - net: hns3: Add more packet size statisctics + - Revert "net: hns3: Add packet statistics of netdev" + - net: hns3: report the function type the same line with hns3_nic_get_stats64 + - net: hns3: add ethtool_ops.get_channels support for VF + - net: hns3: remove TSO config command from VF driver + - net: hns3: add ethtool_ops.get_coalesce support to PF + - net: hns3: add ethtool_ops.set_coalesce support to PF + - net: hns3: refactor interrupt coalescing init function + - net: hns3: refactor GL update function + - net: hns3: remove unused GL setup function + - net: hns3: change the unit of GL value macro + - net: hns3: add int_gl_idx setup for TX and RX queues + - net: hns3: add feature check when feature changed + - net: hns3: check for NULL function pointer in hns3_nic_set_features + - net: hns: Fix for variable may be used uninitialized warnings + - net: hns3: add support for get_regs + - net: hns3: add manager table initialization for hardware + - net: hns3: add ethtool -p support for fiber port + - net: hns3: add net status led support for fiber port + - net: hns3: converting spaces into tabs to avoid checkpatch.pl warning + - net: hns3: add get/set_coalesce support to VF + - net: hns3: add int_gl_idx setup for VF + - [Config]: enable CONFIG_HNS3_HCLGEVF as module. + + * [Bionic][ARM64] add RAS extension and SDEI features (LP: #1756096) + - KVM: arm64: Store vcpu on the stack during __guest_enter() + - KVM: arm/arm64: Convert kvm_host_cpu_state to a static per-cpu allocation + - KVM: arm64: Change hyp_panic()s dependency on tpidr_el2 + - arm64: alternatives: use tpidr_el2 on VHE hosts + - KVM: arm64: Stop save/restoring host tpidr_el1 on VHE + - Docs: dt: add devicetree binding for describing arm64 SDEI firmware + - firmware: arm_sdei: Add driver for Software Delegated Exceptions + - arm64: Add vmap_stack header file + - arm64: uaccess: Add PAN helper + - arm64: kernel: Add arch-specific SDEI entry code and CPU masking + - firmware: arm_sdei: Add support for CPU and system power states + - firmware: arm_sdei: add support for CPU private events + - arm64: acpi: Remove __init from acpi_psci_use_hvc() for use by SDEI + - firmware: arm_sdei: Discover SDEI support via ACPI + - arm64: sysreg: Move to use definitions for all the SCTLR bits + - arm64: cpufeature: Detect CPU RAS Extentions + - arm64: kernel: Survive corrected RAS errors notified by SError + - arm64: Unconditionally enable IESB on exception entry/return for firmware- + first + - arm64: kernel: Prepare for a DISR user + - KVM: arm/arm64: mask/unmask daif around VHE guests + - KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2. + - KVM: arm64: Save/Restore guest DISR_EL1 + - KVM: arm64: Save ESR_EL2 on guest SError + - KVM: arm64: Handle RAS SErrors from EL1 on guest exit + - KVM: arm64: Handle RAS SErrors from EL2 on guest exit + - KVM: arm64: Emulate RAS error registers and set HCR_EL2's TERR & TEA + - [Config]: enable RAS_EXTN and ARM_SDE_INTERFACE + + * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094) + - scsi: hisi_sas: fix dma_unmap_sg() parameter + - scsi: ata: enhance the definition of SET MAX feature field value + - scsi: hisi_sas: relocate clearing ITCT and freeing device + - scsi: hisi_sas: optimise port id refresh function + - scsi: hisi_sas: some optimizations of host controller reset + - scsi: hisi_sas: modify hisi_sas_dev_gone() for reset + - scsi: hisi_sas: add an mechanism to do reset work synchronously + - scsi: hisi_sas: change ncq process for v3 hw + - scsi: hisi_sas: add RAS feature for v3 hw + - scsi: hisi_sas: add some print to enhance debugging + - scsi: hisi_sas: improve int_chnl_int_v2_hw() consistency with v3 hw + - scsi: hisi_sas: add v2 hw port AXI error handling support + - scsi: hisi_sas: use an general way to delay PHY work + - scsi: hisi_sas: do link reset for some CHL_INT2 ints + - scsi: hisi_sas: judge result of internal abort + - scsi: hisi_sas: add internal abort dev in some places + - scsi: hisi_sas: fix SAS_QUEUE_FULL problem while running IO + - scsi: hisi_sas: re-add the lldd_port_deformed() + - scsi: hisi_sas: add v3 hw suspend and resume + - scsi: hisi_sas: Change frame type for SET MAX commands + - scsi: hisi_sas: make local symbol host_attrs static + - scsi: hisi_sas: fix a bug in hisi_sas_dev_gone() + - SAUCE: scsi: hisi_sas: config for hip08 ES + - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace + - PM / core: Add LEAVE_SUSPENDED driver flag + - PCI / PM: Support for LEAVE_SUSPENDED driver flag + - PCI/AER: Skip recovery callbacks for correctable errors from ACPI APEI + - PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics + - PCI/ASPM: Enable Latency Tolerance Reporting when supported + - PCI/ASPM: Unexport internal ASPM interfaces + - PCI: Make PCI_SCAN_ALL_PCIE_DEVS work for Root as well as Downstream Ports + - PCI/AER: Return error if AER is not supported + - PCI/DPC: Enable DPC only if AER is available + + * [CVE] Spectre: System Z {kernel} UBUNTU18.04 (LP: #1754580) + - s390: scrub registers on kernel entry and KVM exit + - s390: add optimized array_index_mask_nospec + - s390/alternative: use a copy of the facility bit mask + - s390: add options to change branch prediction behaviour for the kernel + - s390: run user space and KVM guests with modified branch prediction + - s390: introduce execute-trampolines for branches + - s390: Replace IS_ENABLED(EXPOLINE_*) with IS_ENABLED(CONFIG_EXPOLINE_*) + - s390: do not bypass BPENTER for interrupt system calls + - s390/entry.S: fix spurious zeroing of r0 + + * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424) + - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove. + + * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug + fixes (LP: #1752182) + - scsi: lpfc: FLOGI failures are reported when connected to a private loop. + - scsi: lpfc: Expand WQE capability of every NVME hardware queue + - scsi: lpfc: Handle XRI_ABORTED_CQE in soft IRQ + - scsi: lpfc: Fix NVME LS abort_xri + - scsi: lpfc: Raise maximum NVME sg list size for 256 elements + - scsi: lpfc: Driver fails to detect direct attach storage array + - scsi: lpfc: Fix display for debugfs queInfo + - scsi: lpfc: Adjust default value of lpfc_nvmet_mrq + - scsi: lpfc: Fix ndlp ref count for pt2pt mode issue RSCN + - scsi: lpfc: Linux LPFC driver does not process all RSCNs + - scsi: lpfc: correct port registrations with nvme_fc + - scsi: lpfc: Correct driver deregistrations with host nvme transport + - scsi: lpfc: Fix crash during driver unload with running nvme traffic + - scsi: lpfc: Fix driver handling of nvme resources during unload + - scsi: lpfc: small sg cnt cleanup + - scsi: lpfc: Fix random heartbeat timeouts during heavy IO + - scsi: lpfc: update driver version to 11.4.0.5 + - scsi: lpfc: Fix -EOVERFLOW behavior for NVMET and defer_rcv + - scsi: lpfc: Fix receive PRLI handling + - scsi: lpfc: Increase SCSI CQ and WQ sizes. + - scsi: lpfc: Fix SCSI LUN discovery when SCSI and NVME enabled + - scsi: lpfc: Fix issues connecting with nvme initiator + - scsi: lpfc: Fix infinite wait when driver unregisters a remote NVME port. + - scsi: lpfc: Beef up stat counters for debug + - scsi: lpfc: update driver version to 11.4.0.6 + - scsi: lpfc: correct sg_seg_cnt attribute min vs default + - scsi: scsi_transport_fc: fix typos on 64/128 GBit define names + - scsi: lpfc: don't dereference localport before it has been null checked + - scsi: lpfc: fix a couple of minor indentation issues + - treewide: Use DEVICE_ATTR_RW + - treewide: Use DEVICE_ATTR_RO + - treewide: Use DEVICE_ATTR_WO + - scsi: lpfc: Fix frequency of Release WQE CQEs + - scsi: lpfc: Increase CQ and WQ sizes for SCSI + - scsi: lpfc: move placement of target destroy on driver detach + - scsi: lpfc: correct debug counters for abort + - scsi: lpfc: Add WQ Full Logic for NVME Target + - scsi: lpfc: Fix PRLI handling when topology type changes + - scsi: lpfc: Fix IO failure during hba reset testing with nvme io. + - scsi: lpfc: Fix RQ empty firmware trap + - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target + - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing + - scsi: lpfc: Fix issue_lip if link is disabled + - scsi: lpfc: Indicate CONF support in NVMe PRLI + - scsi: lpfc: Fix SCSI io host reset causing kernel crash + - scsi: lpfc: Validate adapter support for SRIU option + - scsi: lpfc: Fix header inclusion in lpfc_nvmet + - scsi: lpfc: Treat SCSI Write operation Underruns as an error + - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap. + - scsi: lpfc: update driver version to 11.4.0.7 + - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright + - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers + - scsi: lpfc: Rework sli4 doorbell infrastructure + - scsi: lpfc: Add SLI-4 if_type=6 support to the code base + - scsi: lpfc: Add push-to-adapter support to sli4 + - scsi: lpfc: Add PCI Ids for if_type=6 hardware + - scsi: lpfc: Add 64G link speed support + - scsi: lpfc: Add if_type=6 support for cycling valid bits + - scsi: lpfc: Enable fw download on if_type=6 devices + - scsi: lpfc: Add embedded data pointers for enhanced performance + - scsi: lpfc: Fix nvme embedded io length on new hardware + - scsi: lpfc: Work around NVME cmd iu SGL type + - scsi: lpfc: update driver version to 12.0.0.0 + - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018 + - scsi: lpfc: use __raw_writeX on DPP copies + - scsi: lpfc: Add missing unlock in WQ full logic + + * CVE-2018-8043 + - net: phy: mdio-bcm-unimac: fix potential NULL dereference in + unimac_mdio_probe() + + * Bionic update to 4.15.10 stable release (LP: #1756100) + - Revert "UBUNTU: SAUCE: ALSA: hda/realtek - Add support headset mode for DELL + WYSE" + - RDMA/ucma: Limit possible option size + - RDMA/ucma: Check that user doesn't overflow QP state + - RDMA/mlx5: Fix integer overflow while resizing CQ + - bpf: cpumap: use GFP_KERNEL instead of GFP_ATOMIC in __cpu_map_entry_alloc() + - IB/uverbs: Improve lockdep_check + - mac80211_hwsim: don't use WQ_MEM_RECLAIM + - net/smc: fix NULL pointer dereference on sock_create_kern() error path + - regulator: stm32-vrefbuf: fix check on ready flag + - drm/i915: Check for fused or unused pipes + - drm/i915/audio: fix check for av_enc_map overflow + - drm/i915: Fix rsvd2 mask when out-fence is returned + - drm/i915: Clear the in-use marker on execbuf failure + - drm/i915: Disable DC states around GMBUS on GLK + - drm/i915: Update watermark state correctly in sanitize_watermarks + - drm/i915: Try EDID bitbanging on HDMI after failed read + - drm/i915/perf: fix perf stream opening lock + - scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops + - scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS + - drm/i915: Always call to intel_display_set_init_power() in resume_early. + - workqueue: Allow retrieval of current task's work struct + - drm: Allow determining if current task is output poll worker + - drm/nouveau: Fix deadlock on runtime suspend + - drm/radeon: Fix deadlock on runtime suspend + - drm/amdgpu: Fix deadlock on runtime suspend + - drm/nouveau: prefer XBGR2101010 for addfb ioctl + - drm/amd/powerplay/smu7: allow mclk switching with no displays + - drm/amd/powerplay/vega10: allow mclk switching with no displays + - Revert "drm/radeon/pm: autoswitch power state when in balanced mode" + - drm/amd/display: check for ipp before calling cursor operations + - drm/radeon: insist on 32-bit DMA for Cedar on PPC64/PPC64LE + - drm/amd/powerplay: fix power over limit on Fiji + - drm/amd/display: Default HDMI6G support to true. Log VBIOS table error. + - drm/amdgpu: used cached pcie gen info for SI (v2) + - drm/amdgpu: Notify sbios device ready before send request + - drm/radeon: fix KV harvesting + - drm/amdgpu: fix KV harvesting + - drm/amdgpu:Correct max uvd handles + - drm/amdgpu:Always save uvd vcpu_bo in VM Mode + - ovl: redirect_dir=nofollow should not follow redirect for opaque lower + - MIPS: BMIPS: Do not mask IPIs during suspend + - MIPS: ath25: Check for kzalloc allocation failure + - MIPS: OCTEON: irq: Check for null return on kzalloc allocation + - PCI: dwc: Fix enumeration end when reaching root subordinate + - Input: matrix_keypad - fix race when disabling interrupts + - Revert "Input: synaptics - Lenovo Thinkpad T460p devices should use RMI" + - bug: use %pB in BUG and stack protector failure + - lib/bug.c: exclude non-BUG/WARN exceptions from report_bug() + - mm/memblock.c: hardcode the end_pfn being -1 + - Documentation/sphinx: Fix Directive import error + - loop: Fix lost writes caused by missing flag + - virtio_ring: fix num_free handling in error case + - KVM: s390: fix memory overwrites when not using SCA entries + - arm64: mm: fix thinko in non-global page table attribute check + - IB/core: Fix missing RDMA cgroups release in case of failure to register + device + - Revert "nvme: create 'slaves' and 'holders' entries for hidden controllers" + - kbuild: Handle builtin dtb file names containing hyphens + - dm bufio: avoid false-positive Wmaybe-uninitialized warning + - IB/mlx5: Fix incorrect size of klms in the memory region + - bcache: fix crashes in duplicate cache device register + - bcache: don't attach backing with duplicate UUID + - x86/MCE: Save microcode revision in machine check records + - x86/MCE: Serialize sysfs changes + - perf tools: Fix trigger class trigger_on() + - x86/spectre_v2: Don't check microcode versions when running under + hypervisors + - ALSA: hda/realtek - Add support headset mode for DELL WYSE + - ALSA: hda/realtek - Add headset mode support for Dell laptop + - ALSA: hda/realtek: Limit mic boost on T480 + - ALSA: hda/realtek - Fix dock line-out volume on Dell Precision 7520 + - ALSA: hda/realtek - Make dock sound work on ThinkPad L570 + - ALSA: seq: More protection for concurrent write and ioctl races + - ALSA: hda: add dock and led support for HP EliteBook 820 G3 + - ALSA: hda: add dock and led support for HP ProBook 640 G2 + - scsi: qla2xxx: Fix NULL pointer crash due to probe failure + - scsi: qla2xxx: Fix recursion while sending terminate exchange + - dt-bindings: Document mti,mips-cpc binding + - MIPS: CPC: Map registers using DT in mips_cpc_default_phys_base() + - nospec: Kill array_index_nospec_mask_check() + - nospec: Include dependency + - x86/entry: Reduce the code footprint of the 'idtentry' macro + - x86/entry/64: Use 'xorl' for faster register clearing + - x86/mm: Remove stale comment about KMEMCHECK + - x86/asm: Improve how GEN_*_SUFFIXED_RMWcc() specify clobbers + - x86/IO-APIC: Avoid warning in 32-bit builds + - x86/LDT: Avoid warning in 32-bit builds with older gcc + - x86-64/realmode: Add instruction suffix + - Revert "x86/retpoline: Simplify vmexit_fill_RSB()" + - x86/speculation: Use IBRS if available before calling into firmware + - x86/retpoline: Support retpoline builds with Clang + - x86/speculation, objtool: Annotate indirect calls/jumps for objtool + - x86/speculation: Move firmware_restrict_branch_speculation_*() from C to CPP + - x86/paravirt, objtool: Annotate indirect calls + - x86/boot, objtool: Annotate indirect jump in secondary_startup_64() + - x86/mm/sme, objtool: Annotate indirect call in sme_encrypt_execute() + - objtool: Use existing global variables for options + - objtool: Add retpoline validation + - objtool: Add module specific retpoline rules + - objtool, retpolines: Integrate objtool with retpoline support more closely + - objtool: Fix another switch table detection issue + - objtool: Fix 32-bit build + - x86/kprobes: Fix kernel crash when probing .entry_trampoline code + - watchdog: hpwdt: SMBIOS check + - watchdog: hpwdt: Check source of NMI + - watchdog: hpwdt: fix unused variable warning + - watchdog: hpwdt: Remove legacy NMI sourcing. + - netfilter: add back stackpointer size checks + - netfilter: ipt_CLUSTERIP: fix a race condition of proc file creation + - netfilter: xt_hashlimit: fix lock imbalance + - netfilter: x_tables: fix missing timer initialization in xt_LED + - netfilter: nat: cope with negative port range + - netfilter: IDLETIMER: be syzkaller friendly + - netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets + - netfilter: bridge: ebt_among: add missing match size checks + - netfilter: ipv6: fix use-after-free Write in nf_nat_ipv6_manip_pkt + - netfilter: use skb_to_full_sk in ip6_route_me_harder + - tpm_tis: Move ilb_base_addr to tpm_tis_data + - tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd() + - tpm: delete the TPM_TIS_CLK_ENABLE flag + - tpm: remove unused variables + - tpm: only attempt to disable the LPC CLKRUN if is already enabled + - x86/xen: Calculate __max_logical_packages on PV domains + - scsi: qla2xxx: Fix system crash for Notify ack timeout handling + - scsi: qla2xxx: Fix gpnid error processing + - scsi: qla2xxx: Move session delete to driver work queue + - scsi: qla2xxx: Skip IRQ affinity for Target QPairs + - scsi: qla2xxx: Fix re-login for Nport Handle in use + - scsi: qla2xxx: Retry switch command on time out + - scsi: qla2xxx: Serialize GPNID for multiple RSCN + - scsi: qla2xxx: Fix login state machine stuck at GPDB + - scsi: qla2xxx: Fix NPIV host cleanup in target mode + - scsi: qla2xxx: Relogin to target port on a cable swap + - scsi: qla2xxx: Fix Relogin being triggered too fast + - scsi: qla2xxx: Fix PRLI state check + - scsi: qla2xxx: Fix abort command deadlock due to spinlock + - scsi: qla2xxx: Replace fcport alloc with qla2x00_alloc_fcport + - scsi: qla2xxx: Fix scan state field for fcport + - scsi: qla2xxx: Clear loop id after delete + - scsi: qla2xxx: Defer processing of GS IOCB calls + - scsi: qla2xxx: Remove aborting ELS IOCB call issued as part of timeout. + - scsi: qla2xxx: Fix system crash in qlt_plogi_ack_unref + - scsi: qla2xxx: Fix memory leak in dual/target mode + - NFS: Fix an incorrect type in struct nfs_direct_req + - pNFS: Prevent the layout header refcount going to zero in pnfs_roc() + - NFS: Fix unstable write completion + - Linux 4.15.10 + + * Bionic update to 4.15.10 stable release (LP: #1756100) // CVE-2018-1000004. + - ALSA: seq: Don't allow resizing pool in use + + * nfp: prioritize stats updates (LP: #1752061) + - nfp: flower: prioritize stats updates + + * Ubuntu 18.04 - Kernel crash on nvme subsystem-reset /dev/nvme0 (Bolt / NVMe) + (LP: #1753371) + - nvme-pci: Fix EEH failure on ppc + + * sbsa watchdog crashes thunderx2 system (LP: #1755595) + - watchdog: sbsa: use 32-bit read for WCV + + * KVM: s390: add vcpu stat counters for many instruction (LP: #1755132) + - KVM: s390: diagnoses are instructions as well + - KVM: s390: add vcpu stat counters for many instruction + + * CIFS SMB2/SMB3 does not work for domain based DFS (LP: #1747572) + - CIFS: make IPC a regular tcon + - CIFS: use tcon_ipc instead of use_ipc parameter of SMB2_ioctl + - CIFS: dump IPC tcon in debug proc file + + * i2c-thunderx: erroneous error message "unhandled state: 0" (LP: #1754076) + - i2c: octeon: Prevent error message on bus error + + * Boston-LC:bos1u1: Stress test on Qlogic Fibre Channel on Ubuntu KVM guest + that caused KVM host crashed in qlt_free_session_done call (LP: #1750441) + - scsi: qla2xxx: Fix memory corruption during hba reset test + + * Ubuntu 18.04 - Performance: Radix page fault handler bug in KVM + (LP: #1752236) + - KVM: PPC: Book3S HV: Fix handling of large pages in radix page fault handler + + * Fix ARC hit rate (LP: #1755158) + - SAUCE: Fix ARC hit rate (LP: #1755158) + + * Bionic update to 4.15.9 stable release (LP: #1755275) + - bpf: fix mlock precharge on arraymaps + - bpf: fix memory leak in lpm_trie map_free callback function + - bpf: fix rcu lockdep warning for lpm_trie map_free callback + - bpf, x64: implement retpoline for tail call + - bpf, arm64: fix out of bounds access in tail call + - bpf: add schedule points in percpu arrays management + - bpf: allow xadd only on aligned memory + - bpf, ppc64: fix out of bounds access in tail call + - scsi: mpt3sas: fix oops in error handlers after shutdown/unload + - scsi: mpt3sas: wait for and flush running commands on shutdown/unload + - KVM: x86: fix backward migration with async_PF + - Linux 4.15.9 + + * Bionic update to 4.15.8 stable release (LP: #1755179) + - hrtimer: Ensure POSIX compliance (relative CLOCK_REALTIME hrtimers) + - ipmi_si: Fix error handling of platform device + - platform/x86: dell-laptop: Allocate buffer on heap rather than globally + - powerpc/pseries: Enable RAS hotplug events later + - Bluetooth: btusb: Use DMI matching for QCA reset_resume quirking + - ixgbe: fix crash in build_skb Rx code path + - tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the + bus + - tpm: fix potential buffer overruns caused by bit glitches on the bus + - tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on + the bus + - tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the + bus + - tpm_tis: fix potential buffer overruns caused by bit glitches on the bus + - ALSA: usb-audio: Add a quirck for B&W PX headphones + - ALSA: control: Fix memory corruption risk in snd_ctl_elem_read + - ALSA: x86: Fix missing spinlock and mutex initializations + - ALSA: hda: Add a power_save blacklist + - ALSA: hda - Fix pincfg at resume on Lenovo T470 dock + - mmc: sdhci-pci: Fix S0i3 for Intel BYT-based controllers + - mmc: dw_mmc-k3: Fix out-of-bounds access through DT alias + - mmc: dw_mmc: Avoid accessing registers in runtime suspended state + - mmc: dw_mmc: Factor out dw_mci_init_slot_caps + - mmc: dw_mmc: Fix out-of-bounds access for slot's caps + - timers: Forward timer base before migrating timers + - parisc: Use cr16 interval timers unconditionally on qemu + - parisc: Reduce irq overhead when run in qemu + - parisc: Fix ordering of cache and TLB flushes + - parisc: Hide virtual kernel memory layout + - btrfs: use proper endianness accessors for super_copy + - block: fix the count of PGPGOUT for WRITE_SAME + - block: kyber: fix domain token leak during requeue + - block: pass inclusive 'lend' parameter to truncate_inode_pages_range + - vfio: disable filesystem-dax page pinning + - cpufreq: s3c24xx: Fix broken s3c_cpufreq_init() + - dax: fix vma_is_fsdax() helper + - direct-io: Fix sleep in atomic due to sync AIO + - x86/xen: Zero MSR_IA32_SPEC_CTRL before suspend + - x86/platform/intel-mid: Handle Intel Edison reboot correctly + - x86/cpu_entry_area: Sync cpu_entry_area to initial_page_table + - bridge: check brport attr show in brport_show + - fib_semantics: Don't match route with mismatching tclassid + - hdlc_ppp: carrier detect ok, don't turn off negotiation + - ipv6 sit: work around bogus gcc-8 -Wrestrict warning + - net: amd-xgbe: fix comparison to bitshift when dealing with a mask + - net: ethernet: ti: cpsw: fix net watchdog timeout + - net: fix race on decreasing number of TX queues + - net: ipv4: don't allow setting net.ipv4.route.min_pmtu below 68 + - netlink: ensure to loop over all netns in genlmsg_multicast_allns() + - net: sched: report if filter is too large to dump + - ppp: prevent unregistered channels from connecting to PPP units + - sctp: verify size of a new chunk in _sctp_make_chunk() + - udplite: fix partial checksum initialization + - net/mlx5e: Fix TCP checksum in LRO buffers + - sctp: fix dst refcnt leak in sctp_v4_get_dst + - mlxsw: spectrum_switchdev: Check success of FDB add operation + - net/mlx5e: Specify numa node when allocating drop rq + - net: phy: fix phy_start to consider PHY_IGNORE_INTERRUPT + - tcp: Honor the eor bit in tcp_mtu_probe + - rxrpc: Fix send in rxrpc_send_data_packet() + - tcp_bbr: better deal with suboptimal GSO + - doc: Change the min default value of tcp_wmem/tcp_rmem. + - net/mlx5e: Fix loopback self test when GRO is off + - net_sched: gen_estimator: fix broken estimators based on percpu stats + - net/sched: cls_u32: fix cls_u32 on filter replace + - sctp: do not pr_err for the duplicated node in transport rhlist + - mlxsw: spectrum_router: Fix error path in mlxsw_sp_vr_create + - net: ipv4: Set addr_type in hash_keys for forwarded case + - sctp: fix dst refcnt leak in sctp_v6_get_dst() + - bridge: Fix VLAN reference count problem + - net/mlx5e: Verify inline header size do not exceed SKB linear size + - tls: Use correct sk->sk_prot for IPV6 + - amd-xgbe: Restore PCI interrupt enablement setting on resume + - cls_u32: fix use after free in u32_destroy_key() + - mlxsw: spectrum_router: Do not unconditionally clear route offload + indication + - netlink: put module reference if dump start fails + - tcp: purge write queue upon RST + - tuntap: correctly add the missing XDP flush + - tuntap: disable preemption during XDP processing + - virtio-net: disable NAPI only when enabled during XDP set + - cxgb4: fix trailing zero in CIM LA dump + - net/mlx5: Fix error handling when adding flow rules + - net: phy: Restore phy_resume() locking assumption + - tcp: tracepoint: only call trace_tcp_send_reset with full socket + - l2tp: don't use inet_shutdown on tunnel destroy + - l2tp: don't use inet_shutdown on ppp session destroy + - l2tp: fix races with tunnel socket close + - l2tp: fix race in pppol2tp_release with session object destroy + - l2tp: fix tunnel lookup use-after-free race + - s390/qeth: fix underestimated count of buffer elements + - s390/qeth: fix SETIP command handling + - s390/qeth: fix overestimated count of buffer elements + - s390/qeth: fix IP removal on offline cards + - s390/qeth: fix double-free on IP add/remove race + - Revert "s390/qeth: fix using of ref counter for rxip addresses" + - s390/qeth: fix IP address lookup for L3 devices + - s390/qeth: fix IPA command submission race + - tcp: revert F-RTO middle-box workaround + - tcp: revert F-RTO extension to detect more spurious timeouts + - blk-mq: don't call io sched's .requeue_request when requeueing rq to + ->dispatch + - media: m88ds3103: don't call a non-initalized function + - EDAC, sb_edac: Fix out of bound writes during DIMM configuration on KNL + - KVM: s390: take care of clock-comparator sign control + - KVM: s390: provide only a single function for setting the tod (fix SCK) + - KVM: s390: consider epoch index on hotplugged CPUs + - KVM: s390: consider epoch index on TOD clock syncs + - nospec: Allow index argument to have const-qualified type + - x86/mm: Fix {pmd,pud}_{set,clear}_flags() + - ARM: orion: fix orion_ge00_switch_board_info initialization + - ARM: dts: rockchip: Remove 1.8 GHz operation point from phycore som + - ARM: mvebu: Fix broken PL310_ERRATA_753970 selects + - ARM: kvm: fix building with gcc-8 + - KVM: X86: Fix SMRAM accessing even if VM is shutdown + - KVM: mmu: Fix overlap between public and private memslots + - KVM/x86: Remove indirect MSR op calls from SPEC_CTRL + - KVM: x86: move LAPIC initialization after VMCS creation + - KVM/VMX: Optimize vmx_vcpu_run() and svm_vcpu_run() by marking the RDMSR + path as unlikely() + - KVM: x86: fix vcpu initialization with userspace lapic + - KVM/x86: remove WARN_ON() for when vm_munmap() fails + - ACPI / bus: Parse tables as term_list for Dell XPS 9570 and Precision M5530 + - ARM: dts: LogicPD SOM-LV: Fix I2C1 pinmux + - ARM: dts: LogicPD Torpedo: Fix I2C1 pinmux + - powerpc/64s/radix: Boot-time NULL pointer protection using a guard-PID + - md: only allow remove_and_add_spares when no sync_thread running. + - platform/x86: dell-laptop: fix kbd_get_state's request value + - Linux 4.15.8 + + * ZFS setgid broken on 0.7 (LP: #1753288) + - SAUCE: Fix ZFS setgid + + * /proc/kallsyms prints "(null)" for null addresses in 4.15 (LP: #1754297) + - vsprintf: avoid misleading "(null)" for %px + + * Miscellaneous Ubuntu changes + - d-i: Add netsec to nic-modules + - [Config] fix up retpoline abi files + - [Config] set NOBP and expoline options for s390 + + -- Thadeu Lima de Souza Cascardo Fri, 16 Mar 2018 14:49:27 -0300 + +linux (4.15.0-12.13) bionic; urgency=medium + + * linux: 4.15.0-12.13 -proposed tracker (LP: #1754059) + + * CONFIG_EFI=y on armhf (LP: #1726362) + - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings + + * ppc64el: Support firmware disable of RFI flush (LP: #1751994) + - powerpc/pseries: Support firmware disable of RFI flush + - powerpc/powernv: Support firmware disable of RFI flush + + * [Feature] CFL/CNL (PCH:CNP-H): New GPIO Commit added (GPIO Driver needed) + (LP: #1751714) + - gpio / ACPI: Drop unnecessary ACPI GPIO to Linux GPIO translation + - pinctrl: intel: Allow custom GPIO base for pad groups + - pinctrl: cannonlake: Align GPIO number space with Windows + + * [Feature] Add xHCI debug device support in the driver (LP: #1730832) + - usb: xhci: Make some static functions global + - usb: xhci: Add DbC support in xHCI driver + - [Config] USB_XHCI_DBGCAP=y for commit mainline dfba2174dc42. + + * [SRU] Lenovo E41 Mic mute hotkey is not responding (LP: #1753347) + - platform/x86: ideapad-laptop: Increase timeout to wait for EC answer + + * headset mic can't be detected on two Dell machines (LP: #1748807) + - ALSA: hda - Fix a wrong FIXUP for alc289 on Dell machines + + * hisi_sas: Add disk LED support (LP: #1752695) + - scsi: hisi_sas: directly attached disk LED feature for v2 hw + + * [Feature] [Graphics]Whiskey Lake (Coffelake-U 4+2) new PCI Device ID adds + (LP: #1742561) + - drm/i915/cfl: Adding more Coffee Lake PCI IDs. + + * [Bug] [USB Function][CFL-CNL PCH]Stall Error and USB Transaction Error in + trace, Disable of device-initiated U1/U2 failed and rebind failed: -517 + during suspend/resume with usb storage. (LP: #1730599) + - usb: Don't print a warning if interface driver rebind is deferred at resume + + * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655) + - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386 + - [Config] retpoline -- clean up i386 retpoline files + + * hisilicon hibmc regression due to ea642c3216cb ("drm/ttm: add io_mem_pfn + callback") (LP: #1738334) + - drm/ttm: add ttm_bo_io_mem_pfn to check io_mem_pfn + + * [Asus UX360UA] battery status in unity-panel is not changing when battery is + being charged (LP: #1661876) // AC adapter status not detected on Asus + ZenBook UX410UAK (LP: #1745032) + - ACPI / battery: Add quirk for Asus UX360UA and UX410UAK + + * ASUS UX305LA - Battery state not detected correctly (LP: #1482390) + - ACPI / battery: Add quirk for Asus GL502VSK and UX305LA + + * [18.04 FEAT] Automatically detect layer2 setting in the qeth device driver + (LP: #1747639) + - s390/diag: add diag26c support for VNIC info + - s390/qeth: support early setup for z/VM NICs + + * Bionic update to v4.15.7 stable release (LP: #1752317) + - netfilter: drop outermost socket lock in getsockopt() + - arm64: mm: don't write garbage into TTBR1_EL1 register + - kconfig.h: Include compiler types to avoid missed struct attributes + - MIPS: boot: Define __ASSEMBLY__ for its.S build + - xtensa: fix high memory/reserved memory collision + - scsi: ibmvfc: fix misdefined reserved field in ibmvfc_fcp_rsp_info + - MIPS: Drop spurious __unused in struct compat_flock + - cfg80211: fix cfg80211_beacon_dup + - i2c: designware: must wait for enable + - i2c: bcm2835: Set up the rising/falling edge delays + - X.509: fix BUG_ON() when hash algorithm is unsupported + - X.509: fix NULL dereference when restricting key with unsupported_sig + - PKCS#7: fix certificate chain verification + - PKCS#7: fix certificate blacklisting + - extcon: int3496: process id-pin first so that we start with the right status + - genirq/matrix: Handle CPU offlining proper + - RDMA/uverbs: Protect from races between lookup and destroy of uobjects + - RDMA/uverbs: Protect from command mask overflow + - RDMA/uverbs: Fix bad unlock balance in ib_uverbs_close_xrcd + - RDMA/uverbs: Fix circular locking dependency + - RDMA/uverbs: Sanitize user entered port numbers prior to access it + - iio: adc: stm32: fix stm32h7_adc_enable error handling + - iio: srf08: fix link error "devm_iio_triggered_buffer_setup" undefined + - iio: buffer: check if a buffer has been set up when poll is called + - iio: adis_lib: Initialize trigger before requesting interrupt + - Kbuild: always define endianess in kconfig.h + - x86/apic/vector: Handle vector release on CPU unplug correctly + - x86/oprofile: Fix bogus GCC-8 warning in nmi_setup() + - mm, swap, frontswap: fix THP swap if frontswap enabled + - mm: don't defer struct page initialization for Xen pv guests + - uapi/if_ether.h: move __UAPI_DEF_ETHHDR libc define + - irqchip/gic-v3: Use wmb() instead of smb_wmb() in gic_raise_softirq() + - irqchip/mips-gic: Avoid spuriously handling masked interrupts + - PCI/cxgb4: Extend T3 PCI quirk to T4+ devices + - net: thunderbolt: Tear down connection properly on suspend + - net: thunderbolt: Run disconnect flow asynchronously when logout is received + - ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and + io_watchdog_func() + - usb: ohci: Proper handling of ed_rm_list to handle race condition between + usb_kill_urb() and finish_unlinks() + - arm64: Remove unimplemented syscall log message + - arm64: Disable unhandled signal log messages by default + - arm64: cpufeature: Fix CTR_EL0 field definitions + - Add delay-init quirk for Corsair K70 RGB keyboards + - usb: host: ehci: use correct device pointer for dma ops + - usb: dwc3: gadget: Set maxpacket size for ep0 IN + - usb: dwc3: ep0: Reset TRB counter for ep0 IN + - usb: phy: mxs: Fix NULL pointer dereference on i.MX23/28 + - usb: ldusb: add PIDs for new CASSY devices supported by this driver + - Revert "usb: musb: host: don't start next rx urb if current one failed" + - usb: gadget: f_fs: Process all descriptors during bind + - usb: gadget: f_fs: Use config_ep_by_speed() + - usb: renesas_usbhs: missed the "running" flag in usb_dmac with rx path + - drm/cirrus: Load lut in crtc_commit + - drm/atomic: Fix memleak on ERESTARTSYS during non-blocking commits + - drm: Handle unexpected holes in color-eviction + - drm/amdgpu: disable MMHUB power gating on raven + - drm/amdgpu: fix VA hole handling on Vega10 v3 + - drm/amdgpu: Add dpm quirk for Jet PRO (v2) + - drm/amdgpu: only check mmBIF_IOV_FUNC_IDENTIFIER on tonga/fiji + - drm/amdgpu: Avoid leaking PM domain on driver unbind (v2) + - drm/amdgpu: add new device to use atpx quirk + - arm64: __show_regs: Only resolve kernel symbols when running at EL1 + - drm/i915/breadcrumbs: Ignore unsubmitted signalers + - microblaze: fix endian handling + - Linux 4.15.7 + + * [regression] Colour banding and artefacts appear system-wide on an Asus + Zenbook UX303LA with Intel HD 4400 graphics (LP: #1749420) // Bionic update + to v4.15.7 stable release (LP: #1752317) + - drm/edid: Add 6 bpc quirk for CPT panel in Asus UX303LA + + * errors with sas hotplug (LP: #1752146) + - scsi: libsas: fix memory leak in sas_smp_get_phy_events() + - scsi: libsas: fix error when getting phy events + - scsi: libsas: initialize sas_phy status according to response of DISCOVER + - scsi: libsas: Use dynamic alloced work to avoid sas event lost + - scsi: libsas: shut down the PHY if events reached the threshold + - scsi: libsas: make the event threshold configurable + - scsi: libsas: Use new workqueue to run sas event and disco event + - scsi: libsas: use flush_workqueue to process disco events synchronously + - scsi: libsas: direct call probe and destruct + - scsi: libsas: notify event PORTE_BROADCAST_RCVD in sas_enable_revalidation() + + * rtnetlink: enable namespace identifying properties in rtnetlink requests + (LP: #1748232) + - rtnetlink: enable IFLA_IF_NETNSID in do_setlink() + - rtnetlink: enable IFLA_IF_NETNSID for RTM_SETLINK + - rtnetlink: enable IFLA_IF_NETNSID for RTM_DELLINK + - rtnetlink: enable IFLA_IF_NETNSID for RTM_NEWLINK + - rtnetlink: remove check for IFLA_IF_NETNSID + - rtnetlink: require unique netns identifier + + * Bionic update to v4.15.6 stable release (LP: #1752119) + - tun: fix tun_napi_alloc_frags() frag allocator + - ptr_ring: fail early if queue occupies more than KMALLOC_MAX_SIZE + - ptr_ring: try vmalloc() when kmalloc() fails + - selinux: ensure the context is NUL terminated in + security_context_to_sid_core() + - selinux: skip bounded transition processing if the policy isn't loaded + - media: pvrusb2: properly check endpoint types + - crypto: x86/twofish-3way - Fix %rbp usage + - staging: android: ion: Add __GFP_NOWARN for system contig heap + - staging: android: ion: Switch from WARN to pr_warn + - blk_rq_map_user_iov: fix error override + - KVM: x86: fix escape of guest dr6 to the host + - kcov: detect double association with a single task + - netfilter: x_tables: fix int overflow in xt_alloc_table_info() + - netfilter: x_tables: avoid out-of-bounds reads in + xt_request_find_{match|target} + - netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check() + - netfilter: on sockopt() acquire sock lock only in the required scope + - netfilter: xt_cgroup: initialize info->priv in cgroup_mt_check_v1() + - netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert + - rds: tcp: correctly sequence cleanup on netns deletion. + - rds: tcp: atomically purge entries from rds_tcp_conn_list during netns + delete + - net: avoid skb_warn_bad_offload on IS_ERR + - net_sched: gen_estimator: fix lockdep splat + - soc: qcom: rmtfs_mem: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - ASoC: ux500: add MODULE_LICENSE tag + - video: fbdev/mmp: add MODULE_LICENSE + - ARM: 8743/1: bL_switcher: add MODULE_LICENSE tag + - arm64: dts: add #cooling-cells to CPU nodes + - dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock + - ANDROID: binder: remove WARN() for redundant txn error + - ANDROID: binder: synchronize_rcu() when using POLLFREE. + - staging: android: ashmem: Fix a race condition in pin ioctls + - binder: check for binder_thread allocation failure in binder_poll() + - binder: replace "%p" with "%pK" + - staging: fsl-mc: fix build testing on x86 + - staging: iio: adc: ad7192: fix external frequency setting + - staging: iio: ad5933: switch buffer mode to software + - xhci: Fix NULL pointer in xhci debugfs + - xhci: Fix xhci debugfs devices node disappearance after hibernation + - xhci: xhci debugfs device nodes weren't removed after device plugged out + - xhci: fix xhci debugfs errors in xhci_stop + - usbip: keep usbip_device sockfd state in sync with tcp_socket + - crypto: s5p-sss - Fix kernel Oops in AES-ECB mode + - mei: me: add cannon point device ids + - mei: me: add cannon point device ids for 4th device + - vmalloc: fix __GFP_HIGHMEM usage for vmalloc_32 on 32b systems + - Linux 4.15.6 + + * Unable to insert test_bpf module on Bionic s390x (LP: #1751234) + - bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y + + * [Ubuntu 18.04 FEAT] OpenCAPI enabling (LP: #1746988) + - powerpc/powernv: Introduce new PHB type for opencapi links + - powerpc/powernv: Set correct configuration space size for opencapi devices + - powerpc/powernv: Add opal calls for opencapi + - powerpc/powernv: Add platform-specific services for opencapi + - powerpc/powernv: Capture actag information for the device + - ocxl: Driver code for 'generic' opencapi devices + - ocxl: Add AFU interrupt support + - ocxl: Add a kernel API for other opencapi drivers + - ocxl: Add trace points + - ocxl: Add Makefile and Kconfig + - [Config] CONFIG_OCXL=m for ppc64el + - cxl: Remove support for "Processing accelerators" class + - ocxl: Documentation + - ocxl: add MAINTAINERS entry + - cxl: Add support for ASB_Notify on POWER9 + + * Request to update 18.04 kernel aacraid to upstream 4.16 version + (LP: #1746801) + - scsi: aacraid: remove unused variable managed_request_id + - scsi: aacraid: Do not attempt abort when Fw panicked + - scsi: aacraid: Do not remove offlined devices + - scsi: aacraid: Fix ioctl reset hang + - scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw + - scsi: aacraid: Refactor reset_host store function + - scsi: aacraid: Move code to wait for IO completion to shutdown func + - scsi: aacraid: Create bmic submission function from bmic identify + - scsi: aacraid: Change phy luns function to use common bmic function + - scsi: aacraid: Refactor and rename to make mirror existing changes + - scsi: aacraid: Add target setup helper function + - scsi: aacraid: Untangle targets setup from report phy luns + - scsi: aacraid: Move function around to match existing code + - scsi: aacraid: Create helper functions to get lun info + - scsi: aacraid: Save bmic phy information for each phy + - scsi: aacraid: Add helper function to set queue depth + - scsi: aacraid: Merge func to get container information + - scsi: aacraid: Process hba and container hot plug events in single function + - scsi: aacraid: Added macros to help loop through known buses and targets + - scsi: aacraid: Refactor resolve luns code and scsi functions + - scsi: aacraid: Merge adapter setup with resolve luns + - scsi: aacraid: Block concurrent hotplug event handling + - scsi: aacraid: Use hotplug handling function in place of scsi_scan_host + - scsi: aacraid: Reschedule host scan in case of failure + - scsi: aacraid: Fix hang while scanning in eh recovery + - scsi: aacraid: Skip schedule rescan in case of kdump + - scsi: aacraid: Remove unused rescan variable + - scsi: aacraid: Remove AAC_HIDE_DISK check in queue command + - scsi: aacraid: Update driver version to 50877 + - scsi: aacraid: Fix driver oops with dead battery + - scsi: aacraid: remove redundant setting of variable c + - scsi: aacraid: Get correct lun count + - scsi: aacraid: Delay for rescan worker needs to be 10 seconds + + * [18.04] kpatch - Add livepatch hook support for ppc64le (LP: #1741992) + - powerpc/modules: Add REL24 relocation support of livepatch symbols + - powerpc/modules: Don't try to restore r2 after a sibling call + - powerpc/modules: Improve restore_r2() error message + + * Ubuntu 18.04 - Include latest ibmvnic fixes in Ubuntu kernel (LP: #1748517) + - ibmvnic: Rename IBMVNIC_MAX_TX_QUEUES to IBMVNIC_MAX_QUEUES + - ibmvnic: Increase maximum number of RX/TX queues + - ibmvnic: Include header descriptor support for ARP packets + - ibmvnic: Don't handle RX interrupts when not up. + - ibmvnic: Wait for device response when changing MAC + - ibmvnic: fix firmware version when no firmware level has been provided by + the VIOS server + - ibmvnic: fix empty firmware version and errors cleanup + - ibmvnic: Fix rx queue cleanup for non-fatal resets + - ibmvnic: Ensure that buffers are NULL after free + - ibmvnic: queue reset when CRQ gets closed during reset + - ibmvnic: Reset long term map ID counter + - ibmvnic: Remove skb->protocol checks in ibmvnic_xmit + - ibmvnic: Wait until reset is complete to set carrier on + - ibmvnic: Fix login buffer memory leaks + - ibmvnic: Fix NAPI structures memory leak + - ibmvnic: Free RX socket buffer in case of adapter error + - ibmvnic: Clean RX pool buffers during device close + - ibmvnic: Check for NULL skb's in NAPI poll routine + - ibmvnic: Fix early release of login buffer + + * Power9 DD 2.2 needs HMI fixup backport of upstream + patch(d075745d893c78730e4a3b7a60fca23c2f764081) into kernel (LP: #1751834) + - KVM: PPC: Book3S HV: Improve handling of debug-trigger HMIs on POWER9 + + * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927) + - d-i: add cxgb4 to nic-modules + + * BCM5719/tg3 loses connectivity due to missing heartbeats between fw and + driver (LP: #1751337) + - tg3: APE heartbeat changes + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.2.6-dfsg-5 + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - Revert "UBUNTU: SAUCE: (no-up) Convert bnx2x firmware files to ihex format" + - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches + - [Config] fix up retpoline abi files + - ubuntu: vbox -- update to 5.2.8-dfsg-2 + + -- Seth Forshee Wed, 07 Mar 2018 17:36:23 +0100 + +linux (4.15.0-11.12) bionic; urgency=medium + + * linux: 4.15.0-11.12 -proposed tracker (LP: #1751285) + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_INDIRECT_PIO=y + - SAUCE: LIB: Introduce a generic PIO mapping method + - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range() + - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range() + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - SAUCE: ACPI / scan: do not enumerate Indirect IO host children + - SAUCE: HISI LPC: Add ACPI support + - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver + + * Bionic update to v4.15.5 stable release (LP: #1751131) + - scsi: smartpqi: allow static build ("built-in") + - IB/umad: Fix use of unprotected device pointer + - IB/qib: Fix comparison error with qperf compare/swap test + - IB/mlx4: Fix incorrectly releasing steerable UD QPs when have only ETH ports + - IB/core: Fix two kernel warnings triggered by rxe registration + - IB/core: Fix ib_wc structure size to remain in 64 bytes boundary + - IB/core: Avoid a potential OOPs for an unused optional parameter + - selftests: seccomp: fix compile error seccomp_bpf + - kselftest: fix OOM in memory compaction test + - RDMA/rxe: Fix a race condition related to the QP error state + - RDMA/rxe: Fix a race condition in rxe_requester() + - RDMA/rxe: Fix rxe_qp_cleanup() + - cpufreq: powernv: Dont assume distinct pstate values for nominal and pmin + - PM / devfreq: Propagate error from devfreq_add_device() + - mwifiex: resolve reset vs. remove()/shutdown() deadlocks + - ocfs2: try a blocking lock before return AOP_TRUNCATED_PAGE + - trace_uprobe: Display correct offset in uprobe_events + - powerpc/radix: Remove trace_tlbie call from radix__flush_tlb_all + - powerpc/kernel: Block interrupts when updating TIDR + - powerpc/vas: Don't set uses_vas for kernel windows + - powerpc/numa: Invalidate numa_cpu_lookup_table on cpu remove + - powerpc/mm: Flush radix process translations when setting MMU type + - powerpc/xive: Use hw CPU ids when configuring the CPU queues + - dma-buf: fix reservation_object_wait_timeout_rcu once more v2 + - s390: fix handling of -1 in set{,fs}[gu]id16 syscalls + - arm64: dts: msm8916: Correct ipc references for smsm + - ARM: lpc3250: fix uda1380 gpio numbers + - ARM: dts: STi: Add gpio polarity for "hdmi,hpd-gpio" property + - ARM: dts: nomadik: add interrupt-parent for clcd + - arm: dts: mt7623: fix card detection issue on bananapi-r2 + - arm: spear600: Add missing interrupt-parent of rtc + - arm: spear13xx: Fix dmas cells + - arm: spear13xx: Fix spics gpio controller's warning + - x86/gpu: add CFL to early quirks + - x86/kexec: Make kexec (mostly) work in 5-level paging mode + - x86/xen: init %gs very early to avoid page faults with stack protector + - x86: PM: Make APM idle driver initialize polling state + - mm, memory_hotplug: fix memmap initialization + - x86/entry/64: Clear extra registers beyond syscall arguments, to reduce + speculation attack surface + - x86/entry/64/compat: Clear registers for compat syscalls, to reduce + speculation attack surface + - compiler-gcc.h: Introduce __optimize function attribute + - compiler-gcc.h: __nostackprotector needs gcc-4.4 and up + - crypto: sun4i_ss_prng - fix return value of sun4i_ss_prng_generate + - crypto: sun4i_ss_prng - convert lock to _bh in sun4i_ss_prng_generate + - powerpc/mm/radix: Split linear mapping on hot-unplug + - x86/mm/pti: Fix PTI comment in entry_SYSCALL_64() + - x86/speculation: Update Speculation Control microcode blacklist + - x86/speculation: Correct Speculation Control microcode blacklist again + - Revert "x86/speculation: Simplify indirect_branch_prediction_barrier()" + - KVM/x86: Reduce retpoline performance impact in slot_handle_level_range(), + by always inlining iterator helper methods + - X86/nVMX: Properly set spec_ctrl and pred_cmd before merging MSRs + - KVM/nVMX: Set the CPU_BASED_USE_MSR_BITMAPS if we have a valid L02 MSR + bitmap + - x86/speculation: Clean up various Spectre related details + - PM / runtime: Update links_count also if !CONFIG_SRCU + - PM: cpuidle: Fix cpuidle_poll_state_init() prototype + - platform/x86: wmi: fix off-by-one write in wmi_dev_probe() + - x86/entry/64: Clear registers for exceptions/interrupts, to reduce + speculation attack surface + - x86/entry/64: Merge SAVE_C_REGS and SAVE_EXTRA_REGS, remove unused + extensions + - x86/entry/64: Merge the POP_C_REGS and POP_EXTRA_REGS macros into a single + POP_REGS macro + - x86/entry/64: Interleave XOR register clearing with PUSH instructions + - x86/entry/64: Introduce the PUSH_AND_CLEAN_REGS macro + - x86/entry/64: Use PUSH_AND_CLEAN_REGS in more cases + - x86/entry/64: Get rid of the ALLOC_PT_GPREGS_ON_STACK and + SAVE_AND_CLEAR_REGS macros + - x86/entry/64: Indent PUSH_AND_CLEAR_REGS and POP_REGS properly + - x86/entry/64: Fix paranoid_entry() frame pointer warning + - x86/entry/64: Remove the unused 'icebp' macro + - selftests/x86: Fix vDSO selftest segfault for vsyscall=none + - selftests/x86: Clean up and document sscanf() usage + - selftests/x86/pkeys: Remove unused functions + - selftests/x86: Fix build bug caused by the 5lvl test which has been moved to + the VM directory + - selftests/x86: Do not rely on "int $0x80" in test_mremap_vdso.c + - gfs2: Fixes to "Implement iomap for block_map" + - selftests/x86: Do not rely on "int $0x80" in single_step_syscall.c + - selftests/x86: Disable tests requiring 32-bit support on pure 64-bit systems + - objtool: Fix segfault in ignore_unreachable_insn() + - x86/debug, objtool: Annotate WARN()-related UD2 as reachable + - x86/debug: Use UD2 for WARN() + - x86/speculation: Fix up array_index_nospec_mask() asm constraint + - nospec: Move array_index_nospec() parameter checking into separate macro + - x86/speculation: Add dependency + - x86/mm: Rename flush_tlb_single() and flush_tlb_one() to + __flush_tlb_one_[user|kernel]() + - selftests/x86/mpx: Fix incorrect bounds with old _sigfault + - x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping + - x86/spectre: Fix an error message + - x86/cpu: Change type of x86_cache_size variable to unsigned int + - x86/entry/64: Fix CR3 restore in paranoid_exit() + - drm/ttm: Don't add swapped BOs to swap-LRU list + - drm/ttm: Fix 'buf' pointer update in ttm_bo_vm_access_kmap() (v2) + - drm/qxl: unref cursor bo when finished with it + - drm/qxl: reapply cursor after resetting primary + - drm/amd/powerplay: Fix smu_table_entry.handle type + - drm/ast: Load lut in crtc_commit + - drm: Check for lessee in DROP_MASTER ioctl + - arm64: Add missing Falkor part number for branch predictor hardening + - drm/radeon: Add dpm quirk for Jet PRO (v2) + - drm/radeon: adjust tested variable + - x86/smpboot: Fix uncore_pci_remove() indexing bug when hot-removing a + physical CPU + - rtc-opal: Fix handling of firmware error codes, prevent busy loops + - mbcache: initialize entry->e_referenced in mb_cache_entry_create() + - mmc: sdhci: Implement an SDHCI-specific bounce buffer + - mmc: bcm2835: Don't overwrite max frequency unconditionally + - Revert "mmc: meson-gx: include tx phase in the tuning process" + - mlx5: fix mlx5_get_vector_affinity to start from completion vector 0 + - Revert "apple-gmux: lock iGP IO to protect from vgaarb changes" + - jbd2: fix sphinx kernel-doc build warnings + - ext4: fix a race in the ext4 shutdown path + - ext4: save error to disk in __ext4_grp_locked_error() + - ext4: correct documentation for grpid mount option + - mm: hide a #warning for COMPILE_TEST + - mm: Fix memory size alignment in devm_memremap_pages_release() + - MIPS: Fix typo BIG_ENDIAN to CPU_BIG_ENDIAN + - MIPS: CPS: Fix MIPS_ISA_LEVEL_RAW fallout + - MIPS: Fix incorrect mem=X@Y handling + - PCI: Disable MSI for HiSilicon Hip06/Hip07 only in Root Port mode + - PCI: iproc: Fix NULL pointer dereference for BCMA + - PCI: pciehp: Assume NoCompl+ for Thunderbolt ports + - PCI: keystone: Fix interrupt-controller-node lookup + - video: fbdev: atmel_lcdfb: fix display-timings lookup + - console/dummy: leave .con_font_get set to NULL + - rbd: whitelist RBD_FEATURE_OPERATIONS feature bit + - xen: Fix {set,clear}_foreign_p2m_mapping on autotranslating guests + - xenbus: track caller request id + - seq_file: fix incomplete reset on read from zero offset + - tracing: Fix parsing of globs with a wildcard at the beginning + - mpls, nospec: Sanitize array index in mpls_label_ok() + - rtlwifi: rtl8821ae: Fix connection lost problem correctly + - arm64: proc: Set PTE_NG for table entries to avoid traversing them twice + - xprtrdma: Fix calculation of ri_max_send_sges + - xprtrdma: Fix BUG after a device removal + - blk-wbt: account flush requests correctly + - target/iscsi: avoid NULL dereference in CHAP auth error path + - iscsi-target: make sure to wake up sleeping login worker + - dm: correctly handle chained bios in dec_pending() + - Btrfs: fix deadlock in run_delalloc_nocow + - Btrfs: fix crash due to not cleaning up tree log block's dirty bits + - Btrfs: fix extent state leak from tree log + - Btrfs: fix btrfs_evict_inode to handle abnormal inodes correctly + - Btrfs: fix use-after-free on root->orphan_block_rsv + - Btrfs: fix unexpected -EEXIST when creating new inode + - 9p/trans_virtio: discard zero-length reply + - mtd: nand: vf610: set correct ooblayout + - ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute + - ALSA: hda/realtek - Add headset mode support for Dell laptop + - ALSA: hda/realtek - Enable Thinkpad Dock device for ALC298 platform + - ALSA: hda/realtek: PCI quirk for Fujitsu U7x7 + - ALSA: usb-audio: add implicit fb quirk for Behringer UFX1204 + - ALSA: usb: add more device quirks for USB DSD devices + - ALSA: seq: Fix racy pool initializations + - mvpp2: fix multicast address filter + - usb: Move USB_UHCI_BIG_ENDIAN_* out of USB_SUPPORT + - x86/mm, mm/hwpoison: Don't unconditionally unmap kernel 1:1 pages + - ARM: dts: exynos: fix RTC interrupt for exynos5410 + - ARM: pxa/tosa-bt: add MODULE_LICENSE tag + - arm64: dts: msm8916: Add missing #phy-cells + - ARM: dts: s5pv210: add interrupt-parent for ohci + - arm: dts: mt7623: Update ethsys binding + - arm: dts: mt2701: Add reset-cells + - ARM: dts: Delete bogus reference to the charlcd + - media: r820t: fix r820t_write_reg for KASAN + - mmc: sdhci-of-esdhc: fix eMMC couldn't work after kexec + - mmc: sdhci-of-esdhc: fix the mmc error after sleep on ls1046ardb + - Linux 4.15.5 + + * retpoline abi files are empty on i386 (LP: #1751021) + - [Packaging] retpoline-extract -- instantiate retpoline files for i386 + - [Packaging] final-checks -- sanity checking ABI contents + - [Packaging] final-checks -- check for empty retpoline files + - [Config] Disable i386 retpoline check for next upload + + * Bionic update to v4.15.4 stable release (LP: #1751064) + - watchdog: indydog: Add dependency on SGI_HAS_INDYDOG + - cifs: Fix missing put_xid in cifs_file_strict_mmap + - cifs: Fix autonegotiate security settings mismatch + - CIFS: zero sensitive data when freeing + - cpufreq: mediatek: add mediatek related projects into blacklist + - dmaengine: dmatest: fix container_of member in dmatest_callback + - ssb: Do not disable PCI host on non-Mips + - watchdog: gpio_wdt: set WDOG_HW_RUNNING in gpio_wdt_stop + - Revert "drm/i915: mark all device info struct with __initconst" + - sched/rt: Use container_of() to get root domain in rto_push_irq_work_func() + - sched/rt: Up the root domain ref count when passing it around via IPIs + - media: dvb-usb-v2: lmedm04: Improve logic checking of warm start + - media: dvb-usb-v2: lmedm04: move ts2020 attach to dm04_lme2510_tuner + - media: hdpvr: Fix an error handling path in hdpvr_probe() + - arm64: mm: Use non-global mappings for kernel space + - arm64: mm: Temporarily disable ARM64_SW_TTBR0_PAN + - arm64: mm: Move ASID from TTBR0 to TTBR1 + - arm64: mm: Remove pre_ttbr0_update_workaround for Falkor erratum #E1003 + - arm64: mm: Rename post_ttbr0_update_workaround + - arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN + - arm64: mm: Allocate ASIDs in pairs + - arm64: mm: Add arm64_kernel_unmapped_at_el0 helper + - arm64: mm: Invalidate both kernel and user ASIDs when performing TLBI + - arm64: entry: Add exception trampoline page for exceptions from EL0 + - arm64: mm: Map entry trampoline into trampoline and kernel page tables + - arm64: entry: Explicitly pass exception level to kernel_ventry macro + - arm64: entry: Hook up entry trampoline to exception vectors + - arm64: erratum: Work around Falkor erratum #E1003 in trampoline code + - arm64: cpu_errata: Add Kryo to Falkor 1003 errata + - arm64: tls: Avoid unconditional zeroing of tpidrro_el0 for native tasks + - arm64: entry: Add fake CPU feature for unmapping the kernel at EL0 + - arm64: kaslr: Put kernel vectors address in separate data page + - arm64: use RET instruction for exiting the trampoline + - arm64: Kconfig: Add CONFIG_UNMAP_KERNEL_AT_EL0 + - arm64: Kconfig: Reword UNMAP_KERNEL_AT_EL0 kconfig entry + - arm64: Take into account ID_AA64PFR0_EL1.CSV3 + - arm64: capabilities: Handle duplicate entries for a capability + - arm64: mm: Introduce TTBR_ASID_MASK for getting at the ASID in the TTBR + - arm64: kpti: Fix the interaction between ASID switching and software PAN + - arm64: cputype: Add MIDR values for Cavium ThunderX2 CPUs + - arm64: kpti: Make use of nG dependent on arm64_kernel_unmapped_at_el0() + - arm64: mm: Permit transitioning from Global to Non-Global without BBM + - arm64: kpti: Add ->enable callback to remap swapper using nG mappings + - arm64: Force KPTI to be disabled on Cavium ThunderX + - arm64: entry: Reword comment about post_ttbr_update_workaround + - arm64: idmap: Use "awx" flags for .idmap.text .pushsection directives + - perf: arm_spe: Fail device probe when arm64_kernel_unmapped_at_el0() + - arm64: barrier: Add CSDB macros to control data-value prediction + - arm64: Implement array_index_mask_nospec() + - arm64: Make USER_DS an inclusive limit + - arm64: Use pointer masking to limit uaccess speculation + - arm64: entry: Ensure branch through syscall table is bounded under + speculation + - arm64: uaccess: Prevent speculative use of the current addr_limit + - arm64: uaccess: Don't bother eliding access_ok checks in __{get, put}_user + - arm64: uaccess: Mask __user pointers for __arch_{clear, copy_*}_user + - arm64: futex: Mask __user pointers prior to dereference + - arm64: cpufeature: __this_cpu_has_cap() shouldn't stop early + - arm64: Run enable method for errata work arounds on late CPUs + - arm64: cpufeature: Pass capability structure to ->enable callback + - drivers/firmware: Expose psci_get_version through psci_ops structure + - arm64: Move post_ttbr_update_workaround to C code + - arm64: Add skeleton to harden the branch predictor against aliasing attacks + - arm64: Move BP hardening to check_and_switch_context + - arm64: KVM: Use per-CPU vector when BP hardening is enabled + - arm64: entry: Apply BP hardening for high-priority synchronous exceptions + - arm64: entry: Apply BP hardening for suspicious interrupts from EL0 + - arm64: cputype: Add missing MIDR values for Cortex-A72 and Cortex-A75 + - arm64: Implement branch predictor hardening for affected Cortex-A CPUs + - arm64: Implement branch predictor hardening for Falkor + - arm64: Branch predictor hardening for Cavium ThunderX2 + - arm64: KVM: Increment PC after handling an SMC trap + - arm/arm64: KVM: Consolidate the PSCI include files + - arm/arm64: KVM: Add PSCI_VERSION helper + - arm/arm64: KVM: Add smccc accessors to PSCI code + - arm/arm64: KVM: Implement PSCI 1.0 support + - arm/arm64: KVM: Advertise SMCCC v1.1 + - arm64: KVM: Make PSCI_VERSION a fast path + - arm/arm64: KVM: Turn kvm_psci_version into a static inline + - arm64: KVM: Report SMCCC_ARCH_WORKAROUND_1 BP hardening support + - arm64: KVM: Add SMCCC_ARCH_WORKAROUND_1 fast handling + - firmware/psci: Expose PSCI conduit + - firmware/psci: Expose SMCCC version through psci_ops + - arm/arm64: smccc: Make function identifiers an unsigned quantity + - arm/arm64: smccc: Implement SMCCC v1.1 inline primitive + - arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support + - arm64: Kill PSCI_GET_VERSION as a variant-2 workaround + - mtd: cfi: convert inline functions to macros + - mtd: nand: brcmnand: Disable prefetch by default + - mtd: nand: Fix nand_do_read_oob() return value + - mtd: nand: sunxi: Fix ECC strength choice + - ubi: Fix race condition between ubi volume creation and udev + - ubi: fastmap: Erase outdated anchor PEBs during attach + - ubi: block: Fix locking for idr_alloc/idr_remove + - ubifs: free the encrypted symlink target + - nfs/pnfs: fix nfs_direct_req ref leak when i/o falls back to the mds + - nfs41: do not return ENOMEM on LAYOUTUNAVAILABLE + - NFS: Add a cond_resched() to nfs_commit_release_pages() + - NFS: Fix nfsstat breakage due to LOOKUPP + - NFS: commit direct writes even if they fail partially + - NFS: reject request for id_legacy key without auxdata + - NFS: Fix a race between mmap() and O_DIRECT + - nfsd: Detect unhashed stids in nfsd4_verify_open_stid() + - kernfs: fix regression in kernfs_fop_write caused by wrong type + - ahci: Annotate PCI ids for mobile Intel chipsets as such + - ahci: Add PCI ids for Intel Bay Trail, Cherry Trail and Apollo Lake AHCI + - ahci: Add Intel Cannon Lake PCH-H PCI ID + - crypto: hash - introduce crypto_hash_alg_has_setkey() + - crypto: cryptd - pass through absence of ->setkey() + - crypto: mcryptd - pass through absence of ->setkey() + - crypto: poly1305 - remove ->setkey() method + - crypto: hash - annotate algorithms taking optional key + - crypto: hash - prevent using keyed hashes without setting key + - media: v4l2-ioctl.c: use check_fmt for enum/g/s/try_fmt + - media: v4l2-ioctl.c: don't copy back the result for -ENOTTY + - media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF + - media: v4l2-compat-ioctl32.c: fix the indentation + - media: v4l2-compat-ioctl32.c: move 'helper' functions to + __get/put_v4l2_format32 + - media: v4l2-compat-ioctl32.c: avoid sizeof(type) + - media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32 + - media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer + - media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32 + - media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type + - media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors + - media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic + - media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs + - crypto: caam - fix endless loop when DECO acquire fails + - crypto: sha512-mb - initialize pending lengths correctly + - crypto: talitos - fix Kernel Oops on hashing an empty file + - arm: KVM: Fix SMCCC handling of unimplemented SMC/HVC calls + - KVM: nVMX: Fix races when sending nested PI while dest enters/leaves L2 + - KVM: nVMX: Fix bug of injecting L2 exception into L1 + - KVM: PPC: Book3S HV: Make sure we don't re-enter guest without XIVE loaded + - KVM: PPC: Book3S HV: Drop locks before reading guest memory + - KVM: arm/arm64: Handle CPU_PM_ENTER_FAILED + - KVM: PPC: Book3S PR: Fix broken select due to misspelling + - ASoC: acpi: fix machine driver selection based on quirk + - ASoC: rockchip: i2s: fix playback after runtime resume + - ASoC: skl: Fix kernel warning due to zero NHTL entry + - ASoC: compress: Correct handling of copy callback + - watchdog: imx2_wdt: restore previous timeout after suspend+resume + - afs: Add missing afs_put_cell() + - afs: Need to clear responded flag in addr cursor + - afs: Fix missing cursor clearance + - afs: Fix server list handling + - btrfs: Handle btrfs_set_extent_delalloc failure in fixup worker + - Btrfs: raid56: iterate raid56 internal bio with bio_for_each_segment_all + - kasan: don't emit builtin calls when sanitization is off + - kasan: rework Kconfig settings + - media: dvb_frontend: be sure to init dvb_frontend_handle_ioctl() return code + - media: dvb-frontends: fix i2c access helpers for KASAN + - media: dt-bindings/media/cec-gpio.txt: mention the CEC/HPD max voltages + - media: ts2020: avoid integer overflows on 32 bit machines + - media: vivid: fix module load error when enabling fb and no_error_inj=1 + - media: cxusb, dib0700: ignore XC2028_I2C_FLUSH + - fs/proc/kcore.c: use probe_kernel_read() instead of memcpy() + - kernel/async.c: revert "async: simplify lowest_in_progress()" + - kernel/relay.c: revert "kernel/relay.c: fix potential memory leak" + - pipe: actually allow root to exceed the pipe buffer limits + - pipe: fix off-by-one error when checking buffer limits + - HID: quirks: Fix keyboard + touchpad on Toshiba Click Mini not working + - Bluetooth: btsdio: Do not bind to non-removable BCM43341 + - ipmi: use dynamic memory for DMI driver override + - signal/openrisc: Fix do_unaligned_access to send the proper signal + - signal/sh: Ensure si_signo is initialized in do_divide_error + - alpha: fix crash if pthread_create races with signal delivery + - alpha: osf_sys.c: fix put_tv32 regression + - alpha: Fix mixed up args in EXC macro in futex operations + - alpha: fix reboot on Avanti platform + - alpha: fix formating of stack content + - xtensa: fix futex_atomic_cmpxchg_inatomic + - EDAC, octeon: Fix an uninitialized variable warning + - genirq: Make legacy autoprobing work again + - pinctrl: intel: Initialize GPIO properly when used through irqchip + - pinctrl: mcp23s08: fix irq setup order + - pinctrl: sx150x: Unregister the pinctrl on release + - pinctrl: sx150x: Register pinctrl before adding the gpiochip + - pinctrl: sx150x: Add a static gpio/pinctrl pin range mapping + - pktcdvd: Fix pkt_setup_dev() error path + - pktcdvd: Fix a recently introduced NULL pointer dereference + - blk-mq: quiesce queue before freeing queue + - clocksource/drivers/stm32: Fix kernel panic with multiple timers + - lib/ubsan.c: s/missaligned/misaligned/ + - lib/ubsan: add type mismatch handler for new GCC/Clang + - objtool: Fix switch-table detection + - arm64: dts: marvell: add Ethernet aliases + - drm/i915: Avoid PPS HW/SW state mismatch due to rounding + - ACPI: sbshc: remove raw pointer from printk() message + - acpi, nfit: fix register dimm error handling + - ovl: force r/o mount when index dir creation fails + - ovl: fix failure to fsync lower dir + - ovl: take mnt_want_write() for work/index dir setup + - ovl: take mnt_want_write() for removing impure xattr + - ovl: hash directory inodes for fsnotify + - mn10300/misalignment: Use SIGSEGV SEGV_MAPERR to report a failed user copy + - devpts: fix error handling in devpts_mntget() + - ftrace: Remove incorrect setting of glob search field + - scsi: core: Ensure that the SCSI error handler gets woken up + - scsi: lpfc: Fix crash after bad bar setup on driver attachment + - scsi: cxlflash: Reset command ioasc + - rcu: Export init_rcu_head() and destroy_rcu_head() to GPL modules + - Linux 4.15.4 + - updateconfigs after v4.14.4 stable updates + + * Bionic update to v4.15.4 stable release (LP: #1751064) // CVE-2017-5754 and + do not need KPTI when KASLR is off. + - arm64: Turn on KPTI only on CPUs that need it + + * Miscellaneous Ubuntu changes + - [Config] fix up removed retpoline call sites + + -- Seth Forshee Fri, 23 Feb 2018 08:31:06 -0600 + +linux (4.15.0-10.11) bionic; urgency=medium + + * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250) + + * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10 + (LP: #1749202) + - swiotlb: suppress warning when __GFP_NOWARN is set + - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools + + * linux-tools: perf incorrectly linking libbfd (LP: #1748922) + - SAUCE: tools -- add ability to disable libbfd + - [Packaging] correct disablement of libbfd + + * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in + (LP: #1744058) + - ALSA: hda/realtek - update ALC225 depop optimize + + * [Artful] Support headset mode for DELL WYSE (LP: #1723913) + - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE + + * headset mic can't be detected on two Dell machines (LP: #1748807) + - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289 + - ALSA: hda - Fix headset mic detection problem for two Dell machines + + * Bionic update to v4.15.3 stable release (LP: #1749191) + - ip6mr: fix stale iterator + - net: igmp: add a missing rcu locking section + - qlcnic: fix deadlock bug + - qmi_wwan: Add support for Quectel EP06 + - r8169: fix RTL8168EP take too long to complete driver initialization. + - tcp: release sk_frag.page in tcp_disconnect + - vhost_net: stop device during reset owner + - ipv6: addrconf: break critical section in addrconf_verify_rtnl() + - ipv6: change route cache aging logic + - Revert "defer call to mem_cgroup_sk_alloc()" + - net: ipv6: send unsolicited NA after DAD + - rocker: fix possible null pointer dereference in + rocker_router_fib_event_work + - tcp_bbr: fix pacing_gain to always be unity when using lt_bw + - cls_u32: add missing RCU annotation. + - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only + - soreuseport: fix mem leak in reuseport_add_sock() + - net_sched: get rid of rcu_barrier() in tcf_block_put_ext() + - net: sched: fix use-after-free in tcf_block_put_ext + - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION + - media: soc_camera: soc_scale_crop: add missing + MODULE_DESCRIPTION/AUTHOR/LICENSE + - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE + - crypto: tcrypt - fix S/G table for test_aead_speed() + - Linux 4.15.3 + + * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) // + CVE-2018-1000026 + - net: create skb_gso_validate_mac_len() + - bnx2x: disable GSO where gso_size is too big for hardware + + * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567) + - net: hns: add ACPI mode support for ethtool -p + + * CVE-2017-5715 (Spectre v2 Intel) + - [Packaging] retpoline files must be sorted + - [Packaging] pull in retpoline files + + * [Feature] PXE boot with Intel Omni-Path (LP: #1712031) + - d-i: Add hfi1 to nic-modules + + * CVE-2017-5715 (Spectre v2 retpoline) + - [Packaging] retpoline -- add call site validation + - [Config] disable retpoline checks for first upload + + * Do not duplicate changelog entries assigned to more than one bug or CVE + (LP: #1743383) + - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better + + -- Seth Forshee Tue, 13 Feb 2018 11:33:58 -0600 + +linux (4.15.0-9.10) bionic; urgency=medium + + * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244) + + * Miscellaneous Ubuntu changes + - [Debian] tests -- remove gcc-multilib dependency for arm64 + + -- Seth Forshee Thu, 08 Feb 2018 11:25:04 -0600 + +linux (4.15.0-8.9) bionic; urgency=medium + + * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075) + + * Bionic update to v4.15.2 stable release (LP: #1748072) + - KVM: x86: Make indirect calls in emulator speculation safe + - KVM: VMX: Make indirect call speculation safe + - module/retpoline: Warn about missing retpoline in module + - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf + - x86/cpufeatures: Add Intel feature bits for Speculation Control + - x86/cpufeatures: Add AMD feature bits for Speculation Control + - x86/msr: Add definitions for new speculation control MSRs + - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown + - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes + - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support + - x86/alternative: Print unadorned pointers + - x86/nospec: Fix header guards names + - x86/bugs: Drop one "mitigation" from dmesg + - x86/cpu/bugs: Make retpoline module warning conditional + - x86/cpufeatures: Clean up Spectre v2 related CPUID flags + - x86/retpoline: Simplify vmexit_fill_RSB() + - x86/speculation: Simplify indirect_branch_prediction_barrier() + - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - iio: adc/accel: Fix up module licenses + - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - KVM: nVMX: Eliminate vmcs02 pool + - KVM: VMX: introduce alloc_loaded_vmcs + - objtool: Improve retpoline alternative handling + - objtool: Add support for alternatives at the end of a section + - objtool: Warn on stripped section symbol + - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP + - x86/spectre: Check CONFIG_RETPOLINE in command line parser + - x86/entry/64: Remove the SYSCALL64 fast path + - x86/entry/64: Push extra regs right away + - x86/asm: Move 'status' from thread_struct to thread_info + - Documentation: Document array_index_nospec + - array_index_nospec: Sanitize speculative array de-references + - x86: Implement array_index_mask_nospec + - x86: Introduce barrier_nospec + - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec + - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end} + - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec + - x86/get_user: Use pointer masking to limit speculation + - x86/syscall: Sanitize syscall table de-references under speculation + - vfs, fdtable: Prevent bounds-check bypass via speculative execution + - nl80211: Sanitize array index in parse_txq_params + - x86/spectre: Report get_user mitigation for spectre_v1 + - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable" + - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel + - x86/speculation: Use Indirect Branch Prediction Barrier in context switch + - x86/paravirt: Remove 'noreplace-paravirt' cmdline option + - KVM: VMX: make MSR bitmaps per-VCPU + - x86/kvm: Update spectre-v1 mitigation + - x86/retpoline: Avoid retpolines for built-in __init functions + - x86/spectre: Simplify spectre_v2 command line parsing + - x86/pti: Mark constant arrays as __initconst + - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL + - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX + - KVM/x86: Add IBPB support + - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES + - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL + - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL + - serial: core: mark port as initialized after successful IRQ change + - fpga: region: release of_parse_phandle nodes after use + - Linux 4.15.2 + + * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792) + - net: phy: core: remove now uneeded disabling of interrupts + - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m + - net: socionext: Add Synquacer NetSec driver + - net: socionext: include linux/io.h to fix build + - net: socionext: Fix error return code in netsec_netdev_open() + + * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746) + - [Config] CONFIG_EDAC_GHES=y + + * support thunderx2 vendor pmu events (LP: #1747523) + - perf pmu: Pass pmu as a parameter to get_cpuid_str() + - perf tools arm64: Add support for get_cpuid_str function. + - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices + - perf vendor events arm64: Add ThunderX2 implementation defined pmu core + events + - perf pmu: Add check for valid cpuid in perf_pmu__find_map() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Miscellaneous Ubuntu changes + - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations + + -- Seth Forshee Wed, 07 Feb 2018 21:13:27 -0600 + +linux (4.15.0-7.8) bionic; urgency=medium + + * Bionic update to v4.15.1 stable release (LP: #1747169) + - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops + - tools/gpio: Fix build error with musl libc + - gpio: stmpe: i2c transfer are forbiden in atomic context + - gpio: Fix kernel stack leak to userspace + - ALSA: hda - Reduce the suspend time consumption for ALC256 + - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH + - crypto: aesni - handle zero length dst buffer + - crypto: aesni - fix typo in generic_gcmaes_decrypt + - crypto: aesni - add wrapper for generic gcm(aes) + - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm- + aesni + - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm- + aesni + - crypto: inside-secure - fix hash when length is a multiple of a block + - crypto: inside-secure - avoid unmapping DMA memory that was not mapped + - crypto: sha3-generic - fixes for alignment and big endian operation + - crypto: af_alg - whitelist mask and type + - HID: wacom: EKR: ensure devres groups at higher indexes are released + - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events + - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE + - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - igb: Free IRQs when device is hotplugged + - ima/policy: fix parsing of fsuuid + - scsi: aacraid: Fix udev inquiry race condition + - scsi: aacraid: Fix hang in kdump + - scsi: storvsc: missing error code in storvsc_probe() + - staging: lustre: separate a connection destroy from free struct kib_conn + - staging: ccree: NULLify backup_info when unused + - staging: ccree: fix fips event irq handling build + - tty: fix data race between tty_init_dev and flush of buf + - usb: option: Add support for FS040U modem + - USB: serial: pl2303: new device id for Chilitag + - USB: cdc-acm: Do not log urb submission errors on disconnect + - CDC-ACM: apply quirk for card reader + - USB: serial: io_edgeport: fix possible sleep-in-atomic + - usbip: prevent bind loops on devices attached to vhci_hcd + - usbip: list: don't list devices attached to vhci_hcd + - USB: serial: simple: add Motorola Tetra driver + - usb: f_fs: Prevent gadget unbind if it is already unbound + - usb: uas: unconditionally bring back host after reset + - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc() + - ANDROID: binder: remove waitqueue when thread exits. + - android: binder: use VM_ALLOC to get vm area + - mei: me: allow runtime pm for platform with D0i3 + - serial: 8250_of: fix return code when probe function fails to get reset + - serial: 8250_uniphier: fix error return code in uniphier_uart_probe() + - serial: 8250_dw: Revert "Improve clock rate setting" + - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS + - spi: imx: do not access registers while clocks disabled + - iio: adc: stm32: fix scan of multiple channels with DMA + - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels + - test_firmware: fix missing unlock on error in config_num_requests_store() + - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened + - Input: synaptics-rmi4 - do not delete interrupt memory too early + - x86/efi: Clarify that reset attack mitigation needs appropriate userspace + - Linux 4.15.1 + + * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume + (LP: #1744712) + - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume" + - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten" + version + + * apparmor profile load in stacked policy container fails (LP: #1746463) + - SAUCE: apparmor: fix display of .ns_name for containers + + -- Seth Forshee Sun, 04 Feb 2018 11:56:32 +0100 + +linux (4.15.0-6.7) bionic; urgency=low + + * upload urgency should be medium by default (LP: #1745338) + - [Packaging] update urgency to medium by default + + * Shutdown hang on 16.04 with iscsi targets (LP: #1569925) + - scsi: libiscsi: Allow sd_shutdown on bad transport + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1 + - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM" + - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default" + + [ Upstream Kernel Changes ] + + * Rebase to v4.15 + + -- Seth Forshee Mon, 29 Jan 2018 08:47:07 -0600 + +linux (4.15.0-5.6) bionic; urgency=low + + * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted + (LP: #1744077) + - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly + + * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC + (LP: #1743638) + - [d-i] Add qede to nic-modules udeb + + * boot failure on AMD Raven + WesternXT (LP: #1742759) + - SAUCE: drm/amdgpu: add atpx quirk handling (v2) + + * Unable to handle kernel NULL pointer dereference at isci_task_abort_task + (LP: #1726519) + - SAUCE: Revert "scsi: libsas: allow async aborts" + + * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939) + - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y + + * Miscellaneous Ubuntu changes + - Rebase to v4.15-rc7 + - [Config] CONFIG_CPU_ISOLATION=y + - [Config] Update annotations following config review + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - ubuntu: vbox -- update to 5.2.6-dfsg-1 + - ubuntu: vbox: build fixes for 4.15 + - ubuntu: vbox -- update to 5.2.6-dfsg-2 + - hio: updates for timer api changes in 4.15 + - enable hio build + - Rebase to v4.15-rc9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc9 + + -- Seth Forshee Mon, 22 Jan 2018 10:16:05 -0600 + +linux (4.15.0-4.5) bionic; urgency=low + + * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device (LP: #1741166) + - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010 + + * External HDMI monitor failed to show screen on Lenovo X1 series + (LP: #1738523) + - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series + + * Miscellaneous Ubuntu changes + - [Debian] autoreconstruct - add resoration of execute permissions + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Wed, 10 Jan 2018 10:24:22 -0600 + +linux (4.15.0-3.4) bionic; urgency=low + + * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281) + - SAUCE: make sure ubuntu/xr-usb-serial builds for x86 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc6 + + -- Seth Forshee Wed, 03 Jan 2018 20:20:43 -0600 + +linux (4.15.0-2.3) bionic; urgency=low + + * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux + 4.15.0-1.2 (LP: #1737752) + - x86/mm: Unbreak modules that use the DMA API + + * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147) + - [Config] CONFIG_SPI_INTEL_SPI_*=n + + * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image + and udebs (LP: #1521712) + - [Config] Include ibmvnic in nic-modules + + * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542) + - [Config] Enable support for emulation of deprecated ARMv8 instructions + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761) + - Enable zfs build + - [Debian] add icp to zfs-modules.ignore + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Mon, 18 Dec 2017 09:27:13 -0600 + +linux (4.15.0-1.2) bionic; urgency=low + + * Disabling zfs does not always disable module checks for the zfs modules + (LP: #1737176) + - [Packaging] disable zfs module checks when zfs is disabled + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc3 + + -- Seth Forshee Sun, 10 Dec 2017 22:07:19 -0600 + +linux (4.15.0-0.1) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.2.2-dfsg-2 + - ubuntu: vbox: build fixes for 4.15 + - disable hio build + - [Config] Update kernel lockdown options to fix build errors + - Disable zfs build + - SAUCE: Import aufs driver + - [Config] Enable AUFS config options + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc2 + + -- Seth Forshee Fri, 08 Dec 2017 13:55:42 -0600 + +linux (4.14.0-11.13) bionic; urgency=low + + * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168) + + * CVE-2017-1000405 + - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Bionic update to v4.14.3 stable release (LP: #1735843) + - s390: fix transactional execution control register handling + - s390/noexec: execute kexec datamover without DAT + - s390/runtime instrumention: fix possible memory corruption + - s390/guarded storage: fix possible memory corruption + - s390/disassembler: add missing end marker for e7 table + - s390/disassembler: increase show_code buffer size + - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock + - ACPI / EC: Fix regression related to triggering source of EC event handling + - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq + - serdev: fix registration of second slave + - sched: Make resched_cpu() unconditional + - lib/mpi: call cond_resched() from mpi_powm() loop + - x86/boot: Fix boot failure when SMP MP-table is based at 0 + - x86/decoder: Add new TEST instruction pattern + - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing + - x86/entry/64: Add missing irqflags tracing to native_load_gs_index() + - perf/x86/intel: Hide TSX events when RTM is not supported + - arm64: Implement arch-specific pte_access_permitted() + - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE + - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE + - uapi: fix linux/tls.h userspace compilation error + - uapi: fix linux/rxrpc.h userspace compilation errors + - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP + - MIPS: ralink: Fix MT7628 pinmux + - MIPS: ralink: Fix typo in mt7628 pinmux function + - net: mvneta: fix handling of the Tx descriptor counter + - nbd: wait uninterruptible for the dead timeout + - nbd: don't start req until after the dead connection logic + - PM / OPP: Add missing of_node_put(np) + - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time + - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD + - PCI: hv: Use effective affinity mask + - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF + - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports + - ALSA: hda: Add Raven PCI ID + - dm integrity: allow unaligned bv_offset + - dm cache: fix race condition in the writeback mode overwrite_bio + optimisation + - dm crypt: allow unaligned bv_offset + - dm zoned: ignore last smaller runt zone + - dm mpath: remove annoying message of 'blk_get_request() returned -11' + - dm bufio: fix integer overflow when limiting maximum cache size + - ovl: Put upperdentry if ovl_check_origin() fails + - dm: allocate struct mapped_device with kvzalloc + - sched/rt: Simplify the IPI based RT balancing logic + - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver + - dm: fix race between dm_get_from_kobject() and __dm_destroy() + - dm: discard support requires all targets in a table support discards + - MIPS: Fix odd fp register warnings with MIPS64r2 + - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels + - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry + - MIPS: Fix an n32 core file generation regset support regression + - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1 + - MIPS: math-emu: Fix final emulation phase for certain instructions + - rt2x00usb: mark device removed when get ENOENT usb error + - mm/z3fold.c: use kref to prevent page free/compact race + - autofs: don't fail mount for transient error + - nilfs2: fix race condition that causes file system corruption + - fscrypt: lock mutex before checking for bounce page pool + - eCryptfs: use after free in ecryptfs_release_messaging() + - libceph: don't WARN() if user tries to add invalid key + - bcache: check ca->alloc_thread initialized before wake up it + - fs: guard_bio_eod() needs to consider partitions + - fanotify: fix fsnotify_prepare_user_wait() failure + - isofs: fix timestamps beyond 2027 + - btrfs: change how we decide to commit transactions during flushing + - f2fs: expose some sectors to user in inline data or dentry case + - NFS: Fix typo in nomigration mount option + - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()" + - nfs: Fix ugly referral attributes + - NFS: Avoid RCU usage in tracepoints + - NFS: revalidate "." etc correctly on "open". + - nfsd: deal with revoked delegations appropriately + - rtlwifi: rtl8192ee: Fix memory leak when loading firmware + - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time + - iwlwifi: fix firmware names for 9000 and A000 series hw + - md: fix deadlock error in recent patch. + - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write + - Bluetooth: btqcomsmd: Add support for BD address setup + - md/bitmap: revert a patch + - fsnotify: clean up fsnotify_prepare/finish_user_wait() + - fsnotify: pin both inode and vfsmount mark + - fsnotify: fix pinning group in fsnotify_prepare_user_wait() + - ata: fixes kernel crash while tracing ata_eh_link_autopsy event + - ext4: fix interaction between i_size, fallocate, and delalloc after a crash + - ext4: prevent data corruption with inline data + DAX + - ext4: prevent data corruption with journaling + DAX + - ALSA: pcm: update tstamp only if audio_tstamp changed + - ALSA: usb-audio: Add sanity checks to FE parser + - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU + - ALSA: usb-audio: Add sanity checks in v2 clock parsers + - ALSA: timer: Remove kernel warning at compat ioctl error paths + - ALSA: hda/realtek - Fix ALC275 no sound issue + - ALSA: hda: Fix too short HDMI/DP chmap reporting + - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization + - ALSA: hda/realtek - Fix ALC700 family no sound issue + - ASoC: sun8i-codec: Invert Master / Slave condition + - ASoC: sun8i-codec: Fix left and right channels inversion + - ASoC: sun8i-codec: Set the BCLK divider + - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method + - fix a page leak in vhost_scsi_iov_to_sgl() error recovery + - 9p: Fix missing commas in mount options + - fs/9p: Compare qid.path in v9fs_test_inode + - net/9p: Switch to wait_event_killable() + - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair() + - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics() + - scsi: lpfc: fix pci hot plug crash in timer management routines + - scsi: lpfc: fix pci hot plug crash in list_add call + - scsi: lpfc: Fix crash receiving ELS while detaching driver + - scsi: lpfc: Fix FCP hba_wqidx assignment + - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails + - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref + - iscsi-target: Fix non-immediate TMR reference leak + - target: fix null pointer regression in core_tmr_drain_tmr_list + - target: fix buffer offset in core_scsi3_pri_read_full_status + - target: Fix QUEUE_FULL + SCSI task attribute handling + - target: Fix caw_sem leak in transport_generic_request_failure + - target: Fix quiese during transport_write_pending_qf endless loop + - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK + - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid + - mtd: nand: Export nand_reset() symbol + - mtd: nand: atmel: Actually use the PM ops + - mtd: nand: omap2: Fix subpage write + - mtd: nand: Fix writing mtdoops to nand flash. + - mtd: nand: mtk: fix infinite ECC decode IRQ issue + - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence + - p54: don't unregister leds when they are not initialized + - block: Fix a race between blk_cleanup_queue() and timeout handling + - raid1: prevent freeze_array/wait_all_barriers deadlock + - genirq: Track whether the trigger type has been set + - irqchip/gic-v3: Fix ppi-partitions lookup + - lockd: double unregister of inetaddr notifiers + - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not + enabled + - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state + - KVM: SVM: obey guest PAT + - kvm: vmx: Reinstate support for CPUs without virtual NMI + - dax: fix PMD faults on zero-length files + - dax: fix general protection fault in dax_alloc_inode + - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status + - clk: ti: dra7-atl-clock: fix child-node lookups + - libnvdimm, dimm: clear 'locked' status on successful DIMM enable + - libnvdimm, pfn: make 'resource' attribute only readable by root + - libnvdimm, namespace: fix label initialization to use valid seq numbers + - libnvdimm, region : make 'resource' attribute only readable by root + - libnvdimm, namespace: make 'resource' attribute only readable by root + - svcrdma: Preserve CB send buffer across retransmits + - IB/srpt: Do not accept invalid initiator port names + - IB/cm: Fix memory corruption in handling CM request + - IB/hfi1: Fix incorrect available receive user context count + - IB/srp: Avoid that a cable pull can trigger a kernel crash + - IB/core: Avoid crash on pkey enforcement failed in received MADs + - IB/core: Only maintain real QPs in the security lists + - NFC: fix device-allocation error return + - spi-nor: intel-spi: Fix broken software sequencing codes + - i40e: Use smp_rmb rather than read_barrier_depends + - igb: Use smp_rmb rather than read_barrier_depends + - igbvf: Use smp_rmb rather than read_barrier_depends + - ixgbevf: Use smp_rmb rather than read_barrier_depends + - i40evf: Use smp_rmb rather than read_barrier_depends + - fm10k: Use smp_rmb rather than read_barrier_depends + - ixgbe: Fix skb list corruption on Power systems + - parisc: Fix validity check of pointer size argument in new CAS + implementation + - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX + - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX + - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id() + - powerpc/signal: Properly handle return value from uprobe_deny_signal() + - powerpc/64s: Fix masking of SRR1 bits on instruction fault + - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix 512T hint detection to use >= 128T + - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix fork() with 512TB process address space + - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary + - media: Don't do DMA on stack for firmware upload in the AS102 driver + - media: rc: check for integer overflow + - media: rc: nec decoder should not send both repeat and keycode + - cx231xx-cards: fix NULL-deref on missing association descriptor + - media: v4l2-ctrl: Fix flags field on Control events + - media: venus: fix wrong size on dma_free + - media: venus: venc: fix bytesused v4l2_plane field + - media: venus: reimplement decoder stop command + - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory + zone + - iwlwifi: fix wrong struct for a000 device + - iwlwifi: add a new a000 device + - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons + - iwlwifi: add new cards for a000 series + - iwlwifi: add new cards for 8265 series + - iwlwifi: add new cards for 8260 series + - iwlwifi: fix PCI IDs and configuration mapping for 9000 series + - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command + - e1000e: Fix error path in link detection + - e1000e: Fix return value test + - e1000e: Separate signaling for link check/link up + - e1000e: Avoid receiver overrun interrupt bursts + - e1000e: fix buffer overrun while the I219 is processing DMA transactions + - Linux 4.14.3 + + * Miscellaneous Ubuntu changes + - SAUCE: s390/topology: don't inline cpu_to_node + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 04 Dec 2017 09:08:07 -0600 + +linux (4.14.0-10.12) bionic; urgency=low + + * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901) + + * Miscellaneous Ubuntu changes + - SAUCE: Enable the ACPI kernel debugger and acpidbg tool + - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package + + -- Seth Forshee Tue, 28 Nov 2017 08:46:49 -0600 + +linux (4.14.0-9.11) bionic; urgency=low + + * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728) + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to + 0.7.3-1ubuntu1" + + -- Seth Forshee Mon, 27 Nov 2017 12:44:48 -0600 + +linux (4.14.0-8.10) bionic; urgency=low + + * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695) + + * Bionic update to v4.14.2 stable release (LP: #1734694) + - bio: ensure __bio_clone_fast copies bi_partno + - af_netlink: ensure that NLMSG_DONE never fails in dumps + - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets + - net: cdc_ncm: GetNtbFormat endian fix + - fealnx: Fix building error on MIPS + - net/sctp: Always set scope_id in sctp_inet6_skb_msgname + - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS + - serial: omap: Fix EFR write on RTS deassertion + - serial: 8250_fintek: Fix finding base_port with activated SuperIO + - tpm-dev-common: Reject too short writes + - rcu: Fix up pending cbs check in rcu_prepare_for_idle + - mm/pagewalk.c: report holes in hugetlb ranges + - ocfs2: fix cluster hang after a node dies + - ocfs2: should wait dio before inode lock in ocfs2_setattr() + - ipmi: fix unsigned long underflow + - mm/page_alloc.c: broken deferred calculation + - mm/page_ext.c: check if page_ext is not prepared + - coda: fix 'kernel memory exposure attempt' in fsync + - ipmi: Prefer ACPI system interfaces over SMBIOS ones + - Linux 4.14.2 + + * Bionic update to v4.14.1 stable release (LP: #1734693) + - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present + - dmaengine: dmatest: warn user when dma test times out + - media: imon: Fix null-ptr-deref in imon_probe + - media: dib0700: fix invalid dvb_detach argument + - crypto: dh - Fix double free of ctx->p + - crypto: dh - Don't permit 'p' to be 0 + - crypto: dh - Don't permit 'key' or 'g' size longer than 'p' + - crypto: brcm - Explicity ACK mailbox message + - USB: early: Use new USB product ID and strings for DbC device + - USB: usbfs: compute urb->actual_length for isochronous + - USB: Add delay-init quirk for Corsair K70 LUX keyboards + - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst + - USB: serial: metro-usb: stop I/O after failed open + - USB: serial: Change DbC debug device binding ID + - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update + - USB: serial: garmin_gps: fix I/O after failed probe and remove + - USB: serial: garmin_gps: fix memory leak on probe errors + - selftests/x86/protection_keys: Fix syscall NR redefinition warnings + - x86/MCE/AMD: Always give panic severity for UC errors in kernel context + - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface + - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table + - HID: cp2112: add HIDRAW dependency + - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection + - rpmsg: glink: Add missing MODULE_LICENSE + - staging: wilc1000: Fix bssid buffer offset in Txq + - staging: sm750fb: Fix parameter mistake in poke32 + - staging: ccree: fix 64 bit scatter/gather DMA ops + - staging: greybus: spilib: fix use-after-free after deregistration + - staging: rtl8188eu: Revert 4 commits breaking ARP + - spi: fix use-after-free at controller deregistration + - sparc32: Add cmpxchg64(). + - sparc64: mmu_context: Add missing include files + - sparc64: Fix page table walk for PUD hugepages + - Linux 4.14.1 + + * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660) + - [Config]: Set PANIC_TIMEOUT=10 on ppc64el + + * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users + (LP: #1732627) + - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 27 Nov 2017 07:43:44 -0600 + +linux (4.14.0-7.9) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: add base infastructure for socket mediation + - SAUCE: apparmor: af_unix mediation + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: manage task security blobs + - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs + - SAUCE: LSM stacking: LSM: general but not extreme module stacking + - SAUCE: LSM stacking: LSM: Complete task_alloc hook + - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: check for invalid zero sized writes + - [Config] Run updateconfigs after merging LSM stacking + - [Config] CONFIG_AMD_MEM_ENCRYPT=y + + [ Upstream Kernel Changes ] + + * Rebase to v4.14 + + -- Seth Forshee Mon, 13 Nov 2017 08:12:08 -0600 + +linux (4.14.0-6.8) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: add workarounds to enable ZFS for 4.14 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc8 + + -- Seth Forshee Mon, 06 Nov 2017 11:39:00 -0600 + +linux (4.14.0-5.7) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Fix invocation of dh_prep for dbgsym packages + + -- Seth Forshee Tue, 31 Oct 2017 07:07:23 -0500 + +linux (4.14.0-4.5) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Packaging] virtualbox -- reduce in kernel module versions + - vbox-update: Fix up KERN_DIR definitions + - ubuntu: vbox -- update to 5.2.0-dfsg-2 + - [Config] CONFIG_AMD_MEM_ENCRYPT=n + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc7 + + -- Seth Forshee Mon, 30 Oct 2017 13:29:20 -0500 + +linux (4.14.0-3.4) artful; urgency=low + + * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986) + - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3 + - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI + - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280 + + * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070) + - powerpc/64s: Add workaround for P9 vector CI load issue + + * Miscellaneous Ubuntu changes + - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties + - [Config] CONFIG_DRM_VBOXVIDEO=m + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Config] Reorder annotations file after enabling aufs + - vbox-update: Disable imported vboxvideo module + - ubuntu: vbox -- update to 5.1.30-dfsg-1 + - Enable vbox + - hio: Use correct sizes when initializing ssd_index_bits* arrays + - hio: Update io stat accounting for 4.14 + - Enable hio + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc5 + * Rebase to v4.14-rc6 + + -- Seth Forshee Mon, 23 Oct 2017 13:53:52 -0500 + +linux (4.14.0-2.3) artful; urgency=low + + * [Bug] USB controller failed to respond on Denverton after loading + intel_th_pci module (LP: #1715833) + - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH + + * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu + 17.10 (kernel 4.13) (LP: #1719290) + - SAUCE: s390: update zfcpdump_defconfig + + * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466) + - d-i: Add bnxt_en to nic-modules. + + * Miscellaneous Ubuntu changes + - [Config] Update annotations for 4.14-rc2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc3 + * Rebase to v4.14-rc4 + + -- Seth Forshee Wed, 11 Oct 2017 16:04:27 -0500 + +linux (4.14.0-1.2) artful; urgency=low + + * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045) + - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor + + * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091) + - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev + + * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland + (LP: #1718679) + - [Config] CONFIG_DRM_VBOXVIDEO=n + + * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734) + - [Config] Disable CONFIG_IPMMU_VMSA on arm64 + + * autopkgtest profile fails to build on armhf (LP: #1717920) + - [Packaging] autopkgtest -- disable d-i when dropping flavours + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_I2C_XLP9XX=m + - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc2 + + -- Seth Forshee Fri, 29 Sep 2017 09:09:11 -0400 + +linux (4.14.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable vbox build + - Disable hio build + - Disable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc1 + + -- Seth Forshee Tue, 19 Sep 2017 20:22:29 -0500 + +linux (4.13.0-11.12) artful; urgency=low + + * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699) + + * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399) + - s390/mm: fix local TLB flushing vs. detach of an mm address space + - s390/mm: fix race on mm->context.flush_mm + + * CVE-2017-1000251 + - Bluetooth: Properly check L2CAP config option output buffer length + + -- Seth Forshee Tue, 12 Sep 2017 10:18:38 -0500 + +linux (4.13.0-10.11) artful; urgency=low + + * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287) + + * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093) + - [Packaging] Add aufs-dkms to the Provides: for kernel packages + + * Artful update to v4.13.1 stable release (LP: #1716284) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + - USB: serial: option: add support for D-Link DWM-157 C1 + - usb: Add device quirk for Logitech HD Pro Webcam C920-C + - usb:xhci:Fix regression when ATI chipsets detected + - USB: musb: fix external abort on suspend + - ANDROID: binder: add padding to binder_fd_array_object. + - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES. + - USB: core: Avoid race of async_completed() w/ usbdev_release() + - staging/rts5208: fix incorrect shift to extract upper nybble + - staging: ccree: save ciphertext for CTS IV + - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks + - iio: adc: ti-ads1015: fix incorrect data rate setting update + - iio: adc: ti-ads1015: fix scale information for ADS1115 + - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set + - iio: adc: ti-ads1015: avoid getting stale result after runtime resume + - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks + - iio: adc: ti-ads1015: add adequate wait time to get correct conversion + - driver core: bus: Fix a potential double free + - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage + - binder: free memory on error + - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y + - crypto: caam/qi - fix compilation with DEBUG enabled + - thunderbolt: Fix reset response_type + - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock + - intel_th: pci: Add Cannon Lake PCH-H support + - intel_th: pci: Add Cannon Lake PCH-LP support + - ath10k: fix memory leak in rx ring buffer allocation + - drm/vgem: Pin our pages for dmabuf exports + - drm/ttm: Fix accounting error when fail to get pages for pool + - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly + - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter + - Bluetooth: Add support of 13d3:3494 RTL8723BE device + - iwlwifi: pci: add new PCI ID for 7265D + - dlm: avoid double-free on error path in dlm_device_{register,unregister} + - mwifiex: correct channel stat buffer overflows + - MCB: add support for SC31 to mcb-lpc + - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs + - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default + - drm/nouveau: Fix error handling in nv50_disp_atomic_commit + - workqueue: Fix flag collision + - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme + - cs5536: add support for IDE controller variant + - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE + - scsi: sg: recheck MMAP_IO request length with lock held + - of/device: Prevent buffer overflow in of_device_modalias() + - rtlwifi: Fix memory leak when firmware request fails + - rtlwifi: Fix fallback firmware loading + - Linux 4.13.1 + + * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + + * SRIOV: warning if unload VFs (LP: #1715073) + - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources + + * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578) + - i40e: avoid NVM acquire deadlock during NVM update + - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq + + * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted + twice when perf stat is done (perf:) (LP: #1714571) + - perf vendor events powerpc: Remove duplicate events + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Include vmd in storage-core-modules udeb + + * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064) + - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle + - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug + - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state + offline + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + + -- Seth Forshee Sun, 10 Sep 2017 17:48:59 -0500 + +linux (4.13.0-9.10) artful; urgency=low + + * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145) + + * EDAC sbridge: Failed to register device with error -22. (LP: #1714112) + - [Config] CONFIG_EDAC_GHES=n + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13 + + -- Seth Forshee Tue, 05 Sep 2017 07:51:19 -0500 + +linux (4.13.0-8.9) artful; urgency=low + + * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103) + - SAUCE: apparmor: fix apparmorfs DAC access, permissions + + * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137) + - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64 + + * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping + Harrisonville SDP (LP: #1709257) + - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake + - EDAC, pnd2: Mask off the lower four bits of a BAR + - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR + - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device + - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after + reading BAR + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - SAUCE: selftests/powerpc: Disable some ptrace selftests + - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x + - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el + - [Config] Disable CONFIG_MDIO_* options for s390x + - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x + - [Config] Update annotations for 4.13 + + -- Seth Forshee Thu, 31 Aug 2017 14:27:09 -0500 + +linux (4.13.0-7.8) artful; urgency=low + + * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904) + - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface + paths + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled" + + * Miscellaneous upstream changes + - seccomp: Provide matching filter for introspection + - seccomp: Sysctl to display available actions + - seccomp: Operation for checking if an action is available + - seccomp: Sysctl to configure actions that are allowed to be logged + - seccomp: Selftest for detection of filter flag support + - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW + - seccomp: Action to log before allowing + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc7 + + -- Seth Forshee Mon, 28 Aug 2017 08:12:24 -0500 + +linux (4.13.0-6.7) artful; urgency=low + + * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481) + - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A + + * sort ABI files with C.UTF-8 locale (LP: #1712345) + - [Packaging] sort ABI files with C.UTF-8 locale + + * igb: Support using Broadcom 54616 as PHY (LP: #1712024) + - SAUCE: igb: add support for using Broadcom 54616 as PHY + + * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220) + - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes + - powerpc/mm/radix: Improve TLB/PWC flushes + - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range + + * Linux 4.12 refuses to load self-signed modules under Secure Boot with + properly enrolled keys (LP: #1712168) + - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification + + * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432) + - [Config] CONFIG_BLK_DEV_NVME=m for s390 + + * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0 + (LP: #1711298) + - [Config] CONFIG_INTEL_ATOMISP=n + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: af_unix mediation + + * Miscellaneous upstream changes + - apparmor: Fix shadowed local variable in unpack_trans_table() + - apparmor: Fix logical error in verify_header() + - apparmor: Fix an error code in aafs_create() + - apparmor: Redundant condition: prev_ns. in [label.c:1498] + - apparmor: add the ability to mediate signals + - apparmor: add mount mediation + - apparmor: cleanup conditional check for label in label_print + - apparmor: add support for absolute root view based labels + - apparmor: make policy_unpack able to audit different info messages + - apparmor: add more debug asserts to apparmorfs + - apparmor: add base infastructure for socket mediation + - apparmor: move new_null_profile to after profile lookup fns() + - apparmor: fix race condition in null profile creation + - apparmor: ensure unconfined profiles have dfas initialized + - apparmor: fix incorrect type assignment when freeing proxies + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc6 + + -- Seth Forshee Wed, 23 Aug 2017 08:10:38 -0500 + +linux (4.13.0-5.6) artful; urgency=low + + * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630) + - perf pmu-events: Support additional POWER8+ PVR in mapfile + - perf vendor events: Add POWER9 PMU events + - perf vendor events: Add POWER9 PVRs to mapfile + - SAUCE: perf vendor events powerpc: remove suffix in mapfile + - SAUCE: perf vendor events powerpc: Update POWER9 events + + * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171) + - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el + + * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for + kernels able to boot without initramfs (LP: #1700972) + - [Debian] Don't depend on initramfs-tools + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - SAUCE: aufs -- Add missing argument to loop_switch() call + - [Config] Enable aufs + - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3 + - Enable zfs build + - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall() + - [Packaging] switch up to debhelper 9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc5 + + -- Seth Forshee Tue, 15 Aug 2017 09:24:16 -0500 + +linux (4.13.0-4.5) artful; urgency=low + + * Lenovo Yoga 910 Sensors (LP: #1708120) + - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Add vmd driver to generic inclusion list + + * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430) + - [Config] CONFIG_SATA_HIGHBANK=y + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-1 + - SAUCE: hio: Build fixes for 4.13 + - Enable hio build + - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1 + - [debian] use all rather than amd64 dkms debs for sync + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc4 + + -- Seth Forshee Tue, 08 Aug 2017 11:31:48 -0500 + +linux (4.13.0-3.4) artful; urgency=low + + * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495) + - [Packaging] tests -- reduce rebuild test to one flavour + - [Packaging] tests -- reduce rebuild test to one flavour -- use filter + + * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158) + - SAUCE: virtio_net: Revert mergeable buffer handling rework + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc3 + + -- Seth Forshee Mon, 31 Jul 2017 10:08:16 -0500 + +linux (4.13.0-2.3) artful; urgency=low + + * Change CONFIG_IBMVETH to module (LP: #1704479) + - [Config] CONFIG_IBMVETH=m + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc2 + + -- Seth Forshee Mon, 24 Jul 2017 13:58:08 -0500 + +linux (4.13.0-1.2) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Support sphinx-based kernel documentation + + -- Seth Forshee Thu, 20 Jul 2017 09:18:33 -0500 + +linux (4.13.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable hio + - Disable zfs build + - ubuntu: vbox -- update to 5.1.24-dfsg-1 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc1 + + -- Seth Forshee Wed, 19 Jul 2017 15:09:31 -0500 + +linux (4.12.0-7.8) artful; urgency=low + + * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on + (LP: #1673564) + - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding + - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers + - KVM: arm64: Make kvm_condition_valid32() accessible from EL2 + - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2 + - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler + - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers + - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line + - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler + - KVM: arm64: vgic-v3: Add misc Group-0 handlers + - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers + - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line + - arm64: Add MIDR values for Cavium cn83XX SoCs + - arm64: Add workaround for Cavium Thunder erratum 30115 + - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler + - KVM: arm64: Enable GICv3 common sysreg trapping via command-line + - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped + - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access + - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access + + * hns: under heavy load, NIC may fail and require reboot (LP: #1704146) + - net: hns: Bugfix for Tx timeout handling in hns driver + + * New ACPI identifiers for ThunderX SMMU (LP: #1703437) + - iommu/arm-smmu: Plumb in new ACPI identifiers + + * Transparent hugepages should default to enabled=madvise (LP: #1703742) + - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default + + * Artful update to v4.12.1 stable release (LP: #1703858) + - driver core: platform: fix race condition with driver_override + - RDMA/uverbs: Check port number supplied by user verbs cmds + - usb: dwc3: replace %p with %pK + - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + - usb: usbip: set buffer pointers to NULL after free + - Add USB quirk for HVR-950q to avoid intermittent device resets + - usb: Fix typo in the definition of Endpoint[out]Request + - USB: core: fix device node leak + - USB: serial: option: add two Longcheer device ids + - USB: serial: qcserial: new Sierra Wireless EM7305 device ID + - xhci: Limit USB2 port wake support for AMD Promontory hosts + - gfs2: Fix glock rhashtable rcu bug + - Add "shutdown" to "struct class". + - tpm: Issue a TPM2_Shutdown for TPM2 devices. + - tpm: fix a kernel memory leak in tpm-sysfs.c + - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error + - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings + - sched/fair, cpumask: Export for_each_cpu_wrap() + - sched/core: Implement new approach to scale select_idle_cpu() + - sched/numa: Use down_read_trylock() for the mmap_sem + - sched/numa: Override part of migrate_degrades_locality() when idle balancing + - sched/fair: Simplify wake_affine() for the single socket case + - sched/numa: Implement NUMA node level wake_affine() + - sched/fair: Remove effective_load() + - sched/numa: Hide numa_wake_affine() from UP build + - xen: avoid deadlock in xenbus driver + - crypto: drbg - Fixes panic in wait_for_completion call + - Linux 4.12.1 + + * cxlflash update request in the Xenial SRU stream (LP: #1702521) + - scsi: cxlflash: Combine the send queue locks + - scsi: cxlflash: Update cxlflash_afu_sync() to return errno + - scsi: cxlflash: Reset hardware queue context via specified register + - scsi: cxlflash: Schedule asynchronous reset of the host + - scsi: cxlflash: Handle AFU sync failures + - scsi: cxlflash: Track pending scsi commands in each hardware queue + - scsi: cxlflash: Flush pending commands in cleanup path + - scsi: cxlflash: Add scsi command abort handler + - scsi: cxlflash: Create character device to provide host management interface + - scsi: cxlflash: Separate AFU internal command handling from AFU sync + specifics + - scsi: cxlflash: Introduce host ioctl support + - scsi: cxlflash: Refactor AFU capability checking + - scsi: cxlflash: Support LUN provisioning + - scsi: cxlflash: Support AFU debug + - scsi: cxlflash: Support WS16 unmap + - scsi: cxlflash: Remove zeroing of private command data + - scsi: cxlflash: Update TMF command processing + - scsi: cxlflash: Avoid double free of character device + - scsi: cxlflash: Update send_tmf() parameters + - scsi: cxlflash: Update debug prints in reset handlers + + * make snap-pkg support (LP: #1700747) + - make snap-pkg support + + * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706) + - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge + + * arm64: fix crash reading /proc/kcore (LP: #1702749) + - fs/proc: kcore: use kcore_list type to check for vmalloc/module address + - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT + + * Opal and POWER9 DD2 (LP: #1702159) + - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9 + + * Data corruption with hio driver (LP: #1701316) + - SAUCE: hio: Fix incorrect use of enum req_opf values + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2 + - snapcraft.yaml: Sync with xenial + - [Config] CONFIG_CAVIUM_ERRATUM_30115=y + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and + MokSBState" + + -- Seth Forshee Fri, 14 Jul 2017 15:25:41 -0500 + +linux (4.12.0-6.7) artful; urgency=low + + * update ENA driver to 1.2.0k from net-next (LP: #1701575) + - net: ena: change return value for unsupported features unsupported return + value + - net: ena: add hardware hints capability to the driver + - net: ena: change sizeof() argument to be the type pointer + - net: ena: add reset reason for each device FLR + - net: ena: add support for out of order rx buffers refill + - net: ena: allow the driver to work with small number of msix vectors + - net: ena: use napi_schedule_irqoff when possible + - net: ena: separate skb allocation to dedicated function + - net: ena: use lower_32_bits()/upper_32_bits() to split dma address + - net: ena: update driver's rx drop statistics + - net: ena: update ena driver to version 1.2.0 + + * APST gets enabled against explicit kernel option (LP: #1699004) + - nvme: explicitly disable APST on quirked devices + + * Miscellaneous Ubuntu changes + - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40) + - SAUCE: hio updates for 4.12 + - SAUCE: Enable hio build + + -- Seth Forshee Wed, 05 Jul 2017 14:23:20 -0500 + +linux (4.12.0-5.6) artful; urgency=low + + * ERAT invalidate on context switch removal (LP: #1700819) + - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1 + + * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521) + - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9 + + * Miscellaneous Ubuntu changes + - d-i: Move qcom-emac from arm64 to shared nic-modules + + [ Upstream Kernel Changes ] + + * Rebase to v4.12 + + -- Seth Forshee Mon, 03 Jul 2017 07:52:02 -0500 + +linux (4.12.0-4.5) artful; urgency=low + + * aacraid driver may return uninitialized stack data to userspace + (LP: #1700077) + - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace + + * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651) + - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device + + * AACRAID for power9 platform (LP: #1689980) + - scsi: aacraid: Remove __GFP_DMA for raw srb memory + - scsi: aacraid: Fix DMAR issues with iommu=pt + - scsi: aacraid: Added 32 and 64 queue depth for arc natives + - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks + - scsi: aacraid: Remove reset support from check_health + - scsi: aacraid: Change wait time for fib completion + - scsi: aacraid: Log count info of scsi cmds before reset + - scsi: aacraid: Print ctrl status before eh reset + - scsi: aacraid: Using single reset mask for IOP reset + - scsi: aacraid: Rework IOP reset + - scsi: aacraid: Add periodic checks to see IOP reset status + - scsi: aacraid: Rework SOFT reset code + - scsi: aacraid: Rework aac_src_restart + - scsi: aacraid: Use correct function to get ctrl health + - scsi: aacraid: Make sure ioctl returns on controller reset + - scsi: aacraid: Enable ctrl reset for both hba and arc + - scsi: aacraid: Add reset debugging statements + - scsi: aacraid: Remove reference to Series-9 + - scsi: aacraid: Update driver version to 50834 + + * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700) + - SAUCE: drm: hibmc: Use set_busid function from drm core + + * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954) + - d-i: Add hibmc-drm to kernel-image udeb + + * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844) + - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2 + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x + - [Config] CONFIG_ATA=n for s390x + - [Config] Update annotations for 4.12 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc7 + + -- Seth Forshee Mon, 26 Jun 2017 11:27:29 -0500 + +linux (4.12.0-3.4) artful; urgency=low + + * Miscellaneous upstream changes + - ufs: fix the logics for tail relocation + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc6 + + -- Seth Forshee Mon, 19 Jun 2017 14:50:39 -0500 + +linux (4.12.0-2.3) artful; urgency=low + + * CVE-2014-9900 + - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in + ethtool_get_wol() + + * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen) + (LP: #1671360) + - pinctrl/amd: Use regular interrupt instead of chained + + * extend-diff-ignore should use exact matches (LP: #1693504) + - [Packaging] exact extend-diff-ignore matches + + * Miscellaneous Ubuntu changes + - SAUCE: efi: Don't print secure boot state from the efi stub + - ubuntu: vbox -- Update to 5.1.22-dfsg-1 + - SAUCE: vbox fixes for 4.12 + - Re-enable virtualbox build + - [Config] CONFIG_ORANGEFS_FS=m + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7 + - Enable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc4 + * Rebase to v4.12-rc5 + + -- Seth Forshee Sun, 11 Jun 2017 22:25:13 -0500 + +linux (4.12.0-1.2) artful; urgency=low + + * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337) + - [Config] Enable CONFIG_DRM_MGAG200 as module + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_LIBIO=y on arm64 only + - SAUCE: LIBIO: Introduce a generic PIO mapping method + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07 + - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host + I/O + - SAUCE: LPC: Add the ACPI LPC support + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO + + * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325) + - SAUCE: tty: Fix ldisc crash on reopened tty + + * Miscellaneous Ubuntu changes + - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa' + - Rebase to v4.12-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc3 + + -- Seth Forshee Mon, 29 May 2017 20:56:29 -0500 + +linux (4.12.0-0.1) artful; urgency=low + + * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614) + - [Config] CONFIG_ARM64_LSE_ATOMICS=y + + * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914) + - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64 + + * exec'ing a setuid binary from a threaded program sometimes fails to setuid + (LP: #1672819) + - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct + + * Miscellaneous Ubuntu changes + - Update find-missing-sauce.sh to compare to artful + - Update dropped.txt + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Disable virtualbox build + - Disable hio build + - SAUCE: securityfs: Replace CURRENT_TIME with current_time() + - Disable zfs build + - [Debian] Work out upstream tag for use with gen-auto-reconstruct + - SAUCE: Import aufs driver + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + - [Config] Enable aufs + - SAUCE: perf callchain: Include errno.h on x86 unconditinally + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc2 + + -- Seth Forshee Sun, 21 May 2017 23:44:44 -0500 + +linux (4.11.0-3.8) artful; urgency=low + + [ Seth Forshee ] + + * Release Tracking Bug + - LP: #1690999 + + * apparmor_parser hangs indefinitely when called by multiple threads + (LP: #1645037) + - SAUCE: apparmor: fix lock ordering for mkdir + + * apparmor leaking securityfs pin count (LP: #1660846) + - SAUCE: apparmor: fix leak on securityfs pin count + + * apparmor reference count leak when securityfs_setup_d_inode\ () fails + (LP: #1660845) + - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode() + fails + + * apparmor not checking error if security_pin_fs() fails (LP: #1660842) + - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails + + * libvirt profile is blocking global setrlimit despite having no rlimit rule + (LP: #1679704) + - SAUCE: apparmor: fix complain mode failure for rlimit mediation + - apparmor: update auditing of rlimit check to provide capability information + + * apparmor: does not provide a way to detect policy updataes (LP: #1678032) + - SAUCE: apparmor: add policy revision file interface + + * apparmor does not make support of query data visible (LP: #1678023) + - SAUCE: apparmor: add label data availability to the feature set + + * apparmor query interface does not make supported query info available + (LP: #1678030) + - SAUCE: apparmor: add information about the query inteface to the feature set + + * change_profile incorrect when using namespaces with a compound stack + (LP: #1677959) + - SAUCE: apparmor: fix label parse for stacked labels + + * Regression in 4.4.0-65-generic causes very frequent system crashes + (LP: #1669611) + - apparmor: sync of apparmor 3.6+ (17.04) + + * Artful update to 4.11.1 stable release (LP: #1690814) + - dm ioctl: prevent stack leak in dm ioctl call + - drm/sti: fix GDP size to support up to UHD resolution + - power: supply: lp8788: prevent out of bounds array access + - brcmfmac: Ensure pointer correctly set if skb data location changes + - brcmfmac: Make skb header writable before use + - sparc64: fix fault handling in NGbzero.S and GENbzero.S + - refcount: change EXPORT_SYMBOL markings + - net: macb: fix phy interrupt parsing + - tcp: fix access to sk->sk_state in tcp_poll() + - geneve: fix incorrect setting of UDP checksum flag + - bpf: enhance verifier to understand stack pointer arithmetic + - bpf, arm64: fix jit branch offset related to ldimm64 + - tcp: fix wraparound issue in tcp_lp + - net: ipv6: Do not duplicate DAD on link up + - net: usb: qmi_wwan: add Telit ME910 support + - tcp: do not inherit fastopen_req from parent + - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header + - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string + - ipv6: initialize route null entry in addrconf_init() + - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf + - tcp: randomize timestamps on syncookies + - bnxt_en: allocate enough space for ->ntp_fltr_bmap + - bpf: don't let ldimm64 leak map addresses on unprivileged + - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path + - f2fs: sanity check segment count + - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..." + - xen: Revert commits da72ff5bfcb0 and 72a9b186292d + - block: get rid of blk_integrity_revalidate() + - Linux 4.11.1 + + * Module signing exclusion for staging drivers does not work properly + (LP: #1690908) + - SAUCE: Fix module signing exclusion in package builds + + * perf: qcom: Add L3 cache PMU driver (LP: #1689856) + - [Config] CONFIG_QCOM_L3_PMU=y + - perf: qcom: Add L3 cache PMU driver + + * No PMU support for ACPI-based arm64 systems (LP: #1689661) + - drivers/perf: arm_pmu: rework per-cpu allocation + - drivers/perf: arm_pmu: manage interrupts per-cpu + - drivers/perf: arm_pmu: split irq request from enable + - drivers/perf: arm_pmu: remove pointless PMU disabling + - drivers/perf: arm_pmu: define armpmu_init_fn + - drivers/perf: arm_pmu: fold init into alloc + - drivers/perf: arm_pmu: factor out pmu registration + - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs() + - drivers/perf: arm_pmu: handle no platform_device + - drivers/perf: arm_pmu: rename irq request/free functions + - drivers/perf: arm_pmu: split cpu-local irq request/free + - drivers/perf: arm_pmu: move irq request/free into probe + - drivers/perf: arm_pmu: split out platform device probe logic + - arm64: add function to get a cpu's MADT GICC table + - [Config] CONFIG_ARM_PMU_ACPI=y + - drivers/perf: arm_pmu: add ACPI framework + - arm64: pmuv3: handle !PMUv3 when probing + - arm64: pmuv3: use arm_pmu ACPI framework + + * Fix NVLINK2 TCE route (LP: #1690155) + - powerpc/powernv: Fix TCE kill on NVLink2 + + * CVE-2017-0605 + - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline() + + * Miscellaneous Ubuntu changes + - [Config] Restore powerpc arch to annotations file + - [Config] Disable runtime testing modules + - [Config] Disable drivers not needed on s390x + - [Config] Update annotations for 4.11 + - [Config] updateconfigs after apparmor updates + + * Miscellaneous upstream changes + - apparmor: use SHASH_DESC_ON_STACK + - apparmor: fix invalid reference to index variable of iterator line 836 + - apparmor: fix parameters so that the permission test is bypassed at boot + - apparmor: Make path_max parameter readonly + - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show() + - apparmorfs: Use seq_putc() in two functions + - apparmor: provide information about path buffer size at boot + - apparmor: add/use fns to print hash string hex value + + -- Seth Forshee Tue, 16 May 2017 00:39:13 -0500 + +linux (4.11.0-2.7) artful; urgency=low + + * kernel-wedge fails in artful due to leftover squashfs-modules d-i files + (LP: #1688259) + - Remove squashfs-modules files from d-i + - [Config] as squashfs-modules is builtin kernel-image must Provides: it + + * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297) + - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform." + - d-i: initrd needs qcom_emac on amberwing platform. + + * update for V3 kernel bits and improved multiple fan slice support + (LP: #1470091) + - SAUCE: fan: tunnel multiple mapping mode (v3) + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5 + - Enable zfs + - SAUCE: fan: add VXLAN implementation + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Add EFI signature data types + - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader. + - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db + - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is + disabled + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Update dropped.txt + + [ Upstream Kernel Changes ] + + * rebase to v4.11 + + -- Seth Forshee Fri, 05 May 2017 07:43:14 -0500 + +linux (4.11.0-1.6) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Use default compression for all packages + - SAUCE: (namespace) block_dev: Support checking inode permissions in + lookup_bdev() + - SAUCE: (namespace) block_dev: Check permissions towards block device inode + when mounting + - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode + when mounting + - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes + - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root + - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb() + - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set + security.* xattrs + - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw + filesystems + - SAUCE: (namespace) fuse: Add support for pid namespaces + - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns + - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace + or a descendant + - SAUCE: (namespace) fuse: Allow user namespace mounts + - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user + namespaces + - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts + - SAUCE: (namespace) ext4: Add module parameter to enable user namespace + mounts + - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is + opened for writing + + -- Seth Forshee Wed, 26 Apr 2017 10:08:29 -0500 + +linux (4.11.0-0.5) artful; urgency=low + + * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain + (LP: #1684971) + - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain + + * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups + (LP: #1470250) + - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails + + * Enable virtual scsi server driver for Power (LP: #1615665) + - SAUCE: Return TCMU-generated sense data to fabric module + + * include/linux/security.h header syntax error with !CONFIG_SECURITYFS + (LP: #1630990) + - SAUCE: (no-up) include/linux/security.h -- fix syntax error with + CONFIG_SECURITYFS=n + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Debian] Add script to update virtualbox + - ubuntu: vbox -- Update to 5.1.20-dfsg-2 + - Enable vbox + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc8 + + -- Seth Forshee Tue, 25 Apr 2017 13:42:54 -0500 + +linux (4.11.0-0.4) zesty; urgency=low + + * POWER9: Improve performance on memory management (LP: #1681429) + - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm + flush + - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync + + * Miscellaneous Ubuntu changes + - find-missing-sauce.sh + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc7 + + -- Seth Forshee Tue, 18 Apr 2017 08:19:43 -0500 + +linux (4.11.0-0.3) zesty; urgency=low + + * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888) + - [Config] Disable CONFIG_HVC_UDBG on ppc64el + + * smartpqi driver needed in initram disk and installer (LP: #1680156) + - [Config] Add smartpqi to d-i + + * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315) + - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n + + * Miscellaneous Ubuntu changes + - [Config] flash-kernel should be a Breaks + - [Config] drop the info directory + - [Config] drop NOTES as obsolete + - [Config] drop changelog.historical as obsolete + - rebase to v4.11-rc6 + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc6 + + -- Tim Gardner Tue, 11 Apr 2017 07:16:52 -0600 + +linux (4.11.0-0.2) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc5 + + -- Tim Gardner Mon, 03 Apr 2017 08:26:07 +0100 + +linux (4.11.0-0.1) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc4 + - LP: #1591053 + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 + +linux (4.11.0-0.0) zesty; urgency=low + + * dummy entry + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 --- linux-oracle-5.4.0.orig/debian.oracle/config/annotations +++ linux-oracle-5.4.0/debian.oracle/config/annotations @@ -0,0 +1,2215 @@ +# Menu: HEADER +# FORMAT: 4 +# ARCH: amd64 arm64 +# FLAVOUR: amd64-oracle arm64-oracle +# FLAVOUR_DEP: {'amd64-oracle': 'amd64-generic', 'arm64-oracle': 'arm64-generic'} + +include "../../debian.master/config/annotations" + +CONFIG_ACPI_CUSTOM_DSDT_FILE policy<{'amd64': '""', 'arm64': '""'}> +CONFIG_ACPI_CUSTOM_DSDT_FILE note<'might allow hardware damage'> + +CONFIG_ANDROID policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ANDROID note<'needed for Anbox - LP #1928686'> + +CONFIG_ANDROID_BINDERFS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ANDROID_BINDERFS note<'needed for Anbox - LP #1928686'> + +CONFIG_ANDROID_BINDER_DEVICES policy<{'amd64': '""', 'arm64': '""'}> +CONFIG_ANDROID_BINDER_DEVICES note<'needed for Anbox - LP #1928686'> + +CONFIG_ANDROID_BINDER_IPC policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ANDROID_BINDER_IPC note<'needed for Anbox - LP #1928686'> + +CONFIG_ARCH_ROCKCHIP policy<{'arm64': 'n'}> +CONFIG_ARCH_ROCKCHIP note<'LP:1566283 / LP:1825222'> + +CONFIG_ARM64_SW_TTBR0_PAN policy<{'arm64': 'y'}> +CONFIG_ARM64_SW_TTBR0_PAN note<'LP: #1968902'> + +CONFIG_ARM_SMMU policy<{'arm64': 'y'}> +CONFIG_ARM_SMMU note<'Requested by Oracle after suspected related to some boot-issues, LP #2002381'> + +CONFIG_ARM_SMMU_V3 policy<{'arm64': 'y'}> +CONFIG_ARM_SMMU_V3 note<'Requested by Oracle after suspected related to some boot-issues, LP #2002381'> + +CONFIG_ASHMEM policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ASHMEM note<'needed for Anbox - LP #1928686'> + +CONFIG_ATARI_PARTITION policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_ATARI_PARTITION note<'LP:1908264'> + +CONFIG_CPUFREQ_DT policy<{'arm64': 'n'}> +CONFIG_CPUFREQ_DT note<'not autoloadable'> + +CONFIG_FAILOVER policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_FAILOVER note<'OCI requirement'> + +CONFIG_IPMMU_VMSA policy<{'arm64': '-'}> +CONFIG_IPMMU_VMSA note<'LP:1718734'> + +CONFIG_LATENCYTOP policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_LATENCYTOP note<'not needed for cloud kernels'> + +CONFIG_MFD_TPS65217 policy<{'arm64': 'n'}> +CONFIG_MFD_TPS65217 note<'not needed for cloud kernels'> + +CONFIG_MMC_BLOCK policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_MMC_BLOCK note<'boot essential on armhf/arm64'> + +CONFIG_MTD_DOCG3 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_MTD_DOCG3 note<'LP:1792205'> + +CONFIG_NET_FAILOVER policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_NET_FAILOVER note<'OCI requirement'> + +CONFIG_PAGE_POOL policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PAGE_POOL note<'OCI requirement'> + +CONFIG_REGULATOR_TPS65217 policy<{'arm64': '-'}> +CONFIG_REGULATOR_TPS65217 note<'not needed for cloud kernels'> + +CONFIG_RTC_DRV_EFI policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_EFI note<'LP:#1583738'> + +CONFIG_RTC_DRV_TWL4030 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_TWL4030 note<'boot essential on OMAP3/OMAP4'> + +CONFIG_SAMPLE_TRACE_PRINTK policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_TRACE_PRINTK note<'Disabled for cloud kernel'> + +CONFIG_SERIAL_AMBA_PL011 policy<{'arm64': 'y'}> +CONFIG_SERIAL_AMBA_PL011 note<'needed for serial support in VMs'> + +CONFIG_SERIAL_AMBA_PL011_CONSOLE policy<{'arm64': 'y'}> +CONFIG_SERIAL_AMBA_PL011_CONSOLE note<'needed for serial support in VMs'> + +CONFIG_SERIAL_SH_SCI policy<{'arm64': '-'}> +CONFIG_SERIAL_SH_SCI note<'LP: #2022361'> + +CONFIG_SERIAL_SH_SCI_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_SH_SCI_CONSOLE note<'LP: #2022361'> + +CONFIG_SERIAL_SH_SCI_EARLYCON policy<{'arm64': '-'}> +CONFIG_SERIAL_SH_SCI_EARLYCON note<'LP: #2022361'> + +CONFIG_SND_HDA_POWER_SAVE_DEFAULT policy<{'amd64': '0', 'arm64': '0'}> +CONFIG_SND_HDA_POWER_SAVE_DEFAULT note<'LP:1804265'> + +CONFIG_SND_SOC_INTEL_CFL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_CFL note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_INTEL_CML_H policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_CML_H note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_INTEL_CML_LP policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_CML_LP note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_INTEL_CNL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_CNL note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_INTEL_SKYLAKE policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKYLAKE note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC note<'not selectable for linux-oracle'> + +CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC policy<{'amd64': 'n'}> +CONFIG_SND_SOC_SOF_HDA_COMMON_HDMI_CODEC note<'not needed for cloud kernels'> + +CONFIG_SOUNDWIRE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SOUNDWIRE note<'not needed for cloud kernels'> + +CONFIG_TEST_BLACKHOLE_DEV policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_BLACKHOLE_DEV note<'Used by net selftests'> + +CONFIG_VIDEO_VIMC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_VIDEO_VIMC note<'LP#1831482'> + +CONFIG_X86_UV policy<{'amd64': 'n'}> +CONFIG_X86_UV note<'not needed for cloud kernels'> + + +# ---- Annotations without notes ---- + +CONFIG_842_COMPRESS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_842_DECOMPRESS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACER_WIRELESS policy<{'amd64': 'n'}> +CONFIG_ACPI_CPPC_CPUFREQ policy<{'arm64': 'n'}> +CONFIG_ACPI_CPPC_LIB policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_ACPI_DEBUG policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_DEBUGGER policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_DEBUGGER_USER policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ACPI_NFIT policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_ACPI_SPCR_TABLE policy<{'amd64': 'n', 'arm64': 'y'}> +CONFIG_ACPI_TAD policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ADXL372 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_ADXL372_I2C policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_ADXL372_SPI policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_AHC1EC0_WDT policy<{'amd64': '-'}> +CONFIG_AHCI_BRCM policy<{'arm64': '-'}> +CONFIG_AHCI_CEVA policy<{'arm64': 'n'}> +CONFIG_AHCI_IMX policy<{'arm64': '-'}> +CONFIG_AHCI_MTK policy<{'arm64': '-'}> +CONFIG_AHCI_MVEBU policy<{'arm64': '-'}> +CONFIG_AHCI_QORIQ policy<{'arm64': 'n'}> +CONFIG_AHCI_SUNXI policy<{'arm64': '-'}> +CONFIG_AHCI_XGENE policy<{'arm64': '-'}> +CONFIG_AIRO_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_AK8974 policy<{'arm64': 'n'}> +CONFIG_ALTERA_PR_IP_CORE_PLAT policy<{'arm64': 'n'}> +CONFIG_AL_FIC policy<{'arm64': 'n'}> +CONFIG_AMBA_PL08X policy<{'arm64': 'n'}> +CONFIG_APQ_GCC_8084 policy<{'arm64': '-'}> +CONFIG_APQ_MMCC_8084 policy<{'arm64': '-'}> +CONFIG_ARCH_ACTIONS policy<{'arm64': 'n'}> +CONFIG_ARCH_AGILEX policy<{'arm64': 'n'}> +CONFIG_ARCH_BCM2835 policy<{'arm64': 'n'}> +CONFIG_ARCH_BCM_IPROC policy<{'arm64': 'n'}> +CONFIG_ARCH_BERLIN policy<{'arm64': 'n'}> +CONFIG_ARCH_BITMAIN policy<{'arm64': 'n'}> +CONFIG_ARCH_BRCMSTB policy<{'arm64': 'n'}> +CONFIG_ARCH_HAS_PMEM_API policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_ARCH_HAS_RESET_CONTROLLER policy<{'arm64': '-'}> +CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_ARCH_HISI policy<{'arm64': 'n'}> +CONFIG_ARCH_K3 policy<{'arm64': 'n'}> +CONFIG_ARCH_K3_AM6_SOC policy<{'arm64': '-'}> +CONFIG_ARCH_K3_J721E_SOC policy<{'arm64': '-'}> +CONFIG_ARCH_LAYERSCAPE policy<{'arm64': 'n'}> +CONFIG_ARCH_LG1K policy<{'arm64': 'n'}> +CONFIG_ARCH_MEDIATEK policy<{'arm64': 'n'}> +CONFIG_ARCH_MESON policy<{'arm64': 'n'}> +CONFIG_ARCH_MMAP_RND_BITS policy<{'amd64': '28', 'arm64': '28'}> +CONFIG_ARCH_MVEBU policy<{'arm64': 'n'}> +CONFIG_ARCH_MXC policy<{'arm64': 'n'}> +CONFIG_ARCH_QCOM policy<{'arm64': 'n'}> +CONFIG_ARCH_R8A774A1 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A774C0 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A7795 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A7796 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A77965 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A77970 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A77980 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A77990 policy<{'arm64': '-'}> +CONFIG_ARCH_R8A77995 policy<{'arm64': '-'}> +CONFIG_ARCH_RCAR_GEN3 policy<{'arm64': '-'}> +CONFIG_ARCH_REALTEK policy<{'arm64': 'n'}> +CONFIG_ARCH_RENESAS policy<{'arm64': 'n'}> +CONFIG_ARCH_SEATTLE policy<{'arm64': 'n'}> +CONFIG_ARCH_SPRD policy<{'arm64': 'n'}> +CONFIG_ARCH_STRATIX10 policy<{'arm64': 'n'}> +CONFIG_ARCH_SUNXI policy<{'arm64': 'n'}> +CONFIG_ARCH_SYNQUACER policy<{'arm64': 'n'}> +CONFIG_ARCH_THUNDER policy<{'arm64': 'n'}> +CONFIG_ARCH_THUNDER2 policy<{'arm64': 'n'}> +CONFIG_ARCH_VEXPRESS policy<{'arm64': 'n'}> +CONFIG_ARCH_XGENE policy<{'arm64': 'n'}> +CONFIG_ARCH_ZYNQMP policy<{'arm64': 'n'}> +CONFIG_ARCNET_COM20020_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ARCX_ANYBUS_CONTROLLER policy<{'arm64': '-'}> +CONFIG_ARC_EMAC_CORE policy<{'arm64': '-'}> +CONFIG_ARM64_ACPI_PARKING_PROTOCOL policy<{'arm64': 'n'}> +CONFIG_ARM64_CRYPTO policy<{'arm64': 'n'}> +CONFIG_ARM64_DEBUG_PRIORITY_MASKING policy<{'arm64': '-'}> +CONFIG_ARM64_PMEM policy<{'arm64': 'n'}> +CONFIG_ARM64_PSEUDO_NMI policy<{'arm64': 'n'}> +CONFIG_ARMADA_37XX_CLK policy<{'arm64': '-'}> +CONFIG_ARMADA_37XX_RWTM_MBOX policy<{'arm64': '-'}> +CONFIG_ARMADA_37XX_WATCHDOG policy<{'arm64': '-'}> +CONFIG_ARMADA_AP806_SYSCON policy<{'arm64': '-'}> +CONFIG_ARMADA_AP_CPU_CLK policy<{'arm64': '-'}> +CONFIG_ARMADA_AP_CP_HELPER policy<{'arm64': '-'}> +CONFIG_ARMADA_CP110_SYSCON policy<{'arm64': '-'}> +CONFIG_ARMADA_THERMAL policy<{'arm64': '-'}> +CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM policy<{'arm64': '-'}> +CONFIG_ARM_ARMADA_37XX_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_ARMADA_8K_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_BRCMSTB_AVS_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_CCI policy<{'arm64': '-'}> +CONFIG_ARM_CCI400_COMMON policy<{'arm64': '-'}> +CONFIG_ARM_CCI400_PMU policy<{'arm64': '-'}> +CONFIG_ARM_CCI5xx_PMU policy<{'arm64': '-'}> +CONFIG_ARM_CCI_PMU policy<{'arm64': 'n'}> +CONFIG_ARM_CCN policy<{'arm64': 'n'}> +CONFIG_ARM_CMN policy<{'arm64': 'm'}> +CONFIG_ARM_CPUIDLE policy<{'arm64': 'n'}> +CONFIG_ARM_DMC620_PMU policy<{'arm64': 'm'}> +CONFIG_ARM_DSU_PMU policy<{'arm64': 'n'}> +CONFIG_ARM_GIC_V3_ITS_FSL_MC policy<{'arm64': '-'}> +CONFIG_ARM_IMX6Q_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_IMX_CPUFREQ_DT policy<{'arm64': '-'}> +CONFIG_ARM_MEDIATEK_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_MHU policy<{'arm64': 'n'}> +CONFIG_ARM_PL172_MPMC policy<{'arm64': 'n'}> +CONFIG_ARM_PSCI_CPUIDLE policy<{'arm64': 'n'}> +CONFIG_ARM_QCOM_CPUFREQ_HW policy<{'arm64': '-'}> +CONFIG_ARM_QCOM_CPUFREQ_NVMEM policy<{'arm64': '-'}> +CONFIG_ARM_RASPBERRYPI_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_RK3399_DMC_DEVFREQ policy<{'arm64': '-'}> +CONFIG_ARM_SBSA_WATCHDOG policy<{'arm64': 'n'}> +CONFIG_ARM_SCMI_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_SCMI_POWER_DOMAIN policy<{'arm64': '-'}> +CONFIG_ARM_SCMI_PROTOCOL policy<{'arm64': 'n'}> +CONFIG_ARM_SCPI_CPUFREQ policy<{'arm64': '-'}> +CONFIG_ARM_SCPI_POWER_DOMAIN policy<{'arm64': '-'}> +CONFIG_ARM_SCPI_PROTOCOL policy<{'arm64': 'n'}> +CONFIG_ARM_SDE_INTERFACE policy<{'arm64': 'n'}> +CONFIG_ARM_SP805_WATCHDOG policy<{'arm64': 'n'}> +CONFIG_ARM_SPE_PMU policy<{'arm64': 'n'}> +CONFIG_ARM_TIMER_SP804 policy<{'arm64': '-'}> +CONFIG_ASYNC_RAID6_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA policy<{'arm64': '-'}> +CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA policy<{'arm64': '-'}> +CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH policy<{'arm64': '-'}> +CONFIG_ATA_GENERIC policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ATH10K_AHB policy<{'arm64': 'n'}> +CONFIG_ATH10K_SNOC policy<{'arm64': '-'}> +CONFIG_ATOMIC64_SELFTEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_AX88796B_PHY policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_AXI_DMAC policy<{'arm64': '-'}> +CONFIG_BACKLIGHT_TPS65217 policy<{'arm64': '-'}> +CONFIG_BACKTRACE_SELF_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_BATTERY_ACT8945A policy<{'arm64': '-'}> +CONFIG_BATTERY_CPCAP policy<{'arm64': '-'}> +CONFIG_BATTERY_LEGO_EV3 policy<{'arm64': 'n'}> +CONFIG_BCH_CONST_M policy<{'amd64': '14', 'arm64': '14'}> +CONFIG_BCH_CONST_T policy<{'amd64': '4', 'arm64': '4'}> +CONFIG_BCM2835_MBOX policy<{'arm64': '-'}> +CONFIG_BCM2835_POWER policy<{'arm64': '-'}> +CONFIG_BCM2835_THERMAL policy<{'arm64': '-'}> +CONFIG_BCM2835_VCHIQ policy<{'arm64': '-'}> +CONFIG_BCM2835_WDT policy<{'arm64': '-'}> +CONFIG_BCM7038_L1_IRQ policy<{'arm64': '-'}> +CONFIG_BCM7038_WDT policy<{'arm64': '-'}> +CONFIG_BCM_FLEXRM_MBOX policy<{'arm64': '-'}> +CONFIG_BCM_IPROC_ADC policy<{'arm64': '-'}> +CONFIG_BCM_NS_THERMAL policy<{'arm64': '-'}> +CONFIG_BCM_PDC_MBOX policy<{'arm64': '-'}> +CONFIG_BCM_SBA_RAID policy<{'arm64': 'n'}> +CONFIG_BCM_SR_THERMAL policy<{'arm64': '-'}> +CONFIG_BCM_VIDEOCORE policy<{'arm64': '-'}> +CONFIG_BD70528_WATCHDOG policy<{'arm64': '-'}> +CONFIG_BERLIN2_ADC policy<{'arm64': '-'}> +CONFIG_BGMAC policy<{'arm64': '-'}> +CONFIG_BGMAC_PLATFORM policy<{'arm64': '-'}> +CONFIG_BLK_CGROUP_IOLATENCY policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_BPFILTER_UMH policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_BPF_KPROBE_OVERRIDE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_BRCMSTB_GISB_ARB policy<{'arm64': 'n'}> +CONFIG_BRCMSTB_L2_IRQ policy<{'arm64': '-'}> +CONFIG_BRCMSTB_PM policy<{'arm64': '-'}> +CONFIG_BRCMSTB_THERMAL policy<{'arm64': '-'}> +CONFIG_BT_HCIBLUECARD policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_BT_HCIBT3C policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_BT_HCIBTUSB_AUTOSUSPEND policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_BT_HCIDTL1 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_BT_QCOMSMD policy<{'arm64': '-'}> +CONFIG_CAN_EMS_PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CAN_FLEXCAN policy<{'arm64': 'n'}> +CONFIG_CAN_GRCAN policy<{'arm64': 'n'}> +CONFIG_CAN_PEAK_PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CAN_RCAR policy<{'arm64': '-'}> +CONFIG_CAN_RCAR_CANFD policy<{'arm64': '-'}> +CONFIG_CAN_SOFTING_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CAN_UCAN policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_CAN_XILINXCAN policy<{'arm64': 'n'}> +CONFIG_CARDMAN_4000 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CARDMAN_4040 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CAVIUM_CPT policy<{'arm64': '-'}> +CONFIG_CAVIUM_PTP policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_CDNS_I3C_MASTER policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_CEC_CORE policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CEC_NOTIFIER policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_CEC_PIN policy<{'arm64': '-'}> +CONFIG_CEC_PIN_ERROR_INJ policy<{'arm64': '-'}> +CONFIG_CHARGER_BD70528 policy<{'arm64': '-'}> +CONFIG_CHARGER_CPCAP policy<{'arm64': '-'}> +CONFIG_CHARGER_DETECTOR_MAX14656 policy<{'arm64': 'n'}> +CONFIG_CHARGER_MAX77650 policy<{'arm64': '-'}> +CONFIG_CHARGER_QCOM_SMBB policy<{'arm64': '-'}> +CONFIG_CHARGER_SC2731 policy<{'arm64': '-'}> +CONFIG_CHARGER_TPS65217 policy<{'arm64': '-'}> +CONFIG_CHARGER_UCS1002 policy<{'arm64': 'n'}> +CONFIG_CLKSRC_MMIO policy<{'arm64': '-'}> +CONFIG_CLKSRC_VERSATILE policy<{'arm64': '-'}> +CONFIG_CLK_ACTIONS policy<{'arm64': '-'}> +CONFIG_CLK_BCM2835 policy<{'arm64': '-'}> +CONFIG_CLK_BCM_NS2 policy<{'arm64': '-'}> +CONFIG_CLK_BCM_SR policy<{'arm64': '-'}> +CONFIG_CLK_HSDK policy<{'arm64': 'n'}> +CONFIG_CLK_IMX8MM policy<{'arm64': '-'}> +CONFIG_CLK_IMX8MN policy<{'arm64': '-'}> +CONFIG_CLK_IMX8MQ policy<{'arm64': '-'}> +CONFIG_CLK_IMX8QXP policy<{'arm64': '-'}> +CONFIG_CLK_OWL_S500 policy<{'arm64': '-'}> +CONFIG_CLK_OWL_S700 policy<{'arm64': '-'}> +CONFIG_CLK_OWL_S900 policy<{'arm64': '-'}> +CONFIG_CLK_QORIQ policy<{'arm64': 'n'}> +CONFIG_CLK_R8A774A1 policy<{'arm64': '-'}> +CONFIG_CLK_R8A774C0 policy<{'arm64': '-'}> +CONFIG_CLK_R8A7795 policy<{'arm64': '-'}> +CONFIG_CLK_R8A7796 policy<{'arm64': '-'}> +CONFIG_CLK_R8A77965 policy<{'arm64': '-'}> +CONFIG_CLK_R8A77970 policy<{'arm64': '-'}> +CONFIG_CLK_R8A77980 policy<{'arm64': '-'}> +CONFIG_CLK_R8A77990 policy<{'arm64': '-'}> +CONFIG_CLK_R8A77995 policy<{'arm64': '-'}> +CONFIG_CLK_R9A06G032 policy<{'arm64': '-'}> +CONFIG_CLK_RASPBERRYPI policy<{'arm64': '-'}> +CONFIG_CLK_RCAR_GEN3_CPG policy<{'arm64': '-'}> +CONFIG_CLK_RCAR_USB2_CLOCK_SEL policy<{'arm64': '-'}> +CONFIG_CLK_RENESAS policy<{'arm64': '-'}> +CONFIG_CLK_RENESAS_CPG_MSSR policy<{'arm64': '-'}> +CONFIG_CLK_RENESAS_DIV6 policy<{'arm64': '-'}> +CONFIG_CLK_SP810 policy<{'arm64': '-'}> +CONFIG_CLK_SUNXI policy<{'arm64': '-'}> +CONFIG_CLK_SUNXI_CLOCKS policy<{'arm64': '-'}> +CONFIG_CLK_SUNXI_PRCM_SUN6I policy<{'arm64': '-'}> +CONFIG_CLK_SUNXI_PRCM_SUN8I policy<{'arm64': '-'}> +CONFIG_CLK_SUNXI_PRCM_SUN9I policy<{'arm64': '-'}> +CONFIG_CLK_VEXPRESS_OSC policy<{'arm64': '-'}> +CONFIG_CM3605 policy<{'arm64': 'n'}> +CONFIG_CMDLINE policy<{'arm64': '""'}> +CONFIG_COMEDI_CB_DAS16_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_DAS08_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_NI_DAQ_700_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_NI_DAQ_DIO24_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_NI_LABPC_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_NI_MIO_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_PCMCIA_DRIVERS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMEDI_QUATECH_DAQP_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_COMMON_CLK_AXG policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_AXG_AUDIO policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_BD718XX policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_CDCE925 policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_FIXED_MMIO policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_G12A policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_GXBB policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI3516CV300 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI3519 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI3660 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI3670 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI3798CV200 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI6220 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_HI655X policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_IPROC policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_LOCHNAGAR policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MAX77686 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MAX9485 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_COMMON_CLK_MEDIATEK policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_AO_CLKC policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_CPU_DYNDIV policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_DUALDIV policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_EE_CLKC policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_MPLL policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_PHASE policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_PLL policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_REGMAP policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_SCLK_DIV policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MESON_VID_PLL_DIV policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_BDPSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_IMGSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_JPGDECSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_MFGCFG policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_MMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_VDECSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT2712_VENCSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_AUDSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_CAMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_IMGSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_IPESYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_MFGCFG policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_MMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_VDECSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6779_VENCSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6797 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6797_IMGSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6797_MMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6797_VDECSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT6797_VENCSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT7622 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT7622_AUDSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT7622_ETHSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT7622_HIFSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8173 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_AUDIOSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_CAMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_IMGSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_IPU_ADL policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_IPU_CONN policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_IPU_CORE0 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_IPU_CORE1 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_MFGCFG policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_MMSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_VDECSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8183_VENCSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8516 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_MT8516_AUDSYS policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_QCOM policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_RK808 policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_SCMI policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_SCPI policy<{'arm64': '-'}> +CONFIG_COMMON_CLK_SI514 policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_SI544 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_COMMON_CLK_SI570 policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_VC5 policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_VERSATILE policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_XGENE policy<{'arm64': 'n'}> +CONFIG_COMMON_CLK_ZYNQMP policy<{'arm64': '-'}> +CONFIG_COMMON_RESET_HI3660 policy<{'arm64': '-'}> +CONFIG_COMMON_RESET_HI6220 policy<{'arm64': '-'}> +CONFIG_CPCAP_ADC policy<{'arm64': '-'}> +CONFIG_CPUFREQ_DT_PLATDEV policy<{'arm64': '-'}> +CONFIG_CPU_IDLE_MULTIPLE_DRIVERS policy<{'arm64': '-'}> +CONFIG_CPU_THERMAL policy<{'arm64': 'n'}> +CONFIG_CRC64 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_CROS_EC_RPMSG policy<{'arm64': 'n'}> +CONFIG_CRYPTO_842 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_CRYPTO_AES_ARM64 policy<{'arm64': '-'}> +CONFIG_CRYPTO_AES_ARM64_BS policy<{'arm64': '-'}> +CONFIG_CRYPTO_AES_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_AES_ARM64_CE_BLK policy<{'arm64': '-'}> +CONFIG_CRYPTO_AES_ARM64_CE_CCM policy<{'arm64': '-'}> +CONFIG_CRYPTO_AES_ARM64_NEON_BLK policy<{'arm64': '-'}> +CONFIG_CRYPTO_CHACHA20_NEON policy<{'arm64': '-'}> +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEFLATE policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_CRYPTO_DEV_BCM_SPU policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_CAVIUM_ZIP policy<{'arm64': 'n'}> +CONFIG_CRYPTO_DEV_CCREE policy<{'arm64': 'n'}> +CONFIG_CRYPTO_DEV_CPT policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_JR policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_HISI_HPRE policy<{'arm64': 'n'}> +CONFIG_CRYPTO_DEV_HISI_SEC policy<{'arm64': 'n'}> +CONFIG_CRYPTO_DEV_HISI_SEC2 policy<{'arm64': 'n'}> +CONFIG_CRYPTO_DEV_MARVELL_CESA policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_MXS_DCP policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_QAT_C3XXX policy<{'amd64': 'n'}> +CONFIG_CRYPTO_DEV_QAT_C3XXXVF policy<{'amd64': 'n'}> +CONFIG_CRYPTO_DEV_QAT_C62X policy<{'amd64': 'n'}> +CONFIG_CRYPTO_DEV_QAT_C62XVF policy<{'amd64': 'n'}> +CONFIG_CRYPTO_DEV_QCE policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_QCOM_RNG policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_CRYPTO_DEV_SAHARA policy<{'arm64': '-'}> +CONFIG_CRYPTO_GHASH_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_NHPOLY1305_NEON policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA1_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA256_ARM64 policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA2_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA3_ARM64 policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA512_ARM64 policy<{'arm64': '-'}> +CONFIG_CRYPTO_SHA512_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_SIMD policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_CRYPTO_SM3_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_SM4_ARM64_CE policy<{'arm64': '-'}> +CONFIG_CRYPTO_ZSTD policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_CS89x0 policy<{'amd64': 'y'}> +CONFIG_DA9062_THERMAL policy<{'arm64': 'n'}> +CONFIG_DELL_UART_BACKLIGHT policy<{'amd64': 'n'}> +CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI policy<{'arm64': '-'}> +CONFIG_DMARD06 policy<{'arm64': 'n'}> +CONFIG_DMA_BCM2835 policy<{'arm64': '-'}> +CONFIG_DMA_ENGINE_RAID policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_DMA_SUN6I policy<{'arm64': '-'}> +CONFIG_DMA_VIRTUAL_CHANNELS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_DM_UNSTRIPED policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DP83TC811_PHY policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DPAA2_CONSOLE policy<{'arm64': '-'}> +CONFIG_DPAA_ERRATUM_A050385 policy<{'arm64': '-'}> +CONFIG_DPOT_DAC policy<{'arm64': 'n'}> +CONFIG_DRM_ANALOGIX_DP policy<{'arm64': '-'}> +CONFIG_DRM_ARCPGU policy<{'arm64': 'n'}> +CONFIG_DRM_CDNS_DSI policy<{'arm64': 'n'}> +CONFIG_DRM_DEBUG_SELFTEST policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_DRM_DP_CEC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DRM_DUMB_VGA_DAC policy<{'arm64': 'n'}> +CONFIG_DRM_DW_HDMI policy<{'arm64': '-'}> +CONFIG_DRM_DW_HDMI_AHB_AUDIO policy<{'arm64': '-'}> +CONFIG_DRM_DW_HDMI_CEC policy<{'arm64': '-'}> +CONFIG_DRM_DW_HDMI_I2S_AUDIO policy<{'arm64': '-'}> +CONFIG_DRM_DW_MIPI_DSI policy<{'arm64': '-'}> +CONFIG_DRM_ETNAVIV policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DRM_ETNAVIV_THERMAL policy<{'arm64': '-'}> +CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_DRM_HDLCD policy<{'arm64': 'n'}> +CONFIG_DRM_HDLCD_SHOW_UNDERRUN policy<{'arm64': '-'}> +CONFIG_DRM_HISI_KIRIN policy<{'arm64': 'n'}> +CONFIG_DRM_I2C_ADV7511 policy<{'arm64': 'n'}> +CONFIG_DRM_I2C_ADV7511_AUDIO policy<{'arm64': '-'}> +CONFIG_DRM_I2C_ADV7511_CEC policy<{'arm64': '-'}> +CONFIG_DRM_I2C_ADV7533 policy<{'arm64': '-'}> +CONFIG_DRM_I2C_NXP_TDA9950 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DRM_KOMEDA policy<{'arm64': 'n'}> +CONFIG_DRM_LIB_RANDOM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_DRM_LIMA policy<{'arm64': 'n'}> +CONFIG_DRM_LVDS_ENCODER policy<{'arm64': 'n'}> +CONFIG_DRM_MALI_DISPLAY policy<{'arm64': 'n'}> +CONFIG_DRM_MEDIATEK policy<{'arm64': '-'}> +CONFIG_DRM_MEDIATEK_HDMI policy<{'arm64': '-'}> +CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW policy<{'arm64': 'n'}> +CONFIG_DRM_MESON policy<{'arm64': '-'}> +CONFIG_DRM_MESON_DW_HDMI policy<{'arm64': '-'}> +CONFIG_DRM_MIPI_DSI policy<{'amd64': 'y', 'arm64': '-'}> +CONFIG_DRM_MSM policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_10NM_PHY policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_14NM_PHY policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_20NM_PHY policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_28NM_8960_PHY policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_28NM_PHY policy<{'arm64': '-'}> +CONFIG_DRM_MSM_DSI_PLL policy<{'arm64': '-'}> +CONFIG_DRM_MSM_GPU_STATE policy<{'arm64': '-'}> +CONFIG_DRM_MSM_GPU_SUDO policy<{'arm64': '-'}> +CONFIG_DRM_MSM_HDMI_HDCP policy<{'arm64': '-'}> +CONFIG_DRM_MSM_REGISTER_LOGGING policy<{'arm64': '-'}> +CONFIG_DRM_MXS policy<{'arm64': '-'}> +CONFIG_DRM_MXSFB policy<{'arm64': '-'}> +CONFIG_DRM_NXP_PTN3460 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_ARM_VERSATILE policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_ILITEK_IL9322 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_ILITEK_ILI9881C policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_INNOLUX_P079ZCA policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_JDI_LT070ME05000 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_LG_LB035Q02 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_LG_LG4573 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_LVDS policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_NEC_NL8048HL11 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_NOVATEK_NT39016 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_ORISETECH_OTM8009A policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_DRM_PANEL_RAYDIUM_RM67191 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_RAYDIUM_RM68200 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_RONBO_RB070D30 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SAMSUNG_LD9040 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SEIKO_43WVF1G policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SHARP_LS037V7DW01 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SHARP_LS043T1LE01 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SIMPLE policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SITRONIX_ST7701 policy<{'arm64': '-'}> +CONFIG_DRM_PANEL_SITRONIX_ST7789V policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_SONY_ACX565AKM policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_TPO_TD028TTEC1 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_TPO_TD043MTEA1 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_TPO_TPG110 policy<{'arm64': 'n'}> +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA policy<{'arm64': '-'}> +CONFIG_DRM_PANFROST policy<{'arm64': 'n'}> +CONFIG_DRM_PARADE_PS8622 policy<{'arm64': 'n'}> +CONFIG_DRM_PL111 policy<{'arm64': 'n'}> +CONFIG_DRM_RCAR_DU policy<{'arm64': '-'}> +CONFIG_DRM_RCAR_DW_HDMI policy<{'arm64': 'n'}> +CONFIG_DRM_RCAR_LVDS policy<{'arm64': 'n'}> +CONFIG_DRM_RCAR_VSP policy<{'arm64': '-'}> +CONFIG_DRM_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_DRM_SII902X policy<{'arm64': 'n'}> +CONFIG_DRM_SII9234 policy<{'arm64': 'n'}> +CONFIG_DRM_SIL_SII8620 policy<{'arm64': 'n'}> +CONFIG_DRM_SUN4I policy<{'arm64': '-'}> +CONFIG_DRM_SUN4I_BACKEND policy<{'arm64': '-'}> +CONFIG_DRM_SUN4I_HDMI policy<{'arm64': '-'}> +CONFIG_DRM_SUN4I_HDMI_CEC policy<{'arm64': '-'}> +CONFIG_DRM_SUN6I_DSI policy<{'arm64': '-'}> +CONFIG_DRM_SUN8I_DW_HDMI policy<{'arm64': '-'}> +CONFIG_DRM_SUN8I_MIXER policy<{'arm64': '-'}> +CONFIG_DRM_SUN8I_TCON_TOP policy<{'arm64': '-'}> +CONFIG_DRM_THINE_THC63LVD1024 policy<{'arm64': 'n'}> +CONFIG_DRM_TI_SN65DSI86 policy<{'arm64': 'n'}> +CONFIG_DRM_TI_TFP410 policy<{'arm64': 'n'}> +CONFIG_DRM_TOSHIBA_TC358764 policy<{'arm64': 'n'}> +CONFIG_DRM_TOSHIBA_TC358767 policy<{'arm64': 'n'}> +CONFIG_DRM_VC4 policy<{'arm64': '-'}> +CONFIG_DRM_VC4_HDMI_CEC policy<{'arm64': '-'}> +CONFIG_DRM_VKMS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_DT_IDLE_STATES policy<{'arm64': '-'}> +CONFIG_DWMAC_DWC_QOS_ETH policy<{'arm64': 'n'}> +CONFIG_DWMAC_IPQ806X policy<{'arm64': '-'}> +CONFIG_DWMAC_MEDIATEK policy<{'arm64': '-'}> +CONFIG_DWMAC_MESON policy<{'arm64': '-'}> +CONFIG_DWMAC_QCOM_ETHQOS policy<{'arm64': '-'}> +CONFIG_DWMAC_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_DWMAC_SOCFPGA policy<{'arm64': '-'}> +CONFIG_DWMAC_SUN8I policy<{'arm64': '-'}> +CONFIG_DWMAC_SUNXI policy<{'arm64': '-'}> +CONFIG_DW_APB_ICTL policy<{'arm64': '-'}> +CONFIG_DW_APB_TIMER policy<{'arm64': '-'}> +CONFIG_DW_APB_TIMER_OF policy<{'arm64': '-'}> +CONFIG_DW_AXI_DMAC policy<{'arm64': 'n'}> +CONFIG_DW_I3C_MASTER policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_EARLY_PRINTK_USB_XDBC policy<{'amd64': 'n'}> +CONFIG_EDAC_ALTERA policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_ETHERNET policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_NAND policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_OCRAM policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_QSPI policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_SDMMC policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_SDRAM policy<{'arm64': '-'}> +CONFIG_EDAC_ALTERA_USB policy<{'arm64': '-'}> +CONFIG_EDAC_BLUEFIELD policy<{'arm64': 'n'}> +CONFIG_EDAC_LAYERSCAPE policy<{'arm64': '-'}> +CONFIG_EDAC_QCOM policy<{'arm64': '-'}> +CONFIG_EDAC_SYNOPSYS policy<{'arm64': '-'}> +CONFIG_EDAC_THUNDERX policy<{'arm64': 'n'}> +CONFIG_EDAC_XGENE policy<{'arm64': 'n'}> +CONFIG_EFI_ARMSTUB_DTB_LOADER policy<{'arm64': 'y'}> +CONFIG_EINT_MTK policy<{'arm64': '-'}> +CONFIG_EMAC_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_ENVELOPE_DETECTOR policy<{'arm64': 'n'}> +CONFIG_EROFS_FS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_EROFS_FS_DEBUG policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_EROFS_FS_POSIX_ACL policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_EROFS_FS_ZIP policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_EXTCON_QCOM_SPMI_MISC policy<{'arm64': '-'}> +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET policy<{'arm64': 'n'}> +CONFIG_FB_ARMCLCD policy<{'arm64': 'n'}> +CONFIG_FB_IMX policy<{'arm64': '-'}> +CONFIG_FB_MX3 policy<{'arm64': '-'}> +CONFIG_FB_SH_MOBILE_LCDC policy<{'arm64': '-'}> +CONFIG_FB_SSD1307 policy<{'arm64': 'n'}> +CONFIG_FB_TFT policy<{'arm64': 'n'}> +CONFIG_FB_TFT_AGM1264K_FL policy<{'arm64': '-'}> +CONFIG_FB_TFT_BD663474 policy<{'arm64': '-'}> +CONFIG_FB_TFT_HX8340BN policy<{'arm64': '-'}> +CONFIG_FB_TFT_HX8347D policy<{'arm64': '-'}> +CONFIG_FB_TFT_HX8353D policy<{'arm64': '-'}> +CONFIG_FB_TFT_HX8357D policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9163 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9320 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9325 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9340 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9341 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9481 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ILI9486 policy<{'arm64': '-'}> +CONFIG_FB_TFT_PCD8544 policy<{'arm64': '-'}> +CONFIG_FB_TFT_RA8875 policy<{'arm64': '-'}> +CONFIG_FB_TFT_S6D02A1 policy<{'arm64': '-'}> +CONFIG_FB_TFT_S6D1121 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SH1106 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SSD1289 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SSD1305 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SSD1306 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SSD1331 policy<{'arm64': '-'}> +CONFIG_FB_TFT_SSD1351 policy<{'arm64': '-'}> +CONFIG_FB_TFT_ST7735R policy<{'arm64': '-'}> +CONFIG_FB_TFT_ST7789V policy<{'arm64': '-'}> +CONFIG_FB_TFT_TINYLCD policy<{'arm64': '-'}> +CONFIG_FB_TFT_TLS8204 policy<{'arm64': '-'}> +CONFIG_FB_TFT_UC1611 policy<{'arm64': '-'}> +CONFIG_FB_TFT_UC1701 policy<{'arm64': '-'}> +CONFIG_FB_TFT_UPD161704 policy<{'arm64': '-'}> +CONFIG_FB_TFT_WATTEROTT policy<{'arm64': '-'}> +CONFIG_FB_XILINX policy<{'arm64': '-'}> +CONFIG_FEC policy<{'arm64': '-'}> +CONFIG_FIND_BIT_BENCHMARK policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONTS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_FONT_10x18 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_6x10 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_6x11 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_7x14 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_ACORN_8x8 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_MINI_4x6 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_PEARL_8x8 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_SUN12x22 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_SUN8x16 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FONT_TER16x32 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_FORCE_MAX_ZONEORDER policy<{'arm64': '11'}> +CONFIG_FPGA_DFL_AFU policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_FPGA_DFL_FME_MGR policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_FPGA_MGR_ICE40_SPI policy<{'arm64': 'n'}> +CONFIG_FPGA_MGR_STRATIX10_SOC policy<{'arm64': '-'}> +CONFIG_FPGA_MGR_ZYNQMP_FPGA policy<{'arm64': '-'}> +CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_FSI policy<{'arm64': 'n'}> +CONFIG_FSI_MASTER_GPIO policy<{'arm64': '-'}> +CONFIG_FSI_MASTER_HUB policy<{'arm64': '-'}> +CONFIG_FSI_NEW_DEV_NODE policy<{'arm64': '-'}> +CONFIG_FSI_OCC policy<{'arm64': '-'}> +CONFIG_FSI_SBEFIFO policy<{'arm64': '-'}> +CONFIG_FSI_SCOM policy<{'arm64': '-'}> +CONFIG_FSL_BMAN_TEST policy<{'arm64': '-'}> +CONFIG_FSL_BMAN_TEST_API policy<{'arm64': '-'}> +CONFIG_FSL_DPAA policy<{'arm64': '-'}> +CONFIG_FSL_DPAA2 policy<{'arm64': '-'}> +CONFIG_FSL_DPAA2_ETH policy<{'arm64': '-'}> +CONFIG_FSL_DPAA2_ETHSW policy<{'arm64': '-'}> +CONFIG_FSL_DPAA2_PTP_CLOCK policy<{'arm64': '-'}> +CONFIG_FSL_DPAA_CHECKING policy<{'arm64': '-'}> +CONFIG_FSL_DPAA_ETH policy<{'arm64': '-'}> +CONFIG_FSL_EDMA policy<{'arm64': 'n'}> +CONFIG_FSL_ENETC policy<{'arm64': '-'}> +CONFIG_FSL_ENETC_HW_TIMESTAMPING policy<{'arm64': '-'}> +CONFIG_FSL_ENETC_MDIO policy<{'arm64': '-'}> +CONFIG_FSL_ENETC_PTP_CLOCK policy<{'arm64': '-'}> +CONFIG_FSL_ENETC_VF policy<{'arm64': '-'}> +CONFIG_FSL_FMAN policy<{'arm64': '-'}> +CONFIG_FSL_GUTS policy<{'arm64': '-'}> +CONFIG_FSL_IFC policy<{'arm64': '-'}> +CONFIG_FSL_IMX8_DDR_PMU policy<{'arm64': '-'}> +CONFIG_FSL_MC_BUS policy<{'arm64': '-'}> +CONFIG_FSL_MC_DPIO policy<{'arm64': '-'}> +CONFIG_FSL_PQ_MDIO policy<{'arm64': '-'}> +CONFIG_FSL_QDMA policy<{'arm64': 'n'}> +CONFIG_FSL_QMAN_TEST policy<{'arm64': '-'}> +CONFIG_FSL_XGMAC_MDIO policy<{'arm64': '-'}> +CONFIG_FTM_QUADDEC policy<{'arm64': 'n'}> +CONFIG_FUEL_GAUGE_SC27XX policy<{'arm64': '-'}> +CONFIG_GEMINI_ETHERNET policy<{'arm64': 'n'}> +CONFIG_GENERIC_PHY_MIPI_DPHY policy<{'arm64': '-'}> +CONFIG_GENERIC_PINCTRL_GROUPS policy<{'arm64': '-'}> +CONFIG_GENERIC_PINMUX_FUNCTIONS policy<{'arm64': '-'}> +CONFIG_GIANFAR policy<{'arm64': '-'}> +CONFIG_GNSS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_GNSS_SERIAL policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_GNSS_SIRF_SERIAL policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_GNSS_UBX_SERIAL policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_GPD_POCKET_FAN policy<{'amd64': 'n'}> +CONFIG_GPIO_74X164 policy<{'arm64': 'n'}> +CONFIG_GPIO_74XX_MMIO policy<{'arm64': 'n'}> +CONFIG_GPIO_ADNP policy<{'arm64': 'n'}> +CONFIG_GPIO_ALTERA policy<{'arm64': 'n'}> +CONFIG_GPIO_BD70528 policy<{'arm64': '-'}> +CONFIG_GPIO_BRCMSTB policy<{'arm64': '-'}> +CONFIG_GPIO_CADENCE policy<{'arm64': 'n'}> +CONFIG_GPIO_DAVINCI policy<{'arm64': '-'}> +CONFIG_GPIO_EIC_SPRD policy<{'arm64': '-'}> +CONFIG_GPIO_FTGPIO010 policy<{'arm64': 'n'}> +CONFIG_GPIO_GENERIC policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_GPIO_GENERIC_PLATFORM policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_GPIO_GRGPIO policy<{'arm64': 'n'}> +CONFIG_GPIO_GW_PLD policy<{'arm64': 'n'}> +CONFIG_GPIO_HLWD policy<{'arm64': 'n'}> +CONFIG_GPIO_LP87565 policy<{'arm64': '-'}> +CONFIG_GPIO_MAX77620 policy<{'arm64': '-'}> +CONFIG_GPIO_MAX77650 policy<{'arm64': '-'}> +CONFIG_GPIO_MLXBF policy<{'arm64': 'n'}> +CONFIG_GPIO_MOXTET policy<{'arm64': '-'}> +CONFIG_GPIO_MPC8XXX policy<{'arm64': '-'}> +CONFIG_GPIO_MVEBU policy<{'arm64': '-'}> +CONFIG_GPIO_MXC policy<{'arm64': '-'}> +CONFIG_GPIO_PL061 policy<{'arm64': 'n'}> +CONFIG_GPIO_PMIC_EIC_SPRD policy<{'arm64': '-'}> +CONFIG_GPIO_RASPBERRYPI_EXP policy<{'arm64': '-'}> +CONFIG_GPIO_RCAR policy<{'arm64': '-'}> +CONFIG_GPIO_SAMA5D2_PIOBU policy<{'arm64': 'n'}> +CONFIG_GPIO_SPRD policy<{'arm64': '-'}> +CONFIG_GPIO_STMPE policy<{'arm64': '-'}> +CONFIG_GPIO_SYSCON policy<{'arm64': 'n'}> +CONFIG_GPIO_TC3589X policy<{'arm64': '-'}> +CONFIG_GPIO_THUNDERX policy<{'arm64': '-'}> +CONFIG_GPIO_TPS65218 policy<{'arm64': '-'}> +CONFIG_GPIO_WATCHDOG policy<{'arm64': 'n'}> +CONFIG_GPIO_XGENE policy<{'arm64': 'n'}> +CONFIG_GPIO_XGENE_SB policy<{'arm64': '-'}> +CONFIG_GPIO_XILINX policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_GPIO_XLP policy<{'arm64': '-'}> +CONFIG_GPIO_ZYNQ policy<{'arm64': '-'}> +CONFIG_HAVE_MEMBLOCK_NODE_MAP policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_HBMC_AM654 policy<{'arm64': 'n'}> +CONFIG_HI13X1_GMAC policy<{'arm64': '-'}> +CONFIG_HI3660_MBOX policy<{'arm64': '-'}> +CONFIG_HI6220_MBOX policy<{'arm64': '-'}> +CONFIG_HIP04_ETH policy<{'arm64': 'n'}> +CONFIG_HISILICON_IRQ_MBIGEN policy<{'arm64': '-'}> +CONFIG_HISILICON_LPC policy<{'arm64': '-'}> +CONFIG_HISI_FEMAC policy<{'arm64': 'n'}> +CONFIG_HISI_PMU policy<{'arm64': 'n'}> +CONFIG_HISI_THERMAL policy<{'arm64': '-'}> +CONFIG_HIX5HD2_GMAC policy<{'arm64': 'n'}> +CONFIG_HMS_ANYBUSS_BUS policy<{'arm64': 'n'}> +CONFIG_HMS_PROFINET policy<{'arm64': '-'}> +CONFIG_HNS policy<{'arm64': 'n'}> +CONFIG_HNS3 policy<{'arm64': 'n'}> +CONFIG_HNS3_DCB policy<{'arm64': '-'}> +CONFIG_HNS3_ENET policy<{'arm64': '-'}> +CONFIG_HNS3_HCLGE policy<{'arm64': '-'}> +CONFIG_HNS3_HCLGEVF policy<{'arm64': '-'}> +CONFIG_HNS_DSAF policy<{'arm64': 'n'}> +CONFIG_HNS_ENET policy<{'arm64': 'n'}> +CONFIG_HNS_MDIO policy<{'arm64': '-'}> +CONFIG_HOSTAP_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_HSA_AMD policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_HT16K33 policy<{'arm64': 'n'}> +CONFIG_HWSPINLOCK_OMAP policy<{'arm64': '-'}> +CONFIG_HWSPINLOCK_QCOM policy<{'arm64': '-'}> +CONFIG_HWSPINLOCK_SPRD policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_BCM2835 policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_CAVIUM policy<{'arm64': 'y'}> +CONFIG_HW_RANDOM_HISI policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_HISI_V2 policy<{'arm64': 'y'}> +CONFIG_HW_RANDOM_IMX_RNGC policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_IPROC_RNG200 policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_MESON policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_MTK policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_OMAP policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_OPTEE policy<{'arm64': '-'}> +CONFIG_HW_RANDOM_XGENE policy<{'arm64': '-'}> +CONFIG_HZ policy<{'amd64': '250', 'arm64': '250'}> +CONFIG_HZ_1000 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_HZ_250 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_I2C_AMD_MP2 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_I2C_ARB_GPIO_CHALLENGE policy<{'arm64': 'n'}> +CONFIG_I2C_BCM2835 policy<{'arm64': '-'}> +CONFIG_I2C_BCM_IPROC policy<{'arm64': '-'}> +CONFIG_I2C_BRCMSTB policy<{'arm64': '-'}> +CONFIG_I2C_DEMUX_PINCTRL policy<{'arm64': 'n'}> +CONFIG_I2C_FSI policy<{'arm64': '-'}> +CONFIG_I2C_GPIO_FAULT_INJECTOR policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_I2C_HIX5HD2 policy<{'arm64': '-'}> +CONFIG_I2C_IMX policy<{'arm64': '-'}> +CONFIG_I2C_IMX_LPI2C policy<{'arm64': '-'}> +CONFIG_I2C_MESON policy<{'arm64': '-'}> +CONFIG_I2C_MT65XX policy<{'arm64': '-'}> +CONFIG_I2C_MUX_GPMUX policy<{'arm64': 'n'}> +CONFIG_I2C_MUX_PINCTRL policy<{'arm64': 'n'}> +CONFIG_I2C_MV64XXX policy<{'arm64': '-'}> +CONFIG_I2C_NOMADIK policy<{'arm64': 'n'}> +CONFIG_I2C_NVIDIA_GPU policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_I2C_OMAP policy<{'arm64': '-'}> +CONFIG_I2C_OWL policy<{'arm64': '-'}> +CONFIG_I2C_PXA policy<{'arm64': '-'}> +CONFIG_I2C_PXA_SLAVE policy<{'arm64': '-'}> +CONFIG_I2C_QCOM_GENI policy<{'arm64': '-'}> +CONFIG_I2C_QUP policy<{'arm64': '-'}> +CONFIG_I2C_RCAR policy<{'arm64': '-'}> +CONFIG_I2C_RIIC policy<{'arm64': '-'}> +CONFIG_I2C_RK3X policy<{'arm64': 'n'}> +CONFIG_I2C_SH_MOBILE policy<{'arm64': '-'}> +CONFIG_I2C_SLAVE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_I2C_SLAVE_EEPROM policy<{'arm64': '-'}> +CONFIG_I2C_SPRD policy<{'arm64': '-'}> +CONFIG_I2C_SYNQUACER policy<{'arm64': '-'}> +CONFIG_I2C_THUNDERX policy<{'arm64': 'n'}> +CONFIG_I2C_VERSATILE policy<{'arm64': '-'}> +CONFIG_I2C_XGENE_SLIMPRO policy<{'arm64': '-'}> +CONFIG_I2C_XLP9XX policy<{'arm64': '-'}> +CONFIG_I3C policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_I82092 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ICE policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_IGC policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_IIO_BUFFER_HW_CONSUMER policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_IIO_MUX policy<{'arm64': 'n'}> +CONFIG_IIO_RESCALE policy<{'arm64': 'n'}> +CONFIG_IMX2_WDT policy<{'arm64': '-'}> +CONFIG_IMX7D_ADC policy<{'arm64': '-'}> +CONFIG_IMX7ULP_WDT policy<{'arm64': '-'}> +CONFIG_IMX_DMA policy<{'arm64': '-'}> +CONFIG_IMX_DSP policy<{'arm64': '-'}> +CONFIG_IMX_GPCV2 policy<{'arm64': '-'}> +CONFIG_IMX_GPCV2_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_IMX_IRQSTEER policy<{'arm64': '-'}> +CONFIG_IMX_MBOX policy<{'arm64': '-'}> +CONFIG_IMX_REMOTEPROC policy<{'arm64': '-'}> +CONFIG_IMX_SCU policy<{'arm64': '-'}> +CONFIG_IMX_SCU_PD policy<{'arm64': '-'}> +CONFIG_IMX_SCU_SOC policy<{'arm64': '-'}> +CONFIG_IMX_SC_WDT policy<{'arm64': '-'}> +CONFIG_IMX_SDMA policy<{'arm64': '-'}> +CONFIG_IMX_THERMAL policy<{'arm64': '-'}> +CONFIG_IMX_WEIM policy<{'arm64': '-'}> +CONFIG_INDIRECT_PIO policy<{'arm64': 'n'}> +CONFIG_INFINIBAND_HNS policy<{'arm64': '-'}> +CONFIG_INFINIBAND_HNS_HIP06 policy<{'arm64': '-'}> +CONFIG_INFINIBAND_HNS_HIP08 policy<{'arm64': '-'}> +CONFIG_INLINE_READ_UNLOCK policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INLINE_READ_UNLOCK_IRQ policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INLINE_SPIN_UNLOCK_IRQ policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INLINE_WRITE_UNLOCK_IRQ policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INPUT_ATMEL_CAPTOUCH policy<{'arm64': 'n'}> +CONFIG_INPUT_CPCAP_PWRBUTTON policy<{'arm64': '-'}> +CONFIG_INPUT_HISI_POWERKEY policy<{'arm64': '-'}> +CONFIG_INPUT_MAX77650_ONKEY policy<{'arm64': '-'}> +CONFIG_INPUT_PM8941_PWRKEY policy<{'arm64': '-'}> +CONFIG_INPUT_PM8XXX_VIBRATOR policy<{'arm64': '-'}> +CONFIG_INPUT_RAVE_SP_PWRBUTTON policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_INPUT_RK805_PWRKEY policy<{'arm64': '-'}> +CONFIG_INPUT_SC27XX_VIBRA policy<{'arm64': '-'}> +CONFIG_INPUT_STPMIC1_ONKEY policy<{'arm64': '-'}> +CONFIG_INPUT_TPS65218_PWRBUTTON policy<{'arm64': '-'}> +CONFIG_INTEL_ATOMISP2_PM policy<{'amd64': 'n'}> +CONFIG_INTEL_CHTDC_TI_PWRBTN policy<{'amd64': 'n'}> +CONFIG_INTEL_STRATIX10_RSU policy<{'arm64': '-'}> +CONFIG_INTEL_STRATIX10_SERVICE policy<{'arm64': '-'}> +CONFIG_INTERCONNECT_QCOM policy<{'arm64': '-'}> +CONFIG_INTERCONNECT_QCOM_QCS404 policy<{'arm64': '-'}> +CONFIG_INTERCONNECT_QCOM_SDM845 policy<{'arm64': '-'}> +CONFIG_INTERCONNECT_QCOM_SMD_RPM policy<{'arm64': '-'}> +CONFIG_INTERVAL_TREE_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_IPMB_DEVICE_INTERFACE policy<{'arm64': '-'}> +CONFIG_IPQ_GCC_4019 policy<{'arm64': '-'}> +CONFIG_IPQ_GCC_806X policy<{'arm64': '-'}> +CONFIG_IPQ_GCC_8074 policy<{'arm64': '-'}> +CONFIG_IPQ_LCC_806X policy<{'arm64': '-'}> +CONFIG_IPWIRELESS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_IP_MROUTE_MULTIPLE_TABLES policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS policy<{'arm64': '-'}> +CONFIG_IRQ_FORCED_THREADING_DEFAULT policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_IR_GPIO_CIR policy<{'arm64': 'n'}> +CONFIG_IR_GPIO_TX policy<{'arm64': 'n'}> +CONFIG_IR_HIX5HD2 policy<{'arm64': 'n'}> +CONFIG_IR_IMON_DECODER policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_IR_MESON policy<{'arm64': '-'}> +CONFIG_IR_MTK policy<{'arm64': '-'}> +CONFIG_IR_PWM_TX policy<{'arm64': 'n'}> +CONFIG_IR_SPI policy<{'arm64': 'n'}> +CONFIG_IR_SUNXI policy<{'arm64': '-'}> +CONFIG_ISDN_DRV_AVMB1_AVM_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_JOYSTICK_PXRC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_K3_DMA policy<{'arm64': '-'}> +CONFIG_KEXEC_IMAGE_VERIFY_SIG policy<{'arm64': 'y'}> +CONFIG_KEXEC_JUMP policy<{'amd64': 'n'}> +CONFIG_KEYBOARD_BCM policy<{'arm64': 'n'}> +CONFIG_KEYBOARD_CAP11XX policy<{'arm64': 'n'}> +CONFIG_KEYBOARD_IMX policy<{'arm64': '-'}> +CONFIG_KEYBOARD_MTK_PMIC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_KEYBOARD_OMAP4 policy<{'arm64': 'n'}> +CONFIG_KEYBOARD_SNVS_PWRKEY policy<{'arm64': '-'}> +CONFIG_KEYBOARD_STMPE policy<{'arm64': '-'}> +CONFIG_KEYBOARD_SUN4I_LRADC policy<{'arm64': '-'}> +CONFIG_KEYBOARD_TC3589X policy<{'arm64': '-'}> +CONFIG_KPROBES_SANITY_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_KPSS_XCC policy<{'arm64': '-'}> +CONFIG_KVM_AMD_SEV policy<{'amd64': 'n'}> +CONFIG_LAN743X policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_LEDS_AAT1290 policy<{'arm64': 'n'}> +CONFIG_LEDS_AN30259A policy<{'arm64': 'n'}> +CONFIG_LEDS_BCM6328 policy<{'arm64': 'n'}> +CONFIG_LEDS_BCM6358 policy<{'arm64': 'n'}> +CONFIG_LEDS_CPCAP policy<{'arm64': '-'}> +CONFIG_LEDS_CR0014114 policy<{'arm64': 'n'}> +CONFIG_LEDS_IS31FL319X policy<{'arm64': 'n'}> +CONFIG_LEDS_IS31FL32XX policy<{'arm64': 'n'}> +CONFIG_LEDS_KTD2692 policy<{'arm64': 'n'}> +CONFIG_LEDS_LM3692X policy<{'arm64': 'n'}> +CONFIG_LEDS_LM3697 policy<{'arm64': 'n'}> +CONFIG_LEDS_LP8860 policy<{'arm64': 'n'}> +CONFIG_LEDS_LT3593 policy<{'arm64': 'n'}> +CONFIG_LEDS_MAX77650 policy<{'arm64': '-'}> +CONFIG_LEDS_MAX77693 policy<{'arm64': 'n'}> +CONFIG_LEDS_SC27XX_BLTC policy<{'arm64': '-'}> +CONFIG_LEDS_SPI_BYTE policy<{'arm64': 'n'}> +CONFIG_LEDS_SYSCON policy<{'arm64': 'n'}> +CONFIG_LG_LAPTOP policy<{'amd64': 'n'}> +CONFIG_LIBERTAS_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_LKDTM policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_LS_SCFG_MSI policy<{'arm64': '-'}> +CONFIG_MAILBOX_TEST policy<{'arm64': 'n'}> +CONFIG_MAX5821 policy<{'arm64': 'n'}> +CONFIG_MAX77620_THERMAL policy<{'arm64': '-'}> +CONFIG_MAX77620_WATCHDOG policy<{'arm64': '-'}> +CONFIG_MDIO_BCM_IPROC policy<{'arm64': '-'}> +CONFIG_MDIO_BUS_MUX policy<{'arm64': '-'}> +CONFIG_MDIO_BUS_MUX_BCM_IPROC policy<{'arm64': '-'}> +CONFIG_MDIO_BUS_MUX_GPIO policy<{'arm64': 'n'}> +CONFIG_MDIO_BUS_MUX_MESON_G12A policy<{'arm64': '-'}> +CONFIG_MDIO_BUS_MUX_MMIOREG policy<{'arm64': 'n'}> +CONFIG_MDIO_BUS_MUX_MULTIPLEXER policy<{'arm64': 'n'}> +CONFIG_MDIO_HISI_FEMAC policy<{'arm64': 'n'}> +CONFIG_MDIO_I2C policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_MDIO_MSCC_MIIM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_MDIO_OCTEON policy<{'arm64': 'n'}> +CONFIG_MDIO_SUN4I policy<{'arm64': '-'}> +CONFIG_MDIO_XGENE policy<{'arm64': '-'}> +CONFIG_MDM_GCC_9615 policy<{'arm64': '-'}> +CONFIG_MDM_LCC_9615 policy<{'arm64': '-'}> +CONFIG_MEDIATEK_MT6577_AUXADC policy<{'arm64': '-'}> +CONFIG_MEDIATEK_WATCHDOG policy<{'arm64': '-'}> +CONFIG_MEDIA_CEC_RC policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_MESON_CANVAS policy<{'arm64': '-'}> +CONFIG_MESON_CLK_MEASURE policy<{'arm64': '-'}> +CONFIG_MESON_EE_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_MESON_EFUSE policy<{'arm64': '-'}> +CONFIG_MESON_GXBB_WATCHDOG policy<{'arm64': '-'}> +CONFIG_MESON_GXL_PHY policy<{'arm64': '-'}> +CONFIG_MESON_GX_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_MESON_GX_SOCINFO policy<{'arm64': '-'}> +CONFIG_MESON_IRQ_GPIO policy<{'arm64': '-'}> +CONFIG_MESON_MX_EFUSE policy<{'arm64': '-'}> +CONFIG_MESON_MX_SOCINFO policy<{'arm64': '-'}> +CONFIG_MESON_SARADC policy<{'arm64': '-'}> +CONFIG_MESON_SM policy<{'arm64': '-'}> +CONFIG_MESON_WATCHDOG policy<{'arm64': '-'}> +CONFIG_MFD_AC100 policy<{'arm64': '-'}> +CONFIG_MFD_ACT8945A policy<{'arm64': 'n'}> +CONFIG_MFD_AHC1EC0 policy<{'amd64': '-'}> +CONFIG_MFD_ALTERA_SYSMGR policy<{'arm64': '-'}> +CONFIG_MFD_AS3722 policy<{'arm64': 'n'}> +CONFIG_MFD_ATMEL_FLEXCOM policy<{'arm64': 'n'}> +CONFIG_MFD_ATMEL_HLCDC policy<{'arm64': 'n'}> +CONFIG_MFD_AXP20X_RSB policy<{'arm64': '-'}> +CONFIG_MFD_CPCAP policy<{'arm64': 'n'}> +CONFIG_MFD_CS47L35 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_MFD_HI6421_PMIC policy<{'arm64': 'n'}> +CONFIG_MFD_HI655X_PMIC policy<{'arm64': '-'}> +CONFIG_MFD_LOCHNAGAR policy<{'arm64': 'n'}> +CONFIG_MFD_MAX77620 policy<{'arm64': 'n'}> +CONFIG_MFD_MAX77650 policy<{'arm64': 'n'}> +CONFIG_MFD_MAX77686 policy<{'arm64': 'n'}> +CONFIG_MFD_QCOM_RPM policy<{'arm64': '-'}> +CONFIG_MFD_RK808 policy<{'arm64': 'n'}> +CONFIG_MFD_RN5T618 policy<{'arm64': 'n'}> +CONFIG_MFD_ROHM_BD70528 policy<{'arm64': 'n'}> +CONFIG_MFD_ROHM_BD718XX policy<{'arm64': 'n'}> +CONFIG_MFD_SC27XX_PMIC policy<{'arm64': '-'}> +CONFIG_MFD_SPMI_PMIC policy<{'arm64': '-'}> +CONFIG_MFD_STMFX policy<{'arm64': 'n'}> +CONFIG_MFD_STMPE policy<{'arm64': 'n'}> +CONFIG_MFD_STPMIC1 policy<{'arm64': 'n'}> +CONFIG_MFD_SUN4I_GPADC policy<{'arm64': '-'}> +CONFIG_MFD_SUN6I_PRCM policy<{'arm64': '-'}> +CONFIG_MFD_TC3589X policy<{'arm64': 'n'}> +CONFIG_MFD_TI_AM335X_TSCADC policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_MFD_TI_LP87565 policy<{'arm64': 'n'}> +CONFIG_MFD_TPS65218 policy<{'arm64': 'n'}> +CONFIG_MFD_VEXPRESS_SYSREG policy<{'arm64': '-'}> +CONFIG_MII policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_MLX5_EN_TLS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_MLX5_FPGA_TLS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_MLX5_TLS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_MLXBF_TMFIFO policy<{'arm64': 'n'}> +CONFIG_MLXREG_HOTPLUG policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_MLXREG_IO policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_MMC_ARMMMCI policy<{'arm64': 'n'}> +CONFIG_MMC_BCM2835 policy<{'arm64': '-'}> +CONFIG_MMC_CAVIUM_THUNDERX policy<{'arm64': '-'}> +CONFIG_MMC_DW policy<{'arm64': 'n'}> +CONFIG_MMC_DW_BLUEFIELD policy<{'arm64': '-'}> +CONFIG_MMC_DW_EXYNOS policy<{'arm64': '-'}> +CONFIG_MMC_DW_HI3798CV200 policy<{'arm64': '-'}> +CONFIG_MMC_DW_K3 policy<{'arm64': '-'}> +CONFIG_MMC_DW_PCI policy<{'arm64': '-'}> +CONFIG_MMC_DW_PLTFM policy<{'arm64': '-'}> +CONFIG_MMC_DW_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_MMC_MESON_GX policy<{'arm64': '-'}> +CONFIG_MMC_MESON_MX_SDIO policy<{'arm64': '-'}> +CONFIG_MMC_MXC policy<{'arm64': '-'}> +CONFIG_MMC_QCOM_DML policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_AM654 policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_BRCMSTB policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_CADENCE policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_ESDHC_IMX policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_IPROC policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_MSM policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_OF_ARASAN policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_OF_ASPEED policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_OF_AT91 policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_OF_DWCMSHC policy<{'arm64': 'n'}> +CONFIG_MMC_SDHCI_OF_ESDHC policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_PXAV3 policy<{'arm64': '-'}> +CONFIG_MMC_SDHCI_SPRD policy<{'arm64': '-'}> +CONFIG_MMC_SDHI policy<{'arm64': '-'}> +CONFIG_MMC_SDHI_INTERNAL_DMAC policy<{'arm64': '-'}> +CONFIG_MMC_SDHI_SYS_DMAC policy<{'arm64': '-'}> +CONFIG_MMC_SDRICOH_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_MMC_SH_MMCIF policy<{'arm64': '-'}> +CONFIG_MMC_STM32_SDMMC policy<{'arm64': '-'}> +CONFIG_MMC_SUNXI policy<{'arm64': '-'}> +CONFIG_MMC_TMIO_CORE policy<{'arm64': '-'}> +CONFIG_MOST_DIM2 policy<{'arm64': 'n'}> +CONFIG_MOUSE_PS2_ELANTECH_SMBUS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_MOXTET policy<{'arm64': 'n'}> +CONFIG_MSCC_OCELOT_SWITCH policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_MSCC_OCELOT_SWITCH_OCELOT policy<{'arm64': 'n'}> +CONFIG_MSM_GCC_8660 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8916 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8960 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8974 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8994 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8996 policy<{'arm64': '-'}> +CONFIG_MSM_GCC_8998 policy<{'arm64': '-'}> +CONFIG_MSM_LCC_8960 policy<{'arm64': '-'}> +CONFIG_MSM_MMCC_8960 policy<{'arm64': '-'}> +CONFIG_MSM_MMCC_8974 policy<{'arm64': '-'}> +CONFIG_MSM_MMCC_8996 policy<{'arm64': '-'}> +CONFIG_MTD_AFS_PARTS policy<{'arm64': 'n'}> +CONFIG_MTD_NAND_BRCMNAND policy<{'arm64': 'n'}> +CONFIG_MTD_NAND_DENALI_DT policy<{'arm64': 'n'}> +CONFIG_MTD_NAND_FSL_IFC policy<{'arm64': '-'}> +CONFIG_MTD_NAND_GPMI_NAND policy<{'arm64': '-'}> +CONFIG_MTD_NAND_HISI504 policy<{'arm64': '-'}> +CONFIG_MTD_NAND_MARVELL policy<{'arm64': '-'}> +CONFIG_MTD_NAND_MESON policy<{'arm64': '-'}> +CONFIG_MTD_NAND_MTK policy<{'arm64': '-'}> +CONFIG_MTD_NAND_MXC policy<{'arm64': '-'}> +CONFIG_MTD_NAND_QCOM policy<{'arm64': '-'}> +CONFIG_MTD_NAND_SUNXI policy<{'arm64': '-'}> +CONFIG_MTD_PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_MTD_PCMCIA_ANONYMOUS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_MTD_PHYSMAP_GEMINI policy<{'arm64': '-'}> +CONFIG_MTD_PHYSMAP_GPIO_ADDR policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_MTD_PHYSMAP_OF policy<{'arm64': 'n'}> +CONFIG_MTD_PHYSMAP_VERSATILE policy<{'arm64': '-'}> +CONFIG_MTK_CMDQ policy<{'arm64': '-'}> +CONFIG_MTK_CMDQ_MBOX policy<{'arm64': '-'}> +CONFIG_MTK_CQDMA policy<{'arm64': '-'}> +CONFIG_MTK_EFUSE policy<{'arm64': '-'}> +CONFIG_MTK_HSDMA policy<{'arm64': '-'}> +CONFIG_MTK_INFRACFG policy<{'arm64': '-'}> +CONFIG_MTK_IOMMU policy<{'arm64': '-'}> +CONFIG_MTK_PMIC_WRAP policy<{'arm64': '-'}> +CONFIG_MTK_SCPSYS policy<{'arm64': '-'}> +CONFIG_MTK_SMI policy<{'arm64': '-'}> +CONFIG_MTK_THERMAL policy<{'arm64': '-'}> +CONFIG_MTK_TIMER policy<{'arm64': '-'}> +CONFIG_MTK_UART_APDMA policy<{'arm64': '-'}> +CONFIG_MULTIPLEXER policy<{'arm64': '-'}> +CONFIG_MUX_ADG792A policy<{'arm64': '-'}> +CONFIG_MUX_ADGS1408 policy<{'arm64': '-'}> +CONFIG_MUX_GPIO policy<{'arm64': '-'}> +CONFIG_MUX_MMIO policy<{'arm64': '-'}> +CONFIG_MVEBU_GICP policy<{'arm64': '-'}> +CONFIG_MVEBU_ICU policy<{'arm64': '-'}> +CONFIG_MVEBU_ODMI policy<{'arm64': '-'}> +CONFIG_MVEBU_PIC policy<{'arm64': '-'}> +CONFIG_MVEBU_SEI policy<{'arm64': '-'}> +CONFIG_MVNETA policy<{'arm64': '-'}> +CONFIG_MVPP2 policy<{'arm64': '-'}> +CONFIG_MV_XOR policy<{'arm64': '-'}> +CONFIG_MV_XOR_V2 policy<{'arm64': 'n'}> +CONFIG_MX3_IPU policy<{'arm64': '-'}> +CONFIG_MX3_IPU_IRQS policy<{'arm64': '-'}> +CONFIG_MXC_CLK policy<{'arm64': '-'}> +CONFIG_MXC_CLK_SCU policy<{'arm64': '-'}> +CONFIG_MXS_DMA policy<{'arm64': '-'}> +CONFIG_NCSI_OEM_CMD_GET_MAC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_NETFILTER_NETLINK policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NETFILTER_NETLINK_OSF policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_DSA_VITESSE_VSC73XX policy<{'arm64': '-'}> +CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM policy<{'arm64': 'n'}> +CONFIG_NET_DSA_VITESSE_VSC73XX_SPI policy<{'arm64': 'n'}> +CONFIG_NET_SCH_ETF policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_SCH_SKBPRIO policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_SCH_TAPRIO policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_VENDOR_ALLWINNER policy<{'arm64': '-'}> +CONFIG_NET_VENDOR_FREESCALE policy<{'arm64': '-'}> +CONFIG_NET_VENDOR_FUJITSU policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_VENDOR_MEDIATEK policy<{'arm64': '-'}> +CONFIG_NET_VENDOR_NETERION policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_NET_VENDOR_XIRCOM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NET_XGENE policy<{'arm64': '-'}> +CONFIG_NET_XGENE_V2 policy<{'arm64': '-'}> +CONFIG_NFIT_SECURITY_DEBUG policy<{'amd64': 'n', 'arm64': '-'}> +CONFIG_NI_XGE_MANAGEMENT_ENET policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_NODES_SHIFT policy<{'amd64': '10', 'arm64': '10'}> +CONFIG_NODES_SPAN_OTHER_NODES policy<{'amd64': '-'}> +CONFIG_NVMEM_BCM_OCOTP policy<{'arm64': '-'}> +CONFIG_NVMEM_IMX_IIM policy<{'arm64': '-'}> +CONFIG_NVMEM_IMX_OCOTP policy<{'arm64': '-'}> +CONFIG_NVMEM_IMX_OCOTP_SCU policy<{'arm64': '-'}> +CONFIG_NVMEM_REBOOT_MODE policy<{'arm64': 'n'}> +CONFIG_NVMEM_SNVS_LPGPR policy<{'arm64': '-'}> +CONFIG_NVMEM_SUNXI_SID policy<{'arm64': '-'}> +CONFIG_NVMEM_ZYNQMP policy<{'arm64': '-'}> +CONFIG_OCTEONTX2_AF policy<{'arm64': 'n'}> +CONFIG_OCTEONTX2_MBOX policy<{'arm64': '-'}> +CONFIG_OF_DYNAMIC policy<{'arm64': '-'}> +CONFIG_OF_FPGA_REGION policy<{'arm64': 'n'}> +CONFIG_OF_OVERLAY policy<{'arm64': 'n'}> +CONFIG_OF_PMEM policy<{'arm64': 'y'}> +CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT policy<{'arm64': '-'}> +CONFIG_OF_RESOLVE policy<{'arm64': '-'}> +CONFIG_OMAP2PLUS_MBOX policy<{'arm64': '-'}> +CONFIG_OMAP_MBOX_KFIFO_SIZE policy<{'arm64': '-'}> +CONFIG_OMAP_USB2 policy<{'arm64': '-'}> +CONFIG_OPTEE policy<{'arm64': '-'}> +CONFIG_OPTEE_SHM_NUM_PRIV_PAGES policy<{'arm64': '-'}> +CONFIG_OVERLAY_FS_METACOPY policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_OVERLAY_FS_REDIRECT_DIR policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_OVERLAY_FS_XINO_AUTO policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_OWL_DMA policy<{'arm64': '-'}> +CONFIG_OWL_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_OWL_PM_DOMAINS_HELPER policy<{'arm64': '-'}> +CONFIG_OWL_TIMER policy<{'arm64': '-'}> +CONFIG_PATA_IMX policy<{'arm64': '-'}> +CONFIG_PATA_OF_PLATFORM policy<{'arm64': 'n'}> +CONFIG_PATA_PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PATA_SIS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PCCARD_NONSTATIC policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PCIE_AL policy<{'arm64': 'n'}> +CONFIG_PCIE_ALTERA policy<{'arm64': 'n'}> +CONFIG_PCIE_ALTERA_MSI policy<{'arm64': '-'}> +CONFIG_PCIE_ARMADA_8K policy<{'arm64': '-'}> +CONFIG_PCIE_CADENCE policy<{'arm64': '-'}> +CONFIG_PCIE_CADENCE_EP policy<{'arm64': 'n'}> +CONFIG_PCIE_CADENCE_HOST policy<{'arm64': 'n'}> +CONFIG_PCIE_DW_EP policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_PCIE_DW_PLAT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_PCIE_DW_PLAT_EP policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PCIE_DW_PLAT_HOST policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PCIE_HISI_STB policy<{'arm64': '-'}> +CONFIG_PCIE_IPROC policy<{'arm64': '-'}> +CONFIG_PCIE_IPROC_MSI policy<{'arm64': '-'}> +CONFIG_PCIE_IPROC_PLATFORM policy<{'arm64': '-'}> +CONFIG_PCIE_KIRIN policy<{'arm64': 'n'}> +CONFIG_PCIE_MEDIATEK policy<{'arm64': '-'}> +CONFIG_PCIE_MOBIVEIL policy<{'arm64': '-'}> +CONFIG_PCIE_QCOM policy<{'arm64': '-'}> +CONFIG_PCIE_RCAR policy<{'arm64': '-'}> +CONFIG_PCIE_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_PCIE_ROCKCHIP_EP policy<{'arm64': '-'}> +CONFIG_PCIE_ROCKCHIP_HOST policy<{'arm64': '-'}> +CONFIG_PCIE_XILINX policy<{'arm64': 'n'}> +CONFIG_PCIE_XILINX_NWL policy<{'arm64': '-'}> +CONFIG_PCI_AARDVARK policy<{'arm64': '-'}> +CONFIG_PCI_BRIDGE_EMUL policy<{'arm64': '-'}> +CONFIG_PCI_FTPCI100 policy<{'arm64': 'n'}> +CONFIG_PCI_HISI policy<{'arm64': 'n'}> +CONFIG_PCI_HOST_COMMON policy<{'arm64': '-'}> +CONFIG_PCI_HOST_GENERIC policy<{'arm64': 'n'}> +CONFIG_PCI_HOST_THUNDER_ECAM policy<{'arm64': 'n'}> +CONFIG_PCI_HOST_THUNDER_PEM policy<{'arm64': 'n'}> +CONFIG_PCI_IMX6 policy<{'arm64': '-'}> +CONFIG_PCI_KEYSTONE policy<{'arm64': '-'}> +CONFIG_PCI_KEYSTONE_EP policy<{'arm64': '-'}> +CONFIG_PCI_KEYSTONE_HOST policy<{'arm64': '-'}> +CONFIG_PCI_LAYERSCAPE policy<{'arm64': '-'}> +CONFIG_PCI_LAYERSCAPE_EP policy<{'arm64': '-'}> +CONFIG_PCI_MESON policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PCI_P2PDMA policy<{'amd64': 'y'}> +CONFIG_PCI_PF_STUB policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PCI_XGENE policy<{'arm64': 'n'}> +CONFIG_PCI_XGENE_MSI policy<{'arm64': '-'}> +CONFIG_PCMCIA policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_3C574 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_3C589 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_AHA152X policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_ATMEL policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_AXNET policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_FDOMAIN policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_FMVJ18X policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_HERMES policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_LOAD_CIS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PCMCIA_NMCLAN policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_PCNET policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_QLOGIC policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_RAYCS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_SMC91C92 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_SPECTRUM policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_SYM53C500 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_WL3501 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PCMCIA_XIRC2PS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PD6729 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PERCPU_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_PHY_AM654_SERDES policy<{'arm64': '-'}> +CONFIG_PHY_BCM_NS_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_BCM_NS_USB3 policy<{'arm64': '-'}> +CONFIG_PHY_BCM_SR_PCIE policy<{'arm64': '-'}> +CONFIG_PHY_BCM_SR_USB policy<{'arm64': '-'}> +CONFIG_PHY_BERLIN_SATA policy<{'arm64': '-'}> +CONFIG_PHY_BERLIN_USB policy<{'arm64': '-'}> +CONFIG_PHY_BRCM_SATA policy<{'arm64': '-'}> +CONFIG_PHY_BRCM_USB policy<{'arm64': '-'}> +CONFIG_PHY_CADENCE_DP policy<{'arm64': 'n'}> +CONFIG_PHY_CADENCE_DPHY policy<{'arm64': 'n'}> +CONFIG_PHY_CADENCE_SIERRA policy<{'arm64': 'n'}> +CONFIG_PHY_FSL_IMX8MQ_USB policy<{'arm64': 'n'}> +CONFIG_PHY_HI3660_USB policy<{'arm64': '-'}> +CONFIG_PHY_HI6220_USB policy<{'arm64': '-'}> +CONFIG_PHY_HISI_INNO_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_HISTB_COMBPHY policy<{'arm64': '-'}> +CONFIG_PHY_MAPPHONE_MDM6600 policy<{'arm64': 'n'}> +CONFIG_PHY_MESON8B_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_MESON_G12A_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_MESON_G12A_USB3_PCIE policy<{'arm64': '-'}> +CONFIG_PHY_MESON_GXL_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_MESON_GXL_USB3 policy<{'arm64': '-'}> +CONFIG_PHY_MIXEL_MIPI_DPHY policy<{'arm64': 'n'}> +CONFIG_PHY_MTK_TPHY policy<{'arm64': '-'}> +CONFIG_PHY_MTK_UFS policy<{'arm64': '-'}> +CONFIG_PHY_MTK_XSPHY policy<{'arm64': '-'}> +CONFIG_PHY_MVEBU_A3700_COMPHY policy<{'arm64': '-'}> +CONFIG_PHY_MVEBU_A3700_UTMI policy<{'arm64': '-'}> +CONFIG_PHY_MVEBU_A38X_COMPHY policy<{'arm64': '-'}> +CONFIG_PHY_MVEBU_CP110_COMPHY policy<{'arm64': '-'}> +CONFIG_PHY_NS2_PCIE policy<{'arm64': '-'}> +CONFIG_PHY_NS2_USB_DRD policy<{'arm64': '-'}> +CONFIG_PHY_OCELOT_SERDES policy<{'arm64': 'n'}> +CONFIG_PHY_QCOM_APQ8064_SATA policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_IPQ806X_SATA policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_PCIE2 policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_QMP policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_QUSB2 policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_UFS policy<{'arm64': '-'}> +CONFIG_PHY_QCOM_UFS_14NM policy<{'arm64': '-'}> +CONFIG_PHY_RCAR_GEN2 policy<{'arm64': '-'}> +CONFIG_PHY_RCAR_GEN3_PCIE policy<{'arm64': '-'}> +CONFIG_PHY_RCAR_GEN3_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_RCAR_GEN3_USB3 policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_DP policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_EMMC policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_INNO_HDMI policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_INNO_USB2 policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_PCIE policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_TYPEC policy<{'arm64': '-'}> +CONFIG_PHY_ROCKCHIP_USB policy<{'arm64': '-'}> +CONFIG_PHY_SUN4I_USB policy<{'arm64': '-'}> +CONFIG_PHY_SUN6I_MIPI_DPHY policy<{'arm64': '-'}> +CONFIG_PHY_SUN9I_USB policy<{'arm64': '-'}> +CONFIG_PHY_XGENE policy<{'arm64': 'n'}> +CONFIG_PINCTRL_APQ8064 policy<{'arm64': '-'}> +CONFIG_PINCTRL_APQ8084 policy<{'arm64': '-'}> +CONFIG_PINCTRL_ARMADA_37XX policy<{'arm64': '-'}> +CONFIG_PINCTRL_ARMADA_AP806 policy<{'arm64': '-'}> +CONFIG_PINCTRL_ARMADA_CP110 policy<{'arm64': '-'}> +CONFIG_PINCTRL_AS370 policy<{'arm64': '-'}> +CONFIG_PINCTRL_AS3722 policy<{'arm64': '-'}> +CONFIG_PINCTRL_AXP209 policy<{'arm64': 'n'}> +CONFIG_PINCTRL_BCM2835 policy<{'arm64': '-'}> +CONFIG_PINCTRL_BERLIN policy<{'arm64': '-'}> +CONFIG_PINCTRL_BERLIN_BG4CT policy<{'arm64': '-'}> +CONFIG_PINCTRL_BM1880 policy<{'arm64': '-'}> +CONFIG_PINCTRL_CANNONLAKE policy<{'amd64': 'y'}> +CONFIG_PINCTRL_CS47L35 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_PINCTRL_IMX policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX8MM policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX8MN policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX8MQ policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX8QM policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX8QXP policy<{'arm64': '-'}> +CONFIG_PINCTRL_IMX_SCU policy<{'arm64': '-'}> +CONFIG_PINCTRL_INTEL policy<{'amd64': 'y'}> +CONFIG_PINCTRL_IPQ4019 policy<{'arm64': '-'}> +CONFIG_PINCTRL_IPQ8064 policy<{'arm64': '-'}> +CONFIG_PINCTRL_IPQ8074 policy<{'arm64': '-'}> +CONFIG_PINCTRL_IPROC_GPIO policy<{'arm64': '-'}> +CONFIG_PINCTRL_LOCHNAGAR policy<{'arm64': '-'}> +CONFIG_PINCTRL_MAX77620 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MDM9615 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON8_PMX policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON_AXG policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON_AXG_PMX policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON_G12A policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON_GXBB policy<{'arm64': '-'}> +CONFIG_PINCTRL_MESON_GXL policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8660 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8916 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8960 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8994 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8996 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8998 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MSM8X74 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT2712 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT6397 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT6765 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT6797 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT7622 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT8173 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT8183 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MT8516 policy<{'arm64': '-'}> +CONFIG_PINCTRL_MTK policy<{'arm64': '-'}> +CONFIG_PINCTRL_MTK_MOORE policy<{'arm64': '-'}> +CONFIG_PINCTRL_MTK_PARIS policy<{'arm64': '-'}> +CONFIG_PINCTRL_MVEBU policy<{'arm64': '-'}> +CONFIG_PINCTRL_NS2_MUX policy<{'arm64': '-'}> +CONFIG_PINCTRL_OCELOT policy<{'arm64': 'n'}> +CONFIG_PINCTRL_OWL policy<{'arm64': '-'}> +CONFIG_PINCTRL_PALMAS policy<{'arm64': 'n'}> +CONFIG_PINCTRL_PFC_R8A774A1 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A774C0 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A7795 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A7796 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A77965 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A77970 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A77980 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A77990 policy<{'arm64': '-'}> +CONFIG_PINCTRL_PFC_R8A77995 policy<{'arm64': '-'}> +CONFIG_PINCTRL_QCOM_SPMI_PMIC policy<{'arm64': '-'}> +CONFIG_PINCTRL_QCOM_SSBI_PMIC policy<{'arm64': '-'}> +CONFIG_PINCTRL_QCS404 policy<{'arm64': '-'}> +CONFIG_PINCTRL_QDF2XXX policy<{'arm64': '-'}> +CONFIG_PINCTRL_RK805 policy<{'arm64': '-'}> +CONFIG_PINCTRL_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_PINCTRL_S700 policy<{'arm64': '-'}> +CONFIG_PINCTRL_S900 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SC7180 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SDM660 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SDM845 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SH_PFC policy<{'arm64': '-'}> +CONFIG_PINCTRL_SINGLE policy<{'arm64': 'n'}> +CONFIG_PINCTRL_SM8150 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SPRD policy<{'arm64': '-'}> +CONFIG_PINCTRL_SPRD_SC9860 policy<{'arm64': '-'}> +CONFIG_PINCTRL_STMFX policy<{'arm64': 'n'}> +CONFIG_PINCTRL_SUN4I_A10 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN50I_A64 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN50I_A64_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN50I_H5 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN50I_H6 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN50I_H6_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN5I policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN6I_A31 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN6I_A31_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_A23 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_A23_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_A33 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_A83T policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_A83T_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_H3 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_H3_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN8I_V3S policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN9I_A80 policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUN9I_A80_R policy<{'arm64': '-'}> +CONFIG_PINCTRL_SUNXI policy<{'arm64': '-'}> +CONFIG_PL320_MBOX policy<{'arm64': 'n'}> +CONFIG_PL330_DMA policy<{'arm64': 'n'}> +CONFIG_PLATFORM_MHU policy<{'arm64': 'n'}> +CONFIG_PM8916_WATCHDOG policy<{'arm64': '-'}> +CONFIG_POWER_RESET_AS3722 policy<{'arm64': '-'}> +CONFIG_POWER_RESET_GPIO policy<{'arm64': 'n'}> +CONFIG_POWER_RESET_GPIO_RESTART policy<{'arm64': 'n'}> +CONFIG_POWER_RESET_HISI policy<{'arm64': '-'}> +CONFIG_POWER_RESET_LTC2952 policy<{'arm64': 'n'}> +CONFIG_POWER_RESET_MSM policy<{'arm64': '-'}> +CONFIG_POWER_RESET_QCOM_PON policy<{'arm64': '-'}> +CONFIG_POWER_RESET_SC27XX policy<{'arm64': '-'}> +CONFIG_POWER_RESET_SYSCON policy<{'arm64': 'n'}> +CONFIG_POWER_RESET_SYSCON_POWEROFF policy<{'arm64': 'n'}> +CONFIG_POWER_RESET_VEXPRESS policy<{'arm64': '-'}> +CONFIG_PREEMPT policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PREEMPT_VOLUNTARY policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PRIME_NUMBERS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PSTORE_842_COMPRESS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PSTORE_842_COMPRESS_DEFAULT policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PSTORE_COMPRESS_DEFAULT policy<{'amd64': '"lz4hc"', 'arm64': '"lz4hc"'}> +CONFIG_PSTORE_DEFLATE_COMPRESS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PSTORE_DEFLATE_COMPRESS_DEFAULT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_PSTORE_LZ4HC_COMPRESS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_PSTORE_LZ4HC_COMPRESS_DEFAULT policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PSTORE_ZSTD_COMPRESS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_PSTORE_ZSTD_COMPRESS_DEFAULT policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_PTP_1588_CLOCK_DTE policy<{'arm64': '-'}> +CONFIG_PTP_1588_CLOCK_QORIQ policy<{'arm64': '-'}> +CONFIG_PWM_ATMEL_HLCDC_PWM policy<{'arm64': '-'}> +CONFIG_PWM_BCM2835 policy<{'arm64': '-'}> +CONFIG_PWM_BCM_IPROC policy<{'arm64': '-'}> +CONFIG_PWM_BERLIN policy<{'arm64': '-'}> +CONFIG_PWM_BRCMSTB policy<{'arm64': '-'}> +CONFIG_PWM_FSL_FTM policy<{'arm64': 'n'}> +CONFIG_PWM_HIBVT policy<{'arm64': '-'}> +CONFIG_PWM_IMX1 policy<{'arm64': '-'}> +CONFIG_PWM_IMX27 policy<{'arm64': '-'}> +CONFIG_PWM_IMX_TPM policy<{'arm64': '-'}> +CONFIG_PWM_LPSS policy<{'amd64': 'm'}> +CONFIG_PWM_LPSS_PCI policy<{'amd64': 'm'}> +CONFIG_PWM_LPSS_PLATFORM policy<{'amd64': 'm'}> +CONFIG_PWM_MEDIATEK policy<{'arm64': '-'}> +CONFIG_PWM_MESON policy<{'arm64': '-'}> +CONFIG_PWM_MTK_DISP policy<{'arm64': '-'}> +CONFIG_PWM_RCAR policy<{'arm64': '-'}> +CONFIG_PWM_RENESAS_TPU policy<{'arm64': '-'}> +CONFIG_PWM_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_PWM_SPRD policy<{'arm64': '-'}> +CONFIG_PWM_STMPE policy<{'arm64': '-'}> +CONFIG_PWM_SUN4I policy<{'arm64': '-'}> +CONFIG_PWM_TIECAP policy<{'arm64': '-'}> +CONFIG_PWM_TIEHRPWM policy<{'arm64': '-'}> +CONFIG_PWRSEQ_EMMC policy<{'arm64': 'y'}> +CONFIG_PWRSEQ_SD8787 policy<{'arm64': 'n'}> +CONFIG_PWRSEQ_SIMPLE policy<{'arm64': 'y'}> +CONFIG_PXA168_ETH policy<{'arm64': '-'}> +CONFIG_QCA7000 policy<{'arm64': '-'}> +CONFIG_QCA7000_SPI policy<{'arm64': 'n'}> +CONFIG_QCA7000_UART policy<{'arm64': 'n'}> +CONFIG_QCOM_A53PLL policy<{'arm64': '-'}> +CONFIG_QCOM_AOSS_QMP policy<{'arm64': '-'}> +CONFIG_QCOM_APCS_IPC policy<{'arm64': '-'}> +CONFIG_QCOM_APR policy<{'arm64': '-'}> +CONFIG_QCOM_BAM_DMA policy<{'arm64': '-'}> +CONFIG_QCOM_CLK_APCS_MSM8916 policy<{'arm64': '-'}> +CONFIG_QCOM_CLK_RPM policy<{'arm64': '-'}> +CONFIG_QCOM_CLK_RPMH policy<{'arm64': '-'}> +CONFIG_QCOM_CLK_SMD_RPM policy<{'arm64': '-'}> +CONFIG_QCOM_COINCELL policy<{'arm64': '-'}> +CONFIG_QCOM_COMMAND_DB policy<{'arm64': '-'}> +CONFIG_QCOM_EBI2 policy<{'arm64': '-'}> +CONFIG_QCOM_FASTRPC policy<{'arm64': '-'}> +CONFIG_QCOM_GDSC policy<{'arm64': '-'}> +CONFIG_QCOM_GENI_SE policy<{'arm64': '-'}> +CONFIG_QCOM_GLINK_SSR policy<{'arm64': '-'}> +CONFIG_QCOM_GSBI policy<{'arm64': '-'}> +CONFIG_QCOM_HFPLL policy<{'arm64': '-'}> +CONFIG_QCOM_IOMMU policy<{'arm64': '-'}> +CONFIG_QCOM_IRQ_COMBINER policy<{'arm64': '-'}> +CONFIG_QCOM_L2_PMU policy<{'arm64': '-'}> +CONFIG_QCOM_L3_PMU policy<{'arm64': '-'}> +CONFIG_QCOM_LLCC policy<{'arm64': '-'}> +CONFIG_QCOM_MDT_LOADER policy<{'arm64': '-'}> +CONFIG_QCOM_PDC policy<{'arm64': '-'}> +CONFIG_QCOM_Q6V5_ADSP policy<{'arm64': '-'}> +CONFIG_QCOM_Q6V5_COMMON policy<{'arm64': '-'}> +CONFIG_QCOM_Q6V5_MSS policy<{'arm64': '-'}> +CONFIG_QCOM_Q6V5_PAS policy<{'arm64': '-'}> +CONFIG_QCOM_Q6V5_WCSS policy<{'arm64': '-'}> +CONFIG_QCOM_QFPROM policy<{'arm64': '-'}> +CONFIG_QCOM_QMI_HELPERS policy<{'arm64': '-'}> +CONFIG_QCOM_RMTFS_MEM policy<{'arm64': '-'}> +CONFIG_QCOM_RPMCC policy<{'arm64': '-'}> +CONFIG_QCOM_RPMH policy<{'arm64': '-'}> +CONFIG_QCOM_RPMHPD policy<{'arm64': '-'}> +CONFIG_QCOM_RPROC_COMMON policy<{'arm64': '-'}> +CONFIG_QCOM_SCM policy<{'arm64': '-'}> +CONFIG_QCOM_SCM_64 policy<{'arm64': '-'}> +CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT policy<{'arm64': '-'}> +CONFIG_QCOM_SDM845_LLCC policy<{'arm64': '-'}> +CONFIG_QCOM_SMD_RPM policy<{'arm64': '-'}> +CONFIG_QCOM_SMEM policy<{'arm64': '-'}> +CONFIG_QCOM_SMEM_STATE policy<{'arm64': '-'}> +CONFIG_QCOM_SMP2P policy<{'arm64': '-'}> +CONFIG_QCOM_SMSM policy<{'arm64': '-'}> +CONFIG_QCOM_SOCINFO policy<{'arm64': '-'}> +CONFIG_QCOM_SPMI_TEMP_ALARM policy<{'arm64': '-'}> +CONFIG_QCOM_SYSMON policy<{'arm64': '-'}> +CONFIG_QCOM_TSENS policy<{'arm64': '-'}> +CONFIG_QCOM_WCNSS_CTRL policy<{'arm64': '-'}> +CONFIG_QCOM_WCNSS_PIL policy<{'arm64': '-'}> +CONFIG_QCOM_WDT policy<{'arm64': '-'}> +CONFIG_QCS_GCC_404 policy<{'arm64': '-'}> +CONFIG_QCS_TURING_404 policy<{'arm64': '-'}> +CONFIG_QORIQ_CPUFREQ policy<{'arm64': 'n'}> +CONFIG_QORIQ_THERMAL policy<{'arm64': 'n'}> +CONFIG_QRTR policy<{'arm64': '-'}> +CONFIG_QRTR_SMD policy<{'arm64': '-'}> +CONFIG_QRTR_TUN policy<{'arm64': '-'}> +CONFIG_RASPBERRYPI_FIRMWARE policy<{'arm64': '-'}> +CONFIG_RASPBERRYPI_POWER policy<{'arm64': '-'}> +CONFIG_RAVB policy<{'arm64': '-'}> +CONFIG_RAVE_SP_CORE policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_RAVE_SP_EEPROM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_RBTREE_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_RCAR_DMAC policy<{'arm64': '-'}> +CONFIG_RCAR_GEN3_THERMAL policy<{'arm64': '-'}> +CONFIG_RCAR_THERMAL policy<{'arm64': '-'}> +CONFIG_REBOOT_MODE policy<{'arm64': '-'}> +CONFIG_REED_SOLOMON_TEST policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_REGULATOR_88PG86X policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_REGULATOR_ACT8945A policy<{'arm64': '-'}> +CONFIG_REGULATOR_AS3722 policy<{'arm64': '-'}> +CONFIG_REGULATOR_BD70528 policy<{'arm64': '-'}> +CONFIG_REGULATOR_BD718XX policy<{'arm64': '-'}> +CONFIG_REGULATOR_CPCAP policy<{'arm64': '-'}> +CONFIG_REGULATOR_DA9063 policy<{'arm64': 'n'}> +CONFIG_REGULATOR_HI6421 policy<{'arm64': '-'}> +CONFIG_REGULATOR_HI6421V530 policy<{'arm64': '-'}> +CONFIG_REGULATOR_HI655X policy<{'arm64': '-'}> +CONFIG_REGULATOR_LOCHNAGAR policy<{'arm64': '-'}> +CONFIG_REGULATOR_LP873X policy<{'arm64': 'n'}> +CONFIG_REGULATOR_LP87565 policy<{'arm64': '-'}> +CONFIG_REGULATOR_MAX77620 policy<{'arm64': '-'}> +CONFIG_REGULATOR_MAX77650 policy<{'arm64': '-'}> +CONFIG_REGULATOR_MAX77686 policy<{'arm64': '-'}> +CONFIG_REGULATOR_MAX77802 policy<{'arm64': '-'}> +CONFIG_REGULATOR_MAX8973 policy<{'arm64': 'n'}> +CONFIG_REGULATOR_MCP16502 policy<{'arm64': 'n'}> +CONFIG_REGULATOR_MT6380 policy<{'arm64': '-'}> +CONFIG_REGULATOR_QCOM_RPM policy<{'arm64': '-'}> +CONFIG_REGULATOR_QCOM_RPMH policy<{'arm64': '-'}> +CONFIG_REGULATOR_QCOM_SMD_RPM policy<{'arm64': '-'}> +CONFIG_REGULATOR_RK808 policy<{'arm64': '-'}> +CONFIG_REGULATOR_RN5T618 policy<{'arm64': '-'}> +CONFIG_REGULATOR_SC2731 policy<{'arm64': '-'}> +CONFIG_REGULATOR_STPMIC1 policy<{'arm64': '-'}> +CONFIG_REGULATOR_SY8106A policy<{'arm64': 'n'}> +CONFIG_REGULATOR_SY8824X policy<{'arm64': 'n'}> +CONFIG_REGULATOR_TPS65218 policy<{'arm64': '-'}> +CONFIG_REGULATOR_VCTRL policy<{'arm64': 'n'}> +CONFIG_REGULATOR_VEXPRESS policy<{'arm64': '-'}> +CONFIG_RENESAS_DMA policy<{'arm64': '-'}> +CONFIG_RENESAS_IRQC policy<{'arm64': '-'}> +CONFIG_RENESAS_RZAWDT policy<{'arm64': '-'}> +CONFIG_RENESAS_USB_DMAC policy<{'arm64': '-'}> +CONFIG_RENESAS_WDT policy<{'arm64': '-'}> +CONFIG_RESET_BERLIN policy<{'arm64': '-'}> +CONFIG_RESET_BRCMSTB policy<{'arm64': '-'}> +CONFIG_RESET_HISI policy<{'arm64': '-'}> +CONFIG_RESET_IMX7 policy<{'arm64': '-'}> +CONFIG_RESET_MESON policy<{'arm64': '-'}> +CONFIG_RESET_MESON_AUDIO_ARB policy<{'arm64': '-'}> +CONFIG_RESET_QCOM_AOSS policy<{'arm64': '-'}> +CONFIG_RESET_QCOM_PDC policy<{'arm64': '-'}> +CONFIG_RESET_SCMI policy<{'arm64': '-'}> +CONFIG_RESET_SIMPLE policy<{'arm64': '-'}> +CONFIG_RESET_SUNXI policy<{'arm64': '-'}> +CONFIG_RESET_TI_SCI policy<{'arm64': '-'}> +CONFIG_RN5T618_WATCHDOG policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_ANALOGIX_DP policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_CDN_DP policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_DW_HDMI policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_DW_MIPI_DSI policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_EFUSE policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_GRF policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_INNO_HDMI policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_IODOMAIN policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_IOMMU policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_LVDS policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_MBOX policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_RGB policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_RK3066_HDMI policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_SARADC policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_THERMAL policy<{'arm64': '-'}> +CONFIG_ROCKCHIP_TIMER policy<{'arm64': '-'}> +CONFIG_RPMSG_QCOM_GLINK_SMEM policy<{'arm64': '-'}> +CONFIG_RPMSG_QCOM_SMD policy<{'arm64': '-'}> +CONFIG_RST_RCAR policy<{'arm64': '-'}> +CONFIG_RTC_DRV_AM1805 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_RTC_DRV_ARMADA38X policy<{'arm64': '-'}> +CONFIG_RTC_DRV_AS3722 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_BD70528 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_BRCMSTB policy<{'arm64': '-'}> +CONFIG_RTC_DRV_CADENCE policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_CPCAP policy<{'arm64': '-'}> +CONFIG_RTC_DRV_CROS_EC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_RTC_DRV_FSL_FTM_ALARM policy<{'arm64': '-'}> +CONFIG_RTC_DRV_HYM8563 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_IMXDI policy<{'arm64': '-'}> +CONFIG_RTC_DRV_IMX_SC policy<{'arm64': '-'}> +CONFIG_RTC_DRV_ISL12026 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_MAX77686 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_MESON_VRTC policy<{'arm64': '-'}> +CONFIG_RTC_DRV_MT7622 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_MV policy<{'arm64': '-'}> +CONFIG_RTC_DRV_MXC policy<{'arm64': '-'}> +CONFIG_RTC_DRV_MXC_V2 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_PL030 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_PL031 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_PM8XXX policy<{'arm64': '-'}> +CONFIG_RTC_DRV_R7301 policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_RK808 policy<{'arm64': '-'}> +CONFIG_RTC_DRV_RTD119X policy<{'arm64': '-'}> +CONFIG_RTC_DRV_SC27XX policy<{'arm64': '-'}> +CONFIG_RTC_DRV_SH policy<{'arm64': '-'}> +CONFIG_RTC_DRV_SNVS policy<{'arm64': 'n'}> +CONFIG_RTC_DRV_SUN6I policy<{'arm64': '-'}> +CONFIG_RTC_DRV_XGENE policy<{'arm64': '-'}> +CONFIG_RTC_DRV_ZYNQMP policy<{'arm64': 'n'}> +CONFIG_RTD119X_WATCHDOG policy<{'arm64': '-'}> +CONFIG_RTW88_8723DE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_RUNTIME_TESTING_MENU policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_S2IO policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLES policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SAMPLE_CONFIGFS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_HW_BREAKPOINT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_KDB policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_KFIFO policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_KOBJECT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_KPROBES policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_LIVEPATCH policy<{'amd64': '-'}> +CONFIG_SAMPLE_QMI_CLIENT policy<{'arm64': '-'}> +CONFIG_SAMPLE_RPMSG_CLIENT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_TRACE_EVENTS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_VFIO_MDEV_MBOCHS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_VFIO_MDEV_MDPY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SAMPLE_VFIO_MDEV_MTTY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SATA_AHCI_SEATTLE policy<{'arm64': '-'}> +CONFIG_SATA_MOBILE_LPM_POLICY policy<{'amd64': '0', 'arm64': '0'}> +CONFIG_SATA_RCAR policy<{'arm64': '-'}> +CONFIG_SC27XX_ADC policy<{'arm64': '-'}> +CONFIG_SC27XX_EFUSE policy<{'arm64': '-'}> +CONFIG_SCR24X policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SCSI_HISI_SAS policy<{'arm64': 'n'}> +CONFIG_SCSI_HISI_SAS_PCI policy<{'arm64': '-'}> +CONFIG_SCSI_LOWLEVEL_PCMCIA policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_SCSI_SIM710 policy<{'amd64': 'y'}> +CONFIG_SCSI_SPI_ATTRS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_SCSI_UFS_BSG policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SCSI_UFS_CDNS_PLATFORM policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SCSI_UFS_HISI policy<{'arm64': '-'}> +CONFIG_SCSI_UFS_MEDIATEK policy<{'arm64': '-'}> +CONFIG_SCSI_UFS_QCOM policy<{'arm64': '-'}> +CONFIG_SDM_CAMCC_845 policy<{'arm64': '-'}> +CONFIG_SDM_DISPCC_845 policy<{'arm64': '-'}> +CONFIG_SDM_GCC_660 policy<{'arm64': '-'}> +CONFIG_SDM_GCC_845 policy<{'arm64': '-'}> +CONFIG_SDM_GPUCC_845 policy<{'arm64': '-'}> +CONFIG_SDM_LPASSCC_845 policy<{'arm64': '-'}> +CONFIG_SDM_VIDEOCC_845 policy<{'arm64': '-'}> +CONFIG_SD_ADC_MODULATOR policy<{'arm64': 'n'}> +CONFIG_SENSORS_AHC1EC0_HWMON policy<{'amd64': '-'}> +CONFIG_SENSORS_ALTRA policy<{'arm64': 'm'}> +CONFIG_SENSORS_ARM_SCMI policy<{'arm64': '-'}> +CONFIG_SENSORS_ARM_SCPI policy<{'arm64': '-'}> +CONFIG_SENSORS_GPIO_FAN policy<{'arm64': 'n'}> +CONFIG_SENSORS_LOCHNAGAR policy<{'arm64': '-'}> +CONFIG_SENSORS_OCC_P9_SBE policy<{'arm64': '-'}> +CONFIG_SENSORS_PWM_FAN policy<{'arm64': 'n'}> +CONFIG_SENSORS_RASPBERRYPI_HWMON policy<{'arm64': '-'}> +CONFIG_SENSORS_VEXPRESS policy<{'arm64': '-'}> +CONFIG_SERIAL_8250_ASPEED_VUART policy<{'arm64': 'n'}> +CONFIG_SERIAL_8250_BCM2835AUX policy<{'arm64': '-'}> +CONFIG_SERIAL_8250_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SERIAL_8250_DW policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SERIAL_8250_MT6577 policy<{'arm64': '-'}> +CONFIG_SERIAL_8250_OMAP policy<{'arm64': '-'}> +CONFIG_SERIAL_AMBA_PL010 policy<{'arm64': 'n'}> +CONFIG_SERIAL_CONEXANT_DIGICOLOR policy<{'arm64': 'n'}> +CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST policy<{'arm64': 'n'}> +CONFIG_SERIAL_IMX policy<{'arm64': '-'}> +CONFIG_SERIAL_IMX_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_MESON policy<{'arm64': '-'}> +CONFIG_SERIAL_MESON_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_MSM policy<{'arm64': '-'}> +CONFIG_SERIAL_MSM_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_MVEBU_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_MVEBU_UART policy<{'arm64': '-'}> +CONFIG_SERIAL_OF_PLATFORM policy<{'arm64': 'n'}> +CONFIG_SERIAL_OWL policy<{'arm64': '-'}> +CONFIG_SERIAL_OWL_CONSOLE policy<{'arm64': '-'}> +CONFIG_SERIAL_QCOM_GENI policy<{'arm64': '-'}> +CONFIG_SERIAL_SH_SCI_DMA policy<{'arm64': '-'}> +CONFIG_SERIAL_SH_SCI_NR_UARTS policy<{'arm64': '-'}> +CONFIG_SERIAL_SIFIVE policy<{'arm64': 'n'}> +CONFIG_SERIAL_SPRD policy<{'arm64': '-'}> +CONFIG_SERIAL_XILINX_PS_UART policy<{'arm64': 'n'}> +CONFIG_SERIO_AMBAKMI policy<{'arm64': 'n'}> +CONFIG_SERIO_APBPS2 policy<{'arm64': 'n'}> +CONFIG_SERIO_SUN4I_PS2 policy<{'arm64': '-'}> +CONFIG_SFP policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SGI_GRU policy<{'amd64': '-'}> +CONFIG_SGI_GRU_DEBUG policy<{'amd64': '-'}> +CONFIG_SGI_XP policy<{'amd64': '-'}> +CONFIG_SG_SPLIT policy<{'arm64': '-'}> +CONFIG_SHIFT_FS_POSIX_ACL policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SH_ETH policy<{'arm64': '-'}> +CONFIG_SH_TIMER_CMT policy<{'arm64': '-'}> +CONFIG_SH_TIMER_TMU policy<{'arm64': '-'}> +CONFIG_SIMPLE_PM_BUS policy<{'arm64': 'n'}> +CONFIG_SLIC_DS26522 policy<{'arm64': '-'}> +CONFIG_SLIM_QCOM_NGD_CTRL policy<{'arm64': '-'}> +CONFIG_SMC91X policy<{'arm64': 'n'}> +CONFIG_SM_GCC_8150 policy<{'arm64': '-'}> +CONFIG_SND_AUDIO_GRAPH_CARD policy<{'arm64': 'n'}> +CONFIG_SND_BCM2835 policy<{'arm64': '-'}> +CONFIG_SND_BCM2835_SOC_I2S policy<{'arm64': '-'}> +CONFIG_SND_COMPRESS_OFFLOAD policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SND_IMX_SOC policy<{'arm64': '-'}> +CONFIG_SND_KIRKWOOD_SOC policy<{'arm64': '-'}> +CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_FIFO policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_FRDDR policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_PDM policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_SOUND_CARD policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_SPDIFIN policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_SPDIFOUT policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_TDMIN policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_TDMOUT policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_TDM_FORMATTER policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_TDM_INTERFACE policy<{'arm64': '-'}> +CONFIG_SND_MESON_AXG_TODDR policy<{'arm64': '-'}> +CONFIG_SND_MESON_CARD_UTILS policy<{'arm64': '-'}> +CONFIG_SND_MESON_CODEC_GLUE policy<{'arm64': '-'}> +CONFIG_SND_MESON_G12A_TOHDMITX policy<{'arm64': '-'}> +CONFIG_SND_PCMCIA policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_SND_PDAUDIOCF policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SND_SOC_AK4118 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SND_SOC_AMD_ACP3x policy<{'amd64': 'n'}> +CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SND_SOC_APQ8016_SBC policy<{'arm64': '-'}> +CONFIG_SND_SOC_COMPRESS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SND_SOC_CPCAP policy<{'arm64': '-'}> +CONFIG_SND_SOC_DA7219 policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_SND_SOC_FSL_ASOC_CARD policy<{'arm64': '-'}> +CONFIG_SND_SOC_IMX_AUDMIX policy<{'arm64': '-'}> +CONFIG_SND_SOC_IMX_ES8328 policy<{'arm64': '-'}> +CONFIG_SND_SOC_IMX_PCM_DMA policy<{'arm64': '-'}> +CONFIG_SND_SOC_IMX_SGTL5000 policy<{'arm64': '-'}> +CONFIG_SND_SOC_IMX_SPDIF policy<{'arm64': '-'}> +CONFIG_SND_SOC_INTEL_APL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_BXT_RT298_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_GLK policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH policy<{'amd64': 'n'}> +CONFIG_SND_SOC_INTEL_HASWELL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_HASWELL_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKL policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH policy<{'amd64': 'n'}> +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKL_RT286_MACH policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SST policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SST_ACPI policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SST_FIRMWARE policy<{'amd64': '-'}> +CONFIG_SND_SOC_INTEL_SST_TOPLEVEL policy<{'amd64': 'n'}> +CONFIG_SND_SOC_LOCHNAGAR_SC policy<{'arm64': '-'}> +CONFIG_SND_SOC_LPASS_APQ8016 policy<{'arm64': '-'}> +CONFIG_SND_SOC_LPASS_CPU policy<{'arm64': '-'}> +CONFIG_SND_SOC_LPASS_IPQ806X policy<{'arm64': '-'}> +CONFIG_SND_SOC_LPASS_PLATFORM policy<{'arm64': '-'}> +CONFIG_SND_SOC_MAX98090 policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_SND_SOC_MEDIATEK policy<{'arm64': '-'}> +CONFIG_SND_SOC_MIKROE_PROTO policy<{'arm64': 'n'}> +CONFIG_SND_SOC_MSM8996 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT2701 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT6797 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT6797_MT6351 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT8173 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT8183 policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT8183_DA7219_MAX98357A policy<{'arm64': '-'}> +CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A policy<{'arm64': '-'}> +CONFIG_SND_SOC_NAU8825 policy<{'amd64': '-'}> +CONFIG_SND_SOC_QCOM policy<{'arm64': '-'}> +CONFIG_SND_SOC_QCOM_COMMON policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6 policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_ADM policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_AFE policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_AFE_DAI policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_ASM policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_ASM_DAI policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_COMMON policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_CORE policy<{'arm64': '-'}> +CONFIG_SND_SOC_QDSP6_ROUTING policy<{'arm64': '-'}> +CONFIG_SND_SOC_RCAR policy<{'arm64': '-'}> +CONFIG_SND_SOC_RK3288_HDMI_ANALOG policy<{'arm64': '-'}> +CONFIG_SND_SOC_RK3399_GRU_SOUND policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP_I2S policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP_MAX98090 policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP_PDM policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP_RT5645 policy<{'arm64': '-'}> +CONFIG_SND_SOC_ROCKCHIP_SPDIF policy<{'arm64': '-'}> +CONFIG_SND_SOC_RT298 policy<{'amd64': '-'}> +CONFIG_SND_SOC_RT5514 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SND_SOC_RT5514_SPI policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SND_SOC_RT5660 policy<{'amd64': '-'}> +CONFIG_SND_SOC_RT5663 policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SND_SOC_SDM845 policy<{'arm64': '-'}> +CONFIG_SND_SOC_SH4_FSI policy<{'arm64': '-'}> +CONFIG_SND_SOC_SOF_BROADWELL policy<{'amd64': 'm'}> +CONFIG_SND_SOC_SOF_BROADWELL_SUPPORT policy<{'amd64': 'y'}> +CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 policy<{'amd64': 'n'}> +CONFIG_SND_SOC_SOF_IMX8 policy<{'arm64': '-'}> +CONFIG_SND_SOC_SOF_IMX8_SUPPORT policy<{'arm64': '-'}> +CONFIG_SND_SOC_SOF_IMX_TOPLEVEL policy<{'arm64': '-'}> +CONFIG_SND_SOC_SOF_OF policy<{'arm64': 'n'}> +CONFIG_SND_SOC_SPRD policy<{'arm64': '-'}> +CONFIG_SND_SOC_SPRD_MCDT policy<{'arm64': '-'}> +CONFIG_SND_SOC_STORM policy<{'arm64': '-'}> +CONFIG_SND_SOC_XILINX_I2S policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM policy<{'amd64': '-'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI policy<{'amd64': '-'}> +CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI policy<{'amd64': '-'}> +CONFIG_SND_SST_IPC policy<{'amd64': '-'}> +CONFIG_SND_SST_IPC_ACPI policy<{'amd64': '-'}> +CONFIG_SND_SST_IPC_PCI policy<{'amd64': '-'}> +CONFIG_SND_SUN4I_CODEC policy<{'arm64': '-'}> +CONFIG_SND_SUN4I_I2S policy<{'arm64': '-'}> +CONFIG_SND_SUN4I_SPDIF policy<{'arm64': '-'}> +CONFIG_SND_SUN50I_CODEC_ANALOG policy<{'arm64': '-'}> +CONFIG_SND_SUN8I_ADDA_PR_REGMAP policy<{'arm64': '-'}> +CONFIG_SND_SUN8I_CODEC policy<{'arm64': '-'}> +CONFIG_SND_SUN8I_CODEC_ANALOG policy<{'arm64': '-'}> +CONFIG_SND_VXPOCKET policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SNI_NETSEC policy<{'arm64': '-'}> +CONFIG_SOCK_VALIDATE_XMIT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_SOC_BRCMSTB policy<{'arm64': 'n'}> +CONFIG_SOC_BUS policy<{'arm64': '-'}> +CONFIG_SOC_RENESAS policy<{'arm64': '-'}> +CONFIG_SOUNDWIRE_CADENCE policy<{'amd64': '-'}> +CONFIG_SOUNDWIRE_INTEL policy<{'amd64': '-'}> +CONFIG_SPI_ARMADA_3700 policy<{'arm64': '-'}> +CONFIG_SPI_BCM2835 policy<{'arm64': '-'}> +CONFIG_SPI_BCM2835AUX policy<{'arm64': '-'}> +CONFIG_SPI_BCM_QSPI policy<{'arm64': '-'}> +CONFIG_SPI_CADENCE_QUADSPI policy<{'arm64': 'n'}> +CONFIG_SPI_FSL_DSPI policy<{'arm64': '-'}> +CONFIG_SPI_FSL_LIB policy<{'arm64': '-'}> +CONFIG_SPI_FSL_LPSPI policy<{'arm64': '-'}> +CONFIG_SPI_FSL_QUADSPI policy<{'arm64': '-'}> +CONFIG_SPI_FSL_SPI policy<{'arm64': 'n'}> +CONFIG_SPI_HISI_SFC policy<{'arm64': '-'}> +CONFIG_SPI_HISI_SFC_V3XX policy<{'arm64': 'n'}> +CONFIG_SPI_IMX policy<{'arm64': '-'}> +CONFIG_SPI_MESON_SPICC policy<{'arm64': '-'}> +CONFIG_SPI_MESON_SPIFC policy<{'arm64': '-'}> +CONFIG_SPI_MT65XX policy<{'arm64': '-'}> +CONFIG_SPI_MXIC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SPI_OMAP24XX policy<{'arm64': '-'}> +CONFIG_SPI_ORION policy<{'arm64': '-'}> +CONFIG_SPI_PL022 policy<{'arm64': 'n'}> +CONFIG_SPI_QCOM_GENI policy<{'arm64': '-'}> +CONFIG_SPI_QCOM_QSPI policy<{'arm64': '-'}> +CONFIG_SPI_QUP policy<{'arm64': '-'}> +CONFIG_SPI_ROCKCHIP policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SPI_RSPI policy<{'arm64': '-'}> +CONFIG_SPI_SH_HSPI policy<{'arm64': '-'}> +CONFIG_SPI_SH_MSIOF policy<{'arm64': '-'}> +CONFIG_SPI_SLAVE_MT27XX policy<{'arm64': '-'}> +CONFIG_SPI_SPRD policy<{'arm64': '-'}> +CONFIG_SPI_SPRD_ADI policy<{'arm64': '-'}> +CONFIG_SPI_SUN4I policy<{'arm64': '-'}> +CONFIG_SPI_SUN6I policy<{'arm64': '-'}> +CONFIG_SPI_SYNQUACER policy<{'arm64': '-'}> +CONFIG_SPI_THUNDERX policy<{'arm64': 'n'}> +CONFIG_SPI_XLP policy<{'arm64': '-'}> +CONFIG_SPMI_MSM_PMIC_ARB policy<{'arm64': '-'}> +CONFIG_SPMI_PMIC_CLKDIV policy<{'arm64': '-'}> +CONFIG_SPRD_COMMON_CLK policy<{'arm64': '-'}> +CONFIG_SPRD_DMA policy<{'arm64': '-'}> +CONFIG_SPRD_SC9860_CLK policy<{'arm64': '-'}> +CONFIG_SPRD_TIMER policy<{'arm64': '-'}> +CONFIG_SPRD_WATCHDOG policy<{'arm64': '-'}> +CONFIG_SSB_PCMCIAHOST policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_SSB_PCMCIAHOST_POSSIBLE policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_STAGING_APEX_DRIVER policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_STAGING_GASKET_FRAMEWORK policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_STANDALONE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_STMMAC_PCI policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_STMPE_ADC policy<{'arm64': '-'}> +CONFIG_STMPE_I2C policy<{'arm64': '-'}> +CONFIG_STMPE_SPI policy<{'arm64': '-'}> +CONFIG_STMP_DEVICE policy<{'arm64': '-'}> +CONFIG_STPMIC1_WATCHDOG policy<{'arm64': '-'}> +CONFIG_STUB_CLK_HI3660 policy<{'arm64': '-'}> +CONFIG_STUB_CLK_HI6220 policy<{'arm64': '-'}> +CONFIG_SUN4I_EMAC policy<{'arm64': '-'}> +CONFIG_SUN4I_GPADC policy<{'arm64': '-'}> +CONFIG_SUN50I_A64_CCU policy<{'arm64': '-'}> +CONFIG_SUN50I_DE2_BUS policy<{'arm64': '-'}> +CONFIG_SUN50I_ERRATUM_UNKNOWN1 policy<{'arm64': '-'}> +CONFIG_SUN50I_H6_CCU policy<{'arm64': '-'}> +CONFIG_SUN50I_H6_R_CCU policy<{'arm64': '-'}> +CONFIG_SUN8I_A83T_CCU policy<{'arm64': '-'}> +CONFIG_SUN8I_DE2_CCU policy<{'arm64': '-'}> +CONFIG_SUN8I_H3_CCU policy<{'arm64': '-'}> +CONFIG_SUN8I_R_CCU policy<{'arm64': '-'}> +CONFIG_SUNXI_CCU policy<{'arm64': '-'}> +CONFIG_SUNXI_RSB policy<{'arm64': '-'}> +CONFIG_SUNXI_SRAM policy<{'arm64': '-'}> +CONFIG_SUNXI_WATCHDOG policy<{'arm64': '-'}> +CONFIG_SYNCLINK_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_SYSCON_REBOOT_MODE policy<{'arm64': 'n'}> +CONFIG_SYSCTL_SYSCALL policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_SYSC_R8A774A1 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A774C0 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A7795 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A7796 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A77965 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A77970 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A77980 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A77990 policy<{'arm64': '-'}> +CONFIG_SYSC_R8A77995 policy<{'arm64': '-'}> +CONFIG_SYSC_RCAR policy<{'arm64': '-'}> +CONFIG_SYS_SUPPORTS_SH_CMT policy<{'arm64': '-'}> +CONFIG_SYS_SUPPORTS_SH_TMU policy<{'arm64': '-'}> +CONFIG_TCG_FTPM_TEE policy<{'arm64': '-'}> +CONFIG_TEE policy<{'arm64': 'n'}> +CONFIG_TEST_BITFIELD policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_BITMAP policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_BPF policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_FIRMWARE policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_HASH policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_HEXDUMP policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_IDA policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_KMOD policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_KSTRTOX policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_LIST_SORT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_LIVEPATCH policy<{'amd64': '-'}> +CONFIG_TEST_LKM policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_MEMCAT_P policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_MEMINIT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_OBJAGG policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_OVERFLOW policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_PARMAN policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_PRINTF policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_RHASHTABLE policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_SORT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_STACKINIT policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_STATIC_KEYS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_STRING_HELPERS policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_STRSCPY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_SYSCTL policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_UDELAY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_USER_COPY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_UUID policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_VMALLOC policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TEST_XARRAY policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_THERMAL_MMIO policy<{'arm64': 'n'}> +CONFIG_THERMAL_STATISTICS policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_THUNDERX2_PMU policy<{'arm64': '-'}> +CONFIG_TIMER_IMX_SYS_CTR policy<{'arm64': '-'}> +CONFIG_TINYDRM_HX8357D policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_TINYDRM_ILI9225 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_TINYDRM_ILI9341 policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_TINYDRM_ST7735R policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_TI_ADS124S08 policy<{'arm64': 'n'}> +CONFIG_TI_ADS8344 policy<{'arm64': 'n'}> +CONFIG_TI_ADS8688 policy<{'arm64': 'n'}> +CONFIG_TI_AM335X_ADC policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TI_MESSAGE_MANAGER policy<{'arm64': '-'}> +CONFIG_TI_SCI_CLK policy<{'arm64': '-'}> +CONFIG_TI_SCI_CLK_PROBE_FROM_FW policy<{'arm64': '-'}> +CONFIG_TI_SCI_INTA_IRQCHIP policy<{'arm64': '-'}> +CONFIG_TI_SCI_INTA_MSI_DOMAIN policy<{'arm64': '-'}> +CONFIG_TI_SCI_INTR_IRQCHIP policy<{'arm64': '-'}> +CONFIG_TI_SCI_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_TI_SCI_PROTOCOL policy<{'arm64': '-'}> +CONFIG_TLS_DEVICE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_TOUCHSCREEN_AR1021_I2C policy<{'arm64': 'n'}> +CONFIG_TOUCHSCREEN_BU21029 policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 policy<{'arm64': 'n'}> +CONFIG_TOUCHSCREEN_COLIBRI_VF50 policy<{'arm64': '-'}> +CONFIG_TOUCHSCREEN_DMI policy<{'amd64': 'n'}> +CONFIG_TOUCHSCREEN_EGALAX policy<{'arm64': 'n'}> +CONFIG_TOUCHSCREEN_IMX6UL_TSC policy<{'arm64': 'n'}> +CONFIG_TOUCHSCREEN_IPROC policy<{'arm64': '-'}> +CONFIG_TOUCHSCREEN_RASPBERRYPI_FW policy<{'arm64': '-'}> +CONFIG_TOUCHSCREEN_STMPE policy<{'arm64': '-'}> +CONFIG_TOUCHSCREEN_SUN4I policy<{'arm64': '-'}> +CONFIG_TOUCHSCREEN_TI_AM335X_TSC policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_TQMX86_WDT policy<{'amd64': 'y'}> +CONFIG_TREE_RCU policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_TURRIS_MOX_RWTM policy<{'arm64': '-'}> +CONFIG_UBIFS_FS_AUTHENTICATION policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_UBUNTU_ODM_DRIVERS policy<{'amd64': '-'}> +CONFIG_UDMABUF policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_USB_DWC3_KEYSTONE policy<{'arm64': '-'}> +CONFIG_USB_DWC3_MESON_G12A policy<{'arm64': '-'}> +CONFIG_USB_DWC3_QCOM policy<{'arm64': '-'}> +CONFIG_USB_EHCI_HCD_ORION policy<{'arm64': '-'}> +CONFIG_USB_EHCI_MXC policy<{'arm64': '-'}> +CONFIG_USB_EMXX policy<{'arm64': '-'}> +CONFIG_USB_FSL_USB2 policy<{'arm64': '-'}> +CONFIG_USB_GADGET_XILINX policy<{'arm64': 'n'}> +CONFIG_USB_MTU3 policy<{'arm64': '-'}> +CONFIG_USB_MTU3_DEBUG policy<{'arm64': '-'}> +CONFIG_USB_MTU3_DUAL_ROLE policy<{'arm64': '-'}> +CONFIG_USB_MTU3_GADGET policy<{'arm64': '-'}> +CONFIG_USB_MTU3_HOST policy<{'arm64': '-'}> +CONFIG_USB_MUSB_SUNXI policy<{'arm64': '-'}> +CONFIG_USB_MXS_PHY policy<{'arm64': '-'}> +CONFIG_USB_OHCI_HCD_PLATFORM policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_USB_RENESAS_USB3 policy<{'arm64': '-'}> +CONFIG_USB_RENESAS_USBHS policy<{'arm64': '-'}> +CONFIG_USB_RENESAS_USBHS_HCD policy<{'arm64': '-'}> +CONFIG_USB_RENESAS_USBHS_UDC policy<{'arm64': '-'}> +CONFIG_USB_ROLE_SWITCH policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_USB_SL811_CS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_USB_SNP_UDC_PLAT policy<{'arm64': 'n'}> +CONFIG_USB_ULPI policy<{'arm64': 'n'}> +CONFIG_USB_ULPI_VIEWPORT policy<{'arm64': '-'}> +CONFIG_USB_XHCI_HISTB policy<{'arm64': '-'}> +CONFIG_USB_XHCI_MTK policy<{'arm64': '-'}> +CONFIG_USB_XHCI_MVEBU policy<{'arm64': '-'}> +CONFIG_USB_XHCI_RCAR policy<{'arm64': '-'}> +CONFIG_UV_MMTIMER policy<{'amd64': '-'}> +CONFIG_VEXPRESS_CONFIG policy<{'arm64': 'n'}> +CONFIG_VEXPRESS_SYSCFG policy<{'arm64': '-'}> +CONFIG_VF610_ADC policy<{'arm64': 'n'}> +CONFIG_VF610_DAC policy<{'arm64': 'n'}> +CONFIG_VFIO_AMBA policy<{'arm64': '-'}> +CONFIG_VFIO_MDEV policy<{'amd64': 'm', 'arm64': 'n'}> +CONFIG_VFIO_MDEV_DEVICE policy<{'amd64': 'm', 'arm64': '-'}> +CONFIG_VFIO_NOIOMMU policy<{'amd64': 'y', 'arm64': 'n'}> +CONFIG_VFIO_PLATFORM policy<{'arm64': 'n'}> +CONFIG_VFIO_PLATFORM_AMDXGBE_RESET policy<{'arm64': '-'}> +CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET policy<{'arm64': '-'}> +CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET policy<{'arm64': '-'}> +CONFIG_VIDEO_ADV748X policy<{'arm64': 'n'}> +CONFIG_VIDEO_ADV7511 policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_VIDEO_ADV7511_CEC policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_VIDEO_ALLEGRO_DVT policy<{'arm64': '-'}> +CONFIG_VIDEO_ASPEED policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_VIDEO_BCM2835 policy<{'arm64': '-'}> +CONFIG_VIDEO_CADENCE policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_VIDEO_CADENCE_CSI2RX policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_VIDEO_CADENCE_CSI2TX policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_VIDEO_COBALT policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_VIDEO_CODA policy<{'arm64': '-'}> +CONFIG_VIDEO_CROS_EC_CEC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_VIDEO_IMX_PXP policy<{'arm64': '-'}> +CONFIG_VIDEO_IPU3_CIO2 policy<{'amd64': 'n'}> +CONFIG_VIDEO_MEDIATEK_VPU policy<{'arm64': '-'}> +CONFIG_VIDEO_MESON_AO_CEC policy<{'arm64': '-'}> +CONFIG_VIDEO_MESON_G12A_AO_CEC policy<{'arm64': '-'}> +CONFIG_VIDEO_MESON_VDEC policy<{'arm64': '-'}> +CONFIG_VIDEO_MUX policy<{'arm64': 'n'}> +CONFIG_VIDEO_OV5640 policy<{'arm64': 'n'}> +CONFIG_VIDEO_OV5645 policy<{'arm64': 'n'}> +CONFIG_VIDEO_PCI_SKELETON policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_VIDEO_QCOM_CAMSS policy<{'arm64': '-'}> +CONFIG_VIDEO_QCOM_VENUS policy<{'arm64': '-'}> +CONFIG_VIDEO_RCAR_CSI2 policy<{'arm64': '-'}> +CONFIG_VIDEO_RCAR_DRIF policy<{'arm64': '-'}> +CONFIG_VIDEO_RCAR_VIN policy<{'arm64': '-'}> +CONFIG_VIDEO_RENESAS_FCP policy<{'arm64': '-'}> +CONFIG_VIDEO_RENESAS_FDP1 policy<{'arm64': '-'}> +CONFIG_VIDEO_RENESAS_JPU policy<{'arm64': '-'}> +CONFIG_VIDEO_RENESAS_VSP1 policy<{'arm64': '-'}> +CONFIG_VIDEO_ROCKCHIP_RGA policy<{'arm64': '-'}> +CONFIG_VIDEO_SUN4I_CSI policy<{'arm64': '-'}> +CONFIG_VIDEO_SUN6I_CSI policy<{'arm64': '-'}> +CONFIG_VIDEO_SUNXI policy<{'arm64': '-'}> +CONFIG_VIDEO_VICODEC policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_VIDEO_XILINX policy<{'arm64': 'n'}> +CONFIG_VIDEO_XILINX_TPG policy<{'arm64': '-'}> +CONFIG_VIDEO_XILINX_VTC policy<{'arm64': '-'}> +CONFIG_VIRTIO_IOMMU policy<{'arm64': 'n'}> +CONFIG_VOP policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_VOP_BUS policy<{'amd64': 'm', 'arm64': 'm'}> +CONFIG_VXGE policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_VXGE_DEBUG_TRACE_ALL policy<{'amd64': '-', 'arm64': '-'}> +CONFIG_W1_MASTER_MXC policy<{'arm64': '-'}> +CONFIG_WLCORE_SPI policy<{'arm64': 'n'}> +CONFIG_X86_CPA_STATISTICS policy<{'amd64': 'y'}> +CONFIG_XEN_GNTDEV_DMABUF policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_XEN_SCRUB_PAGES_DEFAULT policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_XFRM_INTERFACE policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_XGENE_DMA policy<{'arm64': '-'}> +CONFIG_XGENE_PMU policy<{'arm64': '-'}> +CONFIG_XGENE_SLIMPRO_MBOX policy<{'arm64': '-'}> +CONFIG_XILINX_DMA policy<{'arm64': 'n'}> +CONFIG_XILINX_VCU policy<{'amd64': 'n', 'arm64': 'n'}> +CONFIG_XILINX_ZYNQMP_DMA policy<{'arm64': 'n'}> +CONFIG_XILLYBUS_OF policy<{'arm64': 'n'}> +CONFIG_XIL_AXIS_FIFO policy<{'arm64': 'n'}> +CONFIG_ZLIB_DEFLATE policy<{'amd64': 'y', 'arm64': 'm'}> +CONFIG_ZSTD_COMPRESS policy<{'amd64': 'y', 'arm64': 'y'}> +CONFIG_ZYNQMP_FIRMWARE policy<{'arm64': '-'}> +CONFIG_ZYNQMP_FIRMWARE_DEBUG policy<{'arm64': '-'}> +CONFIG_ZYNQMP_IPI_MBOX policy<{'arm64': '-'}> +CONFIG_ZYNQMP_PM_DOMAINS policy<{'arm64': '-'}> +CONFIG_ZYNQMP_POWER policy<{'arm64': '-'}> --- linux-oracle-5.4.0.orig/debian.oracle/control.d/flavour-control.stub +++ linux-oracle-5.4.0/debian.oracle/control.d/flavour-control.stub @@ -0,0 +1,141 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# This file describes the template for packages that are created for each flavour +# in debian/control.d/vars.* +# +# This file gets edited in a couple of places. See the debian/control.stub rule in +# debian/rules. PGGVER, ABINUM, and SRCPKGNAME are all converted in the +# process of creating debian/control. +# +# The flavour specific strings (ARCH, DESC, etc) are converted using values from the various +# flavour files in debian/control.d/vars.* +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Provides: linux-image, fuse-module, aufs-dkms, =PROVIDES=${linux:rprovides} +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-PKGVER-ABINUM-FLAVOUR +Recommends: BOOTLOADER, initramfs-tools | linux-initramfs-tool +Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x], initramfs-tools (<< 0.130ubuntu3.6) +Conflicts: linux-image=SIGN-PEER-PKG=-PKGVER-ABINUM-FLAVOUR +Suggests: fdutils, SRCPKGNAME-doc-PKGVER | SRCPKGNAME-source-PKGVER, SRCPKGNAME-tools, linux-headers-PKGVER-ABINUM-FLAVOUR +Description: Oracle Linux kernel image for version PKGVER on DESC + This package contains the=SIGN-ME-TXT= Oracle Linux kernel image for version PKGVER on + DESC. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${linux:BuiltUsing} +Description: Oracle Linux kernel extra modules for version PKGVER on DESC + Contains the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-extra-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-image-PKGVER-ABINUM-FLAVOUR | linux-image-unsigned-PKGVER-ABINUM-FLAVOUR, crda | wireless-crda +Description: Oracle Linux kernel extra modules for version PKGVER on DESC + This package contains the Oracle Linux kernel extra modules for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-headers-PKGVER-ABINUM, ${shlibs:Depends} +Provides: linux-headers, linux-headers-3.0 +Description: Oracle Linux kernel headers for version PKGVER on DESC + This package provides kernel header files for version PKGVER on + DESC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details. + +Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR-dbgsym +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends} +Provides: linux-debug +Description: Oracle Linux kernel debug image for version PKGVER on DESC + This package provides the=SIGN-ME-TXT= kernel debug image for version PKGVER on + DESC. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-tools-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-tools-PKGVER-ABINUM +Description: Oracle Linux kernel version specific tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version PKGVER-ABINUM on + =HUMAN=. + +Package: linux-cloud-tools-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: devel +Priority: optional +Depends: ${misc:Depends}, SRCPKGNAME-cloud-tools-PKGVER-ABINUM +Description: Oracle Linux kernel version specific cloud tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools for cloud for version PKGVER-ABINUM on + =HUMAN=. --- linux-oracle-5.4.0.orig/debian.oracle/control.d/oracle.inclusion-list +++ linux-oracle-5.4.0/debian.oracle/control.d/oracle.inclusion-list @@ -0,0 +1,256 @@ +arch/*/{crypto,kernel,oprofile} +arch/*/kvm/kvm.ko +arch/powerpc/kvm/kvm-hv.ko +arch/powerpc/kvm/kvm-pr.ko +arch/powerpc/kvm/vfio.ko +arch/powerpc/platforms/powernv/opal-prd.ko +arch/s390/* +arch/x86/kvm/kvm-amd.ko +arch/x86/kvm/kvm-intel.ko +crypto/* +drivers/acpi/* +drivers/ata/acard-ahci.ko +drivers/ata/ahci.ko +drivers/ata/ahci_platform.ko +drivers/ata/ata_generic.ko +drivers/ata/libahci.ko +drivers/ata/libahci_platform.ko +drivers/block/brd.ko +drivers/block/cryptoloop.ko +drivers/block/floppy.ko +drivers/block/loop.ko +drivers/block/nbd.ko +drivers/block/rbd.ko +drivers/block/virtio_blk.ko +drivers/block/xen-blkfront.ko +drivers/char/hangcheck-timer.ko +drivers/char/hw_random/powernv-rng.ko +drivers/char/hw_random/virtio-rng.ko +drivers/char/ipmi/* +drivers/char/ipmi/ipmi_msghandler.ko +drivers/char/lp.ko +drivers/char/nvram.ko +drivers/char/ppdev.ko +drivers/char/raw.ko +drivers/char/virtio_console.ko +drivers/crypto/nx/* +drivers/crypto/vmx/vmx-crypto.ko +drivers/firmware/efi/* +drivers/firmware/iscsi_ibft.ko +drivers/gpu/drm/ast/ast.ko +drivers/gpu/drm/drm_kms_helper.ko +drivers/gpu/drm/drm.ko +drivers/gpu/drm/ttm/ttm.ko +drivers/hid/hid-generic.ko +drivers/hid/hid-hyperv.ko +drivers/hid/hid.ko +drivers/hid/usbhid/usbhid.ko +drivers/hv/* +drivers/hwmon/ibmpowernv.ko +drivers/infiniband/core/ib_addr.ko +drivers/infiniband/core/ib_cm.ko +drivers/infiniband/core/ib_core.ko +drivers/infiniband/core/ib_mad.ko +drivers/infiniband/core/ib_sa.ko +drivers/infiniband/core/iw_cm.ko +drivers/infiniband/core/rdma_cm.ko +drivers/infiniband/ulp/iser/ib_iser.ko +drivers/infiniband/ulp/isert/ib_isert.ko +drivers/input/evbug.ko +drivers/input/gameport/gameport.ko +drivers/input/input-leds.ko +drivers/input/joydev.ko +drivers/input/misc/xen-kbdfront.ko +drivers/input/mouse/psmouse.ko +drivers/input/serio/hyperv-keyboard.ko +drivers/input/serio/serio_raw.ko +drivers/input/serio/serport.ko +drivers/input/touchscreen/usbtouchscreen.ko +drivers/leds/leds-powernv.ko +drivers/md/* +drivers/message/fusion* +drivers/misc/cxl/* +drivers/misc/eeprom/at24.ko +drivers/misc/vmw_balloon.ko +drivers/misc/vmw_vmci/vmw_vmci.ko +drivers/mtd/cmdlinepart.ko +drivers/mtd/devices/powernv_flash.ko +drivers/mtd/ofpart.ko +drivers/net/appletalk/ipddp.ko +drivers/net/bonding/bonding.ko +drivers/net/caif/caif_virtio.ko +drivers/net/dummy.ko +drivers/net/eql.ko +drivers/net/ethernet/8390/8390.ko +drivers/net/ethernet/8390/ne2k-pci.ko +drivers/net/ethernet/amazon/ena/ena.ko +drivers/net/ethernet/amd/pcnet32.ko +drivers/net/ethernet/broadcom/bnx2x/* +drivers/net/ethernet/broadcom/bnxt/bnxt_en.ko +drivers/net/ethernet/broadcom/tg3.ko +drivers/net/ethernet/dec/tulip/* +drivers/net/ethernet/emulex/benet/* +drivers/net/ethernet/ibm/* +drivers/net/ethernet/intel/e1000/e1000.ko +drivers/net/ethernet/intel/e1000e/e1000e.ko +drivers/net/ethernet/intel/i40e/* +drivers/net/ethernet/intel/igb/* +drivers/net/ethernet/intel/igbvf/igbvf.ko +drivers/net/ethernet/intel/ixgbe/* +drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko +drivers/net/ethernet/mellanox/* +drivers/net/ethernet/netronome/nfp/nfp.ko +drivers/net/ethernet/realtek/8139cp.ko +drivers/net/ethernet/realtek/8139too.ko +drivers/net/fddi/* +drivers/net/geneve.ko +drivers/net/hyperv/hv_netvsc.ko +drivers/net/ifb.ko +drivers/net/ipvlan/* +drivers/net/macvlan.ko +drivers/net/macvtap.ko +drivers/net/mii.ko +drivers/net/netconsole.ko +drivers/net/ppp/* +drivers/net/ppp/bsd_comp.ko +drivers/net/slip/* +drivers/net/veth.ko +drivers/net/virtio_net.ko +drivers/net/vmxnet3/vmxnet3.ko +drivers/net/vxlan.ko +drivers/net/xen-netback/* +drivers/net/xen-netfront.ko +drivers/nvme/host/nvme.ko +drivers/nvmem/nvmem_core.ko +drivers/parport/parport.ko +drivers/parport/parport_pc.ko +drivers/pci/host/vmd.ko +drivers/platform/x86/pvpanic.ko +drivers/pps/pps_core.ko +drivers/ptp/ptp.ko +drivers/s390/* +drivers/s390/block/xpram.ko +drivers/scsi/aacraid/* +drivers/scsi/BusLogic.ko +drivers/scsi/cxlflash/* +drivers/scsi/device_handler/scsi_dh_alua.ko +drivers/scsi/device_handler/scsi_dh_emc.ko +drivers/scsi/device_handler/scsi_dh_hp_sw.ko +drivers/scsi/device_handler/scsi_dh_rdac.ko +drivers/scsi/hv_storvsc.ko +drivers/scsi/ibmvscsi/* +drivers/scsi/ipr.ko +drivers/scsi/iscsi_boot_sysfs.ko +drivers/scsi/iscsi_tcp.ko +drivers/scsi/libiscsi.ko +drivers/scsi/libiscsi_tcp.ko +drivers/scsi/libsas/* +drivers/scsi/lpfc/* +drivers/scsi/megaraid/* +drivers/scsi/mpt3sas/* +drivers/scsi/osd/libosd.ko +drivers/scsi/osd/osd.ko +drivers/scsi/qla1280.ko +drivers/scsi/qla2xxx/* +drivers/scsi/raid_class.ko +drivers/scsi/scsi_transport_fc.ko +drivers/scsi/scsi_transport_iscsi.ko +drivers/scsi/scsi_transport_sas.ko +drivers/scsi/scsi_transport_spi.ko +drivers/scsi/sd_mod.ko +drivers/scsi/sr_mod.ko +drivers/scsi/virtio_scsi.ko +drivers/scsi/vmw_pvscsi.ko +drivers/target/target_core*.ko +drivers/target/loopback/tcm_loop.ko +drivers/tty/serial/jsm/* +drivers/uio/uio.ko +drivers/uio/uio_pdrv_genirq.ko +drivers/usb/host/* +drivers/usb/storage/uas.ko +drivers/usb/storage/usb-storage.ko +drivers/vfio/* +drivers/vhost/* +drivers/video/fbdev/* +drivers/video/vgastate.ko +drivers/virtio/* +drivers/watchdog/softdog.ko +drivers/xen/* +! find sound/core -name oss -prune -o -name *.ko -print +fs/9p/* +fs/aufs/aufs.ko +fs/autofs/autofs4.ko +fs/binfmt_misc.ko +fs/btrfs/* +fs/cachefiles/cachefiles.ko +fs/ceph/* +fs/cifs/* +fs/configfs/* +fs/dlm/dlm.ko +fs/ecryptfs/* +fs/efivarfs/* +fs/exofs/libore.ko +fs/ext4/* +fs/fat/* +fs/fscache/* +fs/fuse/* +fs/isofs/* +fs/lockd/* +fs/nfs/* +fs/nfs_common/* +fs/nfsd/* +fs/nls/nls_cp437.ko +fs/nls/nls_iso8859-1.ko +fs/overlayfs/* +fs/shiftfs.ko +fs/squashfs/* +fs/udf/* +fs/ufs/* +fs/xfs/* +lib/* +net/6lowpan/* +net/802/* +net/8021q/* +net/9p/* +net/appletalk/* +net/atm/* +net/ax25/* +net/bpfilter/* +net/bridge/* +net/can/* +net/ceph/libceph.ko +net/core/* +net/dccp/* +net/decnet/* +net/ieee802154/* +net/ipv4/* +net/ipv6/* +net/ipx/* +net/irda/* +net/key/* +net/lapb/* +net/llc/* +net/netfilter/* +net/netlink/netlink_diag.ko +net/netrom/* +net/openvswitch/* +net/packet/af_packet_diag.ko +net/phonet/* +net/rose/* +net/rxrpc/* +net/sched/* +net/sctp/* +net/sunrpc/auth_gss/auth_rpcgss.ko +net/sunrpc/auth_gss/rpcsec_gss_krb5.ko +net/sunrpc/sunrpc.ko +net/tipc/* +net/unix/unix_diag.ko +net/vmw_vsock/* +net/x25/* +net/xfrm/* +sound/drivers/pcsp/snd-pcsp.ko +sound/pci/snd-ens1370.ko +sound/soundcore.ko +ubuntu/vbox/vboxguest/vboxguest.ko +ubuntu/vbox/vboxsf/vboxsf.ko +zfs/* --- linux-oracle-5.4.0.orig/debian.oracle/control.d/vars.oracle +++ linux-oracle-5.4.0/debian.oracle/control.d/vars.oracle @@ -0,0 +1,6 @@ +arch="amd64 arm64" +supported="Oracle" +target="Geared toward Oracle Cloud systems." +desc="=HUMAN= SMP" +bootloader="grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-ieee1275 [ppc64el] | grub-efi-arm64 [arm64] " +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64]" --- linux-oracle-5.4.0.orig/debian.oracle/control.stub.in +++ linux-oracle-5.4.0/debian.oracle/control.stub.in @@ -0,0 +1,82 @@ +Source: SRCPKGNAME +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.9.4.0 +Build-Depends: + debhelper (>= 9), + dh-systemd, + cpio, + kernel-wedge, + kmod , + libcap-dev , + makedumpfile [amd64] , + libelf-dev , + libnewt-dev , + libiberty-dev , + default-jdk-headless , + java-common , + rsync , + libdw-dev , + libpci-dev , + pkg-config , + flex , + bison , + libunwind8-dev [amd64] , + liblzma-dev , + openssl , + libssl-dev , + libaudit-dev , + bc , + gawk , + libudev-dev , + autoconf , + automake , + libtool , + uuid-dev , + libnuma-dev [amd64] , + dkms , + dwarfdump , + curl , + lz4 [amd64] , + dwarves [amd64 arm64 armhf ppc64el s390x] , +Build-Depends-Indep: + xmlto , + docbook-utils , + ghostscript , + fig2dev , + bzip2 , + sharutils , + asciidoc , + python3-sphinx , + python3-sphinx-rtd-theme , + fontconfig , + python3-docutils , +Vcs-Git: git://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-oracle/+git/=SERIES= +XS-Testsuite: autopkgtest +#XS-Testsuite-Depends: gcc-4.7 binutils + +Package: SRCPKGNAME-headers-PKGVER-ABINUM +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: devel +Priority: optional +Depends: ${misc:Depends}, coreutils +Description: Header files related to Oracle Linux kernel version PKGVER + This package provides kernel header files for version PKGVER, for sites + that want the latest kernel headers. Please read + /usr/share/doc/SRCPKGNAME-headers-PKGVER-ABINUM/debian.README.gz for details + +Package: SRCPKGNAME-tools-PKGVER-ABINUM +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common +Description: Oracle Linux kernel version specific tools for version PKGVER-ABINUM + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version PKGVER-ABINUM on + =HUMAN=. + You probably want to install linux-tools-PKGVER-ABINUM-. --- linux-oracle-5.4.0.orig/debian.oracle/copyright +++ linux-oracle-5.4.0/debian.oracle/copyright @@ -0,0 +1,29 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-oracle-5.4.0.orig/debian.oracle/d-i/firmware/README.txt +++ linux-oracle-5.4.0/debian.oracle/d-i/firmware/README.txt @@ -0,0 +1,4 @@ +# +# Place the names of udeb modules into this directory that require +# runtime firmware. +# --- linux-oracle-5.4.0.orig/debian.oracle/d-i/kernel-versions +++ linux-oracle-5.4.0/debian.oracle/d-i/kernel-versions @@ -0,0 +1,2 @@ +# arch version flavour installedname suffix bdep +amd64 - oracle - - - --- linux-oracle-5.4.0.orig/debian.oracle/d-i/package-list +++ linux-oracle-5.4.0/debian.oracle/d-i/package-list @@ -0,0 +1,208 @@ +Package: kernel-image +Provides: ext3-modules, ext4-modules, squashfs-modules +Provides_amd64: efi-modules, ext3-modules, ext4-modules, squashfs-modules +Provides_i386: efi-modules, ext3-modules, ext4-modules, squashfs-modules +Provides_ppc64el: ext3-modules, ext4-modules, fat-modules, squashfs-modules +Provides_s390x: ext3-modules, ext4-modules, ppp-modules, squashfs-modules +Description: kernel image and system map + +Package: dasd-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: DASD storage support + +Package: dasd-extra-modules +Depends: dasd-modules +Priority: extra +Description: DASD storage support -- extras + +Package: fat-modules +Depends: kernel-image +Priority: standard +Description: FAT filesystem support + This includes Windows FAT and VFAT support. + +Package: fb-modules +Depends: kernel-image +Priority: standard +Description: Framebuffer modules + +Package: firewire-core-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Firewire (IEEE-1394) Support + +Package: floppy-modules +Depends: kernel-image +Priority: standard +Description: Floppy driver support + +Package: fs-core-modules +Depends: kernel-image +Priority: standard +Provides: ext2-modules, jfs-modules, reiserfs-modules, xfs-modules +Description: Base filesystem modules + This includes jfs, reiserfs and xfs. + +Package: fs-secondary-modules +Depends: kernel-image, fat-modules +Priority: standard +Provides: btrfs-modules, ntfs-modules, hfs-modules +Description: Extra filesystem modules + This includes support for Windows NTFS and MacOS HFS/HFSPlus + +Package: input-modules +Depends: kernel-image, usb-modules +Priority: standard +Description: Support for various input methods + +Package: irda-modules +Depends: kernel-image, nic-shared-modules +Priority: standard +Description: Support for Infrared protocols + +Package: md-modules +Depends: kernel-image +Priority: standard +Provides: crypto-dm-modules +Description: Multi-device support (raid, device-mapper, lvm) + +Package: nic-modules +Depends: kernel-image, nic-shared-modules, virtio-modules +Priority: standard +Description: Network interface support + +Package: nic-pcmcia-modules +Depends: kernel-image, nic-shared-modules, nic-modules +Priority: standard +Description: PCMCIA network interface support + +Package: nic-usb-modules +Depends: kernel-image, nic-shared-modules, usb-modules +Priority: standard +Description: USB network interface support + +Package: nic-shared-modules +Depends: kernel-image, crypto-modules +Priority: standard +Description: nic shared modules + This package contains modules which support nic modules + +Package: parport-modules +Depends: kernel-image +Priority: standard +Description: Parallel port support + +Package: pata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: PATA support modules + +Package: pcmcia-modules +Depends: kernel-image +Priority: standard +Description: PCMCIA Modules + +Package: pcmcia-storage-modules +Depends: kernel-image, scsi-modules +Priority: standard +Description: PCMCIA storage support + +Package: plip-modules +Depends: kernel-image, nic-shared-modules, parport-modules +Priority: standard +Description: PLIP (parallel port) networking support + +Package: ppp-modules +Depends: kernel-image, nic-shared-modules, serial-modules +Priority: standard +Description: PPP (serial port) networking support + +Package: sata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SATA storage support + +Package: scsi-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SCSI storage support + +Package: serial-modules +Depends: kernel-image +Priority: standard +Description: Serial port support + +Package: storage-core-modules +Depends: kernel-image +Priority: standard +Provides: loop-modules +Description: Core storage support + Includes core SCSI, LibATA, USB-Storage. Also includes related block + devices for CD, Disk and Tape medium (and IDE Floppy). + +Package: usb-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Core USB support + +Package: nfs-modules +Priority: standard +Depends: kernel-image +Description: NFS filesystem drivers + Includes the NFS client driver, and supporting modules. + +Package: block-modules +Priority: standard +Provides: nbd-modules +Depends: kernel-image, storage-core-modules, parport-modules, virtio-modules +Description: Block storage devices + This package contains the block storage devices, including DAC960 and + paraide. + +Package: message-modules +Priority: standard +Depends: kernel-image, storage-core-modules, scsi-modules +Description: Fusion and i2o storage modules + This package containes the fusion and i2o storage modules. + +Package: crypto-modules +Priority: extra +Depends: kernel-image +Description: crypto modules + This package contains crypto modules. + +Package: virtio-modules +Priority: standard +Depends: kernel-image +Description: VirtIO Modules + Includes modules for VirtIO (virtual machine, generally kvm guests) + +Package: socket-modules +Depends: kernel-image +Priority: standard +Description: Unix socket support + +Package: mouse-modules +Depends: kernel-image, input-modules, usb-modules +Priority: extra +Description: Mouse support + This package contains mouse drivers for the Linux kernel. + +Package: vlan-modules +Depends: kernel-image +Priority: extra +Description: vlan modules + This package contains vlan (8021.Q) modules. + +Package: ipmi-modules +Depends: kernel-image +Priority: standard +Description: ipmi modules + +Package: multipath-modules +Depends: kernel-image +Priority: extra +Description: DM-Multipath support + This package contains modules for device-mapper multipath support. + --- linux-oracle-5.4.0.orig/debian.oracle/dkms-versions +++ linux-oracle-5.4.0/debian.oracle/dkms-versions @@ -0,0 +1,3 @@ +zfs-linux 0.8.3-1ubuntu12.18 +virtualbox 6.1.50-dfsg-1~ubuntu1.20.04.1 +wireguard-linux-compat 1.0.20201112-1~20.04.1 --- linux-oracle-5.4.0.orig/debian.oracle/etc/kernelconfig +++ linux-oracle-5.4.0/debian.oracle/etc/kernelconfig @@ -0,0 +1,7 @@ +if [ "$variant" = "ports" ]; then + archs="" + family='ports' +else + archs="amd64 arm64" + family='ubuntu' +fi --- linux-oracle-5.4.0.orig/debian.oracle/etc/update.conf +++ linux-oracle-5.4.0/debian.oracle/etc/update.conf @@ -0,0 +1,7 @@ +# WARNING: we do not create update.conf when we are not a +# derivative. Various cranky components make use of this. +# If we start unconditionally creating update.conf we need +# to fix at least cranky close and cranky rebase. +RELEASE_REPO=git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/focal +SOURCE_RELEASE_BRANCH=master-next +DEBIAN_MASTER=debian.master --- linux-oracle-5.4.0.orig/debian.oracle/initramfs-tools.d/oracle.hook.in +++ linux-oracle-5.4.0/debian.oracle/initramfs-tools.d/oracle.hook.in @@ -0,0 +1,23 @@ +#!/bin/sh + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions + +# version is set to "ABI-FLAVOUR", ie "4.15.0-31-generic". +if [ "$version" = '@abiname@@localversion@' ]; then + echo 'NETWORK_SKIP_ENSLAVED=1' >> "$DESTDIR/conf/conf.d/linux-oracle" +fi +exit 0 --- linux-oracle-5.4.0.orig/debian.oracle/modprobe.d/common.conf +++ linux-oracle-5.4.0/debian.oracle/modprobe.d/common.conf @@ -0,0 +1,3 @@ +# LP:1434842 -- disable OSS drivers by default to allow pulseaudio to emulate +blacklist snd-mixer-oss +blacklist snd-pcm-oss --- linux-oracle-5.4.0.orig/debian.oracle/reconstruct +++ linux-oracle-5.4.0/debian.oracle/reconstruct @@ -0,0 +1,127 @@ +# Recreate any symlinks created since the orig. +chmod +x 'arch/mips/pci/pcie-octeon.c' +chmod +x 'debian.oracle/initramfs-tools.d/oracle.hook.in' +chmod +x 'debian/cloud-tools/hv_get_dhcp_info' +chmod +x 'debian/cloud-tools/hv_get_dns_info' +chmod +x 'debian/cloud-tools/hv_set_ifconfig' +chmod +x 'debian/rules' +chmod +x 'debian/scripts/config-check' +chmod +x 'debian/scripts/control-create' +chmod +x 'debian/scripts/dkms-build' +chmod +x 'debian/scripts/dkms-build--nvidia-N' +chmod +x 'debian/scripts/dkms-build--virtualbox-guest' +chmod +x 'debian/scripts/dkms-build-configure--zfs' +chmod +x 'debian/scripts/file-downloader' +chmod +x 'debian/scripts/link-headers' +chmod +x 'debian/scripts/misc/annotations' +chmod +x 'debian/scripts/misc/arch-has-odm-enabled.sh' +chmod +x 'debian/scripts/misc/final-checks' +chmod +x 'debian/scripts/misc/find-missing-sauce.sh' +chmod +x 'debian/scripts/misc/find-obsolete-firmware' +chmod +x 'debian/scripts/misc/fw-to-ihex.sh' +chmod +x 'debian/scripts/misc/gen-auto-reconstruct' +chmod +x 'debian/scripts/misc/get-firmware' +chmod +x 'debian/scripts/misc/git-ubuntu-log' +chmod +x 'debian/scripts/misc/insert-changes.pl' +chmod +x 'debian/scripts/misc/insert-mainline-changes' +chmod +x 'debian/scripts/misc/insert-ubuntu-changes' +chmod +x 'debian/scripts/misc/kernel-wedge-arch.pl' +chmod +x 'debian/scripts/misc/kernelconfig' +chmod +x 'debian/scripts/misc/migrate-annotations' +chmod +x 'debian/scripts/misc/retag' +chmod +x 'debian/scripts/misc/splitconfig.pl' +chmod +x 'debian/scripts/misc/tristate.sh' +chmod +x 'debian/scripts/misc/update-aufs.sh' +chmod +x 'debian/scripts/module-inclusion' +chmod +x 'debian/scripts/retpoline-extract' +chmod +x 'debian/scripts/retpoline-extract-one' +chmod +x 'debian/templates/extra.postinst.in' +chmod +x 'debian/templates/extra.postrm.in' +chmod +x 'debian/templates/headers.postinst.in' +chmod +x 'debian/templates/image.postinst.in' +chmod +x 'debian/templates/image.postrm.in' +chmod +x 'debian/templates/image.preinst.in' +chmod +x 'debian/templates/image.prerm.in' +chmod +x 'debian/tests-build/check-aliases' +chmod +x 'debian/tests/rebuild' +chmod +x 'debian/tests/ubuntu-regression-suite' +chmod +x 'samples/bpf/lwt_len_hist.sh' +chmod +x 'samples/bpf/test_lwt_bpf.sh' +chmod +x 'scripts/kmsg-doc' +chmod +x 'scripts/parse-maintainers.pl' +chmod +x 'tools/testing/selftests/net/fib_nexthop_nongw.sh' +chmod +x 'tools/testing/selftests/netfilter/conntrack_vrf.sh' +# Remove any files deleted from the orig. +rm -f 'Documentation/devicetree/bindings/clock/axi-clkgen.txt' +rm -f 'Documentation/devicetree/bindings/gpu/samsung-rotator.txt' +rm -f 'Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml' +rm -f 'Documentation/features/vm/numa-memblock/arch-support.txt' +rm -f 'Documentation/networking/decnet.txt' +rm -f 'arch/alpha/include/asm/bugs.h' +rm -f 'arch/ia64/include/asm/bugs.h' +rm -f 'arch/m68k/include/asm/bugs.h' +rm -f 'arch/parisc/include/asm/bugs.h' +rm -f 'arch/parisc/kernel/module.lds' +rm -f 'arch/parisc/lib/string.S' +rm -f 'arch/powerpc/include/asm/bugs.h' +rm -f 'arch/powerpc/include/uapi/asm/bpf_perf_event.h' +rm -f 'arch/sh/include/asm/bugs.h' +rm -f 'arch/sparc/include/asm/bugs.h' +rm -f 'arch/um/include/asm/bugs.h' +rm -f 'arch/um/kernel/gmon_syms.c' +rm -f 'arch/x86/events/intel/rapl.c' +rm -f 'arch/x86/include/asm/refcount.h' +rm -f 'arch/xtensa/include/asm/bugs.h' +rm -f 'drivers/block/sx8.c' +rm -f 'drivers/crypto/hisilicon/sgl.h' +rm -f 'drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h' +rm -f 'drivers/iio/adc/stx104.c' +rm -f 'drivers/input/serio/i8042-ppcio.h' +rm -f 'drivers/net/can/dev.c' +rm -f 'drivers/net/can/rx-offload.c' +rm -f 'drivers/net/phy/mdio-i2c.h' +rm -f 'drivers/net/phy/mdio-xgene.h' +rm -f 'drivers/soc/qcom/llcc-sdm845.c' +rm -f 'drivers/soc/qcom/llcc-slice.c' +rm -f 'drivers/staging/mt7621-dma/mtk-hsdma.c' +rm -f 'include/Kbuild' +rm -f 'include/asm-generic/bugs.h' +rm -f 'include/linux/kd.h' +rm -f 'include/net/dn.h' +rm -f 'include/net/dn_dev.h' +rm -f 'include/net/dn_fib.h' +rm -f 'include/net/dn_neigh.h' +rm -f 'include/net/dn_nsp.h' +rm -f 'include/net/dn_route.h' +rm -f 'include/trace/events/random.h' +rm -f 'include/uapi/linux/dn.h' +rm -f 'include/uapi/linux/netfilter_decnet.h' +rm -f 'include/uapi/rdma/nes-abi.h' +rm -f 'kernel/elfcore.c' +rm -f 'net/decnet/Kconfig' +rm -f 'net/decnet/Makefile' +rm -f 'net/decnet/README' +rm -f 'net/decnet/af_decnet.c' +rm -f 'net/decnet/dn_dev.c' +rm -f 'net/decnet/dn_fib.c' +rm -f 'net/decnet/dn_neigh.c' +rm -f 'net/decnet/dn_nsp_in.c' +rm -f 'net/decnet/dn_nsp_out.c' +rm -f 'net/decnet/dn_route.c' +rm -f 'net/decnet/dn_rules.c' +rm -f 'net/decnet/dn_table.c' +rm -f 'net/decnet/dn_timer.c' +rm -f 'net/decnet/netfilter/Kconfig' +rm -f 'net/decnet/netfilter/Makefile' +rm -f 'net/decnet/netfilter/dn_rtmsg.c' +rm -f 'net/decnet/sysctl_net_decnet.c' +rm -f 'net/sched/cls_rsvp.c' +rm -f 'net/sched/cls_rsvp.h' +rm -f 'net/sched/cls_rsvp6.c' +rm -f 'net/sched/cls_tcindex.c' +rm -f 'net/sched/sch_atm.c' +rm -f 'net/sched/sch_cbq.c' +rm -f 'net/sched/sch_dsmark.c' +rm -f 'net/xfrm/xfrm_interface.c' +rm -f 'tools/build/feature/test-libpython-version.c' +exit 0 --- linux-oracle-5.4.0.orig/debian.oracle/rules.d/amd64.mk +++ linux-oracle-5.4.0/debian.oracle/rules.d/amd64.mk @@ -0,0 +1,32 @@ +human_arch = 64 bit x86 +build_arch = x86 +header_arch = $(build_arch) +defconfig = defconfig +flavours = oracle +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz +loader = grub +vdso = vdso_install +no_dumpfile = true +uefi_signed = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_perf_jvmti = true +do_tools_bpftool = true +do_tools_x86 = true +do_tools_hyperv = false +do_tools_host = false +do_extras_package = true +do_tools_common = false +do_tools_acpidbg = true +do_zfs = true +do_dkms_vbox = false +do_libc_dev_package = false +disable_d_i = true +do_doc_package = false +do_source_package = false +do_dtbs = false +do_common_headers_indep = false +do_dkms_wireguard = true --- linux-oracle-5.4.0.orig/debian.oracle/rules.d/arm64.mk +++ linux-oracle-5.4.0/debian.oracle/rules.d/arm64.mk @@ -0,0 +1,30 @@ +human_arch = ARMv8 +build_arch = arm64 +header_arch = $(build_arch) +defconfig = defconfig +flavours = oracle +build_image = Image.gz +kernel_file = arch/$(build_arch)/boot/Image.gz +install_file = vmlinuz +loader = grub +vdso = vdso_install +no_dumpfile = true +uefi_signed = true +do_tools_usbip = true +do_tools_cpupower = true +do_tools_perf = true +do_tools_bpftool = true +do_tools_x86 = false +do_tools_hyperv = false +do_extras_package = true +do_tools_common = true +do_zfs = true +do_dkms_vbox = false +do_dkms_wireguard = true +do_libc_dev_package = false +disable_d_i = true +do_doc_package = false +do_source_package = false +do_dtbs = false +do_common_headers_indep = false +do_dkms_nvidia = false --- linux-oracle-5.4.0.orig/debian.oracle/tracking-bug +++ linux-oracle-5.4.0/debian.oracle/tracking-bug @@ -0,0 +1 @@ +2106864 2025.04.14-1 --- linux-oracle-5.4.0.orig/debian.oracle/variants +++ linux-oracle-5.4.0/debian.oracle/variants @@ -0,0 +1 @@ +-lts-20.04 --- linux-oracle-5.4.0.orig/debian/canonical-certs.pem +++ linux-oracle-5.4.0/debian/canonical-certs.pem @@ -0,0 +1,246 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + c7:7e:51:6a:1c:25:cd:40 + Signature Algorithm: sha512WithRSAEncryption + Issuer: CN = Canonical Ltd. Live Patch Signing + Validity + Not Before: Jul 18 23:41:27 2016 GMT + Not After : Jul 16 23:41:27 2026 GMT + Subject: CN = Canonical Ltd. Live Patch Signing + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:bd:74:ee:72:b3:4a:ab:e6:31:e8:29:24:c2:bd: + 46:98:32:c0:39:ee:a3:fb:8a:ad:fe:ab:1a:5b:a3: + 2e:a1:80:db:79:61:9e:47:79:2c:75:57:a2:21:f0: + 93:f6:87:f2:9b:4b:9d:2f:b3:58:61:28:3c:41:70: + 13:16:a1:72:90:c9:d5:16:71:7c:e0:30:f9:28:5e: + 48:20:36:00:69:b7:59:9f:a3:ec:a8:eb:55:41:9f: + 38:1e:22:4a:57:20:f4:83:59:49:c5:00:93:d3:33: + 02:92:d1:fc:f0:84:3b:4a:5b:8f:b6:73:9a:89:fa: + 30:1e:e6:2a:68:f2:91:ef:59:57:3d:dc:1c:52:6f: + 5e:e6:9b:b5:b8:7c:98:c9:13:d1:39:68:01:67:91: + e0:d3:67:72:16:0a:5e:16:83:45:31:4f:b5:2b:b3: + f6:40:86:89:3a:84:6e:6f:16:61:bc:70:84:be:5a: + 13:36:7b:82:ea:07:19:fc:18:c1:16:c6:32:0b:7d: + 2c:6b:c4:21:b9:38:6b:31:dc:d9:0c:ad:56:40:68: + 7c:e3:c6:64:8e:bf:1c:e0:72:3e:6c:db:d2:73:79: + da:d7:c5:2f:5d:04:7d:b0:07:1e:95:dd:2a:47:5e: + bf:3e:3a:c8:66:f6:67:0f:d4:2a:f1:e2:71:59:d2: + 6c:7b:a0:37:ac:e6:97:80:30:13:97:48:d5:74:fc: + 38:68:e4:57:cb:99:69:5a:84:27:ac:98:51:e4:64: + bd:91:62:e8:58:27:06:2a:b9:0b:b8:08:e5:e5:b4: + 51:a7:a2:10:df:4e:07:6c:a0:3b:96:f2:6e:df:75: + 8c:97:1e:64:a0:9a:86:9b:98:26:f9:d8:b7:de:5b: + 21:b7:af:89:01:a3:f7:98:6b:da:19:ba:86:ef:ef: + f1:ce:bb:2f:89:ed:c0:b6:1b:e5:5b:f8:90:11:9a: + 52:93:e9:be:f7:35:b9:08:cb:ba:c3:ed:2f:73:af: + cc:96:07:55:b5:de:f6:03:f6:f1:89:f9:21:40:76: + c1:69:f2:61:cc:9a:94:df:9c:ec:6a:65:38:be:d1: + 4e:2a:87:c7:2f:3e:53:ae:8b:9f:54:a1:09:59:64: + 25:aa:a9:d8:44:a9:a8:a0:71:e1:32:aa:4c:32:fd: + 44:28:cc:9c:6f:8e:db:81:7e:6f:fa:00:56:c5:e5: + 03:46:63:fb:8e:71:8d:e3:13:91:9f:ac:60:3e:64: + f3:df:25:34:09:fa:2d:96:9f:16:05:ea:93:f5:e6: + 00:08:27:32:7b:3c:bd:ee:70:24:6c:3b:55:e9:db: + f4:10:2d:20:06:b4:ca:e9:29:65:55:ad:f6:52:54: + 5f:e5:a3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: + Digital Signature + X509v3 Subject Key Identifier: + 14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69 + X509v3 Authority Key Identifier: + keyid:14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69 + + Signature Algorithm: sha512WithRSAEncryption + 30:e7:48:02:37:e9:28:cf:04:a2:4d:5c:fa:d8:4e:c9:76:c7: + 14:3f:bd:2c:51:3d:33:f0:1a:bc:49:f1:47:95:8f:69:d8:a9: + 54:14:44:6c:4d:9f:55:82:08:1e:c6:5b:d5:91:d9:bc:2e:b0: + af:d6:25:65:74:96:aa:36:de:ae:31:a8:11:f2:a4:2c:5a:e1: + 4f:73:f8:4a:c3:35:b0:76:96:71:f2:b5:7d:4b:75:ee:5d:bf: + 86:a5:ba:0b:a9:52:cb:ec:ab:e5:23:4b:f2:74:55:28:17:1e: + b3:ac:27:ad:45:13:6e:69:b3:5a:be:42:36:29:48:db:e7:5c: + 22:58:a0:90:82:2c:2a:21:2b:db:f4:64:b7:91:5d:1f:2c:48: + a4:1a:85:e3:86:a5:aa:19:cd:19:e8:a5:fb:a3:7b:94:77:48: + 25:a4:cf:a0:cf:71:82:5c:6f:71:22:7c:d6:97:a0:53:bb:ec: + 30:f6:cb:16:fb:7b:fd:16:94:7a:53:6e:bd:04:64:a2:01:10: + 9f:f0:5b:b5:a6:73:41:9d:5f:6f:45:73:0d:05:f7:30:6d:39: + 90:b6:7d:55:7d:4c:2f:ae:5f:38:56:2f:8b:df:f4:bf:12:06: + 93:6e:0d:02:23:bf:71:91:57:88:e8:bd:62:72:99:00:40:29: + 1e:c9:13:11:da:7e:8e:e1:d2:a5:0d:bf:f7:d6:ec:01:0d:89: + 41:cd:d5:dc:d2:f7:5f:33:0d:4c:2f:85:b7:85:b7:81:e4:17: + 29:f0:74:cf:0e:15:8c:1a:50:0b:08:63:1a:91:4f:e7:76:97: + f1:d4:3b:7e:72:d4:c5:45:58:0c:6a:e9:0d:f2:85:d8:91:1e: + 37:bd:78:e3:39:4d:2e:fd:85:31:c1:a6:3b:6a:cc:2c:53:72: + 1d:8e:7b:f0:e6:76:86:09:6f:1a:f3:e4:a1:e2:dd:76:5f:b0: + 8c:e2:2a:54:5d:c1:88:49:90:10:15:42:7d:05:24:53:8c:54: + ff:48:18:1a:36:e3:31:d3:54:32:78:0d:fe:f2:3d:aa:0d:37: + 15:84:b4:36:47:31:e8:85:6e:0b:58:38:ff:21:91:09:c9:a8: + 43:a3:ea:60:cb:7e:ed:f7:41:6f:4e:91:c1:fd:77:46:e7:d4: + e7:86:c0:1b:fd:50:6c:aa:be:00:b3:63:02:ff:4e:c7:a5:57: + 6e:29:64:e9:54:d5:30:63:38:5f:2d:5a:db:49:5f:14:14:22: + d2:81:1f:61:9e:ee:ee:16:66:d6:bc:bd:ac:1b:5c:fb:38:31: + 95:33:2e:84:6e:7a:de:ee:b9:fc:97:17:06:13:bf:70:1c:6e: + 76:ed:66:38:e2:70:08:00 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIJAMd+UWocJc1AMA0GCSqGSIb3DQEBDQUAMCwxKjAoBgNV +BAMMIUNhbm9uaWNhbCBMdGQuIExpdmUgUGF0Y2ggU2lnbmluZzAeFw0xNjA3MTgy +MzQxMjdaFw0yNjA3MTYyMzQxMjdaMCwxKjAoBgNVBAMMIUNhbm9uaWNhbCBMdGQu +IExpdmUgUGF0Y2ggU2lnbmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAL107nKzSqvmMegpJMK9RpgywDnuo/uKrf6rGlujLqGA23lhnkd5LHVXoiHw +k/aH8ptLnS+zWGEoPEFwExahcpDJ1RZxfOAw+SheSCA2AGm3WZ+j7KjrVUGfOB4i +Slcg9INZScUAk9MzApLR/PCEO0pbj7Zzmon6MB7mKmjyke9ZVz3cHFJvXuabtbh8 +mMkT0TloAWeR4NNnchYKXhaDRTFPtSuz9kCGiTqEbm8WYbxwhL5aEzZ7guoHGfwY +wRbGMgt9LGvEIbk4azHc2QytVkBofOPGZI6/HOByPmzb0nN52tfFL10EfbAHHpXd +Kkdevz46yGb2Zw/UKvHicVnSbHugN6zml4AwE5dI1XT8OGjkV8uZaVqEJ6yYUeRk +vZFi6FgnBiq5C7gI5eW0UaeiEN9OB2ygO5bybt91jJceZKCahpuYJvnYt95bIbev +iQGj95hr2hm6hu/v8c67L4ntwLYb5Vv4kBGaUpPpvvc1uQjLusPtL3OvzJYHVbXe +9gP28Yn5IUB2wWnyYcyalN+c7GplOL7RTiqHxy8+U66Ln1ShCVlkJaqp2ESpqKBx +4TKqTDL9RCjMnG+O24F+b/oAVsXlA0Zj+45xjeMTkZ+sYD5k898lNAn6LZafFgXq +k/XmAAgnMns8ve5wJGw7Venb9BAtIAa0yukpZVWt9lJUX+WjAgMBAAGjXTBbMAwG +A1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBQU3zTRqHzzdiWr7AOe +8r9SEkm5aTAfBgNVHSMEGDAWgBQU3zTRqHzzdiWr7AOe8r9SEkm5aTANBgkqhkiG +9w0BAQ0FAAOCAgEAMOdIAjfpKM8Eok1c+thOyXbHFD+9LFE9M/AavEnxR5WPadip +VBREbE2fVYIIHsZb1ZHZvC6wr9YlZXSWqjberjGoEfKkLFrhT3P4SsM1sHaWcfK1 +fUt17l2/hqW6C6lSy+yr5SNL8nRVKBces6wnrUUTbmmzWr5CNilI2+dcIligkIIs +KiEr2/Rkt5FdHyxIpBqF44alqhnNGeil+6N7lHdIJaTPoM9xglxvcSJ81pegU7vs +MPbLFvt7/RaUelNuvQRkogEQn/BbtaZzQZ1fb0VzDQX3MG05kLZ9VX1ML65fOFYv +i9/0vxIGk24NAiO/cZFXiOi9YnKZAEApHskTEdp+juHSpQ2/99bsAQ2JQc3V3NL3 +XzMNTC+Ft4W3geQXKfB0zw4VjBpQCwhjGpFP53aX8dQ7fnLUxUVYDGrpDfKF2JEe +N7144zlNLv2FMcGmO2rMLFNyHY578OZ2hglvGvPkoeLddl+wjOIqVF3BiEmQEBVC +fQUkU4xU/0gYGjbjMdNUMngN/vI9qg03FYS0Nkcx6IVuC1g4/yGRCcmoQ6PqYMt+ +7fdBb06Rwf13RufU54bAG/1QbKq+ALNjAv9Ox6VXbilk6VTVMGM4Xy1a20lfFBQi +0oEfYZ7u7hZm1ry9rBtc+zgxlTMuhG563u65/JcXBhO/cBxudu1mOOJwCAA= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e9:df:13:0f:92:92:a9:b7 + Signature Algorithm: sha512WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing + Validity + Not Before: May 31 16:06:09 2016 GMT + Not After : May 29 16:06:09 2026 GMT + Subject: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:b3:b0:4f:c6:0a:77:8b:f9:d1:53:33:34:d2:80: + b5:63:6f:e1:f6:a2:83:99:d5:b6:b1:e4:99:91:fa: + 6c:19:c6:d0:91:2a:b9:7d:b5:98:a6:0d:28:01:b8: + 7c:8e:aa:38:ec:51:37:33:96:f0:b0:9b:8d:86:5f: + 67:23:69:2f:d7:c2:f3:fb:c5:d7:f9:04:ff:f2:e5: + 61:68:b7:29:b9:c6:8e:4b:4d:2d:8f:92:0c:00:b3: + a3:d2:5a:08:64:cd:f2:09:0b:a5:0e:e6:64:75:d5: + 41:f4:4d:49:3a:0d:dc:b9:27:8e:c4:d6:b1:df:8f: + 6c:f0:e4:f7:31:cb:a9:04:a1:f9:a7:aa:15:da:59: + 03:4d:46:14:d0:dd:bf:e0:f5:9e:f0:71:0c:70:78: + 2b:08:fb:e0:b6:68:a4:74:12:9d:f7:f2:64:88:17: + 2a:8a:ed:1a:91:b5:6c:13:bd:4c:10:0a:0b:72:0b: + 90:db:7d:f3:78:44:4c:d2:a5:41:f7:1c:77:7d:5a: + 8a:54:bc:8f:fe:b7:ee:e1:bc:59:37:c4:d4:e8:14: + d0:5b:42:9b:04:00:8e:6d:83:8a:25:21:5b:08:c4: + 7b:b2:d9:99:52:c9:5e:59:6d:c4:aa:52:59:e2:e4: + 2f:7e:7e:ac:05:01:99:bf:13:72:b7:45:c5:17:da: + 8a:d5:3e:71:73:2e:d8:aa:e6:eb:5a:d0:9a:c4:93: + f3:be:eb:d2:47:25:34:16:29:fa:dd:9a:2f:b1:20: + e5:41:4e:ed:ea:51:7c:23:80:ba:3d:b5:3a:0b:8c: + 9c:85:48:6c:3c:8b:29:2f:2f:12:c7:52:34:02:ea: + 0f:ac:53:23:3c:f8:3e:40:1b:30:63:e9:2d:e6:f6: + 58:cc:51:f9:eb:08:4a:b4:c7:16:80:d1:8b:c2:64: + 6a:71:a9:70:31:a4:a7:3a:c0:93:99:1b:0e:42:c1: + 00:6d:43:27:99:6c:e5:fd:23:16:c1:8e:b5:66:17: + 2b:4c:53:5a:6d:1e:96:16:13:6a:c6:d4:85:5b:74: + 2e:ce:7c:45:2f:ad:cb:75:9e:5e:91:bd:9a:6a:86: + 1a:06:bd:39:be:a3:50:56:ea:e1:f6:e3:95:69:d7: + 31:e4:66:f7:36:b5:51:c2:22:b4:9c:74:9c:44:0b: + 0e:16:5f:53:f0:23:c6:b9:40:bd:d6:b8:7d:1b:f6: + 73:f6:27:e7:c0:e3:65:a0:58:ab:5c:59:b7:80:8c: + 8c:04:b4:a9:ae:a0:51:40:10:3b:63:59:49:87:d1: + 9b:df:a3:8c:c4:2e:eb:70:c1:0a:18:1f:cb:22:c2: + f2:4a:65:0d:e5:81:74:d8:ce:72:c6:35:be:ba:63: + 72:c4:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: + Digital Signature + X509v3 Subject Key Identifier: + 88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19 + X509v3 Authority Key Identifier: + keyid:88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19 + + Signature Algorithm: sha512WithRSAEncryption + 04:85:16:27:58:ba:71:28:57:86:7b:c2:83:db:e5:72:6f:1e: + b2:1c:63:b0:db:ad:c0:42:96:c0:4f:65:f6:35:4d:c0:07:0d: + 46:be:d3:1e:ec:f1:22:18:2a:18:5d:bb:69:a6:a6:d4:0d:c3: + 57:03:b9:e7:45:49:28:ca:6d:98:17:68:97:cb:7b:36:81:0a: + 37:9e:34:79:f3:e1:0e:5b:77:43:bb:5a:a5:45:b7:16:50:86: + fd:12:a4:96:0f:15:19:09:1c:e1:fa:80:a5:80:09:be:bb:c8: + 26:0b:3e:de:03:d2:c2:18:a4:8d:0d:de:c5:32:82:0b:fb:75: + 55:66:1a:2a:bb:e4:bd:25:91:20:15:d4:be:b8:3f:53:e3:fb: + a8:c3:55:e3:d5:e7:82:18:95:df:39:09:a7:fc:89:6e:b4:1c: + aa:2d:e8:67:c2:0d:34:34:3e:f9:fa:0b:ce:81:92:11:ae:12: + 0a:fe:35:63:ce:46:29:c4:2b:4f:cb:4e:05:0a:a1:11:e2:35: + f6:5a:5d:b5:e8:d2:6f:4c:fc:3d:24:a6:03:4b:dd:98:6b:f2: + 71:58:16:1d:a5:25:ef:d9:06:7c:e8:db:7b:88:6a:89:5c:59: + 01:92:64:db:44:08:63:6c:7c:32:d6:55:98:63:09:26:61:67: + 0a:fe:5d:ee:fd:23:59:b3:4d:91:c1:4d:41:8b:cd:20:58:fa: + 2d:45:e5:bd:1d:69:5c:03:a0:49:a6:97:54:13:b6:c9:e0:f8: + 56:83:a1:2a:c3:f4:6c:fd:ab:20:ca:3d:9c:95:c0:cf:04:bb: + 46:39:cf:34:81:65:45:27:64:01:7d:62:b3:b8:72:ea:10:d5: + 0f:53:7d:39:88:25:09:6f:8c:bc:e0:49:bb:39:e2:0e:8d:cf: + 56:4d:c1:82:6d:87:d2:e7:fc:c0:9f:a7:65:60:d2:6c:65:18: + 59:38:6e:d0:9c:d7:c3:81:9a:9a:29:8f:83:84:c3:b5:44:ff: + 28:ac:13:17:64:f2:26:13:d9:55:06:b7:69:68:7c:bf:ec:d1: + 8c:ef:b7:da:76:e1:07:73:c6:31:62:31:cb:b6:e1:e7:7f:0c: + c3:f7:4c:52:be:25:36:8e:a1:bb:60:02:c3:cb:3e:6f:29:fc: + 7f:6a:fa:f8:ec:0a:df:49:e2:57:0e:bc:bd:93:c3:1b:d5:36: + 8a:ff:d8:1b:17:c7:1f:cb:69:00:d2:54:9e:ad:61:89:92:95: + 11:f8:ea:17:83:9f:9b:09:7d:b8:94:a4:ea:f5:ae:ea:dc:dd: + 62:b9:9e:68:9c:18:ec:19:c4:13:08:c8:b1:62:ab:8e:84:69: + 11:3c:da:ea:0d:b7:22:bd +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIJAOnfEw+Skqm3MA0GCSqGSIb3DQEBDQUAMH0xCzAJBgNV +BAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4GA1UEBwwHRG91Z2xhczEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMMJENhbm9uaWNhbCBMdGQu +IEtlcm5lbCBNb2R1bGUgU2lnbmluZzAeFw0xNjA1MzExNjA2MDlaFw0yNjA1Mjkx +NjA2MDlaMH0xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4G +A1UEBwwHRG91Z2xhczEXMBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMM +JENhbm9uaWNhbCBMdGQuIEtlcm5lbCBNb2R1bGUgU2lnbmluZzCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALOwT8YKd4v50VMzNNKAtWNv4faig5nVtrHk +mZH6bBnG0JEquX21mKYNKAG4fI6qOOxRNzOW8LCbjYZfZyNpL9fC8/vF1/kE//Ll +YWi3KbnGjktNLY+SDACzo9JaCGTN8gkLpQ7mZHXVQfRNSToN3LknjsTWsd+PbPDk +9zHLqQSh+aeqFdpZA01GFNDdv+D1nvBxDHB4Kwj74LZopHQSnffyZIgXKortGpG1 +bBO9TBAKC3ILkNt983hETNKlQfccd31ailS8j/637uG8WTfE1OgU0FtCmwQAjm2D +iiUhWwjEe7LZmVLJXlltxKpSWeLkL35+rAUBmb8TcrdFxRfaitU+cXMu2Krm61rQ +msST877r0kclNBYp+t2aL7Eg5UFO7epRfCOAuj21OguMnIVIbDyLKS8vEsdSNALq +D6xTIzz4PkAbMGPpLeb2WMxR+esISrTHFoDRi8JkanGpcDGkpzrAk5kbDkLBAG1D +J5ls5f0jFsGOtWYXK0xTWm0elhYTasbUhVt0Ls58RS+ty3WeXpG9mmqGGga9Ob6j +UFbq4fbjlWnXMeRm9za1UcIitJx0nEQLDhZfU/AjxrlAvda4fRv2c/Yn58DjZaBY +q1xZt4CMjAS0qa6gUUAQO2NZSYfRm9+jjMQu63DBChgfyyLC8kplDeWBdNjOcsY1 +vrpjcsT5AgMBAAGjXTBbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1Ud +DgQWBBSI91LlYKHgc34xFjpGate3CoUMGTAfBgNVHSMEGDAWgBSI91LlYKHgc34x +FjpGate3CoUMGTANBgkqhkiG9w0BAQ0FAAOCAgEABIUWJ1i6cShXhnvCg9vlcm8e +shxjsNutwEKWwE9l9jVNwAcNRr7THuzxIhgqGF27aaam1A3DVwO550VJKMptmBdo +l8t7NoEKN540efPhDlt3Q7tapUW3FlCG/RKklg8VGQkc4fqApYAJvrvIJgs+3gPS +whikjQ3exTKCC/t1VWYaKrvkvSWRIBXUvrg/U+P7qMNV49XnghiV3zkJp/yJbrQc +qi3oZ8INNDQ++foLzoGSEa4SCv41Y85GKcQrT8tOBQqhEeI19lpdtejSb0z8PSSm +A0vdmGvycVgWHaUl79kGfOjbe4hqiVxZAZJk20QIY2x8MtZVmGMJJmFnCv5d7v0j +WbNNkcFNQYvNIFj6LUXlvR1pXAOgSaaXVBO2yeD4VoOhKsP0bP2rIMo9nJXAzwS7 +RjnPNIFlRSdkAX1is7hy6hDVD1N9OYglCW+MvOBJuzniDo3PVk3Bgm2H0uf8wJ+n +ZWDSbGUYWThu0JzXw4GamimPg4TDtUT/KKwTF2TyJhPZVQa3aWh8v+zRjO+32nbh +B3PGMWIxy7bh538Mw/dMUr4lNo6hu2ACw8s+byn8f2r6+OwK30niVw68vZPDG9U2 +iv/YGxfHH8tpANJUnq1hiZKVEfjqF4Ofmwl9uJSk6vWu6tzdYrmeaJwY7BnEEwjI +sWKrjoRpETza6g23Ir0= +-----END CERTIFICATE----- --- linux-oracle-5.4.0.orig/debian/canonical-revoked-certs.pem +++ linux-oracle-5.4.0/debian/canonical-revoked-certs.pem @@ -0,0 +1,688 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Apr 12 11:39:08 2012 GMT + Not After : Apr 11 11:39:08 2042 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62: + e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce: + b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b: + fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de: + 0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52: + cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76: + 69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4: + a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb: + 1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d: + b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e: + c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af: + e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd: + 3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02: + c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc: + 2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df: + 7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14: + 06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94: + 11:1b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0 + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d: + e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa: + 1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15: + b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83: + 40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4: + a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05: + 15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0: + 52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f: + 26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff: + 8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67: + 4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c: + 85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5: + 18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4: + e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c: + 21:00:c3:39 +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx +MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG +A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD +VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor +XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8 +wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd +eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn +DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC +nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg +MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK +AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl +MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL +wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9 +gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ +Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF +FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG +Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB +7OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M +IQDDOQ== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 2 (0x2) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Sep 26 21:52:11 2017 GMT + Not After : Sep 25 21:52:11 2047 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2017) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ef:9f:fa:9f:19:3a:9d:38:23:91:cc:c4:f9:42: + e0:f8:54:12:82:dc:97:2c:d6:5b:c1:35:eb:ff:4a: + 74:06:b5:9d:32:aa:7b:f3:fc:31:5a:34:3e:a1:a4: + 44:db:7b:6d:16:af:35:76:e0:9b:99:ad:21:11:c6: + 12:4b:ae:24:8f:bb:d3:b2:00:fe:c5:1d:9b:3a:1a: + 4a:6c:ca:fa:16:37:85:22:f9:ff:22:fc:40:e0:58: + 35:c1:39:27:b4:c6:42:1a:96:d8:a5:c5:95:2e:f7: + c5:1e:21:6e:36:84:f7:a9:a1:e1:f1:03:08:96:65: + 71:f8:eb:83:cf:82:f7:9a:44:58:72:00:14:39:29: + 4b:e9:78:2f:65:20:b3:80:76:3b:ba:0d:2d:46:f6: + 37:05:e7:05:fe:bd:6c:c7:a2:65:b5:06:6e:07:24: + 99:a1:c1:cf:e1:0e:5e:49:41:71:17:a8:50:e7:38: + 99:e5:6e:b6:db:9f:63:db:56:f4:9c:7d:89:f6:d2: + 03:6c:99:83:e0:99:23:39:36:bd:cb:b5:26:7c:7d: + b0:c6:fe:82:7c:52:ed:f9:2c:8f:79:71:3d:a9:2f: + b5:aa:7e:77:a0:fd:69:f9:97:10:a8:b2:c6:7d:88: + 9e:a2:19:bd:31:b8:02:2d:34:4d:9d:98:60:82:ad: + 04:ff + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 24:2A:DE:75:AC:4A:15:E5:0D:50:C8:4B:0D:45:FF:3E:AE:70:7A:03 + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 00:b2:b7:57:b5:2b:5d:16:d3:04:88:6a:d7:77:d5:0d:89:f1: + d2:6e:11:d1:8e:f5:62:05:c4:6a:57:df:eb:d2:86:68:f2:fd: + a7:37:11:3c:f4:ce:5d:fe:32:5f:31:a2:6b:3a:da:28:c2:88: + fa:7f:70:b5:25:99:ea:27:9a:56:6a:9d:b2:0f:14:99:e2:b7: + c6:39:1e:8e:a7:76:31:d9:ed:c5:05:8d:48:ae:1b:68:18:14: + 51:a1:7d:f6:c7:df:cb:9d:eb:a4:3b:0b:ff:c2:07:c5:42:bc: + 0d:b2:11:fa:37:17:2b:1c:b5:84:48:2d:f9:31:4a:57:49:8e: + 61:a6:82:11:06:4c:34:ea:9c:2a:47:4d:eb:e0:26:af:da:d2: + c2:08:a0:37:35:7b:73:71:de:0b:c4:ba:c8:34:de:20:04:03: + 6f:46:26:0d:b9:91:02:5b:71:76:cc:45:e4:08:d0:a6:dd:a4: + 50:d3:d9:04:91:2b:d9:5c:34:88:fc:c2:37:fd:c6:d4:3e:57: + f7:6b:ba:7b:d7:02:7a:84:0c:c8:c1:19:cc:bc:fa:52:d5:7f: + b3:35:c4:53:5d:70:0a:f6:44:60:8d:a9:11:7a:1b:7d:ae:7b: + 20:5a:4c:8d:44:f6:c1:a9:61:cb:dc:cb:90:37:d5:28:24:73: + 87:d0:e0:d8 +-----BEGIN CERTIFICATE----- +MIIEKDCCAxCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA5MjYyMTUyMTFaFw00NzA5MjUy +MTUyMTFaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV +BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG +A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxNykw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvn/qfGTqdOCORzMT5QuD4 +VBKC3Jcs1lvBNev/SnQGtZ0yqnvz/DFaND6hpETbe20WrzV24JuZrSERxhJLriSP +u9OyAP7FHZs6GkpsyvoWN4Ui+f8i/EDgWDXBOSe0xkIaltilxZUu98UeIW42hPep +oeHxAwiWZXH464PPgveaRFhyABQ5KUvpeC9lILOAdju6DS1G9jcF5wX+vWzHomW1 +Bm4HJJmhwc/hDl5JQXEXqFDnOJnlbrbbn2PbVvScfYn20gNsmYPgmSM5Nr3LtSZ8 +fbDG/oJ8Uu35LI95cT2pL7Wqfneg/Wn5lxCossZ9iJ6iGb0xuAItNE2dmGCCrQT/ +AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK +KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy +dGlmaWNhdGUwHQYDVR0OBBYEFCQq3nWsShXlDVDISw1F/z6ucHoDMB8GA1UdIwQY +MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQAAsrdX +tStdFtMEiGrXd9UNifHSbhHRjvViBcRqV9/r0oZo8v2nNxE89M5d/jJfMaJrOtoo +woj6f3C1JZnqJ5pWap2yDxSZ4rfGOR6Op3Yx2e3FBY1IrhtoGBRRoX32x9/Lneuk +Owv/wgfFQrwNshH6NxcrHLWESC35MUpXSY5hpoIRBkw06pwqR03r4Cav2tLCCKA3 +NXtzcd4LxLrINN4gBANvRiYNuZECW3F2zEXkCNCm3aRQ09kEkSvZXDSI/MI3/cbU +Plf3a7p71wJ6hAzIwRnMvPpS1X+zNcRTXXAK9kRgjakReht9rnsgWkyNRPbBqWHL +3MuQN9UoJHOH0ODY +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Oct 26 18:31:14 2018 GMT + Not After : Oct 24 18:31:14 2048 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (ESM 2018) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bf:6a:e5:6d:55:7a:ec:7a:11:37:45:9c:4c:8f: + 6b:2d:56:d3:74:2b:32:ac:84:2d:ba:cb:cc:ec:8d: + 92:22:69:48:a5:d4:f6:75:11:66:2f:cb:b2:fd:9e: + 56:ab:e6:f1:52:8e:75:3e:50:bd:25:b3:50:fc:ef: + 3d:76:f3:3f:7f:03:f6:e2:a1:25:69:5c:14:98:54: + bd:11:bf:e9:a5:ac:46:91:4b:1d:de:b7:18:2b:c8: + 22:83:15:a7:4a:00:8d:9d:e4:c0:da:f7:41:02:fd: + 9f:5f:79:93:56:cc:86:e1:b5:e0:39:0e:3c:a2:5b: + fe:c0:56:f0:92:50:5a:2b:67:67:93:56:d7:7a:75: + 99:6a:25:b4:63:a8:5f:69:7e:3a:49:58:2a:a7:80: + f6:5a:b4:be:b2:be:a8:8c:45:41:c9:f2:fc:76:a8: + 65:ef:99:29:0d:c9:9c:54:6b:0a:f0:4a:0e:61:0d: + ed:99:32:af:12:e2:12:7b:9f:7b:ec:05:c4:e0:b6: + d5:c3:71:28:ae:dd:0b:ba:97:ad:68:0b:76:e9:bf: + e7:01:7e:64:54:39:23:85:36:c8:9d:dd:27:a1:ff: + df:46:36:14:7e:cb:cc:a1:cd:49:0b:6d:c2:0c:45: + 99:56:58:7c:87:0d:59:9a:dc:4a:39:3b:1d:d9:15: + 2e:b5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 36:51:88:C1:D3:74:D6:B0:7C:3C:8F:24:0F:8E:F7:22:43:3D:6A:8B + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 4c:0f:cd:77:60:b4:6f:53:87:f3:3c:4f:e6:81:5f:a7:1c:cc: + 60:29:b6:34:6c:4d:08:9b:e2:d2:bd:f6:17:1a:62:79:b8:17: + bc:a2:60:59:fd:03:51:c3:b7:6b:de:73:b3:48:95:f5:0b:aa: + b6:3c:b4:34:dc:1d:0b:c4:97:62:87:e7:48:d5:8f:c9:ea:e8: + 91:8f:2a:40:cd:b7:b3:ee:b2:98:9e:fb:37:31:29:e6:8e:2f: + 0a:39:99:1e:c6:aa:b8:05:62:85:d3:a8:3e:60:38:98:0f:f0: + fe:c7:ab:01:a5:6a:a5:7f:70:a6:26:94:76:23:2f:08:89:74: + 97:c2:2a:ca:22:3e:7a:ea:22:22:08:07:f4:bb:f6:bc:69:9c: + 4e:44:33:e2:8e:70:17:b0:9b:cb:33:94:66:6d:ff:9a:7d:e9: + 50:b2:e8:90:14:e4:2b:91:cb:a0:c5:2e:0e:cf:19:ef:44:ef: + 84:f0:bd:57:9e:26:c2:63:3d:df:fc:a1:84:de:5c:d7:5f:3b: + fb:94:61:f0:93:89:1f:cf:c3:b2:d1:90:97:35:7d:b9:8a:ad: + e6:05:f0:e8:3b:a1:7c:af:2b:c4:af:18:33:2e:5e:87:db:9d: + 80:b5:04:fd:00:d0:60:ab:ff:85:77:0f:cb:47:22:c9:b2:85: + a8:48:16:e2 +-----BEGIN CERTIFICATE----- +MIIELDCCAxSgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xODEwMjYxODMxMTRaFw00ODEwMjQx +ODMxMTRaMIGKMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV +BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDE2MDQG +A1UEAwwtQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoRVNNIDIw +MTgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2rlbVV67HoRN0Wc +TI9rLVbTdCsyrIQtusvM7I2SImlIpdT2dRFmL8uy/Z5Wq+bxUo51PlC9JbNQ/O89 +dvM/fwP24qElaVwUmFS9Eb/ppaxGkUsd3rcYK8gigxWnSgCNneTA2vdBAv2fX3mT +VsyG4bXgOQ48olv+wFbwklBaK2dnk1bXenWZaiW0Y6hfaX46SVgqp4D2WrS+sr6o +jEVByfL8dqhl75kpDcmcVGsK8EoOYQ3tmTKvEuISe5977AXE4LbVw3Eort0Lupet +aAt26b/nAX5kVDkjhTbInd0nof/fRjYUfsvMoc1JC23CDEWZVlh8hw1ZmtxKOTsd +2RUutQIDAQABo4GgMIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUH +AwMGCisGAQQBgjcKAwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk +IENlcnRpZmljYXRlMB0GA1UdDgQWBBQ2UYjB03TWsHw8jyQPjvciQz1qizAfBgNV +HSMEGDAWgBStkZkLwiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEA +TA/Nd2C0b1OH8zxP5oFfpxzMYCm2NGxNCJvi0r32FxpiebgXvKJgWf0DUcO3a95z +s0iV9Quqtjy0NNwdC8SXYofnSNWPyerokY8qQM23s+6ymJ77NzEp5o4vCjmZHsaq +uAVihdOoPmA4mA/w/serAaVqpX9wpiaUdiMvCIl0l8IqyiI+euoiIggH9Lv2vGmc +TkQz4o5wF7CbyzOUZm3/mn3pULLokBTkK5HLoMUuDs8Z70TvhPC9V54mwmM93/yh +hN5c1187+5Rh8JOJH8/DstGQlzV9uYqt5gXw6DuhfK8rxK8YMy5eh9udgLUE/QDQ +YKv/hXcPy0ciybKFqEgW4g== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Sep 18 16:10:17 2019 GMT + Not After : Sep 16 16:10:17 2049 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2019) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e6:47:d8:75:e5:87:59:26:87:83:7d:5b:7a:b8: + 58:3d:7c:ef:36:f8:a0:7a:b7:14:56:58:7d:01:f1: + 1c:3b:8c:e6:5b:03:77:7d:a0:ed:47:0a:45:e6:75: + 5c:de:95:38:0d:38:fa:41:79:89:56:31:87:e7:a3: + 9a:36:70:b6:cf:24:2f:99:26:89:08:39:0e:14:c3: + 35:be:02:8b:52:e1:8e:7b:0c:a6:9d:78:ff:01:60: + d7:f5:c3:d5:f0:5e:dc:e4:23:09:59:72:93:d3:b5: + 22:af:7c:cd:e0:84:0f:af:11:2d:bc:c6:72:42:af: + ea:67:63:c4:10:41:78:02:80:62:0d:43:74:b4:1c: + ed:50:d7:94:f1:b0:bb:f9:57:80:e4:69:0f:83:4b: + a2:e6:2c:4a:9a:e1:7d:7c:62:19:29:27:97:1f:4c: + f1:85:f0:39:f5:31:9f:3a:39:0e:d4:4d:07:3a:40: + 55:4b:a6:6c:9d:04:89:51:2d:7c:b0:ef:40:b5:42: + 29:16:cc:65:73:38:62:21:f6:e3:2c:17:50:9d:74: + 34:4e:df:7c:4a:33:a4:bb:40:cf:d5:e5:ed:05:07: + cd:4c:f9:af:7f:a6:5c:b9:f7:c5:16:45:4e:44:40: + d7:85:32:de:ac:e5:75:ad:9b:d7:c0:26:33:1f:77: + a5:37 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + C0:74:6F:D6:C5:DA:3A:E8:27:86:46:51:AD:66:AE:47:FE:24:B3:E8 + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + aa:12:6c:d1:9d:6a:da:f0:ec:7c:17:46:3b:57:b8:d6:76:5f: + 24:e6:06:a2:0a:55:1f:2f:d3:5e:8f:de:cf:02:f2:ff:e0:dd: + d3:c7:bd:75:59:aa:cd:34:f3:28:80:73:cc:28:69:e7:a2:70: + 88:a2:c7:dc:66:f0:92:0e:ff:64:bf:30:04:54:01:1b:96:ad: + 15:c5:61:fd:32:61:d7:5e:b5:ba:91:fd:31:fc:6b:15:df:ee: + 22:d9:e4:1f:f3:cc:8b:0c:9f:f5:e8:f7:e2:62:3f:40:52:c9: + f0:f1:1c:63:fc:6c:90:e1:5b:74:03:b9:df:d1:3e:a8:ec:db: + 2b:6e:83:6f:9f:7f:ba:b4:79:fc:3d:e7:12:2f:4a:e7:17:8c: + 2b:77:a5:90:74:3c:bd:cf:75:83:0d:1a:95:d5:56:ef:07:9b: + a6:b3:31:e3:8c:97:ce:68:11:b5:7b:25:03:72:1c:ea:67:e9: + 7c:3e:73:c7:7c:3e:fc:f5:ae:8a:b2:07:0d:15:6a:66:09:d7: + 23:b9:5d:80:7a:26:d6:b6:22:30:aa:84:af:c0:42:e9:75:c3: + 59:ab:a3:84:87:6b:0c:b7:ab:4e:92:69:ae:2c:82:6f:ab:01: + 24:ab:ff:78:6d:59:85:c2:3b:23:c0:bd:0d:d8:6e:3a:29:82: + e1:c4:5f:db +-----BEGIN CERTIFICATE----- +MIIEKDCCAxCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTA5MTgxNjEwMTdaFw00OTA5MTYx +NjEwMTdaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV +BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG +A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxOSkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmR9h15YdZJoeDfVt6uFg9 +fO82+KB6txRWWH0B8Rw7jOZbA3d9oO1HCkXmdVzelTgNOPpBeYlWMYfno5o2cLbP +JC+ZJokIOQ4UwzW+AotS4Y57DKadeP8BYNf1w9XwXtzkIwlZcpPTtSKvfM3ghA+v +ES28xnJCr+pnY8QQQXgCgGINQ3S0HO1Q15TxsLv5V4DkaQ+DS6LmLEqa4X18Yhkp +J5cfTPGF8Dn1MZ86OQ7UTQc6QFVLpmydBIlRLXyw70C1QikWzGVzOGIh9uMsF1Cd +dDRO33xKM6S7QM/V5e0FB81M+a9/ply598UWRU5EQNeFMt6s5XWtm9fAJjMfd6U3 +AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK +KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy +dGlmaWNhdGUwHQYDVR0OBBYEFMB0b9bF2jroJ4ZGUa1mrkf+JLPoMB8GA1UdIwQY +MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQCqEmzR +nWra8Ox8F0Y7V7jWdl8k5gaiClUfL9Nej97PAvL/4N3Tx711WarNNPMogHPMKGnn +onCIosfcZvCSDv9kvzAEVAEblq0VxWH9MmHXXrW6kf0x/GsV3+4i2eQf88yLDJ/1 +6PfiYj9AUsnw8Rxj/GyQ4Vt0A7nf0T6o7NsrboNvn3+6tHn8PecSL0rnF4wrd6WQ +dDy9z3WDDRqV1VbvB5umszHjjJfOaBG1eyUDchzqZ+l8PnPHfD789a6KsgcNFWpm +CdcjuV2AeibWtiIwqoSvwELpdcNZq6OEh2sMt6tOkmmuLIJvqwEkq/94bVmFwjsj +wL0N2G46KYLhxF/b +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 6 (0x6) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Sep 23 19:29:32 2021 GMT + Not After : Sep 22 19:29:32 2051 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v1) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:aa:b8:34:5b:b6:ae:44:bf:41:e1:78:11:b9:7a: + c8:88:b3:b0:26:50:10:9c:98:d1:f3:98:9f:23:50: + 64:f6:39:dd:50:3a:23:44:53:65:fc:f3:9f:f5:a5: + 8b:ae:8b:df:47:9f:e9:d5:a0:92:19:f1:21:ea:cc: + 59:3a:74:df:45:71:bc:de:64:15:a5:f6:db:ca:71: + fa:19:d4:44:0d:12:ec:47:3a:43:e2:f2:dd:8b:fe: + 0d:7b:dc:4d:db:53:06:22:61:e5:8b:35:49:b6:33: + c4:0a:69:5f:5b:81:09:84:6b:42:33:18:09:9d:a0: + 35:f7:9c:1e:de:6e:de:90:69:1a:e8:32:e4:49:ad: + c3:31:e9:f8:4a:a2:28:1d:db:0d:29:b6:48:0a:44: + 93:86:41:62:8f:73:97:60:10:8a:74:46:66:55:fe: + a0:95:35:9e:ef:9f:af:11:fa:5b:a3:7c:c2:35:64: + 11:67:28:1e:14:0a:7d:68:61:9c:cd:c7:46:39:30: + 31:79:94:56:b3:45:16:9a:b5:77:66:fe:41:43:0f: + 00:48:6e:99:dd:0c:d4:47:2c:86:8c:50:04:61:20: + dd:aa:8e:73:4f:21:b4:ee:09:4d:d3:40:01:d0:f2: + a7:5b:7d:05:3d:c1:e7:65:26:aa:8c:9a:58:5a:7c: + 6d:6f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + A8:D5:4B:BB:38:25:CF:B9:4F:A1:3C:9F:8A:59:4A:19:5C:10:7B:8D + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 24:25:25:7e:01:a5:c8:3d:54:8c:1b:05:73:d1:06:d8:db:d4: + 3a:71:d5:19:9d:97:1c:85:3c:ca:38:5a:0c:25:25:39:1a:67: + bc:6c:9d:98:6c:f3:7d:5f:b7:40:f9:73:a0:f5:7b:40:a8:66: + a5:f1:53:b1:78:80:24:3f:19:50:2f:02:09:ec:a1:8a:e6:0d: + df:c4:ae:24:9e:69:0d:5c:dc:44:4c:38:3a:53:4e:4b:a1:4b: + 92:9f:43:a4:9d:1e:76:33:18:1b:bf:62:e5:f5:bc:93:3c:4e: + 21:d5:5b:20:69:11:28:c1:c5:93:b5:8e:96:1d:1b:ca:72:79: + 24:de:67:2a:50:9d:ce:8b:41:dd:3e:82:dd:a5:04:75:54:fb: + 35:70:98:87:b4:f3:ea:41:23:23:80:0e:99:d7:03:16:ee:7e: + 11:e2:c8:29:ab:73:c5:6d:5c:a8:2f:32:03:9f:8e:66:d6:cb: + 54:84:55:75:ab:9a:dd:95:fd:05:1e:11:85:37:1e:63:d2:f4: + 7f:34:64:32:a1:63:91:91:50:39:14:1a:ea:54:78:e6:0d:04: + 23:c7:83:51:c5:25:27:07:6c:f8:65:b7:da:95:89:76:83:cc: + f3:7e:06:74:d3:6c:ef:e9:17:de:29:1e:ab:5c:d7:ec:df:f1: + 98:b8:e9:66 +-----BEGIN CERTIFICATE----- +MIIELTCCAxWgAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5MzJaGA8yMDUxMDky +MjE5MjkzMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw +MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx +IHYxKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKq4NFu2rkS/QeF4 +Ebl6yIizsCZQEJyY0fOYnyNQZPY53VA6I0RTZfzzn/Wli66L30ef6dWgkhnxIerM +WTp030VxvN5kFaX228px+hnURA0S7Ec6Q+Ly3Yv+DXvcTdtTBiJh5Ys1SbYzxApp +X1uBCYRrQjMYCZ2gNfecHt5u3pBpGugy5EmtwzHp+EqiKB3bDSm2SApEk4ZBYo9z +l2AQinRGZlX+oJU1nu+frxH6W6N8wjVkEWcoHhQKfWhhnM3HRjkwMXmUVrNFFpq1 +d2b+QUMPAEhumd0M1EcshoxQBGEg3aqOc08htO4JTdNAAdDyp1t9BT3B52Umqoya +WFp8bW8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF +BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl +ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUqNVLuzglz7lPoTyfillKGVwQe40wHwYD +VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB +ACQlJX4Bpcg9VIwbBXPRBtjb1Dpx1RmdlxyFPMo4WgwlJTkaZ7xsnZhs831ft0D5 +c6D1e0CoZqXxU7F4gCQ/GVAvAgnsoYrmDd/EriSeaQ1c3ERMODpTTkuhS5KfQ6Sd +HnYzGBu/YuX1vJM8TiHVWyBpESjBxZO1jpYdG8pyeSTeZypQnc6LQd0+gt2lBHVU ++zVwmIe08+pBIyOADpnXAxbufhHiyCmrc8VtXKgvMgOfjmbWy1SEVXWrmt2V/QUe +EYU3HmPS9H80ZDKhY5GRUDkUGupUeOYNBCPHg1HFJScHbPhlt9qViXaDzPN+BnTT +bO/pF94pHqtc1+zf8Zi46WY= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 7 (0x7) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Sep 23 19:29:42 2021 GMT + Not After : Sep 22 19:29:42 2051 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v2) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ba:06:8b:ee:58:b7:8b:49:7b:53:7a:d1:df:02: + e3:f2:d8:b0:8c:03:5c:f4:2d:0b:d8:18:3b:23:fa: + 68:b0:e8:e9:9d:dc:a2:eb:5e:d3:06:a9:28:d4:9f: + 14:b6:1e:1c:1d:ef:69:0e:7f:44:f2:cc:4a:f1:b1: + d0:71:30:6a:50:1e:b0:d3:f8:a4:19:d0:4a:f1:e3: + eb:7a:e5:57:4c:a1:fb:d1:87:b9:48:e0:55:37:52: + f9:de:99:2e:95:85:36:ce:d3:1d:67:2f:14:cb:7f: + 05:82:75:21:b6:aa:a5:14:ac:da:4a:f4:fe:fa:5c: + 33:49:3d:6f:de:fd:9d:75:ba:e2:c4:02:38:b5:69: + f5:ff:a8:67:4b:3a:e0:34:f6:3b:07:03:a5:7e:59: + 6f:3a:d2:28:a4:2f:25:ac:d8:a9:1f:59:52:5d:24: + 36:58:51:b5:f0:12:a8:d3:78:56:57:b1:e0:a9:df: + 14:05:65:7c:b5:a5:00:f0:88:39:14:44:18:85:2d: + 0c:28:69:7b:b9:b4:1c:47:6f:43:66:4c:22:ad:f7: + f6:19:75:e1:14:2c:0d:33:3f:c1:3f:fc:73:56:b2: + 68:05:b5:92:03:9b:65:6b:81:80:92:35:03:9b:66: + 68:58:c5:66:11:b6:8c:7f:05:09:9a:45:a6:0e:5e: + 5f:bf + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 4C:F0:46:89:2D:6F:D3:C9:A5:B0:3F:98:D8:45:F9:08:51:DC:6A:8C + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 93:9d:49:7d:9f:3e:3e:27:79:97:d9:c2:fc:0b:f7:30:b7:f4: + 78:b2:c9:e4:5e:42:d3:27:26:70:cf:88:96:d1:f2:ea:a0:75: + 7e:3c:f6:b7:d2:e7:95:30:e3:a6:67:a7:ee:b9:53:8f:fd:b2: + cb:db:e1:98:32:be:98:79:09:46:c6:63:6a:57:87:4d:b2:26: + 46:f6:34:5e:18:75:ca:82:80:8e:33:c2:1d:c7:76:d7:14:57: + ef:2e:0e:9e:58:5c:81:8e:ed:53:2c:07:46:0a:8a:fc:2f:f5: + b2:c8:58:f5:fa:fa:bb:f9:7d:47:13:39:f0:f2:1c:15:9c:75: + 90:40:bd:08:04:b3:6a:de:c2:cd:34:21:7e:ba:31:48:bc:a1: + 23:bc:ee:93:b2:62:96:27:30:86:c2:d4:f7:b4:e6:3c:71:47: + 37:84:ff:3d:0c:1e:ec:f3:0e:da:6b:dc:64:7a:b8:c0:7e:45: + 13:09:bf:02:b3:b7:5b:6d:09:2d:6a:4e:0b:93:94:29:4c:a6: + c3:c7:05:fa:69:08:04:53:3c:4c:64:c0:7e:89:00:91:1b:a6: + c2:d7:ea:c4:db:86:38:fe:66:03:85:7b:fc:39:24:99:4c:2a: + 3e:10:8b:91:c3:6e:20:9d:0c:ee:51:70:b5:98:58:f3:5c:ac: + 16:98:7b:ce +-----BEGIN CERTIFICATE----- +MIIELTCCAxWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5NDJaGA8yMDUxMDky +MjE5Mjk0MlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw +MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx +IHYyKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoGi+5Yt4tJe1N6 +0d8C4/LYsIwDXPQtC9gYOyP6aLDo6Z3coute0wapKNSfFLYeHB3vaQ5/RPLMSvGx +0HEwalAesNP4pBnQSvHj63rlV0yh+9GHuUjgVTdS+d6ZLpWFNs7THWcvFMt/BYJ1 +IbaqpRSs2kr0/vpcM0k9b979nXW64sQCOLVp9f+oZ0s64DT2OwcDpX5ZbzrSKKQv +JazYqR9ZUl0kNlhRtfASqNN4Vlex4KnfFAVlfLWlAPCIORREGIUtDChpe7m0HEdv +Q2ZMIq339hl14RQsDTM/wT/8c1ayaAW1kgObZWuBgJI1A5tmaFjFZhG2jH8FCZpF +pg5eX78CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF +BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl +ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUTPBGiS1v08mlsD+Y2EX5CFHcaowwHwYD +VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB +AJOdSX2fPj4neZfZwvwL9zC39HiyyeReQtMnJnDPiJbR8uqgdX489rfS55Uw46Zn +p+65U4/9ssvb4Zgyvph5CUbGY2pXh02yJkb2NF4YdcqCgI4zwh3HdtcUV+8uDp5Y +XIGO7VMsB0YKivwv9bLIWPX6+rv5fUcTOfDyHBWcdZBAvQgEs2rews00IX66MUi8 +oSO87pOyYpYnMIbC1Pe05jxxRzeE/z0MHuzzDtpr3GR6uMB+RRMJvwKzt1ttCS1q +TguTlClMpsPHBfppCARTPExkwH6JAJEbpsLX6sTbhjj+ZgOFe/w5JJlMKj4Qi5HD +biCdDO5RcLWYWPNcrBaYe84= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 8 (0x8) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Sep 23 19:30:02 2021 GMT + Not After : Sep 22 19:30:02 2051 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v3) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d6:29:96:87:ae:07:42:45:bb:65:09:b2:9b:de: + 5d:8e:78:61:10:d5:6d:ae:ae:26:08:6a:06:ec:4a: + dd:2b:e7:1a:a9:ad:78:e3:fc:cf:8f:d1:47:bd:1e: + 33:d8:7a:e3:66:9b:e9:73:c1:5f:42:e2:fe:bc:c3: + 41:f7:cd:d7:85:d7:42:c9:ea:31:e5:47:b1:93:5b: + 43:2b:07:51:b8:75:08:ad:0f:e7:0d:81:38:5a:21: + df:b1:43:5b:db:37:c5:ac:aa:14:3a:33:19:6a:26: + e0:05:fe:cd:41:31:af:5d:a8:ab:31:77:44:fc:da: + 00:e2:7a:44:33:c3:a7:ed:13:54:9f:19:5d:c9:98: + a2:3b:af:4d:0d:87:29:9c:90:9e:42:9e:9a:06:6a: + 70:27:c5:aa:f7:a2:f2:88:e0:b9:66:9a:72:a0:f6: + 61:7e:30:8f:14:9f:44:0d:dd:54:ae:47:c8:82:ba: + d2:b2:db:6f:24:c1:f4:0a:81:07:90:47:49:5f:57: + d6:3f:bf:2a:73:98:f2:f6:24:1a:74:03:d7:35:f0: + 42:d8:14:c5:94:27:5d:3c:49:0c:b0:f0:7a:61:1b: + d7:5a:e3:a3:40:57:e9:a4:07:ee:02:a3:32:27:94: + bb:f3:36:c5:5f:ef:d3:07:04:3a:80:4c:9c:0a:b7: + 88:9f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 10:04:37:BB:6D:E6:E4:69:B5:81:E6:1C:D6:6B:CE:3E:F4:ED:53:AF + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 3b:37:d6:a8:8d:cd:d2:df:13:35:ac:8c:92:d6:b0:ac:d1:38: + a8:00:97:47:59:b8:4a:84:8c:80:a5:1d:c7:29:bf:00:66:e5: + 10:40:26:2e:31:f5:e1:13:c0:1b:29:f3:0b:7e:2d:71:d8:db: + e1:32:8f:79:8e:e3:97:0c:40:a9:a0:12:c1:fc:c2:50:88:72: + 44:c5:bc:8b:45:6e:28:fd:d2:37:d6:db:17:cf:4e:61:33:08: + 5a:5d:08:94:73:44:e2:76:00:44:1b:b8:00:a1:86:00:64:8a: + f1:42:32:3c:28:11:67:7c:8b:aa:06:34:74:58:e8:b3:3a:36: + 8d:f6:04:5d:37:f5:66:52:c9:48:b0:a7:6f:34:09:dd:60:2a: + 86:b9:14:f1:09:f6:06:16:56:e0:51:b1:e8:75:7f:fa:37:dc: + e0:98:a7:69:ae:7b:1a:73:89:0d:06:67:cc:01:ef:80:31:45: + 9e:bb:03:2a:eb:89:70:d6:19:b2:c7:ce:bc:81:df:da:c8:6f: + a9:4b:2d:d7:a7:e1:af:c6:e8:fb:f0:61:c9:cd:d2:91:cd:8b: + c2:6c:ef:e0:b6:7f:f1:c4:81:f9:bb:76:9c:26:e3:fa:a1:a0: + cd:5e:05:de:ee:f9:1b:5b:50:0a:8b:0f:47:e3:90:32:ac:2a: + e7:65:02:80 +-----BEGIN CERTIFICATE----- +MIIELTCCAxWgAwIBAgIBCDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTMwMDJaGA8yMDUxMDky +MjE5MzAwMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw +MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx +IHYzKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANYploeuB0JFu2UJ +spveXY54YRDVba6uJghqBuxK3SvnGqmteOP8z4/RR70eM9h642ab6XPBX0Li/rzD +QffN14XXQsnqMeVHsZNbQysHUbh1CK0P5w2BOFoh37FDW9s3xayqFDozGWom4AX+ +zUExr12oqzF3RPzaAOJ6RDPDp+0TVJ8ZXcmYojuvTQ2HKZyQnkKemgZqcCfFqvei +8ojguWaacqD2YX4wjxSfRA3dVK5HyIK60rLbbyTB9AqBB5BHSV9X1j+/KnOY8vYk +GnQD1zXwQtgUxZQnXTxJDLDwemEb11rjo0BX6aQH7gKjMieUu/M2xV/v0wcEOoBM +nAq3iJ8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF +BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl +ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUEAQ3u23m5Gm1geYc1mvOPvTtU68wHwYD +VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB +ADs31qiNzdLfEzWsjJLWsKzROKgAl0dZuEqEjIClHccpvwBm5RBAJi4x9eETwBsp +8wt+LXHY2+Eyj3mO45cMQKmgEsH8wlCIckTFvItFbij90jfW2xfPTmEzCFpdCJRz +ROJ2AEQbuAChhgBkivFCMjwoEWd8i6oGNHRY6LM6No32BF039WZSyUiwp280Cd1g +Koa5FPEJ9gYWVuBRseh1f/o33OCYp2muexpziQ0GZ8wB74AxRZ67AyrriXDWGbLH +zryB39rIb6lLLden4a/G6PvwYcnN0pHNi8Js7+C2f/HEgfm7dpwm4/qhoM1eBd7u ++RtbUAqLD0fjkDKsKudlAoA= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority + Validity + Not Before: Mar 4 10:27:14 2020 GMT + Not After : Mar 3 10:27:14 2050 GMT + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (Ubuntu Core 2019) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b9:10:47:2e:75:5d:f3:10:23:bb:a0:75:d2:fa: + 02:2d:ff:22:df:c1:e6:cd:38:7c:36:0f:ae:74:15: + 6e:a5:34:52:2b:c3:a4:3a:60:d7:06:ee:1d:99:93: + ff:66:91:a3:18:52:2c:8c:58:e6:b4:2f:4b:c5:fb: + 83:e6:f3:19:bd:1b:ca:23:ec:97:1f:d8:f1:9a:f1: + 04:da:da:10:04:53:4b:ec:1d:b6:26:47:7c:bb:8f: + a7:0a:6e:2e:e8:91:e6:c4:bb:64:34:78:3c:fa:09: + 15:1c:8f:9e:eb:04:99:36:22:c6:8d:07:15:0f:b9: + 69:08:fa:ff:4b:45:bd:ba:2b:cd:01:0e:e7:01:23: + c9:e5:7a:39:3b:91:b0:45:3c:d5:77:ba:ca:f9:29: + 3d:11:3f:1c:6b:5b:8e:6c:4b:3f:c9:29:05:cb:59: + d6:b1:c1:c0:2d:56:88:70:27:fa:73:05:5c:c2:11: + d4:27:11:f7:0b:c2:d5:68:d3:1a:cd:ed:d0:e4:10: + ff:34:cb:b7:45:70:34:2c:23:53:b6:9c:30:70:b4: + 5c:d1:e2:64:18:82:8f:62:b1:5e:aa:0b:d4:89:f2: + 1c:53:c4:32:7d:ef:53:ee:9b:6e:02:ab:78:bd:25: + 67:8b:39:36:d8:84:3b:06:99:02:d6:75:73:4e:f2: + f6:b9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Extended Key Usage: + Code Signing, 1.3.6.1.4.1.311.10.3.6 + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + C1:D5:7B:8F:6B:74:3F:23:EE:41:F4:F7:EE:29:2F:06:EE:CA:DF:B9 + X509v3 Authority Key Identifier: + AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 2d:b5:11:a8:d2:a0:af:81:a0:18:22:18:2c:08:d0:f4:63:e8: + 8f:9a:f4:f5:20:dd:eb:22:77:19:9a:1a:09:3d:7f:aa:7d:c9: + 81:bc:26:98:65:94:46:30:4b:c2:51:7c:f7:21:41:63:87:31: + fc:a4:c9:41:28:c7:2e:2a:2e:d8:a8:75:7a:72:77:3b:1b:9f: + 72:15:0d:0c:96:8d:8b:51:f3:ce:37:b6:ca:9f:ca:59:40:4a: + fc:73:7a:94:12:99:aa:c2:8d:52:ce:91:19:2e:b4:da:ff:e5: + 2c:67:74:d9:58:47:38:2f:61:88:c5:cf:a7:48:e1:08:ba:bc: + ec:d5:3a:47:d9:8c:dc:c3:bc:cb:98:2b:79:7a:02:46:ef:85: + 19:2f:03:4b:05:84:eb:56:98:5f:6d:cf:a5:8b:a2:b6:e5:50: + 51:7c:33:44:bd:7a:94:2e:0d:90:39:39:3e:62:60:ae:3a:e2: + f5:17:fa:f1:94:06:1d:ae:a3:f8:19:20:7f:4b:4c:07:c4:e6: + 2d:0d:e5:94:84:51:6d:6f:0f:c4:c6:79:1d:f0:e8:0e:23:9e: + fd:f9:46:2c:b9:ec:97:38:56:7e:b8:13:f6:d2:e1:8e:a5:93: + 02:7b:6e:dd:33:9a:bf:10:a8:1b:3d:fa:c4:f2:15:f0:27:73: + 26:a6:94:d1 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy +IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMDAzMDQxMDI3MTRaGA8yMDUwMDMw +MzEwMjcxNFowgZIxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MT4w +PAYDVQQDDDVDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nIChVYnVu +dHUgQ29yZSAyMDE5KTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkQ +Ry51XfMQI7ugddL6Ai3/It/B5s04fDYPrnQVbqU0UivDpDpg1wbuHZmT/2aRoxhS +LIxY5rQvS8X7g+bzGb0byiPslx/Y8ZrxBNraEARTS+wdtiZHfLuPpwpuLuiR5sS7 +ZDR4PPoJFRyPnusEmTYixo0HFQ+5aQj6/0tFvborzQEO5wEjyeV6OTuRsEU81Xe6 +yvkpPRE/HGtbjmxLP8kpBctZ1rHBwC1WiHAn+nMFXMIR1CcR9wvC1WjTGs3t0OQQ +/zTLt0VwNCwjU7acMHC0XNHiZBiCj2KxXqoL1InyHFPEMn3vU+6bbgKreL0lZ4s5 +NtiEOwaZAtZ1c07y9rkCAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQY +MBYGCCsGAQUFBwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM +IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUwdV7j2t0PyPuQfT37ikv +Bu7K37kwHwYDVR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcN +AQELBQADggEBAC21EajSoK+BoBgiGCwI0PRj6I+a9PUg3esidxmaGgk9f6p9yYG8 +JphllEYwS8JRfPchQWOHMfykyUEoxy4qLtiodXpydzsbn3IVDQyWjYtR8843tsqf +yllASvxzepQSmarCjVLOkRkutNr/5SxndNlYRzgvYYjFz6dI4Qi6vOzVOkfZjNzD +vMuYK3l6AkbvhRkvA0sFhOtWmF9tz6WLorblUFF8M0S9epQuDZA5OT5iYK464vUX ++vGUBh2uo/gZIH9LTAfE5i0N5ZSEUW1vD8TGeR3w6A4jnv35Riy57Jc4Vn64E/bS +4Y6lkwJ7bt0zmr8QqBs9+sTyFfAncyamlNE= +-----END CERTIFICATE----- --- linux-oracle-5.4.0.orig/debian/certs/canonical-livepatch-all.pem +++ linux-oracle-5.4.0/debian/certs/canonical-livepatch-all.pem @@ -0,0 +1,121 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + c7:7e:51:6a:1c:25:cd:40 + Signature Algorithm: sha512WithRSAEncryption + Issuer: CN = Canonical Ltd. Live Patch Signing + Validity + Not Before: Jul 18 23:41:27 2016 GMT + Not After : Jul 16 23:41:27 2026 GMT + Subject: CN = Canonical Ltd. Live Patch Signing + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:bd:74:ee:72:b3:4a:ab:e6:31:e8:29:24:c2:bd: + 46:98:32:c0:39:ee:a3:fb:8a:ad:fe:ab:1a:5b:a3: + 2e:a1:80:db:79:61:9e:47:79:2c:75:57:a2:21:f0: + 93:f6:87:f2:9b:4b:9d:2f:b3:58:61:28:3c:41:70: + 13:16:a1:72:90:c9:d5:16:71:7c:e0:30:f9:28:5e: + 48:20:36:00:69:b7:59:9f:a3:ec:a8:eb:55:41:9f: + 38:1e:22:4a:57:20:f4:83:59:49:c5:00:93:d3:33: + 02:92:d1:fc:f0:84:3b:4a:5b:8f:b6:73:9a:89:fa: + 30:1e:e6:2a:68:f2:91:ef:59:57:3d:dc:1c:52:6f: + 5e:e6:9b:b5:b8:7c:98:c9:13:d1:39:68:01:67:91: + e0:d3:67:72:16:0a:5e:16:83:45:31:4f:b5:2b:b3: + f6:40:86:89:3a:84:6e:6f:16:61:bc:70:84:be:5a: + 13:36:7b:82:ea:07:19:fc:18:c1:16:c6:32:0b:7d: + 2c:6b:c4:21:b9:38:6b:31:dc:d9:0c:ad:56:40:68: + 7c:e3:c6:64:8e:bf:1c:e0:72:3e:6c:db:d2:73:79: + da:d7:c5:2f:5d:04:7d:b0:07:1e:95:dd:2a:47:5e: + bf:3e:3a:c8:66:f6:67:0f:d4:2a:f1:e2:71:59:d2: + 6c:7b:a0:37:ac:e6:97:80:30:13:97:48:d5:74:fc: + 38:68:e4:57:cb:99:69:5a:84:27:ac:98:51:e4:64: + bd:91:62:e8:58:27:06:2a:b9:0b:b8:08:e5:e5:b4: + 51:a7:a2:10:df:4e:07:6c:a0:3b:96:f2:6e:df:75: + 8c:97:1e:64:a0:9a:86:9b:98:26:f9:d8:b7:de:5b: + 21:b7:af:89:01:a3:f7:98:6b:da:19:ba:86:ef:ef: + f1:ce:bb:2f:89:ed:c0:b6:1b:e5:5b:f8:90:11:9a: + 52:93:e9:be:f7:35:b9:08:cb:ba:c3:ed:2f:73:af: + cc:96:07:55:b5:de:f6:03:f6:f1:89:f9:21:40:76: + c1:69:f2:61:cc:9a:94:df:9c:ec:6a:65:38:be:d1: + 4e:2a:87:c7:2f:3e:53:ae:8b:9f:54:a1:09:59:64: + 25:aa:a9:d8:44:a9:a8:a0:71:e1:32:aa:4c:32:fd: + 44:28:cc:9c:6f:8e:db:81:7e:6f:fa:00:56:c5:e5: + 03:46:63:fb:8e:71:8d:e3:13:91:9f:ac:60:3e:64: + f3:df:25:34:09:fa:2d:96:9f:16:05:ea:93:f5:e6: + 00:08:27:32:7b:3c:bd:ee:70:24:6c:3b:55:e9:db: + f4:10:2d:20:06:b4:ca:e9:29:65:55:ad:f6:52:54: + 5f:e5:a3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: + Digital Signature + X509v3 Subject Key Identifier: + 14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69 + X509v3 Authority Key Identifier: + keyid:14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69 + + Signature Algorithm: sha512WithRSAEncryption + 30:e7:48:02:37:e9:28:cf:04:a2:4d:5c:fa:d8:4e:c9:76:c7: + 14:3f:bd:2c:51:3d:33:f0:1a:bc:49:f1:47:95:8f:69:d8:a9: + 54:14:44:6c:4d:9f:55:82:08:1e:c6:5b:d5:91:d9:bc:2e:b0: + af:d6:25:65:74:96:aa:36:de:ae:31:a8:11:f2:a4:2c:5a:e1: + 4f:73:f8:4a:c3:35:b0:76:96:71:f2:b5:7d:4b:75:ee:5d:bf: + 86:a5:ba:0b:a9:52:cb:ec:ab:e5:23:4b:f2:74:55:28:17:1e: + b3:ac:27:ad:45:13:6e:69:b3:5a:be:42:36:29:48:db:e7:5c: + 22:58:a0:90:82:2c:2a:21:2b:db:f4:64:b7:91:5d:1f:2c:48: + a4:1a:85:e3:86:a5:aa:19:cd:19:e8:a5:fb:a3:7b:94:77:48: + 25:a4:cf:a0:cf:71:82:5c:6f:71:22:7c:d6:97:a0:53:bb:ec: + 30:f6:cb:16:fb:7b:fd:16:94:7a:53:6e:bd:04:64:a2:01:10: + 9f:f0:5b:b5:a6:73:41:9d:5f:6f:45:73:0d:05:f7:30:6d:39: + 90:b6:7d:55:7d:4c:2f:ae:5f:38:56:2f:8b:df:f4:bf:12:06: + 93:6e:0d:02:23:bf:71:91:57:88:e8:bd:62:72:99:00:40:29: + 1e:c9:13:11:da:7e:8e:e1:d2:a5:0d:bf:f7:d6:ec:01:0d:89: + 41:cd:d5:dc:d2:f7:5f:33:0d:4c:2f:85:b7:85:b7:81:e4:17: + 29:f0:74:cf:0e:15:8c:1a:50:0b:08:63:1a:91:4f:e7:76:97: + f1:d4:3b:7e:72:d4:c5:45:58:0c:6a:e9:0d:f2:85:d8:91:1e: + 37:bd:78:e3:39:4d:2e:fd:85:31:c1:a6:3b:6a:cc:2c:53:72: + 1d:8e:7b:f0:e6:76:86:09:6f:1a:f3:e4:a1:e2:dd:76:5f:b0: + 8c:e2:2a:54:5d:c1:88:49:90:10:15:42:7d:05:24:53:8c:54: + ff:48:18:1a:36:e3:31:d3:54:32:78:0d:fe:f2:3d:aa:0d:37: + 15:84:b4:36:47:31:e8:85:6e:0b:58:38:ff:21:91:09:c9:a8: + 43:a3:ea:60:cb:7e:ed:f7:41:6f:4e:91:c1:fd:77:46:e7:d4: + e7:86:c0:1b:fd:50:6c:aa:be:00:b3:63:02:ff:4e:c7:a5:57: + 6e:29:64:e9:54:d5:30:63:38:5f:2d:5a:db:49:5f:14:14:22: + d2:81:1f:61:9e:ee:ee:16:66:d6:bc:bd:ac:1b:5c:fb:38:31: + 95:33:2e:84:6e:7a:de:ee:b9:fc:97:17:06:13:bf:70:1c:6e: + 76:ed:66:38:e2:70:08:00 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIJAMd+UWocJc1AMA0GCSqGSIb3DQEBDQUAMCwxKjAoBgNV +BAMMIUNhbm9uaWNhbCBMdGQuIExpdmUgUGF0Y2ggU2lnbmluZzAeFw0xNjA3MTgy +MzQxMjdaFw0yNjA3MTYyMzQxMjdaMCwxKjAoBgNVBAMMIUNhbm9uaWNhbCBMdGQu +IExpdmUgUGF0Y2ggU2lnbmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAL107nKzSqvmMegpJMK9RpgywDnuo/uKrf6rGlujLqGA23lhnkd5LHVXoiHw +k/aH8ptLnS+zWGEoPEFwExahcpDJ1RZxfOAw+SheSCA2AGm3WZ+j7KjrVUGfOB4i +Slcg9INZScUAk9MzApLR/PCEO0pbj7Zzmon6MB7mKmjyke9ZVz3cHFJvXuabtbh8 +mMkT0TloAWeR4NNnchYKXhaDRTFPtSuz9kCGiTqEbm8WYbxwhL5aEzZ7guoHGfwY +wRbGMgt9LGvEIbk4azHc2QytVkBofOPGZI6/HOByPmzb0nN52tfFL10EfbAHHpXd +Kkdevz46yGb2Zw/UKvHicVnSbHugN6zml4AwE5dI1XT8OGjkV8uZaVqEJ6yYUeRk +vZFi6FgnBiq5C7gI5eW0UaeiEN9OB2ygO5bybt91jJceZKCahpuYJvnYt95bIbev +iQGj95hr2hm6hu/v8c67L4ntwLYb5Vv4kBGaUpPpvvc1uQjLusPtL3OvzJYHVbXe +9gP28Yn5IUB2wWnyYcyalN+c7GplOL7RTiqHxy8+U66Ln1ShCVlkJaqp2ESpqKBx +4TKqTDL9RCjMnG+O24F+b/oAVsXlA0Zj+45xjeMTkZ+sYD5k898lNAn6LZafFgXq +k/XmAAgnMns8ve5wJGw7Venb9BAtIAa0yukpZVWt9lJUX+WjAgMBAAGjXTBbMAwG +A1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBQU3zTRqHzzdiWr7AOe +8r9SEkm5aTAfBgNVHSMEGDAWgBQU3zTRqHzzdiWr7AOe8r9SEkm5aTANBgkqhkiG +9w0BAQ0FAAOCAgEAMOdIAjfpKM8Eok1c+thOyXbHFD+9LFE9M/AavEnxR5WPadip +VBREbE2fVYIIHsZb1ZHZvC6wr9YlZXSWqjberjGoEfKkLFrhT3P4SsM1sHaWcfK1 +fUt17l2/hqW6C6lSy+yr5SNL8nRVKBces6wnrUUTbmmzWr5CNilI2+dcIligkIIs +KiEr2/Rkt5FdHyxIpBqF44alqhnNGeil+6N7lHdIJaTPoM9xglxvcSJ81pegU7vs +MPbLFvt7/RaUelNuvQRkogEQn/BbtaZzQZ1fb0VzDQX3MG05kLZ9VX1ML65fOFYv +i9/0vxIGk24NAiO/cZFXiOi9YnKZAEApHskTEdp+juHSpQ2/99bsAQ2JQc3V3NL3 +XzMNTC+Ft4W3geQXKfB0zw4VjBpQCwhjGpFP53aX8dQ7fnLUxUVYDGrpDfKF2JEe +N7144zlNLv2FMcGmO2rMLFNyHY578OZ2hglvGvPkoeLddl+wjOIqVF3BiEmQEBVC +fQUkU4xU/0gYGjbjMdNUMngN/vI9qg03FYS0Nkcx6IVuC1g4/yGRCcmoQ6PqYMt+ +7fdBb06Rwf13RufU54bAG/1QbKq+ALNjAv9Ox6VXbilk6VTVMGM4Xy1a20lfFBQi +0oEfYZ7u7hZm1ry9rBtc+zgxlTMuhG563u65/JcXBhO/cBxudu1mOOJwCAA= +-----END CERTIFICATE----- --- linux-oracle-5.4.0.orig/debian/certs/ubuntu-drivers-all.pem +++ linux-oracle-5.4.0/debian/certs/ubuntu-drivers-all.pem @@ -0,0 +1,125 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e9:df:13:0f:92:92:a9:b7 + Signature Algorithm: sha512WithRSAEncryption + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing + Validity + Not Before: May 31 16:06:09 2016 GMT + Not After : May 29 16:06:09 2026 GMT + Subject: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:b3:b0:4f:c6:0a:77:8b:f9:d1:53:33:34:d2:80: + b5:63:6f:e1:f6:a2:83:99:d5:b6:b1:e4:99:91:fa: + 6c:19:c6:d0:91:2a:b9:7d:b5:98:a6:0d:28:01:b8: + 7c:8e:aa:38:ec:51:37:33:96:f0:b0:9b:8d:86:5f: + 67:23:69:2f:d7:c2:f3:fb:c5:d7:f9:04:ff:f2:e5: + 61:68:b7:29:b9:c6:8e:4b:4d:2d:8f:92:0c:00:b3: + a3:d2:5a:08:64:cd:f2:09:0b:a5:0e:e6:64:75:d5: + 41:f4:4d:49:3a:0d:dc:b9:27:8e:c4:d6:b1:df:8f: + 6c:f0:e4:f7:31:cb:a9:04:a1:f9:a7:aa:15:da:59: + 03:4d:46:14:d0:dd:bf:e0:f5:9e:f0:71:0c:70:78: + 2b:08:fb:e0:b6:68:a4:74:12:9d:f7:f2:64:88:17: + 2a:8a:ed:1a:91:b5:6c:13:bd:4c:10:0a:0b:72:0b: + 90:db:7d:f3:78:44:4c:d2:a5:41:f7:1c:77:7d:5a: + 8a:54:bc:8f:fe:b7:ee:e1:bc:59:37:c4:d4:e8:14: + d0:5b:42:9b:04:00:8e:6d:83:8a:25:21:5b:08:c4: + 7b:b2:d9:99:52:c9:5e:59:6d:c4:aa:52:59:e2:e4: + 2f:7e:7e:ac:05:01:99:bf:13:72:b7:45:c5:17:da: + 8a:d5:3e:71:73:2e:d8:aa:e6:eb:5a:d0:9a:c4:93: + f3:be:eb:d2:47:25:34:16:29:fa:dd:9a:2f:b1:20: + e5:41:4e:ed:ea:51:7c:23:80:ba:3d:b5:3a:0b:8c: + 9c:85:48:6c:3c:8b:29:2f:2f:12:c7:52:34:02:ea: + 0f:ac:53:23:3c:f8:3e:40:1b:30:63:e9:2d:e6:f6: + 58:cc:51:f9:eb:08:4a:b4:c7:16:80:d1:8b:c2:64: + 6a:71:a9:70:31:a4:a7:3a:c0:93:99:1b:0e:42:c1: + 00:6d:43:27:99:6c:e5:fd:23:16:c1:8e:b5:66:17: + 2b:4c:53:5a:6d:1e:96:16:13:6a:c6:d4:85:5b:74: + 2e:ce:7c:45:2f:ad:cb:75:9e:5e:91:bd:9a:6a:86: + 1a:06:bd:39:be:a3:50:56:ea:e1:f6:e3:95:69:d7: + 31:e4:66:f7:36:b5:51:c2:22:b4:9c:74:9c:44:0b: + 0e:16:5f:53:f0:23:c6:b9:40:bd:d6:b8:7d:1b:f6: + 73:f6:27:e7:c0:e3:65:a0:58:ab:5c:59:b7:80:8c: + 8c:04:b4:a9:ae:a0:51:40:10:3b:63:59:49:87:d1: + 9b:df:a3:8c:c4:2e:eb:70:c1:0a:18:1f:cb:22:c2: + f2:4a:65:0d:e5:81:74:d8:ce:72:c6:35:be:ba:63: + 72:c4:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: + Digital Signature + X509v3 Subject Key Identifier: + 88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19 + X509v3 Authority Key Identifier: + keyid:88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19 + + Signature Algorithm: sha512WithRSAEncryption + 04:85:16:27:58:ba:71:28:57:86:7b:c2:83:db:e5:72:6f:1e: + b2:1c:63:b0:db:ad:c0:42:96:c0:4f:65:f6:35:4d:c0:07:0d: + 46:be:d3:1e:ec:f1:22:18:2a:18:5d:bb:69:a6:a6:d4:0d:c3: + 57:03:b9:e7:45:49:28:ca:6d:98:17:68:97:cb:7b:36:81:0a: + 37:9e:34:79:f3:e1:0e:5b:77:43:bb:5a:a5:45:b7:16:50:86: + fd:12:a4:96:0f:15:19:09:1c:e1:fa:80:a5:80:09:be:bb:c8: + 26:0b:3e:de:03:d2:c2:18:a4:8d:0d:de:c5:32:82:0b:fb:75: + 55:66:1a:2a:bb:e4:bd:25:91:20:15:d4:be:b8:3f:53:e3:fb: + a8:c3:55:e3:d5:e7:82:18:95:df:39:09:a7:fc:89:6e:b4:1c: + aa:2d:e8:67:c2:0d:34:34:3e:f9:fa:0b:ce:81:92:11:ae:12: + 0a:fe:35:63:ce:46:29:c4:2b:4f:cb:4e:05:0a:a1:11:e2:35: + f6:5a:5d:b5:e8:d2:6f:4c:fc:3d:24:a6:03:4b:dd:98:6b:f2: + 71:58:16:1d:a5:25:ef:d9:06:7c:e8:db:7b:88:6a:89:5c:59: + 01:92:64:db:44:08:63:6c:7c:32:d6:55:98:63:09:26:61:67: + 0a:fe:5d:ee:fd:23:59:b3:4d:91:c1:4d:41:8b:cd:20:58:fa: + 2d:45:e5:bd:1d:69:5c:03:a0:49:a6:97:54:13:b6:c9:e0:f8: + 56:83:a1:2a:c3:f4:6c:fd:ab:20:ca:3d:9c:95:c0:cf:04:bb: + 46:39:cf:34:81:65:45:27:64:01:7d:62:b3:b8:72:ea:10:d5: + 0f:53:7d:39:88:25:09:6f:8c:bc:e0:49:bb:39:e2:0e:8d:cf: + 56:4d:c1:82:6d:87:d2:e7:fc:c0:9f:a7:65:60:d2:6c:65:18: + 59:38:6e:d0:9c:d7:c3:81:9a:9a:29:8f:83:84:c3:b5:44:ff: + 28:ac:13:17:64:f2:26:13:d9:55:06:b7:69:68:7c:bf:ec:d1: + 8c:ef:b7:da:76:e1:07:73:c6:31:62:31:cb:b6:e1:e7:7f:0c: + c3:f7:4c:52:be:25:36:8e:a1:bb:60:02:c3:cb:3e:6f:29:fc: + 7f:6a:fa:f8:ec:0a:df:49:e2:57:0e:bc:bd:93:c3:1b:d5:36: + 8a:ff:d8:1b:17:c7:1f:cb:69:00:d2:54:9e:ad:61:89:92:95: + 11:f8:ea:17:83:9f:9b:09:7d:b8:94:a4:ea:f5:ae:ea:dc:dd: + 62:b9:9e:68:9c:18:ec:19:c4:13:08:c8:b1:62:ab:8e:84:69: + 11:3c:da:ea:0d:b7:22:bd +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIJAOnfEw+Skqm3MA0GCSqGSIb3DQEBDQUAMH0xCzAJBgNV +BAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4GA1UEBwwHRG91Z2xhczEX +MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMMJENhbm9uaWNhbCBMdGQu +IEtlcm5lbCBNb2R1bGUgU2lnbmluZzAeFw0xNjA1MzExNjA2MDlaFw0yNjA1Mjkx +NjA2MDlaMH0xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4G +A1UEBwwHRG91Z2xhczEXMBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMM +JENhbm9uaWNhbCBMdGQuIEtlcm5lbCBNb2R1bGUgU2lnbmluZzCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBALOwT8YKd4v50VMzNNKAtWNv4faig5nVtrHk +mZH6bBnG0JEquX21mKYNKAG4fI6qOOxRNzOW8LCbjYZfZyNpL9fC8/vF1/kE//Ll +YWi3KbnGjktNLY+SDACzo9JaCGTN8gkLpQ7mZHXVQfRNSToN3LknjsTWsd+PbPDk +9zHLqQSh+aeqFdpZA01GFNDdv+D1nvBxDHB4Kwj74LZopHQSnffyZIgXKortGpG1 +bBO9TBAKC3ILkNt983hETNKlQfccd31ailS8j/637uG8WTfE1OgU0FtCmwQAjm2D +iiUhWwjEe7LZmVLJXlltxKpSWeLkL35+rAUBmb8TcrdFxRfaitU+cXMu2Krm61rQ +msST877r0kclNBYp+t2aL7Eg5UFO7epRfCOAuj21OguMnIVIbDyLKS8vEsdSNALq +D6xTIzz4PkAbMGPpLeb2WMxR+esISrTHFoDRi8JkanGpcDGkpzrAk5kbDkLBAG1D +J5ls5f0jFsGOtWYXK0xTWm0elhYTasbUhVt0Ls58RS+ty3WeXpG9mmqGGga9Ob6j +UFbq4fbjlWnXMeRm9za1UcIitJx0nEQLDhZfU/AjxrlAvda4fRv2c/Yn58DjZaBY +q1xZt4CMjAS0qa6gUUAQO2NZSYfRm9+jjMQu63DBChgfyyLC8kplDeWBdNjOcsY1 +vrpjcsT5AgMBAAGjXTBbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1Ud +DgQWBBSI91LlYKHgc34xFjpGate3CoUMGTAfBgNVHSMEGDAWgBSI91LlYKHgc34x +FjpGate3CoUMGTANBgkqhkiG9w0BAQ0FAAOCAgEABIUWJ1i6cShXhnvCg9vlcm8e +shxjsNutwEKWwE9l9jVNwAcNRr7THuzxIhgqGF27aaam1A3DVwO550VJKMptmBdo +l8t7NoEKN540efPhDlt3Q7tapUW3FlCG/RKklg8VGQkc4fqApYAJvrvIJgs+3gPS +whikjQ3exTKCC/t1VWYaKrvkvSWRIBXUvrg/U+P7qMNV49XnghiV3zkJp/yJbrQc +qi3oZ8INNDQ++foLzoGSEa4SCv41Y85GKcQrT8tOBQqhEeI19lpdtejSb0z8PSSm +A0vdmGvycVgWHaUl79kGfOjbe4hqiVxZAZJk20QIY2x8MtZVmGMJJmFnCv5d7v0j +WbNNkcFNQYvNIFj6LUXlvR1pXAOgSaaXVBO2yeD4VoOhKsP0bP2rIMo9nJXAzwS7 +RjnPNIFlRSdkAX1is7hy6hDVD1N9OYglCW+MvOBJuzniDo3PVk3Bgm2H0uf8wJ+n +ZWDSbGUYWThu0JzXw4GamimPg4TDtUT/KKwTF2TyJhPZVQa3aWh8v+zRjO+32nbh +B3PGMWIxy7bh538Mw/dMUr4lNo6hu2ACw8s+byn8f2r6+OwK30niVw68vZPDG9U2 +iv/YGxfHH8tpANJUnq1hiZKVEfjqF4Ofmwl9uJSk6vWu6tzdYrmeaJwY7BnEEwjI +sWKrjoRpETza6g23Ir0= +-----END CERTIFICATE----- --- linux-oracle-5.4.0.orig/debian/changelog +++ linux-oracle-5.4.0/debian/changelog @@ -0,0 +1,57485 @@ +linux-oracle (5.4.0-1144.154) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1144.154 -proposed tracker (LP: #2106864) + + [ Ubuntu: 5.4.0-216.236 ] + + * focal/linux: 5.4.0-216.236 -proposed tracker (LP: #2106869) + * CVE-2023-52741 + - cifs: Fix use-after-free in rdata->read_into_pages() + * CVE-2021-47191 + - scsi: scsi_debug: Fix out-of-bound read in resp_readcap16() + * iommu/arm-smmu-v3: Don't reserve implementation defined register space + (LP: #2067864) + - iommu/arm-smmu-v3: Don't reserve implementation defined register space + * CVE-2025-21971 + - net_sched: Prevent creation of classes with TC_H_ROOT + * CVE-2024-56599 + - wifi: ath10k: avoid NULL pointer error during sdio remove + * Focal update: v5.4.291 upstream stable release (LP: #2106002) + - perf cs-etm: Add missing variable in cs_etm__process_queues() + - udf: Fix use of check_add_overflow() with mixed type arguments + - overflow: Add __must_check attribute to check_*() helpers + - overflow: Correct check_shl_overflow() comment + - overflow: Allow mixed type arguments + - afs: Fix directory format encoding struct + - partitions: ldm: remove the initial kernel-doc notation + - drm/etnaviv: Fix page property being used for non writecombine buffers + - wifi: rtlwifi: do not complete firmware loading needlessly + - rtlwifi: rtl8192se Rename RT_TRACE to rtl_dbg + - wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last step + - wifi: rtlwifi: usb: fix workqueue leak when probe fails + - dt-bindings: mmc: controller: clarify the address-cells description + - rtlwifi: replace usage of found with dedicated list iterator variable + - wifi: rtlwifi: remove unused timer and related code + - wifi: rtlwifi: remove unused dualmac control leftovers + - wifi: rtlwifi: pci: wait for firmware loading before releasing memory + - cpupower: fix TSC MHz calculation + - regulator: of: Implement the unwind path of of_regulator_match() + - wifi: wlcore: fix unbalanced pm_runtime calls + - selftests/harness: Display signed values correctly + - selftests: harness: fix printing of mismatch values in __EXPECT() + - clk: analogbits: Fix incorrect calculation of vco rate delta + - net/mlxfw: Drop hard coded max FW flash image size + - tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind + - ASoC: sun4i-spdif: Add clock multiplier settings + - perf header: Fix one memory leakage in process_bpf_btf() + - perf header: Fix one memory leakage in process_bpf_prog_info() + - ktest.pl: Remove unused declarations in run_bisect_test function + - padata: fix sysfs store callback check + - perf top: Don't complain about lack of vmlinux when not resolving some + kernel samples + - perf report: Fix misleading help message about --demangle + - RDMA/mlx4: Avoid false error about access to uninitialized gids array + - arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property + - arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names + - ARM: dts: mediatek: mt7623: fix IR nodename + - fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device() + - media: rc: iguanair: handle timeouts + - media: lmedm04: Use GFP_KERNEL for URB allocation/submission. + - media: lmedm04: Handle errors for lme2510_int_read + - PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy() + - media: mipi-csis: Add check for clk_enable() + - media: camif-core: Add check for clk_enable() + - media: uvcvideo: Propagate buf->error to userspace + - staging: media: imx: fix OF node leak in imx_media_add_of_subdevs() + - scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1 + - scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails + - ocfs2: mark dquot as inactive if failed to start trans while releasing dquot + - module: Extend the preempt disabled section in + dereference_symbol_descriptor(). + - dmaengine: ti: edma: fix OF node reference leaks in edma_driver + - net: fec: implement TSO descriptor cleanup + - PM: hibernate: Add error handling for syscore_suspend() + - perf trace: Fix runtime error of index out of bounds + - vsock: Allow retrying on connect() failure + - net: sh_eth: Fix missing rtnl lock in suspend/resume path + - genksyms: fix memory leak when the same symbol is added from source + - genksyms: fix memory leak when the same symbol is read from *.symref file + - hexagon: fix using plain integer as NULL pointer warning in cmpxchg + - hexagon: Fix unbalanced spinlock in die() + - NFSD: Reset cb_seq_status after NFS4ERR_DELAY + - ktest.pl: Check kernelrelease return in get_version + - drivers/card_reader/rtsx_usb: Restore interrupt based detection + - usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to PD_T_SENDER_RESPONSE + - btrfs: output the reason for open_ctree() failure + - btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error handling + - sched: Don't try to catch up excess steal time. + - x86/amd_nb: Restrict init function to AMD-based systems + - tun: fix group permission check + - mmc: core: Respect quirk_max_rate for non-UHS SDIO card + - mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id + - HID: Wacom: Add PCI Wacom device support + - APEI: GHES: Have GHES honor the panic= setting + - x86/mm: Don't disable PCID when INVLPG has been fixed by microcode + - spi-mxs: Fix chipselect glitch + - nilfs2: move page release outside of nilfs_delete_entry and nilfs_set_link + - nilfs2: eliminate staggered calls to kunmap in nilfs_rename + - media: uvcvideo: Only save async fh if success + - kbuild: userprogs: use correct lld when linking through clang + - tasklet: Introduce new initialization API + - net: usb: rtl8150: use new tasklet API + - usb: xhci: Add timeout argument in address_device USB HCD callback + - nvme: handle connectivity loss in nvme_set_queue_count + - firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry + - gpu: drm_dp_cec: fix broken CEC adapter properties check + - tg3: Disable tg3 PCIe AER on system reboot + - udp: gso: do not drop small packets when PMTU reduces + - tun: revert fix group permission check + - cpufreq: s3c64xx: Fix compilation warning + - leds: lp8860: Write full EEPROM, not only half of it + - s390/futex: Fix FUTEX_OP_ANDN implementation + - m68k: vga: Fix I/O defines + - arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma + - KVM: s390: vsie: fix some corner-cases when grabbing vsie pages + - drm/komeda: Add check for komeda_get_layer_fourcc_list() + - clk: qcom: clk-alpha-pll: fix alpha mode configuration + - clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate + - perf bench: Fix undefined behavior in cmpworker() + - of: Correct child specifier used as input of the 2nd nexus node + - of: Fix of_find_node_opts_by_path() handling of alias+path+options + - of: reserved-memory: Fix using wrong number of cells to get property + 'alignment' + - HID: hid-sensor-hub: don't use stale platform-data on remove + - usb: gadget: f_tcm: Translate error to sense + - usb: gadget: f_tcm: Decrement command ref count on cleanup + - usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint + - usb: gadget: f_tcm: Don't prepare BOT write request twice + - serial: sh-sci: Drop __initdata macro for port_cfg + - serial: sh-sci: Do not probe the serial port if its slot in sci_ports[] is + in use + - powerpc/pseries/eeh: Fix get PE state translation + - kbuild: Move -Wenum-enum-conversion to W=2 + - soc: qcom: smem_state: fix missing of_node_put in error path + - media: ov5640: fix get_light_freq on auto + - media: uvcvideo: Fix event flags in uvc_ctrl_send_events + - media: uvcvideo: Remove redundant NULL assignment + - crypto: qce - fix goto jump in error path + - crypto: qce - unregister previously registered algos in error path + - nvmem: core: improve range check for nvmem_cell_write() + - vfio/platform: check the bounds of read/write syscalls + - ocfs2: fix incorrect CPU endianness conversion causing mount failure + - mtd: onenand: Fix uninitialized retlen in do_otp_read() + - misc: fastrpc: Fix registered buffer page address + - net/ncsi: wait for the last response to Deselect Package before configuring + channel + - MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static + - ocfs2: check dir i_size in ocfs2_find_entry + - ndisc: ndisc_send_redirect() must use dev_get_by_index_rcu() + - gpio: bcm-kona: Fix GPIO lock/unlock for banks above bank 0 + - gpio: bcm-kona: Make sure GPIO bits are unlocked when requesting IRQ + - gpio: bcm-kona: Add missing newline to dev_err format string + - xen: remove a confusing comment on auto-translated guest I/O + - x86/xen: allow larger contiguous memory regions in PV guests + - media: cxd2841er: fix 64-bit division on gcc-9 + - vfio/pci: Enable iowrite64 and ioread64 for vfio pci + - Grab mm lock before grabbing pt lock + - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet 5V + - usb: roles: set switch registered flag early on + - usb: gadget: udc: renesas_usb3: Fix compiler warning + - usb: dwc2: gadget: remove of_node reference upon udc_stop + - USB: pci-quirks: Fix HCCPARAMS register error for LS7A EHCI + - USB: quirks: add USB_QUIRK_NO_LPM quirk for Teclast dist + - USB: Add USB_QUIRK_NO_LPM quirk for sony xperia xz1 smartphone + - USB: cdc-acm: Fill in Renesas R-Car D3 USB Download mode quirk + - usb: cdc-acm: Fix handling of oversized fragments + - USB: serial: option: add MeiG Smart SLM828 + - USB: serial: option: add Telit Cinterion FN990B compositions + - USB: serial: option: fix Telit Cinterion FN990A name + - USB: serial: option: drop MeiG Smart defines + - can: c_can: fix unbalanced runtime PM disable in error path + - can: j1939: j1939_sk_send_loop(): fix unable to send messages with data + length zero + - alpha: make stack 16-byte aligned (most cases) + - serial: 8250: Fix fifo underflow on flush + - alpha: align stack for page fault and user unaligned trap handlers + - gpio: stmpe: Check return value of stmpe_reg_read in + stmpe_gpio_irq_sync_unlock + - regmap-irq: Add missing kfree() + - net: treat possible_net_t net pointer as an RCU one and add read_pnet_rcu() + - net: add dev_net_rcu() helper + - ipv4: use RCU protection in rt_is_expired() + - ipv4: use RCU protection in inet_select_addr() + - neighbour: delete redundant judgment statements + - alpha: replace hardcoded stack offsets with autogenerated ones + - nilfs2: do not output warnings when clearing dirty buffers + - can: ems_pci: move ASIX AX99100 ids to pci_ids.h + - serial: 8250_pci: add support for ASIX AX99100 + - parport_pc: add support for ASIX AX99100 + - x86/i8253: Disable PIT timer 0 when not in use + - Revert "btrfs: avoid monopolizing a core when activating a swap file" + - btrfs: avoid monopolizing a core when activating a swap file + - vlan: introduce vlan_dev_free_egress_priority + - vlan: move dev_put into vlan_dev_uninit + - scsi: storvsc: Set correct data length for sending SCSI command without + payload + - crypto: testmgr - fix wrong key length for pkcs1pad + - crypto: testmgr - Fix wrong test case of RSA + - crypto: testmgr - fix version number of RSA tests + - crypto: testmgr - populate RSA CRT parameters in RSA test vectors + - crypto: testmgr - some more fixes to RSA test vectors + - mm: update mark_victim tracepoints fields + - usb: dwc3: Increase DWC3 controller halt timeout + - usb: dwc3: Fix timeout issue during controller enter/exit from halt state + - usb/gadget: f_midi: convert tasklets to use new tasklet_setup() API + - usb/gadget: f_midi: Replace tasklet with work + - powerpc/64s/mm: Move __real_pte stubs into hash-4k.h + - powerpc/64s: Rewrite __real_pte() and __rpte_to_hidx() as static inline + - ALSA: hda/realtek - Add type for ALC287 + - ALSA: hda/realtek: Fixup ALC225 depop procedure + - geneve: Suppress list corruption splat in geneve_destroy_tunnels(). + - net: extract port range fields from fl_flow_key + - flow_dissector: Fix handling of mixed port and port-range keys + - flow_dissector: Fix port range key handling in BPF conversion + - power: supply: da9150-fg: fix potential overflow + - ALSA: hda/conexant: Add quirk for HP ProBook 450 G4 mute LED + - acct: block access to kernel internal filesystems + - batman-adv: Ignore neighbor throughput metrics in error case + - sunrpc: suppress warnings for unused procfs functions + - net: loopback: Avoid sending IP packets without an Ethernet header + - net: cadence: macb: Synchronize stats calculations + - ASoC: es8328: fix route from DAC to output + - ipvs: Always clear ipvs_property flag in skb_scrub_packet() + - net: mvpp2: cls: Fixed Non IP flow, with vlan tag flow defination. + - x86/CPU: Fix warm boot hang regression on AMD SC1100 SoC systems + - ftrace: Avoid potential division by zero in function_stat_show() + - perf/core: Fix low freq setting via IOC_PERIOD + - phy: tegra: xusb: reset VBUS & ID OVERRIDE + - phy: exynos5-usbdrd: fix MPLL_MULTIPLIER and SSC_REFCLKSEL masks in refclk + - kernel/acct.c: use #elif instead of #end and #elif + - kernel/acct.c: use dedicated helper to access rlimit values + - drm/amdgpu: skip BAR resizing if the bios already did it + - drm/amdgpu: Check extended configuration space register when system uses + large bar + - drm/amdgpu: disable BAR resize on Dell G5 SE + - Revert "of: reserved-memory: Fix using wrong number of cells to get property + 'alignment'" + - HID: appleir: Fix potential NULL dereference at raw event handle + - ALSA: hda: intel: Add Dell ALC3271 to power_save denylist + - ALSA: hda/realtek: update ALC222 depop optimize + - drm/radeon: Fix rs400_gpu_init for ATI mobility radeon Xpress 200M + - platform/x86: thinkpad_acpi: Add battery quirk for ThinkPad X131e + - x86/cacheinfo: Validate CPUID leaf 0x2 EDX output + - x86/cpu: Validate CPUID leaf 0x2 EDX output + - x86/cpu: Properly parse CPUID leaf 0x2 TLB descriptor 0x63 + - wifi: cfg80211: regulatory: improve invalid hints checking + - wifi: nl80211: reject cooked mode if it is set along with other flags + - rapidio: add check for rio_add_net() in rio_scan_alloc_net() + - rapidio: fix an API misues when rio_add_net() fails + - mm/page_alloc: fix uninitialized variable + - wifi: iwlwifi: limit printed string from FW file + - HID: google: fix unused variable warning under !CONFIG_ACPI + - HID: intel-ish-hid: Fix use-after-free issue in ishtp_hid_remove() + - net: gso: fix ownership in __udp_gso_segment + - caif_virtio: fix wrong pointer check in cfv_probe() + - hwmon: (pmbus) Initialise page count in pmbus_identify() + - hwmon: (ntc_thermistor) Fix the ncpXXxh103 sensor table + - hwmon: (ad7314) Validate leading zero bits and return error + - llc: do not use skb_get() before dev_queue_xmit() + - hwmon: fix a NULL vs IS_ERR_OR_NULL() check in xgene_hwmon_probe() + - drm/sched: Fix preprocessor guard + - be2net: fix sleeping while atomic bugs in be_ndo_bridge_getlink + - ppp: Fix KMSAN uninit-value warning with bpf + - vlan: enforce underlying device type + - net-timestamp: support TCP GSO case for a few missing flags + - net: ipv6: fix dst ref loop in ila lwtunnel + - net: ipv6: fix missing dst ref drop in ila lwtunnel + - gpio: rcar: Fix missing of_node_put() call + - Revert "drivers/card_reader/rtsx_usb: Restore interrupt based detection" + - usb: renesas_usbhs: Call clk_put() + - usb: renesas_usbhs: Use devm_usb_get_phy() + - usb: quirks: Add DELAY_INIT and NO_LPM for Prolific Mass Storage Card Reader + - usb: renesas_usbhs: Flush the notify_hotplug_work + - usb: atm: cxacru: fix a flaw in existing endpoint checks + - usb: typec: ucsi: increase timeout for PPM reset operations + - usb: typec: tcpci_rt1711h: Unmask alert interrupts to fix functionality + - usb: gadget: Set self-powered based on MaxPower and bmAttributes + - usb: gadget: Fix setting self-powered state on suspend + - usb: gadget: Check bmAttributes only if configuration is valid + - xhci: pci: Fix indentation in the PCI device ID definitions + - intel_th: pci: Add Arrow Lake support + - intel_th: pci: Add Panther Lake-H support + - intel_th: pci: Add Panther Lake-P/U support + - slimbus: messaging: Free transaction ID in delayed interrupt scenario + - eeprom: digsy_mtc: Make GPIO lookup table match the device + - Linux 5.4.291 + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-26982 + - Squashfs: check the inode number is not the invalid value of zero + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21846 + - acct: perform last write from workqueue + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21862 + - drop_monitor: fix incorrect initialization order + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58090 + - sched/core: Prevent rescheduling when interrupts are disabled + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21877 + - usbnet: gl620a: fix endpoint checking in genelink_bind() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21823 + - batman-adv: Drop unmanaged ELP metric worker + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21848 + - nfp: bpf: Add check for nfp_app_ctrl_msg_alloc() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21871 + - tee: optee: Fix supplicant wait loop + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21865 + - gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl(). + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21858 + - geneve: Fix use-after-free in geneve_find_dev(). + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21866 + - powerpc/code-patching: Fix KASAN hit by not flagging text patching area as + VM_ALLOC + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21859 + - USB: gadget: f_midi: f_midi_complete to call queue_work + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57977 + - memcg: fix soft lockup in the OOM process + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-50055 + - driver core: bus: Fix double free in driver API bus_register() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57979 + - pps: Fix a use-after-free + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21811 + - nilfs2: protect access to buffers with no active references + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21722 + - nilfs2: do not force clear folio if buffer is referenced + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21760 + - ndisc: extend RCU protection in ndisc_send_skb() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21761 + - openvswitch: use RCU protection in ovs_vport_cmd_fill_info() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21762 + - arp: use RCU protection in arp_xmit() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21763 + - neighbour: use RCU protection in __neigh_notify() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21764 + - ndisc: use RCU protection in ndisc_alloc_skb() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21765 + - ipv6: use RCU protection in ip6_default_advmss() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21772 + - partitions: mac: fix handling of bogus partition table + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21704 + - usb: cdc-acm: Check control transfer buffer size before access + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21776 + - USB: hub: Ignore non-compliant devices with too many configs or interfaces + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21835 + - usb: gadget: f_midi: fix MIDI Streaming descriptor lengths + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21781 + - batman-adv: fix panic during interface removal + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21782 + - orangefs: fix a oob in orangefs_debug_write + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21785 + - arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21787 + - team: better TEAM_OPTION_TYPE_STRING validation + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21791 + - vrf: use RCU protection in l3mdev_l3_out() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58020 + - HID: multitouch: Add NULL check in mt_input_configured + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21814 + - ptp: Ensure info->enable callback is always set + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21735 + - NFC: nci: Add bounds checking in nci_hci_create_pipe() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21736 + - nilfs2: fix possible int overflows in nilfs_fiemap() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58001 + - ocfs2: handle a symlink read error correctly + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58007 + - soc: qcom: socinfo: Avoid out of bounds read of serial number + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21744 + - wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58009 + - Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58083 + - KVM: Explicitly verify target vCPU is online in kvm_get_vcpu() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58010 + - binfmt_flat: Fix integer overflow bug on 32 bit systems + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21749 + - net: rose: lock the socket in rose_bind() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57981 + - usb: xhci: Fix NULL pointer dereference on certain command aborts + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21708 + - net: usb: rtl8150: enable basic endpoint checking + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21647 + - sched: sch_cake: add bounds checks to host bulk flow fairness counts + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58002 + - media: uvcvideo: Remove dangling pointers + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21721 + - nilfs2: handle errors that nilfs_prepare_chunk() may return + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58085 + - tomoyo: don't emit warning in tomoyo_write_control() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58014 + - wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy() + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58017 + - printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21753 + - btrfs: fix use-after-free when attempting to join an aborted transaction + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58055 + - usb: gadget: f_tcm: Don't free command immediately + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57980 + - media: uvcvideo: Fix double free in error path + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57986 + - HID: core: Fix assumption that Resolution Multipliers must be in Logical + Collections + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21715 + - net: davicom: fix UAF in dm9000_drv_remove + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21718 + - net: rose: fix timer races against user threads + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21719 + - ipmr: do not call mr_mfc_uses_dev() for unres entries + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58058 + - ubifs: skip dumping tnc tree when zroot is null + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58069 + - rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-57973 + - rdma/cxgb4: Prevent potential integer overflow on 32bit + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21728 + - bpf: Send signals asynchronously if !preemptible + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21806 + - net: let net.core.dev_weight always be non-zero + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58071 + - team: prevent adding a device which is already a team device lower + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58063 + - wifi: rtlwifi: fix memory leaks and invalid access at probe error path + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58072 + - wifi: rtlwifi: remove unused check_buddy_priv + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58051 + - ipmi: ipmb: Add check devm_kasprintf() returned value + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2024-58052 + - drm/amdgpu: Fix potential NULL pointer dereference in + atomctrl_get_smc_sclk_range_table + * Focal update: v5.4.291 upstream stable release (LP: #2106002) // + CVE-2025-21731 + - nbd: don't allow reconnect after disconnect + * CVE-2024-26996 + - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport + error + * CVE-2023-52664 + - net: atlantic: eliminate double free in error handling logic + * CVE-2024-26689 + - ceph: prevent use-after-free in encode_cap_msg() + * CVE-2023-52927 + - netfilter: allow exp not to be removed in nf_ct_find_expectation + + -- Benjamin Wheeler Thu, 08 May 2025 08:32:42 -0400 + +linux-oracle (5.4.0-1143.153) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1143.153 -proposed tracker (LP: #2106913) + + [ Ubuntu: 5.4.0-215.235 ] + + * focal/linux: 5.4.0-215.235 -proposed tracker (LP: #2106919) + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + * CVE-2023-52664 + - net: atlantic: eliminate double free in error handling logic + * CVE-2024-26689 + - ceph: prevent use-after-free in encode_cap_msg() + * CVE-2023-52927 + - netfilter: allow exp not to be removed in nf_ct_find_expectation + + -- Philip Cox Tue, 22 Apr 2025 12:16:04 -0400 + +linux-oracle (5.4.0-1142.152) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1142.152 -proposed tracker (LP: #2102630) + + [ Ubuntu: 5.4.0-214.234 ] + + * focal/linux: 5.4.0-214.234 -proposed tracker (LP: #2102635) + * CVE-2024-50256 + - netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6() + * CVE-2025-21702 + - pfifo_tail_enqueue: Drop new packet when sch->limit == 0 + * CVE-2025-21703 + - netem: Update sch->q.qlen before qdisc_tree_reduce_backlog() + * CVE-2024-26915 + - drm/amdgpu: Reset IH OVERFLOW_CLEAR bit + * CVE-2025-21700 + - net: sched: Disallow replacing of child qdisc from one parent to another + * CVE-2024-46826 + - ELF: fix kernel.randomize_va_space double read + * CVE-2024-56651 + - can: hi311x: hi3110_can_ist(): fix potential use-after-free + * CVE-2024-53237 + - driver core: Introduce device_find_any_child() helper + - Bluetooth: fix use-after-free in device_for_each_child() + * CVE-2024-35958 + - net: ena: Fix incorrect descriptor free behavior + * CVE-2024-49974 + - NFSD: Limit the number of concurrent async COPY operations + * CVE-2021-47119 + - ext4: fix memory leak in ext4_fill_super + * CVE-2024-56658 + - net: defer final 'struct net' free in netns dismantle + * CVE-2024-35864 + - smb: client: fix potential UAF in smb2_is_valid_lease_break() + * CVE-2024-35864/CVE-2024-26928 + - smb: client: fix potential UAF in cifs_debug_files_proc_show() + + -- Philip Cox Thu, 27 Mar 2025 12:27:52 -0400 + +linux-oracle (5.4.0-1141.151) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1141.151 -proposed tracker (LP: #2102362) + + [ Ubuntu: 5.4.0-212.232 ] + + * focal/linux: 5.4.0-212.232 -proposed tracker (LP: #2102367) + * CVE-2024-56658 + - net: defer final 'struct net' free in netns dismantle + * CVE-2024-35864 + - smb: client: fix potential UAF in smb2_is_valid_lease_break() + * CVE-2024-35864/CVE-2024-26928 + - smb: client: fix potential UAF in cifs_debug_files_proc_show() + + -- Philip Cox Tue, 25 Mar 2025 07:07:25 -0400 + +linux-oracle (5.4.0-1140.150) focal; urgency=medium + + -- Philip Cox Fri, 21 Mar 2025 11:18:39 -0400 + +linux-oracle (5.4.0-1140.149) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1140.149 -proposed tracker (LP: #2101991) + + [ Ubuntu: 5.4.0-211.231 ] + + * focal/linux: 5.4.0-211.231 -proposed tracker (LP: #2101996) + * cve-2018-5803 kernel panic (LP: #2101091) + - SAUCE: sctp: sysctl: pass right argument to container_of + + -- Philip Cox Fri, 14 Mar 2025 09:22:44 -0400 + +linux-oracle (5.4.0-1139.148) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1139.148 -proposed tracker (LP: #2098348) + + [ Ubuntu: 5.4.0-210.230 ] + + * focal/linux: 5.4.0-210.230 -proposed tracker (LP: #2098353) + * Focal update: v5.4.290 upstream stable release (LP: #2098439) + - jbd2: flush filesystem device before updating tail sequence + - dm array: fix releasing a faulty array block twice in dm_array_cursor_end + - dm array: fix unreleased btree blocks on closing a faulty array cursor + - dm array: fix cursor index when skipping across block boundaries + - ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe() + - net: 802: LLC+SNAP OID:PID lookup on start of skb data + - tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog + - tcp/dccp: allow a connection when sk_max_ack_backlog is zero + - net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute + - tls: Fix tls_sw_sendmsg error handling + - dm thin: make get_first_thin use rcu-safe list first function + - sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy + - sctp: sysctl: auth_enable: avoid using current->nsproxy + - drm/amd/display: Add check for granularity in dml ceil/floor helpers + - ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[] + - ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[] + - drm/amd/display: increase MAX_SURFACES to the value supported by hw + - USB: serial: option: add MeiG Smart SRM815 + - USB: serial: option: add Neoway N723-EA support + - staging: iio: ad9834: Correct phase range check + - staging: iio: ad9832: Correct phase range check + - usb-storage: Add max sectors quirk for Nokia 208 + - USB: serial: cp210x: add Phoenix Contact UPS Device + - usb: gadget: u_serial: Disable ep before setting port to null to fix the + crash caused by port being null + - USB: usblp: return error when setting unsupported protocol + - USB: core: Disable LPM only for non-suspended ports + - usb: fix reference leak in usb_new_device() + - usb: gadget: f_fs: Remove WARN_ON in functionfs_bind + - iio: pressure: zpa2326: fix information leak in triggered buffer + - iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered + buffer + - iio: light: vcnl4035: fix information leak in triggered buffer + - iio: imu: kmx61: fix information leak in triggered buffer + - iio: adc: ti-ads8688: fix information leak in triggered buffer + - iio: gyro: fxas21002c: Fix missing data update in trigger handler + - iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep() + - iio: adc: at91: call input_free_device() on allocated iio_dev + - iio: inkern: call iio_device_put() only on mapped devices + - arm64: dts: rockchip: fix defines in pd_vio node for rk3399 + - arm64: dts: rockchip: fix pd_tcpc0 and pd_tcpc1 node position on rk3399 + - arm64: dts: rockchip: add #power-domain-cells to power domain nodes + - arm64: dts: rockchip: add hevc power domain clock to rk3328 + - phy: core: fix code style in devm_of_phy_provider_unregister + - phy: core: Fix that API devm_of_phy_provider_unregister() fails to + unregister the phy provider + - ocfs2: correct return value of ocfs2_local_free_info() + - ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv + - sctp: sysctl: rto_min/max: avoid using current->nsproxy + - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field() + - net: net_namespace: Optimize the code + - net: add exit_batch_rtnl() method + - gtp: use exit_batch_rtnl() method + - gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp(). + - gtp: Destroy device along with udp socket's netns dismantle. + - nfp: bpf: prevent integer overflow in nfp_bpf_event_output() + - drm/v3d: Ensure job pointer is set to NULL after job completion + - i2c: mux: demux-pinctrl: check initial mux selection, too + - mac802154: check local interfaces before deleting sdata list + - hfs: Sanity check the root record + - kheaders: Ignore silly-rename files + - poll_wait: add mb() to fix theoretical race between waitqueue_active() and + .poll() + - nvmet: propagate npwg topology + - net: ethernet: xgbe: re-add aneg to supported features in PHY quirks + - fs/proc: fix softlockup in __read_vmcore (part 2) + - irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly + - hrtimers: Handle CPU state correctly on hotplug + - ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev() + - scsi: sg: Fix slab-use-after-free read in sg_release() + - net: fix data-races around sk->sk_forward_alloc + - ASoC: wm8994: Add depends on MFD core + - scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request + - irqchip/sunxi-nmi: Add missing SKIP_WAKE flag + - gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag + - m68k: Update ->thread.esp0 before calling syscall_trace() in ret_from_signal + - m68k: Add missing mmap_read_lock() to sys_cacheflush() + - signal/m68k: Use force_sigsegv(SIGSEGV) in fpsp040_die + - net: xen-netback: hash.c: Use built-in RCU list checking + - net/xen-netback: prevent UAF in xenvif_flush_hash() + - vfio/platform: check the bounds of read/write syscalls + - ext4: avoid ext4_error()'s caused by ENOMEM in the truncate path + - ext4: fix slab-use-after-free in ext4_split_extent_at() + - USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb() + - Revert "usb: gadget: u_serial: Disable ep before setting port to null to fix + the crash caused by port being null" + - Input: atkbd - map F23 key to support default copilot shortcut + - Input: xpad - add unofficial Xbox 360 wireless receiver clone + - Input: xpad - add support for wooting two he (arm) + - drm/v3d: Assign job pointer to NULL before signaling the fence + - xhci: use pm_ptr() instead of #ifdef for CONFIG_PM conditionals + - Partial revert of xhci: use pm_ptr() instead #ifdef for CONFIG_PM + conditionals + - Linux 5.4.290 + * CVE-2021-47219 + - scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs() + * CVE-2024-49925 + - fbdev: efifb: Register sysfs groups through driver core + * CVE-2024-56614 + - xsk: fix OOB map writes when deleting elements + * net: stmmac: kernel continually prints wol unbalance irq warning + (LP: #2095376) + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + * CVE-2024-44938 + - jfs: Fix shift-out-of-bounds in dbDiscardAG + * CVE-2024-43900 + - media: xc2028: avoid use-after-free in load_firmware_cb() + * Focal update: v5.4.289 upstream stable release (LP: #2095437) + - usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with + iommu enabled + - PCI/AER: Disable AER service on suspend + - ALSA: usb: Fix UBSAN warning in parse_audio_unit() + - PCI: Add ACS quirk for Broadcom BCM5760X NIC + - i2c: pnx: Fix timeout in wait functions + - drm/i915: Fix memory leak by correcting cache object name in error handler + - erofs: fix order >= MAX_ORDER warning due to crafted negative i_size + - erofs: fix incorrect symlink detection in fast symlink + - net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll + - ionic: use ee->offset when returning sprom data + - net: hinic: Fix cleanup in create_rxqs/txqs() + - net: ethernet: bgmac-platform: fix an OF node reference leak + - netfilter: ipset: Fix for recursive locking warning + - mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk + - chelsio/chtls: prevent potential integer overflow on 32bit + - i2c: riic: Always round-up when calculating bus period + - efivarfs: Fix error on non-existent file + - USB: serial: option: add TCL IK512 MBIM & ECM + - USB: serial: option: add MeiG Smart SLM770A + - USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready + - USB: serial: option: add MediaTek T7XX compositions + - USB: serial: option: add Telit FE910C04 rmnet compositions + - sh: clk: Fix clk_enable() to return 0 on NULL clk + - zram: refuse to use zero sized block device as backing device + - btrfs: tree-checker: reject inline extent items with 0 ref count + - NFS/pnfs: Fix a live lock between recalled layouts and layoutget + - of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one() + - nilfs2: prevent use of deleted inode + - udmabuf: also check for F_SEAL_FUTURE_WRITE + - of: Fix error path in of_parse_phandle_with_args_map() + - of: Fix refcount leakage for OF node returned by __of_get_dma_parent() + - media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg + - bpf: Check negative offsets in __bpf_skb_min_len() + - nfsd: restore callback functionality for NFSv4.0 + - mtd: diskonchip: Cast an operand to prevent potential overflow + - phy: core: Fix an OF node refcount leakage in _of_phy_get() + - phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup() + - phy: core: Fix that API devm_phy_put() fails to release the phy + - phy: core: Fix that API devm_phy_destroy() fails to destroy the phy + - dmaengine: mv_xor: fix child node refcount handling in early exit + - dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset + - mtd: rawnand: fix double free in atmel_pmecc_create_user() + - tracing/kprobe: Make trace_kprobe's module callback called after jump_label + update + - scsi: qla1280: Fix hw revision numbering for ISP1020/1040 + - scsi: megaraid_sas: Fix for a potential deadlock + - regmap: Use correct format specifier for logging range errors + - platform/x86: asus-nb-wmi: Ignore unknown event 0xCF + - scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load + time + - virtio-blk: don't keep queue frozen during system suspend + - epoll: Add synchronous wakeup support for ep_poll_callback + - MIPS: Probe toolchain support of -msym32 + - ipv6: use skb_expand_head in ip6_finish_output2 + - ipv6: use skb_expand_head in ip6_xmit + - ipv6: fix possible UAF in ip6_finish_output2() + - bpf: fix recursive lock when verdict program return SK_PASS + - tracing: Constify string literal data member in struct trace_event_call + - btrfs: avoid monopolizing a core when activating a swap file + - ipv6: prevent possible UAF in ip6_xmit() + - selinux: ignore unknown extended permissions + - Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet + - IB/mlx5: Introduce and use mlx5_core_is_vf() + - net/mlx5: Make API mlx5_core_is_ecpf accept const pointer + - RDMA/mlx5: Enforce same type port association for multiport RoCE + - RDMA/bnxt_re: Add check for path mtu in modify_qp + - RDMA/bnxt_re: Fix reporting hw_ver in query_device + - RDMA/bnxt_re: Fix max_qp_wrs reported + - drm: bridge: adv7511: Enable SPDIF DAI + - drm/bridge: adv7511_audio: Update Audio InfoFrame properly + - netrom: check buffer length before accessing it + - netfilter: Replace zero-length array with flexible-array member + - netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext + - net: llc: reset skb->transport_header + - ALSA: usb-audio: US16x08: Initialize array before use + - af_packet: fix vlan_get_tci() vs MSG_PEEK + - af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK + - ila: serialize calls to nf_register_net_hooks() + - wifi: mac80211: wake the queues in case of failure in resume + - sound: usb: format: don't warn that raw DSD is unsupported + - bpf: fix potential error return + - net: usb: qmi_wwan: add Telit FE910C04 compositions + - irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base + - ARC: build: Try to guess GCC variant of cross compiler + - modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host + - modpost: fix the missed iteration for the max bit in do_input() + - RDMA/uverbs: Prevent integer overflow issue + - pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking + - sky2: Add device ID 11ab:4373 for Marvell 88E8075 + - net/sctp: Prevent autoclose integer overflow in sctp_association_init() + - drm: adv7511: Drop dsi single lane support + - mm: vmscan: account for free pages to prevent infinite Loop in + throttle_direct_reclaim() + - ftrace: use preempt_enable/disable notrace macros to avoid double fault + - Linux 5.4.289 + * Focal update: v5.4.289 upstream stable release (LP: #2095437) // + CVE-2024-38588 + - ftrace: Fix possible use-after-free issue in ftrace_location() + * Focal update: v5.4.288 upstream stable release (LP: #2095199) + - usb: host: max3421-hcd: Correctly abort a USB request. + - ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys() + - usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature + - usb: ehci-hcd: fix call balance of clocks handling routines + - usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to + accessing null pointer + - xfs: don't drop errno values when we fail to ficlone the entire range + - bpf, sockmap: Fix update element with same + - batman-adv: Do not send uninitialized TT changes + - batman-adv: Remove uninitialized data in full table TT response + - batman-adv: Do not let TT changes list grows indefinitely + - tipc: fix NULL deref in cleanup_bearer() + - net: lapb: increase LAPB_HEADER_LEN + - ACPI: resource: Fix memory resource type union access + - qca_spi: Fix clock speed for multiple QCA7000 + - qca_spi: Make driver probing reliable + - net/sched: netem: account for backlog updates from child qdisc + - ACPICA: events/evxfregn: don't release the ContextMutex that was never + acquired + - blk-iocost: clamp inuse and skip noops in __propagate_weights() + - blk-iocost: fix weight updates of inner active iocgs + - blk-iocost: Avoid using clamp() on inuse in __propagate_weights() + - KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status + - tracing/kprobes: Skip symbol counting logic for module symbols in + create_local_trace_kprobe() + - xen/netfront: fix crash when removing device + - ALSA: usb-audio: Fix a DMA to stack memory bug + - Linux 5.4.288 + * Focal update: v5.4.287 upstream stable release (LP: #2095145) + - netlink: terminate outstanding dump on socket close + - net/mlx5: fs, lock FTE when checking if active + - net/mlx5e: kTLS, Fix incorrect page refcounting + - ocfs2: uncache inode which has failed entering the group + - KVM: VMX: Bury Intel PT virtualization (guest/host mode) behind + CONFIG_BROKEN + - nilfs2: fix null-ptr-deref in block_touch_buffer tracepoint + - ocfs2: fix UBSAN warning in ocfs2_verify_volume() + - nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint + - Revert "mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K" + - media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set + - kbuild: Use uname for LINUX_COMPILE_HOST detection + - mm: revert "mm: shmem: fix data-race in shmem_getattr()" + - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet + - mac80211: fix user-power when emulating chanctx + - selftests/watchdog-test: Fix system accidentally reset after watchdog-test + - ALSA: hda/realtek: Add subwoofer quirk for Infinix ZERO BOOK 13 + - x86/amd_nb: Fix compile-testing without CONFIG_AMD_NB + - net: usb: qmi_wwan: add Quectel RG650V + - soc: qcom: Add check devm_kasprintf() returned value + - regulator: rk808: Add apply_bit for BUCK3 on RK809 + - ASoC: stm: Prevent potential division by zero in stm32_sai_mclk_round_rate() + - ASoC: stm: Prevent potential division by zero in stm32_sai_get_clk_div() + - proc/softirqs: replace seq_printf with seq_put_decimal_ull_width + - ipmr: Fix access to mfc_cache_list without lock held + - cifs: Fix buffer overflow when parsing NFS reparse points + - NFSD: Force all NFSv4.2 COPY requests to be synchronous + - nvme: fix metadata handling in nvme-passthrough + - mips: asm: fix warning when disabling MIPS_FP_SUPPORT + - initramfs: avoid filename buffer overrun + - nvme-pci: fix freeing of the HMB descriptor table + - m68k: mvme147: Fix SCSI controller IRQ numbers + - m68k: mvme16x: Add and use "mvme16x.h" + - m68k: mvme147: Reinstate early console + - acpi/arm64: Adjust error handling procedure in gtdt_parse_timer_block() + - s390/syscalls: Avoid creation of arch/arch/ directory + - hfsplus: don't query the device logical block size multiple times + - firmware: google: Unregister driver_info on failure and exit in gsmi + - firmware: google: Unregister driver_info on failure + - EDAC/bluefield: Fix potential integer overflow + - EDAC/fsl_ddr: Fix bad bit shift operations + - crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return + -EBUSY + - crypto: cavium - Fix the if condition to exit loop after timeout + - crypto: bcm - add error check in the ahash_hmac_init function + - crypto: cavium - Fix an error handling path in cpt_ucode_load_fw() + - time: Fix references to _msecs_to_jiffies() handling of values + - soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq() + - soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get() + - mmc: mmc_spi: drop buggy snprintf() + - efi/tpm: Pass correct address to memblock_reserve + - tpm: fix signed/unsigned bug when checking event logs + - ARM: dts: cubieboard4: Fix DCDC5 regulator constraints + - regmap: irq: Set lockdep class for hierarchical IRQ domains + - firmware: arm_scpi: Check the DVFS OPP count returned by the firmware + - drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused + - wifi: ath9k: add range check for conn_rsp_epid in htc_connect_service() + - drm/omap: Fix locking in omap_gem_new_dmabuf() + - wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq() + - wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq() + - drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq() + - dt-bindings: vendor-prefixes: Add NeoFidelity, Inc + - ASoC: fsl_micfil: Drop unnecessary register read + - ASoC: fsl_micfil: do not define SHIFT/MASK for single bits + - ASoC: fsl_micfil: use GENMASK to define register bit fields + - ASoC: fsl_micfil: fix regmap_write_bits usage + - bpf: Fix the xdp_adjust_tail sample prog issue + - wifi: mwifiex: Fix memcpy() field-spanning write warning in + mwifiex_config_scan() + - drm/panfrost: Remove unused id_mask from struct panfrost_model + - drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq() + - drm/etnaviv: dump: fix sparse warnings + - drm/etnaviv: fix power register offset on GC300 + - drm/etnaviv: hold GPU lock across perfmon sampling + - bpf, sockmap: Several fixes to bpf_msg_push_data + - bpf, sockmap: Several fixes to bpf_msg_pop_data + - bpf, sockmap: Fix sk_msg_reset_curr + - selftests: net: really check for bg process completion + - net: rfkill: gpio: Add check for clk_enable() + - ALSA: us122l: Use snd_card_free_when_closed() at disconnection + - ALSA: caiaq: Use snd_card_free_when_closed() at disconnection + - ALSA: 6fire: Release resources at card release + - netpoll: Use rcu_access_pointer() in netpoll_poll_lock + - trace/trace_event_perf: remove duplicate samples on the first tracepoint + event + - powerpc/vdso: Flag VDSO64 entry points as functions + - mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race + - mfd: da9052-spi: Change read-mask to write-mask + - mfd: intel_soc_pmic_bxtwc: Use dev_err_probe() + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device + - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices + - cpufreq: loongson2: Unregister platform_driver on failure + - mtd: rawnand: atmel: Fix possible memory leak + - RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey + - mfd: rt5033: Fix missing regmap_del_irq_chip() + - scsi: bfa: Fix use-after-free in bfad_im_module_exit() + - scsi: fusion: Remove unused variable 'rc' + - scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb() + - scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb() + - ocfs2: fix uninitialized value in ocfs2_file_read_iter() + - powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static + - fbdev/sh7760fb: Alloc DMA memory from hardware device + - fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem() + - dt-bindings: clock: adi,axi-clkgen: convert old binding to yaml format + - dt-bindings: clock: axi-clkgen: include AXI clk + - clk: axi-clkgen: use devm_platform_ioremap_resource() short-hand + - clk: clk-axi-clkgen: make sure to enable the AXI bus clock + - perf cs-etm: Don't flush when packet_queue fills up + - perf probe: Correct demangled symbols in C++ program + - PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads + - PCI: cpqphp: Fix PCIBIOS_* return value confusion + - m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x + - m68k: coldfire/device.c: only build FEC when HW macros are defined + - perf trace: Do not lose last events in a race + - perf trace: Avoid garbage when not printing a syscall's arguments + - rpmsg: glink: Add TX_DATA_CONT command while sending + - rpmsg: glink: Send READ_NOTIFY command in FIFO full case + - rpmsg: glink: Fix GLINK command prefix + - rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length + - NFSD: Prevent NULL dereference in nfsd4_process_cb_update() + - NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir() + - NFSD: Fix nfsd4_shutdown_copy() + - vfio/pci: Properly hide first-in-list PCIe extended capability + - power: supply: core: Remove might_sleep() from power_supply_put() + - net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device + - tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets + - net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL + configuration + - marvell: pxa168_eth: fix call balance of pep->clk handling routines + - net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken + - ipmr: convert /proc handlers to rcu_read_lock() + - ipmr: fix tables suspicious RCU usage + - usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read() + - usb: yurex: make waiting on yurex_write interruptible + - USB: chaoskey: fail open after removal + - USB: chaoskey: Fix possible deadlock chaoskey_list_lock + - misc: apds990x: Fix missing pm_runtime_disable() + - staging: greybus: uart: clean up TIOCGSERIAL + - apparmor: fix 'Do simple duplicate message elimination' + - usb: ehci-spear: fix call balance of sehci clk handling routines + - cgroup: Make operations on the cgroup root_list RCU safe + - cgroup: Move rcu_head up near the top of cgroup_root + - soc: qcom: socinfo: fix revision check in qcom_socinfo_probe() + - ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox + devices + - ext4: supress data-race warnings in ext4_free_inodes_{count,set}() + - ext4: fix FS_IOC_GETFSMAP handling + - jfs: xattr: check invalid xattr size more strictly + - ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata() + - PCI: Fix use-after-free of slot->bus on hot remove + - comedi: Flush partial mappings in error case + - tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler + - Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}() + - Revert "usb: gadget: composite: fix OS descriptors w_value logic" + - serial: sh-sci: Clean sci_ports[0] after at earlycon exit + - Revert "serial: sh-sci: Clean sci_ports[0] after at earlycon exit" + - spi: Fix acpi deferred irq probe + - ubi: wl: Put source PEB into correct list if trying locking LEB failed + - um: ubd: Do not use drvdata in release + - um: net: Do not use drvdata in release + - serial: 8250: omap: Move pm_runtime_get_sync + - um: vector: Do not use drvdata in release + - sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled + - block: fix ordering between checking BLK_MQ_S_STOPPED request adding + - HID: wacom: Interpret tilt data from Intuos Pro BT as signed values + - media: wl128x: Fix atomicity violation in fmc_send_cmd() + - ALSA: hda/realtek: Update ALC225 depop procedure + - ALSA: hda/realtek: Set PCBeep to default value for ALC274 + - ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max + - ALSA: hda/realtek: Apply quirk for Medion E15433 + - usb: dwc3: gadget: Fix checking for number of TRBs left + - lib: string_helpers: silence snprintf() output truncation warning + - NFSD: Prevent a potential integer overflow + - SUNRPC: make sure cache entry active before cache_show + - rpmsg: glink: Propagate TX failures in intentless mode as well + - um: Fix potential integer overflow during physmem setup + - um: Fix the return value of elf_core_copy_task_fpregs + - um/sysrq: remove needless variable sp + - um: add show_stack_loglvl() + - um: Clean up stacktrace dump + - um: Always dump trace for specified task in show_stack + - NFSv4.0: Fix a use-after-free problem in the asynchronous open() + - rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq() + - rtc: abx80x: Fix WDT bit position of the status register + - rtc: check if __rtc_read_time was successful in rtc_timer_do_work() + - ubifs: Correct the total block count by deducting journal reservation + - ubi: fastmap: Fix duplicate slab cache names while attaching + - ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit + - jffs2: fix use of uninitialized variable + - block: return unsigned int from bdev_io_min + - 9p/xen: fix init sequence + - 9p/xen: fix release of IRQ + - rtc: ab-eoz9: don't fail temperature reads on undervoltage notification + - modpost: remove incorrect code in do_eisa_entry() + - SUNRPC: correct error code comment in xs_tcp_setup_socket() + - SUNRPC: Replace internal use of SOCKWQ_ASYNC_NOSPACE + - sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport + - sh: intc: Fix use-after-free bug in register_intc_controller() + - ASoC: fsl_micfil: fix the naming style for mask definition + - quota: flush quota_release_work upon quota writeback + - btrfs: ref-verify: fix use-after-free after invalid ref action + - media: i2c: tc358743: Fix crash in the probe error path when using polling + - media: ts2020: fix null-ptr-deref in ts2020_probe() + - media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled + - media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate() + - media: platform: allegro-dvt: Fix possible memory leak in + allocate_buffers_internal() + - ovl: Filter invalid inodes with missing lookup function + - ftrace: Fix regression with module command in stack_trace_filter + - clk: qcom: gcc-qcs404: fix initial rate of GPLL3 + - ad7780: fix division by zero in ad7780_write_raw() + - util_macros.h: fix/rework find_closest() macros + - i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs() + - dm thin: Add missing destroy_work_on_stack() + - nfsd: make sure exp active before svc_export_show + - nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur + - drm/etnaviv: flush shader L1 cache after user commandstream + - iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call + - watchdog: mediatek: Make sure system reset gets asserted in + mtk_wdt_restart() + - can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL + - can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics + - ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init() + - netfilter: x_tables: fix LED ID check in led_tg_check() + - net/sched: tbf: correct backlog statistic for GSO packets + - can: j1939: j1939_session_new(): fix skb reference counting + - net/ipv6: release expired exception dst cached in socket + - dccp: Fix memory leak in dccp_feat_change_recv + - tipc: add reference counter to bearer + - tipc: enable creating a "preliminary" node + - tipc: add new AEAD key structure for user API + - tipc: Fix use-after-free of kernel socket in cleanup_bearer(). + - net/qed: allow old cards not supporting "num_images" to work + - igb: Fix potential invalid memory access in igb_init_module() + - netfilter: ipset: Hold module reference while requesting a module + - netfilter: nft_set_hash: skip duplicated elements pending gc run + - xen/xenbus: reference count registered modules + - xenbus/backend: Add memory pressure handler callback + - xenbus/backend: Protect xenbus callback with lock + - xen/xenbus: fix locking + - xen: Fix the issue of resource not being properly released in + xenbus_dev_probe() + - x86/asm: Reorder early variables + - crypto: x86/aegis128 - access 32-bit arguments as 32-bit + - gpio: grgpio: use a helper variable to store the address of ofdev->dev + - gpio: grgpio: Add NULL check in grgpio_probe + - drm/sti: Add __iomem for mixer_dbg_mxn's parameter + - tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg + - spi: mpc52xx: Add cancel_work_sync before module remove + - ocfs2: free inode when ocfs2_get_init_inode() fails + - bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie + - bpf: Fix exact match conditions in trie_get_next_key() + - HID: wacom: fix when get product name maybe null pointer + - tracing: Fix cmp_entries_dup() to respect sort() comparison rules + - ocfs2: update seq_file index in ocfs2_dlm_seq_next + - scsi: qla2xxx: Fix NVMe and NPIV connect issue + - scsi: qla2xxx: Supported speed displayed incorrectly for VPorts + - scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt + - nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry() + - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again + - dma-buf: fix dma_fence_array_signaled v4 + - regmap: detach regmap from dev on regmap_exit + - mmc: core: Further prevent card detect during shutdown + - s390/cpum_sf: Handle CPU hotplug remove during sampling + - media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera + - media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108 + - drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model + - drm/mcde: Enable module autoloading + - drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check() + - samples/bpf: Fix a resource leak + - net: fec_mpc52xx_phy: Use %pa to format resource_size_t + - net: ethernet: fs_enet: Use %pa to format resource_size_t + - net/sched: cbs: Fix integer overflow in cbs_set_port_rate() + - af_packet: avoid erroring out after sock_init_data() in packet_create() + - Bluetooth: L2CAP: do not leave dangling sk pointer on error in + l2cap_sock_create() + - net: af_can: do not leave a dangling sk pointer in can_create() + - net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() + - net: inet: do not leave a dangling sk pointer in inet_create() + - net: inet6: do not leave a dangling sk pointer in inet6_create() + - wifi: ath5k: add PCI ID for SX76X + - wifi: ath5k: add PCI ID for Arcadyan devices + - jfs: array-index-out-of-bounds fix in dtReadFirst + - jfs: fix shift-out-of-bounds in dbSplit + - jfs: fix array-index-out-of-bounds in jfs_readdir + - jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree + - drm/amdgpu: set the right AMDGPU sg segment limitation + - wifi: ipw2x00: libipw_rx_any(): fix bad alignment + - wifi: brcmfmac: Fix oops due to NULL pointer dereference in + brcmf_sdiod_sglist_rw() + - Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables + - ASoC: hdmi-codec: reorder channel allocation list + - rocker: fix link status detection in rocker_carrier_init() + - net/neighbor: clear error in case strict check is not set + - netpoll: Use rcu_access_pointer() in __netpoll_setup + - tracing: Use atomic64_inc_return() in trace_clock_counter() + - leds: class: Protect brightness_show() with led_cdev->led_access mutex + - scsi: st: Don't modify unknown block number in MTIOCGET + - scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset + - pinctrl: qcom-pmic-gpio: add support for PM8937 + - nvdimm: rectify the illogical code within nd_dax_probe() + - f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode. + - PCI: Add 'reset_subordinate' to reset hierarchy below bridge + - PCI: Add ACS quirk for Wangxun FF5xxx NICs + - i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to + avoid deadlock + - usb: chipidea: udc: handle USB Error Interrupt if IOC not set + - powerpc/prom_init: Fixup missing powermac #size-cells + - misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle + - xdp: Simplify devmap cleanup + - bpf: fix OOB devmap writes when deleting elements + - Revert "unicode: Don't special case ignorable code points" + - perf/x86/intel/pt: Fix buffer full but size is 0 case + - KVM: arm64: vgic-its: Add a data length check in vgic_its_save_* + - KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device + - KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE + - jffs2: Prevent rtime decompress memory corruption + - jffs2: Fix rtime decompressor + - ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume" + - modpost: Add .irqentry.text to OTHER_SECTIONS + - Revert "drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()" + - PCI: rockchip-ep: Fix address translation unit programming + - ALSA: usb-audio: Fix out of bounds reads when finding clock sources + - bpf, xdp: Update devmap comments to reflect napi/rcu usage + - Linux 5.4.287 + * CVE-2024-23848 + - media: cec: abort if the current transmit was canceled + - media: cec: core: avoid recursive cec_claim_log_addrs + - media: cec: core: avoid confusing "transmit timed out" message + + [ Ubuntu: 5.4.0-208.228 ] + + * CVE-2025-0927 + - SAUCE: fs: hfs/hfsplus: add key_len boundary check to hfs_bnode_read_key + + -- Philip Cox Thu, 20 Feb 2025 08:46:16 -0500 + +linux-oracle (5.4.0-1138.147) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1138.147 -proposed tracker (LP: #2093780) + + * Add list of source files to linux-buildinfo (LP: #2086606) + - [Packaging] Add dwarfdump package to Build-Depends + + * Focal update: v5.4.285 upstream stable release (LP: #2089233) + - [Config] Disable SND_MESON_CARD_UTILS + + [ Ubuntu: 5.4.0-207.227 ] + + * focal/linux: 5.4.0-207.227 -proposed tracker (LP: #2095347) + * Remove "ftrace: Fix possible use-after-free issue in ftrace_location()" bad + commit from focal (LP: #2095348) + - Revert "ftrace: Fix possible use-after-free issue in ftrace_location()" + + [ Ubuntu: 5.4.0-206.226 ] + + * focal/linux: 5.4.0-206.226 -proposed tracker (LP: #2093785) + * nouveau keeps showing `disp: ctrl 00000080` and crippling the system + (LP: #2078011) + - drm/nouveau/disp/gv100-: halt NV_PDISP_FE_RM_INTR_STAT_CTRL_DISP_ERROR + storms + - drm/nouveau/kms/gv100-: move window ownership setup into modesetting path + - drm/nouveau/kms/gv100-: avoid sending a core update until the first modeset + * CVE-2024-43863 + - drm/vmwgfx: Fix a deadlock in dma buf fence polling + * CVE-2024-40911 + - wifi: cfg80211: Lock wiphy in cfg80211_get_station + * CVE-2024-35896 + - netfilter: validate user input for expected length + - netfilter: complete validation of user input + * CVE-2023-52458 + - block: add check that partition length needs to be aligned with block size + * kernel:nft "Could not process rule: Device or resource busy" on unreferenced + chain (LP: #2089699) + - SAUCE: netfilter: nf_tables: Fix EBUSY on deleting unreferenced chain + * CVE-2024-35887 + - lockdep: Add preemption enabled/disabled assertion APIs + - timers: Don't block on ->expiry_lock for TIMER_IRQSAFE timers + - Documentation: Remove bogus claim about del_timer_sync() + - ARM: spear: Do not use timer namespace for timer_shutdown() function + - clocksource/drivers/arm_arch_timer: Do not use timer namespace for + timer_shutdown() function + - clocksource/drivers/sp804: Do not use timer namespace for timer_shutdown() + function + - timers: Get rid of del_singleshot_timer_sync() + - timers: Replace BUG_ON()s + - timers: Rename del_timer() to timer_delete() + - Documentation: Replace del_timer/del_timer_sync() + - timers: Silently ignore timers with a NULL function + - timers: Split [try_to_]del_timer[_sync]() to prepare for shutdown mode + - timers: Add shutdown mechanism to the internal functions + - timers: Provide timer_shutdown[_sync]() + - timers: Update the documentation to reflect on the new timer_shutdown() API + - ax25: fix use-after-free bugs caused by ax25_ds_del_timer + * CVE-2024-40965 + - clk: Add a devm variant of clk_rate_exclusive_get() + - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get() + - i2c: lpi2c: Avoid calling clk_get_rate during transfer + * CVE-2024-40982 + - ssb: Fix potential NULL pointer dereference in ssb_device_uevent() + * CVE-2024-41066 + - ibmvnic: Add tx check to prevent skb leak + * CVE-2024-42252 + - closures: Change BUG_ON() to WARN_ON() + * CVE-2024-46731 + - drm/amd/pm: fix the Out-of-bounds read warning + * Focal update: v5.4.286 upstream stable release (LP: #2089558) + - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire- + excavator + - arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328 + - arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards + - arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion + - ARM: dts: rockchip: fix rk3036 acodec node + - ARM: dts: rockchip: drop grf reference from rk3036 hdmi + - ARM: dts: rockchip: Fix the spi controller on rk3036 + - ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin + - enetc: simplify the return expression of enetc_vf_set_mac_addr() + - net: enetc: set MAC address to the VF net_device + - can: c_can: fix {rx,tx}_errors statistics + - media: stb0899_algo: initialize cfr before using it + - media: dvb_frontend: don't play tricks with underflow values + - media: adv7604: prevent underflow condition when reporting colorspace + - ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init() + - pwm: imx-tpm: Use correct MODULO value for EPWM mode + - drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported + - dm cache: correct the number of origin blocks to match the target length + - dm cache: optimize dirty bit checking with find_next_bit when resizing + - dm-unstriped: cast an operand to sector_t to prevent potential uint32_t + overflow + - mtd: rawnand: protect access to rawnand devices while in suspend + - spi: fix use-after-free of the add_lock mutex + - media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in + uvc_parse_format + - fs/proc: fix compile warning about variable 'vmcore_mmap_ops' + - USB: serial: qcserial: add support for Sierra Wireless EM86xx + - USB: serial: option: add Fibocom FG132 0x0112 composition + - USB: serial: option: add Quectel RG650V + - irqchip/gic-v3: Force propagation of the active state with a read-back + - ALSA: usb-audio: Support jack detection on Dell dock + - ALSA: usb-audio: Add quirks for Dell WD19 dock + - NFSD: Fix NFSv4's PUTPUBFH operation + - ALSA: usb-audio: Add endianness annotations + - 9p: Avoid creating multiple slab caches with the same name + - HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad + - bpf: use kvzmalloc to allocate BPF verifier environment + - sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML + - powerpc/powernv: Free name on error in opal_event_init() + - fs: Fix uninitialized value issue in from_kuid and from_kgid + - net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition + - md/raid10: improve code of mrdev in raid10_sync_request + - mm: clarify a confusing comment for remap_pfn_range() + - mm: fix ambiguous comments for better code readability + - mm/memory.c: make remap_pfn_range() reject unaligned addr + - mm: add remap_pfn_range_notrack + - 9p: fix slab cache name creation for real + - Linux 5.4.286 + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-47674 + - mm: avoid leaving partial pfn mappings around in error case + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-38588 + - ftrace: Fix possible use-after-free issue in ftrace_location() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50265 + - ocfs2: remove entry once instead of null-ptr-dereference in + ocfs2_xa_remove() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50267 + - USB: serial: io_edgeport: fix use after free in debug printk + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50269 + - usb: musb: sunxi: Fix accessing an released usb phy + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2021-47469 + - spi: Fix deadlock when adding SPI controllers on SPI buses + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50273 + - btrfs: reinitialize delayed ref list after deleting it from the list + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53066 + - nfs: Fix KMSAN warning in decode_getfattr_attrs() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50278 + - dm cache: fix potential out-of-bounds access on the first resume + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50279 + - dm cache: fix out-of-bounds access to the dirty bitset when resizing + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50282 + - drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50287 + - media: v4l2-tpg: prevent the risk of a division by zero + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50290 + - media: cx24116: prevent overflows on SNR calculus + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53061 + - media: s5p-jpeg: prevent buffer overflows + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-53063 + - media: dvbdev: prevent the risk of out of memory access + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50296 + - net: hns3: fix kernel crash when uninstalling driver + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50299 + - sctp: properly validate chunk size in sctp_sf_ootb() + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50301 + - security/keys: fix slab-out-of-bounds in key_task_permission + * Focal update: v5.4.286 upstream stable release (LP: #2089558) // + CVE-2024-50302 + - HID: core: zero-initialize the report buffer + * Add list of source files to linux-buildinfo (LP: #2086606) + - [Packaging] Sort build dependencies alphabetically + - [Packaging] Add list of used source files to buildinfo package + * Focal update: v5.4.285 upstream stable release (LP: #2089233) + - usbnet: ipheth: fix carrier detection in modes 1 and 4 + - net: ethernet: use ip_hdrlen() instead of bit shift + - net: phy: vitesse: repair vsc73xx autonegotiation + - scripts: kconfig: merge_config: config files: add a trailing newline + - arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399 + Puma + - ice: fix accounting for filters shared by multiple VSIs + - net/mlx5e: Add missing link modes to ptys2ethtool_map + - net: ftgmac100: Enable TX interrupt to avoid TX timeout + - soundwire: stream: Revert "soundwire: stream: fix programming slave ports + for non-continous port maps" + - selftests: breakpoints: Fix a typo of function name + - ASoC: allow module autoloading for table db1200_pids + - ALSA: hda/realtek - Fixed ALC256 headphone no sound + - ALSA: hda/realtek - FIxed ALC285 headphone no sound + - pinctrl: at91: make it work with current gpiolib + - microblaze: don't treat zero reserved memory regions as error + - net: ftgmac100: Ensure tx descriptor updates are visible + - wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room() + - ASoC: tda7419: fix module autoloading + - drm: komeda: Fix an issue related to normalized zpos + - spi: bcm63xx: Enable module autoloading + - x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency + - USB: serial: pl2303: add device id for Macrosilicon MS3020 + - ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe() + - wifi: ath9k: fix parameter check in ath9k_init_debug() + - wifi: ath9k: Remove error checks when creating debugfs entries + - fs: explicitly unregister per-superblock BDIs + - mount: warn only once about timestamp range expiration + - fs/namespace: fnic: Switch to use %ptTd + - mount: handle OOM on mnt_warn_timestamp_expiry + - can: j1939: use correct function name in comment + - netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire + - netfilter: nf_tables: reject element expiration with no timeout + - netfilter: nf_tables: reject expiration higher than timeout + - wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan() + - wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors + - mac80211: parse radiotap header when selecting Tx queue + - Bluetooth: btusb: Fix not handling ZPL/short-transfer + - net: tipc: avoid possible garbage value + - block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator() + - block, bfq: don't break merge chain in bfq_split_bfqq() + - spi: ppc4xx: handle irq_of_parse_and_map() errors + - spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ + - ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property + - ARM: versatile: fix OF node leak in CPUs prepare + - reset: berlin: fix OF node leak in probe() error path + - clocksource/drivers/qcom: Add missing iounmap() on errors in + msm_dt_timer_init() + - hwmon: (max16065) Fix overflows seen when writing limits + - mtd: slram: insert break after errors in parsing the map + - hwmon: (ntc_thermistor) fix module autoloading + - power: supply: axp20x_battery: allow disabling battery charging + - power: supply: axp20x_battery: Remove design from min and max voltage + - power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense + - fbdev: hpfb: Fix an error handling path in hpfb_dio_probe() + - mtd: powernv: Add check devm_kasprintf() returned value + - drm/stm: Fix an error handling path in stm_drm_platform_probe() + - drm/amdgpu: Replace one-element array with flexible-array member + - drm/amdgpu: properly handle vbios fake edid sizing + - drm/radeon: Replace one-element array with flexible-array member + - drm/radeon: properly handle vbios fake edid sizing + - drm/rockchip: vop: Allow 4096px width scaling + - drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode + - drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets + - drm/msm: Fix incorrect file name output in adreno_request_fw() + - drm/msm/a5xx: disable preemption in submits by default + - drm/msm/a5xx: properly clear preemption records on resume + - drm/msm/a5xx: fix races in preemption evaluation stage + - ipmi: docs: don't advertise deprecated sysfs entries + - drm/msm: fix %s null argument error + - drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind() + - xen: use correct end address of kernel for conflict checking + - xen/swiotlb: add alignment check for dma buffers + - selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c + - selftests/bpf: Fix compiling flow_dissector.c with musl-libc + - selftests/bpf: Fix compiling tcp_rtt.c with musl-libc + - selftests/bpf: Fix error compiling test_lru_map.c + - xz: cleanup CRC32 edits from 2018 + - kthread: add kthread_work tracepoints + - kthread: fix task state in kthread worker if being frozen + - ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard + - smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso + - ext4: avoid negative min_clusters in find_group_orlov() + - ext4: return error on ext4_find_inline_entry + - nilfs2: determine empty node blocks as corrupted + - bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit + - perf sched timehist: Fix missing free of session in perf_sched__timehist() + - perf sched timehist: Fixed timestamp error when unable to confirm event + sched_in time + - perf time-utils: Fix 32-bit nsec parsing + - clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228 + - PCI: xilinx-nwl: Fix register misspelling + - pinctrl: single: fix missing error code in pcs_probe() + - clk: ti: dra7-atl: Fix leak of of_nodes + - pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function + - watchdog: imx_sc_wdt: Don't disable WDT in suspend + - RDMA/hns: Optimize hem allocation performance + - riscv: Fix fp alignment bug in perf_callchain_user() + - f2fs: enhance to update i_mode and acl atomically in f2fs_setattr() + - f2fs: fix typo + - f2fs: fix to update i_ctime in __f2fs_setxattr() + - f2fs: remove unneeded check condition in __f2fs_setxattr() + - f2fs: reduce expensive checkpoint trigger frequency + - iio: adc: ad7606: fix oversampling gpio array + - iio: adc: ad7606: fix standby gpio state to match the documentation + - coresight: tmc: sg: Do not leak sg_table + - net: qrtr: Update packets cloning when broadcasting + - netfilter: ctnetlink: compile ctnetlink_label_size with + CONFIG_NF_CONNTRACK_EVENTS + - Remove *.orig pattern from .gitignore + - soc: versatile: integrator: fix OF node leak in probe() error path + - drm/amd/display: Round calculated vtotal + - USB: appledisplay: close race between probe and completion handler + - USB: misc: cypress_cy7c63: check for short transfer + - USB: class: CDC-ACM: fix race between get_serial and set_serial + - tty: rp2: Fix reset with non forgiving PCIe host bridges + - drbd: Fix atomicity violation in drbd_uuid_set_bm() + - drbd: Add NULL check for net_conf to prevent dereference in state validation + - ACPI: resource: Add another DMI match for the TongFang GMxXGxx + - wifi: rtw88: 8822c: Fix reported RX band width + - debugobjects: Fix conditions in fill_pool() + - f2fs: prevent possible int overflow in dir_block_index() + - f2fs: avoid potential int overflow in sanity_check_area_boundary() + - hwrng: mtk - Use devm_pm_runtime_enable + - fs: Fix file_set_fowner LSM hook inconsistencies + - nfs: fix memory leak in error path of nfs4_do_reclaim + - ASoC: meson: axg: extract sound card utils + - [Config] updateconfigs for SND_MESON_CARD_UTILS + - PCI: xilinx-nwl: Use irq_data_get_irq_chip_data() + - PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler + - soc: versatile: realview: fix memory leak during device remove + - soc: versatile: realview: fix soc_dev leak during device remove + - usb: yurex: Replace snprintf() with the safer scnprintf() variant + - USB: misc: yurex: fix race between read and write + - pps: remove usage of the deprecated ida_simple_xx() API + - pps: add an error check in parport_attach + - mm: only enforce minimum stack gap size if it's sensible + - i2c: aspeed: Update the stop sw state when the bus recovery occurs + - i2c: isch: Add missed 'else' + - usb: yurex: Fix inconsistent locking bug in yurex_read() + - mailbox: rockchip: fix a typo in module autoloading + - Minor fixes to the CAIF Transport drivers Kconfig file + - drivers: net: Fix Kconfig indentation, continued + - ieee802154: Fix build error + - net/mlx5: Added cond_resched() to crdump collection + - netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED + - net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq() + - Bluetooth: btmrvl_sdio: Refactor irq wakeup + - Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq() + - ipv4: ip_gre: Fix drops of small packets in ipgre_xmit + - ALSA: hda/realtek: Fix the push button function for the ALC257 + - ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs + - ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin + - wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats() + - ice: Adjust over allocation of memory in ice_sched_add_root_node() and + ice_sched_add_node() + - net: hisilicon: hip04: fix OF node leak in probe() + - net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info() + - net: hisilicon: hns_mdio: fix OF node leak in probe() + - ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails + - ACPICA: Fix memory leak if acpi_ps_get_next_field() fails + - net: sched: consistently use rcu_replace_pointer() in taprio_change() + - wifi: rtw88: select WANT_DEV_COREDUMP + - ACPI: EC: Do not release locks during operation region accesses + - net: mvpp2: Increase size of queue_name buffer + - ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR). + - ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family + - tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process + - ACPICA: iasl: handle empty connection_node + - proc: add config & param to block forcing mem writes + - [Config] updateconfigs to select PROC_MEM_ALWAYS_FORCE + - nfp: Use IRQF_NO_AUTOEN flag in request_irq() + - signal: Replace BUG_ON()s + - ALSA: hdsp: Break infinite MIDI input flush loop + - x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments() + - power: reset: brcmstb: Do not go into infinite loop if reset fails + - ata: sata_sil: Rename sil_blacklist to sil_quirks + - jfs: UBSAN: shift-out-of-bounds in dbFindBits + - drm/printer: Allow NULL data in devcoredump printer + - scsi: aacraid: Rearrange order of struct aac_srb_unit + - drm/radeon/r100: Handle unknown family in r100_cp_init_microcode() + - of/irq: Refer to actual buffer size in of_irq_parse_one() + - ext4: ext4_search_dir should return a proper error + - spi: s3c64xx: fix timeout counters in flush_fifo + - selftests: breakpoints: use remaining time to check if suspend succeed + - selftests: vDSO: fix vDSO symbols lookup for powerpc64 + - i2c: xiic: Wait for TX empty to avoid missed TX NAKs + - firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp() + - spi: bcm63xx: Fix module autoloading + - perf/core: Fix small negative period being ignored + - parisc: Fix itlb miss handler for 64-bit programs + - drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS + - ALSA: core: add isascii() check to card ID generator + - ext4: propagate errors from ext4_find_extent() in ext4_insert_range() + - ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space() + - ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit() + - parisc: Fix 64-bit userspace syscall path + - parisc: Fix stack start for ADDR_NO_RANDOMIZE personality + - of/irq: Support #msi-cells=<0> in of_msi_get_domain + - mm: krealloc: consider spare memory for __GFP_ZERO + - ocfs2: fix the la space leak when unmounting an ocfs2 volume + - ocfs2: fix uninit-value in ocfs2_get_block() + - riscv: define ILLEGAL_POINTER_VALUE for 64bit + - clk: rockchip: fix error for unknown clocks + - media: sun4i_csi: Implement link validate for sun4i_csi subdev + - media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags + - iio: magnetometer: ak8975: Fix reading for ak099xx sensors + - tomoyo: fallback to realpath if symlink's pathname does not exist + - rtc: at91sam9: fix OF node leak in probe() error path + - Input: adp5589-keys - fix adp5589_gpio_get_value() + - ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[] + - ACPI: resource: Add Asus ExpertBook B2502CVA to + irq1_level_low_skip_override[] + - gpio: davinci: fix lazy disable + - i2c: qcom-geni: Let firmware specify irq trigger flags + - i2c: qcom-geni: Grow a dev pointer to simplify code + - i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq() + - arm64: Add Cortex-715 CPU part definition + - arm64: cputype: Add Neoverse-N3 definitions + - arm64: errata: Expand speculative SSBS workaround once more + - nfsd: use ktime_get_seconds() for timestamps + - nfsd: fix delegation_blocked() to block correctly for at least 30 seconds + - clk: qcom: rpmh: Simplify clk_rpmh_bcm_send_cmd() + - clk: qcom: clk-rpmh: Fix overflow in BCM vote + - r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun" + - ACPI: battery: Simplify battery hook locking + - ext4: fix inode tree inconsistency caused by ENOMEM + - net: ethernet: cortina: Drop TSO support + - tracing: Remove precision vsnprintf() check from print event + - drm/crtc: fix uninitialized variable use even harder + - tracing: Have saved_cmdlines arrays all in one allocation + - virtio_console: fix misc probe bugs + - Input: synaptics-rmi4 - fix UAF of IRQ domain on driver removal + - bpf: Check percpu map value size first + - s390/facility: Disable compile time optimization for decompressor code + - s390/mm: Add cond_resched() to cmm_alloc/free_pages() + - ext4: nested locking for xattr inode + - s390/cpum_sf: Remove WARN_ON_ONCE statements + - ktest.pl: Avoid false positives with grub2 skip regex + - clk: bcm: bcm53573: fix OF node leak in init + - PCI: Add ACS quirk for Qualcomm SA8775P + - i2c: i801: Use a different adapter-name for IDF adapters + - PCI: Mark Creative Labs EMU20k2 INTx masking as broken + - media: videobuf2-core: clear memory related fields in + __vb2_plane_dmabuf_put() + - usb: chipidea: udc: enable suspend interrupt after usb reset + - usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the + Crashkernel Scenario + - tools/iio: Add memory allocation failure check for trigger_name + - driver core: bus: Return -EIO instead of 0 when show/store invalid bus + attribute + - ice: fix VLAN replay after reset + - SUNRPC: Fix integer overflow in decode_rc_list() + - tcp: fix to allow timestamp undo if no retransmits were sent + - tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe + - gpio: aspeed: Add the flush write to ensure the write complete. + - gpio: aspeed: Use devm_clk api to manage clock source + - net: ibm: emac: mal: fix wrong goto + - net: annotate lockless accesses to sk->sk_ack_backlog + - net: annotate lockless accesses to sk->sk_max_ack_backlog + - sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start + - locking/lockdep: Fix bad recursion pattern + - locking/lockdep: Rework lockdep_lock + - locking/lockdep: Avoid potential access of invalid memory in lock_class + - lockdep: fix deadlock issue between lockdep and rcu + - HID: plantronics: Workaround for an unexcepted opposite volume key + - Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant" + - usb: dwc3: core: Stop processing of pending events if controller is halted + - usb: xhci: Fix problem with xhci resume from suspend + - usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip + - hid: intel-ish-hid: Fix uninitialized variable 'rv' in + ish_fw_xfer_direct_dma + - arm64: probes: Fix simulate_ldr*_literal() + - tracing/kprobes: Return EADDRNOTAVAIL when func matches several symbols + - tracing/kprobes: Fix symbol counting logic by looking at modules as well + - PCI: Add function 0 DMA alias quirk for Glenfly Arise chip + - fat: fix uninitialized variable + - s390/sclp_vt220: Convert newlines to CRLF instead of LFCR + - KVM: s390: Change virtual to physical address access in diag 0x258 handler + - x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET + - drm/vmwgfx: Handle surface check failure correctly + - iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig + - iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig + - iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - iio: hid-sensors: Fix an error handling path in + _hid_sensor_set_report_latency() + - iio: light: opt3001: add missing full-scale range value + - iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig + - Bluetooth: Remove debugfs directory on module init failure + - Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001 + - xhci: Fix incorrect stream context type macro + - USB: serial: option: add support for Quectel EG916Q-GL + - USB: serial: option: add Telit FN920C04 MBIM compositions + - x86/resctrl: Annotate get_mem_config() functions as __init + - x86/apic: Always explicitly disarm TSC-deadline timer + - mac80211: Fix NULL ptr deref for injected rate info + - RDMA/bnxt_re: Fix incorrect AVID type in WQE structure + - ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin + - RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP + - ipv4: give an IPv4 dev to blackhole_netdev + - RDMA/bnxt_re: Return more meaningful error + - drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation + - macsec: don't increment counters for an unrelated SA + - net: ethernet: aeroflex: fix potential memory leak in + greth_start_xmit_gbit() + - genetlink: hold RCU in genlmsg_mcast() + - arm64:uprobe fix the uprobe SWBP_INSN in big-endian + - KVM: s390: gaccess: Check if guest address is in memslot + - jfs: Fix sanity check in dbMount + - net: usb: usbnet: fix name regression + - r8169: avoid unsolicited interrupts + - posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime() + - ALSA: hda/realtek: Update default depop procedure + - ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[] + - ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid + detection issue + - ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593 + - hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event + - selinux: improve error checking in sel_write_load() + - arm64/uprobes: change the uprobe_opcode_t typedef to fix the sparse warning + - cgroup: Fix potential overflow issue when checking max_depth + - wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys + - mac80211: do drv_reconfig_complete() before restarting all + - mac80211: Add support to trigger sta disconnect on hardware restart + - wifi: iwlwifi: mvm: disconnect station vifs if recovery failed + - ASoC: cs42l51: Fix some error handling paths in cs42l51_probe() + - dt-bindings: gpu: Convert Samsung Image Rotator to dt-schema + - gtp: simplify error handling code in 'gtp_encap_enable()' + - gtp: allow -1 to be specified as file description from userspace + - net: support ip generic csum processing in skb_csum_hwoffload_help + - net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension + - drivers/misc: ti-st: Remove unneeded variable in st_tty_open + - firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state() + - net: amd: mvme147: Fix probe banner message + - misc: sgi-gru: Don't disable preemption in GRU driver + - usbip: tools: Fix detach_port() invalid port error path + - usb: phy: Fix API devm_usb_put_phy() can not release the phy + - xhci: Fix Link TRB DMA in command ring stopped completion event + - Revert "driver core: Fix uevent_show() vs driver detach race" + - riscv: Remove unused GENERATING_ASM_OFFSETS + - Revert "drm/mipi-dsi: Set the fwnode for mipi_dsi_device" + - vt: prevent kernel-infoleak in con_font_get() + - mac80211: always have ieee80211_sta_restart() + - mm: krealloc: Fix MTE false alarm in __do_krealloc + - Linux 5.4.285 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50228 + - mm: shmem: fix data-race in shmem_getattr() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50230 + - nilfs2: fix kernel bug due to missing clearing of checked flag + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50218 + - ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50229 + - nilfs2: fix potential deadlock with newly created symlinks + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50233 + - staging: iio: frequency: ad9832: fix division by zero in + ad9832_calc_freqreg() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50234 + - wifi: iwlegacy: Clear stale interrupts before resuming device + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50236 + - wifi: ath10k: Fix memory leak in management tx + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50237 + - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50251 + - netfilter: nft_payload: sanitize offset and length before calling + skb_checksum() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50262 + - bpf: Fix out-of-bounds write in trie_get_next_key() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-53059 + - wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50142 + - xfrm: validate new SA's prefixlen using SA family when sel.family is unset + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50116 + - nilfs2: fix kernel bug due to missing clearing of buffer delay flag + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50117 + - drm/amd: Guard against bad data for ATIF ACPI method + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50205 + - ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50127 + - net: sched: fix use-after-free in taprio_change() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50167 + - be2net: fix potential memory leak in be_xmit() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50168 + - net/sun3_82586: fix potential memory leak in sun3_82586_send_packet() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50131 + - tracing: Consider the NULL character when validating the event length + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50143 + - udf: fix uninit-value use in udf_get_fileshortad + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50134 + - drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real + VLA + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50194 + - arm64: probes: Fix uprobes for big-endian kernels + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50148 + - Bluetooth: bnep: fix wild-memory-access in proto_unregister + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50150 + - usb: typec: altmode should keep reference to parent + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50151 + - smb: client: fix OOBs when building SMB2_IOCTL request + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50171 + - net: systemport: fix potential memory leak in bcm_sysport_xmit() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50202 + - nilfs2: propagate directory read errors from nilfs_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50074 + - parport: Proper fix for array out-of-bounds access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50082 + - blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-40953 + - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50199 + - mm/swapfile: skip HugeTLB pages for unuse_vma + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50099 + - arm64: probes: Remove broken LDR (literal) uprobe support + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50195 + - posix-clock: Fix missing timespec64 check in pc_clock_settime() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50096 + - nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50024 + - net: Fix an unsafe loop on the list + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49878 + - resource: fix region_intersects() vs add_memory_driver_managed() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50033 + - slip: make slhc_remember() more robust against malicious packets + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50035 + - ppp: fix ppp_async_encode() illegal access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50039 + - net/sched: accept TCA_STAB only for root qdisc + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50040 + - igb: Do not bring the device up after non-fatal error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50044 + - Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50045 + - netfilter: br_netfilter: fix panic with metadata_dst skb + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-38544 + - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50180 + - fbdev: sisfb: Fix strbuf array overflow + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50184 + - virtio_pmem: Check device status before requesting flush + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50059 + - ntb: ntb_hw_switchtec: Fix use after free vulnerability in + switchtec_ntb_remove due to race condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50089 + - unicode: Don't special case ignorable code points + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49955 + - ACPI: battery: Fix possible crash when unregistering a battery hook + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49973 + - r8169: add tally counter fields added with RTL8125 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49975 + - uprobes: fix kernel info leak via "[uprobes]" vma + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49867 + - btrfs: wait for fixup workers before stopping cleaner kthread during umount + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49868 + - btrfs: fix a NULL pointer dereference when failed to start a new trasacntion + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49981 + - media: venus: fix use after free bug in venus_remove due to race condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49982 + - aoe: fix the potential use-after-free problem in more places + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49877 + - ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49957 + - ocfs2: fix null-ptr-deref when journal load failed. + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49965 + - ocfs2: remove unreasonable unlock in ocfs2_read_blocks + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49966 + - ocfs2: cancel dqi_sync_work before freeing oinfo + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49958 + - ocfs2: reserve space for inline xattr before attaching reflink tree + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49959 + - jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49879 + - drm: omapdrm: Add missing check for alloc_ordered_workqueue + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49882 + - ext4: fix double brelse() the buffer of the extents path + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49883 + - ext4: aovid use-after-free in ext4_ext_insert_extent() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49985 + - i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50006 + - ext4: fix i_data_sem unlock order in ext4_ind_migrate() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49892 + - drm/amd/display: Initialize get_bytes_per_element's default to 1 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49894 + - drm/amd/display: Fix index out of bounds in degamma hardware format + translation + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49896 + - drm/amd/display: Check stream before comparing them + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49900 + - jfs: Fix uninit-value access of new_ea in ea_buffer + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49902 + - jfs: check if leafidx greater than num leaves per dmap tree + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49903 + - jfs: Fix uaf in dbFreeBits + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49924 + - fbdev: pxafb: Fix possible use after free in pxafb_task() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50007 + - ALSA: asihpi: Fix potential OOB array access + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50008 + - wifi: mwifiex: Fix memcpy() field-spanning write warning in + mwifiex_cmd_802_11_scan_ext() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49995 + - tipc: guard against string buffer overrun + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49962 + - ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in + acpi_db_convert_to_package() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49938 + - wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47740 + - f2fs: Require FMODE_WRITE for atomic write ioctls + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49944 + - sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49948 + - net: add more sanity checks to qdisc_pkt_len_init() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49949 + - net: avoid potential underflow in qdisc_pkt_len_init() with UFO + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49997 + - net: ethernet: lantiq_etop: fix memory disclosure + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49952 + - netfilter: nf_tables: prevent nf_skb_duplicated corruption + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-50179 + - ceph: remove the incorrect Fw reference check when dirtying pages + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49963 + - mailbox: bcm2835: Fix timeout during suspend mode + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46849 + - ASoC: meson: axg-card: fix 'use-after-free' + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47679 + - vfs: fix race between evice_inodes() and find_inode()&iput() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49860 + - ACPI: sysfs: validate return type of _STR method + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47742 + - firmware_loader: Block path traversal + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47684 + - tcp: check skb is non-NULL in tcp_rto_delta_us() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47747 + - net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race + Condition + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47685 + - netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47692 + - nfsd: return -EINVAL when namelen is 0 + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47737 + - nfsd: call cache_put if xdr_reserve_space returns NULL + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2023-52917 + - ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47749 + - RDMA/cxgb4: Added NULL check for lookup_atid + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47696 + - RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47756 + - PCI: keystone: Fix if-statement expression in ks_pcie_quirk() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47697 + - drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47698 + - drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47757 + - nilfs2: fix potential oob read in nilfs_btree_check_delete() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47699 + - nilfs2: fix potential null-ptr-deref in nilfs_btree_insert() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47701 + - ext4: avoid OOB when system.data xattr changes underneath the filesystem + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-49851 + - tpm: Clean up TPM space after command failure + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47723 + - jfs: fix out-of-bounds in dbNextAG() and diAlloc() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47706 + - block, bfq: fix possible UAF for bfqq->bic with merge chain + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47709 + - can: bcm: Clear bo->bcm_proc_read after remove_proc_entry(). + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47710 + - sock_map: Add a cond_resched() in sock_hash_free() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47712 + - wifi: wilc1000: fix potential RCU dereference issue in + wilc_parse_join_bss_param + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47713 + - wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47671 + - USB: usbtmc: prevent kernel-usb-infoleak + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-44931 + - gpio: prevent potential speculation leaks in gpio_device_get_desc() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-41016 + - ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47670 + - ocfs2: add bounds checking to ocfs2_xattr_find_entry() + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-47672 + - wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46853 + - spi: nxp-fspi: fix the KASAN report out-of-bounds bug + * Focal update: v5.4.285 upstream stable release (LP: #2089233) // + CVE-2024-46854 + - net: dpaa: Pad packets to ETH_ZLEN + + -- Vinicius Peixoto Mon, 27 Jan 2025 11:56:28 -0300 + +linux-oracle (5.4.0-1137.146) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1137.146 -proposed tracker (LP: #2093616) + + [ Ubuntu: 5.4.0-205.225 ] + + * focal/linux: 5.4.0-205.225 -proposed tracker (LP: #2093621) + * Hold IOPOLL locks when triggering io_uring's deferred work (LP: #2078659) // + CVE-2023-21400 + - io_uring: remove extra check in __io_commit_cqring + - io_uring: dont kill fasync under completion_lock + - io_uring: ensure IOPOLL locks around deferred work + * CVE-2024-40967 + - iopoll: introduce read_poll_timeout macro + - iopoll: Introduce read_poll_timeout_atomic macro + - serial: imx: Introduce timeout when waiting on transmitter empty + * CVE-2024-53164 + - net: sched: fix ordering of qlen adjustment + * CVE-2024-53141 + - netfilter: ipset: add missing range check in bitmap_ip_uadt + * CVE-2024-53103 + - hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer + + -- Philip Cox Fri, 17 Jan 2025 14:19:39 -0500 + +linux-oracle (5.4.0-1136.145) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1136.145 -proposed tracker (LP: #2090081) + + [ Ubuntu: 5.4.0-204.224 ] + + * focal/linux: 5.4.0-204.224 -proposed tracker (LP: #2091090) + * CVE-2024-50264 + - vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans + * CVE-2024-53057 + - net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT + * CVE-2024-49967 + - ext4: no need to continue when the number of entries is 1 + * CVE-2024-43892 + - memcg: protect concurrent access to mem_cgroup_idr + * CVE-2024-38553 + - net: fec: remove .ndo_poll_controller to avoid deadlocks + * CVE-2024-38597 + - eth: sungem: remove .ndo_poll_controller to avoid deadlocks + * CVE-2023-52821 + - drm/panel: fix a possible null pointer dereference + * CVE-2024-36952 + - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up + * CVE-2024-40910 + - ax25: Fix refcount imbalance on inbound connections + * CVE-2024-35963 + - Bluetooth: hci_sock: Fix not validating setsockopt user input + * CVE-2024-35965 + - Bluetooth: L2CAP: uninitialized variables in l2cap_sock_setsockopt() + - Bluetooth: L2CAP: Fix not validating setsockopt user input + * CVE-2024-35966 + - Bluetooth: RFCOMM: Fix not validating setsockopt user input + * CVE-2024-35967 + - Bluetooth: SCO: Fix not validating setsockopt user input + * CVE-2021-47101 + - net: asix: fix uninit value bugs + - asix: fix wrong return value in asix_check_host_enable() + - asix: fix uninit-value in asix_mdio_read() + * CVE-2022-38096 + - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts + * CVE-2021-47001 + - xprtrdma: Fix cwnd update ordering + + -- Philip Cox Fri, 06 Dec 2024 08:16:15 -0500 + +linux-oracle (5.4.0-1135.144) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1135.144 -proposed tracker (LP: #2086446) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + [ Ubuntu: 5.4.0-202.222 ] + + * focal/linux: 5.4.0-202.222 -proposed tracker (LP: #2086451) + - [Packaging] resync git-ubuntu-log + * CVE-2021-47501 + - i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc + * CVE-2024-46724 + - drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number + * CVE-2024-42240 + - x86/bhi: Avoid warning in #DB handler due to BHI mitigation + * CVE-2024-42077 + - ocfs2: fix DIO failure due to insufficient transaction credits + * CVE-2024-42068 + - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro() + * CVE-2024-36968 + - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init() + * CVE-2024-35904 + - selinux: avoid dereference of garbage after mount failure + * CVE-2023-52498 + - PM: sleep: Avoid calling put_device() under dpm_list_mtx + - PM: sleep: Fix error handling in dpm_prepare() + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - PM: sleep: Fix possible deadlocks in core system-wide PM code + * CVE-2023-52488 + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + * CVE-2022-48938 + - CDC-NCM: avoid overflow in sanity checking + * CVE-2024-42156 + - s390/pkey: Wipe copies of clear-key structures on failure + * CVE-2024-44942 + - f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC + * CVE-2024-38538 + - net: bridge: xmit: make sure we have at least eth header len bytes + * CVE-2021-47076 + - RDMA/rxe: Return CQE error if invalid lkey was supplied + * CVE-2024-36938 + - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue + * CVE-2024-44940 + - fou: remove warn in gue_gro_receive on unsupported protocol + * CVE-2024-35951 + - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr() + * CVE-2023-52497 + - erofs: fix lz4 inplace decompression + * CVE-2024-36953 + - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr() + * CVE-2022-48943 + - KVM: x86/mmu: make apf token non-zero to fix bug + * CVE-2024-26947 + - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses + * CVE-2022-48733 + - btrfs: fix use-after-free after failure to create a snapshot + * CVE-2023-52639 + - KVM: s390: vsie: fix race during shadow creation + + -- Philip Cox Tue, 12 Nov 2024 13:42:03 -0500 + +linux-oracle (5.4.0-1134.143) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1134.143 -proposed tracker (LP: #2082931) + + [ Ubuntu: 5.4.0-200.220 ] + + * focal/linux: 5.4.0-200.220 -proposed tracker (LP: #2082937) + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/2024.09.30) + * CVE-2024-26800 + - tls: rx: coalesce exit paths in tls_decrypt_sg() + - tls: separate no-async decryption request handling from async + - tls: fix use-after-free on failed backlog decryption + * CVE-2024-26641 + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + * CVE-2021-47212 + - net/mlx5: Update error handler for UCTX and UMEM + * wbt:wbt_* trace event NULL pointer dereference with GENHD_FL_HIDDEN disks + (LP: #2081085) + - bdi: use bdi_dev_name() to get device name + * Focal update: v5.4.284 upstream stable release (LP: #2081278) + - drm: panel-orientation-quirks: Add quirk for OrangePi Neo + - i2c: Fix conditional for substituting empty ACPI functions + - net: usb: qmi_wwan: add MeiG Smart SRM825L + - drm/amdgpu: Fix uninitialized variable warning in amdgpu_afmt_acr + - drm/amdgpu: fix overflowed array index read warning + - drm/amd/display: Check gpio_id before used as array index + - drm/amd/display: Stop amdgpu_dm initialize when stream nums greater than 6 + - drm/amd/display: Check num_valid_sets before accessing reader_wm_sets[] + - drm/amd/display: Fix Coverity INTEGER_OVERFLOW within + dal_gpio_service_create + - drm/amdgpu: fix ucode out-of-bounds read warning + - drm/amdgpu: fix mc_data out-of-bounds read warning + - drm/amdkfd: Reconcile the definition and use of oem_id in struct + kfd_topology_device + - apparmor: fix possible NULL pointer dereference + - ionic: fix potential irq name truncation + - usbip: Don't submit special requests twice + - usb: typec: ucsi: Fix null pointer dereference in trace + - smack: tcp: ipv4, fix incorrect labeling + - wifi: cfg80211: make hash table duplicates more survivable + - drm/amd/display: Skip wbscl_set_scaler_filter if filter is null + - media: uvcvideo: Enforce alignment of frame and interval + - block: initialize integrity buffer to zero before writing it to media + - net: set SOCK_RCU_FREE before inserting socket into hashtable + - virtio_net: Fix napi_skb_cache_put warning + - udf: Limit file size to 4TB + - i2c: Use IS_REACHABLE() for substituting empty ACPI functions + - sch/netem: fix use after free in netem_dequeue + - ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object + - ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius + devices + - ata: libata: Fix memory leak for error path in ata_host_alloc() + - irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init() + - mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K + - mmc: sdhci-of-aspeed: fix module autoloading + - fuse: update stats for pages in dropped aux writeback list + - fuse: use unsigned type for getxattr/listxattr size truncation + - reset: hi6220: Add support for AO reset controller + - clk: hi6220: use CLK_OF_DECLARE_DRIVER + - clk: qcom: clk-alpha-pll: Fix the pll post div mask + - clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API + - ila: call nf_unregister_net_hooks() sooner + - sched: sch_cake: fix bulk flow accounting logic for host fairness + - nilfs2: fix missing cleanup on rollforward recovery error + - nilfs2: fix state management in error path of log writing function + - ALSA: hda: Add input value sanity checks to HDMI channel map controls + - smack: unix sockets: fix accept()ed socket label + - irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1 + - af_unix: Remove put_pid()/put_cred() in copy_peercred(). + - netfilter: nf_conncount: fix wrong variable type + - udf: Avoid excessive partition lengths + - wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3 + - usb: uas: set host status byte on data completion error + - PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0) + - media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse + - pcmcia: Use resource_size function on resource object + - can: bcm: Remove proc entry when dev is unregistered. + - igb: Fix not clearing TimeSync interrupts for 82580 + - platform/x86: dell-smbios: Fix error path in dell_smbios_init() + - tcp_bpf: fix return value of tcp_bpf_sendmsg() + - cx82310_eth: re-enable ethernet mode after router reboot + - drivers/net/usb: Remove all strcpy() uses + - net: usb: don't write directly to netdev->dev_addr + - usbnet: modern method to get random MAC + - net: bridge: fdb: convert is_local to bitops + - net: bridge: fdb: convert is_static to bitops + - net: bridge: fdb: convert is_sticky to bitops + - net: bridge: fdb: convert added_by_user to bitops + - net: bridge: fdb: convert added_by_external_learn to use bitops + - net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN + - net: dsa: vsc73xx: fix possible subblocks range of CAPT block + - ASoC: topology: Properly initialize soc_enum values + - dm init: Handle minors larger than 255 + - iommu/vt-d: Handle volatile descriptor status read + - cgroup: Protect css->cgroup write under css_set_lock + - um: line: always fill *error_out in setup_one_line() + - devres: Initialize an uninitialized struct member + - pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv + - hwmon: (adc128d818) Fix underflows seen when writing limit attributes + - hwmon: (lm95234) Fix underflows seen when writing limit attributes + - hwmon: (nct6775-core) Fix underflows seen when writing limit attributes + - hwmon: (w83627ehf) Fix underflows seen when writing limit attributes + - libbpf: Add NULL checks to bpf_object__{prev_map,next_map} + - wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id() + - smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu() + - btrfs: replace BUG_ON with ASSERT in walk_down_proc() + - btrfs: clean up our handling of refs == 0 in snapshot delete + - PCI: Add missing bridge lock to pci_bus_lock() + - btrfs: initialize location to fix -Wmaybe-uninitialized in + btrfs_lookup_dentry() + - HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup + - Input: uinput - reject requests with unreasonable number of slots + - usbnet: ipheth: race between ipheth_close and error handling + - Squashfs: sanity check symbolic link size + - of/irq: Prevent device address out-of-bounds read in interrupt map walk + - lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc() + - ata: pata_macio: Use WARN instead of BUG + - NFSv4: Add missing rescheduling points in + nfs_client_return_marked_delegations + - staging: iio: frequency: ad9834: Validate frequency parameter value + - iio: buffer-dmaengine: fix releasing dma channel on error + - iio: fix scale application in iio_convert_raw_to_processed_unlocked + - binder: fix UAF caused by offsets overwrite + - nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc + - uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind + - Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic + - VMCI: Fix use-after-free when removing resource in vmci_resource_remove() + - clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX + - clocksource/drivers/imx-tpm: Fix next event not taking effect sometime + - clocksource/drivers/timer-of: Remove percpu irq related code + - uprobes: Use kzalloc to allocate xol area + - ring-buffer: Rename ring_buffer_read() to read_buffer_iter_advance() + - tracing: Avoid possible softlockup in tracing_iter_reset() + - nilfs2: replace snprintf in show functions with sysfs_emit + - nilfs2: protect references to superblock parameters exposed in sysfs + - ACPI: processor: Return an error if acpi_processor_get_info() fails in + processor_add() + - ACPI: processor: Fix memory leaks in error paths of processor_add() + - arm64: acpi: Move get_cpu_for_acpi_id() to a header + - arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry + - nvmet-tcp: fix kernel crash if commands allocation fails + - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused + - drm/i915/fence: Mark debug_fence_free() with __maybe_unused + - rtmutex: Drop rt_mutex::wait_lock before scheduling + - net, sunrpc: Remap EPERM in case of connection failure in + xs_tcp_setup_socket + - cx82310_eth: fix error return code in cx82310_bind() + - Linux 5.4.284 + * CVE-2024-42244 + - USB: serial: mos7840: fix crash on resume + * CVE-2024-40929 + - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids + * CVE-2024-41073 + - nvme: avoid double free special payload + * CVE-2024-41071 + - wifi: mac80211: Avoid address calculations via out of bounds array indexing + * CVE-2024-42229 + - crypto: aead, cipher - zeroize key buffer after use + * CVE-2024-38611 + - media: i2c: et8ek8: Don't strip remove function when driver is builtin + * CVE-2024-38602 + - ax25: Fix reference count leak issues of ax25_dev + * CVE-2024-35848 + - misc: eeprom: at24: fix regulator underflow + - misc: eeprom: at24: register nvmem only after eeprom is ready to use + - eeprom: at24: fix memory corruption race condition + * CVE-2024-26669 + - net/sched: flower: Fix chain template offload + * CVE-2024-26668 + - netfilter: nft_limit: rename stateful structure + - netfilter: nft_limit: reject configurations that cause integer overflow + * CVE-2024-26640 + - net-zerocopy: Refactor frag-is-remappable test. + - tcp: add sanity checks to rx zerocopy + * CVE-2024-26607 + - drm/bridge: sii902x: Fix probing race issue + * CVE-2023-52614 + - PM / devfreq: Fix buffer overflow in trans_stat_show + * CVE-2023-52531 + - wifi: iwlwifi: mvm: Fix a memory corruption issue + * CVE-2022-36402 + - drm/vmwgfx: Use enum to represent graphics context capabilities + - drm/vmwgfx: Fix shader stage validation + * Focal update: v5.4.283 upstream stable release (LP: #2080595) + - fuse: Initialize beyond-EOF page contents before setting uptodate + - ALSA: usb-audio: Support Yamaha P-125 quirk entry + - xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration + - s390/dasd: fix error recovery leading to data corruption on ESE devices + - arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to + NUMA_NO_NODE + - dm resume: don't return EINVAL when signalled + - dm persistent data: fix memory allocation failure + - vfs: Don't evict inode under the inode lru traversing context + - bitmap: introduce generic optimized bitmap_size() + - fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE + - selinux: fix potential counting error in avc_add_xperms_decision() + - drm/amdgpu: Actually check flags for all context ops. + - memcg_write_event_control(): fix a user-triggerable oops + - overflow.h: Add flex_array_size() helper + - overflow: Implement size_t saturating arithmetic helpers + - s390/cio: rename bitmap_size() -> idset_bitmap_size() + - btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits() + - s390/uv: Panic for set and remove shared access UVC errors + - net/mlx5e: Correctly report errors for ethtool rx flows + - atm: idt77252: prevent use after free in dequeue_rx() + - net: axienet: Fix DMA descriptor cleanup path + - net: axienet: Improve DMA error handling + - net: axienet: Factor out TX descriptor chain cleanup + - net: axienet: Check for DMA mapping errors + - net: axienet: Drop MDIO interrupt registers from ethtools dump + - net: axienet: Wrap DMA pointer writes to prepare for 64 bit + - net: axienet: Upgrade descriptors to hold 64-bit addresses + - net: axienet: Autodetect 64-bit DMA capability + - net: axienet: Fix register defines comment description + - net: dsa: vsc73xx: pass value in phy_write operation + - net: hns3: fix a deadlock problem when config TC during resetting + - ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7 + - ssb: Fix division by zero issue in ssb_calc_clock_rate + - wifi: cw1200: Avoid processing an invalid TIM IE + - i2c: riic: avoid potential division by zero + - media: radio-isa: use dev_name to fill in bus_info + - staging: ks7010: disable bh on tx_dev_lock + - binfmt_misc: cleanup on filesystem umount + - scsi: spi: Fix sshdr use + - gfs2: setattr_chown: Add missing initialization + - wifi: iwlwifi: abort scan when rfkill on but device enabled + - IB/hfi1: Fix potential deadlock on &irq_src_lock and &dd->uctxt_lock + - powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu + - nvmet-trace: avoid dereferencing pointer too early + - ext4: do not trim the group with corrupted block bitmap + - quota: Remove BUG_ON from dqget() + - media: pci: cx23885: check cx23885_vdev_init() return + - fs: binfmt_elf_efpic: don't use missing interpreter's properties + - scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list() + - net/sun3_82586: Avoid reading past buffer in debug output + - drm/lima: set gp bus_stop bit before hard reset + - virtiofs: forbid newlines in tags + - md: clean up invalid BUG_ON in md_ioctl + - x86: Increase brk randomness entropy for 64-bit systems + - powerpc/boot: Handle allocation failure in simple_realloc() + - powerpc/boot: Only free if realloc() succeeds + - btrfs: change BUG_ON to assertion when checking for delayed_node root + - btrfs: handle invalid root reference found in may_destroy_subvol() + - btrfs: send: handle unexpected data in header buffer in begin_cmd() + - btrfs: delete pointless BUG_ON check on quota root in + btrfs_qgroup_account_extent() + - f2fs: fix to do sanity check in update_sit_entry + - usb: gadget: fsl: Increase size of name buffer for endpoints + - nvme: clear caller pointer on identify failure + - Bluetooth: bnep: Fix out-of-bound access + - nvmet-tcp: do not continue for invalid icreq + - NFS: avoid infinite loop in pnfs_update_layout. + - openrisc: Call setup_memory() earlier in the init sequence + - s390/iucv: fix receive buffer virtual vs physical address confusion + - usb: dwc3: core: Skip setting event buffers for host only controllers + - irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc + - ext4: set the type of max_zeroout to unsigned int to avoid overflow + - nvmet-rdma: fix possible bad dereference when freeing rsps + - hrtimer: Prevent queuing of hrtimer without a function callback + - gtp: pull network headers in gtp_dev_xmit() + - block: use "unsigned long" for blk_validate_block_size(). + - media: solo6x10: replace max(a, min(b, c)) by clamp(b, a, c) + - dm mpath: pass IO start time to path selector + - dm: do not use waitqueue for request-based DM + - dm suspend: return -ERESTARTSYS instead of -EINTR + - Bluetooth: Make use of __check_timeout on hci_sched_le + - Bluetooth: hci_core: Fix not handling link timeouts propertly + - Bluetooth: hci_core: Fix LE quote calculation + - tc-testing: don't access non-existent variable on exception + - kcm: Serialise kcm_sendmsg() for the same socket. + - netfilter: nft_counter: Synchronize nft_counter_reset() against reader. + - net: dsa: mv88e6xxx: global2: Expose ATU stats register + - net: dsa: mv88e6xxx: global1_atu: Add helper for get next + - net: dsa: mv88e6xxx: read FID when handling ATU violations + - net: dsa: mv88e6xxx: replace ATU violation prints with trace points + - net: dsa: mv88e6xxx: Fix out-of-bound access + - ipv6: prevent UAF in ip6_send_skb() + - net: xilinx: axienet: Always disable promiscuous mode + - net: xilinx: axienet: Fix dangling multicast addresses + - drm/msm: use drm_debug_enabled() to check for debug categories + - drm/msm/dpu: don't play tricks with debug macros + - mmc: mmc_test: Fix NULL dereference on allocation failure + - Bluetooth: MGMT: Add error handling to pair_device() + - HID: wacom: Defer calculation of resolution until resolution_code is known + - HID: microsoft: Add rumble support to latest xbox controllers + - cxgb4: add forgotten u64 ivlan cast before shift + - mmc: dw_mmc: allow biu and ciu clocks to defer + - ALSA: timer: Relax start tick time check for slave timer elements + - Input: MT - limit max slots + - tools: move alignment-related macros to new + - pinctrl: single: fix potential NULL dereference in pcs_get_function() + - wifi: mwifiex: duplicate static structs used in driver instances + - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages + - filelock: Correct the filelock owner in fcntl_setlk/fcntl_setlk64 + - media: uvcvideo: Fix integer overflow calculating timestamp + - ata: libata-core: Fix null pointer dereference on error + - cgroup/cpuset: Prevent UAF in proc_cpuset_show() + - net:rds: Fix possible deadlock in rds_message_put + - soundwire: stream: fix programming slave ports for non-continous port maps + - r8152: Factor out OOB link list waits + - ethtool: check device is present when getting link settings + - gtp: fix a potential NULL pointer dereference + - net: busy-poll: use ktime_get_ns() instead of local_clock() + - nfc: pn533: Add dev_up/dev_down hooks to phy_ops + - nfc: pn533: Add autopoll capability + - nfc: pn533: Add poll mod list filling check + - soc: qcom: cmd-db: Map shared memory as WC, not WB + - cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller + - USB: serial: option: add MeiG Smart SRM825L + - usb: dwc3: omap: add missing depopulate in probe error path + - usb: dwc3: core: Prevent USB core invalid event buffer address access + - usb: dwc3: st: fix probed platform device ref count on probe error path + - usb: dwc3: st: add missing depopulate in probe error path + - usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in + remove_power_attributes() + - net: dsa: mv8e6xxx: Fix stub function parameters + - scsi: aacraid: Fix double-free on probe failure + - Linux 5.4.283 + * CVE-2024-27051 + - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value + - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations + * CVE-2024-26891 + - PCI: Make pci_dev_is_disconnected() helper public for other drivers + - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected + * Focal update: v5.4.282 upstream stable release (LP: #2078388) + - EDAC, skx_common: Refactor so that we initialize "dev" in result of adxl + decode. + - EDAC, skx: Retrieve and print retry_rd_err_log registers + - EDAC/skx_common: Add new ADXL components for 2-level memory + - EDAC, i10nm: make skx_common.o a separate module + - platform/chrome: cros_ec_debugfs: fix wrong EC message version + - hfsplus: fix to avoid false alarm of circular locking + - x86/of: Return consistent error type from x86_of_pci_irq_enable() + - x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling + - x86/pci/xen: Fix PCIBIOS_* return code handling + - x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos + - hwmon: (adt7475) Fix default duty on fan is disabled + - pwm: stm32: Always do lazy disabling + - hwmon: (max6697) Fix underflow when writing limit attributes + - hwmon: (max6697) Fix swapped temp{1,8} critical alarms + - arm64: dts: qcom: sdm845: add power-domain to UFS PHY + - arm64: dts: qcom: msm8996: specify UFS core_clk frequencies + - arm64: dts: rockchip: Increase VOP clk rate on RK3328 + - ARM: dts: imx6qdl-kontron-samx6i: move phy reset into phy-node + - ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset + - ARM: dts: imx6qdl-kontron-samx6i: fix board reset + - ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity + - arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux + - arm64: dts: amlogic: gx: correct hdmi clocks + - m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages + - x86/xen: Convert comma to semicolon + - m68k: cmpxchg: Fix return value for default case in __arch_xchg() + - firmware: turris-mox-rwtm: Fix checking return value of + wait_for_completion_timeout() + - firmware: turris-mox-rwtm: Initialize completion before mailbox + - wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device + - net/smc: Allow SMC-D 1MB DMB allocations + - net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when + CONFIG_ARCH_NO_SG_CHAIN is defined + - selftests/bpf: Check length of recv in test_sockmap + - lib: objagg: Fix general protection fault + - mlxsw: spectrum_acl_erp: Fix object nesting warning + - wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he() + - wifi: cfg80211: handle 2x996 RU allocation in + cfg80211_calculate_bitrate_he() + - net: fec: Refactor: #define magic constants + - net: fec: Fix FEC_ECR_EN1588 being cleared on link-down + - ipvs: Avoid unnecessary calls to skb_is_gso_sctp + - netfilter: nf_tables: rise cap on SELinux secmark context + - perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation + - perf: Fix perf_aux_size() for greater-than 32-bit size + - perf: Prevent passing zero nr_pages to rb_alloc_aux() + - qed: Improve the stack space of filter_config() + - wifi: virt_wifi: avoid reporting connection success with wrong SSID + - gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey + - wifi: virt_wifi: don't use strlen() in const context + - bna: adjust 'name' buf size of bna_tcb and bna_ccb structures + - selftests: forwarding: devlink_lib: Wait for udev events after reloading + - media: dvb-usb: Fix unexpected infinite loop in + dvb_usb_read_remote_control() + - media: imon: Fix race getting ictx->lock + - saa7134: Unchecked i2c_transfer function result fixed + - media: uvcvideo: Allow entity-defined get_info and get_cur + - media: uvcvideo: Override default flags + - media: renesas: vsp1: Fix _irqsave and _irq mix + - media: renesas: vsp1: Store RPF partition configuration per RPF instance + - leds: trigger: Unregister sysfs attributes before calling deactivate() + - perf report: Fix condition in sort__sym_cmp() + - drm/etnaviv: fix DMA direction handling for cached RW buffers + - drm/qxl: Add check for drm_cvt_mode + - mfd: omap-usb-tll: Use struct_size to allocate tll + - SUNRPC: avoid soft lockup when transmitting UDP to reachable server. + - ext4: avoid writing unitialized memory to disk in EA inodes + - sparc64: Fix incorrect function signature and add prototype for + prom_cif_init + - SUNRPC: Fixup gss_status tracepoint error output + - PCI: Fix resource double counting on remove & rescan + - Input: qt1050 - handle CHIP_ID reading error + - RDMA/mlx4: Fix truncated output warning in mad.c + - RDMA/mlx4: Fix truncated output warning in alias_GUID.c + - RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs + - ASoC: max98088: Check for clk_prepare_enable() error + - mtd: make mtd_test.c a separate module + - RDMA/device: Return error earlier if port in not valid + - Input: elan_i2c - do not leave interrupt disabled on suspend failure + - MIPS: Octeron: remove source file executable bit + - powerpc/xmon: Fix disassembly CPU feature checks + - macintosh/therm_windtunnel: fix module unload. + - bnxt_re: Fix imm_data endianness + - netfilter: ctnetlink: use helper function to calculate expect ID + - pinctrl: core: fix possible memory leak when pinctrl_enable() fails + - pinctrl: single: fix possible memory leak when pinctrl_enable() fails + - pinctrl: ti: ti-iodelay: Drop if block with always false condition + - pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable() + fails + - pinctrl: freescale: mxs: Fix refcount of child + - fs/nilfs2: remove some unused macros to tame gcc + - nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro + - rtc: interface: Add RTC offset to alarm after fix-up + - tick/broadcast: Make takeover of broadcast hrtimer reliable + - net: netconsole: Disable target before netpoll cleanup + - af_packet: Handle outgoing VLAN packets without hardware offloading + - ipv6: take care of scope when choosing the src addr + - char: tpm: Fix possible memory leak in tpm_bios_measurements_open() + - media: venus: fix use after free in vdec_close + - hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode() + - drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes + - drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes + - drm/amd/display: Check for NULL pointer + - udf: Avoid using corrupted block bitmap buffer + - m68k: amiga: Turn off Warp1260 interrupts during boot + - ext4: check dot and dotdot of dx_root before making dir indexed + - ext4: make sure the first directory block is not a hole + - wifi: mwifiex: Fix interface type change + - leds: ss4200: Convert PCIBIOS_* return codes to errnos + - tools/memory-model: Fix bug in lock.cat + - hwrng: amd - Convert PCIBIOS_* return codes to errnos + - PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN + - binder: fix hang of unregistered readers + - scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds + - f2fs: fix to don't dirty inode for readonly filesystem + - clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use + - ubi: eba: properly rollback inside self_check_eba + - decompress_bunzip2: fix rare decompression failure + - kobject_uevent: Fix OOB access within zap_modalias_env() + - rtc: cmos: Fix return value of nvmem callbacks + - scsi: qla2xxx: During vport delete send async logout explicitly + - scsi: qla2xxx: Fix for possible memory corruption + - scsi: qla2xxx: Complete command early within lock + - scsi: qla2xxx: validate nvme_local_port correctly + - perf/x86/intel/pt: Fix topa_entry base length + - perf/x86/intel/pt: Fix a topa_entry base address calculation + - rtc: isl1208: Fix return value of nvmem callbacks + - watchdog/perf: properly initialize the turbo mode timestamp and rearm + counter + - platform: mips: cpu_hwmon: Disable driver on unsupported hardware + - RDMA/iwcm: Fix a use-after-free related to destroying CM IDs + - selftests/sigaltstack: Fix ppc64 GCC build + - rbd: don't assume rbd_is_lock_owner() for exclusive mappings + - drm/panfrost: Mark simple_ondemand governor as softdep + - rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait + - rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings + - Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591 + - nilfs2: handle inconsistent state in nilfs_btnode_create_block() + - kdb: address -Wformat-security warnings + - kdb: Use the passed prompt in kdb_position_cursor() + - jfs: Fix array-index-out-of-bounds in diFree + - um: time-travel: fix time-travel-start option + - libbpf: Fix no-args func prototype BTF dumping syntax + - dma: fix call order in dmam_free_coherent + - MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later + - ipv4: Fix incorrect source address in Record Route option + - net: bonding: correctly annotate RCU in bond_should_notify_peers() + - tipc: Return non-zero value from tipc_udp_addr2str() on error + - net: nexthop: Initialize all fields in dumped nexthops + - bpf: Fix a segment issue when downgrading gso_size + - mISDN: Fix a use after free in hfcmulti_tx() + - powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap() + - ASoC: Intel: Convert to new X86 CPU match macros + - ASoC: Intel: Move soc_intel_is_foo() helpers to a generic header + - ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable + - nvme-pci: add missing condition check for existence of mapped data + - mm: avoid overflows in dirty throttling logic + - PCI: rockchip: Make 'ep-gpios' DT property optional + - PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio + - parport: Convert printk(KERN_ to pr_( + - parport: Standardize use of printmode + - dev/parport: fix the array out-of-bounds risk + - driver core: Cast to (void *) with __force for __percpu pointer + - devres: Fix memory leakage caused by driver API devm_free_percpu() + - genirq: Allow the PM device to originate from irq domain + - irqchip/imx-irqsteer: Constify irq_chip struct + - irqchip/imx-irqsteer: Add runtime PM support + - irqchip/imx-irqsteer: Handle runtime power management correctly + - remoteproc: imx_rproc: ignore mapping vdev regions + - remoteproc: imx_rproc: Fix ignoring mapping vdev regions + - remoteproc: imx_rproc: Skip over memory region when node value is NULL + - drm/nouveau: prime: fix refcount underflow + - drm/vmwgfx: Fix overlay when using Screen Targets + - net/iucv: fix use after free in iucv_sock_close() + - net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys + - ipv6: fix ndisc_is_useropt() handling for PIO + - HID: wacom: Modify pen IDs + - protect the fetch of ->fd[fd] in do_dup2() from mispredictions + - ALSA: usb-audio: Correct surround channels in UAC1 channel map + - net: usb: sr9700: fix uninitialized variable use in sr_mdio_read + - netfilter: ipset: Add list flush to cancel_gc + - genirq: Allow irq_chip registration functions to take a const irq_chip + - irqchip/mbigen: Fix mbigen node address layout + - x86/mm: Fix pti_clone_pgtable() alignment assumption + - sctp: move hlist_node and hashent out of sctp_ep_common + - sctp: Fix null-ptr-deref in reuseport_add_sock(). + - net: usb: qmi_wwan: fix memory leak for not ip packets + - net: linkwatch: use system_unbound_wq + - Bluetooth: l2cap: always unlock channel in l2cap_conless_channel() + - net: fec: Stop PPS on driver remove + - md/raid5: avoid BUG_ON() while continue reshape after reassembling + - clocksource/drivers/sh_cmt: Address race condition for clock events + - ACPI: battery: create alarm sysfs attribute atomically + - ACPI: SBS: manage alarm sysfs attribute through psy core + - selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT + - PCI: Add Edimax Vendor ID to pci_ids.h + - udf: prevent integer overflow in udf_bitmap_free_blocks() + - wifi: nl80211: don't give key data to userspace + - btrfs: fix bitmap leak when loading free space cache on duplicate entry + - drm/amdgpu: Fix the null pointer dereference to ras_manager + - media: uvcvideo: Ignore empty TS packets + - media: uvcvideo: Fix the bandwdith quirk on USB 3.x + - jbd2: avoid memleak in jbd2_journal_write_metadata_buffer + - s390/sclp: Prevent release of buffer in I/O + - SUNRPC: Fix a race to wake a sync task + - ext4: fix wrong unit use in ext4_mb_find_by_goal + - arm64: cpufeature: Force HWCAP to be based on the sysreg visible to user- + space + - arm64: Add Neoverse-V2 part + - arm64: cputype: Add Cortex-X4 definitions + - arm64: cputype: Add Neoverse-V3 definitions + - arm64: errata: Add workaround for Arm errata 3194386 and 3312417 + - [Config] Set ARM64_ERRATUM_3194386=y + - arm64: cputype: Add Cortex-X3 definitions + - arm64: cputype: Add Cortex-A720 definitions + - arm64: cputype: Add Cortex-X925 definitions + - arm64: errata: Unify speculative SSBS errata logic + - arm64: errata: Expand speculative SSBS workaround + - arm64: cputype: Add Cortex-X1C definitions + - arm64: cputype: Add Cortex-A725 definitions + - arm64: errata: Expand speculative SSBS workaround (again) + - i2c: smbus: Don't filter out duplicate alerts + - i2c: smbus: Improve handling of stuck alerts + - i2c: smbus: Send alert notifications to all devices if source not found + - bpf: kprobe: remove unused declaring of bpf_kprobe_override + - spi: fsl-lpspi: remove unneeded array + - spi: spi-fsl-lpspi: Fix scldiv calculation + - drm/client: fix null pointer dereference in drm_client_modeset_probe + - ALSA: line6: Fix racy access to midibuf + - ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list + - ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4 + - usb: vhci-hcd: Do not drop references before new references are gained + - USB: serial: debug: do not echo input by default + - usb: gadget: core: Check for unset descriptor + - scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic + - tick/broadcast: Move per CPU pointer access into the atomic section + - ntp: Clamp maxerror and esterror to operating range + - driver core: Fix uevent_show() vs driver detach race + - ntp: Safeguard against time_constant overflow + - scsi: mpt3sas: Remove scsi_dma_map() error messages + - scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES + - serial: core: check uartclk for zero to avoid divide by zero + - genirq/irqdesc: Honor caller provided affinity in alloc_desc() + - power: supply: axp288_charger: Fix constant_charge_voltage writes + - power: supply: axp288_charger: Round constant_charge_voltage writes down + - tracing: Fix overflow in get_free_elt() + - x86/mtrr: Check if fixed MTRRs exist before saving them + - drm/bridge: analogix_dp: properly handle zero sized AUX transactions + - drm/mgag200: Set DDC timeout in milliseconds + - Fix gcc 4.9 build issue in 5.4.y + - kbuild: Fix '-S -c' in x86 stack protector scripts + - netfilter: nf_tables: set element extended ACK reporting support + - netfilter: nf_tables: prefer nft_chain_validate + - drm/i915/gem: Fix Virtual Memory mapping boundaries calculation + - arm64: cpufeature: Fix the visibility of compat hwcaps + - media: uvcvideo: Use entity get_cur in uvc_ctrl_set + - exec: Fix ToCToU between perm check and set-uid/gid usage + - nvme/pci: Add APST quirk for Lenovo N60z laptop + - ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode + - media: Revert "media: dvb-usb: Fix unexpected infinite loop in + dvb_usb_read_remote_control()" + - Linux 5.4.282 + * CVE-2024-26885 + - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches + * Focal update: v5.4.281 upstream stable release (LP: #2076097) + - gcc-plugins: Rename last_stmt() for GCC 14+ + - filelock: Remove locks reliably when fcntl/close race is detected + - scsi: qedf: Set qed_slowpath_params to zero before use + - ACPI: EC: Abort address space access upon error + - ACPI: EC: Avoid returning AE_OK on errors in address space handler + - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata + - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan() + - Input: silead - Always support 10 fingers + - ila: block BH in ila_output() + - kconfig: gconf: give a proper initial state to the Save button + - kconfig: remove wrong expr_trans_bool() + - fs/file: fix the check in find_next_fd() + - mei: demote client disconnect warning on suspend to debug + - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check + - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group() + - ALSA: hda/realtek: Add more codec ID to no shutup pins list + - mips: fix compat_sys_lseek syscall + - Input: elantech - fix touchpad state on resume for Lenovo N24 + - bytcr_rt5640 : inverse jack detect for Archos 101 cesium + - ASoC: ti: davinci-mcasp: Set min period size using FIFO config + - ASoC: ti: omap-hdmi: Fix too long driver name + - can: kvaser_usb: fix return value for hif_usb_send_regout + - s390/sclp: Fix sclp_init() cleanup on failure + - ALSA: dmaengine_pcm: terminate dmaengine before synchronize + - net: usb: qmi_wwan: add Telit FN912 compositions + - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and + DEV_STATS_ADD() + - powerpc/pseries: Whitelist dtl slub object for copying to userspace + - powerpc/eeh: avoid possible crash when edev->pdev changes + - scsi: libsas: Fix exp-attached device scan after probe failure scanned in + again after probe failed + - Bluetooth: hci_core: cancel all works upon hci_unregister_dev() + - fs: better handle deep ancestor chains in is_subdir() + - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices + - selftests/vDSO: fix clang build errors and warnings + - hfsplus: fix uninit-value in copy_name + - ARM: 9324/1: fix get_user() broken with veneer + - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency + - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq() + - net: relax socket state check at accept time. + - ocfs2: add bounds checking to ocfs2_check_dir_entry() + - jfs: don't walk off the end of ealist + - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400 + - filelock: Fix fcntl/close race recovery compat path + - tun: add missing verification for short frame + - tap: add missing verification for short frame + - Linux 5.4.281 + * Focal update: v5.4.283 upstream stable release (LP: #2080595) // + CVE-2024-45016 + - netem: fix return value if duplicate enqueue fails + * CVE-2024-38630 + - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger + * CVE-2024-27397 + - netfilter: nf_tables: use timestamp to check for set element timeout + * CVE-2024-26960 + - mm: swap: fix race between free_swap_and_cache() and swapoff() + + -- Philip Cox Mon, 07 Oct 2024 09:30:00 -0400 + +linux-oracle (5.4.0-1133.142) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1133.142 -proposed tracker (LP: #2082227) + + * Packaging resync (LP: #1786013) + - [Packaging] debian.oracle/dkms-versions -- update from kernel-versions + (main/s2024.09.02) + + [ Ubuntu: 5.4.0-198.218 ] + + * focal/linux: 5.4.0-198.218 -proposed tracker (LP: #2082232) + * Packaging resync (LP: #1786013) + - [Packaging] debian.master/dkms-versions -- update from kernel-versions + (main/s2024.09.02) + * CVE-2024-45016 + - netem: fix return value if duplicate enqueue fails + * CVE-2024-38630 + - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger + * CVE-2024-27397 + - netfilter: nf_tables: use timestamp to check for set element timeout + * CVE-2024-26960 + - mm: swap: fix race between free_swap_and_cache() and swapoff() + + -- Philip Cox Thu, 03 Oct 2024 13:23:05 -0400 + +linux-oracle (5.4.0-1132.141) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1132.141 -proposed tracker (LP: #2078200) + + [ Ubuntu: 5.4.0-196.216 ] + + * focal/linux: 5.4.0-196.216 -proposed tracker (LP: #2078205) + * CVE-2024-39494 + - ima: Fix use-after-free on a dentry's dname.name + * CVE-2024-42160 + - f2fs: check validation of fault attrs in f2fs_build_fault_attr() + - f2fs: Add inline to f2fs_build_fault_attr() stub + * CVE-2024-38570 + - gfs2: Rename sd_{ glock => kill }_wait + - gfs2: Fix potential glock use-after-free on unmount + * CVE-2024-42228 + - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc + * CVE-2022-48791 + - scsi: pm80xx: Fix TMF task completion race condition + - scsi: pm8001: Fix use-after-free for aborted TMF sas_task + * CVE-2024-26787 + - mmc: mmci_sdmmc: Rename sdmmc_priv struct to sdmmc_idma + - mmc: mmci: stm32: use a buffer for unaligned DMA requests + - mmc: mmci: stm32: fix DMA API overlapping mappings warning + * CVE-2024-27012 + - netfilter: nf_tables: restore set elements when delete set fails + * CVE-2022-48863 + - mISDN: Fix memory leak in dsp_pipeline_build() + * CVE-2021-47188 + - scsi: ufs: core: Improve SCSI abort handling + * CVE-2024-26677 + - rxrpc: Fix delayed ACKs to not set the reference serial number + + -- Manuel Diewald Mon, 02 Sep 2024 12:23:09 +0200 + +linux-oracle (5.4.0-1131.140) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1131.140 -proposed tracker (LP: #2075949) + + [ Ubuntu: 5.4.0-195.215 ] + + * focal/linux: 5.4.0-195.215 -proposed tracker (LP: #2075954) + * Focal update: v5.4.280 upstream stable release (LP: #2075175) + - Compiler Attributes: Add __uninitialized macro + - drm/lima: fix shared irq handling on driver remove + - media: dvb: as102-fe: Fix as10x_register_addr packing + - media: dvb-usb: dib0700_devices: Add missing release_firmware() + - IB/core: Implement a limit on UMAD receive List + - scsi: qedf: Make qedf_execute_tmf() non-preemptible + - drm/amdgpu: Initialize timestamp for some legacy SOCs + - drm/amd/display: Skip finding free audio for unknown engine_id + - media: dw2102: Don't translate i2c read into write + - sctp: prefer struct_size over open coded arithmetic + - firmware: dmi: Stop decoding on broken entry + - Input: ff-core - prefer struct_size over open coded arithmetic + - net: dsa: mv88e6xxx: Correct check for empty list + - media: dvb-frontends: tda18271c2dd: Remove casting during div + - media: s2255: Use refcount_t instead of atomic_t for num_channels + - media: dvb-frontends: tda10048: Fix integer overflow + - i2c: i801: Annotate apanel_addr as __ro_after_init + - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n + - orangefs: fix out-of-bounds fsid access + - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#" + - jffs2: Fix potential illegal address access in jffs2_free_inode + - s390/pkey: Wipe sensitive data on failure + - tcp: tcp_mark_head_lost is only valid for sack-tcp + - tcp: add ece_ack flag to reno sack functions + - net: tcp better handling of reordering then loss cases + - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open() + - tcp_metrics: validate source addr length + - wifi: wilc1000: fix ies_len type in connect path + - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set() + - selftests: fix OOM in msg_zerocopy selftest + - selftests: make order checking verbose in msg_zerocopy selftest + - inet_diag: Initialize pad field in struct inet_diag_req_v2 + - nilfs2: fix inode number range checks + - nilfs2: add missing check for inode numbers on directory entries + - mm: optimize the redundant loop of mm_update_owner_next() + - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct + - fsnotify: Do not generate events for O_PATH file descriptors + - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), + again" + - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes + - drm/amdgpu/atomfirmware: silence UBSAN warning + - media: dw2102: fix a potential buffer overflow + - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr + - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 + - nvme-multipath: find NUMA path only for online numa-node + - nilfs2: fix incorrect inode allocation from reserved inodes + - filelock: fix potential use-after-free in posix_lock_inode + - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading + - vfs: don't mod negative dentry count when on shrinker list + - tcp: add TCP_INFO status for failed client TFO + - tcp: fix incorrect undo caused by DSACK of TLP retransmit + - octeontx2-af: Fix incorrect value output on error path in + rvu_check_rsrc_availability() + - net: lantiq_etop: add blank line after declaration + - net: ethernet: lantiq_etop: fix double free in detach + - ppp: reject claimed-as-LCP but actually malformed packets + - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port(). + - s390: Mark psw in __load_psw_mask() as __unitialized + - ARM: davinci: Convert comma to semicolon + - octeontx2-af: fix detection of IP layer + - USB: serial: option: add Telit generic core-dump composition + - USB: serial: option: add Telit FN912 rmnet compositions + - USB: serial: option: add Fibocom FM350-GL + - USB: serial: option: add support for Foxconn T99W651 + - USB: serial: option: add Netprisma LCUK54 series modules + - USB: serial: option: add Rolling RW350-GL variants + - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k + - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy() + - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the + descriptor + - hpet: Support 32-bit userspace + - nvmem: meson-efuse: Fix return value of nvmem callbacks + - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX + - libceph: fix race between delayed_work() and ceph_monc_stop() + - SUNRPC: Fix RPC client cleaned up the freed pipefs dentries + - tcp: refactor tcp_retransmit_timer() + - net: tcp: fix unexcepted socket die when snd_wnd is 0 + - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out() + - tcp: avoid too many retransmit packets + - nilfs2: fix kernel bug on rename operation of broken directory + - i2c: rcar: bring hardware to known state when probing + - Linux 5.4.280 + * [SRU] UBSAN warnings in bnx2x kernel driver (LP: #2074215) // Focal update: + v5.4.280 upstream stable release (LP: #2075175) + - bnx2x: Fix multiple UBSAN array-index-out-of-bounds + * Focal update: v5.4.279 upstream stable release (LP: #2073621) + - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects + - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup() + - wifi: cfg80211: pmsr: use correct nla_get_uX functions + - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64 + - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef + - wifi: iwlwifi: mvm: don't read past the mfuart notifcation + - ipv6: sr: block BH in seg6_output_core() and seg6_input_core() + - net: sched: sch_multiq: fix possible OOB write in multiq_tune() + - vxlan: Fix regression when dropping packets due to invalid src addresses + - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB + - net/mlx5: Stop waiting for PCI if pci channel is offline + - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP + - ptp: Fix error message on failed pin verification + - af_unix: Annotate data-race of sk->sk_state in unix_inq_len(). + - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and + poll(). + - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg(). + - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG. + - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen. + - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect(). + - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen(). + - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill(). + - ipv6: fix possible race in __fib6_drop_pcpu_from() + - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete + - ASoC: ti: davinci-mcasp: remove redundant assignment to variable ret + - ASoC: ti: davinci-mcasp: remove always zero of davinci_mcasp_get_dt_params + - ASoC: ti: davinci-mcasp: Use platform_get_irq_byname_optional + - ASoC: ti: davinci-mcasp: Remove legacy dma_request parsing + - ASoC: ti: davinci-mcasp: Simplify the configuration parameter handling + - ASoC: ti: davinci-mcasp: Handle missing required DT properties + - ASoC: ti: davinci-mcasp: Fix race condition during probe + - drm/amd/display: Handle Y carry-over in VCP X.Y calculation + - serial: sc16is7xx: replace hardcoded divisor value with BIT() macro + - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler + - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages + - selftests/mm: conform test to TAP format output + - selftests/mm: compaction_test: fix bogus test success on Aarch64 + - nilfs2: Remove check for PageError + - nilfs2: return the mapped address from nilfs_get_page() + - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors + - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages + - mei: me: release irq in mei_me_pci_resume error path + - jfs: xattr: fix buffer overflow for invalid xattr + - xhci: Set correct transferred length for cancelled bulk transfers + - xhci: Apply reset resume quirk to Etron EJ188 xHCI host + - xhci: Apply broken streams quirk to Etron EJ188 xHCI host + - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory + - Input: try trimming too long modalias strings + - SUNRPC: return proper error from gss_wrap_req_priv + - gpio: tqmx86: fix typo in Kconfig label + - HID: core: remove unnecessary WARN_ON() in implement() + - iommu/amd: Fix sysfs leak in iommu init + - iommu: Return right value in iommu_sva_bind_device() + - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode() + - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet + - drm/komeda: check for error-valued pointer + - drm/bridge/panel: Fix runtime warning on panel bridge release + - tcp: fix race in tcp_v6_syn_recv_sock() + - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN) + packets + - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ + - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set + type + - net/ipv6: Fix the RT cache flush via sysctl using a previous delay + - ionic: fix use after netif_napi_del() + - drivers: core: synchronize really_probe() and dev_uevent() + - drm/exynos/vidi: fix memory leak in .get_modes() + - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found + - tracing/selftests: Fix kprobe event name test for .isra. functions + - vmci: prevent speculation leaks by sanitizing event in event_deliver() + - fs/proc: fix softlockup in __read_vmcore + - ocfs2: use coarse time for new created files + - ocfs2: fix races between hole punching and AIO+DIO + - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id + - dmaengine: axi-dmac: fix possible race in remove() + - intel_th: pci: Add Granite Rapids support + - intel_th: pci: Add Granite Rapids SOC support + - intel_th: pci: Add Sapphire Rapids SOC support + - intel_th: pci: Add Meteor Lake-S support + - intel_th: pci: Add Lunar Lake support + - nilfs2: fix potential kernel bug due to lack of writeback flag waiting + - tick/nohz_full: Don't abuse smp_call_function_single() in + tick_setup_device() + - hv_utils: drain the timesync packets on onchannelcallback + - hugetlb_encode.h: fix undefined behaviour (34 << 26) + - greybus: Fix use-after-free bug in gb_interface_release due to race + condition. + - usb-storage: alauda: Check whether the media is initialized + - i2c: at91: Fix the functionality flags of the slave-only interface + - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment + - selftests/bpf: Prevent client connect before server bind in + test_tc_tunnel.sh + - batman-adv: bypass empty buckets in batadv_purge_orig_ref() + - drop_monitor: replace spin_lock by raw_spin_lock + - scsi: qedi: Fix crash while reading debugfs attribute + - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl + - powerpc/pseries: Enforce hcall result buffer validity and size + - powerpc/io: Avoid clang null pointer arithmetic warnings + - usb: misc: uss720: check for incompatible versions of the Belkin F5U002 + - udf: udftime: prevent overflow in udf_disk_stamp_to_time() + - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports + - MIPS: Octeon: Add PCIe link status check + - MIPS: Routerboard 532: Fix vendor retry check code + - mips: bmips: BCM6358: make sure CBR is correctly set + - cipso: fix total option length computation + - netrom: Fix a memory leak in nr_heartbeat_expiry() + - ipv6: prevent possible NULL deref in fib6_nh_init() + - ipv6: prevent possible NULL dereference in rt6_probe() + - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr() + - netns: Make get_net_ns() handle zero refcount net + - net/sched: act_api: rely on rcu in tcf_idr_check_alloc + - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc() + - virtio_net: checksum offloading handling fix + - netfilter: ipset: Fix suspicious rcu_dereference_protected() + - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings + - regulator: core: Fix modpost error "regulator_get_regmap" undefined + - dmaengine: ioatdma: Fix missing kmem_cache_destroy() + - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is + fine." + - drm/radeon: fix UBSAN warning in kv_dpm.c + - gcov: add support for GCC 14 + - i2c: ocores: set IACK bit after core is enabled + - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat + - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat + - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat + - arm64: dts: qcom: qcs404: fix bluetooth device address + - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test + - Revert "kheaders: substituting --sort in archive creation" + - kheaders: explicitly define file modes for archived headers + - perf/core: Fix missing wakeup when waiting for context reference + - PCI: Add PCI_ERROR_RESPONSE and related definitions + - x86/amd_nb: Check for invalid SMN reads + - iio: dac: ad5592r-base: Replace indio_dev->mlock with own device lock + - iio: dac: ad5592r: un-indent code-block for scale read + - iio: dac: ad5592r: fix temperature channel scaling value + - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins + - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins + - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set + - drm/amdgpu: fix UBSAN warning in kv_dpm.c + - netfilter: nf_tables: validate family when identifying table via handle + - ASoC: fsl-asoc-card: set priv->pdev before using it + - net: dsa: microchip: fix initial port flush problem + - net: phy: mchp: Add support for LAN8814 QUAD PHY + - net: phy: micrel: add Microchip KSZ 9477 to the device table + - sparc: fix old compat_sys_select() + - parisc: use correct compat recv/recvfrom syscalls + - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data + registers + - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep + - mtd: partitions: redboot: Added conversion of operands to a larger type + - net/iucv: Avoid explicit cpumask var allocation on stack + - net/dpaa2: Avoid explicit cpumask var allocation on stack + - ALSA: emux: improve patch ioctl data validation + - media: dvbdev: Initialize sbuf + - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message + - nvme: fixup comment for nvme RDMA Provider Type + - gpio: davinci: Validate the obtained number of IRQs + - x86: stop playing stack games in profile_pc() + - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos + - mmc: sdhci: Do not invert write-protect twice + - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro() + - iio: adc: ad7266: Fix variable checking bug + - iio: chemical: bme680: Fix pressure value output + - iio: chemical: bme680: Fix calibration data variable + - iio: chemical: bme680: Fix overflows in compensate() functions + - iio: chemical: bme680: Fix sensor data read operation + - net: usb: ax88179_178a: improve link status logs + - usb: gadget: printer: SS+ support + - usb: musb: da8xx: fix a resource leak in probe() + - usb: atm: cxacru: fix endpoint checking in cxacru_bind() + - tty: mcf: MCF54418 has 10 UARTS + - net: can: j1939: Initialize unused data in j1939_send_one() + - net: can: j1939: recover socket queue on CAN bus error during BAM + transmission + - net: can: j1939: enhanced error handling for tightly received RTS messages + in xtp_rx_rts_session_new + - csky, hexagon: fix broken sys_sync_file_range + - hexagon: fix fadvise64_64 calling conventions + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes + - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes + - batman-adv: Don't accept TT entries for out-of-spec VIDs + - ata: libata-core: Fix double free on error + - ftruncate: pass a signed offset + - mtd: spinand: macronix: Add support for serial NAND flash + - pwm: stm32: Refuse too small period requests + - nfs: Leave pages in the pagecache if readpage failed + - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node + - arm64: dts: rockchip: Add sound-dai-cells for RK3368 + - Linux 5.4.279 + * CVE-2024-26921 + - skbuff: introduce skb_expand_head() + - skb_expand_head() adjust skb->truesize incorrectly + - inet: inet_defrag: prevent sk release while still in use + * CVE-2024-26929 + - scsi: qla2xxx: Fix double free of fcport + * CVE-2024-39484 + - mmc: davinci: Don't strip remove function when driver is builtin + * CVE-2024-36901 + - ipv6: prevent NULL dereference in ip6_output() + * CVE-2024-26830 + - i40e: Refactoring VF MAC filters counting to make more reliable + - i40e: Fix MAC address setting for a VF via Host/VM + - i40e: Do not allow untrusted VF to remove administratively set MAC + * CVE-2024-24860 + - Bluetooth: Fix atomicity violation in {min, max}_key_size_set + * CVE-2023-52760 + - gfs2: Fix slab-use-after-free in gfs2_qd_dealloc + * CVE-2024-2201 + - [Config] Set SPECTRE_BHI_ON=y + * CVE-2023-52629 + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + * CVE-2021-46926 + - ALSA: hda: intel-sdw-acpi: harden detection of controller + + -- Philip Cox Fri, 16 Aug 2024 15:20:27 -0400 + +linux-oracle (5.4.0-1130.139) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1130.139 -proposed tracker (LP: #2075799) + + [ Ubuntu: 5.4.0-193.213 ] + + * focal/linux: 5.4.0-193.213 -proposed tracker (LP: #2075804) + * CVE-2024-26921 + - skbuff: introduce skb_expand_head() + - skb_expand_head() adjust skb->truesize incorrectly + - inet: inet_defrag: prevent sk release while still in use + * CVE-2024-26929 + - scsi: qla2xxx: Fix double free of fcport + * CVE-2024-39484 + - mmc: davinci: Don't strip remove function when driver is builtin + * CVE-2024-36901 + - ipv6: prevent NULL dereference in ip6_output() + * CVE-2024-26830 + - i40e: Refactoring VF MAC filters counting to make more reliable + - i40e: Fix MAC address setting for a VF via Host/VM + - i40e: Do not allow untrusted VF to remove administratively set MAC + * CVE-2024-24860 + - Bluetooth: Fix atomicity violation in {min, max}_key_size_set + * CVE-2023-52760 + - gfs2: Fix slab-use-after-free in gfs2_qd_dealloc + * CVE-2024-2201 + - [Config] Set SPECTRE_BHI_ON=y + * CVE-2023-52629 + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + * CVE-2021-46926 + - ALSA: hda: intel-sdw-acpi: harden detection of controller + + -- Philip Cox Wed, 07 Aug 2024 10:01:27 -0400 + +linux-oracle (5.4.0-1129.138) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1129.138 -proposed tracker (LP: #2072300) + + [ Ubuntu: 5.4.0-192.212 ] + + * focal/linux: 5.4.0-192.212 -proposed tracker (LP: #2072305) + * Focal update: v5.4.278 upstream stable release (LP: #2071668) + - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs + - speakup: Fix sizeof() vs ARRAY_SIZE() bug + - ring-buffer: Fix a race between readers and resize checks + - net: smc91x: Fix m68k kernel compilation for ColdFire CPU + - nilfs2: fix unexpected freezing of nilfs_segctor_sync() + - nilfs2: fix potential hang in nilfs_detach_log_writer() + - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt + class + - net: usb: qmi_wwan: add Telit FN920C04 compositions + - drm/amd/display: Set color_mgmt_changed to true on unsuspend + - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating + - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property + - ASoC: da7219-aad: fix usage of device_get_named_child_node() + - drm/amdkfd: Flush the process wq before creating a kfd_process + - nvme: find numa distance only if controller has valid numa id + - openpromfs: finish conversion to the new mount API + - crypto: bcm - Fix pointer arithmetic + - firmware: raspberrypi: Use correct device for DMA mappings + - ecryptfs: Fix buffer size for tag 66 packet + - nilfs2: fix out-of-range warning + - parisc: add missing export of __cmpxchg_u8() + - crypto: ccp - drop platform ifdef checks + - s390/cio: fix tracepoint subchannel type field + - jffs2: prevent xattr node from overflowing the eraseblock + - null_blk: Fix missing mutex_destroy() at module removal + - md: fix resync softlockup when bitmap size is less than array size + - wifi: ath10k: poll service ready message before failing + - x86/boot: Ignore relocations in .notes sections in walk_relocs() too + - qed: avoid truncating work queue length + - scsi: ufs: qcom: Perform read back after writing reset bit + - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV + - scsi: ufs: core: Perform read back after disabling interrupts + - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL + - irqchip/alpine-msi: Fix off-by-one in allocation error path + - ACPI: disable -Wstringop-truncation + - cpufreq: Reorganize checks in cpufreq_offline() + - cpufreq: Split cpufreq_offline() + - cpufreq: Rearrange locking in cpufreq_remove_dev() + - cpufreq: exit() callback is optional + - scsi: libsas: Fix the failure of adding phy with zero-address to port + - scsi: hpsa: Fix allocation size for Scsi_Host private data + - x86/purgatory: Switch to the position-independent small code model + - wifi: ath10k: Fix an error code problem in + ath10k_dbg_sta_write_peer_debug_trigger() + - wifi: ath10k: populate board data for WCN3990 + - tcp: minor optimization in tcp_add_backlog() + - tcp: fix a signed-integer-overflow bug in tcp_add_backlog() + - tcp: avoid premature drops in tcp_add_backlog() + - macintosh/via-macii: Fix "BUG: sleeping function called from invalid + context" + - wifi: carl9170: add a proper sanity check for endpoints + - wifi: ar5523: enable proper endpoint verification + - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe() + - Revert "sh: Handle calling csum_partial with misaligned data" + - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors + - scsi: bfa: Ensure the copied buf is NUL terminated + - scsi: qedf: Ensure the copied buf is NUL terminated + - wifi: mwl8k: initialize cmd->addr[] properly + - usb: aqc111: stop lying about skb->truesize + - net: usb: sr9700: stop lying about skb->truesize + - m68k: Fix spinlock race in kernel thread creation + - m68k: mac: Fix reboot hang on Mac IIci + - net: ethernet: cortina: Locking fixes + - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg + - net: usb: smsc95xx: stop lying about skb->truesize + - net: openvswitch: fix overwriting ct original tuple for ICMPv6 + - ipv6: sr: add missing seg6_local_exit + - ipv6: sr: fix incorrect unregister order + - ipv6: sr: fix invalid unregister error path + - drm/amd/display: Fix potential index out of bounds in color transformation + function + - mtd: rawnand: hynix: fixed typo + - fbdev: shmobile: fix snprintf truncation + - drm/mediatek: Add 0 size check to mtk_drm_gem_obj + - powerpc/fsl-soc: hide unused const variable + - fbdev: sisfb: hide unused variables + - media: ngene: Add dvb_ca_en50221_init return value check + - media: radio-shark2: Avoid led_names truncations + - platform/x86: wmi: Make two functions static + - fbdev: sh7760fb: allow modular build + - drm/arm/malidp: fix a possible null pointer dereference + - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value + - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector + - RDMA/hns: Use complete parentheses in macros + - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map + - ext4: avoid excessive credit estimate in ext4_tmpfile() + - sunrpc: removed redundant procp check + - SUNRPC: Fix gss_free_in_token_pages() + - selftests/kcmp: Make the test output consistent and clear + - selftests/kcmp: remove unused open mode + - RDMA/IPoIB: Fix format truncation compilation errors + - netrom: fix possible dead-lock in nr_rt_ioctl() + - af_packet: do not call packet_read_pending() from tpacket_destruct_skb() + - sched/topology: Don't set SD_BALANCE_WAKE on cpuset domain relax + - sched/fair: Allow disabling sched_balance_newidle with + sched_relax_domain_level + - greybus: lights: check return of get_channel_from_mode + - soundwire: cadence/intel: simplify PDI/port mapping + - soundwire: intel: don't filter out PDI0/1 + - soundwire: cadence_master: improve PDI allocation + - soundwire: cadence: fix invalid PDI offset + - dmaengine: idma64: Add check for dma_set_max_seg_size + - firmware: dmi-id: add a release callback function + - serial: max3100: Lock port->lock when calling uart_handle_cts_change() + - serial: max3100: Update uart_driver_registered on driver removal + - serial: max3100: Fix bitwise types + - greybus: arche-ctrl: move device table to its right location + - iio: pressure: dps310: support negative temperature values + - microblaze: Remove gcc flag for non existing early_printk.c file + - microblaze: Remove early printk call from cpuinfo-static.c + - usb: gadget: u_audio: Clear uac pointer when freed. + - stm class: Fix a double free in stm_register_device() + - ppdev: Remove usage of the deprecated ida_simple_xx() API + - ppdev: Add an error check in register_device + - extcon: max8997: select IRQ_DOMAIN instead of depending on it + - f2fs: fix to release node block count in error path of f2fs_new_node_page() + - serial: sh-sci: protect invalidating RXDMA on shutdown + - libsubcmd: Fix parse-options memory leak + - Input: ims-pcu - fix printf string overflow + - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation + - drm/msm/dpu: Always flush the slave INTF on the CTL + - um: Fix return value in ubd_init() + - um: Add winch to winch_handlers before registering winch IRQ + - media: stk1160: fix bounds checking in stk1160_copy_video() + - scsi: qla2xxx: Replace all non-returning strlcpy() with strscpy() + - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp + - um: Fix the -Wmissing-prototypes warning for __switch_mm + - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh + - media: cec: cec-api: add locking in cec_release() + - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION() + - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when + UNWINDER_FRAME_POINTER=y + - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS + - nfc: nci: Fix uninit-value in nci_rx_work + - sunrpc: fix NFSACL RPC retry on soft mount + - ipv6: sr: fix memleak in seg6_hmac_init_algo + - params: lift param_set_uint_minmax to common code + - tcp: Fix shift-out-of-bounds in dctcp_update_alpha(). + - openvswitch: Set the skbuff pkt_type for proper pmtud support. + - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY + - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails + - net: fec: avoid lock evasion when reading pps_enable + - nfc: nci: Fix kcov check in nci_rx_work() + - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work() + - netfilter: nfnetlink_queue: acquire rcu_read_lock() in + instance_destroy_rcu() + - spi: Don't mark message DMA mapped when no transfer in it is + - nvmet: fix ns enable/disable possible hang + - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer + exhaustion + - dma-buf/sw-sync: don't enable IRQ from sync_print_obj() + - enic: Validate length of nl attributes in enic_set_vf_port + - smsc95xx: remove redundant function arguments + - smsc95xx: use usbnet->driver_priv + - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM + - net:fec: Add fec_enet_deinit() + - netfilter: tproxy: bail out if IP has been disabled on the device + - kconfig: fix comparison to constant symbols, 'm', 'n' + - spi: stm32: Don't warn about spurious interrupts + - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound + - ALSA: timer: Set lower bound of start tick time + - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline + - SUNRPC: Fix loop termination condition in gss_free_in_token_pages() + - binder: fix max_thread type inconsistency + - mmc: core: Do not force a retune before RPMB switch + - io_uring: fail NOP if non-zero op flags is passed in + - afs: Don't cross .backup mountpoint from backup volume + - nilfs2: fix use-after-free of timer for log writer thread + - vxlan: Fix regression when dropping packets due to invalid src addresses + - x86/mm: Remove broken vsyscall emulation code from the page fault code + - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode() + - media: lgdt3306a: Add a check against null-pointer-def + - drm/amdgpu: add error handle to avoid out-of-bounds + - ata: pata_legacy: make legacy_exit() work again + - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx + - arm64: tegra: Correct Tegra132 I2C alias + - md/raid5: fix deadlock that raid5d() wait for itself to clear + MD_SB_CHANGE_PENDING + - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU + - arm64: dts: hi3798cv200: fix the size of GICR + - media: mc: mark the media devnode as registered from the, start + - media: mxl5xx: Move xpt structures off stack + - media: v4l2-core: hold videodev_lock until dev reg, finishes + - fbdev: savage: Handle err return when savagefb_check_var failed + - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode + - crypto: ecrdsa - Fix module auto-load on add_key + - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak + - net/ipv6: Fix route deleting failure when metric equals 0 + - net/9p: fix uninit-value in p9_client_rpc() + - intel_th: pci: Add Meteor Lake-S CPU support + - sparc64: Fix number of online CPUs + - kdb: Fix buffer overflow during tab-complete + - kdb: Use format-strings rather than '\0' injection in kdb_read() + - kdb: Fix console handling when editing and tab-completing commands + - kdb: Merge identical case statements in kdb_read() + - kdb: Use format-specifiers rather than memset() for padding in kdb_read() + - net: fix __dst_negative_advice() race + - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING + - sparc: move struct termio to asm/termios.h + - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find() + - s390/ap: Fix crash in AP internal function modify_bitmap() + - nfs: fix undefined behavior in nfs_block_bits() + - Linux 5.4.278 + * CVE-2024-27019 + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get() + * CVE-2024-26886 + - Bluetooth: af_bluetooth: Fix deadlock + * CVE-2023-52752 + - smb: client: fix use-after-free bug in cifs_debug_data_proc_show() + * CVE-2022-48674 + - erofs: fix pcluster use-after-free on UP platforms + * Focal update: v5.4.277 upstream stable release (LP: #2070179) + - pinctrl: core: handle radix_tree_insert() errors in + pinctrl_register_one_pin() + - ext4: fix bug_on in __es_tree_search + - Revert "selftests: mm: fix map_hugetlb failure on 64K page size systems" + - Revert "net: bcmgenet: use RGMII loopback for MAC reset" + - net: bcmgenet: keep MAC in reset until PHY is up + - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access + - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode() + - net: bcmgenet: synchronize UMAC_CMD access + - smb: client: fix potential OOBs in smb2_parse_contexts() + - arm64: dts: qcom: Fix 'interrupt-map' parent address cells + - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks() + - drm/amdgpu: Fix possible NULL dereference in + amdgpu_ras_query_error_status_helper() + - usb: typec: ucsi: displayport: Fix potential deadlock + - serial: kgdboc: Fix NMI-safety problems from keyboard reset code + - docs: kernel_include.py: Cope with docutils 0.21 + - Linux 5.4.277 + * Focal update: v5.4.276 upstream stable release (LP: #2069758) + - dmaengine: pl330: issue_pending waits until WFP state + - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state" + - wifi: nl80211: don't free NULL coalescing rule + - pinctrl: core: delete incorrect free in pinctrl_enable() + - pinctrl: mediatek: Check gpio pin number and use binary search in + mtk_hw_pin_field_lookup() + - pinctrl: mediatek: Supporting driving setting without mapping current to + register value + - pinctrl: mediatek: Refine mtk_pinconf_get() and mtk_pinconf_set() + - pinctrl: mediatek: Refine mtk_pinconf_get() + - pinctrl: mediatek: Backward compatible to previous Mediatek's bias-pull + usage + - pinctrl: mediatek: remove shadow variable declaration + - pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback + - pinctrl: mediatek: paris: Rework mtk_pinconf_{get,set} switch/case logic + - pinctrl: mediatek: paris: Rework support for + PIN_CONFIG_{INPUT,OUTPUT}_ENABLE + - sunrpc: add a struct rpc_stats arg to rpc_create_args + - nfs: expose /proc/net/sunrpc/nfs in net namespaces + - nfs: make the rpc_stat per net namespace + - nfs: Handle error of rpc_proc_register() in nfs_net_init(). + - power: rt9455: hide unused rt9455_boost_voltage_values + - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map() + - s390/mm: Fix storage key clearing for guest huge pages + - s390/mm: Fix clearing storage keys for huge pages + - bna: ensure the copied buf is NUL terminated + - nsh: Restore skb->{protocol,data,mac_header} for outer header in + nsh_gso_segment(). + - net l2tp: drop flow hash on forward + - net: qede: use return from qede_parse_flow_attr() for flow_spec + - net: dsa: mv88e6xxx: Add number of MACs in the ATU + - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341 + - net: bridge: fix multicast-to-unicast with fraglist GSO + - tipc: fix a possible memleak in tipc_buf_append + - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change + - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic + - gfs2: Fix invalid metadata access in punch_hole + - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc + - wifi: cfg80211: fix rdev_dump_mpp() arguments order + - net: mark racy access on sk->sk_rcvbuf + - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload + - ALSA: line6: Zero-initialize message buffers + - net: bcmgenet: Reset RBUF on first open + - ata: sata_gemini: Check clk_enable() result + - firewire: ohci: mask bus reset interrupts between ISR and bottom half + - tools/power turbostat: Fix added raw MSR output + - tools/power turbostat: Fix Bzy_MHz documentation typo + - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve + - btrfs: always clear PERTRANS metadata during commit + - scsi: target: Fix SELinux error when systemd-modules loads the target module + - gpu: host1x: Do not setup DMA for virtual devices + - MIPS: scall: Save thread_info.syscall unconditionally on entry + - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior + - fs/9p: only translate RWX permissions for plain 9P2000 + - fs/9p: translate O_TRUNC into OTRUNC + - 9p: explicitly deny setlease attempts + - gpio: wcove: Use -ENOTSUPP consistently + - gpio: crystalcove: Use -ENOTSUPP consistently + - clk: Don't hold prepare_lock when calling kref_put() + - fs/9p: drop inodes immediately on non-.L too + - net:usb:qmi_wwan: support Rolling modules + - pinctrl: mediatek: Fix fallback call path + - xfrm: Preserve vlan tags for transport mode software GRO + - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets + - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique(). + - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout + - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout + - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation + - phonet: fix rtm_phonet_notify() skb allocation + - net: bridge: fix corrupted ethernet header on multicast-to-unicast + - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action() + - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr() + - net: qede: use return from qede_parse_flow_attr() for flower + - firewire: nosy: ensure user_length is taken into account when fetching + packet contents + - usb: gadget: composite: fix OS descriptors w_value logic + - usb: gadget: f_fs: Fix a race condition when processing setup packets. + - tipc: fix UAF in error path + - dyndbg: fix old BUG_ON in >control parser + - drm/vmwgfx: Fix invalid reads in fence signaled events + - net: fix out-of-bounds access in ops_init + - regulator: core: fix debugfs creation regression + - pinctrl: mediatek: Fix fallback behavior for bias_set_combo + - pinctrl: mediatek: Fix some off by one bugs + - pinctrl: mediatek: remove set but not used variable 'e' + - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback + - Linux 5.4.276 + * Freezing user space processes failed after 20.008 seconds (1 tasks refusing + to freeze, wq_busy=0) (LP: #2061091) + - ALSA: Fix deadlocks with kctl removals at disconnection + * CVE-2024-36016 + - tty: n_gsm: fix possible out-of-bounds in gsm0_receive() + * CVE-2022-48655 + - firmware: arm_scmi: Harden accesses to the reset domains + * CVE-2024-26907 + - RDMA/mlx5: Fix fortify source warning while accessing Eth segment + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26583 + - net/tls: Replace TLS_RX_SYNC_RUNNING with RCU + - net/tls: Fix use-after-free after the TLS device goes down and up + - tls: splice_read: fix record type check + - tls splice: remove inappropriate flags checking for MSG_PEEK + - tls: splice_read: fix accessing pre-processed records + - tls: Fix context leak on tls_device_down + - net/tls: Check for errors in tls_device_init + - net/tls: Remove the context from the list in tls_device_down + - net/tls: pass context to tls_device_decrypted() + - net/tls: Perform immediate device ctx cleanup when possible + - net/tls: Multi-threaded calls to TX tls_dev_del + - net: tls: avoid discarding data on record close + - tls: rx: don't store the record type in socket context + - tls: rx: don't store the decryption status in socket context + - tls: rx: don't issue wake ups when data is decrypted + - tls: rx: refactor decrypt_skb_update() + - tls: hw: rx: use return value of tls_device_decrypted() to carry status + - tls: rx: drop unnecessary arguments from tls_setup_from_iter() + - tls: rx: don't report text length from the bowels of decrypt + - tls: rx: wrap decryption arguments in a structure + - tls: rx: factor out writing ContentType to cmsg + - tls: rx: don't track the async count + - tls: rx: assume crypto always calls our callback + - tls: rx: use async as an in-out argument + - tls: decrement decrypt_pending if no async completion will be called + - net: tls: fix async vs NIC crypto offload + - tls: rx: simplify async wait + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + + -- Philip Cox Wed, 24 Jul 2024 10:47:04 +0300 + +linux-oracle (5.4.0-1128.137) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1128.137 -proposed tracker (LP: #2072103) + + [ Ubuntu: 5.4.0-190.210 ] + + * focal/linux: 5.4.0-190.210 -proposed tracker (LP: #2072108) + * CVE-2024-36016 + - tty: n_gsm: fix possible out-of-bounds in gsm0_receive() + * CVE-2022-48655 + - firmware: arm_scmi: Harden accesses to the reset domains + * CVE-2024-26907 + - RDMA/mlx5: Fix fortify source warning while accessing Eth segment + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26583 + - net/tls: Replace TLS_RX_SYNC_RUNNING with RCU + - net/tls: Fix use-after-free after the TLS device goes down and up + - tls: splice_read: fix record type check + - tls splice: remove inappropriate flags checking for MSG_PEEK + - tls: splice_read: fix accessing pre-processed records + - tls: Fix context leak on tls_device_down + - net/tls: Check for errors in tls_device_init + - net/tls: Remove the context from the list in tls_device_down + - net/tls: pass context to tls_device_decrypted() + - net/tls: Perform immediate device ctx cleanup when possible + - net/tls: Multi-threaded calls to TX tls_dev_del + - net: tls: avoid discarding data on record close + - tls: rx: don't store the record type in socket context + - tls: rx: don't store the decryption status in socket context + - tls: rx: don't issue wake ups when data is decrypted + - tls: rx: refactor decrypt_skb_update() + - tls: hw: rx: use return value of tls_device_decrypted() to carry status + - tls: rx: drop unnecessary arguments from tls_setup_from_iter() + - tls: rx: don't report text length from the bowels of decrypt + - tls: rx: wrap decryption arguments in a structure + - tls: rx: factor out writing ContentType to cmsg + - tls: rx: don't track the async count + - tls: rx: assume crypto always calls our callback + - tls: rx: use async as an in-out argument + - tls: decrement decrypt_pending if no async completion will be called + - net: tls: fix async vs NIC crypto offload + - tls: rx: simplify async wait + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + + -- Philip Cox Thu, 18 Jul 2024 11:45:44 +0300 + +linux-oracle (5.4.0-1127.136) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1127.136 -proposed tracker (LP: #2068448) + + [ Ubuntu: 5.4.0-189.209 ] + + * focal/linux: 5.4.0-189.209 -proposed tracker (LP: #2068454) + * Focal update: v5.4.275 upstream stable release (LP: #2067865) + - batman-adv: Avoid infinite loop trying to resize local TT + - Bluetooth: Fix memory leak in hci_req_sync_complete() + - nouveau: fix function cast warning + - net: openvswitch: fix unwanted error log on timeout policy probing + - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file + - geneve: fix header validation in geneve[6]_xmit_skb + - ipv6: fib: hide unused 'pn' variable + - ipv4/route: avoid unused-but-set-variable warning + - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr + - net/mlx5: Properly link new fs rules into the tree + - net: ena: Fix potential sign extension issue + - btrfs: qgroup: correctly model root qgroup rsv in convert + - drm/client: Fully protect modes[] with dev->mode_config.mutex + - vhost: Add smp_rmb() in vhost_vq_avail_empty() + - selftests: timers: Fix abs() warning in posix_timers test + - x86/apic: Force native_apic_mem_read() to use the MOV instruction + - btrfs: record delayed inode root in transaction + - selftests/ftrace: Limit length in subsystem-enable tests + - kprobes: Fix possible use-after-free issue on kprobe registration + - Revert "tracing/trigger: Fix to return error if failed to alloc snapshot" + - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get() + - tun: limit printing rate when illegal packet received by tun dev + - RDMA/rxe: Fix the problem "mutex_destroy missing" + - RDMA/mlx5: Fix port number for counter query in multi-port configuration + - drm: nv04: Fix out of bounds access + - clk: Remove prepare_lock hold assertion in __clk_release() + - clk: Mark 'all_lists' as const + - clk: remove extra empty line + - clk: Print an info line before disabling unused clocks + - clk: Initialize struct clk_core kref earlier + - clk: Get runtime PM before walking tree during disable_unused + - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ + - comedi: vmk80xx: fix incomplete endpoint checking + - serial/pmac_zilog: Remove flawed mitigation for rx irq flood + - USB: serial: option: add Fibocom FM135-GL variants + - USB: serial: option: add support for Fibocom FM650/FG650 + - USB: serial: option: add Lonsung U8300/U9300 product + - USB: serial: option: support Quectel EM060K sub-models + - USB: serial: option: add Rolling RW101-GL and RW135-GL support + - USB: serial: option: add Telit FN920C04 rmnet compositions + - usb: dwc2: host: Fix dereference issue in DDMA completion flow. + - speakup: Avoid crash on very long word + - fs: sysfs: Fix reference leak in sysfs_break_active_protection() + - nouveau: fix instmem race condition around ptr stores + - nilfs2: fix OOB in nilfs_set_de_type + - KVM: async_pf: Cleanup kvm_setup_async_pf() + - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma + - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma + - arm64: dts: mediatek: mt7622: fix IR nodename + - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible" + - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block + - arm64: dts: mt2712: add ethernet device node + - arm64: dts: mediatek: mt2712: fix validation errors + - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property + - vxlan: drop packets from invalid src-address + - mlxsw: core: Unregister EMAD trap using FORWARD action + - NFC: trf7970a: disable all regulators on removal + - net: usb: ax88179_178a: stop lying about skb->truesize + - net: gtp: Fix Use-After-Free in gtp_dellink + - ipvs: Fix checksumming on GSO of SCTP packets + - net: openvswitch: Fix Use-After-Free in ovs_ct_exit + - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update + - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash + - mlxsw: spectrum_acl_tcam: Rate limit error message + - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash + - mlxsw: spectrum_acl_tcam: Fix warning during rehash + - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage + - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work + - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue + - iavf: Fix TC config comparison with existing adapter TC config + - af_unix: Suppress false-positive lockdep splat for spin_lock() in + __unix_gc(). + - serial: core: Provide port lock wrappers + - serial: mxs-auart: add spinlock around changing cts state + - Revert "crypto: api - Disallow identical driver names" + - net/mlx5e: Fix a race in command alloc flow + - tracing: Show size of requested perf buffer + - tracing: Increase PERF_MAX_TRACE_SIZE to handle Sentinel1 and docker + together + - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old() + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853 + - btrfs: fix information leak in btrfs_ioctl_logical_to_ino() + - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma + - drm/amdgpu: Fix leak when GPU memory allocation fails + - irqchip/gic-v3-its: Prevent double free on error + - ethernet: Add helper for assigning packet type when dest address does not + match device address + - net: b44: set pause params only when interface is up + - stackdepot: respect __GFP_NOLOCKDEP allocation flag + - mtd: diskonchip: work around ubsan link failure + - tcp: Clean up kernel listener's reqsk in inet_twsk_purge() + - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge() + - dmaengine: owl: fix register access functions + - idma64: Don't try to serve interrupts when device is powered off + - i2c: smbus: fix NULL function pointer dereference + - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up + - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS + - udp: preserve the connected status if only UDP cmsg + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - Linux 5.4.275 + * Focal update: v5.4.274 upstream stable release (LP: #2067857) + - amdkfd: use calloc instead of kzalloc to avoid integer overflow + - Documentation/hw-vuln: Update spectre doc + - x86/cpu: Support AMD Automatic IBRS + - x86/bugs: Use sysfs_emit() + - timers: Update kernel-doc for various functions + - timers: Use del_timer_sync() even on UP + - timers: Rename del_timer_sync() to timer_delete_sync() + - media: staging: ipu3-imgu: Set fields before media_entity_pads_init() + - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd + - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr() + - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity() + - ARM: dts: mmp2-brownstone: Don't redeclare phandle references + - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts + - serial: max310x: fix NULL pointer dereference in I2C instantiation + - KVM: Always flush async #PF workqueue when vCPU is being destroyed + - sparc64: NMI watchdog: fix return value of __setup handler + - sparc: vDSO: fix return value of __setup handler + - crypto: qat - fix double free during reset + - crypto: qat - resolve race condition during AER recovery + - selftests/mqueue: Set timeout to 180 seconds + - ext4: correct best extent lstart adjustment logic + - fat: fix uninitialized field in nostale filehandles + - ubifs: Set page uptodate in the correct place + - ubi: Check for too small LEB size in VTBL code + - ubi: correct the calculation of fastmap size + - mtd: rawnand: meson: fix scrambling mode value in command macro + - parisc: Do not hardcode registers in checksum functions + - parisc: Fix ip_fast_csum + - parisc: Fix csum_ipv6_magic on 32-bit systems + - parisc: Fix csum_ipv6_magic on 64-bit systems + - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds + - PM: suspend: Set mem_sleep_current during kernel command line setup + - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays + - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays + - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays + - powerpc/fsl: Fix mfpmr build errors with newer binutils + - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB + - USB: serial: add device ID for VeriFone adapter + - USB: serial: cp210x: add ID for MGP Instruments PDS100 + - USB: serial: option: add MeiG Smart SLM320 product + - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M + - PM: sleep: wakeirq: fix wake irq warning in system suspend + - mmc: tmio: avoid concurrent runs of mmc_request_done() + - fuse: don't unhash root + - btrfs: fix off-by-one chunk length calculation at contains_pending_extent() + - PCI: Drop pci_device_remove() test of pci_dev->driver + - PCI/PM: Drain runtime-idle callbacks before driver removal + - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d"" + - dm-raid: fix lockdep waring in "pers->hot_add_disk" + - mmc: core: Fix switch on gp3 partition + - hwmon: (amc6821) add of_match table + - ext4: fix corruption during on-line resize + - firmware: meson_sm: Rework driver as a proper platform driver + - nvmem: meson-efuse: fix function pointer type mismatch + - slimbus: core: Remove usage of the deprecated ida_simple_xx() API + - speakup: Fix 8bit characters from direct synth + - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1 + - vfio/platform: Disable virqfds on cleanup + - ring-buffer: Fix resetting of shortest_full + - ring-buffer: Fix full_waiters_pending in poll + - soc: fsl: qbman: Always disable interrupts when taking cgr_lock + - soc: fsl: qbman: Add helper for sanity checking cgr ops + - soc: fsl: qbman: Add CGR update function + - soc: fsl: qbman: Use raw spinlock for cgr_lock + - s390/zcrypt: fix reference counting on zcrypt card objects + - drm/exynos: do not return negative values from .get_modes() + - drm/imx/ipuv3: do not return negative values from .get_modes() + - drm/vc4: hdmi: do not return negative values from .get_modes() + - memtest: use {READ,WRITE}_ONCE in memory scanning + - nilfs2: fix failure to detect DAT corruption in btree and direct mappings + - nilfs2: use a more common logging style + - nilfs2: prevent kernel bug at submit_bh_wbc() + - x86/CPU/AMD: Update the Zenbleed microcode revisions + - ahci: asm1064: correct count of reported ports + - ahci: asm1064: asm1166: don't limit reported ports + - dm snapshot: fix lockup in dm_exception_table_exit + - comedi: comedi_test: Prevent timers rescheduling during deletion + - netfilter: nf_tables: reject constant set with timeout + - xfrm: Avoid clang fortify warning in copy_to_user_tmpl() + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + - USB: usb-storage: Prevent divide-by-0 error in isd200_ata_command + - usb: gadget: ncm: Fix handling of zero block length packets + - usb: port: Don't try to peer unused USB ports based on location + - tty: serial: fsl_lpuart: avoid idle preamble pending if CTS is enabled + - vt: fix unicode buffer corruption when deleting characters + - fs/aio: Check IOCB_AIO_RW before the struct aio_kiocb conversion + - objtool: is_fentry_call() crashes if call has no destination + - objtool: Add support for intra-function calls + - x86/speculation: Support intra-function call validation + - xen/events: close evtchn after mapping cleanup + - printk: Update @console_may_schedule in console_trylock_spinning() + - btrfs: allocate btrfs_ioctl_defrag_range_args on stack + - Revert "loop: Check for overflow while configuring loop" + - loop: Call loop_config_discard() only after new config is applied + - loop: Remove sector_t truncation checks + - loop: Factor out setting loop device size + - loop: Refactor loop_set_status() size calculation + - loop: Factor out configuring loop from status + - loop: Check for overflow while configuring loop + - loop: loop_set_status_from_info() check before assignment + - perf/core: Fix reentry problem in perf_output_read_group() + - efivarfs: Request at most 512 bytes for variable names + - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS + - bounds: support non-power-of-two CONFIG_NR_CPUS + - vt: fix memory overlapping when deleting chars in the buffer + - mm/memory-failure: fix an incorrect use of tail pages + - mm/migrate: set swap entry values of THP tail pages properly. + - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes + - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack() + - mmc: core: Initialize mmc_blk_ioc_data + - mmc: core: Avoid negative index with array access + - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs + - scsi: core: Fix unremoved procfs host directory regression + - usb: dwc2: host: Fix remote wakeup from hibernation + - usb: dwc2: host: Fix hibernation flow + - usb: dwc2: host: Fix ISOC flow in DDMA mode + - usb: dwc2: gadget: LPM flow fix + - usb: udc: remove warning when queue disabled ep + - scsi: qla2xxx: Fix command flush on cable pull + - x86/cpu: Enable STIBP on AMD if Automatic IBRS is enabled + - scsi: lpfc: Correct size for wqe for memset() + - USB: core: Fix deadlock in usb_deauthorize_interface() + - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet + - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa() + - tcp: properly terminate timers for kernel sockets + - dm integrity: fix out-of-range warning + - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d + - Bluetooth: hci_event: set the conn encrypted before conn establishes + - Bluetooth: Fix TOCTOU in HCI debugfs implementation + - netfilter: nf_tables: disallow timeout for anonymous sets + - net/rds: fix possible cp null dereference + - vfio/pci: Disable auto-enable of exclusive INTx IRQ + - vfio/pci: Lock external INTx masking ops + - vfio: Introduce interface to flush virqfd inject workqueue + - vfio/pci: Create persistent INTx handler + - vfio/platform: Create persistent IRQ handlers + - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be + mapped." + - mm, vmscan: prevent infinite loop for costly GFP_NOIO | __GFP_RETRY_MAYFAIL + allocations + - netfilter: nf_tables: flush pending destroy work before exit_net release + - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get() + - bpf, sockmap: Prevent lock inversion deadlock in map delete elem + - net/sched: act_skbmod: prevent kernel-infoleak + - net: stmmac: fix rx queue priority assignment + - selftests: reuseaddr_conflict: add missing new line at the end of the output + - ipv6: Fix infinite recursion in fib6_dump_done(). + - i40e: fix vf may be used uninitialized in this function warning + - staging: mmal-vchiq: Allocate and free components as required + - staging: mmal-vchiq: Fix client_component for 64 bit kernel + - staging: vc04_services: changen strncpy() to strscpy_pad() + - staging: vc04_services: fix information leak in create_component() + - fs: add a vfs_fchown helper + - fs: add a vfs_fchmod helper + - initramfs: switch initramfs unpacking to struct file based APIs + - init: open /initrd.image with O_LARGEFILE + - erspan: Add type I version 0 support. + - erspan: make sure erspan_base_hdr is present in skb->head + - net: ravb: Always process TX descriptor ring + - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw + - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit + - scsi: mylex: Fix sysfs buffer lengths + - ata: sata_mv: Fix PCI device ID table declaration compilation warning + - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with + microphone + - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank() + - s390/entry: align system call table on 8 bytes + - wifi: ath9k: fix LNA selection in ath_ant_try_scan() + - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host() + - panic: Flush kernel log buffer at the end + - arm64: dts: rockchip: fix rk3328 hdmi ports node + - arm64: dts: rockchip: fix rk3399 hdmi ports node + - ionic: set adminq irq affinity + - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num() + - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks() + - btrfs: export: handle invalid inode or root reference in btrfs_get_parent() + - btrfs: send: handle path ref underflow in header iterate_inode_ref() + - Bluetooth: btintel: Fix null ptr deref in btintel_read_version + - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails + - sysv: don't call sb_bread() with pointers_lock held + - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc() + - isofs: handle CDs with bad root inode but good Joliet root directory + - media: sta2x11: fix irq handler cast + - drm/amd/display: Fix nanosec stat overflow + - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned + int + - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default" + - block: prevent division by zero in blk_rq_stat_sum() + - Input: allocate keycode for Display refresh rate toggle + - ktest: force $buildonly = 1 for 'make_warnings_file' test type + - tools: iio: replace seekdir() in iio_generic_buffer + - usb: typec: tcpci: add generic tcpci fallback compatible + - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined + - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2 + - fbmon: prevent division by zero in fb_videomode_from_videomode() + - netfilter: nf_tables: reject new basechain after table flag update + - netfilter: nf_tables: discard table flag update with pending basechain + deletion + - tty: n_gsm: require CAP_NET_ADMIN to attach N_GSM0710 ldisc + - drm/vkms: call drm_atomic_helper_shutdown before drm_dev_put() + - virtio: reenable config if freezing device failed + - x86/mm/pat: fix VM_PAT handling in COW mappings + - drm/i915/gt: Reset queue_priority_hint on parking + - x86/alternative: Don't call text_poke() in lazy TLB mode + - Bluetooth: btintel: Fixe build regression + - VMCI: Fix possible memcpy() run-time warning in + vmci_datagram_invoke_guest_handler() + - erspan: Check IFLA_GRE_ERSPAN_VER is set. + - ip_gre: do not report erspan version on GRE interface + - firmware: meson_sm: fix to avoid potential NULL pointer dereference + - Linux 5.4.274 + * CVE-2024-26586 + - mlxsw: spectrum_acl_tcam: Fix stack corruption + * CVE-2024-26923 + - af_unix: Do not use atomic ops for unix_sk(sk)->inflight. + - af_unix: Fix garbage collector racing against connect() + * Focal update: v5.4.273 upstream stable release (LP: #2064561) + - io_uring/unix: drop usage of io_uring socket + - io_uring: drop any code related to SCM_RIGHTS + - selftests: tls: use exact comparison in recv_partial + - ASoC: rt5645: Make LattePanda board DMI match more precise + - x86/xen: Add some null pointer checking to smp.c + - MIPS: Clear Cause.BD in instruction_pointer_set + - HID: multitouch: Add required quirk for Synaptics 0xcddc device + - RDMA/mlx5: Relax DEVX access upon modify commands + - net/iucv: fix the allocation size of iucv_path_table array + - parisc/ftrace: add missing CONFIG_DYNAMIC_FTRACE check + - block: sed-opal: handle empty atoms when parsing response + - dm-verity, dm-crypt: align "struct bvec_iter" correctly + - btrfs: fix data race at btrfs_use_block_rsv() when accessing block reserve + - scsi: mpt3sas: Prevent sending diag_reset when the controller is ready + - Bluetooth: rfcomm: Fix null-ptr-deref in rfcomm_check_security + - firewire: core: use long bus reset on gap count error + - ASoC: Intel: bytcr_rt5640: Add an extra entry for the Chuwi Vi8 tablet + - Input: gpio_keys_polled - suppress deferred probe error for gpio + - ASoC: wm8962: Enable oscillator if selecting WM8962_FLL_OSC + - ASoC: wm8962: Enable both SPKOUTR_ENA and SPKOUTL_ENA in mono mode + - ASoC: wm8962: Fix up incorrect error message in wm8962_set_fll + - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak + - fs/select: rework stack allocation hack for clang + - timekeeping: Fix cross-timestamp interpolation on counter wrap + - timekeeping: Fix cross-timestamp interpolation corner case decision + - timekeeping: Fix cross-timestamp interpolation for non-x86 + - wifi: ath10k: fix NULL pointer dereference in + ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev() + - b43: dma: Fix use true/false for bool type variable + - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled + - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled + - b43: main: Fix use true/false for bool type + - wifi: b43: Stop correct queue in DMA worker when QoS is disabled + - wifi: b43: Disable QoS for bcm4331 + - wifi: wilc1000: fix declarations ordering + - wifi: wilc1000: fix RCU usage in connect path + - wifi: mwifiex: debugfs: Drop unnecessary error check for + debugfs_create_dir() + - sock_diag: annotate data-races around sock_diag_handlers[family] + - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc(). + - net: blackhole_dev: fix build warning for ethh set but not used + - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer() + - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes + - bpf: Add typecast to bpf helpers to help BTF generation + - bpf: Factor out bpf_spin_lock into helpers. + - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly + - arm64: dts: qcom: db820c: Move non-soc entries out of /soc + - arm64: dts: qcom: msm8996: Use node references in db820c + - arm64: dts: qcom: msm8996: Move regulator consumers to db820c + - arm64: dts: qcom: msm8996: Pad addresses + - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit() + - bus: tegra-aconnect: Update dependency to ARCH_TEGRA + - [Config]: Update tegra configs + - iommu/amd: Mark interrupt as managed + - wifi: brcmsmac: avoid function pointer casts + - net: ena: Remove ena_select_queue + - ARM: dts: arm: realview: Fix development chip ROM compatible value + - ARM: dts: imx6dl-yapp4: Move phy reset into switch node + - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address + - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node + - ACPI: scan: Fix device check notification handling + - x86, relocs: Ignore relocations in .notes section + - SUNRPC: fix some memleaks in gssx_dec_option_array + - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove + function + - igb: move PEROUT and EXTTS isr logic to separate functions + - igb: Fix missing time sync events + - Bluetooth: Remove superfluous call to hci_conn_check_pending() + - sr9800: Add check for usbnet_get_endpoints + - bpf: Fix hashtab overflow check on 32-bit arches + - bpf: Fix stackmap overflow check on 32-bit arches + - ipv6: fib6_rules: flush route cache when rule is changed + - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv() + - net: hns3: fix port duplex configure error in IMP reset + - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function + - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt() + function + - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function + - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function + - net/x25: fix incorrect parameter validation in the x25_getsockopt() function + - nfp: flower: handle acti_netdevs allocation failure + - dm raid: fix false positive for requeue needed during reshape + - dm: call the resume method on internal suspend + - drm/tegra: dsi: Add missing check for of_find_device_by_node + - gpu: host1x: mipi: Update tegra_mipi_request() to be node based + - drm/tegra: dsi: Make use of the helper function dev_err_probe() + - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe() + - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path + of tegra_dsi_probe() + - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths + of tegra_output_probe() + - drm/rockchip: inno_hdmi: Fix video timing + - drm: Don't treat 0 as -1 in drm_fixp2int_ceil + - drm/rockchip: lvds: do not overwrite error code + - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA + - media: tc358743: register v4l2 async device only after successful setup + - PCI/DPC: Print all TLP Prefixes, not just the first + - perf record: Fix possible incorrect free in record__switch_output() + - drm/amd/display: Fix potential NULL pointer dereferences in + 'dcn10_set_output_transfer_func()' + - perf evsel: Fix duplicate initialization of data->id in + evsel__parse_sample() + - media: em28xx: annotate unchecked call to media_device_register() + - media: v4l2-tpg: fix some memleaks in tpg_alloc + - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity + - media: edia: dvbdev: fix a use-after-free + - clk: qcom: reset: Allow specifying custom reset delay + - clk: qcom: reset: support resetting multiple bits + - clk: qcom: reset: Commonize the de/assert functions + - clk: qcom: reset: Ensure write completion on reset de/assertion + - quota: simplify drop_dquot_ref() + - quota: Fix potential NULL pointer dereference + - quota: Fix rcu annotations of inode dquot pointers + - PCI: switchtec: Fix an error handling path in switchtec_pci_probe() + - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str() + - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode() + - ALSA: seq: fix function cast warnings + - perf stat: Avoid metric-only segv + - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak + - media: go7007: add check of return value of go7007_read_addr() + - media: pvrusb2: remove redundant NULL check + - media: pvrusb2: fix pvr2_stream_callback casts + - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times + - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions + - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken + - clk: hisilicon: hi3519: Release the correct number of gates in + hi3519_clk_unregister() + - drm/tegra: put drm_gem_object ref on error in tegra_fb_create + - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref + - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a + ref + - crypto: arm/sha - fix function cast warnings + - mtd: maps: physmap-core: fix flash size larger than 32-bit + - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype + - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs + - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int() + - media: pvrusb2: fix uaf in pvr2_context_set_notify + - media: dvb-frontends: avoid stack overflow warnings with clang + - media: go7007: fix a memleak in go7007_load_encoder + - media: v4l2-core: correctly validate video and metadata ioctls + - media: rename VFL_TYPE_GRABBER to _VIDEO + - media: media/pci: rename VFL_TYPE_GRABBER to _VIDEO + - media: ttpci: fix two memleaks in budget_av_attach + - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip + - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks + - drm/msm/dpu: add division of drm_display_mode's hskew parameter + - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc. + - backlight: lm3630a: Initialize backlight_properties on init + - backlight: lm3630a: Don't set bl->props.brightness in get_brightness + - backlight: da9052: Fully initialize backlight_properties during probe + - backlight: lm3639: Fully initialize backlight_properties during probe + - backlight: lp8788: Fully initialize backlight_properties during probe + - sparc32: Fix section mismatch in leon_pci_grpci + - clk: Fix clk_core_get NULL dereference + - ALSA: usb-audio: Stop parsing channels bits when all channels are found. + - scsi: csiostor: Avoid function pointer casts + - RDMA/device: Fix a race between mad_client and cm_client init + - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn + - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr() + - watchdog: stm32_iwdg: initialize default timeout + - NFS: Fix an off by one in root_nfs_cat() + - afs: Revert "afs: Hide silly-rename files from userspace" + - tty: vt: fix 20 vs 0x20 typo in EScsiignore + - serial: max310x: fix syntax error in IRQ error message + - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT + - kconfig: fix infinite loop when expanding a macro at the end of file + - rtc: mt6397: select IRQ_DOMAIN instead of depending on it + - serial: 8250_exar: Don't remove GPIO device on suspend + - staging: greybus: fix get_channel_from_mode() failure path + - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin + - octeontx2-af: Use matching wake_up API variant in CGX command interface + - s390/vtime: fix average steal time calculation + - hsr: Fix uninit-value access in hsr_get_node() + - packet: annotate data-races around ignore_outgoing + - rds: introduce acquire/release ordering in acquire/release_in_xmit() + - hsr: Handle failures in module init + - net/bnx2x: Prevent access to a freed page in page_pool + - octeontx2-af: Use separate handlers for interrupts + - ARM: dts: sun8i-h2-plus-bananapi-m2-zero: add regulator nodes vcc-dram and + vcc1v2 + - netfilter: nf_tables: do not compare internal table flags on updates + - rcu: add a helper to report consolidated flavor QS + - bpf: report RCU QS in cpumap kthread + - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler + - regmap: Add missing map->bus check + - Linux 5.4.273 + * Focal update: v5.4.272 upstream stable release (LP: #2064555) + - lan78xx: Fix white space and style issues + - lan78xx: Add missing return code checks + - lan78xx: Fix partial packet errors on suspend/resume + - lan78xx: Fix race conditions in suspend/resume handling + - net: lan78xx: fix runtime PM count underflow on link stop + - ixgbe: {dis, en}able irqs in ixgbe_txrx_ring_{dis, en}able + - geneve: make sure to pull inner header in geneve_rx() + - net: ice: Fix potential NULL pointer dereference in ice_bridge_setlink() + - net/ipv6: avoid possible UAF in ip6_route_mpath_notify() + - net/rds: fix WARNING in rds_conn_connect_if_down + - netfilter: nft_ct: fix l3num expectations with inet pseudo family + - netfilter: nf_conntrack_h323: Add protection for bmp length out of range + - netrom: Fix a data-race around sysctl_netrom_default_path_quality + - netrom: Fix a data-race around sysctl_netrom_obsolescence_count_initialiser + - netrom: Fix data-races around sysctl_netrom_network_ttl_initialiser + - netrom: Fix a data-race around sysctl_netrom_transport_timeout + - netrom: Fix a data-race around sysctl_netrom_transport_maximum_tries + - netrom: Fix a data-race around sysctl_netrom_transport_acknowledge_delay + - netrom: Fix a data-race around sysctl_netrom_transport_busy_delay + - netrom: Fix a data-race around sysctl_netrom_transport_requested_window_size + - netrom: Fix a data-race around sysctl_netrom_transport_no_activity_timeout + - netrom: Fix a data-race around sysctl_netrom_routing_control + - netrom: Fix a data-race around sysctl_netrom_link_fails_count + - netrom: Fix data-races around sysctl_net_busy_read + - selftests: mm: fix map_hugetlb failure on 64K page size systems + - um: allow not setting extra rpaths in the linux binary + - serial: max310x: Use devm_clk_get_optional() to get the input clock + - serial: max310x: Try to get crystal clock rate from property + - serial: max310x: fail probe if clock crystal is unstable + - serial: max310x: Make use of device properties + - serial: max310x: use regmap methods for SPI batch operations + - serial: max310x: use a separate regmap for each port + - serial: max310x: prevent infinite while() loop in port startup + - Input: i8042 - fix strange behavior of touchpad on Clevo NS70PU + - hv_netvsc: Make netvsc/VF binding check both MAC and serial number + - hv_netvsc: use netif_is_bond_master() instead of open code + - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed + - y2038: rusage: use __kernel_old_timeval + - getrusage: add the "signal_struct *sig" local variable + - getrusage: move thread_group_cputime_adjusted() outside of + lock_task_sighand() + - getrusage: use __for_each_thread() + - getrusage: use sig->stats_lock rather than lock_task_sighand() + - serial: max310x: Unprepare and disable clock in error path + - regmap: allow to define reg_update_bits for no bus configuration + - regmap: Add bulk read/write callbacks into regmap_config + - serial: max310x: make accessing revision id interface-agnostic + - serial: max310x: implement I2C support + - serial: max310x: fix IO data corruption in batched operations + - arm64: dts: qcom: add PDC interrupt controller for SDM845 + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - Linux 5.4.272 + * CVE-2024-23307 + - md/raid5: fix atomicity violation in raid5_cache_count + * CVE-2024-26889 + - Bluetooth: hci_core: Fix possible buffer overflow + * CVE-2024-26828 + - cifs: fix underflow in parse_server_interfaces() + * CVE-2024-24861 + - media: xc4000: Fix atomicity violation in xc4000_get_frequency + * CVE-2023-6270 + - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts + * CVE-2024-26642 + - netfilter: nf_tables: disallow anonymous set with timeout flag + * CVE-2024-26926 + - binder: check offset alignment in binder_get_object() + * CVE-2024-26922 + - drm/amdgpu: validate the parameters of bo mapping operations more clearly + * CVE-2024-26925 + - netfilter: Cleanup nft_net->module_list from nf_tables_exit_net() + - netfilter: nf_tables: release batch on table validation from abort path + - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path + * CVE-2024-26643 + - netfilter: nf_tables: mark set as dead when unbinding anonymous set with + timeout + * CVE-2024-2201 + - x86/cpufeatures: Add new word for scattered features + - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - [Config] updateconfigs for CONFIG_BHI_{AUTO|ON|OFF} + - x86/bugs: Fix BHI documentation + - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES + - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' + - x86/bugs: Fix BHI handling of RRSBA + - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation + - x86/bugs: Fix BHI retpoline check + + -- Philip Cox Fri, 21 Jun 2024 13:34:32 -0400 + +linux-oracle (5.4.0-1126.135) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1126.135 -proposed tracker (LP: #2068286) + + [ Ubuntu: 5.4.0-187.207 ] + + * focal/linux: 5.4.0-187.207 -proposed tracker (LP: #2068291) + * CVE-2024-26925 + - netfilter: Cleanup nft_net->module_list from nf_tables_exit_net() + - netfilter: nf_tables: release batch on table validation from abort path + - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path + * CVE-2024-26643 + - netfilter: nf_tables: mark set as dead when unbinding anonymous set with + timeout + * CVE-2024-2201 + - x86/cpufeatures: Add new word for scattered features + - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - [Config] updateconfigs for CONFIG_BHI_{AUTO|ON|OFF} + - x86/bugs: Fix BHI documentation + - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES + - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr' + - x86/bugs: Fix BHI handling of RRSBA + - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation + - x86/bugs: Fix BHI retpoline check + + -- Philip Cox Thu, 13 Jun 2024 13:13:09 -0400 + +linux-oracle (5.4.0-1125.134) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1125.134 -proposed tracker (LP: #2063806) + + [ Ubuntu: 5.4.0-186.206 ] + + * focal/linux: 5.4.0-186.206 -proposed tracker (LP: #2063812) + * Mount CIFS fails with Permission denied (LP: #2061986) + - cifs: fix ntlmssp auth when there is no key exchange + * USB stick can't be detected (LP: #2040948) + - usb: Disable USB3 LPM at shutdown + * CVE-2024-26733 + - net: dev: Convert sa_data to flexible array in struct sockaddr + - arp: Prevent overflow in arp_req_get(). + - stddef: Introduce DECLARE_FLEX_ARRAY() helper + * CVE-2024-26712 + - powerpc/kasan: Fix addr error caused by page alignment + * CVE-2023-52530 + - wifi: mac80211: fix potential key use-after-free + * CVE-2021-47063 + - drm: bridge/panel: Cleanup connector on bridge detach + * [Ubuntu 22.04.4/linux-image-6.5.0-26-generic] Kernel output "UBSAN: array- + index-out-of-bounds in /build/linux-hwe-6.5-34pCLi/linux- + hwe-6.5-6.5.0/drivers/net/hyperv/netvsc.c:1445:41" multiple times, + especially during boot. (LP: #2058477) + - hv: hyperv.h: Replace one-element array with flexible-array member + * CVE-2024-26614 + - tcp: make sure init the accept_queue's spinlocks once + - ipv6: init the accept_queue's spinlocks in inet6_create + * Focal update: v5.4.271 upstream stable release (LP: #2060216) + - netlink: Fix kernel-infoleak-after-free in __skb_datagram_iter + - net: ip_tunnel: prevent perpetual headroom growth + - tun: Fix xdp_rxq_info's queue_index when detaching + - ipv6: fix potential "struct net" leak in inet6_rtm_getaddr() + - lan78xx: enable auto speed configuration for LAN7850 if no EEPROM is + detected + - net: usb: dm9601: fix wrong return value in dm9601_mdio_read + - Bluetooth: Avoid potential use-after-free in hci_error_reset + - Bluetooth: hci_event: Fix handling of HCI_EV_IO_CAPA_REQUEST + - Bluetooth: Enforce validation on max value of connection interval + - netfilter: nf_tables: allow NFPROTO_INET in nft_(match/target)_validate() + - rtnetlink: fix error logic of IFLA_BRIDGE_FLAGS writing back + - efi/capsule-loader: fix incorrect allocation size + - power: supply: bq27xxx-i2c: Do not free non existing IRQ + - ALSA: Drop leftover snd-rtctimer stuff from Makefile + - afs: Fix endless loop in directory parsing + - gtp: fix use-after-free and null-ptr-deref in gtp_newlink() + - wifi: nl80211: reject iftype change with mesh ID change + - btrfs: dev-replace: properly validate device names + - dmaengine: fsl-qdma: fix SoC may hang on 16 byte unaligned read + - dmaengine: fsl-qdma: init irq after reg initialization + - mmc: core: Fix eMMC initialization with 1-bit bus connection + - x86/cpu/intel: Detect TME keyid bits before setting MTRR mask registers + - cachefiles: fix memory leak in cachefiles_add_cache() + - fs,hugetlb: fix NULL pointer dereference in hugetlbs_fill_super + - gpio: 74x164: Enable output pins after registers are reset + - Linux 5.4.271 + * Focal update: v5.4.270 upstream stable release (LP: #2060019) + - KVM: arm64: vgic-its: Test for valid IRQ in its_sync_lpi_pending_table() + - KVM: arm64: vgic-its: Test for valid IRQ in MOVALL handler + - net/sched: Retire CBQ qdisc + - [Config] updateconfigs for NET_SCH_CBQ + - net/sched: Retire ATM qdisc + - [Config] updateconfigs for NET_SCH_ATM + - net/sched: Retire dsmark qdisc + - [Config] updateconfigs for NET_SCH_DSMARK + - sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset + - memcg: add refcnt for pcpu stock to avoid UAF problem in drain_all_stock() + - nilfs2: replace WARN_ONs for invalid DAT metadata block requests + - userfaultfd: fix mmap_changing checking in mfill_atomic_hugetlb + - sched/rt: Fix sysctl_sched_rr_timeslice intial value + - sched/rt: Disallow writing invalid values to sched_rt_period_us + - scsi: target: core: Add TMF to tmr_list handling + - dmaengine: shdma: increase size of 'dev_id' + - dmaengine: fsl-qdma: increase size of 'irq_name' + - wifi: cfg80211: fix missing interfaces when dumping + - wifi: mac80211: fix race condition on enabling fast-xmit + - fbdev: savage: Error out if pixclock equals zero + - fbdev: sis: Error out if pixclock equals zero + - ahci: asm1166: correct count of reported ports + - ahci: add 43-bit DMA address quirk for ASMedia ASM1061 controllers + - ext4: avoid allocating blocks from corrupted group in + ext4_mb_try_best_found() + - ext4: avoid allocating blocks from corrupted group in ext4_mb_find_by_goal() + - regulator: pwm-regulator: Add validity checks in continuous .get_voltage + - nvmet-tcp: fix nvme tcp ida memory leak + - ASoC: sunxi: sun4i-spdif: Add support for Allwinner H616 + - netfilter: conntrack: check SCTP_CID_SHUTDOWN_ACK for vtag setting in + sctp_new + - nvmet-fc: abort command when there is no binding + - hwmon: (coretemp) Enlarge per package core count limit + - scsi: lpfc: Use unsigned type for num_sge + - firewire: core: send bus reset promptly on gap count error + - virtio-blk: Ensure no requests in virtqueues before deleting vqs. + - s390/qeth: Fix potential loss of L3-IP@ in case of network issues + - pmdomain: renesas: r8a77980-sysc: CR7 must be always on + - tcp: factor out __tcp_close() helper + - tcp: return EPOLLOUT from tcp_poll only when notsent_bytes is half the limit + - tcp: add annotations around sk->sk_shutdown accesses + - pinctrl: pinctrl-rockchip: Fix a bunch of kerneldoc misdemeanours + - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups + - spi: mt7621: Fix an error message in mt7621_spi_probe() + - net: bridge: clear bridge's private skb space on xmit + - selftests/bpf: Avoid running unprivileged tests with alignment requirements + - Revert "drm/sun4i: dsi: Change the start delay calculation" + - drm/amdgpu: Check for valid number of registers to read + - x86/alternatives: Disable KASAN in apply_alternatives() + - dm-integrity: don't modify bio's immutable bio_vec in integrity_metadata() + - iomap: Set all uptodate bits for an Uptodate page + - drm/amdgpu: Fix type of second parameter in trans_msg() callback + - arm64: dts: qcom: msm8916: Fix typo in pronto remoteproc node + - PCI: tegra: Fix reporting GPIO error value + - PCI: tegra: Fix OF node reference leak + - IB/hfi1: Fix sdma.h tx->num_descs off-by-one error + - dm-crypt: don't modify the data when using authenticated encryption + - gtp: fix use-after-free and null-ptr-deref in gtp_genl_dump_pdp() + - PCI/MSI: Prevent MSI hardware interrupt number truncation + - l2tp: pass correct message length to ip6_append_data + - ARM: ep93xx: Add terminator to gpiod_lookup_table + - usb: cdns3: fixed memory use after free at cdns3_gadget_ep_disable() + - usb: cdns3: fix memory double free when handle zero packet + - usb: gadget: ncm: Avoid dropping datagrams of properly parsed NTBs + - usb: roles: don't get/set_role() when usb_role_switch is unregistered + - IB/hfi1: Fix a memleak in init_credit_return + - RDMA/bnxt_re: Return error for SRQ resize + - RDMA/srpt: Make debug output more detailed + - RDMA/srpt: fix function pointer cast warnings + - scripts/bpf: teach bpf_helpers_doc.py to dump BPF helper definitions + - bpf, scripts: Correct GPL license name + - scsi: jazz_esp: Only build if SCSI core is builtin + - nouveau: fix function cast warnings + - ipv4: properly combine dev_base_seq and ipv4.dev_addr_genid + - ipv6: properly combine dev_base_seq and ipv6.dev_addr_genid + - afs: Increase buffer size in afs_update_volume_status() + - ipv6: sr: fix possible use-after-free and null-ptr-deref + - packet: move from strlcpy with unused retval to strscpy + - s390: use the correct count for __iowrite64_copy() + - tls: rx: jump to a more appropriate label + - tls: rx: drop pointless else after goto + - tls: stop recv() if initial process_rx_list gave us non-DATA + - netfilter: nf_tables: set dormant flag on hook register failure + - drm/syncobj: make lockdep complain on WAIT_FOR_SUBMIT v3 + - drm/syncobj: call drm_syncobj_fence_add_wait when WAIT_AVAILABLE flag is set + - fs/aio: Restrict kiocb_set_cancel_fn() to I/O submitted via libaio + - scripts/bpf: Fix xdp_md forward declaration typo + - Linux 5.4.270 + * CVE-2023-47233 + - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach + * CVE-2021-47070 + - uio: uio_hv_generic: use devm_kzalloc() for private data alloc + - uio_hv_generic: Fix another memory leak in error handling paths + * CVE-2024-26622 + - tomoyo: fix UAF write bug in tomoyo_write_control() + + -- Philip Cox Fri, 24 May 2024 15:34:31 -0400 + +linux-oracle (5.4.0-1124.133) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1124.133 -proposed tracker (LP: #2063680) + + [ Ubuntu: 5.4.0-182.202 ] + + * focal/linux: 5.4.0-182.202 -proposed tracker (LP: #2063685) + * CVE-2023-52530 + - wifi: mac80211: fix potential key use-after-free + * CVE-2024-26622 + - tomoyo: fix UAF write bug in tomoyo_write_control() + * CVE-2024-26614 + - tcp: make sure init the accept_queue's spinlocks once + - ipv6: init the accept_queue's spinlocks in inet6_create + * CVE-2023-47233 + - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach + + -- Philip Cox Wed, 01 May 2024 07:17:48 -0400 + +linux-oracle (5.4.0-1123.132) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1123.132 -proposed tracker (LP: #2059544) + + * Focal update: v5.4.269 upstream stable release (LP: #2058948) + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + + [ Ubuntu: 5.4.0-181.201 ] + + * focal/linux: 5.4.0-181.201 -proposed tracker (LP: #2059549) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * Focal update: v5.4.269 upstream stable release (LP: #2058948) + - PCI: mediatek: Clear interrupt status before dispatching handler + - include/linux/units.h: add helpers for kelvin to/from Celsius conversion + - units: Add Watt units + - units: change from 'L' to 'UL' + - units: add the HZ macros + - serial: sc16is7xx: set safe default SPI clock frequency + - spi: introduce SPI_MODE_X_MASK macro + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - ext4: allow for the last group to be marked as trimmed + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - parisc/firmware: Fix F-extend for PDC addresses + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - mmc: core: Use mrq.sbc in close-ended ffu + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - rename(): fix the locking of subdirectories + - block: Remove special-casing of compound pages + - mtd: spinand: macronix: Fix MX35LFxGE4AD page size + - fs: add mode_strip_sgid() helper + - fs: move S_ISGID stripping into the vfs_*() helpers + - powerpc: Use always instead of always-y in for crtsavres.o + - x86/CPU/AMD: Fix disabling XSAVES on AMD family 0x17 due to erratum + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: Use kfree(ft->g) in arfs_create_groups() + - net/mlx5e: fix a double-free in arfs_create_groups + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - rbd: don't move requests to the running list on errors + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: ddbridge: fix an error code problem in ddb_probe + - drm/msm/dpu: Ratelimit framedone timeout msgs + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - usb: hub: Replace hardcoded quirk value with BIT() macro + - fs/kernfs/dir: obey S_ISGID + - PCI/AER: Decode Requester ID when no error info found + - libsubcmd: Fix memory leak in uniq() + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: fix deadlock or deadcode of misusing dget() + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - scsi: isci: Fix an error code problem in isci_io_request_build() + - net: remove unneeded break + - ixgbe: Remove non-inclusive language + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - net: sysfs: Fix /sys/class/net/ path + - HID: apple: Add support for the 2021 Magic Keyboard + - HID: apple: Swap the Fn and Left Control keys on Apple keyboards + - HID: apple: Add 2021 magic keyboard FN key mapping + - bonding: remove print in bond_verify_device_path + - dmaengine: fsl-qdma: Fix a memory leak related to the status queue DMA + - dmaengine: fsl-qdma: Fix a memory leak related to the queue command DMA + - phy: renesas: rcar-gen3-usb2: Fix returning wrong error code + - dmaengine: fix is_slave_direction() return false when DMA_DEV_TO_DEV + - phy: ti: phy-omap-usb2: Fix NULL pointer dereference for SRP + - net: stmmac: xgmac: fix handling of DPP safety error for DMA channels + - selftests: net: avoid just another constant wait + - atm: idt77252: fix a memleak in open_card_ubr0 + - hwmon: (aspeed-pwm-tacho) mutex for tach reading + - hwmon: (coretemp) Fix out-of-bounds memory access + - hwmon: (coretemp) Fix bogus core_id to attr name mapping + - inet: read sk->sk_family once in inet_recv_error() + - rxrpc: Fix response to PING RESPONSE ACKs to a dead call + - tipc: Check the bearer type before calling tipc_udp_nl_bearer_add() + - ppp_async: limit MRU to 64K + - netfilter: nft_compat: reject unused compat flag + - netfilter: nft_compat: restrict match/target protocol to u16 + - netfilter: nft_ct: reject direction for ct id + - net/af_iucv: clean up a try_then_request_module() + - USB: serial: qcserial: add new usb-id for Dell Wireless DW5826e + - USB: serial: option: add Fibocom FM101-GL variant + - USB: serial: cp210x: add ID for IMST iM871A-USB + - hrtimer: Report offline hrtimer enqueue + - Input: atkbd - skip ATKBD_CMD_SETLEDS when skipping ATKBD_CMD_GETID + - net: stmmac: xgmac: use #define for string constants + - net: stmmac: xgmac: fix a typo of register name in DPP safety handling + - btrfs: forbid creating subvol qgroups + - btrfs: forbid deleting live subvol qgroup + - btrfs: send: return EOPNOTSUPP on unknown flags + - of: unittest: add overlay gpio test to catch gpio hog problem + - of: unittest: Fix compile in the non-dynamic case + - spi: ppc4xx: Drop write-only variable + - ASoC: rt5645: Fix deadlock in rt5645_jack_detect_work() + - MIPS: Add 'memory' clobber to csum_ipv6_magic() inline assembler + - i40e: Fix waiting for queues of all VSIs to be disabled + - tracing/trigger: Fix to return error if failed to alloc snapshot + - mm/writeback: fix possible divide-by-zero in wb_dirty_limits(), again + - HID: wacom: generic: Avoid reporting a serial of '0' to userspace + - HID: wacom: Do not register input devices until after hid_hw_start + - USB: hub: check for alternate port before enabling A_ALT_HNP_SUPPORT + - usb: f_mass_storage: forbid async queue when shutdown happen + - i2c: i801: Remove i801_set_block_buffer_mode + - i2c: i801: Fix block process call transactions + - scsi: Revert "scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock" + - firewire: core: correct documentation of fw_csr_string() kernel API + - kbuild: Fix changing ELF file type for output of gen_btf for big endian + - nfc: nci: free rx_data_reassembly skb on NCI device cleanup + - xen-netback: properly sync TX responses + - ALSA: hda/realtek: Enable headset mic on Vaio VJFE-ADL + - binder: signal epoll threads of self-work + - misc: fastrpc: Mark all sessions as invalid in cb_remove + - ext4: fix double-free of blocks due to wrong extents moved_len + - tracing: Fix wasted memory in saved_cmdlines logic + - staging: iio: ad5933: fix type mismatch regression + - iio: magnetometer: rm3100: add boundary check for the value read from + RM3100_REG_TMRC + - ring-buffer: Clean ring_buffer_poll_wait() error return + - serial: max310x: set default value when reading clock ready bit + - serial: max310x: improve crystal stable clock detection + - x86/Kconfig: Transmeta Crusoe is CPU family 5, not 6 + - x86/mm/ident_map: Use gbpages only where full GB page should be mapped. + - mmc: slot-gpio: Allow non-sleeping GPIO ro + - ALSA: hda/conexant: Add quirk for SWS JS201D + - nilfs2: fix data corruption in dsync block recovery for small block sizes + - nilfs2: fix hang in nilfs_lookup_dirty_data_buffers() + - nfp: use correct macro for LengthSelect in BAR config + - nfp: flower: prevent re-adding mac index for bonded port + - irqchip/irq-brcmstb-l2: Add write memory barrier before exit + - can: j1939: Fix UAF in j1939_sk_match_filter during + setsockopt(SO_J1939_FILTER) + - pmdomain: core: Move the unused cleanup to a _sync initcall + - tracing: Inform kmemleak of saved_cmdlines allocation + - Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d" + - bus: moxtet: Add spi device table + - arch, mm: remove stale mentions of DISCONIGMEM + - mips: Fix max_mapnr being uninitialized on early stages + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - netfilter: ipset: fix performance regression in swap operation + - netfilter: ipset: Missing gc cancellations fixed + - net: prevent mss overflow in skb_segment() + - sched/membarrier: reduce the ability to hammer on sys_membarrier + - nilfs2: fix potential bug in end_buffer_async_write + - PM: runtime: add devm_pm_runtime_enable helper + - PM: runtime: Have devm_pm_runtime_enable() handle + pm_runtime_dont_use_autosuspend() + - drm/msm/dsi: Enable runtime PM + - lsm: new security_file_ioctl_compat() hook + - Revert "Revert "mtd: rawnand: gpmi: Fix setting busy timeout setting"" + - net: bcmgenet: Fix EEE implementation + - of: unittest: fix EXPECT text for gpio hog errors + - of: gpio unittest kfree() wrong object + - Linux 5.4.269 + * Focal update: v5.4.269 upstream stable release (LP: #2058948) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * CVE-2023-24023 + - Bluetooth: Add more enc key size check + * CVE-2024-26581 + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - netfilter: nft_set_rbtree: skip end interval element from gc + * CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + + -- Philip Cox Wed, 10 Apr 2024 08:54:23 -0400 + +linux-oracle (5.4.0-1122.131) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1122.131 -proposed tracker (LP: #2059628) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + [ Ubuntu: 5.4.0-177.197 ] + + * focal/linux: 5.4.0-177.197 -proposed tracker (LP: #2059633) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * CVE-2023-24023 + - Bluetooth: Add more enc key size check + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Focal update: v5.4.269 upstream stable release (LP: #2058948) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2024-26581 + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - netfilter: nft_set_rbtree: skip end interval element from gc + * CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + + [ Ubuntu: 5.4.0-176.196 ] + + * focal/linux: 5.4.0-176.196 -proposed tracker (LP: #2058756) + * Problems with HVCS and hotplugging (LP: #2056373) + - powerpc/pseries: Fix bad drc_index_start value parsing of drc-info entry + - powerpc/pseries: Fix of_read_drc_info_cell() to point at next record + - hvcs: Fix hvcs port reference counting + - hvcs: Use dev_groups to manage hvcs device attributes + - hvcs: Use driver groups to manage driver attributes + - hvcs: Get reference to tty in remove + - hvcs: Use vhangup in hotplug remove + - hvcs: Synchronize hotplug remove with port free + + -- Joseph Salisbury Tue, 02 Apr 2024 13:18:04 -0400 + +linux-oracle (5.4.0-1121.130) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1121.130 -proposed tracker (LP: #2055679) + + * Packaging resync (LP: #1786013) + - [Packaging] drop ABI data + - debian.oracle/dkms-versions -- update from kernel-versions (main/2024.03.04) + + [ Ubuntu: 5.4.0-175.195 ] + + * focal/linux: 5.4.0-175.195 -proposed tracker (LP: #2055684) + * Packaging resync (LP: #1786013) + - [Packaging] drop ABI data + - [Packaging] update annotations scripts + - debian.master/dkms-versions -- update from kernel-versions (main/2024.03.04) + * Drop ABI checks from kernel build (LP: #2055686) + - [Packaging] Remove in-tree abi checks + - [Packaging] Bring back install- prerequisite for checks- + - [Packaging] Remove abi-check from final-checks + * Cranky update-dkms-versions rollout (LP: #2055685) + - [Packaging] remove update-dkms-versions + - Move debian/dkms-versions to debian.master/dkms-versions + - [Packaging] Replace debian/dkms-versions with $(DEBIAN)/dkms-versions + - [Packaging] remove update-version-dkms + * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094) + - [Packaging] rules: Put usbip manpages in the correct directory + * CVE-2024-23851 + - dm ioctl: log an error if the ioctl structure is corrupted + - dm: limit the number of targets and parameter size area + * Focal update: v5.4.268 upstream stable release (LP: #2055075) + - f2fs: explicitly null-terminate the xattr list + - pinctrl: lochnagar: Don't build on MIPS + - ALSA: hda - Fix speaker and headset mic pin config for CHUWI CoreBook XPro + - ASoC: Intel: Skylake: Fix mem leak in few functions + - ASoC: nau8822: Fix incorrect type in assignment and cast to restricted + __be16 + - ASoC: Intel: Skylake: mem leak in skl register function + - ASoC: cs43130: Fix the position of const qualifier + - ASoC: cs43130: Fix incorrect frame delay configuration + - ASoC: rt5650: add mutex to avoid the jack detection failure + - nouveau/tu102: flush all pdbs on vmm flush + - net/tg3: fix race condition in tg3_reset_task() + - ASoC: da7219: Support low DC impedance headset + - nvme: introduce helper function to get ctrl state + - drm/exynos: fix a potential error pointer dereference + - drm/exynos: fix a wrong error checking + - clk: rockchip: rk3128: Fix HCLK_OTG gate register + - jbd2: correct the printing of write_flags in jbd2_write_superblock() + - drm/crtc: Fix uninit-value bug in drm_mode_setcrtc + - neighbour: Don't let neigh_forced_gc() disable preemption for long + - tracing: Have large events show up as '[LINE TOO BIG]' instead of nothing + - tracing: Add size check when printing trace_marker output + - ring-buffer: Do not record in NMI if the arch does not support cmpxchg in + NMI + - reset: hisilicon: hi6220: fix Wvoid-pointer-to-enum-cast warning + - Input: atkbd - skip ATKBD_CMD_GETID in translated mode + - Input: i8042 - add nomux quirk for Acer P459-G2-M + - s390/scm: fix virtual vs physical address confusion + - ARC: fix spare error + - Input: xpad - add Razer Wolverine V2 support + - ARM: sun9i: smp: fix return code check of of_property_match_string + - drm/crtc: fix uninitialized variable use + - ACPI: resource: Add another DMI match for the TongFang GMxXGxx + - binder: use EPOLLERR from eventpoll.h + - binder: fix trivial typo of binder_free_buf_locked() + - binder: fix comment on binder_alloc_new_buf() return value + - uio: Fix use-after-free in uio_open + - parport: parport_serial: Add Brainboxes BAR details + - parport: parport_serial: Add Brainboxes device IDs and geometry + - coresight: etm4x: Fix width of CCITMIN field + - x86/lib: Fix overflow when counting digits + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhotplug: Quieten some DLPAR operations + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - net: netlabel: Fix kerneldoc warnings + - netlabel: remove unused parameter in netlbl_netlink_auditinfo() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: virtio - don't use 'default m' + - virtio_crypto: Introduce VIRTIO_CRYPTO_NOSPC + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - ncsi: internal.h: Fix a spello + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - rtlwifi: Use ffs in _phy_calculate_bit_shift + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - scsi: hisi_sas: Replace with standard error code return value + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - rtlwifi: rtl8192de: make arrays static const, makes object smaller + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - media: pvrusb2: fix use after free on context disconnection + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - media: dvbdev: drop refcount on error path in dvb_device_open() + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drivers: clk: zynqmp: calculate closest mux rate + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update annotations for CONFIG_MMC_SDHCI_OMAP + - [Config] remove sdhci-omap module for arm64/ppc64el + - of: Fix double free in of_parse_phandle_with_args_map + - of: unittest: Fix of_count_phandle_with_args() expected value message + - binder: fix async space check for 0-sized buffers + - binder: fix use-after-free in shinker's callback + - Input: atkbd - use ab83 as id when skipping the getid command + - Revert "ASoC: atmel: Remove system clock tree configuration for + at91sam9g20ek" + - binder: fix race between mmput() and do_exit() + - binder: fix unused alloc->free_async_space + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - ALSA: oxygen: Fix right channel of capture volume mixer + - fbdev: flush deferred work in fb_deferred_io_fsync() + - rootfs: Fix support for rootfstype= when root= is given + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - HID: wacom: Correct behavior when processing some confidence == false + touches + - mips: Fix incorrect max_low_pfn adjustment + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - perf genelf: Set ELF program header addresses properly + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Add perf_env__numa_node() + - perf record: Move sb_evlist to 'struct record' + - perf top: Move sb_evlist to 'struct perf_top' + - perf bpf: Decouple creating the evlist from adding the SB event + - perf env: Avoid recursively taking env->bpf_progs.lock + - apparmor: avoid crash when parsed profile name is empty + - serial: imx: Correct clock error message in function probe() + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: qualcomm: rmnet: fix global oob in rmnet_policy + - net: phy: micrel: populate .soft_reset for KSZ9131 + - net: ravb: Fix dma_addr_t truncation in error case + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - netfilter: nf_tables: skip dead set elements in netlink dump + - ipvs: avoid stat macros calls from preemptible context + - kdb: Censor attempts to set PROMPT without ENABLE_MEM_READ + - kdb: Fix a potential buffer overflow in kdb_local() + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - perf top: Skip side-band event setup if HAVE_LIBBPF_SUPPORT is not set + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - Linux 5.4.268 + * CVE-2024-24855 + - scsi: lpfc: Fix a possible data race in lpfc_unregister_fcf_rescan() + * Focal update: v5.4.267 upstream stable release (LP: #2054406) + - nfc: llcp_core: Hold a ref to llcp_local->dev when holding a ref to + llcp_local + - i40e: Fix filter input checks to prevent config with invalid values + - net: sched: em_text: fix possible memory leak in em_text_destroy() + - can: raw: add support for SO_TXTIME/SCM_TXTIME + - can: raw: add support for SO_MARK + - net-timestamp: extend SOF_TIMESTAMPING_OPT_ID to HW timestamps + - ARM: sun9i: smp: Fix array-index-out-of-bounds read in sunxi_mc_smp_init + - net: bcmgenet: Fix FCS generation for fragmented skbuffs + - net: Save and restore msg_namelen in sock_sendmsg + - i40e: fix use-after-free in i40e_aqc_add_filters() + - ASoC: meson: g12a: extract codec-to-codec utils + - [Config] Update annotations for CONFIG_SND_MESON_CODEC_GLUE + - ASoC: meson: g12a-tohdmitx: Validate written enum values + - ASoC: meson: g12a-tohdmitx: Fix event generation for S/PDIF mux + - i40e: Restore VF MSI-X state during PCI reset + - net/qla3xxx: switch from 'pci_' to 'dma_' API + - net/qla3xxx: fix potential memleak in ql_alloc_buffer_queues + - asix: Add check for usbnet_get_endpoints + - bnxt_en: Remove mis-applied code from bnxt_cfg_ntp_filters() + - net: Implement missing SO_TIMESTAMPING_NEW cmsg support + - mm/memory-failure: check the mapcount of the precise page + - firewire: ohci: suppress unexpected system reboot in AMD Ryzen machines and + ASM108x/VT630x PCIe cards + - i2c: core: Fix atomic xfer check for non-preempt config + - mm: fix unmap_mapping_range high bits shift bug + - mmc: rpmb: fixes pause retune on all RPMB partitions. + - mmc: core: Cancel delayed work before releasing host + - mmc: sdhci-sprd: Fix eMMC init failure after hw reset + - ath10k: Wait until copy complete is actually done before completing + - ath10k: Add interrupt summary based CE processing + - ath10k: Keep track of which interrupts fired, don't poll them + - ath10k: Get rid of "per_ce_irq" hw param + - PCI: Extract ATS disabling to a helper function + - PCI: Disable ATS for specific Intel IPU E2000 devices + - net/dst: use a smaller percpu_counter batch for dst entries accounting + - ipv6: make ip6_rt_gc_expire an atomic_t + - ipv6: remove max_size check inline with ipv4 + - ASoC: meson: codec-glue: fix pcm format cast warning + - Linux 5.4.267 + * CVE-2023-23000 + - phy: tegra: xusb: Fix return value of tegra_xusb_find_port_node function + * CVE-2023-23004 + - malidp: Fix NULL vs IS_ERR() checking + * CVE-2023-46838 + - xen-netback: don't produce zero-size SKB frags + * CVE-2024-1086 + - netfilter: nf_tables: reject QUEUE/DROP verdict parameters + * Focal update: v5.4.266 upstream stable release (LP: #2051655) + - ALSA: hda/realtek: Enable headset on Lenovo M90 Gen5 + - ksmbd: fix wrong name of SMB2_CREATE_ALLOCATION_SIZE + - ARM: OMAP2+: Fix null pointer dereference and memory leak in + omap_soc_device_init + - reset: Fix crash when freeing non-existent optional resets + - s390/vx: fix save/restore of fpu kernel context + - wifi: mac80211: mesh_plink: fix matches_local logic + - net/mlx5: improve some comments + - net/mlx5: Fix fw tracer first block check + - net/mlx5e: Correct snprintf truncation handling for fw_version buffer used + by representors + - net: sched: ife: fix potential use-after-free + - ethernet: atheros: fix a memleak in atl1e_setup_ring_resources + - net/rose: fix races in rose_kill_by_device() + - net: check vlan filter feature in vlan_vids_add_by_dev() and + vlan_vids_del_by_dev() + - afs: Fix the dynamic root's d_delete to always delete unused dentries + - afs: Fix dynamic root lookup DNS check + - net: warn if gso_type isn't set for a GSO SKB + - net: check dev->gso_max_size in gso_features_check() + - afs: Fix overwriting of result of DNS query + - i2c: aspeed: Handle the coalesced stop conditions with the start conditions. + - pinctrl: at91-pio4: use dedicated lock class for IRQ + - ALSA: hda/hdmi: Add quirk to force pin connectivity on NUC10 + - ALSA: hda/hdmi: add force-connect quirk for NUC5CPYB + - smb: client: fix NULL deref in asn1_ber_decoder() + - btrfs: do not allow non subvolume root targets for snapshot + - interconnect: Treat xlate() returning NULL node as an error + - iio: imu: inv_mpu6050: fix an error code problem in inv_mpu6050_read_raw + - Input: ipaq-micro-keys - add error handling for devm_kmemdup + - scsi: bnx2fc: Fix skb double free in bnx2fc_rcv() + - iio: common: ms_sensors: ms_sensors_i2c: fix humidity conversion time table + - iio: adc: ti_am335x_adc: Fix return value check of tiadc_request_dma() + - wifi: cfg80211: Add my certificate + - wifi: cfg80211: fix certs build to not depend on file order + - USB: serial: ftdi_sio: update Actisense PIDs constant names + - USB: serial: option: add Quectel EG912Y module support + - USB: serial: option: add Foxconn T99W265 with new baseline + - USB: serial: option: add Quectel RM500Q R13 firmware support + - Bluetooth: hci_event: Fix not checking if HCI_OP_INQUIRY has been sent + - net: 9p: avoid freeing uninit memory in p9pdu_vreadf + - net: rfkill: gpio: set GPIO direction + - x86/alternatives: Sync core before enabling interrupts + - usb: fotg210-hcd: delete an incorrect bounds test + - ring-buffer: Fix wake ups when buffer_percent is set to 100 + - block: Don't invalidate pagecache for invalid falloc modes + - Linux 5.4.266 + * CVE-2024-0607 + - netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval() + + -- Joseph Salisbury Wed, 13 Mar 2024 11:14:52 -0400 + +linux-oracle (5.4.0-1120.129) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1120.129 -proposed tracker (LP: #2055972) + + [ Ubuntu: 5.4.0-174.193 ] + + * focal/linux: 5.4.0-174.193 -proposed tracker (LP: #2055978) + * Packaging resync (LP: #1786013) + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/s2024.02.05) + * CVE-2024-24855 + - scsi: lpfc: Fix a possible data race in lpfc_unregister_fcf_rescan() + * CVE-2024-1086 + - netfilter: nf_tables: reject QUEUE/DROP verdict parameters + * CVE-2023-23004 + - malidp: Fix NULL vs IS_ERR() checking + * CVE-2023-23000 + - phy: tegra: xusb: Fix return value of tegra_xusb_find_port_node function + + -- Joseph Salisbury Mon, 11 Mar 2024 13:56:48 -0400 + +linux-oracle (5.4.0-1119.128) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1119.128 -proposed tracker (LP: #2052130) + + * Focal update: v5.4.260 upstream stable release (LP: #2049024) + - [Config] remove CONFIG_BLK_DEV_SX8 + + [ Ubuntu: 5.4.0-173.191 ] + + * focal/linux: 5.4.0-173.191 -proposed tracker (LP: #2052135) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2024.02.05) + * CVE-2023-0340 + - vhost: use kzalloc() instead of kmalloc() followed by memset() + * CVE-2023-6915 + - ida: Fix crash in ida_free when the bitmap is empty + * Focal update: v5.4.265 upstream stable release (LP: #2051644) + - afs: Fix refcount underflow from error handling race + - net: ipv6: support reporting otherwise unknown prefix flags in RTM_NEWPREFIX + - qca_debug: Prevent crash on TX ring changes + - qca_debug: Fix ethtool -G iface tx behavior + - qca_spi: Fix reset behavior + - atm: solos-pci: Fix potential deadlock on &cli_queue_lock + - atm: solos-pci: Fix potential deadlock on &tx_queue_lock + - atm: Fix Use-After-Free in do_vcc_ioctl + - qed: Fix a potential use-after-free in qed_cxt_tables_alloc + - net: Remove acked SYN flag from packet in the transmit queue correctly + - sign-file: Fix incorrect return values check + - vsock/virtio: Fix unsigned integer wrap around in + virtio_transport_has_space() + - net: stmmac: use dev_err_probe() for reporting mdio bus registration failure + - net: stmmac: Handle disabled MDIO busses from devicetree + - cred: switch to using atomic_long_t + - ALSA: hda/hdmi: add force-connect quirks for ASUSTeK Z170 variants + - usb: aqc111: check packet for fixup for true limit + - blk-throttle: fix lockdep warning of "cgroup_mutex or RCU read lock + required!" + - bcache: avoid oversize memory allocation by small stripe_size + - bcache: add code comments for bch_btree_node_get() and + __bch_btree_node_alloc() + - bcache: avoid NULL checking to c->root in run_cache_set() + - platform/x86: intel_telemetry: Fix kernel doc descriptions + - HID: add ALWAYS_POLL quirk for Apple kb + - HID: hid-asus: reset the backlight brightness level on resume + - HID: multitouch: Add quirk for HONOR GLO-GXXX touchpad + - asm-generic: qspinlock: fix queued_spin_value_unlocked() implementation + - net: usb: qmi_wwan: claim interface 4 for ZTE MF290 + - HID: hid-asus: add const to read-only outgoing usb buffer + - soundwire: stream: fix NULL pointer dereference for multi_link + - ext4: prevent the normalized size from exceeding EXT_MAX_BLOCKS + - arm64: mm: Always make sw-dirty PTEs hw-dirty in pte_modify + - team: Fix use-after-free when an option instance allocation fails + - ring-buffer: Fix memory leak of free page + - mmc: block: Be sure to wait while busy in CQE error recovery + - powerpc/ftrace: Create a dummy stackframe to fix stack unwind + - powerpc/ftrace: Fix stack teardown in ftrace_no_trace + - Linux 5.4.265 + * Focal update: v5.4.264 upstream stable release (LP: #2049935) + - hrtimers: Push pending hrtimers away from outgoing CPU earlier + - netfilter: ipset: fix race condition between swap/destroy and kernel side + add/del/test + - tg3: Move the [rt]x_dropped counters to tg3_napi + - tg3: Increment tx_dropped in tg3_tso_bug() + - kconfig: fix memory leak from range properties + - drm/amdgpu: correct chunk_ptr to a pointer to chunk. + - of: base: Add of_get_cpu_state_node() to get idle states for a CPU node + - ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic + - ACPI/IORT: Make iort_msi_map_rid() PCI agnostic + - of/iommu: Make of_map_rid() PCI agnostic + - of/irq: make of_msi_map_get_device_domain() bus agnostic + - of/irq: Make of_msi_map_rid() PCI bus agnostic + - of: base: Fix some formatting issues and provide missing descriptions + - of: Fix kerneldoc output formatting + - of: Add missing 'Return' section in kerneldoc comments + - of: dynamic: Fix of_reconfig_get_state_change() return value documentation + - ipv6: fix potential NULL deref in fib6_add() + - hv_netvsc: rndis_filter needs to select NLS + - net: arcnet: Fix RESET flag handling + - net: arcnet: com20020 fix error handling + - arcnet: restoring support for multiple Sohard Arcnet cards + - ipv4: ip_gre: Avoid skb_pull() failure in ipgre_xmit() + - net: hns: fix fake link up on xge port + - netfilter: xt_owner: Fix for unsafe access of sk->sk_socket + - tcp: do not accept ACK of bytes we never sent + - bpf: sockmap, updating the sg structure should also update curr + - RDMA/bnxt_re: Correct module description string + - hwmon: (acpi_power_meter) Fix 4.29 MW bug + - ASoC: wm_adsp: fix memleak in wm_adsp_buffer_populate + - tracing: Fix a warning when allocating buffered events fails + - scsi: be2iscsi: Fix a memleak in beiscsi_init_wrb_handle() + - ARM: imx: Check return value of devm_kasprintf in imx_mmdc_perf_init + - ARM: dts: imx: make gpt node name generic + - ARM: dts: imx7: Declare timers compatible with fsl,imx6dl-gpt + - ALSA: pcm: fix out-of-bounds in snd_pcm_state_names + - nilfs2: prevent WARNING in nilfs_sufile_set_segment_usage() + - tracing: Always update snapshot buffer size + - tracing: Fix incomplete locking when disabling buffered events + - tracing: Fix a possible race when disabling buffered events + - packet: Move reference count in packet_sock to atomic_long_t + - arm64: dts: mediatek: mt7622: fix memory node warning check + - arm64: dts: mediatek: mt8173-evb: Fix regulator-fixed node names + - gpiolib: sysfs: Fix error handling on failed export + - mmc: core: add helpers mmc_regulator_enable/disable_vqmmc + - mmc: sdhci-sprd: Fix vqmmc not shutting down after the card was pulled + - usb: gadget: f_hid: fix report descriptor allocation + - parport: Add support for Brainboxes IX/UC/PX parallel cards + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - ARM: PL011: Fix DMA support + - serial: sc16is7xx: address RX timeout interrupt errata + - serial: 8250_omap: Add earlycon support for the AM654 UART controller + - x86/CPU/AMD: Check vendor in the AMD microcode callback + - KVM: s390/mm: Properly reset no-dat + - nilfs2: fix missing error check for sb_set_blocksize call + - io_uring/af_unix: disable sending io_uring over sockets + - netlink: don't call ->netlink_bind with table lock held + - genetlink: add CAP_NET_ADMIN test for multicast bind + - psample: Require 'CAP_NET_ADMIN' when joining "packets" group + - drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group + - tools headers UAPI: Sync linux/perf_event.h with the kernel sources + - cifs: Fix non-availability of dedup breaking generic/304 + - smb: client: fix potential NULL deref in parse_dfs_referrals() + - devcoredump : Serialize devcd_del work + - devcoredump: Send uevent once devcd is ready + - Linux 5.4.264 + * CVE-2024-0646 + - net: tls, update curr on splice as well + * CVE-2024-0565 + - smb: client: fix OOB in receive_encrypted_standard() + * CVE-2023-51781 + - appletalk: Fix Use-After-Free in atalk_ioctl + * CVE-2023-51782 + - net/rose: Fix Use-After-Free in rose_ioctl + * Focal update: v5.4.263 upstream stable release (LP: #2049084) + - driver core: Release all resources during unbind before updating device + links + - RDMA/irdma: Prevent zero-length STAG registration + - PCI: keystone: Drop __init from ks_pcie_add_pcie_{ep,port}() + - afs: Make error on cell lookup failure consistent with OpenAFS + - drm/panel: simple: Fix Innolux G101ICE-L01 bus flags + - drm/panel: simple: Fix Innolux G101ICE-L01 timings + - ata: pata_isapnp: Add missing error check for devm_ioport_map() + - drm/rockchip: vop: Fix color for RGB888/BGR888 format on VOP full + - HID: core: store the unique system identifier in hid_device + - HID: fix HID device resource race between HID core and debugging support + - ipv4: Correct/silence an endian warning in __ip_do_redirect + - net: usb: ax88179_178a: fix failed operations during ax88179_reset + - arm/xen: fix xen_vcpu_info allocation alignment + - amd-xgbe: handle corner-case during sfp hotplug + - amd-xgbe: handle the corner-case during tx completion + - amd-xgbe: propagate the correct speed and duplex status + - net: axienet: Fix check for partial TX checksum + - afs: Return ENOENT if no cell DNS record can be found + - afs: Fix file locking on R/O volumes to operate in local mode + - nvmet: remove unnecessary ctrl parameter + - nvmet: nul-terminate the NQNs passed in the connect command + - MIPS: KVM: Fix a build warning about variable set but not used + - ext4: add a new helper to check if es must be kept + - ext4: factor out __es_alloc_extent() and __es_free_extent() + - ext4: use pre-allocated es in __es_insert_extent() + - ext4: use pre-allocated es in __es_remove_extent() + - ext4: using nofail preallocation in ext4_es_remove_extent() + - ext4: using nofail preallocation in ext4_es_insert_delayed_block() + - ext4: using nofail preallocation in ext4_es_insert_extent() + - ext4: fix slab-use-after-free in ext4_es_insert_extent() + - ext4: make sure allocate pending entry not fail + - arm64: cpufeature: Extract capped perfmon fields + - KVM: arm64: limit PMU version to PMUv3 for ARMv8.1 + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1402CVA + - bcache: replace a mistaken IS_ERR() by IS_ERR_OR_NULL() in + btree_gc_coalesce() + - s390/dasd: protect device queue against concurrent access + - USB: serial: option: add Luat Air72*U series products + - hv_netvsc: Fix race of register_netdevice_notifier and VF register + - hv_netvsc: Mark VF as slave before exposing it to user-mode + - dm-delay: fix a race between delay_presuspend and delay_bio + - bcache: check return value from btree_node_alloc_replacement() + - bcache: prevent potential division by zero error + - USB: serial: option: add Fibocom L7xx modules + - USB: serial: option: fix FM101R-GL defines + - USB: serial: option: don't claim interface 4 for ZTE MF290 + - USB: dwc2: write HCINT with INTMASK applied + - usb: dwc3: set the dma max_seg_size + - USB: dwc3: qcom: fix resource leaks on probe deferral + - USB: dwc3: qcom: fix wakeup after probe deferral + - io_uring: fix off-by one bvec index + - pinctrl: avoid reload of p state in list iteration + - firewire: core: fix possible memory leak in create_units() + - mmc: block: Do not lose cache flush during CQE error recovery + - ALSA: hda: Disable power-save on KONTRON SinglePC + - ALSA: hda/realtek: Headset Mic VREF to 100% + - ALSA: hda/realtek: Add supported ALC257 for ChromeOS + - dm-verity: align struct dm_verity_fec_io properly + - dm verity: don't perform FEC for failed readahead IO + - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR + - powerpc: Don't clobber f0/vs0 during fp|altivec register save + - btrfs: fix off-by-one when checking chunk map includes logical address + - btrfs: send: ensure send_fd is writable + - btrfs: make error messages more clear when getting a chunk map + - Input: xpad - add HyperX Clutch Gladiate Support + - net: stmmac: xgmac: Disable FPE MMC interrupts + - ravb: Fix races between ravb_tx_timeout_work() and net related ops + - net: ravb: Use pm_runtime_resume_and_get() + - net: ravb: Start TX queues after HW initialization succeeded + - smb3: fix touch -h of symlink + - s390/mm: fix phys vs virt confusion in mark_kernel_pXd() functions family + - s390/cmma: fix detection of DAT pages + - mtd: cfi_cmdset_0001: Support the absence of protection registers + - mtd: cfi_cmdset_0001: Byte swap OTP info + - fbdev: stifb: Make the STI next font pointer a 32-bit signed offset + - ima: annotate iint mutex to avoid lockdep false positive warnings + - ovl: skip overlayfs superblocks at global sync + - ima: detect changes to the backing overlay file + - scsi: qla2xxx: Simplify the code for aborting SCSI commands + - scsi: core: Introduce the scsi_cmd_to_rq() function + - scsi: qla2xxx: Use scsi_cmd_to_rq() instead of scsi_cmnd.request + - scsi: qla2xxx: Fix system crash due to bad pointer access + - cpufreq: imx6q: don't warn for disabling a non-existing frequency + - cpufreq: imx6q: Don't disable 792 Mhz OPP unnecessarily + - mmc: cqhci: Increase recovery halt timeout + - mmc: cqhci: Warn of halt or task clear failure + - mmc: cqhci: Fix task clearing in CQE error recovery + - mmc: core: convert comma to semicolon + - mmc: block: Retry commands in CQE error recovery + - Linux 5.4.263 + * Focal update: v5.4.262 upstream stable release (LP: #2049069) + - locking/ww_mutex/test: Fix potential workqueue corruption + - perf/core: Bail out early if the request AUX area is out of bound + - clocksource/drivers/timer-imx-gpt: Fix potential memory leak + - clocksource/drivers/timer-atmel-tcb: Fix initialization on SAM9 hardware + - x86/mm: Drop the 4 MB restriction on minimal NUMA node memory size + - wifi: mac80211_hwsim: fix clang-specific fortify warning + - wifi: mac80211: don't return unset power in ieee80211_get_tx_power() + - wifi: ath9k: fix clang-specific fortify warnings + - wifi: ath10k: fix clang-specific fortify warning + - net: annotate data-races around sk->sk_tx_queue_mapping + - net: annotate data-races around sk->sk_dst_pending_confirm + - wifi: ath10k: Don't touch the CE interrupt registers after power up + - Bluetooth: Fix double free in hci_conn_cleanup + - platform/x86: thinkpad_acpi: Add battery quirk for Thinkpad X120e + - drm/komeda: drop all currently held locks if deadlock happens + - drm/amd: Fix UBSAN array-index-out-of-bounds for SMU7 + - drm/amd: Fix UBSAN array-index-out-of-bounds for Polaris and Tonga + - drm/amdgpu: Fix a null pointer access when the smc_rreg pointer is NULL + - selftests/efivarfs: create-read: fix a resource leak + - crypto: pcrypt - Fix hungtask for PADATA_RESET + - RDMA/hfi1: Use FIELD_GET() to extract Link Width + - fs/jfs: Add check for negative db_l2nbperpage + - fs/jfs: Add validity check for db_maxag and db_agpref + - jfs: fix array-index-out-of-bounds in dbFindLeaf + - jfs: fix array-index-out-of-bounds in diAlloc + - ARM: 9320/1: fix stack depot IRQ stack filter + - ALSA: hda: Fix possible null-ptr-deref when assigning a stream + - PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields + - atm: iphase: Do PCI error checks on own line + - scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup() + - HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W + - tty: vcc: Add check for kstrdup() in vcc_probe() + - usb: gadget: f_ncm: Always set current gadget in ncm_bind() + - i2c: sun6i-p2wi: Prevent potential division by zero + - media: gspca: cpia1: shift-out-of-bounds in set_flicker + - media: vivid: avoid integer overflow + - gfs2: ignore negated quota changes + - media: cobalt: Use FIELD_GET() to extract Link Width + - drm/amd/display: Avoid NULL dereference of timing generator + - kgdb: Flush console before entering kgdb on panic + - ASoC: ti: omap-mcbsp: Fix runtime PM underflow warnings + - pwm: Fix double shift bug + - wifi: iwlwifi: Use FW rate for non-data frames + - NFSv4.1: fix SP4_MACH_CRED protection for pnfs IO + - ipvlan: add ipvlan_route_v6_outbound() helper + - tty: Fix uninit-value access in ppp_sync_receive() + - net: hns3: fix variable may not initialized problem in hns3_init_mac_addr() + - tipc: Fix kernel-infoleak due to uninitialized TLV value + - ppp: limit MRU to 64K + - xen/events: fix delayed eoi list handling + - ptp: annotate data-race around q->head and q->tail + - bonding: stop the device in bond_setup_by_slave() + - net: ethernet: cortina: Fix max RX frame define + - net: ethernet: cortina: Handle large frames + - net: ethernet: cortina: Fix MTU max setting + - netfilter: nf_conntrack_bridge: initialize err to 0 + - net: stmmac: Rework stmmac_rx() + - net: stmmac: fix rx budget limit check + - net/mlx5_core: Clean driver version and name + - net/mlx5e: Check return value of snprintf writing to fw_version buffer for + representors + - macvlan: Don't propagate promisc change to lower dev in passthru + - tools/power/turbostat: Fix a knl bug + - cifs: spnego: add ';' in HOST_KEY_LEN + - media: venus: hfi: add checks to perform sanity on queue pointers + - randstruct: Fix gcc-plugin performance mode to stay in group + - bpf: Fix precision tracking for BPF_ALU | BPF_TO_BE | BPF_END + - scsi: megaraid_sas: Increase register read retry rount from 3 to 30 for + selected registers + - x86/cpu/hygon: Fix the CPU topology evaluation for real + - KVM: x86: hyper-v: Don't auto-enable stimer on write from user-space + - KVM: x86: Ignore MSR_AMD64_TW_CFG access + - audit: don't take task_lock() in audit_exe_compare() code path + - audit: don't WARN_ON_ONCE(!current->mm) in audit_exe_compare() + - hvc/xen: fix error path in xen_hvc_init() to always register frontend driver + - PCI/sysfs: Protect driver's D3cold preference from user space + - ACPI: resource: Do IRQ override on TongFang GMxXGxx + - mmc: meson-gx: Remove setting of CMD_CFG_ERROR + - genirq/generic_chip: Make irq_remove_generic_chip() irqdomain aware + - PCI: keystone: Don't discard .remove() callback + - PCI: keystone: Don't discard .probe() callback + - parisc/pdc: Add width field to struct pdc_model + - clk: qcom: ipq8074: drop the CLK_SET_RATE_PARENT flag from PLL clocks + - mmc: vub300: fix an error code + - PM: hibernate: Use __get_safe_page() rather than touching the list + - PM: hibernate: Clean up sync_read handling in snapshot_write_next() + - btrfs: don't arbitrarily slow down delalloc if we're committing + - jbd2: fix potential data lost in recovering journal raced with synchronizing + fs bdev + - quota: explicitly forbid quota files from being encrypted + - kernel/reboot: emergency_restart: Set correct system_state + - i2c: core: Run atomic i2c xfer when !preemptible + - mcb: fix error handling for different scenarios when parsing + - dmaengine: stm32-mdma: correct desc prep when channel running + - mm/cma: use nth_page() in place of direct struct page manipulation + - i3c: master: cdns: Fix reading status register + - parisc: Prevent booting 64-bit kernels on PA1.x machines + - parisc/pgtable: Do not drop upper 5 address bits of physical address + - ALSA: info: Fix potential deadlock at disconnection + - ALSA: hda/realtek - Enable internal speaker of ASUS K6500ZC + - serial: meson: remove redundant initialization of variable id + - tty: serial: meson: retrieve port FIFO size from DT + - serial: meson: Use platform_get_irq() to get the interrupt + - tty: serial: meson: fix hard LOCKUP on crtscts mode + - Bluetooth: btusb: add Realtek 8822CE to usb_device_id table + - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0cb8:0xc559 + - bluetooth: Add device 0bda:887b to device tables + - bluetooth: Add device 13d3:3571 to device tables + - Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables + - Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE + - Revert ncsi: Propagate carrier gain/loss events to the NCSI controller + - net: dsa: lan9303: consequently nested-lock physical MDIO + - i2c: i801: fix potential race in i801_block_transaction_byte_by_byte + - media: lirc: drop trailing space from scancode transmit + - media: sharp: fix sharp encoding + - media: venus: hfi_parser: Add check to keep the number of codecs within + range + - media: venus: hfi: fix the check to handle session buffer requirement + - media: venus: hfi: add checks to handle capabilities from firmware + - nfsd: fix file memleak on client_opens_release + - ext4: apply umask if ACL support is disabled + - ext4: correct offset of gdb backup in non meta_bg group to update_backups + - ext4: correct return value of ext4_convert_meta_bg + - ext4: correct the start block of counting reserved clusters + - ext4: remove gdb backup copy for meta bg in setup_new_flex_group_blocks + - drm/amdgpu: fix error handling in amdgpu_bo_list_get() + - tracing: Have trace_event_file have ref counters + - netfilter: nf_tables: pass context to nft_set_destroy() + - netfilter: nftables: rename set element data activation/deactivation + functions + - netfilter: nf_tables: drop map element references from preparation phase + - netfilter: nft_set_rbtree: Switch to node list walk for overlap detection + - netfilter: nft_set_rbtree: fix null deref on element insertion + - netfilter: nft_set_rbtree: fix overlap expiration walk + - netfilter: nf_tables: don't skip expired elements during walk + - netfilter: nf_tables: GC transaction API to avoid race with control plane + - netfilter: nf_tables: adapt set backend to use GC transaction API + - netfilter: nft_set_hash: mark set element as dead when deleting from packet + path + - netfilter: nf_tables: remove busy mark and gc batch API + - netfilter: nf_tables: fix GC transaction races with netns and netlink event + exit path + - netfilter: nf_tables: GC transaction race with netns dismantle + - netfilter: nf_tables: GC transaction race with abort path + - netfilter: nf_tables: use correct lock to protect gc_list + - netfilter: nf_tables: defer gc run if previous batch is still pending + - netfilter: nft_set_rbtree: skip sync GC for new elements in this transaction + - netfilter: nft_set_rbtree: use read spinlock to avoid datapath contention + - netfilter: nft_set_hash: try later when GC hits EAGAIN on iteration + - netfilter: nf_tables: fix memleak when more than 255 elements expired + - netfilter: nf_tables: unregister flowtable hooks on netns exit + - netfilter: nf_tables: double hook unregistration in netns path + - netfilter: nftables: update table flags from the commit phase + - netfilter: nf_tables: fix table flag updates + - netfilter: nf_tables: disable toggling dormant table state more than once + - netfilter: nf_tables: bogus EBUSY when deleting flowtable after flush (for + 5.4) + - Linux 5.4.262 + * Focal update: v5.4.261 upstream stable release (LP: #2049049) + - vfs: fix readahead(2) on block devices + - genirq/matrix: Exclude managed interrupts in irq_matrix_allocated() + - i40e: fix potential memory leaks in i40e_remove() + - tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed + - wifi: rtw88: debug: Fix the NULL vs IS_ERR() bug for debugfs_create_file() + - wifi: mt76: mt7603: rework/fix rx pse hang check + - tcp_metrics: add missing barriers on delete + - tcp_metrics: properly set tp->snd_ssthresh in tcp_init_metrics() + - tcp_metrics: do not create an entry from tcp_init_metrics() + - wifi: rtlwifi: fix EDCA limit set by BT coexistence + - can: dev: can_restart(): don't crash kernel if carrier is OK + - can: dev: can_restart(): fix race condition between controller restart and + netif_carrier_on() + - thermal: core: prevent potential string overflow + - r8169: use tp_to_dev instead of open code + - r8169: fix rare issue with broken rx after link-down on RTL8125 + - chtls: fix tp->rcv_tstamp initialization + - tcp: Remove one extra ktime_get_ns() from cookie_init_timestamp + - tcp: fix cookie_init_timestamp() overflows + - ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias() + - ipv6: avoid atomic fragment on GSO packets + - net: add DEV_STATS_READ() helper + - ipvlan: properly track tx_errors + - regmap: debugfs: Fix a erroneous check after snprintf() + - clk: qcom: clk-rcg2: Fix clock rate overflow for high parent frequencies + - clk: qcom: gcc-sm8150: use ARRAY_SIZE instead of specifying num_parents + - clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src + - clk: imx: Select MXC_CLK for CLK_IMX8QXP + - clk: keystone: pll: fix a couple NULL vs IS_ERR() checks + - clk: npcm7xx: Fix incorrect kfree + - clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data + - clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data + - platform/x86: wmi: Fix probe failure when failing to register WMI devices + - platform/x86: wmi: remove unnecessary initializations + - platform/x86: wmi: Fix opening of char device + - hwmon: (coretemp) Fix potentially truncated sysfs attribute name + - drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs + - drm/rockchip: vop: Fix call to crtc reset helper + - drm/radeon: possible buffer overflow + - drm/rockchip: cdn-dp: Fix some error handling paths in cdn_dp_probe() + - arm64: dts: qcom: sdm845-mtp: fix WiFi configuration + - ARM: dts: qcom: mdm9615: populate vsdcc fixed regulator + - soc: qcom: llcc cleanup to get rid of sdm845 specific driver file + - [Config] remove CONFIG_QCOM_SDM845_LLCC + - soc: qcom: Rename llcc-slice to llcc-qcom + - [Config] remove llcc-slice module + - soc: qcom: llcc: Handle a second device without data corruption + - firmware: ti_sci: Replace HTTP links with HTTPS ones + - firmware: ti_sci: Mark driver as non removable + - clk: scmi: Free scmi_clk allocated when the clocks with invalid info are + skipped + - hwrng: geode - fix accessing registers + - libnvdimm/of_pmem: Use devm_kstrdup instead of kstrdup and check its return + value + - sched/rt: Provide migrate_disable/enable() inlines + - nd_btt: Make BTT lanes preemptible + - crypto: caam/qi2 - fix Chacha20 + Poly1305 self test failure + - crypto: caam/jr - fix Chacha20 + Poly1305 self test failure + - HID: cp2112: Use irqchip template + - hid: cp2112: Fix duplicate workqueue initialization + - ARM: 9321/1: memset: cast the constant byte to unsigned char + - ext4: move 'ix' sanity check to corrent position + - scsi: ufs: core: Leave space for '\0' in utf8 desc string + - RDMA/hfi1: Workaround truncation compilation error + - sh: bios: Revive earlyprintk support + - ASoC: Intel: Skylake: Fix mem leak when parsing UUIDs fails + - ASoC: ams-delta.c: use component after check + - mfd: dln2: Fix double put in dln2_probe + - leds: pwm: simplify if condition + - leds: pwm: convert to atomic PWM API + - leds: pwm: Don't disable the PWM when the LED should be off + - ledtrig-cpu: Limit to 8 CPUs + - leds: trigger: ledtrig-cpu:: Fix 'output may be truncated' issue for 'cpu' + - tty: tty_jobctrl: fix pid memleak in disassociate_ctty() + - usb: dwc2: fix possible NULL pointer dereference caused by driver + concurrency + - dmaengine: ti: edma: handle irq_of_parse_and_map() errors + - misc: st_core: Do not call kfree_skb() under spin_lock_irqsave() + - tools: iio: privatize globals and functions in iio_generic_buffer.c file + - tools: iio: iio_generic_buffer: Fix some integer type and calculation + - tools: iio: iio_generic_buffer ensure alignment + - USB: usbip: fix stub_dev hub disconnect + - dmaengine: pxa_dma: Remove an erroneous BUG_ON() in pxad_free_desc() + - f2fs: fix to initialize map.m_pblk in f2fs_precache_extents() + - modpost: fix tee MODULE_DEVICE_TABLE built on big-endian host + - powerpc/xive: Fix endian conversion size + - powerpc/imc-pmu: Use the correct spinlock initializer. + - powerpc/pseries: fix potential memory leak in init_cpu_associativity() + - i3c: Fix potential refcount leak in i3c_master_register_new_i3c_devs + - rtc: pcf85363: fix wrong mask/val parameters in regmap_update_bits call + - pcmcia: cs: fix possible hung task and memory leak pccardd() + - pcmcia: ds: fix refcount leak in pcmcia_device_add() + - pcmcia: ds: fix possible name leak in error path in pcmcia_device_add() + - media: bttv: fix use after free error due to btv->timeout timer + - media: s3c-camif: Avoid inappropriate kfree() + - media: dvb-usb-v2: af9035: fix missing unlock + - regmap: prevent noinc writes from clobbering cache + - pwm: sti: Avoid conditional gotos + - pwm: sti: Reduce number of allocations and drop usage of chip_data + - pwm: brcmstb: Utilize appropriate clock APIs in suspend/resume + - Input: synaptics-rmi4 - fix use after free in rmi_unregister_function() + - llc: verify mac len before reading mac header + - tipc: Change nla_policy for bearer-related names to NLA_NUL_STRING + - inet: shrink struct flowi_common + - dccp: Call security_inet_conn_request() after setting IPv4 addresses. + - dccp/tcp: Call security_inet_conn_request() after setting IPv6 addresses. + - Fix termination state for idr_for_each_entry_ul() + - net: stmmac: xgmac: Enable support for multiple Flexible PPS outputs + - net/smc: fix dangling sock under state SMC_APPFINCLOSEWAIT + - tg3: power down device only on SYSTEM_POWER_OFF + - r8169: respect userspace disabling IFF_MULTICAST + - netfilter: xt_recent: fix (increase) ipv6 literal buffer length + - netfilter: nft_redir: use `struct nf_nat_range2` throughout and deduplicate + eval call-backs + - netfilter: nat: fix ipv6 nat redirect with mapped and scoped addresses + - drm/syncobj: fix DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE + - spi: spi-zynq-qspi: add spi-mem to driver kconfig dependencies + - fbdev: imsttfb: Fix error path of imsttfb_probe() + - fbdev: imsttfb: fix a resource leak in probe + - fbdev: fsl-diu-fb: mark wr_reg_wa() static + - Revert "mmc: core: Capture correct oemid-bits for eMMC cards" + - btrfs: use u64 for buffer sizes in the tree search ioctls + - Linux 5.4.261 + * Focal update: v5.4.260 upstream stable release (LP: #2049024) + - mtd: rawnand: marvell: Ensure program page operations are successful + - selftests/ftrace: Add new test case which checks non unique symbol + - mcb: Return actual parsed size when reading chameleon table + - mcb-lpc: Reallocate memory region to avoid memory overlapping + - virtio_balloon: Fix endless deflation and inflation on arm64 + - virtio-mmio: fix memory leak of vm_dev + - r8169: fix the KCSAN reported data-race in rtl_tx while reading + TxDescArray[entry].opts1 + - r8169: fix the KCSAN reported data race in rtl_rx while reading desc->opts1 + - treewide: Spelling fix in comment + - igb: Fix potential memory leak in igb_add_ethtool_nfc_entry + - neighbour: fix various data-races + - igc: Fix ambiguity in the ethtool advertising + - net: ieee802154: adf7242: Fix some potential buffer overflow in + adf7242_stats_show() + - r8152: Increase USB control msg timeout to 5000ms as per spec + - r8152: Run the unload routine if we have errors during probe + - r8152: Cancel hw_phy_work if we have an error in probe + - tcp: fix wrong RTO timeout when received SACK reneging + - gtp: uapi: fix GTPA_MAX + - gtp: fix fragmentation needed check with gso + - iio: exynos-adc: request second interupt only when touchscreen mode is used + - i2c: muxes: i2c-mux-pinctrl: Use of_get_i2c_adapter_by_node() + - i2c: muxes: i2c-mux-gpmux: Use of_get_i2c_adapter_by_node() + - i2c: muxes: i2c-demux-pinctrl: Use of_get_i2c_adapter_by_node() + - i2c: stm32f7: Fix PEC handling in case of SMBUS transfers + - i2c: aspeed: Fix i2c bus hang in slave read + - nvmem: imx: correct nregs for i.MX6ULL + - nvmem: imx: correct nregs for i.MX6SLL + - nvmem: imx: correct nregs for i.MX6UL + - perf/core: Fix potential NULL deref + - clk: Sanitize possible_parent_show to Handle Return Value of + of_clk_get_parent_name + - i40e: Fix wrong check for I40E_TXR_FLAGS_WB_ON_ITR + - x86/i8259: Skip probing when ACPI/MADT advertises PCAT compatibility + - drm/dp_mst: Fix NULL deref in get_mst_branch_device_by_guid_helper() + - arm64: fix a concurrency issue in emulation_proc_handler() + - smbdirect: missing rc checks while waiting for rdma events + - f2fs: fix to do sanity check on inode type during garbage collection + - nfsd: lock_rename() needs both directories to live on the same fs + - x86/mm: Simplify RESERVE_BRK() + - x86/mm: Fix RESERVE_BRK() for older binutils + - ext4: add two helper functions extent_logical_end() and pa_logical_end() + - ext4: avoid overlapping preallocations due to overflow + - ext4: fix BUG in ext4_mb_new_inode_pa() due to overflow + - driver: platform: Add helper for safer setting of driver_override + - rpmsg: Constify local variable in field store macro + - rpmsg: Fix kfree() of static memory on setting driver_override + - rpmsg: Fix calling device_lock() on non-initialized device + - rpmsg: glink: Release driver_override + - rpmsg: Fix possible refcount leak in rpmsg_register_device_override() + - x86: Fix .brk attribute in linker script + - Input: i8042 - add Fujitsu Lifebook E5411 to i8042 quirk table + - irqchip/stm32-exti: add missing DT IRQ flag translation + - dmaengine: ste_dma40: Fix PM disable depth imbalance in d40_probe + - Input: synaptics-rmi4 - handle reset delay when using SMBus trsnsport + - fbdev: atyfb: only use ioremap_uc() on i386 and ia64 + - spi: npcm-fiu: Fix UMA reads when dummy.nbytes == 0 + - netfilter: nfnetlink_log: silence bogus compiler warning + - ASoC: rt5650: fix the wrong result of key button + - fbdev: uvesafb: Call cn_del_callback() at the end of uvesafb_exit() + - scsi: mpt3sas: Fix in error path + - platform/x86: asus-wmi: Change ASUS_WMI_BRN_DOWN code from 0x20 to 0x2e + - platform/mellanox: mlxbf-tmfifo: Fix a warning message + - net: chelsio: cxgb4: add an error code check in t4_load_phy_fw + - ata: ahci: fix enum constants for gcc-13 + - remove the sx8 block driver + - [Config] remove CONFIG_BLK_DEV_SX8 + - Revert "ARM: dts: Move am33xx and am43xx mmc nodes to sdhci-omap driver" + - PCI: Prevent xHCI driver from claiming AMD VanGogh USB3 DRD device + - usb: storage: set 1.50 as the lower bcdDevice for older "Super Top" + compatibility + - tty: 8250: Remove UC-257 and UC-431 + - tty: 8250: Add support for additional Brainboxes UC cards + - tty: 8250: Add support for Brainboxes UP cards + - tty: 8250: Add support for Intashield IS-100 + - Linux 5.4.260 + * CVE-2023-51779 + - Bluetooth: af_bluetooth: Fix Use-After-Free in bt_sock_recvmsg + * CVE-2023-22995 + - usb: dwc3: dwc3-qcom: Add missing platform_device_put() in + dwc3_qcom_acpi_register_core + + -- Joseph Salisbury Thu, 15 Feb 2024 12:22:11 -0500 + +linux-oracle (5.4.0-1118.127) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1118.127 -proposed tracker (LP: #2052215) + + [ Ubuntu: 5.4.0-172.190 ] + + * focal/linux: 5.4.0-172.190 -proposed tracker (LP: #2052220) + * CVE-2023-51781 + - appletalk: Fix Use-After-Free in atalk_ioctl + * CVE-2023-6915 + - ida: Fix crash in ida_free when the bitmap is empty + * CVE-2024-0565 + - smb: client: fix OOB in receive_encrypted_standard() + * CVE-2024-0646 + - net: tls, update curr on splice as well + + -- Joseph Salisbury Thu, 08 Feb 2024 12:20:23 -0500 + +linux-oracle (5.4.0-1117.126) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1117.126 -proposed tracker (LP: #2048277) + + [ Ubuntu: 5.4.0-171.189 ] + + * focal/linux: 5.4.0-171.189 -proposed tracker (LP: #2048282) + * Packaging resync (LP: #1786013) + - [Packaging] remove helper scripts + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/2024.01.08) + * Page fault in RDMA ODP triggers BUG_ON during MMU notifier registration + (LP: #2046534) + - RDMA/odp: Ensure the mm is still alive before creating an implicit child + * Hotplugging SCSI disk in QEMU VM fails (LP: #2047382) + - Revert "PCI: acpiphp: Reassign resources on bridge if necessary" + * CVE-2023-6040 + - netfilter: nf_tables: Reject tables of unsupported family + * kernel_selftests failures on kernel-P10d-LPAR10.ppc64el.10 + (LP: #2032641) + - selftests: Skip TM tests on synthetic TM implementations + * [Debian] autoreconstruct - Do not generate chmod -x for deleted files + (LP: #2045562) + - [Debian] autoreconstruct - Do not generate chmod -x for deleted files + * CVE-2023-6931 + - perf/core: Add a new read format to get a number of lost samples + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + * CVE-2023-45863 + - kobject: Fix slab-out-of-bounds in fill_kobj_path() + * Focal update: v5.4.259 upstream stable release (LP: #2043724) + - RDMA/cxgb4: Check skb value for failure to allocate + - lib/test_meminit: fix off-by-one error in test_pages() + - pwm: hibvt: Explicitly set .polarity in .get_state() + - HID: logitech-hidpp: Fix kernel crash on receiver USB disconnect + - quota: Fix slow quotaoff + - net: prevent address rewrite in kernel_bind() + - drm: etvnaviv: fix bad backport leading to warning + - drm/msm/dsi: skip the wait for video mode done if not applicable + - ravb: Fix up dma_free_coherent() call in ravb_remove() + - ieee802154: ca8210: Fix a potential UAF in ca8210_probe + - mlxsw: fix mlxsw_sp2_nve_vxlan_learning_set() return type + - xen-netback: use default TX queue size for vifs + - drm/vmwgfx: fix typo of sizeof argument + - ixgbe: fix crash with empty VF macvlan list + - net: nfc: fix races in nfc_llcp_sock_get() and nfc_llcp_sock_get_sn() + - nfc: nci: assert requested protocol is valid + - workqueue: Override implicit ordered attribute in + workqueue_apply_unbound_cpumask() + - dmaengine: stm32-mdma: abort resume if no ongoing transfer + - usb: xhci: xhci-ring: Use sysdev for mapping bounce buffer + - net: usb: dm9601: fix uninitialized variable use in dm9601_mdio_read + - usb: dwc3: Soft reset phy on probe for host + - usb: musb: Get the musb_qh poniter after musb_giveback + - usb: musb: Modify the "HWVers" register address + - iio: pressure: bmp280: Fix NULL pointer exception + - iio: pressure: dps310: Adjust Timeout Settings + - iio: pressure: ms5611: ms5611_prom_is_valid false negative bug + - mcb: remove is_added flag from mcb_device struct + - libceph: use kernel_connect() + - ceph: fix incorrect revoked caps assert in ceph_fill_file_size() + - Input: powermate - fix use-after-free in powermate_config_complete + - Input: psmouse - fix fast_reconnect function for PS/2 mode + - Input: xpad - add PXN V900 support + - cgroup: Remove duplicates in cgroup v1 tasks file + - pinctrl: avoid unsafe code pattern in find_pinctrl() + - usb: gadget: udc-xilinx: replace memcpy with memcpy_toio + - usb: gadget: ncm: Handle decoding of multiple NTB's in unwrap call + - x86/cpu: Fix AMD erratum #1485 on Zen4-based CPUs + - dmaengine: mediatek: Fix deadlock caused by synchronize_irq() + - powerpc/8xx: Fix pte_access_permitted() for PAGE_NONE + - powerpc/64e: Fix wrong test in __ptep_test_and_clear_young() + - ravb: Fix use-after-free issue in ravb_tx_timeout_work() + - Documentation: sysctl: align cells in second content column + - usb: hub: Guard against accesses to uninitialized BOS descriptors + - Bluetooth: hci_event: Ignore NULL link key + - Bluetooth: Reject connection with the device which has same BD_ADDR + - Bluetooth: Fix a refcnt underflow problem for hci_conn + - Bluetooth: vhci: Fix race when opening vhci device + - Bluetooth: hci_event: Fix coding style + - Bluetooth: avoid memcmp() out of bounds warning + - ice: fix over-shifted variable + - nfc: nci: fix possible NULL pointer dereference in send_acknowledge() + - regmap: fix NULL deref on lookup + - KVM: x86: Mask LVTPC when handling a PMI + - netfilter: nft_payload: fix wrong mac header matching + - qed: fix LL2 RX buffer allocation + - xfrm: fix a data-race in xfrm_gen_index() + - xfrm: interface: use DEV_STATS_INC() + - net: ipv4: fix return value check in esp_remove_trailer + - net: ipv6: fix return value check in esp_remove_trailer + - net: rfkill: gpio: prevent value glitch during probe + - tcp: fix excessive TLP and RACK timeouts from HZ rounding + - tcp: tsq: relax tcp_small_queue_check() when rtx queue contains a single skb + - tun: prevent negative ifindex + - ipv4: fib: annotate races around nh->nh_saddr_genid and nh->nh_saddr + - net: usb: smsc95xx: Fix an error code in smsc95xx_reset() + - i40e: prevent crash on probe if hw registers have invalid values + - net/sched: sch_hfsc: upgrade 'rt' to 'sc' when it becomes a inner curve + - neighbor: tracing: Move pin6 inside CONFIG_IPV6=y section + - netfilter: nft_set_rbtree: .deactivate fails if element has expired + - net: pktgen: Fix interface flags printing + - resource: Add irqresource_disabled() + - ACPI: Drop acpi_dev_irqresource_disabled() + - ACPI: resource: Skip IRQ override on Asus Vivobook S5602ZA + - ACPI: resource: Add Asus ExpertBook B2502 to Asus quirks + - ACPI: resource: Skip IRQ override on Asus Expertbook B2402CBA + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1502CBA + - ACPI: resource: Skip IRQ override on ASUS ExpertBook B1402CBA + - ARM: dts: ti: omap: Fix noisy serial with overrun-throttle-ms for mapphone + - btrfs: return -EUCLEAN for delayed tree ref with a ref count not equals to 1 + - btrfs: initialize start_slot in btrfs_log_prealloc_extents + - i2c: mux: Avoid potential false error message in i2c_mux_add_adapter + - overlayfs: set ctime when setting mtime and atime + - gpio: timberdale: Fix potential deadlock on &tgpio->lock + - ata: libata-eh: Fix compilation warning in ata_eh_link_report() + - tracing: relax trace_event_eval_update() execution with cond_resched() + - HID: holtek: fix slab-out-of-bounds Write in holtek_kbd_input_event + - Bluetooth: Avoid redundant authentication + - Bluetooth: hci_core: Fix build warnings + - wifi: mac80211: allow transmitting EAPOL frames with tainted key + - wifi: cfg80211: avoid leaking stack data into trace + - regulator/core: Revert "fix kobject release warning and memory leak in + regulator_register()" + - sky2: Make sure there is at least one frag_addr available + - drm: panel-orientation-quirks: Add quirk for One Mix 2S + - btrfs: fix some -Wmaybe-uninitialized warnings in ioctl.c + - HID: multitouch: Add required quirk for Synaptics 0xcd7e device + - Bluetooth: hci_event: Fix using memcmp when comparing keys + - mtd: rawnand: qcom: Unmap the right resource upon probe failure + - mtd: spinand: micron: correct bitmask for ecc status + - mtd: physmap-core: Restore map_rom fallback + - mmc: core: sdio: hold retuning if sdio in 1-bit mode + - mmc: core: Capture correct oemid-bits for eMMC cards + - Revert "pinctrl: avoid unsafe code pattern in find_pinctrl()" + - ACPI: irq: Fix incorrect return value in acpi_register_gsi() + - USB: serial: option: add Telit LE910C4-WWX 0x1035 composition + - USB: serial: option: add entry for Sierra EM9191 with new firmware + - USB: serial: option: add Fibocom to DELL custom modem FM101R-GL + - s390/pci: fix iommu bitmap allocation + - gpio: vf610: set value before the direction to avoid a glitch + - ASoC: pxa: fix a memory leak in probe() + - phy: mapphone-mdm6600: Fix runtime disable on probe + - phy: mapphone-mdm6600: Fix runtime PM for remove + - phy: mapphone-mdm6600: Fix pinctrl_pm handling for sleep pins + - Bluetooth: hci_sock: fix slab oob read in create_monitor_event + - Bluetooth: hci_sock: Correctly bounds check and pad HCI_MON_NEW_INDEX name + - xfrm6: fix inet6_dev refcount underflow problem + - Linux 5.4.259 + * Focal update: v5.4.258 upstream stable release (LP: #2042107) + - NFS/pNFS: Report EINVAL errors from connect() to the server + - SUNRPC: Mark the cred for revalidation if the server rejects it + - tracing: Increase trace array ref count on enable and filter files + - ata: libahci: clear pending interrupt status + - ext4: remove the 'group' parameter of ext4_trim_extent + - ext4: add new helper interface ext4_try_to_trim_range() + - ext4: scope ret locally in ext4_try_to_trim_range() + - ext4: change s_last_trim_minblks type to unsigned long + - ext4: mark group as trimmed only if it was fully scanned + - ext4: replace the traditional ternary conditional operator with with + max()/min() + - ext4: move setting of trimmed bit into ext4_try_to_trim_range() + - ext4: do not let fstrim block system suspend + - ASoC: meson: spdifin: start hw on dai probe + - netfilter: nf_tables: disallow element removal on anonymous sets + - bpf: Avoid deadlock when using queue and stack maps from NMI + - selftests/tls: Add {} to avoid static checker warning + - selftests: tls: swap the TX and RX sockets in some tests + - ASoC: imx-audmix: Fix return error with devm_clk_get() + - i40e: Fix for persistent lldp support + - SAUCE: Revert "UBUNTU: SAUCE: i40e Fix GPF when deleting VMs" + - i40e: Remove scheduling while atomic possibility + - i40e: Fix warning message and call stack during rmmod i40e driver + - i40e: Fix VF VLAN offloading when port VLAN is configured + - powerpc/perf/hv-24x7: Update domain value check + - dccp: fix dccp_v4_err()/dccp_v6_err() again + - net: hns3: add 5ms delay before clear firmware reset irq source + - net: bridge: use DEV_STATS_INC() + - team: fix null-ptr-deref when team device type is changed + - net: rds: Fix possible NULL-pointer dereference + - gpio: tb10x: Fix an error handling path in tb10x_gpio_probe() + - i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() + - Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN + - scsi: qla2xxx: Fix update_fcport for current_topology + - scsi: qla2xxx: Fix deletion race condition + - drm/amd/display: Reinstate LFC optimization + - drm/amd/display: Fix LFC multiplier changing erratically + - drm/amd/display: prevent potential division by zero errors + - ata: libata: disallow dev-initiated LPM transitions to unsupported states + - MIPS: Alchemy: only build mmc support helpers if au1xmmc is enabled + - clk: tegra: fix error return case for recalc_rate + - ARM: dts: ti: omap: motorola-mapphone: Fix abe_clkctrl warning on boot + - bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up + - xtensa: add default definition for XCHAL_HAVE_DIV32 + - xtensa: iss/network: make functions static + - xtensa: boot: don't add include-dirs + - xtensa: boot/lib: fix function prototypes + - gpio: pmic-eic-sprd: Add can_sleep flag for PMIC EIC chip + - parisc: sba: Fix compile warning wrt list of SBA devices + - parisc: iosapic.c: Fix sparse warnings + - parisc: drivers: Fix sparse warning + - parisc: irq: Make irq_stack_union static to avoid sparse warning + - selftests/ftrace: Correctly enable event in instance-event.tc + - ring-buffer: Avoid softlockup in ring_buffer_resize() + - ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() + - spi: nxp-fspi: reset the FLSHxCR1 registers + - bpf: Clarify error expectations from bpf_clone_redirect + - powerpc/watchpoints: Annotate atomic context in more places + - ncsi: Propagate carrier gain/loss events to the NCSI controller + - fbdev/sh7760fb: Depend on FB=y + - nvme-pci: do not set the NUMA node of device if it has none + - watchdog: iTCO_wdt: No need to stop the timer in probe + - watchdog: iTCO_wdt: Set NO_REBOOT if the watchdog is not already running + - i40e: improve locking of mac_filter_hash + - i40e: always propagate error value in i40e_set_vsi_promisc() + - i40e: fix return of uninitialized aq_ret in i40e_set_vsi_promisc + - smack: Record transmuting in smk_transmuted + - smack: Retrieve transmuting information in smack_inode_getsecurity() + - Smack:- Use overlay inode label in smack_inode_copy_up() + - serial: 8250_port: Check IRQ data before use + - nilfs2: fix potential use after free in nilfs_gccache_submit_read_data() + - ALSA: hda: Disable power save for solving pop issue on Lenovo ThinkCentre + M70q + - ata: libata-scsi: ignore reserved bits for REPORT SUPPORTED OPERATION CODES + - i2c: i801: unregister tco_pdev in i801_probe() error path + - ring-buffer: Update "shortest_full" in polling + - btrfs: properly report 0 avail for very full file systems + - net: thunderbolt: Fix TCPv6 GSO checksum calculation + - ata: libata-core: Fix ata_port_request_pm() locking + - ata: libata-core: Fix port and device removal + - ata: libata-core: Do not register PM operations for SAS ports + - ata: libata-sata: increase PMP SRST timeout to 10s + - fs: binfmt_elf_efpic: fix personality for ELF-FDPIC + - rbd: move rbd_dev_refresh() definition + - rbd: decouple header read-in from updating rbd_dev->header + - rbd: decouple parent info read-in from updating rbd_dev + - rbd: take header_rwsem in rbd_dev_refresh() only when updating + - Revert "PCI: qcom: Disable write access to read only registers for IP + v2.3.3" + - scsi: zfcp: Fix a double put in zfcp_port_enqueue() + - qed/red_ll2: Fix undefined behavior bug in struct qed_ll2_info + - wifi: mwifiex: Fix tlv_buf_left calculation + - net: replace calls to sock->ops->connect() with kernel_connect() + - net: prevent rewrite of msg_name in sock_sendmsg() + - wifi: iwlwifi: dbg_ini: fix structure packing + - wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet + - drivers/net: process the result of hdlc_open() and add call of hdlc_close() + in uhdlc_close() + - wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling + - regmap: rbtree: Fix wrong register marked as in-cache when creating new node + - ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig + - scsi: target: core: Fix deadlock due to recursive locking + - NFS4: Trace state recovery operation + - NFS: Add a helper nfs_client_for_each_server() + - NFSv4: Fix a nfs4_state_manager() race + - modpost: add missing else to the "of" check + - net: fix possible store tearing in neigh_periodic_work() + - ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data() + - net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent + - net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg + - net: nfc: llcp: Add lock when modifying device list + - netfilter: handle the connecting collision properly in + nf_conntrack_proto_sctp + - net: stmmac: dwmac-stm32: fix resume on STM32 MCU + - tcp: fix quick-ack counting to count actual ACKs of new data + - tcp: fix delayed ACKs for MSS boundary condition + - sctp: update transport state when processing a dupcook packet + - sctp: update hb timer immediately after users change hb_interval + - cpupower: add Makefile dependencies for install targets + - RDMA/core: Require admin capabilities to set system parameters + - IB/mlx4: Fix the size of a buffer in add_port_entries() + - gpio: aspeed: fix the GPIO number passed to pinctrl_gpio_set_config() + - gpio: pxa: disable pinctrl calls for MMP_GPIO + - RDMA/cma: Fix truncation compilation warning in make_cma_ports + - RDMA/uverbs: Fix typo of sizeof argument + - RDMA/siw: Fix connection failure handling + - RDMA/mlx5: Fix NULL string error + - parisc: Restore __ldcw_align for PA-RISC 2.0 processors + - NFS: Fix a race in __nfs_list_for_each_server() + - ima: rework CONFIG_IMA dependency block + - [Config] Update IMA_BLACKLIST_KEYRING and IMA_LOAD_X509 + - xen/events: replace evtchn_rwlock with RCU + - Linux 5.4.258 + + -- Joseph Salisbury Tue, 16 Jan 2024 11:16:10 -0500 + +linux-oracle (5.4.0-1116.125) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1116.125 -proposed tracker (LP: #2048649) + + * Packaging resync (LP: #1786013) + - [Packaging] remove helper scripts + + [ Ubuntu: 5.4.0-170.188 ] + + * focal/linux: 5.4.0-170.188 -proposed tracker (LP: #2048654) + * CVE-2023-6040 + - netfilter: nf_tables: Reject tables of unsupported family + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + * CVE-2023-6931 + - perf/core: Add a new read format to get a number of lost samples + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + + -- Joseph Salisbury Thu, 11 Jan 2024 11:29:21 -0500 + +linux-oracle (5.4.0-1115.124) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1115.124 -proposed tracker (LP: #2044801) + + [ Ubuntu: 5.4.0-169.187 ] + + * focal/linux: 5.4.0-169.187 -proposed tracker (LP: #2044375) + * USB bus error after upgrading to proposed kernel on lunar, jammy and focal + (LP: #2043197) + - USB: core: Fix oversight in SuperSpeed initialization + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + - [Packaging] update annotations scripts + + -- Joseph Salisbury Mon, 27 Nov 2023 15:22:35 -0500 + +linux-oracle (5.4.0-1114.123) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1114.123 -proposed tracker (LP: #2041646) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + + [ Ubuntu: 5.4.0-168.186 ] + + * focal/linux: 5.4.0-168.186 -proposed tracker (LP: #2041652) + * Focal update: v5.4.257 upstream stable release (LP: #2040284) + - erofs: ensure that the post-EOF tails are all zeroed + - ARM: pxa: remove use of symbol_get() + - mmc: au1xmmc: force non-modular build and remove symbol_get usage + - net: enetc: use EXPORT_SYMBOL_GPL for enetc_phc_index + - rtc: ds1685: use EXPORT_SYMBOL_GPL for ds1685_rtc_poweroff + - modules: only allow symbol_get of EXPORT_SYMBOL_GPL modules + - USB: serial: option: add Quectel EM05G variant (0x030e) + - USB: serial: option: add FOXCONN T99W368/T99W373 product + - HID: wacom: remove the battery when the EKR is off + - staging: rtl8712: fix race condition + - Bluetooth: btsdio: fix use after free bug in btsdio_remove due to race + condition + - serial: sc16is7xx: fix bug when first setting GPIO direction + - firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe + - fsi: master-ast-cf: Add MODULE_FIRMWARE macro + - nilfs2: fix general protection fault in nilfs_lookup_dirty_data_buffers() + - nilfs2: fix WARNING in mark_buffer_dirty due to discarded buffer reuse + - pinctrl: amd: Don't show `Invalid config param` errors + - 9p: virtio: make sure 'offs' is initialized in zc_request + - ASoC: da7219: Flush pending AAD IRQ when suspending + - ASoC: da7219: Check for failure reading AAD IRQ events + - ethernet: atheros: fix return value check in atl1c_tso_csum() + - vxlan: generalize vxlan_parse_gpe_hdr and remove unused args + - m68k: Fix invalid .section syntax + - s390/dasd: use correct number of retries for ERP requests + - s390/dasd: fix hanging device after request requeue + - fs/nls: make load_nls() take a const parameter + - ASoc: codecs: ES8316: Fix DMIC config + - ASoC: atmel: Fix the 8K sample parameter in I2SC master + - platform/x86: intel: hid: Always call BTNL ACPI method + - platform/x86: huawei-wmi: Silence ambient light sensor + - security: keys: perform capable check only on privileged operations + - clk: fixed-mmio: make COMMON_CLK_FIXED_MMIO depend on HAS_IOMEM + - net: usb: qmi_wwan: add Quectel EM05GV2 + - idmaengine: make FSL_EDMA and INTEL_IDMA64 depends on HAS_IOMEM + - scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock + - netlabel: fix shift wrapping bug in netlbl_catmap_setlong() + - bnx2x: fix page fault following EEH recovery + - sctp: handle invalid error codes without calling BUG() + - cifs: add a warning when the in-flight count goes negative + - scsi: storvsc: Always set no_report_opcodes + - ALSA: seq: oss: Fix racy open/close of MIDI devices + - platform/mellanox: Fix mlxbf-tmfifo not handling all virtio CONSOLE + notifications + - powerpc/32s: Fix assembler warning about r0 + - udf: Check consistency of Space Bitmap Descriptor + - udf: Handle error when adding extent to a file + - Revert "net: macsec: preserve ingress frame ordering" + - reiserfs: Check the return value from __getblk() + - eventfd: Export eventfd_ctx_do_read() + - eventfd: prevent underflow for eventfd semaphores + - new helper: lookup_positive_unlocked() + - fs: Fix error checking for d_hash_and_lookup() + - tmpfs: verify {g,u}id mount options correctly + - OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() + - x86/asm: Make more symbols local + - x86/boot: Annotate local functions + - x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved + - perf/imx_ddr: don't enable counter0 if none of 4 counters are used + - cpufreq: powernow-k8: Use related_cpus instead of cpus in driver.exit() + - bpf: Clear the probe_addr for uprobe + - tcp: tcp_enter_quickack_mode() should be static + - regmap: rbtree: Use alloc_flags for memory allocations + - spi: tegra20-sflash: fix to check return value of platform_get_irq() in + tegra_sflash_probe() + - can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors also + in case of OOM + - wifi: mwifiex: Fix OOB and integer underflow when rx packets + - mwifiex: switch from 'pci_' to 'dma_' API + - wifi: mwifiex: fix error recovery in PCIE buffer descriptor management + - crypto: stm32 - Properly handle pm_runtime_get failing + - Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe() + - crypto: caam - fix unchecked return value error + - hwrng: iproc-rng200 - use semicolons rather than commas to separate + statements + - hwrng: iproc-rng200 - Implement suspend and resume calls + - lwt: Fix return values of BPF xmit ops + - lwt: Check LWTUNNEL_XMIT_CONTINUE strictly + - fs: ocfs2: namei: check return value of ocfs2_add_entry() + - wifi: mwifiex: fix memory leak in mwifiex_histogram_read() + - wifi: mwifiex: Fix missed return in oob checks failed path + - wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx + - wifi: ath9k: protect WMI command response buffer replacement with a lock + - wifi: mwifiex: avoid possible NULL skb pointer dereference + - wifi: ath9k: use IS_ERR() with debugfs_create_dir() + - net: arcnet: Do not call kfree_skb() under local_irq_disable() + - mlxsw: i2c: Fix chunk size setting in output mailbox buffer + - mlxsw: i2c: Limit single transaction buffer size + - netrom: Deny concurrent connect(). + - drm/bridge: tc358764: Fix debug print parameter order + - quota: avoid increasing DQST_LOOKUPS when iterating over dirty/inuse list + - quota: factor out dquot_write_dquot() + - quota: rename dquot_active() to inode_quota_active() + - quota: add new helper dquot_active() + - quota: fix dqput() to follow the guarantees dquot_srcu should provide + - drm/amdgpu: avoid integer overflow warning in amdgpu_device_resize_fb_bar() + - ARM: dts: BCM53573: Drop nonexistent "default-off" LED trigger + - ARM: dts: BCM53573: Add cells sizes to PCIe node + - ARM: dts: BCM53573: Use updated "spi-gpio" binding properties + - drm/etnaviv: fix dumping of active MMU context + - ARM: dts: s3c6410: move fixed clocks under root node in Mini6410 + - ARM: dts: s3c6410: align node SROM bus node name with dtschema in Mini6410 + - ARM: dts: s3c64xx: align pinctrl with dtschema + - ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses (split) + - ARM: dts: s5pv210: add RTC 32 KHz clock in SMDKV210 + - ARM: dts: s5pv210: use defines for IRQ flags in SMDKV210 + - ARM: dts: s5pv210: correct ethernet unit address in SMDKV210 + - ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210 + - ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split) + - drm: adv7511: Fix low refresh rate register for ADV7533/5 + - ARM: dts: BCM53573: Fix Ethernet info for Luxul devices + - arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC + - drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl' + - md/bitmap: don't set max_write_behind if there is no write mostly device + - md/md-bitmap: hold 'reconfig_mutex' in backlog_store() + - drm/tegra: Remove superfluous error messages around platform_get_irq() + - drm/tegra: dpaux: Fix incorrect return value of platform_get_irq + - of: unittest: fix null pointer dereferencing in + of_unittest_find_node_by_name() + - drm/armada: Fix off-by-one error in armada_overlay_get_property() + - drm/panel: simple: Add missing connector type and pixel format for AUO + T215HVN01 + - ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig + - [Config] Update annotations after CONFIG_IMA_TRUSTED_KEYRING removal + - drm/msm/mdp5: Don't leak some plane state + - smackfs: Prevent underflow in smk_set_cipso() + - audit: fix possible soft lockup in __audit_inode_child() + - drm/mediatek: Fix potential memory leak if vmap() fail + - of: unittest: Fix overlay type in apply/revert check + - ALSA: ac97: Fix possible error value of *rac97 + - ipmi:ssif: Add check for kstrdup + - ipmi:ssif: Fix a memory leak when scanning for an adapter + - drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init() + - clk: sunxi-ng: Modify mismatched function name + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - PCI: pciehp: Use RMW accessors for changing LNKCTL + - PCI/ASPM: Use RMW accessors for changing LNKCTL + - clk: imx: composite-8m: fix clock pauses when set_rate would be a no-op + - powerpc/fadump: reset dump area size if fadump memory reserve fails + - PCI: Add #defines for Enter Compliance, Transmit Margin + - drm/amdgpu: Correct Transmit Margin masks + - drm/amdgpu: Replace numbers with PCI_EXP_LNKCTL2 definitions + - drm/amdgpu: Prefer pcie_capability_read_word() + - drm/amdgpu: Use RMW accessors for changing LNKCTL + - drm/radeon: Correct Transmit Margin masks + - drm/radeon: Replace numbers with PCI_EXP_LNKCTL2 definitions + - drm/radeon: Prefer pcie_capability_read_word() + - drm/radeon: Use RMW accessors for changing LNKCTL + - wifi: ath10k: Use RMW accessors for changing LNKCTL + - nfs/blocklayout: Use the passed in gfp flags + - powerpc/iommu: Fix notifiers being shared by PCI and VIO buses + - jfs: validate max amount of blocks before allocation. + - fs: lockd: avoid possible wrong NULL parameter + - NFSD: da_addr_body field missing in some GETDEVICEINFO replies + - NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN + - media: v4l2-fwnode: fix v4l2_fwnode_parse_link handling + - media: v4l2-fwnode: simplify v4l2_fwnode_parse_link + - media: v4l2-core: Fix a potential resource leak in v4l2_fwnode_parse_link() + - drivers: usb: smsusb: fix error handling code in smsusb_init_device + - media: dib7000p: Fix potential division by zero + - media: dvb-usb: m920x: Fix a potential memory leak in m920x_i2c_xfer() + - media: cx24120: Add retval check for cx24120_message_send() + - media: mediatek: vcodec: Return NULL if no vdec_fb is found + - usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host() + - scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param() + - scsi: be2iscsi: Add length check when parsing nlattrs + - scsi: qla4xxx: Add length check when parsing nlattrs + - serial: sprd: getting port index via serial aliases only + - serial: sprd: remove redundant sprd_port cleanup + - serial: sprd: Assign sprd_port after initialized to avoid wrong access + - serial: sprd: Fix DMA buffer leak issue + - x86/APM: drop the duplicate APM_MINOR_DEV macro + - scsi: qedf: Do not touch __user pointer in + qedf_dbg_stop_io_on_error_cmd_read() directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read() + directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read() + directly + - coresight: tmc: Explicit type conversions to prevent integer overflow + - dma-buf/sync_file: Fix docs syntax + - driver core: test_async: fix an error code + - IB/uverbs: Fix an potential error pointer dereference + - iommu/vt-d: Fix to flush cache of PASID directory table + - media: go7007: Remove redundant if statement + - USB: gadget: f_mass_storage: Fix unused variable warning + - media: i2c: ov5640: Configure HVP lines in s_power callback + - media: ov5640: Enable MIPI interface in ov5640_set_power_mipi() + - media: i2c: ov2680: Set V4L2_CTRL_FLAG_MODIFY_LAYOUT on flips + - media: ov2680: Remove auto-gain and auto-exposure controls + - media: ov2680: Fix ov2680_bayer_order() + - media: ov2680: Fix vflip / hflip set functions + - media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors + - scsi: core: Use 32-bit hostnum in scsi_host_lookup() + - scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock + - serial: tegra: handle clk prepare error in tegra_uart_hw_init() + - amba: bus: fix refcount leak + - Revert "IB/isert: Fix incorrect release of isert connection" + - RDMA/siw: Balance the reference of cep->kref in the error path + - RDMA/siw: Correct wrong debug message + - HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode() + - HID: multitouch: Correct devm device reference for hidinput input_dev name + - x86/speculation: Mark all Skylake CPUs as vulnerable to GDS + - tracing: Fix race issue between cpu buffer write and swap + - phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 + - phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate + - phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write + - rpmsg: glink: Add check for kstrdup + - mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume() + - um: Fix hostaudio build errors + - dmaengine: ste_dma40: Add missing IRQ check in d40_probe + - cpufreq: Fix the race condition while updating the transition_task of policy + - virtio_ring: fix avail_wrap_counter in virtqueue_add_packed + - skbuff: skb_segment, Call zero copy functions before using skbuff frags + - PM / devfreq: Fix leak in devfreq_dev_release() + - ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl + - ipmi_si: fix a memleak in try_smi_init() + - ARM: OMAP2+: Fix -Warray-bounds warning in _pwrdm_state_switch() + - backlight/gpio_backlight: Compare against struct fb_info.device + - backlight/bd6107: Compare against struct fb_info.device + - backlight/lv5207lp: Compare against struct fb_info.device + - xtensa: PMU: fix base address for the newer hardware + - media: dvb: symbol fixup for dvb_attach() + - ntb: Drop packets when qp link is down + - ntb: Clean up tx tail index on link down + - ntb: Fix calculation ntb_transport_tx_free_entry() + - Revert "PCI: Mark NVIDIA T4 GPUs to avoid bus reset" + - procfs: block chmod on /proc/thread-self/comm + - parisc: Fix /proc/cpuinfo output for lscpu + - dlm: fix plock lookup when using multiple lockspaces + - dccp: Fix out of bounds access in DCCP error handler + - X.509: if signature is unsupported skip validation + - net: handle ARPHRD_PPP in dev_is_mac_header_xmit() + - fsverity: skip PKCS#7 parser when keyring is empty + - pstore/ram: Check start of empty przs during init + - s390/ipl: add missing secure/has_secure file to ipl type 'unknown' + - crypto: stm32 - fix loop iterating through scatterlist for DMA + - cpufreq: brcmstb-avs-cpufreq: Fix -Warray-bounds bug + - sc16is7xx: Set iobase to device index + - serial: sc16is7xx: fix broken port 0 uart init + - usb: typec: tcpci: clear the fault status bit + - udf: initialize newblock to 0 + - drm: fix double free for gbo in drm_gem_vram_init and drm_gem_vram_create + - net/ipv6: SKB symmetric hash should incorporate transport ports + - scsi: qla2xxx: fix inconsistent TMF timeout + - scsi: qla2xxx: Fix erroneous link up failure + - scsi: qla2xxx: Turn off noisy message log + - scsi: qla2xxx: Remove unsupported ql2xenabledif option + - fbdev/ep93xx-fb: Do not assign to struct fb_info.dev + - drm/ast: Fix DRAM init on AST2200 + - lib/test_meminit: allocate pages up to order MAX_ORDER + - parisc: led: Fix LAN receive and transmit LEDs + - parisc: led: Reduce CPU overhead for disk & lan LED computation + - clk: qcom: gcc-mdm9615: use proper parent for pll0_vote clock + - soc: qcom: qmi_encdec: Restrict string length in decode + - NFSv4/pnfs: minor fix for cleanup path in nfs4_get_device_info + - kconfig: fix possible buffer overflow + - perf annotate bpf: Don't enclose non-debug code with an assert() + - x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() + - perf top: Don't pass an ERR_PTR() directly to perf_session__delete() + - watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load + - pwm: lpc32xx: Remove handling of PWM channels + - sctp: annotate data-races around sk->sk_wmem_queued + - ipv4: annotate data-races around fi->fib_dead + - net: read sk->sk_family once in sk_mc_loop() + - igb: disable virtualization features on 82580 + - veth: Fixing transmit return status for dropped packets + - net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr + - af_unix: Fix data-races around user->unix_inflight. + - af_unix: Fix data-race around unix_tot_inflight. + - af_unix: Fix data-races around sk->sk_shutdown. + - af_unix: Fix data race around sk->sk_err. + - kcm: Destroy mutex in kcm_exit_net() + - igc: Change IGC_MIN to allow set rx/tx value between 64 and 80 + - igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80 + - igb: Change IGB_MIN to allow set rx/tx value between 64 and 80 + - s390/zcrypt: don't leak memory if dev_set_name() fails + - idr: fix param name in idr_alloc_cyclic() doc + - ip_tunnels: use DEV_STATS_INC() + - net: hns3: fix the port information display when sfp is absent + - sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory() + - ata: sata_gemini: Add missing MODULE_DESCRIPTION + - ata: pata_ftide010: Add missing MODULE_DESCRIPTION + - fuse: nlookup missing decrement in fuse_direntplus_link + - btrfs: don't start transaction when joining with TRANS_JOIN_NOSTART + - btrfs: use the correct superblock to compare fsid in btrfs_validate_super + - mtd: rawnand: brcmnand: Fix crash during the panic_write + - mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write + - mtd: rawnand: brcmnand: Fix potential false time out warning + - perf hists browser: Fix hierarchy mode header + - perf tools: Handle old data in PERF_RECORD_ATTR + - usb: typec: tcpm: Refactor tcpm_handle_vdm_request payload handling + - usb: typec: tcpm: Refactor tcpm_handle_vdm_request + - usb: typec: bus: verify partner exists in typec_altmode_attention + - ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2 + - clk: imx8mm: Move 1443X/1416X PLL clock structure to common place + - net: ipv4: fix one memleak in __inet_del_ifa() + - net: ethernet: mvpp2_main: fix possible OOB write in + mvpp2_ethtool_get_rxnfc() + - net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in + mtk_hwlro_get_fdir_all() + - r8152: check budget for r8152_poll() + - kcm: Fix memory leak in error path of kcm_sendmsg() + - platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors + - mlxbf-tmfifo: sparse tags for config access + - platform/mellanox: mlxbf-tmfifo: Drop jumbo frames + - net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() + - ixgbe: fix timestamp configuration code + - kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). + - drm/amd/display: Fix a bug when searching for insert_above_mpcc + - parisc: Drop loops_per_jiffy from per_cpu struct + - autofs: fix memory leak of waitqueues in autofs_catatonic_mode + - btrfs: output extra debug info if we failed to find an inline backref + - locks: fix KASAN: use-after-free in trace_event_raw_event_filelock_lock + - ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer + - kernel/fork: beware of __put_task_struct() calling context + - ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470 + - perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09 + - hw_breakpoint: fix single-stepping when using bpf_overflow_handler + - devlink: remove reload failed checks in params get/set callbacks + - wifi: ath9k: fix printk specifier + - wifi: mwifiex: fix fortify warning + - crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui() + - tpm_tis: Resend command to recover from data transfer errors + - mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450 + - alx: fix OOB-read compiler warning + - wifi: mac80211_hwsim: drop short frames + - drm/exynos: fix a possible null-pointer dereference due to data race in + exynos_drm_crtc_atomic_disable() + - bus: ti-sysc: Configure uart quirks for k3 SoC + - md: raid1: fix potential OOB in raid1_remove_disk() + - ext2: fix datatype of block number in ext2_xattr_set2() + - fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount() + - jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount + - powerpc/pseries: fix possible memory leak in ibmebus_bus_init() + - media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer + - media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer() + - media: af9005: Fix null-ptr-deref in af9005_i2c_xfer + - media: anysee: fix null-ptr-deref in anysee_master_xfer + - media: az6007: Fix null-ptr-deref in az6007_i2c_xfer() + - media: tuners: qt1010: replace BUG_ON with a regular error + - media: pci: cx23885: replace BUG with error return + - usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc + - scsi: target: iscsi: Fix buffer overflow in lio_target_nacl_info_show() + - serial: cpm_uart: Avoid suspicious locking + - media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler warning + - kobject: Add sanity check for kset->kobj.ktype in kset_register() + - tools features: Add feature test to check if libbfd has buildid support + - perf jevents: Make build dependency on test JSONs + - perf tools: Add an option to build without libbfd + - btrfs: move btrfs_pinned_by_swapfile prototype into volumes.h + - btrfs: add a helper to read the superblock metadata_uuid + - btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super + - selftests: tracing: Fix to unmount tracefs for recovering environment + - md/raid1: fix error: ISO C90 forbids mixed declarations + - attr: block mode changes of symlinks + - btrfs: fix lockdep splat and potential deadlock after failure running + delayed items + - tracing: Have current_trace inc the trace array ref count + - tracing: Have option files inc the trace array ref count + - nfsd: fix change_info in NFSv4 RENAME replies + - tracefs: Add missing lockdown check to tracefs_create_dir() + - i2c: aspeed: Reset the i2c controller when timeout occurs + - scsi: megaraid_sas: Fix deadlock on firmware crashdump + - ext4: fix rec_len verify error + - mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller + - drm/amdgpu: fix amdgpu_cs_p1_user_fence + - Linux 5.4.257 + * Focal update: v5.4.257 upstream stable release (LP: #2040284) // + CVE-2023-39189 + - netfilter: nfnetlink_osf: avoid OOB read + * CVE-2023-45871 + - igb: set max size RX buffer when store bad packet is enabled + * CVE-2023-39193 + - netfilter: xt_sctp: validate the flag_info count + * CVE-2023-39192 + - netfilter: xt_u32: validate user space input + * CVE-2023-31085 + - ubi: Refuse attaching if mtd's erasesize is 0 + * CVE-2023-5717 + - perf: Disallow mis-matched inherited group reads + * CVE-2023-5178 + - nvmet-tcp: move send/recv error handling in the send/recv methods instead of + call-sites + - nvmet-tcp: Fix a possible UAF in queue intialization setup + * CVE-2023-42754 + - ipv4: fix null-deref in ipv4_link_failure + * Focal update: v5.4.256 upstream stable release (LP: #2039446) + - powerpc/pmac/smp: Avoid unused-variable warnings + - powerpc/pmac/smp: Drop unnecessary volatile qualifier + - Revert "MIPS: Alchemy: fix dbdma2" + - Linux 5.4.256 + * Focal update: v5.4.255 upstream stable release (LP: #2039440) + - mmc: sdhci_f_sdh30: convert to devm_platform_ioremap_resource + - mmc: sdhci-f-sdh30: Replace with sdhci_pltfm + - selftests: forwarding: tc_flower: Relax success criterion + - macsec: Fix traffic counters/statistics + - macsec: use DEV_STATS_INC() + - drm/radeon: Fix integer overflow in radeon_cs_parser_init + - ALSA: emu10k1: roll up loops in DSP setup code for Audigy + - quota: Properly disable quotas when add_dquot_ref() fails + - quota: fix warning in dqgrab() + - HID: add quirk for 03f0:464a HP Elite Presenter Mouse + - ovl: check type and offset of struct vfsmount in ovl_entry + - udf: Fix uninitialized array access for some pathnames + - fs: jfs: Fix UBSAN: array-index-out-of-bounds in dbAllocDmapLev + - MIPS: dec: prom: Address -Warray-bounds warning + - FS: JFS: Fix null-ptr-deref Read in txBegin + - FS: JFS: Check for read-only mounted filesystem in txBegin + - media: v4l2-mem2mem: add lock to protect parameter num_rdy + - media: platform: mediatek: vpu: fix NULL ptr dereference + - usb: chipidea: imx: don't request QoS for imx8ulp + - gfs2: Fix possible data races in gfs2_show_options() + - pcmcia: rsrc_nonstatic: Fix memory leak in nonstatic_release_resource_db() + - Bluetooth: L2CAP: Fix use-after-free + - drm/amdgpu: Fix potential fence use-after-free v2 + - ALSA: hda/realtek: Add quirks for Unis H3C Desktop B760 & Q760 + - ALSA: hda: fix a possible null-pointer dereference due to data race in + snd_hdac_regmap_sync() + - powerpc/kasan: Disable KCOV in KASAN code + - IMA: allow/fix UML builds + - iio: add addac subdirectory + - iio: adc: stx104: Utilize iomap interface + - iio: adc: stx104: Implement and utilize register structures + - iio: stx104: Move to addac subdirectory + - iio: addac: stx104: Fix race condition for stx104_write_raw() + - iio: addac: stx104: Fix race condition when converting analog-to-digital + - iommu/amd: Fix "Guest Virtual APIC Table Root Pointer" configuration in IRTE + - PM-runtime: add tracepoints for usage_count changes + - PM: runtime: Add pm_runtime_get_if_active() + - ALSA: hda: Fix unhandled register update during auto-suspend period + - irqchip/mips-gic: Get rid of the reliance on irq_cpu_online() + - irqchip/mips-gic: Use raw spinlock for gic_lock + - interconnect: Move internal structs into a separate file + - interconnect: Add helpers for enabling/disabling a path + - usb: dwc3: qcom: Add helper functions to enable,disable wake irqs + - USB: dwc3: qcom: fix NULL-deref on suspend + - mmc: bcm2835: fix deferred probing + - mmc: sunxi: fix deferred probing + - leds: trigger: netdev: Recheck NETDEV_LED_MODE_LINKUP on dev rename + - tracing/probes: Have process_fetch_insn() take a void * instead of pt_regs + - tracing/probes: Fix to update dynamic data counter if fetcharg uses it + - net/ncsi: Fix gma flag setting after response + - nfsd4: kill warnings on testing stateids with mismatched clientids + - nfsd: Remove incorrect check in nfsd4_validate_stateid + - virtio-mmio: convert to devm_platform_ioremap_resource + - virtio-mmio: Use to_virtio_mmio_device() to simply code + - virtio-mmio: don't break lifecycle of vm_dev + - i2c: bcm-iproc: Fix bcm_iproc_i2c_isr deadlock issue + - fbdev: mmp: fix value check in mmphw_probe() + - powerpc/rtas_flash: allow user copy to flash block cache objects + - tty: serial: fsl_lpuart: Clear the error flags by writing 1 for lpuart32 + platforms + - btrfs: fix BUG_ON condition in btrfs_cancel_balance + - net: xfrm: Fix xfrm_address_filter OOB read + - net: af_key: fix sadb_x_filter validation + - xfrm: interface: rename xfrm_interface.c to xfrm_interface_core.c + - xfrm: fix slab-use-after-free in decode_session6 + - ip6_vti: fix slab-use-after-free in decode_session6 + - ip_vti: fix potential slab-use-after-free in decode_session6 + - selftests: mirror_gre_changes: Tighten up the TTL test match + - ipvs: fix racy memcpy in proc_do_sync_threshold + - netfilter: nft_dynset: disallow object maps + - team: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves + - i40e: fix misleading debug logs + - net: dsa: mv88e6xxx: Wait for EEPROM done before HW reset + - sock: Fix misuse of sk_under_memory_pressure() + - net: do not allow gso_size to be set to GSO_BY_FRAGS + - bus: ti-sysc: Improve reset to work with modules with no sysconfig + - bus: ti-sysc: Flush posted write on enable before reset + - ARM: dts: imx7s: Drop dma-apb interrupt-names + - ARM: dts: imx: Adjust dma-apbh node name + - ARM: dts: imx: Set default tuning step for imx7d usdhc + - ARM: dts: imx: Set default tuning step for imx6sx usdhc + - ASoC: rt5665: add missed regulator_bulk_disable + - ASoC: meson: axg-tdm-formatter: fix channel slot allocation + - serial: 8250: Fix oops for port->pm on uart_change_pm() + - ALSA: usb-audio: Add support for Mythware XA001AU capture and playback + interfaces. + - cifs: Release folio lock on fscache read hit. + - mmc: wbsd: fix double mmc_free_host() in wbsd_init() + - mmc: block: Fix in_flight[issue_type] value error + - netfilter: set default timeout to 3 secs for sctp shutdown send and recv + state + - virtio-net: set queues after driver_ok + - net: fix the RTO timer retransmitting skb every 1ms if linear option is + enabled + - net: xfrm: Amend XFRMA_SEC_CTX nla_policy structure + - mmc: f-sdh30: fix order of function calls in sdhci_f_sdh30_remove + - net: phy: broadcom: stub c45 read/write for 54810 + - PCI: acpiphp: Reassign resources on bridge if necessary + - dlm: improve plock logging if interrupted + - dlm: replace usage of found with dedicated list iterator variable + - fs: dlm: add pid to debug log + - fs: dlm: change plock interrupted message to debug again + - fs: dlm: use dlm_plock_info for do_unlock_close + - fs: dlm: fix mismatch of plock results from userspace + - MIPS: cpu-features: Enable octeon_cache by cpu_type + - MIPS: cpu-features: Use boot_cpu_type for CPU type based features + - fbdev: Improve performance of sys_imageblit() + - fbdev: Fix sys_imageblit() for arbitrary image widths + - fbdev: fix potential OOB read in fast_imageblit() + - dm integrity: increase RECALC_SECTORS to improve recalculate speed + - dm integrity: reduce vmalloc space footprint on 32-bit architectures + - ALSA: pcm: Set per-card upper limit of PCM buffer allocations + - ALSA: pcm: Use SG-buffer only when direct DMA is available + - ALSA: pcm: Fix potential data race at PCM memory allocation helpers + - regmap: Account for register length in SMBus I/O limits + - ASoC: fsl_sai: Refine enable/disable TE/RE sequence in trigger() + - ASoC: fsl_sai: Add new added registers and new bit definition + - ASoC: fsl_sai: Disable bit clock with transmitter + - drm/amd/display: do not wait for mpc idle if tg is disabled + - drm/amd/display: check TG is non-null before checking if enabled + - tracing: Fix memleak due to race between current_tracer and trace + - octeontx2-af: SDP: fix receive link config + - sock: annotate data-races around prot->memory_pressure + - dccp: annotate data-races in dccp_poll() + - ipvlan: Fix a reference count leak warning in ipvlan_ns_exit() + - net: bgmac: Fix return value check for fixed_phy_register() + - net: bcmgenet: Fix return value check for fixed_phy_register() + - net: validate veth and vxcan peer ifindexes + - igb: Avoid starting unnecessary workqueues + - net/sched: fix a qdisc modification with ambiguous command request + - net: remove bond_slave_has_mac_rcu() + - bonding: fix macvlan over alb bond support + - ibmveth: Use dcbf rather than dcbfl + - NFSv4: Fix dropped lock for racing OPEN and delegation return + - clk: Fix slab-out-of-bounds error in devm_clk_release() + - nfsd: Fix race to FREE_STATEID and cl_revoked + - batman-adv: Trigger events for auto adjusted MTU + - batman-adv: Don't increase MTU when set by user + - batman-adv: Do not get eth header before batadv_check_management_packet + - batman-adv: Fix TT global entry leak when client roamed back + - batman-adv: Fix batadv_v_ogm_aggr_send memory leak + - batman-adv: Hold rtnl lock during MTU update via netlink + - lib/clz_ctz.c: Fix __clzdi2() and __ctzdi2() for 32-bit kernels + - radix tree: remove unused variable + - media: vcodec: Fix potential array out-of-bounds in encoder queue_setup + - PCI: acpiphp: Use pci_assign_unassigned_bridge_resources() only for non-root + bus + - drm/display/dp: Fix the DP DSC Receiver cap size + - mm: allow a controlled amount of unfairness in the page lock + - rtnetlink: Reject negative ifindexes in RTM_NEWLINK + - ALSA: pcm: Fix build error on m68k and others + - Revert "ALSA: pcm: Use SG-buffer only when direct DMA is available" + - interconnect: Do not skip aggregation for disabled paths + - ALSA: pcm: Check for null pointer of pointer substream before dereferencing + it + - Documentation/sysctl: document page_lock_unfairness + - irqchip/mips-gic: Don't touch vl_map if a local interrupt is not routable + - scsi: snic: Fix double free in snic_tgt_create() + - scsi: core: raid_class: Remove raid_component_add() + - clk: Fix undefined reference to `clk_rate_exclusive_{get,put}' + - pinctrl: renesas: rza2: Add lock around + pinctrl_generic{{add,remove}_group,{add,remove}_function} + - dma-buf/sw_sync: Avoid recursive lock during fence signal + - Linux 5.4.255 + * Focal update: v5.4.254 upstream stable release (LP: #2039291) + - mmc: moxart: read scr register without changing byte order + - ipv6: adjust ndisc_is_useropt() to also return true for PIO + - dmaengine: pl330: Return DMA_PAUSED when transaction is paused + - drm/nouveau/gr: enable memory loads on helper invocation on all channels + - radix tree test suite: fix incorrect allocation size for pthreads + - nilfs2: fix use-after-free of nilfs_root in dirtying inodes via iput + - iio: cros_ec: Fix the allocation size for cros_ec_command + - binder: fix memory leak in binder_init() + - usb-storage: alauda: Fix uninit-value in alauda_check_media() + - usb: dwc3: Properly handle processing of pending events + - usb: common: usb-conn-gpio: Prevent bailing out if initial role is none + - x86/cpu/amd: Enable Zenbleed fix for AMD Custom APU 0405 + - x86/mm: Fix VDSO and VVAR placement on 5-level paging machines + - x86: Move gds_ucode_mitigated() declaration to header + - drm/nouveau/disp: Revert a NULL check inside nouveau_connector_get_modes + - selftests/rseq: Fix build with undefined __weak + - mISDN: Update parameter type of dsp_cmx_send() + - net/packet: annotate data-races around tp->status + - bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves + - dccp: fix data-race around dp->dccps_mss_cache + - drivers: net: prevent tun_build_skb() to exceed the packet size limit + - IB/hfi1: Fix possible panic during hotplug remove + - wifi: cfg80211: fix sband iftype data lookup for AP_VLAN + - dmaengine: mcf-edma: Fix a potential un-allocated memory access + - net/mlx5: Allow 0 for total host VFs + - ibmvnic: Handle DMA unmapping of login buffs in release functions + - btrfs: don't stop integrity writeback too early + - btrfs: set cache_block_group_error if we find an error + - nvme-tcp: fix potential unbalanced freeze & unfreeze + - nvme-rdma: fix potential unbalanced freeze & unfreeze + - netfilter: nf_tables: report use refcount overflow + - scsi: core: Fix legacy /proc parsing buffer overflow + - scsi: storvsc: Fix handling of virtual Fibre Channel timeouts + - scsi: 53c700: Check that command slot is not NULL + - scsi: snic: Fix possible memory leak if device_add() fails + - scsi: core: Fix possible memory leak if device_add() fails + - alpha: remove __init annotation from exported page_is_ram() + - sch_netem: fix issues in netem_change() vs get_dist_table() + - Linux 5.4.254 + * Focal update: v5.4.253 upstream stable release (LP: #2038652) + - jbd2: fix incorrect code style + - jbd2: fix kernel-doc markups + - jbd2: remove redundant buffer io error checks + - jbd2: recheck chechpointing non-dirty buffer + - jbd2: Fix wrongly judgement for buffer head removing while doing checkpoint + - gpio: tps68470: Make tps68470_gpio_output() always set the initial value + - bcache: remove 'int n' from parameter list of bch_bucket_alloc_set() + - bcache: Fix __bch_btree_node_alloc to make the failure behavior consistent + - btrfs: qgroup: catch reserved space leaks at unmount time + - btrfs: fix race between quota disable and relocation + - btrfs: fix extent buffer leak after tree mod log failure at split_node() + - ext4: rename journal_dev to s_journal_dev inside ext4_sb_info + - ext4: Fix reusing stale buffer heads from last failed mounting + - PCI/ASPM: Return 0 or -ETIMEDOUT from pcie_retrain_link() + - PCI/ASPM: Factor out pcie_wait_for_retrain() + - PCI/ASPM: Avoid link retraining race + - dlm: cleanup plock_op vs plock_xop + - dlm: rearrange async condition return + - fs: dlm: interrupt posix locks only when process is killed + - ftrace: Add information on number of page groups allocated + - ftrace: Check if pages were allocated before calling free_pages() + - ftrace: Store the order of pages allocated in ftrace_page + - ftrace: Fix possible warning on checking all pages used in + ftrace_process_locs() + - pwm: meson: Remove redundant assignment to variable fin_freq + - pwm: meson: Simplify duplicated per-channel tracking + - pwm: meson: fix handling of period/duty if greater than UINT_MAX + - scsi: qla2xxx: Fix inconsistent format argument type in qla_os.c + - scsi: qla2xxx: Array index may go out of bound + - uapi: General notification queue definitions + - keys: Fix linking a duplicate key to a keyring's assoc_array + - ext4: fix to check return value of freeze_bdev() in ext4_shutdown() + - i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir() + - vxlan: calculate correct header length for GPE + - phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe() + - ethernet: atheros: fix return value check in atl1e_tso_csum() + - ipv6 addrconf: fix bug where deleting a mngtmpaddr can create a new + temporary address + - bonding: reset bond's flags when down link is P2P device + - team: reset team's flags when down link is P2P device + - platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100 + - net/sched: mqprio: refactor nlattr parsing to a separate function + - net/sched: mqprio: add extack to mqprio_parse_nlattr() + - net/sched: mqprio: Add length check for TCA_MQPRIO_{MAX/MIN}_RATE64 + - benet: fix return value check in be_lancer_xmit_workarounds() + - RDMA/mlx4: Make check for invalid flags stricter + - drm/msm/dpu: drop enum dpu_core_perf_data_bus_id + - drm/msm/adreno: Fix snapshot BINDLESS_DATA size + - drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb() + - ASoC: fsl_spdif: Silence output on stop + - block: Fix a source code comment in include/uapi/linux/blkzoned.h + - dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths + - ata: pata_ns87415: mark ns87560_tf_read static + - ring-buffer: Fix wrong stat of cpu_buffer->read + - tracing: Fix warning in trace_buffered_event_disable() + - serial: 8250_dw: Preserve original value of DLF register + - serial: sifive: Fix sifive_serial_console_setup() section + - USB: serial: option: support Quectel EM060K_128 + - USB: serial: option: add Quectel EC200A module support + - USB: serial: simple: add Kaufmann RKS+CAN VCP + - USB: serial: simple: sort driver entries + - can: gs_usb: gs_can_close(): add missing set of CAN state to + CAN_STATE_STOPPED + - Revert "usb: dwc3: core: Enable AutoRetry feature in the controller" + - usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy + - usb: dwc3: don't reset device side if dwc3 was configured as host-only + - usb: ohci-at91: Fix the unhandle interrupt when resume + - USB: quirks: add quirk for Focusrite Scarlett + - usb: xhci-mtk: set the dma max_seg_size + - Revert "usb: xhci: tegra: Fix error check" + - Documentation: security-bugs.rst: update preferences when dealing with the + linux-distros group + - Documentation: security-bugs.rst: clarify CVE handling + - staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext() + - hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled + - btrfs: check for commit error at btrfs_attach_transaction_barrier() + - tpm_tis: Explicitly check for error code + - irq-bcm6345-l1: Do not assume a fixed block to cpu mapping + - btrfs: check if the transaction was aborted at btrfs_wait_for_commit() + - virtio-net: fix race between set queues and probe + - s390/dasd: fix hanging device after quiesce/resume + - ASoC: wm8904: Fill the cache for WM8904_ADC_TEST_0 register + - dm cache policy smq: ensure IO doesn't prevent cleaner policy progress + - ACPI: processor: perflib: Use the "no limit" frequency QoS + - ACPI: processor: perflib: Avoid updating frequency QoS unnecessarily + - cpufreq: intel_pstate: Drop ACPI _PSS states table patching + - btrfs: qgroup: remove one-time use variables for quota_root checks + - btrfs: qgroup: return ENOTCONN instead of EINVAL when quotas are not enabled + - ASoC: cs42l51: fix driver to properly autoload with automatic module loading + - arm64: Add AMPERE1 to the Spectre-BHB affected list + - arm64: Fix bit-shifting UB in the MIDR_CPU_MODEL() macro + - perf: Fix function pointer case + - loop: Select I/O scheduler 'none' from inside add_disk() + - word-at-a-time: use the same return type for has_zero regardless of + endianness + - KVM: s390: fix sthyi error handling + - net/mlx5: DR, fix memory leak in mlx5dr_cmd_create_reformat_ctx + - net/mlx5e: fix return value check in mlx5e_ipsec_remove_trailer() + - rtnetlink: let rtnl_bridge_setlink checks IFLA_BRIDGE_MODE length + - perf test uprobe_from_different_cu: Skip if there is no gcc + - net: sched: cls_u32: Fix match key mis-addressing + - mISDN: hfcpci: Fix potential deadlock on &hc->lock + - net: annotate data-races around sk->sk_max_pacing_rate + - net: add missing READ_ONCE(sk->sk_rcvlowat) annotation + - net: add missing READ_ONCE(sk->sk_sndbuf) annotation + - net: add missing READ_ONCE(sk->sk_rcvbuf) annotation + - net: add missing data-race annotations around sk->sk_peek_off + - net: add missing data-race annotation for sk_ll_usec + - bpf: sockmap: Remove preempt_disable in sock_map_sk_acquire + - driver core: add device probe log helper + - net: ll_temac: Switch to use dev_err_probe() helper + - net: ll_temac: fix error checking of irq_of_parse_and_map() + - net: dcb: choose correct policy to parse DCB_ATTR_BCN + - ip6mr: Fix skb_under_panic in ip6mr_cache_report() + - tcp_metrics: fix addr_same() helper + - tcp_metrics: annotate data-races around tm->tcpm_stamp + - tcp_metrics: annotate data-races around tm->tcpm_lock + - tcp_metrics: annotate data-races around tm->tcpm_vals[] + - tcp_metrics: annotate data-races around tm->tcpm_net + - tcp_metrics: fix data-race in tcpm_suck_dst() vs fastopen + - scsi: zfcp: Defer fc_rport blocking until after ADISC response + - libceph: fix potential hang in ceph_osdc_notify() + - USB: zaurus: Add ID for A-300/B-500/C-700 + - mtd: spinand: toshiba: Fix ecc_get_status + - mtd: rawnand: meson: fix OOB available bytes for ECC + - fs/sysv: Null check to prevent null-ptr-deref bug + - net: usbnet: Fix WARNING in usbnet_start_xmit/usb_submit_urb + - fs: Protect reconfiguration of sb read-write from racing writes + - ext2: Drop fragment support + - test_firmware: prevent race conditions by a correct implementation of + locking + - test_firmware: return ENOMEM instead of ENOSPC on failed memory allocation + - mtd: rawnand: omap_elm: Fix incorrect type in assignment + - powerpc/mm/altmap: Fix altmap boundary check + - selftests/rseq: check if libc rseq support is registered + - selftests/rseq: Play nice with binaries statically linked against glibc + 2.35+ + - PM / wakeirq: support enabling wake-up irq after runtime_suspend called + - PM: sleep: wakeirq: fix wake irq arming + - ceph: show tasks waiting on caps in debugfs caps file + - ceph: use kill_anon_super helper + - ceph: defer stopping mdsc delayed_work + - arm64: dts: stratix10: fix incorrect I2C property for SCL signal + - ARM: dts: imx6sll: Make ssi node name same as other platforms + - ARM: dts: imx: Align L2 cache-controller nodename with dtschema + - ARM: dts: imx: add usb alias + - ARM: dts: imx6sll: fixup of operating points + - ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node + - driver core: Annotate dev_err_probe() with __must_check + - driver code: print symbolic error code + - drivers: core: fix kernel-doc markup for dev_err_probe() + - Revert "driver core: Annotate dev_err_probe() with __must_check" + - Linux 5.4.253 + - Upstream stable to v5.4.253 + * CVE-2023-37453 + - USB: hub: Clean up use of port initialization schemes and retries + - USB: hub: Add Kconfig option to reduce number of port initialization retries + - USB: core: Unite old scheme and new scheme descriptor reads + - usb: hub: Check device descriptor before resusciation + - USB: core: Change usb_get_device_descriptor() API + - USB: core: Fix race by not overwriting udev->descriptor in hub_port_init() + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 16 Nov 2023 14:15:35 -0500 + +linux-oracle (5.4.0-1113.122) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1113.122 -proposed tracker (LP: #2041983) + + [ Ubuntu: 5.4.0-167.184 ] + + * focal/linux: 5.4.0-167.184 -proposed tracker (LP: #2041988) + * CVE-2023-45871 + - igb: set max size RX buffer when store bad packet is enabled + * CVE-2023-31085 + - ubi: Refuse attaching if mtd's erasesize is 0 + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 02 Nov 2023 12:01:25 -0400 + +linux-oracle (5.4.0-1112.121) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1112.121 -proposed tracker (LP: #2038002) + + * Use new annotations model (LP: #2019000) + - [Config] sanitize annotations + - [Config] migrate to the new annotations format + + [ Ubuntu: 5.4.0-166.183 ] + + * focal/linux: 5.4.0-166.183 -proposed tracker (LP: #2038010) + * Use new annotations model (LP: #2019000) + - [Packaging] new annotations model infrastructure + - [Packaging] config-check: Handle new annotations format 4 + - [Packaging] rules: Use old-kernelconfig for old configs + - [Config] sanitize annotations + - [Config] import generated configs into annotation file + - [Packaging] kernelconfig: add i386 as supported arch + - [Config] Remove all old configs files + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] update annotations scripts + * fix typo in config-checks invocation (LP: #2020413) + - [Packaging] fix typo when calling the old config-check + - [Packaging] fix typo in 4-checks.mk + * support python < 3.9 with annotations (LP: #2020531) + - [Packaging] kconfig/annotations.py: support older way of merging dicts + * CVE-2023-42756 + - netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP + * CVE-2023-4623 + - net/sched: sch_hfsc: Ensure inner classes have fsc curve + * Focal update: v5.4.252 upstream stable release (LP: #2036240) + - ia64/cpu: Switch to arch_cpu_finalize_init() + - m68k/cpu: Switch to arch_cpu_finalize_init() + - mips/cpu: Switch to arch_cpu_finalize_init() + - sh/cpu: Switch to arch_cpu_finalize_init() + - x86/cpufeatures: Add SEV-ES CPU feature + - x86/cpu: Add VM page flush MSR availablility as a CPUID feature + - x86/cpufeatures: Assign dedicated feature word for CPUID_0x8000001F[EAX] + - tools headers cpufeatures: Sync with the kernel sources + - x86/cpu, kvm: Add support for CPUID_80000021_EAX + - Linux 5.4.252 + - Upstream stable to v5.4.252 + * CVE-2023-42755 + - net/sched: Retire rsvp classifier + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + * CVE-2023-42753 + - netfilter: ipset: add the missing IP_SET_HASH_WITH_NET0 macro for + ip_set_hash_netportnet.c + * CVE-2023-34319 + - xen/netback: Fix buffer overrun triggered by unusual packet + * CVE-2023-4921 + - net: sched: sch_qfq: Fix UAF in qfq_dequeue() + * CVE-2023-42752 + - igmp: limit igmpv3_newpack() packet size to IP_MAX_MTU + * Avoid address overwrite in kernel_connect (LP: #2035163) + - net: Avoid address overwrite in kernel_connect + * [regression] Unable to initialize SGX enclaves with XFRM other than 3 + (LP: #2034745) + - x86/fpu: Set X86_FEATURE_OSXSAVE feature after enabling OSXSAVE in CR4 + * CVE-2023-4881 + - netfilter: nftables: exthdr: fix 4-byte stack OOB write + * CVE-2023-4622 + - af_unix: Fix null-ptr-deref in unix_stream_sendpage(). + * Focal update: v5.4.251 upstream stable release (LP: #2034918) + - x86/smp: Use dedicated cache-line for mwait_play_dead() + - video: imsttfb: check for ioremap() failures + - fbdev: imsttfb: Fix use after free bug in imsttfb_probe + - HID: wacom: Use ktime_t rather than int when dealing with timestamps + - drm/i915: Initialise outparam for error return from wait_for_register + - scripts/tags.sh: Resolve gtags empty index generation + - drm/amdgpu: Validate VM ioctl flags. + - bgmac: fix *initial* chip reset to support BCM5358 + - x86/resctrl: Use is_closid_match() in more places + - x86/resctrl: Only show tasks' pid in current pid namespace + - md/raid10: check slab-out-of-bounds in md_bitmap_get_counter + - md/raid10: fix overflow of md/safe_mode_delay + - md/raid10: fix wrong setting of max_corr_read_errors + - md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request + - md/raid10: fix io loss while replacement replace rdev + - irqchip/jcore-aic: Kill use of irq_create_strict_mappings() + - irqchip/jcore-aic: Fix missing allocation of IRQ descriptors + - tracing/timer: Add missing hrtimer modes to decode_hrtimer_mode(). + - clocksource/drivers/cadence-ttc: Use ttc driver as platform driver + - clocksource/drivers/cadence-ttc: Fix memory leak in ttc_timer_probe + - PM: domains: fix integer overflow issues in genpd_parse_state() + - powercap: RAPL: Fix CONFIG_IOSF_MBI dependency + - ARM: 9303/1: kprobes: avoid missing-declaration warnings + - evm: Complete description of evm_inode_setattr() + - pstore/ram: Add check for kstrdup + - ima: Fix build warnings + - wifi: ath9k: fix AR9003 mac hardware hang check register offset calculation + - wifi: ath9k: avoid referencing uninit memory in ath9k_wmi_ctrl_rx + - samples/bpf: Fix buffer overflow in tcp_basertt + - spi: spi-geni-qcom: Correct CS_TOGGLE bit in SPI_TRANS_CFG + - wifi: mwifiex: Fix the size of a memory allocation in + mwifiex_ret_802_11_scan() + - nfc: constify several pointers to u8, char and sk_buff + - nfc: llcp: fix possible use of uninitialized variable in + nfc_llcp_send_connect() + - regulator: core: Fix more error checking for debugfs_create_dir() + - regulator: core: Streamline debugfs operations + - wifi: orinoco: Fix an error handling path in spectrum_cs_probe() + - wifi: orinoco: Fix an error handling path in orinoco_cs_probe() + - wifi: atmel: Fix an error handling path in atmel_probe() + - wl3501_cs: Fix a bunch of formatting issues related to function docs + - wl3501_cs: Remove unnecessary NULL check + - wl3501_cs: Fix misspelling and provide missing documentation + - net: create netdev->dev_addr assignment helpers + - wl3501_cs: use eth_hw_addr_set() + - wifi: wl3501_cs: Fix an error handling path in wl3501_probe() + - wifi: ray_cs: Utilize strnlen() in parse_addr() + - wifi: ray_cs: Drop useless status variable in parse_addr() + - wifi: ray_cs: Fix an error handling path in ray_probe() + - wifi: ath9k: don't allow to overwrite ENDPOINT0 attributes + - wifi: rsi: Do not set MMC_PM_KEEP_POWER in shutdown + - watchdog/perf: define dummy watchdog_update_hrtimer_threshold() on correct + config + - watchdog/perf: more properly prevent false positives with turbo modes + - kexec: fix a memory leak in crash_shrink_memory() + - memstick r592: make memstick_debug_get_tpc_name() static + - wifi: ath9k: Fix possible stall on ath9k_txq_list_has_key() + - rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO + - wifi: iwlwifi: pull from TXQs with softirqs disabled + - wifi: cfg80211: rewrite merging of inherited elements + - wifi: ath9k: convert msecs to jiffies where needed + - netlink: fix potential deadlock in netlink_set_err() + - netlink: do not hard code device address lenth in fdb dumps + - selftests: rtnetlink: remove netdevsim device after ipsec offload test + - gtp: Fix use-after-free in __gtp_encap_destroy(). + - lib/ts_bm: reset initial match offset for every block of text + - netfilter: conntrack: dccp: copy entire header to stack buffer, not just + basic one + - netfilter: nf_conntrack_sip: fix the ct_sip_parse_numerical_param() return + value. + - ipvlan: Fix return value of ipvlan_queue_xmit() + - netlink: Add __sock_i_ino() for __netlink_diag_dump(). + - radeon: avoid double free in ci_dpm_init() + - Input: drv260x - sleep between polling GO bit + - ARM: dts: BCM5301X: Drop "clock-names" from the SPI node + - Input: adxl34x - do not hardcode interrupt trigger type + - drm: sun4i_tcon: use devm_clk_get_enabled in `sun4i_tcon_init_clocks` + - RDMA/bnxt_re: Fix to remove an unnecessary log + - ARM: dts: gta04: Move model property out of pinctrl node + - arm64: dts: qcom: msm8916: correct camss unit address + - drm/panel: simple: fix active size for Ampire AM-480272H3TMQW-T01H + - ARM: ep93xx: fix missing-prototype warnings + - memory: brcmstb_dpfe: fix testing array offset after use + - ASoC: es8316: Increment max value for ALC Capture Target Volume control + - ASoC: es8316: Do not set rate constraints for unsupported MCLKs + - soc/fsl/qe: fix usb.c build errors + - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors + - arm64: dts: renesas: ulcb-kf: Remove flow control for SCIF1 + - fbdev: omapfb: lcd_mipid: Fix an error handling path in mipid_spi_probe() + - drm/amdkfd: Fix potential deallocation of previously deallocated memory. + - drm/radeon: fix possible division-by-zero errors + - clk: tegra: tegra124-emc: Fix potential memory leak + - ALSA: ac97: Fix possible NULL dereference in snd_ac97_mixer + - clk: cdce925: check return value of kasprintf() + - clk: keystone: sci-clk: check return value of kasprintf() + - ASoC: imx-audmix: check return value of devm_kasprintf() + - scsi: qedf: Fix NULL dereference in error handling + - PCI/ASPM: Disable ASPM on MFD function removal to avoid use-after-free + - scsi: 3w-xxxx: Add error handling for initialization failure in tw_probe() + - PCI: pciehp: Cancel bringup sequence if card is not present + - PCI: ftpci100: Release the clock resources + - PCI: Add pci_clear_master() stub for non-CONFIG_PCI + - pinctrl: cherryview: Return correct value if pin in push-pull mode + - perf dwarf-aux: Fix off-by-one in die_get_varname() + - pinctrl: at91-pio4: check return value of devm_kasprintf() + - powerpc/mm/dax: Fix the condition when checking if altmap vmemap can cross- + boundary + - hwrng: virtio - add an internal buffer + - hwrng: virtio - don't wait on cleanup + - hwrng: virtio - don't waste entropy + - hwrng: virtio - always add a pending request + - hwrng: virtio - Fix race on data_avail and actual data + - crypto: nx - fix build warnings when DEBUG_FS is not enabled + - modpost: fix section mismatch message for R_ARM_ABS32 + - modpost: fix section mismatch message for R_ARM_{PC24,CALL,JUMP24} + - crypto: marvell/cesa - Fix type mismatch warning + - modpost: fix off by one in is_executable_section() + - ARC: define ASM_NL and __ALIGN(_STR) outside #ifdef __ASSEMBLY__ guard + - NFSv4.1: freeze the session table upon receiving NFS4ERR_BADSESSION + - hwrng: st - Fix W=1 unused variable warning + - hwrng: st - keep clock enabled while hwrng is registered + - USB: serial: option: add LARA-R6 01B PIDs + - usb: dwc3: gadget: Propagate core init errors to UDC during pullup + - block: fix signed int overflow in Amiga partition support + - block: change all __u32 annotations to __be32 in affs_hardblocks.h + - w1: fix loop in w1_fini() + - sh: j2: Use ioremap() to translate device tree address into kernel memory + - media: usb: Check az6007_read() return value + - media: videodev2.h: Fix struct v4l2_input tuner index comment + - usb: dwc3: qcom: Fix potential memory leak + - extcon: Fix kernel doc of property fields to avoid warnings + - extcon: Fix kernel doc of property capability fields to avoid warnings + - usb: phy: phy-tahvo: fix memory leak in tahvo_usb_probe() + - usb: hide unused usbfs_notify_suspend/resume functions + - mfd: rt5033: Drop rt5033-battery sub-device + - KVM: s390: fix KVM_S390_GET_CMMA_BITS for GFNs in memslot holes + - usb: dwc3: qcom: Release the correct resources in dwc3_qcom_remove() + - mfd: intel-lpss: Add missing check for platform_get_resource + - serial: 8250_omap: Use force_suspend and resume for system suspend + - mfd: stmfx: Fix error path in stmfx_chip_init + - KVM: s390: vsie: fix the length of APCB bitmap + - mfd: stmpe: Only disable the regulators if they are enabled + - pwm: imx-tpm: force 'real_period' to be zero in suspend + - pwm: sysfs: Do not apply state to already disabled PWMs + - rtc: st-lpc: Release some resources in st_rtc_probe() in case of error + - sctp: fix potential deadlock on &net->sctp.addr_wq_lock + - Add MODULE_FIRMWARE() for FIRMWARE_TG357766. + - spi: bcm-qspi: return error if neither hif_mspi nor mspi is available + - mailbox: ti-msgmgr: Fill non-message tx data fields with 0x0 + - f2fs: fix error path handling in truncate_dnode() + - powerpc: allow PPC_EARLY_DEBUG_CPM only when SERIAL_CPM=y + - net: bridge: keep ports without IFF_UNICAST_FLT in BR_PROMISC mode + - tcp: annotate data races in __tcp_oow_rate_limited() + - xsk: Improve documentation for AF_XDP + - xsk: Honor SO_BINDTODEVICE on bind + - net/sched: act_pedit: Add size check for TCA_PEDIT_PARMS_EX + - net: dsa: tag_sja1105: fix MAC DA patching from meta frames + - sh: dma: Fix DMA channel offset calculation + - i2c: xiic: Defer xiic_wakeup() and __xiic_start_xfer() in xiic_process() + - i2c: xiic: Don't try to handle more interrupt events after error + - ALSA: jack: Fix mutex call in snd_jack_report() + - NFSD: add encoding of op_recall flag for write delegation + - mmc: core: disable TRIM on Kingston EMMC04G-M627 + - mmc: core: disable TRIM on Micron MTFC4GACAJCN-1M + - mmc: sdhci: fix DMA configure compatibility issue when 64bit DMA mode is + used. + - bcache: Remove unnecessary NULL point check in node allocations + - integrity: Fix possible multiple allocation in integrity_inode_get() + - jffs2: reduce stack usage in jffs2_build_xattr_subsystem() + - fs: avoid empty option when generating legacy mount string + - ext4: Remove ext4 locking of moved directory + - Revert "f2fs: fix potential corruption when moving a directory" + - fs: Establish locking order for unrelated directories + - fs: Lock moved directories + - btrfs: fix race when deleting quota root from the dirty cow roots list + - ARM: orion5x: fix d2net gpio initialization + - fs: no need to check source + - fanotify: disallow mount/sb marks on kernel internal pseudo fs + - block: add overflow checks for Amiga partition support + - netfilter: nf_tables: fix nat hook table deletion + - netfilter: nftables: add helper function to set the base sequence number + - netfilter: add helper function to set up the nfnetlink header and use it + - netfilter: nf_tables: use net_generic infra for transaction data + - netfilter: nf_tables: add rescheduling points during loop detection walks + - netfilter: nf_tables: add NFT_TRANS_PREPARE_ERROR to deal with bound + set/chain + - netfilter: nf_tables: reject unbound anonymous set before commit phase + - netfilter: nf_tables: unbind non-anonymous set if rule construction fails + - netfilter: nf_tables: fix scheduling-while-atomic splat + - netfilter: conntrack: Avoid nf_ct_helper_hash uses after free + - tty: serial: fsl_lpuart: add earlycon for imx8ulp platform + - block/partition: fix signedness issue for Amiga partitions + - net: lan743x: Don't sleep in atomic context + - workqueue: clean up WORK_* constant types, clarify masking + - drm/panel: Initialise panel dev and funcs through drm_panel_init() + - drm/panel: Add and fill drm_panel type field + - drm/panel: simple: Add connector_type for innolux_at043tn24 + - igc: Remove delay during TX ring configuration + - igc: set TP bit in 'supported' and 'advertising' fields of + ethtool_link_ksettings + - scsi: qla2xxx: Fix error code in qla2x00_start_sp() + - net: mvneta: fix txq_map in case of txq_number==1 + - ionic: improve irq numa locality + - ionic: clean irq affinity on queue deinit + - ionic: move irq request to qcq alloc + - ionic: ionic_intr_free parameter change + - ionic: remove WARN_ON to prevent panic_on_warn + - icmp6: Fix null-ptr-deref of ip6_null_entry->rt6i_idev in icmp6_dev(). + - udp6: fix udp6_ehashfn() typo + - ntb: idt: Fix error handling in idt_pci_driver_init() + - NTB: amd: Fix error handling in amd_ntb_pci_driver_init() + - ntb: intel: Fix error handling in intel_ntb_pci_driver_init() + - NTB: ntb_transport: fix possible memory leak while device_register() fails + - NTB: ntb_tool: Add check for devm_kcalloc + - ipv6/addrconf: fix a potential refcount underflow for idev + - platform/x86: wmi: Replace UUID redefinitions by their originals + - platform/x86: wmi: Fix indentation in some cases + - platform/x86: wmi: remove unnecessary argument + - platform/x86: wmi: use guid_t and guid_equal() + - platform/x86: wmi: move variables + - platform/x86: wmi: Break possible infinite loop when parsing GUID + - erofs: avoid infinite loop in z_erofs_do_read_page() when reading beyond EOF + - wifi: airo: avoid uninitialized warning in airo_get_rate() + - cls_flower: Add extack support for src and dst port range options + - net/sched: flower: Ensure both minimum and maximum ports are specified + - net/sched: make psched_mtu() RTNL-less safe + - pinctrl: amd: Fix mistake in handling clearing pins at startup + - pinctrl: amd: Detect internal GPIO0 debounce handling + - pinctrl: amd: Only use special debounce behavior for GPIO 0 + - tpm: tpm_vtpm_proxy: fix a race condition in /dev/vtpmx creation + - mtd: rawnand: meson: fix unaligned DMA buffers handling + - net: bcmgenet: Ensure MDIO unregistration has clocks enabled + - powerpc: Fail build if using recordmcount with binutils v2.37 + - misc: fastrpc: Create fastrpc scalar with correct buffer count + - SUNRPC: Fix UAF in svc_tcp_listen_data_ready() + - erofs: fix compact 4B support for 16k block size + - ext4: fix wrong unit use in ext4_mb_clear_bb + - ext4: only update i_reserved_data_blocks on successful block allocation + - jfs: jfs_dmap: Validate db_l2nbperpage while mounting + - PCI/PM: Avoid putting EloPOS E2/S2/H2 PCIe Ports in D3cold + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9235 + - PCI: qcom: Disable write access to read only registers for IP v2.3.3 + - PCI: rockchip: Assert PCI Configuration Enable bit after probe + - PCI: rockchip: Write PCI Device ID to correct register + - PCI: rockchip: Add poll and timeout to wait for PHY PLLs to be locked + - PCI: rockchip: Fix legacy IRQ generation for RK3399 PCIe endpoint core + - PCI: rockchip: Use u32 variable to access 32-bit registers + - PCI: rockchip: Set address alignment for endpoint mode + - misc: pci_endpoint_test: Free IRQs before removing the device + - misc: pci_endpoint_test: Re-init completion for every test + - md/raid0: add discard support for the 'original' layout + - fs: dlm: return positive pid value for F_GETLK + - drm/atomic: Allow vblank-enabled + self-refresh "disable" + - drm/rockchip: vop: Leave vblank enabled in self-refresh + - serial: atmel: don't enable IRQs prematurely + - firmware: stratix10-svc: Fix a potential resource leak in + svc_create_memory_pool() + - hwrng: imx-rngc - fix the timeout for init and self check + - ceph: don't let check_caps skip sending responses for revoke msgs + - meson saradc: fix clock divider mask length + - Revert "8250: add support for ASIX devices with a FIFO bug" + - tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() in + case of error + - tty: serial: samsung_tty: Fix a memory leak in s3c24xx_serial_getclk() when + iterating clk + - tracing/histograms: Add histograms to hist_vars if they have referenced + variables + - ring-buffer: Fix deadloop issue on reading trace_pipe + - xtensa: ISS: fix call to split_if_spec + - tracing: Fix null pointer dereference in tracing_err_log_open() + - tracing/probes: Fix not to count error code to total length + - scsi: qla2xxx: Wait for io return on terminate rport + - scsi: qla2xxx: Fix potential NULL pointer dereference + - scsi: qla2xxx: Check valid rport returned by fc_bsg_to_rport() + - scsi: qla2xxx: Correct the index of array + - scsi: qla2xxx: Pointer may be dereferenced + - scsi: qla2xxx: Remove unused nvme_ls_waitq wait queue + - drm/atomic: Fix potential use-after-free in nonblocking commits + - perf probe: Add test for regression introduced by switch to + die_get_decl_file() + - btrfs: fix warning when putting transaction with qgroups enabled after abort + - fuse: revalidate: don't invalidate if interrupted + - selftests: tc: set timeout to 15 minutes + - can: bcm: Fix UAF in bcm_proc_show() + - drm/client: Fix memory leak in drm_client_target_cloned + - drm/client: Fix memory leak in drm_client_modeset_probe + - ext4: correct inline offset when handling xattrs in inode body + - debugobjects: Recheck debug_objects_enabled before reporting + - nbd: Add the maximum limit of allocated index in nbd_dev_add + - md: fix data corruption for raid456 when reshape restart while grow up + - md/raid10: prevent soft lockup while flush writes + - posix-timers: Ensure timer ID search-loop limit is valid + - arm64: mm: fix VA-range sanity check + - sched/fair: Don't balance task to its current running CPU + - bpf: Address KCSAN report on bpf_lru_list + - devlink: report devlink_port_type_warn source device + - wifi: wext-core: Fix -Wstringop-overflow warning in + ioctl_standard_iw_point() + - wifi: iwlwifi: mvm: avoid baid size integer overflow + - igb: Fix igb_down hung on surprise removal + - spi: bcm63xx: fix max prepend length + - fbdev: imxfb: warn about invalid left/right margin + - pinctrl: amd: Use amd_pinconf_set() for all config options + - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field() + - iavf: Fix use-after-free in free_netdev + - net:ipv6: check return value of pskb_trim() + - Revert "tcp: avoid the lookup process failing to get sk in ehash table" + - fbdev: au1200fb: Fix missing IRQ check in au1200fb_drv_probe + - llc: Don't drop packet from non-root netns. + - netfilter: nf_tables: fix spurious set element insertion failure + - netfilter: nf_tables: can't schedule in nft_chain_validate + - tcp: annotate data-races around tp->tcp_tx_delay + - net: Replace the limit of TCP_LINGER2 with TCP_FIN_TIMEOUT_MAX + - tcp: annotate data-races around tp->linger2 + - tcp: annotate data-races around rskq_defer_accept + - tcp: annotate data-races around tp->notsent_lowat + - tcp: annotate data-races around fastopenq.max_qlen + - tracing/histograms: Return an error if we fail to add histogram to hist_vars + list + - Linux 5.4.251 + * Focal update: v5.4.250 upstream stable release (LP: #2033297) + - x86/microcode/AMD: Load late on both threads too + - Linux 5.4.250 + * Focal update: v5.4.249 upstream stable release (LP: #2033278) + - nilfs2: reject devices with insufficient block count + - mm: rewrite wait_on_page_bit_common() logic + - list: add "list_del_init_careful()" to go with "list_empty_careful()" + - epoll: ep_autoremove_wake_function should use list_del_init_careful + - tracing: Add tracing_reset_all_online_cpus_unlocked() function + - x86/purgatory: remove PGO flags + - tick/common: Align tick period during sched_timer setup + - media: dvbdev: Fix memleak in dvb_register_device + - media: dvbdev: fix error logic at dvb_register_device() + - media: dvb-core: Fix use-after-free due to race at dvb_register_device() + - nilfs2: fix buffer corruption due to concurrent device reads + - Drivers: hv: vmbus: Fix vmbus_wait_for_unload() to scan present CPUs + - PCI: hv: Fix a race condition bug in hv_pci_query_relations() + - cgroup: Do not corrupt task iteration when rebinding subsystem + - mmc: meson-gx: remove redundant mmc_request_done() call from irq context + - ip_tunnels: allow VXLAN/GENEVE to inherit TOS/TTL from VLAN + - writeback: fix dereferencing NULL mapping->host on writeback_page_template + - nilfs2: prevent general protection fault in nilfs_clear_dirty_page() + - cifs: Clean up DFS referral cache + - cifs: Get rid of kstrdup_const()'d paths + - cifs: Introduce helpers for finding TCP connection + - cifs: Merge is_path_valid() into get_normalized_path() + - cifs: Fix potential deadlock when updating vol in cifs_reconnect() + - x86/mm: Avoid using set_pgd() outside of real PGD pages + - ieee802154: hwsim: Fix possible memory leaks + - xfrm: Linearize the skb after offloading if needed. + - net: qca_spi: Avoid high load if QCA7000 is not available + - mmc: mtk-sd: fix deferred probing + - mmc: mvsdio: convert to devm_platform_ioremap_resource + - mmc: mvsdio: fix deferred probing + - mmc: omap: fix deferred probing + - mmc: omap_hsmmc: fix deferred probing + - mmc: sdhci-acpi: fix deferred probing + - mmc: sh_mmcif: fix deferred probing + - mmc: usdhi60rol0: fix deferred probing + - ipvs: align inner_mac_header for encapsulation + - net: dsa: mt7530: fix trapping frames on non-MT7621 SoC MT7530 switch + - be2net: Extend xmit workaround to BE3 chip + - netfilter: nf_tables: disallow element updates of bound anonymous sets + - netfilter: nfnetlink_osf: fix module autoload + - Revert "net: phy: dp83867: perform soft reset and retain established link" + - sch_netem: acquire qdisc lock in netem_change() + - scsi: target: iscsi: Prevent login threads from racing between each other + - HID: wacom: Add error check to wacom_parse_and_register() + - arm64: Add missing Set/Way CMO encodings + - media: cec: core: don't set last_initiator if tx in progress + - nfcsim.c: Fix error checking for debugfs_create_dir + - usb: gadget: udc: fix NULL dereference in remove() + - s390/cio: unregister device when the only path is gone + - ASoC: nau8824: Add quirk to active-high jack-detect + - ARM: dts: Fix erroneous ADS touchscreen polarities + - drm/exynos: vidi: fix a wrong error return + - drm/exynos: fix race condition UAF in exynos_g2d_exec_ioctl + - drm/radeon: fix race condition UAF in radeon_gem_set_domain_ioctl + - x86/apic: Fix kernel panic when booting with intremap=off and x2apic_phys + - i2c: imx-lpi2c: fix type char overflow issue when calculating the clock + cycle + - mm: fix VM_BUG_ON(PageTail) and BUG_ON(PageWriteback) + - mm: make wait_on_page_writeback() wait for multiple pending writebacks + - Linux 5.4.249 + * allow io_uring to be disabled in runtime (LP: #2035116) + - io_uring: add a sysctl to disable io_uring system-wide + * CVE-2023-31083 + - Bluetooth: hci_ldisc: check HCI_UART_PROTO_READY flag in HCIUARTGETPROTO + * CVE-2023-4132 + - media: usb: siano: Fix warning due to null work_func_t function pointer + * CVE-2023-3772 + - xfrm: add NULL check in xfrm_update_ae_params + * CVE-2023-0597 + - random32: add noise from network and scheduling activity + - x86/kasan: Map shadow for percpu pages on demand + - x86/mm: Randomize per-cpu entry area + - x86/mm: Recompute physical address for every page of per-CPU CEA mapping + - x86/mm: Populate KASAN shadow for entire per-CPU range of CPU entry area + - x86/mm: Do not shuffle CPU entry areas without KASLR + + -- Joseph Salisbury Wed, 11 Oct 2023 15:19:36 -0400 + +linux-oracle (5.4.0-1111.120) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1111.120 -proposed tracker (LP: #2038155) + + * CVE-2023-42755 + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + + [ Ubuntu: 5.4.0-165.182 ] + + * focal/linux: 5.4.0-165.182 -proposed tracker (LP: #2038163) + * CVE-2023-42756 + - netfilter: ipset: Fix race between IPSET_CMD_CREATE and IPSET_CMD_SWAP + * CVE-2023-4623 + - net/sched: sch_hfsc: Ensure inner classes have fsc curve + * CVE-2023-42755 + - net/sched: Retire rsvp classifier + - [Config] remove NET_CLS_RSVP and NET_CLS_RSVP6 + * CVE-2023-42753 + - netfilter: ipset: add the missing IP_SET_HASH_WITH_NET0 macro for + ip_set_hash_netportnet.c + * CVE-2023-34319 + - xen/netback: Fix buffer overrun triggered by unusual packet + * CVE-2023-4921 + - net: sched: sch_qfq: Fix UAF in qfq_dequeue() + * CVE-2023-42752 + - igmp: limit igmpv3_newpack() packet size to IP_MAX_MTU + * CVE-2023-4881 + - netfilter: nftables: exthdr: fix 4-byte stack OOB write + * CVE-2023-4622 + - af_unix: Fix null-ptr-deref in unix_stream_sendpage(). + + -- Joseph Salisbury Tue, 03 Oct 2023 11:14:36 -0400 + +linux-oracle (5.4.0-1110.119) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1110.119 -proposed tracker (LP: #2033859) + + * Focal update: v5.4.248 upstream stable release (LP: #2031121) + - [Config] updateconfigs for DECNET + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-164.181 ] + + * focal/linux: 5.4.0-164.181 -proposed tracker (LP: #2033867) + * Please enable Renesas RZ platform serial installer (LP: #2022361) + - [Config] enable hihope RZ/G2M serial console + * Azure: hv_netvsc: add support for vlans in AF_PACKET mode (LP: #2030872) + - hv_netvsc: add support for vlans in AF_PACKET mode + * systemd mount units fail during boot, while file system is correctly mounted + (LP: #1837227) + - list: introduce list_for_each_continue() + - proc/mounts: add cursor + * CVE-2023-40283 + - Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb + * CVE-2023-20588 + - x86/bugs: Increase the x86 bugs vector size to two u32s + - x86/CPU/AMD: Do not leak quotient data after a division by 0 + - x86/CPU/AMD: Fix the DIV(0) initial fix attempt + * CVE-2023-4194 + - net: tun_chr_open(): set sk_uid from current_fsuid() + - net: tap_open(): set sk_uid from current_fsuid() + * CVE-2023-1206 + - tcp: Reduce chance of collisions in inet6_hashfn(). + * CVE-2021-4001 + - bpf: Fix toctou on read-only map's constant scalar tracking + * Focal update: v5.4.248 upstream stable release (LP: #2031121) + - test_firmware: fix a memory leak with reqs buffer + - KEYS: asymmetric: Copy sig and digest in public_key_verify_signature() + - dasd: refactor dasd_ioctl_information + - s390/dasd: Use correct lock while counting channel queue length + - power: supply: ab8500: Fix external_power_changed race + - power: supply: sc27xx: Fix external_power_changed race + - power: supply: bq27xxx: Use mod_delayed_work() instead of cancel() + + schedule() + - ARM: dts: vexpress: add missing cache properties + - power: supply: Ratelimit no data debug output + - platform/x86: asus-wmi: Ignore WMI events with codes 0x7B, 0xC0 + - regulator: Fix error checking for debugfs_create_dir + - irqchip/meson-gpio: Mark OF related data as maybe unused + - power: supply: Fix logic checking if system is running from battery + - btrfs: handle memory allocation failure in btrfs_csum_one_bio + - parisc: Improve cache flushing for PCXL in arch_sync_dma_for_cpu() + - parisc: Flush gatt writes and adjust gatt mask in parisc_agp_mask_memory() + - MIPS: Alchemy: fix dbdma2 + - mips: Move initrd_start check after initrd address sanitisation. + - xen/blkfront: Only check REQ_FUA for writes + - drm:amd:amdgpu: Fix missing buffer object unlock in failure path + - ocfs2: fix use-after-free when unmounting read-only filesystem + - ocfs2: check new file size on fallocate call + - nios2: dts: Fix tse_mac "max-frame-size" property + - nilfs2: fix incomplete buffer cleanup in nilfs_btnode_abort_change_key() + - nilfs2: fix possible out-of-bounds segment allocation in resize ioctl + - kexec: support purgatories with .text.hot sections + - powerpc/purgatory: remove PGO flags + - nouveau: fix client work fence deletion race + - RDMA/uverbs: Restrict usage of privileged QKEYs + - net: usb: qmi_wwan: add support for Compal RXM-G1 + - ALSA: hda/realtek: Add a quirk for Compaq N14JP6 + - Remove DECnet support from kernel + - [Config] updateconfigs for DECNET + - USB: serial: option: add Quectel EM061KGL series + - serial: lantiq: add missing interrupt ack + - usb: dwc3: gadget: Reset num TRBs before giving back the request + - spi: spi-fsl-dspi: Remove unused chip->void_write_data + - spi: fsl-dspi: avoid SCK glitches with continuous transfers + - netfilter: nfnetlink: skip error delivery on batch in case of ENOMEM + - ping6: Fix send to link-local addresses with VRF. + - RDMA/rxe: Remove the unused variable obj + - RDMA/rxe: Removed unused name from rxe_task struct + - RDMA/rxe: Fix the use-before-initialization error of resp_pkts + - iavf: remove mask from iavf_irq_enable_queues() + - IB/uverbs: Fix to consider event queue closing also upon non-blocking mode + - IB/isert: Fix dead lock in ib_isert + - IB/isert: Fix possible list corruption in CMA handler + - IB/isert: Fix incorrect release of isert connection + - ipvlan: fix bound dev checking for IPv6 l3s mode + - sctp: fix an error code in sctp_sf_eat_auth() + - igb: fix nvm.ops.read() error handling + - drm/nouveau/dp: check for NULL nv_connector->native_mode + - drm/nouveau/kms: Don't change EDID when it hasn't actually changed + - drm/nouveau: add nv_encoder pointer check for NULL + - net/sched: cls_api: Fix lockup on flushing explicitly created chain + - net: lapbether: only support ethernet devices + - net: tipc: resize nlattr array to correct size + - selftests/ptp: Fix timestamp printf format for PTP_SYS_OFFSET + - afs: Fix vlserver probe RTT handling + - neighbour: Remove unused inline function neigh_key_eq16() + - net: Remove unused inline function dst_hold_and_use() + - neighbour: delete neigh_lookup_nodev as not used + - drm/nouveau/kms: Fix NULL pointer dereference in + nouveau_connector_detect_depth + - mmc: block: ensure error propagation for non-blk + - Linux 5.4.248 + * Focal update: v5.4.247 upstream stable release (LP: #2030818) + - blk-iocost: avoid 64-bit division in ioc_timer_fn + - block/blk-iocost (gcc13): keep large values in a new enum + - i40iw: fix build warning in i40iw_manage_apbvt() + - i40e: fix build warnings in i40e_alloc.h + - spi: qup: Request DMA before enabling clocks + - neighbour: Replace zero-length array with flexible-array member + - neighbour: fix unaligned access to pneigh_entry + - net: dsa: lan9303: allow vid != 0 in port_fdb_{add|del} methods + - Bluetooth: Fix l2cap_disconnect_req deadlock + - Bluetooth: L2CAP: Add missing checks for invalid DCID + - netfilter: conntrack: fix NULL pointer dereference in nf_confirm_cthelper + - netfilter: ipset: Add schedule point in call_ad(). + - rfs: annotate lockless accesses to sk->sk_rxhash + - rfs: annotate lockless accesses to RFS sock flow table + - net: sched: move rtm_tca_policy declaration to include file + - net: sched: fix possible refcount leak in tc_chain_tmplt_add() + - lib: cpu_rmap: Fix potential use-after-free in irq_cpu_rmap_release() + - bnxt_en: Query default VLAN before VNIC setup on a VF + - batman-adv: Broken sync while rescheduling delayed work + - Input: xpad - delete a Razer DeathAdder mouse VID/PID entry + - Input: psmouse - fix OOB access in Elantech protocol + - ALSA: hda/realtek: Add a quirk for HP Slim Desktop S01 + - ALSA: hda/realtek: Add Lenovo P3 Tower platform + - drm/amdgpu: fix xclk freq on CHIP_STONEY + - can: j1939: j1939_sk_send_loop_abort(): improved error queue handling in + J1939 Socket + - can: j1939: change j1939_netdev_lock type to mutex + - can: j1939: avoid possible use-after-free when j1939_can_rx_register fails + - ceph: fix use-after-free bug for inodes when flushing capsnaps + - Bluetooth: Fix use-after-free in hci_remove_ltk/hci_remove_irk + - rbd: move RBD_OBJ_FLAG_COPYUP_ENABLED flag setting + - pinctrl: meson-axg: add missing GPIOA_18 gpio group + - usb: usbfs: Enforce page requirements for mmap + - usb: usbfs: Use consistent mmap functions + - bonding (gcc13): synchronize bond_{a,t}lb_xmit() types + - i2c: sprd: Delete i2c adapter in .remove's error path + - eeprom: at24: also select REGMAP + - ext4: only check dquot_initialize_needed() when debugging + - drm/atomic: Don't pollute crtc_state->mode_blob with error pointers + - rbd: get snapshot context after exclusive lock is ensured to be held + - mtd: spinand: macronix: Add support for MX35LFxGE4AD + - Linux 5.4.247 + * CVE-2023-4128 + - net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_route: No longer copy tcf_result on update to avoid use- + after-free + * CVE-2023-3863 + - nfc: llcp: simplify llcp_sock_connect() error paths + - net: nfc: Fix use-after-free caused by nfc_llcp_find_local + * CVE-2023-3212 + - gfs2: Don't deref jdesc in evict + + -- Joseph Salisbury Mon, 11 Sep 2023 15:19:38 -0400 + +linux-oracle (5.4.0-1109.118) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1109.118 -proposed tracker (LP: #2034239) + + [ Ubuntu: 5.4.0-163.180 ] + + * focal/linux: 5.4.0-163.180 -proposed tracker (LP: #2034247) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * CVE-2023-40283 + - Bluetooth: L2CAP: Fix use-after-free in l2cap_sock_ready_cb + * CVE-2023-20588 + - x86/bugs: Increase the x86 bugs vector size to two u32s + - x86/CPU/AMD: Do not leak quotient data after a division by 0 + - x86/CPU/AMD: Fix the DIV(0) initial fix attempt + * CVE-2023-4128 + - net/sched: cls_u32: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_fw: No longer copy tcf_result on update to avoid use-after- + free + - net/sched: cls_route: No longer copy tcf_result on update to avoid use- + after-free + + -- Joseph Salisbury Wed, 06 Sep 2023 13:35:09 -0400 + +linux-oracle (5.4.0-1108.117) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1108.117 -proposed tracker (LP: #2031009) + + [ Ubuntu: 5.4.0-162.179 ] + + * focal/linux: 5.4.0-162.179 -proposed tracker (LP: #2031128) + * libgnutls report "trap invalid opcode" when trying to install packages over + https (LP: #2031093) + - [Config]: disable CONFIG_GDS_FORCE_MITIGATION + + [ Ubuntu: 5.4.0-160.177 ] + + * focal/linux: 5.4.0-160.177 -proposed tracker (LP: #2031017) + * Fix boot test warning for log_check "CPU: 0 PID: 0 at + arch/x86/kernel/fpu/xstate.c:878 get_xsave_addr+0x98/0xb0" (LP: #2031022) + - x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") + + [ Ubuntu: 5.4.0-158.175 ] + + * focal/linux: 5.4.0-158.175 -proposed tracker (LP: #2030466) + * CVE-2022-40982 + - x86/mm: Initialize text poking earlier + - x86/mm: fix poking_init() for Xen PV guests + - x86/mm: Use mm_alloc() in poking_init() + - mm: Move mm_cachep initialization to mm_init() + - init: Provide arch_cpu_finalize_init() + - x86/cpu: Switch to arch_cpu_finalize_init() + - ARM: cpu: Switch to arch_cpu_finalize_init() + - sparc/cpu: Switch to arch_cpu_finalize_init() + - um/cpu: Switch to arch_cpu_finalize_init() + - init: Remove check_bugs() leftovers + - init: Invoke arch_cpu_finalize_init() earlier + - init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init() + - x86/fpu: Remove cpuinfo argument from init functions + - x86/fpu: Mark init functions __init + - x86/fpu: Move FPU initialization into arch_cpu_finalize_init() + - x86/xen: Fix secondary processors' FPU initialization + - x86/speculation: Add Gather Data Sampling mitigation + - x86/speculation: Add force option to GDS mitigation + - x86/speculation: Add Kconfig option for GDS + - KVM: Add GDS_NO support to KVM + - Documentation/x86: Fix backwards on/off logic about YMM support + - [Config]: Enable CONFIG_ARCH_HAS_CPU_FINALIZE_INIT and + CONFIG_GDS_FORCE_MITIGATION + * CVE-2023-3609 + - net/sched: cls_u32: Fix reference counter leak leading to overflow + * CVE-2023-20593 + - x86/cpu/amd: Move the errata checking functionality up + - x86/cpu/amd: Add a Zenbleed fix + * CVE-2023-3611 + - net/sched: sch_qfq: account for stab overhead in qfq_enqueue + * stacked overlay file system mounts that have chroot() called against them + appear to be getting locked (by the kernel most likely?) (LP: #2016398) + - SAUCE: overlayfs: fix reference count mismatch + * Focal update: v5.4.246 upstream stable release (LP: #2028981) + - RDMA/efa: Fix unsupported page sizes in device + - RDMA/bnxt_re: Enable SRIOV VF support on Broadcom's 57500 adapter series + - RDMA/bnxt_re: Refactor queue pair creation code + - RDMA/bnxt_re: Fix return value of bnxt_re_process_raw_qp_pkt_rx + - iommu/rockchip: Fix unwind goto issue + - iommu/amd: Don't block updates to GATag if guest mode is on + - dmaengine: pl330: rename _start to prevent build error + - net/mlx5: fw_tracer, Fix event handling + - netrom: fix info-leak in nr_write_internal() + - af_packet: Fix data-races of pkt_sk(sk)->num. + - amd-xgbe: fix the false linkup in xgbe_phy_status + - mtd: rawnand: ingenic: fix empty stub helper definitions + - af_packet: do not use READ_ONCE() in packet_bind() + - tcp: deny tcp_disconnect() when threads are waiting + - tcp: Return user_mss for TCP_MAXSEG in CLOSE/LISTEN state if user_mss set + - net/sched: sch_ingress: Only create under TC_H_INGRESS + - net/sched: sch_clsact: Only create under TC_H_CLSACT + - net/sched: Reserve TC_H_INGRESS (TC_H_CLSACT) for ingress (clsact) Qdiscs + - net/sched: Prohibit regrafting ingress or clsact Qdiscs + - net: sched: fix NULL pointer dereference in mq_attach + - ocfs2/dlm: move BITS_TO_BYTES() to bitops.h for wider use + - net/netlink: fix NETLINK_LIST_MEMBERSHIPS length report + - udp6: Fix race condition in udp6_sendmsg & connect + - net: dsa: mv88e6xxx: Increase wait after reset deactivation + - mtd: rawnand: marvell: ensure timing values are written + - mtd: rawnand: marvell: don't set the NAND frequency select + - watchdog: menz069_wdt: fix watchdog initialisation + - mailbox: mailbox-test: Fix potential double-free in + mbox_test_message_write() + - ARM: 9295/1: unwind:fix unwind abort for uleb128 case + - media: rcar-vin: Select correct interrupt mode for V4L2_FIELD_ALTERNATE + - fbdev: modedb: Add 1920x1080 at 60 Hz video mode + - fbdev: stifb: Fix info entry in sti_struct on error path + - nbd: Fix debugfs_create_dir error checking + - ASoC: dwc: limit the number of overrun messages + - xfrm: Check if_id in inbound policy/secpath match + - ASoC: ssm2602: Add workaround for playback distortions + - media: dvb_demux: fix a bug for the continuity counter + - media: dvb-usb: az6027: fix three null-ptr-deref in az6027_i2c_xfer() + - media: dvb-usb-v2: ec168: fix null-ptr-deref in ec168_i2c_xfer() + - media: dvb-usb-v2: ce6230: fix null-ptr-deref in ce6230_i2c_master_xfer() + - media: dvb-usb-v2: rtl28xxu: fix null-ptr-deref in rtl28xxu_i2c_xfer + - media: dvb-usb: digitv: fix null-ptr-deref in digitv_i2c_xfer() + - media: dvb-usb: dw2102: fix uninit-value in su3000_read_mac_address + - media: netup_unidvb: fix irq init by register it at the end of probe + - media: dvb_ca_en50221: fix a size write bug + - media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() + - media: mn88443x: fix !CONFIG_OF error by drop of_match_ptr from ID table + - media: dvb-core: Fix use-after-free due on race condition at dvb_net + - media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 + - wifi: rtl8xxxu: fix authentication timeout due to incorrect RCR value + - ARM: dts: stm32: add pin map for CAN controller on stm32f7 + - arm64/mm: mark private VM_FAULT_X defines as vm_fault_t + - scsi: core: Decrease scsi_device's iorequest_cnt if dispatch failed + - wifi: b43: fix incorrect __packed annotation + - netfilter: conntrack: define variables exp_nat_nla_policy and any_addr with + CONFIG_NF_NAT + - ALSA: oss: avoid missing-prototype warnings + - atm: hide unused procfs functions + - mailbox: mailbox-test: fix a locking issue in mbox_test_message_write() + - iio: adc: mxs-lradc: fix the order of two cleanup operations + - HID: google: add jewel USB id + - HID: wacom: avoid integer overflow in wacom_intuos_inout() + - iio: light: vcnl4035: fixed chip ID check + - iio: dac: mcp4725: Fix i2c_master_send() return value handling + - iio: dac: build ad5758 driver when AD5758 is selected + - net: usb: qmi_wwan: Set DTR quirk for BroadMobi BM818 + - usb: gadget: f_fs: Add unbind event before functionfs_unbind + - misc: fastrpc: return -EPIPE to invocations on device removal + - misc: fastrpc: reject new invocations during device removal + - scsi: stex: Fix gcc 13 warnings + - ata: libata-scsi: Use correct device no in ata_find_dev() + - flow_dissector: work around stack frame size warning + - x86/boot: Wrap literal addresses in absolute_pointer() + - ACPI: thermal: drop an always true check + - gcc-12: disable '-Wdangling-pointer' warning for now + - eth: sun: cassini: remove dead code + - kernel/extable.c: use address-of operator on section symbols + - treewide: Remove uninitialized_var() usage + - lib/dynamic_debug.c: use address-of operator on section symbols + - wifi: rtlwifi: remove always-true condition pointed out by GCC 12 + - mmc: vub300: fix invalid response handling + - tty: serial: fsl_lpuart: use UARTCTRL_TXINV to send break instead of + UARTCTRL_SBK + - selinux: don't use make's grouped targets feature yet + - tracing/probe: trace_probe_primary_from_call(): checked list_first_entry + - ext4: add EA_INODE checking to ext4_iget() + - ext4: set lockdep subclass for the ea_inode in ext4_xattr_inode_cache_find() + - ext4: disallow ea_inodes with extended attributes + - ext4: add lockdep annotations for i_data_sem for ea_inode's + - fbcon: Fix null-ptr-deref in soft_cursor + - test_firmware: fix the memory leak of the allocated firmware buffer + - regmap: Account for register length when chunking + - scsi: dpt_i2o: Remove broken pass-through ioctl (I2OUSERCMD) + - scsi: dpt_i2o: Do not process completions with invalid addresses + - [Config] updateconfigs for SCSI_DPT_I2O + - RDMA/bnxt_re: Remove set but not used variable 'dev_attr' + - RDMA/bnxt_re: Remove the qp from list only if the qp destroy succeeds + - drm/edid: Fix uninitialized variable in drm_cvt_modes() + - wifi: rtlwifi: 8192de: correct checking of IQK reload + - drm/edid: fix objtool warning in drm_cvt_modes() + - Linux 5.4.246 + * Focal update: v5.4.245 upstream stable release (LP: #2028980) + - cdc_ncm: Implement the 32-bit version of NCM Transfer Block + - net: cdc_ncm: Deal with too low values of dwNtbOutMaxSize + - power: supply: bq27xxx: After charger plug in/out wait 0.5s for things to + stabilize + - power: supply: core: Refactor + power_supply_set_input_current_limit_from_supplier() + - power: supply: bq24190: Call power_supply_changed() after updating input + current + - fs: fix undefined behavior in bit shift for SB_NOUSER + - net/mlx5: devcom only supports 2 ports + - net/mlx5: Devcom, serialize devcom registration + - cdc_ncm: Fix the build warning + - io_uring: always grab lock in io_cancel_async_work() + - io_uring: don't drop completion lock before timer is fully initialized + - io_uring: have io_kill_timeout() honor the request references + - bluetooth: Add cmd validity checks at the start of hci_sock_ioctl() + - binder: fix UAF caused by faulty buffer cleanup + - ipv{4,6}/raw: fix output xfrm lookup wrt protocol + - netfilter: ctnetlink: Support offloaded conntrack entry deletion + - Linux 5.4.245 + * Focal update: v5.4.244 upstream stable release (LP: #2028697) + - driver core: add a helper to setup both the of_node and fwnode of a device + - drm/mipi-dsi: Set the fwnode for mipi_dsi_device + - ARM: 9296/1: HP Jornada 7XX: fix kernel-doc warnings + - linux/dim: Do nothing if no time delta between samples + - net: Fix load-tearing on sk->sk_stamp in sock_recv_cmsgs(). + - netfilter: conntrack: fix possible bug_on with enable_hooks=1 + - netlink: annotate accesses to nlk->cb_running + - net: annotate sk->sk_err write from do_recvmmsg() + - net: tap: check vlan with eth_type_vlan() method + - net: add vlan_get_protocol_and_depth() helper + - net: datagram: fix data-races in datagram_poll() + - af_unix: Fix a data race of sk->sk_receive_queue->qlen. + - af_unix: Fix data races around sk->sk_shutdown. + - fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode() + - drm/amd/display: Use DC_LOG_DC in the trasform pixel function + - regmap: cache: Return error in cache sync operations for REGCACHE_NONE + - firmware: arm_sdei: Fix sleep from invalid context BUG + - ACPI: EC: Fix oops when removing custom query handlers + - drm/tegra: Avoid potential 32-bit integer overflow + - ACPICA: Avoid undefined behavior: applying zero offset to null pointer + - ACPICA: ACPICA: check null return of ACPI_ALLOCATE_ZEROED in + acpi_db_display_objects + - wifi: brcmfmac: cfg80211: Pass the PMK in binary instead of hex + - ext2: Check block size validity during mount + - scsi: lpfc: Prevent lpfc_debugfs_lockstat_write() buffer overflow + - net: pasemi: Fix return type of pasemi_mac_start_tx() + - net: Catch invalid index in XPS mapping + - scsi: target: iscsit: Free cmds before session free + - lib: cpu_rmap: Avoid use after free on rmap->obj array entries + - scsi: message: mptlan: Fix use after free bug in mptlan_remove() due to race + condition + - gfs2: Fix inode height consistency check + - ext4: set goal start correctly in ext4_mb_normalize_request + - ext4: Fix best extent lstart adjustment logic in ext4_mb_new_inode_pa() + - f2fs: fix to drop all dirty pages during umount() if cp_error is set + - samples/bpf: Fix fout leak in hbm's run_bpf_prog + - wifi: iwlwifi: pcie: fix possible NULL pointer dereference + - wifi: iwlwifi: pcie: Fix integer overflow in iwl_write_to_user_buf + - wifi: iwlwifi: dvm: Fix memcpy: detected field-spanning write backtrace + - Bluetooth: L2CAP: fix "bad unlock balance" in l2cap_disconnect_rsp + - HID: logitech-hidpp: Don't use the USB serial for USB devices + - HID: logitech-hidpp: Reconcile USB and Unifying serials + - spi: spi-imx: fix MX51_ECSPI_* macros when cs > 3 + - HID: wacom: generic: Set battery quirk only when we see battery data + - usb: typec: tcpm: fix multiple times discover svids error + - serial: 8250: Reinit port->pm on port specific driver unbind + - mcb-pci: Reallocate memory region to avoid memory overlapping + - sched: Fix KCSAN noinstr violation + - recordmcount: Fix memory leaks in the uwrite function + - RDMA/core: Fix multiple -Warray-bounds warnings + - clk: tegra20: fix gcc-7 constant overflow warning + - iommu/arm-smmu-v3: Acknowledge pri/event queue overflow if any + - Input: xpad - add constants for GIP interface numbers + - phy: st: miphy28lp: use _poll_timeout functions for waits + - mfd: dln2: Fix memory leak in dln2_probe() + - btrfs: replace calls to btrfs_find_free_ino with btrfs_find_free_objectid + - btrfs: fix space cache inconsistency after error loading it from disk + - ASoC: fsl_micfil: register platform component before registering cpu dai + - cpupower: Make TSC read per CPU for Mperf monitor + - af_key: Reject optional tunnel/BEET mode templates in outbound policies + - net: fec: Better handle pm_runtime_get() failing in .remove() + - ALSA: firewire-digi00x: prevent potential use after free + - vsock: avoid to close connected socket after the timeout + - serial: arc_uart: fix of_iomap leak in `arc_serial_probe` + - ip6_gre: Fix skb_under_panic in __gre6_xmit() + - ip6_gre: Make o_seqno start from 0 in native mode + - ip_gre, ip6_gre: Fix race condition on o_seqno in collect_md mode + - erspan: get the proto with the md version for collect_md + - net: hns3: fix sending pfc frames after reset issue + - net: hns3: fix reset delay time to avoid configuration timeout + - media: netup_unidvb: fix use-after-free at del_timer() + - drm/exynos: fix g2d_open/close helper function definitions + - net: nsh: Use correct mac_offset to unwind gso skb in nsh_gso_segment() + - net: bcmgenet: Remove phy_stop() from bcmgenet_netif_stop() + - net: bcmgenet: Restore phy_stop() depending upon suspend/close + - wifi: iwlwifi: mvm: don't trust firmware n_channels + - cassini: Fix a memory leak in the error handling path of cas_init_one() + - igb: fix bit_shift to be in [1..8] range + - vlan: fix a potential uninit-value in vlan_dev_hard_start_xmit() + - USB: usbtmc: Fix direction for 0-length ioctl control messages + - usb-storage: fix deadlock when a scsi command timeouts more than once + - USB: UHCI: adjust zhaoxin UHCI controllers OverCurrent bit value + - usb: dwc3: debugfs: Resume dwc3 before accessing registers + - usb: typec: altmodes/displayport: fix pin_assignment_show + - ALSA: hda: Fix Oops by 9.1 surround channel names + - ALSA: hda: Add NVIDIA codec IDs a3 through a7 to patch table + - ALSA: hda/realtek: Add a quirk for HP EliteDesk 805 + - ALSA: hda/realtek: Add quirk for 2nd ASUS GU603 + - can: j1939: recvmsg(): allow MSG_CMSG_COMPAT flag + - can: kvaser_pciefd: Set CAN_STATE_STOPPED in kvaser_pciefd_stop() + - can: kvaser_pciefd: Call request_irq() before enabling interrupts + - can: kvaser_pciefd: Empty SRB buffer in probe + - can: kvaser_pciefd: Clear listen-only bit if not explicitly requested + - can: kvaser_pciefd: Do not send EFLUSH command on TFD interrupt + - can: kvaser_pciefd: Disable interrupts in probe error path + - KVM: x86: do not report a vCPU as preempted outside instruction boundaries + - statfs: enforce statfs[64] structure initialization + - serial: Add support for Advantech PCI-1611U card + - ceph: force updating the msg pointer in non-split case + - tpm/tpm_tis: Disable interrupts for more Lenovo devices + - powerpc/64s/radix: Fix soft dirty tracking + - nilfs2: fix use-after-free bug of nilfs_root in nilfs_evict_inode() + - netfilter: nftables: add nft_parse_register_load() and use it + - netfilter: nftables: add nft_parse_register_store() and use it + - netfilter: nftables: statify nft_parse_register() + - netfilter: nf_tables: validate registers coming from userspace. + - netfilter: nf_tables: add nft_setelem_parse_key() + - netfilter: nf_tables: allow up to 64 bytes in the set element data area + - netfilter: nf_tables: stricter validation of element data + - netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT + flag + - netfilter: nf_tables: hold mutex on netns pre_exit path + - HID: wacom: Force pen out of prox if no events have been received in a while + - HID: wacom: Add new Intuos Pro Small (PTH-460) device IDs + - HID: wacom: add three styli to wacom_intuos_get_tool_type + - lib/string_helpers: Introduce string_upper() and string_lower() helpers + - usb: gadget: u_ether: Convert prints to device prints + - usb: gadget: u_ether: Fix host MAC address case + - vc_screen: rewrite vcs_size to accept vc, not inode + - vc_screen: reload load of struct vc_data pointer in vcs_write() to avoid UAF + - s390/qdio: get rid of register asm + - s390/qdio: fix do_sqbs() inline assembly constraint + - watchdog: sp5100_tco: Immediately trigger upon starting. + - spi: fsl-spi: Re-organise transfer bits_per_word adaptation + - spi: fsl-cpm: Use 16 bit mode for large transfers with even size + - mt76: mt7615: Fix build with older compilers + - ALSA: hda/ca0132: add quirk for EVGA X299 DARK + - ALSA: hda/realtek: Enable headset onLenovo M70/M90 + - m68k: Move signal frame following exception on 68020/030 + - parisc: Handle kgdb breakpoints only in kernel context + - parisc: Allow to reboot machine after system halt + - gpio: mockup: Fix mode of debugfs files + - btrfs: use nofs when cleaning up aborted transactions + - selftests/memfd: Fix unknown type name build failure + - parisc: Fix flush_dcache_page() for usage from irq context + - x86/topology: Fix erroneous smp_num_siblings on Intel Hybrid platforms + - debugobjects: Don't wake up kswapd from fill_pool() + - fbdev: udlfb: Fix endpoint check + - net: fix stack overflow when LRO is disabled for virtual interfaces + - udplite: Fix NULL pointer dereference in __sk_mem_raise_allocated(). + - USB: core: Add routines for endpoint checks in old drivers + - USB: sisusbvga: Add endpoint checks + - media: radio-shark: Add endpoint checks + - net: fix skb leak in __skb_tstamp_tx() + - selftests: fib_tests: mute cleanup error message + - bpf: Fix mask generation for 32-bit narrow loads of 64-bit fields + - ipv6: Fix out-of-bounds access in ipv6_find_tlv() + - power: supply: leds: Fix blink to LED on transition + - power: supply: bq27xxx: Fix bq27xxx_battery_update() race condition + - power: supply: bq27xxx: Fix I2C IRQ race on remove + - power: supply: bq27xxx: Fix poll_interval handling and races on remove + - power: supply: sbs-charger: Fix INHIBITED bit for Status reg + - coresight: Fix signedness bug in tmc_etr_buf_insert_barrier_packet() + - xen/pvcalls-back: fix double frees with pvcalls_new_active_socket() + - x86/show_trace_log_lvl: Ensure stack pointer is aligned, again + - ASoC: Intel: Skylake: Fix declaration of enum skl_ch_cfg + - forcedeth: Fix an error handling path in nv_probe() + - net/mlx5: Fix error message when failing to allocate device memory + - net/mlx5: Devcom, fix error flow in mlx5_devcom_register_device + - 3c589_cs: Fix an error handling path in tc589_probe() + - Linux 5.4.244 + * Focal update: v5.4.243 upstream stable release (LP: #2025387) + - counter: 104-quad-8: Fix race condition between FLAG and CNTR reads + - drm/fb-helper: set x/yres_virtual in drm_fb_helper_check_var + - bluetooth: Perform careful capability checks in hci_sock_ioctl() + - USB: serial: option: add UNISOC vendor and TOZED LT70C product + - iio: adc: palmas_gpadc: fix NULL dereference on rmmod + - ASoC: Intel: bytcr_rt5640: Add quirk for the Acer Iconia One 7 B1-750 + - asm-generic/io.h: suppress endianness warnings for readq() and writeq() + - USB: dwc3: fix runtime pm imbalance on probe errors + - USB: dwc3: fix runtime pm imbalance on unbind + - perf sched: Cast PTHREAD_STACK_MIN to int as it may turn into + sysconf(__SC_THREAD_STACK_MIN_VALUE) + - staging: iio: resolver: ads1210: fix config mode + - debugfs: regset32: Add Runtime PM support + - xhci: fix debugfs register accesses while suspended + - MIPS: fw: Allow firmware to pass a empty env + - ipmi:ssif: Add send_retries increment + - ipmi: fix SSIF not responding under certain cond. + - kheaders: Use array declaration instead of char + - pwm: meson: Fix axg ao mux parents + - pwm: meson: Fix g12a ao clk81 name + - ring-buffer: Sync IRQ works before buffer destruction + - reiserfs: Add security prefix to xattr name in reiserfs_security_write() + - KVM: nVMX: Emulate NOPs in L2, and PAUSE if it's not intercepted + - i2c: omap: Fix standard mode false ACK readings + - Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path" + - ubifs: Fix memleak when insert_old_idx() failed + - ubi: Fix return value overwrite issue in try_write_vid_and_data() + - ubifs: Free memory for tmpfile name + - selinux: fix Makefile dependencies of flask.h + - selinux: ensure av_permissions.h is built when needed + - tpm, tpm_tis: Do not skip reset of original interrupt vector + - erofs: stop parsing non-compact HEAD index if clusterofs is invalid + - erofs: fix potential overflow calculating xattr_isize + - drm/rockchip: Drop unbalanced obj unref + - drm/vgem: add missing mutex_destroy + - drm/probe-helper: Cancel previous job before starting new one + - arm64: dts: renesas: r8a77990: Remove bogus voltages from OPP table + - arm64: dts: renesas: r8a774c0: Remove bogus voltages from OPP table + - EDAC/skx: Fix overflows on the DRAM row address mapping arrays + - ARM: dts: qcom: ipq4019: Fix the PCI I/O port range + - ARM: dts: qcom: ipq8064: reduce pci IO size to 64K + - ARM: dts: qcom: ipq8064: Fix the PCI I/O port range + - media: bdisp: Add missing check for create_workqueue + - media: uapi: add MEDIA_BUS_FMT_METADATA_FIXED media bus format. + - media: av7110: prevent underflow in write_ts_to_decoder() + - firmware: qcom_scm: Clear download bit during reboot + - drm/msm: fix unbalanced pm_runtime_enable in adreno_gpu_{init, cleanup} + - drm/msm/adreno: Defer enabling runpm until hw_init() + - drm/msm/adreno: drop bogus pm_runtime_set_active() + - mmc: sdhci-of-esdhc: fix quirk to ignore command inhibit for data + - drm/lima/lima_drv: Add missing unwind goto in lima_pdev_probe() + - regulator: core: Consistently set mutex_owner when using + ww_mutex_lock_slow() + - regulator: core: Avoid lockdep reports when resolving supplies + - x86/apic: Fix atomic update of offset in reserve_eilvt_offset() + - media: dm1105: Fix use after free bug in dm1105_remove due to race condition + - media: saa7134: fix use after free bug in saa7134_finidev due to race + condition + - media: rcar_fdp1: simplify error check logic at fdp_open() + - media: rcar_fdp1: fix pm_runtime_get_sync() usage count + - media: rcar_fdp1: Make use of the helper function + devm_platform_ioremap_resource() + - media: rcar_fdp1: Fix the correct variable assignments + - media: rcar_fdp1: Fix refcount leak in probe and remove function + - media: rc: gpio-ir-recv: Fix support for wake-up + - regulator: stm32-pwr: fix of_iomap leak + - x86/ioapic: Don't return 0 from arch_dynirq_lower_bound() + - arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step + - debugobject: Prevent init race with static objects + - timekeeping: Split jiffies seqlock + - tick/sched: Use tick_next_period for lockless quick check + - tick/sched: Reduce seqcount held scope in tick_do_update_jiffies64() + - tick/sched: Optimize tick_do_update_jiffies64() further + - tick: Get rid of tick_period + - tick/common: Align tick period with the HZ tick. + - wifi: ath6kl: minor fix for allocation size + - wifi: ath9k: hif_usb: fix memory leak of remain_skbs + - wifi: ath5k: fix an off by one check in ath5k_eeprom_read_freq_list() + - wifi: ath6kl: reduce WARN to dev_dbg() in callback + - tools: bpftool: Remove invalid \' json escape + - wifi: rtw88: mac: Return the original error from rtw_pwr_seq_parser() + - wifi: rtw88: mac: Return the original error from rtw_mac_power_switch() + - scm: fix MSG_CTRUNC setting condition for SO_PASSSEC + - vlan: partially enable SIOCSHWTSTAMP in container + - net/packet: annotate accesses to po->xmit + - net/packet: convert po->origdev to an atomic flag + - net/packet: convert po->auxdata to an atomic flag + - scsi: target: iscsit: Fix TAS handling during conn cleanup + - scsi: megaraid: Fix mega_cmd_done() CMDID_INT_CMDS + - f2fs: handle dqget error in f2fs_transfer_project_quota() + - rtlwifi: Start changing RT_TRACE into rtl_dbg + - rtlwifi: Replace RT_TRACE with rtl_dbg + - wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_rfreg() + - wifi: rtlwifi: fix incorrect error codes in rtl_debugfs_set_write_reg() + - bpftool: Fix bug for long instructions in program CFG dumps + - crypto: drbg - make drbg_prepare_hrng() handle jent instantiation errors + - crypto: drbg - Only fail when jent is unavailable in FIPS mode + - scsi: lpfc: Fix ioremap issues in lpfc_sli4_pci_mem_setup() + - bpf, sockmap: fix deadlocks in the sockhash and sockmap + - nvme: handle the persistent internal error AER + - nvme: fix async event trace event + - nvme-fcloop: fix "inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage" + - bpf, sockmap: Revert buggy deadlock fix in the sockhash and sockmap + - md/raid10: fix leak of 'r10bio->remaining' for recovery + - md/raid10: fix memleak for 'conf->bio_split' + - md: update the optimal I/O size on reshape + - md/raid10: fix memleak of md thread + - wifi: iwlwifi: make the loop for card preparation effective + - wifi: iwlwifi: mvm: check firmware response size + - ixgbe: Allow flow hash to be set via ethtool + - ixgbe: Enable setting RSS table to default values + - bpf: Don't EFAULT for getsockopt with optval=NULL + - netfilter: nf_tables: don't write table validation state without mutex + - ipv4: Fix potential uninit variable access bug in __ip_make_skb() + - netlink: Use copy_to_user() for optval in netlink_getsockopt(). + - net: amd: Fix link leak when verifying config failed + - tcp/udp: Fix memleaks of sk and zerocopy skbs with TX timestamp. + - pstore: Revert pmsg_lock back to a normal mutex + - usb: host: xhci-rcar: remove leftover quirk handling + - fpga: bridge: fix kernel-doc parameter description + - iio: light: max44009: add missing OF device matching + - usb: gadget: udc: renesas_usb3: Fix use after free bug in + renesas_usb3_remove due to race condition + - PCI: imx6: Install the fault handler only on compatible match + - genirq: Add IRQF_NO_AUTOEN for request_irq/nmi() + - ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ + - ASoC: es8316: Handle optional IRQ assignment + - linux/vt_buffer.h: allow either builtin or modular for macros + - spi: qup: Don't skip cleanup in remove's error path + - spi: fsl-spi: Fix CPM/QE mode Litte Endian + - vmci_host: fix a race condition in vmci_host_poll() causing GPF + - of: Fix modalias string generation + - ia64: mm/contig: fix section mismatch warning/error + - ia64: salinfo: placate defined-but-not-used warning + - scripts/gdb: bail early if there are no clocks + - PM: domains: Fix up terminology with parent/child + - scripts/gdb: bail early if there are no generic PD + - mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry + - mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode + - mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure + - mtd: spi-nor: cadence-quadspi: Handle probe deferral while requesting DMA + channel + - spi: cadence-quadspi: fix suspend-resume implementations + - uapi/linux/const.h: prefer ISO-friendly __typeof__ + - sh: sq: Fix incorrect element size for allocating bitmap buffer + - usb: chipidea: fix missing goto in `ci_hdrc_probe` + - usb: mtu3: fix kernel panic at qmu transfer done irq handler + - firmware: stratix10-svc: Fix an NULL vs IS_ERR() bug in probe + - tty: serial: fsl_lpuart: adjust buffer length to the intended size + - serial: 8250: Add missing wakeup event reporting + - staging: rtl8192e: Fix W_DISABLE# does not work after stop/start + - spmi: Add a check for remove callback when removing a SPMI driver + - macintosh/windfarm_smu_sat: Add missing of_node_put() + - powerpc/mpc512x: fix resource printk format warning + - powerpc/wii: fix resource printk format warnings + - powerpc/sysdev/tsi108: fix resource printk format warnings + - macintosh: via-pmu-led: requires ATA to be set + - powerpc/rtas: use memmove for potentially overlapping buffer copy + - perf/core: Fix hardlockup failure caused by perf throttle + - RDMA/siw: Fix potential page_array out of range access + - RDMA/rdmavt: Delete unnecessary NULL check + - rtc: omap: include header for omap_rtc_power_off_program prototype + - RDMA/mlx4: Prevent shift wrapping in set_user_sq_size() + - rtc: meson-vrtc: Use ktime_get_real_ts64() to get the current time + - power: supply: generic-adc-battery: fix unit scaling + - clk: add missing of_node_put() in "assigned-clocks" property parsing + - RDMA/siw: Remove namespace check from siw_netdev_event() + - IB/hfi1: Fix SDMA mmu_rb_node not being evicted in LRU order + - NFSv4.1: Always send a RECLAIM_COMPLETE after establishing lease + - firmware: raspberrypi: Keep count of all consumers + - firmware: raspberrypi: Introduce devm_rpi_firmware_get() + - input: raspberrypi-ts: Release firmware handle when not needed + - Input: raspberrypi-ts - fix refcount leak in rpi_ts_probe + - SUNRPC: remove the maximum number of retries in call_bind_status + - RDMA/mlx5: Use correct device num_ports when modify DC + - clocksource/drivers/davinci: Avoid trailing '\n' hidden in pr_fmt() + - clocksource: davinci: axe a pointless __GFP_NOFAIL + - clocksource/drivers/davinci: Fix memory leak in davinci_timer_register when + init fails + - openrisc: Properly store r31 to pt_regs on unhandled exceptions + - ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline + - leds: TI_LMU_COMMON: select REGMAP instead of depending on it + - dmaengine: mv_xor_v2: Fix an error code. + - pwm: mtk-disp: Don't check the return code of pwmchip_remove() + - pwm: mtk-disp: Adjust the clocks to avoid them mismatch + - pwm: mtk-disp: Disable shadow registers before setting backlight values + - phy: tegra: xusb: Add missing tegra_xusb_port_unregister for usb2_port and + ulpi_port + - dmaengine: dw-edma: Fix to change for continuous transfer + - dmaengine: dw-edma: Fix to enable to issue dma request on DMA processing + - dmaengine: at_xdmac: do not enable all cyclic channels + - afs: Fix updating of i_size with dv jump from server + - parisc: Fix argument pointer in real64_call_asm() + - nilfs2: do not write dirty data after degenerating to read-only + - nilfs2: fix infinite loop in nilfs_mdt_get_block() + - md/raid10: fix null-ptr-deref in raid10_sync_request + - mailbox: zynqmp: Fix IPI isr handling + - mailbox: zynqmp: Fix typo in IPI documentation + - wifi: rtl8xxxu: RTL8192EU always needs full init + - clk: rockchip: rk3399: allow clk_cifout to force clk_cifout_src to reparent + - scripts/gdb: fix lx-timerlist for Python3 + - btrfs: scrub: reject unsupported scrub flags + - s390/dasd: fix hanging blockdevice after request requeue + - dm clone: call kmem_cache_destroy() in dm_clone_init() error path + - dm integrity: call kmem_cache_destroy() in dm_integrity_init() error path + - dm flakey: fix a crash with invalid table line + - perf auxtrace: Fix address filter entire kernel size + - perf intel-pt: Fix CYC timestamps after standalone CBR + - debugobject: Ensure pool refill (again) + - nohz: Add TICK_DEP_BIT_RCU + - tick/nohz: Fix cpu_is_hotpluggable() by checking with nohz subsystem + - mailbox: zynq: Switch to flexible array to simplify code + - mailbox: zynqmp: Fix counts of child nodes + - dm verity: skip redundant verity_handle_err() on I/O errors + - dm verity: fix error handling for check_at_most_once on FEC + - crypto: inside-secure - irq balance + - crypto: safexcel - Cleanup ring IRQ workqueues on load failure + - net/ncsi: clear Tx enable mode when handling a Config required AEN + - net/sched: cls_api: remove block_cb from driver_list before freeing + - sit: update dev->needed_headroom in ipip6_tunnel_bind_dev() + - net: dsa: mv88e6xxx: add mv88e6321 rsvd2cpu + - writeback: fix call of incorrect macro + - net/sched: act_mirred: Add carrier check + - rxrpc: Fix hard call timeout units + - ionic: remove noise from ethtool rxnfc error msg + - af_packet: Don't send zero-byte data in packet_sendmsg_spkt(). + - drm/amdgpu: add a missing lock for AMDGPU_SCHED + - ALSA: caiaq: input: Add error handling for unsupported input methods in + `snd_usb_caiaq_input_init` + - net: dsa: mt7530: fix corrupt frames using trgmii on 40 MHz XTAL MT7621 + - virtio_net: split free_unused_bufs() + - virtio_net: suppress cpu stall when free_unused_bufs + - perf vendor events power9: Remove UTF-8 characters from JSON files + - perf map: Delete two variable initialisations before null pointer checks in + sort__sym_from_cmp() + - perf symbols: Fix return incorrect build_id size in elf_read_build_id() + - btrfs: fix btrfs_prev_leaf() to not return the same key twice + - btrfs: don't free qgroup space unless specified + - btrfs: print-tree: parent bytenr must be aligned to sector size + - cifs: fix pcchunk length type in smb2_copychunk_range + - platform/x86: touchscreen_dmi: Add info for the Dexp Ursus KX210i + - inotify: Avoid reporting event with invalid wd + - sh: math-emu: fix macro redefined warning + - sh: init: use OF_EARLY_FLATTREE for early init + - sh: nmi_debug: fix return value of __setup handler + - remoteproc: stm32: Call of_node_put() on iteration error + - remoteproc: st: Call of_node_put() on iteration error + - ARM: dts: exynos: fix WM8960 clock name in Itop Elite + - ARM: dts: s5pv210: correct MIPI CSIS clock name + - f2fs: fix potential corruption when moving a directory + - drm/panel: otm8009a: Set backlight parent to panel device + - drm/amdgpu: fix an amdgpu_irq_put() issue in gmc_v9_0_hw_fini() + - drm/amdgpu/gfx: disable gfx9 cp_ecc_error_irq only when enabling legacy gfx + ras + - drm/amdgpu: disable sdma ecc irq only when sdma RAS is enabled in suspend + - HID: wacom: Set a default resolution for older tablets + - HID: wacom: insert timestamp to packed Bluetooth (BT) events + - ext4: fix WARNING in mb_find_extent + - ext4: avoid a potential slab-out-of-bounds in ext4_group_desc_csum + - ext4: fix data races when using cached status extents + - ext4: improve error recovery code paths in __ext4_remount() + - ext4: fix deadlock when converting an inline directory in nojournal mode + - ext4: add bounds checking in get_max_inline_xattr_value_size() + - ext4: bail out of ext4_xattr_ibody_get() fails for any reason + - ext4: remove a BUG_ON in ext4_mb_release_group_pa() + - ext4: fix invalid free tracking in ext4_xattr_move_to_block() + - tty: Prevent writing chars during tcsetattr TCSADRAIN/FLUSH + - serial: 8250: Fix serial8250_tx_empty() race with DMA Tx + - drbd: correctly submit flush bio on barrier + - PCI: pciehp: Use down_read/write_nested(reset_lock) to fix lockdep errors + - PCI: pciehp: Fix AB-BA deadlock between reset_lock and device_lock + - printk: declare printk_deferred_{enter,safe}() in include/linux/printk.h + - PM: domains: Restore comment indentation for generic_pm_domain.child_links + - drm/msm: Fix double pm_runtime_disable() call + - firmware: raspberrypi: fix possible memory leak in rpi_firmware_probe() + - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup() + - drm/exynos: move to use request_irq by IRQF_NO_AUTOEN flag + - mm/page_alloc: fix potential deadlock on zonelist_update_seq seqlock + - drm/amd/display: Fix hang when skipping modeset + - Linux 5.4.243 + - Upstream stable to v5.4.243 + * Focal update: v5.4.243 upstream stable release (LP: #2025387) // + CVE-2023-2269 + - dm ioctl: fix nested locking in table_clear() to remove deadlock concern + * Focal update: v5.4.242 upstream stable release (LP: #2025094) + - ARM: dts: rockchip: fix a typo error for rk3288 spdif node + - arm64: dts: meson-g12-common: specify full DMC range + - netfilter: br_netfilter: fix recent physdev match breakage + - regulator: fan53555: Explicitly include bits header + - virtio_net: bugfix overflow inside xdp_linearize_page() + - netfilter: nf_tables: fix ifdef to also consider nf_tables=m + - i40e: fix accessing vsi->active_filters without holding lock + - i40e: fix i40e_setup_misc_vector() error handling + - mlxfw: fix null-ptr-deref in mlxfw_mfa2_tlv_next() + - bpf: Fix incorrect verifier pruning due to missing register precision taints + - e1000e: Disable TSO on i219-LM card to increase speed + - f2fs: Fix f2fs_truncate_partial_nodes ftrace event + - Input: i8042 - add quirk for Fujitsu Lifebook A574/H + - selftests: sigaltstack: fix -Wuninitialized + - scsi: megaraid_sas: Fix fw_crash_buffer_show() + - scsi: core: Improve scsi_vpd_inquiry() checks + - net: dsa: b53: mmap: add phy ops + - s390/ptrace: fix PTRACE_GET_LAST_BREAK error handling + - nvme-tcp: fix a possible UAF when failing to allocate an io queue + - xen/netback: use same error messages for same errors + - iio: light: tsl2772: fix reading proximity-diodes from device tree + - nilfs2: initialize unused bytes in segment summary blocks + - memstick: fix memory leak if card device is never registered + - mmc: sdhci_am654: Set HIGH_SPEED_ENA for SDR12 and SDR25 + - MIPS: Define RUNTIME_DISCARD_EXIT in LD script + - x86/purgatory: Don't generate debug info for purgatory.ro + - Revert "ext4: fix use-after-free in ext4_xattr_set_entry" + - ext4: remove duplicate definition of ext4_xattr_ibody_inline_set() + - ext4: fix use-after-free in ext4_xattr_set_entry + - udp: Call inet6_destroy_sock() in setsockopt(IPV6_ADDRFORM). + - tcp/udp: Call inet6_destroy_sock() in IPv6 sk->sk_destruct(). + - inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy(). + - dccp: Call inet6_destroy_sock() via sk->sk_destruct(). + - sctp: Call inet6_destroy_sock() via sk->sk_destruct(). + - xfs: fix forkoff miscalculation related to XFS_LITINO(mp) + - pwm: meson: Explicitly set .polarity in .get_state() + - iio: adc: at91-sama5d2_adc: fix an error code in at91_adc_allocate_trigger() + - ASN.1: Fix check for strdup() success + - Linux 5.4.242 + - Upstream stable to v5.4.242 + * CVE-2023-31084 // CVE-2023-31084 was assigned to this bug. + - media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() + * CVE-2023-3776 + - net/sched: cls_fw: Fix improper refcount update leads to use-after-free + * CVE-2023-3268 + - kernel/relay.c: fix read_pos error when multiple readers + - relayfs: fix out-of-bounds access in relay_file_read + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] resync getabis + + -- Joseph Salisbury Fri, 18 Aug 2023 11:45:53 -0400 + +linux-oracle (5.4.0-1107.116) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1107.116 -proposed tracker (LP: #2030624) + + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - [Packaging] resync getabis + + * Miscellaneous Ubuntu changes + - [Config] oracle: updateconfigs + + [ Ubuntu: 5.4.0-159.176 ] + + * focal/linux: 5.4.0-159.176 -proposed tracker (LP: #2031149) + * libgnutls report "trap invalid opcode" when trying to install packages over + https (LP: #2031093) + - [Config]: disable CONFIG_GDS_FORCE_MITIGATION + * Fix boot test warning for log_check "CPU: 0 PID: 0 at + arch/x86/kernel/fpu/xstate.c:878 get_xsave_addr+0x98/0xb0" (LP: #2031022) + - x86/pkeys: Revert a5eff7259790 ("x86/pkeys: Add PKRU value to init_fpstate") + + [ Ubuntu: 5.4.0-157.174 ] + + * focal/linux: 5.4.0-157.174 -proposed tracker (LP: #2030632) + * CVE-2022-40982 + - x86/mm: Initialize text poking earlier + - x86/mm: fix poking_init() for Xen PV guests + - x86/mm: Use mm_alloc() in poking_init() + - mm: Move mm_cachep initialization to mm_init() + - init: Provide arch_cpu_finalize_init() + - x86/cpu: Switch to arch_cpu_finalize_init() + - ARM: cpu: Switch to arch_cpu_finalize_init() + - sparc/cpu: Switch to arch_cpu_finalize_init() + - um/cpu: Switch to arch_cpu_finalize_init() + - init: Remove check_bugs() leftovers + - init: Invoke arch_cpu_finalize_init() earlier + - init, x86: Move mem_encrypt_init() into arch_cpu_finalize_init() + - x86/fpu: Remove cpuinfo argument from init functions + - x86/fpu: Mark init functions __init + - x86/fpu: Move FPU initialization into arch_cpu_finalize_init() + - x86/xen: Fix secondary processors' FPU initialization + - x86/speculation: Add Gather Data Sampling mitigation + - x86/speculation: Add force option to GDS mitigation + - x86/speculation: Add Kconfig option for GDS + - KVM: Add GDS_NO support to KVM + - Documentation/x86: Fix backwards on/off logic about YMM support + - [Config]: Enable CONFIG_ARCH_HAS_CPU_FINALIZE_INIT and + CONFIG_GDS_FORCE_MITIGATION + * CVE-2023-20593 + - x86/cpu/amd: Move the errata checking functionality up + - x86/cpu/amd: Add a Zenbleed fix + * CVE-2023-3776 + - net/sched: cls_fw: Fix improper refcount update leads to use-after-free + * CVE-2023-3611 + - net/sched: sch_qfq: account for stab overhead in qfq_enqueue + * CVE-2023-3609 + - net/sched: cls_u32: Fix reference counter leak leading to overflow + + -- Joseph Salisbury Tue, 15 Aug 2023 11:43:23 -0400 + +linux-oracle (5.4.0-1106.115) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1106.115 -proposed tracker (LP: #2026576) + + [ Ubuntu: 5.4.0-156.173 ] + + * focal/linux: 5.4.0-156.173 -proposed tracker (LP: #2026585) + * CVE-2023-3390 + - netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE + * Focal update: v5.4.241 upstream stable release (LP: #2023930) + - scsi: ses: Handle enclosure with just a primary component gracefully + - x86/PCI: Add quirk for AMD XHCI controller that loses MSI-X state in D3hot + - cgroup/cpuset: Wake up cpuset_attach_wq tasks in cpuset_cancel_attach() + - treewide: Replace DECLARE_TASKLET() with DECLARE_TASKLET_OLD() + - smb3: fix problem with null cifs super block with previous patch + - pinctrl: amd: Use irqchip template + - pinctrl: amd: disable and mask interrupts on probe + - pinctrl: amd: Disable and mask interrupts on resume + - pwm: cros-ec: Explicitly set .polarity in .get_state() + - pwm: sprd: Explicitly set .polarity in .get_state() + - wifi: mac80211: fix invalid drv_sta_pre_rcu_remove calls for non-uploaded + sta + - icmp: guard against too small mtu + - net: don't let netpoll invoke NAPI if in xmit context + - sctp: check send stream number after wait_for_sndbuf + - ipv6: Fix an uninit variable access bug in __ip6_make_skb() + - gpio: davinci: Add irq chip flag to skip set wake + - sunrpc: only free unix grouplist after RCU settles + - NFSD: callback request does not use correct credential for AUTH_SYS + - xhci: also avoid the XHCI_ZERO_64B_REGS quirk with a passthrough iommu + - USB: serial: cp210x: add Silicon Labs IFS-USB-DATACABLE IDs + - usb: typec: altmodes/displayport: Fix configure initial pin assignment + - USB: serial: option: add Telit FE990 compositions + - USB: serial: option: add Quectel RM500U-CN modem + - iio: adc: ti-ads7950: Set `can_sleep` flag for GPIO chip + - iio: dac: cio-dac: Fix max DAC write value check for 12-bit + - tty: serial: sh-sci: Fix transmit end interrupt handler + - tty: serial: sh-sci: Fix Rx on RZ/G2L SCI + - tty: serial: fsl_lpuart: avoid checking for transfer complete when + UARTCTRL_SBK is asserted in lpuart32_tx_empty + - nilfs2: fix potential UAF of struct nilfs_sc_info in nilfs_segctor_thread() + - nilfs2: fix sysfs interface lifetime + - ALSA: hda/realtek: Add quirk for Clevo X370SNW + - perf/core: Fix the same task check in perf_event_set_output + - ftrace: Mark get_lock_parent_ip() __always_inline + - can: j1939: j1939_tp_tx_dat_new(): fix out-of-bounds memory access + - tracing: Free error logs of tracing instances + - net_sched: prevent NULL dereference if default qdisc setup failed + - drm/panfrost: Fix the panfrost_mmu_map_fault_addr() error path + - ring-buffer: Fix race while reader and writer are on the same page + - mm/swap: fix swap_info_struct race between swapoff and get_swap_pages() + - irqdomain: Look for existing mapping only once + - irqdomain: Refactor __irq_domain_alloc_irqs() + - irqdomain: Fix mapping-creation race + - Revert "pinctrl: amd: Disable and mask interrupts on resume" + - ALSA: emu10k1: fix capture interrupt handler unlinking + - ALSA: hda/sigmatel: add pin overrides for Intel DP45SG motherboard + - ALSA: i2c/cs8427: fix iec958 mixer control deactivation + - ALSA: firewire-tascam: add missing unwind goto in + snd_tscm_stream_start_duplex() + - ALSA: hda/sigmatel: fix S/PDIF out on Intel D*45* motherboards + - Bluetooth: L2CAP: Fix use-after-free in l2cap_disconnect_{req,rsp} + - Bluetooth: Fix race condition in hidp_session_thread + - btrfs: print checksum type and implementation at mount time + - btrfs: fix fast csum implementation detection + - mtdblock: tolerate corrected bit-flips + - mtd: rawnand: meson: fix bitmask for length in command word + - mtd: rawnand: stm32_fmc2: remove unsupported EDO mode + - niu: Fix missing unwind goto in niu_alloc_channels() + - qlcnic: check pci_reset_function result + - sctp: fix a potential overflow in sctp_ifwdtsn_skip + - RDMA/core: Fix GID entry ref leak when create_ah fails + - udp6: fix potential access to stale information + - net: macb: fix a memory corruption in extended buffer descriptor mode + - power: supply: cros_usbpd: reclassify "default case!" as debug + - i2c: imx-lpi2c: clean rx/tx buffers upon new message + - efi: sysfb_efi: Add quirk for Lenovo Yoga Book X91F/L + - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Book X90F + - verify_pefile: relax wrapper length check + - asymmetric_keys: log on fatal failures in PE/pkcs7 + - ubi: Fix failure attaching when vid_hdr offset equals to (sub)page size + - mtd: ubi: wl: Fix a couple of kernel-doc issues + - ubi: Fix deadlock caused by recursively holding work_sem + - i2c: ocores: generate stop condition after timeout in polling mode + - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits + - coresight-etm4: Fix for() loop drvdata->nr_addr_cmp range bug + - xfs: show the proper user quota options + - xfs: remove the kuid/kgid conversion wrappers + - xfs: add a new xfs_sb_version_has_v3inode helper + - xfs: only check the superblock version for dinode size calculation + - xfs: simplify di_flags2 inheritance in xfs_ialloc + - xfs: simplify a check in xfs_ioctl_setattr_check_cowextsize + - xfs: remove the di_version field from struct icdinode + - xfs: set inode size after creating symlink + - xfs: report corruption only as a regular error + - xfs: shut down the filesystem if we screw up quota reservation + - xfs: consider shutdown in bmapbt cursor delete assert + - xfs: don't reuse busy extents on extent trim + - xfs: force log and push AIL to clear pinned inodes when aborting mount + - Linux 5.4.241 + * [UBUNTU 20.04] [HPS] Kernel panic with "refcount_t: underflow" in mlx5 + driver (LP: #2019011) + - net/mlx5: cmdif, Avoid skipping reclaim pages if FW is not accessible + - net/mlx5: Fix handling of entry refcount when command is not issued to FW + * Disable hv-kvp-daemon if /dev/vmbus/hv_kvp is not present (LP: #2024900) + - [Packaging] disable hv-kvp-daemon if needed + * CVE-2023-35001 + - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval + * CVE-2023-32629 + - ovl: adhere to the vfs_ vs. ovl_do_ conventions for xattrs + * CVE-2023-3141 + - memstick: r592: Fix UAF bug in r592_remove due to race condition + * CVE-2023-3111 + - btrfs: check return value of btrfs_commit_transaction in relocation + - btrfs: unset reloc control if transaction commit fails in + prepare_to_relocate() + * CVE-2023-3090 + - ipvlan:Fix out-of-bounds caused by unclear skb->cb + * CVE-2023-1611 + - btrfs: fix race between quota disable and quota assign ioctls + * CVE-2022-0168 + - cifs: move some variables off the stack in smb2_ioctl_query_info + - cifs: prevent bad output lengths in smb2_ioctl_query_info() + - cifs: fix NULL ptr dereference in smb2_ioctl_query_info() + * CVE-2022-27672 + - x86/speculation: Identify processors vulnerable to SMT RSB predictions + - KVM: x86: Mitigate the cross-thread return address predictions bug + - Documentation/hw-vuln: Add documentation for Cross-Thread Return Predictions + * Severe NFS performance degradation after LP #2003053 (LP: #2022098) + - SAUCE: Make NFS file-access stale cache behaviour opt-in + * Encountering an issue with memcpy_fromio causing failed boot of SEV-enabled + guest (LP: #2020319) + - x86/sev: Unroll string mmio with CC_ATTR_GUEST_UNROLL_STRING_IO + * Focal update: v5.4.240 upstream stable release (LP: #2023601) + - net: tls: fix possible race condition between do_tls_getsockopt_conf() and + do_tls_setsockopt_conf() + - power: supply: da9150: Fix use after free bug in da9150_charger_remove due + to race condition + - iavf: fix inverted Rx hash condition leading to disabled hash + - iavf: fix non-tunneled IPv6 UDP packet type and hashing + - intel/igbvf: free irq on the error path in igbvf_request_msix() + - igbvf: Regard vf reset nack as success + - i2c: imx-lpi2c: check only for enabled interrupt flags + - scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate() + - net: usb: smsc95xx: Limit packet length to skb->len + - qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info + - net: qcom/emac: Fix use after free bug in emac_remove due to race condition + - net/ps3_gelic_net: Fix RX sk_buff length + - net/ps3_gelic_net: Use dma_mapping_error + - keys: Do not cache key in task struct if key is requested from kernel thread + - bpf: Adjust insufficient default bpf_jit_limit + - net/mlx5: Read the TC mapping of all priorities on ETS query + - atm: idt77252: fix kmemleak when rmmod idt77252 + - erspan: do not use skb_mac_header() in ndo_start_xmit() + - net/sonic: use dma_mapping_error() for error check + - nvme-tcp: fix nvme_tcp_term_pdu to match spec + - hvc/xen: prevent concurrent accesses to the shared ring + - net: mdio: thunder: Add missing fwnode_handle_put() + - Bluetooth: btqcomsmd: Fix command timeout after setting BD address + - platform/chrome: cros_ec_chardev: fix kernel data leak from ioctl + - hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs + - scsi: qla2xxx: Perform lockless command completion in abort path + - uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2 + - thunderbolt: Use const qualifier for `ring_interrupt_index` + - riscv: Bump COMMAND_LINE_SIZE value to 1024 + - ca8210: fix mac_len negative array access + - m68k: Only force 030 bus error if PC not in exception table + - selftests/bpf: check that modifier resolves after pointer + - scsi: target: iscsi: Fix an error message in iscsi_check_key() + - scsi: ufs: core: Add soft dependency on governor_simpleondemand + - scsi: lpfc: Avoid usage of list iterator variable after loop + - net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990 + - net: usb: qmi_wwan: add Telit 0x1080 composition + - sh: sanitize the flags on sigreturn + - cifs: empty interface list when server doesn't support query interfaces + - scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR + - usb: gadget: u_audio: don't let userspace block driver unbind + - fsverity: Remove WQ_UNBOUND from fsverity read workqueue + - igb: revert rtnl_lock() that causes deadlock + - dm thin: fix deadlock when swapping to thin device + - usb: cdns3: Fix issue with using incorrect PCI device function + - usb: chipdea: core: fix return -EINVAL if request role is the same with + current role + - usb: chipidea: core: fix possible concurrent when switch role + - wifi: mac80211: fix qos on mesh interfaces + - nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy() + - i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer() + - dm stats: check for and propagate alloc_percpu failure + - dm crypt: add cond_resched() to dmcrypt_write() + - sched/fair: sanitize vruntime of entity being placed + - sched/fair: Sanitize vruntime of entity being migrated + - tun: avoid double free in tun_free_netdev + - ocfs2: fix data corruption after failed write + - fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY + - bus: imx-weim: fix branch condition evaluates to a garbage value + - md: avoid signed overflow in slot_store() + - ALSA: asihpi: check pao in control_message() + - ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set() + - fbdev: tgafb: Fix potential divide by zero + - sched_getaffinity: don't assume 'cpumask_size()' is fully initialized + - fbdev: nvidia: Fix potential divide by zero + - fbdev: intelfb: Fix potential divide by zero + - fbdev: lxfb: Fix potential divide by zero + - fbdev: au1200fb: Fix potential divide by zero + - ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx() + - dma-mapping: drop the dev argument to arch_sync_dma_for_* + - mips: bmips: BCM6358: disable RAC flush for TP1 + - mtd: rawnand: meson: invalidate cache on polling ECC bit + - scsi: megaraid_sas: Fix crash after a double completion + - ptp_qoriq: fix memory leak in probe() + - regulator: fix spelling mistake "Cant" -> "Can't" + - regulator: Handle deferred clk + - net/net_failover: fix txq exceeding warning + - can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write + - s390/vfio-ap: fix memory leak in vfio_ap device driver + - i40e: fix registers dump after run ethtool adapter self test + - bnxt_en: Fix typo in PCI id to device description string mapping + - net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only + - net: mvneta: make tx buffer array agnostic + - pinctrl: ocelot: Fix alt mode for ocelot + - Input: alps - fix compatibility with -funsigned-char + - Input: focaltech - use explicitly signed char type + - cifs: prevent infinite recursion in CIFSGetDFSRefer() + - cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL + - Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table + - xen/netback: don't do grant copy across page boundary + - pinctrl: at91-pio4: fix domain name assignment + - NFSv4: Fix hangs when recovering open state after a server reboot + - ALSA: hda/conexant: Partial revert of a quirk for Lenovo + - ALSA: usb-audio: Fix regression on detection of Roland VS-100 + - drm/etnaviv: fix reference leak when mmaping imported buffer + - btrfs: scan device in non-exclusive mode + - ext4: fix kernel BUG in 'ext4_write_inline_data_end()' + - net_sched: add __rcu annotation to netdev->qdisc + - net: sched: fix race condition in qdisc_graft() + - firmware: arm_scmi: Fix device node validation for mailbox transport + - gfs2: Always check inode size of inline inodes + - Linux 5.4.240 + * Focal update: v5.4.239 upstream stable release (LP: #2023600) + - Linux 5.4.239 + * CVE-2023-2124 + - xfs: verify buffer contents when we skip log replay + * CVE-2020-36691 + - netlink: limit recursion depth in policy validation + * CVE-2022-1184 + - ext4: check if directory block is within i_size + - ext4: fix check for block being out of directory size + * CVE-2022-4269 + - net: sched: extract qstats update code into functions + - net: sched: don't expose action qstats to skb_tc_reinsert() + - net/sched: act_mirred: refactor the handle of xmit + - net: sched: remove unused tcf_result extension + - net/sched: act_mirred: better wording on protection against excessive stack + growth + - act_mirred: use the backlog for nested calls to mirred ingress + * Focal update: v5.4.238 upstream stable release (LP: #2023427) + - ext4: fix cgroup writeback accounting with fs-layer encryption + - xfrm: Allow transport-mode states with AF_UNSPEC selector + - drm/panfrost: Don't sync rpm suspension after mmu flushing + - cifs: Move the in_send statistic to __smb_send_rqst() + - drm/meson: fix 1px pink line on GXM when scaling video overlay + - clk: HI655X: select REGMAP instead of depending on it + - docs: Correct missing "d_" prefix for dentry_operations member + d_weak_revalidate + - scsi: mpt3sas: Fix NULL pointer access in mpt3sas_transport_port_add() + - ALSA: hda - add Intel DG1 PCI and HDMI ids + - ALSA: hda - controller is in GPU on the DG1 + - ALSA: hda: Add Alderlake-S PCI ID and HDMI codec vid + - ALSA: hda: Add Intel DG2 PCI ID and HDMI codec vid + - ALSA: hda: Match only Intel devices with CONTROLLER_IN_GPU() + - netfilter: nft_redir: correct value of inet type `.maxattrs` + - scsi: core: Fix a comment in function scsi_host_dev_release() + - scsi: core: Fix a procfs host directory removal regression + - tcp: tcp_make_synack() can be called from process context + - nfc: pn533: initialize struct pn533_out_arg properly + - ipvlan: Make skb->skb_iif track skb->dev for l3s mode + - i40e: Fix kernel crash during reboot when adapter is in recovery mode + - qed/qed_dev: guard against a possible division by zero + - net: tunnels: annotate lockless accesses to dev->needed_headroom + - net: phy: smsc: bail out in lan87xx_read_status if genphy_read_status fails + - nfc: st-nci: Fix use after free bug in ndlc_remove due to race condition + - net: usb: smsc75xx: Limit packet length to skb->len + - nvmet: avoid potential UAF in nvmet_req_complete() + - block: sunvdc: add check for mdesc_grab() returning NULL + - ipv4: Fix incorrect table ID in IOCTL path + - net: usb: smsc75xx: Move packet length check to prevent kernel panic in + skb_pull + - net/iucv: Fix size of interrupt data + - ethernet: sun: add check for the mdesc_grab() + - hwmon: (adt7475) Display smoothing attributes in correct order + - hwmon: (adt7475) Fix masking of hysteresis registers + - hwmon: (xgene) Fix use after free bug in xgene_hwmon_remove due to race + condition + - hwmon: (ina3221) return prober error code + - media: m5mols: fix off-by-one loop termination error + - mmc: atmel-mci: fix race between stop command and start of next command + - jffs2: correct logic when creating a hole in jffs2_write_begin + - ext4: fail ext4_iget if special inode unallocated + - ext4: fix task hung in ext4_xattr_delete_inode + - drm/amdkfd: Fix an illegal memory access + - sh: intc: Avoid spurious sizeof-pointer-div warning + - ext4: fix possible double unlock when moving a directory + - tty: serial: fsl_lpuart: skip waiting for transmission complete when + UARTCTRL_SBK is asserted + - interconnect: fix mem leak when freeing nodes + - tracing: Check field value in hist_field_name() + - tracing: Make tracepoint lockdep check actually test something + - ftrace: Fix invalid address access in lookup_rec() when index is 0 + - fbdev: stifb: Provide valid pixelclock and add fb_check_var() checks + - x86/mm: Fix use of uninitialized buffer in sme_enable() + - drm/i915: Don't use stolen memory for ring buffers with LLC + - serial: 8250_em: Fix UART port type + - s390/ipl: add missing intersection check to ipl_report handling + - PCI: Unify delay handling for reset and resume + - HID: core: Provide new max_buffer_size attribute to over-ride the default + - HID: uhid: Over-ride the default maximum data buffer value with our own + - Linux 5.4.238 + * Focal update: v5.4.237 upstream stable release (LP: #2023420) + - fs: prevent out-of-bounds array speculation when closing a file descriptor + - x86/CPU/AMD: Disable XSAVES on AMD family 0x17 + - drm/connector: print max_requested_bpc in state debugfs + - ext4: fix RENAME_WHITEOUT handling for inline directories + - ext4: fix another off-by-one fsmap error on 1k block filesystems + - ext4: move where set the MAY_INLINE_DATA flag is set + - ext4: fix WARNING in ext4_update_inline_data + - ext4: zero i_disksize when initializing the bootloader inode + - nfc: change order inside nfc_se_io error path + - iommu/amd: Add PCI segment support for ivrs_[ioapic/hpet/acpihid] commands + - iommu/amd: Fix ill-formed ivrs_ioapic, ivrs_hpet and ivrs_acpihid options + - iommu/amd: Add a length limitation for the ivrs_acpihid command-line + parameter + - ipmi:ssif: make ssif_i2c_send() void + - ipmi:ssif: resend_msg() cannot fail + - ipmi:ssif: Remove rtc_us_timer + - ipmi:ssif: Increase the message retry time + - ipmi:ssif: Add a timer between request retries + - irqdomain: Change the type of 'size' in __irq_domain_add() to be consistent + - irqdomain: Fix domain registration race + - iommu/vt-d: Fix PASID directory pointer coherency + - SMB3: Backup intent flag missing from some more ops + - cifs: Fix uninitialized memory read in smb3_qfs_tcon() + - scsi: core: Remove the /proc/scsi/${proc_name} directory earlier + - ext4: Fix possible corruption when moving a directory + - drm/msm/a5xx: fix setting of the CP_PREEMPT_ENABLE_LOCAL register + - nfc: fdp: add null check of devm_kmalloc_array in + fdp_nci_i2c_read_device_properties + - ila: do not generate empty messages in ila_xlat_nl_cmd_get_mapping() + - selftests: nft_nat: ensuring the listening side is up before starting the + client + - net: usb: lan78xx: Remove lots of set but unused 'ret' variables + - net: lan78xx: fix accessing the LAN7800's internal phy specific registers + from the MAC driver + - net: caif: Fix use-after-free in cfusbl_device_notify() + - bnxt_en: Avoid order-5 memory allocation for TPA data + - netfilter: tproxy: fix deadlock due to missing BH disable + - btf: fix resolving BTF_KIND_VAR after ARRAY, STRUCT, UNION, PTR + - scsi: megaraid_sas: Update max supported LD IDs to 240 + - net/smc: fix fallback failed while sendmsg with fastopen + - riscv: Use READ_ONCE_NOCHECK in imprecise unwinding stack mode + - ext4: Fix deadlock during directory rename + - MIPS: Fix a compilation issue + - alpha: fix R_ALPHA_LITERAL reloc for large modules + - macintosh: windfarm: Use unsigned type for 1-bit bitfields + - PCI: Add SolidRun vendor ID + - media: ov5640: Fix analogue gain control + - ipmi/watchdog: replace atomic_add() and atomic_sub() + - ipmi:watchdog: Set panic count to proper value on a panic + - drm/i915: Don't use BAR mappings for ring buffers with LLC + - x86, vmlinux.lds: Add RUNTIME_DISCARD_EXIT to generic DISCARDS + - arch: fix broken BuildID for arm64 and riscv + - powerpc/vmlinux.lds: Define RUNTIME_DISCARD_EXIT + - powerpc/vmlinux.lds: Don't discard .rela* for relocatable builds + - s390: define RUNTIME_DISCARD_EXIT to fix link error with GNU ld < 2.36 + - sh: define RUNTIME_DISCARD_EXIT + - UML: define RUNTIME_DISCARD_EXIT + - s390/dasd: add missing discipline function + - Linux 5.4.237 + * Focal update: v5.4.236 upstream stable release (LP: #2020390) + - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script + - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh + - Linux 5.4.236 + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + + -- Joseph Salisbury Thu, 13 Jul 2023 17:00:29 -0400 + +linux-oracle (5.4.0-1105.114) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1105.114 -proposed tracker (LP: #2026392) + + [ Ubuntu: 5.4.0-155.172 ] + + * focal/linux: 5.4.0-155.172 -proposed tracker (LP: #2026401) + * CVE-2023-3390 + - netfilter: nf_tables: incorrect error path handling with NFT_MSG_NEWRULE + * CVE-2023-35001 + - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval + * CVE-2023-32629 + - ovl: adhere to the vfs_ vs. ovl_do_ conventions for xattrs + * CVE-2023-3090 + - ipvlan:Fix out-of-bounds caused by unclear skb->cb + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + + -- Joseph Salisbury Tue, 11 Jul 2023 15:12:47 -0400 + +linux-oracle (5.4.0-1104.113) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1104.113 -proposed tracker (LP: #2024099) + + [ Ubuntu: 5.4.0-153.170 ] + + * focal/linux: 5.4.0-153.170 -proposed tracker (LP: #2024108) + * cls_flower: off-by-one in fl_set_geneve_opt (LP: #2023577) + - net/sched: flower: fix possible OOB write in fl_set_geneve_opt() + * Some INVLPG implementations can leave Global translations unflushed when + PCIDs are enabled (LP: #2023220) + - x86/mm: Avoid incomplete Global INVLPG flushes + + [ Ubuntu: 5.4.0-152.169 ] + + * focal/linux: 5.4.0-152.169 -proposed tracker (LP: #2023070) + * Focal update: v5.4.236 upstream stable release (LP: #2020390) + - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext" + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync getabis + + -- Joseph Salisbury Tue, 20 Jun 2023 14:48:46 -0400 + +linux-oracle (5.4.0-1103.112) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1103.112 -proposed tracker (LP: #2019365) + + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.4.0-151.168 ] + + * focal/linux: 5.4.0-151.168 -proposed tracker (LP: #2019375) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - debian/dkms-versions -- update from kernel-versions (main/2023.05.15) + * CVE-2023-32233 + - netfilter: nf_tables: deactivate anonymous set from preparation phase + * CVE-2023-2612 + - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object() + * CVE-2023-31436 + - net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg + * CVE-2023-1380 + - wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies() + * Focal update: Focal update: v5.4.235 upstream stable release (LP: #2017706) + - HID: asus: Remove check for same LED brightness on set + - HID: asus: use spinlock to protect concurrent accesses + - HID: asus: use spinlock to safely schedule workers + - ARM: OMAP2+: Fix memory leak in realtime_counter_init() + - arm64: dts: qcom: qcs404: use symbol names for PCIe resets + - ARM: zynq: Fix refcount leak in zynq_early_slcr_init + - arm64: dts: meson-gx: Fix Ethernet MAC address unit name + - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name + - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address + - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards + - ARM: OMAP1: call platform_device_put() in error case in + omap1_dm_timer_init() + - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato + - ARM: imx: Call ida_simple_remove() for ida_simple_get + - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name + - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible + - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name + - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node + name + - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name + - ARM: dts: imx7s: correct iomuxc gpr mux controller cells + - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node + - Revert "scsi: core: run queue if SCSI device queue isn't ready and queue is + idle" + - block: Limit number of items taken from the I/O scheduler in one go + - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx + - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait + - blk-mq: correct stale comment of .get_budget + - s390/dasd: Prepare for additional path event handling + - s390/dasd: Fix potential memleak in dasd_eckd_init() + - sched/deadline,rt: Remove unused parameter from pick_next_[rt|dl]_entity() + - sched/rt: pick_next_rt_entity(): check list_entry + - block: bio-integrity: Copy flags when bio_integrity_payload is cloned + - wifi: rsi: Fix memory leak in rsi_coex_attach() + - net/wireless: Delete unnecessary checks before the macro call + “dev_kfree_skb” + - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: libertas: fix memory leak in lbs_init_adapter() + - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave() + - rtlwifi: fix -Wpointer-sign warning + - wifi: rtlwifi: Fix global-out-of-bounds bug in + _rtl8812ae_phy_set_txpower_limit() + - ipw2x00: switch from 'pci_' to 'dma_' API + - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave() + - wifi: ipw2200: fix memory leak in ipw_wdev_init() + - wilc1000: let wilc_mac_xmit() return NETDEV_TX_OK + - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit() + - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit() + - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid() + - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave() + - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave() + - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave() + - crypto: x86/ghash - fix unaligned access in ghash_setkey() + - ACPICA: Drop port I/O validation for some regions + - genirq: Fix the return type of kstat_cpu_irqs_sum() + - lib/mpi: Fix buffer overrun when SG is too long + - ACPICA: nsrepair: handle cases without a return value correctly + - wifi: orinoco: check return value of hermes_write_wordrec() + - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback + function + - ath9k: hif_usb: simplify if-if to if-else + - ath9k: htc: clean up statistics macros + - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails + - wifi: ath9k: Fix potential stack-out-of-bounds write in + ath9k_wmi_rsp_callback() + - ACPI: battery: Fix missing NUL-termination with large strings + - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename + - crypto: essiv - remove redundant null pointer check before kfree + - crypto: essiv - Handle EBUSY correctly + - crypto: seqiv - Handle EBUSY correctly + - powercap: fix possible name leak in powercap_register_zone() + - net/mlx5: Enhance debug print in page allocation failure + - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains + - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe + - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe + - mptcp: add sk_stop_timer_sync helper + - net: add sock_init_data_uid() + - tun: tun_chr_open(): correctly initialize socket uid + - tap: tap_open(): correctly initialize socket uid + - OPP: fix error checking in opp_migrate_dentry() + - Bluetooth: L2CAP: Fix potential user-after-free + - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg() + - rds: rds_rm_zerocopy_callback() correct order for list_add_tail() + - crypto: rsa-pkcs1pad - Use akcipher_request_complete + - m68k: /proc/hardware should depend on PROC_FS + - RISC-V: time: initialize hrtimer based broadcast clock event device + - usb: gadget: udc: Avoid tasklet passing a global + - wifi: iwl3945: Add missing check for create_singlethread_workqueue + - wifi: iwl4965: Add missing check for create_singlethread_workqueue() + - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize() + - crypto: crypto4xx - Call dma_unmap_page when done + - wifi: mac80211: make rate u32 in sta_set_rate_info_rx() + - thermal/drivers/hisi: Drop second sensor hi3660 + - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a + bus error + - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts + - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts + - selftests/net: Interpret UDP_GRO cmsg data as an int value + - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats + - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC + - drm/bridge: megachips: Fix error handling in i2c_register_driver() + - drm/vc4: dpi: Add option for inverting pixel clock and output enable + - drm/vc4: dpi: Fix format mapping for RGB565 + - gpu: ipu-v3: common: Add of_node_put() for reference returned by + of_graph_get_port_by_id() + - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue + - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain + - ASoC: fsl_sai: initialize is_dsp_mode flag + - ALSA: hda/ca0132: minor fix for allocation size + - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness + - drm/msm: use strscpy instead of strncpy + - drm/msm/dpu: Add check for cstate + - drm/msm/dpu: Add check for pstates + - drm/exynos: Don't reset bridge->next + - drm/bridge: Rename bridge helpers targeting a bridge chain + - drm/bridge: Introduce drm_bridge_get_next_bridge() + - drm: Initialize struct drm_crtc_state.no_vblank from device settings + - drm/msm/mdp5: Add check for kzalloc + - gpu: host1x: Don't skip assigning syncpoints to channels + - drm/mediatek: remove cast to pointers passed to kfree + - drm/mediatek: Use NULL instead of 0 for NULL pointer + - drm/mediatek: Drop unbalanced obj unref + - drm/mediatek: Clean dangling pointer on bind error path + - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress() + - gpio: vf610: connect GPIO label to dev name + - hwmon: (ltc2945) Handle error case in ltc2945_value_store + - scsi: aic94xx: Add missing check for dma_map_single() + - spi: bcm63xx-hsspi: fix pm_runtime + - spi: bcm63xx-hsspi: Fix multi-bit mode setting + - hwmon: (mlxreg-fan) Return zero speed for broken fan + - dm: remove flush_scheduled_work() during local_exit() + - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one() + - ASoC: dapm: declare missing structure prototypes + - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared + - HID: bigben: use spinlock to protect concurrent accesses + - HID: bigben_worker() remove unneeded check on report_field + - HID: bigben: use spinlock to safely schedule workers + - HID: asus: Only set EV_REP if we are adding a mapping + - HID: asus: Add report_size to struct asus_touchpad_info + - HID: asus: Add support for multi-touch touchpad on Medion Akoya E1239T + - HID: asus: Fix mute and touchpad-toggle keys on Medion Akoya E1239T + - hid: bigben_probe(): validate report count + - nfsd: fix race to check ls_layouts + - cifs: Fix lost destroy smbd connection when MR allocate failed + - cifs: Fix warning and UAF when destroy the MR list + - gfs2: jdata writepage fix + - perf llvm: Fix inadvertent file creation + - perf tools: Fix auto-complete on aarch64 + - sparc: allow PM configs for sparc32 COMPILE_TEST + - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read() + - clk: qcom: gcc-qcs404: disable gpll[04]_out_aux parents + - clk: qcom: gcc-qcs404: fix names of the DSI clocks used as parents + - mtd: rawnand: sunxi: Fix the size of the last OOB region + - clk: renesas: cpg-mssr: Fix use after free if cpg_mssr_common_init() failed + - clk: renesas: cpg-mssr: Use enum clk_reg_layout instead of a boolean flag + - clk: renesas: cpg-mssr: Remove superfluous check in resume code + - Input: ads7846 - don't report pressure for ads7845 + - Input: ads7846 - don't check penirq immediately for 7845 + - clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX GDSC + - powerpc/powernv/ioda: Skip unallocated resources when mapping to PE + - clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled() + - powerpc/pseries/lpar: add missing RTAS retry status handling + - powerpc/pseries/lparcfg: add missing RTAS retry status handling + - powerpc/rtas: make all exports GPL + - powerpc/rtas: ensure 4KB alignment for rtas_data_buf + - powerpc/eeh: Small refactor of eeh_handle_normal_event() + - powerpc/eeh: Set channel state after notifying the drivers + - MIPS: SMP-CPS: fix build error when HOTPLUG_CPU not set + - MIPS: vpe-mt: drop physical_memsize + - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers + - media: platform: ti: Add missing check for devm_regulator_get + - powerpc: Remove linker flag from KBUILD_AFLAGS + - media: ov5675: Fix memleak in ov5675_init_controls() + - media: i2c: ov772x: Fix memleak in ov772x_probe() + - media: i2c: ov7670: 0 instead of -EINVAL was returned + - media: usb: siano: Fix use after free bugs caused by do_submit_urb + - rpmsg: glink: Avoid infinite loop on intent for missing channel + - udf: Define EFSCORRUPTED error code + - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy + - blk-iocost: fix divide by 0 error in calc_lcoefs() + - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds() + - rcu: Suppress smp_processor_id() complaint in + synchronize_rcu_expedited_wait() + - thermal: intel: Fix unsigned comparison with less than zero + - timers: Prevent union confusion from unexpected restart_syscall() + - x86/bugs: Reset speculation control settings on init + - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out- + of-bounds + - wifi: mt7601u: fix an integer underflow + - inet: fix fast path in __inet_hash_connect() + - ice: add missing checks for PF vsi type + - ACPI: Don't build ACPICA with '-Os' + - net: bcmgenet: Add a check for oversized packets + - m68k: Check syscall_trace_enter() return code + - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup + - ACPI: video: Fix Lenovo Ideapad Z570 DMI match + - net/mlx5: fw_tracer: Fix debug print + - coda: Avoid partial allocation of sig_inputArgs + - uaccess: Add minimum bounds check on kernel buffer size + - drm/amd/display: Fix potential null-deref in dm_resume + - drm/omap: dsi: Fix excessive stack usage + - HID: Add Mapping for System Microphone Mute + - drm/radeon: free iio for atombios when driver shutdown + - drm/msm/dsi: Add missing check for alloc_ordered_workqueue + - docs/scripts/gdb: add necessary make scripts_gdb step + - ASoC: kirkwood: Iterate over array indexes instead of using pointer math + - regulator: max77802: Bounds check regulator id against opmode + - regulator: s5m8767: Bounds check id indexing into arrays + - hwmon: (coretemp) Simplify platform device handling + - pinctrl: at91: use devm_kasprintf() to avoid potential leaks + - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5 + - dm thin: add cond_resched() to various workqueue loops + - dm cache: add cond_resched() to various workqueue loops + - nfsd: zero out pointers after putting nfsd_files on COPY setup error + - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu + - firmware: coreboot: framebuffer: Ignore reserved pixel color bits + - rtc: pm8xxx: fix set-alarm race + - ipmi_ssif: Rename idle state and check + - s390: discard .interp section + - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler + - s390/kprobes: fix current_kprobe never cleared after kprobes reenter + - ARM: dts: exynos: correct HDMI phy compatible in Exynos4 + - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create + - fs: hfsplus: fix UAF issue in hfsplus_put_super + - f2fs: fix information leak in f2fs_move_inline_dirents() + - f2fs: fix cgroup writeback accounting with fs-layer encryption + - ocfs2: fix defrag path triggering jbd2 ASSERT + - ocfs2: fix non-auto defrag path not working issue + - udf: Truncate added extents on failed expansion + - udf: Do not bother merging very long extents + - udf: Do not update file length for failed writes to inline files + - udf: Preserve link count of system files + - udf: Detect system inodes linked into directory hierarchy + - udf: Fix file corruption when appending just after end of preallocated + extent + - KVM: Destroy target device if coalesced MMIO unregistration fails + - KVM: s390: disable migration mode when dirty tracking is disabled + - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows) + - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown + - x86/reboot: Disable virtualization in an emergency if SVM is supported + - x86/reboot: Disable SVM, not just VMX, when stopping CPUs + - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic + - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe + range + - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter + - x86/microcode/AMD: Add a @cpu parameter to the reloading functions + - x86/microcode/AMD: Fix mixed steppings support + - x86/speculation: Allow enabling STIBP with legacy IBRS + - Documentation/hw-vuln: Document the interaction between IBRS and STIBP + - ima: Align ima_file_mmap() parameters with mmap_file LSM hook + - irqdomain: Fix association race + - irqdomain: Fix disassociation race + - irqdomain: Drop bogus fwspec-mapping error handling + - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls() + - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC + - ext4: optimize ea_inode block expansion + - ext4: refuse to create ea block when umounted + - wifi: rtl8xxxu: Use a longer retry limit of 48 + - wifi: cfg80211: Fix use after free for wext + - thermal: intel: powerclamp: Fix cur_state for multi package system + - dm flakey: fix logic when corrupting a bio + - dm flakey: don't corrupt the zero page + - ARM: dts: exynos: correct TMU phandle in Exynos4 + - ARM: dts: exynos: correct TMU phandle in Odroid XU + - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails + - alpha: fix FEN fault handling + - mips: fix syscall_get_nr + - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind + - mm: memcontrol: deprecate charge moving + - mm/thp: check and bail out if page in deferred queue already + - ktest.pl: Give back console on Ctrt^C on monitor + - ktest.pl: Fix missing "end_monitor" when machine check fails + - ktest.pl: Add RUN_TIMEOUT option with default unlimited + - scsi: qla2xxx: Fix link failure in NPIV environment + - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests + - scsi: qla2xxx: Fix erroneous link down + - scsi: ses: Don't attach if enclosure has no components + - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process() + - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses + - scsi: ses: Fix possible desc_ptr out-of-bounds accesses + - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove() + - PCI/PM: Observe reset delay irrespective of bridge_d3 + - PCI: hotplug: Allow marking devices as disconnected during bind/unbind + - PCI: Avoid FLR for AMD FCH AHCI adapters + - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv + - drm/radeon: Fix eDP for single-display iMac11,2 + - wifi: ath9k: use proper statements in conditionals + - kbuild: Port silent mode detection to future gnu make. + - fs/jfs: fix shift exponent db_agl2size negative + - pwm: sifive: Reduce time the controller lock is held + - pwm: sifive: Always let the first pwm_apply_state succeed + - pwm: stm32-lp: fix the check on arr and cmp registers update + - f2fs: use memcpy_{to,from}_page() where possible + - fs: f2fs: initialize fsdata in pagecache_write() + - um: vector: Fix memory leak in vector_config + - ubi: ensure that VID header offset + VID header size <= alloc, size + - ubifs: Fix build errors as symbol undefined + - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted + - ubifs: Rectify space budget for ubifs_xrename() + - ubifs: Fix wrong dirty space budget for dirty inode + - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1 + - ubifs: Reserve one leb for each journal head while doing budget + - ubi: Fix use-after-free when volume resizing failed + - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume() + - ubifs: Fix memory leak in alloc_wbufs() + - ubi: Fix possible null-ptr-deref in ubi_free_volume() + - ubifs: Re-statistic cleaned znode count if commit failed + - ubifs: dirty_cow_znode: Fix memleak in error handling path + - ubifs: ubifs_writepage: Mark page dirty after writing inode failed + - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show() + - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed + - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list + - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in + error path + - watchdog: Fix kmemleak in watchdog_cdev_register + - watchdog: pcwd_usb: Fix attempting to access uninitialized memory + - netfilter: ctnetlink: fix possible refcount leak in + ctnetlink_create_conntrack() + - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation + - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop + - net: fix __dev_kfree_skb_any() vs drop monitor + - 9p/xen: fix version parsing + - 9p/xen: fix connection sequence + - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv() + - net/mlx5: Geneve, Fix handling of Geneve object id as error code + - nfc: fix memory leak of se_io context in nfc_genl_se_io + - net/sched: act_sample: fix action bind logic + - ARM: dts: spear320-hmi: correct STMPE GPIO compatible + - tcp: tcp_check_req() can be called from process context + - vc_screen: modify vcs_size() handling in vcs_read() + - rtc: sun6i: Make external 32k oscillator optional + - rtc: sun6i: Always export the internal oscillator + - scsi: ipr: Work around fortify-string warning + - thermal: intel: quark_dts: fix error pointer dereference + - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it + - tracing: Add NULL checks for buffer in ring_buffer_free_read_page() + - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3 + - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak + - media: uvcvideo: Handle cameras with invalid descriptors + - media: uvcvideo: Handle errors from calls to usb_string + - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910 + - media: uvcvideo: Silence memcpy() run-time false positive warnings + - staging: emxx_udc: Add checks for dma_alloc_coherent() + - tty: fix out-of-bounds access in tty_driver_lookup_tty() + - tty: serial: fsl_lpuart: disable the CTS when send break signal + - mei: bus-fixup:upon error print return values of send and receive + - tools/iio/iio_utils:fix memory leak + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_status_word() + - iio: accel: mma9551_core: Prevent uninitialized variable in + mma9551_read_config_word() + - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer + math + - USB: ene_usb6250: Allocate enough memory for full object + - usb: uvc: Enumerate valid values for color matching + - kernel/fail_function: fix memory leak with using debugfs_lookup() + - PCI: Add ACS quirk for Wangxun NICs + - phy: rockchip-typec: Fix unsigned comparison with less than zero + - net: tls: avoid hanging tasks on the tx_lock + - x86/resctrl: Apply READ_ONCE/WRITE_ONCE to task_struct.{rmid,closid} + - x86/resctl: fix scheduler confusion with 'current' + - Bluetooth: hci_sock: purge socket queues in the destruct() callback + - SAUCE: Revert "UBUNTU: SAUCE: Fix inet_csk_listen_start after CVE-2023-0461" + - tcp: Fix listen() regression in 5.4.229. + - media: uvcvideo: Provide sync and async uvc_ctrl_status_event + - media: uvcvideo: Fix race condition with usb_kill_urb + - dt-bindings: rtc: sun6i-a31-rtc: Loosen the requirements on the clocks + - Linux 5.4.235 + - [Config] Drop mxsfb for armhf:generic-lpae + * Focal update: v5.4.234 upstream stable release (LP: #2017691) + - arm64: dts: rockchip: drop unused LED mode property from rk3328-roc-cc + - ARM: dts: rockchip: add power-domains property to dp node on rk3288 + - ACPI: NFIT: fix a potential deadlock during NFIT teardown + - btrfs: send: limit number of clones and allocated memory size + - IB/hfi1: Assign npages earlier + - neigh: make sure used and confirmed times are valid + - HID: core: Fix deadloop in hid_apply_multiplier. + - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state + - net: Remove WARN_ON_ONCE(sk->sk_forward_alloc) from sk_stream_kill_queues(). + - vc_screen: don't clobber return value in vcs_read + - dmaengine: sh: rcar-dmac: Check for error num after dma_set_max_seg_size + - USB: serial: option: add support for VW/Skoda "Carstick LTE" + - USB: core: Don't hold device lock while reading the "descriptors" sysfs file + - Linux 5.4.234 + * CVE-2023-30456 + - KVM: nVMX: add missing consistency checks for CR0 and CR4 + * CVE-2023-1859 + - 9p/xen : Fix use after free bug in xen_9pfs_front_remove due to race + condition + * CVE-2023-1670 + - xirc2ps_cs: Fix use after free bug in xirc2ps_detach + + -- Joseph Salisbury Fri, 26 May 2023 12:39:58 -0400 + +linux-oracle (5.4.0-1102.111) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1102.111 -proposed tracker (LP: #2019672) + + [ Ubuntu: 5.4.0-150.167 ] + + * focal/linux: 5.4.0-150.167 -proposed tracker (LP: #2019682) + * CVE-2023-32233 + - netfilter: nf_tables: deactivate anonymous set from preparation phase + * CVE-2023-2612 + - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object() + * CVE-2023-31436 + - net: sched: sch_qfq: prevent slab-out-of-bounds in qfq_activate_agg + * CVE-2023-1380 + - wifi: brcmfmac: slab-out-of-bounds read in brcmf_get_assoc_ies() + * CVE-2023-30456 + - KVM: nVMX: add missing consistency checks for CR0 and CR4 + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Joseph Salisbury Thu, 18 May 2023 11:32:39 -0400 + +linux-oracle (5.4.0-1101.110) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1101.110 -proposed tracker (LP: #2016580) + + [ Ubuntu: 5.4.0-149.166 ] + + * focal/linux: 5.4.0-149.166 -proposed tracker (LP: #2016591) + * Focal update: v5.4.233 upstream stable release (LP: #2015909) + - dma-mapping: add generic helpers for mapping sgtable objects + - scatterlist: add generic wrappers for iterating over sgtable objects + - drm: etnaviv: fix common struct sg_table related issues + - drm/etnaviv: don't truncate physical page address + - wifi: rtl8xxxu: gen2: Turn on the rate control + - powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G + - random: always mix cycle counter in add_latent_entropy() + - KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception + - can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len + - powerpc: dts: t208x: Disable 10G on MAC1 and MAC2 + - alarmtimer: Prevent starvation by small intervals and SIG_IGN + - drm/i915/gvt: fix double free bug in split_2MB_gtt_entry + - mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh + - uaccess: Add speculation barrier to copy_from_user() + - wifi: mwifiex: Add missing compatible string for SD8787 + - ext4: Fix function prototype mismatch for ext4_feat_ktype + - Revert "net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo + child qdiscs" + - bpf: add missing header file include + - Linux 5.4.233 + * selftest: fib_tests: Always cleanup before exit (LP: #2015956) + - selftest: fib_tests: Always cleanup before exit + * fib_tests.sh in ubuntu_kernel_selftests was skipped silently on Focal + (LP: #2015440) + - selftests: Fix the executable permissions for fib_tests.sh + * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498) + - [Debian] autoreconstruct - fix restoration of execute permissions + * kernel: fix __clear_user() inline assembly constraints (LP: #2013088) + - s390/uaccess: add missing earlyclobber annotations to __clear_user() + * i/o error if next unused loop device is queried (LP: #1856871) + - loop: fix I/O error on fsync() in detached loop devices + * CVE-2023-1075 + - net/tls: tls_is_tx_ready() checked list_entry + * Focal update: v5.4.232 upstream stable release (LP: #2011625) + - firewire: fix memory leak for payload of request subaction to IEC 61883-1 + FCP region + - bus: sunxi-rsb: Fix error handling in sunxi_rsb_init() + - ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use + - ALSA: hda/via: Avoid potential array out-of-bound in add_secret_dac_path() + - arm64: dts: imx8mm: Fix pad control for UART1_DTE_RX + - scsi: Revert "scsi: core: map PQ=1, PDT=other values to + SCSI_SCAN_TARGET_PRESENT" + - WRITE is "data source", not destination... + - fix iov_iter_bvec() "direction" argument + - fix "direction" argument of iov_iter_kvec() + - netrom: Fix use-after-free caused by accept on already connected socket + - netfilter: br_netfilter: disable sabotage_in hook after first suppression + - squashfs: harden sanity check in squashfs_read_xattr_id_table + - net: phy: meson-gxl: Add generic dummy stubs for MMD register access + - can: j1939: fix errant WARN_ON_ONCE in j1939_session_deactivate + - ata: libata: Fix sata_down_spd_limit() when no link speed is reported + - selftests: net: udpgso_bench_rx: Fix 'used uninitialized' compiler warning + - selftests: net: udpgso_bench_rx/tx: Stop when wrong CLI args are provided + - selftests: net: udpgso_bench_tx: Cater for pending datagrams zerocopy + benchmarking + - virtio-net: Keep stop() to follow mirror sequence of open() + - net: openvswitch: fix flow memory leak in ovs_flow_cmd_new + - efi: fix potential NULL deref in efi_mem_reserve_persistent + - scsi: target: core: Fix warning on RT kernels + - scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress + - i2c: rk3x: fix a bunch of kernel-doc warnings + - net/x25: Fix to not accept on connected socket + - iio: adc: stm32-dfsdm: fill module aliases + - usb: dwc3: dwc3-qcom: Fix typo in the dwc3 vbus override API + - usb: dwc3: qcom: enable vbus override when in OTG dr-mode + - usb: gadget: f_fs: Fix unbalanced spinlock in __ffs_ep0_queue_wait + - vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF + - Input: i8042 - move __initconst to fix code styling warning + - Input: i8042 - merge quirk tables + - Input: i8042 - add TUXEDO devices to i8042 quirk tables + - Input: i8042 - add Clevo PCX0DX to i8042 quirk table + - fbcon: Check font dimension limits + - watchdog: diag288_wdt: do not use stack buffers for hardware data + - watchdog: diag288_wdt: fix __diag288() inline assembly + - efi: Accept version 2 of memory attributes table + - iio: hid: fix the retval in accel_3d_capture_sample + - iio: adc: berlin2-adc: Add missing of_node_put() in error path + - iio:adc:twl6030: Enable measurements of VUSB, VBAT and others + - parisc: Fix return code of pdc_iodc_print() + - parisc: Wire up PTRACE_GETREGS/PTRACE_SETREGS for compat case + - riscv: disable generation of unwind tables + - mm: hugetlb: proc: check for hugetlb shared PMD in /proc/PID/smaps + - fpga: stratix10-soc: Fix return value check in s10_ops_write_init() + - mm/swapfile: add cond_resched() in get_swap_pages() + - Squashfs: fix handling and sanity checking of xattr_ids count + - nvmem: core: fix cell removal on error + - mm: swap: properly update readahead statistics in unuse_pte_range() + - xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() + - serial: 8250_dma: Fix DMA Rx completion race + - serial: 8250_dma: Fix DMA Rx rearm race + - powerpc/imc-pmu: Revert nest_init_lock to being a mutex + - fbdev: smscufx: fix error handling code in ufx_usb_probe + - f2fs: fix to do sanity check on i_extra_isize in is_alive() + - wifi: brcmfmac: Check the count value of channel spec to prevent out-of- + bounds reads + - iio:adc:twl6030: Enable measurement of VAC + - btrfs: limit device extents to the device size + - btrfs: zlib: zero-initialize zlib workspace + - ALSA: emux: Avoid potential array out-of-bound in snd_emux_xg_control() + - tracing: Fix poll() and select() do not work on per_cpu trace_pipe and + trace_pipe_raw + - can: j1939: do not wait 250 ms if the same addr was already claimed + - IB/hfi1: Restore allocated resources on failed copyout + - IB/IPoIB: Fix legacy IPoIB due to wrong number of queues + - iommu: Add gfp parameter to iommu_ops::map + - RDMA/usnic: use iommu_map_atomic() under spin_lock() + - xfrm: fix bug with DSCP copy to v6 from v4 tunnel + - bonding: fix error checking in bond_debug_reregister() + - net: phy: meson-gxl: use MMD access dummy stubs for GXL, internal PHY + - ionic: clean interrupt before enabling queue to avoid credit race + - ice: Do not use WQ_MEM_RECLAIM flag for workqueue + - rds: rds_rm_zerocopy_callback() use list_first_entry() + - selftests: forwarding: lib: quote the sysctl values + - ALSA: pci: lx6464es: fix a debug loop + - pinctrl: aspeed: Fix confusing types in return value + - pinctrl: single: fix potential NULL dereference + - pinctrl: intel: Restore the pins that used to be in Direct IRQ mode + - net: USB: Fix wrong-direction WARNING in plusb.c + - usb: core: add quirk for Alcor Link AK9563 smartcard reader + - usb: typec: altmodes/displayport: Fix probe pin assign check + - ceph: flush cap releases when the session is flushed + - riscv: Fixup race condition on PG_dcache_clean in flush_icache_pte + - arm64: dts: meson-gx: Make mmc host controller interrupts level-sensitive + - arm64: dts: meson-g12-common: Make mmc host controller interrupts level- + sensitive + - arm64: dts: meson-axg: Make mmc host controller interrupts level-sensitive + - nvme-pci: Move enumeration by class to be last in the table + - bpf: Always return target ifindex in bpf_fib_lookup + - migrate: hugetlb: check for hugetlb shared PMD in node migration + - selftests/bpf: Verify copy_register_state() preserves parent/live fields + - ASoC: cs42l56: fix DT probe + - tools/virtio: fix the vringh test for virtio ring changes + - net/rose: Fix to not accept on connected socket + - net: stmmac: do not stop RX_CLK in Rx LPI state for qcs404 SoC + - net: sched: sch: Bounds check priority + - s390/decompressor: specify __decompress() buf len to avoid overflow + - nvme-fc: fix a missing queue put in nvmet_fc_ls_create_association + - aio: fix mremap after fork null-deref + - btrfs: free device in btrfs_close_devices for a single device filesystem + - netfilter: nft_tproxy: restrict to prerouting hook + - xfs: remove the xfs_efi_log_item_t typedef + - xfs: remove the xfs_efd_log_item_t typedef + - xfs: remove the xfs_inode_log_item_t typedef + - xfs: factor out a xfs_defer_create_intent helper + - xfs: merge the ->log_item defer op into ->create_intent + - xfs: merge the ->diff_items defer op into ->create_intent + - xfs: turn dfp_intent into a xfs_log_item + - xfs: refactor xfs_defer_finish_noroll + - xfs: log new intent items created as part of finishing recovered intent + items + - xfs: fix finobt btree block recovery ordering + - xfs: proper replay of deferred ops queued during log recovery + - xfs: xfs_defer_capture should absorb remaining block reservations + - xfs: xfs_defer_capture should absorb remaining transaction reservation + - xfs: clean up bmap intent item recovery checking + - xfs: clean up xfs_bui_item_recover iget/trans_alloc/ilock ordering + - xfs: fix an incore inode UAF in xfs_bui_recover + - xfs: change the order in which child and parent defer ops are finished + - xfs: periodically relog deferred intent items + - xfs: expose the log push threshold + - xfs: only relog deferred intent items if free space in the log gets low + - xfs: fix missing CoW blocks writeback conversion retry + - xfs: ensure inobt record walks always make forward progress + - xfs: fix the forward progress assertion in xfs_iwalk_run_callbacks + - xfs: prevent UAF in xfs_log_item_in_current_chkpt + - xfs: sync lazy sb accounting on quiesce of read-only mounts + - Revert "ipv4: Fix incorrect route flushing when source address is deleted" + - ipv4: Fix incorrect route flushing when source address is deleted + - mmc: sdio: fix possible resource leaks in some error paths + - mmc: mmc_spi: fix error handling in mmc_spi_probe() + - ALSA: hda/conexant: add a new hda codec SN6180 + - ALSA: hda/realtek - fixed wrong gpio assigned + - sched/psi: Fix use-after-free in ep_remove_wait_queue() + - hugetlb: check for undefined shift on 32 bit architectures + - Revert "mm: Always release pages to the buddy allocator in + memblock_free_late()." + - net: Fix unwanted sign extension in netdev_stats_to_stats64() + - revert "squashfs: harden sanity check in squashfs_read_xattr_id_table" + - ixgbe: allow to increase MTU to 3K with XDP enabled + - i40e: add double of VLAN header when computing the max MTU + - net: bgmac: fix BCM5358 support by setting correct flags + - sctp: sctp_sock_filter(): avoid list_entry() on possibly empty list + - dccp/tcp: Avoid negative sk_forward_alloc by ipv6_pinfo.pktoptions. + - net/usb: kalmia: Don't pass act_len in usb_bulk_msg error path + - net: stmmac: fix order of dwmac5 FlexPPS parametrization sequence + - bnxt_en: Fix mqprio and XDP ring checking logic + - net: stmmac: Restrict warning on disabling DMA store and fwd mode + - ixgbe: add double of VLAN header when computing the max MTU + - ipv6: Fix datagram socket connection with DSCP. + - ipv6: Fix tcp socket connection with DSCP. + - i40e: Add checking for null for nlmsg_find_attr() + - kvm: initialize all of the kvm_debugregs structure before sending it to + userspace + - nilfs2: fix underflow in second superblock position calculations + - ASoC: SOF: Intel: hda-dai: fix possible stream_tag leak + - net: sched: sch: Fix off by one in htb_activate_prios() + - iommu/amd: Pass gfp flags to iommu_map_page() in amd_iommu_map() + - Linux 5.4.232 + * CVE-2023-1118 + - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim() + + -- Joseph Salisbury Thu, 20 Apr 2023 14:54:45 -0400 + +linux-oracle (5.4.0-1100.109) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1100.109 -proposed tracker (LP: #2016766) + + * CVE-2023-1829 + - [Config]: Make sure CONFIG_NET_CLS_TCINDEX is not available + + [ Ubuntu: 5.4.0-148.165 ] + + * focal/linux: 5.4.0-148.165 -proposed tracker (LP: #2016777) + * CVE-2023-1829 + - net/sched: Retire tcindex classifier + - [Config]: Make sure CONFIG_NET_CLS_TCINDEX is not available + + -- Thadeu Lima de Souza Cascardo Wed, 19 Apr 2023 22:32:58 -0300 + +linux-oracle (5.4.0-1099.108) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1099.108 -proposed tracker (LP: #2011949) + + [ Ubuntu: 5.4.0-147.164 ] + + * focal/linux: 5.4.0-147.164 -proposed tracker (LP: #2011959) + * CVE-2023-26545 + - net: mpls: fix stale pointer if allocation fails during device rename + * CVE-2023-1281 + - rcu: Upgrade rcu_swap_protected() to rcu_replace_pointer() + - net/sched: tcindex: update imperfect hash filters respecting rcu + * Focal update: v5.4.231 upstream stable release (LP: #2011226) + - clk: generalize devm_clk_get() a bit + - clk: Provide new devm_clk helpers for prepared and enabled clocks + - memory: atmel-sdramc: Fix missing clk_disable_unprepare in + atmel_ramc_probe() + - memory: mvebu-devbus: Fix missing clk_disable_unprepare in + mvebu_devbus_probe() + - ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts' + - ARM: imx27: Retrieve the SYSCTRL base address from devicetree + - ARM: imx31: Retrieve the IIM base address from devicetree + - ARM: imx35: Retrieve the IIM base address from devicetree + - ARM: imx: add missing of_node_put() + - HID: intel_ish-hid: Add check for ishtp_dma_tx_map + - EDAC/highbank: Fix memory leak in highbank_mc_probe() + - tomoyo: fix broken dependency on *.conf.default + - RDMA/core: Fix ib block iterator counter overflow + - IB/hfi1: Reject a zero-length user expected buffer + - IB/hfi1: Reserve user expected TIDs + - IB/hfi1: Fix expected receive setup error exit issues + - affs: initialize fsdata in affs_truncate() + - amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent + - amd-xgbe: Delay AN timeout during KR training + - bpf: Fix pointer-leak due to insufficient speculative store bypass + mitigation + - phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in + rockchip_usb2phy_power_on() + - net: nfc: Fix use-after-free in local_cleanup() + - net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs + - gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode + - net/sched: sch_taprio: fix possible use-after-free + - net: fix a concurrency bug in l2tp_tunnel_register() + - l2tp: Serialize access to sk_user_data with sk_callback_lock + - l2tp: Don't sleep and disable BH under writer-side sk_callback_lock + - net: usb: sr9700: Handle negative len + - net: mdio: validate parameter addr in mdiobus_get_phy() + - HID: check empty report_list in hid_validate_values() + - HID: check empty report_list in bigben_probe() + - net: stmmac: fix invalid call to mdiobus_get_phy() + - HID: revert CHERRY_MOUSE_000C quirk + - usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait + - usb: gadget: f_fs: Ensure ep0req is dequeued before free_request + - net: mlx5: eliminate anonymous module_init & module_exit + - drm/panfrost: fix GENERIC_ATOMIC64 dependency + - dmaengine: Fix double increment of client_count in dma_chan_get() + - net: macb: fix PTP TX timestamp failure due to packet padding + - HID: betop: check shape of output reports + - dmaengine: xilinx_dma: use devm_platform_ioremap_resource() + - dmaengine: xilinx_dma: Fix devm_platform_ioremap_resource error handling + - dmaengine: xilinx_dma: call of_node_put() when breaking out of + for_each_child_of_node() + - tcp: avoid the lookup process failing to get sk in ehash table + - w1: fix deadloop in __w1_remove_master_device() + - w1: fix WARNING after calling w1_process() + - driver core: Fix test_async_probe_init saves device in wrong array + - net: dsa: microchip: ksz9477: port map correction in ALU table entry + register + - tcp: fix rate_app_limited to default to 1 + - cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist + - ASoC: fsl_micfil: Correct the number of steps on SX controls + - drm: Add orientation quirk for Lenovo ideapad D330-10IGL + - s390/debug: add _ASM_S390_ prefix to header guard + - cpufreq: armada-37xx: stop using 0 as NULL pointer + - ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97 CODEC + - ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets + - spi: spidev: remove debug messages that access spidev->spi without locking + - KVM: s390: interrupt: use READ_ONCE() before cmpxchg() + - scsi: hisi_sas: Set a port invalid only if there are no devices attached + when refreshing port id + - platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD + - platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK + - lockref: stop doing cpu_relax in the cmpxchg loop + - mmc: sdhci-esdhc-imx: clear pending interrupt and halt cqhci + - mmc: sdhci-esdhc-imx: disable the CMD CRC check for standard tuning + - mmc: sdhci-esdhc-imx: correct the tuning start tap and step setting + - netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state + - fs: reiserfs: remove useless new_opts in reiserfs_remount + - Bluetooth: hci_sync: cancel cmd_timer if hci_open failed + - scsi: hpsa: Fix allocation size for scsi_host_alloc() + - module: Don't wait for GOING modules + - tracing: Make sure trace_printk() can output as soon as it can be used + - trace_events_hist: add check for return value of 'create_hist_field' + - ftrace/scripts: Update the instructions for ftrace-bisect.sh + - cifs: Fix oops due to uncleared server->smbd_conn in reconnect + - KVM: x86/vmx: Do not skip segment attributes if unusable bit is set + - thermal: intel: int340x: Protect trip temperature from concurrent updates + - ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment + - EDAC/device: Respect any driver-supplied workqueue polling value + - EDAC/qcom: Do not pass llcc_driv_data as edac_device_ctl_info's pvt_info + - netlink: prevent potential spectre v1 gadgets + - net: fix UaF in netns ops registration error path + - netfilter: nft_set_rbtree: skip elements in transaction from garbage + collection + - netlink: annotate data races around nlk->portid + - netlink: annotate data races around dst_portid and dst_group + - netlink: annotate data races around sk_state + - ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() + - ipv4: prevent potential spectre v1 gadget in fib_metrics_match() + - netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE + - netrom: Fix use-after-free of a listening socket. + - net/sched: sch_taprio: do not schedule in taprio_reset() + - sctp: fail if no bound addresses can be used for a given scope + - net: ravb: Fix possible hang if RIS2_QFF1 happen + - thermal: intel: int340x: Add locking to int340x_thermal_get_trip_type() + - net/tg3: resolve deadlock in tg3_reset_task() during EEH + - net/phy/mdio-i2c: Move header file to include/linux/mdio + - net: xgene: Move shared header file into include/linux + - net: mdio-mux-meson-g12a: force internal PHY off on mux switch + - Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI + mode" + - nfsd: Ensure knfsd shuts down when the "nfsd" pseudofs is unmounted + - block: fix and cleanup bio_check_ro + - x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL + - netfilter: conntrack: unify established states for SCTP paths + - perf/x86/amd: fix potential integer overflow on shift of a int + - clk: Fix pointer casting to prevent oops in devm_clk_release() + - x86/asm: Fix an assembler warning with current binutils + - ARM: dts: imx: Fix pca9547 i2c-mux node name + - bpf: Skip task with pid=1 in send_signal_common() + - blk-cgroup: fix missing pd_online_fn() while activating policy + - dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init + - sysctl: add a new register_sysctl_init() interface + - panic: unset panic_on_warn inside panic() + - mm: kasan: do not panic if both panic_on_warn and kasan_multishot set + - exit: Add and use make_task_dead. + - objtool: Add a missing comma to avoid string concatenation + - hexagon: Fix function name in die() + - h8300: Fix build errors from do_exit() to make_task_dead() transition + - csky: Fix function name in csky_alignment() and die() + - ia64: make IA64_MCA_RECOVERY bool instead of tristate + - exit: Put an upper limit on how often we can oops + - exit: Expose "oops_count" to sysfs + - exit: Allow oops_limit to be disabled + - panic: Consolidate open-coded panic_on_warn checks + - panic: Introduce warn_limit + - panic: Expose "warn_count" to sysfs + - docs: Fix path paste-o for /sys/kernel/warn_count + - exit: Use READ_ONCE() for all oops/warn limit reads + - ipv6: ensure sane device mtu in tunnels + - Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt + - usb: host: xhci-plat: add wakeup entry at sysfs + - Revert "xprtrdma: Fix regbuf data not freed in rpcrdma_req_create()" + - Linux 5.4.231 + * CVE-2022-3903 + - USB: add usb_control_msg_send() and usb_control_msg_recv() + - USB: correct API of usb_control_msg_send/recv + - USB: move snd_usb_pipe_sanity_check into the USB core + - media: mceusb: Use new usb_control_msg_*() routines + * CVE-2022-3108 + - drm/amdkfd: Check for null pointer after calling kmemdup + * Focal update: v5.4.230 upstream stable release (LP: #2008946) + - pNFS/filelayout: Fix coalescing test for single DS + - net/ethtool/ioctl: return -EOPNOTSUPP if we have no phy stats + - RDMA/srp: Move large values to a new enum for gcc13 + - f2fs: let's avoid panic if extent_tree is not created + - wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices + - Add exception protection processing for vd in axi_chan_handle_err function + - nilfs2: fix general protection fault in nilfs_btree_insert() + - efi: fix userspace infinite retry read efivars after EFI runtime services + page fault + - drm/i915/gt: Reset twice + - ALSA: hda/realtek - Turn on power early + - xhci-pci: set the dma max_seg_size + - usb: xhci: Check endpoint is valid before dereferencing it + - xhci: Fix null pointer dereference when host dies + - xhci: Add update_hub_device override for PCI xHCI hosts + - xhci: Add a flag to disable USB3 lpm on a xhci root port level. + - usb: acpi: add helper to check port lpm capability using acpi _DSM + - xhci: Detect lpm incapable xHC USB3 roothub ports from ACPI tables + - prlimit: do_prlimit needs to have a speculation check + - USB: serial: option: add Quectel EM05-G (GR) modem + - USB: serial: option: add Quectel EM05-G (CS) modem + - USB: serial: option: add Quectel EM05-G (RS) modem + - USB: serial: option: add Quectel EC200U modem + - USB: serial: option: add Quectel EM05CN (SG) modem + - USB: serial: option: add Quectel EM05CN modem + - USB: misc: iowarrior: fix up header size for USB_DEVICE_ID_CODEMERCS_IOW100 + - misc: fastrpc: Don't remove map on creater_process and device_release + - misc: fastrpc: Fix use-after-free race condition for maps + - usb: core: hub: disable autosuspend for TI TUSB8041 + - comedi: adv_pci1760: Fix PWM instruction handling + - mmc: sunxi-mmc: Fix clock refcount imbalance during unbind + - btrfs: fix race between quota rescan and disable leading to NULL pointer + deref + - cifs: do not include page data when checking signature + - USB: serial: cp210x: add SCALANCE LPE-9000 device id + - usb: host: ehci-fsl: Fix module alias + - usb: typec: altmodes/displayport: Add pin assignment helper + - usb: typec: altmodes/displayport: Fix pin assignment calculation + - usb: gadget: g_webcam: Send color matching descriptor per frame + - usb: gadget: f_ncm: fix potential NULL ptr deref in ncm_bitrate() + - usb-storage: apply IGNORE_UAS only for HIKSEMI MD202 on RTL9210 + - dt-bindings: phy: g12a-usb3-pcie-phy: fix compatible string documentation + - serial: pch_uart: Pass correct sg to dma_unmap_sg() + - dmaengine: tegra210-adma: fix global intr clear + - serial: atmel: fix incorrect baudrate setup + - gsmi: fix null-deref in gsmi_get_variable + - drm/i915: re-disable RC6p on Sandy Bridge + - drm/amd/display: Fix set scaling doesn's work + - drm/amd/display: Fix COLOR_SPACE_YCBCR2020_TYPE matrix + - x86/fpu: Use _Alignof to avoid undefined behavior in TYPE_ALIGN + - mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma + - Linux 5.4.230 + + [ Ubuntu: 5.4.0-146.163 ] + + * focal/linux: 5.4.0-146.163 -proposed tracker (LP: #2012094) + * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325) + - NFS: Correct timing for assigning access cache timestamp + + -- Joseph Salisbury Wed, 29 Mar 2023 20:09:30 -0400 + +linux-oracle (5.4.0-1098.107) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1098.107 -proposed tracker (LP: #2009667) + + [ Ubuntu: 5.4.0-145.162 ] + + * focal/linux: 5.4.0-145.162 -proposed tracker (LP: #2008389) + * [SRU]Update ice driver to support E823 devices (LP: #1986717) + - ice: Add device ids for E822 devices + - ice: add support for E823 devices + * btrfs/154: rename fails with EOVERFLOW when calculating item size during + item key collision (LP: #2004132) + - btrfs: correctly calculate item size used when item key collision happens + * rtcpie in timers from ubuntu_kernel_selftests randomly failing + (LP: #1814234) + - SAUCE: selftest: rtcpie: Force passing unreliable subtest + * [UBUNTU 20.04] KVM: s390: pv: don't allow userspace to set the clock under + PV - kernel part (LP: #1999882) + - KVM: s390x: fix SCK locking + - KVM: s390: pv: don't allow userspace to set the clock under PV + * CVE-2021-3669 + - ipc: replace costly bailout check in sysvipc_find_ipc() + * net:fcnal-test.sh 'nettest' command not found on F/K (LP: #2006391) + - selftests/net: Find nettest in current directory + * xfs: Preallocated ioend transactions cause deadlock due to log buffer + exhaustion (LP: #2007219) + - xfs: drop submit side trans alloc for append ioends + * CVE-2022-4382 + - USB: gadgetfs: Fix race between mounting and unmounting + * CVE-2022-2196 + - KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS + * ubuntu_kernel_selftests: net:udpgso_bench.sh failed (LP: #1951447) + - selftests: net: udpgso_bench: Fix racing bug between the rx/tx programs + * net:fcnal-test.sh didn't return a non-zero value even with some sub-tests + failed (LP: #2006692) + - selftests: net/fcnal-test.sh: add exit code + * Fix selftests/ftracetests/Meta-selftests in Focal (LP: #2006453) + - SAUCE: Fix ftrace/Meta-selftests bashism check + * CVE-2023-23559 + - wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid + + -- Khalid Elmously Thu, 16 Mar 2023 22:28:03 -0400 + +linux-oracle (5.4.0-1097.106) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1097.106 -proposed tracker (LP: #2009337) + + * arm64 support (LP: #1925421) + - [config] Enable ARM_SMMU and ARM_SMMU_V3 + + -- Khalid Elmously Wed, 08 Mar 2023 00:29:07 -0500 + +linux-oracle (5.4.0-1094.103) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1094.103 -proposed tracker (LP: #2004376) + + [ Ubuntu: 5.4.0-144.161 ] + + * focal/linux: 5.4.0-144.161 -proposed tracker (LP: #2004653) + * CVE-2023-0461 + - SAUCE: Fix inet_csk_listen_start after CVE-2023-0461 + + [ Ubuntu: 5.4.0-143.160 ] + + * focal/linux: 5.4.0-143.160 -proposed tracker (LP: #2004385) + * NFS: client permission error after adding user to permissible group + (LP: #2003053) + - NFS: Clear the file access cache upon login + - NFS: Judge the file access cache's timestamp in rcu path + - NFS: Fix up a sparse warning + * Focal update: v5.4.229 upstream stable release (LP: #2003914) + - tracing/ring-buffer: Only do full wait when cpu != RING_BUFFER_ALL_CPUS + - udf: Discard preallocation before extending file with a hole + - udf: Fix preallocation discarding at indirect extent boundary + - udf: Do not bother looking for prealloc extents if i_lenExtents matches + i_size + - udf: Fix extending file within last block + - usb: gadget: uvc: Prevent buffer overflow in setup handler + - USB: serial: option: add Quectel EM05-G modem + - USB: serial: cp210x: add Kamstrup RF sniffer PIDs + - USB: serial: f81232: fix division by zero on line-speed change + - USB: serial: f81534: fix division by zero on line-speed change + - igb: Initialize mailbox message for VF reset + - xen-netback: move removal of "hotplug-status" to the right place + - HID: ite: Add support for Acer S1002 keyboard-dock + - HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch 10E + - HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch V 10 + - HID: uclogic: Add HID_QUIRK_HIDINPUT_FORCE quirk + - net: loopback: use NET_NAME_PREDICTABLE for name_assign_type + - usb: musb: remove extra check in musb_gadget_vbus_draw + - ARM: dts: qcom: apq8064: fix coresight compatible + - arm64: dts: qcom: sdm845-cheza: fix AP suspend pin bias + - drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static + - arm: dts: spear600: Fix clcd interrupt + - soc: ti: knav_qmss_queue: Use pm_runtime_resume_and_get instead of + pm_runtime_get_sync + - soc: ti: knav_qmss_queue: Fix PM disable depth imbalance in knav_queue_probe + - soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe + - perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init() + - perf/smmuv3: Fix hotplug callback leak in arm_smmu_pmu_init() + - arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators + - arm64: dts: mt2712e: Fix unit address for pinctrl node + - arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names + - arm64: dts: mt2712-evb: Fix usb vbus regulators unit names + - arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name + - ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port + - ARM: dts: turris-omnia: Add ethernet aliases + - ARM: dts: turris-omnia: Add switch port 6 node + - arm64: dts: armada-3720-turris-mox: Add missing interrupt for RTC + - pstore/ram: Fix error return code in ramoops_probe() + - ARM: mmp: fix timer_read delay + - pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP + - tpm/tpm_crb: Fix error message in __crb_relinquish_locality() + - cpuidle: dt: Return the correct numbers of parsed idle states + - alpha: fix syscall entry in !AUDUT_SYSCALL case + - PM: hibernate: Fix mistake in kerneldoc comment + - fs: don't audit the capability check in simple_xattr_list() + - selftests/ftrace: event_triggers: wait longer for test_event_enable + - perf: Fix possible memleak in pmu_dev_alloc() + - timerqueue: Use rb_entry_safe() in timerqueue_getnext() + - proc: fixup uptime selftest + - lib/fonts: fix undefined behavior in bit shift for get_default_font + - ocfs2: fix memory leak in ocfs2_stack_glue_init() + - MIPS: vpe-mt: fix possible memory leak while module exiting + - MIPS: vpe-cmp: fix possible memory leak while module exiting + - selftests/efivarfs: Add checking of the test return value + - PNP: fix name memory leak in pnp_alloc_dev() + - perf/x86/intel/uncore: Fix reference count leak in hswep_has_limit_sbox() + - irqchip: gic-pm: Use pm_runtime_resume_and_get() in gic_probe() + - EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper() + - nfsd: don't call nfsd_file_put from client states seqfile display + - genirq/irqdesc: Don't try to remove non-existing sysfs files + - cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() + - libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value + - lib/notifier-error-inject: fix error when writing -errno to debugfs file + - docs: fault-injection: fix non-working usage of negative values + - debugfs: fix error when writing negative value to atomic_t debugfs file + - ocfs2: ocfs2_mount_volume does cleanup job before return error + - ocfs2: rewrite error handling of ocfs2_fill_super + - ocfs2: fix memory leak in ocfs2_mount_volume() + - rapidio: fix possible name leaks when rio_add_device() fails + - rapidio: rio: fix possible name leak in rio_register_mport() + - clocksource/drivers/sh_cmt: Make sure channel clock supply is enabled + - ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() + - uprobes/x86: Allow to probe a NOP instruction with 0x66 prefix + - xen/events: only register debug interrupt for 2-level events + - x86/xen: Fix memory leak in xen_smp_intr_init{_pv}() + - x86/xen: Fix memory leak in xen_init_lock_cpu() + - xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource() + - PM: runtime: Improve path in rpm_idle() when no callback + - PM: runtime: Do not call __rpm_callback() from rpm_idle() + - platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]() + - MIPS: BCM63xx: Add check for NULL for clk in clk_enable + - MIPS: OCTEON: warn only once if deprecated link status is being used + - fs: sysv: Fix sysv_nblocks() returns wrong value + - rapidio: fix possible UAF when kfifo_alloc() fails + - eventfd: change int to __u64 in eventfd_signal() ifndef CONFIG_EVENTFD + - relay: fix type mismatch when allocating memory in relay_create_buf() + - hfs: Fix OOB Write in hfs_asc2mac + - rapidio: devices: fix missing put_device in mport_cdev_open + - wifi: ath9k: hif_usb: fix memory leak of urbs in + ath9k_hif_usb_dealloc_tx_urbs() + - wifi: ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb() + - wifi: rtl8xxxu: Fix reading the vendor of combo chips + - pata_ipx4xx_cf: Fix unsigned comparison with less than zero + - media: i2c: ad5820: Fix error path + - can: kvaser_usb: do not increase tx statistics when sending error message + frames + - can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device + - can: kvaser_usb: kvaser_usb_leaf: Rename {leaf,usbcan}_cmd_error_event to + {leaf,usbcan}_cmd_can_error_event + - can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT + - can: kvaser_usb_leaf: Set Warning state even without bus errors + - can: kvaser_usb_leaf: Fix improved state not being reported + - can: kvaser_usb_leaf: Fix wrong CAN state after stopping + - can: kvaser_usb_leaf: Fix bogus restart events + - can: kvaser_usb: Add struct kvaser_usb_busparams + - can: kvaser_usb: Compare requested bittiming parameters with actual + parameters in do_set_{,data}_bittiming + - clk: renesas: r9a06g032: Repair grave increment error + - spi: Update reference to struct spi_controller + - drm/panel/panel-sitronix-st7701: Remove panel on DSI attach failure + - ima: Rename internal filter rule functions + - ima: Fix fall-through warnings for Clang + - ima: Handle -ESTALE returned by ima_filter_rule_match() + - media: vivid: fix compose size exceed boundary + - bpf: propagate precision in ALU/ALU64 operations + - mtd: Fix device name leak when register device failed in add_mtd_device() + - wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port + - media: camss: Clean up received buffers on failed start of streaming + - net, proc: Provide PROC_FS=n fallback for proc_create_net_single_write() + - rxrpc: Fix ack.bufferSize to be 0 when generating an ack + - drm/radeon: Add the missed acpi_put_table() to fix memory leak + - drm/mediatek: Modify dpi power on/off sequence. + - ASoC: pxa: fix null-pointer dereference in filter() + - regulator: core: fix unbalanced of node refcount in regulator_dev_lookup() + - amdgpu/pm: prevent array underflow in vega20_odn_edit_dpm_table() + - integrity: Fix memory leakage in keyring allocation error path + - ima: Fix misuse of dereference of pointer in template_desc_init_fields() + - wifi: ath10k: Fix return value in ath10k_pci_init() + - mtd: lpddr2_nvm: Fix possible null-ptr-deref + - Input: elants_i2c - properly handle the reset GPIO when power is off + - media: solo6x10: fix possible memory leak in solo_sysfs_init() + - media: platform: exynos4-is: Fix error handling in fimc_md_init() + - media: videobuf-dma-contig: use dma_mmap_coherent + - bpf: Move skb->len == 0 checks into __bpf_redirect + - HID: hid-sensor-custom: set fixed size for custom attributes + - ALSA: pcm: fix undefined behavior in bit shift for SNDRV_PCM_RATE_KNOT + - ALSA: seq: fix undefined behavior in bit shift for + SNDRV_SEQ_FILTER_USE_EVENT + - regulator: core: use kfree_const() to free space conditionally + - clk: rockchip: Fix memory leak in rockchip_clk_register_pll() + - bonding: Export skip slave logic to function + - bonding: Rename slave_arr to usable_slaves + - bonding: fix link recovery in mode 2 when updelay is nonzero + - mtd: maps: pxa2xx-flash: fix memory leak in probe + - media: imon: fix a race condition in send_packet() + - clk: imx8mn: correct the usb1_ctrl parent to be usb_bus + - clk: imx: replace osc_hdmi with dummy + - pinctrl: pinconf-generic: add missing of_node_put() + - media: dvb-core: Fix ignored return value in dvb_register_frontend() + - media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer() + - media: s5p-mfc: Add variant data for MFC v7 hardware for Exynos 3250 SoC + - drm/tegra: Add missing clk_disable_unprepare() in tegra_dc_probe() + - ASoC: dt-bindings: wcd9335: fix reset line polarity in example + - ASoC: mediatek: mtk-btcvsd: Add checks for write and read of mtk_btcvsd_snd + - NFSv4.2: Clear FATTR4_WORD2_SECURITY_LABEL when done decoding + - NFSv4.2: Fix a memory stomp in decode_attr_security_label + - NFSv4.2: Fix initialisation of struct nfs4_label + - NFSv4: Fix a deadlock between nfs4_open_recover_helper() and delegreturn + - ALSA: asihpi: fix missing pci_disable_device() + - wifi: iwlwifi: mvm: fix double free on tx path. + - ASoC: mediatek: mt8173: Enable IRQ when pdata is ready + - drm/radeon: Fix PCI device refcount leak in radeon_atrm_get_bios() + - drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios() + - ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe + - netfilter: conntrack: set icmpv6 redirects as RELATED + - bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data + - bpf, sockmap: Fix data loss caused by using apply_bytes on ingress redirect + - bonding: uninitialized variable in bond_miimon_inspect() + - spi: spidev: mask SPI_CS_HIGH in SPI_IOC_RD_MODE + - wifi: cfg80211: Fix not unregister reg_pdev when load_builtin_regdb_keys() + fails + - regulator: core: fix module refcount leak in set_supply() + - clk: qcom: clk-krait: fix wrong div2 functions + - hsr: Avoid double remove of a node. + - configfs: fix possible memory leak in configfs_create_dir() + - regulator: core: fix resource leak in regulator_register() + - bpf, sockmap: fix race in sock_map_free() + - media: saa7164: fix missing pci_disable_device() + - ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt + - xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() + - SUNRPC: Fix missing release socket in rpc_sockname() + - NFSv4.x: Fail client initialisation if state manager thread can't run + - mmc: alcor: fix return value check of mmc_add_host() + - mmc: moxart: fix return value check of mmc_add_host() + - mmc: mxcmmc: fix return value check of mmc_add_host() + - mmc: pxamci: fix return value check of mmc_add_host() + - mmc: rtsx_usb_sdmmc: fix return value check of mmc_add_host() + - mmc: toshsd: fix return value check of mmc_add_host() + - mmc: vub300: fix return value check of mmc_add_host() + - mmc: wmt-sdmmc: fix return value check of mmc_add_host() + - mmc: atmel-mci: fix return value check of mmc_add_host() + - mmc: omap_hsmmc: fix return value check of mmc_add_host() + - mmc: meson-gx: fix return value check of mmc_add_host() + - mmc: via-sdmmc: fix return value check of mmc_add_host() + - mmc: wbsd: fix return value check of mmc_add_host() + - mmc: mmci: fix return value check of mmc_add_host() + - media: c8sectpfe: Add of_node_put() when breaking out of loop + - media: coda: Add check for dcoda_iram_alloc + - media: coda: Add check for kmalloc + - clk: samsung: Fix memory leak in _samsung_clk_register_pll() + - spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode + - wifi: rtl8xxxu: Add __packed to struct rtl8723bu_c2h + - wifi: brcmfmac: Fix error return code in brcmf_sdio_download_firmware() + - blktrace: Fix output non-blktrace event when blk_classic option enabled + - clk: socfpga: clk-pll: Remove unused variable 'rc' + - clk: socfpga: use clk_hw_register for a5/c5 + - clk: socfpga: Fix memory leak in socfpga_gate_init() + - net: vmw_vsock: vmci: Check memcpy_from_msg() + - net: defxx: Fix missing err handling in dfx_init() + - net: stmmac: selftests: fix potential memleak in stmmac_test_arpoffload() + - drivers: net: qlcnic: Fix potential memory leak in qlcnic_sriov_init() + - of: overlay: fix null pointer dereferencing in find_dup_cset_node_entry() + and find_dup_cset_prop() + - ethernet: s2io: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: farsync: Fix kmemleak when rmmods farsync + - net/tunnel: wait until all sk_user_data reader finish before releasing the + sock + - net: apple: mace: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: apple: bmac: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: emaclite: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: ethernet: dnet: don't call dev_kfree_skb() under spin_lock_irqsave() + - hamradio: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: amd: lance: don't call dev_kfree_skb() under spin_lock_irqsave() + - net: amd-xgbe: Fix logic around active and passive cables + - net: amd-xgbe: Check only the minimum speed for active/passive cables + - can: tcan4x5x: Remove invalid write in clear_interrupts + - net: lan9303: Fix read error execution path + - ntb_netdev: Use dev_kfree_skb_any() in interrupt context + - Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() + - Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() + - stmmac: fix potential division by 0 + - apparmor: fix a memleak in multi_transaction_new() + - apparmor: fix lockdep warning when removing a namespace + - apparmor: Fix abi check to include v8 abi + - apparmor: Use pointer to struct aa_label for lbs_cred + - RDMA/core: Fix order of nldev_exit call + - f2fs: fix normal discard process + - RDMA/siw: Fix immediate work request flush to completion queue + - RDMA/nldev: Return "-EAGAIN" if the cm_id isn't from expected port + - RDMA/siw: Set defined status for work completion with undefined status + - scsi: scsi_debug: Fix a warning in resp_write_scat() + - crypto: ccree - swap SHA384 and SHA512 larval hashes at build time + - crypto: ccree - Remove debugfs when platform_driver_register failed + - PCI: Check for alloc failure in pci_request_irq() + - RDMA/hfi: Decrease PCI device reference count in error path + - crypto: ccree - Make cc_debugfs_global_fini() available for module init + function + - RDMA/rxe: Fix NULL-ptr-deref in rxe_qp_do_cleanup() when socket create + failed + - scsi: hpsa: Fix possible memory leak in hpsa_init_one() + - crypto: tcrypt - Fix multibuffer skcipher speed test mem leak + - scsi: mpt3sas: Fix possible resource leaks in mpt3sas_transport_port_add() + - scsi: hpsa: Fix error handling in hpsa_add_sas_host() + - scsi: hpsa: Fix possible memory leak in hpsa_add_sas_device() + - scsi: fcoe: Fix possible name leak when device_register() fails + - scsi: ipr: Fix WARNING in ipr_init() + - scsi: fcoe: Fix transport not deattached when fcoe_if_init() fails + - scsi: snic: Fix possible UAF in snic_tgt_create() + - RDMA/nldev: Add checks for nla_nest_start() in fill_stat_counter_qps() + - f2fs: avoid victim selection from previous victim section + - crypto: omap-sham - Use pm_runtime_resume_and_get() in omap_sham_probe() + - RDMA/hfi1: Fix error return code in parse_platform_config() + - orangefs: Fix sysfs not cleanup when dev init failed + - crypto: img-hash - Fix variable dereferenced before check 'hdev->req' + - hwrng: amd - Fix PCI device refcount leak + - hwrng: geode - Fix PCI device refcount leak + - IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces + - drivers: dio: fix possible memory leak in dio_init() + - tty: serial: tegra: Activate RX DMA transfer by request + - serial: tegra: Read DMA status before terminating + - class: fix possible memory leak in __class_register() + - vfio: platform: Do not pass return buffer to ACPI _RST method + - uio: uio_dmem_genirq: Fix missing unlock in irq configuration + - uio: uio_dmem_genirq: Fix deadlock between irq config and handling + - usb: fotg210-udc: Fix ages old endianness issues + - staging: vme_user: Fix possible UAF in tsi148_dma_list_add + - usb: typec: Check for ops->exit instead of ops->enter in altmode_exit + - usb: typec: tcpci: fix of node refcount leak in tcpci_register_port() + - serial: amba-pl011: avoid SBSA UART accessing DMACR register + - serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle. + - serial: pch: Fix PCI device refcount leak in pch_request_dma() + - tty: serial: clean up stop-tx part in altera_uart_tx_chars() + - tty: serial: altera_uart_{r,t}x_chars() need only uart_port + - serial: altera_uart: fix locking in polling mode + - serial: sunsab: Fix error handling in sunsab_init() + - test_firmware: fix memory leak in test_firmware_init() + - misc: ocxl: fix possible name leak in ocxl_file_register_afu() + - misc: tifm: fix possible memory leak in tifm_7xx1_switch_media() + - misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault + and gru_handle_user_call_os + - cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() + - cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() + - counter: stm32-lptimer-cnt: fix the check on arr and cmp registers update + - usb: roles: fix of node refcount leak in usb_role_switch_is_parent() + - usb: gadget: f_hid: optional SETUP/SET_REPORT mode + - usb: gadget: f_hid: fix f_hidg lifetime vs cdev + - usb: gadget: f_hid: fix refcount leak on error path + - drivers: mcb: fix resource leak in mcb_probe() + - mcb: mcb-parse: fix error handing in chameleon_parse_gdd() + - chardev: fix error handling in cdev_device_add() + - i2c: pxa-pci: fix missing pci_disable_device() on error in ce4100_i2c_probe + - staging: rtl8192u: Fix use after free in ieee80211_rx() + - staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() + - vme: Fix error not catched in fake_init() + - i2c: ismt: Fix an out-of-bounds bug in ismt_access() + - usb: storage: Add check for kcalloc + - tracing/hist: Fix issue of losting command info in error_log + - samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() + - fbdev: ssd1307fb: Drop optional dependency + - fbdev: pm2fb: fix missing pci_disable_device() + - fbdev: via: Fix error in via_core_init() + - fbdev: vermilion: decrease reference count in error path + - fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() + - HSI: omap_ssi_core: fix unbalanced pm_runtime_disable() + - HSI: omap_ssi_core: fix possible memory leak in ssi_probe() + - power: supply: fix residue sysfs file in error handle route of + __power_supply_register() + - perf trace: Return error if a system call doesn't exist + - perf trace: Separate 'struct syscall_fmt' definition from syscall_fmts + variable + - perf trace: Factor out the initialization of syscal_arg_fmt->scnprintf + - perf trace: Add the syscall_arg_fmt pointer to syscall_arg + - perf trace: Allow associating scnprintf routines with well known arg names + - perf trace: Add a strtoul() method to 'struct syscall_arg_fmt' + - perf trace: Use macro RAW_SYSCALL_ARGS_NUM to replace number + - perf trace: Handle failure when trace point folder is missed + - perf symbol: correction while adjusting symbol + - HSI: omap_ssi_core: Fix error handling in ssi_init() + - power: supply: fix null pointer dereferencing in + power_supply_get_battery_info + - RDMA/siw: Fix pointer cast warning + - include/uapi/linux/swab: Fix potentially missing __always_inline + - rtc: snvs: Allow a time difference on clock register read + - rtc: pcf85063: Fix reading alarm + - iommu/amd: Fix pci device refcount leak in ppr_notifier() + - iommu/fsl_pamu: Fix resource leak in fsl_pamu_probe() + - macintosh: fix possible memory leak in macio_add_one_device() + - macintosh/macio-adb: check the return value of ioremap() + - powerpc/52xx: Fix a resource leak in an error handling path + - cxl: Fix refcount leak in cxl_calc_capp_routing + - powerpc/xive: add missing iounmap() in error path in + xive_spapr_populate_irq_data() + - powerpc/perf: callchain validate kernel stack pointer bounds + - powerpc/83xx/mpc832x_rdb: call platform_device_put() in error case in + of_fsl_spi_probe() + - powerpc/hv-gpci: Fix hv_gpci event list + - selftests/powerpc: Fix resource leaks + - pwm: sifive: Call pwm_sifive_update_clock() while mutex is held + - remoteproc: sysmon: fix memory leak in qcom_add_sysmon_subdev() + - remoteproc: qcom_q6v5_pas: Fix missing of_node_put() in + adsp_alloc_memory_region() + - rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe() + - rtc: pic32: Move devm_rtc_allocate_device earlier in pic32_rtc_probe() + - nfsd: Define the file access mode enum for tracing + - NFSD: Add tracepoints to NFSD's duplicate reply cache + - nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure + - mISDN: hfcsusb: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - mISDN: hfcpci: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under + spin_lock_irqsave() + - nfc: pn533: Clear nfc_target before being used + - r6040: Fix kmemleak in probe and remove + - rtc: mxc_v2: Add missing clk_disable_unprepare() + - openvswitch: Fix flow lookup to use unmasked key + - skbuff: Account for tail adjustment during pull operations + - mailbox: zynq-ipi: fix error handling while device_register() fails + - net_sched: reject TCF_EM_SIMPLE case for complex ematch module + - rxrpc: Fix missing unlock in rxrpc_do_sendmsg() + - myri10ge: Fix an error handling path in myri10ge_probe() + - net: stream: purge sk_error_queue in sk_stream_kill_queues() + - rcu: Fix __this_cpu_read() lockdep warning in rcu_force_quiescent_state() + - binfmt_misc: fix shift-out-of-bounds in check_special_flags + - fs: jfs: fix shift-out-of-bounds in dbAllocAG + - udf: Avoid double brelse() in udf_rename() + - fs: jfs: fix shift-out-of-bounds in dbDiscardAG + - ACPICA: Fix error code path in acpi_ds_call_control_method() + - nilfs2: fix shift-out-of-bounds/overflow in nilfs_sb2_bad_offset() + - acct: fix potential integer overflow in encode_comp_t() + - hfs: fix OOB Read in __hfs_brec_find + - drm/etnaviv: add missing quirks for GC300 + - brcmfmac: return error when getting invalid max_flowrings from dongle + - wifi: ath9k: verify the expected usb_endpoints are present + - wifi: ar5523: Fix use-after-free on ar5523_cmd() timed out + - ASoC: codecs: rt298: Add quirk for KBL-R RVP platform + - ipmi: fix memleak when unload ipmi driver + - bpf: make sure skb->len != 0 when redirecting to a tunneling device + - net: ethernet: ti: Fix return type of netcp_ndo_start_xmit() + - hamradio: baycom_epp: Fix return type of baycom_send_packet() + - wifi: brcmfmac: Fix potential shift-out-of-bounds in + brcmf_fw_alloc_request() + - igb: Do not free q_vector unless new one was allocated + - s390/ctcm: Fix return type of ctc{mp,}m_tx() + - s390/netiucv: Fix return type of netiucv_tx() + - s390/lcs: Fix return type of lcs_start_xmit() + - drm/rockchip: Use drm_mode_copy() + - drm/sti: Use drm_mode_copy() + - drivers/md/md-bitmap: check the return value of md_bitmap_get_counter() + - md/raid1: stop mdx_raid1 thread when raid1 array run failed + - net: add atomic_long_t to net_device_stats fields + - mrp: introduce active flags to prevent UAF when applicant uninit + - ppp: associate skb with a device at tx + - bpf: Prevent decl_tag from being referenced in func_proto arg + - media: dvb-frontends: fix leak of memory fw + - media: dvbdev: adopts refcnt to avoid UAF + - media: dvb-usb: fix memory leak in dvb_usb_adapter_init() + - blk-mq: fix possible memleak when register 'hctx' failed + - regulator: core: fix use_count leakage when handling boot-on + - mmc: f-sdh30: Add quirks for broken timeout clock capability + - media: si470x: Fix use-after-free in si470x_int_in_callback() + - clk: st: Fix memory leak in st_of_quadfs_setup() + - hugetlbfs: fix null-ptr-deref in hugetlbfs_parse_param() + - drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() + - drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() + - orangefs: Fix kmemleak in orangefs_prepare_debugfs_help_string() + - orangefs: Fix kmemleak in orangefs_{kernel,client}_debug_init() + - ALSA/ASoC: hda: move/rename snd_hdac_ext_stop_streams to hdac_stream.c + - ALSA: hda: add snd_hdac_stop_streams() helper + - ASoC: Intel: Skylake: Fix driver hang during shutdown + - ASoC: mediatek: mt8173-rt5650-rt5514: fix refcount leak in + mt8173_rt5650_rt5514_dev_probe() + - ASoC: audio-graph-card: fix refcount leak of cpu_ep in + __graph_for_each_link() + - ASoC: rockchip: pdm: Add missing clk_disable_unprepare() in + rockchip_pdm_runtime_resume() + - ASoC: wm8994: Fix potential deadlock + - ASoC: rockchip: spdif: Add missing clk_disable_unprepare() in + rk_spdif_runtime_resume() + - ASoC: rt5670: Remove unbalanced pm_runtime_put() + - pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion + - pstore: Make sure CONFIG_PSTORE_PMSG selects CONFIG_RT_MUTEXES + - ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB + - ALSA: hda/hdmi: Add HP Device 0x8711 to force connect list + - usb: dwc3: core: defer probe on ulpi_read_id timeout + - HID: wacom: Ensure bootloader PID is usable in hidraw mode + - reiserfs: Add missing calls to reiserfs_security_free() + - iio: adc: ad_sigma_delta: do not use internal iio_dev lock + - iio: adc128s052: add proper .data members in adc128_of_match table + - regulator: core: fix deadlock on regulator enable + - gcov: add support for checksum field + - media: dvbdev: fix build warning due to comments + - media: dvbdev: fix refcnt bug + - cifs: fix oops during encryption + - nvme-pci: fix doorbell buffer value endianness + - ata: ahci: Fix PCS quirk application for suspend + - nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition + - objtool: Fix SEGFAULT + - powerpc/rtas: avoid device tree lookups in rtas_os_term() + - powerpc/rtas: avoid scheduling in rtas_os_term() + - HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint + - HID: plantronics: Additional PIDs for double volume key presses quirk + - hfsplus: fix bug causing custom uid and gid being unable to be assigned with + mount + - ovl: Use ovl mounter's fsuid and fsgid in ovl_link() + - ALSA: line6: correct midi status byte when receiving data from podxt + - ALSA: line6: fix stack overflow in line6_midi_transmit + - pnode: terminate at peers of source + - md: fix a crash in mempool_free + - mm, compaction: fix fast_isolate_around() to stay within boundaries + - f2fs: should put a page when checking the summary info + - mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING + - tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak + - tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak + - SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails + - net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO + - net/af_packet: make sure to pull mac header + - media: stv0288: use explicitly signed char + - soc: qcom: Select REMAP_MMIO for LLCC driver + - kest.pl: Fix grub2 menu handling for rebooting + - ktest.pl minconfig: Unset configs instead of just removing them + - mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K + - btrfs: fix resolving backrefs for inline extent followed by prealloc + - ARM: ux500: do not directly dereference __iomem + - arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength + - selftests: Use optional USERCFLAGS and USERLDFLAGS + - cpufreq: Init completion before kobject_init_and_add() + - binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf + - binfmt: Fix error return code in load_elf_fdpic_binary() + - dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort + - dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata + - dm thin: Use last transaction's pmd->root when commit failed + - dm thin: Fix UAF in run_timer_softirq() + - dm integrity: Fix UAF in dm_integrity_dtr() + - dm clone: Fix UAF in clone_dtr() + - dm cache: Fix UAF in destroy() + - dm cache: set needs_check flag after aborting metadata + - tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx' + - x86/microcode/intel: Do not retry microcode reloading on the APs + - tracing/hist: Fix wrong return value in parse_action_params() + - tracing: Fix infinite loop in tracing_read_pipe on overflowed + print_trace_line + - ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod + - media: dvb-core: Fix double free in dvb_register_device() + - cifs: fix confusing debug message + - cifs: fix missing display of three mount options + - md/bitmap: Fix bitmap chunk size overflow issues + - efi: Add iMac Pro 2017 to uefi skip cert quirk + - ipmi: fix long wait in unload when IPMI disconnect + - mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type() + - ima: Fix a potential NULL pointer access in ima_restore_measurement_list + - ipmi: fix use after free in _ipmi_destroy_user() + - PCI: Fix pci_device_is_present() for VFs by checking PF + - PCI/sysfs: Fix double free in error path + - crypto: n2 - add missing hash statesize + - iommu/amd: Fix ivrs_acpihid cmdline parsing code + - parisc: led: Fix potential null-ptr-deref in start_task() + - device_cgroup: Roll back to original exceptions after copy failure + - drm/connector: send hotplug uevent on connector cleanup + - drm/vmwgfx: Validate the box size for the snooped cursor + - ext4: add inode table check in __ext4_get_inode_loc to aovid possible + infinite loop + - ext4: fix undefined behavior in bit shift for ext4_check_flag_values + - ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode + - ext4: add helper to check quota inums + - ext4: fix reserved cluster accounting in __es_remove_extent() + - ext4: fix bug_on in __es_tree_search caused by bad boot loader inode + - ext4: init quota for 'old.inode' in 'ext4_rename' + - ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline + - ext4: fix corruption when online resizing a 1K bigalloc fs + - ext4: fix error code return to user-space in ext4_get_branch() + - ext4: avoid BUG_ON when creating xattrs + - ext4: fix inode leak in ext4_xattr_inode_create() on an error path + - ext4: initialize quota before expanding inode in setproject ioctl + - ext4: avoid unaccounted block allocation when expanding inode + - ext4: allocate extended attribute value in vmalloc area + - btrfs: replace strncpy() with strscpy() + - PM/devfreq: governor: Add a private governor_data for governor + - media: s5p-mfc: Fix to handle reference queue during finishing + - media: s5p-mfc: Clear workbit to handle error condition + - media: s5p-mfc: Fix in register read and write for H264 + - dm thin: resume even if in FAIL mode + - perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor + - perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged + data + - KVM: x86: optimize more exit handlers in vmx.c + - KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers + - KVM: VMX: Rename INTERRUPT_PENDING to INTERRUPT_WINDOW + - KVM: VMX: Rename NMI_PENDING to NMI_WINDOW + - KVM: VMX: Fix the spelling of CPU_BASED_USE_TSC_OFFSETTING + - KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1 + - ravb: Fix "failed to switch device to config mode" message during unbind + - ext4: goto right label 'failed_mount3a' + - ext4: correct inconsistent error msg in nojournal mode + - mm/highmem: Lift memcpy_[to|from]_page to core + - ext4: use memcpy_to_page() in pagecache_write() + - fs: ext4: initialize fsdata in pagecache_write() + - ext4: use kmemdup() to replace kmalloc + memcpy + - mbcache: don't reclaim used entries + - mbcache: add functions to delete entry if unused + - ext4: remove EA inode entry from mbcache on inode eviction + - ext4: unindent codeblock in ext4_xattr_block_set() + - ext4: fix race when reusing xattr blocks + - mbcache: automatically delete entries from cache on freeing + - ext4: fix deadlock due to mbcache entry corruption + - SUNRPC: ensure the matching upcall is in-flight upon downcall + - bpf: pull before calling skb_postpull_rcsum() + - nfsd: shut down the NFSv4 state objects before the filecache + - net: hns3: add interrupts re-initialization while doing VF FLR + - net: sched: fix memory leak in tcindex_set_parms + - qlcnic: prevent ->dcb use-after-free on qlcnic_dcb_enable() failure + - nfc: Fix potential resource leaks + - vhost: fix range used in translate_desc() + - net: amd-xgbe: add missed tasklet_kill + - net: phy: xgmiitorgmii: Fix refcount leak in xgmiitorgmii_probe + - RDMA/uverbs: Silence shiftTooManyBitsSigned warning + - RDMA/mlx5: Fix validation of max_rd_atomic caps for DC + - net: sched: atm: dont intepret cls results when asked to drop + - net: sched: cbq: dont intepret cls results when asked to drop + - perf tools: Fix resources leak in perf_data__open_dir() + - drivers/net/bonding/bond_3ad: return when there's no aggregator + - usb: rndis_host: Secure rndis_query check against int overflow + - drm/i915: unpin on error in intel_vgpu_shadow_mm_pin() + - caif: fix memory leak in cfctrl_linkup_request() + - udf: Fix extension of the last extent in the file + - ASoC: Intel: bytcr_rt5640: Add quirk for the Advantech MICA-071 tablet + - x86/bugs: Flush IBP in ib_prctl_set() + - nfsd: fix handling of readdir in v4root vs. mount upcall timeout + - riscv: uaccess: fix type of 0 variable on error in get_user() + - ext4: don't allow journal inode to have encrypt flag + - hfs/hfsplus: use WARN_ON for sanity check + - hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling + - mbcache: Avoid nesting of cache->c_list_lock under bit locks + - parisc: Align parisc MADV_XXX constants with all other architectures + - selftests: Fix kselftest O=objdir build from cluttering top level objdir + - selftests: set the BUILD variable to absolute path + - driver core: Fix bus_type.match() error handling in __driver_attach() + - net: sched: disallow noqueue for qdisc classes + - KVM: arm64: Fix S1PTW handling on RO memslots + - efi: tpm: Avoid READ_ONCE() for accessing the event log + - docs: Fix the docs build with Sphinx 6.0 + - perf auxtrace: Fix address filter duplicate symbol selection + - s390/kexec: fix ipl report address for kdump + - s390/percpu: add READ_ONCE() to arch_this_cpu_to_op_simple() + - net/ulp: prevent ULP without clone op from entering the LISTEN status + - ALSA: hda/hdmi: Add a HP device 0x8715 to force connect list + - cifs: Fix uninitialized memory read for smb311 posix symlink create + - drm/msm/adreno: Make adreno quirks not overwrite each other + - platform/x86: sony-laptop: Don't turn off 0x153 keyboard backlight during + probe + - ixgbe: fix pci device refcount leak + - ipv6: raw: Deduct extension header length in rawv6_push_pending_frames + - wifi: wilc1000: sdio: fix module autoloading + - usb: ulpi: defer ulpi_register on ulpi_read_id timeout + - jbd2: use the correct print format + - quota: Factor out setup of quota inode + - ext4: fix bug_on in __es_tree_search caused by bad quota inode + - ext4: lost matching-pair of trace in ext4_truncate + - ext4: fix use-after-free in ext4_orphan_cleanup + - ext4: fix uninititialized value in 'ext4_evict_inode' + - netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() + function. + - powerpc/imc-pmu: Fix use of mutex in IRQs disabled section + - x86/boot: Avoid using Intel mnemonics in AT&T syntax asm + - EDAC/device: Fix period calculation in edac_device_reset_delay_period() + - regulator: da9211: Use irq handler when ready + - tipc: improve throughput between nodes in netns + - tipc: eliminate checking netns if node established + - tipc: fix unexpected link reset due to discovery messages + - hvc/xen: lock console list traversal + - nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() + - net/sched: act_mpls: Fix warning during failed attribute validation + - net/mlx5: Rename ptp clock info + - net/mlx5: Fix ptp max frequency adjustment range + - iommu/mediatek-v1: Add error handle for mtk_iommu_probe + - iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() + - x86/resctrl: Use task_curr() instead of task_struct->on_cpu to prevent + unnecessary IPI + - x86/resctrl: Fix task CLOSID/RMID update race + - drm/virtio: Fix GEM handle creation UAF + - arm64: atomics: format whitespace consistently + - arm64: atomics: remove LL/SC trampolines + - arm64: cmpxchg_double*: hazard against entire exchange variable + - efi: fix NULL-deref in init error path + - mm: Always release pages to the buddy allocator in memblock_free_late(). + - Revert "usb: ulpi: defer ulpi_register on ulpi_read_id timeout" + - tipc: fix use-after-free in tipc_disc_rcv() + - tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started + - tipc: Add a missing case of TIPC_DIRECT_MSG type + - ocfs2: fix freeing uninitialized resource on ocfs2_dlm_shutdown + - tipc: call tipc_lxc_xmit without holding node_read_lock + - Linux 5.4.229 + * Focal update: v5.4.229 upstream stable release (LP: #2003914) // + CVE-2023-0266 was assigned for this issue. + - ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF + * Focal update: v5.4.229 upstream stable release (LP: #2003914) // + CVE-2022-41218 is assigned to those bugs above. + - media: dvb-core: Fix UAF due to refcount races at releasing + * Focal update: v5.4.228 upstream stable release (LP: #2003904) + - x86/smpboot: Move rcu_cpu_starting() earlier + - mm/hugetlb: fix races when looking up a CONT-PTE/PMD size hugetlb page + - block: unhash blkdev part inode when the part is deleted + - ASoC: ops: Check bounds for second channel in snd_soc_put_volsw_sx() + - pinctrl: meditatek: Startup with the IRQs disabled + - can: sja1000: fix size of OCR_MODE_MASK define + - can: mcba_usb: Fix termination command argument + - ASoC: ops: Correct bounds check for second channel on SX controls + - Linux 5.4.228 + * Focal update: v5.4.227 upstream stable release (LP: #2003901) + - arm64: dts: rockchip: keep I2S1 disabled for GPIO function on ROCK Pi 4 + series + - arm: dts: rockchip: fix node name for hym8563 rtc + - ARM: dts: rockchip: fix ir-receiver node names + - ARM: dts: rockchip: rk3188: fix lcdc1-rgb24 node name + - ARM: 9251/1: perf: Fix stacktraces for tracepoint events in THUMB2 kernels + - ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation + - ARM: dts: rockchip: disable arm_global_timer on rk3066 and rk3188 + - 9p/fd: Use P9_HDRSZ for header size + - regulator: slg51000: Wait after asserting CS pin + - ALSA: seq: Fix function prototype mismatch in snd_seq_expand_var_event + - btrfs: send: avoid unaligned encoded writes when attempting to clone range + - ASoC: soc-pcm: Add NULL check in BE reparenting + - regulator: twl6030: fix get status of twl6032 regulators + - fbcon: Use kzalloc() in fbcon_prepare_logo() + - 9p/xen: check logical size for buffer size + - net: usb: qmi_wwan: add u-blox 0x1342 composition + - mm/khugepaged: take the right locks for page table retraction + - mm/khugepaged: fix GUP-fast interaction by sending IPI + - mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths + - xen/netback: do some code cleanup + - xen/netback: don't call kfree_skb() with interrupts disabled + - Revert "net: dsa: b53: Fix valid setting for MDB entries" + - media: v4l2-dv-timings.c: fix too strict blanking sanity checks + - memcg: fix possible use-after-free in memcg_write_event_control() + - mm/gup: fix gup_pud_range() for dax + - KVM: s390: vsie: Fix the initialization of the epoch extension (epdx) field + - drm/shmem-helper: Remove errant put in error path + - HID: usbhid: Add ALWAYS_POLL quirk for some mice + - HID: hid-lg4ff: Add check for empty lbuf + - HID: core: fix shift-out-of-bounds in hid_report_raw_event + - can: af_can: fix NULL pointer dereference in can_rcv_filter + - ieee802154: cc2520: Fix error return code in cc2520_hw_init() + - ca8210: Fix crash by zero initializing data + - drm/bridge: ti-sn65dsi86: Fix output polarity setting bug + - gpio: amd8111: Fix PCI device reference count leak + - e1000e: Fix TX dispatch condition + - igb: Allocate MSI-X vector when testing + - af_unix: Get user_ns from in_skb in unix_diag_get_exact(). + - Bluetooth: 6LoWPAN: add missing hci_dev_put() in get_l2cap_conn() + - Bluetooth: Fix not cleanup led when bt_init fails + - net: dsa: ksz: Check return value + - selftests: rtnetlink: correct xfrm policy rule in kci_test_ipsec_offload + - mac802154: fix missing INIT_LIST_HEAD in ieee802154_if_add() + - net: encx24j600: Add parentheses to fix precedence + - net: encx24j600: Fix invalid logic in reading of MISTAT register + - xen-netfront: Fix NULL sring after live migration + - net: mvneta: Prevent out of bounds read in mvneta_config_rss() + - i40e: Fix not setting default xps_cpus after reset + - i40e: Fix for VF MAC address 0 + - i40e: Disallow ip4 and ip6 l4_4_bytes + - NFC: nci: Bounds check struct nfc_target arrays + - nvme initialize core quirks before calling nvme_init_subsystem + - net: stmmac: fix "snps,axi-config" node property parsing + - net: thunderx: Fix missing destroy_workqueue of nicvf_rx_mode_wq + - net: hisilicon: Fix potential use-after-free in hisi_femac_rx() + - net: hisilicon: Fix potential use-after-free in hix5hd2_rx() + - tipc: Fix potential OOB in tipc_link_proto_rcv() + - ipv4: Fix incorrect route flushing when source address is deleted + - ipv4: Fix incorrect route flushing when table ID 0 is used + - ethernet: aeroflex: fix potential skb leak in greth_init_rings() + - net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() + - ipv6: avoid use-after-free in ip6_fragment() + - net: mvneta: Fix an out of bounds check + - can: esd_usb: Allow REC and TEC to return to zero + - Linux 5.4.227 + * 5.15.0-58.64 breaks xen bridge networking (pvh domU) (LP: #2002889) // Focal + update: v5.4.227 upstream stable release (LP: #2003901) + - xen/netback: fix build warning + * Focal update: v5.4.226 upstream stable release (LP: #2003896) + - wifi: mac80211: fix memory free error when registering wiphy fail + - wifi: mac80211_hwsim: fix debugfs attribute ps with rc table support + - audit: fix undefined behavior in bit shift for AUDIT_BIT + - wifi: mac80211: Fix ack frame idr leak when mesh has no route + - spi: stm32: fix stm32_spi_prepare_mbr() that halves spi clk for every run + - drm: panel-orientation-quirks: Add quirk for Acer Switch V 10 (SW5-017) + - block, bfq: fix null pointer dereference in bfq_bio_bfqg() + - arm64/syscall: Include asm/ptrace.h in syscall_wrapper header. + - RISC-V: vdso: Do not add missing symbols to version section in linker script + - MIPS: pic32: treat port as signed integer + - af_key: Fix send_acquire race with pfkey_register + - ARM: dts: am335x-pcm-953: Define fixed regulators in root node + - ASoC: sgtl5000: Reset the CHIP_CLK_CTRL reg on remove + - regulator: core: fix kobject release warning and memory leak in + regulator_register() + - regulator: core: fix UAF in destroy_regulator() + - bus: sunxi-rsb: Support atomic transfers + - tee: optee: fix possible memory leak in optee_register_device() + - ARM: dts: at91: sam9g20ek: enable udc vbus gpio pinctrl + - net: liquidio: simplify if expression + - nfc/nci: fix race with opening and closing + - net: pch_gbe: fix potential memleak in pch_gbe_tx_queue() + - 9p/fd: fix issue of list_del corruption in p9_fd_cancel() + - ARM: mxs: fix memory leak in mxs_machine_init() + - net/mlx4: Check retval of mlx4_bitmap_init + - net/qla3xxx: fix potential memleak in ql3xxx_send() + - net: pch_gbe: fix pci device refcount leak while module exiting + - nfp: add port from netdev validation for EEPROM access + - Drivers: hv: vmbus: fix double free in the error path of + vmbus_add_channel_work() + - Drivers: hv: vmbus: fix possible memory leak in vmbus_device_register() + - net/mlx5: Fix FW tracer timestamp calculation + - tipc: set con sock in tipc_conn_alloc + - tipc: add an extra conn_get in tipc_conn_alloc + - tipc: check skb_linearize() return value in tipc_disc_rcv() + - xfrm: Fix ignored return value in xfrm6_init() + - NFC: nci: fix memory leak in nci_rx_data_packet() + - regulator: twl6030: re-add TWL6032_SUBCLASS + - bnx2x: fix pci device refcount leak in bnx2x_vf_is_pcie_pending() + - dccp/tcp: Reset saddr on failure after inet6?_hash_connect(). + - s390/dasd: fix no record found for raw_track_access + - nfc: st-nci: fix incorrect validating logic in EVT_TRANSACTION + - nfc: st-nci: fix memory leaks in EVT_TRANSACTION + - net: thunderx: Fix the ACPI memory leak + - s390/crashdump: fix TOD programmable field size + - lib/vdso: use "grep -E" instead of "egrep" + - usb: dwc3: exynos: Fix remove() function + - arm64: dts: rockchip: lower rk3399-puma-haikou SD controller clock frequency + - iio: light: apds9960: fix wrong register for gesture gain + - iio: core: Fix entry not deleted when iio_register_sw_trigger_type() fails + - init/Kconfig: fix CC_HAS_ASM_GOTO_TIED_OUTPUT test with dash + - nios2: add FORCE for vmlinuz.gz + - iio: ms5611: Simplify IO callback parameters + - iio: pressure: ms5611: fixed value compensation bug + - ceph: do not update snapshot context when there is no new snapshot + - ceph: avoid putting the realm twice when decoding snaps fails + - firmware: google: Release devices before unregistering the bus + - firmware: coreboot: Register bus in module init + - nilfs2: fix nilfs_sufile_mark_dirty() not set segment usage as dirty + - gcov: clang: fix the buffer overflow issue + - Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode + - ASoC: Intel: bytcht_es8316: Add quirk for the Nanote UMPC-01 + - serial: 8250: 8250_omap: Avoid RS485 RTS glitch on ->set_termios() + - xen/platform-pci: add missing free_irq() in error path + - platform/x86: asus-wmi: add missing pci_dev_put() in asus_wmi_set_xusb2pr() + - platform/x86: acer-wmi: Enable SW_TABLET_MODE on Switch V 10 (SW5-017) + - platform/x86: hp-wmi: Ignore Smart Experience App event + - [Config] updateconfigs for INET_TABLE_PERTURB_ORDER + - tcp: configurable source port perturb table size + - net: usb: qmi_wwan: add Telit 0x103a composition + - dm integrity: flush the journal on suspend + - binder: avoid potential data leakage when copying txn + - binder: read pre-translated fds from sender buffer + - binder: defer copies of pre-patched txn data + - binder: fix pointer cast warning + - binder: Address corner cases in deferred copy and fixup + - binder: Gracefully handle BINDER_TYPE_FDA objects with num_fds=0 + - btrfs: free btrfs_path before copying root refs to userspace + - btrfs: free btrfs_path before copying fspath to userspace + - btrfs: free btrfs_path before copying subvol info to userspace + - btrfs: sysfs: normalize the error handling branch in btrfs_init_sysfs() + - drm/amd/dc/dce120: Fix audio register mapping, stop triggering KASAN + - drm/amdgpu: always register an MMU notifier for userptr + - fuse: lock inode unconditionally in fuse_fallocate() + - btrfs: free btrfs_path before copying inodes to userspace + - spi: spi-imx: Fix spi_bus_clk if requested clock is higher than input clock + - btrfs: move QUOTA_ENABLED check to rescan_should_stop from + btrfs_qgroup_rescan_worker + - drm/amdgpu: update drm_display_info correctly when the edid is read + - drm/amdgpu: Partially revert "drm/amdgpu: update drm_display_info correctly + when the edid is read" + - btrfs: qgroup: fix sleep from invalid context bug in btrfs_qgroup_inherit() + - iio: health: afe4403: Fix oob read in afe4403_read_raw + - iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw + - iio: light: rpr0521: add missing Kconfig dependencies + - scripts/faddr2line: Fix regression in name resolution on ppc64le + - hwmon: (i5500_temp) fix missing pci_disable_device() + - hwmon: (ibmpex) Fix possible UAF when ibmpex_register_bmc() fails + - of: property: decrement node refcount in of_fwnode_get_reference_args() + - net/mlx5: Fix uninitialized variable bug in outlen_write() + - net/mlx5e: Fix use-after-free when reverting termination table + - can: sja1000_isa: sja1000_isa_probe(): add missing free_sja1000dev() + - can: cc770: cc770_isa_probe(): add missing free_cc770dev() + - qlcnic: fix sleep-in-atomic-context bugs caused by msleep + - wifi: cfg80211: fix buffer overflow in elem comparison + - net: phy: fix null-ptr-deref while probe() failed + - net: net_netdev: Fix error handling in ntb_netdev_init_module() + - net/9p: Fix a potential socket leak in p9_socket_open + - net: ethernet: nixge: fix NULL dereference + - dsa: lan9303: Correct stat name + - net: hsr: Fix potential use-after-free + - afs: Fix fileserver probe RTT handling + - net: tun: Fix use-after-free in tun_detach() + - packet: do not set TP_STATUS_CSUM_VALID on CHECKSUM_COMPLETE + - sctp: fix memory leak in sctp_stream_outq_migrate() + - net: ethernet: renesas: ravb: Fix promiscuous mode after system resumed + - hwmon: (coretemp) Check for null before removing sysfs attrs + - hwmon: (coretemp) fix pci device refcount leak in nv1a_ram_new() + - net/mlx5: DR, Fix uninitialized var warning + - error-injection: Add prompt for function error injection + - tools/vm/slabinfo-gnuplot: use "grep -E" instead of "egrep" + - nilfs2: fix NULL pointer dereference in nilfs_palloc_commit_free_entry() + - x86/bugs: Make sure MSR_SPEC_CTRL is updated properly upon resume from S3 + - pinctrl: intel: Save and restore pins in "direct IRQ" mode + - mmc: mmc_test: Fix removal of debugfs file + - mmc: core: Fix ambiguous TRIM and DISCARD arg + - mmc: sdhci-esdhc-imx: correct CQHCI exit halt state check + - mmc: sdhci-sprd: Fix no reset data and command after voltage switch + - tracing: Free buffers when a used dynamic event is removed + - arm64: Fix panic() when Spectre-v2 causes Spectre-BHB to re-allocate KVM + vectors + - arm64: errata: Fix KVM Spectre-v2 mitigation selection for Cortex-A57/A72 + - mm: Fix '.data.once' orphan section warning + - ASoC: ops: Fix bounds check for _sx controls + - pinctrl: single: Fix potential division by zero + - iommu/vt-d: Fix PCI device refcount leak in dmar_dev_scope_init() + - parisc: Increase size of gcc stack frame check + - xtensa: increase size of gcc stack frame check + - parisc: Increase FRAME_WARN to 2048 bytes on parisc + - Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is + enabled + - selftests: net: add delete nexthop route warning test + - selftests: net: fix nexthop warning cleanup double ip typo + - ipv4: Handle attempt to delete multipath route when fib_info contains an nh + reference + - ipv4: Fix route deletion when nexthop info is not specified + - tracing/ring-buffer: Have polling block on watermark + - nvme: restrict management ioctls to admin + - nvme: ensure subsystem reset is single threaded + - x86/tsx: Add a feature bit for TSX control MSR support + - x86/pm: Add enumeration check before spec MSRs save/restore setup + - x86/ioremap: Fix page aligned size calculation in __ioremap_caller() + - Revert "clocksource/drivers/riscv: Events are stopped during CPU suspend" + - char: tpm: Protect tpm_pm_suspend with locks + - mmc: sdhci: use FIELD_GET for preset value bit masks + - mmc: sdhci: Fix voltage switch delay + - proc: avoid integer type confusion in get_proc_long + - proc: proc_skip_spaces() shouldn't think it is working on C strings + - v4l2: don't fall back to follow_pfn() if pin_user_pages_fast() fails + - ipc/sem: Fix dangling sem_array access in semtimedop race + - Linux 5.4.226 + * CVE-2022-4139 + - drm/i915: fix TLB invalidation for Gen12 video and compute engines + * Focal update: v5.4.225 upstream stable release (LP: #2002347) + - xfs: preserve rmapbt swapext block reservation from freed blocks + - xfs: rename xfs_bmap_is_real_extent to is_written_extent + - xfs: redesign the reflink remap loop to fix blkres depletion crash + - xfs: use MMAPLOCK around filemap_map_pages() + - xfs: preserve inode versioning across remounts + - xfs: drain the buf delwri queue before xfsaild idles + - phy: stm32: fix an error code in probe + - wifi: cfg80211: silence a sparse RCU warning + - wifi: cfg80211: fix memory leak in query_regdb_file() + - bpf, sockmap: Fix the sk->sk_forward_alloc warning of sk_stream_kill_queues + - HID: hyperv: fix possible memory leak in mousevsc_probe() + - net: gso: fix panic on frag_list with mixed head alloc types + - net: tun: Fix memory leaks of napi_get_frags + - bnxt_en: Fix possible crash in bnxt_hwrm_set_coal() + - bnxt_en: fix potentially incorrect return value for ndo_rx_flow_steer + - net: fman: Unregister ethernet device on removal + - capabilities: fix undefined behavior in bit shift for CAP_TO_MASK + - net: lapbether: fix issue of dev reference count leakage in + lapbeth_device_event() + - hamradio: fix issue of dev reference count leakage in bpq_device_event() + - drm/vc4: Fix missing platform_unregister_drivers() call in + vc4_drm_register() + - ipv6: addrlabel: fix infoleak when sending struct ifaddrlblmsg to network + - can: af_can: fix NULL pointer dereference in can_rx_register() + - tipc: fix the msg->req tlv len check in + tipc_nl_compat_name_table_dump_header + - dmaengine: pxa_dma: use platform_get_irq_optional + - dmaengine: mv_xor_v2: Fix a resource leak in mv_xor_v2_remove() + - drivers: net: xgene: disable napi when register irq failed in + xgene_enet_open() + - perf stat: Fix printing os->prefix in CSV metrics output + - net: nixge: disable napi when enable interrupts failed in nixge_open() + - net/mlx5: Allow async trigger completion execution on single CPU systems + - net: cpsw: disable napi in cpsw_ndo_open() + - net: cxgb3_main: disable napi when bind qsets failed in cxgb_up() + - cxgb4vf: shut down the adapter when t4vf_update_port_info() failed in + cxgb4vf_open() + - ethernet: s2io: disable napi when start nic failed in s2io_card_up() + - net: mv643xx_eth: disable napi when init rxq or txq failed in + mv643xx_eth_open() + - ethernet: tundra: free irq when alloc ring failed in tsi108_open() + - net: macvlan: fix memory leaks of macvlan_common_newlink + - riscv: process: fix kernel info leakage + - arm64: efi: Fix handling of misaligned runtime regions and drop warning + - MIPS: jump_label: Fix compat branch range check + - mmc: cqhci: Provide helper for resetting both SDHCI and CQHCI + - mmc: sdhci-of-arasan: Fix SDHCI_RESET_ALL for CQHCI + - mmc: sdhci-tegra: Fix SDHCI_RESET_ALL for CQHCI + - ALSA: hda/ca0132: add quirk for EVGA Z390 DARK + - ALSA: hda: fix potential memleak in 'add_widget_node' + - ALSA: usb-audio: Add quirk entry for M-Audio Micro + - ALSA: usb-audio: Add DSD support for Accuphase DAC-60 + - vmlinux.lds.h: Fix placement of '.data..decrypted' section + - nilfs2: fix deadlock in nilfs_count_free_blocks() + - nilfs2: fix use-after-free bug of ns_writer on remount + - drm/i915/dmabuf: fix sg_table handling in map_dma_buf + - btrfs: selftests: fix wrong error check in btrfs_free_dummy_root() + - udf: Fix a slab-out-of-bounds write bug in udf_find_entry() + - can: j1939: j1939_send_one(): fix missing CAN header initialization + - cert host tools: Stop complaining about deprecated OpenSSL functions + - dmaengine: at_hdmac: Fix at_lli struct definition + - dmaengine: at_hdmac: Don't start transactions at tx_submit level + - dmaengine: at_hdmac: Fix completion of unissued descriptor in case of errors + - dmaengine: at_hdmac: Don't allow CPU to reorder channel enable + - dmaengine: at_hdmac: Fix impossible condition + - dmaengine: at_hdmac: Check return code of dma_async_device_register + - net: tun: call napi_schedule_prep() to ensure we own a napi + - x86/cpu: Restore AMD's DE_CFG MSR after resume + - ASoC: wm5102: Revert "ASoC: wm5102: Fix PM disable depth imbalance in + wm5102_probe" + - ASoC: wm5110: Revert "ASoC: wm5110: Fix PM disable depth imbalance in + wm5110_probe" + - ASoC: wm8997: Revert "ASoC: wm8997: Fix PM disable depth imbalance in + wm8997_probe" + - ASoC: wm8962: Add an event handler for TEMP_HP and TEMP_SPK + - spi: intel: Fix the offset to get the 64K erase opcode + - ASoC: codecs: jz4725b: add missed Line In power control bit + - ASoC: codecs: jz4725b: fix reported volume for Master ctl + - ASoC: codecs: jz4725b: use right control for Capture Volume + - ASoC: codecs: jz4725b: fix capture selector naming + - selftests/futex: fix build for clang + - selftests/intel_pstate: fix build for ARCH=x86_64 + - NFSv4: Retry LOCK on OLD_STATEID during delegation return + - i2c: i801: add lis3lv02d's I2C address for Vostro 5568 + - drm/imx: imx-tve: Fix return type of imx_tve_connector_mode_valid + - btrfs: remove pointless and double ulist frees in error paths of qgroup + tests + - ASoC: codecs: jz4725b: Fix spelling mistake "Sourc" -> "Source", "Routee" -> + "Route" + - spi: stm32: Print summary 'callbacks suppressed' message + - ASoC: core: Fix use-after-free in snd_soc_exit() + - serial: 8250_omap: remove wait loop from Errata i202 workaround + - serial: 8250: omap: Fix unpaired pm_runtime_put_sync() in omap8250_remove() + - serial: 8250: omap: Flush PM QOS work on remove + - serial: imx: Add missing .thaw_noirq hook + - tty: n_gsm: fix sleep-in-atomic-context bug in gsm_control_send + - ASoC: soc-utils: Remove __exit for snd_soc_util_exit() + - block: sed-opal: kmalloc the cmd/resp buffers + - siox: fix possible memory leak in siox_device_add() + - parport_pc: Avoid FIFO port location truncation + - pinctrl: devicetree: fix null pointer dereferencing in pinctrl_dt_to_map + - arm64: dts: imx8mm: Fix NAND controller size-cells + - arm64: dts: imx8mn: Fix NAND controller size-cells + - ata: libata-transport: fix double ata_host_put() in ata_tport_add() + - net: bgmac: Drop free_netdev() from bgmac_enet_remove() + - mISDN: fix possible memory leak in mISDN_dsp_element_register() + - net: liquidio: release resources when liquidio driver open failed + - mISDN: fix misuse of put_device() in mISDN_register_device() + - net: macvlan: Use built-in RCU list checking + - net: caif: fix double disconnect client in chnl_net_open() + - bnxt_en: Remove debugfs when pci_register_driver failed + - xen/pcpu: fix possible memory leak in register_pcpu() + - drbd: use after free in drbd_create_device() + - platform/x86/intel: pmc: Don't unconditionally attach Intel PMC when + virtualized + - net/x25: Fix skb leak in x25_lapb_receive_frame() + - cifs: Fix wrong return value checking when GETFLAGS + - net: thunderbolt: Fix error handling in tbnet_init() + - cifs: add check for returning value of SMB2_set_info_init + - ftrace: Fix the possible incorrect kernel message + - ftrace: Optimize the allocation for mcount entries + - ftrace: Fix null pointer dereference in ftrace_add_mod() + - ring_buffer: Do not deactivate non-existant pages + - ALSA: usb-audio: Drop snd_BUG_ON() from snd_usbmidi_output_open() + - Revert "usb: dwc3: disable USB core PHY management" + - slimbus: stream: correct presence rate frequencies + - speakup: fix a segfault caused by switching consoles + - USB: serial: option: add Sierra Wireless EM9191 + - USB: serial: option: remove old LARA-R6 PID + - USB: serial: option: add u-blox LARA-R6 00B modem + - USB: serial: option: add u-blox LARA-L6 modem + - USB: serial: option: add Fibocom FM160 0x0111 composition + - usb: add NO_LPM quirk for Realforce 87U Keyboard + - usb: chipidea: fix deadlock in ci_otg_del_timer + - iio: adc: at91_adc: fix possible memory leak in at91_adc_allocate_trigger() + - iio: trigger: sysfs: fix possible memory leak in iio_sysfs_trig_init() + - iio: pressure: ms5611: changed hardcoded SPI speed to value limited + - dm ioctl: fix misbehavior if list_versions races with module loading + - serial: 8250: Fall back to non-DMA Rx if IIR_RDI occurs + - serial: 8250_lpss: Configure DMA also w/o DMA filter + - Input: iforce - invert valid length check when fetching device IDs + - scsi: zfcp: Fix double free of FSF request when qdio send fails + - mmc: core: properly select voltage range without power cycle + - mmc: sdhci-pci-o2micro: fix card detect fail issue caused by CD# debounce + timeout + - mmc: sdhci-pci: Fix possible memory leak caused by missing pci_dev_put() + - docs: update mediator contact information in CoC doc + - misc/vmw_vmci: fix an infoleak in vmci_host_do_receive_datagram() + - serial: 8250: Flush DMA Rx on RLSI + - ring-buffer: Include dropped pages in counting dirty patches + - scsi: target: tcm_loop: Fix possible name leak in tcm_loop_setup_hba_bus() + - kprobes: Skip clearing aggrprobe's post_handler in kprobe-on-ftrace case + - Input: i8042 - fix leaking of platform device on module removal + - macvlan: enforce a consistent minimal mtu + - tcp: cdg: allow tcp_cdg_release() to be called multiple times + - kcm: avoid potential race in kcm_tx_work + - bpf, test_run: Fix alignment problem in bpf_prog_test_run_skb() + - kcm: close race conditions on sk_receive_queue + - 9p: trans_fd/p9_conn_cancel: drop client lock earlier + - gfs2: Check sb_bsize_shift after reading superblock + - gfs2: Switch from strlcpy to strscpy + - 9p/trans_fd: always use O_NONBLOCK read/write + - mm: fs: initialize fsdata passed to write_begin/write_end interface + - ntfs: fix use-after-free in ntfs_attr_find() + - ntfs: fix out-of-bounds read in ntfs_attr_find() + - ntfs: check overflow when iterating ATTR_RECORDs + - Linux 5.4.225 + * CVE-2022-47520 + - wifi: wilc1000: validate pairwise and authentication suite offsets + * CVE-2022-3545 + - nfp: fix use-after-free in area_cache_get() + + -- Joseph Salisbury Thu, 09 Feb 2023 13:55:27 -0500 + +linux-oracle (5.4.0-1093.102) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1093.102 -proposed tracker (LP: #2003480) + + * Focal update: v5.4.221 upstream stable release (LP: #1997993) + - [Config] oracle: updateconfigs for ARM64_ERRATUM_1742098 + + [ Ubuntu: 5.4.0-139.156 ] + + * focal/linux: 5.4.0-139.156 -proposed tracker (LP: #2003486) + * Revoke & rotate to new signing key (LP: #2002812) + - [Packaging] Revoke and rotate to new signing key + + [ Ubuntu: 5.4.0-138.155 ] + + * focal/linux: 5.4.0-138.155 -proposed tracker (LP: #2001845) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Focal update: v5.4.224 upstream stable release (LP: #1999273) + - RDMA/cma: Use output interface for net_dev check + - IB/hfi1: Correctly move list in sc_disable() + - NFSv4.1: Handle RECLAIM_COMPLETE trunking errors + - NFSv4.1: We must always send RECLAIM_COMPLETE after a reboot + - nfs4: Fix kmemleak when allocate slot failed + - net: dsa: Fix possible memory leaks in dsa_loop_init() + - RDMA/core: Fix null-ptr-deref in ib_core_cleanup() + - RDMA/qedr: clean up work queue on failure in qedr_alloc_resources() + - nfc: s3fwrn5: Fix potential memory leak in s3fwrn5_nci_send() + - nfc: nfcmrvl: Fix potential memory leak in nfcmrvl_i2c_nci_send() + - net: fec: fix improper use of NETDEV_TX_BUSY + - ata: pata_legacy: fix pdc20230_set_piomode() + - net: sched: Fix use after free in red_enqueue() + - net: tun: fix bugs for oversize packet when napi frags enabled + - netfilter: nf_tables: release flow rule object from commit path + - ipvs: use explicitly signed chars + - ipvs: fix WARNING in __ip_vs_cleanup_batch() + - ipvs: fix WARNING in ip_vs_app_net_cleanup() + - rose: Fix NULL pointer dereference in rose_send_frame() + - mISDN: fix possible memory leak in mISDN_register_device() + - isdn: mISDN: netjet: fix wrong check of device registration + - btrfs: fix inode list leak during backref walking at resolve_indirect_refs() + - btrfs: fix inode list leak during backref walking at find_parent_nodes() + - btrfs: fix ulist leaks in error paths of qgroup self tests + - Bluetooth: L2CAP: fix use-after-free in l2cap_conn_del() + - net: mdio: fix undefined behavior in bit shift for __mdiobus_register + - net, neigh: Fix null-ptr-deref in neigh_table_clear() + - ipv6: fix WARNING in ip6_route_net_exit_late() + - media: s5p_cec: limit msg.len to CEC_MAX_MSG_SIZE + - media: cros-ec-cec: limit msg.len to CEC_MAX_MSG_SIZE + - media: dvb-frontends/drxk: initialize err to 0 + - media: meson: vdec: fix possible refcount leak in vdec_probe() + - scsi: core: Restrict legal sdev_state transitions via sysfs + - HID: saitek: add madcatz variant of MMO7 mouse device ID + - i2c: xiic: Add platform module alias + - xfs: don't fail verifier on empty attr3 leaf block + - xfs: use ordered buffers to initialize dquot buffers during quotacheck + - xfs: gut error handling in xfs_trans_unreserve_and_mod_sb() + - xfs: group quota should return EDQUOT when prj quota enabled + - xfs: don't fail unwritten extent conversion on writeback due to edquot + - xfs: Add the missed xfs_perag_put() for xfs_ifree_cluster() + - Bluetooth: L2CAP: Fix attempting to access uninitialized memory + - block, bfq: protect 'bfqd->queued' by 'bfqd->lock' + - binder: fix UAF of alloc->vma in race with munmap() + - btrfs: fix type of parameter generation in btrfs_get_dentry + - tcp/udp: Make early_demux back namespacified. + - kprobe: reverse kp->flags when arm_kprobe failed + - tools/nolibc/string: Fix memcmp() implementation + - tracing/histogram: Update document for KEYS_MAX size + - capabilities: fix potential memleak on error path from vfs_getxattr_alloc() + - fuse: add file_modified() to fallocate + - efi: random: reduce seed size to 32 bytes + - perf/x86/intel: Fix pebs event constraints for ICL + - perf/x86/intel: Add Cooper Lake stepping to isolation_ucodes[] + - ALSA: usb-audio: Add quirks for MacroSilicon MS2100/MS2106 devices + - parisc: Make 8250_gsc driver dependend on CONFIG_PARISC + - parisc: Export iosapic_serial_irq() symbol for serial port driver + - parisc: Avoid printing the hardware path twice + - ext4: fix warning in 'ext4_da_release_space' + - ext4: fix BUG_ON() when directory entry has invalid rec_len + - KVM: x86: Mask off reserved bits in CPUID.8000001AH + - KVM: x86: Mask off reserved bits in CPUID.80000008H + - KVM: x86: emulator: em_sysexit should update ctxt->mode + - KVM: x86: emulator: introduce emulator_recalc_and_set_mode + - KVM: x86: emulator: update the emulation mode after CR0 write + - mtd: rawnand: gpmi: Set WAIT_FOR_READY timeout based on program/erase times + - drm/rockchip: dsi: Force synchronous probe + - drm/i915/sdvo: Filter out invalid outputs more sensibly + - drm/i915/sdvo: Setup DDC fully before output init + - wifi: brcmfmac: Fix potential buffer overflow in brcmf_fweh_event_worker() + - ipc: remove memcg accounting for sops objects in do_semtimedop() + - Linux 5.4.224 + * Focal update: v5.4.223 upstream stable release (LP: #1999179) + - can: j1939: transport: j1939_session_skb_drop_old(): + spin_unlock_irqrestore() before kfree_skb() + - can: kvaser_usb: Fix possible completions during init_completion + - ALSA: Use del_timer_sync() before freeing timer + - ALSA: au88x0: use explicitly signed char + - USB: add RESET_RESUME quirk for NVIDIA Jetson devices in RCM + - usb: dwc3: gadget: Stop processing more requests on IMI + - usb: dwc3: gadget: Don't set IMI for no_interrupt + - usb: bdc: change state when port disconnected + - usb: xhci: add XHCI_SPURIOUS_SUCCESS to ASM1042 despite being a V0.96 + controller + - mtd: rawnand: marvell: Use correct logic for nand-keep-config + - xhci: Remove device endpoints from bandwidth list when freeing the device + - tools: iio: iio_utils: fix digit calculation + - iio: light: tsl2583: Fix module unloading + - fbdev: smscufx: Fix several use-after-free bugs + - mac802154: Fix LQI recording + - drm/msm/dsi: fix memory corruption with too many bridges + - drm/msm/hdmi: fix memory corruption with too many bridges + - mmc: core: Fix kernel panic when remove non-standard SDIO card + - kernfs: fix use-after-free in __kernfs_remove + - perf auxtrace: Fix address filter symbol name match for modules + - s390/futex: add missing EX_TABLE entry to __futex_atomic_op() + - s390/pci: add missing EX_TABLE entries to + __pcistg_mio_inuser()/__pcilg_mio_inuser() + - xfs: finish dfops on every insert range shift iteration + - xfs: clear XFS_DQ_FREEING if we can't lock the dquot buffer to flush + - xfs: force the log after remapping a synchronous-writes file + - Xen/gntdev: don't ignore kernel unmapping error + - xen/gntdev: Prevent leaking grants + - mm,hugetlb: take hugetlb_lock before decrementing h->resv_huge_pages + - net: ieee802154: fix error return code in dgram_bind() + - media: v4l2: Fix v4l2_i2c_subdev_set_name function documentation + - drm/msm: Fix return type of mdp4_lvds_connector_mode_valid + - arc: iounmap() arg is volatile + - ALSA: ac97: fix possible memory leak in snd_ac97_dev_register() + - tipc: fix a null-ptr-deref in tipc_topsrv_accept + - net: netsec: fix error handling in netsec_register_mdio() + - x86/unwind/orc: Fix unreliable stack dump with gcov + - amd-xgbe: fix the SFP compliance codes check for DAC cables + - amd-xgbe: add the bit rate quirk for Molex cables + - kcm: annotate data-races around kcm->rx_psock + - kcm: annotate data-races around kcm->rx_wait + - net: fix UAF issue in nfqnl_nf_hook_drop() when ops_init() failed + - net: lantiq_etop: don't free skb when returning NETDEV_TX_BUSY + - tcp: fix indefinite deferral of RTO with SACK reneging + - can: mscan: mpc5xxx: mpc5xxx_can_probe(): add missing put_clock() in error + path + - PM: hibernate: Allow hybrid sleep to work with s2idle + - media: vivid: s_fbuf: add more sanity checks + - media: vivid: dev->bitmap_cap wasn't freed in all cases + - media: v4l2-dv-timings: add sanity checks for blanking values + - media: videodev2.h: V4L2_DV_BT_BLANKING_HEIGHT should check 'interlaced' + - i40e: Fix ethtool rx-flow-hash setting for X722 + - i40e: Fix VF hang when reset is triggered on another VF + - i40e: Fix flow-type by setting GL_HASH_INSET registers + - net: ksz884x: fix missing pci_disable_device() on error in pcidev_init() + - PM: domains: Fix handling of unavailable/disabled idle states + - ALSA: aoa: i2sbus: fix possible memory leak in i2sbus_add_dev() + - ALSA: aoa: Fix I2S device accounting + - openvswitch: switch from WARN to pr_warn + - net: ehea: fix possible memory leak in ehea_register_port() + - nh: fix scope used to find saddr when adding non gw nh + - net/mlx5e: Do not increment ESN when updating IPsec ESN state + - net/mlx5: Fix possible use-after-free in async command interface + - net: enetc: survive memory pressure without crashing + - can: rcar_canfd: rcar_canfd_handle_global_receive(): fix IRQ storm on global + FIFO receive + - Linux 5.4.223 + * Focal update: v5.4.222 upstream stable release (LP: #1997994) + - once: fix section mismatch on clang builds + - Linux 5.4.222 + * Focal update: v5.4.221 upstream stable release (LP: #1997993) + - xfs: open code insert range extent split helper + - xfs: rework insert range into an atomic operation + - xfs: rework collapse range into an atomic operation + - xfs: add a function to deal with corrupt buffers post-verifiers + - xfs: xfs_buf_corruption_error should take __this_address + - xfs: fix buffer corruption reporting when xfs_dir3_free_header_check fails + - xfs: check owner of dir3 data blocks + - xfs: check owner of dir3 blocks + - xfs: Use scnprintf() for avoiding potential buffer overflow + - xfs: remove the xfs_disk_dquot_t and xfs_dquot_t + - xfs: remove the xfs_dq_logitem_t typedef + - xfs: remove the xfs_qoff_logitem_t typedef + - xfs: Replace function declaration by actual definition + - xfs: factor out quotaoff intent AIL removal and memory free + - xfs: fix unmount hang and memory leak on shutdown during quotaoff + - xfs: preserve default grace interval during quotacheck + - xfs: Lower CIL flush limit for large logs + - xfs: Throttle commits on delayed background CIL push + - xfs: factor common AIL item deletion code + - xfs: tail updates only need to occur when LSN changes + - xfs: don't write a corrupt unmount record to force summary counter recalc + - xfs: trylock underlying buffer on dquot flush + - xfs: factor out a new xfs_log_force_inode helper + - xfs: reflink should force the log out if mounted with wsync + - xfs: move inode flush to the sync workqueue + - xfs: fix use-after-free on CIL context on shutdown + - ocfs2: clear dinode links count in case of error + - ocfs2: fix BUG when iput after ocfs2_mknod fails + - x86/microcode/AMD: Apply the patch early on every logical thread + - hwmon/coretemp: Handle large core ID value + - ata: ahci-imx: Fix MODULE_ALIAS + - ata: ahci: Match EM_MAX_SLOTS with SATA_PMP_MAX_PORTS + - KVM: arm64: vgic: Fix exit condition in scan_its_table() + - media: venus: dec: Handle the case where find_format fails + - [Config] updateconfigs for ARM64_ERRATUM_1742098 + - arm64: errata: Remove AES hwcap for COMPAT tasks + - r8152: add PID for the Lenovo OneLink+ Dock + - btrfs: fix processing of delayed data refs during backref walking + - btrfs: fix processing of delayed tree block refs during backref walking + - ACPI: extlog: Handle multiple records + - tipc: Fix recognition of trial period + - tipc: fix an information leak in tipc_topsrv_kern_subscr + - HID: magicmouse: Do not set BTN_MOUSE on double report + - net/atm: fix proc_mpc_write incorrect return value + - net: phy: dp83867: Extend RX strap quirk for SGMII mode + - net: sched: cake: fix null pointer access issue when cake_init() fails + - net: hns: fix possible memory leak in hnae_ae_register() + - iommu/vt-d: Clean up si_domain in the init_dmars() error path + - arm64: topology: move store_cpu_topology() to shared code + - riscv: topology: fix default topology reporting + - ACPI: video: Force backlight native for more TongFang devices + - Makefile.debug: re-enable debug info for .S files + - hv_netvsc: Fix race between VF offering and VF association message from host + - mm: /proc/pid/smaps_rollup: fix no vma's null-deref + - Linux 5.4.221 + * Focal update: v5.4.220 upstream stable release (LP: #1996812) + - ALSA: oss: Fix potential deadlock at unregistration + - ALSA: rawmidi: Drop register_mutex in snd_rawmidi_free() + - ALSA: usb-audio: Fix potential memory leaks + - ALSA: usb-audio: Fix NULL dererence at error path + - ALSA: hda/realtek: remove ALC289_FIXUP_DUAL_SPK for Dell 5530 + - ALSA: hda/realtek: Correct pin configs for ASUS G533Z + - ALSA: hda/realtek: Add quirk for ASUS GV601R laptop + - ALSA: hda/realtek: Add Intel Reference SSID to support headset keys + - mtd: rawnand: atmel: Unmap streaming DMA mappings + - cifs: destage dirty pages before re-reading them for cache=none + - cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message + - iio: dac: ad5593r: Fix i2c read protocol requirements + - iio: pressure: dps310: Refactor startup procedure + - iio: pressure: dps310: Reset chip after timeout + - usb: add quirks for Lenovo OneLink+ Dock + - can: kvaser_usb: Fix use of uninitialized completion + - can: kvaser_usb_leaf: Fix overread with an invalid command + - can: kvaser_usb_leaf: Fix TX queue out of sync after restart + - can: kvaser_usb_leaf: Fix CAN state after restart + - mmc: sdhci-sprd: Fix minimum clock limit + - fs: dlm: fix race between test_bit() and queue_work() + - fs: dlm: handle -EBUSY first in lock arg validation + - HID: multitouch: Add memory barriers + - quota: Check next/prev free block number after reading from quota file + - ASoC: wcd9335: fix order of Slimbus unprepare/disable + - regulator: qcom_rpm: Fix circular deferral regression + - RISC-V: Make port I/O string accessors actually work + - parisc: fbdev/stifb: Align graphics memory size to 4MB + - riscv: Allow PROT_WRITE-only mmap() + - riscv: Pass -mno-relax only on lld < 15.0.0 + - UM: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge + - powerpc/boot: Explicitly disable usage of SPE instructions + - fbdev: smscufx: Fix use-after-free in ufx_ops_open() + - btrfs: fix race between quota enable and quota rescan ioctl + - f2fs: increase the limit for reserve_root + - f2fs: fix to do sanity check on destination blkaddr during recovery + - f2fs: fix to do sanity check on summary info + - nilfs2: fix use-after-free bug of struct nilfs_root + - jbd2: wake up journal waiters in FIFO order, not LIFO + - ext4: avoid crash when inline data creation follows DIO write + - ext4: fix null-ptr-deref in ext4_write_info + - ext4: make ext4_lazyinit_thread freezable + - ext4: place buffer head allocation before handle start + - livepatch: fix race between fork and KLP transition + - ftrace: Properly unset FTRACE_HASH_FL_MOD + - ring-buffer: Allow splice to read previous partially read pages + - ring-buffer: Have the shortest_full queue be the shortest not longest + - ring-buffer: Check pending waiters when doing wake ups as well + - ring-buffer: Fix race between reset page and reading page + - media: cedrus: Set the platform driver data earlier + - KVM: x86/emulator: Fix handing of POP SS to correctly set interruptibility + - KVM: nVMX: Unconditionally purge queued/injected events on nested "exit" + - KVM: VMX: Drop bits 31:16 when shoving exception error code into VMCS + - gcov: support GCC 12.1 and newer compilers + - drm/nouveau: fix a use-after-free in nouveau_gem_prime_import_sg_table() + - selinux: use "grep -E" instead of "egrep" + - tracing: Disable interrupt or preemption before acquiring arch_spinlock_t + - userfaultfd: open userfaultfds with O_RDONLY + - sh: machvec: Use char[] for section boundaries + - ARM: 9247/1: mm: set readonly for MT_MEMORY_RO with ARM_LPAE + - nfsd: Fix a memory leak in an error handling path + - wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state() + - wifi: mac80211: allow bw change during channel switch in mesh + - bpftool: Fix a wrong type cast in btf_dumper_int + - x86/resctrl: Fix to restore to original value when re-enabling hardware + prefetch register + - wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse() + - spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume() + - spi: qup: add missing clk_disable_unprepare on error in + spi_qup_pm_resume_runtime() + - wifi: rtl8xxxu: Fix skb misuse in TX queue selection + - bpf: btf: fix truncated last_member_type_id in btf_struct_resolve + - wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration + - net: fs_enet: Fix wrong check in do_pd_setup + - bpf: Ensure correct locking around vulnerable function find_vpid() + - x86/microcode/AMD: Track patch allocation size explicitly + - spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe + - netfilter: nft_fib: Fix for rpath check with VRF devices + - spi: s3c64xx: Fix large transfers with DMA + - vhost/vsock: Use kvmalloc/kvfree for larger packets. + - sctp: handle the error returned from sctp_auth_asoc_init_active_key + - tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited + - net: rds: don't hold sock lock when cancelling work from + rds_tcp_reset_callbacks() + - bnx2x: fix potential memory leak in bnx2x_tpa_stop() + - net/ieee802154: reject zero-sized raw_sendmsg() + - once: add DO_ONCE_SLOW() for sleepable contexts + - net: mvpp2: fix mvpp2 debugfs leak + - drm: bridge: adv7511: fix CEC power down control register offset + - drm/mipi-dsi: Detach devices when removing the host + - platform/chrome: fix double-free in chromeos_laptop_prepare() + - platform/chrome: fix memory corruption in ioctl + - platform/x86: msi-laptop: Fix old-ec check for backlight registering + - platform/x86: msi-laptop: Fix resource cleanup + - drm: fix drm_mipi_dbi build errors + - drm/bridge: megachips: Fix a null pointer dereference bug + - ASoC: rsnd: Add check for rsnd_mod_power_on + - ALSA: hda: beep: Simplify keep-power-at-enable behavior + - drm/omap: dss: Fix refcount leak bugs + - mmc: au1xmmc: Fix an error handling path in au1xmmc_probe() + - ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API + - drm/msm/dpu: index dpu_kms->hw_vbif using vbif_idx + - ALSA: dmaengine: increment buffer pointer atomically + - mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe() + - ASoC: wm8997: Fix PM disable depth imbalance in wm8997_probe + - ASoC: wm5110: Fix PM disable depth imbalance in wm5110_probe + - ASoC: wm5102: Fix PM disable depth imbalance in wm5102_probe + - ALSA: hda/hdmi: Don't skip notification handling during PM operation + - memory: pl353-smc: Fix refcount leak bug in pl353_smc_probe() + - memory: of: Fix refcount leak bug in of_get_ddr_timings() + - soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe() + - soc: qcom: smem_state: Add refcounting for the 'state->of_node' + - ARM: dts: turris-omnia: Fix mpp26 pin name and comment + - ARM: dts: kirkwood: lsxl: fix serial line + - ARM: dts: kirkwood: lsxl: remove first ethernet port + - ARM: dts: exynos: correct s5k6a3 reset polarity on Midas family + - ARM: Drop CMDLINE_* dependency on ATAGS + - ARM: dts: exynos: fix polarity of VBUS GPIO of Origen + - iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX + - iio: adc: at91-sama5d2_adc: check return status for pressure and touch + - iio: adc: at91-sama5d2_adc: lock around oversampling and sample freq + - iio: inkern: only release the device node when done with it + - iio: ABI: Fix wrong format of differential capacitance channel ABI. + - clk: meson: Hold reference returned by of_get_parent() + - clk: oxnas: Hold reference returned by of_get_parent() + - clk: berlin: Add of_node_put() for of_get_parent() + - clk: tegra: Fix refcount leak in tegra210_clock_init + - clk: tegra: Fix refcount leak in tegra114_clock_init + - clk: tegra20: Fix refcount leak in tegra20_clock_init + - HSI: omap_ssi: Fix refcount leak in ssi_probe + - HSI: omap_ssi_port: Fix dma_map_sg error check + - media: exynos4-is: fimc-is: Add of_node_put() when breaking out of loop + - tty: xilinx_uartps: Fix the ignore_status + - media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init + - RDMA/rxe: Fix "kernel NULL pointer dereference" error + - RDMA/rxe: Fix the error caused by qp->sk + - misc: ocxl: fix possible refcount leak in afu_ioctl() + - dyndbg: fix module.dyndbg handling + - dyndbg: let query-modname override actual module name + - mtd: devices: docg3: check the return value of devm_ioremap() in the probe + - RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall. + - ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting() + - ata: fix ata_id_has_devslp() + - ata: fix ata_id_has_ncq_autosense() + - ata: fix ata_id_has_dipm() + - mtd: rawnand: meson: fix bit map use in meson_nfc_ecc_correct() + - md/raid5: Ensure stripe_fill happens on non-read IO with journal + - xhci: Don't show warning for reinit on known broken suspend + - usb: gadget: function: fix dangling pnp_string in f_printer.c + - drivers: serial: jsm: fix some leaks in probe + - tty: serial: fsl_lpuart: disable dma rx/tx use flags in lpuart_dma_shutdown + - phy: qualcomm: call clk_disable_unprepare in the error handling + - staging: vt6655: fix some erroneous memory clean-up loops + - firmware: google: Test spinlock on panic path to avoid lockups + - serial: 8250: Fix restoring termios speed after suspend + - scsi: libsas: Fix use-after-free bug in smp_execute_task_sg() + - fsi: core: Check error number after calling ida_simple_get + - mfd: intel_soc_pmic: Fix an error handling path in + intel_soc_pmic_i2c_probe() + - mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq() + - mfd: lp8788: Fix an error handling path in lp8788_probe() + - mfd: lp8788: Fix an error handling path in lp8788_irq_init() and + lp8788_irq_init() + - mfd: fsl-imx25: Fix check for platform_get_irq() errors + - mfd: sm501: Add check for platform_driver_register() + - clk: mediatek: mt8183: mfgcfg: Propagate rate changes to parent + - dmaengine: ioat: stop mod_timer from resurrecting deleted timer in + __cleanup() + - spmi: pmic-arb: correct duplicate APID to PPID mapping logic + - clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration + - clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe + - clk: ast2600: BCLK comes from EPLL + - mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg + - powerpc/math_emu/efp: Include module.h + - powerpc/sysdev/fsl_msi: Add missing of_node_put() + - powerpc/pci_dn: Add missing of_node_put() + - powerpc/powernv: add missing of_node_put() in opal_export_attrs() + - x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition + - powerpc/64s: Fix GENERIC_CPU build flags for PPC970 / G5 + - powerpc: Fix SPE Power ISA properties for e500v1 platforms + - cgroup/cpuset: Enable update_tasks_cpumask() on top_cpuset + - iommu/omap: Fix buffer overflow in debugfs + - crypto: akcipher - default implementation for setting a private key + - crypto: ccp - Release dma channels before dmaengine unrgister + - iommu/iova: Fix module config properly + - kbuild: remove the target in signal traps when interrupted + - crypto: cavium - prevent integer overflow loading firmware + - f2fs: fix race condition on setting FI_NO_EXTENT flag + - ACPI: video: Add Toshiba Satellite/Portege Z830 quirk + - MIPS: BCM47XX: Cast memcmp() of function to (void *) + - powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue + - thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to + avoid crash + - NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data + - wifi: brcmfmac: fix invalid address access when enabling SCAN log level + - bpftool: Clear errno after libcap's checks + - openvswitch: Fix double reporting of drops in dropwatch + - openvswitch: Fix overreporting of drops in dropwatch + - tcp: annotate data-race around tcp_md5sig_pool_populated + - wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg() + - xfrm: Update ipcomp_scratches with NULL when freed + - wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit() + - Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create() + - Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times + - can: bcm: check the result of can_send() in bcm_can_tx() + - wifi: rt2x00: don't run Rt5592 IQ calibration on MT7620 + - wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620 + - wifi: rt2x00: set VGC gain for both chains of MT7620 + - wifi: rt2x00: set SoC wmac clock register + - wifi: rt2x00: correctly set BBP register 86 for MT7620 + - net: If sock is dead don't access sock's sk_wq in sk_stream_wait_memory + - Bluetooth: L2CAP: Fix user-after-free + - drm/nouveau/nouveau_bo: fix potential memory leak in nouveau_bo_alloc() + - drm: Use size_t type for len variable in drm_copy_field() + - drm: Prevent drm_copy_field() to attempt copying a NULL pointer + - drm/amd/display: fix overflow on MIN_I64 definition + - drm/vc4: vec: Fix timings for VEC modes + - drm: panel-orientation-quirks: Add quirk for Anbernic Win600 + - platform/x86: msi-laptop: Change DMI match / alias strings to fix module + autoloading + - drm/amdgpu: fix initial connector audio value + - mmc: sdhci-msm: add compatible string check for sdm670 + - ARM: dts: imx7d-sdb: config the max pressure for tsc2046 + - ARM: dts: imx6q: add missing properties for sram + - ARM: dts: imx6dl: add missing properties for sram + - ARM: dts: imx6qp: add missing properties for sram + - ARM: dts: imx6sl: add missing properties for sram + - ARM: dts: imx6sll: add missing properties for sram + - ARM: dts: imx6sx: add missing properties for sram + - btrfs: scrub: try to fix super block errors + - clk: zynqmp: Fix stack-out-of-bounds in strncpy` + - media: cx88: Fix a null-ptr-deref bug in buffer_prepare() + - clk: zynqmp: pll: rectify rate rounding in zynqmp_pll_round_rate + - scsi: 3w-9xxx: Avoid disabling device if failing to enable it + - nbd: Fix hung when signal interrupts nbd_start_device_ioctl() + - power: supply: adp5061: fix out-of-bounds read in adp5061_get_chg_type() + - staging: vt6655: fix potential memory leak + - ata: libahci_platform: Sanity check the DT child nodes number + - bcache: fix set_at_max_writeback_rate() for multiple attached devices + - HID: roccat: Fix use-after-free in roccat_read() + - md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d + - usb: host: xhci: Fix potential memory leak in xhci_alloc_stream_info() + - usb: musb: Fix musb_gadget.c rxstate overflow bug + - Revert "usb: storage: Add quirk for Samsung Fit flash" + - staging: rtl8723bs: fix a potential memory leak in rtw_init_cmd_priv() + - nvme: copy firmware_rev on each init + - nvmet-tcp: add bounds check on Transfer Tag + - usb: idmouse: fix an uninit-value in idmouse_open + - clk: bcm2835: Make peripheral PLLC critical + - perf intel-pt: Fix segfault in intel_pt_print_info() with uClibc + - net: ieee802154: return -EINVAL for unknown addr type + - Revert "net/ieee802154: reject zero-sized raw_sendmsg()" + - net/ieee802154: don't warn zero-sized raw_sendmsg() + - ext4: continue to expand file system when the target size doesn't reach + - efi: libstub: drop pointless get_memory_map() call + - inet: fully convert sk->sk_rx_dst to RCU rules + - thermal: intel_powerclamp: Use first online CPU as control_cpu + - Linux 5.4.220 + * Focal update: v5.4.219 upstream stable release (LP: #1996804) + - Linux 5.4.219 + + -- Luke Nowakowski-Krijger Wed, 25 Jan 2023 10:56:48 -0800 + +linux-oracle (5.4.0-1092.101) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1092.101 -proposed tracker (LP: #2001959) + + [ Ubuntu: 5.4.0-137.154 ] + + * focal/linux: 5.4.0-137.154 -proposed tracker (LP: #2001969) + * CVE-2022-3643 + - xen/netback: Ensure protocol headers don't fall in the non-linear area + * CVE-2022-43945 + - NFSD: Cap rsize_bop result based on send buffer size + * CVE-2022-45934 + - Bluetooth: L2CAP: Fix u8 overflow + * CVE-2022-42896 + - Bluetooth: L2CAP: Fix accepting connection request for invalid SPSM + - Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm + + -- Thadeu Lima de Souza Cascardo Tue, 10 Jan 2023 11:19:33 -0300 + +linux-oracle (5.4.0-1091.100) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1091.100 -proposed tracker (LP: #1997824) + + [ Ubuntu: 5.4.0-136.153 ] + + * focal/linux: 5.4.0-136.153 -proposed tracker (LP: #1997835) + * Expose built-in trusted and revoked certificates (LP: #1996892) + - [Packaging] Expose built-in trusted and revoked certificates + * [UBUNTU 20.04] KVM: PV: ext call delivered twice when receiver in PSW wait + (LP: #1995941) + - KVM: s390: pv: don't present the ecall interrupt twice + * [UBUNTU 20.04] boot: Add s390x secure boot trailer (LP: #1996071) + - s390/boot: add secure boot trailer + * Fix rfkill causing soft blocked wifi (LP: #1996198) + - platform/x86: hp_wmi: Fix rfkill causing soft blocked wifi + * md: Replace snprintf with scnprintf (LP: #1993315) + - md: Replace snprintf with scnprintf + * input/keyboard: the keyboard on some Asus laptops can't work (LP: #1992266) + - ACPI: resource: Skip IRQ override on Asus Vivobook K3402ZA/K3502ZA + - ACPI: resource: Add ASUS model S5402ZA to quirks + * Focal update: v5.4.218 upstream stable release (LP: #1995530) + - mm: pagewalk: Fix race between unmap and page walker + - perf tools: Fixup get_current_dir_name() compilation + - firmware: arm_scmi: Add SCMI PM driver remove routine + - dmaengine: xilinx_dma: cleanup for fetching xlnx,num-fstores property + - dmaengine: xilinx_dma: Report error in case of dma_set_mask_and_coherent API + failure + - ARM: dts: fix Moxa SDIO 'compatible', remove 'sdhci' misnomer + - scsi: qedf: Fix a UAF bug in __qedf_probe() + - net/ieee802154: fix uninit value bug in dgram_sendmsg + - um: Cleanup syscall_handler_t cast in syscalls_32.h + - um: Cleanup compiler warning in arch/x86/um/tls_32.c + - arch: um: Mark the stack non-executable to fix a binutils warning + - usb: mon: make mmapped memory read only + - USB: serial: ftdi_sio: fix 300 bps rate for SIO + - mmc: core: Replace with already defined values for readability + - mmc: core: Terminate infinite loop in SD-UHS voltage switch + - rpmsg: qcom: glink: replace strncpy() with strscpy_pad() + - nilfs2: fix leak of nilfs_root in case of writer thread creation failure + - nilfs2: replace WARN_ONs by nilfs_error for checkpoint acquisition failure + - ceph: don't truncate file in atomic_open + - random: clamp credited irq bits to maximum mixed + - ALSA: hda: Fix position reporting on Poulsbo + - efi: Correct Macmini DMI match in uefi cert quirk + - USB: serial: qcserial: add new usb-id for Dell branded EM7455 + - random: restore O_NONBLOCK support + - random: avoid reading two cache lines on irq randomness + - random: use expired timer rather than wq for mixing fast pool + - Input: xpad - add supported devices as contributed on github + - Input: xpad - fix wireless 360 controller breaking after suspend + - Linux 5.4.218 + * Focal update: v5.4.217 upstream stable release (LP: #1995528) + - xfs: fix misuse of the XFS_ATTR_INCOMPLETE flag + - xfs: introduce XFS_MAX_FILEOFF + - xfs: truncate should remove all blocks, not just to the end of the page + cache + - xfs: fix s_maxbytes computation on 32-bit kernels + - xfs: fix IOCB_NOWAIT handling in xfs_file_dio_aio_read + - xfs: refactor remote attr value buffer invalidation + - xfs: fix memory corruption during remote attr value buffer invalidation + - xfs: move incore structures out of xfs_da_format.h + - xfs: streamline xfs_attr3_leaf_inactive + - xfs: fix uninitialized variable in xfs_attr3_leaf_inactive + - xfs: remove unused variable 'done' + - Makefile.extrawarn: Move -Wcast-function-type-strict to W=1 + - docs: update mediator information in CoC docs + - Linux 5.4.217 + * Focal update: v5.4.216 upstream stable release (LP: #1995526) + - uas: add no-uas quirk for Hiksemi usb_disk + - usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS + - uas: ignore UAS for Thinkplus chips + - net: usb: qmi_wwan: Add new usb-id for Dell branded EM7455 + - clk: ingenic-tcu: Properly enable registers before accessing timers + - ARM: dts: integrator: Tag PCI host with device_type + - ntfs: fix BUG_ON in ntfs_lookup_inode_by_name() + - libata: add ATA_HORKAGE_NOLPM for Pioneer BDR-207M and BDR-205 + - mmc: moxart: fix 4-bit bus width and remove 8-bit bus width + - mm/page_alloc: fix race condition between build_all_zonelists and page + allocation + - mm: prevent page_frag_alloc() from corrupting the memory + - mm/migrate_device.c: flush TLB while holding PTL + - mm: fix madivse_pageout mishandling on non-LRU page + - media: dvb_vb2: fix possible out of bound access + - ARM: dts: Move am33xx and am43xx mmc nodes to sdhci-omap driver + - ARM: dts: am33xx: Fix MMCHS0 dma properties + - soc: sunxi: sram: Actually claim SRAM regions + - soc: sunxi: sram: Prevent the driver from being unbound + - soc: sunxi_sram: Make use of the helper function + devm_platform_ioremap_resource() + - soc: sunxi: sram: Fix probe function ordering issues + - soc: sunxi: sram: Fix debugfs info for A64 SRAM C + - Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in + suspend/resume time" + - Input: melfas_mip4 - fix return value check in mip4_probe() + - usbnet: Fix memory leak in usbnet_disconnect() + - nvme: add new line after variable declatation + - nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices + - selftests: Fix the if conditions of in test_extra_filter() + - clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks + - clk: iproc: Do not rely on node name for correct PLL setup + - Linux 5.4.216 + * Focal update: v5.4.215 upstream stable release (LP: #1993203) + - of: fdt: fix off-by-one error in unflatten_dt_nodes() + - NFSv4: Turn off open-by-filehandle and NFS re-export for NFSv4.0 + - gpio: mpc8xxx: Fix support for IRQ_TYPE_LEVEL_LOW flow_type in mpc85xx + - drm/meson: Correct OSD1 global alpha value + - drm/meson: Fix OSD1 RGB to YCbCr coefficient + - parisc: ccio-dma: Add missing iounmap in error path in ccio_probe() + - ALSA: pcm: oss: Fix race at SNDCTL_DSP_SYNC + - task_stack, x86/cea: Force-inline stack helpers + - tracing: hold caller_addr to hardirq_{enable,disable}_ip + - cifs: revalidate mapping when doing direct writes + - cifs: don't send down the destination address to sendmsg for a SOCK_STREAM + - MAINTAINERS: add Chandan as xfs maintainer for 5.4.y + - iomap: iomap that extends beyond EOF should be marked dirty + - ASoC: nau8824: Fix semaphore unbalance at error paths + - regulator: pfuze100: Fix the global-out-of-bounds access in + pfuze100_regulator_probe() + - rxrpc: Fix local destruction being repeated + - rxrpc: Fix calc of resend age + - ALSA: hda/sigmatel: Keep power up while beep is enabled + - ALSA: hda/tegra: Align BDL entry to 4KB boundary + - net: usb: qmi_wwan: add Quectel RM520N + - afs: Return -EAGAIN, not -EREMOTEIO, when a file already locked + - MIPS: OCTEON: irq: Fix octeon_irq_force_ciu_mapping() + - mksysmap: Fix the mismatch of 'L0' symbols in System.map + - video: fbdev: pxa3xx-gcu: Fix integer overflow in pxa3xx_gcu_write + - cgroup: Add missing cpus_read_lock() to cgroup_attach_task_all() + - ALSA: hda/sigmatel: Fix unused variable warning for beep power change + - usb: dwc3: gadget: Avoid starting DWC3 gadget during UDC unbind + - usb: dwc3: Issue core soft reset before enabling run/stop + - usb: dwc3: gadget: Prevent repeat pullup() + - usb: dwc3: gadget: Refactor pullup() + - usb: dwc3: gadget: Don't modify GEVNTCOUNT in pullup() + - usb: dwc3: gadget: Avoid duplicate requests to enable Run/Stop + - usb: xhci-mtk: get the microframe boundary for ESIT + - usb: xhci-mtk: add only one extra CS for FS/LS INTR + - usb: xhci-mtk: use @sch_tt to check whether need do TT schedule + - usb: xhci-mtk: add a function to (un)load bandwidth info + - usb: xhci-mtk: add some schedule error number + - usb: xhci-mtk: allow multiple Start-Split in a microframe + - usb: xhci-mtk: relax TT periodic bandwidth allocation + - wifi: mac80211: Fix UAF in ieee80211_scan_rx() + - tty/serial: atmel: RS485 & ISO7816: wait for TXRDY before sending data + - serial: atmel: remove redundant assignment in rs485_config + - tty: serial: atmel: Preserve previous USART mode if RS485 disabled + - usb: add quirks for Lenovo OneLink+ Dock + - usb: gadget: udc-xilinx: replace memcpy with memcpy_toio + - usb: cdns3: fix issue with rearming ISO OUT endpoint + - Revert "usb: add quirks for Lenovo OneLink+ Dock" + - Revert "usb: gadget: udc-xilinx: replace memcpy with memcpy_toio" + - USB: core: Fix RST error in hub.c + - USB: serial: option: add Quectel BG95 0x0203 composition + - USB: serial: option: add Quectel RM520N + - ALSA: hda/tegra: set depop delay for tegra + - ALSA: hda: add Intel 5 Series / 3400 PCI DID + - ALSA: hda/realtek: Add quirk for Huawei WRT-WX9 + - ALSA: hda/realtek: Re-arrange quirk table entries + - ALSA: hda/realtek: Add pincfg for ASUS G513 HP jack + - ALSA: hda/realtek: Add pincfg for ASUS G533Z HP jack + - ALSA: hda/realtek: Add quirk for ASUS GA503R laptop + - ALSA: hda/realtek: Enable 4-speaker output Dell Precision 5530 laptop + - efi: libstub: check Shim mode using MokSBStateRT + - mm/slub: fix to return errno if kmalloc() fails + - arm64: dts: rockchip: Pull up wlan wake# on Gru-Bob + - arm64: dts: rockchip: Set RK3399-Gru PCLK_EDP to 24 MHz + - arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma + - netfilter: nf_conntrack_sip: fix ct_sip_walk_headers + - netfilter: nf_conntrack_irc: Tighten matching on DCC message + - netfilter: nfnetlink_osf: fix possible bogus match in nf_osf_find() + - iavf: Fix cached head and tail value for iavf_get_tx_pending + - ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header + - net: team: Unsync device addresses on ndo_stop + - MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko + - MIPS: Loongson32: Fix PHY-mode being left unspecified + - iavf: Fix bad page state + - i40e: Fix set max_tx_rate when it is lower than 1 Mbps + - of: mdio: Add of_node_put() when breaking out of for_each_xx + - net/sched: taprio: avoid disabling offload when it was never enabled + - net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child + qdiscs + - netfilter: ebtables: fix memory leak when blob is malformed + - can: gs_usb: gs_can_open(): fix race dev->can.state condition + - perf jit: Include program header in ELF files + - perf kcore_copy: Do not check /proc/modules is unchanged + - net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD + - net: sched: fix possible refcount leak in tc_new_tfilter() + - serial: Create uart_xmit_advance() + - serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting + - serial: tegra-tcu: Use uart_xmit_advance(), fixes icount.tx accounting + - s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup + - usb: xhci-mtk: fix issue of out-of-bounds array access + - cifs: always initialize struct msghdr smb_msg completely + - Drivers: hv: Never allocate anything besides framebuffer from framebuffer + memory region + - drm/amd/display: Limit user regamma to a valid value + - drm/rockchip: Fix return type of cdn_dp_connector_mode_valid + - workqueue: don't skip lockdep work dependency in cancel_work_sync() + - ext4: fix bug in extents parsing when eh_entries == 0 and eh_depth > 0 + - xfs: replace -EIO with -EFSCORRUPTED for corrupt metadata + - xfs: slightly tweak an assert in xfs_fs_map_blocks + - xfs: add missing assert in xfs_fsmap_owner_from_rmap + - xfs: range check ri_cnt when recovering log items + - xfs: attach dquots and reserve quota blocks during unwritten conversion + - xfs: convert EIO to EFSCORRUPTED when log contents are invalid + - xfs: constify the buffer pointer arguments to error functions + - xfs: always log corruption errors + - xfs: fix some memory leaks in log recovery + - xfs: stabilize insert range start boundary to avoid COW writeback race + - xfs: use bitops interface for buf log item AIL flag check + - xfs: refactor agfl length computation function + - xfs: split the sunit parameter update into two parts + - xfs: don't commit sunit/swidth updates to disk if that would cause repair + failures + - xfs: fix an ABBA deadlock in xfs_rename + - xfs: fix use-after-free when aborting corrupt attr inactivation + - ext4: make directory inode spreading reflect flexbg size + - Linux 5.4.215 + * Focal update: v5.4.214 upstream stable release (LP: #1993196) + - drm/msm/rd: Fix FIFO-full deadlock + - HID: ishtp-hid-clientHID: ishtp-hid-client: Fix comment typo + - hid: intel-ish-hid: ishtp: Fix ishtp client sending disordered message + - tg3: Disable tg3 device on system reboot to avoid triggering AER + - ieee802154: cc2520: add rc code in cc2520_tx() + - Input: iforce - add support for Boeder Force Feedback Wheel + - nvmet-tcp: fix unhandled tcp states in nvmet_tcp_state_change() + - perf/arm_pmu_platform: fix tests for platform_get_irq() failure + - platform/x86: acer-wmi: Acer Aspire One AOD270/Packard Bell Dot keymap fixes + - usb: storage: Add ASUS <0x0b05:0x1932> to IGNORE_UAS + - mm: Fix TLB flush for not-first PFNMAP mappings in unmap_region() + - net: dp83822: disable rx error interrupt + - soc: fsl: select FSL_GUTS driver for DPIO + - tracefs: Only clobber mode/uid/gid on remount if asked + - Linux 5.4.214 + * Focal update: v5.4.213 upstream stable release (LP: #1992211) + - efi: capsule-loader: Fix use-after-free in efi_capsule_write + - wifi: iwlegacy: 4965: corrected fix for potential off-by-one overflow in + il4965_rs_fill_link_cmd() + - fs: only do a memory barrier for the first set_buffer_uptodate() + - Revert "mm: kmemleak: take a full lowmem check in kmemleak_*_phys()" + - net: dp83822: disable false carrier interrupt + - drm/msm/dsi: fix the inconsistent indenting + - drm/msm/dsi: Fix number of regulators for msm8996_dsi_cfg + - platform/x86: pmc_atom: Fix SLP_TYPx bitfield mask + - iio: adc: mcp3911: make use of the sign bit + - ieee802154/adf7242: defer destroy_workqueue call + - wifi: cfg80211: debugfs: fix return type in ht40allow_map_read() + - Revert "xhci: turn off port power in shutdown" + - net: sched: tbf: don't call qdisc_put() while holding tree lock + - ethernet: rocker: fix sleep in atomic context bug in neigh_timer_handler + - kcm: fix strp_init() order and cleanup + - sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb + - tcp: annotate data-race around challenge_timestamp + - Revert "sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb" + - net/smc: Remove redundant refcount increase + - serial: fsl_lpuart: RS485 RTS polariy is inverse + - staging: rtl8712: fix use after free bugs + - powerpc: align syscall table for ppc32 + - vt: Clear selection before changing the font + - tty: serial: lpuart: disable flow control while waiting for the transmit + engine to complete + - Input: iforce - wake up after clearing IFORCE_XMIT_RUNNING flag + - iio: adc: mcp3911: use correct formula for AD conversion + - misc: fastrpc: fix memory corruption on probe + - misc: fastrpc: fix memory corruption on open + - USB: serial: ftdi_sio: add Omron CS1W-CIF31 device id + - binder: fix UAF of ref->proc caused by race condition + - usb: dwc3: qcom: fix use-after-free on runtime-PM wakeup + - drm/i915/reg: Fix spelling mistake "Unsupport" -> "Unsupported" + - clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops + - Revert "clk: core: Honor CLK_OPS_PARENT_ENABLE for clk gate ops" + - clk: core: Fix runtime PM sequence in clk_core_unprepare() + - Input: rk805-pwrkey - fix module autoloading + - clk: bcm: rpi: Fix error handling of raspberrypi_fw_get_rate + - hwmon: (gpio-fan) Fix array out of bounds access + - gpio: pca953x: Add mutex_lock for regcache sync in PM + - thunderbolt: Use the actual buffer in tb_async_error() + - xhci: Add grace period after xHC start to prevent premature runtime suspend. + - USB: serial: cp210x: add Decagon UCA device id + - USB: serial: option: add support for OPPO R11 diag port + - USB: serial: option: add Quectel EM060K modem + - USB: serial: option: add support for Cinterion MV32-WA/WB RmNet mode + - usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles + - usb: dwc2: fix wrong order of phy_power_on and phy_init + - USB: cdc-acm: Add Icom PMR F3400 support (0c26:0020) + - usb-storage: Add ignore-residue quirk for NXP PN7462AU + - s390/hugetlb: fix prepare_hugepage_range() check for 2 GB hugepages + - s390: fix nospec table alignments + - USB: core: Prevent nested device-reset calls + - usb: gadget: mass_storage: Fix cdrom data transfers on MAC-OS + - driver core: Don't probe devices after bus_type.match() probe deferral + - wifi: mac80211: Don't finalize CSA in IBSS mode if state is disconnected + - net: mac802154: Fix a condition in the receive path + - ALSA: seq: oss: Fix data-race for max_midi_devs access + - ALSA: seq: Fix data-race at module auto-loading + - drm/i915/glk: ECS Liva Q2 needs GLK HDMI port timing quirk + - btrfs: harden identification of a stale device + - usb: dwc3: fix PHY disable sequence + - usb: dwc3: disable USB core PHY management + - USB: serial: ch341: fix lost character on LCR updates + - USB: serial: ch341: fix disabled rx timer on older devices + - scsi: megaraid_sas: Fix double kfree() + - drm/gem: Fix GEM handle release errors + - drm/amdgpu: Check num_gfx_rings for gfx v9_0 rb setup. + - drm/radeon: add a force flush to delay work when radeon + - parisc: ccio-dma: Handle kmalloc failure in ccio_init_resources() + - parisc: Add runtime check to prevent PA2.0 kernels on PA1.x machines + - arm64: cacheinfo: Fix incorrect assignment of signed error value to unsigned + fw_level + - fbdev: chipsfb: Add missing pci_disable_device() in chipsfb_pci_init() + - drm/amdgpu: mmVM_L2_CNTL3 register not initialized correctly + - ALSA: emu10k1: Fix out of bounds access in snd_emu10k1_pcm_channel_alloc() + - ALSA: aloop: Fix random zeros in capture data when using jiffies timer + - ALSA: usb-audio: Fix an out-of-bounds bug in + __snd_usb_parse_audio_interface() + - kprobes: Prohibit probes in gate area + - debugfs: add debugfs_lookup_and_remove() + - nvmet: fix a use-after-free + - scsi: mpt3sas: Fix use-after-free warning + - scsi: lpfc: Add missing destroy_workqueue() in error path + - cgroup: Optimize single thread migration + - cgroup: Elide write-locking threadgroup_rwsem when updating csses on an + empty subtree + - cgroup: Fix threadgroup_rwsem <-> cpus_read_lock() deadlock + - smb3: missing inode locks in punch hole + - ARM: dts: imx6qdl-kontron-samx6i: remove duplicated node + - regulator: core: Clean up on enable failure + - RDMA/cma: Fix arguments order in net device validation + - soc: brcmstb: pm-arm: Fix refcount leak and __iomem leak bugs + - RDMA/hns: Fix supported page size + - netfilter: br_netfilter: Drop dst references before setting. + - rxrpc: Fix an insufficiently large sglist in rxkad_verify_packet_2() + - afs: Use the operation issue time instead of the reply time for callbacks + - sch_sfb: Don't assume the skb is still around after enqueueing to child + - tipc: fix shift wrapping bug in map_get() + - i40e: Fix kernel crash during module removal + - RDMA/siw: Pass a pointer to virt_to_page() + - ipv6: sr: fix out-of-bounds read when setting HMAC data. + - RDMA/mlx5: Set local port to one when accessing counters + - nvme-tcp: fix UAF when detecting digest errors + - tcp: fix early ETIMEDOUT after spurious non-SACK RTO + - sch_sfb: Also store skb len before calling child enqueue + - x86/nospec: Fix i386 RSB stuffing + - MIPS: loongson32: ls1c: Fix hang during startup + - Linux 5.4.213 + * CVE-2022-2663 + - netfilter: nf_conntrack_irc: Fix forged IP logic + * CVE-2022-3061 + - video: fbdev: i740fb: Error out if 'pixclock' equals zero + + -- Joseph Salisbury Wed, 30 Nov 2022 11:57:19 -0500 + +linux-oracle (5.4.0-1090.99) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1090.99 -proposed tracker (LP: #1997402) + + [ Ubuntu: 5.4.0-135.152 ] + + * focal/linux: 5.4.0-135.152 -proposed tracker (LP: #1997412) + * containerd sporadic timeouts (LP: #1996678) + - epoll: call final ep_events_available() check under the lock + - epoll: check for events when removing a timed out thread from the wait queue + - Revert "fs: check FMODE_LSEEK to control internal pipe splicing" + * CVE-2022-3621 + - nilfs2: fix NULL pointer dereference at nilfs_bmap_lookup_at_level() + * CVE-2022-3565 + - mISDN: fix use-after-free bugs in l1oip timer handlers + * CVE-2022-3566 + - tcp: Fix data races around icsk->icsk_af_ops. + * CVE-2022-3567 + - ipv6: annotate some data-races around sk->sk_prot + - ipv6: Fix data races around sk->sk_prot. + * CVE-2022-3564 + - Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu + * CVE-2022-3524 + - tcp/udp: Fix memory leak in ipv6_renew_options(). + * CVE-2022-3594 + - r8152: Rate limit overflow messages + * CVE-2022-42703 + - mm/rmap.c: don't reuse anon_vma if we just want a copy + + -- Thadeu Lima de Souza Cascardo Thu, 24 Nov 2022 23:26:26 -0300 + +linux-oracle (5.4.0-1087.96) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1087.96 -proposed tracker (LP: #1992054) + + [ Ubuntu: 5.4.0-132.148 ] + + * CVE-2022-42719 + - mac80211: mlme: find auth challenge directly + - wifi: mac80211: don't parse mbssid in assoc response + - wifi: mac80211: fix MBSSID parsing use-after-free + * iavf: SR-IOV VFs error with no traffic flow when MTU greater than 1500 + (LP: #1983656) + - iavf: Fix set max MTU size with port VLAN and jumbo frames + - i40e: Fix VF set max MTU size + * fib_nexthop_nongw.sh from ubuntu_kernel_selftests failed on B-5.4 + (LP: #1990800) + - SAUCE: selftests/net: skipping tests for older ip command releases + * CVE-2022-29901 + - Revert "x86/speculation: Add RSB VM Exit protections" + - Revert "x86/cpu: Add a steppings field to struct x86_cpu_id" + - x86/devicetable: Move x86 specific macro out of generic code + - x86/cpu: Add consistent CPU match macros + - x86/cpu: Add a steppings field to struct x86_cpu_id + - x86/kvm/vmx: Make noinstr clean + - x86/cpufeatures: Move RETPOLINE flags to word 11 + - x86/bugs: Report AMD retbleed vulnerability + - x86/bugs: Add AMD retbleed= boot parameter + - x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value + - x86/entry: Remove skip_r11rcx + - x86/entry: Add kernel IBRS implementation + - x86/bugs: Optimize SPEC_CTRL MSR writes + - x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS + - x86/bugs: Split spectre_v2_select_mitigation() and + spectre_v2_user_select_mitigation() + - x86/bugs: Report Intel retbleed vulnerability + - intel_idle: Disable IBRS during long idle + - x86/speculation: Change FILL_RETURN_BUFFER to work with objtool + - x86/speculation: Fix RSB filling with CONFIG_RETPOLINE=n + - x86/speculation: Fix firmware entry SPEC_CTRL handling + - x86/speculation: Fix SPEC_CTRL write on SMT state change + - x86/speculation: Use cached host SPEC_CTRL value for guest entry/exit + - x86/speculation: Remove x86_spec_ctrl_mask + - KVM/VMX: Use TEST %REG,%REG instead of CMP $0,%REG in vmenter.S + - KVM/nVMX: Use __vmx_vcpu_run in nested_vmx_check_vmentry_hw + - KVM: VMX: Flatten __vmx_vcpu_run() + - KVM: VMX: Convert launched argument to flags + - KVM: VMX: Prevent guest RSB poisoning attacks with eIBRS + - KVM: VMX: Fix IBRS handling after vmexit + - x86/speculation: Fill RSB on vmexit for IBRS + - x86/common: Stamp out the stepping madness + - x86/cpu/amd: Enumerate BTC_NO + - x86/bugs: Add Cannon lake to RETBleed affected CPU list + - x86/speculation: Disable RRSBA behavior + - x86/speculation: Use DECLARE_PER_CPU for x86_spec_ctrl_current + - x86/bugs: Warn when "ibrs" mitigation is selected on Enhanced IBRS parts + - x86/speculation: Add RSB VM Exit protections + * ACPI: processor idle: Practically limit "Dummy wait" workaround to old Intel + systems (LP: #1990985) + - ACPI: processor_idle: Skip dummy wait if kernel is in guest + - ACPI: processor idle: Practically limit "Dummy wait" workaround to old Intel + systems + * cgroup: all controllers mounted when using 'cgroup_no_v1=' (LP: #1988584) + - cgroup-v1: add disabled controller check in cgroup1_parse_param() + * Focal update: v5.4.212 upstream stable release (LP: #1991156) + - audit: fix potential double free on error path from fsnotify_add_inode_mark + - parisc: Fix exception handler for fldw and fstw instructions + - kernel/sys_ni: add compat entry for fadvise64_64 + - usb: cdns3: Fix issue for clear halt endpoint + - pinctrl: amd: Don't save/restore interrupt status and wake status bits + - sched/deadline: Unthrottle PI boosted threads while enqueuing + - sched/deadline: Fix stale throttling on de-/boosted tasks + - sched/deadline: Fix priority inheritance with multiple scheduling classes + - kernel/sched: Remove dl_boosted flag comment + - xfrm: fix refcount leak in __xfrm_policy_check() + - SUNRPC: RPC level errors should set task->tk_rpc_status + - rose: check NULL rose_loopback_neigh->loopback + - net/mlx5e: Properly disable vlan strip on non-UL reps + - net: moxa: get rid of asymmetry in DMA mapping/unmapping + - bonding: 802.3ad: fix no transmission of LACPDUs + - net: ipvtap - add __init/__exit annotations to module init/exit funcs + - netfilter: ebtables: reject blobs that don't provide all entry points + - bnxt_en: fix NQ resource accounting during vf creation on 57500 chips + - netfilter: nft_payload: report ERANGE for too long offset and length + - netfilter: nft_payload: do not truncate csum_offset and csum_type + - netfilter: nft_osf: restrict osf to ipv4, ipv6 and inet families + - netfilter: nft_tunnel: restrict it to netdev family + - net: Fix data-races around weight_p and dev_weight_[rt]x_bias. + - net: Fix data-races around netdev_tstamp_prequeue. + - ratelimit: Fix data-races in ___ratelimit(). + - net: Fix a data-race around sysctl_tstamp_allow_data. + - net: Fix a data-race around sysctl_net_busy_poll. + - net: Fix a data-race around sysctl_net_busy_read. + - net: Fix a data-race around netdev_budget. + - net: Fix a data-race around netdev_budget_usecs. + - net: Fix a data-race around sysctl_somaxconn. + - ixgbe: stop resetting SYSTIME in ixgbe_ptp_start_cyclecounter + - btrfs: fix silent failure when deleting root reference + - btrfs: replace: drop assert for suspended replace + - btrfs: add info when mount fails due to stale replace target + - btrfs: check if root is readonly while setting security xattr + - x86/unwind/orc: Unwind ftrace trampolines with correct ORC entry + - loop: Check for overflow while configuring loop + - asm-generic: sections: refactor memory_intersects + - s390: fix double free of GS and RI CBs on fork() failure + - ACPI: processor: Remove freq Qos request for all CPUs + - mm/hugetlb: fix hugetlb not supporting softdirty tracking + - md: call __md_stop_writes in md_stop + - perf/x86/intel/uncore: Fix broken read_counter() for SNB IMC PMU + - scsi: storvsc: Remove WQ_MEM_RECLAIM from storvsc_error_wq + - mm: Force TLB flush for PFNMAP mappings before unlink_file_vma() + - s390/mm: do not trigger write fault when vma does not allow VM_WRITE + - x86/bugs: Add "unknown" reporting for MMIO Stale Data + - kbuild: Fix include path in scripts/Makefile.modpost + - Bluetooth: L2CAP: Fix build errors in some archs + - HID: steam: Prevent NULL pointer dereference in steam_{recv,send}_report + - udmabuf: Set the DMA mask for the udmabuf device (v2) + - media: pvrusb2: fix memory leak in pvr_probe + - HID: hidraw: fix memory leak in hidraw_release() + - fbdev: fb_pm2fb: Avoid potential divide by zero error + - ftrace: Fix NULL pointer dereference in is_ftrace_trampoline when ftrace is + dead + - bpf: Don't redirect packets with invalid pkt_len + - mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse + - btrfs: introduce btrfs_lookup_match_dir + - btrfs: do not pin logs too early during renames + - btrfs: unify lookup return value when dir entry is missing + - drm/amd/display: Avoid MPC infinite loop + - drm/amd/display: clear optc underflow before turn off odm clock + - neigh: fix possible DoS due to net iface start/stop loop + - s390/hypfs: avoid error message under KVM + - drm/amd/display: Fix pixel clock programming + - netfilter: conntrack: NF_CONNTRACK_PROCFS should no longer default to y + - btrfs: tree-checker: check for overlapping extent items + - lib/vdso: Let do_coarse() return 0 to simplify the callsite + - lib/vdso: Mark do_hres() and do_coarse() as __always_inline + - kprobes: don't call disarm_kprobe() for disabled kprobes + - net/af_packet: check len when min_header_len equals to 0 + - net: neigh: don't call kfree_skb() under spin_lock_irqsave() + - Linux 5.4.212 + * Focal update: v5.4.211 upstream stable release (LP: #1990190) + - Makefile: link with -z noexecstack --no-warn-rwx-segments + - x86: link vdso and boot with -z noexecstack --no-warn-rwx-segments + - scsi: Revert "scsi: qla2xxx: Fix disk failure to rediscover" + - ALSA: bcd2000: Fix a UAF bug on the error path of probing + - igc: Remove _I_PHY_ID checking + - wifi: mac80211_hwsim: fix race condition in pending packet + - wifi: mac80211_hwsim: add back erroneously removed cast + - wifi: mac80211_hwsim: use 32-bit skb cookie + - add barriers to buffer_uptodate and set_buffer_uptodate + - HID: wacom: Only report rotation for art pen + - HID: wacom: Don't register pad_input for touch switch + - KVM: nVMX: Snapshot pre-VM-Enter BNDCFGS for !nested_run_pending case + - KVM: nVMX: Snapshot pre-VM-Enter DEBUGCTL for !nested_run_pending case + - KVM: SVM: Don't BUG if userspace injects an interrupt with GIF=0 + - KVM: nVMX: Let userspace set nVMX MSR to any _host_ supported value + - KVM: x86: Mark TSS busy during LTR emulation _after_ all fault checks + - KVM: x86: Set error code to segment selector on LLDT/LTR non-canonical #GP + - mm/mremap: hold the rmap lock in write mode when moving page table entries. + - ALSA: hda/conexant: Add quirk for LENOVO 20149 Notebook model + - ALSA: hda/cirrus - support for iMac 12,1 model + - ALSA: hda/realtek: Add quirk for another Asus K42JZ model + - tty: vt: initialize unicode screen buffer + - vfs: Check the truncate maximum size in inode_newsize_ok() + - fs: Add missing umask strip in vfs_tmpfile + - thermal: sysfs: Fix cooling_device_stats_setup() error code path + - fbcon: Fix boundary checks for fbcon=vc:n1-n2 parameters + - usbnet: Fix linkwatch use-after-free on disconnect + - ovl: drop WARN_ON() dentry is NULL in ovl_encode_fh() + - parisc: Fix device names in /proc/iomem + - parisc: io_pgetevents_time64() needs compat syscall in 32-bit compat mode + - drm/gem: Properly annotate WW context on drm_gem_lock_reservations() error + - drm/nouveau: fix another off-by-one in nvbios_addr + - drm/amdgpu: Check BO's requested pinning domains against its + preferred_domains + - iio: light: isl29028: Fix the warning in isl29028_remove() + - fuse: limit nsec + - serial: mvebu-uart: uart2 error bits clearing + - md-raid10: fix KASAN warning + - ia64, processor: fix -Wincompatible-pointer-types in ia64_get_irr() + - PCI: Add defines for normal and subtractive PCI bridges + - powerpc/fsl-pci: Fix Class Code of PCIe Root Port + - powerpc/ptdump: Fix display of RW pages on FSL_BOOK3E + - powerpc/powernv: Avoid crashing if rng is NULL + - MIPS: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK + - coresight: Clear the connection field properly + - USB: HCD: Fix URB giveback issue in tasklet function + - ARM: dts: uniphier: Fix USB interrupts for PXs2 SoC + - arm64: dts: uniphier: Fix USB interrupts for PXs3 SoC + - netfilter: nf_tables: fix null deref due to zeroed list head + - epoll: autoremove wakers even more aggressively + - x86: Handle idle=nomwait cmdline properly for x86_idle + - arm64: Do not forget syscall when starting a new thread. + - arm64: fix oops in concurrently setting insn_emulation sysctls + - ext2: Add more validity checks for inode counts + - genirq: Don't return error on missing optional irq_request_resources() + - wait: Fix __wait_event_hrtimeout for RT/DL tasks + - ARM: dts: imx6ul: add missing properties for sram + - ARM: dts: imx6ul: change operating-points to uint32-matrix + - ARM: dts: imx6ul: fix csi node compatible + - ARM: dts: imx6ul: fix lcdif node compatible + - ARM: dts: imx6ul: fix qspi node compatible + - spi: synquacer: Add missing clk_disable_unprepare() + - ARM: OMAP2+: display: Fix refcount leak bug + - ACPI: EC: Remove duplicate ThinkPad X1 Carbon 6th entry from DMI quirks + - ACPI: PM: save NVS memory for Lenovo G40-45 + - ACPI: LPSS: Fix missing check in register_device_clock() + - arm64: dts: qcom: ipq8074: fix NAND node name + - arm64: dts: allwinner: a64: orangepi-win: Fix LED node name + - ARM: shmobile: rcar-gen2: Increase refcount for new reference + - PM: hibernate: defer device probing when resuming from hibernation + - selinux: Add boundary check in put_entry() + - spi: spi-rspi: Fix PIO fallback on RZ platforms + - ARM: findbit: fix overflowing offset + - meson-mx-socinfo: Fix refcount leak in meson_mx_socinfo_init + - ARM: bcm: Fix refcount leak in bcm_kona_smc_init + - x86/pmem: Fix platform-device leak in error path + - ARM: dts: ast2500-evb: fix board compatible + - ARM: dts: ast2600-evb: fix board compatible + - soc: fsl: guts: machine variable might be unset + - ARM: dts: qcom: mdm9615: add missing PMIC GPIO reg + - ARM: OMAP2+: Fix refcount leak in omapdss_init_of + - ARM: OMAP2+: Fix refcount leak in omap3xxx_prm_late_init + - cpufreq: zynq: Fix refcount leak in zynq_get_revision + - soc: qcom: aoss: Fix refcount leak in qmp_cooling_devices_register + - ARM: dts: qcom: pm8841: add required thermal-sensor-cells + - bus: hisi_lpc: fix missing platform_device_put() in hisi_lpc_acpi_probe() + - arm64: dts: mt7622: fix BPI-R64 WPS button + - erofs: avoid consecutive detection for Highmem memory + - blk-mq: don't create hctx debugfs dir until q->debugfs_dir is created + - regulator: of: Fix refcount leak bug in of_get_regulation_constraints() + - nohz/full, sched/rt: Fix missed tick-reenabling bug in dequeue_task_rt() + - thermal/tools/tmon: Include pthread and time headers in tmon.h + - dm: return early from dm_pr_call() if DM device is suspended + - ath10k: do not enforce interrupt trigger type + - wifi: rtlwifi: fix error codes in rtl_debugfs_set_write_h2c() + - drm/mipi-dbi: align max_chunk to 2 in spi_transfer + - drm/radeon: fix potential buffer overflow in ni_set_mc_special_registers() + - drm/mediatek: Add pull-down MIPI operation in mtk_dsi_poweroff function + - drm: adv7511: override i2c address of cec before accessing it + - i2c: Fix a potential use after free + - media: tw686x: Register the irq at the end of probe + - wifi: iwlegacy: 4965: fix potential off-by-one overflow in + il4965_rs_fill_link_cmd() + - drm: bridge: adv7511: Add check for mipi_dsi_driver_register + - drm/mcde: Fix refcount leak in mcde_dsi_bind + - media: hdpvr: fix error value returns in hdpvr_read + - drm/vc4: plane: Remove subpixel positioning check + - drm/vc4: plane: Fix margin calculations for the right/bottom edges + - drm/vc4: dsi: Correct DSI divider calculations + - crypto: arm64/gcm - Select AEAD for GHASH_ARM64_CE + - drm/rockchip: vop: Don't crash for invalid duplicate_state() + - drm/rockchip: Fix an error handling path rockchip_dp_probe() + - drm/mediatek: dpi: Remove output format of YUV + - drm/mediatek: dpi: Only enable dpi after the bridge is enabled + - drm: bridge: sii8620: fix possible off-by-one + - drm/msm/mdp5: Fix global state lock backoff + - crypto: hisilicon - Kunpeng916 crypto driver don't sleep when in softirq + - media: platform: mtk-mdp: Fix mdp_ipi_comm structure alignment + - mediatek: mt76: mac80211: Fix missing of_node_put() in mt76_led_init() + - drm/exynos/exynos7_drm_decon: free resources when clk_set_parent() failed. + - tcp: make retransmitted SKB fit into the send window + - libbpf: Fix the name of a reused map + - selftests: timers: valid-adjtimex: build fix for newer toolchains + - selftests: timers: clocksource-switch: fix passing errors from child + - fs: check FMODE_LSEEK to control internal pipe splicing + - wifi: wil6210: debugfs: fix info leak in wil_write_file_wmi() + - wifi: p54: Fix an error handling path in p54spi_probe() + - wifi: p54: add missing parentheses in p54_flush() + - selftests/bpf: fix a test for snprintf() overflow + - can: pch_can: do not report txerr and rxerr during bus-off + - can: rcar_can: do not report txerr and rxerr during bus-off + - can: sja1000: do not report txerr and rxerr during bus-off + - can: hi311x: do not report txerr and rxerr during bus-off + - can: sun4i_can: do not report txerr and rxerr during bus-off + - can: kvaser_usb_hydra: do not report txerr and rxerr during bus-off + - can: kvaser_usb_leaf: do not report txerr and rxerr during bus-off + - can: usb_8dev: do not report txerr and rxerr during bus-off + - can: error: specify the values of data[5..7] of CAN error frames + - can: pch_can: pch_can_error(): initialize errc before using it + - Bluetooth: hci_intel: Add check for platform_driver_register + - i2c: cadence: Support PEC for SMBus block read + - i2c: mux-gpmux: Add of_node_put() when breaking out of loop + - wifi: wil6210: debugfs: fix uninitialized variable use in + `wil_write_file_wmi()` + - wifi: iwlwifi: mvm: fix double list_add at iwl_mvm_mac_wake_tx_queue + - wifi: libertas: Fix possible refcount leak in if_usb_probe() + - net/mlx5e: Fix the value of MLX5E_MAX_RQ_NUM_MTTS + - crypto: inside-secure - Add missing MODULE_DEVICE_TABLE for of + - iavf: Fix max_rate limiting + - netdevsim: Avoid allocation warnings triggered from user space + - net: rose: fix netdev reference changes + - dccp: put dccp_qpolicy_full() and dccp_qpolicy_push() in the same lock + - clk: renesas: r9a06g032: Fix UART clkgrp bitsel + - mtd: maps: Fix refcount leak in of_flash_probe_versatile + - mtd: maps: Fix refcount leak in ap_flash_init + - mtd: rawnand: meson: Fix a potential double free issue + - HID: cp2112: prevent a buffer overflow in cp2112_xfer() + - mtd: sm_ftl: Fix deadlock caused by cancel_work_sync in sm_release + - mtd: partitions: Fix refcount leak in parse_redboot_of + - mtd: st_spi_fsm: Add a clk_disable_unprepare() in .probe()'s error path + - fpga: altera-pr-ip: fix unsigned comparison with less than zero + - usb: host: Fix refcount leak in ehci_hcd_ppc_of_probe + - usb: ohci-nxp: Fix refcount leak in ohci_hcd_nxp_probe + - usb: xhci: tegra: Fix error check + - clk: mediatek: reset: Fix written reset bit offset + - misc: rtsx: Fix an error handling path in rtsx_pci_probe() + - driver core: fix potential deadlock in __driver_attach + - clk: qcom: clk-krait: unlock spin after mux completion + - usb: host: xhci: use snprintf() in xhci_decode_trb() + - clk: qcom: ipq8074: fix NSS port frequency tables + - clk: qcom: ipq8074: set BRANCH_HALT_DELAY flag for UBI clocks + - clk: qcom: camcc-sdm845: Fix topology around titan_top power domain + - soundwire: bus_type: fix remove and shutdown support + - intel_th: Fix a resource leak in an error handling path + - intel_th: msu-sink: Potential dereference of null pointer + - intel_th: msu: Fix vmalloced buffers + - staging: rtl8192u: Fix sleep in atomic context bug in + dm_fsync_timer_callback + - mmc: sdhci-of-esdhc: Fix refcount leak in esdhc_signal_voltage_switch + - memstick/ms_block: Fix some incorrect memory allocation + - memstick/ms_block: Fix a memory leak + - mmc: sdhci-of-at91: fix set_uhs_signaling rewriting of MC1R + - scsi: smartpqi: Fix DMA direction for RAID requests + - usb: gadget: udc: amd5536 depends on HAS_DMA + - RDMA/hns: Fix incorrect clearing of interrupt status register + - RDMA/siw: Fix duplicated reported IW_CM_EVENT_CONNECT_REPLY event + - RDMA/hfi1: fix potential memory leak in setup_base_ctxt() + - gpio: gpiolib-of: Fix refcount bugs in of_mm_gpiochip_add_data() + - mmc: cavium-octeon: Add of_node_put() when breaking out of loop + - mmc: cavium-thunderx: Add of_node_put() when breaking out of loop + - HID: alps: Declare U1_UNICORN_LEGACY support + - PCI: tegra194: Fix Root Port interrupt handling + - PCI: tegra194: Fix link up retry sequence + - USB: serial: fix tty-port initialized comments + - platform/olpc: Fix uninitialized data in debugfs write + - mm/mmap.c: fix missing call to vm_unacct_memory in mmap_region + - RDMA/rxe: Fix error unwind in rxe_create_qp() + - null_blk: fix ida error handling in null_add_dev() + - jbd2: fix outstanding credits assert in jbd2_journal_commit_transaction() + - ext4: recover csum seed of tmp_inode after migrating to extents + - jbd2: fix assertion 'jh->b_frozen_data == NULL' failure when journal aborted + - opp: Fix error check in dev_pm_opp_attach_genpd() + - ASoC: mediatek: mt8173: Fix refcount leak in mt8173_rt5650_rt5676_dev_probe + - ASoC: mt6797-mt6351: Fix refcount leak in mt6797_mt6351_dev_probe + - ASoC: codecs: da7210: add check for i2c_add_driver + - ASoC: mediatek: mt8173-rt5650: Fix refcount leak in mt8173_rt5650_dev_probe + - serial: 8250_dw: Store LSR into lsr_saved_flags in dw8250_tx_wait_empty() + - ASoC: codecs: msm8916-wcd-digital: move gains from SX_TLV to S8_TLV + - ASoC: codecs: wcd9335: move gains from SX_TLV to S8_TLV + - profiling: fix shift too large makes kernel panic + - tty: n_gsm: fix non flow control frames during mux flow off + - tty: n_gsm: fix packet re-transmission without open control channel + - tty: n_gsm: fix race condition in gsmld_write() + - remoteproc: qcom: wcnss: Fix handling of IRQs + - vfio/ccw: Do not change FSM state in subchannel event + - tty: n_gsm: fix wrong T1 retry count handling + - tty: n_gsm: fix DM command + - tty: n_gsm: fix missing corner cases in gsmld_poll() + - iommu/exynos: Handle failed IOMMU device registration properly + - rpmsg: qcom_smd: Fix refcount leak in qcom_smd_parse_edge + - kfifo: fix kfifo_to_user() return type + - mfd: t7l66xb: Drop platform disable callback + - mfd: max77620: Fix refcount leak in max77620_initialise_fps + - iommu/arm-smmu: qcom_iommu: Add of_node_put() when breaking out of loop + - s390/zcore: fix race when reading from hardware system area + - ASoC: qcom: q6dsp: Fix an off-by-one in q6adm_alloc_copp() + - fuse: Remove the control interface for virtio-fs + - ASoC: audio-graph-card: Add of_node_put() in fail path + - watchdog: armada_37xx_wdt: check the return value of devm_ioremap() in + armada_37xx_wdt_probe() + - video: fbdev: amba-clcd: Fix refcount leak bugs + - video: fbdev: sis: fix typos in SiS_GetModeID() + - powerpc/32: Do not allow selection of e5500 or e6500 CPUs on PPC32 + - powerpc/pci: Prefer PCI domain assignment via DT 'linux,pci-domain' and + alias + - powerpc/spufs: Fix refcount leak in spufs_init_isolated_loader + - powerpc/xive: Fix refcount leak in xive_get_max_prio + - powerpc/cell/axon_msi: Fix refcount leak in setup_msi_msg_address + - perf symbol: Fail to read phdr workaround + - kprobes: Forbid probing on trampoline and BPF code areas + - powerpc/pci: Fix PHB numbering when using opal-phbid + - genelf: Use HAVE_LIBCRYPTO_SUPPORT, not the never defined HAVE_LIBCRYPTO + - scripts/faddr2line: Fix vmlinux detection on arm64 + - x86/numa: Use cpumask_available instead of hardcoded NULL check + - video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock() + - tools/thermal: Fix possible path truncations + - video: fbdev: vt8623fb: Check the size of screen before memset_io() + - video: fbdev: arkfb: Check the size of screen before memset_io() + - video: fbdev: s3fb: Check the size of screen before memset_io() + - scsi: zfcp: Fix missing auto port scan and thus missing target ports + - scsi: qla2xxx: Fix discovery issues in FC-AL topology + - scsi: qla2xxx: Turn off multi-queue for 8G adapters + - scsi: qla2xxx: Fix erroneous mailbox timeout after PCI error injection + - x86/olpc: fix 'logical not is only applied to the left hand side' + - spmi: trace: fix stack-out-of-bound access in SPMI tracing functions + - kexec, KEYS, s390: Make use of built-in and secondary keyring for signature + verification + - tpm: eventlog: Fix section mismatch for DEBUG_SECTION_MISMATCH + - btrfs: reset block group chunk force if we have to wait + - ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h + - ext4: make sure ext4_append() always allocates new block + - ext4: fix use-after-free in ext4_xattr_set_entry + - ext4: update s_overhead_clusters in the superblock during an on-line resize + - ext4: fix extent status tree race in writeback error recovery path + - ext4: correct max_inline_xattr_value_size computing + - ext4: correct the misjudgment in ext4_iget_extra_inode + - intel_th: pci: Add Raptor Lake-S CPU support + - intel_th: pci: Add Raptor Lake-S PCH support + - intel_th: pci: Add Meteor Lake-P support + - dm raid: fix address sanitizer warning in raid_resume + - dm raid: fix address sanitizer warning in raid_status + - dm thin: fix use-after-free crash in dm_sm_register_threshold_callback + - dm writecache: set a default MAX_WRITEBACK_JOBS + - ACPI: CPPC: Do not prevent CPPC from working in the future + - timekeeping: contribute wall clock to rng on time change + - firmware: arm_scpi: Ensure scpi_info is not assigned if the probe fails + - iommu/vt-d: avoid invalid memory access via node_online(NUMA_NO_NODE) + - btrfs: reject log replay if there is unsupported RO compat flag + - KVM: Add infrastructure and macro to mark VM as bugged + - KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq + - KVM: x86: Avoid theoretical NULL pointer dereference in + kvm_irq_delivery_to_apic_fast() + - tcp: fix over estimation in sk_forced_mem_schedule() + - scsi: sg: Allow waiting for commands to complete on removed device + - Bluetooth: L2CAP: Fix l2cap_global_chan_by_psm regression + - net/9p: Initialize the iounit field during fid creation + - net_sched: cls_route: disallow handle of 0 + - ALSA: info: Fix llseek return value when using callback + - rds: add missing barrier to release_refill + - ata: libata-eh: Add missing command name + - mmc: pxamci: Fix another error handling path in pxamci_probe() + - mmc: pxamci: Fix an error handling path in pxamci_probe() + - btrfs: fix lost error handling when looking up extended ref on log replay + - tracing: Have filter accept "common_cpu" to be consistent + - can: ems_usb: fix clang's -Wunaligned-access warning + - apparmor: fix quiet_denied for file rules + - apparmor: fix absroot causing audited secids to begin with = + - apparmor: Fix failed mount permission check error message + - apparmor: fix aa_label_asxprint return check + - apparmor: fix overlapping attachment computation + - apparmor: fix reference count leak in aa_pivotroot() + - apparmor: Fix memleak in aa_simple_write_to_buffer() + - Documentation: ACPI: EINJ: Fix obsolete example + - NFSv4.1: Don't decrease the value of seq_nr_highest_sent + - NFSv4.1: Handle NFS4ERR_DELAY replies to OP_SEQUENCE correctly + - NFSv4: Fix races in the legacy idmapper upcall + - NFSv4.1: RECLAIM_COMPLETE must handle EACCES + - NFSv4/pnfs: Fix a use-after-free bug in open + - can: mcp251x: Fix race condition on receive interrupt + - sunrpc: fix expiry of auth creds + - SUNRPC: Reinitialise the backchannel request buffers before reuse + - devlink: Fix use-after-free after a failed reload + - net: bgmac: Fix a BUG triggered by wrong bytes_compl + - pinctrl: nomadik: Fix refcount leak in nmk_pinctrl_dt_subnode_to_map + - pinctrl: qcom: msm8916: Allow CAMSS GP clocks to be muxed + - pinctrl: sunxi: Add I/O bias setting for H6 R-PIO + - ACPI: property: Return type of acpi_add_nondev_subnodes() should be bool + - geneve: do not use RT_TOS for IPv6 flowlabel + - plip: avoid rcu debug splat + - vsock: Fix memory leak in vsock_connect() + - vsock: Set socket state back to SS_UNCONNECTED in vsock_connect_timeout() + - dt-bindings: arm: qcom: fix MSM8916 MTP compatibles + - tools/vm/slabinfo: use alphabetic order when two values are equal + - tools build: Switch to new openssl API for test-libcrypto + - NTB: ntb_tool: uninitialized heap data in tool_fn_write() + - nfp: ethtool: fix the display error of `ethtool -m DEVNAME` + - xen/xenbus: fix return type in xenbus_file_read() + - atm: idt77252: fix use-after-free bugs caused by tst_timer + - dpaa2-eth: trace the allocated address instead of page struct + - tee: add overflow check in register_shm_helper() + - nios2: page fault et.al. are *not* restartable syscalls... + - nios2: don't leave NULLs in sys_call_table[] + - nios2: traced syscall does need to check the syscall number + - nios2: fix syscall restart checks + - nios2: restarts apply only to the first sigframe we build... + - nios2: add force_successful_syscall_return() + - iavf: Fix adminq error handling + - clk: rockchip: add sclk_mac_lbtest to rk3188_critical_clocks + - netfilter: nf_tables: really skip inactive sets when allocating name + - powerpc/pci: Fix get_phb_number() locking + - net: dsa: mv88e6060: prevent crash on an unused port + - net: moxa: pass pdev instead of ndev to DMA functions + - net: dsa: microchip: ksz9477: fix fdb_dump last invalid entry + - ice: Ignore EEXIST when setting promisc mode + - i40e: Fix to stop tx_timeout recovery if GLOBR fails + - fec: Fix timer capture timing in `fec_ptp_enable_pps()` + - igb: Add lock to avoid data race + - gcc-plugins: Undefine LATENT_ENTROPY_PLUGIN when plugin disabled for a file + - locking/atomic: Make test_and_*_bit() ordered on failure + - drm/meson: Fix refcount bugs in meson_vpu_has_available_connectors() + - PCI: Add ACS quirk for Broadcom BCM5750x NICs + - usb: cdns3 fix use-after-free at workaround 2 + - usb: gadget: uvc: call uvc uvcg_warn on completed status instead of + uvcg_info + - irqchip/tegra: Fix overflow implicit truncation warnings + - drm/meson: Fix overflow implicit truncation warnings + - usb: host: ohci-ppc-of: Fix refcount leak bug + - usb: renesas: Fix refcount leak bug + - vboxguest: Do not use devm for irq + - clk: qcom: ipq8074: dont disable gcc_sleep_clk_src + - scsi: lpfc: Prevent buffer overflow crashes in debugfs with malformed user + input + - gadgetfs: ep_io - wait until IRQ finishes + - cxl: Fix a memory leak in an error handling path + - PCI/ACPI: Guard ARM64-specific mcfg_quirks + - um: add "noreboot" command line option for PANIC_TIMEOUT=-1 setups + - selftests/kprobe: Do not test for GRP/ without event failures + - dmaengine: sprd: Cleanup in .remove() after pm_runtime_get_sync() failed + - nvmet-tcp: fix lockdep complaint on nvmet_tcp_wq flush during queue teardown + - drivers:md:fix a potential use-after-free bug + - ext4: avoid remove directory when directory is corrupted + - ext4: avoid resizing to a partial cluster size + - lib/list_debug.c: Detect uninitialized lists + - tty: serial: Fix refcount leak bug in ucc_uart.c + - vfio: Clear the caps->buf to NULL after free + - mips: cavium-octeon: Fix missing of_node_put() in octeon2_usb_clocks_start + - riscv: mmap with PROT_WRITE but no PROT_READ is invalid + - RISC-V: Add fast call path of crash_kexec() + - watchdog: export lockup_detector_reconfigure + - powerpc/32: Don't always pass -mcpu=powerpc to the compiler + - ALSA: core: Add async signal helpers + - ALSA: timer: Use deferred fasync helper + - f2fs: fix to avoid use f2fs_bug_on() in f2fs_new_node_page() + - smb3: check xattr value length earlier + - powerpc/64: Init jump labels before parse_early_param() + - video: fbdev: i740fb: Check the argument of i740_calc_vclk() + - MIPS: tlbex: Explicitly compare _PAGE_NO_EXEC against 0 + - tracing/probes: Have kprobes and uprobes use $COMM too + - can: j1939: j1939_sk_queue_activate_next_locked(): replace WARN_ON_ONCE with + netdev_warn_once() + - can: j1939: j1939_session_destroy(): fix memory leak of skbs + - btrfs: only write the sectors in the vertical stripe which has data stripes + - btrfs: raid56: don't trust any cached sector in __raid56_parity_recover() + - Linux 5.4.211 + * CVE-2022-3028 + - af_key: Do not call xfrm_probe_algs in parallel + * CVE-2022-2978 + - fs: fix UAF/GPF bug in nilfs_mdt_destroy + * CVE-2022-40768 + - scsi: stex: Properly zero out the passthrough command structure + + -- Joseph Salisbury Wed, 19 Oct 2022 14:20:00 -0400 + +linux-oracle (5.4.0-1086.95) focal; urgency=medium + + [ Ubuntu: 5.4.0-131.147 ] + + * CVE-2022-2602 + - SAUCE: io_uring/af_unix: defer registered files gc to io_uring release + - SAUCE: io_uring/af_unix: fix memleak during unix GC + * CVE-2022-41674 + - SAUCE: wifi: cfg80211: fix u8 overflow in + cfg80211_update_notlisted_nontrans() + - SAUCE: wifi: cfg80211/mac80211: reject bad MBSSID elements + - SAUCE: wifi: cfg80211: ensure length byte is present before access + - SAUCE: wifi: mac80211_hwsim: avoid mac80211 warning on bad rate + - SAUCE: wifi: cfg80211: update hidden BSSes to avoid WARN_ON + * CVE-2022-42721 + - SAUCE: wifi: cfg80211: avoid nontransmitted BSS list corruption + * CVE-2022-42720 + - SAUCE: wifi: cfg80211: fix BSS refcounting bugs + + -- Thadeu Lima de Souza Cascardo Mon, 17 Oct 2022 00:32:23 -0300 + +linux-oracle (5.4.0-1084.92) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1084.92 -proposed tracker (LP: #1989882) + + [ Ubuntu: 5.4.0-128.144 ] + + * focal/linux: 5.4.0-128.144 -proposed tracker (LP: #1990152) + * CVE-2022-3176 + - io_uring: disable polling pollfree files + * ip/nexthop: fix default address selection for connected nexthop + (LP: #1988809) + - selftests/net: test nexthop without gw + * ip/nexthop: fix default address selection for connected nexthop + (LP: #1988809) // icmp_redirect.sh in ubuntu_kernel_selftests failed on + Jammy 5.15.0-49.55 (LP: #1990124) + - ip: fix triggering of 'icmp redirect' + + [ Ubuntu: 5.4.0-127.143 ] + + * focal/linux: 5.4.0-127.143 -proposed tracker (LP: #1989892) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.09.19) + * [UBUNTU 20.04] mlx5 driver crashes on accessing device attributes during + recovery (LP: #1987287) + - net/mlx5: Avoid processing commands before cmdif is ready + * Focal update: v5.4.210 upstream stable release (LP: #1989230) + - thermal: Fix NULL pointer dereferences in of_thermal_ functions + - ACPI: video: Force backlight native for some TongFang devices + - ACPI: video: Shortening quirk list by identifying Clevo by board_name only + - ACPI: APEI: Better fix to avoid spamming the console with old error logs + - bpf: Verifer, adjust_scalar_min_max_vals to always call update_reg_bounds() + - selftests/bpf: Extend verifier and bpf_sock tests for dst_port loads + - bpf: Test_verifier, #70 error message updates for 32-bit right shift + - KVM: Don't null dereference ops->destroy + - selftests: KVM: Handle compiler optimizations in ucall + - media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls + - macintosh/adb: fix oob read in do_adb_query() function + - x86/speculation: Add RSB VM Exit protections + - x86/speculation: Add LFENCE to RSB fill sequence + - Linux 5.4.210 + * Focal update: v5.4.209 upstream stable release (LP: #1989228) + - Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put + - ntfs: fix use-after-free in ntfs_ucsncmp() + - s390/archrandom: prevent CPACF trng invocations in interrupt context + - tcp: Fix data-races around sysctl_tcp_dsack. + - tcp: Fix a data-race around sysctl_tcp_app_win. + - tcp: Fix a data-race around sysctl_tcp_adv_win_scale. + - tcp: Fix a data-race around sysctl_tcp_frto. + - tcp: Fix a data-race around sysctl_tcp_nometrics_save. + - ice: check (DD | EOF) bits on Rx descriptor rather than (EOP | RS) + - ice: do not setup vlan for loopback VSI + - scsi: ufs: host: Hold reference returned by of_parse_phandle() + - tcp: Fix a data-race around sysctl_tcp_limit_output_bytes. + - tcp: Fix a data-race around sysctl_tcp_challenge_ack_limit. + - net: ping6: Fix memleak in ipv6_renew_options(). + - ipv6/addrconf: fix a null-ptr-deref bug for ip6_ptr + - igmp: Fix data-races around sysctl_igmp_qrv. + - net: sungem_phy: Add of_node_put() for reference returned by of_get_parent() + - tcp: Fix a data-race around sysctl_tcp_min_tso_segs. + - tcp: Fix a data-race around sysctl_tcp_min_rtt_wlen. + - tcp: Fix a data-race around sysctl_tcp_autocorking. + - tcp: Fix a data-race around sysctl_tcp_invalid_ratelimit. + - Documentation: fix sctp_wmem in ip-sysctl.rst + - tcp: Fix a data-race around sysctl_tcp_comp_sack_delay_ns. + - tcp: Fix a data-race around sysctl_tcp_comp_sack_nr. + - i40e: Fix interface init with MSI interrupts (no MSI-X) + - sctp: fix sleep in atomic context bug in timer handlers + - virtio-net: fix the race between refill work and close + - perf symbol: Correct address for bss symbols + - sfc: disable softirqs for ptp TX + - sctp: leave the err path free in sctp_stream_init to sctp_stream_free + - ARM: crypto: comment out gcc warning that breaks clang builds + - mt7601u: add USB device ID for some versions of XiaoDu WiFi Dongle. + - scsi: core: Fix race between handling STS_RESOURCE and completion + - Linux 5.4.209 + * Focal update: v5.4.208 upstream stable release (LP: #1988225) + - pinctrl: stm32: fix optional IRQ support to gpios + - riscv: add as-options for modules with assembly compontents + - mlxsw: spectrum_router: Fix IPv4 nexthop gateway indication + - lockdown: Fix kexec lockdown bypass with ima policy + - xen/gntdev: Ignore failure to unmap INVALID_GRANT_HANDLE + - PCI: hv: Fix multi-MSI to allow more than one MSI vector + - PCI: hv: Fix hv_arch_irq_unmask() for multi-MSI + - PCI: hv: Reuse existing IRTE allocation in compose_msi_msg() + - PCI: hv: Fix interrupt mapping for multi-MSI + - serial: mvebu-uart: correctly report configured baudrate value + - xfrm: xfrm_policy: fix a possible double xfrm_pols_put() in + xfrm_bundle_lookup() + - power/reset: arm-versatile: Fix refcount leak in versatile_reboot_probe + - pinctrl: ralink: Check for null return of devm_kcalloc + - perf/core: Fix data race between perf_event_set_output() and + perf_mmap_close() + - igc: Reinstate IGC_REMOVED logic and implement it properly + - ip: Fix data-races around sysctl_ip_no_pmtu_disc. + - ip: Fix data-races around sysctl_ip_fwd_use_pmtu. + - ip: Fix data-races around sysctl_ip_nonlocal_bind. + - ip: Fix a data-race around sysctl_fwmark_reflect. + - tcp/dccp: Fix a data-race around sysctl_tcp_fwmark_accept. + - tcp: Fix data-races around sysctl_tcp_mtu_probing. + - tcp: Fix data-races around sysctl_tcp_base_mss. + - tcp: Fix data-races around sysctl_tcp_min_snd_mss. + - tcp: Fix a data-race around sysctl_tcp_mtu_probe_floor. + - tcp: Fix a data-race around sysctl_tcp_probe_threshold. + - tcp: Fix a data-race around sysctl_tcp_probe_interval. + - i2c: cadence: Change large transfer count reset logic to be unconditional + - net: stmmac: fix dma queue left shift overflow issue + - net/tls: Fix race in TLS device down flow + - igmp: Fix data-races around sysctl_igmp_llm_reports. + - igmp: Fix a data-race around sysctl_igmp_max_memberships. + - tcp: Fix data-races around sysctl_tcp_syncookies. + - tcp: Fix data-races around sysctl_tcp_reordering. + - tcp: Fix data-races around some timeout sysctl knobs. + - tcp: Fix a data-race around sysctl_tcp_notsent_lowat. + - tcp: Fix a data-race around sysctl_tcp_tw_reuse. + - tcp: Fix data-races around sysctl_max_syn_backlog. + - tcp: Fix data-races around sysctl_tcp_fastopen. + - iavf: Fix handling of dummy receive descriptors + - i40e: Fix erroneous adapter reinitialization during recovery process + - ixgbe: Add locking to prevent panic when setting sriov_numvfs to zero + - gpio: pca953x: only use single read/write for No AI mode + - be2net: Fix buffer overflow in be_get_module_eeprom + - ipv4: Fix a data-race around sysctl_fib_multipath_use_neigh. + - udp: Fix a data-race around sysctl_udp_l3mdev_accept. + - tcp: Fix data-races around sysctl knobs related to SYN option. + - tcp: Fix a data-race around sysctl_tcp_early_retrans. + - tcp: Fix data-races around sysctl_tcp_recovery. + - tcp: Fix a data-race around sysctl_tcp_thin_linear_timeouts. + - tcp: Fix data-races around sysctl_tcp_slow_start_after_idle. + - tcp: Fix a data-race around sysctl_tcp_retrans_collapse. + - tcp: Fix a data-race around sysctl_tcp_stdurg. + - tcp: Fix a data-race around sysctl_tcp_rfc1337. + - tcp: Fix data-races around sysctl_tcp_max_reordering. + - spi: bcm2835: bcm2835_spi_handle_err(): fix NULL pointer deref for non DMA + transfers + - mm/mempolicy: fix uninit-value in mpol_rebind_policy() + - bpf: Make sure mac_header was set before using it + - dlm: fix pending remove if msg allocation fails + - ima: remove the IMA_TEMPLATE Kconfig option + - [Config] updateconfigs for IMA_TEMPLATE + - locking/refcount: Define constants for saturation and max refcount values + - locking/refcount: Ensure integer operands are treated as signed + - locking/refcount: Remove unused refcount_*_checked() variants + - locking/refcount: Move the bulk of the REFCOUNT_FULL implementation into the + header + - locking/refcount: Improve performance of generic REFCOUNT_FULL code + - locking/refcount: Move saturation warnings out of line + - locking/refcount: Consolidate REFCOUNT_{MAX,SATURATED} definitions + - locking/refcount: Consolidate implementations of refcount_t + - [Config] updateconfigs for REFCOUNT_FULL + - x86: get rid of small constant size cases in raw_copy_{to,from}_user() + - x86/uaccess: Implement macros for CMPXCHG on user addresses + - mmap locking API: initial implementation as rwsem wrappers + - x86/mce: Deduplicate exception handling + - bitfield.h: Fix "type of reg too small for mask" test + - ALSA: memalloc: Align buffer allocations in page size + - Bluetooth: Add bt_skb_sendmsg helper + - Bluetooth: Add bt_skb_sendmmsg helper + - Bluetooth: SCO: Replace use of memcpy_from_msg with bt_skb_sendmsg + - Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg + - Bluetooth: Fix passing NULL to PTR_ERR + - Bluetooth: SCO: Fix sco_send_frame returning skb->len + - Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks + - tty: drivers/tty/, stop using tty_schedule_flip() + - tty: the rest, stop using tty_schedule_flip() + - tty: drop tty_schedule_flip() + - tty: extract tty_flip_buffer_commit() from tty_flip_buffer_push() + - tty: use new tty_insert_flip_string_and_push_buffer() in pty_write() + - x86: drop bogus "cc" clobber from __try_cmpxchg_user_asm() + - Linux 5.4.208 + * Focal update: v5.4.207 upstream stable release (LP: #1988219) + - ALSA: hda - Add fixup for Dell Latitidue E5430 + - ALSA: hda/conexant: Apply quirk for another HP ProDesk 600 G3 model + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671 + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc221 + - ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop + - xen/netback: avoid entering xenvif_rx_next_skb() with an empty rx queue + - tracing/histograms: Fix memory leak problem + - net: sock: tracing: Fix sock_exceed_buf_limit not to dereference stale + pointer + - ip: fix dflt addr selection for connected nexthop + - ARM: 9213/1: Print message about disabled Spectre workarounds only once + - ARM: 9214/1: alignment: advance IT state after emulating Thumb instruction + - wifi: mac80211: fix queue selection for mesh/OCB interfaces + - cgroup: Use separate src/dst nodes when preloading css_sets for migration + - drm/panfrost: Fix shrinker list corruption by madvise IOCTL + - nilfs2: fix incorrect masking of permission flags for symlinks + - Revert "evm: Fix memleak in init_desc" + - sched/rt: Disable RT_RUNTIME_SHARE by default + - ext4: fix race condition between ext4_write and ext4_convert_inline_data + - ARM: dts: imx6qdl-ts7970: Fix ngpio typo and count + - ARM: 9209/1: Spectre-BHB: avoid pr_info() every time a CPU comes out of idle + - ARM: 9210/1: Mark the FDT_FIXED sections as shareable + - drm/i915: fix a possible refcount leak in intel_dp_add_mst_connector() + - ima: Fix a potential integer overflow in ima_appraise_measurement + - ASoC: sgtl5000: Fix noise on shutdown/remove + - net: stmmac: dwc-qos: Disable split header for Tegra194 + - inetpeer: Fix data-races around sysctl. + - net: Fix data-races around sysctl_mem. + - cipso: Fix data-races around sysctl. + - icmp: Fix data-races around sysctl. + - ipv4: Fix a data-race around sysctl_fib_sync_mem. + - ARM: dts: at91: sama5d2: Fix typo in i2s1 node + - ARM: dts: sunxi: Fix SPI NOR campatible on Orange Pi Zero + - drm/i915/gt: Serialize TLB invalidates with GT resets + - icmp: Fix a data-race around sysctl_icmp_ratelimit. + - icmp: Fix a data-race around sysctl_icmp_ratemask. + - raw: Fix a data-race around sysctl_raw_l3mdev_accept. + - ipv4: Fix data-races around sysctl_ip_dynaddr. + - net: ftgmac100: Hold reference returned by of_get_child_by_name() + - sfc: fix use after free when disabling sriov + - seg6: fix skb checksum evaluation in SRH encapsulation/insertion + - seg6: fix skb checksum in SRv6 End.B6 and End.B6.Encaps behaviors + - seg6: bpf: fix skb checksum in bpf_push_seg6_encap() + - sfc: fix kernel panic when creating VF + - mm: sysctl: fix missing numa_stat when !CONFIG_HUGETLB_PAGE + - virtio_mmio: Add missing PM calls to freeze/restore + - virtio_mmio: Restore guest page size on resume + - netfilter: br_netfilter: do not skip all hooks with 0 priority + - cpufreq: pmac32-cpufreq: Fix refcount leak bug + - platform/x86: hp-wmi: Ignore Sanitization Mode event + - net: tipc: fix possible refcount leak in tipc_sk_create() + - NFC: nxp-nci: don't print header length mismatch on i2c error + - nvme: fix regression when disconnect a recovering ctrl + - net: sfp: fix memory leak in sfp_probe() + - ASoC: ops: Fix off by one in range control validation + - ASoC: wm5110: Fix DRE control + - ASoC: cs47l15: Fix event generation for low power mux control + - ASoC: madera: Fix event generation for OUT1 demux + - ASoC: madera: Fix event generation for rate controls + - irqchip: or1k-pic: Undefine mask_ack for level triggered hardware + - x86: Clear .brk area at early boot + - soc: ixp4xx/npe: Fix unused match warning + - ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 + - signal handling: don't use BUG_ON() for debugging + - USB: serial: ftdi_sio: add Belimo device ids + - usb: typec: add missing uevent when partner support PD + - usb: dwc3: gadget: Fix event pending check + - tty: serial: samsung_tty: set dma burst_size to 1 + - serial: 8250: fix return error code in serial8250_request_std_resource() + - serial: stm32: Clear prev values before setting RTS delays + - serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle + - can: m_can: m_can_tx_handler(): fix use after free of skb + - Linux 5.4.207 + * Focal update: v5.4.206 upstream stable release (LP: #1988215) + - Linux 5.4.206 + * Focal update: v5.4.205 upstream stable release (LP: #1988214) + - esp: limit skb_page_frag_refill use to a single page + - mm/slub: add missing TID updates on slab deactivation + - can: bcm: use call_rcu() instead of costly synchronize_rcu() + - can: grcan: grcan_probe(): remove extra of_node_get() + - can: gs_usb: gs_usb_open/close(): fix memory leak + - usbnet: fix memory leak in error case + - net: rose: fix UAF bug caused by rose_t0timer_expiry + - iommu/vt-d: Fix PCI bus rescan device hot add + - fbdev: fbmem: Fix logo center image dx issue + - video: of_display_timing.h: include errno.h + - powerpc/powernv: delay rng platform device creation until later in boot + - can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info + - can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression + - can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits + - xfs: remove incorrect ASSERT in xfs_rename + - ARM: meson: Fix refcount leak in meson_smp_prepare_cpus + - pinctrl: sunxi: a83t: Fix NAND function name for some pins + - pinctrl: sunxi: sunxi_pconf_set: use correct offset + - ARM: at91: pm: use proper compatible for sama5d2's rtc + - ARM: at91: pm: use proper compatibles for sam9x60's rtc and rtt + - ibmvnic: Properly dispose of all skbs during a failover. + - selftests: forwarding: fix flood_unicast_test when h2 supports + IFF_UNICAST_FLT + - selftests: forwarding: fix learning_test when h1 supports IFF_UNICAST_FLT + - selftests: forwarding: fix error message in learning_test + - i2c: cadence: Unregister the clk notifier in error path + - dmaengine: imx-sdma: Allow imx8m for imx7 FW revs + - misc: rtsx_usb: fix use of dma mapped buffer for usb bulk transfer + - misc: rtsx_usb: use separate command and response buffers + - misc: rtsx_usb: set return value in rsp_buf alloc err path + - dt-bindings: dma: allwinner,sun50i-a64-dma: Fix min/max typo + - ida: don't use BUG_ON() for debugging + - dmaengine: pl330: Fix lockdep warning about non-static key + - dmaengine: at_xdma: handle errors of at_xdmac_alloc_desc() correctly + - dmaengine: ti: Fix refcount leak in ti_dra7_xbar_route_allocate + - dmaengine: ti: Add missing put_device in ti_dra7_xbar_route_allocate + - Linux 5.4.205 + * Focal update: v5.4.204 upstream stable release (LP: #1988212) + - ipv6: take care of disable_policy when restoring routes + - nvdimm: Fix badblocks clear off-by-one error + - powerpc/prom_init: Fix kernel config grep + - powerpc/bpf: Fix use of user_pt_regs in uapi + - dm raid: fix accesses beyond end of raid member array + - dm raid: fix KASAN warning in raid5_add_disks + - s390/archrandom: simplify back to earlier design and initialize earlier + - SUNRPC: Fix READ_PLUS crasher + - net: rose: fix UAF bugs caused by timer handler + - net: usb: ax88179_178a: Fix packet receiving + - virtio-net: fix race between ndo_open() and virtio_device_ready() + - selftests/net: pass ipv6_args to udpgso_bench's IPv6 TCP test + - net: tun: unlink NAPI from device on destruction + - net: tun: stop NAPI when detaching queues + - RDMA/qedr: Fix reporting QP timeout attribute + - linux/dim: Fix divide by 0 in RDMA DIM + - usbnet: fix memory allocation in helpers + - net: ipv6: unexport __init-annotated seg6_hmac_net_init() + - caif_virtio: fix race between virtio_device_ready() and ndo_open() + - PM / devfreq: exynos-ppmu: Fix refcount leak in of_get_devfreq_events + - s390: remove unneeded 'select BUILD_BIN2C' + - netfilter: nft_dynset: restore set element counter when failing to update + - net/sched: act_api: Notify user space if any actions were flushed before + error + - net: bonding: fix possible NULL deref in rlb code + - net: bonding: fix use-after-free after 802.3ad slave unbind + - nfc: nfcmrvl: Fix irq_of_parse_and_map() return value + - NFC: nxp-nci: Don't issue a zero length i2c_master_read() + - net: tun: avoid disabling NAPI twice + - xen/gntdev: Avoid blocking in unmap_grant_pages() + - hwmon: (ibmaem) don't call platform_device_del() if platform_device_add() + fails + - net: dsa: bcm_sf2: force pause link settings + - sit: use min + - ipv6/sit: fix ipip6_tunnel_get_prl return value + - rseq/selftests,x86_64: Add rseq_offset_deref_addv() + - selftests/rseq: remove ARRAY_SIZE define from individual tests + - selftests/rseq: introduce own copy of rseq uapi header + - selftests/rseq: Remove useless assignment to cpu variable + - selftests/rseq: Remove volatile from __rseq_abi + - selftests/rseq: Introduce rseq_get_abi() helper + - selftests/rseq: Introduce thread pointer getters + - selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35 + - selftests/rseq: Fix ppc32: wrong rseq_cs 32-bit field pointer on big endian + - selftests/rseq: Fix ppc32 missing instruction selection "u" and "x" for + load/store + - selftests/rseq: Fix ppc32 offsets by using long rather than off_t + - selftests/rseq: Fix warnings about #if checks of undefined tokens + - selftests/rseq: Remove arm/mips asm goto compiler work-around + - selftests/rseq: Fix: work-around asm goto compiler bugs + - selftests/rseq: x86-64: use %fs segment selector for accessing rseq thread + area + - selftests/rseq: x86-32: use %gs segment selector for accessing rseq thread + area + - selftests/rseq: Change type of rseq_offset to ptrdiff_t + - xen/blkfront: fix leaking data in shared pages + - xen/netfront: fix leaking data in shared pages + - xen/netfront: force data bouncing when backend is untrusted + - xen/blkfront: force data bouncing when backend is untrusted + - xen/arm: Fix race in RB-tree based P2M accounting + - net: usb: qmi_wwan: add Telit 0x1060 composition + - net: usb: qmi_wwan: add Telit 0x1070 composition + - clocksource/drivers/ixp4xx: remove EXPORT_SYMBOL_GPL from + ixp4xx_timer_setup() + - Linux 5.4.204 + + -- Joseph Salisbury Wed, 21 Sep 2022 14:35:10 -0400 + +linux-oracle (5.4.0-1083.91) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1083.91 -proposed tracker (LP: #1987809) + + [ Ubuntu: 5.4.0-126.142 ] + + * focal/linux: 5.4.0-126.142 -proposed tracker (LP: #1987819) + * [SRU] fnic driver on needs to be updated to 1.6.0.53 on Focal (LP: #1984011) + - scsi: fnic: Change shost_printk() to FNIC_FCS_DBG() + - scsi: fnic: Avoid looping in TRANS ETH on unload + - scsi: fnic: Change shost_printk() to FNIC_MAIN_DBG() + - scsi: fnic: Set scsi_set_resid() only for underflow + - scsi: fnic: Validate io_req before others + * Focal update: v5.4.203 upstream stable release (LP: #1986999) + - drm: remove drm_fb_helper_modinit + - powerpc/ftrace: Remove ftrace init tramp once kernel init is complete + - kexec_file: drop weak attribute from arch_kexec_apply_relocations[_add] + - net: mscc: ocelot: allow unregistered IP multicast flooding + - ARM: 8989/1: use .fpu assembler directives instead of assembler arguments + - ARM: 8990/1: use VFP assembler mnemonics in register load/store macros + - ARM: 8971/1: replace the sole use of a symbol with its definition + - crypto: arm/sha256-neon - avoid ADRL pseudo instruction + - crypto: arm/sha512-neon - avoid ADRL pseudo instruction + - ARM: 8933/1: replace Sun/Solaris style flag on section directive + - ARM: 8929/1: use APSR_nzcv instead of r15 as mrc operand + - ARM: OMAP2+: drop unnecessary adrl + - ARM: 9029/1: Make iwmmxt.S support Clang's integrated assembler + - crypto: arm - use Kconfig based compiler checks for crypto opcodes + - crypto: arm/ghash-ce - define fpu before fpu registers are referenced + - Linux 5.4.203 + * Focal update: v5.4.202 upstream stable release (LP: #1986995) + - random: schedule mix_interrupt_randomness() less often + - ALSA: hda/via: Fix missing beep setup + - ALSA: hda/conexant: Fix missing beep setup + - ALSA: hda/realtek - ALC897 headset MIC no sound + - ALSA: hda/realtek: Add quirk for Clevo PD70PNT + - net: openvswitch: fix parsing of nw_proto for IPv6 fragments + - mmc: sdhci-pci-o2micro: Fix card detect by dealing with debouncing + - ata: libata: add qc->flags in ata_qc_complete_template tracepoint + - dm era: commit metadata in postsuspend after worker stops + - dm mirror log: clear log bits up to BITS_PER_LONG boundary + - random: quiet urandom warning ratelimit suppression message + - USB: serial: option: add Telit LE910Cx 0x1250 composition + - USB: serial: option: add Quectel EM05-G modem + - USB: serial: option: add Quectel RM500K module support + - bpf: Fix request_sock leak in sk lookup helpers + - phy: aquantia: Fix AN when higher speeds than 1G are not advertised + - bonding: ARP monitor spams NETDEV_NOTIFY_PEERS notifiers + - net/sched: sch_netem: Fix arithmetic in netem_dump() for 32-bit platforms + - drm/msm/mdp4: Fix refcount leak in mdp4_modeset_init_intf + - erspan: do not assume transport header is always set + - net/tls: fix tls_sk_proto_close executed repeatedly + - udmabuf: add back sanity check + - x86/xen: Remove undefined behavior in setup_features() + - MIPS: Remove repetitive increase irq_err_count + - afs: Fix dynamic root getattr + - ice: ethtool: advertise 1000M speeds properly + - regmap-irq: Fix a bug in regmap_irq_enable() for type_in_mask chips + - igb: Make DMA faster when CPU is active on the PCIe link + - virtio_net: fix xdp_rxq_info bug after suspend/resume + - Revert "net/tls: fix tls_sk_proto_close executed repeatedly" + - gpio: winbond: Fix error code in winbond_gpio_get() + - s390/cpumf: Handle events cycles and instructions identical + - iio: adc: vf610: fix conversion mode sysfs node name + - xhci: turn off port power in shutdown + - usb: chipidea: udc: check request status before setting device address + - iio:chemical:ccs811: rearrange iio trigger get and register + - iio:accel:bma180: rearrange iio trigger get and register + - iio:accel:mxc4005: rearrange iio trigger get and register + - iio: accel: mma8452: ignore the return value of reset operation + - iio: gyro: mpu3050: Fix the error handling in mpu3050_power_up() + - iio: trigger: sysfs: fix use-after-free on remove + - iio: adc: stm32: fix maximum clock rate for stm32mp15x + - iio: adc: axp288: Override TS pin bias current for some models + - xtensa: xtfpga: Fix refcount leak bug in setup + - xtensa: Fix refcount leak bug in time.c + - parisc: Enable ARCH_HAS_STRICT_MODULE_RWX + - powerpc: Enable execve syscall exit tracepoint + - powerpc/rtas: Allow ibm,platform-dump RTAS call with null buffer address + - powerpc/powernv: wire up rng during setup_arch + - ARM: dts: imx6qdl: correct PU regulator ramp delay + - ARM: exynos: Fix refcount leak in exynos_map_pmu + - soc: bcm: brcmstb: pm: pm-arm: Fix refcount leak in brcmstb_pm_probe + - ARM: Fix refcount leak in axxia_boot_secondary + - ARM: cns3xxx: Fix refcount leak in cns3xxx_init + - modpost: fix section mismatch check for exported init/exit sections + - random: update comment from copy_to_user() -> copy_to_iter() + - kbuild: link vmlinux only once for CONFIG_TRIM_UNUSED_KSYMS (2nd attempt) + - powerpc/pseries: wire up rng during setup_arch() + - Linux 5.4.202 + * Focal update: v5.4.201 upstream stable release (LP: #1986993) + - dm: remove special-casing of bio-based immutable singleton target on NVMe + - usb: gadget: u_ether: fix regression in setting fixed MAC address + - tcp: add some entropy in __inet_hash_connect() + - tcp: use different parts of the port_offset for index and offset + - tcp: add small random increments to the source port + - tcp: dynamically allocate the perturb table used by source ports + - tcp: increase source port perturb table to 2^16 + - tcp: drop the hash_32() part from the index calculation + - arm64: mm: Don't invalidate FROM_DEVICE buffers at start of DMA transfer + - Linux 5.4.201 + * Focal update: v5.4.200 upstream stable release (LP: #1983152) + - Revert "UBUNTU: SAUCE: random: Make getrandom() ready earlier" + - 9p: missing chunk of "fs/9p: Don't update file type when updating file + attributes" + - bpf: Fix incorrect memory charge cost calculation in stack_map_alloc() + - nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION + - crypto: blake2s - generic C library implementation and selftest + - lib/crypto: blake2s: move hmac construction into wireguard + - lib/crypto: sha1: re-roll loops to reduce code size + - compat_ioctl: remove /dev/random commands + - random: don't forget compat_ioctl on urandom + - random: Don't wake crng_init_wait when crng_init == 1 + - random: Add a urandom_read_nowait() for random APIs that don't warn + - random: add GRND_INSECURE to return best-effort non-cryptographic bytes + - random: ignore GRND_RANDOM in getentropy(2) + - random: make /dev/random be almost like /dev/urandom + - random: remove the blocking pool + - random: delete code to pull data into pools + - random: remove kernel.random.read_wakeup_threshold + - random: remove unnecessary unlikely() + - random: convert to ENTROPY_BITS for better code readability + - random: Add and use pr_fmt() + - random: fix typo in add_timer_randomness() + - random: remove some dead code of poolinfo + - random: split primary/secondary crng init paths + - random: avoid warnings for !CONFIG_NUMA builds + - x86: Remove arch_has_random, arch_has_random_seed + - powerpc: Remove arch_has_random, arch_has_random_seed + - s390: Remove arch_has_random, arch_has_random_seed + - linux/random.h: Remove arch_has_random, arch_has_random_seed + - linux/random.h: Use false with bool + - linux/random.h: Mark CONFIG_ARCH_RANDOM functions __must_check + - powerpc: Use bool in archrandom.h + - random: add arch_get_random_*long_early() + - random: avoid arch_get_random_seed_long() when collecting IRQ randomness + - random: remove dead code left over from blocking pool + - MAINTAINERS: co-maintain random.c + - crypto: blake2s - include instead of + - crypto: blake2s - adjust include guard naming + - random: document add_hwgenerator_randomness() with other input functions + - random: remove unused irq_flags argument from add_interrupt_randomness() + - random: use BLAKE2s instead of SHA1 in extraction + - random: do not sign extend bytes for rotation when mixing + - random: do not re-init if crng_reseed completes before primary init + - random: mix bootloader randomness into pool + - random: harmonize "crng init done" messages + - random: use IS_ENABLED(CONFIG_NUMA) instead of ifdefs + - random: initialize ChaCha20 constants with correct endianness + - random: early initialization of ChaCha constants + - random: avoid superfluous call to RDRAND in CRNG extraction + - random: don't reset crng_init_cnt on urandom_read() + - random: fix typo in comments + - random: cleanup poolinfo abstraction + - random: cleanup integer types + - random: remove incomplete last_data logic + - random: remove unused extract_entropy() reserved argument + - random: rather than entropy_store abstraction, use global + - random: remove unused OUTPUT_POOL constants + - random: de-duplicate INPUT_POOL constants + - random: prepend remaining pool constants with POOL_ + - random: cleanup fractional entropy shift constants + - random: access input_pool_data directly rather than through pointer + - random: selectively clang-format where it makes sense + - random: simplify arithmetic function flow in account() + - random: continually use hwgenerator randomness + - random: access primary_pool directly rather than through pointer + - random: only call crng_finalize_init() for primary_crng + - random: use computational hash for entropy extraction + - random: simplify entropy debiting + - random: use linear min-entropy accumulation crediting + - random: always wake up entropy writers after extraction + - random: make credit_entropy_bits() always safe + - random: remove use_input_pool parameter from crng_reseed() + - random: remove batched entropy locking + - random: fix locking in crng_fast_load() + - random: use RDSEED instead of RDRAND in entropy extraction + - random: get rid of secondary crngs + - random: inline leaves of rand_initialize() + - random: ensure early RDSEED goes through mixer on init + - random: do not xor RDRAND when writing into /dev/random + - random: absorb fast pool into input pool after fast load + - random: use simpler fast key erasure flow on per-cpu keys + - random: use hash function for crng_slow_load() + - random: make more consistent use of integer types + - random: remove outdated INT_MAX >> 6 check in urandom_read() + - random: zero buffer after reading entropy from userspace + - random: fix locking for crng_init in crng_reseed() + - random: tie batched entropy generation to base_crng generation + - random: remove ifdef'd out interrupt bench + - random: remove unused tracepoints + - random: add proper SPDX header + - random: deobfuscate irq u32/u64 contributions + - random: introduce drain_entropy() helper to declutter crng_reseed() + - random: remove useless header comment + - random: remove whitespace and reorder includes + - random: group initialization wait functions + - random: group crng functions + - random: group entropy extraction functions + - random: group entropy collection functions + - random: group userspace read/write functions + - random: group sysctl functions + - random: rewrite header introductory comment + - random: defer fast pool mixing to worker + - random: do not take pool spinlock at boot + - random: unify early init crng load accounting + - random: check for crng_init == 0 in add_device_randomness() + - random: pull add_hwgenerator_randomness() declaration into random.h + - random: clear fast pool, crng, and batches in cpuhp bring up + - random: round-robin registers as ulong, not u32 + - random: only wake up writers after zap if threshold was passed + - random: cleanup UUID handling + - random: unify cycles_t and jiffies usage and types + - random: do crng pre-init loading in worker rather than irq + - random: give sysctl_random_min_urandom_seed a more sensible value + - random: don't let 644 read-only sysctls be written to + - random: replace custom notifier chain with standard one + - random: use SipHash as interrupt entropy accumulator + - random: make consistent usage of crng_ready() + - random: reseed more often immediately after booting + - random: check for signal and try earlier when generating entropy + - random: skip fast_init if hwrng provides large chunk of entropy + - random: treat bootloader trust toggle the same way as cpu trust toggle + - random: re-add removed comment about get_random_{u32,u64} reseeding + - random: mix build-time latent entropy into pool at init + - random: do not split fast init input in add_hwgenerator_randomness() + - random: do not allow user to keep crng key around on stack + - random: check for signal_pending() outside of need_resched() check + - random: check for signals every PAGE_SIZE chunk of /dev/[u]random + - random: allow partial reads if later user copies fail + - random: make random_get_entropy() return an unsigned long + - random: document crng_fast_key_erasure() destination possibility + - random: fix sysctl documentation nits + - init: call time_init() before rand_initialize() + - ia64: define get_cycles macro for arch-override + - s390: define get_cycles macro for arch-override + - parisc: define get_cycles macro for arch-override + - alpha: define get_cycles macro for arch-override + - powerpc: define get_cycles macro for arch-override + - timekeeping: Add raw clock fallback for random_get_entropy() + - m68k: use fallback for random_get_entropy() instead of zero + - mips: use fallback for random_get_entropy() instead of just c0 random + - arm: use fallback for random_get_entropy() instead of zero + - nios2: use fallback for random_get_entropy() instead of zero + - x86/tsc: Use fallback for random_get_entropy() instead of zero + - um: use fallback for random_get_entropy() instead of zero + - sparc: use fallback for random_get_entropy() instead of zero + - xtensa: use fallback for random_get_entropy() instead of zero + - random: insist on random_get_entropy() existing in order to simplify + - random: do not use batches when !crng_ready() + - random: use first 128 bits of input as fast init + - random: do not pretend to handle premature next security model + - random: order timer entropy functions below interrupt functions + - random: do not use input pool from hard IRQs + - random: help compiler out with fast_mix() by using simpler arguments + - siphash: use one source of truth for siphash permutations + - random: use symbolic constants for crng_init states + - random: avoid initializing twice in credit race + - random: move initialization out of reseeding hot path + - random: remove ratelimiting for in-kernel unseeded randomness + - random: use proper jiffies comparison macro + - random: handle latent entropy and command line from random_init() + - random: credit architectural init the exact amount + - random: use static branch for crng_ready() + - random: remove extern from functions in header + - random: use proper return types on get_random_{int,long}_wait() + - random: make consistent use of buf and len + - random: move initialization functions out of hot pages + - random: move randomize_page() into mm where it belongs + - random: unify batched entropy implementations + - random: convert to using fops->read_iter() + - random: convert to using fops->write_iter() + - random: wire up fops->splice_{read,write}_iter() + - random: check for signals after page of pool writes + - Revert "random: use static branch for crng_ready()" + - crypto: drbg - always seeded with SP800-90B compliant noise source + - crypto: drbg - prepare for more fine-grained tracking of seeding state + - crypto: drbg - track whether DRBG was seeded with !rng_is_initialized() + - crypto: drbg - move dynamic ->reseed_threshold adjustments to __drbg_seed() + - crypto: drbg - always try to free Jitter RNG instance + - crypto: drbg - make reseeding from get_random_bytes() synchronous + - random: avoid checking crng_ready() twice in random_init() + - random: mark bootloader randomness code as __init + - random: account for arch randomness in bits + - powerpc/kasan: Silence KASAN warnings in __get_wchan() + - ASoC: nau8822: Add operation for internal PLL off and on + - dma-debug: make things less spammy under memory pressure + - ASoC: cs42l52: Fix TLV scales for mixer controls + - ASoC: cs35l36: Update digital volume TLV + - ASoC: cs53l30: Correct number of volume levels on SX controls + - ASoC: cs42l52: Correct TLV for Bypass Volume + - ASoC: cs42l56: Correct typo in minimum level for SX volume controls + - ata: libata-core: fix NULL pointer deref in ata_host_alloc_pinfo() + - ASoC: wm8962: Fix suspend while playing music + - ASoC: es8328: Fix event generation for deemphasis control + - ASoC: wm_adsp: Fix event generation for wm_adsp_fw_put() + - scsi: vmw_pvscsi: Expand vcpuHint to 16 bits + - scsi: lpfc: Fix port stuck in bypassed state after LIP in PT2PT topology + - scsi: lpfc: Allow reduced polling rate for nvme_admin_async_event cmd + completion + - scsi: ipr: Fix missing/incorrect resource cleanup in error case + - scsi: pmcraid: Fix missing resource cleanup in error case + - ALSA: hda/realtek - Add HW8326 support + - virtio-mmio: fix missing put_device() when vm_cmdline_parent registration + failed + - nfc: nfcmrvl: Fix memory leak in nfcmrvl_play_deferred + - ipv6: Fix signed integer overflow in l2tp_ip6_sendmsg + - net: ethernet: mtk_eth_soc: fix misuse of mem alloc interface + netdev[napi]_alloc_frag + - random: credit cpu and bootloader seeds by default + - pNFS: Don't keep retrying if the server replied NFS4ERR_LAYOUTUNAVAILABLE + - clocksource: hyper-v: unexport __init-annotated hv_init_clocksource() + - i40e: Fix adding ADQ filter to TC0 + - i40e: Fix calculating the number of queue pairs + - i40e: Fix call trace in setup_tx_descriptors + - tty: goldfish: Fix free_irq() on remove + - misc: atmel-ssc: Fix IRQ check in ssc_probe + - mlxsw: spectrum_cnt: Reorder counter pools + - net: bgmac: Fix an erroneous kfree() in bgmac_remove() + - arm64: ftrace: fix branch range checks + - certs/blacklist_hashes.c: fix const confusion in certs blacklist + - faddr2line: Fix overlapping text section failures, the sequel + - irqchip/gic/realview: Fix refcount leak in realview_gic_of_init + - irqchip/gic-v3: Fix error handling in gic_populate_ppi_partitions + - irqchip/gic-v3: Fix refcount leak in gic_populate_ppi_partitions + - i2c: designware: Use standard optional ref clock implementation + - comedi: vmk80xx: fix expression for tx buffer size + - USB: serial: option: add support for Cinterion MV31 with new baseline + - USB: serial: io_ti: add Agilent E5805A support + - usb: dwc2: Fix memory leak in dwc2_hcd_init + - usb: gadget: lpc32xx_udc: Fix refcount leak in lpc32xx_udc_probe + - serial: 8250: Store to lsr_save_flags after lsr read + - dm mirror log: round up region bitmap size to BITS_PER_LONG + - ext4: fix bug_on ext4_mb_use_inode_pa + - ext4: make variable "count" signed + - ext4: add reserved GDT blocks check + - ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP machine + - virtio-pci: Remove wrong address verification in vp_del_vqs() + - net/sched: act_police: more accurate MTU policing + - net: openvswitch: fix leak of nested actions + - arm64: kprobes: Use BRK instead of single-step when executing instructions + out-of-line + - RISC-V: fix barrier() use in + - riscv: Less inefficient gcc tishift helpers (and export their symbols) + - powerpc/mm: Switch obsolete dssall to .long + - Linux 5.4.200 + * Focal update: v5.4.199 upstream stable release (LP: #1983150) + - Linux 5.4.199 + * Focal update: v5.4.198 upstream stable release (LP: #1982409) + - binfmt_flat: do not stop relocating GOT entries prematurely on riscv + - ALSA: hda/realtek - Fix microphone noise on ASUS TUF B550M-PLUS + - USB: serial: option: add Quectel BG95 modem + - USB: new quirk for Dell Gen 2 devices + - perf/x86/intel: Fix event constraints for ICL + - ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP + - ptrace/xtensa: Replace PT_SINGLESTEP with TIF_SINGLESTEP + - ptrace: Reimplement PTRACE_KILL by always sending SIGKILL + - btrfs: add "0x" prefix for unsupported optional features + - btrfs: repair super block num_devices automatically + - drm/virtio: fix NULL pointer dereference in virtio_gpu_conn_get_modes + - mwifiex: add mutex lock for call in mwifiex_dfs_chan_sw_work_queue + - b43legacy: Fix assigning negative value to unsigned variable + - b43: Fix assigning negative value to unsigned variable + - ipw2x00: Fix potential NULL dereference in libipw_xmit() + - ipv6: fix locking issues with loops over idev->addr_list + - fbcon: Consistently protect deferred_takeover with console_lock() + - ACPICA: Avoid cache flush inside virtual machines + - drm/komeda: return early if drm_universal_plane_init() fails. + - ALSA: jack: Access input_dev under mutex + - spi: spi-rspi: Remove setting {src,dst}_{addr,addr_width} based on DMA + direction + - tools/power turbostat: fix ICX DRAM power numbers + - drm/amd/pm: fix double free in si_parse_power_table() + - ath9k: fix QCA9561 PA bias level + - media: venus: hfi: avoid null dereference in deinit + - media: pci: cx23885: Fix the error handling in cx23885_initdev() + - media: cx25821: Fix the warning when removing the module + - md/bitmap: don't set sb values if can't pass sanity check + - mmc: jz4740: Apply DMA engine limits to maximum segment size + - scsi: megaraid: Fix error check return value of register_chrdev() + - drm/plane: Move range check for format_count earlier + - drm/amd/pm: fix the compile warning + - arm64: compat: Do not treat syscall number as ESR_ELx for a bad syscall + - drm: msm: fix error check return value of irq_of_parse_and_map() + - ipv6: Don't send rs packets to the interface of ARPHRD_TUNNEL + - net/mlx5: fs, delete the FTE when there are no rules attached to it + - ASoC: dapm: Don't fold register value changes into notifications + - mlxsw: spectrum_dcb: Do not warn about priority changes + - drm/amdgpu/ucode: Remove firmware load type check in amdgpu_ucode_free_bo + - HID: bigben: fix slab-out-of-bounds Write in bigben_probe + - ASoC: tscs454: Add endianness flag in snd_soc_component_driver + - s390/preempt: disable __preempt_count_add() optimization for + PROFILE_ALL_BRANCHES + - spi: stm32-qspi: Fix wait_cmd timeout in APM mode + - dma-debug: change allocation mode from GFP_NOWAIT to GFP_ATIOMIC + - ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default + - ipmi:ssif: Check for NULL msg when handling events and messages + - ipmi: Fix pr_fmt to avoid compilation issues + - rtlwifi: Use pr_warn instead of WARN_ONCE + - media: coda: limit frame interval enumeration to supported encoder frame + sizes + - media: cec-adap.c: fix is_configuring state + - openrisc: start CPU timer early in boot + - nvme-pci: fix a NULL pointer dereference in nvme_alloc_admin_tags + - ASoC: rt5645: Fix errorenous cleanup order + - nbd: Fix hung on disconnect request if socket is closed before + - net: phy: micrel: Allow probing without .driver_data + - media: exynos4-is: Fix compile warning + - ASoC: max98357a: remove dependency on GPIOLIB + - rxrpc: Return an error to sendmsg if call failed + - eth: tg3: silence the GCC 12 array-bounds warning + - selftests/bpf: fix btf_dump/btf_dump due to recent clang change + - IB/rdmavt: add missing locks in rvt_ruc_loopback + - ARM: dts: ox820: align interrupt controller node name with dtschema + - PM / devfreq: rk3399_dmc: Disable edev on remove() + - fs: jfs: fix possible NULL pointer dereference in dbFree() + - ARM: OMAP1: clock: Fix UART rate reporting algorithm + - powerpc/fadump: Fix fadump to work with a different endian capture kernel + - fat: add ratelimit to fat*_ent_bread() + - ARM: versatile: Add missing of_node_put in dcscb_init + - ARM: dts: exynos: add atmel,24c128 fallback to Samsung EEPROM + - ARM: hisi: Add missing of_node_put after of_find_compatible_node + - PCI: Avoid pci_dev_lock() AB/BA deadlock with sriov_numvfs_store() + - tracing: incorrect isolate_mote_t cast in mm_vmscan_lru_isolate + - powerpc/xics: fix refcount leak in icp_opal_init() + - powerpc/powernv: fix missing of_node_put in uv_init() + - macintosh/via-pmu: Fix build failure when CONFIG_INPUT is disabled + - powerpc/iommu: Add missing of_node_put in iommu_init_early_dart + - RDMA/hfi1: Prevent panic when SDMA is disabled + - drm: fix EDID struct for old ARM OABI format + - ath9k: fix ar9003_get_eepmisc + - drm/edid: fix invalid EDID extension block filtering + - drm/bridge: adv7511: clean up CEC adapter when probe fails + - ASoC: mediatek: Fix error handling in mt8173_max98090_dev_probe + - ASoC: mediatek: Fix missing of_node_put in mt2701_wm8960_machine_probe + - x86/delay: Fix the wrong asm constraint in delay_loop() + - drm/mediatek: Fix mtk_cec_mask() + - drm/vc4: txp: Don't set TXP_VSTART_AT_EOF + - drm/vc4: txp: Force alpha to be 0xff if it's disabled + - bpf: Fix excessive memory allocation in stack_map_alloc() + - nl80211: show SSID for P2P_GO interfaces + - drm/komeda: Fix an undefined behavior bug in komeda_plane_add() + - drm: mali-dp: potential dereference of null pointer + - spi: spi-ti-qspi: Fix return value handling of wait_for_completion_timeout + - NFC: NULL out the dev->rfkill to prevent UAF + - efi: Add missing prototype for efi_capsule_setup_info + - drbd: fix duplicate array initializer + - HID: hid-led: fix maximum brightness for Dream Cheeky + - HID: elan: Fix potential double free in elan_input_configured + - drm/bridge: Fix error handling in analogix_dp_probe + - sched/fair: Fix cfs_rq_clock_pelt() for throttled cfs_rq + - spi: img-spfi: Fix pm_runtime_get_sync() error checking + - cpufreq: Fix possible race in cpufreq online error path + - ath9k_htc: fix potential out of bounds access with invalid + rxstatus->rs_keyix + - inotify: show inotify mask flags in proc fdinfo + - fsnotify: fix wrong lockdep annotations + - of: overlay: do not break notify on NOTIFY_{OK|STOP} + - scsi: ufs: core: Exclude UECxx from SFR dump list + - x86/pm: Fix false positive kmemleak report in msr_build_context() + - x86/speculation: Add missing prototype for unpriv_ebpf_notify() + - ASoC: rk3328: fix disabling mclk on pclk probe failure + - perf tools: Add missing headers needed by util/data.h + - drm/msm/disp/dpu1: set vbif hw config to NULL to avoid use after memory free + during pm runtime resume + - drm/msm/dsi: fix error checks and return values for DSI xmit functions + - drm/msm/hdmi: check return value after calling + platform_get_resource_byname() + - drm/msm/hdmi: fix error check return value of irq_of_parse_and_map() + - drm/rockchip: vop: fix possible null-ptr-deref in vop_bind() + - virtio_blk: fix the discard_granularity and discard_alignment queue limits + - x86: Fix return value of __setup handlers + - irqchip/exiu: Fix acknowledgment of edge triggered interrupts + - irqchip/aspeed-i2c-ic: Fix irq_of_parse_and_map() return value + - x86/mm: Cleanup the control_va_addr_alignment() __setup handler + - regulator: core: Fix enable_count imbalance with EXCLUSIVE_GET + - drm/msm/mdp5: Return error code in mdp5_pipe_release when deadlock is + detected + - drm/msm/mdp5: Return error code in mdp5_mixer_release when deadlock is + detected + - drm/msm: return an error pointer in msm_gem_prime_get_sg_table() + - media: uvcvideo: Fix missing check to determine if element is found in list + - iomap: iomap_write_failed fix + - Revert "cpufreq: Fix possible race in cpufreq online error path" + - perf/amd/ibs: Use interrupt regs ip for stack unwinding + - ASoC: fsl: Fix refcount leak in imx_sgtl5000_probe + - ASoC: mxs-saif: Fix refcount leak in mxs_saif_probe + - regulator: pfuze100: Fix refcount leak in pfuze_parse_regulators_dt + - scripts/faddr2line: Fix overlapping text section failures + - media: aspeed: Fix an error handling path in aspeed_video_probe() + - media: st-delta: Fix PM disable depth imbalance in delta_probe + - media: exynos4-is: Change clk_disable to clk_disable_unprepare + - media: pvrusb2: fix array-index-out-of-bounds in pvr2_i2c_core_init + - media: vsp1: Fix offset calculation for plane cropping + - Bluetooth: fix dangling sco_conn and use-after-free in sco_sock_timeout + - m68k: math-emu: Fix dependencies of math emulation support + - sctp: read sk->sk_bound_dev_if once in sctp_rcv() + - media: ov7670: remove ov7670_power_off from ov7670_remove + - ext4: reject the 'commit' option on ext2 filesystems + - drm/msm/a6xx: Fix refcount leak in a6xx_gpu_init + - drm: msm: fix possible memory leak in mdp5_crtc_cursor_set() + - thermal/drivers/broadcom: Fix potential NULL dereference in sr_thermal_probe + - ASoC: wm2000: fix missing clk_disable_unprepare() on error in + wm2000_anc_transition() + - NFC: hci: fix sleep in atomic context bugs in nfc_hci_hcp_message_tx + - rxrpc: Fix listen() setting the bar too high for the prealloc rings + - rxrpc: Don't try to resend the request if we're receiving the reply + - rxrpc: Fix overlapping ACK accounting + - rxrpc: Don't let ack.previousPacket regress + - rxrpc: Fix decision on when to generate an IDLE ACK + - net/smc: postpone sk_refcnt increment in connect() + - arm64: dts: rockchip: Move drive-impedance-ohm to emmc phy on rk3399 + - ARM: dts: suniv: F1C100: fix watchdog compatible + - soc: qcom: smp2p: Fix missing of_node_put() in smp2p_parse_ipc + - soc: qcom: smsm: Fix missing of_node_put() in smsm_parse_ipc + - PCI: cadence: Fix find_first_zero_bit() limit + - PCI: rockchip: Fix find_first_zero_bit() limit + - KVM: nVMX: Leave most VM-Exit info fields unmodified on failed VM-Entry + - can: xilinx_can: mark bit timing constants as const + - ARM: dts: bcm2835-rpi-zero-w: Fix GPIO line name for Wifi/BT + - ARM: dts: bcm2837-rpi-cm3-io3: Fix GPIO line names for SMPS I2C + - ARM: dts: bcm2837-rpi-3-b-plus: Fix GPIO line name of power LED + - ARM: dts: bcm2835-rpi-b: Fix GPIO line names + - misc: ocxl: fix possible double free in ocxl_file_register_afu + - crypto: marvell/cesa - ECB does not IV + - arm: mediatek: select arch timer for mt7629 + - powerpc/fadump: fix PT_LOAD segment for boot memory area + - mfd: ipaq-micro: Fix error check return value of platform_get_irq() + - scsi: fcoe: Fix Wstringop-overflow warnings in fcoe_wwn_from_mac() + - firmware: arm_scmi: Fix list protocols enumeration in the base protocol + - nvdimm: Allow overwrite in the presence of disabled dimms + - pinctrl: mvebu: Fix irq_of_parse_and_map() return value + - drivers/base/node.c: fix compaction sysfs file leak + - dax: fix cache flush on PMD-mapped pages + - powerpc/8xx: export 'cpm_setbrg' for modules + - powerpc/idle: Fix return value of __setup() handler + - powerpc/4xx/cpm: Fix return value of __setup() handler + - proc: fix dentry/inode overinstantiating under /proc/${pid}/net + - ipc/mqueue: use get_tree_nodev() in mqueue_get_tree() + - PCI: imx6: Fix PERST# start-up sequence + - tty: fix deadlock caused by calling printk() under tty_port->lock + - crypto: cryptd - Protect per-CPU resource by disabling BH. + - Input: sparcspkr - fix refcount leak in bbc_beep_probe + - powerpc/64: Only WARN if __pa()/__va() called with bad addresses + - powerpc/perf: Fix the threshold compare group constraint for power9 + - macintosh: via-pmu and via-cuda need RTC_LIB + - powerpc/fsl_rio: Fix refcount leak in fsl_rio_setup + - mfd: davinci_voicecodec: Fix possible null-ptr-deref davinci_vc_probe() + - mailbox: forward the hrtimer if not queued and under a lock + - RDMA/hfi1: Prevent use of lock before it is initialized + - Input: stmfts - do not leave device disabled in stmfts_input_open + - f2fs: fix dereference of stale list iterator after loop body + - iommu/mediatek: Add list_del in mtk_iommu_remove + - i2c: at91: use dma safe buffers + - i2c: at91: Initialize dma_buf in at91_twi_xfer() + - NFS: Do not report EINTR/ERESTARTSYS as mapping errors + - NFS: Do not report flush errors in nfs_write_end() + - NFS: Don't report errors from nfs_pageio_complete() more than once + - NFSv4/pNFS: Do not fail I/O when we fail to allocate the pNFS layout + - video: fbdev: clcdfb: Fix refcount leak in clcdfb_of_vram_setup + - dmaengine: stm32-mdma: remove GISR1 register + - iommu/amd: Increase timeout waiting for GA log enablement + - perf c2c: Use stdio interface if slang is not supported + - perf jevents: Fix event syntax error caused by ExtSel + - f2fs: fix to avoid f2fs_bug_on() in dec_valid_node_count() + - f2fs: fix to do sanity check on block address in f2fs_do_zero_range() + - f2fs: fix to clear dirty inode in f2fs_evict_inode() + - f2fs: fix deadloop in foreground GC + - f2fs: don't need inode lock for system hidden quota + - f2fs: fix fallocate to use file_modified to update permissions consistently + - wifi: mac80211: fix use-after-free in chanctx code + - iwlwifi: mvm: fix assert 1F04 upon reconfig + - fs-writeback: writeback_sb_inodes:Recalculate 'wrote' according skipped + pages + - efi: Do not import certificates from UEFI Secure Boot for T2 Macs + - bfq: Split shared queues on move between cgroups + - bfq: Update cgroup information before merging bio + - bfq: Track whether bfq_group is still online + - ext4: fix use-after-free in ext4_rename_dir_prepare + - ext4: fix warning in ext4_handle_inode_extension + - ext4: fix bug_on in ext4_writepages + - ext4: verify dir block before splitting it + - ext4: avoid cycles in directory h-tree + - ACPI: property: Release subnode properties with data nodes + - tracing: Fix potential double free in create_var_ref() + - PCI/PM: Fix bridge_d3_blacklist[] Elo i2 overwrite of Gigabyte X299 + - PCI: qcom: Fix runtime PM imbalance on probe errors + - PCI: qcom: Fix unbalanced PHY init on probe errors + - mm, compaction: fast_find_migrateblock() should return pfn in the target + zone + - dlm: fix plock invalid read + - dlm: fix missing lkb refcount handling + - ocfs2: dlmfs: fix error handling of user_dlm_destroy_lock + - scsi: dc395x: Fix a missing check on list iterator + - scsi: ufs: qcom: Add a readl() to make sure ref_clk gets enabled + - drm/amdgpu/cs: make commands with 0 chunks illegal behaviour. + - drm/etnaviv: check for reaped mapping in etnaviv_iommu_unmap_gem + - drm/nouveau/clk: Fix an incorrect NULL check on list iterator + - drm/bridge: analogix_dp: Grab runtime PM reference for DP-AUX + - md: fix an incorrect NULL check in does_sb_need_changing + - md: fix an incorrect NULL check in md_reload_sb + - mtd: cfi_cmdset_0002: Move and rename + chip_check/chip_ready/chip_good_for_write + - media: coda: Fix reported H264 profile + - media: coda: Add more H264 levels for CODA960 + - Kconfig: Add option for asm goto w/ tied outputs to workaround clang-13 bug + - RDMA/hfi1: Fix potential integer multiplication overflow errors + - irqchip/armada-370-xp: Do not touch Performance Counter Overflow on A375, + A38x, A39x + - irqchip: irq-xtensa-mx: fix initial IRQ affinity + - mac80211: upgrade passive scan to active scan on DFS channels after beacon + rx + - um: chan_user: Fix winch_tramp() return value + - um: Fix out-of-bounds read in LDT setup + - iommu/msm: Fix an incorrect NULL check on list iterator + - nodemask.h: fix compilation error with GCC12 + - hugetlb: fix huge_pmd_unshare address update + - rtl818x: Prevent using not initialized queues + - ASoC: rt5514: Fix event generation for "DSP Voice Wake Up" control + - carl9170: tx: fix an incorrect use of list iterator + - serial: pch: don't overwrite xmit->buf[0] by x_char + - tilcdc: tilcdc_external: fix an incorrect NULL check on list iterator + - gma500: fix an incorrect NULL check on list iterator + - arm64: dts: qcom: ipq8074: fix the sleep clock frequency + - phy: qcom-qmp: fix struct clk leak on probe errors + - ARM: pxa: maybe fix gpio lookup tables + - docs/conf.py: Cope with removal of language=None in Sphinx 5.0.0 + - dt-bindings: gpio: altera: correct interrupt-cells + - blk-iolatency: Fix inflight count imbalances and IO hangs on offline + - phy: qcom-qmp: fix reset-controller leak on probe errors + - Kconfig: add config option for asm goto w/ outputs + - RDMA/rxe: Generate a completion for unsupported/invalid opcode + - MIPS: IP27: Remove incorrect `cpu_has_fpu' override + - bfq: Avoid merging queues with different parents + - bfq: Drop pointless unlock-lock pair + - bfq: Remove pointless bfq_init_rq() calls + - bfq: Get rid of __bio_blkcg() usage + - bfq: Make sure bfqg for which we are queueing requests is online + - block: fix bio_clone_blkg_association() to associate with proper blkcg_gq + - md: bcache: check the return value of kzalloc() in detached_dev_do_request() + - pcmcia: db1xxx_ss: restrict to MIPS_DB1XXX boards + - staging: greybus: codecs: fix type confusion of list iterator variable + - iio: adc: ad7124: Remove shift from scan_type + - tty: goldfish: Use tty_port_destroy() to destroy port + - tty: serial: owl: Fix missing clk_disable_unprepare() in owl_uart_probe + - tty: serial: fsl_lpuart: fix potential bug when using both of_alias_get_id + and ida_simple_get + - usb: usbip: fix a refcount leak in stub_probe() + - usb: usbip: add missing device lock on tweak configuration cmd + - USB: storage: karma: fix rio_karma_init return + - usb: musb: Fix missing of_node_put() in omap2430_probe + - staging: fieldbus: Fix the error handling path in + anybuss_host_common_probe() + - pwm: lp3943: Fix duty calculation in case period was clamped + - rpmsg: qcom_smd: Fix irq_of_parse_and_map() return value + - usb: dwc3: pci: Fix pm_runtime_get_sync() error checking + - firmware: stratix10-svc: fix a missing check on list iterator + - iio: adc: stmpe-adc: Fix wait_for_completion_timeout return value check + - iio: adc: sc27xx: fix read big scale voltage not right + - iio: adc: sc27xx: Fine tune the scale calibration values + - rpmsg: qcom_smd: Fix returning 0 if irq_of_parse_and_map() fails + - phy: qcom-qmp: fix pipe-clock imbalance on power-on failure + - serial: sifive: Report actual baud base rather than fixed 115200 + - coresight: cpu-debug: Replace mutex with mutex_trylock on panic notifier + - soc: rockchip: Fix refcount leak in rockchip_grf_init + - clocksource/drivers/riscv: Events are stopped during CPU suspend + - rtc: mt6397: check return value after calling platform_get_resource() + - serial: meson: acquire port->lock in startup() + - serial: 8250_fintek: Check SER_RS485_RTS_* only with RS485 + - serial: digicolor-usart: Don't allow CS5-6 + - serial: rda-uart: Don't allow CS5-6 + - serial: txx9: Don't allow CS5-6 + - serial: sh-sci: Don't allow CS5-6 + - serial: sifive: Sanitize CSIZE and c_iflag + - serial: st-asc: Sanitize CSIZE and correct PARENB for CS7 + - serial: stm32-usart: Correct CSIZE, bits, and parity + - firmware: dmi-sysfs: Fix memory leak in dmi_sysfs_register_handle + - bus: ti-sysc: Fix warnings for unbind for serial + - driver: base: fix UAF when driver_attach failed + - driver core: fix deadlock in __device_attach + - watchdog: ts4800_wdt: Fix refcount leak in ts4800_wdt_probe + - ASoC: fsl_sai: Fix FSL_SAI_xDR/xFR definition + - clocksource/drivers/oxnas-rps: Fix irq_of_parse_and_map() return value + - s390/crypto: fix scatterwalk_unmap() callers in AES-GCM + - net: sched: fixed barrier to prevent skbuff sticking in qdisc backlog + - net: ethernet: mtk_eth_soc: out of bounds read in mtk_hwlro_get_fdir_entry() + - net: dsa: mv88e6xxx: Fix refcount leak in mv88e6xxx_mdios_register + - modpost: fix removing numeric suffixes + - jffs2: fix memory leak in jffs2_do_fill_super + - ubi: ubi_create_volume: Fix use-after-free when volume creation failed + - nfp: only report pause frame configuration for physical device + - net/mlx5: Don't use already freed action pointer + - net/mlx5e: Update netdev features after changing XDP state + - net: sched: add barrier to fix packet stuck problem for lockless qdisc + - tcp: tcp_rtx_synack() can be called from process context + - afs: Fix infinite loop found by xfstest generic/676 + - tipc: check attribute length for bearer name + - perf c2c: Fix sorting in percent_rmt_hitm_cmp() + - mips: cpc: Fix refcount leak in mips_cpc_default_phys_base + - tracing: Fix sleeping function called from invalid context on RT kernel + - tracing: Avoid adding tracer option before update_tracer_options + - f2fs: remove WARN_ON in f2fs_is_valid_blkaddr + - i2c: cadence: Increase timeout per message if necessary + - m68knommu: set ZERO_PAGE() to the allocated zeroed page + - m68knommu: fix undefined reference to `_init_sp' + - dmaengine: zynqmp_dma: In struct zynqmp_dma_chan fix desc_size data type + - NFSv4: Don't hold the layoutget locks across multiple RPC calls + - video: fbdev: pxa3xx-gcu: release the resources correctly in + pxa3xx_gcu_probe/remove() + - xprtrdma: treat all calls not a bcall when bc_serv is NULL + - netfilter: nat: really support inet nat without l3 address + - ata: pata_octeon_cf: Fix refcount leak in octeon_cf_probe + - netfilter: nf_tables: memleak flow rule from commit path + - xen: unexport __init-annotated xen_xlate_map_ballooned_pages() + - af_unix: Fix a data-race in unix_dgram_peer_wake_me(). + - bpf, arm64: Clear prog->jited_len along prog->jited + - net: dsa: lantiq_gswip: Fix refcount leak in gswip_gphy_fw_list + - net/mlx4_en: Fix wrong return value on ioctl EEPROM query failure + - SUNRPC: Fix the calculation of xdr->end in xdr_get_next_encode_buffer() + - net: mdio: unexport __init-annotated mdio_bus_init() + - net: xfrm: unexport __init-annotated xfrm4_protocol_init() + - net: ipv6: unexport __init-annotated seg6_hmac_init() + - net/mlx5: Rearm the FW tracer after each tracer event + - net/mlx5: fs, fail conflicting actions + - ip_gre: test csum_start instead of transport header + - net: altera: Fix refcount leak in altera_tse_mdio_create + - drm: imx: fix compiler warning with gcc-12 + - iio: dummy: iio_simple_dummy: check the return value of kstrdup() + - iio: st_sensors: Add a local lock for protecting odr + - lkdtm/usercopy: Expand size of "out of frame" object + - tty: synclink_gt: Fix null-pointer-dereference in slgt_clean() + - tty: Fix a possible resource leak in icom_probe + - drivers: staging: rtl8192u: Fix deadlock in ieee80211_beacons_stop() + - drivers: staging: rtl8192e: Fix deadlock in rtllib_beacons_stop() + - USB: host: isp116x: check return value after calling platform_get_resource() + - drivers: tty: serial: Fix deadlock in sa1100_set_termios() + - drivers: usb: host: Fix deadlock in oxu_bus_suspend() + - USB: hcd-pci: Fully suspend across freeze/thaw cycle + - usb: dwc2: gadget: don't reset gadget's driver->bus + - misc: rtsx: set NULL intfdata when probe fails + - extcon: Modify extcon device to be created after driver data is set + - clocksource/drivers/sp804: Avoid error on multiple instances + - staging: rtl8712: fix uninit-value in usb_read8() and friends + - staging: rtl8712: fix uninit-value in r871xu_drv_init() + - serial: msm_serial: disable interrupts in __msm_console_write() + - kernfs: Separate kernfs_pr_cont_buf and rename_lock. + - watchdog: wdat_wdt: Stop watchdog when rebooting the system + - md: protect md_unregister_thread from reentrancy + - scsi: myrb: Fix up null pointer access on myrb_cleanup() + - ceph: allow ceph.dir.rctime xattr to be updatable + - drm/radeon: fix a possible null pointer dereference + - modpost: fix undefined behavior of is_arm_mapping_symbol() + - x86/cpu: Elide KCSAN for cpu_has() and friends + - nbd: call genl_unregister_family() first in nbd_cleanup() + - nbd: fix race between nbd_alloc_config() and module removal + - cifs: version operations for smb20 unneeded when legacy support disabled + - nodemask: Fix return values to be unsigned + - vringh: Fix loop descriptors check in the indirect cases + - scripts/gdb: change kernel config dumping method + - ALSA: hda/conexant - Fix loopback issue with CX20632 + - cifs: return errors during session setup during reconnects + - ata: libata-transport: fix {dma|pio|xfer}_mode sysfs files + - mmc: block: Fix CQE recovery reset success + - nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION + - nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling + - ixgbe: fix bcast packets Rx on VF after promisc removal + - ixgbe: fix unexpected VLAN Rx in promisc mode on VF + - Input: bcm5974 - set missing URB_NO_TRANSFER_DMA_MAP urb flag + - powerpc/32: Fix overread/overwrite of thread_struct via ptrace + - md/raid0: Ignore RAID0 layout if the second zone has only one device + - mtd: cfi_cmdset_0002: Use chip_ready() for write on S29GL064N + - tcp: fix tcp_mtup_probe_success vs wrong snd_cwnd + - Linux 5.4.198 + * Focal update: v5.4.197 upstream stable release (LP: #1981758) + - x86/pci/xen: Disable PCI/MSI[-X] masking for XEN_HVM guests + - staging: rtl8723bs: prevent ->Ssid overflow in rtw_wx_set_scan() + - Input: goodix - fix spurious key release events + - tcp: change source port randomizarion at connect() time + - secure_seq: use the 64 bits of the siphash for port offset calculation + - media: vim2m: Register video device after setting up internals + - media: vim2m: initialize the media device earlier + - ACPI: sysfs: Make sparse happy about address space in use + - ACPI: sysfs: Fix BERT error region memory mapping + - pinctrl: sunxi: fix f1c100s uart2 function + - net: af_key: check encryption module availability consistency + - net: ftgmac100: Disable hardware checksum on AST2600 + - i2c: ismt: Provide a DMA buffer for Interrupt Cause Logging + - drivers: i2c: thunderx: Allow driver to work with ACPI defined TWSI + controllers + - assoc_array: Fix BUG_ON during garbage collect + - cfg80211: set custom regdomain after wiphy registration + - drm/i915: Fix -Wstringop-overflow warning in call to intel_read_wm_latency() + - exec: Force single empty string when argv is empty + - netfilter: conntrack: re-fetch conntrack after insertion + - crypto: ecrdsa - Fix incorrect use of vli_cmp + - zsmalloc: fix races between asynchronous zspage free and page migration + - dm integrity: fix error code in dm_integrity_ctr() + - dm crypt: make printing of the key constant-time + - dm stats: add cond_resched when looping over entries + - dm verity: set DM_TARGET_IMMUTABLE feature flag + - raid5: introduce MD_BROKEN + - HID: multitouch: Add support for Google Whiskers Touchpad + - tpm: Fix buffer access in tpm2_get_tpm_pt() + - tpm: ibmvtpm: Correct the return value in tpm_ibmvtpm_probe() + - docs: submitting-patches: Fix crossref to 'The canonical patch format' + - NFS: Memory allocation failures are not server fatal errors + - NFSD: Fix possible sleep during nfsd4_release_lockowner() + - bpf: Enlarge offset check value to INT_MAX in bpf_skb_{load,store}_bytes + - Linux 5.4.197 + * Focal update: v5.4.196 upstream stable release (LP: #1981111) + - x86/xen: Make the boot CPU idle task reliable + - x86/xen: Make the secondary CPU idle tasks reliable + - rtc: fix use-after-free on device removal + - um: Cleanup syscall_handler_t definition/cast, fix warning + - Input: add bounds checking to input_set_capability() + - Input: stmfts - fix reference leak in stmfts_input_open + - crypto: stm32 - fix reference leak in stm32_crc_remove + - crypto: x86/chacha20 - Avoid spurious jumps to other functions + - ALSA: hda/realtek: Enable headset mic on Lenovo P360 + - nvme-multipath: fix hang when disk goes live over reconnect + - rtc: mc146818-lib: Fix the AltCentury for AMD platforms + - MIPS: lantiq: check the return value of kzalloc() + - drbd: remove usage of list iterator variable after loop + - platform/chrome: cros_ec_debugfs: detach log reader wq from devm + - ARM: 9191/1: arm/stacktrace, kasan: Silence KASAN warnings in unwind_frame() + - nilfs2: fix lockdep warnings in page operations for btree nodes + - nilfs2: fix lockdep warnings during disk space reclamation + - mmc: core: Specify timeouts for BKOPS and CACHE_FLUSH for eMMC + - mmc: block: Use generic_cmd6_time when modifying INAND_CMD38_ARG_EXT_CSD + - mmc: core: Default to generic_cmd6_time as timeout in __mmc_switch() + - SUNRPC: Clean up scheduling of autoclose + - SUNRPC: Prevent immediate close+reconnect + - SUNRPC: Don't call connect() more than once on a TCP socket + - ALSA: wavefront: Proper check of get_user() error + - perf: Fix sys_perf_event_open() race against self + - Fix double fget() in vhost_net_set_backend() + - PCI/PM: Avoid putting Elo i2 PCIe Ports in D3cold + - KVM: x86/mmu: Update number of zapped pages even if page list is stable + - crypto: qcom-rng - fix infinite loop on requests not multiple of WORD_SZ + - drm/dp/mst: fix a possible memory leak in fetch_monitor_name() + - dma-buf: fix use of DMA_BUF_SET_NAME_{A,B} in userspace + - ARM: dts: aspeed-g6: remove FWQSPID group in pinctrl dtsi + - ARM: dts: aspeed-g6: fix SPI1/SPI2 quad pin group + - net: macb: Increment rx bd head after allocating skb and buffer + - net/sched: act_pedit: sanitize shift argument before usage + - net: vmxnet3: fix possible use-after-free bugs in vmxnet3_rq_alloc_rx_buf() + - net: vmxnet3: fix possible NULL pointer dereference in vmxnet3_rq_cleanup() + - ice: fix possible under reporting of ethtool Tx and Rx statistics + - clk: at91: generated: consider range when calculating best rate + - net/qla3xxx: Fix a test in ql_reset_work() + - NFC: nci: fix sleep in atomic context bugs caused by nci_skb_alloc + - net/mlx5e: Properly block LRO when XDP is enabled + - ARM: 9196/1: spectre-bhb: enable for Cortex-A15 + - ARM: 9197/1: spectre-bhb: fix loop8 sequence for Thumb2 + - igb: skip phy status check where unavailable + - net: bridge: Clear offload_fwd_mark when passing frame up bridge interface. + - gpio: gpio-vf610: do not touch other bits when set the target bit + - gpio: mvebu/pwm: Refuse requests with inverted polarity + - perf bench numa: Address compiler error on s390 + - scsi: qla2xxx: Fix missed DMA unmap for aborted commands + - mac80211: fix rx reordering with non explicit / psmp ack policy + - selftests: add ping test with ping_group_range tuned + - ethernet: tulip: fix missing pci_disable_device() on error in + tulip_init_one() + - net: stmmac: fix missing pci_disable_device() on error in stmmac_pci_probe() + - net: atlantic: verify hw_head_ lies within TX buffer ring + - Input: ili210x - fix reset timing + - block: return ELEVATOR_DISCARD_MERGE if possible + - net: stmmac: disable Split Header (SPH) for Intel platforms + - firmware_loader: use kernel credentials when reading firmware + - ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk + - Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE"" + - x86/xen: fix booting 32-bit pv guest + - x86/xen: Mark cpu_bringup_and_idle() as dead_end_function + - i2c: mt7621: fix missing clk_disable_unprepare() on error in mtk_i2c_probe() + - afs: Fix afs_getattr() to refetch file status if callback break occurred + - Linux 5.4.196 + * CVE-2022-36946 + - netfilter: nf_queue: do not allow packet truncation below transport header + offset + * CVE-2021-33655 + - fbcon: Disallow setting font bigger than screen size + - fbcon: Prevent that screen size is smaller than font size + - fbmem: Check virtual screen sizes in fb_set_var() + + -- Joseph Salisbury Tue, 30 Aug 2022 12:38:02 -0400 + +linux-oracle (5.4.0-1082.90) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1082.90 -proposed tracker (LP: #1983937) + + [ Ubuntu: 5.4.0-125.141 ] + + * focal/linux: 5.4.0-125.141 -proposed tracker (LP: #1983947) + * nbd: requests can become stuck when disconnecting from server with qemu-nbd + (LP: #1896350) + - blk-mq: blk-mq: provide forced completion method + - blk-mq: move failure injection out of blk_mq_complete_request + - nbd: don't handle response without a corresponding request message + - nbd: make sure request completion won't concurrent + - nbd: don't clear 'NBD_CMD_INFLIGHT' flag if request is not completed + - nbd: fix io hung while disconnecting device + * CVE-2021-33656 + - vt: drop old FONT ioctls + * CVE-2021-33061 + - ixgbe: add the ability for the PF to disable VF link state + - ixgbe: add improvement for MDD response functionality + - ixgbevf: add disable link state + + -- Joseph Salisbury Fri, 12 Aug 2022 10:17:46 -0400 + +linux-oracle (5.4.0-1081.89) focal; urgency=medium + + [ Ubuntu: 5.4.0-124.140 ] + + * CVE-2022-2586 + - SAUCE: netfilter: nf_tables: do not allow SET_ID to refer to another table + - SAUCE: netfilter: nf_tables: do not allow RULE_ID to refer to another chain + * CVE-2022-2588 + - SAUCE: net_sched: cls_route: remove from list when handle is 0 + * CVE-2022-34918 + - netfilter: nf_tables: stricter validation of element data + + -- Thadeu Lima de Souza Cascardo Mon, 08 Aug 2022 03:41:31 -0300 + +linux-oracle (5.4.0-1080.88) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1080.88 -proposed tracker (LP: #1981274) + + * ARM64_SW_TTBR0_PAN Should Be Enabled For Oracle Kernels (LP: #1968902) + - [config] oracle: Enable CONFIG_ARM64_SW_TTBR0_PAN + + [ Ubuntu: 5.4.0-123.139 ] + + * focal/linux: 5.4.0-123.139 -proposed tracker (LP: #1981284) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.07.11) + * Hairpin traffic does not work with centralized NAT gw (LP: #1967856) + - net: openvswitch: fix misuse of the cached connection on tuple changes + * [UBUNTU 20.04] Include patches to avoid self-detected stall with Secure + Execution (LP: #1979296) + - KVM: s390: pv: add macros for UVC CC values + - KVM: s390: pv: avoid stalls when making pages secure + - KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm + * Focal update: v5.4.195 upstream stable release (LP: #1980407) + - batman-adv: Don't skb_split skbuffs with frag_list + - hwmon: (tmp401) Add OF device ID table + - mac80211: Reset MBSSID parameters upon connection + - net: Fix features skip in for_each_netdev_feature() + - ipv4: drop dst in multicast routing path + - drm/nouveau: Fix a potential theorical leak in nouveau_get_backlight_name() + - netlink: do not reset transport header in netlink_recvmsg() + - mac80211_hwsim: call ieee80211_tx_prepare_skb under RCU protection + - dim: initialize all struct fields + - hwmon: (ltq-cputemp) restrict it to SOC_XWAY + - s390/ctcm: fix variable dereferenced before check + - s390/ctcm: fix potential memory leak + - s390/lcs: fix variable dereferenced before check + - net/sched: act_pedit: really ensure the skb is writable + - net/smc: non blocking recvmsg() return -EAGAIN when no data and + signal_pending + - net: sfc: ef10: fix memory leak in efx_ef10_mtd_probe() + - gfs2: Fix filesystem block deallocation for short writes + - hwmon: (f71882fg) Fix negative temperature + - ASoC: max98090: Reject invalid values in custom control put() + - ASoC: max98090: Generate notifications on changes for custom control + - ASoC: ops: Validate input values in snd_soc_put_volsw_range() + - s390: disable -Warray-bounds + - net: emaclite: Don't advertise 1000BASE-T and do auto negotiation + - tcp: resalt the secret every 10 seconds + - tty: n_gsm: fix mux activation issues in gsm_config() + - usb: cdc-wdm: fix reading stuck on device close + - usb: typec: tcpci: Don't skip cleanup in .remove() on error + - USB: serial: pl2303: add device id for HP LM930 Display + - USB: serial: qcserial: add support for Sierra Wireless EM7590 + - USB: serial: option: add Fibocom L610 modem + - USB: serial: option: add Fibocom MA510 modem + - slimbus: qcom: Fix IRQ check in qcom_slim_probe + - serial: 8250_mtk: Fix UART_EFR register address + - serial: 8250_mtk: Fix register address for XON/XOFF character + - drm/nouveau/tegra: Stop using iommu_present() + - i40e: i40e_main: fix a missing check on list iterator + - cgroup/cpuset: Remove cpus_allowed/mems_allowed setup in cpuset_init_smp() + - drm/vmwgfx: Initialize drm_mode_fb_cmd2 + - MIPS: fix build with gcc-12 + - net: phy: Fix race condition on link status change + - arm[64]/memremap: don't abuse pfn_valid() to ensure presence of linear map + - ping: fix address binding wrt vrf + - tty/serial: digicolor: fix possible null-ptr-deref in digicolor_uart_probe() + - Linux 5.4.195 + * Focal update: v5.4.194 upstream stable release (LP: #1980399) + - MIPS: Use address-of operator on section symbols + - block: drbd: drbd_nl: Make conversion to 'enum drbd_ret_code' explicit + - drm/amd/display/dc/gpio/gpio_service: Pass around correct dce_{version, + environment} types + - drm/i915: Cast remain to unsigned long in eb_relocate_vma + - nfp: bpf: silence bitwise vs. logical OR warning + - can: grcan: grcan_probe(): fix broken system id check for errata workaround + needs + - can: grcan: only use the NAPI poll budget for RX + - arm: remove CONFIG_ARCH_HAS_HOLES_MEMORYMODEL + - [Config] updateconfigs for ARCH_HAS_HOLES_MEMORYMODEL + - KVM: x86/pmu: Refactoring find_arch_event() to pmc_perf_hw_id() + - x86/asm: Allow to pass macros to __ASM_FORM() + - x86: xen: kvm: Gather the definition of emulate prefixes + - x86: xen: insn: Decode Xen and KVM emulate-prefix signature + - x86: kprobes: Prohibit probing on instruction which has emulate prefix + - KVM: x86/svm: Account for family 17h event renumberings in + amd_pmc_perf_hw_id + - Bluetooth: Fix the creation of hdev->name + - mm: fix missing cache flush for all tail pages of compound page + - mm: hugetlb: fix missing cache flush in copy_huge_page_from_user() + - mm: userfaultfd: fix missing cache flush in mcopy_atomic_pte() and + __mcopy_atomic() + - Linux 5.4.194 + * Focal update: v5.4.193 upstream stable release (LP: #1979566) + - MIPS: Fix CP0 counter erratum detection for R4k CPUs + - parisc: Merge model and model name into one line in /proc/cpuinfo + - ALSA: fireworks: fix wrong return count shorter than expected by 4 bytes + - gpiolib: of: fix bounds check for 'gpio-reserved-ranges' + - Revert "SUNRPC: attempt AF_LOCAL connect on setup" + - firewire: fix potential uaf in outbound_phy_packet_callback() + - firewire: remove check of list iterator against head past the loop body + - firewire: core: extend card->lock in fw_core_handle_bus_reset + - ACPICA: Always create namespace nodes using acpi_ns_create_node() + - genirq: Synchronize interrupt thread startup + - ASoC: da7219: Fix change notifications for tone generator frequency + - ASoC: wm8958: Fix change notifications for DSP controls + - ASoC: meson: Fix event generation for G12A tohdmi mux + - s390/dasd: fix data corruption for ESE devices + - s390/dasd: prevent double format of tracks for ESE devices + - s390/dasd: Fix read for ESE with blksize < 4k + - s390/dasd: Fix read inconsistency for ESE DASD devices + - can: grcan: grcan_close(): fix deadlock + - can: grcan: use ofdev->dev when allocating DMA memory + - nfc: replace improper check device_is_registered() in netlink related + functions + - NFC: netlink: fix sleep in atomic bug when firmware download timeout + - hwmon: (adt7470) Fix warning on module removal + - ASoC: dmaengine: Restore NULL prepare_slave_config() callback + - RDMA/siw: Fix a condition race issue in MPA request processing + - net: ethernet: mediatek: add missing of_node_put() in mtk_sgmii_init() + - net: stmmac: dwmac-sun8i: add missing of_node_put() in + sun8i_dwmac_register_mdio_mux() + - net: emaclite: Add error handling for of_address_to_resource() + - selftests: mirror_gre_bridge_1q: Avoid changing PVID while interface is + operational + - bnxt_en: Fix possible bnxt_open() failure caused by wrong RFS flag + - smsc911x: allow using IRQ0 + - btrfs: always log symlinks in full mode + - net: igmp: respect RCU rules in ip_mc_source() and ip_mc_msfilter() + - drm/amdkfd: Use drm_priv to pass VM from KFD to amdgpu + - NFSv4: Don't invalidate inode attributes on delegation return + - kvm: x86/cpuid: Only provide CPUID leaf 0xA if host has architectural PMU + - x86/kvm: Preserve BSP MSR_KVM_POLL_CONTROL across suspend/resume + - KVM: LAPIC: Enable timer posted-interrupt only when mwait/hlt is advertised + - net: ipv6: ensure we call ipv6_mc_down() at most once + - block-map: add __GFP_ZERO flag for alloc_page in function bio_copy_kern + - mm: fix unexpected zeroed page mapping with zram swap + - ALSA: pcm: Fix races among concurrent hw_params and hw_free calls + - ALSA: pcm: Fix races among concurrent read/write and buffer changes + - ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls + - ALSA: pcm: Fix races among concurrent prealloc proc writes + - ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock + - tcp: make sure treq->af_specific is initialized + - dm: fix mempool NULL pointer race when completing IO + - dm: interlock pending dm_io and dm_wait_for_bios_completion + - PCI: aardvark: Clear all MSIs at setup + - PCI: aardvark: Fix reading MSI interrupt number + - mmc: rtsx: add 74 Clocks in power on flow + - Linux 5.4.193 + * CVE-2022-1679 + - SAUCE: ath9k: fix use-after-free in ath9k_hif_usb_rx_cb + * CVE-2022-28893 + - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free() + - SUNRPC: Don't leak sockets in xs_local_connect() + * CVE-2022-1734 + - nfc: nfcmrvl: main: reorder destructive operations in + nfcmrvl_nci_unregister_dev to avoid bugs + * CVE-2022-1652 + - floppy: use a statically allocated error counter + + -- Joseph Salisbury Thu, 14 Jul 2022 13:26:00 -0400 + +linux-oracle (5.4.0-1079.87) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1079.87 -proposed tracker (LP: #1979479) + + * Focal update: upstream stable patchset v5.4.192 (LP: #1979014) + - [Config] updateconfigs for BLK_DEV_FD_RAWCMD + - [Config] updateconfigs for NVM, NVM_PBLK + + [ Ubuntu: 5.4.0-122.138 ] + + * focal/linux: 5.4.0-122.138 -proposed tracker (LP: #1979489) + * Remove SAUCE patches from test_vxlan_under_vrf.sh in net of + ubuntu_kernel_selftests (LP: #1975691) + - Revert "UBUNTU: SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on + xfail" + - Revert "UBUNTU: SAUCE: selftests: net: Make test for VXLAN underlay in non- + default VRF an expected failure" + * Enable Asus USB-BT500 Bluetooth dongle(0b05:190e) (LP: #1976613) + - Bluetooth: btusb: Add flag to define wideband speech capability + - Bluetooth: btrtl: Add support for RTL8761B + - Bluetooth: btusb: Add 0x0b05:0x190e Realtek 8761BU (ASUS BT500) device. + * [UBUNTU 20.04] rcu stalls with many storage key guests (LP: #1975582) + - s390/gmap: voluntarily schedule during key setting + - s390/mm: use non-quiescing sske for KVM switch to keyed guest + * Ubuntu 5.4.0-117.132-generic 5.4.189 has BUG: kernel NULL pointer + dereference, address: 0000000000000034 (LP: #1978719) + - mm: rmap: explicitly reset vma->anon_vma in unlink_anon_vmas() + * Focal update: upstream stable patchset v5.4.192 (LP: #1979014) + - floppy: disable FDRAWCMD by default + - [Config] updateconfigs for BLK_DEV_FD_RAWCMD + - hamradio: defer 6pack kfree after unregister_netdev + - hamradio: remove needs_free_netdev to avoid UAF + - lightnvm: disable the subsystem + - [Config] updateconfigs for NVM, NVM_PBLK + - usb: mtu3: fix USB 3.0 dual-role-switch from device to host + - USB: quirks: add a Realtek card reader + - USB: quirks: add STRING quirk for VCOM device + - USB: serial: whiteheat: fix heap overflow in WHITEHEAT_GET_DTR_RTS + - USB: serial: cp210x: add PIDs for Kamstrup USB Meter Reader + - USB: serial: option: add support for Cinterion MV32-WA/MV32-WB + - USB: serial: option: add Telit 0x1057, 0x1058, 0x1075 compositions + - xhci: stop polling roothubs after shutdown + - xhci: increase usb U3 -> U0 link resume timeout from 100ms to 500ms + - iio: dac: ad5592r: Fix the missing return value. + - iio: dac: ad5446: Fix read_raw not returning set value + - iio: magnetometer: ak8975: Fix the error handling in ak8975_power_on() + - usb: misc: fix improper handling of refcount in uss720_probe() + - usb: typec: ucsi: Fix role swapping + - usb: gadget: uvc: Fix crash when encoding data for usb request + - usb: gadget: configfs: clear deactivation flag in + configfs_composite_unbind() + - usb: dwc3: core: Fix tx/rx threshold settings + - usb: dwc3: gadget: Return proper request status + - serial: imx: fix overrun interrupts in DMA mode + - serial: 8250: Also set sticky MCR bits in console restoration + - serial: 8250: Correct the clock for EndRun PTP/1588 PCIe device + - arch_topology: Do not set llc_sibling if llc_id is invalid + - hex2bin: make the function hex_to_bin constant-time + - hex2bin: fix access beyond string end + - video: fbdev: udlfb: properly check endpoint type + - arm64: dts: meson: remove CPU opps below 1GHz for G12B boards + - arm64: dts: meson: remove CPU opps below 1GHz for SM1 boards + - mtd: rawnand: fix ecc parameters for mt7622 + - USB: Fix xhci event ring dequeue pointer ERDP update issue + - ARM: dts: imx6qdl-apalis: Fix sgtl5000 detection issue + - phy: samsung: Fix missing of_node_put() in exynos_sata_phy_probe + - phy: samsung: exynos5250-sata: fix missing device put in probe error paths + - ARM: OMAP2+: Fix refcount leak in omap_gic_of_init + - phy: ti: omap-usb2: Fix error handling in omap_usb2_enable_clocks + - ARM: dts: at91: Map MCLK for wm8731 on at91sam9g20ek + - phy: mapphone-mdm6600: Fix PM error handling in phy_mdm6600_probe + - phy: ti: Add missing pm_runtime_disable() in serdes_am654_probe + - ARM: dts: Fix mmc order for omap3-gta04 + - ARM: dts: am3517-evm: Fix misc pinmuxing + - ARM: dts: logicpd-som-lv: Fix wrong pinmuxing on OMAP35 + - ipvs: correctly print the memory size of ip_vs_conn_tab + - mtd: rawnand: Fix return value check of wait_for_completion_timeout + - bpf, lwt: Fix crash when using bpf_skb_set_tunnel_key() from bpf_xmit lwt + hook + - tcp: md5: incorrect tcp_header_len for incoming connections + - tcp: ensure to use the most recently sent skb when filling the rate sample + - sctp: check asoc strreset_chunk in sctp_generate_reconf_event + - ARM: dts: imx6ull-colibri: fix vqmmc regulator + - arm64: dts: imx8mn-ddr4-evk: Describe the 32.768 kHz PMIC clock + - pinctrl: pistachio: fix use of irq_of_parse_and_map() + - cpufreq: fix memory leak in sun50i_cpufreq_nvmem_probe + - net: hns3: add validity check for message data length + - net/smc: sync err code when tcp connection was refused + - ip_gre: Make o_seqno start from 0 in native mode + - tcp: fix potential xmit stalls caused by TCP_NOTSENT_LOWAT + - bus: sunxi-rsb: Fix the return value of sunxi_rsb_device_create() + - clk: sunxi: sun9i-mmc: check return value after calling + platform_get_resource() + - net: bcmgenet: hide status block before TX timestamping + - net: dsa: lantiq_gswip: Don't set GSWIP_MII_CFG_RMII_CLK + - drm/amd/display: Fix memory leak in dcn21_clock_source_create + - tls: Skip tls_append_frag on zero copy size + - bnx2x: fix napi API usage sequence + - ixgbe: ensure IPsec VF<->PF compatibility + - tcp: fix F-RTO may not work correctly when receiving DSACK + - ASoC: wm8731: Disable the regulator when probing fails + - ip6_gre: Avoid updating tunnel->tun_hlen in __gre6_xmit() + - x86: __memcpy_flushcache: fix wrong alignment if size > 2^32 + - cifs: destage any unwritten data to the server before calling + copychunk_write + - drivers: net: hippi: Fix deadlock in rr_close() + - net: ethernet: stmmac: fix write to sgmii_adapter_base + - x86/cpu: Load microcode during restore_processor_state() + - tty: n_gsm: fix wrong signal octet encoding in convergence layer type 2 + - tty: n_gsm: fix malformed counter for out of frame data + - netfilter: nft_socket: only do sk lookups when indev is available + - tty: n_gsm: fix insufficient txframe size + - tty: n_gsm: fix missing explicit ldisc flush + - tty: n_gsm: fix wrong command retry handling + - tty: n_gsm: fix wrong command frame length field encoding + - tty: n_gsm: fix incorrect UA handling + - hugetlbfs: get unmapped area below TASK_UNMAPPED_BASE for hugetlbfs + - mm, hugetlb: allow for "high" userspace addresses + - Linux 5.4.192 + * CVE-2022-1789 + - KVM: x86/mmu: fix NULL pointer dereference on guest INVPCID + * Focal update: v5.4.191 upstream stable release (LP: #1976116) + - etherdevice: Adjust ether_addr* prototypes to silence -Wstringop-overead + - mm: page_alloc: fix building error on -Werror=array-compare + - tracing: Dump stacktrace trigger to the corresponding instance + - gfs2: assign rgrp glock before compute_bitstructs + - tcp: fix race condition when creating child sockets from syncookies + - tcp: Fix potential use-after-free due to double kfree() + - ALSA: usb-audio: Clear MIDI port active flag after draining + - ASoC: atmel: Remove system clock tree configuration for at91sam9g20ek + - ASoC: msm8916-wcd-digital: Check failure for devm_snd_soc_register_component + - dmaengine: imx-sdma: Fix error checking in sdma_event_remap + - dmaengine: mediatek:Fix PM usage reference leak of + mtk_uart_apdma_alloc_chan_resources + - igc: Fix infinite loop in release_swfw_sync + - igc: Fix BUG: scheduling while atomic + - rxrpc: Restore removed timer deletion + - net/smc: Fix sock leak when release after smc_shutdown() + - net/packet: fix packet_sock xmit return value checking + - net/sched: cls_u32: fix possible leak in u32_init_knode() + - l3mdev: l3mdev_master_upper_ifindex_by_index_rcu should be using + netdev_master_upper_dev_get_rcu + - netlink: reset network and mac headers in netlink_dump() + - selftests: mlxsw: vxlan_flooding: Prevent flooding of unwanted packets + - ARM: vexpress/spc: Avoid negative array index when !SMP + - reset: tegra-bpmp: Restore Handle errors in BPMP response + - platform/x86: samsung-laptop: Fix an unsigned comparison which can never be + negative + - ALSA: usb-audio: Fix undefined behavior due to shift overflowing the + constant + - vxlan: fix error return code in vxlan_fdb_append + - cifs: Check the IOCB_DIRECT flag, not O_DIRECT + - mt76: Fix undefined behavior due to shift overflowing the constant + - brcmfmac: sdio: Fix undefined behavior due to shift overflowing the constant + - dpaa_eth: Fix missing of_node_put in dpaa_get_ts_info() + - drm/msm/mdp5: check the return of kzalloc() + - net: macb: Restart tx only if queue pointer is lagging + - scsi: qedi: Fix failed disconnect handling + - stat: fix inconsistency between struct stat and struct compat_stat + - EDAC/synopsys: Read the error count from the correct register + - oom_kill.c: futex: delay the OOM reaper to allow time for proper futex + cleanup + - ata: pata_marvell: Check the 'bmdma_addr' beforing reading + - dma: at_xdmac: fix a missing check on list iterator + - drm/panel/raspberrypi-touchscreen: Avoid NULL deref if not initialised + - drm/panel/raspberrypi-touchscreen: Initialise the bridge in prepare + - KVM: PPC: Fix TCE handling for VFIO + - drm/vc4: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage + - powerpc/perf: Fix power9 event alternatives + - xtensa: patch_text: Fixup last cpu should be master + - xtensa: fix a7 clobbering in coprocessor context load/store + - openvswitch: fix OOB access in reserve_sfa_size() + - ASoC: soc-dapm: fix two incorrect uses of list iterator + - e1000e: Fix possible overflow in LTR decoding + - ARC: entry: fix syscall_trace_exit argument + - arm_pmu: Validate single/group leader events + - ext4: fix symlink file size not match to file content + - ext4: fix use-after-free in ext4_search_dir + - ext4, doc: fix incorrect h_reserved size + - ext4: fix overhead calculation to account for the reserved gdt blocks + - ext4: force overhead calculation if the s_overhead_cluster makes no sense + - jbd2: fix a potential race while discarding reserved buffers after an abort + - spi: atmel-quadspi: Fix the buswidth adjustment between spi-mem and + controller + - staging: ion: Prevent incorrect reference counting behavour + - block/compat_ioctl: fix range check in BLKGETSIZE + - Linux 5.4.191 + * Focal update: v5.4.190 upstream stable release (LP: #1973085) + - memory: atmel-ebi: Fix missing of_node_put in atmel_ebi_probe + - net/sched: flower: fix parsing of ethertype following VLAN header + - veth: Ensure eth header is in skb's linear part + - gpiolib: acpi: use correct format characters + - mlxsw: i2c: Fix initialization error flow + - net/sched: fix initialization order when updating chain 0 head + - net: ethernet: stmmac: fix altr_tse_pcs function when using a fixed-link + - net/sched: taprio: Check if socket flags are valid + - cfg80211: hold bss_lock while updating nontrans_list + - drm/msm/dsi: Use connector directly in msm_dsi_manager_connector_init() + - net/smc: Fix NULL pointer dereference in smc_pnet_find_ib() + - sctp: Initialize daddr on peeled off socket + - testing/selftests/mqueue: Fix mq_perf_tests to free the allocated cpu set + - nfc: nci: add flush_workqueue to prevent uaf + - cifs: potential buffer overflow in handling symlinks + - drm/amd: Add USBC connector ID + - drm/amd/display: fix audio format not updated after edid updated + - drm/amd/display: Update VTEM Infopacket definition + - drm/amdkfd: Fix Incorrect VMIDs passed to HWS + - drm/amdkfd: Check for potential null return of kmalloc_array() + - Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer + - scsi: target: tcmu: Fix possible page UAF + - scsi: ibmvscsis: Increase INITIAL_SRP_LIMIT to 1024 + - ata: libata-core: Disable READ LOG DMA EXT for Samsung 840 EVOs + - gpu: ipu-v3: Fix dev_dbg frequency output + - regulator: wm8994: Add an off-on delay for WM8994 variant + - arm64: alternatives: mark patch_alternative() as `noinstr` + - tlb: hugetlb: Add more sizes to tlb_remove_huge_tlb_entry + - net: usb: aqc111: Fix out-of-bounds accesses in RX fixup + - drm/amd/display: Fix allocate_mst_payload assert on resume + - powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit + - scsi: mvsas: Add PCI ID of RocketRaid 2640 + - scsi: megaraid_sas: Target with invalid LUN ID is deleted during scan + - drivers: net: slip: fix NPD bug in sl_tx_timeout() + - perf/imx_ddr: Fix undefined behavior due to shift overflowing the constant + - mm, page_alloc: fix build_zonerefs_node() + - mm: kmemleak: take a full lowmem check in kmemleak_*_phys() + - gcc-plugins: latent_entropy: use /dev/urandom + - ath9k: Properly clear TX status area before reporting to mac80211 + - ath9k: Fix usage of driver-private space in tx_info + - btrfs: remove unused variable in btrfs_{start,write}_dirty_block_groups() + - btrfs: mark resumed async balance as writing + - ALSA: hda/realtek: Add quirk for Clevo PD50PNT + - ALSA: pcm: Test for "silence" field in struct "pcm_format_data" + - ipv6: fix panic when forwarding a pkt with no in6 dev + - drm/amd/display: don't ignore alpha property on pre-multiplied mode + - genirq/affinity: Consider that CPUs on nodes can be unbalanced + - tick/nohz: Use WARN_ON_ONCE() to prevent console saturation + - ARM: davinci: da850-evm: Avoid NULL pointer dereference + - dm integrity: fix memory corruption when tag_size is less than digest size + - smp: Fix offline cpu check in flush_smp_call_function_queue() + - i2c: pasemi: Wait for write xfers to finish + - dma-direct: avoid redundant memory sync for swiotlb + - ax25: add refcount in ax25_dev to avoid UAF bugs + - ax25: fix reference count leaks of ax25_dev + - ax25: fix UAF bugs of net_device caused by rebinding operation + - ax25: Fix refcount leaks caused by ax25_cb_del() + - ax25: fix UAF bug in ax25_send_control() + - ax25: fix NPD bug in ax25_disconnect + - ax25: Fix NULL pointer dereferences in ax25 timers + - ax25: Fix UAF bugs in ax25 timers + - Linux 5.4.190 + + [ Ubuntu: 5.4.0-121.137 ] + + * focal/linux: 5.4.0-121.137 -proposed tracker (LP: #1978666) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.05.30) + * CVE-2022-28388 + - can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error + path + * test_vxlan_under_vrf.sh in net from ubuntu_kernel_selftests failed (Check VM + connectivity through VXLAN (underlay in the default VRF) [FAIL]) + (LP: #1871015) + - selftests: net: test_vxlan_under_vrf: fix HV connectivity test + * [UBUNTU 20.04] CPU-MF: add extended counter set definitions for new IBM z16 + (LP: #1974433) + - s390/cpumf: add new extended counter set for IBM z16 + * [UBUNTU 20.04] KVM nesting support leaks too much memory, might result in + stalls during cleanup (LP: #1974017) + - KVM: s390: vsie/gmap: reduce gmap_rmap overhead + * [UBUNTU 20.04] Null Pointer issue in nfs code running Ubuntu on IBM Z + (LP: #1968096) + - NFS: Fix up nfs_ctx_key_to_expire() + + -- Joseph Salisbury Wed, 22 Jun 2022 14:29:37 -0400 + +linux-oracle (5.4.0-1078.86) focal; urgency=medium + + [ Ubuntu: 5.4.0-120.136 ] + + * CVE-2022-21123 // CVE-2022-21125 // CVE-2022-21166 + - cpu/speculation: Add prototype for cpu_show_srbds() + - x86/cpu: Add Jasper Lake to Intel family + - x86/cpu: Add Lakefield, Alder Lake and Rocket Lake models to the to Intel + CPU family + - x86/cpu: Add another Alder Lake CPU to the Intel family + - Documentation: Add documentation for Processor MMIO Stale Data + - x86/speculation/mmio: Enumerate Processor MMIO Stale Data bug + - x86/speculation: Add a common function for MD_CLEAR mitigation update + - x86/speculation/mmio: Add mitigation for Processor MMIO Stale Data + - x86/bugs: Group MDS, TAA & Processor MMIO Stale Data mitigations + - x86/speculation/mmio: Enable CPU Fill buffer clearing on idle + - x86/speculation/mmio: Add sysfs reporting for Processor MMIO Stale Data + - x86/speculation/srbds: Update SRBDS mitigation selection + - x86/speculation/mmio: Reuse SRBDS mitigation for SBDS + - KVM: x86/speculation: Disable Fill buffer clear within guests + - x86/speculation/mmio: Print SMT warning + + -- Thadeu Lima de Souza Cascardo Fri, 10 Jun 2022 12:44:31 -0300 + +linux-oracle (5.4.0-1076.83) focal; urgency=medium + + [ Ubuntu: 5.4.0-117.132 ] + + * CVE-2022-1966 + - netfilter: nf_tables: add nft_set_elem_expr_alloc() + - netfilter: nf_tables: disallow non-stateful expression in sets earlier + + -- Thadeu Lima de Souza Cascardo Wed, 01 Jun 2022 22:23:06 -0300 + +linux-oracle (5.4.0-1074.80) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1074.80 -proposed tracker (LP: #1974380) + + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2022.05.09) + + [ Ubuntu: 5.4.0-115.129 ] + + * CVE-2022-21499 + - SAUCE: debug: Lock down kgdb + + [ Ubuntu: 5.4.0-114.128 ] + + * focal/linux: 5.4.0-114.128 -proposed tracker (LP: #1974391) + * 32 GT/s PCI link speeds reporting "Unknown speed" in sysfs (LP: #1970798) + - PCI: Add 32 GT/s decoding in some macros + - PCI: Add pci_speed_string() + - PCI: Use pci_speed_string() for all PCI/PCI-X/PCIe strings + - PCI: Add PCIE_LNKCAP2_SLS2SPEED() macro + * issuing invalid ioctl to /dev/vsock may spam dmesg (LP: #1971480) + - vsock: remove ratelimit unknown ioctl message + * config CONFIG_HISI_PMU for kunpeng920 (LP: #1956086) + - drivers/perf: hisi: Permit modular builds of HiSilicon uncore drivers + - [Config] CONFIG_HISI_PMU=m + * Focal update: v5.4.189 upstream stable release (LP: #1971497) + - swiotlb: fix info leak with DMA_FROM_DEVICE + - USB: serial: pl2303: add IBM device IDs + - USB: serial: simple: add Nokia phone driver + - netdevice: add the case if dev is NULL + - HID: logitech-dj: add new lightspeed receiver id + - xfrm: fix tunnel model fragmentation behavior + - virtio_console: break out of buf poll on remove + - ethernet: sun: Free the coherent when failing in probing + - spi: Fix invalid sgs value + - net:mcf8390: Use platform_get_irq() to get the interrupt + - spi: Fix erroneous sgs value with min_t() + - af_key: add __GFP_ZERO flag for compose_sadb_supported in function + pfkey_register + - net: dsa: microchip: add spi_device_id tables + - iommu/iova: Improve 32-bit free space estimate + - tpm: fix reference counting for struct tpm_chip + - block: Add a helper to validate the block size + - virtio-blk: Use blk_validate_block_size() to validate block size + - USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c + - xhci: fix runtime PM imbalance in USB2 resume + - xhci: make xhci_handshake timeout for xhci_reset() adjustable + - xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx() + - coresight: Fix TRCCONFIGR.QE sysfs interface + - iio: afe: rescale: use s64 for temporary scale calculations + - iio: inkern: apply consumer scale on IIO_VAL_INT cases + - iio: inkern: apply consumer scale when no channel scale is available + - iio: inkern: make a best effort on offset calculation + - greybus: svc: fix an error handling bug in gb_svc_hello() + - clk: uniphier: Fix fixed-rate initialization + - KEYS: fix length validation in keyctl_pkey_params_get_2() + - Documentation: add link to stable release candidate tree + - Documentation: update stable tree link + - HID: intel-ish-hid: Use dma_alloc_coherent for firmware update + - SUNRPC: avoid race between mod_timer() and del_timer_sync() + - NFSD: prevent underflow in nfssvc_decode_writeargs() + - NFSD: prevent integer overflow on 32 bit systems + - f2fs: fix to unlock page correctly in error path of is_alive() + - f2fs: quota: fix loop condition at f2fs_quota_sync() + - f2fs: fix to do sanity check on .cp_pack_total_block_count + - pinctrl: samsung: drop pin banks references on error paths + - spi: mxic: Fix the transmit path + - jffs2: fix use-after-free in jffs2_clear_xattr_subsystem + - jffs2: fix memory leak in jffs2_do_mount_fs + - jffs2: fix memory leak in jffs2_scan_medium + - mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node + - mm: invalidate hwpoison page cache page in fault path + - mempolicy: mbind_range() set_policy() after vma_merge() + - scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands + - qed: display VF trust config + - qed: validate and restrict untrusted VFs vlan promisc mode + - riscv: Fix fill_callchain return value + - Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads" + - ALSA: cs4236: fix an incorrect NULL check on list iterator + - ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020 + - mm,hwpoison: unmap poisoned page before invalidation + - mm/kmemleak: reset tag when compare object pointer + - drbd: fix potential silent data corruption + - powerpc/kvm: Fix kvm_use_magic_page + - udp: call udp_encap_enable for v6 sockets when enabling encap + - ACPI: properties: Consistently return -ENOENT if there are no more + references + - drivers: hamradio: 6pack: fix UAF bug caused by mod_timer() + - mailbox: tegra-hsp: Flush whole channel + - block: don't merge across cgroup boundaries if blkcg is enabled + - drm/edid: check basic audio support on CEA extension block + - video: fbdev: sm712fb: Fix crash in smtcfb_read() + - video: fbdev: atari: Atari 2 bpp (STe) palette bugfix + - ARM: dts: at91: sama5d2: Fix PMERRLOC resource size + - ARM: dts: exynos: fix UART3 pins configuration in Exynos5250 + - ARM: dts: exynos: add missing HDMI supplies on SMDK5250 + - ARM: dts: exynos: add missing HDMI supplies on SMDK5420 + - carl9170: fix missing bit-wise or operator for tx_params + - thermal: int340x: Increase bitmap size + - lib/raid6/test: fix multiple definition linking error + - crypto: rsa-pkcs1pad - correctly get hash from source scatterlist + - crypto: rsa-pkcs1pad - restore signature length check + - crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete() + - DEC: Limit PMAX memory probing to R3k systems + - media: davinci: vpif: fix unbalanced runtime PM get + - xtensa: fix stop_machine_cpuslocked call in patch_text + - xtensa: fix xtensa_wsr always writing 0 + - brcmfmac: firmware: Allocate space for default boardrev in nvram + - brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path + - brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio + - brcmfmac: pcie: Fix crashes due to early IRQs + - PCI: pciehp: Clear cmd_busy bit in polling mode + - regulator: qcom_smd: fix for_each_child.cocci warnings + - crypto: authenc - Fix sleep in atomic context in decrypt_tail + - crypto: mxs-dcp - Fix scatterlist processing + - spi: tegra114: Add missing IRQ check in tegra_spi_probe + - selftests/x86: Add validity check and allow field splitting + - audit: log AUDIT_TIME_* records only from rules + - crypto: ccree - don't attempt 0 len DMA mappings + - spi: pxa2xx-pci: Balance reference count for PCI DMA device + - hwmon: (pmbus) Add mutex to regulator ops + - hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING + - block: don't delete queue kobject before its children + - PM: hibernate: fix __setup handler error handling + - PM: suspend: fix return value of __setup handler + - hwrng: atmel - disable trng on failure path + - crypto: vmx - add missing dependencies + - clocksource/drivers/timer-of: Check return value of of_iomap in + timer_of_base_init() + - ACPI: APEI: fix return value of __setup handlers + - crypto: ccp - ccp_dmaengine_unregister release dma channels + - hwmon: (pmbus) Add Vin unit off handling + - clocksource: acpi_pm: fix return value of __setup handler + - sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa + - perf/core: Fix address filter parser for multiple filters + - perf/x86/intel/pt: Fix address filter config for 32-bit kernel + - f2fs: fix missing free nid in f2fs_handle_failed_inode + - f2fs: fix to avoid potential deadlock + - media: bttv: fix WARNING regression on tunerless devices + - media: coda: Fix missing put_device() call in coda_get_vdoa_data + - media: hantro: Fix overfill bottom register field name + - media: aspeed: Correct value for h-total-pixels + - video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe() + - video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe() + - video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name() + - ARM: dts: qcom: ipq4019: fix sleep clock + - soc: qcom: rpmpd: Check for null return of devm_kcalloc + - soc: qcom: aoss: remove spurious IRQF_ONESHOT flags + - arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc + - soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe + - ARM: dts: imx: Add missing LVDS decoder on M53Menlo + - media: video/hdmi: handle short reads of hdmi info frame. + - media: em28xx: initialize refcount before kref_get + - media: usb: go7007: s2250-board: fix leak in probe() + - uaccess: fix nios2 and microblaze get_user_8() + - ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp() + - ASoC: ti: davinci-i2s: Add check for clk_enable() + - ALSA: spi: Add check for clk_enable() + - arm64: dts: ns2: Fix spi-cpol and spi-cpha property + - arm64: dts: broadcom: Fix sata nodename + - printk: fix return value of printk.devkmsg __setup handler + - ASoC: mxs-saif: Handle errors for clk_enable + - ASoC: atmel_ssc_dai: Handle errors for clk_enable + - ASoC: soc-compress: prevent the potentially use of null pointer + - memory: emif: Add check for setup_interrupts + - memory: emif: check the pointer temp in get_device_details() + - ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction + - arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly + - media: stk1160: If start stream fails, return buffers with + VB2_BUF_STATE_QUEUED + - ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe + - ASoC: wm8350: Handle error for wm8350_register_irq + - ASoC: fsi: Add check for clk_enable + - video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of + - ivtv: fix incorrect device_caps for ivtvfb + - ASoC: dmaengine: do not use a NULL prepare_slave_config() callback + - ASoC: mxs: Fix error handling in mxs_sgtl5000_probe + - ASoC: imx-es8328: Fix error return code in imx_es8328_probe() + - ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in + msm8916_wcd_digital_probe + - mmc: davinci_mmc: Handle error for clk_enable + - ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe + - drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev + - drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe + - ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern + - udmabuf: validate ubuf->pagecount + - Bluetooth: hci_serdev: call init_rwsem() before p->open() + - mtd: onenand: Check for error irq + - mtd: rawnand: gpmi: fix controller timings setting + - drm/edid: Don't clear formats if using deep color + - drm/amd/display: Fix a NULL pointer dereference in + amdgpu_dm_connector_add_common_modes() + - ath9k_htc: fix uninit value bugs + - KVM: PPC: Fix vmx/vsx mixup in mmio emulation + - i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb + - power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe + - ray_cs: Check ioremap return value + - powerpc/perf: Don't use perf_hw_context for trace IMC PMU + - mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update + - mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update + - net: dsa: mv88e6xxx: Enable port policy support on 6097 + - PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge + - power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init + - HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports + - iommu/ipmmu-vmsa: Check for error num after setting mask + - drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug + - IB/cma: Allow XRC INI QPs to set their local ACK timeout + - dax: make sure inodes are flushed before destroy cache + - iwlwifi: Fix -EIO error code that is never returned + - iwlwifi: mvm: Fix an error code in iwl_mvm_up() + - dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS + - scsi: pm8001: Fix command initialization in pm80XX_send_read_log() + - scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req() + - scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config() + - scsi: pm8001: Fix abort all task initialization + - drm/amd/display: Remove vupdate_int_entry definition + - TOMOYO: fix __setup handlers return values + - ext2: correct max file size computing + - drm/tegra: Fix reference leak in tegra_dsi_ganged_probe + - power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false + return + - scsi: hisi_sas: Change permission of parameter prot_mask + - drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt + - bpf, arm64: Call build_prologue() first in first JIT pass + - bpf, arm64: Feed byte-offset into bpf line info + - libbpf: Skip forward declaration when counting duplicated type names + - powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit + - KVM: x86: Fix emulation in writing cr8 + - KVM: x86/emulator: Defer not-present segment check in + __load_segment_descriptor() + - hv_balloon: rate-limit "Unhandled message" warning + - i2c: xiic: Make bus names unique + - power: supply: wm8350-power: Handle error for wm8350_register_irq + - power: supply: wm8350-power: Add missing free in free_charger_irq + - PCI: Reduce warnings on possible RW1C corruption + - mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n + - powerpc/sysdev: fix incorrect use to determine if list is empty + - mfd: mc13xxx: Add check for mc13xxx_irq_request + - selftests/bpf: Make test_lwt_ip_encap more stable and faster + - powerpc: 8xx: fix a return value error in mpc8xx_pic_init + - vxcan: enable local echo for sent CAN frames + - MIPS: RB532: fix return value of __setup handler + - mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init + - RDMA/mlx5: Fix memory leak in error flow for subscribe event routine + - bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full + - bpf, sockmap: Fix more uncharged while msg has more_data + - bpf, sockmap: Fix double uncharge the mem of sk_msg + - USB: storage: ums-realtek: fix error code in rts51x_read_mem() + - Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt + - af_netlink: Fix shift out of bounds in group mask calculation + - i2c: mux: demux-pinctrl: do not deactivate a master that is not active + - selftests/bpf/test_lirc_mode2.sh: Exit with proper code + - tcp: ensure PMTU updates are processed during fastopen + - openvswitch: always update flow key after nat + - tipc: fix the timer expires after interval 100ms + - mfd: asic3: Add missing iounmap() on error asic3_mfd_probe + - mxser: fix xmit_buf leak in activate when LSR == 0xff + - pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add() + - misc: alcor_pci: Fix an error handling path + - staging:iio:adc:ad7280a: Fix handing of device address bit reversing. + - pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel + - clk: qcom: ipq8074: Use floor ops for SDCC1 clock + - phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure}) + - serial: 8250_mid: Balance reference count for PCI DMA device + - serial: 8250: Fix race condition in RTS-after-send handling + - iio: adc: Add check for devm_request_threaded_irq + - NFS: Return valid errors from nfs2/3_decode_dirent() + - dma-debug: fix return value of __setup handlers + - clk: imx7d: Remove audio_mclk_root_clk + - clk: qcom: clk-rcg2: Update logic to calculate D value for RCG + - clk: qcom: clk-rcg2: Update the frac table for pixel clock + - remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region + - remoteproc: qcom_wcnss: Add missing of_node_put() in + wcnss_alloc_memory_region + - clk: actions: Terminate clk_div_table with sentinel element + - clk: loongson1: Terminate clk_div_table with sentinel element + - clk: clps711x: Terminate clk_div_table with sentinel element + - clk: tegra: tegra124-emc: Fix missing put_device() call in + emc_ensure_emc_driver + - NFS: remove unneeded check in decode_devicenotify_args() + - staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree + - pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init + - pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get() + - pinctrl: mediatek: paris: Fix pingroup pin config state readback + - pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe + - pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe + - tty: hvc: fix return value of __setup handler + - kgdboc: fix return value of __setup handler + - kgdbts: fix return value of __setup handler + - firmware: google: Properly state IOMEM dependency + - driver core: dd: fix return value of __setup handler + - jfs: fix divide error in dbNextAG + - netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options + - NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error + - clk: qcom: gcc-msm8994: Fix gpll4 width + - clk: Initialize orphan req_rate + - xen: fix is_xen_pmu() + - net: phy: broadcom: Fix brcm_fet_config_init() + - selftests: test_vxlan_under_vrf: Fix broken test case + - qlcnic: dcb: default to returning -EOPNOTSUPP + - net/x25: Fix null-ptr-deref caused by x25_disconnect + - NFSv4/pNFS: Fix another issue with a list iterator pointing to the head + - net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator + - lib/test: use after free in register_test_dev_kmod() + - LSM: general protection fault in legacy_parse_param + - gcc-plugins/stackleak: Exactly match strings instead of prefixes + - pinctrl: npcm: Fix broken references to chip->parent_device + - block, bfq: don't move oom_bfqq + - selinux: use correct type for context length + - loop: use sysfs_emit() in the sysfs xxx show() + - Fix incorrect type in assignment of ipv6 port for audit + - irqchip/qcom-pdc: Fix broken locking + - irqchip/nvic: Release nvic_base upon failure + - bfq: fix use-after-free in bfq_dispatch_request + - ACPICA: Avoid walking the ACPI Namespace if it is not there + - lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3 + - Revert "Revert "block, bfq: honor already-setup queue merges"" + - ACPI/APEI: Limit printable size of BERT table data + - PM: core: keep irq flags in device_pm_check_callbacks() + - spi: tegra20: Use of_device_get_match_data() + - ext4: don't BUG if someone dirty pages without asking ext4 first + - ntfs: add sanity check on allocation size + - video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow + - video: fbdev: w100fb: Reset global state + - video: fbdev: cirrusfb: check pixclock to avoid divide by zero + - video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit + - ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960 + - ARM: dts: bcm2837: Add the missing L1/L2 cache information + - ASoC: madera: Add dependencies on MFD + - video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf() + - video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of + snprintf() + - video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit + - ASoC: soc-core: skip zero num_dai component in searching dai name + - media: cx88-mpeg: clear interrupt status register before streaming video + - ARM: tegra: tamonten: Fix I2C3 pad setting + - ARM: mmp: Fix failure to remove sram device + - video: fbdev: sm712fb: Fix crash in smtcfb_write() + - media: Revert "media: em28xx: add missing em28xx_close_extension" + - media: hdpvr: initialize dev->worker at hdpvr_register_videodev + - mmc: host: Return an error when ->enable_sdio_irq() ops is missing + - ALSA: hda/realtek: Add alc256-samsung-headphone fixup + - powerpc/lib/sstep: Fix 'sthcx' instruction + - powerpc/lib/sstep: Fix build errors with newer binutils + - powerpc: Fix build errors with newer binutils + - scsi: qla2xxx: Fix stuck session in gpdb + - scsi: qla2xxx: Fix wrong FDMI data for 64G adapter + - scsi: qla2xxx: Fix warning for missing error code + - scsi: qla2xxx: Fix device reconnect in loop topology + - scsi: qla2xxx: Add devids and conditionals for 28xx + - scsi: qla2xxx: Check for firmware dump already collected + - scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair() + - scsi: qla2xxx: Fix disk failure to rediscover + - scsi: qla2xxx: Fix incorrect reporting of task management failure + - scsi: qla2xxx: Fix hang due to session stuck + - scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests + - scsi: qla2xxx: Fix N2N inconsistent PLOGI + - scsi: qla2xxx: Reduce false trigger to login + - scsi: qla2xxx: Use correct feature type field during RFF_ID processing + - KVM: Prevent module exit until all VMs are freed + - KVM: x86: fix sending PV IPI + - ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM + - ubifs: rename_whiteout: Fix double free for whiteout_ui->data + - ubifs: Fix deadlock in concurrent rename whiteout and inode writeback + - ubifs: Add missing iput if do_tmpfile() failed in rename whiteout + - ubifs: setflags: Make dirtied_ino_d 8 bytes aligned + - ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock() + - ubifs: rename_whiteout: correct old_dir size computing + - XArray: Fix xas_create_range() when multi-order entry present + - can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path + - can: mcba_usb: properly check endpoint type + - XArray: Update the LRU list in xas_split() + - rtc: check if __rtc_read_time was successful + - gfs2: Make sure FITRIM minlen is rounded up to fs block size + - net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware + - pinctrl: pinconf-generic: Print arguments for bias-pull-* + - pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR() + - pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE() + - ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs + - ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl + - ARM: iop32x: offset IRQ numbers by 1 + - ACPI: CPPC: Avoid out of bounds access when parsing _CPC data + - powerpc/kasan: Fix early region not updated correctly + - ASoC: soc-compress: Change the check for codec_dai + - mm/mmap: return 1 from stack_guard_gap __setup() handler + - mm/memcontrol: return 1 from cgroup.memory __setup() handler + - mm/usercopy: return 1 from hardened_usercopy __setup() handler + - bpf: Fix comment for helper bpf_current_task_under_cgroup() + - dt-bindings: mtd: nand-controller: Fix the reg property description + - dt-bindings: mtd: nand-controller: Fix a comment in the examples + - dt-bindings: spi: mxic: The interrupt property is not mandatory + - ubi: fastmap: Return error code if memory allocation fails in add_aeb() + - ASoC: topology: Allow TLV control to be either read or write + - ARM: dts: spear1340: Update serial node properties + - ARM: dts: spear13xx: Update SPI dma properties + - um: Fix uml_mconsole stop/go + - openvswitch: Fixed nd target mask field in the flow dump. + - KVM: x86/mmu: do compare-and-exchange of gPTE via the user address + - KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated + - ubifs: Rectify space amount budget for mkdir/tmpfile operations + - rtc: wm8350: Handle error for wm8350_register_irq + - riscv module: remove (NOLOAD) + - ARM: 9187/1: JIVE: fix return value of __setup handler + - KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs + - drm: Add orientation quirk for GPD Win Max + - ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111 + - drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj + - ptp: replace snprintf with sysfs_emit + - powerpc: dts: t104xrdb: fix phy type for FMAN 4/5 + - bpf: Make dst_port field in struct bpf_sock 16-bit wide + - scsi: mvsas: Replace snprintf() with sysfs_emit() + - scsi: bfa: Replace snprintf() with sysfs_emit() + - power: supply: axp20x_battery: properly report current when discharging + - ipv6: make mc_forwarding atomic + - powerpc: Set crashkernel offset to mid of RMA region + - drm/amdgpu: Fix recursive locking warning + - PCI: aardvark: Fix support for MSI interrupts + - iommu/arm-smmu-v3: fix event handling soft lockup + - usb: ehci: add pci device support for Aspeed platforms + - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum + - power: supply: axp288-charger: Set Vhold to 4.4V + - ipv4: Invalidate neighbour for broadcast address upon address addition + - dm ioctl: prevent potential spectre v1 gadget + - drm/amdkfd: make CRAT table missing message informational only + - scsi: pm8001: Fix pm8001_mpi_task_abort_resp() + - scsi: aha152x: Fix aha152x_setup() __setup handler return value + - net/smc: correct settings of RMB window update limit + - mips: ralink: fix a refcount leak in ill_acc_of_setup() + - macvtap: advertise link netns via netlink + - tuntap: add sanity checks about msg_controllen in sendmsg + - bnxt_en: Eliminate unintended link toggle during FW reset + - MIPS: fix fortify panic when copying asm exception handlers + - scsi: libfc: Fix use after free in fc_exch_abts_resp() + - usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm + - xtensa: fix DTC warning unit_address_format + - Bluetooth: Fix use after free in hci_send_acl + - netlabel: fix out-of-bounds memory accesses + - init/main.c: return 1 from handled __setup() functions + - minix: fix bug when opening a file with O_DIRECT + - clk: si5341: fix reported clk_rate when output divider is 2 + - w1: w1_therm: fixes w1_seq for ds28ea00 sensors + - NFSv4: Protect the state recovery thread against direct reclaim + - xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32 + - clk: Enforce that disjoints limits are invalid + - SUNRPC/call_alloc: async tasks mustn't block waiting for memory + - NFS: swap IO handling is slightly different for O_DIRECT IO + - NFS: swap-out must always use STABLE writes. + - serial: samsung_tty: do not unlock port->lock for uart_write_wakeup() + - virtio_console: eliminate anonymous module_init & module_exit + - jfs: prevent NULL deref in diFree + - SUNRPC: Fix socket waits for write buffer space + - parisc: Fix CPU affinity for Lasi, WAX and Dino chips + - parisc: Fix patch code locking and flushing + - mm: fix race between MADV_FREE reclaim and blkdev direct IO read + - KVM: arm64: Check arm64_get_bp_hardening_data() didn't return NULL + - drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire() + - Drivers: hv: vmbus: Fix potential crash on module unload + - scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one() + - net/tls: fix slab-out-of-bounds bug in decrypt_internal + - net: ipv4: fix route with nexthop object delete warning + - net: stmmac: Fix unset max_speed difference between DT and non-DT platforms + - drm/imx: Fix memory leak in imx_pd_connector_get_modes + - bnxt_en: reserve space inside receive page for skb_shared_info + - IB/rdmavt: add lock to call to rvt_error_qp to prevent a race condition + - dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe + - ipv6: Fix stats accounting in ip6_pkt_drop + - net: openvswitch: don't send internal clone attribute to the userspace. + - rxrpc: fix a race in rxrpc_exit_net() + - qede: confirm skb is allocated before using + - spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op() + - bpf: Support dual-stack sockets in bpf_tcp_check_syncookie + - drbd: Fix five use after free bugs in get_initial_state + - SUNRPC: Handle ENOMEM in call_transmit_status() + - SUNRPC: Handle low memory situations in call_status() + - perf tools: Fix perf's libperf_print callback + - perf session: Remap buf if there is no space for event + - Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning" + - mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is + complete + - lz4: fix LZ4_decompress_safe_partial read out of bound + - mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0) + - mm/mempolicy: fix mpol_new leak in shared_policy_replace + - x86/pm: Save the MSR validity status at context setup + - x86/speculation: Restore speculation related MSRs during S3 resume + - btrfs: fix qgroup reserve overflow the qgroup limit + - arm64: patch_text: Fixup last cpu should be master + - ata: sata_dwc_460ex: Fix crash due to OOB write + - perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator + - irqchip/gic-v3: Fix GICR_CTLR.RWP polling + - tools build: Filter out options and warnings not supported by clang + - tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts + - dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error" + - mmc: mmci_sdmmc: Replace sg_dma_xxx macros + - mmc: mmci: stm32: correctly check all elements of sg list + - mm: don't skip swap entry even if zap_details specified + - arm64: module: remove (NOLOAD) from linker script + - mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning + - drm/amdkfd: add missing void argument to function kgd2kfd_init + - drm/amdkfd: Fix -Wstrict-prototypes from + amdgpu_amdkfd_gfx_10_0_get_functions() + - cgroup: Use open-time credentials for process migraton perm checks + - cgroup: Allocate cgroup_file_ctx for kernfs_open_file->priv + - cgroup: Use open-time cgroup namespace for process migration perm checks + - selftests: cgroup: Make cg_create() use 0755 for permission instead of 0644 + - selftests: cgroup: Test open-time credential usage for migration checks + - selftests: cgroup: Test open-time cgroup namespace usage for migration + checks + - cpuidle: PSCI: Move the `has_lpi` check to the beginning of the function + - ACPI: processor idle: Check for architectural support for LPI + - Linux 5.4.189 + * Focal update: v5.4.188 upstream stable release (LP: #1971496) + - nfsd: cleanup nfsd_file_lru_dispose() + - nfsd: Containerise filecache laundrette + - net: ipv6: fix skb_over_panic in __ip6_append_data + - tpm: Fix error handling in async work + - staging: fbtft: fb_st7789v: reset display before initialization + - thermal: int340x: fix memory leak in int3400_notify() + - llc: fix netdevice reference leaks in llc_ui_bind() + - ALSA: pcm: Add stream lock during PCM reset ioctl operations + - ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB + - ALSA: cmipci: Restore aux vol on suspend/resume + - ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec + - drivers: net: xgene: Fix regression in CRC stripping + - ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call + - ALSA: oss: Fix PCM OSS buffer allocation overflow + - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671 + - ALSA: hda/realtek: Add quirk for ASUS GA402 + - ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board + - ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3 + - ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU + - crypto: qat - disable registration of algorithms + - rcu: Don't deboost before reporting expedited quiescent state + - mac80211: fix potential double free on mesh join + - tpm: use try_get_ops() in tpm-space.c + - nds32: fix access_ok() checks in get/put_user + - llc: only change llc->dev when bind() succeeds + - Linux 5.4.188 + * Focal update: v5.4.187 upstream stable release (LP: #1971493) + - crypto: qcom-rng - ensure buffer for generate is completely filled + - ocfs2: fix crash when initialize filecheck kobj fails + - efi: fix return value of __setup handlers + - net: phy: marvell: Fix invalid comparison in the resume and suspend + functions + - net/packet: fix slab-out-of-bounds access in packet_recvmsg() + - atm: eni: Add check for dma_map_single + - hv_netvsc: Add check for kvmalloc_array + - drm/panel: simple: Fix Innolux G070Y2-L01 BPP settings + - net: handle ARPHRD_PIMREG in dev_is_mac_header_xmit() + - net: dsa: Add missing of_node_put() in dsa_port_parse_of + - arm64: fix clang warning about TRAMP_VALIAS + - usb: gadget: rndis: prevent integer overflow in rndis_set_response() + - usb: gadget: Fix use-after-free bug by not setting udc->dev.driver + - usb: usbtmc: Fix bug in pipe direction for control transfers + - Input: aiptek - properly check endpoint type + - perf symbols: Fix symbol size calculation condition + - Linux 5.4.187 + * Focal update: v5.4.186 upstream stable release (LP: #1969678) + - Revert "xfrm: state and policy should fail if XFRMA_IF_ID 0" + - sctp: fix the processing for INIT chunk + - xfrm: Check if_id in xfrm_migrate + - xfrm: Fix xfrm migrate issues when address family changes + - arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity + - arm64: dts: rockchip: reorder rk3399 hdmi clocks + - arm64: dts: agilex: use the compatible "intel,socfpga-agilex-hsotg" + - ARM: dts: rockchip: reorder rk322x hmdi clocks + - ARM: dts: rockchip: fix a typo on rk3288 crypto-controller + - mac80211: refuse aggregations sessions before authorized + - MIPS: smp: fill in sibling and core maps earlier + - ARM: 9178/1: fix unmet dependency on BITREVERSE for HAVE_ARCH_BITREVERSE + - can: rcar_canfd: rcar_canfd_channel_probe(): register the CAN device when + fully ready + - atm: firestream: check the return value of ioremap() in fs_init() + - iwlwifi: don't advertise TWT support + - drm/vrr: Set VRR capable prop only if it is attached to connector + - nl80211: Update bss channel on channel switch for P2P_CLIENT + - tcp: make tcp_read_sock() more robust + - sfc: extend the locking on mcdi->seqno + - kselftest/vm: fix tests build with old libc + - fixup for "arm64 entry: Add macro for reading symbol address from the + trampoline" + - Linux 5.4.186 + * Focal update: v5.4.185 upstream stable release (LP: #1969672) + - clk: qcom: gdsc: Add support to update GDSC transition delay + - arm64: dts: armada-3720-turris-mox: Add missing ethernet0 alias + - virtio-blk: Don't use MAX_DISCARD_SEGMENTS if max_discard_seg is zero + - net: qlogic: check the return value of dma_alloc_coherent() in + qed_vf_hw_prepare() + - qed: return status of qed_iov_get_link + - drm/sun4i: mixer: Fix P010 and P210 format numbers + - ARM: dts: aspeed: Fix AST2600 quad spi group + - ethernet: Fix error handling in xemaclite_of_probe + - net: ethernet: ti: cpts: Handle error for clk_enable + - net: ethernet: lpc_eth: Handle error for clk_enable + - ax25: Fix NULL pointer dereference in ax25_kill_by_device + - net/mlx5: Fix size field in bufferx_reg struct + - net/mlx5: Fix a race on command flush flow + - NFC: port100: fix use-after-free in port100_send_complete + - selftests: pmtu.sh: Kill tcpdump processes launched by subshell. + - gpio: ts4900: Do not set DAT and OE together + - gianfar: ethtool: Fix refcount leak in gfar_get_ts_info + - net: phy: DP83822: clear MISR2 register to disable interrupts + - sctp: fix kernel-infoleak for SCTP sockets + - net: bcmgenet: Don't claim WOL when its not available + - net-sysfs: add check for netdevice being present to speed_show + - Revert "xen-netback: remove 'hotplug-status' once it has served its purpose" + - Revert "xen-netback: Check for hotplug-status existence before watching" + - ipv6: prevent a possible race condition with lifetimes + - tracing: Ensure trace buffer is at least 4096 bytes large + - selftest/vm: fix map_fixed_noreplace test failure + - selftests/memfd: clean up mapping in mfd_fail_write + - ARM: Spectre-BHB: provide empty stub for non-config + - fuse: fix pipe buffer lifetime for direct_io + - staging: gdm724x: fix use after free in gdm_lte_rx() + - net: macb: Fix lost RX packet wakeup race in NAPI receive + - mmc: meson: Fix usage of meson_mmc_post_req() + - riscv: Fix auipc+jalr relocation range checks + - arm64: dts: marvell: armada-37xx: Remap IO space to bus address 0x0 + - virtio: unexport virtio_finalize_features + - virtio: acknowledge all features before access + - ARM: fix Thumb2 regression with Spectre BHB + - ext4: add check to prevent attempting to resize an fs with sparse_super2 + - x86/cpufeatures: Mark two free bits in word 3 + - x86/cpu: Add hardware-enforced cache coherency as a CPUID feature + - x86/mm/pat: Don't flush cache if hardware enforces cache coherency across + encryption domnains + - KVM: SVM: Don't flush cache if hardware enforces cache coherency across + encryption domains + - Linux 5.4.185 + * Focal update: v5.4.184 upstream stable release (LP: #1969242) + - arm/arm64: Provide a wrapper for SMCCC 1.1 calls + - arm/arm64: smccc/psci: add arm_smccc_1_1_get_conduit() + - ARM: report Spectre v2 status through sysfs + - ARM: early traps initialisation + - ARM: use LOADADDR() to get load address of sections + - [Config] updateconfigs for HARDEN_BRANCH_HISTORY + - ARM: Spectre-BHB workaround + - ARM: include unprivileged BPF status in Spectre V2 reporting + - ARM: fix build error when BPF_SYSCALL is disabled + - ARM: fix co-processor register typo + - ARM: Do not use NOCROSSREFS directive with ld.lld + - ARM: fix build warning in proc-v7-bugs.c + - xen/xenbus: don't let xenbus_grant_ring() remove grants in error case + - xen/grant-table: add gnttab_try_end_foreign_access() + - xen/blkfront: don't use gnttab_query_foreign_access() for mapped status + - xen/netfront: don't use gnttab_query_foreign_access() for mapped status + - xen/scsifront: don't use gnttab_query_foreign_access() for mapped status + - xen/gntalloc: don't use gnttab_query_foreign_access() + - xen: remove gnttab_query_foreign_access() + - xen/9p: use alloc/free_pages_exact() + - xen/pvcalls: use alloc/free_pages_exact() + - xen/gnttab: fix gnttab_end_foreign_access() without page specified + - xen/netfront: react properly to failing gnttab_end_foreign_access_ref() + - Linux 5.4.184 + * Focal update: v5.4.183 upstream stable release (LP: #1969239) + - mac80211_hwsim: report NOACK frames in tx_status + - mac80211_hwsim: initialize ieee80211_tx_info at hw_scan_work + - i2c: bcm2835: Avoid clock stretching timeouts + - ASoC: rt5668: do not block workqueue if card is unbound + - ASoC: rt5682: do not block workqueue if card is unbound + - Input: clear BTN_RIGHT/MIDDLE on buttonpads + - cifs: fix double free race when mount fails in cifs_get_root() + - dmaengine: shdma: Fix runtime PM imbalance on error + - i2c: cadence: allow COMPILE_TEST + - i2c: qup: allow COMPILE_TEST + - net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990 + - usb: gadget: don't release an existing dev->buf + - usb: gadget: clear related members when goto fail + - ata: pata_hpt37x: fix PCI clock detection + - ALSA: intel_hdmi: Fix reference to PCM buffer address + - ASoC: ops: Shift tested values in snd_soc_put_volsw() by +min + - xfrm: fix MTU regression + - netfilter: fix use-after-free in __nf_register_net_hook() + - xfrm: enforce validity of offload input flags + - netfilter: nf_queue: don't assume sk is full socket + - netfilter: nf_queue: fix possible use-after-free + - batman-adv: Request iflink once in batadv-on-batadv check + - batman-adv: Request iflink once in batadv_get_real_netdevice + - batman-adv: Don't expect inter-netns unique iflink indices + - net: dcb: flush lingering app table entries for unregistered devices + - net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client + - net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server + - block: Fix fsync always failed if once failed + - xen/netfront: destroy queues before real_num_tx_queues is zeroed + - sched/topology: Make sched_init_numa() use a set for the deduplicating sort + - sched/topology: Fix sched_domain_topology_level alloc in sched_init_numa() + - ia64: ensure proper NUMA distance and possible map initialization + - mac80211: fix forwarded mesh frames AC & queue selection + - net: stmmac: fix return value of __setup handler + - iavf: Fix missing check for running netdev + - net: sxgbe: fix return value of __setup handler + - net: arcnet: com20020: Fix null-ptr-deref in com20020pci_probe() + - ixgbe: xsk: change !netif_carrier_ok() handling in ixgbe_xmit_zc() + - efivars: Respect "block" flag in efivar_entry_set_safe() + - firmware: arm_scmi: Remove space in MODULE_ALIAS name + - ASoC: cs4265: Fix the duplicated control name + - can: gs_usb: change active_channels's type from atomic_t to u8 + - arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output + - igc: igc_read_phy_reg_gpy: drop premature return + - ARM: Fix kgdb breakpoint for Thumb2 + - ARM: 9182/1: mmu: fix returns from early_param() and __setup() functions + - igc: igc_write_phy_reg_gpy: drop premature return + - ibmvnic: free reset-work-item when flushing + - memfd: fix F_SEAL_WRITE after shmem huge page allocated + - soc: fsl: qe: Check of ioremap return value + - net: chelsio: cxgb3: check the return value of pci_find_capability() + - nl80211: Handle nla_memdup failures in handle_nan_filter + - Input: elan_i2c - move regulator_[en|dis]able() out of + elan_[en|dis]able_power() + - Input: elan_i2c - fix regulator enable count imbalance after suspend/resume + - HID: add mapping for KEY_DICTATE + - HID: add mapping for KEY_ALL_APPLICATIONS + - tracing/histogram: Fix sorting on old "cpu" value + - tracing: Fix return value of __setup handlers + - btrfs: fix lost prealloc extents beyond eof after full fsync + - btrfs: qgroup: fix deadlock between rescan worker and remove qgroup + - btrfs: add missing run of delayed items after unlink during log replay + - Revert "xfrm: xfrm_state_mtu should return at least 1280 for ipv6" + - net: dcb: disable softirqs in dcbnl_flush_dev() + - hamradio: fix macro redefine warning + - Linux 5.4.183 + * Focal update: v5.4.182 upstream stable release (LP: #1969236) + - cgroup/cpuset: Fix a race between cpuset_attach() and cpu hotplug + - clk: jz4725b: fix mmc0 clock gating + - vhost/vsock: don't check owner in vhost_vsock_stop() while releasing + - parisc/unaligned: Fix fldd and fstd unaligned handlers on 32-bit kernel + - parisc/unaligned: Fix ldw() and stw() unalignment handlers + - drm/amdgpu: disable MMHUB PG for Picasso + - sr9700: sanity check for packet length + - USB: zaurus: support another broken Zaurus + - x86/fpu: Correct pkru/xstate inconsistency + - tee: export teedev_open() and teedev_close_context() + - optee: use driver internal tee_context for some rpc + - lan743x: fix deadlock in lan743x_phy_link_status_change() + - ping: remove pr_err from ping_lookup + - perf data: Fix double free in perf_session__delete() + - bpf: Do not try bpf_msg_push_data with len 0 + - net: __pskb_pull_tail() & pskb_carve_frag_list() drop_monitor friends + - tipc: Fix end of loop tests for list_for_each_entry() + - gso: do not skip outer ip header in case of ipip and net_failover + - openvswitch: Fix setting ipv6 fields causing hw csum failure + - drm/edid: Always set RGB444 + - net/mlx5e: Fix wrong return value on ioctl EEPROM query failure + - net: ll_temac: check the return value of devm_kmalloc() + - net: Force inlining of checksum functions in net/checksum.h + - nfp: flower: Fix a potential leak in nfp_tunnel_add_shared_mac() + - netfilter: nf_tables: fix memory leak during stateful obj update + - net/mlx5: Fix possible deadlock on rule deletion + - net/mlx5: Fix wrong limitation of metadata match on ecpf + - spi: spi-zynq-qspi: Fix a NULL pointer dereference in + zynq_qspi_exec_mem_op() + - configfs: fix a race in configfs_{,un}register_subsystem() + - RDMA/ib_srp: Fix a deadlock + - tracing: Have traceon and traceoff trigger honor the instance + - iio: adc: men_z188_adc: Fix a resource leak in an error handling path + - iio: adc: ad7124: fix mask used for setting AIN_BUFP & AIN_BUFM bits + - iio: Fix error handling for PM + - ata: pata_hpt37x: disable primary channel on HPT371 + - Revert "USB: serial: ch341: add new Product ID for CH341A" + - usb: gadget: rndis: add spinlock for rndis response list + - tracefs: Set the group ownership in apply_options() not parse_options() + - USB: serial: option: add support for DW5829e + - USB: serial: option: add Telit LE910R1 compositions + - usb: dwc3: pci: Fix Bay Trail phy GPIO mappings + - usb: dwc3: gadget: Let the interrupt handler disable bottom halves. + - xhci: re-initialize the HC during resume if HCE was set + - xhci: Prevent futile URB re-submissions due to incorrect return value. + - tty: n_gsm: fix encoding of control signal octet bit DV + - tty: n_gsm: fix proper link termination after failed open + - tty: n_gsm: fix NULL pointer access due to DLCI release + - gpio: tegra186: Fix chip_data type confusion + - Revert "drm/nouveau/pmu/gm200-: avoid touching PMU outside of + DEVINIT/PREOS/ACR" + - memblock: use kfree() to release kmalloced memblock regions + - fget: clarify and improve __fget_files() implementation + - Linux 5.4.182 + * CVE-2022-28390 + - can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path + + -- Joseph Salisbury Fri, 27 May 2022 13:23:49 -0400 + +linux-oracle (5.4.0-1073.79) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1073.79 -proposed tracker (LP: #1973970) + + [ Ubuntu: 5.4.0-113.127 ] + + * focal/linux: 5.4.0-113.127 -proposed tracker (LP: #1973980) + * CVE-2022-29581 + - net/sched: cls_u32: fix netns refcount changes in u32_change() + * CVE-2022-1116 + - io_uring: fix fs->users overflow + * ext4: limit length to bitmap_maxbytes (LP: #1972281) + - ext4: limit length to bitmap_maxbytes - blocksize in punch_hole + * Unprivileged users may use PTRACE_SEIZE to set PTRACE_O_SUSPEND_SECCOMP + option (LP: #1972740) + - ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE + + -- Joseph Salisbury Tue, 24 May 2022 15:07:36 -0400 + +linux-oracle (5.4.0-1071.77) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1071.77 -proposed tracker (LP: #1969043) + + [ Ubuntu: 5.4.0-110.124 ] + + * focal/linux: 5.4.0-110.124 -proposed tracker (LP: #1969053) + * net/mlx5e: Fix page DMA map/unmap attributes (LP: #1967292) + - net/mlx5e: Fix page DMA map/unmap attributes + * xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename() + (LP: #1966803) + - xfs: Fix deadlock between AGI and AGF when target_ip exists in xfs_rename() + * LRMv6: add multi-architecture support (LP: #1968774) + - [Packaging] resync dkms-build{,--nvidia-N} + * xfrm interface cannot be changed anymore (LP: #1968591) + - xfrm: fix the if_id check in changelink + * Use kernel-testing repo from launchpad for ADT tests (LP: #1968016) + - [Debian] Use kernel-testing repo from launchpad + * vmx_ldtr_test in ubuntu_kvm_unit_tests failed (FAIL: Expected 0 for L1 LDTR + selector (got 50)) (LP: #1956315) + - KVM: nVMX: Set LDTR to its architecturally defined value on nested VM-Exit + * [SRU][Regression] Revert "PM: ACPI: reboot: Use S5 for reboot" which causes + Bus Fatal Error when rebooting system with BCM5720 NIC (LP: #1917471) + - Revert "PM: ACPI: reboot: Use S5 for reboot" + * Focal update: v5.4.181 upstream stable release (LP: #1967582) + - Makefile.extrawarn: Move -Wunaligned-access to W=1 + - HID:Add support for UGTABLET WP5540 + - Revert "svm: Add warning message for AVIC IPI invalid target" + - serial: parisc: GSC: fix build when IOSAPIC is not set + - parisc: Drop __init from map_pages declaration + - parisc: Fix data TLB miss in sba_unmap_sg + - parisc: Fix sglist access in ccio-dma.c + - btrfs: send: in case of IO error log it + - platform/x86: ISST: Fix possible circular locking dependency detected + - selftests: rtc: Increase test timeout so that all tests run + - net: ieee802154: at86rf230: Stop leaking skb's + - selftests/zram: Skip max_comp_streams interface on newer kernel + - selftests/zram01.sh: Fix compression ratio calculation + - selftests/zram: Adapt the situation that /dev/zram0 is being used + - ax25: improve the incomplete fix to avoid UAF and NPD bugs + - vfs: make freeze_super abort when sync_filesystem returns error + - quota: make dquot_quota_sync return errors from ->sync_fs + - nvme: fix a possible use-after-free in controller reset during load + - nvme-tcp: fix possible use-after-free in transport error_recovery work + - nvme-rdma: fix possible use-after-free in transport error_recovery work + - drm/amdgpu: fix logic inversion in check + - Revert "module, async: async_synchronize_full() on module init iff async is + used" + - ftrace: add ftrace_init_nop() + - module/ftrace: handle patchable-function-entry + - arm64: module: rework special section handling + - arm64: module/ftrace: intialize PLT at load time + - iwlwifi: fix use-after-free + - drm/radeon: Fix backlight control on iMac 12,1 + - ext4: check for out-of-order index extents in ext4_valid_extent_entries() + - ext4: check for inconsistent extents between index and leaf block + - ext4: prevent partial update of the extent blocks + - taskstats: Cleanup the use of task->exit_code + - dmaengine: at_xdmac: Start transfer for cyclic channels in issue_pending + - vsock: remove vsock from connected table when connect is interrupted by a + signal + - mmc: block: fix read single on recovery logic + - iwlwifi: pcie: fix locking when "HW not ready" + - iwlwifi: pcie: gen2: fix locking when "HW not ready" + - netfilter: nft_synproxy: unregister hooks on init error path + - net: dsa: lan9303: fix reset on probe + - net: ieee802154: ca8210: Fix lifs/sifs periods + - ping: fix the dif and sdif check in ping_lookup + - bonding: force carrier update when releasing slave + - drop_monitor: fix data-race in dropmon_net_event / trace_napi_poll_hit + - bonding: fix data-races around agg_select_timer + - libsubcmd: Fix use-after-free for realloc(..., 0) + - ALSA: hda: Fix regression on forced probe mask option + - ALSA: hda: Fix missing codec probe on Shenker Dock 15 + - ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw() + - ASoC: ops: Fix stereo change notifications in snd_soc_put_volsw_range() + - powerpc/lib/sstep: fix 'ptesync' build error + - mtd: rawnand: gpmi: don't leak PM reference in error path + - block/wbt: fix negative inflight counter when remove scsi device + - NFS: LOOKUP_DIRECTORY is also ok with symlinks + - NFS: Do not report writeback errors in nfs_getattr() + - mtd: rawnand: qcom: Fix clock sequencing in qcom_nandc_probe() + - mtd: rawnand: brcmnand: Fixed incorrect sub-page ECC status + - scsi: lpfc: Fix pt2pt NVMe PRLI reject LOGO loop + - EDAC: Fix calculation of returned address and next offset in + edac_align_ptr() + - net: sched: limit TC_ACT_REPEAT loops + - dmaengine: sh: rcar-dmac: Check for error num after setting mask + - copy_process(): Move fd_install() out of sighand->siglock critical section + - i2c: brcmstb: fix support for DSL and CM variants + - Drivers: hv: vmbus: Fix memory leak in vmbus_add_channel_kobj + - KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW + - ARM: OMAP2+: hwmod: Add of_node_put() before break + - ARM: OMAP2+: adjust the location of put_device() call in omapdss_init_of + - irqchip/sifive-plic: Add missing thead,c900-plic match string + - netfilter: conntrack: don't refresh sctp entries in closed state + - arm64: dts: meson-gx: add ATF BL32 reserved-memory region + - arm64: dts: meson-g12: add ATF BL32 reserved-memory region + - arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610 + - kconfig: let 'shell' return enough output for deep path names + - ata: libata-core: Disable TRIM on M88V29 + - drm/rockchip: dw_hdmi: Do not leave clock enabled in error case + - tracing: Fix tp_printk option related with tp_printk_stop_on_boot + - net: usb: qmi_wwan: Add support for Dell DW5829e + - net: macb: Align the dma and coherent dma masks + - kconfig: fix failing to generate auto.conf + - Linux 5.4.181 + * Focal update: v5.4.180 upstream stable release (LP: #1966118) + - integrity: check the return value of audit_log_start() + - ima: Remove ima_policy file before directory + - ima: Allow template selection with ima_template[_fmt]= after ima_hash= + - ima: Do not print policy rule with inactive LSM labels + - mmc: sdhci-of-esdhc: Check for error num after setting mask + - net: phy: marvell: Fix RGMII Tx/Rx delays setting in 88e1121-compatible PHYs + - net: phy: marvell: Fix MDI-x polarity setting in 88e1118-compatible PHYs + - NFS: Fix initialisation of nfs_client cl_flags field + - NFSD: Clamp WRITE offsets + - NFSD: Fix offset type in I/O trace points + - NFSv4 only print the label when its queried + - nfs: nfs4clinet: check the return value of kstrdup() + - NFSv4.1: Fix uninitialised variable in devicenotify + - NFSv4 remove zero number of fs_locations entries error check + - NFSv4 expose nfs_parse_server_name function + - drm: panel-orientation-quirks: Add quirk for the 1Netbook OneXPlayer + - net: sched: Clarify error message when qdisc kind is unknown + - scsi: target: iscsi: Make sure the np under each tpg is unique + - scsi: qedf: Fix refcount issue when LOGO is received during TMF + - scsi: myrs: Fix crash in error case + - PM: hibernate: Remove register_nosave_region_late() + - usb: dwc2: gadget: don't try to disable ep0 in dwc2_hsotg_suspend + - net: stmmac: dwmac-sun8i: use return val of readl_poll_timeout() + - KVM: nVMX: eVMCS: Filter out VM_EXIT_SAVE_VMX_PREEMPTION_TIMER + - riscv: fix build with binutils 2.38 + - ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from hog group + - ARM: socfpga: fix missing RESET_CONTROLLER + - nvme-tcp: fix bogus request completion when failing to send AER + - ACPI/IORT: Check node revision for PMCG resources + - PM: s2idle: ACPI: Fix wakeup interrupts handling + - net: bridge: fix stale eth hdr pointer in br_dev_xmit + - perf probe: Fix ppc64 'perf probe add events failed' case + - ARM: dts: meson: Fix the UART compatible strings + - staging: fbtft: Fix error path in fbtft_driver_module_init() + - ARM: dts: imx6qdl-udoo: Properly describe the SD card detect + - usb: f_fs: Fix use-after-free for epfile + - misc: fastrpc: avoid double fput() on failed usercopy + - ixgbevf: Require large buffers for build_skb on 82599VF + - bonding: pair enable_port with slave_arr_updates + - ipmr,ip6mr: acquire RTNL before calling ip[6]mr_free_table() on failure path + - nfp: flower: fix ida_idx not being released + - net: do not keep the dst cache when uncloning an skb dst and its metadata + - net: fix a memleak when uncloning an skb dst and its metadata + - veth: fix races around rq->rx_notify_masked + - net: mdio: aspeed: Add missing MODULE_DEVICE_TABLE + - tipc: rate limit warning for received illegal binding update + - net: amd-xgbe: disable interrupts during pci removal + - vt_ioctl: fix array_index_nospec in vt_setactivate + - vt_ioctl: add array_index_nospec to VT_ACTIVATE + - n_tty: wake up poll(POLLRDNORM) on receiving data + - eeprom: ee1004: limit i2c reads to I2C_SMBUS_BLOCK_MAX + - net: usb: ax88179_178a: Fix out-of-bounds accesses in RX fixup + - usb: ulpi: Move of_node_put to ulpi_dev_release + - usb: ulpi: Call of_node_put correctly + - usb: dwc3: gadget: Prevent core from processing stale TRBs + - usb: gadget: udc: renesas_usb3: Fix host to USB_ROLE_NONE transition + - USB: gadget: validate interface OS descriptor requests + - usb: gadget: rndis: check size of RNDIS_MSG_SET command + - usb: gadget: f_uac2: Define specific wTerminalType + - USB: serial: ftdi_sio: add support for Brainboxes US-159/235/320 + - USB: serial: option: add ZTE MF286D modem + - USB: serial: ch341: add support for GW Instek USB2.0-Serial devices + - USB: serial: cp210x: add NCR Retail IO box id + - USB: serial: cp210x: add CPI Bulk Coin Recycler id + - seccomp: Invalidate seccomp mode to catch death failures + - hwmon: (dell-smm) Speed up setting of fan speed + - scsi: lpfc: Remove NVMe support if kernel has NVME_FC disabled + - perf: Fix list corruption in perf_cgroup_switch() + - Linux 5.4.180 + * Focal update: v5.4.179 upstream stable release (LP: #1965591) + - moxart: fix potential use-after-free on remove path + - Linux 5.4.179 + * CVE-2020-27820 + - drm/nouveau: Add a dedicated mutex for the clients list + - drm/nouveau: clean up all clients on device removal + * CVE-2022-1016 + - netfilter: nf_tables: initialize registers in nft_do_chain() + * CVE-2022-27223 + - USB: gadget: validate endpoint index for xilinx udc + * CVE-2022-26490 + - nfc: st21nfca: Fix potential buffer overflows in EVT_TRANSACTION + * CVE-2021-26401 + - x86/speculation: Use generic retpoline by default on AMD + - x86/speculation: Update link to AMD speculation whitepaper + - x86/speculation: Warn about Spectre v2 LFENCE mitigation + - x86/speculation: Warn about eIBRS + LFENCE + Unprivileged eBPF + SMT + * CVE-2022-0001 + - x86/speculation: Include unprivileged eBPF status in Spectre v2 mitigation + reporting + + [ Ubuntu: 5.4.0-109.123 ] + + * focal/linux: 5.4.0-109.123 -proposed tracker (LP: #1968290) + * USB devices not detected during boot on USB 3.0 hubs (LP: #1968210) + - SAUCE: Revert "Revert "xhci: Set HCD flag to defer primary roothub + registration"" + - SAUCE: Revert "Revert "usb: core: hcd: Add support for deferring roothub + registration"" + + -- Joseph Salisbury Tue, 19 Apr 2022 12:47:36 -0400 + +linux-oracle (5.4.0-1070.76) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1070.76 -proposed tracker (LP: #1967385) + + [ Ubuntu: 5.4.0-108.122 ] + + * focal/linux: 5.4.0-108.122 -proposed tracker (LP: #1966740) + * Packaging resync (LP: #1786013) + - [Packaging] resync dkms-build{,--nvidia-N} from LRMv5 + - debian/dkms-versions -- update from kernel-versions (main/2022.03.21) + * Low RX performance for 40G Solarflare NICs (LP: #1964512) + - SAUCE: sfc: The size of the RX recycle ring should be more flexible + * [UBUNTU 20.04] KVM: Enable storage key checking for intercepted instruction + (LP: #1962831) + - selftests: kvm: add _vm_ioctl + - selftests: kvm: Introduce the TEST_FAIL macro + - KVM: selftests: Add GUEST_ASSERT variants to pass values to host + - KVM: s390: gaccess: Refactor gpa and length calculation + - KVM: s390: gaccess: Refactor access address range check + - KVM: s390: gaccess: Cleanup access to guest pages + - s390/uaccess: introduce bit field for OAC specifier + - s390/uaccess: fix compile error + - s390/uaccess: Add copy_from/to_user_key functions + - KVM: s390: Honor storage keys when accessing guest memory + - KVM: s390: handle_tprot: Honor storage keys + - KVM: s390: selftests: Test TEST PROTECTION emulation + - KVM: s390: Add optional storage key checking to MEMOP IOCTL + - KVM: s390: Add vm IOCTL for key checked guest absolute memory access + - KVM: s390: Rename existing vcpu memop functions + - KVM: s390: Add capability for storage key extension of MEM_OP IOCTL + - KVM: s390: Update api documentation for memop ioctl + - KVM: s390: Clarify key argument for MEM_OP in api docs + - KVM: s390: Add missing vm MEM_OP size check + * 【sec-0911】 fail to reset sec module (LP: #1943301) + - crypto: hisilicon/sec2 - Add workqueue for SEC driver. + - crypto: hisilicon/sec2 - update SEC initialization and reset + * Lots of hisi_qm zombie task slow down system after stress test + (LP: #1932117) + - crypto: hisilicon - Use one workqueue per qm instead of per qp + * Lots of hisi_qm zombie task slow down system after stress test + (LP: #1932117) // 【sec-0911】 fail to reset sec module (LP: #1943301) + - crypto: hisilicon - Unify hardware error init/uninit into QM + * [UBUNTU 20.04] Fix SIGP processing on KVM/s390 (LP: #1962578) + - KVM: s390: Simplify SIGP Set Arch handling + - KVM: s390: Add a routine for setting userspace CPU state + * Move virtual graphics drivers from linux-modules-extra to linux-modules + (LP: #1960633) + - [Packaging] Move VM DRM drivers into modules + * Focal update: v5.4.178 upstream stable release (LP: #1964634) + - audit: improve audit queue handling when "audit=1" on cmdline + - ASoC: ops: Reject out of bounds values in snd_soc_put_volsw() + - ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx() + - ASoC: ops: Reject out of bounds values in snd_soc_put_xr_sx() + - ALSA: usb-audio: Simplify quirk entries with a macro + - ALSA: hda/realtek: Add quirk for ASUS GU603 + - ALSA: hda/realtek: Add missing fixup-model entry for Gigabyte X570 ALC1220 + quirks + - ALSA: hda/realtek: Fix silent output on Gigabyte X570S Aorus Master (newer + chipset) + - ALSA: hda/realtek: Fix silent output on Gigabyte X570 Aorus Xtreme after + reboot from Windows + - btrfs: fix deadlock between quota disable and qgroup rescan worker + - drm/nouveau: fix off by one in BIOS boundary checking + - mm/kmemleak: avoid scanning potential huge holes + - block: bio-integrity: Advance seed correctly for larger interval sizes + - memcg: charge fs_context and legacy_fs_context + - IB/rdmavt: Validate remote_addr during loopback atomic tests + - RDMA/siw: Fix broken RDMA Read Fence/Resume logic. + - RDMA/mlx4: Don't continue event handler after memory allocation failure + - iommu/vt-d: Fix potential memory leak in intel_setup_irq_remapping() + - iommu/amd: Fix loop timeout issue in iommu_ga_log_enable() + - spi: bcm-qspi: check for valid cs before applying chip select + - spi: mediatek: Avoid NULL pointer crash in interrupt + - spi: meson-spicc: add IRQ check in meson_spicc_probe + - net: ieee802154: hwsim: Ensure proper channel selection at probe time + - net: ieee802154: mcr20a: Fix lifs/sifs periods + - net: ieee802154: ca8210: Stop leaking skb's + - net: ieee802154: Return meaningful error codes from the netlink helpers + - net: macsec: Verify that send_sci is on when setting Tx sci explicitly + - net: stmmac: dump gmac4 DMA registers correctly + - net: stmmac: ensure PTP time register reads are consistent + - drm/i915/overlay: Prevent divide by zero bugs in scaling + - ASoC: fsl: Add missing error handling in pcm030_fabric_probe + - ASoC: xilinx: xlnx_formatter_pcm: Make buffer bytes multiple of period bytes + - ASoC: cpcap: Check for NULL pointer after calling of_get_child_by_name + - ASoC: max9759: fix underflow in speaker_gain_control_put() + - pinctrl: bcm2835: Fix a few error paths + - scsi: bnx2fc: Make bnx2fc_recv_frame() mp safe + - nfsd: nfsd4_setclientid_confirm mistakenly expires confirmed client. + - selftests: futex: Use variable MAKE instead of make + - rtc: cmos: Evaluate century appropriate + - EDAC/altera: Fix deferred probing + - EDAC/xgene: Fix deferred probing + - ext4: fix error handling in ext4_restore_inline_data() + - cgroup/cpuset: Fix "suspicious RCU usage" lockdep warning + - Linux 5.4.178 + * Focal update: v5.4.177 upstream stable release (LP: #1964628) + - PCI: pciehp: Fix infinite loop in IRQ handler upon power fault + - psi: Fix uaf issue when psi trigger is destroyed while being polled + - ipheth: fix EOVERFLOW in ipheth_rcvbulk_callback + - net: amd-xgbe: ensure to reset the tx_timer_active flag + - net: amd-xgbe: Fix skb data length underflow + - rtnetlink: make sure to refresh master_dev/m_ops in __rtnl_newlink() + - cpuset: Fix the bug that subpart_cpus updated wrongly in update_cpumask() + - af_packet: fix data-race in packet_setsockopt / packet_setsockopt + - Linux 5.4.177 + * Focal update: v5.4.176 upstream stable release (LP: #1962345) + - s390/hypfs: include z/VM guests with access control group set + - scsi: zfcp: Fix failed recovery on gone remote port with non-NPIV FCP + devices + - udf: Restore i_lenAlloc when inode expansion fails + - udf: Fix NULL ptr deref when converting from inline format + - PM: wakeup: simplify the output logic of pm_show_wakelocks() + - tracing/histogram: Fix a potential memory leak for kstrdup() + - tracing: Don't inc err_log entry count if entry allocation fails + - fsnotify: fix fsnotify hooks in pseudo filesystems + - drm/etnaviv: relax submit size limits + - arm64: errata: Fix exec handling in erratum 1418040 workaround + - netfilter: nft_payload: do not update layer 4 checksum when mangling + fragments + - serial: 8250: of: Fix mapped region size when using reg-offset property + - serial: stm32: fix software flow control transfer + - tty: n_gsm: fix SW flow control encoding/handling + - tty: Add support for Brainboxes UC cards. + - usb-storage: Add unusual-devs entry for VL817 USB-SATA bridge + - usb: common: ulpi: Fix crash in ulpi_match() + - usb: gadget: f_sourcesink: Fix isoc transfer for USB_SPEED_SUPER_PLUS + - USB: core: Fix hang in usb_kill_urb by adding memory barriers + - usb: typec: tcpm: Do not disconnect while receiving VBUS off + - ucsi_ccg: Check DEV_INT bit only when starting CCG4 + - net: sfp: ignore disabled SFP node + - powerpc/32: Fix boot failure with GCC latent entropy plugin + - i40e: Increase delay to 1 s after global EMP reset + - i40e: Fix issue when maximum queues is exceeded + - i40e: Fix queues reservation for XDP + - i40e: fix unsigned stat widths + - rpmsg: char: Fix race between the release of rpmsg_ctrldev and cdev + - rpmsg: char: Fix race between the release of rpmsg_eptdev and cdev + - scsi: bnx2fc: Flush destroy_work queue before calling bnx2fc_interface_put() + - ipv6_tunnel: Rate limit warning messages + - net: fix information leakage in /proc/net/ptype + - hwmon: (lm90) Mark alert as broken for MAX6646/6647/6649 + - hwmon: (lm90) Mark alert as broken for MAX6680 + - ping: fix the sk_bound_dev_if match in ping_lookup + - ipv4: avoid using shared IP generator for connected sockets + - hwmon: (lm90) Reduce maximum conversion rate for G781 + - NFSv4: Handle case where the lookup of a directory fails + - NFSv4: nfs_atomic_open() can race when looking up a non-regular file + - net-procfs: show net devices bound packet types + - drm/msm: Fix wrong size calculation + - drm/msm/dsi: Fix missing put_device() call in dsi_get_phy + - drm/msm/dsi: invalid parameter check in msm_dsi_phy_enable + - ipv6: annotate accesses to fn->fn_sernum + - NFS: Ensure the server has an up to date ctime before hardlinking + - NFS: Ensure the server has an up to date ctime before renaming + - netfilter: conntrack: don't increment invalid counter on NF_REPEAT + - net: phy: broadcom: hook up soft_reset for BCM54616S + - phylib: fix potential use-after-free + - rxrpc: Adjust retransmission backoff + - hwmon: (lm90) Mark alert as broken for MAX6654 + - ibmvnic: init ->running_cap_crqs early + - ibmvnic: don't spin in tasklet + - drm/msm/hdmi: Fix missing put_device() call in msm_hdmi_get_phy + - yam: fix a memory leak in yam_siocdevprivate() + - net: hns3: handle empty unknown interrupt for VF + - ipv4: raw: lock the socket in raw_bind() + - ipv4: tcp: send zero IPID in SYNACK messages + - ipv4: remove sparse error in ip_neigh_gw4() + - dt-bindings: can: tcan4x5x: fix mram-cfg RX FIFO config + - fsnotify: invalidate dcache before IN_DELETE event + - block: Fix wrong offset in bio_truncate() + - mtd: rawnand: mpc5121: Remove unused variable in ads5121_select_chip() + - Linux 5.4.176 + * Focal update: v5.4.175 upstream stable release (LP: #1962330) + - rcu: Tighten rcu_advance_cbs_nowake() checks + - pinctrl: bcm2835: Drop unused define + - pinctrl: bcm2835: Refactor platform data + - pinctrl: bcm2835: Add support for all GPIOs on BCM2711 + - pinctrl: bcm2835: Match BCM7211 compatible string + - pinctrl: bcm2835: Add support for wake-up interrupts + - pinctrl: bcm2835: Change init order for gpio hogs + - ARM: dts: gpio-ranges property is now required + - mmc: sdhci-esdhc-imx: disable CMDQ support + - select: Fix indefinitely sleeping task in poll_schedule_timeout() + - Linux 5.4.175 + + -- Ian May Tue, 05 Apr 2022 08:55:53 -0500 + +linux-oracle (5.4.0-1069.75) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1069.75 -proposed tracker (LP: #1966265) + + [ Ubuntu: 5.4.0-107.121 ] + + * focal/linux: 5.4.0-107.121 -proposed tracker (LP: #1966275) + * CVE-2022-27666 + - esp: Fix possible buffer overflow in ESP transformation + * CVE-2022-1055 + - net: sched: fix use-after-free in tc_new_tfilter() + * Pick fixup from v5.4.176 upstream stable release to address cert + failure with clock jitter test in NUC7i3DNHE (LP: #1964204) + - Bluetooth: refactor malicious adv data check + + -- Tim Gardner Fri, 25 Mar 2022 06:34:29 -0600 + +linux-oracle (5.4.0-1067.72) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1067.72 -proposed tracker (LP: #1964198) + + * Miscellaneous Ubuntu changes + - [Config]: oracle: Update gcc version used for build to 90400 + + [ Ubuntu: 5.4.0-105.119 ] + + * CVE-2022-0847 + - lib/iov_iter: initialize "flags" in new pipe_buffer + * Broken network on some AWS instances with focal/impish kernels + (LP: #1961968) + - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success" + * [UBUNTU 20.04] kernel: Add support for CPU-MF counter second version 7 + (LP: #1960182) + - s390/cpumf: Support for CPU Measurement Facility CSVN 7 + - s390/cpumf: Support for CPU Measurement Sampling Facility LS bit + * Hipersocket page allocation failure on Ubuntu 20.04 based SSC environments + (LP: #1959529) + - s390/qeth: use memory reserves to back RX buffers + * CVE-2022-0516 + - KVM: s390: Return error on SIDA memop on normal guest + * CVE-2022-0435 + - tipc: improve size validations for received domain records + * CVE-2022-0492 + - cgroup-v1: Require capabilities to set release_agent + * Recalled NFSv4 files delegations overwhelm server (LP: #1957986) + - NFSv4: Fix delegation handling in update_open_stateid() + - NFSv4: nfs4_callback_getattr() should ignore revoked delegations + - NFSv4: Delegation recalls should not find revoked delegations + - NFSv4: fail nfs4_refresh_delegation_stateid() when the delegation was + revoked + - NFS: Rename nfs_inode_return_delegation_noreclaim() + - NFSv4: Don't remove the delegation from the super_list more than once + - NFSv4: Hold the delegation spinlock when updating the seqid + - NFSv4: Clear the NFS_DELEGATION_REVOKED flag in + nfs_update_inplace_delegation() + - NFSv4: Update the stateid seqid in nfs_revoke_delegation() + - NFSv4: Revoke the delegation on success in nfs4_delegreturn_done() + - NFSv4: Ignore requests to return the delegation if it was revoked + - NFSv4: Don't reclaim delegations that have been returned or revoked + - NFSv4: nfs4_return_incompatible_delegation() should check delegation + validity + - NFSv4: Fix nfs4_inode_make_writeable() + - NFS: nfs_inode_find_state_and_recover() fix stateid matching + - NFSv4: Fix races between open and delegreturn + - NFSv4: Handle NFS4ERR_OLD_STATEID in delegreturn + - NFSv4: Don't retry the GETATTR on old stateid in nfs4_delegreturn_done() + - NFSv4: nfs_inode_evict_delegation() should set NFS_DELEGATION_RETURNING + - NFS: Clear NFS_DELEGATION_RETURN_IF_CLOSED when the delegation is returned + - NFSv4: Try to return the delegation immediately when marked for return on + close + - NFSv4: Add accounting for the number of active delegations held + - NFSv4: Limit the total number of cached delegations + - NFSv4: Ensure the delegation is pinned in nfs_do_return_delegation() + - NFSv4: Ensure the delegation cred is pinned when we call delegreturn + * Focal update: v5.4.174 upstream stable release (LP: #1960566) + - HID: uhid: Fix worker destroying device without any protection + - HID: wacom: Reset expected and received contact counts at the same time + - HID: wacom: Ignore the confidence flag when a touch is removed + - HID: wacom: Avoid using stale array indicies to read contact count + - f2fs: fix to do sanity check in is_alive() + - nfc: llcp: fix NULL error pointer dereference on sendmsg() after failed + bind() + - mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings + - mtd: rawnand: gpmi: Remove explicit default gpmi clock setting for i.MX6 + - x86/gpu: Reserve stolen memory for first integrated Intel GPU + - tools/nolibc: x86-64: Fix startup code bug + - tools/nolibc: i386: fix initial stack alignment + - tools/nolibc: fix incorrect truncation of exit code + - rtc: cmos: take rtc_lock while reading from CMOS + - media: v4l2-ioctl.c: readbuffers depends on V4L2_CAP_READWRITE + - media: flexcop-usb: fix control-message timeouts + - media: mceusb: fix control-message timeouts + - media: em28xx: fix control-message timeouts + - media: cpia2: fix control-message timeouts + - media: s2255: fix control-message timeouts + - media: dib0700: fix undefined behavior in tuner shutdown + - media: redrat3: fix control-message timeouts + - media: pvrusb2: fix control-message timeouts + - media: stk1160: fix control-message timeouts + - can: softing_cs: softingcs_probe(): fix memleak on registration failure + - lkdtm: Fix content of section containing lkdtm_rodata_do_nothing() + - iommu/io-pgtable-arm-v7s: Add error handle for page table allocation failure + - dma_fence_array: Fix PENDING_ERROR leak in dma_fence_array_signaled() + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9125 SATA controller + - mm_zone: add function to check if managed dma zone exists + - mm/page_alloc.c: do not warn allocation failure on zone DMA if no managed + pages + - shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode + - drm/rockchip: dsi: Hold pm-runtime across bind/unbind + - drm/rockchip: dsi: Reconfigure hardware on resume() + - drm/panel: kingdisplay-kd097d04: Delete panel on attach() failure + - drm/panel: innolux-p079zca: Delete panel on attach() failure + - drm/rockchip: dsi: Fix unbalanced clock on probe error + - Bluetooth: cmtp: fix possible panic when cmtp_init_sockets() fails + - clk: bcm-2835: Pick the closest clock rate + - clk: bcm-2835: Remove rounding up the dividers + - wcn36xx: Indicate beacon not connection loss on MISSED_BEACON_IND + - wcn36xx: Release DMA channel descriptor allocations + - media: videobuf2: Fix the size printk format + - media: aspeed: fix mode-detect always time out at 2nd run + - media: em28xx: fix memory leak in em28xx_init_dev + - media: aspeed: Update signal status immediately to ensure sane hw state + - arm64: dts: meson-gxbb-wetek: fix HDMI in early boot + - arm64: dts: meson-gxbb-wetek: fix missing GPIO binding + - Bluetooth: stop proccessing malicious adv data + - tee: fix put order in teedev_close_context() + - media: dmxdev: fix UAF when dvb_register_device() fails + - crypto: qce - fix uaf on qce_ahash_register_one + - arm64: dts: ti: k3-j721e: correct cache-sets info + - tty: serial: atmel: Check return code of dmaengine_submit() + - tty: serial: atmel: Call dma_async_issue_pending() + - media: rcar-csi2: Correct the selection of hsfreqrange + - media: imx-pxp: Initialize the spinlock prior to using it + - media: si470x-i2c: fix possible memory leak in si470x_i2c_probe() + - media: mtk-vcodec: call v4l2_m2m_ctx_release first when file is released + - media: venus: core: Fix a resource leak in the error handling path of + 'venus_probe()' + - netfilter: bridge: add support for pppoe filtering + - arm64: dts: qcom: msm8916: fix MMC controller aliases + - ACPI: EC: Rework flushing of EC work while suspended to idle + - drm/amdgpu: Fix a NULL pointer dereference in + amdgpu_connector_lcd_native_mode() + - drm/radeon/radeon_kms: Fix a NULL pointer dereference in + radeon_driver_open_kms() + - arm64: dts: ti: k3-j721e: Fix the L2 cache sets + - tty: serial: uartlite: allow 64 bit address + - serial: amba-pl011: do not request memory region twice + - floppy: Fix hang in watchdog when disk is ejected + - staging: rtl8192e: return error code from rtllib_softmac_init() + - staging: rtl8192e: rtllib_module: fix error handle case in alloc_rtllib() + - Bluetooth: btmtksdio: fix resume failure + - media: dib8000: Fix a memleak in dib8000_init() + - media: saa7146: mxb: Fix a NULL pointer dereference in mxb_attach() + - media: si2157: Fix "warm" tuner state detection + - sched/rt: Try to restart rt period timer when rt runtime exceeded + - rcu/exp: Mark current CPU as exp-QS in IPI loop second pass + - mwifiex: Fix possible ABBA deadlock + - xfrm: fix a small bug in xfrm_sa_len() + - crypto: stm32/cryp - fix xts and race condition in crypto_engine requests + - crypto: stm32/cryp - fix double pm exit + - crypto: stm32/cryp - fix lrw chaining mode + - ARM: dts: gemini: NAS4220-B: fis-index-block with 128 KiB sectors + - media: dw2102: Fix use after free + - media: msi001: fix possible null-ptr-deref in msi001_probe() + - media: coda/imx-vdoa: Handle dma_set_coherent_mask error codes + - drm/msm/dpu: fix safe status debugfs file + - drm/bridge: ti-sn65dsi86: Set max register for regmap + - media: hantro: Fix probe func error path + - xfrm: interface with if_id 0 should return error + - xfrm: state and policy should fail if XFRMA_IF_ID 0 + - ARM: 9159/1: decompressor: Avoid UNPREDICTABLE NOP encoding + - usb: ftdi-elan: fix memory leak on device disconnect + - ARM: dts: armada-38x: Add generic compatible to UART nodes + - mmc: meson-mx-sdio: add IRQ check + - selinux: fix potential memleak in selinux_add_opt() + - bpftool: Enable line buffering for stdout + - x86/mce/inject: Avoid out-of-bounds write when setting flags + - ACPI: scan: Create platform device for BCM4752 and LNV4752 ACPI nodes + - pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in + __nonstatic_find_io_region() + - pcmcia: rsrc_nonstatic: Fix a NULL pointer dereference in + nonstatic_find_mem_region() + - netfilter: ipt_CLUSTERIP: fix refcount leak in clusterip_tg_check() + - bpf: Fix SO_RCVBUF/SO_SNDBUF handling in _bpf_setsockopt(). + - ppp: ensure minimum packet size in ppp_write() + - rocker: fix a sleeping in atomic bug + - staging: greybus: audio: Check null pointer + - fsl/fman: Check for null pointer after calling devm_ioremap + - Bluetooth: hci_bcm: Check for error irq + - HID: hid-uclogic-params: Invalid parameter check in uclogic_params_init + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_get_str_desc + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_huion_init + - HID: hid-uclogic-params: Invalid parameter check in + uclogic_params_frame_init_v1_buttonpad + - debugfs: lockdown: Allow reading debugfs files that are not world readable + - net/mlx5e: Don't block routes with nexthop objects in SW + - Revert "net/mlx5e: Block offload of outer header csum for UDP tunnels" + - net/mlx5: Set command entry semaphore up once got index free + - spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe + - tpm: add request_locality before write TPM_INT_ENABLE + - can: softing: softing_startstop(): fix set but not used variable warning + - can: xilinx_can: xcan_probe(): check for error irq + - pcmcia: fix setting of kthread task states + - net: mcs7830: handle usb read errors properly + - ext4: avoid trim error on fs with small groups + - ALSA: jack: Add missing rwsem around snd_ctl_remove() calls + - ALSA: PCM: Add missing rwsem around snd_ctl_remove() calls + - ALSA: hda: Add missing rwsem around snd_ctl_remove() calls + - RDMA/hns: Validate the pkey index + - clk: imx8mn: Fix imx8mn_clko1_sels + - powerpc/prom_init: Fix improper check of prom_getprop() + - ASoC: uniphier: drop selecting non-existing SND_SOC_UNIPHIER_AIO_DMA + - ALSA: oss: fix compile error when OSS_DEBUG is enabled + - char/mwave: Adjust io port register size + - binder: fix handling of error during copy + - iommu/io-pgtable-arm: Fix table descriptor paddr formatting + - scsi: ufs: Fix race conditions related to driver data + - PCI/MSI: Fix pci_irq_vector()/pci_irq_get_affinity() + - powerpc/powermac: Add additional missing lockdep_register_key() + - RDMA/core: Let ib_find_gid() continue search even after empty entry + - RDMA/cma: Let cma_resolve_ib_dev() continue search even after empty entry + - ASoC: rt5663: Handle device_property_read_u32_array error codes + - clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after system + enter shell + - dmaengine: pxa/mmp: stop referencing config->slave_id + - iommu/iova: Fix race between FQ timeout and teardown + - phy: uniphier-usb3ss: fix unintended writing zeros to PHY register + - ASoC: samsung: idma: Check of ioremap return value + - misc: lattice-ecp3-config: Fix task hung when firmware load failed + - mips: lantiq: add support for clk_set_parent() + - mips: bcm63xx: add support for clk_set_parent() + - RDMA/cxgb4: Set queue pair state when being queried + - of: base: Fix phandle argument length mismatch error message + - Bluetooth: Fix debugfs entry leak in hci_register_dev() + - fs: dlm: filter user dlm messages for kernel locks + - drm/lima: fix warning when CONFIG_DEBUG_SG=y & CONFIG_DMA_API_DEBUG=y + - ar5523: Fix null-ptr-deref with unexpected WDCMSG_TARGET_START reply + - drm/nouveau/pmu/gm200-: avoid touching PMU outside of DEVINIT/PREOS/ACR + - ARM: shmobile: rcar-gen2: Add missing of_node_put() + - batman-adv: allow netlink usage in unprivileged containers + - usb: gadget: f_fs: Use stream_open() for endpoint files + - drm: panel-orientation-quirks: Add quirk for the Lenovo Yoga Book X91F/L + - HID: apple: Do not reset quirks when the Fn key is not found + - media: b2c2: Add missing check in flexcop_pci_isr: + - EDAC/synopsys: Use the quirk for version instead of ddr version + - mlxsw: pci: Add shutdown method in PCI driver + - drm/bridge: megachips: Ensure both bridges are probed before registration + - gpiolib: acpi: Do not set the IRQ type if the IRQ is already in use + - HSI: core: Fix return freed object in hsi_new_client + - mwifiex: Fix skb_over_panic in mwifiex_usb_recv() + - rsi: Fix use-after-free in rsi_rx_done_handler() + - rsi: Fix out-of-bounds read in rsi_read_pkt() + - usb: uhci: add aspeed ast2600 uhci support + - floppy: Add max size check for user space request + - x86/mm: Flush global TLB when switching to trampoline page-table + - media: uvcvideo: Increase UVC_CTRL_CONTROL_TIMEOUT to 5 seconds. + - media: saa7146: hexium_orion: Fix a NULL pointer dereference in + hexium_attach() + - media: m920x: don't use stack on USB reads + - iwlwifi: mvm: synchronize with FW after multicast commands + - ath10k: Fix tx hanging + - net-sysfs: update the queue counts in the unregistration path + - net: phy: prefer 1000baseT over 1000baseKX + - gpio: aspeed: Convert aspeed_gpio.lock to raw_spinlock + - x86/mce: Mark mce_panic() noinstr + - x86/mce: Mark mce_end() noinstr + - x86/mce: Mark mce_read_aux() noinstr + - net: bonding: debug: avoid printing debug logs when bond is not notifying + peers + - bpf: Do not WARN in bpf_warn_invalid_xdp_action() + - HID: quirks: Allow inverting the absolute X/Y values + - media: igorplugusb: receiver overflow should be reported + - media: saa7146: hexium_gemini: Fix a NULL pointer dereference in + hexium_attach() + - mmc: core: Fixup storing of OCR for MMC_QUIRK_NONSTD_SDIO + - audit: ensure userspace is penalized the same as the kernel when under + pressure + - arm64: dts: ls1028a-qds: move rtc node to the correct i2c bus + - arm64: tegra: Adjust length of CCPLEX cluster MMIO region + - cpufreq: Fix initialization of min and max frequency QoS requests + - usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0 + - ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream + - iwlwifi: fix leaks/bad data after failed firmware load + - iwlwifi: remove module loading failure message + - iwlwifi: mvm: Fix calculation of frame length + - um: registers: Rename function names to avoid conflicts and build problems + - jffs2: GC deadlock reading a page that is used in jffs2_write_begin() + - ACPICA: actypes.h: Expand the ACPI_ACCESS_ definitions + - ACPICA: Utilities: Avoid deleting the same object twice in a row + - ACPICA: Executer: Fix the REFCLASS_REFOF case in acpi_ex_opcode_1A_0T_1R() + - ACPICA: Fix wrong interpretation of PCC address + - ACPICA: Hardware: Do not flush CPU cache when entering S4 and S5 + - drm/amdgpu: fixup bad vram size on gmc v8 + - ACPI: battery: Add the ThinkPad "Not Charging" quirk + - btrfs: remove BUG_ON() in find_parent_nodes() + - btrfs: remove BUG_ON(!eie) in find_parent_nodes + - net: mdio: Demote probed message to debug print + - mac80211: allow non-standard VHT MCS-10/11 + - dm btree: add a defensive bounds check to insert_at() + - dm space map common: add bounds check to sm_ll_lookup_bitmap() + - net: phy: marvell: configure RGMII delays for 88E1118 + - net: gemini: allow any RGMII interface mode + - regulator: qcom_smd: Align probe function with rpmh-regulator + - serial: pl010: Drop CR register reset on set_termios + - serial: core: Keep mctrl register state and cached copy in sync + - random: do not throw away excess input to crng_fast_load + - parisc: Avoid calling faulthandler_disabled() twice + - powerpc/6xx: add missing of_node_put + - powerpc/powernv: add missing of_node_put + - powerpc/cell: add missing of_node_put + - powerpc/btext: add missing of_node_put + - powerpc/watchdog: Fix missed watchdog reset due to memory ordering race + - i2c: i801: Don't silently correct invalid transfer size + - powerpc/smp: Move setup_profiling_timer() under CONFIG_PROFILING + - i2c: mpc: Correct I2C reset procedure + - clk: meson: gxbb: Fix the SDM_EN bit for MPLL0 on GXBB + - powerpc/powermac: Add missing lockdep_register_key() + - KVM: PPC: Book3S: Suppress failed alloc warning in H_COPY_TOFROM_GUEST + - w1: Misuse of get_user()/put_user() reported by sparse + - scsi: lpfc: Trigger SLI4 firmware dump before doing driver cleanup + - ALSA: seq: Set upper limit of processed events + - powerpc: handle kdump appropriately with crash_kexec_post_notifiers option + - MIPS: OCTEON: add put_device() after of_find_device_by_node() + - i2c: designware-pci: Fix to change data types of hcnt and lcnt parameters + - MIPS: Octeon: Fix build errors using clang + - scsi: sr: Don't use GFP_DMA + - ASoC: mediatek: mt8173: fix device_node leak + - power: bq25890: Enable continuous conversion for ADC at charging + - rpmsg: core: Clean up resources on announce_create failure. + - crypto: omap-aes - Fix broken pm_runtime_and_get() usage + - crypto: stm32/crc32 - Fix kernel BUG triggered in probe() + - crypto: caam - replace this_cpu_ptr with raw_cpu_ptr + - ubifs: Error path in ubifs_remount_rw() seems to wrongly free write buffers + - fuse: Pass correct lend value to filemap_write_and_wait_range() + - serial: Fix incorrect rs485 polarity on uart open + - cputime, cpuacct: Include guest time in user time in cpuacct.stat + - tracing/kprobes: 'nmissed' not showed correctly for kretprobe + - iwlwifi: mvm: Increase the scan timeout guard to 30 seconds + - s390/mm: fix 2KB pgtable release race + - drm/etnaviv: limit submit sizes + - drm/nouveau/kms/nv04: use vzalloc for nv04_display + - drm/bridge: analogix_dp: Make PSR-exit block less + - PCI: pci-bridge-emul: Properly mark reserved PCIe bits in PCI config space + - PCI: pci-bridge-emul: Correctly set PCIe capabilities + - PCI: pci-bridge-emul: Set PCI_STATUS_CAP_LIST for PCIe device + - xfrm: fix policy lookup for ipv6 gre packets + - btrfs: fix deadlock between quota enable and other quota operations + - btrfs: check the root node for uptodate before returning it + - btrfs: respect the max size in the header when activating swap file + - ext4: make sure to reset inode lockdep class when quota enabling fails + - ext4: make sure quota gets properly shutdown on error + - ext4: set csum seed in tmp inode while migrating to extents + - ext4: Fix BUG_ON in ext4_bread when write quota data + - ext4: don't use the orphan list when migrating an inode + - drm/radeon: fix error handling in radeon_driver_open_kms + - of: base: Improve argument length mismatch error + - firmware: Update Kconfig help text for Google firmware + - media: rcar-csi2: Optimize the selection PHTW register + - Documentation: dmaengine: Correctly describe dmatest with channel unset + - Documentation: ACPI: Fix data node reference documentation + - Documentation: refer to config RANDOMIZE_BASE for kernel address-space + randomization + - Documentation: fix firewire.rst ABI file path error + - scsi: core: Show SCMD_LAST in text form + - RDMA/hns: Modify the mapping attribute of doorbell to device + - RDMA/rxe: Fix a typo in opcode name + - dmaengine: stm32-mdma: fix STM32_MDMA_CTBR_TSEL_MASK + - Revert "net/mlx5: Add retry mechanism to the command entry index allocation" + - powerpc/cell: Fix clang -Wimplicit-fallthrough warning + - powerpc/fsl/dts: Enable WA for erratum A-009885 on fman3l MDIO buses + - bpftool: Remove inclusion of utilities.mak from Makefiles + - ipv4: avoid quadratic behavior in netns dismantle + - net/fsl: xgmac_mdio: Fix incorrect iounmap when removing module + - parisc: pdc_stable: Fix memory leak in pdcs_register_pathentries + - f2fs: fix to reserve space for IO align feature + - af_unix: annote lockless accesses to unix_tot_inflight & gc_in_progress + - clk: si5341: Fix clock HW provider cleanup + - net: axienet: limit minimum TX ring size + - net: axienet: fix number of TX ring slots for available check + - net: axienet: increase default TX ring size to 128 + - rtc: pxa: fix null pointer dereference + - inet: frags: annotate races around fqdir->dead and fqdir->high_thresh + - netns: add schedule point in ops_exit_list() + - xfrm: Don't accidentally set RTO_ONLINK in decode_session4() + - gre: Don't accidentally set RTO_ONLINK in gre_fill_metadata_dst() + - libcxgb: Don't accidentally set RTO_ONLINK in cxgb_find_route() + - perf script: Fix hex dump character output + - dmaengine: at_xdmac: Don't start transactions at tx_submit level + - dmaengine: at_xdmac: Print debug message after realeasing the lock + - dmaengine: at_xdmac: Fix concurrency over xfers_list + - dmaengine: at_xdmac: Fix lld view setting + - dmaengine: at_xdmac: Fix at_xdmac_lld struct definition + - arm64: dts: qcom: msm8996: drop not documented adreno properties + - net_sched: restore "mpu xxx" handling + - bcmgenet: add WOL IRQ check + - net: ethernet: mtk_eth_soc: fix error checking in mtk_mac_config() + - dt-bindings: display: meson-dw-hdmi: add missing sound-name-prefix property + - dt-bindings: display: meson-vpu: Add missing amlogic,canvas property + - scripts/dtc: dtx_diff: remove broken example from help text + - lib82596: Fix IRQ check in sni_82596_probe + - lib/test_meminit: destroy cache in kmem_cache_alloc_bulk() test + - mtd: nand: bbt: Fix corner case in bad block table handling + - Revert "ia64: kprobes: Use generic kretprobe trampoline handler" + - Linux 5.4.174 + * Focal update: v5.4.173 upstream stable release (LP: #1959701) + - kbuild: Add $(KBUILD_HOSTLDFLAGS) to 'has_libelf' test + - devtmpfs regression fix: reconfigure on each mount + - orangefs: Fix the size of a memory allocation in orangefs_bufmap_alloc() + - perf: Protect perf_guest_cbs with RCU + - KVM: s390: Clarify SIGP orders versus STOP/RESTART + - media: uvcvideo: fix division by zero at stream start + - rtlwifi: rtl8192cu: Fix WARNING when calling local_irq_restore() with + interrupts enabled + - firmware: qemu_fw_cfg: fix sysfs information leak + - firmware: qemu_fw_cfg: fix NULL-pointer deref on duplicate entries + - firmware: qemu_fw_cfg: fix kobject leak in probe error path + - KVM: x86: remove PMU FIXED_CTR3 from msrs_to_save_all + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master after + reboot from Windows + - mtd: fixup CFI on ixp4xx + - ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD + - Linux 5.4.173 + * Focal update: v5.4.172 upstream stable release (LP: #1959698) + - workqueue: Fix unbind_workers() VS wq_worker_running() race + - Bluetooth: btusb: fix memory leak in btusb_mtk_submit_wmt_recv_urb() + - Bluetooth: bfusb: fix division by zero in send path + - USB: core: Fix bug in resuming hub's handling of wakeup requests + - USB: Fix "slab-out-of-bounds Write" bug in usb_hcd_poll_rh_status + - mmc: sdhci-pci: Add PCI ID for Intel ADL + - veth: Do not record rx queue hint in veth_xmit + - mfd: intel-lpss: Fix too early PM enablement in the ACPI ->probe() + - drivers core: Use sysfs_emit and sysfs_emit_at for show(device *...) + functions + - can: gs_usb: fix use of uninitialized variable, detach device on reception + of invalid USB data + - can: gs_usb: gs_can_start_xmit(): zero-initialize hf->{flags,reserved} + - random: fix data race on crng_node_pool + - random: fix data race on crng init time + - random: fix crash on multiple early calls to add_bootloader_randomness() + - media: Revert "media: uvcvideo: Set unique vdev name based in type" + - staging: wlan-ng: Avoid bitwise vs logical OR warning in + hfa384x_usb_throttlefn() + - drm/i915: Avoid bitwise vs logical OR warning in snb_wm_latency_quirk() + - staging: greybus: fix stack size warning with UBSAN + - Linux 5.4.172 + * Focal update: v5.4.171 upstream stable release (LP: #1959437) + - f2fs: quota: fix potential deadlock + - Input: touchscreen - Fix backport of + a02dcde595f7cbd240ccd64de96034ad91cffc40 + - selftests: x86: fix [-Wstringop-overread] warn in test_process_vm_readv() + - tracing: Fix check for trace_percpu_buffer validity in get_trace_buf() + - tracing: Tag trace_percpu_buffer as a percpu pointer + - ieee802154: atusb: fix uninit value in atusb_set_extended_addr + - iavf: Fix limit of total number of queues to active queues of VF + - RDMA/core: Don't infoleak GRH fields + - RDMA/uverbs: Check for null return of kmalloc_array + - mac80211: initialize variable have_higher_than_11mbit + - i40e: fix use-after-free in i40e_sync_filters_subtask() + - i40e: Fix for displaying message regarding NVM version + - i40e: Fix incorrect netdev's real number of RX/TX queues + - ipv4: Check attribute length for RTA_GATEWAY in multipath route + - ipv4: Check attribute length for RTA_FLOW in multipath route + - ipv6: Check attribute length for RTA_GATEWAY in multipath route + - ipv6: Check attribute length for RTA_GATEWAY when deleting multipath route + - lwtunnel: Validate RTA_ENCAP_TYPE attribute length + - batman-adv: mcast: don't send link-local multicast to mcast routers + - sch_qfq: prevent shift-out-of-bounds in qfq_init_qdisc + - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8081 + - power: supply: core: Break capacity loop + - power: reset: ltc2952: Fix use of floating point literals + - rndis_host: support Hytera digital radios + - phonet: refcount leak in pep_sock_accep + - ipv6: Continue processing multipath route even if gateway attribute is + invalid + - ipv6: Do cleanup if attribute validation fails in multipath route + - usb: mtu3: fix interval value for intr and isoc + - scsi: libiscsi: Fix UAF in iscsi_conn_get_param()/iscsi_conn_teardown() + - ip6_vti: initialize __ip6_tnl_parm struct in vti6_siocdevprivate + - net: udp: fix alignment problem in udp4_seq_show() + - atlantic: Fix buff_ring OOB in aq_ring_rx_clean + - mISDN: change function names to avoid conflicts + - Linux 5.4.171 + * Focal update: v5.4.170 upstream stable release (LP: #1958898) + - tee: handle lookup of shm with reference count 0 + - Input: i8042 - add deferred probe support + - Input: i8042 - enable deferred probe quirk for ASUS UM325UA + - tomoyo: Check exceeded quota early in tomoyo_domain_quota_is_ok(). + - platform/x86: apple-gmux: use resource_size() with res + - memblock: fix memblock_phys_alloc() section mismatch error + - recordmcount.pl: fix typo in s390 mcount regex + - selinux: initialize proto variable in selinux_ip_postroute_compat() + - scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write() + - net/mlx5: DR, Fix NULL vs IS_ERR checking in dr_domain_init_resources + - sctp: use call_rcu to free endpoint + - net: usb: pegasus: Do not drop long Ethernet frames + - net: lantiq_xrx200: fix statistics of received bytes + - NFC: st21nfca: Fix memory leak in device probe and remove + - ionic: Initialize the 'lif->dbid_inuse' bitmap + - net/mlx5e: Fix wrong features assignment in case of error + - selftests/net: udpgso_bench_tx: fix dst ip argument + - net/ncsi: check for error return from call to nla_put_u32 + - fsl/fman: Fix missing put_device() call in fman_port_probe + - i2c: validate user data in compat ioctl + - nfc: uapi: use kernel size_t to fix user-space builds + - uapi: fix linux/nfc.h userspace compilation errors + - xhci: Fresco FL1100 controller should not have BROKEN_MSI quirk set. + - usb: gadget: f_fs: Clear ffs_eventfd in ffs_data_clear. + - usb: mtu3: add memory barrier before set GPD's HWO + - usb: mtu3: fix list_head check warning + - usb: mtu3: set interval of FS intr and isoc endpoint + - binder: fix async_free_space accounting for empty parcels + - scsi: vmw_pvscsi: Set residual data length conditionally + - Input: appletouch - initialize work before device registration + - Input: spaceball - fix parsing of movement data packets + - net: fix use-after-free in tw_timer_handler + - perf script: Fix CPU filtering of a script's switch events + - Linux 5.4.170 + * Focal update: v5.4.170 upstream stable release (LP: #1958898) // HID_ASUS + should depend on USB_HID in stable v4.15 backports (LP: #1959762) + - HID: asus: Add depends on USB_HID to HID_ASUS Kconfig option + * Focal update: v5.4.169 upstream stable release (LP: #1958557) + - net: usb: lan78xx: add Allied Telesis AT29M2-AF + - serial: 8250_fintek: Fix garbled text for console + - arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode + - spi: change clk_disable_unprepare to clk_unprepare + - IB/qib: Fix memory leak in qib_user_sdma_queue_pkts() + - netfilter: fix regression in looped (broad|multi)cast's MAC handling + - qlcnic: potential dereference null pointer of rx_queue->page_ring + - net: accept UFOv6 packages in virtio_net_hdr_to_skb + - net: skip virtio_net_hdr_set_proto if protocol already set + - ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module + - bonding: fix ad_actor_system option setting to default + - fjes: Check for error irq + - drivers: net: smc911x: Check for error irq + - sfc: falcon: Check null pointer of rx_queue->page_ring + - Input: elantech - fix stack out of bound access in + elantech_change_report_id() + - hwmon: (lm90) Fix usage of CONFIG2 register in detect function + - hwmon: (lm90) Add max6654 support to lm90 driver + - hwmon: (lm90) Add basic support for TI TMP461 + - hwmon: (lm90) Introduce flag indicating extended temperature support + - hwmon: (lm90) Drop critical attribute support for MAX6654 + - ALSA: jack: Check the return value of kstrdup() + - ALSA: drivers: opl3: Fix incorrect use of vp->state + - ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6 + - Input: atmel_mxt_ts - fix double free in mxt_read_info_block + - ipmi: bail out if init_srcu_struct fails + - ipmi: ssif: initialize ssif_info->client early + - ipmi: fix initialization when workqueue allocation fails + - parisc: Correct completer in lws start + - x86/pkey: Fix undefined behaviour with PKRU_WD_BIT + - pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines + - mmc: sdhci-tegra: Fix switch to HS400ES mode + - mmc: core: Disable card detect during shutdown + - ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling + - tee: optee: Fix incorrect page free bug + - f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr() + - usb: gadget: u_ether: fix race in setting MAC address in setup phase + - KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state + - mm: mempolicy: fix THP allocations escaping mempolicy restrictions + - pinctrl: mediatek: fix global-out-of-bounds issue + - hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681 + - hwmon: (lm90) Do not report 'busy' status bit as alarm + - ax25: NPD bug when detaching AX25 device + - hamradio: defer ax25 kfree after unregister_netdev + - hamradio: improve the incomplete fix to avoid NPD + - phonet/pep: refuse to enable an unbound pipe + - Linux 5.4.169 + * Focal update: v5.4.168 upstream stable release (LP: #1957991) + - KVM: selftests: Make sure kvm_create_max_vcpus test won't hit RLIMIT_NOFILE + - mac80211: mark TX-during-stop for TX in in_reconfig + - mac80211: send ADDBA requests using the tid/queue of the aggregation session + - firmware: arm_scpi: Fix string overflow in SCPI genpd driver + - virtio_ring: Fix querying of maximum DMA mapping size for virtio device + - recordmcount.pl: look for jgnop instruction as well as bcrl on s390 + - dm btree remove: fix use after free in rebalance_children() + - audit: improve robustness of the audit queue handling + - iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda + - nfsd: fix use-after-free due to delegation race + - arm64: dts: rockchip: remove mmc-hs400-enhanced-strobe from rk3399-khadas- + edge + - arm64: dts: rockchip: fix rk3399-leez-p710 vcc3v3-lan supply + - arm64: dts: rockchip: fix audio-supply for Rock Pi 4 + - mac80211: track only QoS data frames for admission control + - ARM: socfpga: dts: fix qspi node compatible + - clk: Don't parent clks until the parent is fully registered + - selftests: net: Correct ping6 expected rc from 2 to 1 + - s390/kexec_file: fix error handling when applying relocations + - sch_cake: do not call cake_destroy() from cake_init() + - inet_diag: use jiffies_delta_to_msecs() + - inet_diag: fix kernel-infoleak for UDP sockets + - selftests: Fix raw socket bind tests with VRF + - selftests: Fix IPv6 address bind tests + - dmaengine: st_fdma: fix MODULE_ALIAS + - selftest/net/forwarding: declare NETIFS p9 p10 + - mac80211: agg-tx: refactor sending addba + - mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock + - mac80211: accept aggregation sessions on 6 GHz + - mac80211: fix lookup when adding AddBA extension element + - net: sched: lock action when translating it to flow_action infra + - flow_offload: return EOPNOTSUPP for the unsupported mpls action type + - rds: memory leak in __rds_conn_create() + - soc/tegra: fuse: Fix bitwise vs. logical OR warning + - igb: Fix removal of unicast MAC filters of VFs + - igbvf: fix double free in `igbvf_probe` + - ixgbe: set X550 MDIO speed before talking to PHY + - netdevsim: Zero-initialize memory for new map's value in function + nsim_bpf_map_alloc + - net: Fix double 0x prefix print in SKB dump + - net/smc: Prevent smc_release() from long blocking + - net: systemport: Add global locking for descriptor lifecycle + - sit: do not call ipip6_dev_free() from sit_init_net() + - USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04) + - PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error + - PCI/MSI: Mask MSI-X vectors only on success + - usb: xhci: Extend support for runtime power management for AMD's Yellow + carp. + - USB: serial: cp210x: fix CP2105 GPIO registration + - USB: serial: option: add Telit FN990 compositions + - timekeeping: Really make sure wall_to_monotonic isn't positive + - libata: if T_LENGTH is zero, dma direction should be DMA_NONE + - drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE + - mac80211: validate extended element ID is present + - mwifiex: Remove unnecessary braces from HostCmd_SET_SEQ_NO_BSS_INFO + - Input: touchscreen - avoid bitwise vs logical OR warning + - ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name + - xsk: Do not sleep in poll() when need_wakeup set + - media: mxl111sf: change mutex_init() location + - fuse: annotate lock in fuse_reverse_inval_entry() + - ovl: fix warning in ovl_create_real() + - scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select() + - rcu: Mark accesses to rcu_state.n_force_qs + - mac80211: fix regression in SSN handling of addba tx + - net: sched: Fix suspicious RCU usage while accessing tcf_tunnel_info + - Revert "xsk: Do not sleep in poll() when need_wakeup set" + - xen/blkfront: harden blkfront against event channel storms + - xen/netfront: harden netfront against event channel storms + - xen/console: harden hvc_xen against event channel storms + - xen/netback: fix rx queue stall detection + - xen/netback: don't queue unlimited number of packages + - Linux 5.4.168 + * Focal update: v5.4.167 upstream stable release (LP: #1957987) + - nfc: fix segfault in nfc_genl_dump_devices_done + - drm/msm/dsi: set default num_data_lanes + - net/mlx4_en: Update reported link modes for 1/10G + - parisc/agp: Annotate parisc agp init functions with __init + - i2c: rk3x: Handle a spurious start completion interrupt flag + - net: netlink: af_netlink: Prevent empty skb by adding a check on len. + - drm/amd/display: Fix for the no Audio bug with Tiled Displays + - drm/amd/display: add connector type check for CRC source set + - tracing: Fix a kmemleak false positive in tracing_map + - KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req + - selinux: fix race condition when computing ocontext SIDs + - bpf: Fix integer overflow in argument calculation for bpf_map_area_alloc + - hwmon: (dell-smm) Fix warning on /proc/i8k creation error + - memblock: free_unused_memmap: use pageblock units instead of MAX_ORDER + - memblock: align freed memory map on pageblock boundaries with SPARSEMEM + - memblock: ensure there is no overflow in memblock_overlaps_region() + - arm: extend pfn_valid to take into account freed memory map alignment + - arm: ioremap: don't abuse pfn_valid() to check if pfn is in RAM + - Linux 5.4.167 + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.4.0-104.118 ] + + * CVE-2022-23960 + - SAUCE: kvm: arm: fix build on 32-bit + + -- Tim Gardner Mon, 14 Mar 2022 07:15:47 -0600 + +linux-oracle (5.4.0-1066.71) focal; urgency=medium + + * CVE-2022-23960 + - [Config] bluefield: Set CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY + + * Disable unprivileged BPF by default (LP: #1961338) + - [Config] azure: Enable CONFIG_BPF_UNPRIV_DEFAULT_OFF + + [ Ubuntu: 5.4.0-103.117 ] + + * CVE-2022-23960 + - arm64: Add part number for Arm Cortex-A77 + - arm64: Add Neoverse-N2, Cortex-A710 CPU part definition + - arm64: Add Cortex-X2 CPU part definition + - arm64: add ID_AA64ISAR2_EL1 sys register + - SAUCE: arm64: entry.S: Add ventry overflow sanity checks + - SAUCE: arm64: entry: Make the trampoline cleanup optional + - SAUCE: arm64: entry: Free up another register on kpti's tramp_exit path + - SAUCE: arm64: entry: Move the trampoline data page before the text page + - SAUCE: arm64: entry: Allow tramp_alias to access symbols after the 4K + boundary + - SAUCE: arm64: entry: Don't assume tramp_vectors is the start of the vectors + - SAUCE: arm64: entry: Move trampoline macros out of ifdef'd section + - SAUCE: arm64: entry: Make the kpti trampoline's kpti sequence optional + - SAUCE: arm64: entry: Allow the trampoline text to occupy multiple pages + - SAUCE: arm64: entry: Add non-kpti __bp_harden_el1_vectors for mitigations + - SAUCE: arm64: entry: Add vectors that have the bhb mitigation sequences + - SAUCE: arm64: entry: Add macro for reading symbol addresses from the + trampoline + - SAUCE: arm64: Add percpu vectors for EL1 + - SAUCE: arm64: proton-pack: Report Spectre-BHB vulnerabilities as part of + Spectre-v2 + - SAUCE: KVM: arm64: Add templates for BHB mitigation sequences + - SAUCE: arm64: Mitigate spectre style branch history side channels + - SAUCE: KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and + migrated + - SAUCE: arm64: Use the clearbhb instruction in mitigations + - [Config]: set CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY=y + * CVE-2022-25636 + - netfilter: nf_tables_offload: incorrect flow offload action array size + * CVE-2022-0001 + - x86/speculation: Merge one test in spectre_v2_user_select_mitigation() + - x86,bugs: Unconditionally allow spectre_v2=retpoline,amd + - SAUCE: x86/speculation: Rename RETPOLINE_AMD to RETPOLINE_LFENCE + - SAUCE: x86/speculation: Add eIBRS + Retpoline options + - SAUCE: Documentation/hw-vuln: Update spectre doc + * Disable unprivileged BPF by default (LP: #1961338) + - bpf: Add kconfig knob for disabling unpriv bpf by default + - [Config] set CONFIG_BPF_UNPRIV_DEFAULT_OFF=y + + -- Thadeu Lima de Souza Cascardo Wed, 02 Mar 2022 08:49:20 -0300 + +linux-oracle (5.4.0-1064.68) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1064.68 -proposed tracker (LP: #1959267) + + [ Ubuntu: 5.4.0-100.113 ] + + * focal/linux: 5.4.0-100.113 -proposed tracker (LP: #1959900) + * CVE-2022-22942 + - SAUCE: drm/vmwgfx: Fix stale file descriptors on failed usercopy + * CVE-2022-0330 + - drm/i915: Flush TLBs before releasing backing store + * Focal update: v5.4.166 upstream stable release (LP: #1957008) + - netfilter: selftest: conntrack_vrf.sh: fix file permission + - Linux 5.4.166 + - net/packet: rx_owner_map depends on pg_vec + - USB: gadget: bRequestType is a bitfield, not a enum + - HID: holtek: fix mouse probing + - udp: using datalen to cap ipv6 udp max gso segments + - selftests: Calculate udpgso segment count without header adjustment + * Focal update: v5.4.165 upstream stable release (LP: #1957007) + - serial: tegra: Change lower tolerance baud rate limit for tegra20 and + tegra30 + - ntfs: fix ntfs_test_inode and ntfs_init_locked_inode function type + - HID: quirks: Add quirk for the Microsoft Surface 3 type-cover + - HID: google: add eel USB id + - HID: add hid_is_usb() function to make it simpler for USB detection + - HID: add USB_HID dependancy to hid-prodikeys + - HID: add USB_HID dependancy to hid-chicony + - HID: add USB_HID dependancy on some USB HID drivers + - HID: bigbenff: prevent null pointer dereference + - HID: wacom: fix problems when device is not a valid USB device + - HID: check for valid USB device for many HID drivers + - can: kvaser_usb: get CAN clock frequency from device + - can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct + stats->{rx,tx}_errors counter + - can: sja1000: fix use after free in ems_pcmcia_add_card() + - nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done + - selftests: netfilter: add a vrf+conntrack testcase + - vrf: don't run conntrack on vrf with !dflt qdisc + - bpf: Fix the off-by-two error in range markings + - ice: ignore dropped packets during init + - bonding: make tx_rebalance_counter an atomic + - nfp: Fix memory leak in nfp_cpp_area_cache_add() + - seg6: fix the iif in the IPv6 socket control block + - udp: using datalen to cap max gso segments + - iavf: restore MSI state on reset + - iavf: Fix reporting when setting descriptor count + - IB/hfi1: Correct guard on eager buffer deallocation + - mm: bdi: initialize bdi_min_ratio when bdi is unregistered + - ALSA: ctl: Fix copy of updated id with element read/write + - ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform + - ALSA: pcm: oss: Fix negative period/buffer sizes + - ALSA: pcm: oss: Limit the period size to 16MB + - ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*() + - btrfs: clear extent buffer uptodate when we fail to write it + - btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling + - nfsd: Fix nsfd startup race (again) + - tracefs: Have new files inherit the ownership of their parent + - clk: qcom: regmap-mux: fix parent clock lookup + - drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence. + - can: pch_can: pch_can_rx_normal: fix use after free + - can: m_can: Disable and ignore ELO interrupt + - x86/sme: Explicitly map new EFI memmap table as encrypted + - libata: add horkage for ASMedia 1092 + - wait: add wake_up_pollfree() + - SAUCE: binder: export __wake_up_pollfree for binder module + - binder: use wake_up_pollfree() + - signalfd: use wake_up_pollfree() + - aio: keep poll requests on waitqueue until completed + - aio: fix use-after-free due to missing POLLFREE handling + - tracefs: Set all files to the same group ownership as the mount option + - block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2) + - qede: validate non LSO skb length + - ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer + - i40e: Fix failed opcode appearing if handling messages from VF + - i40e: Fix pre-set max number of queues for VF + - mtd: rawnand: fsmc: Take instruction delay into account + - mtd: rawnand: fsmc: Fix timing computation + - dt-bindings: net: Reintroduce PHY no lane swap binding + - tools build: Remove needless libpython-version feature check that breaks + test-all fast path + - net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero + - net: altera: set a couple error code in probe() + - net: fec: only clear interrupt of handling queue in fec_enet_rx_queue() + - net, neigh: clear whole pneigh_entry at alloc time + - net/qla3xxx: fix an error code in ql_adapter_up() + - Revert "UBUNTU: SAUCE: selftests: fib_tests: assign address to dummy1 for + rp_filter tests" + - selftests/fib_tests: Rework fib_rp_filter_test() + - USB: gadget: detect too-big endpoint 0 requests + - USB: gadget: zero allocate endpoint 0 buffers + - usb: core: config: fix validation of wMaxPacketValue entries + - xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime + suspending + - usb: core: config: using bit mask instead of individual bits + - xhci: avoid race between disable slot command and host runtime suspend + - iio: trigger: Fix reference counting + - iio: trigger: stm32-timer: fix MODULE_ALIAS + - iio: stk3310: Don't return error code in interrupt handler + - iio: mma8452: Fix trigger reference couting + - iio: ltr501: Don't return error code in trigger handler + - iio: kxsd9: Don't return error code in trigger handler + - iio: itg3200: Call iio_trigger_notify_done() on error + - iio: dln2-adc: Fix lockdep complaint + - iio: dln2: Check return value of devm_iio_trigger_register() + - iio: at91-sama5d2: Fix incorrect sign extension + - iio: adc: axp20x_adc: fix charging current reporting on AXP22x + - iio: ad7768-1: Call iio_trigger_notify_done() on error + - iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove + - irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc() + - irqchip/armada-370-xp: Fix support for Multi-MSI interrupts + - irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL + - irqchip: nvic: Fix offset for Interrupt Priority Offsets + - misc: fastrpc: fix improper packet size calculation + - bpf: Add selftests to cover packet access corner cases + - Linux 5.4.165 + * Focal update: v5.4.164 upstream stable release (LP: #1956381) + - NFSv42: Fix pagecache invalidation after COPY/CLONE + - of: clk: Make self-contained + - arm64: dts: mcbin: support 2W SFP modules + - can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM + - gfs2: Fix length of holes reported at end-of-file + - drm/sun4i: fix unmet dependency on RESET_CONTROLLER for PHY_SUN6I_MIPI_DPHY + - mac80211: do not access the IV when it was stripped + - net/smc: Transfer remaining wait queue entries during fallback + - atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait + - net: return correct error code + - platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep + - s390/setup: avoid using memblock_enforce_memory_limit + - btrfs: check-integrity: fix a warning on write caching disabled disk + - thermal: core: Reset previous low and high trip during thermal zone init + - scsi: iscsi: Unblock session then wake up error handler + - ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile + - ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in + hns_dsaf_ge_srst_by_port() + - net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of + bound + - net: ethernet: dec: tulip: de4x5: fix possible array overflows in + type3_infoblock() + - perf hist: Fix memory leak of a perf_hpp_fmt + - perf report: Fix memory leaks around perf_tip() + - net/smc: Avoid warning of possible recursive locking + - vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit + - kprobes: Limit max data_size of the kretprobe instances + - rt2x00: do not mark device gone on EPROTO errors during start + - cpufreq: Fix get_cpu_device() failure in add_cpu_dev_symlink() + - s390/pci: move pseudo-MMIO to prevent MIO overlap + - sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl + - sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl + - i2c: stm32f7: flush TX FIFO upon transfer errors + - i2c: stm32f7: recover the bus on access timeout + - i2c: stm32f7: stop dma transfer in case of NACK + - i2c: cbus-gpio: set atomic transfer callback + - natsemi: xtensa: fix section mismatch warnings + - net: qlogic: qlcnic: Fix a NULL pointer dereference in + qlcnic_83xx_add_rings() + - net: mpls: Fix notifications when deleting a device + - siphash: use _unaligned version by default + - net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources() + - selftests: net: Correct case name + - rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer() + - net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ + is available + - net: marvell: mvpp2: Fix the computation of shared CPUs + - net: annotate data-races on txq->xmit_lock_owner + - ipv4: convert fib_num_tclassid_users to atomic_t + - net/rds: correct socket tunable error in rds_tcp_tune() + - net/smc: Keep smc_close_final rc during active close + - drm/msm: Do hw_init() before capturing GPU state + - ipv6: fix memory leak in fib6_rule_suppress + - KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register + - sched/uclamp: Fix rq->uclamp_max not set on first enqueue + - parisc: Fix KBUILD_IMAGE for self-extracting kernel + - parisc: Fix "make install" on newer debian releases + - vgacon: Propagate console boot parameters before calling `vc_resize' + - xhci: Fix commad ring abort, write all 64 bits to CRCR register. + - USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub + - usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect + - x86/tsc: Add a timer to make sure TSC_adjust is always checked + - x86/tsc: Disable clocksource watchdog for TSC on qualified platorms + - x86/64/mm: Map all kernel memory into trampoline_pgd + - tty: serial: msm_serial: Deactivate RX DMA for polling support + - serial: pl011: Add ACPI SBSA UART match id + - serial: core: fix transmit-buffer reset and memleak + - serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array + - serial: 8250_pci: rewrite pericom_do_set_divisor() + - iwlwifi: mvm: retry init flow if failed + - parisc: Mark cr16 CPU clocksource unstable on all SMP machines + - net/tls: Fix authentication failure in CCM mode + - Linux 5.4.164 + * Focal update: v5.4.163 upstream stable release (LP: #1956380) + - USB: serial: option: add Telit LE910S1 0x9200 composition + - USB: serial: option: add Fibocom FM101-GL variants + - usb: dwc2: gadget: Fix ISOC flow for elapsed frames + - usb: dwc2: hcd_queue: Fix use of floating point literal + - net: nexthop: fix null pointer dereference when IPv6 is not enabled + - usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts + - usb: hub: Fix usb enumeration issue due to address0 race + - usb: hub: Fix locking issues with address0_mutex + - binder: fix test regression due to sender_euid change + - ALSA: ctxfi: Fix out-of-range access + - media: cec: copy sequence field for the reply + - HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts + - staging/fbtft: Fix backlight + - staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect() + - xen: don't continue xenstore initialization in case of errors + - xen: detect uninitialized xenbus in xenbus_init + - KVM: PPC: Book3S HV: Prevent POWER7/8 TLB flush flushing SLB + - tracing/uprobe: Fix uprobe_perf_open probes iteration + - tracing: Fix pid filtering when triggers are attached + - mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB + - mdio: aspeed: Fix "Link is Down" issue + - PCI: aardvark: Deduplicate code in advk_pcie_rd_conf() + - PCI: aardvark: Wait for endpoint to be ready before training link + - PCI: aardvark: Fix big endian support + - PCI: aardvark: Train link immediately after enabling training + - PCI: aardvark: Improve link training + - PCI: aardvark: Issue PERST via GPIO + - PCI: aardvark: Replace custom macros by standard linux/pci_regs.h macros + - PCI: aardvark: Don't touch PCIe registers if no card connected + - PCI: aardvark: Fix compilation on s390 + - PCI: aardvark: Move PCIe reset card code to advk_pcie_train_link() + - PCI: aardvark: Update comment about disabling link training + - PCI: pci-bridge-emul: Fix array overruns, improve safety + - PCI: aardvark: Configure PCIe resources from 'ranges' DT property + - PCI: aardvark: Fix PCIe Max Payload Size setting + - PCI: aardvark: Implement re-issuing config requests on CRS response + - PCI: aardvark: Simplify initialization of rootcap on virtual bridge + - PCI: aardvark: Fix link training + - PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated + bridge + - PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge + - PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge + - pinctrl: armada-37xx: Correct PWM pins definitions + - arm64: dts: marvell: armada-37xx: Set pcie_reset_pin to gpio function + - proc/vmcore: fix clearing user buffer by properly using clear_user() + - netfilter: ipvs: Fix reuse connection if RS weight is 0 + - ARM: dts: BCM5301X: Fix I2C controller interrupt + - ARM: dts: BCM5301X: Add interrupt properties to GPIO node + - ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer + - ASoC: topology: Add missing rwsem around snd_ctl_remove() calls + - net: ieee802154: handle iftypes as u32 + - firmware: arm_scmi: pm: Propagate return value to caller + - NFSv42: Don't fail clone() unless the OP_CLONE operation failed + - ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE + - scsi: mpt3sas: Fix kernel panic during drive powercycle test + - drm/vc4: fix error code in vc4_create_object() + - iavf: Prevent changing static ITR values if adaptive moderation is on + - ipv6: fix typos in __ip6_finish_output() + - nfp: checking parameter process for rx-usecs/tx-usecs is invalid + - net: ipv6: add fib6_nh_release_dsts stub + - net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group + - scsi: core: sysfs: Fix setting device state to SDEV_RUNNING + - net/smc: Ensure the active closing peer first closes clcsock + - nvmet-tcp: fix incomplete data digest send + - net/ncsi : Add payload to be 32-bit aligned to fix dropped packets + - PM: hibernate: use correct mode for swsusp_close() + - tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited + flows + - nvmet: use IOCB_NOWAIT only if the filesystem supports it + - igb: fix netpoll exit with traffic + - MIPS: use 3-level pgtable for 64KB page size on MIPS_VA_BITS_48 + - net: vlan: fix underflow for the real_dev refcnt + - net/smc: Don't call clcsock shutdown twice when smc shutdown + - net: hns3: fix VF RSS failed problem after PF enable multi-TCs + - net: mscc: ocelot: don't downgrade timestamping RX filters in SIOCSHWTSTAMP + - net: mscc: ocelot: correctly report the timestamping RX filters in ethtool + - f2fs: set SBI_NEED_FSCK flag when inconsistent node block found + - smb3: do not error on fsync when readonly + - vhost/vsock: fix incorrect used length reported to the guest + - tracing: Check pid filtering when creating events + - s390/mm: validate VMA in PGSTE manipulation functions + - shm: extend forced shm destroy to support objects from several IPC nses + - NFC: add NCI_UNREG flag to eliminate the race + - fuse: release pipe buf after last use + - xen: sync include/xen/interface/io/ring.h with Xen's newest version + - xen/blkfront: read response from backend only once + - xen/blkfront: don't take local copy of a request from the ring page + - xen/blkfront: don't trust the backend response data blindly + - xen/netfront: read response from backend only once + - xen/netfront: don't read data from request on the ring page + - xen/netfront: disentangle tx_skb_freelist + - xen/netfront: don't trust the backend response data blindly + - tty: hvc: replace BUG_ON() with negative return value + - Linux 5.4.163 + * net/mlx5e: EPERM on vlan 0 programming (LP: #1957753) + - net/mlx5e: Unblock setting vid 0 for VF in case PF isn't eswitch manager + * CVE-2021-4083 + - fget: check that the fd still exists after getting a ref to it + * CVE-2021-4155 + - xfs: map unwritten blocks in XFS_IOC_{ALLOC, FREE}SP just like fallocate + + -- Tim Gardner Wed, 09 Feb 2022 05:36:10 -0700 + +linux-oracle (5.4.0-1063.67) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1063.67 -proposed tracker (LP: #1959807) + + [ Ubuntu: 5.4.0-99.112 ] + + * focal/linux: 5.4.0-99.112 -proposed tracker (LP: #1959817) + * linux-image-5.4.0-97.110 freezes by accessing cifs shares (LP: #1959665) + - Revert "cifs: To match file servers, make sure the server hostname matches" + - Revert "cifs: set a minimum of 120s for next dns resolution" + - Revert "cifs: use the expiry output of dns_query to schedule next + resolution" + + -- Tim Gardner Thu, 03 Feb 2022 07:51:50 -0700 + +linux-oracle (5.4.0-1062.66) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1062.66 -proposed tracker (LP: #1955235) + + [ Ubuntu: 5.4.0-97.110 ] + + * icmp_redirect from selftests fails on F/kvm (unary operator expected) + (LP: #1938964) + - selftests: icmp_redirect: pass xfail=0 to log_test() + * Focal: CIFS stable updates (LP: #1954926) + - cifs: use the expiry output of dns_query to schedule next resolution + - cifs: set a minimum of 120s for next dns resolution + - cifs: To match file servers, make sure the server hostname matches + * seccomp_bpf in seccomp from ubuntu_kernel_selftests failed to build on B-5.4 + (LP: #1896420) + - SAUCE: selftests/seccomp: fix "storage size of 'md' isn't known" build issue + - SAUCE: selftests/seccomp: Fix s390x regs not defined issue + * system crash when removing ipmi_msghandler module (LP: #1950666) + - ipmi: Move remove_work to dedicated workqueue + - ipmi: msghandler: Make symbol 'remove_work_wq' static + * zcrypt DD: Toleration for new IBM Z Crypto Hardware - (Backport to Ubuntu + 20.04) (LP: #1954680) + - s390/AP: support new dynamic AP bus size limit + * [UBUNTU 20.04] KVM hardware diagnose data improvements for guest kernel - + kernel part (LP: #1953334) + - s390/setup: diag 318: refactor struct + - s390/kvm: diagnose 0x318 sync and reset + - KVM: s390: remove diag318 reset code + - KVM: s390: add debug statement for diag 318 CPNC data + * Updates to ib_peer_memory requested by Nvidia (LP: #1947206) + - SAUCE: RDMA/core: Updated ib_peer_memory + * Include Infiniband Peer Memory interface (LP: #1923104) + - IB: Allow calls to ib_umem_get from kernel ULPs + - SAUCE: RDMA/core: Introduce peer memory interface + * Focal update: v5.4.162 upstream stable release (LP: #1954834) + - arm64: zynqmp: Do not duplicate flash partition label property + - arm64: zynqmp: Fix serial compatible string + - ARM: dts: NSP: Fix mpcore, mmc node names + - scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq() + - arm64: dts: hisilicon: fix arm,sp805 compatible string + - RDMA/bnxt_re: Check if the vlan is valid before reporting + - usb: musb: tusb6010: check return value after calling + platform_get_resource() + - usb: typec: tipd: Remove WARN_ON in tps6598x_block_read + - arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency + - arm64: dts: freescale: fix arm,sp805 compatible string + - ASoC: SOF: Intel: hda-dai: fix potential locking issue + - clk: imx: imx6ul: Move csi_sel mux to correct base register + - ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect + - scsi: advansys: Fix kernel pointer leak + - firmware_loader: fix pre-allocated buf built-in firmware use + - ARM: dts: omap: fix gpmc,mux-add-data type + - usb: host: ohci-tmio: check return value after calling + platform_get_resource() + - ARM: dts: ls1021a: move thermal-zones node out of soc/ + - ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash + - ALSA: ISA: not for M68K + - tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc + - MIPS: sni: Fix the build + - scsi: target: Fix ordered tag handling + - scsi: target: Fix alua_tg_pt_gps_count tracking + - iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr() + - powerpc/5200: dts: fix memory node unit name + - ALSA: gus: fix null pointer dereference on pointer block + - powerpc/dcr: Use cmplwi instead of 3-argument cmpli + - sh: check return code of request_irq + - maple: fix wrong return value of maple_bus_init(). + - f2fs: fix up f2fs_lookup tracepoints + - sh: fix kconfig unmet dependency warning for FRAME_POINTER + - sh: math-emu: drop unused functions + - sh: define __BIG_ENDIAN for math-emu + - clk: ingenic: Fix bugs with divided dividers + - clk/ast2600: Fix soc revision for AHB + - clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk + - mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set + - sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain() + - tracing: Save normal string variables + - tracing/histogram: Do not copy the fixed-size char array field over the + field size + - RDMA/netlink: Add __maybe_unused to static inline in C file + - perf bpf: Avoid memory leak from perf_env__insert_btf() + - perf bench futex: Fix memory leak of perf_cpu_map__new() + - perf tests: Remove bash construct from record+zstd_comp_decomp.sh + - net: bnx2x: fix variable dereferenced before check + - iavf: check for null in iavf_fix_features + - iavf: free q_vectors before queues in iavf_disable_vf + - iavf: Fix failure to exit out from last all-multicast mode + - iavf: prevent accidental free of filter structure + - iavf: validate pointers + - iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset + - MIPS: generic/yamon-dt: fix uninitialized variable error + - mips: bcm63xx: add support for clk_get_parent() + - mips: lantiq: add support for clk_get_parent() + - platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()' + - scsi: core: sysfs: Fix hang when device state is set via sysfs + - net: sched: act_mirred: drop dst for the direction from egress to ingress + - net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove + - net: virtio_net_hdr_to_skb: count transport header in UFO + - i40e: Fix correct max_pkt_size on VF RX queue + - i40e: Fix NULL ptr dereference on VSI filter sync + - i40e: Fix changing previously set num_queue_pairs for PFs + - i40e: Fix ping is lost after configuring ADq on VF + - i40e: Fix creation of first queue by omitting it if is not power of two + - i40e: Fix display error code in dmesg + - NFC: reorganize the functions in nci_request + - drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame + - NFC: reorder the logic in nfc_{un,}register_device + - KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr() + - perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server + - perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server + - s390/kexec: fix return code handling + - arm64: vdso32: suppress error message for 'make mrproper' + - tun: fix bonding active backup with arp monitoring + - hexagon: export raw I/O routines for modules + - ipc: WARN if trying to remove ipc object which is absent + - mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag + - x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails + - s390/kexec: fix memory leak of ipl report buffer + - udf: Fix crash after seekdir + - btrfs: fix memory ordering between normal and ordered work functions + - parisc/sticon: fix reverse colors + - cfg80211: call cfg80211_stop_ap when switch from P2P_GO type + - drm/udl: fix control-message timeout + - drm/nouveau: use drm_dev_unplug() during device removal + - drm/i915/dp: Ensure sink rate values are always valid + - drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga + and dvi connectors + - Revert "net: mvpp2: disable force link UP during port init procedure" + - perf/core: Avoid put_page() when GUP fails + - batman-adv: Consider fragmentation for needed_headroom + - batman-adv: Reserve needed_*room for fragments + - batman-adv: Don't always reallocate the fragmentation skb head + - ASoC: DAPM: Cover regression by kctl change notification fix + - usb: max-3421: Use driver data instead of maintaining a list of bound + devices + - ice: Delete always true check of PF pointer + - ALSA: hda: hdac_ext_stream: fix potential locking issues + - ALSA: hda: hdac_stream: fix potential locking issue in + snd_hdac_stream_assign() + - Linux 5.4.162 + * Focal update: v5.4.161 upstream stable release (LP: #1954828) + - scsi: ufs: Fix interrupt error message for shared interrupts + - MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL + - ext4: fix lazy initialization next schedule time computation in more + granular unit + - scsi: ufs: Fix tm request when non-fatal error happens + - fortify: Explicitly disable Clang support + - parisc/entry: fix trace test in syscall exit path + - PCI/MSI: Destroy sysfs before freeing entries + - PCI/MSI: Deal with devices lying about their MSI mask capability + - PCI: Add MSI masking quirk for Nvidia ION AHCI + - erofs: remove the occupied parameter from z_erofs_pagevec_enqueue() + - erofs: fix unsafe pagevec reuse of hooked pclusters + - Linux 5.4.161 + * Focal update: v5.4.160 upstream stable release (LP: #1953387) + - xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good + delay + - usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform + - binder: use euid from cred instead of using task + - binder: use cred instead of task for selinux checks + - binder: use cred instead of task for getsecid + - Input: iforce - fix control-message timeout + - Input: elantench - fix misreporting trackpoint coordinates + - Input: i8042 - Add quirk for Fujitsu Lifebook T725 + - libata: fix read log timeout value + - ocfs2: fix data corruption on truncate + - scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file + - scsi: qla2xxx: Fix use after free in eh_abort path + - mmc: dw_mmc: Dont wait for DRTO on Write RSP error + - parisc: Fix ptrace check on syscall return + - tpm: Check for integer overflow in tpm2_map_response_body() + - firmware/psci: fix application of sizeof to pointer + - crypto: s5p-sss - Add error handling in s5p_aes_probe() + - media: ite-cir: IR receiver stop working after receive overflow + - media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers + - media: v4l2-ioctl: Fix check_ext_ctrls + - ALSA: hda/realtek: Add quirk for Clevo PC70HS + - ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N + - ALSA: hda/realtek: Add quirk for ASUS UX550VE + - ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED + - ALSA: ua101: fix division by zero at probe + - ALSA: 6fire: fix control and bulk message timeouts + - ALSA: line6: fix control and interrupt message timeouts + - ALSA: usb-audio: Add registration quirk for JBL Quantum 400 + - ALSA: synth: missing check for possible NULL after the call to kstrdup + - ALSA: timer: Fix use-after-free problem + - ALSA: timer: Unconditionally unlink slave instances, too + - fuse: fix page stealing + - x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c + - x86/cpu: Fix migration safety with X86_BUG_NULL_SEL + - x86/irq: Ensure PI wakeup handler is unregistered before module unload + - cavium: Return negative value when pci_alloc_irq_vectors() fails + - scsi: qla2xxx: Return -ENOMEM if kzalloc() fails + - scsi: qla2xxx: Fix unmap of already freed sgl + - cavium: Fix return values of the probe function + - sfc: Don't use netif_info before net_device setup + - hyperv/vmbus: include linux/bitops.h + - ARM: dts: sun7i: A20-olinuxino-lime2: Fix ethernet phy-mode + - reset: socfpga: add empty driver allowing consumers to probe + - mmc: winbond: don't build on M68K + - drm: panel-orientation-quirks: Add quirk for Aya Neo 2021 + - bpf: Define bpf_jit_alloc_exec_limit for arm64 JIT + - bpf: Prevent increasing bpf_jit_limit above max + - xen/netfront: stop tx queues during live migration + - nvmet-tcp: fix a memory leak when releasing a queue + - spi: spl022: fix Microwire full duplex mode + - net: multicast: calculate csum of looped-back and forwarded packets + - watchdog: Fix OMAP watchdog early handling + - drm: panel-orientation-quirks: Add quirk for GPD Win3 + - nvmet-tcp: fix header digest verification + - r8169: Add device 10ec:8162 to driver r8169 + - vmxnet3: do not stop tx queues after netif_device_detach() + - nfp: bpf: relax prog rejection for mtu check through max_pkt_offset + - net/smc: Correct spelling mistake to TCPF_SYN_RECV + - btrfs: clear MISSING device status bit in btrfs_close_one_device + - btrfs: fix lost error handling when replaying directory deletes + - btrfs: call btrfs_check_rw_degradable only if there is a missing device + - ia64: kprobes: Fix to pass correct trampoline address to the handler + - hwmon: (pmbus/lm25066) Add offset coefficients + - regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is + disabled + - regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default- + dvs-idx property + - EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell + - mwifiex: fix division by zero in fw download path + - ath6kl: fix division by zero in send path + - ath6kl: fix control-message timeout + - ath10k: fix control-message timeout + - ath10k: fix division by zero in send path + - PCI: Mark Atheros QCA6174 to avoid bus reset + - rtl8187: fix control-message timeouts + - evm: mark evm_fixmode as __ro_after_init + - wcn36xx: Fix HT40 capability for 2Ghz band + - mwifiex: Read a PCI register after writing the TX ring write pointer + - libata: fix checking of DMA state + - wcn36xx: handle connection loss indication + - rsi: fix occasional initialisation failure with BT coex + - rsi: fix key enabled check causing unwanted encryption for vap_id > 0 + - rsi: fix rate mask set leading to P2P failure + - rsi: Fix module dev_oper_mode parameter description + - RDMA/qedr: Fix NULL deref for query_qp on the GSI QP + - signal: Remove the bogus sigkill_pending in ptrace_stop + - signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT + - power: supply: max17042_battery: Prevent int underflow in set_soc_threshold + - power: supply: max17042_battery: use VFSOC for capacity when no rsns + - KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use + - can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport + - can: j1939: j1939_can_recv(): ignore messages with invalid source address + - powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found + - serial: core: Fix initializing and restoring termios speed + - ALSA: mixer: oss: Fix racy access to slots + - ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume + - xen/balloon: add late_initcall_sync() for initial ballooning done + - PCI: pci-bridge-emul: Fix emulation of W1C bits + - PCI: aardvark: Do not clear status bits of masked interrupts + - PCI: aardvark: Fix checking for link up via LTSSM state + - PCI: aardvark: Do not unmask unused interrupts + - PCI: aardvark: Fix reporting Data Link Layer Link Active + - PCI: aardvark: Fix return value of MSI domain .alloc() method + - PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG + - quota: check block number when reading the block in quota file + - quota: correct error number in free_dqentry() + - pinctrl: core: fix possible memory leak in pinctrl_enable() + - iio: dac: ad5446: Fix ad5622_write() return value + - USB: serial: keyspan: fix memleak on probe errors + - USB: iowarrior: fix control-message timeouts + - USB: chipidea: fix interrupt deadlock + - dma-buf: WARN on dmabuf release with pending attachments + - drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2) + - drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1 + - drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6 + - Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg() + - Bluetooth: fix use-after-free error in lock_sock_nested() + - drm/panel-orientation-quirks: add Valve Steam Deck + - platform/x86: wmi: do not fail if disabling fails + - MIPS: lantiq: dma: add small delay after reset + - MIPS: lantiq: dma: reset correct number of channel + - locking/lockdep: Avoid RCU-induced noinstr fail + - net: sched: update default qdisc visibility after Tx queue cnt changes + - smackfs: Fix use-after-free in netlbl_catmap_walk() + - x86: Increase exception stack sizes + - mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type + - mwifiex: Properly initialize private structure on interface type changes + - ath10k: high latency fixes for beacon buffer + - media: mt9p031: Fix corrupted frame after restarting stream + - media: netup_unidvb: handle interrupt properly according to the firmware + - media: stm32: Potential NULL pointer dereference in dcmi_irq_thread() + - media: uvcvideo: Set capability in s_param + - media: uvcvideo: Return -EIO for control errors + - media: uvcvideo: Set unique vdev name based in type + - media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe() + - media: s5p-mfc: Add checking to s5p_mfc_probe(). + - media: imx: set a media_device bus_info string + - media: mceusb: return without resubmitting URB in case of -EPROTO error. + - ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK + - brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet + - media: rcar-csi2: Add checking to rcsi2_start_receiver() + - ipmi: Disable some operations during a panic + - ACPICA: Avoid evaluating methods too early during system resume + - media: ipu3-imgu: imgu_fmt: Handle properly try + - media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info + - media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte() + - net-sysfs: try not to restart the syscall if it will fail eventually + - tracefs: Have tracefs directories not set OTH permission bits by default + - ath: dfs_pattern_detector: Fix possible null-pointer dereference in + channel_detector_create() + - iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value + - ACPI: battery: Accept charges over the design capacity as full + - leaking_addresses: Always print a trailing newline + - memstick: r592: Fix a UAF bug when removing the driver + - lib/xz: Avoid overlapping memcpy() with invalid input with in-place + decompression + - lib/xz: Validate the value before assigning it to an enum variable + - workqueue: make sysfs of unbound kworker cpumask more clever + - tracing/cfi: Fix cmp_entries_* functions signature mismatch + - mwl8k: Fix use-after-free in mwl8k_fw_state_machine() + - block: remove inaccurate requeue check + - nvmet: fix use-after-free when a port is removed + - nvmet-tcp: fix use-after-free when a port is removed + - nvme: drop scan_lock and always kick requeue list when removing namespaces + - PM: hibernate: Get block device exclusively in swsusp_check() + - selftests: kvm: fix mismatched fclose() after popen() + - iwlwifi: mvm: disable RX-diversity in powersave + - smackfs: use __GFP_NOFAIL for smk_cipso_doi() + - ARM: clang: Do not rely on lr register for stacktrace + - gre/sit: Don't generate link-local addr if addr_gen_mode is + IN6_ADDR_GEN_MODE_NONE + - ARM: 9136/1: ARMv7-M uses BE-8, not BE-32 + - vrf: run conntrack only in context of lower/physdev for locally generated + packets + - net: annotate data-race in neigh_output() + - btrfs: do not take the uuid_mutex in btrfs_rm_device + - spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in + bcm_qspi_probe() + - x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted + - parisc: fix warning in flush_tlb_all + - task_stack: Fix end_of_stack() for architectures with upwards-growing stack + - parisc/unwind: fix unwinder when CONFIG_64BIT is enabled + - parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling + - netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream + state + - selftests/bpf: Fix strobemeta selftest regression + - Bluetooth: fix init and cleanup of sco_conn.timeout_work + - rcu: Fix existing exp request check in sync_sched_exp_online_cleanup() + - drm/v3d: fix wait for TMU write combiner flush + - virtio-gpu: fix possible memory allocation failure + - net: net_namespace: Fix undefined member in key_remove_domain() + - cgroup: Make rebind_subsystems() disable v2 controllers all at once + - wilc1000: fix possible memory leak in cfg_scan_result() + - Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync + - crypto: caam - disable pkc for non-E SoCs + - rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies() + - net: dsa: rtl8366rb: Fix off-by-one bug + - ath10k: Fix missing frame timestamp for beacon/probe-resp + - drm/amdgpu: fix warning for overflow check + - media: em28xx: add missing em28xx_close_extension + - media: cxd2880-spi: Fix a null pointer dereference on error handling path + - media: dvb-usb: fix ununit-value in az6027_rc_query + - media: TDA1997x: handle short reads of hdmi info frame. + - media: mtk-vpu: Fix a resource leak in the error handling path of + 'mtk_vpu_probe()' + - media: radio-wl1273: Avoid card name truncation + - media: si470x: Avoid card name truncation + - media: tm6000: Avoid card name truncation + - media: cx23885: Fix snd_card_free call on null card pointer + - kprobes: Do not use local variable when creating debugfs file + - crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency + - cpuidle: Fix kobject memory leaks in error paths + - media: em28xx: Don't use ops->suspend if it is NULL + - ath9k: Fix potential interrupt storm on queue reset + - EDAC/amd64: Handle three rank interleaving mode + - netfilter: nft_dynset: relax superfluous check on set updates + - media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable() + - crypto: qat - detect PFVF collision after ACK + - crypto: qat - disregard spurious PFVF interrupts + - hwrng: mtk - Force runtime pm ops for sleep ops + - b43legacy: fix a lower bounds test + - b43: fix a lower bounds test + - mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured + - memstick: avoid out-of-range warning + - memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host() + - net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE + - hwmon: Fix possible memleak in __hwmon_device_register() + - hwmon: (pmbus/lm25066) Let compiler determine outer dimension of + lm25066_coeff + - ath10k: fix max antenna gain unit + - drm/msm: uninitialized variable in msm_gem_import() + - net: stream: don't purge sk_error_queue in sk_stream_kill_queues() + - mmc: mxs-mmc: disable regulator on error and in the remove function + - block: ataflop: fix breakage introduced at blk-mq refactoring + - platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning + - mt76: mt76x02: fix endianness warnings in mt76x02_mac.c + - rsi: stop thread firstly in rsi_91x_init() error handling + - mwifiex: Send DELBA requests according to spec + - phy: micrel: ksz8041nl: do not use power down mode + - nvme-rdma: fix error code in nvme_rdma_setup_ctrl + - PM: hibernate: fix sparse warnings + - clocksource/drivers/timer-ti-dm: Select TIMER_OF + - drm/msm: Fix potential NULL dereference in DPU SSPP + - smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi + - libbpf: Fix BTF data layout checks and allow empty BTF + - s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap() + - irq: mips: avoid nested irq_enter() + - tcp: don't free a FIN sk_buff in tcp_remove_empty_skb() + - samples/kretprobes: Fix return value if register_kretprobe() failed + - KVM: s390: Fix handle_sske page fault handling + - libertas_tf: Fix possible memory leak in probe and disconnect + - libertas: Fix possible memory leak in probe and disconnect + - wcn36xx: add proper DMA memory barriers in rx path + - drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits + - net: amd-xgbe: Toggle PLL settings during rate change + - net: phylink: avoid mvneta warning when setting pause parameters + - crypto: pcrypt - Delay write to padata->info + - selftests/bpf: Fix fclose/pclose mismatch in test_progs + - udp6: allow SO_MARK ctrl msg to affect routing + - ibmvnic: don't stop queue in xmit + - ibmvnic: Process crqs after enabling interrupts + - RDMA/rxe: Fix wrong port_cap_flags + - clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths + - ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc() + - arm64: dts: rockchip: Fix GPU register width for RK3328 + - ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY + - RDMA/bnxt_re: Fix query SRQ failure + - arm64: dts: meson-g12a: Fix the pwm regulator supply properties + - ARM: dts: at91: tse850: the emac<->phy interface is rmii + - scsi: dc395: Fix error case unwinding + - MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT + - JFS: fix memleak in jfs_mount + - ALSA: hda: Reduce udelay() at SKL+ position reporting + - arm: dts: omap3-gta04a4: accelerometer irq fix + - soc/tegra: Fix an error handling path in tegra_powergate_power_up() + - memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe + - clk: at91: check pmc node status before registering syscore ops + - video: fbdev: chipsfb: use memset_io() instead of memset() + - serial: 8250_dw: Drop wrong use of ACPI_PTR() + - usb: gadget: hid: fix error code in do_config() + - power: supply: rt5033_battery: Change voltage values to µV + - scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn() + - RDMA/mlx4: Return missed an error if device doesn't support steering + - staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC + - ARM: dts: stm32: fix SAI sub nodes register range + - ASoC: cs42l42: Correct some register default values + - ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER + - phy: qcom-qusb2: Fix a memory leak on probe + - serial: xilinx_uartps: Fix race condition causing stuck TX + - HID: u2fzero: clarify error check and length calculations + - HID: u2fzero: properly handle timeouts in usb_submit_urb + - powerpc/44x/fsp2: add missing of_node_put + - mips: cm: Convert to bitfield API to fix out-of-bounds access + - power: supply: bq27xxx: Fix kernel crash on IRQ handler register error + - apparmor: fix error check + - rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined + - pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds + - drm/plane-helper: fix uninitialized variable reference + - PCI: aardvark: Don't spam about PIO Response Status + - PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge + - opp: Fix return in _opp_add_static_v2() + - NFS: Fix deadlocks in nfs_scan_commit_list() + - fs: orangefs: fix error return code of orangefs_revalidate_lookup() + - mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare() + - mtd: core: don't remove debugfs directory if device is in use + - dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro + - auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string + - auxdisplay: ht16k33: Connect backlight to fbdev + - auxdisplay: ht16k33: Fix frame buffer device blanking + - soc: fsl: dpaa2-console: free buffer before returning from + dpaa2_console_read + - netfilter: nfnetlink_queue: fix OOB when mac header was cleared + - dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result` + - signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL) + - m68k: set a default value for MEMORY_RESERVE + - watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT + - ar7: fix kernel builds for compiler test + - scsi: qla2xxx: Fix gnl list corruption + - scsi: qla2xxx: Turn off target reset during issue_lip + - NFSv4: Fix a regression in nfs_set_open_stateid_locked() + - i2c: xlr: Fix a resource leak in the error handling path of + 'xlr_i2c_probe()' + - xen-pciback: Fix return in pm_ctrl_init() + - net: davinci_emac: Fix interrupt pacing disable + - net: vlan: fix a UAF in vlan_dev_real_dev() + - ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses + - bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed + - mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and + zs_unregister_migration() + - zram: off by one in read_block_state() + - perf bpf: Add missing free to bpf_event__print_bpf_prog_info() + - llc: fix out-of-bound array index in llc_sk_dev_hash() + - nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails + - arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions + - bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding + - net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any + - net: hns3: allow configure ETS bandwidth of all TCs + - vsock: prevent unnecessary refcnt inc for nonblocking connect + - net/smc: fix sk_refcnt underflow on linkdown and fallback + - cxgb4: fix eeprom len when diagnostics not implemented + - selftests/net: udpgso_bench_rx: fix port argument + - ARM: 9155/1: fix early early_iounmap() + - ARM: 9156/1: drop cc-option fallbacks for architecture selection + - parisc: Fix set_fixmap() on PA1.x CPUs + - irqchip/sifive-plic: Fixup EOI failed when masked + - f2fs: should use GFP_NOFS for directory inodes + - net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE + - 9p/net: fix missing error check in p9_check_errors + - ovl: fix deadlock in splice write + - powerpc/lib: Add helper to check if offset is within conditional branch + range + - powerpc/bpf: Validate branch ranges + - powerpc/bpf: Fix BPF_SUB when imm == 0x80000000 + - powerpc/security: Add a helper to query stf_barrier type + - powerpc/bpf: Emit stf barrier instruction sequences for BPF_NOSPEC + - mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks + - mm, oom: do not trigger out_of_memory from the #PF + - video: backlight: Drop maximum brightness override for brightness zero + - s390/cio: check the subchannel validity for dev_busid + - s390/tape: fix timer initialization in tape_std_assign() + - s390/cio: make ccw_device_dma_* more robust + - powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload + - PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros + - SUNRPC: Partial revert of commit 6f9f17287e78 + - ath10k: fix invalid dma_addr_t token assignment + - selftests/bpf: Fix also no-alu32 strobemeta selftest + - Linux 5.4.160 + - soc/tegra: pmc: Fix imbalanced clock disabling in error code path + * Focal update: v5.4.159 upstream stable release (LP: #1953071) + - Revert "x86/kvm: fix vcpu-id indexed array sizes" + - usb: ehci: handshake CMD_RUN instead of STS_HALT + - usb: gadget: Mark USB_FSL_QE broken on 64-bit + - usb: musb: Balance list entry in musb_gadget_queue + - usb-storage: Add compatibility quirk flags for iODD 2531/2541 + - binder: don't detect sender/target during buffer cleanup + - printk/console: Allow to disable console output by using console="" or + console=null + - isofs: Fix out of bound access for corrupted isofs image + - comedi: dt9812: fix DMA buffers on stack + - comedi: ni_usb6501: fix NULL-deref in command paths + - comedi: vmk80xx: fix transfer-buffer overflows + - comedi: vmk80xx: fix bulk-buffer overflow + - comedi: vmk80xx: fix bulk and interrupt message timeouts + - staging: r8712u: fix control-message timeout + - staging: rtl8192u: fix control-message timeouts + - media: staging/intel-ipu3: css: Fix wrong size comparison imgu_css_fw_init + - rsi: fix control-message timeout + - Linux 5.4.159 + * Focal update: v5.4.158 upstream stable release (LP: #1953066) + - scsi: core: Put LLD module refcnt after SCSI device is released + - vrf: Revert "Reset skb conntrack connection..." + - net: ethernet: microchip: lan743x: Fix skb allocation failure + - media: firewire: firedtv-avc: fix a buffer overflow in avc_ca_pmt() + - Revert "xhci: Set HCD flag to defer primary roothub registration" + - Revert "usb: core: hcd: Add support for deferring roothub registration" + - sfc: Fix reading non-legacy supported link modes + - ARM: 9120/1: Revert "amba: make use of -1 IRQs warn" + - Linux 5.4.158 + * [Ubuntu 20.04] Problem leading IUCV service down (on s390x) (LP: #1913442) + - usercopy: mark dma-kmalloc caches as usercopy caches + + -- Tim Gardner Wed, 19 Jan 2022 05:59:07 -0700 + +linux-oracle (5.4.0-1061.65) focal; urgency=medium + + [ Ubuntu: 5.4.0-96.109 ] + + * Support builtin revoked certificates (LP: #1932029) + - [Config]: add i386 to CONFIG_SYSTEM_REVOCATION_KEYS annotation + * CVE-2022-0185 + - SAUCE: vfs: Out-of-bounds write of heap buffer in fs_context.c + - SAUCE: vfs: test that one given mount param is not larger than PAGE_SIZE + + [ Ubuntu: 5.4.0-94.106 ] + + * focal/linux: 5.4.0-94.106 -proposed tracker (LP: #1956628) + * [Regression] Focal kernel 5.4.0-92.103 fails to boot when Secure Encrypted + Virtualization(SEV) is enabled (LP: #1956575) + - x86/ioremap: Map EFI-reserved memory as encrypted for SEV + + -- Stefan Bader Thu, 13 Jan 2022 15:25:18 +0100 + +linux-oracle (5.4.0-1059.63) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1059.63 -proposed tracker (LP: #1952306) + + * Re-enable DEBUG_INFO_BTF where it was disabled (LP: #1945632) + - [Config] oracle: Enable CONFIG_DEBUG_INFO_BTF on all arches + + * Support builtin revoked certificates (LP: #1932029) + - [Config] oracle: Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys + + [ Ubuntu: 5.4.0-92.103 ] + + * focal/linux: 5.4.0-92.103 -proposed tracker (LP: #1952316) + * Packaging resync (LP: #1786013) + - [Packaging] resync update-dkms-versions helper + - debian/dkms-versions -- update from kernel-versions (main/2021.11.29) + * CVE-2021-4002 + - tlb: mmu_gather: add tlb_flush_*_range APIs + - hugetlbfs: flush TLBs correctly after huge_pmd_unshare + * Re-enable DEBUG_INFO_BTF where it was disabled (LP: #1945632) + - [Config] Enable CONFIG_DEBUG_INFO_BTF on all arches + * Focal linux-azure: Vm crash on Dv5/Ev5 (LP: #1950462) + - KVM: VMX: eVMCS: make evmcs_sanitize_exec_ctrls() work again + - jump_label: Fix usage in module __init + * Support builtin revoked certificates (LP: #1932029) + - Revert "UBUNTU: SAUCE: (lockdown) Make get_cert_list() not complain about + cert lists that aren't present." + - integrity: Move import of MokListRT certs to a separate routine + - integrity: Load certs from the EFI MOK config table + - certs: Add ability to preload revocation certs + - integrity: Load mokx variables into the blacklist keyring + - certs: add 'x509_revocation_list' to gitignore + - SAUCE: Dump stack when X.509 certificates cannot be loaded + - [Packaging] build canonical-revoked-certs.pem from branch/arch certs + - [Packaging] Revoke 2012 UEFI signing certificate as built-in + - [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys + * Support importing mokx keys into revocation list from the mok table + (LP: #1928679) + - efi: Support for MOK variable config table + - efi: mokvar-table: fix some issues in new code + - efi: mokvar: add missing include of asm/early_ioremap.h + - efi/mokvar: Reserve the table only if it is in boot services data + - SAUCE: integrity: add informational messages when revoking certs + * Support importing mokx keys into revocation list from the mok table + (LP: #1928679) // CVE-2020-26541 when certificates are revoked via + MokListXRT. + - SAUCE: integrity: Load mokx certs from the EFI MOK config table + * Focal update: v5.4.157 upstream stable release (LP: #1951883) + - ARM: 9133/1: mm: proc-macros: ensure *_tlb_fns are 4B aligned + - ARM: 9134/1: remove duplicate memcpy() definition + - ARM: 9139/1: kprobes: fix arch_init_kprobes() prototype + - ARM: 9141/1: only warn about XIP address when not compile testing + - ipv6: use siphash in rt6_exception_hash() + - ipv4: use siphash instead of Jenkins in fnhe_hashfun() + - usbnet: sanity check for maxpacket + - usbnet: fix error return code in usbnet_probe() + - Revert "pinctrl: bcm: ns: support updated DT binding as syscon subnode" + - ata: sata_mv: Fix the error handling of mv_chip_id() + - nfc: port100: fix using -ERRNO as command type mask + - net/tls: Fix flipped sign in tls_err_abort() calls + - mmc: vub300: fix control-message timeouts + - mmc: cqhci: clear HALT state after CQE enable + - mmc: dw_mmc: exynos: fix the finding clock sample value + - mmc: sdhci: Map more voltage level to SDHCI_POWER_330 + - mmc: sdhci-esdhc-imx: clear the buffer_read_ready to reset standard tuning + circuit + - cfg80211: scan: fix RCU in cfg80211_add_nontrans_list() + - net: lan78xx: fix division by zero in send path + - tcp_bpf: Fix one concurrency problem in the tcp_bpf_send_verdict function + - IB/qib: Protect from buffer overflow in struct qib_user_sdma_pkt fields + - IB/hfi1: Fix abba locking issue with sc_disable() + - nvmet-tcp: fix data digest pointer calculation + - nvme-tcp: fix data digest pointer calculation + - RDMA/mlx5: Set user priority for DCT + - arm64: dts: allwinner: h5: NanoPI Neo 2: Fix ethernet node + - regmap: Fix possible double-free in regcache_rbtree_exit() + - net: batman-adv: fix error handling + - net: Prevent infinite while loop in skb_tx_hash() + - RDMA/sa_query: Use strscpy_pad instead of memcpy to copy a string + - nios2: Make NIOS2_DTB_SOURCE_BOOL depend on !COMPILE_TEST + - net: ethernet: microchip: lan743x: Fix driver crash when lan743x_pm_resume + fails + - net: ethernet: microchip: lan743x: Fix dma allocation failure by using + dma_set_mask_and_coherent + - net: nxp: lpc_eth.c: avoid hang when bringing interface down + - net/tls: Fix flipped sign in async_wait.err assignment + - phy: phy_ethtool_ksettings_get: Lock the phy for consistency + - phy: phy_start_aneg: Add an unlocked version + - sctp: use init_tag from inithdr for ABORT chunk + - sctp: fix the processing for INIT_ACK chunk + - sctp: fix the processing for COOKIE_ECHO chunk + - sctp: add vtag check in sctp_sf_violation + - sctp: add vtag check in sctp_sf_do_8_5_1_E_sa + - sctp: add vtag check in sctp_sf_ootb + - net: use netif_is_bridge_port() to check for IFF_BRIDGE_PORT + - cfg80211: correct bridge/4addr mode check + - KVM: s390: clear kicked_mask before sleeping again + - KVM: s390: preserve deliverable_mask in __airqs_kick_single_vcpu + - perf script: Check session->header.env.arch before using it + - Linux 5.4.157 + * keyboard not working on Medion notebook s17 series (LP: #1950536) + - ACPI: resources: Add one more Medion model in IRQ override quirk + * creat09 from ubuntu_ltp_syscalls and cve-2018-13405 from ubuntu_ltp/cve + failed with XFS (LP: #1950239) + - xfs: ensure that the inode uid/gid match values match the icdinode ones + - xfs: merge the projid fields in struct xfs_icdinode + - xfs: remove the icdinode di_uid/di_gid members + - xfs: fix up non-directory creation in SGID directories + * reuseport_bpf_numa in net from ubuntu_kernel_selftests fails on ppc64le + (LP: #1867570) + - selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes + * Focal update: v5.4.156 upstream stable release (LP: #1951295) + - parisc: math-emu: Fix fall-through warnings + - net: switchdev: do not propagate bridge updates across bridges + - tee: optee: Fix missing devices unregister during optee_remove + - ARM: dts: at91: sama5d2_som1_ek: disable ISC node by default + - xtensa: xtfpga: use CONFIG_USE_OF instead of CONFIG_OF + - xtensa: xtfpga: Try software restart before simulating CPU reset + - NFSD: Keep existing listeners on portlist error + - dma-debug: fix sg checks in debug_dma_map_sg() + - ASoC: wm8960: Fix clock configuration on slave mode + - netfilter: ipvs: make global sysctl readonly in non-init netns + - lan78xx: select CRC32 + - net: dsa: lantiq_gswip: fix register definition + - NIOS2: irqflags: rename a redefined register name + - net: hns3: reset DWRR of unused tc to zero + - net: hns3: add limit ets dwrr bandwidth cannot be 0 + - net: hns3: disable sriov before unload hclge layer + - net: stmmac: Fix E2E delay mechanism + - net: enetc: fix ethtool counter name for PM0_TERR + - can: rcar_can: fix suspend/resume + - can: peak_usb: pcan_usb_fd_decode_status(): fix back to ERROR_ACTIVE state + notification + - can: peak_pci: peak_pci_remove(): fix UAF + - can: j1939: j1939_tp_rxtimer(): fix errant alert in j1939_tp_rxtimer + - can: j1939: j1939_netdev_start(): fix UAF for rx_kref of j1939_priv + - can: j1939: j1939_xtp_rx_dat_one(): cancel session if receive TP.DT with + error length + - can: j1939: j1939_xtp_rx_rts_session_new(): abort TP less than 9 bytes + - ceph: fix handling of "meta" errors + - ocfs2: fix data corruption after conversion from inline format + - ocfs2: mount fails with buffer overflow in strlen + - elfcore: correct reference to CONFIG_UML + - ALSA: usb-audio: Provide quirk for Sennheiser GSP670 Headset + - ALSA: hda/realtek: Add quirk for Clevo PC50HS + - ASoC: DAPM: Fix missing kctl change notifications + - audit: fix possible null-pointer dereference in audit_filter_rules + - powerpc64/idle: Fix SP offsets when saving GPRs + - KVM: PPC: Book3S HV: Fix stack handling in idle_kvm_start_guest() + - KVM: PPC: Book3S HV: Make idle_kvm_start_guest() return 0 if it went to + guest + - powerpc/idle: Don't corrupt back chain when going idle + - mm, slub: fix mismatch between reconstructed freelist depth and cnt + - mm, slub: fix potential memoryleak in kmem_cache_open() + - nfc: nci: fix the UAF of rf_conn_info object + - isdn: cpai: check ctr->cnr to avoid array index out of bound + - netfilter: Kconfig: use 'default y' instead of 'm' for bool config option + - selftests: netfilter: remove stray bash debug line + - gcc-plugins/structleak: add makefile var for disabling structleak + - btrfs: deal with errors when checking if a dir entry exists during log + replay + - net: stmmac: add support for dwmac 3.40a + - ARM: dts: spear3xx: Fix gmac node + - isdn: mISDN: Fix sleeping function called from invalid context + - platform/x86: intel_scu_ipc: Update timeout value in comment + - ALSA: hda: avoid write to STATESTS if controller is in reset + - Input: snvs_pwrkey - add clk handling + - scsi: core: Fix shost->cmd_per_lun calculation in scsi_add_host_with_dma() + - tracing: Have all levels of checks prevent recursion + - ARM: 9122/1: select HAVE_FUTEX_CMPXCHG + - pinctrl: stm32: use valid pin identifier in stm32_pinctrl_resume() + - Linux 5.4.156 + * ubuntu_ltp / finit_module02 fails on v4.15 and other kernels + (LP: #1950644) // Focal update: v5.4.156 upstream stable release + (LP: #1951295) + - vfs: check fd has read access in kernel_read_file_from_fd() + * Focal update: v5.4.155 upstream stable release (LP: #1951291) + - ovl: simplify file splice + - ALSA: usb-audio: Add quirk for VF0770 + - ALSA: seq: Fix a potential UAF by wrong private_free call order + - ALSA: hda/realtek: Complete partial device name to avoid ambiguity + - ALSA: hda/realtek: Add quirk for Clevo X170KM-G + - ALSA: hda/realtek - ALC236 headset MIC recording issue + - ALSA: hda/realtek: Fix the mic type detection issue for ASUS G551JW + - nds32/ftrace: Fix Error: invalid operands (*UND* and *UND* sections) for `^' + - s390: fix strrchr() implementation + - csky: don't let sigreturn play with priveleged bits of status register + - csky: Fixup regs.sr broken in ptrace + - btrfs: unlock newly allocated extent buffer after error + - btrfs: deal with errors when replaying dir entry during log replay + - btrfs: deal with errors when adding inode reference during log replay + - btrfs: check for error when looking up inode during dir entry replay + - watchdog: orion: use 0 for unset heartbeat + - x86/resctrl: Free the ctrlval arrays when domain_setup_mon_state() fails + - mei: me: add Ice Lake-N device id. + - xhci: guard accesses to ep_state in xhci_endpoint_reset() + - xhci: Fix command ring pointer corruption while aborting a command + - xhci: Enable trust tx length quirk for Fresco FL11 USB controller + - cb710: avoid NULL pointer subtraction + - efi/cper: use stack buffer for error record decoding + - efi: Change down_interruptible() in virt_efi_reset_system() to + down_trylock() + - usb: musb: dsps: Fix the probe error path + - Input: xpad - add support for another USB ID of Nacon GC-100 + - USB: serial: qcserial: add EM9191 QDL support + - USB: serial: option: add Quectel EC200S-CN module support + - USB: serial: option: add Telit LE910Cx composition 0x1204 + - USB: serial: option: add prod. id for Quectel EG91 + - EDAC/armada-xp: Fix output of uncorrectable error counter + - nvmem: Fix shift-out-of-bound (UBSAN) with byte size cells + - x86/Kconfig: Do not enable AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT automatically + - powerpc/xive: Discard disabled interrupts in get_irqchip_state() + - iio: adc: aspeed: set driver data when adc probe. + - iio: adc128s052: Fix the error handling path of 'adc128_probe()' + - iio: mtk-auxadc: fix case IIO_CHAN_INFO_PROCESSED + - iio: light: opt3001: Fixed timeout error when 0 lux + - iio: ssp_sensors: add more range checking in ssp_parse_dataframe() + - iio: ssp_sensors: fix error code in ssp_print_mcu_debug() + - iio: dac: ti-dac5571: fix an error code in probe() + - sctp: account stream padding length for reconf chunk + - gpio: pca953x: Improve bias setting + - net: arc: select CRC32 + - net: korina: select CRC32 + - net/mlx5e: Mutually exclude RX-FCS and RX-port-timestamp + - net: stmmac: fix get_hw_feature() on old hardware + - net: encx24j600: check error in devm_regmap_init_encx24j600 + - ethernet: s2io: fix setting mac address during resume + - nfc: fix error handling of nfc_proto_register() + - NFC: digital: fix possible memory leak in digital_tg_listen_mdaa() + - NFC: digital: fix possible memory leak in digital_in_send_sdd_req() + - pata_legacy: fix a couple uninitialized variable bugs + - ata: ahci_platform: fix null-ptr-deref in ahci_platform_enable_regulators() + - mlxsw: thermal: Fix out-of-bounds memory accesses + - platform/mellanox: mlxreg-io: Fix argument base in kstrtou32() call + - drm/panel: olimex-lcd-olinuxino: select CRC32 + - drm/msm: Fix null pointer dereference on pointer edp + - drm/msm/dsi: Fix an error code in msm_dsi_modeset_init() + - drm/msm/dsi: fix off by one in dsi_bus_clk_enable error handling + - acpi/arm64: fix next_platform_timer() section mismatch error + - mqprio: Correct stats in mqprio_dump_class_stats(). + - qed: Fix missing error code in qed_slowpath_start() + - r8152: select CRC32 and CRYPTO/CRYPTO_HASH/CRYPTO_SHA256 + - ionic: don't remove netdev->dev_addr when syncing uc list + - Linux 5.4.155 + * [UBUNTU 20.04] kernel: unable to read partitions on virtio-block dasd (kvm) + (LP: #1950144) // Focal update: v5.4.155 upstream stable release + (LP: #1951291) + - virtio: write back F_VERSION_1 before validate + * Focal update: v5.4.154 upstream stable release (LP: #1951288) + - net: phy: bcm7xxx: Fixed indirect MMD operations + - ext4: correct the error path of ext4_write_inline_data_end() + - HID: apple: Fix logical maximum and usage maximum of Magic Keyboard JIS + - netfilter: ip6_tables: zero-initialize fragment offset + - HID: wacom: Add new Intuos BT (CTL-4100WL/CTL-6100WL) device IDs + - netfilter: nf_nat_masquerade: make async masq_inet6_event handling generic + - netfilter: nf_nat_masquerade: defer conntrack walk to work queue + - mac80211: Drop frames from invalid MAC address in ad-hoc mode + - m68k: Handle arrivals of multiple signals correctly + - net: prevent user from passing illegal stab size + - mac80211: check return value of rhashtable_init + - net: sun: SUNVNET_COMMON should depend on INET + - drm/amdgpu: fix gart.bo pin_count leak + - scsi: ses: Fix unsigned comparison with less than zero + - scsi: virtio_scsi: Fix spelling mistake "Unsupport" -> "Unsupported" + - sched: Always inline is_percpu_thread() + - Linux 5.4.154 + * Focal update: v5.4.153 upstream stable release (LP: #1950014) + - Partially revert "usb: Kconfig: using select for USB_COMMON dependency" + - USB: cdc-acm: fix racy tty buffer accesses + - USB: cdc-acm: fix break reporting + - usb: typec: tcpm: handle SRC_STARTUP state if cc changes + - xen/privcmd: fix error handling in mmap-resource processing + - mmc: meson-gx: do not use memcpy_to/fromio for dram-access-quirk + - ovl: fix missing negative dentry check in ovl_rename() + - nfsd: fix error handling of register_pernet_subsys() in init_nfsd() + - nfsd4: Handle the NFSv4 READDIR 'dircount' hint being zero + - xen/balloon: fix cancelled balloon action + - ARM: dts: omap3430-sdp: Fix NAND device node + - ARM: dts: qcom: apq8064: use compatible which contains chipid + - MIPS: BPF: Restore MIPS32 cBPF JIT + - bpf, mips: Validate conditional branch offsets + - soc: qcom: socinfo: Fixed argument passed to platform_set_data() + - ARM: dts: qcom: apq8064: Use 27MHz PXO clock as DSI PLL reference + - soc: qcom: mdt_loader: Drop PT_LOAD check on hash segment + - ARM: dts: imx: Add missing pinctrl-names for panel on M53Menlo + - ARM: dts: imx: Fix USB host power regulator polarity on M53Menlo + - arm64: dts: qcom: pm8150: use qcom,pm8998-pon binding + - xtensa: move XCHAL_KIO_* definitions to kmem_layout.h + - xtensa: use CONFIG_USE_OF instead of CONFIG_OF + - xtensa: call irqchip_init only when CONFIG_USE_OF is selected + - bpf, arm: Fix register clobbering in div/mod implementation + - bpf: Fix integer overflow in prealloc_elems_and_freelist() + - phy: mdio: fix memory leak + - net_sched: fix NULL deref in fifo_set_limit() + - powerpc/fsl/dts: Fix phy-connection-type for fm1mac3 + - ptp_pch: Load module automatically if ID matches + - arm64: dts: freescale: Fix SP805 clock-names + - arm64: dts: ls1028a: add missing CAN nodes + - ARM: imx6: disable the GIC CPU interface before calling stby-poweroff + sequence + - net: bridge: use nla_total_size_64bit() in br_get_linkxstats_size() + - net/sched: sch_taprio: properly cancel timer from taprio_destroy() + - net: sfp: Fix typo in state machine debug string + - netlink: annotate data races around nlk->bound + - bus: ti-sysc: Use CLKDM_NOAUTO for dra7 dcan1 for errata i893 + - video: fbdev: gbefb: Only instantiate device when built for IP32 + - drm/nouveau/debugfs: fix file release memory leak + - gve: Correct available tx qpl check + - rtnetlink: fix if_nlmsg_stats_size() under estimation + - gve: fix gve_get_stats() + - i40e: fix endless loop under rtnl + - i40e: Fix freeing of uninitialized misc IRQ vector + - net: prefer socket bound to interface when not in VRF + - i2c: acpi: fix resource leak in reconfiguration device addition + - bpf, s390: Fix potential memory leak about jit_data + - RISC-V: Include clone3() on rv32 + - x86/platform/olpc: Correct ifdef symbol to intended CONFIG_OLPC_XO15_SCI + - x86/hpet: Use another crystalball to evaluate HPET usability + - x86/Kconfig: Correct reference to MWINCHIP3D + - Linux 5.4.153 + * Focal update: v5.4.152 upstream stable release (LP: #1950009) + - net: mdio: introduce a shutdown method to mdio device drivers + - xen-netback: correct success/error reporting for the SKB-with-fraglist case + - sparc64: fix pci_iounmap() when CONFIG_PCI is not set + - ext2: fix sleeping in atomic bugs on error + - scsi: sd: Free scsi_disk device via put_device() + - usb: testusb: Fix for showing the connection speed + - usb: dwc2: check return value after calling platform_get_resource() + - selftests: be sure to make khdr before other targets + - selftests:kvm: fix get_warnings_count() ignoring fscanf() return warn + - scsi: ses: Retry failed Send/Receive Diagnostic commands + - tools/vm/page-types: remove dependency on opt_file for idle page tracking + - KVM: do not shrink halt_poll_ns below grow_start + - kvm: x86: Add AMD PMU MSRs to msrs_to_save_all[] + - perf/x86: Reset destroy callback on event init failure + - silence nfscache allocation warnings with kvzalloc + - libata: Add ATA_HORKAGE_NO_NCQ_ON_ATI for Samsung 860 and 870 SSD. + - Linux 5.4.152 + * linux-aws: Fix backport of RDMA/efa: Expose maximum TX doorbell batch + (LP: #1949882) + - SAUCE: aws: Fix backport of RDMA/efa: Expose maximum TX doorbell batch + + -- Tim Gardner Wed, 01 Dec 2021 07:22:40 -0700 + +linux-oracle (5.4.0-1058.62) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1058.62 -proposed tracker (LP: #1949831) + + [ Ubuntu: 5.4.0-91.102 ] + + * focal/linux: 5.4.0-91.102 -proposed tracker (LP: #1949840) + * Packaging resync (LP: #1786013) + - [Packaging] update Ubuntu.md + - debian/dkms-versions -- update from kernel-versions (main/2021.11.08) + * KVM emulation failure when booting into VM crash kernel with multiple CPUs + (LP: #1948862) + - KVM: x86: Properly reset MMU context at vCPU RESET/INIT + * aufs: kernel bug with apparmor and fuseblk (LP: #1948470) + - SAUCE: aufs: bugfix, stop omitting path->mnt + * ebpf: bpf_redirect fails with ip6 gre interfaces (LP: #1947164) + - net: handle ARPHRD_IP6GRE in dev_is_mac_header_xmit() + * require CAP_NET_ADMIN to attach N_HCI ldisc (LP: #1949516) + - Bluetooth: hci_ldisc: require CAP_NET_ADMIN to attach N_HCI ldisc + * ACL updates on OCFS2 are not revalidated (LP: #1947161) + - ocfs2: fix remounting needed after setfacl command + * ppc64 BPF JIT mod by 1 will not return 0 (LP: #1948351) + - powerpc/bpf: Fix BPF_MOD when imm == 1 + * Drop "UBUNTU: SAUCE: cachefiles: Page leaking in + cachefiles_read_backing_file while vmscan is active" (LP: #1947709) + - Revert "UBUNTU: SAUCE: cachefiles: Page leaking in + cachefiles_read_backing_file while vmscan is active" + * Reassign I/O Path of ConnectX-5 Port 1 before Port 2 causes NULL dereference + (LP: #1943464) + - s390/pci: fix leak of PCI device structure + - s390/pci: fix use after free of zpci_dev + - s390/pci: fix zpci_zdev_put() on reserve + * [SRU][F] USB: serial: pl2303: add support for PL2303HXN (LP: #1948377) + - USB: serial: pl2303: add support for PL2303HXN + - USB: serial: pl2303: fix line-speed handling on newer chips + * Focal update: v5.4.151 upstream stable release (LP: #1947888) + - tty: Fix out-of-bound vmalloc access in imageblit + - cpufreq: schedutil: Use kobject release() method to free sugov_tunables + - cpufreq: schedutil: Destroy mutex before kobject_put() frees the memory + - usb: cdns3: fix race condition before setting doorbell + - fs-verity: fix signed integer overflow with i_size near S64_MAX + - hwmon: (w83793) Fix NULL pointer dereference by removing unnecessary + structure field + - hwmon: (w83792d) Fix NULL pointer dereference by removing unnecessary + structure field + - hwmon: (w83791d) Fix NULL pointer dereference by removing unnecessary + structure field + - scsi: ufs: Fix illegal offset in UPIU event trace + - mac80211: fix use-after-free in CCMP/GCMP RX + - x86/kvmclock: Move this_cpu_pvti into kvmclock.h + - drm/amd/display: Pass PCI deviceid into DC + - ipvs: check that ip_vs_conn_tab_bits is between 8 and 20 + - hwmon: (mlxreg-fan) Return non-zero value when fan current state is enforced + from sysfs + - mac80211: Fix ieee80211_amsdu_aggregate frag_tail bug + - mac80211: limit injected vht mcs/nss in ieee80211_parse_tx_radiotap + - mac80211: mesh: fix potentially unaligned access + - mac80211-hwsim: fix late beacon hrtimer handling + - sctp: break out if skb_header_pointer returns NULL in sctp_rcv_ootb + - hwmon: (tmp421) report /PVLD condition as fault + - hwmon: (tmp421) fix rounding for negative values + - net: ipv4: Fix rtnexthop len when RTA_FLOW is present + - e100: fix length calculation in e100_get_regs_len + - e100: fix buffer overrun in e100_get_regs + - selftests, bpf: test_lwt_ip_encap: Really disable rp_filter + - scsi: csiostor: Add module softdep on cxgb4 + - net: hns3: do not allow call hns3_nic_net_open repeatedly + - net: sched: flower: protect fl_walk() with rcu + - af_unix: fix races in sk_peer_pid and sk_peer_cred accesses + - perf/x86/intel: Update event constraints for ICX + - elf: don't use MAP_FIXED_NOREPLACE for elf interpreter mappings + - debugfs: debugfs_create_file_size(): use IS_ERR to check for error + - ipack: ipoctal: fix stack information leak + - ipack: ipoctal: fix tty registration race + - ipack: ipoctal: fix tty-registration error handling + - ipack: ipoctal: fix missing allocation-failure check + - ipack: ipoctal: fix module reference leak + - ext4: fix loff_t overflow in ext4_max_bitmap_size() + - ext4: fix reserved space counter leakage + - ext4: fix potential infinite loop in ext4_dx_readdir() + - HID: u2fzero: ignore incomplete packets without data + - net: udp: annotate data race around udp_sk(sk)->corkflag + - net: stmmac: don't attach interface until resume finishes + - PCI: Fix pci_host_bridge struct device release/free handling + - libnvdimm/pmem: Fix crash triggered when I/O in-flight during unbind + - hso: fix bailout in error case of probe + - usb: hso: fix error handling code of hso_create_net_device + - usb: hso: remove the bailout parameter + - crypto: ccp - fix resource leaks in ccp_run_aes_gcm_cmd() + - HID: betop: fix slab-out-of-bounds Write in betop_probe + - netfilter: ipset: Fix oversized kvmalloc() calls + - HID: usbhid: free raw_report buffers in usbhid_stop + - Linux 5.4.151 + * Focal update: v5.4.150 upstream stable release (LP: #1947886) + - usb: gadget: r8a66597: fix a loop in set_feature() + - usb: dwc2: gadget: Fix ISOC flow for BDMA and Slave + - usb: dwc2: gadget: Fix ISOC transfer complete handling for DDMA + - usb: musb: tusb6010: uninitialized data in tusb_fifo_write_unaligned() + - cifs: fix incorrect check for null pointer in header_assemble + - xen/x86: fix PV trap handling on secondary processors + - usb-storage: Add quirk for ScanLogic SL11R-IDE older than 2.6c + - USB: serial: cp210x: add ID for GW Instek GDM-834x Digital Multimeter + - USB: cdc-acm: fix minor-number release + - binder: make sure fd closes complete + - staging: greybus: uart: fix tty use after free + - Re-enable UAS for LaCie Rugged USB3-FW with fk quirk + - USB: serial: mos7840: remove duplicated 0xac24 device ID + - USB: serial: option: add Telit LN920 compositions + - USB: serial: option: remove duplicate USB device ID + - USB: serial: option: add device id for Foxconn T99W265 + - mcb: fix error handling in mcb_alloc_bus() + - erofs: fix up erofs_lookup tracepoint + - btrfs: prevent __btrfs_dump_space_info() to underflow its free space + - serial: mvebu-uart: fix driver's tx_empty callback + - net: hso: fix muxed tty registration + - afs: Fix incorrect triggering of sillyrename on 3rd-party invalidation + - platform/x86/intel: punit_ipc: Drop wrong use of ACPI_PTR() + - enetc: Fix illegal access when reading affinity_hint + - bnxt_en: Fix TX timeout when TX ring size is set to the smallest + - net/smc: add missing error check in smc_clc_prfx_set() + - gpio: uniphier: Fix void functions to remove return value + - qed: rdma - don't wait for resources under hw error recovery flow + - net/mlx4_en: Don't allow aRFS for encapsulated packets + - scsi: iscsi: Adjust iface sysfs attr detection + - tty: synclink_gt, drop unneeded forward declarations + - tty: synclink_gt: rename a conflicting function name + - fpga: machxo2-spi: Return an error on failure + - fpga: machxo2-spi: Fix missing error code in machxo2_write_complete() + - thermal/core: Potential buffer overflow in thermal_build_list_of_policies() + - cifs: fix a sign extension bug + - scsi: qla2xxx: Restore initiator in dual mode + - scsi: lpfc: Use correct scnprintf() limit + - irqchip/goldfish-pic: Select GENERIC_IRQ_CHIP to fix build + - irqchip/gic-v3-its: Fix potential VPE leak on error + - md: fix a lock order reversal in md_alloc + - blktrace: Fix uaf in blk_trace access after removing by sysfs + - net: macb: fix use after free on rmmod + - net: stmmac: allow CSR clock of 300MHz + - m68k: Double cast io functions to unsigned long + - ipv6: delay fib6_sernum increase in fib6_add + - bpf: Add oversize check before call kvcalloc() + - xen/balloon: use a kernel thread instead a workqueue + - nvme-multipath: fix ANA state updates when a namespace is not present + - sparc32: page align size in arch_dma_alloc + - blk-cgroup: fix UAF by grabbing blkcg lock before destroying blkg pd + - compiler.h: Introduce absolute_pointer macro + - net: i825xx: Use absolute_pointer for memcpy from fixed memory location + - sparc: avoid stringop-overread errors + - qnx4: avoid stringop-overread errors + - parisc: Use absolute_pointer() to define PAGE0 + - arm64: Mark __stack_chk_guard as __ro_after_init + - alpha: Declare virt_to_phys and virt_to_bus parameter as pointer to volatile + - net: 6pack: Fix tx timeout and slot time + - spi: Fix tegra20 build with CONFIG_PM=n + - EDAC/synopsys: Fix wrong value type assignment for edac_mode + - thermal/drivers/int340x: Do not set a wrong tcc offset on resume + - arm64: dts: marvell: armada-37xx: Extend PCIe MEM space + - xen/balloon: fix balloon kthread freezing + - qnx4: work around gcc false positive warning bug + - Linux 5.4.150 + * ACL updates on OCFS2 are not revalidated (LP: #1947161) // Focal update: + v5.4.150 upstream stable release (LP: #1947886) + - ocfs2: drop acl cache for directories too + * Focal update: v5.4.149 upstream stable release (LP: #1947885) + - PCI: pci-bridge-emul: Fix big-endian support + - PCI: aardvark: Indicate error in 'val' when config read fails + - PCI: pci-bridge-emul: Add PCIe Root Capabilities Register + - PCI: aardvark: Fix reporting CRS value + - PCI/ACPI: Add Ampere Altra SOC MCFG quirk + - KVM: remember position in kvm->vcpus array + - console: consume APC, DM, DCS + - s390/pci_mmio: fully validate the VMA before calling follow_pte() + - ARM: Qualify enabling of swiotlb_init() + - apparmor: remove duplicate macro list_entry_is_head() + - ARM: 9077/1: PLT: Move struct plt_entries definition to header + - ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link() + - ARM: 9079/1: ftrace: Add MODULE_PLTS support + - ARM: 9098/1: ftrace: MODULE_PLT: Fix build problem without DYNAMIC_FTRACE + - sctp: validate chunk size in __rcv_asconf_lookup + - sctp: add param size validation for SCTP_PARAM_SET_PRIMARY + - staging: rtl8192u: Fix bitwise vs logical operator in + TranslateRxSignalStuff819xUsb() + - um: virtio_uml: fix memory leak on init failures + - dmaengine: acpi: Avoid comparison GSI with Linux vIRQ + - thermal/drivers/exynos: Fix an error code in exynos_tmu_probe() + - 9p/trans_virtio: Remove sysfs file on probe failure + - prctl: allow to setup brk for et_dyn executables + - nilfs2: use refcount_dec_and_lock() to fix potential UAF + - profiling: fix shift-out-of-bounds bugs + - pwm: lpc32xx: Don't modify HW state in .probe() after the PWM chip was + registered + - phy: avoid unnecessary link-up delay in polling mode + - net: stmmac: reset Tx desc base address before restarting Tx + - Kconfig.debug: drop selecting non-existing HARDLOCKUP_DETECTOR_ARCH + - thermal/core: Fix thermal_cooling_device_register() prototype + - drivers: base: cacheinfo: Get rid of DEFINE_SMP_CALL_CACHE_FUNCTION() + - parisc: Move pci_dev_is_behind_card_dino to where it is used + - dmaengine: sprd: Add missing MODULE_DEVICE_TABLE + - dmaengine: ioat: depends on !UML + - dmaengine: xilinx_dma: Set DMA mask for coherent APIs + - ceph: request Fw caps before updating the mtime in ceph_write_iter + - ceph: lockdep annotations for try_nonblocking_invalidate + - btrfs: fix lockdep warning while mounting sprout fs + - nilfs2: fix memory leak in nilfs_sysfs_create_device_group + - nilfs2: fix NULL pointer in nilfs_##name##_attr_release + - nilfs2: fix memory leak in nilfs_sysfs_create_##name##_group + - nilfs2: fix memory leak in nilfs_sysfs_delete_##name##_group + - nilfs2: fix memory leak in nilfs_sysfs_create_snapshot_group + - nilfs2: fix memory leak in nilfs_sysfs_delete_snapshot_group + - pwm: img: Don't modify HW state in .remove() callback + - pwm: rockchip: Don't modify HW state in .remove() callback + - pwm: stm32-lp: Don't modify HW state in .remove() callback + - blk-throttle: fix UAF by deleteing timer in blk_throtl_exit() + - rtc: rx8010: select REGMAP_I2C + - drm/nouveau/nvkm: Replace -ENOSYS with -ENODEV + - Linux 5.4.149 + + -- Tim Gardner Tue, 09 Nov 2021 09:39:20 -0700 + +linux-oracle (5.4.0-1057.61) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1057.61 -proposed tracker (LP: #1947250) + + * Packaging resync (LP: #1786013) + - [Packaging] update Ubuntu.md + + [ Ubuntu: 5.4.0-90.101 ] + + * focal/linux: 5.4.0-90.101 -proposed tracker (LP: #1947260) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.10.18) + * Add final-checks to check certificates (LP: #1947174) + - [Packaging] Add system trusted and revocation keys final check + * No sound on Lenovo laptop models Legion 15IMHG05, Yoga 7 14ITL5, and 13s + Gen2 (LP: #1939052) + - ALSA: hda/realtek: Quirks to enable speaker output for Lenovo Legion 7i + 15IMHG05, Yoga 7i 14ITL5/15ITL5, and 13s Gen2 laptops. + - ALSA: hda/realtek: Fix for quirk to enable speaker output on the Lenovo 13s + Gen2 + * CVE-2020-36385 + - RDMA/cma: Add missing locking to rdma_accept() + - RDMA/ucma: Fix the locking of ctx->file + - RDMA/ucma: Rework ucma_migrate_id() to avoid races with destroy + * Focal update: v5.4.148 upstream stable release (LP: #1946802) + - rtc: tps65910: Correct driver module alias + - btrfs: wake up async_delalloc_pages waiters after submit + - btrfs: reset replace target device to allocation state on close + - blk-zoned: allow zone management send operations without CAP_SYS_ADMIN + - blk-zoned: allow BLKREPORTZONE without CAP_SYS_ADMIN + - PCI/MSI: Skip masking MSI-X on Xen PV + - powerpc/perf/hv-gpci: Fix counter value parsing + - xen: fix setting of max_pfn in shared_info + - include/linux/list.h: add a macro to test if entry is pointing to the head + - 9p/xen: Fix end of loop tests for list_for_each_entry + - tools/thermal/tmon: Add cross compiling support + - pinctrl: stmfx: Fix hazardous u8[] to unsigned long cast + - pinctrl: ingenic: Fix incorrect pull up/down info + - soc: qcom: aoss: Fix the out of bound usage of cooling_devs + - soc: aspeed: lpc-ctrl: Fix boundary check for mmap + - soc: aspeed: p2a-ctrl: Fix boundary check for mmap + - arm64: head: avoid over-mapping in map_memory + - crypto: public_key: fix overflow during implicit conversion + - block: bfq: fix bfq_set_next_ioprio_data() + - power: supply: max17042: handle fails of reading status register + - dm crypt: Avoid percpu_counter spinlock contention in crypt_page_alloc() + - VMCI: fix NULL pointer dereference when unmapping queue pair + - media: uvc: don't do DMA on stack + - media: rc-loopback: return number of emitters rather than error + - Revert "dmaengine: imx-sdma: refine to load context only once" + - dmaengine: imx-sdma: remove duplicated sdma_load_context + - libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs + - ARM: 9105/1: atags_to_fdt: don't warn about stack size + - PCI/portdrv: Enable Bandwidth Notification only if port supports it + - PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported + - PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure + - PCI: xilinx-nwl: Enable the clock through CCF + - PCI: aardvark: Fix checking for PIO status + - PCI: aardvark: Increase polling delay to 1.5s while waiting for PIO response + - PCI: aardvark: Fix masking and unmasking legacy INTx interrupts + - HID: input: do not report stylus battery state as "full" + - f2fs: quota: fix potential deadlock + - scsi: bsg: Remove support for SCSI_IOCTL_SEND_COMMAND + - IB/hfi1: Adjust pkey entry in index 0 + - RDMA/iwcm: Release resources if iw_cm module initialization fails + - docs: Fix infiniband uverbs minor number + - pinctrl: samsung: Fix pinctrl bank pin count + - vfio: Use config not menuconfig for VFIO_NOIOMMU + - powerpc/stacktrace: Include linux/delay.h + - RDMA/efa: Remove double QP type assignment + - f2fs: show f2fs instance in printk_ratelimited + - f2fs: reduce the scope of setting fsck tag when de->name_len is zero + - openrisc: don't printk() unconditionally + - dma-debug: fix debugfs initialization order + - SUNRPC: Fix potential memory corruption + - scsi: fdomain: Fix error return code in fdomain_probe() + - pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry() + - scsi: smartpqi: Fix an error code in pqi_get_raid_map() + - scsi: qedi: Fix error codes in qedi_alloc_global_queues() + - scsi: qedf: Fix error codes in qedf_alloc_global_queues() + - powerpc/config: Renable MTD_PHYSMAP_OF + - scsi: target: avoid per-loop XCOPY buffer allocations + - HID: i2c-hid: Fix Elan touchpad regression + - KVM: PPC: Book3S HV Nested: Reflect guest PMU in-use to L0 when guest SPRs + are live + - platform/x86: dell-smbios-wmi: Add missing kfree in error-exit from + run_smbios_call + - fscache: Fix cookie key hashing + - clk: at91: sam9x60: Don't use audio PLL + - clk: at91: clk-generated: pass the id of changeable parent at registration + - clk: at91: clk-generated: Limit the requested rate to our range + - KVM: PPC: Fix clearing never mapped TCEs in realmode + - f2fs: fix to account missing .skipped_gc_rwsem + - f2fs: fix unexpected ENOENT comes from f2fs_map_blocks() + - f2fs: fix to unmap pages from userspace process in punch_hole() + - MIPS: Malta: fix alignment of the devicetree buffer + - kbuild: Fix 'no symbols' warning when CONFIG_TRIM_UNUSD_KSYMS=y + - userfaultfd: prevent concurrent API initialization + - drm/amdgpu: Fix amdgpu_ras_eeprom_init() + - ASoC: atmel: ATMEL drivers don't need HAS_DMA + - media: dib8000: rewrite the init prbs logic + - crypto: mxs-dcp - Use sg_mapping_iter to copy data + - PCI: Use pci_update_current_state() in pci_enable_device_flags() + - tipc: keep the skb in rcv queue until the whole data is read + - iio: dac: ad5624r: Fix incorrect handling of an optional regulator. + - iavf: do not override the adapter state in the watchdog task + - iavf: fix locking of critical sections + - ARM: dts: qcom: apq8064: correct clock names + - video: fbdev: kyro: fix a DoS bug by restricting user input + - netlink: Deal with ESRCH error in nlmsg_notify() + - Smack: Fix wrong semantics in smk_access_entry() + - drm: avoid blocking in drm_clients_info's rcu section + - igc: Check if num of q_vectors is smaller than max before array access + - usb: host: fotg210: fix the endpoint's transactional opportunities + calculation + - usb: host: fotg210: fix the actual_length of an iso packet + - usb: gadget: u_ether: fix a potential null pointer dereference + - USB: EHCI: ehci-mv: improve error handling in mv_ehci_enable() + - usb: gadget: composite: Allow bMaxPower=0 if self-powered + - staging: board: Fix uninitialized spinlock when attaching genpd + - tty: serial: jsm: hold port lock when reporting modem line changes + - drm/amd/display: Fix timer_per_pixel unit error + - drm/amd/amdgpu: Update debugfs link_settings output link_rate field in hex + - bpf/tests: Fix copy-and-paste error in double word test + - bpf/tests: Do not PASS tests without actually testing the result + - video: fbdev: asiliantfb: Error out if 'pixclock' equals zero + - video: fbdev: kyro: Error out if 'pixclock' equals zero + - video: fbdev: riva: Error out if 'pixclock' equals zero + - ipv4: ip_output.c: Fix out-of-bounds warning in ip_copy_addrs() + - flow_dissector: Fix out-of-bounds warnings + - s390/jump_label: print real address in a case of a jump label bug + - s390: make PCI mio support a machine flag + - serial: 8250: Define RX trigger levels for OxSemi 950 devices + - xtensa: ISS: don't panic in rs_init + - hvsi: don't panic on tty_register_driver failure + - serial: 8250_pci: make setup_port() parameters explicitly unsigned + - staging: ks7010: Fix the initialization of the 'sleep_status' structure + - samples: bpf: Fix tracex7 error raised on the missing argument + - ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init() + - Bluetooth: skip invalid hci_sync_conn_complete_evt + - workqueue: Fix possible memory leaks in wq_numa_init() + - bonding: 3ad: fix the concurrency between __bond_release_one() and + bond_3ad_state_machine_handler() + - arm64: tegra: Fix Tegra194 PCIe EP compatible string + - ASoC: Intel: bytcr_rt5640: Move "Platform Clock" routes to the maps for the + matching in-/output + - media: imx258: Rectify mismatch of VTS value + - media: imx258: Limit the max analogue gain to 480 + - media: v4l2-dv-timings.c: fix wrong condition in two for-loops + - media: TDA1997x: fix tda1997x_query_dv_timings() return value + - media: tegra-cec: Handle errors of clk_prepare_enable() + - ARM: dts: imx53-ppd: Fix ACHC entry + - arm64: dts: qcom: sdm660: use reg value for memory node + - net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe() + - drm/msm: mdp4: drop vblank get/put from prepare/complete_commit + - selftests/bpf: Fix xdp_tx.c prog section name + - Bluetooth: schedule SCO timeouts with delayed_work + - Bluetooth: avoid circular locks in sco_sock_connect + - net/mlx5: Fix variable type to match 64bit + - gpu: drm: amd: amdgpu: amdgpu_i2c: fix possible uninitialized-variable + access in amdgpu_i2c_router_select_ddc_port() + - drm/display: fix possible null-pointer dereference in dcn10_set_clock() + - mac80211: Fix monitor MTU limit so that A-MSDUs get through + - ARM: tegra: tamonten: Fix UART pad setting + - arm64: tegra: Fix compatible string for Tegra132 CPUs + - arm64: dts: ls1046a: fix eeprom entries + - nvme-tcp: don't check blk_mq_tag_to_rq when receiving pdu data + - Bluetooth: Fix handling of LE Enhanced Connection Complete + - opp: Don't print an error if required-opps is missing + - serial: sh-sci: fix break handling for sysrq + - tcp: enable data-less, empty-cookie SYN with TFO_SERVER_COOKIE_NOT_REQD + - rpc: fix gss_svc_init cleanup on failure + - staging: rts5208: Fix get_ms_information() heap buffer size + - gfs2: Don't call dlm after protocol is unmounted + - usb: chipidea: host: fix port index underflow and UBSAN complains + - lockd: lockd server-side shouldn't set fl_ops + - drm/exynos: Always initialize mapping in exynos_drm_register_dma() + - m68knommu: only set CONFIG_ISA_DMA_API for ColdFire sub-arch + - btrfs: tree-log: check btrfs_lookup_data_extent return value + - ASoC: Intel: Skylake: Fix module configuration for KPB and MIXER + - ASoC: Intel: Skylake: Fix passing loadable flag for module + - of: Don't allow __of_attached_node_sysfs() without CONFIG_SYSFS + - mmc: sdhci-of-arasan: Check return value of non-void funtions + - mmc: rtsx_pci: Fix long reads when clock is prescaled + - selftests/bpf: Enlarge select() timeout for test_maps + - mmc: core: Return correct emmc response in case of ioctl error + - cifs: fix wrong release in sess_alloc_buffer() failed path + - Revert "USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST + quirk set" + - usb: musb: musb_dsps: request_irq() after initializing musb + - usbip: give back URBs for unsent unlink requests during cleanup + - usbip:vhci_hcd USB port can get stuck in the disabled state + - ASoC: rockchip: i2s: Fix regmap_ops hang + - ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B + - drm/amdkfd: Account for SH/SE count when setting up cu masks. + - iwlwifi: mvm: fix a memory leak in iwl_mvm_mac_ctxt_beacon_changed + - iwlwifi: mvm: avoid static queue number aliasing + - iwlwifi: mvm: fix access to BSS elements + - net/mlx5: DR, Enable QP retransmission + - parport: remove non-zero check on count + - ath9k: fix OOB read ar9300_eeprom_restore_internal + - ath9k: fix sleeping in atomic context + - net: fix NULL pointer reference in cipso_v4_doi_free + - fix array-index-out-of-bounds in taprio_change + - net: w5100: check return value after calling platform_get_resource() + - parisc: fix crash with signals and alloca + - ovl: fix BUG_ON() in may_delete() when called from ovl_cleanup() + - scsi: BusLogic: Fix missing pr_cont() use + - scsi: qla2xxx: Changes to support kdump kernel + - scsi: qla2xxx: Sync queue idx with queue_pair_map idx + - cpufreq: powernv: Fix init_chip_info initialization in numa=off + - s390/pv: fix the forcing of the swiotlb + - mm/hugetlb: initialize hugetlb_usage in mm_init + - mm,vmscan: fix divide by zero in get_scan_count + - memcg: enable accounting for pids in nested pid namespaces + - platform/chrome: cros_ec_proto: Send command again when timeout occurs + - lib/test_stackinit: Fix static initializer test + - net: dsa: lantiq_gswip: fix maximum frame length + - drm/msi/mdp4: populate priv->kms in mdp4_kms_init + - drm/amdgpu: Fix BUG_ON assert + - drm/panfrost: Simplify lock_region calculation + - drm/panfrost: Use u64 for size in lock_region + - drm/panfrost: Clamp lock region to Bifrost minimum + - btrfs: fix upper limit for max_inline for page size 64K + - xen: reset legacy rtc flag for PV domU + - bnx2x: Fix enabling network interfaces without VFs + - arm64/sve: Use correct size when reinitialising SVE state + - PM: base: power: don't try to use non-existing RTC for storing data + - PCI: Add AMD GPU multi-function power dependencies + - drm/amd/amdgpu: Increase HWIP_MAX_INSTANCE to 10 + - drm/etnaviv: return context from etnaviv_iommu_context_get + - drm/etnaviv: put submit prev MMU context when it exists + - drm/etnaviv: stop abusing mmu_context as FE running marker + - drm/etnaviv: keep MMU context across runtime suspend/resume + - drm/etnaviv: exec and MMU state is lost when resetting the GPU + - drm/etnaviv: fix MMU context leak on GPU reset + - drm/etnaviv: reference MMU context when setting up hardware state + - drm/etnaviv: add missing MMU context put when reaping MMU mapping + - s390/sclp: fix Secure-IPL facility detection + - x86/mm: Fix kern_addr_valid() to cope with existing but not present entries + - tipc: fix an use-after-free issue in tipc_recvmsg + - net-caif: avoid user-triggerable WARN_ON(1) + - ptp: dp83640: don't define PAGE0 + - net/l2tp: Fix reference count leak in l2tp_udp_recv_core + - r6040: Restore MDIO clock frequency after MAC reset + - tipc: increase timeout in tipc_sk_enqueue() + - perf machine: Initialize srcline string member in add_location struct + - net/mlx5: FWTrace, cancel work on alloc pd error flow + - net/mlx5: Fix potential sleeping in atomic context + - events: Reuse value read using READ_ONCE instead of re-reading it + - vhost_net: fix OoB on sendmsg() failure. + - net/af_unix: fix a data-race in unix_dgram_poll + - net: dsa: destroy the phylink instance on any error in dsa_slave_phy_setup + - tcp: fix tp->undo_retrans accounting in tcp_sacktag_one() + - qed: Handle management FW error + - dt-bindings: arm: Fix Toradex compatible typo + - ibmvnic: check failover_pending in login response + - KVM: PPC: Book3S HV: Tolerate treclaim. in fake-suspend mode changing + registers + - net: hns3: pad the short tunnel frame before sending to hardware + - net: hns3: change affinity_mask to numa node range + - net: hns3: disable mac in flr process + - net: hns3: fix the timing issue of VF clearing interrupt sources + - mm/memory_hotplug: use "unsigned long" for PFN in zone_for_pfn_range() + - dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation + - mfd: db8500-prcmu: Adjust map to reality + - PCI: Add ACS quirks for NXP LX2xx0 and LX2xx2 platforms + - fuse: fix use after free in fuse_read_interrupt() + - mfd: Don't use irq_create_mapping() to resolve a mapping + - tracing/probes: Reject events which have the same name of existing one + - PCI: Add ACS quirks for Cavium multi-function devices + - Set fc_nlinfo in nh_create_ipv4, nh_create_ipv6 + - net: usb: cdc_mbim: avoid altsetting toggling for Telit LN920 + - PCI: ibmphp: Fix double unmap of io_mem + - ethtool: Fix an error code in cxgb2.c + - NTB: Fix an error code in ntb_msit_probe() + - NTB: perf: Fix an error code in perf_setup_inbuf() + - mfd: axp20x: Update AXP288 volatile ranges + - PCI: Fix pci_dev_str_match_path() alloc while atomic bug + - mfd: tqmx86: Clear GPIO IRQ resource when no IRQ is set + - KVM: arm64: Handle PSCI resets before userspace touches vCPU state + - PCI: Sync __pci_register_driver() stub for CONFIG_PCI=n + - mtd: rawnand: cafe: Fix a resource leak in the error handling path of + 'cafe_nand_probe()' + - ARC: export clear_user_page() for modules + - perf unwind: Do not overwrite FEATURE_CHECK_LDFLAGS-libunwind-{x86,aarch64} + - net: dsa: b53: Fix calculating number of switch ports + - netfilter: socket: icmp6: fix use-after-scope + - fq_codel: reject silly quantum parameters + - qlcnic: Remove redundant unlock in qlcnic_pinit_from_rom + - ip_gre: validate csum_start only on pull + - net: renesas: sh_eth: Fix freeing wrong tx descriptor + - Linux 5.4.148 + * Focal update: v5.4.147 upstream stable release (LP: #1946795) + - Linux 5.4.147 + - upstream stable to v5.4.147 + * CVE-2021-3428 + - ext4: save the error code which triggered an ext4_error() in the superblock + - ext4: simulate various I/O and checksum errors when reading metadata + - ext4: save all error info in save_error_info() and drop ext4_set_errno() + - ext4: check journal inode extents more carefully + * ip6gretap / erspan / ip6erspan in rtnetlink.sh from net of + ubuntu_kernel_selftests failed on B-5.4-aws / B-5.4-gke / B-5.4-oracle / + B-5.4-azure / B-5.4 (LP: #1896448) + - SAUCE: selftests: rtnetlink: fixes for older iproute2 + * CVE-2019-19449 + - f2fs: fix wrong total_sections check and fsmeta check + - f2fs: fix to do sanity check on segment/section count + * kernel bug found when disconnecting one fiber channel interface on Cisco + Chassis with fnic DRV_VERSION "1.6.0.47" (LP: #1944586) + - scsi: fnic: Do not call 'scsi_done()' for unhandled commands + * memfd from ubuntu_kernel_selftests failed to build on B-5.4 (unknown type + name ‘__u64’) (LP: #1944613) + - SAUCE: selftests/memfd: fix __u64 not defined build issue + * Medion Notebook Keyboard not working (LP: #1909814) + - ACPI: resources: Add DMI-based legacy IRQ override quirk + * vrf: fix refcnt leak with vxlan slaves (LP: #1945180) + - ipv4: Fix device used for dst_alloc with local routes + * Check for changes relevant for security certifications (LP: #1945989) + - [Packaging] Add a new fips-checks script + - [Packaging] Add fips-checks as part of finalchecks + * Fix cold plugged USB device on certain PCIe USB cards (LP: #1945211) + - Revert "UBUNTU: SAUCE: Revert "usb: core: reduce power-on-good delay time of + root hub"" + - usb: core: hcd: Add support for deferring roothub registration + - xhci: Set HCD flag to defer primary roothub registration + - usb: core: hcd: Modularize HCD stop configuration in usb_stop_hcd() + * CVE-2021-3759 + - memcg: enable accounting of ipc resources + * Focal update: v5.4.146 upstream stable release (LP: #1946024) + - locking/mutex: Fix HANDOFF condition + - regmap: fix the offset of register error log + - crypto: mxs-dcp - Check for DMA mapping errors + - sched/deadline: Fix reset_on_fork reporting of DL tasks + - power: supply: axp288_fuel_gauge: Report register-address on readb / writeb + errors + - crypto: omap-sham - clear dma flags only after omap_sham_update_dma_stop() + - sched/deadline: Fix missing clock update in migrate_task_rq_dl() + - rcu/tree: Handle VM stoppage in stall detection + - hrtimer: Avoid double reprogramming in __hrtimer_start_range_ns() + - hrtimer: Ensure timerfd notification for HIGHRES=n + - udf: Check LVID earlier + - udf: Fix iocharset=utf8 mount option + - isofs: joliet: Fix iocharset=utf8 mount option + - bcache: add proper error unwinding in bcache_device_init + - nvme-tcp: don't update queue count when failing to set io queues + - nvme-rdma: don't update queue count when failing to set io queues + - nvmet: pass back cntlid on successful completion + - power: supply: max17042_battery: fix typo in MAx17042_TOFF + - s390/cio: add dev_busid sysfs entry for each subchannel + - libata: fix ata_host_start() + - crypto: qat - do not ignore errors from enable_vf2pf_comms() + - crypto: qat - handle both source of interrupt in VF ISR + - crypto: qat - fix reuse of completion variable + - crypto: qat - fix naming for init/shutdown VF to PF notifications + - crypto: qat - do not export adf_iov_putmsg() + - fcntl: fix potential deadlock for &fasync_struct.fa_lock + - udf_get_extendedattr() had no boundary checks. + - s390/kasan: fix large PMD pages address alignment check + - s390/debug: fix debug area life cycle + - m68k: emu: Fix invalid free in nfeth_cleanup() + - sched: Fix UCLAMP_FLAG_IDLE setting + - spi: spi-fsl-dspi: Fix issue with uninitialized dma_slave_config + - spi: spi-pic32: Fix issue with uninitialized dma_slave_config + - genirq/timings: Fix error return code in irq_timings_test_irqs() + - lib/mpi: use kcalloc in mpi_resize + - clocksource/drivers/sh_cmt: Fix wrong setting if don't request IRQ for clock + source channel + - crypto: qat - use proper type for vf_mask + - certs: Trigger creation of RSA module signing key if it's not an RSA key + - regulator: vctrl: Use locked regulator_get_voltage in probe path + - regulator: vctrl: Avoid lockdep warning in enable/disable ops + - spi: sprd: Fix the wrong WDG_LOAD_VAL + - spi: spi-zynq-qspi: use wait_for_completion_timeout to make + zynq_qspi_exec_mem_op not interruptible + - EDAC/i10nm: Fix NVDIMM detection + - drm/panfrost: Fix missing clk_disable_unprepare() on error in + panfrost_clk_init() + - media: TDA1997x: enable EDID support + - soc: rockchip: ROCKCHIP_GRF should not default to y, unconditionally + - media: cxd2880-spi: Fix an error handling path + - bpf: Fix a typo of reuseport map in bpf.h. + - bpf: Fix potential memleak and UAF in the verifier. + - ARM: dts: aspeed-g6: Fix HVI3C function-group in pinctrl dtsi + - arm64: dts: renesas: r8a77995: draak: Remove bogus adv7511w properties + - soc: qcom: rpmhpd: Use corner in power_off + - media: dvb-usb: fix uninit-value in dvb_usb_adapter_dvb_init + - media: dvb-usb: fix uninit-value in vp702x_read_mac_addr + - media: dvb-usb: Fix error handling in dvb_usb_i2c_init + - media: go7007: remove redundant initialization + - media: coda: fix frame_mem_ctrl for YUV420 and YVU420 formats + - Bluetooth: sco: prevent information leak in sco_conn_defer_accept() + - 6lowpan: iphc: Fix an off-by-one check of array index + - netns: protect netns ID lookups with RCU + - tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos + - ARM: dts: meson8: Use a higher default GPU clock frequency + - ARM: dts: meson8b: odroidc1: Fix the pwm regulator supply properties + - ARM: dts: meson8b: mxq: Fix the pwm regulator supply properties + - ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties + - net/mlx5e: Prohibit inner indir TIRs in IPoIB + - cgroup/cpuset: Fix a partition bug with hotplug + - net: cipso: fix warnings in netlbl_cipsov4_add_std + - i2c: highlander: add IRQ check + - leds: lt3593: Put fwnode in any case during ->probe() + - leds: trigger: audio: Add an activate callback to ensure the initial + brightness is set + - media: em28xx-input: fix refcount bug in em28xx_usb_disconnect + - media: venus: venc: Fix potential null pointer dereference on pointer fmt + - PCI: PM: Avoid forcing PCI_D0 for wakeup reasons inconsistently + - PCI: PM: Enable PME if it can be signaled from D3cold + - soc: qcom: smsm: Fix missed interrupts if state changes while masked + - debugfs: Return error during {full/open}_proxy_open() on rmmod + - Bluetooth: increase BTNAMSIZ to 21 chars to fix potential buffer overflow + - PM: EM: Increase energy calculation precision + - drm/msm/dpu: make dpu_hw_ctl_clear_all_blendstages clear necessary LMs + - arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 + - counter: 104-quad-8: Return error when invalid mode during ceiling_write + - Bluetooth: fix repeated calls to sco_sock_kill + - drm/msm/dsi: Fix some reference counted resource leaks + - usb: gadget: udc: at91: add IRQ check + - usb: phy: fsl-usb: add IRQ check + - usb: phy: twl6030: add IRQ checks + - usb: gadget: udc: renesas_usb3: Fix soc_device_match() abuse + - usb: host: ohci-tmio: add IRQ check + - usb: phy: tahvo: add IRQ check + - mac80211: Fix insufficient headroom issue for AMSDU + - lockd: Fix invalid lockowner cast after vfs_test_lock + - nfsd4: Fix forced-expiry locking + - usb: gadget: mv_u3d: request_irq() after initializing UDC + - mm/swap: consider max pages in iomap_swapfile_add_extent + - Bluetooth: add timeout sanity check to hci_inquiry + - i2c: iop3xx: fix deferred probing + - i2c: s3c2410: fix IRQ check + - rsi: fix error code in rsi_load_9116_firmware() + - rsi: fix an error code in rsi_probe() + - ASoC: Intel: Skylake: Leave data as is when invoking TLV IPCs + - ASoC: Intel: Skylake: Fix module resource and format selection + - mmc: dw_mmc: Fix issue with uninitialized dma_slave_config + - mmc: moxart: Fix issue with uninitialized dma_slave_config + - bpf: Fix possible out of bound write in narrow load handling + - CIFS: Fix a potencially linear read overflow + - i2c: mt65xx: fix IRQ check + - usb: ehci-orion: Handle errors of clk_prepare_enable() in probe + - usb: bdc: Fix an error handling path in 'bdc_probe()' when no suitable DMA + config is available + - tty: serial: fsl_lpuart: fix the wrong mapbase value + - ASoC: wcd9335: Fix a double irq free in the remove function + - ASoC: wcd9335: Fix a memory leak in the error handling path of the probe + function + - ASoC: wcd9335: Disable irq on slave ports in the remove function + - ath6kl: wmi: fix an error code in ath6kl_wmi_sync_point() + - bcma: Fix memory leak for internally-handled cores + - brcmfmac: pcie: fix oops on failure to resume and reprobe + - ipv6: make exception cache less predictible + - ipv4: make exception cache less predictible + - net: sched: Fix qdisc_rate_table refcount leak when get tcf_block failed + - net: qualcomm: fix QCA7000 checksum handling + - octeontx2-af: Fix loop in free and unmap counter + - ipv4: fix endianness issue in inet_rtm_getroute_build_skb() + - bpf: Introduce BPF nospec instruction for mitigating Spectre v4 + - bpf: Fix leakage due to insufficient speculative store bypass mitigation + - bpf: verifier: Allocate idmap scratch in verifier env + - bpf: Fix pointer arithmetic mask tightening under state pruning + - tty: Fix data race between tiocsti() and flush_to_ldisc() + - perf/x86/amd/ibs: Extend PERF_PMU_CAP_NO_EXCLUDE to IBS Op + - x86/resctrl: Fix a maybe-uninitialized build warning treated as error + - KVM: s390: index kvm->arch.idle_mask by vcpu_idx + - KVM: x86: Update vCPU's hv_clock before back to guest when tsc_offset is + adjusted + - KVM: nVMX: Unconditionally clear nested.pi_pending on nested VM-Enter + - fuse: truncate pagecache on atomic_o_trunc + - fuse: flush extending writes + - IMA: remove -Wmissing-prototypes warning + - IMA: remove the dependency on CRYPTO_MD5 + - fbmem: don't allow too huge resolutions + - backlight: pwm_bl: Improve bootloader/kernel device handover + - clk: kirkwood: Fix a clocking boot regression + - Linux 5.4.146 + * AMD A8-7680 (amdgpu): broken Xorg acceleration and hibernation + (LP: #1920674) // Focal update: v5.4.146 upstream stable release + (LP: #1946024) + - drm/amdgpu/acp: Make PM domain really work + * Focal update: v5.4.145 upstream stable release (LP: #1945517) + - fscrypt: add fscrypt_symlink_getattr() for computing st_size + - ext4: report correct st_size for encrypted symlinks + - f2fs: report correct st_size for encrypted symlinks + - ubifs: report correct st_size for encrypted symlinks + - kthread: Fix PF_KTHREAD vs to_kthread() race + - xtensa: fix kconfig unmet dependency warning for HAVE_FUTEX_CMPXCHG + - gpu: ipu-v3: Fix i.MX IPU-v3 offset calculations for (semi)planar U/V + formats + - reset: reset-zynqmp: Fixed the argument data type + - qed: Fix the VF msix vectors flow + - net: macb: Add a NULL check on desc_ptp + - qede: Fix memset corruption + - perf/x86/intel/pt: Fix mask of num_address_ranges + - perf/x86/amd/ibs: Work around erratum #1197 + - perf/x86/amd/power: Assign pmu.module + - cryptoloop: add a deprecation warning + - ARM: 8918/2: only build return_address() if needed + - ALSA: hda/realtek: Workaround for conflicting SSID on ASUS ROG Strix G17 + - ALSA: pcm: fix divide error in snd_pcm_lib_ioctl + - ARC: wireup clone3 syscall + - media: stkwebcam: fix memory leak in stk_camera_probe + - igmp: Add ip_mc_list lock in ip_check_mc_rcu + - USB: serial: mos7720: improve OOM-handling in read_mos_reg() + - ipv4/icmp: l3mdev: Perform icmp error route lookup on source device routing + table (v2) + - powerpc/boot: Delete unneeded .globl _zimage_start + - net: ll_temac: Remove left-over debug message + - mm/page_alloc: speed up the iteration of max_order + - Revert "r8169: avoid link-up interrupt issue on RTL8106e if user enables + ASPM" + - x86/events/amd/iommu: Fix invalid Perf result due to IOMMU PMC power-gating + - Revert "btrfs: compression: don't try to compress if we don't have enough + pages" + - ALSA: usb-audio: Add registration quirk for JBL Quantum 800 + - usb: host: xhci-rcar: Don't reload firmware after the completion + - usb: mtu3: use @mult for HS isoc or intr + - usb: mtu3: fix the wrong HS mult value + - xhci: fix unsafe memory usage in xhci tracing + - x86/reboot: Limit Dell Optiplex 990 quirk to early BIOS versions + - PCI: Call Max Payload Size-related fixup quirks early + - Linux 5.4.145 + * Focal update: v5.4.144 upstream stable release (LP: #1944756) + - net: qrtr: fix another OOB Read in qrtr_endpoint_post + - ARC: Fix CONFIG_STACKDEPOT + - netfilter: conntrack: collect all entries in one cycle + - once: Fix panic when module unload + - ovl: fix uninitialized pointer read in ovl_lookup_real_one() + - mmc: sdhci-msm: Update the software timeout value for sdhc + - mm, oom: make the calculation of oom badness more accurate + - can: usb: esd_usb2: esd_usb2_rx_event(): fix the interchange of the CAN RX + and TX error counters + - Revert "USB: serial: ch341: fix character loss at high transfer rates" + - USB: serial: option: add new VID/PID to support Fibocom FG150 + - usb: dwc3: gadget: Fix dwc3_calc_trbs_left() + - usb: dwc3: gadget: Stop EP0 transfers during pullup disable + - scsi: core: Fix hang of freezing queue between blocking and running device + - RDMA/bnxt_re: Add missing spin lock initialization + - IB/hfi1: Fix possible null-pointer dereference in _extend_sdma_tx_descs() + - e1000e: Fix the max snoop/no-snoop latency for 10M + - RDMA/efa: Free IRQ vectors on error flow + - ip_gre: add validation for csum_start + - xgene-v2: Fix a resource leak in the error handling path of 'xge_probe()' + - net: marvell: fix MVNETA_TX_IN_PRGRS bit number + - rtnetlink: Return correct error on changing device netns + - net: hns3: clear hardware resource when loading driver + - net: hns3: fix duplicate node in VLAN list + - net: hns3: fix get wrong pfc_en when query PFC configuration + - drm/i915: Fix syncmap memory leak + - usb: gadget: u_audio: fix race condition on endpoint stop + - perf/x86/intel/uncore: Fix integer overflow on 23 bit left shift of a u32 + - opp: remove WARN when no valid OPPs remain + - virtio: Improve vq->broken access to avoid any compiler optimization + - virtio_pci: Support surprise removal of virtio pci device + - vringh: Use wiov->used to check for read/write desc order + - qed: qed ll2 race condition fixes + - qed: Fix null-pointer dereference in qed_rdma_create_qp() + - drm: Copy drm_wait_vblank to user before returning + - drm/nouveau/disp: power down unused DP links during init + - net/rds: dma_map_sg is entitled to merge entries + - btrfs: fix race between marking inode needs to be logged and log syncing + - vt_kdsetmode: extend console locking + - bpf: Track contents of read-only maps as scalars + - bpf: Fix cast to pointer from integer of different size warning + - net: dsa: mt7530: fix VLAN traffic leaks again + - KVM: x86/mmu: Treat NX as used (not reserved) for all !TDP shadow MMUs + - arm64: dts: qcom: msm8994-angler: Fix gpio-reserved-ranges 85-88 + - btrfs: fix NULL pointer dereference when deleting device by invalid id + - Revert "floppy: reintroduce O_NDELAY fix" + - Revert "parisc: Add assembly implementations for memset, strlen, strcpy, + strncpy and strcat" + - net: don't unconditionally copy_from_user a struct ifreq for socket ioctls + - audit: move put_tree() to avoid trim_trees refcount underflow and UAF + - Linux 5.4.144 + + -- Tim Gardner Thu, 21 Oct 2021 13:08:00 -0600 + +linux-oracle (5.4.0-1056.60) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1056.60 -proposed tracker (LP: #1944892) + + [ Ubuntu: 5.4.0-89.100 ] + + * focal/linux: 5.4.0-89.100 -proposed tracker (LP: #1944901) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.27) + * ext4 journal recovery fails w/ data=journal + mmap (LP: #1847340) + - jbd2: introduce/export functions + jbd2_journal_submit|finish_inode_data_buffers() + - jbd2, ext4, ocfs2: introduce/use journal callbacks + j_submit|finish_inode_data_buffers() + - ext4: data=journal: fixes for ext4_page_mkwrite() + - ext4: data=journal: write-protect pages on j_submit_inode_data_buffers() + - ext4: fix mmap write protection for data=journal mode + * CVE-2021-40490 + - ext4: fix race writing to an inline_data file while its xattrs are changing + * Obsolete patch "UBUNTU: SAUCE: ext4: fix directory index node split + corruption" (LP: #1942902) + - Revert "UBUNTU: SAUCE: ext4: fix directory index node split corruption" + * psock_snd.sh in net from ubuntu_kernel_selftests ADT failure with + focal/groovy/hirsute/impish (LP: #1892213) + - selftests/net: remove min gso test in packet_snd + * Focal update: v5.4.143 upstream stable release (LP: #1944212) + - ext4: fix EXT4_MAX_LOGICAL_BLOCK macro + - x86/fpu: Make init_fpstate correct with optimized XSAVE + - ath: Use safer key clearing with key cache entries + - ath9k: Clear key cache explicitly on disabling hardware + - ath: Export ath_hw_keysetmac() + - ath: Modify ath_key_delete() to not need full key entry + - ath9k: Postpone key cache entry deletion for TXQ frames reference it + - mtd: cfi_cmdset_0002: fix crash when erasing/writing AMD cards + - media: zr364xx: propagate errors from zr364xx_start_readpipe() + - media: zr364xx: fix memory leaks in probe() + - media: drivers/media/usb: fix memory leak in zr364xx_probe + - USB: core: Avoid WARNings for 0-length descriptor requests + - dmaengine: xilinx_dma: Fix read-after-free bug when terminating transfers + - dmaengine: usb-dmac: Fix PM reference leak in usb_dmac_probe() + - ARM: dts: am43x-epos-evm: Reduce i2c0 bus speed for tps65218 + - dmaengine: of-dma: router_xlate to return -EPROBE_DEFER if controller is not + yet available + - scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry() + - scsi: scsi_dh_rdac: Avoid crash during rdac_bus_attach() + - scsi: core: Avoid printing an error if target_alloc() returns -ENXIO + - scsi: core: Fix capacity set to zero after offlinining device + - ARM: dts: nomadik: Fix up interrupt controller node names + - net: usb: lan78xx: don't modify phy_device state concurrently + - drm/amd/display: Fix Dynamic bpp issue with 8K30 with Navi 1X + - Bluetooth: hidp: use correct wait queue when removing ctrl_wait + - iommu: Check if group is NULL before remove device + - cpufreq: armada-37xx: forbid cpufreq for 1.2 GHz variant + - dccp: add do-while-0 stubs for dccp_pr_debug macros + - virtio: Protect vqs list access + - vhost: Fix the calculation in vhost_overflow() + - bpf: Clear zext_dst of dead insns + - bnxt: don't lock the tx queue from napi poll + - bnxt: disable napi before canceling DIM + - net: 6pack: fix slab-out-of-bounds in decode_data + - ptp_pch: Restore dependency on PCI + - bnxt_en: Add missing DMA memory barriers + - vrf: Reset skb conntrack connection on VRF rcv + - virtio-net: support XDP when not more queues + - virtio-net: use NETIF_F_GRO_HW instead of NETIF_F_LRO + - net: qlcnic: add missed unlock in qlcnic_83xx_flash_read32 + - net: mdio-mux: Don't ignore memory allocation errors + - net: mdio-mux: Handle -EPROBE_DEFER correctly + - ovs: clear skb->tstamp in forwarding path + - i40e: Fix ATR queue selection + - iavf: Fix ping is lost after untrusted VF had tried to change MAC + - ovl: add splice file read write helper + - mmc: dw_mmc: Fix hang on data CRC error + - ALSA: hda - fix the 'Capture Switch' value change notifications + - tracing / histogram: Fix NULL pointer dereference on strcmp() on NULL event + name + - slimbus: messaging: start transaction ids from 1 instead of zero + - slimbus: messaging: check for valid transaction id + - slimbus: ngd: reset dma setup during runtime pm + - ipack: tpci200: fix many double free issues in tpci200_pci_probe + - ipack: tpci200: fix memory leak in the tpci200_register + - btrfs: prevent rename2 from exchanging a subvol with a directory from + different parents + - PCI: Increase D3 delay for AMD Renoir/Cezanne XHCI + - ASoC: intel: atom: Fix breakage for PCM buffer address setup + - mm, memcg: avoid stale protection values when cgroup is above protection + - mm: memcontrol: fix occasional OOMs due to proportional memory.low reclaim + - fs: warn about impending deprecation of mandatory locks + - netfilter: nft_exthdr: fix endianness of tcp option cast + - Linux 5.4.143 + * Focal update: v5.4.142 upstream stable release (LP: #1944202) + - iio: adc: ti-ads7950: Ensure CS is deasserted after reading channels + - iio: humidity: hdc100x: Add margin to the conversion time + - iio: adc: Fix incorrect exit of for-loop + - ASoC: xilinx: Fix reference to PCM buffer address + - ASoC: intel: atom: Fix reference to PCM buffer address + - i2c: dev: zero out array used for i2c reads from userspace + - ceph: reduce contention in ceph_check_delayed_caps() + - ACPI: NFIT: Fix support for virtual SPA ranges + - libnvdimm/region: Fix label activation vs errors + - ieee802154: hwsim: fix GPF in hwsim_set_edge_lqi + - ieee802154: hwsim: fix GPF in hwsim_new_edge_nl + - ASoC: cs42l42: Correct definition of ADC Volume control + - ASoC: cs42l42: Don't allow SND_SOC_DAIFMT_LEFT_J + - ASoC: cs42l42: Fix inversion of ADC Notch Switch control + - ASoC: cs42l42: Remove duplicate control for WNF filter frequency + - netfilter: nf_conntrack_bridge: Fix memory leak when error + - ASoC: cs42l42: Fix LRCLK frame start edge + - net: dsa: mt7530: add the missing RxUnicast MIB counter + - platform/x86: pcengines-apuv2: revert wiring up simswitch GPIO as LED + - platform/x86: pcengines-apuv2: Add missing terminating entries to gpio- + lookup tables + - net: phy: micrel: Fix link detection on ksz87xx switch" + - ppp: Fix generating ifname when empty IFLA_IFNAME is specified + - net: sched: act_mirred: Reset ct info when mirror/redirect skb + - iavf: Set RSS LUT and key in reset handle path + - psample: Add a fwd declaration for skbuff + - net/mlx5: Fix return value from tracer initialization + - drm/meson: fix colour distortion from HDR set during vendor u-boot + - net: dsa: microchip: Fix ksz_read64() + - net: Fix memory leak in ieee802154_raw_deliver + - net: igmp: fix data-race in igmp_ifc_timer_expire() + - net: dsa: lan9303: fix broken backpressure in .port_fdb_dump + - net: dsa: lantiq: fix broken backpressure in .port_fdb_dump + - net: dsa: sja1105: fix broken backpressure in .port_fdb_dump + - net: bridge: fix memleak in br_add_if() + - net: linkwatch: fix failure to restore device state across suspend/resume + - tcp_bbr: fix u32 wrap bug in round logic if bbr_init() called after 2B + packets + - net: igmp: increase size of mr_ifc_count + - xen/events: Fix race in set_evtchn_to_irq + - vsock/virtio: avoid potential deadlock when vsock device remove + - nbd: Aovid double completion of a request + - powerpc/kprobes: Fix kprobe Oops happens in booke + - x86/tools: Fix objdump version check again + - genirq: Provide IRQCHIP_AFFINITY_PRE_STARTUP + - x86/msi: Force affinity setup before startup + - x86/ioapic: Force affinity setup before startup + - x86/resctrl: Fix default monitoring groups reporting + - genirq/msi: Ensure deactivation on teardown + - genirq/timings: Prevent potential array overflow in __irq_timings_store() + - PCI/MSI: Enable and mask MSI-X early + - PCI/MSI: Mask all unused MSI-X entries + - PCI/MSI: Enforce that MSI-X table entry is masked for update + - PCI/MSI: Enforce MSI[X] entry updates to be visible + - PCI/MSI: Do not set invalid bits in MSI mask + - PCI/MSI: Correct misleading comments + - PCI/MSI: Use msi_mask_irq() in pci_msi_shutdown() + - PCI/MSI: Protect msi_desc::masked for multi-MSI + - KVM: VMX: Use current VMCS to query WAITPKG support for MSR emulation + - ceph: add some lockdep assertions around snaprealm handling + - ceph: clean up locking annotation for ceph_get_snap_realm and + __lookup_snap_realm + - ceph: take snap_empty_lock atomically with snaprealm refcount change + - vmlinux.lds.h: Handle clang's module.{c,d}tor sections + - iommu/vt-d: Fix agaw for a supported 48 bit guest address width + - Linux 5.4.142 + * Focal update: v5.4.141 upstream stable release (LP: #1943484) + - KVM: SVM: Fix off-by-one indexing when nullifying last used SEV VMCB + - tee: Correct inappropriate usage of TEE_SHM_DMA_BUF flag + - media: v4l2-mem2mem: always consider OUTPUT queue during poll + - tracing: Reject string operand in the histogram expression + - usb: dwc3: Stop active transfers before halting the controller + - usb: dwc3: gadget: Allow runtime suspend if UDC unbinded + - usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup + - usb: dwc3: gadget: Prevent EP queuing while stopping transfers + - usb: dwc3: gadget: Clear DEP flags after stop transfers in ep disable + - usb: dwc3: gadget: Disable gadget IRQ during pullup disable + - usb: dwc3: gadget: Avoid runtime resume if disabling pullup + - KVM: X86: MMU: Use the correct inherited permissions to get shadow page + - USB:ehci:fix Kunpeng920 ehci hardware problem + - ALSA: hda: Add quirk for ASUS Flow x13 + - ppp: Fix generating ppp unit id when ifname is not specified + - ovl: prevent private clone if bind mount is not allowed + - btrfs: make qgroup_free_reserved_data take btrfs_inode + - btrfs: make btrfs_qgroup_reserve_data take btrfs_inode + - btrfs: qgroup: allow to unreserve range without releasing other ranges + - btrfs: qgroup: try to flush qgroup space when we get -EDQUOT + - btrfs: transaction: Cleanup unused TRANS_STATE_BLOCKED + - btrfs: qgroup: remove ASYNC_COMMIT mechanism in favor of reserve retry- + after-EDQUOT + - btrfs: fix lockdep splat when enabling and disabling qgroups + - net: xilinx_emaclite: Do not print real IOMEM pointer + - btrfs: qgroup: don't commit transaction when we already hold the handle + - btrfs: export and rename qgroup_reserve_meta + - btrfs: don't flush from btrfs_delayed_inode_reserve_metadata + - Linux 5.4.141 + + [ Ubuntu: 5.4.0-88.99 ] + + * focal/linux: 5.4.0-88.99 -proposed tracker (LP: #1944747) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.06) + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - Revert "UBUNTU: [Config] Disable virtualbox dkms build" + + [ Ubuntu: 5.4.0-86.97 ] + + * s390x BPF JIT vulnerabilities (LP: #1943960) + - SAUCE: s390/bpf: Fix 64-bit subtraction of the -0x80000000 constant + - SAUCE: s390/bpf: Fix optimizing out zero-extensions + + -- Tim Gardner Wed, 29 Sep 2021 06:48:56 -0600 + +linux-oracle (5.4.0-1055.59) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1055.59 -proposed tracker (LP: #1942548) + + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - [Config] oracle: Disable virtualbox dkms build + + [ Ubuntu: 5.4.0-85.95 ] + + * focal/linux: 5.4.0-85.95 -proposed tracker (LP: #1942557) + * please drop virtualbox-guest-dkms virtualbox-guest-source (LP: #1933248) + - [Config] Disable virtualbox dkms build + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.09.06) + * LRMv5: switch primary version handling to kernel-versions data set + (LP: #1928921) + - [Packaging] switch to kernel-versions + * disable “CONFIG_HISI_DMA” config for ubuntu version (LP: #1936771) + - Disable CONFIG_HISI_DMA + - [Config] Record hisi_dma no longer built for arm64 + * memory leaking when removing a profile (LP: #1939915) + - apparmor: Fix memory leak of profile proxy + * CryptoExpress EP11 cards are going offline (LP: #1939618) + - s390/zcrypt: Support for CCA protected key block version 2 + - s390: Replace zero-length array with flexible-array member + - s390/zcrypt: Use scnprintf() for avoiding potential buffer overflow + - s390/zcrypt: replace snprintf/sprintf with scnprintf + - s390/ap: Remove ap device suspend and resume callbacks + - s390/zcrypt: use fallthrough; + - s390/zcrypt: use kvmalloc instead of kmalloc for 256k alloc + - s390/ap: remove power management code from ap bus and drivers + - s390/ap: introduce new ap function ap_get_qdev() + - s390/zcrypt: use kzalloc + - s390/zcrypt: fix smatch warnings + - s390/zcrypt: code beautification and struct field renames + - s390/zcrypt: split ioctl function into smaller code units + - s390/ap: rename and clarify ap state machine related stuff + - s390/zcrypt: provide cex4 cca sysfs attributes for cex3 + - s390/ap: rework crypto config info and default domain code + - s390/zcrypt: simplify cca_findcard2 loop code + - s390/zcrypt: remove set_fs() invocation in zcrypt device driver + - s390/ap: remove unnecessary spin_lock_init() + - s390/zcrypt: Support for CCA APKA master keys + - s390/zcrypt: introduce msg tracking in zcrypt functions + - s390/ap: split ap queue state machine state from device state + - s390/ap: add error response code field for ap queue devices + - s390/ap: add card/queue deconfig state + - s390/sclp: Add support for SCLP AP adapter config/deconfig + - s390/ap: Support AP card SCLP config and deconfig operations + - s390/ap/zcrypt: revisit ap and zcrypt error handling + - s390/zcrypt: move ap_msg param one level up the call chain + - s390/zcrypt: Introduce Failure Injection feature + - s390/zcrypt: fix wrong format specifications + - s390/ap: fix ap devices reference counting + - s390/zcrypt: return EIO when msg retry limit reached + - s390/zcrypt: fix zcard and zqueue hot-unplug memleak + - s390/ap: Fix hanging ioctl caused by wrong msg counter + * memfd from ubuntu_kernel_selftests failed to build on B-5.4 (LP: #1926142) + - SAUCE: selftests/memfd: fix build when F_SEAL_FUTURE_WRITE is not defined + * [SRU] Ice driver causes the kernel to crash with Ubuntu 20.04.2 with ethtool + specific register commands (LP: #1939855) + - ice: Fix bad register reads + * ubunut_kernel_selftests: memory-hotplug: avoid spamming logs with + dump_page() (LP: #1941829) + - selftests: memory-hotplug: avoid spamming logs with dump_page(), ratio limit + hot-remove error test + * e1000e blocks the boot process when it tried to write checksum to its NVM + (LP: #1936998) + - e1000e: Do not take care about recovery NVM checksum + * Focal update: v5.4.140 upstream stable release (LP: #1941798) + - Revert "ACPICA: Fix memory leak caused by _CID repair function" + - ALSA: seq: Fix racy deletion of subscriber + - arm64: dts: ls1028a: fix node name for the sysclk + - ARM: imx: add missing iounmap() + - ARM: imx: add missing clk_disable_unprepare() + - ARM: dts: imx6qdl-sr-som: Increase the PHY reset duration to 10ms + - ARM: dts: colibri-imx6ull: limit SDIO clock to 25MHz + - ARM: imx: fix missing 3rd argument in macro imx_mmdc_perf_init + - ARM: dts: imx: Swap M53Menlo pinctrl_power_button/pinctrl_power_out pins + - arm64: dts: armada-3720-turris-mox: remove mrvl,i2c-fast-mode + - ALSA: usb-audio: fix incorrect clock source setting + - clk: stm32f4: fix post divisor setup for I2S/SAI PLLs + - ARM: dts: am437x-l4: fix typo in can@0 node + - omap5-board-common: remove not physically existing vdds_1v8_main fixed- + regulator + - spi: imx: mx51-ecspi: Reinstate low-speed CONFIGREG delay + - spi: imx: mx51-ecspi: Fix low-speed CONFIGREG delay calculation + - scsi: sr: Return correct event when media event code is 3 + - media: videobuf2-core: dequeue if start_streaming fails + - dmaengine: imx-dma: configure the generic DMA type to make it work + - net, gro: Set inner transport header offset in tcp/udp GRO hook + - net: dsa: sja1105: overwrite dynamic FDB entries with static ones in + .port_fdb_add + - net: dsa: sja1105: invalidate dynamic FDB entries learned concurrently with + statically added ones + - net: phy: micrel: Fix detection of ksz87xx switch + - net: natsemi: Fix missing pci_disable_device() in probe and remove + - gpio: tqmx86: really make IRQ optional + - sctp: move the active_key update after sh_keys is added + - nfp: update ethtool reporting of pauseframe control + - net: ipv6: fix returned variable type in ip6_skb_dst_mtu + - mips: Fix non-POSIX regexp + - bnx2x: fix an error code in bnx2x_nic_load() + - net: pegasus: fix uninit-value in get_interrupt_interval + - net: fec: fix use-after-free in fec_drv_remove + - net: vxge: fix use-after-free in vxge_device_unregister + - blk-iolatency: error out if blk_get_queue() failed in iolatency_set_limit() + - Bluetooth: defer cleanup of resources in hci_unregister_dev() + - USB: usbtmc: Fix RCU stall warning + - USB: serial: option: add Telit FD980 composition 0x1056 + - USB: serial: ch341: fix character loss at high transfer rates + - USB: serial: ftdi_sio: add device ID for Auto-M3 OP-COM v2 + - firmware_loader: use -ETIMEDOUT instead of -EAGAIN in fw_load_sysfs_fallback + - firmware_loader: fix use-after-free in firmware_fallback_sysfs + - ALSA: hda/realtek: add mic quirk for Acer SF314-42 + - ALSA: usb-audio: Add registration quirk for JBL Quantum 600 + - usb: cdns3: Fixed incorrect gadget state + - usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers + - usb: gadget: f_hid: fixed NULL pointer dereference + - usb: gadget: f_hid: idle uses the highest byte for duration + - usb: otg-fsm: Fix hrtimer list corruption + - clk: fix leak on devm_clk_bulk_get_all() unwind + - scripts/tracing: fix the bug that can't parse raw_trace_func + - tracing / histogram: Give calculation hist_fields a size + - optee: Clear stale cache entries during initialization + - tee: add tee_shm_alloc_kernel_buf() + - optee: Fix memory leak when failing to register shm pages + - tpm_ftpm_tee: Free and unregister TEE shared memory during kexec + - staging: rtl8723bs: Fix a resource leak in sd_int_dpc + - staging: rtl8712: get rid of flush_scheduled_work + - media: rtl28xxu: fix zero-length control request + - pipe: increase minimum default pipe size to 2 pages + - ext4: fix potential htree corruption when growing large_dir directories + - serial: tegra: Only print FIFO error message when an error occurs + - serial: 8250_mtk: fix uart corruption issue when rx power off + - serial: 8250: Mask out floating 16/32-bit bus bits + - MIPS: Malta: Do not byte-swap accesses to the CBUS UART + - serial: 8250_pci: Enumerate Elkhart Lake UARTs via dedicated driver + - serial: 8250_pci: Avoid irq sharing for MSI(-X) interrupts. + - timers: Move clearing of base::timer_running under base:: Lock + - pcmcia: i82092: fix a null pointer dereference bug + - md/raid10: properly indicate failure when ending a failed write request + - KVM: x86: accept userspace interrupt only if no event is injected + - KVM: Do not leak memory for duplicate debugfs directories + - KVM: x86/mmu: Fix per-cpu counter corruption on 32-bit builds + - arm64: vdso: Avoid ISB after reading from cntvct_el0 + - soc: ixp4xx: fix printing resources + - spi: meson-spicc: fix memory leak in meson_spicc_remove + - soc: ixp4xx/qmgr: fix invalid __iomem access + - perf/x86/amd: Don't touch the AMD64_EVENTSEL_HOSTONLY bit inside the guest + - bpf, selftests: Adjust few selftest result_unpriv outcomes + - libata: fix ata_pio_sector for CONFIG_HIGHMEM + - reiserfs: add check for root_inode in reiserfs_fill_super + - reiserfs: check directory items on read from disk + - virt_wifi: fix error on connect + - alpha: Send stop IPI to send to online CPUs + - net/qla3xxx: fix schedule while atomic in ql_wait_for_drvr_lock and + ql_adapter_reset + - arm64: fix compat syscall return truncation + - Linux 5.4.140 + * Focal update: v5.4.139 upstream stable release (LP: #1941796) + - btrfs: delete duplicated words + other fixes in comments + - btrfs: do not commit logs and transactions during link and rename operations + - btrfs: fix race causing unnecessary inode logging during link and rename + - btrfs: fix lost inode on log replay after mix of fsync, rename and inode + eviction + - regulator: rt5033: Fix n_voltages settings for BUCK and LDO + - spi: stm32h7: fix full duplex irq handler handling + - ASoC: tlv320aic31xx: fix reversed bclk/wclk master bits + - r8152: Fix potential PM refcount imbalance + - qed: fix possible unpaired spin_{un}lock_bh in _qed_mcp_cmd_and_union() + - net: Fix zero-copy head len calculation. + - nvme: fix nvme_setup_command metadata trace event + - ACPI: fix NULL pointer dereference + - Revert "Bluetooth: Shutdown controller after workqueues are flushed or + cancelled" + - firmware: arm_scmi: Ensure drivers provide a probe function + - firmware: arm_scmi: Add delayed response status check + - bpf: Inherit expanded/patched seen count from old aux data + - bpf: Do not mark insn as seen under speculative path verification + - bpf: Fix leakage under speculation on mispredicted branches + - bpf: Test_verifier, add alu32 bounds tracking tests + - bpf, selftests: Add a verifier test for assigning 32bit reg states to 64bit + ones + - bpf, selftests: Adjust few selftest outcomes wrt unreachable code + - spi: mediatek: Fix fifo transfer + - Linux 5.4.139 + * Focal update: v5.4.138 upstream stable release (LP: #1940559) + - net_sched: check error pointer in tcf_dump_walker() + - x86/asm: Ensure asm/proto.h can be included stand-alone + - btrfs: fix rw device counting in __btrfs_free_extra_devids + - btrfs: mark compressed range uptodate only if all bio succeed + - x86/kvm: fix vcpu-id indexed array sizes + - KVM: add missing compat KVM_CLEAR_DIRTY_LOG + - ocfs2: fix zero out valid data + - ocfs2: issue zeroout to EOF blocks + - can: j1939: j1939_xtp_rx_dat_one(): fix rxtimer value between consecutive + TP.DT to 750ms + - can: raw: raw_setsockopt(): fix raw_rcv panic for sock UAF + - can: mcba_usb_start(): add missing urb->transfer_dma initialization + - can: usb_8dev: fix memory leak + - can: ems_usb: fix memory leak + - can: esd_usb2: fix memory leak + - HID: wacom: Re-enable touch by default for Cintiq 24HDT / 27QHDT + - NIU: fix incorrect error return, missed in previous revert + - nfc: nfcsim: fix use after free during module unload + - cfg80211: Fix possible memory leak in function cfg80211_bss_update + - netfilter: conntrack: adjust stop timestamp to real expiry value + - netfilter: nft_nat: allow to specify layer 4 protocol NAT only + - i40e: Fix logic of disabling queues + - i40e: Fix firmware LLDP agent related warning + - i40e: Fix queue-to-TC mapping on Tx + - i40e: Fix log TC creation failure when max num of queues is exceeded + - tipc: fix sleeping in tipc accept routine + - net: Set true network header for ECN decapsulation + - mlx4: Fix missing error code in mlx4_load_one() + - net: llc: fix skb_over_panic + - net/mlx5: Fix flow table chaining + - net/mlx5e: Fix nullptr in mlx5e_hairpin_get_mdev() + - sctp: fix return value check in __sctp_rcv_asconf_lookup + - tulip: windbond-840: Fix missing pci_disable_device() in probe and remove + - sis900: Fix missing pci_disable_device() in probe and remove + - can: hi311x: fix a signedness bug in hi3110_cmd() + - PCI: mvebu: Setup BAR0 in order to fix MSI + - powerpc/pseries: Fix regression while building external modules + - i40e: Add additional info to PHY type error + - can: j1939: j1939_session_deactivate(): clarify lifetime of session object + - Linux 5.4.138 + * Focal update: v5.4.137 upstream stable release (LP: #1940557) + - selftest: fix build error in tools/testing/selftests/vm/userfaultfd.c + - tools: Allow proper CC/CXX/... override with LLVM=1 in Makefile.include + - KVM: x86: determine if an exception has an error code only when injecting + it. + - af_unix: fix garbage collect vs MSG_PEEK + - workqueue: fix UAF in pwq_unbound_release_workfn() + - cgroup1: fix leaked context root causing sporadic NULL deref in LTP + - net/802/mrp: fix memleak in mrp_request_join() + - net/802/garp: fix memleak in garp_request_join() + - net: annotate data race around sk_ll_usec + - sctp: move 198 addresses from unusable to private scope + - ipv6: allocate enough headroom in ip6_finish_output2() + - hfs: add missing clean-up in hfs_fill_super + - hfs: fix high memory mapping in hfs_bnode_read + - hfs: add lock nesting notation to hfs_find_init + - firmware: arm_scmi: Fix possible scmi_linux_errmap buffer overflow + - firmware: arm_scmi: Fix range check for the maximum number of pending + messages + - cifs: fix the out of range assignment to bit fields in + parse_server_interfaces + - iomap: remove the length variable in iomap_seek_data + - iomap: remove the length variable in iomap_seek_hole + - ARM: dts: versatile: Fix up interrupt controller node names + - ipv6: ip6_finish_output2: set sk into newly allocated nskb + - Linux 5.4.137 + * Focal update: v5.4.136 upstream stable release (LP: #1939899) + - igc: Fix use-after-free error during reset + - igb: Fix use-after-free error during reset + - igc: change default return of igc_read_phy_reg() + - ixgbe: Fix an error handling path in 'ixgbe_probe()' + - igc: Prefer to use the pci_release_mem_regions method + - igc: Fix an error handling path in 'igc_probe()' + - igb: Fix an error handling path in 'igb_probe()' + - fm10k: Fix an error handling path in 'fm10k_probe()' + - e1000e: Fix an error handling path in 'e1000_probe()' + - iavf: Fix an error handling path in 'iavf_probe()' + - igb: Check if num of q_vectors is smaller than max before array access + - igb: Fix position of assignment to *ring + - gve: Fix an error handling path in 'gve_probe()' + - ipv6: fix 'disable_policy' for fwd packets + - selftests: icmp_redirect: remove from checking for IPv6 route get + - selftests: icmp_redirect: IPv6 PMTU info should be cleared after redirect + - pwm: sprd: Ensure configuring period and duty_cycle isn't wrongly skipped + - cxgb4: fix IRQ free race during driver unload + - nvme-pci: do not call nvme_dev_remove_admin from nvme_remove + - perf probe: Fix dso->nsinfo refcounting + - perf env: Fix sibling_dies memory leak + - perf test session_topology: Delete session->evlist + - perf test event_update: Fix memory leak of evlist + - perf dso: Fix memory leak in dso__new_map() + - perf script: Fix memory 'threads' and 'cpus' leaks on exit + - perf lzma: Close lzma stream on exit + - perf probe-file: Delete namelist in del_events() on the error path + - perf data: Close all files in close_dir() + - spi: imx: add a check for speed_hz before calculating the clock + - spi: stm32: Use dma_request_chan() instead dma_request_slave_channel() + - spi: stm32: fixes pm_runtime calls in probe/remove + - regulator: hi6421: Use correct variable type for regmap api val argument + - regulator: hi6421: Fix getting wrong drvdata + - spi: mediatek: fix fifo rx mode + - ASoC: rt5631: Fix regcache sync errors on resume + - liquidio: Fix unintentional sign extension issue on left shift of u16 + - s390/bpf: Perform r1 range checking before accessing jit->seen_reg[r1] + - bpf, sockmap, tcp: sk_prot needs inuse_idx set for proc stats + - bpftool: Check malloc return value in mount_bpffs_for_pin + - net: fix uninit-value in caif_seqpkt_sendmsg + - efi/tpm: Differentiate missing and invalid final event log table. + - net: decnet: Fix sleeping inside in af_decnet + - KVM: PPC: Book3S: Fix CONFIG_TRANSACTIONAL_MEM=n crash + - KVM: PPC: Fix kvm_arch_vcpu_ioctl vcpu_load leak + - net: sched: fix memory leak in tcindex_partial_destroy_work + - netrom: Decrease sock refcount when sock timers expire + - scsi: iscsi: Fix iface sysfs attr detection + - scsi: target: Fix protect handling in WRITE SAME(32) + - spi: cadence: Correct initialisation of runtime PM again + - bnxt_en: Improve bnxt_ulp_stop()/bnxt_ulp_start() call sequence. + - bnxt_en: Refresh RoCE capabilities in bnxt_ulp_probe() + - bnxt_en: Add missing check for BNXT_STATE_ABORT_ERR in bnxt_fw_rset_task() + - bnxt_en: Check abort error state in bnxt_half_open_nic() + - net: hisilicon: rename CACHE_LINE_MASK to avoid redefinition + - net/tcp_fastopen: fix data races around tfo_active_disable_stamp + - net: hns3: fix rx VLAN offload state inconsistent issue + - net/sched: act_skbmod: Skip non-Ethernet packets + - ipv6: fix another slab-out-of-bounds in fib6_nh_flush_exceptions + - nvme-pci: don't WARN_ON in nvme_reset_work if ctrl.state is not RESETTING + - Revert "USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem" + - afs: Fix tracepoint string placement with built-in AFS + - r8169: Avoid duplicate sysfs entry creation error + - nvme: set the PRACT bit when using Write Zeroes with T10 PI + - sctp: update active_key for asoc when old key is being replaced + - net: sched: cls_api: Fix the the wrong parameter + - drm/panel: raspberrypi-touchscreen: Prevent double-free + - proc: Avoid mixing integer types in mem_rw() + - s390/ftrace: fix ftrace_update_ftrace_func implementation + - s390/boot: fix use of expolines in the DMA code + - ALSA: usb-audio: Add missing proc text entry for BESPOKEN type + - ALSA: usb-audio: Add registration quirk for JBL Quantum headsets + - ALSA: sb: Fix potential ABBA deadlock in CSP driver + - ALSA: hdmi: Expose all pins on MSI MS-7C94 board + - xhci: Fix lost USB 2 remote wake + - KVM: PPC: Book3S: Fix H_RTAS rets buffer overflow + - KVM: PPC: Book3S HV Nested: Sanitise H_ENTER_NESTED TM state + - usb: hub: Disable USB 3 device initiated lpm if exit latency is too high + - usb: hub: Fix link power management max exit latency (MEL) calculations + - USB: usb-storage: Add LaCie Rugged USB3-FW to IGNORE_UAS + - usb: max-3421: Prevent corruption of freed memory + - usb: renesas_usbhs: Fix superfluous irqs happen after usb_pkt_pop() + - USB: serial: option: add support for u-blox LARA-R6 family + - USB: serial: cp210x: fix comments for GE CS1000 + - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + - usb: dwc2: gadget: Fix sending zero length packet in DDMA mode. + - firmware/efi: Tell memblock about EFI iomem reservations + - tracing/histogram: Rename "cpu" to "common_cpu" + - tracing: Fix bug in rb_per_cpu_empty() that might cause deadloop. + - btrfs: check for missing device in btrfs_trim_fs + - media: ngene: Fix out-of-bounds bug in ngene_command_config_free_buf() + - ixgbe: Fix packet corruption due to missing DMA sync + - selftest: use mmap instead of posix_memalign to allocate memory + - userfaultfd: do not untag user pointers + - hugetlbfs: fix mount mode command line processing + - rbd: don't hold lock_rwsem while running_list is being drained + - rbd: always kick acquire on "acquired" and "released" notifications + - nds32: fix up stack guard gap + - drm: Return -ENOTTY for non-drm ioctls + - net: dsa: mv88e6xxx: use correct .stats_set_histogram() on Topaz + - net: bcmgenet: ensure EXT_ENERGY_DET_MASK is clear + - iio: accel: bma180: Use explicit member assignment + - iio: accel: bma180: Fix BMA25x bandwidth register values + - btrfs: compression: don't try to compress if we don't have enough pages + - PCI: Mark AMD Navi14 GPU ATS as broken + - perf inject: Close inject.output on exit + - xhci: add xhci_get_virt_ep() helper + - Linux 5.4.136 + * Focal update: v5.4.135 upstream stable release (LP: #1939442) + - ARM: dts: gemini: rename mdio to the right name + - ARM: dts: gemini: add device_type on pci + - ARM: dts: rockchip: fix pinctrl sleep nodename for rk3036-kylin and rk3288 + - arm64: dts: rockchip: fix pinctrl sleep nodename for rk3399.dtsi + - ARM: dts: rockchip: Fix the timer clocks order + - ARM: dts: rockchip: Fix IOMMU nodes properties on rk322x + - ARM: dts: rockchip: Fix power-controller node names for rk3066a + - ARM: dts: rockchip: Fix power-controller node names for rk3188 + - ARM: dts: rockchip: Fix power-controller node names for rk3288 + - arm64: dts: rockchip: Fix power-controller node names for px30 + - arm64: dts: rockchip: Fix power-controller node names for rk3328 + - reset: ti-syscon: fix to_ti_syscon_reset_data macro + - ARM: brcmstb: dts: fix NAND nodes names + - ARM: Cygnus: dts: fix NAND nodes names + - ARM: NSP: dts: fix NAND nodes names + - ARM: dts: BCM63xx: Fix NAND nodes names + - ARM: dts: Hurricane 2: Fix NAND nodes names + - ARM: dts: imx6: phyFLEX: Fix UART hardware flow control + - ARM: imx: pm-imx5: Fix references to imx5_cpu_suspend_info + - rtc: mxc_v2: add missing MODULE_DEVICE_TABLE + - kbuild: sink stdout from cmd for silent build + - ARM: dts: am57xx-cl-som-am57x: fix ti,no-reset-on-init flag for gpios + - ARM: dts: am437x-gp-evm: fix ti,no-reset-on-init flag for gpios + - ARM: dts: stm32: fix gpio-keys node on STM32 MCU boards + - ARM: dts: stm32: fix RCC node name on stm32f429 MCU + - ARM: dts: stm32: fix timer nodes on STM32 MCU to prevent warnings + - arm64: dts: juno: Update SCPI nodes as per the YAML schema + - ARM: dts: rockchip: fix supply properties in io-domains nodes + - ARM: dts: stm32: fix i2c node name on stm32f746 to prevent warnings + - ARM: dts: stm32: move stmmac axi config in ethernet node on stm32mp15 + - soc/tegra: fuse: Fix Tegra234-only builds + - firmware: tegra: bpmp: Fix Tegra234-only builds + - arm64: dts: ls208xa: remove bus-num from dspi node + - arm64: dts: imx8mq: assign PCIe clocks + - thermal/core: Correct function name thermal_zone_device_unregister() + - kbuild: mkcompile_h: consider timestamp if KBUILD_BUILD_TIMESTAMP is set + - rtc: max77686: Do not enforce (incorrect) interrupt trigger type + - scsi: aic7xxx: Fix unintentional sign extension issue on left shift of u8 + - scsi: libsas: Add LUN number check in .slave_alloc callback + - scsi: libfc: Fix array index out of bound exception + - scsi: qedf: Add check to synchronize abort and flush + - sched/fair: Fix CFS bandwidth hrtimer expiry type + - s390: introduce proper type handling call_on_stack() macro + - cifs: prevent NULL deref in cifs_compose_mount_options() + - arm64: dts: armada-3720-turris-mox: add firmware node + - firmware: turris-mox-rwtm: add marvell,armada-3700-rwtm-firmware compatible + string + - arm64: dts: marvell: armada-37xx: move firmware node to generic dtsi file + - f2fs: Show casefolding support only when supported + - usb: cdns3: Enable TDL_CHK only for OUT ep + - Revert "UBUNTU: SAUCE: Revert "mm: memcg/slab: fix memory leak at non-root + kmem_cache destroy"" + - mm: slab: fix kmem_cache_create failed when sysfs node not destroyed + - dm writecache: return the exact table values that were set + - net: dsa: mv88e6xxx: enable .port_set_policy() on Topaz + - net: dsa: mv88e6xxx: enable .rmu_disable() on Topaz + - net: ipv6: fix return value of ip6_skb_dst_mtu + - netfilter: ctnetlink: suspicious RCU usage in ctnetlink_dump_helpinfo + - net/sched: act_ct: fix err check for nf_conntrack_confirm + - net: bridge: sync fdb to new unicast-filtering ports + - net: bcmgenet: Ensure all TX/RX queues DMAs are disabled + - net: ip_tunnel: fix mtu calculation for ETHER tunnel devices + - net: moxa: fix UAF in moxart_mac_probe + - net: qcom/emac: fix UAF in emac_remove + - net: ti: fix UAF in tlan_remove_one + - net: send SYNACK packet with accepted fwmark + - net: validate lwtstate->data before returning from skb_tunnel_info() + - net: fddi: fix UAF in fza_probe + - dma-buf/sync_file: Don't leak fences on merge failure + - tcp: annotate data races around tp->mtu_info + - ipv6: tcp: drop silly ICMPv6 packet too big messages + - bpftool: Properly close va_list 'ap' by va_end() on error + - perf test bpf: Free obj_buf + - udp: annotate data races around unix_sk(sk)->gso_size + - Linux 5.4.135 + * Focal update: v5.4.134 upstream stable release (LP: #1939440) + - KVM: mmio: Fix use-after-free Read in kvm_vm_ioctl_unregister_coalesced_mmio + - KVM: x86: Use guest MAXPHYADDR from CPUID.0x8000_0008 iff TDP is enabled + - KVM: X86: Disable hardware breakpoints unconditionally before kvm_x86->run() + - scsi: core: Fix bad pointer dereference when ehandler kthread is invalid + - tracing: Do not reference char * as a string in histograms + - cgroup: verify that source is a string + - fbmem: Do not delete the mode that is still in use + - net: moxa: Use devm_platform_get_and_ioremap_resource() + - dmaengine: fsl-qdma: check dma_set_mask return value + - srcu: Fix broken node geometry after early ssp init + - tty: serial: fsl_lpuart: fix the potential risk of division or modulo by + zero + - misc/libmasm/module: Fix two use after free in ibmasm_init_one + - misc: alcor_pci: fix null-ptr-deref when there is no PCI bridge + - iio: gyro: fxa21002c: Balance runtime pm + use pm_runtime_resume_and_get(). + - iio: magn: bmc150: Balance runtime pm + use pm_runtime_resume_and_get() + - ALSA: usx2y: Don't call free_pages_exact() with NULL address + - Revert "ALSA: bebob/oxfw: fix Kconfig entry for Mackie d.2 Pro" + - w1: ds2438: fixing bug that would always get page0 + - scsi: hisi_sas: Propagate errors in interrupt_init_v1_hw() + - scsi: lpfc: Fix "Unexpected timeout" error in direct attach topology + - scsi: lpfc: Fix crash when lpfc_sli4_hba_setup() fails to initialize the + SGLs + - scsi: core: Cap scsi_host cmd_per_lun at can_queue + - ALSA: ac97: fix PM reference leak in ac97_bus_remove() + - tty: serial: 8250: serial_cs: Fix a memory leak in error handling path + - scsi: scsi_dh_alua: Check for negative result value + - fs/jfs: Fix missing error code in lmLogInit() + - scsi: megaraid_sas: Fix resource leak in case of probe failure + - scsi: megaraid_sas: Early detection of VD deletion through RaidMap update + - scsi: megaraid_sas: Handle missing interrupts while re-enabling IRQs + - scsi: iscsi: Add iscsi_cls_conn refcount helpers + - scsi: iscsi: Fix conn use after free during resets + - scsi: iscsi: Fix shost->max_id use + - scsi: qedi: Fix null ref during abort handling + - mfd: da9052/stmpe: Add and modify MODULE_DEVICE_TABLE + - mfd: cpcap: Fix cpcap dmamask not set warnings + - ASoC: img: Fix PM reference leak in img_i2s_in_probe() + - serial: tty: uartlite: fix console setup + - s390/sclp_vt220: fix console name to match device + - ALSA: sb: Fix potential double-free of CSP mixer elements + - powerpc/ps3: Add dma_mask to ps3_dma_region + - iommu/arm-smmu: Fix arm_smmu_device refcount leak when arm_smmu_rpm_get + fails + - iommu/arm-smmu: Fix arm_smmu_device refcount leak in address translation + - gpio: zynq: Check return value of pm_runtime_get_sync + - ALSA: ppc: fix error return code in snd_pmac_probe() + - selftests/powerpc: Fix "no_handler" EBB selftest + - gpio: pca953x: Add support for the On Semi pca9655 + - ASoC: soc-core: Fix the error return code in + snd_soc_of_parse_audio_routing() + - s390/processor: always inline stap() and __load_psw_mask() + - s390/ipl_parm: fix program check new psw handling + - s390/mem_detect: fix diag260() program check new psw handling + - s390/mem_detect: fix tprot() program check new psw handling + - Input: hideep - fix the uninitialized use in hideep_nvm_unlock() + - ALSA: bebob: add support for ToneWeal FW66 + - ALSA: usb-audio: scarlett2: Fix 18i8 Gen 2 PCM Input count + - ALSA: usb-audio: scarlett2: Fix data_mutex lock + - ALSA: usb-audio: scarlett2: Fix scarlett2_*_ctl_put() return values + - usb: gadget: f_hid: fix endianness issue with descriptors + - usb: gadget: hid: fix error return code in hid_bind() + - powerpc/boot: Fixup device-tree on little endian + - ASoC: Intel: kbl_da7219_max98357a: shrink platform_id below 20 characters + - backlight: lm3630a: Fix return code of .update_status() callback + - ALSA: hda: Add IRQ check for platform_get_irq() + - ALSA: usb-audio: scarlett2: Fix 6i6 Gen 2 line out descriptions + - staging: rtl8723bs: fix macro value for 2.4Ghz only device + - intel_th: Wait until port is in reset before programming it + - i2c: core: Disable client irq on reboot/shutdown + - power: supply: sc27xx: Add missing MODULE_DEVICE_TABLE + - power: supply: sc2731_charger: Add missing MODULE_DEVICE_TABLE + - pwm: spear: Don't modify HW state in .remove callback + - power: supply: ab8500: Avoid NULL pointers + - power: supply: max17042: Do not enforce (incorrect) interrupt trigger type + - power: reset: gpio-poweroff: add missing MODULE_DEVICE_TABLE + - ARM: 9087/1: kprobes: test-thumb: fix for LLVM_IAS=1 + - PCI/P2PDMA: Avoid pci_get_slot(), which may sleep + - watchdog: Fix possible use-after-free in wdt_startup() + - watchdog: sc520_wdt: Fix possible use-after-free in wdt_turnoff() + - watchdog: Fix possible use-after-free by calling del_timer_sync() + - watchdog: imx_sc_wdt: fix pretimeout + - x86/fpu: Return proper error codes from user access functions + - PCI: tegra: Add missing MODULE_DEVICE_TABLE + - orangefs: fix orangefs df output. + - ceph: remove bogus checks and WARN_ONs from ceph_set_page_dirty + - NFS: nfs_find_open_context() may only select open files + - power: supply: charger-manager: add missing MODULE_DEVICE_TABLE + - power: supply: ab8500: add missing MODULE_DEVICE_TABLE + - pwm: img: Fix PM reference leak in img_pwm_enable() + - pwm: tegra: Don't modify HW state in .remove callback + - ACPI: AMBA: Fix resource name in /proc/iomem + - ACPI: video: Add quirk for the Dell Vostro 3350 + - virtio-blk: Fix memory leak among suspend/resume procedure + - virtio_net: Fix error handling in virtnet_restore() + - virtio_console: Assure used length from device is limited + - x86/signal: Detect and prevent an alternate signal stack overflow + - f2fs: add MODULE_SOFTDEP to ensure crc32 is included in the initramfs + - PCI/sysfs: Fix dsm_label_utf16s_to_utf8s() buffer overrun + - power: supply: rt5033_battery: Fix device tree enumeration + - NFSv4: Initialise connection to the server in nfs4_alloc_client() + - um: fix error return code in slip_open() + - um: fix error return code in winch_tramp() + - watchdog: aspeed: fix hardware timeout calculation + - nfs: fix acl memory leak of posix_acl_create() + - ubifs: Set/Clear I_LINKABLE under i_lock for whiteout inode + - PCI: iproc: Fix multi-MSI base vector number allocation + - PCI: iproc: Support multi-MSI only on uniprocessor kernel + - x86/fpu: Limit xstate copy size in xstateregs_set() + - pwm: imx1: Don't disable clocks at device remove time + - virtio_net: move tx vq operation under tx queue lock + - nvme-tcp: can't set sk_user_data without write_lock + - ALSA: isa: Fix error return code in snd_cmi8330_probe() + - NFSv4/pNFS: Don't call _nfs4_pnfs_v3_ds_connect multiple times + - hexagon: use common DISCARDS macro + - ARM: dts: gemini-rut1xx: remove duplicate ethernet node + - reset: a10sr: add missing of_match_table reference + - ARM: exynos: add missing of_node_put for loop iteration + - ARM: dts: exynos: fix PWM LED max brightness on Odroid XU/XU3 + - ARM: dts: exynos: fix PWM LED max brightness on Odroid HC1 + - ARM: dts: exynos: fix PWM LED max brightness on Odroid XU4 + - memory: atmel-ebi: add missing of_node_put for loop iteration + - reset: brcmstb: Add missing MODULE_DEVICE_TABLE + - memory: pl353: Fix error return code in pl353_smc_probe() + - rtc: fix snprintf() checking in is_rtc_hctosys() + - arm64: dts: renesas: v3msk: Fix memory size + - ARM: dts: r8a7779, marzen: Fix DU clock names + - firmware: tegra: Fix error return code in tegra210_bpmp_init() + - firmware: arm_scmi: Reset Rx buffer to max size during async commands + - ARM: dts: BCM5301X: Fixup SPI binding + - reset: bail if try_module_get() fails + - memory: fsl_ifc: fix leak of IO mapping on probe failure + - memory: fsl_ifc: fix leak of private memory on probe failure + - ARM: dts: am335x: align ti,pindir-d0-out-d1-in property with dt-shema + - ARM: dts: am437x: align ti,pindir-d0-out-d1-in property with dt-shema + - ARM: dts: imx6q-dhcom: Fix ethernet reset time properties + - ARM: dts: imx6q-dhcom: Fix ethernet plugin detection problems + - ARM: dts: imx6q-dhcom: Add gpios pinctrl for i2c bus recovery + - thermal/drivers/rcar_gen3_thermal: Fix coefficient calculations + - firmware: turris-mox-rwtm: fix reply status decoding function + - firmware: turris-mox-rwtm: report failures better + - firmware: turris-mox-rwtm: fail probing when firmware does not support hwrng + - scsi: be2iscsi: Fix an error handling path in beiscsi_dev_probe() + - mips: always link byteswap helpers into decompressor + - mips: disable branch profiling in boot/decompress.o + - MIPS: vdso: Invalid GIC access through VDSO + - scsi: scsi_dh_alua: Fix signedness bug in alua_rtpg() + - misc: alcor_pci: fix inverted branch condition + - Linux 5.4.134 + + [ Ubuntu: 5.4.0-84.94 ] + + * focal/linux: 5.4.0-84.94 -proposed tracker (LP: #1941767) + * Server boot failure after adding checks for ACPI IRQ override (LP: #1941657) + - Revert "ACPI: resources: Add checks for ACPI IRQ override" + + -- Luke Nowakowski-Krijger Wed, 08 Sep 2021 10:52:18 -0700 + +linux-oracle (5.4.0-1054.58) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1054.58 -proposed tracker (LP: #1939790) + + * Focal update: v5.4.129 upstream stable release (LP: #1936242) + - [Config] oracle: enable CONFIG_SYSTEM_REVOCATION_LIST + + [ Ubuntu: 5.4.0-83.93 ] + + * focal/linux: 5.4.0-83.93 -proposed tracker (LP: #1940159) + * fails to launch linux L2 guests on AMD (LP: #1940134) // CVE-2021-3653 + - KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl + (CVE-2021-3653) + * fails to launch linux L2 guests on AMD (LP: #1940134) + - SAUCE: Revert "UBUNTU: SAUCE: KVM: nSVM: avoid picking up unsupported bits + from L2 in int_ctl" + + [ Ubuntu: 5.4.0-82.92 ] + + * focal/linux: 5.4.0-82.92 -proposed tracker (LP: #1939799) + * Packaging resync (LP: #1786013) + - debian/dkms-versions -- update from kernel-versions (main/2021.08.16) + * CVE-2021-3656 + - SAUCE: KVM: nSVM: always intercept VMLOAD/VMSAVE when nested + * CVE-2021-3653 + - SAUCE: KVM: nSVM: avoid picking up unsupported bits from L2 in int_ctl + * [regression] USB device is not detected during boot (LP: #1939638) + - SAUCE: Revert "usb: core: reduce power-on-good delay time of root hub" + * dev_forward_skb: do not scrub skb mark within the same name space + (LP: #1935040) + - dev_forward_skb: do not scrub skb mark within the same name space + * XPS 9510 (TGL) Screen Brightness could not be changed (LP: #1933566) + - SAUCE: drm/i915: Force DPCD backlight mode for Dell XPS 9510(TGL) + * Acer Aspire 5 sound driver issues (LP: #1930188) + - ALSA: hda/realtek: headphone and mic don't work on an Acer laptop + * Sony Dualshock 4 usb dongle crashes the whole system (LP: #1935846) + - HID: sony: Workaround for DS4 dongle hotplug kernel crash. + * [21.10 FEAT] KVM: Provide a secure guest indication (LP: #1933173) + - s390/uv: add prot virt guest/host indication files + - s390/uv: fix prot virt host indication compilation + * Skip rtcpie test in kselftests/timers if the default RTC device does not + exist (LP: #1937991) + - selftests: timers: rtcpie: skip test if default RTC device does not exist + * Focal update: v5.4.133 upstream stable release (LP: #1938713) + - drm/mxsfb: Don't select DRM_KMS_FB_HELPER + - drm/zte: Don't select DRM_KMS_FB_HELPER + - drm/amd/amdgpu/sriov disable all ip hw status by default + - drm/vc4: fix argument ordering in vc4_crtc_get_margins() + - net: pch_gbe: Use proper accessors to BE data in pch_ptp_match() + - drm/amd/display: fix use_max_lb flag for 420 pixel formats + - hugetlb: clear huge pte during flush function on mips platform + - atm: iphase: fix possible use-after-free in ia_module_exit() + - mISDN: fix possible use-after-free in HFC_cleanup() + - atm: nicstar: Fix possible use-after-free in nicstar_cleanup() + - net: Treat __napi_schedule_irqoff() as __napi_schedule() on PREEMPT_RT + - drm/mediatek: Fix PM reference leak in mtk_crtc_ddp_hw_init() + - reiserfs: add check for invalid 1st journal block + - drm/virtio: Fix double free on probe failure + - drm/sched: Avoid data corruptions + - udf: Fix NULL pointer dereference in udf_symlink function + - e100: handle eeprom as little endian + - igb: handle vlan types with checker enabled + - drm/bridge: cdns: Fix PM reference leak in cdns_dsi_transfer() + - clk: renesas: r8a77995: Add ZA2 clock + - clk: tegra: Ensure that PLLU configuration is applied properly + - ipv6: use prandom_u32() for ID generation + - RDMA/cxgb4: Fix missing error code in create_qp() + - dm space maps: don't reset space map allocation cursor when committing + - pinctrl: mcp23s08: fix race condition in irq handler + - ice: set the value of global config lock timeout longer + - virtio_net: Remove BUG() to avoid machine dead + - net: bcmgenet: check return value after calling platform_get_resource() + - net: mvpp2: check return value after calling platform_get_resource() + - net: micrel: check return value after calling platform_get_resource() + - drm/amd/display: Update scaling settings on modeset + - drm/amd/display: Release MST resources on switch from MST to SST + - drm/amd/display: Set DISPCLK_MAX_ERRDET_CYCLES to 7 + - drm/amdkfd: use allowed domain for vmbo validation + - fjes: check return value after calling platform_get_resource() + - selinux: use __GFP_NOWARN with GFP_NOWAIT in the AVC + - r8169: avoid link-up interrupt issue on RTL8106e if user enables ASPM + - drm/amd/display: Verify Gamma & Degamma LUT sizes in amdgpu_dm_atomic_check + - xfrm: Fix error reporting in xfrm_state_construct. + - wlcore/wl12xx: Fix wl12xx get_mac error if device is in ELP + - wl1251: Fix possible buffer overflow in wl1251_cmd_scan + - cw1200: add missing MODULE_DEVICE_TABLE + - bpf: Fix up register-based shifts in interpreter to silence KUBSAN + - mt76: mt7615: fix fixed-rate tx status reporting + - net: fix mistake path for netdev_features_strings + - net: sched: fix error return code in tcf_del_walker() + - drm/amdkfd: Walk through list with dqm lock hold + - rtl8xxxu: Fix device info for RTL8192EU devices + - atm: nicstar: use 'dma_free_coherent' instead of 'kfree' + - atm: nicstar: register the interrupt handler in the right place + - vsock: notify server to shutdown when client has pending signal + - RDMA/rxe: Don't overwrite errno from ib_umem_get() + - iwlwifi: mvm: don't change band on bound PHY contexts + - iwlwifi: pcie: free IML DMA memory allocation + - iwlwifi: pcie: fix context info freeing + - sfc: avoid double pci_remove of VFs + - sfc: error code if SRIOV cannot be disabled + - wireless: wext-spy: Fix out-of-bounds warning + - media, bpf: Do not copy more entries than user space requested + - net: ip: avoid OOM kills with large UDP sends over loopback + - RDMA/cma: Fix rdma_resolve_route() memory leak + - Bluetooth: btusb: Fixed too many in-token issue for Mediatek Chip. + - Bluetooth: Fix the HCI to MGMT status conversion table + - Bluetooth: Shutdown controller after workqueues are flushed or cancelled + - Bluetooth: btusb: fix bt fiwmare downloading failure issue for qca btsoc. + - sctp: validate from_addr_param return + - sctp: add size validation when walking chunks + - MIPS: loongsoon64: Reserve memory below starting pfn to prevent Oops + - MIPS: set mips32r5 for virt extensions + - fscrypt: don't ignore minor_hash when hash is 0 + - crypto: ccp - Annotate SEV Firmware file names + - perf bench: Fix 2 memory sanitizer warnings + - powerpc/mm: Fix lockup on kernel exec fault + - powerpc/barrier: Avoid collision with clang's __lwsync macro + - drm/amdgpu: Update NV SIMD-per-CU to 2 + - drm/radeon: Add the missed drm_gem_object_put() in + radeon_user_framebuffer_create() + - drm/rockchip: dsi: remove extra component_del() call + - drm/amd/display: fix incorrrect valid irq check + - pinctrl/amd: Add device HID for new AMD GPIO controller + - drm/tegra: Don't set allow_fb_modifiers explicitly + - drm/msm/mdp4: Fix modifier support enabling + - drm/arm/malidp: Always list modifiers + - mmc: sdhci: Fix warning message when accessing RPMB in HS400 mode + - mmc: core: clear flags before allowing to retune + - mmc: core: Allow UHS-I voltage switch for SDSC cards if supported + - ata: ahci_sunxi: Disable DIPM + - cpu/hotplug: Cure the cpusets trainwreck + - clocksource/arm_arch_timer: Improve Allwinner A64 timer workaround + - fpga: stratix10-soc: Add missing fpga_mgr_free() call + - MIPS: fix "mipsel-linux-ld: decompress.c:undefined reference to `memmove'" + - ASoC: tegra: Set driver_name=tegra for all machine drivers + - qemu_fw_cfg: Make fw_cfg_rev_attr a proper kobj_attribute + - ipmi/watchdog: Stop watchdog timer when the current action is 'none' + - thermal/drivers/int340x/processor_thermal: Fix tcc setting + - ubifs: Fix races between xattr_{set|get} and listxattr operations + - power: supply: ab8500: Fix an old bug + - nvmem: core: add a missing of_node_put + - extcon: intel-mrfld: Sync hardware and software state on init + - seq_buf: Fix overflow in seq_buf_putmem_hex() + - rq-qos: fix missed wake-ups in rq_qos_throttle try two + - tracing: Simplify & fix saved_tgids logic + - tracing: Resize tgid_map to pid_max, not PID_MAX_DEFAULT + - ipack/carriers/tpci200: Fix a double free in tpci200_pci_probe + - coresight: tmc-etf: Fix global-out-of-bounds in tmc_update_etf_buffer() + - dm btree remove: assign new_root only when removal succeeds + - PCI: Leave Apple Thunderbolt controllers on for s2idle or standby + - PCI: aardvark: Fix checking for PIO Non-posted Request + - PCI: aardvark: Implement workaround for the readback value of VEND_ID + - media: subdev: disallow ioctl for saa6588/davinci + - media: dtv5100: fix control-request directions + - media: zr364xx: fix memory leak in zr364xx_start_readpipe + - media: gspca/sq905: fix control-request direction + - media: gspca/sunplus: fix zero-length control requests + - pinctrl: mcp23s08: Fix missing unlock on error in mcp23s08_irq() + - jfs: fix GPF in diFree + - smackfs: restrict bytes count in smk_set_cipso() + - Linux 5.4.133 + * Focal update: v5.4.132 upstream stable release (LP: #1938199) + - ALSA: usb-audio: fix rate on Ozone Z90 USB headset + - ALSA: usb-audio: Fix OOB access at proc output + - ALSA: usb-audio: scarlett2: Fix wrong resume call + - ALSA: intel8x0: Fix breakage at ac97 clock measurement + - ALSA: hda/realtek: Add another ALC236 variant support + - ALSA: hda/realtek: Improve fixup for HP Spectre x360 15-df0xxx + - ALSA: hda/realtek: Fix bass speaker DAC mapping for Asus UM431D + - ALSA: hda/realtek: Apply LED fixup for HP Dragonfly G1, too + - media: dvb-usb: fix wrong definition + - Input: usbtouchscreen - fix control-request directions + - net: can: ems_usb: fix use-after-free in ems_usb_disconnect() + - usb: gadget: eem: fix echo command packet response issue + - USB: cdc-acm: blacklist Heimann USB Appset device + - usb: dwc3: Fix debugfs creation flow + - usb: typec: Add the missed altmode_id_remove() in typec_register_altmode() + - xhci: solve a double free problem while doing s4 + - ntfs: fix validity check for file name attribute + - copy_page_to_iter(): fix ITER_DISCARD case + - iov_iter_fault_in_readable() should do nothing in xarray case + - Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl + - arm_pmu: Fix write counter incorrect in ARMv7 big-endian mode + - ARM: dts: at91: sama5d4: fix pinctrl muxing + - btrfs: send: fix invalid path for unlink operations after parent + orphanization + - btrfs: clear defrag status of a root if starting transaction fails + - ext4: cleanup in-core orphan list if ext4_truncate() failed to get a + transaction handle + - ext4: fix kernel infoleak via ext4_extent_header + - ext4: return error code when ext4_fill_flex_info() fails + - ext4: correct the cache_nr in tracepoint ext4_es_shrink_exit + - ext4: remove check for zero nr_to_scan in ext4_es_scan() + - ext4: fix avefreec in find_group_orlov + - ext4: use ext4_grp_locked_error in mb_find_extent + - can: gw: synchronize rcu operations before removing gw job entry + - can: j1939: j1939_sk_init(): set SOCK_RCU_FREE to call sk_destruct() after + RCU is done + - can: peak_pciefd: pucan_handle_status(): fix a potential starvation issue in + TX path + - mac80211: remove iwlwifi specific workaround that broke sta NDP tx + - SUNRPC: Fix the batch tasks count wraparound. + - SUNRPC: Should wake up the privileged task firstly. + - perf/smmuv3: Don't trample existing events with global filter + - KVM: PPC: Book3S HV: Workaround high stack usage with clang + - s390/cio: dont call css_wait_for_slow_path() inside a lock + - rtc: stm32: Fix unbalanced clk_disable_unprepare() on probe error path + - iio: light: tcs3472: do not free unallocated IRQ + - iio: ltr501: mark register holding upper 8 bits of ALS_DATA{0,1} and PS_DATA + as volatile, too + - iio: ltr501: ltr559: fix initialization of LTR501_ALS_CONTR + - iio: ltr501: ltr501_read_ps(): add missing endianness conversion + - serial: mvebu-uart: fix calculation of clock divisor + - serial: sh-sci: Stop dmaengine transfer in sci_stop_tx() + - serial_cs: Add Option International GSM-Ready 56K/ISDN modem + - serial_cs: remove wrong GLOBETROTTER.cis entry + - ath9k: Fix kernel NULL pointer dereference during ath_reset_internal() + - ssb: sdio: Don't overwrite const buffer if block_write fails + - rsi: Assign beacon rate settings to the correct rate_info descriptor field + - rsi: fix AP mode with WPA failure due to encrypted EAPOL + - tracing/histograms: Fix parsing of "sym-offset" modifier + - tracepoint: Add tracepoint_probe_register_may_exist() for BPF tracing + - seq_buf: Make trace_seq_putmem_hex() support data longer than 8 + - powerpc/stacktrace: Fix spurious "stale" traces in raise_backtrace_ipi() + - evm: Execute evm_inode_init_security() only when an HMAC key is loaded + - evm: Refuse EVM_ALLOW_METADATA_WRITES only if an HMAC key is loaded + - fuse: ignore PG_workingset after stealing + - fuse: check connected before queueing on fpq->io + - fuse: reject internal errno + - spi: Make of_register_spi_device also set the fwnode + - media: mdk-mdp: fix pm_runtime_get_sync() usage count + - media: s5p: fix pm_runtime_get_sync() usage count + - media: sh_vou: fix pm_runtime_get_sync() usage count + - media: mtk-vcodec: fix PM runtime get logic + - media: s5p-jpeg: fix pm_runtime_get_sync() usage count + - media: sti/bdisp: fix pm_runtime_get_sync() usage count + - media: exynos-gsc: fix pm_runtime_get_sync() usage count + - spi: spi-loopback-test: Fix 'tx_buf' might be 'rx_buf' + - spi: spi-topcliff-pch: Fix potential double free in + pch_spi_process_messages() + - spi: omap-100k: Fix the length judgment problem + - regulator: uniphier: Add missing MODULE_DEVICE_TABLE + - hwrng: exynos - Fix runtime PM imbalance on error + - crypto: nx - add missing MODULE_DEVICE_TABLE + - media: sti: fix obj-$(config) targets + - media: cpia2: fix memory leak in cpia2_usb_probe + - media: cobalt: fix race condition in setting HPD + - media: pvrusb2: fix warning in pvr2_i2c_core_done + - media: imx: imx7_mipi_csis: Fix logging of only error event counters + - crypto: qat - check return code of qat_hal_rd_rel_reg() + - crypto: qat - remove unused macro in FW loader + - sched/fair: Fix ascii art by relpacing tabs + - media: em28xx: Fix possible memory leak of em28xx struct + - media: v4l2-core: Avoid the dangling pointer in v4l2_fh_release + - media: bt8xx: Fix a missing check bug in bt878_probe + - media: st-hva: Fix potential NULL pointer dereferences + - Makefile: fix GDB warning with CONFIG_RELR + - media: dvd_usb: memory leak in cinergyt2_fe_attach + - memstick: rtsx_usb_ms: fix UAF + - mmc: sdhci-sprd: use sdhci_sprd_writew + - mmc: via-sdmmc: add a check against NULL pointer dereference + - crypto: shash - avoid comparing pointers to exported functions under CFI + - media: dvb_net: avoid speculation from net slot + - media: siano: fix device register error path + - media: imx-csi: Skip first few frames from a BT.656 source + - hwmon: (max31790) Report correct current pwm duty cycles + - hwmon: (max31790) Fix pwmX_enable attributes + - drivers/perf: fix the missed ida_simple_remove() in ddr_perf_probe() + - KVM: PPC: Book3S HV: Fix TLB management on SMT8 POWER9 and POWER10 + processors + - btrfs: fix error handling in __btrfs_update_delayed_inode + - btrfs: abort transaction if we fail to update the delayed inode + - btrfs: disable build on platforms having page size 256K + - locking/lockdep: Fix the dep path printing for backwards BFS + - lockding/lockdep: Avoid to find wrong lock dep path in check_irq_usage() + - KVM: s390: get rid of register asm usage + - regulator: mt6358: Fix vdram2 .vsel_mask + - regulator: da9052: Ensure enough delay time for .set_voltage_time_sel + - media: Fix Media Controller API config checks + - HID: do not use down_interruptible() when unbinding devices + - EDAC/ti: Add missing MODULE_DEVICE_TABLE + - ACPI: processor idle: Fix up C-state latency if not ordered + - hv_utils: Fix passing zero to 'PTR_ERR' warning + - lib: vsprintf: Fix handling of number field widths in vsscanf + - ACPI: EC: Make more Asus laptops use ECDT _GPE + - block_dump: remove block_dump feature in mark_inode_dirty() + - fs: dlm: cancel work sync othercon + - random32: Fix implicit truncation warning in prandom_seed_state() + - fs: dlm: fix memory leak when fenced + - ACPICA: Fix memory leak caused by _CID repair function + - ACPI: bus: Call kobject_put() in acpi_init() error path + - block: fix race between adding/removing rq qos and normal IO + - platform/x86: toshiba_acpi: Fix missing error code in + toshiba_acpi_setup_keyboard() + - nvmet-fc: do not check for invalid target port in nvmet_fc_handle_fcp_rqst() + - EDAC/Intel: Do not load EDAC driver when running as a guest + - PCI: hv: Add check for hyperv_initialized in init_hv_pci_drv() + - clocksource: Retry clock read if long delays detected + - ACPI: tables: Add custom DSDT file as makefile prerequisite + - HID: wacom: Correct base usage for capacitive ExpressKey status bits + - cifs: fix missing spinlock around update to ses->status + - block: fix discard request merge + - kthread_worker: fix return value when kthread_mod_delayed_work() races with + kthread_cancel_delayed_work_sync() + - ia64: mca_drv: fix incorrect array size calculation + - writeback, cgroup: increment isw_nr_in_flight before grabbing an inode + - media: s5p_cec: decrement usage count if disabled + - crypto: ixp4xx - dma_unmap the correct address + - crypto: ux500 - Fix error return code in hash_hw_final() + - sata_highbank: fix deferred probing + - pata_rb532_cf: fix deferred probing + - media: I2C: change 'RST' to "RSET" to fix multiple build errors + - sched/uclamp: Fix wrong implementation of cpu.uclamp.min + - sched/uclamp: Fix locking around cpu_util_update_eff() + - kbuild: run the checker after the compiler + - kbuild: Fix objtool dependency for 'OBJECT_FILES_NON_STANDARD_ := n' + - pata_octeon_cf: avoid WARN_ON() in ata_host_activate() + - evm: fix writing /evm overflow + - crypto: ccp - Fix a resource leak in an error handling path + - media: rc: i2c: Fix an error message + - pata_ep93xx: fix deferred probing + - media: exynos4-is: Fix a use after free in isp_video_release + - media: au0828: fix a NULL vs IS_ERR() check + - media: tc358743: Fix error return code in tc358743_probe_of() + - media: gspca/gl860: fix zero-length control requests + - m68k: atari: Fix ATARI_KBD_CORE kconfig unmet dependency warning + - media: siano: Fix out-of-bounds warnings in smscore_load_firmware_family2() + - crypto: nitrox - fix unchecked variable in nitrox_register_interrupts + - crypto: omap-sham - Fix PM reference leak in omap sham ops + - mmc: usdhi6rol0: fix error return code in usdhi6_probe() + - arm64: consistently use reserved_pg_dir + - arm64/mm: Fix ttbr0 values stored in struct thread_info for software-pan + - media: s5p-g2d: Fix a memory leak on ctx->fh.m2m_ctx + - hwmon: (max31722) Remove non-standard ACPI device IDs + - hwmon: (max31790) Fix fan speed reporting for fan7..12 + - KVM: nVMX: Ensure 64-bit shift when checking VMFUNC bitmap + - regulator: hi655x: Fix pass wrong pointer to config.driver_data + - btrfs: clear log tree recovering status if starting transaction fails + - sched/rt: Fix RT utilization tracking during policy change + - sched/rt: Fix Deadline utilization tracking during policy change + - sched/uclamp: Fix uclamp_tg_restrict() + - spi: spi-sun6i: Fix chipselect/clock bug + - crypto: nx - Fix RCU warning in nx842_OF_upd_status + - ACPI: sysfs: Fix a buffer overrun problem with description_show() + - extcon: extcon-max8997: Fix IRQ freeing at error path + - blk-wbt: introduce a new disable state to prevent false positive by + rwb_enabled() + - blk-wbt: make sure throttle is enabled properly + - ACPI: Use DEVICE_ATTR_ macros + - ACPI: bgrt: Fix CFI violation + - cpufreq: Make cpufreq_online() call driver->offline() on errors + - ocfs2: fix snprintf() checking + - dax: fix ENOMEM handling in grab_mapping_entry() + - xfrm: xfrm_state_mtu should return at least 1280 for ipv6 + - video: fbdev: imxfb: Fix an error message + - net: mvpp2: Put fwnode in error case during ->probe() + - net: pch_gbe: Propagate error from devm_gpio_request_one() + - pinctrl: renesas: r8a7796: Add missing bias for PRESET# pin + - pinctrl: renesas: r8a77990: JTAG pins do not have pull-down capabilities + - clk: meson: g12a: fix gp0 and hifi ranges + - net: ftgmac100: add missing error return code in ftgmac100_probe() + - drm/rockchip: cdn-dp-core: add missing clk_disable_unprepare() on error in + cdn_dp_grf_write() + - drm/rockchip: dsi: move all lane config except LCDC mux to bind() + - ehea: fix error return code in ehea_restart_qps() + - net/sched: act_vlan: Fix modify to allow 0 + - RDMA/core: Sanitize WQ state received from the userspace + - RDMA/rxe: Fix failure during driver load + - drm: qxl: ensure surf.data is ininitialized + - tools/bpftool: Fix error return code in do_batch() + - ath10k: go to path err_unsupported when chip id is not supported + - ath10k: add missing error return code in ath10k_pci_probe() + - wireless: carl9170: fix LEDS build errors & warnings + - ieee802154: hwsim: Fix possible memory leak in hwsim_subscribe_all_others + - wcn36xx: Move hal_buf allocation to devm_kmalloc in probe + - ssb: Fix error return code in ssb_bus_scan() + - brcmfmac: fix setting of station info chains bitmask + - brcmfmac: correctly report average RSSI in station info + - brcmsmac: mac80211_if: Fix a resource leak in an error handling path + - ath10k: Fix an error code in ath10k_add_interface() + - netlabel: Fix memory leak in netlbl_mgmt_add_common + - RDMA/mlx5: Don't add slave port to unaffiliated list + - netfilter: nft_exthdr: check for IPv6 packet before further processing + - netfilter: nft_osf: check for TCP packet before further processing + - netfilter: nft_tproxy: restrict support to TCP and UDP transport protocols + - RDMA/rxe: Fix qp reference counting for atomic ops + - samples/bpf: Fix the error return code of xdp_redirect's main() + - net: ethernet: aeroflex: fix UAF in greth_of_remove + - net: ethernet: ezchip: fix UAF in nps_enet_remove + - net: ethernet: ezchip: fix error handling + - vrf: do not push non-ND strict packets with a source LLA through packet taps + again + - net: sched: add barrier to ensure correct ordering for lockless qdisc + - tls: prevent oversized sendfile() hangs by ignoring MSG_MORE + - pkt_sched: sch_qfq: fix qfq_change_class() error path + - vxlan: add missing rcu_read_lock() in neigh_reduce() + - net/ipv4: swap flow ports when validating source + - tc-testing: fix list handling + - ieee802154: hwsim: Fix memory leak in hwsim_add_one + - ieee802154: hwsim: avoid possible crash in hwsim_del_edge_nl() + - mac80211: remove iwlwifi specific workaround NDPs of null_response + - net: bcmgenet: Fix attaching to PYH failed on RPi 4B + - ipv6: exthdrs: do not blindly use init_net + - bpf: Do not change gso_size during bpf_skb_change_proto() + - i40e: Fix error handling in i40e_vsi_open + - i40e: Fix autoneg disabling for non-10GBaseT links + - Revert "ibmvnic: remove duplicate napi_schedule call in open function" + - ibmvnic: free tx_pool if tso_pool alloc fails + - ipv6: fix out-of-bound access in ip6_parse_tlv() + - e1000e: Check the PCIm state + - bpfilter: Specify the log level for the kmsg message + - gve: Fix swapped vars when fetching max queues + - Revert "be2net: disable bh with spin_lock in be_process_mcc" + - Bluetooth: mgmt: Fix slab-out-of-bounds in tlv_data_is_valid + - Bluetooth: Fix handling of HCI_LE_Advertising_Set_Terminated event + - clk: actions: Fix UART clock dividers on Owl S500 SoC + - clk: actions: Fix SD clocks factor table on Owl S500 SoC + - clk: actions: Fix bisp_factor_table based clocks on Owl S500 SoC + - clk: si5341: Avoid divide errors due to bogus register contents + - clk: si5341: Update initialization magic + - writeback: fix obtain a reference to a freeing memcg css + - net: lwtunnel: handle MTU calculation in forwading + - net: sched: fix warning in tcindex_alloc_perfect_hash + - RDMA/mlx5: Don't access NULL-cleared mpi pointer + - MIPS: Fix PKMAP with 32-bit MIPS huge page support + - staging: fbtft: Rectify GPIO handling + - rcu: Invoke rcu_spawn_core_kthreads() from rcu_spawn_gp_kthread() + - tty: nozomi: Fix a resource leak in an error handling function + - mwifiex: re-fix for unaligned accesses + - iio: adis_buffer: do not return ints in irq handlers + - iio: adis16400: do not return ints in irq handlers + - iio: accel: bma180: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: bma220: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: hid: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: kxcjk-1013: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio:accel:mxc4005: Drop unnecessary explicit casts in regmap_bulk_read calls + - iio: accel: mxc4005: Fix overread of data and alignment issue. + - iio: accel: stk8312: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: accel: stk8ba50: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: ti-ads1015: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: vf610: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: gyro: bmg160: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: humidity: am2315: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: srf08: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: pulsed-light: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: as3935: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: magn: hmc5843: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: magn: bmc150: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: isl29125: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: tcs3414: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: light: tcs3472: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: cros_ec_sensors: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - iio: potentiostat: lmp91000: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - ASoC: rk3328: fix missing clk_disable_unprepare() on error in + rk3328_platform_probe() + - ASoC: hisilicon: fix missing clk_disable_unprepare() on error in + hi6210_i2s_startup() + - backlight: lm3630a_bl: Put fwnode in error case during ->probe() + - ASoC: rsnd: tidyup loop on rsnd_adg_clk_query() + - Input: hil_kbd - fix error return code in hil_dev_connect() + - mtd: partitions: redboot: seek fis-index-block in the right node + - char: pcmcia: error out if 'num_bytes_read' is greater than 4 in + set_protocol() + - firmware: stratix10-svc: Fix a resource leak in an error handling path + - tty: nozomi: Fix the error handling path of 'nozomi_card_init()' + - leds: lm3532: select regmap I2C API + - leds: lm36274: cosmetic: rename lm36274_data to chip + - leds: lm3692x: Put fwnode in any case during ->probe() + - scsi: FlashPoint: Rename si_flags field + - fsi: core: Fix return of error values on failures + - fsi: scom: Reset the FSI2PIB engine for any error + - fsi: occ: Don't accept response from un-initialized OCC + - fsi/sbefifo: Clean up correct FIFO when receiving reset request from SBE + - fsi/sbefifo: Fix reset timeout + - visorbus: fix error return code in visorchipset_init() + - s390: appldata depends on PROC_SYSCTL + - iommu/dma: Fix IOVA reserve dma ranges + - ASoC: mediatek: mtk-btcvsd: Fix an error handling path in + 'mtk_btcvsd_snd_probe()' + - usb: gadget: f_fs: Fix setting of device and driver data cross-references + - usb: dwc2: Don't reset the core after setting turnaround time + - eeprom: idt_89hpesx: Put fwnode in matching case during ->probe() + - eeprom: idt_89hpesx: Restore printing the unsupported fwnode name + - iio: at91-sama5d2_adc: remove usage of iio_priv_to_dev() helper + - iio: adc: at91-sama5d2: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: hx711: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: mxs-lradc: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: adc: ti-ads8688: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - iio: magn: rm3100: Fix alignment of buffer in + iio_push_to_buffers_with_timestamp() + - staging: gdm724x: check for buffer overflow in gdm_lte_multi_sdu_pkt() + - staging: gdm724x: check for overflow in gdm_lte_netif_rx() + - staging: rtl8712: remove redundant check in r871xu_drv_init + - staging: rtl8712: fix memory leak in rtl871x_load_fw_cb + - staging: mt7621-dts: fix pci address for PCI memory range + - serial: 8250: Actually allow UPF_MAGIC_MULTIPLIER baud rates + - iio: light: vcnl4035: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - iio: prox: isl29501: Fix buffer alignment in + iio_push_to_buffers_with_timestamp() + - ASoC: cs42l42: Correct definition of CS42L42_ADC_PDN_MASK + - of: Fix truncation of memory sizes on 32-bit platforms + - mtd: rawnand: marvell: add missing clk_disable_unprepare() on error in + marvell_nfc_resume() + - scsi: mpt3sas: Fix error return value in _scsih_expander_add() + - soundwire: stream: Fix test for DP prepare complete + - phy: uniphier-pcie: Fix updating phy parameters + - phy: ti: dm816x: Fix the error handling path in 'dm816x_usb_phy_probe() + - extcon: sm5502: Drop invalid register write in sm5502_reg_data + - extcon: max8997: Add missing modalias string + - ASoC: atmel-i2s: Fix usage of capture and playback at the same time + - configfs: fix memleak in configfs_release_bin_file + - leds: as3645a: Fix error return code in as3645a_parse_node() + - leds: ktd2692: Fix an error handling path + - powerpc: Offline CPU in stop_this_cpu() + - serial: mvebu-uart: do not allow changing baudrate when uartclk is not + available + - serial: mvebu-uart: correctly calculate minimal possible baudrate + - arm64: dts: marvell: armada-37xx: Fix reg for standard variant of UART + - vfio/pci: Handle concurrent vma faults + - mm/huge_memory.c: don't discard hugepage if other processes are mapping it + - mm/z3fold: fix potential memory leak in z3fold_destroy_pool() + - selftests/vm/pkeys: fix alloc_random_pkey() to make it really, really random + - perf llvm: Return -ENOMEM when asprintf() fails + - scsi: target: cxgbit: Unmap DMA buffer before calling target_execute_cmd() + - mmc: block: Disable CMDQ on the ioctl path + - mmc: vub3000: fix control-request direction + - scsi: core: Retry I/O for Notify (Enable Spinup) Required error + - iommu/dma: Fix compile warning in 32-bit builds + - Linux 5.4.132 + * Keyboard not working (LP: #1909814) // Focal update: v5.4.132 upstream + stable release (LP: #1938199) + - ACPI: resources: Add checks for ACPI IRQ override + * Focal update: v5.4.131 upstream stable release (LP: #1936245) + - KVM: SVM: Periodically schedule when unregistering regions on destroy + - s390/stack: fix possible register corruption with stack switch helper + - KVM: SVM: Call SEV Guest Decommission if ASID binding fails + - xen/events: reset active flag for lateeoi events later + - Linux 5.4.131 + * Focal update: v5.4.130 upstream stable release (LP: #1936244) + - scsi: sr: Return appropriate error code when disk is ejected + - drm/nouveau: fix dma_address check for CPU/GPU sync + - gpio: AMD8111 and TQMX86 require HAS_IOPORT_MAP + - RDMA/mlx5: Block FDB rules when not in switchdev mode + - Linux 5.4.130 + * Focal update: v5.4.129 upstream stable release (LP: #1936242) + - module: limit enabling module.sig_enforce + - drm/nouveau: wait for moving fence after pinning v2 + - drm/radeon: wait for moving fence after pinning + - ARM: 9081/1: fix gcc-10 thumb2-kernel regression + - mmc: meson-gx: use memcpy_to/fromio for dram-access-quirk + - kbuild: add CONFIG_LD_IS_LLD + - arm64: link with -z norelro for LLD or aarch64-elf + - MIPS: generic: Update node names to avoid unit addresses + - spi: spi-nxp-fspi: move the register operation after the clock enable + - Revert "PCI: PM: Do not read power state in pci_enable_device_flags()" + - dmaengine: zynqmp_dma: Fix PM reference leak in + zynqmp_dma_alloc_chan_resourc() + - mac80211: remove warning in ieee80211_get_sband() + - mac80211_hwsim: drop pending frames on stop + - cfg80211: call cfg80211_leave_ocb when switching away from OCB + - dmaengine: rcar-dmac: Fix PM reference leak in rcar_dmac_probe() + - dmaengine: mediatek: free the proper desc in desc_free handler + - dmaengine: mediatek: do not issue a new desc if one is still current + - dmaengine: mediatek: use GFP_NOWAIT instead of GFP_ATOMIC in prep_dma + - net: ipv4: Remove unneed BUG() function + - mac80211: drop multicast fragments + - net: ethtool: clear heap allocations for ethtool function + - ping: Check return value of function 'ping_queue_rcv_skb' + - inet: annotate date races around sk->sk_txhash + - net: phy: dp83867: perform soft reset and retain established link + - net: caif: fix memory leak in ldisc_open + - net/packet: annotate accesses to po->bind + - net/packet: annotate accesses to po->ifindex + - r8152: Avoid memcpy() over-reading of ETH_SS_STATS + - sh_eth: Avoid memcpy() over-reading of ETH_SS_STATS + - r8169: Avoid memcpy() over-reading of ETH_SS_STATS + - KVM: selftests: Fix kvm_check_cap() assertion + - net: qed: Fix memcpy() overflow of qed_dcbx_params() + - recordmcount: Correct st_shndx handling + - PCI: Add AMD RS690 quirk to enable 64-bit DMA + - net: ll_temac: Add memory-barriers for TX BD access + - net: ll_temac: Avoid ndo_start_xmit returning NETDEV_TX_BUSY + - pinctrl: stm32: fix the reported number of GPIO lines per bank + - nilfs2: fix memory leak in nilfs_sysfs_delete_device_group + - KVM: do not allow mapping valid but non-reference-counted pages + - i2c: robotfuzz-osif: fix control-request directions + - kthread_worker: split code for canceling the delayed work timer + - kthread: prevent deadlock when kthread_mod_delayed_work() races with + kthread_cancel_delayed_work_sync() + - mm: add VM_WARN_ON_ONCE_PAGE() macro + - mm/rmap: remove unneeded semicolon in page_not_mapped() + - mm/rmap: use page_not_mapped in try_to_unmap() + - mm, thp: use head page in __migration_entry_wait() + - mm/thp: fix __split_huge_pmd_locked() on shmem migration entry + - mm/thp: make is_huge_zero_pmd() safe and quicker + - mm/thp: try_to_unmap() use TTU_SYNC for safe splitting + - mm/thp: fix vma_address() if virtual address below file offset + - mm/thp: fix page_address_in_vma() on file THP tails + - mm/thp: unmap_mapping_page() to fix THP truncate_cleanup_page() + - mm: thp: replace DEBUG_VM BUG with VM_WARN when unmap fails for split + - mm: page_vma_mapped_walk(): use page for pvmw->page + - mm: page_vma_mapped_walk(): settle PageHuge on entry + - mm: page_vma_mapped_walk(): use pmde for *pvmw->pmd + - mm: page_vma_mapped_walk(): prettify PVMW_MIGRATION block + - mm: page_vma_mapped_walk(): crossing page table boundary + - mm: page_vma_mapped_walk(): add a level of indentation + - mm: page_vma_mapped_walk(): use goto instead of while (1) + - mm: page_vma_mapped_walk(): get vma_address_end() earlier + - mm/thp: fix page_vma_mapped_walk() if THP mapped by ptes + - mm/thp: another PVMW_SYNC fix in page_vma_mapped_walk() + - mm, futex: fix shared futex pgoff on shmem huge page + - [Config] enable CONFIG_SYSTEM_REVOCATION_LIST + - certs: Add EFI_CERT_X509_GUID support for dbx entries + - certs: Move load_system_certificate_list to a common function + - Linux 5.4.129 + * Patch To Fix Bug in the Linux Block Layer Responsible For Merging BIOs + (LP: #1931497) + - block: return the correct bvec when checking for gaps + + -- Luke Nowakowski-Krijger Fri, 20 Aug 2021 09:31:09 -0700 + +linux-oracle (5.4.0-1053.57) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1053.57 -proposed tracker (LP: #1936529) + + [ Ubuntu: 5.4.0-81.91 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + * large_dir in ext4 broken (LP: #1933074) + - SAUCE: ext4: fix directory index node split corruption + * Some test in kselftest/net on focal source tree were not tested at all + (LP: #1934282) + - selftests/net: add missing tests to Makefile + * curtin: install flash-kernel in arm64 UEFI unexpected (LP: #1918427) + - [Packaging] Allow grub-efi-arm* to satisfy recommends on ARM + * Add l2tp.sh in net from ubuntu_kernel_selftests back (LP: #1934293) + - Revert "UBUNTU: SAUCE: selftests/net -- disable l2tp.sh test" + * icmp_redirect.sh in net from ubuntu_kernel_selftests failed on F-OEM-5.6 / + F-OEM-5.10 / F-OEM-5.13 / F / G / H (LP: #1880645) + - selftests: icmp_redirect: support expected failures + * Focal update: v5.4.128 upstream stable release (LP: #1934179) + - dmaengine: ALTERA_MSGDMA depends on HAS_IOMEM + - dmaengine: QCOM_HIDMA_MGMT depends on HAS_IOMEM + - dmaengine: stedma40: add missing iounmap() on error in d40_probe() + - afs: Fix an IS_ERR() vs NULL check + - mm/memory-failure: make sure wait for page writeback in memory_failure + - kvm: LAPIC: Restore guard to prevent illegal APIC register access + - batman-adv: Avoid WARN_ON timing related checks + - net: ipv4: fix memory leak in netlbl_cipsov4_add_std + - vrf: fix maximum MTU + - net: rds: fix memory leak in rds_recvmsg + - net: lantiq: disable interrupt before sheduling NAPI + - udp: fix race between close() and udp_abort() + - rtnetlink: Fix regression in bridge VLAN configuration + - net/sched: act_ct: handle DNAT tuple collision + - net/mlx5e: Remove dependency in IPsec initialization flows + - net/mlx5e: Fix page reclaim for dead peer hairpin + - net/mlx5: Consider RoCE cap before init RDMA resources + - net/mlx5e: allow TSO on VXLAN over VLAN topologies + - net/mlx5e: Block offload of outer header csum for UDP tunnels + - netfilter: synproxy: Fix out of bounds when parsing TCP options + - sch_cake: Fix out of bounds when parsing TCP options and header + - alx: Fix an error handling path in 'alx_probe()' + - net: stmmac: dwmac1000: Fix extended MAC address registers definition + - net: make get_net_ns return error if NET_NS is disabled + - qlcnic: Fix an error handling path in 'qlcnic_probe()' + - netxen_nic: Fix an error handling path in 'netxen_nic_probe()' + - net: qrtr: fix OOB Read in qrtr_endpoint_post + - ptp: improve max_adj check against unreasonable values + - net: cdc_ncm: switch to eth%d interface naming + - lantiq: net: fix duplicated skb in rx descriptor ring + - net: usb: fix possible use-after-free in smsc75xx_bind + - net: fec_ptp: fix issue caused by refactor the fec_devtype + - net: ipv4: fix memory leak in ip_mc_add1_src + - net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock + - be2net: Fix an error handling path in 'be_probe()' + - net: hamradio: fix memory leak in mkiss_close + - net: cdc_eem: fix tx fixup skb leak + - cxgb4: fix wrong shift. + - bnxt_en: Rediscover PHY capabilities after firmware reset + - bnxt_en: Call bnxt_ethtool_free() in bnxt_init_one() error path + - icmp: don't send out ICMP messages with a source address of 0.0.0.0 + - net: ethernet: fix potential use-after-free in ec_bhf_remove + - regulator: bd70528: Fix off-by-one for buck123 .n_voltages setting + - ASoC: rt5659: Fix the lost powers for the HDA header + - spi: stm32-qspi: Always wait BUSY bit to be cleared in stm32_qspi_wait_cmd() + - pinctrl: ralink: rt2880: avoid to error in calls is pin is already enabled + - radeon: use memcpy_to/fromio for UVD fw upload + - hwmon: (scpi-hwmon) shows the negative temperature properly + - can: bcm: fix infoleak in struct bcm_msg_head + - can: bcm/raw/isotp: use per module netdevice notifier + - can: j1939: fix Use-after-Free, hold skb ref while in use + - can: mcba_usb: fix memory leak in mcba_usb + - usb: core: hub: Disable autosuspend for Cypress CY7C65632 + - tracing: Do not stop recording cmdlines when tracing is off + - tracing: Do not stop recording comms if the trace file is being read + - tracing: Do no increment trace_clock_global() by one + - PCI: Mark TI C667X to avoid bus reset + - PCI: Mark some NVIDIA GPUs to avoid bus reset + - PCI: aardvark: Don't rely on jiffies while holding spinlock + - PCI: aardvark: Fix kernel panic during PIO transfer + - PCI: Add ACS quirk for Broadcom BCM57414 NIC + - PCI: Work around Huawei Intelligent NIC VF FLR erratum + - KVM: x86: Immediately reset the MMU context when the SMM flag is cleared + - ARCv2: save ABI registers across signal handling + - x86/process: Check PF_KTHREAD and not current->mm for kernel threads + - x86/pkru: Write hardware init value to PKRU when xstate is init + - x86/fpu: Reset state for all signal restore failures + - dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc + - cfg80211: make certificate generation more robust + - cfg80211: avoid double free of PMSR request + - net: ll_temac: Make sure to free skb when it is completely used + - net: ll_temac: Fix TX BD buffer overwrite + - net: bridge: fix vlan tunnel dst null pointer dereference + - net: bridge: fix vlan tunnel dst refcnt when egressing + - mm/slub: clarify verification reporting + - mm/slub: fix redzoning for small allocations + - mm/slub.c: include swab.h + - net: stmmac: disable clocks in stmmac_remove_config_dt() + - net: fec_ptp: add clock rate zero check + - tools headers UAPI: Sync linux/in.h copy with the kernel sources + - KVM: arm/arm64: Fix KVM_VGIC_V3_ADDR_TYPE_REDIST read + - ARM: OMAP: replace setup_irq() by request_irq() + - clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support + - clocksource/drivers/timer-ti-dm: Prepare to handle dra7 timer wrap issue + - clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940 + - usb: dwc3: debugfs: Add and remove endpoint dirs dynamically + - usb: dwc3: core: fix kernel panic when do reboot + - Linux 5.4.128 + * linux-azure CIFS DFS oops (LP: #1935833) + - cifs: get rid of unused parameter in reconn_setup_dfs_targets() + - cifs: handle empty list of targets in cifs_reconnect() + * pmtu.sh from net in ubuntu_kernel_selftests failed with no error message + (LP: #1887661) + - selftests: pmtu.sh: improve the test result processing + * cifs: On cifs_reconnect, resolve the hostname again (LP: #1929831) + - cifs: rename reconn_inval_dfs_target() + - cifs: Simplify reconnect code when dfs upcall is enabled + - cifs: Avoid error pointer dereference + - cifs: On cifs_reconnect, resolve the hostname again. + * Pixel format change broken for Elgato Cam Link 4K (LP: #1932367) + - (upstream) media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K + * Focal update: v5.4.127 upstream stable release (LP: #1933851) + - net: ieee802154: fix null deref in parse dev addr + - HID: quirks: Set INCREMENT_USAGE_ON_DUPLICATE for Saitek X65 + - HID: hid-input: add mapping for emoji picker key + - HID: hid-sensor-hub: Return error for hid_set_field() failure + - HID: quirks: Add quirk for Lenovo optical mouse + - HID: multitouch: set Stylus suffix for Stylus-application devices, too + - HID: Add BUS_VIRTUAL to hid_connect logging + - HID: usbhid: fix info leak in hid_submit_ctrl + - drm/tegra: sor: Do not leak runtime PM reference + - ARM: OMAP2+: Fix build warning when mmc_omap is not built + - gfs2: Prevent direct-I/O write fallback errors from getting lost + - HID: gt683r: add missing MODULE_DEVICE_TABLE + - riscv: Use -mno-relax when using lld linker + - gfs2: Fix use-after-free in gfs2_glock_shrink_scan + - scsi: target: core: Fix warning on realtime kernels + - ethernet: myri10ge: Fix missing error code in myri10ge_probe() + - scsi: qedf: Do not put host in qedf_vport_create() unconditionally + - scsi: scsi_devinfo: Add blacklist entry for HPE OPEN-V + - nvme-loop: reset queue count to 1 in nvme_loop_destroy_io_queues() + - nvme-loop: clear NVME_LOOP_Q_LIVE when nvme_loop_configure_admin_queue() + fails + - nvme-loop: check for NVME_LOOP_Q_LIVE in nvme_loop_destroy_admin_queue() + - net: ipconfig: Don't override command-line hostnames or domains + - drm/amd/display: Allow bandwidth validation for 0 streams. + - rtnetlink: Fix missing error code in rtnl_bridge_notify() + - net/x25: Return the correct errno code + - net: Return the correct errno code + - fib: Return the correct errno code + - Linux 5.4.127 + * Focal update: v5.4.126 upstream stable release (LP: #1933369) + - proc: Check /proc/$pid/attr/ writes against file opener + - proc: Track /proc/$pid/attr/ opener mm_struct + - ASoC: max98088: fix ni clock divider calculation + - spi: Fix spi device unregister flow + - net/nfc/rawsock.c: fix a permission check bug + - usb: cdns3: Fix runtime PM imbalance on error + - ASoC: Intel: bytcr_rt5640: Add quirk for the Glavey TM800A550L tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Lenovo Miix 3-830 tablet + - vfio-ccw: Serialize FSM IDLE state with I/O completion + - ASoC: sti-sas: add missing MODULE_DEVICE_TABLE + - spi: sprd: Add missing MODULE_DEVICE_TABLE + - isdn: mISDN: netjet: Fix crash in nj_probe: + - bonding: init notify_work earlier to avoid uninitialized use + - netlink: disable IRQs for netlink_lock_table() + - net: mdiobus: get rid of a BUG_ON() + - cgroup: disable controllers at parse time + - wq: handle VM suspension in stall detection + - net/qla3xxx: fix schedule while atomic in ql_sem_spinlock + - RDS tcp loopback connection can hang + - scsi: bnx2fc: Return failure if io_req is already in ABTS processing + - scsi: vmw_pvscsi: Set correct residual data length + - scsi: hisi_sas: Drop free_irq() of devm_request_irq() allocated irq + - scsi: target: qla2xxx: Wait for stop_phase1 at WWN removal + - net: macb: ensure the device is available before accessing GEMGXL control + registers + - net: appletalk: cops: Fix data race in cops_probe1 + - net: dsa: microchip: enable phy errata workaround on 9567 + - nvme-fabrics: decode host pathing error for connect + - MIPS: Fix kernel hang under FUNCTION_GRAPH_TRACER and PREEMPT_TRACER + - dm verity: fix require_signatures module_param permissions + - bnx2x: Fix missing error code in bnx2x_iov_init_one() + - nvme-tcp: remove incorrect Kconfig dep in BLK_DEV_NVME + - powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P2041 i2c controllers + - powerpc/fsl: set fsl,i2c-erratum-a004447 flag for P1010 i2c controllers + - spi: Don't have controller clean up spi device before driver unbind + - spi: Cleanup on failure of initial setup + - i2c: mpc: Make use of i2c_recover_bus() + - i2c: mpc: implement erratum A-004447 workaround + - x86/boot: Add .text.* to setup.ld + - spi: bcm2835: Fix out-of-bounds access with more than 4 slaves + - drm: Fix use-after-free read in drm_getunique() + - drm: Lock pointer access in drm_master_release() + - kvm: avoid speculation-based attacks from out-of-range memslot accesses + - staging: rtl8723bs: Fix uninitialized variables + - btrfs: return value from btrfs_mark_extent_written() in case of error + - btrfs: promote debugging asserts to full-fledged checks in validate_super + - cgroup1: don't allow '\n' in renaming + - USB: f_ncm: ncm_bitrate (speed) is unsigned + - usb: f_ncm: only first packet of aggregate needs to start timer + - usb: pd: Set PD_T_SINK_WAIT_CAP to 310ms + - usb: dwc3: ep0: fix NULL pointer exception + - usb: musb: fix MUSB_QUIRK_B_DISCONNECT_99 handling + - usb: typec: wcove: Use LE to CPU conversion when accessing msg->header + - usb: typec: ucsi: Clear PPM capability data in ucsi_init() error path + - usb: gadget: f_fs: Ensure io_completion_wq is idle during unbind + - USB: serial: ftdi_sio: add NovaTech OrionMX product ID + - USB: serial: omninet: add device id for Zyxel Omni 56K Plus + - USB: serial: quatech2: fix control-request directions + - USB: serial: cp210x: fix alternate function for CP2102N QFN20 + - usb: gadget: eem: fix wrong eem header operation + - usb: fix various gadgets null ptr deref on 10gbps cabling. + - usb: fix various gadget panics on 10gbps cabling + - regulator: core: resolve supply for boot-on/always-on regulators + - regulator: max77620: Use device_set_of_node_from_dev() + - usb: typec: mux: Fix copy-paste mistake in typec_mux_match + - RDMA/ipoib: Fix warning caused by destroying non-initial netns + - RDMA/mlx4: Do not map the core_clock page to user space unless enabled + - vmlinux.lds.h: Avoid orphan section with !SMP + - perf: Fix data race between pin_count increment/decrement + - sched/fair: Make sure to update tg contrib for blocked load + - KVM: x86: Ensure liveliness of nested VM-Enter fail tracepoint message + - IB/mlx5: Fix initializing CQ fragments buffer + - NFS: Fix a potential NULL dereference in nfs_get_client() + - NFSv4: Fix deadlock between nfs4_evict_inode() and nfs4_opendata_get_inode() + - perf session: Correct buffer copying when peeking events + - kvm: fix previous commit for 32-bit builds + - NFS: Fix use-after-free in nfs4_init_client() + - NFSv4: Fix second deadlock in nfs4_evict_inode() + - NFSv4: nfs4_proc_set_acl needs to restore NFS_CAP_UIDGID_NOMAP on error. + - scsi: core: Fix error handling of scsi_host_alloc() + - scsi: core: Fix failure handling of scsi_add_host_with_dma() + - scsi: core: Put .shost_dev in failure path if host state changes to RUNNING + - scsi: core: Only put parent device if host state differs from SHOST_CREATED + - ftrace: Do not blindly read the ip address in ftrace_bug() + - tracing: Correct the length check which causes memory corruption + - proc: only require mm_struct for writing + - Linux 5.4.126 + * Focal update: v5.4.125 upstream stable release (LP: #1932957) + - btrfs: tree-checker: do not error out if extent ref hash doesn't match + - net: usb: cdc_ncm: don't spew notifications + - ALSA: usb: update old-style static const declaration + - nl80211: validate key indexes for cfg80211_registered_device + - hwmon: (dell-smm-hwmon) Fix index values + - netfilter: conntrack: unregister ipv4 sockopts on error unwind + - efi: Allow EFI_MEMORY_XP and EFI_MEMORY_RO both to be cleared + - efi: cper: fix snprintf() use in cper_dimm_err_location() + - vfio/pci: Fix error return code in vfio_ecap_init() + - vfio/pci: zap_vma_ptes() needs MMU + - samples: vfio-mdev: fix error handing in mdpy_fb_probe() + - vfio/platform: fix module_put call in error flow + - ipvs: ignore IP_VS_SVC_F_HASHED flag when adding service + - HID: pidff: fix error return code in hid_pidff_init() + - HID: i2c-hid: fix format string mismatch + - net/sched: act_ct: Fix ct template allocation for zone 0 + - ACPICA: Clean up context mutex during object deletion + - netfilter: nft_ct: skip expectations for confirmed conntrack + - netfilter: nfnetlink_cthelper: hit EBUSY on updates if size mismatches + - ieee802154: fix error return code in ieee802154_add_iface() + - ieee802154: fix error return code in ieee802154_llsec_getparams() + - ixgbevf: add correct exception tracing for XDP + - ipv6: Fix KASAN: slab-out-of-bounds Read in fib6_nh_flush_exceptions + - ice: write register with correct offset + - ice: Fix VFR issues for AVF drivers that expect ATQLEN cleared + - ice: Allow all LLDP packets from PF to Tx + - i2c: qcom-geni: Add shutdown callback for i2c + - i40e: optimize for XDP_REDIRECT in xsk path + - i40e: add correct exception tracing for XDP + - arm64: dts: ls1028a: fix memory node + - arm64: dts: zii-ultra: fix 12V_MAIN voltage + - ARM: dts: imx7d-meerkat96: Fix the 'tuning-step' property + - ARM: dts: imx7d-pico: Fix the 'tuning-step' property + - ARM: dts: imx: emcon-avari: Fix nxp,pca8574 #gpio-cells + - bus: ti-sysc: Fix flakey idling of uarts and stop using swsup_sidle_act + - tipc: add extack messages for bearer/media failure + - tipc: fix unique bearer names sanity check + - Bluetooth: fix the erroneous flush_work() order + - Bluetooth: use correct lock to prevent UAF of hdev object + - net: caif: added cfserl_release function + - net: caif: add proper error handling + - net: caif: fix memory leak in caif_device_notify + - net: caif: fix memory leak in cfusbl_device_notify + - HID: i2c-hid: Skip ELAN power-on command after reset + - HID: magicmouse: fix NULL-deref on disconnect + - HID: multitouch: require Finger field to mark Win8 reports as MT + - ALSA: timer: Fix master timer notification + - ALSA: hda: Fix for mute key LED for HP Pavilion 15-CK0xx + - ARM: dts: imx6dl-yapp4: Fix RGMII connection to QCA8334 switch + - ARM: dts: imx6q-dhcom: Add PU,VDD1P1,VDD2P5 regulators + - ext4: fix bug on in ext4_es_cache_extent as ext4_split_extent_at failed + - usb: dwc2: Fix build in periphal-only mode + - pid: take a reference when initializing `cad_pid` + - ocfs2: fix data corruption by fallocate + - nfc: fix NULL ptr dereference in llcp_sock_getname() after failed connect + - drm/amdgpu: Don't query CE and UE errors + - drm/amdgpu: make sure we unpin the UVD BO + - x86/apic: Mark _all_ legacy interrupts when IO/APIC is missing + - btrfs: mark ordered extent and inode with error if we fail to finish + - btrfs: fix error handling in btrfs_del_csums + - btrfs: return errors from btrfs_del_csums in cleanup_ref_head + - btrfs: fixup error handling in fixup_inode_link_counts + - mm, hugetlb: fix simple resv_huge_pages underflow on UFFDIO_COPY + - bnxt_en: Remove the setting of dev_port. + - mm: add thp_order + - XArray: add xa_get_order + - XArray: add xas_split + - mm/filemap: fix storing to a THP shadow entry + - btrfs: fix unmountable seed device after fstrim + - KVM: SVM: Truncate GPR value for DR and CR accesses in !64-bit mode + - KVM: arm64: Fix debug register indexing + - lib/lz4: explicitly support in-place decompression + - xen-pciback: redo VF placement in the virtual topology + - i2c: qcom-geni: Suspend and resume the bus during SYSTEM_SLEEP_PM ops + - neighbour: allow NUD_NOARP entries to be forced GCed + - Linux 5.4.125 + + -- Tim Gardner Fri, 23 Jul 2021 10:02:32 -0600 + +linux-oracle (5.4.0-1052.56) focal; urgency=medium + + [ Ubuntu: 5.4.0-80.90 ] + + * CVE-2021-33909 + - SAUCE: seq_file: Disallow extremely large seq buffer allocations + + -- Kleber Sacilotto de Souza Wed, 14 Jul 2021 19:34:46 +0200 + +linux-oracle (5.4.0-1051.55) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1051.55 -proposed tracker (LP: #1934335) + + [ Ubuntu: 5.4.0-79.88 ] + + * focal/linux: 5.4.0-79.88 -proposed tracker (LP: #1934343) + * lxd exec fails (LP: #1934187) + - SAUCE: Revert "proc: Check /proc/$pid/attr/ writes against file opener" + + -- Kelsey Skunberg Fri, 02 Jul 2021 09:59:31 -0600 + +linux-oracle (5.4.0-1050.54) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1050.54 -proposed tracker (LP: #1932470) + + [ Ubuntu: 5.4.0-78.87 ] + + * focal/linux: 5.4.0-78.87 -proposed tracker (LP: #1932478) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + - update dkms package versions + * Disable hv-kvp-daemon.service on certain instance types (LP: #1932081) + - [Packaging]: Add kernel command line condition to hv-kvp-daemon service + * QLogic Direct-Connect host can't discover SCSI-FC or NVMe/FC devices + (LP: #1860724) + - scsi: qla2xxx: Serialize fc_port alloc in N2N + - scsi: qla2xxx: Set Nport ID for N2N + - scsi: qla2xxx: Fix point-to-point (N2N) device discovery issue + - scsi: qla2xxx: Fix N2N and NVMe connect retry failure + * [SRU] Add support for E810 NIC to Ice Driver in Focal (LP: #1912511) + - ice: add additional E810 device id + * Focal update: v5.4.124 upstream stable release (LP: #1931166) + - ALSA: hda/realtek: Headphone volume is controlled by Front mixer + - ALSA: usb-audio: scarlett2: Fix device hang with ehci-pci + - ALSA: usb-audio: scarlett2: Improve driver startup messages + - cifs: set server->cipher_type to AES-128-CCM for SMB3.0 + - NFSv4: Fix a NULL pointer dereference in pnfs_mark_matching_lsegs_return() + - iommu/vt-d: Fix sysfs leak in alloc_iommu() + - perf intel-pt: Fix sample instruction bytes + - perf intel-pt: Fix transaction abort handling + - perf scripts python: exported-sql-viewer.py: Fix copy to clipboard from Top + Calls by elapsed Time report + - perf scripts python: exported-sql-viewer.py: Fix Array TypeError + - perf scripts python: exported-sql-viewer.py: Fix warning display + - proc: Check /proc/$pid/attr/ writes against file opener + - net: hso: fix control-request directions + - ath10k: Validate first subframe of A-MSDU before processing the list + - dm snapshot: properly fix a crash when an origin has no snapshots + - drm/amdgpu/vcn1: add cancel_delayed_work_sync before power gate + - drm/amdgpu/vcn2.0: add cancel_delayed_work_sync before power gate + - drm/amdgpu/vcn2.5: add cancel_delayed_work_sync before power gate + - selftests/gpio: Use TEST_GEN_PROGS_EXTENDED + - selftests/gpio: Move include of lib.mk up + - selftests/gpio: Fix build when source tree is read only + - kgdb: fix gcc-11 warnings harder + - Documentation: seccomp: Fix user notification documentation + - serial: core: fix suspicious security_locked_down() call + - misc/uss720: fix memory leak in uss720_probe + - thunderbolt: dma_port: Fix NVM read buffer bounds and offset issue + - mei: request autosuspend after sending rx flow control + - staging: iio: cdc: ad7746: avoid overwrite of num_channels + - iio: gyro: fxas21002c: balance runtime power in error path + - iio: adc: ad7768-1: Fix too small buffer passed to + iio_push_to_buffers_with_timestamp() + - iio: adc: ad7124: Fix missbalanced regulator enable / disable on error. + - iio: adc: ad7124: Fix potential overflow due to non sequential channel + numbers + - iio: adc: ad7793: Add missing error code in ad7793_setup() + - serial: 8250_pci: Add support for new HPE serial device + - serial: 8250_pci: handle FL_NOIRQ board flag + - USB: trancevibrator: fix control-request direction + - USB: usbfs: Don't WARN about excessively large memory allocations + - serial: tegra: Fix a mask operation that is always true + - serial: sh-sci: Fix off-by-one error in FIFO threshold register setting + - serial: rp2: use 'request_firmware' instead of 'request_firmware_nowait' + - USB: serial: ti_usb_3410_5052: add startech.com device id + - USB: serial: option: add Telit LE910-S1 compositions 0x7010, 0x7011 + - USB: serial: ftdi_sio: add IDs for IDS GmbH Products + - USB: serial: pl2303: add device id for ADLINK ND-6530 GC + - thermal/drivers/intel: Initialize RW trip to THERMAL_TEMP_INVALID + - usb: dwc3: gadget: Properly track pending and queued SG + - usb: gadget: udc: renesas_usb3: Fix a race in usb3_start_pipen() + - net: usb: fix memory leak in smsc75xx_bind + - spi: spi-geni-qcom: Fix use-after-free on unbind + - Bluetooth: cmtp: fix file refcount when cmtp_attach_device fails + - fs/nfs: Use fatal_signal_pending instead of signal_pending + - NFS: fix an incorrect limit in filelayout_decode_layout() + - NFS: Fix an Oopsable condition in __nfs_pageio_add_request() + - NFS: Don't corrupt the value of pg_bytes_written in nfs_do_recoalesce() + - NFSv4: Fix v4.0/v4.1 SEEK_DATA return -ENOTSUPP when set NFS_V4_2 config + - drm/meson: fix shutdown crash when component not probed + - net/mlx5e: Fix multipath lag activation + - net/mlx5e: Fix nullptr in add_vlan_push_action() + - net/mlx4: Fix EEPROM dump support + - Revert "net:tipc: Fix a double free in tipc_sk_mcast_rcv" + - tipc: wait and exit until all work queues are done + - tipc: skb_linearize the head skb when reassembling msgs + - spi: spi-fsl-dspi: Fix a resource leak in an error handling path + - net: dsa: mt7530: fix VLAN traffic leaks + - net: dsa: fix a crash if ->get_sset_count() fails + - net: dsa: sja1105: error out on unsupported PHY mode + - i2c: s3c2410: fix possible NULL pointer deref on read message after write + - i2c: i801: Don't generate an interrupt on bus reset + - i2c: sh_mobile: Use new clock calculation formulas for RZ/G2E + - perf jevents: Fix getting maximum number of fds + - platform/x86: hp_accel: Avoid invoking _INI to speed up resume + - gpio: cadence: Add missing MODULE_DEVICE_TABLE + - Revert "media: usb: gspca: add a missed check for goto_low_power" + - Revert "ALSA: sb: fix a missing check of snd_ctl_add" + - Revert "serial: max310x: pass return value of spi_register_driver" + - serial: max310x: unregister uart driver in case of failure and abort + - Revert "net: fujitsu: fix a potential NULL pointer dereference" + - net: fujitsu: fix potential null-ptr-deref + - Revert "net/smc: fix a NULL pointer dereference" + - net: caif: remove BUG_ON(dev == NULL) in caif_xmit + - Revert "char: hpet: fix a missing check of ioremap" + - char: hpet: add checks after calling ioremap + - Revert "ALSA: gus: add a check of the status of snd_ctl_add" + - Revert "ALSA: usx2y: Fix potential NULL pointer dereference" + - Revert "isdn: mISDNinfineon: fix potential NULL pointer dereference" + - isdn: mISDNinfineon: check/cleanup ioremap failure correctly in setup_io + - Revert "ath6kl: return error code in ath6kl_wmi_set_roam_lrssi_cmd()" + - ath6kl: return error code in ath6kl_wmi_set_roam_lrssi_cmd() + - Revert "isdn: mISDN: Fix potential NULL pointer dereference of kzalloc" + - isdn: mISDN: correctly handle ph_info allocation failure in hfcsusb_ph_info + - Revert "dmaengine: qcom_hidma: Check for driver register failure" + - dmaengine: qcom_hidma: comment platform_driver_register call + - Revert "libertas: add checks for the return value of sysfs_create_group" + - libertas: register sysfs groups properly + - Revert "ASoC: cs43130: fix a NULL pointer dereference" + - ASoC: cs43130: handle errors in cs43130_probe() properly + - Revert "media: dvb: Add check on sp8870_readreg" + - media: dvb: Add check on sp8870_readreg return + - Revert "media: gspca: mt9m111: Check write_bridge for timeout" + - media: gspca: mt9m111: Check write_bridge for timeout + - Revert "media: gspca: Check the return value of write_bridge for timeout" + - media: gspca: properly check for errors in po1030_probe() + - Revert "net: liquidio: fix a NULL pointer dereference" + - net: liquidio: Add missing null pointer checks + - Revert "brcmfmac: add a check for the status of usb_register" + - brcmfmac: properly check for bus register errors + - btrfs: return whole extents in fiemap + - scsi: BusLogic: Fix 64-bit system enumeration error for Buslogic + - openrisc: Define memory barrier mb + - btrfs: do not BUG_ON in link_to_fixup_dir + - platform/x86: hp-wireless: add AMD's hardware id to the supported list + - platform/x86: intel_punit_ipc: Append MODULE_DEVICE_TABLE for ACPI + - platform/x86: touchscreen_dmi: Add info for the Mediacom Winpad 7.0 W700 + tablet + - SMB3: incorrect file id in requests compounded with open + - drm/amd/display: Disconnect non-DP with no EDID + - drm/amd/amdgpu: fix refcount leak + - drm/amdgpu: Fix a use-after-free + - drm/amd/amdgpu: fix a potential deadlock in gpu reset + - net: netcp: Fix an error message + - net: dsa: fix error code getting shifted with 4 in dsa_slave_get_sset_count + - ASoC: cs42l42: Regmap must use_single_read/write + - vfio-ccw: Check initialized flag in cp_init() + - net: really orphan skbs tied to closing sk + - net: fec: fix the potential memory leak in fec_enet_init() + - net: mdio: thunder: Fix a double free issue in the .remove function + - net: mdio: octeon: Fix some double free issues + - openvswitch: meter: fix race when getting now_ms. + - tls splice: check SPLICE_F_NONBLOCK instead of MSG_DONTWAIT + - net: sched: fix packet stuck problem for lockless qdisc + - net: sched: fix tx action rescheduling issue during deactivation + - net: sched: fix tx action reschedule issue with stopped queue + - net: hso: check for allocation failure in hso_create_bulk_serial_device() + - net: bnx2: Fix error return code in bnx2_init_board() + - bnxt_en: Include new P5 HV definition in VF check. + - mld: fix panic in mld_newpack() + - gve: Check TX QPL was actually assigned + - gve: Update mgmt_msix_idx if num_ntfy changes + - gve: Add NULL pointer checks when freeing irqs. + - gve: Upgrade memory barrier in poll routine + - gve: Correct SKB queue index validation. + - cxgb4: avoid accessing registers when clearing filters + - staging: emxx_udc: fix loop in _nbu2ss_nuke() + - ASoC: cs35l33: fix an error code in probe() + - bpf: Set mac_len in bpf_skb_change_head + - ixgbe: fix large MTU request from VF + - scsi: libsas: Use _safe() loop in sas_resume_port() + - net: lantiq: fix memory corruption in RX ring + - ipv6: record frag_max_size in atomic fragments in input path + - ALSA: usb-audio: scarlett2: snd_scarlett_gen2_controls_create() can be + static + - net: ethernet: mtk_eth_soc: Fix packet statistics support for MT7628/88 + - sch_dsmark: fix a NULL deref in qdisc_reset() + - MIPS: alchemy: xxs1500: add gpio-au1000.h header file + - MIPS: ralink: export rt_sysc_membase for rt2880_wdt.c + - drm/i915/display: fix compiler warning about array overrun + - i915: fix build warning in intel_dp_get_link_status() + - drivers/net/ethernet: clean up unused assignments + - net: hns3: check the return of skb_checksum_help() + - Revert "Revert "ALSA: usx2y: Fix potential NULL pointer dereference"" + - net: hso: bail out on interrupt URB allocation failure + - neighbour: Prevent Race condition in neighbour subsytem + - usb: core: reduce power-on-good delay time of root hub + - Linux 5.4.124 + * Focal update: v5.4.123 upstream stable release (LP: #1931160) + - usb: dwc3: gadget: Enable suspend events + - perf unwind: Fix separate debug info files when using elfutils' libdw's + unwinder + - perf unwind: Set userdata for all __report_module() paths + - NFC: nci: fix memory leak in nci_allocate_device + - Linux 5.4.123 + * Focal update: v5.4.122 upstream stable release (LP: #1931159) + - firmware: arm_scpi: Prevent the ternary sign expansion bug + - openrisc: Fix a memory leak + - RDMA/siw: Properly check send and receive CQ pointers + - RDMA/siw: Release xarray entry + - RDMA/rxe: Clear all QP fields if creation failed + - scsi: ufs: core: Increase the usable queue depth + - scsi: qla2xxx: Fix error return code in qla82xx_write_flash_dword() + - RDMA/mlx5: Recover from fatal event in dual port mode + - RDMA/core: Don't access cm_id after its destruction + - platform/mellanox: mlxbf-tmfifo: Fix a memory barrier issue + - platform/x86: dell-smbios-wmi: Fix oops on rmmod dell_smbios + - RDMA/uverbs: Fix a NULL vs IS_ERR() bug + - ptrace: make ptrace() fail if the tracee changed its pid unexpectedly + - nvmet: seset ns->file when open fails + - locking/mutex: clear MUTEX_FLAGS if wait_list is empty due to signal + - btrfs: avoid RCU stalls while running delayed iputs + - cifs: fix memory leak in smb2_copychunk_range + - ALSA: dice: fix stream format for TC Electronic Konnekt Live at high + sampling transfer frequency + - ALSA: intel8x0: Don't update period unless prepared + - ALSA: line6: Fix racy initialization of LINE6 MIDI + - ALSA: dice: fix stream format at middle sampling rate for Alesis iO 26 + - ALSA: firewire-lib: fix calculation for size of IR context payload + - ALSA: usb-audio: Validate MS endpoint descriptors + - ALSA: bebob/oxfw: fix Kconfig entry for Mackie d.2 Pro + - ALSA: hda: fixup headset for ASUS GU502 laptop + - Revert "ALSA: sb8: add a check for request_region" + - ALSA: firewire-lib: fix check for the size of isochronous packet payload + - ALSA: hda/realtek: reset eapd coeff to default value for alc287 + - ALSA: hda/realtek: Add some CLOVE SSIDs of ALC293 + - ALSA: hda/realtek: Fix silent headphone output on ASUS UX430UA + - ALSA: hda/realtek: Add fixup for HP OMEN laptop + - ALSA: hda/realtek: Add fixup for HP Spectre x360 15-df0xxx + - uio_hv_generic: Fix a memory leak in error handling paths + - Revert "rapidio: fix a NULL pointer dereference when create_workqueue() + fails" + - rapidio: handle create_workqueue() failure + - Revert "serial: mvebu-uart: Fix to avoid a potential NULL pointer + dereference" + - drm/amdgpu: disable 3DCGCG on picasso/raven1 to avoid compute hang + - drm/amdgpu: update gc golden setting for Navi12 + - drm/amdgpu: update sdma golden setting for Navi12 + - mmc: sdhci-pci-gli: increase 1.8V regulator wait + - xen-pciback: reconfigure also from backend watch handler + - dm snapshot: fix crash with transient storage and zero chunk size + - Revert "video: hgafb: fix potential NULL pointer dereference" + - Revert "net: stmicro: fix a missing check of clk_prepare" + - Revert "leds: lp5523: fix a missing check of return value of lp55xx_read" + - Revert "hwmon: (lm80) fix a missing check of bus read in lm80 probe" + - Revert "video: imsttfb: fix potential NULL pointer dereferences" + - Revert "ecryptfs: replace BUG_ON with error handling code" + - Revert "scsi: ufs: fix a missing check of devm_reset_control_get" + - Revert "gdrom: fix a memory leak bug" + - cdrom: gdrom: deallocate struct gdrom_unit fields in remove_gdrom + - cdrom: gdrom: initialize global variable at init time + - Revert "media: rcar_drif: fix a memory disclosure" + - Revert "rtlwifi: fix a potential NULL pointer dereference" + - Revert "qlcnic: Avoid potential NULL pointer dereference" + - Revert "niu: fix missing checks of niu_pci_eeprom_read" + - ethernet: sun: niu: fix missing checks of niu_pci_eeprom_read() + - net: stmicro: handle clk_prepare() failure during init + - scsi: ufs: handle cleanup correctly on devm_reset_control_get error + - net: rtlwifi: properly check for alloc_workqueue() failure + - ics932s401: fix broken handling of errors when word reading fails + - leds: lp5523: check return value of lp5xx_read and jump to cleanup code + - qlcnic: Add null check after calling netdev_alloc_skb + - video: hgafb: fix potential NULL pointer dereference + - vgacon: Record video mode changes with VT_RESIZEX + - vt: Fix character height handling with VT_RESIZEX + - tty: vt: always invoke vc->vc_sw->con_resize callback + - nvme-multipath: fix double initialization of ANA state + - ext4: fix error handling in ext4_end_enable_verity() + - Bluetooth: L2CAP: Fix handling LE modes by L2CAP_OPTIONS + - nvmet: use new ana_log_size instead the old one + - video: hgafb: correctly handle card detect failure during probe + - Bluetooth: SMP: Fail if remote and local public keys are identical + - Linux 5.4.122 + * Focal update: v5.4.121 upstream stable release (LP: #1931158) + - x86/msr: Fix wr/rdmsr_safe_regs_on_cpu() prototypes + - kgdb: fix gcc-11 warning on indentation + - usb: sl811-hcd: improve misleading indentation + - cxgb4: Fix the -Wmisleading-indentation warning + - isdn: capi: fix mismatched prototypes + - pinctrl: ingenic: Improve unreachable code generation + - xsk: Simplify detection of empty and full rings + - virtio_net: Do not pull payload in skb->head + - PCI: thunder: Fix compile testing + - dmaengine: dw-edma: Fix crash on loading/unloading driver + - ARM: 9066/1: ftrace: pause/unpause function graph tracer in cpu_suspend() + - ACPI / hotplug / PCI: Fix reference count leak in enable_slot() + - Input: elants_i2c - do not bind to i2c-hid compatible ACPI instantiated + devices + - Input: silead - add workaround for x86 BIOS-es which bring the chip up in a + stuck state + - um: Mark all kernel symbols as local + - um: Disable CONFIG_GCOV with MODULES + - ARM: 9075/1: kernel: Fix interrupted SMC calls + - scripts/recordmcount.pl: Fix RISC-V regex for clang + - riscv: Workaround mcount name prior to clang-13 + - scsi: lpfc: Fix illegal memory access on Abort IOCBs + - ceph: fix fscache invalidation + - scsi: target: tcmu: Return from tcmu_handle_completions() if cmd_id not + found + - bridge: Fix possible races between assigning rx_handler_data and setting + IFF_BRIDGE_PORT bit + - drm/amd/display: Fix two cursor duplication when using overlay + - gpiolib: acpi: Add quirk to ignore EC wakeups on Dell Venue 10 Pro 5055 + - ALSA: hda: generic: change the DAC ctl name for LO+SPK or LO+HP + - block: reexpand iov_iter after read/write + - lib: stackdepot: turn depot_lock spinlock to raw_spinlock + - net: stmmac: Do not enable RX FIFO overflow interrupts + - ip6_gre: proper dev_{hold|put} in ndo_[un]init methods + - sit: proper dev_{hold|put} in ndo_[un]init methods + - ip6_tunnel: sit: proper dev_{hold|put} in ndo_[un]init methods + - ipv6: remove extra dev_hold() for fallback tunnels + - KVM: arm64: Initialize VCPU mdcr_el2 before loading it + - tweewide: Fix most Shebang lines + - scripts: switch explicitly to Python 3 + - Linux 5.4.121 + * Focal update: v5.4.120 upstream stable release (LP: #1930474) + - tpm: fix error return code in tpm2_get_cc_attrs_tbl() + - tpm, tpm_tis: Extend locality handling to TPM2 in tpm_tis_gen_interrupt() + - tpm, tpm_tis: Reserve locality in tpm_tis_resume() + - KVM: x86/mmu: Remove the defunct update_pte() paging hook + - PM: runtime: Fix unpaired parent child_count for force_resume + - fs: dlm: fix debugfs dump + - tipc: convert dest node's address to network order + - ASoC: Intel: bytcr_rt5640: Enable jack-detect support on Asus T100TAF + - net: stmmac: Set FIFO sizes for ipq806x + - ASoC: rsnd: core: Check convert rate in rsnd_hw_params + - i2c: bail out early when RDWR parameters are wrong + - ALSA: hdsp: don't disable if not enabled + - ALSA: hdspm: don't disable if not enabled + - ALSA: rme9652: don't disable if not enabled + - ALSA: bebob: enable to deliver MIDI messages for multiple ports + - Bluetooth: Set CONF_NOT_COMPLETE as l2cap_chan default + - Bluetooth: initialize skb_queue_head at l2cap_chan_create() + - net: bridge: when suppression is enabled exclude RARP packets + - Bluetooth: check for zapped sk before connecting + - ip6_vti: proper dev_{hold|put} in ndo_[un]init methods + - ASoC: Intel: bytcr_rt5640: Add quirk for the Chuwi Hi8 tablet + - i2c: Add I2C_AQ_NO_REP_START adapter quirk + - mac80211: clear the beacon's CRC after channel switch + - pinctrl: samsung: use 'int' for register masks in Exynos + - mt76: mt76x0: disable GTK offloading + - cuse: prevent clone + - ASoC: rsnd: call rsnd_ssi_master_clk_start() from rsnd_ssi_init() + - Revert "iommu/amd: Fix performance counter initialization" + - iommu/amd: Remove performance counter pre-initialization test + - drm/amd/display: Force vsync flip when reconfiguring MPCC + - selftests: Set CC to clang in lib.mk if LLVM is set + - kconfig: nconf: stop endless search loops + - ALSA: hda/hdmi: fix race in handling acomp ELD notification at resume + - sctp: Fix out-of-bounds warning in sctp_process_asconf_param() + - flow_dissector: Fix out-of-bounds warning in __skb_flow_bpf_to_target() + - powerpc/smp: Set numa node before updating mask + - ASoC: rt286: Generalize support for ALC3263 codec + - ethtool: ioctl: Fix out-of-bounds warning in store_link_ksettings_for_user() + - net: sched: tapr: prevent cycle_time == 0 in parse_taprio_schedule + - samples/bpf: Fix broken tracex1 due to kprobe argument change + - powerpc/pseries: Stop calling printk in rtas_stop_self() + - drm/amd/display: fixed divide by zero kernel crash during dsc enablement + - wl3501_cs: Fix out-of-bounds warnings in wl3501_send_pkt + - wl3501_cs: Fix out-of-bounds warnings in wl3501_mgmt_join + - qtnfmac: Fix possible buffer overflow in qtnf_event_handle_external_auth + - powerpc/iommu: Annotate nested lock for lockdep + - iavf: remove duplicate free resources calls + - net: ethernet: mtk_eth_soc: fix RX VLAN offload + - bnxt_en: Add PCI IDs for Hyper-V VF devices. + - ia64: module: fix symbolizer crash on fdescr + - ASoC: rt286: Make RT286_SET_GPIO_* readable and writable + - thermal: thermal_of: Fix error return code of + thermal_of_populate_bind_params() + - f2fs: fix a redundant call to f2fs_balance_fs if an error occurs + - PCI: iproc: Fix return value of iproc_msi_irq_domain_alloc() + - PCI: Release OF node in pci_scan_device()'s error path + - ARM: 9064/1: hw_breakpoint: Do not directly check the event's + overflow_handler hook + - rpmsg: qcom_glink_native: fix error return code of qcom_glink_rx_data() + - NFSv4.2: Always flush out writes in nfs42_proc_fallocate() + - NFS: Deal correctly with attribute generation counter overflow + - PCI: endpoint: Fix missing destroy_workqueue() + - pNFS/flexfiles: fix incorrect size check in decode_nfs_fh() + - NFSv4.2 fix handling of sr_eof in SEEK's reply + - rtc: fsl-ftm-alarm: add MODULE_TABLE() + - ceph: fix inode leak on getattr error in __fh_to_dentry + - rtc: ds1307: Fix wday settings for rx8130 + - net: hns3: fix incorrect configuration for igu_egu_hw_err + - net: hns3: initialize the message content in hclge_get_link_mode() + - net: hns3: add check for HNS3_NIC_STATE_INITED in + hns3_reset_notify_up_enet() + - net: hns3: fix for vxlan gpe tx checksum bug + - net: hns3: use netif_tx_disable to stop the transmit queue + - net: hns3: disable phy loopback setting in hclge_mac_start_phy + - sctp: do asoc update earlier in sctp_sf_do_dupcook_a + - RISC-V: Fix error code returned by riscv_hartid_to_cpuid() + - sunrpc: Fix misplaced barrier in call_decode + - ethernet:enic: Fix a use after free bug in enic_hard_start_xmit + - sctp: fix a SCTP_MIB_CURRESTAB leak in sctp_sf_do_dupcook_b + - netfilter: xt_SECMARK: add new revision to fix structure layout + - drm/radeon: Fix off-by-one power_state index heap overwrite + - drm/radeon: Avoid power table parsing memory leaks + - khugepaged: fix wrong result value for trace_mm_collapse_huge_page_isolate() + - mm/hugeltb: handle the error case in hugetlb_fix_reserve_counts() + - mm/migrate.c: fix potential indeterminate pte entry in + migrate_vma_insert_page() + - ksm: fix potential missing rmap_item for stable_node + - net: fix nla_strcmp to handle more then one trailing null character + - smc: disallow TCP_ULP in smc_setsockopt() + - netfilter: nfnetlink_osf: Fix a missing skb_header_pointer() NULL check + - can: m_can: m_can_tx_work_queue(): fix tx_skb race condition + - sched: Fix out-of-bound access in uclamp + - sched/fair: Fix unfairness caused by missing load decay + - kernel: kexec_file: fix error return code of kexec_calculate_store_digests() + - netfilter: nftables: avoid overflows in nft_hash_buckets() + - i40e: Fix use-after-free in i40e_client_subtask() + - i40e: fix the restart auto-negotiation after FEC modified + - i40e: Fix PHY type identifiers for 2.5G and 5G adapters + - ARC: entry: fix off-by-one error in syscall number validation + - ARC: mm: PAE: use 40-bit physical page mask + - powerpc/64s: Fix crashes when toggling stf barrier + - powerpc/64s: Fix crashes when toggling entry flush barrier + - hfsplus: prevent corruption in shrinking truncate + - squashfs: fix divide error in calculate_skip() + - userfaultfd: release page in error path to avoid BUG_ON + - mm/hugetlb: fix F_SEAL_FUTURE_WRITE + - drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors + are connected + - drm/i915: Avoid div-by-zero on gen2 + - iio: proximity: pulsedlight: Fix rumtime PM imbalance on error + - usb: fotg210-hcd: Fix an error message + - hwmon: (occ) Fix poll rate limiting + - ACPI: scan: Fix a memory leak in an error handling path + - kyber: fix out of bounds access when preempted + - nbd: Fix NULL pointer in flush_workqueue + - blk-mq: Swap two calls in blk_mq_exit_queue() + - iomap: fix sub-page uptodate handling + - usb: dwc3: omap: improve extcon initialization + - usb: dwc3: pci: Enable usb2-gadget-lpm-disable for Intel Merrifield + - usb: xhci: Increase timeout for HC halt + - usb: dwc2: Fix gadget DMA unmap direction + - usb: core: hub: fix race condition about TRSMRCY of resume + - usb: dwc3: gadget: Return success always for kick transfer in ep queue + - xhci: Do not use GFP_KERNEL in (potentially) atomic context + - xhci: Add reset resume quirk for AMD xhci controller. + - iio: gyro: mpu3050: Fix reported temperature value + - iio: tsl2583: Fix division by a zero lux_val + - cdc-wdm: untangle a circular dependency between callback and softint + - KVM: x86: Cancel pvclock_gtod_work on module removal + - mm: fix struct page layout on 32-bit systems + - FDDI: defxx: Make MMIO the configuration default except for EISA + - MIPS: Reinstate platform `__div64_32' handler + - MIPS: Avoid DIVU in `__div64_32' is result would be zero + - MIPS: Avoid handcoded DIVU in `__div64_32' altogether + - thermal/core/fair share: Lock the thermal zone while looping over instances + - f2fs: fix error handling in f2fs_end_enable_verity() + - ARM: 9011/1: centralize phys-to-virt conversion of DT/ATAGS address + - ARM: 9012/1: move device tree mapping out of linear region + - ARM: 9020/1: mm: use correct section size macro to describe the FDT virtual + address + - ARM: 9027/1: head.S: explicitly map DT even if it lives in the first + physical section + - usb: typec: tcpm: Fix error while calculating PPS out values + - kobject_uevent: remove warning in init_uevent_argv() + - netfilter: conntrack: Make global sysctls readonly in non-init netns + - clk: exynos7: Mark aclk_fsys1_200 as critical + - nvme: do not try to reconfigure APST when the controller is not live + - ASoC: rsnd: check all BUSIF status when error + - Linux 5.4.120 + * scsi: storvsc: Parameterize number hardware queues (LP: #1930626) + - scsi: storvsc: Parameterize number hardware queues + + -- Dimitri John Ledkov Wed, 30 Jun 2021 10:58:18 +0100 + +linux-oracle (5.4.0-1049.53) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1049.53 -proposed tracker (LP: #1933407) + + * iscsi-related backports requested for Oracle-cloud (LP: #1931959) + - scsi: core: Add limitless cmd retry support + - scsi: sd: Allow user to configure command retries + + * Oracle kernel has Android related config options disabled (LP: #1928686) + - [config] oracle: Enable Android options for anbox + + -- Khalid Elmously Thu, 24 Jun 2021 00:22:51 -0400 + +linux-oracle (5.4.0-1048.52) focal; urgency=medium + + [ Ubuntu: 5.4.0-77.86 ] + + * UAF on CAN J1939 j1939_can_recv (LP: #1932209) + - SAUCE: can: j1939: delay release of j1939_priv after synchronize_rcu + * UAF on CAN BCM bcm_rx_handler (LP: #1931855) + - SAUCE: can: bcm: delay release of struct bcm_op after synchronize_rcu + + [ Ubuntu: 5.4.0-76.85 ] + + * focal/linux: 5.4.0-76.85 -proposed tracker (LP: #1932123) + * Upstream v5.9 introduced 'module' patches that removed exported symbols + (LP: #1932065) + - SAUCE: Revert "modules: inherit TAINT_PROPRIETARY_MODULE" + - SAUCE: Revert "modules: return licensing information from find_symbol" + - SAUCE: Revert "modules: rename the licence field in struct symsearch to + license" + - SAUCE: Revert "modules: unexport __module_address" + - SAUCE: Revert "modules: unexport __module_text_address" + - SAUCE: Revert "modules: mark each_symbol_section static" + - SAUCE: Revert "modules: mark find_symbol static" + - SAUCE: Revert "modules: mark ref_module static" + + -- Stefan Bader Thu, 17 Jun 2021 21:27:15 +0200 + +linux-oracle (5.4.0-1047.51) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1047.51 -proposed tracker (LP: #1930024) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-75.84 ] + + * focal/linux: 5.4.0-75.84 -proposed tracker (LP: #1930032) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CVE-2021-33200 + - bpf: Wrap aux data inside bpf_sanitize_info container + - bpf: Fix mask direction swap upon off reg sign change + - bpf: No need to simulate speculative domain for immediates + * Realtek USB hubs in Dell WD19SC/DC/TB fail to work after exiting s2idle + (LP: #1928242) + - USB: Verify the port status when timeout happens during port suspend + * CVE-2020-26145 + - ath10k: drop fragments with multicast DA for SDIO + - ath10k: add CCMP PN replay protection for fragmented frames for PCIe + - ath10k: drop fragments with multicast DA for PCIe + * CVE-2020-26141 + - ath10k: Fix TKIP Michael MIC verification for PCIe + * CVE-2020-24588 + - mac80211: properly handle A-MSDUs that start with an RFC 1042 header + - cfg80211: mitigate A-MSDU aggregation attacks + - mac80211: drop A-MSDUs on old ciphers + - ath10k: drop MPDU which has discard flag set by firmware for SDIO + * CVE-2020-26139 + - mac80211: do not accept/forward invalid EAPOL frames + * CVE-2020-24586 // CVE-2020-24587 // CVE-2020-24587 for such cases. + - mac80211: extend protection against mixed key and fragment cache attacks + * CVE-2020-24586 // CVE-2020-24587 + - mac80211: prevent mixed key and fragment cache attacks + - mac80211: add fragment cache to sta_info + - mac80211: check defrag PN against current frame + - mac80211: prevent attacks on TKIP/WEP as well + * CVE-2020-26147 + - mac80211: assure all fragments are encrypted + * raid10: Block discard is very slow, causing severe delays for mkfs and + fstrim operations (LP: #1896578) + - md: add md_submit_discard_bio() for submitting discard bio + - md/raid10: extend r10bio devs to raid disks + - md/raid10: pull the code that wait for blocked dev into one function + - md/raid10: improve raid10 discard request + - md/raid10: improve discard request for far layout + - dm raid: remove unnecessary discard limits for raid0 and raid10 + * [SRU] mpt3sas: only one vSES is handy even IOC has multi vSES (LP: #1926517) + - scsi: mpt3sas: Only one vSES is present even when IOC has multi vSES + * kvm: properly tear down PV features on hibernate (LP: #1920944) + - x86/kvm: Fix pr_info() for async PF setup/teardown + - x86/kvm: Teardown PV features on boot CPU as well + - x86/kvm: Disable kvmclock on all CPUs on shutdown + - x86/kvm: Disable all PV features on crash + - x86/kvm: Unify kvm_pv_guest_cpu_reboot() with kvm_guest_cpu_offline() + * Focal update: v5.4.119 upstream stable release (LP: #1929615) + - Bluetooth: verify AMP hci_chan before amp_destroy + - hsr: use netdev_err() instead of WARN_ONCE() + - bluetooth: eliminate the potential race condition when removing the HCI + controller + - net/nfc: fix use-after-free llcp_sock_bind/connect + - Revert "USB: cdc-acm: fix rounding error in TIOCSSERIAL" + - tty: moxa: fix TIOCSSERIAL jiffies conversions + - tty: amiserial: fix TIOCSSERIAL permission check + - USB: serial: usb_wwan: fix TIOCSSERIAL jiffies conversions + - staging: greybus: uart: fix TIOCSSERIAL jiffies conversions + - USB: serial: ti_usb_3410_5052: fix TIOCSSERIAL permission check + - staging: fwserial: fix TIOCSSERIAL jiffies conversions + - tty: moxa: fix TIOCSSERIAL permission check + - staging: fwserial: fix TIOCSSERIAL permission check + - usb: typec: tcpm: Address incorrect values of tcpm psy for fixed supply + - usb: typec: tcpm: Address incorrect values of tcpm psy for pps supply + - usb: typec: tcpm: update power supply once partner accepts + - usb: xhci-mtk: remove or operator for setting schedule parameters + - usb: xhci-mtk: improve bandwidth scheduling with TT + - ASoC: samsung: tm2_wm5110: check of of_parse return value + - ASoC: Intel: kbl_da7219_max98927: Fix kabylake_ssp_fixup function + - MIPS: pci-mt7620: fix PLL lock check + - MIPS: pci-rt2880: fix slot 0 configuration + - FDDI: defxx: Bail out gracefully with unassigned PCI resource for CSR + - PCI: Allow VPD access for QLogic ISP2722 + - iio:accel:adis16201: Fix wrong axis assignment that prevents loading + - misc: lis3lv02d: Fix false-positive WARN on various HP models + - misc: vmw_vmci: explicitly initialize vmci_notify_bm_set_msg struct + - misc: vmw_vmci: explicitly initialize vmci_datagram payload + - md/bitmap: wait for external bitmap writes to complete during tear down + - md-cluster: fix use-after-free issue when removing rdev + - md: split mddev_find + - md: factor out a mddev_find_locked helper from mddev_find + - md: md_open returns -EBUSY when entering racing area + - md: Fix missing unused status line of /proc/mdstat + - ipw2x00: potential buffer overflow in libipw_wx_set_encodeext() + - cfg80211: scan: drop entry from hidden_list on overflow + - rtw88: Fix array overrun in rtw_get_tx_power_params() + - drm/panfrost: Clear MMU irqs before handling the fault + - drm/panfrost: Don't try to map pages that are already mapped + - drm/radeon: fix copy of uninitialized variable back to userspace + - drm/amd/display: Reject non-zero src_y and src_x for video planes + - ALSA: hda/realtek: Re-order ALC882 Acer quirk table entries + - ALSA: hda/realtek: Re-order ALC882 Sony quirk table entries + - ALSA: hda/realtek: Re-order ALC882 Clevo quirk table entries + - ALSA: hda/realtek: Re-order ALC269 HP quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Acer quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Dell quirk table entries + - ALSA: hda/realtek: Re-order ALC269 ASUS quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Sony quirk table entries + - ALSA: hda/realtek: Re-order ALC269 Lenovo quirk table entries + - ALSA: hda/realtek: Re-order remaining ALC269 quirk table entries + - ALSA: hda/realtek: Re-order ALC662 quirk table entries + - ALSA: hda/realtek: Remove redundant entry for ALC861 Haier/Uniwill devices + - ALSA: hda/realtek: ALC285 Thinkpad jack pin quirk is unreachable + - KVM: s390: split kvm_s390_logical_to_effective + - KVM: s390: fix guarded storage control register handling + - s390: fix detection of vector enhancements facility 1 vs. vector packed + decimal facility + - KVM: s390: split kvm_s390_real_to_abs + - KVM: nVMX: Truncate bits 63:32 of VMCS field on nested check in !64-bit + - KVM: Stop looking for coalesced MMIO zones if the bus is destroyed + - Revert "i3c master: fix missing destroy_workqueue() on error in + i3c_master_register" + - ovl: fix missing revert_creds() on error path + - usb: gadget: pch_udc: Revert d3cb25a12138 completely + - memory: gpmc: fix out of bounds read and dereference on gpmc_cs[] + - ARM: dts: exynos: correct fuel gauge interrupt trigger level on Midas family + - ARM: dts: exynos: correct MUIC interrupt trigger level on Midas family + - ARM: dts: exynos: correct PMIC interrupt trigger level on Midas family + - ARM: dts: exynos: correct PMIC interrupt trigger level on Odroid X/U3 family + - ARM: dts: exynos: correct PMIC interrupt trigger level on SMDK5250 + - ARM: dts: exynos: correct PMIC interrupt trigger level on Snow + - serial: stm32: fix incorrect characters on console + - serial: stm32: fix tx_empty condition + - usb: typec: tcpci: Check ROLE_CONTROL while interpreting CC_STATUS + - regmap: set debugfs_name to NULL after it is freed + - mtd: rawnand: fsmc: Fix error code in fsmc_nand_probe() + - mtd: rawnand: brcmnand: fix OOB R/W with Hamming ECC + - mtd: Handle possible -EPROBE_DEFER from parse_mtd_partitions() + - mtd: rawnand: qcom: Return actual error code instead of -ENODEV + - arm64: dts: qcom: sm8150: fix number of pins in 'gpio-ranges' + - spi: stm32: drop devres version of spi_register_master + - arm64: dts: renesas: r8a77980: Fix vin4-7 endpoint binding + - x86/microcode: Check for offline CPUs before requesting new microcode + - usb: gadget: pch_udc: Replace cpu_to_le32() by lower_32_bits() + - usb: gadget: pch_udc: Check if driver is present before calling ->setup() + - usb: gadget: pch_udc: Check for DMA mapping error + - crypto: qat - don't release uninitialized resources + - crypto: qat - ADF_STATUS_PF_RUNNING should be set after adf_dev_init + - fotg210-udc: Fix DMA on EP0 for length > max packet size + - fotg210-udc: Fix EP0 IN requests bigger than two packets + - fotg210-udc: Remove a dubious condition leading to fotg210_done + - fotg210-udc: Mask GRP2 interrupts we don't handle + - fotg210-udc: Don't DMA more than the buffer can take + - fotg210-udc: Complete OUT requests on short packets + - mtd: require write permissions for locking and badblock ioctls + - bus: qcom: Put child node before return + - soundwire: bus: Fix device found flag correctly + - phy: marvell: ARMADA375_USBCLUSTER_PHY should not default to y, + unconditionally + - crypto: qat - fix error path in adf_isr_resource_alloc() + - usb: gadget: aspeed: fix dma map failure + - USB: gadget: udc: fix wrong pointer passed to IS_ERR() and PTR_ERR() + - memory: pl353: fix mask of ECC page_size config register + - soundwire: stream: fix memory leak in stream config error path + - m68k: mvme147,mvme16x: Don't wipe PCC timer config bits + - mtd: rawnand: gpmi: Fix a double free in gpmi_nand_init + - irqchip/gic-v3: Fix OF_BAD_ADDR error handling + - staging: rtl8192u: Fix potential infinite loop + - staging: greybus: uart: fix unprivileged TIOCCSERIAL + - PM / devfreq: Use more accurate returned new_freq as resume_freq + - spi: Fix use-after-free with devm_spi_alloc_* + - soc: qcom: mdt_loader: Validate that p_filesz < p_memsz + - soc: qcom: mdt_loader: Detect truncated read of segments + - ACPI: CPPC: Replace cppc_attr with kobj_attribute + - crypto: qat - Fix a double free in adf_create_ring + - cpufreq: armada-37xx: Fix setting TBG parent for load levels + - clk: mvebu: armada-37xx-periph: remove .set_parent method for CPU PM clock + - cpufreq: armada-37xx: Fix the AVS value for load L1 + - clk: mvebu: armada-37xx-periph: Fix switching CPU freq from 250 Mhz to 1 GHz + - clk: mvebu: armada-37xx-periph: Fix workaround for switching from L1 to L0 + - cpufreq: armada-37xx: Fix driver cleanup when registration failed + - cpufreq: armada-37xx: Fix determining base CPU frequency + - spi: fsl-lpspi: Fix PM reference leak in lpspi_prepare_xfer_hardware() + - usb: gadget: r8a66597: Add missing null check on return from + platform_get_resource + - USB: cdc-acm: fix unprivileged TIOCCSERIAL + - USB: cdc-acm: fix TIOCGSERIAL implementation + - tty: fix return value for unsupported ioctls + - serial: core: return early on unsupported ioctls + - firmware: qcom-scm: Fix QCOM_SCM configuration + - node: fix device cleanups in error handling code + - usbip: vudc: fix missing unlock on error in usbip_sockfd_store() + - platform/x86: pmc_atom: Match all Beckhoff Automation baytrail boards with + critclk_systems DMI table + - x86/platform/uv: Fix !KEXEC build failure + - usb: dwc2: Fix host mode hibernation exit with remote wakeup flow. + - usb: dwc2: Fix hibernation between host and device modes. + - ttyprintk: Add TTY hangup callback. + - xen-blkback: fix compatibility bug with single page rings + - soc: aspeed: fix a ternary sign expansion bug + - media: vivid: fix assignment of dev->fbuf_out_flags + - media: omap4iss: return error code when omap4iss_get() failed + - media: aspeed: fix clock handling logic + - media: platform: sunxi: sun6i-csi: fix error return code of + sun6i_video_start_streaming() + - media: m88rs6000t: avoid potential out-of-bounds reads on arrays + - drm/amdkfd: fix build error with AMD_IOMMU_V2=m + - x86/kprobes: Fix to check non boostable prefixes correctly + - pata_arasan_cf: fix IRQ check + - pata_ipx4xx_cf: fix IRQ check + - sata_mv: add IRQ checks + - ata: libahci_platform: fix IRQ check + - nvme-tcp: block BH in sk state_change sk callback + - nvmet-tcp: fix incorrect locking in state_change sk callback + - nvme: retrigger ANA log update if group descriptor isn't found + - media: v4l2-ctrls.c: fix race condition in hdl->requests list + - vfio/mdev: Do not allow a mdev_type to have a NULL parent pointer + - clk: zynqmp: move zynqmp_pll_set_mode out of round_rate callback + - clk: qcom: a53-pll: Add missing MODULE_DEVICE_TABLE + - clk: uniphier: Fix potential infinite loop + - scsi: hisi_sas: Fix IRQ checks + - scsi: jazz_esp: Add IRQ check + - scsi: sun3x_esp: Add IRQ check + - scsi: sni_53c710: Add IRQ check + - scsi: ibmvfc: Fix invalid state machine BUG_ON() + - mfd: stm32-timers: Avoid clearing auto reload register + - nvme-pci: don't simple map sgl when sgls are disabled + - HSI: core: fix resource leaks in hsi_add_client_from_dt() + - x86/events/amd/iommu: Fix sysfs type mismatch + - sched/debug: Fix cgroup_path[] serialization + - drivers/block/null_blk/main: Fix a double free in null_init. + - HID: plantronics: Workaround for double volume key presses + - perf symbols: Fix dso__fprintf_symbols_by_name() to return the number of + printed chars + - net: lapbether: Prevent racing when checking whether the netif is running + - powerpc/fadump: Mark fadump_calculate_reserve_size as __init + - powerpc/prom: Mark identical_pvr_fixup as __init + - inet: use bigger hash table for IP ID generation + - powerpc: Fix HAVE_HARDLOCKUP_DETECTOR_ARCH build configuration + - ALSA: core: remove redundant spin_lock pair in snd_card_disconnect + - bug: Remove redundant condition check in report_bug + - nfc: pn533: prevent potential memory corruption + - net: hns3: Limiting the scope of vector_ring_chain variable + - mips: bmips: fix syscon-reboot nodes + - ALSA: usb-audio: Add error checks for usb_driver_claim_interface() calls + - ASoC: simple-card: fix possible uninitialized single_cpu local variable + - liquidio: Fix unintented sign extension of a left shift of a u16 + - powerpc/64s: Fix pte update for kernel memory on radix + - powerpc/perf: Fix PMU constraint check for EBB events + - powerpc: iommu: fix build when neither PCI or IBMVIO is set + - mac80211: bail out if cipher schemes are invalid + - mt7601u: fix always true expression + - KVM: PPC: Book3S HV P9: Restore host CTRL SPR after guest exit + - RDMA/qedr: Fix error return code in qedr_iw_connect() + - IB/hfi1: Fix error return code in parse_platform_config() + - cxgb4: Fix unintentional sign extension issues + - net: thunderx: Fix unintentional sign extension issue + - RDMA/srpt: Fix error return code in srpt_cm_req_recv() + - i2c: img-scb: fix reference leak when pm_runtime_get_sync fails + - i2c: imx-lpi2c: fix reference leak when pm_runtime_get_sync fails + - i2c: omap: fix reference leak when pm_runtime_get_sync fails + - i2c: sprd: fix reference leak when pm_runtime_get_sync fails + - i2c: cadence: add IRQ check + - i2c: emev2: add IRQ check + - i2c: jz4780: add IRQ check + - i2c: sh7760: add IRQ check + - powerpc/xive: Fix xmon command "dxi" + - ASoC: ak5558: correct reset polarity + - drm/i915/gvt: Fix error code in intel_gvt_init_device() + - perf beauty: Fix fsconfig generator + - MIPS: pci-legacy: stop using of_pci_range_to_resource + - powerpc/pseries: extract host bridge from pci_bus prior to bus removal + - rtlwifi: 8821ae: upgrade PHY and RF parameters + - i2c: sh7760: fix IRQ error path + - mwl8k: Fix a double Free in mwl8k_probe_hw + - vsock/vmci: log once the failed queue pair allocation + - gro: fix napi_gro_frags() Fast GRO breakage due to IP alignment check + - RDMA/cxgb4: add missing qpid increment + - RDMA/i40iw: Fix error unwinding when i40iw_hmc_sd_one fails + - ALSA: usb: midi: don't return -ENOMEM when usb_urb_ep_type_check fails + - net: davinci_emac: Fix incorrect masking of tx and rx error channel + - net: renesas: ravb: Fix a stuck issue when a lot of frames are received + - net: phy: intel-xway: enable integrated led functions + - ath9k: Fix error check in ath9k_hw_read_revisions() for PCI devices + - ath10k: Fix ath10k_wmi_tlv_op_pull_peer_stats_info() unlock without lock + - powerpc/52xx: Fix an invalid ASM expression ('addi' used instead of 'add') + - bnxt_en: fix ternary sign extension bug in bnxt_show_temp() + - ARM: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins for + RTL8211E + - arm64: dts: uniphier: Change phy-mode to RGMII-ID to enable delay pins for + RTL8211E + - net: geneve: modify IP header check in geneve6_xmit_skb and geneve_xmit_skb + - selftests: net: mirror_gre_vlan_bridge_1q: Make an FDB entry static + - bnxt_en: Fix RX consumer index logic in the error path. + - net:emac/emac-mac: Fix a use after free in emac_mac_tx_buf_send + - RDMA/siw: Fix a use after free in siw_alloc_mr + - RDMA/bnxt_re: Fix a double free in bnxt_qplib_alloc_res + - net: bridge: mcast: fix broken length + header check for MRDv6 Adv. + - net:nfc:digital: Fix a double free in digital_tg_recv_dep_req + - kfifo: fix ternary sign extension bugs + - mm/sparse: add the missing sparse_buffer_fini() in error branch + - mm/memory-failure: unnecessary amount of unmapping + - net: Only allow init netns to set default tcp cong to a restricted algo + - smp: Fix smp_call_function_single_async prototype + - Revert "net/sctp: fix race condition in sctp_destroy_sock" + - sctp: delay auto_asconf init until binding the first addr + - Revert "of/fdt: Make sure no-map does not remove already reserved regions" + - Revert "fdt: Properly handle "no-map" field in the memory region" + - Linux 5.4.119 + * seccomp_bpf:syscall_faked from kselftests fail on s390x (LP: #1928522) + - selftests/seccomp: s390 shares the syscall and return value register + * Can't detect intel wifi 6235 (LP: #1920180) + - SAUCE: iwlwifi: add new pci id for 6235 + * Mark kprobe_args_user.tc in kselftest/ftrace as unsupported (LP: #1929527) + - selftests/ftrace: Return unsupported for the unconfigured features + * pmtu.sh from net in ubuntu_kernel_selftests failed with no error message + (LP: #1887661) + - selftests: pmtu.sh: use $ksft_skip for skipped return code + * alsa/sof: make sof driver work in the case of without i915 (focal kernel) + (LP: #1927672) + - SAUCE: ASoC: SOF: Intel: hda: move the probe_bus ahead of creation of mach + device + * Fix kdump failures (LP: #1927518) + - video: hyperv_fb: Add ratelimit on error message + - Drivers: hv: vmbus: Increase wait time for VMbus unload + - Drivers: hv: vmbus: Initialize unload_event statically + * Ubuntu 20.04 - 'Support flow counters offset for bulk counters' + (LP: #1922494) + - IB/mlx5: Support flow counters offset for bulk counters + * Focal update: v5.4.118 upstream stable release (LP: #1928825) + - s390/disassembler: increase ebpf disasm buffer size + - ACPI: custom_method: fix potential use-after-free issue + - ACPI: custom_method: fix a possible memory leak + - ftrace: Handle commands when closing set_ftrace_filter file + - ARM: 9056/1: decompressor: fix BSS size calculation for LLVM ld.lld + - arm64: dts: marvell: armada-37xx: add syscon compatible to NB clk node + - arm64: dts: mt8173: fix property typo of 'phys' in dsi node + - ecryptfs: fix kernel panic with null dev_name + - mtd: spinand: core: add missing MODULE_DEVICE_TABLE() + - mtd: rawnand: atmel: Update ecc_stats.corrected counter + - erofs: add unsupported inode i_format check + - spi: spi-ti-qspi: Free DMA resources + - scsi: qla2xxx: Fix crash in qla2xxx_mqueuecommand() + - scsi: mpt3sas: Block PCI config access from userspace during reset + - mmc: uniphier-sd: Fix an error handling path in uniphier_sd_probe() + - mmc: uniphier-sd: Fix a resource leak in the remove function + - mmc: sdhci: Check for reset prior to DMA address unmap + - mmc: sdhci-pci: Fix initialization of some SD cards for Intel BYT-based + controllers + - mmc: block: Update ext_csd.cache_ctrl if it was written + - mmc: block: Issue a cache flush only when it's enabled + - mmc: core: Do a power cycle when the CMD11 fails + - mmc: core: Set read only for SD cards with permanent write protect bit + - mmc: core: Fix hanging on I/O during system suspend for removable cards + - modules: mark ref_module static + - modules: mark find_symbol static + - modules: mark each_symbol_section static + - modules: unexport __module_text_address + - modules: unexport __module_address + - modules: rename the licence field in struct symsearch to license + - modules: return licensing information from find_symbol + - modules: inherit TAINT_PROPRIETARY_MODULE + - irqchip/gic-v3: Do not enable irqs when handling spurious interrups + - cifs: Return correct error code from smb2_get_enc_key + - btrfs: fix metadata extent leak after failure to create subvolume + - intel_th: pci: Add Rocket Lake CPU support + - posix-timers: Preserve return value in clock_adjtime32() + - fbdev: zero-fill colormap in fbcmap.c + - bus: ti-sysc: Probe for l4_wkup and l4_cfg interconnect devices first + - staging: wimax/i2400m: fix byte-order issue + - spi: ath79: always call chipselect function + - spi: ath79: remove spi-master setup and cleanup assignment + - crypto: api - check for ERR pointers in crypto_destroy_tfm() + - crypto: qat - fix unmap invalid dma address + - usb: gadget: uvc: add bInterval checking for HS mode + - usb: webcam: Invalid size of Processing Unit Descriptor + - genirq/matrix: Prevent allocation counter corruption + - usb: gadget: f_uac2: validate input parameters + - usb: gadget: f_uac1: validate input parameters + - usb: dwc3: gadget: Ignore EP queue requests during bus reset + - usb: xhci: Fix port minor revision + - PCI: PM: Do not read power state in pci_enable_device_flags() + - x86/build: Propagate $(CLANG_FLAGS) to $(REALMODE_FLAGS) + - tee: optee: do not check memref size on return from Secure World + - perf/arm_pmu_platform: Fix error handling + - usb: xhci-mtk: support quirk to disable usb2 lpm + - xhci: check control context is valid before dereferencing it. + - xhci: fix potential array out of bounds with several interrupters + - spi: dln2: Fix reference leak to master + - spi: omap-100k: Fix reference leak to master + - spi: qup: fix PM reference leak in spi_qup_remove() + - usb: musb: fix PM reference leak in musb_irq_work() + - usb: core: hub: Fix PM reference leak in usb_port_resume() + - tty: n_gsm: check error while registering tty devices + - intel_th: Consistency and off-by-one fix + - phy: phy-twl4030-usb: Fix possible use-after-free in twl4030_usb_remove() + - crypto: stm32/hash - Fix PM reference leak on stm32-hash.c + - crypto: stm32/cryp - Fix PM reference leak on stm32-cryp.c + - crypto: omap-aes - Fix PM reference leak on omap-aes.c + - platform/x86: intel_pmc_core: Don't use global pmcdev in quirks + - btrfs: convert logic BUG_ON()'s in replace_path to ASSERT()'s + - drm: Added orientation quirk for OneGX1 Pro + - drm/qxl: release shadow on shutdown + - drm/amd/display: Check for DSC support instead of ASIC revision + - drm/amd/display: Don't optimize bandwidth before disabling planes + - scsi: lpfc: Fix incorrect dbde assignment when building target abts wqe + - scsi: lpfc: Fix pt2pt connection does not recover after LOGO + - scsi: target: pscsi: Fix warning in pscsi_complete_cmd() + - media: ite-cir: check for receive overflow + - media: drivers: media: pci: sta2x11: fix Kconfig dependency on GPIOLIB + - media: imx: capture: Return -EPIPE from __capture_legacy_try_fmt() + - power: supply: bq27xxx: fix power_avg for newer ICs + - extcon: arizona: Fix some issues when HPDET IRQ fires after the jack has + been unplugged + - extcon: arizona: Fix various races on driver unbind + - media: media/saa7164: fix saa7164_encoder_register() memory leak bugs + - media: gspca/sq905.c: fix uninitialized variable + - power: supply: Use IRQF_ONESHOT + - drm/amdgpu: mask the xgmi number of hops reported from psp to kfd + - drm/amdkfd: Fix UBSAN shift-out-of-bounds warning + - drm/amdgpu : Fix asic reset regression issue introduce by 8f211fe8ac7c4f + - drm/amd/display: Fix UBSAN warning for not a valid value for type '_Bool' + - drm/amd/display: fix dml prefetch validation + - scsi: qla2xxx: Always check the return value of qla24xx_get_isp_stats() + - drm/vkms: fix misuse of WARN_ON + - scsi: qla2xxx: Fix use after free in bsg + - mmc: sdhci-pci: Add PCI IDs for Intel LKF + - ata: ahci: Disable SXS for Hisilicon Kunpeng920 + - scsi: smartpqi: Correct request leakage during reset operations + - scsi: smartpqi: Add new PCI IDs + - scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg() + - media: em28xx: fix memory leak + - media: vivid: update EDID + - clk: socfpga: arria10: Fix memory leak of socfpga_clk on error return + - power: supply: generic-adc-battery: fix possible use-after-free in + gab_remove() + - power: supply: s3c_adc_battery: fix possible use-after-free in + s3c_adc_bat_remove() + - media: tc358743: fix possible use-after-free in tc358743_remove() + - media: adv7604: fix possible use-after-free in adv76xx_remove() + - media: i2c: adv7511-v4l2: fix possible use-after-free in adv7511_remove() + - media: i2c: tda1997: Fix possible use-after-free in tda1997x_remove() + - media: i2c: adv7842: fix possible use-after-free in adv7842_remove() + - media: platform: sti: Fix runtime PM imbalance in regs_show + - media: dvb-usb: fix memory leak in dvb_usb_adapter_init + - media: gscpa/stv06xx: fix memory leak + - sched/fair: Ignore percpu threads for imbalance pulls + - drm/msm/mdp5: Configure PP_SYNC_HEIGHT to double the vtotal + - drm/msm/mdp5: Do not multiply vclk line count by 100 + - drm/amdkfd: Fix cat debugfs hang_hws file causes system crash bug + - amdgpu: avoid incorrect %hu format string + - drm/amdgpu: fix NULL pointer dereference + - scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO + response + - scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL mode + - scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic + - mfd: arizona: Fix rumtime PM imbalance on error + - scsi: libfc: Fix a format specifier + - s390/archrandom: add parameter check for s390_arch_random_generate + - ALSA: emu8000: Fix a use after free in snd_emu8000_create_mixer + - ALSA: hda/conexant: Re-order CX5066 quirk table entries + - ALSA: sb: Fix two use after free in snd_sb_qsound_build + - ALSA: usb-audio: Explicitly set up the clock selector + - ALSA: usb-audio: More constifications + - ALSA: usb-audio: Add dB range mapping for Sennheiser Communications Headset + PC 8 + - ALSA: hda/realtek: GA503 use same quirks as GA401 + - ALSA: hda/realtek: fix mic boost on Intel NUC 8 + - ALSA: hda/realtek: fix static noise on ALC285 Lenovo laptops + - ALSA: hda/realtek: Add quirk for Intel Clevo PCx0Dx + - btrfs: fix race when picking most recent mod log operation for an old root + - arm64/vdso: Discard .note.gnu.property sections in vDSO + - Makefile: Move -Wno-unused-but-set-variable out of GCC only block + - virtiofs: fix memory leak in virtio_fs_probe() + - ubifs: Only check replay with inode type to judge if inode linked + - f2fs: fix to avoid out-of-bounds memory access + - mlxsw: spectrum_mr: Update egress RIF list before route's action + - openvswitch: fix stack OOB read while fragmenting IPv4 packets + - ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure + - NFS: Don't discard pNFS layout segments that are marked for return + - NFSv4: Don't discard segments marked for return in _pnfs_return_layout() + - Input: ili210x - add missing negation for touch indication on ili210x + - jffs2: Fix kasan slab-out-of-bounds problem + - powerpc/eeh: Fix EEH handling for hugepages in ioremap space. + - powerpc: fix EDEADLOCK redefinition error in uapi/asm/errno.h + - intel_th: pci: Add Alder Lake-M support + - tpm: efi: Use local variable for calculating final log size + - tpm: vtpm_proxy: Avoid reading host log when using a virtual device + - crypto: rng - fix crypto_rng_reset() refcounting when !CRYPTO_STATS + - md/raid1: properly indicate failure when ending a failed write request + - dm raid: fix inconclusive reshape layout on fast raid4/5/6 table reload + sequences + - fuse: fix write deadlock + - security: commoncap: fix -Wstringop-overread warning + - Fix misc new gcc warnings + - jffs2: check the validity of dstlen in jffs2_zlib_compress() + - Revert 337f13046ff0 ("futex: Allow FUTEX_CLOCK_REALTIME with FUTEX_WAIT op") + - x86/cpu: Initialize MSR_TSC_AUX if RDTSCP *or* RDPID is supported + - kbuild: update config_data.gz only when the content of .config is changed + - ext4: fix check to prevent false positive report of incorrect used inodes + - ext4: do not set SB_ACTIVE in ext4_orphan_cleanup() + - ext4: fix error code in ext4_commit_super + - media: dvbdev: Fix memory leak in dvb_media_device_free() + - media: dvb-usb: Fix use-after-free access + - media: dvb-usb: Fix memory leak at error in dvb_usb_device_init() + - media: staging/intel-ipu3: Fix memory leak in imu_fmt + - media: staging/intel-ipu3: Fix set_fmt error handling + - media: staging/intel-ipu3: Fix race condition during set_fmt + - usb: gadget: dummy_hcd: fix gpf in gadget_setup + - usb: gadget: Fix double free of device descriptor pointers + - usb: gadget/function/f_fs string table fix for multiple languages + - usb: dwc3: gadget: Fix START_TRANSFER link state check + - usb: dwc2: Fix session request interrupt handler + - tty: fix memory leak in vc_deallocate + - rsi: Use resume_noirq for SDIO + - tracing: Map all PIDs to command lines + - tracing: Restructure trace_clock_global() to never block + - dm persistent data: packed struct should have an aligned() attribute too + - dm space map common: fix division bug in sm_ll_find_free_block() + - dm integrity: fix missing goto in bitmap_flush_interval error handling + - dm rq: fix double free of blk_mq_tag_set in dev remove after table load + fails + - Linux 5.4.118 + * Focal update: v5.4.117 upstream stable release (LP: #1928823) + - mips: Do not include hi and lo in clobber list for R6 + - ACPI: tables: x86: Reserve memory occupied by ACPI tables + - ACPI: x86: Call acpi_boot_table_init() after acpi_table_upgrade() + - net: usb: ax88179_178a: initialize local variables before use + - igb: Enable RSS for Intel I211 Ethernet Controller + - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_enqueue_hcmd() + - bpf: Fix masking negation logic upon negative dst register + - bpf: Fix leakage of uninitialized bpf stack under speculation + - avoid __memcat_p link failure + - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd() + - perf data: Fix error return code in perf_data__create_dir() + - perf ftrace: Fix access to pid in array when setting a pid filter + - ALSA: usb-audio: Add MIDI quirk for Vox ToneLab EX + - USB: Add reset-resume quirk for WD19's Realtek Hub + - platform/x86: thinkpad_acpi: Correct thermal sensor allocation + - scsi: ufs: Unlock on a couple error paths + - ovl: allow upperdir inside lowerdir + - perf/core: Fix unconditional security_locked_down() call + - vfio: Depend on MMU + - Linux 5.4.117 + * r8152 tx status -71 (LP: #1922651) // Focal update: v5.4.117 upstream stable + release (LP: #1928823) + - USB: Add LPM quirk for Lenovo ThinkPad USB-C Dock Gen2 Ethernet + * Focal update: v5.4.116 upstream stable release (LP: #1928821) + - bpf: Move off_reg into sanitize_ptr_alu + - bpf: Ensure off_reg has no mixed signed bounds for all types + - bpf: Rework ptr_limit into alu_limit and add common error path + - bpf: Improve verifier error messages for users + - bpf: Refactor and streamline bounds check into helper + - bpf: Move sanitize_val_alu out of op switch + - bpf: Tighten speculative pointer arithmetic mask + - bpf: Update selftests to reflect new error states + - Linux 5.4.116 + * Focal update: v5.4.115 upstream stable release (LP: #1927997) + - gpio: omap: Save and restore sysconfig + - pinctrl: lewisburg: Update number of pins in community + - arm64: dts: allwinner: Revert SD card CD GPIO for Pine64-LTS + - perf/x86/intel/uncore: Remove uncore extra PCI dev HSWEP_PCI_PCU_3 + - perf/x86/kvm: Fix Broadwell Xeon stepping in isolation_ucodes[] + - perf auxtrace: Fix potential NULL pointer dereference + - HID: google: add don USB id + - HID: alps: fix error return code in alps_input_configured() + - HID: wacom: Assign boolean values to a bool variable + - ARM: dts: Fix swapped mmc order for omap3 + - net: geneve: check skb is large enough for IPv4/IPv6 header + - s390/entry: save the caller of psw_idle + - xen-netback: Check for hotplug-status existence before watching + - cavium/liquidio: Fix duplicate argument + - csky: change a Kconfig symbol name to fix e1000 build error + - ia64: fix discontig.c section mismatches + - ia64: tools: remove duplicate definition of ia64_mf() on ia64 + - x86/crash: Fix crash_setup_memmap_entries() out-of-bounds access + - net: hso: fix NULL-deref on disconnect regression + - USB: CDC-ACM: fix poison/unpoison imbalance + - Linux 5.4.115 + + -- Tim Gardner Fri, 11 Jun 2021 10:58:51 -0600 + +linux-oracle (5.4.0-1046.50) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1046.50 -proposed tracker (LP: #1927611) + + * Packaging resync (LP: #1786013) + - update dkms package versions + + [ Ubuntu: 5.4.0-74.83 ] + + * focal/linux: 5.4.0-74.83 -proposed tracker (LP: #1927619) + * Introduce the 465 driver series, fabric-manager, and libnvidia-nscq + (LP: #1925522) + - debian/dkms-versions -- add NVIDIA 465 and migrate 450 to 460 + * linux-image-5.0.0-35-generic breaks checkpointing of container + (LP: #1857257) + - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files + * Enable CIFS GCM256 (LP: #1921916) + - smb3: add defines for new crypto algorithms + - smb3.1.1: add new module load parm require_gcm_256 + - smb3.1.1: add new module load parm enable_gcm_256 + - smb3.1.1: print warning if server does not support requested encryption type + - smb3.1.1: rename nonces used for GCM and CCM encryption + - smb3.1.1: set gcm256 when requested + - cifs: Adjust key sizes and key generation routines for AES256 encryption + * locking/qrwlock: Fix ordering in queued_write_lock_slowpath() (LP: #1926184) + - locking/qrwlock: Fix ordering in queued_write_lock_slowpath() + * [Ubuntu 21.04] net/mlx5: Fix HW spec violation configuring uplink + (LP: #1925452) + - net/mlx5: Fix HW spec violation configuring uplink + * Focal update: v5.4.114 upstream stable release (LP: #1926493) + - Revert "scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure" + - Revert "scsi: qla2xxx: Fix stuck login session using prli_pend_timer" + - scsi: qla2xxx: Dual FCP-NVMe target port support + - scsi: qla2xxx: Fix device connect issues in P2P configuration + - scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure + - scsi: qla2xxx: Add a shadow variable to hold disc_state history of fcport + - scsi: qla2xxx: Fix stuck login session using prli_pend_timer + - scsi: qla2xxx: Fix fabric scan hang + - net/sctp: fix race condition in sctp_destroy_sock + - Input: nspire-keypad - enable interrupts only when opened + - gpio: sysfs: Obey valid_mask + - dmaengine: dw: Make it dependent to HAS_IOMEM + - ARM: dts: Drop duplicate sha2md5_fck to fix clk_disable race + - ARM: dts: Fix moving mmc devices with aliases for omap4 & 5 + - lockdep: Add a missing initialization hint to the "INFO: Trying to register + non-static key" message + - arc: kernel: Return -EFAULT if copy_to_user() fails + - ASoC: max98373: Added 30ms turn on/off time delay + - neighbour: Disregard DEAD dst in neigh_update + - ARM: keystone: fix integer overflow warning + - ARM: omap1: fix building with clang IAS + - drm/msm: Fix a5xx/a6xx timestamps + - ASoC: fsl_esai: Fix TDM slot setup for I2S mode + - scsi: scsi_transport_srp: Don't block target in SRP_PORT_LOST state + - net: ieee802154: stop dump llsec keys for monitors + - net: ieee802154: forbid monitor for add llsec key + - net: ieee802154: forbid monitor for del llsec key + - net: ieee802154: stop dump llsec devs for monitors + - net: ieee802154: forbid monitor for add llsec dev + - net: ieee802154: forbid monitor for del llsec dev + - net: ieee802154: stop dump llsec devkeys for monitors + - net: ieee802154: forbid monitor for add llsec devkey + - net: ieee802154: forbid monitor for del llsec devkey + - net: ieee802154: stop dump llsec seclevels for monitors + - net: ieee802154: forbid monitor for add llsec seclevel + - pcnet32: Use pci_resource_len to validate PCI resource + - mac80211: clear sta->fast_rx when STA removed from 4-addr VLAN + - virt_wifi: Return micros for BSS TSF values + - Input: s6sy761 - fix coordinate read bit shift + - Input: i8042 - fix Pegatron C15B ID entry + - HID: wacom: set EV_KEY and EV_ABS only for non-HID_GENERIC type of devices + - dm verity fec: fix misaligned RS roots IO + - readdir: make sure to verify directory entry for legacy interfaces too + - arm64: fix inline asm in load_unaligned_zeropad() + - arm64: alternatives: Move length validation in alternative_{insn, endif} + - vfio/pci: Add missing range check in vfio_pci_mmap + - riscv: Fix spelling mistake "SPARSEMEM" to "SPARSMEM" + - scsi: libsas: Reset num_scatter if libata marks qc as NODATA + - netfilter: conntrack: do not print icmpv6 as unknown via /proc + - libnvdimm/region: Fix nvdimm_has_flush() to handle ND_REGION_ASYNC + - netfilter: bridge: add pre_exit hooks for ebtable unregistration + - netfilter: arp_tables: add pre_exit hook for table unregister + - net: macb: fix the restore of cmp registers + - netfilter: nft_limit: avoid possible divide error in nft_limit_init + - net: davicom: Fix regulator not turned off on failed probe + - net: sit: Unregister catch-all devices + - net: ip6_tunnel: Unregister catch-all devices + - i40e: fix the panic when running bpf in xdpdrv mode + - ibmvnic: avoid calling napi_disable() twice + - ibmvnic: remove duplicate napi_schedule call in do_reset function + - ibmvnic: remove duplicate napi_schedule call in open function + - gro: ensure frag0 meets IP header alignment + - ARM: footbridge: fix PCI interrupt mapping + - arm64: dts: allwinner: Fix SD card CD GPIO for SOPine systems + - r8169: remove fiddling with the PCIe max read request size + - r8169: simplify setting PCI_EXP_DEVCTL_NOSNOOP_EN + - r8169: fix performance regression related to PCIe max read request size + - r8169: improve rtl_jumbo_config + - r8169: tweak max read request size for newer chips also in jumbo mtu mode + - r8169: don't advertise pause in jumbo mode + - ARM: 9071/1: uprobes: Don't hook on thumb instructions + - net: phy: marvell: fix detection of PHY on Topaz switches + - Linux 5.4.114 + * Focal update: v5.4.113 upstream stable release (LP: #1926490) + - interconnect: core: fix error return code of icc_link_destroy() + - KVM: arm64: Hide system instruction access to Trace registers + - KVM: arm64: Disable guest access to trace filter controls + - drm/imx: imx-ldb: fix out of bounds array access warning + - gfs2: report "already frozen/thawed" errors + - drm/tegra: dc: Don't set PLL clock to 0Hz + - block: only update parent bi_status when bio fail + - radix tree test suite: Register the main thread with the RCU library + - idr test suite: Take RCU read lock in idr_find_test_1 + - idr test suite: Create anchor before launching throbber + - riscv,entry: fix misaligned base for excp_vect_table + - block: don't ignore REQ_NOWAIT for direct IO + - netfilter: x_tables: fix compat match/target pad out-of-bound write + - driver core: Fix locking bug in deferred_probe_timeout_work_func() + - perf tools: Use %define api.pure full instead of %pure-parser + - perf tools: Use %zd for size_t printf formats on 32-bit + - perf map: Tighten snprintf() string precision to pass gcc check on some + 32-bit arches + - xen/events: fix setting irq affinity + - Linux 5.4.113 + * Focal update: v5.4.112 upstream stable release (LP: #1926489) + - counter: stm32-timer-cnt: fix ceiling miss-alignment with reload register + - ALSA: aloop: Fix initialization of controls + - ALSA: hda/realtek: Fix speaker amp setup on Acer Aspire E1 + - ASoC: intel: atom: Stop advertising non working S24LE support + - nfc: fix refcount leak in llcp_sock_bind() + - nfc: fix refcount leak in llcp_sock_connect() + - nfc: fix memory leak in llcp_sock_connect() + - nfc: Avoid endless loops caused by repeated llcp_sock_connect() + - xen/evtchn: Change irq_info lock to raw_spinlock_t + - net: ipv6: check for validity before dereferencing cfg->fc_nlinfo.nlh + - net: dsa: lantiq_gswip: Let GSWIP automatically set the xMII clock + - drm/i915: Fix invalid access to ACPI _DSM objects + - gcov: re-fix clang-11+ support + - ia64: fix user_stack_pointer() for ptrace() + - nds32: flush_dcache_page: use page_mapping_file to avoid races with swapoff + - ocfs2: fix deadlock between setattr and dio_end_io_write + - fs: direct-io: fix missing sdio->boundary + - parisc: parisc-agp requires SBA IOMMU driver + - parisc: avoid a warning on u8 cast for cmpxchg on u8 pointers + - ARM: dts: turris-omnia: configure LED[2]/INTn pin as interrupt pin + - batman-adv: initialize "struct batadv_tvlv_tt_vlan_data"->reserved field + - ice: Increase control queue timeout + - ice: Fix for dereference of NULL pointer + - ice: Cleanup fltr list in case of allocation issues + - net: hso: fix null-ptr-deref during tty device unregistration + - ethernet/netronome/nfp: Fix a use after free in nfp_bpf_ctrl_msg_rx + - bpf, sockmap: Fix sk->prot unhash op reset + - net: ensure mac header is set in virtio_net_hdr_to_skb() + - i40e: Fix sparse warning: missing error code 'err' + - i40e: Fix sparse error: 'vsi->netdev' could be null + - net: sched: sch_teql: fix null-pointer dereference + - mac80211: fix TXQ AC confusion + - net: hsr: Reset MAC header for Tx path + - net-ipv6: bugfix - raw & sctp - switch to ipv6_can_nonlocal_bind() + - net: let skb_orphan_partial wake-up waiters. + - usbip: add sysfs_lock to synchronize sysfs code paths + - usbip: stub-dev synchronize sysfs code paths + - usbip: vudc synchronize sysfs code paths + - usbip: synchronize event handler with sysfs code paths + - i2c: turn recovery error on init to debug + - virtio_net: Add XDP meta data support + - net: dsa: lantiq_gswip: Don't use PHY auto polling + - net: dsa: lantiq_gswip: Configure all remaining GSWIP_MII_CFG bits + - xfrm: interface: fix ipv4 pmtu check to honor ip header df + - regulator: bd9571mwv: Fix AVS and DVFS voltage range + - net: xfrm: Localize sequence counter per network namespace + - esp: delete NETIF_F_SCTP_CRC bit from features for esp offload + - ASoC: SOF: Intel: hda: remove unnecessary parentheses + - ASoC: SOF: Intel: HDA: fix core status verification + - ASoC: wm8960: Fix wrong bclk and lrclk with pll enabled for some chips + - xfrm: Fix NULL pointer dereference on policy lookup + - i40e: Added Asym_Pause to supported link modes + - i40e: Fix kernel oops when i40e driver removes VF's + - hostfs: Use kasprintf() instead of fixed buffer formatting + - hostfs: fix memory handling in follow_link() + - amd-xgbe: Update DMA coherency values + - sch_red: fix off-by-one checks in red_check_params() + - arm64: dts: imx8mm/q: Fix pad control of SD1_DATA0 + - can: bcm/raw: fix msg_namelen values depending on CAN_REQUIRED_SIZE + - gianfar: Handle error code at MAC address change + - cxgb4: avoid collecting SGE_QBASE regs during traffic + - net:tipc: Fix a double free in tipc_sk_mcast_rcv + - ARM: dts: imx6: pbab01: Set vmmc supply for both SD interfaces + - net/ncsi: Avoid channel_monitor hrtimer deadlock + - nfp: flower: ignore duplicate merge hints from FW + - net: phy: broadcom: Only advertise EEE for supported modes + - ASoC: sunxi: sun4i-codec: fill ASoC card owner + - net/mlx5e: Fix ethtool indication of connector type + - net/mlx5: Don't request more than supported EQs + - net/rds: Fix a use after free in rds_message_map_pages + - soc/fsl: qbman: fix conflicting alignment attributes + - i40e: Fix display statistics for veb_tc + - drm/msm: Set drvdata to NULL when msm_drm_init() fails + - net: udp: Add support for getsockopt(..., ..., UDP_GRO, ..., ...); + - scsi: ufs: Fix irq return code + - scsi: ufs: Avoid busy-waiting by eliminating tag conflicts + - scsi: ufs: Use blk_{get,put}_request() to allocate and free TMFs + - scsi: ufs: core: Fix task management request completion timeout + - scsi: ufs: core: Fix wrong Task Tag used in task management request UPIUs + - net: macb: restore cmp registers on resume path + - clk: fix invalid usage of list cursor in register + - clk: fix invalid usage of list cursor in unregister + - workqueue: Move the position of debug_work_activate() in __queue_work() + - s390/cpcmd: fix inline assembly register clobbering + - perf inject: Fix repipe usage + - net: openvswitch: conntrack: simplify the return expression of + ovs_ct_limit_get_default_limit() + - openvswitch: fix send of uninitialized stack memory in ct limit reply + - net: hns3: clear VF down state bit before request link status + - net/mlx5: Fix placement of log_max_flow_counter + - net/mlx5: Fix PBMC register mapping + - RDMA/cxgb4: check for ipv6 address properly while destroying listener + - RDMA/addr: Be strict with gid size + - RAS/CEC: Correct ce_add_elem()'s returned values + - clk: socfpga: fix iomem pointer cast on 64-bit + - dt-bindings: net: ethernet-controller: fix typo in NVMEM + - net: sched: bump refcount for new action in ACT replace mode + - cfg80211: remove WARN_ON() in cfg80211_sme_connect + - net: tun: set tun->dev->addr_len during TUNSETLINK processing + - drivers: net: fix memory leak in atusb_probe + - drivers: net: fix memory leak in peak_usb_create_dev + - net: mac802154: Fix general protection fault + - net: ieee802154: nl-mac: fix check on panid + - net: ieee802154: fix nl802154 del llsec key + - net: ieee802154: fix nl802154 del llsec dev + - net: ieee802154: fix nl802154 add llsec key + - net: ieee802154: fix nl802154 del llsec devkey + - net: ieee802154: forbid monitor for set llsec params + - net: ieee802154: forbid monitor for del llsec seclevel + - net: ieee802154: stop dump llsec params for monitors + - Linux 5.4.112 + * crash utility fails on arm64 with cannot determine VA_BITS_ACTUAL + (LP: #1919275) + - arm64/crash_core: Export TCR_EL1.T1SZ in vmcoreinfo + * Focal update: v5.4.111 upstream stable release (LP: #1923874) + - ARM: dts: am33xx: add aliases for mmc interfaces + - bus: ti-sysc: Fix warning on unbind if reset is not deasserted + - platform/x86: intel-hid: Support Lenovo ThinkPad X1 Tablet Gen 2 + - bpf, x86: Use kvmalloc_array instead kmalloc_array in bpf_jit_comp + - net/mlx5e: Enforce minimum value check for ICOSQ size + - net: pxa168_eth: Fix a potential data race in pxa168_eth_remove + - mISDN: fix crash in fritzpci + - mac80211: choose first enabled channel for monitor + - drm/msm/adreno: a5xx_power: Don't apply A540 lm_setup to other GPUs + - drm/msm: Ratelimit invalid-fence message + - netfilter: conntrack: Fix gre tunneling over ipv6 + - platform/x86: thinkpad_acpi: Allow the FnLock LED to change state + - x86/build: Turn off -fcf-protection for realmode targets + - scsi: target: pscsi: Clean up after failure in pscsi_map_sg() + - ia64: mca: allocate early mca with GFP_ATOMIC + - ia64: fix format strings for err_inject + - cifs: revalidate mapping when we open files for SMB1 POSIX + - cifs: Silently ignore unknown oplock break handle + - nvme-mpath: replace direct_make_request with generic_make_request + - init/Kconfig: make COMPILE_TEST depend on !S390 + - init/Kconfig: make COMPILE_TEST depend on HAS_IOMEM + - Linux 5.4.111 + * Focal update: v5.4.110 upstream stable release (LP: #1923869) + - selinux: vsock: Set SID for socket returned by accept() + - ipv6: weaken the v4mapped source check + - modsign: print module name along with error message + - module: merge repetitive strings in module_sig_check() + - module: avoid *goto*s in module_sig_check() + - module: harden ELF info handling + - ext4: shrink race window in ext4_should_retry_alloc() + - ext4: fix bh ref count on error paths + - fs: nfsd: fix kconfig dependency warning for NFSD_V4 + - rpc: fix NULL dereference on kmalloc failure + - iomap: Fix negative assignment to unsigned sis->pages in + iomap_swapfile_activate + - ASoC: rt5640: Fix dac- and adc- vol-tlv values being off by a factor of 10 + - ASoC: rt5651: Fix dac- and adc- vol-tlv values being off by a factor of 10 + - ASoC: sgtl5000: set DAP_AVC_CTRL register to correct default value on probe + - ASoC: es8316: Simplify adc_pga_gain_tlv table + - ASoC: cs42l42: Fix Bitclock polarity inversion + - ASoC: cs42l42: Fix channel width support + - ASoC: cs42l42: Fix mixer volume control + - ASoC: cs42l42: Always wait at least 3ms after reset + - NFSD: fix error handling in NFSv4.0 callbacks + - powerpc: Force inlining of cpu_has_feature() to avoid build failure + - vhost: Fix vhost_vq_reset() + - scsi: st: Fix a use after free in st_open() + - scsi: qla2xxx: Fix broken #endif placement + - staging: comedi: cb_pcidas: fix request_irq() warn + - staging: comedi: cb_pcidas64: fix request_irq() warn + - ASoC: rt5659: Update MCLK rate in set_sysclk() + - thermal/core: Add NULL pointer check before using cooling device stats + - locking/ww_mutex: Simplify use_ww_ctx & ww_ctx handling + - ext4: do not iput inode under running transaction in ext4_rename() + - net: mvpp2: fix interrupt mask/unmask skip condition + - flow_dissector: fix TTL and TOS dissection on IPv4 fragments + - can: dev: move driver related infrastructure into separate subdir + - net: introduce CAN specific pointer in the struct net_device + - can: tcan4x5x: fix max register value + - brcmfmac: clear EAP/association status bits on linkdown events + - ath10k: hold RCU lock when calling ieee80211_find_sta_by_ifaddr() + - net: ethernet: aquantia: Handle error cleanup of start on open + - appletalk: Fix skb allocation size in loopback case + - net: wan/lmc: unregister device when no matching device is found + - bpf: Remove MTU check in __bpf_skb_max_len + - ALSA: usb-audio: Apply sample rate quirk to Logitech Connect + - ALSA: hda: Re-add dropped snd_poewr_change_state() calls + - ALSA: hda: Add missing sanity checks in PM prepare/complete callbacks + - ALSA: hda/realtek: fix a determine_headset_type issue for a Dell AIO + - ALSA: hda/realtek: call alc_update_headset_mode() in hp_automute_hook + - xtensa: move coprocessor_flush to the .text section + - PM: runtime: Fix race getting/putting suppliers at probe + - PM: runtime: Fix ordering in pm_runtime_get_suppliers() + - tracing: Fix stack trace event size + - mm: fix race by making init_zero_pfn() early_initcall + - drm/amdgpu: fix offset calculation in amdgpu_vm_bo_clear_mappings() + - drm/amdgpu: check alignment on CPU page for bo map + - reiserfs: update reiserfs_xattrs_initialized() condition + - vfio/nvlink: Add missing SPAPR_TCE_IOMMU depends + - pinctrl: rockchip: fix restore error in resume + - extcon: Add stubs for extcon_register_notifier_all() functions + - extcon: Fix error handling in extcon_dev_register + - firewire: nosy: Fix a use-after-free bug in nosy_ioctl() + - usbip: vhci_hcd fix shift out-of-bounds in vhci_hub_control() + - USB: quirks: ignore remote wake-up on Fibocom L850-GL LTE modem + - usb: musb: Fix suspend with devices connected for a64 + - usb: xhci-mtk: fix broken streams issue on 0.96 xHCI + - cdc-acm: fix BREAK rx code path adding necessary calls + - USB: cdc-acm: untangle a circular dependency between callback and softint + - USB: cdc-acm: downgrade message to debug + - USB: cdc-acm: fix double free on probe failure + - USB: cdc-acm: fix use-after-free after probe failure + - usb: gadget: udc: amd5536udc_pci fix null-ptr-dereference + - usb: dwc2: Fix HPRT0.PrtSusp bit setting for HiKey 960 board. + - usb: dwc2: Prevent core suspend when port connection flag is 0 + - staging: rtl8192e: Fix incorrect source in memcpy() + - staging: rtl8192e: Change state information from u16 to u8 + - drivers: video: fbcon: fix NULL dereference in fbcon_cursor() + - Linux 5.4.110 + * Focal update: v5.4.109 upstream stable release (LP: #1923220) + - hugetlbfs: hugetlb_fault_mutex_hash() cleanup + - net: fec: ptp: avoid register access when ipg clock is disabled + - powerpc/4xx: Fix build errors from mfdcr() + - atm: eni: dont release is never initialized + - atm: lanai: dont run lanai_dev_close if not open + - Revert "r8152: adjust the settings about MAC clock speed down for RTL8153" + - ALSA: hda: ignore invalid NHLT table + - ixgbe: Fix memleak in ixgbe_configure_clsu32 + - net: tehuti: fix error return code in bdx_probe() + - net: intel: iavf: fix error return code of iavf_init_get_resources() + - sun/niu: fix wrong RXMAC_BC_FRM_CNT_COUNT count + - gianfar: fix jumbo packets+napi+rx overrun crash + - cifs: ask for more credit on async read/write code paths + - cpufreq: blacklist Arm Vexpress platforms in cpufreq-dt-platdev + - gpiolib: acpi: Add missing IRQF_ONESHOT + - nfs: fix PNFS_FLEXFILE_LAYOUT Kconfig default + - NFS: Correct size calculation for create reply length + - net: hisilicon: hns: fix error return code of hns_nic_clear_all_rx_fetch() + - net: wan: fix error return code of uhdlc_init() + - net: davicom: Use platform_get_irq_optional() + - atm: uPD98402: fix incorrect allocation + - atm: idt77252: fix null-ptr-dereference + - cifs: change noisy error message to FYI + - irqchip/ingenic: Add support for the JZ4760 + - sparc64: Fix opcode filtering in handling of no fault loads + - habanalabs: Call put_pid() when releasing control device + - u64_stats,lockdep: Fix u64_stats_init() vs lockdep + - regulator: qcom-rpmh: Correct the pmic5_hfsmps515 buck + - drm/amd/display: Revert dram_clock_change_latency for DCN2.1 + - drm/amdgpu: fb BO should be ttm_bo_type_device + - drm/radeon: fix AGP dependency + - nvme: add NVME_REQ_CANCELLED flag in nvme_cancel_request() + - nvme-fc: return NVME_SC_HOST_ABORTED_CMD when a command has been aborted + - nvme-pci: add the DISABLE_WRITE_ZEROES quirk for a Samsung PM1725a + - nfs: we don't support removing system.nfs4_acl + - block: Suppress uevent for hidden device when removed + - ia64: fix ia64_syscall_get_set_arguments() for break-based syscalls + - ia64: fix ptrace(PTRACE_SYSCALL_INFO_EXIT) sign + - netsec: restore phy power state after controller reset + - platform/x86: intel-vbtn: Stop reporting SW_DOCK events + - squashfs: fix inode lookup sanity checks + - squashfs: fix xattr id and id lookup sanity checks + - kasan: fix per-page tags for non-page_alloc pages + - gcov: fix clang-11+ support + - ACPI: video: Add missing callback back for Sony VPCEH3U1E + - arm64: dts: ls1046a: mark crypto engine dma coherent + - arm64: dts: ls1012a: mark crypto engine dma coherent + - arm64: dts: ls1043a: mark crypto engine dma coherent + - ARM: dts: at91-sama5d27_som1: fix phy address to 7 + - integrity: double check iint_cache was initialized + - dm verity: fix DM_VERITY_OPTS_MAX value + - dm ioctl: fix out of bounds array access when no devices + - bus: omap_l3_noc: mark l3 irqs as IRQF_NO_THREAD + - veth: Store queue_mapping independently of XDP prog presence + - libbpf: Fix INSTALL flag order + - net/mlx5e: Don't match on Geneve options in case option masks are all zero + - ipv6: fix suspecious RCU usage warning + - macvlan: macvlan_count_rx() needs to be aware of preemption + - net: sched: validate stab values + - net: dsa: bcm_sf2: Qualify phydev->dev_flags based on port + - igc: Fix Pause Frame Advertising + - igc: Fix Supported Pause Frame Link Setting + - e1000e: add rtnl_lock() to e1000_reset_task + - e1000e: Fix error handling in e1000_set_d0_lplu_state_82571 + - net/qlcnic: Fix a use after free in qlcnic_83xx_get_minidump_template + - ftgmac100: Restart MAC HW once + - selftests/bpf: Set gopt opt_class to 0 if get tunnel opt failed + - netfilter: ctnetlink: fix dump of the expect mask attribute + - tcp: relookup sock for RST+ACK packets handled by obsolete req sock + - can: peak_usb: add forgotten supported devices + - can: flexcan: flexcan_chip_freeze(): fix chip freeze for missing bitrate + - can: kvaser_pciefd: Always disable bus load reporting + - can: c_can_pci: c_can_pci_remove(): fix use-after-free + - can: c_can: move runtime PM enable/disable to c_can_platform + - can: m_can: m_can_do_rx_poll(): fix extraneous msg loss warning + - can: m_can: m_can_rx_peripheral(): fix RX being blocked by errors + - mac80211: fix rate mask reset + - nfp: flower: fix pre_tun mask id allocation + - libbpf: Use SOCK_CLOEXEC when opening the netlink socket + - octeontx2-af: Fix irq free in rvu teardown + - octeontx2-af: fix infinite loop in unmapping NPC counter + - net: cdc-phonet: fix data-interface release on probe failure + - r8152: limit the RX buffer size of RTL8153A for USB 2.0 + - net: stmmac: dwmac-sun8i: Provide TX and RX fifo sizes + - selftests: forwarding: vxlan_bridge_1d: Fix vxlan ecn decapsulate value + - libbpf: Fix BTF dump of pointer-to-array-of-struct + - drm/msm: fix shutdown hook in case GPU components failed to bind + - arm64: kdump: update ppos when reading elfcorehdr + - PM: runtime: Defer suspending suppliers + - net/mlx5e: Fix error path for ethtool set-priv-flag + - PM: EM: postpone creating the debugfs dir till fs_initcall + - RDMA/cxgb4: Fix adapter LE hash errors while destroying ipv6 listening + server + - bpf: Don't do bpf_cgroup_storage_set() for kuprobe/tp programs + - ACPI: scan: Rearrange memory allocation in acpi_device_add() + - ACPI: scan: Use unique number for instance_no + - perf auxtrace: Fix auxtrace queue conflict + - block: recalculate segment count for multi-segment discards correctly + - scsi: Revert "qla2xxx: Make sure that aborted commands are freed" + - scsi: qedi: Fix error return code of qedi_alloc_global_queues() + - scsi: mpt3sas: Fix error return code of mpt3sas_base_attach() + - locking/mutex: Fix non debug version of mutex_lock_io_nested() + - x86/mem_encrypt: Correct physical address calculation in __set_clr_pte_enc() + - can: dev: Move device back to init netns on owning netns delete + - net: dsa: b53: VLAN filtering is global to all users + - net: qrtr: fix a kernel-infoleak in qrtr_recvmsg() + - mac80211: fix double free in ibss_leave + - ext4: add reclaim checks to xattr code + - can: peak_usb: Revert "can: peak_usb: add forgotten supported devices" + - xen-blkback: don't leak persistent grants from xen_blkbk_map() + - Linux 5.4.109 + * Focal update: v5.4.108 upstream stable release (LP: #1923214) + - ASoC: ak4458: Add MODULE_DEVICE_TABLE + - ASoC: ak5558: Add MODULE_DEVICE_TABLE + - ALSA: dice: fix null pointer dereference when node is disconnected + - ALSA: hda/realtek: apply pin quirk for XiaomiNotebook Pro + - ALSA: hda: generic: Fix the micmute led init state + - ALSA: hda/realtek: Apply headset-mic quirks for Xiaomi Redmibook Air + - Revert "PM: runtime: Update device status before letting suppliers suspend" + - ARM: 9030/1: entry: omit FP emulation for UND exceptions taken in kernel + mode + - ARM: 9044/1: vfp: use undef hook for VFP support detection + - btrfs: fix race when cloning extent buffer during rewind of an old root + - btrfs: fix slab cache flags for free space tree bitmap + - ASoC: fsl_ssi: Fix TDM slot setup for I2S mode + - ASoC: SOF: Intel: unregister DMIC device on probe error + - ASoC: SOF: intel: fix wrong poll bits in dsp power down + - ASoC: simple-card-utils: Do not handle device clock + - afs: Stop listxattr() from listing "afs.*" attributes + - nvme: fix Write Zeroes limitations + - nvme-tcp: fix possible hang when failing to set io queues + - nvme-tcp: fix a NULL deref when receiving a 0-length r2t PDU + - nvmet: don't check iosqes,iocqes for discovery controllers + - nfsd: Don't keep looking up unhashed files in the nfsd file cache + - NFSD: Repair misuse of sv_lock in 5.10.16-rt30. + - svcrdma: disable timeouts on rdma backchannel + - vfio: IOMMU_API should be selected + - sunrpc: fix refcount leak for rpc auth modules + - net/qrtr: fix __netdev_alloc_skb call + - kbuild: Fix for empty SUBLEVEL or PATCHLEVEL again + - riscv: Correct SPARSEMEM configuration + - scsi: lpfc: Fix some error codes in debugfs + - scsi: myrs: Fix a double free in myrs_cleanup() + - counter: stm32-timer-cnt: Report count function when SLAVE_MODE_DISABLED + - nvme-rdma: fix possible hang when failing to set io queues + - usb-storage: Add quirk to defeat Kindle's automatic unload + - usbip: Fix incorrect double assignment to udc->ud.tcp_rx + - USB: replace hardcode maximum usb string length by definition + - usb: gadget: configfs: Fix KASAN use-after-free + - usb: typec: tcpm: Invoke power_supply_changed for tcpm-source-psy- + - iio:adc:stm32-adc: Add HAS_IOMEM dependency + - iio:adc:qcom-spmi-vadc: add default scale to LR_MUX2_BAT_ID channel + - iio: adis16400: Fix an error code in adis16400_initial_setup() + - iio: gyro: mpu3050: Fix error handling in mpu3050_trigger_handler + - iio: adc: ad7949: fix wrong ADC result due to incorrect bit mask + - iio: hid-sensor-humidity: Fix alignment issue of timestamp channel + - iio: hid-sensor-prox: Fix scale not correct issue + - iio: hid-sensor-temperature: Fix issues of timestamp channel + - counter: stm32-timer-cnt: fix ceiling write max value + - PCI: rpadlpar: Fix potential drc_name corruption in store functions + - perf/x86/intel: Fix a crash caused by zero PEBS status + - x86/ioapic: Ignore IRQ2 again + - kernel, fs: Introduce and use set_restart_fn() and arch_set_restart_data() + - x86: Move TS_COMPAT back to asm/thread_info.h + - x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall() + - ext4: find old entry again if failed to rename whiteout + - ext4: do not try to set xattr into ea_inode if value is empty + - ext4: fix potential error in ext4_do_update_inode + - efi: use 32-bit alignment for efi_guid_t literals + - firmware/efi: Fix a use after bug in efi_mem_reserve_persistent + - genirq: Disable interrupts for force threaded handlers + - x86/apic/of: Fix CPU devicetree-node lookups + - cifs: Fix preauth hash corruption + - Linux 5.4.108 + * Focal update: v5.4.107 upstream stable release (LP: #1923210) + - KVM: arm64: nvhe: Save the SPE context early + - btrfs: scrub: Don't check free space before marking a block group RO + - drm/i915/gvt: Set SNOOP for PAT3 on BXT/APL to workaround GPU BB hang + - drm/i915/gvt: Fix mmio handler break on BXT/APL. + - drm/i915/gvt: Fix virtual display setup for BXT/APL + - drm/i915/gvt: Fix port number for BDW on EDID region setup + - drm/i915/gvt: Fix vfio_edid issue for BXT/APL + - fuse: fix live lock in fuse_iget() + - crypto: x86 - Regularize glue function prototypes + - crypto: aesni - Use TEST %reg,%reg instead of CMP $0,%reg + - crypto: x86/aes-ni-xts - use direct calls to and 4-way stride + - net: dsa: tag_mtk: fix 802.1ad VLAN egress + - net: dsa: b53: Support setting learning on port + - Linux 5.4.107 + + -- Tim Gardner Tue, 11 May 2021 12:38:29 -0600 + +linux-oracle (5.4.0-1045.49) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1045.49 -proposed tracker (LP: #1926814) + + * arm64 support (LP: #1925421) + - [config] oracle: Bring-up for arm64 support + - SAUCE: perf/smmuv3: Allow sharing MMIO registers with the SMMU driver + - SAUCE: arm64: Split the old READ_IMPLIES_EXEC workaround from executable + - mm/memory-failure: Add memory_failure_queue_kick() + - ACPI: APEI: Kick the memory_failure() queue for synchronous errors + - perf: Add Arm CMN-600 PMU driver + - perf: Add Arm CMN-600 DT binding + - PCI/ACPI: Add Ampere Altra SOC MCFG quirk + - mm: memblock: replace dereferences of memblock_region.nid with API calls + - mm: make early_pfn_to_nid() and related defintions close to each other + - mm: remove CONFIG_HAVE_MEMBLOCK_NODE_MAP option + - mm: free_area_init: use maximal zone PFNs rather than zone sizes + - mm: use free_area_init() instead of free_area_init_nodes() + - alpha: simplify detection of memory zone boundaries + - arm: simplify detection of memory zone boundaries + - arm64: simplify detection of memory zone boundaries for UMA configs + - csky: simplify detection of memory zone boundaries + - m68k: mm: simplify detection of memory zone boundaries + - parisc: simplify detection of memory zone boundaries + - sparc32: simplify detection of memory zone boundaries + - unicore32: simplify detection of memory zone boundaries + - xtensa: simplify detection of memory zone boundaries + - mm: memmap_init: iterate over memblock regions rather that check each PFN + - mm/page_alloc.c: initialize memmap of unavailable memory directly + - mm: pass migratetype into memmap_init_zone() and move_pfn_range_to_zone() + - mm: rename memmap_init() and memmap_init_zone() + - mm: simplify parater of function memmap_init_zone() + - mm/page_alloc.c: refactor initialization of struct page for holes in memory + layout + - mm: remove early_pfn_in_nid() and CONFIG_NODES_SPAN_OTHER_NODES + - mm: free_area_init: allow defining max_zone_pfn in descending order + - arc: fix memory initialization for systems with two memory banks + - mm: rename free_area_init_node() to free_area_init_memoryless_node() + - mm: clean up free_area_init_node() and its helpers + - mm: simplify find_min_pfn_with_active_regions() + - docs/vm: update memory-models documentation + - SAUCE: hwmon: Add Ampere Altra HW monitor driver + - arm64: NUMA: Kconfig: Increase NODES_SHIFT to 4 + - driver/perf: Add PMU driver for the ARM DMC-620 memory controller + - perf/arm_dmc620_pmu: Fix error return code in dmc620_pmu_device_probe() + - perf: arm_dsu: Support DSU ACPI devices + - SAUCE: perf: arm_dsu: Allow IRQ to be shared among devices. + - Perf: arm-cmn: Allow irq to be shared. + - perf: arm-cmn: Fix unsigned comparison to less than zero + - perf/arm-cmn: Fix PMU instance naming + - perf/arm-cmn: Move IRQs when migrating context + - [config] Disable vbox dkms for arm64 + + -- Khalid Elmously Sun, 02 May 2021 23:45:42 -0400 + +linux-oracle (5.4.0-1044.47) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1044.47 -proposed tracker (LP: #1923773) + + * Focal update: v5.4.106 upstream stable release (LP: #1920246) + - [Config] oracle: update abi for rc-cec + + * Disable Atari partition support for cloud kernels (LP: #1908264) + - [Config]: Disable ATARI_PARTITION + + [ Ubuntu: 5.4.0-73.82 ] + + * focal/linux: 5.4.0-73.82 -proposed tracker (LP: #1923781) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CIFS DFS entries not accessible with 5.4.0-71.74-generic (LP: #1923670) + - Revert "cifs: Set CIFS_MOUNT_USE_PREFIX_PATH flag on setting + cifs_sb->prepath." + * CVE-2021-29650 + - Revert "netfilter: x_tables: Update remaining dereference to RCU" + - Revert "netfilter: x_tables: Switch synchronization to RCU" + - netfilter: x_tables: Use correct memory barriers. + * LRMv4: switch to signing nvidia modules via the Ubuntu Modules signing key + (LP: #1918134) + - [Packaging] dkms-build{,--nvidia-N} sync back from LRMv4 + * 5.4 kernel: when iommu is on crashdump fails (LP: #1922738) + - iommu/vt-d: Refactor find_domain() helper + - iommu/vt-d: Add attach_deferred() helper + - iommu/vt-d: Move deferred device attachment into helper function + - iommu/vt-d: Do deferred attachment in iommu_need_mapping() + - iommu/vt-d: Remove deferred_attach_domain() + - iommu/vt-d: Simplify check in identity_mapping() + * Backport mlx5e fix for tunnel offload (LP: #1921769) + - net/mlx5e: Check tunnel offload is required before setting SWP + * Bcache bypasse writeback on caching device with fragmentation (LP: #1900438) + - bcache: consider the fragmentation when update the writeback rate + * Fix implicit declaration warnings for kselftests/memfd test on newer + releases (LP: #1910323) + - selftests/memfd: Fix implicit declaration warnings + * net/mlx5e: Add missing capability check for uplink follow (LP: #1921104) + - net/mlx5e: Add missing capability check for uplink follow + * [UBUNUT 21.04] s390/vtime: fix increased steal time accounting + (LP: #1921498) + - s390/vtime: fix increased steal time accounting + * Mute/Mic-mute LEDs are not work on HP 850/840/440 G8 Laptops (LP: #1920030) + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 840 G8 + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 440 G8 + - ALSA: hda/realtek: fix mute/micmute LEDs for HP 850 G8 + * Focal update: v5.4.106 upstream stable release (LP: #1920246) + - uapi: nfnetlink_cthelper.h: fix userspace compilation error + - powerpc/pseries: Don't enforce MSI affinity with kdump + - ath9k: fix transmitting to stations in dynamic SMPS mode + - net: Fix gro aggregation for udp encaps with zero csum + - net: check if protocol extracted by virtio_net_hdr_set_proto is correct + - net: avoid infinite loop in mpls_gso_segment when mpls_hlen == 0 + - sh_eth: fix TRSCER mask for SH771x + - can: skb: can_skb_set_owner(): fix ref counting if socket was closed before + setting skb ownership + - can: flexcan: assert FRZ bit in flexcan_chip_freeze() + - can: flexcan: enable RX FIFO after FRZ/HALT valid + - can: flexcan: invoke flexcan_chip_freeze() to enter freeze mode + - can: tcan4x5x: tcan4x5x_init(): fix initialization - clear MRAM before + entering Normal Mode + - tcp: add sanity tests to TCP_QUEUE_SEQ + - netfilter: nf_nat: undo erroneous tcp edemux lookup + - netfilter: x_tables: gpf inside xt_find_revision() + - selftests/bpf: No need to drop the packet when there is no geneve opt + - selftests/bpf: Mask bpf_csum_diff() return value to 16 bits in test_verifier + - samples, bpf: Add missing munmap in xdpsock + - ibmvnic: always store valid MAC address + - mt76: dma: do not report truncated frames to mac80211 + - powerpc/603: Fix protection of user pages mapped with PROT_NONE + - mount: fix mounting of detached mounts onto targets that reside on shared + mounts + - cifs: return proper error code in statfs(2) + - Revert "mm, slub: consider rest of partial list if acquire_slab() fails" + - net: enetc: don't overwrite the RSS indirection table when initializing + - net/mlx4_en: update moderation when config reset + - net: stmmac: fix incorrect DMA channel intr enable setting of EQoS v4.10 + - nexthop: Do not flush blackhole nexthops when loopback goes down + - net: sched: avoid duplicates in classes dump + - net: usb: qmi_wwan: allow qmimux add/del with master up + - netdevsim: init u64 stats for 32bit hardware + - cipso,calipso: resolve a number of problems with the DOI refcounts + - net: lapbether: Remove netif_start_queue / netif_stop_queue + - net: davicom: Fix regulator not turned off on failed probe + - net: davicom: Fix regulator not turned off on driver removal + - net: qrtr: fix error return code of qrtr_sendmsg() + - ixgbe: fail to create xfrm offload of IPsec tunnel mode SA + - net: stmmac: stop each tx channel independently + - net: stmmac: fix watchdog timeout during suspend/resume stress test + - selftests: forwarding: Fix race condition in mirror installation + - perf traceevent: Ensure read cmdlines are null terminated. + - net: hns3: fix query vlan mask value error for flow director + - net: hns3: fix bug when calculating the TCAM table info + - s390/cio: return -EFAULT if copy_to_user() fails again + - bnxt_en: reliably allocate IRQ table on reset to avoid crash + - drm/compat: Clear bounce structures + - drm/shmem-helper: Check for purged buffers in fault handler + - drm/shmem-helper: Don't remove the offset in vm_area_struct pgoff + - drm: meson_drv add shutdown function + - s390/cio: return -EFAULT if copy_to_user() fails + - s390/crypto: return -EFAULT if copy_to_user() fails + - qxl: Fix uninitialised struct field head.surface_id + - sh_eth: fix TRSCER mask for R7S9210 + - media: usbtv: Fix deadlock on suspend + - media: v4l: vsp1: Fix uif null pointer access + - media: v4l: vsp1: Fix bru null pointer access + - media: rc: compile rc-cec.c into rc-core + - [Config] update abi for rc-cec + - net: hns3: fix error mask definition of flow director + - net: enetc: initialize RFS/RSS memories for unused ports too + - net: phy: fix save wrong speed and duplex problem if autoneg is on + - i2c: rcar: faster irq code to minimize HW race condition + - i2c: rcar: optimize cacheline to minimize HW race condition + - udf: fix silent AED tagLocation corruption + - mmc: mxs-mmc: Fix a resource leak in an error handling path in + 'mxs_mmc_probe()' + - mmc: mediatek: fix race condition between msdc_request_timeout and irq + - Platform: OLPC: Fix probe error handling + - powerpc/pci: Add ppc_md.discover_phbs() + - spi: stm32: make spurious and overrun interrupts visible + - powerpc: improve handling of unrecoverable system reset + - powerpc/perf: Record counter overflow always if SAMPLE_IP is unset + - HID: logitech-dj: add support for the new lightspeed connection iteration + - powerpc/64: Fix stack trace not displaying final frame + - iommu/amd: Fix performance counter initialization + - sparc32: Limit memblock allocation to low memory + - sparc64: Use arch_validate_flags() to validate ADI flag + - Input: applespi - don't wait for responses to commands indefinitely. + - PCI: xgene-msi: Fix race in installing chained irq handler + - PCI: mediatek: Add missing of_node_put() to fix reference leak + - kbuild: clamp SUBLEVEL to 255 + - PCI: Fix pci_register_io_range() memory leak + - i40e: Fix memory leak in i40e_probe + - s390/smp: __smp_rescan_cpus() - move cpumask away from stack + - sysctl.c: fix underflow value setting risk in vm_table + - scsi: libiscsi: Fix iscsi_prep_scsi_cmd_pdu() error handling + - scsi: target: core: Add cmd length set before cmd complete + - scsi: target: core: Prevent underflow for service actions + - ALSA: usb: Add Plantronics C320-M USB ctrl msg delay quirk + - ALSA: hda/hdmi: Cancel pending works before suspend + - ALSA: hda/ca0132: Add Sound BlasterX AE-5 Plus support + - ALSA: hda: Drop the BATCH workaround for AMD controllers + - ALSA: hda: Flush pending unsolicited events before suspend + - ALSA: hda: Avoid spurious unsol event handling during S3/S4 + - ALSA: usb-audio: Fix "cannot get freq eq" errors on Dell AE515 sound bar + - ALSA: usb-audio: Apply the control quirk to Plantronics headsets + - Revert 95ebabde382c ("capabilities: Don't allow writing ambiguous v3 file + capabilities") + - arm64: kasan: fix page_alloc tagging with DEBUG_VIRTUAL + - s390/dasd: fix hanging DASD driver unbind + - s390/dasd: fix hanging IO request during DASD driver unbind + - software node: Fix node registration + - mmc: core: Fix partition switch time for eMMC + - mmc: cqhci: Fix random crash when remove mmc module/card + - Goodix Fingerprint device is not a modem + - USB: gadget: u_ether: Fix a configfs return code + - usb: gadget: f_uac2: always increase endpoint max_packet_size by one audio + slot + - usb: gadget: f_uac1: stop playback on function disable + - usb: dwc3: qcom: Add missing DWC3 OF node refcount decrement + - usb: dwc3: qcom: Honor wakeup enabled/disabled state + - USB: usblp: fix a hang in poll() if disconnected + - usb: renesas_usbhs: Clear PIPECFG for re-enabling pipe with other EPNUM + - usb: xhci: do not perform Soft Retry for some xHCI hosts + - xhci: Improve detection of device initiated wake signal. + - usb: xhci: Fix ASMedia ASM1042A and ASM3242 DMA addressing + - xhci: Fix repeated xhci wake after suspend due to uncleared internal wake + state + - USB: serial: io_edgeport: fix memory leak in edge_startup + - USB: serial: ch341: add new Product ID + - USB: serial: cp210x: add ID for Acuity Brands nLight Air Adapter + - USB: serial: cp210x: add some more GE USB IDs + - usbip: fix stub_dev to check for stream socket + - usbip: fix vhci_hcd to check for stream socket + - usbip: fix vudc to check for stream socket + - usbip: fix stub_dev usbip_sockfd_store() races leading to gpf + - usbip: fix vhci_hcd attach_store() races leading to gpf + - usbip: fix vudc usbip_sockfd_store races leading to gpf + - misc/pvpanic: Export module FDT device table + - misc: fastrpc: restrict user apps from sending kernel RPC messages + - staging: rtl8192u: fix ->ssid overflow in r8192_wx_set_scan() + - staging: rtl8188eu: prevent ->ssid overflow in rtw_wx_set_scan() + - staging: rtl8712: unterminated string leads to read overflow + - staging: rtl8188eu: fix potential memory corruption in + rtw_check_beacon_data() + - staging: ks7010: prevent buffer overflow in ks_wlan_set_scan() + - staging: rtl8712: Fix possible buffer overflow in r8712_sitesurvey_cmd + - staging: rtl8192e: Fix possible buffer overflow in _rtl92e_wx_set_scan + - staging: comedi: addi_apci_1032: Fix endian problem for COS sample + - staging: comedi: addi_apci_1500: Fix endian problem for command sample + - staging: comedi: adv_pci1710: Fix endian problem for AI command data + - staging: comedi: das6402: Fix endian problem for AI command data + - staging: comedi: das800: Fix endian problem for AI command data + - staging: comedi: dmm32at: Fix endian problem for AI command data + - staging: comedi: me4000: Fix endian problem for AI command data + - staging: comedi: pcl711: Fix endian problem for AI command data + - staging: comedi: pcl818: Fix endian problem for AI command data + - sh_eth: fix TRSCER mask for R7S72100 + - arm64/mm: Fix pfn_valid() for ZONE_DEVICE based memory + - SUNRPC: Set memalloc_nofs_save() for sync tasks + - NFS: Don't revalidate the directory permissions on a lookup failure + - NFS: Don't gratuitously clear the inode cache when lookup failed + - NFSv4.2: fix return value of _nfs4_get_security_label() + - block: rsxx: fix error return code of rsxx_pci_probe() + - configfs: fix a use-after-free in __configfs_open_file + - arm64: mm: use a 48-bit ID map when possible on 52-bit VA builds + - hrtimer: Update softirq_expires_next correctly after + __hrtimer_get_next_event() + - stop_machine: mark helpers __always_inline + - include/linux/sched/mm.h: use rcu_dereference in in_vfork() + - zram: fix return value on writeback_store + - sched/membarrier: fix missing local execution of ipi_sync_rq_state() + - powerpc/64s: Fix instruction encoding for lis in ppc_function_entry() + - binfmt_misc: fix possible deadlock in bm_register_write + - x86/unwind/orc: Disable KASAN checking in the ORC unwinder, part 2 + - KVM: arm64: Fix exclusive limit for IPA size + - nvme: unlink head after removing last namespace + - nvme: release namespace head reference on error + - KVM: arm64: Ensure I-cache isolation between vcpus of a same VM + - KVM: arm64: Reject VM creation when the default IPA size is unsupported + - xen/events: reset affinity of 2-level event when tearing it down + - xen/events: don't unmask an event channel when an eoi is pending + - xen/events: avoid handling the same event on two cpus at the same time + - Linux 5.4.106 + * Focal update: v5.4.105 upstream stable release (LP: #1920244) + - net: dsa: add GRO support via gro_cells + - dm table: fix iterate_devices based device capability checks + - dm table: fix DAX iterate_devices based device capability checks + - dm table: fix zoned iterate_devices based device capability checks + - ACPICA: Fix race in generic_serial_bus (I2C) and GPIO op_region parameter + handling + - iommu/amd: Fix sleeping in atomic in increase_address_space() + - mwifiex: pcie: skip cancel_work_sync() on reset failure path + - platform/x86: acer-wmi: Cleanup ACER_CAP_FOO defines + - platform/x86: acer-wmi: Cleanup accelerometer device handling + - platform/x86: acer-wmi: Add new force_caps module parameter + - platform/x86: acer-wmi: Add ACER_CAP_SET_FUNCTION_MODE capability flag + - platform/x86: acer-wmi: Add support for SW_TABLET_MODE on Switch devices + - platform/x86: acer-wmi: Add ACER_CAP_KBD_DOCK quirk for the Aspire Switch + 10E SW3-016 + - HID: mf: add support for 0079:1846 Mayflash/Dragonrise USB Gamecube Adapter + - media: cx23885: add more quirks for reset DMA on some AMD IOMMU + - ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 + - ASoC: Intel: bytcr_rt5640: Add quirk for ARCHOS Cesium 140 + - PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller + - misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom + - drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register + - mmc: sdhci-of-dwcmshc: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN + - HID: i2c-hid: Add I2C_HID_QUIRK_NO_IRQ_AFTER_RESET for ITE8568 EC on Voyo + Winpad A15 + - nvme-pci: mark Seagate Nytro XM1440 as QUIRK_NO_NS_DESC_LIST. + - nvme-pci: add quirks for Lexar 256GB SSD + - Linux 5.4.105 + * Focal update: v5.4.104 upstream stable release (LP: #1920238) + - tpm, tpm_tis: Decorate tpm_tis_gen_interrupt() with request_locality() + - tpm, tpm_tis: Decorate tpm_get_timeouts() with request_locality() + - btrfs: raid56: simplify tracking of Q stripe presence + - btrfs: fix raid6 qstripe kmap + - btrfs: validate qgroup inherit for SNAP_CREATE_V2 ioctl + - btrfs: free correct amount of space in btrfs_delayed_inode_reserve_metadata + - btrfs: unlock extents in btrfs_zero_range in case of quota reservation + errors + - btrfs: fix warning when creating a directory with smack enabled + - PM: runtime: Update device status before letting suppliers suspend + - dm bufio: subtract the number of initial sectors in dm_bufio_get_device_size + - dm verity: fix FEC for RS roots unaligned to block size + - drm/amdgpu: fix parameter error of RREG32_PCIE() in amdgpu_regs_pcie + - arm64: ptrace: Fix seccomp of traced syscall -1 (NO_SYSCALL) + - crypto - shash: reduce minimum alignment of shash_desc structure + - usbip: tools: fix build error for multiple definition + - ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits + - RDMA/rxe: Fix missing kconfig dependency on CRYPTO + - IB/mlx5: Add missing error code + - ALSA: hda: intel-nhlt: verify config type + - ftrace: Have recordmcount use w8 to read relp->r_info in + arm64_is_fake_mcount + - rsxx: Return -EFAULT if copy_to_user() fails + - r8169: fix resuming from suspend on RTL8105e if machine runs on battery + - Linux 5.4.104 + * Focal update: v5.4.103 upstream stable release (LP: #1920235) + - net: usb: qmi_wwan: support ZTE P685M modem + - nvme-pci: refactor nvme_unmap_data + - nvme-pci: fix error unwind in nvme_map_data + - arm64 module: set plt* section addresses to 0x0 + - MIPS: VDSO: Use CLANG_FLAGS instead of filtering out '--target=' + - JFS: more checks for invalid superblock + - udlfb: Fix memory leak in dlfb_usb_probe + - media: mceusb: sanity check for prescaler value + - erofs: fix shift-out-of-bounds of blkszbits + - media: v4l2-ctrls.c: fix shift-out-of-bounds in std_validate + - xfs: Fix assert failure in xfs_setattr_size() + - net/af_iucv: remove WARN_ONCE on malformed RX packets + - smackfs: restrict bytes count in smackfs write functions + - net: fix up truesize of cloned skb in skb_prepare_for_shift() + - nbd: handle device refs for DESTROY_ON_DISCONNECT properly + - mm/hugetlb.c: fix unnecessary address expansion of pmd sharing + - net: bridge: use switchdev for port flags set through sysfs too + - net: ag71xx: remove unnecessary MTU reservation + - net: fix dev_ifsioc_locked() race condition + - dt-bindings: ethernet-controller: fix fixed-link specification + - dt-bindings: net: btusb: DT fix s/interrupt-name/interrupt-names/ + - MIPS: Drop 32-bit asm string functions + - drm/virtio: use kvmalloc for large allocations + - rsi: Fix TX EAPOL packet handling against iwlwifi AP + - rsi: Move card interrupt handling to RX thread + - staging: fwserial: Fix error handling in fwserial_create + - x86/reboot: Add Zotac ZBOX CI327 nano PCI reboot quirk + - vt/consolemap: do font sum unsigned + - wlcore: Fix command execute failure 19 for wl12xx + - Bluetooth: hci_h5: Set HCI_QUIRK_SIMULTANEOUS_DISCOVERY for btrtl + - pktgen: fix misuse of BUG_ON() in pktgen_thread_worker() + - ath10k: fix wmi mgmt tx queue full due to race condition + - x86/build: Treat R_386_PLT32 relocation as R_386_PC32 + - Bluetooth: Fix null pointer dereference in amp_read_loc_assoc_final_data + - staging: most: sound: add sanity check for function argument + - staging: bcm2835-audio: Replace unsafe strcpy() with strscpy() + - brcmfmac: Add DMI nvram filename quirk for Predia Basic tablet + - brcmfmac: Add DMI nvram filename quirk for Voyo winpad A15 tablet + - drm/hisilicon: Fix use-after-free + - crypto: tcrypt - avoid signed overflow in byte count + - drm/amdgpu: Add check to prevent IH overflow + - PCI: Add a REBAR size quirk for Sapphire RX 5600 XT Pulse + - drm/amd/display: Guard against NULL pointer deref when get_i2c_info fails + - media: uvcvideo: Allow entities with no pads + - f2fs: handle unallocated section and zone on pinned/atgc + - f2fs: fix to set/clear I_LINKABLE under i_lock + - nvme-core: add cancel tagset helpers + - nvme-rdma: add clean action for failed reconnection + - nvme-tcp: add clean action for failed reconnection + - ASoC: Intel: Add DMI quirk table to soc_intel_is_byt_cr() + - btrfs: fix error handling in commit_fs_roots + - perf/x86/kvm: Add Cascade Lake Xeon steppings to isolation_ucodes[] + - parisc: Bump 64-bit IRQ stack size to 64 KB + - sched/features: Fix hrtick reprogramming + - ASoC: Intel: bytcr_rt5640: Add quirk for the Estar Beauty HD MID 7316R + tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Voyo Winpad A15 tablet + - ASoC: Intel: bytcr_rt5651: Add quirk for the Jumper EZpad 7 tablet + - ASoC: Intel: bytcr_rt5640: Add quirk for the Acer One S1002 tablet + - Xen/gnttab: handle p2m update errors on a per-slot basis + - xen-netback: respect gnttab_map_refs()'s return value + - zsmalloc: account the number of compacted pages correctly + - swap: fix swapfile read/write offset + - media: v4l: ioctl: Fix memory leak in video_usercopy + - ALSA: hda/realtek: Add quirk for Clevo NH55RZQ + - ALSA: hda/realtek: Add quirk for Intel NUC 10 + - ALSA: hda/realtek: Apply dual codec quirks for MSI Godlike X570 board + - Linux 5.4.103 + * Focal update: v5.4.102 upstream stable release (LP: #1918974) + - vmlinux.lds.h: add DWARF v5 sections + - kvm: x86: replace kvm_spec_ctrl_test_value with runtime test on the host + - debugfs: be more robust at handling improper input in debugfs_lookup() + - debugfs: do not attempt to create a new file before the filesystem is + initalized + - kdb: Make memory allocations more robust + - PCI: qcom: Use PHY_REFCLK_USE_PAD only for ipq8064 + - PCI: Decline to resize resources if boot config must be preserved + - virt: vbox: Do not use wait_event_interruptible when called from kernel + context + - bfq: Avoid false bfq queue merging + - ALSA: usb-audio: Fix PCM buffer allocation in non-vmalloc mode + - MIPS: vmlinux.lds.S: add missing PAGE_ALIGNED_DATA() section + - random: fix the RNDRESEEDCRNG ioctl + - ath10k: Fix error handling in case of CE pipe init failure + - Bluetooth: btqcomsmd: Fix a resource leak in error handling paths in the + probe function + - Bluetooth: hci_uart: Fix a race for write_work scheduling + - Bluetooth: Fix initializing response id after clearing struct + - ARM: dts: exynos: correct PMIC interrupt trigger level on Artik 5 + - ARM: dts: exynos: correct PMIC interrupt trigger level on Monk + - ARM: dts: exynos: correct PMIC interrupt trigger level on Rinato + - ARM: dts: exynos: correct PMIC interrupt trigger level on Spring + - ARM: dts: exynos: correct PMIC interrupt trigger level on Arndale Octa + - ARM: dts: exynos: correct PMIC interrupt trigger level on Odroid XU3 family + - arm64: dts: exynos: correct PMIC interrupt trigger level on TM2 + - arm64: dts: exynos: correct PMIC interrupt trigger level on Espresso + - memory: mtk-smi: Fix PM usage counter unbalance in mtk_smi ops + - bpf: Add bpf_patch_call_args prototype to include/linux/bpf.h + - bpf: Avoid warning when re-casting __bpf_call_base into __bpf_call_base_args + - arm64: dts: allwinner: A64: properly connect USB PHY to port 0 + - arm64: dts: allwinner: H6: properly connect USB PHY to port 0 + - arm64: dts: allwinner: Drop non-removable from SoPine/LTS SD card + - arm64: dts: allwinner: H6: Allow up to 150 MHz MMC bus frequency + - arm64: dts: allwinner: A64: Limit MMC2 bus frequency to 150 MHz + - cpufreq: brcmstb-avs-cpufreq: Free resources in error path + - cpufreq: brcmstb-avs-cpufreq: Fix resource leaks in ->remove() + - ACPICA: Fix exception code class checks + - usb: gadget: u_audio: Free requests only after callback + - Bluetooth: drop HCI device reference before return + - Bluetooth: Put HCI device if inquiry procedure interrupts + - memory: ti-aemif: Drop child node when jumping out loop + - ARM: dts: Configure missing thermal interrupt for 4430 + - usb: dwc2: Do not update data length if it is 0 on inbound transfers + - usb: dwc2: Abort transaction after errors with unknown reason + - usb: dwc2: Make "trimming xfer length" a debug message + - staging: rtl8723bs: wifi_regd.c: Fix incorrect number of regulatory rules + - ARM: dts: armada388-helios4: assign pinctrl to LEDs + - ARM: dts: armada388-helios4: assign pinctrl to each fan + - arm64: dts: armada-3720-turris-mox: rename u-boot mtd partition to + a53-firmware + - Bluetooth: btusb: Fix memory leak in btusb_mtk_wmt_recv + - arm64: dts: msm8916: Fix reserved and rfsa nodes unit address + - ARM: s3c: fix fiq for clang IAS + - soc: aspeed: snoop: Add clock control logic + - bpf_lru_list: Read double-checked variable once without lock + - ath9k: fix data bus crash when setting nf_override via debugfs + - ibmvnic: Set to CLOSED state even on error + - bnxt_en: reverse order of TX disable and carrier off + - xen/netback: fix spurious event detection for common event case + - mac80211: fix potential overflow when multiplying to u32 integers + - bpf: Fix bpf_fib_lookup helper MTU check for SKB ctx + - tcp: fix SO_RCVLOWAT related hangs under mem pressure + - net: axienet: Handle deferred probe on clock properly + - cxgb4/chtls/cxgbit: Keeping the max ofld immediate data size same in cxgb4 + and ulds + - b43: N-PHY: Fix the update of coef for the PHY revision >= 3case + - ibmvnic: add memory barrier to protect long term buffer + - ibmvnic: skip send_request_unmap for timeout reset + - net: amd-xgbe: Reset the PHY rx data path when mailbox command timeout + - net: amd-xgbe: Fix NETDEV WATCHDOG transmit queue timeout warning + - net: amd-xgbe: Reset link when the link never comes back + - net: amd-xgbe: Fix network fluctuations when using 1G BELFUSE SFP + - net: mvneta: Remove per-cpu queue mapping for Armada 3700 + - fbdev: aty: SPARC64 requires FB_ATY_CT + - drm/gma500: Fix error return code in psb_driver_load() + - gma500: clean up error handling in init + - drm/fb-helper: Add missed unlocks in setcmap_legacy() + - crypto: sun4i-ss - linearize buffers content must be kept + - crypto: sun4i-ss - fix kmap usage + - crypto: arm64/aes-ce - really hide slower algos when faster ones are enabled + - drm/amdgpu: Fix macro name _AMDGPU_TRACE_H_ in preprocessor if condition + - MIPS: c-r4k: Fix section mismatch for loongson2_sc_init + - MIPS: lantiq: Explicitly compare LTQ_EBU_PCC_ISTAT against 0 + - media: i2c: ov5670: Fix PIXEL_RATE minimum value + - media: imx: Unregister csc/scaler only if registered + - media: imx: Fix csc/scaler unregister + - media: camss: missing error code in msm_video_register() + - media: vsp1: Fix an error handling path in the probe function + - media: em28xx: Fix use-after-free in em28xx_alloc_urbs + - media: media/pci: Fix memleak in empress_init + - media: tm6000: Fix memleak in tm6000_start_stream + - media: aspeed: fix error return code in aspeed_video_setup_video() + - ASoC: cs42l56: fix up error handling in probe + - evm: Fix memleak in init_desc + - crypto: bcm - Rename struct device_private to bcm_device_private + - drm/sun4i: tcon: fix inverted DCLK polarity + - MIPS: properly stop .eh_frame generation + - bsg: free the request before return error code + - drm/amd/display: Fix 10/12 bpc setup in DCE output bit depth reduction. + - drm/amd/display: Fix HDMI deep color output for DCE 6-11. + - media: software_node: Fix refcounts in software_node_get_next_child() + - media: lmedm04: Fix misuse of comma + - media: qm1d1c0042: fix error return code in qm1d1c0042_init() + - media: cx25821: Fix a bug when reallocating some dma memory + - media: pxa_camera: declare variable when DEBUG is defined + - media: uvcvideo: Accept invalid bFormatIndex and bFrameIndex values + - sched/eas: Don't update misfit status if the task is pinned + - mtd: parser: imagetag: fix error codes in + bcm963xx_parse_imagetag_partitions() + - crypto: talitos - Work around SEC6 ERRATA (AES-CTR mode data size error) + - drm/nouveau: bail out of nouveau_channel_new if channel init fails + - ata: ahci_brcm: Add back regulators management + - ASoC: cpcap: fix microphone timeslot mask + - mtd: parsers: afs: Fix freeing the part name memory in failure + - f2fs: fix to avoid inconsistent quota data + - drm/amdgpu: Prevent shift wrapping in amdgpu_read_mask() + - f2fs: fix a wrong condition in __submit_bio + - Drivers: hv: vmbus: Avoid use-after-free in vmbus_onoffer_rescind() + - ASoC: SOF: debug: Fix a potential issue on string buffer termination + - btrfs: clarify error returns values in __load_free_space_cache + - hwrng: timeriomem - Fix cooldown period calculation + - crypto: ecdh_helper - Ensure 'len >= secret.len' in decode_key() + - ima: Free IMA measurement buffer on error + - ima: Free IMA measurement buffer after kexec syscall + - ASoC: simple-card-utils: Fix device module clock + - fs/jfs: fix potential integer overflow on shift of a int + - jffs2: fix use after free in jffs2_sum_write_data() + - ubifs: Fix memleak in ubifs_init_authentication + - ubifs: Fix error return code in alloc_wbufs() + - capabilities: Don't allow writing ambiguous v3 file capabilities + - HSI: Fix PM usage counter unbalance in ssi_hw_init + - clk: meson: clk-pll: fix initializing the old rate (fallback) for a PLL + - clk: meson: clk-pll: make "ret" a signed integer + - clk: meson: clk-pll: propagate the error from meson_clk_pll_set_rate() + - quota: Fix memory leak when handling corrupted quota file + - i2c: iproc: handle only slave interrupts which are enabled + - i2c: iproc: update slave isr mask (ISR_MASK_SLAVE) + - i2c: iproc: handle master read request + - spi: cadence-quadspi: Abort read if dummy cycles required are too many + - clk: sunxi-ng: h6: Fix CEC clock + - HID: core: detect and skip invalid inputs to snto32() + - RDMA/siw: Fix handling of zero-sized Read and Receive Queues. + - dmaengine: fsldma: Fix a resource leak in the remove function + - dmaengine: fsldma: Fix a resource leak in an error handling path of the + probe function + - dmaengine: owl-dma: Fix a resource leak in the remove function + - dmaengine: hsu: disable spurious interrupt + - mfd: bd9571mwv: Use devm_mfd_add_devices() + - fdt: Properly handle "no-map" field in the memory region + - of/fdt: Make sure no-map does not remove already reserved regions + - power: reset: at91-sama5d2_shdwc: fix wkupdbc mask + - rtc: s5m: select REGMAP_I2C + - clocksource/drivers/ixp4xx: Select TIMER_OF when needed + - clocksource/drivers/mxs_timer: Add missing semicolon when DEBUG is defined + - RDMA/mlx5: Use the correct obj_id upon DEVX TIR creation + - clk: sunxi-ng: h6: Fix clock divider range on some clocks + - regulator: axp20x: Fix reference cout leak + - certs: Fix blacklist flag type confusion + - regulator: s5m8767: Fix reference count leak + - spi: atmel: Put allocated master before return + - regulator: s5m8767: Drop regulators OF node reference + - regulator: core: Avoid debugfs: Directory ... already present! error + - isofs: release buffer head before return + - auxdisplay: ht16k33: Fix refresh rate handling + - objtool: Fix error handling for STD/CLD warnings + - objtool: Fix ".cold" section suffix check for newer versions of GCC + - IB/umad: Return EIO in case of when device disassociated + - IB/umad: Return EPOLLERR in case of when device disassociated + - KVM: PPC: Make the VMX instruction emulation routines static + - powerpc/47x: Disable 256k page size + - mmc: sdhci-sprd: Fix some resource leaks in the remove function + - mmc: usdhi6rol0: Fix a resource leak in the error handling path of the probe + - mmc: renesas_sdhi_internal_dmac: Fix DMA buffer alignment from 8 to + 128-bytes + - ARM: 9046/1: decompressor: Do not clear SCTLR.nTLSMD for ARMv7+ cores + - i2c: qcom-geni: Store DMA mapping data in geni_i2c_dev struct + - amba: Fix resource leak for drivers without .remove + - IB/mlx5: Return appropriate error code instead of ENOMEM + - IB/cm: Avoid a loop when device has 255 ports + - tracepoint: Do not fail unregistering a probe due to memory failure + - perf tools: Fix DSO filtering when not finding a map for a sampled address + - perf vendor events arm64: Fix Ampere eMag event typo + - RDMA/rxe: Fix coding error in rxe_recv.c + - RDMA/rxe: Fix coding error in rxe_rcv_mcast_pkt + - RDMA/rxe: Correct skb on loopback path + - spi: stm32: properly handle 0 byte transfer + - mfd: wm831x-auxadc: Prevent use after free in wm831x_auxadc_read_irq() + - powerpc/pseries/dlpar: handle ibm, configure-connector delay status + - powerpc/8xx: Fix software emulation interrupt + - clk: qcom: gcc-msm8998: Fix Alpha PLL type for all GPLLs + - RDMA/hns: Fixed wrong judgments in the goto branch + - RDMA/siw: Fix calculation of tx_valid_cpus size + - RDMA/hns: Fix type of sq_signal_bits + - spi: pxa2xx: Fix the controller numbering for Wildcat Point + - regulator: qcom-rpmh: fix pm8009 ldo7 + - clk: aspeed: Fix APLL calculate formula from ast2600-A2 + - nfsd: register pernet ops last, unregister first + - RDMA/hns: Fixes missing error code of CMDQ + - Input: sur40 - fix an error code in sur40_probe() + - perf intel-pt: Fix missing CYC processing in PSB + - perf intel-pt: Fix premature IPC + - perf test: Fix unaligned access in sample parsing test + - Input: elo - fix an error code in elo_connect() + - sparc64: only select COMPAT_BINFMT_ELF if BINFMT_ELF is set + - misc: eeprom_93xx46: Fix module alias to enable module autoprobe + - phy: rockchip-emmc: emmc_phy_init() always return 0 + - misc: eeprom_93xx46: Add module alias to avoid breaking support for non + device tree users + - soundwire: cadence: fix ACK/NAK handling + - pwm: rockchip: rockchip_pwm_probe(): Remove superfluous clk_unprepare() + - VMCI: Use set_page_dirty_lock() when unregistering guest memory + - PCI: Align checking of syscall user config accessors + - mei: hbm: call mei_set_devstate() on hbm stop response + - drm/msm/dsi: Correct io_start for MSM8994 (20nm PHY) + - drm/msm/mdp5: Fix wait-for-commit for cmd panels + - vfio/iommu_type1: Fix some sanity checks in detach group + - ext4: fix potential htree index checksum corruption + - nvmem: core: Fix a resource leak on error in nvmem_add_cells_from_of() + - nvmem: core: skip child nodes not matching binding + - regmap: sdw: use _no_pm functions in regmap_read/write + - i40e: Fix flow for IPv6 next header (extension header) + - i40e: Add zero-initialization of AQ command structures + - i40e: Fix overwriting flow control settings during driver loading + - i40e: Fix addition of RX filters after enabling FW LLDP agent + - i40e: Fix VFs not created + - i40e: Fix add TC filter for IPv6 + - vfio/type1: Use follow_pte() + - net/mlx4_core: Add missed mlx4_free_cmd_mailbox() + - vxlan: move debug check after netdev unregister + - ocfs2: fix a use after free on error + - mm/memory.c: fix potential pte_unmap_unlock pte error + - mm/hugetlb: fix potential double free in hugetlb_register_node() error path + - mm/compaction: fix misbehaviors of fast_find_migrateblock() + - r8169: fix jumbo packet handling on RTL8168e + - arm64: Add missing ISB after invalidating TLB in __primary_switch + - i2c: brcmstb: Fix brcmstd_send_i2c_cmd condition + - mm/rmap: fix potential pte_unmap on an not mapped pte + - scsi: bnx2fc: Fix Kconfig warning & CNIC build errors + - blk-settings: align max_sectors on "logical_block_size" boundary + - ACPI: property: Fix fwnode string properties matching + - ACPI: configfs: add missing check after configfs_register_default_group() + - HID: logitech-dj: add support for keyboard events in eQUAD step 4 Gaming + - HID: wacom: Ignore attempts to overwrite the touch_max value from HID + - Input: raydium_ts_i2c - do not send zero length + - Input: xpad - add support for PowerA Enhanced Wired Controller for Xbox + Series X|S + - Input: joydev - prevent potential read overflow in ioctl + - Input: i8042 - add ASUS Zenbook Flip to noselftest list + - media: mceusb: Fix potential out-of-bounds shift + - USB: serial: option: update interface mapping for ZTE P685M + - usb: musb: Fix runtime PM race in musb_queue_resume_work + - usb: dwc3: gadget: Fix setting of DEPCFG.bInterval_m1 + - usb: dwc3: gadget: Fix dep->interval for fullspeed interrupt + - USB: serial: ftdi_sio: fix FTX sub-integer prescaler + - USB: serial: mos7840: fix error code in mos7840_write() + - USB: serial: mos7720: fix error code in mos7720_write() + - ALSA: hda: Add another CometLake-H PCI ID + - ALSA: hda/realtek: modify EAPD in the ALC886 + - Revert "bcache: Kill btree_io_wq" + - bcache: Give btree_io_wq correct semantics again + - bcache: Move journal work to new flush wq + - drm/amd/display: Add vupdate_no_lock interrupts for DCN2.1 + - drm/amdgpu: Set reference clock to 100Mhz on Renoir (v2) + - drm/nouveau/kms: handle mDP connectors + - drm/sched: Cancel and flush all outstanding jobs before finish. + - erofs: initialized fields can only be observed after bit is set + - tpm_tis: Fix check_locality for correct locality acquisition + - tpm_tis: Clean up locality release + - KEYS: trusted: Fix migratable=1 failing + - btrfs: abort the transaction if we fail to inc ref in btrfs_copy_root + - btrfs: fix reloc root leak with 0 ref reloc roots on recovery + - btrfs: splice remaining dirty_bg's onto the transaction dirty bg list + - btrfs: fix extent buffer leak on failure to copy root + - crypto: arm64/sha - add missing module aliases + - crypto: aesni - prevent misaligned buffers on the stack + - crypto: sun4i-ss - checking sg length is not sufficient + - crypto: sun4i-ss - handle BigEndian for cipher + - crypto: sun4i-ss - initialize need_fallback + - seccomp: Add missing return in non-void function + - misc: rtsx: init of rts522a add OCP power off when no card is present + - drivers/misc/vmw_vmci: restrict too big queue size in qp_host_alloc_queue + - pstore: Fix typo in compression option name + - dts64: mt7622: fix slow sd card access + - staging/mt7621-dma: mtk-hsdma.c->hsdma-mt7621.c + - staging: gdm724x: Fix DMA from stack + - staging: rtl8188eu: Add Edimax EW-7811UN V2 to device table + - media: ipu3-cio2: Fix mbus_code processing in cio2_subdev_set_fmt() + - x86/virt: Eat faults on VMXOFF in reboot flows + - x86/reboot: Force all cpus to exit VMX root if VMX is supported + - powerpc/prom: Fix "ibm,arch-vec-5-platform-support" scan + - rcu: Pull deferred rcuog wake up to rcu_eqs_enter() callers + - rcu/nocb: Perform deferred wake up before last idle's need_resched() check + - floppy: reintroduce O_NDELAY fix + - arm64: kexec_file: fix memory leakage in create_dtb() when fdt_open_into() + fails + - arm64: uprobe: Return EOPNOTSUPP for AARCH32 instruction probing + - watchdog: qcom: Remove incorrect usage of QCOM_WDT_ENABLE_IRQ + - watchdog: mei_wdt: request stop on unregister + - mtd: spi-nor: sfdp: Fix last erase region marking + - mtd: spi-nor: sfdp: Fix wrong erase type bitmask for overlaid region + - mtd: spi-nor: core: Fix erase type discovery for overlaid region + - mtd: spi-nor: core: Add erase size check for erase command initialization + - mtd: spi-nor: hisi-sfc: Put child node np on error path + - fs/affs: release old buffer head on error path + - seq_file: document how per-entry resources are managed. + - x86: fix seq_file iteration for pat/memtype.c + - hugetlb: fix update_and_free_page contig page struct assumption + - hugetlb: fix copy_huge_page_from_user contig page struct assumption + - arm64: Extend workaround for erratum 1024718 to all versions of Cortex-A55 + - media: smipcie: fix interrupt handling and IR timeout + - module: Ignore _GLOBAL_OFFSET_TABLE_ when warning for undefined symbols + - mmc: sdhci-esdhc-imx: fix kernel panic when remove module + - powerpc/32s: Add missing call to kuep_lock on syscall entry + - spmi: spmi-pmic-arb: Fix hw_irq overflow + - gpio: pcf857x: Fix missing first interrupt + - printk: fix deadlock when kernel panic + - cpufreq: intel_pstate: Get per-CPU max freq via MSR_HWP_CAPABILITIES if + available + - s390/vtime: fix inline assembly clobber list + - virtio/s390: implement virtio-ccw revision 2 correctly + - um: mm: check more comprehensively for stub changes + - f2fs: fix out-of-repair __setattr_copy() + - sparc32: fix a user-triggerable oops in clear_user() + - spi: spi-synquacer: fix set_cs handling + - gfs2: Don't skip dlm unlock if glock has an lvb + - gfs2: Recursive gfs2_quota_hold in gfs2_iomap_end + - dm: fix deadlock when swapping to encrypted device + - dm writecache: fix writing beyond end of underlying device when shrinking + - dm era: Recover committed writeset after crash + - dm era: Verify the data block size hasn't changed + - dm era: Fix bitset memory leaks + - dm era: Use correct value size in equality function of writeset tree + - dm era: Reinitialize bitset cache before digesting a new writeset + - dm era: only resize metadata in preresume + - drm/i915: Reject 446-480MHz HDMI clock on GLK + - icmp: introduce helper for nat'd source address in network device context + - icmp: allow icmpv6_ndo_send to work with CONFIG_IPV6=n + - gtp: use icmp_ndo_send helper + - sunvnet: use icmp_ndo_send helper + - xfrm: interface: use icmp_ndo_send helper + - ipv6: icmp6: avoid indirect call for icmpv6_send() + - ipv6: silence compilation warning for non-IPV6 builds + - net: icmp: pass zeroed opts from icmp{,v6}_ndo_send before sending + - net: sched: fix police ext initialization + - dm era: Update in-core bitset after committing the metadata + - net: qrtr: Fix memory leak in qrtr_tun_open + - ARM: dts: aspeed: Add LCLK to lpc-snoop + - Linux 5.4.102 + * eeh-basic.sh from powerpc in ubuntu_kernel_selftests failed with unexpected + operator on F-5.8 (LP: #1909428) + - selftests/powerpc: Make the test check in eeh-basic.sh posix compliant + + -- Tim Gardner Mon, 19 Apr 2021 11:18:24 -0600 + +linux-oracle (5.4.0-1043.46) focal; urgency=medium + + [ Ubuntu: 5.4.0-72.80 ] + + * overlayfs calls vfs_setxattr without cap_convert_nscap + - vfs: move cap_convert_nscap() call into vfs_setxattr() + * CVE-2021-3492 + - SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace() + error paths + - SAUCE: shiftfs: handle copy_to_user() return values correctly + * CVE-2021-29154 + - SAUCE: bpf, x86: Validate computation of branch displacements for x86-64 + - SAUCE: bpf, x86: Validate computation of branch displacements for x86-32 + + -- Kleber Sacilotto de Souza Tue, 13 Apr 2021 10:28:47 +0200 + +linux-oracle (5.4.0-1042.45) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1042.45 -proposed tracker (LP: #1921032) + + * Enforce CONFIG_DRM_BOCHS=m (LP: #1916290) + - [Config] [oracle] updateconfigs for CONFIG_DRM_BOCHS + + [ Ubuntu: 5.4.0-71.79 ] + + * focal/linux: 5.4.0-71.79 -proposed tracker (LP: #1921040) + * selftests: bpf verifier fails after sanitize_ptr_alu fixes (LP: #1920995) + - bpf: Simplify alu_limit masking for pointer arithmetic + - bpf: Add sanity check for upper ptr_limit + - bpf, selftests: Fix up some test_verifier cases for unprivileged + * Packaging resync (LP: #1786013) + - update dkms package versions + * Fix missing HDMI/DP audio on NVidia card after S3 (LP: #1918228) + - ALSA: hda/hdmi: Reduce hda_jack_tbl lookup at unsol event handling + - ALSA: hda/hdmi: Don't use standard hda_jack for generic HDMI jacks + - ALSA: hda/hdmi: Move runtime PM resume into hdmi_present_sense_via_verbs() + - ALSA: hda/hdmi: Move ELD parse and jack reporting into update_eld() + * Focal update: v5.4.101 upstream stable release (LP: #1918170) + - HID: make arrays usage and value to be the same + - USB: quirks: sort quirk entries + - usb: quirks: add quirk to start video capture on ELMO L-12F document camera + reliable + - ntfs: check for valid standard information attribute + - arm64: tegra: Add power-domain for Tegra210 HDA + - scripts: use pkg-config to locate libcrypto + - scripts: set proper OpenSSL include dir also for sign-file + - mm: unexport follow_pte_pmd + - mm: simplify follow_pte{,pmd} + - KVM: do not assume PTE is writable after follow_pfn + - mm: provide a saner PTE walking API for modules + - KVM: Use kvm_pfn_t for local PFN variable in hva_to_pfn_remapped() + - NET: usb: qmi_wwan: Adding support for Cinterion MV31 + - cxgb4: Add new T6 PCI device id 0x6092 + - cifs: Set CIFS_MOUNT_USE_PREFIX_PATH flag on setting cifs_sb->prepath. + - scripts/recordmcount.pl: support big endian for ARCH sh + - Linux 5.4.101 + * Focal update: v5.4.100 upstream stable release (LP: #1918168) + - KVM: SEV: fix double locking due to incorrect backport + - net: qrtr: Fix port ID for control messages + - net: bridge: Fix a warning when del bridge sysfs + - Xen/x86: don't bail early from clear_foreign_p2m_mapping() + - Xen/x86: also check kernel mapping in set_foreign_p2m_mapping() + - Xen/gntdev: correct dev_bus_addr handling in gntdev_map_grant_pages() + - Xen/gntdev: correct error checking in gntdev_map_grant_pages() + - xen/arm: don't ignore return errors from set_phys_to_machine + - xen-blkback: don't "handle" error by BUG() + - xen-netback: don't "handle" error by BUG() + - xen-scsiback: don't "handle" error by BUG() + - xen-blkback: fix error handling in xen_blkbk_map() + - media: pwc: Use correct device for DMA + - btrfs: fix backport of 2175bf57dc952 in 5.4.95 + - Linux 5.4.100 + * Focal update: v5.4.99 upstream stable release (LP: #1918167) + - gpio: ep93xx: fix BUG_ON port F usage + - gpio: ep93xx: Fix single irqchip with multi gpiochips + - tracing: Do not count ftrace events in top level enable output + - tracing: Check length before giving out the filter buffer + - arm/xen: Don't probe xenbus as part of an early initcall + - cgroup: fix psi monitor for root cgroup + - arm64: dts: rockchip: Fix PCIe DT properties on rk3399 + - arm64: dts: qcom: sdm845: Reserve LPASS clocks in gcc + - ARM: OMAP2+: Fix suspcious RCU usage splats for omap_enter_idle_coupled + - platform/x86: hp-wmi: Disable tablet-mode reporting by default + - ovl: perform vfs_getxattr() with mounter creds + - cap: fix conversions on getxattr + - ovl: skip getxattr of security labels + - nvme-pci: ignore the subsysem NQN on Phison E16 + - drm/amd/display: Add more Clock Sources to DCN2.1 + - drm/amd/display: Fix dc_sink kref count in emulated_link_detect + - drm/amd/display: Free atomic state after drm_atomic_commit + - drm/amd/display: Decrement refcount of dc_sink before reassignment + - riscv: virt_addr_valid must check the address belongs to linear mapping + - bfq-iosched: Revert "bfq: Fix computation of shallow depth" + - ARM: dts: lpc32xx: Revert set default clock rate of HCLK PLL + - ARM: ensure the signal page contains defined contents + - ARM: kexec: fix oops after TLB are invalidated + - vmlinux.lds.h: Create section for protection against instrumentation + - lkdtm: don't move ctors to .rodata + - mt76: dma: fix a possible memory leak in mt76_add_fragment() + - drm/vc4: hvs: Fix buffer overflow with the dlist handling + - bpf: Check for integer overflow when using roundup_pow_of_two() + - netfilter: xt_recent: Fix attempt to update deleted entry + - netfilter: nftables: fix possible UAF over chains from packet path in netns + - netfilter: flowtable: fix tcp and udp header checksum update + - xen/netback: avoid race in xenvif_rx_ring_slots_available() + - net: enetc: initialize the RFS and RSS memories + - selftests: txtimestamp: fix compilation issue + - net: stmmac: set TxQ mode back to DCB after disabling CBS + - ibmvnic: Clear failover_pending if unable to schedule + - netfilter: conntrack: skip identical origin tuple in same zone only + - x86/build: Disable CET instrumentation in the kernel for 32-bit too + - net: hns3: add a check for queue_id in hclge_reset_vf_queue() + - firmware_loader: align .builtin_fw to 8 + - drm/sun4i: tcon: set sync polarity for tcon1 channel + - drm/sun4i: Fix H6 HDMI PHY configuration + - drm/sun4i: dw-hdmi: Fix max. frequency for H6 + - clk: sunxi-ng: mp: fix parent rate change flag check + - i2c: stm32f7: fix configuration of the digital filter + - h8300: fix PREEMPTION build, TI_PRE_COUNT undefined + - usb: dwc3: ulpi: fix checkpatch warning + - usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one + - rxrpc: Fix clearance of Tx/Rx ring when releasing a call + - udp: fix skb_copy_and_csum_datagram with odd segment sizes + - net: dsa: call teardown method on probe failure + - net: gro: do not keep too many GRO packets in napi->rx_list + - net: fix iteration for sctp transport seq_files + - net/vmw_vsock: improve locking in vsock_connect_timeout() + - net: watchdog: hold device global xmit lock during tx disable + - vsock/virtio: update credit only if socket is not closed + - vsock: fix locking in vsock_shutdown() + - net/rds: restrict iovecs length for RDS_CMSG_RDMA_ARGS + - net/qrtr: restrict user-controlled length in qrtr_tun_write_iter() + - ovl: expand warning in ovl_d_real() + - Linux 5.4.99 + * Focal update: v5.4.98 upstream stable release (LP: #1918158) + - tracing/kprobe: Fix to support kretprobe events on unloaded modules + - af_key: relax availability checks for skb size calculation + - regulator: core: avoid regulator_resolve_supply() race condition + - mac80211: 160MHz with extended NSS BW in CSA + - ASoC: Intel: Skylake: Zero snd_ctl_elem_value + - chtls: Fix potential resource leak + - pNFS/NFSv4: Try to return invalid layout in pnfs_layout_process() + - ASoC: ak4458: correct reset polarity + - iwlwifi: mvm: skip power command when unbinding vif during CSA + - iwlwifi: mvm: take mutex for calling iwl_mvm_get_sync_time() + - iwlwifi: pcie: add a NULL check in iwl_pcie_txq_unmap + - iwlwifi: pcie: fix context info memory leak + - iwlwifi: mvm: invalidate IDs of internal stations at mvm start + - iwlwifi: mvm: guard against device removal in reprobe + - SUNRPC: Move simple_get_bytes and simple_get_netobj into private header + - SUNRPC: Handle 0 length opaque XDR object data properly + - i2c: mediatek: Move suspend and resume handling to NOIRQ phase + - blk-cgroup: Use cond_resched() when destroy blkgs + - regulator: Fix lockdep warning resolving supplies + - Fix unsynchronized access to sev members through svm_register_enc_region + - squashfs: add more sanity checks in id lookup + - squashfs: add more sanity checks in inode lookup + - squashfs: add more sanity checks in xattr id lookup + - Linux 5.4.98 + * Enforce CONFIG_DRM_BOCHS=m (LP: #1916290) + - [Config] Enforce CONFIG_DRM_BOCHS=m + * powerpc/eeh-basic.sh in kselftest make P8 node stopped working + (LP: #1916468) + - selftests/eeh: Skip ahci adapters + * Focal update: v5.4.97 upstream stable release (LP: #1916066) + - USB: serial: cp210x: add pid/vid for WSDA-200-USB + - USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000 + - USB: serial: option: Adding support for Cinterion MV31 + - arm64: dts: qcom: c630: keep both touchpad devices enabled + - arm64: dts: amlogic: meson-g12: Set FL-adj property value + - arm64: dts: rockchip: fix vopl iommu irq on px30 + - bpf, cgroup: Fix optlen WARN_ON_ONCE toctou + - bpf, cgroup: Fix problematic bounds check + - um: virtio: free vu_dev only with the contained struct device + - rxrpc: Fix deadlock around release of dst cached on udp tunnel + - arm64: dts: ls1046a: fix dcfg address range + - igc: set the default return value to -IGC_ERR_NVM in igc_write_nvm_srwr + - igc: check return value of ret_val in igc_config_fc_after_link_up + - i40e: Revert "i40e: don't report link up for a VF who hasn't enabled queues" + - net/mlx5: Fix leak upon failure of rule creation + - net: lapb: Copy the skb before sending a packet + - net: mvpp2: TCAM entry enable should be written after SRAM data + - r8169: fix WoL on shutdown if CONFIG_DEBUG_SHIRQ is set + - ARM: dts: sun7i: a20: bananapro: Fix ethernet phy-mode + - nvmet-tcp: fix out-of-bounds access when receiving multiple h2cdata PDUs + - memblock: do not start bottom-up allocations with kernel_end + - USB: gadget: legacy: fix an error code in eth_bind() + - USB: usblp: don't call usb_set_interface if there's a single alt + - usb: renesas_usbhs: Clear pipe running flag in usbhs_pkt_pop() + - usb: dwc2: Fix endpoint direction check in ep_from_windex + - usb: dwc3: fix clock issue during resume in OTG mode + - usb: xhci-mtk: fix unreleased bandwidth data + - usb: xhci-mtk: skip dropping bandwidth of unchecked endpoints + - usb: xhci-mtk: break loop when find the endpoint to drop + - usb: host: xhci-plat: add priv quirk for skip PHY initialization + - ovl: fix dentry leak in ovl_get_redirect + - mac80211: fix station rate table updates on assoc + - fgraph: Initialize tracing_graph_pause at task creation + - kretprobe: Avoid re-registration of the same kretprobe earlier + - libnvdimm/dimm: Avoid race between probe and available_slots_show() + - genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set + - xhci: fix bounce buffer usage for non-sg list case + - cifs: report error instead of invalid when revalidating a dentry fails + - smb3: Fix out-of-bounds bug in SMB2_negotiate() + - smb3: fix crediting for compounding when only one request in flight + - mmc: core: Limit retries when analyse of SDIO tuples fails + - drm/amd/display: Revert "Fix EDID parsing after resume from suspend" + - nvme-pci: avoid the deepest sleep state on Kingston A2000 SSDs + - KVM: SVM: Treat SVM as unsupported when running as an SEV guest + - KVM: x86: Update emulator context mode if SYSENTER xfers to 64-bit mode + - ARM: footbridge: fix dc21285 PCI configuration accessors + - mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page + - mm: hugetlb: fix a race between freeing and dissolving the page + - mm: hugetlb: fix a race between isolating and freeing page + - mm: hugetlb: remove VM_BUG_ON_PAGE from page_huge_active + - mm, compaction: move high_pfn to the for loop scope + - mm: thp: fix MADV_REMOVE deadlock on shmem THP + - x86/build: Disable CET instrumentation in the kernel + - x86/apic: Add extra serialization for non-serializing MSRs + - iwlwifi: mvm: don't send RFH_QUEUE_CONFIG_CMD with no queues + - Input: xpad - sync supported devices with fork on GitHub + - iommu/vt-d: Do not use flush-queue when caching-mode is on + - md: Set prev_flush_start and flush_bio in an atomic way + - neighbour: Prevent a dead entry from updating gc_list + - net: ip_tunnel: fix mtu calculation + - net: dsa: mv88e6xxx: override existent unicast portvec in port_fdb_add + - net: sched: replaced invalid qdisc tree flush helper in qdisc_replace + - usb: host: xhci: mvebu: make USB 3.0 PHY optional for Armada 3720 + - Linux 5.4.97 + * Focal update: v5.4.96 upstream stable release (LP: #1916061) + - net: dsa: bcm_sf2: put device node before return + - net: switchdev: don't set port_obj_info->handled true when -EOPNOTSUPP + - ibmvnic: Ensure that CRQ entry read are correctly ordered + - Revert "Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and + REQ_NOWAIT"" + - ACPI: thermal: Do not call acpi_thermal_check() directly + - arm64: Fix kernel address detection of __is_lm_address() + - arm64: Do not pass tagged addresses to __is_lm_address() + - tcp: make TCP_USER_TIMEOUT accurate for zero window probes + - btrfs: backref, only collect file extent items matching backref offset + - btrfs: backref, don't add refs from shared block when resolving normal + backref + - btrfs: backref, only search backref entries from leaves of the same root + - btrfs: backref, use correct count to resolve normal data refs + - net_sched: gen_estimator: support large ewma log + - phy: cpcap-usb: Fix warning for missing regulator_disable + - platform/x86: touchscreen_dmi: Add swap-x-y quirk for Goodix touchscreen on + Estar Beauty HD tablet + - platform/x86: intel-vbtn: Support for tablet mode on Dell Inspiron 7352 + - x86: __always_inline __{rd,wr}msr() + - scsi: scsi_transport_srp: Don't block target in failfast state + - scsi: libfc: Avoid invoking response handler twice if ep is already + completed + - scsi: fnic: Fix memleak in vnic_dev_init_devcmd2 + - ASoC: SOF: Intel: hda: Resume codec to do jack detection + - mac80211: fix fast-rx encryption check + - scsi: ibmvfc: Set default timeout to avoid crash during migration + - udf: fix the problem that the disc content is not displayed + - nvme: check the PRINFO bit before deciding the host buffer length + - selftests/powerpc: Only test lwm/stmw on big endian + - drm/amd/display: Update dram_clock_change_latency for DCN2.1 + - drm/amd/display: Change function decide_dp_link_settings to avoid infinite + looping + - objtool: Don't fail on missing symbol table + - kthread: Extract KTHREAD_IS_PER_CPU + - workqueue: Restrict affinity change to rescuer + - Linux 5.4.96 + * Focal update: v5.4.95 upstream stable release (LP: #1916056) + - ICMPv6: Add ICMPv6 Parameter Problem, code 3 definition + - IPv6: reply ICMP error if the first fragment don't include all headers + - nbd: freeze the queue while we're adding connections + - ACPI: sysfs: Prefer "compatible" modalias + - kernel: kexec: remove the lock operation of system_transition_mutex + - ALSA: hda/realtek: Enable headset of ASUS B1400CEPE with ALC256 + - ALSA: hda/via: Apply the workaround generically for Clevo machines + - media: rc: ensure that uevent can be read directly after rc device register + - ARM: dts: imx6qdl-gw52xx: fix duplicate regulator naming + - wext: fix NULL-ptr-dereference with cfg80211's lack of commit() + - net: usb: qmi_wwan: added support for Thales Cinterion PLSx3 modem family + - s390/vfio-ap: No need to disable IRQ after queue reset + - PM: hibernate: flush swap writer after marking + - drivers: soc: atmel: Avoid calling at91_soc_init on non AT91 SoCs + - drivers: soc: atmel: add null entry at the end of at91_soc_allowed_list[] + - btrfs: fix possible free space tree corruption with online conversion + - KVM: x86/pmu: Fix HW_REF_CPU_CYCLES event pseudo-encoding in + intel_arch_events[] + - KVM: x86/pmu: Fix UBSAN shift-out-of-bounds warning in intel_pmu_refresh() + - KVM: nVMX: Sync unsync'd vmcs02 state to vmcs12 on migration + - KVM: x86: get smi pending status correctly + - KVM: Forbid the use of tagged userspace addresses for memslots + - xen: Fix XenStore initialisation for XS_LOCAL + - leds: trigger: fix potential deadlock with libata + - arm64: dts: broadcom: Fix USB DMA address translation for Stingray + - mt7601u: fix kernel crash unplugging the device + - mt7601u: fix rx buffer refcounting + - drm/nouveau/svm: fail NOUVEAU_SVM_INIT ioctl on unsupported devices + - drm/i915: Check for all subplatform bits + - tee: optee: replace might_sleep with cond_resched + - xen-blkfront: allow discard-* nodes to be optional + - ARM: imx: build suspend-imx6.S with arm instruction set + - netfilter: nft_dynset: add timeout extension to template + - xfrm: Fix oops in xfrm_replay_advance_bmp + - xfrm: fix disable_xfrm sysctl when used on xfrm interfaces + - selftests: xfrm: fix test return value override issue in xfrm_policy.sh + - xfrm: Fix wraparound in xfrm_policy_addr_delta() + - arm64: dts: ls1028a: fix the offset of the reset register + - ARM: dts: imx6qdl-kontron-samx6i: fix i2c_lcd/cam default status + - firmware: imx: select SOC_BUS to fix firmware build + - RDMA/cxgb4: Fix the reported max_recv_sge value + - ASoC: Intel: Skylake: skl-topology: Fix OOPs ib skl_tplg_complete + - pNFS/NFSv4: Fix a layout segment leak in pnfs_layout_process() + - iwlwifi: pcie: use jiffies for memory read spin time limit + - iwlwifi: pcie: reschedule in long-running memory reads + - mac80211: pause TX while changing interface type + - i40e: acquire VSI pointer only after VF is initialized + - igc: fix link speed advertising + - net/mlx5: Fix memory leak on flow table creation error flow + - net/mlx5e: E-switch, Fix rate calculation for overflow + - net/mlx5e: Reduce tc unsupported key print level + - can: dev: prevent potential information leak in can_fill_info() + - nvme-multipath: Early exit if no path is available + - selftests: forwarding: Specify interface when invoking mausezahn + - iommu/vt-d: Gracefully handle DMAR units with no supported address widths + - iommu/vt-d: Don't dereference iommu_device if IOMMU_API is not built + - rxrpc: Fix memory leak in rxrpc_lookup_local + - NFC: fix resource leak when target index is invalid + - NFC: fix possible resource leak + - ASoC: topology: Fix memory corruption in soc_tplg_denum_create_values() + - team: protect features update by RCU to avoid deadlock + - tcp: fix TLP timer not set when CA_STATE changes from DISORDER to OPEN + - Linux 5.4.95 + + -- Ian May Thu, 25 Mar 2021 14:59:44 -0500 + +linux-oracle (5.4.0-1041.44) focal; urgency=medium + + [ Ubuntu: 5.4.0-70.78 ] + + * CVE-2020-27170 + - bpf: Fix off-by-one for area size in creating mask to left + * CVE-2020-27171 + - bpf: Prohibit alu ops for pointer types not defining ptr_limit + * binary assembly failures with CONFIG_MODVERSIONS present (LP: #1919315) + - [Packaging] quiet (nomially) benign errors in BUILD script + + -- Kleber Sacilotto de Souza Fri, 19 Mar 2021 18:40:26 +0100 + +linux-oracle (5.4.0-1040.43) focal; urgency=medium + + * binary assembly failures with CONFIG_MODVERSIONS present (LP: #1919315) + - [Packaging] quiet (nomially) benign errors in BUILD script + + [ Ubuntu: 5.4.0-69.77 ] + + * CVE-2021-3444 + - bpf: Fix 32 bit src register truncation on div/mod + - bpf: Fix truncation handling for mod32 dst reg wrt zero + * CVE-2021-27365 + - scsi: iscsi: Verify lengths on passthrough PDUs + - sysfs: Add sysfs_emit and sysfs_emit_at to format sysfs output + - scsi: iscsi: Ensure sysfs attributes are limited to PAGE_SIZE + * CVE-2021-27363 // CVE-2021-27364 + - scsi: iscsi: Restrict sessions and handles to admin capabilities + + -- Kleber Sacilotto de Souza Wed, 17 Mar 2021 17:55:33 +0100 + +linux-oracle (5.4.0-1039.42) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1039.42 -proposed tracker (LP: #1916161) + + * Focal update: v5.4.93 upstream stable release (LP: #1915195) + - oracle: [Config] updateconfigs for USB_BDC_PCI + + * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716) + - oracle: [Config] Enable MODVERSIONS, ASM_MODVERSIONS and set + SYSTEM_TRUSTED_KEYS + + [ Ubuntu: 5.4.0-67.75 ] + + * focal/linux: 5.4.0-67.75 -proposed tracker (LP: #1916169) + * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716) + - [Config] enable CONFIG_MODVERSIONS=y + - [Packaging] build canonical-certs.pem from branch/arch certs + - [Config] add Canonical Livepatch Service key to SYSTEM_TRUSTED_KEYS + - [Config] add ubuntu-drivers key to SYSTEM_TRUSTED_KEYS + - [Config] Allow ASM_MODVERSIONS and MODULE_REL_CRCS + * geneve overlay network on vlan interface broken with offload enabled + (LP: #1914447) + - net/mlx5e: Fix SWP offsets when vlan inserted by driver + * Add support for selective build of special drivers (LP: #1912789) + - [Packaging] Fix ODM support in actual build + * devlink: don't do reporter recovery if the state is healthy (LP: #1915403) + - devlink: don't do reporter recovery if the state is healthy + * Missing device id for Intel TGL-H ISH [8086:43fc] in intel-ish-hid driver + (LP: #1914543) + - HID: intel-ish-hid: ipc: Add Tiger Lake H PCI device ID + * Focal update: v5.4.94 upstream stable release (LP: #1915200) + - gpio: mvebu: fix pwm .get_state period calculation + - futex: Ensure the correct return value from futex_lock_pi() + - futex: Replace pointless printk in fixup_owner() + - futex: Provide and use pi_state_update_owner() + - rtmutex: Remove unused argument from rt_mutex_proxy_unlock() + - futex: Use pi_state_update_owner() in put_pi_state() + - futex: Simplify fixup_pi_state_owner() + - futex: Handle faults correctly for PI futexes + - HID: wacom: Correct NULL dereference on AES pen proximity + - io_uring: Fix current->fs handling in io_sq_wq_submit_work() + - tracing: Fix race in trace_open and buffer resize call + - arm64: mm: use single quantity to represent the PA to VA translation + - SMB3.1.1: do not log warning message if server doesn't populate salt + - tools: Factor HOSTCC, HOSTLD, HOSTAR definitions + - dm integrity: conditionally disable "recalculate" feature + - writeback: Drop I_DIRTY_TIME_EXPIRE + - fs: fix lazytime expiration handling in __writeback_single_inode() + - Linux 5.4.94 + * Focal update: v5.4.93 upstream stable release (LP: #1915195) + - i2c: bpmp-tegra: Ignore unknown I2C_M flags + - platform/x86: ideapad-laptop: Disable touchpad_switch for ELAN0634 + - ALSA: seq: oss: Fix missing error check in snd_seq_oss_synth_make_info() + - ALSA: hda/via: Add minimum mute flag + - ACPI: scan: Make acpi_bus_get_device() clear return pointer on error + - btrfs: don't get an EINTR during drop_snapshot for reloc + - btrfs: fix lockdep splat in btrfs_recover_relocation + - btrfs: don't clear ret in btrfs_start_dirty_block_groups + - btrfs: send: fix invalid clone operations when cloning from the same file + and root + - mmc: core: don't initialize block size from ext_csd if not present + - mmc: sdhci-xenon: fix 1.8v regulator stabilization + - dm: avoid filesystem lookup in dm_get_dev_t() + - dm integrity: fix a crash if "recalculate" used without "internal_hash" + - drm/atomic: put state on error path + - drm/syncobj: Fix use-after-free + - drm/i915/gt: Prevent use of engine->wa_ctx after error + - ASoC: Intel: haswell: Add missing pm_ops + - dm integrity: select CRYPTO_SKCIPHER + - scsi: ufs: Correct the LUN used in eh_device_reset_handler() callback + - scsi: qedi: Correct max length of CHAP secret + - scsi: sd: Suppress spurious errors when WRITE SAME is being disabled + - riscv: Fix kernel time_init() + - riscv: Fix sifive serial driver + - HID: logitech-dj: add the G602 receiver + - HID: Ignore battery for Elan touchscreen on ASUS UX550 + - clk: tegra30: Add hda clock default rates to clock driver + - arm64: make atomic helpers __always_inline + - xen: Fix event channel callback via INTX/GSI + - x86/xen: Add xen_no_vector_callback option to test PCI INTX delivery + - dts: phy: fix missing mdio device and probe failure of vsc8541-01 device + - riscv: defconfig: enable gpio support for HiFive Unleashed + - drm/amdgpu/psp: fix psp gfx ctrl cmds + - drm/amd/display: Fix to be able to stop crc calculation + - drm/nouveau/bios: fix issue shadowing expansion ROMs + - drm/nouveau/privring: ack interrupts the same way as RM + - drm/nouveau/i2c/gm200: increase width of aux semaphore owner fields + - drm/nouveau/mmu: fix vram heap sizing + - drm/nouveau/kms/nv50-: fix case where notifier buffer is at offset 0 + - powerpc: Use the common INIT_DATA_SECTION macro in vmlinux.lds.S + - pinctrl: aspeed: g6: Fix PWMG0 pinctrl setting + - scsi: megaraid_sas: Fix MEGASAS_IOC_FIRMWARE regression + - powerpc: Fix alignment bug within the init sections + - i2c: octeon: check correct size of maximum RECV_LEN packet + - platform/x86: intel-vbtn: Drop HP Stream x360 Convertible PC 11 from allow- + list + - selftests: net: fib_tests: remove duplicate log test + - can: dev: can_restart: fix use after free bug + - can: vxcan: vxcan_xmit: fix use after free bug + - can: peak_usb: fix use after free bugs + - iio: ad5504: Fix setting power-down state + - cifs: do not fail __smb_send_rqst if non-fatal signals are pending + - irqchip/mips-cpu: Set IPI domain parent chip + - x86/fpu: Add kernel_fpu_begin_mask() to selectively initialize state + - x86/topology: Make __max_die_per_package available unconditionally + - x86/mmx: Use KFPU_387 for MMX string operations + - intel_th: pci: Add Alder Lake-P support + - stm class: Fix module init return on allocation failure + - serial: mvebu-uart: fix tx lost characters at power off + - ehci: fix EHCI host controller initialization sequence + - USB: ehci: fix an interrupt calltrace error + - usb: gadget: aspeed: fix stop dma register setting. + - usb: udc: core: Use lock when write to soft_connect + - [Config] updateconfigs for USB_BDC_PCI + - usb: bdc: Make bdc pci driver depend on BROKEN + - xhci: make sure TRB is fully written before giving it to the controller + - xhci: tegra: Delay for disabling LFPS detector + - driver core: Extend device_is_dependent() + - pinctrl: ingenic: Fix JZ4760 support + - x86/cpu/amd: Set __max_die_per_package on AMD + - netfilter: rpfilter: mask ecn bits before fib lookup + - sh: dma: fix kconfig dependency for G2_DMA + - net: dsa: mv88e6xxx: also read STU state in mv88e6250_g1_vtu_getnext + - sh_eth: Fix power down vs. is_opened flag ordering + - lightnvm: fix memory leak when submit fails + - skbuff: back tiny skbs with kmalloc() in __netdev_alloc_skb() too + - kasan: fix unaligned address is unhandled in kasan_remove_zero_shadow + - kasan: fix incorrect arguments passing in kasan_add_zero_shadow + - udp: mask TOS bits in udp_v4_early_demux() + - ipv6: create multicast route with RTPROT_KERNEL + - net_sched: avoid shift-out-of-bounds in tcindex_set_parms() + - net_sched: reject silly cell_log in qdisc_get_rtab() + - ipv6: set multicast flag on the multicast route + - net: mscc: ocelot: allow offloading of bridge on top of LAG + - net: Disable NETIF_F_HW_TLS_RX when RXCSUM is disabled + - net: dsa: b53: fix an off by one in checking "vlan->vid" + - tcp: do not mess with cloned skbs in tcp_add_backlog() + - tcp: fix TCP_USER_TIMEOUT with zero window + - Linux 5.4.93 + * High load from process irq/65-i2c-INT3 - kernel module tps6598x + (LP: #1883511) // Focal update: v5.4.93 upstream stable release + (LP: #1915195) + - platform/x86: i2c-multi-instantiate: Don't create platform device for + INT3515 ACPI nodes + * Focal update: v5.4.92 upstream stable release (LP: #1915186) + - usb: ohci: Make distrust_firmware param default to false + - compiler.h: Raise minimum version of GCC to 5.1 for arm64 + - xen/privcmd: allow fetching resource sizes + - elfcore: fix building with clang + - scsi: lpfc: Make lpfc_defer_acc_rsp static + - spi: npcm-fiu: simplify the return expression of npcm_fiu_probe() + - spi: npcm-fiu: Disable clock in probe error path + - nfsd4: readdirplus shouldn't return parent of export + - bpf: Don't leak memory in bpf getsockopt when optlen == 0 + - bpf: Fix helper bpf_map_peek_elem_proto pointing to wrong callback + - udp: Prevent reuseport_select_sock from reading uninitialized socks + - netxen_nic: fix MSI/MSI-x interrupts + - net: introduce skb_list_walk_safe for skb segment walking + - net: skbuff: disambiguate argument and member for skb_list_walk_safe helper + - net: ipv6: Validate GSO SKB before finish IPv6 processing + - mlxsw: core: Add validation of transceiver temperature thresholds + - mlxsw: core: Increase critical threshold for ASIC thermal zone + - net: mvpp2: Remove Pause and Asym_Pause support + - rndis_host: set proper input size for OID_GEN_PHYSICAL_MEDIUM request + - esp: avoid unneeded kmap_atomic call + - net: dcb: Validate netlink message in DCB handler + - net: dcb: Accept RTM_GETDCB messages carrying set-like DCB commands + - rxrpc: Call state should be read with READ_ONCE() under some circumstances + - net: stmmac: Fixed mtu channged by cache aligned + - net: sit: unregister_netdevice on newlink's error path + - net: avoid 32 x truesize under-estimation for tiny skbs + - rxrpc: Fix handling of an unsupported token type in rxrpc_read() + - net, sctp, filter: remap copy_from_user failure error + - tipc: fix NULL deref in tipc_link_xmit() + - mac80211: do not drop tx nulldata packets on encrypted links + - mac80211: check if atf has been disabled in __ieee80211_schedule_txq + - spi: cadence: cache reference clock rate during probe + - Linux 5.4.92 + * intel-hid is not loaded on new Intel platform (LP: #1907160) + - platform/x86: intel-hid: Add Tiger Lake ACPI device ID + - platform/x86: intel-hid: fix: Update Tiger Lake ACPI device ID + - platform/x86: intel-hid: Move MODULE_DEVICE_TABLE() closer to the table + - platform/x86: intel-hid: add Rocket Lake ACPI device ID + * Support Advantech UNO-420 platform (LP: #1902672) + - ODM: MAINTAINERS: Add Advantech AHC1EC0 embedded controller entry + - ODM: mfd: ahc1ec0: Add Advantech EC include file used by dt-bindings + - ODM: dt-bindings: mfd: ahc1ec0.yaml: Add Advantech embedded controller - + AHC1EC0 + - ODM: mfd: ahc1ec0: Add support for Advantech embedded controller + - ODM: hwmon: ahc1ec0-hwmon: Add sub-device hwmon for Advantech embedded + controller + - ODM: watchdog: ahc1ec0-wdt: Add sub-device watchdog for Advantech embedded + controller + - ODM: [Config] update config for Advantech devices + * Remove scary stack trace from Realtek WiFi driver (LP: #1913263) + - rtw88: reduce the log level for failure of tx report + * Focal update: v5.4.91 upstream stable release (LP: #1914654) + - kbuild: enforce -Werror=return-type + - btrfs: prevent NULL pointer dereference in extent_io_tree_panic + - ASoC: dapm: remove widget from dirty list on free + - x86/hyperv: check cpu mask after interrupt has been disabled + - tracing/kprobes: Do the notrace functions check without kprobes on ftrace + - [Config] update annotations for KPROBE_EVENTS_ON_NOTRACE + - mips: fix Section mismatch in reference + - mips: lib: uncached: fix non-standard usage of variable 'sp' + - MIPS: boot: Fix unaligned access with CONFIG_MIPS_RAW_APPENDED_DTB + - MIPS: relocatable: fix possible boot hangup with KASLR enabled + - RDMA/ocrdma: Fix use after free in ocrdma_dealloc_ucontext_pd() + - ACPI: scan: Harden acpi_device_add() against device ID overflows + - mm/hugetlb: fix potential missing huge page size info + - dm raid: fix discard limits for raid1 + - dm snapshot: flush merged data before committing metadata + - dm integrity: fix the maximum number of arguments + - r8152: Add Lenovo Powered USB-C Travel Hub + - btrfs: tree-checker: check if chunk item end overflows + - drm/i915/backlight: fix CPU mode backlight takeover on LPT + - ext4: fix bug for rename with RENAME_WHITEOUT + - ext4: don't leak old mountpoint samples + - cifs: fix interrupted close commands + - dm integrity: fix flush with external metadata device + - ARC: build: remove non-existing bootpImage from KBUILD_IMAGE + - ARC: build: add uImage.lzma to the top-level target + - ARC: build: add boot_targets to PHONY + - ARC: build: move symlink creation to arch/arc/Makefile to avoid race + - netfilter: ipset: fixes possible oops in mtype_resize + - btrfs: fix transaction leak and crash after RO remount caused by qgroup + rescan + - regulator: bd718x7: Add enable times + - ethernet: ucc_geth: fix definition and size of ucc_geth_tx_global_pram + - habanalabs: register to pci shutdown callback + - habanalabs: Fix memleak in hl_device_reset + - hwmon: (pwm-fan) Ensure that calculation doesn't discard big period values + - lib/raid6: Let $(UNROLL) rules work with macOS userland + - bfq: Fix computation of shallow depth + - arch/arc: add copy_user_page() to to fix build error on ARC + - misdn: dsp: select CONFIG_BITREVERSE + - net: ethernet: fs_enet: Add missing MODULE_LICENSE + - nvme-pci: mark Samsung PM1725a as IGNORE_DEV_SUBNQN + - nvmet-rdma: Fix list_del corruption on queue establishment failure + - drm/amdgpu: fix a GPU hang issue when remove device + - usb: typec: Fix copy paste error for NVIDIA alt-mode description + - ACPI: scan: add stub acpi_create_platform_device() for !CONFIG_ACPI + - drm/msm: Call msm_init_vram before binding the gpu + - ARM: picoxcell: fix missing interrupt-parent properties + - perf intel-pt: Fix 'CPU too large' error + - dump_common_audit_data(): fix racy accesses to ->d_name + - ASoC: meson: axg-tdm-interface: fix loopback + - ASoC: meson: axg-tdmin: fix axg skew offset + - ASoC: Intel: fix error code cnl_set_dsp_D0() + - nvme-tcp: fix possible data corruption with bio merges + - NFS4: Fix use-after-free in trace_event_raw_event_nfs4_set_lock + - pNFS: We want return-on-close to complete when evicting the inode + - pNFS: Mark layout for return if return-on-close was not sent + - pNFS: Stricter ordering of layoutget and layoutreturn + - NFS/pNFS: Fix a leak of the layout 'plh_outstanding' counter + - NFS: nfs_igrab_and_active must first reference the superblock + - ext4: fix superblock checksum failure when setting password salt + - RDMA/restrack: Don't treat as an error allocation ID wrapping + - RDMA/usnic: Fix memleak in find_free_vf_and_create_qp_grp + - bnxt_en: Improve stats context resource accounting with RDMA driver loaded. + - RDMA/mlx5: Fix wrong free of blue flame register on error + - IB/mlx5: Fix error unwinding when set_has_smi_cap fails + - drm/i915/dsi: Use unconditional msleep for the panel_on_delay when there is + no reset-deassert MIPI-sequence + - mm, slub: consider rest of partial list if acquire_slab() fails + - iommu/vt-d: Fix unaligned addresses for intel_flush_svm_range_dev() + - net: sunrpc: interpret the return value of kstrtou32 correctly + - dm: eliminate potential source of excessive kernel log noise + - ALSA: fireface: Fix integer overflow in transmit_midi_msg() + - ALSA: firewire-tascam: Fix integer overflow in midi_port_work() + - netfilter: conntrack: fix reading nf_conntrack_buckets + - netfilter: nf_nat: Fix memleak in nf_nat_init + - netfilter: nft_compat: remove flush counter optimization + - Linux 5.4.91 + * Focal update: v5.4.90 upstream stable release (LP: #1913487) + - x86/asm/32: Add ENDs to some functions and relabel with SYM_CODE_* + - vfio iommu: Add dma available capability + - net: cdc_ncm: correct overhead in delayed_ndp_size + - net: hns3: fix the number of queues actually used by ARQ + - net: hns3: fix a phy loopback fail issue + - net: stmmac: dwmac-sun8i: Balance internal PHY resource references + - net: stmmac: dwmac-sun8i: Balance internal PHY power + - net: vlan: avoid leaks on register_vlan_dev() failures + - net/sonic: Fix some resource leaks in error handling paths + - net: ipv6: fib: flush exceptions when purging route + - tools: selftests: add test for changing routes with PTMU exceptions + - net: fix pmtu check in nopmtudisc mode + - net: ip: always refragment ip defragmented packets + - octeontx2-af: fix memory leak of lmac and lmac->name + - nexthop: Fix off-by-one error in error path + - nexthop: Unlink nexthop group entry in error path + - s390/qeth: fix L2 header access in qeth_l3_osa_features_check() + - net: dsa: lantiq_gswip: Exclude RMII from modes that report 1 GbE + - net/mlx5: Use port_num 1 instead of 0 when delete a RoCE address + - net/mlx5e: ethtool, Fix restriction of autoneg with 56G + - chtls: Fix hardware tid leak + - chtls: Remove invalid set_tcb call + - chtls: Fix panic when route to peer not configured + - chtls: Replace skb_dequeue with skb_peek + - chtls: Added a check to avoid NULL pointer dereference + - chtls: Fix chtls resources release sequence + - x86/resctrl: Use an IPI instead of task_work_add() to update PQR_ASSOC MSR + - x86/resctrl: Don't move a task to the same resource group + - exfat: Month timestamp metadata accidentally incremented + - vmlinux.lds.h: Add PGO and AutoFDO input sections + - iio: imu: st_lsm6dsx: fix edge-trigger interrupts + - HID: wacom: Fix memory leakage caused by kfifo_alloc + - ARM: OMAP2+: omap_device: fix idling of devices during probe + - i2c: sprd: use a specific timeout to avoid system hang up issue + - dmaengine: dw-edma: Fix use after free in dw_edma_alloc_chunk() + - can: tcan4x5x: fix bittiming const, use common bittiming from m_can driver + - can: m_can: m_can_class_unregister(): remove erroneous m_can_clk_stop() + - can: kvaser_pciefd: select CONFIG_CRC32 + - cpufreq: powernow-k8: pass policy rather than use cpufreq_cpu_get() + - spi: stm32: FIFO threshold level - fix align packet size + - i2c: i801: Fix the i2c-mux gpiod_lookup_table not being properly terminated + - dmaengine: mediatek: mtk-hsdma: Fix a resource leak in the error handling + path of the probe function + - dmaengine: xilinx_dma: check dma_async_device_register return value + - dmaengine: xilinx_dma: fix incompatible param warning in _child_probe() + - dmaengine: xilinx_dma: fix mixed_enum_type coverity warning + - qed: select CONFIG_CRC32 + - wil6210: select CONFIG_CRC32 + - block: rsxx: select CONFIG_CRC32 + - lightnvm: select CONFIG_CRC32 + - iommu/intel: Fix memleak in intel_irq_remapping_alloc + - bpftool: Fix compilation failure for net.o with older glibc + - net/mlx5e: Fix memleak in mlx5e_create_l2_table_groups + - net/mlx5e: Fix two double free cases + - regmap: debugfs: Fix a memory leak when calling regmap_attach_dev + - wan: ds26522: select CONFIG_BITREVERSE + - regulator: qcom-rpmh-regulator: correct hfsmps515 definition + - net: mvpp2: disable force link UP during port init procedure + - KVM: arm64: Don't access PMCR_EL0 when no PMU is available + - block: fix use-after-free in disk_part_iter_next + - net: drop bogus skb with CHECKSUM_PARTIAL and offset beyond end of trimmed + packet + - regmap: debugfs: Fix a reversed if statement in regmap_debugfs_init() + - Linux 5.4.90 + * Focal update: v5.4.89 upstream stable release (LP: #1913486) + - workqueue: Kick a worker based on the actual activation of delayed works + - scsi: ufs: Fix wrong print message in dev_err() + - scsi: ufs-pci: Ensure UFS device is in PowerDown mode for suspend-to-disk + ->poweroff() + - scsi: ide: Do not set the RQF_PREEMPT flag for sense requests + - scsi: scsi_transport_spi: Set RQF_PM for domain validation commands + - lib/genalloc: fix the overflow when size is too big + - depmod: handle the case of /sbin/depmod without /sbin in PATH + - proc: change ->nlink under proc_subdir_lock + - proc: fix lookup in /proc/net subdirectories after setns(2) + - i40e: Fix Error I40E_AQ_RC_EINVAL when removing VFs + - iavf: fix double-release of rtnl_lock + - net: mvpp2: Add TCAM entry to drop flow control pause frames + - net: mvpp2: prs: fix PPPoE with ipv6 packet parse + - net: systemport: set dev->max_mtu to UMAC_MAX_MTU_SIZE + - ethernet: ucc_geth: fix use-after-free in ucc_geth_remove() + - ethernet: ucc_geth: set dev->max_mtu to 1518 + - atm: idt77252: call pci_disable_device() on error path + - net: mvpp2: Fix GoP port 3 Networking Complex Control configurations + - ibmvnic: continue fatal error reset after passive init + - net: ethernet: mvneta: Fix error handling in mvneta_probe + - virtio_net: Fix recursive call to cpus_read_lock() + - net/ncsi: Use real net-device for response handler + - net: ethernet: Fix memleak in ethoc_probe + - net-sysfs: take the rtnl lock when storing xps_cpus + - net-sysfs: take the rtnl lock when accessing xps_cpus_map and num_tc + - net-sysfs: take the rtnl lock when storing xps_rxqs + - net-sysfs: take the rtnl lock when accessing xps_rxqs_map and num_tc + - net: ethernet: ti: cpts: fix ethtool output when no ptp_clock registered + - tun: fix return value when the number of iovs exceeds MAX_SKB_FRAGS + - net: mvpp2: fix pkt coalescing int-threshold configuration + - ipv4: Ignore ECN bits for fib lookups in fib_compute_spec_dst() + - net: sched: prevent invalid Scell_log shift count + - net: hns: fix return value check in __lb_other_process() + - erspan: fix version 1 check in gre_parse_header() + - net: hdlc_ppp: Fix issues when mod_timer is called while timer is running + - r8169: work around power-saving bug on some chip versions + - net: dsa: lantiq_gswip: Enable GSWIP_MII_CFG_EN also for internal PHYs + - net: dsa: lantiq_gswip: Fix GSWIP_MII_CFG(p) register access + - CDC-NCM: remove "connected" log message + - net: usb: qmi_wwan: add Quectel EM160R-GL + - vhost_net: fix ubuf refcount incorrectly when sendmsg fails + - ionic: account for vlan tag len in rx buffer len + - net/sched: sch_taprio: ensure to reset/destroy all child qdiscs + - kbuild: don't hardcode depmod path + - Bluetooth: revert: hci_h5: close serdev device and free hu in h5_close + - video: hyperv_fb: Fix the mmap() regression for v5.4.y and older + - crypto: ecdh - avoid buffer overflow in ecdh_set_secret() + - crypto: asym_tpm: correct zero out potential secrets + - powerpc: Handle .text.{hot,unlikely}.* in linker script + - staging: mt7621-dma: Fix a resource leak in an error handling path + - usb: gadget: enable super speed plus + - USB: cdc-acm: blacklist another IR Droid device + - USB: cdc-wdm: Fix use after free in service_outstanding_interrupt(). + - usb: dwc3: ulpi: Use VStsDone to detect PHY regs access completion + - usb: chipidea: ci_hdrc_imx: add missing put_device() call in + usbmisc_get_init_data() + - USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set + - usb: usbip: vhci_hcd: protect shift size + - usb: uas: Add PNY USB Portable SSD to unusual_uas + - USB: serial: iuu_phoenix: fix DMA from stack + - USB: serial: option: add LongSung M5710 module support + - USB: serial: option: add Quectel EM160R-GL + - USB: yurex: fix control-URB timeout handling + - USB: usblp: fix DMA to stack + - ALSA: usb-audio: Fix UBSAN warnings for MIDI jacks + - usb: gadget: select CONFIG_CRC32 + - usb: gadget: f_uac2: reset wMaxPacketSize + - usb: gadget: function: printer: Fix a memory leak for interface descriptor + - usb: gadget: u_ether: Fix MTU size mismatch with RX packet size + - USB: gadget: legacy: fix return error code in acm_ms_bind() + - usb: gadget: Fix spinlock lockup on usb_function_deactivate + - usb: gadget: configfs: Preserve function ordering after bind failure + - usb: gadget: configfs: Fix use-after-free issue with udc_name + - USB: serial: keyspan_pda: remove unused variable + - x86/mm: Fix leak of pmd ptlock + - kvm: check tlbs_dirty directly + - ALSA: hda/via: Fix runtime PM for Clevo W35xSS + - ALSA: hda/conexant: add a new hda codec CX11970 + - ALSA: hda/realtek - Fix speaker volume control on Lenovo C940 + - ALSA: hda/realtek: Add two "Intel Reference board" SSID in the ALC256. + - btrfs: send: fix wrong file path when there is an inode with a pending rmdir + - Revert "device property: Keep secondary firmware node secondary by type" + - dmabuf: fix use-after-free of dmabuf's file->f_inode + - drm/i915: clear the gpu reloc batch + - netfilter: x_tables: Update remaining dereference to RCU + - netfilter: ipset: fix shift-out-of-bounds in htable_bits() + - netfilter: xt_RATEEST: reject non-null terminated string from userspace + - netfilter: nft_dynset: report EOPNOTSUPP on missing set feature + - x86/mtrr: Correct the range check before performing MTRR type lookups + - KVM: x86: fix shift out of bounds reported by UBSAN + - Linux 5.4.89 + * Focal update: v5.4.88 upstream stable release (LP: #1913223) + - Revert "drm/amd/display: Fix memory leaks in S3 resume" + - Revert "mtd: spinand: Fix OOB read" + - dmaengine: at_hdmac: Substitute kzalloc with kmalloc + - dmaengine: at_hdmac: add missing put_device() call in at_dma_xlate() + - dmaengine: at_hdmac: add missing kfree() call in at_dma_xlate() + - kdev_t: always inline major/minor helper functions + - iio:imu:bmi160: Fix alignment and data leak issues + - fuse: fix bad inode + - perf: Break deadlock involving exec_update_mutex + - rwsem: Implement down_read_killable_nested + - rwsem: Implement down_read_interruptible + - exec: Transform exec_update_mutex into a rw_semaphore + - mwifiex: Fix possible buffer overflows in mwifiex_cmd_802_11_ad_hoc_start + - Linux 5.4.88 + * Focal update: v5.4.87 upstream stable release (LP: #1912681) + - net/sched: sch_taprio: reset child qdiscs before freeing them + - md/raid10: initialize r10_bio->read_slot before use. + - thermal/drivers/cpufreq_cooling: Update cpufreq_state only if state has + changed + - ext4: prevent creating duplicate encrypted filenames + - ubifs: prevent creating duplicate encrypted filenames + - f2fs: prevent creating duplicate encrypted filenames + - fscrypt: add fscrypt_is_nokey_name() + - fscrypt: remove kernel-internal constants from UAPI header + - vfio/pci: Move dummy_resources_list init in vfio_pci_probe() + - btrfs: fix race when defragmenting leads to unnecessary IO + - ext4: don't remount read-only with errors=continue on reboot + - KVM: x86: avoid incorrect writes to host MSR_IA32_SPEC_CTRL + - KVM: SVM: relax conditions for allowing MSR_IA32_SPEC_CTRL accesses + - KVM: x86: reinstate vendor-agnostic check on SPEC_CTRL cpuid bits + - powerpc/bitops: Fix possible undefined behaviour with fls() and fls64() + - jffs2: Allow setting rp_size to zero during remounting + - jffs2: Fix NULL pointer dereference in rp_size fs option parsing + - scsi: block: Fix a race in the runtime power management code + - uapi: move constants from to + - tools headers UAPI: Sync linux/const.h with the kernel headers + - null_blk: Fix zone size initialization + - of: fix linker-section match-table corruption + - cgroup: Fix memory leak when parsing multiple source parameters + - scsi: cxgb4i: Fix TLS dependency + - Bluetooth: hci_h5: close serdev device and free hu in h5_close + - reiserfs: add check for an invalid ih_entry_count + - misc: vmw_vmci: fix kernel info-leak by initializing dbells in + vmci_ctx_get_chkpt_doorbells() + - media: gp8psk: initialize stats at power control logic + - f2fs: fix shift-out-of-bounds in sanity_check_raw_super() + - ALSA: seq: Use bool for snd_seq_queue internal flags + - ALSA: rawmidi: Access runtime->avail always in spinlock + - bfs: don't use WARNING: string when it's just info. + - fcntl: Fix potential deadlock in send_sig{io, urg}() + - rtc: sun6i: Fix memleak in sun6i_rtc_clk_init + - module: set MODULE_STATE_GOING state when a module fails to load + - quota: Don't overflow quota file offsets + - rtc: pl031: fix resource leak in pl031_probe + - powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe() + - i3c master: fix missing destroy_workqueue() on error in i3c_master_register + - NFSv4: Fix a pNFS layout related use-after-free race when freeing the inode + - f2fs: avoid race condition for shrinker count + - module: delay kobject uevent until after module init call + - fs/namespace.c: WARN if mnt_count has become negative + - um: ubd: Submit all data segments atomically + - tick/sched: Remove bogus boot "safety" check + - ALSA: pcm: Clear the full allocated memory at hw_params + - dm verity: skip verity work if I/O error when system is shutting down + - Linux 5.4.87 + + -- Guilherme G. Piccoli Thu, 25 Feb 2021 16:41:54 -0300 + +linux-oracle (5.4.0-1038.41) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1038.41 -proposed tracker (LP: #1913149) + + * Focal update: v5.4.85 upstream stable release (LP: #1910817) + - [Config] [oracle] updateconfigs for USB_SISUSBVGA_CON + + * Focal update: v5.4.84 upstream stable release (LP: #1910816) + - [Config] [oracle] updateconfigs for PGTABLE_MAPPING + + * Focal update: v5.4.80 upstream stable release (LP: #1908561) + - [Config] [oracle] updateconfigs for INFINIBAND_VIRT_DMA + + [ Ubuntu: 5.4.0-66.74 ] + + * focal/linux: 5.4.0-66.74 -proposed tracker (LP: #1913152) + * Add support for selective build of special drivers (LP: #1912789) + - [Packaging] Add support for ODM drivers + - [Packaging] Turn on ODM support for amd64 + * Packaging resync (LP: #1786013) + - update dkms package versions + - update dkms package versions + * Introduce the new NVIDIA 460-server series and update the 460 series + (LP: #1913200) + - [Config] dkms-versions -- drop NVIDIA 435 455 and 440-server + - [Config] dkms-versions -- add the 460-server nvidia driver + * Enable mute and micmute LED on HP EliteBook 850 G7 (LP: #1910102) + - ALSA: hda/realtek: Enable mute and micmute LED on HP EliteBook 850 G7 + * SYNA30B4:00 06CB:CE09 Mouse on HP EliteBook 850 G7 not working at all + (LP: #1908992) + - HID: multitouch: Enable multi-input for Synaptics pointstick/touchpad device + * HD Audio Device PCI ID for the Intel Cometlake-R platform (LP: #1912427) + - SAUCE: ALSA: hda: Add Cometlake-R PCI ID + * switch to an autogenerated nvidia series based core via dkms-versions + (LP: #1912803) + - [Packaging] nvidia -- use dkms-versions to define versions built + - [Packaging] update-version-dkms -- maintain flags fields + - [Config] dkms-versions -- add transitional/skip information for nvidia + packages + * udpgro.sh in net from ubuntu_kernel_selftests seems not reflecting sub-test + result (LP: #1908499) + - selftests: fix the return value for UDP GRO test + * qede: Kubernetes Internal DNS Failure due to QL41xxx NIC not supporting IPIP + tx csum offload (LP: #1909062) + - qede: fix offload for IPIP tunnel packets + * Use DCPD to control HP DreamColor panel (LP: #1911001) + - SAUCE: drm/dp: Another HP DreamColor panel brigntness fix + * kvm: Windows 2k19 with Hyper-v role gets stuck on pending hypervisor + requests on cascadelake based kvm hosts (LP: #1911848) + - KVM: x86: Set KVM_REQ_EVENT if run is canceled with req_immediate_exit set + * Ubuntu 20.10 four needed fixes to 'Add driver for Mellanox Connect-IB + adapters' (LP: #1905574) + - net/mlx5: Fix a race when moving command interface to polling mode + * Fix right sounds and mute/micmute LEDs for HP ZBook Fury 15/17 G7 Mobile + Workstation (LP: #1910561) + - ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP machines + * Ubuntu 20.04 - multicast counter is not increased in ip -s (LP: #1901842) + - net/mlx5e: Fix multicast counter not up-to-date in "ip -s" + * eeh-basic.sh in powerpc from ubuntu_kernel_selftests timeout with 5.4 P8 / + P9 (LP: #1882503) + - selftests/powerpc/eeh: disable kselftest timeout setting for eeh-basic + * DMI entry syntax fix for Pegatron / ByteSpeed C15B (LP: #1910639) + - Input: i8042 - unbreak Pegatron C15B + * CVE-2020-29372 + - mm: check that mm is still valid in madvise() + * update ENA driver, incl. new ethtool stats (LP: #1910291) + - net: ena: Change WARN_ON expression in ena_del_napi_in_range() + - net: ena: ethtool: convert stat_offset to 64 bit resolution + - net: ena: ethtool: Add new device statistics + - net: ena: ethtool: add stats printing to XDP queues + - net: ena: xdp: add queue counters for xdp actions + - net: ena: Change license into format to SPDX in all files + - net: ena: Change log message to netif/dev function + - net: ena: Capitalize all log strings and improve code readability + - net: ena: Remove redundant print of placement policy + - net: ena: Change RSS related macros and variables names + - net: ena: Fix all static chekers' warnings + - drivers/net/ethernet: remove incorrectly formatted doc + - net: ena: handle bad request id in ena_netdev + - net: ena: fix packet's addresses for rx_offset feature + * s390x broken with unknown syscall number on kernels < 5.8 (LP: #1895132) + - s390/ptrace: return -ENOSYS when invalid syscall is supplied + * Focal update: v5.4.86 upstream stable release (LP: #1910822) + - ARM: dts: sun7i: bananapi: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun8i: r40: bananapi-m2-berry: Fix dcdc1 regulator + - ARM: dts: sun8i: v40: bananapi-m2-berry: Fix ethernet node + - pinctrl: merrifield: Set default bias in case no particular value given + - pinctrl: baytrail: Avoid clearing debounce value when turning it off + - ARM: dts: sun8i: v3s: fix GIC node memory range + - ARM: dts: sun7i: pcduino3-nano: enable RGMII RX/TX delay on PHY + - ARM: dts: imx6qdl-wandboard-revd1: Remove PAD_GPIO_6 from enetgrp + - ARM: dts: imx6qdl-kontron-samx6i: fix I2C_PM scl pin + - PM: runtime: Add pm_runtime_resume_and_get to deal with usage counter + - gpio: zynq: fix reference leak in zynq_gpio functions + - gpio: mvebu: fix potential user-after-free on probe + - scsi: bnx2i: Requires MMU + - xsk: Fix xsk_poll()'s return type + - xsk: Replace datagram_poll by sock_poll_wait + - can: softing: softing_netdev_open(): fix error handling + - clk: renesas: r9a06g032: Drop __packed for portability + - block: Simplify REQ_OP_ZONE_RESET_ALL handling + - block: factor out requeue handling from dispatch code + - blk-mq: In blk_mq_dispatch_rq_list() "no budget" is a reason to kick + - pinctrl: aspeed: Fix GPIO requests on pass-through banks + - netfilter: x_tables: Switch synchronization to RCU + - netfilter: nft_compat: make sure xtables destructors have run + - netfilter: nft_dynset: fix timeouts later than 23 days + - afs: Fix memory leak when mounting with multiple source parameters + - Revert "gpio: eic-sprd: Use devm_platform_ioremap_resource()" + - gpio: eic-sprd: break loop when getting NULL device resource + - netfilter: nft_ct: Remove confirmation check for NFT_CT_ID + - selftests/bpf/test_offload.py: Reset ethtool features after failed setting + - RDMA/cm: Fix an attempt to use non-valid pointer when cleaning timewait + - i40e: Refactor rx_bi accesses + - i40e: optimise prefetch page refcount + - i40e: avoid premature Rx buffer reuse + - ixgbe: avoid premature Rx buffer reuse + - selftests: fix poll error in udpgro.sh + - net: mvpp2: add mvpp2_phylink_to_port() helper + - drm/tegra: replace idr_init() by idr_init_base() + - kernel/cpu: add arch override for clear_tasks_mm_cpumask() mm handling + - drm/tegra: sor: Disable clocks on error in tegra_sor_init() + - habanalabs: put devices before driver removal + - arm64: syscall: exit userspace before unmasking exceptions + - vxlan: Add needed_headroom for lower device + - vxlan: Copy needed_tailroom from lowerdev + - scsi: mpt3sas: Increase IOCInit request timeout to 30s + - dm table: Remove BUG_ON(in_interrupt()) + - iwlwifi: pcie: add one missing entry for AX210 + - drm/amd/display: Init clock value by current vbios CLKs + - perf/x86/intel: Check PEBS status correctly + - kbuild: avoid split lines in .mod files + - soc/tegra: fuse: Fix index bug in get_process_id + - usb: mtu3: fix memory corruption in mtu3_debugfs_regset() + - USB: serial: option: add interface-number sanity check to flag handling + - USB: gadget: f_acm: add support for SuperSpeed Plus + - USB: gadget: f_midi: setup SuperSpeed Plus descriptors + - usb: gadget: f_fs: Re-use SS descriptors for SuperSpeedPlus + - USB: gadget: f_rndis: fix bitrate for SuperSpeed and above + - usb: chipidea: ci_hdrc_imx: Pass DISABLE_DEVICE_STREAMING flag to imx6ul + - ARM: dts: exynos: fix roles of USB 3.0 ports on Odroid XU + - ARM: dts: exynos: fix USB 3.0 VBUS control and over-current pins on + Exynos5410 + - ARM: dts: exynos: fix USB 3.0 pins supply being turned off on Odroid XU + - coresight: tmc-etf: Fix NULL ptr dereference in tmc_enable_etf_sink_perf() + - coresight: tmc-etr: Check if page is valid before dma_map_page() + - coresight: tmc-etr: Fix barrier packet insertion for perf buffer + - coresight: etb10: Fix possible NULL ptr dereference in etb_enable_perf() + - scsi: megaraid_sas: Check user-provided offsets + - HID: i2c-hid: add Vero K147 to descriptor override + - serial_core: Check for port state when tty is in error state + - Bluetooth: Fix slab-out-of-bounds read in hci_le_direct_adv_report_evt() + - quota: Sanity-check quota file headers on load + - media: msi2500: assign SPI bus number dynamically + - crypto: af_alg - avoid undefined behavior accessing salg_name + - md: fix a warning caused by a race between concurrent md_ioctl()s + - drm/gma500: fix double free of gma_connector + - drm/aspeed: Fix Kconfig warning & subsequent build errors + - drm/mcde: Fix handling of platform_get_irq() error + - drm/tve200: Fix handling of platform_get_irq() error + - arm64: dts: renesas: hihope-rzg2-ex: Drop rxc-skew-ps from ethernet-phy node + - arm64: dts: renesas: cat875: Remove rxc-skew-ps from ethernet-phy node + - soc: renesas: rmobile-sysc: Fix some leaks in rmobile_init_pm_domains() + - soc: mediatek: Check if power domains can be powered on at boot time + - soc: qcom: geni: More properly switch to DMA mode + - Revert "i2c: i2c-qcom-geni: Fix DMA transfer race" + - RDMA/bnxt_re: Set queue pair state when being queried + - rtc: pcf2127: fix pcf2127_nvmem_read/write() returns + - selinux: fix error initialization in inode_doinit_with_dentry() + - ARM: dts: aspeed: s2600wf: Fix VGA memory region location + - RDMA/rxe: Compute PSN windows correctly + - x86/mm/ident_map: Check for errors from ident_pud_init() + - ARM: p2v: fix handling of LPAE translation in BE mode + - x86/apic: Fix x2apic enablement without interrupt remapping + - sched/deadline: Fix sched_dl_global_validate() + - sched: Reenable interrupts in do_sched_yield() + - drm/amdgpu: fix incorrect enum type + - crypto: talitos - Endianess in current_desc_hdr() + - crypto: talitos - Fix return type of current_desc_hdr() + - crypto: inside-secure - Fix sizeof() mismatch + - ASoC: sun4i-i2s: Fix lrck_period computation for I2S justified mode + - ARM: dts: aspeed: tiogapass: Remove vuart + - drm/amdgpu: fix build_coefficients() argument + - powerpc/64: Set up a kernel stack for secondaries before cpu_restore() + - spi: img-spfi: fix reference leak in img_spfi_resume + - f2fs: call f2fs_get_meta_page_retry for nat page + - drm/msm/dsi_pll_10nm: restore VCO rate during restore_state + - spi: spi-mem: fix reference leak in spi_mem_access_start + - ASoC: pcm: DRAIN support reactivation + - selinux: fix inode_doinit_with_dentry() LABEL_INVALID error handling + - spi: stm32: fix reference leak in stm32_spi_resume + - brcmfmac: Fix memory leak for unpaired brcmf_{alloc/free} + - arm64: dts: exynos: Include common syscon restart/poweroff for Exynos7 + - arm64: dts: exynos: Correct psci compatible used on Exynos7 + - Bluetooth: Fix null pointer dereference in hci_event_packet() + - Bluetooth: hci_h5: fix memory leak in h5_close + - spi: spi-ti-qspi: fix reference leak in ti_qspi_setup + - spi: mt7621: fix missing clk_disable_unprepare() on error in + mt7621_spi_probe + - spi: tegra20-slink: fix reference leak in slink ops of tegra20 + - spi: tegra20-sflash: fix reference leak in tegra_sflash_resume + - spi: tegra114: fix reference leak in tegra spi ops + - spi: bcm63xx-hsspi: fix missing clk_disable_unprepare() on error in + bcm63xx_hsspi_resume + - mwifiex: fix mwifiex_shutdown_sw() causing sw reset failure + - selftest/bpf: Add missed ip6ip6 test back + - ASoC: wm8998: Fix PM disable depth imbalance on error + - spi: sprd: fix reference leak in sprd_spi_remove + - ASoC: arizona: Fix a wrong free in wm8997_probe + - RDMa/mthca: Work around -Wenum-conversion warning + - MIPS: BCM47XX: fix kconfig dependency bug for BCM47XX_BCMA + - crypto: qat - fix status check in qat_hal_put_rel_rd_xfer() + - staging: greybus: codecs: Fix reference counter leak in error handling + - staging: gasket: interrupt: fix the missed eventfd_ctx_put() in + gasket_interrupt.c + - media: tm6000: Fix sizeof() mismatches + - media: mtk-vcodec: add missing put_device() call in mtk_vcodec_init_dec_pm() + - media: mtk-vcodec: add missing put_device() call in + mtk_vcodec_release_dec_pm() + - media: mtk-vcodec: add missing put_device() call in mtk_vcodec_init_enc_pm() + - media: v4l2-fwnode: Return -EINVAL for invalid bus-type + - ASoC: meson: fix COMPILE_TEST error + - scsi: core: Fix VPD LUN ID designator priorities + - media: solo6x10: fix missing snd_card_free in error handling case + - video: fbdev: atmel_lcdfb: fix return error code in atmel_lcdfb_of_init() + - drm/omap: dmm_tiler: fix return error code in omap_dmm_probe() + - Input: ads7846 - fix race that causes missing releases + - Input: ads7846 - fix integer overflow on Rt calculation + - Input: ads7846 - fix unaligned access on 7845 + - usb/max3421: fix return error code in max3421_probe() + - spi: mxs: fix reference leak in mxs_spi_probe + - selftests/bpf: Fix broken riscv build + - powerpc: Avoid broken GCC __attribute__((optimize)) + - powerpc/feature: Fix CPU_FTRS_ALWAYS by removing CPU_FTRS_GENERIC_32 + - EDAC/mce_amd: Use struct cpuinfo_x86.cpu_die_id for AMD NodeId + - crypto: crypto4xx - Replace bitwise OR with logical OR in crypto4xx_build_pd + - crypto: omap-aes - Fix PM disable depth imbalance in omap_aes_probe + - spi: fix resource leak for drivers without .remove callback + - soc: ti: knav_qmss: fix reference leak in knav_queue_probe + - soc: ti: Fix reference imbalance in knav_dma_probe + - drivers: soc: ti: knav_qmss_queue: Fix error return code in knav_queue_probe + - Input: omap4-keypad - fix runtime PM error handling + - clk: meson: Kconfig: fix dependency for G12A + - RDMA/cxgb4: Validate the number of CQEs + - memstick: fix a double-free bug in memstick_check + - ARM: dts: at91: sama5d4_xplained: add pincontrol for USB Host + - ARM: dts: at91: sama5d3_xplained: add pincontrol for USB Host + - mmc: pxamci: Fix error return code in pxamci_probe + - orinoco: Move context allocation after processing the skb + - qtnfmac: fix error return code in qtnf_pcie_probe() + - rsi: fix error return code in rsi_reset_card() + - cw1200: fix missing destroy_workqueue() on error in cw1200_init_common + - dmaengine: mv_xor_v2: Fix error return code in mv_xor_v2_probe() + - arm64: tegra: Fix DT binding for IO High Voltage entry + - media: siano: fix memory leak of debugfs members in smsdvb_hotplug + - platform/x86: mlx-platform: Remove PSU EEPROM from default platform + configuration + - platform/x86: mlx-platform: Remove PSU EEPROM from MSN274x platform + configuration + - samples: bpf: Fix lwt_len_hist reusing previous BPF map + - media: imx214: Fix stop streaming + - mips: cdmm: fix use-after-free in mips_cdmm_bus_discover + - media: max2175: fix max2175_set_csm_mode() error code + - slimbus: qcom-ngd-ctrl: Avoid sending power requests without QMI + - HSI: omap_ssi: Don't jump to free ID in ssi_add_controller() + - ARM: dts: Remove non-existent i2c1 from 98dx3236 + - arm64: dts: armada-3720-turris-mox: update ethernet-phy handle name + - arm64: dts: rockchip: Set dr_mode to "host" for OTG on rk3328-roc-cc + - power: supply: axp288_charger: Fix HP Pavilion x2 10 DMI matching + - power: supply: bq24190_charger: fix reference leak + - genirq/irqdomain: Don't try to free an interrupt that has no mapping + - arm64: dts: ls1028a: fix ENETC PTP clock input + - arm64: dts: qcom: c630: Polish i2c-hid devices + - PCI: Bounds-check command-line resource alignment requests + - PCI: Fix overflow in command-line resource alignment requests + - PCI: iproc: Fix out-of-bound array accesses + - arm64: dts: meson: fix spi-max-frequency on Khadas VIM2 + - arm64: dts: meson-sm1: fix typo in opp table + - soc: amlogic: canvas: add missing put_device() call in meson_canvas_get() + - ARM: dts: at91: at91sam9rl: fix ADC triggers + - platform/x86: dell-smbios-base: Fix error return code in dell_smbios_init + - ath10k: Fix the parsing error in service available event + - ath10k: Fix an error handling path + - ath10k: Release some resources in an error handling path + - SUNRPC: rpc_wake_up() should wake up tasks in the correct order + - NFSv4.2: condition READDIR's mask for security label based on LSM state + - SUNRPC: xprt_load_transport() needs to support the netid "rdma6" + - NFSv4: Fix the alignment of page data in the getdeviceinfo reply + - net: sunrpc: Fix 'snprintf' return value check in 'do_xprt_debugfs' + - lockd: don't use interval-based rebinding over TCP + - NFS: switch nfsiod to be an UNBOUND workqueue. + - selftests/seccomp: Update kernel config + - vfio-pci: Use io_remap_pfn_range() for PCI IO memory + - hwmon: (ina3221) Fix PM usage counter unbalance in ina3221_write_enable + - media: saa7146: fix array overflow in vidioc_s_audio() + - powerpc/perf: Fix crash with is_sier_available when pmu is not set + - powerpc/64: Fix an EMIT_BUG_ENTRY in head_64.S + - clocksource/drivers/orion: Add missing clk_disable_unprepare() on error path + - clocksource/drivers/cadence_ttc: Fix memory leak in ttc_setup_clockevent() + - iio: hrtimer-trigger: Mark hrtimer to expire in hard interrupt context + - ARM: dts: at91: sama5d2: map securam as device + - bpf: Fix bpf_put_raw_tracepoint()'s use of __module_address() + - pinctrl: falcon: add missing put_device() call in pinctrl_falcon_probe() + - arm64: dts: rockchip: Fix UART pull-ups on rk3328 + - memstick: r592: Fix error return in r592_probe() + - MIPS: Don't round up kernel sections size for memblock_add() + - net/mlx5: Properly convey driver version to firmware + - ASoC: jz4740-i2s: add missed checks for clk_get() + - dm ioctl: fix error return code in target_message + - phy: renesas: rcar-gen3-usb2: disable runtime pm in case of failure + - clocksource/drivers/arm_arch_timer: Use stable count reader in erratum sne + - clocksource/drivers/arm_arch_timer: Correct fault programming of + CNTKCTL_EL1.EVNTI + - cpufreq: ap806: Add missing MODULE_DEVICE_TABLE + - cpufreq: highbank: Add missing MODULE_DEVICE_TABLE + - cpufreq: mediatek: Add missing MODULE_DEVICE_TABLE + - cpufreq: qcom: Add missing MODULE_DEVICE_TABLE + - cpufreq: st: Add missing MODULE_DEVICE_TABLE + - cpufreq: sun50i: Add missing MODULE_DEVICE_TABLE + - cpufreq: loongson1: Add missing MODULE_ALIAS + - cpufreq: scpi: Add missing MODULE_ALIAS + - Bluetooth: btusb: Add the missed release_firmware() in + btusb_mtk_setup_firmware() + - Bluetooth: btmtksdio: Add the missed release_firmware() in + mtk_setup_firmware() + - arm64: dts: meson: fix PHY deassert timing requirements + - ARM: dts: meson: fix PHY deassert timing requirements + - arm64: dts: meson: g12a: x96-max: fix PHY deassert timing requirements + - scsi: qedi: Fix missing destroy_workqueue() on error in __qedi_probe + - scsi: pm80xx: Fix error return in pm8001_pci_probe() + - seq_buf: Avoid type mismatch for seq_buf_init + - scsi: fnic: Fix error return code in fnic_probe() + - platform/x86: mlx-platform: Fix item counter assignment for MSN2700, MSN24xx + systems + - powerpc/pseries/hibernation: drop pseries_suspend_begin() from suspend ops + - powerpc/pseries/hibernation: remove redundant cacheinfo update + - drm/mediatek: avoid dereferencing a null hdmi_phy on an error message + - ASoC: amd: change clk_get() to devm_clk_get() and add missed checks + - powerpc/mm: sanity_check_fault() should work for all, not only BOOK3S + - usb: ehci-omap: Fix PM disable depth umbalance in ehci_hcd_omap_probe + - usb: oxu210hp-hcd: Fix memory leak in oxu_create + - speakup: fix uninitialized flush_lock + - nfsd: Fix message level for normal termination + - nfs_common: need lock during iterate through the list + - x86/kprobes: Restore BTF if the single-stepping is cancelled + - platform/chrome: cros_ec_spi: Don't overwrite spi::mode + - bus: fsl-mc: fix error return code in fsl_mc_object_allocate() + - s390/cio: fix use-after-free in ccw_device_destroy_console + - iwlwifi: mvm: hook up missing RX handlers + - erofs: avoid using generic_block_bmap + - can: m_can: m_can_config_endisable(): remove double clearing of clock stop + request bit + - RDMA/core: Do not indicate device ready when device enablement fails + - remoteproc: q6v5-mss: fix error handling in q6v5_pds_enable + - remoteproc: qcom: fix reference leak in adsp_start + - remoteproc: qcom: Fix potential NULL dereference in adsp_init_mmio() + - clk: tegra: Fix duplicated SE clock entry + - mtd: rawnand: gpmi: fix reference count leak in gpmi ops + - mtd: rawnand: meson: Fix a resource leak in init + - mtd: rawnand: gpmi: Fix the random DMA timeout issue + - extcon: max77693: Fix modalias string + - crypto: atmel-i2c - select CONFIG_BITREVERSE + - mac80211: don't set set TDLS STA bandwidth wider than possible + - ASoC: wm_adsp: remove "ctl" from list on error in wm_adsp_create_control() + - irqchip/alpine-msi: Fix freeing of interrupts on allocation error path + - watchdog: armada_37xx: Add missing dependency on HAS_IOMEM + - watchdog: sirfsoc: Add missing dependency on HAS_IOMEM + - watchdog: sprd: remove watchdog disable from resume fail path + - watchdog: sprd: check busy bit before new loading rather than after that + - watchdog: Fix potential dereferencing of null pointer + - ubifs: Fix error return code in ubifs_init_authentication() + - um: Monitor error events in IRQ controller + - um: tty: Fix handling of close in tty lines + - um: chan_xterm: Fix fd leak + - sunrpc: fix xs_read_xdr_buf for partial pages receive + - RDMA/cma: Don't overwrite sgid_attr after device is released + - nfc: s3fwrn5: Release the nfc firmware + - powerpc/ps3: use dma_mapping_error() + - sparc: fix handling of page table constructor failure + - mm: don't wake kswapd prematurely when watermark boosting is disabled + - checkpatch: fix unescaped left brace + - lan743x: fix rx_napi_poll/interrupt ping-pong + - net: bcmgenet: Fix a resource leak in an error handling path in the probe + functin + - net: allwinner: Fix some resources leak in the error handling path of the + probe and in the remove function + - net: korina: fix return value + - libnvdimm/label: Return -ENXIO for no slot in __blk_label_update + - watchdog: qcom: Avoid context switch in restart handler + - watchdog: coh901327: add COMMON_CLK dependency + - clk: ti: Fix memleak in ti_fapll_synth_setup + - pwm: zx: Add missing cleanup in error path + - pwm: lp3943: Dynamically allocate PWM chip base + - perf record: Fix memory leak when using '--user-regs=?' to list registers + - qlcnic: Fix error code in probe + - virtio_ring: Cut and paste bugs in vring_create_virtqueue_packed() + - virtio_net: Fix error code in probe() + - virtio_ring: Fix two use after free bugs + - clk: at91: sam9x60: remove atmel,osc-bypass support + - clk: s2mps11: Fix a resource leak in error handling paths in the probe + function + - clk: sunxi-ng: Make sure divider tables have sentinel + - kconfig: fix return value of do_error_if() + - perf probe: Fix memory leak when synthesizing SDT probes + - ARM: sunxi: Add machine match for the Allwinner V3 SoC + - cfg80211: initialize rekey_data + - fix namespaced fscaps when !CONFIG_SECURITY + - lwt: Disable BH too in run_lwt_bpf() + - drm/amd/display: Prevent bandwidth overflow + - drm/amdkfd: Fix leak in dmabuf import + - Input: cros_ec_keyb - send 'scancodes' in addition to key events + - initramfs: fix clang build failure + - Input: goodix - add upside-down quirk for Teclast X98 Pro tablet + - vfio/pci/nvlink2: Do not attempt NPU2 setup on POWER8NVL NPU + - media: gspca: Fix memory leak in probe + - media: sunxi-cir: ensure IR is handled when it is continuous + - media: netup_unidvb: Don't leak SPI master in probe error path + - media: ipu3-cio2: Remove traces of returned buffers + - media: ipu3-cio2: Return actual subdev format + - media: ipu3-cio2: Serialise access to pad format + - media: ipu3-cio2: Validate mbus format in setting subdev format + - media: ipu3-cio2: Make the field on subdev format V4L2_FIELD_NONE + - Input: cyapa_gen6 - fix out-of-bounds stack access + - ALSA: hda/ca0132 - Change Input Source enum strings. + - Revert "ACPI / resources: Use AE_CTRL_TERMINATE to terminate resources + walks" + - ACPI: PNP: compare the string length in the matching_id() + - ALSA: hda: Fix regressions on clear and reconfig sysfs + - ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg. + - ALSA: hda/realtek: make bass spk volume adjustable on a yoga laptop + - ALSA: hda/realtek - Enable headset mic of ASUS X430UN with ALC256 + - ALSA: hda/realtek - Enable headset mic of ASUS Q524UQK with ALC255 + - ALSA: hda/realtek - Add supported for more Lenovo ALC285 Headset Button + - ALSA: pcm: oss: Fix a few more UBSAN fixes + - ALSA/hda: apply jack fixup for the Acer Veriton N4640G/N6640G/N2510G + - ALSA: hda/realtek: Add quirk for MSI-GP73 + - ALSA: hda/realtek: Apply jack fixup for Quanta NL3 + - ALSA: usb-audio: Add VID to support native DSD reproduction on FiiO devices + - ALSA: usb-audio: Disable sample read check if firmware doesn't give back + - ALSA: core: memalloc: add page alignment for iram + - s390/smp: perform initial CPU reset also for SMT siblings + - s390/kexec_file: fix diag308 subcode when loading crash kernel + - s390/dasd: fix hanging device offline processing + - s390/dasd: prevent inconsistent LCU device data + - s390/dasd: fix list corruption of pavgroup group list + - s390/dasd: fix list corruption of lcu list + - binder: add flag to clear buffer on txn complete + - ASoC: cx2072x: Fix doubly definitions of Playback and Capture streams + - staging: comedi: mf6x4: Fix AI end-of-conversion detection + - perf/x86/intel: Add event constraint for CYCLE_ACTIVITY.STALLS_MEM_ANY + - perf/x86/intel: Fix rtm_abort_event encoding on Ice Lake + - powerpc/perf: Exclude kernel samples while counting events in user space. + - crypto: ecdh - avoid unaligned accesses in ecdh_set_secret() + - crypto: arm/aes-ce - work around Cortex-A57/A72 silion errata + - EDAC/i10nm: Use readl() to access MMIO registers + - EDAC/amd64: Fix PCI component registration + - cpuset: fix race between hotplug work and later CPU offline + - USB: serial: mos7720: fix parallel-port state restore + - USB: serial: digi_acceleport: fix write-wakeup deadlocks + - USB: serial: keyspan_pda: fix dropped unthrottle interrupts + - USB: serial: keyspan_pda: fix write deadlock + - USB: serial: keyspan_pda: fix stalled writes + - USB: serial: keyspan_pda: fix write-wakeup use-after-free + - USB: serial: keyspan_pda: fix tx-unthrottle use-after-free + - USB: serial: keyspan_pda: fix write unthrottling + - btrfs: do not shorten unpin len for caching block groups + - ext4: fix a memory leak of ext4_free_data + - ext4: fix deadlock with fs freezing and EA inodes + - KVM: arm64: Introduce handling of AArch32 TTBCR2 traps + - ARM: dts: pandaboard: fix pinmux for gpio user button of Pandaboard ES + - ARM: dts: at91: sama5d2: fix CAN message ram offset and size + - xprtrdma: Fix XDRBUF_SPARSE_PAGES support + - powerpc: Fix incorrect stw{, ux, u, x} instructions in __set_pte_at + - powerpc/rtas: Fix typo of ibm,open-errinjct in RTAS filter + - powerpc/feature: Add CPU_FTR_NOEXECUTE to G2_LE + - powerpc/xmon: Change printk() to pr_cont() + - powerpc/8xx: Fix early debug when SMC1 is relocated + - powerpc/mm: Fix verification of MMU_FTR_TYPE_44x + - powerpc/powernv/npu: Do not attempt NPU2 setup on POWER8NVL NPU + - powerpc/powernv/memtrace: Don't leak kernel memory to user space + - powerpc/powernv/memtrace: Fix crashing the kernel when enabling concurrently + - ima: Don't modify file descriptor mode on the fly + - um: Remove use of asprinf in umid.c + - ceph: fix race in concurrent __ceph_remove_cap invocations + - SMB3: avoid confusing warning message on mount to Azure + - ubifs: wbuf: Don't leak kernel memory to flash + - jffs2: Fix GC exit abnormally + - jffs2: Fix ignoring mounting options problem during remounting + - jfs: Fix array index bounds check in dbAdjTree + - platform/x86: mlx-platform: remove an unused variable + - drm/amd/display: Fix memory leaks in S3 resume + - drm/dp_aux_dev: check aux_dev before use in drm_dp_aux_dev_get_by_minor() + - drm/i915: Fix mismatch between misplaced vma check and vma insert + - spi: pxa2xx: Fix use-after-free on unbind + - spi: spi-sh: Fix use-after-free on unbind + - spi: atmel-quadspi: Fix use-after-free on unbind + - spi: davinci: Fix use-after-free on unbind + - spi: fsl: fix use of spisel_boot signal on MPC8309 + - spi: gpio: Don't leak SPI master in probe error path + - spi: mxic: Don't leak SPI master in probe error path + - spi: pic32: Don't leak DMA channels in probe error path + - spi: rb4xx: Don't leak SPI master in probe error path + - spi: sc18is602: Don't leak SPI master in probe error path + - spi: st-ssc4: Fix unbalanced pm_runtime_disable() in probe error path + - spi: synquacer: Disable clock in probe error path + - spi: mt7621: Disable clock in probe error path + - spi: mt7621: Don't leak SPI master in probe error path + - spi: atmel-quadspi: Disable clock in probe error path + - spi: atmel-quadspi: Fix AHB memory accesses + - soc: qcom: smp2p: Safely acquire spinlock without IRQs + - mtd: spinand: Fix OOB read + - mtd: parser: cmdline: Fix parsing of part-names with colons + - mtd: rawnand: qcom: Fix DMA sync on FLASH_STATUS register read + - mtd: rawnand: meson: fix meson_nfc_dma_buffer_release() arguments + - scsi: qla2xxx: Fix crash during driver load on big endian machines + - scsi: lpfc: Fix invalid sleeping context in lpfc_sli4_nvmet_alloc() + - scsi: lpfc: Re-fix use after free in lpfc_rq_buf_free() + - iio: buffer: Fix demux update + - iio: adc: rockchip_saradc: fix missing clk_disable_unprepare() on error in + rockchip_saradc_resume + - iio:light:rpr0521: Fix timestamp alignment and prevent data leak. + - iio:light:st_uvis25: Fix timestamp alignment and prevent data leak. + - iio:magnetometer:mag3110: Fix alignment and data leak issues. + - iio:pressure:mpl3115: Force alignment of buffer + - iio:imu:bmi160: Fix too large a buffer. + - iio:adc:ti-ads124s08: Fix buffer being too long. + - iio:adc:ti-ads124s08: Fix alignment and data leak issues. + - md/cluster: block reshape with remote resync job + - md/cluster: fix deadlock when node is doing resync job + - pinctrl: sunxi: Always call chained_irq_{enter, exit} in + sunxi_pinctrl_irq_handler + - clk: ingenic: Fix divider calculation with div tables + - clk: mvebu: a3700: fix the XTAL MODE pin to MPP1_9 + - clk: tegra: Do not return 0 on failure + - device-dax/core: Fix memory leak when rmmod dax.ko + - dma-buf/dma-resv: Respect num_fences when initializing the shared fence + list. + - xen-blkback: set ring->xenblkd to NULL after kthread_stop() + - xen/xenbus: Allow watches discard events before queueing + - xen/xenbus: Add 'will_handle' callback support in xenbus_watch_path() + - xen/xenbus/xen_bus_type: Support will_handle watch callback + - xen/xenbus: Count pending messages for each watch + - xenbus/xenbus_backend: Disallow pending watch messages + - libnvdimm/namespace: Fix reaping of invalidated block-window-namespace + labels + - platform/x86: intel-vbtn: Allow switch events on Acer Switch Alpha 12 + - PCI: Fix pci_slot_release() NULL pointer dereference + - regulator: axp20x: Fix DLDO2 voltage control register mask for AXP22x + - rtc: ep93xx: Fix NULL pointer dereference in ep93xx_rtc_read_time + - Revert: "ring-buffer: Remove HAVE_64BIT_ALIGNED_ACCESS" + - x86/CPU/AMD: Save AMD NodeId as cpu_die_id + - Linux 5.4.86 + * Focal update: v5.4.85 upstream stable release (LP: #1910817) + - ptrace: Prevent kernel-infoleak in ptrace_get_syscall_info() + - ipv4: fix error return code in rtm_to_fib_config() + - mac80211: mesh: fix mesh_pathtbl_init() error path + - net: bridge: vlan: fix error return code in __vlan_add() + - vrf: packets with lladdr src needs dst at input with orig_iif when needs + strict + - net: hns3: remove a misused pragma packed + - udp: fix the proto value passed to ip_protocol_deliver_rcu for the segments + - enetc: Fix reporting of h/w packet counters + - bridge: Fix a deadlock when enabling multicast snooping + - net: stmmac: free tx skb buffer in stmmac_resume() + - tcp: select sane initial rcvq_space.space for big MSS + - tcp: fix cwnd-limited bug for TSO deferral where we send nothing + - net/mlx4_en: Avoid scheduling restart task if it is already running + - lan743x: fix for potential NULL pointer dereference with bare card + - net/mlx4_en: Handle TX error CQE + - net: ll_temac: Fix potential NULL dereference in temac_probe() + - net: stmmac: dwmac-meson8b: fix mask definition of the m250_sel mux + - net: stmmac: delete the eee_ctrl_timer after napi disabled + - ktest.pl: If size of log is too big to email, email error message + - USB: dummy-hcd: Fix uninitialized array use in init() + - USB: add RESET_RESUME quirk for Snapscan 1212 + - ALSA: usb-audio: Fix potential out-of-bounds shift + - ALSA: usb-audio: Fix control 'access overflow' errors from chmap + - xhci: Give USB2 ports time to enter U3 in bus suspend + - xhci-pci: Allow host runtime PM as default for Intel Alpine Ridge LP + - USB: UAS: introduce a quirk to set no_write_same + - USB: sisusbvga: Make console support depend on BROKEN + - [Config] updateconfigs for USB_SISUSBVGA_CON + - ALSA: pcm: oss: Fix potential out-of-bounds shift + - serial: 8250_omap: Avoid FIFO corruption caused by MDR1 access + - KVM: mmu: Fix SPTE encoding of MMIO generation upper half + - membarrier: Explicitly sync remote cores when SYNC_CORE is requested + - x86/resctrl: Remove unused struct mbm_state::chunks_bw + - x86/resctrl: Fix incorrect local bandwidth when mba_sc is enabled + - Linux 5.4.85 + * Focal update: v5.4.84 upstream stable release (LP: #1910816) + - Kbuild: do not emit debug info for assembly with LLVM_IAS=1 + - x86/lib: Change .weak to SYM_FUNC_START_WEAK for arch/x86/lib/mem*_64.S + - iwlwifi: pcie: limit memory read spin time + - arm64: dts: rockchip: Assign a fixed index to mmc devices on rk3399 boards. + - iwlwifi: pcie: set LTR to avoid completion timeout + - iwlwifi: mvm: fix kernel panic in case of assert during CSA + - powerpc: Drop -me200 addition to build flags + - arm64: dts: broadcom: clear the warnings caused by empty dma-ranges + - ARC: stack unwinding: don't assume non-current task is sleeping + - scsi: ufs: Make sure clk scaling happens only when HBA is runtime ACTIVE + - interconnect: qcom: qcs404: Remove GPU and display RPM IDs + - ibmvnic: skip tx timeout reset while in resetting + - irqchip/gic-v3-its: Unconditionally save/restore the ITS state on suspend + - spi: spi-nxp-fspi: fix fspi panic by unexpected interrupts + - soc: fsl: dpio: Get the cpumask through cpumask_of(cpu) + - arm64: tegra: Disable the ACONNECT for Jetson TX2 + - platform/x86: thinkpad_acpi: Do not report SW_TABLET_MODE on Yoga 11e + - platform/x86: thinkpad_acpi: Add BAT1 is primary battery quirk for Thinkpad + Yoga 11e 4th gen + - platform/x86: acer-wmi: add automatic keyboard background light toggle key + as KEY_LIGHTS_TOGGLE + - platform/x86: intel-vbtn: Support for tablet mode on HP Pavilion 13 x360 PC + - platform/x86: touchscreen_dmi: Add info for the Irbis TW118 tablet + - can: m_can: m_can_dev_setup(): add support for bosch mcan version 3.3.0 + - ktest.pl: Fix incorrect reboot for grub2bls + - Input: cm109 - do not stomp on control URB + - Input: i8042 - add Acer laptops to the i8042 reset list + - mmc: block: Fixup condition for CMD13 polling for RPMB requests + - drm/i915/display/dp: Compute the correct slice count for VDSC on DP + - kbuild: avoid static_assert for genksyms + - proc: use untagged_addr() for pagemap_read addresses + - scsi: be2iscsi: Revert "Fix a theoretical leak in beiscsi_create_eqs()" + - x86/mm/mem_encrypt: Fix definition of PMD_FLAGS_DEC_WP + - x86/membarrier: Get rid of a dubious optimization + - x86/apic/vector: Fix ordering in vector assignment + - mm/zsmalloc.c: drop ZSMALLOC_PGTABLE_MAPPING + - [Config] updateconfigs for PGTABLE_MAPPING + - compiler.h: fix barrier_data() on clang + - Linux 5.4.84 + * MSFT Touchpad not working on Lenovo Legion-5 15ARH05 (LP: #1887190) // Focal + update: v5.4.84 upstream stable release (LP: #1910816) + - pinctrl: amd: remove debounce filter setting in IRQ type setting + * Focal update: v5.4.83 upstream stable release (LP: #1910784) + - pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq + pin to output + - pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., + GPIOD_OUT_HIGH) + - usb: gadget: f_fs: Use local copy of descriptors for userspace copy + - USB: serial: kl5kusb105: fix memleak on open + - USB: serial: ch341: add new Product ID for CH341A + - USB: serial: ch341: sort device-id entries + - USB: serial: option: add Fibocom NL668 variants + - USB: serial: option: add support for Thales Cinterion EXS82 + - USB: serial: option: fix Quectel BG96 matching + - tty: Fix ->pgrp locking in tiocspgrp() + - tty: Fix ->session locking + - ALSA: hda/realtek: Fix bass speaker DAC assignment on Asus Zephyrus G14 + - ALSA: hda/realtek: Add mute LED quirk to yet another HP x360 model + - ALSA: hda/realtek: Enable headset of ASUS UX482EG & B9400CEA with ALC294 + - ALSA: hda/realtek - Add new codec supported for ALC897 + - ALSA: hda/generic: Add option to enforce preferred_dacs pairs + - ftrace: Fix updating FTRACE_FL_TRAMP + - cifs: allow syscalls to be restarted in __smb_send_rqst() + - cifs: fix potential use-after-free in cifs_echo_request() + - i2c: imx: Don't generate STOP condition if arbitration has been lost + - thunderbolt: Fix use-after-free in remove_unplugged_switch() + - drm/i915/gt: Program mocs:63 for cache eviction on gen9 + - scsi: mpt3sas: Fix ioctl timeout + - dm writecache: fix the maximum number of arguments + - powerpc/64s/powernv: Fix memory corruption when saving SLB entries on MCE + - genirq/irqdomain: Add an irq_create_mapping_affinity() function + - powerpc/pseries: Pass MSI affinity to irq_create_mapping() + - dm: fix bug with RCU locking in dm_blk_report_zones + - dm: remove invalid sparse __acquires and __releases annotations + - x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes + - coredump: fix core_pattern parse error + - mm: list_lru: set shrinker map bit when child nr_items is not zero + - mm/swapfile: do not sleep with a spin lock held + - speakup: Reject setting the speakup line discipline outside of speakup + - i2c: imx: Fix reset of I2SR_IAL flag + - i2c: imx: Check for I2SR_IAL after every byte + - spi: bcm2835: Release the DMA channel if probe fails after dma_init + - iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs + - tracing: Fix userstacktrace option for instances + - lib/syscall: fix syscall registers retrieval on 32-bit platforms + - can: af_can: can_rx_unregister(): remove WARN() statement from list + operation sanity check + - gfs2: check for empty rgrp tree in gfs2_ri_update + - netfilter: ipset: prevent uninit-value in hash_ip6_add + - tipc: fix a deadlock when flushing scheduled work + - ASoC: wm_adsp: fix error return code in wm_adsp_load() + - rtw88: debug: Fix uninitialized memory in debugfs code + - i2c: qup: Fix error return code in qup_i2c_bam_schedule_desc() + - dm writecache: remove BUG() and fail gracefully instead + - Input: i8042 - fix error return code in i8042_setup_aux() + - netfilter: nf_tables: avoid false-postive lockdep splat + - netfilter: nftables_offload: set address type in control dissector + - x86/insn-eval: Use new for_each_insn_prefix() macro to loop over prefixes + bytes + - Linux 5.4.83 + * dep-8 ubuntu-regression-suite tests are not run for all linux-hwe-* kernels + (LP: #1908529) + - [dep-8] Allow all hwe kernels + * failing ftrace self tests from 5.7+ onwards (LP: #1893024) + - SAUCE: Revert "selftests/ftrace: check for do_sys_openat2 in user-memory + test" + * selftests: test_vxlan_under_vrf: mute unnecessary error message + (LP: #1908342) + - selftests: test_vxlan_under_vrf: mute unnecessary error message + * Focal update: v5.4.82 upstream stable release (LP: #1908564) + - devlink: Hold rtnl lock while reading netdev attributes + - ipv6: addrlabel: fix possible memory leak in ip6addrlbl_net_init + - net/af_iucv: set correct sk_protocol for child sockets + - net/tls: missing received data after fast remote close + - net/tls: Protect from calling tls_dev_del for TLS RX twice + - rose: Fix Null pointer dereference in rose_send_frame() + - sock: set sk_err to ee_errno on dequeue from errq + - tcp: Set INET_ECN_xmit configuration in tcp_reinit_congestion_control + - tun: honor IOCB_NOWAIT flag + - usbnet: ipheth: fix connectivity with iOS 14 + - bonding: wait for sysfs kobject destruction before freeing struct slave + - staging/octeon: fix up merge error + - ima: extend boot_aggregate with kernel measurements + - sched/fair: Fix unthrottle_cfs_rq() for leaf_cfs_rq list + - netfilter: bridge: reset skb->pkt_type after NF_INET_POST_ROUTING traversal + - ipv4: Fix tos mask in inet_rtm_getroute() + - dt-bindings: net: correct interrupt flags in examples + - chelsio/chtls: fix panic during unload reload chtls + - ibmvnic: Ensure that SCRQ entry reads are correctly ordered + - ibmvnic: Fix TX completion error handling + - inet_ecn: Fix endianness of checksum update when setting ECT(1) + - net: ip6_gre: set dev->hard_header_len when using header_ops + - net/x25: prevent a couple of overflows + - cxgb3: fix error return code in t3_sge_alloc_qset() + - net: pasemi: fix error return code in pasemi_mac_open() + - vxlan: fix error return code in __vxlan_dev_create() + - chelsio/chtls: fix a double free in chtls_setkey() + - net: mvpp2: Fix error return code in mvpp2_open() + - net: skbuff: ensure LSE is pullable before decrementing the MPLS ttl + - net: openvswitch: ensure LSE is pullable before reading it + - net/sched: act_mpls: ensure LSE is pullable before reading it + - net/mlx5: DR, Proper handling of unsupported Connect-X6DX SW steering + - net/mlx5: Fix wrong address reclaim when command interface is down + - ALSA: usb-audio: US16x08: fix value count for level meters + - Input: xpad - support Ardwiino Controllers + - tracing: Remove WARN_ON in start_thread() + - RDMA/i40iw: Address an mmap handler exploit in i40iw + - Linux 5.4.82 + * Focal update: v5.4.81 upstream stable release (LP: #1908562) + - spi: bcm-qspi: Fix use-after-free on unbind + - spi: bcm2835: Fix use-after-free on unbind + - ipv4: use IS_ENABLED instead of ifdef + - netfilter: clear skb->next in NF_HOOK_LIST() + - btrfs: tree-checker: add missing return after error in root_item + - btrfs: tree-checker: add missing returns after data_ref alignment checks + - btrfs: don't access possibly stale fs_info data for printing duplicate + device + - btrfs: fix lockdep splat when reading qgroup config on mount + - wireless: Use linux/stddef.h instead of stddef.h + - smb3: Call cifs reconnect from demultiplex thread + - smb3: Avoid Mid pending list corruption + - smb3: Handle error case during offload read path + - cifs: fix a memleak with modefromsid + - KVM: PPC: Book3S HV: XIVE: Fix possible oops when accessing ESB page + - KVM: arm64: vgic-v3: Drop the reporting of GICR_TYPER.Last for userspace + - KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint + - KVM: x86: Fix split-irqchip vs interrupt injection window request + - trace: fix potenial dangerous pointer + - arm64: pgtable: Fix pte_accessible() + - arm64: pgtable: Ensure dirty bit is preserved across pte_wrprotect() + - HID: uclogic: Add ID for Trust Flex Design Tablet + - HID: ite: Replace ABS_MISC 120/121 events with touchpad on/off keypresses + - HID: cypress: Support Varmilo Keyboards' media hotkeys + - HID: add support for Sega Saturn + - Input: i8042 - allow insmod to succeed on devices without an i8042 + controller + - HID: hid-sensor-hub: Fix issue with devices with no report ID + - staging: ralink-gdma: fix kconfig dependency bug for DMA_RALINK + - HID: add HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE for Gamevice devices + - dmaengine: xilinx_dma: use readl_poll_timeout_atomic variant + - x86/xen: don't unbind uninitialized lock_kicker_irq + - HID: logitech-hidpp: Add HIDPP_CONSUMER_VENDOR_KEYS quirk for the Dinovo + Edge + - HID: Add Logitech Dinovo Edge battery quirk + - proc: don't allow async path resolution of /proc/self components + - nvme: free sq/cq dbbuf pointers when dbbuf set fails + - vhost scsi: fix cmd completion race + - dmaengine: pl330: _prep_dma_memcpy: Fix wrong burst size + - scsi: libiscsi: Fix NOP race condition + - scsi: target: iscsi: Fix cmd abort fabric stop race + - perf/x86: fix sysfs type mismatches + - xtensa: uaccess: Add missing __user to strncpy_from_user() prototype + - net: dsa: mv88e6xxx: Wait for EEPROM done after HW reset + - bus: ti-sysc: Fix bogus resetdone warning on enable for cpsw + - ARM: OMAP2+: Manage MPU state properly for omap_enter_idle_coupled() + - phy: tegra: xusb: Fix dangling pointer on probe failure + - iwlwifi: mvm: write queue_sync_state only for sync + - batman-adv: set .owner to THIS_MODULE + - arch: pgtable: define MAX_POSSIBLE_PHYSMEM_BITS where needed + - ARM: dts: dra76x: m_can: fix order of clocks + - scsi: ufs: Fix race between shutdown and runtime resume flow + - bnxt_en: fix error return code in bnxt_init_one() + - bnxt_en: fix error return code in bnxt_init_board() + - video: hyperv_fb: Fix the cache type when mapping the VRAM + - bnxt_en: Release PCI regions when DMA mask setup fails during probe. + - cxgb4: fix the panic caused by non smac rewrite + - s390/qeth: make af_iucv TX notification call more robust + - s390/qeth: fix af_iucv notification race + - s390/qeth: fix tear down of async TX buffers + - ibmvnic: fix call_netdevice_notifiers in do_reset + - ibmvnic: notify peers when failover and migration happen + - powerpc/64s: Fix allnoconfig build since uaccess flush + - IB/mthca: fix return value of error branch in mthca_init_cq() + - i40e: Fix removing driver while bare-metal VFs pass traffic + - nfc: s3fwrn5: use signed integer for parsing GPIO numbers + - net: ena: set initial DMA width to avoid intel iommu issue + - ibmvnic: fix NULL pointer dereference in reset_sub_crq_queues + - ibmvnic: fix NULL pointer dereference in ibmvic_reset_crq + - optee: add writeback to valid memory type + - arm64: tegra: Wrong AON HSP reg property size + - efivarfs: revert "fix memory leak in efivarfs_create()" + - efi: EFI_EARLYCON should depend on EFI + - can: gs_usb: fix endianess problem with candleLight firmware + - platform/x86: thinkpad_acpi: Send tablet mode switch at wakeup time + - platform/x86: toshiba_acpi: Fix the wrong variable assignment + - RDMA/hns: Fix retry_cnt and rnr_cnt when querying QP + - RDMA/hns: Bugfix for memory window mtpt configuration + - can: m_can: m_can_open(): remove IRQF_TRIGGER_FALLING from + request_threaded_irq()'s flags + - can: m_can: fix nominal bitiming tseg2 min for version >= 3.1 + - perf stat: Use proper cpu for shadow stats + - perf probe: Fix to die_entrypc() returns error correctly + - spi: bcm2835aux: Restore err assignment in bcm2835aux_spi_probe + - USB: core: Change %pK for __user pointers to %px + - usb: gadget: f_midi: Fix memleak in f_midi_alloc + - USB: quirks: Add USB_QUIRK_DISCONNECT_SUSPEND quirk for Lenovo A630Z TIO + built-in usb-audio card + - usb: gadget: Fix memleak in gadgetfs_fill_super + - irqchip/exiu: Fix the index of fwspec for IRQ type + - x86/mce: Do not overwrite no_way_out if mce_end() fails + - x86/speculation: Fix prctl() when spectre_v2_user={seccomp,prctl},ibpb + - x86/resctrl: Remove superfluous kernfs_get() calls to prevent refcount leak + - x86/resctrl: Add necessary kernfs_put() calls to prevent refcount leak + - USB: core: Fix regression in Hercules audio card + - ASoC: Intel: Skylake: Remove superfluous chip initialization + - ASoC: Intel: Skylake: Select hda configuration permissively + - ASoC: Intel: Skylake: Enable codec wakeup during chip init + - ASoC: Intel: Skylake: Shield against no-NHLT configurations + - ASoC: Intel: Allow for ROM init retry on CNL platforms + - ASoC: Intel: Skylake: Await purge request ack on CNL + - ASoC: Intel: Multiple I/O PCM format support for pipe + - ASoC: Intel: Skylake: Automatic DMIC format configuration according to + information from NHLT + - Linux 5.4.81 + * Focal update: v5.4.80 upstream stable release (LP: #1908561) + - ah6: fix error return code in ah6_input() + - atm: nicstar: Unmap DMA on send error + - bnxt_en: read EEPROM A2h address using page 0 + - devlink: Add missing genlmsg_cancel() in devlink_nl_sb_port_pool_fill() + - Exempt multicast addresses from five-second neighbor lifetime + - inet_diag: Fix error path to cancel the meseage in inet_req_diag_fill() + - ipv6: Fix error path to cancel the meseage + - lan743x: fix issue causing intermittent kernel log warnings + - lan743x: prevent entire kernel HANG on open, for some platforms + - mlxsw: core: Use variable timeout for EMAD retries + - net: b44: fix error return code in b44_init_one() + - net: bridge: add missing counters to ndo_get_stats64 callback + - net: dsa: mv88e6xxx: Avoid VTU corruption on 6097 + - net: ethernet: ti: cpsw: fix error return code in cpsw_probe() + - net: Have netpoll bring-up DSA management interface + - netlabel: fix our progress tracking in netlbl_unlabel_staticlist() + - netlabel: fix an uninitialized warning in netlbl_unlabel_staticlist() + - net: lantiq: Wait for the GPHY firmware to be ready + - net/mlx4_core: Fix init_hca fields offset + - net: qualcomm: rmnet: Fix incorrect receive packet handling during cleanup + - net/smc: fix direct access to ib_gid_addr->ndev in smc_ib_determine_gid() + - net/tls: fix corrupted data in recvmsg + - net: x25: Increase refcnt of "struct x25_neigh" in x25_rx_call_request + - page_frag: Recover from memory pressure + - qed: fix error return code in qed_iwarp_ll2_start() + - qlcnic: fix error return code in qlcnic_83xx_restart_hw() + - sctp: change to hold/put transport for proto_unreach_timer + - tcp: only postpone PROBE_RTT if RTT is < current min_rtt estimate + - net/mlx5: Add handling of port type in rule deletion + - net/mlx5: Disable QoS when min_rates on all VFs are zero + - net: usb: qmi_wwan: Set DTR quirk for MR400 + - net/ncsi: Fix netlink registration + - net: ftgmac100: Fix crash when removing driver + - pinctrl: rockchip: enable gpio pclk for rockchip_gpio_to_irq + - scsi: ufs: Fix unbalanced scsi_block_reqs_cnt caused by ufshcd_hold() + - selftests: kvm: Fix the segment descriptor layout to match the actual layout + - ACPI: button: Add DMI quirk for Medion Akoya E2228T + - arm64: errata: Fix handling of 1418040 with late CPU onlining + - arm64: psci: Avoid printing in cpu_psci_cpu_die() + - arm64: smp: Tell RCU about CPUs that fail to come online + - vfs: remove lockdep bogosity in __sb_start_write + - gfs2: fix possible reference leak in gfs2_check_blk_type + - hwmon: (pwm-fan) Fix RPM calculation + - arm64: dts: allwinner: beelink-gs1: Enable both RGMII RX/TX delay + - arm64: dts: allwinner: Pine H64: Enable both RGMII RX/TX delay + - arm64: dts: allwinner: a64: OrangePi Win: Fix ethernet node + - arm64: dts: allwinner: a64: Pine64 Plus: Fix ethernet node + - arm64: dts: allwinner: h5: OrangePi PC2: Fix ethernet node + - ARM: dts: sun8i: r40: bananapi-m2-ultra: Fix ethernet node + - Revert "arm: sun8i: orangepi-pc-plus: Set EMAC activity LEDs to active high" + - ARM: dts: sun6i: a31-hummingbird: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun7i: cubietruck: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun7i: bananapi-m1-plus: Enable RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun8i: h3: orangepi-plus2e: Enable RGMII RX/TX delay on Ethernet + PHY + - ARM: dts: sun8i: a83t: Enable both RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sun9i: Enable both RGMII RX/TX delay on Ethernet PHY + - ARM: dts: sunxi: bananapi-m2-plus: Enable RGMII RX/TX delay on Ethernet PHY + - arm64: dts: allwinner: a64: bananapi-m64: Enable RGMII RX/TX delay on PHY + - Input: adxl34x - clean up a data type in adxl34x_probe() + - MIPS: export has_transparent_hugepage() for modules + - arm64: dts: allwinner: h5: OrangePi Prime: Fix ethernet node + - arm64: dts imx8mn: Remove non-existent USB OTG2 + - arm: dts: imx6qdl-udoo: fix rgmii phy-mode for ksz9031 phy + - swiotlb: using SIZE_MAX needs limits.h included + - arm64: dts: imx8mm: fix voltage for 1.6GHz CPU operating point + - ARM: dts: imx50-evk: Fix the chip select 1 IOMUX + - Input: resistive-adc-touch - fix kconfig dependency on IIO_BUFFER + - rfkill: Fix use-after-free in rfkill_resume() + - RDMA/pvrdma: Fix missing kfree() in pvrdma_register_device() + - [Config] updateconfigs for INFINIBAND_VIRT_DMA + - RMDA/sw: Don't allow drivers using dma_virt_ops on highmem configs + - perf lock: Don't free "lock_seq_stat" if read_count isn't zero + - tools, bpftool: Add missing close before bpftool net attach exit + - ip_tunnels: Set tunnel option flag when tunnel metadata is present + - can: af_can: prevent potential access of uninitialized member in can_rcv() + - can: af_can: prevent potential access of uninitialized member in canfd_rcv() + - can: dev: can_restart(): post buffer from the right context + - can: ti_hecc: Fix memleak in ti_hecc_probe + - can: mcba_usb: mcba_usb_start_xmit(): first fill skb, then pass to + can_put_echo_skb() + - can: peak_usb: fix potential integer overflow on shift of a int + - can: flexcan: fix failure handling of pm_runtime_get_sync() + - can: tcan4x5x: replace depends on REGMAP_SPI with depends on SPI + - can: tcan4x5x: tcan4x5x_can_probe(): add missing error checking for + devm_regmap_init() + - can: tcan4x5x: tcan4x5x_can_remove(): fix order of deregistration + - can: m_can: m_can_handle_state_change(): fix state change + - can: m_can: m_can_class_free_dev(): introduce new function + - can: m_can: m_can_stop(): set device to software init mode before closing + - ASoC: qcom: lpass-platform: Fix memory leak + - selftests/bpf: Fix error return code in run_getsockopt_test() + - MIPS: Alchemy: Fix memleak in alchemy_clk_setup_cpu + - drm/sun4i: dw-hdmi: fix error return code in sun8i_dw_hdmi_bind() + - net/mlx5: E-Switch, Fail mlx5_esw_modify_vport_rate if qos disabled + - bpf, sockmap: Fix partial copy_page_to_iter so progress can still be made + - bpf, sockmap: Ensure SO_RCVBUF memory is observed on ingress redirect + - can: kvaser_pciefd: Fix KCAN bittiming limits + - can: kvaser_usb: kvaser_usb_hydra: Fix KCAN bittiming limits + - iommu/vt-d: Move intel_iommu_gfx_mapped to Intel IOMMU header + - iommu/vt-d: Avoid panic if iommu init fails in tboot system + - can: flexcan: flexcan_chip_start(): fix erroneous + flexcan_transceiver_enable() during bus-off recovery + - can: m_can: process interrupt only when not runtime suspended + - xfs: fix the minrecs logic when dealing with inode root child blocks + - xfs: strengthen rmap record flags checking + - xfs: return corresponding errcode if xfs_initialize_perag() fail + - regulator: ti-abb: Fix array out of bound read access on the first + transition + - fail_function: Remove a redundant mutex unlock + - xfs: revert "xfs: fix rmap key and record comparison functions" + - bpf, sockmap: Skb verdict SK_PASS to self already checked rmem limits + - bpf, sockmap: On receive programs try to fast track SK_PASS ingress + - bpf, sockmap: Use truesize with sk_rmem_schedule() + - bpf, sockmap: Avoid returning unneeded EAGAIN when redirecting to self + - efi/x86: Free efi_pgd with free_pages() + - libfs: fix error cast of negative value in simple_attr_write() + - HID: logitech-hidpp: Add PID for MX Anywhere 2 + - HID: logitech-dj: Handle quad/bluetooth keyboards with a builtin trackpad + - HID: logitech-dj: Fix Dinovo Mini when paired with a MX5x00 receiver + - speakup: Do not let the line discipline be used several times + - ALSA: firewire: Clean up a locking issue in copy_resp_to_buf() + - ALSA: usb-audio: Add delay quirk for all Logitech USB devices + - ALSA: ctl: fix error path at adding user-defined element set + - ALSA: mixart: Fix mutex deadlock + - ALSA: hda/realtek - Add supported for Lenovo ThinkPad Headset Button + - ALSA: hda/realtek: Add some Clove SSID in the ALC293(ALC1220) + - tty: serial: imx: fix potential deadlock + - tty: serial: imx: keep console clocks always on + - HID: logitech-dj: Fix an error in mse_bluetooth_descriptor + - efivarfs: fix memory leak in efivarfs_create() + - staging: rtl8723bs: Add 024c:0627 to the list of SDIO device-ids + - iio: light: fix kconfig dependency bug for VCNL4035 + - ext4: fix bogus warning in ext4_update_dx_flag() + - iio: accel: kxcjk1013: Replace is_smo8500_device with an acpi_type enum + - iio: accel: kxcjk1013: Add support for KIOX010A ACPI DSM for setting tablet- + mode + - iio: adc: mediatek: fix unset field + - spi: lpspi: Fix use-after-free on unbind + - spi: Introduce device-managed SPI controller allocation + - spi: npcm-fiu: Don't leak SPI master in probe error path + - spi: bcm2835aux: Fix use-after-free on unbind + - regulator: pfuze100: limit pfuze-support-disable-sw to pfuze{100,200} + - regulator: fix memory leak with repeated set_machine_constraints() + - regulator: avoid resolve_supply() infinite recursion + - regulator: workaround self-referent regulators + - xtensa: fix TLBTEMP area placement + - xtensa: disable preemption around cache alias management calls + - mac80211: minstrel: remove deferred sampling code + - mac80211: minstrel: fix tx status processing corner case + - mac80211: free sta in sta_info_insert_finish() on errors + - s390/cpum_sf.c: fix file permission for cpum_sfb_size + - s390/dasd: fix null pointer dereference for ERP requests + - Drivers: hv: vmbus: Allow cleanup of VMBUS_CONNECT_CPU if disconnected + - drm/amd/display: Add missing pflip irq for dcn2.0 + - drm/i915: Handle max_bpc==16 + - mmc: sdhci-pci: Prefer SDR25 timing for High Speed mode for BYT-based Intel + controllers + - ptrace: Set PF_SUPERPRIV when checking capability + - seccomp: Set PF_SUPERPRIV when checking capability + - x86/microcode/intel: Check patch signature before saving microcode for early + loading + - mm: memcg/slab: fix root memcg vmstats + - mm/userfaultfd: do not access vma->vm_mm after calling handle_userfault() + - mm, page_alloc: skip ->waternark_boost for atomic order-0 allocations + - sched/fair: Fix overutilized update in enqueue_task_fair() + - Linux 5.4.80 + * [SRU][F/G/H/U/OEM-5.6] Fix i2c report error on elan trackpoint + (LP: #1908335) + - Input: elan_i2c - add support for high resolution reports + - Input: elan_i2c - add new trackpoint report type 0x5F + - Input: elantech - fix protocol errors for some trackpoints in SMBus mode + * rtwpci driver blocks the system to enter PC10, stuck at PC3 (LP: #1907200) + - SAUCE: rtw88: 8723de: let cpu enter c10 + * [UBUNTU 21.04] s390/pci: vfio-pci mmio being disabled erroneously + (LP: #1907265) + - s390/pci: Mark all VFs as not implementing PCI_COMMAND_MEMORY + * Touchpad not detected on ByteSpeed C15B laptop (LP: #1906128) + - Input: i8042 - add ByteSpeed touchpad to noloop table + * Fix reading speed and duplex sysfs on igc device (LP: #1906851) + - SAUCE: igc: Report speed and duplex as unknown when device is runtime + suspended + * stack trace in kernel (LP: #1903596) + - net: napi: remove useless stack trace + * Refresh ACPI wakeup power to make Thunderbolt hotplug detection work + (LP: #1906229) + - PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup() + - PM: ACPI: Refresh wakeup device power configuration every time + * CVE-2020-27777 + - [Config]: Set CONFIG_PPC_RTAS_FILTER + * Add dpcd backlight control for 0x4c83 0x4f41 (LP: #1905663) + - SAUCE: drm/dp: Add dpcd backlight control for 0x4c83 0x4f41 + * Focal update: v5.4.79 upstream stable release (LP: #1907151) + - powerpc: Only include kup-radix.h for 64-bit Book3S + - MIPS: PCI: Fix MIPS build + - powerpc/8xx: Always fault when _PAGE_ACCESSED is not set + - net: lantiq: Add locking for TX DMA channel + - Input: sunkbd - avoid use-after-free in teardown paths + - mac80211: always wind down STA state + - can: proc: can_remove_proc(): silence remove_proc_entry warning + - KVM: x86: clflushopt should be treated as a no-op by emulation + - ACPI: GED: fix -Wformat + - Linux 5.4.79 + + [ Ubuntu: 5.4.0-65.73 ] + + * focal/linux: 5.4.0-65.73 -proposed tracker (LP: #1912220) + * initramfs unpacking failed (LP: #1835660) + - SAUCE: lib/decompress_unlz4.c: correctly handle zero-padding around initrds. + + [ Ubuntu: 5.4.0-64.72 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Fri, 05 Feb 2021 15:35:18 +0100 + +linux-oracle (5.4.0-1037.40) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1037.40 -proposed tracker (LP: #1911328) + + [ Ubuntu: 5.4.0-63.71 ] + + * focal/linux: 5.4.0-63.71 -proposed tracker (LP: #1911333) + * overlay: permission regression in 5.4.0-51.56 due to patches related to + CVE-2020-16120 (LP: #1900141) + - ovl: do not fail because of O_NOATIME + * Focal update: v5.4.79 upstream stable release (LP: #1907151) + - net/mlx5: Use async EQ setup cleanup helpers for multiple EQs + - net/mlx5: poll cmd EQ in case of command timeout + - net/mlx5: Fix a race when moving command interface to events mode + - net/mlx5: Add retry mechanism to the command entry index allocation + * Kernel 5.4.0-56 Wi-Fi does not connect (LP: #1906770) + - mt76: fix fix ampdu locking + * [Ubuntu 21.04 FEAT] mpt3sas: Request to include the patch set which supports + topology where zoning is enabled in expander (LP: #1899802) + - scsi: mpt3sas: Define hba_port structure + - scsi: mpt3sas: Allocate memory for hba_port objects + - scsi: mpt3sas: Rearrange _scsih_mark_responding_sas_device() + - scsi: mpt3sas: Update hba_port's sas_address & phy_mask + - scsi: mpt3sas: Get device objects using sas_address & portID + - scsi: mpt3sas: Rename transport_del_phy_from_an_existing_port() + - scsi: mpt3sas: Get sas_device objects using device's rphy + - scsi: mpt3sas: Update hba_port objects after host reset + - scsi: mpt3sas: Set valid PhysicalPort in SMPPassThrough + - scsi: mpt3sas: Handling HBA vSES device + - scsi: mpt3sas: Add bypass_dirty_port_flag parameter + - scsi: mpt3sas: Handle vSES vphy object during HBA reset + - scsi: mpt3sas: Add module parameter multipath_on_hba + - scsi: mpt3sas: Bump driver version to 35.101.00.00 + + [ Ubuntu: 5.4.0-62.70 ] + + * focal/linux: 5.4.0-62.70 -proposed tracker (LP: #1911144) + * CVE-2020-28374 + - SAUCE: target: fix XCOPY NAA identifier lookup + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- William Breathitt Gray Thu, 14 Jan 2021 03:13:44 -0500 + +linux-oracle (5.4.0-1035.38) focal; urgency=medium + + [ Ubuntu: 5.4.0-60.67 ] + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - update dkms package versions + * CVE-2021-1052 // CVE-2021-1053 + - [Packaging] NVIDIA -- Add the NVIDIA 460 driver + + -- Thadeu Lima de Souza Cascardo Wed, 06 Jan 2021 16:30:54 -0300 + +linux-oracle (5.4.0-1034.36) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1033.35 -proposed tracker (LP: #1907600) + + [ Ubuntu: 5.4.0-59.65 ] + + * focal/linux: 5.4.0-59.65 -proposed tracker (LP: #1907604) + * focal: selftests/bpf build broken: test_map_init.skel.h: No such file or + directory (LP: #1906866) + - SAUCE: Revert selftests/ "bpf: Zero-fill re-used per-cpu map element" + * Packaging resync (LP: #1786013) + - update dkms package versions + * memory is leaked when tasks are moved to net_prio (LP: #1886859) + - netprio_cgroup: Fix unlimited memory leak of v2 cgroups + * Focal update: v5.4.78 upstream stable release (LP: #1905618) + - drm/i915/gem: Flush coherency domains on first set-domain-ioctl + - time: Prevent undefined behaviour in timespec64_to_ns() + - nbd: don't update block size after device is started + - KVM: arm64: Force PTE mapping on fault resulting in a device mapping + - PCI: qcom: Make sure PCIe is reset before init for rev 2.1.0 + - usb: dwc3: gadget: Continue to process pending requests + - usb: dwc3: gadget: Reclaim extra TRBs after request completion + - btrfs: tracepoints: output proper root owner for trace_find_free_extent() + - btrfs: sysfs: init devices outside of the chunk_mutex + - btrfs: reschedule when cloning lots of extents + - ASoC: Intel: kbl_rt5663_max98927: Fix kabylake_ssp_fixup function + - genirq: Let GENERIC_IRQ_IPI select IRQ_DOMAIN_HIERARCHY + - hv_balloon: disable warning when floor reached + - net: xfrm: fix a race condition during allocing spi + - ASoC: codecs: wcd9335: Set digital gain range correctly + - xfs: set xefi_discard when creating a deferred agfl free log intent item + - netfilter: use actual socket sk rather than skb sk when routing harder + - netfilter: nf_tables: missing validation from the abort path + - netfilter: ipset: Update byte and packet counters regardless of whether they + match + - powerpc/eeh_cache: Fix a possible debugfs deadlock + - perf trace: Fix segfault when trying to trace events by cgroup + - perf tools: Add missing swap for ino_generation + - ALSA: hda: prevent undefined shift in snd_hdac_ext_bus_get_link() + - iommu/vt-d: Fix a bug for PDP check in prq_event_thread + - afs: Fix warning due to unadvanced marshalling pointer + - can: rx-offload: don't call kfree_skb() from IRQ context + - can: dev: can_get_echo_skb(): prevent call to kfree_skb() in hard IRQ + context + - can: dev: __can_get_echo_skb(): fix real payload length return value for RTR + frames + - can: can_create_echo_skb(): fix echo skb generation: always use skb_clone() + - can: j1939: swap addr and pgn in the send example + - can: j1939: j1939_sk_bind(): return failure if netdev is down + - can: ti_hecc: ti_hecc_probe(): add missed clk_disable_unprepare() in error + path + - can: xilinx_can: handle failure cases of pm_runtime_get_sync + - can: peak_usb: add range checking in decode operations + - can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping + - can: peak_canfd: pucan_handle_can_rx(): fix echo management when loopback is + on + - can: flexcan: remove FLEXCAN_QUIRK_DISABLE_MECR quirk for LS1021A + - can: flexcan: flexcan_remove(): disable wakeup completely + - xfs: flush new eof page on truncate to avoid post-eof corruption + - xfs: fix scrub flagging rtinherit even if there is no rt device + - tpm: efi: Don't create binary_bios_measurements file for an empty log + - random32: make prandom_u32() output unpredictable + - KVM: arm64: ARM_SMCCC_ARCH_WORKAROUND_1 doesn't return + SMCCC_RET_NOT_REQUIRED + - KVM: x86: don't expose MSR_IA32_UMWAIT_CONTROL unconditionally + - ath9k_htc: Use appropriate rs_datalen type + - ASoC: qcom: sdm845: set driver name correctly + - ASoC: cs42l51: manage mclk shutdown delay + - usb: dwc3: pci: add support for the Intel Alder Lake-S + - opp: Reduce the size of critical section in _opp_table_kref_release() + - usb: gadget: goku_udc: fix potential crashes in probe + - selftests/ftrace: check for do_sys_openat2 in user-memory test + - selftests: pidfd: fix compilation errors due to wait.h + - ALSA: hda: Separate runtime and system suspend + - ALSA: hda: Reinstate runtime_allow() for all hda controllers + - gfs2: Free rd_bits later in gfs2_clear_rgrpd to fix use-after-free + - gfs2: Add missing truncate_inode_pages_final for sd_aspace + - gfs2: check for live vs. read-only file system in gfs2_fitrim + - scsi: hpsa: Fix memory leak in hpsa_init_one() + - drm/amdgpu: perform srbm soft reset always on SDMA resume + - drm/amd/pm: perform SMC reset on suspend/hibernation + - drm/amd/pm: do not use ixFEATURE_STATUS for checking smc running + - mac80211: fix use of skb payload instead of header + - cfg80211: initialize wdev data earlier + - cfg80211: regulatory: Fix inconsistent format argument + - tracing: Fix the checking of stackidx in __ftrace_trace_stack + - scsi: scsi_dh_alua: Avoid crash during alua_bus_detach() + - scsi: mpt3sas: Fix timeouts observed while reenabling IRQ + - nvme: introduce nvme_sync_io_queues + - nvme-rdma: avoid race between time out and tear down + - nvme-tcp: avoid race between time out and tear down + - nvme-rdma: avoid repeated request completion + - nvme-tcp: avoid repeated request completion + - iommu/amd: Increase interrupt remapping table limit to 512 entries + - s390/smp: move rcu_cpu_starting() earlier + - vfio: platform: fix reference leak in vfio_platform_open + - vfio/pci: Bypass IGD init in case of -ENODEV + - i2c: mediatek: move dma reset before i2c reset + - amd/amdgpu: Disable VCN DPG mode for Picasso + - selftests: proc: fix warning: _GNU_SOURCE redefined + - riscv: Set text_offset correctly for M-Mode + - i2c: sh_mobile: implement atomic transfers + - tpm_tis: Disable interrupts on ThinkPad T490s + - spi: bcm2835: remove use of uninitialized gpio flags variable + - tick/common: Touch watchdog in tick_unfreeze() on all CPUs + - mfd: sprd: Add wakeup capability for PMIC IRQ + - pinctrl: intel: Set default bias in case no particular value given + - ARM: 9019/1: kprobes: Avoid fortify_panic() when copying optprobe template + - bpf: Don't rely on GCC __attribute__((optimize)) to disable GCSE + - pinctrl: aspeed: Fix GPI only function problem. + - net/mlx5: Fix deletion of duplicate rules + - SUNRPC: Fix general protection fault in trace_rpc_xdr_overflow() + - bpf: Zero-fill re-used per-cpu map element + - nbd: fix a block_device refcount leak in nbd_release + - igc: Fix returning wrong statistics + - xfs: fix flags argument to rmap lookup when converting shared file rmaps + - xfs: set the unwritten bit in rmap lookup flags in xchk_bmap_get_rmapextents + - xfs: fix rmap key and record comparison functions + - xfs: fix brainos in the refcount scrubber's rmap fragment processor + - lan743x: fix "BUG: invalid wait context" when setting rx mode + - xfs: fix a missing unlock on error in xfs_fs_map_blocks + - of/address: Fix of_node memory leak in of_dma_is_coherent + - cosa: Add missing kfree in error path of cosa_write + - vrf: Fix fast path output packet handling with async Netfilter rules + - perf: Fix get_recursion_context() + - erofs: derive atime instead of leaving it empty + - ext4: correctly report "not supported" for {usr,grp}jquota when + !CONFIG_QUOTA + - ext4: unlock xattr_sem properly in ext4_inline_data_truncate() + - btrfs: ref-verify: fix memory leak in btrfs_ref_tree_mod + - btrfs: fix min reserved size calculation in merge_reloc_root + - btrfs: dev-replace: fail mount if we don't have replace item with target + device + - KVM: arm64: Don't hide ID registers from userspace + - thunderbolt: Fix memory leak if ida_simple_get() fails in + enumerate_services() + - thunderbolt: Add the missed ida_simple_remove() in ring_request_msix() + - uio: Fix use-after-free in uio_unregister_device() + - usb: cdc-acm: Add DISABLE_ECHO for Renesas USB Download mode + - xhci: hisilicon: fix refercence leak in xhci_histb_probe + - virtio: virtio_console: fix DMA memory allocation for rproc serial + - mei: protect mei_cl_mtu from null dereference + - futex: Don't enable IRQs unconditionally in put_pi_state() + - jbd2: fix up sparse warnings in checkpoint code + - mm/slub: fix panic in slab_alloc_node() + - Revert "kernel/reboot.c: convert simple_strtoul to kstrtoint" + - reboot: fix overflow parsing reboot cpu number + - ocfs2: initialize ip_next_orphan + - btrfs: fix potential overflow in cluster_pages_for_defrag on 32bit arch + - selinux: Fix error return code in sel_ib_pkey_sid_slow() + - gpio: pcie-idio-24: Fix irq mask when masking + - gpio: pcie-idio-24: Fix IRQ Enable Register value + - gpio: pcie-idio-24: Enable PEX8311 interrupts + - mmc: sdhci-of-esdhc: Handle pulse width detection erratum for more SoCs + - mmc: renesas_sdhi_core: Add missing tmio_mmc_host_free() at remove + - don't dump the threads that had been already exiting when zapped. + - drm/gma500: Fix out-of-bounds access to struct drm_device.vblank[] + - pinctrl: amd: use higher precision for 512 RtcClk + - pinctrl: amd: fix incorrect way to disable debounce filter + - swiotlb: fix "x86: Don't panic if can not alloc buffer for swiotlb" + - IPv6: Set SIT tunnel hard_header_len to zero + - net/af_iucv: fix null pointer dereference on shutdown + - net: udp: fix UDP header access on Fast/frag0 UDP GRO + - net: Update window_clamp if SOCK_RCVBUF is set + - net/x25: Fix null-ptr-deref in x25_connect + - tipc: fix memory leak in tipc_topsrv_start() + - r8169: fix potential skb double free in an error path + - drm/i915: Correctly set SFC capability for video engines + - powerpc/603: Always fault when _PAGE_ACCESSED is not set + - x86/speculation: Allow IBPB to be conditionally enabled on CPUs with always- + on STIBP + - perf scripting python: Avoid declaring function pointers with a visibility + attribute + - net: sch_generic: fix the missing new qdisc assignment bug + - Convert trailing spaces and periods in path components + - Linux 5.4.78 + * Focal update: v5.4.77 upstream stable release (LP: #1905614) + - Linux 5.4.77 + * Focal update: v5.4.76 upstream stable release (LP: #1905612) + - drm/i915: Break up error capture compression loops with cond_resched() + - drm/i915/gt: Delay execlist processing for tgl + - drm/i915: Drop runtime-pm assert from vgpu io accessors + - ASoC: Intel: Skylake: Add alternative topology binary name + - update dkms package versions + - linkage: Introduce new macros for assembler symbols + - arm64: asm: Add new-style position independent function annotations + - arm64: lib: Use modern annotations for assembly functions + - arm64: Change .weak to SYM_FUNC_START_WEAK_PI for arch/arm64/lib/mem*.S + - tipc: fix use-after-free in tipc_bcast_get_mode + - ptrace: fix task_join_group_stop() for the case when current is traced + - cadence: force nonlinear buffers to be cloned + - chelsio/chtls: fix memory leaks caused by a race + - chelsio/chtls: fix always leaking ctrl_skb + - gianfar: Replace skb_realloc_headroom with skb_cow_head for PTP + - gianfar: Account for Tx PTP timestamp in the skb headroom + - ionic: check port ptr before use + - ip_tunnel: fix over-mtu packet send fail without TUNNEL_DONT_FRAGMENT flags + - net: usb: qmi_wwan: add Telit LE910Cx 0x1230 composition + - powerpc/vnic: Extend "failover pending" window + - sctp: Fix COMM_LOST/CANT_STR_ASSOC err reporting on big-endian platforms + - sfp: Fix error handing in sfp_probe() + - Fonts: Replace discarded const qualifier + - ALSA: hda/realtek - Fixed HP headset Mic can't be detected + - ALSA: hda/realtek - Enable headphone for ASUS TM420 + - ALSA: usb-audio: Add implicit feedback quirk for Zoom UAC-2 + - ALSA: usb-audio: add usb vendor id as DSD-capable for Khadas devices + - ALSA: usb-audio: Add implicit feedback quirk for Qu-16 + - ALSA: usb-audio: Add implicit feedback quirk for MODX + - mm: mempolicy: fix potential pte_unmap_unlock pte error + - lib/crc32test: remove extra local_irq_disable/enable + - kthread_worker: prevent queuing delayed work from timer_fn when it is being + canceled + - mm: always have io_remap_pfn_range() set pgprot_decrypted() + - gfs2: Wake up when sd_glock_disposal becomes zero + - ring-buffer: Fix recursion protection transitions between interrupt context + - mtd: spi-nor: Don't copy self-pointing struct around + - ftrace: Fix recursion check for NMI test + - ftrace: Handle tracing when switching between context + - regulator: defer probe when trying to get voltage from unresolved supply + - spi: bcm2835: fix gpio cs level inversion + - tracing: Fix out of bounds write in get_trace_buf + - futex: Handle transient "ownerless" rtmutex state correctly + - ARM: dts: sun4i-a10: fix cpu_alert temperature + - arm64: dts: meson: add missing g12 rng clock + - x86/kexec: Use up-to-dated screen_info copy to fill boot params + - of: Fix reserved-memory overlap detection + - drm/sun4i: frontend: Rework a bit the phase data + - drm/sun4i: frontend: Reuse the ch0 phase for RGB formats + - drm/sun4i: frontend: Fix the scaler phase on A33 + - blk-cgroup: Fix memleak on error path + - blk-cgroup: Pre-allocate tree node on blkg_conf_prep + - scsi: core: Don't start concurrent async scan on same host + - drm/amdgpu: add DID for navi10 blockchain SKU + - scsi: ibmvscsi: Fix potential race after loss of transport + - vsock: use ns_capable_noaudit() on socket create + - nvme-rdma: handle unexpected nvme completion data length + - nvmet: fix a NULL pointer dereference when tracing the flush command + - drm/vc4: drv: Add error handding for bind + - ACPI: NFIT: Fix comparison to '-ENXIO' + - usb: cdns3: gadget: suspicious implicit sign extension + - drm/nouveau/nouveau: fix the start/end range for migration + - drm/nouveau/gem: fix "refcount_t: underflow; use-after-free" + - arm64/smp: Move rcu_cpu_starting() earlier + - vt: Disable KD_FONT_OP_COPY + - fork: fix copy_process(CLONE_PARENT) race with the exiting ->real_parent + - s390/pkey: fix paes selftest failure with paes and pkey static build + - serial: 8250_mtk: Fix uart_get_baud_rate warning + - serial: txx9: add missing platform_driver_unregister() on error in + serial_txx9_init + - USB: serial: cyberjack: fix write-URB completion race + - USB: serial: option: add Quectel EC200T module support + - USB: serial: option: add LE910Cx compositions 0x1203, 0x1230, 0x1231 + - USB: serial: option: add Telit FN980 composition 0x1055 + - tty: serial: fsl_lpuart: add LS1028A support + - tty: serial: fsl_lpuart: LS1021A has a FIFO size of 16 words, like LS1028A + - usb: dwc3: ep0: Fix delay status handling + - USB: Add NO_LPM quirk for Kingston flash drive + - usb: mtu3: fix panic in mtu3_gadget_stop() + - drm/panfrost: Fix a deadlock between the shrinker and madvise path + - ARC: stack unwinding: avoid indefinite looping + - PM: runtime: Drop runtime PM references to supplier on link removal + - PM: runtime: Drop pm_runtime_clean_up_links() + - PM: runtime: Resume the device earlier in __device_release_driver() + - xfs: flush for older, xfs specific ioctls + - perf/core: Fix a memory leak in perf_event_parse_addr_filter() + - arm64: dts: marvell: espressobin: Add ethernet switch aliases + - Linux 5.4.76 + * s390: dbginfo.sh triggers kernel panic, reading from + /sys/kernel/mm/page_idle/bitmap (LP: #1904884) + - mm/page_idle.c: skip offline pages + * Ask 8821C Bluetooth controller to drop old firmware (LP: #1904221) + - Bluetooth: btrtl: Ask 8821C to drop old firmware + - Bluetooth: btrtl: fix incorrect skb allocation failure check + * Use ACPI S5 for reboot (LP: #1904225) + - PM: ACPI: reboot: Use S5 for reboot + * Focal update: v5.4.75 upstream stable release (LP: #1904450) + - xen/events: avoid removing an event channel while handling it + - xen/events: add a proper barrier to 2-level uevent unmasking + - xen/events: fix race in evtchn_fifo_unmask() + - xen/events: add a new "late EOI" evtchn framework + - xen/blkback: use lateeoi irq binding + - xen/netback: use lateeoi irq binding + - xen/scsiback: use lateeoi irq binding + - xen/pvcallsback: use lateeoi irq binding + - xen/pciback: use lateeoi irq binding + - xen/events: switch user event channels to lateeoi model + - xen/events: use a common cpu hotplug hook for event channels + - xen/events: defer eoi in case of excessive number of events + - xen/events: block rogue events for some time + - firmware: arm_scmi: Fix ARCH_COLD_RESET + - firmware: arm_scmi: Add missing Rx size re-initialisation + - x86/unwind/orc: Fix inactive tasks with stack pointer in %sp on GCC 10 + compiled kernels + - mlxsw: core: Fix use-after-free in mlxsw_emad_trans_finish() + - RDMA/qedr: Fix memory leak in iWARP CM + - ata: sata_nv: Fix retrieving of active qcs + - futex: Fix incorrect should_fail_futex() handling + - powerpc/powernv/smp: Fix spurious DBG() warning + - [Config] update config for ARCH_WANT_IRQS_OFF_ACTIVATE_MM + - mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race + - powerpc: select ARCH_WANT_IRQS_OFF_ACTIVATE_MM + - sparc64: remove mm_cpumask clearing to fix kthread_use_mm race + - f2fs: add trace exit in exception path + - f2fs: fix uninit-value in f2fs_lookup + - f2fs: fix to check segment boundary during SIT page readahead + - s390/startup: avoid save_area_sync overflow + - um: change sigio_spinlock to a mutex + - f2fs: handle errors of f2fs_get_meta_page_nofail + - ARM: 8997/2: hw_breakpoint: Handle inexact watchpoint addresses + - NFS4: Fix oops when copy_file_range is attempted with NFS4.0 source + - power: supply: bq27xxx: report "not charging" on all types + - xfs: fix realtime bitmap/summary file truncation when growing rt volume + - video: fbdev: pvr2fb: initialize variables + - ath10k: start recovery process when payload length exceeds max htc length + for sdio + - ath10k: fix VHT NSS calculation when STBC is enabled + - drm/brige/megachips: Add checking if ge_b850v3_lvds_init() is working + correctly + - selftests/x86/fsgsbase: Reap a forgotten child + - media: videodev2.h: RGB BT2020 and HSV are always full range + - media: platform: Improve queue set up flow for bug fixing + - usb: typec: tcpm: During PR_SWAP, source caps should be sent only after + tSwapSourceStart + - media: tw5864: check status of tw5864_frameinterval_get + - media: imx274: fix frame interval handling + - mmc: via-sdmmc: Fix data race bug + - drm/bridge/synopsys: dsi: add support for non-continuous HS clock + - arm64: topology: Stop using MPIDR for topology information + - printk: reduce LOG_BUF_SHIFT range for H8300 + - ia64: kprobes: Use generic kretprobe trampoline handler + - kgdb: Make "kgdbcon" work properly with "kgdb_earlycon" + - bpf: Permit map_ptr arithmetic with opcode add and offset 0 + - media: uvcvideo: Fix dereference of out-of-bound list iterator + - selftests/bpf: Define string const as global for test_sysctl_prog.c + - samples/bpf: Fix possible deadlock in xdpsock + - riscv: Define AT_VECTOR_SIZE_ARCH for ARCH_DLINFO + - cpufreq: sti-cpufreq: add stih418 support + - USB: adutux: fix debugging + - uio: free uio id after uio file node is freed + - usb: xhci: omit duplicate actions when suspending a runtime suspended host. + - SUNRPC: Mitigate cond_resched() in xprt_transmit() + - arm64/mm: return cpu_all_mask when node is NUMA_NO_NODE + - can: flexcan: disable clocks during stop mode + - xfs: don't free rt blocks when we're doing a REMAP bunmapi call + - ACPI: Add out of bounds and numa_off protections to pxm_to_node() + - brcmfmac: Fix warning message after dongle setup failed + - drivers/net/wan/hdlc_fr: Correctly handle special skb->protocol values + - bus/fsl_mc: Do not rely on caller to provide non NULL mc_io + - ACPI: HMAT: Fix handling of changes from ACPI 6.2 to ACPI 6.3 + - power: supply: test_power: add missing newlines when printing parameters by + sysfs + - drm/amd/display: HDMI remote sink need mode validation for Linux + - ARC: [dts] fix the errors detected by dtbs_check + - btrfs: fix replace of seed device + - md/bitmap: md_bitmap_get_counter returns wrong blocks + - bnxt_en: Log unknown link speed appropriately. + - rpmsg: glink: Use complete_all for open states + - clk: ti: clockdomain: fix static checker warning + - net: 9p: initialize sun_server.sun_path to have addr's value only when addr + is valid + - drivers: watchdog: rdc321x_wdt: Fix race condition bugs + - ext4: Detect already used quota file early + - KVM: PPC: Book3S HV: Do not allocate HPT for a nested guest + - gfs2: use-after-free in sysfs deregistration + - gfs2: add validation checks for size of superblock + - cifs: handle -EINTR in cifs_setattr + - arm64: dts: renesas: ulcb: add full-pwr-cycle-in-suspend into eMMC nodes + - ARM: dts: omap4: Fix sgx clock rate for 4430 + - memory: emif: Remove bogus debugfs error handling + - ARM: dts: s5pv210: remove DMA controller bus node name to fix dtschema + warnings + - ARM: dts: s5pv210: move fixed clocks under root node + - ARM: dts: s5pv210: move PMU node out of clock controller + - ARM: dts: s5pv210: remove dedicated 'audio-subsystem' node + - nbd: make the config put is called before the notifying the waiter + - sgl_alloc_order: fix memory leak + - nvme-rdma: fix crash when connect rejected + - md/raid5: fix oops during stripe resizing + - mmc: sdhci: Add LTR support for some Intel BYT based controllers + - mmc: sdhci-acpi: AMDI0040: Set SDHCI_QUIRK2_PRESET_VALUE_BROKEN + - seccomp: Make duplicate listener detection non-racy + - selftests/x86/fsgsbase: Test PTRACE_PEEKUSER for GSBASE with invalid LDT GS + - perf/x86/intel: Fix Ice Lake event constraint table + - perf/x86/amd/ibs: Don't include randomized bits in get_ibs_op_count() + - perf/x86/amd/ibs: Fix raw sample data accumulation + - spi: sprd: Release DMA channel also on probe deferral + - extcon: ptn5150: Fix usage of atomic GPIO with sleeping GPIO chips + - leds: bcm6328, bcm6358: use devres LED registering function + - media: uvcvideo: Fix uvc_ctrl_fixup_xu_info() not having any effect + - fs: Don't invalidate page buffers in block_write_full_page() + - NFS: fix nfs_path in case of a rename retry + - ACPI: button: fix handling lid state changes when input device closed + - ACPI / extlog: Check for RDMSR failure + - ACPI: debug: don't allow debugging when ACPI is disabled + - PCI/ACPI: Whitelist hotplug ports for D3 if power managed by ACPI + - ACPI: EC: PM: Flush EC work unconditionally after wakeup + - ACPI: EC: PM: Drop ec_no_wakeup check from acpi_ec_dispatch_gpe() + - acpi-cpufreq: Honor _PSD table setting on new AMD CPUs + - w1: mxc_w1: Fix timeout resolution problem leading to bus error + - scsi: mptfusion: Fix null pointer dereferences in mptscsih_remove() + - scsi: qla2xxx: Fix crash on session cleanup with unload + - PM: runtime: Remove link state checks in rpm_get/put_supplier() + - btrfs: qgroup: fix wrong qgroup metadata reserve for delayed inode + - btrfs: improve device scanning messages + - btrfs: reschedule if necessary when logging directory items + - btrfs: send, orphanize first all conflicting inodes when processing + references + - btrfs: send, recompute reference path after orphanization of a directory + - btrfs: use kvzalloc() to allocate clone_roots in btrfs_ioctl_send() + - btrfs: tree-checker: fix false alert caused by legacy btrfs root item + - btrfs: cleanup cow block on error + - btrfs: tree-checker: validate number of chunk stripes and parity + - btrfs: fix use-after-free on readahead extent after failure to create it + - btrfs: fix readahead hang and use-after-free after removing a device + - Revert "UBUNTU: SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC" + - usb: xhci: Workaround for S3 issue on AMD SNPS 3.0 xHC + - usb: dwc3: pci: Allow Elkhart Lake to utilize DSM method for PM + functionality + - usb: dwc3: ep0: Fix ZLP for OUT ep0 requests + - usb: dwc3: gadget: Check MPS of the request length + - usb: dwc3: core: add phy cleanup for probe error handling + - usb: dwc3: core: don't trigger runtime pm when remove driver + - usb: dwc3: gadget: Resume pending requests after CLEAR_STALL + - usb: dwc3: gadget: END_TRANSFER before CLEAR_STALL command + - usb: cdc-acm: fix cooldown mechanism + - usb: typec: tcpm: reset hard_reset_count for any disconnect + - usb: host: fsl-mph-dr-of: check return of dma_set_mask() + - drm/i915: Force VT'd workarounds when running as a guest OS + - vt: keyboard, simplify vt_kdgkbsent + - vt: keyboard, extend func_buf_lock to readers + - HID: wacom: Avoid entering wacom_wac_pen_report for pad / battery + - udf: Fix memory leak when mounting + - dmaengine: dma-jz4780: Fix race in jz4780_dma_tx_status + - iio:light:si1145: Fix timestamp alignment and prevent data leak. + - iio: adc: gyroadc: fix leak of device node iterator + - iio:adc:ti-adc0832 Fix alignment issue with timestamp + - iio:adc:ti-adc12138 Fix alignment issue with timestamp + - iio:gyro:itg3200: Fix timestamp alignment and prevent data leak. + - powerpc/drmem: Make lmb_size 64 bit + - MIPS: DEC: Restore bootmem reservation for firmware working memory area + - s390/stp: add locking to sysfs functions + - [Config] update config for PPC_RTAS_FILTER + - powerpc/rtas: Restrict RTAS requests from userspace + - powerpc: Warn about use of smt_snooze_delay + - powerpc/memhotplug: Make lmb size 64bit + - powerpc/powernv/elog: Fix race while processing OPAL error log event. + - powerpc/powermac: Fix low_sleep_handler with KUAP and KUEP + - NFSv4: Wait for stateid updates after CLOSE/OPEN_DOWNGRADE + - NFSv4.2: support EXCHGID4_FLAG_SUPP_FENCE_OPS 4.2 EXCHANGE_ID flag + - NFSD: Add missing NFSv2 .pc_func methods + - ubifs: dent: Fix some potential memory leaks while iterating entries + - ubifs: xattr: Fix some potential memory leaks while iterating entries + - ubifs: journal: Make sure to not dirty twice for auth nodes + - ubifs: Fix a memleak after dumping authentication mount options + - ubifs: Don't parse authentication mount options in remount process + - ubifs: mount_ubifs: Release authentication resource in error handling path + - perf python scripting: Fix printable strings in python3 scripts + - ARC: perf: redo the pct irq missing in device-tree handling + - ubi: check kthread_should_stop() after the setting of task state + - ia64: fix build error with !COREDUMP + - rtc: rx8010: don't modify the global rtc ops + - i2c: imx: Fix external abort on interrupt in exit paths + - drm/amdgpu: don't map BO in reserved region + - drm/amd/display: Increase timeout for DP Disable + - drm/amdgpu: correct the gpu reset handling for job != NULL case + - drm/amdkfd: Use same SQ prefetch setting as amdgpu + - drm/amd/display: Avoid MST manager resource leak. + - drm/amdgpu: increase the reserved VM size to 2MB + - drm/amd/display: Don't invoke kgdb_breakpoint() unconditionally + - drm/amd/display: Fix kernel panic by dal_gpio_open() error + - ceph: promote to unsigned long long before shifting + - libceph: clear con->out_msg on Policy::stateful_server faults + - 9P: Cast to loff_t before multiplying + - ring-buffer: Return 0 on success from ring_buffer_resize() + - vringh: fix __vringh_iov() when riov and wiov are different + - ext4: fix leaking sysfs kobject after failed mount + - ext4: fix error handling code in add_new_gdb + - ext4: fix invalid inode checksum + - drm/ttm: fix eviction valuable range check. + - mmc: sdhci-of-esdhc: set timeout to max before tuning + - mmc: sdhci: Use Auto CMD Auto Select only when v4_mode is true + - drm/amd/pm: increase mclk switch threshold to 200 us + - tty: make FONTX ioctl use the tty pointer they were actually passed + - arm64: berlin: Select DW_APB_TIMER_OF + - [Config] update annotations for DW_APB_TIMER + - cachefiles: Handle readpage error correctly + - hil/parisc: Disable HIL driver when it gets stuck + - arm: dts: mt7623: add missing pause for switchport + - ARM: samsung: fix PM debug build with DEBUG_LL but !MMU + - ARM: s3c24xx: fix missing system reset + - device property: Keep secondary firmware node secondary by type + - device property: Don't clear secondary pointer for shared primary firmware + node + - KVM: arm64: Fix AArch32 handling of DBGD{CCINT,SCRext} and DBGVCR + - staging: fieldbus: anybuss: jump to correct label in an error path + - staging: comedi: cb_pcidas: Allow 2-channel commands for AO subdevice + - staging: octeon: repair "fixed-link" support + - staging: octeon: Drop on uncorrectable alignment or FCS error + - Linux 5.4.75 + * [HP 635] Radeon 6310 brightness control does not work (LP: #1894667) // + Focal update: v5.4.75 upstream stable release (LP: #1904450) + - ACPI: video: use ACPI backlight for HP 635 Notebook + * Focal update: v5.4.74 upstream stable release (LP: #1904445) + - netfilter: nftables_offload: KASAN slab-out-of-bounds Read in + nft_flow_rule_create + - socket: don't clear SOCK_TSTAMP_NEW when SO_TIMESTAMPNS is disabled + - objtool: Support Clang non-section symbols in ORC generation + - scripts/setlocalversion: make git describe output more reliable + - arm64: Run ARCH_WORKAROUND_1 enabling code on all CPUs + - arm64: Run ARCH_WORKAROUND_2 enabling code on all CPUs + - arm64: link with -z norelro regardless of CONFIG_RELOCATABLE + - x86/PCI: Fix intel_mid_pci.c build error when ACPI is not enabled + - bnxt_en: Check abort error state in bnxt_open_nic(). + - bnxt_en: Send HWRM_FUNC_RESET fw command unconditionally. + - chelsio/chtls: fix deadlock issue + - chelsio/chtls: fix memory leaks in CPL handlers + - chelsio/chtls: fix tls record info to user + - cxgb4: set up filter action after rewrites + - gtp: fix an use-before-init in gtp_newlink() + - ibmvnic: fix ibmvnic_set_mac + - mlxsw: core: Fix memory leak on module removal + - netem: fix zero division in tabledist + - net/sched: act_mpls: Add softdep on mpls_gso.ko + - r8169: fix issue with forced threading in combination with shared interrupts + - ravb: Fix bit fields checking in ravb_hwtstamp_get() + - tcp: Prevent low rmem stalls with SO_RCVLOWAT. + - tipc: fix memory leak caused by tipc_buf_append() + - net: hns3: Clear the CMDQ registers before unmapping BAR region + - bnxt_en: Re-write PCI BARs after PCI fatal error. + - bnxt_en: Fix regression in workqueue cleanup logic in bnxt_remove_one(). + - bnxt_en: Invoke cancel_delayed_work_sync() for PFs also. + - erofs: avoid duplicated permission check for "trusted." xattrs + - arch/x86/amd/ibs: Fix re-arming IBS Fetch + - x86/xen: disable Firmware First mode for correctable memory errors + - ata: ahci: mvebu: Make SATA PHY optional for Armada 3720 + - fuse: fix page dereference after free + - bpf: Fix comment for helper bpf_current_task_under_cgroup() + - evm: Check size of security.evm before using it + - p54: avoid accessing the data mapped to streaming DMA + - cxl: Rework error message for incompatible slots + - RDMA/addr: Fix race with netevent_callback()/rdma_addr_cancel() + - mtd: lpddr: Fix bad logic in print_drs_error + - serial: qcom_geni_serial: To correct QUP Version detection logic + - serial: pl011: Fix lockdep splat when handling magic-sysrq interrupt + - PM: runtime: Fix timer_expires data type on 32-bit arches + - ata: sata_rcar: Fix DMA boundary mask + - xen/gntdev.c: Mark pages as dirty + - crypto: x86/crc32c - fix building with clang ias + - openrisc: Fix issue with get_user for 64-bit values + - misc: rtsx: do not setting OC_POWER_DOWN reg in rtsx_pci_init_ocp() + - phy: marvell: comphy: Convert internal SMCC firmware return codes to errno + - Linux 5.4.74 + * Bionic: btrfs: kernel BUG at /build/linux- + eTBZpZ/linux-4.15.0/fs/btrfs/ctree.c:3233! (LP: #1902254) + - btrfs: tree-checker: fix incorrect printk format + * NULL pointer dereference when configuring multi-function with devfn != 0 + before devfn == 0 (LP: #1903682) + - s390/pci: fix hot-plug of PCI function missing bus + + -- Ian May Mon, 14 Dec 2020 09:14:09 -0600 + +linux-oracle (5.4.0-1032.34) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1032.34 -proposed tracker (LP: #1907386) + + [ Ubuntu: 5.4.0-58.64 ] + + * focal/linux: 5.4.0-58.64 -proposed tracker (LP: #1907390) + * Packaging resync (LP: #1786013) + - update dkms package versions + * raid10: discard leads to corrupted file system (LP: #1907262) + - Revert "dm raid: remove unnecessary discard limits for raid10" + - Revert "dm raid: fix discard limits for raid1 and raid10" + - Revert "md/raid10: improve discard request for far layout" + - Revert "md/raid10: improve raid10 discard request" + - Revert "md/raid10: pull codes that wait for blocked dev into one function" + - Revert "md/raid10: extend r10bio devs to raid disks" + - Revert "md: add md_submit_discard_bio() for submitting discard bio" + + [ Ubuntu: 5.4.0-56.62 ] + + * focal/linux: 5.4.0-56.62 -proposed tracker (LP: #1905300) + * CVE-2020-4788 + - selftests/powerpc: rfi_flush: disable entry flush if present + - powerpc/64s: flush L1D on kernel entry + - powerpc/64s: flush L1D after user accesses + - selftests/powerpc: entry flush test + + -- Kleber Sacilotto de Souza Wed, 09 Dec 2020 14:52:13 +0100 + +linux-oracle (5.4.0-1030.32) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1030.32 -proposed tracker (LP: #1903170) + + * Focal update: v5.4.66 upstream stable release (LP: #1896824) + - [Config] [oracle] updateconfigs for VGACON_SOFT_SCROLLBACK + + [ Ubuntu: 5.4.0-55.61 ] + + * focal/linux: 5.4.0-55.61 -proposed tracker (LP: #1903175) + * Update kernel packaging to support forward porting kernels (LP: #1902957) + - [Debian] Update for leader included in BACKPORT_SUFFIX + * Avoid double newline when running insertchanges (LP: #1903293) + - [Packaging] insertchanges: avoid double newline + * EFI: Fails when BootCurrent entry does not exist (LP: #1899993) + - efivarfs: Replace invalid slashes with exclamation marks in dentries. + * CVE-2020-14351 + - perf/core: Fix race in the perf_mmap_close() function + * raid10: Block discard is very slow, causing severe delays for mkfs and + fstrim operations (LP: #1896578) + - md: add md_submit_discard_bio() for submitting discard bio + - md/raid10: extend r10bio devs to raid disks + - md/raid10: pull codes that wait for blocked dev into one function + - md/raid10: improve raid10 discard request + - md/raid10: improve discard request for far layout + - dm raid: fix discard limits for raid1 and raid10 + - dm raid: remove unnecessary discard limits for raid10 + * Bionic: btrfs: kernel BUG at /build/linux- + eTBZpZ/linux-4.15.0/fs/btrfs/ctree.c:3233! (LP: #1902254) + - btrfs: drop unnecessary offset_in_page in extent buffer helpers + - btrfs: extent_io: do extra check for extent buffer read write functions + - btrfs: extent-tree: kill BUG_ON() in __btrfs_free_extent() + - btrfs: extent-tree: kill the BUG_ON() in insert_inline_extent_backref() + - btrfs: ctree: check key order before merging tree blocks + * Ethernet no link lights after reboot (Intel i225-v 2.5G) (LP: #1902578) + - igc: Add PHY power management control + * Undetected Data corruption in MPI workloads that use VSX for reductions on + POWER9 DD2.1 systems (LP: #1902694) + - powerpc: Fix undetected data corruption with P9N DD2.1 VSX CI load emulation + - selftests/powerpc: Make alignment handler test P9N DD2.1 vector CI load + workaround + * [20.04 FEAT] Support/enhancement of NVMe IPL (LP: #1902179) + - s390: nvme ipl + - s390: nvme reipl + - s390/ipl: support NVMe IPL kernel parameters + * uvcvideo: add mapping for HEVC payloads (LP: #1895803) + - media: uvcvideo: Add mapping for HEVC payloads + * Focal update: v5.4.73 upstream stable release (LP: #1902115) + - ibmveth: Switch order of ibmveth_helper calls. + - ibmveth: Identify ingress large send packets. + - ipv4: Restore flowi4_oif update before call to xfrm_lookup_route + - mlx4: handle non-napi callers to napi_poll + - net: fec: Fix phy_device lookup for phy_reset_after_clk_enable() + - net: fec: Fix PHY init after phy_reset_after_clk_enable() + - net: fix pos incrementment in ipv6_route_seq_next + - net/smc: fix valid DMBE buffer sizes + - net/tls: sendfile fails with ktls offload + - net: usb: qmi_wwan: add Cellient MPL200 card + - tipc: fix the skb_unshare() in tipc_buf_append() + - socket: fix option SO_TIMESTAMPING_NEW + - can: m_can_platform: don't call m_can_class_suspend in runtime suspend + - can: j1935: j1939_tp_tx_dat_new(): fix missing initialization of skbcnt + - net: j1939: j1939_session_fresh_new(): fix missing initialization of skbcnt + - net/ipv4: always honour route mtu during forwarding + - net_sched: remove a redundant goto chain check + - r8169: fix data corruption issue on RTL8402 + - cxgb4: handle 4-tuple PEDIT to NAT mode translation + - binder: fix UAF when releasing todo list + - ALSA: bebob: potential info leak in hwdep_read() + - ALSA: hda/hdmi: fix incorrect locking in hdmi_pcm_close + - nvme-pci: disable the write zeros command for Intel 600P/P3100 + - chelsio/chtls: fix socket lock + - chelsio/chtls: correct netdevice for vlan interface + - chelsio/chtls: correct function return and return type + - ibmvnic: save changed mac address to adapter->mac_addr + - net: ftgmac100: Fix Aspeed ast2600 TX hang issue + - net: hdlc: In hdlc_rcv, check to make sure dev is an HDLC device + - net: hdlc_raw_eth: Clear the IFF_TX_SKB_SHARING flag after calling + ether_setup + - net: Properly typecast int values to set sk_max_pacing_rate + - net/sched: act_tunnel_key: fix OOB write in case of IPv6 ERSPAN tunnels + - nexthop: Fix performance regression in nexthop deletion + - nfc: Ensure presence of NFC_ATTR_FIRMWARE_NAME attribute in + nfc_genl_fw_download() + - r8169: fix operation under forced interrupt threading + - selftests: forwarding: Add missing 'rp_filter' configuration + - tcp: fix to update snd_wl1 in bulk receiver fast path + - icmp: randomize the global rate limiter + - ALSA: hda/realtek - set mic to auto detect on a HP AIO machine + - ALSA: hda/realtek - Add mute Led support for HP Elitebook 845 G7 + - ALSA: hda/realtek: Enable audio jacks of ASUS D700SA with ALC887 + - cifs: remove bogus debug code + - cifs: Return the error from crypt_message when enc/dec key not found. + - SMB3: Resolve data corruption of TCP server info fields + - KVM: nVMX: Reset the segment cache when stuffing guest segs + - KVM: nVMX: Reload vmcs01 if getting vmcs12's pages fails + - KVM: x86/mmu: Commit zap of remaining invalid pages when recovering lpages + - KVM: SVM: Initialize prev_ga_tag before use + - ima: Don't ignore errors from crypto_shash_update() + - crypto: algif_aead - Do not set MAY_BACKLOG on the async path + - crypto: caam/qi - add fallback for XTS with more than 8B IV + - EDAC/i5100: Fix error handling order in i5100_init_one() + - EDAC/aspeed: Fix handling of platform_get_irq() error + - EDAC/ti: Fix handling of platform_get_irq() error + - perf/x86/intel/ds: Fix x86_pmu_stop warning for large PEBS + - x86/fpu: Allow multiple bits in clearcpuid= parameter + - drivers/perf: xgene_pmu: Fix uninitialized resource struct + - drivers/perf: thunderx2_pmu: Fix memory resource error handling + - sched/fair: Fix wrong cpu selecting from isolated domain + - perf/x86/intel/uncore: Update Ice Lake uncore units + - perf/x86/intel/uncore: Reduce the number of CBOX counters + - x86/nmi: Fix nmi_handle() duration miscalculation + - x86/events/amd/iommu: Fix sizeof mismatch + - crypto: algif_skcipher - EBUSY on aio should be an error + - crypto: mediatek - Fix wrong return value in mtk_desc_ring_alloc() + - crypto: ixp4xx - Fix the size used in a 'dma_free_coherent()' call + - crypto: picoxcell - Fix potential race condition bug + - media: tuner-simple: fix regression in simple_set_radio_freq + - media: Revert "media: exynos4-is: Add missed check for + pinctrl_lookup_state()" + - media: ov5640: Correct Bit Div register in clock tree diagram + - media: m5mols: Check function pointer in m5mols_sensor_power + - media: uvcvideo: Set media controller entity functions + - media: uvcvideo: Silence shift-out-of-bounds warning + - media: staging/intel-ipu3: css: Correctly reset some memory + - media: omap3isp: Fix memleak in isp_probe + - media: i2c: ov5640: Remain in power down for DVP mode unless streaming + - media: i2c: ov5640: Separate out mipi configuration from s_power + - media: i2c: ov5640: Enable data pins on poweron for DVP mode + - media: rcar_drif: Fix fwnode reference leak when parsing DT + - media: rcar_drif: Allocate v4l2_async_subdev dynamically + - media: rcar-csi2: Allocate v4l2_async_subdev dynamically + - crypto: omap-sham - fix digcnt register handling with export/import + - hwmon: (pmbus/max34440) Fix status register reads for MAX344{51,60,61} + - cypto: mediatek - fix leaks in mtk_desc_ring_alloc + - media: mx2_emmaprp: Fix memleak in emmaprp_probe + - media: tc358743: initialize variable + - media: tc358743: cleanup tc358743_cec_isr + - media: rcar-vin: Fix a reference count leak. + - media: rockchip/rga: Fix a reference count leak. + - media: platform: fcp: Fix a reference count leak. + - media: camss: Fix a reference count leak. + - media: s5p-mfc: Fix a reference count leak + - media: stm32-dcmi: Fix a reference count leak + - media: ti-vpe: Fix a missing check and reference count leak + - regulator: resolve supply after creating regulator + - pinctrl: bcm: fix kconfig dependency warning when !GPIOLIB + - spi: spi-s3c64xx: swap s3c64xx_spi_set_cs() and s3c64xx_enable_datapath() + - spi: spi-s3c64xx: Check return values + - blk-mq: move cancel of hctx->run_work to the front of blk_exit_queue + - ath10k: provide survey info as accumulated data + - drm/vkms: fix xrgb on compute crc + - Bluetooth: hci_uart: Cancel init work before unregistering + - drm/amd/display: Fix wrong return value in dm_update_plane_state() + - drm: panel: Fix bus format for OrtusTech COM43H4M85ULC panel + - ath6kl: prevent potential array overflow in ath6kl_add_new_sta() + - ath9k: Fix potential out of bounds in ath9k_htc_txcompletion_cb() + - ath10k: Fix the size used in a 'dma_free_coherent()' call in an error + handling path + - wcn36xx: Fix reported 802.11n rx_highest rate wcn3660/wcn3680 + - ASoC: qcom: lpass-platform: fix memory leak + - ASoC: qcom: lpass-cpu: fix concurrency issue + - brcmfmac: check ndev pointer + - mwifiex: Do not use GFP_KERNEL in atomic context + - staging: rtl8192u: Do not use GFP_KERNEL in atomic context + - drm/gma500: fix error check + - scsi: qla4xxx: Fix an error handling path in 'qla4xxx_get_host_stats()' + - scsi: qla2xxx: Fix wrong return value in qlt_chk_unresolv_exchg() + - scsi: qla2xxx: Fix wrong return value in qla_nvme_register_hba() + - scsi: csiostor: Fix wrong return value in csio_hw_prep_fw() + - backlight: sky81452-backlight: Fix refcount imbalance on error + - staging: emxx_udc: Fix passing of NULL to dma_alloc_coherent() + - VMCI: check return value of get_user_pages_fast() for errors + - mm/error_inject: Fix allow_error_inject function signatures. + - drm: panel: Fix bpc for OrtusTech COM43H4M85ULC panel + - drm/crc-debugfs: Fix memleak in crc_control_write + - binder: Remove bogus warning on failed same-process transaction + - tty: serial: earlycon dependency + - pty: do tty_flip_buffer_push without port->lock in pty_write + - pwm: lpss: Fix off by one error in base_unit math in pwm_lpss_prepare() + - pwm: lpss: Add range limit check for the base_unit register value + - drivers/virt/fsl_hypervisor: Fix error handling path + - video: fbdev: vga16fb: fix setting of pixclock because a pass-by-value error + - video: fbdev: sis: fix null ptr dereference + - video: fbdev: radeon: Fix memleak in radeonfb_pci_register + - ASoC: fsl: imx-es8328: add missing put_device() call in imx_es8328_probe() + - HID: roccat: add bounds checking in kone_sysfs_write_settings() + - drm/msm: Avoid div-by-zero in dpu_crtc_atomic_check() + - drm/panfrost: Ensure GPU quirks are always initialised + - iomap: Clear page error before beginning a write + - pinctrl: mcp23s08: Fix mcp23x17_regmap initialiser + - pinctrl: mcp23s08: Fix mcp23x17 precious range + - net/mlx5: Don't call timecounter cyc2time directly from 1PPS flow + - scsi: mpt3sas: Fix sync irqs + - net: stmmac: use netif_tx_start|stop_all_queues() function + - cpufreq: armada-37xx: Add missing MODULE_DEVICE_TABLE + - drm: mxsfb: check framebuffer pitch + - coresight: etm4x: Handle unreachable sink in perf mode + - xhci: don't create endpoint debugfs entry before ring buffer is set. + - net: dsa: rtl8366: Check validity of passed VLANs + - net: dsa: rtl8366: Refactor VLAN/PVID init + - net: dsa: rtl8366: Skip PVID setting if not requested + - net: wilc1000: clean up resource in error path of init mon interface + - ASoC: tlv320aic32x4: Fix bdiv clock rate derivation + - net: dsa: rtl8366rb: Support all 4096 VLANs + - spi: omap2-mcspi: Improve performance waiting for CHSTAT + - ath6kl: wmi: prevent a shift wrapping bug in ath6kl_wmi_delete_pstream_cmd() + - dmaengine: dmatest: Check list for emptiness before access its last entry + - misc: mic: scif: Fix error handling path + - ALSA: seq: oss: Avoid mutex lock for a long-time ioctl + - usb: dwc2: Fix parameter type in function pointer prototype + - quota: clear padding in v2r1_mem2diskdqb() + - slimbus: core: check get_addr before removing laddr ida + - slimbus: core: do not enter to clock pause mode in core + - slimbus: qcom-ngd-ctrl: disable ngd in qmi server down callback + - ASoC: fsl_sai: Instantiate snd_soc_dai_driver + - HID: hid-input: fix stylus battery reporting + - nvmem: core: fix possibly memleak when use nvmem_cell_info_to_nvmem_cell() + - nl80211: fix OBSS PD min and max offset validation + - coresight: etm: perf: Fix warning caused by etm_setup_aux failure + - ibmvnic: set up 200GBPS speed + - qtnfmac: fix resource leaks on unsupported iftype error return path + - iio: adc: stm32-adc: fix runtime autosuspend delay when slow polling + - net: enic: Cure the enic api locking trainwreck + - mfd: sm501: Fix leaks in probe() + - iwlwifi: mvm: split a print to avoid a WARNING in ROC + - usb: gadget: f_ncm: fix ncm_bitrate for SuperSpeed and above. + - usb: gadget: u_ether: enable qmult on SuperSpeed Plus as well + - nl80211: fix non-split wiphy information + - usb: dwc2: Fix INTR OUT transfers in DDMA mode. + - scsi: target: tcmu: Fix warning: 'page' may be used uninitialized + - scsi: be2iscsi: Fix a theoretical leak in beiscsi_create_eqs() + - ipmi_si: Fix wrong return value in try_smi_init() + - platform/x86: mlx-platform: Remove PSU EEPROM configuration + - mwifiex: fix double free + - ipvs: clear skb->tstamp in forwarding path + - net: korina: fix kfree of rx/tx descriptor array + - netfilter: nf_log: missing vlan offload tag and proto + - mm/swapfile.c: fix potential memory leak in sys_swapon + - mm/memcg: fix device private memcg accounting + - mm, oom_adj: don't loop through tasks in __set_oom_adj when not necessary + - fs: fix NULL dereference due to data race in prepend_path() + - selftests/ftrace: Change synthetic event name for inter-event-combined test + - i3c: master add i3c_master_attach_boardinfo to preserve boardinfo + - IB/mlx4: Fix starvation in paravirt mux/demux + - IB/mlx4: Adjust delayed work when a dup is observed + - powerpc/pseries: Fix missing of_node_put() in rng_init() + - powerpc/icp-hv: Fix missing of_node_put() in success path + - RDMA/ucma: Fix locking for ctx->events_reported + - RDMA/ucma: Add missing locking around rdma_leave_multicast() + - mtd: lpddr: fix excessive stack usage with clang + - RDMA/hns: Add a check for current state before modifying QP + - RDMA/umem: Fix signature of stub ib_umem_find_best_pgsz() + - powerpc/pseries: explicitly reschedule during drmem_lmb list traversal + - pseries/drmem: don't cache node id in drmem_lmb struct + - RDMA/mlx5: Fix potential race between destroy and CQE poll + - mtd: mtdoops: Don't write panic data twice + - ARM: 9007/1: l2c: fix prefetch bits init in L2X0_AUX_CTRL using DT values + - arc: plat-hsdk: fix kconfig dependency warning when !RESET_CONTROLLER + - ida: Free allocated bitmap in error path + - xfs: limit entries returned when counting fsmap records + - xfs: fix deadlock and streamline xfs_getfsmap performance + - xfs: fix high key handling in the rt allocator's query_range function + - RDMA/umem: Fix ib_umem_find_best_pgsz() for mappings that cross a page + boundary + - RDMA/umem: Prevent small pages from being returned by + ib_umem_find_best_pgsz() + - RDMA/qedr: Fix qp structure memory leak + - RDMA/qedr: Fix use of uninitialized field + - RDMA/qedr: Fix return code if accept is called on a destroyed qp + - RDMA/qedr: Fix inline size returned for iWARP + - powerpc/book3s64/hash/4k: Support large linear mapping range with 4K + - powerpc/tau: Use appropriate temperature sample interval + - powerpc/tau: Convert from timer to workqueue + - powerpc/tau: Remove duplicated set_thresholds() call + - powerpc/tau: Check processor type before enabling TAU interrupt + - powerpc/tau: Disable TAU between measurements + - powerpc/64s/radix: Fix mm_cpumask trimming race vs kthread_use_mm + - RDMA/cma: Remove dead code for kernel rdmacm multicast + - RDMA/cma: Consolidate the destruction of a cma_multicast in one place + - perf intel-pt: Fix "context_switch event has no tid" error + - RDMA/hns: Set the unsupported wr opcode + - RDMA/mlx5: Disable IB_DEVICE_MEM_MGT_EXTENSIONS if IB_WR_REG_MR can't work + - i40iw: Add support to make destroy QP synchronous + - perf stat: Skip duration_time in setup_system_wide + - RDMA/hns: Fix the wrong value of rnr_retry when querying qp + - RDMA/hns: Fix missing sq_sig_type when querying QP + - mtd: rawnand: vf610: disable clk on error handling path in probe + - mtd: spinand: gigadevice: Only one dummy byte in QUADIO + - mtd: spinand: gigadevice: Add QE Bit + - kdb: Fix pager search for multi-line strings + - overflow: Include header file with SIZE_MAX declaration + - RDMA/ipoib: Set rtnl_link_ops for ipoib interfaces + - powerpc/perf: Exclude pmc5/6 from the irrelevant PMU group constraints + - powerpc/perf/hv-gpci: Fix starting index value + - i3c: master: Fix error return in cdns_i3c_master_probe() + - cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_reboot_notifier + - IB/rdmavt: Fix sizeof mismatch + - RDMA/rxe: Fix skb lifetime in rxe_rcv_mcast_pkt() + - maiblox: mediatek: Fix handling of platform_get_irq() error + - selftests/powerpc: Fix eeh-basic.sh exit codes + - f2fs: wait for sysfs kobject removal before freeing f2fs_sb_info + - RDMA/rxe: Handle skb_clone() failure in rxe_recv.c + - mm/page_owner: change split_page_owner to take a count + - lib/crc32.c: fix trivial typo in preprocessor condition + - ramfs: fix nommu mmap with gaps in the page cache + - rapidio: fix error handling path + - rapidio: fix the missed put_device() for rio_mport_add_riodev + - mailbox: avoid timer start from callback + - i2c: rcar: Auto select RESET_CONTROLLER + - clk: meson: g12a: mark fclk_div2 as critical + - PCI: aardvark: Check for errors from pci_bridge_emul_init() call + - PCI: iproc: Set affinity mask on MSI interrupts + - rpmsg: smd: Fix a kobj leak in in qcom_smd_parse_edge() + - PCI/IOV: Mark VFs as not implementing PCI_COMMAND_MEMORY + - vfio/pci: Decouple PCI_COMMAND_MEMORY bit checks from is_virtfn + - clk: qcom: gcc-sdm660: Fix wrong parent_map + - clk: keystone: sci-clk: fix parsing assigned-clock data during probe + - pwm: img: Fix null pointer access in probe + - clk: rockchip: Initialize hw to error to avoid undefined behavior + - clk: mediatek: add UART0 clock support + - module: statically initialize init section freeing data + - clk: at91: clk-main: update key before writing AT91_CKGR_MOR + - clk: bcm2835: add missing release if devm_clk_hw_register fails + - watchdog: Fix memleak in watchdog_cdev_register + - watchdog: Use put_device on error + - watchdog: sp5100: Fix definition of EFCH_PM_DECODEEN3 + - svcrdma: fix bounce buffers for unaligned offsets and multiple pages + - ext4: limit entries returned when counting fsmap records + - vfio/pci: Clear token on bypass registration failure + - vfio iommu type1: Fix memory leak in vfio_iommu_type1_pin_pages + - clk: imx8mq: Fix usdhc parents order + - SUNRPC: fix copying of multiple pages in gss_read_proxy_verf() + - Input: imx6ul_tsc - clean up some errors in imx6ul_tsc_resume() + - Input: stmfts - fix a & vs && typo + - Input: ep93xx_keypad - fix handling of platform_get_irq() error + - Input: omap4-keypad - fix handling of platform_get_irq() error + - Input: twl4030_keypad - fix handling of platform_get_irq() error + - Input: sun4i-ps2 - fix handling of platform_get_irq() error + - KVM: x86: emulating RDPID failure shall return #UD rather than #GP + - scsi: bfa: Fix error return in bfad_pci_init() + - netfilter: conntrack: connection timeout after re-register + - netfilter: ebtables: Fixes dropping of small packets in bridge nat + - netfilter: nf_fwd_netdev: clear timestamp in forwarding path + - arm64: dts: meson: vim3: correct led polarity + - ARM: dts: imx6sl: fix rng node + - ARM: at91: pm: of_node_put() after its usage + - ARM: s3c24xx: fix mmc gpio lookup tables + - ARM: dts: sun8i: r40: bananapi-m2-ultra: Fix dcdc1 regulator + - arm64: dts: allwinner: h5: remove Mali GPU PMU module + - memory: omap-gpmc: Fix a couple off by ones + - memory: omap-gpmc: Fix build error without CONFIG_OF + - memory: fsl-corenet-cf: Fix handling of platform_get_irq() error + - arm64: dts: imx8mq: Add missing interrupts to GPC + - arm64: dts: qcom: msm8916: Remove one more thermal trip point unit name + - arm64: dts: qcom: pm8916: Remove invalid reg size from wcd_codec + - arm64: dts: qcom: msm8916: Fix MDP/DSI interrupts + - arm64: dts: renesas: r8a77990: Fix MSIOF1 DMA channels + - arm64: dts: renesas: r8a774c0: Fix MSIOF1 DMA channels + - arm64: dts: actions: limit address range for pinctrl node + - ARM: dts: owl-s500: Fix incorrect PPI interrupt specifiers + - soc: fsl: qbman: Fix return value on success + - ARM: OMAP2+: Restore MPU power domain if cpu_cluster_pm_enter() fails + - arm64: dts: zynqmp: Remove additional compatible string for i2c IPs + - ARM: dts: meson8: remove two invalid interrupt lines from the GPU node + - lightnvm: fix out-of-bounds write to array devices->info[] + - powerpc/powernv/dump: Fix race while processing OPAL dump + - powerpc/pseries: Avoid using addr_to_pfn in real mode + - nvmet: fix uninitialized work for zero kato + - NTB: hw: amd: fix an issue about leak system resources + - sched/features: Fix !CONFIG_JUMP_LABEL case + - perf: correct SNOOPX field offset + - i2c: core: Restore acpi_walk_dep_device_list() getting called after + registering the ACPI i2c devs + - md/bitmap: fix memory leak of temporary bitmap + - block: ratelimit handle_bad_sector() message + - crypto: ccp - fix error handling + - x86/asm: Replace __force_order with a memory clobber + - x86/mce: Add Skylake quirk for patrol scrub reported errors + - media: firewire: fix memory leak + - media: ati_remote: sanity check for both endpoints + - media: st-delta: Fix reference count leak in delta_run_work + - media: sti: Fix reference count leaks + - media: exynos4-is: Fix several reference count leaks due to + pm_runtime_get_sync + - media: exynos4-is: Fix a reference count leak due to pm_runtime_get_sync + - media: exynos4-is: Fix a reference count leak + - media: vsp1: Fix runtime PM imbalance on error + - media: platform: s3c-camif: Fix runtime PM imbalance on error + - media: platform: sti: hva: Fix runtime PM imbalance on error + - media: bdisp: Fix runtime PM imbalance on error + - media: media/pci: prevent memory leak in bttv_probe + - x86/mce: Make mce_rdmsrl() panic on an inaccessible MSR + - media: uvcvideo: Ensure all probed info is returned to v4l2 + - mmc: sdio: Check for CISTPL_VERS_1 buffer size + - media: saa7134: avoid a shift overflow + - media: venus: fixes for list corruption + - fs: dlm: fix configfs memory leak + - media: venus: core: Fix runtime PM imbalance in venus_probe + - ntfs: add check for mft record size in superblock + - ip_gre: set dev->hard_header_len and dev->needed_headroom properly + - mac80211: handle lack of sband->bitrates in rates + - PM: hibernate: remove the bogus call to get_gendisk() in software_resume() + - scsi: mvumi: Fix error return in mvumi_io_attach() + - scsi: target: core: Add CONTROL field for trace events + - mic: vop: copy data to kernel space then write to io memory + - misc: vop: add round_up(x,4) for vring_size to avoid kernel panic + - usb: dwc3: Add splitdisable quirk for Hisilicon Kirin Soc + - usb: gadget: function: printer: fix use-after-free in __lock_acquire + - udf: Limit sparing table size + - udf: Avoid accessing uninitialized data on failed inode read + - rtw88: increse the size of rx buffer size + - USB: cdc-acm: handle broken union descriptors + - usb: dwc3: simple: add support for Hikey 970 + - can: flexcan: flexcan_chip_stop(): add error handling and propagate error + value + - ath9k: hif_usb: fix race condition between usb_get_urb() and + usb_kill_anchored_urbs() + - drm/panfrost: add amlogic reset quirk callback + - bpf: Limit caller's stack depth 256 for subprogs with tailcalls + - misc: rtsx: Fix memory leak in rtsx_pci_probe + - reiserfs: only call unlock_new_inode() if I_NEW + - opp: Prevent memory leak in dev_pm_opp_attach_genpd() + - xfs: make sure the rt allocator doesn't run off the end + - usb: ohci: Default to per-port over-current protection + - Bluetooth: Only mark socket zapped after unlocking + - drm/msm/a6xx: fix a potential overflow issue + - iomap: fix WARN_ON_ONCE() from unprivileged users + - scsi: ibmvfc: Fix error return in ibmvfc_probe() + - scsi: qla2xxx: Warn if done() or free() are called on an already freed srb + - selftests/bpf: Fix test_sysctl_loop{1, 2} failure due to clang change + - brcmsmac: fix memory leak in wlc_phy_attach_lcnphy + - rtl8xxxu: prevent potential memory leak + - Fix use after free in get_capset_info callback. + - HID: ite: Add USB id match for Acer One S1003 keyboard dock + - scsi: qedf: Return SUCCESS if stale rport is encountered + - scsi: qedi: Protect active command list to avoid list corruption + - scsi: qedi: Fix list_del corruption while removing active I/O + - fbmem: add margin check to fb_check_caps() + - tty: ipwireless: fix error handling + - Bluetooth: btusb: Fix memleak in btusb_mtk_submit_wmt_recv_urb + - ipvs: Fix uninit-value in do_ip_vs_set_ctl() + - reiserfs: Fix memory leak in reiserfs_parse_options() + - mwifiex: don't call del_timer_sync() on uninitialized timer + - ALSA: hda/ca0132 - Add AE-7 microphone selection commands. + - ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7. + - scsi: smartpqi: Avoid crashing kernel for controller issues + - brcm80211: fix possible memleak in brcmf_proto_msgbuf_attach + - usb: core: Solve race condition in anchor cleanup functions + - scsi: ufs: ufs-qcom: Fix race conditions caused by ufs_qcom_testbus_config() + - dmaengine: dw: Add DMA-channels mask cell support + - dmaengine: dw: Activate FIFO-mode for memory peripherals only + - ath10k: check idx validity in __ath10k_htt_rx_ring_fill_n() + - net: korina: cast KSEG0 address to pointer in kfree + - s390/qeth: don't let HW override the configured port role + - tty: serial: lpuart: fix lpuart32_write usage + - tty: serial: fsl_lpuart: fix lpuart32_poll_get_char + - usb: cdc-acm: add quirk to blacklist ETAS ES58X devices + - USB: cdc-wdm: Make wdm_flush() interruptible and add wdm_fsync(). + - usb: cdns3: gadget: free interrupt after gadget has deleted + - eeprom: at25: set minimum read/write access stride to 1 + - usb: gadget: f_ncm: allow using NCM in SuperSpeed Plus gadgets. + - Linux 5.4.73 + * Focal update: v5.4.72 upstream stable release (LP: #1902111) + - perf cs-etm: Move definition of 'traceid_list' global variable from header + file + - btrfs: don't pass system_chunk into can_overcommit + - btrfs: take overcommit into account in inc_block_group_ro + - ARM: 8939/1: kbuild: use correct nm executable + - ACPI: Always build evged in + - Bluetooth: Consolidate encryption handling in hci_encrypt_cfm + - Bluetooth: Fix update of connection state in `hci_encrypt_cfm` + - Bluetooth: Disconnect if E0 is used for Level 4 + - media: usbtv: Fix refcounting mixup + - USB: serial: option: add Cellient MPL200 card + - USB: serial: option: Add Telit FT980-KS composition + - staging: comedi: check validity of wMaxPacketSize of usb endpoints found + - USB: serial: pl2303: add device-id for HP GC device + - USB: serial: ftdi_sio: add support for FreeCalypso JTAG+UART adapters + - reiserfs: Initialize inode keys properly + - reiserfs: Fix oops during mount + - xen/events: don't use chip_data for legacy IRQs + - crypto: bcm - Verify GCM/CCM key length in setkey + - crypto: qat - check cipher length for aead AES-CBC-HMAC-SHA + - Linux 5.4.72 + * Focal update: v5.4.71 upstream stable release (LP: #1902110) + - fbdev, newport_con: Move FONT_EXTRA_WORDS macros into linux/font.h + - Fonts: Support FONT_EXTRA_WORDS macros for built-in fonts + - fbcon: Fix global-out-of-bounds read in fbcon_get_font() + - Revert "ravb: Fixed to be able to unload modules" + - io_uring: Fix resource leaking when kill the process + - io_uring: Fix missing smp_mb() in io_cancel_async_work() + - io_uring: Fix remove irrelevant req from the task_list + - io_uring: Fix double list add in io_queue_async_work() + - net: wireless: nl80211: fix out-of-bounds access in nl80211_del_key() + - drm/nouveau/mem: guard against NULL pointer access in mem_del + - vhost: Don't call access_ok() when using IOTLB + - vhost: Use vhost_get_used_size() in vhost_vring_set_addr() + - usermodehelper: reset umask to default before executing user process + - Platform: OLPC: Fix memleak in olpc_ec_probe + - platform/x86: intel-vbtn: Fix SW_TABLET_MODE always reporting 1 on the HP + Pavilion 11 x360 + - platform/x86: thinkpad_acpi: initialize tp_nvram_state variable + - bpf: Fix sysfs export of empty BTF section + - bpf: Prevent .BTF section elimination + - platform/x86: intel-vbtn: Switch to an allow-list for SW_TABLET_MODE + reporting + - platform/x86: thinkpad_acpi: re-initialize ACPI buffer size when reuse + - driver core: Fix probe_count imbalance in really_probe() + - perf test session topology: Fix data path + - perf top: Fix stdio interface input handling with glibc 2.28+ + - i2c: i801: Exclude device from suspend direct complete optimization + - arm64: dts: stratix10: add status to qspi dts node + - Btrfs: send, allow clone operations within the same file + - Btrfs: send, fix emission of invalid clone operations within the same file + - btrfs: volumes: Use more straightforward way to calculate map length + - btrfs: Ensure we trim ranges across block group boundary + - btrfs: fix RWF_NOWAIT write not failling when we need to cow + - btrfs: allow btrfs_truncate_block() to fallback to nocow for data space + reservation + - nvme-core: put ctrl ref when module ref get fail + - macsec: avoid use-after-free in macsec_handle_frame() + - mm/khugepaged: fix filemap page_to_pgoff(page) != offset + - net: introduce helper sendpage_ok() in include/linux/net.h + - tcp: use sendpage_ok() to detect misused .sendpage + - nvme-tcp: check page by sendpage_ok() before calling kernel_sendpage() + - xfrmi: drop ignore_df check before updating pmtu + - cifs: Fix incomplete memory allocation on setxattr path + - i2c: meson: fix clock setting overwrite + - i2c: meson: fixup rate calculation with filter delay + - i2c: owl: Clear NACK and BUS error bits + - sctp: fix sctp_auth_init_hmacs() error path + - team: set dev->needed_headroom in team_setup_by_port() + - net: team: fix memory leak in __team_options_register + - openvswitch: handle DNAT tuple collision + - drm/amdgpu: prevent double kfree ttm->sg + - iommu/vt-d: Fix lockdep splat in iommu_flush_dev_iotlb() + - xfrm: clone XFRMA_SET_MARK in xfrm_do_migrate + - xfrm: clone XFRMA_REPLAY_ESN_VAL in xfrm_do_migrate + - xfrm: clone XFRMA_SEC_CTX in xfrm_do_migrate + - xfrm: clone whole liftime_cur structure in xfrm_do_migrate + - net: stmmac: removed enabling eee in EEE set callback + - platform/x86: fix kconfig dependency warning for FUJITSU_LAPTOP + - xfrm: Use correct address family in xfrm_state_find + - iavf: use generic power management + - iavf: Fix incorrect adapter get in iavf_resume + - net: ethernet: cavium: octeon_mgmt: use phy_start and phy_stop + - bonding: set dev->needed_headroom in bond_setup_by_slave() + - mdio: fix mdio-thunder.c dependency & build error + - mlxsw: spectrum_acl: Fix mlxsw_sp_acl_tcam_group_add()'s error path + - r8169: fix RTL8168f/RTL8411 EPHY config + - net: usb: ax88179_178a: fix missing stop entry in driver_info + - virtio-net: don't disable guest csum when disable LRO + - net/mlx5: Avoid possible free of command entry while timeout comp handler + - net/mlx5: Fix request_irqs error flow + - net/mlx5e: Add resiliency in Striding RQ mode for packets larger than MTU + - net/mlx5e: Fix VLAN cleanup flow + - net/mlx5e: Fix VLAN create flow + - rxrpc: Fix rxkad token xdr encoding + - rxrpc: Downgrade the BUG() for unsupported token type in rxrpc_read() + - rxrpc: Fix some missing _bh annotations on locking conn->state_lock + - rxrpc: The server keyring isn't network-namespaced + - rxrpc: Fix server keyring leak + - perf: Fix task_function_call() error handling + - mmc: core: don't set limits.discard_granularity as 0 + - mm: khugepaged: recalculate min_free_kbytes after memory hotplug as expected + by khugepaged + - tcp: fix receive window update in tcp_add_backlog() + - net/core: check length before updating Ethertype in skb_mpls_{push,pop} + - net/tls: race causes kernel panic + - net/mlx5e: Fix driver's declaration to support GRE offload + - Input: ati_remote2 - add missing newlines when printing module parameters + - net: usb: rtl8150: set random MAC address when set_ethernet_addr() fails + - net_sched: defer tcf_idr_insert() in tcf_action_init_1() + - net_sched: commit action insertions together + - Linux 5.4.71 + * kci_test_encap_fou() in rtnetlink.sh from kselftests/net failed with "FAIL: + can't add fou port 7777, skipping test" (LP: #1891421) + - selftests: rtnetlink: load fou module for kci_test_encap_fou() test + * alsa/hda/realtek - The front Mic on a HP machine doesn't work (LP: #1899508) + - ALSA: hda/realtek - The front Mic on a HP machine doesn't work + * Enable brightness control on HP DreamColor panel (LP: #1898865) + - drm/i915/dpcd_bl: Unbreak enable_dpcd_backlight modparam + - SAUCE: drm/i915/dpcd_bl: Skip testing control capability with force DPCD + quirk + - SAUCE: drm/dp: HP DreamColor panel brigntness fix + * Fix non-working Intel NVMe after S3 (LP: #1900847) + - SAUCE: PCI: Enable ACS quirk on all CML root ports + * bcache: Issues with large IO wait in bch_mca_scan() when shrinker is enabled + (LP: #1898786) + - bcache: remove member accessed from struct btree + - bcache: reap c->btree_cache_freeable from the tail in bch_mca_scan() + - bcache: reap from tail of c->btree_cache in bch_mca_scan() + * Improve descriptions for XFAIL cases in kselftests/net/psock_snd + (LP: #1900088) + - selftests/net: improve descriptions for XFAIL cases in psock_snd.sh + * ceph: fix inode number handling on arches with 32-bit ino_t (LP: #1899582) + - ceph: fix inode number handling on arches with 32-bit ino_t + * Fix system reboot when disconnecting WiFi (LP: #1899726) + - iwlwifi: msix: limit max RX queues for 9000 family + * Fix broken MSI interrupt after HDA controller was suspended (LP: #1899586) + - ALSA: hda: fix jack detection with Realtek codecs when in D3 + * Focal update: v5.4.70 upstream stable release (LP: #1900632) + - btrfs: fix filesystem corruption after a device replace + - mmc: sdhci: Workaround broken command queuing on Intel GLK based IRBIS + models + - USB: gadget: f_ncm: Fix NDP16 datagram validation + - gpio: siox: explicitly support only threaded irqs + - gpio: mockup: fix resource leak in error path + - gpio: tc35894: fix up tc35894 interrupt configuration + - clk: socfpga: stratix10: fix the divider for the emac_ptp_free_clk + - vsock/virtio: add transport parameter to the + virtio_transport_reset_no_sock() + - net: virtio_vsock: Enhance connection semantics + - xfs: trim IO to found COW extent limit + - Input: i8042 - add nopnp quirk for Acer Aspire 5 A515 + - iio: adc: qcom-spmi-adc5: fix driver name + - ftrace: Move RCU is watching check after recursion check + - memstick: Skip allocating card when removing host + - drm/amdgpu: restore proper ref count in amdgpu_display_crtc_set_config + - clocksource/drivers/timer-gx6605s: Fixup counter reload + - libbpf: Remove arch-specific include path in Makefile + - drivers/net/wan/hdlc_fr: Add needed_headroom for PVC devices + - drm/sun4i: mixer: Extend regmap max_register + - net: dec: de2104x: Increase receive ring size for Tulip + - rndis_host: increase sleep time in the query-response loop + - nvme-core: get/put ctrl and transport module in nvme_dev_open/release() + - fuse: fix the ->direct_IO() treatment of iov_iter + - drivers/net/wan/lapbether: Make skb->protocol consistent with the header + - drivers/net/wan/hdlc: Set skb->protocol before transmitting + - mac80211: Fix radiotap header channel flag for 6GHz band + - mac80211: do not allow bigger VHT MPDUs than the hardware supports + - tracing: Make the space reserved for the pid wider + - tools/io_uring: fix compile breakage + - spi: fsl-espi: Only process interrupts for expected events + - nvme-pci: fix NULL req in completion handler + - nvme-fc: fail new connections to a deleted host or remote port + - gpio: sprd: Clear interrupt when setting the type as edge + - phy: ti: am654: Fix a leak in serdes_am654_probe() + - pinctrl: mvebu: Fix i2c sda definition for 98DX3236 + - nfs: Fix security label length not being reset + - clk: tegra: Always program PLL_E when enabled + - clk: samsung: exynos4: mark 'chipid' clock as CLK_IGNORE_UNUSED + - iommu/exynos: add missing put_device() call in exynos_iommu_of_xlate() + - gpio/aspeed-sgpio: enable access to all 80 input & output sgpios + - gpio/aspeed-sgpio: don't enable all interrupts by default + - gpio: aspeed: fix ast2600 bank properties + - i2c: cpm: Fix i2c_ram structure + - Input: trackpoint - enable Synaptics trackpoints + - scripts/dtc: only append to HOST_EXTRACFLAGS instead of overwriting + - random32: Restore __latent_entropy attribute on net_rand_state + - block/diskstats: more accurate approximation of io_ticks for slow disks + - mm: replace memmap_context by meminit_context + - mm: don't rely on system state to detect hot-plug operations + - nvme: Cleanup and rename nvme_block_nr() + - nvme: Introduce nvme_lba_to_sect() + - nvme: consolidate chunk_sectors settings + - epoll: do not insert into poll queues until all sanity checks are done + - epoll: replace ->visited/visited_list with generation count + - epoll: EPOLL_CTL_ADD: close the race in decision to take fast path + - ep_create_wakeup_source(): dentry name can change under you... + - netfilter: ctnetlink: add a range check for l3/l4 protonum + - Linux 5.4.70 + * Focal update: v5.4.69 upstream stable release (LP: #1900624) + - kernel/sysctl-test: Add null pointer test for sysctl.c:proc_dointvec() + - selinux: allow labeling before policy is loaded + - media: mc-device.c: fix memleak in media_device_register_entity + - drm/amd/display: Do not double-buffer DTO adjustments + - drm/amdkfd: Fix race in gfx10 context restore handler + - dma-fence: Serialise signal enabling (dma_fence_enable_sw_signaling) + - scsi: qla2xxx: Add error handling for PLOGI ELS passthrough + - ath10k: fix array out-of-bounds access + - ath10k: fix memory leak for tpc_stats_final + - PCI/IOV: Serialize sysfs sriov_numvfs reads vs writes + - mm: fix double page fault on arm64 if PTE_AF is cleared + - scsi: aacraid: fix illegal IO beyond last LBA + - m68k: q40: Fix info-leak in rtc_ioctl + - xfs: fix inode fork extent count overflow + - gma/gma500: fix a memory disclosure bug due to uninitialized bytes + - ASoC: kirkwood: fix IRQ error handling + - soundwire: intel/cadence: fix startup sequence + - media: smiapp: Fix error handling at NVM reading + - drm/amd/display: Free gamma after calculating legacy transfer function + - xfs: properly serialise fallocate against AIO+DIO + - leds: mlxreg: Fix possible buffer overflow + - dm table: do not allow request-based DM to stack on partitions + - PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out + - scsi: fnic: fix use after free + - powerpc/64s: Always disable branch profiling for prom_init.o + - net: silence data-races on sk_backlog.tail + - dax: Fix alloc_dax_region() compile warning + - iomap: Fix overflow in iomap_page_mkwrite + - f2fs: avoid kernel panic on corruption test + - clk/ti/adpll: allocate room for terminating null + - drm/amdgpu/powerplay: fix AVFS handling with custom powerplay table + - ice: Fix to change Rx/Tx ring descriptor size via ethtool with DCBx + - mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of + cfi_amdstd_setup() + - mfd: mfd-core: Protect against NULL call-back function pointer + - drm/amdgpu/powerplay/smu7: fix AVFS handling with custom powerplay table + - tpm_crb: fix fTPM on AMD Zen+ CPUs + - tracing: Verify if trace array exists before destroying it. + - tracing: Adding NULL checks for trace_array descriptor pointer + - bcache: fix a lost wake-up problem caused by mca_cannibalize_lock + - dmaengine: mediatek: hsdma_probe: fixed a memory leak when devm_request_irq + fails + - x86/kdump: Always reserve the low 1M when the crashkernel option is + specified + - RDMA/qedr: Fix potential use after free + - RDMA/i40iw: Fix potential use after free + - PCI: Avoid double hpmemsize MMIO window assignment + - fix dget_parent() fastpath race + - xfs: fix attr leaf header freemap.size underflow + - RDMA/iw_cgxb4: Fix an error handling path in 'c4iw_connect()' + - ubi: Fix producing anchor PEBs + - mmc: core: Fix size overflow for mmc partitions + - gfs2: clean up iopen glock mess in gfs2_create_inode + - scsi: pm80xx: Cleanup command when a reset times out + - mt76: do not use devm API for led classdev + - mt76: add missing locking around ampdu action + - debugfs: Fix !DEBUG_FS debugfs_create_automount + - SUNRPC: Capture completion of all RPC tasks + - CIFS: Use common error handling code in smb2_ioctl_query_info() + - CIFS: Properly process SMB3 lease breaks + - f2fs: stop GC when the victim becomes fully valid + - ASoC: max98090: remove msleep in PLL unlocked workaround + - xtensa: fix system_call interaction with ptrace + - s390: avoid misusing CALL_ON_STACK for task stack setup + - xfs: fix realtime file data space leak + - drm/amdgpu: fix calltrace during kmd unload(v3) + - arm64: insn: consistently handle exit text + - selftests/bpf: De-flake test_tcpbpf + - kernel/notifier.c: intercept duplicate registrations to avoid infinite loops + - kernel/sys.c: avoid copying possible padding bytes in copy_to_user + - KVM: arm/arm64: vgic: Fix potential double free dist->spis in + __kvm_vgic_destroy() + - module: Remove accidental change of module_enable_x() + - xfs: fix log reservation overflows when allocating large rt extents + - ALSA: hda: enable regmap internal locking + - tipc: fix link overflow issue at socket shutdown + - vcc_seq_next should increase position index + - neigh_stat_seq_next() should increase position index + - rt_cpu_seq_next should increase position index + - ipv6_route_seq_next should increase position index + - drm/mcde: Handle pending vblank while disabling display + - seqlock: Require WRITE_ONCE surrounding raw_seqcount_barrier + - drm/scheduler: Avoid accessing freed bad job. + - media: ti-vpe: cal: Restrict DMA to avoid memory corruption + - opp: Replace list_kref with a local counter + - scsi: qla2xxx: Fix stuck session in GNL + - sctp: move trace_sctp_probe_path into sctp_outq_sack + - ACPI: EC: Reference count query handlers under lock + - scsi: ufs: Make ufshcd_add_command_trace() easier to read + - scsi: ufs: Fix a race condition in the tracing code + - drm/amd/display: Initialize DSC PPS variables to 0 + - i2c: tegra: Prevent interrupt triggering after transfer timeout + - btrfs: tree-checker: Check leaf chunk item size + - dmaengine: zynqmp_dma: fix burst length configuration + - s390/cpum_sf: Use kzalloc and minor changes + - nfsd: Fix a soft lockup race in nfsd_file_mark_find_or_create() + - powerpc/eeh: Only dump stack once if an MMIO loop is detected + - Bluetooth: btrtl: Use kvmalloc for FW allocations + - tracing: Set kernel_stack's caller size properly + - ARM: 8948/1: Prevent OOB access in stacktrace + - ar5523: Add USB ID of SMCWUSBT-G2 wireless adapter + - ceph: ensure we have a new cap before continuing in fill_inode + - selftests/ftrace: fix glob selftest + - tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility + - Bluetooth: Fix refcount use-after-free issue + - mm/swapfile.c: swap_next should increase position index + - mm: pagewalk: fix termination condition in walk_pte_range() + - Bluetooth: prefetch channel before killing sock + - ALSA: hda: Clear RIRB status before reading WP + - skbuff: fix a data race in skb_queue_len() + - nfsd: Fix a perf warning + - drm/amd/display: fix workaround for incorrect double buffer register for DLG + ADL and TTU + - audit: CONFIG_CHANGE don't log internal bookkeeping as an event + - selinux: sel_avc_get_stat_idx should increase position index + - drm/omap: fix possible object reference leak + - locking/lockdep: Decrement IRQ context counters when removing lock chain + - clk: stratix10: use do_div() for 64-bit calculation + - crypto: chelsio - This fixes the kernel panic which occurs during a libkcapi + test + - mt76: clear skb pointers from rx aggregation reorder buffer during cleanup + - mt76: fix handling full tx queues in mt76_dma_tx_queue_skb_raw + - ALSA: usb-audio: Don't create a mixer element with bogus volume range + - perf test: Fix test trace+probe_vfs_getname.sh on s390 + - RDMA/rxe: Fix configuration of atomic queue pair attributes + - KVM: x86: fix incorrect comparison in trace event + - KVM: nVMX: Hold KVM's srcu lock when syncing vmcs12->shadow + - dmaengine: stm32-mdma: use vchan_terminate_vdesc() in .terminate_all + - media: staging/imx: Missing assignment in + imx_media_capture_device_register() + - x86/pkeys: Add check for pkey "overflow" + - bpf: Remove recursion prevention from rcu free callback + - dmaengine: stm32-dma: use vchan_terminate_vdesc() in .terminate_all + - dmaengine: tegra-apb: Prevent race conditions on channel's freeing + - soundwire: bus: disable pm_runtime in sdw_slave_delete + - drm/amd/display: dal_ddc_i2c_payloads_create can fail causing panic + - drm/omap: dss: Cleanup DSS ports on initialisation failure + - iavf: use tc_cls_can_offload_and_chain0() instead of chain check + - firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhp + - random: fix data races at timer_rand_state + - bus: hisi_lpc: Fixup IO ports addresses to avoid use-after-free in host + removal + - ASoC: SOF: ipc: check ipc return value before data copy + - media: go7007: Fix URB type for interrupt handling + - Bluetooth: guard against controllers sending zero'd events + - timekeeping: Prevent 32bit truncation in scale64_check_overflow() + - powerpc/book3s64: Fix error handling in mm_iommu_do_alloc() + - drm/amd/display: fix image corruption with ODM 2:1 DSC 2 slice + - ext4: fix a data race at inode->i_disksize + - perf jevents: Fix leak of mapfile memory + - mm: avoid data corruption on CoW fault into PFN-mapped VMA + - drm/amdgpu: increase atombios cmd timeout + - ARM: OMAP2+: Handle errors for cpu_pm + - clk: imx: Fix division by zero warning on pfdv2 + - cpu-topology: Fix the potential data corruption + - s390/irq: replace setup_irq() by request_irq() + - perf cs-etm: Swap packets for instruction samples + - perf cs-etm: Correct synthesizing instruction samples + - ath10k: use kzalloc to read for ath10k_sdio_hif_diag_read + - scsi: aacraid: Disabling TM path and only processing IOP reset + - Bluetooth: L2CAP: handle l2cap config request during open state + - media: tda10071: fix unsigned sign extension overflow + - tty: sifive: Finish transmission before changing the clock + - xfs: don't ever return a stale pointer from __xfs_dir3_free_read + - xfs: mark dir corrupt when lookup-by-hash fails + - ext4: mark block bitmap corrupted when found instead of BUGON + - tpm: ibmvtpm: Wait for buffer to be set before proceeding + - rtc: sa1100: fix possible race condition + - rtc: ds1374: fix possible race condition + - nfsd: Don't add locks to closed or closing open stateids + - RDMA/cm: Remove a race freeing timewait_info + - intel_th: Disallow multi mode on devices where it's broken + - KVM: PPC: Book3S HV: Treat TM-related invalid form instructions on P9 like + the valid ones + - drm/msm: fix leaks if initialization fails + - drm/msm/a5xx: Always set an OPP supported hardware value + - tracing: Use address-of operator on section symbols + - thermal: rcar_thermal: Handle probe error gracefully + - KVM: LAPIC: Mark hrtimer for period or oneshot mode to expire in hard + interrupt context + - perf parse-events: Fix 3 use after frees found with clang ASAN + - btrfs: do not init a reloc root if we aren't relocating + - btrfs: free the reloc_control in a consistent way + - r8169: improve RTL8168b FIFO overflow workaround + - serial: 8250_port: Don't service RX FIFO if throttled + - serial: 8250_omap: Fix sleeping function called from invalid context during + probe + - serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout + - perf cpumap: Fix snprintf overflow check + - net: axienet: Convert DMA error handler to a work queue + - net: axienet: Propagate failure of DMA descriptor setup + - cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_work_fn + - tools: gpio-hammer: Avoid potential overflow in main + - exec: Add exec_update_mutex to replace cred_guard_mutex + - exec: Fix a deadlock in strace + - selftests/ptrace: add test cases for dead-locks + - kernel/kcmp.c: Use new infrastructure to fix deadlocks in execve + - proc: Use new infrastructure to fix deadlocks in execve + - proc: io_accounting: Use new infrastructure to fix deadlocks in execve + - perf: Use new infrastructure to fix deadlocks in execve + - nvme-multipath: do not reset on unknown status + - nvme: Fix ctrl use-after-free during sysfs deletion + - nvme: Fix controller creation races with teardown flow + - brcmfmac: Fix double freeing in the fmac usb data path + - xfs: prohibit fs freezing when using empty transactions + - RDMA/rxe: Set sys_image_guid to be aligned with HW IB devices + - IB/iser: Always check sig MR before putting it to the free pool + - scsi: hpsa: correct race condition in offload enabled + - SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' + - svcrdma: Fix leak of transport addresses + - netfilter: nf_tables: silence a RCU-list warning in nft_table_lookup() + - PCI: Use ioremap(), not phys_to_virt() for platform ROM + - ubifs: ubifs_jnl_write_inode: Fix a memory leak bug + - ubifs: ubifs_add_orphan: Fix a memory leak bug + - ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len + - ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra + endpoint descriptor + - PCI: pciehp: Fix MSI interrupt race + - NFS: Fix races nfs_page_group_destroy() vs + nfs_destroy_unlinked_subrequests() + - drm/amdgpu/vcn2.0: stall DPG when WPTR/RPTR reset + - powerpc/perf: Implement a global lock to avoid races between trace, core and + thread imc events. + - mm/kmemleak.c: use address-of operator on section symbols + - mm/filemap.c: clear page error before actual read + - mm/swapfile: fix data races in try_to_unuse() + - mm/vmscan.c: fix data races using kswapd_classzone_idx + - SUNRPC: Don't start a timer on an already queued rpc task + - nvmet-rdma: fix double free of rdma queue + - workqueue: Remove the warning in wq_worker_sleeping() + - drm/amdgpu/sriov add amdgpu_amdkfd_pre_reset in gpu reset + - mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area + - ALSA: hda: Skip controller resume if not needed + - scsi: qedi: Fix termination timeouts in session logout + - serial: uartps: Wait for tx_empty in console setup + - btrfs: fix setting last_trans for reloc roots + - KVM: Remove CREATE_IRQCHIP/SET_PIT2 race + - perf stat: Force error in fallback on :k events + - bdev: Reduce time holding bd_mutex in sync in blkdev_close() + - drivers: char: tlclk.c: Avoid data race between init and interrupt handler + - KVM: arm64: vgic-v3: Retire all pending LPIs on vcpu destroy + - KVM: arm64: vgic-its: Fix memory leak on the error path of vgic_add_lpi() + - net: openvswitch: use u64 for meter bucket + - scsi: aacraid: Fix error handling paths in aac_probe_one() + - staging:r8188eu: avoid skb_clone for amsdu to msdu conversion + - sparc64: vcc: Fix error return code in vcc_probe() + - arm64: cpufeature: Relax checks for AArch32 support at EL[0-2] + - sched/fair: Eliminate bandwidth race between throttling and distribution + - dpaa2-eth: fix error return code in setup_dpni() + - dt-bindings: sound: wm8994: Correct required supplies based on actual + implementaion + - devlink: Fix reporter's recovery condition + - atm: fix a memory leak of vcc->user_back + - media: venus: vdec: Init registered list unconditionally + - perf mem2node: Avoid double free related to realloc + - mm/slub: fix incorrect interpretation of s->offset + - i2c: tegra: Restore pinmux on system resume + - power: supply: max17040: Correct voltage reading + - phy: samsung: s5pv210-usb2: Add delay after reset + - Bluetooth: Handle Inquiry Cancel error after Inquiry Complete + - USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() + - KVM: x86: handle wrap around 32-bit address space + - tipc: fix memory leak in service subscripting + - tty: serial: samsung: Correct clock selection logic + - ALSA: hda: Fix potential race in unsol event handler + - drm/exynos: dsi: Remove bridge node reference in error handling path in + probe function + - ipmi:bt-bmc: Fix error handling and status check + - powerpc/traps: Make unrecoverable NMIs die instead of panic + - svcrdma: Fix backchannel return code + - fuse: don't check refcount after stealing page + - fuse: update attr_version counter on fuse_notify_inval_inode() + - USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int + - coresight: etm4x: Fix use-after-free of per-cpu etm drvdata + - arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work + - scsi: cxlflash: Fix error return code in cxlflash_probe() + - arm64/cpufeature: Drop TraceFilt feature exposure from ID_DFR0 register + - drm/amdkfd: fix restore worker race condition + - e1000: Do not perform reset in reset_task if we are already down + - drm/nouveau/debugfs: fix runtime pm imbalance on error + - drm/nouveau: fix runtime pm imbalance on error + - drm/nouveau/dispnv50: fix runtime pm imbalance on error + - printk: handle blank console arguments passed in. + - usb: dwc3: Increase timeout for CmdAct cleared by device controller + - btrfs: don't force read-only after error in drop snapshot + - btrfs: fix double __endio_write_update_ordered in direct I/O + - gpio: rcar: Fix runtime PM imbalance on error + - vfio/pci: fix memory leaks of eventfd ctx + - KVM: PPC: Book3S HV: Close race with page faults around memslot flushes + - perf evsel: Fix 2 memory leaks + - perf trace: Fix the selection for architectures to generate the errno name + tables + - perf stat: Fix duration_time value for higher intervals + - perf util: Fix memory leak of prefix_if_not_in + - perf metricgroup: Free metric_events on error + - perf kcore_copy: Fix module map when there are no modules loaded + - PCI: tegra194: Fix runtime PM imbalance on error + - ASoC: img-i2s-out: Fix runtime PM imbalance on error + - wlcore: fix runtime pm imbalance in wl1271_tx_work + - wlcore: fix runtime pm imbalance in wlcore_regdomain_config + - mtd: rawnand: gpmi: Fix runtime PM imbalance on error + - mtd: rawnand: omap_elm: Fix runtime PM imbalance on error + - PCI: tegra: Fix runtime PM imbalance on error + - ceph: fix potential race in ceph_check_caps + - mm/swap_state: fix a data race in swapin_nr_pages + - mm: memcontrol: fix stat-corrupting race in charge moving + - rapidio: avoid data race between file operation callbacks and + mport_cdev_add(). + - mtd: parser: cmdline: Support MTD names containing one or more colons + - x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline + - NFS: nfs_xdr_status should record the procedure name + - vfio/pci: Clear error and request eventfd ctx after releasing + - cifs: Fix double add page to memcg when cifs_readpages + - nvme: fix possible deadlock when I/O is blocked + - mac80211: skip mpath lookup also for control port tx + - scsi: libfc: Handling of extra kref + - scsi: libfc: Skip additional kref updating work event + - selftests/x86/syscall_nt: Clear weird flags after each test + - vfio/pci: fix racy on error and request eventfd ctx + - btrfs: qgroup: fix data leak caused by race between writeback and truncate + - perf tests: Fix test 68 zstd compression for s390 + - scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure + - ubi: fastmap: Free unused fastmap anchor peb during detach + - mt76: fix LED link time failure + - opp: Increase parsed_static_opps in _of_add_opp_table_v1() + - perf parse-events: Use strcmp() to compare the PMU name + - ALSA: hda: Always use jackpoll helper for jack update after resume + - ALSA: hda: Workaround for spurious wakeups on some Intel platforms + - net: openvswitch: use div_u64() for 64-by-32 divisions + - nvme: explicitly update mpath disk capacity on revalidation + - device_cgroup: Fix RCU list debugging warning + - ASoC: pcm3168a: ignore 0 Hz settings + - ASoC: wm8994: Skip setting of the WM8994_MICBIAS register for WM1811 + - ASoC: wm8994: Ensure the device is resumed in wm89xx_mic_detect functions + - ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN Converter9 2-in-1 + - RISC-V: Take text_mutex in ftrace_init_nop() + - i2c: aspeed: Mask IRQ status to relevant bits + - s390/init: add missing __init annotations + - lockdep: fix order in trace_hardirqs_off_caller() + - EDAC/ghes: Check whether the driver is on the safe list correctly + - drm/amdkfd: fix a memory leak issue + - drm/amd/display: update nv1x stutter latencies + - drm/amdgpu/dc: Require primary plane to be enabled whenever the CRTC is + - objtool: Fix noreturn detection for ignored functions + - ieee802154: fix one possible memleak in ca8210_dev_com_init + - ieee802154/adf7242: check status of adf7242_read_reg + - clocksource/drivers/h8300_timer8: Fix wrong return value in + h8300_8timer_init() + - batman-adv: bla: fix type misuse for backbone_gw hash indexing + - atm: eni: fix the missed pci_disable_device() for eni_init_one() + - batman-adv: mcast/TT: fix wrongly dropped or rerouted packets + - netfilter: conntrack: nf_conncount_init is failing with IPv6 disabled + - mac802154: tx: fix use-after-free + - bpf: Fix clobbering of r2 in bpf_gen_ld_abs + - drm/vc4/vc4_hdmi: fill ASoC card owner + - net: qed: Disable aRFS for NPAR and 100G + - net: qede: Disable aRFS for NPAR and 100G + - net: qed: RDMA personality shouldn't fail VF load + - drm/sun4i: sun8i-csc: Secondary CSC register correction + - batman-adv: Add missing include for in_interrupt() + - nvme-tcp: fix kconfig dependency warning when !CRYPTO + - batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN + - batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh + - batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh + - bpf: Fix a rcu warning for bpffs map pretty-print + - lib80211: fix unmet direct dependendices config warning when !CRYPTO + - ALSA: asihpi: fix iounmap in error handler + - regmap: fix page selection for noinc reads + - regmap: fix page selection for noinc writes + - MIPS: Add the missing 'CPU_1074K' into __get_cpu_type() + - regulator: axp20x: fix LDO2/4 description + - KVM: x86: Reset MMU context if guest toggles CR4.SMAP or CR4.PKE + - KVM: SVM: Add a dedicated INVD intercept routine + - mm: validate pmd after splitting + - arch/x86/lib/usercopy_64.c: fix __copy_user_flushcache() cache writeback + - x86/ioapic: Unbreak check_timer() + - scsi: lpfc: Fix initial FLOGI failure due to BBSCN not supported + - ALSA: usb-audio: Add delay quirk for H570e USB headsets + - ALSA: hda/realtek - Couldn't detect Mic if booting with headset plugged + - ALSA: hda/realtek: Enable front panel headset LED on Lenovo ThinkStation + P520 + - lib/string.c: implement stpcpy + - tracing: fix double free + - s390/dasd: Fix zero write for FBA devices + - kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() + - kprobes: tracing/kprobes: Fix to kill kprobes on initmem after boot + - btrfs: fix overflow when copying corrupt csums for a message + - dmabuf: fix NULL pointer dereference in dma_buf_release() + - mm, THP, swap: fix allocating cluster for swapfile by mistake + - mm/gup: fix gup_fast with dynamic page table folding + - s390/zcrypt: Fix ZCRYPT_PERDEV_REQCNT ioctl + - KVM: arm64: Assume write fault on S1PTW permission fault on instruction + fetch + - dm: fix bio splitting and its bio completion order for regular IO + - ata: define AC_ERR_OK + - ata: make qc_prep return ata_completion_errors + - ata: sata_mv, avoid trigerrable BUG_ON + - Linux 5.4.69 + * Focal update: v5.4.68 upstream stable release (LP: #1899511) + - af_key: pfkey_dump needs parameter validation + - ibmvnic fix NULL tx_pools and rx_tools issue at do_reset + - ibmvnic: add missing parenthesis in do_reset() + - kprobes: fix kill kprobe which has been marked as gone + - mm/thp: fix __split_huge_pmd_locked() for migration PMD + - act_ife: load meta modules before tcf_idr_check_alloc() + - bnxt_en: Avoid sending firmware messages when AER error is detected. + - bnxt_en: Fix NULL ptr dereference crash in bnxt_fw_reset_task() + - cxgb4: fix memory leak during module unload + - cxgb4: Fix offset when clearing filter byte counters + - geneve: add transport ports in route lookup for geneve + - hdlc_ppp: add range checks in ppp_cp_parse_cr() + - ip: fix tos reflection in ack and reset packets + - ipv4: Initialize flowi4_multipath_hash in data path + - ipv4: Update exception handling for multipath routes via same device + - ipv6: avoid lockdep issue in fib6_del() + - net: bridge: br_vlan_get_pvid_rcu() should dereference the VLAN group under + RCU + - net: DCB: Validate DCB_ATTR_DCB_BUFFER argument + - net: dsa: rtl8366: Properly clear member config + - net: Fix bridge enslavement failure + - net: ipv6: fix kconfig dependency warning for IPV6_SEG6_HMAC + - net/mlx5: Fix FTE cleanup + - net: sch_generic: aviod concurrent reset and enqueue op for lockless qdisc + - net: sctp: Fix IPv6 ancestor_size calc in sctp_copy_descendant + - nfp: use correct define to return NONE fec + - taprio: Fix allowing too small intervals + - tipc: Fix memory leak in tipc_group_create_member() + - tipc: fix shutdown() of connection oriented socket + - tipc: use skb_unshare() instead in tipc_buf_append() + - net/mlx5e: Enable adding peer miss rules only if merged eswitch is supported + - net/mlx5e: TLS, Do not expose FPGA TLS counter if not supported + - bnxt_en: return proper error codes in bnxt_show_temp + - bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. + - net: lantiq: Wake TX queue again + - net: lantiq: use netif_tx_napi_add() for TX NAPI + - net: lantiq: Use napi_complete_done() + - net: lantiq: Disable IRQs only if NAPI gets scheduled + - net: phy: Avoid NPD upon phy_detach() when driver is unbound + - net: phy: Do not warn in phy_stop() on PHY_DOWN + - net: qrtr: check skb_put_padto() return value + - net: add __must_check to skb_put_padto() + - mm: memcg: fix memcg reclaim soft lockup + - iommu/amd: Use cmpxchg_double() when updating 128-bit IRTE + - Linux 5.4.68 + * *-tools-common packages descriptions have typo "PGKVER" (LP: #1898903) + - [Packaging] Fix typo in -tools template s/PGKVER/PKGVER/ + * tc/ebpf: unable to use BPF_FUNC_skb_change_head (LP: #1896504) + - net: bpf: Allow TC programs to call BPF_FUNC_skb_change_head + * HP Zbook Studio G7 boots into corrupted screen with PSR featured panel + (LP: #1897501) + - SAUCE: drm/i915/psr: allow overriding PSR disable param by quirk + - SAUCE: drm/dp: add DP_QUIRK_FORCE_PSR_CHIP_DEFAULT quirk to CMN prod-ID + 19-15 + * Fix broken e1000e device after S3 (LP: #1897755) + - SAUCE: e1000e: Increase polling timeout on MDIC ready bit + * debian/rules editconfigs does not work on s390x to change s390x only configs + (LP: #1863116) + - [Packaging] kernelconfig -- only update/edit configurations on architectures + we have compiler support + * acpi event detection crashes (LP: #1896482) + - ACPI: EC: tweak naming in preparation for GpioInt support + - ACPI: EC: add support for hardware-reduced systems + - ACPI: EC: Avoid passing redundant argument to functions + - ACPI: EC: Consolidate event handler installation code + * mwifiex stops working after kernel upgrade (LP: #1897299) + - mwifiex: Increase AES key storage size to 256 bits + * Remove NVMe suspend-to-idle workaround (LP: #1897227) + - Revert "UBUTU: SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3" + - Revert "UBUNTU: SAUCE: pci: prevent sk hynix nvme from entering D3" + * Request for CIFS patches to be available in 5.4 kernel (LP: #1896642) + - smb3: remove unused flag passed into close functions + - smb3: query attributes on file close + * Lenovo ThinkBook 14-IML Touchpad not showing up in /proc/bus/input/devices + (LP: #1853277) + - i2c: core: Call i2c_acpi_install_space_handler() before + i2c_acpi_register_devices() + * [Ubuntu 20.10] zPCI DMA tables and bitmap leak on hard unplug (PCI Event + 0x0304) (LP: #1896216) + - s390/pci: fix leak of DMA tables on hard unplug + * Thunderbolt3 daisy chain sometimes doesn't work (LP: #1895606) + - thunderbolt: Retry DROM read once if parsing fails + * btrfs: trimming a btrfs device which has been shrunk previously fails and + fills root disk with garbage data (LP: #1896154) + - btrfs: trim: fix underflow in trim length to prevent access beyond device + boundary + * EFA: add support for 0xefa1 devices (LP: #1896791) + - RDMA/efa: Expose maximum TX doorbell batch + - RDMA/efa: Expose minimum SQ size + - RDMA/efa: User/kernel compatibility handshake mechanism + - RDMA/efa: Add EFA 0xefa1 PCI ID + * Focal update: v5.4.67 upstream stable release (LP: #1896828) + - gfs2: initialize transaction tr_ailX_lists earlier + - RDMA/bnxt_re: Restrict the max_gids to 256 + - dsa: Allow forwarding of redirected IGMP traffic + - net: handle the return value of pskb_carve_frag_list() correctly + - hv_netvsc: Remove "unlikely" from netvsc_select_queue + - firmware_loader: fix memory leak for paged buffer + - NFSv4.1 handle ERR_DELAY error reclaiming locking state on delegation recall + - scsi: pm8001: Fix memleak in pm8001_exec_internal_task_abort + - scsi: libfc: Fix for double free() + - scsi: lpfc: Fix FLOGI/PLOGI receive race condition in pt2pt discovery + - regulator: pwm: Fix machine constraints application + - spi: spi-loopback-test: Fix out-of-bounds read + - NFS: Zero-stateid SETATTR should first return delegation + - SUNRPC: stop printk reading past end of string + - rapidio: Replace 'select' DMAENGINES 'with depends on' + - cifs: fix DFS mount with cifsacl/modefromsid + - openrisc: Fix cache API compile issue when not inlining + - nvme-fc: cancel async events before freeing event struct + - nvme-rdma: cancel async events before freeing event struct + - nvme-tcp: cancel async events before freeing event struct + - block: only call sched requeue_request() for scheduled requests + - f2fs: fix indefinite loop scanning for free nid + - f2fs: Return EOF on unaligned end of file DIO read + - i2c: algo: pca: Reapply i2c bus settings after reset + - spi: Fix memory leak on splited transfers + - KVM: MIPS: Change the definition of kvm type + - clk: davinci: Use the correct size when allocating memory + - clk: rockchip: Fix initialization of mux_pll_src_4plls_p + - ASoC: qcom: Set card->owner to avoid warnings + - ASoC: qcom: common: Fix refcount imbalance on error + - powerpc/book3s64/radix: Fix boot failure with large amount of guest memory + - ASoC: meson: axg-toddr: fix channel order on g12 platforms + - Drivers: hv: vmbus: hibernation: do not hang forever in vmbus_bus_resume() + - scsi: libsas: Fix error path in sas_notify_lldd_dev_found() + - arm64: Allow CPUs unffected by ARM erratum 1418040 to come in late + - Drivers: hv: vmbus: Add timeout to vmbus_wait_for_unload + - perf test: Fix the "signal" test inline assembly + - MIPS: SNI: Fix MIPS_L1_CACHE_SHIFT + - perf evlist: Fix cpu/thread map leak + - perf parse-event: Fix memory leak in evsel->unit + - perf test: Free formats for perf pmu parse test + - fbcon: Fix user font detection test at fbcon_resize(). + - MIPS: SNI: Fix spurious interrupts + - drm/mediatek: Add exception handing in mtk_drm_probe() if component init + fail + - drm/mediatek: Add missing put_device() call in mtk_hdmi_dt_parse_pdata() + - arm64: bpf: Fix branch offset in JIT + - iommu/amd: Fix potential @entry null deref + - i2c: mxs: use MXS_DMA_CTRL_WAIT4END instead of DMA_CTRL_ACK + - riscv: Add sfence.vma after early page table changes + - drm/i915: Filter wake_flags passed to default_wake_function + - USB: quirks: Add USB_QUIRK_IGNORE_REMOTE_WAKEUP quirk for BYD zhaoxin + notebook + - USB: UAS: fix disconnect by unplugging a hub + - usblp: fix race between disconnect() and read() + - i2c: i801: Fix resume bug + - Revert "ALSA: hda - Fix silent audio output and corrupted input on MSI + X570-A PRO" + - ALSA: hda: fixup headset for ASUS GX502 laptop + - ALSA: hda/realtek - The Mic on a RedmiBook doesn't work + - percpu: fix first chunk size calculation for populated bitmap + - Input: trackpoint - add new trackpoint variant IDs + - Input: i8042 - add Entroware Proteus EL07R4 to nomux and reset lists + - serial: 8250_pci: Add Realtek 816a and 816b + - x86/boot/compressed: Disable relocation relaxation + - s390/zcrypt: fix kmalloc 256k failure + - ehci-hcd: Move include to keep CRC stable + - powerpc/dma: Fix dma_map_ops::get_required_mask + - selftests/vm: fix display of page size in map_hugetlb + - dm/dax: Fix table reference counts + - mm/memory_hotplug: drain per-cpu pages again during memory offline + - dm: Call proper helper to determine dax support + - dax: Fix compilation for CONFIG_DAX && !CONFIG_FS_DAX + - Linux 5.4.67 + * Focal update: v5.4.67 upstream stable release (LP: #1896828) // Cherry Pick + needed for Critical upstream patch for Kernel null pointer dereference - + usb-c altmode (LP: #1897963) + - usb: typec: ucsi: Prevent mode overrun + * Focal update: v5.4.66 upstream stable release (LP: #1896824) + - ARM: dts: logicpd-torpedo-baseboard: Fix broken audio + - ARM: dts: logicpd-som-lv-baseboard: Fix broken audio + - ARM: dts: logicpd-som-lv-baseboard: Fix missing video + - regulator: push allocation in regulator_ena_gpio_request() out of lock + - regulator: remove superfluous lock in regulator_resolve_coupling() + - ARM: dts: socfpga: fix register entry for timer3 on Arria10 + - ARM: dts: ls1021a: fix QuadSPI-memory reg range + - ARM: dts: imx7ulp: Correct gpio ranges + - RDMA/rxe: Fix memleak in rxe_mem_init_user + - RDMA/rxe: Drop pointless checks in rxe_init_ports + - RDMA/rxe: Fix panic when calling kmem_cache_create() + - RDMA/bnxt_re: Do not report transparent vlan from QP1 + - drm/sun4i: add missing put_device() call in sun8i_r40_tcon_tv_set_mux() + - arm64: dts: imx8mq: Fix TMU interrupt property + - drm/sun4i: Fix dsi dcs long write function + - iio: adc: mcp3422: fix locking on error path + - iio: adc: mcp3422: fix locking scope + - scsi: libsas: Set data_dir as DMA_NONE if libata marks qc as NODATA + - RDMA/core: Fix reported speed and width + - scsi: megaraid_sas: Don't call disable_irq from process IRQ poll + - scsi: mpt3sas: Don't call disable_irq from IRQ poll handler + - soundwire: fix double free of dangling pointer + - drm/sun4i: backend: Support alpha property on lowest plane + - drm/sun4i: backend: Disable alpha on the lowest plane on the A20 + - mmc: sdhci-acpi: Clear amd_sdhci_host on reset + - mmc: sdhci-msm: Add retries when all tuning phases are found valid + - spi: stm32: Rate-limit the 'Communication suspended' message + - nvme-fabrics: allow to queue requests for live queues + - spi: stm32: fix pm_runtime_get_sync() error checking + - block: Set same_page to false in __bio_try_merge_page if ret is false + - IB/isert: Fix unaligned immediate-data handling + - ARM: dts: bcm: HR2: Fixed QSPI compatible string + - ARM: dts: NSP: Fixed QSPI compatible string + - ARM: dts: BCM5301X: Fixed QSPI compatible string + - arm64: dts: ns2: Fixed QSPI compatible string + - ARC: HSDK: wireup perf irq + - dmaengine: acpi: Put the CSRT table after using it + - netfilter: conntrack: allow sctp hearbeat after connection re-use + - drivers/net/wan/lapbether: Added needed_tailroom + - NFC: st95hf: Fix memleak in st95hf_in_send_cmd + - firestream: Fix memleak in fs_open + - ALSA: hda: Fix 2 channel swapping for Tegra + - ALSA: hda/tegra: Program WAKEEN register for Tegra + - drivers/dma/dma-jz4780: Fix race condition between probe and irq handler + - net: hns3: Fix for geneve tx checksum bug + - xfs: fix off-by-one in inode alloc block reservation calculation + - drivers/net/wan/lapbether: Set network_header before transmitting + - cfg80211: Adjust 6 GHz frequency to channel conversion + - xfs: initialize the shortform attr header padding entry + - irqchip/eznps: Fix build error for !ARC700 builds + - nvmet-tcp: Fix NULL dereference when a connect data comes in h2cdata pdu + - nvme-fabrics: don't check state NVME_CTRL_NEW for request acceptance + - nvme: have nvme_wait_freeze_timeout return if it timed out + - nvme-tcp: serialize controller teardown sequences + - nvme-tcp: fix timeout handler + - nvme-tcp: fix reset hang if controller died in the middle of a reset + - nvme-rdma: serialize controller teardown sequences + - nvme-rdma: fix timeout handler + - nvme-rdma: fix reset hang if controller died in the middle of a reset + - nvme-pci: cancel nvme device request before disabling + - HID: quirks: Set INCREMENT_USAGE_ON_DUPLICATE for all Saitek X52 devices + - HID: microsoft: Add rumble support for the 8bitdo SN30 Pro+ controller + - drivers/net/wan/hdlc_cisco: Add hard_header_len + - HID: elan: Fix memleak in elan_input_configured + - ARC: [plat-hsdk]: Switch ethernet phy-mode to rgmii-id + - cpufreq: intel_pstate: Refuse to turn off with HWP enabled + - cpufreq: intel_pstate: Fix intel_pstate_get_hwp_max() for turbo disabled + - arm64/module: set trampoline section flags regardless of + CONFIG_DYNAMIC_FTRACE + - ALSA: hda: hdmi - add Rocketlake support + - ALSA: hda: fix a runtime pm issue in SOF when integrated GPU is disabled + - drm/amdgpu: Fix bug in reporting voltage for CIK + - iommu/amd: Do not use IOMMUv2 functionality when SME is active + - gcov: Disable gcov build with GCC 10 + - iio: adc: ti-ads1015: fix conversion when CONFIG_PM is not set + - iio: cros_ec: Set Gyroscope default frequency to 25Hz + - iio:light:ltr501 Fix timestamp alignment issue. + - iio:proximity:mb1232: Fix timestamp alignment and prevent data leak. + - iio:accel:bmc150-accel: Fix timestamp alignment and prevent data leak. + - iio:adc:ti-adc084s021 Fix alignment and data leak issues. + - iio:adc:ina2xx Fix timestamp alignment issue. + - iio:adc:max1118 Fix alignment of timestamp and data leak issues + - iio:adc:ti-adc081c Fix alignment and data leak issues + - iio:magnetometer:ak8975 Fix alignment and data leak issues. + - iio:light:max44000 Fix timestamp alignment and prevent data leak. + - iio:chemical:ccs811: Fix timestamp alignment and prevent data leak. + - iio: accel: kxsd9: Fix alignment of local buffer. + - iio:accel:mma7455: Fix timestamp alignment and prevent data leak. + - iio:accel:mma8452: Fix timestamp alignment and prevent data leak. + - staging: wlan-ng: fix out of bounds read in prism2sta_probe_usb() + - btrfs: require only sector size alignment for parent eb bytenr + - btrfs: fix lockdep splat in add_missing_dev + - btrfs: fix wrong address when faulting in pages in the search ioctl + - kobject: Restore old behaviour of kobject_del(NULL) + - regulator: push allocation in regulator_init_coupling() outside of lock + - regulator: push allocations in create_regulator() outside of lock + - regulator: push allocation in set_consumer_device_supply() out of lock + - regulator: plug of_node leak in regulator_register()'s error path + - regulator: core: Fix slab-out-of-bounds in regulator_unlock_recursive() + - scsi: target: iscsi: Fix data digest calculation + - scsi: target: iscsi: Fix hang in iscsit_access_np() when getting + tpg->np_login_sem + - drm/i915/gvt: do not check len & max_len for lri + - drm/tve200: Stabilize enable/disable + - drm/msm: Disable preemption on all 5xx targets + - mmc: sdio: Use mmc_pre_req() / mmc_post_req() + - mmc: sdhci-of-esdhc: Don't walk device-tree on every interrupt + - rbd: require global CAP_SYS_ADMIN for mapping and unmapping + - RDMA/rxe: Fix the parent sysfs read when the interface has 15 chars + - RDMA/mlx4: Read pkey table length instead of hardcoded value + - fbcon: remove soft scrollback code + - fbcon: remove now unusued 'softback_lines' cursor() argument + - vgacon: remove software scrollback support + - [Config] updateconfigs for VGACON_SOFT_SCROLLBACK + - KVM: VMX: Don't freeze guest when event delivery causes an APIC-access exit + - KVM: arm64: Do not try to map PUDs when they are folded into PMD + - KVM: fix memory leak in kvm_io_bus_unregister_dev() + - debugfs: Fix module state check condition + - ARM: dts: vfxxx: Add syscon compatible with OCOTP + - video: fbdev: fix OOB read in vga_8planes_imageblit() + - staging: greybus: audio: fix uninitialized value issue + - phy: qcom-qmp: Use correct values for ipq8074 PCIe Gen2 PHY init + - usb: core: fix slab-out-of-bounds Read in read_descriptors + - USB: serial: ftdi_sio: add IDs for Xsens Mti USB converter + - USB: serial: option: support dynamic Quectel USB compositions + - USB: serial: option: add support for SIM7070/SIM7080/SIM7090 modules + - usb: Fix out of sync data toggle if a configured device is reconfigured + - usb: typec: ucsi: acpi: Check the _DEP dependencies + - drm/msm/gpu: make ringbuffer readonly + - drm/msm: Disable the RPTR shadow + - gcov: add support for GCC 10.1 + - Linux 5.4.66 + + [ Ubuntu: 5.4.0-54.60 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + * Introduce the new NVIDIA 455 series (LP: #1902093) + - [Packaging] NVIDIA -- Add the NVIDIA 455 driver + + -- Kleber Sacilotto de Souza Fri, 13 Nov 2020 13:15:32 +0100 + +linux-oracle (5.4.0-1029.31) focal; urgency=medium + + * CVE-2020-12351 // CVE-2020-12352 // CVE-2020-24490 + - [Config] oracle: Disable BlueZ highspeed support + + [ Ubuntu: 5.4.0-53.59 ] + + * CVE-2020-8694 + - powercap: make attributes only readable by root + + [ Ubuntu: 5.4.0-52.57 ] + + * focal/linux: 5.4.0-52.57 -proposed tracker (LP: #1899920) + * CVE-2020-12351 // CVE-2020-12352 // CVE-2020-24490 + - Bluetooth: Disable High Speed by default + - Bluetooth: MGMT: Fix not checking if BT_HS is enabled + - [Config] Disable BlueZ highspeed support + * CVE-2020-12351 + - Bluetooth: L2CAP: Fix calling sk_filter on non-socket based channel + * CVE-2020-12352 + - Bluetooth: A2MP: Fix not initializing all members + + -- Kleber Sacilotto de Souza Wed, 21 Oct 2020 14:51:22 +0200 + +linux-oracle (5.4.0-1028.29) focal; urgency=medium + + [ Ubuntu: 5.4.0-51.56 ] + + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Tue, 06 Oct 2020 11:52:22 +0200 + +linux-oracle (5.4.0-1027.28) focal; urgency=medium + + [ Ubuntu: 5.4.0-50.55 ] + + * CVE-2020-16119 + - SAUCE: dccp: avoid double free of ccid on child socket + * CVE-2020-16120 + - Revert "UBUNTU: SAUCE: overlayfs: ensure mounter privileges when reading + directories" + - ovl: pass correct flags for opening real directory + - ovl: switch to mounter creds in readdir + - ovl: verify permissions in ovl_path_open() + - ovl: call secutiry hook in ovl_real_ioctl() + - ovl: check permission to open real file + + -- Kleber Sacilotto de Souza Thu, 01 Oct 2020 11:14:15 +0200 + +linux-oracle (5.4.0-1026.26) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1026.26 -proposed tracker (LP: #1896002) + + * Focal update: v5.4.61 upstream stable release (LP: #1893115) + - oracle: [Config] update config for SPI_DYNAMIC + + [ Ubuntu: 5.4.0-49.53 ] + + * focal/linux: 5.4.0-49.53 -proposed tracker (LP: #1896007) + * Comet Lake PCH-H RAID not support on Ubuntu20.04 (LP: #1892288) + - ahci: Add Intel Comet Lake PCH-H PCI ID + * Novalink (mkvterm command failure) (LP: #1892546) + - tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup() + * Oops and hang when starting LVM snapshots on 5.4.0-47 (LP: #1894780) + - SAUCE: Revert "mm: memcg/slab: fix memory leak at non-root kmem_cache + destroy" + * Intel x710 LOMs do not work on Focal (LP: #1893956) + - i40e: Fix LED blinking flow for X710T*L devices + - i40e: enable X710 support + * Add/Backport EPYC-v3 and EPYC-Rome CPU model (LP: #1887490) + - kvm: svm: Update svm_xsaves_supported + * Fix non-working NVMe after S3 (LP: #1895718) + - SAUCE: PCI: Enable ACS quirk on CML root port + * Focal update: v5.4.65 upstream stable release (LP: #1895881) + - ipv4: Silence suspicious RCU usage warning + - ipv6: Fix sysctl max for fib_multipath_hash_policy + - netlabel: fix problems with mapping removal + - net: usb: dm9601: Add USB ID of Keenetic Plus DSL + - sctp: not disable bh in the whole sctp_get_port_local() + - taprio: Fix using wrong queues in gate mask + - tipc: fix shutdown() of connectionless socket + - net: disable netpoll on fresh napis + - Linux 5.4.65 + * Focal update: v5.4.64 upstream stable release (LP: #1895880) + - HID: quirks: Always poll three more Lenovo PixArt mice + - drm/msm/dpu: Fix scale params in plane validation + - tty: serial: qcom_geni_serial: Drop __init from qcom_geni_console_setup + - drm/msm: add shutdown support for display platform_driver + - hwmon: (applesmc) check status earlier. + - nvmet: Disable keep-alive timer when kato is cleared to 0h + - drm/msm: enable vblank during atomic commits + - habanalabs: validate FW file size + - habanalabs: check correct vmalloc return code + - drm/msm/a6xx: fix gmu start on newer firmware + - ceph: don't allow setlease on cephfs + - drm/omap: fix incorrect lock state + - cpuidle: Fixup IRQ state + - nbd: restore default timeout when setting it to zero + - s390: don't trace preemption in percpu macros + - drm/amd/display: Reject overlay plane configurations in multi-display + scenarios + - drivers: gpu: amd: Initialize amdgpu_dm_backlight_caps object to 0 in + amdgpu_dm_update_backlight_caps + - drm/amd/display: Retry AUX write when fail occurs + - drm/amd/display: Fix memleak in amdgpu_dm_mode_config_init + - xen/xenbus: Fix granting of vmalloc'd memory + - fsldma: fix very broken 32-bit ppc ioread64 functionality + - dmaengine: of-dma: Fix of_dma_router_xlate's of_dma_xlate handling + - batman-adv: Avoid uninitialized chaddr when handling DHCP + - batman-adv: Fix own OGM check in aggregated OGMs + - batman-adv: bla: use netif_rx_ni when not in interrupt context + - dmaengine: at_hdmac: check return value of of_find_device_by_node() in + at_dma_xlate() + - rxrpc: Keep the ACK serial in a var in rxrpc_input_ack() + - rxrpc: Make rxrpc_kernel_get_srtt() indicate validity + - MIPS: mm: BMIPS5000 has inclusive physical caches + - MIPS: BMIPS: Also call bmips_cpu_setup() for secondary cores + - mmc: sdhci-acpi: Fix HS400 tuning for AMDI0040 + - netfilter: nf_tables: add NFTA_SET_USERDATA if not null + - netfilter: nf_tables: incorrect enum nft_list_attributes definition + - netfilter: nf_tables: fix destination register zeroing + - net: hns: Fix memleak in hns_nic_dev_probe + - net: systemport: Fix memleak in bcm_sysport_probe + - ravb: Fixed to be able to unload modules + - net: arc_emac: Fix memleak in arc_mdio_probe + - dmaengine: pl330: Fix burst length if burst size is smaller than bus width + - gtp: add GTPA_LINK info to msg sent to userspace + - net: ethernet: ti: cpsw: fix clean up of vlan mc entries for host port + - bnxt_en: Don't query FW when netif_running() is false. + - bnxt_en: Check for zero dir entries in NVRAM. + - bnxt_en: Fix PCI AER error recovery flow + - bnxt_en: Fix possible crash in bnxt_fw_reset_task(). + - bnxt_en: fix HWRM error when querying VF temperature + - xfs: fix boundary test in xfs_attr_shortform_verify + - bnxt: don't enable NAPI until rings are ready + - media: vicodec: add missing v4l2_ctrl_request_hdl_put() + - media: cedrus: Add missing v4l2_ctrl_request_hdl_put() + - selftests/bpf: Fix massive output from test_maps + - net: dsa: mt7530: fix advertising unsupported 1000baseT_Half + - netfilter: nfnetlink: nfnetlink_unicast() reports EAGAIN instead of ENOBUFS + - nvmet-fc: Fix a missed _irqsave version of spin_lock in + 'nvmet_fc_fod_op_done()' + - nvme: fix controller instance leak + - cxgb4: fix thermal zone device registration + - perf tools: Correct SNOOPX field offset + - net: ethernet: mlx4: Fix memory allocation in mlx4_buddy_init() + - fix regression in "epoll: Keep a reference on files added to the check list" + - net: gemini: Fix another missing clk_disable_unprepare() in probe + - MIPS: add missing MSACSR and upper MSA initialization + - xfs: fix xfs_bmap_validate_extent_raw when checking attr fork of rt files + - perf jevents: Fix suspicious code in fixregex() + - tg3: Fix soft lockup when tg3_reset_task() fails. + - x86, fakenuma: Fix invalid starting node ID + - iommu/vt-d: Serialize IOMMU GCMD register modifications + - thermal: ti-soc-thermal: Fix bogus thermal shutdowns for omap4430 + - thermal: qcom-spmi-temp-alarm: Don't suppress negative temp + - iommu/amd: Restore IRTE.RemapEn bit after programming IRTE + - include/linux/log2.h: add missing () around n in roundup_pow_of_two() + - iommu/vt-d: Handle 36bit addressing for x86-32 + - tracing/kprobes, x86/ptrace: Fix regs argument order for i386 + - ext2: don't update mtime on COW faults + - xfs: don't update mtime on COW faults + - ARC: perf: don't bail setup if pct irq missing in device-tree + - btrfs: drop path before adding new uuid tree entry + - btrfs: allocate scrub workqueues outside of locks + - btrfs: set the correct lockdep class for new nodes + - btrfs: set the lockdep class for log tree extent buffers + - btrfs: tree-checker: fix the error message for transid error + - net: core: use listified Rx for GRO_NORMAL in napi_gro_receive() + - btrfs: fix potential deadlock in the search ioctl + - ALSA: ca0106: fix error code handling + - ALSA: usb-audio: Add implicit feedback quirk for UR22C + - ALSA: pcm: oss: Remove superfluous WARN_ON() for mulaw sanity check + - ALSA: hda/hdmi: always check pin power status in i915 pin fixup + - ALSA: firewire-digi00x: exclude Avid Adrenaline from detection + - ALSA: hda - Fix silent audio output and corrupted input on MSI X570-A PRO + - ALSA; firewire-tascam: exclude Tascam FE-8 from detection + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Book Ion NT950XCJ-X716A + - ALSA: hda/realtek - Improved routing for Thinkpad X1 7th/8th Gen + - arm64: dts: mt7622: add reset node for mmc device + - mmc: mediatek: add optional module reset property + - mmc: dt-bindings: Add resets/reset-names for Mediatek MMC bindings + - mmc: cqhci: Add cqhci_deactivate() + - mmc: sdhci-pci: Fix SDHCI_RESET_ALL for CQHCI for Intel GLK-based + controllers + - media: rc: do not access device via sysfs after rc_unregister_device() + - media: rc: uevent sysfs file races with rc_unregister_device() + - affs: fix basic permission bits to actually work + - block: allow for_each_bvec to support zero len bvec + - block: ensure bdi->io_pages is always initialized + - libata: implement ATA_HORKAGE_MAX_TRIM_128M and apply to Sandisks + - blk-iocost: ioc_pd_free() shouldn't assume irq disabled + - dmaengine: dw-edma: Fix scatter-gather address calculation + - drm/amd/pm: avoid false alarm due to confusing softwareshutdowntemp setting + - dm writecache: handle DAX to partitions on persistent memory correctly + - dm mpath: fix racey management of PG initialization + - dm integrity: fix error reporting in bitmap mode after creation + - dm crypt: Initialize crypto wait structures + - dm cache metadata: Avoid returning cmd->bm wild pointer on error + - dm thin metadata: Avoid returning cmd->bm wild pointer on error + - dm thin metadata: Fix use-after-free in dm_bm_set_read_only + - mm: slub: fix conversion of freelist_corrupted() + - mm: madvise: fix vma user-after-free + - vfio/pci: Fix SR-IOV VF handling with MMIO blocking + - perf record: Correct the help info of option "--no-bpf-event" + - sdhci: tegra: Add missing TMCLK for data timeout + - checkpatch: fix the usage of capture group ( ... ) + - mm/hugetlb: fix a race between hugetlb sysctl handlers + - mm/khugepaged.c: fix khugepaged's request size in collapse_file + - cfg80211: regulatory: reject invalid hints + - net: usb: Fix uninit-was-stored issue in asix_read_phy_addr() + - Linux 5.4.64 + * Focal update: v5.4.63 upstream stable release (LP: #1895879) + - HID: core: Correctly handle ReportSize being zero + - HID: core: Sanitize event code and type when mapping input + - perf record/stat: Explicitly call out event modifiers in the documentation + - drm/sched: Fix passing zero to 'PTR_ERR' warning v2 + - drm/etnaviv: fix TS cache flushing on GPUs with BLT engine + - KVM: arm64: Add kvm_extable for vaxorcism code + - KVM: arm64: Survive synchronous exceptions caused by AT instructions + - KVM: arm64: Set HCR_EL2.PTW to prevent AT taking synchronous exception + - dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later + - arm64: tegra: Add missing timeout clock to Tegra194 SDMMC nodes + - arm64: tegra: Add missing timeout clock to Tegra186 SDMMC nodes + - arm64: tegra: Add missing timeout clock to Tegra210 SDMMC + - sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210 + - sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186 + - scsi: target: tcmu: Fix size in calls to tcmu_flush_dcache_range + - scsi: target: tcmu: Optimize use of flush_dcache_page + - Linux 5.4.63 + * Focal update: v5.4.62 upstream stable release (LP: #1895174) + - binfmt_flat: revert "binfmt_flat: don't offset the data start" + - gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY + - net: Fix potential wrong skb->protocol in skb_vlan_untag() + - net: nexthop: don't allow empty NHA_GROUP + - net: qrtr: fix usage of idr in port assignment to socket + - net: sctp: Fix negotiation of the number of data streams. + - net/smc: Prevent kernel-infoleak in __smc_diag_dump() + - tipc: fix uninit skb->data in tipc_nl_compat_dumpit() + - net: ena: Make missed_tx stat incremental + - net/sched: act_ct: Fix skb double-free in tcf_ct_handle_fragments() error + flow + - ipvlan: fix device features + - ALSA: pci: delete repeated words in comments + - ASoC: img: Fix a reference count leak in img_i2s_in_set_fmt + - ASoC: img-parallel-out: Fix a reference count leak + - ASoC: tegra: Fix reference count leaks. + - mfd: intel-lpss: Add Intel Emmitsburg PCH PCI IDs + - arm64: dts: qcom: msm8916: Pull down PDM GPIOs during sleep + - powerpc/xive: Ignore kmemleak false positives + - media: pci: ttpci: av7110: fix possible buffer overflow caused by bad DMA + value in debiirq() + - blktrace: ensure our debugfs dir exists + - scsi: target: tcmu: Fix crash on ARM during cmd completion + - mfd: intel-lpss: Add Intel Tiger Lake PCH-H PCI IDs + - iommu/iova: Don't BUG on invalid PFNs + - drm/amdkfd: Fix reference count leaks. + - drm/radeon: fix multiple reference count leak + - drm/amdgpu: fix ref count leak in amdgpu_driver_open_kms + - drm/amd/display: fix ref count leak in amdgpu_drm_ioctl + - drm/amdgpu: fix ref count leak in amdgpu_display_crtc_set_config + - drm/amdgpu/display: fix ref count leak when pm_runtime_get_sync fails + - scsi: lpfc: Fix shost refcount mismatch when deleting vport + - xfs: Don't allow logging of XFS_ISTALE inodes + - scsi: target: Fix xcopy sess release leak + - selftests/powerpc: Purge extra count_pmc() calls of ebb selftests + - f2fs: fix error path in do_recover_data() + - omapfb: fix multiple reference count leaks due to pm_runtime_get_sync + - PCI: Fix pci_create_slot() reference count leak + - ARM: dts: ls1021a: output PPS signal on FIPER2 + - rtlwifi: rtl8192cu: Prevent leaking urb + - mips/vdso: Fix resource leaks in genvdso.c + - cec-api: prevent leaking memory through hole in structure + - HID: quirks: add NOGET quirk for Logitech GROUP + - f2fs: fix use-after-free issue + - drm/nouveau/drm/noveau: fix reference count leak in nouveau_fbcon_open + - drm/nouveau: fix reference count leak in nv50_disp_atomic_commit + - drm/nouveau: Fix reference count leak in nouveau_connector_detect + - locking/lockdep: Fix overflow in presentation of average lock-time + - btrfs: file: reserve qgroup space after the hole punch range is locked + - btrfs: make btrfs_qgroup_check_reserved_leak take btrfs_inode + - scsi: iscsi: Do not put host in iscsi_set_flashnode_param() + - ceph: fix potential mdsc use-after-free crash + - ceph: do not access the kiocb after aio requests + - scsi: fcoe: Memory leak fix in fcoe_sysfs_fcf_del() + - EDAC/ie31200: Fallback if host bridge device is already initialized + - hugetlbfs: prevent filesystem stacking of hugetlbfs + - media: davinci: vpif_capture: fix potential double free + - KVM: arm64: Fix symbol dependency in __hyp_call_panic_nvhe + - powerpc/spufs: add CONFIG_COREDUMP dependency + - USB: sisusbvga: Fix a potential UB casued by left shifting a negative value + - brcmfmac: Set timeout value when configuring power save + - efi: provide empty efi_enter_virtual_mode implementation + - arm64: Fix __cpu_logical_map undefined issue + - Revert "ath10k: fix DMA related firmware crashes on multiple devices" + - sched/uclamp: Protect uclamp fast path code with static key + - sched/uclamp: Fix a deadlock when enabling uclamp static key + - usb: cdns3: gadget: always zeroed TRB buffer when enable endpoint + - PM / devfreq: rk3399_dmc: Add missing of_node_put() + - PM / devfreq: rk3399_dmc: Disable devfreq-event device when fails + - PM / devfreq: rk3399_dmc: Fix kernel oops when rockchip,pmu is absent + - drm/xen: fix passing zero to 'PTR_ERR' warning + - drm/xen-front: Fix misused IS_ERR_OR_NULL checks + - s390/numa: set node distance to LOCAL_DISTANCE + - btrfs: factor out inode items copy loop from btrfs_log_inode() + - btrfs: only commit the delayed inode when doing a full fsync + - btrfs: only commit delayed items at fsync if we are logging a directory + - mm/shuffle: don't move pages between zones and don't read garbage memmaps + - mm: fix kthread_use_mm() vs TLB invalidate + - mm/cma.c: switch to bitmap_zalloc() for cma bitmap allocation + - cma: don't quit at first error when activating reserved areas + - gpu/drm: ingenic: Use the plane's src_[x,y] to configure DMA length + - drm/ingenic: Fix incorrect assumption about plane->index + - drm/amd/display: Trigger modesets on MST DSC connectors + - drm/amd/display: Add additional config guards for DCN + - drm/amd/display: Fix dmesg warning from setting abm level + - mm/vunmap: add cond_resched() in vunmap_pmd_range + - EDAC: sb_edac: get rid of unused vars + - EDAC: skx_common: get rid of unused type var + - EDAC/{i7core,sb,pnd2,skx}: Fix error event severity + - PCI: qcom: Add missing ipq806x clocks in PCIe driver + - PCI: qcom: Change duplicate PCI reset to phy reset + - PCI: qcom: Add missing reset for ipq806x + - cpufreq: intel_pstate: Fix EPP setting via sysfs in active mode + - ALSA: usb-audio: Add capture support for Saffire 6 (USB 1.1) + - media: gpio-ir-tx: improve precision of transmitted signal due to scheduling + - block: respect queue limit of max discard segment + - block: virtio_blk: fix handling single range discard request + - drm/msm/adreno: fix updating ring fence + - block: Fix page_is_mergeable() for compound pages + - bfq: fix blkio cgroup leakage v4 + - hwmon: (nct7904) Correct divide by 0 + - blk-mq: insert request not through ->queue_rq into sw/scheduler queue + - blkcg: fix memleak for iolatency + - nvme-fc: Fix wrong return value in __nvme_fc_init_request() + - nvme: multipath: round-robin: fix single non-optimized path case + - null_blk: fix passing of REQ_FUA flag in null_handle_rq + - i2c: core: Don't fail PRP0001 enumeration when no ID table exist + - i2c: rcar: in slave mode, clear NACK earlier + - usb: gadget: f_tcm: Fix some resource leaks in some error paths + - spi: stm32: clear only asserted irq flags on interrupt + - jbd2: make sure jh have b_transaction set in refile/unfile_buffer + - ext4: don't BUG on inconsistent journal feature + - ext4: handle read only external journal device + - jbd2: abort journal if free a async write error metadata buffer + - ext4: handle option set by mount flags correctly + - ext4: handle error of ext4_setup_system_zone() on remount + - ext4: correctly restore system zone info when remount fails + - fs: prevent BUG_ON in submit_bh_wbc() + - spi: stm32h7: fix race condition at end of transfer + - spi: stm32: fix fifo threshold level in case of short transfer + - spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate + - spi: stm32: always perform registers configuration prior to transfer + - drm/amd/powerplay: correct Vega20 cached smu feature state + - drm/amd/powerplay: correct UVD/VCE PG state on custom pptable uploading + - drm/amd/display: Switch to immediate mode for updating infopackets + - netfilter: avoid ipv6 -> nf_defrag_ipv6 module dependency + - can: j1939: transport: j1939_xtp_rx_dat_one(): compare own packets to detect + corruptions + - ALSA: hda/realtek: Add model alc298-samsung-headphone + - s390/cio: add cond_resched() in the slow_eval_known_fn() loop + - ASoC: wm8994: Avoid attempts to read unreadable registers + - selftests: disable rp_filter for icmp_redirect.sh + - scsi: fcoe: Fix I/O path allocation + - scsi: ufs: Fix possible infinite loop in ufshcd_hold + - scsi: ufs: Improve interrupt handling for shared interrupts + - scsi: ufs: Clean up completed request without interrupt notification + - scsi: qla2xxx: Fix login timeout + - scsi: qla2xxx: Check if FW supports MQ before enabling + - scsi: qla2xxx: Fix null pointer access during disconnect from subsystem + - Revert "scsi: qla2xxx: Fix crash on qla2x00_mailbox_command" + - macvlan: validate setting of multiple remote source MAC addresses + - net: gianfar: Add of_node_put() before goto statement + - powerpc/perf: Fix soft lockups due to missed interrupt accounting + - arm64: Move handling of erratum 1418040 into C code + - arm64: Allow booting of late CPUs affected by erratum 1418040 + - block: fix get_max_io_size() + - block: loop: set discard granularity and alignment for block device backed + loop + - HID: i2c-hid: Always sleep 60ms after I2C_HID_PWR_ON commands + - blk-mq: order adding requests to hctx->dispatch and checking SCHED_RESTART + - btrfs: reset compression level for lzo on remount + - btrfs: check the right error variable in btrfs_del_dir_entries_in_log + - btrfs: fix space cache memory leak after transaction abort + - btrfs: detect nocow for swap after snapshot delete + - fbcon: prevent user font height or width change from causing potential out- + of-bounds access + - USB: lvtest: return proper error code in probe + - vt: defer kfree() of vc_screenbuf in vc_do_resize() + - vt_ioctl: change VT_RESIZEX ioctl to check for error return from vc_resize() + - serial: samsung: Removes the IRQ not found warning + - serial: pl011: Fix oops on -EPROBE_DEFER + - serial: pl011: Don't leak amba_ports entry on driver register error + - serial: stm32: avoid kernel warning on absence of optional IRQ + - serial: 8250_exar: Fix number of ports for Commtech PCIe cards + - serial: 8250: change lock order in serial8250_do_startup() + - writeback: Protect inode->i_io_list with inode->i_lock + - writeback: Avoid skipping inode writeback + - writeback: Fix sync livelock due to b_dirty_time processing + - XEN uses irqdesc::irq_data_common::handler_data to store a per interrupt XEN + data pointer which contains XEN specific information. + - usb: host: xhci: fix ep context print mismatch in debugfs + - xhci: Do warm-reset when both CAS and XDEV_RESUME are set + - xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed + - ARM64: vdso32: Install vdso32 from vdso_install + - arm64: vdso32: make vdso32 install conditional + - PM: sleep: core: Fix the handling of pending runtime resume requests + - powerpc/perf: Fix crashes with generic_compat_pmu & BHRB + - device property: Fix the secondary firmware node handling in + set_primary_fwnode() + - crypto: af_alg - Work around empty control messages without MSG_MORE + - genirq/matrix: Deal with the sillyness of for_each_cpu() on UP + - irqchip/stm32-exti: Avoid losing interrupts due to clearing pending bits by + mistake + - x86/hotplug: Silence APIC only after all interrupts are migrated + - drm/amdgpu: Fix buffer overflow in INFO ioctl + - drm/amdgpu/gfx10: refine mgcg setting + - drm/amd/powerplay: Fix hardmins not being sent to SMU for RV + - drm/amd/pm: correct Vega10 swctf limit setting + - drm/amd/pm: correct Vega12 swctf limit setting + - drm/amd/pm: correct Vega20 swctf limit setting + - drm/amd/pm: correct the thermal alert temperature limit settings + - USB: yurex: Fix bad gfp argument + - usb: uas: Add quirk for PNY Pro Elite + - USB: quirks: Ignore duplicate endpoint on Sound Devices MixPre-D + - USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge + - usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe() + - USB: gadget: u_f: add overflow checks to VLA macros + - USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb() + - USB: gadget: u_f: Unbreak offset calculation in VLAs + - USB: cdc-acm: rework notification_buffer resizing + - usb: storage: Add unusual_uas entry for Sony PSZ drives + - drm/i915: Fix cmd parser desc matching with masks + - usb: dwc3: gadget: Don't setup more than requested + - usb: dwc3: gadget: Fix handling ZLP + - usb: dwc3: gadget: Handle ZLP for sg requests + - fbmem: pull fbcon_update_vcs() out of fb_set_var() + - kheaders: remove unneeded 'cat' command piped to 'head' / 'tail' + - kheaders: optimize md5sum calculation for in-tree builds + - kheaders: optimize header copy for in-tree builds + - kheaders: remove the last bashism to allow sh to run it + - kheaders: explain why include/config/autoconf.h is excluded from md5sum + - kbuild: add variables for compression tools + - kbuild: fix broken builds because of GZIP,BZIP2,LZOP variables + - HID: hiddev: Fix slab-out-of-bounds write in hiddev_ioctl_usage() + - ALSA: usb-audio: Update documentation comment for MS2109 quirk + - io_uring: Fix NULL pointer dereference in io_sq_wq_submit_work() + - Linux 5.4.62 + * DELL LATITUDE 5491 touchscreen doesn't work (LP: #1889446) // Focal update: + v5.4.62 upstream stable release (LP: #1895174) + - USB: quirks: Add no-lpm quirk for another Raydium touchscreen + * [NUC8CCHK][HDA-Intel - HDA Intel PCH, playback] No sound at all + (LP: #1875199) // Focal update: v5.4.62 upstream stable release + (LP: #1895174) + - ALSA: hda/realtek: Fix pin default on Intel NUC 8 Rugged + * Focal update: v5.4.61 upstream stable release (LP: #1893115) + - Documentation/llvm: add documentation on building w/ Clang/LLVM + - Documentation/llvm: fix the name of llvm-size + - net: wan: wanxl: use allow to pass CROSS_COMPILE_M68k for rebuilding + firmware + - net: wan: wanxl: use $(M68KCC) instead of $(M68KAS) for rebuilding firmware + - x86/boot: kbuild: allow readelf executable to be specified + - kbuild: remove PYTHON2 variable + - kbuild: remove AS variable + - kbuild: replace AS=clang with LLVM_IAS=1 + - kbuild: support LLVM=1 to switch the default tools to Clang/LLVM + - drm/vgem: Replace opencoded version of drm_gem_dumb_map_offset() + - gfs2: Improve mmap write vs. punch_hole consistency + - gfs2: Never call gfs2_block_zero_range with an open transaction + - perf probe: Fix memory leakage when the probe point is not found + - khugepaged: khugepaged_test_exit() check mmget_still_valid() + - khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter() + - bcache: avoid nr_stripes overflow in bcache_device_init() + - btrfs: export helpers for subvolume name/id resolution + - btrfs: don't show full path of bind mounts in subvol= + - btrfs: return EROFS for BTRFS_FS_STATE_ERROR cases + - btrfs: add wrapper for transaction abort predicate + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Flex Book + - ALSA: hda/realtek: Add quirk for Samsung Galaxy Book Ion + - can: j1939: transport: j1939_session_tx_dat(): fix use-after-free read in + j1939_tp_txtimer() + - can: j1939: socket: j1939_sk_bind(): make sure ml_priv is allocated + - [Config] update config for SPI_DYNAMIC + - spi: Prevent adding devices below an unregistering controller + - romfs: fix uninitialized memory leak in romfs_dev_read() + - kernel/relay.c: fix memleak on destroy relay channel + - uprobes: __replace_page() avoid BUG in munlock_vma_page() + - mm: include CMA pages in lowmem_reserve at boot + - mm, page_alloc: fix core hung in free_pcppages_bulk() + - RDMA/hfi1: Correct an interlock issue for TID RDMA WRITE request + - ext4: fix checking of directory entry validity for inline directories + - jbd2: add the missing unlock_buffer() in the error path of + jbd2_write_superblock() + - scsi: zfcp: Fix use-after-free in request timeout handlers + - drm/amdgpu/display: use GFP_ATOMIC in dcn20_validate_bandwidth_internal + - drm/amd/display: Fix EDID parsing after resume from suspend + - drm/amd/display: fix pow() crashing when given base 0 + - kthread: Do not preempt current task if it is going to call schedule() + - opp: Enable resources again if they were disabled earlier + - scsi: ufs: Add DELAY_BEFORE_LPM quirk for Micron devices + - scsi: target: tcmu: Fix crash in tcmu_flush_dcache_range on ARM + - media: budget-core: Improve exception handling in budget_register() + - rtc: goldfish: Enable interrupt in set_alarm() when necessary + - media: vpss: clean up resources in init + - Input: psmouse - add a newline when printing 'proto' by sysfs + - MIPS: Fix unable to reserve memory for Crash kernel + - m68knommu: fix overwriting of bits in ColdFire V3 cache control + - svcrdma: Fix another Receive buffer leak + - xfs: fix inode quota reservation checks + - drm/ttm: fix offset in VMAs with a pg_offs in ttm_bo_vm_access + - jffs2: fix UAF problem + - ceph: fix use-after-free for fsc->mdsc + - swiotlb-xen: use vmalloc_to_page on vmalloc virt addresses + - cpufreq: intel_pstate: Fix cpuinfo_max_freq when MSR_TURBO_RATIO_LIMIT is 0 + - scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases + - virtio_ring: Avoid loop when vq is broken in virtqueue_poll + - media: camss: fix memory leaks on error handling paths in probe + - tools/testing/selftests/cgroup/cgroup_util.c: cg_read_strcmp: fix null + pointer dereference + - xfs: Fix UBSAN null-ptr-deref in xfs_sysfs_init + - alpha: fix annotation of io{read,write}{16,32}be() + - fs/signalfd.c: fix inconsistent return codes for signalfd4 + - ext4: fix potential negative array index in do_split() + - ext4: don't allow overlapping system zones + - netfilter: nf_tables: nft_exthdr: the presence return value should be + little-endian + - spi: stm32: fixes suspend/resume management + - ASoC: q6afe-dai: mark all widgets registers as SND_SOC_NOPM + - ASoC: q6routing: add dummy register read/write function + - bpf: sock_ops sk access may stomp registers when dst_reg = src_reg + - can: j1939: fix kernel-infoleak in j1939_sk_sock2sockaddr_can() + - can: j1939: transport: j1939_simple_recv(): ignore local J1939 messages send + not by J1939 stack + - can: j1939: transport: add j1939_session_skb_find_by_offset() function + - i40e: Set RX_ONLY mode for unicast promiscuous on VLAN + - i40e: Fix crash during removing i40e driver + - net: fec: correct the error path for regulator disable in probe + - bonding: show saner speed for broadcast mode + - can: j1939: fix support for multipacket broadcast message + - can: j1939: cancel rxtimer on multipacket broadcast session complete + - can: j1939: abort multipacket broadcast session when timeout occurs + - can: j1939: add rxtimer for multipacket broadcast session + - bonding: fix a potential double-unregister + - s390/runtime_instrumentation: fix storage key handling + - s390/ptrace: fix storage key handling + - ASoC: msm8916-wcd-analog: fix register Interrupt offset + - ASoC: intel: Fix memleak in sst_media_open + - vfio/type1: Add proper error unwind for vfio_iommu_replay() + - kvm: x86: Toggling CR4.SMAP does not load PDPTEs in PAE mode + - kvm: x86: Toggling CR4.PKE does not load PDPTEs in PAE mode + - Revert "scsi: qla2xxx: Disable T10-DIF feature with FC-NVMe during probe" + - kconfig: qconf: do not limit the pop-up menu to the first row + - kconfig: qconf: fix signal connection to invalid slots + - efi: avoid error message when booting under Xen + - Fix build error when CONFIG_ACPI is not set/enabled: + - RDMA/bnxt_re: Do not add user qps to flushlist + - afs: Fix NULL deref in afs_dynroot_depopulate() + - bonding: fix active-backup failover for current ARP slave + - net: ena: Prevent reset after device destruction + - net: gemini: Fix missing free_netdev() in error path of + gemini_ethernet_port_probe() + - hv_netvsc: Fix the queue_mapping in netvsc_vf_xmit() + - net: dsa: b53: check for timeout + - powerpc/pseries: Do not initiate shutdown when system is running on UPS + - efi: add missed destroy_workqueue when efisubsys_init fails + - epoll: Keep a reference on files added to the check list + - do_epoll_ctl(): clean the failure exits up a bit + - mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible + - xen: don't reschedule in preemption off sections + - KVM: Pass MMU notifier range flags to kvm_unmap_hva_range() + - KVM: arm64: Only reschedule if MMU_NOTIFIER_RANGE_BLOCKABLE is not set + - Linux 5.4.61 + * [UBUNTU 20.04] zPCI device hot-plug during boot may result in unusable + device (LP: #1893778) + - s390/pci: ignore stale configuration request event + * [SRU] [Focal/OEM-5.6/Groovy]Fix AMD usb host controller lost after stress S3 + (LP: #1893914) + - SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC + + -- William Breathitt Gray Mon, 21 Sep 2020 08:28:57 -0400 + +linux-oracle (5.4.0-1025.25) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1025.25 -proposed tracker (LP: #1894649) + + [ Ubuntu: 5.4.0-48.52 ] + + * focal/linux: 5.4.0-48.52 -proposed tracker (LP: #1894654) + * mm/slub kernel oops on focal kernel 5.4.0-45 (LP: #1895109) + - SAUCE: Revert "mm/slub: fix a memory leak in sysfs_slab_add()" + * Packaging resync (LP: #1786013) + - update dkms package versions + - update dkms package versions + * Introduce the new NVIDIA 450-server and the 450 UDA series (LP: #1887674) + - [packaging] add signed modules for nvidia 450 and 450-server + * [UBUNTU 20.04] zPCI attach/detach issues with PF/VF linking support + (LP: #1892849) + - s390/pci: fix zpci_bus_link_virtfn() + - s390/pci: re-introduce zpci_remove_device() + - s390/pci: fix PF/VF linking on hot plug + * [UBUNTU 20.04] kernel: s390/cpum_cf,perf: changeDFLT_CCERROR counter name + (LP: #1891454) + - s390/cpum_cf, perf: change DFLT_CCERROR counter name + * [UBUNTU 20.04] zPCI: Enabling of a reserved PCI function regression + introduced by multi-function support (LP: #1891437) + - s390/pci: fix enabling a reserved PCI function + * CVE-2020-12888 + - vfio/type1: Support faulting PFNMAP vmas + - vfio-pci: Fault mmaps to enable vma tracking + - vfio-pci: Invalidate mmaps and block MMIO access on disabled memory + * [Hyper-V] VSS and File Copy daemons intermittently fails to start + (LP: #1891224) + - [Packaging] Bind hv_vss_daemon startup to hv_vss device + - [Packaging] bind hv_fcopy_daemon startup to hv_fcopy device + * alsa/hdmi: support nvidia mst hdmi/dp audio (LP: #1867704) + - ALSA: hda - Rename snd_hda_pin_sense to snd_hda_jack_pin_sense + - ALSA: hda - Add DP-MST jack support + - ALSA: hda - Add DP-MST support for non-acomp codecs + - ALSA: hda - Add DP-MST support for NVIDIA codecs + - ALSA: hda: hdmi - fix regression in connect list handling + - ALSA: hda: hdmi - fix kernel oops caused by invalid PCM idx + - ALSA: hda: hdmi - preserve non-MST PCM routing for Intel platforms + - ALSA: hda: hdmi - Keep old slot assignment behavior for Intel platforms + - ALSA: hda - Fix DP-MST support for NVIDIA codecs + * Focal update: v5.4.60 upstream stable release (LP: #1892899) + - smb3: warn on confusing error scenario with sec=krb5 + - genirq/affinity: Make affinity setting if activated opt-in + - genirq/PM: Always unlock IRQ descriptor in rearm_wake_irq() + - PCI: hotplug: ACPI: Fix context refcounting in acpiphp_grab_context() + - PCI: Add device even if driver attach failed + - PCI: qcom: Define some PARF params needed for ipq8064 SoC + - PCI: qcom: Add support for tx term offset for rev 2.1.0 + - btrfs: allow use of global block reserve for balance item deletion + - btrfs: free anon block device right after subvolume deletion + - btrfs: don't allocate anonymous block device for user invisible roots + - btrfs: ref-verify: fix memory leak in add_block_entry + - btrfs: stop incremening log_batch for the log root tree when syncing log + - btrfs: remove no longer needed use of log_writers for the log root tree + - btrfs: don't traverse into the seed devices in show_devname + - btrfs: open device without device_list_mutex + - btrfs: move the chunk_mutex in btrfs_read_chunk_tree + - btrfs: relocation: review the call sites which can be interrupted by signal + - btrfs: add missing check for nocow and compression inode flags + - btrfs: avoid possible signal interruption of btrfs_drop_snapshot() on + relocation tree + - btrfs: sysfs: use NOFS for device creation + - btrfs: don't WARN if we abort a transaction with EROFS + - btrfs: fix race between page release and a fast fsync + - btrfs: fix messages after changing compression level by remount + - btrfs: only search for left_info if there is no right_info in + try_merge_free_space + - btrfs: inode: fix NULL pointer dereference if inode doesn't need compression + - btrfs: fix memory leaks after failure to lookup checksums during inode + logging + - btrfs: make sure SB_I_VERSION doesn't get unset by remount + - btrfs: fix return value mixup in btrfs_get_extent + - arm64: perf: Correct the event index in sysfs + - dt-bindings: iio: io-channel-mux: Fix compatible string in example code + - iio: dac: ad5592r: fix unbalanced mutex unlocks in ad5592r_read_raw() + - xtensa: add missing exclusive access state management + - xtensa: fix xtensa_pmu_setup prototype + - cifs: Fix leak when handling lease break for cached root fid + - powerpc/ptdump: Fix build failure in hashpagetable.c + - powerpc: Allow 4224 bytes of stack expansion for the signal frame + - powerpc: Fix circular dependency between percpu.h and mmu.h + - pinctrl: ingenic: Enhance support for IRQ_TYPE_EDGE_BOTH + - media: vsp1: dl: Fix NULL pointer dereference on unbind + - net: ethernet: stmmac: Disable hardware multicast filter + - net: stmmac: dwmac1000: provide multicast filter fallback + - net/compat: Add missing sock updates for SCM_RIGHTS + - md/raid5: Fix Force reconstruct-write io stuck in degraded raid5 + - bcache: allocate meta data pages as compound pages + - bcache: fix overflow in offset_to_stripe() + - mac80211: fix misplaced while instead of if + - driver core: Avoid binding drivers to dead devices + - MIPS: CPU#0 is not hotpluggable + - MIPS: qi_lb60: Fix routing to audio amplifier + - ext2: fix missing percpu_counter_inc + - khugepaged: collapse_pte_mapped_thp() flush the right range + - khugepaged: collapse_pte_mapped_thp() protect the pmd lock + - ocfs2: change slot number type s16 to u16 + - mm/page_counter.c: fix protection usage propagation + - mm/memory_hotplug: fix unpaired mem_hotplug_begin/done + - ftrace: Setup correct FTRACE_FL_REGS flags for module + - kprobes: Fix NULL pointer dereference at kprobe_ftrace_handler + - tracing/hwlat: Honor the tracing_cpumask + - tracing: Use trace_sched_process_free() instead of exit() for pid tracing + - tracing: Move pipe reference to trace array instead of current_tracer + - watchdog: f71808e_wdt: indicate WDIOF_CARDRESET support in + watchdog_info.options + - watchdog: f71808e_wdt: remove use of wrong watchdog_info option + - watchdog: f71808e_wdt: clear watchdog timeout occurred flag + - ceph: set sec_context xattr on symlink creation + - ceph: handle zero-length feature mask in session messages + - pseries: Fix 64 bit logical memory block panic + - module: Correctly truncate sysfs sections output + - perf intel-pt: Fix FUP packet state + - perf intel-pt: Fix duplicate branch after CBR + - remoteproc: qcom: q6v5: Update running state before requesting stop + - remoteproc: qcom_q6v5_mss: Validate MBA firmware size before load + - remoteproc: qcom_q6v5_mss: Validate modem blob firmware size before load + - drm/imx: imx-ldb: Disable both channels for split mode in enc->disable() + - orangefs: get rid of knob code... + - pinctrl: ingenic: Properly detect GPIO direction when configured for IRQ + - crypto: algif_aead - Only wake up when ctx->more is zero + - mfd: arizona: Ensure 32k clock is put on driver unbind and error + - octeontx2-af: change (struct qmem)->entry_sz from u8 to u16 + - mtd: rawnand: fsl_upm: Remove unused mtd var + - platform/chrome: cros_ec_ishtp: Fix a double-unlock issue + - RDMA/ipoib: Return void from ipoib_ib_dev_stop() + - RDMA/ipoib: Fix ABBA deadlock with ipoib_reap_ah() + - media: rockchip: rga: Introduce color fmt macros and refactor CSC mode logic + - media: rockchip: rga: Only set output CSC mode for RGB input + - IB/uverbs: Set IOVA on IB MR in uverbs layer + - selftests/bpf: Test_progs indicate to shell on non-actions + - selftests/bpf: test_progs use another shell exit on non-actions + - USB: serial: ftdi_sio: make process-packet buffer unsigned + - USB: serial: ftdi_sio: clean up receive processing + - crypto: af_alg - Fix regression on empty requests + - devres: keep both device name and resource name in pretty name + - RDMA/counter: Only bind user QPs in auto mode + - RDMA/counter: Allow manually bind QPs with different pids to same counter + - mmc: renesas_sdhi_internal_dmac: clean up the code for dma complete + - crypto: caam - Remove broken arc4 support + - gpu: ipu-v3: image-convert: Combine rotate/no-rotate irq handlers + - gpu: ipu-v3: image-convert: Wait for all EOFs before completing a tile + - dm rq: don't call blk_mq_queue_stopped() in dm_stop_queue() + - clk: actions: Fix h_clk for Actions S500 SoC + - selftests/powerpc: ptrace-pkey: Rename variables to make it easier to follow + code + - selftests/powerpc: ptrace-pkey: Update the test to mark an invalid pkey + correctly + - selftests/powerpc: ptrace-pkey: Don't update expected UAMOR value + - iommu/omap: Check for failure of a call to omap_iommu_dump_ctx + - clk: qcom: gcc: fix sm8150 GPU and NPU clocks + - clk: qcom: clk-alpha-pll: remove unused/incorrect PLL_CAL_VAL + - iommu/vt-d: Enforce PASID devTLB field mask + - i2c: rcar: slave: only send STOP event when we have been addressed + - clk: qcom: gcc-sdm660: Fix up gcc_mss_mnoc_bimc_axi_clk + - clk: clk-atlas6: fix return value check in atlas6_clk_init() + - pwm: bcm-iproc: handle clk_get_rate() return + - tools build feature: Use CC and CXX from parent + - i2c: rcar: avoid race when unregistering slave + - nfs: ensure correct writeback errors are returned on close() + - ubifs: Fix wrong orphan node deletion in ubifs_jnl_update|rename + - clk: bcm2835: Do not use prediv with bcm2711's PLLs + - libnvdimm/security: fix a typo + - libnvdimm/security: ensure sysfs poll thread woke up and fetch updated attr + - openrisc: Fix oops caused when dumping stack + - scsi: lpfc: nvmet: Avoid hang / use-after-free again when destroying + targetport + - nfs: nfs_file_write() should check for writeback errors + - watchdog: initialize device before misc_register + - md-cluster: Fix potential error pointer dereference in resize_bitmaps() + - x86/tsr: Fix tsc frequency enumeration bug on Lightning Mountain SoC + - Input: sentelic - fix error return when fsp_reg_write fails + - recordmcount: Fix build failure on non arm64 + - drm/vmwgfx: Use correct vmw_legacy_display_unit pointer + - drm/vmwgfx: Fix two list_for_each loop exit tests + - net: qcom/emac: add missed clk_disable_unprepare in error path of + emac_clks_phase1_init + - nfs: Fix getxattr kernel panic and memory overflow + - fs/minix: set s_maxbytes correctly + - fs/minix: fix block limit check for V1 filesystems + - fs/minix: remove expected error message in block_to_path() + - fs/ufs: avoid potential u32 multiplication overflow + - test_kmod: avoid potential double free in trigger_config_run_type() + - i2c: iproc: fix race between client unreg and isr + - mfd: dln2: Run event handler loop under spinlock + - crypto: algif_aead - fix uninitialized ctx->init + - ALSA: echoaudio: Fix potential Oops in snd_echo_resume() + - perf bench mem: Always memset source before memcpy + - tools build feature: Quote CC and CXX for their arguments + - perf/x86/rapl: Fix missing psys sysfs attributes + - sh: landisk: Add missing initialization of sh_io_port_base + - khugepaged: retract_page_tables() remember to test exit + - arm64: dts: marvell: espressobin: add ethernet alias + - drm/panfrost: Use kvfree() to free bo->sgts + - drm: Added orientation quirk for ASUS tablet model T103HAF + - drm: fix drm_dp_mst_port refcount leaks in drm_dp_mst_allocate_vcpi + - drm/amdgpu: Fix bug where DPM is not enabled after hibernate and resume + - drm/amd/display: dchubbub p-state warning during surface planes switch + - Linux 5.4.60 + - kprobes: Fix compiler warning for !CONFIG_KPROBES_ON_FTRACE + * Focal update: v5.4.59 upstream stable release (LP: #1892417) + - tracepoint: Mark __tracepoint_string's __used + - HID: input: Fix devices that return multiple bytes in battery report + - nvme: add a Identify Namespace Identification Descriptor list quirk + - fs/io_uring.c: Fix uninitialized variable is referenced in io_submit_sqe + - clk: qcom: clk-rpmh: Wait for completion when enabling clocks + - x86/mce/inject: Fix a wrong assignment of i_mce.status + - sched/fair: Fix NOHZ next idle balance + - sched: correct SD_flags returned by tl->sd_flags() + - arm64: dts: rockchip: fix rk3368-lion gmac reset gpio + - arm64: dts: rockchip: fix rk3399-puma vcc5v0-host gpio + - arm64: dts: rockchip: fix rk3399-puma gmac reset gpio + - EDAC: Fix reference count leaks + - crc-t10dif: Fix potential crypto notify dead-lock + - arm64: dts: qcom: msm8916: Replace invalid bias-pull-none property + - crypto: ccree - fix resource leak on error path + - ARM: exynos: MCPM: Restore big.LITTLE cpuidle support + - firmware: arm_scmi: Fix SCMI genpd domain probing + - arm64: dts: exynos: Fix silent hang after boot on Espresso + - sched/uclamp: Fix initialization of struct uclamp_rq + - clk: scmi: Fix min and max rate when registering clocks with discrete rates + - m68k: mac: Don't send IOP message until channel is idle + - m68k: mac: Fix IOP status/control register writes + - platform/x86: intel-hid: Fix return value check in check_acpi_dev() + - platform/x86: intel-vbtn: Fix return value check in check_acpi_dev() + - ARM: dts: gose: Fix ports node name for adv7180 + - ARM: dts: gose: Fix ports node name for adv7612 + - ARM: at91: pm: add missing put_device() call in at91_pm_sram_init() + - ARM: dts: sunxi: bananapi-m2-plus-v1.2: Add regulator supply to all CPU + cores + - ARM: dts: sunxi: bananapi-m2-plus-v1.2: Fix CPU supply voltages + - spi: lantiq: fix: Rx overflow error in full duplex mode + - tpm: Require that all digests are present in TCG_PCR_EVENT2 structures + - recordmcount: only record relocation of type R_AARCH64_CALL26 on arm64. + - regulator: fix memory leak on error path of regulator_register() + - io_uring: fix sq array offset calculation + - spi: rockchip: Fix error in SPI slave pio read + - ARM: socfpga: PM: add missing put_device() call in + socfpga_setup_ocram_self_refresh() + - iocost: Fix check condition of iocg abs_vdebt + - irqchip/ti-sci-inta: Fix return value about devm_ioremap_resource() + - seccomp: Fix ioctl number for SECCOMP_IOCTL_NOTIF_ID_VALID + - md: raid0/linear: fix dereference before null check on pointer mddev + - nvme-tcp: fix controller reset hang during traffic + - nvme-rdma: fix controller reset hang during traffic + - nvme-multipath: fix logic for non-optimized paths + - nvme-multipath: do not fall back to __nvme_find_path() for non-optimized + paths + - drm/tilcdc: fix leak & null ref in panel_connector_get_modes + - soc: qcom: rpmh-rsc: Set suppress_bind_attrs flag + - Bluetooth: add a mutex lock to avoid UAF in do_enale_set + - loop: be paranoid on exit and prevent new additions / removals + - fs/btrfs: Add cond_resched() for try_release_extent_mapping() stalls + - drm/amdgpu: avoid dereferencing a NULL pointer + - drm/radeon: Fix reference count leaks caused by pm_runtime_get_sync + - crypto: aesni - Fix build with LLVM_IAS=1 + - video: fbdev: savage: fix memory leak on error handling path in probe + - video: fbdev: neofb: fix memory leak in neo_scan_monitor() + - bus: ti-sysc: Add missing quirk flags for usb_host_hs + - md-cluster: fix wild pointer of unlock_all_bitmaps() + - drm/nouveau/kms/nv50-: Fix disabling dithering + - arm64: dts: hisilicon: hikey: fixes to comply with adi, adv7533 DT binding + - drm/etnaviv: fix ref count leak via pm_runtime_get_sync + - drm/nouveau: fix reference count leak in nouveau_debugfs_strap_peek + - drm/nouveau: fix multiple instances of reference count leaks + - mmc: sdhci-cadence: do not use hardware tuning for SD mode + - btrfs: fix lockdep splat from btrfs_dump_space_info + - usb: mtu3: clear dual mode of u3port when disable device + - drm: msm: a6xx: fix gpu failure after system resume + - drm/msm: Fix a null pointer access in msm_gem_shrinker_count() + - drm/debugfs: fix plain echo to connector "force" attribute + - drm/radeon: disable AGP by default + - irqchip/irq-mtk-sysirq: Replace spinlock with raw_spinlock + - mm/mmap.c: Add cond_resched() for exit_mmap() CPU stalls + - drm/amdgpu/display bail early in dm_pp_get_static_clocks + - drm/amd/powerplay: fix compile error with ARCH=arc + - bpf: Fix fds_example SIGSEGV error + - brcmfmac: keep SDIO watchdog running when console_interval is non-zero + - brcmfmac: To fix Bss Info flag definition Bug + - brcmfmac: set state of hanger slot to FREE when flushing PSQ + - platform/x86: asus-nb-wmi: add support for ASUS ROG Zephyrus G14 and G15 + - iwlegacy: Check the return value of pcie_capability_read_*() + - gpu: host1x: debug: Fix multiple channels emitting messages simultaneously + - ionic: update eid test for overflow + - mmc: sdhci-pci-o2micro: Bug fix for O2 host controller Seabird1 + - usb: gadget: net2280: fix memory leak on probe error handling paths + - bdc: Fix bug causing crash after multiple disconnects + - usb: bdc: Halt controller on suspend + - dyndbg: fix a BUG_ON in ddebug_describe_flags + - bcache: fix super block seq numbers comparision in register_cache_set() + - ACPICA: Do not increment operation_region reference counts for field units + - drm/msm: ratelimit crtc event overflow error + - drm/gem: Fix a leak in drm_gem_objects_lookup() + - drm/bridge: ti-sn65dsi86: Clear old error bits before AUX transfers + - agp/intel: Fix a memory leak on module initialisation failure + - mwifiex: Fix firmware filename for sd8977 chipset + - mwifiex: Fix firmware filename for sd8997 chipset + - btmrvl: Fix firmware filename for sd8977 chipset + - btmrvl: Fix firmware filename for sd8997 chipset + - video: fbdev: sm712fb: fix an issue about iounmap for a wrong address + - console: newport_con: fix an issue about leak related system resources + - video: pxafb: Fix the function used to balance a 'dma_alloc_coherent()' call + - ath10k: Acquire tx_lock in tx error paths + - iio: improve IIO_CONCENTRATION channel type description + - drm/etnaviv: Fix error path on failure to enable bus clk + - drm/arm: fix unintentional integer overflow on left shift + - clk: bcm63xx-gate: fix last clock availability + - leds: lm355x: avoid enum conversion warning + - Bluetooth: btusb: fix up firmware download sequence + - Bluetooth: btmtksdio: fix up firmware download sequence + - media: cxusb-analog: fix V4L2 dependency + - media: marvell-ccic: Add missed v4l2_async_notifier_cleanup() + - media: omap3isp: Add missed v4l2_ctrl_handler_free() for + preview_init_entities() + - ASoC: SOF: nocodec: add missing .owner field + - ASoC: Intel: bxt_rt298: add missing .owner field + - scsi: cumana_2: Fix different dev_id between request_irq() and free_irq() + - drm/mipi: use dcs write for mipi_dsi_dcs_set_tear_scanline + - cxl: Fix kobject memleak + - drm/radeon: fix array out-of-bounds read and write issues + - staging: vchiq_arm: Add a matching unregister call + - iavf: fix error return code in iavf_init_get_resources() + - iavf: Fix updating statistics + - RDMA/core: Fix bogus WARN_ON during ib_unregister_device_queued() + - scsi: powertec: Fix different dev_id between request_irq() and free_irq() + - scsi: eesox: Fix different dev_id between request_irq() and free_irq() + - ipvs: allow connection reuse for unconfirmed conntrack + - media: firewire: Using uninitialized values in node_probe() + - media: exynos4-is: Add missed check for pinctrl_lookup_state() + - media: cros-ec-cec: do not bail on device_init_wakeup failure + - xfs: don't eat an EIO/ENOSPC writeback error when scrubbing data fork + - xfs: fix reflink quota reservation accounting error + - RDMA/rxe: Skip dgid check in loopback mode + - PCI: Fix pci_cfg_wait queue locking problem + - drm/stm: repair runtime power management + - kobject: Avoid premature parent object freeing in kobject_cleanup() + - leds: core: Flush scheduled work for system suspend + - drm: panel: simple: Fix bpc for LG LB070WV8 panel + - phy: exynos5-usbdrd: Calibrating makes sense only for USB2.0 PHY + - drm/bridge: sil_sii8620: initialize return of sii8620_readb + - scsi: scsi_debug: Add check for sdebug_max_queue during module init + - mwifiex: Prevent memory corruption handling keys + - kernfs: do not call fsnotify() with name without a parent + - powerpc/rtas: don't online CPUs for partition suspend + - powerpc/vdso: Fix vdso cpu truncation + - RDMA/qedr: SRQ's bug fixes + - RDMA/rxe: Prevent access to wr->next ptr afrer wr is posted to send queue + - ima: Have the LSM free its audit rule + - staging: rtl8192u: fix a dubious looking mask before a shift + - ASoC: meson: fixes the missed kfree() for axg_card_add_tdm_loopback + - PCI/ASPM: Add missing newline in sysfs 'policy' + - phy: renesas: rcar-gen3-usb2: move irq registration to init + - powerpc/book3s64/pkeys: Use PVR check instead of cpu feature + - drm/imx: fix use after free + - drm/imx: tve: fix regulator_disable error path + - gpu: ipu-v3: Restore RGB32, BGR32 + - spi: lantiq-ssc: Fix warning by using WQ_MEM_RECLAIM + - USB: serial: iuu_phoenix: fix led-activity helpers + - usb: core: fix quirks_param_set() writing to a const pointer + - thermal: ti-soc-thermal: Fix reversed condition in + ti_thermal_expose_sensor() + - coresight: tmc: Fix TMC mode read in tmc_read_unprepare_etb() + - powerpc/perf: Fix missing is_sier_aviable() during build + - mt76: mt7615: fix potential memory leak in mcu message handler + - phy: armada-38x: fix NETA lockup when repeatedly switching speeds + - MIPS: OCTEON: add missing put_device() call in dwc3_octeon_device_init() + - usb: dwc2: Fix error path in gadget registration + - usb: gadget: f_uac2: fix AC Interface Header Descriptor wTotalLength + - scsi: megaraid_sas: Clear affinity hint + - scsi: mesh: Fix panic after host or bus reset + - net: dsa: mv88e6xxx: MV88E6097 does not support jumbo configuration + - macintosh/via-macii: Access autopoll_devs when inside lock + - PCI: cadence: Fix updating Vendor ID and Subsystem Vendor ID register + - RDMA/core: Fix return error value in _ib_modify_qp() to negative + - Smack: fix another vsscanf out of bounds + - Smack: prevent underflow in smk_set_cipso() + - power: supply: check if calc_soc succeeded in pm860x_init_battery + - Bluetooth: hci_h5: Set HCI_UART_RESET_ON_INIT to correct flags + - Bluetooth: hci_serdev: Only unregister device if it was registered + - net: dsa: rtl8366: Fix VLAN semantics + - net: dsa: rtl8366: Fix VLAN set-up + - xfs: fix inode allocation block res calculation precedence + - selftests/powerpc: Squash spurious errors due to device removal + - powerpc/32s: Fix CONFIG_BOOK3S_601 uses + - powerpc/boot: Fix CONFIG_PPC_MPC52XX references + - selftests/powerpc: Fix CPU affinity for child process + - RDMA/netlink: Remove CAP_NET_RAW check when dump a raw QP + - PCI: Release IVRS table in AMD ACS quirk + - [Config] update config for ARMADA_AP_CPU_CLK + - cpufreq: ap806: fix cpufreq driver needs ap cpu clk + - selftests/powerpc: Fix online CPU selection + - ASoC: meson: axg-tdm-interface: fix link fmt setup + - ASoC: meson: axg-tdmin: fix g12a skew + - ASoC: meson: axg-tdm-formatters: fix sclk inversion + - ASoC: fsl_sai: Fix value of FSL_SAI_CR1_RFW_MASK + - s390/qeth: don't process empty bridge port events + - ice: Graceful error handling in HW table calloc failure + - rtw88: fix LDPC field for RA info + - rtw88: fix short GI capability based on current bandwidth + - rtw88: coex: only skip coex triggered by BT info + - wl1251: fix always return 0 error + - tools, build: Propagate build failures from tools/build/Makefile.build + - tools, bpftool: Fix wrong return value in do_dump() + - net/mlx5: DR, Change push vlan action sequence + - net/mlx5: Delete extra dump stack that gives nothing + - net: ethernet: aquantia: Fix wrong return value + - liquidio: Fix wrong return value in cn23xx_get_pf_num() + - net: spider_net: Fix the size used in a 'dma_free_coherent()' call + - fsl/fman: use 32-bit unsigned integer + - fsl/fman: fix dereference null return value + - fsl/fman: fix unreachable code + - fsl/fman: check dereferencing null pointer + - fsl/fman: fix eth hash table allocation + - net: thunderx: initialize VF's mailbox mutex before first usage + - dlm: Fix kobject memleak + - ocfs2: fix unbalanced locking + - pinctrl-single: fix pcs_parse_pinconf() return value + - svcrdma: Fix page leak in svc_rdma_recv_read_chunk() + - x86/fsgsbase/64: Fix NULL deref in 86_fsgsbase_read_task + - crypto: aesni - add compatibility with IAS + - af_packet: TPACKET_V3: fix fill status rwlock imbalance + - drivers/net/wan/lapbether: Added needed_headroom and a skb->len check + - net: Fix potential memory leak in proto_register() + - net/nfc/rawsock.c: add CAP_NET_RAW check. + - net: phy: fix memory leak in device-create error path + - net: Set fput_needed iff FDPUT_FPUT is set + - net/tls: Fix kmap usage + - vmxnet3: use correct tcp hdr length when packet is encapsulated + - net: refactor bind_bucket fastreuse into helper + - net: initialize fastreuse on inet_inherit_port + - USB: serial: cp210x: re-enable auto-RTS on open + - USB: serial: cp210x: enable usb generic throttle/unthrottle + - ALSA: hda - fix the micmute led status for Lenovo ThinkCentre AIO + - ALSA: usb-audio: Creative USB X-Fi Pro SB1095 volume knob support + - ALSA: usb-audio: fix overeager device match for MacroSilicon MS2109 + - ALSA: usb-audio: work around streaming quirk for MacroSilicon MS2109 + - 9p: Fix memory leak in v9fs_mount + - media: media-request: Fix crash if memory allocation fails + - drm/ttm/nouveau: don't call tt destroy callback on alloc failure. + - io_uring: set ctx sq/cq entry count earlier + - NFS: Don't move layouts to plh_return_segs list while in use + - NFS: Don't return layout segments that are in use + - cpufreq: Fix locking issues with governors + - cpufreq: dt: fix oops on armada37xx + - include/asm-generic/vmlinux.lds.h: align ro_after_init + - spi: spidev: Align buffers for DMA + - mtd: rawnand: qcom: avoid write to unavailable register + - erofs: fix extended inode could cross boundary + - Revert "parisc: Drop LDCW barrier in CAS code when running UP" + - Revert "parisc: Use ldcw instruction for SMP spinlock release barrier" + - Revert "parisc: Revert "Release spinlocks using ordered store"" + - parisc: Do not use an ordered store in pa_tlb_lock() + - parisc: Implement __smp_store_release and __smp_load_acquire barriers + - parisc: mask out enable and reserved bits from sba imask + - ARM: 8992/1: Fix unwind_frame for clang-built kernels + - irqdomain/treewide: Free firmware node after domain removal + - ALSA: usb-audio: add quirk for Pioneer DDJ-RB + - tpm: Unify the mismatching TPM space buffer sizes + - pstore: Fix linking when crypto API disabled + - crypto: hisilicon - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not + specified + - crypto: qat - fix double free in qat_uclo_create_batch_init_list + - crypto: ccp - Fix use of merged scatterlists + - crypto: cpt - don't sleep of CRYPTO_TFM_REQ_MAY_SLEEP was not specified + - bitfield.h: don't compile-time validate _val in FIELD_FIT + - fs/minix: check return value of sb_getblk() + - fs/minix: don't allow getting deleted inodes + - fs/minix: reject too-large maximum file size + - xen/balloon: fix accounting in alloc_xenballooned_pages error path + - xen/balloon: make the balloon wait interruptible + - xen/gntdev: Fix dmabuf import with non-zero sgt offset + - s390/dasd: fix inability to use DASD with DIAG driver + - s390/gmap: improve THP splitting + - io_uring: Fix NULL pointer dereference in loop_rw_iter() + - Linux 5.4.59 + * Regression on NFS: unable to handle page fault in mempool_alloc_slab + (LP: #1886277) // Focal update: v5.4.59 upstream stable release + (LP: #1892417) + - SUNRPC: Fix ("SUNRPC: Add "@len" parameter to gss_unwrap()") + * Focal update: v5.4.59 upstream stable release (LP: #1892417) // + CVE-2019-19770 which shows this issue is not a core debugfs issue, but + - blktrace: fix debugfs use after free + * update ENA driver for LLQ acceleration mode, new hw support (LP: #1890845) + - net: ena: change num_queues to num_io_queues for clarity and consistency + - net: ena: multiple queue creation related cleanups + - net: ena: ethtool: get_channels: use combined only + - net: ena: make ethtool -l show correct max number of queues + - net: ena: remove redundant print of number of queues + - net: ena: ethtool: support set_channels callback + - net: ena: implement XDP drop support + - net: ena: Implement XDP_TX action + - net: ena: Add first_interrupt field to napi struct + - net: ena: fix default tx interrupt moderation interval + - net: ena: remove set but not used variable 'rx_ring' + - net: ena: remove set but not used variable 'hash_key' + - net: ena: ethtool: remove redundant non-zero check on rc + - net/amazon: Ensure that driver version is aligned to the linux kernel + - net: ena: fix broken interface between ENA driver and FW + - net: ena: ethtool: clean up minor indentation issue + - net: ena: fix incorrect setting of the number of msix vectors + - net: ena: fix request of incorrect number of IRQ vectors + - net: ena: avoid memory access violation by validating req_id properly + - net: ena: fix continuous keep-alive resets + - net: ena: Make some functions static + - net: ena: avoid unnecessary admin command when RSS function set fails + - net: ena: allow setting the hash function without changing the key + - net: ena: change default RSS hash function to Toeplitz + - net: ena: changes to RSS hash key allocation + - net: ena: remove code that does nothing + - net: ena: add unmask interrupts statistics to ethtool + - net: ena: add support for reporting of packet drops + - net: ena: drop superfluous prototype + - net: ena: use SHUTDOWN as reset reason when closing interface + - net: ena: cosmetic: remove unnecessary spaces and tabs in ena_com.h macros + - net: ena: cosmetic: extract code to ena_indirection_table_set() + - net: ena: add support for the rx offset feature + - net: ena: rename ena_com_free_desc to make API more uniform + - net: ena: use explicit variable size for clarity + - net: ena: fix ena_com_comp_status_to_errno() return value + - net: ena: simplify ena_com_update_intr_delay_resolution() + - net: ena: cosmetic: set queue sizes to u32 for consistency + - net: ena: cosmetic: fix spelling and grammar mistakes in comments + - net: ena: cosmetic: fix line break issues + - net: ena: cosmetic: remove unnecessary code + - net: ena: cosmetic: code reorderings + - net: ena: cosmetic: fix spacing issues + - net: ena: cosmetic: minor code changes + - net: ena: reduce driver load time + - net: ena: xdp: XDP_TX: fix memory leak + - net: ena: xdp: update napi budget for DROP and ABORTED + - ena_netdev: use generic power management + - net: ena: Fix using plain integer as NULL pointer in ena_init_napi_in_range + - net: ena: avoid unnecessary rearming of interrupt vector when busy-polling + - net: ena: add reserved PCI device ID + - net: ena: cosmetic: satisfy gcc warning + - net: ena: cosmetic: change ena_com_stats_admin stats to u64 + - net: ena: add support for traffic mirroring + - net: ena: enable support of rss hash key and function changes + - net: ena: move llq configuration from ena_probe to ena_device_init() + - net: ena: support new LLQ acceleration mode + * [SRU] Fix acpi backlight issue on some thinkpads (LP: #1892010) + - platform/x86: thinkpad_acpi: not loading brightness_init when _BCL invalid + * [SRU][F/OEM-5.6] add a new OLED panel support for brightness control + (LP: #1887909) + - drm/dp: Lenovo X13 Yoga OLED panel brightness fix + * Realtek [10ec:c82f] Subsystem [17aa:c02f] Wifi adapter not found + (LP: #1886247) + - SAUCE: rtw88: 8822ce: add support for device ID 0xc82f + * KVM: Fix zero_page reference counter overflow when using KSM on KVM compute + host (LP: #1837810) + - KVM: fix overflow of zero page refcount with ksm running + * Fix missing HDMI Audio on another HP Desktop (LP: #1891617) + - ALSA: hda/hdmi: Use force connectivity quirk on another HP desktop + * alsa/sof: support 1 and 3 dmics (LP: #1891585) + - SAUCE: ASoC: SOF: intel: hda: support also devices with 1 and 3 dmics + * tcp_fastopen_backup_key.sh from net in ubuntu_kernel_selftests failed on + Eoan LPAR (LP: #1869134) + - tcp: correct read of TFO keys on big endian systems + * Fix false-negative return value for rtnetlink.sh in kselftests/net + (LP: #1890136) + - selftests: rtnetlink: correct the final return value for the test + - selftests: rtnetlink: make kci_test_encap() return sub-test result + * Focal update: v5.4.58 upstream stable release (LP: #1891387) + - USB: serial: qcserial: add EM7305 QDL product ID + - perf/core: Fix endless multiplex timer + - USB: iowarrior: fix up report size handling for some devices + - usb: xhci: define IDs for various ASMedia host controllers + - usb: xhci: Fix ASMedia ASM1142 DMA addressing + - io_uring: prevent re-read of sqe->opcode + - io_uring: Fix use-after-free in io_sq_wq_submit_work() + - Revert "ALSA: hda: call runtime_allow() for all hda controllers" + - ALSA: hda/realtek: Add alc269/alc662 pin-tables for Loongson-3 laptops + - ALSA: hda/ca0132 - Add new quirk ID for Recon3D. + - ALSA: hda/ca0132 - Fix ZxR Headphone gain control get value. + - ALSA: hda/ca0132 - Fix AE-5 microphone selection commands. + - ALSA: seq: oss: Serialize ioctls + - staging: android: ashmem: Fix lockdep warning for write operation + - staging: rtl8712: handle firmware load failure + - Staging: rtl8188eu: rtw_mlme: Fix uninitialized variable authmode + - Bluetooth: Fix slab-out-of-bounds read in hci_extended_inquiry_result_evt() + - Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_evt() + - Bluetooth: Prevent out-of-bounds read in hci_inquiry_result_with_rssi_evt() + - omapfb: dss: Fix max fclk divider for omap36xx + - binder: Prevent context manager from incrementing ref 0 + - Smack: fix use-after-free in smk_write_relabel_self() + - scripts: add dummy report mode to add_namespace.cocci + - vgacon: Fix for missing check in scrollback handling + - mtd: properly check all write ioctls for permissions + - leds: wm831x-status: fix use-after-free on unbind + - leds: lm36274: fix use-after-free on unbind + - leds: da903x: fix use-after-free on unbind + - leds: lm3533: fix use-after-free on unbind + - leds: 88pm860x: fix use-after-free on unbind + - net/9p: validate fds in p9_fd_open + - drm/nouveau/fbcon: fix module unload when fbcon init has failed for some + reason + - drm/nouveau/fbcon: zero-initialise the mode_cmd2 structure + - drm/drm_fb_helper: fix fbdev with sparc64 + - i2c: slave: improve sanity check when registering + - i2c: slave: add sanity check when unregistering + - usb: hso: check for return value in hso_serial_common_create() + - net: ethernet: mtk_eth_soc: Always call mtk_gmac0_rgmii_adjust() for mt7623 + - ALSA: hda: fix NULL pointer dereference during suspend + - firmware: Fix a reference count leak. + - cfg80211: check vendor command doit pointer before use + - igb: reinit_locked() should be called with rtnl_lock + - atm: fix atm_dev refcnt leaks in atmtcp_remove_persistent + - tools lib traceevent: Fix memory leak in process_dynamic_array_len + - Drivers: hv: vmbus: Ignore CHANNELMSG_TL_CONNECT_RESULT(23) + - xattr: break delegations in {set,remove}xattr + - Revert "powerpc/kasan: Fix shadow pages allocation failure" + - PCI: tegra: Revert tegra124 raw_violation_fixup + - ipv4: Silence suspicious RCU usage warning + - ipv6: fix memory leaks on IPV6_ADDRFORM path + - ipv6: Fix nexthop refcnt leak when creating ipv6 route info + - net: ethernet: mtk_eth_soc: fix MTU warnings + - rxrpc: Fix race between recvmsg and sendmsg on immediate call failure + - vxlan: Ensure FDB dump is performed under RCU + - net: lan78xx: replace bogus endpoint lookup + - appletalk: Fix atalk_proc_init() return path + - dpaa2-eth: Fix passing zero to 'PTR_ERR' warning + - hv_netvsc: do not use VF device if link is down + - net: gre: recompute gre csum for sctp over gre tunnels + - net: thunderx: use spin_lock_bh in nicvf_set_rx_mode_task() + - openvswitch: Prevent kernel-infoleak in ovs_ct_put_key() + - Revert "vxlan: fix tos value before xmit" + - tcp: apply a floor of 1 for RTT samples from TCP timestamps + - ima: move APPRAISE_BOOTPARAM dependency on ARCH_POLICY to runtime + - [Config] update annotations for IMA_APPRAISE_BOOTPARAM + - nfsd: Fix NFSv4 READ on RDMA when using readv + - Linux 5.4.58 + * Focal update: v5.4.57 upstream stable release (LP: #1891064) + - random32: update the net random state on interrupt and activity + - ARM: percpu.h: fix build error + - random: fix circular include dependency on arm64 after addition of percpu.h + - random32: remove net_rand_state from the latent entropy gcc plugin + - random32: move the pseudo-random 32-bit definitions to prandom.h + - arm64: Workaround circular dependency in pointer_auth.h + - ext4: fix direct I/O read error + - selftests: bpf: Fix detach from sockmap tests + - bpf: sockmap: Require attach_bpf_fd when detaching a program + - Linux 5.4.57 + * Focal update: v5.4.56 upstream stable release (LP: #1891063) + - crypto: ccp - Release all allocated memory if sha type is invalid + - media: rc: prevent memory leak in cx23888_ir_probe + - sunrpc: check that domain table is empty at module unload. + - ath10k: enable transmit data ack RSSI for QCA9884 + - PCI/ASPM: Disable ASPM on ASMedia ASM1083/1085 PCIe-to-PCI bridge + - mm/filemap.c: don't bother dropping mmap_sem for zero size readahead + - ALSA: usb-audio: Add implicit feedback quirk for SSL2 + - ALSA: hda/realtek: enable headset mic of ASUS ROG Zephyrus G15(GA502) series + with ALC289 + - ALSA: hda/realtek: typo_fix: enable headset mic of ASUS ROG Zephyrus + G14(GA401) series with ALC289 + - ALSA: hda/realtek: Fix add a "ultra_low_power" function for intel reference + board (alc256) + - ALSA: hda/hdmi: Fix keep_power assignment for non-component devices + - IB/rdmavt: Fix RQ counting issues causing use of an invalid RWQE + - vhost/scsi: fix up req type endian-ness + - 9p/trans_fd: Fix concurrency del of req_list in p9_fd_cancelled/p9_read_work + - wireless: Use offsetof instead of custom macro. + - ARM: 8986/1: hw_breakpoint: Don't invoke overflow handler on uaccess + watchpoints + - ARM: dts: imx6sx-sabreauto: Fix the phy-mode on fec2 + - ARM: dts: imx6sx-sdb: Fix the phy-mode on fec2 + - ARM: dts: imx6qdl-icore: Fix OTG_ID pin and sdcard detect + - virtio_balloon: fix up endian-ness for free cmd id + - Revert "drm/amdgpu: Fix NULL dereference in dpm sysfs handlers" + - drm/amd/display: Clear dm_state for fast updates + - drm/amdgpu: Prevent kernel-infoleak in amdgpu_info_ioctl() + - drm/dbi: Fix SPI Type 1 (9-bit) transfer + - drm: hold gem reference until object is no longer accessed + - rds: Prevent kernel-infoleak in rds_notify_queue_get() + - libtraceevent: Fix build with binutils 2.35 + - net/x25: Fix x25_neigh refcnt leak when x25 disconnect + - net/x25: Fix null-ptr-deref in x25_disconnect + - ARM: dts sunxi: Relax a bit the CMA pool allocation range + - xfrm: Fix crash when the hold queue is used. + - ARM: dts: armada-38x: fix NETA lockup when repeatedly switching speeds + - nvme-tcp: fix possible hang waiting for icresp response + - selftests/net: rxtimestamp: fix clang issues for target arch PowerPC + - selftests/net: psock_fanout: fix clang issues for target arch PowerPC + - selftests/net: so_txtime: fix clang issues for target arch PowerPC + - sh/tlb: Fix PGTABLE_LEVELS > 2 + - sh: Fix validation of system call number + - net: hns3: fix a TX timeout issue + - net: hns3: fix aRFS FD rules leftover after add a user FD rule + - net/mlx5: E-switch, Destroy TSAR when fail to enable the mode + - net/mlx5e: Fix error path of device attach + - net/mlx5: Verify Hardware supports requested ptp function on a given pin + - net/mlx5e: Modify uplink state on interface up/down + - net/mlx5e: Fix kernel crash when setting vf VLANID on a VF dev + - net: lan78xx: add missing endpoint sanity check + - net: lan78xx: fix transfer-buffer memory leak + - rhashtable: Fix unprotected RCU dereference in __rht_ptr + - mlx4: disable device on shutdown + - mlxsw: core: Increase scope of RCU read-side critical section + - mlxsw: core: Free EMAD transactions using kfree_rcu() + - ibmvnic: Fix IRQ mapping disposal in error path + - bpf: Fix map leak in HASH_OF_MAPS map + - mac80211: mesh: Free ie data when leaving mesh + - mac80211: mesh: Free pending skb when destroying a mpath + - arm64/alternatives: move length validation inside the subsection + - arm64: csum: Fix handling of bad packets + - Bluetooth: fix kernel oops in store_pending_adv_report + - net: nixge: fix potential memory leak in nixge_probe() + - net: gemini: Fix missing clk_disable_unprepare() in error path of + gemini_ethernet_port_probe() + - net/mlx5e: fix bpf_prog reference count leaks in mlx5e_alloc_rq + - perf tools: Fix record failure when mixed with ARM SPE event + - vxlan: fix memleak of fdb + - usb: hso: Fix debug compile warning on sparc32 + - selftests: fib_nexthop_multiprefix: fix cleanup() netns deletion + - qed: Disable "MFW indication via attention" SPAM every 5 minutes + - selftests: net: ip_defrag: modprobe missing nf_defrag_ipv6 support + - nfc: s3fwrn5: add missing release on skb in s3fwrn5_recv_frame + - scsi: core: Run queue in case of I/O resource contention failure + - parisc: add support for cmpxchg on u8 pointers + - net: ethernet: ravb: exit if re-initialization fails in tx timeout + - Revert "i2c: cadence: Fix the hold bit setting" + - x86/unwind/orc: Fix ORC for newly forked tasks + - x86/stacktrace: Fix reliable check for empty user task stacks + - cxgb4: add missing release on skb in uld_send() + - xen-netfront: fix potential deadlock in xennet_remove() + - RISC-V: Set maximum number of mapped pages correctly + - drivers/net/wan: lapb: Corrected the usage of skb_cow + - KVM: arm64: Don't inherit exec permission across page-table levels + - KVM: LAPIC: Prevent setting the tscdeadline timer if the lapic is hw + disabled + - x86/i8259: Use printk_deferred() to prevent deadlock + - perf tests bp_account: Make global variable static + - perf env: Do not return pointers to local variables + - perf bench: Share some global variables to fix build with gcc 10 + - Linux 5.4.56 + + -- William Breathitt Gray Fri, 11 Sep 2020 08:36:45 -0400 + +linux-oracle (5.4.0-1024.24) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1024.24 -proposed tracker (LP: #1894311) + + [ Ubuntu: 5.4.0-47.51 ] + + * focal/linux: 5.4.0-47.51 -proposed tracker (LP: #1894315) + * CVE-2020-14386 + - SAUCE: net/packet: fix overflow in tpacket_rcv + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 5.4.0-45.49 ] + + * focal/linux: 5.4.0-45.49 -proposed tracker (LP: #1893050) + * [Potential Regression] dscr_inherit_exec_test from powerpc in + ubuntu_kernel_selftests failed on B/E/F (LP: #1888332) + - powerpc/64s: Don't init FSCR_DSCR in __init_FSCR() + + -- Khalid Elmously Sat, 05 Sep 2020 02:59:35 -0400 + +linux-oracle (5.4.0-1022.22) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1022.22 -proposed tracker (LP: #1890742) + + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update update.conf + + * soc/amd/renoir: change the module name to make it work with ucm3 + (LP: #1888166) + - [config] Remove (rename) acp3x-rn + + * Focal update: v5.4.52 upstream stable release (LP: #1887853) + - [config] Remove (rename) intel-rapl-perf + + * Fix statistics on Broadcom Ethernet driver (LP: #1892397) + - bnxt_en: Store the running firmware version code. + - bnxt_en: Do not enable legacy TX push on older firmware. + - bnxt_en: Fix statistics counters issue during ifdown with older firmware. + + * Focal update: v5.4.51 upstream stable release (LP: #1886995) + - [config] updateconfigs for EFI_CUSTOM_SSDT_OVERLAYS + + [ Ubuntu: 5.4.0-44.48 ] + + * focal/linux: 5.4.0-44.48 -proposed tracker (LP: #1891049) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * ipsec: policy priority management is broken (LP: #1890796) + - xfrm: policy: match with both mark and mask on user interfaces + + [ Ubuntu: 5.4.0-43.47 ] + + * focal/linux: 5.4.0-43.47 -proposed tracker (LP: #1890746) + * Packaging resync (LP: #1786013) + - update dkms package versions + * Devlink - add RoCE disable kernel support (LP: #1877270) + - devlink: Add new "enable_roce" generic device param + - net/mlx5: Document flow_steering_mode devlink param + - net/mlx5: Handle "enable_roce" devlink param + - IB/mlx5: Rename profile and init methods + - IB/mlx5: Load profile according to RoCE enablement state + - net/mlx5: Remove unneeded variable in mlx5_unload_one + - net/mlx5: Add devlink reload + - IB/mlx5: Do reverse sequence during device removal + * msg_zerocopy.sh in net from ubuntu_kernel_selftests failed (LP: #1812620) + - selftests/net: relax cpu affinity requirement in msg_zerocopy test + * Enlarge hisi_sec2 capability (LP: #1890222) + - Revert "UBUNTU: [Config] Disable hisi_sec2 temporarily" + - crypto: hisilicon - update SEC driver module parameter + * Fix missing HDMI/DP Audio on an HP Desktop (LP: #1890441) + - ALSA: hda/hdmi: Add quirk to force connectivity + * Fix IOMMU error on AMD Radeon Pro W5700 (LP: #1890306) + - PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken + * ASoC:amd:renoir: the dmic can't record sound after suspend and resume + (LP: #1890220) + - SAUCE: ASoC: amd: renoir: restore two more registers during resume + * No sound, Dummy output on Acer Swift 3 SF314-57G with Ice Lake core-i7 CPU + (LP: #1877757) + - ASoC: SOF: Intel: hda: fix generic hda codec support + * Fix right speaker of HP laptop (LP: #1889375) + - SAUCE: hda/realtek: Fix right speaker of HP laptop + * blk_update_request error when mount nvme partition (LP: #1872383) + - SAUCE: nvme-pci: prevent SK hynix PC400 from using Write Zeroes command + * soc/amd/renoir: detect dmic from acpi table (LP: #1887734) + - ASoC: amd: add logic to check dmic hardware runtime + - ASoC: amd: add ACPI dependency check + - ASoC: amd: fixed kernel warnings + * soc/amd/renoir: change the module name to make it work with ucm3 + (LP: #1888166) + - AsoC: amd: add missing snd- module prefix to the acp3x-rn driver kernel + module + - SAUCE: remove a kernel module since its name is changed + * Focal update: v5.4.55 upstream stable release (LP: #1890343) + - AX.25: Fix out-of-bounds read in ax25_connect() + - AX.25: Prevent out-of-bounds read in ax25_sendmsg() + - dev: Defer free of skbs in flush_backlog + - drivers/net/wan/x25_asy: Fix to make it work + - ip6_gre: fix null-ptr-deref in ip6gre_init_net() + - net-sysfs: add a newline when printing 'tx_timeout' by sysfs + - net: udp: Fix wrong clean up for IS_UDPLITE macro + - qrtr: orphan socket in qrtr_release() + - rtnetlink: Fix memory(net_device) leak when ->newlink fails + - rxrpc: Fix sendmsg() returning EPIPE due to recvmsg() returning ENODATA + - tcp: allow at most one TLP probe per flight + - AX.25: Prevent integer overflows in connect and sendmsg + - sctp: shrink stream outq only when new outcnt < old outcnt + - sctp: shrink stream outq when fails to do addstream reconf + - udp: Copy has_conns in reuseport_grow(). + - udp: Improve load balancing for SO_REUSEPORT. + - regmap: debugfs: check count when read regmap file + - PM: wakeup: Show statistics for deleted wakeup sources again + - Revert "dpaa_eth: fix usage as DSA master, try 3" + - Linux 5.4.55 + * Add support for Atlantic NIC firmware v4 (LP: #1886908) + - net: atlantic: simplify hw_get_fw_version() usage + - net: atlantic: align return value of ver_match function with function name + - net: atlantic: add support for FW 4.x + * perf vendor events s390: Add new deflate counters for IBM z15 (LP: #1888551) + - perf vendor events s390: Add new deflate counters for IBM z15 + * Focal update: v5.4.54 upstream stable release (LP: #1889669) + - soc: qcom: rpmh: Dirt can only make you dirtier, not cleaner + - gpio: arizona: handle pm_runtime_get_sync failure case + - gpio: arizona: put pm_runtime in case of failure + - pinctrl: amd: fix npins for uart0 in kerncz_groups + - mac80211: allow rx of mesh eapol frames with default rx key + - scsi: scsi_transport_spi: Fix function pointer check + - xtensa: fix __sync_fetch_and_{and,or}_4 declarations + - xtensa: update *pos in cpuinfo_op.next + - scsi: mpt3sas: Fix unlock imbalance + - drivers/net/wan/lapbether: Fixed the value of hard_header_len + - ALSA: hda/hdmi: fix failures at PCM open on Intel ICL and later + - net: sky2: initialize return of gm_phy_read + - drm/nouveau/i2c/g94-: increase NV_PMGR_DP_AUXCTL_TRANSACTREQ timeout + - scsi: mpt3sas: Fix error returns in BRM_status_show + - scsi: dh: Add Fujitsu device to devinfo and dh lists + - dm: use bio_uninit instead of bio_disassociate_blkg + - drivers/firmware/psci: Fix memory leakage in alloc_init_cpu_groups() + - fuse: fix weird page warning + - irqdomain/treewide: Keep firmware node unconditionally allocated + - ARM: dts: imx6qdl-gw551x: Do not use 'simple-audio-card,dai-link' + - ARM: dts: imx6qdl-gw551x: fix audio SSI + - dmabuf: use spinlock to access dmabuf->name + - drm/amd/display: Check DMCU Exists Before Loading + - SUNRPC reverting d03727b248d0 ("NFSv4 fix CLOSE not waiting for direct IO + compeletion") + - btrfs: reloc: fix reloc root leak and NULL pointer dereference + - btrfs: reloc: clear DEAD_RELOC_TREE bit for orphan roots to prevent runaway + balance + - uprobes: Change handle_swbp() to send SIGTRAP with si_code=SI_KERNEL, to fix + GDB regression + - ALSA: hda/realtek: Fixed ALC298 sound bug by adding quirk for Samsung + Notebook Pen S + - ALSA: info: Drop WARN_ON() from buffer NULL sanity check + - ASoC: rt5670: Correct RT5670_LDO_SEL_MASK + - btrfs: fix double free on ulist after backref resolution failure + - btrfs: fix mount failure caused by race with umount + - btrfs: fix page leaks after failure to lock page for delalloc + - bnxt_en: Fix race when modifying pause settings. + - bnxt_en: Fix completion ring sizing with TPA enabled. + - fpga: dfl: pci: reduce the scope of variable 'ret' + - fpga: dfl: fix bug in port reset handshake + - hippi: Fix a size used in a 'pci_free_consistent()' in an error handling + path + - vsock/virtio: annotate 'the_virtio_vsock' RCU pointer + - ax88172a: fix ax88172a_unbind() failures + - RDMA/mlx5: Use xa_lock_irq when access to SRQ table + - ASoC: Intel: bytcht_es8316: Add missed put_device() + - net: dp83640: fix SIOCSHWTSTAMP to update the struct with actual + configuration + - ieee802154: fix one possible memleak in adf7242_probe + - drm: sun4i: hdmi: Fix inverted HPD result + - net: smc91x: Fix possible memory leak in smc_drv_probe() + - bonding: check error value of register_netdevice() immediately + - mlxsw: destroy workqueue when trap_register in mlxsw_emad_init + - ionic: use offset for ethtool regs data + - ionic: fix up filter locks and debug msgs + - net: ag71xx: add missed clk_disable_unprepare in error path of probe + - net: hns3: fix error handling for desc filling + - net: dsa: microchip: call phy_remove_link_mode during probe + - netdevsim: fix unbalaced locking in nsim_create() + - qed: suppress "don't support RoCE & iWARP" flooding on HW init + - qed: suppress false-positives interrupt error messages on HW init + - ipvs: fix the connection sync failed in some cases + - net: ethernet: ave: Fix error returns in ave_init + - Revert "PCI/PM: Assume ports without DLL Link Active train links in 100 ms" + - nfsd4: fix NULL dereference in nfsd/clients display code + - enetc: Remove the mdio bus on PF probe bailout + - i2c: rcar: always clear ICSAR to avoid side effects + - i2c: i2c-qcom-geni: Fix DMA transfer race + - bonding: check return value of register_netdevice() in bond_newlink() + - geneve: fix an uninitialized value in geneve_changelink() + - serial: exar: Fix GPIO configuration for Sealevel cards based on XR17V35X + - scripts/decode_stacktrace: strip basepath from all paths + - scripts/gdb: fix lx-symbols 'gdb.error' while loading modules + - HID: i2c-hid: add Mediacom FlexBook edge13 to descriptor override + - HID: alps: support devices with report id 2 + - HID: steam: fixes race in handling device list. + - HID: apple: Disable Fn-key key-re-mapping on clone keyboards + - dmaengine: tegra210-adma: Fix runtime PM imbalance on error + - Input: add `SW_MACHINE_COVER` + - ARM: dts: n900: remove mmc1 card detect gpio + - spi: mediatek: use correct SPI_CFG2_REG MACRO + - regmap: dev_get_regmap_match(): fix string comparison + - hwmon: (aspeed-pwm-tacho) Avoid possible buffer overflow + - dmaengine: fsl-edma: fix wrong tcd endianness for big-endian cpu + - dmaengine: ioat setting ioat timeout as module parameter + - Input: synaptics - enable InterTouch for ThinkPad X1E 1st gen + - Input: elan_i2c - only increment wakeup count on touch + - usb: dwc3: pci: add support for the Intel Tiger Lake PCH -H variant + - usb: dwc3: pci: add support for the Intel Jasper Lake + - usb: gadget: udc: gr_udc: fix memleak on error handling path in gr_ep_init() + - usb: cdns3: ep0: fix some endian issues + - usb: cdns3: trace: fix some endian issues + - hwmon: (adm1275) Make sure we are reading enough data for different chips + - drm/amdgpu/gfx10: fix race condition for kiq + - drm/amdgpu: fix preemption unit test + - hwmon: (nct6775) Accept PECI Calibration as temperature source for NCT6798D + - platform/x86: ISST: Add new PCI device ids + - platform/x86: asus-wmi: allow BAT1 battery name + - hwmon: (scmi) Fix potential buffer overflow in scmi_hwmon_probe() + - ALSA: hda/realtek - fixup for yet another Intel reference board + - drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling + - arm64: Use test_tsk_thread_flag() for checking TIF_SINGLESTEP + - x86: math-emu: Fix up 'cmp' insn for clang ias + - asm-generic/mmiowb: Allow mmiowb_set_pending() when preemptible() + - drivers/perf: Prevent forced unbinding of PMU drivers + - RISC-V: Upgrade smp_mb__after_spinlock() to iorw,iorw + - binder: Don't use mmput() from shrinker function. + - usb: xhci-mtk: fix the failure of bandwidth allocation + - usb: xhci: Fix ASM2142/ASM3142 DMA addressing + - Revert "cifs: Fix the target file was deleted when rename failed." + - iwlwifi: mvm: don't call iwl_mvm_free_inactive_queue() under RCU + - tty: xilinx_uartps: Really fix id assignment + - staging: wlan-ng: properly check endpoint types + - staging: comedi: addi_apci_1032: check INSN_CONFIG_DIGITAL_TRIG shift + - staging: comedi: ni_6527: fix INSN_CONFIG_DIGITAL_TRIG support + - staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift + - staging: comedi: addi_apci_1564: check INSN_CONFIG_DIGITAL_TRIG shift + - serial: tegra: fix CREAD handling for PIO + - serial: 8250: fix null-ptr-deref in serial8250_start_tx() + - serial: 8250_mtk: Fix high-speed baud rates clamping + - /dev/mem: Add missing memory barriers for devmem_inode + - fbdev: Detect integer underflow at "struct fbcon_ops"->clear_margins. + - vt: Reject zero-sized screen buffer size. + - Makefile: Fix GCC_TOOLCHAIN_DIR prefix for Clang cross compilation + - mm/mmap.c: close race between munmap() and expand_upwards()/downwards() + - mm/memcg: fix refcount error while moving and swapping + - mm: memcg/slab: fix memory leak at non-root kmem_cache destroy + - khugepaged: fix null-pointer dereference due to race + - io-mapping: indicate mapping failure + - mmc: sdhci-of-aspeed: Fix clock divider calculation + - drm/amdgpu: Fix NULL dereference in dpm sysfs handlers + - drm/amd/powerplay: fix a crash when overclocking Vega M + - parisc: Add atomic64_set_release() define to avoid CPU soft lockups + - x86, vmlinux.lds: Page-align end of ..page_aligned sections + - ASoC: rt5670: Add new gpio1_is_ext_spk_en quirk and enable it on the Lenovo + Miix 2 10 + - ASoC: qcom: Drop HAS_DMA dependency to fix link failure + - ASoC: topology: fix kernel oops on route addition error + - ASoC: topology: fix tlvs in error handling for widget_dmixer + - dm integrity: fix integrity recalculation that is improperly skipped + - ath9k: Fix regression with Atheros 9271 + - Linux 5.4.54 + * Focal update: v5.4.53 upstream stable release (LP: #1888560) + - crypto: atmel - Fix selection of CRYPTO_AUTHENC + - crypto: atmel - Fix build error of CRYPTO_AUTHENC + - net: atlantic: fix ip dst and ipv6 address filters + - net: rmnet: fix lower interface leak + - bridge: mcast: Fix MLD2 Report IPv6 payload length check + - genetlink: remove genl_bind + - ipv4: fill fl4_icmp_{type,code} in ping_v4_sendmsg + - ipv6: fib6_select_path can not use out path for nexthop objects + - ipv6: Fix use of anycast address with loopback + - l2tp: remove skb_dst_set() from l2tp_xmit_skb() + - llc: make sure applications use ARPHRD_ETHER + - net: Added pointer check for dst->ops->neigh_lookup in dst_neigh_lookup_skb + - net_sched: fix a memory leak in atm_tc_init() + - sched: consistently handle layer3 header accesses in the presence of VLANs + - tcp: fix SO_RCVLOWAT possible hangs under high mem pressure + - tcp: make sure listeners don't initialize congestion-control state + - tcp: md5: add missing memory barriers in tcp_md5_do_add()/tcp_md5_hash_key() + - tcp: md5: do not send silly options in SYNCOOKIES + - vlan: consolidate VLAN parsing code and limit max parsing depth + - tcp: md5: refine tcp_md5_do_add()/tcp_md5_hash_key() barriers + - tcp: md5: allow changing MD5 keys in all socket states + - cgroup: fix cgroup_sk_alloc() for sk_clone_lock() + - cgroup: Fix sock_cgroup_data on big-endian. + - ip: Fix SO_MARK in RST, ACK and ICMP packets + - arm64: Introduce a way to disable the 32bit vdso + - arm64: arch_timer: Allow an workaround descriptor to disable compat vdso + - arm64: arch_timer: Disable the compat vdso for cores affected by + ARM64_WORKAROUND_1418040 + - drm/msm: fix potential memleak in error branch + - drm/msm/dpu: allow initialization of encoder locks during encoder init + - drm/exynos: Properly propagate return value in drm_iommu_attach_device() + - drm/exynos: fix ref count leak in mic_pre_enable + - x86/fpu: Reset MXCSR to default in kernel_fpu_begin() + - thermal/drivers: imx: Fix missing of_node_put() at probe time + - blk-mq-debugfs: update blk_queue_flag_name[] accordingly for new flags + - m68k: nommu: register start of the memory with memblock + - m68k: mm: fix node memblock init + - dt-bindings: mailbox: zynqmp_ipi: fix unit address + - cifs: prevent truncation from long to int in wait_for_free_credits + - arm64/alternatives: use subsections for replacement sequences + - tpm_tis: extra chip->ops check on error path in tpm_tis_core_init + - gfs2: read-only mounts should grab the sd_freeze_gl glock + - i2c: eg20t: Load module automatically if ID matches + - arm64/alternatives: don't patch up internal branches + - iio:magnetometer:ak8974: Fix alignment and data leak issues + - iio:humidity:hdc100x Fix alignment and data leak issues + - iio: magnetometer: ak8974: Fix runtime PM imbalance on error + - iio: core: add missing IIO_MOD_H2/ETHANOL string identifiers + - iio: mma8452: Add missed iio_device_unregister() call in mma8452_probe() + - iio: pressure: zpa2326: handle pm_runtime_get_sync failure + - iio:humidity:hts221 Fix alignment and data leak issues + - iio:pressure:ms5611 Fix buffer element alignment + - iio:health:afe4403 Fix timestamp alignment and prevent data leak. + - spi: spi-fsl-dspi: Fix lockup if device is shutdown during SPI transfer + - net: dsa: bcm_sf2: Fix node reference count + - of: of_mdio: Correct loop scanning logic + - net: macb: call pm_runtime_put_sync on failure path + - net: ethernet: mvneta: Do not error out in non serdes modes + - net: ethernet: mvneta: Add back interface mode validation + - Revert "usb/ohci-platform: Fix a warning when hibernating" + - Revert "usb/ehci-platform: Set PM runtime as active on resume" + - Revert "usb/xhci-plat: Set PM runtime as active on resume" + - net: sfp: add support for module quirks + - net: sfp: add some quirks for GPON modules + - ARM: OMAP4+: remove pdata quirks for omap4+ iommus + - ARM: OMAP2+: Add workaround for DRA7 DSP MStandby errata i879 + - ARM: OMAP2+: use separate IOMMU pdata to fix DRA7 IPU1 boot + - mmc: mmci: Support any block sizes for ux500v2 and qcom variant + - HID: quirks: Remove ITE 8595 entry from hid_have_special_driver + - ARM: at91: pm: add quirk for sam9x60's ulp1 + - drm/sun4i: tcon: Separate quirks for tcon0 and tcon1 on A20 + - scsi: sr: remove references to BLK_DEV_SR_VENDOR, leave it enabled + - [Config] updateconfigs for BLK_DEV_SR_VENDOR + - bus: ti-sysc: Rename clk related quirks to pre_reset and post_reset quirks + - bus: ti-sysc: Consider non-existing registers too when matching quirks + - bus: ti-sysc: Handle module unlock quirk needed for some RTC + - bus: ti-sysc: Detect display subsystem related devices + - arm64: dts: g12-common: add parkmode_disable_ss_quirk on DWC3 controller + - bus: ti-sysc: Detect EDMA and set quirk flags for tptc + - ALSA: usb-audio: Add support for MOTU MicroBook IIc + - Input: goodix - fix touch coordinates on Cube I15-TC + - ALSA: usb-audio: Create a registration quirk for Kingston HyperX Amp + (0951:16d8) + - doc: dt: bindings: usb: dwc3: Update entries for disabling SS instances in + park mode + - mmc: sdhci: do not enable card detect interrupt for gpio cd type + - ALSA: usb-audio: Rewrite registration quirk handling + - ACPI: video: Use native backlight on Acer Aspire 5783z + - ALSA: usb-audio: Add registration quirk for Kingston HyperX Cloud Alpha S + - ALSA: usb-audio: Add quirk for Focusrite Scarlett 2i2 + - Input: mms114 - add extra compatible for mms345l + - ACPI: video: Use native backlight on Acer TravelMate 5735Z + - bus: ti-sysc: Use optional clocks on for enable and wait for softreset bit + - ALSA: usb-audio: Add registration quirk for Kingston HyperX Cloud Flight S + - iio:health:afe4404 Fix timestamp alignment and prevent data leak. + - soundwire: intel: fix memory leak with devm_kasprintf + - dmaengine: sh: usb-dmac: set tx_result parameters + - phy: sun4i-usb: fix dereference of pointer phy0 before it is null checked + - arm64: dts: meson: add missing gxl rng clock + - arm64: dts: meson-gxl-s805x: reduce initial Mali450 core frequency + - bus: ti-sysc: Fix wakeirq sleeping function called from invalid context + - bus: ti-sysc: Fix sleeping function called from invalid context for RTC + quirk + - bus: ti-sysc: Do not disable on suspend for no-idle + - iio: adc: ad7780: Fix a resource handling path in 'ad7780_probe()' + - dmaengine: dw: Initialize channel before each transfer + - dmaengine: dmatest: stop completed threads when running without set channel + - spi: spi-sun6i: sun6i_spi_transfer_one(): fix setting of clock rate + - usb: gadget: udc: atmel: fix uninitialized read in debug printk + - staging: comedi: verify array index is correct before using it + - clk: mvebu: ARMADA_AP_CPU_CLK needs to select ARMADA_AP_CP_HELPER + - clk: AST2600: Add mux for EMMC clock + - NFS: Fix interrupted slots by sending a solo SEQUENCE operation + - fuse: don't ignore errors from fuse_writepages_fill() + - ARM: dts: Fix dcan driver probe failed on am437x platform + - Revert "thermal: mediatek: fix register index error" + - xprtrdma: fix incorrect header size calculations + - ARM: dts: socfpga: Align L2 cache-controller nodename with dtschema + - arm64: dts: spcfpga: Align GIC, NAND and UART nodenames with dtschema + - keys: asymmetric: fix error return code in software_key_query() + - regmap: debugfs: Don't sleep while atomic for fast_io regmaps + - copy_xstate_to_kernel: Fix typo which caused GDB regression + - arm: dts: mt7623: add phy-mode property for gmac2 + - soc: qcom: socinfo: add missing soc_id sysfs entry + - habanalabs: Align protection bits configuration of all TPCs + - PCI/PM: Call .bridge_d3() hook only if non-NULL + - perf stat: Zero all the 'ena' and 'run' array slot stats for interval mode + - soc: qcom: rpmh: Update dirty flag only when data changes + - soc: qcom: rpmh: Invalidate SLEEP and WAKE TCSes before flushing new data + - soc: qcom: rpmh-rsc: Clear active mode configuration for wake TCS + - soc: qcom: rpmh-rsc: Allow using free WAKE TCS for active request + - RDMA/mlx5: Verify that QP is created with RQ or SQ + - mtd: rawnand: marvell: Fix the condition on a return code + - mtd: rawnand: marvell: Use nand_cleanup() when the device is not yet + registered + - mtd: rawnand: marvell: Fix probe error path + - mtd: rawnand: timings: Fix default tR_max and tCCS_min timings + - mtd: rawnand: brcmnand: correctly verify erased pages + - mtd: rawnand: brcmnand: fix CS0 layout + - mtd: rawnand: oxnas: Keep track of registered devices + - mtd: rawnand: oxnas: Unregister all devices on error + - mtd: rawnand: oxnas: Release all devices in the _remove() path + - clk: qcom: gcc: Add GPU and NPU clocks for SM8150 + - clk: qcom: gcc: Add missing UFS clocks for SM8150 + - slimbus: core: Fix mismatch in of_node_get/put + - HID: logitech-hidpp: avoid repeated "multiplier = " log messages + - HID: magicmouse: do not set up autorepeat + - HID: quirks: Always poll Obins Anne Pro 2 keyboard + - HID: quirks: Ignore Simply Automated UPB PIM + - ALSA: line6: Perform sanity check for each URB creation + - ALSA: line6: Sync the pending work cancel at disconnection + - ALSA: usb-audio: Fix race against the error recovery URB submission + - ALSA: hda/realtek - change to suitable link model for ASUS platform + - ALSA: hda/realtek: enable headset mic of ASUS ROG Zephyrus G14(G401) series + with ALC289 + - ALSA: hda/realtek: Enable headset mic of Acer TravelMate B311R-31 with + ALC256 + - ALSA: hda/realtek - Enable Speaker for ASUS UX533 and UX534 + - ALSA: hda/realtek - Enable Speaker for ASUS UX563 + - USB: c67x00: fix use after free in c67x00_giveback_urb + - usb: dwc2: Fix shutdown callback in platform + - usb: chipidea: core: add wakeup support for extcon + - usb: gadget: function: fix missing spinlock in f_uac1_legacy + - USB: serial: iuu_phoenix: fix memory corruption + - USB: serial: cypress_m8: enable Simply Automated UPB PIM + - USB: serial: ch341: add new Product ID for CH340 + - USB: serial: option: add GosunCn GM500 series + - virt: vbox: Fix VBGL_IOCTL_VMMDEV_REQUEST_BIG and _LOG req numbers to match + upstream + - virt: vbox: Fix guest capabilities mask check + - Revert "tty: xilinx_uartps: Fix missing id assignment to the console" + - virtio: virtio_console: add missing MODULE_DEVICE_TABLE() for rproc serial + - serial: mxs-auart: add missed iounmap() in probe failure and remove + - ovl: fix regression with re-formatted lower squashfs + - ovl: inode reference leak in ovl_is_inuse true case. + - ovl: relax WARN_ON() when decoding lower directory file handle + - ovl: fix unneeded call to ovl_change_flags() + - fuse: ignore 'data' argument of mount(..., MS_REMOUNT) + - fuse: use ->reconfigure() instead of ->remount_fs() + - fuse: Fix parameter for FS_IOC_{GET,SET}FLAGS + - Revert "zram: convert remaining CLASS_ATTR() to CLASS_ATTR_RO()" + - mei: bus: don't clean driver pointer + - Input: i8042 - add Lenovo XiaoXin Air 12 to i8042 nomux list + - uio_pdrv_genirq: Remove warning when irq is not specified + - uio_pdrv_genirq: fix use without device tree and no interrupt + - scsi: megaraid_sas: Remove undefined ENABLE_IRQ_POLL macro + - timer: Prevent base->clk from moving backward + - timer: Fix wheel index calculation on last level + - riscv: use 16KB kernel stack on 64-bit + - hwmon: (emc2103) fix unable to change fan pwm1_enable attribute + - powerpc/book3s64/pkeys: Fix pkey_access_permitted() for execute disable pkey + - powerpc/pseries/svm: Fix incorrect check for shared_lppaca_size + - intel_th: pci: Add Jasper Lake CPU support + - intel_th: pci: Add Tiger Lake PCH-H support + - intel_th: pci: Add Emmitsburg PCH support + - intel_th: Fix a NULL dereference when hub driver is not loaded + - dmaengine: fsl-edma: Fix NULL pointer exception in fsl_edma_tx_handler + - dmaengine: mcf-edma: Fix NULL pointer exception in mcf_edma_tx_handler + - dmaengine: fsl-edma-common: correct DSIZE_32BYTE + - misc: atmel-ssc: lock with mutex instead of spinlock + - thermal: int3403_thermal: Downgrade error message + - thermal/drivers/cpufreq_cooling: Fix wrong frequency converted from power + - arm64: ptrace: Override SPSR.SS when single-stepping is enabled + - arm64: ptrace: Consistently use pseudo-singlestep exceptions + - arm64: compat: Ensure upper 32 bits of x0 are zero on syscall return + - sched: Fix unreliable rseq cpu_id for new tasks + - sched/fair: handle case of task_h_load() returning 0 + - genirq/affinity: Handle affinity setting on inactive interrupts correctly + - drm/amdgpu/sdma5: fix wptr overwritten in ->get_wptr() + - drm/i915/gt: Ignore irq enabling on the virtual engines + - block: fix splitting segments on boundary masks + - block: fix get_max_segment_size() overflow on 32bit arch + - libceph: don't omit recovery_deletes in target_copy() + - rxrpc: Fix trace string + - spi: sprd: switch the sequence of setting WDG_LOAD_LOW and _HIGH + - ionic: export features for vlans to use + - iommu/vt-d: Make Intel SVM code 64-bit only + - drm/i915/gvt: Fix two CFL MMIO handling caused by regression. + - gpio: pca953x: disable regmap locking for automatic address incrementing + - Linux 5.4.53 + * linux-libc-dev broken for crossbuilding, Multi-Arch:same violation + (LP: #1886188) + - [Packaging] Produce linux-libc-dev package for riscv64 + - [Debian] Disallow building linux-libc-dev from linux-riscv + * [UBUNTU 20.04] DIF and DIX support in zfcp (s390x) is broken and the kernel + crashes unconditionally (LP: #1887124) + - scsi: zfcp: signal incomplete or error for sync exchange config/port data + - scsi: zfcp: diagnostics buffer caching and use for exchange port data + - scsi: zfcp: add diagnostics buffer for exchange config data + - scsi: zfcp: support retrieval of SFP Data via Exchange Port Data + - scsi: zfcp: introduce sysfs interface for diagnostics of local SFP + transceiver + - scsi: zfcp: implicitly refresh port-data diagnostics when reading sysfs + - scsi: zfcp: introduce sysfs interface to read the local B2B-Credit + - scsi: zfcp: implicitly refresh config-data diagnostics when reading sysfs + - scsi: zfcp: move maximum age of diagnostic buffers into a per-adapter + variable + - scsi: zfcp: proper indentation to reduce confusion in zfcp_erp_required_act + - scsi: zfcp: fix wrong data and display format of SFP+ temperature + - scsi: zfcp: expose fabric name as common fc_host sysfs attribute + - scsi: zfcp: wire previously driver-specific sysfs attributes also to fc_host + - scsi: zfcp: fix fc_host attributes that should be unknown on local link down + - scsi: zfcp: auto variables for dereferenced structs in open port handler + - scsi: zfcp: report FC Endpoint Security in sysfs + - scsi: zfcp: log FC Endpoint Security of connections + - scsi: zfcp: trace FC Endpoint Security of FCP devices and connections + - scsi: zfcp: enhance handling of FC Endpoint Security errors + - scsi: zfcp: log FC Endpoint Security errors + - scsi: zfcp: use fallthrough; + - scsi: zfcp: Move shost modification after QDIO (re-)open into fenced + function + - scsi: zfcp: Move shost updates during xconfig data handling into fenced + function + - scsi: zfcp: Move fc_host updates during xport data handling into fenced + function + - scsi: zfcp: Fence fc_host updates during link-down handling + - scsi: zfcp: Move p-t-p port allocation to after xport data + - scsi: zfcp: Fence adapter status propagation for common statuses + - scsi: zfcp: Fence early sysfs interfaces for accesses of shost objects + - scsi: zfcp: Move allocation of the shost object to after xconf- and xport- + data + * Enable Quectel EG95 LTE modem [2c7c:0195] (LP: #1886744) + - net: usb: qmi_wwan: add support for Quectel EG95 LTE modem + - USB: serial: option: add Quectel EG95 LTE modem + * Kernel Regression between 5.4.0-26 and 5.4.0-40 causes laptop internal audio + devices to fail to load w/o unacceptable workaround (Lenovo IdeaPad 5 + 15IIL05) (LP: #1886341) + - ASoC: SOF: intel: hda: Modify signature for hda_codec_probe_bus() + - ASoC: SOF: Intel: drop HDA codec upon probe failure + - ASoC: SOF: Intel: hda: move i915 init earlier + * [UBUNTU 20.04] smc: SMC connections hang with later-level implementations + (LP: #1882088) + - net/smc: tolerate future SMCD versions + * zfs: backport AES-GCM performance accelleration (LP: #1881107) + - debian/dkms-versions: update ZFS dkms package version (LP: #1881107) + * Regression in kernel 4.15.0-91 causes kernel panic with Bcache + (LP: #1867916) + - bcache: check and adjust logical block size for backing devices + * [SRU][OEM-5.6/U] Fix r8117 firmware base issue (LP: #1885072) + - r8169: add helper r8168g_phy_param + - r8169: add support for RTL8117 + - r8169: load firmware for RTL8168fp/RTL8117 + - r8169: fix OCP access on RTL8117 + - r8169: fix firmware not resetting tp->ocp_base + * [UBUNTU 20.04] Deflate counters reported by lscpumf are not valid or + available with perf (LP: #1881096) + - s390/cpum_cf: Add new extended counters for IBM z15 + * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757) + - SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups + * shiftfs: fix btrfs regression (LP: #1884767) + - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation" + * Focal update: v5.4.52 upstream stable release (LP: #1887853) + - KVM: s390: reduce number of IO pins to 1 + - spi: spi-fsl-dspi: Adding shutdown hook + - spi: spi-fsl-dspi: Fix lockup if device is removed during SPI transfer + - regmap: fix alignment issue + - perf/x86/rapl: Move RAPL support to common x86 code + - perf/x86/rapl: Fix RAPL config variable bug + - [Packaging] module intel-rapl-perf rename + - ARM: dts: omap4-droid4: Fix spi configuration and increase rate + - drm/ttm: Fix dma_fence refcnt leak when adding move fence + - drm/tegra: hub: Do not enable orphaned window group + - gpu: host1x: Detach driver on unregister + - drm: mcde: Fix display initialization problem + - ASoC: SOF: Intel: add PCI ID for CometLake-S + - ALSA: hda: Intel: add missing PCI IDs for ICL-H, TGL-H and EKL + - spi: spidev: fix a race between spidev_release and spidev_remove + - spi: spidev: fix a potential use-after-free in spidev_release() + - net: ethernet: mvneta: Fix Serdes configuration for SoCs without comphy + - net: ethernet: mvneta: Add 2500BaseX support for SoCs without comphy + - ixgbe: protect ring accesses with READ- and WRITE_ONCE + - i40e: protect ring accesses with READ- and WRITE_ONCE + - ibmvnic: continue to init in CRQ reset returns H_CLOSED + - powerpc/kvm/book3s64: Fix kernel crash with nested kvm & DEBUG_VIRTUAL + - iommu/vt-d: Don't apply gfx quirks to untrusted devices + - drm: panel-orientation-quirks: Add quirk for Asus T101HA panel + - drm: panel-orientation-quirks: Use generic orientation-data for Acer S1003 + - s390/kasan: fix early pgm check handler execution + - cifs: update ctime and mtime during truncate + - ARM: imx6: add missing put_device() call in imx6q_suspend_init() + - scsi: mptscsih: Fix read sense data size + - usb: dwc3: pci: Fix reference count leak in dwc3_pci_resume_work + - block: release bip in a right way in error path + - nvme-rdma: assign completion vector correctly + - x86/entry: Increase entry_stack size to a full page + - sched/core: Check cpus_mask, not cpus_ptr in __set_cpus_allowed_ptr(), to + fix mask corruption + - net: qrtr: Fix an out of bounds read qrtr_endpoint_post() + - gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2 + - gpio: pca953x: Fix GPIO resource leak on Intel Galileo Gen 2 + - nl80211: don't return err unconditionally in nl80211_start_ap() + - drm/mediatek: Check plane visibility in atomic_update + - bpf, sockmap: RCU splat with redirect and strparser error or TLS + - bpf, sockmap: RCU dereferenced psock may be used outside RCU block + - netfilter: ipset: call ip_set_free() instead of kfree() + - net: mvneta: fix use of state->speed + - net: cxgb4: fix return error value in t4_prep_fw + - IB/sa: Resolv use-after-free in ib_nl_make_request() + - net: dsa: microchip: set the correct number of ports + - netfilter: conntrack: refetch conntrack after nf_conntrack_update() + - perf report TUI: Fix segmentation fault in perf_evsel__hists_browse() + - perf intel-pt: Fix recording PEBS-via-PT with registers + - perf intel-pt: Fix PEBS sample for XMM registers + - smsc95xx: check return value of smsc95xx_reset + - smsc95xx: avoid memory leak in smsc95xx_bind + - net: hns3: add a missing uninit debugfs when unload driver + - net: hns3: fix use-after-free when doing self test + - ALSA: compress: fix partial_drain completion state + - RDMA/siw: Fix reporting vendor_part_id + - arm64: kgdb: Fix single-step exception handling oops + - nbd: Fix memory leak in nbd_add_socket + - cxgb4: fix all-mask IP address comparison + - IB/mlx5: Fix 50G per lane indication + - qed: Populate nvm-file attributes while reading nvm config partition. + - net/mlx5: Fix eeprom support for SFP module + - net/mlx5e: Fix 50G per lane indication + - bnxt_en: fix NULL dereference in case SR-IOV configuration fails + - net: macb: fix wakeup test in runtime suspend/resume routines + - net: macb: mark device wake capable when "magic-packet" property present + - net: macb: fix call to pm_runtime in the suspend/resume functions + - mlxsw: spectrum_router: Remove inappropriate usage of WARN_ON() + - mlxsw: pci: Fix use-after-free in case of failed devlink reload + - IB/hfi1: Do not destroy hfi1_wq when the device is shut down + - IB/hfi1: Do not destroy link_wq when the device is shut down + - ALSA: opl3: fix infoleak in opl3 + - ALSA: hda - let hs_mic be picked ahead of hp_mic + - ALSA: usb-audio: add quirk for MacroSilicon MS2109 + - ALSA: usb-audio: Add implicit feedback quirk for RTX6001 + - ALSA: hda/realtek - Fix Lenovo Thinkpad X1 Carbon 7th quirk subdevice id + - ALSA: hda/realtek - Enable audio jacks of Acer vCopperbox with ALC269VC + - ALSA: hda/realtek: Enable headset mic of Acer C20-820 with ALC269VC + - ALSA: hda/realtek: Enable headset mic of Acer Veriton N4660G with ALC269VC + - KVM: arm64: Fix definition of PAGE_HYP_DEVICE + - KVM: arm64: Stop clobbering x0 for HVC_SOFT_RESTART + - KVM: arm64: Annotate hyp NMI-related functions as __always_inline + - KVM: x86: bit 8 of non-leaf PDPEs is not reserved + - KVM: x86: Inject #GP if guest attempts to toggle CR4.LA57 in 64-bit mode + - KVM: x86: Mark CR4.TSD as being possibly owned by the guest + - KVM: arm64: Fix kvm_reset_vcpu() return code being incorrect with SVE + - kallsyms: Refactor kallsyms_show_value() to take cred + - module: Refactor section attr into bin attribute + - module: Do not expose section addresses to non-CAP_SYSLOG + - kprobes: Do not expose probe addresses to non-CAP_SYSLOG + - bpf: Check correct cred for CAP_SYSLOG in bpf_dump_raw_ok() + - btrfs: fix fatal extent_buffer readahead vs releasepage race + - btrfs: fix double put of block group with nocow + - drm/radeon: fix double free + - drm/amdgpu: don't do soft recovery if gpu_recovery=0 + - dm: use noio when sending kobject event + - mmc: meson-gx: limit segments to 1 when dram-access-quirk is needed + - ARC: entry: fix potential EFA clobber when TIF_SYSCALL_TRACE + - ARC: elf: use right ELF_ARCH + - s390/setup: init jump labels before command line parsing + - s390/mm: fix huge pte soft dirty copying + - blk-mq: consider non-idle request as "inflight" in blk_mq_rq_inflight() + - dm writecache: reject asynchronous pmem devices + - perf scripts python: export-to-postgresql.py: Fix struct.pack() int argument + - perf scripts python: exported-sql-viewer.py: Fix zero id in call graph + 'Find' result + - perf scripts python: exported-sql-viewer.py: Fix zero id in call tree 'Find' + result + - perf scripts python: exported-sql-viewer.py: Fix unexpanded 'Find' result + - pwm: jz4740: Fix build failure + - s390: Change s390_kernel_write() return type to match memcpy() + - s390/maccess: add no DAT mode to kernel_write + - Linux 5.4.52 + * Focal update: v5.4.45 upstream stable release (LP: #1882802) // Focal + update: v5.4.52 upstream stable release (LP: #1887853) + - Revert "cgroup: Add memory barriers to plug cgroup_rstat_updated() race + window" + * Focal update: v5.4.51 upstream stable release (LP: #1886995) + - io_uring: make sure async workqueue is canceled on exit + - mm: fix swap cache node allocation mask + - EDAC/amd64: Read back the scrub rate PCI register on F15h + - usbnet: smsc95xx: Fix use-after-free after removal + - sched/debug: Make sd->flags sysctl read-only + - mm/slub.c: fix corrupted freechain in deactivate_slab() + - mm/slub: fix stack overruns with SLUB_STATS + - rxrpc: Fix race between incoming ACK parser and retransmitter + - usb: usbtest: fix missing kfree(dev->buf) in usbtest_disconnect + - tools lib traceevent: Add append() function helper for appending strings + - tools lib traceevent: Handle __attribute__((user)) in field names + - s390/debug: avoid kernel warning on too large number of pages + - nvme-multipath: set bdi capabilities once + - nvme-multipath: fix deadlock between ana_work and scan_work + - nvme-multipath: fix deadlock due to head->lock + - nvme-multipath: fix bogus request queue reference put + - kgdb: Avoid suspicious RCU usage warning + - selftests: tpm: Use /bin/sh instead of /bin/bash + - crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock() + - drm/msm/dpu: fix error return code in dpu_encoder_init + - rxrpc: Fix afs large storage transmission performance drop + - RDMA/counter: Query a counter before release + - cxgb4: use unaligned conversion for fetching timestamp + - cxgb4: parse TC-U32 key values and masks natively + - cxgb4: fix endian conversions for L4 ports in filters + - cxgb4: use correct type for all-mask IP address comparison + - cxgb4: fix SGE queue dump destination buffer context + - hwmon: (max6697) Make sure the OVERT mask is set correctly + - hwmon: (acpi_power_meter) Fix potential memory leak in + acpi_power_meter_add() + - thermal/drivers/mediatek: Fix bank number settings on mt8183 + - thermal/drivers/rcar_gen3: Fix undefined temperature if negative + - nfsd4: fix nfsdfs reference count loop + - nfsd: fix nfsdfs inode reference count leak + - drm: sun4i: hdmi: Remove extra HPD polling + - virtio-blk: free vblk-vqs in error path of virtblk_probe() + - SMB3: Honor 'posix' flag for multiuser mounts + - nvme: fix identify error status silent ignore + - nvme: fix a crash in nvme_mpath_add_disk + - samples/vfs: avoid warning in statx override + - i2c: algo-pca: Add 0x78 as SCL stuck low status for PCA9665 + - i2c: mlxcpld: check correct size of maximum RECV_LEN packet + - spi: spi-fsl-dspi: Fix external abort on interrupt in resume or exit paths + - nfsd: apply umask on fs without ACL support + - Revert "ALSA: usb-audio: Improve frames size computation" + - SMB3: Honor 'seal' flag for multiuser mounts + - SMB3: Honor persistent/resilient handle flags for multiuser mounts + - SMB3: Honor lease disabling for multiuser mounts + - SMB3: Honor 'handletimeout' flag for multiuser mounts + - cifs: Fix the target file was deleted when rename failed. + - MIPS: lantiq: xway: sysctrl: fix the GPHY clock alias names + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen + - drm/amd/display: Only revalidate bandwidth on medium and fast updates + - drm/amdgpu: use %u rather than %d for sclk/mclk + - drm/amdgpu/atomfirmware: fix vram_info fetching for renoir + - dma-buf: Move dma_buf_release() from fops to dentry_ops + - irqchip/gic: Atomically update affinity + - mm, compaction: fully assume capture is not NULL in compact_zone_order() + - mm, compaction: make capture control handling safe wrt interrupts + - x86/resctrl: Fix memory bandwidth counter width for AMD + - dm zoned: assign max_io_len correctly + - [Config] updateconfigs for EFI_CUSTOM_SSDT_OVERLAYS + - efi: Make it possible to disable efivar_ssdt entirely + - Linux 5.4.51 + * Focal update: v5.4.50 upstream stable release (LP: #1885942) + - block/bio-integrity: don't free 'buf' if bio_integrity_add_page() failed + - enetc: Fix tx rings bitmap iteration range, irq handling + - geneve: allow changing DF behavior after creation + - ibmveth: Fix max MTU limit + - mld: fix memory leak in ipv6_mc_destroy_dev() + - mvpp2: ethtool rxtx stats fix + - net: bridge: enfore alignment for ethernet address + - net: core: reduce recursion limit value + - net: Do not clear the sock TX queue in sk_set_socket() + - net: fix memleak in register_netdevice() + - net: Fix the arp error in some cases + - net: increment xmit_recursion level in dev_direct_xmit() + - net: usb: ax88179_178a: fix packet alignment padding + - openvswitch: take into account de-fragmentation/gso_size in + execute_check_pkt_len + - rocker: fix incorrect error handling in dma_rings_init + - rxrpc: Fix notification call on completion of discarded calls + - sctp: Don't advertise IPv4 addresses if ipv6only is set on the socket + - tcp: don't ignore ECN CWR on pure ACK + - tcp: grow window for OOO packets only for SACK flows + - tg3: driver sleeps indefinitely when EEH errors exceed eeh_max_freezes + - ip6_gre: fix use-after-free in ip6gre_tunnel_lookup() + - net: phy: Check harder for errors in get_phy_id() + - ip_tunnel: fix use-after-free in ip_tunnel_lookup() + - sch_cake: don't try to reallocate or unshare skb unconditionally + - sch_cake: don't call diffserv parsing code when it is not needed + - sch_cake: fix a few style nits + - tcp_cubic: fix spurious HYSTART_DELAY exit upon drop in min RTT + - Revert "i2c: tegra: Fix suspending in active runtime PM state" + - btrfs: fix a block group ref counter leak after failure to remove block + group + - net: sched: export __netdev_watchdog_up() + - fix a braino in "sparc32: fix register window handling in + genregs32_[gs]et()" + - ALSA: usb-audio: Fix potential use-after-free of streams + - binder: fix null deref of proc->context + - USB: ohci-sm501: Add missed iounmap() in remove + - usb: dwc2: Postponed gadget registration to the udc class driver + - usb: add USB_QUIRK_DELAY_INIT for Logitech C922 + - USB: ehci: reopen solution for Synopsys HC bug + - usb: host: xhci-mtk: avoid runtime suspend when removing hcd + - xhci: Poll for U0 after disabling USB2 LPM + - usb: host: ehci-exynos: Fix error check in exynos_ehci_probe() + - usb: typec: tcpci_rt1711h: avoid screaming irq causing boot hangs + - ALSA: usb-audio: Add implicit feedback quirk for SSL2+. + - ALSA: usb-audio: add quirk for Denon DCD-1500RE + - ALSA: usb-audio: add quirk for Samsung USBC Headset (AKG) + - ALSA: usb-audio: Fix OOB access of mixer element list + - usb: cdns3: trace: using correct dir value + - usb: cdns3: ep0: fix the test mode set incorrectly + - usb: cdns3: ep0: add spinlock for cdns3_check_new_setup + - scsi: qla2xxx: Keep initiator ports after RSCN + - scsi: zfcp: Fix panic on ERP timeout for previously dismissed ERP action + - cifs: Fix cached_fid refcnt leak in open_shroot + - cifs/smb3: Fix data inconsistent when punch hole + - cifs/smb3: Fix data inconsistent when zero file range + - xhci: Fix incorrect EP_STATE_MASK + - xhci: Fix enumeration issue when setting max packet size for FS devices. + - xhci: Return if xHCI doesn't support LPM + - cdc-acm: Add DISABLE_ECHO quirk for Microchip/SMSC chip + - loop: replace kill_bdev with invalidate_bdev + - IB/mad: Fix use after free when destroying MAD agent + - IB/hfi1: Fix module use count flaw due to leftover module put calls + - bus: ti-sysc: Flush posted write on enable and disable + - bus: ti-sysc: Ignore clockactivity unless specified as a quirk + - ARM: OMAP2+: Fix legacy mode dss_reset + - xfrm: Fix double ESP trailer insertion in IPsec crypto offload. + - ASoC: q6asm: handle EOS correctly + - efi/tpm: Verify event log header before parsing + - efi/esrt: Fix reference count leak in esre_create_sysfs_entry. + - ASoc: q6afe: add support to get port direction + - ASoC: qcom: common: set correct directions for dailinks + - regualtor: pfuze100: correct sw1a/sw2 on pfuze3000 + - RDMA/siw: Fix pointer-to-int-cast warning in siw_rx_pbl() + - ASoC: fsl_ssi: Fix bclk calculation for mono channel + - samples/bpf: xdp_redirect_cpu: Set MAX_CPUS according to NR_CPUS + - bpf, xdp, samples: Fix null pointer dereference in *_user code + - ARM: dts: am335x-pocketbeagle: Fix mmc0 Write Protect + - ARM: dts: Fix duovero smsc interrupt for suspend + - x86/resctrl: Fix a NULL vs IS_ERR() static checker warning in + rdt_cdp_peer_get() + - regmap: Fix memory leak from regmap_register_patch + - devmap: Use bpf_map_area_alloc() for allocating hash buckets + - bpf: Don't return EINVAL from {get,set}sockopt when optlen > PAGE_SIZE + - ARM: dts: NSP: Correct FA2 mailbox node + - rxrpc: Fix handling of rwind from an ACK packet + - RDMA/rvt: Fix potential memory leak caused by rvt_alloc_rq + - RDMA/qedr: Fix KASAN: use-after-free in ucma_event_handler+0x532 + - RDMA/cma: Protect bind_list and listen_list while finding matching cm id + - ASoC: rockchip: Fix a reference count leak. + - s390/qeth: fix error handling for isolation mode cmds + - RDMA/mad: Fix possible memory leak in ib_mad_post_receive_mads() + - selftests/net: report etf errors correctly + - iommu/vt-d: Enable PCI ACS for platform opt in hint + - iommu/vt-d: Update scalable mode paging structure coherency + - net: qed: fix left elements count calculation + - net: qed: fix async event callbacks unregistering + - net: qede: stop adding events on an already destroyed workqueue + - net: qed: fix NVMe login fails over VFs + - net: qed: fix excessive QM ILT lines consumption + - net: qede: fix PTP initialization on recovery + - net: qede: fix use-after-free on recovery and AER handling + - cxgb4: move handling L2T ARP failures to caller + - ARM: imx5: add missing put_device() call in imx_suspend_alloc_ocram() + - scsi: lpfc: Avoid another null dereference in lpfc_sli4_hba_unset() + - usb: gadget: udc: Potential Oops in error handling code + - usb: renesas_usbhs: getting residue from callback_result + - nvme: don't protect ns mutation with ns->head->lock + - netfilter: ipset: fix unaligned atomic access + - net: bcmgenet: use hardware padding of runt frames + - clk: sifive: allocate sufficient memory for struct __prci_data + - i2c: fsi: Fix the port number field in status register + - i2c: core: check returned size of emulated smbus block read + - afs: Fix storage of cell names + - sched/deadline: Initialize ->dl_boosted + - sched/core: Fix PI boosting between RT and DEADLINE tasks + - sata_rcar: handle pm_runtime_get_sync failure cases + - ata/libata: Fix usage of page address by page_address in + ata_scsi_mode_select_xlat function + - drm/amd/display: Use kfree() to free rgb_user in + calculate_user_regamma_ramp() + - riscv/atomic: Fix sign extension for RV64I + - hwrng: ks-sa - Fix runtime PM imbalance on error + - ibmvnic: Harden device login requests + - net: alx: fix race condition in alx_remove + - test_objagg: Fix potential memory leak in error handling + - pinctrl: qcom: spmi-gpio: fix warning about irq chip reusage + - pinctrl: tegra: Use noirq suspend/resume callbacks + - s390/ptrace: pass invalid syscall numbers to tracing + - s390/ptrace: fix setting syscall number + - s390/vdso: Use $(LD) instead of $(CC) to link vDSO + - s390/vdso: fix vDSO clock_getres() + - arm64: sve: Fix build failure when ARM64_SVE=y and SYSCTL=n + - kbuild: improve cc-option to clean up all temporary files + - recordmcount: support >64k sections + - kprobes: Suppress the suspicious RCU warning on kprobes + - blktrace: break out of blktrace setup on concurrent calls + - block: update hctx map when use multiple maps + - RISC-V: Don't allow write+exec only page mapping request in mmap + - ALSA: hda: Add NVIDIA codec IDs 9a & 9d through a0 to patch table + - ALSA: hda/realtek - Add quirk for MSI GE63 laptop + - ACPI: sysfs: Fix pm_profile_attr type + - erofs: fix partially uninitialized misuse in z_erofs_onlinepage_fixup + - KVM: X86: Fix MSR range of APIC registers in X2APIC mode + - KVM: nVMX: Plumb L2 GPA through to PML emulation + - KVM: VMX: Stop context switching MSR_IA32_UMWAIT_CONTROL + - x86/cpu: Use pinning mask for CR4 bits needing to be 0 + - x86/asm/64: Align start of __clear_user() loop to 16-bytes + - btrfs: fix bytes_may_use underflow when running balance and scrub in + parallel + - btrfs: fix data block group relocation failure due to concurrent scrub + - btrfs: check if a log root exists before locking the log_mutex on unlink + - btrfs: fix failure of RWF_NOWAIT write into prealloc extent beyond eof + - mm/slab: use memzero_explicit() in kzfree() + - ocfs2: avoid inode removal while nfsd is accessing it + - ocfs2: load global_inode_alloc + - ocfs2: fix value of OCFS2_INVALID_SLOT + - ocfs2: fix panic on nfs server over ocfs2 + - mm/memcontrol.c: add missed css_put() + - arm64: perf: Report the PC value in REGS_ABI_32 mode + - arm64: dts: imx8mm-evk: correct ldo1/ldo2 voltage range + - arm64: dts: imx8mn-ddr4-evk: correct ldo1/ldo2 voltage range + - tracing: Fix event trigger to accept redundant spaces + - ring-buffer: Zero out time extend if it is nested and not absolute + - drm/amd: fix potential memleak in err branch + - drm: rcar-du: Fix build error + - drm/radeon: fix fb_div check in ni_init_smc_spll_table() + - drm/amdgpu: add fw release for sdma v5_0 + - Staging: rtl8723bs: prevent buffer overflow in update_sta_support_rate() + - sunrpc: fixed rollback in rpc_gssd_dummy_populate() + - SUNRPC: Properly set the @subbuf parameter of xdr_buf_subsegment() + - pNFS/flexfiles: Fix list corruption if the mirror count changes + - NFSv4 fix CLOSE not waiting for direct IO compeletion + - xprtrdma: Fix handling of RDMA_ERROR replies + - dm writecache: correct uncommitted_block when discarding uncommitted entry + - dm writecache: add cond_resched to loop in persistent_memory_claim() + - xfs: add agf freeblocks verify in xfs_agf_verify + - Revert "tty: hvc: Fix data abort due to race in hvc_open" + - Linux 5.4.50 + * Focal update: v5.4.49 upstream stable release (LP: #1885322) + - power: supply: bq24257_charger: Replace depends on REGMAP_I2C with select + - clk: sunxi: Fix incorrect usage of round_down() + - ASoC: tegra: tegra_wm8903: Support nvidia, headset property + - i2c: piix4: Detect secondary SMBus controller on AMD AM4 chipsets + - ASoC: SOF: imx8: Fix randbuild error + - iio: pressure: bmp280: Tolerate IRQ before registering + - remoteproc: Fix IDR initialisation in rproc_alloc() + - clk: qcom: msm8916: Fix the address location of pll->config_reg + - ASoC: fsl_esai: Disable exception interrupt before scheduling tasklet + - backlight: lp855x: Ensure regulators are disabled on probe failure + - ARM: dts: renesas: Fix IOMMU device node names + - ASoC: davinci-mcasp: Fix dma_chan refcnt leak when getting dma type + - ARM: integrator: Add some Kconfig selections + - ARM: dts: stm32: Add missing ethernet PHY reset on AV96 + - scsi: core: free sgtables in case command setup fails + - scsi: qedi: Check for buffer overflow in qedi_set_path() + - arm64: dts: meson: fixup SCP sram nodes + - ALSA: isa/wavefront: prevent out of bounds write in ioctl + - PCI: Allow pci_resize_resource() for devices on root bus + - scsi: qla2xxx: Fix issue with adapter's stopping state + - Input: edt-ft5x06 - fix get_default register write access + - powerpc/kasan: Fix stack overflow by increasing THREAD_SHIFT + - rtc: mc13xxx: fix a double-unlock issue + - iio: bmp280: fix compensation of humidity + - f2fs: report delalloc reserve as non-free in statfs for project quota + - i2c: pxa: clear all master action bits in i2c_pxa_stop_message() + - remoteproc: qcom_q6v5_mss: map/unmap mpss segments before/after use + - clk: samsung: Mark top ISP and CAM clocks on Exynos542x as critical + - usblp: poison URBs upon disconnect + - serial: 8250: Fix max baud limit in generic 8250 port + - misc: fastrpc: Fix an incomplete memory release in fastrpc_rpmsg_probe() + - misc: fastrpc: fix potential fastrpc_invoke_ctx leak + - dm mpath: switch paths in dm_blk_ioctl() code path + - arm64: dts: armada-3720-turris-mox: forbid SDR104 on SDIO for FCC purposes + - arm64: dts: armada-3720-turris-mox: fix SFP binding + - arm64: dts: juno: Fix GIC child nodes + - pinctrl: ocelot: Fix GPIO interrupt decoding on Jaguar2 + - clk: renesas: cpg-mssr: Fix STBCR suspend/resume handling + - ASoC: SOF: Do nothing when DSP PM callbacks are not set + - arm64: dts: fvp: Fix GIC child nodes + - PCI: aardvark: Don't blindly enable ASPM L0s and don't write to read-only + register + - ps3disk: use the default segment boundary + - arm64: dts: fvp/juno: Fix node address fields + - vfio/pci: fix memory leaks in alloc_perm_bits() + - coresight: tmc: Fix TMC mode read in tmc_read_prepare_etb() + - RDMA/mlx5: Add init2init as a modify command + - scsi: hisi_sas: Do not reset phy timer to wait for stray phy up + - PCI: pci-bridge-emul: Fix PCIe bit conflicts + - m68k/PCI: Fix a memory leak in an error handling path + - gpio: dwapb: Call acpi_gpiochip_free_interrupts() on GPIO chip de- + registration + - usb: gadget: core: sync interrupt before unbind the udc + - powerpc/ptdump: Add _PAGE_COHERENT flag + - mfd: wm8994: Fix driver operation if loaded as modules + - scsi: cxgb3i: Fix some leaks in init_act_open() + - clk: zynqmp: fix memory leak in zynqmp_register_clocks + - scsi: lpfc: Fix lpfc_nodelist leak when processing unsolicited event + - scsi: vhost: Notify TCM about the maximum sg entries supported per command + - clk: clk-flexgen: fix clock-critical handling + - IB/mlx5: Fix DEVX support for MLX5_CMD_OP_INIT2INIT_QP command + - powerpc/perf/hv-24x7: Fix inconsistent output values incase multiple hv-24x7 + events run + - nfsd: Fix svc_xprt refcnt leak when setup callback client failed + - PCI: vmd: Filter resource type bits from shadow register + - RDMA/core: Fix several reference count leaks. + - cifs: set up next DFS target before generic_ip_connect() + - ASoC: qcom: q6asm-dai: kCFI fix + - powerpc/crashkernel: Take "mem=" option into account + - pwm: img: Call pm_runtime_put() in pm_runtime_get_sync() failed case + - sparc32: mm: Don't try to free page-table pages if ctor() fails + - yam: fix possible memory leak in yam_init_driver + - NTB: ntb_pingpong: Choose doorbells based on port number + - NTB: Fix the default port and peer numbers for legacy drivers + - mksysmap: Fix the mismatch of '.L' symbols in System.map + - apparmor: fix introspection of of task mode for unconfined tasks + - net: dsa: lantiq_gswip: fix and improve the unsupported interface error + - f2fs: handle readonly filesystem in f2fs_ioc_shutdown() + - ASoC: meson: add missing free_irq() in error path + - bpf, sockhash: Fix memory leak when unlinking sockets in sock_hash_free + - scsi: sr: Fix sr_probe() missing deallocate of device minor + - scsi: ibmvscsi: Don't send host info in adapter info MAD after LPM + - x86/purgatory: Disable various profiling and sanitizing options + - staging: greybus: fix a missing-check bug in gb_lights_light_config() + - arm64: dts: mt8173: fix unit name warnings + - scsi: qedi: Do not flush offload work if ARP not resolved + - arm64: dts: qcom: msm8916: remove unit name for thermal trip points + - ARM: dts: sun8i-h2-plus-bananapi-m2-zero: Fix led polarity + - RDMA/mlx5: Fix udata response upon SRQ creation + - gpio: dwapb: Append MODULE_ALIAS for platform driver + - scsi: qedf: Fix crash when MFW calls for protocol stats while function is + still probing + - pinctrl: rza1: Fix wrong array assignment of rza1l_swio_entries + - virtiofs: schedule blocking async replies in separate worker + - arm64: dts: qcom: fix pm8150 gpio interrupts + - firmware: qcom_scm: fix bogous abuse of dma-direct internals + - staging: gasket: Fix mapping refcnt leak when put attribute fails + - staging: gasket: Fix mapping refcnt leak when register/store fails + - ALSA: usb-audio: Improve frames size computation + - ALSA: usb-audio: Fix racy list management in output queue + - s390/qdio: put thinint indicator after early error + - tty: hvc: Fix data abort due to race in hvc_open + - slimbus: ngd: get drvdata from correct device + - clk: meson: meson8b: Fix the first parent of vid_pll_in_sel + - clk: meson: meson8b: Fix the polarity of the RESET_N lines + - clk: meson: meson8b: Fix the vclk_div{1, 2, 4, 6, 12}_en gate bits + - gpio: pca953x: fix handling of automatic address incrementing + - thermal/drivers/ti-soc-thermal: Avoid dereferencing ERR_PTR + - clk: meson: meson8b: Don't rely on u-boot to init all GP_PLL registers + - ASoC: max98373: reorder max98373_reset() in resume + - soundwire: slave: don't init debugfs on device registration error + - HID: intel-ish-hid: avoid bogus uninitialized-variable warning + - usb: dwc3: gadget: Properly handle ClearFeature(halt) + - usb: dwc3: gadget: Properly handle failed kick_transfer + - staging: wilc1000: Increase the size of wid_list array + - staging: sm750fb: add missing case while setting FB_VISUAL + - PCI: v3-semi: Fix a memory leak in v3_pci_probe() error handling paths + - i2c: pxa: fix i2c_pxa_scream_blue_murder() debug output + - serial: amba-pl011: Make sure we initialize the port.lock spinlock + - drivers: base: Fix NULL pointer exception in __platform_driver_probe() if a + driver developer is foolish + - PCI: rcar: Fix incorrect programming of OB windows + - PCI/ASPM: Allow ASPM on links to PCIe-to-PCI/PCI-X Bridges + - scsi: qla2xxx: Fix warning after FC target reset + - ALSA: firewire-lib: fix invalid assignment to union data for directional + parameter + - power: supply: lp8788: Fix an error handling path in + 'lp8788_charger_probe()' + - power: supply: smb347-charger: IRQSTAT_D is volatile + - ASoC: SOF: core: fix error return code in sof_probe_continue() + - arm64: dts: msm8996: Fix CSI IRQ types + - scsi: target: loopback: Fix READ with data and sensebytes + - scsi: mpt3sas: Fix double free warnings + - SoC: rsnd: add interrupt support for SSI BUSIF buffer + - ASoC: ux500: mop500: Fix some refcounted resources issues + - ASoC: ti: omap-mcbsp: Fix an error handling path in 'asoc_mcbsp_probe()' + - pinctrl: rockchip: fix memleak in rockchip_dt_node_to_map + - dlm: remove BUG() before panic() + - USB: ohci-sm501: fix error return code in ohci_hcd_sm501_drv_probe() + - clk: ti: composite: fix memory leak + - PCI: Fix pci_register_host_bridge() device_register() error handling + - powerpc/64: Don't initialise init_task->thread.regs + - tty: n_gsm: Fix SOF skipping + - tty: n_gsm: Fix waking up upper tty layer when room available + - ALSA: usb-audio: Add duplex sound support for USB devices using implicit + feedback + - HID: Add quirks for Trust Panora Graphic Tablet + - PCI/PM: Assume ports without DLL Link Active train links in 100 ms + - habanalabs: increase timeout during reset + - ipmi: use vzalloc instead of kmalloc for user creation + - powerpc/64s/exception: Fix machine check no-loss idle wakeup + - powerpc/pseries/ras: Fix FWNMI_VALID off by one + - drivers: phy: sr-usb: do not use internal fsm for USB2 phy init + - powerpc/ps3: Fix kexec shutdown hang + - vfio-pci: Mask cap zero + - usb/ohci-platform: Fix a warning when hibernating + - drm/msm/mdp5: Fix mdp5_init error path for failed mdp5_kms allocation + - ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT8-A tablet + - USB: host: ehci-mxc: Add error handling in ehci_mxc_drv_probe() + - tty: n_gsm: Fix bogus i++ in gsm_data_kick + - fpga: dfl: afu: Corrected error handling levels + - clk: samsung: exynos5433: Add IGNORE_UNUSED flag to sclk_i2s1 + - RDMA/hns: Bugfix for querying qkey + - RDMA/hns: Fix cmdq parameter of querying pf timer resource + - scsi: target: tcmu: Userspace must not complete queued commands + - firmware: imx: scu: Fix possible memory leak in imx_scu_probe() + - fuse: fix copy_file_range cache issues + - fuse: copy_file_range should truncate cache + - arm64: tegra: Fix ethernet phy-mode for Jetson Xavier + - arm64: tegra: Fix flag for 64-bit resources in 'ranges' property + - powerpc/64s/pgtable: fix an undefined behaviour + - dm zoned: return NULL if dmz_get_zone_for_reclaim() fails to find a zone + - PCI/PTM: Inherit Switch Downstream Port PTM settings from Upstream Port + - PCI: dwc: Fix inner MSI IRQ domain registration + - PCI: amlogic: meson: Don't use FAST_LINK_MODE to set up link + - IB/cma: Fix ports memory leak in cma_configfs + - watchdog: da9062: No need to ping manually before setting timeout + - usb: dwc2: gadget: move gadget resume after the core is in L0 state + - USB: gadget: udc: s3c2410_udc: Remove pointless NULL check in + s3c2410_udc_nuke + - usb: gadget: lpc32xx_udc: don't dereference ep pointer before null check + - usb: gadget: fix potential double-free in m66592_probe. + - usb: gadget: Fix issue with config_ep_by_speed function + - scripts: headers_install: Exit with error on config leak + - RDMA/iw_cxgb4: cleanup device debugfs entries on ULD remove + - x86/apic: Make TSC deadline timer detection message visible + - mfd: stmfx: Reset chip on resume as supply was disabled + - mfd: stmfx: Fix stmfx_irq_init error path + - mfd: stmfx: Disable IRQ in suspend to avoid spurious interrupt + - powerpc/32s: Don't warn when mapping RO data ROX. + - ASoC: fix incomplete error-handling in img_i2s_in_probe. + - scsi: target: tcmu: Fix a use after free in tcmu_check_expired_queue_cmd() + - clk: bcm2835: Fix return type of bcm2835_register_gate + - scsi: ufs-qcom: Fix scheduling while atomic issue + - KVM: PPC: Book3S HV: Ignore kmemleak false positives + - KVM: PPC: Book3S: Fix some RCU-list locks + - clk: sprd: return correct type of value for _sprd_pll_recalc_rate + - clk: ast2600: Fix AHB clock divider for A1 + - misc: xilinx-sdfec: improve get_user_pages_fast() error handling + - /dev/mem: Revoke mappings when a driver claims the region + - net: sunrpc: Fix off-by-one issues in 'rpc_ntop6' + - NFSv4.1 fix rpc_call_done assignment for BIND_CONN_TO_SESSION + - of: Fix a refcounting bug in __of_attach_node_sysfs() + - input: i8042 - Remove special PowerPC handling + - powerpc/4xx: Don't unmap NULL mbase + - extcon: adc-jack: Fix an error handling path in 'adc_jack_probe()' + - ASoC: fsl_asrc_dma: Fix dma_chan leak when config DMA channel failed + - vfio/mdev: Fix reference count leak in add_mdev_supported_type + - rtc: rv3028: Add missed check for devm_regmap_init_i2c() + - mailbox: zynqmp-ipi: Fix NULL vs IS_ERR() check in zynqmp_ipi_mbox_probe() + - rxrpc: Adjust /proc/net/rxrpc/calls to display call->debug_id not user_ID + - openrisc: Fix issue with argument clobbering for clone/fork + - drm/nouveau/disp/gm200-: fix NV_PDISP_SOR_HDMI2_CTRL(n) selection + - ceph: don't return -ESTALE if there's still an open file + - nfsd4: make drc_slab global, not per-net + - gfs2: Allow lock_nolock mount to specify jid=X + - scsi: iscsi: Fix reference count leak in iscsi_boot_create_kobj + - scsi: ufs: Don't update urgent bkops level when toggling auto bkops + - pinctrl: imxl: Fix an error handling path in 'imx1_pinctrl_core_probe()' + - pinctrl: freescale: imx: Fix an error handling path in 'imx_pinctrl_probe()' + - nfsd: safer handling of corrupted c_type + - drm/amd/display: Revalidate bandwidth before commiting DC updates + - crypto: omap-sham - add proper load balancing support for multicore + - geneve: change from tx_error to tx_dropped on missing metadata + - lib/zlib: remove outdated and incorrect pre-increment optimization + - include/linux/bitops.h: avoid clang shift-count-overflow warnings + - selftests/vm/pkeys: fix alloc_random_pkey() to make it really random + - blktrace: use errno instead of bi_status + - blktrace: fix endianness in get_pdu_int() + - blktrace: fix endianness for blk_log_remap() + - gfs2: fix use-after-free on transaction ail lists + - net: marvell: Fix OF_MDIO config check + - ntb_perf: pass correct struct device to dma_alloc_coherent + - ntb_tool: pass correct struct device to dma_alloc_coherent + - NTB: ntb_tool: reading the link file should not end in a NULL byte + - NTB: Revert the change to use the NTB device dev for DMA allocations + - NTB: perf: Don't require one more memory window than number of peers + - NTB: perf: Fix support for hardware that doesn't have port numbers + - NTB: perf: Fix race condition when run with ntb_test + - NTB: ntb_test: Fix bug when counting remote files + - i2c: icy: Fix build with CONFIG_AMIGA_PCMCIA=n + - drivers/perf: hisi: Fix wrong value for all counters enable + - selftests/net: in timestamping, strncpy needs to preserve null byte + - f2fs: don't return vmalloc() memory from f2fs_kmalloc() + - afs: Fix memory leak in afs_put_sysnames() + - ASoC: core: only convert non DPCM link to DPCM link + - ASoC: SOF: nocodec: conditionally set dpcm_capture/dpcm_playback flags + - ASoC: Intel: bytcr_rt5640: Add quirk for Toshiba Encore WT10-A tablet + - ASoC: rt5645: Add platform-data for Asus T101HA + - bpf/sockmap: Fix kernel panic at __tcp_bpf_recvmsg + - bpf, sockhash: Synchronize delete from bucket list on map free + - tracing/probe: Fix bpf_task_fd_query() for kprobes and uprobes + - drm/sun4i: hdmi ddc clk: Fix size of m divider + - libbpf: Handle GCC noreturn-turned-volatile quirk + - scsi: acornscsi: Fix an error handling path in acornscsi_probe() + - x86/idt: Keep spurious entries unset in system_vectors + - net/filter: Permit reading NET in load_bytes_relative when MAC not set + - nvme-pci: use simple suspend when a HMB is enabled + - nfs: set invalid blocks after NFSv4 writes + - xdp: Fix xsk_generic_xmit errno + - iavf: fix speed reporting over virtchnl + - bpf: Fix memlock accounting for sock_hash + - usb/xhci-plat: Set PM runtime as active on resume + - usb: host: ehci-platform: add a quirk to avoid stuck + - usb/ehci-platform: Set PM runtime as active on resume + - perf report: Fix NULL pointer dereference in + hists__fprintf_nr_sample_events() + - perf stat: Fix NULL pointer dereference + - ext4: stop overwrite the errcode in ext4_setup_super + - bcache: fix potential deadlock problem in btree_gc_coalesce + - powerpc: Fix kernel crash in show_instructions() w/DEBUG_VIRTUAL + - afs: Fix non-setting of mtime when writing into mmap + - afs: afs_write_end() should change i_size under the right lock + - afs: Fix EOF corruption + - afs: Always include dir in bulk status fetch from afs_do_lookup() + - afs: Set error flag rather than return error from file status decode + - afs: Fix the mapping of the UAEOVERFLOW abort code + - bnxt_en: Return from timer if interface is not in open state. + - scsi: ufs-bsg: Fix runtime PM imbalance on error + - block: Fix use-after-free in blkdev_get() + - mvpp2: remove module bugfix + - arm64: hw_breakpoint: Don't invoke overflow handler on uaccess watchpoints + - drm: encoder_slave: fix refcouting error for modules + - ext4: fix partial cluster initialization when splitting extent + - ext4: avoid utf8_strncasecmp() with unstable name + - drm/dp_mst: Reformat drm_dp_check_act_status() a bit + - drm/qxl: Use correct notify port address when creating cursor ring + - drm/amdgpu: Replace invalid device ID with a valid device ID + - selinux: fix double free + - jbd2: clean __jbd2_journal_abort_hard() and __journal_abort_soft() + - ext4: avoid race conditions when remounting with options that change dax + - drm/dp_mst: Increase ACT retry timeout to 3s + - drm/amd/display: Use swap() where appropriate + - x86/boot/compressed: Relax sed symbol type regex for LLVM ld.lld + - block: nr_sects_write(): Disable preemption on seqcount write + - net/mlx5: DR, Fix freeing in dr_create_rc_qp() + - f2fs: split f2fs_d_compare() from f2fs_match_name() + - f2fs: avoid utf8_strncasecmp() with unstable name + - s390: fix syscall_get_error for compat processes + - drm/i915: Fix AUX power domain toggling across TypeC mode resets + - drm/msm: Check for powered down HW in the devfreq callbacks + - drm/i915/gem: Avoid iterating an empty list + - drm/i915: Whitelist context-local timestamp in the gen9 cmdparser + - drm/connector: notify userspace on hotplug after register complete + - drm/amd/display: Use kvfree() to free coeff in build_regamma() + - drm/i915/icl+: Fix hotplug interrupt disabling after storm detection + - Revert "drm/amd/display: disable dcn20 abm feature for bring up" + - crypto: algif_skcipher - Cap recv SG list at ctx->used + - crypto: algboss - don't wait during notifier callback + - tracing/probe: Fix memleak in fetch_op_data operations + - kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex + - kretprobe: Prevent triggering kretprobe from within kprobe_flush_task + - e1000e: Do not wake up the system via WOL if device wakeup is disabled + - net: octeon: mgmt: Repair filling of RX ring + - pwm: jz4740: Enhance precision in calculation of duty cycle + - sched/rt, net: Use CONFIG_PREEMPTION.patch + - net: core: device_rename: Use rwsem instead of a seqcount + - Linux 5.4.49 + * Computer is frozen after suspend (LP: #1867983) // Focal update: v5.4.49 + upstream stable release (LP: #1885322) + - libata: Use per port sync for detach + * Focal update: v5.4.48 upstream stable release (LP: #1885023) + - ACPI: GED: use correct trigger type field in _Exx / _Lxx handling + - drm/amdgpu: fix and cleanup amdgpu_gem_object_close v4 + - ath10k: Fix the race condition in firmware dump work queue + - drm: bridge: adv7511: Extend list of audio sample rates + - media: staging: imgu: do not hold spinlock during freeing mmu page table + - media: imx: imx7-mipi-csis: Cleanup and fix subdev pad format handling + - crypto: ccp -- don't "select" CONFIG_DMADEVICES + - media: vicodec: Fix error codes in probe function + - media: si2157: Better check for running tuner in init + - objtool: Ignore empty alternatives + - spi: spi-mem: Fix Dual/Quad modes on Octal-capable devices + - drm/amdgpu: Init data to avoid oops while reading pp_num_states. + - arm64/kernel: Fix range on invalidating dcache for boot page tables + - libbpf: Fix memory leak and possible double-free in hashmap__clear + - spi: pxa2xx: Apply CS clk quirk to BXT + - x86,smap: Fix smap_{save,restore}() alternatives + - sched/fair: Refill bandwidth before scaling + - net: atlantic: make hw_get_regs optional + - net: ena: fix error returning in ena_com_get_hash_function() + - efi/libstub/x86: Work around LLVM ELF quirk build regression + - ath10k: remove the max_sched_scan_reqs value + - arm64: cacheflush: Fix KGDB trap detection + - media: staging: ipu3: Fix stale list entries on parameter queue failure + - rtw88: fix an issue about leak system resources + - spi: dw: Zero DMA Tx and Rx configurations on stack + - ACPICA: Dispatcher: add status checks + - block: alloc map and request for new hardware queue + - arm64: insn: Fix two bugs in encoding 32-bit logical immediates + - block: reset mapping if failed to update hardware queue count + - drm: rcar-du: Set primary plane zpos immutably at initializing + - lockdown: Allow unprivileged users to see lockdown status + - ixgbe: Fix XDP redirect on archs with PAGE_SIZE above 4K + - platform/x86: dell-laptop: don't register micmute LED if there is no token + - MIPS: Loongson: Build ATI Radeon GPU driver as module + - Bluetooth: Add SCO fallback for invalid LMP parameters error + - kgdb: Disable WARN_CONSOLE_UNLOCKED for all kgdb + - kgdb: Prevent infinite recursive entries to the debugger + - pmu/smmuv3: Clear IRQ affinity hint on device removal + - ACPI/IORT: Fix PMCG node single ID mapping handling + - mips: Fix cpu_has_mips64r1/2 activation for MIPS32 CPUs + - spi: dw: Enable interrupts in accordance with DMA xfer mode + - clocksource: dw_apb_timer: Make CPU-affiliation being optional + - clocksource: dw_apb_timer_of: Fix missing clockevent timers + - media: dvbdev: Fix tuner->demod media controller link + - btrfs: account for trans_block_rsv in may_commit_transaction + - btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums + - ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE + - batman-adv: Revert "disable ethtool link speed detection when auto + negotiation off" + - ice: Fix memory leak + - ice: Fix for memory leaks and modify ICE_FREE_CQ_BUFS + - mmc: meson-mx-sdio: trigger a soft reset after a timeout or CRC error + - Bluetooth: btmtkuart: Improve exception handling in btmtuart_probe() + - spi: dw: Fix Rx-only DMA transfers + - x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit + - net: vmxnet3: fix possible buffer overflow caused by bad DMA value in + vmxnet3_get_rss() + - x86: fix vmap arguments in map_irq_stack + - staging: android: ion: use vmap instead of vm_map_ram + - ath10k: fix kernel null pointer dereference + - media: staging/intel-ipu3: Implement lock for stream on/off operations + - spi: Respect DataBitLength field of SpiSerialBusV2() ACPI resource + - brcmfmac: fix wrong location to get firmware feature + - regulator: qcom-rpmh: Fix typos in pm8150 and pm8150l + - tools api fs: Make xxx__mountpoint() more scalable + - e1000: Distribute switch variables for initialization + - dt-bindings: display: mediatek: control dpi pins mode to avoid leakage + - drm/mediatek: set dpi pin mode to gpio low to avoid leakage current + - audit: fix a net reference leak in audit_send_reply() + - media: dvb: return -EREMOTEIO on i2c transfer failure. + - media: platform: fcp: Set appropriate DMA parameters + - MIPS: Make sparse_init() using top-down allocation + - ath10k: add flush tx packets for SDIO chip + - Bluetooth: btbcm: Add 2 missing models to subver tables + - audit: fix a net reference leak in audit_list_rules_send() + - Drivers: hv: vmbus: Always handle the VMBus messages on CPU0 + - dpaa2-eth: fix return codes used in ndo_setup_tc + - netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported + - selftests/bpf: Fix memory leak in extract_build_id() + - net: bcmgenet: set Rx mode before starting netif + - net: bcmgenet: Fix WoL with password after deep sleep + - lib/mpi: Fix 64-bit MIPS build with Clang + - exit: Move preemption fixup up, move blocking operations down + - sched/core: Fix illegal RCU from offline CPUs + - drivers/perf: hisi: Fix typo in events attribute array + - iocost_monitor: drop string wrap around numbers when outputting json + - net: lpc-enet: fix error return code in lpc_mii_init() + - selinux: fix error return code in policydb_read() + - drivers: net: davinci_mdio: fix potential NULL dereference in + davinci_mdio_probe() + - media: cec: silence shift wrapping warning in __cec_s_log_addrs() + - net: allwinner: Fix use correct return type for ndo_start_xmit() + - powerpc/spufs: fix copy_to_user while atomic + - libertas_tf: avoid a null dereference in pointer priv + - xfs: clean up the error handling in xfs_swap_extents + - Crypto/chcr: fix for ccm(aes) failed test + - MIPS: Truncate link address into 32bit for 32bit kernel + - mips: cm: Fix an invalid error code of INTVN_*_ERR + - kgdb: Fix spurious true from in_dbg_master() + - xfs: reset buffer write failure state on successful completion + - xfs: fix duplicate verification from xfs_qm_dqflush() + - platform/x86: intel-vbtn: Use acpi_evaluate_integer() + - platform/x86: intel-vbtn: Split keymap into buttons and switches parts + - platform/x86: intel-vbtn: Do not advertise switches to userspace if they are + not there + - platform/x86: intel-vbtn: Also handle tablet-mode switch on "Detachable" and + "Portable" chassis-types + - iwlwifi: avoid debug max amsdu config overwriting itself + - nvme: refine the Qemu Identify CNS quirk + - nvme-pci: align io queue count with allocted nvme_queue in nvme_probe + - nvme-tcp: use bh_lock in data_ready + - ath10k: Remove msdu from idr when management pkt send fails + - wcn36xx: Fix error handling path in 'wcn36xx_probe()' + - net: qed*: Reduce RX and TX default ring count when running inside kdump + kernel + - drm/mcde: dsi: Fix return value check in mcde_dsi_bind() + - mt76: avoid rx reorder buffer overflow + - md: don't flush workqueue unconditionally in md_open + - raid5: remove gfp flags from scribble_alloc() + - iocost: don't let vrate run wild while there's no saturation signal + - veth: Adjust hard_start offset on redirect XDP frames + - net/mlx5e: IPoIB, Drop multicast packets that this interface sent + - rtlwifi: Fix a double free in _rtl_usb_tx_urb_setup() + - mwifiex: Fix memory corruption in dump_station + - kgdboc: Use a platform device to handle tty drivers showing up late + - x86/boot: Correct relocation destination on old linkers + - sched: Defend cfs and rt bandwidth quota against overflow + - mips: MAAR: Use more precise address mask + - mips: Add udelay lpj numbers adjustment + - crypto: stm32/crc32 - fix ext4 chksum BUG_ON() + - crypto: stm32/crc32 - fix run-time self test issue. + - crypto: stm32/crc32 - fix multi-instance + - drm/amd/powerpay: Disable gfxoff when setting manual mode on picasso and + raven + - drm/amdgpu: Sync with VM root BO when switching VM to CPU update mode + - selftests/bpf: CONFIG_IPV6_SEG6_BPF required for test_seg6_loop.o + - x86/mm: Stop printing BRK addresses + - MIPS: tools: Fix resource leak in elf-entry.c + - m68k: mac: Don't call via_flush_cache() on Mac IIfx + - btrfs: improve global reserve stealing logic + - btrfs: qgroup: mark qgroup inconsistent if we're inherting snapshot to a new + qgroup + - macvlan: Skip loopback packets in RX handler + - PCI: Don't disable decoding when mmio_always_on is set + - MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe() + - bcache: fix refcount underflow in bcache_device_free() + - mmc: sdhci-msm: Set SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 quirk + - staging: greybus: sdio: Respect the cmd->busy_timeout from the mmc core + - mmc: via-sdmmc: Respect the cmd->busy_timeout from the mmc core + - ice: fix potential double free in probe unrolling + - ixgbe: fix signed-integer-overflow warning + - iwlwifi: mvm: fix aux station leak + - mmc: sdhci-esdhc-imx: fix the mask for tuning start point + - spi: dw: Return any value retrieved from the dma_transfer callback + - cpuidle: Fix three reference count leaks + - platform/x86: hp-wmi: Convert simple_strtoul() to kstrtou32() + - platform/x86: intel-hid: Add a quirk to support HP Spectre X2 (2015) + - platform/x86: intel-vbtn: Only blacklist SW_TABLET_MODE on the 9 / "Laptop" + chasis-type + - platform/x86: asus_wmi: Reserve more space for struct bias_args + - libbpf: Fix perf_buffer__free() API for sparse allocs + - bpf: Fix map permissions check + - bpf: Refactor sockmap redirect code so its easy to reuse + - bpf: Fix running sk_skb program types with ktls + - selftests/bpf, flow_dissector: Close TAP device FD after the test + - kasan: stop tests being eliminated as dead code with FORTIFY_SOURCE + - string.h: fix incompatibility between FORTIFY_SOURCE and KASAN + - btrfs: free alien device after device add + - btrfs: include non-missing as a qualifier for the latest_bdev + - btrfs: send: emit file capabilities after chown + - btrfs: force chunk allocation if our global rsv is larger than metadata + - btrfs: fix error handling when submitting direct I/O bio + - btrfs: fix wrong file range cleanup after an error filling dealloc range + - btrfs: fix space_info bytes_may_use underflow after nocow buffered write + - btrfs: fix space_info bytes_may_use underflow during space cache writeout + - powerpc/mm: Fix conditions to perform MMU specific management by blocks on + PPC32. + - mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked() + - mm: initialize deferred pages with interrupts enabled + - mm/pagealloc.c: call touch_nmi_watchdog() on max order boundaries in + deferred init + - mm: call cond_resched() from deferred_init_memmap() + - ima: Fix ima digest hash table key calculation + - ima: Switch to ima_hash_algo for boot aggregate + - ima: Evaluate error in init_ima() + - ima: Directly assign the ima_default_policy pointer to ima_rules + - ima: Call ima_calc_boot_aggregate() in ima_eventdigest_init() + - ima: Remove __init annotation from ima_pcrread() + - evm: Fix possible memory leak in evm_calc_hmac_or_hash() + - ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max + - ext4: fix error pointer dereference + - ext4: fix race between ext4_sync_parent() and rename() + - PCI: Add ACS quirk for Intel Root Complex Integrated Endpoints + - PCI: Add Loongson vendor ID + - x86/amd_nb: Add AMD family 17h model 60h PCI IDs + - ima: Remove redundant policy rule set in add_rules() + - ima: Set again build_ima_appraise variable + - PCI: Program MPS for RCiEP devices + - e1000e: Relax condition to trigger reset for ME workaround + - carl9170: remove P2P_GO support + - media: go7007: fix a miss of snd_card_free + - media: cedrus: Program output format during each run + - serial: 8250: Avoid error message on reprobe + - Bluetooth: hci_bcm: fix freeing not-requested IRQ + - b43legacy: Fix case where channel status is corrupted + - b43: Fix connection problem with WPA3 + - b43_legacy: Fix connection problem with WPA3 + - media: ov5640: fix use of destroyed mutex + - clk: mediatek: assign the initial value to clk_init_data of mtk_mux + - hwmon: (k10temp) Add AMD family 17h model 60h PCI match + - EDAC/amd64: Add AMD family 17h model 60h PCI IDs + - power: vexpress: add suppress_bind_attrs to true + - power: supply: core: fix HWMON temperature labels + - power: supply: core: fix memory leak in HWMON error path + - pinctrl: samsung: Correct setting of eint wakeup mask on s5pv210 + - pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs + - gnss: sirf: fix error return code in sirf_probe() + - sparc32: fix register window handling in genregs32_[gs]et() + - sparc64: fix misuses of access_process_vm() in genregs32_[sg]et() + - dm crypt: avoid truncating the logical block size + - alpha: fix memory barriers so that they conform to the specification + - powerpc/fadump: use static allocation for reserved memory ranges + - powerpc/fadump: consider reserved ranges while reserving memory + - powerpc/fadump: Account for memory_limit while reserving memory + - kernel/cpu_pm: Fix uninitted local in cpu_pm + - ARM: tegra: Correct PL310 Auxiliary Control Register initialization + - soc/tegra: pmc: Select GENERIC_PINCONF + - ARM: dts: exynos: Fix GPIO polarity for thr GalaxyS3 CM36651 sensor's bus + - ARM: dts: at91: sama5d2_ptc_ek: fix vbus pin + - ARM: dts: s5pv210: Set keep-power-in-suspend for SDHCI1 on Aries + - drivers/macintosh: Fix memleak in windfarm_pm112 driver + - powerpc/32s: Fix another build failure with CONFIG_PPC_KUAP_DEBUG + - powerpc/kasan: Fix issues by lowering KASAN_SHADOW_END + - powerpc/kasan: Fix shadow pages allocation failure + - powerpc/32: Disable KASAN with pages bigger than 16k + - powerpc/64s: Don't let DT CPU features set FSCR_DSCR + - powerpc/64s: Save FSCR to init_task.thread.fscr after feature init + - kbuild: force to build vmlinux if CONFIG_MODVERSION=y + - sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate + registrations. + - sunrpc: clean up properly in gss_mech_unregister() + - mtd: rawnand: Fix nand_gpio_waitrdy() + - mtd: rawnand: onfi: Fix redundancy detection check + - mtd: rawnand: brcmnand: fix hamming oob layout + - mtd: rawnand: diskonchip: Fix the probe error path + - mtd: rawnand: sharpsl: Fix the probe error path + - mtd: rawnand: ingenic: Fix the probe error path + - mtd: rawnand: xway: Fix the probe error path + - mtd: rawnand: orion: Fix the probe error path + - mtd: rawnand: socrates: Fix the probe error path + - mtd: rawnand: oxnas: Fix the probe error path + - mtd: rawnand: sunxi: Fix the probe error path + - mtd: rawnand: plat_nand: Fix the probe error path + - mtd: rawnand: pasemi: Fix the probe error path + - mtd: rawnand: mtk: Fix the probe error path + - mtd: rawnand: tmio: Fix the probe error path + - w1: omap-hdq: cleanup to add missing newline for some dev_dbg + - f2fs: fix checkpoint=disable:%u%% + - perf probe: Do not show the skipped events + - perf probe: Fix to check blacklist address correctly + - perf probe: Check address correctness by map instead of _etext + - perf symbols: Fix debuginfo search for Ubuntu + - perf symbols: Fix kernel maps for kcore and eBPF + - Linux 5.4.48 + * The thread level parallelism would be a bottleneck when searching for the + shared pmd by using hugetlbfs (LP: #1882039) + - hugetlbfs: take read_lock on i_mmap for PMD sharing + * Support Audio Mute LED for two new HP laptops (LP: #1884251) + - ALSA: hda/realtek: Add mute LED and micmute LED support for HP systems + * Focal update: v5.4.47 upstream stable release (LP: #1884089) + - ipv6: fix IPV6_ADDRFORM operation logic + - mlxsw: core: Use different get_trend() callbacks for different thermal zones + - net_failover: fixed rollback in net_failover_open() + - tun: correct header offsets in napi frags mode + - bridge: Avoid infinite loop when suppressing NS messages with invalid + options + - vxlan: Avoid infinite loop when suppressing NS messages with invalid options + - bpf: Support llvm-objcopy for vmlinux BTF + - elfnote: mark all .note sections SHF_ALLOC + - Input: mms114 - fix handling of mms345l + - ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook + - sched/fair: Don't NUMA balance for kthreads + - Input: synaptics - add a second working PNP_ID for Lenovo T470s + - csky: Fixup abiv2 syscall_trace break a4 & a5 + - gfs2: Even more gfs2_find_jhead fixes + - drivers/net/ibmvnic: Update VNIC protocol version reporting + - powerpc/xive: Clear the page tables for the ESB IO mapping + - spi: dw: Fix native CS being unset + - ath9k_htc: Silence undersized packet warnings + - smack: avoid unused 'sip' variable warning + - RDMA/uverbs: Make the event_queue fds return POLLERR when disassociated + - padata: add separate cpuhp node for CPUHP_PADATA_DEAD + - s390/pci: Log new handle in clp_disable_fh() + - x86/cpu/amd: Make erratum #1054 a legacy erratum + - KVM: x86: only do L1TF workaround on affected processors + - PCI/PM: Adjust pcie_wait_for_link_delay() for caller delay + - perf probe: Accept the instance number of kretprobe event + - mm: add kvfree_sensitive() for freeing sensitive data objects + - selftests: fix flower parent qdisc + - fanotify: fix ignore mask logic for events on child and on dir + - aio: fix async fsync creds + - ipv4: fix a RCU-list lock in fib_triestat_seq_show + - iwlwifi: mvm: fix NVM check for 3168 devices + - sctp: fix possibly using a bad saddr with a given dst + - sctp: fix refcount bug in sctp_wfree + - x86_64: Fix jiffies ODR violation + - x86/PCI: Mark Intel C620 MROMs as having non-compliant BARs + - x86/speculation: Prevent rogue cross-process SSBD shutdown + - x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced + IBRS. + - x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches. + - x86/reboot/quirks: Add MacBook6,1 reboot quirk + - perf/x86/intel: Add more available bits for OFFCORE_RESPONSE of Intel + Tremont + - KVM: x86/mmu: Set mmio_value to '0' if reserved #PF can't be generated + - KVM: x86: respect singlestep when emulating instruction + - KVM: x86: Fix APIC page invalidation race + - powerpc/ptdump: Properly handle non standard page size + - ASoC: max9867: fix volume controls + - io_uring: use kvfree() in io_sqe_buffer_register() + - efi/efivars: Add missing kobject_put() in sysfs entry creation error path + - smb3: fix incorrect number of credits when ioctl MaxOutputResponse > 64K + - smb3: add indatalen that can be a non-zero value to calculation of credit + charge in smb2 ioctl + - watchdog: imx_sc_wdt: Fix reboot on crash + - ALSA: es1688: Add the missed snd_card_free() + - ALSA: fireface: fix configuration error for nominal sampling transfer + frequency + - ALSA: hda/realtek - add a pintbl quirk for several Lenovo machines + - ALSA: pcm: disallow linking stream to itself + - ALSA: pcm: fix snd_pcm_link() lockdep splat + - ALSA: usb-audio: Fix inconsistent card PM state after resume + - ALSA: usb-audio: Add vendor, product and profile name for HP Thunderbolt + Dock + - ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile() + - ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe() + - ACPI: GED: add support for _Exx / _Lxx handler methods + - ACPI: PM: Avoid using power resources if there are none for D0 + - arm64: acpi: fix UBSAN warning + - lib/lzo: fix ambiguous encoding bug in lzo-rle + - nilfs2: fix null pointer dereference at nilfs_segctor_do_construct() + - spi: dw: Fix controller unregister order + - spi: Fix controller unregister order + - spi: pxa2xx: Fix controller unregister order + - spi: pxa2xx: Fix runtime PM ref imbalance on probe error + - spi: bcm2835: Fix controller unregister order + - spi: bcm2835aux: Fix controller unregister order + - spi: bcm-qspi: Handle clock probe deferral + - spi: bcm-qspi: when tx/rx buffer is NULL set to 0 + - PM: runtime: clk: Fix clk_pm_runtime_get() error path + - gup: document and work around "COW can break either way" issue + - crypto: cavium/nitrox - Fix 'nitrox_get_first_device()' when ndevlist is + fully iterated + - crypto: algapi - Avoid spurious modprobe on LOADED + - crypto: drbg - fix error return code in drbg_alloc_state() + - x86/{mce,mm}: Unmap the entire page if the whole page is affected and + poisoned + - firmware: imx: warn on unexpected RX + - firmware: imx-scu: Support one TX and one RX + - firmware: imx: scu: Fix corruption of header + - crypto: virtio: Fix use-after-free in virtio_crypto_skcipher_finalize_req() + - crypto: virtio: Fix src/dst scatterlist calculation in + __virtio_crypto_skcipher_do_req() + - crypto: virtio: Fix dest length calculation in + __virtio_crypto_skcipher_do_req() + - dccp: Fix possible memleak in dccp_init and dccp_fini + - selftests/net: in rxtimestamp getopt_long needs terminating null entry + - net/mlx5: drain health workqueue in case of driver load error + - net/mlx5: Fix fatal error handling during device load + - net/mlx5e: Fix repeated XSK usage on one channel + - ovl: initialize error in ovl_copy_xattr + - proc: Use new_inode not new_inode_pseudo + - remoteproc: Fall back to using parent memory pool if no dedicated available + - remoteproc: Fix and restore the parenting hierarchy for vdev + - cpufreq: Fix up cpufreq_boost_set_sw() + - EDAC/skx: Use the mcmtr register to retrieve close_pg/bank_xor_enable + - video: vt8500lcdfb: fix fallthrough warning + - video: fbdev: w100fb: Fix a potential double free. + - KVM: nVMX: Skip IBPB when switching between vmcs01 and vmcs02 + - KVM: nSVM: fix condition for filtering async PF + - KVM: nSVM: leave ASID aside in copy_vmcb_control_area + - KVM: nVMX: Consult only the "basic" exit reason when routing nested exit + - KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data) + - KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits + - KVM: arm64: Stop writing aarch32's CSSELR into ACTLR + - KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts + - scsi: megaraid_sas: TM command refire leads to controller firmware crash + - scsi: lpfc: Fix negation of else clause in lpfc_prep_node_fc4type + - selftests/ftrace: Return unsupported if no error_log file + - ath9k: Fix use-after-free Read in htc_connect_service + - ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx + - ath9k: Fix use-after-free Write in ath9k_htc_rx_msg + - ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb + - ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb + - Smack: slab-out-of-bounds in vsscanf + - drm/vkms: Hold gem object while still in-use + - mm/slub: fix a memory leak in sysfs_slab_add() + - fat: don't allow to mount if the FAT length == 0 + - perf: Add cond_resched() to task_function_call() + - agp/intel: Reinforce the barrier after GTT updates + - mmc: sdhci-msm: Clear tuning done flag while hs400 tuning + - mmc: mmci_sdmmc: fix DMA API warning overlapping mappings + - mmc: tmio: Further fixup runtime PM management at remove + - mmc: uniphier-sd: call devm_request_irq() after tmio_mmc_host_probe() + - ARM: dts: at91: sama5d2_ptc_ek: fix sdmmc0 node description + - mmc: sdio: Fix potential NULL pointer error in mmc_sdio_init_card() + - mmc: sdio: Fix several potential memory leaks in mmc_sdio_init_card() + - block/floppy: fix contended case in floppy_queue_rq() + - xen/pvcalls-back: test for errors when calling backend_connect() + - KVM: arm64: Synchronize sysreg state on injecting an AArch32 exception + - KVM: arm64: Save the host's PtrAuth keys in non-preemptible context + - Linux 5.4.47 + * apparmor reference leak causes refcount_t overflow with af_alg_accept() + (LP: #1883962) + - apparmor: check/put label on apparmor_sk_clone_security() + * Focal update: v5.4.46 upstream stable release (LP: #1883184) + - devinet: fix memleak in inetdev_init() + - l2tp: add sk_family checks to l2tp_validate_socket + - l2tp: do not use inet_hash()/inet_unhash() + - net/mlx5: Fix crash upon suspend/resume + - net: stmmac: enable timestamp snapshot for required PTP packets in dwmac + v5.10a + - net: usb: qmi_wwan: add Telit LE910C1-EUX composition + - NFC: st21nfca: add missed kfree_skb() in an error path + - nfp: flower: fix used time of merge flow statistics + - vsock: fix timeout in vsock_accept() + - net: check untrusted gso_size at kernel entry + - net: be more gentle about silly gso requests coming from user + - USB: serial: qcserial: add DW5816e QDL support + - USB: serial: usb_wwan: do not resubmit rx urb on fatal errors + - USB: serial: option: add Telit LE910C1-EUX compositions + - USB: serial: ch341: add basis for quirk detection + - iio:chemical:sps30: Fix timestamp alignment + - iio: vcnl4000: Fix i2c swapped word reading. + - iio:chemical:pms7003: Fix timestamp alignment and prevent data leak. + - iio: adc: stm32-adc: fix a wrong error message when probing interrupts + - usb: musb: start session in resume for host port + - usb: musb: Fix runtime PM imbalance on error + - vt: keyboard: avoid signed integer overflow in k_ascii + - tty: hvc_console, fix crashes on parallel open/close + - staging: rtl8712: Fix IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK + - CDC-ACM: heed quirk also in error handling + - nvmem: qfprom: remove incorrect write support + - uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly + aligned + - Revert "net/mlx5: Annotate mutex destroy for root ns" + - Linux 5.4.46 + * Focal update: v5.4.45 upstream stable release (LP: #1882802) + - mm: Fix mremap not considering huge pmd devmap + - HID: sony: Fix for broken buttons on DS3 USB dongles + - HID: multitouch: enable multi-input as a quirk for some devices + - HID: i2c-hid: add Schneider SCL142ALM to descriptor override + - p54usb: add AirVasT USB stick device-id + - mt76: mt76x02u: Add support for newer versions of the XBox One wifi adapter + - mmc: fix compilation of user API + - media: Revert "staging: imgu: Address a compiler warning on alignment" + - media: staging: ipu3-imgu: Move alignment attribute to field + - scsi: ufs: Release clock if DMA map fails + - net: dsa: mt7530: set CPU port to fallback mode + - airo: Fix read overflows sending packets + - RDMA/qedr: Fix qpids xarray api used + - RDMA/qedr: Fix synchronization methods and memory leaks in qedr + - ARC: Fix ICCM & DCCM runtime size checks + - ARC: [plat-eznps]: Restrict to CONFIG_ISA_ARCOMPACT + - evm: Fix RCU list related warnings + - scsi: pm: Balance pm_only counter of request queue during system resume + - i2c: altera: Fix race between xfer_msg and isr thread + - io_uring: initialize ctx->sqo_wait earlier + - x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables + - net: bmac: Fix read of MAC address from ROM + - drm/edid: Add Oculus Rift S to non-desktop list + - s390/mm: fix set_huge_pte_at() for empty ptes + - null_blk: return error for invalid zone size + - net/ethernet/freescale: rework quiesce/activate for ucc_geth + - net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x + - selftests: mlxsw: qos_mc_aware: Specify arping timeout as an integer + - net: smsc911x: Fix runtime PM imbalance on error + - Linux 5.4.45 + + -- Khalid Elmously Sat, 22 Aug 2020 01:06:16 -0400 + +linux-oracle (5.4.0-1021.21) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1021.21 -proposed tracker (LP: #1887065) + + [ Ubuntu: 5.4.0-42.46 ] + + * focal/linux: 5.4.0-42.46 -proposed tracker (LP: #1887069) + * linux 4.15.0-109-generic network DoS regression vs -108 (LP: #1886668) + - SAUCE: Revert "netprio_cgroup: Fix unlimited memory leak of v2 cgroups" + + -- Khalid Elmously Fri, 10 Jul 2020 02:11:06 -0400 + +linux-oracle (5.4.0-1020.20) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1020.20 -proposed tracker (LP: #1885851) + + [ Ubuntu: 5.4.0-41.45 ] + + * focal/linux: 5.4.0-41.45 -proposed tracker (LP: #1885855) + * Packaging resync (LP: #1786013) + - update dkms package versions + * CVE-2019-19642 + - kernel/relay.c: handle alloc_percpu returning NULL in relay_open + * CVE-2019-16089 + - SAUCE: nbd_genl_status: null check for nla_nest_start + * CVE-2020-11935 + - aufs: do not call i_readcount_inc() + * ip_defrag.sh in net from ubuntu_kernel_selftests failed with 5.0 / 5.3 / 5.4 + kernel (LP: #1826848) + - selftests: net: ip_defrag: ignore EPERM + * Update lockdown patches (LP: #1884159) + - SAUCE: acpi: disallow loading configfs acpi tables when locked down + * seccomp_bpf fails on powerpc (LP: #1885757) + - SAUCE: selftests/seccomp: fix ptrace tests on powerpc + * Introduce the new NVIDIA 418-server and 440-server series, and update the + current NVIDIA drivers (LP: #1881137) + - [packaging] add signed modules for the 418-server and the 440-server + flavours + + -- Ian May Mon, 06 Jul 2020 15:48:40 -0500 + +linux-oracle (5.4.0-1019.19) focal; urgency=medium + + * Focal update: v5.4.42 upstream stable release (LP: #1879759) + - [Config] oracle: Record CC_HAS_WARN_MAYBE_UNINITIALIZED drop + + * ASoC/amd: add audio driver for amd renoir (LP: #1881046) + - [Config] oracle: match amd renoir config with master + + [ Ubuntu: 5.4.0-40.44 ] + + * linux-oem-5.6-tools-common and -tools-host should be dropped (LP: #1881120) + - [Packaging] Add Conflicts/Replaces to remove linux-oem-5.6-tools-common and + -tools-host + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Slow send speed with Intel I219-V on Ubuntu 18.04.1 (LP: #1802691) + - e1000e: Disable TSO for buffer overrun workaround + * CVE-2020-0543 + - UBUNTU/SAUCE: x86/speculation/srbds: do not try to turn mitigation off when + not supported + * Realtek 8723DE [10ec:d723] subsystem [10ec:d738] disconnects unsolicitedly + when Bluetooth is paired: Reason: 23=IEEE8021X_FAILED (LP: #1878147) + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: Move driver IQK to set channel before + association for 11N chip" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: fix rate for a while after being + connected" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: No retry and report for auth and assoc" + - SAUCE: Revert "UBUNTU: SAUCE: rtw88: 8723d: Add coex support" + - rtw88: add a debugfs entry to dump coex's info + - rtw88: add a debugfs entry to enable/disable coex mechanism + - rtw88: 8723d: Add coex support + - SAUCE: rtw88: coex: 8723d: set antanna control owner + - SAUCE: rtw88: coex: 8723d: handle BT inquiry cases + - SAUCE: rtw88: fix EAPOL 4-way failure by finish IQK earlier + * CPU stress test fails with focal kernel (LP: #1867900) + - [Config] Disable hisi_sec2 temporarily + * Enforce all config annotations (LP: #1879327) + - [Config]: do not enforce CONFIG_VERSION_SIGNATURE + - [Config]: prepare to enforce all + - [Config]: enforce all config options + * Focal update: v5.4.44 upstream stable release (LP: #1881927) + - ax25: fix setsockopt(SO_BINDTODEVICE) + - dpaa_eth: fix usage as DSA master, try 3 + - net: don't return invalid table id error when we fall back to PF_UNSPEC + - net: dsa: mt7530: fix roaming from DSA user ports + - net: ethernet: ti: cpsw: fix ASSERT_RTNL() warning during suspend + - __netif_receive_skb_core: pass skb by reference + - net: inet_csk: Fix so_reuseport bind-address cache in tb->fast* + - net: ipip: fix wrong address family in init error path + - net/mlx5: Add command entry handling completion + - net: mvpp2: fix RX hashing for non-10G ports + - net: nlmsg_cancel() if put fails for nhmsg + - net: qrtr: Fix passing invalid reference to qrtr_local_enqueue() + - net: revert "net: get rid of an signed integer overflow in + ip_idents_reserve()" + - net sched: fix reporting the first-time use timestamp + - net/tls: fix race condition causing kernel panic + - nexthop: Fix attribute checking for groups + - r8152: support additional Microsoft Surface Ethernet Adapter variant + - sctp: Don't add the shutdown timer if its already been added + - sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and + socket is closed + - tipc: block BH before using dst_cache + - net/mlx5e: kTLS, Destroy key object after destroying the TIS + - net/mlx5e: Fix inner tirs handling + - net/mlx5: Fix memory leak in mlx5_events_init + - net/mlx5e: Update netdev txq on completions during closure + - net/mlx5: Fix error flow in case of function_setup failure + - net/mlx5: Annotate mutex destroy for root ns + - net/tls: fix encryption error checking + - net/tls: free record only on encryption error + - net: sun: fix missing release regions in cas_init_one(). + - net/mlx4_core: fix a memory leak bug. + - mlxsw: spectrum: Fix use-after-free of split/unsplit/type_set in case reload + fails + - ARM: dts: rockchip: fix phy nodename for rk3228-evb + - ARM: dts: rockchip: fix phy nodename for rk3229-xms6 + - arm64: dts: rockchip: fix status for &gmac2phy in rk3328-evb.dts + - arm64: dts: rockchip: swap interrupts interrupt-names rk3399 gpu node + - ARM: dts: rockchip: swap clock-names of gpu nodes + - ARM: dts: rockchip: fix pinctrl sub nodename for spi in rk322x.dtsi + - gpio: tegra: mask GPIO IRQs during IRQ shutdown + - ALSA: usb-audio: add mapping for ASRock TRX40 Creator + - net: microchip: encx24j600: add missed kthread_stop + - gfs2: move privileged user check to gfs2_quota_lock_check + - gfs2: Grab glock reference sooner in gfs2_add_revoke + - drm/amdgpu: drop unnecessary cancel_delayed_work_sync on PG ungate + - drm/amd/powerplay: perform PG ungate prior to CG ungate + - drm/amdgpu: Use GEM obj reference for KFD BOs + - cachefiles: Fix race between read_waiter and read_copier involving op->to_do + - usb: dwc3: pci: Enable extcon driver for Intel Merrifield + - usb: phy: twl6030-usb: Fix a resource leak in an error handling path in + 'twl6030_usb_probe()' + - usb: gadget: legacy: fix redundant initialization warnings + - net: freescale: select CONFIG_FIXED_PHY where needed + - IB/i40iw: Remove bogus call to netdev_master_upper_dev_get() + - riscv: stacktrace: Fix undefined reference to `walk_stackframe' + - clk: ti: am33xx: fix RTC clock parent + - csky: Fixup msa highest 3 bits mask + - csky: Fixup perf callchain unwind + - csky: Fixup remove duplicate irq_disable + - hwmon: (nct7904) Fix incorrect range of temperature limit registers + - cifs: Fix null pointer check in cifs_read + - csky: Fixup raw_copy_from_user() + - samples: bpf: Fix build error + - drivers: net: hamradio: Fix suspicious RCU usage warning in bpqether.c + - Input: usbtouchscreen - add support for BonXeon TP + - Input: evdev - call input_flush_device() on release(), not flush() + - Input: xpad - add custom init packet for Xbox One S controllers + - Input: dlink-dir685-touchkeys - fix a typo in driver name + - Input: i8042 - add ThinkPad S230u to i8042 reset list + - Input: synaptics-rmi4 - really fix attn_data use-after-free + - Input: synaptics-rmi4 - fix error return code in rmi_driver_probe() + - ARM: 8970/1: decompressor: increase tag size + - ARM: uaccess: consolidate uaccess asm to asm/uaccess-asm.h + - ARM: uaccess: integrate uaccess_save and uaccess_restore + - ARM: uaccess: fix DACR mismatch with nested exceptions + - gpio: exar: Fix bad handling for ida_simple_get error path + - arm64: dts: mt8173: fix vcodec-enc clock + - soc: mediatek: cmdq: return send msg error code + - gpu/drm: Ingenic: Fix opaque pointer casted to wrong type + - IB/qib: Call kobject_put() when kobject_init_and_add() fails + - ARM: dts/imx6q-bx50v3: Set display interface clock parents + - ARM: dts: bcm2835-rpi-zero-w: Fix led polarity + - ARM: dts: bcm: HR2: Fix PPI interrupt types + - mmc: block: Fix use-after-free issue for rpmb + - gpio: pxa: Fix return value of pxa_gpio_probe() + - gpio: bcm-kona: Fix return value of bcm_kona_gpio_probe() + - RDMA/pvrdma: Fix missing pci disable in pvrdma_pci_probe() + - ALSA: hwdep: fix a left shifting 1 by 31 UB bug + - ALSA: hda/realtek - Add a model for Thinkpad T570 without DAC workaround + - ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC + - exec: Always set cap_ambient in cap_bprm_set_creds + - clk: qcom: gcc: Fix parent for gpll0_out_even + - ALSA: usb-audio: Quirks for Gigabyte TRX40 Aorus Master onboard audio + - ALSA: hda/realtek - Add new codec supported for ALC287 + - libceph: ignore pool overlay and cache logic on redirects + - ceph: flush release queue when handling caps for unknown inode + - RDMA/core: Fix double destruction of uobject + - drm/amd/display: drop cursor position check in atomic test + - IB/ipoib: Fix double free of skb in case of multicast traffic in CM mode + - mm,thp: stop leaking unreleased file pages + - mm: remove VM_BUG_ON(PageSlab()) from page_mapcount() + - fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info() + - include/asm-generic/topology.h: guard cpumask_of_node() macro argument + - Revert "block: end bio with BLK_STS_AGAIN in case of non-mq devs and + REQ_NOWAIT" + - gpio: fix locking open drain IRQ lines + - iommu: Fix reference count leak in iommu_group_alloc. + - parisc: Fix kernel panic in mem_init() + - cfg80211: fix debugfs rename crash + - x86/syscalls: Revert "x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long" + - mac80211: mesh: fix discovery timer re-arming issue / crash + - x86/dma: Fix max PFN arithmetic overflow on 32 bit systems + - copy_xstate_to_kernel(): don't leave parts of destination uninitialized + - xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input + - xfrm: do pskb_pull properly in __xfrm_transport_prep + - xfrm: remove the xfrm_state_put call becofe going to out_reset + - xfrm: call xfrm_output_gso when inner_protocol is set in xfrm_output + - xfrm interface: fix oops when deleting a x-netns interface + - xfrm: fix a warning in xfrm_policy_insert_list + - xfrm: fix a NULL-ptr deref in xfrm_local_error + - xfrm: fix error in comment + - ip_vti: receive ipip packet by calling ip_tunnel_rcv + - netfilter: nft_reject_bridge: enable reject with bridge vlan + - netfilter: ipset: Fix subcounter update skip + - netfilter: conntrack: make conntrack userspace helpers work again + - netfilter: nfnetlink_cthelper: unbreak userspace helper support + - netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code + - esp6: get the right proto for transport mode in esp6_gso_encap + - bnxt_en: Fix accumulation of bp->net_stats_prev. + - ieee80211: Fix incorrect mask for default PE duration + - xsk: Add overflow check for u64 division, stored into u32 + - qlcnic: fix missing release in qlcnic_83xx_interrupt_test. + - crypto: chelsio/chtls: properly set tp->lsndtime + - nexthops: Move code from remove_nexthop_from_groups to remove_nh_grp_entry + - nexthops: don't modify published nexthop groups + - nexthop: Expand nexthop_is_multipath in a few places + - ipv4: nexthop version of fib_info_nh_uses_dev + - net: dsa: declare lockless TX feature for slave ports + - bonding: Fix reference count leak in bond_sysfs_slave_add. + - netfilter: conntrack: comparison of unsigned in cthelper confirmation + - netfilter: conntrack: Pass value of ctinfo to __nf_conntrack_update + - netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build + - perf: Make perf able to build with latest libbfd + - Linux 5.4.44 + * Focal update: v5.4.43 upstream stable release (LP: #1881178) + - i2c: dev: Fix the race between the release of i2c_dev and cdev + - KVM: SVM: Fix potential memory leak in svm_cpu_init() + - ima: Set file->f_mode instead of file->f_flags in ima_calc_file_hash() + - evm: Check also if *tfm is an error pointer in init_desc() + - ima: Fix return value of ima_write_policy() + - ubifs: fix wrong use of crypto_shash_descsize() + - ACPI: EC: PM: Avoid flushing EC work when EC GPE is inactive + - mtd: spinand: Propagate ECC information to the MTD structure + - fix multiplication overflow in copy_fdtable() + - ubifs: remove broken lazytime support + - i2c: fix missing pm_runtime_put_sync in i2c_device_probe + - iommu/amd: Fix over-read of ACPI UID from IVRS table + - evm: Fix a small race in init_desc() + - i2c: mux: demux-pinctrl: Fix an error handling path in + 'i2c_demux_pinctrl_probe()' + - ubi: Fix seq_file usage in detailed_erase_block_info debugfs file + - afs: Don't unlock fetched data pages until the op completes successfully + - mtd: Fix mtd not registered due to nvmem name collision + - kbuild: avoid concurrency issue in parallel building dtbs and dtbs_check + - net: drop_monitor: use IS_REACHABLE() to guard net_dm_hw_report() + - gcc-common.h: Update for GCC 10 + - HID: multitouch: add eGalaxTouch P80H84 support + - HID: alps: Add AUI1657 device ID + - HID: alps: ALPS_1657 is too specific; use U1_UNICORN_LEGACY instead + - scsi: qla2xxx: Fix hang when issuing nvme disconnect-all in NPIV + - scsi: qla2xxx: Delete all sessions before unregister local nvme port + - configfs: fix config_item refcnt leak in configfs_rmdir() + - vhost/vsock: fix packet delivery order to monitoring devices + - aquantia: Fix the media type of AQC100 ethernet controller in the driver + - component: Silence bind error on -EPROBE_DEFER + - net/ena: Fix build warning in ena_xdp_set() + - scsi: ibmvscsi: Fix WARN_ON during event pool release + - HID: i2c-hid: reset Synaptics SYNA2393 on resume + - x86/mm/cpa: Flush direct map alias during cpa + - ibmvnic: Skip fatal error reset after passive init + - x86/apic: Move TSC deadline timer debug printk + - gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp() + - HID: quirks: Add HID_QUIRK_NO_INIT_REPORTS quirk for Dell K12A keyboard-dock + - ceph: fix double unlock in handle_cap_export() + - stmmac: fix pointer check after utilization in stmmac_interrupt + - USB: core: Fix misleading driver bug report + - platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA + - iommu/amd: Call domain_flush_complete() in update_domain() + - drm/amd/display: Prevent dpcd reads with passive dongles + - KVM: selftests: Fix build for evmcs.h + - ARM: futex: Address build warning + - scripts/gdb: repair rb_first() and rb_last() + - ALSA: hda - constify and cleanup static NodeID tables + - ALSA: hda: patch_realtek: fix empty macro usage in if block + - ALSA: hda: Manage concurrent reg access more properly + - ALSA: hda/realtek - Add supported new mute Led for HP + - ALSA: hda/realtek - Add HP new mute led supported for ALC236 + - ALSA: hda/realtek: Add quirk for Samsung Notebook + - ALSA: hda/realtek - Enable headset mic of ASUS GL503VM with ALC295 + - ALSA: hda/realtek - Enable headset mic of ASUS UX550GE with ALC295 + - ALSA: hda/realtek: Enable headset mic of ASUS UX581LV with ALC295 + - KVM: x86: Fix pkru save/restore when guest CR4.PKE=0, move it to x86.c + - ALSA: iec1712: Initialize STDSP24 properly when using the model=staudio + option + - ALSA: pcm: fix incorrect hw_base increase + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Xtreme + - ALSA: hda/realtek - Add more fixup entries for Clevo machines + - scsi: qla2xxx: Do not log message when reading port speed via sysfs + - scsi: target: Put lun_ref at end of tmr processing + - arm64: Fix PTRACE_SYSEMU semantics + - drm/etnaviv: fix perfmon domain interation + - apparmor: Fix aa_label refcnt leak in policy_update + - dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()' + - drm/etnaviv: Fix a leak in submit_pin_objects() + - dmaengine: dmatest: Restore default for channel + - dmaengine: owl: Use correct lock in owl_dma_get_pchan() + - vsprintf: don't obfuscate NULL and error pointers + - drm/i915/gvt: Init DPLL/DDI vreg for virtual display instead of inheritance. + - drm/i915: Propagate error from completed fences + - powerpc: Remove STRICT_KERNEL_RWX incompatibility with RELOCATABLE + - powerpc/64s: Disable STRICT_KERNEL_RWX + - bpf: Avoid setting bpf insns pages read-only when prog is jited + - kbuild: Remove debug info from kallsyms linking + - Revert "gfs2: Don't demote a glock until its revokes are written" + - media: fdp1: Fix R-Car M3-N naming in debug message + - staging: iio: ad2s1210: Fix SPI reading + - staging: kpc2000: fix error return code in kp2000_pcie_probe() + - staging: greybus: Fix uninitialized scalar variable + - iio: sca3000: Remove an erroneous 'get_device()' + - iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()' + - iio: adc: ti-ads8344: Fix channel selection + - misc: rtsx: Add short delay after exit from ASPM + - tty: serial: add missing spin_lock_init for SiFive serial console + - mei: release me_cl object reference + - ipack: tpci200: fix error return code in tpci200_register() + - s390/kaslr: add support for R_390_JMP_SLOT relocation type + - device-dax: don't leak kernel memory to user space after unloading kmem + - rapidio: fix an error in get_user_pages_fast() error handling + - kasan: disable branch tracing for core runtime + - rxrpc: Fix the excessive initial retransmission timeout + - rxrpc: Fix a memory leak in rxkad_verify_response() + - s390/kexec_file: fix initrd location for kdump kernel + - flow_dissector: Drop BPF flow dissector prog ref on netns cleanup + - x86/unwind/orc: Fix unwind_get_return_address_ptr() for inactive tasks + - iio: adc: stm32-adc: Use dma_request_chan() instead + dma_request_slave_channel() + - iio: adc: stm32-adc: fix device used to request dma + - iio: adc: stm32-dfsdm: Use dma_request_chan() instead + dma_request_slave_channel() + - iio: adc: stm32-dfsdm: fix device used to request dma + - rxrpc: Trace discarded ACKs + - rxrpc: Fix ack discard + - tpm: check event log version before reading final events + - sched/fair: Reorder enqueue/dequeue_task_fair path + - sched/fair: Fix reordering of enqueue/dequeue_task_fair() + - sched/fair: Fix enqueue_task_fair() warning some more + - Linux 5.4.43 + * Focal update: v5.4.42 upstream stable release (LP: #1879759) + - net: dsa: Do not make user port errors fatal + - shmem: fix possible deadlocks on shmlock_user_lock + - net: phy: microchip_t1: add lan87xx_phy_init to initialize the lan87xx phy. + - KVM: arm: vgic: Synchronize the whole guest on GIC{D,R}_I{S,C}ACTIVER read + - gpio: pca953x: Fix pca953x_gpio_set_config + - SUNRPC: Add "@len" parameter to gss_unwrap() + - SUNRPC: Fix GSS privacy computation of auth->au_ralign + - net/sonic: Fix a resource leak in an error handling path in + 'jazz_sonic_probe()' + - net: moxa: Fix a potential double 'free_irq()' + - ftrace/selftests: workaround cgroup RT scheduling issues + - drop_monitor: work around gcc-10 stringop-overflow warning + - virtio-blk: handle block_device_operations callbacks after hot unplug + - sun6i: dsi: fix gcc-4.8 + - net_sched: fix tcm_parent in tc filter dump + - scsi: sg: add sg_remove_request in sg_write + - mmc: sdhci-acpi: Add SDHCI_QUIRK2_BROKEN_64_BIT_DMA for AMDI0040 + - dpaa2-eth: properly handle buffer size restrictions + - net: fix a potential recursive NETDEV_FEAT_CHANGE + - netlabel: cope with NULL catmap + - net: phy: fix aneg restart in phy_ethtool_set_eee + - net: stmmac: fix num_por initialization + - pppoe: only process PADT targeted at local interfaces + - Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu" + - tcp: fix error recovery in tcp_zerocopy_receive() + - tcp: fix SO_RCVLOWAT hangs with fat skbs + - virtio_net: fix lockdep warning on 32 bit + - dpaa2-eth: prevent array underflow in update_cls_rule() + - hinic: fix a bug of ndo_stop + - net: dsa: loop: Add module soft dependency + - net: ipv4: really enforce backoff for redirects + - netprio_cgroup: Fix unlimited memory leak of v2 cgroups + - net: tcp: fix rx timestamp behavior for tcp_recvmsg + - nfp: abm: fix error return code in nfp_abm_vnic_alloc() + - r8169: re-establish support for RTL8401 chip version + - umh: fix memory leak on execve failure + - riscv: fix vdso build with lld + - dmaengine: pch_dma.c: Avoid data race between probe and irq handler + - dmaengine: mmp_tdma: Do not ignore slave config validation errors + - dmaengine: mmp_tdma: Reset channel error on release + - selftests/ftrace: Check the first record for kprobe_args_type.tc + - cpufreq: intel_pstate: Only mention the BIOS disabling turbo mode once + - ALSA: hda/hdmi: fix race in monitor detection during probe + - drm/amd/powerplay: avoid using pm_en before it is initialized revised + - drm/amd/display: check if REFCLK_CNTL register is present + - drm/amd/display: Update downspread percent to match spreadsheet for DCN2.1 + - drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper() + - drm/amdgpu: simplify padding calculations (v2) + - drm/amdgpu: invalidate L2 before SDMA IBs (v2) + - ipc/util.c: sysvipc_find_ipc() incorrectly updates position index + - gfs2: Another gfs2_walk_metadata fix + - mmc: sdhci-pci-gli: Fix no irq handler from suspend + - IB/hfi1: Fix another case where pq is left on waitlist + - ACPI: EC: PM: Avoid premature returns from acpi_s2idle_wake() + - pinctrl: sunrisepoint: Fix PAD lock register offset for SPT-H + - pinctrl: baytrail: Enable pin configuration setting for GPIO chip + - pinctrl: qcom: fix wrong write in update_dual_edge + - pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler + - bpf: Fix error return code in map_lookup_and_delete_elem() + - ALSA: firewire-lib: fix 'function sizeof not defined' error of tracepoints + format + - i40iw: Fix error handling in i40iw_manage_arp_cache() + - drm/i915: Don't enable WaIncreaseLatencyIPCEnabled when IPC is disabled + - bpf, sockmap: msg_pop_data can incorrecty set an sge length + - bpf, sockmap: bpf_tcp_ingress needs to subtract bytes from sg.size + - mmc: alcor: Fix a resource leak in the error path for ->probe() + - mmc: sdhci-pci-gli: Fix can not access GL9750 after reboot from Windows 10 + - mmc: core: Check request type before completing the request + - mmc: core: Fix recursive locking issue in CQE recovery path + - mmc: block: Fix request completion in the CQE timeout path + - gfs2: More gfs2_find_jhead fixes + - fork: prevent accidental access to clone3 features + - drm/amdgpu: force fbdev into vram + - NFS: Fix fscache super_cookie index_key from changing after umount + - nfs: fscache: use timespec64 in inode auxdata + - NFSv4: Fix fscache cookie aux_data to ensure change_attr is included + - netfilter: conntrack: avoid gcc-10 zero-length-bounds warning + - drm/i915/gvt: Fix kernel oops for 3-level ppgtt guest + - arm64: fix the flush_icache_range arguments in machine_kexec + - nfs: fix NULL deference in nfs4_get_valid_delegation + - SUNRPC: Signalled ASYNC tasks need to exit + - netfilter: nft_set_rbtree: Introduce and use nft_rbtree_interval_start() + - netfilter: nft_set_rbtree: Add missing expired checks + - RDMA/rxe: Always return ERR_PTR from rxe_create_mmap_info() + - IB/mlx4: Test return value of calls to ib_get_cached_pkey + - IB/core: Fix potential NULL pointer dereference in pkey cache + - RDMA/core: Fix double put of resource + - RDMA/iw_cxgb4: Fix incorrect function parameters + - hwmon: (da9052) Synchronize access with mfd + - s390/ism: fix error return code in ism_probe() + - mm, memcg: fix inconsistent oom event behavior + - NFSv3: fix rpc receive buffer size for MOUNT call + - pnp: Use list_for_each_entry() instead of open coding + - net/rds: Use ERR_PTR for rds_message_alloc_sgs() + - Stop the ad-hoc games with -Wno-maybe-initialized + - [Config] updateconfigs for CC_HAS_WARN_MAYBE_UNINITIALIZED + - gcc-10: disable 'zero-length-bounds' warning for now + - gcc-10: disable 'array-bounds' warning for now + - gcc-10: disable 'stringop-overflow' warning for now + - gcc-10: disable 'restrict' warning for now + - gcc-10 warnings: fix low-hanging fruit + - gcc-10: mark more functions __init to avoid section mismatch warnings + - gcc-10: avoid shadowing standard library 'free()' in crypto + - usb: usbfs: correct kernel->user page attribute mismatch + - USB: usbfs: fix mmap dma mismatch + - ALSA: hda/realtek - Limit int mic boost for Thinkpad T530 + - ALSA: hda/realtek - Add COEF workaround for ASUS ZenBook UX431DA + - ALSA: rawmidi: Fix racy buffer resize under concurrent accesses + - ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset + - usb: core: hub: limit HUB_QUIRK_DISABLE_AUTOSUSPEND to USB5534B + - usb: host: xhci-plat: keep runtime active when removing host + - usb: cdns3: gadget: prev_req->trb is NULL for ep0 + - usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list + - Make the "Reducing compressed framebufer size" message be DRM_INFO_ONCE() + - ARM: dts: dra7: Fix bus_dma_limit for PCIe + - ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries + - ARM: dts: imx6dl-yapp4: Fix Ursa board Ethernet connection + - drm/amd/display: add basic atomic check for cursor plane + - powerpc/32s: Fix build failure with CONFIG_PPC_KUAP_DEBUG + - cifs: fix leaked reference on requeued write + - x86: Fix early boot crash on gcc-10, third try + - x86/unwind/orc: Fix error handling in __unwind_start() + - exec: Move would_dump into flush_old_exec + - clk: rockchip: fix incorrect configuration of rk3228 aclk_gpu* clocks + - dwc3: Remove check for HWO flag in dwc3_gadget_ep_reclaim_trb_sg() + - fanotify: fix merging marks masks with FAN_ONDIR + - usb: gadget: net2272: Fix a memory leak in an error handling path in + 'net2272_plat_probe()' + - usb: gadget: audio: Fix a missing error return value in audio_bind() + - usb: gadget: legacy: fix error return code in gncm_bind() + - usb: gadget: legacy: fix error return code in cdc_bind() + - clk: Unlink clock if failed to prepare or enable + - arm64: dts: meson-g12b-khadas-vim3: add missing frddr_a status property + - arm64: dts: meson-g12-common: fix dwc2 clock names + - arm64: dts: rockchip: Replace RK805 PMIC node name with "pmic" on rk3328 + boards + - arm64: dts: rockchip: Rename dwc3 device nodes on rk3399 to make dtc happy + - arm64: dts: imx8mn: Change SDMA1 ahb clock for imx8mn + - ARM: dts: r8a73a4: Add missing CMT1 interrupts + - arm64: dts: renesas: r8a77980: Fix IPMMU VIP[01] nodes + - ARM: dts: r8a7740: Add missing extal2 to CPG node + - SUNRPC: Revert 241b1f419f0e ("SUNRPC: Remove xdr_buf_trim()") + - bpf: Fix sk_psock refcnt leak when receiving message + - KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce + - Makefile: disallow data races on gcc-10 as well + - Linux 5.4.42 + * upgrading to 4.15.0-99-generic breaks the sound and the trackpad + (LP: #1875916) // Focal update: v5.4.42 upstream stable release + (LP: #1879759) + - Revert "ALSA: hda/realtek: Fix pop noise on ALC225" + * Pop sound from build-in speaker during cold boot and resume from S3 + (LP: #1866357) // Focal update: v5.4.42 upstream stable release + (LP: #1879759) + - ALSA: hda/realtek - Fix S3 pop noise on Dell Wyse + * tpm: fix TIS locality timeout problems (LP: #1881710) + - SAUCE: tpm: fix TIS locality timeout problems + * [UBUNTU 20.04] s390x/pci: fix linking between PF and VF for multifunction + devices (LP: #1879704) + - PCI/IOV: Introduce pci_iov_sysfs_link() function + - s390/pci: create links between PFs and VFs + * Performing function level reset of AMD onboard USB and audio devices causes + system lockup (LP: #1865988) + - SAUCE: PCI: Avoid FLR for AMD Matisse HD Audio & USB 3.0 + - SAUCE: PCI: Avoid FLR for AMD Starship USB 3.0 + * seccomp_benchmark times out on eoan (LP: #1881576) + - SAUCE: selftests/seccomp: use 90s as timeout + * ASoC/amd: add audio driver for amd renoir (LP: #1881046) + - ASoC: amd: add Renoir ACP3x IP register header + - ASoC: amd: add Renoir ACP PCI driver + - ASoC: amd: add acp init/de-init functions + - ASoC: amd: create acp3x pdm platform device + - ASoC: amd: add ACP3x PDM platform driver + - ASoC: amd: irq handler changes for ACP3x PDM dma driver + - ASoC: amd: add acp3x pdm driver dma ops + - ASoC: amd: add ACP PDM DMA driver dai ops + - ASoC: amd: add Renoir ACP PCI driver PM ops + - ASoC: amd: add ACP PDM DMA driver pm ops + - ASoC: amd: enable Renoir acp3x drivers build + - ASoC: amd: create platform devices for Renoir + - ASoC: amd: RN machine driver using dmic + - ASoC: amd: enable build for RN machine driver + - ASoC: amd: fix kernel warning + - ASoC: amd: refactoring dai_hw_params() callback + - ASoC: amd: return error when acp de-init fails + - [Config]: enable amd renoir ASoC audio + * Fix for secure boot rules in IMA arch policy on powerpc (LP: #1877955) + - powerpc/ima: Fix secure boot rules in ima arch policy + * [UBUNTU 20.04] s390x/pci: s390_pci_mmio_write/read fail when MIO + instructions are available (LP: #1874055) + - s390/pci: Fix s390_mmio_read/write with MIO + * security: lockdown: remove trailing semicolon before function body + (LP: #1880660) + - SAUCE: (lockdown) security: lockdown: remove trailing semicolon before + function body + * Fix incorrect speed/duplex when I210 device is runtime suspended + (LP: #1880656) + - igb: Report speed and duplex as unknown when device is runtime suspended + * [OMEN by HP Laptop 15-dh0xxx, Realtek ALC285, Black Mic, Left] Recording + problem (LP: #1874698) + - ASoC: SOF: Intel: hda: allow operation without i915 gfx + - ASoC: intel/skl/hda - add no-HDMI cases to generic HDA driver + * CVE-2020-13143 + - USB: gadget: fix illegal array access in binding with UDC + * rtl8723bu wifi issue after being turned off (LP: #1878296) + - rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver + - rtl8xxxu: add bluetooth co-existence support for single antenna + - rtl8xxxu: remove set but not used variable 'rate_mask' + - rtl8xxxu: Remove set but not used variable 'vif', 'dev', 'len' + * Fix Pericom USB controller OHCI/EHCI PME# defect (LP: #1879321) + - serial: 8250_pci: Move Pericom IDs to pci_ids.h + - PCI: Avoid Pericom USB controller OHCI/EHCI PME# defect + * shiftfs: fix btrfs snapshot deletion (LP: #1879688) + - SAUCE: shiftfs: let userns root destroy subvolumes from other users + * [UBUNTU 20.04] s390x/pci: enumerate pci functions per physical adapter + (LP: #1874056) + - s390/pci: Improve handling of unset UID + - s390/pci: embedding hotplug_slot in zdev + - s390/pci: Expose new port attribute for PCIe functions + - s390/pci: adaptation of iommu to multifunction + - s390/pci: define kernel parameters for PCI multifunction + - s390/pci: define RID and RID available + - s390/pci: create zPCI bus + - s390/pci: adapt events for zbus + - s390/pci: Handling multifunctions + - s390/pci: Do not disable PF when VFs exist + - s390/pci: Documentation for zPCI + - s390/pci: removes wrong PCI multifunction assignment + * update-initramfs complains of missing amdgpu firmware files (LP: #1873325) + - SAUCE: drm/amdgpu: Remove unreleased arcturus and navi12 firmware from + modinfo + + -- Kleber Sacilotto de Souza Tue, 23 Jun 2020 17:34:33 +0200 + +linux-oracle (5.4.0-1018.18) focal; urgency=medium + + + [ Ubuntu: 5.4.0-39.43 ] + + * dkms-build: downloads fail in private PPAs (LP: #1883874) + - dkms-build: apt-cache policy elides username:password information + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Mon, 22 Jun 2020 12:05:44 +0200 + +linux-oracle (5.4.0-1015.15) focal; urgency=medium + + + [ Ubuntu: 5.4.0-37.41 ] + + * CVE-2020-0543 + - SAUCE: x86/speculation/spectre_v2: Exclude Zhaoxin CPUs from SPECTRE_V2 + - SAUCE: x86/cpu: Add a steppings field to struct x86_cpu_id + - SAUCE: x86/cpu: Add 'table' argument to cpu_matches() + - SAUCE: x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) + mitigation + - SAUCE: x86/speculation: Add SRBDS vulnerability and mitigation documentation + - SAUCE: x86/speculation: Add Ivy Bridge to affected list + + -- Thadeu Lima de Souza Cascardo Thu, 04 Jun 2020 21:51:32 -0300 + +linux-oracle (5.4.0-1012.12) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1012.12 -proposed tracker (LP: #1878796) + + * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after + upgrade to 20.04 (LP: #1875665) + - [Config] Turn off CONFIG_RT_GROUP_SCHED + + [ Ubuntu: 5.4.0-34.38 ] + + * focal/linux: 5.4.0-34.38 -proposed tracker (LP: #1880118) + * debian/scripts/file-downloader does not handle positive failures correctly + (LP: #1878897) + - [Packaging] file-downloader not handling positive failures correctly + * Focal update: v5.4.41 upstream stable release (LP: #1878649) + - USB: serial: qcserial: Add DW5816e support + - nvme: refactor nvme_identify_ns_descs error handling + - nvme: fix possible hang when ns scanning fails during error recovery + - tracing/kprobes: Fix a double initialization typo + - net: macb: Fix runtime PM refcounting + - drm/amdgpu: move kfd suspend after ip_suspend_phase1 + - drm/amdgpu: drop redundant cg/pg ungate on runpm enter + - vt: fix unicode console freeing with a common interface + - tty: xilinx_uartps: Fix missing id assignment to the console + - devlink: fix return value after hitting end in region read + - dp83640: reverse arguments to list_add_tail + - fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks + - ipv6: Use global sernum for dst validation with nexthop objects + - mlxsw: spectrum_acl_tcam: Position vchunk in a vregion list properly + - neigh: send protocol value in neighbor create notification + - net: dsa: Do not leave DSA master with NULL netdev_ops + - net: macb: fix an issue about leak related system resources + - net: macsec: preserve ingress frame ordering + - net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc() + - net_sched: sch_skbprio: add message validation to skbprio_change() + - net: stricter validation of untrusted gso packets + - net: tc35815: Fix phydev supported/advertising mask + - net/tls: Fix sk_psock refcnt leak in bpf_exec_tx_verdict() + - net/tls: Fix sk_psock refcnt leak when in tls_data_ready() + - net: usb: qmi_wwan: add support for DW5816e + - nfp: abm: fix a memory leak bug + - sch_choke: avoid potential panic in choke_reset() + - sch_sfq: validate silly quantum values + - tipc: fix partial topology connection closure + - tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 + - bnxt_en: Fix VF anti-spoof filter setup. + - bnxt_en: Reduce BNXT_MSIX_VEC_MAX value to supported CQs per PF. + - bnxt_en: Improve AER slot reset. + - bnxt_en: Return error when allocating zero size context memory. + - bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features(). + - net/mlx5: DR, On creation set CQ's arm_db member to right value + - net/mlx5: Fix forced completion access non initialized command entry + - net/mlx5: Fix command entry leak in Internal Error State + - net: mvpp2: prevent buffer overflow in mvpp22_rss_ctx() + - net: mvpp2: cls: Prevent buffer overflow in mvpp2_ethtool_cls_rule_del() + - HID: wacom: Read HID_DG_CONTACTMAX directly for non-generic devices + - sctp: Fix bundling of SHUTDOWN with COOKIE-ACK + - Revert "HID: wacom: generic: read the number of expected touches on a per + collection basis" + - HID: usbhid: Fix race between usbhid_close() and usbhid_stop() + - HID: wacom: Report 2nd-gen Intuos Pro S center button status over BT + - USB: uas: add quirk for LaCie 2Big Quadra + - usb: chipidea: msm: Ensure proper controller reset using role switch API + - USB: serial: garmin_gps: add sanity checking for data length + - tracing: Add a vmalloc_sync_mappings() for safe measure + - crypto: arch/nhpoly1305 - process in explicit 4k chunks + - KVM: s390: Remove false WARN_ON_ONCE for the PQAP instruction + - KVM: VMX: Explicitly clear RFLAGS.CF and RFLAGS.ZF in VM-Exit RSB path + - KVM: arm: vgic: Fix limit condition when writing to GICD_I[CS]ACTIVER + - KVM: arm64: Fix 32bit PC wrap-around + - arm64: hugetlb: avoid potential NULL dereference + - drm: ingenic-drm: add MODULE_DEVICE_TABLE + - ipc/mqueue.c: change __do_notify() to bypass check_kill_permission() + - epoll: atomically remove wait entry on wake up + - eventpoll: fix missing wakeup for ovflist in ep_poll_callback + - mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous() + - mm: limit boost_watermark on small zones + - ceph: demote quotarealm lookup warning to a debug message + - staging: gasket: Check the return value of gasket_get_bar_index() + - coredump: fix crash when umh is disabled + - iocost: protect iocg->abs_vdebt with iocg->waitq.lock + - batman-adv: fix batadv_nc_random_weight_tq + - batman-adv: Fix refcnt leak in batadv_show_throughput_override + - batman-adv: Fix refcnt leak in batadv_store_throughput_override + - batman-adv: Fix refcnt leak in batadv_v_ogm_process + - x86/entry/64: Fix unwind hints in register clearing code + - x86/entry/64: Fix unwind hints in kernel exit path + - x86/entry/64: Fix unwind hints in rewind_stack_do_exit() + - x86/unwind/orc: Don't skip the first frame for inactive tasks + - x86/unwind/orc: Prevent unwinding before ORC initialization + - x86/unwind/orc: Fix error path for bad ORC entry type + - x86/unwind/orc: Fix premature unwind stoppage due to IRET frames + - KVM: x86: Fixes posted interrupt check for IRQs delivery modes + - arch/x86/kvm/svm/sev.c: change flag passed to GUP fast in sev_pin_memory() + - netfilter: nat: never update the UDP checksum when it's 0 + - netfilter: nf_osf: avoid passing pointer to local var + - objtool: Fix stack offset tracking for indirect CFAs + - iommu/virtio: Reverse arguments to list_add + - scripts/decodecode: fix trapping instruction formatting + - mm, memcg: fix error return value of mem_cgroup_css_alloc() + - bdi: move bdi_dev_name out of line + - bdi: add a ->dev_name field to struct backing_dev_info + - fsnotify: replace inode pointer with an object id + - fanotify: merge duplicate events on parent and child + - Linux 5.4.41 + * Intel GPU Hangs : random screen freezing w/ Ubuntu 20.04 (Linux 5.4) + i915_active_acquire (LP: #1868551) + - drm/i915: Hold reference to intel_frontbuffer as we track activity + - drm/i915: fix uninitialized pointer reads on pointers to and from + * Kernel panic due to NULL ringbuffer vaddr dereference in i915 (LP: #1877394) + - Revert "UBUNTU: SAUCE: drm/i915: Synchronize active and retire callbacks" + - drm/i915/gt: Make intel_ring_unpin() safe for concurrent pint + * add 16-bit width registers support for EEPROM at24 device (LP: #1876699) + - regmap-i2c: add 16-bit width registers support + * [UBUNTU 20.04] PSI generates overhead on s390x (LP: #1876044) + - Ubuntu: [Config] Set CONFIG_PSI_DEFAULT_DISABLED=y on s390x + * Focal update: v5.4.40 upstream stable release (LP: #1878040) + - vhost: vsock: kick send_pkt worker once device is started + - drm/bridge: analogix_dp: Split bind() into probe() and real bind() + - ASoC: topology: Check return value of soc_tplg_create_tlv + - ASoC: topology: Check return value of soc_tplg_*_create + - ASoC: topology: Check soc_tplg_add_route return value + - ASoC: topology: Check return value of pcm_new_ver + - ASoC: topology: Check return value of soc_tplg_dai_config + - selftests/ipc: Fix test failure seen after initial test run + - ASoC: sgtl5000: Fix VAG power-on handling + - ASoC: topology: Fix endianness issue + - usb: dwc3: gadget: Properly set maxpacket limit + - ASoC: rsnd: Fix parent SSI start/stop in multi-SSI mode + - ASoC: rsnd: Fix HDMI channel mapping for multi-SSI mode + - ASoC: codecs: hdac_hdmi: Fix incorrect use of list_for_each_entry + - remoteproc: qcom_q6v5_mss: fix a bug in q6v5_probe() + - drm/amdgpu: Correctly initialize thermal controller for GPUs with Powerplay + table v0 (e.g Hawaii) + - wimax/i2400m: Fix potential urb refcnt leak + - net: stmmac: fix enabling socfpga's ptp_ref_clock + - net: stmmac: Fix sub-second increment + - ASoC: rsnd: Don't treat master SSI in multi SSI setup as parent + - ASoC: rsnd: Fix "status check failed" spam for multi-SSI + - cifs: protect updating server->dstaddr with a spinlock + - scripts/config: allow colons in option strings for sed + - cifs: do not share tcons with DFS + - tracing: Fix memory leaks in trace_events_hist.c + - lib/mpi: Fix building for powerpc with clang + - mac80211: sta_info: Add lockdep condition for RCU list usage + - net: bcmgenet: suppress warnings on failed Rx SKB allocations + - net: systemport: suppress warnings on failed Rx SKB allocations + - drm/i915: Extend WaDisableDARBFClkGating to icl,ehl,tgl + - sctp: Fix SHUTDOWN CTSN Ack in the peer restart case + - Revert "software node: Simplify software_node_release() function" + - hexagon: clean up ioremap + - hexagon: define ioremap_uc + - ALSA: hda: Match both PCI ID and SSID for driver blacklist + - x86/kvm: fix a missing-prototypes "vmread_error" + - platform/x86: GPD pocket fan: Fix error message when temp-limits are out of + range + - ACPI: PM: s2idle: Fix comment in acpi_s2idle_prepare_late() + - mac80211: add ieee80211_is_any_nullfunc() + - cgroup, netclassid: remove double cond_resched + - libbpf: Fix readelf output parsing for Fedora + - mm/mremap: Add comment explaining the untagging behaviour of mremap() + - Revert "drm/amd/display: setting the DIG_MODE to the correct value." + - tools headers UAPI: Sync copy of arm64's asm/unistd.h with the kernel + sources + - udp: document udp_rcv_segment special case for looped packets + - PM / devfreq: Add missing locking while setting suspend_freq + - Linux 5.4.40 + * Focal update: v5.4.39 upstream stable release (LP: #1877592) + - dma-buf: Fix SET_NAME ioctl uapi + - drm/edid: Fix off-by-one in DispID DTD pixel clock + - drm/amd/display: Fix green screen issue after suspend + - drm/qxl: qxl_release leak in qxl_draw_dirty_fb() + - drm/qxl: qxl_release leak in qxl_hw_surface_alloc() + - drm/qxl: qxl_release use after free + - NFSv4.1: fix handling of backchannel binding in BIND_CONN_TO_SESSION + - btrfs: fix transaction leak in btrfs_recover_relocation + - btrfs: fix block group leak when removing fails + - btrfs: fix partial loss of prealloc extent past i_size after fsync + - btrfs: transaction: Avoid deadlock due to bad initialization timing of + fs_info::journal_info + - mmc: cqhci: Avoid false "cqhci: CQE stuck on" by not open-coding timeout + loop + - mmc: sdhci-xenon: fix annoying 1.8V regulator warning + - mmc: sdhci-pci: Fix eMMC driver strength for BYT-based controllers + - mmc: sdhci-msm: Enable host capabilities pertains to R1b response + - mmc: meson-mx-sdio: Set MMC_CAP_WAIT_WHILE_BUSY + - mmc: meson-mx-sdio: remove the broken ->card_busy() op + - crypto: caam - fix the address of the last entry of S/G + - ALSA: hda/realtek - Two front mics on a Lenovo ThinkCenter + - ALSA: usb-audio: Correct a typo of NuPrime DAC-10 USB ID + - ALSA: hda/hdmi: fix without unlocked before return + - ALSA: line6: Fix POD HD500 audio playback + - ALSA: pcm: oss: Place the plugin buffer overflow checks correctly + - i2c: amd-mp2-pci: Fix Oops in amd_mp2_pci_init() error handling + - Drivers: hv: vmbus: Fix Suspend-to-Idle for Generation-2 VM + - dlmfs_file_write(): fix the bogosity in handling non-zero *ppos + - IB/rdmavt: Always return ERR_PTR from rvt_create_mmap_info() + - PM: ACPI: Output correct message on target power state + - PM: hibernate: Freeze kernel threads in software_resume() + - dm verity fec: fix hash block number in verity_fec_decode + - dm writecache: fix data corruption when reloading the target + - dm multipath: use updated MPATHF_QUEUE_IO on mapping for bio-based mpath + - ARM: dts: imx6qdl-sr-som-ti: indicate powering off wifi is safe + - scsi: qla2xxx: set UNLOADING before waiting for session deletion + - scsi: qla2xxx: check UNLOADING before posting async work + - RDMA/mlx5: Set GRH fields in query QP on RoCE + - RDMA/mlx4: Initialize ib_spec on the stack + - RDMA/siw: Fix potential siw_mem refcnt leak in siw_fastreg_mr() + - RDMA/core: Prevent mixed use of FDs between shared ufiles + - RDMA/core: Fix race between destroy and release FD object + - RDMA/cm: Fix ordering of xa_alloc_cyclic() in ib_create_cm_id() + - RDMA/cm: Fix an error check in cm_alloc_id_priv() + - i2c: iproc: generate stop event for slave writes + - vfio: avoid possible overflow in vfio_iommu_type1_pin_pages + - vfio/type1: Fix VA->PA translation for PFNMAP VMAs in vaddr_get_pfn() + - iommu/qcom: Fix local_base status check + - scsi: target/iblock: fix WRITE SAME zeroing + - iommu/amd: Fix legacy interrupt remapping for x2APIC-enabled system + - i2c: aspeed: Avoid i2c interrupt status clear race condition. + - ALSA: opti9xx: shut up gcc-10 range warning + - Fix use after free in get_tree_bdev() + - nvme: prevent double free in nvme_alloc_ns() error handling + - nfs: Fix potential posix_acl refcnt leak in nfs3_set_acl + - dmaengine: dmatest: Fix iteration non-stop logic + - dmaengine: dmatest: Fix process hang when reading 'wait' parameter + - arm64: vdso: Add -fasynchronous-unwind-tables to cflags + - selinux: properly handle multiple messages in selinux_netlink_send() + - Linux 5.4.39 + * Focal update: v5.4.38 upstream stable release (LP: #1876767) + - Linux 5.4.38 + * Focal update: v5.4.37 upstream stable release (LP: #1876765) + - remoteproc: Fix wrong rvring index computation + - ubifs: Fix ubifs_tnc_lookup() usage in do_kill_orphans() + - printk: queue wake_up_klogd irq_work only if per-CPU areas are ready + - ASoC: stm32: sai: fix sai probe + - usb: dwc3: gadget: Do link recovery for SS and SSP + - kbuild: fix DT binding schema rule again to avoid needless rebuilds + - usb: gadget: udc: bdc: Remove unnecessary NULL checks in bdc_req_complete + - usb: gadget: udc: atmel: Fix vbus disconnect handling + - afs: Make record checking use TASK_UNINTERRUPTIBLE when appropriate + - afs: Fix to actually set AFS_SERVER_FL_HAVE_EPOCH + - iio:ad7797: Use correct attribute_group + - propagate_one(): mnt_set_mountpoint() needs mount_lock + - counter: 104-quad-8: Add lock guards - generic interface + - s390/ftrace: fix potential crashes when switching tracers + - ASoC: q6dsp6: q6afe-dai: add missing channels to MI2S DAIs + - ASoC: tas571x: disable regulators on failed probe + - ASoC: wm8960: Fix wrong clock after suspend & resume + - drivers: soc: xilinx: fix firmware driver Kconfig dependency + - nfsd: memory corruption in nfsd4_lock() + - bpf: Forbid XADD on spilled pointers for unprivileged users + - i2c: altera: use proper variable to hold errno + - rxrpc: Fix DATA Tx to disable nofrag for UDP on AF_INET6 socket + - net/cxgb4: Check the return from t4_query_params properly + - xfs: acquire superblock freeze protection on eofblocks scans + - svcrdma: Fix trace point use-after-free race + - svcrdma: Fix leak of svc_rdma_recv_ctxt objects + - net/mlx5e: Don't trigger IRQ multiple times on XSK wakeup to avoid WQ + overruns + - net/mlx5e: Get the latest values from counters in switchdev mode + - PCI: Add ACS quirk for Zhaoxin multi-function devices + - PCI: Make ACS quirk implementations more uniform + - PCI: Unify ACS quirk desired vs provided checking + - PCI: Add Zhaoxin Vendor ID + - PCI: Add ACS quirk for Zhaoxin Root/Downstream Ports + - PCI: Move Apex Edge TPU class quirk to fix BAR assignment + - ARM: dts: bcm283x: Disable dsi0 node + - cpumap: Avoid warning when CONFIG_DEBUG_PER_CPU_MAPS is enabled + - s390/pci: do not set affinity for floating irqs + - net/mlx5: Fix failing fw tracer allocation on s390 + - sched/core: Fix reset-on-fork from RT with uclamp + - perf/core: fix parent pid/tid in task exit events + - netfilter: nat: fix error handling upon registering inet hook + - PM: sleep: core: Switch back to async_schedule_dev() + - blk-iocost: Fix error on iocost_ioc_vrate_adj + - um: ensure `make ARCH=um mrproper` removes + arch/$(SUBARCH)/include/generated/ + - bpf, x86_32: Fix incorrect encoding in BPF_LDX zero-extension + - bpf, x86_32: Fix clobbering of dst for BPF_JSET + - bpf, x86_32: Fix logic error in BPF_LDX zero-extension + - mm: shmem: disable interrupt when acquiring info->lock in userfaultfd_copy + path + - xfs: clear PF_MEMALLOC before exiting xfsaild thread + - bpf, x86: Fix encoding for lower 8-bit registers in BPF_STX BPF_B + - libbpf: Initialize *nl_pid so gcc 10 is happy + - net: fec: set GPR bit on suspend by DT configuration. + - x86: hyperv: report value of misc_features + - signal: check sig before setting info in kill_pid_usb_asyncio + - afs: Fix length of dump of bad YFSFetchStatus record + - xfs: fix partially uninitialized structure in xfs_reflink_remap_extent + - ALSA: hda: Release resources at error in delayed probe + - ALSA: hda: Keep the controller initialization even if no codecs found + - ALSA: hda: Explicitly permit using autosuspend if runtime PM is supported + - scsi: target: fix PR IN / READ FULL STATUS for FC + - scsi: target: tcmu: reset_ring should reset TCMU_DEV_BIT_BROKEN + - objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings + - objtool: Support Clang non-section symbols in ORC dump + - xen/xenbus: ensure xenbus_map_ring_valloc() returns proper grant status + - ALSA: hda: call runtime_allow() for all hda controllers + - net: stmmac: socfpga: Allow all RGMII modes + - mac80211: fix channel switch trigger from unknown mesh peer + - arm64: Delete the space separator in __emit_inst + - ext4: use matching invalidatepage in ext4_writepage + - ext4: increase wait time needed before reuse of deleted inode numbers + - ext4: convert BUG_ON's to WARN_ON's in mballoc.c + - blk-mq: Put driver tag in blk_mq_dispatch_rq_list() when no budget + - hwmon: (jc42) Fix name to have no illegal characters + - taprio: do not use BIT() in TCA_TAPRIO_ATTR_FLAG_* definitions + - qed: Fix race condition between scheduling and destroying the slowpath + workqueue + - Crypto: chelsio - Fixes a hang issue during driver registration + - net: use indirect call wrappers for skb_copy_datagram_iter() + - qed: Fix use after free in qed_chain_free + - ext4: check for non-zero journal inum in ext4_calculate_overhead + - ASoC: soc-core: disable route checks for legacy devices + - ASoC: stm32: spdifrx: fix regmap status check + - Linux 5.4.37 + * Focal update: v5.4.36 upstream stable release (LP: #1876361) + - ext4: fix extent_status fragmentation for plain files + - f2fs: fix to avoid memory leakage in f2fs_listxattr + - net, ip_tunnel: fix interface lookup with no key + - [Config] updateconfigs for ARM64_ERRATUM_1542419 + - arm64: errata: Hide CTR_EL0.DIC on systems affected by Neoverse-N1 #1542419 + - arm64: Fake the IminLine size on systems affected by Neoverse-N1 #1542419 + - arm64: compat: Workaround Neoverse-N1 #1542419 for compat user-space + - arm64: Silence clang warning on mismatched value/register sizes + - tools/testing/nvdimm: Fix compilation failure without + CONFIG_DEV_DAX_PMEM_COMPAT + - watchdog: reset last_hw_keepalive time at start + - scsi: lpfc: Fix kasan slab-out-of-bounds error in lpfc_unreg_login + - scsi: lpfc: Fix crash after handling a pci error + - scsi: lpfc: Fix crash in target side cable pulls hitting WAIT_FOR_UNREG + - scsi: libfc: If PRLI rejected, move rport to PLOGI state + - ceph: return ceph_mdsc_do_request() errors from __get_parent() + - ceph: don't skip updating wanted caps when cap is stale + - pwm: rcar: Fix late Runtime PM enablement + - nvme-tcp: fix possible crash in write_zeroes processing + - scsi: iscsi: Report unbind session event when the target has been removed + - tools/test/nvdimm: Fix out of tree build + - ASoC: Intel: atom: Take the drv->lock mutex before calling + sst_send_slot_map() + - nvme: fix deadlock caused by ANA update wrong locking + - drm/amd/display: Update stream adjust in dc_stream_adjust_vmin_vmax + - dma-direct: fix data truncation in dma_direct_get_required_mask() + - kernel/gcov/fs.c: gcov_seq_next() should increase position index + - selftests: kmod: fix handling test numbers above 9 + - ipc/util.c: sysvipc_find_ipc() should increase position index + - kconfig: qconf: Fix a few alignment issues + - lib/raid6/test: fix build on distros whose /bin/sh is not bash + - s390/cio: generate delayed uevent for vfio-ccw subchannels + - s390/cio: avoid duplicated 'ADD' uevents + - loop: Better discard support for block devices + - Revert "powerpc/64: irq_work avoid interrupt when called with hardware irqs + enabled" + - powerpc/pseries: Fix MCE handling on pseries + - nvme: fix compat address handling in several ioctls + - pwm: renesas-tpu: Fix late Runtime PM enablement + - pwm: bcm2835: Dynamically allocate base + - perf/core: Disable page faults when getting phys address + - drm/amd/display: Calculate scaling ratios on every medium/full update + - ASoC: Intel: bytcr_rt5640: Add quirk for MPMAN MPWIN895CL tablet + - ALSA: usb-audio: Add Pioneer DJ DJM-250MK2 quirk + - drm/amd/display: Not doing optimize bandwidth if flip pending. + - cxgb4: fix adapter crash due to wrong MC size + - cxgb4: fix large delays in PTP synchronization + - ipv4: Update fib_select_default to handle nexthop objects + - ipv6: fix restrict IPV6_ADDRFORM operation + - macsec: avoid to set wrong mtu + - macvlan: fix null dereference in macvlan_device_event() + - mlxsw: Fix some IS_ERR() vs NULL bugs + - net: bcmgenet: correct per TX/RX ring statistics + - net/mlx4_en: avoid indirect call in TX completion + - net: netrom: Fix potential nr_neigh refcnt leak in nr_add_node + - net: openvswitch: ovs_ct_exit to be done under ovs_lock + - net: stmmac: dwmac-meson8b: Add missing boundary to RGMII TX clock array + - net/x25: Fix x25_neigh refcnt leak when receiving frame + - sched: etf: do not assume all sockets are full blown + - selftests: Fix suppress test in fib_tests.sh + - tcp: cache line align MAX_TCP_HEADER + - team: fix hang in team_mode_get() + - vrf: Fix IPv6 with qdisc and xfrm + - net: dsa: b53: Lookup VID in ARL searches when VLAN is enabled + - net: dsa: b53: Fix valid setting for MDB entries + - net: dsa: b53: Fix ARL register definitions + - net: dsa: b53: Rework ARL bin logic + - net: dsa: b53: b53_arl_rw_op() needs to select IVL or SVL + - vxlan: use the correct nlattr array in NL_SET_ERR_MSG_ATTR + - geneve: use the correct nlattr array in NL_SET_ERR_MSG_ATTR + - xfrm: Always set XFRM_TRANSFORMED in xfrm{4,6}_output_finish + - vrf: Check skb for XFRM_TRANSFORMED flag + - KEYS: Avoid false positive ENOMEM error on key read + - ALSA: hda: Remove ASUS ROG Zenith from the blacklist + - ALSA: usb-audio: Add static mapping table for ALC1220-VB-based mobos + - ALSA: usb-audio: Add connector notifier delegation + - iio: core: remove extra semi-colon from devm_iio_device_register() macro + - iio: st_sensors: rely on odr mask to know if odr can be set + - iio: adc: stm32-adc: fix sleep in atomic context + - iio: adc: ti-ads8344: properly byte swap value + - iio: xilinx-xadc: Fix ADC-B powerdown + - iio: xilinx-xadc: Fix clearing interrupt when enabling trigger + - iio: xilinx-xadc: Fix sequencer configuration for aux channels in + simultaneous mode + - iio: xilinx-xadc: Make sure not exceed maximum samplerate + - USB: sisusbvga: Change port variable from signed to unsigned + - USB: Add USB_QUIRK_DELAY_CTRL_MSG and USB_QUIRK_DELAY_INIT for Corsair K70 + RGB RAPIDFIRE + - USB: early: Handle AMD's spec-compliant identifiers, too + - USB: core: Fix free-while-in-use bug in the USB S-Glibrary + - USB: hub: Fix handling of connect changes during sleep + - USB: hub: Revert commit bd0e6c9614b9 ("usb: hub: try old enumeration scheme + first for high speed devices") + - tty: serial: owl: add "much needed" clk_prepare_enable() + - vmalloc: fix remap_vmalloc_range() bounds checks + - staging: gasket: Fix incongruency in handling of sysfs entries creation + - coredump: fix null pointer dereference on coredump + - mm/hugetlb: fix a addressing exception caused by huge_pte_offset + - mm/ksm: fix NULL pointer dereference when KSM zero page is enabled + - tools/vm: fix cross-compile build + - ALSA: usx2y: Fix potential NULL dereference + - ALSA: hda/realtek - Fix unexpected init_amp override + - ALSA: hda/realtek - Add new codec supported for ALC245 + - ALSA: hda/hdmi: Add module option to disable audio component binding + - ALSA: usb-audio: Fix usb audio refcnt leak when getting spdif + - ALSA: usb-audio: Filter out unsupported sample rates on Focusrite devices + - tpm/tpm_tis: Free IRQ if probing fails + - tpm: fix wrong return value in tpm_pcr_extend + - tpm: ibmvtpm: retry on H_CLOSED in tpm_ibmvtpm_send() + - KVM: s390: Return last valid slot if approx index is out-of-bounds + - KVM: Check validity of resolved slot when searching memslots + - KVM: VMX: Enable machine check support for 32bit targets + - tty: hvc: fix buffer overflow during hvc_alloc(). + - tty: rocket, avoid OOB access + - usb-storage: Add unusual_devs entry for JMicron JMS566 + - signal: Avoid corrupting si_pid and si_uid in do_notify_parent + - audit: check the length of userspace generated audit records + - ASoC: dapm: fixup dapm kcontrol widget + - mac80211: populate debugfs only after cfg80211 init + - SUNRPC: Fix backchannel RPC soft lockups + - iwlwifi: pcie: actually release queue memory in TVQM + - iwlwifi: mvm: beacon statistics shouldn't go backwards + - iwlwifi: mvm: limit maximum queue appropriately + - iwlwifi: mvm: Do not declare support for ACK Enabled Aggregation + - iwlwifi: mvm: fix inactive TID removal return value usage + - cifs: fix uninitialised lease_key in open_shroot() + - ARM: imx: provide v7_cpu_resume() only on ARM_CPU_SUSPEND=y + - powerpc/setup_64: Set cache-line-size based on cache-block-size + - staging: comedi: dt2815: fix writing hi byte of analog output + - staging: comedi: Fix comedi_device refcnt leak in comedi_open + - vt: don't hardcode the mem allocation upper bound + - vt: don't use kmalloc() for the unicode screen buffer + - staging: vt6656: Don't set RCR_MULTICAST or RCR_BROADCAST by default. + - staging: vt6656: Fix calling conditions of vnt_set_bss_mode + - staging: vt6656: Fix drivers TBTT timing counter. + - staging: vt6656: Fix pairwise key entry save. + - staging: vt6656: Power save stop wake_up_count wrap around. + - cdc-acm: close race betrween suspend() and acm_softint + - cdc-acm: introduce a cool down + - UAS: no use logging any details in case of ENODEV + - UAS: fix deadlock in error handling and PM flushing work + - fpga: dfl: pci: fix return value of cci_pci_sriov_configure + - usb: dwc3: gadget: Fix request completion check + - usb: f_fs: Clear OS Extended descriptor counts to zero in ffs_data_reset() + - usb: typec: tcpm: Ignore CC and vbus changes in PORT_RESET change + - usb: typec: altmode: Fix typec_altmode_get_partner sometimes returning an + invalid pointer + - xhci: Fix handling halted endpoint even if endpoint ring appears empty + - xhci: prevent bus suspend if a roothub port detected a over-current + condition + - xhci: Don't clear hub TT buffer on ep0 protocol stall + - serial: sh-sci: Make sure status register SCxSR is read in correct sequence + - Revert "serial: uartps: Fix uartps_major handling" + - Revert "serial: uartps: Use the same dynamic major number for all ports" + - Revert "serial: uartps: Fix error path when alloc failed" + - Revert "serial: uartps: Do not allow use aliases >= MAX_UART_INSTANCES" + - Revert "serial: uartps: Change uart ID port allocation" + - Revert "serial: uartps: Move Port ID to device data structure" + - Revert "serial: uartps: Register own uart console and driver structures" + - powerpc/kuap: PPC_KUAP_DEBUG should depend on PPC_KUAP + - powerpc/mm: Fix CONFIG_PPC_KUAP_DEBUG on PPC32 + - compat: ARM64: always include asm-generic/compat.h + - Linux 5.4.36 + * Focal update: v5.4.35 upstream stable release (LP: #1875660) + - ext4: use non-movable memory for superblock readahead + - watchdog: sp805: fix restart handler + - xsk: Fix out of boundary write in __xsk_rcv_memcpy + - arm, bpf: Fix bugs with ALU64 {RSH, ARSH} BPF_K shift by 0 + - arm, bpf: Fix offset overflow for BPF_MEM BPF_DW + - objtool: Fix switch table detection in .text.unlikely + - scsi: sg: add sg_remove_request in sg_common_write + - ALSA: hda: Honor PM disablement in PM freeze and thaw_noirq ops + - ARM: dts: imx6: Use gpc for FEC interrupt controller to fix wake on LAN. + - kbuild, btf: Fix dependencies for DEBUG_INFO_BTF + - netfilter: nf_tables: report EOPNOTSUPP on unsupported flags/object type + - irqchip/mbigen: Free msi_desc on device teardown + - ALSA: hda: Don't release card at firmware loading error + - xsk: Add missing check on user supplied headroom size + - of: unittest: kmemleak on changeset destroy + - of: unittest: kmemleak in of_unittest_platform_populate() + - of: unittest: kmemleak in of_unittest_overlay_high_level() + - of: overlay: kmemleak in dup_and_fixup_symbol_prop() + - x86/Hyper-V: Unload vmbus channel in hv panic callback + - x86/Hyper-V: Trigger crash enlightenment only once during system crash. + - x86/Hyper-V: Report crash register data or kmsg before running crash kernel + - x86/Hyper-V: Report crash register data when sysctl_record_panic_msg is not + set + - x86/Hyper-V: Report crash data in die() when panic_on_oops is set + - afs: Fix missing XDR advance in xdr_decode_{AFS,YFS}FSFetchStatus() + - afs: Fix decoding of inline abort codes from version 1 status records + - afs: Fix rename operation status delivery + - afs: Fix afs_d_validate() to set the right directory version + - afs: Fix race between post-modification dir edit and readdir/d_revalidate + - block, bfq: turn put_queue into release_process_ref in + __bfq_bic_change_cgroup + - block, bfq: make reparent_leaf_entity actually work only on leaf entities + - block, bfq: invoke flush_idle_tree after reparent_active_queues in + pd_offline + - rbd: avoid a deadlock on header_rwsem when flushing notifies + - rbd: call rbd_dev_unprobe() after unwatching and flushing notifies + - x86/Hyper-V: Free hv_panic_page when fail to register kmsg dump + - drm/ttm: flush the fence on the bo after we individualize the reservation + object + - clk: Don't cache errors from clk_ops::get_phase() + - clk: at91: usb: continue if clk_hw_round_rate() return zero + - net/mlx5e: Enforce setting of a single FEC mode + - f2fs: fix the panic in do_checkpoint() + - ARM: dts: rockchip: fix vqmmc-supply property name for rk3188-bqedison2qc + - arm64: dts: allwinner: a64: Fix display clock register range + - power: supply: bq27xxx_battery: Silence deferred-probe error + - clk: tegra: Fix Tegra PMC clock out parents + - arm64: tegra: Add PCIe endpoint controllers nodes for Tegra194 + - arm64: tegra: Fix Tegra194 PCIe compatible string + - arm64: dts: clearfog-gt-8k: set gigabit PHY reset deassert delay + - soc: imx: gpc: fix power up sequencing + - dma-coherent: fix integer overflow in the reserved-memory dma allocation + - rtc: 88pm860x: fix possible race condition + - NFS: alloc_nfs_open_context() must use the file cred when available + - NFSv4/pnfs: Return valid stateids in nfs_layout_find_inode_by_stateid() + - NFSv4.2: error out when relink swapfile + - ARM: dts: rockchip: fix lvds-encoder ports subnode for rk3188-bqedison2qc + - KVM: PPC: Book3S HV: Fix H_CEDE return code for nested guests + - f2fs: fix to show norecovery mount option + - phy: uniphier-usb3ss: Add Pro5 support + - NFS: direct.c: Fix memory leak of dreq when nfs_get_lock_context fails + - f2fs: Fix mount failure due to SPO after a successful online resize FS + - f2fs: Add a new CP flag to help fsck fix resize SPO issues + - s390/cpuinfo: fix wrong output when CPU0 is offline + - hibernate: Allow uswsusp to write to swap + - btrfs: add RCU locks around block group initialization + - powerpc/prom_init: Pass the "os-term" message to hypervisor + - powerpc/maple: Fix declaration made after definition + - s390/cpum_sf: Fix wrong page count in error message + - ext4: do not commit super on read-only bdev + - um: ubd: Prevent buffer overrun on command completion + - cifs: Allocate encryption header through kmalloc + - mm/hugetlb: fix build failure with HUGETLB_PAGE but not HUGEBTLBFS + - drm/nouveau/svm: check for SVM initialized before migrating + - drm/nouveau/svm: fix vma range check for migration + - include/linux/swapops.h: correct guards for non_swap_entry() + - percpu_counter: fix a data race at vm_committed_as + - compiler.h: fix error in BUILD_BUG_ON() reporting + - KVM: s390: vsie: Fix possible race when shadowing region 3 tables + - drm/nouveau: workaround runpm fail by disabling PCI power management on + certain intel bridges + - leds: core: Fix warning message when init_data + - x86: ACPI: fix CPU hotplug deadlock + - csky: Fixup cpu speculative execution to IO area + - drm/amdkfd: kfree the wrong pointer + - NFS: Fix memory leaks in nfs_pageio_stop_mirroring() + - csky: Fixup get wrong psr value from phyical reg + - f2fs: fix NULL pointer dereference in f2fs_write_begin() + - ACPICA: Fixes for acpiExec namespace init file + - um: falloc.h needs to be directly included for older libc + - drm/vc4: Fix HDMI mode validation + - iommu/virtio: Fix freeing of incomplete domains + - iommu/vt-d: Fix mm reference leak + - ext2: fix empty body warnings when -Wextra is used + - iommu/vt-d: Silence RCU-list debugging warning in dmar_find_atsr() + - iommu/vt-d: Fix page request descriptor size + - ext2: fix debug reference to ext2_xattr_cache + - sunrpc: Fix gss_unwrap_resp_integ() again + - csky: Fixup init_fpu compile warning with __init + - power: supply: axp288_fuel_gauge: Broaden vendor check for Intel Compute + Sticks. + - libnvdimm: Out of bounds read in __nd_ioctl() + - iommu/amd: Fix the configuration of GCR3 table root pointer + - f2fs: fix to wait all node page writeback + - drm/nouveau/gr/gp107,gp108: implement workaround for HW hanging during init + - net: dsa: bcm_sf2: Fix overflow checks + - dma-debug: fix displaying of dma allocation type + - fbdev: potential information leak in do_fb_ioctl() + - ARM: dts: sunxi: Fix DE2 clocks register range + - iio: si1133: read 24-bit signed integer for measurement + - fbmem: Adjust indentation in fb_prepare_logo and fb_blank + - tty: evh_bytechan: Fix out of bounds accesses + - locktorture: Print ratio of acquisitions, not failures + - mtd: rawnand: free the nand_device object + - mtd: spinand: Explicitly use MTD_OPS_RAW to write the bad block marker to + OOB + - docs: Fix path to MTD command line partition parser + - mtd: lpddr: Fix a double free in probe() + - mtd: phram: fix a double free issue in error path + - KEYS: Don't write out to userspace while holding key semaphore + - bpf: fix buggy r0 retval refinement for tracing helpers + - bpf: Test_verifier, bpf_get_stack return value add <0 + - bpf: Test_progs, add test to catch retval refine error handling + - SAUCE: bpf: Test_progs, fix test_get_stack_rawtp_err.c build + - bpf, test_verifier: switch bpf_get_stack's 0 s> r8 test + - Linux 5.4.35 + * Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW), + REV=0x354 [8086:a0f0] subsystem id [1a56:1651] wireless adapter not found + due to firmware crash (LP: #1874685) + - iwlwifi: pcie: handle QuZ configs with killer NICs as well + * Support DMIC micmute LED on HP platforms (LP: #1876859) + - ALSA: hda/realtek - Introduce polarity for micmute LED GPIO + - ALSA: hda/realtek - Enable micmute LED on and HP system + - ALSA: hda/realtek - Add LED class support for micmute LED + - ALSA: hda/realtek - Fix unused variable warning w/o + CONFIG_LEDS_TRIGGER_AUDIO + - ASoC: SOF: Update correct LED status at the first time usage of + update_mute_led() + * linux: riscv: set max_pfn to the PFN of the last page (LP: #1876885) + - riscv: set max_pfn to the PFN of the last page + * Dell XPS 13 9300 mirror mode doesn't work sometimes with WD19TB + (LP: #1877013) + - drm/i915/perf: Do not clear pollin for small user read buffers + * [UBUNTU 20.04] s390x/pci: do not allow to create more pci functions than + configured via CONFIG_PCI_NR_FUNCTIONS (LP: #1874057) + - s390/pci: Fix zpci_alloc_domain() over allocation + * [Ubuntu 20.04] net/mlx5e: Fix endianness handling in pedit mask + (LP: #1872726) + - net/mlx5e: Fix endianness handling in pedit mask + * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after + upgrade to 20.04 (LP: #1875665) + - [Config] Turn off CONFIG_RT_GROUP_SCHED everywhere + * ceph -- Unable to mount ceph volume on s390x (LP: #1875863) + - ceph: fix endianness bug when handling MDS session feature bits + * Do not treat unresolved test case in ftrace from ubuntu_kernel_selftests as + failure (LP: #1877958) + - ftrace/selftest: make unresolved cases cause failure if --fail-unresolved + set + * Add support for Ambiq micro AM1805 RTC chip (LP: #1876667) + - SAUCE: rtc: add am-1805 RTC driver + * alsa/sof: kernel oops on the machine without Intel hdmi audio codec (a + regression in the asoc machine driver) (LP: #1874359) + - SAUCE: ASoC: intel/skl/hda - fix oops on systems without i915 audio codec + * 'Elan touchpad' not detected on 'Lenovo ThinkBook 15 IIL' (LP: #1861610) + - SAUCE: Input: elan_i2c - add more hardware ID for Lenovo laptop + + [ Ubuntu: 5.4.0-33.37 ] + + * focal/linux: 5.4.0-33.37 -proposed tracker (LP: #1879926) + * Docker registry doesn't stay up and keeps restarting (LP: #1879690) + - Revert "UBUNTU: SAUCE: overlayfs: fix shitfs special-casing" + - Revert "UBUNTU: SAUCE: overlayfs: use shiftfs hacks only with shiftfs as + underlay" + + -- Kleber Sacilotto de Souza Tue, 26 May 2020 16:00:59 +0200 + +linux-oracle (5.4.0-1011.11) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1011.11 -proposed tracker (LP: #1878001) + + [ Ubuntu: 5.4.0-31.35 ] + + * focal/linux: 5.4.0-31.35 -proposed tracker (LP: #1877253) + * Intermittent display blackouts on event (LP: #1875254) + - drm/i915: Limit audio CDCLK>=2*BCLK constraint back to GLK only + * Unable to handle kernel pointer dereference in virtual kernel address space + on Eoan (LP: #1876645) + - SAUCE: overlayfs: fix shitfs special-casing + + -- Ian May Mon, 11 May 2020 08:56:57 -0500 + +linux-oracle (5.4.0-1010.10) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1010.10 -proposed tracker (LP: #1875383) + + * bionic/oracle-5.3: Move bnxt_en driver from -modules-extras to -modules + (LP: #1874553) + - [Config] Move bnxt_en driver from modules-extra to modules + + * Packaging resync (LP: #1786013) + - [Packaging] add libcap-dev dependency + + [ Ubuntu: 5.4.0-30.34 ] + + * focal/linux: 5.4.0-30.34 -proposed tracker (LP: #1875385) + * ubuntu/focal64 fails to mount Vagrant shared folders (LP: #1873506) + - [Packaging] Move virtualbox modules to linux-modules + - [Packaging] Remove vbox and zfs modules from generic.inclusion-list + * linux-image-5.0.0-35-generic breaks checkpointing of container + (LP: #1857257) + - SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay + * shiftfs: broken shiftfs nesting (LP: #1872094) + - SAUCE: shiftfs: record correct creator credentials + * Add debian/rules targets to compile/run kernel selftests (LP: #1874286) + - [Packaging] add support to compile/run selftests + * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757) + - SAUCE: shiftfs: fix dentry revalidation + * LIO hanging in iscsit_free_session and iscsit_stop_session (LP: #1871688) + - scsi: target: iscsi: calling iscsit_stop_session() inside + iscsit_close_session() has no effect + * [ICL] TC port in legacy/static mode can't be detected due TCCOLD + (LP: #1868936) + - SAUCE: drm/i915: Align power domain names with port names + - SAUCE: drm/i915/display: Move out code to return the digital_port of the aux + ch + - SAUCE: drm/i915/display: Add intel_legacy_aux_to_power_domain() + - SAUCE: drm/i915/display: Split hsw_power_well_enable() into two + - SAUCE: drm/i915/tc/icl: Implement TC cold sequences + - SAUCE: drm/i915/tc: Skip ref held check for TC legacy aux power wells + - SAUCE: drm/i915/tc/tgl: Implement TC cold sequences + - SAUCE: drm/i915/tc: Catch TC users accessing FIA registers without enable + aux + - SAUCE: drm/i915/tc: Do not warn when aux power well of static TC ports + timeout + * alsa/sof: external mic can't be deteced on Lenovo and HP laptops + (LP: #1872569) + - SAUCE: ASoC: intel/skl/hda - set autosuspend timeout for hda codecs + * amdgpu kernel errors in Linux 5.4 (LP: #1871248) + - drm/amd/display: Stop if retimer is not available + * Focal update: v5.4.34 upstream stable release (LP: #1874111) + - amd-xgbe: Use __napi_schedule() in BH context + - hsr: check protocol version in hsr_newlink() + - l2tp: Allow management of tunnels and session in user namespace + - net: dsa: mt7530: fix tagged frames pass-through in VLAN-unaware mode + - net: ipv4: devinet: Fix crash when add/del multicast IP with autojoin + - net: ipv6: do not consider routes via gateways for anycast address check + - net: phy: micrel: use genphy_read_status for KSZ9131 + - net: qrtr: send msgs from local of same id as broadcast + - net: revert default NAPI poll timeout to 2 jiffies + - net: tun: record RX queue in skb before do_xdp_generic() + - net: dsa: mt7530: move mt7623 settings out off the mt7530 + - net: ethernet: mediatek: move mt7623 settings out off the mt7530 + - net/mlx5: Fix frequent ioread PCI access during recovery + - net/mlx5e: Add missing release firmware call + - net/mlx5e: Fix nest_level for vlan pop action + - net/mlx5e: Fix pfnum in devlink port attribute + - net: stmmac: dwmac-sunxi: Provide TX and RX fifo sizes + - ovl: fix value of i_ino for lower hardlink corner case + - scsi: ufs: Fix ufshcd_hold() caused scheduling while atomic + - platform/chrome: cros_ec_rpmsg: Fix race with host event + - jbd2: improve comments about freeing data buffers whose page mapping is NULL + - acpi/nfit: improve bounds checking for 'func' + - perf report: Fix no branch type statistics report issue + - pwm: pca9685: Fix PWM/GPIO inter-operation + - ext4: fix incorrect group count in ext4_fill_super error message + - ext4: fix incorrect inodes per group in error message + - clk: at91: sam9x60: fix usb clock parents + - clk: at91: usb: use proper usbs_mask + - ARM: dts: imx7-colibri: fix muxing of usbc_det pin + - arm64: dts: librem5-devkit: add a vbus supply to usb0 + - usb: dwc3: gadget: Don't clear flags before transfer ended + - ASoC: Intel: mrfld: fix incorrect check on p->sink + - ASoC: Intel: mrfld: return error codes when an error occurs + - ALSA: hda/realtek - Enable the headset mic on Asus FX505DT + - ALSA: usb-audio: Filter error from connector kctl ops, too + - ALSA: usb-audio: Don't override ignore_ctl_error value from the map + - ALSA: usb-audio: Don't create jack controls for PCM terminals + - ALSA: usb-audio: Check mapping at creating connector controls, too + - arm64: vdso: don't free unallocated pages + - keys: Fix proc_keys_next to increase position index + - tracing: Fix the race between registering 'snapshot' event trigger and + triggering 'snapshot' operation + - btrfs: check commit root generation in should_ignore_root + - nl80211: fix NL80211_ATTR_FTM_RESPONDER policy + - mac80211: fix race in ieee80211_register_hw() + - mac80211_hwsim: Use kstrndup() in place of kasprintf() + - net/mlx5e: Encapsulate updating netdev queues into a function + - net/mlx5e: Rename hw_modify to preactivate + - net/mlx5e: Use preactivate hook to set the indirection table + - drm/amd/powerplay: force the trim of the mclk dpm_levels if OD is enabled + - drm/amdgpu: fix the hw hang during perform system reboot and reset + - i2c: designware: platdrv: Remove DPM_FLAG_SMART_SUSPEND flag on BYT and CHT + - ext4: do not zeroout extents beyond i_disksize + - irqchip/ti-sci-inta: Fix processing of masked irqs + - x86/resctrl: Preserve CDP enable over CPU hotplug + - x86/resctrl: Fix invalid attempt at removing the default resource group + - scsi: target: remove boilerplate code + - scsi: target: fix hang when multiple threads try to destroy the same iscsi + session + - x86/microcode/AMD: Increase microcode PATCH_MAX_SIZE + - Linux 5.4.34 + * Focal update: v5.4.33 upstream stable release (LP: #1873481) + - ARM: dts: sun8i-a83t-tbs-a711: HM5065 doesn't like such a high voltage + - bus: sunxi-rsb: Return correct data when mixing 16-bit and 8-bit reads + - ARM: dts: Fix dm814x Ethernet by changing to use rgmii-id mode + - bpf: Fix deadlock with rq_lock in bpf_send_signal() + - iwlwifi: mvm: Fix rate scale NSS configuration + - Input: tm2-touchkey - add support for Coreriver TC360 variant + - soc: fsl: dpio: register dpio irq handlers after dpio create + - rxrpc: Abstract out the calculation of whether there's Tx space + - rxrpc: Fix call interruptibility handling + - net: stmmac: platform: Fix misleading interrupt error msg + - net: vxge: fix wrong __VA_ARGS__ usage + - hinic: fix a bug of waitting for IO stopped + - hinic: fix the bug of clearing event queue + - hinic: fix out-of-order excution in arm cpu + - hinic: fix wrong para of wait_for_completion_timeout + - hinic: fix wrong value of MIN_SKB_LEN + - selftests/net: add definition for SOL_DCCP to fix compilation errors for old + libc + - cxgb4/ptp: pass the sign of offset delta in FW CMD + - drm/scheduler: fix rare NULL ptr race + - cfg80211: Do not warn on same channel at the end of CSA + - qlcnic: Fix bad kzalloc null test + - i2c: st: fix missing struct parameter description + - i2c: pca-platform: Use platform_irq_get_optional + - media: rc: add keymap for Videostrong KII Pro + - cpufreq: imx6q: Fixes unwanted cpu overclocking on i.MX6ULL + - staging: wilc1000: avoid double unlocking of 'wilc->hif_cs' mutex + - media: venus: hfi_parser: Ignore HEVC encoding for V1 + - firmware: arm_sdei: fix double-lock on hibernate with shared events + - null_blk: Fix the null_add_dev() error path + - null_blk: Handle null_add_dev() failures properly + - null_blk: fix spurious IO errors after failed past-wp access + - media: imx: imx7_mipi_csis: Power off the source when stopping streaming + - media: imx: imx7-media-csi: Fix video field handling + - xhci: bail out early if driver can't accress host in resume + - x86: Don't let pgprot_modify() change the page encryption bit + - dma-mapping: Fix dma_pgprot() for unencrypted coherent pages + - block: keep bdi->io_pages in sync with max_sectors_kb for stacked devices + - debugfs: Check module state before warning in {full/open}_proxy_open() + - irqchip/versatile-fpga: Handle chained IRQs properly + - time/sched_clock: Expire timer in hardirq context + - media: allegro: fix type of gop_length in channel_create message + - sched: Avoid scale real weight down to zero + - selftests/x86/ptrace_syscall_32: Fix no-vDSO segfault + - PCI/switchtec: Fix init_completion race condition with poll_wait() + - block, bfq: move forward the getting of an extra ref in bfq_bfqq_move + - media: i2c: video-i2c: fix build errors due to 'imply hwmon' + - libata: Remove extra scsi_host_put() in ata_scsi_add_hosts() + - pstore/platform: fix potential mem leak if pstore_init_fs failed + - gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty + - gfs2: Don't demote a glock until its revokes are written + - cpufreq: imx6q: fix error handling + - x86/boot: Use unsigned comparison for addresses + - efi/x86: Ignore the memory attributes table on i386 + - genirq/irqdomain: Check pointer in irq_domain_alloc_irqs_hierarchy() + - block: Fix use-after-free issue accessing struct io_cq + - media: i2c: ov5695: Fix power on and off sequences + - usb: dwc3: core: add support for disabling SS instances in park mode + - irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency + - md: check arrays is suspended in mddev_detach before call quiesce operations + - firmware: fix a double abort case with fw_load_sysfs_fallback + - spi: spi-fsl-dspi: Replace interruptible wait queue with a simple completion + - locking/lockdep: Avoid recursion in lockdep_count_{for,back}ward_deps() + - block, bfq: fix use-after-free in bfq_idle_slice_timer_body + - btrfs: qgroup: ensure qgroup_rescan_running is only set when the worker is + at least queued + - btrfs: remove a BUG_ON() from merge_reloc_roots() + - btrfs: restart relocate_tree_blocks properly + - btrfs: track reloc roots based on their commit root bytenr + - ASoC: fix regwmask + - ASoC: dapm: connect virtual mux with default value + - ASoC: dpcm: allow start or stop during pause for backend + - ASoC: topology: use name_prefix for new kcontrol + - usb: gadget: f_fs: Fix use after free issue as part of queue failure + - usb: gadget: composite: Inform controller driver of self-powered + - ALSA: usb-audio: Add mixer workaround for TRX40 and co + - ALSA: hda: Add driver blacklist + - ALSA: hda: Fix potential access overflow in beep helper + - ALSA: ice1724: Fix invalid access for enumerated ctl items + - ALSA: pcm: oss: Fix regression by buffer overflow fix + - ALSA: hda/realtek - a fake key event is triggered by running shutup + - ALSA: doc: Document PC Beep Hidden Register on Realtek ALC256 + - ALSA: hda/realtek - Set principled PC Beep configuration for ALC256 + - ALSA: hda/realtek - Remove now-unnecessary XPS 13 headphone noise fixups + - ALSA: hda/realtek - Add quirk for Lenovo Carbon X1 8th gen + - ALSA: hda/realtek - Add quirk for MSI GL63 + - media: venus: firmware: Ignore secure call error on first resume + - media: hantro: Read be32 words starting at every fourth byte + - media: ti-vpe: cal: fix disable_irqs to only the intended target + - media: ti-vpe: cal: fix a kernel oops when unloading module + - seccomp: Add missing compat_ioctl for notify + - acpi/x86: ignore unspecified bit positions in the ACPI global lock field + - ACPICA: Allow acpi_any_gpe_status_set() to skip one GPE + - ACPI: PM: s2idle: Refine active GPEs check + - thermal: devfreq_cooling: inline all stubs for CONFIG_DEVFREQ_THERMAL=n + - nvmet-tcp: fix maxh2cdata icresp parameter + - efi/x86: Add TPM related EFI tables to unencrypted mapping checks + - PCI: pciehp: Fix indefinite wait on sysfs requests + - PCI/ASPM: Clear the correct bits when enabling L1 substates + - PCI: Add boot interrupt quirk mechanism for Xeon chipsets + - PCI: qcom: Fix the fixup of PCI_VENDOR_ID_QCOM + - PCI: endpoint: Fix for concurrent memory allocation in OB address region + - sched/fair: Fix enqueue_task_fair warning + - tpm: Don't make log failures fatal + - tpm: tpm1_bios_measurements_next should increase position index + - tpm: tpm2_bios_measurements_next should increase position index + - cpu/hotplug: Ignore pm_wakeup_pending() for disable_nonboot_cpus() + - genirq/debugfs: Add missing sanity checks to interrupt injection + - irqchip/versatile-fpga: Apply clear-mask earlier + - io_uring: remove bogus RLIMIT_NOFILE check in file registration + - pstore: pstore_ftrace_seq_next should increase position index + - MIPS/tlbex: Fix LDDIR usage in setup_pw() for Loongson-3 + - MIPS: OCTEON: irq: Fix potential NULL pointer dereference + - PM / Domains: Allow no domain-idle-states DT property in genpd when parsing + - PM: sleep: wakeup: Skip wakeup_source_sysfs_remove() if device is not there + - ath9k: Handle txpower changes even when TPC is disabled + - signal: Extend exec_id to 64bits + - x86/tsc_msr: Use named struct initializers + - x86/tsc_msr: Fix MSR_FSB_FREQ mask for Cherry Trail devices + - x86/tsc_msr: Make MSR derived TSC frequency more accurate + - x86/entry/32: Add missing ASM_CLAC to general_protection entry + - platform/x86: asus-wmi: Support laptops where the first battery is named + BATT + - KVM: nVMX: Properly handle userspace interrupt window request + - KVM: s390: vsie: Fix region 1 ASCE sanity shadow address checks + - KVM: s390: vsie: Fix delivery of addressing exceptions + - KVM: x86: Allocate new rmap and large page tracking when moving memslot + - KVM: VMX: Always VMCLEAR in-use VMCSes during crash with kexec support + - KVM: x86: Gracefully handle __vmalloc() failure during VM allocation + - KVM: VMX: Add a trampoline to fix VMREAD error handling + - KVM: VMX: fix crash cleanup when KVM wasn't used + - smb3: fix performance regression with setting mtime + - CIFS: Fix bug which the return value by asynchronous read is error + - mtd: spinand: Stop using spinand->oobbuf for buffering bad block markers + - mtd: spinand: Do not erase the block before writing a bad block marker + - btrfs: Don't submit any btree write bio if the fs has errors + - Btrfs: fix crash during unmount due to race with delayed inode workers + - btrfs: reloc: clean dirty subvols if we fail to start a transaction + - btrfs: set update the uuid generation as soon as possible + - btrfs: drop block from cache on error in relocation + - btrfs: fix missing file extent item for hole after ranged fsync + - btrfs: unset reloc control if we fail to recover + - btrfs: fix missing semaphore unlock in btrfs_sync_file + - btrfs: use nofs allocations for running delayed items + - remoteproc: qcom_q6v5_mss: Don't reassign mpss region on shutdown + - remoteproc: qcom_q6v5_mss: Reload the mba region on coredump + - remoteproc: Fix NULL pointer dereference in rproc_virtio_notify + - crypto: rng - Fix a refcounting bug in crypto_rng_reset() + - crypto: mxs-dcp - fix scatterlist linearization for hash + - erofs: correct the remaining shrink objects + - io_uring: honor original task RLIMIT_FSIZE + - mmc: sdhci-of-esdhc: fix esdhc_reset() for different controller versions + - powerpc/pseries: Drop pointless static qualifier in vpa_debugfs_init() + - tools: gpio: Fix out-of-tree build regression + - net: qualcomm: rmnet: Allow configuration updates to existing devices + - arm64: dts: allwinner: h6: Fix PMU compatible + - sched/core: Remove duplicate assignment in sched_tick_remote() + - arm64: dts: allwinner: h5: Fix PMU compatible + - mm, memcg: do not high throttle allocators based on wraparound + - dm writecache: add cond_resched to avoid CPU hangs + - dm integrity: fix a crash with unusually large tag size + - dm verity fec: fix memory leak in verity_fec_dtr + - dm clone: Add overflow check for number of regions + - dm clone metadata: Fix return type of dm_clone_nr_of_hydrated_regions() + - XArray: Fix xas_pause for large multi-index entries + - xarray: Fix early termination of xas_for_each_marked + - crypto: caam/qi2 - fix chacha20 data size error + - crypto: caam - update xts sector size for large input length + - crypto: ccree - protect against empty or NULL scatterlists + - crypto: ccree - only try to map auth tag if needed + - crypto: ccree - dec auth tag size from cryptlen map + - scsi: zfcp: fix missing erp_lock in port recovery trigger for point-to-point + - scsi: ufs: fix Auto-Hibern8 error detection + - ARM: dts: exynos: Fix polarity of the LCD SPI bus on UniversalC210 board + - arm64: dts: ti: k3-am65: Add clocks to dwc3 nodes + - arm64: armv8_deprecated: Fix undef_hook mask for thumb setend + - selftests: vm: drop dependencies on page flags from mlock2 tests + - selftests/vm: fix map_hugetlb length used for testing read and write + - selftests/powerpc: Add tlbie_test in .gitignore + - vfio: platform: Switch to platform_get_irq_optional() + - drm/i915/gem: Flush all the reloc_gpu batch + - drm/etnaviv: rework perfmon query infrastructure + - drm: Remove PageReserved manipulation from drm_pci_alloc + - drm/amdgpu/powerplay: using the FCLK DPM table to set the MCLK + - drm/amdgpu: unify fw_write_wait for new gfx9 asics + - powerpc/pseries: Avoid NULL pointer dereference when drmem is unavailable + - nfsd: fsnotify on rmdir under nfsd/clients/ + - NFS: Fix use-after-free issues in nfs_pageio_add_request() + - NFS: Fix a page leak in nfs_destroy_unlinked_subrequests() + - ext4: fix a data race at inode->i_blocks + - fs/filesystems.c: downgrade user-reachable WARN_ONCE() to pr_warn_once() + - ocfs2: no need try to truncate file beyond i_size + - perf tools: Support Python 3.8+ in Makefile + - s390/diag: fix display of diagnose call statistics + - Input: i8042 - add Acer Aspire 5738z to nomux list + - ftrace/kprobe: Show the maxactive number on kprobe_events + - clk: ingenic/jz4770: Exit with error if CGU init failed + - clk: ingenic/TCU: Fix round_rate returning error + - kmod: make request_module() return an error when autoloading is disabled + - cpufreq: powernv: Fix use-after-free + - hfsplus: fix crash and filesystem corruption when deleting files + - ipmi: fix hung processes in __get_guid() + - xen/blkfront: fix memory allocation flags in blkfront_setup_indirect() + - powerpc/64/tm: Don't let userspace set regs->trap via sigreturn + - powerpc/fsl_booke: Avoid creating duplicate tlb1 entry + - powerpc/hash64/devmap: Use H_PAGE_THP_HUGE when setting up huge devmap PTE + entries + - powerpc/xive: Use XIVE_BAD_IRQ instead of zero to catch non configured IPIs + - powerpc/64: Setup a paca before parsing device tree etc. + - powerpc/xive: Fix xmon support on the PowerNV platform + - powerpc/kprobes: Ignore traps that happened in real mode + - powerpc/64: Prevent stack protection in early boot + - scsi: mpt3sas: Fix kernel panic observed on soft HBA unplug + - powerpc: Make setjmp/longjmp signature standard + - arm64: Always force a branch protection mode when the compiler has one + - dm zoned: remove duplicate nr_rnd_zones increase in dmz_init_zone() + - dm clone: replace spin_lock_irqsave with spin_lock_irq + - dm clone: Fix handling of partial region discards + - dm clone: Add missing casts to prevent overflows and data corruption + - Revert "drm/dp_mst: Remove VCPI while disabling topology mgr" + - drm/dp_mst: Fix clearing payload state on topology disable + - drm/amdgpu: fix gfx hang during suspend with video playback (v2) + - drm/i915/icl+: Don't enable DDI IO power on a TypeC port in TBT mode + - powerpc/kasan: Fix kasan_remap_early_shadow_ro() + - mmc: sdhci: Convert sdhci_set_timeout_irq() to non-static + - mmc: sdhci: Refactor sdhci_set_timeout() + - bpf: Fix tnum constraints for 32-bit comparisons + - mfd: dln2: Fix sanity checking for endpoints + - efi/x86: Fix the deletion of variables in mixed mode + - ASoC: stm32: sai: Add missing cleanup + - Linux 5.4.33 + - SUNRPC: fix krb5p mount to provide large enough buffer in rq_rcvsize + * Panic on suspend/resume Kernel panic - not syncing: stack-protector: Kernel + stack is corrupted in: sata_pmp_eh_recover+0xa2b/0xa40 (LP: #1821434) // + Focal update: v5.4.33 upstream stable release (LP: #1873481) + - libata: Return correct status in sata_pmp_eh_recover_pm() when + ATA_DFLAG_DETACH is set + * Focal update: v5.4.32 upstream stable release (LP: #1873292) + - cxgb4: fix MPS index overwrite when setting MAC address + - ipv6: don't auto-add link-local address to lag ports + - net: dsa: bcm_sf2: Do not register slave MDIO bus with OF + - net: dsa: bcm_sf2: Ensure correct sub-node is parsed + - net: dsa: mt7530: fix null pointer dereferencing in port5 setup + - net: phy: micrel: kszphy_resume(): add delay after genphy_resume() before + accessing PHY registers + - net_sched: add a temporary refcnt for struct tcindex_data + - net_sched: fix a missing refcnt in tcindex_init() + - net: stmmac: dwmac1000: fix out-of-bounds mac address reg setting + - tun: Don't put_page() for all negative return values from XDP program + - mlxsw: spectrum_flower: Do not stop at FLOW_ACTION_VLAN_MANGLE + - r8169: change back SG and TSO to be disabled by default + - s390: prevent leaking kernel address in BEAR + - random: always use batched entropy for get_random_u{32,64} + - usb: dwc3: gadget: Wrap around when skip TRBs + - uapi: rename ext2_swab() to swab() and share globally in swab.h + - slub: improve bit diffusion for freelist ptr obfuscation + - tools/accounting/getdelays.c: fix netlink attribute length + - hwrng: imx-rngc - fix an error path + - ACPI: PM: Add acpi_[un]register_wakeup_handler() + - platform/x86: intel_int0002_vgpio: Use acpi_register_wakeup_handler() + - ASoC: jz4740-i2s: Fix divider written at incorrect offset in register + - IB/hfi1: Call kobject_put() when kobject_init_and_add() fails + - IB/hfi1: Fix memory leaks in sysfs registration and unregistration + - IB/mlx5: Replace tunnel mpls capability bits for tunnel_offloads + - ARM: imx: Enable ARM_ERRATA_814220 for i.MX6UL and i.MX7D + - ARM: imx: only select ARM_ERRATA_814220 for ARMv7-A + - ceph: remove the extra slashes in the server path + - ceph: canonicalize server path in place + - include/uapi/linux/swab.h: fix userspace breakage, use __BITS_PER_LONG for + swap + - RDMA/ucma: Put a lock around every call to the rdma_cm layer + - RDMA/cma: Teach lockdep about the order of rtnl and lock + - RDMA/siw: Fix passive connection establishment + - Bluetooth: RFCOMM: fix ODEBUG bug in rfcomm_dev_ioctl + - RDMA/cm: Update num_paths in cma_resolve_iboe_route error flow + - blk-mq: Keep set->nr_hw_queues and set->map[].nr_queues in sync + - fbcon: fix null-ptr-deref in fbcon_switch + - iommu/vt-d: Allow devices with RMRRs to use identity domain + - Linux 5.4.32 + * Focal update: v5.4.31 upstream stable release (LP: #1871651) + - nvme-rdma: Avoid double freeing of async event data + - kconfig: introduce m32-flag and m64-flag + - drm/amd/display: Add link_rate quirk for Apple 15" MBP 2017 + - drm/bochs: downgrade pci_request_region failure from error to warning + - initramfs: restore default compression behavior + - drm/amdgpu: fix typo for vcn1 idle check + - [Packaging] add libcap-dev dependency + - tools/power turbostat: Fix gcc build warnings + - tools/power turbostat: Fix missing SYS_LPI counter on some Chromebooks + - tools/power turbostat: Fix 32-bit capabilities warning + - net/mlx5e: kTLS, Fix TCP seq off-by-1 issue in TX resync flow + - XArray: Fix xa_find_next for large multi-index entries + - padata: fix uninitialized return value in padata_replace() + - brcmfmac: abort and release host after error + - misc: rtsx: set correct pcr_ops for rts522A + - misc: pci_endpoint_test: Fix to support > 10 pci-endpoint-test devices + - misc: pci_endpoint_test: Avoid using module parameter to determine irqtype + - PCI: sysfs: Revert "rescan" file renames + - coresight: do not use the BIT() macro in the UAPI header + - mei: me: add cedar fork device ids + - nvmem: check for NULL reg_read and reg_write before dereferencing + - extcon: axp288: Add wakeup support + - power: supply: axp288_charger: Add special handling for HP Pavilion x2 10 + - Revert "dm: always call blk_queue_split() in dm_process_bio()" + - ALSA: hda/ca0132 - Add Recon3Di quirk to handle integrated sound on EVGA X99 + Classified motherboard + - soc: mediatek: knows_txdone needs to be set in Mediatek CMDQ helper + - net/mlx5e: kTLS, Fix wrong value in record tracker enum + - iwlwifi: consider HE capability when setting LDPC + - iwlwifi: yoyo: don't add TLV offset when reading FIFOs + - iwlwifi: dbg: don't abort if sending DBGC_SUSPEND_RESUME fails + - rxrpc: Fix sendmsg(MSG_WAITALL) handling + - IB/hfi1: Ensure pq is not left on waitlist + - tcp: fix TFO SYNACK undo to avoid double-timestamp-undo + - watchdog: iTCO_wdt: Export vendorsupport + - watchdog: iTCO_wdt: Make ICH_RES_IO_SMI optional + - i2c: i801: Do not add ICH_RES_IO_SMI for the iTCO_wdt device + - net: Fix Tx hash bound checking + - padata: always acquire cpu_hotplug_lock before pinst->lock + - mm: mempolicy: require at least one nodeid for MPOL_PREFERRED + - Linux 5.4.31 + * Add hw timestamps to received skbs in peak_canfd (LP: #1874124) + - can: peak_canfd: provide hw timestamps in rx skbs + * kselftest: seccomp kill_after_ptrace() timeout (LP: #1872047) + - SAUCE: kselftest/runner: allow to properly deliver signals to tests + + [ Ubuntu: 5.4.0-29.33 ] + + * focal/linux: 5.4.0-29.33 -proposed tracker (LP: #1875858) + * Packaging resync (LP: #1786013) + - update dkms package versions + * Add signed modules for the 435 NVIDIA driver (LP: #1875888) + - [Packaging] NVIDIA -- add signed modules for the 435 NVIDIA driver + * built-using constraints preventing uploads (LP: #1875601) + - temporarily drop Built-Using data + + [ Ubuntu: 5.4.0-28.32 ] + + * CVE-2020-11884 + - SAUCE: s390/mm: fix page table upgrade vs 2ndary address mode accesses + + [ Ubuntu: 5.4.0-26.30 ] + + * focal/linux: 5.4.0-26.30 -proposed tracker (LP: #1873882) + * Packaging resync (LP: #1786013) + - update dkms package versions + * swap storms kills interactive use (LP: #1861359) + - SAUCE: drm/i915: prevent direct writeback from the shrinker + * 5.4.0-24.28 does not seem to apply rtprio, whereas -21 does. (LP: #1873315) + - [Config] lowlatency: turn off RT_GROUP_SCHED + * [RTL810xE] No ethernet connection (LP: #1871182) + - net: phy: realtek: fix handling of RTL8105e-integrated PHY + + [ Ubuntu: 5.4.0-25.29 ] + + * focal/linux: 5.4.0-25.29 -proposed tracker (LP: #1873459) + * [TGL] VMD support in TGL (LP: #1855954) + - PCI: vmd: Add bus 224-255 restriction decode + - PCI: vmd: Add device id for VMD device 8086:9A0B + * Can not see the storage with Intel RAID On mode enabled on Intel Comet Lake + (LP: #1871812) + - ahci: Add Intel Comet Lake PCH RAID PCI ID + + -- Stefan Bader Tue, 05 May 2020 17:10:19 +0200 + +linux-oracle (5.4.0-1009.9) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1009.9 -proposed tracker (LP: #1871937) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to 5.4.0-24.28 + - [Config] CONFIG_RT_GROUP_SCHED=y + + [ Ubuntu: 5.4.0-24.28 ] + + * focal/linux: 5.4.0-24.28 -proposed tracker (LP: #1871939) + * getitimer returns it_value=0 erroneously (LP: #1349028) + - [Config] CONTEXT_TRACKING_FORCE policy should be unset + * 12d1:1038 Dual-Role OTG device on non-HNP port - unable to enumerate USB + device on port 1 (LP: #1047527) + - [Config] USB_OTG_FSM policy not needed + * Add DCPD backlight support for HP CML system (LP: #1871589) + - SAUCE: drm/i915: Force DPCD backlight mode for HP CML 2020 system + * Backlight brightness cannot be adjusted using keys (LP: #1860303) + - SAUCE drm/i915: Force DPCD backlight mode for HP Spectre x360 Convertible + 13t-aw100 + * CVE-2020-11494 + - slcan: Don't transmit uninitialized stack data in padding + * Ubuntu Kernel Support for OpenPOWER NV Secure & Trusted Boot (LP: #1866909) + - powerpc: Detect the secure boot mode of the system + - powerpc/ima: Add support to initialize ima policy rules + - powerpc: Detect the trusted boot state of the system + - powerpc/ima: Define trusted boot policy + - ima: Make process_buffer_measurement() generic + - certs: Add wrapper function to check blacklisted binary hash + - ima: Check against blacklisted hashes for files with modsig + - powerpc/ima: Update ima arch policy to check for blacklist + - powerpc/ima: Indicate kernel modules appended signatures are enforced + - powerpc/powernv: Add OPAL API interface to access secure variable + - powerpc: expose secure variables to userspace via sysfs + - x86/efi: move common keyring handler functions to new file + - powerpc: Load firmware trusted keys/hashes into kernel keyring + - x86/efi: remove unused variables + * [roce-0227]sync mainline kernel 5.6rc3 roce patchset into ubuntu HWE kernel + branch (LP: #1864950) + - RDMA/hns: Cleanups of magic numbers + - RDMA/hns: Optimize eqe buffer allocation flow + - RDMA/hns: Add the workqueue framework for flush cqe handler + - RDMA/hns: Delayed flush cqe process with workqueue + - RDMA/hns: fix spelling mistake: "attatch" -> "attach" + - RDMA/hns: Initialize all fields of doorbells to zero + - RDMA/hns: Treat revision HIP08_A as a special case + - RDMA/hns: Use flush framework for the case in aeq + - RDMA/hns: Stop doorbell update while qp state error + - RDMA/hns: Optimize qp destroy flow + - RDMA/hns: Optimize qp context create and destroy flow + - RDMA/hns: Optimize qp number assign flow + - RDMA/hns: Optimize qp buffer allocation flow + - RDMA/hns: Optimize qp param setup flow + - RDMA/hns: Optimize kernel qp wrid allocation flow + - RDMA/hns: Optimize qp doorbell allocation flow + - RDMA/hns: Check if depth of qp is 0 before configure + * [hns3-0316]sync mainline kernel 5.6rc4 hns3 patchset into ubuntu HWE kernel + branch (LP: #1867586) + - net: hns3: modify an unsuitable print when setting unknown duplex to fibre + - net: hns3: add enabled TC numbers and DWRR weight info in debugfs + - net: hns3: add support for dump MAC ID and loopback status in debugfs + - net: hns3: add missing help info for QS shaper in debugfs + - net: hns3: fix some mixed type assignment + - net: hns3: rename macro HCLGE_MAX_NCL_CONFIG_LENGTH + - net: hns3: remove an unnecessary resetting check in + hclge_handle_hw_ras_error() + - net: hns3: delete some reduandant code + - net: hns3: add a check before PF inform VF to reset + - net: hns3: print out status register when VF receives unknown source + interrupt + - net: hns3: print out command code when dump fails in debugfs + - net: hns3: synchronize some print relating to reset issue + - net: hns3: delete unnecessary logs after kzalloc fails + * [SRU][F/U/OEM-5.6] UBUNTU: SAUCE: Fix amdgpu hang during acpi event + (LP: #1871316) + - SAUCE: drm/amdgpu: Fix oops when pp_funcs is unset in ACPI event + * alsa: make the dmic detection align to the mainline kernel-5.6 + (LP: #1871284) + - ALSA: hda: add Intel DSP configuration / probe code + - ALSA: hda: fix intel DSP config + - ALSA: hda: Allow non-Intel device probe gracefully + - ALSA: hda: More constifications + - ALSA: hda: Rename back to dmic_detect option + - [Config] SND_INTEL_DSP_CONFIG=m + * add_key05 from ubuntu_ltp_syscalls failed (LP: #1869644) + - KEYS: reaching the keys quotas correctly + * Fix authentication fail on Realtek WiFi 8723de (LP: #1871300) + - SAUCE: rtw88: No retry and report for auth and assoc + - SAUCE: rtw88: fix rate for a while after being connected + - SAUCE: rtw88: Move driver IQK to set channel before association for 11N chip + * Add Mute LED support for an HP laptop (LP: #1871090) + - ALSA: hda/realtek: Enable mute LED on an HP system + * dscr_sysfs_test / futex_bench / tm-unavailable in powerpc from + ubuntu_kernel_selftests timeout on PowerPC nodes with B-5.3 (LP: #1864642) + - Revert "UBUNTU: SAUCE: selftests/powerpc -- Disable timeout for benchmark + and tm tests" + - selftests/powerpc: Turn off timeout setting for benchmarks, dscr, signal, tm + * Update 20.0.4 NVMe Core, NVMe FC Transport and nvme-cli for Broadcom Emulex + lpfc driver 12.6.0.x dependencies (LP: #1856340) + - nvme-fc: Sync nvme-fc header to FC-NVME-2 + - nvme-fc and nvmet-fc: sync with FC-NVME-2 header changes + - nvme-fc: Set new cmd set indicator in nvme-fc cmnd iu + - nvme-fc: clarify error messages + - nvme-fc: ensure association_id is cleared regardless of a Disconnect LS + - nvme: resync include/linux/nvme.h with nvmecli + - nvme: Fix parsing of ANA log page + * Update Broadcom Emulex lpfc driver in 5.4 to 12.6.0.x from 5.5 + (LP: #1855303) + - scsi: lpfc: Fix pt2pt discovery on SLI3 HBAs + - scsi: lpfc: Fix premature re-enabling of interrupts in lpfc_sli_host_down + - scsi: lpfc: Fix miss of register read failure check + - scsi: lpfc: Fix NVME io abort failures causing hangs + - scsi: lpfc: Fix device recovery errors after PLOGI failures + - scsi: lpfc: Fix GPF on scsi command completion + - scsi: lpfc: Fix NVMe ABTS in response to receiving an ABTS + - scsi: lpfc: Fix coverity errors on NULL pointer checks + - scsi: lpfc: Fix host hang at boot or slow boot + - scsi: lpfc: Update async event logging + - scsi: lpfc: Complete removal of FCoE T10 PI support on SLI-4 adapters + - scsi: lpfc: cleanup: remove unused fcp_txcmlpq_cnt + - scsi: lpfc: Update lpfc version to 12.4.0.1 + - scsi: lpfc: Make function lpfc_defer_pt2pt_acc static + - scsi: lpfc: fix lpfc_nvmet_mrq to be bound by hdw queue count + - scsi: lpfc: Fix reporting of read-only fw error errors + - scsi: lpfc: Fix lockdep errors in sli_ringtx_put + - scsi: lpfc: fix coverity error of dereference after null check + - scsi: lpfc: Slight fast-path performance optimizations + - scsi: lpfc: Remove lock contention target write path + - scsi: lpfc: Revise interrupt coalescing for missing scenarios + - scsi: lpfc: Make FW logging dynamically configurable + - scsi: lpfc: Add log macros to allow print by serverity or verbosity setting + - scsi: lpfc: Add FA-WWN Async Event reporting + - scsi: lpfc: Add FC-AL support to lpe32000 models + - scsi: lpfc: Add additional discovery log messages + - scsi: lpfc: Update lpfc version to 12.6.0.0 + - scsi: lpfc: lpfc_attr: Fix Use plain integer as NULL pointer + - scsi: lpfc: lpfc_nvmet: Fix Use plain integer as NULL pointer + - scsi: lpfc: fix build error of lpfc_debugfs.c for vfree/vmalloc + - scsi: lpfc: fix spelling error in MAGIC_NUMER_xxx + - scsi: lpfc: Fix NULL check before mempool_destroy is not needed + - scsi: lpfc: Make lpfc_debugfs_ras_log_data static + - scsi: lpfc: Fix configuration of BB credit recovery in service parameters + - scsi: lpfc: Fix kernel crash at lpfc_nvme_info_show during remote port + bounce + - scsi: lpfc: Fix dynamic fw log enablement check + - scsi: lpfc: Sync with FC-NVMe-2 SLER change to require Conf with SLER + - scsi: lpfc: Clarify FAWNN error message + - scsi: lpfc: Add registration for CPU Offline/Online events + - scsi: lpfc: Change default IRQ model on AMD architectures + - scsi: lpfc: Add enablement of multiple adapter dumps + - scsi: lpfc: Update lpfc version to 12.6.0.1 + - scsi: lpfc: Fix a kernel warning triggered by lpfc_sli4_enable_intr() + - scsi: lpfc: Fix lpfc_cpumask_of_node_init() + - scsi: lpfc: fix inlining of lpfc_sli4_cleanup_poll_list() + - scsi: lpfc: Initialize cpu_map for not present cpus + - scsi: lpfc: revise nvme max queues to be hdwq count + - scsi: lpfc: Update lpfc version to 12.6.0.2 + - scsi: lpfc: size cpu map by last cpu id set + - scsi: lpfc: Fix incomplete NVME discovery when target + - scsi: lpfc: Fix missing check for CSF in Write Object Mbox Rsp + - scsi: lpfc: Fix Fabric hostname registration if system hostname changes + - scsi: lpfc: Fix ras_log via debugfs + - scsi: lpfc: Fix disablement of FC-AL on lpe35000 models + - scsi: lpfc: Fix unmap of dpp bars affecting next driver load + - scsi: lpfc: Fix MDS Latency Diagnostics Err-drop rates + - scsi: lpfc: Fix improper flag check for IO type + - scsi: lpfc: Update lpfc version to 12.6.0.3 + - scsi: lpfc: Fix RQ buffer leakage when no IOCBs available + - scsi: lpfc: Fix lpfc_io_buf resource leak in lpfc_get_scsi_buf_s4 error path + - scsi: lpfc: Fix broken Credit Recovery after driver load + - scsi: lpfc: Fix registration of ELS type support in fdmi + - scsi: lpfc: Fix release of hwq to clear the eq relationship + - scsi: lpfc: Fix compiler warning on frame size + - scsi: lpfc: Fix coverity errors in fmdi attribute handling + - scsi: lpfc: Remove handler for obsolete ELS - Read Port Status (RPS) + - scsi: lpfc: Clean up hba max_lun_queue_depth checks + - scsi: lpfc: Update lpfc version to 12.6.0.4 + - scsi: lpfc: Copyright updates for 12.6.0.4 patches + - scsi: fc: Update Descriptor definition and add RDF and Link Integrity FPINs + - scsi: lpfc: add RDF registration and Link Integrity FPIN logging + * lockdown on power (LP: #1855668) // Ubuntu Kernel Support for OpenPOWER NV + Secure & Trusted Boot (LP: #1866909) + - [Config] Enable configs for OpenPOWER NV Secure & Trusted Boot + * lockdown on power (LP: #1855668) + - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode + * Focal update: v5.4.30 upstream stable release (LP: #1870571) + - mac80211: Check port authorization in the ieee80211_tx_dequeue() case + - mac80211: fix authentication with iwlwifi/mvm + - serial: sprd: Fix a dereference warning + - vt: selection, introduce vc_is_sel + - vt: ioctl, switch VT_IS_IN_USE and VT_BUSY to inlines + - vt: switch vt_dont_switch to bool + - vt: vt_ioctl: remove unnecessary console allocation checks + - vt: vt_ioctl: fix VT_DISALLOCATE freeing in-use virtual console + - vt: vt_ioctl: fix use-after-free in vt_in_use() + - platform/x86: pmc_atom: Add Lex 2I385SW to critclk_systems DMI table + - bpf: Explicitly memset the bpf_attr structure + - bpf: Explicitly memset some bpf info structures declared on the stack + - gpiolib: acpi: Add quirk to ignore EC wakeups on HP x2 10 CHT + AXP288 model + - net: ks8851-ml: Fix IO operations, again + - clk: imx: Align imx sc clock msg structs to 4 + - clk: imx: Align imx sc clock parent msg structs to 4 + - clk: ti: am43xx: Fix clock parent for RTC clock + - libceph: fix alloc_msg_with_page_vector() memory leaks + - arm64: alternative: fix build with clang integrated assembler + - perf map: Fix off by one in strncpy() size argument + - ARM: dts: oxnas: Fix clear-mask property + - ARM: bcm2835-rpi-zero-w: Add missing pinctrl name + - ARM: dts: imx6: phycore-som: fix arm and soc minimum voltage + - ARM: dts: N900: fix onenand timings + - ARM: dts: sun8i: r40: Move AHCI device node based on address order + - arm64: dts: ls1043a-rdb: correct RGMII delay mode to rgmii-id + - arm64: dts: ls1046ardb: set RGMII interfaces to RGMII_ID mode + - Linux 5.4.30 + * Miscellaneous Ubuntu changes + - [Config] CONFIG_RT_GROUP_SCHED=y + - SAUCE: powerpc/ima: require IMA module signatures only if MODULE_SIG is not + enabled + - SAUCE: Update aufs to 5.4.3 20200302 + - SAUCE: drm/amdgpu: Remove missing firmware files from modinfo + - SAUCE: drm/i915: Fix ref->mutex deadlock in i915_active_wait() + - SAUCE: drm/i915: Synchronize active and retire callbacks + - SAUCE: apparmor: add a valid state flags check + - SAUCE: aapparmor: add consistency check between state and dfa diff encode + flags + - SAUCE: aapparmor: remove useless aafs_create_symlink + - SAUCE: aapparmor: fail unpack if profile mode is unknown + - SAUCE: apparmor: ensure that dfa state tables have entries + - SAUCE: apparmor: fix potential label refcnt leak in aa_change_profile + - SAUCE: security/apparmor/label.c: Clean code by removing redundant + instructions + - [Config] Remove PCIEASPM_DEBUG from annotations + - [Config] Remove HEADER_TEST from annotations + - SAUCE: selftests/seccomp: allow clock_nanosleep instead of nanosleep + - [Debian] Allow building linux-libc-dev from linux-riscv + - [Packaging] Remove riscv64 packaging from master kernel + - [Config] Remove CONFIG_SND_HDA_INTEL_DETECT_DMIC from annotations + * Miscellaneous upstream changes + - net/bpfilter: remove superfluous testing message + - apparmor: increase left match history buffer size + + [ Ubuntu: 5.4.0-23.27 ] + + * Miscellaneous Ubuntu changes + - [Packaging] Enable riscv64 build + + -- Seth Forshee Fri, 10 Apr 2020 14:58:55 -0500 + +linux-oracle (5.4.0-1008.8) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1008.8 -proposed tracker (LP: #1870501) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to 5.4.0-22.26 + + [ Ubuntu: 5.4.0-22.26 ] + + * focal/linux: 5.4.0-22.26 -proposed tracker (LP: #1870502) + * Packaging resync (LP: #1786013) + - [Packaging] update variants + - [Packaging] update helper scripts + - update dkms package versions + * [SFC-0316]sync mainline kernel 5.7rc1 SFC patchset into ubuntu HWE kernel + branch (LP: #1867588) + - spi: Allow SPI controller override device buswidth + - spi: HiSilicon v3xx: Properly set CMD_CONFIG for Dual/Quad modes + - spi: HiSilicon v3xx: Use DMI quirk to set controller buswidth override bits + * [hns3-0316]sync mainline kernel 5.6rc4 hns3 patchset into ubuntu HWE kernel + branch (LP: #1867586) + - net: hns3: fix VF VLAN table entries inconsistent issue + - net: hns3: fix RMW issue for VLAN filter switch + - net: hns3: clear port base VLAN when unload PF + * [sas-0316]sync mainline kernel 5.6rc1 roce patchset into ubuntu HWE kernel + branch (LP: #1867587) + - scsi: hisi_sas: use threaded irq to process CQ interrupts + - scsi: hisi_sas: replace spin_lock_irqsave/spin_unlock_restore with + spin_lock/spin_unlock + - scsi: hisi_sas: Replace magic number when handle channel interrupt + - scsi: hisi_sas: Modify the file permissions of trigger_dump to write only + - scsi: hisi_sas: Add prints for v3 hw interrupt converge and automatic + affinity + - scsi: hisi_sas: Rename hisi_sas_cq.pci_irq_mask + * Revert "nvme_fc: add module to ops template to allow module references" + (LP: #1869947) + - SAUCE: Revert "nvme_fc: add module to ops template to allow module + references" + * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570) + - Revert "UBUNTU: SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th" + - SAUCE: e1000e: bump up timeout to wait when ME un-configure ULP mode + * Focal update: v5.4.29 upstream stable release (LP: #1870142) + - mmc: core: Allow host controllers to require R1B for CMD6 + - mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for erase/trim/discard + - mmc: core: Respect MMC_CAP_NEED_RSP_BUSY for eMMC sleep command + - mmc: sdhci-omap: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY + - mmc: sdhci-tegra: Fix busy detection by enabling MMC_CAP_NEED_RSP_BUSY + - ACPI: PM: s2idle: Rework ACPI events synchronization + - cxgb4: fix throughput drop during Tx backpressure + - cxgb4: fix Txq restart check during backpressure + - geneve: move debug check after netdev unregister + - hsr: fix general protection fault in hsr_addr_is_self() + - ipv4: fix a RCU-list lock in inet_dump_fib() + - macsec: restrict to ethernet devices + - mlxsw: pci: Only issue reset when system is ready + - mlxsw: spectrum_mr: Fix list iteration in error path + - net/bpfilter: fix dprintf usage for /dev/kmsg + - net: cbs: Fix software cbs to consider packet sending time + - net: dsa: Fix duplicate frames flooded by learning + - net: dsa: mt7530: Change the LINK bit to reflect the link status + - net: dsa: tag_8021q: replace dsa_8021q_remove_header with __skb_vlan_pop + - net: ena: Add PCI shutdown handler to allow safe kexec + - net: mvneta: Fix the case where the last poll did not process all rx + - net/packet: tpacket_rcv: avoid a producer race condition + - net: phy: dp83867: w/a for fld detect threshold bootstrapping issue + - net: phy: mdio-bcm-unimac: Fix clock handling + - net: phy: mdio-mux-bcm-iproc: check clk_prepare_enable() return value + - net: qmi_wwan: add support for ASKEY WWHC050 + - net/sched: act_ct: Fix leak of ct zone template on replace + - net_sched: cls_route: remove the right filter from hashtable + - net_sched: hold rtnl lock in tcindex_partial_destroy_work() + - net_sched: keep alloc_hash updated after hash allocation + - net: stmmac: dwmac-rk: fix error path in rk_gmac_probe + - NFC: fdp: Fix a signedness bug in fdp_nci_send_patch() + - r8169: re-enable MSI on RTL8168c + - slcan: not call free_netdev before rtnl_unlock in slcan_open + - tcp: also NULL skb->dev when copy was needed + - tcp: ensure skb->dev is NULL before leaving TCP stack + - tcp: repair: fix TCP_QUEUE_SEQ implementation + - vxlan: check return value of gro_cells_init() + - bnxt_en: Fix Priority Bytes and Packets counters in ethtool -S. + - bnxt_en: fix memory leaks in bnxt_dcbnl_ieee_getets() + - bnxt_en: Return error if bnxt_alloc_ctx_mem() fails. + - bnxt_en: Free context memory after disabling PCI in probe error path. + - bnxt_en: Reset rings if ring reservation fails during open() + - net: ip_gre: Separate ERSPAN newlink / changelink callbacks + - net: ip_gre: Accept IFLA_INFO_DATA-less configuration + - hsr: use rcu_read_lock() in hsr_get_node_{list/status}() + - hsr: add restart routine into hsr_get_node_list() + - hsr: set .netnsok flag + - net/mlx5: DR, Fix postsend actions write length + - net/mlx5e: Enhance ICOSQ WQE info fields + - net/mlx5e: Fix missing reset of SW metadata in Striding RQ reset + - net/mlx5e: Fix ICOSQ recovery flow with Striding RQ + - net/mlx5e: Do not recover from a non-fatal syndrome + - cgroup-v1: cgroup_pidlist_next should update position index + - nfs: add minor version to nfs_server_key for fscache + - cpupower: avoid multiple definition with gcc -fno-common + - drivers/of/of_mdio.c:fix of_mdiobus_register() + - cgroup1: don't call release_agent when it is "" + - [Config] updateconfigs for DPAA_ERRATUM_A050385 + - dt-bindings: net: FMan erratum A050385 + - arm64: dts: ls1043a: FMan erratum A050385 + - fsl/fman: detect FMan erratum A050385 + - drm/amd/display: update soc bb for nv14 + - drm/amdgpu: correct ROM_INDEX/DATA offset for VEGA20 + - drm/exynos: Fix cleanup of IOMMU related objects + - iommu/vt-d: Silence RCU-list debugging warnings + - s390/qeth: don't reset default_out_queue + - s390/qeth: handle error when backing RX buffer + - scsi: ipr: Fix softlockup when rescanning devices in petitboot + - mac80211: Do not send mesh HWMP PREQ if HWMP is disabled + - dpaa_eth: Remove unnecessary boolean expression in dpaa_get_headroom + - sxgbe: Fix off by one in samsung driver strncpy size arg + - net: hns3: fix "tc qdisc del" failed issue + - iommu/vt-d: Fix debugfs register reads + - iommu/vt-d: Populate debugfs if IOMMUs are detected + - iwlwifi: mvm: fix non-ACPI function + - i2c: hix5hd2: add missed clk_disable_unprepare in remove + - Input: raydium_i2c_ts - fix error codes in raydium_i2c_boot_trigger() + - Input: fix stale timestamp on key autorepeat events + - Input: synaptics - enable RMI on HP Envy 13-ad105ng + - Input: avoid BIT() macro usage in the serio.h UAPI header + - IB/rdmavt: Free kernel completion queue when done + - RDMA/core: Fix missing error check on dev_set_name() + - gpiolib: Fix irq_disable() semantics + - RDMA/nl: Do not permit empty devices names during RDMA_NLDEV_CMD_NEWLINK/SET + - RDMA/mad: Do not crash if the rdma device does not have a umad interface + - ceph: check POOL_FLAG_FULL/NEARFULL in addition to OSDMAP_FULL/NEARFULL + - ceph: fix memory leak in ceph_cleanup_snapid_map() + - ARM: dts: dra7: Add bus_dma_limit for L3 bus + - ARM: dts: omap5: Add bus_dma_limit for L3 bus + - x86/ioremap: Fix CONFIG_EFI=n build + - perf probe: Fix to delete multiple probe event + - perf probe: Do not depend on dwfl_module_addrsym() + - rtlwifi: rtl8188ee: Fix regression due to commit d1d1a96bdb44 + - tools: Let O= makes handle a relative path with -C option + - scripts/dtc: Remove redundant YYLOC global declaration + - scsi: sd: Fix optimal I/O size for devices that change reported values + - nl80211: fix NL80211_ATTR_CHANNEL_WIDTH attribute type + - mac80211: drop data frames without key on encrypted links + - mac80211: mark station unauthorized before key removal + - mm/swapfile.c: move inode_lock out of claim_swapfile + - drivers/base/memory.c: indicate all memory blocks as removable + - mm/sparse: fix kernel crash with pfn_section_valid check + - mm: fork: fix kernel_stack memcg stats for various stack implementations + - gpiolib: acpi: Correct comment for HP x2 10 honor_wakeup quirk + - gpiolib: acpi: Rework honor_wakeup option into an ignore_wake option + - gpiolib: acpi: Add quirk to ignore EC wakeups on HP x2 10 BYT + AXP288 model + - bpf: Fix cgroup ref leak in cgroup_bpf_inherit on out-of-memory + - RDMA/core: Ensure security pkey modify is not lost + - afs: Fix handling of an abort from a service handler + - genirq: Fix reference leaks on irq affinity notifiers + - xfrm: handle NETDEV_UNREGISTER for xfrm device + - vti[6]: fix packet tx through bpf_redirect() in XinY cases + - RDMA/mlx5: Fix the number of hwcounters of a dynamic counter + - RDMA/mlx5: Fix access to wrong pointer while performing flush due to error + - RDMA/mlx5: Block delay drop to unprivileged users + - xfrm: fix uctx len check in verify_sec_ctx_len + - xfrm: add the missing verify_sec_ctx_len check in xfrm_add_acquire + - xfrm: policy: Fix doulbe free in xfrm_policy_timer + - afs: Fix client call Rx-phase signal handling + - afs: Fix some tracing details + - afs: Fix unpinned address list during probing + - ieee80211: fix HE SPR size calculation + - mac80211: set IEEE80211_TX_CTRL_PORT_CTRL_PROTO for nl80211 TX + - netfilter: flowtable: reload ip{v6}h in nf_flow_tuple_ip{v6} + - netfilter: nft_fwd_netdev: validate family and chain type + - netfilter: nft_fwd_netdev: allow to redirect to ifb via ingress + - i2c: nvidia-gpu: Handle timeout correctly in gpu_i2c_check_status() + - bpf, x32: Fix bug with JMP32 JSET BPF_X checking upper bits + - bpf: Initialize storage pointers to NULL to prevent freeing garbage pointer + - bpf/btf: Fix BTF verification of enum members in struct/union + - bpf, sockmap: Remove bucket->lock from sock_{hash|map}_free + - ARM: dts: sun8i-a83t-tbs-a711: Fix USB OTG mode detection + - vti6: Fix memory leak of skb if input policy check fails + - r8169: fix PHY driver check on platforms w/o module softdeps + - clocksource/drivers/hyper-v: Untangle stimers and timesync from clocksources + - USB: serial: option: add support for ASKEY WWHC050 + - USB: serial: option: add BroadMobi BM806U + - USB: serial: option: add Wistron Neweb D19Q1 + - USB: cdc-acm: restore capability check order + - USB: serial: io_edgeport: fix slab-out-of-bounds read in + edge_interrupt_callback + - usb: musb: fix crash with highmen PIO and usbmon + - media: flexcop-usb: fix endpoint sanity check + - media: usbtv: fix control-message timeouts + - staging: kpc2000: prevent underflow in cpld_reconfigure() + - staging: rtl8188eu: Add ASUS USB-N10 Nano B1 to device table + - staging: wlan-ng: fix ODEBUG bug in prism2sta_disconnect_usb + - staging: wlan-ng: fix use-after-free Read in hfa384x_usbin_callback + - ahci: Add Intel Comet Lake H RAID PCI ID + - libfs: fix infoleak in simple_attr_read() + - media: ov519: add missing endpoint sanity checks + - media: dib0700: fix rc endpoint lookup + - media: stv06xx: add missing descriptor sanity checks + - media: xirlink_cit: add missing descriptor sanity checks + - media: v4l2-core: fix a use-after-free bug of sd->devnode + - update wireguard dkms package version + - [Config] updateconfigs for NET_REDIRECT + - net: Fix CONFIG_NET_CLS_ACT=n and CONFIG_NFT_FWD_NETDEV={y, m} build + - Linux 5.4.29 + * Restore kernel control of PCIe DPC via option (LP: #1869423) + - PCI/DPC: Add "pcie_ports=dpc-native" to allow DPC without AER control + * swap storms kills interactive use (LP: #1861359) + - SAUCE: mm/page_alloc.c: disable memory reclaim watermark boosting by default + * sysfs: incorrect network device permissions on network namespace change + (LP: #1865359) + - sysfs: add sysfs_file_change_owner() + - sysfs: add sysfs_link_change_owner() + - sysfs: add sysfs_group{s}_change_owner() + - sysfs: add sysfs_change_owner() + - device: add device_change_owner() + - drivers/base/power: add dpm_sysfs_change_owner() + - net-sysfs: add netdev_change_owner() + - net-sysfs: add queue_change_owner() + - net: fix sysfs permssions when device changes network namespace + - sysfs: fix static inline declaration of sysfs_groups_change_owner() + * Kernel Oops - general protection fault: 0000 [#1] SMP PTI after + disconnecting thunderbolt docking station (LP: #1864754) + - SAUCE: ptp: free ptp clock properly + * [Selftests] Apply various fixes and improvements (LP: #1870543) + - SAUCE: selftests: net: ip_defrag: limit packet to 1000 fragments + - SAUCE: kselftest/runner: avoid using timeout if timeout is disabled + - SAUCE: selftests/seccomp -- Disable timeout for seccomp tests + * Focal update: v5.4.28 upstream stable release (LP: #1869061) + - locks: fix a potential use-after-free problem when wakeup a waiter + - locks: reinstate locks_delete_block optimization + - spi: spi-omap2-mcspi: Support probe deferral for DMA channels + - drm/mediatek: Find the cursor plane instead of hard coding it + - phy: ti: gmii-sel: fix set of copy-paste errors + - phy: ti: gmii-sel: do not fail in case of gmii + - ARM: dts: dra7-l4: mark timer13-16 as pwm capable + - spi: qup: call spi_qup_pm_resume_runtime before suspending + - powerpc: Include .BTF section + - cifs: fix potential mismatch of UNC paths + - cifs: add missing mount option to /proc/mounts + - ARM: dts: dra7: Add "dma-ranges" property to PCIe RC DT nodes + - spi: pxa2xx: Add CS control clock quirk + - spi/zynqmp: remove entry that causes a cs glitch + - drm/exynos: dsi: propagate error value and silence meaningless warning + - drm/exynos: dsi: fix workaround for the legacy clock name + - drm/exynos: hdmi: don't leak enable HDMI_EN regulator if probe fails + - drivers/perf: fsl_imx8_ddr: Correct the CLEAR bit definition + - drivers/perf: arm_pmu_acpi: Fix incorrect checking of gicc pointer + - altera-stapl: altera_get_note: prevent write beyond end of 'key' + - dm bio record: save/restore bi_end_io and bi_integrity + - dm integrity: use dm_bio_record and dm_bio_restore + - riscv: avoid the PIC offset of static percpu data in module beyond 2G limits + - ASoC: stm32: sai: manage rebind issue + - spi: spi_register_controller(): free bus id on error paths + - riscv: Force flat memory model with no-mmu + - riscv: Fix range looking for kernel image memblock + - drm/amdgpu: clean wptr on wb when gpu recovery + - drm/amd/display: Clear link settings on MST disable connector + - drm/amd/display: fix dcc swath size calculations on dcn1 + - xenbus: req->body should be updated before req->state + - xenbus: req->err should be updated before req->state + - block, bfq: fix overwrite of bfq_group pointer in bfq_find_set_group() + - parse-maintainers: Mark as executable + - binderfs: use refcount for binder control devices too + - Revert "drm/fbdev: Fallback to non tiled mode if all tiles not present" + - usb: quirks: add NO_LPM quirk for RTL8153 based ethernet adapters + - USB: serial: option: add ME910G1 ECM composition 0x110b + - usb: host: xhci-plat: add a shutdown + - USB: serial: pl2303: add device-id for HP LD381 + - usb: xhci: apply XHCI_SUSPEND_DELAY to AMD XHCI controller 1022:145c + - usb: typec: ucsi: displayport: Fix NULL pointer dereference + - usb: typec: ucsi: displayport: Fix a potential race during registration + - USB: cdc-acm: fix close_delay and closing_wait units in TIOCSSERIAL + - USB: cdc-acm: fix rounding error in TIOCSSERIAL + - ALSA: line6: Fix endless MIDI read loop + - ALSA: hda/realtek - Enable headset mic of Acer X2660G with ALC662 + - ALSA: hda/realtek - Enable the headset of Acer N50-600 with ALC662 + - ALSA: seq: virmidi: Fix running status after receiving sysex + - ALSA: seq: oss: Fix running status after receiving sysex + - ALSA: pcm: oss: Avoid plugin buffer overflow + - ALSA: pcm: oss: Remove WARNING from snd_pcm_plug_alloc() checks + - tty: fix compat TIOCGSERIAL leaking uninitialized memory + - tty: fix compat TIOCGSERIAL checking wrong function ptr + - iio: chemical: sps30: fix missing triggered buffer dependency + - iio: st_sensors: remap SMO8840 to LIS2DH12 + - iio: trigger: stm32-timer: disable master mode when stopping + - iio: accel: adxl372: Set iio_chan BE + - iio: magnetometer: ak8974: Fix negative raw values in sysfs + - iio: adc: stm32-dfsdm: fix sleep in atomic context + - iio: adc: at91-sama5d2_adc: fix differential channels in triggered mode + - iio: light: vcnl4000: update sampling periods for vcnl4200 + - iio: light: vcnl4000: update sampling periods for vcnl4040 + - mmc: rtsx_pci: Fix support for speed-modes that relies on tuning + - mmc: sdhci-of-at91: fix cd-gpios for SAMA5D2 + - mmc: sdhci-cadence: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN for UniPhier + - CIFS: fiemap: do not return EINVAL if get nothing + - kbuild: Disable -Wpointer-to-enum-cast + - staging: rtl8188eu: Add device id for MERCUSYS MW150US v2 + - staging: greybus: loopback_test: fix poll-mask build breakage + - staging/speakup: fix get_word non-space look-ahead + - intel_th: msu: Fix the unexpected state warning + - intel_th: Fix user-visible error codes + - intel_th: pci: Add Elkhart Lake CPU support + - modpost: move the namespace field in Module.symvers last + - rtc: max8907: add missing select REGMAP_IRQ + - arm64: compat: Fix syscall number of compat_clock_getres + - xhci: Do not open code __print_symbolic() in xhci trace events + - btrfs: fix log context list corruption after rename whiteout error + - drm/amd/amdgpu: Fix GPR read from debugfs (v2) + - drm/lease: fix WARNING in idr_destroy + - stm class: sys-t: Fix the use of time_after() + - memcg: fix NULL pointer dereference in __mem_cgroup_usage_unregister_event + - mm, memcg: fix corruption on 64-bit divisor in memory.high throttling + - mm, memcg: throttle allocators based on ancestral memory.high + - mm/hotplug: fix hot remove failure in SPARSEMEM|!VMEMMAP case + - mm: do not allow MADV_PAGEOUT for CoW pages + - epoll: fix possible lost wakeup on epoll_ctl() path + - mm: slub: be more careful about the double cmpxchg of freelist + - mm, slub: prevent kmalloc_node crashes and memory leaks + - page-flags: fix a crash at SetPageError(THP_SWAP) + - x86/mm: split vmalloc_sync_all() + - futex: Fix inode life-time issue + - futex: Unbreak futex hashing + - arm64: smp: fix smp_send_stop() behaviour + - arm64: smp: fix crash_smp_send_stop() behaviour + - nvmet-tcp: set MSG_MORE only if we actually have more to send + - drm/bridge: dw-hdmi: fix AVI frame colorimetry + - staging: greybus: loopback_test: fix potential path truncation + - staging: greybus: loopback_test: fix potential path truncations + - Linux 5.4.28 + * Pop sound from build-in speaker during cold boot and resume from S3 + (LP: #1866357) // Focal update: v5.4.28 upstream stable release + (LP: #1869061) + - ALSA: hda/realtek: Fix pop noise on ALC225 + * Focal update: v5.4.28 upstream stable release (LP: #1869061) + - perf/x86/amd: Add support for Large Increment per Cycle Events + - EDAC/amd64: Add family ops for Family 19h Models 00h-0Fh + - x86/MCE/AMD, EDAC/mce_amd: Add new Load Store unit McaType + - EDAC/mce_amd: Always load on SMCA systems + - x86/amd_nb: Add Family 19h PCI IDs + - EDAC/amd64: Drop some family checks for newer systems + * Update mpt3sas Driver to 33.100.00.00 for Ubuntu 20.04 (LP: #1863574) + - scsi: mpt3sas: Register trace buffer based on NVDATA settings + - scsi: mpt3sas: Display message before releasing diag buffer + - scsi: mpt3sas: Free diag buffer without any status check + - scsi: mpt3sas: Maintain owner of buffer through UniqueID + - scsi: mpt3sas: clear release bit when buffer reregistered + - scsi: mpt3sas: Reuse diag buffer allocated at load time + - scsi: mpt3sas: Add app owned flag support for diag buffer + - scsi: mpt3sas: Fail release cmnd if diag buffer is released + - scsi: mpt3sas: Use Component img header to get Package ver + - scsi: mpt3sas: Fix module parameter max_msix_vectors + - scsi: mpt3sas: Bump mpt3sas driver version to 32.100.00.00 + - scsi: mpt3sas: Clean up some indenting + - scsi: mpt3sas: change allocation option + - scsi: mpt3sas: Update MPI Headers to v02.00.57 + - scsi: mpt3sas: Add support for NVMe shutdown + - scsi: mpt3sas: renamed _base_after_reset_handler function + - scsi: mpt3sas: Add support IOCs new state named COREDUMP + - scsi: mpt3sas: Handle CoreDump state from watchdog thread + - scsi: mpt3sas: print in which path firmware fault occurred + - scsi: mpt3sas: Optimize mpt3sas driver logging + - scsi: mpt3sas: Print function name in which cmd timed out + - scsi: mpt3sas: Remove usage of device_busy counter + - scsi: mpt3sas: Update drive version to 33.100.00.00 + * Ubuntu 20.04: megaraid_sas driver update to version 07.713.01.00-rc1 + (LP: #1863581) + - scsi: megaraid_sas: Unique names for MSI-X vectors + - scsi: megaraid_sas: remove unused variables 'debugBlk','fusion' + - compat_ioctl: use correct compat_ptr() translation in drivers + - scsi: megaraid_sas: Make poll_aen_lock static + - scsi: megaraid_sas: Reset adapter if FW is not in READY state after device + resume + - scsi: megaraid_sas: Set no_write_same only for Virtual Disk + - scsi: megaraid_sas: Update optimal queue depth for SAS and NVMe devices + - scsi: megaraid_sas: Do not kill host bus adapter, if adapter is already dead + - scsi: megaraid_sas: Do not kill HBA if JBOD Seqence map or RAID map is + disabled + - scsi: megaraid_sas: Do not set HBA Operational if FW is not in operational + state + - scsi: megaraid_sas: Re-Define enum DCMD_RETURN_STATUS + - scsi: megaraid_sas: Limit the number of retries for the IOCTLs causing + firmware fault + - scsi: megaraid_sas: Use Block layer API to check SCSI device in-flight IO + requests + - scsi: megaraid_sas: Update driver version to 07.713.01.00-rc1 + - scsi: megaraid_sas: fixup MSIx interrupt setup during resume + + -- Seth Forshee Fri, 03 Apr 2020 22:05:52 -0500 + +linux-oracle (5.4.0-1007.7) focal; urgency=medium + + + [ Ubuntu: 5.4.0-21.25 ] + + * CVE-2020-8835 + - SAUCE: bpf: undo incorrect __reg_bound_offset32 handling + + -- Thadeu Lima de Souza Cascardo Fri, 27 Mar 2020 20:07:28 -0300 + +linux-oracle (5.4.0-1006.6) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1006.6 -proposed tracker (LP: #1868346) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following Ubuntu-5.4.0-19.23 rebase + + [ Ubuntu: 5.4.0-20.24 ] + + * Miscellaneous Ubuntu changes + - SAUCE: (lockdown) Reduce lockdown level to INTEGRITY for secure boot + + [ Ubuntu: 5.4.0-19.23 ] + + * focal/linux: 5.4.0-19.23 -proposed tracker (LP: #1868347) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - update dkms package versions + * Focal update: v5.4.27 upstream stable release (LP: #1868538) + - netfilter: hashlimit: do not use indirect calls during gc + - netfilter: xt_hashlimit: unregister proc file before releasing mutex + - drm/amdgpu: Fix TLB invalidation request when using semaphore + - ACPI: watchdog: Allow disabling WDAT at boot + - HID: apple: Add support for recent firmware on Magic Keyboards + - ACPI: watchdog: Set default timeout in probe + - HID: hid-bigbenff: fix general protection fault caused by double kfree + - HID: hid-bigbenff: call hid_hw_stop() in case of error + - HID: hid-bigbenff: fix race condition for scheduled work during removal + - selftests/rseq: Fix out-of-tree compilation + - tracing: Fix number printing bug in print_synth_event() + - cfg80211: check reg_rule for NULL in handle_channel_custom() + - scsi: libfc: free response frame from GPN_ID + - net: usb: qmi_wwan: restore mtu min/max values after raw_ip switch + - net: ks8851-ml: Fix IRQ handling and locking + - mac80211: rx: avoid RCU list traversal under mutex + - net: ll_temac: Fix race condition causing TX hang + - net: ll_temac: Add more error handling of dma_map_single() calls + - net: ll_temac: Fix RX buffer descriptor handling on GFP_ATOMIC pressure + - net: ll_temac: Handle DMA halt condition caused by buffer underrun + - blk-mq: insert passthrough request into hctx->dispatch directly + - drm/amdgpu: fix memory leak during TDR test(v2) + - kbuild: add dtbs_check to PHONY + - kbuild: add dt_binding_check to PHONY in a correct place + - signal: avoid double atomic counter increments for user accounting + - slip: not call free_netdev before rtnl_unlock in slip_open + - net: phy: mscc: fix firmware paths + - hinic: fix a irq affinity bug + - hinic: fix a bug of setting hw_ioctxt + - hinic: fix a bug of rss configuration + - net: rmnet: fix NULL pointer dereference in rmnet_newlink() + - net: rmnet: fix NULL pointer dereference in rmnet_changelink() + - net: rmnet: fix suspicious RCU usage + - net: rmnet: remove rcu_read_lock in rmnet_force_unassociate_device() + - net: rmnet: do not allow to change mux id if mux id is duplicated + - net: rmnet: use upper/lower device infrastructure + - net: rmnet: fix bridge mode bugs + - net: rmnet: fix packet forwarding in rmnet bridge mode + - sfc: fix timestamp reconstruction at 16-bit rollover points + - jbd2: fix data races at struct journal_head + - blk-mq: insert flush request to the front of dispatch queue + - net: qrtr: fix len of skb_put_padto in qrtr_node_enqueue + - ARM: 8957/1: VDSO: Match ARMv8 timer in cntvct_functional() + - ARM: 8958/1: rename missed uaccess .fixup section + - mm: slub: add missing TID bump in kmem_cache_alloc_bulk() + - HID: google: add moonball USB id + - HID: add ALWAYS_POLL quirk to lenovo pixart mouse + - ARM: 8961/2: Fix Kbuild issue caused by per-task stack protector GCC plugin + - ipv4: ensure rcu_read_lock() in cipso_v4_error() + - Linux 5.4.27 + * This laptop contains a touchpadwhich is not recognized. (LP: #1858299) // + Focal update: v5.4.27 upstream stable release (LP: #1868538) + - HID: i2c-hid: add Trekstor Surfbook E11B to descriptor override + * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570) + - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th + * Make Dell WD19 dock more reliable after suspend (LP: #1868217) + - xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3 + - xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0 + - xhci: Finetune host initiated USB3 rootport link suspend and resume + - USB: Disable LPM on WD19's Realtek Hub + * update-version-dkms doesn't add a BugLink (LP: #1867790) + - [Packaging] Add BugLink to update-version-dkms commit + * enable realtek ethernet device ASPM function (LP: #1836030) + - PCI/ASPM: Add L1 PM substate support to pci_disable_link_state() + - PCI/ASPM: Allow re-enabling Clock PM + - PCI/ASPM: Remove pcie_aspm_enabled() unnecessary locking + - PCI/ASPM: Add pcie_aspm_get_link() + - PCI/ASPM: Add sysfs attributes for controlling ASPM link states + * Update SmartPQI driver in Focal to 1.2.10-025 (LP: #1864484) + - scsi: smartpqi: clean up indentation of a statement + - scsi: smartpqi: remove set but not used variable 'ctrl_info' + - scsi: smartpqi: clean up an indentation issue + - scsi: smartpqi: fix controller lockup observed during force reboot + - scsi: smartpqi: fix call trace in device discovery + - scsi: smartpqi: add inquiry timeouts + - scsi: smartpqi: fix LUN reset when fw bkgnd thread is hung + - scsi: smartpqi: change TMF timeout from 60 to 30 seconds + - scsi: smartpqi: correct syntax issue + - scsi: smartpqi: fix problem with unique ID for physical device + - scsi: smartpqi: remove unused manifest constants + - scsi: smartpqi: Align driver syntax with oob + - scsi: smartpqi: bump version + * [roce-0111]sync mainline kernel 5.5rc6 roce patchset into ubuntu HWE kernel + branch (LP: #1859269) + - RDMA/hns: Modify variable/field name from vlan to vlan_id + - RDMA/hns: Fix a spelling mistake in a macro + - RDMA/hns: Delete BITS_PER_BYTE redefinition + - RDMA/core: Move core content from ib_uverbs to ib_core + - RDMA/core: Create mmap database and cookie helper functions + - RDMA: Connect between the mmap entry and the umap_priv structure + - RDMA/hns: Remove unsupported modify_port callback + - RDMA/hns: Delete unnecessary variable max_post + - RDMA/hns: Remove unnecessary structure hns_roce_sqp + - RDMA/hns: Delete unnecessary uar from hns_roce_cq + - RDMA/hns: Modify fields of struct hns_roce_srq + - RDMA/hns: Replace not intuitive function/macro names + - RDMA/hns: Simplify doorbell initialization code + - RDMA/hns: Modify hns_roce_hw_v2_get_cfg to simplify the code + - RDMA/hns: Fix non-standard error codes + - RDMA/hns: Modify appropriate printings + - dma-mapping: remove the DMA_ATTR_WRITE_BARRIER flag + - IB/umem: remove the dmasync argument to ib_umem_get + - RDMA/hns: Redefine interfaces used in creating cq + - RDMA/hns: Redefine the member of hns_roce_cq struct + - RDMA/hns: Rename the functions used inside creating cq + - RDMA/hns: Delete unnecessary callback functions for cq + - RDMA/hns: Remove unused function hns_roce_init_eq_table() + - RDMA/hns: Update the value of qp type + - RDMA/hns: Delete unnessary parameters in hns_roce_v2_qp_modify() + - RDMA/hns: Remove redundant print information + - RDMA/hns: Replace custom macros HNS_ROCE_ALIGN_UP + - RDMA/hns: Fix coding style issues + - RDMA/hns: Add support for reporting wc as software mode + - RDMA/hns: Remove some redundant variables related to capabilities + - RDMA/hns: Add interfaces to get pf capabilities from firmware + - RDMA/hns: Get pf capabilities from firmware + - RDMA/hns: Add support for extended atomic in userspace + * dmaengine: hisilicon: Add Kunpeng DMA engine support (LP: #1864442) + - dmaengine: hisilicon: Add Kunpeng DMA engine support + - [Config] CONFIG_HISI_DMA=m + * Add support for Realtek 8723DE wireless adapter (LP: #1780590) + - rtw88: 8822c: fix boolreturn.cocci warnings + - rtw88: remove redundant flag check helper function + - rtw88: pci: reset H2C queue indexes in a single write + - rtw88: not to enter or leave PS under IRQ + - rtw88: not to control LPS by each vif + - rtw88: remove unused lps state check helper + - rtw88: LPS enter/leave should be protected by lock + - rtw88: leave PS state for dynamic mechanism + - rtw88: add deep power save support + - rtw88: not to enter LPS by coex strategy + - rtw88: select deep PS mode when module is inserted + - rtw88: add deep PS PG mode for 8822c + - rtw88: remove misleading module parameter rtw_fw_support_lps + - mac80211: simplify TX aggregation start + - rtw88: check firmware leave lps successfully + - rtw88: allows to set RTS in TX descriptor + - rtw88: add driver TX queue support + - rtw88: take over rate control from mac80211 + - rtw88: report tx rate to mac80211 stack + - rtw88: add TX-AMSDU support + - rtw88: flush hardware tx queues + - rtw88: Don't set RX_FLAG_DECRYPTED if packet has no encryption + - rtw88: configure TX queue EDCA parameters + - rtw88: raise firmware version debug level + - rtw88: use struct rtw_fw_hdr to access firmware header + - rtw88: Fix an error message + - rtw88: config 8822c multicast address in MAC init flow + - rtw88: add NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 support + - rtw88: Use rtw_write8_set to set SYS_FUNC + - rtw88: pci: config phy after chip info is setup + - rtw88: use a for loop in rtw_power_mode_change(), not goto + - rtw88: include interrupt.h for tasklet_struct + - rtw88: mark rtw_fw_hdr __packed + - rtw88: use macro to check the current band + - rtw88: add power tracking support + - rtw88: Enable 802.11ac beamformee support + - rtw88: add set_bitrate_mask support + - rtw88: add phy_info debugfs to show Tx/Rx physical status + - rtw88: fix GENMASK_ULL for u64 + - rtw88: fix sparse warnings for DPK + - rtw88: fix sparse warnings for power tracking + - rtw88: 8822b: add RFE type 3 support + - rtw88: use rtw_phy_pg_cfg_pair struct, not arrays + - rtw88: rearrange if..else statements for rx rate indexes + - rtw88: avoid FW info flood + - rtw88: remove redundant null pointer check on arrays + - rtw88: raise LPS threshold to 50, for less power consumption + - rtw88: fix potential NULL pointer access for firmware + - rtw88: signal completion even on firmware-request failure + - rtw88: remove duplicated include from ps.c + - rtw88: pci: use macros to access PCI DBI/MDIO registers + - rtw88: pci: use for loop instead of while loop for DBI/MDIO + - rtw88: pci: enable CLKREQ function if host supports it + - rtw88: allows to enable/disable HCI link PS mechanism + - rtw88: pci: reset ring index when release skbs in tx ring + - rtw88: pci: reset dma when reset pci trx ring + - rtw88: add interface config for 8822c + - rtw88: load wowlan firmware if wowlan is supported + - rtw88: support wowlan feature for 8822c + - rtw88: Add wowlan pattern match support + - rtw88: Add wowlan net-detect support + - rtw88: fix TX secondary channel offset of 40M if current bw is 20M or 40M + - rtw88: 8822c: update power sequence to v15 + - rtw88: remove unused spinlock + - rtw88: remove unused variable 'in_lps' + - rtw88: remove unused vif pointer in struct rtw_vif + - rtw88: use rtw_hci_stop() instead of rtwdev->hci.ops->stop() + - rtw88: assign NULL to skb after being kfree()'ed + - rtw88: change max_num_of_tx_queue() definition to inline in pci.h + - rtw88: use true,false for bool variable + - rtw88: use shorter delay time to poll PS state + - rtw88: Fix return value of rtw_wow_check_fw_status + - SAUCE: rtw88: add regulatory process strategy for different chipset + - SAUCE: rtw88: support dynamic user regulatory setting + - SAUCE: rtw88: Use secondary channel offset enumeration + - SAUCE: rtw88: 8822c: modify rf protection setting + - SAUCE: rtw88: disable TX-AMSDU on 2.4G band + - SAUCE: Revert "rtw88: disable TX-AMSDU on 2.4G band" + - SAUCE: rtw88: disable TX-AMSDU on 2.4G band + - SAUCE: rtw88: remove unused parameter vif in rtw_lps_pg_info_get() + - SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask + - SAUCE: rtw88: pci: 8822c should set clock delay to zero + - SAUCE: rtw88: move rtw_enter_ips() to the last when config + - SAUCE: rtw88: avoid holding mutex for cancel_delayed_work_sync() + - SAUCE: rtw88: add ciphers to suppress error message + - SAUCE: rtw88: 8822c: update power sequence to v16 + - SAUCE: rtw88: Fix incorrect beamformee role setting + - SAUCE: rtw88: don't hold all IRQs disabled for PS operations + - SAUCE: rtw88: extract alloc rsvd_page and h2c skb routines + - SAUCE: rtw88: associate reserved pages with each vif + - SAUCE: rtw88: add adaptivity support for EU/JP regulatory + - SAUCE: rtw88: 8723d: Add basic chip capabilities + - SAUCE: rtw88: 8723d: add beamform wrapper functions + - SAUCE: rtw88: 8723d: Add power sequence + - SAUCE: rtw88: 8723d: Add RF read/write ops + - SAUCE: rtw88: 8723d: Add mac/bb/rf/agc/power_limit tables + - SAUCE: rtw88: 8723d: Add cfg_ldo25 to control LDO25 + - SAUCE: rtw88: 8723d: Add new chip op efuse_grant() to control efuse access + - SAUCE: rtw88: 8723d: Add read_efuse to recognize efuse info from map + - SAUCE: rtw88: add legacy firmware download for 8723D devices + - SAUCE: rtw88: no need to send additional information to legacy firmware + - SAUCE: rtw88: 8723d: Add mac power-on/-off function + - SAUCE: rtw88: decompose while(1) loop of power sequence polling command + - SAUCE: rtw88: 8723d: 11N chips don't support H2C queue + - SAUCE: rtw88: 8723d: implement set_tx_power_index ops + - SAUCE: rtw88: 8723d: Organize chip TX/RX FIFO + - SAUCE: rtw88: 8723d: initialize mac/bb/rf basic functions + - SAUCE: rtw88: 8723d: Add DIG parameter + - SAUCE: rtw88: 8723d: Add query_rx_desc + - SAUCE: rtw88: 8723d: Add set_channel + - SAUCE: rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully + - SAUCE: rtw88: 8723d: 11N chips don't support LDPC + - SAUCE: rtw88: set default port to firmware + - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets + - SAUCE: rtw88: sar: add SAR of TX power limit + - SAUCE: rtw88: sar: Load static SAR table from ACPI WRDS method + - SAUCE: rtw88: sar: Load dynamic SAR table from ACPI methods + - SAUCE: rtw88: sar: apply dynamic SAR table to tx power limit + - SAUCE: rtw88: sar: add sar_work to poll if dynamic SAR table is changed + - SAUCE: rtw88: sar: dump sar information via debugfs + - SAUCE: rtw88: 8723d: Add chip_ops::false_alarm_statistics + - SAUCE: rtw88: 8723d: Set IG register for CCK rate + - SAUCE: rtw88: 8723d: add interface configurations table + - SAUCE: rtw88: 8723d: Add LC calibration + - SAUCE: rtw88: 8723d: add IQ calibration + - SAUCE: rtw88: 8723d: Add power tracking + - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend + - SAUCE: rtw88: 8723d: implement flush queue + - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info + - SAUCE: rtw88: 8723d: Add coex support + - SAUCE: rtw88: fill zeros to words 0x06 and 0x07 of security cam entry + - SAUCE: rtw88: 8723d: Add 8723DE to Kconfig and Makefile + - [Config] CONFIG_RTW88_8723DE=y + * [Ubuntu 20.04] Unset HIBERNATION and PM kernel config options for focal + (LP: #1867753) + - [Config] CONFIG_HIBERNATION=n and CONFIG_PM=n for s390x + * [20.04 FEAT] Base KVM setup for secure guests - kernel part (LP: #1835531) + - KVM: s390: Cleanup kvm_arch_init error path + - KVM: s390: Cleanup initial cpu reset + - KVM: s390: Add new reset vcpu API + - s390/protvirt: introduce host side setup + - s390/protvirt: add ultravisor initialization + - s390/mm: provide memory management functions for protected KVM guests + - s390/mm: add (non)secure page access exceptions handlers + - s390/protvirt: Add sysfs firmware interface for Ultravisor information + - KVM: s390/interrupt: do not pin adapter interrupt pages + - KVM: s390: protvirt: Add UV debug trace + - KVM: s390: add new variants of UV CALL + - KVM: s390: protvirt: Add initial vm and cpu lifecycle handling + - KVM: s390: protvirt: Secure memory is not mergeable + - KVM: s390/mm: Make pages accessible before destroying the guest + - KVM: s390: protvirt: Handle SE notification interceptions + - KVM: s390: protvirt: Instruction emulation + - KVM: s390: protvirt: Implement interrupt injection + - KVM: s390: protvirt: Add SCLP interrupt handling + - KVM: s390: protvirt: Handle spec exception loops + - KVM: s390: protvirt: Add new gprs location handling + - KVM: S390: protvirt: Introduce instruction data area bounce buffer + - KVM: s390: protvirt: handle secure guest prefix pages + - KVM: s390/mm: handle guest unpin events + - KVM: s390: protvirt: Write sthyi data to instruction data area + - KVM: s390: protvirt: STSI handling + - KVM: s390: protvirt: disallow one_reg + - KVM: s390: protvirt: Do only reset registers that are accessible + - KVM: s390: protvirt: Only sync fmt4 registers + - KVM: s390: protvirt: Add program exception injection + - KVM: s390: protvirt: UV calls in support of diag308 0, 1 + - KVM: s390: protvirt: Report CPU state to Ultravisor + - KVM: s390: protvirt: Support cmd 5 operation state + - KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112 + - KVM: s390: protvirt: do not inject interrupts after start + - KVM: s390: protvirt: Add UV cpu reset calls + - DOCUMENTATION: Protected virtual machine introduction and IPL + - KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED + - KVM: s390: protvirt: Add KVM api documentation + - mm/gup/writeback: add callbacks for inaccessible pages + * Sys oopsed with sysfs test in ubuntu_stress_smoke_test on X-hwe ARM64 + (LP: #1866772) + - ACPI: sysfs: copy ACPI data using io memory copying + * Focal update: v5.4.26 upstream stable release (LP: #1867903) + - virtio_balloon: Adjust label in virtballoon_probe + - ALSA: hda/realtek - More constifications + - cgroup, netclassid: periodically release file_lock on classid updating + - gre: fix uninit-value in __iptunnel_pull_header + - inet_diag: return classid for all socket types + - ipv6/addrconf: call ipv6_mc_up() for non-Ethernet interface + - ipvlan: add cond_resched_rcu() while processing muticast backlog + - ipvlan: do not add hardware address of master to its unicast filter list + - ipvlan: do not use cond_resched_rcu() in ipvlan_process_multicast() + - ipvlan: don't deref eth hdr before checking it's set + - macvlan: add cond_resched() during multicast processing + - net: dsa: fix phylink_start()/phylink_stop() calls + - net: dsa: mv88e6xxx: fix lockup on warm boot + - net: fec: validate the new settings in fec_enet_set_coalesce() + - net: hns3: fix a not link up issue when fibre port supports autoneg + - net/ipv6: use configured metric when add peer route + - netlink: Use netlink header as base to calculate bad attribute offset + - net: macsec: update SCI upon MAC address change. + - net: nfc: fix bounds checking bugs on "pipe" + - net/packet: tpacket_rcv: do not increment ring index on drop + - net: phy: bcm63xx: fix OOPS due to missing driver name + - net: stmmac: dwmac1000: Disable ACS if enhanced descs are not used + - net: systemport: fix index check to avoid an array out of bounds access + - sfc: detach from cb_page in efx_copy_channel() + - slip: make slhc_compress() more robust against malicious packets + - taprio: Fix sending packets without dequeueing them + - bonding/alb: make sure arp header is pulled before accessing it + - bnxt_en: reinitialize IRQs when MTU is modified + - bnxt_en: fix error handling when flashing from file + - cgroup: memcg: net: do not associate sock with unrelated cgroup + - net: memcg: late association of sock to memcg + - net: memcg: fix lockdep splat in inet_csk_accept() + - devlink: validate length of param values + - devlink: validate length of region addr/len + - fib: add missing attribute validation for tun_id + - nl802154: add missing attribute validation + - nl802154: add missing attribute validation for dev_type + - can: add missing attribute validation for termination + - macsec: add missing attribute validation for port + - net: fq: add missing attribute validation for orphan mask + - net: taprio: add missing attribute validation for txtime delay + - team: add missing attribute validation for port ifindex + - team: add missing attribute validation for array index + - tipc: add missing attribute validation for MTU property + - nfc: add missing attribute validation for SE API + - nfc: add missing attribute validation for deactivate target + - nfc: add missing attribute validation for vendor subcommand + - net: phy: avoid clearing PHY interrupts twice in irq handler + - net: phy: fix MDIO bus PM PHY resuming + - net/ipv6: need update peer route when modify metric + - net/ipv6: remove the old peer route if change it to a new one + - selftests/net/fib_tests: update addr_metric_test for peer route testing + - net: dsa: Don't instantiate phylink for CPU/DSA ports unless needed + - net: phy: Avoid multiple suspends + - cgroup: cgroup_procs_next should increase position index + - cgroup: Iterate tasks that did not finish do_exit() + - netfilter: nf_tables: fix infinite loop when expr is not available + - iwlwifi: mvm: Do not require PHY_SKU NVM section for 3168 devices + - iommu/vt-d: quirk_ioat_snb_local_iommu: replace WARN_TAINT with pr_warn + + add_taint + - netfilter: nf_conntrack: ct_cpu_seq_next should increase position index + - netfilter: synproxy: synproxy_cpu_seq_next should increase position index + - netfilter: xt_recent: recent_seq_next should increase position index + - netfilter: x_tables: xt_mttg_seq_next should increase position index + - workqueue: don't use wq_select_unbound_cpu() for bound works + - drm/amd/display: remove duplicated assignment to grph_obj_type + - drm/i915: be more solid in checking the alignment + - drm/i915: Defer semaphore priority bumping to a workqueue + - mmc: sdhci-pci-gli: Enable MSI interrupt for GL975x + - pinctrl: falcon: fix syntax error + - ktest: Add timeout for ssh sync testing + - cifs_atomic_open(): fix double-put on late allocation failure + - gfs2_atomic_open(): fix O_EXCL|O_CREAT handling on cold dcache + - KVM: x86: clear stale x86_emulate_ctxt->intercept value + - KVM: nVMX: avoid NULL pointer dereference with incorrect EVMCS GPAs + - ARC: define __ALIGN_STR and __ALIGN symbols for ARC + - fuse: fix stack use after return + - s390/dasd: fix data corruption for thin provisioned devices + - ipmi_si: Avoid spurious errors for optional IRQs + - blk-iocost: fix incorrect vtime comparison in iocg_is_idle() + - fscrypt: don't evict dirty inodes after removing key + - macintosh: windfarm: fix MODINFO regression + - x86/ioremap: Map EFI runtime services data as encrypted for SEV + - efi: Fix a race and a buffer overflow while reading efivars via sysfs + - efi: Add a sanity check to efivar_store_raw() + - i2c: designware-pci: Fix BUG_ON during device removal + - mt76: fix array overflow on receiving too many fragments for a packet + - perf/amd/uncore: Replace manual sampling check with CAP_NO_INTERRUPT flag + - x86/mce: Fix logic and comments around MSR_PPIN_CTL + - iommu/dma: Fix MSI reservation allocation + - iommu/vt-d: dmar: replace WARN_TAINT with pr_warn + add_taint + - iommu/vt-d: Fix RCU list debugging warnings + - iommu/vt-d: Fix a bug in intel_iommu_iova_to_phys() for huge page + - batman-adv: Don't schedule OGM for disabled interface + - clk: imx8mn: Fix incorrect clock defines + - pinctrl: meson-gxl: fix GPIOX sdio pins + - pinctrl: imx: scu: Align imx sc msg structs to 4 + - virtio_ring: Fix mem leak with vring_new_virtqueue() + - drm/i915/gvt: Fix dma-buf display blur issue on CFL + - pinctrl: core: Remove extra kref_get which blocks hogs being freed + - drm/i915/gvt: Fix unnecessary schedule timer when no vGPU exits + - driver code: clarify and fix platform device DMA mask allocation + - iommu/vt-d: Fix RCU-list bugs in intel_iommu_init() + - i2c: gpio: suppress error on probe defer + - nl80211: add missing attribute validation for critical protocol indication + - nl80211: add missing attribute validation for beacon report scanning + - nl80211: add missing attribute validation for channel switch + - perf bench futex-wake: Restore thread count default to online CPU count + - netfilter: cthelper: add missing attribute validation for cthelper + - netfilter: nft_payload: add missing attribute validation for payload csum + flags + - netfilter: nft_tunnel: add missing attribute validation for tunnels + - netfilter: nf_tables: dump NFTA_CHAIN_FLAGS attribute + - netfilter: nft_chain_nat: inet family is missing module ownership + - iommu/vt-d: Fix the wrong printing in RHSA parsing + - iommu/vt-d: Ignore devices with out-of-spec domain number + - i2c: acpi: put device when verifying client fails + - iommu/amd: Fix IOMMU AVIC not properly update the is_run bit in IRTE + - ipv6: restrict IPV6_ADDRFORM operation + - net/smc: check for valid ib_client_data + - net/smc: cancel event worker during device removal + - Linux 5.4.26 + * please help enable CONFIG_EROFS_FS_ZIP (LP: #1867099) + - [Config] CONFIG_EROFS_FS_ZIP=y + - [Config] CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1 + * All PS/2 ports on PS/2 Serial add-in bracket are not working after S3 + (LP: #1866734) + - SAUCE: Input: i8042 - fix the selftest retry logic + * [UBUNTU 20.04] virtio-blk disks can go dissfunctional when swiotlb fills up + (LP: #1867109) + - virtio-blk: fix hw_queue stopped on arbitrary error + - virtio-blk: improve virtqueue error to BLK_STS + * Focal update: v5.4.25 upstream stable release (LP: #1867178) + - block, bfq: get extra ref to prevent a queue from being freed during a group + move + - block, bfq: do not insert oom queue into position tree + - net: dsa: bcm_sf2: Forcibly configure IMP port for 1Gb/sec + - net: stmmac: fix notifier registration + - dm thin metadata: fix lockdep complaint + - RDMA/core: Fix pkey and port assignment in get_new_pps + - RDMA/core: Fix use of logical OR in get_new_pps + - kbuild: fix 'No such file or directory' warning when cleaning + - kprobes: Fix optimize_kprobe()/unoptimize_kprobe() cancellation logic + - blktrace: fix dereference after null check + - ALSA: hda: do not override bus codec_mask in link_get() + - serial: ar933x_uart: set UART_CS_{RX,TX}_READY_ORIDE + - selftests: fix too long argument + - usb: gadget: composite: Support more than 500mA MaxPower + - usb: gadget: ffs: ffs_aio_cancel(): Save/restore IRQ flags + - usb: gadget: serial: fix Tx stall after buffer overflow + - habanalabs: halt the engines before hard-reset + - habanalabs: do not halt CoreSight during hard reset + - habanalabs: patched cb equals user cb in device memset + - drm/msm/mdp5: rate limit pp done timeout warnings + - drm: msm: Fix return type of dsi_mgr_connector_mode_valid for kCFI + - drm/modes: Make sure to parse valid rotation value from cmdline + - drm/modes: Allow DRM_MODE_ROTATE_0 when applying video mode parameters + - scsi: megaraid_sas: silence a warning + - drm/msm/dsi: save pll state before dsi host is powered off + - drm/msm/dsi/pll: call vco set rate explicitly + - selftests: forwarding: use proto icmp for {gretap, ip6gretap}_mac testing + - selftests: forwarding: vxlan_bridge_1d: fix tos value + - net: atlantic: check rpc result and wait for rpc address + - net: ks8851-ml: Remove 8-bit bus accessors + - net: ks8851-ml: Fix 16-bit data access + - net: ks8851-ml: Fix 16-bit IO operation + - net: ethernet: dm9000: Handle -EPROBE_DEFER in dm9000_parse_dt() + - watchdog: da9062: do not ping the hw during stop() + - s390/cio: cio_ignore_proc_seq_next should increase position index + - s390: make 'install' not depend on vmlinux + - efi: Only print errors about failing to get certs if EFI vars are found + - net/mlx5: DR, Fix matching on vport gvmi + - nvme/pci: Add sleep quirk for Samsung and Toshiba drives + - nvme-pci: Use single IRQ vector for old Apple models + - x86/boot/compressed: Don't declare __force_order in kaslr_64.c + - s390/qdio: fill SL with absolute addresses + - nvme: Fix uninitialized-variable warning + - ice: Don't tell the OS that link is going down + - x86/xen: Distribute switch variables for initialization + - net: thunderx: workaround BGX TX Underflow issue + - csky/mm: Fixup export invalid_pte_table symbol + - csky: Set regs->usp to kernel sp, when the exception is from kernel + - csky/smp: Fixup boot failed when CONFIG_SMP + - csky: Fixup ftrace modify panic + - csky: Fixup compile warning for three unimplemented syscalls + - arch/csky: fix some Kconfig typos + - selftests: forwarding: vxlan_bridge_1d: use more proper tos value + - firmware: imx: scu: Ensure sequential TX + - binder: prevent UAF for binderfs devices + - binder: prevent UAF for binderfs devices II + - ALSA: hda/realtek - Add Headset Mic supported + - ALSA: hda/realtek - Add Headset Button supported for ThinkPad X1 + - ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master + - ALSA: hda/realtek - Enable the headset of ASUS B9450FA with ALC294 + - cifs: don't leak -EAGAIN for stat() during reconnect + - cifs: fix rename() by ensuring source handle opened with DELETE bit + - usb: storage: Add quirk for Samsung Fit flash + - usb: quirks: add NO_LPM quirk for Logitech Screen Share + - usb: dwc3: gadget: Update chain bit correctly when using sg list + - usb: cdns3: gadget: link trb should point to next request + - usb: cdns3: gadget: toggle cycle bit before reset endpoint + - usb: core: hub: fix unhandled return by employing a void function + - usb: core: hub: do error out if usb_autopm_get_interface() fails + - usb: core: port: do error out if usb_autopm_get_interface() fails + - vgacon: Fix a UAF in vgacon_invert_region + - mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking + page tables prot_numa + - mm: fix possible PMD dirty bit lost in set_pmd_migration_entry() + - mm, hotplug: fix page online with DEBUG_PAGEALLOC compiled but not enabled + - fat: fix uninit-memory access for partial initialized inode + - btrfs: fix RAID direct I/O reads with alternate csums + - arm64: dts: socfpga: agilex: Fix gmac compatible + - arm: dts: dra76x: Fix mmc3 max-frequency + - tty:serial:mvebu-uart:fix a wrong return + - tty: serial: fsl_lpuart: free IDs allocated by IDA + - serial: 8250_exar: add support for ACCES cards + - vt: selection, close sel_buffer race + - vt: selection, push console lock down + - vt: selection, push sel_lock up + - media: hantro: Fix broken media controller links + - media: mc-entity.c: use & to check pad flags, not == + - media: vicodec: process all 4 components for RGB32 formats + - media: v4l2-mem2mem.c: fix broken links + - perf intel-pt: Fix endless record after being terminated + - perf intel-bts: Fix endless record after being terminated + - perf cs-etm: Fix endless record after being terminated + - perf arm-spe: Fix endless record after being terminated + - spi: spidev: Fix CS polarity if GPIO descriptors are used + - x86/pkeys: Manually set X86_FEATURE_OSPKE to preserve existing changes + - s390/pci: Fix unexpected write combine on resource + - s390/mm: fix panic in gup_fast on large pud + - dmaengine: imx-sdma: fix context cache + - dmaengine: imx-sdma: Fix the event id check to include RX event for UART6 + - dmaengine: tegra-apb: Fix use-after-free + - dmaengine: tegra-apb: Prevent race conditions of tasklet vs free list + - dm integrity: fix recalculation when moving from journal mode to bitmap mode + - dm integrity: fix a deadlock due to offloading to an incorrect workqueue + - dm integrity: fix invalid table returned due to argument count mismatch + - dm cache: fix a crash due to incorrect work item cancelling + - dm: report suspended device during destroy + - dm writecache: verify watermark during resume + - dm zoned: Fix reference counter initial value of chunk works + - dm: fix congested_fn for request-based device + - arm64: dts: meson-sm1-sei610: add missing interrupt-names + - ARM: dts: ls1021a: Restore MDIO compatible to gianfar + - spi: bcm63xx-hsspi: Really keep pll clk enabled + - drm/virtio: make resource id workaround runtime switchable. + - drm/virtio: fix resource id creation race + - ASoC: topology: Fix memleak in soc_tplg_link_elems_load() + - ASoC: topology: Fix memleak in soc_tplg_manifest_load() + - ASoC: SOF: Fix snd_sof_ipc_stream_posn() + - ASoC: intel: skl: Fix pin debug prints + - ASoC: intel: skl: Fix possible buffer overflow in debug outputs + - powerpc: define helpers to get L1 icache sizes + - powerpc: Convert flush_icache_range & friends to C + - powerpc/mm: Fix missing KUAP disable in flush_coherent_icache() + - ASoC: pcm: Fix possible buffer overflow in dpcm state sysfs output + - ASoC: pcm512x: Fix unbalanced regulator enable call in probe error path + - ASoC: Intel: Skylake: Fix available clock counter incrementation + - ASoC: dapm: Correct DAPM handling of active widgets during shutdown + - spi: atmel-quadspi: fix possible MMIO window size overrun + - drm/panfrost: Don't try to map on error faults + - drm: kirin: Revert "Fix for hikey620 display offset problem" + - drm/sun4i: Add separate DE3 VI layer formats + - drm/sun4i: Fix DE2 VI layer format support + - drm/sun4i: de2/de3: Remove unsupported VI layer formats + - drm/i915: Program MBUS with rmw during initialization + - drm/i915/selftests: Fix return in assert_mmap_offset() + - phy: mapphone-mdm6600: Fix timeouts by adding wake-up handling + - phy: mapphone-mdm6600: Fix write timeouts with shorter GPIO toggle interval + - ARM: dts: imx6: phycore-som: fix emmc supply + - arm64: dts: imx8qxp-mek: Remove unexisting Ethernet PHY + - firmware: imx: misc: Align imx sc msg structs to 4 + - firmware: imx: scu-pd: Align imx sc msg structs to 4 + - firmware: imx: Align imx_sc_msg_req_cpu_start to 4 + - soc: imx-scu: Align imx sc msg structs to 4 + - Revert "RDMA/cma: Simplify rdma_resolve_addr() error flow" + - RDMA/rw: Fix error flow during RDMA context initialization + - RDMA/nldev: Fix crash when set a QP to a new counter but QPN is missing + - RDMA/siw: Fix failure handling during device creation + - RDMA/iwcm: Fix iwcm work deallocation + - RDMA/core: Fix protection fault in ib_mr_pool_destroy + - regulator: stm32-vrefbuf: fix a possible overshoot when re-enabling + - RMDA/cm: Fix missing ib_cm_destroy_id() in ib_cm_insert_listen() + - IB/hfi1, qib: Ensure RCU is locked when accessing list + - ARM: imx: build v7_cpu_resume() unconditionally + - ARM: dts: am437x-idk-evm: Fix incorrect OPP node names + - ARM: dts: dra7xx-clocks: Fixup IPU1 mux clock parent source + - ARM: dts: imx7-colibri: Fix frequency for sd/mmc + - hwmon: (adt7462) Fix an error return in ADT7462_REG_VOLT() + - dma-buf: free dmabuf->name in dma_buf_release() + - dmaengine: coh901318: Fix a double lock bug in dma_tc_handle() + - arm64: dts: meson: fix gxm-khadas-vim2 wifi + - bus: ti-sysc: Fix 1-wire reset quirk + - EDAC/synopsys: Do not print an error with back-to-back snprintf() calls + - powerpc: fix hardware PMU exception bug on PowerVM compatibility mode + systems + - efi/x86: Align GUIDs to their size in the mixed mode runtime wrapper + - efi/x86: Handle by-ref arguments covering multiple pages in mixed mode + - efi: READ_ONCE rng seed size before munmap + - block, bfq: get a ref to a group when adding it to a service tree + - block, bfq: remove ifdefs from around gets/puts of bfq groups + - csky: Implement copy_thread_tls + - drm/virtio: module_param_named() requires linux/moduleparam.h + - Linux 5.4.25 + * Miscellaneous Ubuntu changes + - hio -- remove duplicated MODULE_DEVICE_TABLE declaration + - [Config] Add initial riscv64 config + - [Config] Bring riscv64 in line with other arches + - [Packaging] Add riscv64 arch support + - [Packaging] Add initial riscv64 abi + - [Config] updateconfigs for riscv64 + - [Config] Update annotations for riscv64 + - SAUCE: r8169: disable ASPM L1.1 + - update wireguard dkms package version + - [Config] garbage collect PCIEASPM_DEBUG + - [Config] gcc version updateconfigs + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: platform/x86: dell-uart-backlight: move retry block" + - RISC-V: Do not invoke SBI call if cpumask is empty + - RISC-V: Issue a local tlbflush if possible. + - RISC-V: Issue a tlb page flush if possible + - riscv: add support for SECCOMP and SECCOMP_FILTER + - riscv: reject invalid syscalls below -1 + - mtd: spi-nor: Add support for is25wp256 + - PCI/ASPM: Remove PCIEASPM_DEBUG Kconfig option and related code + + -- Paolo Pisati Tue, 24 Mar 2020 11:40:50 +0100 + +linux-oracle (5.4.0-1005.5) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1005.5 -proposed tracker (LP: #1866487) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following Ubuntu-5.4.0-18.22 rebase + + [ Ubuntu: 5.4.0-18.22 ] + + * focal/linux: 5.4.0-18.22 -proposed tracker (LP: #1866488) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + * Add sysfs attribute to show remapped NVMe (LP: #1863621) + - SAUCE: ata: ahci: Add sysfs attribute to show remapped NVMe device count + * [20.04 FEAT] Compression improvements in Linux kernel (LP: #1830208) + - lib/zlib: add s390 hardware support for kernel zlib_deflate + - s390/boot: rename HEAP_SIZE due to name collision + - lib/zlib: add s390 hardware support for kernel zlib_inflate + - s390/boot: add dfltcc= kernel command line parameter + - lib/zlib: add zlib_deflate_dfltcc_enabled() function + - btrfs: use larger zlib buffer for s390 hardware compression + - [Config] Introducing s390x specific kernel config option CONFIG_ZLIB_DFLTCC + * [UBUNTU 20.04] s390x/pci: increase CONFIG_PCI_NR_FUNCTIONS to 512 in kernel + config (LP: #1866056) + - [Config] Increase CONFIG_PCI_NR_FUNCTIONS from 64 to 512 starting with focal + on s390x + * CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set (LP: #1865332) + - [Config] CONFIG_IP_MROUTE_MULTIPLE_TABLES=y + * Dell XPS 13 9300 Intel 1650S wifi [34f0:1651] fails to load firmware + (LP: #1865962) + - iwlwifi: remove IWL_DEVICE_22560/IWL_DEVICE_FAMILY_22560 + - iwlwifi: 22000: fix some indentation + - iwlwifi: pcie: rx: use rxq queue_size instead of constant + - iwlwifi: allocate more receive buffers for HE devices + - iwlwifi: remove some outdated iwl22000 configurations + - iwlwifi: assume the driver_data is a trans_cfg, but allow full cfg + * [FOCAL][REGRESSION] Intel Gen 9 brightness cannot be controlled + (LP: #1861521) + - Revert "USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision + 4K sku" + - Revert "UBUNTU: SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd + Gen 4K AMOLED panel" + - SAUCE: drm/dp: Introduce EDID-based quirks + - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED + panel + - SAUCE: drm/i915: Force DPCD backlight mode for some Dell CML 2020 panels + * [20.04 FEAT] Enable proper kprobes on ftrace support (LP: #1865858) + - s390/ftrace: save traced function caller + - s390: support KPROBES_ON_FTRACE + * alsa/sof: load different firmware on different platforms (LP: #1857409) + - ASoC: SOF: Intel: hda: use fallback for firmware name + - ASoC: Intel: acpi-match: split CNL tables in three + - ASoC: SOF: Intel: Fix CFL and CML FW nocodec binary names. + * [UBUNTU 20.04] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x + starting with focal (LP: #1865452) + - [Config] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x starting + with focal + * Focal update: v5.4.24 upstream stable release (LP: #1866333) + - io_uring: grab ->fs as part of async offload + - EDAC: skx_common: downgrade message importance on missing PCI device + - net: dsa: b53: Ensure the default VID is untagged + - net: fib_rules: Correctly set table field when table number exceeds 8 bits + - net: macb: ensure interface is not suspended on at91rm9200 + - net: mscc: fix in frame extraction + - net: phy: restore mdio regs in the iproc mdio driver + - net: sched: correct flower port blocking + - net/tls: Fix to avoid gettig invalid tls record + - nfc: pn544: Fix occasional HW initialization failure + - qede: Fix race between rdma destroy workqueue and link change event + - Revert "net: dev: introduce support for sch BYPASS for lockless qdisc" + - udp: rehash on disconnect + - sctp: move the format error check out of __sctp_sf_do_9_1_abort + - bnxt_en: Improve device shutdown method. + - bnxt_en: Issue PCIe FLR in kdump kernel to cleanup pending DMAs. + - bonding: add missing netdev_update_lockdep_key() + - net: export netdev_next_lower_dev_rcu() + - bonding: fix lockdep warning in bond_get_stats() + - ipv6: Fix route replacement with dev-only route + - ipv6: Fix nlmsg_flags when splitting a multipath route + - ipmi:ssif: Handle a possible NULL pointer reference + - drm/msm: Set dma maximum segment size for mdss + - sched/core: Don't skip remote tick for idle CPUs + - timers/nohz: Update NOHZ load in remote tick + - sched/fair: Prevent unlimited runtime on throttled group + - dax: pass NOWAIT flag to iomap_apply + - mac80211: consider more elements in parsing CRC + - cfg80211: check wiphy driver existence for drvinfo report + - s390/zcrypt: fix card and queue total counter wrap + - qmi_wwan: re-add DW5821e pre-production variant + - qmi_wwan: unconditionally reject 2 ep interfaces + - NFSv4: Fix races between open and dentry revalidation + - perf/smmuv3: Use platform_get_irq_optional() for wired interrupt + - perf/x86/intel: Add Elkhart Lake support + - perf/x86/cstate: Add Tremont support + - perf/x86/msr: Add Tremont support + - ceph: do not execute direct write in parallel if O_APPEND is specified + - ARM: dts: sti: fixup sound frame-inversion for stihxxx-b2120.dtsi + - drm/amd/display: Do not set optimized_require to false after plane disable + - RDMA/siw: Remove unwanted WARN_ON in siw_cm_llp_data_ready() + - drm/amd/display: Check engine is not NULL before acquiring + - drm/amd/display: Limit minimum DPPCLK to 100MHz. + - drm/amd/display: Add initialitions for PLL2 clock source + - amdgpu: Prevent build errors regarding soft/hard-float FP ABI tags + - soc/tegra: fuse: Fix build with Tegra194 configuration + - i40e: Fix the conditional for i40e_vc_validate_vqs_bitmaps + - net: ena: fix potential crash when rxfh key is NULL + - net: ena: fix uses of round_jiffies() + - net: ena: add missing ethtool TX timestamping indication + - net: ena: fix incorrect default RSS key + - net: ena: rss: do not allocate key when not supported + - net: ena: rss: fix failure to get indirection table + - net: ena: rss: store hash function as values and not bits + - net: ena: fix incorrectly saving queue numbers when setting RSS indirection + table + - net: ena: fix corruption of dev_idx_to_host_tbl + - net: ena: ethtool: use correct value for crc32 hash + - net: ena: ena-com.c: prevent NULL pointer dereference + - ice: update Unit Load Status bitmask to check after reset + - cifs: Fix mode output in debugging statements + - cfg80211: add missing policy for NL80211_ATTR_STATUS_CODE + - mac80211: fix wrong 160/80+80 MHz setting + - nvme/tcp: fix bug on double requeue when send fails + - nvme: prevent warning triggered by nvme_stop_keep_alive + - nvme/pci: move cqe check after device shutdown + - ext4: potential crash on allocation error in ext4_alloc_flex_bg_array() + - audit: fix error handling in audit_data_to_entry() + - audit: always check the netlink payload length in audit_receive_msg() + - ACPICA: Introduce ACPI_ACCESS_BYTE_WIDTH() macro + - ACPI: watchdog: Fix gas->access_width usage + - KVM: VMX: check descriptor table exits on instruction emulation + - HID: ite: Only bind to keyboard USB interface on Acer SW5-012 keyboard dock + - HID: core: fix off-by-one memset in hid_report_raw_event() + - HID: core: increase HID report buffer size to 8KiB + - drm/amdgpu: Drop DRIVER_USE_AGP + - drm/radeon: Inline drm_get_pci_dev + - macintosh: therm_windtunnel: fix regression when instantiating devices + - tracing: Disable trace_printk() on post poned tests + - Revert "PM / devfreq: Modify the device name as devfreq(X) for sysfs" + - amdgpu/gmc_v9: save/restore sdpif regs during S3 + - cpufreq: Fix policy initialization for internal governor drivers + - io_uring: fix 32-bit compatability with sendmsg/recvmsg + - netfilter: ipset: Fix "INFO: rcu detected stall in hash_xxx" reports + - net/smc: transfer fasync_list in case of fallback + - vhost: Check docket sk_family instead of call getname + - netfilter: ipset: Fix forceadd evaluation path + - netfilter: xt_hashlimit: reduce hashlimit_mutex scope for htable_put() + - HID: alps: Fix an error handling path in 'alps_input_configured()' + - HID: hiddev: Fix race in in hiddev_disconnect() + - MIPS: VPE: Fix a double free and a memory leak in 'release_vpe()' + - i2c: altera: Fix potential integer overflow + - i2c: jz4780: silence log flood on txabrt + - drm/i915/gvt: Fix orphan vgpu dmabuf_objs' lifetime + - drm/i915/gvt: Separate display reset from ALL_ENGINES reset + - nl80211: fix potential leak in AP start + - mac80211: Remove a redundant mutex unlock + - kbuild: fix DT binding schema rule to detect command line changes + - hv_netvsc: Fix unwanted wakeup in netvsc_attach() + - usb: charger: assign specific number for enum value + - nvme-pci: Hold cq_poll_lock while completing CQEs + - s390/qeth: vnicc Fix EOPNOTSUPP precedence + - net: netlink: cap max groups which will be considered in netlink_bind() + - net: atlantic: fix use after free kasan warn + - net: atlantic: fix potential error handling + - net: atlantic: fix out of range usage of active_vlans array + - net/smc: no peer ID in CLC decline for SMCD + - net: ena: make ena rxfh support ETH_RSS_HASH_NO_CHANGE + - selftests: Install settings files to fix TIMEOUT failures + - kbuild: remove header compile test + - kbuild: move headers_check rule to usr/include/Makefile + - kbuild: remove unneeded variable, single-all + - kbuild: make single target builds even faster + - namei: only return -ECHILD from follow_dotdot_rcu() + - mwifiex: drop most magic numbers from mwifiex_process_tdls_action_frame() + - mwifiex: delete unused mwifiex_get_intf_num() + - KVM: SVM: Override default MMIO mask if memory encryption is enabled + - KVM: Check for a bad hva before dropping into the ghc slow path + - sched/fair: Optimize select_idle_cpu + - f2fs: fix to add swap extent correctly + - RDMA/hns: Simplify the calculation and usage of wqe idx for post verbs + - RDMA/hns: Bugfix for posting a wqe with sge + - drivers: net: xgene: Fix the order of the arguments of + 'alloc_etherdev_mqs()' + - ima: ima/lsm policy rule loading logic bug fixes + - kprobes: Set unoptimized flag after unoptimizing code + - lib/vdso: Make __arch_update_vdso_data() logic understandable + - lib/vdso: Update coarse timekeeper unconditionally + - pwm: omap-dmtimer: put_device() after of_find_device_by_node() + - perf hists browser: Restore ESC as "Zoom out" of DSO/thread/etc + - perf ui gtk: Add missing zalloc object + - x86/resctrl: Check monitoring static key in the MBM overflow handler + - KVM: x86: Remove spurious kvm_mmu_unload() from vcpu destruction path + - KVM: x86: Remove spurious clearing of async #PF MSR + - rcu: Allow only one expedited GP to run concurrently with wakeups + - ubifs: Fix ino_t format warnings in orphan_delete() + - thermal: db8500: Depromote debug print + - thermal: brcmstb_thermal: Do not use DT coefficients + - netfilter: nft_tunnel: no need to call htons() when dumping ports + - netfilter: nf_flowtable: fix documentation + - bus: tegra-aconnect: Remove PM_CLK dependency + - xfs: clear kernel only flags in XFS_IOC_ATTRMULTI_BY_HANDLE + - locking/lockdep: Fix lockdep_stats indentation problem + - mm/debug.c: always print flags in dump_page() + - mm/gup: allow FOLL_FORCE for get_user_pages_fast() + - mm/huge_memory.c: use head to check huge zero page + - mm, thp: fix defrag setting if newline is not used + - kvm: nVMX: VMWRITE checks VMCS-link pointer before VMCS field + - kvm: nVMX: VMWRITE checks unsupported field before read-only field + - blktrace: Protect q->blk_trace with RCU + - Linux 5.4.24 + * Focal update: v5.4.23 upstream stable release (LP: #1866165) + - iommu/qcom: Fix bogus detach logic + - ALSA: hda: Use scnprintf() for printing texts for sysfs/procfs + - ALSA: hda/realtek - Apply quirk for MSI GP63, too + - ALSA: hda/realtek - Apply quirk for yet another MSI laptop + - ASoC: codec2codec: avoid invalid/double-free of pcm runtime + - ASoC: sun8i-codec: Fix setting DAI data format + - tpm: Initialize crypto_id of allocated_banks to HASH_ALGO__LAST + - ecryptfs: fix a memory leak bug in parse_tag_1_packet() + - ecryptfs: fix a memory leak bug in ecryptfs_init_messaging() + - btrfs: handle logged extent failure properly + - thunderbolt: Prevent crash if non-active NVMem file is read + - USB: misc: iowarrior: add support for 2 OEMed devices + - USB: misc: iowarrior: add support for the 28 and 28L devices + - USB: misc: iowarrior: add support for the 100 device + - e1000e: Use rtnl_lock to prevent race conditions between net and pci/pm + - floppy: check FDC index for errors before assigning it + - vt: fix scrollback flushing on background consoles + - vt: selection, handle pending signals in paste_selection + - vt: vt_ioctl: fix race in VT_RESIZEX + - staging: android: ashmem: Disallow ashmem memory from being remapped + - staging: vt6656: fix sign of rx_dbm to bb_pre_ed_rssi. + - xhci: Force Maximum Packet size for Full-speed bulk devices to valid range. + - xhci: fix runtime pm enabling for quirky Intel hosts + - xhci: apply XHCI_PME_STUCK_QUIRK to Intel Comet Lake platforms + - xhci: Fix memory leak when caching protocol extended capability PSI tables - + take 2 + - usb: host: xhci: update event ring dequeue pointer on purpose + - USB: core: add endpoint-blacklist quirk + - USB: quirks: blacklist duplicate ep on Sound Devices USBPre2 + - usb: uas: fix a plug & unplug racing + - USB: Fix novation SourceControl XL after suspend + - USB: hub: Don't record a connect-change event during reset-resume + - USB: hub: Fix the broken detection of USB3 device in SMSC hub + - usb: dwc2: Fix SET/CLEAR_FEATURE and GET_STATUS flows + - usb: dwc3: gadget: Check for IOC/LST bit in TRB->ctrl fields + - usb: dwc3: debug: fix string position formatting mixup with ret and len + - scsi: Revert "target/core: Inline transport_lun_remove_cmd()" + - staging: rtl8188eu: Fix potential security hole + - staging: rtl8188eu: Fix potential overuse of kernel memory + - staging: rtl8723bs: Fix potential security hole + - staging: rtl8723bs: Fix potential overuse of kernel memory + - drm/panfrost: perfcnt: Reserve/use the AS attached to the perfcnt MMU + context + - powerpc/8xx: Fix clearing of bits 20-23 in ITLB miss + - powerpc/eeh: Fix deadlock handling dead PHB + - powerpc/tm: Fix clearing MSR[TS] in current when reclaiming on signal + delivery + - powerpc/entry: Fix an #if which should be an #ifdef in entry_32.S + - powerpc/hugetlb: Fix 512k hugepages on 8xx with 16k page size + - powerpc/hugetlb: Fix 8M hugepages on 8xx + - arm64: memory: Add missing brackets to untagged_addr() macro + - jbd2: fix ocfs2 corrupt when clearing block group bits + - x86/ima: use correct identifier for SetupMode variable + - x86/mce/amd: Publish the bank pointer only after setup has succeeded + - x86/mce/amd: Fix kobject lifetime + - x86/cpu/amd: Enable the fixed Instructions Retired counter IRPERF + - serial: 8250: Check UPF_IRQ_SHARED in advance + - tty/serial: atmel: manage shutdown in case of RS485 or ISO7816 mode + - tty: serial: imx: setup the correct sg entry for tx dma + - tty: serial: qcom_geni_serial: Fix RX cancel command failure + - serdev: ttyport: restore client ops on deregistration + - MAINTAINERS: Update drm/i915 bug filing URL + - ACPI: PM: s2idle: Check fixed wakeup events in acpi_s2idle_wake() + - mm/memcontrol.c: lost css_put in memcg_expand_shrinker_maps() + - nvme-multipath: Fix memory leak with ana_log_buf + - genirq/irqdomain: Make sure all irq domain flags are distinct + - mm/vmscan.c: don't round up scan size for online memory cgroup + - mm/sparsemem: pfn_to_page is not valid yet on SPARSEMEM + - lib/stackdepot.c: fix global out-of-bounds in stack_slabs + - mm: Avoid creating virtual address aliases in brk()/mmap()/mremap() + - drm/amdgpu/soc15: fix xclk for raven + - drm/amdgpu/gfx9: disable gfxoff when reading rlc clock + - drm/amdgpu/gfx10: disable gfxoff when reading rlc clock + - drm/nouveau/kms/gv100-: Re-set LUT after clearing for modesets + - drm/i915: Wean off drm_pci_alloc/drm_pci_free + - drm/i915: Update drm/i915 bug filing URL + - sched/psi: Fix OOB write when writing 0 bytes to PSI files + - KVM: nVMX: Don't emulate instructions in guest mode + - KVM: x86: don't notify userspace IOAPIC on edge-triggered interrupt EOI + - ext4: fix a data race in EXT4_I(inode)->i_disksize + - ext4: add cond_resched() to __ext4_find_entry() + - ext4: fix potential race between online resizing and write operations + - ext4: fix potential race between s_group_info online resizing and access + - ext4: fix potential race between s_flex_groups online resizing and access + - ext4: fix mount failure with quota configured as module + - ext4: rename s_journal_flag_rwsem to s_writepages_rwsem + - ext4: fix race between writepages and enabling EXT4_EXTENTS_FL + - KVM: nVMX: Refactor IO bitmap checks into helper function + - KVM: nVMX: Check IO instruction VM-exit conditions + - KVM: nVMX: clear PIN_BASED_POSTED_INTR from nested pinbased_ctls only when + apicv is globally disabled + - KVM: nVMX: handle nested posted interrupts when apicv is disabled for L1 + - KVM: apic: avoid calculating pending eoi from an uninitialized val + - btrfs: destroy qgroup extent records on transaction abort + - btrfs: fix bytes_may_use underflow in prealloc error condtition + - btrfs: reset fs_root to NULL on error in open_ctree + - btrfs: do not check delayed items are empty for single transaction cleanup + - Btrfs: fix btrfs_wait_ordered_range() so that it waits for all ordered + extents + - Btrfs: fix race between shrinking truncate and fiemap + - btrfs: don't set path->leave_spinning for truncate + - Btrfs: fix deadlock during fast fsync when logging prealloc extents beyond + eof + - Revert "dmaengine: imx-sdma: Fix memory leak" + - drm/i915/gvt: more locking for ppgtt mm LRU list + - drm/bridge: tc358767: fix poll timeouts + - drm/i915/gt: Protect defer_request() from new waiters + - drm/msm/dpu: fix BGR565 vs RGB565 confusion + - scsi: Revert "RDMA/isert: Fix a recently introduced regression related to + logout" + - scsi: Revert "target: iscsi: Wait for all commands to finish before freeing + a session" + - usb: gadget: composite: Fix bMaxPower for SuperSpeedPlus + - usb: dwc2: Fix in ISOC request length checking + - staging: rtl8723bs: fix copy of overlapping memory + - staging: greybus: use after free in gb_audio_manager_remove_all() + - ASoC: atmel: fix atmel_ssc_set_audio link failure + - ASoC: fsl_sai: Fix exiting path on probing failure + - ecryptfs: replace BUG_ON with error handling code + - iommu/vt-d: Fix compile warning from intel-svm.h + - crypto: rename sm3-256 to sm3 in hash_algo_name + - genirq/proc: Reject invalid affinity masks (again) + - bpf, offload: Replace bitwise AND by logical AND in + bpf_prog_offload_info_fill + - arm64: lse: Fix LSE atomics with LLVM + - io_uring: fix __io_iopoll_check deadlock in io_sq_thread + - ALSA: rawmidi: Avoid bit fields for state flags + - ALSA: seq: Avoid concurrent access to queue flags + - ALSA: seq: Fix concurrent access to queue current tick/time + - netfilter: xt_hashlimit: limit the max size of hashtable + - rxrpc: Fix call RCU cleanup using non-bh-safe locks + - io_uring: prevent sq_thread from spinning when it should stop + - ata: ahci: Add shutdown to freeze hardware resources of ahci + - xen: Enable interrupts when calling _cond_resched() + - net/mlx5e: Reset RQ doorbell counter before moving RQ state from RST to RDY + - net/mlx5: Fix sleep while atomic in mlx5_eswitch_get_vepa + - net/mlx5e: Fix crash in recovery flow without devlink reporter + - s390/kaslr: Fix casts in get_random + - s390/mm: Explicitly compare PAGE_DEFAULT_KEY against zero in + storage_key_init_range + - bpf: Selftests build error in sockmap_basic.c + - ASoC: SOF: Intel: hda: Add iDisp4 DAI + - Linux 5.4.23 + * Miscellaneous Ubuntu changes + - SAUCE: selftests/net -- disable timeout + - SAUCE: selftests/net -- disable l2tp.sh test + - SAUCE: selftests/ftrace: Use printf instead of echo in kprobe syntax error + tests + - SAUCE: selftests/powerpc -- Disable timeout for benchmark and tm tests + - SAUCE: selftests/ftrace: Escape additional strings in kprobe syntax error + tests + - SAUCE: Revert "UBUNTU: SAUCE: blk/core: Gracefully handle unset + make_request_fn" + - [Packaging] prevent duplicated entries in modules.ignore + - update dkms package versions + + -- Paolo Pisati Mon, 09 Mar 2020 12:16:41 +0100 + +linux-oracle (5.4.0-1004.4) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1004.4 -proposed tracker (LP: #1865024) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.4.0-17.21 ] + + * focal/linux: 5.4.0-17.20 -proposed tracker (LP: #1865025) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Miscellaneous Ubuntu changes + - SAUCE: drm/i915/execlists: fix off by one in execlists_update_context() + + [ Ubuntu: 5.4.0-16.19 ] + + * focal/linux: 5.4.0-16.19 -proposed tracker (LP: #1864889) + * system hang: i915 Resetting rcs0 for hang on rcs0 (LP: #1861395) + - drm/i915/execlists: Always force a context reload when rewinding RING_TAIL + * nsleep-lat / set-timer-lat / inconsistency-check / raw_skew from timer in + ubuntu_kernel_selftests timeout on 5.3 / 5.4 (LP: #1864626) + - selftests/timers: Turn off timeout setting + * [sfc-0121]enable the HiSilicon v3xx SFC driver (LP: #1860401) + - spi: Add HiSilicon v3xx SPI NOR flash controller driver + - MAINTAINERS: Add a maintainer for the HiSilicon v3xx SFC driver + - [Config] CONFIG_SPI_HISI_SFC_V3XX=m + * [hns3-0217]sync mainline kernel 5.6rc1 hns3 patchset into ubuntu HWE kernel + branch (LP: #1863575) + - net: hns3: add management table after IMP reset + - net: hns3: fix VF bandwidth does not take effect in some case + - net: hns3: fix a copying IPv6 address error in hclge_fd_get_flow_tuples() + * [hns3-0111]sync mainline kernel 5.5rc6 hns3 patchset into ubuntu HWE kernel + branch Edit (LP: #1859261) + - net: hns3: schedule hclgevf_service by using delayed workqueue + - net: hns3: remove mailbox and reset work in hclge_main + - net: hns3: remove unnecessary work in hclgevf_main + - net: hns3: allocate WQ with WQ_MEM_RECLAIM flag + - net: hns3: do not schedule the periodic task when reset fail + - net: hns3: check FE bit before calling hns3_add_frag() + - net: hns3: remove useless mutex vport_cfg_mutex in the struct hclge_dev + - net: hns3: optimization for CMDQ uninitialization + - net: hns3: get FD rules location before dump in debugfs + - net: hns3: implement ndo_features_check ops for hns3 driver + - net: hns3: add some VF VLAN information for command "ip link show" + - net: hns3: add a log for getting chain failure in + hns3_nic_uninit_vector_data() + - net: hns3: only print misc interrupt status when handling fails + - net: hns3: add trace event support for HNS3 driver + - net: hns3: re-organize vector handle + - net: hns3: modify the IRQ name of TQP vector + - net: hns3: modify an unsuitable log in hclge_map_ring_to_vector() + - net: hns3: modify the IRQ name of misc vectors + - net: hns3: add protection when get SFP speed as 0 + - net: hns3: replace an unsuitable variable type in + hclge_inform_reset_assert_to_vf() + - net: hns3: modify an unsuitable reset level for hardware error + - net: hns3: split hclge_reset() into preparing and rebuilding part + - net: hns3: split hclgevf_reset() into preparing and rebuilding part + - net: hns3: refactor the precedure of PF FLR + - net: hns3: refactor the procedure of VF FLR + - net: hns3: enlarge HCLGE_RESET_WAIT_CNT + - net: hns3: modify hclge_func_reset_sync_vf()'s return type to void + - net: hns3: refactor the notification scheme of PF reset + * alsa/hda/realtek: fix a mute led regression on Lenovo X1 Carbon + (LP: #1864576) + - SAUCE: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1 + * ipc/sem.c : process loops infinitely in exit_sem() (LP: #1858834) + - Revert "ipc, sem: remove uneeded sem_undo_list lock usage in exit_sem()" + * r8152 init may take up to 40 seconds at initialization with Dell WD19/WD19DC + during hotplug (LP: #1864284) + - UBUNTU SAUCE: r8151: check disconnect status after long sleep + * Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU for focal + (LP: #1864198) + - Ubuntu: [Config] Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU + * ftrace test in ubuntu_kernel_selftests will timeout randomly (LP: #1864172) + - tracing/selftests: Turn off timeout setting + * Another Dell AIO backlight issue (LP: #1863880) + - SAUCE: platform/x86: dell-uart-backlight: move retry block + * Backport GetFB2 ioctl (LP: #1863874) + - SAUCE: drm: Add getfb2 ioctl + * [20.04] Allow to reset an opencapi adapter (LP: #1862121) + - powerpc/powernv/ioda: Fix ref count for devices with their own PE + - powerpc/powernv/ioda: Protect PE list + - powerpc/powernv/ioda: set up PE on opencapi device when enabling + - powerpc/powernv/ioda: Release opencapi device + - powerpc/powernv/ioda: Find opencapi slot for a device node + - pci/hotplug/pnv-php: Remove erroneous warning + - pci/hotplug/pnv-php: Improve error msg on power state change failure + - pci/hotplug/pnv-php: Register opencapi slots + - pci/hotplug/pnv-php: Relax check when disabling slot + - pci/hotplug/pnv-php: Wrap warnings in macro + - ocxl: Add PCI hotplug dependency to Kconfig + * alsa/asoc: export the number of dmic to userspace to work with the latest + ucm2 (focal) (LP: #1864400) + - ASoC: add control components management + - ASoC: intel/skl/hda - export number of digital microphones via control + components + * alsa/sof: let sof driver work with topology with volume and led control + (focal) (LP: #1864398) + - ASoC: SOF: enable dual control for pga + - AsoC: SOF: refactor control load code + - ASoC: SOF: acpi led support for switch controls + - ASoC: SOF: topology: check errors when parsing LED tokens + * machine doesn't come up after suspend and re-opening the lid (LP: #1861837) + - ASoC: SOF: trace: fix unconditional free in trace release + * 5.3.0-23-generic causes fans to spin when idle (LP: #1853044) + - drm/i915/gt: Close race between engine_park and intel_gt_retire_requests + - drm/i915/gt: Adapt engine_park synchronisation rules for engine_retire + - drm/i915/gt: Schedule request retirement when timeline idles + * Focal update: 5.4.22 upstream stable release (LP: #1864488) + - core: Don't skip generic XDP program execution for cloned SKBs + - enic: prevent waking up stopped tx queues over watchdog reset + - net/smc: fix leak of kernel memory to user space + - net: dsa: tag_qca: Make sure there is headroom for tag + - net/sched: matchall: add missing validation of TCA_MATCHALL_FLAGS + - net/sched: flower: add missing validation of TCA_FLOWER_FLAGS + - drm/gma500: Fixup fbdev stolen size usage evaluation + - ath10k: Fix qmi init error handling + - wil6210: fix break that is never reached because of zero'ing of a retry + counter + - drm/qxl: Complete exception handling in qxl_device_init() + - rcu/nocb: Fix dump_tree hierarchy print always active + - rcu: Fix missed wakeup of exp_wq waiters + - rcu: Fix data-race due to atomic_t copy-by-value + - f2fs: preallocate DIO blocks when forcing buffered_io + - f2fs: call f2fs_balance_fs outside of locked page + - media: meson: add missing allocation failure check on new_buf + - clk: meson: pll: Fix by 0 division in __pll_params_to_rate() + - cpu/hotplug, stop_machine: Fix stop_machine vs hotplug order + - brcmfmac: Fix memory leak in brcmf_p2p_create_p2pdev() + - brcmfmac: Fix use after free in brcmf_sdio_readframes() + - PCI: Fix pci_add_dma_alias() bitmask size + - drm/amd/display: Map ODM memory correctly when doing ODM combine + - leds: pca963x: Fix open-drain initialization + - ext4: fix ext4_dax_read/write inode locking sequence for IOCB_NOWAIT + - ALSA: ctl: allow TLV read operation for callback type of element in locked + case + - gianfar: Fix TX timestamping with a stacked DSA driver + - pinctrl: sh-pfc: sh7264: Fix CAN function GPIOs + - printk: fix exclusive_console replaying + - drm/mipi_dbi: Fix off-by-one bugs in mipi_dbi_blank() + - drm/msm/adreno: fix zap vs no-zap handling + - pxa168fb: Fix the function used to release some memory in an error handling + path + - media: ov5640: Fix check for PLL1 exceeding max allowed rate + - media: i2c: mt9v032: fix enum mbus codes and frame sizes + - media: sun4i-csi: Deal with DRAM offset + - media: sun4i-csi: Fix data sampling polarity handling + - media: sun4i-csi: Fix [HV]sync polarity handling + - clk: at91: sam9x60: fix programmable clock prescaler + - powerpc/powernv/iov: Ensure the pdn for VFs always contains a valid PE + number + - clk: meson: meson8b: make the CCF use the glitch-free mali mux + - gpio: gpio-grgpio: fix possible sleep-in-atomic-context bugs in + grgpio_irq_map/unmap() + - iommu/vt-d: Fix off-by-one in PASID allocation + - x86/fpu: Deactivate FPU state after failure during state load + - char/random: silence a lockdep splat with printk() + - media: sti: bdisp: fix a possible sleep-in-atomic-context bug in + bdisp_device_run() + - kernel/module: Fix memleak in module_add_modinfo_attrs() + - IB/core: Let IB core distribute cache update events + - pinctrl: baytrail: Do not clear IRQ flags on direct-irq enabled pins + - efi/x86: Map the entire EFI vendor string before copying it + - MIPS: Loongson: Fix potential NULL dereference in loongson3_platform_init() + - sparc: Add .exit.data section. + - net: ethernet: ixp4xx: Standard module init + - raid6/test: fix a compilation error + - uio: fix a sleep-in-atomic-context bug in uio_dmem_genirq_irqcontrol() + - drm/amdgpu/sriov: workaround on rev_id for Navi12 under sriov + - spi: fsl-lpspi: fix only one cs-gpio working + - drm/nouveau/nouveau: fix incorrect sizeof on args.src an args.dst + - usb: gadget: udc: fix possible sleep-in-atomic-context bugs in gr_probe() + - usb: dwc2: Fix IN FIFO allocation + - clocksource/drivers/bcm2835_timer: Fix memory leak of timer + - drm/amd/display: Clear state after exiting fixed active VRR state + - kselftest: Minimise dependency of get_size on C library interfaces + - jbd2: clear JBD2_ABORT flag before journal_reset to update log tail info + when load journal + - ext4: fix deadlock allocating bio_post_read_ctx from mempool + - clk: ti: dra7: fix parent for gmac_clkctrl + - x86/sysfb: Fix check for bad VRAM size + - pwm: omap-dmtimer: Simplify error handling + - udf: Allow writing to 'Rewritable' partitions + - dmaengine: fsl-qdma: fix duplicated argument to && + - wan/hdlc_x25: fix skb handling + - powerpc/iov: Move VF pdev fixup into pcibios_fixup_iov() + - tracing: Fix tracing_stat return values in error handling paths + - tracing: Fix very unlikely race of registering two stat tracers + - ARM: 8952/1: Disable kmemleak on XIP kernels + - ext4, jbd2: ensure panic when aborting with zero errno + - ath10k: Correct the DMA direction for management tx buffers + - rtw88: fix rate mask for 1SS chip + - brcmfmac: sdio: Fix OOB interrupt initialization on brcm43362 + - selftests: settings: tests can be in subsubdirs + - rtc: i2c/spi: Avoid inclusion of REGMAP support when not needed + - drm/amd/display: Retrain dongles when SINK_COUNT becomes non-zero + - tracing: Simplify assignment parsing for hist triggers + - nbd: add a flush_workqueue in nbd_start_device + - KVM: s390: ENOTSUPP -> EOPNOTSUPP fixups + - Btrfs: keep pages dirty when using btrfs_writepage_fixup_worker + - drivers/block/zram/zram_drv.c: fix error return codes not being returned in + writeback_store + - block, bfq: do not plug I/O for bfq_queues with no proc refs + - kconfig: fix broken dependency in randconfig-generated .config + - clk: qcom: Don't overwrite 'cfg' in clk_rcg2_dfs_populate_freq() + - clk: qcom: rcg2: Don't crash if our parent can't be found; return an error + - drm/amdkfd: Fix a bug in SDMA RLC queue counting under HWS mode + - bpf, sockhash: Synchronize_rcu before free'ing map + - drm/amdgpu: remove 4 set but not used variable in + amdgpu_atombios_get_connector_info_from_object_table + - ath10k: correct the tlv len of ath10k_wmi_tlv_op_gen_config_pno_start + - drm/amdgpu: Ensure ret is always initialized when using SOC15_WAIT_ON_RREG + - drm/panel: simple: Add Logic PD Type 28 display support + - arm64: dts: rockchip: Fix NanoPC-T4 cooling maps + - modules: lockdep: Suppress suspicious RCU usage warning + - ASoC: intel: sof_rt5682: Add quirk for number of HDMI DAI's + - ASoC: intel: sof_rt5682: Add support for tgl-max98357a-rt5682 + - regulator: rk808: Lower log level on optional GPIOs being not available + - net/wan/fsl_ucc_hdlc: reject muram offsets above 64K + - NFC: port100: Convert cpu_to_le16(le16_to_cpu(E1) + E2) to use + le16_add_cpu(). + - arm64: dts: allwinner: H6: Add PMU mode + - arm64: dts: allwinner: H5: Add PMU node + - arm: dts: allwinner: H3: Add PMU node + - opp: Free static OPPs on errors while adding them + - selinux: ensure we cleanup the internal AVC counters on error in + avc_insert() + - arm64: dts: qcom: msm8996: Disable USB2 PHY suspend by core + - padata: validate cpumask without removed CPU during offline + - clk: imx: Add correct failure handling for clk based helpers + - ARM: exynos_defconfig: Bring back explicitly wanted options + - ARM: dts: imx6: rdu2: Disable WP for USDHC2 and USDHC3 + - ARM: dts: imx6: rdu2: Limit USBH1 to Full Speed + - bus: ti-sysc: Implement quirk handling for CLKDM_NOAUTO + - PCI: iproc: Apply quirk_paxc_bridge() for module as well as built-in + - media: cx23885: Add support for AVerMedia CE310B + - PCI: Add generic quirk for increasing D3hot delay + - PCI: Increase D3 delay for AMD Ryzen5/7 XHCI controllers + - gpu/drm: ingenic: Avoid null pointer deference in plane atomic update + - selftests/net: make so_txtime more robust to timer variance + - media: v4l2-device.h: Explicitly compare grp{id,mask} to zero in v4l2_device + macros + - reiserfs: Fix spurious unlock in reiserfs_fill_super() error handling + - samples/bpf: Set -fno-stack-protector when building BPF programs + - r8169: check that Realtek PHY driver module is loaded + - fore200e: Fix incorrect checks of NULL pointer dereference + - netfilter: nft_tunnel: add the missing ERSPAN_VERSION nla_policy + - ALSA: usx2y: Adjust indentation in snd_usX2Y_hwdep_dsp_status + - PCI: Add nr_devfns parameter to pci_add_dma_alias() + - PCI: Add DMA alias quirk for PLX PEX NTB + - b43legacy: Fix -Wcast-function-type + - ipw2x00: Fix -Wcast-function-type + - iwlegacy: Fix -Wcast-function-type + - rtlwifi: rtl_pci: Fix -Wcast-function-type + - orinoco: avoid assertion in case of NULL pointer + - drm/amdgpu: fix KIQ ring test fail in TDR of SRIOV + - clk: qcom: smd: Add missing bimc clock + - ACPICA: Disassembler: create buffer fields in ACPI_PARSE_LOAD_PASS1 + - nfsd: Clone should commit src file metadata too + - scsi: ufs: Complete pending requests in host reset and restore path + - scsi: aic7xxx: Adjust indentation in ahc_find_syncrate + - crypto: inside-secure - add unspecified HAS_IOMEM dependency + - drm/mediatek: handle events when enabling/disabling crtc + - clk: renesas: rcar-gen3: Allow changing the RPC[D2] clocks + - ARM: dts: r8a7779: Add device node for ARM global timer + - selinux: ensure we cleanup the internal AVC counters on error in + avc_update() + - scsi: lpfc: Fix: Rework setting of fdmi symbolic node name registration + - arm64: dts: qcom: db845c: Enable ath10k 8bit host-cap quirk + - iommu/amd: Check feature support bit before accessing MSI capability + registers + - iommu/amd: Only support x2APIC with IVHD type 11h/40h + - iommu/iova: Silence warnings under memory pressure + - clk: actually call the clock init before any other callback of the clock + - dmaengine: Store module owner in dma_device struct + - dmaengine: imx-sdma: Fix memory leak + - bpf: Print error message for bpftool cgroup show + - net: phy: realtek: add logging for the RGMII TX delay configuration + - crypto: chtls - Fixed memory leak + - x86/vdso: Provide missing include file + - PM / devfreq: exynos-ppmu: Fix excessive stack usage + - PM / devfreq: rk3399_dmc: Add COMPILE_TEST and HAVE_ARM_SMCCC dependency + - drm/fbdev: Fallback to non tiled mode if all tiles not present + - pinctrl: sh-pfc: sh7269: Fix CAN function GPIOs + - reset: uniphier: Add SCSSI reset control for each channel + - ASoC: soc-topology: fix endianness issues + - fbdev: fix numbering of fbcon options + - RDMA/rxe: Fix error type of mmap_offset + - clk: sunxi-ng: add mux and pll notifiers for A64 CPU clock + - ALSA: sh: Fix unused variable warnings + - clk: Use parent node pointer during registration if necessary + - clk: uniphier: Add SCSSI clock gate for each channel + - ALSA: hda/realtek - Apply mic mute LED quirk for Dell E7xx laptops, too + - ALSA: sh: Fix compile warning wrt const + - net: phy: fixed_phy: fix use-after-free when checking link GPIO + - tools lib api fs: Fix gcc9 stringop-truncation compilation error + - vfio/spapr/nvlink2: Skip unpinning pages on error exit + - ASoC: Intel: sof_rt5682: Ignore the speaker amp when there isn't one. + - ACPI: button: Add DMI quirk for Razer Blade Stealth 13 late 2019 lid switch + - iommu/vt-d: Match CPU and IOMMU paging mode + - iommu/vt-d: Avoid sending invalid page response + - drm/amdkfd: Fix permissions of hang_hws + - mlx5: work around high stack usage with gcc + - RDMA/hns: Avoid printing address of mtt page + - drm: remove the newline for CRC source name. + - usb: dwc3: use proper initializers for property entries + - ARM: dts: stm32: Add power-supply for DSI panel on stm32f469-disco + - usbip: Fix unsafe unaligned pointer usage + - udf: Fix free space reporting for metadata and virtual partitions + - drm/mediatek: Add gamma property according to hardware capability + - staging: rtl8188: avoid excessive stack usage + - IB/hfi1: Add software counter for ctxt0 seq drop + - IB/hfi1: Add RcvShortLengthErrCnt to hfi1stats + - soc/tegra: fuse: Correct straps' address for older Tegra124 device trees + - efi/x86: Don't panic or BUG() on non-critical error conditions + - rcu: Use WRITE_ONCE() for assignments to ->pprev for hlist_nulls + - Input: edt-ft5x06 - work around first register access error + - bnxt: Detach page from page pool before sending up the stack + - x86/nmi: Remove irq_work from the long duration NMI handler + - wan: ixp4xx_hss: fix compile-testing on 64-bit + - clocksource: davinci: only enable clockevents once tim34 is initialized + - arm64: dts: rockchip: fix dwmmc clock name for px30 + - arm64: dts: rockchip: add reg property to brcmf sub-nodes + - ARM: dts: rockchip: add reg property to brcmf sub node for + rk3188-bqedison2qc + - ALSA: usb-audio: Add boot quirk for MOTU M Series + - ASoC: atmel: fix build error with CONFIG_SND_ATMEL_SOC_DMA=m + - raid6/test: fix a compilation warning + - tty: synclinkmp: Adjust indentation in several functions + - tty: synclink_gt: Adjust indentation in several functions + - misc: xilinx_sdfec: fix xsdfec_poll()'s return type + - visorbus: fix uninitialized variable access + - driver core: platform: Prevent resouce overflow from causing infinite loops + - driver core: Print device when resources present in really_probe() + - ASoC: SOF: Intel: hda-dai: fix compilation warning in pcm_prepare + - bpf: Return -EBADRQC for invalid map type in __bpf_tx_xdp_map + - vme: bridges: reduce stack usage + - drm/nouveau/secboot/gm20b: initialize pointer in gm20b_secboot_new() + - drm/nouveau/gr/gk20a,gm200-: add terminators to method lists read from fw + - drm/nouveau: Fix copy-paste error in nouveau_fence_wait_uevent_handler + - drm/nouveau/drm/ttm: Remove set but not used variable 'mem' + - drm/nouveau/fault/gv100-: fix memory leak on module unload + - dm thin: don't allow changing data device during thin-pool reload + - gpiolib: Set lockdep class for hierarchical irq domains + - drm/vmwgfx: prevent memory leak in vmw_cmdbuf_res_add + - perf/imx_ddr: Fix cpu hotplug state cleanup + - usb: musb: omap2430: Get rid of musb .set_vbus for omap2430 glue + - kbuild: remove *.tmp file when filechk fails + - iommu/arm-smmu-v3: Use WRITE_ONCE() when changing validity of an STE + - ALSA: usb-audio: unlock on error in probe + - f2fs: set I_LINKABLE early to avoid wrong access by vfs + - f2fs: free sysfs kobject + - scsi: ufs: pass device information to apply_dev_quirks + - scsi: ufs-mediatek: add apply_dev_quirks variant operation + - scsi: iscsi: Don't destroy session if there are outstanding connections + - crypto: essiv - fix AEAD capitalization and preposition use in help text + - ALSA: usb-audio: add implicit fb quirk for MOTU M Series + - RDMA/mlx5: Don't fake udata for kernel path + - arm64: lse: fix LSE atomics with LLVM's integrated assembler + - arm64: fix alternatives with LLVM's integrated assembler + - drm/amd/display: fixup DML dependencies + - EDAC/sifive: Fix return value check in ecc_register() + - KVM: PPC: Remove set but not used variable 'ra', 'rs', 'rt' + - arm64: dts: ti: k3-j721e-main: Add missing power-domains for smmu + - sched/core: Fix size of rq::uclamp initialization + - sched/topology: Assert non-NUMA topology masks don't (partially) overlap + - perf/x86/amd: Constrain Large Increment per Cycle events + - watchdog/softlockup: Enforce that timestamp is valid on boot + - debugobjects: Fix various data races + - ASoC: SOF: Intel: hda: Fix SKL dai count + - regulator: vctrl-regulator: Avoid deadlock getting and setting the voltage + - f2fs: fix memleak of kobject + - x86/mm: Fix NX bit clearing issue in kernel_map_pages_in_pgd + - pwm: omap-dmtimer: Remove PWM chip in .remove before making it unfunctional + - cmd64x: potential buffer overflow in cmd64x_program_timings() + - ide: serverworks: potential overflow in svwks_set_pio_mode() + - pwm: Remove set but not set variable 'pwm' + - btrfs: fix possible NULL-pointer dereference in integrity checks + - btrfs: safely advance counter when looking up bio csums + - btrfs: device stats, log when stats are zeroed + - module: avoid setting info->name early in case we can fall back to + info->mod->name + - remoteproc: Initialize rproc_class before use + - regulator: core: Fix exported symbols to the exported GPL version + - irqchip/mbigen: Set driver .suppress_bind_attrs to avoid remove problems + - ALSA: hda/hdmi - add retry logic to parse_intel_hdmi() + - spi: spi-fsl-qspi: Ensure width is respected in spi-mem operations + - kbuild: use -S instead of -E for precise cc-option test in Kconfig + - objtool: Fix ARCH=x86_64 build error + - x86/decoder: Add TEST opcode to Group3-2 + - s390: adjust -mpacked-stack support check for clang 10 + - s390/ftrace: generate traced function stack frame + - driver core: platform: fix u32 greater or equal to zero comparison + - bpf, btf: Always output invariant hit in pahole DWARF to BTF transform + - ALSA: hda - Add docking station support for Lenovo Thinkpad T420s + - sunrpc: Fix potential leaks in sunrpc_cache_unhash() + - drm/nouveau/mmu: fix comptag memory leak + - powerpc/sriov: Remove VF eeh_dev state when disabling SR-IOV + - media: uvcvideo: Add a quirk to force GEO GC6500 Camera bits-per-pixel value + - btrfs: separate definition of assertion failure handlers + - btrfs: Fix split-brain handling when changing FSID to metadata uuid + - bcache: cached_dev_free needs to put the sb page + - bcache: rework error unwinding in register_bcache + - bcache: fix use-after-free in register_bcache() + - iommu/vt-d: Remove unnecessary WARN_ON_ONCE() + - alarmtimer: Make alarmtimer platform device child of RTC device + - selftests: bpf: Reset global state between reuseport test runs + - jbd2: switch to use jbd2_journal_abort() when failed to submit the commit + record + - jbd2: make sure ESHUTDOWN to be recorded in the journal superblock + - powerpc/pseries/lparcfg: Fix display of Maximum Memory + - selftests/eeh: Bump EEH wait time to 60s + - ARM: 8951/1: Fix Kexec compilation issue. + - ALSA: usb-audio: add quirks for Line6 Helix devices fw>=2.82 + - hostap: Adjust indentation in prism2_hostapd_add_sta + - rtw88: fix potential NULL skb access in TX ISR + - iwlegacy: ensure loop counter addr does not wrap and cause an infinite loop + - cifs: fix unitialized variable poential problem with network I/O cache lock + patch + - cifs: Fix mount options set in automount + - cifs: fix NULL dereference in match_prepath + - bpf: map_seq_next should always increase position index + - powerpc/mm: Don't log user reads to 0xffffffff + - ceph: check availability of mds cluster on mount after wait timeout + - rbd: work around -Wuninitialized warning + - drm/amd/display: do not allocate display_mode_lib unnecessarily + - irqchip/gic-v3: Only provision redistributors that are enabled in ACPI + - drm/nouveau/disp/nv50-: prevent oops when no channel method map provided + - char: hpet: Fix out-of-bounds read bug + - ftrace: fpid_next() should increase position index + - trigger_next should increase position index + - radeon: insert 10ms sleep in dce5_crtc_load_lut + - powerpc: Do not consider weak unresolved symbol relocations as bad + - btrfs: do not do delalloc reservation under page lock + - ocfs2: make local header paths relative to C files + - ocfs2: fix a NULL pointer dereference when call + ocfs2_update_inode_fsync_trans() + - lib/scatterlist.c: adjust indentation in __sg_alloc_table + - reiserfs: prevent NULL pointer dereference in reiserfs_insert_item() + - bcache: fix memory corruption in bch_cache_accounting_clear() + - bcache: explicity type cast in bset_bkey_last() + - bcache: fix incorrect data type usage in btree_flush_write() + - irqchip/gic-v3-its: Reference to its_invall_cmd descriptor when building + INVALL + - nvmet: Pass lockdep expression to RCU lists + - nvme-pci: remove nvmeq->tags + - iwlwifi: mvm: Fix thermal zone registration + - iwlwifi: mvm: Check the sta is not NULL in iwl_mvm_cfg_he_sta() + - asm-generic/tlb: add missing CONFIG symbol + - microblaze: Prevent the overflow of the start + - brd: check and limit max_part par + - drm/amdgpu/smu10: fix smu10_get_clock_by_type_with_latency + - drm/amdgpu/smu10: fix smu10_get_clock_by_type_with_voltage + - NFS: Fix memory leaks + - help_next should increase position index + - i40e: Relax i40e_xsk_wakeup's return value when PF is busy + - cifs: log warning message (once) if out of disk space + - virtio_balloon: prevent pfn array overflow + - fuse: don't overflow LLONG_MAX with end offset + - mlxsw: spectrum_dpipe: Add missing error path + - drm/amdgpu/display: handle multiple numbers of fclks in dcn_calcs.c (v2) + - bcache: properly initialize 'path' and 'err' in register_bcache() + - rtc: Kconfig: select REGMAP_I2C when necessary + - Linux 5.4.22 + * Focal update: 5.4.22 upstream stable release (LP: #1864488) // + CVE-2019-19076. + - Revert "nfp: abm: fix memory leak in nfp_abm_u32_knode_replace" + * Miscellaneous Ubuntu changes + - [Debian] Revert "UBUNTU: [Debian] Update linux source package name in + debian/tests/*" + - SAUCE: selftests: fix undefined lable cleanup build error + - SAUCE: selftests: fix undefined macro RET_IF() build error + - [Packaging] Include modules.builtin.modinfo in linux-modules + - update dkms package versions + - Revert "UBUNTU: [Debian] Update package name in getabis repo list" + * Miscellaneous upstream changes + - libbpf: Extract and generalize CPU mask parsing logic + + -- Paolo Pisati Mon, 02 Mar 2020 11:33:37 +0100 + +linux-oracle (5.4.0-1003.3) focal; urgency=medium + + * focal/linux-oracle: 5.4.0-1003.3 -proposed tracker (LP: #1864084) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs following rebase to 5.4.0-15.18 + + [ Ubuntu: 5.4.0-15.18 ] + + * focal/linux: 5.4.0-15.18 -proposed tracker (LP: #1864085) + * Focal update: v5.4.21 upstream stable release (LP: #1864046) + - Input: synaptics - switch T470s to RMI4 by default + - Input: synaptics - enable SMBus on ThinkPad L470 + - Input: synaptics - remove the LEN0049 dmi id from topbuttonpad list + - ALSA: usb-audio: Fix UAC2/3 effect unit parsing + - ALSA: hda/realtek - Add more codec supported Headset Button + - ALSA: hda/realtek - Fix silent output on MSI-GL73 + - ALSA: usb-audio: Apply sample rate quirk for Audioengine D1 + - ACPI: EC: Fix flushing of pending work + - ACPI: PM: s2idle: Avoid possible race related to the EC GPE + - ACPICA: Introduce acpi_any_gpe_status_set() + - ACPI: PM: s2idle: Prevent spurious SCIs from waking up the system + - ALSA: usb-audio: sound: usb: usb true/false for bool return type + - ALSA: usb-audio: Add clock validity quirk for Denon MC7000/MCX8000 + - ext4: don't assume that mmp_nodename/bdevname have NUL + - ext4: fix support for inode sizes > 1024 bytes + - ext4: fix checksum errors with indexed dirs + - ext4: add cond_resched() to ext4_protect_reserved_inode + - ext4: improve explanation of a mount failure caused by a misconfigured + kernel + - Btrfs: fix race between using extent maps and merging them + - btrfs: ref-verify: fix memory leaks + - btrfs: print message when tree-log replay starts + - btrfs: log message when rw remount is attempted with unclean tree-log + - ARM: npcm: Bring back GPIOLIB support + - gpio: xilinx: Fix bug where the wrong GPIO register is written to + - arm64: ssbs: Fix context-switch when SSBS is present on all CPUs + - xprtrdma: Fix DMA scatter-gather list mapping imbalance + - cifs: make sure we do not overflow the max EA buffer size + - EDAC/sysfs: Remove csrow objects on errors + - EDAC/mc: Fix use-after-free and memleaks during device removal + - KVM: nVMX: Use correct root level for nested EPT shadow page tables + - perf/x86/amd: Add missing L2 misses event spec to AMD Family 17h's event map + - s390/pkey: fix missing length of protected key on return + - s390/uv: Fix handling of length extensions + - drm/vgem: Close use-after-free race in vgem_gem_create + - drm/panfrost: Make sure the shrinker does not reclaim referenced BOs + - bus: moxtet: fix potential stack buffer overflow + - nvme: fix the parameter order for nvme_get_log in nvme_get_fw_slot_info + - drivers: ipmi: fix off-by-one bounds check that leads to a out-of-bounds + write + - IB/mlx5: Return failure when rts2rts_qp_counters_set_id is not supported + - IB/hfi1: Acquire lock to release TID entries when user file is closed + - IB/hfi1: Close window for pq and request coliding + - IB/rdmavt: Reset all QPs when the device is shut down + - IB/umad: Fix kernel crash while unloading ib_umad + - RDMA/core: Fix invalid memory access in spec_filter_size + - RDMA/iw_cxgb4: initiate CLOSE when entering TERM + - RDMA/hfi1: Fix memory leak in _dev_comp_vect_mappings_create + - RDMA/rxe: Fix soft lockup problem due to using tasklets in softirq + - RDMA/core: Fix protection fault in get_pkey_idx_qp_list + - s390/time: Fix clk type in get_tod_clock + - sched/uclamp: Reject negative values in cpu_uclamp_write() + - spmi: pmic-arb: Set lockdep class for hierarchical irq domains + - perf/x86/intel: Fix inaccurate period in context switch for auto-reload + - hwmon: (pmbus/ltc2978) Fix PMBus polling of MFR_COMMON definitions. + - mac80211: fix quiet mode activation in action frames + - cifs: fix mount option display for sec=krb5i + - arm64: dts: fast models: Fix FVP PCI interrupt-map property + - KVM: x86: Mask off reserved bit from #DB exception payload + - perf stat: Don't report a null stalled cycles per insn metric + - NFSv4.1 make cachethis=no for writes + - Revert "drm/sun4i: drv: Allow framebuffer modifiers in mode config" + - jbd2: move the clearing of b_modified flag to the journal_unmap_buffer() + - jbd2: do not clear the BH_Mapped flag when forgetting a metadata buffer + - ext4: choose hardlimit when softlimit is larger than hardlimit in + ext4_statfs_project() + - KVM: x86/mmu: Fix struct guest_walker arrays for 5-level paging + - gpio: add gpiod_toggle_active_low() + - mmc: core: Rework wp-gpio handling + - Linux 5.4.21 + * Fix AMD Stoney Ridge screen flickering under 4K resolution (LP: #1864005) + - iommu/amd: Disable IOMMU on Stoney Ridge systems + * Focal Fossa (20.04) feature request - Enable CONFIG_X86_UV (LP: #1863810) + - [Config] CONFIG_X86_UV=y + * [UBUNTU 20.04] Enable proper reset/recovery of s390x/pci functions in error + state (LP: #1863768) + - s390/pci: Recover handle in clp_set_pci_fn() + - s390/pci: Fix possible deadlock in recover_store() + * [20.04 FEAT] Enhanced handling of secure keys and protected keys + (LP: #1853303) + - s390/zcrypt: enable card/domain autoselect on ep11 cprbs + - s390/zcrypt: ep11 structs rework, export zcrypt_send_ep11_cprb + - s390/zcrypt: add new low level ep11 functions support file + - s390/zcrypt: extend EP11 card and queue sysfs attributes + - s390/pkey/zcrypt: Support EP11 AES secure keys + * [20.04 FEAT] paes self test (LP: #1854948) + - s390/pkey: use memdup_user() to simplify code + - s390/pkey: Add support for key blob with clear key value + - s390/crypto: Rework on paes implementation + - s390/crypto: enable clear key values for paes ciphers + - crypto/testmgr: enable selftests for paes-s390 ciphers + * Sometimes can't adjust brightness on Dell AIO (LP: #1862885) + - SAUCE: platform/x86: dell-uart-backlight: increase retry times + * change the ASoC card name and card longname to meet the requirement of alsa- + lib-1.2.1 (Focal) (LP: #1862712) + - ASoC: improve the DMI long card code in asoc-core + - ASoC: DMI long name - avoid to add board name if matches with product name + - ASoC: intel - fix the card names + * Support Headset Mic on HP cPC (LP: #1862313) + - ALSA: hda/realtek - Add Headset Mic supported for HP cPC + - ALSA: hda/realtek - Fixed one of HP ALC671 platform Headset Mic supported + * [hns3-0205]sync mainline kernel 5.5rc7 hns3 patchset into ubuntu HWE kernel + branch (LP: #1861972) + - net: hns3: replace snprintf with scnprintf in hns3_dbg_cmd_read + - net: hns3: replace snprintf with scnprintf in hns3_update_strings + - net: hns3: limit the error logging in the hns3_clean_tx_ring() + - net: hns3: do not reuse pfmemalloc pages + - net: hns3: set VF's default reset_type to HNAE3_NONE_RESET + - net: hns3: move duplicated macro definition into header + - net: hns3: refine the input parameter 'size' for snprintf() + - net: hns3: rewrite a log in hclge_put_vector() + - net: hns3: delete unnecessary blank line and space for cleanup + - net: hns3: remove redundant print on ENOMEM + * [acc-0205]sync mainline kernel 5.5rc6 acc patchset into ubuntu HWE kernel + branch (LP: #1861976) + - crypto: hisilicon/sec2 - Use atomics instead of __sync + - crypto: hisilicon - still no need to check return value of debugfs_create + functions + - crypto: hisilicon - Update debugfs usage of SEC V2 + - crypto: hisilicon - fix print/comment of SEC V2 + - crypto: hisilicon - Update some names on SEC V2 + - crypto: hisilicon - Update QP resources of SEC V2 + - crypto: hisilicon - Adjust some inner logic + - crypto: hisilicon - Add callback error check + - crypto: hisilicon - Add branch prediction macro + - crypto: hisilicon - redefine skcipher initiation + - crypto: hisilicon - Add aead support on SEC2 + - crypto: hisilicon - Bugfixed tfm leak + - crypto: hisilicon - Fixed some tiny bugs of HPRE + - crypto: hisilicon - adjust hpre_crt_para_get + - crypto: hisilicon - add branch prediction macro + - crypto: hisilicon - fix spelling mistake "disgest" -> "digest" + * [spi-0115]spi: dw: use "smp_mb()" to avoid sending spi data error + (LP: #1859744) + - spi: dw: use "smp_mb()" to avoid sending spi data error + * [tpm-0115]EFI/stub: tpm: enable tpm eventlog function for ARM64 platform + (LP: #1859743) + - efi: libstub/tpm: enable tpm eventlog function for ARM platforms + * Restrict xmon to read-only-mode if kernel is locked down (LP: #1863562) + - powerpc/xmon: Restrict when kernel is locked down + * [CML-H] Add intel_thermal_pch driver support Comet Lake -H (LP: #1853219) + - thermal: intel: intel_pch_thermal: Add Comet Lake (CML) platform support + * Root can lift kernel lockdown via USB/IP (LP: #1861238) + - Revert "UBUNTU: SAUCE: (lockdown) Add a SysRq option to lift kernel + lockdown" + * Dell XPS 13 (7390) Display Flickering - 19.10 (LP: #1849947) + - SAUCE: drm/i915: Disable PSR by default on all platforms + * Focal update: v5.4.20 upstream stable release (LP: #1863589) + - ASoC: pcm: update FE/BE trigger order based on the command + - hv_sock: Remove the accept port restriction + - IB/mlx4: Fix memory leak in add_gid error flow + - IB/srp: Never use immediate data if it is disabled by a user + - IB/mlx4: Fix leak in id_map_find_del + - RDMA/netlink: Do not always generate an ACK for some netlink operations + - RDMA/i40iw: fix a potential NULL pointer dereference + - RDMA/core: Fix locking in ib_uverbs_event_read + - RDMA/uverbs: Verify MR access flags + - RDMA/cma: Fix unbalanced cm_id reference count during address resolve + - RDMA/umem: Fix ib_umem_find_best_pgsz() + - scsi: ufs: Fix ufshcd_probe_hba() reture value in case + ufshcd_scsi_add_wlus() fails + - PCI/IOV: Fix memory leak in pci_iov_add_virtfn() + - ath10k: pci: Only dump ATH10K_MEM_REGION_TYPE_IOREG when safe + - PCI/switchtec: Use dma_set_mask_and_coherent() + - PCI/switchtec: Fix vep_vector_number ioread width + - PCI: tegra: Fix afi_pex2_ctrl reg offset for Tegra30 + - PCI: Don't disable bridge BARs when assigning bus resources + - PCI/AER: Initialize aer_fifo + - iwlwifi: mvm: avoid use after free for pmsr request + - bpftool: Don't crash on missing xlated program instructions + - bpf, sockmap: Don't sleep while holding RCU lock on tear-down + - bpf, sockhash: Synchronize_rcu before free'ing map + - selftests/bpf: Test freeing sockmap/sockhash with a socket in it + - bpf: Improve bucket_log calculation logic + - bpf, sockmap: Check update requirements after locking + - nfs: NFS_SWAP should depend on SWAP + - NFS: Revalidate the file size on a fatal write error + - NFS/pnfs: Fix pnfs_generic_prepare_to_resend_writes() + - NFS: Fix fix of show_nfs_errors + - NFSv4: pnfs_roc() must use cred_fscmp() to compare creds + - NFSv4: try lease recovery on NFS4ERR_EXPIRED + - NFSv4.0: nfs4_do_fsinfo() should not do implicit lease renewals + - x86/boot: Handle malformed SRAT tables during early ACPI parsing + - rtc: hym8563: Return -EINVAL if the time is known to be invalid + - rtc: cmos: Stop using shared IRQ + - watchdog: qcom: Use platform_get_irq_optional() for bark irq + - ARC: [plat-axs10x]: Add missing multicast filter number to GMAC node + - platform/x86: intel_mid_powerbtn: Take a copy of ddata + - arm64: dts: qcom: msm8998: Fix tcsr syscon size + - arm64: dts: uDPU: fix broken ethernet + - ARM: dts: at91: Reenable UART TX pull-ups + - ARM: dts: am43xx: add support for clkout1 clock + - arm64: dts: renesas: r8a77990: ebisu: Remove clkout-lr-synchronous from + sound + - arm64: dts: marvell: clearfog-gt-8k: fix switch cpu port node + - ARM: dts: meson8: use the actual frequency for the GPU's 182.1MHz OPP + - ARM: dts: meson8b: use the actual frequency for the GPU's 364MHz OPP + - ARM: dts: at91: sama5d3: fix maximum peripheral clock rates + - ARM: dts: at91: sama5d3: define clock rate range for tcb1 + - tools/power/acpi: fix compilation error + - soc: qcom: rpmhpd: Set 'active_only' for active only power domains + - Revert "powerpc/pseries/iommu: Don't use dma_iommu_ops on secure guests" + - powerpc/ptdump: Fix W+X verification call in mark_rodata_ro() + - powerpc/ptdump: Only enable PPC_CHECK_WX with STRICT_KERNEL_RWX + - powerpc/papr_scm: Fix leaking 'bus_desc.provider_name' in some paths + - powerpc/pseries/vio: Fix iommu_table use-after-free refcount warning + - powerpc/pseries: Allow not having ibm, hypertas-functions::hcall-multi-tce + for DDW + - iommu/arm-smmu-v3: Populate VMID field for CMDQ_OP_TLBI_NH_VA + - ARM: at91: pm: use SAM9X60 PMC's compatible + - ARM: at91: pm: use of_device_id array to find the proper shdwc node + - KVM: arm/arm64: vgic-its: Fix restoration of unmapped collections + - ARM: 8949/1: mm: mark free_memmap as __init + - sched/uclamp: Fix a bug in propagating uclamp value in new cgroups + - arm64: cpufeature: Fix the type of no FP/SIMD capability + - arm64: cpufeature: Set the FP/SIMD compat HWCAP bits properly + - arm64: ptrace: nofpsimd: Fail FP/SIMD regset operations + - KVM: arm/arm64: Fix young bit from mmu notifier + - KVM: arm: Fix DFSR setting for non-LPAE aarch32 guests + - KVM: arm: Make inject_abt32() inject an external abort instead + - KVM: arm64: pmu: Don't increment SW_INCR if PMCR.E is unset + - KVM: arm64: pmu: Fix chained SW_INCR counters + - KVM: arm64: Treat emulated TVAL TimerValue as a signed 32-bit integer + - arm64: nofpsmid: Handle TIF_FOREIGN_FPSTATE flag cleanly + - mtd: onenand_base: Adjust indentation in onenand_read_ops_nolock + - mtd: sharpslpart: Fix unsigned comparison to zero + - crypto: testmgr - don't try to decrypt uninitialized buffers + - crypto: artpec6 - return correct error code for failed setkey() + - crypto: atmel-sha - fix error handling when setting hmac key + - crypto: caam/qi2 - fix typo in algorithm's driver name + - drivers: watchdog: stm32_iwdg: set WDOG_HW_RUNNING at probe + - media: i2c: adv748x: Fix unsafe macros + - dt-bindings: iio: adc: ad7606: Fix wrong maxItems value + - bcache: avoid unnecessary btree nodes flushing in btree_flush_write() + - selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" + - selinux: fix regression introduced by move_mount(2) syscall + - pinctrl: sh-pfc: r8a77965: Fix DU_DOTCLKIN3 drive/bias control + - pinctrl: sh-pfc: r8a7778: Fix duplicate SDSELF_B and SD1_CLK_B + - regmap: fix writes to non incrementing registers + - mfd: max77650: Select REGMAP_IRQ in Kconfig + - clk: meson: g12a: fix missing uart2 in regmap table + - dmaengine: axi-dmac: add a check for devm_regmap_init_mmio + - mwifiex: Fix possible buffer overflows in mwifiex_ret_wmm_get_status() + - mwifiex: Fix possible buffer overflows in mwifiex_cmd_append_vsie_tlv() + - libertas: don't exit from lbs_ibss_join_existing() with RCU read lock held + - libertas: make lbs_ibss_join_existing() return error code on rates overflow + - selinux: fall back to ref-walk if audit is required + - Linux 5.4.20 + * Focal update: v5.4.19 upstream stable release (LP: #1863588) + - sparc32: fix struct ipc64_perm type definition + - bnxt_en: Move devlink_register before registering netdev + - cls_rsvp: fix rsvp_policy + - gtp: use __GFP_NOWARN to avoid memalloc warning + - l2tp: Allow duplicate session creation with UDP + - net: hsr: fix possible NULL deref in hsr_handle_frame() + - net_sched: fix an OOB access in cls_tcindex + - net: stmmac: Delete txtimer in suspend() + - bnxt_en: Fix TC queue mapping. + - rxrpc: Fix use-after-free in rxrpc_put_local() + - rxrpc: Fix insufficient receive notification generation + - rxrpc: Fix missing active use pinning of rxrpc_local object + - rxrpc: Fix NULL pointer deref due to call->conn being cleared on disconnect + - tcp: clear tp->total_retrans in tcp_disconnect() + - tcp: clear tp->delivered in tcp_disconnect() + - tcp: clear tp->data_segs{in|out} in tcp_disconnect() + - tcp: clear tp->segs_{in|out} in tcp_disconnect() + - ionic: fix rxq comp packet type mask + - MAINTAINERS: correct entries for ISDN/mISDN section + - netdevsim: fix stack-out-of-bounds in nsim_dev_debugfs_init() + - bnxt_en: Fix logic that disables Bus Master during firmware reset. + - media: uvcvideo: Avoid cyclic entity chains due to malformed USB descriptors + - mfd: dln2: More sanity checking for endpoints + - netfilter: ipset: fix suspicious RCU usage in find_set_and_id + - ipc/msg.c: consolidate all xxxctl_down() functions + - tracing/kprobes: Have uname use __get_str() in print_fmt + - tracing: Fix sched switch start/stop refcount racy updates + - rcu: Use *_ONCE() to protect lockless ->expmask accesses + - rcu: Avoid data-race in rcu_gp_fqs_check_wake() + - srcu: Apply *_ONCE() to ->srcu_last_gp_end + - rcu: Use READ_ONCE() for ->expmask in rcu_read_unlock_special() + - nvmet: Fix error print message at nvmet_install_queue function + - nvmet: Fix controller use after free + - Bluetooth: btusb: fix memory leak on fw + - Bluetooth: btusb: Disable runtime suspend on Realtek devices + - brcmfmac: Fix memory leak in brcmf_usbdev_qinit + - usb: dwc3: gadget: Check END_TRANSFER completion + - usb: dwc3: gadget: Delay starting transfer + - usb: typec: tcpci: mask event interrupts when remove driver + - objtool: Silence build output + - usb: gadget: f_fs: set req->num_sgs as 0 for non-sg transfer + - usb: gadget: legacy: set max_speed to super-speed + - usb: gadget: f_ncm: Use atomic_t to track in-flight request + - usb: gadget: f_ecm: Use atomic_t to track in-flight request + - ALSA: usb-audio: Fix endianess in descriptor validation + - ALSA: usb-audio: Annotate endianess in Scarlett gen2 quirk + - ALSA: dummy: Fix PCM format loop in proc output + - memcg: fix a crash in wb_workfn when a device disappears + - mm/sparse.c: reset section's mem_map when fully deactivated + - mmc: sdhci-pci: Make function amd_sdhci_reset static + - utimes: Clamp the timestamps in notify_change() + - mm/memory_hotplug: fix remove_memory() lockdep splat + - mm: thp: don't need care deferred split queue in memcg charge move path + - mm: move_pages: report the number of non-attempted pages + - media/v4l2-core: set pages dirty upon releasing DMA buffers + - media: v4l2-core: compat: ignore native command codes + - media: v4l2-rect.h: fix v4l2_rect_map_inside() top/left adjustments + - lib/test_kasan.c: fix memory leak in kmalloc_oob_krealloc_more() + - irqdomain: Fix a memory leak in irq_domain_push_irq() + - x86/cpu: Update cached HLE state on write to TSX_CTRL_CPUID_CLEAR + - platform/x86: intel_scu_ipc: Fix interrupt support + - ALSA: hda: Apply aligned MMIO access only conditionally + - ALSA: hda: Add Clevo W65_67SB the power_save blacklist + - ALSA: hda: Add JasperLake PCI ID and codec vid + - arm64: acpi: fix DAIF manipulation with pNMI + - KVM: arm64: Correct PSTATE on exception entry + - KVM: arm/arm64: Correct CPSR on exception entry + - KVM: arm/arm64: Correct AArch32 SPSR on exception entry + - KVM: arm64: Only sign-extend MMIO up to register width + - MIPS: syscalls: fix indentation of the 'SYSNR' message + - MIPS: fix indentation of the 'RELOCS' message + - MIPS: boot: fix typo in 'vmlinux.lzma.its' target + - s390/mm: fix dynamic pagetable upgrade for hugetlbfs + - powerpc/mmu_gather: enable RCU_TABLE_FREE even for !SMP case + - powerpc/ptdump: Fix W+X verification + - powerpc/xmon: don't access ASDR in VMs + - powerpc/pseries: Advance pfn if section is not present in lmb_is_removable() + - powerpc/32s: Fix bad_kuap_fault() + - powerpc/32s: Fix CPU wake-up from sleep mode + - tracing: Fix now invalid var_ref_vals assumption in trace action + - PCI: tegra: Fix return value check of pm_runtime_get_sync() + - PCI: keystone: Fix outbound region mapping + - PCI: keystone: Fix link training retries initiation + - PCI: keystone: Fix error handling when "num-viewport" DT property is not + populated + - mmc: spi: Toggle SPI polarity, do not hardcode it + - ACPI: video: Do not export a non working backlight interface on MSI MS-7721 + boards + - ACPI / battery: Deal with design or full capacity being reported as -1 + - ACPI / battery: Use design-cap for capacity calculations if full-cap is not + available + - ACPI / battery: Deal better with neither design nor full capacity not being + reported + - alarmtimer: Unregister wakeup source when module get fails + - fscrypt: don't print name of busy file when removing key + - ubifs: don't trigger assertion on invalid no-key filename + - ubifs: Fix wrong memory allocation + - ubifs: Fix FS_IOC_SETFLAGS unexpectedly clearing encrypt flag + - ubifs: Fix deadlock in concurrent bulk-read and writepage + - mmc: sdhci-of-at91: fix memleak on clk_get failure + - ASoC: SOF: core: free trace on errors + - hv_balloon: Balloon up according to request page number + - mfd: axp20x: Mark AXP20X_VBUS_IPSOUT_MGMT as volatile + - nvmem: core: fix memory abort in cleanup path + - crypto: api - Check spawn->alg under lock in crypto_drop_spawn + - crypto: ccree - fix backlog memory leak + - crypto: ccree - fix AEAD decrypt auth fail + - crypto: ccree - fix pm wrongful error reporting + - crypto: ccree - fix FDE descriptor sequence + - crypto: ccree - fix PM race condition + - padata: Remove broken queue flushing + - fs: allow deduplication of eof block into the end of the destination file + - scripts/find-unused-docs: Fix massive false positives + - erofs: fix out-of-bound read for shifted uncompressed block + - scsi: megaraid_sas: Do not initiate OCR if controller is not in ready state + - scsi: qla2xxx: Fix mtcp dump collection failure + - cpupower: Revert library ABI changes from commit ae2917093fb60bdc1ed3e + - power: supply: axp20x_ac_power: Fix reporting online status + - power: supply: ltc2941-battery-gauge: fix use-after-free + - ovl: fix wrong WARN_ON() in ovl_cache_update_ino() + - ovl: fix lseek overflow on 32bit + - f2fs: choose hardlimit when softlimit is larger than hardlimit in + f2fs_statfs_project() + - f2fs: fix miscounted block limit in f2fs_statfs_project() + - f2fs: code cleanup for f2fs_statfs_project() + - f2fs: fix dcache lookup of !casefolded directories + - f2fs: fix race conditions in ->d_compare() and ->d_hash() + - PM: core: Fix handling of devices deleted during system-wide resume + - cpufreq: Avoid creating excessively large stack frames + - of: Add OF_DMA_DEFAULT_COHERENT & select it on powerpc + - ARM: dma-api: fix max_pfn off-by-one error in __dma_supported() + - dm zoned: support zone sizes smaller than 128MiB + - dm space map common: fix to ensure new block isn't already in use + - dm writecache: fix incorrect flush sequence when doing SSD mode commit + - dm crypt: fix GFP flags passed to skcipher_request_alloc() + - dm crypt: fix benbi IV constructor crash if used in authenticated mode + - dm thin metadata: use pool locking at end of dm_pool_metadata_close + - scsi: qla2xxx: Fix stuck login session using prli_pend_timer + - ASoC: SOF: Introduce state machine for FW boot + - ASoC: SOF: core: release resources on errors in probe_continue + - tracing: Annotate ftrace_graph_hash pointer with __rcu + - tracing: Annotate ftrace_graph_notrace_hash pointer with __rcu + - ftrace: Add comment to why rcu_dereference_sched() is open coded + - ftrace: Protect ftrace_graph_hash with ftrace_sync + - crypto: pcrypt - Avoid deadlock by using per-instance padata queues + - btrfs: fix improper setting of scanned for range cyclic write cache pages + - btrfs: Handle another split brain scenario with metadata uuid feature + - riscv, bpf: Fix broken BPF tail calls + - selftests/bpf: Fix perf_buffer test on systems w/ offline CPUs + - bpf, devmap: Pass lockdep expression to RCU lists + - libbpf: Fix realloc usage in bpf_core_find_cands + - tc-testing: fix eBPF tests failure on linux fresh clones + - samples/bpf: Don't try to remove user's homedir on clean + - samples/bpf: Xdp_redirect_cpu fix missing tracepoint attach + - selftests/bpf: Fix test_attach_probe + - selftests/bpf: Skip perf hw events test if the setup disabled it + - selftests: bpf: Use a temporary file in test_sockmap + - selftests: bpf: Ignore FIN packets for reuseport tests + - crypto: api - fix unexpectedly getting generic implementation + - crypto: hisilicon - Use the offset fields in sqe to avoid need to split + scatterlists + - crypto: ccp - set max RSA modulus size for v3 platform devices as well + - crypto: arm64/ghash-neon - bump priority to 150 + - crypto: pcrypt - Do not clear MAY_SLEEP flag in original request + - crypto: atmel-aes - Fix counter overflow in CTR mode + - crypto: api - Fix race condition in crypto_spawn_alg + - crypto: picoxcell - adjust the position of tasklet_init and fix missed + tasklet_kill + - powerpc/futex: Fix incorrect user access blocking + - scsi: qla2xxx: Fix unbound NVME response length + - NFS: Fix memory leaks and corruption in readdir + - NFS: Directory page cache pages need to be locked when read + - nfsd: fix filecache lookup + - jbd2_seq_info_next should increase position index + - ext4: fix deadlock allocating crypto bounce page from mempool + - ext4: fix race conditions in ->d_compare() and ->d_hash() + - Btrfs: fix missing hole after hole punching and fsync when using NO_HOLES + - Btrfs: make deduplication with range including the last block work + - Btrfs: fix infinite loop during fsync after rename operations + - btrfs: set trans->drity in btrfs_commit_transaction + - btrfs: drop log root for dropped roots + - Btrfs: fix race between adding and putting tree mod seq elements and nodes + - btrfs: flush write bio if we loop in extent_write_cache_pages + - btrfs: Correctly handle empty trees in find_first_clear_extent_bit + - ARM: tegra: Enable PLLP bypass during Tegra124 LP1 + - iwlwifi: don't throw error when trying to remove IGTK + - mwifiex: fix unbalanced locking in mwifiex_process_country_ie() + - sunrpc: expiry_time should be seconds not timeval + - gfs2: fix gfs2_find_jhead that returns uninitialized jhead with seq 0 + - gfs2: move setting current->backing_dev_info + - gfs2: fix O_SYNC write handling + - drm: atmel-hlcdc: use double rate for pixel clock only if supported + - drm: atmel-hlcdc: enable clock before configuring timing engine + - drm: atmel-hlcdc: prefer a lower pixel-clock than requested + - drm/rect: Avoid division by zero + - media: iguanair: fix endpoint sanity check + - media: rc: ensure lirc is initialized before registering input device + - tools/kvm_stat: Fix kvm_exit filter name + - xen/balloon: Support xend-based toolstack take two + - watchdog: fix UAF in reboot notifier handling in watchdog core code + - bcache: add readahead cache policy options via sysfs interface + - eventfd: track eventfd_signal() recursion depth + - aio: prevent potential eventfd recursion on poll + - KVM: x86: Refactor picdev_write() to prevent Spectre-v1/L1TF attacks + - KVM: x86: Refactor prefix decoding to prevent Spectre-v1/L1TF attacks + - KVM: x86: Protect pmu_intel.c from Spectre-v1/L1TF attacks + - KVM: x86: Protect DR-based index computations from Spectre-v1/L1TF attacks + - KVM: x86: Protect kvm_lapic_reg_write() from Spectre-v1/L1TF attacks + - KVM: x86: Protect kvm_hv_msr_[get|set]_crash_data() from Spectre-v1/L1TF + attacks + - KVM: x86: Protect ioapic_write_indirect() from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations in pmu.h from Spectre-v1/L1TF + attacks + - KVM: x86: Protect ioapic_read_indirect() from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations from Spectre-v1/L1TF attacks + in x86.c + - KVM: x86: Protect x86_decode_insn from Spectre-v1/L1TF attacks + - KVM: x86: Protect MSR-based index computations in fixed_msr_to_seg_unit() + from Spectre-v1/L1TF attacks + - KVM: x86: Fix potential put_fpu() w/o load_fpu() on MPX platform + - KVM: PPC: Book3S HV: Uninit vCPU if vcore creation fails + - KVM: PPC: Book3S PR: Free shared page if mmu initialization fails + - kvm/svm: PKU not currently supported + - KVM: VMX: Add non-canonical check on writes to RTIT address MSRs + - KVM: x86: Don't let userspace set host-reserved cr4 bits + - KVM: x86: Free wbinvd_dirty_mask if vCPU creation fails + - KVM: x86: Handle TIF_NEED_FPU_LOAD in kvm_{load,put}_guest_fpu() + - KVM: x86: Ensure guest's FPU state is loaded when accessing for emulation + - KVM: x86: Revert "KVM: X86: Fix fpu state crash in kvm guest" + - KVM: s390: do not clobber registers during guest reset/store status + - ocfs2: fix oops when writing cloned file + - mm/page_alloc.c: fix uninitialized memmaps on a partially populated last + section + - arm64: dts: qcom: qcs404-evb: Set vdd_apc regulator in high power mode + - mm/mmu_gather: invalidate TLB correctly on batch allocation failure and + flush + - clk: tegra: Mark fuse clock as critical + - drm/amd/dm/mst: Ignore payload update failures + - virtio-balloon: initialize all vq callbacks + - virtio-pci: check name when counting MSI-X vectors + - fix up iter on short count in fuse_direct_io() + - broken ping to ipv6 linklocal addresses on debian buster + - percpu: Separate decrypted varaibles anytime encryption can be enabled + - ASoC: meson: axg-fifo: fix fifo threshold setup + - scsi: qla2xxx: Fix the endianness of the qla82xx_get_fw_size() return type + - scsi: csiostor: Adjust indentation in csio_device_reset + - scsi: qla4xxx: Adjust indentation in qla4xxx_mem_free + - scsi: ufs: Recheck bkops level if bkops is disabled + - mtd: spi-nor: Split mt25qu512a (n25q512a) entry into two + - phy: qualcomm: Adjust indentation in read_poll_timeout + - ext2: Adjust indentation in ext2_fill_super + - powerpc/44x: Adjust indentation in ibm4xx_denali_fixup_memsize + - drm: msm: mdp4: Adjust indentation in mdp4_dsi_encoder_enable + - NFC: pn544: Adjust indentation in pn544_hci_check_presence + - ppp: Adjust indentation into ppp_async_input + - net: smc911x: Adjust indentation in smc911x_phy_configure + - net: tulip: Adjust indentation in {dmfe, uli526x}_init_module + - IB/mlx5: Fix outstanding_pi index for GSI qps + - IB/core: Fix ODP get user pages flow + - nfsd: fix delay timer on 32-bit architectures + - nfsd: fix jiffies/time_t mixup in LRU list + - nfsd: Return the correct number of bytes written to the file + - virtio-balloon: Fix memory leak when unloading while hinting is in progress + - virtio_balloon: Fix memory leaks on errors in virtballoon_probe() + - ubi: fastmap: Fix inverted logic in seen selfcheck + - ubi: Fix an error pointer dereference in error handling code + - ubifs: Fix memory leak from c->sup_node + - regulator: core: Add regulator_is_equal() helper + - ASoC: sgtl5000: Fix VDDA and VDDIO comparison + - bonding/alb: properly access headers in bond_alb_xmit() + - devlink: report 0 after hitting end in region read + - dpaa_eth: support all modes with rate adapting PHYs + - net: dsa: b53: Always use dev->vlan_enabled in b53_configure_vlan() + - net: dsa: bcm_sf2: Only 7278 supports 2Gb/sec IMP port + - net: dsa: microchip: enable module autoprobe + - net: mvneta: move rx_dropped and rx_errors in per-cpu stats + - net_sched: fix a resource leak in tcindex_set_parms() + - net: stmmac: fix a possible endless loop + - net: systemport: Avoid RBUF stuck in Wake-on-LAN mode + - net/mlx5: IPsec, Fix esp modify function attribute + - net/mlx5: IPsec, fix memory leak at mlx5_fpga_ipsec_delete_sa_ctx + - net: macb: Remove unnecessary alignment check for TSO + - net: macb: Limit maximum GEM TX length in TSO + - taprio: Fix enabling offload with wrong number of traffic classes + - taprio: Fix still allowing changing the flags during runtime + - taprio: Add missing policy validation for flags + - taprio: Use taprio_reset_tc() to reset Traffic Classes configuration + - taprio: Fix dropping packets when using taprio + ETF offloading + - ipv6/addrconf: fix potential NULL deref in inet6_set_link_af() + - qed: Fix timestamping issue for L2 unicast ptp packets. + - drop_monitor: Do not cancel uninitialized work item + - net/mlx5: Fix deadlock in fs_core + - net/mlx5: Deprecate usage of generic TLS HW capability bit + - ASoC: Intel: skl_hda_dsp_common: Fix global-out-of-bounds bug + - mfd: da9062: Fix watchdog compatible string + - mfd: rn5t618: Mark ADC control register volatile + - mfd: bd70528: Fix hour register mask + - x86/timer: Don't skip PIT setup when APIC is disabled or in legacy mode + - btrfs: use bool argument in free_root_pointers() + - btrfs: free block groups after free'ing fs trees + - drm/dp_mst: Remove VCPI while disabling topology mgr + - KVM: x86/mmu: Apply max PA check for MMIO sptes to 32-bit KVM + - KVM: x86: use CPUID to locate host page table reserved bits + - KVM: x86: Use gpa_t for cr2/gpa to fix TDP support on 32-bit KVM + - KVM: x86: fix overlap between SPTE_MMIO_MASK and generation + - KVM: nVMX: vmread should not set rflags to specify success in case of #PF + - KVM: Use vcpu-specific gva->hva translation when querying host page size + - KVM: Play nice with read-only memslots when querying host page size + - cifs: fail i/o on soft mounts if sessionsetup errors out + - x86/apic/msi: Plug non-maskable MSI affinity race + - clocksource: Prevent double add_timer_on() for watchdog_timer + - perf/core: Fix mlock accounting in perf_mmap() + - rxrpc: Fix service call disconnection + - regulator fix for "regulator: core: Add regulator_is_equal() helper" + - powerpc/kuap: Fix set direction in allow/prevent_user_access() + - Linux 5.4.19 + - [Config] updateconfigs following v5.4.19 stable update + * 5.4.0-11 crash on cryptsetup open (LP: #1860231) // Focal update: v5.4.19 + upstream stable release (LP: #1863588) + - dm: fix potential for q->make_request_fn NULL pointer + * Miscellaneous Ubuntu changes + - update dkms package versions + - [debian] ignore missing wireguard module + - debian: remove snapdragon config, rules and flavour + - [Config] updateconfigs following snapdragon removal + - remove snapdragon abi files + + -- Seth Forshee Fri, 21 Feb 2020 14:16:44 -0600 + +linux-oracle (5.4.0-1002.2) focal; urgency=medium + + * Change source package name to linux-oracle. + + -- Seth Forshee Fri, 21 Feb 2020 13:06:41 -0600 + +linux-oracle-5.4 (5.4.0-1002.2) focal; urgency=medium + + * focal/linux-oracle-5.4: 5.4.0-1002.2 -proposed tracker (LP: #1862254) + + * installing linux-modules-nvidia does not remove nvidia-dkms, and the kernel + prioritizes the wrong version of the module from disk (LP: #1856414) + - Revert "UBUNTU: [Packaging] dkms -- add Provides: specifiers" + + [ Ubuntu: 5.4.0-14.17 ] + + * focal/linux-5.4: 5.4.0-14.17 -proposed tracker (LP: #1862255) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * Boot log is swamped with "debugfs: Directory 'imc' with parent 'powerpc' + already present" messages on kernel 5.4 (LP: #1861379) + - powerpc/powernv: Avoid re-registration of imc debugfs directory + * CVE-2019-3016 + - SAUCE: x86/kvm: Be careful not to clear KVM_VCPU_FLUSH_TLB bit + - SAUCE: x86/kvm: Introduce kvm_(un)map_gfn() + - SAUCE: x86/kvm: Cache gfn to pfn translation + - SAUCE: x86/KVM: Make sure KVM_VCPU_FLUSH_TLB flag is not missed + - SAUCE: x86/KVM: Clean up host's steal time structure + * installing linux-modules-nvidia does not remove nvidia-dkms, and the kernel + prioritizes the wrong version of the module from disk (LP: #1856414) + - Revert "UBUNTU: [Packaging] dkms -- switch basic provides to *-modules" + - Revert "UBUNTU: [Packaging] dkms -- add Provides: specifiers for existing + zfs/nvidia/vbox" + - Revert "UBUNTU: [packaging] dkms-build -- include versioned provides" + - [Packaging] wireguard -- drop provides + * Focal update: v5.4.18 upstream stable release (LP: #1862203) + - vfs: fix do_last() regression + - cifs: fix soft mounts hanging in the reconnect code + - x86/resctrl: Fix a deadlock due to inaccurate reference + - x86/resctrl: Fix use-after-free when deleting resource groups + - x86/resctrl: Fix use-after-free due to inaccurate refcount of rdtgroup + - e1000e: Drop unnecessary __E1000_DOWN bit twiddling + - e1000e: Revert "e1000e: Make watchdog use delayed work" + - gfs2: Another gfs2_find_jhead fix + - perf c2c: Fix return type for histogram sorting comparision functions + - PM / devfreq: Add new name attribute for sysfs + - tools lib: Fix builds when glibc contains strlcpy() + - arm64: kbuild: remove compressed images on 'make ARCH=arm64 (dist)clean' + - mm/mempolicy.c: fix out of bounds write in mpol_parse_str() + - reiserfs: Fix memory leak of journal device string + - media: digitv: don't continue if remote control state can't be read + - media: af9005: uninitialized variable printked + - media: vp7045: do not read uninitialized values if usb transfer fails + - media: gspca: zero usb_buf + - media: dvb-usb/dvb-usb-urb.c: initialize actlen to 0 + - tomoyo: Use atomic_t for statistics counter + - ttyprintk: fix a potential deadlock in interrupt context issue + - Bluetooth: Fix race condition in hci_release_sock() + - cgroup: Prevent double killing of css when enabling threaded cgroup + - clk: sunxi-ng: v3s: Fix incorrect number of hw_clks. + - arm64: dts: meson-sm1-sei610: add gpio bluetooth interrupt + - ARM: dts: sun8i: a83t: Correct USB3503 GPIOs polarity + - ARM: dts: am57xx-beagle-x15/am57xx-idk: Remove "gpios" for endpoint dt nodes + - ARM: dts: beagle-x15-common: Model 5V0 regulator + - soc: ti: wkup_m3_ipc: Fix race condition with rproc_boot + - tools lib traceevent: Fix memory leakage in filter_event + - rseq: Unregister rseq for clone CLONE_VM + - clk: sunxi-ng: sun8i-r: Fix divider on APB0 clock + - clk: sunxi-ng: h6-r: Fix AR100/R_APB2 parent order + - mac80211: mesh: restrict airtime metric to peered established plinks + - clk: mmp2: Fix the order of timer mux parents + - ASoC: rt5640: Fix NULL dereference on module unload + - s390/zcrypt: move ap device reset from bus to driver code + - i40e: Fix virtchnl_queue_select bitmap validation + - ixgbevf: Remove limit of 10 entries for unicast filter list + - ixgbe: Fix calculation of queue with VFs and flow director on interface flap + - igb: Fix SGMII SFP module discovery for 100FX/LX. + - iavf: remove current MAC address filter on VF reset + - platform/x86: GPD pocket fan: Allow somewhat lower/higher temperature limits + - platform/x86: intel_pmc_core: update Comet Lake platform driver + - ASoC: hdac_hda: Fix error in driver removal after failed probe + - ASoC: sti: fix possible sleep-in-atomic + - qmi_wwan: Add support for Quectel RM500Q + - parisc: Use proper printk format for resource_size_t + - lkdtm/bugs: fix build error in lkdtm_UNSET_SMEP + - wireless: fix enabling channel 12 for custom regulatory domain + - cfg80211: Fix radar event during another phy CAC + - mac80211: Fix TKIP replay protection immediately after key setup + - wireless: wext: avoid gcc -O3 warning + - perf/x86/intel/uncore: Add PCI ID of IMC for Xeon E3 V5 Family + - perf/x86/intel/uncore: Remove PCIe3 unit for SNR + - riscv: delete temporary files + - XArray: Fix xas_pause at ULONG_MAX + - iwlwifi: pcie: allocate smaller dev_cmd for TX headers + - iwlwifi: Don't ignore the cap field upon mcc update + - iwlwifi: dbg: force stop the debug monitor HW + - Input: evdev - convert kzalloc()/vzalloc() to kvzalloc() + - ARM: dts: am335x-boneblack-common: fix memory size + - xfrm: interface: do not confirm neighbor when do pmtu update + - Input: max77650-onkey - add of_match table + - scsi: fnic: do not queue commands during fwreset + - ARM: 8955/1: virt: Relax arch timer version check during early boot + - led: max77650: add of_match table + - tee: optee: Fix compilation issue with nommu + - r8152: get default setting of WOL before initializing + - r8152: disable U2P3 for RTL8153B + - r8152: Disable PLA MCU clock speed down + - r8152: disable test IO for RTL8153B + - r8152: avoid the MCU to clear the lanwake + - r8152: disable DelayPhyPwrChg + - ARM: dts: am43x-epos-evm: set data pin directions for spi0 and spi1 + - qlcnic: Fix CPU soft lockup while collecting firmware dump + - powerpc/fsl/dts: add fsl,erratum-a011043 + - net/fsl: treat fsl,erratum-a011043 + - net: fsl/fman: rename IF_MODE_XGMII to IF_MODE_10G + - seq_tab_next() should increase position index + - l2t_seq_next should increase position index + - netfilter: conntrack: sctp: use distinct states for new SCTP connections + - netfilter: nf_tables_offload: fix check the chain offload flag + - net: Fix skb->csum update in inet_proto_csum_replace16(). + - btrfs: do not zero f_bavail if we have available space + - cpuidle: teo: Avoid using "early hits" incorrectly + - flow_dissector: Fix to use new variables for port ranges in bpf hook + - dm thin: fix use-after-free in metadata_pre_commit_callback + - perf report: Fix no libunwind compiled warning break s390 issue + - mm/migrate.c: also overwrite error when it is bigger than zero + - ASoC: topology: fix soc_tplg_fe_link_create() - link->dobj initialization + order + - Revert "rsi: fix potential null dereference in rsi_probe()" + - tracing/uprobe: Fix to make trace_uprobe_filter alignment safe + - Linux 5.4.18 + * Integrate Intel SGX driver into linux-azure (LP: #1844245) + - [Packaging] Add systemd service to load intel_sgx + * Focal update: v5.4.17 upstream stable release (LP: #1861784) + - Bluetooth: btusb: fix non-atomic allocation in completion handler + - orinoco_usb: fix interface sanity check + - rsi_91x_usb: fix interface sanity check + - usb: dwc3: pci: add ID for the Intel Comet Lake -V variant + - usb: host: xhci-tegra: set MODULE_FIRMWARE for tegra186 + - USB: serial: ir-usb: add missing endpoint sanity check + - USB: serial: ir-usb: fix link-speed handling + - USB: serial: ir-usb: fix IrLAP framing + - usb: dwc3: turn off VBUS when leaving host mode + - usb: typec: wcove: fix "op-sink-microwatt" default that was in mW + - usb: typec: fusb302: fix "op-sink-microwatt" default that was in mW + - staging: most: net: fix buffer overflow + - staging: wlan-ng: ensure error return is actually returned + - staging: vt6656: correct packet types for CTS protect, mode. + - staging: vt6656: use NULLFUCTION stack on mac80211 + - staging: vt6656: Fix false Tx excessive retries reporting. + - serial: 8250_bcm2835aux: Fix line mismatch on driver unbind + - serial: imx: fix a race condition in receive path + - debugfs: Return -EPERM when locked down + - component: do not dereference opaque pointer in debugfs + - binder: fix log spam for existing debugfs file creation. + - mei: hdcp: bind only with i915 on the same PCH + - mei: me: add comet point (lake) H device ids + - iio: adc: stm32-dfsdm: fix single conversion + - iio: st_gyro: Correct data for LSM9DS0 gyro + - driver core: Fix test_async_driver_probe if NUMA is disabled + - crypto: chelsio - fix writing tfm flags to wrong place + - CIFS: Fix task struct use-after-free on reconnect + - cifs: set correct max-buffer-size for smb2_ioctl_init() + - cifs: Fix memory allocation in __smb2_handle_cancelled_cmd() + - ath9k: fix storage endpoint lookup + - brcmfmac: fix interface sanity check + - rtl8xxxu: fix interface sanity check + - zd1211rw: fix storage endpoint lookup + - net_sched: ematch: reject invalid TCF_EM_SIMPLE + - net_sched: fix ops->bind_class() implementations + - net_sched: walk through all child classes in tc_bind_tclass() + - net: socionext: fix possible user-after-free in netsec_process_rx + - net: socionext: fix xdp_result initialization in netsec_process_rx + - udp: segment looped gso packets correctly + - mlxsw: minimal: Fix an error handling path in 'mlxsw_m_port_create()' + - net: include struct nhmsg size in nh nlmsg size + - rxrpc: Fix use-after-free in rxrpc_receive_data() + - arc: eznps: fix allmodconfig kconfig warning + - HID: Add quirk for Xin-Mo Dual Controller + - HID: ite: Add USB id match for Acer SW5-012 keyboard dock + - HID: asus: Ignore Asus vendor-page usage-code 0xff events + - HID: Add quirk for incorrect input length on Lenovo Y720 + - HID: intel-ish-hid: ipc: add CMP device id + - HID: wacom: Recognize new MobileStudio Pro PID + - ASoC: SOF: fix fault at driver unload after failed probe + - ASoC: SOF: Intel: hda: hda-dai: fix oops on hda_link .hw_free + - drivers/hid/hid-multitouch.c: fix a possible null pointer access. + - phy: qcom-qmp: Increase PHY ready timeout + - ASoC: fsl_audmix: add missed pm_runtime_disable + - ASoC: topology: Prevent use-after-free in snd_soc_get_pcm_runtime() + - phy: cpcap-usb: Prevent USB line glitches from waking up modem + - HID: intel-ish-hid: ipc: Add Tiger Lake PCI device ID + - watchdog: max77620_wdt: fix potential build errors + - watchdog: rn5t618_wdt: fix module aliases + - watchdog: orion: fix platform_get_irq() complaints + - usb: musb: jz4740: Silence error if code is -EPROBE_DEFER + - can: tcan4x5x: tcan4x5x_parse_config(): reset device before register access + - spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls + - net: Google gve: Remove dma_wmb() before ringing doorbell + - drivers/net/b44: Change to non-atomic bit operations on pwol_mask + - net: wan: sdla: Fix cast from pointer to integer of different size + - gpio: max77620: Add missing dependency on GPIOLIB_IRQCHIP + - iommu/dma: fix variable 'cookie' set but not used + - drm/amd/display: Reduce HDMI pixel encoding if max clock is exceeded + - stmmac: debugfs entry name is not be changed when udev rename device name. + - atm: eni: fix uninitialized variable warning + - HID: steam: Fix input device disappearing + - extcon-intel-cht-wc: Don't reset USB data connection at probe + - ASoC: Intel: cht_bsw_rt5645: Add quirk for boards using pmc_plt_clk_0 + - drm/amdgpu/SRIOV: add navi12 pci id for SRIOV (v2) + - libbpf: Fix BTF-defined map's __type macro handling of arrays + - staging: mt7621-pci: add quirks for 'E2' revision using + 'soc_device_attribute' + - platform/x86: dell-laptop: disable kbd backlight on Inspiron 10xx + - PCI: Add DMA alias quirk for Intel VCA NTB + - media: dvbsky: add support for eyeTV Geniatech T2 lite + - bus: ti-sysc: Handle mstandby quirk and use it for musb + - bus: ti-sysc: Use swsup quirks also for am335x musb + - spi: pxa2xx: Add support for Intel Comet Lake-H + - iommu/amd: Support multiple PCI DMA aliases in device table + - iommu/amd: Support multiple PCI DMA aliases in IRQ Remapping + - perf/imx_ddr: Add enhanced AXI ID filter support + - ARM: config: aspeed-g5: Enable 8250_DW quirks + - ARM: OMAP2+: SmartReflex: add omap_sr_pdata definition + - mmc: sdhci-pci: Quirk for AMD SDHC Device 0x7906 + - mmc: sdhci-pci: Add support for Intel JSL + - bus: ti-sysc: Add module enable quirk for audio AESS + - usb-storage: Disable UAS on JMicron SATA enclosure + - ALSA: hda/realtek - Move some alc236 pintbls to fallback table + - Bluetooth: Allow combination of BDADDR_PROPERTY and INVALID_BDADDR quirks + - Bluetooth: btbcm: Use the BDADDR_PROPERTY quirk + - bus: ti-sysc: Fix missing force mstandby quirk handling + - rsi: fix use-after-free on failed probe and unbind + - rsi: fix use-after-free on probe errors + - rsi: fix memory leak on failed URB submission + - rsi: fix non-atomic allocation in completion handler + - crypto: af_alg - Use bh_lock_sock in sk_destruct + - crypto: vmx - reject xts inputs that are too short + - crypto: caam - do not reset pointer size from MCFGR register + - crypto: pcrypt - Fix user-after-free on module unload + - KVM: arm64: Write arch.mdcr_el2 changes since last vcpu_load on VHE + - Revert "um: Enable CONFIG_CONSTRUCTORS" + - power/supply: ingenic-battery: Don't change scale if there's only one + - Linux 5.4.17 + * Miscellaneous Ubuntu changes + - [Packaging] dkms -- switch basic provides to *-modules + - update dkms package versions + + -- Seth Forshee Sat, 15 Feb 2020 15:41:40 -0600 + +linux-oracle-5.4 (5.4.0-1001.1) focal; urgency=medium + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] update update.conf + - [Packaging] update variants + + * Miscellaneous Ubuntu changes + - [Packaging] Change package name to linux-oracle-5.4 + - [Packaging] Remove i386 and x32 arches from control vars + - [Packaging] Regenerate reconstruct + - [Packaging] Remove python-dev build-depends + - [Packaging] dkms -- add Provides: specifiers + - [Packaging] Replace wget with curl in build-depends + - [Config] Enable wireguard dkms build + - [Debian] Add upstream version to packagenames in getabis + - [Config] Update configs and annotations for 5.4 + + -- Seth Forshee Wed, 05 Feb 2020 15:02:31 -0600 + +linux-oracle-5.4 (5.4.0-1000.0) focal; urgency=medium + + * Empty entry. + + -- Seth Forshee Wed, 05 Feb 2020 14:12:59 -0600 + +linux-oracle (5.3.0-1009.10) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1009.10 -proposed tracker (LP: #1861208) + + [ Ubuntu: 5.3.0-40.32 ] + + * eoan/linux: 5.3.0-40.32 -proposed tracker (LP: #1861214) + * No sof soundcard for 'ASoC: CODEC DAI intel-hdmi-hifi1 not registered' after + modprobe sof (LP: #1860248) + - ASoC: SOF: Intel: fix HDA codec driver probe with multiple controllers + * ocfs2-tools is causing kernel panics in Ubuntu Focal (Ubuntu-5.4.0-9.12) + (LP: #1852122) + - ocfs2: fix the crash due to call ocfs2_get_dlm_debug once less + * QAT drivers for C3XXX and C62X not included as modules (LP: #1845959) + - [Config] CRYPTO_DEV_QAT_C3XXX=m, CRYPTO_DEV_QAT_C62X=m and + CRYPTO_DEV_QAT_DH895xCC=m + * Eoan update: upstream stable patchset 2020-01-24 (LP: #1860816) + - scsi: lpfc: Fix discovery failures when target device connectivity bounces + - scsi: mpt3sas: Fix clear pending bit in ioctl status + - scsi: lpfc: Fix locking on mailbox command completion + - Input: atmel_mxt_ts - disable IRQ across suspend + - f2fs: fix to update time in lazytime mode + - iommu: rockchip: Free domain on .domain_free + - iommu/tegra-smmu: Fix page tables in > 4 GiB memory + - dmaengine: xilinx_dma: Clear desc_pendingcount in xilinx_dma_reset + - scsi: target: compare full CHAP_A Algorithm strings + - scsi: lpfc: Fix SLI3 hba in loop mode not discovering devices + - scsi: csiostor: Don't enable IRQs too early + - scsi: hisi_sas: Replace in_softirq() check in hisi_sas_task_exec() + - powerpc/pseries: Mark accumulate_stolen_time() as notrace + - powerpc/pseries: Don't fail hash page table insert for bolted mapping + - powerpc/tools: Don't quote $objdump in scripts + - dma-debug: add a schedule point in debug_dma_dump_mappings() + - leds: lm3692x: Handle failure to probe the regulator + - clocksource/drivers/asm9260: Add a check for of_clk_get + - clocksource/drivers/timer-of: Use unique device name instead of timer + - powerpc/security/book3s64: Report L1TF status in sysfs + - powerpc/book3s64/hash: Add cond_resched to avoid soft lockup warning + - ext4: update direct I/O read lock pattern for IOCB_NOWAIT + - ext4: iomap that extends beyond EOF should be marked dirty + - jbd2: Fix statistics for the number of logged blocks + - scsi: tracing: Fix handling of TRANSFER LENGTH == 0 for READ(6) and WRITE(6) + - scsi: lpfc: Fix duplicate unreg_rpi error in port offline flow + - f2fs: fix to update dir's i_pino during cross_rename + - clk: qcom: Allow constant ratio freq tables for rcg + - clk: clk-gpio: propagate rate change to parent + - irqchip/irq-bcm7038-l1: Enable parent IRQ if necessary + - irqchip: ingenic: Error out if IRQ domain creation failed + - fs/quota: handle overflows of sysctl fs.quota.* and report as unsigned long + - scsi: lpfc: fix: Coverity: lpfc_cmpl_els_rsp(): Null pointer dereferences + - PCI: rpaphp: Fix up pointer to first drc-info entry + - scsi: ufs: fix potential bug which ends in system hang + - powerpc/pseries/cmm: Implement release() function for sysfs device + - PCI: rpaphp: Don't rely on firmware feature to imply drc-info support + - PCI: rpaphp: Annotate and correctly byte swap DRC properties + - PCI: rpaphp: Correctly match ibm, my-drc-index to drc-name when using drc- + info + - powerpc/security: Fix wrong message when RFI Flush is disable + - scsi: atari_scsi: sun3_scsi: Set sg_tablesize to 1 instead of SG_NONE + - clk: pxa: fix one of the pxa RTC clocks + - bcache: at least try to shrink 1 node in bch_mca_scan() + - HID: quirks: Add quirk for HP MSU1465 PIXART OEM mouse + - HID: logitech-hidpp: Silence intermittent get_battery_capacity errors + - ARM: 8937/1: spectre-v2: remove Brahma-B53 from hardening + - libnvdimm/btt: fix variable 'rc' set but not used + - HID: Improve Windows Precision Touchpad detection. + - HID: rmi: Check that the RMI_STARTED bit is set before unregistering the RMI + transport device + - watchdog: Fix the race between the release of watchdog_core_data and cdev + - scsi: pm80xx: Fix for SATA device discovery + - scsi: ufs: Fix error handing during hibern8 enter + - scsi: scsi_debug: num_tgts must be >= 0 + - scsi: NCR5380: Add disconnect_mask module parameter + - scsi: iscsi: Don't send data to unbound connection + - scsi: target: iscsi: Wait for all commands to finish before freeing a + session + - gpio: mpc8xxx: Don't overwrite default irq_set_type callback + - apparmor: fix unsigned len comparison with less than zero + - scripts/kallsyms: fix definitely-lost memory leak + - powerpc: Don't add -mabi= flags when building with Clang + - cdrom: respect device capabilities during opening action + - perf script: Fix brstackinsn for AUXTRACE + - perf regs: Make perf_reg_name() return "unknown" instead of NULL + - s390/zcrypt: handle new reply code FILTERED_BY_HYPERVISOR + - libfdt: define INT32_MAX and UINT32_MAX in libfdt_env.h + - s390/cpum_sf: Check for SDBT and SDB consistency + - ocfs2: fix passing zero to 'PTR_ERR' warning + - mailbox: imx: Fix Tx doorbell shutdown path + - kernel: sysctl: make drop_caches write-only + - userfaultfd: require CAP_SYS_PTRACE for UFFD_FEATURE_EVENT_FORK + - net, sysctl: Fix compiler warning when only cBPF is present + - netfilter: nf_queue: enqueue skbs with NULL dst + - ALSA: hda - Downgrade error message for single-cmd fallback + - bonding: fix active-backup transition after link failure + - netfilter: ebtables: compat: reject all padding in matches/watchers + - 6pack,mkiss: fix possible deadlock + - netfilter: bridge: make sure to pull arp header in br_nf_forward_arp() + - inetpeer: fix data-race in inet_putpeer / inet_putpeer + - net: add a READ_ONCE() in skb_peek_tail() + - net: icmp: fix data-race in cmp_global_allow() + - hrtimer: Annotate lockless access to timer->state + - net: ena: fix napi handler misbehavior when the napi budget is zero + - net/mlxfw: Fix out-of-memory error in mfa2 flash burning + - net: stmmac: dwmac-meson8b: Fix the RGMII TX delay on Meson8b/8m2 SoCs + - ptp: fix the race between the release of ptp_clock and cdev + - tcp: Fix highest_sack and highest_sack_seq + - udp: fix integer overflow while computing available space in sk_rcvbuf + - vhost/vsock: accept only packets with the right dst_cid + - net: add bool confirm_neigh parameter for dst_ops.update_pmtu + - ip6_gre: do not confirm neighbor when do pmtu update + - gtp: do not confirm neighbor when do pmtu update + - net/dst: add new function skb_dst_update_pmtu_no_confirm + - tunnel: do not confirm neighbor when do pmtu update + - vti: do not confirm neighbor when do pmtu update + - sit: do not confirm neighbor when do pmtu update + - net/dst: do not confirm neighbor for vxlan and geneve pmtu update + - gtp: do not allow adding duplicate tid and ms_addr pdp context + - net: marvell: mvpp2: phylink requires the link interrupt + - tcp/dccp: fix possible race __inet_lookup_established() + - tcp: do not send empty skb from tcp_write_xmit() + - gtp: fix wrong condition in gtp_genl_dump_pdp() + - gtp: fix an use-after-free in ipv4_pdp_find() + - gtp: avoid zero size hashtable + - scsi: lpfc: Fix spinlock_irq issues in lpfc_els_flush_cmd() + - scsi: mpt3sas: Reject NVMe Encap cmnds to unsupported HBA + - gpio: mxc: Only get the second IRQ when there is more than one IRQ + - powerpc/papr_scm: Fix an off-by-one check in papr_scm_meta_{get, set} + - scsi: lpfc: Fix hardlockup in lpfc_abort_handler + - scsi: hisi_sas: Delete the debugfs folder of hisi_sas when the probe fails + - Input: st1232 - do not reset the chip too early + - selftests/powerpc: Fixup clobbers for TM tests + - dma-mapping: Add vmap checks to dma_map_single() + - dma-mapping: fix handling of dma-ranges for reserved memory (again) + - dmaengine: fsl-qdma: Handle invalid qdma-queue0 IRQ + - leds: an30259a: add a check for devm_regmap_init_i2c + - leds: trigger: netdev: fix handling on interface rename + - dtc: Use pkg-config to locate libyaml + - selftests/powerpc: Skip tm-signal-sigreturn-nt if TM not available + - scsi: lpfc: Fix unexpected error messages during RSCN handling + - clk: qcom: smd: Add missing pnoc clock + - dma-direct: check for overflows on 32 bit DMA addresses + - i2c: stm32f7: fix & reorder remove & probe error handling + - iomap: fix return value of iomap_dio_bio_actor on 32bit systems + - Input: ili210x - handle errors from input_mt_init_slots() + - scsi: zorro_esp: Limit DMA transfers to 65536 bytes (except on Fastlane) + - powerpc/book3s/mm: Update Oops message to print the correct translation in + use + - powerpc/fixmap: Use __fix_to_virt() instead of fix_to_virt() + - scsi: target: core: Release SPC-2 reservations when closing a session + - scsi: ufs: Fix up auto hibern8 enablement + - habanalabs: skip VA block list update in reset flow + - platform/x86: intel_pmc_core: Fix the SoC naming inconsistency + - gpio: lynxpoint: Setup correct IRQ handlers + - tools/power/x86/intel-speed-select: Ignore missing config level + - cifs: Fix use-after-free bug in cifs_reconnect() + - of: unittest: fix memory leak in attach_node_and_children + - mailbox: imx: Clear the right interrupts at shutdown + - s390/unwind: filter out unreliable bogus %r14 + - s390: disable preemption when switching to nodat stack with CALL_ON_STACK + - selftests: vm: add fragment CONFIG_TEST_VMALLOC + - mm/hugetlbfs: fix error handling when setting up mounts + - sctp: fix err handling of stream initialization + - Revert "iwlwifi: assign directly to iwl_trans->cfg in QuZ detection" + - powerpc: Fix __clear_user() with KUAP enabled + - net/smc: add fallback check to connect() + - tomoyo: Don't use nifty names on sockets. + - uaccess: disallow > INT_MAX copy sizes + - drm: limit to INT_MAX in create_blob ioctl + - xfs: fix mount failure crash on invalid iclog memory access + - cxgb4/cxgb4vf: fix flow control display for auto negotiation + - net: dsa: bcm_sf2: Fix IP fragment location and behavior + - net: phy: aquantia: add suspend / resume ops for AQR105 + - net/sched: act_mirred: Pull mac prior redir to non mac_header_xmit device + - net/sched: add delete_empty() to filters and use it in cls_flower + - net_sched: sch_fq: properly set sk->sk_pacing_status + - bnxt_en: Fix MSIX request logic for RDMA driver. + - bnxt_en: Return error if FW returns more data than dump length + - mlxsw: spectrum_router: Skip loopback RIFs during MAC validation + - mlxsw: spectrum: Use dedicated policer for VRRP packets + - net: dsa: sja1105: Reconcile the meaning of TPID and TPID2 for E/T and + P/Q/R/S + - hv_netvsc: Fix tx_table init in rndis_set_subchannel() + - bnxt: apply computed clamp value for coalece parameter + - ipv6/addrconf: only check invalid header values when NETLINK_F_STRICT_CHK is + set + - net: phylink: fix interface passed to mac_link_up + - mmc: sdhci-of-esdhc: fix up erratum A-008171 workaround + - mmc: sdhci-of-esdhc: re-implement erratum A-009204 workaround + - mm/hugetlbfs: fix for_each_hstate() loop in init_hugetlbfs_fs() + - md: make sure desc_nr less than MD_SB_DISKS + * Eoan update: upstream stable patchset 2020-01-21 (LP: #1860490) + - af_packet: set defaule value for tmo + - fjes: fix missed check in fjes_acpi_add + - mod_devicetable: fix PHY module format + - net: dst: Force 4-byte alignment of dst_metrics + - net: gemini: Fix memory leak in gmac_setup_txqs + - net: hisilicon: Fix a BUG trigered by wrong bytes_compl + - net: nfc: nci: fix a possible sleep-in-atomic-context bug in + nci_uart_tty_receive() + - net: qlogic: Fix error paths in ql_alloc_large_buffers() + - net: usb: lan78xx: Fix suspend/resume PHY register access error + - qede: Disable hardware gro when xdp prog is installed + - qede: Fix multicast mac configuration + - sctp: fully initialize v4 addr in some functions + - selftests: forwarding: Delete IPv6 address at the end + - btrfs: don't double lock the subvol_sem for rename exchange + - btrfs: do not call synchronize_srcu() in inode_tree_del + - Btrfs: fix missing data checksums after replaying a log tree + - btrfs: send: remove WARN_ON for readonly mount + - btrfs: abort transaction after failed inode updates in create_subvol + - btrfs: skip log replay on orphaned roots + - btrfs: do not leak reloc root if we fail to read the fs root + - btrfs: handle ENOENT in btrfs_uuid_tree_iterate + - Btrfs: fix removal logic of the tree mod log that leads to use-after-free + issues + - ALSA: pcm: Avoid possible info leaks from PCM stream buffers + - ALSA: hda/ca0132 - Keep power on during processing DSP response + - ALSA: hda/ca0132 - Avoid endless loop + - ALSA: hda/ca0132 - Fix work handling in delayed HP detection + - drm: mst: Fix query_payload ack reply struct + - drm/panel: Add missing drm_panel_init() in panel drivers + - drm/bridge: analogix-anx78xx: silence -EPROBE_DEFER warnings + - iio: light: bh1750: Resolve compiler warning and make code more readable + - drm/amdgpu: grab the id mgr lock while accessing passid_mapping + - spi: Add call to spi_slave_abort() function when spidev driver is released + - staging: rtl8192u: fix multiple memory leaks on error path + - staging: rtl8188eu: fix possible null dereference + - rtlwifi: prevent memory leak in rtl_usb_probe + - libertas: fix a potential NULL pointer dereference + - ath10k: fix backtrace on coredump + - IB/iser: bound protection_sg size by data_sg size + - media: am437x-vpfe: Setting STD to current value is not an error + - media: i2c: ov2659: fix s_stream return value + - media: ov6650: Fix crop rectangle alignment not passed back + - media: i2c: ov2659: Fix missing 720p register config + - media: ov6650: Fix stored frame format not in sync with hardware + - media: ov6650: Fix stored crop rectangle not in sync with hardware + - tools/power/cpupower: Fix initializer override in hsw_ext_cstates + - media: venus: core: Fix msm8996 frequency table + - ath10k: fix offchannel tx failure when no ath10k_mac_tx_frm_has_freq + - pinctrl: devicetree: Avoid taking direct reference to device name string + - drm/amdkfd: fix a potential NULL pointer dereference (v2) + - selftests/bpf: Correct path to include msg + path + - media: venus: Fix occasionally failures to suspend + - usb: renesas_usbhs: add suspend event support in gadget mode + - hwrng: omap3-rom - Call clk_disable_unprepare() on exit only if not idled + - regulator: max8907: Fix the usage of uninitialized variable in + max8907_regulator_probe() + - media: flexcop-usb: fix NULL-ptr deref in flexcop_usb_transfer_init() + - media: cec-funcs.h: add status_req checks + - drm/bridge: dw-hdmi: Refuse DDC/CI transfers on the internal I2C controller + - samples: pktgen: fix proc_cmd command result check logic + - block: Fix writeback throttling W=1 compiler warnings + - mwifiex: pcie: Fix memory leak in mwifiex_pcie_init_evt_ring + - drm/drm_vblank: Change EINVAL by the correct errno + - media: cx88: Fix some error handling path in 'cx8800_initdev()' + - media: ti-vpe: vpe: Fix Motion Vector vpdma stride + - media: ti-vpe: vpe: fix a v4l2-compliance warning about invalid pixel format + - media: ti-vpe: vpe: fix a v4l2-compliance failure about frame sequence + number + - media: ti-vpe: vpe: Make sure YUYV is set as default format + - media: ti-vpe: vpe: fix a v4l2-compliance failure causing a kernel panic + - media: ti-vpe: vpe: ensure buffers are cleaned up properly in abort cases + - media: ti-vpe: vpe: fix a v4l2-compliance failure about invalid sizeimage + - syscalls/x86: Use the correct function type in SYSCALL_DEFINE0 + - drm/amd/display: Fix dongle_caps containing stale information. + - extcon: sm5502: Reset registers during initialization + - x86/mm: Use the correct function type for native_set_fixmap() + - ath10k: Correct error handling of dma_map_single() + - drm/bridge: dw-hdmi: Restore audio when setting a mode + - perf test: Report failure for mmap events + - perf report: Add warning when libunwind not compiled in + - usb: usbfs: Suppress problematic bind and unbind uevents. + - iio: adc: max1027: Reset the device at probe time + - Bluetooth: missed cpu_to_le16 conversion in hci_init4_req + - Bluetooth: Workaround directed advertising bug in Broadcom controllers + - Bluetooth: hci_core: fix init for HCI_USER_CHANNEL + - bpf/stackmap: Fix deadlock with rq_lock in bpf_get_stack() + - x86/mce: Lower throttling MCE messages' priority to warning + - perf tests: Disable bp_signal testing for arm64 + - drm/gma500: fix memory disclosures due to uninitialized bytes + - rtl8xxxu: fix RTL8723BU connection failure issue after warm reboot + - ipmi: Don't allow device module unload when in use + - x86/ioapic: Prevent inconsistent state when moving an interrupt + - media: smiapp: Register sensor after enabling runtime PM on the device + - md/bitmap: avoid race window between md_bitmap_resize and + bitmap_file_clear_bit + - arm64: psci: Reduce the waiting time for cpu_psci_cpu_kill() + - i40e: initialize ITRN registers with correct values + - net: phy: dp83867: enable robust auto-mdix + - drm/tegra: sor: Use correct SOR index on Tegra210 + - spi: sprd: adi: Add missing lock protection when rebooting + - ACPI: button: Add DMI quirk for Medion Akoya E2215T + - RDMA/qedr: Fix memory leak in user qp and mr + - gpu: host1x: Allocate gather copy for host1x + - net: dsa: LAN9303: select REGMAP when LAN9303 enable + - phy: qcom-usb-hs: Fix extcon double register after power cycle + - s390/time: ensure get_clock_monotonic() returns monotonic values + - s390/mm: add mm_pxd_folded() checks to pxd_free() + - net: hns3: add struct netdev_queue debug info for TX timeout + - libata: Ensure ata_port probe has completed before detach + - loop: fix no-unmap write-zeroes request behavior + - pinctrl: sh-pfc: sh7734: Fix duplicate TCLK1_B + - iio: dln2-adc: fix iio_triggered_buffer_postenable() position + - libbpf: Fix error handling in bpf_map__reuse_fd() + - Bluetooth: Fix advertising duplicated flags + - pinctrl: amd: fix __iomem annotation in amd_gpio_irq_handler() + - ixgbe: protect TX timestamping from API misuse + - media: rcar_drif: fix a memory disclosure + - media: v4l2-core: fix touch support in v4l_g_fmt + - nvmem: imx-ocotp: reset error status on probe + - rfkill: allocate static minor + - bnx2x: Fix PF-VF communication over multi-cos queues. + - spi: img-spfi: fix potential double release + - ALSA: timer: Limit max amount of slave instances + - rtlwifi: fix memory leak in rtl92c_set_fw_rsvdpagepkt() + - perf probe: Fix to find range-only function instance + - perf probe: Fix to list probe event with correct line number + - perf jevents: Fix resource leak in process_mapfile() and main() + - perf probe: Walk function lines in lexical blocks + - perf probe: Fix to probe an inline function which has no entry pc + - perf probe: Fix to show ranges of variables in functions without entry_pc + - perf probe: Fix to show inlined function callsite without entry_pc + - libsubcmd: Use -O0 with DEBUG=1 + - perf probe: Fix to probe a function which has no entry pc + - perf tools: Splice events onto evlist even on error + - drm/amdgpu: disallow direct upload save restore list from gfx driver + - drm/amdgpu: fix potential double drop fence reference + - xen/gntdev: Use select for DMA_SHARED_BUFFER + - perf parse: If pmu configuration fails free terms + - perf probe: Skip overlapped location on searching variables + - perf probe: Return a better scope DIE if there is no best scope + - perf probe: Fix to show calling lines of inlined functions + - perf probe: Skip end-of-sequence and non statement lines + - perf probe: Filter out instances except for inlined subroutine and + subprogram + - ath10k: fix get invalid tx rate for Mesh metric + - fsi: core: Fix small accesses and unaligned offsets via sysfs + - media: pvrusb2: Fix oops on tear-down when radio support is not present + - soundwire: intel: fix PDI/stream mapping for Bulk + - crypto: atmel - Fix authenc support when it is set to m + - ice: delay less + - media: si470x-i2c: add missed operations in remove + - EDAC/ghes: Fix grain calculation + - spi: pxa2xx: Add missed security checks + - ASoC: rt5677: Mark reg RT5677_PWR_ANLG2 as volatile + - iio: dac: ad5446: Add support for new AD5600 DAC + - ASoC: Intel: kbl_rt5663_rt5514_max98927: Add dmic format constraint + - s390/disassembler: don't hide instruction addresses + - parport: load lowlevel driver if ports not found + - bcache: fix static checker warning in bcache_device_free() + - cpufreq: Register drivers only after CPU devices have been registered + - x86/crash: Add a forward declaration of struct kimage + - tracing: use kvcalloc for tgid_map array allocation + - tracing/kprobe: Check whether the non-suffixed symbol is notrace + - iwlwifi: mvm: fix unaligned read of rx_pkt_status + - ASoC: wm8904: fix regcache handling + - spi: tegra20-slink: add missed clk_unprepare + - tun: fix data-race in gro_normal_list() + - crypto: virtio - deal with unsupported input sizes + - mmc: tmio: Add MMC_CAP_ERASE to allow erase/discard/trim requests + - btrfs: don't prematurely free work in end_workqueue_fn() + - btrfs: don't prematurely free work in run_ordered_work() + - ASoC: wm2200: add missed operations in remove and probe failure + - spi: st-ssc4: add missed pm_runtime_disable + - ASoC: wm5100: add missed pm_runtime_disable + - ASoC: Intel: bytcr_rt5640: Update quirk for Acer Switch 10 SW5-012 2-in-1 + - x86/insn: Add some Intel instructions to the opcode map + - brcmfmac: remove monitor interface when detaching + - iwlwifi: check kasprintf() return value + - fbtft: Make sure string is NULL terminated + - net: ethernet: ti: ale: clean ale tbl on init and intf restart + - crypto: sun4i-ss - Fix 64-bit size_t warnings + - crypto: sun4i-ss - Fix 64-bit size_t warnings on sun4i-ss-hash.c + - mac80211: consider QoS Null frames for STA_NULLFUNC_ACKED + - crypto: vmx - Avoid weird build failures + - libtraceevent: Fix memory leakage in copy_filter_type + - mips: fix build when "48 bits virtual memory" is enabled + - drm/amdgpu: fix bad DMA from INTERRUPT_CNTL2 + - net: phy: initialise phydev speed and duplex sanely + - btrfs: don't prematurely free work in reada_start_machine_worker() + - btrfs: don't prematurely free work in scrub_missing_raid56_worker() + - Revert "mmc: sdhci: Fix incorrect switch to HS mode" + - mmc: mediatek: fix CMD_TA to 2 for MT8173 HS200/HS400 mode + - can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices + - usb: xhci: Fix build warning seen with CONFIG_PM=n + - drm/amdgpu: fix uninitialized variable pasid_mapping_needed + - s390/ftrace: fix endless recursion in function_graph tracer + - btrfs: return error pointer from alloc_test_extent_buffer + - usbip: Fix receive error in vhci-hcd when using scatter-gather + - usbip: Fix error path of vhci_recv_ret_submit() + - cpufreq: Avoid leaving stale IRQ work items during CPU offline + - USB: EHCI: Do not return -EPIPE when hub is disconnected + - intel_th: pci: Add Comet Lake PCH-V support + - intel_th: pci: Add Elkhart Lake SOC support + - platform/x86: hp-wmi: Make buffer for HPWMI_FEATURE2_QUERY 128 bytes + - staging: comedi: gsc_hpdi: check dma_alloc_coherent() return value + - ext4: fix ext4_empty_dir() for directories with holes + - ext4: check for directory entries too close to block end + - ext4: unlock on error in ext4_expand_extra_isize() + - KVM: arm64: Ensure 'params' is initialised when looking up sys register + - x86/MCE/AMD: Do not use rdmsr_safe_on_cpu() in smca_configure() + - x86/MCE/AMD: Allow Reserved types to be overwritten in smca_banks[] + - powerpc/irq: fix stack overflow verification + - mmc: sdhci-msm: Correct the offset and value for DDR_CONFIG register + - mmc: sdhci-of-esdhc: Revert "mmc: sdhci-of-esdhc: add erratum A-009204 + support" + - mmc: sdhci: Update the tuning failed messages to pr_debug level + - mmc: sdhci-of-esdhc: fix P2020 errata handling + - mmc: sdhci: Workaround broken command queuing on Intel GLK + - mmc: sdhci: Add a quirk for broken command queuing + - nbd: fix shutdown and recv work deadlock v2 + - perf probe: Fix to show function entry line as probe-able + - net: phy: ensure that phy IDs are correctly typed + - nfp: flower: fix stats id allocation + - sctp: fix memleak on err handling of stream initialization + - neighbour: remove neigh_cleanup() method + - bonding: fix bond_neigh_init() + - net: ena: fix default tx interrupt moderation interval + - dpaa2-ptp: fix double free of the ptp_qoriq IRQ + - mlxsw: spectrum_router: Remove unlikely user-triggerable warning + - net: ethernet: ti: davinci_cpdma: fix warning "device driver frees DMA + memory with different size" + - net: stmmac: platform: Fix MDIO init for platforms without PHY + - Btrfs: make tree checker detect checksum items with overlapping ranges + - drm/vc4/vc4_hdmi: fill in connector info + - drm/mipi-dbi: fix a loop in debugfs code + - drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register + - drm: Use EOPNOTSUPP, not ENOTSUPP + - drm/amd/display: verify stream link before link test + - iio: max31856: add missing of_node and parent references to iio_dev + - drm/amdgpu/sriov: add ring_stop before ring_create in psp v11 code + - ath10k: add cleanup in ath10k_sta_state() + - drm/amd/display: Handle virtual signal type in disable_link() + - ath10k: Check if station exists before forwarding tx airtime report + - Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit30 when using SSI_SCK2 + and SSI_WS2" + - Revert "pinctrl: sh-pfc: r8a77990: Fix MOD_SEL1 bit31 when using SIM0_D" + - drm/komeda: Workaround for broken FLIP_COMPLETE timestamps + - spi: gpio: prevent memory leak in spi_gpio_probe + - media: cedrus: fill in bus_info for media device + - media: seco-cec: Add a missing 'release_region()' in an error handling path + - media: vim2m: Fix abort issue + - media: vim2m: Fix BUG_ON in vim2m_device_release() + - media: max2175: Fix build error without CONFIG_REGMAP_I2C + - media: ov6650: Fix control handler not freed on init error + - media: vimc: Fix gpf in rmmod path when stream is active + - drm/amd/display: Set number of pipes to 1 if the second pipe was disabled + - drm/sun4i: dsi: Fix TCON DRQ set bits + - x86/math-emu: Check __copy_from_user() result + - drm/amd/powerplay: A workaround to GPU RESET on APU + - rtw88: fix NSS of hw_cap + - drm/amd/display: fix struct init in update_bounding_box + - tools/memory-model: Fix data race detection for unordered store and load + - drm/amdkfd: Fix MQD size calculation + - selftests/bpf: Fix btf_dump padding test case + - libbpf: Fix struct end padding in btf_dump + - libbpf: Fix passing uninitialized bytes to setsockopt + - net/smc: increase device refcount for added link group + - team: call RCU read lock when walking the port_list + - misc: fastrpc: fix memory leak from miscdev->name + - drm/amd/display: Properly round nominal frequency for SPD + - drm/amd/display: wait for set pipe mcp command completion + - drm/amd/display: Program DWB watermarks from correct state + - rtw88: coex: Set 4 slot mode for A2DP + - perf test: Avoid infinite loop for task exit case + - perf vendor events arm64: Fix Hisi hip08 DDRC PMU eventname + - drm/amd/powerplay: avoid disabling ECC if RAS is enabled for VEGA20 + - Bluetooth: btusb: avoid unused function warning + - drm/amdgpu: fix amdgpu trace event print string format error + - staging: iio: ad9834: add a check for devm_clk_get + - power: supply: cpcap-battery: Check voltage before orderly_poweroff + - net: hns3: log and clear hardware error after reset complete + - ASoC: soc-pcm: fixup dpcm_prune_paths() loop continue + - RDMA/siw: Fix SQ/RQ drain logic + - media: cedrus: Fix undefined shift with a SHIFT_AND_MASK_BITS macro + - media: aspeed: set hsync and vsync polarities to normal before starting mode + detection + - drm/nouveau: Don't grab runtime PM refs for HPD IRQs + - media: ov6650: Fix stored frame interval not in sync with hardware + - media: ad5820: Define entity function + - media: ov5640: Make 2592x1944 mode only available at 15 fps + - media: st-mipid02: add a check for devm_gpiod_get_optional + - media: imx7-mipi-csis: Add a check for devm_regulator_get + - media: aspeed: clear garbage interrupts + - staging: wilc1000: potential corruption in wilc_parse_join_bss_param() + - drm: Don't free jobs in wait_event_interruptible() + - EDAC/amd64: Set grain per DIMM + - drm/amd/display: setting the DIG_MODE to the correct value. + - drm/amd/display: correctly populate dpp refclk in fpga + - regulator: core: Release coupled_rdevs on regulator_init_coupling() error + - ubsan, x86: Annotate and allow __ubsan_handle_shift_out_of_bounds() in + uaccess regions + - RDMA/hns: Fix memory leak on 'context' on error return path + - RDMA/qedr: Fix srqs xarray initialization + - RDMA/core: Set DMA parameters correctly + - phy: renesas: phy-rcar-gen2: Fix the array off by one warning + - s390: add error handling to perf_callchain_kernel + - net/mlx5e: Verify that rule has at least one fwd/drop action + - ALSA: bebob: expand sleep just after breaking connections for protocol + version 1 + - ALSA: pcm: Fix missing check of the new non-cached buffer type + - spi: sifive: disable clk when probe fails and remove + - media: staging/imx: Use a shorter name for driver + - nvmem: core: fix nvmem_cell_write inline function + - ASoC: SOF: topology: set trigger order for FE DAI link + - media: vivid: media_device_cleanup was called too early + - spi: dw: Fix Designware SPI loopback + - RDMA/core: Fix return code when modify_port isn't supported + - drm: msm: a6xx: fix debug bus register configuration + - perf cs-etm: Fix definition of macro TO_CS_QUEUE_NR + - ice: Check for null pointer dereference when setting rings + - net: avoid potential false sharing in neighbor related code + - libbpf: Fix negative FD close() in xsk_setup_xdp_prog() + - s390/bpf: Use kvcalloc for addrs array + - cgroup: freezer: don't change task and cgroups status unnecessarily + - selftests: proc: Make va_max 1MB + - drm/amdgpu: Avoid accidental thread reactivation. + - media: exynos4-is: fix wrong mdev and v4l2 dev order in error path + - selftests: net: Fix printf format warnings on arm + - media: v4l2-ctrl: Lock main_hdl on operations of requests_queued. + - media: vicodec: media_device_cleanup was called too early + - media: vim2m: media_device_cleanup was called too early + - bpf, testing: Workaround a verifier failure for test_progs + - net: dsa: sja1105: Disallow management xmit during switch reset + - net: ethernet: ti: Add dependency for TI_DAVINCI_EMAC + - qtnfmac: fix debugfs support for multiple cards + - qtnfmac: fix invalid channel information output + - qtnfmac: fix using skb after free + - RDMA/efa: Clear the admin command buffer prior to its submission + - regulator: core: Let boot-on regulators be powered off + - xhci-pci: Allow host runtime PM as default also for Intel Ice Lake xHCI + - perf/core: Fix the mlock accounting, again + - selftests, bpf: Fix test_tc_tunnel hanging + - selftests, bpf: Workaround an alu32 sub-register spilling issue + - net: phy: avoid matching all-ones clause 45 PHY IDs + - firmware_loader: Fix labels with comma for builtin firmware + - net-af_xdp: Use correct number of channels from ethtool + - s390/kasan: support memcpy_real with TRACE_IRQFLAGS + - ASoC: soc-pcm: check symmetry before hw_params + - s390/cpumf: Adjust registration of s390 PMU device drivers + - ice: Only disable VF state when freeing each VF resources + - RDMA/bnxt_re: Fix missing le16_to_cpu + - bpf: Provide better register bounds after jmp32 instructions + - RDMA/bnxt_re: Fix chip number validation Broadcom's Gen P5 series + - tpm: fix invalid locking in NONBLOCKING mode + - iommu: set group default domain before creating direct mappings + - iommu/vt-d: Fix dmar pte read access not set error + - iommu/vt-d: Set ISA bridge reserved region as relaxable + - iommu/vt-d: Allocate reserved region for ISA with correct permission + - can: xilinx_can: Fix missing Rx can packets on CANFD2.0 + - can: flexcan: fix possible deadlock and out-of-order reception after wakeup + - can: flexcan: poll MCR_LPM_ACK instead of GPR ACK for stop mode + acknowledgment + - selftests: net: tls: remove recv_rcvbuf test + - spi: dw: Correct handling of native chipselect + - spi: cadence: Correct handling of native chipselect + - ath10k: Revert "ath10k: add cleanup in ath10k_sta_state()" + - RDMA/siw: Fix post_recv QP state locking + - ARM: dts: Fix vcsi regulator to be always-on for droid4 to prevent hangs + - can: flexcan: add low power enter/exit acknowledgment helper + - spi: fsl: don't map irq during probe + - spi: fsl: use platform_get_irq() instead of of_irq_to_resource() + - efi/memreserve: Register reservations as 'reserved' in /proc/iomem + - KEYS: asymmetric: return ENOMEM if akcipher_request_alloc() fails + - mm: vmscan: protect shrinker idr replace with CONFIG_MEMCG + - intel_th: Fix freeing IRQs + - intel_th: msu: Fix window switching without windows + - tty/serial: atmel: fix out of range clock divider handling + - serial: sprd: Add clearing break interrupt operation + - pinctrl: baytrail: Really serialize all register accesses + - clk: imx: clk-imx7ulp: Add missing sentinel of ulp_div_table + - clk: imx: clk-composite-8m: add lock to gate/mux + - clk: imx: pll14xx: fix clk_pll14xx_wait_lock + - KVM: arm/arm64: Properly handle faulting of device mappings + - x86/mce: Fix possibly incorrect severity calculation on AMD + - ocxl: Fix concurrent AFU open and device removal + - md: no longer compare spare disk superblock events in super_load + - md: avoid invalid memory access for array sb->dev_roles + * CVE-2019-19965 + - scsi: libsas: stop discovering if oob mode is disconnected + * Eoan update: upstream stable patchset 2020-01-17 (LP: #1860179) + - mmc: block: Make card_busy_detect() a bit more generic + - mmc: block: Add CMD13 polling for MMC IOCTLS with R1B response + - mmc: core: Drop check for mmc_card_is_removable() in mmc_rescan() + - mmc: core: Re-work HW reset for SDIO cards + - PCI/switchtec: Read all 64 bits of part_event_bitmap + - PCI/PM: Always return devices to D0 when thawing + - PCI: pciehp: Avoid returning prematurely from sysfs requests + - PCI: Fix Intel ACS quirk UPDCR register address + - PCI/MSI: Fix incorrect MSI-X masking on resume + - PCI: Do not use bus number zero from EA capability + - PCI: rcar: Fix missing MACCTLR register setting in initialization sequence + - PCI: Apply Cavium ACS quirk to ThunderX2 and ThunderX3 + - xtensa: use MEMBLOCK_ALLOC_ANYWHERE for KASAN shadow map + - gfs2: Multi-block allocations in gfs2_page_mkwrite + - gfs2: fix glock reference problem in gfs2_trans_remove_revoke + - xtensa: fix TLB sanity checker + - xtensa: fix syscall_set_return_value + - rpmsg: glink: Set tail pointer to 0 at end of FIFO + - rpmsg: glink: Fix reuse intents memory leak issue + - rpmsg: glink: Fix use after free in open_ack TIMEOUT case + - rpmsg: glink: Put an extra reference during cleanup + - rpmsg: glink: Fix rpmsg_register_device err handling + - rpmsg: glink: Don't send pending rx_done during remove + - rpmsg: glink: Free pending deferred work on remove + - cifs: smbd: Return -EAGAIN when transport is reconnecting + - cifs: smbd: Only queue work for error recovery on memory registration + - cifs: smbd: Add messages on RDMA session destroy and reconnection + - cifs: smbd: Return -EINVAL when the number of iovs exceeds SMBDIRECT_MAX_SGE + - cifs: smbd: Return -ECONNABORTED when trasnport is not in connected state + - cifs: Don't display RDMA transport on reconnect + - CIFS: Respect O_SYNC and O_DIRECT flags during reconnect + - CIFS: Close open handle after interrupted close + - CIFS: Do not miss cancelled OPEN responses + - CIFS: Fix NULL pointer dereference in mid callback + - ARM: dts: s3c64xx: Fix init order of clock providers + - ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume() + - vfio/pci: call irq_bypass_unregister_producer() before freeing irq + - dma-buf: Fix memory leak in sync_file_merge() + - drm/mgag200: Extract device type from flags + - drm/mgag200: Store flags from PCI driver data in device structure + - drm/mgag200: Add workaround for HW that does not support 'startadd' + - drm/mgag200: Flag all G200 SE A machines as broken wrt + - drm: meson: venc: cvbs: fix CVBS mode matching + - dm mpath: remove harmful bio-based optimization + - dm btree: increase rebalance threshold in __rebalance2() + - dm thin metadata: Add support for a pre-commit callback + - dm thin: Flush data device before committing metadata + - scsi: ufs: Disable autohibern8 feature in Cadence UFS + - scsi: iscsi: Fix a potential deadlock in the timeout handler + - scsi: qla2xxx: Ignore NULL pointer in tcm_qla2xxx_free_mcmd + - scsi: qla2xxx: Initialize free_work before flushing it + - scsi: qla2xxx: Added support for MPI and PEP regions for ISP28XX + - scsi: qla2xxx: Correctly retrieve and interpret active flash region + - scsi: qla2xxx: Fix incorrect SFUB length used for Secure Flash Update MB Cmd + - drm/nouveau/kms/nv50-: Call outp_atomic_check_view() before handling PBN + - drm/nouveau/kms/nv50-: Store the bpc we're using in nv50_head_atom + - drm/nouveau/kms/nv50-: Limit MST BPC to 8 + - drm/i915/fbc: Disable fbc by default on all glk+ + - drm/radeon: fix r1xx/r2xx register checker for POT textures + - drm/dp_mst: Correct the bug in drm_dp_update_payload_part1() + - drm/amd/display: re-enable wait in pipelock, but add timeout + - drm/amd/display: add default clocks if not able to fetch them + - drm/amdgpu/gfx10: explicitly wait for cp idle after halt/unhalt + - drm/amdgpu/gfx10: re-init clear state buffer after gpu reset + - ALSA: hda: Fix regression by strip mask fix + * fstrim on nvme / AMD CPU fails and produces kernel error messages + (LP: #1856603) + - nvme: Discard workaround for non-conformant devices + * multi-zone raid0 corruption (LP: #1850540) + - md/raid0: avoid RAID0 data corruption due to layout confusion. + - md: add feature flag MD_FEATURE_RAID0_LAYOUT + - md/raid0: fix warning message for parameter default_layout + - md/raid0: Fix an error message in raid0_make_request() + - SAUCE: md/raid0: Link to wiki with guidance on multi-zone RAID0 layout + migration + - SAUCE: md/raid0: Use kernel specific layout + * Dell AIO can't adjust brightness (LP: #1858761) + - SAUCE: platform/x86: dell-uart-backlight: add retry for get scalar status + * [SRU][B/OEM-B/OEM-OSP1/D/E/Unstable] UBUNTU: SAUCE: Use native backlight on + Lenovo E41-25/45 (LP: #1859561) + - SAUCE: ACPI: video: Use native backlight on Lenovo E41-25/45 + * debian/tests/corosync: gfs2_jadd fails with ENOTTY for i386 package on amd64 + kernel (LP: #1859827) + - gfs2: add compat_ioctl support + * Smartpqi updates for 18.04.4 (LP: #1860690) + - scsi: smartpqi: add module param for exposure order + - scsi: smartpqi: add pci ids for fiberhome controller + - scsi: smartpqi: add module param to hide vsep + - scsi: smartpqi: add sysfs entries + - scsi: smartpqi: add bay identifier + - scsi: smartpqi: correct hang when deleting 32 lds + - scsi: smartpqi: add gigabyte controller + - scsi: smartpqi: correct REGNEWD return status + - scsi: smartpqi: add new pci ids + - scsi: smartpqi: update copyright + - scsi: smartpqi: bump version + * Fix misleading error message: Configuring the VNIC characteristics failed + (LP: #1860523) + - (upstream) s390/qeth: fix false reporting of VNIC CHAR config failure + * Disable ECKD Thin Provisioning to prevent data loss (LP: #1860535) + - SAUCE: s390/dasd: disable ese support due to possible data corruption + * alsa/sof: change to use hda hdmi codec driver to make hdmi audio on the + docking station work (LP: #1855666) + - ALSA: hda/hdmi - implement mst_no_extra_pcms flag + - ASoC: hdac_hda: add support for HDMI/DP as a HDA codec + - ASoC: Intel: skl-hda-dsp-generic: use snd-hda-codec-hdmi + - ASoC: Intel: skl-hda-dsp-generic: fix include guard name + - ASoC: SOF: Intel: add support for snd-hda-codec-hdmi + - ASoC: Intel: bxt-da7219-max98357a: common hdmi codec support + - ASoC: Intel: glk_rt5682_max98357a: common hdmi codec support + - ASoC: intel: sof_rt5682: common hdmi codec support + - ASoC: Intel: bxt_rt298: common hdmi codec support + - ASoC: SOF: enable sync_write in hdac_bus + - [config]: SND_SOC_SOF_HDA_COMMON_HDMI_CODEC=y + * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312) + - SAUCE: USB: core: Make port power cycle a seperate helper function + - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state + * [sas-1126]scsi: hisi_sas: Fix out of bound at debug_I_T_nexus_reset() + (LP: #1853992) + - scsi: hisi_sas: Fix out of bound at debug_I_T_nexus_reset() + * [sas-1126]scsi: hisi_sas: Assign NCQ tag for all NCQ commands (LP: #1853995) + - scsi: hisi_sas: Assign NCQ tag for all NCQ commands + * [sas-1126]scsi: hisi_sas: Fix the conflict between device gone and host + reset (LP: #1853997) + - scsi: hisi_sas: Fix the conflict between device gone and host reset + * scsi: hisi_sas: Check sas_port before using it (LP: #1855952) + - scsi: hisi_sas: Check sas_port before using it + * The system cannot resume from S3 if user unplugs the TB16 during suspend + state (LP: #1849269) + - PCI: pciehp: Do not disable interrupt twice on suspend + - PCI: pciehp: Prevent deadlock on disconnect + * [SRU][B/OEM-B/OEM-OSP1/D/E/F] Add LG I2C touchscreen multitouch support + (LP: #1857541) + - SAUCE: HID: multitouch: Add LG MELF0410 I2C touchscreen support + * cifs: DFS Caching feature causing problems traversing multi-tier DFS setups + (LP: #1854887) + - cifs: Fix retrieval of DFS referrals in cifs_mount() + * Fix Realtek Bluetooth firmware download (LP: #1856079) + - Bluetooth: btrtl: Fix an issue that failing to download the FW which size is + over 32K bytes + * usb-audio: the mic can't record any sound after resume on Dell Dock WD19 + (LP: #1857496) + - ALSA: usb-audio: set the interface format after resume on Dell WD19 + * [mgag200] Ubuntu 19.10 upgrade results in invisible mouse cursor on Matrox + G200eR2 (LP: #1851340) + - drm/mgag200: add in missing { } around if block + - drm/mgag200: Don't unpin the current cursor image's buffer. + - drm/mgag200: Set cursor scanout address to correct BO + - drm/mgag200: Pin displayed cursor BO to video memory + * [roce-1126]RDMA/hns: bugfix for slab-out-of-bounds when loading hip08 driver + (LP: #1853989) + - RDMA/hns: Bugfix for slab-out-of-bounds when unloading hip08 driver + - RDMA/hns: bugfix for slab-out-of-bounds when loading hip08 driver + * [hns-1126]net: hns3: revert to old channel when setting new channel num fail + (LP: #1853983) + - net: hns3: revert to old channel when setting new channel num fail + * [hns-1126]net: hns3: fix port setting handle for fibre port + (LP: #1853984) + - net: hns3: fix port setting handle for fibre port + * alsa/hda/realtek: the line-out jack doens't work on a dell AIO + (LP: #1855999) + - ALSA: hda/realtek - Line-out jack doesn't work on a Dell AIO + * change kconfig of the soundwire bus driver from y to m (LP: #1855685) + - [config]: SOUNDWIRE=m + * CVE-2019-19082 + - drm/amd/display: prevent memory leak + * Eoan update: 5.3.18 upstream stable release (LP: #1856870) + - inet: protect against too small mtu values. + - mqprio: Fix out-of-bounds access in mqprio_dump + - net: bridge: deny dev_set_mac_address() when unregistering + - net: dsa: fix flow dissection on Tx path + - net: ethernet: ti: cpsw: fix extra rx interrupt + - net: sched: fix dump qlen for sch_mq/sch_mqprio with NOLOCK subqueues + - net: thunderx: start phy before starting autonegotiation + - net/tls: Fix return values to avoid ENOTSUPP + - openvswitch: support asymmetric conntrack + - tcp: md5: fix potential overestimation of TCP option space + - tipc: fix ordering of tipc module init and exit routine + - net/mlx5e: Query global pause state before setting prio2buffer + - net: ipv6: add net argument to ip6_dst_lookup_flow + - net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup + - tcp: fix rejected syncookies due to stale timestamps + - tcp: tighten acceptance of ACKs not matching a child socket + - tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE() + - gre: refetch erspan header from skb->data after pskb_may_pull() + - Fixed updating of ethertype in function skb_mpls_pop + - hsr: fix a NULL pointer dereference in hsr_dev_xmit() + - net: Fixed updating of ethertype in skb_mpls_push() + - net/mlx5e: Fix TXQ indices to be sequential + - page_pool: do not release pool until inflight == 0. + - xdp: obtain the mem_id mutex before trying to remove an entry. + - Linux 5.3.18 + * Eoan update: 5.3.17 upstream stable release (LP: #1856869) + - usb: gadget: configfs: Fix missing spin_lock_init() + - usb: gadget: pch_udc: fix use after free + - Revert "nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T" + - scsi: zfcp: trace channel log even for FCP command responses + - scsi: qla2xxx: Fix driver unload hang + - scsi: qla2xxx: Fix memory leak when sending I/O fails + - media: venus: remove invalid compat_ioctl32 handler + - USB: uas: honor flag to avoid CAPACITY16 + - USB: uas: heed CAPACITY_HEURISTICS + - USB: documentation: flags on usb-storage versus UAS + - usb: Allow USB device to be warm reset in suspended state + - usb: host: xhci-tegra: Correct phy enable sequence + - binder: fix incorrect calculation for num_valid + - staging: rtl8188eu: fix interface sanity check + - staging: rtl8712: fix interface sanity check + - staging: vchiq: call unregister_chrdev_region() when driver registration + fails + - staging: gigaset: fix general protection fault on probe + - staging: gigaset: fix illegal free on probe errors + - staging: gigaset: add endpoint-type sanity check + - usb: xhci: only set D3hot for pci device + - xhci: Fix memory leak in xhci_add_in_port() + - xhci: fix USB3 device initiated resume race with roothub autosuspend + - xhci: Increase STS_HALT timeout in xhci_suspend() + - xhci: handle some XHCI_TRUST_TX_LENGTH quirks cases as default behaviour. + - xhci: make sure interrupts are restored to correct state + - interconnect: qcom: sdm845: Walk the list safely on node removal + - ARM: dts: pandora-common: define wl1251 as child node of mmc3 + - iio: adis16480: Add debugfs_reg_access entry + - iio: adis16480: Fix scales factors + - iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting + - iio: imu: inv_mpu6050: fix temperature reporting using bad unit + - iio: adc: ad7606: fix reading unnecessary data from device + - iio: adc: ad7124: Enable internal reference + - USB: atm: ueagle-atm: add missing endpoint check + - USB: idmouse: fix interface sanity checks + - USB: serial: io_edgeport: fix epic endpoint lookup + - usb: roles: fix a potential use after free + - USB: adutux: fix interface sanity check + - usb: core: urb: fix URB structure initialization function + - usb: mon: Fix a deadlock in usbmon between mmap and read + - tpm: add check after commands attribs tab allocation + - EDAC/altera: Use fast register IO for S10 IRQs + - brcmfmac: disable PCIe interrupts before bus reset + - mtd: spear_smi: Fix Write Burst mode + - mtd: rawnand: Change calculating of position page containing BBM + - virt_wifi: fix use-after-free in virt_wifi_newlink() + - virtio-balloon: fix managed page counts when migrating pages between zones + - usb: dwc3: gadget: Fix logical condition + - usb: dwc3: gadget: Clear started flag for non-IOC + - usb: dwc3: ep0: Clear started flag on completion + - phy: renesas: rcar-gen3-usb2: Fix sysfs interface of "role" + - usb: typec: fix use after free in typec_register_port() + - iwlwifi: pcie: fix support for transmitting SKBs with fraglist + - btrfs: check page->mapping when loading free space cache + - btrfs: use refcount_inc_not_zero in kill_all_nodes + - Btrfs: fix metadata space leak on fixup worker failure to set range as + delalloc + - Btrfs: fix negative subv_writers counter and data space leak after buffered + write + - btrfs: Avoid getting stuck during cyclic writebacks + - btrfs: Remove btrfs_bio::flags member + - Btrfs: send, skip backreference walking for extents with many references + - btrfs: record all roots for rename exchange on a subvol + - rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address + - rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer + - rtlwifi: rtl8192de: Fix missing enable interrupt flag + - lib: raid6: fix awk build warnings + - Revert "UBUNTU: SAUCE: ovl: fix lookup failure on multi lower squashfs" + - ovl: fix lookup failure on multi lower squashfs + - ovl: fix corner case of non-unique st_dev;st_ino + - ovl: relax WARN_ON() on rename to self + - hwrng: omap - Fix RNG wait loop timeout + - dm writecache: handle REQ_FUA + - dm zoned: reduce overhead of backing device checks + - workqueue: Fix spurious sanity check failures in destroy_workqueue() + - workqueue: Fix pwq ref leak in rescuer_thread() + - ASoC: rt5645: Fixed buddy jack support. + - ASoC: rt5645: Fixed typo for buddy jack support. + - ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report + - ASoC: fsl_audmix: Add spin lock to protect tdms + - md: improve handling of bio with REQ_PREFLUSH in md_flush_request() + - blk-mq: avoid sysfs buffer overflow with too many CPU cores + - cgroup: pids: use atomic64_t for pids->limit + - wil6210: check len before memcpy() calls + - ar5523: check NULL before memcpy() in ar5523_cmd() + - s390/mm: properly clear _PAGE_NOEXEC bit when it is not supported + - media: hantro: Fix s_fmt for dynamic resolution changes + - media: bdisp: fix memleak on release + - media: radio: wl1273: fix interrupt masking on release + - media: cec.h: CEC_OP_REC_FLAG_ values were swapped + - cpuidle: Do not unset the driver if it is there already + - cpuidle: teo: Ignore disabled idle states that are too deep + - cpuidle: teo: Rename local variable in teo_select() + - cpuidle: teo: Consider hits and misses metrics of disabled states + - cpuidle: teo: Fix "early hits" handling for disabled idle states + - erofs: zero out when listxattr is called with no xattr + - powerpc/perf: Disable trace_imc pmu + - intel_th: Fix a double put_device() in error path + - intel_th: pci: Add Ice Lake CPU support + - intel_th: pci: Add Tiger Lake CPU support + - PM / devfreq: Lock devfreq in trans_stat_show + - cpufreq: powernv: fix stack bloat and hard limit on number of CPUs + - ALSA: fireface: fix return value in error path of isochronous resources + reservation + - ALSA: oxfw: fix return value in error path of isochronous resources + reservation + - ACPI / utils: Move acpi_dev_get_first_match_dev() under CONFIG_ACPI + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C7 to lpss_device_links + - ACPI: LPSS: Add LNXVIDEO -> BYT I2C1 to lpss_device_links + - ACPI: LPSS: Add dmi quirk for skipping _DEP check for some device-links + - ACPI / hotplug / PCI: Allocate resources directly under the non-hotplug + bridge + - ACPI: OSL: only free map once in osl.c + - ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data() + - ACPI: PM: Avoid attaching ACPI PM domain to certain devices + - pinctrl: rza2: Fix gpio name typos + - pinctrl: armada-37xx: Fix irq mask access in armada_37xx_irq_set_type() + - pinctrl: samsung: Add of_node_put() before return in error path + - pinctrl: samsung: Fix device node refcount leaks in Exynos wakeup controller + init + - pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup + controller init + - pinctrl: samsung: Fix device node refcount leaks in init code + - pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup + controller init + - mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of + pandora_wl1251_init_card + - ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity + - RDMA/core: Fix ib_dma_max_seg_size() + - ppdev: fix PPGETTIME/PPSETTIME ioctls + - stm class: Lose the protocol driver when dropping its reference + - coresight: Serialize enabling/disabling a link device. + - powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB + - powerpc/xive: Prevent page fault issues in the machine crash handler + - powerpc: Allow flush_icache_range to work across ranges >4GB + - powerpc/xive: Skip ioremap() of ESB pages for LSI interrupts + - video/hdmi: Fix AVI bar unpack + - quota: Check that quota is not dirty before release + - ext2: check err when partial != NULL + - Revert "UBUNTU: SAUCE: seccomp: avoid overflow in implicit constant + conversion" + - seccomp: avoid overflow in implicit constant conversion + - quota: fix livelock in dquot_writeback_dquots + - ext4: Fix credit estimate for final inode freeing + - reiserfs: fix extended attributes on the root directory + - scsi: lpfc: Fix bad ndlp ptr in xri aborted handling + - scsi: qla2xxx: Fix abort timeout race condition. + - scsi: qla2xxx: Do command completion on abort timeout + - scsi: qla2xxx: Fix premature timer expiration + - scsi: qla2xxx: Fix DMA unmap leak + - scsi: qla2xxx: Fix different size DMA Alloc/Unmap + - scsi: qla2xxx: Fix NVMe port discovery after a short device port loss + - scsi: qla2xxx: Fix hang in fcport delete path + - scsi: qla2xxx: Make qla2x00_abort_srb() again decrease the sp reference + count + - scsi: qla2xxx: Really fix qla2xxx_eh_abort() + - scsi: qla2xxx: Fix session lookup in qlt_abort_work() + - scsi: qla2xxx: Fix qla24xx_process_bidir_cmd() + - scsi: qla2xxx: Always check the qla2x00_wait_for_hba_online() return value + - scsi: qla2xxx: Check secondary image if reading the primary image fails + - scsi: qla2xxx: Make sure that aborted commands are freed + - scsi: qla2xxx: qla2x00_alloc_fw_dump: set ha->eft + - scsi: qla2xxx: Fix message indicating vectors used by driver + - scsi: qla2xxx: Fix flash read for Qlogic ISPs + - scsi: qla2xxx: Fix driver reload for ISP82xx + - scsi: qla2xxx: Fix stuck login session + - scsi: qla2xxx: Fix stale session + - scsi: qla2xxx: Fix SRB leak on switch command timeout + - scsi: qla2xxx: Fix a dma_pool_free() call + - Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails" + - scsi: qla2xxx: Fix a race condition between aborting and completing a SCSI + command + - scsi: qla2xxx: Fix double scsi_done for abort path + - scsi: qla2xxx: Introduce the function qla2xxx_init_sp() + - iio: imu: st_lsm6dsx: move odr_table in st_lsm6dsx_sensor_settings + - iio: imu: st_lsm6dsx: fix ODR check in st_lsm6dsx_write_raw + - iio: ad7949: kill pointless "readback"-handling code + - iio: ad7949: fix channels mixups + - omap: pdata-quirks: revert pandora specific gpiod additions + - omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251 + - powerpc: Avoid clang warnings around setjmp and longjmp + - powerpc: Fix vDSO clock_getres() + - mm, memfd: fix COW issue on MAP_PRIVATE and F_SEAL_FUTURE_WRITE mappings + - Revert "UBUNTU: SAUCE: mfd: rk808: Fix RK818 ID template" + - mfd: rk808: Fix RK818 ID template + - mm: memcg/slab: wait for !root kmem_cache refcnt killing on root kmem_cache + destruction + - ext4: work around deleting a file with i_nlink == 0 safely + - firmware: qcom: scm: Ensure 'a0' status code is treated as signed + - s390/smp,vdso: fix ASCE handling + - s390/kaslr: store KASLR offset for early dumps + - mm/shmem.c: cast the type of unmap_start to u64 + - rtc: disable uie before setting time and enable after + - splice: only read in as much information as there is pipe buffer space + - ext4: fix a bug in ext4_wait_for_tail_page_commit + - blk-mq: make sure that line break can be printed + - workqueue: Fix missing kfree(rescuer) in destroy_workqueue() + - raid5: need to set STRIPE_HANDLE for batch head + - scsi: qla2xxx: Change discovery state before PLOGI + - SUNRPC: Fix another issue with MIC buffer space + - net_sched: validate TCA_KIND attribute in tc_chain_tmplt_add() + - arm64: dts: allwinner: a64: Re-add PMU node + - block: fix "check bi_size overflow before merge" + - EDAC/ghes: Do not warn when incrementing refcount on 0 + - Linux 5.3.17 + * Add new PCH ID for the Intel Comet Lake -H variant (LP: #1856642) + - usb: dwc3: pci: add ID for the Intel Comet Lake -H variant + * CVE-2019-19078 + - ath10k: fix memory leak + * CVE-2019-19077 + - RDMA: Fix goto target to release the allocated memory + * Eoan update: 5.3.16 upstream stable release (LP: #1856334) + - rsi: release skb if rsi_prepare_beacon fails + - arm64: tegra: Fix 'active-low' warning for Jetson TX1 regulator + - perf scripts python: exported-sql-viewer.py: Fix use of TRUE with SQLite + - sparc64: implement ioremap_uc + - lp: fix sparc64 LPSETTIMEOUT ioctl + - time: Zero the upper 32-bits in __kernel_timespec on 32-bit + - usb: gadget: u_serial: add missing port entry locking + - tty: serial: fsl_lpuart: use the sg count from dma_map_sg + - tty: serial: msm_serial: Fix flow control + - serial: pl011: Fix DMA ->flush_buffer() + - serial: serial_core: Perform NULL checks for break_ctl ops + - serial: stm32: fix clearing interrupt error flags + - serial: ifx6x60: add missed pm_runtime_disable + - aio: Fix io_pgetevents() struct __compat_aio_sigset layout + - autofs: fix a leak in autofs_expire_indirect() + - MIPS: SGI-IP27: fix exception handler replication + - RDMA/hns: Correct the value of HNS_ROCE_HEM_CHUNK_LEN + - RDMA/hns: Correct the value of srq_desc_size + - iwlwifi: pcie: don't consider IV len in A-MSDU + - cgroup: don't put ERR_PTR() into fc->root + - exportfs_decode_fh(): negative pinned may become positive without the parent + locked + - audit_get_nd(): don't unlock parent too early + - ecryptfs: fix unlink and rmdir in face of underlying fs modifications + - Revert "UBUNTU: SAUCE: ALSA: hda: Add Cometlake-S PCI ID" + - ALSA: hda: Add Cometlake-S PCI ID + - NFC: nxp-nci: Fix NULL pointer dereference after I2C communication error + - xfrm: release device reference for invalid state + - block: check bi_size overflow before merge + - Input: cyttsp4_core - fix use after free bug + - sched/core: Avoid spurious lock dependencies + - sched/pelt: Fix update of blocked PELT ordering + - perf/core: Consistently fail fork on allocation failures + - ALSA: pcm: Fix stream lock usage in snd_pcm_period_elapsed() + - x86/resctrl: Fix potential lockdep warning + - drm/sun4i: tcon: Set min division of TCON0_DCLK to 1. + - selftests: kvm: fix build with glibc >= 2.30 + - rbd: silence bogus uninitialized warning in rbd_object_map_update_finish() + - rsxx: add missed destroy_workqueue calls in remove + - ravb: implement MTU change while device is up + - net: hns3: reallocate SSU' buffer size when pfc_en changes + - net: hns3: fix ETS bandwidth validation bug + - afs: Fix race in commit bulk status fetch + - net: ep93xx_eth: fix mismatch of request_mem_region in remove + - i2c: core: fix use after free in of_i2c_notify + - io_uring: transform send/recvmsg() -ERESTARTSYS to -EINTR + - fuse: verify nlink + - fuse: verify attributes + - io_uring: ensure req->submit is copied when req is deferred + - SUNRPC: Avoid RPC delays when exiting suspend + - ALSA: hda/realtek - Enable internal speaker of ASUS UX431FLC + - Revert "UBUNTU: SAUCE: ALSA: hda/realtek - Dell headphone has noise on + unmute for ALC236" + - ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236 + - ALSA: pcm: oss: Avoid potential buffer overflows + - ALSA: hda - Add mute led support for HP ProBook 645 G4 + - ALSA: hda: Modify stream stripe mask only when needed + - Input: synaptics - switch another X1 Carbon 6 to RMI/SMbus + - Input: synaptics-rmi4 - re-enable IRQs in f34v7_do_reflash + - Input: synaptics-rmi4 - don't increment rmiaddr for SMBus transfers + - Input: goodix - add upside-down quirk for Teclast X89 tablet + - coresight: etm4x: Fix input validation for sysfs. + - Input: Fix memory leak in psxpad_spi_probe + - media: rc: mark input device as pointing stick + - x86/mm/32: Sync only to VMALLOC_END in vmalloc_sync_all() + - CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks + - CIFS: Fix SMB2 oplock break processing + - tty: vt: keyboard: reject invalid keycodes + - can: slcan: Fix use-after-free Read in slcan_open + - nfsd: Ensure CLONE persists data and metadata changes to the target file + - nfsd: restore NFSv3 ACL support + - kernfs: fix ino wrap-around detection + - jbd2: Fix possible overflow in jbd2_log_space_left() + - drm/msm: fix memleak on release + - drm: damage_helper: Fix race checking plane->state->fb + - drm/i810: Prevent underflow in ioctl + - arm64: dts: exynos: Revert "Remove unneeded address space mapping for soc + node" + - KVM: PPC: Book3S HV: XIVE: Free previous EQ page when setting up a new one + - KVM: PPC: Book3S HV: XIVE: Fix potential page leak on error path + - KVM: PPC: Book3S HV: XIVE: Set kvm->arch.xive when VPs are allocated + - KVM: nVMX: Always write vmcs02.GUEST_CR3 during nested VM-Enter + - KVM: arm/arm64: vgic: Don't rely on the wrong pending table + - KVM: x86: do not modify masked bits of shared MSRs + - KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES + - KVM: x86: Remove a spurious export of a static function + - KVM: x86: Grab KVM's srcu lock when setting nested state + - crypto: crypto4xx - fix double-free in crypto4xx_destroy_sdr + - crypto: atmel-aes - Fix IV handling when req->nbytes < ivsize + - crypto: af_alg - cast ki_complete ternary op to int + - crypto: geode-aes - switch to skcipher for cbc(aes) fallback + - crypto: ccp - fix uninitialized list head + - crypto: ecdh - fix big endian bug in ECC library + - crypto: user - fix memory leak in crypto_report + - spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register + - spi: stm32-qspi: Fix kernel oops when unbinding driver + - spi: atmel: Fix CS high support + - spi: Fix SPI_CS_HIGH setting when using native and GPIO CS + - spi: Fix NULL pointer when setting SPI_CS_HIGH for GPIO CS + - can: ucan: fix non-atomic allocation in completion handler + - RDMA/qib: Validate ->show()/store() callbacks before calling them + - iomap: Fix pipe page leakage during splicing + - thermal: Fix deadlock in thermal thermal_zone_device_check + - vcs: prevent write access to vcsu devices + - binder: Fix race between mmap() and binder_alloc_print_pages() + - binder: Prevent repeated use of ->mmap() via NULL mapping + - binder: Handle start==NULL in binder_update_page_range() + - KVM: x86: fix out-of-bounds write in KVM_GET_EMULATED_CPUID (CVE-2019-19332) + - ALSA: hda - Fix pending unsol events at shutdown + - cpufreq: imx-cpufreq-dt: Correct i.MX8MN's default speed grade value + - drm/mcde: Fix an error handling path in 'mcde_probe()' + - watchdog: aspeed: Fix clock behaviour for ast2600 + - EDAC/ghes: Fix locking and memory barrier issues + - perf script: Fix invalid LBR/binary mismatch error + - kselftest: Fix NULL INSTALL_PATH for TARGETS runlist + - ALSA: hda: hdmi - fix pin setup on Tigerlake + - Linux 5.3.16 + * Realtek ALC256M with DTS Audio Processing internal microphone doesn't work + on Redmi Book 14 2019 (LP: #1846148) // Eoan update: 5.3.16 upstream stable + release (LP: #1856334) + - ALSA: hda/realtek - Enable the headset-mic on a Xiaomi's laptop + * CVE-2019-19050 + - crypto: user - fix memory leak in crypto_reportstat + * Fix MST support on Ice Lake (LP: #1854432) + - drm/i915: fix port checks for MST support on gen >= 11 + * headphone has noise as not mute on dell machines with alc236/256 + (LP: #1854401) + - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236 + * Eoan update: 5.3.15 upstream stable release (LP: #1855306) + - io_uring: async workers should inherit the user creds + - net: separate out the msghdr copy from ___sys_{send,recv}msg() + - net: disallow ancillary data for __sys_{send,recv}msg_file() + - XArray: Fix xas_next() with a single entry at 0 + - clk: meson: gxbb: let sar_adc_clk_div set the parent clock rate + - clk: at91: sam9x60: fix programmable clock + - thunderbolt: Read DP IN adapter first two dwords in one go + - thunderbolt: Fix lockdep circular locking depedency warning + - clocksource/drivers/mediatek: Fix error handling + - soundwire: intel: fix intel_register_dai PDI offsets and numbers + - ASoC: msm8916-wcd-analog: Fix RX1 selection in RDAC2 MUX + - ASoC: compress: fix unsigned integer overflow check + - reset: Fix memory leak in reset_control_array_put() + - clk: samsung: exynos5433: Fix error paths + - clk: samsung: exynos542x: Move G3D subsystem clocks to its sub-CMU + - ASoC: kirkwood: fix external clock probe defer + - ASoC: kirkwood: fix device remove ordering + - arm64: dts: ls1028a: fix a compatible issue + - clk: samsung: exynos5420: Preserve PLL configuration during suspend/resume + - pinctrl: cherryview: Allocate IRQ chip dynamic + - ARM: dts: imx6qdl-sabreauto: Fix storm of accelerometer interrupts + - soc: imx: gpc: fix initialiser format + - reset: fix reset_control_ops kerneldoc comment + - arm64: dts: imx8mm: fix compatible string for sdma + - ASoC: SOF: ipc: Fix memory leak in sof_set_get_large_ctrl_data + - ASoC: ti: sdma-pcm: Add back the flags parameter for non standard dma names + - ASoC: rockchip: rockchip_max98090: Enable SHDN to fix headset detection + - clk: at91: avoid sleeping early + - clk: sunxi: Fix operator precedence in sunxi_divs_clk_setup + - clk: sunxi-ng: a80: fix the zero'ing of bits 16 and 18 + - ARM: dts: sun8i-a83t-tbs-a711: Fix WiFi resume from suspend + - bpf: Allow narrow loads of bpf_sysctl fields with offset > 0 + - samples/bpf: fix build by setting HAVE_ATTR_TEST to zero + - bpf: Change size to u64 for bpf_map_{area_alloc, charge_init}() + - powerpc/bpf: Fix tail call implementation + - idr: Fix idr_get_next_ul race with idr_remove + - idr: Fix integer overflow in idr_for_each_entry + - idr: Fix idr_alloc_u32 on 32-bit systems + - x86/resctrl: Prevent NULL pointer dereference when reading mondata + - arm64: dts: zii-ultra: fix ARM regulator GPIO handle + - fbdev: c2p: Fix link failure on non-inlining + - ASoC: hdac_hda: fix race in device removal + - clk: ti: dra7-atl-clock: Remove ti_clk_add_alias call + - clk: ti: clkctrl: Fix failed to enable error with double udelay timeout + - net: fec: add missed clk_disable_unprepare in remove + - netfilter: ipset: Fix nla_policies to fully support NL_VALIDATE_STRICT + - bridge: ebtables: don't crash when using dnat target in output chains + - netfilter: nf_tables: bogus EOPNOTSUPP on basechain update + - netfilter: nf_tables_offload: skip EBUSY on chain update + - stacktrace: Don't skip first entry on noncurrent tasks + - can: peak_usb: report bus recovery as well + - can: c_can: D_CAN: c_can_chip_config(): perform a sofware reset on open + - can: rx-offload: can_rx_offload_queue_tail(): fix error handling, avoid skb + mem leak + - can: rx-offload: can_rx_offload_offload_one(): do not increase the skb_queue + beyond skb_queue_len_max + - can: rx-offload: can_rx_offload_offload_one(): increment rx_fifo_errors on + queue overflow or OOM + - can: rx-offload: can_rx_offload_offload_one(): use ERR_PTR() to propagate + error value in case of errors + - can: rx-offload: can_rx_offload_irq_offload_timestamp(): continue on error + - can: rx-offload: can_rx_offload_irq_offload_fifo(): continue on error + - can: flexcan: increase error counters if skb enqueueing via + can_rx_offload_queue_sorted() fails + - x86/tsc: Respect tsc command line paraemeter for clocksource_tsc_early + - perf scripting engines: Iterate on tep event arrays directly + - can: mcp251x: mcp251x_restart_work_handler(): Fix potential force_quit race + condition + - nvme-rdma: fix a segmentation fault during module unload + - nvme-multipath: fix crash in nvme_mpath_clear_ctrl_paths + - watchdog: pm8916_wdt: fix pretimeout registration flow + - watchdog: meson: Fix the wrong value of left time + - watchdog: imx_sc_wdt: Pretimeout should follow SCU firmware format + - watchdog: bd70528: Add MODULE_ALIAS to allow module auto loading + - ASoC: stm32: sai: add restriction on mmap support + - ALSA: hda: hdmi - add Tigerlake support + - ARM: dts: stm32: Fix CAN RAM mapping on stm32mp157c + - ASoC: SOF: topology: Fix bytes control size checks + - mm/gup_benchmark: fix MAP_HUGETLB case + - scripts/gdb: fix debugging modules compiled with hot/cold partitioning + - net: bcmgenet: use RGMII loopback for MAC reset + - net: bcmgenet: reapply manual settings to the PHY + - drm/amdgpu: dont schedule jobs while in reset + - net/mlx5e: Fix eswitch debug print of max fdb flow + - net/mlx5e: Use correct enum to determine uplink port + - net: mscc: ocelot: fix __ocelot_rmw_ix prototype + - drm/amd/swSMU: fix smu workload bit map error + - drm/amdgpu: register gpu instance before fan boost feature enablment + - drm/amdgpu: add warning for GRBM 1-cycle delay issue in gfx9 + - net: stmmac: gmac4: bitrev32 returns u32 + - net: stmmac: xgmac: bitrev32 returns u32 + - net: stmmac: xgmac: Fix TSA selection + - net: stmmac: xgmac: Disable Flow Control when 1 or more queues are in AV + - ceph: return -EINVAL if given fsc mount option on kernel w/o support + - mac80211: fix ieee80211_txq_setup_flows() failure path + - net/fq_impl: Switch to kvmalloc() for memory allocation + - mac80211: fix station inactive_time shortly after boot + - block: drbd: remove a stray unlock in __drbd_send_protocol() + - pwm: bcm-iproc: Prevent unloading the driver module while in use + - ice: fix potential infinite loop because loop counter being too small + - iavf: initialize ITRN registers with correct values + - i40e: Fix for ethtool -m issue on X722 NIC + - clk: at91: fix update bit maps on CFG_MOR write + - usb: dwc2: use a longer core rest timeout in dwc2_core_reset() + - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param() + - staging: rtl8192e: fix potential use after free + - staging: rtl8723bs: Drop ACPI device ids + - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids + - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P + - mei: bus: prefix device names on bus with the bus name + - mei: me: add comet point V device id + - thunderbolt: Power cycle the router if NVM authentication fails + - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx + - gve: Fix the queue page list allocated pages count + - macvlan: schedule bc_work even if error + - mdio_bus: don't use managed reset-controller + - net: dsa: sja1105: fix sja1105_parse_rgmii_delays() + - net: macb: add missed tasklet_kill + - net: psample: fix skb_over_panic + - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues + - openvswitch: fix flow command message size + - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook + - slip: Fix use-after-free Read in slip_open + - sctp: cache netns in sctp_ep_common + - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info() + - openvswitch: remove another BUG_ON() + - net/tls: take into account that bpf_exec_tx_verdict() may free the record + - net/tls: free the record on encryption error + - net: skmsg: fix TLS 1.3 crash with full sk_msg + - selftests/tls: add a test for fragmented messages + - net/tls: remove the dead inplace_crypto code + - net/tls: use sg_next() to walk sg entries + - selftests: bpf: test_sockmap: handle file creation failures gracefully + - selftests: bpf: correct perror strings + - tipc: fix link name length check + - selftests: pmtu: use -oneline for ip route list cache + - ext4: add more paranoia checking in ext4_expand_extra_isize handling + - HID: core: check whether Usage Page item is after Usage ID items + - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer + - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size + - net: fec: fix clock count mis-match + - Linux 5.3.15 + * Eoan update: 5.3.14 upstream stable release (LP: #1854861) + - mlxsw: spectrum_router: Fix determining underlay for a GRE tunnel + - net/mlx4_en: fix mlx4 ethtool -N insertion + - net/mlx4_en: Fix wrong limitation for number of TX rings + - net: rtnetlink: prevent underflows in do_setvfinfo() + - net/sched: act_pedit: fix WARN() in the traffic path + - net: sched: ensure opts_len <= IP_TUNNEL_OPTS_MAX in act_tunnel_key + - sfc: Only cancel the PPS workqueue if it exists + - net/mlxfw: Verify FSM error code translation doesn't exceed array size + - net/mlx5e: Fix set vf link state error flow + - net/mlx5: Fix auto group size calculation + - net/tls: enable sk_msg redirect to tls socket egress + - ipv6/route: return if there is no fib_nh_gw_family + - taprio: don't reject same mqprio settings + - net/ipv4: fix sysctl max for fib_multipath_hash_policy + - net/mlx5e: Fix error flow cleanup in mlx5e_tc_tun_create_header_ipv4/6 + - net/mlx5e: Do not use non-EXT link modes in EXT mode + - net/mlx5: Update the list of the PCI supported devices + - vhost/vsock: split packets to send using multiple buffers + - gpio: max77620: Fixup debounce delays + - gpio: bd70528: Use correct unit for debounce times + - tools: gpio: Correctly add make dependencies for gpio_utils + - fork: fix pidfd_poll()'s return type + - nbd:fix memory leak in nbd_get_socket() + - virtio_console: allocate inbufs in add_port() only if it is needed + - virtio_ring: fix return code on DMA mapping fails + - virtio_balloon: fix shrinker count + - Revert "fs: ocfs2: fix possible null-pointer dereferences in + ocfs2_xa_prepare_entry()" + - mm/memory_hotplug: don't access uninitialized memmaps in shrink_zone_span() + - mm/ksm.c: don't WARN if page is still mapped in remove_stable_node() + - drm/amdgpu: disable gfxoff when using register read interface + - drm/amdgpu: disable gfxoff on original raven + - drm/amd/powerplay: issue no PPSMC_MSG_GetCurrPkgPwr on unsupported ASICs + - drm/i915: Don't oops in dumb_create ioctl if we have no crtcs + - drm/i915/pmu: "Frequency" is reported as accumulated cycles + - drm/i915/userptr: Try to acquire the page lock around set_page_dirty() + - Bluetooth: Fix invalid-free in bcsp_close() + - ath10k: restore QCA9880-AR1A (v1) detection + - ath10k: Fix HOST capability QMI incompatibility + - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe + - ath9k_hw: fix uninitialized variable data + - Revert "Bluetooth: hci_ll: set operational frequency earlier" + - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues" + - md/raid10: prevent access of uninitialized resync_pages offset + - mdio_bus: Fix init if CONFIG_RESET_CONTROLLER=n + - ARM: 8904/1: skip nomap memblocks while finding the lowmem/highmem boundary + - x86/insn: Fix awk regexp warnings + - x86/speculation: Fix incorrect MDS/TAA mitigation status + - x86/speculation: Fix redundant MDS mitigation message + - nbd: prevent memory leak + - gve: fix dma sync bug where not all pages synced + - x86/stackframe/32: Repair 32-bit Xen PV + - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout + - x86/xen/32: Simplify ring check in xen_iret_crit_fixup() + - x86/doublefault/32: Fix stack canaries in the double fault handler + - x86/pti/32: Size initial_page_table correctly + - x86/cpu_entry_area: Add guard page for entry stack on 32bit + - x86/entry/32: Fix IRET exception + - x86/entry/32: Use %ss segment where required + - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL + - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry + - x86/entry/32: Fix NMI vs ESPFIX + - selftests/x86/mov_ss_trap: Fix the SYSENTER test + - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel + - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make + the CPU_ENTRY_AREA_PAGES assert precise + - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3 + - futex: Prevent robust futex exit race + - ALSA: usb-audio: Fix NULL dereference at parsing BADD + - nfc: port100: handle command failure cleanly + - media: vivid: Set vid_cap_streaming and vid_out_streaming to true + - media: vivid: Fix wrong locking that causes race conditions on streaming + stop + - media: usbvision: Fix invalid accesses after device disconnect + - media: usbvision: Fix races among open, close, and disconnect + - cpufreq: Add NULL checks to show() and store() methods of cpufreq + - media: uvcvideo: Fix error path in control parsing failure + - media: b2c2-flexcop-usb: add sanity checking + - media: cxusb: detect cxusb_ctrl_msg error in query + - media: imon: invalid dereference in imon_touch_event + - media: mceusb: fix out of bounds read in MCE receiver buffer + - mm/slub.c: init_on_free=1 should wipe freelist ptr for bulk allocations + - USBIP: add config dependency for SGL_ALLOC + - usbip: tools: fix fd leakage in the function of read_attr_usbip_status + - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit() + - usb-serial: cp201x: support Mark-10 digital force gauge + - USB: chaoskey: fix error case of a timeout + - appledisplay: fix error handling in the scheduled work + - USB: serial: mos7840: add USB ID to support Moxa UPort 2210 + - USB: serial: mos7720: fix remote wakeup + - USB: serial: mos7840: fix remote wakeup + - USB: serial: option: add support for DW5821e with eSIM support + - USB: serial: option: add support for Foxconn T77W968 LTE modules + - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error + - Linux 5.3.14 + + [ Ubuntu: 5.3.0-29.31 ] + + * eoan/linux: 5.3.0-29.31 -proposed tracker (LP: #1860119) + * Integrate Intel SGX driver into linux-azure (LP: #1844245) + - [Packaging] Add systemd service to load intel_sgx + + [ Ubuntu: 5.3.0-28.30 ] + + * eoan/linux: 5.3.0-28.30 -proposed tracker (LP: #1859694) + * CVE-2019-14615 + - drm/i915/gen9: Clear residual context state on context switch + * PAN is broken for execute-only user mappings on ARMv8 (LP: #1858815) + - arm64: Revert support for execute-only user mappings + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-27.29 ] + + * eoan/linux: 5.3.0-27.29 -proposed tracker (LP: #1858943) + * [Regression] usb usb2-port2: Cannot enable. Maybe the USB cable is bad? + (LP: #1856608) + - SAUCE: Revert "usb: handle warm-reset port requests on hub resume" + + [ Ubuntu: 5.3.0-26.28 ] + + * eoan/linux: 5.3.0-26.28 -proposed tracker (LP: #1856807) + * nvidia-435 is in eoan, linux-restricted-modules only builds against 430, + ubiquity gives me the self-signed modules experience instead of using the + Canonical-signed modules (LP: #1856407) + - Add nvidia-435 dkms build + + -- Khalid Elmously Mon, 03 Feb 2020 02:05:35 -0500 + +linux-oracle (5.3.0-1008.9) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1008.9 -proposed tracker (LP: #1854755) + + [ Ubuntu: 5.3.0-25.27 ] + + * eoan/linux: 5.3.0-25.27 -proposed tracker (LP: #1854762) + * CVE-2019-14901 + - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame() + * CVE-2019-14896 // CVE-2019-14897 + - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor + * CVE-2019-14895 + - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie() + * [CML] New device id's for CMP-H (LP: #1846335) + - mmc: sdhci-pci: Add another Id for Intel CML + - i2c: i801: Add support for Intel Comet Lake PCH-H + - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash + - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs + * i915: Display flickers (monitor loses signal briefly) during "flickerfree" + boot, while showing the BIOS logo on a black background (LP: #1836858) + - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y + * Please add patch fixing RK818 ID detection (LP: #1853192) + - SAUCE: mfd: rk808: Fix RK818 ID template + * Kernel build log filled with "/bin/bash: line 5: warning: command + substitution: ignored null byte in input" (LP: #1853843) + - [Debian] Fix warnings when checking for modules signatures + * Lenovo dock MAC Address pass through doesn't work in Ubuntu (LP: #1827961) + - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2 + * Dell XPS 13 9350/9360 headphone audio hiss (LP: #1654448) // [XPS 13 9360, + Realtek ALC3246, Black Headphone Out, Front] High noise floor (LP: #1845810) + - ALSA: hda/realtek: Reduce the Headphone static noise on XPS 9350/9360 + * no HDMI video output since GDM greeter after linux-oem-osp1 version + 5.0.0-1026 (LP: #1852386) + - drm/i915: Add new CNL PCH ID seen on a CML platform + - SAUCE: drm/i915: Fix detection for a CMP-V PCH + * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer + works on Dell Venue 11 Pro 7140 (LP: #1846539) + - [Config] Drop snd-sof-intel-bdw build + - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy + driver + * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2 + (LP: #1847451) + - SAUCE: tools/power turbostat: Add Cometlake support + * External microphone can't work on some dell machines with the codec alc256 + or alc236 (LP: #1853791) + - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table + - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table + * Memory leak in net/xfrm/xfrm_state.c - 8 pages per ipsec connection + (LP: #1853197) + - xfrm: Fix memleak on xfrm state destroy + * CVE-2019-18660: patches for Ubuntu (LP: #1853142) // CVE-2019-18660 + - powerpc/64s: support nospectre_v2 cmdline option + - powerpc/book3s64: Fix link stack flush on context switch + - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel + * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721) + - HID: i2c-hid: fix no irq after reset on raydium 3118 + * Make Goodix I2C touchpads work (LP: #1853842) + - HID: i2c-hid: Remove runtime power management + - HID: i2c-hid: Send power-on command after reset + * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901) + - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 + 2-in-1" + - lib: devres: add a helper function for ioremap_uc + - mfd: intel-lpss: Use devm_ioremap_uc for MMIO + * CVE-2019-19055 + - nl80211: fix memory leak in nl80211_get_ftm_responder_stats + * CML: perf enabling for core (LP: #1848978) + - perf/x86/intel: Add Comet Lake CPU support + - perf/x86/msr: Add Comet Lake CPU support + - perf/x86/cstate: Add Comet Lake CPU support + - perf/x86/msr: Add new CPU model numbers for Ice Lake + - perf/x86/cstate: Update C-state counters for Ice Lake + * Boot hangs after "Loading initial ramdisk ..." (LP: #1852586) + - SAUCE: Revert "tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for + interrupts" + - SAUCE: Revert "tpm_tis_core: Turn on the TPM before probing IRQ's" + * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2 + (LP: #1847454) + - powercap/intel_rapl: add support for CometLake Mobile + - powercap/intel_rapl: add support for Cometlake desktop + * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2 + (LP: #1847450) + - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support + to intel_pmc_core driver + * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180) + - net: ena: add intr_moder_rx_interval to struct ena_com_dev and use it + - net: ena: switch to dim algorithm for rx adaptive interrupt moderation + - net: ena: reimplement set/get_coalesce() + - net: ena: enable the interrupt_moderation in driver_supported_features + - net: ena: remove code duplication in + ena_com_update_nonadaptive_moderation_interval _*() + - net: ena: remove old adaptive interrupt moderation code from ena_netdev + - net: ena: remove ena_restore_ethtool_params() and relevant fields + - net: ena: remove all old adaptive rx interrupt moderation code from ena_com + - net: ena: fix update of interrupt moderation register + - net: ena: fix retrieval of nonadaptive interrupt moderation intervals + - net: ena: fix incorrect update of intr_delay_resolution + - net: ena: Select DIMLIB for ENA_ETHERNET + - SAUCE: net: ena: fix issues in setting interrupt moderation params in + ethtool + - SAUCE: net: ena: fix too long default tx interrupt moderation interval + * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222) + - [Config] Enable ROCKCHIP support for arm64 + * remount of multilower moved pivoted-root overlayfs root, results in I/O + errors on some modified files (LP: #1824407) + - SAUCE: ovl: fix lookup failure on multi lower squashfs + * Eoan update: 5.3.13 upstream stable release (LP: #1853882) + - net: cdc_ncm: Signedness bug in cdc_ncm_set_dgram_size() + - block, bfq: deschedule empty bfq_queues not referred by any process + - mm/memory_hotplug: don't access uninitialized memmaps in shrink_pgdat_span() + - mm/memory_hotplug: fix updating the node span + - arm64: uaccess: Ensure PAN is re-enabled after unhandled uaccess fault + - fbdev: Ditch fb_edid_add_monspecs + - Linux 5.3.13 + * Eoan update: 5.3.12 upstream stable release (LP: #1853475) + - scsi: core: Handle drivers which set sg_tablesize to zero + - ax88172a: fix information leak on short answers + - devlink: disallow reload operation during device cleanup + - ipmr: Fix skb headroom in ipmr_get_route(). + - mlxsw: core: Enable devlink reload only on probe + - net: gemini: add missed free_netdev + - net/smc: fix fastopen for non-blocking connect() + - net: usb: qmi_wwan: add support for Foxconn T77W968 LTE modules + - slip: Fix memory leak in slip_open error path + - tcp: remove redundant new line from tcp_event_sk_skb + - dpaa2-eth: free already allocated channels on probe defer + - devlink: Add method for time-stamp on reporter's dump + - net/smc: fix refcount non-blocking connect() -part 2 + - ALSA: usb-audio: Fix missing error check at mixer resolution test + - ALSA: usb-audio: not submit urb for stopped endpoint + - ALSA: usb-audio: Fix incorrect NULL check in create_yamaha_midi_quirk() + - ALSA: usb-audio: Fix incorrect size check for processing/extension units + - Btrfs: fix log context list corruption after rename exchange operation + - cgroup: freezer: call cgroup_enter_frozen() with preemption disabled in + ptrace_stop() + - Input: ff-memless - kill timer in destroy() + - Input: synaptics-rmi4 - fix video buffer size + - Input: synaptics-rmi4 - disable the relative position IRQ in the F12 driver + - Input: synaptics-rmi4 - do not consume more data than we have (F11, F12) + - Input: synaptics-rmi4 - clear IRQ enables for F54 + - Input: synaptics-rmi4 - destroy F54 poller workqueue when removing + - KVM: MMU: Do not treat ZONE_DEVICE pages as being reserved + - IB/hfi1: Ensure r_tid_ack is valid before building TID RDMA ACK packet + - IB/hfi1: Calculate flow weight based on QP MTU for TID RDMA + - IB/hfi1: TID RDMA WRITE should not return IB_WC_RNR_RETRY_EXC_ERR + - IB/hfi1: Ensure full Gen3 speed in a Gen4 system + - IB/hfi1: Use a common pad buffer for 9B and 16B packets + - i2c: acpi: Force bus speed to 400KHz if a Silead touchscreen is present + - SAUCE: Revert "UBUNTU: SAUCE: x86/intel: Disable HPET on Intel Coffe Lake + platforms" + - x86/quirks: Disable HPET on Intel Coffe Lake platforms + - ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable + - ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable either + - io_uring: ensure registered buffer import returns the IO length + - drm/i915: update rawclk also on resume + - Revert "drm/i915/ehl: Update MOCS table for EHL" + - ntp/y2038: Remove incorrect time_t truncation + - net: ethernet: dwmac-sun8i: Use the correct function in exit path + - iommu/vt-d: Fix QI_DEV_IOTLB_PFSID and QI_DEV_EIOTLB_PFSID macros + - mm: mempolicy: fix the wrong return value and potential pages leak of mbind + - mm: memcg: switch to css_tryget() in get_mem_cgroup_from_mm() + - mm: hugetlb: switch to css_tryget() in hugetlb_cgroup_charge_cgroup() + - mm: slub: really fix slab walking for init_on_free + - mm/memory_hotplug: fix try_offline_node() + - mm/page_io.c: do not free shared swap slots + - mmc: sdhci-of-at91: fix quirk2 overwrite + - slcan: Fix memory leak in error path + - Linux 5.3.12 + * Eoan update: 5.3.11 upstream stable release (LP: #1852338) + - bonding: fix state transition issue in link monitoring + - CDC-NCM: handle incomplete transfer of MTU + - ipv4: Fix table id reference in fib_sync_down_addr + - net: ethernet: octeon_mgmt: Account for second possible VLAN header + - net: fix data-race in neigh_event_send() + - net: qualcomm: rmnet: Fix potential UAF when unregistering + - net/tls: fix sk_msg trim on fallback to copy mode + - net: usb: qmi_wwan: add support for DW5821e with eSIM support + - NFC: fdp: fix incorrect free object + - nfc: netlink: fix double device reference drop + - NFC: st21nfca: fix double free + - qede: fix NULL pointer deref in __qede_remove() + - net: mscc: ocelot: don't handle netdev events for other netdevs + - net: mscc: ocelot: fix NULL pointer on LAG slave removal + - net/tls: don't pay attention to sk_write_pending when pushing partial + records + - net/tls: add a TX lock + - selftests/tls: add test for concurrent recv and send + - ipv6: fixes rt6_probe() and fib6_nh->last_probe init + - net: hns: Fix the stray netpoll locks causing deadlock in NAPI path + - net: prevent load/store tearing on sk->sk_stamp + - net: sched: prevent duplicate flower rules from tcf_proto destroy race + - net/smc: fix ethernet interface refcounting + - vsock/virtio: fix sock refcnt holding during the shutdown + - r8169: fix page read in r8168g_mdio_read + - ALSA: timer: Fix incorrectly assigned timer instance + - ALSA: bebob: fix to detect configured source of sampling clock for Focusrite + Saffire Pro i/o series + - ALSA: hda/ca0132 - Fix possible workqueue stall + - mm: memcontrol: fix NULL-ptr deref in percpu stats flush + - mm: memcontrol: fix network errors from failing __GFP_ATOMIC charges + - mm, meminit: recalculate pcpu batch and high limits after init completes + - mm: thp: handle page cache THP correctly in PageTransCompoundMap + - mm, vmstat: hide /proc/pagetypeinfo from normal users + - dump_stack: avoid the livelock of the dump_lock + - mm: slab: make page_cgroup_ino() to recognize non-compound slab pages + properly + - btrfs: Consider system chunk array size for new SYSTEM chunks + - btrfs: tree-checker: Fix wrong check on max devid + - btrfs: save i_size to avoid double evaluation of i_size_read in + compress_file_range + - tools: gpio: Use !building_out_of_srctree to determine srctree + - pinctrl: intel: Avoid potential glitches if pin is in GPIO mode + - perf tools: Fix time sorting + - perf map: Use zalloc for map_groups + - drm/radeon: fix si_enable_smc_cac() failed issue + - HID: wacom: generic: Treat serial number and related fields as unsigned + - mm/khugepaged: fix might_sleep() warn with CONFIG_HIGHPTE=y + - soundwire: depend on ACPI + - soundwire: depend on ACPI || OF + - soundwire: bus: set initial value to port_status + - blkcg: make blkcg_print_stat() print stats only for online blkgs + - arm64: Do not mask out PTE_RDONLY in pte_same() + - ASoC: rsnd: dma: fix SSI9 4/5/6/7 busif dma address + - ceph: fix use-after-free in __ceph_remove_cap() + - ceph: fix RCU case handling in ceph_d_revalidate() + - ceph: add missing check in d_revalidate snapdir handling + - ceph: don't try to handle hashed dentries in non-O_CREAT atomic_open + - ceph: don't allow copy_file_range when stripe_count != 1 + - iio: adc: stm32-adc: fix stopping dma + - iio: imu: adis16480: make sure provided frequency is positive + - iio: imu: inv_mpu6050: fix no data on MPU6050 + - iio: srf04: fix wrong limitation in distance measuring + - ARM: sunxi: Fix CPU powerdown on A83T + - ARM: dts: imx6-logicpd: Re-enable SNVS power key + - cpufreq: intel_pstate: Fix invalid EPB setting + - clone3: validate stack arguments + - netfilter: nf_tables: Align nft_expr private data to 64-bit + - netfilter: ipset: Fix an error code in ip_set_sockfn_get() + - intel_th: gth: Fix the window switching sequence + - intel_th: pci: Add Comet Lake PCH support + - intel_th: pci: Add Jasper Lake PCH support + - x86/dumpstack/64: Don't evaluate exception stacks before setup + - x86/apic/32: Avoid bogus LDR warnings + - SMB3: Fix persistent handles reconnect + - can: usb_8dev: fix use-after-free on disconnect + - can: flexcan: disable completely the ECC mechanism + - can: c_can: c_can_poll(): only read status register after status IRQ + - can: peak_usb: fix a potential out-of-sync while decoding packets + - can: rx-offload: can_rx_offload_queue_sorted(): fix error handling, avoid + skb mem leak + - can: gs_usb: gs_can_open(): prevent memory leak + - can: dev: add missing of_node_put() after calling of_get_child_by_name() + - can: mcba_usb: fix use-after-free on disconnect + - can: peak_usb: fix slab info leak + - configfs: fix a deadlock in configfs_symlink() + - ALSA: usb-audio: More validations of descriptor units + - ALSA: usb-audio: Simplify parse_audio_unit() + - ALSA: usb-audio: Unify the release of usb_mixer_elem_info objects + - ALSA: usb-audio: Remove superfluous bLength checks + - ALSA: usb-audio: Clean up check_input_term() + - ALSA: usb-audio: Fix possible NULL dereference at create_yamaha_midi_quirk() + - ALSA: usb-audio: remove some dead code + - ALSA: usb-audio: Fix copy&paste error in the validator + - usbip: Implement SG support to vhci-hcd and stub driver + - HID: google: add magnemite/masterball USB ids + - dmaengine: sprd: Fix the link-list pointer register configuration issue + - bpf: lwtunnel: Fix reroute supplying invalid dst + - dmaengine: xilinx_dma: Fix 64-bit simple AXIDMA transfer + - dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config + - dmaengine: sprd: Fix the possible memory leak issue + - HID: intel-ish-hid: fix wrong error handling in ishtp_cl_alloc_tx_ring() + - powerpc/32s: fix allow/prevent_user_access() when crossing segment + boundaries. + - RDMA/mlx5: Clear old rate limit when closing QP + - iw_cxgb4: fix ECN check on the passive accept + - RDMA/siw: free siw_base_qp in kref release routine + - RDMA/qedr: Fix reported firmware version + - IB/core: Use rdma_read_gid_l2_fields to compare GID L2 fields + - net/mlx5e: Tx, Fix assumption of single WQEBB of NOP in cleanup flow + - net/mlx5e: kTLS, Release reference on DUMPed fragments in shutdown flow + - net/mlx5e: TX, Fix consumer index of error cqe dump + - net/mlx5: prevent memory leak in mlx5_fpga_conn_create_cq + - net/mlx5: fix memory leak in mlx5_fw_fatal_reporter_dump + - selftests/bpf: More compatible nc options in test_tc_edt + - scsi: qla2xxx: fixup incorrect usage of host_byte + - scsi: lpfc: Check queue pointer before use + - scsi: ufs-bsg: Wake the device before sending raw upiu commands + - ARC: [plat-hsdk]: Enable on-board SPI NOR flash IC + - RDMA/uverbs: Prevent potential underflow + - bpf: Fix use after free in subprog's jited symbol removal + - net: stmmac: Fix the problem of tso_xmit + - net: openvswitch: free vport unless register_netdevice() succeeds + - scsi: lpfc: Honor module parameter lpfc_use_adisc + - scsi: qla2xxx: Initialized mailbox to prevent driver load failure + - bpf: Fix use after free in bpf_get_prog_name + - iwlwifi: pcie: fix PCI ID 0x2720 configs that should be soc + - iwlwifi: pcie: fix all 9460 entries for qnj + - iwlwifi: pcie: 0x2720 is qu and 0x30DC is not + - netfilter: nf_flow_table: set timeout before insertion into hashes + - drm/v3d: Fix memory leak in v3d_submit_cl_ioctl + - xsk: Fix registration of Rx-only sockets + - net: phy: smsc: LAN8740: add PHY_RST_AFTER_CLK_EN flag + - ipvs: don't ignore errors in case refcounting ip_vs module fails + - ipvs: move old_secure_tcp into struct netns_ipvs + - netfilter: nft_payload: fix missing check for matching length in offloads + - RDMA/nldev: Skip counter if port doesn't match + - bonding: fix unexpected IFF_BONDING bit unset + - bonding: use dynamic lockdep key instead of subclass + - macsec: fix refcnt leak in module exit routine + - virt_wifi: fix refcnt leak in module exit routine + - scsi: sd: define variable dif as unsigned int instead of bool + - usb: dwc3: select CONFIG_REGMAP_MMIO + - usb: fsl: Check memory resource before releasing it + - usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode. + - usb: gadget: composite: Fix possible double free memory bug + - usb: dwc3: pci: prevent memory leak in dwc3_pci_probe + - usb: gadget: configfs: fix concurrent issue between composite APIs + - usb: dwc3: remove the call trace of USBx_GFLADJ + - perf/x86/amd/ibs: Fix reading of the IBS OpData register and thus precise + RIP validity + - perf/x86/amd/ibs: Handle erratum #420 only on the affected CPU family (10h) + - perf/x86/uncore: Fix event group support + - USB: Skip endpoints with 0 maxpacket length + - USB: ldusb: use unsigned size format specifiers + - usbip: tools: Fix read_usb_vudc_device() error path handling + - RDMA/iw_cxgb4: Avoid freeing skb twice in arp failure case + - RDMA/hns: Prevent memory leaks of eq->buf_list + - hwmon: (ina3221) Fix read timeout issue + - scsi: qla2xxx: stop timer in shutdown path + - sched/topology: Don't try to build empty sched domains + - sched/topology: Allow sched_asym_cpucapacity to be disabled + - nvme-multipath: fix possible io hang after ctrl reconnect + - fjes: Handle workqueue allocation failure + - net: hisilicon: Fix "Trying to free already-free IRQ" + - wimax: i2400: Fix memory leak in i2400m_op_rfkill_sw_toggle + - net: mscc: ocelot: fix vlan_filtering when enslaving to bridge before link + is up + - net: mscc: ocelot: refuse to overwrite the port's native vlan + - iommu/amd: Apply the same IVRS IOAPIC workaround to Acer Aspire A315-41 + - mt76: dma: fix buffer unmap with non-linear skbs + - drm/amdgpu/sdma5: do not execute 0-sized IBs (v2) + - drm/sched: Set error to s_fence if HW job submission failed. + - drm/amdgpu: If amdgpu_ib_schedule fails return back the error. + - drm/amd/display: do not synchronize "drr" displays + - drm/amd/display: add 50us buffer as WA for pstate switch in active + - drm/amd/display: Passive DP->HDMI dongle detection fix + - dc.c:use kzalloc without test + - SUNRPC: The TCP back channel mustn't disappear while requests are + outstanding + - SUNRPC: The RDMA back channel mustn't disappear while requests are + outstanding + - SUNRPC: Destroy the back channel when we destroy the host transport + - hv_netvsc: Fix error handling in netvsc_attach() + - efi/tpm: Return -EINVAL when determining tpm final events log size fails + - efi: libstub/arm: Account for firmware reserved memory at the base of RAM + - x86, efi: Never relocate kernel below lowest acceptable address + - arm64: cpufeature: Enable Qualcomm Falkor errata 1009 for Kryo + - usb: dwc3: gadget: fix race when disabling ep with cancelled xfers + - arm64: apply ARM64_ERRATUM_845719 workaround for Brahma-B53 core + - arm64: Brahma-B53 is SSB and spectre v2 safe + - arm64: apply ARM64_ERRATUM_843419 workaround for Brahma-B53 core + - NFSv4: Don't allow a cached open with a revoked delegation + - net: ethernet: arc: add the missed clk_disable_unprepare + - igb: Fix constant media auto sense switching when no cable is connected + - e1000: fix memory leaks + - gve: Fixes DMA synchronization. + - ocfs2: protect extent tree in ocfs2_prepare_inode_for_write() + - pinctrl: cherryview: Fix irq_valid_mask calculation + - clk: imx8m: Use SYS_PLL1_800M as intermediate parent of CLK_ARM + - timekeeping/vsyscall: Update VDSO data unconditionally + - mm/filemap.c: don't initiate writeback if mapping has no dirty pages + - cgroup,writeback: don't switch wbs immediately on dead wbs if the memcg is + dead + - ARM: dts: stm32: change joystick pinctrl definition on stm32mp157c-ev1 + - ASoC: SOF: Intel: hda-stream: fix the CONFIG_ prefix missing + - usbip: Fix free of unallocated memory in vhci tx + - bonding: fix using uninitialized mode_lock + - netfilter: ipset: Copy the right MAC address in hash:ip,mac IPv6 sets + - arm64: errata: Update stale comment + - net/ibmvnic: unlock rtnl_lock in reset so linkwatch_event can run + - SAUCE: Revert "UBUNTU: SAUCE: kvm: x86: mmu: Recovery of shattered NX large + pages" + - SAUCE: Revert "UBUNTU: SAUCE: kvm: Add helper function for creating VM + worker threads" + - SAUCE: Revert "UBUNTU: SAUCE: kvm: mmu: ITLB_MULTIHIT mitigation" + - SAUCE: Revert "kvm: x86, powerpc: do not allow clearing largepages debugfs + entry" + - SAUCE: Revert "UBUNTU: SAUCE: cpu/speculation: Uninline and export CPU + mitigations helpers" + - SAUCE: Revert "UBUNTU: SAUCE: x86: Add ITLB_MULTIHIT bug infrastructure" + - SAUCE: Revert "x86/tsx: Add config options to set tsx=on|off|auto" + - SAUCE: Revert "x86/speculation/taa: Add documentation for TSX Async Abort" + - SAUCE: Revert "x86/tsx: Add "auto" option to the tsx= cmdline parameter" + - SAUCE: Revert "kvm/x86: Export MDS_NO=0 to guests when TSX is enabled" + - SAUCE: Revert "x86/speculation/taa: Add sysfs reporting for TSX Async Abort" + - SAUCE: Revert "x86/speculation/taa: Add mitigation for TSX Async Abort" + - SAUCE: Revert "x86/cpu: Add a "tsx=" cmdline option with TSX disabled by + default" + - SAUCE: Revert "x86/cpu: Add a helper function x86_read_arch_cap_msr()" + - SAUCE: Revert "x86/msr: Add the IA32_TSX_CTRL MSR" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Fix jump whitelist + clearing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/gen8+: Add RC6 CTX corruption WA" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Lower RM timeout to avoid DSI hard + hangs" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Ignore Length operands + during command matching" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Add support for backward + jumps" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915/cmdparser: Use explicit goto for + error paths" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Add gen9 BCS cmdparsing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Allow parsing of unsized batches" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Support ro ppgtt mapped cmdparser + shadow buffers" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Add support for mandatory + cmdparsing" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Remove Master tables from cmdparser" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Disable Secure Batches for gen6+" + - SAUCE: Revert "UBUNTU: SAUCE: drm/i915: Rename gen7 cmdparser tables" + - drm/i915: Rename gen7 cmdparser tables + - drm/i915: Disable Secure Batches for gen6+ + - drm/i915: Remove Master tables from cmdparser + - drm/i915: Add support for mandatory cmdparsing + - drm/i915: Support ro ppgtt mapped cmdparser shadow buffers + - drm/i915: Allow parsing of unsized batches + - drm/i915: Add gen9 BCS cmdparsing + - drm/i915/cmdparser: Use explicit goto for error paths + - drm/i915/cmdparser: Add support for backward jumps + - drm/i915/cmdparser: Ignore Length operands during command matching + - drm/i915: Lower RM timeout to avoid DSI hard hangs + - drm/i915/gen8+: Add RC6 CTX corruption WA + - drm/i915/cmdparser: Fix jump whitelist clearing + - x86/msr: Add the IA32_TSX_CTRL MSR + - x86/cpu: Add a helper function x86_read_arch_cap_msr() + - x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default + - x86/speculation/taa: Add mitigation for TSX Async Abort + - x86/speculation/taa: Add sysfs reporting for TSX Async Abort + - kvm/x86: Export MDS_NO=0 to guests when TSX is enabled + - x86/tsx: Add "auto" option to the tsx= cmdline parameter + - x86/speculation/taa: Add documentation for TSX Async Abort + - x86/tsx: Add config options to set tsx=on|off|auto + - x86/speculation/taa: Fix printing of TAA_MSG_SMT on IBRS_ALL CPUs + - x86/bugs: Add ITLB_MULTIHIT bug infrastructure + - x86/cpu: Add Tremont to the cpu vulnerability whitelist + - cpu/speculation: Uninline and export CPU mitigations helpers + - Documentation: Add ITLB_MULTIHIT documentation + - kvm: x86, powerpc: do not allow clearing largepages debugfs entry + - kvm: mmu: ITLB_MULTIHIT mitigation + - kvm: Add helper function for creating VM worker threads + - kvm: x86: mmu: Recovery of shattered NX large pages + - Linux 5.3.11 + * The alsa hda driver is not loaded due to the missing of PCIID for Comet + Lake-S [8086:a3f0] (LP: #1852070) + - SAUCE: ALSA: hda: Add Cometlake-S PCI ID + * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877) + - SAUCE: platform/x86: dell-uart-backlight: add missing status command + - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status + - SAUCE: platform/x86: dell-uart-backlight: add force parameter + - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms + * Disable unreliable HPET on CFL-H system (LP: #1852216) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms + * i40e: Setting VF MAC address causes General Protection Fault (LP: #1852432) + - i40e: Fix crash caused by stress setting of VF MAC addresses + * CVE-2019-19072 + - tracing: Have error path in predicate_parse() free its allocated memory + * i40e: general protection fault in i40e_config_vf_promiscuous_mode + (LP: #1852663) + - SAUCE: i40e Fix GPF when deleting VMs + * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO + (LP: #1852581) + - [Packaging] Fix module signing with older modinfo + + -- Manoj Iyer Thu, 05 Dec 2019 09:10:06 -0600 + +linux-oracle (5.3.0-1007.8) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1007.8 -proposed tracker (LP: #1852230) + + * Eoan update: 5.3.10 upstream stable release (LP: #1852111) + - [Config] SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1=n + + [ Ubuntu: 5.3.0-24.26 ] + + * eoan/linux: 5.3.0-24.26 -proposed tracker (LP: #1852232) + * Eoan update: 5.3.9 upstream stable release (LP: #1851550) + - io_uring: fix up O_NONBLOCK handling for sockets + - dm snapshot: introduce account_start_copy() and account_end_copy() + - dm snapshot: rework COW throttling to fix deadlock + - Btrfs: fix inode cache block reserve leak on failure to allocate data space + - btrfs: qgroup: Always free PREALLOC META reserve in + btrfs_delalloc_release_extents() + - iio: adc: meson_saradc: Fix memory allocation order + - iio: fix center temperature of bmc150-accel-core + - libsubcmd: Make _FORTIFY_SOURCE defines dependent on the feature + - perf tests: Avoid raising SEGV using an obvious NULL dereference + - perf map: Fix overlapped map handling + - perf script brstackinsn: Fix recovery from LBR/binary mismatch + - perf jevents: Fix period for Intel fixed counters + - perf tools: Propagate get_cpuid() error + - perf annotate: Propagate perf_env__arch() error + - perf annotate: Fix the signedness of failure returns + - perf annotate: Propagate the symbol__annotate() error return + - perf annotate: Fix arch specific ->init() failure errors + - perf annotate: Return appropriate error code for allocation failures + - perf annotate: Don't return -1 for error when doing BPF disassembly + - staging: rtl8188eu: fix null dereference when kzalloc fails + - RDMA/siw: Fix serialization issue in write_space() + - RDMA/hfi1: Prevent memory leak in sdma_init + - RDMA/iw_cxgb4: fix SRQ access from dump_qp() + - RDMA/iwcm: Fix a lock inversion issue + - HID: hyperv: Use in-place iterator API in the channel callback + - kselftest: exclude failed TARGETS from runlist + - selftests/kselftest/runner.sh: Add 45 second timeout per test + - nfs: Fix nfsi->nrequests count error on nfs_inode_remove_request + - arm64: cpufeature: Effectively expose FRINT capability to userspace + - arm64: Fix incorrect irqflag restore for priority masking for compat + - arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1 #1542419 + - tty: serial: owl: Fix the link time qualifier of 'owl_uart_exit()' + - tty: serial: rda: Fix the link time qualifier of 'rda_uart_exit()' + - serial/sifive: select SERIAL_EARLYCON + - tty: n_hdlc: fix build on SPARC + - misc: fastrpc: prevent memory leak in fastrpc_dma_buf_attach + - RDMA/core: Fix an error handling path in 'res_get_common_doit()' + - RDMA/cm: Fix memory leak in cm_add/remove_one + - RDMA/nldev: Reshuffle the code to avoid need to rebind QP in error path + - RDMA/mlx5: Do not allow rereg of a ODP MR + - RDMA/mlx5: Order num_pending_prefetch properly with synchronize_srcu + - RDMA/mlx5: Add missing synchronize_srcu() for MW cases + - gpio: max77620: Use correct unit for debounce times + - fs: cifs: mute -Wunused-const-variable message + - arm64: vdso32: Fix broken compat vDSO build warnings + - arm64: vdso32: Detect binutils support for dmb ishld + - serial: mctrl_gpio: Check for NULL pointer + - serial: 8250_omap: Fix gpio check for auto RTS/CTS + - arm64: Default to building compat vDSO with clang when CONFIG_CC_IS_CLANG + - arm64: vdso32: Don't use KBUILD_CPPFLAGS unconditionally + - efi/cper: Fix endianness of PCIe class code + - efi/x86: Do not clean dummy variable in kexec path + - MIPS: include: Mark __cmpxchg as __always_inline + - riscv: avoid kernel hangs when trapped in BUG() + - riscv: avoid sending a SIGTRAP to a user thread trapped in WARN() + - riscv: Correct the handling of unexpected ebreak in do_trap_break() + - x86/xen: Return from panic notifier + - ocfs2: clear zero in unaligned direct IO + - fs: ocfs2: fix possible null-pointer dereferences in + ocfs2_xa_prepare_entry() + - fs: ocfs2: fix a possible null-pointer dereference in + ocfs2_write_end_nolock() + - fs: ocfs2: fix a possible null-pointer dereference in + ocfs2_info_scan_inode_alloc() + - btrfs: silence maybe-uninitialized warning in clone_range + - arm64: armv8_deprecated: Checking return value for memory allocation + - sched/fair: Scale bandwidth quota and period without losing quota/period + ratio precision + - sched/vtime: Fix guest/system mis-accounting on task switch + - perf/core: Rework memory accounting in perf_mmap() + - perf/core: Fix corner case in perf_rotate_context() + - perf/x86/amd: Change/fix NMI latency mitigation to use a timestamp + - drm/amdgpu: fix memory leak + - iio: imu: adis16400: release allocated memory on failure + - iio: imu: adis16400: fix memory leak + - iio: imu: st_lsm6dsx: fix waitime for st_lsm6dsx i2c controller + - MIPS: include: Mark __xchg as __always_inline + - MIPS: fw: sni: Fix out of bounds init of o32 stack + - s390/cio: fix virtio-ccw DMA without PV + - virt: vbox: fix memory leak in hgcm_call_preprocess_linaddr + - nbd: fix possible sysfs duplicate warning + - NFSv4: Fix leak of clp->cl_acceptor string + - SUNRPC: fix race to sk_err after xs_error_report + - s390/uaccess: avoid (false positive) compiler warnings + - tracing: Initialize iter->seq after zeroing in tracing_read_pipe() + - perf annotate: Fix multiple memory and file descriptor leaks + - perf/aux: Fix tracking of auxiliary trace buffer allocation + - USB: legousbtower: fix a signedness bug in tower_probe() + - nbd: verify socket is supported during setup + - fuse: flush dirty data/metadata before non-truncate setattr + - fuse: truncate pending writes on O_TRUNC + - ALSA: bebob: Fix prototype of helper function to return negative value + - ALSA: timer: Fix mutex deadlock at releasing card + - ath10k: fix latency issue for QCA988x + - UAS: Revert commit 3ae62a42090f ("UAS: fix alignment of scatter/gather + segments") + - nl80211: fix validation of mesh path nexthop + - USB: gadget: Reject endpoints with 0 maxpacket value + - usb-storage: Revert commit 747668dbc061 ("usb-storage: Set + virt_boundary_mask to avoid SG overflows") + - USB: ldusb: fix ring-buffer locking + - USB: ldusb: fix control-message timeout + - usb: xhci: fix Immediate Data Transfer endianness + - usb: xhci: fix __le32/__le64 accessors in debugfs code + - USB: serial: whiteheat: fix potential slab corruption + - USB: serial: whiteheat: fix line-speed endianness + - xhci: Fix use-after-free regression in xhci clear hub TT implementation + - scsi: qla2xxx: Fix partial flash write of MBI + - scsi: target: cxgbit: Fix cxgbit_fw4_ack() + - HID: i2c-hid: add Trekstor Primebook C11B to descriptor override + - HID: Fix assumption that devices have inputs + - HID: fix error message in hid_open_report() + - HID: logitech-hidpp: split g920_get_config() + - HID: logitech-hidpp: rework device validation + - HID: logitech-hidpp: do all FF cleanup in hidpp_ff_destroy() + - um-ubd: Entrust re-queue to the upper layers + - s390/unwind: fix mixing regs and sp + - s390/cmm: fix information leak in cmm_timeout_handler() + - s390/idle: fix cpu idle time calculation + - ARC: perf: Accommodate big-endian CPU + - IB/hfi1: Avoid excessive retry for TID RDMA READ request + - arm64: Ensure VM_WRITE|VM_SHARED ptes are clean by default + - arm64: cpufeature: Enable Qualcomm Falkor/Kryo errata 1003 + - virtio_ring: fix stalls for packed rings + - rtlwifi: rtl_pci: Fix problem of too small skb->len + - dmaengine: qcom: bam_dma: Fix resource leak + - dmaengine: tegra210-adma: fix transfer failure + - dmaengine: imx-sdma: fix size check for sdma script_number + - dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle + - drm/amdgpu/gmc10: properly set BANK_SELECT and FRAGMENT_SIZE + - drm/i915: Fix PCH reference clock for FDI on HSW/BDW + - drm/amdgpu/gfx10: update gfx golden settings + - drm/amdgpu/powerplay/vega10: allow undervolting in p7 + - drm/amdgpu: Fix SDMA hang when performing VKexample test + - NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid() + - io_uring: ensure we clear io_kiocb->result before each issue + - iommu/vt-d: Fix panic after kexec -p for kdump + - batman-adv: Avoid free/alloc race when handling OGM buffer + - llc: fix sk_buff leak in llc_sap_state_process() + - llc: fix sk_buff leak in llc_conn_service() + - rxrpc: Fix call ref leak + - rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record + - rxrpc: Fix trace-after-put looking at the put peer record + - NFC: pn533: fix use-after-free and memleaks + - bonding: fix potential NULL deref in bond_update_slave_arr + - netfilter: conntrack: avoid possible false sharing + - net: usb: sr9800: fix uninitialized local variable + - sch_netem: fix rcu splat in netem_enqueue() + - net: sched: sch_sfb: don't call qdisc_put() while holding tree lock + - iwlwifi: exclude GEO SAR support for 3168 + - sched/fair: Fix low cpu usage with high throttling by removing expiration of + cpu-local slices + - ALSA: usb-audio: DSD auto-detection for Playback Designs + - ALSA: usb-audio: Update DSD support quirks for Oppo and Rotel + - ALSA: usb-audio: Add DSD support for Gustard U16/X26 USB Interface + - RDMA/mlx5: Use irq xarray locking for mkey_table + - sched/fair: Fix -Wunused-but-set-variable warnings + - powerpc/powernv: Fix CPU idle to be called with IRQs disabled + - Revert "nvme: allow 64-bit results in passthru commands" + - Revert "ALSA: hda: Flush interrupts on disabling" + - Linux 5.3.9 + - [Config] Remove CONFIG_GENERIC_COMPAT_VDSO and + CONFIG_CROSS_COMPILE_COMPAT_VDSO + * Eoan update: v5.3.8 upstream stable release (LP: #1850456) + - drm: Free the writeback_job when it with an empty fb + - drm: Clear the fence pointer when writeback job signaled + - clk: ti: dra7: Fix mcasp8 clock bits + - ARM: dts: Fix wrong clocks for dra7 mcasp + - nvme-pci: Fix a race in controller removal + - scsi: ufs: skip shutdown if hba is not powered + - scsi: megaraid: disable device when probe failed after enabled device + - scsi: qla2xxx: Silence fwdump template message + - scsi: qla2xxx: Fix unbound sleep in fcport delete path. + - scsi: qla2xxx: Fix stale mem access on driver unload + - scsi: qla2xxx: Fix N2N link reset + - scsi: qla2xxx: Fix N2N link up fail + - ARM: dts: Fix gpio0 flags for am335x-icev2 + - ARM: OMAP2+: Fix missing reset done flag for am3 and am43 + - ARM: OMAP2+: Add missing LCDC midlemode for am335x + - ARM: OMAP2+: Fix warnings with broken omap2_set_init_voltage() + - nvme-tcp: fix wrong stop condition in io_work + - nvme-pci: Save PCI state before putting drive into deepest state + - nvme: fix an error code in nvme_init_subsystem() + - nvme-rdma: Fix max_hw_sectors calculation + - Added QUIRKs for ADATA XPG SX8200 Pro 512GB + - nvme: Add quirk for Kingston NVME SSD running FW E8FK11.T + - nvme: allow 64-bit results in passthru commands + - drm/komeda: prevent memory leak in komeda_wb_connector_add + - nvme-rdma: fix possible use-after-free in connect timeout + - blk-mq: honor IO scheduler for multiqueue devices + - ieee802154: ca8210: prevent memory leak + - ARM: dts: am4372: Set memory bandwidth limit for DISPC + - net: dsa: qca8k: Use up to 7 ports for all operations + - MIPS: dts: ar9331: fix interrupt-controller size + - xen/efi: Set nonblocking callbacks + - loop: change queue block size to match when using DIO + - nl80211: fix null pointer dereference + - mac80211: fix txq null pointer dereference + - netfilter: nft_connlimit: disable bh on garbage collection + - net: mscc: ocelot: add missing of_node_put after calling + of_get_child_by_name + - net: dsa: rtl8366rb: add missing of_node_put after calling + of_get_child_by_name + - net: stmmac: xgmac: Not all Unicast addresses may be available + - net: stmmac: dwmac4: Always update the MAC Hash Filter + - net: stmmac: Correctly take timestamp for PTPv2 + - net: stmmac: Do not stop PHY if WoL is enabled + - net: ag71xx: fix mdio subnode support + - RISC-V: Clear load reservations while restoring hart contexts + - riscv: Fix memblock reservation for device tree blob + - drm/amdgpu: fix multiple memory leaks in acp_hw_init + - drm/amd/display: memory leak + - mips: Loongson: Fix the link time qualifier of 'serial_exit()' + - net: hisilicon: Fix usage of uninitialized variable in function + mdio_sc_cfg_reg_write() + - net: stmmac: Avoid deadlock on suspend/resume + - selftests: kvm: Fix libkvm build error + - lib: textsearch: fix escapes in example code + - s390/mm: fix -Wunused-but-set-variable warnings + - net: phy: allow for reset line to be tied to a sleepy GPIO controller + - net: phy: fix write to mii-ctrl1000 register + - namespace: fix namespace.pl script to support relative paths + - Convert filldir[64]() from __put_user() to unsafe_put_user() + - elf: don't use MAP_FIXED_NOREPLACE for elf executable mappings + - Make filldir[64]() verify the directory entry filename is valid + - uaccess: implement a proper unsafe_copy_to_user() and switch filldir over to + it + - filldir[64]: remove WARN_ON_ONCE() for bad directory entries + - net_sched: fix backward compatibility for TCA_KIND + - net_sched: fix backward compatibility for TCA_ACT_KIND + - libata/ahci: Fix PCS quirk application + - Revert "drm/radeon: Fix EEH during kexec" + - ocfs2: fix panic due to ocfs2_wq is null + - nvme-pci: Set the prp2 correctly when using more than 4k page + - ipv4: fix race condition between route lookup and invalidation + - ipv4: Return -ENETUNREACH if we can't create route but saddr is valid + - net: avoid potential infinite loop in tc_ctl_action() + - net: bcmgenet: Fix RGMII_MODE_EN value for GENET v1/2/3 + - net: bcmgenet: Set phydev->dev_flags only for internal PHYs + - net: i82596: fix dma_alloc_attr for sni_82596 + - net/ibmvnic: Fix EOI when running in XIVE mode. + - net: ipv6: fix listify ip6_rcv_finish in case of forwarding + - net: stmmac: disable/enable ptp_ref_clk in suspend/resume flow + - rxrpc: Fix possible NULL pointer access in ICMP handling + - sched: etf: Fix ordering of packets with same txtime + - sctp: change sctp_prot .no_autobind with true + - net: aquantia: temperature retrieval fix + - net: aquantia: when cleaning hw cache it should be toggled + - net: aquantia: do not pass lro session with invalid tcp checksum + - net: aquantia: correctly handle macvlan and multicast coexistence + - net: phy: micrel: Discern KSZ8051 and KSZ8795 PHYs + - net: phy: micrel: Update KSZ87xx PHY name + - net: avoid errors when trying to pop MLPS header on non-MPLS packets + - net/sched: fix corrupted L2 header with MPLS 'push' and 'pop' actions + - netdevsim: Fix error handling in nsim_fib_init and nsim_fib_exit + - net: ethernet: broadcom: have drivers select DIMLIB as needed + - net: phy: Fix "link partner" information disappear issue + - rxrpc: use rcu protection while reading sk->sk_user_data + - io_uring: fix bad inflight accounting for SETUP_IOPOLL|SETUP_SQTHREAD + - io_uring: Fix corrupted user_data + - USB: legousbtower: fix memleak on disconnect + - ALSA: hda/realtek - Add support for ALC711 + - ALSA: hda/realtek - Enable headset mic on Asus MJ401TA + - ALSA: usb-audio: Disable quirks for BOSS Katana amplifiers + - ALSA: hda - Force runtime PM on Nvidia HDMI codecs + - usb: udc: lpc32xx: fix bad bit shift operation + - USB: serial: ti_usb_3410_5052: fix port-close races + - USB: ldusb: fix memleak on disconnect + - USB: usblp: fix use-after-free on disconnect + - USB: ldusb: fix read info leaks + - binder: Don't modify VMA bounds in ->mmap handler + - MIPS: tlbex: Fix build_restore_pagemask KScratch restore + - staging: wlan-ng: fix exit return when sme->key_idx >= NUM_WEPKEYS + - scsi: zfcp: fix reaction on bit error threshold notification + - scsi: sd: Ignore a failure to sync cache due to lack of authorization + - scsi: core: save/restore command resid for error handling + - scsi: core: try to get module before removing device + - scsi: ch: Make it possible to open a ch device multiple times again + - Revert "Input: elantech - enable SMBus on new (2018+) systems" + - Input: da9063 - fix capability and drop KEY_SLEEP + - Input: synaptics-rmi4 - avoid processing unknown IRQs + - Input: st1232 - fix reporting multitouch coordinates + - ASoC: rsnd: Reinitialize bit clock inversion flag for every format setting + - ACPI: CPPC: Set pcc_data[pcc_ss_id] to NULL in acpi_cppc_processor_exit() + - ACPI: NFIT: Fix unlock on error in scrub_show() + - iwlwifi: pcie: change qu with jf devices to use qu configuration + - cfg80211: wext: avoid copying malformed SSIDs + - mac80211: Reject malformed SSID elements + - drm/ttm: Restore ttm prefaulting + - drm/panfrost: Handle resetting on timeout better + - drm/amdgpu: Bail earlier when amdgpu.cik_/si_support is not set to 1 + - drm/amdgpu/sdma5: fix mask value of POLL_REGMEM packet for pipe sync + - drm/i915/userptr: Never allow userptr into the mappable GGTT + - drm/i915: Favor last VBT child device with conflicting AUX ch/DDC pin + - drm/amdgpu/vce: fix allocation size in enc ring test + - drm/amdgpu/vcn: fix allocation size in enc ring test + - drm/amdgpu/uvd6: fix allocation size in enc ring test (v2) + - drm/amdgpu/uvd7: fix allocation size in enc ring test (v2) + - drm/amdgpu: user pages array memory leak fix + - drivers/base/memory.c: don't access uninitialized memmaps in + soft_offline_page_store() + - fs/proc/page.c: don't access uninitialized memmaps in fs/proc/page.c + - io_uring: Fix broken links with offloading + - io_uring: Fix race for sqes with userspace + - io_uring: used cached copies of sq->dropped and cq->overflow + - mmc: mxs: fix flags passed to dmaengine_prep_slave_sg + - mmc: cqhci: Commit descriptors before setting the doorbell + - mmc: sdhci-omap: Fix Tuning procedure for temperatures < -20C + - mm/memory-failure.c: don't access uninitialized memmaps in memory_failure() + - mm/slub: fix a deadlock in show_slab_objects() + - mm/page_owner: don't access uninitialized memmaps when reading + /proc/pagetypeinfo + - mm/memunmap: don't access uninitialized memmap in memunmap_pages() + - mm: memcg/slab: fix panic in __free_slab() caused by premature memcg pointer + release + - mm, compaction: fix wrong pfn handling in __reset_isolation_pfn() + - mm: memcg: get number of pages on the LRU list in memcgroup base on + lru_zone_size + - mm: memblock: do not enforce current limit for memblock_phys* family + - hugetlbfs: don't access uninitialized memmaps in pfn_range_valid_gigantic() + - mm/memory-failure: poison read receives SIGKILL instead of SIGBUS if mmaped + more than once + - zram: fix race between backing_dev_show and backing_dev_store + - xtensa: drop EXPORT_SYMBOL for outs*/ins* + - xtensa: fix change_bit in exclusive access option + - s390/zcrypt: fix memleak at release + - s390/kaslr: add support for R_390_GLOB_DAT relocation type + - lib/vdso: Make clock_getres() POSIX compliant again + - parisc: Fix vmap memory leak in ioremap()/iounmap() + - EDAC/ghes: Fix Use after free in ghes_edac remove path + - arm64: KVM: Trap VM ops when ARM64_WORKAROUND_CAVIUM_TX2_219_TVM is set + - arm64: Avoid Cavium TX2 erratum 219 when switching TTBR + - arm64: Enable workaround for Cavium TX2 erratum 219 when running SMT + - arm64: Allow CAVIUM_TX2_ERRATUM_219 to be selected + - CIFS: avoid using MID 0xFFFF + - cifs: Fix missed free operations + - CIFS: Fix use after free of file info structures + - perf/aux: Fix AUX output stopping + - tracing: Fix race in perf_trace_buf initialization + - fs/dax: Fix pmd vs pte conflict detection + - dm cache: fix bugs when a GFP_NOWAIT allocation fails + - irqchip/sifive-plic: Switch to fasteoi flow + - x86/boot/64: Make level2_kernel_pgt pages invalid outside kernel area + - x86/apic/x2apic: Fix a NULL pointer deref when handling a dying cpu + - x86/hyperv: Make vapic support x2apic mode + - pinctrl: cherryview: restore Strago DMI workaround for all versions + - pinctrl: armada-37xx: fix control of pins 32 and up + - pinctrl: armada-37xx: swap polarity on LED group + - btrfs: block-group: Fix a memory leak due to missing btrfs_put_block_group() + - Btrfs: add missing extents release on file extent cluster relocation error + - btrfs: don't needlessly create extent-refs kernel thread + - Btrfs: fix qgroup double free after failure to reserve metadata for delalloc + - Btrfs: check for the full sync flag while holding the inode lock during + fsync + - btrfs: tracepoints: Fix wrong parameter order for qgroup events + - btrfs: tracepoints: Fix bad entry members of qgroup events + - KVM: PPC: Book3S HV: XIVE: Ensure VP isn't already in use + - memstick: jmb38x_ms: Fix an error handling path in 'jmb38x_ms_probe()' + - cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown + - ceph: just skip unrecognized info in ceph_reply_info_extra + - xen/netback: fix error path of xenvif_connect_data() + - PCI: PM: Fix pci_power_up() + - opp: of: drop incorrect lockdep_assert_held() + - of: reserved_mem: add missing of_node_put() for proper ref-counting + - blk-rq-qos: fix first node deletion of rq_qos_del() + - RDMA/cxgb4: Do not dma memory off of the stack + - Linux 5.3.8 + - [Config] CONFIG_CAVIUM_TX2_ERRATUM_219=y + * Eoan update: 5.3.10 upstream stable release (LP: #1852111) + - regulator: of: fix suspend-min/max-voltage parsing + - ASoC: samsung: arndale: Add missing OF node dereferencing + - ASoC: wm8994: Do not register inapplicable controls for WM1811 + - regulator: da9062: fix suspend_enable/disable preparation + - ASoC: topology: Fix a signedness bug in soc_tplg_dapm_widget_create() + - arm64: dts: allwinner: a64: pine64-plus: Add PHY regulator delay + - arm64: dts: allwinner: a64: Drop PMU node + - arm64: dts: allwinner: a64: sopine-baseboard: Add PHY regulator delay + - arm64: dts: Fix gpio to pinmux mapping + - regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone + - pinctrl: intel: Allocate IRQ chip dynamic + - ASoC: SOF: loader: fix kernel oops on firmware boot failure + - ASoC: SOF: topology: fix parse fail issue for byte/bool tuple types + - ASoC: SOF: Intel: hda: fix warnings during FW load + - ASoC: SOF: Intel: initialise and verify FW crash dump data. + - ASoC: SOF: Intel: hda: Disable DMI L1 entry during capture + - ASoC: rt5682: add NULL handler to set_jack function + - ASoC: intel: sof_rt5682: add remove function to disable jack + - ASoC: intel: bytcr_rt5651: add null check to support_button_press + - regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() + could be uninitialized + - ASoC: wm_adsp: Don't generate kcontrols without READ flags + - ASoc: rockchip: i2s: Fix RPM imbalance + - arm64: dts: rockchip: fix Rockpro64 RK808 interrupt line + - ARM: dts: logicpd-torpedo-som: Remove twl_keypad + - arm64: dts: rockchip: fix RockPro64 vdd-log regulator settings + - arm64: dts: rockchip: fix RockPro64 sdhci settings + - pinctrl: ns2: Fix off by one bugs in ns2_pinmux_enable() + - pinctrl: stmfx: fix null pointer on remove + - arm64: dts: zii-ultra: fix ARM regulator states + - ARM: dts: am3874-iceboard: Fix 'i2c-mux-idle-disconnect' usage + - ASoC: msm8916-wcd-digital: add missing MIX2 path for RX1/2 + - ASoC: simple_card_utils.h: Fix potential multiple redefinition error + - ARM: dts: Use level interrupt for omap4 & 5 wlcore + - ARM: mm: fix alignment handler faults under memory pressure + - scsi: qla2xxx: fix a potential NULL pointer dereference + - scsi: scsi_dh_alua: handle RTPG sense code correctly during state + transitions + - scsi: sni_53c710: fix compilation error + - scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE + - ARM: 8908/1: add __always_inline to functions called from __get_user_check() + - ARM: 8914/1: NOMMU: Fix exc_ret for XIP + - arm64: dts: rockchip: fix RockPro64 sdmmc settings + - arm64: dts: rockchip: Fix usb-c on Hugsun X99 TV Box + - arm64: dts: lx2160a: Correct CPU core idle state name + - ARM: dts: imx6q-logicpd: Re-Enable SNVS power key + - ARM: dts: vf610-zii-scu4-aib: Specify 'i2c-mux-idle-disconnect' + - ARM: dts: imx7s: Correct GPT's ipg clock source + - arm64: dts: imx8mq: Use correct clock for usdhc's ipg clk + - arm64: dts: imx8mm: Use correct clock for usdhc's ipg clk + - perf tools: Fix resource leak of closedir() on the error paths + - perf c2c: Fix memory leak in build_cl_output() + - 8250-men-mcb: fix error checking when get_num_ports returns -ENODEV + - perf kmem: Fix memory leak in compact_gfp_flags() + - ARM: davinci: dm365: Fix McBSP dma_slave_map entry + - drm/amdgpu: fix potential VM faults + - drm/amdgpu: fix error handling in amdgpu_bo_list_create + - scsi: target: core: Do not overwrite CDB byte 1 + - scsi: hpsa: add missing hunks in reset-patch + - ASoC: Intel: sof-rt5682: add a check for devm_clk_get + - ASoC: SOF: control: return true when kcontrol values change + - tracing: Fix "gfp_t" format for synthetic events + - ARM: dts: bcm2837-rpi-cm3: Avoid leds-gpio probing issue + - i2c: aspeed: fix master pending state handling + - drm/komeda: Don't flush inactive pipes + - ARM: 8926/1: v7m: remove register save to stack before svc + - selftests: kvm: vmx_set_nested_state_test: don't check for VMX support twice + - selftests: kvm: fix sync_regs_test with newer gccs + - ALSA: hda: Add Tigerlake/Jasperlake PCI ID + - of: unittest: fix memory leak in unittest_data_add + - MIPS: bmips: mark exception vectors as char arrays + - irqchip/gic-v3-its: Use the exact ITSList for VMOVP + - i2c: mt65xx: fix NULL ptr dereference + - i2c: stm32f7: fix first byte to send in slave mode + - i2c: stm32f7: fix a race in slave mode with arbitration loss irq + - i2c: stm32f7: remove warning when compiling with W=1 + - cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs + - irqchip/sifive-plic: Skip contexts except supervisor in plic_init() + - nbd: protect cmd->status with cmd->lock + - nbd: handle racing with error'ed out commands + - cxgb4: fix panic when attaching to ULD fail + - cxgb4: request the TX CIDX updates to status page + - dccp: do not leak jiffies on the wire + - erspan: fix the tun_info options_len check for erspan + - inet: stop leaking jiffies on the wire + - net: annotate accesses to sk->sk_incoming_cpu + - net: annotate lockless accesses to sk->sk_napi_id + - net: dsa: bcm_sf2: Fix IMP setup for port different than 8 + - net: ethernet: ftgmac100: Fix DMA coherency issue with SW checksum + - net: fix sk_page_frag() recursion from memory reclaim + - net: hisilicon: Fix ping latency when deal with high throughput + - net/mlx4_core: Dynamically set guaranteed amount of counters per VF + - netns: fix GFP flags in rtnl_net_notifyid() + - net: rtnetlink: fix a typo fbd -> fdb + - net: usb: lan78xx: Disable interrupts before calling generic_handle_irq() + - SAUCE: Revert "UBUNTU: SAUCE: (no-up) net: Zeroing the structure + ethtool_wolinfo in ethtool_get_wol()" + - net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() + - selftests: net: reuseport_dualstack: fix uninitalized parameter + - udp: fix data-race in udp_set_dev_scratch() + - vxlan: check tun_info options_len properly + - net: add skb_queue_empty_lockless() + - udp: use skb_queue_empty_lockless() + - net: use skb_queue_empty_lockless() in poll() handlers + - net: use skb_queue_empty_lockless() in busy poll contexts + - net: add READ_ONCE() annotation in __skb_wait_for_more_packets() + - ipv4: fix route update on metric change. + - selftests: fib_tests: add more tests for metric update + - net/smc: fix closing of fallback SMC sockets + - net/smc: keep vlan_id for SMC-R in smc_listen_work() + - keys: Fix memory leak in copy_net_ns + - net: phylink: Fix phylink_dbg() macro + - rxrpc: Fix handling of last subpacket of jumbo packet + - net/mlx5e: Determine source port properly for vlan push action + - net/mlx5e: Remove incorrect match criteria assignment line + - net/mlx5e: Initialize on stack link modes bitmap + - net/mlx5: Fix flow counter list auto bits struct + - net/smc: fix refcounting for non-blocking connect() + - net/mlx5: Fix rtable reference leak + - mlxsw: core: Unpublish devlink parameters during reload + - r8169: fix wrong PHY ID issue with RTL8168dp + - net/mlx5e: Fix ethtool self test: link speed + - net/mlx5e: Fix handling of compressed CQEs in case of low NAPI budget + - ipv4: fix IPSKB_FRAG_PMTU handling with fragmentation + - net: bcmgenet: don't set phydev->link from MAC + - net: dsa: b53: Do not clear existing mirrored port mask + - net: dsa: fix switch tree list + - net: ensure correct skb->tstamp in various fragmenters + - net: hns3: fix mis-counting IRQ vector numbers issue + - net: netem: fix error path for corrupted GSO frames + - net: reorder 'struct net' fields to avoid false sharing + - net: usb: lan78xx: Connect PHY before registering MAC + - r8152: add device id for Lenovo ThinkPad USB-C Dock Gen 2 + - net: netem: correct the parent's backlog when corrupted packet was dropped + - net: phy: bcm7xxx: define soft_reset for 40nm EPHY + - net: bcmgenet: reset 40nm EPHY on energy detect + - net/flow_dissector: switch to siphash + - platform/x86: pmc_atom: Add Siemens SIMATIC IPC227E to critclk_systems DMI + table + - CIFS: Fix retry mid list corruption on reconnects + - selftests/powerpc: Add test case for tlbie vs mtpidr ordering issue + - selftests/powerpc: Fix compile error on tlbie_test due to newer gcc + - ASoC: pcm3168a: The codec does not support S32_LE + - arm64: dts: ti: k3-am65-main: Fix gic-its node unit-address + - usb: gadget: udc: core: Fix segfault if udc_bind_to_driver() for pending + driver fails + - Linux 5.3.10 + - [Config] SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1=n + * Some EFI systems fail to boot in efi_init() when booted via maas + (LP: #1851810) + - efi: efi_get_memory_map -- increase map headroom + * dkms artifacts may expire from the pool (LP: #1850958) + - [Packaging] dkms -- try launchpad librarian for pool downloads + - [Packaging] dkms -- dkms-build quieten wget verbiage + * update ENA driver to version 2.1.0 (LP: #1850175) + - net: ena: don't wake up tx queue when down + - net: ena: clean up indentation issue + * drm/i915: Add support for another CMP-H PCH (LP: #1848491) + - drm/i915/cml: Add second PCH ID for CMP + * Add Intel Comet Lake ethernet support (LP: #1848555) + - SAUCE: e1000e: Add support for Comet Lake + * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281) + - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: avoid overflow in implicit constant conversion + - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test + * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239) + - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms + - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms + * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled + cloud (LP: #1848481) + - [Packaging] include iavf/i40evf in generic + * High power consumption using 5.0.0-25-generic (LP: #1840835) + - PCI: Add a helper to check Power Resource Requirements _PR3 existence + - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a + driver + - PCI: Fix missing inline for pci_pr3_present() + * CML CPUIDs (LP: #1843794) + - x86/cpu: Add Comet Lake to the Intel CPU models header + * shiftfs: prevent exceeding project quotas (LP: #1849483) + - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities + * shiftfs: fix fallocate() (LP: #1849482) + - SAUCE: shiftfs: setup correct s_maxbytes limit + * Bluetooth: hidp: Fix assumptions on the return value of hidp_send_message + (LP: #1850443) + - Bluetooth: hidp: Fix assumptions on the return value of hidp_send_message + * [SRU][B/OEM-B/OEM-OSP1/D/E] UBUNTU: SAUCE: add rtl623 codec support and fix + mic issues (LP: #1850599) + - SAUCE: ALSA: hda/realtek - Add support for ALC623 + - SAUCE: ALSA: hda/realtek - Fix 2 front mics of codec 0x623 + * Suppress "hid_field_extract() called with n (192) > 32!" message floods + (LP: #1850600) + - HID: core: reformat and reduce hid_printk macros + - HID: core: Add printk_once variants to hid_warn() etc + - HID: core: fix dmesg flooding if report field larger than 32bit + * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs + error path (LP: #1850994) // CVE-2019-15794 + - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails + - SAUCE: ovl: Restore vm_file value when lower fs mmap fails + * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677) + - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags + * root can lift kernel lockdown (LP: #1851380) + - SAUCE: (efi-lockdown) Really don't allow lifting lockdown from userspace + * Colour banding in Lenovo G50-80 laptop display (i915) (LP: #1819968) // Eoan + update: v5.3.8 upstream stable release (LP: #1850456) + - drm/edid: Add 6 bpc quirk for SDC panel in Lenovo G50 + + [ Ubuntu: 5.3.0-23.25 ] + + * Incomplete i915 fix for 64-bit x86 kernels (LP: #1852141) // CVE-2019-0155 + - SAUCE: drm/i915/cmdparser: Fix jump whitelist clearing + + -- Khalid Elmously Sun, 17 Nov 2019 21:10:05 -0500 + +linux-oracle (5.3.0-1006.7) eoan; urgency=medium + + * CVE-2019-11135 + - [Config] Disable TSX by default when possible + + [ Ubuntu: 5.3.0-22.24 ] + + * [REGRESSION] md/raid0: cannot assemble multi-zone RAID0 with default_layout + setting (LP: #1849682) + - Revert "md/raid0: avoid RAID0 data corruption due to layout confusion." + * refcount underflow and type confusion in shiftfs (LP: #1850867) // CVE-2019-15793 + - SAUCE: shiftfs: Correct id translation for lower fs operations + - SAUCE: shiftfs: prevent type confusion + - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling + * CVE-2018-12207 + - kvm: x86, powerpc: do not allow clearing largepages debugfs entry + - SAUCE: KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is + active + - SAUCE: x86: Add ITLB_MULTIHIT bug infrastructure + - SAUCE: kvm: mmu: ITLB_MULTIHIT mitigation + - SAUCE: kvm: Add helper function for creating VM worker threads + - SAUCE: kvm: x86: mmu: Recovery of shattered NX large pages + - SAUCE: cpu/speculation: Uninline and export CPU mitigations helpers + - SAUCE: kvm: x86: mmu: Apply global mitigations knob to ITLB_MULTIHIT + * CVE-2019-11135 + - x86/msr: Add the IA32_TSX_CTRL MSR + - x86/cpu: Add a helper function x86_read_arch_cap_msr() + - x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default + - x86/speculation/taa: Add mitigation for TSX Async Abort + - x86/speculation/taa: Add sysfs reporting for TSX Async Abort + - kvm/x86: Export MDS_NO=0 to guests when TSX is enabled + - x86/tsx: Add "auto" option to the tsx= cmdline parameter + - x86/speculation/taa: Add documentation for TSX Async Abort + - x86/tsx: Add config options to set tsx=on|off|auto + - [Config] Disable TSX by default when possible + * CVE-2019-0154 + - SAUCE: drm/i915: Lower RM timeout to avoid DSI hard hangs + - SAUCE: drm/i915/gen8+: Add RC6 CTX corruption WA + * CVE-2019-0155 + - SAUCE: drm/i915: Rename gen7 cmdparser tables + - SAUCE: drm/i915: Disable Secure Batches for gen6+ + - SAUCE: drm/i915: Remove Master tables from cmdparser + - SAUCE: drm/i915: Add support for mandatory cmdparsing + - SAUCE: drm/i915: Support ro ppgtt mapped cmdparser shadow buffers + - SAUCE: drm/i915: Allow parsing of unsized batches + - SAUCE: drm/i915: Add gen9 BCS cmdparsing + - SAUCE: drm/i915/cmdparser: Use explicit goto for error paths + - SAUCE: drm/i915/cmdparser: Add support for backward jumps + - SAUCE: drm/i915/cmdparser: Ignore Length operands during command matching + + -- Andrea Righi Mon, 11 Nov 2019 14:54:13 +0100 + +linux-oracle (5.3.0-1005.5) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1005.5 -proposed tracker (LP: #1850483) + + [ Ubuntu: 5.3.0-21.22 ] + + * eoan/linux: 5.3.0-21.22 -proposed tracker (LP: #1850486) + * Fix signing of staging modules in eoan (LP: #1850234) + - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink + + -- Khalid Elmously Tue, 29 Oct 2019 20:59:22 -0400 + +linux-oracle (5.3.0-1004.4) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1004.4 -proposed tracker (LP: #1849062) + + * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490) + - [Config] oracle: Enable SOF_HDA link and codec + + * Eoan update: v5.3.5 upstream stable release (LP: #1848047) + - [Config] oracle: disable rtc-bd70528 module + + * Eoan update: 5.3.7 upstream stable release (LP: #1848750) + - [Config] oracle: disable staging/fbtft driver + - [Config] oracle: disable Rio 500 driver + + [ Ubuntu: 5.3.0-20.21 ] + + * eoan/linux: 5.3.0-20.21 -proposed tracker (LP: #1849064) + * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490) + - [Config] Enable SOF_HDA link and codec + * Eoan update: 5.3.7 upstream stable release (LP: #1848750) + - panic: ensure preemption is disabled during panic() + - [Config] updateconfigs for USB_RIO500 + - USB: rio500: Remove Rio 500 kernel driver + - USB: yurex: Don't retry on unexpected errors + - USB: yurex: fix NULL-derefs on disconnect + - USB: usb-skeleton: fix runtime PM after driver unbind + - USB: usb-skeleton: fix NULL-deref on disconnect + - xhci: Fix false warning message about wrong bounce buffer write length + - xhci: Prevent device initiated U1/U2 link pm if exit latency is too long + - xhci: Check all endpoints for LPM timeout + - xhci: Fix USB 3.1 capability detection on early xHCI 1.1 spec based hosts + - usb: xhci: wait for CNR controller not ready bit in xhci resume + - xhci: Prevent deadlock when xhci adapter breaks during init + - xhci: Fix NULL pointer dereference in xhci_clear_tt_buffer_complete() + - USB: adutux: fix use-after-free on disconnect + - USB: adutux: fix NULL-derefs on disconnect + - USB: adutux: fix use-after-free on release + - USB: iowarrior: fix use-after-free on disconnect + - USB: iowarrior: fix use-after-free on release + - USB: iowarrior: fix use-after-free after driver unbind + - USB: usblp: fix runtime PM after driver unbind + - USB: chaoskey: fix use-after-free on release + - USB: ldusb: fix NULL-derefs on driver unbind + - serial: uartlite: fix exit path null pointer + - serial: uartps: Fix uartps_major handling + - USB: serial: keyspan: fix NULL-derefs on open() and write() + - USB: serial: ftdi_sio: add device IDs for Sienna and Echelon PL-20 + - USB: serial: option: add Telit FN980 compositions + - USB: serial: option: add support for Cinterion CLS8 devices + - USB: serial: fix runtime PM after driver unbind + - USB: usblcd: fix I/O after disconnect + - USB: microtek: fix info-leak at probe + - USB: dummy-hcd: fix power budget for SuperSpeed mode + - usb: renesas_usbhs: gadget: Do not discard queues in + usb_ep_set_{halt,wedge}() + - usb: renesas_usbhs: gadget: Fix usb_ep_set_{halt,wedge}() behavior + - usb: typec: tcpm: usb: typec: tcpm: Fix a signedness bug in + tcpm_fw_get_caps() + - usb: typec: ucsi: ccg: Remove run_isr flag + - usb: typec: ucsi: displayport: Fix for the mode entering routine + - USB: legousbtower: fix slab info leak at probe + - USB: legousbtower: fix deadlock on disconnect + - USB: legousbtower: fix potential NULL-deref on disconnect + - USB: legousbtower: fix open after failed reset request + - USB: legousbtower: fix use-after-free on release + - mei: me: add comet point (lake) LP device ids + - mei: avoid FW version request on Ibex Peak and earlier + - gpio: eic: sprd: Fix the incorrect EIC offset when toggling + - staging/fbtft: Depend on OF + - staging: bcm2835-audio: Fix draining behavior regression + - Staging: fbtft: fix memory leak in fbtft_framebuffer_alloc + - staging: rtl8188eu: fix HighestRate check in odm_ARFBRefresh_8188E() + - staging: vt6655: Fix memory leak in vt6655_probe + - iio: adc: hx711: fix bug in sampling of data + - iio: adc: ad799x: fix probe error handling + - iio: adc: axp288: Override TS pin bias current for some models + - iio: adc: stm32-adc: move registers definitions + - iio: adc: stm32-adc: fix a race when using several adcs with dma and irq + - iio: light: opt3001: fix mutex unlock race + - iio: light: add missing vcnl4040 of_compatible + - iio: accel: adxl372: Fix/remove limitation for FIFO samples + - iio: accel: adxl372: Fix push to buffers lost samples + - iio: accel: adxl372: Perform a reset at start up + - efivar/ssdt: Don't iterate over EFI vars if no SSDT override was specified + - perf llvm: Don't access out-of-scope array + - perf inject jit: Fix JIT_CODE_MOVE filename + - drm/i915: Perform GGTT restore much earlier during resume + - selinux: fix context string corruption in convert_context() + - CIFS: Gracefully handle QueryInfo errors during open + - CIFS: Force revalidate inode when dentry is stale + - CIFS: Force reval dentry if LOOKUP_REVAL flag is set + - cifs: use cifsInodeInfo->open_file_lock while iterating to avoid a panic + - kernel/sysctl.c: do not override max_threads provided by userspace + - mm/z3fold.c: claim page in the beginning of free + - mm/page_alloc.c: fix a crash in free_pages_prepare() + - mm/vmpressure.c: fix a signedness bug in vmpressure_register_event() + - IB/core: Fix wrong iterating on ports + - firmware: google: increment VPD key_len properly + - gpio: fix getting nonexclusive gpiods from DT + - gpiolib: don't clear FLAG_IS_OUT when emulating open-drain/open-source + - btrfs: relocation: fix use-after-free on dead relocation roots + - btrfs: allocate new inode in NOFS context + - btrfs: fix balance convert to single on 32-bit host CPUs + - Btrfs: fix memory leak due to concurrent append writes with fiemap + - btrfs: fix incorrect updating of log root tree + - btrfs: fix uninitialized ret in ref-verify + - NFS: Fix O_DIRECT accounting of number of bytes read/written + - MIPS: Disable Loongson MMI instructions for kernel build + - MIPS: elf_hwcap: Export userspace ASEs + - RDMA/vmw_pvrdma: Free SRQ only once + - ACPI/PPTT: Add support for ACPI 6.3 thread flag + - arm64: topology: Use PPTT to determine if PE is a thread + - iio: light: fix vcnl4000 devicetree hooks + - Fix the locking in dcache_readdir() and friends + - drm/i915: Bump skl+ max plane width to 5k for linear/x-tiled + - drm/i915: Whitelist COMMON_SLICE_CHICKEN2 + - drm/i915: Mark contents as dirty on a write fault + - drm/msm: Use the correct dma_sync calls harder + - media: stkwebcam: fix runtime PM after driver unbind + - arm64/sve: Fix wrong free for task->thread.sve_state + - tracing/hwlat: Report total time spent in all NMIs during the sample + - tracing/hwlat: Don't ignore outer-loop duration when calculating max_latency + - ftrace: Get a reference counter for the trace_array on filter files + - tracing: Get trace_array reference for available_tracers files + - hwmon: Fix HWMON_P_MIN_ALARM mask + - mtd: rawnand: au1550nd: Fix au_read_buf16() prototype + - x86/asm: Fix MWAITX C-state hint value + - io_uring: only flush workqueues on fileset removal + - efi/tpm: Fix sanity check of unsigned tbl_size being less than zero + - Linux 5.3.7 + - [Packaging] Remove now un-used modules for amd64 + - [Config] Remove Rio500 + - [Config] Remove deselected modules + * Eoan update: v5.3.5 upstream stable release (LP: #1848047) + - drm/vkms: Fix crc worker races + - drm/mcde: Fix uninitialized variable + - drm/bridge: tc358767: Increase AUX transfer length limit + - drm/vkms: Avoid assigning 0 for possible_crtc + - drm/panel: simple: fix AUO g185han01 horizontal blanking + - drm/amd/display: add monitor patch to add T7 delay + - drm/amd/display: Power-gate all DSCs at driver init time + - drm/amd/display: fix not calling ppsmu to trigger PME + - drm/amd/display: Clear FEC_READY shadow register if DPCD write fails + - drm/amd/display: Copy GSL groups when committing a new context + - video: ssd1307fb: Start page range at page_offset + - drm/tinydrm/Kconfig: drivers: Select BACKLIGHT_CLASS_DEVICE + - drm/stm: attach gem fence to atomic state + - drm/bridge: sii902x: fix missing reference to mclk clock + - drm/panel: check failure cases in the probe func + - drm/rockchip: Check for fast link training before enabling psr + - drm/amdgpu: Fix hard hang for S/G display BOs. + - drm/amd/display: Use proper enum conversion functions + - drm/radeon: Fix EEH during kexec + - gpu: drm: radeon: Fix a possible null-pointer dereference in + radeon_connector_set_property() + - clk: imx8mq: Mark AHB clock as critical + - PCI: rpaphp: Avoid a sometimes-uninitialized warning + - pinctrl: stmfx: update pinconf settings + - ipmi_si: Only schedule continuously in the thread in maintenance mode + - clk: qoriq: Fix -Wunused-const-variable + - clk: ingenic/jz4740: Fix "pll half" divider not read/written properly + - clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks + - drm/amd/display: fix issue where 252-255 values are clipped + - drm/amd/display: Fix frames_to_insert math + - drm/amd/display: reprogram VM config when system resume + - drm/amd/display: Register VUPDATE_NO_LOCK interrupts for DCN2 + - powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA + window + - clk: actions: Don't reference clk_init_data after registration + - clk: sirf: Don't reference clk_init_data after registration + - clk: meson: axg-audio: Don't reference clk_init_data after registration + - clk: sprd: Don't reference clk_init_data after registration + - clk: zx296718: Don't reference clk_init_data after registration + - clk: sunxi: Don't call clk_hw_get_name() on a hw that isn't registered + - powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL + - powerpc/rtas: use device model APIs and serialization during LPM + - powerpc/ptdump: fix walk_pagetables() address mismatch + - powerpc/futex: Fix warning: 'oldval' may be used uninitialized in this + function + - powerpc/64s/radix: Fix memory hotplug section page table creation + - powerpc/pseries/mobility: use cond_resched when updating device tree + - powerpc/perf: fix imc allocation failure handling + - pinctrl: tegra: Fix write barrier placement in pmx_writel + - powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag + - vfio_pci: Restore original state on release + - drm/amdgpu/sdma5: fix number of sdma5 trap irq types for navi1x + - drm/nouveau/kms/tu102-: disable input lut when input is already FP16 + - drm/nouveau/volt: Fix for some cards having 0 maximum voltage + - pinctrl: amd: disable spurious-firing GPIO IRQs + - clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain + - clk: renesas: cpg-mssr: Set GENPD_FLAG_ALWAYS_ON for clock domain + - drm/amd/display: support spdif + - drm/amd/powerpaly: fix navi series custom peak level value error + - drm/amd/display: fix MPO HUBP underflow with Scatter Gather + - drm/amd/display: fix trigger not generated for freesync + - selftests/powerpc: Retry on host facility unavailable + - kbuild: Do not enable -Wimplicit-fallthrough for clang for now + - drm/amdgpu/si: fix ASIC tests + - powerpc/64s/exception: machine check use correct cfar for late handler + - pstore: fs superblock limits + - powerpc/eeh: Clean up EEH PEs after recovery finishes + - clk: qcom: gcc-sdm845: Use floor ops for sdcc clks + - powerpc/pseries: correctly track irq state in default idle + - pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c + - mailbox: mediatek: cmdq: clear the event in cmdq initial flow + - ARM: dts: dir685: Drop spi-cpol from the display + - arm64: fix unreachable code issue with cmpxchg + - clk: at91: select parent if main oscillator or bypass is enabled + - clk: imx: pll14xx: avoid glitch when set rate + - clk: imx: clk-pll14xx: unbypass PLL by default + - clk: Make clk_bulk_get_all() return a valid "id" + - powerpc: dump kernel log before carrying out fadump or kdump + - mbox: qcom: add APCS child device for QCS404 + - clk: sprd: add missing kfree + - scsi: core: Reduce memory required for SCSI logging + - dma-buf/sw_sync: Synchronize signal vs syncpt free + - f2fs: fix to drop meta/node pages during umount + - ext4: fix potential use after free after remounting with noblock_validity + - MIPS: Ingenic: Disable broken BTB lookup optimization. + - MIPS: Don't use bc_false uninitialized in __mm_isBranchInstr + - MIPS: tlbex: Explicitly cast _PAGE_NO_EXEC to a boolean + - i2c-cht-wc: Fix lockdep warning + - PCI: tegra: Fix OF node reference leak + - HID: wacom: Fix several minor compiler warnings + - rtc: bd70528: fix driver dependencies + - mips/atomic: Fix loongson_llsc_mb() wreckage + - PCI: pci-hyperv: Fix build errors on non-SYSFS config + - PCI: layerscape: Add the bar_fixed_64bit property to the endpoint driver + - livepatch: Nullify obj->mod in klp_module_coming()'s error path + - mips/atomic: Fix smp_mb__{before,after}_atomic() + - ARM: 8898/1: mm: Don't treat faults reported from cache maintenance as + writes + - soundwire: intel: fix channel number reported by hardware + - PCI: mobiveil: Fix the CPU base address setup in inbound window + - ARM: 8875/1: Kconfig: default to AEABI w/ Clang + - rtc: snvs: fix possible race condition + - rtc: pcf85363/pcf85263: fix regmap error in set_time + - power: supply: register HWMON devices with valid names + - selinux: fix residual uses of current_security() for the SELinux blob + - PCI: Add pci_info_ratelimited() to ratelimit PCI separately + - HID: apple: Fix stuck function keys when using FN + - PCI: rockchip: Propagate errors for optional regulators + - PCI: histb: Propagate errors for optional regulators + - PCI: imx6: Propagate errors for optional regulators + - PCI: exynos: Propagate errors for optional PHYs + - security: smack: Fix possible null-pointer dereferences in + smack_socket_sock_rcv_skb() + - PCI: Use static const struct, not const static struct + - ARM: 8905/1: Emit __gnu_mcount_nc when using Clang 10.0.0 or newer + - ARM: 8903/1: ensure that usable memory in bank 0 starts from a PMD-aligned + address + - i2c: tegra: Move suspend handling to NOIRQ phase + - block, bfq: push up injection only after setting service time + - fat: work around race with userspace's read via blockdev while mounting + - pktcdvd: remove warning on attempting to register non-passthrough dev + - hypfs: Fix error number left in struct pointer member + - tools/power/x86/intel-speed-select: Fix high priority core mask over count + - crypto: hisilicon - Fix double free in sec_free_hw_sgl() + - mm: add dummy can_do_mlock() helper + - kbuild: clean compressed initramfs image + - ocfs2: wait for recovering done after direct unlock request + - kmemleak: increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE default to 16K + - arm64: consider stack randomization for mmap base only when necessary + - mips: properly account for stack randomization and stack guard gap + - arm: properly account for stack randomization and stack guard gap + - arm: use STACK_TOP when computing mmap base address + - cxgb4:Fix out-of-bounds MSI-X info array access + - erspan: remove the incorrect mtu limit for erspan + - hso: fix NULL-deref on tty open + - ipv6: drop incoming packets having a v4mapped source address + - ipv6: Handle missing host route in __ipv6_ifa_notify + - net: ipv4: avoid mixed n_redirects and rate_tokens usage + - net: qlogic: Fix memory leak in ql_alloc_large_buffers + - net: sched: taprio: Fix potential integer overflow in + taprio_set_picos_per_byte + - net: Unpublish sk from sk_reuseport_cb before call_rcu + - nfc: fix memory leak in llcp_sock_bind() + - qmi_wwan: add support for Cinterion CLS8 devices + - rxrpc: Fix rxrpc_recvmsg tracepoint + - sch_cbq: validate TCA_CBQ_WRROPT to avoid crash + - sch_dsmark: fix potential NULL deref in dsmark_init() + - tipc: fix unlimited bundling of small messages + - udp: fix gso_segs calculations + - vsock: Fix a lockdep warning in __vsock_release() + - net: dsa: rtl8366: Check VLAN ID and not ports + - tcp: adjust rto_base in retransmits_timed_out() + - udp: only do GSO if # of segs > 1 + - net/rds: Fix error handling in rds_ib_add_one() + - net: dsa: sja1105: Initialize the meta_lock + - xen-netfront: do not use ~0U as error return value for xennet_fill_frags() + - net: dsa: sja1105: Fix sleeping while atomic in .port_hwtstamp_set + - ptp_qoriq: Initialize the registers' spinlock before calling + ptp_qoriq_settime + - net: dsa: sja1105: Ensure PTP time for rxtstamp reconstruction is not in the + past + - net: dsa: sja1105: Prevent leaking memory + - net: socionext: netsec: always grab descriptor lock + - net: sched: cbs: Avoid division by zero when calculating the port rate + - net: sched: taprio: Avoid division by zero on invalid link speed + - Smack: Don't ignore other bprm->unsafe flags if LSM_UNSAFE_PTRACE is set + - smack: use GFP_NOFS while holding inode_smack::smk_lock + - dm raid: fix updating of max_discard_sectors limit + - dm zoned: fix invalid memory access + - NFC: fix attrs checks in netlink interface + - kexec: bail out upon SIGKILL when allocating memory. + - KVM: hyperv: Fix Direct Synthetic timers assert an interrupt w/o + lapic_in_kernel + - 9p/cache.c: Fix memory leak in v9fs_cache_session_get_cookie + - vfs: set fs_context::user_ns for reconfigure + - Linux 5.3.5 + - [Config] add rtc-bd70528 to modules.ignore + - [Packaging] remove rtc-bd70528 from modules + * Suspend stopped working from 4.4.0-157 onwards (LP: #1844021) // Eoan + update: 5.3.7 upstream stable release (LP: #1848750) + - xhci: Increase STS_SAVE timeout in xhci_suspend() + * CVE-2019-17666 + - SAUCE: rtlwifi: Fix potential overflow on P2P code + * md raid0/linear doesn't show error state if an array member is removed and + allows successful writes (LP: #1847773) + - md raid0/linear: Mark array as 'broken' and fail BIOs if a member is gone + * linux won't build when new virtualbox version is present on the archive + (LP: #1848788) + - [Packaging]: download virtualbox from sources + * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE (LP: #1847744) + - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE + - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE + * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes + to no (LP: #1848492) + - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x + from yes to no + * shiftfs: rework how shiftfs opens files (LP: #1846265) + - SAUCE: shiftfs: rework how shiftfs opens files + * fdatasync performance regression on 5.0 kernels (LP: #1847641) + - blk-wbt: fix performance regression in wbt scale_up/scale_down + * bcache: Performance degradation when querying priority_stats (LP: #1840043) + - bcache: add cond_resched() in __bch_cache_cmp() + * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL + platforms (LP: #1847192) + - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display + - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms + * Add installer support for iwlmvm adapters (LP: #1848236) + - d-i: Add iwlmvm to nic-modules + * Eoan update: v5.3.6 upstream stable release (LP: #1848039) + - s390/process: avoid potential reading of freed stack + - KVM: s390: Test for bad access register and size at the start of S390_MEM_OP + - s390/topology: avoid firing events before kobjs are created + - s390/cio: avoid calling strlen on null pointer + - s390/cio: exclude subchannels with no parent from pseudo check + - KVM: s390: fix __insn32_query() inline assembly + - KVM: PPC: Book3S: Enable XIVE native capability only if OPAL has required + functions + - KVM: PPC: Book3S HV: XIVE: Free escalation interrupts before disabling the + VP + - KVM: PPC: Book3S HV: Don't push XIVE context when not using XIVE device + - KVM: PPC: Book3S HV: Fix race in re-enabling XIVE escalation interrupts + - KVM: PPC: Book3S HV: Check for MMU ready on piggybacked virtual cores + - KVM: PPC: Book3S HV: Don't lose pending doorbell request on migration on P9 + - KVM: X86: Fix userspace set invalid CR4 + - nbd: fix max number of supported devs + - PM / devfreq: tegra: Fix kHz to Hz conversion + - ASoC: Define a set of DAPM pre/post-up events + - ASoC: sgtl5000: Improve VAG power and mute control + - powerpc/xive: Implement get_irqchip_state method for XIVE to fix shutdown + race + - powerpc/mce: Fix MCE handling for huge pages + - powerpc/mce: Schedule work from irq_work + - powerpc/603: Fix handling of the DIRTY flag + - powerpc/32s: Fix boot failure with DEBUG_PAGEALLOC without KASAN. + - powerpc/ptdump: Fix addresses display on PPC32 + - powerpc/powernv: Restrict OPAL symbol map to only be readable by root + - powerpc/pseries: Fix cpu_hotplug_lock acquisition in resize_hpt() + - powerpc/powernv/ioda: Fix race in TCE level allocation + - powerpc/kasan: Fix parallel loading of modules. + - powerpc/kasan: Fix shadow area set up for modules. + - powerpc/book3s64/mm: Don't do tlbie fixup for some hardware revisions + - powerpc/book3s64/radix: Rename CPU_FTR_P9_TLBIE_BUG feature flag + - powerpc/mm: Add a helper to select PAGE_KERNEL_RO or PAGE_READONLY + - powerpc/mm: Fix an Oops in kasan_mmu_init() + - powerpc/mm: Fixup tlbie vs mtpidr/mtlpidr ordering issue on POWER9 + - can: mcp251x: mcp251x_hw_reset(): allow more time after a reset + - tools lib traceevent: Fix "robust" test of do_generate_dynamic_list_file + - tools lib traceevent: Do not free tep->cmdlines in add_new_comm() on failure + - crypto: qat - Silence smp_processor_id() warning + - crypto: skcipher - Unmap pages after an external error + - crypto: cavium/zip - Add missing single_release() + - crypto: caam/qi - fix error handling in ERN handler + - crypto: caam - fix concurrency issue in givencrypt descriptor + - crypto: ccree - account for TEE not ready to report + - crypto: ccree - use the full crypt length value + - MIPS: Treat Loongson Extensions as ASEs + - power: supply: sbs-battery: use correct flags field + - power: supply: sbs-battery: only return health when battery present + - tracing: Make sure variable reference alias has correct var_ref_idx + - usercopy: Avoid HIGHMEM pfn warning + - timer: Read jiffies once when forwarding base clk + - PCI: vmd: Fix config addressing when using bus offsets + - PCI: hv: Avoid use of hv_pci_dev->pci_slot after freeing it + - PCI: vmd: Fix shadow offsets to reflect spec changes + - selftests/tpm2: Add the missing TEST_FILES assignment + - selftests: pidfd: Fix undefined reference to pthread_create() + - watchdog: imx2_wdt: fix min() calculation in imx2_wdt_set_timeout + - perf tools: Fix segfault in cpu_cache_level__read() + - perf stat: Fix a segmentation fault when using repeat forever + - drm/i915/dp: Fix dsc bpp calculations, v5. + - drm/atomic: Reject FLIP_ASYNC unconditionally + - drm/atomic: Take the atomic toys away from X + - drm: mali-dp: Mark expected switch fall-through + - drm/omap: fix max fclk divider for omap36xx + - drm/msm/dsi: Fix return value check for clk_get_parent + - drm/nouveau/kms/nv50-: Don't create MSTMs for eDP connectors + - drm/amd/powerplay: change metrics update period from 1ms to 100ms + - drm/i915/gvt: update vgpu workload head pointer correctly + - drm/i915: to make vgpu ppgtt notificaiton as atomic operation + - mac80211: keep BHs disabled while calling drv_tx_wake_queue() + - mmc: tegra: Implement ->set_dma_mask() + - mmc: sdhci: improve ADMA error reporting + - mmc: sdhci-of-esdhc: set DMA snooping based on DMA coherence + - mmc: sdhci: Let drivers define their DMA mask + - Revert "locking/pvqspinlock: Don't wait if vCPU is preempted" + - libnvdimm/altmap: Track namespace boundaries in altmap + - DTS: ARM: gta04: introduce legacy spi-cs-high to make display work again + - xen/balloon: Set pages PageOffline() in balloon_add_region() + - xen/xenbus: fix self-deadlock after killing user process + - ieee802154: atusb: fix use-after-free at disconnect + - nl80211: validate beacon head + - cfg80211: validate SSID/MBSSID element ordering assumption + - cfg80211: initialize on-stack chandefs + - drivers: thermal: qcom: tsens: Fix memory leak from qfprom read + - ima: always return negative code for error + - ima: fix freeing ongoing ahash_request + - fs: nfs: Fix possible null-pointer dereferences in encode_attrs() + - xprtrdma: Toggle XPRT_CONGESTED in xprtrdma's slot methods + - xprtrdma: Send Queue size grows after a reconnect + - 9p: Transport error uninitialized + - 9p: avoid attaching writeback_fid on mmap with type PRIVATE + - xen/pci: reserve MCFG areas earlier + - fuse: fix request limit + - ceph: fix directories inode i_blkbits initialization + - ceph: fetch cap_gen under spinlock in ceph_add_cap + - ceph: reconnect connection if session hang in opening state + - SUNRPC: RPC level errors should always set task->tk_rpc_status + - watchdog: aspeed: Add support for AST2600 + - netfilter: nf_tables: allow lookups in dynamic sets + - drm/amdgpu: Fix KFD-related kernel oops on Hawaii + - drm/amdgpu: Check for valid number of registers to read + - perf probe: Fix to clear tev->nargs in clear_probe_trace_event() + - pNFS: Ensure we do clear the return-on-close layout stateid on fatal errors + - SUNRPC: Don't try to parse incomplete RPC messages + - pwm: stm32-lp: Add check in case requested period cannot be achieved + - selftests/seccomp: fix build on older kernels + - x86/purgatory: Disable the stackleak GCC plugin for the purgatory + - ntb: point to right memory window index + - thermal: Fix use-after-free when unregistering thermal zone device + - thermal_hwmon: Sanitize thermal_zone type + - iommu/amd: Fix downgrading default page-sizes in alloc_pte() + - libnvdimm/region: Initialize bad block for volatile namespaces + - libnvdimm: Fix endian conversion issues + - fuse: fix memleak in cuse_channel_open + - libnvdimm/nfit_test: Fix acpi_handle redefinition + - sched/membarrier: Call sync_core only before usermode for same mm + - sched/membarrier: Fix private expedited registration check + - sched/core: Fix migration to invalid CPU in __set_cpus_allowed_ptr() + - perf build: Add detection of java-11-openjdk-devel package + - include/trace/events/writeback.h: fix -Wstringop-truncation warnings + - selftests/bpf: adjust strobemeta loop to satisfy latest clang + - kernel/elfcore.c: include proper prototypes + - libbpf: fix false uninitialized variable warning + - blk-mq: move lockdep_assert_held() into elevator_exit + - bpf: Fix bpf_event_output re-entry issue + - net: dsa: microchip: Always set regmap stride to 1 + - perf unwind: Fix libunwind build failure on i386 systems + - mlxsw: spectrum_flower: Fail in case user specifies multiple mirror actions + - nfp: abm: fix memory leak in nfp_abm_u32_knode_replace + - drm/radeon: Bail earlier when radeon.cik_/si_support=0 is passed + - Btrfs: fix selftests failure due to uninitialized i_mode in test inodes + - KVM: nVMX: Fix consistency check on injected exception error code + - tick: broadcast-hrtimer: Fix a race in bc_set_next + - perf stat: Reset previous counts on repeat with interval + - riscv: Avoid interrupts being erroneously enabled in handle_exception() + - vfs: Fix EOVERFLOW testing in put_compat_statfs64 + - coresight: etm4x: Use explicit barriers on enable/disable + - staging: erofs: fix an error handling in erofs_readdir() + - staging: erofs: some compressed cluster should be submitted for corrupted + images + - staging: erofs: add two missing erofs_workgroup_put for corrupted images + - staging: erofs: avoid endless loop of invalid lookback distance 0 + - staging: erofs: detect potential multiref due to corrupted images + - libnvdimm: prevent nvdimm from requesting key when security is disabled + - Linux 5.3.6 + * Eoan update: v5.3.4 upstream stable release (LP: #1848046) + - arcnet: provide a buffer big enough to actually receive packets + - cdc_ncm: fix divide-by-zero caused by invalid wMaxPacketSize + - macsec: drop skb sk before calling gro_cells_receive + - net/phy: fix DP83865 10 Mbps HDX loopback disable function + - net: qrtr: Stop rx_worker before freeing node + - net/sched: act_sample: don't push mac header on ip6gre ingress + - net_sched: add max len check for TCA_KIND + - net: stmmac: Fix page pool size + - nfp: flower: fix memory leak in nfp_flower_spawn_vnic_reprs + - nfp: flower: prevent memory leak in nfp_flower_spawn_phy_reprs + - openvswitch: change type of UPCALL_PID attribute to NLA_UNSPEC + - ppp: Fix memory leak in ppp_write + - sch_netem: fix a divide by zero in tabledist() + - selftests: Update fib_tests to handle missing ping6 + - skge: fix checksum byte order + - tcp_bbr: fix quantization code to not raise cwnd if not probing bandwidth + - usbnet: ignore endpoints with invalid wMaxPacketSize + - usbnet: sanity checking of packet sizes and device mtu + - net/rds: Check laddr_check before calling it + - net/mlx5e: Fix matching on tunnel addresses type + - ipv6: fix a typo in fib6_rule_lookup() + - selftests: Update fib_nexthop_multiprefix to handle missing ping6 + - net: phy: micrel: add Asym Pause workaround for KSZ9021 + - net/sched: cbs: Fix not adding cbs instance to list + - ipv4: Revert removal of rt_uses_gateway + - net_sched: add policy validation for action attributes + - vrf: Do not attempt to create IPv6 mcast rule if IPv6 is disabled + - net/mlx5e: Fix traffic duplication in ethtool steering + - net: sched: fix possible crash in tcf_action_destroy() + - tcp: better handle TCP_USER_TIMEOUT in SYN_SENT state + - net/mlx5: Add device ID of upcoming BlueField-2 + - ALSA: hda: Flush interrupts on disabling + - ASoC: SOF: Intel: hda: Make hdac_device device-managed + - cpufreq: ap806: Add NULL check after kcalloc + - ALSA: hda/hdmi - Don't report spurious jack state changes + - regulator: lm363x: Fix off-by-one n_voltages for lm3632 ldo_vpos/ldo_vneg + - regulator: lm363x: Fix n_voltages setting for lm36274 + - spi: dw-mmio: Clock should be shut when error occurs + - ASoC: tlv320aic31xx: suppress error message for EPROBE_DEFER + - ASoC: sgtl5000: Fix of unmute outputs on probe + - ASoC: sgtl5000: Fix charge pump source assignment + - firmware: qcom_scm: Use proper types for dma mappings + - dmaengine: bcm2835: Print error in case setting DMA mask fails + - leds: leds-lp5562 allow firmware files up to the maximum length + - ASoC: SOF: reset DMA state in prepare + - media: dib0700: fix link error for dibx000_i2c_set_speed + - media: mtk-cir: lower de-glitch counter for rc-mm protocol + - ASoC: SOF: pci: mark last_busy value at runtime PM init + - media: exynos4-is: fix leaked of_node references + - media: vivid:add sanity check to avoid divide error and set value to 1 if 0. + - media: vb2: reorder checks in vb2_poll() + - media: vivid: work around high stack usage with clang + - media: hdpvr: Add device num check and handling + - media: i2c: ov5640: Check for devm_gpiod_get_optional() error + - time/tick-broadcast: Fix tick_broadcast_offline() lockdep complaint + - sched/fair: Fix imbalance due to CPU affinity + - sched/core: Fix CPU controller for !RT_GROUP_SCHED + - x86/apic: Make apic_pending_intr_clear() more robust + - sched/deadline: Fix bandwidth accounting at all levels after offline + migration + - x86/reboot: Always use NMI fallback when shutdown via reboot vector IPI + fails + - rcu/tree: Call setschedule() gp ktread to SCHED_FIFO outside of atomic + region + - x86/apic: Soft disable APIC before initializing it + - ALSA: hda - Show the fatal CORB/RIRB error more clearly + - ALSA: i2c: ak4xxx-adda: Fix a possible null pointer dereference in + build_adc_controls() + - rcu: Add destroy_work_on_stack() to match INIT_WORK_ONSTACK() + - EDAC/mc: Fix grain_bits calculation + - arm64: dts: imx8mq: Correct OPP table according to latest datasheet + - media: iguanair: add sanity checks + - cpuidle: teo: Allow tick to be stopped if PM QoS is used + - gpio: madera: Add support for Cirrus Logic CS47L15 + - gpio: madera: Add support for Cirrus Logic CS47L92 + - arm64: mm: free the initrd reserved memblock in a aligned manner + - soc: amlogic: meson-clk-measure: protect measure with a mutex + - base: soc: Export soc_device_register/unregister APIs + - ALSA: usb-audio: Skip bSynchAddress endpoint check if it is invalid + - ia64:unwind: fix double free for mod->arch.init_unw_table + - EDAC/altera: Use the proper type for the IRQ status bits + - ASoC: rsnd: don't call clk_get_rate() under atomic context + - arm64/prefetch: fix a -Wtype-limits warning + - md/raid1: end bio when the device faulty + - md: don't call spare_active in md_reap_sync_thread if all member devices + can't work + - md: don't set In_sync if array is frozen + - media: media/platform: fsl-viu.c: fix build for MICROBLAZE + - media: staging: tegra-vde: Fix build error + - RAS: Build debugfs.o only when enabled in Kconfig + - ASoC: hdac_hda: fix page fault issue by removing race + - ACPI / processor: don't print errors for processorIDs == 0xff + - loop: Add LOOP_SET_DIRECT_IO to compat ioctl + - perf tools: Fix paths in include statements + - EDAC, pnd2: Fix ioremap() size in dnv_rd_reg() + - efi: cper: print AER info of PCIe fatal error + - firmware: arm_scmi: Check if platform has released shmem before using + - sched/fair: Use rq_lock/unlock in online_fair_sched_group + - idle: Prevent late-arriving interrupts from disrupting offline + - blk-mq: Fix memory leak in blk_mq_init_allocated_queue error handling + - media: gspca: zero usb_buf on error + - perf config: Honour $PERF_CONFIG env var to specify alternate .perfconfig + - perf test vfs_getname: Disable ~/.perfconfig to get default output + - media: mtk-mdp: fix reference count on old device tree + - media: i2c: tda1997x: prevent potential NULL pointer access + - media: fdp1: Reduce FCP not found message level to debug + - media: em28xx: modules workqueue not inited for 2nd device + - arm64/efi: Move variable assignments after SECTIONS + - perf unwind: Fix libunwind when tid != pid + - media: rc: imon: Allow iMON RC protocol for ffdc 7e device + - dmaengine: iop-adma: use correct printk format strings + - ARM: xscale: fix multi-cpu compilation + - perf record: Support aarch64 random socket_id assignment + - media: vsp1: fix memory leak of dl on error return path + - media: i2c: ov5645: Fix power sequence + - media: omap3isp: Don't set streaming state on random subdevs + - media: imx: mipi csi-2: Don't fail if initial state times-out + - kasan/arm64: fix CONFIG_KASAN_SW_TAGS && KASAN_INLINE + - net: lpc-enet: fix printk format strings + - m68k: Prevent some compiler warnings in Coldfire builds + - ARM: dts: imx7d: cl-som-imx7: make ethernet work again + - arm64: dts: qcom: qcs404-evb: Mark WCSS clocks protected + - ARM: dts: imx7-colibri: disable HS400 + - x86/platform/intel/iosf_mbi Rewrite locking + - media: radio/si470x: kill urb on error + - media: hdpvr: add terminating 0 at end of string + - ASoC: uniphier: Fix double reset assersion when transitioning to suspend + state + - powerpc/Makefile: Always pass --synthetic to nm if supported + - tools headers: Fixup bitsperlong per arch includes + - ASoC: sun4i-i2s: Don't use the oversample to calculate BCLK + - ASoC: mchp-i2s-mcc: Wait for RX/TX RDY only if controller is running + - led: triggers: Fix a memory leak bug + - ASoC: mchp-i2s-mcc: Fix unprepare of GCLK + - nbd: add missing config put + - ACPI / APEI: Release resources if gen_pool_add() fails + - arm64: entry: Move ct_user_exit before any other exception + - s390/kasan: provide uninstrumented __strlen + - media: mceusb: fix (eliminate) TX IR signal length limit + - media: dvb-frontends: use ida for pll number + - posix-cpu-timers: Sanitize bogus WARNONS + - media: dvb-core: fix a memory leak bug + - EDAC/amd64: Support more than two controllers for chip selects handling + - cpufreq: imx-cpufreq-dt: Add i.MX8MN support + - libperf: Fix alignment trap with xyarray contents in 'perf stat' + - EDAC/amd64: Recognize DRAM device type ECC capability + - EDAC/amd64: Decode syndrome before translating address + - ARM: at91: move platform-specific asm-offset.h to arch/arm/mach-at91 + - soc: renesas: rmobile-sysc: Set GENPD_FLAG_ALWAYS_ON for always-on domain + - soc: renesas: Enable ARM_ERRATA_754322 for affected Cortex-A9 + - PM / devfreq: Fix kernel oops on governor module load + - ARM: OMAP2+: move platform-specific asm-offset.h to arch/arm/mach-omap2 + - PM / devfreq: passive: Use non-devm notifiers + - PM / devfreq: exynos-bus: Correct clock enable sequence + - media: cec-notifier: clear cec_adap in cec_notifier_unregister + - media: saa7146: add cleanup in hexium_attach() + - media: cpia2_usb: fix memory leaks + - media: saa7134: fix terminology around saa7134_i2c_eeprom_md7134_gate() + - perf trace beauty ioctl: Fix off-by-one error in cmd->string table + - perf report: Fix --ns time sort key output + - perf script: Fix memory leaks in list_scripts() + - media: aspeed-video: address a protential usage of an unitialized var + - media: ov9650: add a sanity check + - leds: lm3532: Fixes for the driver for stability + - ASoC: es8316: fix headphone mixer volume table + - ACPI / CPPC: do not require the _PSD method + - sched/cpufreq: Align trace event behavior of fast switching + - arm64: dts: meson: fix boards regulators states format + - x86/apic/vector: Warn when vector space exhaustion breaks affinity + - arm64: kpti: ensure patched kernel text is fetched from PoU + - perf evlist: Use unshare(CLONE_FS) in sb threads to let setns(CLONE_NEWNS) + work + - arm64: Use correct ll/sc atomic constraints + - jump_label: Don't warn on __exit jump entries + - x86/mm/pti: Do not invoke PTI functions when PTI is disabled + - ASoC: fsl_ssi: Fix clock control issue in master mode + - x86/mm/pti: Handle unaligned address gracefully in pti_clone_pagetable() + - nvmet: fix data units read and written counters in SMART log + - nvme-multipath: fix ana log nsid lookup when nsid is not found + - ALSA: firewire-motu: add support for MOTU 4pre + - iommu/amd: Silence warnings under memory pressure + - ASoC: Intel: Haswell: Adjust machine device private context + - libata/ahci: Drop PCS quirk for Denverton and beyond + - iommu/iova: Avoid false sharing on fq_timer_on + - libtraceevent: Change users plugin directory + - ASoC: dt-bindings: sun4i-spdif: Fix dma-names warning + - ARM: dts: exynos: Mark LDO10 as always-on on Peach Pit/Pi Chromebooks + - x86/amd_nb: Add PCI device IDs for family 17h, model 70h + - ACPI: custom_method: fix memory leaks + - ACPI / PCI: fix acpi_pci_irq_enable() memory leak + - closures: fix a race on wakeup from closure_sync + - hwmon: (k10temp) Add support for AMD family 17h, model 70h CPUs + - hwmon: (acpi_power_meter) Change log level for 'unsafe software power cap' + - md/raid1: fail run raid1 array when active disk less than one + - dmaengine: ti: edma: Do not reset reserved paRAM slots + - kprobes: Prohibit probing on BUG() and WARN() address + - x86/mm: Fix cpumask_of_node() error condition + - irqchip/sifive-plic: set max threshold for ignored handlers + - s390/crypto: xts-aes-s390 fix extra run-time crypto self tests finding + - irqchip/gic-v3-its: Fix LPI release for Multi-MSI devices + - x86/cpu: Add Tiger Lake to Intel family + - platform/x86: intel_pmc_core: Do not ioremap RAM + - platform/x86: intel_pmc_core_pltdrv: Module removal warning fix + - ASoC: dmaengine: Make the pcm->name equal to pcm->id if the name is not set + - tools/power/x86/intel-speed-select: Fix memory leak + - spi: bcm2835: Work around DONE bit erratum + - io_uring: fix wrong sequence setting logic + - block: make rq sector size accessible for block stats + - raid5: don't set STRIPE_HANDLE to stripe which is in batch list + - mmc: core: Clarify sdio_irq_pending flag for MMC_CAP2_SDIO_IRQ_NOTHREAD + - sched/psi: Correct overly pessimistic size calculation + - mmc: sdhci: Fix incorrect switch to HS mode + - mmc: core: Add helper function to indicate if SDIO IRQs is enabled + - mmc: dw_mmc: Re-store SDIO IRQs mask at system resume + - raid5: don't increment read_errors on EILSEQ return + - mmc: mtk-sd: Re-store SDIO IRQs mask at system resume + - libertas: Add missing sentinel at end of if_usb.c fw_table + - ALSA: hda - Add a quirk model for fixing Huawei Matebook X right speaker + - ALSA: hda - Drop unsol event handler for Intel HDMI codecs + - drm/amd/powerplay/smu7: enforce minimal VBITimeout (v2) + - media: ttusb-dec: Fix info-leak in ttusb_dec_send_command() + - drm: fix module name in edid_firmware log message + - ALSA: hda/realtek - Blacklist PC beep for Lenovo ThinkCentre M73/93 + - zd1211rw: remove false assertion from zd_mac_clear() + - btrfs: delayed-inode: Kill the BUG_ON() in btrfs_delete_delayed_dir_index() + - btrfs: extent-tree: Make sure we only allocate extents from block groups + with the same type + - btrfs: tree-checker: Add ROOT_ITEM check + - btrfs: Detect unbalanced tree with empty leaf before crashing btree + operations + - kvm: Nested KVM MMUs need PAE root too + - media: omap3isp: Set device on omap3isp subdevs + - PM / devfreq: passive: fix compiler warning + - ARM: dts: logicpd-torpedo-baseboard: Fix missing video + - ARM: omap2plus_defconfig: Fix missing video + - iwlwifi: fw: don't send GEO_TX_POWER_LIMIT command to FW version 36 + - ALSA: firewire-tascam: handle error code when getting current source of + clock + - ALSA: firewire-tascam: check intermediate state of clock status and retry + - scsi: scsi_dh_rdac: zero cdb in send_mode_select() + - scsi: qla2xxx: Fix Relogin to prevent modifying scan_state flag + - printk: Do not lose last line in kmsg buffer dump + - IB/mlx5: Free mpi in mp_slave mode + - IB/hfi1: Define variables as unsigned long to fix KASAN warning + - IB/hfi1: Do not update hcrc for a KDETH packet during fault injection + - RDMA: Fix double-free in srq creation error flow + - randstruct: Check member structs in is_pure_ops_struct() + - ARM: dts: am3517-evm: Fix missing video + - rcu/tree: Fix SCHED_FIFO params + - ALSA: hda/realtek - PCI quirk for Medion E4254 + - blk-mq: add callback of .cleanup_rq + - scsi: implement .cleanup_rq callback + - powerpc/imc: Dont create debugfs files for cpu-less nodes + - tpm_tis_core: Turn on the TPM before probing IRQ's + - tpm_tis_core: Set TPM_CHIP_FLAG_IRQ before probing for interrupts + - tpm: Wrap the buffer from the caller to tpm_buf in tpm_send() + - fuse: fix deadlock with aio poll and fuse_iqueue::waitq.lock + - fuse: fix missing unlock_page in fuse_writepage() + - fuse: fix beyond-end-of-page access in fuse_parse_cache() + - parisc: Disable HP HSC-PCI Cards to prevent kernel crash + - platform/x86: intel_int0002_vgpio: Fix wakeups not working on Cherry Trail + - KVM: x86: always stop emulation on page fault + - KVM: x86: set ctxt->have_exception in x86_decode_insn() + - KVM: x86: Manually calculate reserved bits when loading PDPTRS + - KVM: x86: Disable posted interrupts for non-standard IRQs delivery modes + - kvm: x86: Add "significant index" flag to a few CPUID leaves + - KVM: x86/mmu: Use fast invalidate mechanism to zap MMIO sptes + - media: videobuf-core.c: poll_wait needs a non-NULL buf pointer + - media: sn9c20x: Add MSI MS-1039 laptop to flip_dmi_table + - media: hantro: Set DMA max segment size + - media: don't drop front-end reference count for ->detach + - media: vivid: fix device init when no_error_inj=1 and fb disabled + - spi: ep93xx: Repair SPI CS lookup tables + - spi: spi-fsl-dspi: Exit the ISR with IRQ_NONE when it's not ours + - binfmt_elf: Do not move brk for INTERP-less ET_EXEC + - ASoC: Intel: NHLT: Fix debug print format + - ASoC: Intel: Skylake: Use correct function to access iomem space + - ASoC: Intel: Fix use of potentially uninitialized variable + - staging: erofs: cannot set EROFS_V_Z_INITED_BIT if fill_inode_lazy fails + - ARM: samsung: Fix system restart on S3C6410 + - ARM: zynq: Use memcpy_toio instead of memcpy on smp bring-up + - arm64: tlb: Ensure we execute an ISB following walk cache invalidation + - arm64: dts: rockchip: limit clock rate of MMC controllers for RK3328 + - iommu/arm-smmu-v3: Disable detection of ATS and PRI + - alarmtimer: Use EOPNOTSUPP instead of ENOTSUPP + - iommu/vt-d: Fix wrong analysis whether devices share the same bus + - regulator: Defer init completion for a while after late_initcall + - efifb: BGRT: Improve efifb_bgrt_sanity_check + - gfs2: clear buf_in_tr when ending a transaction in sweep_bh_for_rgrps + - z3fold: fix retry mechanism in page reclaim + - z3fold: fix memory leak in kmem cache + - mm/compaction.c: clear total_{migrate,free}_scanned before scanning a new + zone + - memcg, oom: don't require __GFP_FS when invoking memcg OOM killer + - memcg, kmem: do not fail __GFP_NOFAIL charges + - lib/lzo/lzo1x_compress.c: fix alignment bug in lzo-rle + - mt76: round up length on mt76_wr_copy + - KEYS: trusted: correctly initialize digests and fix locking issue + - ath10k: fix channel info parsing for non tlv target + - i40e: check __I40E_VF_DISABLE bit in i40e_sync_filters_subtask + - block: mq-deadline: Fix queue restart handling + - block: fix null pointer dereference in blk_mq_rq_timed_out() + - smb3: allow disabling requesting leases + - smb3: fix unmount hang in open_shroot + - smb3: fix leak in "open on server" perf counter + - ovl: Fix dereferencing possible ERR_PTR() + - ovl: filter of trusted xattr results in audit + - btrfs: fix allocation of free space cache v1 bitmap pages + - Btrfs: fix use-after-free when using the tree modification log + - btrfs: Relinquish CPUs in btrfs_compare_trees + - btrfs: adjust dirty_metadata_bytes after writeback failure of extent buffer + - btrfs: qgroup: Fix the wrong target io_tree when freeing reserved data space + - btrfs: qgroup: Fix reserved data space leak if we have multiple reserve + calls + - Btrfs: fix race setting up and completing qgroup rescan workers + - btrfs: Fix a regression which we can't convert to SINGLE profile + - SUNRPC: Dequeue the request from the receive queue while we're re-encoding + - SUNRPC: Fix buffer handling of GSS MIC without slack + - ACPI / LPSS: Save/restore LPSS private registers also on Lynxpoint + - md/raid6: Set R5_ReadError when there is read failure on parity disk + - md: don't report active array_state until after revalidate_disk() completes. + - md: only call set_in_sync() when it is expected to succeed. + - cfg80211: Purge frame registrations on iftype change + - /dev/mem: Bail out upon SIGKILL. + - fs: Export generic_fadvise() + - mm: Handle MADV_WILLNEED through vfs_fadvise() + - xfs: Fix stale data exposure when readahead races with hole punch + - ipmi: move message error checking to avoid deadlock + - mtd: rawnand: stm32_fmc2: avoid warnings when building with W=1 option + - ext4: fix warning inside ext4_convert_unwritten_extents_endio + - ext4: fix punch hole for inline_data file systems + - quota: fix wrong condition in is_quota_modification() + - hwrng: core - don't wait on add_early_randomness() + - i2c: riic: Clear NACK in tend isr + - CIFS: fix max ea value size + - CIFS: Fix oplock handling for SMB 2.1+ protocols + - drm/amd/display: Restore backlight brightness after system resume + - drm/amd/display: dce11.x /dce12 update formula input + - drm/amd/display: Add missing HBM support and raise Vega20's uclk. + - drm/amdgpu/display: fix 64 bit divide + - md/raid0: avoid RAID0 data corruption due to layout confusion. + - mt76: mt7615: always release sem in mt7615_load_patch + - mt76: mt7615: fix mt7615 firmware path definitions + - platform/chrome: cros_ec_rpmsg: Fix race with host command when probe failed + - Linux 5.3.4 + * ELAN469D touch pad not working (LP: #1795292) // Ubuntu won't boot on Dell + Inspiron 7375 (LP: #1837688) // Eoan update: v5.3.4 upstream stable release + (LP: #1848046) + - iommu/amd: Override wrong IVRS IOAPIC on Raven Ridge systems + * Eoan update: v5.3.3 upstream stable release (LP: #1848045) + - Linux 5.3.2 + - Revert "Linux 5.3.2" + - Linux 5.3.3 + * Eoan update: v5.3.2 upstream stable release (LP: #1848042) + - netfilter: add missing IS_ENABLED(CONFIG_NF_TABLES) check to header-file. + - clocksource/drivers/timer-of: Do not warn on deferred probe + - clocksource/drivers: Do not warn on probe defer + - drm/amd/display: Allow cursor async updates for framebuffer swaps + - drm/amd/display: Skip determining update type for async updates + - drm/amd/display: Don't replace the dc_state for fast updates + - drm/amd/display: readd -msse2 to prevent Clang from emitting libcalls to + undefined SW FP routines + - powerpc/xive: Fix bogus error code returned by OPAL + - HID: prodikeys: Fix general protection fault during probe + - HID: sony: Fix memory corruption issue on cleanup. + - HID: logitech: Fix general protection fault caused by Logitech driver + - HID: logitech-dj: Fix crash when initial logi_dj_recv_query_paired_devices + fails + - HID: hidraw: Fix invalid read in hidraw_ioctl + - HID: Add quirk for HP X500 PIXART OEM mouse + - mtd: cfi_cmdset_0002: Use chip_good() to retry in do_write_oneword() + - crypto: talitos - fix missing break in switch statement + - clk: imx: imx8mm: fix audio pll setting + - Revert "mm/z3fold.c: fix race between migration and destruction" + - ALSA: usb-audio: Add Hiby device family to quirks for native DSD support + - ALSA: usb-audio: Add DSD support for EVGA NU Audio + - ALSA: dice: fix wrong packet parameter for Alesis iO26 + - ALSA: hda - Add laptop imic fixup for ASUS M9V laptop + - ALSA: hda - Apply AMD controller workaround for Raven platform + - platform/x86: i2c-multi-instantiate: Derive the device name from parent + - objtool: Clobber user CFLAGS variable + - Linux 5.3.2 + * Check for CPU Measurement sampling (LP: #1847590) + - s390/cpumsf: Check for CPU Measurement sampling + * revert the revert of ext4: make __ext4_get_inode_loc plug (LP: #1846486) + - random: try to actively add entropy rather than passively wait for it + - Revert "Revert "ext4: make __ext4_get_inode_loc plug"" + * Fix non-working Realtek USB ethernet after system resume (LP: #1847063) + - r8152: Set macpassthru in reset_resume callback + * overlayfs: allow with shiftfs as underlay (LP: #1846272) + - SAUCE: overlayfs: allow with shiftfs as underlay + * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186) + - SAUCE: apparmor: fix nnp subset test for unconfined + * PM / hibernate: fix potential memory corruption (LP: #1847118) + - PM / hibernate: memory_bm_find_bit(): Tighten node optimisation + * Miscellaneous Ubuntu changes + - update dkms package versions + + -- Kleber Sacilotto de Souza Thu, 24 Oct 2019 14:07:37 +0200 + +linux-oracle (5.3.0-1003.3) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1003.3 -proposed tracker (LP: #1848644) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-19.20 ] + + * eoan/linux: 5.3.0-19.20 -proposed tracker (LP: #1848648) + * eoan kernel does not contain "ipv6: do not free rt if FIB_LOOKUP_NOREF is + set on suppress rule" (LP: #1847478) + - ipv6: do not free rt if FIB_LOOKUP_NOREF is set on suppress rule + + -- Marcelo Henrique Cerri Fri, 18 Oct 2019 16:14:50 -0300 + +linux-oracle (5.3.0-1002.2) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1002.2 -proposed tracker (LP: #1847295) + + * Miscellaneous Ubuntu changes + - update dkms package versions + + [ Ubuntu: 5.3.0-18.19 ] + + * eoan/linux: 5.3.0-18.19 -proposed tracker (LP: #1847298) + * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704) + - [Packaging] arm64: snapdragon: introduce a snapdragon flavour + - [Packaging] arm64: snapdragon: switch kernel format to Image + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y + - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y + - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y + - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y + - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y + - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y + - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y + - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y + - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y + - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y + - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y + - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y + - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y + - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y + - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y + - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y + - [Config] arm64: snapdragon: CONFIG_USB_OTG=y + - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y + - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y + - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y + - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y + - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y + - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y + - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y + - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y + - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y + - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y + - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y + - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y + + [ Ubuntu: 5.3.0-17.18 ] + + * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641) + * CVE-2019-17056 + - nfc: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17055 + - mISDN: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17054 + - appletalk: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17053 + - ieee802154: enforce CAP_NET_RAW for raw sockets + * CVE-2019-17052 + - ax25: enforce CAP_NET_RAW for raw sockets + * CVE-2019-15098 + - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe() + * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices. + (LP: #1846470) + - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect + * Re-enable linux-libc-dev build on i386 (LP: #1846508) + - [Packaging] Build only linux-libc-dev for i386 + - [Debian] final-checks -- ignore archtictures with no binaries + * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic- + proposed (LP: #1845820) + - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT + * Revert ESE DASD discard support (LP: #1846219) + - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes" + * Miscellaneous Ubuntu changes + - update dkms package versions + + -- Andrea Righi Thu, 10 Oct 2019 14:37:44 +0200 + +linux-oracle (5.3.0-1001.1) eoan; urgency=medium + + * eoan/linux-oracle: 5.3.0-1001.1 -proposed tracker (LP: #1845724) + + * Packaging resync (LP: #1786013) + - [Packaging] update update.conf + + * Change kernel compression method to improve boot speed (LP: #1840934) + - UBUNTU [Config] Change kernel compression to LZ4 + + * Miscellaneous Ubuntu changes + - [Config] update configs after rebase to 5.3 + - [Packaging] Update packaging for rebase to 5.3 + + [ Ubuntu: 5.3.0-16.17 ] + + * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204) + * zfs fails to build on s390x with debug symbols enabled (LP: #1846143) + - SAUCE: s390: Mark atomic const ops always inline + + -- Seth Forshee Wed, 02 Oct 2019 09:25:24 -0500 + +linux-oracle (5.3.0-1000.0) eoan; urgency=medium + + * Emtpy entry + + -- Seth Forshee Wed, 02 Oct 2019 08:22:09 -0500 + +linux-oracle (5.0.0-1004.7) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1004.7 -proposed tracker (LP: #1846019) + + * 5.0-based linux-oracle kernels can't run ADT (LP: #1845434) + - [config] CONFIG_VIRTIO=y + + [ Ubuntu: 5.0.0-31.33 ] + + * disco/linux: 5.0.0-31.33 -proposed tracker (LP: #1846026) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * /proc/self/maps paths missing on live session (was vlc won't start; eoan + 19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies) + (LP: #1842382) + - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs" + + -- Khalid Elmously Mon, 30 Sep 2019 20:23:48 -0400 + +linux-oracle (5.0.0-1003.4) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1003.4 -proposed tracker (LP: #1844358) + + * Disco update: upstream stable patchset 2019-08-13 (LP: #1840076) + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + + [ Ubuntu: 5.0.0-30.32 ] + + * disco/linux: 5.0.0-30.32 -proposed tracker (LP: #1844362) + * Disco update: upstream stable patchset 2019-08-20 (LP: #1840846) + - Revert "e1000e: fix cyclic resets at link up with active tx" + - e1000e: start network tx queue only when link is up + - Input: synaptics - enable SMBUS on T480 thinkpad trackpad + - nilfs2: do not use unexported cpu_to_le32()/le32_to_cpu() in uapi header + - drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT + - firmware: improve LSM/IMA security behaviour + - irqchip/gic-v3-its: Fix command queue pointer comparison bug + - clk: ti: clkctrl: Fix returning uninitialized data + - efi/bgrt: Drop BGRT status field reserved bits check + - perf/core: Fix perf_sample_regs_user() mm check + - ARM: dts: gemini Fix up DNS-313 compatible string + - ARM: omap2: remove incorrect __init annotation + - afs: Fix uninitialised spinlock afs_volume::cb_break_lock + - x86/apic: Fix integer overflow on 10 bit left shift of cpu_khz + - be2net: fix link failure after ethtool offline test + - ppp: mppe: Add softdep to arc4 + - sis900: fix TX completion + - ARM: dts: imx6ul: fix PWM[1-4] interrupts + - pinctrl: mcp23s08: Fix add_data and irqchip_add_nested call order + - dm table: don't copy from a NULL pointer in realloc_argv() + - dm verity: use message limit for data block corruption message + - x86/boot/64: Fix crash if kernel image crosses page table boundary + - x86/boot/64: Add missing fixup_pointer() for next_early_pgt access + - HID: chicony: add another quirk for PixArt mouse + - pinctrl: mediatek: Ignore interrupts that are wake only during resume + - cpu/hotplug: Fix out-of-bounds read when setting fail state + - pinctrl: mediatek: Update cur_mask in mask/mask ops + - linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL + - genirq: Delay deactivation in free_irq() + - genirq: Fix misleading synchronize_irq() documentation + - genirq: Add optional hardware synchronization for shutdown + - x86/ioapic: Implement irq_get_irqchip_state() callback + - x86/irq: Handle spurious interrupt after shutdown gracefully + - x86/irq: Seperate unused system vectors from spurious entry again + - ARC: hide unused function unw_hdr_alloc + - s390: fix stfle zero padding + - s390/qdio: (re-)initialize tiqdio list entries + - s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + - crypto: talitos - move struct talitos_edesc into talitos.h + - crypto: talitos - fix hash on SEC1. + - crypto/NX: Set receive window credits to max number of CRBs in RxFIFO + - drm/udl: introduce a macro to convert dev to udl. + - drm/udl: move to embedding drm device inside udl device. + - x86/entry/32: Fix ENDPROC of common_spurious + - irqchip/irq-csky-mpintc: Support auto irq deliver to all cpus + - arm64: dts: ls1028a: Fix CPU idle fail. + - selftests/powerpc: Add test of fork with mapping above 512TB + - x86/efi: fix a -Wtype-limits compilation warning + - pinctrl: ocelot: fix gpio direction for pins after 31 + - pinctrl: ocelot: fix pinmuxing for pins after 31 + - mm/oom_kill.c: fix uninitialized oc->constraint + - fork,memcg: alloc_thread_stack_node needs to set tsk->stack + - MIPS: ath79: fix ar933x uart parity mode + - MIPS: fix build on non-linux hosts + - arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly + - scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported + - dmaengine: imx-sdma: fix use-after-free on probe error path + - wil6210: fix potential out-of-bounds read + - ath10k: Do not send probe response template for mesh + - ath9k: Check for errors when reading SREV register + - ath6kl: add some bounds checking + - ath10k: add peer id check in ath10k_peer_find_by_id + - wil6210: fix spurious interrupts in 3-msi + - ath: DFS JP domain W56 fixed pulse type 3 RADAR detection + - regmap: debugfs: Fix memory leak in regmap_debugfs_init + - batman-adv: fix for leaked TVLV handler. + - media: dvb: usb: fix use after free in dvb_usb_device_exit + - media: spi: IR LED: add missing of table registration + - crypto: talitos - fix skcipher failure due to wrong output IV + - media: ov7740: avoid invalid framesize setting + - media: marvell-ccic: fix DMA s/g desc number calculation + - media: vpss: fix a potential NULL pointer dereference + - media: media_device_enum_links32: clean a reserved field + - net: stmmac: dwmac1000: Clear unused address entries + - net: stmmac: dwmac4/5: Clear unused address entries + - qed: Set the doorbell address correctly + - signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig + - af_key: fix leaks in key_pol_get_resp and dump_sp. + - xfrm: Fix xfrm sel prefix length validation + - fscrypt: clean up some BUG_ON()s in block encryption/decryption + - perf annotate TUI browser: Do not use member from variable within its own + initialization + - media: mc-device.c: don't memset __user pointer contents + - media: saa7164: fix remove_proc_entry warning + - media: staging: media: davinci_vpfe: - Fix for memory leak if decoder + initialization fails. + - net: phy: Check against net_device being NULL + - crypto: talitos - properly handle split ICV. + - crypto: talitos - Align SEC1 accesses to 32 bits boundaries. + - tua6100: Avoid build warnings. + - batman-adv: Fix duplicated OGMs on NETDEV_UP + - locking/lockdep: Fix merging of hlocks with non-zero references + - media: wl128x: Fix some error handling in fm_v4l2_init_video_device() + - cpupower : frequency-set -r option misses the last cpu in related cpu list + - arm64: mm: make CONFIG_ZONE_DMA32 configurable + - perf jvmti: Address gcc string overflow warning for strncpy() + - net: stmmac: dwmac4: fix flow control issue + - net: stmmac: modify default value of tx-frames + - crypto: inside-secure - do not rely on the hardware last bit for result + descriptors + - net: fec: Do not use netdev messages too early + - net: axienet: Fix race condition causing TX hang + - s390/qdio: handle PENDING state for QEBSM devices + - RAS/CEC: Fix pfn insertion + - net: sfp: add mutex to prevent concurrent state checks + - ipset: Fix memory accounting for hash types on resize + - perf cs-etm: Properly set the value of 'old' and 'head' in snapshot mode + - perf test 6: Fix missing kvm module load for s390 + - perf report: Fix OOM error in TUI mode on s390 + - irqchip/meson-gpio: Add support for Meson-G12A SoC + - media: uvcvideo: Fix access to uninitialized fields on probe error + - media: fdp1: Support M3N and E3 platforms + - iommu: Fix a leak in iommu_insert_resv_region + - gpio: omap: fix lack of irqstatus_raw0 for OMAP4 + - gpio: omap: ensure irq is enabled before wakeup + - regmap: fix bulk writes on paged registers + - bpf: silence warning messages in core + - media: s5p-mfc: fix reading min scratch buffer size on MFC v6/v7 + - selinux: fix empty write to keycreate file + - x86/cpu: Add Ice Lake NNPI to Intel family + - ASoC: meson: axg-tdm: fix sample clock inversion + - rcu: Force inlining of rcu_read_lock() + - x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS + - qed: iWARP - Fix tc for MPA ll2 connection + - block: null_blk: fix race condition for null_del_dev + - blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership + arbitration + - xfrm: fix sa selector validation + - sched/core: Add __sched tag for io_schedule() + - sched/fair: Fix "runnable_avg_yN_inv" not used warnings + - perf/x86/intel/uncore: Handle invalid event coding for free-running counter + - x86/atomic: Fix smp_mb__{before,after}_atomic() + - perf evsel: Make perf_evsel__name() accept a NULL argument + - vhost_net: disable zerocopy by default + - ipoib: correcly show a VF hardware address + - x86/cacheinfo: Fix a -Wtype-limits warning + - blk-iolatency: only account submitted bios + - ACPICA: Clear status of GPEs on first direct enable + - EDAC/sysfs: Fix memory leak when creating a csrow object + - nvme: fix possible io failures when removing multipathed ns + - nvme-pci: properly report state change failure in nvme_reset_work + - nvme-pci: set the errno on ctrl state change error + - lightnvm: pblk: fix freeing of merged pages + - arm64: Do not enable IRQs for ct_user_exit + - ipsec: select crypto ciphers for xfrm_algo + - ipvs: defer hook registration to avoid leaks + - media: s5p-mfc: Make additional clocks optional + - media: i2c: fix warning same module names + - [Config] rename module adv7511 + - ntp: Limit TAI-UTC offset + - timer_list: Guard procfs specific code + - acpi/arm64: ignore 5.1 FADTs that are reported as 5.0 + - media: coda: fix mpeg2 sequence number handling + - media: coda: fix last buffer handling in V4L2_ENC_CMD_STOP + - media: coda: increment sequence offset for the last returned frame + - media: vimc: cap: check v4l2_fill_pixfmt return value + - media: hdpvr: fix locking and a missing msleep + - net: stmmac: sun8i: force select external PHY when no internal one + - rtlwifi: rtl8192cu: fix error handle when usb probe failed + - mt7601u: do not schedule rx_tasklet when the device has been disconnected + - x86/build: Add 'set -e' to mkcapflags.sh to delete broken capflags.c + - mt7601u: fix possible memory leak when the device is disconnected + - ipvs: fix tinfo memory leak in start_sync_thread + - ath10k: add missing error handling + - ath10k: fix PCIE device wake up failed + - perf tools: Increase MAX_NR_CPUS and MAX_CACHES + - ASoC: Intel: hdac_hdmi: Set ops to NULL on remove + - libata: don't request sense data on !ZAC ATA devices + - clocksource/drivers/exynos_mct: Increase priority over ARM arch timer + - xsk: Properly terminate assignment in xskq_produce_flush_desc + - rslib: Fix decoding of shortened codes + - rslib: Fix handling of of caller provided syndrome + - ixgbe: Check DDM existence in transceiver before access + - crypto: serpent - mark __serpent_setkey_sbox noinline + - crypto: asymmetric_keys - select CRYPTO_HASH where needed + - wil6210: drop old event after wmi_call timeout + - EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec + - bcache: check CACHE_SET_IO_DISABLE in allocator code + - bcache: check CACHE_SET_IO_DISABLE bit in bch_journal() + - bcache: acquire bch_register_lock later in cached_dev_free() + - bcache: check c->gc_thread by IS_ERR_OR_NULL in cache_set_flush() + - bcache: fix potential deadlock in cached_def_free() + - net: hns3: fix a -Wformat-nonliteral compile warning + - net: hns3: add some error checking in hclge_tm module + - ath10k: destroy sdio workqueue while remove sdio module + - net: mvpp2: prs: Don't override the sign bit in SRAM parser shift + - igb: clear out skb->tstamp after reading the txtime + - iwlwifi: mvm: Drop large non sta frames + - bpf: fix uapi bpf_prog_info fields alignment + - perf stat: Make metric event lookup more robust + - perf stat: Fix group lookup for metric group + - net: usb: asix: init MAC address buffers + - rxrpc: Fix oops in tracepoint + - bpf, libbpf, smatch: Fix potential NULL pointer dereference + - selftests: bpf: fix inlines in test_lwt_seg6local + - bonding: validate ip header before check IPPROTO_IGMP + - gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants + - tools: bpftool: Fix json dump crash on powerpc + - Bluetooth: hci_bcsp: Fix memory leak in rx_skb + - Bluetooth: Add new 13d3:3491 QCA_ROME device + - Bluetooth: Add new 13d3:3501 QCA_ROME device + - Bluetooth: 6lowpan: search for destination address in all peers + - perf tests: Fix record+probe_libc_inet_pton.sh for powerpc64 + - Bluetooth: Check state in l2cap_disconnect_rsp + - gtp: add missing gtp_encap_disable_sock() in gtp_encap_enable() + - Bluetooth: validate BLE connection interval updates + - gtp: fix suspicious RCU usage + - gtp: fix Illegal context switch in RCU read-side critical section. + - gtp: fix use-after-free in gtp_encap_destroy() + - gtp: fix use-after-free in gtp_newlink() + - net: mvmdio: defer probe of orion-mdio if a clock is not ready + - iavf: fix dereference of null rx_buffer pointer + - floppy: fix out-of-bounds read in next_valid_format + - floppy: fix invalid pointer dereference in drive_name + - xen: let alloc_xenballooned_pages() fail if not enough memory free + - scsi: NCR5380: Always re-enable reselection interrupt + - Revert "scsi: ncr5380: Increase register polling limit" + - scsi: core: Fix race on creating sense cache + - scsi: megaraid_sas: Fix calculation of target ID + - scsi: mac_scsi: Increase PIO/PDMA transfer length threshold + - scsi: mac_scsi: Fix pseudo DMA implementation, take 2 + - crypto: ghash - fix unaligned memory access in ghash_setkey() + - crypto: ccp - Validate the the error value used to index error messages + - crypto: arm64/sha1-ce - correct digest for empty data in finup + - crypto: arm64/sha2-ce - correct digest for empty data in finup + - crypto: chacha20poly1305 - fix atomic sleep when using async algorithm + - crypto: crypto4xx - fix AES CTR blocksize value + - crypto: crypto4xx - fix blocksize for cfb and ofb + - crypto: crypto4xx - block ciphers should only accept complete blocks + - crypto: ccp - memset structure fields to zero before reuse + - crypto: ccp/gcm - use const time tag comparison. + - crypto: crypto4xx - fix a potential double free in ppc4xx_trng_probe + - bcache: Revert "bcache: fix high CPU occupancy during journal" + - bcache: Revert "bcache: free heap cache_set->flush_btree in + bch_journal_free" + - bcache: ignore read-ahead request failure on backing device + - bcache: fix mistaken sysfs entry for io_error counter + - bcache: destroy dc->writeback_write_wq if failed to create + dc->writeback_thread + - Input: gtco - bounds check collection indent level + - Input: synaptics - whitelist Lenovo T580 SMBus intertouch + - regulator: s2mps11: Fix buck7 and buck8 wrong voltages + - arm64: tegra: Update Jetson TX1 GPU regulator timings + - iwlwifi: pcie: don't service an interrupt that was masked + - iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X + - iwlwifi: don't WARN when calling iwl_get_shared_mem_conf with RF-Kill + - iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices + - NFSv4: Handle the special Linux file open access mode + - pnfs/flexfiles: Fix PTR_ERR() dereferences in ff_layout_track_ds_error + - pNFS: Fix a typo in pnfs_update_layout + - pnfs: Fix a problem where we gratuitously start doing I/O through the MDS + - lib/scatterlist: Fix mapping iterator when sg->offset is greater than + PAGE_SIZE + - ASoC: dapm: Adapt for debugfs API change + - raid5-cache: Need to do start() part job after adding journal device + - ALSA: seq: Break too long mutex context in the write loop + - ALSA: hda/realtek - Fixed Headphone Mic can't record on Dell platform + - media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() + - media: coda: Remove unbalanced and unneeded mutex unlock + - media: videobuf2-core: Prevent size alignment wrapping buffer size to 0 + - media: videobuf2-dma-sg: Prevent size from overflowing + - KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed + - arm64: tegra: Fix AGIC register range + - fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys + inodes. + - kconfig: fix missing choice values in auto.conf + - drm/nouveau/i2c: Enable i2c pads & busses during preinit + - padata: use smp_mb in padata_reorder to avoid orphaned padata jobs + - dm zoned: fix zone state management race + - xen/events: fix binding user event channels to cpus + - 9p/xen: Add cleanup path in p9_trans_xen_init + - 9p/virtio: Add cleanup path in p9_virtio_init + - x86/boot: Fix memory leak in default_get_smp_config() + - perf/x86/intel: Fix spurious NMI on fixed counter + - perf/x86/amd/uncore: Do not set 'ThreadMask' and 'SliceMask' for non-L3 PMCs + - perf/x86/amd/uncore: Set the thread mask for F17h L3 PMCs + - drm/edid: parse CEA blocks embedded in DisplayID + - intel_th: pci: Add Ice Lake NNPI support + - PCI: hv: Fix a use-after-free bug in hv_eject_device_work() + - PCI: Do not poll for PME if the device is in D3cold + - PCI: qcom: Ensure that PERST is asserted for at least 100 ms + - Btrfs: fix data loss after inode eviction, renaming it, and fsync it + - Btrfs: fix fsync not persisting dentry deletions due to inode evictions + - Btrfs: add missing inode version, ctime and mtime updates when punching hole + - IB/mlx5: Report correctly tag matching rendezvous capability + - HID: wacom: generic: only switch the mode on devices with LEDs + - HID: wacom: generic: Correct pad syncing + - HID: wacom: correct touch resolution x/y typo + - libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields + - coda: pass the host file in vma->vm_file on mmap + - include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT + architectures + - xfs: don't overflow xattr listent buffer + - xfs: rename m_inotbt_nores to m_finobt_nores + - xfs: don't ever put nlink > 0 inodes on the unlinked list + - xfs: reserve blocks for ifree transaction during log recovery + - xfs: fix reporting supported extra file attributes for statx() + - xfs: serialize unaligned dio writes against all other dio writes + - xfs: abort unaligned nowait directio early + - gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM + - crypto: caam - limit output IV to CBC to work around CTR mode DMA issue + - parisc: Ensure userspace privilege for ptraced processes in regset functions + - parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 + - powerpc/32s: fix suspend/resume when IBATs 4-7 are used + - powerpc/watchpoint: Restore NV GPRs while returning from exception + - powerpc/powernv/npu: Fix reference leak + - powerpc/pseries: Fix oops in hotplug memory notifier + - mmc: sdhci-msm: fix mutex while in spinlock + - eCryptfs: fix a couple type promotion bugs + - mtd: rawnand: mtk: Correct low level time calculation of r/w cycle + - mtd: spinand: read returns badly if the last page has bitflips + - intel_th: msu: Fix single mode with disabled IOMMU + - Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug + - usb: Handle USB3 remote wakeup for LPM enabled devices correctly + - blk-throttle: fix zero wait time for iops throttled group + - blk-iolatency: clear use_delay when io.latency is set to zero + - blkcg: update blkcg_print_stat() to handle larger outputs + - net: mvmdio: allow up to four clocks to be specified for orion-mdio + - dt-bindings: allow up to four clocks for orion-mdio + - dm bufio: fix deadlock with loop device + - ath10k: Check tx_stats before use it + - ath10k: fix incorrect multicast/broadcast rate setting + - spi: rockchip: turn down tx dma bursts + - ath10k: Fix encoding for protected management frames + - media: v4l2-core: fix use-after-free error + - media: usb:zr364xx:Fix KASAN:null-ptr-deref Read in zr364xx_vidioc_querycap + - locking/lockdep: Fix OOO unlock when hlocks need merging + - media: aspeed: change irq to threaded irq + - gpio: omap: Fix lost edge wake-up interrupts + - media: davinci: vpif_capture: fix memory leak in vpif_probe() + - perf/x86/intel: Disable check_msr for real HW + - integrity: Fix __integrity_init_keyring() section mismatch + - iavf: allow null RX descriptors + - ASoC: rsnd: fixup mod ID calculation in rsnd_ctu_probe_ + - bpf: fix callees pruning callers + - net: netsec: initialize tx ring on ndo_open + - EDAC/sysfs: Drop device references properly + - nvme-pci: adjust irq max_vector using num_possible_cpus() + - media: mt9m111: fix fw-node refactoring + - ASoC: soc-core: call snd_soc_unbind_card() under mutex_lock; + - ath10k: fix fw crash by moving chip reset after napi disabled + - netfilter: ctnetlink: Fix regression in conntrack entry deletion + - bpf: fix BPF_ALU32 | BPF_ARSH on BE arches + - gpio: Fix return value mismatch of function gpiod_get_from_of_node() + - ath9k: correctly handle short radar pulses + - ath10k: Fix memory leak in qmi + - net: hns3: add Asym Pause support to fix autoneg problem + - iwlwifi: dbg: fix debug monitor stop and restart delays + - bnxt_en: Disable bus master during PCI shutdown and driver unload. + - bnxt_en: Fix statistics context reservation logic for RDMA driver. + - perf stat: Fix metrics with --no-merge + - perf stat: Don't merge events in the same PMU + - net: hns3: enable broadcast promisc mode when initializing VF + - Bluetooth: hidp: NUL terminate a string in the compat ioctl + - xdp: fix race on generic receive path + - net: hns3: fix __QUEUE_STATE_STACK_XOFF not cleared issue + - blk-iolatency: fix STS_AGAIN handling + - scsi: NCR5380: Handle PDMA failure reliably + - scsi: sd_zbc: Fix compilation warning + - scsi: zfcp: fix request object use-after-free in send path causing seqno + errors + - scsi: zfcp: fix request object use-after-free in send path causing wrong + traces + - cifs: fix crash in smb2_compound_op()/smb2_set_next_command() + - cifs: Properly handle auto disabling of serverino option + - regulator: s2mps11: Fix ERR_PTR dereference on GPIO lookup failure + - iwlwifi: mvm: delay GTK setting in FW in AP mode + - iwlwifi: mvm: clear rfkill_safe_init_done when we start the firmware + - opp: Don't use IS_ERR on invalid supplies + - ASoC: core: Adapt for debugfs API change + - ceph: fix end offset in truncate_inode_pages_range call + - KVM: nVMX: Always sync GUEST_BNDCFGS when it comes from vmcs01 + - KVM: VMX: Fix handling of #MC that occurs during VM-Entry + - KVM: VMX: check CPUID before allowing read/write of IA32_XSS + - KVM: PPC: Book3S HV: Signed extend decrementer value if not using large + decrementer + - KVM: PPC: Book3S HV: Clear pending decrementer exceptions on nested guest + entry + - KVM: PPC: Book3S HV: Fix CR0 setting in TM emulation + - signal/usb: Replace kill_pid_info_as_cred with kill_pid_usb_asyncio + - signal: Correct namespace fixups of si_pid and si_uid + - i3c: fix i2c and i3c scl rate by bus mode + - ARM: dts: gemini: Set DIR-685 SPI CS as active low + - rt2x00usb: fix rx queue hang + - block: Allow mapping of vmalloc-ed buffers + - block: Fix potential overflow in blk_report_zones() + - RDMA/srp: Accept again source addresses that do not have a port number + - mm/nvdimm: add is_ioremap_addr and use that to check ioremap address + - resource: fix locking in find_next_iomem_res() + - powerpc/powernv: Fix stale iommu table base after VFIO + - dax: Fix missed wakeup with PMD faults + - pstore: Fix double-free in pstore_mkfile() failure path + - [Config] rename module adv7511 + * ACPI support for the ARMv8.2 Statistical Profiling Extension (LP: #1841490) + - ACPICA: ACPI 6.3: MADT: add support for statistical profiling in GICC + - ACPICA: ACPI 6.3: PPTT add additional fields in Processor Structure Flags + - ACPI/PPTT: Modify node flag detection to find last IDENTICAL + - ACPI/PPTT: Add function to return ACPI 6.3 Identical tokens + - arm_pmu: acpi: spe: Add initial MADT/SPE probing + - perf: arm_spe: Enable ACPI/Platform automatic module loading + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // QEMU - count cache flush + Spectre v2 mitigation (CVE) (required for POWER9 DD2.3) (LP: #1832622) + - KVM: PPC: Book3S: Add count cache flush parameters to kvmppc_get_cpu_char() + * Additional regression in CMA allocation rework (LP: #1841483) + - dma-direct: fix zone selection after an unaddressable CMA allocation + * [SRU][B-OEM-OSP1/D/E] reduce s2idle power consumption when BIOS uses shared + power resources (LP: #1840882) + - PCI / ACPI: Use cached ACPI device state to get PCI device power state + - ACPI / PM: Introduce concept of a _PR0 dependent device + - PCI / ACPI: Add _PR0 dependent devices + * ipv6: fix neighbour resolution with raw socket (LP: #1834465) + - ipv6: constify rt6_nexthop() + - ipv6: fix neighbour resolution with raw socket + * realtek r8822be kernel module fails after update to linux kernel-headers + 5.0.0-21 (LP: #1838133) + - build_bug.h: add wrapper for _Static_assert + - lib/vsprintf.c: move sizeof(struct printf_spec) next to its definition + - linux/fs.h: move member alignment check next to definition of struct + filename + - rtw88: add license for Makefile + - rtw88: fix subscript above array bounds compiler warning + - rtw88: fix unassigned rssi_level in rtw_sta_info + - rtw88: avoid circular locking between local->iflist_mtx and rtwdev->mutex + - rtw88: Make some symbols static + - rtw88: pci: use ieee80211_ac_numbers instead of 0-3 + - rtw88: pci: check if queue mapping exceeds size of ac_to_hwq + - rtw88: more descriptions about LPS + - rtw88: add fast xmit support + - rtw88: add support for random mac scan + - rtw88: add beacon function setting + - rtw88: 8822c: add rf write protection when switching channel + - rtw88: 8822c: update channel and bandwidth BB setting + - rtw88: 8822c: disable rx clock gating before counter reset + - rtw88: 8822c: use more accurate ofdm fa counting + - rtw88: power on again if it was already on + - rtw88: restore DACK results to save time + - rtw88: rsvd page should go though management queue + - rtw88: fix typo rtw_writ16_set + - rtw88: resolve order of tx power setting routines + - rtw88: do not use (void *) as argument + - rtw88: unify prefixes for tx power setting routine + - rtw88: remove unused variable + - rtw88: fix incorrect tx power limit at 5G + - rtw88: choose the lowest as world-wide power limit + - rtw88: correct power limit selection + - rtw88: update tx power limit table to RF v20 + - rtw88: remove all RTW_MAX_POWER_INDEX macro + - rtw88: refine flow to get tx power index + - rtw88: Fix misuse of GENMASK macro + - rtw88: pci: Rearrange the memory usage for skb in RX ISR + - rtw88: pci: Use DMA sync instead of remapping in RX ISR + - rtw88: debug: dump tx power indexes in use + - rtw88: use txpwr_lmt_cfg_pair struct, not arrays + - rtw88: pci: remove set but not used variable 'ip_sel' + - rtw88: allow c2h operation in irq context + - rtw88: enclose c2h cmd handle with mutex + - rtw88: add BT co-existence support + - SAUCE: rtw88: pci: enable MSI interrupt + * Disco update: upstream stable patchset 2019-08-30 (LP: #1842128) + - selftests/bpf: fix sendmsg6_prog on s390 + - net: mvpp2: Don't check for 3 consecutive Idle frames for 10G links + - selftests: forwarding: gre_multipath: Enable IPv4 forwarding + - selftests: forwarding: gre_multipath: Fix flower filters + - can: mcp251x: add error check when wq alloc failed + - can: gw: Fix error path of cgw_module_init + - ASoC: rockchip: Fix mono capture + - mac80211_hwsim: Fix possible null-pointer dereferences in + hwsim_dump_radio_nl() + - netfilter: ipset: Actually allow destination MAC address for hash:ip,mac + sets too + - netfilter: ipset: Copy the right MAC address in bitmap:ip,mac and + hash:ip,mac sets + - rxrpc: Fix potential deadlock + - rxrpc: Fix the lack of notification when sendmsg() fails on a DATA packet + - net: phy: phy_led_triggers: Fix a possible null-pointer dereference in + phy_led_trigger_change_speed() + - NFS: Fix regression whereby fscache errors are appearing on 'nofsc' mounts + - HID: quirks: Set the INCREMENT_USAGE_ON_DUPLICATE quirk on Saitek X52 + - drm/rockchip: Suspend DP late + - SMB3: Fix potential memory leak when processing compound chain + - s390: put _stext and _etext into .text section + - net: stmmac: Fix issues when number of Queues >= 4 + - net: stmmac: tc: Do not return a fragment entry + - block, bfq: handle NULL return value by bfq_init_rq() + - KVM: arm64: Don't write junk to sysregs on reset + - KVM: arm: Don't write junk to CP15 registers on reset + - clk: socfpga: stratix10: fix rate caclulationg for cnt_clks + - ceph: clear page dirty before invalidate page + - Drivers: hv: vmbus: Fix virt_to_hvpfn() for X86_PAE + - dm integrity: fix a crash due to BUG_ON in __journal_read_write() + - dm raid: add missing cleanup in raid_ctr() + - xfs: don't trip over uninitialized buffer on extent read of corrupted inode + - xfs: always rejoin held resources during defer roll + - rxrpc: Fix local endpoint refcounting + - rxrpc: Fix read-after-free in rxrpc_queue_local() + - rxrpc: Fix local endpoint replacement + - rxrpc: Fix local refcounting + - regulator: axp20x: fix DCDCA and DCDCD for AXP806 + - regulator: axp20x: fix DCDC5 and DCDC6 for AXP803 + - HID: Add 044f:b320 ThrustMaster, Inc. 2 in 1 DT + - MIPS: kernel: only use i8253 clocksource with periodic clockevent + - mips: fix cacheinfo + - netfilter: ebtables: fix a memory leak bug in compat + - ASoC: dapm: Fix handling of custom_stop_condition on DAPM graph walks + - spi: pxa2xx: Balance runtime PM enable/disable on error + - bpf: sockmap, sock_map_delete needs to use xchg + - bpf: sockmap, synchronize_rcu before free'ing map + - bpf: sockmap, only create entry if ulp is not already enabled + - ASoC: dapm: fix a memory leak bug + - bonding: Force slave speed check after link state recovery for 802.3ad + - can: dev: call netif_carrier_off() in register_candev() + - ASoC: Fail card instantiation if DAI format setup fails + - st21nfca_connectivity_event_received: null check the allocation + - st_nci_hci_connectivity_event_received: null check the allocation + - {nl,mac}80211: fix interface combinations on crypto controlled devices + - ASoC: ti: davinci-mcasp: Fix clk PDIR handling for i2s master mode + - ASoC: ti: davinci-mcasp: Correct slot_width posed constraint + - net: usb: qmi_wwan: Add the BroadMobi BM818 card + - qed: RDMA - Fix the hw_ver returned in device attributes + - isdn: mISDN: hfcsusb: Fix possible null-pointer dereferences in + start_isoc_chain() + - net: stmmac: manage errors returned by of_get_mac_address() + - netfilter: ipset: Fix rename concurrency with listing + - nvmem: Use the same permissions for eeprom as for nvmem + - iwlwifi: mvm: avoid races in rate init and rate perform + - iwlwifi: dbg_ini: move iwl_dbg_tlv_load_bin out of debug override ifdef + - iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef + - iwlwifi: fix locking in delayed GTK setting + - iwlwifi: mvm: send LQ command always ASYNC + - isdn: hfcsusb: Fix mISDN driver crash caused by transfer buffer on the stack + - perf bench numa: Fix cpu0 binding + - spi: pxa2xx: Add support for Intel Comet Lake + - spi: pxa2xx: Add support for Intel Tiger Lake + - can: sja1000: force the string buffer NULL-terminated + - can: peak_usb: force the string buffer NULL-terminated + - net/ethernet/qlogic/qed: force the string buffer NULL-terminated + - NFSv4: Fix a credential refcount leak in nfs41_check_delegation_stateid + - NFSv4: When recovering state fails with EAGAIN, retry the same recovery + - NFSv4.1: Fix open stateid recovery + - NFSv4.1: Only reap expired delegations + - NFSv4: Fix a potential sleep while atomic in nfs4_do_reclaim() + - HID: input: fix a4tech horizontal wheel custom usage + - SMB3: Kernel oops mounting a encryptData share with CONFIG_DEBUG_VIRTUAL + - sched/deadline: Fix double accounting of rq/running bw in push & pull + - s390/mm: fix dump_pagetables top level page table walking + - ata: rb532_cf: Fix unused variable warning in rb532_pata_driver_probe + - net: cxgb3_main: Fix a resource leak in a error path in 'init_one()' + - drm/amdgpu: pin the csb buffer on hw init for gfx v8 + - net: hisilicon: make hip04_tx_reclaim non-reentrant + - net: hisilicon: fix hip04-xmit never return TX_BUSY + - net: hisilicon: Fix dma_map_single failed on arm64 + - NFSv4: Ensure state recovery handles ETIMEDOUT correctly + - libata: have ata_scsi_rw_xlat() fail invalid passthrough requests + - libata: add SG safety checks in SFF pio transfers + - x86/lib/cpu: Address missing prototypes warning + - drm/vmwgfx: fix memory leak when too many retries have occurred + - block: aoe: Fix kernel crash due to atomic sleep when exiting + - perf ftrace: Fix failure to set cpumask when only one cpu is present + - perf cpumap: Fix writing to illegal memory in handling cpumap mask + - perf pmu-events: Fix missing "cpu_clk_unhalted.core" event + - selftests: kvm: Adding config fragments + - HID: wacom: correct misreported EKR ring values + - HID: wacom: Correct distance scale for 2nd-gen Intuos devices + - Revert "dm bufio: fix deadlock with loop device" + - ceph: don't try fill file_lock on unsuccessful GETFILELOCK reply + - libceph: fix PG split vs OSD (re)connect race + - drm/nouveau: Don't retry infinitely when receiving no data on i2c over AUX + - gpiolib: never report open-drain/source lines as 'input' to user-space + - userfaultfd_release: always remove uffd flags and clear vm_userfaultfd_ctx + - x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC on i386 + - x86/apic: Handle missing global clockevent gracefully + - x86/CPU/AMD: Clear RDRAND CPUID bit on AMD family 15h/16h + - x86/boot: Save fields explicitly, zero out everything else + - x86/boot: Fix boot regression caused by bootparam sanitizing + - dm kcopyd: always complete failed jobs + - dm btree: fix order of block initialization in btree_split_beneath + - dm space map metadata: fix missing store of apply_bops() return value + - dm table: fix invalid memory accesses with too high sector number + - dm zoned: improve error handling in reclaim + - dm zoned: improve error handling in i/o map code + - dm zoned: properly handle backing device failure + - genirq: Properly pair kobject_del() with kobject_add() + - mm, page_alloc: move_freepages should not examine struct page of reserved + memory + - mm, page_owner: handle THP splits correctly + - mm/zsmalloc.c: migration can leave pages in ZS_EMPTY indefinitely + - mm/zsmalloc.c: fix race condition in zs_destroy_pool + - mm/kasan: fix false positive invalid-free reports with + CONFIG_KASAN_SW_TAGS=y + - xfs: fix missing ILOCK unlock when xfs_setattr_nonsize fails due to EDQUOT + - dm zoned: fix potential NULL dereference in dmz_do_reclaim() + - powerpc: Allow flush_(inval_)dcache_range to work across ranges >4GB + * Disco update: upstream stable patchset 2019-08-29 (LP: #1841994) + - scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure + - gcc-9: don't warn about uninitialized variable + - driver core: Establish order of operations for device_add and device_del via + bitflag + - drivers/base: Introduce kill_device() + - libnvdimm/bus: Prevent duplicate device_unregister() calls + - libnvdimm/bus: Prepare the nd_ioctl() path to be re-entrant + - libnvdimm/bus: Fix wait_nvdimm_bus_probe_idle() ABBA deadlock + - HID: wacom: fix bit shift for Cintiq Companion 2 + - HID: Add quirk for HP X1200 PIXART OEM mouse + - atm: iphase: Fix Spectre v1 vulnerability + - bnx2x: Disable multi-cos feature. + - ife: error out when nla attributes are empty + - ip6_gre: reload ipv6h in prepare_ip6gre_xmit_ipv6 + - ip6_tunnel: fix possible use-after-free on xmit + - ipip: validate header length in ipip_tunnel_xmit + - mlxsw: spectrum: Fix error path in mlxsw_sp_module_init() + - mvpp2: fix panic on module removal + - mvpp2: refactor MTU change code + - net: bridge: delete local fdb on device init failure + - net: bridge: mcast: don't delete permanent entries when fast leave is + enabled + - net: fix ifindex collision during namespace removal + - net/mlx5e: always initialize frag->last_in_page + - net/mlx5: Use reversed order when unregister devices + - net: phylink: Fix flow control for fixed-link + - net: qualcomm: rmnet: Fix incorrect UL checksum offload logic + - net: sched: Fix a possible null-pointer dereference in dequeue_func() + - net sched: update vlan action for batched events operations + - net: sched: use temporary variable for actions indexes + - net/smc: do not schedule tx_work in SMC_CLOSED state + - NFC: nfcmrvl: fix gpio-handling regression + - ocelot: Cancel delayed work before wq destruction + - tipc: compat: allow tipc commands without arguments + - tun: mark small packets as owned by the tap sock + - net/mlx5: Fix modify_cq_in alignment + - net/mlx5e: Prevent encap flow counter update async to user query + - r8169: don't use MSI before RTL8168d + - compat_ioctl: pppoe: fix PPPOEIOCSFWD handling + - cgroup: Call cgroup_release() before __exit_signal() + - cgroup: Implement css_task_iter_skip() + - cgroup: Include dying leaders with live threads in PROCS iterations + - cgroup: css_task_iter_skip()'d iterators must be advanced before accessed + - cgroup: Fix css_task_iter_advance_css_set() cset skip condition + - spi: bcm2835: Fix 3-wire mode if DMA is enabled + - ALSA: usb-audio: Sanity checks for each pipe and EP types + - ALSA: usb-audio: Fix gpf in snd_usb_pipe_sanity_check + - drivers/net/ethernet/marvell/mvmdio.c: Fix non OF case + - net: phylink: don't start and stop SGMII PHYs in SFP modules twice + - net: phy: mscc: initialize stats array + - bpf: fix XDP vlan selftests test_xdp_vlan.sh + - selftests/bpf: add wrapper scripts for test_xdp_vlan.sh + - selftests/bpf: reduce time to execute test_xdp_vlan.sh + - net: fix bpf_xdp_adjust_head regression for generic-XDP + - hv_sock: Fix hang when a connection is closed + - iio: cros_ec_accel_legacy: Fix incorrect channel setting + - iio: adc: max9611: Fix misuse of GENMASK macro + - staging: gasket: apex: fix copy-paste typo + - staging: android: ion: Bail out upon SIGKILL when allocating memory. + - crypto: ccp - Fix oops by properly managing allocated structures + - crypto: ccp - Add support for valid authsize values less than 16 + - crypto: ccp - Ignore tag length when decrypting GCM ciphertext + - usb: usbfs: fix double-free of usb memory upon submiturb error + - usb: iowarrior: fix deadlock on disconnect + - sound: fix a memory leak bug + - mmc: cavium: Set the correct dma max segment size for mmc_host + - mmc: cavium: Add the missing dma unmap when the dma has finished. + - loop: set PF_MEMALLOC_NOIO for the worker thread + - Input: usbtouchscreen - initialize PM mutex before using it + - Input: elantech - enable SMBus on new (2018+) systems + - Input: synaptics - enable RMI mode for HP Spectre X360 + - perf annotate: Fix s390 gap between kernel end and module start + - perf db-export: Fix thread__exec_comm() + - perf record: Fix module size on s390 + - x86/purgatory: Use CFLAGS_REMOVE rather than reset KBUILD_CFLAGS + - gfs2: gfs2_walk_metadata fix + - usb: host: xhci-rcar: Fix timeout in xhci_suspend() + - usb: yurex: Fix use-after-free in yurex_delete + - usb: typec: tcpm: free log buf memory when remove debug file + - usb: typec: tcpm: remove tcpm dir if no children + - usb: typec: tcpm: Add NULL check before dereferencing config + - usb: typec: tcpm: Ignore unsupported/unknown alternate mode requests + - can: rcar_canfd: fix possible IRQ storm on high load + - can: peak_usb: fix potential double kfree_skb() + - netfilter: nfnetlink: avoid deadlock due to synchronous request_module + - vfio-ccw: Set pa_nr to 0 if memory allocation fails for pa_iova_pfn + - netfilter: Fix rpfilter dropping vrf packets by mistake + - netfilter: conntrack: always store window size un-scaled + - netfilter: nft_hash: fix symhash with modulus one + - scripts/sphinx-pre-install: fix script for RHEL/CentOS + - drm/amd/display: Wait for backlight programming completion in set backlight + level + - drm/amd/display: use encoder's engine id to find matched free audio device + - drm/amd/display: Fix dc_create failure handling and 666 color depths + - drm/amd/display: Only enable audio if speaker allocation exists + - drm/amd/display: Increase size of audios array + - iscsi_ibft: make ISCSI_IBFT dependson ACPI instead of ISCSI_IBFT_FIND + - nl80211: fix NL80211_HE_MAX_CAPABILITY_LEN + - mac80211: don't warn about CW params when not using them + - allocate_flower_entry: should check for null deref + - hwmon: (nct6775) Fix register address and added missed tolerance for nct6106 + - drm: silence variable 'conn' set but not used + - cpufreq/pasemi: fix use-after-free in pas_cpufreq_cpu_init() + - s390/qdio: add sanity checks to the fast-requeue path + - ALSA: compress: Fix regression on compressed capture streams + - ALSA: compress: Prevent bypasses of set_params + - ALSA: compress: Don't allow paritial drain operations on capture streams + - ALSA: compress: Be more restrictive about when a drain is allowed + - perf tools: Fix proper buffer size for feature processing + - perf probe: Avoid calling freeing routine multiple times for same pointer + - drbd: dynamically allocate shash descriptor + - ACPI/IORT: Fix off-by-one check in iort_dev_find_its_id() + - ARM: davinci: fix sleep.S build error on ARMv4 + - ARM: dts: bcm: bcm47094: add missing #cells for mdio-bus-mux + - scsi: megaraid_sas: fix panic on loading firmware crashdump + - scsi: ibmvfc: fix WARN_ON during event pool release + - scsi: scsi_dh_alua: always use a 2 second delay before retrying RTPG + - test_firmware: fix a memory leak bug + - tty/ldsem, locking/rwsem: Add missing ACQUIRE to read_failed sleep loop + - perf/core: Fix creating kernel counters for PMUs that override event->cpu + - s390/dma: provide proper ARCH_ZONE_DMA_BITS value + - HID: sony: Fix race condition between rumble and device remove. + - x86/purgatory: Do not use __builtin_memcpy and __builtin_memset + - ALSA: usb-audio: fix a memory leak bug + - can: peak_usb: pcan_usb_pro: Fix info-leaks to USB devices + - can: peak_usb: pcan_usb_fd: Fix info-leaks to USB devices + - hwmon: (nct7802) Fix wrong detection of in4 presence + - drm/i915: Fix wrong escape clock divisor init for GLK + - ALSA: firewire: fix a memory leak bug + - ALSA: hiface: fix multiple memory leak bugs + - ALSA: hda - Don't override global PCM hw info flag + - ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457) + - mac80211: don't WARN on short WMM parameters from AP + - dax: dax_layout_busy_page() should not unmap cow pages + - SMB3: Fix deadlock in validate negotiate hits reconnect + - smb3: send CAP_DFS capability during session setup + - NFSv4: Fix an Oops in nfs4_do_setattr + - KVM: Fix leak vCPU's VMCS value into other pCPU + - mwifiex: fix 802.11n/WPA detection + - iwlwifi: don't unmap as page memory that was mapped as single + - iwlwifi: mvm: fix an out-of-bound access + - iwlwifi: mvm: don't send GEO_TX_POWER_LIMIT on version < 41 + - iwlwifi: mvm: fix version check for GEO_TX_POWER_LIMIT support + - iio: adc: gyroadc: fix uninitialized return code + - staging: wilc1000: flush the workqueue before deinit the host + - can: flexcan: fix stop mode acknowledgment + - can: flexcan: fix an use-after-free in flexcan_setup_stop_mode() + - powerpc: fix off by one in max_zone_pfn initialization for ZONE_DMA + - scripts/sphinx-pre-install: don't use LaTeX with CentOS 7 + - rq-qos: don't reset has_sleepers on spurious wakeups + - rq-qos: set ourself TASK_UNINTERRUPTIBLE after we schedule + - rq-qos: use a mb for got_token + - drm/amd/display: Clock does not lower in Updateplanes + - drm/amd/display: fix DMCU hang when going into Modern Standby + - drm/amd/display: allocate 4 ddc engines for RV2 + - mac80211: fix possible memory leak in ieee80211_assign_beacon + - hwmon: (occ) Fix division by zero issue + - ARM: dts: imx6ul: fix clock frequency property name of I2C buses + - powerpc/papr_scm: Force a scm-unbind if initial scm-bind fails + - arm64: Force SSBS on context switch + - arm64: entry: SP Alignment Fault doesn't write to FAR_EL1 + - drm/msm/dpu: Correct dpu encoder spinlock initialization + - perf script: Fix off by one in brstackinsn IPC computation + - perf stat: Fix segfault for event group in repeat mode + - nvme: ignore subnqn for ADATA SX6000LNP + - nvme: fix memory leak caused by incorrect subsystem free + - perf/x86: Apply more accurate check on hypervisor platform + - gen_compile_commands: lower the entry count threshold + - NFSv4: Fix delegation state recovery + - NFSv4: Check the return value of update_open_stateid() + - KVM: arm/arm64: Sync ICH_VMCR_EL2 back when about to block + - iwlwifi: mvm: fix a use-after-free bug in iwl_mvm_tx_tso_segment + - sh: kernel: hw_breakpoint: Fix missing break in switch statement + - seq_file: fix problem when seeking mid-record + - mm/hmm: fix bad subpage pointer in try_to_unmap_one + - mm: mempolicy: make the behavior consistent when MPOL_MF_MOVE* and + MPOL_MF_STRICT were specified + - mm: mempolicy: handle vma with unmovable pages mapped correctly in mbind + - mm/memcontrol.c: fix use after free in mem_cgroup_iter() + - mm/usercopy: use memory range to be accessed for wraparound check + - cpufreq: schedutil: Don't skip freq update when limits change + - xtensa: add missing isync to the cpu_reset TLB code + - ALSA: hda/realtek - Add quirk for HP Envy x360 + - ALSA: usb-audio: Fix a stack buffer overflow bug in check_input_term + - ALSA: usb-audio: Fix an OOB bug in parse_audio_mixer_unit + - ALSA: hda - Apply workaround for another AMD chip 1022:1487 + - ALSA: hda - Fix a memory leak bug + - HID: holtek: test for sanity of intfdata + - HID: hiddev: avoid opening a disconnected device + - HID: hiddev: do cleanup in failure of opening a device + - Input: kbtab - sanity check for endpoint type + - Input: iforce - add sanity checks + - net: usb: pegasus: fix improper read if get_registers() fail + - netfilter: ebtables: also count base chain policies + - riscv: Make __fstate_clean() work correctly. + - clk: at91: generated: Truncate divisor to GENERATED_MAX_DIV + 1 + - clk: sprd: Select REGMAP_MMIO to avoid compile errors + - clk: renesas: cpg-mssr: Fix reset control race condition + - xen/pciback: remove set but not used variable 'old_state' + - irqchip/gic-v3-its: Free unused vpt_page when alloc vpe table fail + - irqchip/irq-imx-gpcv2: Forward irq type to parent + - perf header: Fix divide by zero error if f_header.attr_size==0 + - perf header: Fix use of unitialized value warning + - libata: zpodd: Fix small read overflow in zpodd_get_mech_type() + - drm/bridge: lvds-encoder: Fix build error while CONFIG_DRM_KMS_HELPER=m + - Btrfs: fix deadlock between fiemap and transaction commits + - scsi: hpsa: correct scsi command status issue after reset + - scsi: qla2xxx: Fix possible fcport null-pointer dereferences + - drm/amdgpu: fix a potential information leaking bug + - ata: libahci: do not complain in case of deferred probe + - kbuild: modpost: handle KBUILD_EXTRA_SYMBOLS only for external modules + - kbuild: Check for unknown options with cc-option usage in Kconfig and clang + - arm64/efi: fix variable 'si' set but not used + - arm64: unwind: Prohibit probing on return_address() + - arm64/mm: fix variable 'pud' set but not used + - IB/core: Add mitigation for Spectre V1 + - IB/mlx5: Fix MR registration flow to use UMR properly + - IB/mad: Fix use-after-free in ib mad completion handling + - drm: msm: Fix add_gpu_components + - drm/exynos: fix missing decrement of retry counter + - Revert "kmemleak: allow to coexist with fault injection" + - ocfs2: remove set but not used variable 'last_hash' + - asm-generic: fix -Wtype-limits compiler warnings + - arm64: KVM: regmap: Fix unexpected switch fall-through + - staging: comedi: dt3000: Fix signed integer overflow 'divider * base' + - staging: comedi: dt3000: Fix rounding up of timer divisor + - iio: adc: max9611: Fix temperature reading in probe + - USB: core: Fix races in character device registration and deregistraion + - usb: gadget: udc: renesas_usb3: Fix sysfs interface of "role" + - usb: cdc-acm: make sure a refcount is taken early enough + - USB: CDC: fix sanity checks in CDC union parser + - USB: serial: option: add D-Link DWM-222 device ID + - USB: serial: option: Add support for ZTE MF871A + - USB: serial: option: add the BroadMobi BM818 card + - USB: serial: option: Add Motorola modem UARTs + - arm64: ftrace: Ensure module ftrace trampoline is coherent with I-side + - netfilter: conntrack: Use consistent ct id hash calculation + - Input: psmouse - fix build error of multiple definition + - bnx2x: Fix VF's VLAN reconfiguration in reload. + - bonding: Add vlan tx offload to hw_enc_features + - net: dsa: Check existence of .port_mdb_add callback before calling it + - net/mlx4_en: fix a memory leak bug + - net/packet: fix race in tpacket_snd() + - sctp: fix memleak in sctp_send_reset_streams + - sctp: fix the transport error_count check + - team: Add vlan tx offload to hw_enc_features + - tipc: initialise addr_trail_end when setting node addresses + - xen/netback: Reset nr_frags before freeing skb + - net/mlx5e: Only support tx/rx pause setting for port owner + - net/mlx5e: Use flow keys dissector to parse packets for ARFS + - mm/z3fold.c: fix z3fold_destroy_pool() ordering + - mm, vmscan: do not special-case slab reclaim when watermarks are boosted + - drm/amdgpu: fix gfx9 soft recovery + - riscv: Correct the initialized flow of FP register + - blk-mq: move cancel of requeue_work to the front of blk_exit_queue + - IB/mlx5: Replace kfree with kvfree + - dma-mapping: check pfn validity in dma_common_{mmap,get_sgtable} + - f2fs: fix to read source block before invalidating it + - tools perf beauty: Fix usbdevfs_ioctl table generator to handle _IOC() + - ALSA: pcm: fix lost wakeup event scenarios in snd_pcm_drain + - drm/bridge: tc358764: Fix build error + - tracing: Fix header include guards in trace event headers + - drm/amdkfd: Fix byte align on VegaM + - RDMA/restrack: Track driver QP types in resource tracker + - RDMA/mlx5: Release locks during notifier unregister + - arm64: kprobes: Recover pstate.D in single-step exception handler + - arm64: Make debug exception handlers visible from RCU + - page flags: prioritize kasan bits over last-cpuid + - bnxt_en: Fix VNIC clearing logic for 57500 chips. + - bnxt_en: Improve RX doorbell sequence. + - bnxt_en: Fix handling FRAG_ERR when NVM_INSTALL_UPDATE cmd fails + - bnxt_en: Suppress HWRM errors for HWRM_NVM_GET_VARIABLE command + - bnxt_en: Use correct src_fid to determine direction of the flow + - bnxt_en: Fix to include flow direction in L2 key + - net sched: update skbedit action for batched events operations + - tc-testing: updated skbedit action tests with batch create/delete + * Disco update: upstream stable patchset 2019-08-27 (LP: #1841681) + - hv_sock: Add support for delayed close + - vsock: correct removal of socket from the list + - ISDN: hfcsusb: checking idx of ep configuration + - media: au0828: fix null dereference in error path + - ath10k: Change the warning message string + - media: cpia2_usb: first wake up, then free in disconnect + - media: pvrusb2: use a different format for warnings + - NFS: Cleanup if nfs_match_client is interrupted + - media: radio-raremono: change devm_k*alloc to k*alloc + - Bluetooth: hci_uart: check for missing tty operations + - sched/fair: Don't free p->numa_faults with concurrent readers + - sched/fair: Use RCU accessors consistently for ->numa_group + - /proc//cmdline: remove all the special cases + - /proc//cmdline: add back the setproctitle() special case + - drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl + - Fix allyesconfig output. + - ceph: hold i_ceph_lock when removing caps for freeing inode + - ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL + - xfrm: policy: fix bydst hlist corruption on hash rebuild + - nvme: fix multipath crash when ANA is deactivated + - ARM: riscpc: fix DMA + - ARM: dts: rockchip: Make rk3288-veyron-minnie run at hs200 + - ARM: dts: rockchip: Make rk3288-veyron-mickey's emmc work again + - ARM: dts: rockchip: Mark that the rk3288 timer might stop in suspend + - ftrace: Enable trampoline when rec count returns back to one + - dmaengine: tegra-apb: Error out if DMA_PREP_INTERRUPT flag is unset + - arm64: dts: rockchip: fix isp iommu clocks and power domain + - kernel/module.c: Only return -EEXIST for modules that have finished loading + - firmware/psci: psci_checker: Park kthreads before stopping them + - MIPS: lantiq: Fix bitfield masking + - dmaengine: rcar-dmac: Reject zero-length slave DMA requests + - clk: tegra210: fix PLLU and PLLU_OUT1 + - fs/adfs: super: fix use-after-free bug + - clk: sprd: Add check for return value of sprd_clk_regmap_init() + - btrfs: fix minimum number of chunk errors for DUP + - btrfs: qgroup: Don't hold qgroup_ioctl_lock in btrfs_qgroup_inherit() + - cifs: Fix a race condition with cifs_echo_request + - ceph: fix improper use of smp_mb__before_atomic() + - ceph: return -ERANGE if virtual xattr value didn't fit in buffer + - ACPI: blacklist: fix clang warning for unused DMI table + - scsi: zfcp: fix GCC compiler warning emitted with -Wmaybe-uninitialized + - perf version: Fix segfault due to missing OPT_END() + - x86: kvm: avoid constant-conversion warning + - ACPI: fix false-positive -Wuninitialized warning + - be2net: Signal that the device cannot transmit during reconfiguration + - x86/apic: Silence -Wtype-limits compiler warnings + - x86: math-emu: Hide clang warnings for 16-bit overflow + - mm/cma.c: fail if fixed declaration can't be honored + - lib/test_overflow.c: avoid tainting the kernel and fix wrap size + - lib/test_string.c: avoid masking memset16/32/64 failures + - coda: add error handling for fget + - coda: fix build using bare-metal toolchain + - uapi linux/coda_psdev.h: move upc_req definition from uapi to kernel side + headers + - drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings + - ipc/mqueue.c: only perform resource calculation if user valid + - xen/pv: Fix a boot up hang revealed by int3 self test + - x86/kvm: Don't call kvm_spurious_fault() from .fixup + - x86/paravirt: Fix callee-saved function ELF sizes + - x86, boot: Remove multiple copy of static function sanitize_boot_params() + - drm/nouveau: fix memory leak in nouveau_conn_reset() + - kconfig: Clear "written" flag to avoid data loss + - kbuild: initialize CLANG_FLAGS correctly in the top Makefile + - Btrfs: fix incremental send failure after deduplication + - Btrfs: fix race leading to fs corruption after transaction abort + - mmc: dw_mmc: Fix occasional hang after tuning on eMMC + - mmc: meson-mx-sdio: Fix misuse of GENMASK macro + - gpiolib: fix incorrect IRQ requesting of an active-low lineevent + - IB/hfi1: Fix Spectre v1 vulnerability + - mtd: rawnand: micron: handle on-die "ECC-off" devices correctly + - selinux: fix memory leak in policydb_init() + - ALSA: hda: Fix 1-minute detection delay when i915 module is not available + - mm: vmscan: check if mem cgroup is disabled or not before calling memcg slab + shrinker + - s390/dasd: fix endless loop after read unit address configuration + - cgroup: kselftest: relax fs_spec checks + - parisc: Fix build of compressed kernel even with debug enabled + - drivers/perf: arm_pmu: Fix failure path in PM notifier + - arm64: compat: Allow single-byte watchpoints on all addresses + - arm64: cpufeature: Fix feature comparison for CTR_EL0.{CWG,ERG} + - nbd: replace kill_bdev() with __invalidate_device() again + - xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() + - IB/mlx5: Fix unreg_umr to ignore the mkey state + - IB/mlx5: Use direct mkey destroy command upon UMR unreg failure + - IB/mlx5: Move MRs to a kernel PD when freeing them to the MR cache + - IB/mlx5: Fix clean_mr() to work in the expected order + - IB/mlx5: Fix RSS Toeplitz setup to be aligned with the HW specification + - IB/hfi1: Check for error on call to alloc_rsm_map_table + - drm/i915/gvt: fix incorrect cache entry for guest page mapping + - eeprom: at24: make spd world-readable again + - gcc-9: properly declare the {pv,hv}clock_page storage + - scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA + - Documentation: Add swapgs description to the Spectre v1 documentation + - arm64: dts: marvell: mcbin: enlarge PCI memory window + - PCI: OF: Initialize dev->fwnode appropriately + - arm64: qcom: qcs404: Add reset-cells to GCC node + - swiotlb: fix phys_addr_t overflow warning + - arm64: dts: rockchip: Fix USB3 Type-C on rk3399-sapphire + - btrfs: Flush before reflinking any extent to prevent NOCOW write falling + back to COW without data reservation + - virtio-mmio: add error check for platform_get_irq + - cifs: fix crash in cifs_dfs_do_automount + - KVM: nVMX: Ignore segment base for VMX memory operand when segment not FS or + GS + - bpf: fix BTF verifier size resolution logic + - mm/slab_common.c: work around clang bug #42570 + - mm/ioremap: check virtual address alignment while creating huge mappings + - nds32: fix asm/syscall.h + - mm/hotplug: make remove_memory() interface usable + - crypto: ccp - Fix SEV_VERSION_GREATER_OR_EQUAL + - bpf: Disable GCC -fgcse optimization for ___bpf_prog_run() + - kbuild: modpost: include .*.cmd files only when targets exist + - dax: Fix missed wakeup in put_unlocked_entry() + - fgraph: Remove redundant ftrace_graph_notrace_addr() test + - mmc: host: sdhci-sprd: Fix the missing pm_runtime_put_noidle() + - mmc: mmc_spi: Enable stable writes + - gpiolib: Preserve desc->flags when setting state + - gpio: don't WARN() on NULL descs if gpiolib is disabled + - i2c: at91: disable TXRDY interrupt after sending data + - i2c: at91: fix clk_offset for sama5d2 + - mm: migrate: fix reference check race between __find_get_block() and + migration + - mm/migrate.c: initialize pud_entry in migrate_vma() + - parisc: Add archclean Makefile target + - parisc: Strip debug info from kernel before creating compressed vmlinuz + - RDMA/bnxt_re: Honor vlan_id in GID entry comparison + - drm/i915/perf: fix ICL perf register offsets + * Disco update: upstream stable patchset 2019-08-22 (LP: #1841121) + - hvsock: fix epollout hang from race condition + - drm/panel: simple: Fix panel_simple_dsi_probe + - iio: adc: stm32-dfsdm: manage the get_irq error case + - iio: adc: stm32-dfsdm: missing error case during probe + - staging: vt6656: use meaningful error code during buffer allocation + - usb: core: hub: Disable hub-initiated U1/U2 + - tty: max310x: Fix invalid baudrate divisors calculator + - pinctrl: rockchip: fix leaked of_node references + - tty: serial: cpm_uart - fix init when SMC is relocated + - drm/amd/display: Fill prescale_params->scale for RGB565 + - drm/amdgpu/sriov: Need to initialize the HDP_NONSURFACE_BAStE + - drm/amd/display: Disable ABM before destroy ABM struct + - drm/amdkfd: Fix a potential memory leak + - drm/amdkfd: Fix sdma queue map issue + - drm/edid: Fix a missing-check bug in drm_load_edid_firmware() + - PCI: Return error if cannot probe VF + - drm/bridge: tc358767: read display_props in get_modes() + - drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz + - gpu: host1x: Increase maximum DMA segment size + - drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry + - drm/crc-debugfs: Also sprinkle irqrestore over early exits + - memstick: Fix error cleanup path of memstick_init + - tty/serial: digicolor: Fix digicolor-usart already registered warning + - tty: serial: msm_serial: avoid system lockup condition + - serial: 8250: Fix TX interrupt handling condition + - drm/amd/display: Always allocate initial connector state state + - drm/virtio: Add memory barriers for capset cache. + - phy: renesas: rcar-gen2: Fix memory leak at error paths + - drm/amd/display: fix compilation error + - powerpc/pseries/mobility: prevent cpu hotplug during DT update + - drm/rockchip: Properly adjust to a true clock in adjusted_mode + - serial: imx: fix locking in set_termios() + - tty: serial_core: Set port active bit in uart_port_activate + - usb: gadget: Zero ffs_io_data + - mmc: sdhci: sdhci-pci-o2micro: Check if controller supports 8-bit width + - powerpc/pci/of: Fix OF flags parsing for 64bit BARs + - drm/msm: Depopulate platform on probe failure + - serial: mctrl_gpio: Check if GPIO property exisits before requesting it + - PCI: sysfs: Ignore lockdep for remove attribute + - i2c: stm32f7: fix the get_irq error cases + - kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS + - genksyms: Teach parser about 128-bit built-in types + - PCI: xilinx-nwl: Fix Multi MSI data programming + - iio: iio-utils: Fix possible incorrect mask calculation + - powerpc/cacheflush: fix variable set but not used + - powerpc/xmon: Fix disabling tracing while in xmon + - recordmcount: Fix spurious mcount entries on powerpc + - mfd: madera: Add missing of table registration + - mfd: core: Set fwnode for created devices + - mfd: arizona: Fix undefined behavior + - mfd: hi655x-pmic: Fix missing return value check for + devm_regmap_init_mmio_clk + - mm/swap: fix release_pages() when releasing devmap pages + - um: Silence lockdep complaint about mmap_sem + - powerpc/4xx/uic: clear pending interrupt after irq type/pol change + - RDMA/i40iw: Set queue pair state when being queried + - serial: sh-sci: Terminate TX DMA during buffer flushing + - serial: sh-sci: Fix TX DMA buffer flushing and workqueue races + - IB/mlx5: Fixed reporting counters on 2nd port for Dual port RoCE + - powerpc/mm: Handle page table allocation failures + - IB/ipoib: Add child to parent list only if device initialized + - arm64: assembler: Switch ESB-instruction with a vanilla nop if + !ARM64_HAS_RAS + - PCI: mobiveil: Fix PCI base address in MEM/IO outbound windows + - PCI: mobiveil: Fix the Class Code field + - kallsyms: exclude kasan local symbols on s390 + - PCI: mobiveil: Initialize Primary/Secondary/Subordinate bus numbers + - PCI: mobiveil: Use the 1st inbound window for MEM inbound transactions + - perf test mmap-thread-lookup: Initialize variable to suppress memory + sanitizer warning + - perf stat: Fix use-after-freed pointer detected by the smatch tool + - perf top: Fix potential NULL pointer dereference detected by the smatch tool + - perf session: Fix potential NULL pointer dereference found by the smatch + tool + - perf annotate: Fix dereferencing freed memory found by the smatch tool + - perf hists browser: Fix potential NULL pointer dereference found by the + smatch tool + - RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM + - PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB + - powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h + - block: init flush rq ref count to 1 + - f2fs: avoid out-of-range memory access + - mailbox: handle failed named mailbox channel request + - dlm: check if workqueues are NULL before flushing/destroying + - powerpc/eeh: Handle hugepages in ioremap space + - block/bio-integrity: fix a memory leak bug + - sh: prevent warnings when using iounmap + - mm/kmemleak.c: fix check for softirq context + - 9p: pass the correct prototype to read_cache_page + - mm/gup.c: mark undo_dev_pagemap as __maybe_unused + - mm/gup.c: remove some BUG_ONs from get_gate_page() + - memcg, fsnotify: no oom-kill for remote memcg charging + - mm/mmu_notifier: use hlist_add_head_rcu() + - proc: use down_read_killable mmap_sem for /proc/pid/smaps_rollup + - proc: use down_read_killable mmap_sem for /proc/pid/pagemap + - proc: use down_read_killable mmap_sem for /proc/pid/clear_refs + - proc: use down_read_killable mmap_sem for /proc/pid/map_files + - cxgb4: reduce kernel stack usage in cudbg_collect_mem_region() + - proc: use down_read_killable mmap_sem for /proc/pid/maps + - locking/lockdep: Fix lock used or unused stats error + - mm: use down_read_killable for locking mmap_sem in access_remote_vm + - locking/lockdep: Hide unused 'class' variable + - usb: wusbcore: fix unbalanced get/put cluster_id + - usb: pci-quirks: Correct AMD PLL quirk detection + - btrfs: inode: Don't compress if NODATASUM or NODATACOW set + - x86/sysfb_efi: Add quirks for some devices with swapped width and height + - x86/speculation/mds: Apply more accurate check on hypervisor platform + - binder: prevent transactions to context manager from its own process. + - fpga-manager: altera-ps-spi: Fix build error + - mei: me: add mule creek canyon (EHL) device ids + - hpet: Fix division by zero in hpet_time_div() + - ALSA: ac97: Fix double free of ac97_codec_device + - powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask() + - libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl() + - access: avoid the RCU grace period for the temporary subjective credentials + - regulator: 88pm800: fix warning same module names + - media: drivers: media: coda: fix warning same module names + - btrfs: shut up bogus -Wmaybe-uninitialized warning + - drm/virtio: set seqno for dma-fence + - ipmi_si: fix unexpected driver unregister warning + - drm/bochs: Fix connector leak during driver unload + - drm/msm/a6xx: Check for ERR or NULL before iounmap + - ipmi:ssif: Only unregister the platform driver if it was registered + - ipmi_ssif: fix unexpected driver unregister warning + - drm/amd/display: Disable cursor when offscreen in negative direction + - drm/amdgpu: Reserve shared fence for eviction fence + - f2fs: fix to avoid deadloop if data_flush is on + - tools: PCI: Fix broken pcitest compilation + - drm/amd/display: Increase Backlight Gain Step Size + - f2fs: Fix accounting for unusable blocks + - f2fs: Lower threshold for disable_cp_again + - drm/vkms: Forward timer right after drm_crtc_handle_vblank + - i2c: nvidia-gpu: resume ccgx i2c client + - PCI: endpoint: Allocate enough space for fixed size BAR + - dma-remap: Avoid de-referencing NULL atomic_pool + - platform/x86: asus-wmi: Increase input buffer size of WMI methods + - iio: adxl372: fix iio_triggered_buffer_{pre,post}enable positions + - serial: uartps: Use the same dynamic major number for all ports + - kvm: vmx: fix limit checking in get_vmx_mem_address() + - KVM: nVMX: Intercept VMWRITEs to GUEST_{CS,SS}_AR_BYTES + - kvm: vmx: segment limit check: use access length + - powerpc/rtas: retry when cpu offline races with suspend/migration + - fixdep: check return value of printf() and putchar() + - KVM: nVMX: Stash L1's CR3 in vmcs01.GUEST_CR3 on nested entry w/o EPT + - perf trace: Fix potential NULL pointer dereference found by the smatch tool + - perf map: Fix potential NULL pointer dereference found by smatch tool + - perf intel-bts: Fix potential NULL pointer dereference found by the smatch + tool + - RDMA/core: Fix race when resolving IP address + - nvme-pci: check for NULL return from pci_alloc_p2pmem() + - nvme-pci: limit max_hw_sectors based on the DMA max mapping size + - nvme-tcp: don't use sendpage for SLAB pages + - nvme-tcp: set the STABLE_WRITES flag when data digests are enabled + - powerpc/irq: Don't WARN continuously in arch_local_irq_restore() + - nvme: fix NULL deref for fabrics options + - mm/mincore.c: fix race between swapoff and mincore + - mm, swap: fix race between swapoff and some swap operations + - usb-storage: Add a limitation for blk_queue_max_hw_sectors() + - KVM: PPC: Book3S HV: Always save guest pmu for guest capable of nesting + - KVM: PPC: Book3S HV: Save and restore guest visible PSSCR bits on pseries + - selinux: check sidtab limit before adding a new entry + - x86/stacktrace: Prevent access_ok() warnings in arch_stack_walk_user() + - eeprom: make older eeprom drivers select NVMEM_SYSFS + - drm/panel: Add support for Armadeus ST0700 Adapt + - ALSA: hda - Fix intermittent CORB/RIRB stall on Intel chips + - powerpc/mm: Limit rma_size to 1TB when running without HV mode + - powerpc/pmu: Set pmcregs_in_use in paca when running as LPAR + - iommu/vt-d: Don't queue_iova() if there is no flush queue + - iommu/iova: Remove stale cached32_node + - iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA + - libnvdimm/region: Register badblocks before namespaces + * Line 6 POD HD500 driver fault (LP: #1790595) // Disco update: upstream + stable patchset 2019-08-22 (LP: #1841121) + - ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1 + * Disco update: upstream stable patchset 2019-08-21 (LP: #1840961) + - bnx2x: Prevent load reordering in tx completion processing + - caif-hsi: fix possible deadlock in cfhsi_exit_module() + - hv_netvsc: Fix extra rcu_read_unlock in netvsc_recv_callback() + - igmp: fix memory leak in igmpv3_del_delrec() + - ipv4: don't set IPv6 only flags to IPv4 addresses + - ipv6: rt6_check should return NULL if 'from' is NULL + - ipv6: Unlink sibling route in case of failure + - net: bcmgenet: use promisc for unsupported filters + - net: dsa: mv88e6xxx: wait after reset deactivation + - net: make skb_dst_force return true when dst is refcounted + - net: neigh: fix multiple neigh timer scheduling + - net: openvswitch: fix csum updates for MPLS actions + - net: phy: sfp: hwmon: Fix scaling of RX power + - net: stmmac: Re-work the queue selection for TSO packets + - nfc: fix potential illegal memory access + - r8169: fix issue with confused RX unit after PHY power-down on RTL8411b + - rxrpc: Fix send on a connected, but unbound socket + - sctp: fix error handling on stream scheduler initialization + - sky2: Disable MSI on ASUS P6T + - tcp: be more careful in tcp_fragment() + - tcp: fix tcp_set_congestion_control() use from bpf hook + - tcp: Reset bytes_acked and bytes_received when disconnecting + - vrf: make sure skb->data contains ip header to make routing + - net/mlx5e: IPoIB, Add error path in mlx5_rdma_setup_rn + - macsec: fix use-after-free of skb during RX + - macsec: fix checksumming after decryption + - netrom: fix a memory leak in nr_rx_frame() + - netrom: hold sock when setting skb->destructor + - net_sched: unset TCQ_F_CAN_BYPASS when adding filters + - net/tls: make sure offload also gets the keys wiped + - sctp: not bind the socket in sctp_connect + - net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling + - net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query + - net: bridge: don't cache ether dest pointer on input + - net: bridge: stp: don't cache eth dest pointer before skb pull + - dma-buf: balance refcount inbalance + - dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc + - gpio: davinci: silence error prints in case of EPROBE_DEFER + - MIPS: lb60: Fix pin mappings + - perf/core: Fix exclusive events' grouping + - perf/core: Fix race between close() and fork() + - ext4: don't allow any modifications to an immutable file + - ext4: enforce the immutable flag on open files + - mm: add filemap_fdatawait_range_keep_errors() + - jbd2: introduce jbd2_inode dirty range scoping + - ext4: use jbd2_inode dirty range scoping + - ext4: allow directory holes + - KVM: nVMX: do not use dangling shadow VMCS after guest reset + - KVM: nVMX: Clear pending KVM_REQ_GET_VMCS12_PAGES when leaving nested + - mm: vmscan: scan anonymous pages on file refaults + - net: sched: verify that q!=NULL before setting q->flags + - selftests: txring_overwrite: fix incorrect test of mmap() return value + - net/tls: reject offload of TLS 1.3 + - net/mlx5e: Rx, Fix checksum calculation for new hardware + - gpiolib: of: fix a memory leak in of_gpio_flags_quirks() + - sd_zbc: Fix report zones buffer allocation + - block: Limit zone array allocation size + - bnxt_en: Fix VNIC accounting when enabling aRFS on 57500 chips. + - mlxsw: spectrum_dcb: Configure DSCP map as the last rule is removed + - mlxsw: spectrum: Do not process learned records with a dummy FID + - Revert "kvm: x86: Use task structs fpu field for user" + * Disco update: upstream stable patchset 2019-08-19 (LP: #1840718) + - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections + - Bluetooth: Fix regression with minimum encryption key size alignment + - Bluetooth: Fix faulty expression for minimum encryption key size check + - netfilter: nf_flow_table: ignore DF bit setting + - netfilter: nft_flow_offload: set liberal tracking mode for tcp + - netfilter: nft_flow_offload: don't offload when sequence numbers need + adjustment + - netfilter: nft_flow_offload: IPCB is only valid for ipv4 family + - ASoC : cs4265 : readable register too low + - ASoC: ak4458: add return value for ak4458_probe + - ASoC: soc-pcm: BE dai needs prepare when pause release after resume + - ASoC: ak4458: rstn_control - return a non-zero on error only + - spi: bitbang: Fix NULL pointer dereference in spi_unregister_master + - drm/mediatek: fix unbind functions + - drm/mediatek: unbind components in mtk_drm_unbind() + - drm/mediatek: call drm_atomic_helper_shutdown() when unbinding driver + - drm/mediatek: clear num_pipes when unbind driver + - drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() + - ASoC: max98090: remove 24-bit format support if RJ is 0 + - ASoC: sun4i-i2s: Fix sun8i tx channel offset mask + - ASoC: sun4i-i2s: Add offset to RX channel select + - x86/CPU: Add more Icelake model numbers + - usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i] + - usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC + - ALSA: hdac: fix memory release for SST and SOF drivers + - SoC: rt274: Fix internal jack assignment in set_jack callback + - scsi: hpsa: correct ioaccel2 chaining + - drm: panel-orientation-quirks: Add quirk for GPD pocket2 + - drm: panel-orientation-quirks: Add quirk for GPD MicroPC + - platform/x86: intel-vbtn: Report switch events when event wakes device + - platform/x86: mlx-platform: Fix parent device in i2c-mux-reg device + registration + - platform/mellanox: mlxreg-hotplug: Add devm_free_irq call to remove flow + - i2c: pca-platform: Fix GPIO lookup code + - cpuset: restore sanity to cpuset_cpus_allowed_fallback() + - scripts/decode_stacktrace.sh: prefix addr2line with $CROSS_COMPILE + - mm/mlock.c: change count_mm_mlocked_page_nr return type + - tracing: avoid build warning with HAVE_NOP_MCOUNT + - module: Fix livepatch/ftrace module text permissions race + - ftrace: Fix NULL pointer dereference in free_ftrace_func_mapper() + - crypto: user - prevent operating on larval algorithms + - crypto: cryptd - Fix skcipher instance memory leak + - ALSA: seq: fix incorrect order of dest_client/dest_ports arguments + - ALSA: firewire-lib/fireworks: fix miss detection of received MIDI messages + - ALSA: line6: Fix write on zero-sized buffer + - ALSA: usb-audio: fix sign unintended sign extension on left shifts + - ALSA: hda/realtek: Add quirks for several Clevo notebook barebones + - ALSA: hda/realtek - Change front mic location for Lenovo M710q + - lib/mpi: Fix karactx leak in mpi_powm + - fs/userfaultfd.c: disable irqs for fault_pending and event locks + - tracing/snapshot: Resize spare buffer if size changed + - ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node + - arm64: kaslr: keep modules inside module region when KASAN is enabled + - drm/amd/powerplay: use hardware fan control if no powerplay fan table + - drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE + - drm/etnaviv: add missing failure path to destroy suballoc + - drm/imx: notify drm core before sending event during crtc disable + - drm/imx: only send event on crtc disable if kept disabled + - ftrace/x86: Remove possible deadlock between register_kprobe() and + ftrace_run_update_code() + - mm/vmscan.c: prevent useless kswapd loops + - btrfs: Ensure replaced device doesn't have pending chunk allocation + - tty: rocket: fix incorrect forward declaration of 'rp_init()' + - net/smc: move unhash before release of clcsock + - media: s5p-mfc: fix incorrect bus assignment in virtual child device + - drm/fb-helper: generic: Don't take module ref for fbcon + - f2fs: don't access node/meta inode mapping after iput + - ALSA: hda: Initialize power_state field properly + - ip6: fix skb leak in ip6frag_expire_frag_queue() + - net: IP defrag: encapsulate rbtree defrag code into callable functions + - net: IP6 defrag: use rbtrees for IPv6 defrag + - net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c + - netfilter: ipv6: nf_defrag: fix leakage of unqueued fragments + - sc16is7xx: move label 'err_spi' to correct section + - netfilter: ipv6: nf_defrag: accept duplicate fragments again + - KVM: x86: degrade WARN to pr_warn_ratelimited + - KVM: LAPIC: Fix pending interrupt in IRR blocked by software disable LAPIC + - nfsd: Fix overflow causing non-working mounts on 1 TB machines + - svcrdma: Ignore source port when computing DRC hash + - MIPS: Fix bounds check virt_addr_valid + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence. + - MIPS: have "plain" make calls build dtbs for selected platforms + - dmaengine: qcom: bam_dma: Fix completed descriptors count + - dmaengine: imx-sdma: remove BD_INTR for channel0 + - signal: remove the wrong signal_pending() check in restore_user_sigmask() + - idr: Fix idr_get_next race with idr_remove + - ASoC: core: lock client_mutex while removing link components + - iommu/vt-d: Set the right field for Page Walk Snoop + - HID: a4tech: fix horizontal scrolling + - ASoC: hda: fix unbalanced codec dev refcount for HDA_DEV_ASOC + - gpio: pca953x: hack to fix 24 bit gpio expanders + - ASoC: Intel: sst: fix kmalloc call with wrong flags + - arm64: tlbflush: Ensure start/end of address range are aligned to stride + - dax: Fix xarray entry association for mixed mappings + - swap_readpage(): avoid blk_wake_io_task() if !synchronous + - drm/virtio: move drm_connector_update_edid_property() call + - s390/mm: fix pxd_bad with folded page tables + - dmaengine: jz4780: Fix an endian bug in IRQ handler + - scsi: target/iblock: Fix overrun in WRITE SAME emulation + - crypto: talitos - rename alternative AEAD algos. + - soc: brcmstb: Fix error path for unsupported CPUs + - soc: bcm: brcmstb: biuctrl: Register writes require a barrier + - samples, bpf: fix to change the buffer size for read() + - samples, bpf: suppress compiler warning + - mac80211: fix rate reporting inside cfg80211_calculate_bitrate_he() + - bpf: sockmap, fix use after free from sleep in psock backlog workqueue + - soundwire: stream: fix out of boundary access on port properties + - staging:iio:ad7150: fix threshold mode config bit + - mac80211: mesh: fix RCU warning + - mac80211: free peer keys before vif down in mesh + - iwlwifi: Fix double-free problems in iwl_req_fw_callback() + - soundwire: intel: set dai min and max channels correctly + - dt-bindings: can: mcp251x: add mcp25625 support + - can: mcp251x: add support for mcp25625 + - can: m_can: implement errata "Needless activation of MRAF irq" + - can: af_can: Fix error path of can_init() + - ibmvnic: Do not close unopened driver during reset + - ibmvnic: Refresh device multicast list after reset + - ibmvnic: Fix unchecked return codes of memory allocations + - ARM: dts: am335x phytec boards: Fix cd-gpios active level + - s390/boot: disable address-of-packed-member warning + - drm/vmwgfx: Honor the sg list segment size limitation + - drm/vmwgfx: fix a warning due to missing dma_parms + - riscv: Fix udelay in RV32. + - Input: imx_keypad - make sure keyboard can always wake up system + - KVM: arm/arm64: vgic: Fix kvm_device leak in vgic_its_destroy + - mlxsw: spectrum: Disallow prio-tagged packets when PVID is removed + - ARM: davinci: da850-evm: call regulator_has_full_constraints() + - ARM: davinci: da8xx: specify dma_coherent_mask for lcdc + - mac80211: only warn once on chanctx_conf being NULL + - mac80211: do not start any work during reconfigure flow + - bpf, devmap: Fix premature entry free on destroying map + - bpf, devmap: Add missing bulk queue free + - bpf, devmap: Add missing RCU read lock on flush + - bpf, x64: fix stack layout of JITed bpf code + - qmi_wwan: add support for QMAP padding in the RX path + - qmi_wwan: avoid RCU stalls on device disconnect when in QMAP mode + - qmi_wwan: extend permitted QMAP mux_id value range + - mmc: core: complete HS400 before checking status + - md: fix for divide error in status_resync + - bnx2x: Check if transceiver implements DDM before access + - drm: return -EFAULT if copy_to_user() fails + - ip6_tunnel: allow not to count pkts on tstats by passing dev as NULL + - net: lio_core: fix potential sign-extension overflow on large shift + - scsi: qedi: Check targetname while finding boot target information + - quota: fix a problem about transfer quota + - net: dsa: mv88e6xxx: fix shift of FID bits in mv88e6185_g1_vtu_loadpurge() + - NFS4: Only set creation opendata if O_CREAT + - net :sunrpc :clnt :Fix xps refcount imbalance on the error path + - fscrypt: don't set policy for a dead directory + - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + - media: stv0297: fix frequency range limit + - ALSA: usb-audio: Fix parse of UAC2 Extension Units + - ALSA: hda/realtek - Headphone Mic can't record after S3 + - block, bfq: NULL out the bic when it's no longer valid + - perf pmu: Fix uncore PMU alias list for ARM64 + - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + - x86/tls: Fix possible spectre-v1 in do_get_thread_area() + - Documentation: Add section about CPU vulnerabilities for Spectre + - Documentation/admin: Remove the vsyscall=native documentation + - mwifiex: Abort at too short BSS descriptor element + - mwifiex: Don't abort on small, spec-compliant vendor IEs + - USB: serial: ftdi_sio: add ID for isodebug v1 + - USB: serial: option: add support for GosunCn ME3630 RNDIS mode + - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled" + - p54usb: Fix race between disconnect and firmware loading + - usb: gadget: ether: Fix race between gether_disconnect and rx_submit + - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset() + - usb: renesas_usbhs: add a workaround for a race condition of workqueue + - drivers/usb/typec/tps6598x.c: fix portinfo width + - drivers/usb/typec/tps6598x.c: fix 4CC cmd write + - staging: comedi: dt282x: fix a null pointer deref on interrupt + - staging: comedi: amplc_pci230: fix null pointer deref on interrupt + - HID: Add another Primax PIXART OEM mouse quirk + - lkdtm: support llvm-objcopy + - binder: fix memory leak in error path + - carl9170: fix misuse of device driver API + - VMCI: Fix integer overflow in VMCI handle arrays + - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work + - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex + - staging: bcm2835-camera: Ensure all buffers are returned on disable + - staging: bcm2835-camera: Remove check of the number of buffers supplied + - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming + - staging: rtl8712: reduce stack usage, again + - crypto: lrw - use correct alignmask + - bpf: sockmap, restore sk_write_space when psock gets dropped + - ARM: dts: Drop bogus CLKSEL for timer12 on dra7 + - iwlwifi: fix load in rfkill flow for unified firmware + - tools: bpftool: Fix JSON output when lookup fails + - soundwire: stream: fix bad unlock balance + - can: flexcan: Remove unneeded registration message + - RISC-V: defconfig: enable clocks, serial console + - xdp: check device pointer before clearing + - KVM: nVMX: use correct clean fields when copying from eVMCS + - gpu: ipu-v3: image-convert: Fix input bytesperline width/height align + - gpu: ipu-v3: image-convert: Fix input bytesperline for packed formats + - gpu: ipu-v3: image-convert: Fix image downsize coefficients + - cfg80211: util: fix bit count off by one + - cfg80211: report measurement start TSF correctly + - IB/hfi1: Create inline to get extended headers + - IB/hfi1: Wakeup QPs orphaned on wait list after flush + - IB/hfi1: Handle wakeup of orphaned QPs for pio + - IB/hfi1: Handle port down properly in pio + - powerpc: enable a 30-bit ZONE_DMA for 32-bit pmac + - tpm: Actually fail on TPM errors during "get random" + - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations + - perf intel-pt: Fix itrace defaults for perf script + - perf auxtrace: Fix itrace defaults for perf script + - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation + - perf header: Assign proper ff->ph in perf_event__synthesize_features() + - usb: gadget: f_fs: data_len used before properly set + - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize() + - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro + - iio: adc: stm32-adc: add missing vdda-supply + - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()" + - staging: vchiq: revert "switch to wait_for_completion_killable" + - staging: vchiq: make wait events interruptible + * Touchpad not detecting in Linux (LP: #1825718) // Disco update: upstream + stable patchset 2019-08-19 (LP: #1840718) + - HID: i2c-hid: add iBall Aer3 to descriptor override + * Disco update: upstream stable patchset 2019-08-16 (LP: #1840521) + - arm64: Don't unconditionally add -Wno-psabi to KBUILD_CFLAGS + - Revert "x86/uaccess, ftrace: Fix ftrace_likely_update() vs. SMAP" + - qmi_wwan: Fix out-of-bounds read + - fs/proc/array.c: allow reporting eip/esp for all coredumping threads + - mm/mempolicy.c: fix an incorrect rebind node in mpol_rebind_nodemask + - fs/binfmt_flat.c: make load_flat_shared_library() work + - clk: socfpga: stratix10: fix divider entry for the emac clocks + - mm: soft-offline: return -EBUSY if set_hwpoison_free_buddy_page() fails + - mm: hugetlb: soft-offline: dissolve_free_huge_page() return zero on + !PageHuge + - dm log writes: make sure super sector log updates are written in order + - scsi: vmw_pscsi: Fix use-after-free in pvscsi_queue_lck() + - x86/speculation: Allow guests to use SSBD even if host does not + - x86/microcode: Fix the microcode load on CPU hotplug for real + - x86/resctrl: Prevent possible overrun during bitmap operations + - NFS/flexfiles: Use the correct TCP timeout for flexfiles I/O + - cpu/speculation: Warn on unsupported mitigations= parameter + - irqchip/mips-gic: Use the correct local interrupt map registers + - af_packet: Block execution of tasks waiting for transmit to complete in + AF_PACKET + - bonding: Always enable vlan tx offload + - ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop + - net/packet: fix memory leak in packet_set_ring() + - net: remove duplicate fetch in sock_getsockopt + - net: stmmac: fixed new system time seconds value calculation + - net: stmmac: set IC bit when transmitting frames with HW timestamp + - sctp: change to hold sk after auth shkey is created successfully + - team: Always enable vlan tx offload + - tipc: change to use register_pernet_device + - tipc: check msg->req data len in tipc_nl_compat_bearer_disable + - tun: wake up waitqueues after IFF_UP is set + - bpf: simplify definition of BPF_FIB_LOOKUP related flags + - bpf: lpm_trie: check left child of last leftmost node for NULL + - bpf: fix nested bpf tracepoints with per-cpu data + - bpf: fix unconnected udp hooks + - bpf: udp: Avoid calling reuseport's bpf_prog from udp_gro + - bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err + - arm64: futex: Avoid copying out uninitialised stack in failed cmpxchg() + - bpf, arm64: use more scalable stadd over ldxr / stxr loop in xadd + - futex: Update comments and docs about return values of arch futex code + - RDMA: Directly cast the sockaddr union to sockaddr + - tipc: pass tunnel dev as NULL to udp_tunnel(6)_xmit_skb + - arm64: insn: Fix ldadd instruction encoding + - clk: tegra210: Fix default rates for HDA clocks + - mm, swap: fix THP swap out + - mm: fix page cache convergence regression + - efi/memreserve: deal with memreserve entries in unmapped memory + - net: aquantia: fix vlans not working over bridged network + * Disco update: upstream stable patchset 2019-08-15 (LP: #1840373) + - tracing: Silence GCC 9 array bounds warning + - gcc-9: silence 'address-of-packed-member' warning + - ovl: support the FS_IOC_FS[SG]ETXATTR ioctls + - ovl: fix wrong flags check in FS_IOC_FS[SG]ETXATTR ioctls + - ovl: make i_ino consistent with st_ino in more cases + - ovl: detect overlapping layers + - ovl: don't fail with disconnected lower NFS + - ovl: fix bogus -Wmaybe-unitialized warning + - mmc: sdhci: sdhci-pci-o2micro: Correctly set bus width when tuning + - mmc: core: API to temporarily disable retuning for SDIO CRC errors + - mmc: core: Add sdio_retune_hold_now() and sdio_retune_release() + - mmc: core: Prevent processing SDIO IRQs when the card is suspended + - scsi: ufs: Avoid runtime suspend possibly being blocked forever + - usb: chipidea: udc: workaround for endpoint conflict issue + - xhci: detect USB 3.2 capable host controllers correctly + - usb: xhci: Don't try to recover an endpoint if port is in error state. + - IB/hfi1: Validate fault injection opcode user input + - IB/hfi1: Silence txreq allocation warnings + - iio: temperature: mlx90632 Relax the compatibility check + - Input: synaptics - enable SMBus on ThinkPad E480 and E580 + - Input: uinput - add compat ioctl number translation for UI_*_FF_UPLOAD + - Input: silead - add MSSL0017 to acpi_device_id + - apparmor: enforce nullbyte at end of tag string + - brcmfmac: sdio: Disable auto-tuning around commands expected to fail + - brcmfmac: sdio: Don't tune while the card is off + - ARC: fix build warnings + - dmaengine: dw-axi-dmac: fix null dereference when pointer first is null + - dmaengine: sprd: Fix block length overflow + - ARC: [plat-hsdk]: Add missing multicast filter bins number to GMAC node + - ARC: [plat-hsdk]: Add missing FIFO size entry in GMAC node + - fpga: dfl: afu: Pass the correct device to dma_mapping_error() + - fpga: dfl: Add lockdep classes for pdata->lock + - parport: Fix mem leak in parport_register_dev_model + - parisc: Fix compiler warnings in float emulation code + - IB/rdmavt: Fix alloc_qpn() WARN_ON() + - IB/hfi1: Insure freeze_work work_struct is canceled on shutdown + - IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value + - IB/hfi1: Validate page aligned for a given virtual address + - MIPS: uprobes: remove set but not used variable 'epc' + - xtensa: Fix section mismatch between memblock_reserve and mem_reserve + - kselftest/cgroup: fix unexpected testing failure on test_memcontrol + - kselftest/cgroup: fix unexpected testing failure on test_core + - kselftest/cgroup: fix incorrect test_core skip + - selftests: vm: install test_vmalloc.sh for run_vmtests + - net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0 + - mdesc: fix a missing-check bug in get_vdev_port_node_info() + - sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD + - net: ethernet: mediatek: Use hw_feature to judge if HWLRO is supported + - net: ethernet: mediatek: Use NET_IP_ALIGN to judge if HW RX_2BYTE_OFFSET is + enabled + - drm/arm/mali-dp: Add a loop around the second set CVAL and try 5 times + - drm/arm/hdlcd: Actually validate CRTC modes + - drm/arm/hdlcd: Allow a bit of clock tolerance + - nvmet: fix data_len to 0 for bdev-backed write_zeroes + - scripts/checkstack.pl: Fix arm64 wrong or unknown architecture + - scsi: ufs: Check that space was properly alloced in copy_query_response + - scsi: smartpqi: unlock on error in pqi_submit_raid_request_synchronous() + - net: ipvlan: Fix ipvlan device tso disabled while NETIF_F_IP_CSUM is set + - s390/qeth: fix VLAN attribute in bridge_hostnotify udev event + - hwmon: (core) add thermal sensors only if dev->of_node is present + - hwmon: (pmbus/core) Treat parameters as paged if on multiple pages + - arm64: Silence gcc warnings about arch ABI drift + - nvme: Fix u32 overflow in the number of namespace list calculation + - btrfs: start readahead also in seed devices + - can: xilinx_can: use correct bittiming_const for CAN FD core + - can: flexcan: fix timeout when set small bitrate + - can: purge socket error queue on sock destruct + - riscv: mm: synchronize MMU after pte change + - powerpc/bpf: use unsigned division instruction for 64-bit operations + - ARM: imx: cpuidle-imx6sx: Restrict the SW2ISO increase to i.MX6SX + - ARM: dts: dra76x: Update MMC2_HS200_MANUAL1 iodelay values + - ARM: dts: am57xx-idk: Remove support for voltage switching for SD card + - arm64/sve: should not depend on + - arm64: ssbd: explicitly depend on + - drm/vmwgfx: Use the backdoor port if the HB port is not available + - staging: erofs: add requirements field in superblock + - SMB3: retry on STATUS_INSUFFICIENT_RESOURCES instead of failing write + - cfg80211: fix memory leak of wiphy device name + - mac80211: drop robust management frames from unknown TA + - {nl,mac}80211: allow 4addr AP operation on crypto controlled devices + - mac80211: handle deauthentication/disassociation from TDLS peer + - nl80211: fix station_info pertid memory leak + - mac80211: Do not use stack memory with scatterlist for GMAC + - x86/resctrl: Don't stop walking closids when a locksetup group is found + - mmc: sdhi: disallow HS400 for M3-W ES1.2, RZ/G2M, and V3H + - mmc: mediatek: fix SDIO IRQ interrupt handle flow + - mmc: mediatek: fix SDIO IRQ detection issue + - cifs: fix GlobalMid_Lock bug in cifs_reconnect + - IB/hfi1: Close PSM sdma_progress sleep window + - IB/hfi1: Avoid hardlockup with flushlist_lock + - IB/hfi1: Correct tid qp rcd to match verbs context + - iio: imu: st_lsm6dsx: fix PM support for st_lsm6dsx i2c controller + - apparmor: reset pos on failure to unpack for various functions + - Revert "brcmfmac: disable command decode in sdio_aos" + - lkdtm/usercopy: Moves the KERNEL_DS test to non-canonical + - dmaengine: jz4780: Fix transfers being ACKed too soon + - dmaengine: mediatek-cqdma: sleeping in atomic context + - dmaengine: sprd: Fix the possible crash when getting descriptor status + - dmaengine: sprd: Add validation of current descriptor in irq handler + - dmaengine: sprd: Fix the incorrect start for 2-stage destination channels + - dmaengine: sprd: Fix the right place to configure 2-stage transfer + - fpga: stratix10-soc: fix use-after-free on s10_init() + - crypto: hmac - fix memory leak in hmac_init_tfm() + - userfaultfd: selftest: fix compiler warning + - selftests: set sysctl bc_forwarding properly in router_broadcast.sh + - kbuild: tar-pkg: enable communication with jobserver + - net: phylink: avoid reducing support mask + - udmabuf: actually unmap the scatterlist + - s390/qeth: handle limited IPv4 broadcast in L3 TX path + - s390/qeth: check dst entry before use + - ARM: mvebu_v7_defconfig: fix Ethernet on Clearfog + - KVM: x86/mmu: Allocate PAE root array when using SVM's 32-bit NPT + - binder: fix possible UAF when freeing buffer + - x86/vdso: Prevent segfaults due to hoisted vclock reads + * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482) + - [Config] Enable VIMC module + * reboot will introduce an alarm 'beep ...' during BIOS phase (LP: #1840395) + - ALSA: hda - Let all conexant codec enter D3 when rebooting + - ALSA: hda - Add a generic reboot_notify + * Include Sunix serial/parallel driver (LP: #1826716) + - serial: 8250_pci: Add support for Sunix serial boards + - parport: parport_serial: Add support for Sunix Multi I/O boards + * Intel HDMI audio print "Unable to sync register" errors (LP: #1840394) + - ALSA: hda - Don't resume forcibly i915 HDMI/DP codec + * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231) + - SAUCE: shiftfs: pass correct point down + * shiftfs: add O_DIRECT support (LP: #1837223) + - SAUCE: shiftfs: add O_DIRECT support + * p54usb module in linux-modules-extra-5.0.0-23-generic does not work + (LP: #1839693) + - p54: fix crash during initialization + * Goodix touchpad may drop first input event (LP: #1840075) + - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c + quirk" + - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk" + - mfd: intel-lpss: Remove D3cold delay + * NULL pointer dereference when Inserting the VIMC module (LP: #1840028) + - media: vimc: fix component match compare + * Fix touchpad IRQ storm after S3 (LP: #1841396) + - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin + * [SRU][B/OEM-B/OEM-OSP1/D] UBUNTU: SAUCE: enable middle button for one more + ThinkPad (LP: #1841722) + - SAUCE: Input: elantech - enable middle button for one more ThinkPad + * Disco update: upstream stable patchset 2019-08-13 (LP: #1840076) + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + - drm/nouveau: add kconfig option to turn off nouveau legacy contexts. (v3) + - nouveau: Fix build with CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT disabled + - HID: multitouch: handle faulty Elo touch device + - HID: wacom: Don't set tool type until we're in range + - HID: wacom: Don't report anything prior to the tool entering range + - HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact + - HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth + - HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary + - ALSA: oxfw: allow PCM capture for Stanton SCS.1m + - ALSA: hda/realtek - Update headset mode for ALC256 + - ALSA: firewire-motu: fix destruction of data for isochronous resources + - libata: Extend quirks for the ST1000LM024 drives with NOLPM quirk + - mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node + - fs/ocfs2: fix race in ocfs2_dentry_attach_lock() + - mm/vmscan.c: fix trying to reclaim unevictable LRU page + - signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO + - ptrace: restore smp_rmb() in __ptrace_may_access() + - iommu/arm-smmu: Avoid constant zero in TLBI writes + - i2c: acorn: fix i2c warning + - bcache: fix stack corruption by PRECEDING_KEY() + - cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() + - ASoC: cs42xx8: Add regcache mask dirty + - ASoC: fsl_asrc: Fix the issue about unsupported rate + - drm/i915/sdvo: Implement proper HDMI audio support for SDVO + - x86/uaccess, kcov: Disable stack protector + - ALSA: seq: Protect in-kernel ioctl calls with mutex + - ALSA: seq: Fix race of get-subscription call vs port-delete ioctls + - Revert "ALSA: seq: Protect in-kernel ioctl calls with mutex" + - s390/kasan: fix strncpy_from_user kasan checks + - Drivers: misc: fix out-of-bounds access in function param_set_kgdbts_var + - f2fs: fix to avoid accessing xattr across the boundary + - scsi: qedi: remove memset/memcpy to nfunc and use func instead + - scsi: qedi: remove set but not used variables 'cdev' and 'udev' + - scsi: lpfc: correct rcu unlock issue in lpfc_nvme_info_show + - scsi: lpfc: add check for loss of ndlp when sending RRQ + - arm64/mm: Inhibit huge-vmap with ptdump + - nvme: fix srcu locking on error return in nvme_get_ns_from_disk + - nvme: remove the ifdef around nvme_nvm_ioctl + - nvme: merge nvme_ns_ioctl into nvme_ioctl + - nvme: release namespace SRCU protection before performing controller ioctls + - nvme: fix memory leak for power latency tolerance + - platform/x86: pmc_atom: Add Lex 3I380D industrial PC to critclk_systems DMI + table + - platform/x86: pmc_atom: Add several Beckhoff Automation boards to + critclk_systems DMI table + - scsi: bnx2fc: fix incorrect cast to u64 on shift operation + - libnvdimm: Fix compilation warnings with W=1 + - selftests/timers: Add missing fflush(stdout) calls + - tracing: Prevent hist_field_var_ref() from accessing NULL tracing_map_elts + - usbnet: ipheth: fix racing condition + - KVM: arm/arm64: Move cc/it checks under hyp's Makefile to avoid + instrumentation + - KVM: x86/pmu: mask the result of rdpmc according to the width of the + counters + - KVM: x86/pmu: do not mask the value that is written to fixed PMUs + - KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION + - tools/kvm_stat: fix fields filter for child events + - drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an + invalid read + - drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define() + - usb: dwc2: Fix DMA cache alignment issues + - usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression) + - USB: Fix chipmunk-like voice when using Logitech C270 for recording audio. + - USB: serial: pl2303: add Allied Telesis VT-Kit3 + - USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode + - USB: serial: option: add Telit 0x1260 and 0x1261 compositions + - timekeeping: Repair ktime_get_coarse*() granularity + - RAS/CEC: Convert the timer callback to a workqueue + - RAS/CEC: Fix binary search function + - x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback + - x86/kasan: Fix boot with 5-level paging and KASAN + - x86/mm/KASLR: Compute the size of the vmemmap section properly + - x86/resctrl: Prevent NULL pointer dereference when local MBM is disabled + - drm/edid: abstract override/firmware EDID retrieval + - drm: add fallback override/firmware EDID modes workaround + - HID: input: make sure the wheel high resolution multiplier is set + - HID: input: fix assignment of .value + - Revert "HID: Increase maximum report size allowed by hid_field_extract()" + - selinux: fix a missing-check bug in selinux_add_mnt_opt( ) + - selinux: fix a missing-check bug in selinux_sb_eat_lsm_opts() + - media: dvb: warning about dvb frequency limits produces too much noise + - drm/amdgpu/{uvd,vcn}: fetch ring's read_ptr after alloc + - drm/i915/dsi: Use a fuzzy check for burst mode clock check + - drm/i915: Fix per-pixel alpha with CCS + - drm/i915/dmc: protect against reading random memory + - drivers/perf: arm_spe: Don't error on high-order pages for aux buf + - bpf: sockmap, only stop/flush strp if it was enabled at some point + - bpf: sockmap remove duplicate queue free + - bpf: sockmap fix msg->sg.size account on ingress skb + - scsi: qla2xxx: Add cleanup for PCI EEH recovery + - scsi: lpfc: resolve lockdep warnings + - arm64: Print physical address of page table base in show_pte() + - net: macb: fix error format in dev_err() + - bpf, tcp: correctly handle DONT_WAIT flags and timeo == 0 + - tools/bpftool: move set_max_rlimit() before __bpf_object__open_xattr() + - nvme-pci: Fix controller freeze wait disabling + - scsi: myrs: Fix uninitialized variable + - nvme-pci: use blk-mq mapping for unmanaged irqs + - KVM: nVMX: really fix the size checks on KVM_SET_NESTED_STATE + - KVM: selftests: Fix a condition in test_hv_cpuid() + - kvm: vmx: Fix -Wmissing-prototypes warnings + - KVM: LAPIC: Fix lapic_timer_advance_ns parameter overflow + - KVM: x86: do not spam dmesg with VMCS/VMCB dumps + - kvm: selftests: aarch64: dirty_log_test: fix unaligned memslot size + - kvm: selftests: aarch64: fix default vm mode + - tracing/uprobe: Fix NULL pointer dereference in trace_uprobe_create() + - powerpc: Fix kexec failure on book3s/32 + - powerpc/64s: Fix THP PMD collapse serialisation + - ax25: fix inconsistent lock state in ax25_destroy_timer + - be2net: Fix number of Rx queues used for flow hashing + - hv_netvsc: Set probe mode to sync + - ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero + - lapb: fixed leak of control-blocks. + - neigh: fix use-after-free read in pneigh_get_next + - net: dsa: rtl8366: Fix up VLAN filtering + - net: openvswitch: do not free vport if register_netdevice() is failed. + - sctp: Free cookie before we memdup a new one + - sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg + - tipc: purge deferredq list for each grp member in tipc_group_delete + - vsock/virtio: set SOCK_DONE on peer shutdown + - net/mlx5: Avoid reloading already removed devices + - net: mvpp2: prs: Fix parser range for VID filtering + - net: mvpp2: prs: Use the correct helpers when removing all VID filters + - Staging: vc04_services: Fix a couple error codes + - perf/x86/intel/ds: Fix EVENT vs. UEVENT PEBS constraints + - netfilter: nf_queue: fix reinject verdict handling + - ipvs: Fix use-after-free in ip_vs_in + - selftests: netfilter: missing error check when setting up veth interface + - clk: ti: clkctrl: Fix clkdm_clk handling + - powerpc/powernv: Return for invalid IMC domain + - usb: xhci: Fix a potential null pointer dereference in + xhci_debugfs_create_endpoint() + - mISDN: make sure device name is NUL terminated + - x86/CPU/AMD: Don't force the CPB cap when running under a hypervisor + - perf/ring_buffer: Fix exposing a temporarily decreased data_head + - perf/ring_buffer: Add ordering to rb->nest increment + - perf/ring-buffer: Always use {READ,WRITE}_ONCE() for rb->user_page data + - gpio: fix gpio-adp5588 build errors + - net: stmmac: update rx tail pointer register to fix rx dma hang issue. + - net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() + - ACPI/PCI: PM: Add missing wakeup.flags.valid checks + - drm/etnaviv: lock MMU while dumping core + - net: aquantia: tx clean budget logic error + - net: aquantia: fix LRO with FCS error + - i2c: dev: fix potential memory leak in i2cdev_ioctl_rdwr + - ALSA: hda - Force polling mode on CNL for fixing codec communication + - configfs: Fix use-after-free when accessing sd->s_dentry + - perf data: Fix 'strncat may truncate' build failure with recent gcc + - perf namespace: Protect reading thread's namespace + - perf record: Fix s390 missing module symbol and warning for non-root users + - ia64: fix build errors by exporting paddr_to_nid() + - xen/pvcalls: Remove set but not used variable + - xenbus: Avoid deadlock during suspend due to open transactions + - KVM: PPC: Book3S: Use new mutex to synchronize access to rtas token list + - KVM: PPC: Book3S HV: Don't take kvm->lock around kvm_for_each_vcpu + - arm64: fix syscall_fn_t type + - arm64: use the correct function type in SYSCALL_DEFINE0 + - arm64: use the correct function type for __arm64_sys_ni_syscall + - net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs + - net: phylink: ensure consistent phy interface mode + - net: phy: dp83867: Set up RGMII TX delay + - scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() + - scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask + - scsi: scsi_dh_alua: Fix possible null-ptr-deref + - mlxsw: spectrum: Prevent force of 56G + - ocfs2: fix error path kobject memory leak + - coredump: fix race condition between collapse_huge_page() and core dumping + - Abort file_remove_privs() for non-reg. files + - net: tls, correctly account for copied bytes with multiple sk_msgs + - vxlan: Don't assume linear buffers in error handler + - geneve: Don't assume linear buffers in error handler + - net/mlx5: Update pci error handler entries and command translation + - mlxsw: spectrum_router: Refresh nexthop neighbour when it becomes dead + - net/mlx5e: Add ndo_set_feature for uplink representor + - mlxsw: spectrum_flower: Fix TOS matching + - net/mlx5e: Support tagged tunnel over bond + - net: correct udp zerocopy refcnt also when zerocopy only on append + - net/mlx5e: Avoid detaching non-existing netdev under switchdev mode + - staging: erofs: set sb->s_root to NULL when failing from __getname() + - staging: wilc1000: Fix some double unlock bugs in wilc_wlan_cleanup() + - pinctrl: intel: Clear interrupt status in mask/unmask callback + - netfilter: nf_tables: fix oops during rule dump + - netfilter: nft_fib: Fix existence check support + - net: stmmac: dwmac-mediatek: modify csr_clk value to fix mdio read/write + fail + - dpaa2-eth: Fix potential spectre issue + - dpaa2-eth: Use PTR_ERR_OR_ZERO where appropriate + - dpaa_eth: use only online CPU portals + - dfs_cache: fix a wrong use of kfree in flush_cache_ent() + - KVM: PPC: Book3S HV: Use new mutex to synchronize MMU setup + - blk-mq: Fix memory leak in error handling + - mm: mmu_gather: remove __tlb_reset_range() for force flush + - nvme-tcp: rename function to have nvme_tcp prefix + - nvme-tcp: fix possible null deref on a timed out io queue connect + - nvme-tcp: fix queue mapping when queue count is limited + * Disco update: upstream stable patchset 2019-08-12 (LP: #1839887) + - selftests/tls: test for lowat overshoot with multiple records + - selftests/tls: add test for sleeping even though there is data + - sparc64: Fix regression in non-hypervisor TLB flush xcall + - include/linux/bitops.h: sanitize rotate primitives + - xhci: update bounce buffer with correct sg num + - xhci: Use %zu for printing size_t type + - xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() + - usb: xhci: avoid null pointer deref when bos field is NULL + - usbip: usbip_host: fix BUG: sleeping function called from invalid context + - usbip: usbip_host: fix stub_dev lock context imbalance regression + - USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor + - USB: sisusbvga: fix oops in error path of sisusb_probe + - USB: Add LPM quirk for Surface Dock GigE adapter + - USB: rio500: refuse more than one device at a time + - USB: rio500: fix memory leak in close after disconnect + - media: usb: siano: Fix general protection fault in smsusb + - media: usb: siano: Fix false-positive "uninitialized variable" warning + - media: smsusb: better handle optional alignment + - brcmfmac: fix NULL pointer derefence during USB disconnect + - scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove + - scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) + - tracing: Avoid memory leak in predicate_parse() + - Btrfs: fix wrong ctime and mtime of a directory after log replay + - Btrfs: fix race updating log root item during fsync + - Btrfs: fix fsync not persisting changed attributes of a directory + - Btrfs: incremental send, fix file corruption when no-holes feature is + enabled + - iio: dac: ds4422/ds4424 fix chip verification + - iio: adc: ti-ads8688: fix timestamp is not updated in buffer + - s390/crypto: fix possible sleep during spinlock aquired + - KVM: PPC: Book3S HV: XIVE: Do not clear IRQ data of passthrough interrupts + - powerpc/perf: Fix MMCRA corruption by bhrb_filter + - ALSA: line6: Assure canceling delayed work at disconnection + - ALSA: hda/realtek - Set default power save node to 0 + - KVM: s390: Do not report unusabled IDs via KVM_CAP_MAX_VCPU_ID + - drm/nouveau/i2c: Disable i2c bus access after ->fini() + - i2c: mlxcpld: Fix wrong initialization order in probe + - i2c: synquacer: fix synquacer_i2c_doxfer() return value + - tty: serial: msm_serial: Fix XON/XOFF + - tty: max310x: Fix external crystal register setup + - memcg: make it work on sparse non-0-node systems + - kernel/signal.c: trace_signal_deliver when signal_group_exit + - arm64: Fix the arm64_personality() syscall wrapper redirection + - docs: Fix conf.py for Sphinx 2.0 + - doc: Cope with the deprecation of AutoReporter + - doc: Cope with Sphinx logging deprecations + - ima: show rules with IMA_INMASK correctly + - evm: check hash algorithm passed to init_desc() + - vt/fbcon: deinitialize resources in visual_init() after failed memory + allocation + - serial: sh-sci: disable DMA for uart_console + - staging: vc04_services: prevent integer overflow in create_pagelist() + - staging: wlan-ng: fix adapter initialization failure + - cifs: fix memory leak of pneg_inbuf on -EOPNOTSUPP ioctl case + - CIFS: cifs_read_allocate_pages: don't iterate through whole page array on + ENOMEM + - Revert "lockd: Show pid of lockd for remote locks" + - gcc-plugins: Fix build failures under Darwin host + - drm/tegra: gem: Fix CPU-cache maintenance for BO's allocated using + get_pages() + - drm/vmwgfx: Don't send drm sysfs hotplug events on initial master set + - drm/sun4i: Fix sun8i HDMI PHY clock initialization + - drm/sun4i: Fix sun8i HDMI PHY configuration for > 148.5 MHz + - drm/rockchip: shutdown drm subsystem on shutdown + - drm/lease: Make sure implicit planes are leased + - Revert "x86/build: Move _etext to actual end of .text" + - scsi: lpfc: Fix backport of faf5a744f4f8 ("scsi: lpfc: avoid uninitialized + variable warning") + - KVM: PPC: Book3S HV: Fix lockdep warning when entering guest on POWER9 + - KVM: PPC: Book3S HV: Restore SPRG3 in kvmhv_p9_guest_entry() + - powerpc/kexec: Fix loading of kernel + initramfs with kexec_file_load() + - kasan: initialize tag to 0xff in __kasan_kmalloc + - signal/arm64: Use force_sig not force_sig_fault for SIGKILL + - x86/ima: Check EFI_RUNTIME_SERVICES before using + - ima: fix wrong signed policy requirement when not appraising + - drm/vmwgfx: Fix user space handle equal to zero + - drm/vmwgfx: Fix compat mode shader operation + - drm/atomic: Wire file_priv through for property changes + - drm: Expose "FB_DAMAGE_CLIPS" property to atomic aware user-space only + - drm/cma-helper: Fix drm_gem_cma_free_object() + - ethtool: fix potential userspace buffer overflow + - Fix memory leak in sctp_process_init + - ipv4: not do cache for local delivery if bc_forwarding is enabled + - ipv6: fix the check before getting the cookie in rt6_get_cookie + - neighbor: Call __ipv4_neigh_lookup_noref in neigh_xmit + - net: ethernet: ti: cpsw_ethtool: fix ethtool ring param set + - net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query + - net: mvpp2: Use strscpy to handle stat strings + - net: rds: fix memory leak in rds_ib_flush_mr_pool + - net: sfp: read eeprom in maximum 16 byte increments + - net/tls: replace the sleeping lock around RX resync with a bit lock + - packet: unconditionally free po->rollover + - pktgen: do not sleep with the thread lock held. + - Revert "fib_rules: return 0 directly if an exactly same rule exists when + NLM_F_EXCL not supplied" + - ipv6: use READ_ONCE() for inet->hdrincl as in ipv4 + - ipv6: fix EFAULT on sendto with icmpv6 and hdrincl + - mtd: spinand: macronix: Fix ECC Status Read + - rcu: locking and unlocking need to always be at least barriers + - parisc: Use implicit space register selection for loading the coherence + index of I/O pdirs + - NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter + - NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled + - fuse: fallocate: fix return with locked inode + - pstore: Set tfm to NULL on free_buf_for_compression + - pstore/ram: Run without kernel crash dump region + - x86/power: Fix 'nosmt' vs hibernation triple fault during resume + - i2c: xiic: Add max_read_len quirk + - s390/mm: fix address space detection in exception handling + - xen-blkfront: switch kcalloc to kvcalloc for large array allocation + - MIPS: Bounds check virt_addr_valid + - MIPS: pistachio: Build uImage.gz by default + - Revert "MIPS: perf: ath79: Fix perfcount IRQ assignment" + - genwqe: Prevent an integer overflow in the ioctl + - test_firmware: Use correct snprintf() limit + - drm/gma500/cdv: Check vbt config bits when detecting lvds panels + - drm/msm: fix fb references in async update + - drm: add non-desktop quirk for Valve HMDs + - drm: add non-desktop quirks to Sensics and OSVR headsets. + - drm/amdgpu/psp: move psp version specific function pointers to early_init + - drm/amdgpu: remove ATPX_DGPU_REQ_POWER_FOR_DISPLAYS check when hotplug-in + - drm/i915: Fix I915_EXEC_RING_MASK + - drm/i915/fbc: disable framebuffer compression on GeminiLake + - drm/i915: Maintain consistent documentation subsection ordering + - drm: don't block fb changes for async plane updates + - drm/i915/gvt: Initialize intel_gvt_gtt_entry in stack + - TTY: serial_core, add ->install + - ipv4: Define __ipv4_neigh_lookup_noref when CONFIG_INET is disabled + - udp: only choose unbound UDP socket for multicast when not in a VRF + - neighbor: Reset gc_entries counter if new entry is released before insert + - cls_matchall: avoid panic when receiving a packet before filter set + - ipmr_base: Do not reset index in mr_table_dump + - ARC: mm: SIGSEGV userspace trying to access kernel virtual memory + - parisc: Fix crash due alternative coding for NP iopdir_fdc bit + - SUNRPC fix regression in umount of a secure mount + - fuse: fix copy_file_range() in the writeback case + - memstick: mspro_block: Fix an error code in mspro_block_issue_req() + - mmc: tmio: fix SCC error handling to avoid false positive CRC error + - mmc: sdhci_am654: Fix SLOTTYPE write + - nvme-rdma: fix queue mapping when queue count is limited + - drm/vc4: fix fb references in async update + - drm: Fix timestamp docs for variable refresh properties. + - drm/amd/display: Add ASICREV_IS_PICASSO + - drm/amdgpu: fix ring test failure issue during s3 in vce 3.0 (V2) + - drm/amd: fix fb references in async update + - rapidio: fix a NULL pointer dereference when create_workqueue() fails + - fs/fat/file.c: issue flush after the writeback of FAT + - sysctl: return -EINVAL if val violates minmax + - ipc: prevent lockup on alloc_msg and free_msg + - drm/pl111: Initialize clock spinlock early + - ARM: prevent tracing IPI_CPU_BACKTRACE + - mm/hmm: select mmu notifier when selecting HMM + - hugetlbfs: on restore reserve error path retain subpool reservation + - mem-hotplug: fix node spanned pages when we have a node with only + ZONE_MOVABLE + - mm/cma.c: fix crash on CMA allocation if bitmap allocation fails + - initramfs: free initrd memory if opening /initrd.image fails + - mm/cma.c: fix the bitmap status to show failed allocation reason + - mm: page_mkclean vs MADV_DONTNEED race + - mm/cma_debug.c: fix the break condition in cma_maxchunk_get() + - mm/slab.c: fix an infinite loop in leaks_show() + - kernel/sys.c: prctl: fix false positive in validate_prctl_map() + - thermal: rcar_gen3_thermal: disable interrupt in .remove + - drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER + - mfd: tps65912-spi: Add missing of table registration + - mfd: intel-lpss: Set the device in reset state when init + - drm/nouveau/disp/dp: respect sink limits when selecting failsafe link + configuration + - mfd: twl6040: Fix device init errors for ACCCTL register + - perf/x86/intel: Allow PEBS multi-entry in watermark mode + - drm/nouveau/kms/gf119-gp10x: push HeadSetControlOutputResource() mthd when + encoders change + - drm/bridge: adv7511: Fix low refresh rate selection + - objtool: Don't use ignore flag for fake jumps + - drm/nouveau/kms/gv100-: fix spurious window immediate interlocks + - bpf: fix undefined behavior in narrow load handling + - EDAC/mpc85xx: Prevent building as a module + - pwm: meson: Use the spin-lock only to protect register modifications + - mailbox: stm32-ipcc: check invalid irq + - ntp: Allow TAI-UTC offset to be set to zero + - f2fs: fix to avoid panic in do_recover_data() + - f2fs: fix to avoid panic in f2fs_inplace_write_data() + - f2fs: fix to avoid panic in f2fs_remove_inode_page() + - f2fs: fix to do sanity check on free nid + - f2fs: fix to clear dirty inode in error path of f2fs_iget() + - f2fs: fix to avoid panic in dec_valid_block_count() + - f2fs: fix to use inline space only if inline_xattr is enable + - f2fs: fix to do sanity check on valid block count of segment + - f2fs: fix to do checksum even if inode page is uptodate + - percpu: remove spurious lock dependency between percpu and sched + - configfs: fix possible use-after-free in configfs_register_group + - uml: fix a boot splat wrt use of cpu_all_mask + - PCI: dwc: Free MSI in dw_pcie_host_init() error path + - PCI: dwc: Free MSI IRQ page in dw_pcie_free_msi() + - mmc: mmci: Prevent polling for busy detection in IRQ context + - netfilter: nf_flow_table: fix missing error check for rhashtable_insert_fast + - netfilter: nf_conntrack_h323: restore boundary check correctness + - mips: Make sure dt memory regions are valid + - netfilter: nf_tables: fix base chain stat rcu_dereference usage + - watchdog: imx2_wdt: Fix set_timeout for big timeout values + - watchdog: fix compile time error of pretimeout governors + - blk-mq: move cancel of requeue_work into blk_mq_release + - iommu/vt-d: Set intel_iommu_gfx_mapped correctly + - misc: pci_endpoint_test: Fix test_reg_bar to be updated in pci_endpoint_test + - PCI: designware-ep: Use aligned ATU window for raising MSI interrupts + - nvme-pci: unquiesce admin queue on shutdown + - nvme-pci: shutdown on timeout during deletion + - netfilter: nf_flow_table: check ttl value in flow offload data path + - netfilter: nf_flow_table: fix netdev refcnt leak + - ALSA: hda - Register irq handler after the chip initialization + - nvmem: core: fix read buffer in place + - nvmem: sunxi_sid: Support SID on A83T and H5 + - fuse: retrieve: cap requested size to negotiated max_write + - nfsd: allow fh_want_write to be called twice + - nfsd: avoid uninitialized variable warning + - vfio: Fix WARNING "do not call blocking ops when !TASK_RUNNING" + - switchtec: Fix unintended mask of MRPC event + - net: thunderbolt: Unregister ThunderboltIP protocol handler when suspending + - x86/PCI: Fix PCI IRQ routing table memory leak + - i40e: Queues are reserved despite "Invalid argument" error + - platform/chrome: cros_ec_proto: check for NULL transfer function + - PCI: keystone: Prevent ARM32 specific code to be compiled for ARM64 + - soc: mediatek: pwrap: Zero initialize rdata in pwrap_init_cipher + - clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 + - soc: rockchip: Set the proper PWM for rk3288 + - ARM: dts: imx51: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx50: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx53: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sll: Specify IMX6SLL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx7d: Specify IMX7D_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6ul: Specify IMX6UL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6qdl: Specify IMX6QDL_CLK_IPG as "ipg" clock to SDMA + - PCI: rpadlpar: Fix leaked device_node references in add/remove paths + - drm/amd/display: Use plane->color_space for dpp if specified + - ARM: OMAP2+: pm33xx-core: Do not Turn OFF CEFUSE as PPA may be using it + - platform/x86: intel_pmc_ipc: adding error handling + - power: supply: max14656: fix potential use-before-alloc + - PCI: rcar: Fix a potential NULL pointer dereference + - PCI: rcar: Fix 64bit MSI message address handling + - scsi: qla2xxx: Reset the FCF_ASYNC_{SENT|ACTIVE} flags + - video: hgafb: fix potential NULL pointer dereference + - video: imsttfb: fix potential NULL pointer dereferences + - block, bfq: increase idling for weight-raised queues + - PCI: xilinx: Check for __get_free_pages() failure + - gpio: gpio-omap: add check for off wake capable gpios + - ice: Add missing case in print_link_msg for printing flow control + - dmaengine: idma64: Use actual device for DMA transfers + - pwm: tiehrpwm: Update shadow register for disabling PWMs + - ARM: dts: exynos: Always enable necessary APIO_1V8 and ABB_1V8 regulators on + Arndale Octa + - pwm: Fix deadlock warning when removing PWM device + - ARM: exynos: Fix undefined instruction during Exynos5422 resume + - usb: typec: fusb302: Check vconn is off when we start toggling + - soc: renesas: Identify R-Car M3-W ES1.3 + - gpio: vf610: Do not share irq_chip + - percpu: do not search past bitmap when allocating an area + - ovl: check the capability before cred overridden + - ovl: support stacked SEEK_HOLE/SEEK_DATA + - ALSA: seq: Cover unsubscribe_port() in list_mutex + - media: rockchip/vpu: Fix/re-order probe-error/remove path + - media: rockchip/vpu: Add missing dont_use_autosuspend() calls + - drm/msm: correct attempted NULL pointer dereference in debugfs + - mm/memory_hotplug: release memory resource after arch_remove_memory() + - mm/memory_hotplug.c: fix the wrong usage of N_HIGH_MEMORY + - drm/nouveau: fix duplication of nv50_head_atom struct + - f2fs: fix error path of recovery + - f2fs: fix to avoid panic in dec_valid_node_count() + - f2fs: fix to avoid deadloop in foreground GC + - f2fs: fix to retrieve inline xattr space + - media: atmel: atmel-isc: fix asd memory allocation + - vfio-pci/nvlink2: Fix potential VMA leak + - powerpc/pseries: Track LMB nid instead of using device tree + - arm64: defconfig: Update UFSHCD for Hi3660 soc + - iommu/vt-d: Don't request page request irq under dmar_global_lock + - soc/tegra: pmc: Remove reset sysfs entries on error + - power: supply: cpcap-battery: Fix signed counter sample register + - PCI: keystone: Invoke phy_reset() API before enabling PHY + - iommu/vt-d: Flush IOTLB for untrusted device in time + - arm64: dts: imx8mq: Mark iomuxc_gpr as i.MX6Q compatible + - pinctrl: pinctrl-intel: move gpio suspend/resume to noirq phase + - f2fs: fix potential recursive call when enabling data_flush + - arm64: dts: qcom: qcs404: Fix regulator supply names + - gpio: gpio-omap: limit errata 1.101 handling to wkup domain gpios only + - media: v4l2-ctrl: v4l2_ctrl_request_setup returns with error upon failure + - batman-adv: Adjust name for batadv_dat_send_data + - ice: Enable LAN_EN for the right recipes + - ice: Do not set LB_EN for prune switch rules + - media: v4l2-fwnode: Defaults may not override endpoint configuration in + firmware + - ARM: shmobile: porter: enable R-Car Gen2 regulator quirk + + [ Ubuntu: 5.0.0-29.31 ] + + * powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts + (CVE-2019-15031) / powerpc/tm: Fix FP/VMX unavailable exceptions inside a + transaction (CVE-2019-15030) (LP: #1843533) // CVE-2019-15031 + - powerpc/tm: Fix FP/VMX unavailable exceptions inside a transaction + - powerpc/tm: Fix restoring FP/VMX facility incorrectly on interrupts + * CVE-2019-14835 + - vhost: fix dirty log buffer overflow + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + + [ Ubuntu: 5.0.0-27.28 ] + + * disco/linux: 5.0.0-27.28 -proposed tracker (LP: #1840816) + * [Potential Regression] System crashes when running ftrace test in + ubuntu_kernel_selftests (LP: #1840750) + - x86/kprobes: Set instruction page as executable + + -- Marcelo Henrique Cerri Wed, 18 Sep 2019 06:52:12 -0300 + +linux-oracle (5.0.0-1002.3) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1002.3 -proposed tracker (LP: #1842155) + + * Packaging resync (LP: #1786013) + - [Packaging] fix Vcs-Git: package + + * Miscellaneous Ubuntu changes + - [config] Update annotations format to version 3 + - [config] CONFIG_PAGE_POISONING=y + - [config] CONFIG_NETWORK_PHY_TIMESTAMPING=y + - [config] Un-escaping string literal in CONFIG_LSM + + -- Khalid Elmously Fri, 30 Aug 2019 17:55:51 -0400 + +linux-oracle (5.0.0-1001.2) disco; urgency=medium + + * disco/linux-oracle: 5.0.0-1001.2 -proposed tracker (LP: #1840811) + + * disco: unable to use iptables/enable ufw under -virtual kernel + (LP: #1823862) + - [Packaging] add bpfilter to linux-modules + + * tcm_loop.ko: move from modules-extra into main modules package + (LP: #1817786) + - [Packaging] move tcm_loop.lo to main linux-modules package + + * autofs kernel module missing (LP: #1824333) + - [Config] Update autofs4 path in inclusion list + + * [Packaging] Improve config annotations check on custom kernels + (LP: #1820075) + - [Config] linux-oracle: Include custom annotations files + + * Miscellaneous Ubuntu changes + - [Packaging] update update.conf + - [Config] update configs following rebase to 5.0.0-26.27 + - [Packaging] sync packaging updates from master + - [Config] Update getabis to use linux-buildinfo + - [Config] Include shiftfs in generic inclusion list. + + -- Khalid Elmously Mon, 26 Aug 2019 21:52:36 -0400 + +linux-oracle (5.0.0-1000.0) disco; urgency=medium + + * Emtpy entry + + -- Khalid Elmously Fri, 23 Aug 2019 01:00:54 -0400 + +linux-oracle (4.15.0-1022.25) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1022.25 -proposed tracker (LP: #1839997) + + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] oracle: enable build and signing nvidia + + * Bionic update: upstream stable patchset 2019-08-05 (LP: #1839036) + - [Packaging] oracle: adv7511 to adv7511-v4l2 rename + + * Bionic update: upstream stable patchset 2019-08-02 (LP: #1838824) + - [Config] oracle: Add CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT=y + + * Bionic update: upstream stable patchset 2019-07-29 (LP: #1838349) + - [Config] oracle: include CONFIG_INTEL_ATOMISP2_PM + + * Bionic update: upstream stable patchset 2019-07-26 (LP: #1838116) + - [Config] oracle: Drop CONFIG_R3964 + - [Config] oracle: Add CONFIG_LDISC_AUTOLOAD=y + + * Bionic update: upstream stable patchset 2019-07-22 (LP: #1837477) + - [Config] oracle: Add CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y + + [ Ubuntu: 4.15.0-59.66 ] + + * bionic/linux: 4.15.0-59.66 -proposed tracker (LP: #1840006) + * zfs not completely removed from bionic tree (LP: #1840051) + - SAUCE: (noup) remove completely the zfs code + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * [18.04 FEAT] Enhanced hardware support (LP: #1836857) + - s390: report new CPU capabilities + - s390: add alignment hints to vector load and store + * [18.04 FEAT] Enhanced CPU-MF hardware counters - kernel part (LP: #1836860) + - s390/cpum_cf: Add support for CPU-MF SVN 6 + - s390/cpumf: Add extended counter set definitions for model 8561 and 8562 + * ideapad_laptop disables WiFi/BT radios on Lenovo Y540 (LP: #1837136) + - platform/x86: ideapad-laptop: Remove no_hw_rfkill_list + * Stacked onexec transitions fail when under NO NEW PRIVS restrictions + (LP: #1839037) + - SAUCE: apparmor: fix nnp subset check failure when, stacking + * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight + timeout for bcache removal causes spurious failures (LP: #1796292) + - SAUCE: bcache: fix deadlock in bcache_allocator + * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) + - bcache: never writeback a discard operation + - bcache: improve bcache_reboot() + - bcache: fix writeback target calc on large devices + - bcache: add journal statistic + - bcache: fix high CPU occupancy during journal + - bcache: use pr_info() to inform duplicated CACHE_SET_IO_DISABLE set + - bcache: fix incorrect sysfs output value of strip size + - bcache: fix error return value in memory shrink + - bcache: fix using of loop variable in memory shrink + - bcache: Fix indentation + - bcache: Add __printf annotation to __bch_check_keys() + - bcache: Annotate switch fall-through + - bcache: Fix kernel-doc warnings + - bcache: Remove an unused variable + - bcache: Suppress more warnings about set-but-not-used variables + - bcache: Reduce the number of sparse complaints about lock imbalances + - bcache: Fix a compiler warning in bcache_device_init() + - bcache: Move couple of string arrays to sysfs.c + - bcache: Move couple of functions to sysfs.c + - bcache: Replace bch_read_string_list() by __sysfs_match_string() + * linux hwe i386 kernel 5.0.0-21.22~18.04.1 crashes on Lenovo x220 + (LP: #1838115) + - x86/mm: Check for pfn instead of page in vmalloc_sync_one() + - x86/mm: Sync also unmappings in vmalloc_sync_all() + - mm/vmalloc.c: add priority threshold to __purge_vmap_area_lazy() + - mm/vmalloc: Sync unmappings in __purge_vmap_area_lazy() + * [bionic] drm/i915: softpin broken, needs to be fixed for 32bit mesa + (LP: #1815172) + - drm/i915: Mark up GTT sizes as u64 + - drm/i915/gvt: Use I915_GTT_PAGE_SIZE + - drm/i915: Compare user's 64b GTT offset even on 32b + * Bionic update: upstream stable patchset 2019-08-07 (LP: #1839376) + - ARM: riscpc: fix DMA + - ARM: dts: rockchip: Make rk3288-veyron-minnie run at hs200 + - ARM: dts: rockchip: Make rk3288-veyron-mickey's emmc work again + - ARM: dts: rockchip: Mark that the rk3288 timer might stop in suspend + - ftrace: Enable trampoline when rec count returns back to one + - kernel/module.c: Only return -EEXIST for modules that have finished loading + - MIPS: lantiq: Fix bitfield masking + - dmaengine: rcar-dmac: Reject zero-length slave DMA requests + - clk: tegra210: fix PLLU and PLLU_OUT1 + - fs/adfs: super: fix use-after-free bug + - btrfs: fix minimum number of chunk errors for DUP + - cifs: Fix a race condition with cifs_echo_request + - ceph: fix improper use of smp_mb__before_atomic() + - ceph: return -ERANGE if virtual xattr value didn't fit in buffer + - ACPI: blacklist: fix clang warning for unused DMI table + - scsi: zfcp: fix GCC compiler warning emitted with -Wmaybe-uninitialized + - x86: kvm: avoid constant-conversion warning + - ACPI: fix false-positive -Wuninitialized warning + - be2net: Signal that the device cannot transmit during reconfiguration + - x86/apic: Silence -Wtype-limits compiler warnings + - x86: math-emu: Hide clang warnings for 16-bit overflow + - mm/cma.c: fail if fixed declaration can't be honored + - coda: add error handling for fget + - coda: fix build using bare-metal toolchain + - uapi linux/coda_psdev.h: move upc_req definition from uapi to kernel side + headers + - drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings + - ipc/mqueue.c: only perform resource calculation if user valid + - xen/pv: Fix a boot up hang revealed by int3 self test + - x86/kvm: Don't call kvm_spurious_fault() from .fixup + - x86/paravirt: Fix callee-saved function ELF sizes + - x86, boot: Remove multiple copy of static function sanitize_boot_params() + - drm/nouveau: fix memory leak in nouveau_conn_reset() + - kbuild: initialize CLANG_FLAGS correctly in the top Makefile + - Btrfs: fix incremental send failure after deduplication + - Btrfs: fix race leading to fs corruption after transaction abort + - mmc: dw_mmc: Fix occasional hang after tuning on eMMC + - gpiolib: fix incorrect IRQ requesting of an active-low lineevent + - IB/hfi1: Fix Spectre v1 vulnerability + - selinux: fix memory leak in policydb_init() + - s390/dasd: fix endless loop after read unit address configuration + - parisc: Fix build of compressed kernel even with debug enabled + - drivers/perf: arm_pmu: Fix failure path in PM notifier + - nbd: replace kill_bdev() with __invalidate_device() again + - xen/swiotlb: fix condition for calling xen_destroy_contiguous_region() + - IB/mlx5: Fix unreg_umr to ignore the mkey state + - IB/mlx5: Use direct mkey destroy command upon UMR unreg failure + - IB/mlx5: Move MRs to a kernel PD when freeing them to the MR cache + - IB/mlx5: Fix RSS Toeplitz setup to be aligned with the HW specification + - IB/hfi1: Check for error on call to alloc_rsm_map_table + - eeprom: at24: make spd world-readable again + - objtool: Support GCC 9 cold subfunction naming scheme + - gcc-9: properly declare the {pv,hv}clock_page storage + - x86/vdso: Prevent segfaults due to hoisted vclock reads + - Documentation: Add swapgs description to the Spectre v1 documentation + - firmware/psci: psci_checker: Park kthreads before stopping them + - btrfs: qgroup: Don't hold qgroup_ioctl_lock in btrfs_qgroup_inherit() + - lib/test_string.c: avoid masking memset16/32/64 failures + - mmc: meson-mx-sdio: Fix misuse of GENMASK macro + - arm64: compat: Allow single-byte watchpoints on all addresses + - arm64: cpufeature: Fix feature comparison for CTR_EL0.{CWG,ERG} + - IB/mlx5: Fix clean_mr() to work in the expected order + - ARC: enable uboot support unconditionally + - scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA + * Bionic update: upstream stable patchset 2019-08-06 (LP: #1839213) + - staging: vt6656: use meaningful error code during buffer allocation + - drm/amd/display: Fill prescale_params->scale for RGB565 + - drm/amd/display: Disable ABM before destroy ABM struct + - gpu: host1x: Increase maximum DMA segment size + - drm/amd/display: Always allocate initial connector state state + - drm/amd/display: fix compilation error + - mmc: sdhci: sdhci-pci-o2micro: Check if controller supports 8-bit width + - i2c: stm32f7: fix the get_irq error cases + - genksyms: Teach parser about 128-bit built-in types + - powerpc/mm: Handle page table allocation failures + - arm64: assembler: Switch ESB-instruction with a vanilla nop if + !ARM64_HAS_RAS + - dlm: check if workqueues are NULL before flushing/destroying + - proc: use down_read_killable mmap_sem for /proc/pid/pagemap + - proc: use down_read_killable mmap_sem for /proc/pid/clear_refs + - proc: use down_read_killable mmap_sem for /proc/pid/map_files + - proc: use down_read_killable mmap_sem for /proc/pid/maps + - mm: use down_read_killable for locking mmap_sem in access_remote_vm + - ALSA: ac97: Fix double free of ac97_codec_device + - libnvdimm/bus: Stop holding nvdimm_bus_list_mutex over __nd_ioctl() + - vsock: correct removal of socket from the list + - NFS: Fix dentry revalidation on NFSv4 lookup + - NFS: Refactor nfs_lookup_revalidate() + - NFSv4: Fix lookup revalidate of regular files + - i2c: qup: fixed releasing dma without flush operation completion + - arm64: compat: Provide definition for COMPAT_SIGMINSTKSZ + - binder: fix possible UAF when freeing buffer + - ISDN: hfcsusb: checking idx of ep configuration + - media: au0828: fix null dereference in error path + - ath10k: Change the warning message string + - media: cpia2_usb: first wake up, then free in disconnect + - media: pvrusb2: use a different format for warnings + - NFS: Cleanup if nfs_match_client is interrupted + - media: radio-raremono: change devm_k*alloc to k*alloc + - iommu/vt-d: Don't queue_iova() if there is no flush queue + - iommu/iova: Fix compilation error with !CONFIG_IOMMU_IOVA + - hv_sock: Add support for delayed close + - Bluetooth: hci_uart: check for missing tty operations + - sched/fair: Don't free p->numa_faults with concurrent readers + - drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl + - Fix allyesconfig output. + - ip_tunnel: allow not to count pkts on tstats by setting skb's dev to NULL + * Bionic update: upstream stable patchset 2019-08-05 (LP: #1839036) + - e1000e: start network tx queue only when link is up + - Input: synaptics - enable SMBUS on T480 thinkpad trackpad + - nilfs2: do not use unexported cpu_to_le32()/le32_to_cpu() in uapi header + - drivers: base: cacheinfo: Ensure cpu hotplug work is done before Intel RDT + - crypto: talitos - rename alternative AEAD algos. + - samples, bpf: fix to change the buffer size for read() + - bpf: sockmap, fix use after free from sleep in psock backlog workqueue + - staging:iio:ad7150: fix threshold mode config bit + - mac80211: mesh: fix RCU warning + - mac80211: free peer keys before vif down in mesh + - iwlwifi: Fix double-free problems in iwl_req_fw_callback() + - dt-bindings: can: mcp251x: add mcp25625 support + - can: mcp251x: add support for mcp25625 + - can: m_can: implement errata "Needless activation of MRAF irq" + - can: af_can: Fix error path of can_init() + - ibmvnic: Refresh device multicast list after reset + - ARM: dts: am335x phytec boards: Fix cd-gpios active level + - Input: imx_keypad - make sure keyboard can always wake up system + - KVM: arm/arm64: vgic: Fix kvm_device leak in vgic_its_destroy + - mlxsw: spectrum: Disallow prio-tagged packets when PVID is removed + - ARM: davinci: da850-evm: call regulator_has_full_constraints() + - ARM: davinci: da8xx: specify dma_coherent_mask for lcdc + - mac80211: only warn once on chanctx_conf being NULL + - qmi_wwan: add support for QMAP padding in the RX path + - qmi_wwan: avoid RCU stalls on device disconnect when in QMAP mode + - qmi_wwan: extend permitted QMAP mux_id value range + - md: fix for divide error in status_resync + - bnx2x: Check if transceiver implements DDM before access + - drm: return -EFAULT if copy_to_user() fails + - ip6_tunnel: allow not to count pkts on tstats by passing dev as NULL + - net: lio_core: fix potential sign-extension overflow on large shift + - quota: fix a problem about transfer quota + - net: dsa: mv88e6xxx: fix shift of FID bits in mv88e6185_g1_vtu_loadpurge() + - net :sunrpc :clnt :Fix xps refcount imbalance on the error path + - fscrypt: don't set policy for a dead directory + - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length + - ALSA: hda/realtek - Headphone Mic can't record after S3 + - block, bfq: NULL out the bic when it's no longer valid + - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg() + - x86/tls: Fix possible spectre-v1 in do_get_thread_area() + - Documentation: Add section about CPU vulnerabilities for Spectre + - mwifiex: Abort at too short BSS descriptor element + - mwifiex: Don't abort on small, spec-compliant vendor IEs + - USB: serial: ftdi_sio: add ID for isodebug v1 + - USB: serial: option: add support for GosunCn ME3630 RNDIS mode + - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled" + - p54usb: Fix race between disconnect and firmware loading + - usb: gadget: ether: Fix race between gether_disconnect and rx_submit + - usb: renesas_usbhs: add a workaround for a race condition of workqueue + - staging: comedi: dt282x: fix a null pointer deref on interrupt + - staging: comedi: amplc_pci230: fix null pointer deref on interrupt + - binder: fix memory leak in error path + - carl9170: fix misuse of device driver API + - VMCI: Fix integer overflow in VMCI handle arrays + - MIPS: Remove superfluous check for __linux__ + - clk: ti: clkctrl: Fix returning uninitialized data + - efi/bgrt: Drop BGRT status field reserved bits check + - perf/core: Fix perf_sample_regs_user() mm check + - ARM: omap2: remove incorrect __init annotation + - be2net: fix link failure after ethtool offline test + - ppp: mppe: Add softdep to arc4 + - sis900: fix TX completion + - ARM: dts: imx6ul: fix PWM[1-4] interrupts + - dm verity: use message limit for data block corruption message + - x86/boot/64: Fix crash if kernel image crosses page table boundary + - cpu/hotplug: Fix out-of-bounds read when setting fail state + - linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL + - ARC: hide unused function unw_hdr_alloc + - s390: fix stfle zero padding + - s390/qdio: (re-)initialize tiqdio list entries + - s390/qdio: don't touch the dsci in tiqdio_add_input_queues() + - crypto/NX: Set receive window credits to max number of CRBs in RxFIFO + - drm/udl: introduce a macro to convert dev to udl. + - drm/udl: move to embedding drm device inside udl device. + - drm/vmwgfx: fix a warning due to missing dma_parms + - riscv: Fix udelay in RV32. + - mac80211: do not start any work during reconfigure flow + - bpf, devmap: Fix premature entry free on destroying map + - NFS4: Only set creation opendata if O_CREAT + - perf pmu: Fix uncore PMU alias list for ARM64 + - Documentation/admin: Remove the vsyscall=native documentation + - drivers/usb/typec/tps6598x.c: fix portinfo width + - staging: bcm2835-camera: Ensure all buffers are returned on disable + - staging: bcm2835-camera: Remove check of the number of buffers supplied + - staging: rtl8712: reduce stack usage, again + - irqchip/gic-v3-its: Fix command queue pointer comparison bug + - x86/apic: Fix integer overflow on 10 bit left shift of cpu_khz + - pinctrl: mcp23s08: Fix add_data and irqchip_add_nested call order + - x86/boot/64: Add missing fixup_pointer() for next_early_pgt access + - genirq: Delay deactivation in free_irq() + - genirq: Fix misleading synchronize_irq() documentation + - genirq: Update code comments wrt recycled thread_mask + - genirq: Synchronize only with single thread on free_irq() + - genirq: Add optional hardware synchronization for shutdown + - x86/ioapic: Implement irq_get_irqchip_state() callback + - x86/irq: Handle spurious interrupt after shutdown gracefully + - crypto: talitos - move struct talitos_edesc into talitos.h + - crypto: talitos - fix hash on SEC1. + - regmap-irq: do not write mask register if mask_base is zero + - MIPS: ath79: fix ar933x uart parity mode + - MIPS: fix build on non-linux hosts + - arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly + - scsi: iscsi: set auth_protocol back to NULL if CHAP_A value is not supported + - dmaengine: imx-sdma: fix use-after-free on probe error path + - wil6210: fix potential out-of-bounds read + - ath10k: Do not send probe response template for mesh + - ath9k: Check for errors when reading SREV register + - ath6kl: add some bounds checking + - ath: DFS JP domain W56 fixed pulse type 3 RADAR detection + - batman-adv: fix for leaked TVLV handler. + - media: dvb: usb: fix use after free in dvb_usb_device_exit + - media: spi: IR LED: add missing of table registration + - crypto: talitos - fix skcipher failure due to wrong output IV + - media: marvell-ccic: fix DMA s/g desc number calculation + - media: vpss: fix a potential NULL pointer dereference + - media: media_device_enum_links32: clean a reserved field + - net: stmmac: dwmac1000: Clear unused address entries + - net: stmmac: dwmac4/5: Clear unused address entries + - qed: Set the doorbell address correctly + - signal/pid_namespace: Fix reboot_pid_ns to use send_sig not force_sig + - af_key: fix leaks in key_pol_get_resp and dump_sp. + - xfrm: Fix xfrm sel prefix length validation + - fscrypt: clean up some BUG_ON()s in block encryption/decryption + - media: mc-device.c: don't memset __user pointer contents + - media: staging: media: davinci_vpfe: - Fix for memory leak if decoder + initialization fails. + - net: phy: Check against net_device being NULL + - crypto: talitos - properly handle split ICV. + - crypto: talitos - Align SEC1 accesses to 32 bits boundaries. + - tua6100: Avoid build warnings. + - locking/lockdep: Fix merging of hlocks with non-zero references + - media: wl128x: Fix some error handling in fm_v4l2_init_video_device() + - cpupower : frequency-set -r option misses the last cpu in related cpu list + - net: stmmac: dwmac4: fix flow control issue + - net: fec: Do not use netdev messages too early + - net: axienet: Fix race condition causing TX hang + - s390/qdio: handle PENDING state for QEBSM devices + - RAS/CEC: Fix pfn insertion + - net: sfp: add mutex to prevent concurrent state checks + - ipset: Fix memory accounting for hash types on resize + - perf cs-etm: Properly set the value of 'old' and 'head' in snapshot mode + - perf tests: Add valid callback for parse-events test + - perf test 6: Fix missing kvm module load for s390 + - media: fdp1: Support M3N and E3 platforms + - iommu: Fix a leak in iommu_insert_resv_region + - gpio: omap: fix lack of irqstatus_raw0 for OMAP4 + - gpio: omap: ensure irq is enabled before wakeup + - regmap: fix bulk writes on paged registers + - bpf: silence warning messages in core + - rcu: Force inlining of rcu_read_lock() + - x86/cpufeatures: Add FDP_EXCPTN_ONLY and ZERO_FCS_FDS + - blkcg, writeback: dead memcgs shouldn't contribute to writeback ownership + arbitration + - xfrm: fix sa selector validation + - sched/core: Add __sched tag for io_schedule() + - x86/atomic: Fix smp_mb__{before,after}_atomic() + - perf evsel: Make perf_evsel__name() accept a NULL argument + - vhost_net: disable zerocopy by default + - ipoib: correcly show a VF hardware address + - EDAC/sysfs: Fix memory leak when creating a csrow object + - ipsec: select crypto ciphers for xfrm_algo + - ipvs: defer hook registration to avoid leaks + - media: s5p-mfc: Make additional clocks optional + - media: i2c: fix warning same module names + - ntp: Limit TAI-UTC offset + - timer_list: Guard procfs specific code + - acpi/arm64: ignore 5.1 FADTs that are reported as 5.0 + - media: coda: fix mpeg2 sequence number handling + - media: coda: fix last buffer handling in V4L2_ENC_CMD_STOP + - media: coda: increment sequence offset for the last returned frame + - media: vimc: cap: check v4l2_fill_pixfmt return value + - media: hdpvr: fix locking and a missing msleep + - rtlwifi: rtl8192cu: fix error handle when usb probe failed + - mt7601u: do not schedule rx_tasklet when the device has been disconnected + - x86/build: Add 'set -e' to mkcapflags.sh to delete broken capflags.c + - mt7601u: fix possible memory leak when the device is disconnected + - ipvs: fix tinfo memory leak in start_sync_thread + - ath10k: add missing error handling + - ath10k: fix PCIE device wake up failed + - perf tools: Increase MAX_NR_CPUS and MAX_CACHES + - libata: don't request sense data on !ZAC ATA devices + - clocksource/drivers/exynos_mct: Increase priority over ARM arch timer + - rslib: Fix decoding of shortened codes + - rslib: Fix handling of of caller provided syndrome + - ixgbe: Check DDM existence in transceiver before access + - crypto: serpent - mark __serpent_setkey_sbox noinline + - crypto: asymmetric_keys - select CRYPTO_HASH where needed + - EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec + - bcache: check c->gc_thread by IS_ERR_OR_NULL in cache_set_flush() + - net: hns3: fix a -Wformat-nonliteral compile warning + - net: hns3: add some error checking in hclge_tm module + - ath10k: destroy sdio workqueue while remove sdio module + - iwlwifi: mvm: Drop large non sta frames + - perf stat: Make metric event lookup more robust + - net: usb: asix: init MAC address buffers + - gpiolib: Fix references to gpiod_[gs]et_*value_cansleep() variants + - Bluetooth: hci_bcsp: Fix memory leak in rx_skb + - Bluetooth: 6lowpan: search for destination address in all peers + - Bluetooth: Check state in l2cap_disconnect_rsp + - gtp: add missing gtp_encap_disable_sock() in gtp_encap_enable() + - Bluetooth: validate BLE connection interval updates + - gtp: fix suspicious RCU usage + - gtp: fix Illegal context switch in RCU read-side critical section. + - gtp: fix use-after-free in gtp_encap_destroy() + - gtp: fix use-after-free in gtp_newlink() + - net: mvmdio: defer probe of orion-mdio if a clock is not ready + - iavf: fix dereference of null rx_buffer pointer + - floppy: fix out-of-bounds read in next_valid_format + - floppy: fix invalid pointer dereference in drive_name + - xen: let alloc_xenballooned_pages() fail if not enough memory free + - scsi: NCR5380: Reduce goto statements in NCR5380_select() + - scsi: NCR5380: Always re-enable reselection interrupt + - Revert "scsi: ncr5380: Increase register polling limit" + - scsi: core: Fix race on creating sense cache + - scsi: megaraid_sas: Fix calculation of target ID + - scsi: mac_scsi: Increase PIO/PDMA transfer length threshold + - scsi: mac_scsi: Fix pseudo DMA implementation, take 2 + - crypto: ghash - fix unaligned memory access in ghash_setkey() + - crypto: ccp - Validate the the error value used to index error messages + - crypto: arm64/sha1-ce - correct digest for empty data in finup + - crypto: arm64/sha2-ce - correct digest for empty data in finup + - crypto: chacha20poly1305 - fix atomic sleep when using async algorithm + - crypto: ccp - memset structure fields to zero before reuse + - crypto: ccp/gcm - use const time tag comparison. + - crypto: crypto4xx - fix a potential double free in ppc4xx_trng_probe + - Input: gtco - bounds check collection indent level + - Input: alps - don't handle ALPS cs19 trackpoint-only device + - Input: synaptics - whitelist Lenovo T580 SMBus intertouch + - Input: alps - fix a mismatch between a condition check and its comment + - regulator: s2mps11: Fix buck7 and buck8 wrong voltages + - arm64: tegra: Update Jetson TX1 GPU regulator timings + - iwlwifi: pcie: don't service an interrupt that was masked + - iwlwifi: pcie: fix ALIVE interrupt handling for gen2 devices w/o MSI-X + - NFSv4: Handle the special Linux file open access mode + - pnfs/flexfiles: Fix PTR_ERR() dereferences in ff_layout_track_ds_error + - lib/scatterlist: Fix mapping iterator when sg->offset is greater than + PAGE_SIZE + - ASoC: dapm: Adapt for debugfs API change + - ALSA: seq: Break too long mutex context in the write loop + - media: v4l2: Test type instead of cfg->type in v4l2_ctrl_new_custom() + - media: coda: Remove unbalanced and unneeded mutex unlock + - KVM: x86/vPMU: refine kvm_pmu err msg when event creation failed + - arm64: tegra: Fix AGIC register range + - fs/proc/proc_sysctl.c: fix the default values of i_uid/i_gid on /proc/sys + inodes. + - drm/nouveau/i2c: Enable i2c pads & busses during preinit + - padata: use smp_mb in padata_reorder to avoid orphaned padata jobs + - dm zoned: fix zone state management race + - xen/events: fix binding user event channels to cpus + - 9p/xen: Add cleanup path in p9_trans_xen_init + - 9p/virtio: Add cleanup path in p9_virtio_init + - x86/boot: Fix memory leak in default_get_smp_config() + - perf/x86/amd/uncore: Do not set 'ThreadMask' and 'SliceMask' for non-L3 PMCs + - perf/x86/amd/uncore: Set the thread mask for F17h L3 PMCs + - intel_th: pci: Add Ice Lake NNPI support + - PCI: Do not poll for PME if the device is in D3cold + - Btrfs: fix data loss after inode eviction, renaming it, and fsync it + - Btrfs: fix fsync not persisting dentry deletions due to inode evictions + - Btrfs: add missing inode version, ctime and mtime updates when punching hole + - HID: wacom: generic: only switch the mode on devices with LEDs + - HID: wacom: correct touch resolution x/y typo + - libnvdimm/pfn: fix fsdax-mode namespace info-block zero-fields + - coda: pass the host file in vma->vm_file on mmap + - gpu: ipu-v3: ipu-ic: Fix saturation bit offset in TPMEM + - PCI: hv: Fix a use-after-free bug in hv_eject_device_work() + - crypto: caam - limit output IV to CBC to work around CTR mode DMA issue + - parisc: Ensure userspace privilege for ptraced processes in regset functions + - parisc: Fix kernel panic due invalid values in IAOQ0 or IAOQ1 + - powerpc/32s: fix suspend/resume when IBATs 4-7 are used + - powerpc/watchpoint: Restore NV GPRs while returning from exception + - eCryptfs: fix a couple type promotion bugs + - intel_th: msu: Fix single mode with disabled IOMMU + - Bluetooth: Add SMP workaround Microsoft Surface Precision Mouse bug + - usb: Handle USB3 remote wakeup for LPM enabled devices correctly + - net: mvmdio: allow up to four clocks to be specified for orion-mdio + - dt-bindings: allow up to four clocks for orion-mdio + - dm bufio: fix deadlock with loop device + - compiler.h, kasan: Avoid duplicating __read_once_size_nocheck() + - compiler.h: Add read_word_at_a_time() function. + - lib/strscpy: Shut up KASAN false-positives in strscpy() + - bnx2x: Prevent load reordering in tx completion processing + - caif-hsi: fix possible deadlock in cfhsi_exit_module() + - igmp: fix memory leak in igmpv3_del_delrec() + - ipv4: don't set IPv6 only flags to IPv4 addresses + - net: bcmgenet: use promisc for unsupported filters + - net: dsa: mv88e6xxx: wait after reset deactivation + - net: neigh: fix multiple neigh timer scheduling + - net: openvswitch: fix csum updates for MPLS actions + - nfc: fix potential illegal memory access + - rxrpc: Fix send on a connected, but unbound socket + - sky2: Disable MSI on ASUS P6T + - vrf: make sure skb->data contains ip header to make routing + - macsec: fix use-after-free of skb during RX + - macsec: fix checksumming after decryption + - netrom: fix a memory leak in nr_rx_frame() + - netrom: hold sock when setting skb->destructor + - bonding: validate ip header before check IPPROTO_IGMP + - net: make skb_dst_force return true when dst is refcounted + - tcp: fix tcp_set_congestion_control() use from bpf hook + - tcp: Reset bytes_acked and bytes_received when disconnecting + - net: bridge: mcast: fix stale nsrcs pointer in igmp3/mld2 report handling + - net: bridge: mcast: fix stale ipv6 hdr pointer when handling v6 query + - net: bridge: stp: don't cache eth dest pointer before skb pull + - dma-buf: balance refcount inbalance + - dma-buf: Discard old fence_excl on retrying get_fences_rcu for realloc + - MIPS: lb60: Fix pin mappings + - ext4: don't allow any modifications to an immutable file + - ext4: enforce the immutable flag on open files + - mm: add filemap_fdatawait_range_keep_errors() + - jbd2: introduce jbd2_inode dirty range scoping + - ext4: use jbd2_inode dirty range scoping + - ext4: allow directory holes + - mm: vmscan: scan anonymous pages on file refaults + - hvsock: fix epollout hang from race condition + - drm/panel: simple: Fix panel_simple_dsi_probe + - usb: core: hub: Disable hub-initiated U1/U2 + - tty: max310x: Fix invalid baudrate divisors calculator + - pinctrl: rockchip: fix leaked of_node references + - tty: serial: cpm_uart - fix init when SMC is relocated + - drm/edid: Fix a missing-check bug in drm_load_edid_firmware() + - PCI: Return error if cannot probe VF + - drm/bridge: tc358767: read display_props in get_modes() + - drm/bridge: sii902x: pixel clock unit is 10kHz instead of 1kHz + - drm/crc-debugfs: User irqsafe spinlock in drm_crtc_add_crc_entry + - memstick: Fix error cleanup path of memstick_init + - tty/serial: digicolor: Fix digicolor-usart already registered warning + - tty: serial: msm_serial: avoid system lockup condition + - serial: 8250: Fix TX interrupt handling condition + - drm/virtio: Add memory barriers for capset cache. + - phy: renesas: rcar-gen2: Fix memory leak at error paths + - powerpc/pseries/mobility: prevent cpu hotplug during DT update + - drm/rockchip: Properly adjust to a true clock in adjusted_mode + - tty: serial_core: Set port active bit in uart_port_activate + - usb: gadget: Zero ffs_io_data + - powerpc/pci/of: Fix OF flags parsing for 64bit BARs + - drm/msm: Depopulate platform on probe failure + - serial: mctrl_gpio: Check if GPIO property exisits before requesting it + - PCI: sysfs: Ignore lockdep for remove attribute + - kbuild: Add -Werror=unknown-warning-option to CLANG_FLAGS + - PCI: xilinx-nwl: Fix Multi MSI data programming + - iio: iio-utils: Fix possible incorrect mask calculation + - powerpc/xmon: Fix disabling tracing while in xmon + - recordmcount: Fix spurious mcount entries on powerpc + - mfd: core: Set fwnode for created devices + - mfd: arizona: Fix undefined behavior + - mfd: hi655x-pmic: Fix missing return value check for + devm_regmap_init_mmio_clk + - um: Silence lockdep complaint about mmap_sem + - powerpc/4xx/uic: clear pending interrupt after irq type/pol change + - RDMA/i40iw: Set queue pair state when being queried + - serial: sh-sci: Terminate TX DMA during buffer flushing + - serial: sh-sci: Fix TX DMA buffer flushing and workqueue races + - kallsyms: exclude kasan local symbols on s390 + - perf test mmap-thread-lookup: Initialize variable to suppress memory + sanitizer warning + - perf session: Fix potential NULL pointer dereference found by the smatch + tool + - perf annotate: Fix dereferencing freed memory found by the smatch tool + - RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM + - PCI: dwc: pci-dra7xx: Fix compilation when !CONFIG_GPIOLIB + - powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h + - f2fs: avoid out-of-range memory access + - mailbox: handle failed named mailbox channel request + - powerpc/eeh: Handle hugepages in ioremap space + - block/bio-integrity: fix a memory leak bug + - sh: prevent warnings when using iounmap + - mm/kmemleak.c: fix check for softirq context + - 9p: pass the correct prototype to read_cache_page + - mm/gup.c: mark undo_dev_pagemap as __maybe_unused + - mm/gup.c: remove some BUG_ONs from get_gate_page() + - mm/mmu_notifier: use hlist_add_head_rcu() + - locking/lockdep: Fix lock used or unused stats error + - locking/lockdep: Hide unused 'class' variable + - drm/crc: Only report a single overflow when a CRC fd is opened + - drm/crc-debugfs: Also sprinkle irqrestore over early exits + - usb: wusbcore: fix unbalanced get/put cluster_id + - usb: pci-quirks: Correct AMD PLL quirk detection + - KVM: nVMX: do not use dangling shadow VMCS after guest reset + - btrfs: inode: Don't compress if NODATASUM or NODATACOW set + - x86/sysfb_efi: Add quirks for some devices with swapped width and height + - x86/speculation/mds: Apply more accurate check on hypervisor platform + - binder: prevent transactions to context manager from its own process. + - fpga-manager: altera-ps-spi: Fix build error + - hpet: Fix division by zero in hpet_time_div() + - powerpc/xive: Fix loop exit-condition in xive_find_target_in_mask() + - powerpc/tm: Fix oops on sigreturn on systems without TM + - access: avoid the RCU grace period for the temporary subjective credentials + - batman-adv: Fix duplicated OGMs on NETDEV_UP + - net: hns3: set ops to null when unregister ad_dev + - x86/cpu: Add Ice Lake NNPI to Intel family + - qed: iWARP - Fix tc for MPA ll2 connection + - net: hns3: fix for skb leak when doing selftest + - sched/fair: Fix "runnable_avg_yN_inv" not used warnings + - x86/cacheinfo: Fix a -Wtype-limits warning + - nvme-pci: properly report state change failure in nvme_reset_work + - nvme-pci: set the errno on ctrl state change error + - arm64: Do not enable IRQs for ct_user_exit + - net: stmmac: sun8i: force select external PHY when no internal one + - bcache: check CACHE_SET_IO_DISABLE in allocator code + - bcache: check CACHE_SET_IO_DISABLE bit in bch_journal() + - bcache: acquire bch_register_lock later in cached_dev_free() + - bcache: fix potential deadlock in cached_def_free() + - perf stat: Fix group lookup for metric group + - tools: bpftool: Fix json dump crash on powerpc + - Bluetooth: Add a new 13d3:3496 QCA_ROME device + - Bluetooth: Add new 13d3:3491 QCA_ROME device + - Bluetooth: Add new 13d3:3501 QCA_ROME device + - bcache: ignore read-ahead request failure on backing device + - bcache: fix mistaken sysfs entry for io_error counter + - bcache: destroy dc->writeback_write_wq if failed to create + dc->writeback_thread + - iwlwifi: don't WARN when calling iwl_get_shared_mem_conf with RF-Kill + - iwlwifi: fix RF-Kill interrupt while FW load for gen2 devices + - ALSA: hda/realtek - Fixed Headphone Mic can't record on Dell platform + - media: videobuf2-core: Prevent size alignment wrapping buffer size to 0 + - media: videobuf2-dma-sg: Prevent size from overflowing + - perf/x86/intel: Fix spurious NMI on fixed counter + - drm/edid: parse CEA blocks embedded in DisplayID + - PCI: qcom: Ensure that PERST is asserted for at least 100 ms + - IB/mlx5: Report correctly tag matching rendezvous capability + - include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT + architectures + - xfs: fix pagecache truncation prior to reflink + - xfs: flush removing page cache in xfs_reflink_remap_prep + - xfs: don't overflow xattr listent buffer + - xfs: don't ever put nlink > 0 inodes on the unlinked list + - xfs: fix reporting supported extra file attributes for statx() + - xfs: serialize unaligned dio writes against all other dio writes + - xfs: abort unaligned nowait directio early + - powerpc/powernv/npu: Fix reference leak + - powerpc/pseries: Fix oops in hotplug memory notifier + - mmc: sdhci-msm: fix mutex while in spinlock + - mtd: rawnand: mtk: Correct low level time calculation of r/w cycle + - blk-throttle: fix zero wait time for iops throttled group + - tcp: be more careful in tcp_fragment() + - net/mlx5e: IPoIB, Add error path in mlx5_rdma_setup_rn + - net_sched: unset TCQ_F_CAN_BYPASS when adding filters + - net: bridge: don't cache ether dest pointer on input + - net: sched: verify that q!=NULL before setting q->flags + * Line 6 POD HD500 driver fault (LP: #1790595) // Bionic update: upstream + stable patchset 2019-08-05 (LP: #1839036) + - ALSA: line6: Fix wrong altsetting for LINE6_PODHD500_1 + * Bionic update: upstream stable patchset 2019-08-02 (LP: #1838824) + - rapidio: fix a NULL pointer dereference when create_workqueue() fails + - fs/fat/file.c: issue flush after the writeback of FAT + - sysctl: return -EINVAL if val violates minmax + - ipc: prevent lockup on alloc_msg and free_msg + - ARM: prevent tracing IPI_CPU_BACKTRACE + - mm/hmm: select mmu notifier when selecting HMM + - hugetlbfs: on restore reserve error path retain subpool reservation + - mem-hotplug: fix node spanned pages when we have a node with only + ZONE_MOVABLE + - mm/cma.c: fix crash on CMA allocation if bitmap allocation fails + - mm/cma.c: fix the bitmap status to show failed allocation reason + - mm/cma_debug.c: fix the break condition in cma_maxchunk_get() + - mm/slab.c: fix an infinite loop in leaks_show() + - kernel/sys.c: prctl: fix false positive in validate_prctl_map() + - thermal: rcar_gen3_thermal: disable interrupt in .remove + - drivers: thermal: tsens: Don't print error message on -EPROBE_DEFER + - mfd: tps65912-spi: Add missing of table registration + - mfd: intel-lpss: Set the device in reset state when init + - drm/nouveau/disp/dp: respect sink limits when selecting failsafe link + configuration + - mfd: twl6040: Fix device init errors for ACCCTL register + - perf/x86/intel: Allow PEBS multi-entry in watermark mode + - drm/bridge: adv7511: Fix low refresh rate selection + - objtool: Don't use ignore flag for fake jumps + - EDAC/mpc85xx: Prevent building as a module + - pwm: meson: Use the spin-lock only to protect register modifications + - ntp: Allow TAI-UTC offset to be set to zero + - f2fs: fix to avoid panic in do_recover_data() + - f2fs: fix to clear dirty inode in error path of f2fs_iget() + - f2fs: fix to avoid panic in dec_valid_block_count() + - f2fs: fix to do sanity check on valid block count of segment + - percpu: remove spurious lock dependency between percpu and sched + - configfs: fix possible use-after-free in configfs_register_group + - uml: fix a boot splat wrt use of cpu_all_mask + - mmc: mmci: Prevent polling for busy detection in IRQ context + - watchdog: imx2_wdt: Fix set_timeout for big timeout values + - watchdog: fix compile time error of pretimeout governors + - blk-mq: move cancel of requeue_work into blk_mq_release + - iommu/vt-d: Set intel_iommu_gfx_mapped correctly + - misc: pci_endpoint_test: Fix test_reg_bar to be updated in pci_endpoint_test + - nvme-pci: unquiesce admin queue on shutdown + - ALSA: hda - Register irq handler after the chip initialization + - nvmem: core: fix read buffer in place + - fuse: retrieve: cap requested size to negotiated max_write + - nfsd: allow fh_want_write to be called twice + - vfio: Fix WARNING "do not call blocking ops when !TASK_RUNNING" + - x86/PCI: Fix PCI IRQ routing table memory leak + - platform/chrome: cros_ec_proto: check for NULL transfer function + - PCI: keystone: Prevent ARM32 specific code to be compiled for ARM64 + - soc: mediatek: pwrap: Zero initialize rdata in pwrap_init_cipher + - clk: rockchip: Turn on "aclk_dmac1" for suspend on rk3288 + - soc: rockchip: Set the proper PWM for rk3288 + - ARM: dts: imx51: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx50: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx53: Specify IMX5_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ahb" clock to SDMA + - ARM: dts: imx7d: Specify IMX7D_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6ul: Specify IMX6UL_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6sx: Specify IMX6SX_CLK_IPG as "ipg" clock to SDMA + - ARM: dts: imx6qdl: Specify IMX6QDL_CLK_IPG as "ipg" clock to SDMA + - PCI: rpadlpar: Fix leaked device_node references in add/remove paths + - platform/x86: intel_pmc_ipc: adding error handling + - power: supply: max14656: fix potential use-before-alloc + - PCI: rcar: Fix a potential NULL pointer dereference + - PCI: rcar: Fix 64bit MSI message address handling + - video: hgafb: fix potential NULL pointer dereference + - video: imsttfb: fix potential NULL pointer dereferences + - block, bfq: increase idling for weight-raised queues + - PCI: xilinx: Check for __get_free_pages() failure + - gpio: gpio-omap: add check for off wake capable gpios + - dmaengine: idma64: Use actual device for DMA transfers + - pwm: tiehrpwm: Update shadow register for disabling PWMs + - ARM: dts: exynos: Always enable necessary APIO_1V8 and ABB_1V8 regulators on + Arndale Octa + - pwm: Fix deadlock warning when removing PWM device + - ARM: exynos: Fix undefined instruction during Exynos5422 resume + - usb: typec: fusb302: Check vconn is off when we start toggling + - gpio: vf610: Do not share irq_chip + - percpu: do not search past bitmap when allocating an area + - drm: don't block fb changes for async plane updates + - ALSA: seq: Cover unsubscribe_port() in list_mutex + - initramfs: free initrd memory if opening /initrd.image fails + - bpf: fix undefined behavior in narrow load handling + - f2fs: fix to avoid panic in f2fs_remove_inode_page() + - f2fs: fix to use inline space only if inline_xattr is enable + - netfilter: nf_conntrack_h323: restore boundary check correctness + - mips: Make sure dt memory regions are valid + - nvmem: sunxi_sid: Support SID on A83T and H5 + - nfsd: avoid uninitialized variable warning + - switchtec: Fix unintended mask of MRPC event + - net: thunderbolt: Unregister ThunderboltIP protocol handler when suspending + - i40e: Queues are reserved despite "Invalid argument" error + - net: hns3: return 0 and print warning when hit duplicate MAC + - soc: renesas: Identify R-Car M3-W ES1.1 + - soc: renesas: Identify R-Car M3-W ES1.3 + - [Config] updateconfigs for CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT + - drm/nouveau: add kconfig option to turn off nouveau legacy contexts. (v3) + - nouveau: Fix build with CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT disabled + - HID: wacom: Correct button numbering 2nd-gen Intuos Pro over Bluetooth + - HID: wacom: Sync INTUOSP2_BT touch state after each frame if necessary + - ALSA: oxfw: allow PCM capture for Stanton SCS.1m + - ALSA: hda/realtek - Update headset mode for ALC256 + - ALSA: firewire-motu: fix destruction of data for isochronous resources + - libata: Extend quirks for the ST1000LM024 drives with NOLPM quirk + - mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node + - fs/ocfs2: fix race in ocfs2_dentry_attach_lock() + - mm/vmscan.c: fix trying to reclaim unevictable LRU page + - signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO + - ptrace: restore smp_rmb() in __ptrace_may_access() + - media: v4l2-ioctl: clear fields in s_parm + - iommu/arm-smmu: Avoid constant zero in TLBI writes + - i2c: acorn: fix i2c warning + - bcache: fix stack corruption by PRECEDING_KEY() + - cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() + - ASoC: cs42xx8: Add regcache mask dirty + - ASoC: fsl_asrc: Fix the issue about unsupported rate + - drm/i915/sdvo: Implement proper HDMI audio support for SDVO + - x86/uaccess, kcov: Disable stack protector + - ALSA: seq: Protect in-kernel ioctl calls with mutex + - ALSA: seq: Fix race of get-subscription call vs port-delete ioctls + - Revert "ALSA: seq: Protect in-kernel ioctl calls with mutex" + - s390/kasan: fix strncpy_from_user kasan checks + - Drivers: misc: fix out-of-bounds access in function param_set_kgdbts_var + - scsi: qedi: remove memset/memcpy to nfunc and use func instead + - scsi: qedi: remove set but not used variables 'cdev' and 'udev' + - scsi: lpfc: add check for loss of ndlp when sending RRQ + - arm64/mm: Inhibit huge-vmap with ptdump + - nvme: remove the ifdef around nvme_nvm_ioctl + - platform/x86: pmc_atom: Add Lex 3I380D industrial PC to critclk_systems DMI + table + - platform/x86: pmc_atom: Add several Beckhoff Automation boards to + critclk_systems DMI table + - scsi: bnx2fc: fix incorrect cast to u64 on shift operation + - libnvdimm: Fix compilation warnings with W=1 + - selftests/timers: Add missing fflush(stdout) calls + - usbnet: ipheth: fix racing condition + - KVM: x86/pmu: do not mask the value that is written to fixed PMUs + - KVM: s390: fix memory slot handling for KVM_SET_USER_MEMORY_REGION + - drm/vmwgfx: integer underflow in vmw_cmd_dx_set_shader() leading to an + invalid read + - drm/vmwgfx: NULL pointer dereference from vmw_cmd_dx_view_define() + - usb: dwc2: Fix DMA cache alignment issues + - usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression) + - USB: Fix chipmunk-like voice when using Logitech C270 for recording audio. + - USB: serial: pl2303: add Allied Telesis VT-Kit3 + - USB: serial: option: add support for Simcom SIM7500/SIM7600 RNDIS mode + - USB: serial: option: add Telit 0x1260 and 0x1261 compositions + - RAS/CEC: Fix binary search function + - x86/microcode, cpuhotplug: Add a microcode loader CPU hotplug callback + - x86/kasan: Fix boot with 5-level paging and KASAN + - rtc: pcf8523: don't return invalid date when battery is low + - HID: wacom: Don't set tool type until we're in range + - HID: wacom: Don't report anything prior to the tool entering range + - HID: wacom: Send BTN_TOUCH in response to INTUOSP2_BT eraser contact + - bcache: only set BCACHE_DEV_WB_RUNNING when cached device attached + - f2fs: fix to avoid accessing xattr across the boundary + - nvme: fix srcu locking on error return in nvme_get_ns_from_disk + - nvme: merge nvme_ns_ioctl into nvme_ioctl + - nvme: release namespace SRCU protection before performing controller ioctls + - nvme: fix memory leak for power latency tolerance + - KVM: x86/pmu: mask the result of rdpmc according to the width of the + counters + - tools/kvm_stat: fix fields filter for child events + - RAS/CEC: Convert the timer callback to a workqueue + - x86/mm/KASLR: Compute the size of the vmemmap section properly + - ax25: fix inconsistent lock state in ax25_destroy_timer + - be2net: Fix number of Rx queues used for flow hashing + - ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero + - lapb: fixed leak of control-blocks. + - neigh: fix use-after-free read in pneigh_get_next + - net: openvswitch: do not free vport if register_netdevice() is failed. + - sctp: Free cookie before we memdup a new one + - sunhv: Fix device naming inconsistency between sunhv_console and sunhv_reg + - Staging: vc04_services: Fix a couple error codes + - perf/x86/intel/ds: Fix EVENT vs. UEVENT PEBS constraints + - netfilter: nf_queue: fix reinject verdict handling + - ipvs: Fix use-after-free in ip_vs_in + - selftests: netfilter: missing error check when setting up veth interface + - clk: ti: clkctrl: Fix clkdm_clk handling + - powerpc/powernv: Return for invalid IMC domain + - mISDN: make sure device name is NUL terminated + - x86/CPU/AMD: Don't force the CPB cap when running under a hypervisor + - perf/ring_buffer: Fix exposing a temporarily decreased data_head + - perf/ring_buffer: Add ordering to rb->nest increment + - perf/ring-buffer: Always use {READ,WRITE}_ONCE() for rb->user_page data + - gpio: fix gpio-adp5588 build errors + - net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() + - net: aquantia: fix LRO with FCS error + - i2c: dev: fix potential memory leak in i2cdev_ioctl_rdwr + - ALSA: hda - Force polling mode on CNL for fixing codec communication + - configfs: Fix use-after-free when accessing sd->s_dentry + - perf data: Fix 'strncat may truncate' build failure with recent gcc + - perf record: Fix s390 missing module symbol and warning for non-root users + - ia64: fix build errors by exporting paddr_to_nid() + - KVM: PPC: Book3S: Use new mutex to synchronize access to rtas token list + - KVM: PPC: Book3S HV: Don't take kvm->lock around kvm_for_each_vcpu + - net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs + - net: phy: dp83867: Set up RGMII TX delay + - scsi: libcxgbi: add a check for NULL pointer in cxgbi_check_route() + - scsi: smartpqi: properly set both the DMA mask and the coherent DMA mask + - scsi: scsi_dh_alua: Fix possible null-ptr-deref + - scsi: libsas: delete sas port if expander discover failed + - mlxsw: spectrum: Prevent force of 56G + - coredump: fix race condition between collapse_huge_page() and core dumping + - infiniband: fix race condition between infiniband mlx4, mlx5 driver and core + dumping + - Abort file_remove_privs() for non-reg. files + - tipc: purge deferredq list for each grp member in tipc_group_delete + - vsock/virtio: set SOCK_DONE on peer shutdown + - usb: xhci: Fix a potential null pointer dereference in + xhci_debugfs_create_endpoint() + - ACPI/PCI: PM: Add missing wakeup.flags.valid checks + - drm/etnaviv: lock MMU while dumping core + - net: aquantia: tx clean budget logic error + - perf namespace: Protect reading thread's namespace + - xen/pvcalls: Remove set but not used variable + - xen: xenbus: Catch closing of non existent transactions + - xen: xenbus_dev_frontend: Verify body of XS_TRANSACTION_END + - xenbus: Avoid deadlock during suspend due to open transactions + - tracing: Silence GCC 9 array bounds warning + - objtool: Support per-function rodata sections + - gcc-9: silence 'address-of-packed-member' warning + - net: phy: broadcom: Use strlcpy() for ethtool::get_strings + - mmc: core: Prevent processing SDIO IRQs when the card is suspended + - scsi: ufs: Avoid runtime suspend possibly being blocked forever + - usb: chipidea: udc: workaround for endpoint conflict issue + - IB/hfi1: Silence txreq allocation warnings + - Input: synaptics - enable SMBus on ThinkPad E480 and E580 + - Input: uinput - add compat ioctl number translation for UI_*_FF_UPLOAD + - apparmor: enforce nullbyte at end of tag string + - ARC: fix build warnings + - ARC: [plat-hsdk]: Add missing multicast filter bins number to GMAC node + - ARC: [plat-hsdk]: Add missing FIFO size entry in GMAC node + - parport: Fix mem leak in parport_register_dev_model + - parisc: Fix compiler warnings in float emulation code + - IB/rdmavt: Fix alloc_qpn() WARN_ON() + - IB/hfi1: Insure freeze_work work_struct is canceled on shutdown + - IB/{qib, hfi1, rdmavt}: Correct ibv_devinfo max_mr value + - IB/hfi1: Validate page aligned for a given virtual address + - MIPS: uprobes: remove set but not used variable 'epc' + - xtensa: Fix section mismatch between memblock_reserve and mem_reserve + - net: dsa: mv88e6xxx: avoid error message on remove from VLAN 0 + - net: hns: Fix loopback test failed at copper ports + - mdesc: fix a missing-check bug in get_vdev_port_node_info() + - sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD + - net: ethernet: mediatek: Use hw_feature to judge if HWLRO is supported + - net: ethernet: mediatek: Use NET_IP_ALIGN to judge if HW RX_2BYTE_OFFSET is + enabled + - drm/arm/hdlcd: Actually validate CRTC modes + - drm/arm/hdlcd: Allow a bit of clock tolerance + - scripts/checkstack.pl: Fix arm64 wrong or unknown architecture + - scsi: ufs: Check that space was properly alloced in copy_query_response + - scsi: smartpqi: unlock on error in pqi_submit_raid_request_synchronous() + - net: ipvlan: Fix ipvlan device tso disabled while NETIF_F_IP_CSUM is set + - s390/qeth: fix VLAN attribute in bridge_hostnotify udev event + - hwmon: (core) add thermal sensors only if dev->of_node is present + - hwmon: (pmbus/core) Treat parameters as paged if on multiple pages + - nvme: Fix u32 overflow in the number of namespace list calculation + - btrfs: start readahead also in seed devices + - can: flexcan: fix timeout when set small bitrate + - can: purge socket error queue on sock destruct + - powerpc/bpf: use unsigned division instruction for 64-bit operations + - ARM: imx: cpuidle-imx6sx: Restrict the SW2ISO increase to i.MX6SX + - ARM: dts: am57xx-idk: Remove support for voltage switching for SD card + - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections + - Bluetooth: Fix regression with minimum encryption key size alignment + - SMB3: retry on STATUS_INSUFFICIENT_RESOURCES instead of failing write + - cfg80211: fix memory leak of wiphy device name + - mac80211: drop robust management frames from unknown TA + - mac80211: handle deauthentication/disassociation from TDLS peer + - mac80211: Do not use stack memory with scatterlist for GMAC + - s390/jump_label: Use "jdd" constraint on gcc9 + - s390/ap: rework assembler functions to use unions for in/out register + variables + - mmc: core: API to temporarily disable retuning for SDIO CRC errors + - mmc: core: Add sdio_retune_hold_now() and sdio_retune_release() + - Input: silead - add MSSL0017 to acpi_device_id + - selftests: vm: install test_vmalloc.sh for run_vmtests + - arm64: Silence gcc warnings about arch ABI drift + - riscv: mm: synchronize MMU after pte change + - arm64/sve: should not depend on + - drm/vmwgfx: Use the backdoor port if the HB port is not available + - {nl,mac}80211: allow 4addr AP operation on crypto controlled devices + - perf ui helpline: Use strlcpy() as a shorter form of strncpy() + explicit + set nul + - perf help: Remove needless use of strncpy() + - perf header: Fix unchecked usage of strncpy() + - IB/hfi1: Close PSM sdma_progress sleep window + - 9p/xen: fix check for xenbus_read error in front_probe + - 9p/rdma: do not disconnect on down_interruptible EAGAIN + - 9p: acl: fix uninitialized iattr access + - 9p/rdma: remove useless check in cm_event_handler + - 9p: p9dirent_read: check network-provided name length + - net/9p: include trans_common.h to fix missing prototype warning. + - qmi_wwan: Fix out-of-bounds read + - fs/proc/array.c: allow reporting eip/esp for all coredumping threads + - mm/mempolicy.c: fix an incorrect rebind node in mpol_rebind_nodemask + - fs/binfmt_flat.c: make load_flat_shared_library() work + - dm log writes: make sure super sector log updates are written in order + - scsi: vmw_pscsi: Fix use-after-free in pvscsi_queue_lck() + - x86/speculation: Allow guests to use SSBD even if host does not + - x86/microcode: Fix the microcode load on CPU hotplug for real + - NFS/flexfiles: Use the correct TCP timeout for flexfiles I/O + - cpu/speculation: Warn on unsupported mitigations= parameter + - eeprom: at24: fix unexpected timeout under high load + - af_packet: Block execution of tasks waiting for transmit to complete in + AF_PACKET + - ipv4: Use return value of inet_iif() for __raw_v4_lookup in the while loop + - net/packet: fix memory leak in packet_set_ring() + - net: remove duplicate fetch in sock_getsockopt + - net: stmmac: fixed new system time seconds value calculation + - sctp: change to hold sk after auth shkey is created successfully + - tipc: change to use register_pernet_device + - tipc: check msg->req data len in tipc_nl_compat_bearer_disable + - tun: wake up waitqueues after IFF_UP is set + - team: Always enable vlan tx offload + - bonding: Always enable vlan tx offload + - bpf: udp: Avoid calling reuseport's bpf_prog from udp_gro + - bpf: udp: ipv6: Avoid running reuseport's bpf_prog from __udp6_lib_err + - arm64: futex: Avoid copying out uninitialised stack in failed cmpxchg() + - bpf, arm64: use more scalable stadd over ldxr / stxr loop in xadd + - futex: Update comments and docs about return values of arch futex code + - tipc: pass tunnel dev as NULL to udp_tunnel(6)_xmit_skb + - arm64: insn: Fix ldadd instruction encoding + - arm64: Don't unconditionally add -Wno-psabi to KBUILD_CFLAGS + - irqchip/mips-gic: Use the correct local interrupt map registers + - Bluetooth: Fix faulty expression for minimum encryption key size check + - ASoC : cs4265 : readable register too low + - ASoC: soc-pcm: BE dai needs prepare when pause release after resume + - spi: bitbang: Fix NULL pointer dereference in spi_unregister_master + - drm/mediatek: fix unbind functions + - drm/mediatek: call drm_atomic_helper_shutdown() when unbinding driver + - drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() + - ASoC: max98090: remove 24-bit format support if RJ is 0 + - ASoC: sun4i-i2s: Fix sun8i tx channel offset mask + - ASoC: sun4i-i2s: Add offset to RX channel select + - usb: gadget: fusb300_udc: Fix memory leak of fusb300->ep[i] + - usb: gadget: udc: lpc32xx: allocate descriptor with GFP_ATOMIC + - SoC: rt274: Fix internal jack assignment in set_jack callback + - scsi: hpsa: correct ioaccel2 chaining + - platform/x86: mlx-platform: Fix parent device in i2c-mux-reg device + registration + - cpuset: restore sanity to cpuset_cpus_allowed_fallback() + - scripts/decode_stacktrace.sh: prefix addr2line with $CROSS_COMPILE + - mm/mlock.c: change count_mm_mlocked_page_nr return type + - module: Fix livepatch/ftrace module text permissions race + - ftrace: Fix NULL pointer dereference in free_ftrace_func_mapper() + - MIPS: netlogic: xlr: Remove erroneous check in nlm_fmn_send() + - drm/i915/dmc: protect against reading random memory + - crypto: user - prevent operating on larval algorithms + - crypto: cryptd - Fix skcipher instance memory leak + - ALSA: seq: fix incorrect order of dest_client/dest_ports arguments + - ALSA: firewire-lib/fireworks: fix miss detection of received MIDI messages + - ALSA: line6: Fix write on zero-sized buffer + - ALSA: usb-audio: fix sign unintended sign extension on left shifts + - ALSA: hda/realtek - Change front mic location for Lenovo M710q + - lib/mpi: Fix karactx leak in mpi_powm + - tracing/snapshot: Resize spare buffer if size changed + - arm64: kaslr: keep modules inside module region when KASAN is enabled + - drm/amdgpu/gfx9: use reset default for PA_SC_FIFO_SIZE + - drm/imx: notify drm core before sending event during crtc disable + - drm/imx: only send event on crtc disable if kept disabled + - ftrace/x86: Remove possible deadlock between register_kprobe() and + ftrace_run_update_code() + - mm/vmscan.c: prevent useless kswapd loops + - btrfs: Ensure replaced device doesn't have pending chunk allocation + - vhost-net: set packet weight of tx polling to 2 * vq size + - vhost_net: use packet weight for rx handler, too + - vhost_net: introduce vhost_exceeds_weight() + - vhost: introduce vhost_exceeds_weight() + - vhost_net: fix possible infinite loop + - vhost: vsock: add weight support + - vhost: scsi: add weight support + - tty: rocket: fix incorrect forward declaration of 'rp_init()' + - KVM: x86: degrade WARN to pr_warn_ratelimited + - KVM: LAPIC: Fix pending interrupt in IRR blocked by software disable LAPIC + - svcrdma: Ignore source port when computing DRC hash + - MIPS: Fix bounds check virt_addr_valid + - MIPS: Add missing EHB in mtc0 -> mfc0 sequence. + - dmaengine: imx-sdma: remove BD_INTR for channel0 + - drm/mediatek: unbind components in mtk_drm_unbind() + - drm/mediatek: clear num_pipes when unbind driver + - x86/CPU: Add more Icelake model numbers + - platform/x86: asus-wmi: Only Tell EC the OS will handle display hotkeys from + asus_nb_wmi + - platform/x86: intel-vbtn: Report switch events when event wakes device + - i2c: pca-platform: Fix GPIO lookup code + - ALSA: hda/realtek: Add quirks for several Clevo notebook barebones + - ARM: dts: armada-xp-98dx3236: Switch to armada-38x-uart serial node + - drm/amd/powerplay: use hardware fan control if no powerplay fan table + - drm/etnaviv: add missing failure path to destroy suballoc + - mlxsw: spectrum: Handle VLAN device unlinking + - media: s5p-mfc: fix incorrect bus assignment in virtual child device + - net: hns: Fixes the missing put_device in positive leg for roce reset + - ALSA: hda: Initialize power_state field properly + - rds: Fix warning. + - ip6: fix skb leak in ip6frag_expire_frag_queue() + - netfilter: ipv6: nf_defrag: fix leakage of unqueued fragments + - sc16is7xx: move label 'err_spi' to correct section + - netfilter: ipv6: nf_defrag: accept duplicate fragments again + - nfsd: Fix overflow causing non-working mounts on 1 TB machines + - MIPS: have "plain" make calls build dtbs for selected platforms + - dmaengine: qcom: bam_dma: Fix completed descriptors count + * Bionic update: upstream stable patchset 2019-08-01 (LP: #1838700) + - x86: Hide the int3_emulate_call/jmp functions from UML + - ext4: do not delete unlinked inode from orphan list on failed truncate + - f2fs: Fix use of number of devices + - KVM: x86: fix return value for reserved EFER + - bio: fix improper use of smp_mb__before_atomic() + - sbitmap: fix improper use of smp_mb__before_atomic() + - Revert "scsi: sd: Keep disk read-only when re-reading partition" + - crypto: vmx - CTR: always increment IV as quadword + - mmc: sdhci-iproc: cygnus: Set NO_HISPD bit to fix HS50 data hold time + problem + - mmc: sdhci-iproc: Set NO_HISPD bit to fix HS50 data hold time problem + - kvm: svm/avic: fix off-by-one in checking host APIC ID + - libnvdimm/pmem: Bypass CONFIG_HARDENED_USERCOPY overhead + - arm64/iommu: handle non-remapped addresses in ->mmap and ->get_sgtable + - gfs2: Fix sign extension bug in gfs2_update_stats + - Btrfs: do not abort transaction at btrfs_update_root() after failure to COW + path + - Btrfs: avoid fallback to transaction commit during fsync of files with holes + - Btrfs: fix race between ranged fsync and writeback of adjacent ranges + - btrfs: sysfs: Fix error path kobject memory leak + - btrfs: sysfs: don't leak memory when failing add fsid + - fbdev: fix divide error in fb_var_to_videomode + - btrfs: honor path->skip_locking in backref code + - fbdev: fix WARNING in __alloc_pages_nodemask bug + - media: cpia2: Fix use-after-free in cpia2_exit + - media: serial_ir: Fix use-after-free in serial_ir_init_module + - media: vivid: use vfree() instead of kfree() for dev->bitmap_cap + - ssb: Fix possible NULL pointer dereference in ssb_host_pcmcia_exit + - bpf: devmap: fix use-after-free Read in __dev_map_entry_free + - batman-adv: mcast: fix multicast tt/tvlv worker locking + - at76c50x-usb: Don't register led_trigger if usb_register_driver failed + - net: erspan: fix use-after-free + - gfs2: Fix lru_count going negative + - cxgb4: Fix error path in cxgb4_init_module + - NFS: make nfs_match_client killable + - IB/hfi1: Fix WQ_MEM_RECLAIM warning + - gfs2: Fix occasional glock use-after-free + - mmc: core: Verify SD bus width + - tools/bpf: fix perf build error with uClibc (seen on ARC) + - dmaengine: tegra210-dma: free dma controller in remove() + - net: ena: gcc 8: fix compilation warning + - pinctrl: zte: fix leaked of_node references + - ASoC: hdmi-codec: unlock the device on startup errors + - powerpc/perf: Return accordingly on invalid chip-id in + - powerpc/boot: Fix missing check of lseek() return value + - ASoC: imx: fix fiq dependencies + - spi: pxa2xx: fix SCR (divisor) calculation + - brcm80211: potential NULL dereference in + brcmf_cfg80211_vndr_cmds_dcmd_handler() + - ACPI / property: fix handling of data_nodes in acpi_get_next_subnode() + - ARM: vdso: Remove dependency with the arch_timer driver internals + - arm64: Fix compiler warning from pte_unmap() with -Wunused-but-set-variable + - sched/cpufreq: Fix kobject memleak + - scsi: qla2xxx: Fix a qla24xx_enable_msix() error path + - scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() + - scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in + tcm_qla2xxx_close_session() + - Btrfs: fix data bytes_may_use underflow with fallocate due to failed quota + reserve + - btrfs: fix panic during relocation after ENOSPC before writeback happens + - btrfs: Don't panic when we can't find a root key + - iwlwifi: pcie: don't crash on invalid RX interrupt + - rtc: 88pm860x: prevent use-after-free on device remove + - scsi: qedi: Abort ep termination if offload not scheduled + - w1: fix the resume command API + - dmaengine: pl330: _stop: clear interrupt status + - mac80211/cfg80211: update bss channel on channel switch + - libbpf: fix samples/bpf build failure due to undefined UINT32_MAX + - ASoC: fsl_sai: Update is_slave_mode with correct value + - mwifiex: prevent an array overflow + - net: cw1200: fix a NULL pointer dereference + - crypto: sun4i-ss - Fix invalid calculation of hash end + - bcache: return error immediately in bch_journal_replay() + - bcache: fix failure in journal relplay + - bcache: add failure check to run_cache_set() for journal replay + - bcache: avoid clang -Wunintialized warning + - vfio-ccw: Do not call flush_workqueue while holding the spinlock + - vfio-ccw: Release any channel program when releasing/removing vfio-ccw mdev + - smpboot: Place the __percpu annotation correctly + - x86/mm: Remove in_nmi() warning from 64-bit implementation of + vmalloc_fault() + - mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC + versions + - HID: logitech-hidpp: use RAP instead of FAP to get the protocol version + - pinctrl: pistachio: fix leaked of_node references + - pinctrl: samsung: fix leaked of_node references + - clk: rockchip: undo several noc and special clocks as critical on rk3288 + - dmaengine: at_xdmac: remove BUG_ON macro in tasklet + - media: coda: clear error return value before picture run + - media: ov6650: Move v4l2_clk_get() to ov6650_video_probe() helper + - media: au0828: stop video streaming only when last user stops + - media: ov2659: make S_FMT succeed even if requested format doesn't match + - audit: fix a memory leak bug + - media: stm32-dcmi: fix crash when subdev do not expose any formats + - media: au0828: Fix NULL pointer dereference in au0828_analog_stream_enable() + - media: pvrusb2: Prevent a buffer overflow + - powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX + - random: add a spinlock_t to struct batched_entropy + - cgroup: protect cgroup->nr_(dying_)descendants by css_set_lock + - sched/core: Check quota and period overflow at usec to nsec conversion + - sched/rt: Check integer overflow at usec to nsec conversion + - sched/core: Handle overflow in cpu_shares_write_u64 + - drm/msm: a5xx: fix possible object reference leak + - USB: core: Don't unbind interfaces following device reset failure + - x86/irq/64: Limit IST stack overflow check to #DB stack + - phy: sun4i-usb: Make sure to disable PHY0 passby for peripheral mode + - i40e: Able to add up to 16 MAC filters on an untrusted VF + - i40e: don't allow changes to HW VLAN stripping on active port VLANs + - arm64: vdso: Fix clock_getres() for CLOCK_REALTIME + - RDMA/cxgb4: Fix null pointer dereference on alloc_skb failure + - hwmon: (vt1211) Use request_muxed_region for Super-IO accesses + - hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses + - hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses + - hwmon: (pc87427) Use request_muxed_region for Super-IO accesses + - hwmon: (f71805f) Use request_muxed_region for Super-IO accesses + - scsi: libsas: Do discovery on empty PHY to update PHY info + - mmc: core: make pwrseq_emmc (partially) support sleepy GPIO controllers + - mmc_spi: add a status check for spi_sync_locked + - mmc: sdhci-of-esdhc: add erratum eSDHC5 support + - mmc: sdhci-of-esdhc: add erratum A-009204 support + - mmc: sdhci-of-esdhc: add erratum eSDHC-A001 and A-008358 support + - drm/amdgpu: fix old fence check in amdgpu_fence_emit + - PM / core: Propagate dev->power.wakeup_path when no callbacks + - clk: rockchip: Fix video codec clocks on rk3288 + - extcon: arizona: Disable mic detect if running when driver is removed + - clk: rockchip: Make rkpwm a critical clock on rk3288 + - s390: zcrypt: initialize variables before_use + - x86/microcode: Fix the ancient deprecated microcode loading method + - s390: cio: fix cio_irb declaration + - cpufreq: ppc_cbe: fix possible object reference leak + - cpufreq/pasemi: fix possible object reference leak + - cpufreq: pmac32: fix possible object reference leak + - cpufreq: kirkwood: fix possible object reference leak + - block: sed-opal: fix IOC_OPAL_ENABLE_DISABLE_MBR + - x86/build: Keep local relocations with ld.lld + - iio: ad_sigma_delta: Properly handle SPI bus locking vs CS assertion + - iio: hmc5843: fix potential NULL pointer dereferences + - iio: common: ssp_sensors: Initialize calculated_time in + ssp_common_process_data + - rtlwifi: fix a potential NULL pointer dereference + - mwifiex: Fix mem leak in mwifiex_tm_cmd + - brcmfmac: fix missing checks for kmemdup + - b43: shut up clang -Wuninitialized variable warning + - brcmfmac: convert dev_init_lock mutex to completion + - brcmfmac: fix WARNING during USB disconnect in case of unempty psq + - brcmfmac: fix race during disconnect when USB completion is in progress + - brcmfmac: fix Oops when bringing up interface during USB disconnect + - rtc: xgene: fix possible race condition + - rtlwifi: fix potential NULL pointer dereference + - scsi: ufs: Fix regulator load and icc-level configuration + - scsi: ufs: Avoid configuring regulator with undefined voltage range + - arm64: cpu_ops: fix a leaked reference by adding missing of_node_put + - x86/uaccess, signal: Fix AC=1 bloat + - x86/ia32: Fix ia32_restore_sigcontext() AC leak + - chardev: add additional check for minor range overlap + - RDMA/hns: Fix bad endianess of port_pd variable + - HID: core: move Usage Page concatenation to Main item + - ASoC: eukrea-tlv320: fix a leaked reference by adding missing of_node_put + - ASoC: fsl_utils: fix a leaked reference by adding missing of_node_put + - cxgb3/l2t: Fix undefined behaviour + - HID: logitech-hidpp: change low battery level threshold from 31 to 30 + percent + - spi: tegra114: reset controller on probe + - kobject: Don't trigger kobject_uevent(KOBJ_REMOVE) twice. + - media: video-mux: fix null pointer dereferences + - media: wl128x: prevent two potential buffer overflows + - scsi: qedf: Add missing return in qedf_post_io_req() in the fcport offload + check + - virtio_console: initialize vtermno value for ports + - tty: ipwireless: fix missing checks for ioremap + - x86/mce: Fix machine_check_poll() tests for error types + - rcutorture: Fix cleanup path for invalid torture_type strings + - rcuperf: Fix cleanup path for invalid perf_type strings + - usb: core: Add PM runtime calls to usb_hcd_platform_shutdown + - scsi: qla4xxx: avoid freeing unallocated dma memory + - batman-adv: allow updating DAT entry timeouts on incoming ARP Replies + - dmaengine: tegra210-adma: use devm_clk_*() helpers + - hwrng: omap - Set default quality + - thunderbolt: Fix to check for kmemdup failure + - media: m88ds3103: serialize reset messages in m88ds3103_set_frontend + - media: vimc: stream: fix thread state before sleep + - media: go7007: avoid clang frame overflow warning with KASAN + - media: vimc: zero the media_device on probe + - scsi: lpfc: Fix FDMI manufacturer attribute value + - scsi: lpfc: Fix fc4type information for FDMI + - media: saa7146: avoid high stack usage with clang + - scsi: lpfc: Fix SLI3 commands being issued on SLI4 devices + - spi : spi-topcliff-pch: Fix to handle empty DMA buffers + - spi: rspi: Fix sequencer reset during initialization + - spi: Fix zero length xfer bug + - ASoC: davinci-mcasp: Fix clang warning without CONFIG_PM + - drm/drv: Hold ref on parent device during drm_device lifetime + - drm: Wake up next in drm_read() chain if we are forced to putback the event + - vfio-ccw: Prevent quiesce function going into an infinite loop + - NFS: Fix a double unlock from nfs_match,get_client + - ext4: wait for outstanding dio during truncate in nojournal mode + - NFSv4.1 fix incorrect return value in copy_file_range + - media: vb2: add waiting_in_dqbuf flag + - acct_on(): don't mess with freeze protection + - hv_netvsc: fix race that may miss tx queue wakeup + - Bluetooth: Ignore CC events not matching the last HCI command + - powerpc/perf: Fix loop exit condition in nest_imc_event_init + - drm/nouveau/bar/nv50: ensure BAR is mapped + - media: stm32-dcmi: return appropriate error codes during probe + - powerpc/watchdog: Use hrtimers for per-CPU heartbeat + - scsi: qla2xxx: Fix hardirq-unsafe locking + - x86/modules: Avoid breaking W^X while loading modules + - sched/nohz: Run NOHZ idle load balancer on HK_FLAG_MISC CPUs + - s390: qeth: address type mismatch warning + - rsi: Fix NULL pointer dereference in kmalloc + - nvme: set 0 capacity if namespace block size exceeds PAGE_SIZE + - bcache: avoid potential memleak of list of journal_replay(s) in the + CACHE_SYNC branch of run_cache_set + - RDMA/cma: Consider scope_id while binding to ipv6 ll address + - block: fix use-after-free on gendisk + - staging: vc04_services: handle kzalloc failure + - irq_work: Do not raise an IPI when queueing work on the local CPU + - thunderbolt: Take domain lock in switch sysfs attribute callbacks + - drm: etnaviv: avoid DMA API warning when importing buffers + - ACPI/IORT: Reject platform device creation on NUMA node mapping failure + - perf/x86/msr: Add Icelake support + - perf/x86/intel/rapl: Add Icelake support + - perf/x86/intel/cstate: Add Icelake support + - drm/panel: otm8009a: Add delay at the end of initialization + - thunderbolt: property: Fix a missing check of kzalloc + - thunderbolt: Fix to check the return value of kmemdup + - x86/mce: Handle varying MCA bank counts + - scsi: lpfc: avoid uninitialized variable warning + - thunderbolt: Fix to check return value of ida_simple_get + - drm/amd/display: fix releasing planes when exiting odm + - thunderbolt: property: Fix a NULL pointer dereference + - e1000e: Disable runtime PM on CNP+ + - igb: Exclude device from suspend direct complete optimization + - media: si2165: fix a missing check of return value + - drm/amd/display: Fix Divide by 0 in memory calculations + - spi: imx: stop buffer overflow in RX FIFO flush + - bonding/802.3ad: fix slave link initialization transition states + - cxgb4: offload VLAN flows regardless of VLAN ethtype + - inet: switch IP ID generator to siphash + - ipv4/igmp: fix another memory leak in igmpv3_del_delrec() + - ipv4/igmp: fix build error if !CONFIG_IP_MULTICAST + - ipv6: Consider sk_bound_dev_if when binding a raw socket to an address + - llc: fix skb leak in llc_build_and_send_ui_pkt() + - net: dsa: mv88e6xxx: fix handling of upper half of STATS_TYPE_PORT + - net: fec: fix the clk mismatch in failed_reset path + - net-gro: fix use-after-free read in napi_gro_frags() + - net: mvneta: Fix err code path of probe + - net: mvpp2: fix bad MVPP2_TXQ_SCHED_TOKEN_CNTR_REG queue value + - net: phy: marvell10g: report if the PHY fails to boot firmware + - net: stmmac: fix reset gpio free missing + - usbnet: fix kernel crash after disconnect + - tipc: Avoid copying bytes beyond the supplied data + - net/mlx5: Allocate root ns memory using kzalloc to match kfree + - bnxt_en: Fix aggregation buffer leak under OOM condition. + - crypto: vmx - ghash: do nosimd fallback manually + - include/linux/compiler*.h: define asm_volatile_goto + - compiler.h: give up __compiletime_assert_fallback() + - xen/pciback: Don't disable PCI_COMMAND on PCI device reset. + - tipc: fix modprobe tipc failed after switch order of device registration + - sparc64: Fix regression in non-hypervisor TLB flush xcall + - include/linux/bitops.h: sanitize rotate primitives + - xhci: update bounce buffer with correct sg num + - xhci: Use %zu for printing size_t type + - xhci: Convert xhci_handshake() to use readl_poll_timeout_atomic() + - usb: xhci: avoid null pointer deref when bos field is NULL + - usbip: usbip_host: fix BUG: sleeping function called from invalid context + - usbip: usbip_host: fix stub_dev lock context imbalance regression + - USB: Fix slab-out-of-bounds write in usb_get_bos_descriptor + - USB: sisusbvga: fix oops in error path of sisusb_probe + - USB: Add LPM quirk for Surface Dock GigE adapter + - USB: rio500: refuse more than one device at a time + - USB: rio500: fix memory leak in close after disconnect + - media: usb: siano: Fix general protection fault in smsusb + - media: usb: siano: Fix false-positive "uninitialized variable" warning + - media: smsusb: better handle optional alignment + - scsi: zfcp: fix missing zfcp_port reference put on -EBUSY from port_remove + - scsi: zfcp: fix to prevent port_remove with pure auto scan LUNs (only sdevs) + - Btrfs: fix wrong ctime and mtime of a directory after log replay + - Btrfs: fix race updating log root item during fsync + - Btrfs: fix fsync not persisting changed attributes of a directory + - Btrfs: incremental send, fix file corruption when no-holes feature is + enabled + - KVM: PPC: Book3S HV: XIVE: Do not clear IRQ data of passthrough interrupts + - powerpc/perf: Fix MMCRA corruption by bhrb_filter + - ALSA: hda/realtek - Set default power save node to 0 + - KVM: s390: Do not report unusabled IDs via KVM_CAP_MAX_VCPU_ID + - drm/nouveau/i2c: Disable i2c bus access after ->fini() + - tty: serial: msm_serial: Fix XON/XOFF + - tty: max310x: Fix external crystal register setup + - memcg: make it work on sparse non-0-node systems + - kernel/signal.c: trace_signal_deliver when signal_group_exit + - docs: Fix conf.py for Sphinx 2.0 + - doc: Cope with the deprecation of AutoReporter + - doc: Cope with Sphinx logging deprecations + - ima: show rules with IMA_INMASK correctly + - serial: sh-sci: disable DMA for uart_console + - staging: vc04_services: prevent integer overflow in create_pagelist() + - staging: wlan-ng: fix adapter initialization failure + - CIFS: cifs_read_allocate_pages: don't iterate through whole page array on + ENOMEM + - gcc-plugins: Fix build failures under Darwin host + - drm/vmwgfx: Don't send drm sysfs hotplug events on initial master set + - drm/rockchip: shutdown drm subsystem on shutdown + - Compiler Attributes: add support for __copy (gcc >= 9) + - include/linux/module.h: copy __init/__exit attrs to init/cleanup_module + - binder: fix race between munmap() and direct reclaim + - media: uvcvideo: Fix uvc_alloc_entity() allocation alignment + - brcmfmac: fix NULL pointer derefence during USB disconnect + - iio: dac: ds4422/ds4424 fix chip verification + - s390/crypto: fix possible sleep during spinlock aquired + - ALSA: line6: Assure canceling delayed work at disconnection + - vt/fbcon: deinitialize resources in visual_init() after failed memory + allocation + - cifs: fix memory leak of pneg_inbuf on -EOPNOTSUPP ioctl case + - x86/ftrace: Do not call function graph from dynamic trampolines + - x86/ftrace: Set trampoline pages as executable + - x86/kprobes: Set instruction page as executable + - of: overlay: validate overlay properties #address-cells and #size-cells + - of: overlay: set node fields from properties when add new overlay node + - ethtool: fix potential userspace buffer overflow + - Fix memory leak in sctp_process_init + - neighbor: Call __ipv4_neigh_lookup_noref in neigh_xmit + - net/mlx4_en: ethtool, Remove unsupported SFP EEPROM high pages query + - net: rds: fix memory leak in rds_ib_flush_mr_pool + - pktgen: do not sleep with the thread lock held. + - ipv6: fix EFAULT on sendto with icmpv6 and hdrincl + - ipv6: use READ_ONCE() for inet->hdrincl as in ipv4 + - net: sfp: read eeprom in maximum 16 byte increments + - ipv6: fix the check before getting the cookie in rt6_get_cookie + - rcu: locking and unlocking need to always be at least barriers + - parisc: Use implicit space register selection for loading the coherence + index of I/O pdirs + - fuse: fallocate: fix return with locked inode + - pstore: Remove needless lock during console writes + - pstore: Convert buf_lock to semaphore + - pstore/ram: Run without kernel crash dump region + - x86/power: Fix 'nosmt' vs hibernation triple fault during resume + - i2c: xiic: Add max_read_len quirk + - MIPS: Bounds check virt_addr_valid + - MIPS: pistachio: Build uImage.gz by default + - genwqe: Prevent an integer overflow in the ioctl + - test_firmware: Use correct snprintf() limit + - drm/gma500/cdv: Check vbt config bits when detecting lvds panels + - drm/amdgpu/psp: move psp version specific function pointers to early_init + - drm/i915: Fix I915_EXEC_RING_MASK + - drm/i915/fbc: disable framebuffer compression on GeminiLake + - TTY: serial_core, add ->install + - qmi_wwan: Add quirk for Quectel dynamic config + - ipv4: Define __ipv4_neigh_lookup_noref when CONFIG_INET is disabled + - ethtool: check the return value of get_regs_len + - net: ethernet: ti: cpsw_ethtool: fix ethtool ring param set + - net: mvpp2: Use strscpy to handle stat strings + - packet: unconditionally free po->rollover + - NFSv4.1: Again fix a race where CB_NOTIFY_LOCK fails to wake a waiter + - NFSv4.1: Fix bug only first CB_NOTIFY_LOCK is handled + - s390/mm: fix address space detection in exception handling + - drm/msm: fix fb references in async update + - drm: add non-desktop quirk for Valve HMDs + - drm: add non-desktop quirks to Sensics and OSVR headsets. + - drm/amdgpu: remove ATPX_DGPU_REQ_POWER_FOR_DISPLAYS check when hotplug-in + * CVE-2019-14283 + - floppy: fix out-of-bounds read in copy_buffer + * CVE-2019-14284 + - floppy: fix div-by-zero in setup_format_params + * Bionic linux 4.15.0-56.62 fails to build with CONFIG_NVM disabled + (LP: #1838533) + - Revert "nvme: warn when finding multi-port subsystems without multipathing + enabled" + * Bionic update: upstream stable patchset 2019-07-31 (LP: #1838576) + - netfilter: compat: initialize all fields in xt_init + - platform/x86: sony-laptop: Fix unintentional fall-through + - platform/x86: thinkpad_acpi: Disable Bluetooth for some machines + - hwmon: (pwm-fan) Disable PWM if fetching cooling data fails + - kernfs: fix barrier usage in __kernfs_new_node() + - USB: serial: fix unthrottle races + - iio: adc: xilinx: fix potential use-after-free on remove + - libnvdimm/namespace: Fix a potential NULL pointer dereference + - HID: input: add mapping for Expose/Overview key + - HID: input: add mapping for keyboard Brightness Up/Down/Toggle keys + - HID: input: add mapping for "Toggle Display" key + - libnvdimm/btt: Fix a kmemdup failure check + - s390/dasd: Fix capacity calculation for large volumes + - mac80211: fix unaligned access in mesh table hash function + - mac80211: Increase MAX_MSG_LEN + - mac80211: fix memory accounting with A-MSDU aggregation + - nl80211: Add NL80211_FLAG_CLEAR_SKB flag for other NL commands + - s390/3270: fix lockdep false positive on view->lock + - clocksource/drivers/oxnas: Fix OX820 compatible + - mISDN: Check address length before reading address family + - s390/pkey: add one more argument space for debug feature entry + - x86/reboot, efi: Use EFI reboot for Acer TravelMate X514-51T + - KVM: fix spectrev1 gadgets + - KVM: x86: avoid misreporting level-triggered irqs as edge-triggered in + tracing + - tools lib traceevent: Fix missing equality check for strcmp + - mm: fix inactive list balancing between NUMA nodes and cgroups + - init: initialize jump labels before command line option parsing + - selftests: netfilter: check icmp pkttoobig errors are set as related + - ipvs: do not schedule icmp errors from tunnels + - netfilter: ctnetlink: don't use conntrack/expect object addresses as id + - s390: ctcm: fix ctcm_new_device error return code + - drm/sun4i: Set device driver data at bind time for use in unbind + - gpu: ipu-v3: dp: fix CSC handling + - drm/imx: don't skip DP channel disable for background plane + - spi: Micrel eth switch: declare missing of table + - spi: ST ST95HF NFC: declare missing of table + - Input: synaptics-rmi4 - fix possible double free + - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit + - ima: open a new file instance if no read permissions + - drm/i915: Disable LP3 watermarks on all SNB machines + - net: stmmac: Move debugfs init/exit to ->probe()/->remove() + - x86/vdso: Pass --eh-frame-hdr to the linker + - mm/memory.c: fix modifying of page protection by insert_pfn() + - net: fec: manage ahb clock in runtime pm + - mlxsw: spectrum_switchdev: Add MDB entries in prepare phase + - mlxsw: core: Do not use WQ_MEM_RECLAIM for EMAD workqueue + - mlxsw: core: Do not use WQ_MEM_RECLAIM for mlxsw ordered workqueue + - mlxsw: core: Do not use WQ_MEM_RECLAIM for mlxsw workqueue + - NFC: nci: Add some bounds checking in nci_hci_cmd_received() + - nfc: nci: Potential off by one in ->pipes[] array + - x86/kprobes: Avoid kretprobe recursion bug + - cw1200: fix missing unlock on error in cw1200_hw_scan() + - mwl8k: Fix rate_idx underflow + - rtlwifi: rtl8723ae: Fix missing break in switch statement + - bonding: fix arp_validate toggling in active-backup mode + - bridge: Fix error path for kobject_init_and_add() + - dpaa_eth: fix SG frame cleanup + - ipv4: Fix raw socket lookup for local traffic + - net: dsa: Fix error cleanup path in dsa_init_module + - net: ethernet: stmmac: dwmac-sun8i: enable support of unicast filtering + - net: seeq: fix crash caused by not set dev.parent + - net: ucc_geth - fix Oops when changing number of buffers in the ring + - packet: Fix error path in packet_init + - vlan: disable SIOCSHWTSTAMP in container + - vrf: sit mtu should not be updated when vrf netdev is the link + - tipc: fix hanging clients using poll with EPOLLOUT flag + - drivers/virt/fsl_hypervisor.c: dereferencing error pointers in ioctl + - drivers/virt/fsl_hypervisor.c: prevent integer overflow in ioctl + - powerpc/powernv/idle: Restore IAMR after idle + - powerpc/booke64: set RI in default MSR + - platform/x86: dell-laptop: fix rfkill functionality + - iio: adc: xilinx: fix potential use-after-free on probe + - iio: adc: xilinx: prevent touching unclocked h/w on remove + - acpi/nfit: Always dump _DSM output payload + - libnvdimm/pmem: fix a possible OOB access when read and write pmem + - vxge: fix return of a free'd memblock on a failed dma mapping + - qede: fix write to free'd pointer error and double free of ptp + - afs: Unlock pages for __pagevec_release() + - ipmi: ipmi_si_hardcode.c: init si_type array to fix a crash + - scsi: aic7xxx: fix EISA support + - drm/sun4i: Fix component unbinding and component master deletion + - netfilter: fix nf_l4proto_log_invalid to log invalid packets + - drm/sun4i: Unbind components before releasing DRM and memory + - usb: typec: Fix unchecked return value + - netfilter: nf_tables: use-after-free in dynamic operations + - um: Don't hardcode path as it is architecture dependent + - powerpc/book3s/64: check for NULL pointer in pgd_alloc() + - PCI: hv: Add hv_pci_remove_slots() when we unload the driver + - PCI: hv: Add pci_destroy_slot() in pci_devices_present_work(), if necessary + - net: core: another layer of lists, around PF_MEMALLOC skb handling + - locking/rwsem: Prevent decrement of reader count before increment + - PCI: hv: Fix a memory leak in hv_eject_device_work() + - x86/speculation/mds: Revert CPU buffer clear on double fault exit + - x86/speculation/mds: Improve CPU buffer clear documentation + - objtool: Fix function fallthrough detection + - ARM: dts: exynos: Fix interrupt for shared EINTs on Exynos5260 + - ARM: dts: exynos: Fix audio (microphone) routing on Odroid XU3 + - ARM: exynos: Fix a leaked reference by adding missing of_node_put + - power: supply: axp288_charger: Fix unchecked return value + - arm64: compat: Reduce address limit + - arm64: Clear OSDLR_EL1 on CPU boot + - arm64: Save and restore OSDLR_EL1 across suspend/resume + - sched/x86: Save [ER]FLAGS on context switch + - crypto: chacha20poly1305 - set cra_name correctly + - crypto: vmx - fix copy-paste error in CTR mode + - crypto: skcipher - don't WARN on unprocessed data after slow walk step + - crypto: crct10dif-generic - fix use via crypto_shash_digest() + - crypto: x86/crct10dif-pcl - fix use via crypto_shash_digest() + - crypto: gcm - fix incompatibility between "gcm" and "gcm_base" + - crypto: rockchip - update IV buffer to contain the next IV + - crypto: arm/aes-neonbs - don't access already-freed walk.iv + - ALSA: usb-audio: Fix a memory leak bug + - ALSA: hda/realtek - EAPD turn on later + - ASoC: max98090: Fix restore of DAPM Muxes + - ASoC: RT5677-SPI: Disable 16Bit SPI Transfers + - bpf, arm64: remove prefetch insn in xadd mapping + - mm/mincore.c: make mincore() more conservative + - ocfs2: fix ocfs2 read inode data panic in ocfs2_iget + - userfaultfd: use RCU to free the task struct when fork fails + - mfd: da9063: Fix OTP control register names to match datasheets for + DA9063/63L + - mfd: max77620: Fix swapped FPS_PERIOD_MAX_US values + - mtd: spi-nor: intel-spi: Avoid crossing 4K address boundary on read/write + - tty: vt.c: Fix TIOCL_BLANKSCREEN console blanking if blankinterval == 0 + - tty/vt: fix write/write race in ioctl(KDSKBSENT) handler + - jbd2: check superblock mapped prior to committing + - ext4: make sanity check in mballoc more strict + - ext4: ignore e_value_offs for xattrs with value-in-ea-inode + - ext4: avoid drop reference to iloc.bh twice + - Btrfs: do not start a transaction during fiemap + - Btrfs: do not start a transaction at iterate_extent_inodes() + - bcache: fix a race between cache register and cacheset unregister + - bcache: never set KEY_PTRS of journal key to 0 in journal_reclaim() + - ext4: fix use-after-free race with debug_want_extra_isize + - ext4: actually request zeroing of inode table after grow + - ext4: fix ext4_show_options for file systems w/o journal + - ipmi:ssif: compare block number correctly for multi-part return messages + - crypto: arm64/aes-neonbs - don't access already-freed walk.iv + - crypto: salsa20 - don't access already-freed walk.iv + - crypto: ccm - fix incompatibility between "ccm" and "ccm_base" + - fs/writeback.c: use rcu_barrier() to wait for inflight wb switches going + into workqueue when umount + - ext4: fix data corruption caused by overlapping unaligned and aligned IO + - ext4: fix use-after-free in dx_release() + - ALSA: hda/realtek - Fix for Lenovo B50-70 inverted internal microphone bug + - KVM: x86: Skip EFER vs. guest CPUID checks for host-initiated writes + - iov_iter: optimize page_copy_sane() + - ext4: fix compile error when using BUFFER_TRACE + - arm64: dts: rockchip: Disable DCMDs on RK3399's eMMC controller. + - arm64: mmap: Ensure file offset is treated as unsigned + - arm64: arch_timer: Ensure counter register reads occur with seqlock held + - crypto: crypto4xx - fix ctr-aes missing output IV + - crypto: crypto4xx - fix cfb and ofb "overran dst buffer" issues + - ALSA: line6: toneport: Fix broken usage of timer for delayed execution + - ASoC: fsl_esai: Fix missing break in switch statement + - mm/huge_memory: fix vmf_insert_pfn_{pmd, pud}() crash, handle unaligned + addresses + - hugetlb: use same fault hash key for shared and private mappings + - ACPI: PM: Set enable_for_wake for wakeup GPEs during suspend-to-idle + - btrfs: Correctly free extent buffer in case btree_read_extent_buffer_pages + fails + - ext4: avoid panic during forced reboot due to aborted journal + - libnvdimm/namespace: Fix label tracking error + - ext4: don't update s_rev_level if not required + - net: avoid weird emergency message + - net/mlx4_core: Change the error print to info print + - net: test nouarg before dereferencing zerocopy pointers + - net: usb: qmi_wwan: add Telit 0x1260 and 0x1261 compositions + - ppp: deflate: Fix possible crash in deflate_init + - tipc: switch order of device registration to fix a crash + - vsock/virtio: free packets during the socket release + - vsock/virtio: Initialize core virtio vsock before registering the driver + - net: Always descend into dsa/ + - parisc: Export running_on_qemu symbol for modules + - parisc: Skip registering LED when running in QEMU + - parisc: Use PA_ASM_LEVEL in boot code + - parisc: Rename LEVEL to PA_ASM_LEVEL to avoid name clash with DRBD code + - stm class: Fix channel free in stm output free path + - md: add mddev->pers to avoid potential NULL pointer dereference + - intel_th: msu: Fix single mode with IOMMU + - p54: drop device reference count if fails to enable device + - of: fix clang -Wunsequenced for be32_to_cpu() + - media: ov6650: Fix sensor possibly not detected on probe + - NFS4: Fix v4.0 client state corruption when mount + - PNFS fallback to MDS if no deviceid found + - clk: hi3660: Mark clk_gate_ufs_subsys as critical + - clk: tegra: Fix PLLM programming on Tegra124+ when PMC overrides divider + - clk: rockchip: fix wrong clock definitions for rk3328 + - fuse: fix writepages on 32bit + - fuse: honor RLIMIT_FSIZE in fuse_file_fallocate + - iommu/tegra-smmu: Fix invalid ASID bits on Tegra30/114 + - ceph: flush dirty inodes before proceeding with remount + - x86_64: Add gap to int3 to allow for call emulation + - x86_64: Allow breakpoints to emulate call instructions + - ftrace/x86_64: Emulate call function while updating in breakpoint handler + - tracing: Fix partial reading of trace event's id file + - memory: tegra: Fix integer overflow on tick value calculation + - perf intel-pt: Fix instructions sampling rate + - perf intel-pt: Fix improved sample timestamp + - perf intel-pt: Fix sample timestamp wrt non-taken branches + - objtool: Allow AR to be overridden with HOSTAR + - fbdev: sm712fb: fix brightness control on reboot, don't set SR30 + - fbdev: sm712fb: fix VRAM detection, don't set SR70/71/74/75 + - fbdev: sm712fb: fix white screen of death on reboot, don't set CR3B-CR3F + - fbdev: sm712fb: fix boot screen glitch when sm712fb replaces VGA + - fbdev: sm712fb: fix crashes during framebuffer writes by correctly mapping + VRAM + - fbdev: sm712fb: fix support for 1024x768-16 mode + - fbdev: sm712fb: use 1024x768 by default on non-MIPS, fix garbled display + - fbdev: sm712fb: fix crashes and garbled display during DPMS modesetting + - PCI: Mark AMD Stoney Radeon R7 GPU ATS as broken + - PCI: Mark Atheros AR9462 to avoid bus reset + - PCI: Factor out pcie_retrain_link() function + - PCI: Work around Pericom PCIe-to-PCI bridge Retrain Link erratum + - dm cache metadata: Fix loading discard bitset + - dm zoned: Fix zone report handling + - dm delay: fix a crash when invalid device is specified + - xfrm: policy: Fix out-of-bound array accesses in __xfrm_policy_unlink + - xfrm6_tunnel: Fix potential panic when unloading xfrm6_tunnel module + - vti4: ipip tunnel deregistration fixes. + - esp4: add length check for UDP encapsulation + - xfrm4: Fix uninitialized memory read in _decode_session4 + - power: supply: cpcap-battery: Fix division by zero + - securityfs: fix use-after-free on symlink traversal + - apparmorfs: fix use-after-free on symlink traversal + - mac80211: Fix kernel panic due to use of txq after free + - KVM: arm/arm64: Ensure vcpu target is unset on reset failure + - power: supply: sysfs: prevent endless uevent loop with + CONFIG_POWER_SUPPLY_DEBUG + - iwlwifi: mvm: check for length correctness in iwl_mvm_create_skb() + - sched/cpufreq: Fix kobject memleak + - x86/mm/mem_encrypt: Disable all instrumentation for early SME setup + - ufs: fix braino in ufs_get_inode_gid() for solaris UFS flavour + - perf bench numa: Add define for RUSAGE_THREAD if not present + - md/raid: raid5 preserve the writeback action after the parity check + - driver core: Postpone DMA tear-down until after devres release for probe + failure + - bpf: add map_lookup_elem_sys_only for lookups from syscall side + - bpf, lru: avoid messing with eviction heuristics upon syscall lookup + - fbdev: sm712fb: fix memory frequency by avoiding a switch/case fallthrough + - nfp: flower: add rcu locks when accessing netdev for tunnels + - rtnetlink: always put IFLA_LINK for links with a link-netnsid + - brd: re-enable __GFP_HIGHMEM in brd_insert_page() + - proc: prevent changes to overridden credentials + - md: batch flush requests. + - phy: ti-pipe3: fix missing bit-wise or operator when assigning val + - clk: mediatek: Disable tuner_en before change PLL rate + - PCI: rcar: Add the initialization of PCIe link in resume_noirq() + - fuse: Add FOPEN_STREAM to use stream_open() + - qmi_wwan: new Wistron, ZTE and D-Link devices + - bpf: relax inode permission check for retrieving bpf program + * Bionic update: upstream stable patchset 2019-07-30 (LP: #1838459) + - kbuild: simplify ld-option implementation + - cifs: do not attempt cifs operation on smb2+ rename error + - tracing: Fix a memory leak by early error exit in trace_pid_write() + - tracing: Fix buffer_ref pipe ops + - zram: pass down the bvec we need to read into in the work struct + - lib/Kconfig.debug: fix build error without CONFIG_BLOCK + - MIPS: scall64-o32: Fix indirect syscall number load + - trace: Fix preempt_enable_no_resched() abuse + - IB/rdmavt: Fix frwr memory registration + - sched/numa: Fix a possible divide-by-zero + - ceph: only use d_name directly when parent is locked + - ceph: ensure d_name stability in ceph_dentry_hash() + - ceph: fix ci->i_head_snapc leak + - nfsd: Don't release the callback slot unless it was actually held + - sunrpc: don't mark uninitialised items as VALID. + - Input: synaptics-rmi4 - write config register values to the right offset + - dmaengine: sh: rcar-dmac: With cyclic DMA residue 0 is valid + - ARM: 8857/1: efi: enable CP15 DMB instructions before cleaning the cache + - drm/vc4: Fix memory leak during gpu reset. + - drm/vc4: Fix compilation error reported by kbuild test bot + - ext4: fix some error pointer dereferences + - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock + - tipc: handle the err returned from cmd header function + - slip: make slhc_free() silently accept an error pointer + - intel_th: gth: Fix an off-by-one in output unassigning + - fs/proc/proc_sysctl.c: Fix a NULL pointer dereference + - ipvs: fix warning on unused variable + - sched/deadline: Correctly handle active 0-lag timers + - NFS: Forbid setting AF_INET6 to "struct sockaddr_in"->sin_family. + - netfilter: ebtables: CONFIG_COMPAT: drop a bogus WARN_ON + - fm10k: Fix a potential NULL pointer dereference + - tipc: check bearer name with right length in tipc_nl_compat_bearer_enable + - tipc: check link name with right length in tipc_nl_compat_link_set + - x86, retpolines: Raise limit for generating indirect calls from switch-case + - x86/retpolines: Disable switch jump tables when retpolines are enabled + - mm: Fix warning in insert_pfn() + - ipv4: add sanity checks in ipv4_link_failure() + - mlxsw: spectrum: Fix autoneg status in ethtool + - net/mlx5e: ethtool, Remove unsupported SFP EEPROM high pages query + - net: rds: exchange of 8K and 1M pool + - net: stmmac: move stmmac_check_ether_addr() to driver probe + - stmmac: pci: Adjust IOT2000 matching + - team: fix possible recursive locking when add slaves + - net/rose: fix unbound loop in rose_loopback_timer() + - ipv4: set the tcp_min_rtt_wlen range from 0 to one day + - powerpc/fsl: Add FSL_PPC_BOOK3E as supported arch for nospectre_v2 boot arg + - Documentation: Add nospectre_v1 parameter + - netfilter: nf_tables: warn when expr implements only one of + activate/deactivate + - net/ibmvnic: Fix RTNL deadlock during device reset + - drm/rockchip: fix for mailbox read validation. + - powerpc/vdso32: fix CLOCK_MONOTONIC on PPC64 + - perf/x86/intel: Enable C-state residency events for Cannon Lake + - perf/x86/intel: Update KBL Package C-state events to also include + PC8/PC9/PC10 counters + - powerpc/mm/radix: Make Radix require HUGETLB_PAGE + - workqueue: Try to catch flush_work() without INIT_WORK(). + - mlxsw: pci: Reincrease PCI reset timeout + - mm: make page ref count overflow check tighter and more explicit + - mm: add 'try_get_page()' helper function + - mm: prevent get_user_pages() from overflowing page refcount + - fs: prevent page refcount overflow in pipe_buf_get + - ARM: dts: bcm283x: Fix hdmi hpd gpio pull + - s390: limit brk randomization to 32MB + - qlcnic: Avoid potential NULL pointer dereference + - netfilter: nft_set_rbtree: check for inactive element after flag mismatch + - netfilter: bridge: set skb transport_header before entering + NF_INET_PRE_ROUTING + - s390/qeth: fix race when initializing the IP address table + - sc16is7xx: missing unregister/delete driver on error in sc16is7xx_init() + - serial: ar933x_uart: Fix build failure with disabled console + - KVM: arm/arm64: vgic-its: Take the srcu lock when parsing the memslots + - usb: gadget: net2280: Fix overrun of OUT messages + - usb: gadget: net2280: Fix net2280_dequeue() + - usb: gadget: net2272: Fix net2272_dequeue() + - ARM: dts: pfla02: increase phy reset duration + - net: ks8851: Dequeue RX packets explicitly + - net: ks8851: Reassert reset pin if chip ID check fails + - net: ks8851: Delay requesting IRQ until opened + - net: ks8851: Set initial carrier state to down + - staging: rtl8188eu: Fix potential NULL pointer dereference of kcalloc + - staging: rtlwifi: rtl8822b: fix to avoid potential NULL pointer dereference + - staging: rtl8712: uninitialized memory in read_bbreg_hdl() + - staging: rtlwifi: Fix potential NULL pointer dereference of kzalloc + - net: macb: Add null check for PCLK and HCLK + - net/sched: don't dereference a->goto_chain to read the chain index + - ARM: dts: imx6qdl: Fix typo in imx6qdl-icore-rqs.dtsi + - NFS: Fix a typo in nfs_init_timeout_values() + - net: xilinx: fix possible object reference leak + - net: ibm: fix possible object reference leak + - net: ethernet: ti: fix possible object reference leak + - gpio: aspeed: fix a potential NULL pointer dereference + - drm/meson: Fix invalid pointer in meson_drv_unbind() + - drm/meson: Uninstall IRQ handler + - scsi: qla4xxx: fix a potential NULL pointer dereference + - usb: usb251xb: fix to avoid potential NULL pointer dereference + - usb: u132-hcd: fix resource leak + - ceph: fix use-after-free on symlink traversal + - scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN + - libata: fix using DMA buffers on stack + - gpio: of: Fix of_gpiochip_add() error path + - kconfig/[mn]conf: handle backspace (^H) key + - ptrace: take into account saved_sigmask in PTRACE{GET,SET}SIGMASK + - leds: pca9532: fix a potential NULL pointer dereference + - KVM: arm64: Reset the PMU in preemptible context + - KVM: arm/arm64: vgic-its: Take the srcu lock when writing to guest memory + - scsi: aacraid: Insure we don't access PCIe space during AER/EEH + - x86/realmode: Don't leak the trampoline kernel address + - x86/mm: Don't exceed the valid physical address space + - ipv4: ip_do_fragment: Preserve skb_iif during fragmentation + - ipv6/flowlabel: wait rcu grace period before put_pid() + - ipv6: invert flowlabel sharing check in process and user mode + - l2ip: fix possible use-after-free + - l2tp: use rcu_dereference_sk_user_data() in l2tp_udp_encap_recv() + - net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc + - net: phy: marvell: Fix buffer overrun with stats counters + - sctp: avoid running the sctp state machine recursively + - packet: validate msg_namelen in send directly + - bnxt_en: Improve multicast address setup logic. + - bnxt_en: Free short FW command HWRM memory in error path in bnxt_init_one() + - ALSA: line6: use dynamic buffers + - rxrpc: Fix net namespace cleanup + - kasan: remove redundant initialization of variable 'real_size' + - kasan: prevent compiler from optimizing away memset in tests + - caif: reduce stack size with KASAN + - ALSA: hda/realtek - Add new Dell platform for headset mode + - USB: yurex: Fix protection fault after device removal + - USB: w1 ds2490: Fix bug caused by improper use of altsetting array + - usb: usbip: fix isoc packet num validation in get_pipe + - USB: core: Fix unterminated string returned by usb_string() + - USB: core: Fix bug caused by duplicate interface PM usage counter + - nvme-loop: init nvmet_ctrl fatal_err_work when allocate + - HID: logitech: check the return value of create_singlethread_workqueue + - HID: debug: fix race condition with between rdesc_show() and device removal + - rtc: sh: Fix invalid alarm warning for non-enabled alarm + - batman-adv: Reduce claim hash refcnt only for removed entry + - batman-adv: Reduce tt_local hash refcnt only for removed entry + - batman-adv: Reduce tt_global hash refcnt only for removed entry + - ARM: dts: rockchip: Fix gpu opp node names for rk3288 + - net/mlx5: E-Switch, Fix esw manager vport indication for more vport commands + - bonding: show full hw address in sysfs for slave entries + - net: stmmac: ratelimit RX error logs + - net: stmmac: don't overwrite discard_frame status + - net: stmmac: fix dropping of multi-descriptor RX frames + - net: stmmac: don't log oversized frames + - jffs2: fix use-after-free on symlink traversal + - debugfs: fix use-after-free on symlink traversal + - rtc: da9063: set uie_unsupported when relevant + - HID: input: add mapping for Assistant key + - vfio/pci: use correct format characters + - scsi: core: add new RDAC LENOVO/DE_Series device + - scsi: storvsc: Fix calculation of sub-channel count + - net: hns: Fix WARNING when remove HNS driver with SMMU enabled + - kmemleak: powerpc: skip scanning holes in the .bss section + - hugetlbfs: fix memory leak for resv_map + - sh: fix multiple function definition build errors + - xsysace: Fix error handling in ace_setup + - ARM: orion: don't use using 64-bit DMA masks + - ARM: iop: don't use using 64-bit DMA masks + - perf/x86/amd: Update generic hardware cache events for Family 17h + - Bluetooth: btusb: request wake pin with NOAUTOEN + - staging: iio: adt7316: allow adt751x to use internal vref for all dacs + - staging: iio: adt7316: fix the dac read calculation + - staging: iio: adt7316: fix the dac write calculation + - scsi: RDMA/srpt: Fix a credit leak for aborted commands + - ASoC: stm32: fix sai driver name initialisation + - IB/core: Unregister notifier before freeing MAD security + - IB/core: Fix potential memory leak while creating MAD agents + - IB/core: Destroy QP if XRC QP fails + - Input: snvs_pwrkey - initialize necessary driver data before enabling IRQ + - Input: stmfts - acknowledge that setting brightness is a blocking call + - selinux: never allow relabeling on context mounts + - powerpc/mm/hash: Handle mmap_min_addr correctly in get_unmapped_area topdown + search + - x86/mce: Improve error message when kernel cannot recover, p2 + - clk: x86: Add system specific quirk to mark clocks as critical + - i2c: i2c-stm32f7: Fix SDADEL minimum formula + - media: v4l2: i2c: ov7670: Fix PLL bypass register values + - mm/kmemleak.c: fix unused-function warning + - mac80211: don't attempt to rename ERR_PTR() debugfs dirs + - i2c: Remove unnecessary call to irq_find_mapping + - i2c: Clear client->irq in i2c_device_remove + - i2c: Allow recovery of the initial IRQ by an I2C client device. + - i2c: Prevent runtime suspend of adapter when Host Notify is required + - USB: dummy-hcd: Fix failure to give back unlinked URBs + - batman-adv: fix warning in function batadv_v_elp_get_throughput + - riscv: fix accessing 8-byte variable from RV32 + - net: stmmac: don't stop NAPI processing when dropping a packet + - mfd: twl-core: Disable IRQ while suspended + - block: use blk_free_flush_queue() to free hctx->fq in blk_mq_init_hctx + - arm/mach-at91/pm : fix possible object reference leak + - fs: stream_open - opener for stream-like files so that read and write can + run simultaneously without deadlock + - block: pass no-op callback to INIT_WORK(). + - platform/x86: intel_pmc_core: Fix PCH IP name + - platform/x86: intel_pmc_core: Handle CFL regmap properly + - x86/mm: Fix a crash with kmemleak_scan() + - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup() + - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings + - staging: greybus: power_supply: fix prop-descriptor request size + - ASoC: hdmi-codec: fix S/PDIF DAI + - ASoC:soc-pcm:fix a codec fixup issue in TDM case + - ASoC: nau8824: fix the issue of the widget with prefix name + - ASoC: nau8810: fix the issue of widget with prefixed name + - ASoC: samsung: odroid: Fix clock configuration for 44100 sample rate + - ASoC: wm_adsp: Add locking to wm_adsp2_bus_error + - ASoC: cs4270: Set auto-increment bit for register writes + - IB/hfi1: Eliminate opcode tests on mr deref + - MIPS: KGDB: fix kgdb support for SMP platforms. + - ASoC: tlv320aic32x4: Fix Common Pins + - drm/mediatek: Fix an error code in mtk_hdmi_dt_parse_pdata() + - perf/x86/intel: Fix handling of wakeup_events for multi-entry PEBS + - perf/x86/intel: Initialize TFA MSR + - linux/kernel.h: Use parentheses around argument in u64_to_user_ptr() + - ASoC: rockchip: pdm: fix regmap_ops hang issue + - slab: fix a crash by reading /proc/slab_allocators + - virtio_pci: fix a NULL pointer reference in vp_del_vqs + - RDMA/vmw_pvrdma: Fix memory leak on pvrdma_pci_remove + - scsi: csiostor: fix missing data copy in csio_scsi_err_handler() + - drm/mediatek: fix possible object reference leak + - ASoC: Intel: kbl: fix wrong number of channels + - virtio-blk: limit number of hw queues by nr_cpu_ids + - platform/x86: pmc_atom: Drop __initconst on dmi table + - genirq: Prevent use-after-free and work list corruption + - usb: dwc3: Fix default lpm_nyet_threshold value + - USB: serial: f81232: fix interrupt worker not stop + - USB: cdc-acm: fix unthrottle races + - usb-storage: Set virt_boundary_mask to avoid SG overflows + - intel_th: pci: Add Comet Lake support + - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines + - UAS: fix alignment of scatter/gather segments + - ASoC: Intel: avoid Oops if DMA setup fails + - locking/futex: Allow low-level atomic operations to return -EAGAIN + - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP + - ASoC: tlv320aic3x: fix reset gpio reference counting + - ASoC: stm32: sai: fix exposed capabilities in spdif mode + - ASoC:intel:skl:fix a simultaneous playback & capture issue on hda platform + - ASoC: dapm: Fix NULL pointer dereference in snd_soc_dapm_free_kcontrol + - drm/omap: hdmi4_cec: Fix CEC clock handling for PM + - IB/hfi1: Fix the allocation of RSM table + - drm/amd/display: fix cursor black issue + - objtool: Add machine_real_restart() to the noreturn list + - objtool: Add rewind_stack_do_exit() to the noreturn list + - RDMA/hns: Fix bug that caused srq creation to fail + - perf/core: Fix perf_event_disable_inatomic() race + - soc: sunxi: Fix missing dependency on REGMAP_MMIO + - scsi: lpfc: change snprintf to scnprintf for possible overflow + * [ZenBook S UX391UA, Realtek ALC294, Mic, Internal] No sound at all + (LP: #1784485) // Bionic update: upstream stable patchset 2019-07-30 + (LP: #1838459) + - ALSA: hda/realtek - Apply the fixup for ASUS Q325UAR + * Bionic update: upstream stable patchset 2019-07-29 (LP: #1838349) + - ARC: u-boot args: check that magic number is correct + - arc: hsdk_defconfig: Enable CONFIG_BLK_DEV_RAM + - perf/core: Restore mmap record type correctly + - ext4: add missing brelse() in add_new_gdb_meta_bg() + - ext4: report real fs size after failed resize + - ALSA: echoaudio: add a check for ioremap_nocache + - ALSA: sb8: add a check for request_region + - auxdisplay: hd44780: Fix memory leak on ->remove() + - IB/mlx4: Fix race condition between catas error reset and aliasguid flows + - mmc: davinci: remove extraneous __init annotation + - ALSA: opl3: fix mismatch between snd_opl3_drum_switch definition and + declaration + - thermal/intel_powerclamp: fix __percpu declaration of worker_data + - thermal: bcm2835: Fix crash in bcm2835_thermal_debugfs + - thermal/int340x_thermal: Add additional UUIDs + - thermal/int340x_thermal: fix mode setting + - thermal/intel_powerclamp: fix truncated kthread name + - scsi: iscsi: flush running unbind operations when removing a session + - x86/mm: Don't leak kernel addresses + - tools/power turbostat: return the exit status of a command + - perf list: Don't forget to drop the reference to the allocated thread_map + - perf config: Fix an error in the config template documentation + - perf config: Fix a memory leak in collect_config() + - perf build-id: Fix memory leak in print_sdt_events() + - perf top: Fix error handling in cmd_top() + - perf hist: Add missing map__put() in error case + - perf evsel: Free evsel->counts in perf_evsel__exit() + - perf tests: Fix a memory leak of cpu_map object in the + openat_syscall_event_on_all_cpus test + - perf tests: Fix memory leak by expr__find_other() in test__expr() + - perf tests: Fix a memory leak in test__perf_evsel__tp_sched_test() + - irqchip/mbigen: Don't clear eventid when freeing an MSI + - x86/hpet: Prevent potential NULL pointer dereference + - x86/cpu/cyrix: Use correct macros for Cyrix calls on Geode processors + - drm/nouveau/debugfs: Fix check of pm_runtime_get_sync failure + - iommu/vt-d: Check capability before disabling protected memory + - x86/hw_breakpoints: Make default case in hw_breakpoint_arch_parse() return + an error + - fix incorrect error code mapping for OBJECTID_NOT_FOUND + - ext4: prohibit fstrim in norecovery mode + - gpio: pxa: handle corner case of unprobed device + - rsi: improve kernel thread handling to fix kernel panic + - 9p: do not trust pdu content for stat item size + - 9p locks: add mount option for lock retry interval + - f2fs: fix to do sanity check with current segment number + - netfilter: xt_cgroup: shrink size of v2 path + - serial: uartps: console_setup() can't be placed to init section + - powerpc/pseries: Remove prrn_work workqueue + - media: au0828: cannot kfree dev before usb disconnect + - HID: i2c-hid: override HID descriptors for certain devices + - ARM: samsung: Limit SAMSUNG_PM_CHECK config option to non-Exynos platforms + - [Config] updateconfigs for CONFIG_SAMSUNG_PM_CHECK + - usbip: fix vhci_hcd controller counting + - ACPI / SBS: Fix GPE storm on recent MacBookPro's + - KVM: nVMX: restore host state in nested_vmx_vmexit for VMFail + - cifs: fallback to older infolevels on findfirst queryinfo retry + - kernel: hung_task.c: disable on suspend + - crypto: sha256/arm - fix crash bug in Thumb2 build + - crypto: sha512/arm - fix crash bug in Thumb2 build + - iommu/dmar: Fix buffer overflow during PCI bus notification + - soc/tegra: pmc: Drop locking from tegra_powergate_is_powered() + - lkdtm: Print real addresses + - lkdtm: Add tests for NULL pointer dereference + - drm/panel: panel-innolux: set display off in innolux_panel_unprepare + - crypto: axis - fix for recursive locking from bottom half + - Revert "ACPI / EC: Remove old CLEAR_ON_RESUME quirk" + - coresight: cpu-debug: Support for CA73 CPUs + - drm/nouveau/volt/gf117: fix speedo readout register + - ARM: 8839/1: kprobe: make patch_lock a raw_spinlock_t + - drm/amdkfd: use init_mqd function to allocate object for hid_mqd (CI) + - appletalk: Fix use-after-free in atalk_proc_exit + - lib/div64.c: off by one in shift + - include/linux/swap.h: use offsetof() instead of custom __swapoffset macro + - bpf: fix use after free in bpf_evict_inode + - dm: disable CRYPTO_TFM_REQ_MAY_SLEEP to fix a GFP_KERNEL recursion deadlock + - net: stmmac: Set dma ring length before enabling the DMA + - mm: hide incomplete nr_indirectly_reclaimable in sysfs + - appletalk: Fix compile regression + - ext4: avoid panic during forced reboot + - i40iw: Avoid panic when handling the inetdev event + - sched/core: Fix buffer overflow in cgroup2 property cpu.max + - ACPI / utils: Drop reference in test for device presence + - PM / Domains: Avoid a potential deadlock + - drm/exynos/mixer: fix MIXER shadow registry synchronisation code + - Bluetooth: Fix debugfs NULL pointer dereference + - f2fs: cleanup dirty pages if recover failed + - [Config] updateconfigs for CONFIG_INTEL_ATOMISP2_PM + - platform/x86: Add Intel AtomISP2 dummy / power-management driver + - drm/ttm: Fix bo_global and mem_global kfree error + - ALSA: hda: fix front speakers on Huawei MBXP + - ACPI: EC / PM: Disable non-wakeup GPEs for suspend-to-idle + - net/rds: fix warn in rds_message_alloc_sgs + - scsi: core: Avoid that system resume triggers a kernel warning + - PCI: Blacklist power management of Gigabyte X299 DESIGNARE EX PCIe ports + - rxrpc: Fix client call connect/disconnect race + - f2fs: fix to dirty inode for i_mode recovery + - bonding: fix event handling for stacked bonds + - net: atm: Fix potential Spectre v1 vulnerabilities + - net: bridge: fix per-port af_packet sockets + - net: bridge: multicast: use rcu to access port list from + br_multicast_start_querier + - net: fou: do not use guehdr after iptunnel_pull_offloads in gue_udp_recv + - tcp: tcp_grow_window() needs to respect tcp_space() + - team: set slave to promisc if team is already in promisc mode + - vhost: reject zero size iova range + - ipv4: recompile ip options in ipv4_link_failure + - ipv4: ensure rcu_read_lock() in ipv4_link_failure() + - net: thunderx: raise XDP MTU to 1508 + - net: thunderx: don't allow jumbo frames with XDP + - KVM: x86: Don't clear EFER during SMM transitions for 32-bit vCPU + - KVM: x86: svm: make sure NMI is injected after nmi_singlestep + - Staging: iio: meter: fixed typo + - staging: iio: ad7192: Fix ad7193 channel address + - iio: gyro: mpu3050: fix chip ID reading + - iio/gyro/bmg160: Use millidegrees for temperature scale + - iio: cros_ec: Fix the maths for gyro scale calculation + - iio: ad_sigma_delta: select channel when reading register + - iio: dac: mcp4725: add missing powerdown bits in store eeprom + - iio: Fix scan mask selection + - iio: adc: at91: disable adc channel interrupt in timeout case + - iio: core: fix a possible circular locking dependency + - io: accel: kxcjk1013: restore the range after resume. + - staging: comedi: vmk80xx: Fix use of uninitialized semaphore + - staging: comedi: vmk80xx: Fix possible double-free of ->usb_rx_buf + - staging: comedi: ni_usb6501: Fix use of uninitialized mutex + - staging: comedi: ni_usb6501: Fix possible double-free of ->usb_rx_buf + - ALSA: core: Fix card races between register and disconnect + - scsi: core: set result when the command cannot be dispatched + - coredump: fix race condition between mmget_not_zero()/get_task_mm() and core + dumping + - crypto: x86/poly1305 - fix overflow during partial reduction + - arm64: futex: Restore oldval initialization to work around buggy compilers + - x86/kprobes: Verify stack frame on kretprobe + - kprobes: Mark ftrace mcount handler functions nokprobe + - kprobes: Fix error check when reusing optimized probes + - rt2x00: do not increment sequence number while re-transmitting + - mac80211: do not call driver wake_tx_queue op during reconfig + - perf/x86/amd: Add event map for AMD Family 17h + - x86/cpu/bugs: Use __initconst for 'const' init data + - perf/x86: Fix incorrect PEBS_REGS + - x86/speculation: Prevent deadlock on ssb_state::lock + - crypto: crypto4xx - properly set IV after de- and encrypt + - mmc: sdhci: Fix data command CRC error handling + - mmc: sdhci: Rename SDHCI_ACMD12_ERR and SDHCI_INT_ACMD12ERR + - mmc: sdhci: Handle auto-command errors + - modpost: file2alias: go back to simple devtable lookup + - modpost: file2alias: check prototype of handler + - tpm/tpm_i2c_atmel: Return -E2BIG when the transfer is incomplete + - ipv6: frags: fix a lockdep false positive + - Revert "kbuild: use -Oz instead of -Os when using clang" + - device_cgroup: fix RCU imbalance in error case + - mm/vmstat.c: fix /proc/vmstat format for CONFIG_DEBUG_TLBFLUSH=y + CONFIG_SMP=n + - ALSA: info: Fix racy addition/deletion of nodes + - percpu: stop printing kernel addresses + - iomap: report collisions between directio and buffered writes to userspace + - i2c-hid: properly terminate i2c_hid_dmi_desc_override_table[] array + - net: Fix missing meta data in skb with vlan packet + - nfp: flower: replace CFI with vlan present + - nfp: flower: remove vlan CFI bit from push vlan action + - ip: add helpers to process in-order fragments faster. + - net: IP defrag: encapsulate rbtree defrag code into callable functions + - ip: process in-order fragments efficiently + - ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module + - net: IP6 defrag: use rbtrees for IPv6 defrag + - net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c + - cifs: fix handle leak in smb2_query_symlink() + - Input: elan_i2c - add hardware ID for multiple Lenovo laptops + - drm/ttm: fix out-of-bounds read in ttm_put_pages() v2 + - timers/sched_clock: Prevent generic sched_clock wrap caused by tick_freeze() + - tpm: Fix the type of the return value in calc_tpm2_event_size() + * Bionic update: upstream stable patchset 2019-07-26 (LP: #1838116) + - mmc: pxamci: fix enum type confusion + - drm/vmwgfx: Don't double-free the mode stored in par->set_mode + - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE + - libceph: wait for latest osdmap in ceph_monc_blacklist_add() + - udf: Fix crash on IO error during truncate + - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction. + - MIPS: Ensure ELF appended dtb is relocated + - MIPS: Fix kernel crash for R6 in jump label branch function + - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton + - scsi: ibmvscsi: Fix empty event pool access during host removal + - futex: Ensure that futex address is aligned in handle_futex_death() + - perf probe: Fix getting the kernel map + - objtool: Move objtool_file struct off the stack + - ALSA: x86: Fix runtime PM for hdmi-lpe-audio + - ext4: fix NULL pointer dereference while journal is aborted + - ext4: fix data corruption caused by unaligned direct AIO + - ext4: brelse all indirect buffer in ext4_ind_remove_space() + - media: v4l2-ctrls.c/uvc: zero v4l2_event + - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf() + - Bluetooth: Fix decrementing reference count twice in releasing socket + - Bluetooth: hci_ldisc: Initialize hci_dev before open() + - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in + hci_uart_set_proto() + - drm: Reorder set_property_atomic to avoid returning with an active ww_ctx + - netfilter: ebtables: remove BUGPRINT messages + - x86/unwind: Handle NULL pointer calls better in frame unwinder + - x86/unwind: Add hardcoded ORC entry for NULL + - locking/lockdep: Add debug_locks check in __lock_downgrade() + - ALSA: hda - Record the current power state before suspend/resume calls + - PCI: designware-ep: dw_pcie_ep_set_msi() should only set MMC bits + - PCI: designware-ep: Read-only registers need DBI_RO_WR_EN to be writable + - PCI: endpoint: Use EPC's device in dma_alloc_coherent()/dma_free_coherent() + - rtc: Fix overflow when converting time64_t to rtc_time + - sched/cpufreq/schedutil: Fix error path mutex unlock + - pwm-backlight: Enable/disable the PWM before/after LCD enable toggle. + - power: supply: charger-manager: Fix incorrect return value + - ath10k: avoid possible string overflow + - mmc: renesas_sdhi: limit block count to 16 bit for old revisions + - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038 + - RDMA/cma: Rollback source IP address if failing to acquire device + - f2fs: fix to avoid deadlock of atomic file operations + - loop: access lo_backing_file only when the loop device is Lo_bound + - video: fbdev: Set pixclock = 0 in goldfishfb + - dccp: do not use ipv6 header for ipv4 flow + - genetlink: Fix a memory leak on error path + - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S + - net: datagram: fix unbounded loop in __skb_try_recv_datagram() + - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec + - net: rose: fix a possible stack overflow + - net: stmmac: fix memory corruption with large MTUs + - net-sysfs: call dev_hold if kobject_init_and_add success + - packets: Always register packet sk in the same order + - rhashtable: Still do rehash when we get EEXIST + - tcp: do not use ipv6 header for ipv4 flow + - thunderx: enable page recycling for non-XDP case + - thunderx: eliminate extra calls to put_page() for pages held for recycling + - vxlan: Don't call gro_cells_destroy() before device is unregistered + - sctp: get sctphdr by offset in sctp_compute_cksum + - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6 + - mac8390: Fix mmio access size probe + - tun: properly test for IFF_UP + - tun: add a missing rcu_read_unlock() in error path + - powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E + - powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit platforms + - powerpc/fsl: Add infrastructure to fixup branch predictor flush + - powerpc/fsl: Add macro to flush the branch predictor + - powerpc/fsl: Emulate SPRN_BUCSR register + - powerpc/fsl: Flush the branch predictor at each kernel entry (64bit) + - powerpc/fsl: Flush the branch predictor at each kernel entry (32 bit) + - powerpc/fsl: Flush branch predictor when entering KVM + - powerpc/fsl: Enable runtime patching if nospectre_v2 boot arg is used + - powerpc/fsl: Fixed warning: orphan section `__btb_flush_fixup' + - powerpc/fsl: Fix the flush of branch predictor. + - Btrfs: fix incorrect file size after shrinking truncate and fsync + - btrfs: remove WARN_ON in log_dir_items + - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time + - powerpc: bpf: Fix generation of load/store DW instructions + - NFSv4.1 don't free interrupted slot on open + - net: dsa: qca8k: remove leftover phy accessors + - ALSA: pcm: Fix possible OOB access in PCM oss plugins + - ALSA: pcm: Don't suspend stream in unrecoverable PCM state + - kbuild: modversions: Fix relative CRC byte order interpretation + - fs/open.c: allow opening only regular files during execve() + - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock + - scsi: sd: Fix a race between closing an sd device and sd I/O + - scsi: sd: Quiesce warning if device does not report optimal I/O size + - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host + - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP + devices + - tty: atmel_serial: fix a potential NULL pointer dereference + - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest + - staging: vt6655: Remove vif check from vnt_interrupt + - staging: vt6655: Fix interrupt race condition on device start up. + - serial: max310x: Fix to avoid potential NULL pointer dereference + - serial: sh-sci: Fix setting SCSCR_TIE while transferring data + - USB: serial: cp210x: add new device id + - USB: serial: ftdi_sio: add additional NovaTech products + - USB: serial: mos7720: fix mos_parport refcount imbalance on error path + - USB: serial: option: set driver_info for SIM5218 and compatibles + - USB: serial: option: add support for Quectel EM12 + - USB: serial: option: add Olicard 600 + - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc + - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links + - drm/vgem: fix use-after-free when drm_gem_handle_create() fails + - gpio: exar: add a check for the return value of ida_simple_get fails + - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input + - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs + - usb: mtu3: fix EXTCON dependency + - USB: gadget: f_hid: fix deadlock in f_hidg_write() + - usb: common: Consider only available nodes for dr_mode + - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk + - xhci: Fix port resume done detection for SS ports with LPM enabled + - usb: cdc-acm: fix race during wakeup blocking TX traffic + - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate + - perf intel-pt: Fix TSC slip + - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n + - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y + - KVM: Reject device ioctls from processes other than the VM's creator + - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts + - vfio: ccw: only free cp on final interrupt + - ipmi_si: Fix crash when using hard-coded device + - gtp: change NET_UDP_TUNNEL dependency to select + - Btrfs: fix assertion failure on fsync with NO_HOLES enabled + - NFS: fix mount/umount race in nlmclnt. + - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286 + - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286 + - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic + - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256 + - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256 + - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256 + - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops + - drm/rockchip: Do not use memcpy for MMIO addresses + - drm/rockchip: vop: reset scale mode when win is disabled + - tty: mxs-auart: fix a potential NULL pointer dereference + - staging: speakup_soft: Fix alternate speech with other synths + - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference + - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check + - usb: xhci: dbc: Don't free all memory with spinlock held + - xhci: Don't let USB3 ports stuck in polling state prevent suspend + - mm: add support for kmem caches in DMA32 zone + - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging + - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified + - perf pmu: Fix parser error for uncore event alias + - objtool: Query pkg-config for libelf location + - bpf: do not restore dst_reg when cur_state is freed + - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals + - ext4: cleanup bh release code in ext4_ind_remove_space() + - tty/serial: atmel: Add is_half_duplex helper + - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped + - CIFS: fix POSIX lock leak and invalid ptr deref + - h8300: use cc-cross-prefix instead of hardcoding h8300-unknown-linux- + - f2fs: fix to avoid deadlock in f2fs_read_inline_dir() + - tracing: kdb: Fix ftdump to not sleep + - net/mlx5: Avoid panic when setting vport rate + - net/mlx5: Avoid panic when setting vport mac, getting vport config + - gpio: gpio-omap: fix level interrupt idling + - include/linux/relay.h: fix percpu annotation in struct rchan + - enic: fix build warning without CONFIG_CPUMASK_OFFSTACK + - scsi: hisi_sas: Set PHY linkrate when disconnected + - iio: adc: fix warning in Qualcomm PM8xxx HK/XOADC driver + - perf c2c: Fix c2c report for empty numa node + - mm/cma.c: cma_declare_contiguous: correct err handling + - mm/page_ext.c: fix an imbalance with kmemleak + - mm, mempolicy: fix uninit memory access + - mm/vmalloc.c: fix kernel BUG at mm/vmalloc.c:512! + - mm/slab.c: kmemleak no scan alien caches + - ocfs2: fix a panic problem caused by o2cb_ctl + - f2fs: do not use mutex lock in atomic context + - fs/file.c: initialize init_files.resize_wait + - page_poison: play nicely with KASAN + - cifs: use correct format characters + - dm thin: add sanity checks to thin-pool and external snapshot creation + - cifs: Fix NULL pointer dereference of devname + - jbd2: fix invalid descriptor block checksum + - fs: fix guard_bio_eod to check for real EOD errors + - tools lib traceevent: Fix buffer overflow in arg_eval + - PCI/PME: Fix hotplug/sysfs remove deadlock in pcie_pme_remove() + - wil6210: check null pointer in _wil_cfg80211_merge_extra_ies + - crypto: crypto4xx - add missing of_node_put after of_device_is_available + - crypto: cavium/zip - fix collision with generic cra_driver_name + - usb: chipidea: Grab the (legacy) USB PHY by phandle first + - scsi: core: replace GFP_ATOMIC with GFP_KERNEL in scsi_scan.c + - powerpc/xmon: Fix opcode being uninitialized in print_insn_powerpc + - coresight: etm4x: Add support to enable ETMv4.2 + - serial: 8250_pxa: honor the port number from devicetree + - ARM: 8840/1: use a raw_spinlock_t in unwind + - iommu/io-pgtable-arm-v7s: Only kmemleak_ignore L2 tables + - powerpc/hugetlb: Handle mmap_min_addr correctly in get_unmapped_area + callback + - mmc: omap: fix the maximum timeout setting + - e1000e: Fix -Wformat-truncation warnings + - mlxsw: spectrum: Avoid -Wformat-truncation warnings + - IB/mlx4: Increase the timeout for CM cache + - clk: fractional-divider: check parent rate only if flag is set + - cpufreq: acpi-cpufreq: Report if CPU doesn't support boost technologies + - efi: cper: Fix possible out-of-bounds access + - scsi: megaraid_sas: return error when create DMA pool failed + - scsi: fcoe: make use of fip_mode enum complete + - perf test: Fix failure of 'evsel-tp-sched' test on s390 + - SoC: imx-sgtl5000: add missing put_device() + - media: sh_veu: Correct return type for mem2mem buffer helpers + - media: s5p-jpeg: Correct return type for mem2mem buffer helpers + - media: s5p-g2d: Correct return type for mem2mem buffer helpers + - media: mx2_emmaprp: Correct return type for mem2mem buffer helpers + - media: mtk-jpeg: Correct return type for mem2mem buffer helpers + - vfs: fix preadv64v2 and pwritev64v2 compat syscalls with offset == -1 + - HID: intel-ish-hid: avoid binding wrong ishtp_cl_device + - jbd2: fix race when writing superblock + - leds: lp55xx: fix null deref on firmware load failure + - iwlwifi: pcie: fix emergency path + - ACPI / video: Refactor and fix dmi_is_desktop() + - kprobes: Prohibit probing on bsearch() + - netfilter: conntrack: fix cloned unconfirmed skb->_nfct race in + __nf_conntrack_confirm + - ARM: 8833/1: Ensure that NEON code always compiles with Clang + - ALSA: PCM: check if ops are defined before suspending PCM + - usb: f_fs: Avoid crash due to out-of-scope stack ptr access + - sched/topology: Fix percpu data types in struct sd_data & struct s_data + - bcache: fix input overflow to cache set sysfs file io_error_halflife + - bcache: fix input overflow to sequential_cutoff + - bcache: improve sysfs_strtoul_clamp() + - genirq: Avoid summation loops for /proc/stat + - iw_cxgb4: fix srqidx leak during connection abort + - fbdev: fbmem: fix memory access if logo is bigger than the screen + - cdrom: Fix race condition in cdrom_sysctl_register + - platform/x86: intel_pmc_core: Fix PCH IP sts reading + - ASoC: fsl-asoc-card: fix object reference leaks in fsl_asoc_card_probe + - sched/debug: Initialize sd_sysctl_cpus if !CONFIG_CPUMASK_OFFSTACK + - efi/memattr: Don't bail on zero VA if it equals the region's PA + - ARM: dts: lpc32xx: Remove leading 0x and 0s from bindings notation + - soc: qcom: gsbi: Fix error handling in gsbi_probe() + - mt7601u: bump supported EEPROM version + - ARM: 8830/1: NOMMU: Toggle only bits in EXC_RETURN we are really care of + - ARM: avoid Cortex-A9 livelock on tight dmb loops + - bpf: fix missing prototype warnings + - cgroup/pids: turn cgroup_subsys->free() into cgroup_subsys->release() to fix + the accounting + - backlight: pwm_bl: Use gpiod_get_value_cansleep() to get initial state + - tty: increase the default flip buffer limit to 2*640K + - powerpc/pseries: Perform full re-add of CPU for topology update post- + migration + - usb: dwc3: gadget: Fix OTG events when gadget driver isn't loaded + - media: mt9m111: set initial frame size other than 0x0 + - hwrng: virtio - Avoid repeated init of completion + - soc/tegra: fuse: Fix illegal free of IO base address + - HID: intel-ish: ipc: handle PIMR before ish_wakeup also clear PISR + busy_clear bit + - hpet: Fix missing '=' character in the __setup() code of hpet_mmap_enable + - cpu/hotplug: Mute hotplug lockdep during init + - dmaengine: imx-dma: fix warning comparison of distinct pointer types + - dmaengine: qcom_hidma: assign channel cookie correctly + - dmaengine: qcom_hidma: initialize tx flags in hidma_prep_dma_* + - netfilter: physdev: relax br_netfilter dependency + - media: s5p-jpeg: Check for fmt_ver_flag when doing fmt enumeration + - regulator: act8865: Fix act8600_sudcdc_voltage_ranges setting + - drm: Auto-set allow_fb_modifiers when given modifiers at plane init + - drm/nouveau: Stop using drm_crtc_force_disable + - x86/build: Specify elf_i386 linker emulation explicitly for i386 objects + - selinux: do not override context on context mounts + - wlcore: Fix memory leak in case wl12xx_fetch_firmware failure + - x86/build: Mark per-CPU symbols as absolute explicitly for LLD + - clk: rockchip: fix frac settings of GPLL clock for rk3328 + - dmaengine: tegra: avoid overflow of byte tracking + - drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers + - ACPI / video: Extend chassis-type detection with a "Lunch Box" check + - f2fs: fix to adapt small inline xattr space in __find_inline_xattr() + - net: stmmac: Avoid sometimes uninitialized Clang warnings + - libbpf: force fixdep compilation at the start of the build + - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO + - x86/hyperv: Fix kernel panic when kexec on HyperV + - mm/sparse: fix a bad comparison + - mm, swap: bounds check swap_info array accesses to avoid NULL derefs + - memcg: killed threads should not invoke memcg OOM killer + - cifs: Accept validate negotiate if server return NT_STATUS_NOT_SUPPORTED + - netfilter: nf_tables: check the result of dereferencing base_chain->stats + - netfilter: conntrack: tcp: only close if RST matches exact sequence + - kbuild: invoke syncconfig if include/config/auto.conf.cmd is missing + - mwifiex: don't advertise IBSS features without FW support + - perf report: Don't shadow inlined symbol with different addr range + - media: rockchip/rga: Correct return type for mem2mem buffer helpers + - selftests: skip seccomp get_metadata test if not real root + - kprobes: Prohibit probing on RCU debug routine + - bcache: fix potential div-zero error of writeback_rate_i_term_inverse + - drm: rcar-du: add missing of_node_put + - perf/aux: Make perf_event accessible to setup_aux() + - e1000e: Exclude device from suspend direct complete optimization + - i2c: of: Try to find an I2C adapter matching the parent + - sched/core: Use READ_ONCE()/WRITE_ONCE() in + move_queued_task()/task_rq_lock() + - powerpc/64s: Clear on-stack exception marker upon exception return + - platform/x86: intel-hid: Missing power button release on some Dell models + - pinctrl: meson: meson8b: add the eth_rxd2 and eth_rxd3 pins + - net: stmmac: Avoid one more sometimes uninitialized Clang warning + - bcache: fix potential div-zero error of writeback_rate_p_term_inverse + - net: sfp: move sfp_register_socket call from sfp_remove to sfp_probe + - drm/i915/gvt: do not let pin count of shadow mm go negative + - powerpc/tm: Limit TM code inside PPC_TRANSACTIONAL_MEM + - kbuild: clang: choose GCC_TOOLCHAIN_DIR not on LD + - x86: vdso: Use $LD instead of $CC to link + - x86/vdso: Drop implicit common-page-size linker flag + - lib/string.c: implement a basic bcmp + - stating: ccree: revert "staging: ccree: fix leak of import() after init()" + - arm64: kaslr: Reserve size of ARM64_MEMSTART_ALIGN in linear region + - tty: mark Siemens R3964 line discipline as BROKEN + - [Config] updateconfigs for CONFIG_R3964 (BROKEN) + - [Config] updateconfigs for CONFIG_LDISC_AUTOLOAD + - tty: ldisc: add sysctl to prevent autoloading of ldiscs + - ipv6: Fix dangling pointer when ipv6 fragment + - ipv6: sit: reset ip header pointer in ipip6_rcv + - kcm: switch order of device registration to fix a crash + - net-gro: Fix GRO flush when receiving a GSO packet. + - net/mlx5: Decrease default mr cache size + - net/sched: fix ->get helper of the matchall cls + - qmi_wwan: add Olicard 600 + - sctp: initialize _pad of sockaddr_in before copying to user memory + - tcp: Ensure DCTCP reacts to losses + - vrf: check accept_source_route on the original netdevice + - net/mlx5e: Fix error handling when refreshing TIRs + - net/mlx5e: Add a lock on tir list + - nfp: validate the return code from dev_queue_xmit() + - bnxt_en: Improve RX consumer index validity check. + - bnxt_en: Reset device on RX buffer errors. + - net/sched: act_sample: fix divide by zero in the traffic path + - netns: provide pure entropy for net_hash_mix() + - net: ethtool: not call vzalloc for zero sized memory request + - ALSA: seq: Fix OOB-reads from strlcpy + - ip6_tunnel: Match to ARPHRD_TUNNEL6 for dev type + - hv_netvsc: Fix unwanted wakeup after tx_disable + - arm64: dts: rockchip: fix rk3328 sdmmc0 write errors + - parisc: Detect QEMU earlier in boot process + - parisc: regs_return_value() should return gpr28 + - alarmtimer: Return correct remaining time + - drm/udl: add a release method and delay modeset teardown + - include/linux/bitrev.h: fix constant bitrev + - ASoC: fsl_esai: fix channel swap issue when stream starts + - Btrfs: do not allow trimming when a fs is mounted with the nologreplay + option + - btrfs: prop: fix zstd compression parameter validation + - btrfs: prop: fix vanished compression property after failed set + - block: do not leak memory in bio_copy_user_iov() + - block: fix the return errno for direct IO + - genirq: Respect IRQCHIP_SKIP_SET_WAKE in irq_chip_set_wake_parent() + - genirq: Initialize request_mutex if CONFIG_SPARSE_IRQ=n + - virtio: Honour 'may_reduce_num' in vring_create_virtqueue + - ARM: dts: am335x-evmsk: Correct the regulators for the audio codec + - ARM: dts: am335x-evm: Correct the regulators for the audio codec + - ARM: dts: at91: Fix typo in ISC_D0 on PC9 + - arm64: futex: Fix FUTEX_WAKE_OP atomic ops with non-zero result value + - arm64: dts: rockchip: fix rk3328 rgmii high tx error rate + - arm64: backtrace: Don't bother trying to unwind the userspace stack + - xen: Prevent buffer overflow in privcmd ioctl + - sched/fair: Do not re-read ->h_load_next during hierarchical load + calculation + - xtensa: fix return_address + - x86/perf/amd: Resolve race condition when disabling PMC + - x86/perf/amd: Resolve NMI latency issues for active PMCs + - x86/perf/amd: Remove need to check "running" bit in NMI handler + - PCI: Add function 1 DMA alias quirk for Marvell 9170 SATA controller + - dm table: propagate BDI_CAP_STABLE_WRITES to fix sporadic checksum errors + - arm64: dts: rockchip: fix vcc_host1_5v pin assign on rk3328-rock64 + - arm64: dts: rockchip: Fix vcc_host1_5v GPIO polarity on rk3328-rock64 + - tcp: fix a potential NULL pointer dereference in tcp_sk_exit + - nfp: disable netpoll on representors + - r8169: disable default rx interrupt coalescing on RTL8168 + - kbuild: deb-pkg: fix bindeb-pkg breakage when O= is used + - ACPICA: Namespace: remove address node from global list after method + termination + - ALSA: hda/realtek - Add quirk for Tuxedo XC 1509 + - mm/huge_memory.c: fix modifying of page protection by insert_pfn_pmd() + - riscv: Fix syscall_get_arguments() and syscall_set_arguments() + - x86/asm: Remove dead __GNUC__ conditionals + - dm integrity: change memcmp to strncmp in dm_integrity_ctr + * Bionic update: upstream stable patchset 2019-07-25 (LP: #1837952) + - ACPICA: Reference Counts: increase max to 0x4000 for large servers + - gro_cells: make sure device is up in gro_cells_receive() + - ipv4/route: fail early when inet dev is missing + - l2tp: fix infoleak in l2tp_ip6_recvmsg() + - net: hsr: fix memory leak in hsr_dev_finalize() + - net/hsr: fix possible crash in add_timer() + - net: sit: fix UBSAN Undefined behaviour in check_6rd + - net/x25: fix use-after-free in x25_device_event() + - net/x25: reset state in x25_connect() + - pptp: dst_release sk_dst_cache in pptp_sock_destruct + - ravb: Decrease TxFIFO depth of Q3 and Q2 to one + - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race + - rxrpc: Fix client call queueing, waiting for channel + - tcp: Don't access TCP_SKB_CB before initializing it + - tcp: handle inet_csk_reqsk_queue_add() failures + - vxlan: Fix GRO cells race condition between receive and link delete + - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() + - net/mlx4_core: Fix reset flow when in command polling mode + - net/mlx4_core: Fix locking in SRIOV mode when switching between events and + polling + - net/mlx4_core: Fix qp mtt size calculation + - net/x25: fix a race in x25_bind() + - net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 + - bonding: fix PACKET_ORIGDEV regression + - missing barriers in some of unix_sock ->addr and ->path accesses + - ipvlan: disallow userns cap_net_admin to change global mode/flags + - perf/x86: Fixup typo in stub functions + - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against + Liquid Saffire 56 + - ALSA: firewire-motu: fix construction of PCM frame for capture direction + - perf/x86/intel: Fix memory corruption + - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static + - It's wrong to add len to sector_nr in raid10 reshape twice + - sctp: remove sched init from sctp_stream_init + - team: use operstate consistently for linkup + - ipv6: route: enforce RCU protection in rt6_update_exception_stamp_rt() + - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240 + - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294 + - i40e: report correct statistics when XDP is enabled + - 9p: use inode->i_lock to protect i_size_write() under 32-bit + - 9p/net: fix memory leak in p9_client_create + - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode + - iio: adc: exynos-adc: Fix NULL pointer exception on unbind + - stm class: Fix an endless loop in channel allocation + - crypto: caam - fixed handling of sg list + - crypto: ahash - fix another early termination in hash walk + - crypto: rockchip - fix scatterlist nents error + - crypto: rockchip - update new iv to device in multiple operations + - drm/imx: ignore plane updates on disabled crtcs + - gpu: ipu-v3: Fix i.MX51 CSI control registers offset + - drm/imx: imx-ldb: add missing of_node_puts + - gpu: ipu-v3: Fix CSI offsets for imx53 + - s390/dasd: fix using offset into zero size array error + - Input: pwm-vibra - prevent unbalanced regulator + - Input: pwm-vibra - stop regulator after disabling pwm, not before + - ARM: OMAP2+: Variable "reg" in function omap4_dsi_mux_pads() could be + uninitialized + - ASoC: dapm: fix out-of-bounds accesses to DAPM lookup tables + - ASoC: rsnd: fixup rsnd_ssi_master_clk_start() user count check + - KVM: arm/arm64: Reset the VCPU without preemption and vcpu state loaded + - ARM: OMAP2+: fix lack of timer interrupts on CPU1 after hotplug + - Input: cap11xx - switch to using set_brightness_blocking() + - Input: ps2-gpio - flush TX work when closing port + - Input: matrix_keypad - use flush_delayed_work() + - mac80211: Fix Tx aggregation session tear down with ITXQs + - ipvs: fix dependency on nf_defrag_ipv6 + - floppy: check_events callback should not return a negative number + - NFS: Don't use page_file_mapping after removing the page + - mm/gup: fix gup_pmd_range() for dax + - Revert "mm: use early_pfn_to_nid in page_ext_init" + - mm: page_alloc: fix ref bias in page_frag_alloc() for 1-byte allocs + - net: hns: Fix object reference leaks in hns_dsaf_roce_reset() + - i2c: cadence: Fix the hold bit setting + - i2c: bcm2835: Clear current buffer pointers and counts after a transfer + - auxdisplay: ht16k33: fix potential user-after-free on module unload + - Input: st-keyscan - fix potential zalloc NULL dereference + - clk: sunxi-ng: v3s: Fix TCON reset de-assert bit + - clk: sunxi: A31: Fix wrong AHB gate number + - esp: Skip TX bytes accounting when sending from a request socket + - ARM: 8824/1: fix a migrating irq bug when hotplug cpu + - af_key: unconditionally clone on broadcast + - assoc_array: Fix shortcut creation + - keys: Fix dependency loop between construction record and auth key + - scsi: libiscsi: Fix race between iscsi_xmit_task and iscsi_complete_task + - net: systemport: Fix reception of BPDUs + - pinctrl: meson: meson8b: fix the sdxc_a data 1..3 pins + - qmi_wwan: apply SET_DTR quirk to Sierra WP7607 + - net: mv643xx_eth: disable clk on error path in mv643xx_eth_shared_probe() + - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush timeout issue + - ASoC: topology: free created components in tplg load error + - qed: Fix iWARP syn packet mac address validation. + - arm64: Relax GIC version check during early boot + - net: marvell: mvneta: fix DMA debug warning + - tmpfs: fix link accounting when a tmpfile is linked in + - ixgbe: fix older devices that do not support IXGBE_MRQC_L3L4TXSWEN + - ARCv2: lib: memcpy: fix doing prefetchw outside of buffer + - ARC: uacces: remove lp_start, lp_end from clobber list + - ARCv2: support manual regfile save on interrupts + - phonet: fix building with clang + - mac80211_hwsim: propagate genlmsg_reply return code + - net: thunderx: make CFG_DONE message to run through generic send-ack + sequence + - nfp: bpf: fix code-gen bug on BPF_ALU | BPF_XOR | BPF_K + - nfp: bpf: fix ALU32 high bits clearance bug + - net: set static variable an initial value in atl2_probe() + - tmpfs: fix uninitialized return value in shmem_link + - media: videobuf2-v4l2: drop WARN_ON in vb2_warn_zero_bytesused() + - stm class: Prevent division by zero + - libnvdimm/label: Clear 'updating' flag after label-set update + - libnvdimm, pfn: Fix over-trim in trim_pfn_device() + - libnvdimm/pmem: Honor force_raw for legacy pmem regions + - libnvdimm: Fix altmap reservation size calculation + - fix cgroup_do_mount() handling of failure exits + - crypto: arm/crct10dif - revert to C code for short inputs + - crypto: arm64/crct10dif - revert to C code for short inputs + - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails + - crypto: testmgr - skip crc32c context test for ahash algorithms + - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling + - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine + - CIFS: Do not reset lease state to NONE on lease break + - CIFS: Fix read after write for files with read caching + - tracing: Use strncpy instead of memcpy for string keys in hist triggers + - tracing: Do not free iter->trace in fail path of tracing_open_pipe() + - xen: fix dom0 boot on huge systems + - ACPI / device_sysfs: Avoid OF modalias creation for removed device + - mmc: sdhci-esdhc-imx: fix HS400 timing issue + - spi: ti-qspi: Fix mmap read when more than one CS in use + - spi: pxa2xx: Setup maximum supported DMA transfer length + - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35 + - regulator: max77620: Initialize values for DT properties + - regulator: s2mpa01: Fix step values for some LDOs + - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR + - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown + - s390/setup: fix early warning messages + - s390/virtio: handle find on invalid queue gracefully + - scsi: virtio_scsi: don't send sc payload with tmfs + - scsi: aacraid: Fix performance issue on logical drives + - scsi: sd: Optimal I/O size should be a multiple of physical block size + - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock + - fs/devpts: always delete dcache dentry-s in dput() + - splice: don't merge into linked buffers + - m68k: Add -ffreestanding to CFLAGS + - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl + - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes + - Btrfs: fix corruption reading shared and compressed extents after hole + punching + - crypto: pcbc - remove bogus memcpy()s with src == dest + - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer + - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table + - x86/kprobes: Prohibit probing on optprobe template code + - cpufreq: tegra124: add missing of_node_put() + - cpufreq: pxa2xx: remove incorrect __init annotation + - ext4: add mask of ext4 flags to swap + - ext4: fix crash during online resizing + - IB/hfi1: Close race condition on user context disable and close + - cxl: Wrap iterations over afu slices inside 'afu_list_lock' + - ext2: Fix underflow in ext2_max_size() + - clk: uniphier: Fix update register for CPU-gear + - clk: clk-twl6040: Fix imprecise external abort for pdmclk + - clk: ingenic: Fix round_rate misbehaving with non-integer dividers + - clk: ingenic: Fix doc of ingenic_cgu_div_info + - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device() + - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place + - mm: hwpoison: fix thp split handing in soft_offline_in_use_page() + - mm/vmalloc: fix size check for remap_vmalloc_range_partial() + - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv + - device property: Fix the length used in PROPERTY_ENTRY_STRING() + - intel_th: Don't reference unassigned outputs + - parport_pc: fix find_superio io compare code, should use equal test. + - i2c: tegra: fix maximum transfer size + - crypto: arm64/aes-neonbs - fix returning final keystream block + - drm/i915: Relax mmap VMA check + - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO + - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart + - serial: 8250_pci: Fix number of ports for ACCES serial cards + - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954 + chip use the pci_pericom_setup() + - jbd2: clear dirty flag when revoking a buffer from an older transaction + - jbd2: fix compile warning when using JBUFFER_TRACE + - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock + - powerpc/32: Clear on-stack exception marker upon exception return + - powerpc/wii: properly disable use of BATs when requested. + - powerpc/powernv: Make opal log only readable by root + - powerpc/83xx: Also save/restore SPRG4-7 during suspend + - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest + - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning + - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR + configuration + - powerpc/traps: fix recoverability of machine check handling on book3s/32 + - powerpc/traps: Fix the message printed when stack overflows + - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify + - arm64: Fix HCR.TGE status for NMI contexts + - arm64: debug: Ensure debug handlers check triggering exception level + - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2 + - dm: fix to_sector() for 32bit + - dm integrity: limit the rate of error messages + - cpcap-charger: generate events for userspace + - NFS: Fix I/O request leakages + - NFS: Fix an I/O request leakage in nfs_do_recoalesce + - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror() + - nfsd: fix memory corruption caused by readdir + - nfsd: fix wrong check in write_v4_end_grace() + - NFSv4.1: Reinitialise sequence results before retransmitting a request + - PM / wakeup: Rework wakeup source timer cancellation + - x86/unwind/orc: Fix ORC unwind table alignment + - perf intel-pt: Fix CYC timestamp calculation after OVF + - perf auxtrace: Define auxtrace record alignment + - perf intel-pt: Fix overlap detection to identify consecutive buffers + correctly + - perf intel-pt: Fix overlap calculation for padding + - perf intel-pt: Fix divide by zero when TSC is not available + - md: Fix failed allocation of md_register_thread + - tpm/tpm_crb: Avoid unaligned reads in crb_recv() + - tpm: Unify the send callback behaviour + - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt + - media: imx: prpencvf: Stop upstream before disabling IDMA channel + - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming + - media: vimc: Add vimc-streamer for stream control + - media: imx: csi: Disable CSI immediately after last EOF + - media: imx: csi: Stop upstream before disabling IDMA channel + - drm/radeon/evergreen_cs: fix missing break in switch statement + - KVM: Call kvm_arch_memslots_updated() before updating memslots + - KVM: x86/mmu: Detect MMIO generation wrap in any address space + - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux + - KVM: nVMX: Sign extend displacements of VMX instr's mem operands + - KVM: nVMX: Apply addr size mask to effective address for VMX instructions + - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments + - s390/setup: fix boot crash for machine without EDAT-1 + - crypto: caam - fix hash context DMA unmap size + - crypto: caam - fix DMA mapping of stack memory + - KVM: arm/arm64: vgic: Make vgic_dist->lpi_list_lock a raw_spinlock + - arm/arm64: KVM: Allow a VCPU to fully reset itself + - arm/arm64: KVM: Don't panic on failure to properly reset system registers + - ASoC: samsung: Prevent clk_get_rate() calls in atomic context + - mac80211: call drv_ibss_join() on restart + - blk-mq: insert rq with DONTPREP to hctx dispatch list when requeue + - xprtrdma: Make sure Send CQ is allocated on an existing compvec + - net: dsa: bcm_sf2: potential array overflow in bcm_sf2_sw_suspend() + - x86/CPU: Add Icelake model number + - kallsyms: Handle too long symbols in kallsyms.c + - ARM: 8835/1: dma-mapping: Clear DMA ops on teardown + - net: dsa: bcm_sf2: Do not assume DSA master supports WoL + - qed: Fix iWARP buffer size provided for syn packet processing. + - mm: handle lru_add_drain_all for UP properly + - ARCv2: don't assume core 0x54 has dual issue + - bpf, lpm: fix lookup bug in map_delete_elem + - acpi/nfit: Fix bus command validation + - mmc:fix a bug when max_discard is 0 + - netfilter: ipt_CLUSTERIP: fix warning unused variable cn + - [Config] updateconfigs for CONFIG_SUN50I_ERRATUM_UNKNOWN1 + - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer + instability + - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code + - ext4: fix check of inode in swap_inode_boot_loader + - ext4: cleanup pagecache before swap i_data + - ext4: update quota information while swapping boot loader inode + - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit + - mm/memory.c: do_fault: avoid usage of stale vm_area_struct + - media: i2c: ov5640: Fix post-reset delay + - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit + - mfd: sm501: Fix potential NULL pointer dereference + - nfsd: fix performance-limiting session calculation + - svcrpc: fix UDP on servers with lots of threads + - stable-kernel-rules.rst: add link to networking patch queue + - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata + * Bionic update: upstream stable patchset 2019-07-24 (LP: #1837813) + - dt-bindings: eeprom: at24: add "atmel,24c2048" compatible string + - eeprom: at24: add support for 24c2048 + - blk-mq: fix a hung issue when fsync + - ARM: 8789/1: signal: copy registers using __copy_to_user() + - ARM: 8790/1: signal: always use __copy_to_user to save iwmmxt context + - ARM: 8791/1: vfp: use __copy_to_user() when saving VFP state + - ARM: 8792/1: oabi-compat: copy oabi events using __copy_to_user() + - ARM: 8793/1: signal: replace __put_user_error with __put_user + - ARM: 8794/1: uaccess: Prevent speculative use of the current addr_limit + - ARM: 8795/1: spectre-v1.1: use put_user() for __put_user() + - ARM: 8796/1: spectre-v1,v1.1: provide helpers for address sanitization + - ARM: 8797/1: spectre-v1.1: harden __copy_to_user + - ARM: 8810/1: vfp: Fix wrong assignement to ufp_exc + - ARM: make lookup_processor_type() non-__init + - ARM: split out processor lookup + - ARM: clean up per-processor check_bugs method call + - ARM: add PROC_VTABLE and PROC_TABLE macros + - ARM: spectre-v2: per-CPU vtables to work around big.Little systems + - ARM: ensure that processor vtables is not lost after boot + - ARM: fix the cockup in the previous patch + - ACPI: NUMA: Use correct type for printing addresses on i386-PAE + - perf test shell: Use a fallback to get the pathname in vfs_getname + - cpufreq: check if policy is inactive early in __cpufreq_get() + - drm/bridge: tc358767: add defines for DP1_SRCCTRL & PHY_2LANE + - drm/bridge: tc358767: fix single lane configuration + - drm/bridge: tc358767: fix initial DP0/1_SRCCTRL value + - drm/bridge: tc358767: reject modes which require too much BW + - drm/bridge: tc358767: fix output H/V syncs + - nvme-pci: use the same attributes when freeing host_mem_desc_bufs. + - ARM: dts: da850-evm: Correct the sound card name + - ARM: dts: da850-lcdk: Correct the sound card name + - ARM: dts: kirkwood: Fix polarity of GPIO fan lines + - gpio: pl061: handle failed allocations + - drm/nouveau: Don't disable polling in fallback mode + - drm/nouveau/falcon: avoid touching registers if engine is off + - cifs: Limit memory used by lock request calls to a page + - Revert "Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G" + - Input: elan_i2c - add ACPI ID for touchpad in Lenovo V330-15ISK + - perf/core: Fix impossible ring-buffer sizes warning + - perf/x86: Add check_period PMU callback + - ALSA: hda - Add quirk for HP EliteBook 840 G5 + - ALSA: usb-audio: Fix implicit fb endpoint setup by quirk + - kvm: vmx: Fix entry number check for add_atomic_switch_msr() + - Input: bma150 - register input device after setting private data + - Input: elantech - enable 3rd button support on Fujitsu CELSIUS H780 + - mm: proc: smaps_rollup: fix pss_locked calculation + - alpha: fix page fault handling for r16-r18 targets + - alpha: Fix Eiger NR_IRQS to 128 + - tracing/uprobes: Fix output for multiple string arguments + - x86/platform/UV: Use efi_runtime_lock to serialise BIOS calls + - signal: Restore the stop PTRACE_EVENT_EXIT + - md/raid1: don't clear bitmap bits on interrupted recovery. + - x86/a.out: Clear the dump structure initially + - dm crypt: don't overallocate the integrity tag space + - dm thin: fix bug where bio that overwrites thin block ignores FUA + - drm/i915: Prevent a race during I915_GEM_MMAP ioctl with WC set + - perf report: Fix wrong iteration count in --branch-history + - riscv: fix trace_sys_exit hook + - ARM: dts: da850-lcdk: Correct the audio codec regulators + - ARM: OMAP5+: Fix inverted nirq pin interrupts with irq_set_type + - ASoC: hdmi-codec: fix oops on re-probe + - riscv: Add pte bit to distinguish swap from invalid + - mmc: sunxi: Filter out unsupported modes declared in the device tree + - s390/zcrypt: fix specification exception on z196 during ap probe + - drm/i915: Block fbdev HPD processing during suspend + - dsa: mv88e6xxx: Ensure all pending interrupts are handled prior to exit + - net: fix IPv6 prefix route residue + - net: ipv4: use a dedicated counter for icmp_v4 redirect packets + - vsock: cope with memory allocation failure at socket creation time + - vxlan: test dev->flags & IFF_UP before calling netif_rx() + - hwmon: (lm80) Fix missing unlock on error in set_fan_div() + - mlxsw: __mlxsw_sp_port_headroom_set(): Fix a use of local variable + - net: Fix for_each_netdev_feature on Big endian + - net: phy: xgmiitorgmii: Support generic PHY status read + - net: stmmac: Fix a race in EEE enable callback + - net: stmmac: handle endianness in dwmac4_get_timestamp + - vhost: correctly check the return value of translate_desc() in log_used() + - net: Add header for usage of fls64() + - net: Do not allocate page fragments that are not skb aligned + - tcp: clear icsk_backoff in tcp_write_queue_purge() + - sunrpc: fix 4 more call sites that were using stack memory with a + scatterlist + - net/x25: do not hold the cpu too long in x25_new_lci() + - mISDN: fix a race in dev_expire_timer() + - ax25: fix possible use-after-free + - af_packet: fix raw sockets over 6in4 tunnel + - tcp: tcp_v4_err() should be more careful + - mmc: meson-gx: fix interrupt name + - ARM: 8834/1: Fix: kprobes: optimized kprobes illegal instruction + - tracing: Fix number of entries in trace header + - MIPS: eBPF: Always return sign extended 32b values + - mac80211: Restore vif beacon interval if start ap fails + - mac80211: Free mpath object when rhashtable insertion fails + - libceph: handle an empty authorize reply + - ceph: avoid repeatedly adding inode to mdsc->snap_flush_list + - numa: change get_mempolicy() to use nr_node_ids instead of MAX_NUMNODES + - proc, oom: do not report alien mms when setting oom_score_adj + - KEYS: allow reaching the keys quotas exactly + - mfd: ti_am335x_tscadc: Use PLATFORM_DEVID_AUTO while registering mfd cells + - pvcalls-back: set -ENOTCONN in pvcalls_conn_back_read + - mfd: twl-core: Fix section annotations on {,un}protect_pm_master + - mfd: db8500-prcmu: Fix some section annotations + - mfd: mt6397: Do not call irq_domain_remove if PMIC unsupported + - mfd: ab8500-core: Return zero in get_register_interruptible() + - mfd: bd9571mwv: Add volatile register to make DVFS work + - mfd: qcom_rpm: write fw_version to CTRL_REG + - mfd: wm5110: Add missing ASRC rate register + - mfd: tps65218: Use devm_regmap_add_irq_chip and clean up error path in + probe() + - mfd: mc13xxx: Fix a missing check of a register-read failure + - xen/pvcalls: remove set but not used variable 'intf' + - qed: Fix qed_chain_set_prod() for PBL chains with non power of 2 page count + - qed: Fix qed_ll2_post_rx_buffer_notify_fw() by adding a write memory barrier + - net: hns: Fix use after free identified by SLUB debug + - MIPS: ath79: Enable OF serial ports in the default config + - netfilter: nf_tables: fix leaking object reference count + - scsi: qla4xxx: check return code of qla4xxx_copy_from_fwddb_param + - scsi: isci: initialize shost fully before calling scsi_add_host() + - MIPS: jazz: fix 64bit build + - bpf: correctly set initial window on active Fast Open sender + - net: stmmac: Fix PCI module removal leak + - isdn: i4l: isdn_tty: Fix some concurrency double-free bugs + - scsi: ufs: Fix system suspend status + - scsi: qedi: Add ep_state for login completion on un-reachable targets + - always clear the X2APIC_ENABLE bit for PV guest + - drm/meson: add missing of_node_put + - atm: he: fix sign-extension overflow on large shift + - hwmon: (tmp421) Correct the misspelling of the tmp442 compatible attribute + in OF device ID table + - leds: lp5523: fix a missing check of return value of lp55xx_read + - bpf: bpf_setsockopt: reset sock dst on SO_MARK changes + - mlxsw: spectrum_switchdev: Do not treat static FDB entries as sticky + - net/mlx5e: Fix wrong (zero) TX drop counter indication for representor + - isdn: avm: Fix string plus integer warning from Clang + - batman-adv: fix uninit-value in batadv_interface_tx() + - ipv6: propagate genlmsg_reply return code + - net/mlx5e: Don't overwrite pedit action when multiple pedit used + - net/packet: fix 4gb buffer limit due to overflow check + - net: sfp: do not probe SFP module before we're attached + - sctp: call gso_reset_checksum when computing checksum in sctp_gso_segment + - team: avoid complex list operations in team_nl_cmd_options_set() + - sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach() + - net/mlx4_en: Force CHECKSUM_NONE for short ethernet frames + - inet_diag: fix reporting cgroup classid and fallback to priority + - RDMA/srp: Rework SCSI device reset handling + - KEYS: user: Align the payload buffer + - KEYS: always initialize keyring_index_key::desc_len + - parisc: Fix ptrace syscall number modification + - ARCv2: Enable unaligned access in early ASM code + - ARC: U-boot: check arguments paranoidly + - ARC: define ARCH_SLAB_MINALIGN = 8 + - net: validate untrusted gso packets without csum offload + - net: avoid false positives in untrusted gso validation + - Revert "bridge: do not add port to router list when receives query with + source 0.0.0.0" + - netfilter: nf_tables: fix flush after rule deletion in the same batch + - netfilter: nft_compat: use-after-free when deleting targets + - netfilter: ipv6: Don't preserve original oif for loopback address + - pinctrl: max77620: Use define directive for max77620_pinconf_param values + - phy: tegra: remove redundant self assignment of 'map' + - net: phylink: avoid resolving link state too early + - gpio: pxa: avoid attempting to set pin direction via pinctrl on MMP2 + - pvcalls-front: read all data before closing the connection + - pvcalls-front: don't try to free unallocated rings + - pvcalls-front: properly allocate sk + - mfd: cros_ec_dev: Add missing mfd_remove_devices() call in remove + - bpf: Fix [::] -> [::1] rewrite in sys_sendmsg + - watchdog: mt7621_wdt/rt2880_wdt: Fix compilation problem + - net/mlx4: Get rid of page operation after dma_alloc_coherent + - xprtrdma: Double free in rpcrdma_sendctxs_create() + - RDMA/mthca: Clear QP objects during their allocation + - powerpc/8xx: fix setting of pagetable for Abatron BDI debug tool. + - net: stmmac: Fix the logic of checking if RX Watchdog must be enabled + - scsi: ufs: Fix geometry descriptor size + - scsi: cxgb4i: add wait_for_completion() + - afs: Fix key refcounting in file locking code + - dpaa_eth: NETIF_F_LLTX requires to do our own update of trans_start + - mlxsw: pci: Return error on PCI reset timeout + - sctp: set stream ext to NULL after freeing it in sctp_stream_outq_migrate + - drm/amdgpu: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime + - gpu: drm: radeon: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime + - drm/amd/display: Fix MST reboot/poweroff sequence + - mac80211: allocate tailroom for forwarded mesh packets + - netfilter: ipt_CLUSTERIP: fix sleep-in-atomic bug in + clusterip_config_entry_put() + - net: stmmac: Fix reception of Broadcom switches tags + - drm/msm: Unblock writer if reader closes file + - ASoC: Intel: Haswell/Broadwell: fix setting for .dynamic field + - ALSA: compress: prevent potential divide by zero bugs + - ASoC: Variable "val" in function rt274_i2c_probe() could be uninitialized + - clk: vc5: Abort clock configuration without upstream clock + - thermal: int340x_thermal: Fix a NULL vs IS_ERR() check + - usb: dwc3: gadget: synchronize_irq dwc irq in suspend + - usb: dwc3: gadget: Fix the uninitialized link_state when udc starts + - usb: gadget: Potential NULL dereference on allocation error + - genirq: Make sure the initial affinity is not empty + - ASoC: dapm: change snprintf to scnprintf for possible overflow + - ASoC: imx-audmux: change snprintf to scnprintf for possible overflow + - selftests: seccomp: use LDLIBS instead of LDFLAGS + - selftests: gpio-mockup-chardev: Check asprintf() for error + - ARC: fix __ffs return value to avoid build warnings + - drivers: thermal: int340x_thermal: Fix sysfs race condition + - staging: rtl8723bs: Fix build error with Clang when inlining is disabled + - mac80211: fix miscounting of ttl-dropped frames + - sched/wait: Fix rcuwait_wake_up() ordering + - futex: Fix (possible) missed wakeup + - locking/rwsem: Fix (possible) missed wakeup + - drm/amd/powerplay: OD setting fix on Vega10 + - serial: fsl_lpuart: fix maximum acceptable baud rate with over-sampling + - staging: android: ion: Support cpu access during dma_buf_detach + - direct-io: allow direct writes to empty inodes + - writeback: synchronize sync(2) against cgroup writeback membership switches + - scsi: csiostor: fix NULL pointer dereference in csio_vport_set_state() + - net: altera_tse: fix connect_local_phy error path + - hv_netvsc: Fix ethtool change hash key error + - net: usb: asix: ax88772_bind return error when hw_reset fail + - net: dev_is_mac_header_xmit() true for ARPHRD_RAWIP + - ibmveth: Do not process frames after calling napi_reschedule + - mac80211: don't initiate TDLS connection if station is not associated to AP + - mac80211: Add attribute aligned(2) to struct 'action' + - cfg80211: extend range deviation for DMG + - KVM: nSVM: clear events pending from svm_complete_interrupts() when exiting + to L1 + - mmc: spi: Fix card detection during probe + - mmc: tmio_mmc_core: don't claim spurious interrupts + - mmc: tmio: fix access width of Block Count Register + - mmc: sdhci-esdhc-imx: correct the fix of ERR004536 + - MIPS: fix truncation in __cmpxchg_small for short values + - MIPS: eBPF: Fix icache flush end address + - x86/uaccess: Don't leak the AC flag into __put_user() value evaluation + - irq/matrix: Split out the CPU selection code into a helper + - irq/matrix: Spread managed interrupts on allocation + - genirq/matrix: Improve target CPU selection for managed interrupts. + - clk: tegra: dfll: Fix a potential Oop in remove() + - selftests/vm/gup_benchmark.c: match gup struct to kernel + - ARC: show_regs: lockdep: avoid page allocator... + - sched/wake_q: Fix wakeup ordering for wake_q + - drm/sun4i: hdmi: Fix usage of TMDS clock + - scsi: lpfc: nvme: avoid hang / use-after-free when destroying localport + - scsi: lpfc: nvmet: avoid hang / use-after-free when destroying targetport + - mmc: core: Fix NULL ptr crash from mmc_should_fail_request + - drm: Block fb changes for async plane updates + - hugetlbfs: fix races and page leaks during migration + - MIPS: BCM63XX: provide DMA masks for ethernet devices + - cpufreq: Use struct kobj_attribute instead of struct global_attr + - USB: serial: option: add Telit ME910 ECM composition + - USB: serial: cp210x: add ID for Ingenico 3070 + - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485 + - staging: comedi: ni_660x: fix missing break in switch statement + - staging: wilc1000: fix to set correct value for 'vif_num' + - staging: android: ion: fix sys heap pool's gfp_flags + - ip6mr: Do not call __IP6_INC_STATS() from preemptible context + - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in + mv88e6xxx_port_set_duplex + - net-sysfs: Fix mem leak in netdev_register_kobject + - team: Free BPF filter when unregistering netdev + - tipc: fix RDM/DGRAM connect() regression + - bnxt_en: Drop oversize TX packets to prevent errors. + - hv_netvsc: Fix IP header checksum for coalesced packets + - net: dsa: mv88e6xxx: Fix statistics on mv88e6161 + - net: dsa: mv88e6xxx: Fix u64 statistics + - netlabel: fix out-of-bounds memory accesses + - net: netem: fix skb length BUG_ON in __skb_to_sgvec + - net: phy: Micrel KSZ8061: link failure after cable connect + - net: phy: phylink: fix uninitialized variable in phylink_get_mac_state + - net: sit: fix memory leak in sit_init_net() + - tipc: fix race condition causing hung sendto + - tun: fix blocking read + - xen-netback: don't populate the hash cache on XenBus disconnect + - xen-netback: fix occasional leak of grant ref mappings under memory pressure + - tun: remove unnecessary memory barrier + - net: Add __icmp_send helper. + - net: avoid use IPCB in cipso_v4_error + - ipv4: Return error for RTA_VIA attribute + - ipv6: Return error for RTA_VIA attribute + - mpls: Return error for RTA_GATEWAY attribute + - net/sched: act_ipt: fix refcount leak when replace fails + - x86/CPU/AMD: Set the CPB bit unconditionally on F17h + - MIPS: irq: Allocate accurate order pages for irq stack + - xtensa: fix get_wchan + - Bluetooth: Fix locking in bt_accept_enqueue() for BH context + - scsi: core: reset host byte in DID_NEXUS_FAILURE case + - bpf: fix sanitation rewrite in case of non-pointers + - vti4: Fix a ipip packet processing bug in 'IPCOMP' virtual tunnel + - perf core: Fix perf_proc_update_handler() bug + - perf tools: Handle TOPOLOGY headers with no CPU + - IB/{hfi1, qib}: Fix WC.byte_len calculation for UD_SEND_WITH_IMM + - iommu/amd: Call free_iova_fast with pfn in map_sg + - iommu/amd: Unmap all mapped pages in error path of map_sg + - ipvs: Fix signed integer overflow when setsockopt timeout + - iommu/amd: Fix IOMMU page flush when detach device from a domain + - xtensa: SMP: fix ccount_timer_shutdown + - selftests: cpu-hotplug: fix case where CPUs offline > CPUs present + - xtensa: SMP: fix secondary CPU initialization + - xtensa: smp_lx200_defconfig: fix vectors clash + - xtensa: SMP: mark each possible CPU as present + - xtensa: SMP: limit number of possible CPUs by NR_CPUS + - net: altera_tse: fix msgdma_tx_completion on non-zero fill_level case + - net: hns: Fix for missing of_node_put() after of_parse_phandle() + - net: hns: Fix wrong read accesses via Clause 45 MDIO protocol + - net: stmmac: dwmac-rk: fix error handling in rk_gmac_powerup() + - netfilter: ebtables: compat: un-break 32bit setsockopt when no rules are + present + - gpio: vf610: Mask all GPIO interrupts + - selftests: timers: use LDLIBS instead of LDFLAGS + - nfs: Fix NULL pointer dereference of dev_name + - qed: Fix bug in tx promiscuous mode settings + - qed: Fix LACP pdu drops for VFs + - qed: Fix VF probe failure while FLR + - qed: Fix system crash in ll2 xmit + - qed: Fix stack out of bounds bug + - scsi: libfc: free skb when receiving invalid flogi resp + - scsi: 53c700: pass correct "dev" to dma_alloc_attrs() + - platform/x86: Fix unmet dependency warning for SAMSUNG_Q10 + - cifs: fix computation for MAX_SMB2_HDR_SIZE + - x86/microcode/amd: Don't falsely trick the late loading mechanism + - arm64: kprobe: Always blacklist the KVM world-switch code + - apparmor: Fix aa_label_build() error handling for failed merges + - x86/kexec: Don't setup EFI info if EFI runtime is not enabled + - x86_64: increase stack size for KASAN_EXTRA + - mm, memory_hotplug: is_mem_section_removable do not pass the end of a zone + - mm, memory_hotplug: test_pages_in_a_zone do not pass the end of zone + - lib/test_kmod.c: potential double free in error handling + - fs/drop_caches.c: avoid softlockups in drop_pagecache_sb() + - autofs: drop dentry reference only when it is never used + - autofs: fix error return in autofs_fill_super() + - ARM: dts: omap4-droid4: Fix typo in cpcap IRQ flags + - arm64: dts: renesas: r8a7796: Enable DMA for SCIF2 + - soc: fsl: qbman: avoid race in clearing QMan interrupt + - bpf: sock recvbuff must be limited by rmem_max in bpf_setsockopt() + - ARM: pxa: ssp: unneeded to free devm_ allocated data + - arm64: dts: add msm8996 compatible to gicv3 + - DTS: CI20: Fix bugs in ci20's device tree. + - usb: phy: fix link errors + - irqchip/mmp: Only touch the PJ4 IRQ & FIQ bits on enable/disable + - net: stmmac: Fallback to Platform Data clock in Watchdog conversion + - net: stmmac: Send TSO packets always from Queue 0 + - net: stmmac: Disable EEE mode earlier in XMIT callback + - irqchip/gic-v3-its: Fix ITT_entry_size accessor + - relay: check return of create_buf_file() properly + - bpf, selftests: fix handling of sparse CPU allocations + - bpf: fix lockdep false positive in percpu_freelist + - drm/sun4i: tcon: Prepare and enable TCON channel 0 clock at init + - dmaengine: at_xdmac: Fix wrongfull report of a channel as in use + - vsock/virtio: fix kernel panic after device hot-unplug + - vsock/virtio: reset connected sockets on device removal + - dmaengine: dmatest: Abort test in case of mapping error + - selftests: netfilter: fix config fragment CONFIG_NF_TABLES_INET + - selftests: netfilter: add simple masq/redirect test cases + - s390/qeth: fix use-after-free in error path + - perf symbols: Filter out hidden symbols from labels + - perf trace: Support multiple "vfs_getname" probes + - MIPS: Remove function size check in get_frame_info() + - i2c: omap: Use noirq system sleep pm ops to idle device for suspend + - fs: ratelimit __find_get_block_slow() failure message. + - qed: Fix EQ full firmware assert. + - qed: Consider TX tcs while deriving the max num_queues for PF. + - Input: wacom_serial4 - add support for Wacom ArtPad II tablet + - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20 + - iscsi_ibft: Fix missing break in switch statement + - scsi: aacraid: Fix missing break in switch statement + - arm64: dts: hikey: Give wifi some time after power-on + - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3 + - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU + - drm: disable uncached DMA optimization for ARM and arm64 + - ARM: 8781/1: Fix Thumb-2 syscall return for binutils 2.29+ + - gfs2: Fix missed wakeups in find_insert_glock + - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom + - perf/x86/intel: Make cpuc allocations consistent + - perf/x86/intel: Generalize dynamic constraint creation + - x86: Add TSX Force Abort CPUID/MSR + - perf/x86/intel: Implement support for TSX Force Abort + - perf script: Fix crash with printing mixed trace point and other events + - clk: ti: Fix error handling in ti_clk_parse_divider_data() + - riscv: Adjust mmap base address at a third of task size + - IB/ipoib: Fix for use-after-free in ipoib_cm_tx_start + - iomap: fix a use after free in iomap_dio_rw + - selftests: net: use LDLIBS instead of LDFLAGS + - scsi: scsi_debug: fix write_same with virtual_gb problem + - scsi: bnx2fc: Fix error handling in probe() + - ARM: OMAP: dts: N950/N9: fix onenand timings + - ARM: dts: sun8i: h3: Add ethernet0 alias to Beelink X2 + - ARM: dts: imx6sx: correct backward compatible of gpt + - pinctrl: mcp23s08: spi: Fix regmap allocation for mcp23s18 + - bpftool: Fix prog dump by tag + - bpftool: fix percpu maps updating + - batman-adv: release station info tidstats + - irqchip/gic-v4: Fix occasional VLPI drop + - s390/qeth: release cmd buffer in error paths + - nvme-pci: add missing unlock for reset error + - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub + - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4 + * Bionic update: upstream stable patchset 2019-07-23 (LP: #1837664) + - amd-xgbe: Fix mdio access for non-zero ports and clause 45 PHYs + - net: bridge: Fix ethernet header pointer before check skb forwardable + - net: Fix usage of pskb_trim_rcsum + - net: phy: mdio_bus: add missing device_del() in mdiobus_register() error + handling + - net_sched: refetch skb protocol for each filter + - openvswitch: Avoid OOB read when parsing flow nlattrs + - vhost: log dirty page correctly + - net: ipv4: Fix memory leak in network namespace dismantle + - tcp: allow MSG_ZEROCOPY transmission also in CLOSE_WAIT state + - mei: me: add denverton innovation engine device IDs + - USB: serial: simple: add Motorola Tetra TPG2200 device id + - USB: serial: pl2303: add new PID to support PL2303TB + - ASoC: atom: fix a missing check of snd_pcm_lib_malloc_pages + - ASoC: rt5514-spi: Fix potential NULL pointer dereference + - ARCv2: lib: memeset: fix doing prefetchw outside of buffer + - ARC: adjust memblock_reserve of kernel memory + - ARC: perf: map generic branches to correct hardware condition + - s390/smp: fix CPU hotplug deadlock with CPU rescan + - staging: rtl8188eu: Add device code for D-Link DWA-121 rev B1 + - tty: Handle problem if line discipline does not have receive_buf + - uart: Fix crash in uart_write and uart_put_char + - tty/n_hdlc: fix __might_sleep warning + - hv_balloon: avoid touching uninitialized struct page during tail onlining + - Drivers: hv: vmbus: Check for ring when getting debug info + - CIFS: Fix possible hang during async MTU reads and writes + - CIFS: Fix credits calculations for reads with errors + - CIFS: Fix credit calculation for encrypted reads with errors + - CIFS: Do not reconnect TCP session in add_credits() + - Input: xpad - add support for SteelSeries Stratus Duo + - compiler.h: enable builtin overflow checkers and add fallback code + - Input: uinput - fix undefined behavior in uinput_validate_absinfo() + - acpi/nfit: Block function zero DSMs + - acpi/nfit: Fix command-supported detection + - dm thin: fix passdown_double_checking_shared_status() + - dm crypt: fix parsing of extended IV arguments + - KVM: x86: Fix single-step debugging + - x86/pkeys: Properly copy pkey state at fork() + - x86/selftests/pkeys: Fork() to check for state being preserved + - x86/kaslr: Fix incorrect i8254 outb() parameters + - posix-cpu-timers: Unbreak timer rearming + - irqchip/gic-v3-its: Align PCI Multi-MSI allocation on their size + - can: dev: __can_get_echo_skb(): fix bogous check for non-existing skb by + removing it + - can: bcm: check timer values before ktime conversion + - vt: invoke notifier on screen size change + - Revert "seccomp: add a selftest for get_metadata" + - s390/smp: Fix calling smp_call_ipl_cpu() from ipl CPU + - nvmet-rdma: Add unlikely for response allocated check + - nvmet-rdma: fix null dereference under heavy load + - usb: dwc3: gadget: Clear req->needs_extra_trb flag on cleanup + - x86/xen/time: Output xen sched_clock time from 0 + - xen: Fix x86 sched_clock() interface for xen + - mlxsw: pci: Increase PCI SW reset timeout + - mlxsw: spectrum_fid: Update dummy FID index + - ASoC: tlv320aic32x4: Kernel OOPS while entering DAPM standby mode + - s390/mm: always force a load of the primary ASCE on context switch + - mmc: meson-gx: Free irq in release() callback + - vgacon: unconfuse vc_origin when using soft scrollback + - drm/amdgpu: Add APTX quirk for Lenovo laptop + - vt: always call notifier with the console lock held + - drm/meson: Fix atomic mode switching regression + - bpf: improve verifier branch analysis + - bpf: add per-insn complexity limit + - ipv6: Consider sk_bound_dev_if when binding a socket to an address + - ipv6: sr: clear IP6CB(skb) on SRH ip4ip6 encapsulation + - l2tp: copy 4 more bytes to linear part if necessary + - net/mlx4_core: Add masking for a few queries on HCA caps + - netrom: switch to sock timer API + - net/rose: fix NULL ax25_cb kernel panic + - net: set default network namespace in init_dummy_netdev() + - net/mlx5e: Allow MAC invalidation while spoofchk is ON + - Revert "net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager" + - virtio_net: Don't enable NAPI when interface is down + - virtio_net: Don't call free_old_xmit_skbs for xdp_frames + - virtio_net: Fix not restoring real_num_rx_queues + - sctp: improve the events for sctp stream adding + - sctp: improve the events for sctp stream reset + - l2tp: remove l2specific_len dependency in l2tp_core + - l2tp: fix reading optional fields of L2TPv3 + - ipvlan, l3mdev: fix broken l3s mode wrt local routes + - CIFS: Do not count -ENODATA as failure for query directory + - fs/dcache: Fix incorrect nr_dentry_unused accounting in shrink_dcache_sb() + - iommu/vt-d: Fix memory leak in intel_iommu_put_resv_regions() + - NFS: Fix up return value on fatal errors in nfs_page_async_flush() + - ARM: cns3xxx: Fix writing to wrong PCI config registers after alignment + - arm64: kaslr: ensure randomized quantities are clean also when kaslr is off + - arm64: hyp-stub: Forbid kprobing of the hyp-stub + - arm64: hibernate: Clean the __hyp_text to PoC after resume + - gpio: altera-a10sr: Set proper output level for direction_output + - gpio: pcf857x: Fix interrupts on multiple instances + - mmc: bcm2835: Fix DMA channel leak on probe error + - IB/hfi1: Remove overly conservative VM_EXEC flag check + - platform/x86: asus-nb-wmi: Map 0x35 to KEY_SCREENLOCK + - platform/x86: asus-nb-wmi: Drop mapping of 0x33 and 0x34 scan codes + - mmc: sdhci-iproc: handle mmc_of_parse() errors during probe + - kernel/exit.c: release ptraced tasks before zap_pid_ns_processes + - oom, oom_reaper: do not enqueue same task twice + - mm, oom: fix use-after-free in oom_kill_process + - mm: hwpoison: use do_send_sig_info() instead of force_sig() + - mm: migrate: don't rely on __PageMovable() of newpage after unlocking it + - md/raid5: fix 'out of memory' during raid cache recovery + - cifs: Always resolve hostname before reconnecting + - drivers: core: Remove glue dirs from sysfs earlier + - fanotify: fix handling of events on child sub-directory + - drm/msm/gpu: fix building without debugfs + - ravb: expand rx descriptor data to accommodate hw checksum + - tun: move the call to tun_set_real_num_queues + - sctp: set chunk transport correctly when it's a new asoc + - sctp: set flow sport from saddr only when it's 0 + - virtio_net: Don't process redirected XDP frames when XDP is disabled + - CIFS: Do not consider -ENODATA as stat failure for reads + - mmc: mediatek: fix incorrect register setting of hs400_cmd_int_delay + - ALSA: usb-audio: Add Opus #3 to quirks for native DSD support + - Btrfs: fix deadlock when allocating tree block during leaf/node split + - mm/hugetlb.c: teach follow_hugetlb_page() to handle FOLL_NOWAIT + - mm,memory_hotplug: fix scan_movable_pages() for gigantic hugepages + - of: Convert to using %pOFn instead of device_node.name + - of: overlay: add tests to validate kfrees from overlay removal + - of: overlay: add missing of_node_get() in __of_attach_node_sysfs + - of: overlay: use prop add changeset entry for property in new nodes + - ucc_geth: Reset BQL queue when stopping device + - staging: iio: adc: ad7280a: handle error from __ad7280_read32() + - drm/vgem: Fix vgem_init to get drm device available. + - pinctrl: bcm2835: Use raw spinlock for RT compatibility + - ASoC: Intel: mrfld: fix uninitialized variable access + - gpu: ipu-v3: image-convert: Prevent race between run and unprepare + - ath9k: dynack: use authentication messages for 'late' ack + - scsi: lpfc: Correct LCB RJT handling + - scsi: mpt3sas: Call sas_remove_host before removing the target devices + - scsi: lpfc: Fix LOGO/PLOGI handling when triggerd by ABTS Timeout event + - ARM: 8808/1: kexec:offline panic_smp_self_stop CPU + - clk: boston: fix possible memory leak in clk_boston_setup() + - dlm: Don't swamp the CPU with callbacks queued during recovery + - x86/PCI: Fix Broadcom CNB20LE unintended sign extension (redux) + - powerpc/pseries: add of_node_put() in dlpar_detach_node() + - crypto: aes_ti - disable interrupts while accessing S-box + - drm/vc4: ->x_scaling[1] should never be set to VC4_SCALING_NONE + - serial: fsl_lpuart: clear parity enable bit when disable parity + - ptp: check gettime64 return code in PTP_SYS_OFFSET ioctl + - MIPS: Boston: Disable EG20T prefetch + - staging:iio:ad2s90: Make probe handle spi_setup failure + - fpga: altera-cvp: Fix registration for CvP incapable devices + - Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1 + - platform/chrome: don't report EC_MKBP_EVENT_SENSOR_FIFO as wakeup + - staging: iio: ad7780: update voltage on read + - usbnet: smsc95xx: fix rx packet alignment + - drm/rockchip: fix for mailbox read size + - ARM: OMAP2+: hwmod: Fix some section annotations + - net/mlx5: EQ, Use the right place to store/read IRQ affinity hint + - modpost: validate symbol names also in find_elf_symbol + - perf tools: Add Hygon Dhyana support + - soc/tegra: Don't leak device tree node reference + - media: mtk-vcodec: Release device nodes in mtk_vcodec_init_enc_pm() + - ptp: Fix pass zero to ERR_PTR() in ptp_clock_register + - dmaengine: xilinx_dma: Remove __aligned attribute on zynqmp_dma_desc_ll + - iio: adc: meson-saradc: check for devm_kasprintf failure + - iio: adc: meson-saradc: fix internal clock names + - iio: accel: kxcjk1013: Add KIOX010A ACPI Hardware-ID + - media: adv*/tc358743/ths8200: fill in min width/height/pixelclock + - ACPI: SPCR: Consider baud rate 0 as preconfigured state + - staging: pi433: fix potential null dereference + - f2fs: move dir data flush to write checkpoint process + - f2fs: fix race between write_checkpoint and write_begin + - f2fs: fix wrong return value of f2fs_acl_create + - i2c: sh_mobile: add support for r8a77990 (R-Car E3) + - arm64: io: Ensure calls to delay routines are ordered against prior readX() + - sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN + - soc: bcm: brcmstb: Don't leak device tree node reference + - nfsd4: fix crash on writing v4_end_grace before nfsd startup + - drm: Clear state->acquire_ctx before leaving + drm_atomic_helper_commit_duplicated_state() + - arm64: io: Ensure value passed to __iormb() is held in a 64-bit register + - Thermal: do not clear passive state during system sleep + - firmware/efi: Add NULL pointer checks in efivars API functions + - s390/zcrypt: improve special ap message cmd handling + - arm64: ftrace: don't adjust the LR value + - ARM: dts: mmp2: fix TWSI2 + - x86/fpu: Add might_fault() to user_insn() + - media: DaVinci-VPBE: fix error handling in vpbe_initialize() + - smack: fix access permissions for keyring + - usb: dwc3: Correct the logic for checking TRB full in + __dwc3_prepare_one_trb() + - usb: hub: delay hub autosuspend if USB3 port is still link training + - timekeeping: Use proper seqcount initializer + - usb: mtu3: fix the issue about SetFeature(U1/U2_Enable) + - clk: sunxi-ng: a33: Set CLK_SET_RATE_PARENT for all audio module clocks + - driver core: Move async_synchronize_full call + - kobject: return error code if writing /sys/.../uevent fails + - IB/hfi1: Unreserve a reserved request when it is completed + - usb: dwc3: trace: add missing break statement to make compiler happy + - pinctrl: sx150x: handle failure case of devm_kstrdup + - iommu/amd: Fix amd_iommu=force_isolation + - ARM: dts: Fix OMAP4430 SDP Ethernet startup + - mips: bpf: fix encoding bug for mm_srlv32_op + - media: coda: fix H.264 deblocking filter controls + - ARM: dts: Fix up the D-Link DIR-685 MTD partition info + - watchdog: renesas_wdt: don't set divider while watchdog is running + - usb: dwc3: gadget: Disable CSP for stream OUT ep + - iommu/arm-smmu: Add support for qcom,smmu-v2 variant + - iommu/arm-smmu-v3: Use explicit mb() when moving cons pointer + - sata_rcar: fix deferred probing + - clk: imx6sl: ensure MMDC CH0 handshake is bypassed + - cpuidle: big.LITTLE: fix refcount leak + - OPP: Use opp_table->regulators to verify no regulator case + - i2c-axxia: check for error conditions first + - phy: sun4i-usb: add support for missing USB PHY index + - udf: Fix BUG on corrupted inode + - switchtec: Fix SWITCHTEC_IOCTL_EVENT_IDX_ALL flags overwrite + - selftests/bpf: use __bpf_constant_htons in test_prog.c + - ARM: pxa: avoid section mismatch warning + - ASoC: fsl: Fix SND_SOC_EUKREA_TLV320 build error on i.MX8M + - KVM: PPC: Book3S: Only report KVM_CAP_SPAPR_TCE_VFIO on powernv machines + - mmc: bcm2835: Recover from MMC_SEND_EXT_CSD + - mmc: bcm2835: reset host on timeout + - mmc: sdhci-of-esdhc: Fix timeout checks + - mmc: sdhci-xenon: Fix timeout checks + - tty: serial: samsung: Properly set flags in autoCTS mode + - perf test: Fix perf_event_attr test failure + - perf header: Fix unchecked usage of strncpy() + - perf probe: Fix unchecked usage of strncpy() + - arm64: KVM: Skip MMIO insn after emulation + - usb: musb: dsps: fix otg state machine + - percpu: convert spin_lock_irq to spin_lock_irqsave. + - powerpc/uaccess: fix warning/error with access_ok() + - mac80211: fix radiotap vendor presence bitmap handling + - xfrm6_tunnel: Fix spi check in __xfrm6_tunnel_alloc_spi + - mlxsw: spectrum: Properly cleanup LAG uppers when removing port from LAG + - scsi: smartpqi: correct host serial num for ssa + - scsi: smartpqi: correct volume status + - scsi: smartpqi: increase fw status register read timeout + - cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan() + - powerpc/perf: Fix thresholding counter data for unknown type + - drbd: narrow rcu_read_lock in drbd_sync_handshake + - drbd: disconnect, if the wrong UUIDs are attached on a connected peer + - drbd: skip spurious timeout (ping-timeo) when failing promote + - drbd: Avoid Clang warning about pointless switch statment + - video: clps711x-fb: release disp device node in probe() + - fbdev: fbmem: behave better with small rotated displays and many CPUs + - i40e: define proper net_device::neigh_priv_len + - ACPI/APEI: Clear GHES block_status before panic() + - fbdev: fbcon: Fix unregister crash when more than one framebuffer + - powerpc/mm: Fix reporting of kernel execute faults on the 8xx + - pinctrl: meson: meson8: fix the GPIO function for the GPIOAO pins + - pinctrl: meson: meson8b: fix the GPIO function for the GPIOAO pins + - KVM: x86: svm: report MSR_IA32_MCG_EXT_CTL as unsupported + - powerpc/fadump: Do not allow hot-remove memory from fadump reserved area. + - kvm: Change offset in kvm_write_guest_offset_cached to unsigned + - NFS: nfs_compare_mount_options always compare auth flavors. + - hwmon: (lm80) fix a missing check of the status of SMBus read + - hwmon: (lm80) fix a missing check of bus read in lm80 probe + - seq_buf: Make seq_buf_puts() null-terminate the buffer + - crypto: ux500 - Use proper enum in cryp_set_dma_transfer + - crypto: ux500 - Use proper enum in hash_set_dma_transfer + - MIPS: ralink: Select CONFIG_CPU_MIPSR2_IRQ_VI on MT7620/8 + - cifs: check ntwrk_buf_start for NULL before dereferencing it + - um: Avoid marking pages with "changed protection" + - niu: fix missing checks of niu_pci_eeprom_read + - f2fs: fix sbi->extent_list corruption issue + - cgroup: fix parsing empty mount option string + - scripts/decode_stacktrace: only strip base path when a prefix of the path + - ocfs2: don't clear bh uptodate for block read + - ocfs2: improve ocfs2 Makefile + - isdn: hisax: hfc_pci: Fix a possible concurrency use-after-free bug in + HFCPCI_l1hw() + - gdrom: fix a memory leak bug + - fsl/fman: Use GFP_ATOMIC in {memac,tgec}_add_hash_mac_address() + - block/swim3: Fix -EBUSY error when re-opening device after unmount + - thermal: bcm2835: enable hwmon explicitly + - kdb: Don't back trace on a cpu that didn't round up + - thermal: generic-adc: Fix adc to temp interpolation + - HID: lenovo: Add checks to fix of_led_classdev_register + - kernel/hung_task.c: break RCU locks based on jiffies + - proc/sysctl: fix return error for proc_doulongvec_minmax() + - kernel/hung_task.c: force console verbose before panic + - fs/epoll: drop ovflist branch prediction + - scripts/gdb: fix lx-version string output + - thermal: hwmon: inline helpers when CONFIG_THERMAL_HWMON is not set + - dccp: fool proof ccid_hc_[rt]x_parse_options() + - enic: fix checksum validation for IPv6 + - net: dp83640: expire old TX-skb + - rxrpc: bad unlock balance in rxrpc_recvmsg + - skge: potential memory corruption in skge_get_regs() + - rds: fix refcount bug in rds_sock_addref + - net: systemport: Fix WoL with password after deep sleep + - net/mlx5e: Force CHECKSUM_UNNECESSARY for short ethernet frames + - net: dsa: slave: Don't propagate flag changes on down slave interfaces + - ALSA: compress: Fix stop handling on compressed capture streams + - ALSA: hda - Serialize codec registrations + - dmaengine: bcm2835: Fix interrupt race on RT + - dmaengine: bcm2835: Fix abort of transactions + - dmaengine: imx-dma: fix wrong callback invoke + - futex: Handle early deadlock return correctly + - irqchip/gic-v3-its: Plug allocation race for devices sharing a DevID + - usb: phy: am335x: fix race condition in _probe + - usb: dwc3: gadget: Handle 0 xfer length for OUT EP + - usb: gadget: udc: net2272: Fix bitwise and boolean operations + - usb: gadget: musb: fix short isoc packets with inventra dma + - staging: speakup: fix tty-operation NULL derefs + - scsi: cxlflash: Prevent deadlock when adapter probe fails + - scsi: aic94xx: fix module loading + - cpu/hotplug: Fix "SMT disabled by BIOS" detection for KVM + - perf/x86/intel/uncore: Add Node ID mask + - x86/MCE: Initialize mce.bank in the case of a fatal error in + mce_no_way_out() + - perf/core: Don't WARN() for impossible ring-buffer sizes + - perf tests evsel-tp-sched: Fix bitwise operator + - serial: fix race between flush_to_ldisc and tty_open + - serial: 8250_pci: Make PCI class test non fatal + - IB/hfi1: Add limit test for RC/UC send via loopback + - perf/x86/intel: Delay memory deallocation until x86_pmu_dead_cpu() + - ath9k: dynack: make ewma estimation faster + - ath9k: dynack: check da->enabled first in sampling routines + - devres: Align data[] to ARCH_KMALLOC_MINALIGN + - genirq/affinity: Spread IRQs to all available NUMA nodes + - wil6210: fix memory leak in wil_find_tx_bcast_2 + - fpga: altera-cvp: fix 'bad IO access' on x86_64 + - drm/amd/display: calculate stream->phy_pix_clk before clock mapping + - net: aquantia: return 'err' if set MPI_DEINIT state fails + - perf: arm_spe: handle devm_kasprintf() failure + - xtensa: xtfpga.dtsi: fix dtc warnings about SPI + - media: imx274: select REGMAP_I2C + - drm/amdgpu/powerplay: fix clock stretcher limits on polaris (v2) + - tipc: fix node keep alive interval calculation + - mmc: meson-mx-sdio: check devm_kasprintf for failure + - mmc: sdhci-omap: Fix timeout checks + - mmc: jz4740: Get CD/WP GPIOs from descriptors + - usb: renesas_usbhs: add support for RZ/G2E + - i2c: sh_mobile: Add support for r8a774c0 (RZ/G2E) + - livepatch: check kzalloc return values + - usb: musb: dsps: fix runtime pm for peripheral mode + - perf header: Fix up argument to ctime() + - drm/amd/display: Add retry to read ddc_clock pin + - Bluetooth: hci_bcm: Handle deferred probing for the clock supply + - mlx5: update timecounter at least twice per counter overflow + - drm/amd/display: validate extended dongle caps + - perf build: Don't unconditionally link the libbfd feature test to -liberty + and -lz + - PCI: imx: Enable MSI from downstream components + - arm64/sve: ptrace: Fix SVE_PT_REGS_OFFSET definition + - kernel/kcov.c: mark write_comp_data() as notrace + - xfs: Fix xqmstats offsets in /proc/fs/xfs/xqmstat + - xfs: Fix error code in 'xfs_ioc_getbmap()' + - xfs: fix shared extent data corruption due to missing cow reservation + - xfs: fix transient reference count error in xfs_buf_resubmit_failed_buffers + - xfs: delalloc -> unwritten COW fork allocation can go wrong + - fs/xfs: fix f_ffree value for statfs when project quota is set + - lib/test_rhashtable: Make test_insert_dup() allocate its hash table + dynamically + - net: dsa: Fix lockdep false positive splat + - Revert "net: phy: marvell: avoid pause mode on SGMII-to-Copper for 88e151x" + - ALSA: hda/realtek - Fix lose hp_pins for disable auto mute + - serial: sh-sci: Do not free irqs that have already been freed + - mtd: rawnand: gpmi: fix MX28 bus master lockup problem + - iio: adc: axp288: Fix TS-pin handling + - iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius + - signal: Always notice exiting tasks + - signal: Better detection of synchronous signals + - misc: vexpress: Off by one in vexpress_syscfg_exec() + - samples: mei: use /dev/mei0 instead of /dev/mei + - debugfs: fix debugfs_rename parameter checking + - tracing: uprobes: Fix typo in pr_fmt string + - mips: cm: reprime error cause + - MIPS: OCTEON: don't set octeon_dma_bar_type if PCI is disabled + - MIPS: VDSO: Include $(ccflags-vdso) in o32,n32 .lds builds + - ARM: iop32x/n2100: fix PCI IRQ mapping + - ARM: tango: Improve ARCH_MULTIPLATFORM compatibility + - mac80211: ensure that mgmt tx skbs have tailroom for encryption + - drm/modes: Prevent division by zero htotal + - drm/vmwgfx: Fix setting of dma masks + - drm/vmwgfx: Return error code from vmw_execbuf_copy_fence_user + - HID: debug: fix the ring buffer implementation + - libceph: avoid KEEPALIVE_PENDING races in ceph_con_keepalive() + - xfrm: refine validation of template and selector families + - batman-adv: Avoid WARN on net_device without parent in netns + - batman-adv: Force mac header to start of data on xmit + - uio: Reduce return paths from uio_write() + - uio: Prevent device destruction while fds are open + - uio: change to use the mutex lock instead of the spin lock + - uio: fix crash after the device is unregistered + - uio: fix wrong return value from uio_mmap() + - uio: fix possible circular locking dependency + - mtd: Make sure mtd->erasesize is valid even if the partition is of size 0 + - libata: Add NOLPM quirk for SAMSUNG MZ7TE512HMHP-000L1 SSD + - mips: loongson64: remove unreachable(), fix loongson_poweroff(). + - SUNRPC: Always drop the XPRT_LOCK on XPRT_CLOSE_WAIT + * HP ProBook 470 G5, LED's in Hotkeys f5, f8 and f11 without function + (LP: #1811254) // Bionic update: upstream stable patchset 2019-07-23 + (LP: #1837664) + - ALSA: hda - Add mute LED support for HP ProBook 470 G5 + * Bionic update: upstream stable patchset 2019-07-22 (LP: #1837477) + - pinctrl: meson: fix pull enable register calculation + - powerpc: Fix COFF zImage booting on old powermacs + - powerpc/mm: Fix linux page tables build with some configs + - HID: ite: Add USB id match for another ITE based keyboard rfkill key quirk + - ARM: imx: update the cpu power up timing setting on i.mx6sx + - ARM: dts: imx7d-nitrogen7: Fix the description of the Wifi clock + - Input: restore EV_ABS ABS_RESERVED + - checkstack.pl: fix for aarch64 + - xfrm: Fix error return code in xfrm_output_one() + - xfrm: Fix bucket count reported to userspace + - xfrm: Fix NULL pointer dereference in xfrm_input when skb_dst_force clears + the dst_entry. + - netfilter: seqadj: re-load tcp header pointer after possible head + reallocation + - scsi: bnx2fc: Fix NULL dereference in error handling + - Input: omap-keypad - fix idle configuration to not block SoC idle states + - Input: synaptics - enable RMI on ThinkPad T560 + - ibmvnic: Fix non-atomic memory allocation in IRQ context + - ieee802154: ca8210: fix possible u8 overflow in ca8210_rx_done + - i40e: fix mac filter delete when setting mac address + - netfilter: ipset: do not call ipset_nest_end after nla_nest_cancel + - netfilter: nat: can't use dst_hold on noref dst + - bnx2x: Clear fip MAC when fcoe offload support is disabled + - bnx2x: Remove configured vlans as part of unload sequence. + - bnx2x: Send update-svid ramrod with retry/poll flags enabled + - scsi: target: iscsi: cxgbit: add missing spin_lock_init() + - x86, hyperv: remove PCI dependency + - drivers: net: xgene: Remove unnecessary forward declarations + - w90p910_ether: remove incorrect __init annotation + - SUNRPC: Fix a race with XPRT_CONNECTING + - qed: Fix an error code qed_ll2_start_xmit() + - net: macb: fix random memory corruption on RX with 64-bit DMA + - net: macb: fix dropped RX frames due to a race + - lan78xx: Resolve issue with changing MAC address + - vxge: ensure data0 is initialized in when fetching firmware version + information + - mac80211: free skb fraglist before freeing the skb + - kbuild: fix false positive warning/error about missing libelf + - virtio: fix test build after uio.h change + - gpio: mvebu: only fail on missing clk if pwm is actually to be used + - Input: synaptics - enable SMBus for HP EliteBook 840 G4 + - net: netxen: fix a missing check and an uninitialized use + - qmi_wwan: Fix qmap header retrieval in qmimux_rx_fixup + - serial/sunsu: fix refcount leak + - scsi: zfcp: fix posting too many status read buffers leading to adapter + shutdown + - scsi: lpfc: do not set queue->page_count to 0 if pc_sli4_params.wqpcnt is + invalid + - tools: fix cross-compile var clobbering + - zram: fix double free backing device + - hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined + - mm, devm_memremap_pages: mark devm_memremap_pages() EXPORT_SYMBOL_GPL + - mm, devm_memremap_pages: kill mapping "System RAM" support + - mm, hmm: use devm semantics for hmm_devmem_{add, remove} + - mm, hmm: mark hmm_devmem_{add, add_resource} EXPORT_SYMBOL_GPL + - mm, swap: fix swapoff with KSM pages + - sunrpc: fix cache_head leak due to queued request + - powerpc: avoid -mno-sched-epilog on GCC 4.9 and newer + - powerpc: Disable -Wbuiltin-requires-header when setjmp is used + - ftrace: Build with CPPFLAGS to get -Qunused-arguments + - kbuild: add -no-integrated-as Clang option unconditionally + - kbuild: consolidate Clang compiler flags + - Makefile: Export clang toolchain variables + - powerpc/boot: Set target when cross-compiling for clang + - raid6/ppc: Fix build for clang + - ALSA: cs46xx: Potential NULL dereference in probe + - ALSA: usb-audio: Avoid access before bLength check in build_audio_procunit() + - ALSA: usb-audio: Fix an out-of-bound read in create_composite_quirks + - dlm: fixed memory leaks after failed ls_remove_names allocation + - dlm: possible memory leak on error path in create_lkb() + - dlm: lost put_lkb on error path in receive_convert() and receive_unlock() + - dlm: memory leaks on error path in dlm_user_request() + - gfs2: Get rid of potential double-freeing in gfs2_create_inode + - b43: Fix error in cordic routine + - selinux: policydb - fix byte order and alignment issues + - scripts/kallsyms: filter arm64's __efistub_ symbols + - arm64: drop linker script hack to hide __efistub_ symbols + - arm64: relocatable: fix inconsistencies in linker script and options + - powerpc/tm: Set MSR[TS] just prior to recheckpoint + - 9p/net: put a lower bound on msize + - rxe: fix error completion wr_id and qp_num + - iommu/vt-d: Handle domain agaw being less than iommu agaw + - sched/fair: Fix infinite loop in update_blocked_averages() by reverting + a9e7f6544b9c + - ceph: don't update importing cap's mseq when handing cap export + - genwqe: Fix size check + - intel_th: msu: Fix an off-by-one in attribute store + - power: supply: olpc_battery: correct the temperature units + - lib: fix build failure in CONFIG_DEBUG_VIRTUAL test + - drm/vc4: Set ->is_yuv to false when num_planes == 1 + - bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw + - tools: power/acpi, revert to LD = gcc + - ARM: dts: sun8i: a83t: bananapi-m3: increase vcc-pd voltage to 3.3V + - arm64: dts: mt7622: fix no more console output on rfb1 + - ibmvnic: Convert reset work item mutex to spin lock + - ixgbe: Fix race when the VF driver does a reset + - net: macb: add missing barriers when reading descriptors + - powerpc: remove old GCC version checks + - Fix failure path in alloc_pid() + - block: deactivate blk_stat timer in wbt_disable_default() + - PCI / PM: Allow runtime PM without callback functions + - leds: pwm: silently error out on EPROBE_DEFER + - Revert "powerpc/tm: Unset MSR[TS] if not recheckpointing" + - iio: dac: ad5686: fix bit shift read register + - video: fbdev: pxafb: Fix "WARNING: invalid free of devm_ allocated data" + - drivers/perf: hisi: Fixup one DDRC PMU register offset + - drm/nouveau/drm/nouveau: Check rc from drm_dp_mst_topology_mgr_resume() + - drm/rockchip: psr: do not dereference encoder before it is null checked. + - CIFS: Fix adjustment of credits for MTU requests + - CIFS: Do not hide EINTR after sending network packets + - cifs: Fix potential OOB access of lock element array + - usb: cdc-acm: send ZLP for Telit 3G Intel based modems + - USB: storage: don't insert sane sense for SPC3+ when bad sense specified + - USB: storage: add quirk for SMI SM3350 + - USB: Add USB_QUIRK_DELAY_CTRL_MSG quirk for Corsair K70 RGB + - slab: alien caches must not be initialized if the allocation of the alien + cache failed + - mm: page_mapped: don't assume compound page is huge or THP + - mm, memcg: fix reclaim deadlock with writeback + - ACPI: power: Skip duplicate power resource references in _PRx + - ACPI / PMIC: xpower: Fix TS-pin current-source handling + - i2c: dev: prevent adapter retries and timeout being set as minus value + - drm/fb-helper: Partially bring back workaround for bugs of SDL 1.2 + - rbd: don't return 0 on unmap if RBD_DEV_FLAG_REMOVING is set + - ext4: make sure enough credits are reserved for dioread_nolock writes + - ext4: fix a potential fiemap/page fault deadlock w/ inline_data + - ext4: avoid kernel warning when writing the superblock to a dead device + - ext4: track writeback errors using the generic tracking infrastructure + - KVM: arm/arm64: Fix VMID alloc race by reverting to lock-less + - Btrfs: fix deadlock when using free space tree due to block group creation + - mm/usercopy.c: no check page span for stack objects + - vfio/type1: Fix unmap overflow off-by-one + - drm/amdgpu: Don't ignore rc from drm_dp_mst_topology_mgr_resume() + - ext4: fix special inode number checks in __ext4_iget() + - Btrfs: fix access to available allocation bits when starting balance + - Btrfs: use nofs context when initializing security xattrs to avoid deadlock + - tty/ldsem: Wake up readers after timed out down_write() + - can: gw: ensure DLC boundaries after CAN frame modification + - mmc: sdhci-msm: Disable CDR function on TX + - media: em28xx: Fix misplaced reset of dev->v4l::field_count + - scsi: target: iscsi: cxgbit: fix csk leak + - scsi: target: iscsi: cxgbit: fix csk leak + - arm64/kvm: consistently handle host HCR_EL2 flags + - arm64: Don't trap host pointer auth use to EL2 + - ipv6: fix kernel-infoleak in ipv6_local_error() + - net: bridge: fix a bug on using a neighbour cache entry without checking its + state + - packet: Do not leak dev refcounts on error exit + - bonding: update nest level on unlink + - ip: on queued skb use skb_header_pointer instead of pskb_may_pull + - crypto: caam - fix zero-length buffer DMA mapping + - crypto: authencesn - Avoid twice completion call in decrypt path + - crypto: bcm - convert to use crypto_authenc_extractkeys() + - btrfs: wait on ordered extents on abort cleanup + - Yama: Check for pid death before checking ancestry + - scsi: core: Synchronize request queue PM status only on successful resume + - scsi: sd: Fix cache_type_store() + - crypto: talitos - reorder code in talitos_edesc_alloc() + - crypto: talitos - fix ablkcipher for CONFIG_VMAP_STACK + - mips: fix n32 compat_ipc_parse_version + - MIPS: lantiq: Fix IPI interrupt handling + - OF: properties: add missing of_node_put + - mfd: tps6586x: Handle interrupts on suspend + - media: v4l: ioctl: Validate num_planes for debug messages + - pstore/ram: Avoid allocation and leak of platform data + - arm64: kaslr: ensure randomized quantities are clean to the PoC + - Disable MSI also when pcie-octeon.pcie_disable on + - omap2fb: Fix stack memory disclosure + - media: vivid: fix error handling of kthread_run + - media: vivid: set min width/height to a value > 0 + - bpf: in __bpf_redirect_no_mac pull mac only if present + - LSM: Check for NULL cred-security on free + - media: vb2: vb2_mmap: move lock up + - sunrpc: handle ENOMEM in rpcb_getport_async + - netfilter: ebtables: account ebt_table_info to kmemcg + - selinux: fix GPF on invalid policy + - blockdev: Fix livelocks on loop device + - sctp: allocate sctp_sockaddr_entry with kzalloc + - tipc: fix uninit-value in tipc_nl_compat_link_reset_stats + - tipc: fix uninit-value in tipc_nl_compat_bearer_enable + - tipc: fix uninit-value in tipc_nl_compat_link_set + - tipc: fix uninit-value in tipc_nl_compat_name_table_dump + - tipc: fix uninit-value in tipc_nl_compat_doit + - block/loop: Don't grab "struct file" for vfs_getattr() operation. + - loop: drop caches if offset or block_size are changed + - drm/fb-helper: Ignore the value of fb_var_screeninfo.pixclock + - media: vb2: be sure to unlock mutex on errors + - nbd: Use set_blocksize() to set device blocksize + - tun: publish tfile after it's fully initialized + - crypto: sm3 - fix undefined shift by >= width of value + - MIPS: BCM47XX: Setup struct device for the SoC + - RDMA/vmw_pvrdma: Return the correct opcode when creating WR + - arm64: dts: marvell: armada-ap806: reserve PSCI area + - ipv6: make icmp6_send() robust against null skb->dev + - block: use rcu_work instead of call_rcu to avoid sleep in softirq + - selftests: Fix test errors related to lib.mk khdr target + - ipv6: Consider sk_bound_dev_if when binding a socket to a v4 mapped address + - mlxsw: spectrum: Disable lag port TX before removing it + - mlxsw: spectrum_switchdev: Set PVID correctly during VLAN deletion + - net, skbuff: do not prefer skb allocation fails early + - qmi_wwan: add MTU default to qmap network interface + - ipv6: Take rcu_read_lock in __inet6_bind for mapped addresses + - net: dsa: mv88x6xxx: mv88e6390 errata + - gpio: pl061: Move irq_chip definition inside struct pl061 + - platform/x86: asus-wmi: Tell the EC the OS will handle the display off + hotkey + - e1000e: allow non-monotonic SYSTIM readings + - writeback: don't decrement wb->refcnt if !wb->bdi + - serial: set suppress_bind_attrs flag only if builtin + - ALSA: oxfw: add support for APOGEE duet FireWire + - x86/mce: Fix -Wmissing-prototypes warnings + - MIPS: SiByte: Enable swiotlb for SWARM, LittleSur and BigSur + - arm64: perf: set suppress_bind_attrs flag to true + - usb: gadget: udc: renesas_usb3: add a safety connection way for + forced_b_device + - selinux: always allow mounting submounts + - rxe: IB_WR_REG_MR does not capture MR's iova field + - jffs2: Fix use of uninitialized delayed_work, lockdep breakage + - clk: imx: make mux parent strings const + - pstore/ram: Do not treat empty buffers as valid + - powerpc/xmon: Fix invocation inside lock region + - powerpc/pseries/cpuidle: Fix preempt warning + - media: firewire: Fix app_info parameter type in avc_ca{,_app}_info + - media: venus: core: Set dma maximum segment size + - net: call sk_dst_reset when set SO_DONTROUTE + - scsi: target: use consistent left-aligned ASCII INQUIRY data + - selftests: do not macro-expand failed assertion expressions + - clk: imx6q: reset exclusive gates on init + - arm64: Fix minor issues with the dcache_by_line_op macro + - kconfig: fix file name and line number of warn_ignored_character() + - kconfig: fix memory leak when EOF is encountered in quotation + - mmc: atmel-mci: do not assume idle after atmci_request_end + - btrfs: improve error handling of btrfs_add_link + - tty/serial: do not free trasnmit buffer page under port lock + - perf intel-pt: Fix error with config term "pt=0" + - perf svghelper: Fix unchecked usage of strncpy() + - perf parse-events: Fix unchecked usage of strncpy() + - netfilter: ipt_CLUSTERIP: check MAC address when duplicate config is set + - dm crypt: use u64 instead of sector_t to store iv_offset + - dm kcopyd: Fix bug causing workqueue stalls + - tools lib subcmd: Don't add the kernel sources to the include path + - dm snapshot: Fix excessive memory usage and workqueue stalls + - quota: Lock s_umount in exclusive mode for Q_XQUOTA{ON,OFF} quotactls. + - clocksource/drivers/integrator-ap: Add missing of_node_put() + - ALSA: bebob: fix model-id of unit for Apogee Ensemble + - sysfs: Disable lockdep for driver bind/unbind files + - IB/usnic: Fix potential deadlock + - scsi: smartpqi: correct lun reset issues + - scsi: smartpqi: call pqi_free_interrupts() in pqi_shutdown() + - scsi: megaraid: fix out-of-bound array accesses + - ocfs2: fix panic due to unrecovered local alloc + - mm/page-writeback.c: don't break integrity writeback on ->writepage() error + - mm/swap: use nr_node_ids for avail_lists in swap_info_struct + - mm, proc: be more verbose about unstable VMA flags in /proc//smaps + - cifs: allow disabling insecure dialects in the config + - cifs: In Kconfig CONFIG_CIFS_POSIX needs depends on legacy (insecure cifs) + - PCI: dwc: Move interrupt acking into the proper callback + - ipmi:ssif: Fix handling of multi-part return messages + - net: clear skb->tstamp in bridge forwarding path + - netfilter: ipset: Allow matching on destination MAC address for mac and + ipmac sets + - drm/amdkfd: fix interrupt spin lock + - of: overlay: add missing of_node_put() after add new node to changeset + - drm/atomic-helper: Complete fake_commit->flip_done potentially earlier + - ASoC: pcm3168a: Don't disable pcm3168a when CONFIG_PM defined + - efi/libstub: Disable some warnings for x86{,_64} + - media: uvcvideo: Refactor teardown of uvc on USB disconnect + - arm64: kasan: Increase stack size for KASAN_EXTRA + - bpf: relax verifier restriction on BPF_MOV | BPF_ALU + - perf vendor events intel: Fix Load_Miss_Real_Latency on SKL/SKX + - netfilter: ipt_CLUSTERIP: remove wrong WARN_ON_ONCE in netns exit routine + - netfilter: ipt_CLUSTERIP: fix deadlock in netns exit routine + - x86/topology: Use total_cpus for max logical packages calculation + - perf stat: Avoid segfaults caused by negated options + - perf tools: Add missing sigqueue() prototype for systems lacking it + - perf tools: Add missing open_memstream() prototype for systems lacking it + - dm: Check for device sector overflow if CONFIG_LBDAF is not set + - userfaultfd: clear flag if remap event not enabled + * Bionic update: upstream stable patchset 2019-07-19 (LP: #1837257) + - pinctrl: sunxi: a83t: Fix IRQ offset typo for PH11 + - userfaultfd: check VM_MAYWRITE was set after verifying the uffd is + registered + - arm64: dma-mapping: Fix FORCE_CONTIGUOUS buffer clearing + - MMC: OMAP: fix broken MMC on OMAP15XX/OMAP5910/OMAP310 + - mmc: sdhci: fix the timeout check window for clock and reset + - ARM: mmp/mmp2: fix cpu_is_mmp2() on mmp2-dt + - dm thin: send event about thin-pool state change _after_ making it + - dm cache metadata: verify cache has blocks in + blocks_are_clean_separate_dirty() + - tracing: Fix memory leak in set_trigger_filter() + - tracing: Fix memory leak of instance function hash filters + - powerpc/msi: Fix NULL pointer access in teardown code + - drm/nouveau/kms: Fix memory leak in nv50_mstm_del() + - drm/i915/execlists: Apply a full mb before execution for Braswell + - drm/amdgpu: update SMC firmware image for polaris10 variants + - x86/build: Fix compiler support check for CONFIG_RETPOLINE + - locking: Remove smp_read_barrier_depends() from queued_spin_lock_slowpath() + - locking/qspinlock: Ensure node is initialised before updating prev->next + - locking/qspinlock: Bound spinning on pending->locked transition in slowpath + - locking/qspinlock: Merge 'struct __qspinlock' into 'struct qspinlock' + - locking/qspinlock: Remove unbounded cmpxchg() loop from locking slowpath + - locking/qspinlock: Remove duplicate clear_pending() function from PV code + - locking/qspinlock: Kill cmpxchg() loop when claiming lock from head of queue + - locking/qspinlock: Re-order code + - locking/qspinlock/x86: Increase _Q_PENDING_LOOPS upper bound + - locking/qspinlock, x86: Provide liveness guarantee + - mac80211: don't WARN on bad WMM parameters from buggy APs + - mac80211: Fix condition validating WMM IE + - IB/hfi1: Remove race conditions in user_sdma send path + - locking/qspinlock: Fix build for anonymous union in older GCC compilers + - mac80211_hwsim: fix module init error paths for netlink + - Input: hyper-v - fix wakeup from suspend-to-idle + - scsi: libiscsi: Fix NULL pointer dereference in iscsi_eh_session_reset + - scsi: vmw_pscsi: Rearrange code to avoid multiple calls to free_irq during + unload + - x86/earlyprintk/efi: Fix infinite loop on some screen widths + - drm/msm: Grab a vblank reference when waiting for commit_done + - ARC: io.h: Implement reads{x}()/writes{x}() + - bonding: fix 802.3ad state sent to partner when unbinding slave + - bpf: Fix verifier log string check for bad alignment. + - nfs: don't dirty kernel pages read by direct-io + - SUNRPC: Fix a potential race in xprt_connect() + - sbus: char: add of_node_put() + - drivers/sbus/char: add of_node_put() + - drivers/tty: add missing of_node_put() + - ide: pmac: add of_node_put() + - drm/msm: Fix error return checking + - clk: mvebu: Off by one bugs in cp110_of_clk_get() + - clk: mmp: Off by one in mmp_clk_add() + - Input: synaptics - enable SMBus for HP 15-ay000 + - Input: omap-keypad - fix keyboard debounce configuration + - libata: whitelist all SAMSUNG MZ7KM* solid-state disks + - mv88e6060: disable hardware level MAC learning + - net/mlx4_en: Fix build break when CONFIG_INET is off + - ARM: 8814/1: mm: improve/fix ARM v7_dma_inv_range() unaligned address + handling + - ARM: 8815/1: V7M: align v7m_dma_inv_range() with v7 counterpart + - ethernet: fman: fix wrong of_node_put() in probe function + - drm/ast: Fix connector leak during driver unload + - vhost/vsock: fix reset orphans race with close timeout + - mlxsw: spectrum_switchdev: Fix VLAN device deletion via ioctl + - i2c: axxia: properly handle master timeout + - i2c: scmi: Fix probe error on devices with an empty SMB0001 ACPI device node + - i2c: uniphier: fix violation of tLOW requirement for Fast-mode + - i2c: uniphier-f: fix violation of tLOW requirement for Fast-mode + - nvmet-rdma: fix response use after free + - rtc: snvs: Add timeouts to avoid kernel lockups + - bpf, arm: fix emit_ldx_r and emit_mov_i using TMP_REG_1 + - scsi: raid_attrs: fix unused variable warning + - staging: olpc_dcon: add a missing dependency + - ARM: dts: qcom-apq8064-arrow-sd-600eval fix graph_endpoint warning + - mmc: core: use mrq->sbc when sending CMD23 for RPMB + - dm: call blk_queue_split() to impose device limits on bios + - media: vb2: don't call __vb2_queue_cancel if vb2_start_streaming failed + - powerpc: Look for "stdout-path" when setting up legacy consoles + - dm zoned: Fix target BIO completion handling + - block: fix infinite loop if the device loses discard capability + - ASoC: sta32x: set ->component pointer in private struct + - perf record: Synthesize features before events in pipe mode + - USB: hso: Fix OOB memory access in hso_probe/hso_get_config_data + - xhci: Don't prevent USB2 bus suspend in state check intended for USB3 only + - USB: xhci: fix 'broken_suspend' placement in struct xchi_hcd + - USB: serial: option: add GosunCn ZTE WeLink ME3630 + - USB: serial: option: add HP lt4132 + - USB: serial: option: add Simcom SIM7500/SIM7600 (MBIM mode) + - USB: serial: option: add Fibocom NL668 series + - USB: serial: option: add Telit LN940 series + - scsi: sd: use mempool for discard special page + - mmc: core: Reset HPI enabled state during re-init and in case of errors + - mmc: core: Allow BKOPS and CACHE ctrl even if no HPI support + - mmc: core: Use a minimum 1600ms timeout when enabling CACHE ctrl + - mmc: omap_hsmmc: fix DMA API warning + - gpio: max7301: fix driver for use with CONFIG_VMAP_STACK + - gpiolib-acpi: Only defer request_irq for GpioInt ACPI event handlers + - posix-timers: Fix division by zero bug + - kvm: x86: Add AMD's EX_CFG to the list of ignored MSRs + - Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels + - x86/mtrr: Don't copy uninitialized gentry fields back to userspace + - panic: avoid deadlocks in re-entrant console drivers + - iwlwifi: mvm: don't send GEO_TX_POWER_LIMIT to old firmwares + - iwlwifi: add new cards for 9560, 9462, 9461 and killer series + - ubifs: Handle re-linking of inodes correctly while recovery + - mm: don't miss the last page because of round-off error + - proc/sysctl: don't return ENOMEM on lookup when a table is unregistering + - i2c: rcar: check bus state before reinitializing + - drm/amd/display: Fix 6x4K displays light-up on Vega20 (v2) + - drm/msm: Fix task dump in gpu recovery + - drm/msm: fix handling of cmdstream offset + - net: aquantia: fix rx checksum offload bits + - liquidio: read sc->iq_no before release sc + - drm/msm/hdmi: Enable HPD after HDMI IRQ is set up + - macvlan: return correct error value + - bpf: check pending signals while verifying programs + - ARM: 8816/1: dma-mapping: fix potential uninitialized return + - tools/testing/nvdimm: Align test resources to 128M + - Btrfs: fix missing delayed iputs on unmount + - ax25: fix a use-after-free in ax25_fillin_cb() + - gro_cell: add napi_disable in gro_cells_destroy + - ibmveth: fix DMA unmap error in ibmveth_xmit_start error path + - ieee802154: lowpan_header_create check must check daddr + - ipv6: explicitly initialize udp6_addr in udp_sock_create6() + - ipv6: tunnels: fix two use-after-free + - isdn: fix kernel-infoleak in capi_unlocked_ioctl + - net: macb: restart tx after tx used bit read + - net: phy: Fix the issue that netif always links up after resuming + - netrom: fix locking in nr_find_socket() + - net/wan: fix a double free in x25_asy_open_tty() + - packet: validate address length + - packet: validate address length if non-zero + - ptr_ring: wrap back ->producer in __ptr_ring_swap_queue() + - qmi_wwan: Added support for Telit LN940 series + - sctp: initialize sin6_flowinfo for ipv6 addrs in sctp_inet6addr_event + - tcp: fix a race in inet_diag_dump_icsk() + - tipc: fix a double kfree_skb() + - vhost: make sure used idx is seen before log in vhost_add_used_n() + - VSOCK: Send reset control packet when socket is partially bound + - xen/netfront: tolerate frags with no data + - net/mlx5: Typo fix in del_sw_hw_rule + - net/mlx5e: RX, Fix wrong early return in receive queue poll + - mlxsw: core: Increase timeout during firmware flash process + - net/mlx5e: Remove the false indication of software timestamping support + - tipc: use lock_sock() in tipc_sk_reinit() + - tipc: compare remote and local protocols in tipc_udp_enable() + - qmi_wwan: Added support for Fibocom NL668 series + - qmi_wwan: Add support for Fibocom NL678 series + - net/smc: fix TCP fallback socket release + - sock: Make sock->sk_stamp thread-safe + - IB/hfi1: Incorrect sizing of sge for PIO will OOPs + - mtd: atmel-quadspi: disallow building on ebsa110 + - ALSA: hda: add mute LED support for HP EliteBook 840 G4 + - ALSA: fireface: fix for state to fetch PCM frames + - ALSA: firewire-lib: fix wrong handling payload_length as payload_quadlet + - ALSA: firewire-lib: fix wrong assignment for 'out_packet_without_header' + tracepoint + - ALSA: firewire-lib: use the same print format for 'without_header' + tracepoints + - ALSA: hda/tegra: clear pending irq handlers + - USB: serial: pl2303: add ids for Hewlett-Packard HP POS pole displays + - USB: serial: option: add Fibocom NL678 series + - usb: r8a66597: Fix a possible concurrency use-after-free bug in + r8a66597_endpoint_disable() + - staging: wilc1000: fix missing read_write setting when reading data + - qmi_wwan: apply SET_DTR quirk to the SIMCOM shared device ID + - s390/pci: fix sleeping in atomic during hotplug + - x86/speculation/l1tf: Drop the swap storage limit restriction when l1tf=off + - KVM: x86: Use jmp to invoke kvm_spurious_fault() from .fixup + - KVM: nVMX: Free the VMREAD/VMWRITE bitmaps if alloc_kvm_area() fails + - platform-msi: Free descriptors in platform_msi_domain_free() + - perf pmu: Suppress potential format-truncation warning + - ext4: add ext4_sb_bread() to disambiguate ENOMEM cases + - ext4: fix possible use after free in ext4_quota_enable + - ext4: missing unlock/put_page() in ext4_try_to_write_inline_data() + - ext4: fix EXT4_IOC_GROUP_ADD ioctl + - ext4: include terminating u32 in size of xattr entries when expanding inodes + - ext4: force inode writes when nfsd calls commit_metadata() + - ext4: check for shutdown and r/o file system in ext4_write_inode() + - spi: bcm2835: Fix race on DMA termination + - spi: bcm2835: Fix book-keeping of DMA termination + - spi: bcm2835: Avoid finishing transfer prematurely in IRQ mode + - clk: rockchip: fix typo in rk3188 spdif_frac parent + - crypto: cavium/nitrox - fix a DMA pool free failure + - cgroup: fix CSS_TASK_ITER_PROCS + - cdc-acm: fix abnormal DATA RX issue for Mediatek Preloader. + - Btrfs: fix fsync of files with multiple hard links in new directories + - f2fs: fix validation of the block count in sanity_check_raw_super + - serial: uartps: Fix interrupt mask issue to handle the RX interrupts + properly + - media: vivid: free bitmap_cap when updating std/timings/etc. + - media: v4l2-tpg: array index could become negative + - MIPS: math-emu: Write-protect delay slot emulation pages + - MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 + - MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() + - MIPS: Align kernel load address to 64KB + - MIPS: Expand MIPS32 ASIDs to 64 bits + - MIPS: OCTEON: mark RGMII interface disabled on OCTEON III + - CIFS: Fix error mapping for SMB2_LOCK command which caused OFD lock problem + - arm64: KVM: Avoid setting the upper 32 bits of VTCR_EL2 to 1 + - arm/arm64: KVM: vgic: Force VM halt when changing the active state of GICv3 + PPIs/SGIs + - rtc: m41t80: Correct alarm month range with RTC reads + - tpm: tpm_i2c_nuvoton: use correct command duration for TPM 2.x + - spi: bcm2835: Unbreak the build of esoteric configs + - MIPS: Only include mmzone.h when CONFIG_NEED_MULTIPLE_NODES=y + - KVM: X86: Fix NULL deref in vcpu_scan_ioapic + - futex: Cure exit race + - x86/mm: Fix decoy address handling vs 32-bit builds + - x86/intel_rdt: Ensure a CPU remains online for the region's pseudo-locking + sequence + - mm: add mm_pxd_folded checks to pgtable_bytes accounting functions + - mm: make the __PAGETABLE_PxD_FOLDED defines non-empty + - mm: introduce mm_[p4d|pud|pmd]_folded + - ip: validate header length on virtual device xmit + - net: clear skb->tstamp in forwarding paths + - net/hamradio/6pack: use mod_timer() to rearm timers + - tipc: check tsk->group in tipc_wait_for_cond() + - tipc: check group dests after tipc_wait_for_cond() + - ipv6: frags: Fix bogus skb->sk in reassembled packets + - ALSA: hda/realtek: Enable audio jacks of ASUS UX391UA with ALC294 + - ALSA: hda/realtek: Enable the headset mic auto detection for ASUS laptops + - ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook + Clapper + - ASoC: intel: cht_bsw_max98090_ti: Add pmc_plt_clk_0 quirk for Chromebook + Gnawty + - Input: elan_i2c - add ACPI ID for touchpad in ASUS Aspire F5-573G + - arm64: KVM: Make VHE Stage-2 TLB invalidation operations non-interruptible + - DRM: UDL: get rid of useless vblank initialization + - clocksource/drivers/arc_timer: Utilize generic sched_clock + - ocxl: Fix endiannes bug in ocxl_link_update_pe() + - ocxl: Fix endiannes bug in read_afu_name() + - ext4: add verifier check for symlink with append/immutable flags + - ext4: avoid declaring fs inconsistent due to invalid file handles + - clk: sunxi-ng: Use u64 for calculation of NM rate + - crypto: testmgr - add AES-CFB tests + - btrfs: dev-replace: go back to suspended state if target device is missing + - btrfs: run delayed items before dropping the snapshot + - powerpc/tm: Unset MSR[TS] if not recheckpointing + - f2fs: read page index before freeing + - f2fs: sanity check of xattr entry size + - media: cec: keep track of outstanding transmits + - media: imx274: fix stack corruption in imx274_read_reg + - media: vb2: check memory model for VIDIOC_CREATE_BUFS + - MIPS: Fix a R10000_LLSC_WAR logic in atomic.h + - KVM: arm/arm64: vgic: Do not cond_resched_lock() with IRQs disabled + - KVM: arm/arm64: vgic: Cap SPIs to the VM-defined maximum + * alsa/hda: neither mute led nor mic-mute led work on several Lenovo laptops + (LP: #1837963) + - SAUCE: ALSA: hda - Add a conexant codec entry to let mute led work + + -- Stefan Bader Thu, 15 Aug 2019 19:46:04 +0200 + +linux-oracle (4.15.0-1021.23) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1021.23 -proposed tracker (LP: #1839280) + + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + [ Ubuntu: 4.15.0-58.64 ] + + * unable to handle kernel NULL pointer dereference at 000000000000002c (IP: + iget5_locked+0x9e/0x1f0) (LP: #1838982) + - Revert "ovl: set I_CREATING on inode being created" + - Revert "new primitive: discard_new_inode()" + + -- Kleber Sacilotto de Souza Wed, 07 Aug 2019 17:41:57 +0200 + +linux-oracle (4.15.0-1020.22) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-57.63 ] + + * CVE-2019-1125 + - x86/cpufeatures: Carve out CQM features retrieval + - x86/cpufeatures: Combine word 11 and 12 into a new scattered features word + - x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations + - x86/speculation: Enable Spectre v1 swapgs mitigations + - x86/entry/64: Use JMP instead of JMPQ + - x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS + * Packaging resync (LP: #1786013) + - update dkms package versions + + -- Kleber Sacilotto de Souza Fri, 02 Aug 2019 14:44:04 +0200 + +linux-oracle (4.15.0-1019.21) bionic; urgency=medium + + * bionic/linux-oracle: 4.15.0-1019.21 -proposed tracker (LP: #1837616) + + * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940) + - [Config] linux-oracle: remove CONFIG_DRM_HISI_HIBMC=m + + * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] linux-oracle: add build deps for building dkms + + [ Ubuntu: 4.15.0-56.62 ] + + * bionic/linux: 4.15.0-56.62 -proposed tracker (LP: #1837626) + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] update helper scripts + * CVE-2019-2101 + - media: uvcvideo: Fix 'type' check leading to overflow + * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940) + - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only + - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64 + * Bionic: support for Solarflare X2542 network adapter (sfc driver) + (LP: #1836635) + - sfc: make mem_bar a function rather than a constant + - sfc: support VI strides other than 8k + - sfc: add Medford2 (SFC9250) PCI Device IDs + - sfc: improve PTP error reporting + - sfc: update EF10 register definitions + - sfc: populate the timer reload field + - sfc: update MCDI protocol headers + - sfc: support variable number of MAC stats + - sfc: expose FEC stats on Medford2 + - sfc: expose CTPIO stats on NICs that support them + - sfc: basic MCDI mapping of 25/50/100G link speeds + - sfc: support the ethtool ksettings API properly so that 25/50/100G works + - sfc: add bits for 25/50/100G supported/advertised speeds + - sfc: remove tx and MCDI handling from NAPI budget consideration + - sfc: handle TX timestamps in the normal data path + - sfc: add function to determine which TX timestamping method to use + - sfc: use main datapath for HW timestamps if available + - sfc: only enable TX timestamping if the adapter is licensed for it + - sfc: MAC TX timestamp handling on the 8000 series + - sfc: on 8000 series use TX queues for TX timestamps + - sfc: only advertise TX timestamping if we have the license for it + - sfc: simplify RX datapath timestamping + - sfc: support separate PTP and general timestamping + - sfc: support second + quarter ns time format for receive datapath + - sfc: support Medford2 frequency adjustment format + - sfc: add suffix to large constant in ptp + - sfc: mark some unexported symbols as static + - sfc: update MCDI protocol headers + - sfc: support FEC configuration through ethtool + - sfc: remove ctpio_dmabuf_start from stats + - sfc: stop the TX queue before pushing new buffers + * [18.04 FEAT] zKVM: Add hardware CPU Model - kernel part (LP: #1836153) + - KVM: s390: add debug logging for cpu model subfunctions + - KVM: s390: implement subfunction processor calls + - KVM: s390: add vector enhancements facility 2 to cpumodel + - KVM: s390: add vector BCD enhancements facility to cpumodel + - KVM: s390: add MSA9 to cpumodel + - KVM: s390: provide query function for instructions returning 32 byte + - KVM: s390: add enhanced sort facilty to cpu model + - KVM: s390: add deflate conversion facilty to cpu model + - KVM: s390: enable MSA9 keywrapping functions depending on cpu model + * Intel ethernet I219 has slow RX speed (LP: #1836152) + - SAUCE: e1000e: add workaround for possible stalled packet + - SAUCE: e1000e: disable force K1-off feature + * Intel ethernet I219 may wrongly detect connection speed as 10Mbps + (LP: #1836177) + - SAUCE: e1000e: Make watchdog use delayed work + * Unhide Nvidia HDA audio controller (LP: #1836308) + - PCI: Enable NVIDIA HDA controllers + * selftests: Remove broken Power9 paste tests and fix compilation issue + (LP: #1836715) + - selftests/powerpc: Remove Power9 paste tests + - selftests/powerpc: Fix Makefiles for headers_install change + * ixgbe{vf} - Physical Function gets IRQ when VF checks link state + (LP: #1836760) + - ixgbevf: Use cached link state instead of re-reading the value for ethtool + * Fix nf_conntrack races when dealing with same origin requests in NAT + environments (LP: #1836816) + - netfilter: nf_conntrack: resolve clash for matching conntracks + - netfilter: nf_nat: skip nat clash resolution for same-origin entries + * CVE-2018-5383 + - crypto: ecdh - add public key verification test + * sched: Prevent CPU lockups when task groups take longer than the period + (LP: #1836971) + - sched/fair: Limit sched_cfs_period_timer() loop to avoid hard lockup + * depmod may prefer unsigned l-r-m nvidia modules to signed modules + (LP: #1834479) + - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files + - [Packaging] Add update-version-dkms + - update dkms package versions + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) // zfs/spl + build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] dkms-build--nvidia-* -- convert to generic -N form + * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378) + - [Packaging] dkms -- dkms package build packaging support + - [Packaging] dkms -- build zfs/spl packages + - [Packaging] dkms -- drop zfs/spl source code from kernel + * Build Nvidia drivers in conjunction with kernel (LP: #1764792) + - [Packaging] dkms -- introduce dkms package versions + - [Packaging] dkms -- add per package post-process step + - [Packaging] dkms -- switch to a consistent build prefix length and strip + - [Packaging] dkms-build -- support building against packages in PPAs + - [Packaging] dkms-build: do not redownload files on subsequent passes + - [Packaging] dkms-build -- add support for unversioned overrides + - [Packaging] dkms-build -- backport latest version from disco + - [Packaging] nvidia -- build and sign nvidia packages and ship signatures + - [Packaging] nvidia -- make nvidia package version explicit + * CVE-2019-13233 + - x86/insn-eval: Fix use-after-free access to LDT entry + * kernel panic using CIFS share in smb2_push_mandatory_locks() (LP: #1795659) + - CIFS: keep FileInfo handle live during oplock break + * cifs set_oplock buffer overflow in strcat (LP: #1824981) + - cifs: fix strcat buffer overflow and reduce raciness in + smb21_set_oplock_level() + * CVE-2019-13272 + - ptrace: Fix ->ptracer_cred handling for PTRACE_TRACEME + * Bionic update: upstream stable patchset 2019-07-18 (LP: #1837161) + - Kbuild: suppress packed-not-aligned warning for default setting only + - disable stringop truncation warnings for now + - test_hexdump: use memcpy instead of strncpy + - kobject: Replace strncpy with memcpy + - ALSA: intel_hdmi: Use strlcpy() instead of strncpy() + - unifdef: use memcpy instead of strncpy + - kernfs: Replace strncpy with memcpy + - ip_tunnel: Fix name string concatenate in __ip_tunnel_create() + - scsi: bfa: convert to strlcpy/strlcat + - kdb: use memmove instead of overlapping memcpy + - iser: set sector for ambiguous mr status errors + - uprobes: Fix handle_swbp() vs. unregister() + register() race once more + - MIPS: ralink: Fix mt7620 nd_sd pinmux + - mips: fix mips_get_syscall_arg o32 check + - IB/mlx5: Avoid load failure due to unknown link width + - drm/ast: Fix incorrect free on ioregs + - drm: set is_master to 0 upon drm_new_set_master() failure + - drm/meson: Enable fast_io in meson_dw_hdmi_regmap_config + - drm/meson: Fix OOB memory accesses in meson_viu_set_osd_lut() + - ALSA: trident: Suppress gcc string warning + - kgdboc: Fix restrict error + - kgdboc: Fix warning with module build + - svm: Add mutex_lock to protect apic_access_page_done on AMD systems + - drm/msm: fix OF child-node lookup + - Input: xpad - quirk all PDP Xbox One gamepads + - Input: synaptics - add PNP ID for ThinkPad P50 to SMBus + - Input: matrix_keypad - check for errors from of_get_named_gpio() + - Input: cros_ec_keyb - fix button/switch capability reports + - Input: elan_i2c - add ELAN0620 to the ACPI table + - Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15ARR + - Input: elan_i2c - add support for ELAN0621 touchpad + - btrfs: tree-checker: Don't check max block group size as current max chunk + size limit is unreliable + - ARC: change defconfig defaults to ARCv2 + - arc: [devboards] Add support of NFSv3 ACL + - reset: make device_reset_optional() really optional + - reset: remove remaining WARN_ON() in + - mm: hide incomplete nr_indirectly_reclaimable in /proc/zoneinfo + - net: qed: use correct strncpy() size + - tipc: use destination length for copy string + - arm64: ftrace: Fix to enable syscall events on arm64 + - sched, trace: Fix prev_state output in sched_switch tracepoint + - tracing/fgraph: Fix set_graph_function from showing interrupts + - drm/meson: Fixes for drm_crtc_vblank_on/off support + - scsi: lpfc: fix block guard enablement on SLI3 adapters + - media: omap3isp: Unregister media device as first + - iommu/vt-d: Fix NULL pointer dereference in prq_event_thread() + - brcmutil: really fix decoding channel info for 160 MHz bandwidth + - iommu/ipmmu-vmsa: Fix crash on early domain free + - can: rcar_can: Fix erroneous registration + - test_firmware: fix error return getting clobbered + - HID: input: Ignore battery reported by Symbol DS4308 + - batman-adv: Use explicit tvlv padding for ELP packets + - batman-adv: Expand merged fragment buffer for full packet + - amd/iommu: Fix Guest Virtual APIC Log Tail Address Register + - bnx2x: Assign unique DMAE channel number for FW DMAE transactions. + - qed: Fix PTT leak in qed_drain() + - qed: Fix reading wrong value in loop condition + - net/mlx4_core: Zero out lkey field in SW2HW_MPT fw command + - net/mlx4_core: Fix uninitialized variable compilation warning + - net/mlx4: Fix UBSAN warning of signed integer overflow + - gpio: mockup: fix indicated direction + - mtd: rawnand: qcom: Namespace prefix some commands + - mtd: spi-nor: Fix Cadence QSPI page fault kernel panic + - qed: Fix bitmap_weight() check + - qed: Fix QM getters to always return a valid pq + - net: faraday: ftmac100: remove netif_running(netdev) check before disabling + interrupts + - iommu/vt-d: Use memunmap to free memremap + - flexfiles: use per-mirror specified stateid for IO + - ibmvnic: Fix RX queue buffer cleanup + - team: no need to do team_notify_peers or team_mcast_rejoin when disabling + port + - net: amd: add missing of_node_put() + - usb: quirk: add no-LPM quirk on SanDisk Ultra Flair device + - usb: appledisplay: Add 27" Apple Cinema Display + - USB: check usb_get_extra_descriptor for proper size + - ALSA: hda: Add support for AMD Stoney Ridge + - ALSA: pcm: Fix starvation on down_write_nonblock() + - ALSA: pcm: Call snd_pcm_unlink() conditionally at closing + - ALSA: pcm: Fix interval evaluation with openmin/max + - ALSA: hda/realtek - Fix speaker output regression on Thinkpad T570 + - SUNRPC: Fix leak of krb5p encode pages + - dmaengine: dw: Fix FIFO size for Intel Merrifield + - dmaengine: cppi41: delete channel from pending list when stop channel + - ARM: 8806/1: kprobes: Fix false positive with FORTIFY_SOURCE + - xhci: Prevent U1/U2 link pm states if exit latency is too long + - f2fs: fix to do sanity check with block address in main area v2 + - swiotlb: clean up reporting + - Staging: lustre: remove two build warnings + - staging: atomisp: remove "fun" strncpy warning + - cifs: Fix separator when building path from dentry + - staging: rtl8712: Fix possible buffer overrun + - Revert commit ef9209b642f "staging: rtl8723bs: Fix indenting errors and an + off-by-one mistake in core/rtw_mlme_ext.c" + - drm/amdgpu: update mc firmware image for polaris12 variants + - drm/amdgpu/gmc8: update MC firmware for polaris + - tty: serial: 8250_mtk: always resume the device in probe. + - kgdboc: fix KASAN global-out-of-bounds bug in param_set_kgdboc_var() + - libnvdimm, pfn: Pad pfn namespaces relative to other regions + - mac80211: Clear beacon_int in ieee80211_do_stop + - mac80211: ignore tx status for PS stations in ieee80211_tx_status_ext + - mac80211: fix reordering of buffered broadcast packets + - mac80211: ignore NullFunc frames in the duplicate detection + - qed: Fix rdma_info structure allocation + - drm/amdgpu: Add amdgpu "max bpc" connector property (v2) + - drivers/net/ethernet/qlogic/qed/qed_rdma.h: fix typo + - gpio: pxa: fix legacy non pinctrl aware builds again + - tc-testing: tdc.py: ignore errors when decoding stdout/stderr + - NFSv4: Fix a NFSv4 state manager deadlock + - USB: serial: console: fix reported terminal settings + - ALSA: usb-audio: Add SMSL D1 to quirks for native DSD support + - ALSA: hda/realtek: ALC286 mic and headset-mode fixups for Acer Aspire + U27-880 + - ALSA: hda/realtek - Add support for Acer Aspire C24-860 headset mic + - ALSA: hda/realtek: Fix mic issue on Acer AIO Veriton Z4660G + - ALSA: hda/realtek: Fix mic issue on Acer AIO Veriton Z4860G/Z6860G + - media: dvb-pll: don't re-validate tuner frequencies + - parisc: Enable -ffunction-sections for modules on 32-bit kernel + - Revert "x86/e820: put !E820_TYPE_RAM regions into memblock.reserved" + - drm/lease: Send a distinct uevent + - drm/msm: Move fence put to where failure occurs + - drm/amdgpu/gmc8: always load MC firmware in the driver + - drm/i915: Downgrade Gen9 Plane WM latency error + - x86/efi: Allocate e820 buffer before calling efi_exit_boot_service + - cfg80211: Fix busy loop regression in ieee80211_ie_split_ric() + - ipv4: ipv6: netfilter: Adjust the frag mem limit when truesize changes + - ipv6: Check available headroom in ip6_xmit() even without options + - neighbour: Avoid writing before skb->head in neigh_hh_output() + - ipv6: sr: properly initialize flowi6 prior passing to ip6_route_output + - net: 8139cp: fix a BUG triggered by changing mtu with network traffic + - net/mlx4_core: Correctly set PFC param if global pause is turned off. + - net/mlx4_en: Change min MTU size to ETH_MIN_MTU + - net: phy: don't allow __set_phy_supported to add unsupported modes + - net: Prevent invalid access to skb->prev in __qdisc_drop_all + - rtnetlink: ndo_dflt_fdb_dump() only work for ARPHRD_ETHER devices + - sctp: kfree_rcu asoc + - tcp: Do not underestimate rwnd_limited + - tcp: fix NULL ref in tail loss probe + - tun: forbid iface creation with rtnl ops + - virtio-net: keep vnet header zeroed after processing XDP + - ARM: OMAP2+: prm44xx: Fix section annotation on + omap44xx_prm_enable_io_wakeup + - ASoC: rsnd: fixup clock start checker + - staging: rtl8723bs: Fix the return value in case of error in + 'rtw_wx_read32()' + - ARM: dts: logicpd-somlv: Fix interrupt on mmc3_dat1 + - ARM: OMAP1: ams-delta: Fix possible use of uninitialized field + - sysv: return 'err' instead of 0 in __sysv_write_inode + - selftests: add script to stress-test nft packet path vs. control plane + - netfilter: nf_tables: fix use-after-free when deleting compat expressions + - hwmon (ina2xx) Fix NULL id pointer in probe() + - ASoC: wm_adsp: Fix dma-unsafe read of scratch registers + - s390/cpum_cf: Reject request for sampling in event initialization + - hwmon: (ina2xx) Fix current value calculation + - ASoC: omap-abe-twl6040: Fix missing audio card caused by deferred probing + - ASoC: dapm: Recalculate audio map forcely when card instantiated + - netfilter: xt_hashlimit: fix a possible memory leak in htable_create() + - hwmon: (w83795) temp4_type has writable permission + - perf tools: Restore proper cwd on return from mnt namespace + - PCI: imx6: Fix link training status detection in link up check + - objtool: Fix double-free in .cold detection error path + - objtool: Fix segfault in .cold detection with -ffunction-sections + - ARM: dts: at91: sama5d2: use the divided clock for SMC + - Btrfs: send, fix infinite loop due to directory rename dependencies + - RDMA/mlx5: Fix fence type for IB_WR_LOCAL_INV WR + - RDMA/rdmavt: Fix rvt_create_ah function signature + - ASoC: omap-mcbsp: Fix latency value calculation for pm_qos + - ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns with CPU_IDLE + - ASoC: omap-dmic: Add pm_qos handling to avoid overruns with CPU_IDLE + - exportfs: do not read dentry after free + - bpf: fix check of allowed specifiers in bpf_trace_printk + - ipvs: call ip_vs_dst_notifier earlier than ipv6_dev_notf + - USB: omap_udc: use devm_request_irq() + - USB: omap_udc: fix crashes on probe error and module removal + - USB: omap_udc: fix omap_udc_start() on 15xx machines + - USB: omap_udc: fix USB gadget functionality on Palm Tungsten E + - USB: omap_udc: fix rejection of out transfers when DMA is used + - drm/meson: add support for 1080p25 mode + - netfilter: ipv6: Preserve link scope traffic original oif + - IB/mlx5: Fix page fault handling for MW + - KVM: x86: fix empty-body warnings + - x86/kvm/vmx: fix old-style function declaration + - net: thunderx: fix NULL pointer dereference in nic_remove + - usb: gadget: u_ether: fix unsafe list iteration + - netfilter: nf_tables: deactivate expressions in rule replecement routine + - igb: fix uninitialized variables + - ixgbe: recognize 1000BaseLX SFP modules as 1Gbps + - net: hisilicon: remove unexpected free_netdev + - drm/amdgpu: Add delay after enable RLC ucode + - drm/ast: fixed reading monitor EDID not stable issue + - xen: xlate_mmu: add missing header to fix 'W=1' warning + - Revert "xen/balloon: Mark unallocated host memory as UNUSABLE" + - pstore/ram: Correctly calculate usable PRZ bytes + - fscache, cachefiles: remove redundant variable 'cache' + - nvme: flush namespace scanning work just before removing namespaces + - ACPI/IORT: Fix iort_get_platform_device_domain() uninitialized pointer value + - ocfs2: fix deadlock caused by ocfs2_defrag_extent() + - mm/page_alloc.c: fix calculation of pgdat->nr_zones + - hfs: do not free node before using + - hfsplus: do not free node before using + - debugobjects: avoid recursive calls with kmemleak + - ocfs2: fix potential use after free + - printk: Add console owner and waiter logic to load balance console writes + - printk: Hide console waiter logic into helpers + - printk: Never set console_may_schedule in console_trylock() + - printk: Wake klogd when passing console_lock owner + - flexfiles: enforce per-mirror stateid only for v4 DSes + - staging: speakup: Replace strncpy with memcpy + - ALSA: fireface: fix reference to wrong register for clock configuration + - IB/hfi1: Fix an out-of-bounds access in get_hw_stats + - tcp: lack of available data can also cause TSO defer + - Revert "net/ibm/emac: wrong bit is used for STA control" + - tools: bpftool: prevent infinite loop in get_fdinfo() + - ASoC: sun8i-codec: fix crash on module removal + - ASoC: acpi: fix: continue searching when machine is ignored + - RDMA/bnxt_re: Fix system hang when registration with L2 driver fails + - RDMA/bnxt_re: Avoid accessing the device structure after it is freed + - RDMA/hns: Bugfix pbl configuration for rereg mr + - thunderbolt: Prevent root port runtime suspend during NVM upgrade + - netfilter: add missing error handling code for register functions + - netfilter: nat: fix double register in masquerade modules + - cachefiles: Fix an assertion failure when trying to update a failed object + - fscache: Fix race in fscache_op_complete() due to split atomic_sub & read + - pvcalls-front: fixes incorrect error handling + - nvme: warn when finding multi-port subsystems without multipathing enabled + - kernel/kcov.c: mark funcs in __sanitizer_cov_trace_pc() as notrace + - ALSA: hda/realtek: ALC294 mic and headset-mode fixups for ASUS X542UN + - ALSA: hda/realtek: Enable audio jacks of ASUS UX533FD with ALC294 + - ALSA: hda/realtek: Enable audio jacks of ASUS UX433FN/UX333FA with ALC294 + * Bionic update: upstream stable patchset 2019-07-17 (LP: #1836968) + - flow_dissector: do not dissect l4 ports for fragments + - ibmvnic: fix accelerated VLAN handling + - ip_tunnel: don't force DF when MTU is locked + - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF + - net-gro: reset skb->pkt_type in napi_reuse_skb() + - sctp: not allow to set asoc prsctp_enable by sockopt + - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths + - tuntap: fix multiqueue rx + - net: systemport: Protect stop from timeout + - net: qualcomm: rmnet: Fix incorrect assignment of real_dev + - net: dsa: microchip: initialize mutex before use + - sctp: fix strchange_flags name for Stream Change Event + - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs + - sctp: not increase stream's incnt before sending addstrm_in request + - mlxsw: spectrum: Fix IP2ME CPU policer configuration + - net: smsc95xx: Fix MTU range + - usbnet: smsc95xx: disable carrier check while suspending + - inet: frags: better deal with smp races + - ARM: dts: r8a7791: Correct critical CPU temperature + - ARM: dts: r8a7793: Correct critical CPU temperature + - net: bcmgenet: protect stop from timeout + - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP + coalescing + - tipc: don't assume linear buffer when reading ancillary data + - tipc: fix link re-establish failure + - net/mlx5e: Claim TC hw offloads support only under a proper build config + - net/mlx5e: Adjust to max number of channles when re-attaching + - net/mlx5e: Fix selftest for small MTUs + - l2tp: fix a sock refcnt leak in l2tp_tunnel_register + - net/mlx5e: IPoIB, Reset QP after channels are closed + - net: dsa: mv88e6xxx: Fix clearing of stats counters + - net: phy: realtek: fix RTL8201F sysfs name + - sctp: define SCTP_SS_DEFAULT for Stream schedulers + - rxrpc: Fix lockup due to no error backoff after ack transmit error + - cifs: don't dereference smb_file_target before null check + - cifs: fix return value for cifs_listxattr + - arm64: kprobe: make page to RO mode when allocate it + - ixgbe: fix MAC anti-spoofing filter after VFLR + - reiserfs: propagate errors from fill_with_dentries() properly + - hfs: prevent btree data loss on root split + - hfsplus: prevent btree data loss on root split + - um: Give start_idle_thread() a return code + - drm/edid: Add 6 bpc quirk for BOE panel. + - platform/x86: intel_telemetry: report debugfs failure + - clk: fixed-rate: fix of_node_get-put imbalance + - perf symbols: Set PLT entry/header sizes properly on Sparc + - fs/exofs: fix potential memory leak in mount option parsing + - clk: samsung: exynos5420: Enable PERIS clocks for suspend + - apparmor: Fix uninitialized value in aa_split_fqname + - x86/earlyprintk: Add a force option for pciserial device + - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307 + - arm64: percpu: Initialize ret in the default case + - s390/vdso: add missing FORCE to build targets + - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and + replace + - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net + - s390/mm: Fix ERROR: "__node_distance" undefined! + - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment() + - netfilter: xt_IDLETIMER: add sysfs filename checking routine + - s390/qeth: fix HiperSockets sniffer + - hwmon: (ibmpowernv) Remove bogus __init annotations + - Revert "drm/exynos/decon5433: implement frame counter" + - clk: fixed-factor: fix of_node_get-put imbalance + - lib/raid6: Fix arm64 test build + - s390/perf: Change CPUM_CF return code in event init function + - sched/core: Take the hotplug lock in sched_init_smp() + - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features + - qed: Fix memory/entry leak in qed_init_sp_request() + - qed: Fix blocking/unlimited SPQ entries leak + - qed: Fix potential memory corruption + - net: stmmac: Fix RX packet size > 8191 + - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer() + - ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM + - perf machine: Add machine__is() to identify machine arch + - perf tools: Fix kernel_start for PTI on x86 + - perf machine: Add nr_cpus_avail() + - perf machine: Workaround missing maps for x86 PTI entry trampolines + - perf test code-reading: Fix perf_env setup for PTI entry trampolines + - media: v4l: event: Add subscription to list before calling "add" operation + - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver + - uio: Fix an Oops on load + - usb: cdc-acm: add entry for Hiro (Conexant) modem + - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB + - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data + - USB: misc: appledisplay: add 20" Apple Cinema Display + - ACPI / platform: Add SMB0001 HID to forbidden_id_list + - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges + - libceph: fall back to sendmsg for slab pages + - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE + - perf unwind: Take pgoff into account when reporting elf to libdwfl + - netfilter: bridge: define INT_MIN & INT_MAX in userspace + - s390/decompressor: add missing FORCE to build targets + - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS" + - HID: alps: allow incoming reports when only the trackstick is opened + - s390/mm: fix mis-accounting of pgtable_bytes + - drm/amd/display: Stop leaking planes + - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder() + - ceph: quota: fix null pointer dereference in quota check + - nvme: make sure ns head inherits underlying device limits + - i2c: omap: Enable for ARCH_K3 + - net: aquantia: fix potential IOMMU fault after driver unbind + - net: aquantia: fixed enable unicast on 32 macvlan + - net: aquantia: invalid checksumm offload implementation + - mtd: rawnand: atmel: fix OF child-node lookup + - efi/libstub: arm: support building with clang + - ARM: 8766/1: drop no-thumb-interwork in EABI mode + - ARM: 8767/1: add support for building ARM kernel with clang + - bus: arm-cci: remove unnecessary unreachable() + - ARM: trusted_foundations: do not use naked function + - usb: core: Fix hub port connection events lost + - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers + - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB + - usb: dwc3: core: Clean up ULPI device + - xhci: Add check for invalid byte size error when UAS devices are connected. + - ALSA: oss: Use kvzalloc() for local buffer allocations + - MAINTAINERS: Add Sasha as a stable branch maintainer + - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL + - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path + - iwlwifi: mvm: support sta_statistics() even on older firmware + - iwlwifi: mvm: fix regulatory domain update when the firmware starts + - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used + - brcmfmac: fix reporting support for 160 MHz channels + - tools/power/cpupower: fix compilation with STATIC=true + - v9fs_dir_readdir: fix double-free on p9stat_read error + - selinux: Add __GFP_NOWARN to allocation at str_read() + - Input: synaptics - avoid using uninitialized variable when probing + - bfs: add sanity check at bfs_fill_super() + - sctp: clear the transport of some out_chunk_list chunks in + sctp_assoc_rm_peer + - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd + - llc: do not use sk_eat_skb() + - mm: don't warn about large allocations for slab + - mm/memory.c: recheck page table entry with page table lock held + - IB/core: Perform modify QP on real one + - usb: xhci: Prevent bus suspend if a port connect change or polling state is + detected + - drm/ast: change resolution may cause screen blurred + - drm/ast: fixed cursor may disappear sometimes + - can: dev: can_get_echo_skb(): factor out non sending code to + __can_get_echo_skb() + - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to + access frame length + - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb + is accessed out of bounds + - can: dev: __can_get_echo_skb(): print error message, if trying to echo non + existing skb + - can: rx-offload: introduce can_rx_offload_get_echo_skb() and + can_rx_offload_queue_sorted() functions + - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to + can_rx_offload_queue_tail() + - can: raw: check for CAN FD capable netdev in raw_sendmsg() + - can: hi311x: Use level-triggered interrupt + - IB/hfi1: Eliminate races in the SDMA send error path + - pinctrl: meson: fix pinconf bias disable + - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE + - cpufreq: imx6q: add return value check for voltage scale + - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write + - crypto: simd - correctly take reqsize of wrapped skcipher into account + - floppy: fix race condition in __floppy_read_block_0() + - powerpc/io: Fix the IO workarounds code to work with Radix + - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs + - SUNRPC: Fix a bogus get/put in generic_key_to_expire() + - kdb: Use strscpy with destination buffer size + - powerpc/numa: Suppress "VPHN is not supported" messages + - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset + - mm, page_alloc: check for max order in hot path + - arm64: remove no-op -p linker flag + - ubi: fastmap: Check each mapping only once + - Input: xpad - add PDP device id 0x02a4 + - Input: xpad - fix some coding style issues + - Input: xpad - avoid using __set_bit() for capabilities + - Input: xpad - add support for Xbox1 PDP Camo series gamepad + - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE + - kbuild: allow to use GCC toolchain not in Clang search path + - PCI: endpoint: Populate func_no before calling pci_epc_add_epf() + - i40iw: Fix memory leak in error path of create QP + - clk: samsung: exynos5250: Add missing clocks for FIMC LITE SYSMMU devices + - ARM: dts: exynos: Fix invalid node referenced by i2c20 alias in Peach Pit + and Pi + - include/linux/pfn_t.h: force '~' to be parsed as an unary operator + - tty: wipe buffer. + - tty: wipe buffer if not echoing data + - lan78xx: Read MAC address from DT if present + - s390/mm: Check for valid vma before zapping in gmap_discard + - rcu: Make need_resched() respond to urgent RCU-QS needs + - net: ieee802154: 6lowpan: fix frag reassembly + - EVM: Add support for portable signature format + - ima: re-introduce own integrity cache lock + - ima: re-initialize iint->atomic_flags + - xhci: Fix leaking USB3 shared_hcd at xhci removal + - Documentation/security-bugs: Clarify treatment of embargoed information + - Documentation/security-bugs: Postpone fix publication in exceptional cases + - ACPICA: AML interpreter: add region addresses in global list during + initialization + - fsnotify: generalize handling of extra event flags + - pinctrl: meson: fix gxbb ao pull register bits + - pinctrl: meson: fix gxl ao pull register bits + - pinctrl: meson: fix meson8 ao pull register bits + - pinctrl: meson: fix meson8b ao pull register bits + - riscv: add missing vdso_install target + - media: ov5640: fix wrong binning value in exposure calculation + - media: ov5640: fix auto controls values when switching to manual mode + - mm/huge_memory: rename freeze_page() to unmap_page() + - mm/huge_memory.c: reorder operations in __split_huge_page_tail() + - mm/huge_memory: splitting set mapping+index before unfreeze + - mm/huge_memory: fix lockdep complaint on 32-bit i_size_read() + - mm/khugepaged: collapse_shmem() stop if punched or truncated + - mm/khugepaged: fix crashes due to misaccounted holes + - mm/khugepaged: collapse_shmem() remember to clear holes + - mm/khugepaged: minor reorderings in collapse_shmem() + - mm/khugepaged: collapse_shmem() without freezing new_page + - mm/khugepaged: collapse_shmem() do not crash on Compound + - media: em28xx: Fix use-after-free when disconnecting + - ubi: Initialize Fastmap checkmapping correctly + - libceph: store ceph_auth_handshake pointer in ceph_connection + - libceph: factor out __prepare_write_connect() + - libceph: factor out __ceph_x_decrypt() + - libceph: factor out encrypt_authorizer() + - libceph: add authorizer challenge + - libceph: implement CEPHX_V2 calculation mode + - net/tls: Fixed return value when tls_complete_pending_work() fails + - wil6210: missing length check in wmi_set_ie + - btrfs: validate type when reading a chunk + - btrfs: Verify that every chunk has corresponding block group at mount time + - btrfs: tree-checker: Add checker for dir item + - btrfs: tree-checker: use %zu format string for size_t + - btrfs: tree-check: reduce stack consumption in check_dir_item + - btrfs: tree-checker: Verify block_group_item + - btrfs: tree-checker: Detect invalid and empty essential trees + - btrfs: Check that each block group has corresponding chunk at mount time + - btrfs: tree-checker: Check level for leaves and nodes + - btrfs: tree-checker: Fix misleading group system information + - f2fs: check blkaddr more accuratly before issue a bio + - f2fs: enhance sanity_check_raw_super() to avoid potential overflow + - f2fs: clean up with is_valid_blkaddr() + - f2fs: introduce and spread verify_blkaddr + - f2fs: fix to do sanity check with secs_per_zone + - f2fs: fix to do sanity check with user_block_count + - f2fs: fix to do sanity check with node footer and iblocks + - f2fs: fix to do sanity check with block address in main area + - f2fs: fix to do sanity check with i_extra_isize + - f2fs: fix to do sanity check with cp_pack_start_sum + - net: skb_scrub_packet(): Scrub offload_fwd_mark + - net: thunderx: set xdp_prog to NULL if bpf_prog_add fails + - virtio-net: disable guest csum during XDP set + - virtio-net: fail XDP set if guest csum is negotiated + - net: thunderx: set tso_hdrs pointer to NULL in nicvf_free_snd_queue + - packet: copy user buffers before orphan or clone + - rapidio/rionet: do not free skb before reading its length + - usbnet: ipheth: fix potential recvmsg bug and recvmsg bug 2 + - kvm: mmu: Fix race in emulated page table writes + - KVM: x86: Fix kernel info-leak in KVM_HC_CLOCK_PAIRING hypercall + - xtensa: enable coprocessors that are being flushed + - xtensa: fix coprocessor context offset definitions + - xtensa: fix coprocessor part of ptrace_{get,set}xregs + - Btrfs: ensure path name is null terminated at btrfs_control_ioctl + - btrfs: relocation: set trans to be NULL after ending transaction + - PCI: layerscape: Fix wrong invocation of outbound window disable accessor + - arm64: dts: rockchip: Fix PCIe reset polarity for rk3399-puma-haikou. + - x86/fpu: Disable bottom halves while loading FPU registers + - perf/x86/intel: Move branch tracing setup to the Intel-specific source file + - perf/x86/intel: Add generic branch tracing check to intel_pmu_has_bts() + - fs: fix lost error code in dio_complete + - ALSA: wss: Fix invalid snd_free_pages() at error path + - ALSA: ac97: Fix incorrect bit shift at AC97-SPSA control write + - ALSA: control: Fix race between adding and removing a user element + - ALSA: sparc: Fix invalid snd_free_pages() at error path + - ALSA: hda/realtek - Support ALC300 + - ALSA: hda/realtek - fix headset mic detection for MSI MS-B171 + - ext2: fix potential use after free + - ARM: dts: rockchip: Remove @0 from the veyron memory node + - dmaengine: at_hdmac: fix memory leak in at_dma_xlate() + - dmaengine: at_hdmac: fix module unloading + - staging: vchiq_arm: fix compat VCHIQ_IOC_AWAIT_COMPLETION + - staging: rtl8723bs: Add missing return for cfg80211_rtw_get_station + - usb: core: quirks: add RESET_RESUME quirk for Cherry G230 Stream series + - Revert "usb: dwc3: gadget: skip Set/Clear Halt when invalid" + - iio:st_magn: Fix enable device after trigger + - lib/test_kmod.c: fix rmmod double free + - mm: use swp_offset as key in shmem_replace_page() + - misc: mic/scif: fix copy-paste error in scif_create_remote_lookup + - binder: fix race that allows malicious free of live buffer + - libceph: weaken sizeof check in ceph_x_verify_authorizer_reply() + - libceph: check authorizer reply/challenge length before reading + - f2fs: fix missing up_read + - net: don't keep lonely packets forever in the gro hash + - net: phy: add workaround for issue where PHY driver doesn't bind to the + device + - KVM: nVMX/nSVM: Fix bug which sets vcpu->arch.tsc_offset to L1 tsc_offset + - udf: Allow mounting volumes with incorrect identification strings + - btrfs: Always try all copies when reading extent buffers + - Btrfs: fix rare chances for data loss when doing a fast fsync + - Btrfs: fix race between enabling quotas and subvolume creation + - perf/x86/intel: Disallow precise_ip on BTS events + - ALSA: hda: Add ASRock H81M-HDS to the power_save blacklist + - ALSA: hda: Add ASRock N68C-S UCC the power_save blacklist + - function_graph: Create function_graph_enter() to consolidate architecture + code + - ARM: function_graph: Simplify with function_graph_enter() + - microblaze: function_graph: Simplify with function_graph_enter() + - x86/function_graph: Simplify with function_graph_enter() + - powerpc/function_graph: Simplify with function_graph_enter() + - sh/function_graph: Simplify with function_graph_enter() + - sparc/function_graph: Simplify with function_graph_enter() + - parisc: function_graph: Simplify with function_graph_enter() + - s390/function_graph: Simplify with function_graph_enter() + - arm64: function_graph: Simplify with function_graph_enter() + - MIPS: function_graph: Simplify with function_graph_enter() + - function_graph: Make ftrace_push_return_trace() static + - function_graph: Use new curr_ret_depth to manage depth instead of + curr_ret_stack + - function_graph: Have profiler use curr_ret_stack and not depth + - function_graph: Move return callback before update of curr_ret_stack + - function_graph: Reverse the order of pushing the ret_stack and the callback + - ext2: initialize opts.s_mount_opt as zero before using it + - ASoC: intel: cht_bsw_max98090_ti: Add quirk for boards using pmc_plt_clk_0 + - staging: most: use format specifier "%s" in snprintf + - iio/hid-sensors: Fix IIO_CHAN_INFO_RAW returning wrong values for signed + numbers + - mm: cleancache: fix corruption on missed inode invalidation + * Bionic update: upstream stable patchset 2019-07-17 (LP: #1836968) // + CVE-2000-1134 // CVE-2007-3852 // CVE-2008-0525 // CVE-2009-0416 // + CVE-2011-4834 // CVE-2015-1838 // CVE-2015-7442 // CVE-2016-7489 + - namei: allow restricted O_CREAT of FIFOs and regular files + * bcache: risk of data loss on I/O errors in backing or caching devices + (LP: #1829563) + - bcache: add CACHE_SET_IO_DISABLE to struct cache_set flags + - bcache: add stop_when_cache_set_failed option to backing device + - bcache: fix inaccurate io state for detached bcache devices + - bcache: add backing_request_endio() for bi_end_io + - bcache: add io_disable to struct cached_dev + - bcache: store disk name in struct cache and struct cached_dev + - bcache: count backing device I/O error for writeback I/O + - bcache: add wait_for_kthread_stop() in bch_allocator_thread() + - bcache: set dc->io_disable to true in conditional_stop_bcache_device() + - bcache: stop bcache device when backing device is offline + - bcache: fix ioctl in flash device + * Bionic update: upstream stable patchset 2019-07-16 (LP: #1836802) + - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB + - spi: bcm-qspi: switch back to reading flash using smaller chunks + - bcache: trace missed reading by cache_missed + - bcache: fix miss key refill->end in writeback + - hwmon: (pmbus) Fix page count auto-detection. + - jffs2: free jffs2_sb_info through jffs2_kill_sb() + - cpufreq: conservative: Take limits changes into account properly + - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges + - parisc: Fix address in HPMC IVA + - parisc: Fix map_pages() to not overwrite existing pte entries + - parisc: Fix exported address of os_hpmc handler + - ALSA: hda - Add quirk for ASUS G751 laptop + - ALSA: hda - Fix headphone pin config for ASUS G751 + - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905) + - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops + - x86/xen: Fix boot loader version reported for PVH guests + - x86/corruption-check: Fix panic in memory_corruption_check() when boot + option without value is provided + - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen + - bpf: do not blindly change rlimit in reuseport net selftest + - Revert "perf tools: Fix PMU term format max value calculation" + - xfrm: policy: use hlist rcu variants on insert + - perf vendor events intel: Fix wrong filter_band* values for uncore events + - sched/fair: Fix the min_vruntime update logic in dequeue_entity() + - perf tools: Fix use of alternatives to find JDIR + - perf cpu_map: Align cpu map synthesized events properly. + - x86/fpu: Remove second definition of fpu in __fpu__restore_sig() + - net: qla3xxx: Remove overflowing shift statement + - selftests: ftrace: Add synthetic event syntax testcase + - i2c: rcar: cleanup DMA for all kinds of failure + - locking/lockdep: Fix debug_locks off performance problem + - ataflop: fix error handling during setup + - swim: fix cleanup on setup error + - nfp: devlink port split support for 1x100G CXP NIC + - tun: Consistently configure generic netdev params via rtnetlink + - s390/sthyi: Fix machine name validity indication + - hwmon: (pwm-fan) Set fan speed to 0 on suspend + - lightnvm: pblk: fix two sleep-in-atomic-context bugs + - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare} + - perf tools: Free temporary 'sys' string in read_event_files() + - perf tools: Cleanup trace-event-info 'tdata' leak + - perf strbuf: Match va_{add,copy} with va_end + - cpupower: Fix coredump on VMWare + - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01 + - iwlwifi: pcie: avoid empty free RB queue + - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface + - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC + - ACPI / processor: Fix the return value of acpi_processor_ids_walk() + - cpufreq: dt: Try freeing static OPPs only if we have added them + - mtd: rawnand: atmel: Fix potential NULL pointer dereference + - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack + - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth + - x86: boot: Fix EFI stub alignment + - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux + - brcmfmac: fix for proper support of 160MHz bandwidth + - net: phy: phylink: ensure the carrier is off when starting phylink + - block, bfq: correctly charge and reset entity service in all cases + - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON() + - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers + - pinctrl: qcom: spmi-mpp: Fix drive strength setting + - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant + - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant + - net: dsa: mv88e6xxx: Fix writing to a PHY page. + - iwlwifi: mvm: fix BAR seq ctrl reporting + - ixgbevf: VF2VF TCP RSS + - ath10k: schedule hardware restart if WMI command times out + - thermal: da9062/61: Prevent hardware access during system suspend + - cgroup, netclassid: add a preemption point to write_classid + - scsi: esp_scsi: Track residual for PIO transfers + - UAPI: ndctl: Fix g++-unsupported initialisation in headers + - KVM: nVMX: Clear reserved bits of #DB exit qualification + - scsi: megaraid_sas: fix a missing-check bug + - RDMA/core: Do not expose unsupported counters + - IB/ipoib: Clear IPCB before icmp_send + - RDMA/bnxt_re: Fix recursive lock warning in debug kernel + - usb: host: ohci-at91: fix request of irq for optional gpio + - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic + - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated + - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask + - VMCI: Resource wildcard match fixed + - PCI / ACPI: Enable wake automatically for power managed bridges + - usb: gadget: udc: atmel: handle at91sam9rl PMC + - ext4: fix argument checking in EXT4_IOC_MOVE_EXT + - MD: fix invalid stored role for a disk + - f2fs: fix to recover inode's i_flags during POR + - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice + - coresight: etb10: Fix handling of perf mode + - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode + - crypto: caam - fix implicit casts in endianness helpers + - usb: chipidea: Prevent unbalanced IRQ disable + - driver/dma/ioat: Call del_timer_sync() without holding prep_lock + - uio: ensure class is registered before devices + - scsi: lpfc: Correct soft lockup when running mds diagnostics + - scsi: lpfc: Correct race with abort on completion path + - f2fs: report error if quota off error during umount + - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace + init + - mfd: menelaus: Fix possible race condition and leak + - dmaengine: dma-jz4780: Return error if not probed from DT + - IB/rxe: fix for duplicate request processing and ack psns + - ALSA: hda: Check the non-cached stream buffers more explicitly + - cpupower: Fix AMD Family 0x17 msr_pstate size + - f2fs: fix to account IO correctly + - ARM: dts: exynos: Remove "cooling-{min|max}-level" for CPU nodes + - arm: dts: exynos: Add missing cooling device properties for CPUs + - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings + - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250 + - xen-swiotlb: use actually allocated size on check physical continuous + - tpm: Restore functionality to xen vtpm driver. + - xen/blkfront: avoid NULL blkfront_info dereference on device removal + - xen/balloon: Support xend-based toolstack + - xen: fix race in xen_qlock_wait() + - xen: make xen_qlock_wait() nestable + - xen/pvh: increase early stack size + - xen/pvh: don't try to unplug emulated devices + - libertas: don't set URB_ZERO_PACKET on IN USB transfer + - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten + - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround" + - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate() + - net/ipv4: defensive cipso option parsing + - dmaengine: ppc4xx: fix off-by-one build failure + - dmaengine: stm32-dma: fix incomplete configuration in cyclic mode + - libnvdimm: Hold reference on parent while scheduling async init + - libnvdimm, region: Fail badblocks listing for inactive regions + - ASoC: intel: skylake: Add missing break in skl_tplg_get_token() + - IB/mlx5: Fix MR cache initialization + - jbd2: fix use after free in jbd2_log_do_checkpoint() + - gfs2_meta: ->mount() can get NULL dev_name + - ext4: initialize retries variable in ext4_da_write_inline_data_begin() + - ext4: fix setattr project check in fssetxattr ioctl + - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR + - ext4: fix use-after-free race in ext4_remount()'s error path + - EDAC, amd64: Add Family 17h, models 10h-2fh support + - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting + - EDAC, skx_edac: Fix logical channel intermediate decoding + - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP + - PCI/ASPM: Fix link_state teardown on device removal + - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk + - PCI: vmd: White list for fast interrupt handlers + - signal/GenWQE: Fix sending of SIGKILL + - signal: Guard against negative signal numbers in copy_siginfo_from_user32 + - crypto: lrw - Fix out-of bounds access on counter overflow + - crypto: tcrypt - fix ghash-generic speed test + - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range() + - ima: fix showing large 'violations' or 'runtime_measurements_count' + - hugetlbfs: dirty pages as they are added to pagecache + - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly + - KVM: arm64: Fix caching of host MDCR_EL2 value + - kbuild: fix kernel/bounds.c 'W=1' warning + - iio: ad5064: Fix regulator handling + - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs() + - iio: adc: at91: fix acking DRDY irq on simple conversions + - iio: adc: at91: fix wrong channel number in triggered buffer mode + - w1: omap-hdq: fix missing bus unregister at removal + - smb3: allow stats which track session and share reconnects to be reset + - smb3: do not attempt cifs operation in smb3 query info error path + - smb3: on kerberos mount if server doesn't specify auth type use krb5 + - printk: Fix panic caused by passing log_buf_len to command line + - genirq: Fix race on spurious interrupt detection + - NFSv4.1: Fix the r/wsize checking + - nfs: Fix a missed page unlock after pg_doio() + - nfsd: Fix an Oops in free_session() + - lockd: fix access beyond unterminated strings in prints + - dm ioctl: harden copy_params()'s copy_from_user() from malicious users + - dm zoned: fix metadata block ref counting + - dm zoned: fix various dmz_get_mblock() issues + - powerpc/msi: Fix compile error on mpc83xx + - MIPS: OCTEON: fix out of bounds array access on CN68XX + - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI + - TC: Set DMA masks for devices + - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD + - kgdboc: Passing ekgdboc to command line causes panic + - xen: fix xen_qlock_wait() + - xen-blkfront: fix kernel panic with negotiate_mq error path + - media: em28xx: use a default format if TRY_FMT fails + - media: tvp5150: avoid going past array on v4l2_querymenu() + - media: em28xx: fix input name for Terratec AV 350 + - media: em28xx: make v4l2-compliance happier by starting sequence on zero + - media: media colorspaces*.rst: rename AdobeRGB to opRGB + - arm64: lse: remove -fcall-used-x0 flag + - rpmsg: smd: fix memory leak on channel create + - Cramfs: fix abad comparison when wrap-arounds occur + - ARM: dts: socfpga: Fix SDRAM node address for Arria10 + - arm64: dts: stratix10: Correct System Manager register size + - soc/tegra: pmc: Fix child-node lookup + - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled + - btrfs: Handle owner mismatch gracefully when walking up tree + - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock + - btrfs: fix error handling in free_log_tree + - btrfs: Enhance btrfs_trim_fs function to handle error better + - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem + - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list + - btrfs: don't attempt to trim devices that don't support it + - btrfs: wait on caching when putting the bg cache + - btrfs: protect space cache inode alloc with GFP_NOFS + - btrfs: reset max_extent_size on clear in a bitmap + - btrfs: make sure we create all new block groups + - Btrfs: fix warning when replaying log after fsync of a tmpfile + - Btrfs: fix wrong dentries after fsync of file that got its parent replaced + - btrfs: qgroup: Dirty all qgroups before rescan + - Btrfs: fix null pointer dereference on compressed write path error + - Btrfs: fix assertion on fsync of regular file when using no-holes feature + - btrfs: set max_extent_size properly + - btrfs: don't use ctl->free_space for max_extent_size + - btrfs: only free reserved extent if we didn't insert it + - btrfs: don't run delayed_iputs in commit + - btrfs: move the dio_sem higher up the callchain + - Btrfs: fix use-after-free during inode eviction + - Btrfs: fix use-after-free when dumping free space + - Btrfs: fix fsync after hole punching when using no-holes feature + - net: sched: Remove TCA_OPTIONS from policy + - bpf: wait for running BPF programs when updating map-in-map + - MD: fix invalid stored role for a disk - try2 + - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash + - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus + - bcache: correct dirty data statistics + - block: don't deal with discard limit in blkdev_issue_discard() + - block: make sure discard bio is aligned with logical block size + - block: make sure writesame bio is aligned with logical block size + - dma-mapping: fix panic caused by passing empty cma command line argument + - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer() + - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended + opcodes + - kprobes/x86: Use preempt_enable() in optimized_callback() + - mailbox: PCC: handle parse error + - ALSA: hda: Add 2 more models to the power_save blacklist + - drm: fix use of freed memory in drm_mode_setcrtc + - nvme: remove ns sibling before clearing path + - nfp: flower: fix pedit set actions for multiple partial masks + - nfp: flower: use offsets provided by pedit instead of index for ipv6 + - perf report: Don't crash on invalid inline debug information + - drm: Get ref on CRTC commit object when waiting for flip_done + - net: socionext: Reset tx queue in ndo_stop + - lightnvm: pblk: fix race on sysfs line state + - lightnvm: pblk: fix race condition on metadata I/O + - bcache: Populate writeback_rate_minimum attribute + - sdhci: acpi: add free_slot callback + - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset + - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI + - ACPI/PPTT: Handle architecturally unknown cache types + - ACPI / PM: LPIT: Register sysfs attributes based on FADT + - pinctrl: sunxi: fix 'pctrl->functions' allocation in + sunxi_pinctrl_build_state + - arm64: entry: Allow handling of undefined instructions from EL1 + - bpf/verifier: fix verifier instability + - gpio: brcmstb: allow 0 width GPIO banks + - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9 + - thermal: rcar_thermal: Prevent doing work after unbind + - net: stmmac: dwmac-sun8i: fix OF child-node lookup + - f2fs: clear PageError on the read path + - xprtrdma: Reset credit grant properly after a disconnect + - nvmem: check the return value of nvmem_add_cells() + - f2fs: avoid sleeping under spin_lock + - f2fs: fix to recover cold bit of inode block during POR + - OPP: Free OPP table properly on performance state irregularities + - IB/rxe: Revise the ib_wr_opcode enum + - ext4: fix EXT4_IOC_SWAP_BOOT + - selinux: fix mounting of cgroup2 under older policies + - KVM: arm/arm64: Ensure only THP is candidate for adjustment + - NFC: nfcmrvl_uart: fix OF child-node lookup + - media: ov7670: make "xclk" clock optional + - powerpc/tm: Fix HFSCR bit for no suspend case + - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9 + - MIPS: memset: Fix CPU_DADDI_WORKAROUNDS `small_fixup' regression + - power: supply: twl4030-charger: fix OF sibling-node lookup + - ocxl: Fix access to the AFU Descriptor Data + - net: bcmgenet: fix OF child-node lookup + - media: cec: make cec_get_edid_spa_location() an inline function + - media: cec: integrate cec_validate_phys_addr() in cec-api.c + - media: adv7604: when the EDID is cleared, unconfigure CEC as well + - media: adv7842: when the EDID is cleared, unconfigure CEC as well + - drm/mediatek: fix OF sibling-node lookup + - media: replace ADOBERGB by OPRGB + - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC + - btrfs: fix error handling in btrfs_dev_replace_start + - btrfs: keep trim from interfering with transaction commits + - Btrfs: don't clean dirty pages during buffered writes + - btrfs: release metadata before running delayed refs + - Btrfs: fix deadlock when writing out free space caches + - btrfs: reset max_extent_size properly + - btrfs: fix insert_reserved error handling + - powerpc/traps: restore recoverability of machine_check interrupts + - powerpc/64/module: REL32 relocation range check + - powerpc/mm: Fix page table dump to work on Radix + - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log() + - tty: check name length in tty_find_polling_driver() + - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL + - powerpc/nohash: fix undefined behaviour when testing page size support + - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak + - drm/omap: fix memory barrier bug in DMM driver + - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer + - media: pci: cx23885: handle adding to list failure + - media: coda: don't overwrite h.264 profile_idc on decoder instance + - MIPS: kexec: Mark CPU offline before disabling local IRQ + - powerpc/boot: Ensure _zimage_start is a weak symbol + - powerpc/memtrace: Remove memory in chunks + - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS + - sc16is7xx: Fix for multi-channel stall + - media: tvp5150: fix width alignment during set_selection() + - powerpc/selftests: Wait all threads to join + - staging:iio:ad7606: fix voltage scales + - 9p locks: fix glock.client_id leak in do_lock + - 9p: clear dangling pointers in p9stat_free + - ovl: fix error handling in ovl_verify_set_fh() + - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters + - scsi: qla2xxx: Fix process response queue for ISP26XX and above + - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx + - scsi: qla2xxx: shutdown chip if reset fail + - scsi: qla2xxx: Fix re-using LoopID when handle is in use + - ovl: fix recursive oi->lock in ovl_link() + - MIPS: Loongson-3: Fix CPU UART irq delivery problem + - MIPS: Loongson-3: Fix BRIDGE irq delivery problem + - xtensa: add NOTES section to the linker script + - xtensa: make sure bFLT stack is 16 byte aligned + - xtensa: fix boot parameters address translation + - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP + - clk: s2mps11: Fix matching when built as module and DT node contains + compatible + - clk: at91: Fix division by zero in PLL recalc_rate() + - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call + - clk: mvebu: use correct bit for 98DX3236 NAND + - libceph: bump CEPH_MSG_MAX_DATA_LEN + - mach64: fix display corruption on big endian machines + - mach64: fix image corruption due to reading accelerator registers + - reset: hisilicon: fix potential NULL pointer dereference + - vhost/scsi: truncate T10 PI iov_iter to prot_bytes + - scsi: qla2xxx: Initialize port speed to avoid setting lower speed + - SCSI: fix queue cleanup race before queue initialization is done + - soc: ti: QMSS: Fix usage of irq_set_affinity_hint + - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry + - ocfs2: free up write context when direct IO failed + - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings + - netfilter: conntrack: fix calculation of next bucket number in early_drop + - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm + - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option + - of, numa: Validate some distance map rules + - x86/cpu/vmware: Do not trace vmware_sched_clock() + - x86/hyper-v: Enable PIT shutdown quirk + - termios, tty/tty_baudrate.c: fix buffer overrun + - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2 + - watchdog/core: Add missing prototypes for weak functions + - btrfs: fix pinned underflow after transaction aborted + - Btrfs: fix cur_offset in the error case for nocow + - Btrfs: fix infinite loop on inode eviction after deduplication of eof block + - Btrfs: fix data corruption due to cloning of eof block + - clockevents/drivers/i8253: Add support for PIT shutdown quirk + - ext4: add missing brelse() update_backups()'s error path + - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path + - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path + - ext4: avoid potential extra brelse in setup_new_flex_group_blocks() + - ext4: missing !bh check in ext4_xattr_inode_write() + - ext4: fix possible inode leak in the retry loop of ext4_resize_fs() + - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty() + - ext4: avoid buffer leak in ext4_orphan_add() after prior errors + - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing + - ext4: avoid possible double brelse() in add_new_gdb() on error path + - ext4: fix possible leak of sbi->s_group_desc_leak in error path + - ext4: fix possible leak of s_journal_flag_rwsem in error path + - ext4: fix buffer leak in ext4_xattr_get_block() on error path + - ext4: release bs.bh before re-using in ext4_xattr_block_find() + - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path + - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path + - ext4: fix buffer leak in __ext4_read_dirblock() on error path + - mount: Prevent MNT_DETACH from disconnecting locked mounts + - kdb: use correct pointer when 'btc' calls 'btt' + - kdb: print real address of pointers instead of hashed addresses + - sunrpc: correct the computation for page_ptr when truncating + - rtc: hctosys: Add missing range error reporting + - configfs: replace strncpy with memcpy + - gfs2: Put bitmap buffers in put_super + - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn + - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444! + - mm/swapfile.c: use kvzalloc for swap_info_struct allocation + - efi/arm/libstub: Pack FDT after populating it + - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type + - drm/nouveau: Check backlight IDs are >= 0, not > 0 + - drm/dp_mst: Check if primary mstb is null + - drm/i915: Restore vblank interrupts earlier + - drm/i915: Don't unset intel_connector->mst_port + - drm/i915: Skip vcpi allocation for MSTB ports that are gone + - drm/i915: Large page offsets for pread/pwrite + - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values + - drm/i915: Don't oops during modeset shutdown after lpe audio deinit + - drm/i915: Mark pin flags as u64 + - drm/i915/execlists: Force write serialisation into context image vs + execution + - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM + - ovl: check whiteout in ovl_create_over_whiteout() + - nvme-loop: fix kernel oops in case of unhandled command + - Input: wm97xx-ts - fix exit path + - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS + - tracing/kprobes: Check the probe on unloaded module correctly + - drm/amdgpu/powerplay: fix missing break in switch statements + - udf: Prevent write-unsupported filesystem to be remounted read-write + - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout + - zram: close udev startup race condition as default groups + - clk: rockchip: fix wrong mmc sample phase shift for rk3328 + - bonding/802.3ad: fix link_failure_count tracking + - hwmon: (core) Fix double-free in __hwmon_device_register() + - perf stat: Handle different PMU names with common prefix + - mnt: fix __detach_mounts infinite loop + - NFSv4: Don't exit the state manager without clearing + NFS4CLNT_MANAGER_RUNNING + - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD + - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit + panel's native mode + - drm/i915: Fix ilk+ watermarks when disabling pipes + - drm/i915: Fix possible race in intel_dp_add_mst_connector() + * [SRU][B/B-OEM]Fix resume failure on some TPM chips (LP: #1836031) + - tpm: tpm_try_transmit() refactor error flow. + * Linux md raid-10 freezes during resync (LP: #1767992) + - md: fix raid10 hang issue caused by barrier + * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755) + - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine + * CVE-2019-12614 + - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property() + * x86: mm: early boot problem on i386 with KPTI enabled (LP: #1827884) + - Revert "perf/core: Make sure the ring-buffer is mapped in all page-tables" + - x86/mm: Clarify hardware vs. software "error_code" + - x86/mm: Break out kernel address space handling + - x86/mm: Break out user address space handling + - x86/mm/fault: Allow stack access below %rsp + * bnx2x driver causes 100% CPU load (LP: #1832082) + - bnx2x: Prevent ptp_task to be rescheduled indefinitely + * Sometimes touchpad detected as mouse(i2c designware fails to get adapter + number) (LP: #1835150) + - i2c: i2c-designware-platdrv: Cleanup setting of the adapter number + - i2c: i2c-designware-platdrv: Always use a dynamic adapter number + * HP EliteBook 745 G5 (Ryzen 2500U) fails to boot unless `mce=off` is set on + command line (LP: #1796443) + - x86/MCE/AMD: Turn off MC4_MISC thresholding on all family 0x15 models + - x86/MCE/AMD: Carve out the MC4_MISC thresholding quirk + - x86/MCE: Add an MCE-record filtering function + - x86/MCE/AMD: Don't report L1 BTB MCA errors on some family 17h models + * Bionic update: upstream stable patchset 2019-07-15 (LP: #1836654) + - media: af9035: prevent buffer overflow on write + - batman-adv: Avoid probe ELP information leak + - batman-adv: Fix segfault when writing to throughput_override + - batman-adv: Fix segfault when writing to sysfs elp_interval + - batman-adv: Prevent duplicated gateway_node entry + - batman-adv: Prevent duplicated nc_node entry + - batman-adv: Prevent duplicated softif_vlan entry + - batman-adv: Prevent duplicated global TT entry + - batman-adv: Prevent duplicated tvlv handler + - batman-adv: fix backbone_gw refcount on queue_work() failure + - batman-adv: fix hardif_neigh refcount on queue_work() failure + - clocksource/drivers/ti-32k: Add CLOCK_SOURCE_SUSPEND_NONSTOP flag for non- + am43 SoCs + - scsi: ibmvscsis: Fix a stringop-overflow warning + - scsi: ibmvscsis: Ensure partition name is properly NUL terminated + - intel_th: pci: Add Ice Lake PCH support + - Input: atakbd - fix Atari keymap + - Input: atakbd - fix Atari CapsLock behaviour + - net: emac: fix fixed-link setup for the RTL8363SB switch + - ravb: do not write 1 to reserved bits + - PCI: dwc: Fix scheduling while atomic issues + - drm: mali-dp: Call drm_crtc_vblank_reset on device init + - scsi: ipr: System hung while dlpar adding primary ipr adapter back + - scsi: sd: don't crash the host on invalid commands + - net/mlx4: Use cpumask_available for eq->affinity_mask + - clocksource/drivers/fttmr010: Fix set_next_event handler + - powerpc/tm: Fix userspace r13 corruption + - powerpc/tm: Avoid possible userspace r1 corruption on reclaim + - iommu/amd: Return devid as alias for ACPI HID devices + - ARC: build: Get rid of toolchain check + - ARC: build: Don't set CROSS_COMPILE in arch's Makefile + - HID: quirks: fix support for Apple Magic Keyboards + - staging: ccree: check DMA pool buf !NULL before free + - net/smc: fix sizeof to int comparison + - qed: Fix populating the invalid stag value in multi function mode. + - RDMA/uverbs: Fix validity check for modify QP + - bpf: test_maps, only support ESTABLISHED socks + - RDMA/bnxt_re: Fix system crash during RDMA resource initialization + - RISC-V: include linux/ftrace.h in asm-prototypes.h + - powerpc/numa: Use associativity if VPHN hcall is successful + - x86/boot: Fix kexec booting failure in the SEV bit detection code + - xfrm: Validate address prefix lengths in the xfrm selector. + - xfrm6: call kfree_skb when skb is toobig + - xfrm: reset transport header back to network header after all input + transforms ahave been applied + - xfrm: reset crypto_done when iterating over multiple input xfrms + - mac80211: Always report TX status + - cfg80211: reg: Init wiphy_idx in regulatory_hint_core() + - mac80211: fix pending queue hang due to TX_DROP + - cfg80211: Address some corner cases in scan result channel updating + - mac80211: TDLS: fix skb queue/priority assignment + - mac80211: fix TX status reporting for ieee80211s + - ARM: 8799/1: mm: fix pci_ioremap_io() offset check + - xfrm: validate template mode + - netfilter: bridge: Don't sabotage nf_hook calls from an l3mdev + - arm64: hugetlb: Fix handling of young ptes + - ARM: dts: BCM63xx: Fix incorrect interrupt specifiers + - net: macb: Clean 64b dma addresses if they are not detected + - soc: fsl: qbman: qman: avoid allocating from non existing gen_pool + - soc: fsl: qe: Fix copy/paste bug in ucc_get_tdm_sync_shift() + - mac80211_hwsim: do not omit multicast announce of first added radio + - Bluetooth: SMP: fix crash in unpairing + - pxa168fb: prepare the clock + - qed: Avoid implicit enum conversion in qed_set_tunn_cls_info + - qed: Fix mask parameter in qed_vf_prep_tunn_req_tlv + - qed: Avoid implicit enum conversion in qed_roce_mode_to_flavor + - qed: Avoid constant logical operation warning in qed_vf_pf_acquire + - qed: Avoid implicit enum conversion in qed_iwarp_parse_rx_pkt + - asix: Check for supported Wake-on-LAN modes + - ax88179_178a: Check for supported Wake-on-LAN modes + - lan78xx: Check for supported Wake-on-LAN modes + - sr9800: Check for supported Wake-on-LAN modes + - r8152: Check for supported Wake-on-LAN Modes + - smsc75xx: Check for Wake-on-LAN modes + - smsc95xx: Check for Wake-on-LAN modes + - cfg80211: fix use-after-free in reg_process_hint() + - perf/core: Fix perf_pmu_unregister() locking + - perf/ring_buffer: Prevent concurent ring buffer access + - perf/x86/intel/uncore: Fix PCI BDF address of M3UPI on SKX + - perf/x86/amd/uncore: Set ThreadMask and SliceMask for L3 Cache perf events + - net: fec: fix rare tx timeout + - declance: Fix continuation with the adapter identification message + - locking/ww_mutex: Fix runtime warning in the WW mutex selftest + - be2net: don't flip hw_features when VXLANs are added/deleted + - net: cxgb3_main: fix a missing-check bug + - yam: fix a missing-check bug + - ocfs2: fix crash in ocfs2_duplicate_clusters_by_page() + - iwlwifi: mvm: check for short GI only for OFDM + - iwlwifi: dbg: allow wrt collection before ALIVE + - iwlwifi: fix the ALIVE notification layout + - usbip: vhci_hcd: update 'status' file header and format + - net/mlx5: Fix mlx5_get_vector_affinity function + - powerpc/pseries: Add empty update_numa_cpu_lookup_table() for NUMA=n + - dm integrity: fail early if required HMAC key is not available + - net: phy: realtek: Use the dummy stubs for MMD register access for rtl8211b + - net: phy: Add general dummy stubs for MMD register access + - scsi: qla2xxx: Avoid double completion of abort command + - kbuild: set no-integrated-as before incl. arch Makefile + - IB/mlx5: Avoid passing an invalid QP type to firmware + - l2tp: remove configurable payload offset + - cifs: Use ULL suffix for 64-bit constant + - KVM: x86: Update the exit_qualification access bits while walking an address + - sparc64: Fix regression in pmdp_invalidate(). + - tpm: move the delay_msec increment after sleep in tpm_transmit() + - bpf: sockmap, map_release does not hold refcnt for pinned maps + - tpm: tpm_crb: relinquish locality on error path. + - IB/usnic: Update with bug fixes from core code + - mmc: dw_mmc-rockchip: correct property names in debug + - MIPS: Workaround GCC __builtin_unreachable reordering bug + - iio: buffer: fix the function signature to match implementation + - selftests/powerpc: Add ptrace hw breakpoint test + - scsi: ibmvfc: Avoid unnecessary port relogin + - scsi: sd: Remember that READ CAPACITY(16) succeeded + - btrfs: quota: Set rescan progress to (u64)-1 if we hit last leaf + - net: phy: phylink: Don't release NULL GPIO + - x86/paravirt: Fix some warning messages + - net: stmmac: mark PM functions as __maybe_unused + - kconfig: fix the rule of mainmenu_stmt symbol + - libertas: call into generic suspend code before turning off power + - compiler.h: Allow arch-specific asm/compiler.h + - ARM: dts: imx53-qsb: disable 1.2GHz OPP + - perf python: Use -Wno-redundant-decls to build with PYTHON=python3 + - rxrpc: Don't check RXRPC_CALL_TX_LAST after calling rxrpc_rotate_tx_window() + - rxrpc: Only take the rwind and mtu values from latest ACK + - rxrpc: Fix connection-level abort handling + - selftests: rtnetlink.sh explicitly requires bash. + - fs/fat/fatent.c: add cond_resched() to fat_count_free_clusters() + - mtd: spi-nor: Add support for is25wp series chips + - ARM: dts: r8a7790: Correct critical CPU temperature + - media: uvcvideo: Fix driver reference counting + - Revert "netfilter: ipv6: nf_defrag: drop skb dst before queueing" + - perf tools: Disable parallelism for 'make clean' + - drm/i915/gvt: fix memory leak of a cmd_entry struct on error exit path + - bridge: do not add port to router list when receives query with source + 0.0.0.0 + - net: bridge: remove ipv6 zero address check in mcast queries + - ipv6: mcast: fix a use-after-free in inet6_mc_check + - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are + called + - llc: set SOCK_RCU_FREE in llc_sap_add_socket() + - net: fec: don't dump RX FIFO register when not available + - net/ipv6: Fix index counter for unicast addresses in in6_dump_addrs + - net: sched: gred: pass the right attribute to gred_change_table_def() + - net: socket: fix a missing-check bug + - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules + - net: udp: fix handling of CHECKSUM_COMPLETE packets + - r8169: fix NAPI handling under high load + - sctp: fix race on sctp_id2asoc + - udp6: fix encap return code for resubmitting + - virtio_net: avoid using netif_tx_disable() for serializing tx routine + - ethtool: fix a privilege escalation bug + - bonding: fix length of actor system + - ip6_tunnel: Fix encapsulation layout + - openvswitch: Fix push/pop ethernet validation + - net/mlx5: Take only bit 24-26 of wqe.pftype_wq for page fault type + - net: sched: Fix for duplicate class dump + - net: drop skb on failure in ip_check_defrag() + - net: fix pskb_trim_rcsum_slow() with odd trim offset + - net/mlx5e: fix csum adjustments caused by RXFCS + - rtnetlink: Disallow FDB configuration for non-Ethernet device + - net: ipmr: fix unresolved entry dumps + - net: bcmgenet: Poll internal PHY for GENETv5 + - net/sched: cls_api: add missing validation of netlink attributes + - net/mlx5: Fix build break when CONFIG_SMP=n + - mac80211_hwsim: fix locking when iterating radios during ns exit + - rxrpc: Fix checks as to whether we should set up a new call + - rxrpc: Fix transport sockopts to get IPv4 errors on an IPv6 socket + - thunderbolt: Do not handle ICM events after domain is stopped + - thunderbolt: Initialize after IOMMUs + - RISCV: Fix end PFN for low memory + - drm/amd/display: Signal hw_done() after waiting for flip_done() + - powerpc/numa: Skip onlining a offline node in kdump path + - mm/gup_benchmark: fix unsigned comparison to zero in __gup_benchmark_ioctl + - perf report: Don't try to map ip to invalid map + - perf record: Use unmapped IP for inline callchain cursors + - rxrpc: Carry call state out of locked section in rxrpc_rotate_tx_window() + - gpio: Assign gpio_irq_chip::parents to non-stack pointer + - IB/mlx5: Unmap DMA addr from HCA before IOMMU + - rds: RDS (tcp) hangs on sendto() to unresponding address + - sparc64: Export __node_distance. + - sparc64: Make corrupted user stacks more debuggable. + - sparc64: Make proc_id signed. + - sparc64: Set %l4 properly on trap return after handling signals. + - sparc: Fix single-pcr perf event counter management. + - sparc: Fix syscall fallback bugs in VDSO. + - sparc: Throttle perf events properly. + - eeprom: at24: Add support for address-width property + - vfs: swap names of {do,vfs}_clone_file_range() + - bpf: fix partial copy of map_ptr when dst is scalar + - gpio: mxs: Get rid of external API call + - xfs: truncate transaction does not modify the inobt + - cachefiles: fix the race between cachefiles_bury_object() and rmdir(2) + - drm/edid: VSDB yCBCr420 Deep Color mode bit definitions + - drm: fb-helper: Reject all pixel format changing requests + - cdc-acm: do not reset notification buffer index upon urb unlinking + - cdc-acm: correct counting of UART states in serial state notification + - cdc-acm: fix race between reset and control messaging + - usb: usbip: Fix BUG: KASAN: slab-out-of-bounds in vhci_hub_control() + - USB: fix the usbfs flag sanitization for control transfers + - Input: elan_i2c - add ACPI ID for Lenovo IdeaPad 330-15IGM + - sched/fair: Fix throttle_list starvation with low CFS quota + - x86/tsc: Force inlining of cyc2ns bits + - x86, hibernate: Fix nosave_regions setup for hibernation + - x86/percpu: Fix this_cpu_read() + - x86/time: Correct the attribute on jiffies' definition + - x86/fpu: Fix i486 + no387 boot crash by only saving FPU registers on context + switch if there is an FPU + - clk: sunxi-ng: sun4i: Set VCO and PLL bias current to lowest setting + - drm/sun4i: Fix an ulong overflow in the dotclock driver + - x86/swiotlb: Enable swiotlb for > 4GiG RAM on 32-bit kernels + * Colour banding in HP Pavilion 15-n233sl integrated display (LP: #1794387) // + Bionic update: upstream stable patchset 2019-07-15 (LP: #1836654) + - drm/edid: Add 6 bpc quirk for BOE panel in HP Pavilion 15-n233sl + * Bionic update: upstream stable patchset 2019-07-12 (LP: #1836426) + - drm/amd/pp: initialize result to before or'ing in data + - drm/amdgpu: add another ATPX quirk for TOPAZ + - tools/power turbostat: fix possible sprintf buffer overflow + - mac80211: Run TXQ teardown code before de-registering interfaces + - mac80211_hwsim: require at least one channel + - btrfs: btrfs_shrink_device should call commit transaction at the end + - scsi: csiostor: add a check for NULL pointer after kmalloc() + - mac80211: correct use of IEEE80211_VHT_CAP_RXSTBC_X + - mac80211_hwsim: correct use of IEEE80211_VHT_CAP_RXSTBC_X + - gpio: adp5588: Fix sleep-in-atomic-context bug + - mac80211: mesh: fix HWMP sequence numbering to follow standard + - mac80211: avoid kernel panic when building AMSDU from non-linear SKB + - gpiolib: acpi: Switch to cansleep version of GPIO library call + - gpiolib-acpi: Register GpioInt ACPI event handlers from a late_initcall + - cfg80211: nl80211_update_ft_ies() to validate NL80211_ATTR_IE + - mac80211: do not convert to A-MSDU if frag/subframe limited + - mac80211: always account for A-MSDU header changes + - tools/kvm_stat: fix handling of invalid paths in debugfs provider + - gpio: Fix crash due to registration race + - ARC: atomics: unbork atomic_fetch_##op() + - md/raid5-cache: disable reshape completely + - RAID10 BUG_ON in raise_barrier when force is true and conf->barrier is 0 + - i2c: uniphier: issue STOP only for last message or I2C_M_STOP + - i2c: uniphier-f: issue STOP only for last message or I2C_M_STOP + - net: cadence: Fix a sleep-in-atomic-context bug in macb_halt_tx() + - fs/cifs: don't translate SFM_SLASH (U+F026) to backslash + - mac80211: fix an off-by-one issue in A-MSDU max_subframe computation + - cfg80211: fix a type issue in ieee80211_chandef_to_operating_class() + - mac80211: fix a race between restart and CSA flows + - mac80211: Fix station bandwidth setting after channel switch + - mac80211: don't Tx a deauth frame if the AP forbade Tx + - mac80211: shorten the IBSS debug messages + - tools/vm/slabinfo.c: fix sign-compare warning + - tools/vm/page-types.c: fix "defined but not used" warning + - mm: madvise(MADV_DODUMP): allow hugetlbfs pages + - netfilter: xt_cluster: add dependency on conntrack module + - HID: add support for Apple Magic Keyboards + - usb: gadget: fotg210-udc: Fix memory leak of fotg210->ep[i] + - HID: hid-saitek: Add device ID for RAT 7 Contagion + - scsi: qedi: Add the CRC size within iSCSI NVM image + - perf evsel: Fix potential null pointer dereference in perf_evsel__new_idx() + - perf util: Fix bad memory access in trace info. + - perf probe powerpc: Ignore SyS symbols irrespective of endianness + - netfilter: nf_tables: release chain in flushing set + - Revert "iio: temperature: maxim_thermocouple: add MAX31856 part" + - RDMA/ucma: check fd type in ucma_migrate_id() + - HID: sensor-hub: Restore fixup for Lenovo ThinkPad Helix 2 sensor hub report + - USB: yurex: Check for truncation in yurex_read() + - nvmet-rdma: fix possible bogus dereference under heavy load + - net/mlx5: Consider PCI domain in search for next dev + - drm/nouveau/TBDdevinit: don't fail when PMU/PRE_OS is missing from VBIOS + - drm/nouveau/disp: fix DP disable race + - dm raid: fix rebuild of specific devices by updating superblock + - fs/cifs: suppress a string overflow warning + - perf/x86/intel: Add support/quirk for the MISPREDICT bit on Knights Landing + CPUs + - dm thin metadata: try to avoid ever aborting transactions + - arch/hexagon: fix kernel/dma.c build warning + - hexagon: modify ffs() and fls() to return int + - arm64: jump_label.h: use asm_volatile_goto macro instead of "asm goto" + - drm/amdgpu: fix error handling in amdgpu_cs_user_fence_chunk + - r8169: Clear RTL_FLAG_TASK_*_PENDING when clearing RTL_FLAG_TASK_ENABLED + - s390/qeth: don't dump past end of unknown HW header + - cifs: read overflow in is_valid_oplock_break() + - xen/manage: don't complain about an empty value in control/sysrq node + - xen: avoid crash in disable_hotplug_cpu + - xen: fix GCC warning and remove duplicate EVTCHN_ROW/EVTCHN_COL usage + - ovl: fix access beyond unterminated strings + - ovl: fix memory leak on unlink of indexed file + - ovl: fix format of setxattr debug + - sysfs: Do not return POSIX ACL xattrs via listxattr + - smb2: fix missing files in root share directory listing + - iommu/amd: Clear memory encryption mask from physical address + - crypto: qat - Fix KASAN stack-out-of-bounds bug in adf_probe() + - crypto: mxs-dcp - Fix wait logic on chan threads + - crypto: caam/jr - fix ablkcipher_edesc pointer arithmetic + - gpiolib: Free the last requested descriptor + - Drivers: hv: vmbus: Use get/put_cpu() in vmbus_connect() + - tools: hv: fcopy: set 'error' in case an unknown operation was requested + - ocfs2: fix locking for res->tracking and dlm->tracking_list + - ixgbe: check return value of napi_complete_done() + - dm thin metadata: fix __udivdi3 undefined on 32-bit + - Btrfs: fix unexpected failure of nocow buffered writes after snapshotting + when low on space + - scsi: aacraid: fix a signedness bug + - tipc: switch to rhashtable iterator + - net: mvpp2: initialize port of_node pointer + - tc-testing: add test-cases for numeric and invalid control action + - tools/kvm_stat: fix updates for dead guests + - ibmvnic: Include missing return code checks in reset function + - net/ibm/emac: wrong emac_calc_base call was used by typo + - ceph: avoid a use-after-free in ceph_destroy_options() + - afs: Fix cell specification to permit an empty address list + - netfilter: xt_checksum: ignore gso skbs + - HID: intel-ish-hid: Enable Sunrise Point-H ish driver + - iio: imu: st_lsm6dsx: take into account ts samples in wm configuration + - riscv: Do not overwrite initrd_start and initrd_end + - drm/nouveau: fix oops in client init failure path + - drm/nouveau/mmu: don't attempt to dereference vmm without valid instance + pointer + - drm/nouveau/disp/gm200-: enforce identity-mapped SOR assignment for LVDS/eDP + panels + - sched/topology: Set correct NUMA topology type + - drm/amdgpu: Fix SDMA hang in prt mode v2 + - asm-generic: io: Fix ioport_map() for !CONFIG_GENERIC_IOMAP && + CONFIG_INDIRECT_PIO + - x86/APM: Fix build warning when PROC_FS is not enabled + - new primitive: discard_new_inode() + - ovl: set I_CREATING on inode being created + - crypto: chelsio - Fix memory corruption in DMA Mapped buffers. + - perf/core: Add sanity check to deal with pinned event failure + - mm: migration: fix migration of huge PMD shared pages + - mm, thp: fix mlocking THP page with migration enabled + - mm/vmstat.c: skip NR_TLB_REMOTE_FLUSH* properly + - KVM: x86: fix L1TF's MMIO GFN calculation + - blk-mq: I/O and timer unplugs are inverted in blktrace + - clocksource/drivers/timer-atmel-pit: Properly handle error cases + - fbdev/omapfb: fix omapfb_memory_read infoleak + - drm/amdgpu: Fix vce work queue was not cancelled when suspend + - x86/vdso: Fix asm constraints on vDSO syscall fallbacks + - selftests/x86: Add clock_gettime() tests to test_vdso + - x86/vdso: Only enable vDSO retpolines when enabled and supported + - x86/vdso: Fix vDSO syscall fallback asm constraint regression + - mac80211: fix setting IEEE80211_KEY_FLAG_RX_MGMT for AP mode keys + - PM / core: Clear the direct_complete flag on errors + - dm cache metadata: ignore hints array being too small during resize + - dm cache: fix resize crash if user doesn't reload cache table + - xhci: Add missing CAS workaround for Intel Sunrise Point xHCI + - usb: xhci-mtk: resume USB3 roothub first + - USB: serial: simple: add Motorola Tetra MTP6550 id + - usb: cdc_acm: Do not leak URB buffers + - of: unittest: Disable interrupt node tests for old world MAC systems + - perf annotate: Use asprintf when formatting objdump command line + - perf tools: Fix python extension build for gcc 8 + - ath10k: fix use-after-free in ath10k_wmi_cmd_send_nowait + - ath10k: fix kernel panic issue during pci probe + - nvme_fc: fix ctrl create failures racing with workq items + - powerpc/lib: fix book3s/32 boot failure due to code patching + - ARC: clone syscall to setp r25 as thread pointer + - perf utils: Move is_directory() to path.h + - f2fs: fix invalid memory access + - ucma: fix a use-after-free in ucma_resolve_ip() + - ubifs: Check for name being NULL while mounting + - rds: rds_ib_recv_alloc_cache() should call alloc_percpu_gfp() instead + - ath10k: fix scan crash due to incorrect length calculation + - pstore/ram: Fix failure-path memory leak in ramoops_init + - mac80211: allocate TXQs for active monitor interfaces + - drm: fix use-after-free read in drm_mode_create_lease_ioctl() + - USB: serial: option: improve Quectel EP06 detection + - USB: serial: option: add two-endpoints device-id flag + - tipc: call start and done ops directly in __tipc_nl_compat_dumpit() + - bnxt_en: Fix TX timeout during netpoll. + - bnxt_en: free hwrm resources, if driver probe fails. + - bonding: avoid possible dead-lock + - ip6_tunnel: be careful when accessing the inner header + - ip_tunnel: be careful when accessing the inner header + - ipv4: fix use-after-free in ip_cmsg_recv_dstaddr() + - ipv6: take rcu lock in rawv6_send_hdrinc() + - net: dsa: bcm_sf2: Call setup during switch resume + - net: hns: fix for unmapping problem when SMMU is on + - net: ipv4: update fnhe_pmtu when first hop's MTU changes + - net/ipv6: Display all addresses in output of /proc/net/if_inet6 + - netlabel: check for IPV4MASK in addrinfo_get + - net: mvpp2: Extract the correct ethtype from the skb for tx csum offload + - net: mvpp2: fix a txq_done race condition + - net: sched: Add policy validation for tc attributes + - net: systemport: Fix wake-up interrupt race during resume + - net/usb: cancel pending work when unbinding smsc75xx + - qmi_wwan: Added support for Gemalto's Cinterion ALASxx WWAN interface + - rtnl: limit IFLA_NUM_TX_QUEUES and IFLA_NUM_RX_QUEUES to 4096 + - sctp: update dst pmtu with the correct daddr + - team: Forbid enslaving team device to itself + - tipc: fix flow control accounting for implicit connect + - udp: Unbreak modules that rely on external __skb_recv_udp() availability + - net: stmmac: Fixup the tail addr setting in xmit path + - net/packet: fix packet drop as of virtio gso + - net: dsa: bcm_sf2: Fix unbind ordering + - net/mlx5e: Set vlan masks for all offloaded TC rules + - net: aquantia: memory corruption on jumbo frames + - net/mlx5: E-Switch, Fix out of bound access when setting vport rate + - bonding: pass link-local packets to bonding master also. + - bonding: fix warning message + - nfp: avoid soft lockups under control message storm + - bnxt_en: don't try to offload VLAN 'modify' action + - net-ethtool: ETHTOOL_GUFO did not and should not require CAP_NET_ADMIN + - tcp/dccp: fix lockdep issue when SYN is backlogged + - inet: make sure to grab rcu_read_lock before using ireq->ireq_opt + - ASoC: rt5514: Fix the issue of the delay volume applied again + - ASoC: wm8804: Add ACPI support + - ASoC: sigmadsp: safeload should not have lower byte limit + - selftests/efivarfs: add required kernel configs + - selftests: memory-hotplug: add required configs + - ASoC: rsnd: adg: care clock-frequency size + - ASoC: rsnd: don't fallback to PIO mode when -EPROBE_DEFER + - Bluetooth: hci_ldisc: Free rw_semaphore on close + - mfd: omap-usb-host: Fix dts probe of children + - scsi: iscsi: target: Don't use stack buffer for scatterlist + - scsi: qla2xxx: Fix an endian bug in fcpcmd_is_corrupted() + - sound: enable interrupt after dma buffer initialization + - sound: don't call skl_init_chip() to reset intel skl soc + - stmmac: fix valid numbers of unicast filter entries + - net: macb: disable scatter-gather for macb on sama5d3 + - ARM: dts: at91: add new compatibility string for macb on sama5d3 + - PCI: hv: support reporting serial number as slot information + - clk: x86: add "ether_clk" alias for Bay Trail / Cherry Trail + - clk: x86: Stop marking clocks as CLK_IS_CRITICAL + - x86/kvm/lapic: always disable MMIO interface in x2APIC mode + - drm/amdgpu: Fix SDMA HQD destroy error on gfx_v7 + - mm/vmstat.c: fix outdated vmstat_text + - MIPS: VDSO: Always map near top of user memory + - mach64: detect the dot clock divider correctly on sparc + - percpu: stop leaking bitmap metadata blocks + - perf script python: Fix export-to-postgresql.py occasional failure + - perf script python: Fix export-to-sqlite.py sample columns + - s390/cio: Fix how vfio-ccw checks pinned pages + - dm cache: destroy migration_cache if cache target registration failed + - dm: fix report zone remapping to account for partition offset + - dm linear: eliminate linear_end_io call if CONFIG_DM_ZONED disabled + - dm linear: fix linear_end_io conditional definition + - cgroup: Fix dom_cgrp propagation when enabling threaded mode + - mmc: block: avoid multiblock reads for the last sector in SPI mode + - pinctrl: mcp23s08: fix irq and irqchip setup order + - arm64: perf: Reject stand-alone CHAIN events for PMUv3 + - mm/thp: fix call to mmu_notifier in set_pmd_migration_entry() v2 + - mm: Preserve _PAGE_DEVMAP across mprotect() calls + - i2c: i2c-scmi: fix for i2c_smbus_write_block_data + - xhci: Don't print a warning when setting link state for disabled ports + - mm: introduce NR_INDIRECTLY_RECLAIMABLE_BYTES + - mm: treat indirectly reclaimable memory as available in MemAvailable + - dcache: account external names as indirectly reclaimable memory + - mm: treat indirectly reclaimable memory as free in overcommit logic + - mm: don't show nr_indirectly_reclaimable in /proc/vmstat + - ARM: add more CPU part numbers for Cortex and Brahma B15 CPUs + - ARM: bugs: prepare processor bug infrastructure + - ARM: bugs: hook processor bug checking into SMP and suspend paths + - ARM: bugs: add support for per-processor bug checking + - [Config] updateconfigs for CPU_SPECTRE + - ARM: spectre: add Kconfig symbol for CPUs vulnerable to Spectre + - ARM: spectre-v2: harden branch predictor on context switches + - ARM: spectre-v2: add Cortex A8 and A15 validation of the IBE bit + - ARM: spectre-v2: harden user aborts in kernel space + - ARM: spectre-v2: add firmware based hardening + - ARM: spectre-v2: warn about incorrect context switching functions + - ARM: KVM: invalidate BTB on guest exit for Cortex-A12/A17 + - ARM: KVM: invalidate icache on guest exit for Cortex-A15 + - ARM: spectre-v2: KVM: invalidate icache on guest exit for Brahma B15 + - ARM: KVM: Add SMCCC_ARCH_WORKAROUND_1 fast handling + - ARM: KVM: report support for SMCCC_ARCH_WORKAROUND_1 + - ARM: spectre-v1: add speculation barrier (csdb) macros + - ARM: spectre-v1: add array_index_mask_nospec() implementation + - ARM: spectre-v1: fix syscall entry + - ARM: signal: copy registers using __copy_from_user() + - ARM: vfp: use __copy_from_user() when restoring VFP state + - ARM: oabi-compat: copy semops using __copy_from_user() + - ARM: use __inttype() in get_user() + - ARM: spectre-v1: use get_user() for __get_user() + - ARM: spectre-v1: mitigate user accesses + - perf tools: Fix snprint warnings for gcc 8 + - net: sched: cls_u32: fix hnode refcounting + - net: qualcomm: rmnet: Skip processing loopback packets + - net: qualcomm: rmnet: Fix incorrect allocation flag in transmit + - tun: remove unused parameters + - tun: initialize napi_mutex unconditionally + - tun: napi flags belong to tfile + - net: dsa: b53: Keep CPU port as tagged in all VLANs + - rtnetlink: Fail dump if target netnsid is invalid + - net: ipv4: don't let PMTU updates increase route MTU + - ASoC: dapm: Fix NULL pointer deference on CODEC to CODEC DAIs + - selftests: android: move config up a level + - selftests: add headers_install to lib.mk + - Bluetooth: SMP: Fix trying to use non-existent local OOB data + - Bluetooth: Use correct tfm to generate OOB data + - net: ethernet: ti: add missing GENERIC_ALLOCATOR dependency + - afs: Fix afs_server struct leak + - afs: Fix clearance of reply + * Volume control not working Dell XPS 27 (7760) (LP: #1775068) // Bionic + update: upstream stable patchset 2019-07-12 (LP: #1836426) + - ALSA: hda/realtek - Cannot adjust speaker's volume on Dell XPS 27 7760 + * Bionic update: upstream stable patchset 2019-07-11 (LP: #1836287) + - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so + - gso_segment: Reset skb->mac_len after modifying network header + - ipv6: fix possible use-after-free in ip6_xmit() + - net/appletalk: fix minor pointer leak to userspace in SIOCFINDIPDDPRT + - net: hp100: fix always-true check for link up state + - pppoe: fix reception of frames with no mac header + - qmi_wwan: set DTR for modems in forced USB2 mode + - udp4: fix IP_CMSG_CHECKSUM for connected sockets + - neighbour: confirm neigh entries when ARP packet is received + - udp6: add missing checks on edumux packet processing + - net/sched: act_sample: fix NULL dereference in the data path + - tls: don't copy the key out of tls12_crypto_info_aes_gcm_128 + - tls: zero the crypto information from tls_context before freeing + - tls: clear key material from kernel memory when do_tls_setsockopt_conf fails + - NFC: Fix possible memory corruption when handling SHDLC I-Frame commands + - NFC: Fix the number of pipes + - ASoC: cs4265: fix MMTLR Data switch control + - ASoC: rsnd: fixup not to call clk_get/set under non-atomic + - ALSA: bebob: fix memory leak for M-Audio FW1814 and ProjectMix I/O at error + path + - ALSA: bebob: use address returned by kmalloc() instead of kernel stack for + streaming DMA mapping + - ALSA: emu10k1: fix possible info leak to userspace on + SNDRV_EMU10K1_IOCTL_INFO + - ALSA: fireface: fix memory leak in ff400_switch_fetching_mode() + - ALSA: firewire-digi00x: fix memory leak of private data + - ALSA: firewire-tascam: fix memory leak of private data + - ALSA: fireworks: fix memory leak of response buffer at error path + - ALSA: oxfw: fix memory leak for model-dependent data at error path + - ALSA: oxfw: fix memory leak of discovered stream formats at error path + - ALSA: oxfw: fix memory leak of private data + - platform/x86: alienware-wmi: Correct a memory leak + - xen/netfront: don't bug in case of too many frags + - xen/x86/vpmu: Zero struct pt_regs before calling into sample handling code + - spi: fix IDR collision on systems with both fixed and dynamic SPI bus + numbers + - ring-buffer: Allow for rescheduling when removing pages + - mm: shmem.c: Correctly annotate new inodes for lockdep + - scsi: target: iscsi: Use bin2hex instead of a re-implementation + - ocfs2: fix ocfs2 read block panic + - drm/nouveau: Fix deadlocks in nouveau_connector_detect() + - drm/nouveau/drm/nouveau: Don't forget to cancel hpd_work on suspend/unload + - drm/nouveau/drm/nouveau: Fix bogus drm_kms_helper_poll_enable() placement + - drm/nouveau/drm/nouveau: Use pm_runtime_get_noresume() in connector_detect() + - drm/nouveau/drm/nouveau: Prevent handling ACPI HPD events too early + - drm/vc4: Fix the "no scaling" case on multi-planar YUV formats + - drm: udl: Destroy framebuffer only if it was initialized + - drm/amdgpu: add new polaris pci id + - ext4: check to make sure the rename(2)'s destination is not freed + - ext4: avoid divide by zero fault when deleting corrupted inline directories + - ext4: avoid arithemetic overflow that can trigger a BUG + - ext4: recalucate superblock checksum after updating free blocks/inodes + - ext4: fix online resize's handling of a too-small final block group + - ext4: fix online resizing for bigalloc file systems with a 1k block size + - ext4: don't mark mmp buffer head dirty + - ext4: show test_dummy_encryption mount option in /proc/mounts + - sched/fair: Fix vruntime_normalized() for remote non-migration wakeup + - PCI: aardvark: Size bridges before resources allocation + - vmw_balloon: include asm/io.h + - iw_cxgb4: only allow 1 flush on user qps + - tick/nohz: Prevent bogus softirq pending warning + - spi: Fix double IDR allocation with DT aliases + - hv_netvsc: fix schedule in RCU context + - bnxt_en: Fix VF mac address regression. + - net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags + - mtd: rawnand: denali: fix a race condition when DMA is kicked + - platform/x86: dell-smbios-wmi: Correct a memory leak + - fork: report pid exhaustion correctly + - mm: disable deferred struct page for 32-bit arches + - libata: mask swap internal and hardware tag + - drm/i915/bdw: Increase IPS disable timeout to 100ms + - drm/nouveau: Reset MST branching unit before enabling + - drm/nouveau: Only write DP_MSTM_CTRL when needed + - drm/nouveau: Remove duplicate poll_enable() in pmops_runtime_suspend() + - ext4, dax: set ext4_dax_aops for dax files + - crypto: skcipher - Fix -Wstringop-truncation warnings + - iio: adc: ina2xx: avoid kthread_stop() with stale task_struct + - tsl2550: fix lux1_input error in low light + - vmci: type promotion bug in qp_host_get_user_memory() + - x86/numa_emulation: Fix emulated-to-physical node mapping + - staging: rts5208: fix missing error check on call to rtsx_write_register + - power: supply: axp288_charger: Fix initial constant_charge_current value + - misc: sram: enable clock before registering regions + - serial: sh-sci: Stop RX FIFO timer during port shutdown + - uwb: hwa-rc: fix memory leak at probe + - power: vexpress: fix corruption in notifier registration + - iommu/amd: make sure TLB to be flushed before IOVA freed + - Bluetooth: Add a new Realtek 8723DE ID 0bda:b009 + - USB: serial: kobil_sct: fix modem-status error handling + - 6lowpan: iphc: reset mac_header after decompress to fix panic + - iommu/msm: Don't call iommu_device_{,un}link from atomic context + - s390/mm: correct allocate_pgste proc_handler callback + - power: remove possible deadlock when unregistering power_supply + - md-cluster: clear another node's suspend_area after the copy is finished + - RDMA/bnxt_re: Fix a couple off by one bugs + - RDMA/i40w: Hold read semaphore while looking after VMA + - IB/core: type promotion bug in rdma_rw_init_one_mr() + - media: exynos4-is: Prevent NULL pointer dereference in __isp_video_try_fmt() + - IB/mlx4: Test port number before querying type. + - powerpc/kdump: Handle crashkernel memory reservation failure + - media: fsl-viu: fix error handling in viu_of_probe() + - media: staging/imx: fill vb2_v4l2_buffer field entry + - x86/tsc: Add missing header to tsc_msr.c + - ARM: hwmod: RTC: Don't assume lock/unlock will be called with irq enabled + - x86/entry/64: Add two more instruction suffixes + - ARM: dts: ls1021a: Add missing cooling device properties for CPUs + - scsi: target/iscsi: Make iscsit_ta_authentication() respect the output + buffer size + - scsi: klist: Make it safe to use klists in atomic context + - scsi: ibmvscsi: Improve strings handling + - scsi: target: Avoid that EXTENDED COPY commands trigger lock inversion + - usb: wusbcore: security: cast sizeof to int for comparison + - ath10k: sdio: use same endpoint id for all packets in a bundle + - ath10k: sdio: set skb len for all rx packets + - powerpc/powernv/ioda2: Reduce upper limit for DMA window size + - s390/sysinfo: add missing #ifdef CONFIG_PROC_FS + - alarmtimer: Prevent overflow for relative nanosleep + - s390/dasd: correct numa_node in dasd_alloc_queue + - s390/scm_blk: correct numa_node in scm_blk_dev_setup + - s390/extmem: fix gcc 8 stringop-overflow warning + - mtd: rawnand: atmel: add module param to avoid using dma + - iio: accel: adxl345: convert address field usage in iio_chan_spec + - posix-timers: Make forward callback return s64 + - ALSA: snd-aoa: add of_node_put() in error path + - media: s3c-camif: ignore -ENOIOCTLCMD from v4l2_subdev_call for s_power + - media: soc_camera: ov772x: correct setting of banding filter + - media: omap3isp: zero-initialize the isp cam_xclk{a,b} initial data + - staging: android: ashmem: Fix mmap size validation + - drivers/tty: add error handling for pcmcia_loop_config + - media: tm6000: add error handling for dvb_register_adapter + - net: phy: xgmiitorgmii: Check read_status results + - ath10k: protect ath10k_htt_rx_ring_free with rx_ring.lock + - net: phy: xgmiitorgmii: Check phy_driver ready before accessing + - drm/sun4i: Fix releasing node when enumerating enpoints + - ath10k: transmit queued frames after processing rx packets + - rndis_wlan: potential buffer overflow in rndis_wlan_auth_indication() + - brcmsmac: fix wrap around in conversion from constant to s16 + - ARM: mvebu: declare asm symbols as character arrays in pmsu.c + - arm: dts: mediatek: Add missing cooling device properties for CPUs + - HID: hid-ntrig: add error handling for sysfs_create_group + - MIPS: boot: fix build rule of vmlinux.its.S + - perf/x86/intel/lbr: Fix incomplete LBR call stack + - scsi: bnx2i: add error handling for ioremap_nocache + - iomap: complete partial direct I/O writes synchronously + - scsi: megaraid_sas: Update controller info during resume + - EDAC, i7core: Fix memleaks and use-after-free on probe and remove + - ASoC: dapm: Fix potential DAI widget pointer deref when linking DAIs + - module: exclude SHN_UNDEF symbols from kallsyms api + - gpio: Fix wrong rounding in gpio-menz127 + - nfsd: fix corrupted reply to badly ordered compound + - EDAC: Fix memleak in module init error path + - fs/lock: skip lock owner pid translation in case we are in init_pid_ns + - Input: xen-kbdfront - fix multi-touch XenStore node's locations + - iio: 104-quad-8: Fix off-by-one error in register selection + - ARM: dts: dra7: fix DCAN node addresses + - x86/mm: Expand static page table for fixmap space + - tty: serial: lpuart: avoid leaking struct tty_struct + - serial: cpm_uart: return immediately from console poll + - intel_th: Fix device removal logic + - spi: tegra20-slink: explicitly enable/disable clock + - spi: sh-msiof: Fix invalid SPI use during system suspend + - spi: sh-msiof: Fix handling of write value for SISTR register + - spi: rspi: Fix invalid SPI use during system suspend + - spi: rspi: Fix interrupted DMA transfers + - regulator: fix crash caused by null driver data + - USB: fix error handling in usb_driver_claim_interface() + - USB: handle NULL config in usb_find_alt_setting() + - usb: musb: dsps: do not disable CPPI41 irq in driver teardown + - slub: make ->cpu_partial unsigned int + - USB: usbdevfs: sanitize flags more + - USB: usbdevfs: restore warning for nonsensical flags + - USB: remove LPM management from usb_driver_claim_interface() + - IB/srp: Avoid that sg_reset -d ${srp_device} triggers an infinite loop + - IB/hfi1: Fix SL array bounds check + - IB/hfi1: Invalid user input can result in crash + - IB/hfi1: Fix context recovery when PBC has an UnsupportedVL + - RDMA/uverbs: Atomically flush and mark closed the comp event queue + - ovl: hash non-dir by lower inode for fsnotify + - drm/i915: Remove vma from object on destroy, not close + - serial: imx: restore handshaking irq for imx1 + - qed: Wait for ready indication before rereading the shmem + - qed: Wait for MCP halt and resume commands to take place + - qed: Prevent a possible deadlock during driver load and unload + - qed: Avoid sending mailbox commands when MFW is not responsive + - thermal: of-thermal: disable passive polling when thermal zone is disabled + - isofs: reject hardware sector size > 2048 bytes + - tls: possible hang when do_tcp_sendpages hits sndbuf is full case + - bpf: sockmap: write_space events need to be passed to TCP handler + - net: hns: fix length and page_offset overflow when CONFIG_ARM64_64K_PAGES + - e1000: check on netif_running() before calling e1000_up() + - e1000: ensure to free old tx/rx rings in set_ringparam() + - crypto: cavium/nitrox - fix for command corruption in queue full case with + backlog submissions. + - hwmon: (ina2xx) fix sysfs shunt resistor read access + - hwmon: (adt7475) Make adt7475_read_word() return errors + - Revert "ARM: dts: imx7d: Invert legacy PCI irq mapping" + - drm/amdgpu: Enable/disable gfx PG feature in rlc safe mode + - drm/amdgpu: Update power state at the end of smu hw_init. + - ata: ftide010: Add a quirk for SQ201 + - nvme-fcloop: Fix dropped LS's to removed target port + - ARM: dts: omap4-droid4: Fix emmc errors seen on some devices + - arm/arm64: smccc-1.1: Make return values unsigned long + - arm/arm64: smccc-1.1: Handle function result as parameters + - i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus + - x86/pti: Fix section mismatch warning/error + - media: v4l: event: Prevent freeing event subscriptions while accessed + - drm/amd/display/dc/dce: Fix multiple potential integer overflows + - drm/amd/display: fix use of uninitialized memory + - RDMA/bnxt_re: Fix a bunch of off by one bugs in qplib_fp.c + - vhost_net: Avoid tx vring kicks during busyloop + - thermal: i.MX: Allow thermal probe to fail gracefully in case of bad + calibration. + - platform/x86: asus-wireless: Fix uninitialized symbol usage + - ACPI / button: increment wakeup count only when notified + - media: ov772x: add checks for register read errors + - media: ov772x: allow i2c controllers without I2C_FUNC_PROTOCOL_MANGLING + - drm/omap: gem: Fix mm_list locking + - ASoC: rsnd: SSI parent cares SWSP bit + - staging: pi433: fix race condition in pi433_ioctl + - perf tests: Fix indexing when invoking subtests + - gpio: tegra: Fix tegra_gpio_irq_set_type() + - block: fix deadline elevator drain for zoned block devices + - serial: mvebu-uart: Fix reporting of effective CSIZE to userspace + - intel_th: Fix resource handling for ACPI glue layer + - ext2, dax: set ext2_dax_aops for dax files + - IB/hfi1: Fix destroy_qp hang after a link down + - ARM: OMAP2+: Fix null hwmod for ti-sysc debug + - ARM: OMAP2+: Fix module address for modules using mpu_rt_idx + - bus: ti-sysc: Fix module register ioremap for larger offsets + - drm/amdgpu: fix preamble handling + - amdgpu: fix multi-process hang issue + - tcp_bbr: add bbr_check_probe_rtt_done() helper + - tcp_bbr: in restart from idle, see if we should exit PROBE_RTT + - net: hns3: fix page_offset overflow when CONFIG_ARM64_64K_PAGES + - ixgbe: fix driver behaviour after issuing VFLR + - powerpc/pseries: Fix unitialized timer reset on migration + * Kernel 4.15.0-50 or newer wont boot as Xen-DomU with PVH (LP: #1829378) + - SAUCE: ACPI / bus: Fix NULL pointer dereference in + acpi_quirk_matches_bios_ids() + * CVE-2019-10126 + - mwifiex: Fix heap overflow in mwifiex_uap_parse_tail_ies() + * CVE-2019-3846 + - mwifiex: Fix possible buffer overflows at parsing bss descriptor + * CVE-2019-12818 + - net: nfc: Fix NULL dereference on nfc_llcp_build_tlv fails + * CVE-2019-12984 + - nfc: Ensure presence of required attributes in the deactivate_target handler + * Bionic update: upstream stable patchset 2019-07-10 (LP: #1836117) + - i2c: xiic: Make the start and the byte count write atomic + - i2c: i801: fix DNV's SMBCTRL register offset + - scsi: lpfc: Correct MDS diag and nvmet configuration + - nbd: don't allow invalid blocksize settings + - block: bfq: swap puts in bfqg_and_blkg_put + - android: binder: fix the race mmap and alloc_new_buf_locked + - MIPS: VDSO: Match data page cache colouring when D$ aliases + - SMB3: Backup intent flag missing for directory opens with backupuid mounts + - smb3: check for and properly advertise directory lease support + - Btrfs: fix data corruption when deduplicating between different files + - KVM: s390: vsie: copy wrapping keys to right place + - KVM: VMX: Do not allow reexecute_instruction() when skipping MMIO instr + - ALSA: hda - Fix cancel_work_sync() stall from jackpoll work + - cpu/hotplug: Adjust misplaced smb() in cpuhp_thread_fun() + - cpu/hotplug: Prevent state corruption on error rollback + - x86/microcode: Make sure boot_cpu_data.microcode is up-to-date + - x86/microcode: Update the new microcode revision unconditionally + - crypto: aes-generic - fix aes-generic regression on powerpc + - tpm: separate cmd_ready/go_idle from runtime_pm + - ARC: [plat-axs*]: Enable SWAP + - misc: mic: SCIF Fix scif_get_new_port() error handling + - ethtool: Remove trailing semicolon for static inline + - i2c: aspeed: Add an explicit type casting for *get_clk_reg_val + - Bluetooth: h5: Fix missing dependency on BT_HCIUART_SERDEV + - gpio: tegra: Move driver registration to subsys_init level + - selftests/bpf: fix a typo in map in map test + - media: davinci: vpif_display: Mix memory leak on probe error path + - media: dw2102: Fix memleak on sequence of probes + - net: phy: Fix the register offsets in Broadcom iProc mdio mux driver + - blk-mq: fix updating tags depth + - scsi: target: fix __transport_register_session locking + - md/raid5: fix data corruption of replacements after originals dropped + - timers: Clear timer_base::must_forward_clk with timer_base::lock held + - media: camss: csid: Configure data type and decode format properly + - gpu: ipu-v3: default to id 0 on missing OF alias + - misc: ti-st: Fix memory leak in the error path of probe() + - uio: potential double frees if __uio_register_device() fails + - firmware: vpd: Fix section enabled flag on vpd_section_destroy + - Drivers: hv: vmbus: Cleanup synic memory free path + - tty: rocket: Fix possible buffer overwrite on register_PCI + - f2fs: fix to active page in lru list for read path + - f2fs: do not set free of current section + - f2fs: fix defined but not used build warnings + - perf tools: Allow overriding MAX_NR_CPUS at compile time + - NFSv4.0 fix client reference leak in callback + - perf c2c report: Fix crash for empty browser + - perf evlist: Fix error out while applying initial delay and LBR + - macintosh/via-pmu: Add missing mmio accessors + - ath9k: report tx status on EOSP + - ath9k_hw: fix channel maximum power level test + - ath10k: prevent active scans on potential unusable channels + - wlcore: Set rx_status boottime_ns field on rx + - MIPS: Fix ISA virt/bus conversion for non-zero PHYS_OFFSET + - scsi: 3ware: fix return 0 on the error path of probe + - tools/testing/nvdimm: kaddr and pfn can be NULL to ->direct_access() + - ath10k: disable bundle mgmt tx completion event support + - Bluetooth: hidp: Fix handling of strncpy for hid->name information + - pinctrl: imx: off by one in imx_pinconf_group_dbg_show() + - gpio: ml-ioh: Fix buffer underwrite on probe error path + - pinctrl/amd: only handle irq if it is pending and unmasked + - net: mvneta: fix mtu change on port without link + - f2fs: try grabbing node page lock aggressively in sync scenario + - f2fs: fix to skip GC if type in SSA and SIT is inconsistent + - tpm_tis_spi: Pass the SPI IRQ down to the driver + - tpm/tpm_i2c_infineon: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - f2fs: fix to do sanity check with reserved blkaddr of inline inode + - MIPS: Octeon: add missing of_node_put() + - MIPS: generic: fix missing of_node_put() + - net: dcb: For wild-card lookups, use priority -1, not 0 + - dm cache: only allow a single io_mode cache feature to be requested + - Input: atmel_mxt_ts - only use first T9 instance + - media: s5p-mfc: Fix buffer look up in s5p_mfc_handle_frame_{new, copy_time} + functions + - media: helene: fix xtal frequency setting at power on + - f2fs: fix to wait on page writeback before updating page + - f2fs: Fix uninitialized return in f2fs_ioc_shutdown() + - iommu/ipmmu-vmsa: Fix allocation in atomic context + - mfd: ti_am335x_tscadc: Fix struct clk memory leak + - f2fs: fix to do sanity check with {sit,nat}_ver_bitmap_bytesize + - NFSv4.1: Fix a potential layoutget/layoutrecall deadlock + - MIPS: WARN_ON invalid DMA cache maintenance, not BUG_ON + - RDMA/cma: Do not ignore net namespace for unbound cm_id + - inet: frags: change inet_frags_init_net() return value + - inet: frags: add a pointer to struct netns_frags + - inet: frags: refactor ipfrag_init() + - inet: frags: refactor ipv6_frag_init() + - inet: frags: refactor lowpan_net_frag_init() + - ipv6: export ip6 fragments sysctl to unprivileged users + - rhashtable: add schedule points + - inet: frags: use rhashtables for reassembly units + - inet: frags: remove some helpers + - inet: frags: get rif of inet_frag_evicting() + - inet: frags: remove inet_frag_maybe_warn_overflow() + - inet: frags: break the 2GB limit for frags storage + - inet: frags: do not clone skb in ip_expire() + - ipv6: frags: rewrite ip6_expire_frag_queue() + - rhashtable: reorganize struct rhashtable layout + - inet: frags: reorganize struct netns_frags + - inet: frags: get rid of ipfrag_skb_cb/FRAG_CB + - inet: frags: fix ip6frag_low_thresh boundary + - ip: discard IPv4 datagrams with overlapping segments. + - net: modify skb_rbtree_purge to return the truesize of all purged skbs. + - ipv6: defrag: drop non-last frags smaller than min mtu + - net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends + - mtd: ubi: wl: Fix error return code in ubi_wl_init() + - tun: fix use after free for ptr_ring + - tuntap: fix use after free during release + - autofs: fix autofs_sbi() does not check super block type + - KVM: PPC: Book3S HV: Use correct pagesize in kvm_unmap_radix() + - ARC: [plat-axs*/plat-hsdk]: Allow U-Boot to pass MAC-address to the kernel + - x86/apic/vector: Make error return value negative + - tc-testing: flush gact actions on test teardown + - pinctrl: berlin: fix 'pctrl->functions' allocation in + berlin_pinctrl_build_state + - powerpc/4xx: Fix error return path in ppc4xx_msi_probe() + - scsi: qla2xxx: Fix unintended Logout + - iwlwifi: pcie: don't access periphery registers when not available + - f2fs: Keep alloc_valid_block_count in sync + - f2fs: issue discard align to section in LFS mode + - device-dax: avoid hang on error before devm_memremap_pages() + - regulator: tps65217: Fix NULL pointer dereference on probe + - gpio: pxa: disable pinctrl calls for PXA3xx + - thermal_hwmon: Sanitize attribute name passed to hwmon + - f2fs: fix to do sanity check with extra_attr feature + - RDMA/hns: Add illegal hop_num judgement + - RDMA/hns: Update the data type of immediate data + - be2net: Fix memory leak in be_cmd_get_profile_config() + - net/mlx5: Fix use-after-free in self-healing flow + - net: qca_spi: Fix race condition in spi transfers + - rds: fix two RCU related problems + - net/mlx5: Check for error in mlx5_attach_interface + - net/mlx5: Fix debugfs cleanup in the device init/remove flow + - net/mlx5: E-Switch, Fix memory leak when creating switchdev mode FDB tables + - net/tls: Set count of SG entries if sk_alloc_sg returns -ENOSPC + - erspan: fix error handling for erspan tunnel + - erspan: return PACKET_REJECT when the appropriate tunnel is not found + - tcp: really ignore MSG_ZEROCOPY if no SO_ZEROCOPY + - usb: dwc3: change stream event enable bit back to 13 + - iommu/io-pgtable-arm-v7s: Abort allocation when table address overflows the + PTE + - ALSA: msnd: Fix the default sample sizes + - ALSA: usb-audio: Fix multiple definitions in AU0828_DEVICE() macro + - xfrm: fix 'passing zero to ERR_PTR()' warning + - amd-xgbe: use dma_mapping_error to check map errors + - gfs2: Special-case rindex for gfs2_grow + - clk: imx6ul: fix missing of_node_put() + - clk: core: Potentially free connection id + - clk: clk-fixed-factor: Clear OF_POPULATED flag in case of failure + - kbuild: add .DELETE_ON_ERROR special target + - media: tw686x: Fix oops on buffer alloc failure + - dmaengine: pl330: fix irq race with terminate_all + - MIPS: ath79: fix system restart + - media: videobuf2-core: check for q->error in vb2_core_qbuf() + - IB/rxe: Drop QP0 silently + - block: allow max_discard_segments to be stacked + - IB/ipoib: Fix error return code in ipoib_dev_init() + - mtd/maps: fix solutionengine.c printk format warnings + - media: ov5645: Supported external clock is 24MHz + - perf test: Fix subtest number when showing results + - gfs2: Don't reject a supposedly full bitmap if we have blocks reserved + - perf tools: Synthesize GROUP_DESC feature in pipe mode + - fbdev: omapfb: off by one in omapfb_register_client() + - perf tools: Fix struct comm_str removal crash + - video: goldfishfb: fix memory leak on driver remove + - fbdev/via: fix defined but not used warning + - perf powerpc: Fix callchain ip filtering when return address is in a + register + - video: fbdev: pxafb: clear allocated memory for video modes + - fbdev: Distinguish between interlaced and progressive modes + - ARM: exynos: Clear global variable on init error path + - perf powerpc: Fix callchain ip filtering + - nvme-rdma: unquiesce queues when deleting the controller + - powerpc/powernv: opal_put_chars partial write fix + - staging: bcm2835-camera: fix timeout handling in wait_for_completion_timeout + - staging: bcm2835-camera: handle wait_for_completion_timeout return properly + - ASoC: rt5514: Fix the issue of the delay volume applied + - MIPS: jz4740: Bump zload address + - mac80211: restrict delayed tailroom needed decrement + - Smack: Fix handling of IPv4 traffic received by PF_INET6 sockets + - wan/fsl_ucc_hdlc: use IS_ERR_VALUE() to check return value of qe_muram_alloc + - reset: imx7: Fix always writing bits as 0 + - nfp: avoid buffer leak when FW communication fails + - xen-netfront: fix queue name setting + - arm64: dts: qcom: db410c: Fix Bluetooth LED trigger + - ARM: dts: qcom: msm8974-hammerhead: increase load on l20 for sdhci + - s390/qeth: fix race in used-buffer accounting + - s390/qeth: reset layer2 attribute on layer switch + - platform/x86: toshiba_acpi: Fix defined but not used build warnings + - KVM: arm/arm64: Fix vgic init race + - drivers/base: stop new probing during shutdown + - i2c: aspeed: Fix initial values of master and slave state + - dmaengine: mv_xor_v2: kill the tasklets upon exit + - crypto: sharah - Unregister correct algorithms for SAHARA 3 + - xen-netfront: fix warn message as irq device name has '/' + - RDMA/cma: Protect cma dev list with lock + - pstore: Fix incorrect persistent ram buffer mapping + - xen/netfront: fix waiting for xenbus state change + - IB/ipoib: Avoid a race condition between start_xmit and cm_rep_handler + - mmc: omap_hsmmc: fix wakeirq handling on removal + - ipmi: Fix I2C client removal in the SSIF driver + - Tools: hv: Fix a bug in the key delete code + - xhci: Fix use after free for URB cancellation on a reallocated endpoint + - usb: Don't die twice if PCI xhci host is not responding in resume + - mei: ignore not found client in the enumeration + - mei: bus: need to unlink client before freeing + - USB: Add quirk to support DJI CineSSD + - usb: uas: add support for more quirk flags + - usb: Avoid use-after-free by flushing endpoints early in usb_set_interface() + - usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame() + - USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller + - usb: gadget: udc: renesas_usb3: fix maxpacket size of ep0 + - USB: net2280: Fix erroneous synchronization change + - USB: serial: io_ti: fix array underflow in completion handler + - usb: misc: uss720: Fix two sleep-in-atomic-context bugs + - USB: serial: ti_usb_3410_5052: fix array underflow in completion handler + - USB: yurex: Fix buffer over-read in yurex_write() + - Revert "cdc-acm: implement put_char() and flush_chars()" + - cifs: prevent integer overflow in nxt_dir_entry() + - CIFS: fix wrapping bugs in num_entries() + - xtensa: ISS: don't allocate memory in platform_setup + - perf/core: Force USER_DS when recording user stack data + - NFSv4.1 fix infinite loop on I/O. + - binfmt_elf: Respect error return from `regset->active' + - net/mlx5: Add missing SET_DRIVER_VERSION command translation + - arm64: dts: uniphier: Add missing cooling device properties for CPUs + - audit: fix use-after-free in audit_add_watch + - mtdchar: fix overflows in adjustment of `count` + - Bluetooth: Use lock_sock_nested in bt_accept_enqueue + - evm: Don't deadlock if a crypto algorithm is unavailable + - KVM: PPC: Book3S HV: Add of_node_put() in success path + - security: check for kstrdup() failure in lsm_append() + - MIPS: loongson64: cs5536: Fix PCI_OHCI_INT_REG reads + - configfs: fix registered group removal + - pinctrl: rza1: Fix selector use for groups and functions + - sched/core: Use smp_mb() in wake_woken_function() + - efi/esrt: Only call efi_mem_reserve() for boot services memory + - ARM: hisi: handle of_iomap and fix missing of_node_put + - ARM: hisi: fix error handling and missing of_node_put + - ARM: hisi: check of_iomap and fix missing of_node_put + - liquidio: fix hang when re-binding VF host drv after running DPDK VF driver + - gpu: ipu-v3: csi: pass back mbus_code_to_bus_cfg error codes + - tty: fix termios input-speed encoding when using BOTHER + - tty: fix termios input-speed encoding + - mmc: sdhci-of-esdhc: set proper dma mask for ls104x chips + - mmc: tegra: prevent HS200 on Tegra 3 + - mmc: sdhci: do not try to use 3.3V signaling if not supported + - drm/nouveau: Fix runtime PM leak in drm_open() + - drm/nouveau/debugfs: Wake up GPU before doing any reclocking + - drm/nouveau: tegra: Detach from ARM DMA/IOMMU mapping + - parport: sunbpp: fix error return code + - sched/fair: Fix util_avg of new tasks for asymmetric systems + - coresight: Handle errors in finding input/output ports + - coresight: tpiu: Fix disabling timeouts + - coresight: ETM: Add support for Arm Cortex-A73 and Cortex-A35 + - staging: bcm2835-audio: Don't leak workqueue if open fails + - gpio: pxa: Fix potential NULL dereference + - gpiolib: Mark gpio_suffixes array with __maybe_unused + - mfd: 88pm860x-i2c: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - input: rohm_bu21023: switch to i2c_lock_bus(..., I2C_LOCK_SEGMENT) + - drm/amdkfd: Fix error codes in kfd_get_process + - rtc: bq4802: add error handling for devm_ioremap + - ALSA: pcm: Fix snd_interval_refine first/last with open min/max + - scsi: libfc: fixup 'sleeping function called from invalid context' + - drm/panel: type promotion bug in s6e8aa0_read_mtp_id() + - blk-mq: only attempt to merge bio if there is rq in sw queue + - blk-mq: avoid to synchronize rcu inside blk_cleanup_queue() + - pinctrl: msm: Fix msm_config_group_get() to be compliant + - pinctrl: qcom: spmi-gpio: Fix pmic_gpio_config_get() to be compliant + - clk: tegra: bpmp: Don't crash when a clock fails to register + - mei: bus: type promotion bug in mei_nfc_if_version() + - earlycon: Initialize port->uartclk based on clock-frequency property + - earlycon: Remove hardcoded port->uartclk initialization in of_setup_earlycon + - net/ipv6: prevent use after free in ip6_route_mpath_notify + - Partial revert "e1000e: Avoid receiver overrun interrupt bursts" + - e1000e: Fix queue interrupt re-raising in Other interrupt + - e1000e: Avoid missed interrupts following ICR read + - Revert "e1000e: Separate signaling for link check/link up" + - e1000e: Fix link check race condition + - e1000e: Fix check_for_link return value with autoneg off + - tipc: orphan sock in tipc_release() + - net/mlx5: Fix not releasing read lock when adding flow rules + - iommu/arm-smmu-v3: sync the OVACKFLG to PRIQ consumer register + - iwlwifi: cancel the injective function between hw pointers to tfd entry + index + - kbuild: do not update config when running install targets + - omapfb: rename omap2 module to omap2fb.ko + - [Config] Rename omapfb to omap2fb + - perf script: Show correct offsets for DWARF-based unwinding + - iommu/ipmmu-vmsa: IMUCTRn.TTSEL needs a special usage on R-Car Gen3 + - ipmi: Move BT capabilities detection to the detect call + - ovl: fix oopses in ovl_fill_super() failure paths + - usb: xhci: fix interrupt transfer error happened on MTK platforms + - usb: mtu3: fix error of xhci port id when enable U3 dual role + - dm verity: fix crash on bufio buffer that was allocated with vmalloc + - cifs: integer overflow in in SMB2_ioctl() + - perf tools: Fix maps__find_symbol_by_name() + - NFSv4: Fix a tracepoint Oops in initiate_file_draining() + - of: add helper to lookup compatible child node + - mmc: meson-mx-sdio: fix OF child-node lookup + - bpf: fix rcu annotations in compute_effective_progs() + - spi: dw: fix possible race condition + - PM / devfreq: use put_device() instead of kfree() + - ASoC: hdmi-codec: fix routing + - drm/amd/display: support access ddc for mst branch + - rcutorture: Use monotonic timestamp for stall detection + - selftests: vDSO - fix to return KSFT_SKIP when test couldn't be run + - selftests/android: initialize heap_type to avoid compiling warning + - scsi: lpfc: Fix NVME Target crash in defer rcv logic + - scsi: lpfc: Fix panic if driver unloaded when port is offline + - arm64: perf: Disable PMU while processing counter overflows + - staging: fsl-dpaa2/eth: Fix DMA mapping direction + - block/DAC960.c: fix defined but not used build warnings + - IB/mlx5: fix uaccess beyond "count" in debugfs read/write handlers + * Bionic update: upstream stable patchset 2019-07-09 (LP: #1835972) + - vti6: fix PMTU caching and reporting on xmit + - xfrm: fix missing dst_release() after policy blocking lbcast and multicast + - xfrm: free skb if nlsk pointer is NULL + - esp6: fix memleak on error path in esp6_input + - mac80211: add stations tied to AP_VLANs during hw reconfig + - ext4: clear mmp sequence number when remounting read-only + - nl80211: Add a missing break in parse_station_flags + - drm/bridge: adv7511: Reset registers on hotplug + - scsi: target: iscsi: cxgbit: fix max iso npdu calculation + - scsi: libiscsi: fix possible NULL pointer dereference in case of TMF + - drm/imx: imx-ldb: disable LDB on driver bind + - drm/imx: imx-ldb: check if channel is enabled before printing warning + - nbd: don't requeue the same request twice. + - nbd: handle unexpected replies better + - usb: gadget: r8a66597: Fix two possible sleep-in-atomic-context bugs in + init_controller() + - usb: gadget: r8a66597: Fix a possible sleep-in-atomic-context bugs in + r8a66597_queue() + - usb: gadget: f_uac2: fix error handling in afunc_bind (again) + - usb: gadget: u_audio: fix pcm/card naming in g_audio_setup() + - usb: gadget: u_audio: update hw_ptr in iso_complete after data copied + - usb: gadget: u_audio: remove caching of stream buffer parameters + - usb: gadget: u_audio: remove cached period bytes value + - usb: gadget: u_audio: protect stream runtime fields with stream spinlock + - usb/phy: fix PPC64 build errors in phy-fsl-usb.c + - tools: usb: ffs-test: Fix build on big endian systems + - usb: gadget: f_uac2: fix endianness of 'struct cntrl_*_lay3' + - netfilter: nft_set_hash: add rcu_barrier() in the nft_rhash_destroy() + - bpf, ppc64: fix unexpected r0=0 exit path inside bpf_xadd + - netfilter: nf_tables: fix memory leaks on chain rename + - netfilter: nf_tables: don't allow to rename to already-pending name + - KVM: vmx: use local variable for current_vmptr when emulating VMPTRST + - tools/power turbostat: fix -S on UP systems + - net: caif: Add a missing rcu_read_unlock() in caif_flow_cb + - qed: Fix link flap issue due to mismatching EEE capabilities. + - qed: Fix possible race for the link state value. + - qed: Correct Multicast API to reflect existence of 256 approximate buckets. + - atl1c: reserve min skb headroom + - net: prevent ISA drivers from building on PPC32 + - can: mpc5xxx_can: check of_iomap return before use + - can: m_can: Move accessing of message ram to after clocks are enabled + - i2c: davinci: Avoid zero value of CLKH + - perf/x86/amd/ibs: Don't access non-started event + - media: staging: omap4iss: Include asm/cacheflush.h after generic includes + - bnx2x: Fix invalid memory access in rss hash config path. + - net: axienet: Fix double deregister of mdio + - locking/rtmutex: Allow specifying a subclass for nested locking + - i2c/mux, locking/core: Annotate the nested rt_mutex usage + - sched/rt: Restore rt_runtime after disabling RT_RUNTIME_SHARE + - x86/boot: Fix if_changed build flip/flop bug + - selftests/ftrace: Add snapshot and tracing_on test case + - ipc/sem.c: prevent queue.status tearing in semop + - zswap: re-check zswap_is_full() after do zswap_shrink() + - tools/power turbostat: Read extended processor family from CPUID + - ARC: dma [non-IOC] setup SMP_CACHE_BYTES and cache_line_size + - bpf: use GFP_ATOMIC instead of GFP_KERNEL in bpf_parse_prog() + - nfp: flower: fix port metadata conversion bug + - enic: handle mtu change for vf properly + - ARC: [plat-eznps] Add missing struct nps_host_reg_aux_dpc + - arc: [plat-eznps] fix data type errors in platform headers + - arc: [plat-eznps] fix printk warning in arc/plat-eznps/mtm.c + - arc: fix build errors in arc/include/asm/delay.h + - arc: fix type warnings in arc/mm/cache.c + - sparc/time: Add missing __init to init_tick_ops() + - sparc: use asm-generic version of msi.h + - enic: do not call enic_change_mtu in enic_probe + - mm: delete historical BUG from zap_pmd_range() + - drivers: net: lmc: fix case value for target abort error + - memcg: remove memcg_cgroup::id from IDR on mem_cgroup_css_alloc() failure + - gpiolib-acpi: make sure we trigger edge events at least once on boot + - scsi: fcoe: fix use-after-free in fcoe_ctlr_els_send + - scsi: fcoe: drop frames in ELS LOGO error path + - scsi: vmw_pvscsi: Return DID_RESET for status SAM_STAT_COMMAND_TERMINATED + - mm/memory.c: check return value of ioremap_prot + - mei: don't update offset in write + - cifs: add missing debug entries for kconfig options + - cifs: check kmalloc before use + - smb3: enumerating snapshots was leaving part of the data off end + - smb3: Do not send SMB3 SET_INFO if nothing changed + - smb3: don't request leases in symlink creation and query + - smb3: fill in statfs fsid and correct namelen + - btrfs: use correct compare function of dirty_metadata_bytes + - btrfs: don't leak ret from do_chunk_alloc + - Btrfs: fix btrfs_write_inode vs delayed iput deadlock + - iommu/arm-smmu: Error out only if not enough context interrupts + - printk: Split the code for storing a message into the log buffer + - printk: Create helper function to queue deferred console handling + - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI + - kprobes/arm64: Fix %p uses in error messages + - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid() + - arm64: dts: rockchip: corrected uart1 clock-names for rk3328 + - KVM: arm/arm64: Skip updating PMD entry if no change + - KVM: arm/arm64: Skip updating PTE entry if no change + - stop_machine: Reflow cpu_stop_queue_two_works() + - ext4: check for NUL characters in extended attribute's name + - ext4: sysfs: print ext4_super_block fields as little-endian + - ext4: reset error code in ext4_find_entry in fallback + - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too + - x86/vdso: Fix vDSO build if a retpoline is emitted + - x86/process: Re-export start_thread() + - x86/kvm/vmx: Remove duplicate l1d flush definitions + - fuse: Add missed unlock_page() to fuse_readpages_fill() + - udl-kms: change down_interruptible to down + - udl-kms: handle allocation failure + - udl-kms: fix crash due to uninitialized memory + - udl-kms: avoid division + - b43legacy/leds: Ensure NUL-termination of LED name string + - b43/leds: Ensure NUL-termination of LED name string + - ASoC: dpcm: don't merge format from invalid codec dai + - ASoC: zte: Fix incorrect PCM format bit usages + - ASoC: sirf: Fix potential NULL pointer dereference + - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show() + - x86/vdso: Fix lsl operand order + - x86/irqflags: Mark native_restore_fl extern inline + - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit() + - s390/mm: fix addressing exception after suspend/resume + - s390/numa: move initial setup of node_to_cpumask_map + - kprobes/arm: Fix %p uses in error messages + - kprobes: Make list and blacklist root user read only + - MIPS: Correct the 64-bit DSP accumulator register size + - MIPS: Always use -march=, not - shortcuts + - MIPS: Change definition of cpu_relax() for Loongson-3 + - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7 + - tpm: Return the actual size when receiving an unsupported command + - scsi: mpt3sas: Fix _transport_smp_handler() error path + - scsi: sysfs: Introduce sysfs_{un,}break_active_protection() + - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock + - clk: rockchip: fix clk_i2sout parent selection bits on rk3399 + - PM / clk: signedness bug in of_pm_clk_add_clks() + - power: generic-adc-battery: fix out-of-bounds write when copying channel + properties + - power: generic-adc-battery: check for duplicate properties copied from iio + channels + - watchdog: Mark watchdog touch functions as notrace + - gcc-plugins: Add include required by GCC release 8 + - gcc-plugins: Use dynamic initializers + - Btrfs: fix send failure when root has deleted files still open + - Btrfs: send, fix incorrect file layout after hole punching beyond eof + - hwmon: (k10temp) 27C Offset needed for Threadripper2 + - KVM: arm/arm64: Fix potential loss of ptimer interrupts + - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked + - perf kvm: Fix subcommands on s390 + - ext4: use ext4_warning() for sb_getblk failure + - platform/x86: wmi: Do not mix pages and kmalloc + - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd + - lib/vsprintf: Do not handle %pO[^F] as %px + - soc: qcom: rmtfs-mem: fix memleak in probe error paths + - kprobes: Show blacklist addresses as same as kallsyms does + - kprobes: Replace %p with other pointer types + - MIPS: memset.S: Fix byte_fixup for MIPSr6 + - mtd: rawnand: qcom: wait for desc completion in all BAM channels + - net: 6lowpan: fix reserved space for single frames + - net: mac802154: tx: expand tailroom if necessary + - 9p/net: Fix zero-copy path in the 9p virtio transport + - spi: davinci: fix a NULL pointer dereference + - spi: pxa2xx: Add support for Intel Ice Lake + - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe + - spi: cadence: Change usleep_range() to udelay(), for atomic context + - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS + - readahead: stricter check for bdi io_pages + - block: blk_init_allocated_queue() set q->fq as NULL in the fail case + - block: really disable runtime-pm for blk-mq + - drm/i915/userptr: reject zero user_size + - libertas: fix suspend and resume for SDIO connected cards + - media: Revert "[media] tvp5150: fix pad format frame height" + - mailbox: xgene-slimpro: Fix potential NULL pointer dereference + - Replace magic for trusting the secondary keyring with #define + - powerpc/fadump: handle crash memory ranges array index overflow + - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler. + - PCI: Add wrappers for dev_printk() + - cxl: Fix wrong comparison in cxl_adapter_context_get() + - ib_srpt: Fix a use-after-free in srpt_close_ch() + - RDMA/rxe: Set wqe->status correctly if an unexpected response is received + - 9p: fix multiple NULL-pointer-dereferences + - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed + - 9p/virtio: fix off-by-one error in sg list bounds check + - net/9p/client.c: version pointer uninitialized + - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the + kfree() + - dm integrity: change 'suspending' variable from bool to int + - dm thin: stop no_space_timeout worker when switching to write-mode + - dm cache metadata: save in-core policy_hint_size to on-disk superblock + - dm cache metadata: set dirty on all cache blocks after a crash + - dm crypt: don't decrease device limits + - uart: fix race between uart_put_char() and uart_shutdown() + - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind() + - iio: sca3000: Fix missing return in switch + - iio: ad9523: Fix displayed phase + - iio: ad9523: Fix return value for ad952x_store() + - extcon: Release locking when sending the notification of connector state + - vmw_balloon: fix inflation of 64-bit GFNs + - vmw_balloon: do not use 2MB without batching + - vmw_balloon: VMCI_DOORBELL_SET does not check status + - vmw_balloon: fix VMCI use when balloon built into kernel + - rtc: omap: fix potential crash on power off + - tracing: Do not call start/stop() functions when tracing_on does not change + - tracing/blktrace: Fix to allow setting same value + - printk/tracing: Do not trace printk_nmi_enter() + - livepatch: Validate module/old func name length + - uprobes: Use synchronize_rcu() not synchronize_sched() + - mfd: hi655x: Fix regmap area declared size for hi655x + - ovl: fix wrong use of impure dir cache in ovl_iterate() + - drivers/block/zram/zram_drv.c: fix bug storing backing_dev + - cpufreq: governor: Avoid accessing invalid governor_data + - PM / sleep: wakeup: Fix build error caused by missing SRCU support + - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages + - xtensa: limit offsets in __loop_cache_{all,page} + - xtensa: increase ranges in ___invalidate_{i,d}cache_all + - block, bfq: return nbytes and not zero from struct cftype .write() method + - pnfs/blocklayout: off by one in bl_map_stripe() + - NFSv4 client live hangs after live data migration recovery + - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs + - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence() + - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset + - iommu/vt-d: Add definitions for PFSID + - iommu/vt-d: Fix dev iotlb pfsid use + - sys: don't hold uts_sem while accessing userspace memory + - userns: move user access out of the mutex + - ubifs: Fix memory leak in lprobs self-check + - ubifs: Check data node size before truncate + - ubifs: Fix synced_i_size calculation for xattr inodes + - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output + - pwm: tiehrpwm: Fix disabling of output of PWMs + - fb: fix lost console when the user unplugs a USB adapter + - udlfb: set optimal write delay + - libnvdimm: fix ars_status output length calculation + - bcache: release dc->writeback_lock properly in bch_writeback_thread() + - perf auxtrace: Fix queue resize + - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3 + - crypto: caam/jr - fix descriptor DMA unmapping + - crypto: caam/qi - fix error path in xts setkey + - arm64: mm: always enable CONFIG_HOLES_IN_ZONE + - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts + - blkcg: Introduce blkg_root_lookup() + - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls + - IB/mlx5: Fix leaking stack memory to userspace + - rtc: omap: fix resource leak in registration error path + - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure + - ALSA: ac97: fix device initialization in the compat layer + - ALSA: ac97: fix check of pm_runtime_get_sync failure + - ALSA: ac97: fix unbalanced pm_runtime_enable + - nfsd: fix leaked file lock with nfs exported overlayfs + - ubifs: Fix directory size calculation for symlinks + - mm, dev_pagemap: Do not clear ->mapping on final put + - act_ife: fix a potential use-after-free + - ipv4: tcp: send zero IPID for RST and ACK sent in SYN-RECV and TIME-WAIT + state + - net: bcmgenet: use MAC link status for fixed phy + - net: macb: do not disable MDIO bus at open/close time + - qlge: Fix netdev features configuration. + - r8169: add support for NCube 8168 network card + - tcp: do not restart timewait timer on rst reception + - vti6: remove !skb->ignore_df check from vti6_xmit() + - net/sched: act_pedit: fix dump of extended layered op + - tipc: fix a missing rhashtable_walk_exit() + - nfp: wait for posted reconfigs when disabling the device + - sctp: hold transport before accessing its asoc in sctp_transport_get_next + - mlxsw: spectrum_switchdev: Do not leak RIFs when removing bridge + - vhost: correctly check the iova range when waking virtqueue + - hv_netvsc: ignore devices that are not PCI + - act_ife: move tcfa_lock down to where necessary + - act_ife: fix a potential deadlock + - net: sched: action_ife: take reference to meta module + - cifs: check if SMB2 PDU size has been padded and suppress the warning + - hfsplus: don't return 0 when fill_super() failed + - hfs: prevent crash on exit from failed search + - sunrpc: Don't use stack buffer with scatterlist + - fork: don't copy inconsistent signal handler state to child + - reiserfs: change j_timestamp type to time64_t + - hfsplus: fix NULL dereference in hfsplus_lookup() + - fs/proc/kcore.c: use __pa_symbol() for KCORE_TEXT list entries + - fat: validate ->i_start before using + - scripts: modpost: check memory allocation results + - virtio: pci-legacy: Validate queue pfn + - x86/mce: Add notifier_block forward declaration + - IB/hfi1: Invalid NUMA node information can cause a divide by zero + - pwm: meson: Fix mux clock names + - mm/fadvise.c: fix signed overflow UBSAN complaint + - fs/dcache.c: fix kmemcheck splat at take_dentry_name_snapshot() + - platform/x86: intel_punit_ipc: fix build errors + - netfilter: ip6t_rpfilter: set F_IFACE for linklocal addresses + - s390/kdump: Fix memleak in nt_vmcoreinfo + - ipvs: fix race between ip_vs_conn_new() and ip_vs_del_dest() + - mfd: sm501: Set coherent_dma_mask when creating subdevices + - platform/x86: asus-nb-wmi: Add keymap entry for lid flip action on UX360 + - netfilter: fix memory leaks on netlink_dump_start error + - tcp, ulp: add alias for all ulp modules + - RDMA/hns: Fix usage of bitmap allocation functions return values + - net: hns3: Fix for command format parsing error in + hclge_is_all_function_id_zero + - perf tools: Check for null when copying nsinfo. + - irqchip/bcm7038-l1: Hide cpu offline callback when building for !SMP + - net/9p/trans_fd.c: fix race by holding the lock + - net/9p: fix error path of p9_virtio_probe + - powerpc/uaccess: Enable get_user(u64, *p) on 32-bit + - powerpc: Fix size calculation using resource_size() + - perf probe powerpc: Fix trace event post-processing + - block: bvec_nr_vecs() returns value for wrong slab + - s390/dasd: fix hanging offline processing due to canceled worker + - s390/dasd: fix panic for failed online processing + - ACPI / scan: Initialize status to ACPI_STA_DEFAULT + - scsi: aic94xx: fix an error code in aic94xx_init() + - NFSv4: Fix error handling in nfs4_sp4_select_mode() + - Input: do not use WARN() in input_alloc_absinfo() + - xen/balloon: fix balloon initialization for PVH Dom0 + - PCI: mvebu: Fix I/O space end address calculation + - dm kcopyd: avoid softlockup in run_complete_job + - staging: comedi: ni_mio_common: fix subdevice flags for PFI subdevice + - ASoC: rt5677: Fix initialization of rt5677_of_match.data + - iommu/omap: Fix cache flushes on L2 table entries + - selftests/powerpc: Kill child processes on SIGINT + - RDS: IB: fix 'passing zero to ERR_PTR()' warning + - cfq: Suppress compiler warnings about comparisons + - smb3: fix reset of bytes read and written stats + - SMB3: Number of requests sent should be displayed for SMB3 not just CIFS + - powerpc/platforms/85xx: fix t1042rdb_diu.c build errors & warning + - powerpc/64s: Make rfi_flush_fallback a little more robust + - powerpc/pseries: Avoid using the size greater than RTAS_ERROR_LOG_MAX. + - clk: rockchip: Add pclk_rkpwm_pmu to PMU critical clocks in rk3399 + - KVM: vmx: track host_state.loaded using a loaded_vmcs pointer + - kvm: nVMX: Fix fault vector for VMX operation at CPL > 0 + - btrfs: Exit gracefully when chunk map cannot be inserted to the tree + - btrfs: replace: Reset on-disk dev stats value after replace + - btrfs: relocation: Only remove reloc rb_trees if reloc control has been + initialized + - btrfs: Don't remove block group that still has pinned down bytes + - arm64: rockchip: Force CONFIG_PM on Rockchip systems + - ARM: rockchip: Force CONFIG_PM on Rockchip systems + - drm/i915/lpe: Mark LPE audio runtime pm as "no callbacks" + - drm/amdgpu: Fix RLC safe mode test in gfx_v9_0_enter_rlc_safe_mode + - drm/amd/pp/Polaris12: Fix a chunk of registers missed to program + - drm/amdgpu: update tmr mc address + - drm/amdgpu:add tmr mc address into amdgpu_firmware_info + - drm/amdgpu:add new firmware id for VCN + - drm/amdgpu:add VCN support in PSP driver + - drm/amdgpu:add VCN booting with firmware loaded by PSP + - debugobjects: Make stack check warning more informative + - mm: Fix devm_memremap_pages() collision handling + - HID: add quirk for another PIXART OEM mouse used by HP + - usb: dwc3: core: Fix ULPI PHYs and prevent phy_get/ulpi_init during + suspend/resume + - x86/pae: use 64 bit atomic xchg function in native_ptep_get_and_clear + - x86/xen: don't write ptes directly in 32-bit PV guests + - drm/i915: Increase LSPCON timeout + - kbuild: make missing $DEPMOD a Warning instead of an Error + - kvm: x86: Set highest physical address bits in non-present/reserved SPTEs + - x86: kvm: avoid unused variable warning + - arm64: cpu_errata: include required headers + - ASoC: wm8994: Fix missing break in switch + - arm64: Fix mismatched cache line size detection + - arm64: Handle mismatched cache type + - tipc: fix the big/little endian issue in tipc_dest + - ip6_vti: fix a null pointer deference when destroy vti6 tunnel + - workqueue: skip lockdep wq dependency in cancel_work_sync() + - workqueue: re-add lockdep dependencies for flushing + - apparmor: fix an error code in __aa_create_ns() + - tcp, ulp: fix leftover icsk_ulp_ops preventing sock from reattach + - netfilter: x_tables: do not fail xt_alloc_table_info too easilly + - ACPICA: ACPICA: add status check for acpi_hw_read before assigning return + value + - PCI: Match Root Port's MPS to endpoint's MPSS as necessary + - coccicheck: return proper error code on fail + - RISC-V: Use KBUILD_CFLAGS instead of KCFLAGS when building the vDSO + - blk-mq: count the hctx as active before allocating tag + - selinux: cleanup dentry and inodes on error in selinuxfs + - drm/amd/display: Read back max backlight value at boot + - btrfs: check-integrity: Fix NULL pointer dereference for degraded mount + - btrfs: lift uuid_mutex to callers of btrfs_open_devices + - btrfs: Fix a C compliance issue + - drm/i915: Nuke the LVDS lid notifier + - drm/edid: Quirk Vive Pro VR headset non-desktop. + - drm/amd/display: fix type of variable + - drm/amd/display: Don't share clk source between DP and HDMI + - drm/amd/display: update clk for various HDMI color depths + - drm/amd/display: Use requested HDMI aspect ratio + - drm/rockchip: lvds: add missing of_node_put + - drm/amd/display: Pass connector id when executing VBIOS CT + - drm/amd/display: Check if clock source in use before disabling + - drm/amdgpu: fix incorrect use of fcheck + - drm/amdgpu: fix incorrect use of drm_file->pid + - drm/i915: set DP Main Stream Attribute for color range on DDI platforms + - x86/tsc: Prevent result truncation on 32bit + * [Regression] Colour banding appears on Lenovo B50-80 integrated display + (LP: #1788308) // Bionic update: upstream stable patchset 2019-07-09 + (LP: #1835972) + - drm/edid: Add 6 bpc quirk for SDC panel in Lenovo B50-80 + * CVE-2019-12819 + - mdio_bus: Fix use-after-free on device_register fails + * proc_thermal flooding dmesg (LP: #1824690) + - drivers: thermal: processor_thermal: Downgrade error message + * Bionic update: upstream stable patchset 2019-07-08 (LP: #1835845) + - bonding: avoid lockdep confusion in bond_get_stats() + - inet: frag: enforce memory limits earlier + - ipv4: frags: handle possible skb truesize change + - net: dsa: Do not suspend/resume closed slave_dev + - net: stmmac: Fix WoL for PCI-based setups + - rxrpc: Fix user call ID check in rxrpc_service_prealloc_one + - can: ems_usb: Fix memory leak on ems_usb_disconnect() + - virtio_balloon: fix another race between migration and ballooning + - x86/apic: Future-proof the TSC_DEADLINE quirk for SKX + - kvm: x86: vmx: fix vpid leak + - audit: fix potential null dereference 'context->module.name' + - userfaultfd: remove uffd flags from vma->vm_flags if UFFD_EVENT_FORK fails + - RDMA/uverbs: Expand primary and alt AV port checks + - crypto: padlock-aes - Fix Nano workaround data corruption + - drm/vc4: Reset ->{x, y}_scaling[1] when dealing with uniplanar formats + - scsi: sg: fix minor memory leak in error path + - net/mlx5e: E-Switch, Initialize eswitch only if eswitch manager + - net/mlx5e: Set port trust mode to PCP as default + - x86/efi: Access EFI MMIO data as unencrypted when SEV is active + - drm/atomic: Check old_plane_state->crtc in drm_atomic_helper_async_check() + - drm/atomic: Initialize variables in drm_atomic_helper_async_check() to make + gcc happy + - scsi: qla2xxx: Fix unintialized List head crash + - scsi: qla2xxx: Fix NPIV deletion by calling wait_for_sess_deletion + - scsi: qla2xxx: Fix ISP recovery on unload + - scsi: qla2xxx: Return error when TMF returns + - genirq: Make force irq threading setup more robust + - nohz: Fix local_timer_softirq_pending() + - nohz: Fix missing tick reprogram when interrupting an inline softirq + - ring_buffer: tracing: Inherit the tracing setting to next ring buffer + - i2c: imx: Fix reinit_completion() use + - Btrfs: fix file data corruption after cloning a range and fsync + - nvme-pci: allocate device queues storage space at probe + - nvme-pci: Fix queue double allocations + - xfs: catch inode allocation state mismatch corruption + - xfs: validate cached inodes are free when allocated + - perf/x86/intel/uncore: Fix hardcoded index of Broadwell extra PCI devices + - parisc: Enable CONFIG_MLONGCALLS by default + - parisc: Define mb() and add memory barriers to assembler unlock sequences + - kasan: add no_sanitize attribute for clang builds + - Mark HI and TASKLET softirq synchronous + - xen/netfront: don't cache skb_shinfo() + - scsi: sr: Avoid that opening a CD-ROM hangs with runtime power management + enabled + - scsi: qla2xxx: Fix memory leak for allocating abort IOCB + - init: rename and re-order boot_cpu_state_init() + - root dentries need RCU-delayed freeing + - make sure that __dentry_kill() always invalidates d_seq, unhashed or not + - fix mntput/mntput race + - fix __legitimize_mnt()/mntput() race + - mtd: nand: qcom: Add a NULL check for devm_kasprintf() + - phy: phy-mtk-tphy: use auto instead of force to bypass utmi signals + - ARM: dts: imx6sx: fix irq for pcie bridge + - kprobes/x86: Fix %p uses in error messages + - x86/irqflags: Provide a declaration for native_save_fl + - x86/apic: Ignore secondary threads if nosmt=force + - x86/mm/kmmio: Make the tracer robust against L1TF + - tools headers: Synchronise x86 cpufeatures.h for L1TF additions + - x86/microcode: Allow late microcode loading with SMT disabled + - x86/smp: fix non-SMP broken build due to redefinition of + apic_id_is_primary_thread + - cpu/hotplug: Non-SMP machines do not make use of booted_once + - sched/deadline: Update rq_clock of later_rq when pushing a task + - zram: remove BD_CAP_SYNCHRONOUS_IO with writeback feature + - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled + - x86: i8259: Add missing include file + - kbuild: verify that $DEPMOD is installed + - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2() + - crypto: vmac - require a block cipher with 128-bit block size + - crypto: vmac - separate tfm and request context + - crypto: blkcipher - fix crash flushing dcache in error path + - crypto: ablkcipher - fix crash flushing dcache in error path + - crypto: skcipher - fix aligning block size in skcipher_copy_iv() + - crypto: skcipher - fix crash flushing dcache in error path + - x86/platform/UV: Mark memblock related init code and data correctly + - dccp: fix undefined behavior with 'cwnd' shift in ccid2_cwnd_restart() + - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache + - llc: use refcount_inc_not_zero() for llc_sap_find() + - vsock: split dwork to avoid reinitializations + - net_sched: Fix missing res info when create new tc_index filter + - vhost: reset metadata cache when initializing new IOTLB + - ip6_tunnel: use the right value for ipv4 min mtu check in ip6_tnl_xmit + - net: aquantia: Fix IFF_ALLMULTI flag functionality + - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs + - ALSA: hda - Turn CX8200 into D3 as well upon reboot + - ALSA: vx222: Fix invalid endian conversions + - ALSA: virmidi: Fix too long output trigger loop + - ALSA: cs5535audio: Fix invalid endian conversion + - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry + - ALSA: memalloc: Don't exceed over the requested size + - ALSA: vxpocket: Fix invalid endian conversions + - USB: serial: sierra: fix potential deadlock at close + - USB: serial: pl2303: add a new device id for ATEN + - ACPI / PM: save NVS memory for ASUS 1025C laptop + - tty: serial: 8250: Revert NXP SC16C2552 workaround + - serial: 8250_exar: Read INT0 from slave device, too + - serial: 8250_dw: always set baud rate in dw8250_set_termios + - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC + - misc: sram: fix resource leaks in probe error path + - Bluetooth: avoid killing an already killed socket + - isdn: Disable IIOCDBGVAR + - cls_matchall: fix tcf_unbind_filter missing + - mlxsw: core_acl_flex_actions: Return error for conflicting actions + - ip_vti: fix a null pointer deferrence when create vti fallback tunnel + - net: ethernet: mvneta: Fix napi structure mixup on armada 3700 + - net: mvneta: fix mvneta_config_rss on armada 3700 + - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[] + - pty: fix O_CLOEXEC for TIOCGPTPEER + - arm: dts: armada: Fix "#cooling-cells" property's name + - vfio: ccw: fix error return in vfio_ccw_sch_event + - perf tools: Fix error index for pmu event parser + - Input: synaptics-rmi4 - fix axis-swap behavior + - IB/mlx4: Fix an error handling path in 'mlx4_ib_rereg_user_mr()' + - drm/bridge/sii8620: fix loops in EDID fetch logic + - drm/bridge/sii8620: fix potential buffer overflow + - ARC: Explicitly add -mmedium-calls to CFLAGS + - hwmon: (nct6775) Fix loop limit + - soc: imx: gpcv2: correct PGC offset + - usb: dwc3: pci: add support for Intel IceLake + - usb: dwc2: gadget: Fix issue in dwc2_gadget_start_isoc() + - usb: dwc3: of-simple: fix use-after-free on remove + - ACPI / EC: Use ec_no_wakeup on Thinkpad X1 Carbon 6th + - netfilter: ipv6: nf_defrag: reduce struct net memory waste + - netfilter: nf_ct_helper: Fix possible panic after + nf_conntrack_helper_unregister + - selftests: pstore: return Kselftest Skip code for skipped tests + - selftests: static_keys: return Kselftest Skip code for skipped tests + - selftests: sysctl: return Kselftest Skip code for skipped tests + - selftests: zram: return Kselftest Skip code for skipped tests + - selftests: vm: return Kselftest Skip code for skipped tests + - selftests: sync: add config fragment for testing sync framework + - ARM: dts: NSP: Fix i2c controller interrupt type + - ARM: dts: NSP: Fix PCIe controllers interrupt types + - ARM: dts: BCM5301x: Fix i2c controller interrupt type + - ARM: dts: Cygnus: Fix I2C controller interrupt type + - ARM: dts: Cygnus: Fix PCIe controller interrupt type + - arm64: dts: specify 1.8V EMMC capabilities for bcm958742k + - arm64: dts: specify 1.8V EMMC capabilities for bcm958742t + - arm64: dts: ns2: Fix I2C controller interrupt type + - arm64: dts: ns2: Fix PCIe controller interrupt type + - arm64: dts: Stingray: Fix I2C controller interrupt type + - drivers/perf: xgene_pmu: Fix IOB SLOW PMU parser error + - drm: mali-dp: Enable Global SE interrupts mask for DP500 + - drm/arm/malidp: Preserve LAYER_FORMAT contents when setting format + - IB/rxe: Fix missing completion for mem_reg work requests + - usb: dwc2: alloc dma aligned buffer for isoc split in + - usb: dwc2: fix isoc split in transfer with no data + - usb: gadget: composite: fix delayed_status race condition when set_interface + - usb: gadget: dwc2: fix memory leak in gadget_init() + - dwc2: gadget: Fix ISOC IN DDMA PID bitfield value calculation + - xen: add error handling for xenbus_printf + - pNFS: Always free the session slot on error in + nfs4_layoutget_handle_exception + - scsi: xen-scsifront: add error handling for xenbus_printf + - xen/scsiback: add error handling for xenbus_printf + - arm64: dma-mapping: clear buffers allocated with FORCE_CONTIGUOUS flag + - arm64: make secondary_start_kernel() notrace + - qed: Fix possible memory leak in Rx error path handling. + - qed: Add sanity check for SIMD fastpath handler. + - qed: Do not advertise DCBX_LLD_MANAGED capability. + - enic: initialize enic->rfs_h.lock in enic_probe + - net: hamradio: use eth_broadcast_addr + - net: propagate dev_get_valid_name return code + - net: stmmac: socfpga: add additional ocp reset line for Stratix10 + - nvmet: reset keep alive timer in controller enable + - block: sed-opal: Fix a couple off by one bugs + - ARC: Enable machine_desc->init_per_cpu for !CONFIG_SMP + - nbd: Add the nbd NBD_DISCONNECT_ON_CLOSE config flag. + - net: davinci_emac: match the mdio device against its compatible if possible + - sctp: fix erroneous inc of snmp SctpFragUsrMsgs + - KVM: arm/arm64: Drop resource size check for GICV window + - drm/bridge/sii8620: fix display of packed pixel modes in MHL2 + - locking/lockdep: Do not record IRQ state within lockdep code + - selftests: bpf: notification about privilege required to run test_kmod.sh + testing script + - mtd: dataflash: Use ULL suffix for 64-bit constants + - x86/microcode/intel: Fix memleak in save_microcode_patch() + - ipv6: mcast: fix unsolicited report interval after receiving querys + - Smack: Mark inode instant in smack_task_to_inode + - arm64: dts: msm8916: fix Coresight ETF graph connections + - batman-adv: Fix bat_ogm_iv best gw refcnt after netlink dump + - batman-adv: Fix bat_v best gw refcnt after netlink dump + - batman-adv: Avoid storing non-TT-sync flags on singular entries too + - batman-adv: Fix multicast TT issues with bogus ROAM flags + - cxgb4: when disabling dcb set txq dcb priority to 0 + - iio: pressure: bmp280: fix relative humidity unit + - brcmfmac: stop watchdog before detach and free everything + - ARM: dts: am437x: make edt-ft5x06 a wakeup source + - ALSA: seq: Fix UBSAN warning at SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT ioctl + - usb: xhci: remove the code build warning + - usb: xhci: increase CRS timeout value + - NFC: pn533: Fix wrong GFP flag usage + - typec: tcpm: Fix a msecs vs jiffies bug + - kconfig: fix line numbers for if-entries in menu tree + - perf record: Support s390 random socket_id assignment + - perf test session topology: Fix test on s390 + - perf report powerpc: Fix crash if callchain is empty + - perf tools: Fix a clang 7.0 compilation error + - perf bench: Fix numa report output code + - ARM: davinci: board-da850-evm: fix WP pin polarity for MMC/SD + - netfilter: nf_log: fix uninit read in nf_log_proc_dostring + - net/mlx5: E-Switch, Disallow vlan/spoofcheck setup if not being esw manager + - nfp: cast sizeof() to int when comparing with error code + - selftests/x86/sigreturn/64: Fix spurious failures on AMD CPUs + - selftests/x86/sigreturn: Do minor cleanups + - ARM: dts: da850: Fix interrups property for gpio + - ARM64: dts: meson-gxl: fix Mali GPU compatible string + - dmaengine: pl330: report BURST residue granularity + - dmaengine: k3dma: Off by one in k3_of_dma_simple_xlate() + - ath10k: update the phymode along with bandwidth change request + - md/raid10: fix that replacement cannot complete recovery after reassemble + - dev-dax: check_vma: ratelimit dev_info-s + - nl80211: relax ht operation checks for mesh + - nl80211: check nla_parse_nested() return values + - drm/exynos: gsc: Fix support for NV16/61, YUV420/YVU420 and YUV422 modes + - drm/exynos: decon5433: Fix per-plane global alpha for XRGB modes + - drm/exynos: decon5433: Fix WINCONx reset value + - drbd: Fix drbd_request_prepare() discard handling + - bpf, s390: fix potential memleak when later bpf_jit_prog fails + - PCI: xilinx: Add missing of_node_put() + - PCI: xilinx-nwl: Add missing of_node_put() + - PCI: faraday: Add missing of_node_put() + - bnx2x: Fix receiving tx-timeout in error or recovery state. + - fsl/fman: fix parser reporting bad checksum on short frames + - dpaa_eth: DPAA SGT needs to be 256B + - acpi/nfit: fix cmd_rc for acpi_nfit_ctl to always return a value + - openrisc: entry: Fix delay slot exception detection + - m68k: fix "bad page state" oops on ColdFire boot + - objtool: Support GCC 8 '-fnoreorder-functions' + - ipvlan: call dev_change_flags when ipvlan mode is reset + - drm/amdgpu: fix swapped emit_ib_size in vce3 + - x86/mm/32: Initialize the CR4 shadow before __flush_tlb_all() + - HID: wacom: Correct touch maximum XY of 2nd-gen Intuos + - ARM: imx_v4_v5_defconfig: Select ULPI support + - bpf: hash map: decrement counter on error + - tracing: Use __printf markup to silence compiler + - kasan: fix shadow_size calculation error in kasan_module_alloc + - smsc75xx: Add workaround for gigabit link up hardware errata. + - drm/bridge/sii8620: Fix display of packed pixel modes + - samples/bpf: add missing + - samples/bpf: Check the result of system() + - samples/bpf: Check the error of write() and read() + - ieee802154: 6lowpan: set IFLA_LINK + - netfilter: x_tables: set module owner for icmp(6) matches + - ipv6: make ipv6_renew_options() interrupt/kernel safe + - net: qrtr: Broadcast messages only from control port + - sh_eth: fix invalid context bug while calling auto-negotiation by ethtool + - sh_eth: fix invalid context bug while changing link options by ethtool + - ravb: fix invalid context bug while calling auto-negotiation by ethtool + - ravb: fix invalid context bug while changing link options by ethtool + - ARM: pxa: irq: fix handling of ICMR registers in suspend/resume + - net/sched: act_tunnel_key: fix NULL dereference when 'goto chain' is used + - nvmem: Don't let a NULL cell_id for nvmem_cell_get() crash us + - ieee802154: at86rf230: switch from BUG_ON() to WARN_ON() on problem + - ieee802154: at86rf230: use __func__ macro for debug messages + - ieee802154: fakelb: switch from BUG_ON() to WARN_ON() on problem + - gpu: host1x: Check whether size of unpin isn't 0 + - drm/tegra: Fix comparison operator for buffer size + - drm/armada: fix colorkey mode property + - drm/armada: fix irq handling + - netfilter: nft_compat: explicitly reject ERROR and standard target + - netfilter: nf_conntrack: Fix possible possible crash on module loading. + - ARC: Improve cmpxchg syscall implementation + - bnxt_en: Fix inconsistent BNXT_FLAG_AGG_RINGS logic. + - bnxt_en: Always set output parameters in bnxt_get_max_rings(). + - bnxt_en: Fix for system hang if request_irq fails + - scsi: qedf: Send the driver state to MFW + - scsi: qedi: Send driver state to MFW + - perf llvm-utils: Remove bashism from kernel include fetch script + - perf tools: Fix compilation errors on gcc8 + - perf script python: Fix dict reference counting + - nfit: fix unchecked dereference in acpi_nfit_ctl + - RDMA/mlx5: Fix memory leak in mlx5_ib_create_srq() error path + - ARM: 8780/1: ftrace: Only set kernel memory back to read-only after boot + - ARM: DRA7/OMAP5: Enable ACTLR[0] (Enable invalidates of BTB) for secondary + cores + - ARM: dts: am3517.dtsi: Disable reference to OMAP3 OTG controller + - ixgbe: Be more careful when modifying MAC filters + - tools: build: Use HOSTLDFLAGS with fixdep + - kbuild: suppress warnings from 'getconf LFS_*' + - packet: reset network header if packet shorter than ll reserved space + - qlogic: check kstrtoul() for errors + - tcp: remove DELAYED ACK events in DCTCP + - pinctrl: ingenic: Fix inverted direction for < JZ4770 + - pinctrl: nsp: off by ones in nsp_pinmux_enable() + - pinctrl: nsp: Fix potential NULL dereference + - drm/nouveau/gem: off by one bugs in nouveau_gem_pushbuf_reloc_apply() + - net/ethernet/freescale/fman: fix cross-build error + - ibmvnic: Fix error recovery on login failure + - btrfs: scrub: Don't use inode page cache in scrub_handle_errored_block() + - octeon_mgmt: Fix MIX registers configuration on MTU setup + - net: usb: rtl8150: demote allmulti message to dev_dbg() + - PCI: OF: Fix I/O space page leak + - PCI: versatile: Fix I/O space page leak + - net: qca_spi: Avoid packet drop during initial sync + - net: qca_spi: Make sure the QCA7000 reset is triggered + - net: qca_spi: Fix log level if probe fails + - tcp: identify cryptic messages as TCP seq # bugs + - soc: imx: gpc: restrict register range for regmap access + - ACPI / EC: Use ec_no_wakeup on more Thinkpad X1 Carbon 6th systems + - ARM: dts: imx6: RDU2: fix irq type for mv88e6xxx switch + - nvme: fix handling of metadata_len for NVME_IOCTL_IO_CMD + - parisc: Remove ordered stores from syscall.S + - xfrm_user: prevent leaking 2 bytes of kernel memory + - netfilter: conntrack: dccp: treat SYNC/SYNCACK as invalid if no prior state + - packet: refine ring v3 block size test to hold one frame + - net/smc: no shutdown in state SMC_LISTEN + - parisc: Remove unnecessary barriers from spinlock.h + - PCI: hotplug: Don't leak pci_slot on registration failure + - PCI: Skip MPS logic for Virtual Functions (VFs) + - PCI: pciehp: Fix use-after-free on unplug + - PCI: pciehp: Fix unprotected list iteration in IRQ handler + - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes + - i2c: imx: Fix race condition in dma read + - reiserfs: fix broken xattr handling (heap corruption, bad retval) + - updateconfigs for v4.14.67 + - IB/rxe: avoid double kfree skb + - RDMA/qedr: Fix NULL pointer dereference when running over iWARP without + RDMA-CM + - smb3: increase initial number of credits requested to allow write + - hwmon: (dell-smm) Disable fan support for Dell XPS13 9333 + - ARM: dts: HR2: Fix interrupt types for i2c and PCIe + - drm/arm/malidp: Ensure that the crtcs are shutdown before removing any + encoder/connector + - drm/mali-dp: Rectify the width and height passed to rotmem_required() + - dmaengine: ti: omap-dma: Fix OMAP1510 incorrect residue_granularity + - nvme-rdma: fix possible double free condition when failing to create a + controller + - nvme-rdma: Fix command completion race at error recovery + - nvme-pci: move nvme_kill_queues to nvme_remove_dead_ctrl + - clk: sunxi-ng: replace lib-y with obj-y + - batman-adv: Fix debugfs path for renamed hardif + - batman-adv: Fix debugfs path for renamed softif + - nfp: bpf: don't stop offload if replace failed + - perf tests: Add event parsing error handling to parse events test + - perf script: Fix crash because of missing evsel->priv + - perf tools: Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE] + - s390/qeth: consistently re-enable device features + - sched/fair: Fix bandwidth timer clock drift condition + - r8169: fix mac address change + - RISC-V: Don't include irq-riscv-intc.h + - RISC-V: Fix PTRACE_SETREGSET bug. + - net: qrtr: Reset the node and port ID of broadcast messages + - cxgb4: assume flash part size to be 4MB, if it can't be determined + - bpf: fix sk_skb programs without skb->dev assigned + - ipfrag: really prevent allocation on netns exit + - gpu: host1x: Skip IOMMU initialization if firewall is enabled + - ARC: [plat-hsdk]: Configure APB GPIO controller on ARC HSDK platform + - bnxt_en: Do not modify max IRQ count after RDMA driver requests/frees IRQs. + - scsi: hpsa: correct enclosure sas address + - perf tools: Use python-config --includes rather than --cflags + - sfp: ensure we clean up properly on bus registration failure + - amd/dc/dce100: On dce100, set clocks to 0 on suspend + - tools: build: Fixup host c flags + - kvm: nVMX: Restore exit qual for VM-entry failure due to MSR loading + - ibmvnic: Revise RX/TX queue error messages + - net/smc: reset recv timeout after clc handshake + - PCI: xgene: Fix I/O space page leak + - PCI: designware: Fix I/O space page leak + - PCI: aardvark: Fix I/O space page leak + - PCI: faraday: Fix I/O space page leak + - PCI: mediatek: Fix I/O space page leak + - PCI: v3-semi: Fix I/O space page leak + - platform/x86: dell-laptop: Fix backlight detection + - mm: use helper functions for allocating and freeing vm_area structs + - mm: make vm_area_dup() actually copy the old vma data + - mm: make vm_area_alloc() initialize core fields + - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM + + -- Kleber Sacilotto de Souza Thu, 25 Jul 2019 14:26:11 +0200 + +linux-oracle (4.15.0-1018.20) bionic; urgency=medium + + * linux-oracle: 4.15.0-1018.20 -proposed tracker (LP: #1834943) + + [ Ubuntu: 4.15.0-55.60 ] + + * linux: 4.15.0-55.60 -proposed tracker (LP: #1834954) + * Request backport of ceph commits into bionic (LP: #1834235) + - ceph: use atomic_t for ceph_inode_info::i_shared_gen + - ceph: define argument structure for handle_cap_grant + - ceph: flush pending works before shutdown super + - ceph: send cap releases more aggressively + - ceph: single workqueue for inode related works + - ceph: avoid dereferencing invalid pointer during cached readdir + - ceph: quota: add initial infrastructure to support cephfs quotas + - ceph: quota: support for ceph.quota.max_files + - ceph: quota: don't allow cross-quota renames + - ceph: fix root quota realm check + - ceph: quota: support for ceph.quota.max_bytes + - ceph: quota: update MDS when max_bytes is approaching + - ceph: quota: add counter for snaprealms with quota + - ceph: avoid iput_final() while holding mutex or in dispatch thread + * QCA9377 isn't being recognized sometimes (LP: #1757218) + - SAUCE: USB: Disable USB2 LPM at shutdown + * hns: fix ICMP6 neighbor solicitation messages discard problem (LP: #1833140) + - net: hns: fix ICMP6 neighbor solicitation messages discard problem + - net: hns: fix unsigned comparison to less than zero + * Fix occasional boot time crash in hns driver (LP: #1833138) + - net: hns: Fix probabilistic memory overwrite when HNS driver initialized + * use-after-free in hns_nic_net_xmit_hw (LP: #1833136) + - net: hns: fix KASAN: use-after-free in hns_nic_net_xmit_hw() + * hns: attempt to restart autoneg when disabled should report error + (LP: #1833147) + - net: hns: Restart autoneg need return failed when autoneg off + * systemd 237-3ubuntu10.14 ADT test failure on Bionic ppc64el (test-seccomp) + (LP: #1821625) + - powerpc: sys_pkey_alloc() and sys_pkey_free() system calls + - powerpc: sys_pkey_mprotect() system call + * [UBUNTU] pkey: Indicate old mkvp only if old and curr. mkvp are different + (LP: #1832625) + - pkey: Indicate old mkvp only if old and current mkvp are different + * [UBUNTU] kernel: Fix gcm-aes-s390 wrong scatter-gather list processing + (LP: #1832623) + - s390/crypto: fix gcm-aes-s390 selftest failures + * System crashes on hot adding a core with drmgr command (4.15.0-48-generic) + (LP: #1833716) + - powerpc/numa: improve control of topology updates + - powerpc/numa: document topology_updates_enabled, disable by default + * Kernel modules generated incorrectly when system is localized to a non- + English language (LP: #1828084) + - scripts: override locale from environment when running recordmcount.pl + * [UBUNTU] kernel: Fix wrong dispatching for control domain CPRBs + (LP: #1832624) + - s390/zcrypt: Fix wrong dispatching for control domain CPRBs + * CVE-2019-11815 + - net: rds: force to destroy connection if t_sock is NULL in + rds_tcp_kill_sock(). + * Sound device not detected after resume from hibernate (LP: #1826868) + - drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled + - drm/i915: Save the old CDCLK atomic state + - drm/i915: Remove redundant store of logical CDCLK state + - drm/i915: Skip modeset for cdclk changes if possible + * Handle overflow in proc_get_long of sysctl (LP: #1833935) + - sysctl: handle overflow in proc_get_long + * Dell XPS 13 (9370) defaults to s2idle sleep/suspend instead of deep, NVMe + drains lots of power under s2idle (LP: #1808957) + - Revert "UBUNTU: SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 + and being disabled" + - Revert "UBUNTU: SAUCE: nvme: add quirk to not call disable function when + suspending" + - Revert "UBUNTU: SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3" + - Revert "SAUCE: nvme: add quirk to not call disable function when suspending" + - Revert "SAUCE: pci: prevent sk hynix nvme from entering D3" + - PCI: PM: Avoid possible suspend-to-idle issue + - PCI: PM: Skip devices in D0 for suspend-to-idle + - nvme-pci: Sync queues on reset + - nvme: Export get and set features + - nvme-pci: Use host managed power state for suspend + * linux v4.15 ftbfs on a newer host kernel (e.g. hwe) (LP: #1823429) + - selinux: use kernel linux/socket.h for genheaders and mdp + * 32-bit x86 kernel 4.15.0-50 crash in vmalloc_sync_all (LP: #1830433) + - x86/mm/pat: Disable preemption around __flush_tlb_all() + - x86/mm: Drop usage of __flush_tlb_all() in kernel_physical_mapping_init() + - x86/mm: Disable ioremap free page handling on x86-PAE + - ioremap: Update pgtable free interfaces with addr + - x86/mm: Add TLB purge to free pmd/pte page interfaces + - x86/init: fix build with CONFIG_SWAP=n + - x86/mm: provide pmdp_establish() helper + - x86/mm: Use WRITE_ONCE() when setting PTEs + * hinic: fix oops due to race in set_rx_mode (LP: #1832048) + - hinic: fix a bug in set rx mode + * ubuntu 18.04 flickering screen with Radeon X1600 (LP: #1791312) + - drm/radeon: prefer lower reference dividers + * Login screen never appears on vmwgfx using bionic kernel 4.15 (LP: #1832138) + - drm/vmwgfx: use monotonic event timestamps + * [linux-azure] Block Layer Commits Requested in Azure Kernels (LP: #1834499) + - block: Clear kernel memory before copying to user + - block/bio: Do not zero user pages + * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864) + - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches + * Handle overflow for file-max (LP: #1834310) + - sysctl: handle overflow for file-max + - kernel/sysctl.c: fix out-of-bounds access when setting file-max + * [ALSA] [PATCH] Headset fixup for System76 Gazelle (gaze14) (LP: #1827555) + - ALSA: hda/realtek - Headset fixup for System76 Gazelle (gaze14) + - ALSA: hda/realtek - Corrected fixup for System76 Gazelle (gaze14) + * crashdump fails on HiSilicon D06 (LP: #1828868) + - iommu/arm-smmu-v3: Abort all transactions if SMMU is enabled in kdump kernel + - iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel + * CVE-2019-11833 + - ext4: zero out the unused memory region in the extent tree block + * zfs 0.7.9 fixes a bug (https://github.com/zfsonlinux/zfs/pull/7343) that + hangs the system completely (LP: #1772412) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.6 + * does not detect headphone when there is no other output devices + (LP: #1831065) + - ALSA: hda/realtek - Fixed hp_pin no value + - ALSA: hda/realtek - Use a common helper for hp pin reference + * kernel crash : net_sched race condition in tcindex_destroy() (LP: #1825942) + - net_sched: fix NULL pointer dereference when delete tcindex filter + - RCU, workqueue: Implement rcu_work + - net_sched: switch to rcu_work + - net_sched: fix a race condition in tcindex_destroy() + - net_sched: fix a memory leak in cls_tcindex + - net_sched: initialize net pointer inside tcf_exts_init() + - net_sched: fix two more memory leaks in cls_tcindex + * Support new ums-realtek device (LP: #1831840) + - USB: usb-storage: Add new ID to ums-realtek + * amd_iommu possible data corruption (LP: #1823037) + - iommu/amd: Reserve exclusion range in iova-domain + - iommu/amd: Set exclusion range correctly + * Add new sound card PCIID into the alsa driver (LP: #1832299) + - ALSA: hda: Add Icelake PCI ID + - ALSA: hda/intel: add CometLake PCI IDs + * sky2 ethernet card doesn't work after returning from suspend + (LP: #1807259) // sky2 ethernet card link not up after suspend + (LP: #1809843) + - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79 + * idle-page oopses when accessing page frames that are out of range + (LP: #1833410) + - mm/page_idle.c: fix oops because end_pfn is larger than max_pfn + * Add pointstick support on HP ZBook 17 G5 (LP: #1833387) + - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A" + - SAUCE: HID: multitouch: Add pointstick support for ALPS Touchpad + * [SRU][B/B-OEM/B-OEM-OSP-1/C/D/E] Add trackpoint middle button support of 2 + new thinpads (LP: #1833637) + - Input: elantech - enable middle button support on 2 ThinkPads + * CVE-2019-11085 + - drm/i915/gvt: Fix mmap range check + - drm/i915: make mappable struct resource centric + - drm/i915/gvt: Fix aperture read/write emulation when enable x-no-mmap=on + * CVE-2019-11884 + - Bluetooth: hidp: fix buffer overflow + * af_alg06 test from crypto test suite in LTP failed with kernel oops on B/C + (LP: #1829725) + - crypto: authenc - fix parsing key with misaligned rta_len + * CVE-2018-12126 // CVE-2018-12127 // CVE-2018-12130 // CVE-2019-11091 + - SAUCE: Synchronize MDS mitigations with upstream + - Documentation: Correct the possible MDS sysfs values + - x86/speculation/mds: Fix documentation typo + * CVE-2019-11091 + - x86/mds: Add MDSUM variant to the MDS documentation + * alignment test in powerpc from ubuntu_kernel_selftests failed on B/C Power9 + (LP: #1813118) + - selftests/powerpc: Remove Power9 copy_unaligned test + * TRACE_syscall.ptrace_syscall_dropped in seccomp from ubuntu_kernel_selftests + failed on B/C PowerPC (LP: #1812796) + - selftests/seccomp: Enhance per-arch ptrace syscall skip tests + * Add powerpc/alignment_handler test for selftests (LP: #1828935) + - selftests/powerpc: Add alignment handler selftest + - selftests/powerpc: Fix to use ucontext_t instead of struct ucontext + * Cannot build kernel 4.15.0-48.51 due to an in-source-tree ZFS module. + (LP: #1828763) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.5 + * Eletrical noise occurred when external headset enter powersaving mode on a + DEll machine (LP: #1828798) + - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone + - ALSA: hda/realtek - Fixup headphone noise via runtime suspend + * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on + Ubuntu (LP: #1761379) + - [Packaging] Support building libperf-jvmti.so + * TCP : race condition on socket ownership in tcp_close() (LP: #1830813) + - tcp: do not release socket ownership in tcp_close() + * bionic: netlink: potential shift overflow in netlink_bind() (LP: #1831103) + - netlink: Don't shift on 64 for ngroups + * Add support to Comet Lake LPSS (LP: #1830175) + - mfd: intel-lpss: Add Intel Comet Lake PCI IDs + * Reduce NAPI weight in hns driver from 256 to 64 (LP: #1830587) + - net: hns: Use NAPI_POLL_WEIGHT for hns driver + * x86: add support for AMD Rome (LP: #1819485) + - x86: irq_remapping: Move irq remapping mode enum + - iommu/amd: Add support for higher 64-bit IOMMU Control Register + - iommu/amd: Add support for IOMMU XT mode + - hwmon/k10temp, x86/amd_nb: Consolidate shared device IDs + - hwmon/k10temp: Add support for AMD family 17h, model 30h CPUs + - x86/amd_nb: Add PCI device IDs for family 17h, model 30h + - x86/MCE/AMD: Fix the thresholding machinery initialization order + - x86/amd_nb: Add support for newer PCI topologies + * nx842 - CRB request time out (-110) when uninstall NX modules and initiate + NX request (LP: #1827755) + - crypto/nx: Initialize 842 high and normal RxFIFO control registers + * Require improved hypervisor detection patch in Ubuntu 18.04 (LP: #1829972) + - s390/early: improve machine detection + + -- Khalid Elmously Wed, 03 Jul 2019 02:12:27 -0400 + +linux-oracle (4.15.0-1017.19) bionic; urgency=medium + + * linux-oracle: 4.15.0-1017.19 -proposed tracker (LP: #1833979) + + [ Ubuntu: 4.15.0-54.58 ] + + * linux: 4.15.0-54.58 -proposed tracker (LP: #1833987) + * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard + manipulation (LP: #1831638) // CVE-2019-11478 + - tcp: refine memory limit test in tcp_fragment() + * CVE-2019-11479 + - SAUCE: tcp: add tcp_min_snd_mss sysctl + - SAUCE: tcp: enforce tcp_min_snd_mss in tcp_mtu_probing() + + -- Kleber Sacilotto de Souza Mon, 24 Jun 2019 17:48:50 +0200 + +linux-oracle (4.15.0-1015.17) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-52.56 ] + + * Remote denial of service (resource exhaustion) caused by TCP SACK scoreboard + manipulation (LP: #1831638) + - SAUCE: tcp: tcp_fragment() should apply sane memory limits + * Remote denial of service (system crash) caused by integer overflow in TCP + SACK handling (LP: #1831637) + - SAUCE: tcp: limit payload size of sacked skbs + + -- Marcelo Henrique Cerri Wed, 05 Jun 2019 14:48:40 -0300 + +linux-oracle (4.15.0-1014.16) bionic; urgency=medium + + * linux-oracle: 4.15.0-1014.16 -proposed tracker (LP: #1829210) + + [ Ubuntu: 4.15.0-51.55 ] + + * linux: 4.15.0-51.55 -proposed tracker (LP: #1829219) + * disable a.out support (LP: #1818552) + - [Config] Disable a.out support + * [UBUNTU] qdio: clear intparm during shutdown (LP: #1828394) + - s390/qdio: clear intparm during shutdown + * ftrace in ubuntu_kernel_selftests hang with Cosmic kernel (LP: #1826385) + - kprobes/x86: Fix instruction patching corruption when copying more than one + RIP-relative instruction + * touchpad not working on lenovo yoga 530 (LP: #1787775) + - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI" + - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base" + - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for + upcoming platform" + - i2c: add helpers to ease DMA handling + - i2c: add a message flag for DMA safe buffers + - i2c: add extra check to safe DMA buffer helper + - i2c: Add drivers for the AMD PCIe MP2 I2C controller + - [Config] Update config for AMD MP2 I2C driver + - [Config] Update I2C_AMD_MP2 annotations + * tm-unavailable in powerpc/tm failed on Bionic Power9 (LP: #1813129) + - selftests/powerpc: Check for pthread errors in tm-unavailable + - selftests/powerpc: Skip tm-unavailable if TM is not enabled + * cp_abort in powerpc/context_switch from ubunut_kernel_selftests failed on + Bionic P9 (LP: #1813134) + - selftests/powerpc: Remove redundant cp_abort test + * bionic/linux: completely remove snapdragon files from sources (LP: #1827880) + - [Packaging] remove snapdragon dead files + - [Config] update configs after snapdragon removal + * The noise keeps occurring when Headset is plugged in on a Dell machine + (LP: #1827972) + - ALSA: hda/realtek - Fixed Dell AIO speaker noise + * Geneve tunnels don't work when ipv6 is disabled (LP: #1794232) + - geneve: correctly handle ipv6.disable module parameter + * There are 4 HDMI/Displayport audio output listed in sound setting without + attach any HDMI/DP monitor (LP: #1827967) + - ALSA: hda/hdmi - Read the pin sense from register when repolling + - ALSA: hda/hdmi - Consider eld_valid when reporting jack event + * Headphone jack switch sense is inverted: plugging in headphones disables + headphone output (LP: #1824259) + - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board + * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error + Checking for all LINUX clients for devops4p10 (LP: #1766201) + - SAUCE: integrity: downgrade error to warning + * Screen freeze after resume from S3 when HDMI monitor plugged on Dell + Precision 7740 (LP: #1825958) + - PCI: Restore resized BAR state on resume + * potential memory corruption on arm64 on dev release (LP: #1827437) + - driver core: Postpone DMA tear-down until after devres release + * powerpc/pmu/ebb test in ubuntu_kernel_selftest failed with "error while + loading shared libraries" on Bionic/Cosmic PowerPC (LP: #1812805) + - selftests/powerpc/pmu: Link ebb tests with -no-pie + * unnecessary request_queue freeze (LP: #1815733) + - block: avoid setting nr_requests to current value + - block: avoid setting none scheduler if it's already none + * Kprobe event string type argument failed in ftrace from + ubuntu_kernel_selftests on B/C i386 (LP: #1825780) + - selftests/ftrace: Fix kprobe string testcase to not probe notrace function + * hns: fix socket accounting (LP: #1826911) + - net: hns: fix skb->truesize underestimation + * False positive test result in run_netsocktests from net in + ubuntu_kernel_selftest (LP: #1825777) + - selftests/net: correct the return value for run_netsocktests + + -- Kleber Sacilotto de Souza Mon, 20 May 2019 15:37:04 +0200 + +linux-oracle (4.15.0-1013.15) bionic; urgency=medium + + + [ Ubuntu: 4.15.0-50.54 ] + + * CVE-2018-12126 // CVE-2018-12127 // CVE-2018-12130 + - Documentation/l1tf: Fix small spelling typo + - x86/cpu: Sanitize FAM6_ATOM naming + - kvm: x86: Report STIBP on GET_SUPPORTED_CPUID + - locking/atomics, asm-generic: Move some macros from to a + new file + - tools include: Adopt linux/bits.h + - x86/msr-index: Cleanup bit defines + - x86/speculation: Consolidate CPU whitelists + - x86/speculation/mds: Add basic bug infrastructure for MDS + - x86/speculation/mds: Add BUG_MSBDS_ONLY + - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests + - x86/speculation/mds: Add mds_clear_cpu_buffers() + - x86/speculation/mds: Clear CPU buffers on exit to user + - x86/kvm/vmx: Add MDS protection when L1D Flush is not active + - x86/speculation/mds: Conditionally clear CPU buffers on idle entry + - x86/speculation/mds: Add mitigation control for MDS + - x86/speculation/mds: Add sysfs reporting for MDS + - x86/speculation/mds: Add mitigation mode VMWERV + - Documentation: Move L1TF to separate directory + - Documentation: Add MDS vulnerability documentation + - x86/speculation/mds: Add mds=full,nosmt cmdline option + - x86/speculation: Move arch_smt_update() call to after mitigation decisions + - x86/speculation/mds: Add SMT warning message + - x86/speculation/mds: Fix comment + - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off + - x86/speculation/mds: Add 'mitigations=' support for MDS + * CVE-2017-5715 // CVE-2017-5753 + - s390/speculation: Support 'mitigations=' cmdline option + * CVE-2017-5715 // CVE-2017-5753 // CVE-2017-5754 // CVE-2018-3639 + - powerpc/speculation: Support 'mitigations=' cmdline option + * CVE-2017-5715 // CVE-2017-5754 // CVE-2018-3620 // CVE-2018-3639 // + CVE-2018-3646 + - cpu/speculation: Add 'mitigations=' cmdline option + - x86/speculation: Support 'mitigations=' cmdline option + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + -- Stefan Bader Wed, 08 May 2019 16:17:05 +0200 + +linux-oracle (4.15.0-1012.14) bionic; urgency=medium + + * linux-oracle: 4.15.0-1012.14 -proposed tracker (LP: #1826348) + + * linux-oracle: Use upstream approach to fix a race when hot adding a VF + (LP: #1825229) + - Revert "UBUNTU: SAUCE: net_failover: delay taking over primary device to + accommodate udevd renaming" + - ipvlan, l3mdev: fix broken l3s mode wrt local routes + - SAUCE: failover: allow name change on IFF_UP slave interfaces + + [ Ubuntu: 4.15.0-49.53 ] + + * linux: 4.15.0-49.53 -proposed tracker (LP: #1826358) + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) + - powerpc/64s: Add support for ori barrier_nospec patching + - powerpc/64s: Patch barrier_nospec in modules + - powerpc/64s: Enable barrier_nospec based on firmware settings + - powerpc: Use barrier_nospec in copy_from_user() + - powerpc/64: Use barrier_nospec in syscall entry + - powerpc/64s: Enhance the information in cpu_show_spectre_v1() + - powerpc/64: Disable the speculation barrier from the command line + - powerpc/64: Make stf barrier PPC_BOOK3S_64 specific. + - powerpc/64: Add CONFIG_PPC_BARRIER_NOSPEC + - powerpc/64: Call setup_barrier_nospec() from setup_arch() + - powerpc/64: Make meltdown reporting Book3S 64 specific + - powerpc/lib/code-patching: refactor patch_instruction() + - powerpc/lib/feature-fixups: use raw_patch_instruction() + - powerpc/asm: Add a patch_site macro & helpers for patching instructions + - powerpc/64s: Add new security feature flags for count cache flush + - powerpc/64s: Add support for software count cache flush + - powerpc/pseries: Query hypervisor for count cache flush settings + - powerpc/powernv: Query firmware for count cache flush settings + - powerpc/fsl: Add nospectre_v2 command line argument + - KVM: PPC: Book3S: Add count cache flush parameters to kvmppc_get_cpu_char() + - [Config] Add CONFIG_PPC_BARRIER_NOSPEC + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + * autopkgtests run too often, too much and don't skip enough (LP: #1823056) + - [Debian] Set +x on rebuild testcase. + - [Debian] Skip rebuild test, for regression-suite deps. + - [Debian] Make ubuntu-regression-suite skippable on unbootable kernels. + - [Debian] make rebuild use skippable error codes when skipping. + - [Debian] Only run regression-suite, if requested to. + * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868) + - [Packaging] remove arm64 snapdragon from getabis + - [Config] config changes for snapdragon split + - packaging: arm64: disable building the snapdragon flavour + - [Packaging] arm64: Drop snapdragon from kernel-versions + * CVE-2017-5753 + - KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_get_irq() + - media: dvb_ca_en50221: prevent using slot_info for Spectre attacs + - sysvipc/sem: mitigate semnum index against spectre v1 + - libahci: Fix possible Spectre-v1 pmp indexing in ahci_led_store() + - s390/keyboard: sanitize array index in do_kdsk_ioctl + - arm64: fix possible spectre-v1 write in ptrace_hbp_set_event() + - KVM: arm/arm64: vgic: Fix possible spectre-v1 write in vgic_mmio_write_apr() + - pktcdvd: Fix possible Spectre-v1 for pkt_devs + - net: socket: fix potential spectre v1 gadget in socketcall + - net: socket: Fix potential spectre v1 gadget in sock_is_registered + - drm/amdgpu/pm: Fix potential Spectre v1 + - netlink: Fix spectre v1 gadget in netlink_create() + - ext4: fix spectre gadget in ext4_mb_regular_allocator() + - drm/i915/kvmgt: Fix potential Spectre v1 + - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd() + - fs/quota: Fix spectre gadget in do_quotactl + - hwmon: (nct6775) Fix potential Spectre v1 + - mac80211_hwsim: Fix possible Spectre-v1 for hwsim_world_regdom_custom + - switchtec: Fix Spectre v1 vulnerability + - misc: hmc6352: fix potential Spectre v1 + - tty: vt_ioctl: fix potential Spectre v1 + - nl80211: Fix possible Spectre-v1 for NL80211_TXRATE_HT + - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds + - IB/ucm: Fix Spectre v1 vulnerability + - RDMA/ucma: Fix Spectre v1 vulnerability + - drm/bufs: Fix Spectre v1 vulnerability + - usb: gadget: storage: Fix Spectre v1 vulnerability + - ptp: fix Spectre v1 vulnerability + - HID: hiddev: fix potential Spectre v1 + - vhost: Fix Spectre V1 vulnerability + - drivers/misc/sgi-gru: fix Spectre v1 vulnerability + - ipv4: Fix potential Spectre v1 vulnerability + - aio: fix spectre gadget in lookup_ioctx + - ALSA: emux: Fix potential Spectre v1 vulnerabilities + - ALSA: pcm: Fix potential Spectre v1 vulnerability + - ip6mr: Fix potential Spectre v1 vulnerability + - ALSA: rme9652: Fix potential Spectre v1 vulnerability + - ALSA: emu10k1: Fix potential Spectre v1 vulnerabilities + - KVM: arm/arm64: vgic: Fix off-by-one bug in vgic_get_irq() + - drm/ioctl: Fix Spectre v1 vulnerabilities + - char/mwave: fix potential Spectre v1 vulnerability + - applicom: Fix potential Spectre v1 vulnerabilities + - ipmi: msghandler: Fix potential Spectre v1 vulnerabilities + - powerpc/ptrace: Mitigate potential Spectre v1 + - cfg80211: prevent speculation on cfg80211_classify8021d() return + - ALSA: rawmidi: Fix potential Spectre v1 vulnerability + - ALSA: seq: oss: Fix Spectre v1 vulnerability + * Bionic: Sync to Xenial (Spectre) (LP: #1822760) + - x86/speculation/l1tf: Suggest what to do on systems with too much RAM + - KVM: SVM: Add MSR-based feature support for serializing LFENCE + - KVM: VMX: fixes for vmentry_l1d_flush module parameter + - KVM: X86: Allow userspace to define the microcode version + - SAUCE: [Fix] x86/KVM/VMX: Add L1D flush logic + - SAUCE: [Fix] x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on + vmentry + * [SRU] [B/OEM] Fix ACPI bug that causes boot failure (LP: #1819921) + - SAUCE: ACPI / bus: Add some Lenovo laptops in list of acpi table term list + * Bionic update: upstream stable patchset for fuse 2019-04-12 (LP: #1824553) + - fuse: fix double request_end() + - fuse: fix unlocked access to processing queue + - fuse: umount should wait for all requests + - fuse: Fix oops at process_init_reply() + - fuse: Don't access pipe->buffers without pipe_lock() + - fuse: Fix use-after-free in fuse_dev_do_read() + - fuse: Fix use-after-free in fuse_dev_do_write() + - fuse: set FR_SENT while locked + - fuse: fix blocked_waitq wakeup + - fuse: fix leaked notify reply + - fuse: fix possibly missed wake-up after abort + - fuse: fix use-after-free in fuse_direct_IO() + - fuse: continue to send FUSE_RELEASEDIR when FUSE_OPEN returns ENOSYS + - fuse: handle zero sized retrieve correctly + - fuse: call pipe_buf_release() under pipe lock + - fuse: decrement NR_WRITEBACK_TEMP on the right page + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // Backport support for software + count cache flush Spectre v2 mitigation. (CVE) (required for POWER9 DD2.3) + (LP: #1822870) + - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2 + - powerpc/fsl: Fix spectre_v2 mitigations reporting + - powerpc: Avoid code patching freed init sections + * Backport support for software count cache flush Spectre v2 mitigation. (CVE) + (required for POWER9 DD2.3) (LP: #1822870) // Backport support for software + count cache flush Spectre v2 mitigation. (CVE) (required for POWER9 DD2.3) + (LP: #1822870) // Backport support for software count cache flush Spectre v2 + mitigation. (CVE) (required for POWER9 DD2.3) (LP: #1822870) + - powerpc/security: Fix spectre_v2 reporting + * CVE-2019-3874 + - sctp: use sk_wmem_queued to check for writable space + - sctp: implement memory accounting on tx path + - sctp: implement memory accounting on rx path + * NULL pointer dereference when using z3fold and zswap (LP: #1814874) + - z3fold: fix possible reclaim races + * Kprobe event argument syntax in ftrace from ubuntu_kernel_selftests failed + on B PowerPC (LP: #1812809) + - selftests/ftrace: Add ppc support for kprobe args tests + * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487) + - misc: rtsx: make various functions static + - misc: rtsx: Enable OCP for rts522a rts524a rts525a rts5260 + - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch + * headset-mic doesn't work on two Dell laptops. (LP: #1825272) + - ALSA: hda/realtek - add two more pin configuration sets to quirk table + * CVE-2018-16884 + - sunrpc: use SVC_NET() in svcauth_gss_* functions + - sunrpc: use-after-free in svc_process_common() + * sky2 ethernet card don't work after returning from suspension (LP: #1798921) + - sky2: Increase D3 delay again + * CVE-2019-9500 + - brcmfmac: assure SSID length from firmware is limited + * CVE-2019-9503 + - brcmfmac: add subtype check for event handling in data path + * CVE-2019-3882 + - vfio/type1: Limit DMA mappings per container + * Intel I210 Ethernet card not working after hotplug [8086:1533] + (LP: #1818490) + - igb: Fix WARN_ONCE on runtime suspend + * bionic, xenial/hwe: misses "fuse: fix initial parallel dirops" patch + (LP: #1823972) + - fuse: fix initial parallel dirops + * amdgpu resume failure: failed to allocate wb slot (LP: #1825074) + - drm/amdgpu: fix&cleanups for wb_clear + * Pop noise when headset is plugged in or removed from GHS/Line-out jack + (LP: #1821290) + - ALSA: hda/realtek - Add unplug function into unplug state of Headset Mode + for ALC225 + - ALSA: hda/realtek - Disable headset Mic VREF for headset mode of ALC225 + - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO + - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB + * mac80211_hwsim unable to handle kernel NULL pointer dereference + at0000000000000000 (LP: #1825058) + - mac80211_hwsim: Timer should be initialized before device registered + * [regression][snd_hda_codec_realtek] repeating crackling noise after 19.04 + upgrade (LP: #1821663) + - ALSA: hda: Add Intel NUC7i3BNB to the power_save blacklist + - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist + - ALSA: hda - Add two more machines to the power_save_blacklist + * ubuntu_nbd_smoke_test failed on P9 with Bionic kernel (LP: #1822247) + - nbd: fix how we set bd_invalidated + * TSC clocksource not available in nested guests (LP: #1822821) + - kvmclock: fix TSC calibration for nested guests + * 4.15 kernel ip_vs --ops causes performance and hang problem (LP: #1819786) + - ipvs: fix refcount usage for conns in ops mode + * systemd cause kernel trace "BUG: unable to handle kernel paging request at + 6db23a14" on Cosmic i386 (LP: #1813244) // systemd cause kernel trace "BUG: + unable to handle kernel paging request at 6db23a14" on Cosmic i386 + (LP: #1813244) + - openvswitch: fix flow actions reallocation + + -- Khalid Elmously Fri, 26 Apr 2019 02:39:11 -0400 + +linux-oracle (4.15.0-1011.13) bionic; urgency=medium + + * linux-oracle: 4.15.0-1011.13 -proposed tracker (LP: #1822812) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + + [ Ubuntu: 4.15.0-48.51 ] + + * linux: 4.15.0-48.51 -proposed tracker (LP: #1822820) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + - [Packaging] resync retpoline extraction + * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes + triggers system hang on i386 (LP: #1812845) + - btrfs: raid56: properly unmap parity page in finish_parity_scrub() + * [P9][LTCTest][Opal][FW910] cpupower monitor shows multiple stop Idle_Stats + (LP: #1719545) + - cpupower : Fix header name to read idle state name + * [amdgpu] screen corruption when using touchpad (LP: #1818617) + - drm/amdgpu/gmc: steal the appropriate amount of vram for fw hand-over (v3) + - drm/amdgpu: Free VGA stolen memory as soon as possible. + * [SRU][B/C/OEM]IOMMU: add kernel dma protection (LP: #1820153) + - ACPICA: AML parser: attempt to continue loading table after error + - ACPI / property: Allow multiple property compatible _DSD entries + - PCI / ACPI: Identify untrusted PCI devices + - iommu/vt-d: Force IOMMU on for platform opt in hint + - iommu/vt-d: Do not enable ATS for untrusted devices + - thunderbolt: Export IOMMU based DMA protection support to userspace + - iommu/vt-d: Disable ATS support on untrusted devices + * Add basic support to NVLink2 passthrough (LP: #1819989) + - powerpc/powernv/npu: Do not try invalidating 32bit table when 64bit table is + enabled + - powerpc/powernv: call OPAL_QUIESCE before OPAL_SIGNAL_SYSTEM_RESET + - powerpc/powernv: Export opal_check_token symbol + - powerpc/powernv: Make possible for user to force a full ipl cec reboot + - powerpc/powernv/idoa: Remove unnecessary pcidev from pci_dn + - powerpc/powernv: Move npu struct from pnv_phb to pci_controller + - powerpc/powernv/npu: Move OPAL calls away from context manipulation + - powerpc/pseries/iommu: Use memory@ nodes in max RAM address calculation + - powerpc/pseries/npu: Enable platform support + - powerpc/pseries: Remove IOMMU API support for non-LPAR systems + - powerpc/powernv/npu: Check mmio_atsd array bounds when populating + - powerpc/powernv/npu: Fault user page into the hypervisor's pagetable + * Huawei Hi1822 NIC has poor performance (LP: #1820187) + - net-next: hinic: fix a problem in free_tx_poll() + - hinic: remove ndo_poll_controller + - net-next/hinic: add checksum offload and TSO support + - hinic: Fix l4_type parameter in hinic_task_set_tunnel_l4 + - net-next/hinic:replace multiply and division operators + - net-next/hinic:add rx checksum offload for HiNIC + - net-next/hinic:fix a bug in set mac address + - net-next/hinic: fix a bug in rx data flow + - net: hinic: fix null pointer dereference on pointer hwdev + - hinic: optmize rx refill buffer mechanism + - net-next/hinic:add shutdown callback + - net-next/hinic: replace disable_irq_nosync/enable_irq + * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881) + - Fonts: New Terminus large console font + - [Config]: enable highdpi Terminus 16x32 font support + * [19.04 FEAT] qeth: Enhanced link speed - kernel part (LP: #1814892) + - s390/qeth: report 25Gbit link speed + * CVE-2017-5754 + - x86/nmi: Fix NMI uaccess race against CR3 switching + - x86/mm: Fix documentation of module mapping range with 4-level paging + - x86/pti: Enable global pages for shared areas + - x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image + - x86/pti: Leave kernel text global for !PCID + - x86/pti: Fix boot problems from Global-bit setting + - x86/pti: Fix boot warning from Global-bit setting + - x86/pti: Reduce amount of kernel text allowed to be Global + - x86/pti: Disallow global kernel text with RANDSTRUCT + - x86/entry/32: Add explicit 'l' instruction suffix + - x86/asm-offsets: Move TSS_sp0 and TSS_sp1 to asm-offsets.c + - x86/entry/32: Rename TSS_sysenter_sp0 to TSS_entry2task_stack + - x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler + - x86/entry/32: Put ESPFIX code into a macro + - x86/entry/32: Unshare NMI return path + - x86/entry/32: Split off return-to-kernel path + - x86/entry/32: Enter the kernel via trampoline stack + - x86/entry/32: Leave the kernel via trampoline stack + - x86/entry/32: Introduce SAVE_ALL_NMI and RESTORE_ALL_NMI + - x86/entry/32: Handle Entry from Kernel-Mode on Entry-Stack + - x86/entry/32: Simplify debug entry point + - x86/entry/32: Add PTI cr3 switch to non-NMI entry/exit points + - x86/entry/32: Add PTI CR3 switches to NMI handler code + - x86/entry: Rename update_sp0 to update_task_stack + - x86/pgtable: Rename pti_set_user_pgd() to pti_set_user_pgtbl() + - x86/pgtable/pae: Unshare kernel PMDs when PTI is enabled + - x86/pgtable/32: Allocate 8k page-tables when PTI is enabled + - x86/pgtable: Move pgdp kernel/user conversion functions to pgtable.h + - x86/pgtable: Move pti_set_user_pgtbl() to pgtable.h + - x86/pgtable: Move two more functions from pgtable_64.h to pgtable.h + - x86/mm/pae: Populate valid user PGD entries + - x86/mm/pae: Populate the user page-table with user pgd's + - x86/mm/pti: Add an overflow check to pti_clone_pmds() + - x86/mm/pti: Define X86_CR3_PTI_PCID_USER_BIT on x86_32 + - x86/mm/pti: Clone CPU_ENTRY_AREA on PMD level on x86_32 + - x86/mm/pti: Make pti_clone_kernel_text() compile on 32 bit + - x86/mm/pti: Keep permissions when cloning kernel text in + pti_clone_kernel_text() + - x86/mm/pti: Introduce pti_finalize() + - x86/mm/pti: Clone entry-text again in pti_finalize() + - x86/mm/dump_pagetables: Define INIT_PGD + - x86/pgtable/pae: Use separate kernel PMDs for user page-table + - x86/ldt: Reserve address-space range on 32 bit for the LDT + - x86/ldt: Define LDT_END_ADDR + - x86/ldt: Split out sanity check in map_ldt_struct() + - x86/ldt: Enable LDT user-mapping for PAE + - x86/pti: Allow CONFIG_PAGE_TABLE_ISOLATION for x86_32 + - [Config] Update PAGE_TABLE_ISOLATION annotations + - x86/mm/pti: Add Warning when booting on a PCID capable CPU + - x86/entry/32: Add debug code to check entry/exit CR3 + - x86/pti: Check the return value of pti_user_pagetable_walk_p4d() + - x86/pti: Check the return value of pti_user_pagetable_walk_pmd() + - perf/core: Make sure the ring-buffer is mapped in all page-tables + - x86/entry/32: Check for VM86 mode in slow-path check + - x86/mm: Remove in_nmi() warning from vmalloc_fault() + - x86/kexec: Allocate 8k PGDs for PTI + - x86/mm/pti: Clear Global bit more aggressively + - mm: Allow non-direct-map arguments to free_reserved_area() + - x86/mm/init: Pass unconverted symbol addresses to free_init_pages() + - x86/mm/init: Add helper for freeing kernel image pages + - x86/mm/init: Remove freed kernel image areas from alias mapping + - x86/mm/pti: Fix 32 bit PCID check + - x86/mm/pti: Don't clear permissions in pti_clone_pmd() + - x86/mm/pti: Clone kernel-image on PTE level for 32 bit + - x86/relocs: Add __end_rodata_aligned to S_REL + - x86/mm/pti: Move user W+X check into pti_finalize() + - x86/efi: Load fixmap GDT in efi_call_phys_epilog() + - x86/efi: Load fixmap GDT in efi_call_phys_epilog() before setting %cr3 + - x86/mm/doc: Clean up the x86-64 virtual memory layout descriptions + - x86/mm/doc: Enhance the x86-64 virtual memory layout descriptions + - x86/entry/32: Clear the CS high bits + - x86/mm: Move LDT remap out of KASLR region on 5-level paging + - x86/ldt: Unmap PTEs for the slot before freeing LDT pages + - x86/ldt: Remove unused variable in map_ldt_struct() + - x86/mm: Fix guard hole handling + - x86/dump_pagetables: Fix LDT remap address marker + * Avoid potential memory corruption on HiSilicon SoCs (LP: #1819546) + - iommu/arm-smmu-v3: Avoid memory corruption from Hisilicon MSI payloads + * Ubuntu18.04.01: [Power9] power8 Compat guest(RHEL7.6) crashes during guest + boot with > 256G of memory (kernel/kvm) (LP: #1818645) + - ]PATCH] KVM: PPC: Book3S HV: Don't truncate HPTE index in xlate function + * Fix for dual Intel NVMes (LP: #1821961) + - SAUCE: nvme: Merge two quirk entries into one for Intel 760p/Pro 7600p + * CVE-2017-5715 + - tools headers: Synchronize prctl.h ABI header + - x86/spectre: Add missing family 6 check to microcode check + - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation + - x86/speculation: Apply IBPB more strictly to avoid cross-process data leak + - x86/speculation: Propagate information about RSB filling mitigation to sysfs + - x86/speculation: Add RETPOLINE_AMD support to the inline asm CALL_NOSPEC + variant + - x86/retpoline: Make CONFIG_RETPOLINE depend on compiler support + - x86/retpoline: Remove minimal retpoline support + - x86/speculation: Update the TIF_SSBD comment + - x86/speculation: Clean up spectre_v2_parse_cmdline() + - x86/speculation: Remove unnecessary ret variable in cpu_show_common() + - x86/speculation: Move STIPB/IBPB string conditionals out of + cpu_show_common() + - x86/speculation: Disable STIBP when enhanced IBRS is in use + - x86/speculation: Rename SSBD update functions + - x86/speculation: Reorganize speculation control MSRs update + - sched/smt: Make sched_smt_present track topology + - x86/Kconfig: Select SCHED_SMT if SMP enabled + - sched/smt: Expose sched_smt_present static key + - x86/speculation: Rework SMT state change + - x86/l1tf: Show actual SMT state + - x86/speculation: Reorder the spec_v2 code + - x86/speculation: Mark string arrays const correctly + - x86/speculataion: Mark command line parser data __initdata + - x86/speculation: Unify conditional spectre v2 print functions + - x86/speculation: Add command line control for indirect branch speculation + - x86/speculation: Prepare for per task indirect branch speculation control + - x86/process: Consolidate and simplify switch_to_xtra() code + - x86/speculation: Avoid __switch_to_xtra() calls + - x86/speculation: Prepare for conditional IBPB in switch_mm() + - ptrace: Remove unused ptrace_may_access_sched() and MODE_IBRS + - x86/speculation: Split out TIF update + - x86/speculation: Prevent stale SPEC_CTRL msr content + - x86/speculation: Prepare arch_smt_update() for PRCTL mode + - x86/speculation: Add prctl() control for indirect branch speculation + - x86/speculation: Enable prctl mode for spectre_v2_user + - x86/speculation: Add seccomp Spectre v2 user space protection mode + - x86/speculation: Provide IBPB always command line options + - kvm: svm: Ensure an IBPB on all affected CPUs when freeing a vmcb + - x86/speculation: Change misspelled STIPB to STIBP + - x86/speculation: Add support for STIBP always-on preferred mode + - x86, modpost: Replace last remnants of RETPOLINE with CONFIG_RETPOLINE + - s390: remove closung punctuation from spectre messages + - x86/speculation: Simplify the CPU bug detection logic + * CVE-2018-3639 + - x86/bugs: Add AMD's variant of SSB_NO + - x86/bugs: Add AMD's SPEC_CTRL MSR usage + - x86/bugs: Switch the selection of mitigation from CPU vendor to CPU features + - x86/bugs: Update when to check for the LS_CFG SSBD mitigation + - x86/bugs: Fix the AMD SSBD usage of the SPEC_CTRL MSR + - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled + * [Ubuntu] vfio-ap: add subsystem to matrix device to avoid libudev failures + (LP: #1818854) + - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem + * Kernel regularly logs: Bluetooth: hci0: last event is not cmd complete + (0x0f) (LP: #1748565) + - Bluetooth: Fix unnecessary error message for HCI request completion + * HiSilicon HNS ethernet broken in 4.15.0-45 (LP: #1818294) + - net: hns: Fix WARNING when hns modules installed + * rtl8723be wifi does not work under linux-modules-extra-4.15.0-33-generic + (LP: #1788997) + - SAUCE: Revert "rtlwifi: cleanup 8723be ant_sel definition" + * Crash from :i915 module with 4.15.0-46-generic using multi-display + (LP: #1819486) + - SAUCE: Revert "drm/i915: Fix hotplug irq ack on i965/g4x" + * kernel linux-image-4.15.0-44 not booting on Hyperv Server 2008R2 + (LP: #1814069) + - hv/netvsc: fix handling of fallback to single queue mode + - hv/netvsc: Fix NULL dereference at single queue mode fallback + * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815) + - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill + * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204) + - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list + * fscache: jobs might hang when fscache disk is full (LP: #1821395) + - fscache: fix race between enablement and dropping of object + * hns3: fix oops in hns3_clean_rx_ring() (LP: #1821064) + - net: hns3: add dma_rmb() for rx description + * Hard lockup in 2 CPUs due to deadlock in cpu_stoppers (LP: #1821259) + - stop_machine: Disable preemption after queueing stopper threads + - stop_machine: Atomically queue and wake stopper threads + * tcm_loop.ko: move from modules-extra into main modules package + (LP: #1817786) + - [Packaging] move tcm_loop.lo to main linux-modules package + * tcmu user space crash results in kernel module hang. (LP: #1819504) + - scsi: tcmu: delete unused __wait + - scsi: tcmu: track nl commands + - scsi: tcmu: simplify nl interface + - scsi: tcmu: add module wide block/reset_netlink support + * Intel XL710 - i40e driver does not work with kernel 4.15 (Ubuntu 18.04) + (LP: #1779756) + - i40e: Fix for Tx timeouts when interface is brought up if DCB is enabled + - i40e: prevent overlapping tx_timeout recover + * some codecs stop working after S3 (LP: #1820930) + - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec + * i40e xps management broken when > 64 queues/cpus (LP: #1820948) + - i40e: Do not allow use more TC queue pairs than MSI-X vectors exist + - i40e: Fix the number of queues available to be mapped for use + * 4.15 s390x kernel BUG at /build/linux- + Gycr4Z/linux-4.15.0/drivers/block/virtio_blk.c:565! (LP: #1788432) + - virtio/s390: avoid race on vcdev->config + - virtio/s390: fix race in ccw_io_helper() + * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990) + - iommu/amd: Fix NULL dereference bug in match_hid_uid + * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu + system (LP: #1821271) + - iwlwifi: add new card for 9260 series + * Add support for MAC address pass through on RTL8153-BD (LP: #1821276) + - r8152: Add support for MAC address pass through on RTL8153-BD + - r8152: Fix an error on RTL8153-BD MAC Address Passthrough support + + -- Andrea Righi Thu, 04 Apr 2019 09:58:48 +0200 + +linux-oracle (4.15.0-1010.12) bionic; urgency=medium + + * linux-oracle: 4.15.0-1010.12 -proposed tracker (LP: #1819704) + + * hot add VF to net_failover - could not rename interface '8' from 'eth0' to + 'ens4': Device or resource busy (LP: #1815268) + - SAUCE: net_failover: delay taking over primary device to accommodate udevd + renaming + + [ Ubuntu: 4.15.0-47.50 ] + + * linux: 4.15.0-47.50 -proposed tracker (LP: #1819716) + * Packaging resync (LP: #1786013) + - [Packaging] resync getabis + - [Packaging] update helper scripts + - [Packaging] resync retpoline extraction + * C++ demangling support missing from perf (LP: #1396654) + - [Packaging] fix a mistype + * arm-smmu-v3 arm-smmu-v3.3.auto: CMD_SYNC timeout (LP: #1818162) + - iommu/arm-smmu-v3: Fix unexpected CMD_SYNC timeout + * Crash in nvme_irq_check() when using threaded interrupts (LP: #1818747) + - nvme-pci: fix out of bounds access in nvme_cqe_pending + * CVE-2019-9213 + - mm: enforce min addr even if capable() in expand_downwards() + * CVE-2019-3460 + - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt + * amdgpu with mst WARNING on blanking (LP: #1814308) + - drm/amd/display: Don't use dc_link in link_encoder + - drm/amd/display: Move wait for hpd ready out from edp power control. + - drm/amd/display: eDP sequence BL off first then DP blank. + - drm/amd/display: Fix unused variable compilation error + - drm/amd/display: Fix warning about misaligned code + - drm/amd/display: Fix MST dp_blank REG_WAIT timeout + * tun/tap: unable to manage carrier state from userland (LP: #1806392) + - tun: implement carrier change + * CVE-2019-8980 + - exec: Fix mem leak in kernel_read_file + * raw_skew in timer from the ubuntu_kernel_selftests failed on Bionic + (LP: #1811194) + - selftest: timers: Tweak raw_skew to SKIP when ADJ_OFFSET/other clock + adjustments are in progress + * [Packaging] Allow overlay of config annotations (LP: #1752072) + - [Packaging] config-check: Add an include directive + * CVE-2019-7308 + - bpf: move {prev_,}insn_idx into verifier env + - bpf: move tmp variable into ax register in interpreter + - bpf: enable access to ax register also from verifier rewrite + - bpf: restrict map value pointer arithmetic for unprivileged + - bpf: restrict stack pointer arithmetic for unprivileged + - bpf: restrict unknown scalars of mixed signed bounds for unprivileged + - bpf: fix check_map_access smin_value test when pointer contains offset + - bpf: prevent out of bounds speculation on pointer arithmetic + - bpf: fix sanitation of alu op with pointer / scalar type from different + paths + - bpf: add various test cases to selftests + * CVE-2017-5753 + - bpf: properly enforce index mask to prevent out-of-bounds speculation + - bpf: fix inner map masking to prevent oob under speculation + * BPF: kernel pointer leak to unprivileged userspace (LP: #1815259) + - bpf/verifier: disallow pointer subtraction + * squashfs hardening (LP: #1816756) + - squashfs: more metadata hardening + - squashfs metadata 2: electric boogaloo + - squashfs: more metadata hardening + - Squashfs: Compute expected length from inode size rather than block length + * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982) + - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted + * Update ENA driver to version 2.0.3K (LP: #1816806) + - net: ena: update driver version from 2.0.2 to 2.0.3 + - net: ena: fix race between link up and device initalization + - net: ena: fix crash during failed resume from hibernation + * ipset kernel error: 4.15.0-43-generic (LP: #1811394) + - netfilter: ipset: Fix wraparound in hash:*net* types + * Silent "Unknown key" message when pressing keyboard backlight hotkey + (LP: #1817063) + - platform/x86: dell-wmi: Ignore new keyboard backlight change event + * CVE-2018-18021 + - arm64: KVM: Tighten guest core register access from userspace + - KVM: arm/arm64: Introduce vcpu_el1_is_32bit + - arm64: KVM: Sanitize PSTATE.M when being set from userspace + * CVE-2018-14678 + - x86/entry/64: Remove %ebx handling from error_entry/exit + * CVE-2018-19824 + - ALSA: usb-audio: Fix UAF decrement if card has no live interfaces in card.c + * CVE-2019-3459 + - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer + * Bionic update: upstream stable patchset 2019-02-08 (LP: #1815234) + - fork: unconditionally clear stack on fork + - spi: spi-s3c64xx: Fix system resume support + - Input: elan_i2c - add ACPI ID for lenovo ideapad 330 + - Input: i8042 - add Lenovo LaVie Z to the i8042 reset list + - Input: elan_i2c - add another ACPI ID for Lenovo Ideapad 330-15AST + - kvm, mm: account shadow page tables to kmemcg + - delayacct: fix crash in delayacct_blkio_end() after delayacct init failure + - tracing: Fix double free of event_trigger_data + - tracing: Fix possible double free in event_enable_trigger_func() + - kthread, tracing: Don't expose half-written comm when creating kthreads + - tracing/kprobes: Fix trace_probe flags on enable_trace_kprobe() failure + - tracing: Quiet gcc warning about maybe unused link variable + - arm64: fix vmemmap BUILD_BUG_ON() triggering on !vmemmap setups + - mlxsw: spectrum_switchdev: Fix port_vlan refcounting + - kcov: ensure irq code sees a valid area + - xen/netfront: raise max number of slots in xennet_get_responses() + - skip LAYOUTRETURN if layout is invalid + - ALSA: emu10k1: add error handling for snd_ctl_add + - ALSA: fm801: add error handling for snd_ctl_add + - NFSv4.1: Fix the client behaviour on NFS4ERR_SEQ_FALSE_RETRY + - nfsd: fix potential use-after-free in nfsd4_decode_getdeviceinfo + - vfio: platform: Fix reset module leak in error path + - vfio/mdev: Check globally for duplicate devices + - vfio/type1: Fix task tracking for QEMU vCPU hotplug + - kernel/hung_task.c: show all hung tasks before panic + - mm: /proc/pid/pagemap: hide swap entries from unprivileged users + - mm: vmalloc: avoid racy handling of debugobjects in vunmap + - mm/slub.c: add __printf verification to slab_err() + - rtc: ensure rtc_set_alarm fails when alarms are not supported + - perf tools: Fix pmu events parsing rule + - netfilter: ipset: forbid family for hash:mac sets + - netfilter: ipset: List timing out entries with "timeout 1" instead of zero + - irqchip/ls-scfg-msi: Map MSIs in the iommu + - watchdog: da9063: Fix updating timeout value + - printk: drop in_nmi check from printk_safe_flush_on_panic() + - bpf, arm32: fix inconsistent naming about emit_a32_lsr_{r64,i64} + - ceph: fix alignment of rasize + - e1000e: Ignore TSYNCRXCTL when getting I219 clock attributes + - powerpc/lib: Adjust .balign inside string functions for PPC32 + - powerpc/64s: Add barrier_nospec + - powerpc/eeh: Fix use-after-release of EEH driver + - hvc_opal: don't set tb_ticks_per_usec in udbg_init_opal_common() + - powerpc/64s: Fix compiler store ordering to SLB shadow area + - RDMA/mad: Convert BUG_ONs to error flows + - lightnvm: pblk: warn in case of corrupted write buffer + - netfilter: nf_tables: check msg_type before nft_trans_set(trans) + - pnfs: Don't release the sequence slot until we've processed layoutget on + open + - disable loading f2fs module on PAGE_SIZE > 4KB + - f2fs: fix error path of move_data_page + - f2fs: fix to don't trigger writeback during recovery + - f2fs: fix to wait page writeback during revoking atomic write + - f2fs: Fix deadlock in shutdown ioctl + - f2fs: fix to detect failure of dquot_initialize + - f2fs: fix race in between GC and atomic open + - block, bfq: remove wrong lock in bfq_requests_merged + - usbip: usbip_detach: Fix memory, udev context and udev leak + - usbip: dynamically allocate idev by nports found in sysfs + - perf/x86/intel/uncore: Correct fixed counter index check in generic code + - perf/x86/intel/uncore: Correct fixed counter index check for NHM + - selftests/intel_pstate: Improve test, minor fixes + - selftests: memfd: return Kselftest Skip code for skipped tests + - selftests: intel_pstate: return Kselftest Skip code for skipped tests + - PCI: Fix devm_pci_alloc_host_bridge() memory leak + - iwlwifi: pcie: fix race in Rx buffer allocator + - Bluetooth: hci_qca: Fix "Sleep inside atomic section" warning + - Bluetooth: btusb: Add a new Realtek 8723DE ID 2ff8:b011 + - ASoC: dpcm: fix BE dai not hw_free and shutdown + - mfd: cros_ec: Fail early if we cannot identify the EC + - mwifiex: handle race during mwifiex_usb_disconnect + - wlcore: sdio: check for valid platform device data before suspend + - media: tw686x: Fix incorrect vb2_mem_ops GFP flags + - media: videobuf2-core: don't call memop 'finish' when queueing + - Btrfs: don't return ino to ino cache if inode item removal fails + - Btrfs: don't BUG_ON() in btrfs_truncate_inode_items() + - btrfs: add barriers to btrfs_sync_log before log_commit_wait wakeups + - btrfs: qgroup: Finish rescan when hit the last leaf of extent tree + - x86/microcode: Make the late update update_lock a raw lock for RT + - PM / wakeup: Make s2idle_lock a RAW_SPINLOCK + - PCI: Prevent sysfs disable of device while driver is attached + - nvme-rdma: stop admin queue before freeing it + - nvme-pci: Fix AER reset handling + - ath: Add regulatory mapping for FCC3_ETSIC + - ath: Add regulatory mapping for ETSI8_WORLD + - ath: Add regulatory mapping for APL13_WORLD + - ath: Add regulatory mapping for APL2_FCCA + - ath: Add regulatory mapping for Uganda + - ath: Add regulatory mapping for Tanzania + - ath: Add regulatory mapping for Serbia + - ath: Add regulatory mapping for Bermuda + - ath: Add regulatory mapping for Bahamas + - powerpc/32: Add a missing include header + - powerpc/chrp/time: Make some functions static, add missing header include + - powerpc/powermac: Add missing prototype for note_bootable_part() + - powerpc/powermac: Mark variable x as unused + - powerpc: Add __printf verification to prom_printf + - spi: sh-msiof: Fix setting SIRMDR1.SYNCAC to match SITMDR1.SYNCAC + - powerpc/8xx: fix invalid register expression in head_8xx.S + - pinctrl: at91-pio4: add missing of_node_put + - bpf: powerpc64: pad function address loads with NOPs + - PCI: pciehp: Request control of native hotplug only if supported + - net: dsa: qca8k: Add support for QCA8334 switch + - mwifiex: correct histogram data with appropriate index + - ima: based on policy verify firmware signatures (pre-allocated buffer) + - drivers/perf: arm-ccn: don't log to dmesg in event_init + - spi: Add missing pm_runtime_put_noidle() after failed get + - fscrypt: use unbound workqueue for decryption + - scsi: ufs: ufshcd: fix possible unclocked register access + - scsi: ufs: fix exception event handling + - scsi: zfcp: assert that the ERP lock is held when tracing a recovery trigger + - drm/nouveau/fifo/gk104-: poll for runlist update completion + - Bluetooth: btusb: add ID for LiteOn 04ca:301a + - rtc: tps6586x: fix possible race condition + - rtc: vr41xx: fix possible race condition + - rtc: tps65910: fix possible race condition + - ALSA: emu10k1: Rate-limit error messages about page errors + - regulator: pfuze100: add .is_enable() for pfuze100_swb_regulator_ops + - md/raid1: add error handling of read error from FailFast device + - md: fix NULL dereference of mddev->pers in remove_and_add_spares() + - ixgbevf: fix MAC address changes through ixgbevf_set_mac() + - media: smiapp: fix timeout checking in smiapp_read_nvm + - net: ethernet: ti: cpsw-phy-sel: check bus_find_device() ret value + - ALSA: usb-audio: Apply rate limit to warning messages in URB complete + callback + - media: atomisp: ov2680: don't declare unused vars + - arm64: cmpwait: Clear event register before arming exclusive monitor + - HID: hid-plantronics: Re-resend Update to map button for PTT products + - arm64: dts: renesas: salvator-common: use audio-graph-card for Sound + - drm/radeon: fix mode_valid's return type + - drm/amdgpu: Remove VRAM from shared bo domains. + - powerpc/embedded6xx/hlwd-pic: Prevent interrupts from being handled by + Starlet + - HID: i2c-hid: check if device is there before really probing + - EDAC, altera: Fix ARM64 build warning + - ARM: dts: stih407-pinctrl: Fix complain about IRQ_TYPE_NONE usage + - ARM: dts: emev2: Add missing interrupt-affinity to PMU node + - ARM: dts: sh73a0: Add missing interrupt-affinity to PMU node + - nvmem: properly handle returned value nvmem_reg_read + - i40e: free the skb after clearing the bitlock + - tty: Fix data race in tty_insert_flip_string_fixed_flag + - dma-iommu: Fix compilation when !CONFIG_IOMMU_DMA + - net: phy: phylink: Release link GPIO + - media: rcar_jpu: Add missing clk_disable_unprepare() on error in jpu_open() + - libata: Fix command retry decision + - ACPI / LPSS: Only call pwm_add_table() for Bay Trail PWM if PMIC HRV is 2 + - media: media-device: fix ioctl function types + - media: saa7164: Fix driver name in debug output + - mtd: rawnand: fsl_ifc: fix FSL NAND driver to read all ONFI parameter pages + - brcmfmac: Add support for bcm43364 wireless chipset + - s390/cpum_sf: Add data entry sizes to sampling trailer entry + - perf: fix invalid bit in diagnostic entry + - bnxt_en: Check unsupported speeds in bnxt_update_link() on PF only. + - scsi: 3w-9xxx: fix a missing-check bug + - scsi: 3w-xxxx: fix a missing-check bug + - scsi: megaraid: silence a static checker bug + - scsi: qedf: Set the UNLOADING flag when removing a vport + - staging: lustre: o2iblnd: fix race at kiblnd_connect_peer + - staging: lustre: o2iblnd: Fix FastReg map/unmap for MLX5 + - thermal: exynos: fix setting rising_threshold for Exynos5433 + - bpf: fix references to free_bpf_prog_info() in comments + - f2fs: avoid fsync() failure caused by EAGAIN in writepage() + - media: siano: get rid of __le32/__le16 cast warnings + - drm/atomic: Handling the case when setting old crtc for plane + - ALSA: hda/ca0132: fix build failure when a local macro is defined + - mmc: dw_mmc: update actual clock for mmc debugfs + - mmc: pwrseq: Use kmalloc_array instead of stack VLA + - dt-bindings: pinctrl: meson: add support for the Meson8m2 SoC + - spi: meson-spicc: Fix error handling in meson_spicc_probe() + - dt-bindings: net: meson-dwmac: new compatible name for AXG SoC + - backlight: pwm_bl: Don't use GPIOF_* with gpiod_get_direction + - stop_machine: Use raw spinlocks + - delayacct: Use raw_spinlocks + - memory: tegra: Do not handle spurious interrupts + - memory: tegra: Apply interrupts mask per SoC + - nvme: lightnvm: add granby support + - arm64: defconfig: Enable Rockchip io-domain driver + - igb: Fix queue selection on MAC filters on i210 + - drm/gma500: fix psb_intel_lvds_mode_valid()'s return type + - ipconfig: Correctly initialise ic_nameservers + - rsi: Fix 'invalid vdd' warning in mmc + - rsi: fix nommu_map_sg overflow kernel panic + - audit: allow not equal op for audit by executable + - staging: vchiq_core: Fix missing semaphore release in error case + - staging: lustre: llite: correct removexattr detection + - staging: lustre: ldlm: free resource when ldlm_lock_create() fails. + - serial: core: Make sure compiler barfs for 16-byte earlycon names + - soc: imx: gpcv2: Do not pass static memory as platform data + - microblaze: Fix simpleImage format generation + - usb: hub: Don't wait for connect state at resume for powered-off ports + - crypto: authencesn - don't leak pointers to authenc keys + - crypto: authenc - don't leak pointers to authenc keys + - media: omap3isp: fix unbalanced dma_iommu_mapping + - regulator: Don't return or expect -errno from of_map_mode() + - scsi: scsi_dh: replace too broad "TP9" string with the exact models + - scsi: megaraid_sas: Increase timeout by 1 sec for non-RAID fastpath IOs + - media: atomisp: compat32: fix __user annotations + - media: si470x: fix __be16 annotations + - ASoC: topology: Fix bclk and fsync inversion in set_link_hw_format() + - ASoC: topology: Add missing clock gating parameter when parsing hw_configs + - drm: Add DP PSR2 sink enable bit + - drm/atomic-helper: Drop plane->fb references only for + drm_atomic_helper_shutdown() + - drm/dp/mst: Fix off-by-one typo when dump payload table + - block: reset bi_iter.bi_done after splitting bio + - random: mix rdrand with entropy sent in from userspace + - squashfs: be more careful about metadata corruption + - ext4: fix inline data updates with checksums enabled + - ext4: fix check to prevent initializing reserved inodes + - PCI: xgene: Remove leftover pci_scan_child_bus() call + - RDMA/uverbs: Protect from attempts to create flows on unsupported QP + - net: dsa: qca8k: Force CPU port to its highest bandwidth + - net: dsa: qca8k: Enable RXMAC when bringing up a port + - net: dsa: qca8k: Add QCA8334 binding documentation + - net: dsa: qca8k: Allow overwriting CPU port setting + - ipv4: remove BUG_ON() from fib_compute_spec_dst + - net: fix amd-xgbe flow-control issue + - net: lan78xx: fix rx handling before first packet is send + - net: mdio-mux: bcm-iproc: fix wrong getter and setter pair + - NET: stmmac: align DMA stuff to largest cache line length + - tcp_bbr: fix bw probing to raise in-flight data for very small BDPs + - xen-netfront: wait xenbus state change when load module manually + - netlink: Do not subscribe to non-existent groups + - netlink: Don't shift with UB on nlk->ngroups + - tcp: do not force quickack when receiving out-of-order packets + - tcp: add max_quickacks param to tcp_incr_quickack and + tcp_enter_quickack_mode + - tcp: do not aggressively quick ack after ECN events + - tcp: refactor tcp_ecn_check_ce to remove sk type cast + - tcp: add one more quick ack after after ECN events + - mm: disallow mappings that conflict for devm_memremap_pages() + - drm/i915/glk: Add Quirk for GLK NUC HDMI port issues. + - mm: check for SIGKILL inside dup_mmap() loop + - rxrpc: Fix terminal retransmission connection ID to include the channel + - ceph: fix use-after-free in ceph_statfs() + - lightnvm: proper error handling for pblk_bio_add_pages + - f2fs: don't drop dentry pages after fs shutdown + - selftests: filesystems: return Kselftest Skip code for skipped tests + - selftests/filesystems: devpts_pts included wrong header + - iwlwifi: mvm: open BA session only when sta is authorized + - drm/amd/display: Do not program interrupt status on disabled crtc + - soc: qcom: smem: fix qcom_smem_set_global_partition() + - soc: qcom: smem: byte swap values properly + - pinctrl: msm: fix gpio-hog related boot issues + - net: mvpp2: Add missing VLAN tag detection + - drm/nouveau: remove fence wait code from deferred client work handler + - drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl + - clocksource: Move inline keyword to the beginning of function declarations + - media: staging: atomisp: Comment out several unused sensor resolutions + - IB: Fix RDMA_RXE and INFINIBAND_RDMAVT dependencies for DMA_VIRT_OPS + - rsi: Add null check for virtual interfaces in wowlan config + - ARM: dts: stih410: Fix complain about IRQ_TYPE_NONE usage + - ARM: dts: imx53: Fix LDB OF graph warning + - soc/tegra: pmc: Don't allocate struct tegra_powergate on stack + - mlxsw: spectrum_router: Return an error for non-default FIB rules + - i40e: Add advertising 10G LR mode + - i40e: avoid overflow in i40e_ptp_adjfreq() + - ath10k: fix kernel panic while reading tpc_stats + - ASoC: fsl_ssi: Use u32 variable type when using regmap_read() + - platform/x86: dell-smbios: Match on www.dell.com in OEM strings too + - staging: ks7010: fix error handling in ks7010_upload_firmware + - media: rc: mce_kbd decoder: low timeout values cause double keydowns + - ath10k: search all IEs for variant before falling back + - PCI/ASPM: Disable ASPM L1.2 Substate if we don't have LTR + - ARM: dts: imx6qdl-wandboard: Let the codec control MCLK pinctrl + - drm/amdgpu: Avoid reclaim while holding locks taken in MMU notifier + - nvmet-fc: fix target sgl list on large transfers + - i2c: rcar: handle RXDMA HW behaviour on Gen3 + - gpio: uniphier: set legitimate irq trigger type in .to_irq hook + - tcp: ack immediately when a cwr packet arrives + - ACPICA: AML Parser: ignore control method status in module-level code + * Bionic update: upstream stable patchset 2019-02-05 (LP: #1814813) + - MIPS: ath79: fix register address in ath79_ddr_wb_flush() + - MIPS: Fix off-by-one in pci_resource_to_user() + - xen/PVH: Set up GS segment for stack canary + - drm/nouveau/drm/nouveau: Fix runtime PM leak in nv50_disp_atomic_commit() + - drm/nouveau: Set DRIVER_ATOMIC cap earlier to fix debugfs + - bonding: set default miimon value for non-arp modes if not set + - ip: hash fragments consistently + - ip: in cmsg IP(V6)_ORIGDSTADDR call pskb_may_pull + - net/mlx4_core: Save the qpn from the input modifier in RST2INIT wrapper + - net: skb_segment() should not return NULL + - net/mlx5: Adjust clock overflow work period + - net/mlx5e: Don't allow aRFS for encapsulated packets + - net/mlx5e: Fix quota counting in aRFS expire flow + - net/ipv6: Fix linklocal to global address with VRF + - multicast: do not restore deleted record source filter mode to new one + - net: phy: consider PHY_IGNORE_INTERRUPT in phy_start_aneg_priv + - sock: fix sg page frag coalescing in sk_alloc_sg + - rtnetlink: add rtnl_link_state check in rtnl_configure_link + - vxlan: add new fdb alloc and create helpers + - vxlan: make netlink notify in vxlan_fdb_destroy optional + - vxlan: fix default fdb entry netlink notify ordering during netdev create + - tcp: fix dctcp delayed ACK schedule + - tcp: helpers to send special DCTCP ack + - tcp: do not cancel delay-AcK on DCTCP special ACK + - tcp: do not delay ACK in DCTCP upon CE status change + - staging: speakup: fix wraparound in uaccess length check + - usb: cdc_acm: Add quirk for Castles VEGA3000 + - usb: core: handle hub C_PORT_OVER_CURRENT condition + - usb: dwc2: Fix DMA alignment to start at allocated boundary + - usb: gadget: f_fs: Only return delayed status when len is 0 + - driver core: Partially revert "driver core: correct device's shutdown order" + - can: xilinx_can: fix RX loop if RXNEMP is asserted without RXOK + - can: xilinx_can: fix power management handling + - can: xilinx_can: fix recovery from error states not being propagated + - can: xilinx_can: fix device dropping off bus on RX overrun + - can: xilinx_can: keep only 1-2 frames in TX FIFO to fix TX accounting + - can: xilinx_can: fix incorrect clear of non-processed interrupts + - can: xilinx_can: fix RX overflow interrupt not being enabled + - can: peak_canfd: fix firmware < v3.3.0: limit allocation to 32-bit DMA addr + only + - can: m_can.c: fix setup of CCCR register: clear CCCR NISO bit before + checking can.ctrlmode + - turn off -Wattribute-alias + - net-next/hinic: fix a problem in hinic_xmit_frame() + - net/mlx5e: Refine ets validation function + - nfp: flower: ensure dead neighbour entries are not offloaded + - usb: gadget: Fix OS descriptors support + - ACPICA: AML Parser: ignore dispatcher error status during table load + * installer does not support iSCSI iBFT (LP: #1817321) + - d-i: add iscsi_ibft to scsi-modules + * CVE-2019-7222 + - KVM: x86: work around leak of uninitialized stack contents (CVE-2019-7222) + * CVE-2019-7221 + - KVM: nVMX: unconditionally cancel preemption timer in free_nested + (CVE-2019-7221) + * CVE-2019-6974 + - kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974) + * Regular D-state processes impacting LXD containers (LP: #1817628) + - mm: do not stall register_shrinker() + * hns3 nic speed may not match optical port speed (LP: #1817969) + - net: hns3: Config NIC port speed same as that of optical module + * [Hyper-V] srcu: Lock srcu_data structure in srcu_gp_start() (LP: #1802021) + - srcu: Prohibit call_srcu() use under raw spinlocks + - srcu: Lock srcu_data structure in srcu_gp_start() + * libsas disks can have non-unique by-path names (LP: #1817784) + - scsi: libsas: Fix rphy phy_identifier for PHYs with end devices attached + * Bluetooth not working (Intel CyclonePeak) (LP: #1817518) + - Bluetooth: btusb: Add support for Intel bluetooth device 8087:0029 + * CVE-2019-8912 + - net: crypto set sk to NULL when af_alg_release. + - net: socket: set sock->sk to NULL after calling proto_ops::release() + * Trackpad is not recognized. (LP: #1817200) + - pinctrl: cannonlake: Fix gpio base for GPP-E + * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831) + - ALSA: hda/realtek - Headset microphone support for System76 darp5 + - ALSA: hda/realtek - Headset microphone and internal speaker support for + System76 oryp5 + * Constant noise in the headphone on Lenovo X1 machines (LP: #1817263) + - ALSA: hda/realtek: Disable PC beep in passthrough on alc285 + * AC adapter status not detected on Asus ZenBook UX410UAK (LP: #1745032) + - Revert "ACPI / battery: Add quirk for Asus GL502VSK and UX305LA" + - ACPI / AC: Remove initializer for unused ident dmi_system_id + - ACPI / battery: Remove initializer for unused ident dmi_system_id + - ACPI / battery: Add handling for devices which wrongly report discharging + state + - ACPI / battery: Ignore AC state in handle_discharging on systems where it is + broken + * TPM intermittently fails after cold-boot (LP: #1762672) + - tpm: fix intermittent failure with self tests + * qlcnic: Firmware aborts/hangs in QLogic NIC (LP: #1815033) + - qlcnic: fix Tx descriptor corruption on 82xx devices + + -- Khalid Elmously Mon, 18 Mar 2019 00:16:01 -0400 + +linux-oracle (4.15.0-1009.11) bionic; urgency=medium + + * linux-oracle: 4.15.0-1009.11 -proposed tracker (LP: #1814738) + + [ Ubuntu: 4.15.0-46.49 ] + + * linux: 4.15.0-46.49 -proposed tracker (LP: #1814726) + * mprotect fails on ext4 with dax (LP: #1799237) + - x86/speculation/l1tf: Exempt zeroed PTEs from inversion + * kernel BUG at /build/linux-vxxS7y/linux-4.15.0/mm/slub.c:296! (LP: #1812086) + - iscsi target: fix session creation failure handling + - scsi: iscsi: target: Set conn->sess to NULL when iscsi_login_set_conn_values + fails + - scsi: iscsi: target: Fix conn_ops double free + * user_copy in user from ubuntu_kernel_selftests failed on KVM kernel + (LP: #1812198) + - selftests: user: return Kselftest Skip code for skipped tests + - selftests: kselftest: change KSFT_SKIP=4 instead of KSFT_PASS + - selftests: kselftest: Remove outdated comment + * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472) + - SAUCE: staging: rtlwifi: allow RTLWIFI_DEBUG_ST to be disabled + - [Config] CONFIG_RTLWIFI_DEBUG_ST=n + - SAUCE: Add r8822be to signature inclusion list + * kernel oops in bcache module (LP: #1793901) + - SAUCE: bcache: never writeback a discard operation + * CVE-2018-18397 + - userfaultfd: use ENOENT instead of EFAULT if the atomic copy user fails + - userfaultfd: shmem: allocate anonymous memory for MAP_PRIVATE shmem + - userfaultfd: shmem/hugetlbfs: only allow to register VM_MAYWRITE vmas + - userfaultfd: shmem: add i_size checks + - userfaultfd: shmem: UFFDIO_COPY: set the page dirty if VM_WRITE is not set + * Ignore "incomplete report" from Elan touchpanels (LP: #1813733) + - HID: i2c-hid: Ignore input report if there's no data present on Elan + touchpanels + * Vsock connect fails with ENODEV for large CID (LP: #1813934) + - vhost/vsock: fix vhost vsock cid hashing inconsistent + * SRU: Fix thinkpad 11e 3rd boot hang (LP: #1804604) + - ACPI / LPSS: Force LPSS quirks on boot + * Bionic update: upstream stable patchset 2019-01-17 (LP: #1812229) + - scsi: sd_zbc: Fix variable type and bogus comment + - KVM/Eventfd: Avoid crash when assign and deassign specific eventfd in + parallel. + - x86/apm: Don't access __preempt_count with zeroed fs + - x86/events/intel/ds: Fix bts_interrupt_threshold alignment + - x86/MCE: Remove min interval polling limitation + - fat: fix memory allocation failure handling of match_strdup() + - ALSA: hda/realtek - Add Panasonic CF-SZ6 headset jack quirk + - ARCv2: [plat-hsdk]: Save accl reg pair by default + - ARC: Fix CONFIG_SWAP + - ARC: configs: Remove CONFIG_INITRAMFS_SOURCE from defconfigs + - ARC: mm: allow mprotect to make stack mappings executable + - mm: memcg: fix use after free in mem_cgroup_iter() + - mm/huge_memory.c: fix data loss when splitting a file pmd + - cpufreq: intel_pstate: Register when ACPI PCCH is present + - vfio/pci: Fix potential Spectre v1 + - stop_machine: Disable preemption when waking two stopper threads + - drm/i915: Fix hotplug irq ack on i965/g4x + - drm/nouveau: Use drm_connector_list_iter_* for iterating connectors + - drm/nouveau: Avoid looping through fake MST connectors + - gen_stats: Fix netlink stats dumping in the presence of padding + - ipv4: Return EINVAL when ping_group_range sysctl doesn't map to user ns + - ipv6: fix useless rol32 call on hash + - ipv6: ila: select CONFIG_DST_CACHE + - lib/rhashtable: consider param->min_size when setting initial table size + - net: diag: Don't double-free TCP_NEW_SYN_RECV sockets in tcp_abort + - net: Don't copy pfmemalloc flag in __copy_skb_header() + - skbuff: Unconditionally copy pfmemalloc in __skb_clone() + - net/ipv4: Set oif in fib_compute_spec_dst + - net: phy: fix flag masking in __set_phy_supported + - ptp: fix missing break in switch + - qmi_wwan: add support for Quectel EG91 + - tg3: Add higher cpu clock for 5762. + - hv_netvsc: Fix napi reschedule while receive completion is busy + - net/mlx4_en: Don't reuse RX page when XDP is set + - net: systemport: Fix CRC forwarding check for SYSTEMPORT Lite + - ipv6: make DAD fail with enhanced DAD when nonce length differs + - net: usb: asix: replace mii_nway_restart in resume path + - alpha: fix osf_wait4() breakage + - cxl_getfile(): fix double-iput() on alloc_file() failures + - powerpc/powernv: Fix save/restore of SPRG3 on entry/exit from stop (idle) + - xhci: Fix perceived dead host due to runtime suspend race with event handler + - KVM: irqfd: fix race between EPOLLHUP and irq_bypass_register_consumer + - x86/kvmclock: set pvti_cpu0_va after enabling kvmclock + - ALSA: hda/realtek - Yet another Clevo P950 quirk entry + - drm/amdgpu: Reserve VM root shared fence slot for command submission (v3) + - rhashtable: add restart routine in rhashtable_free_and_destroy() + - sch_fq_codel: zero q->flows_cnt when fq_codel_init fails + - sctp: introduce sctp_dst_mtu + - sctp: fix the issue that pathmtu may be set lower than MINSEGMENT + - net: aquantia: vlan unicast address list correct handling + - drm_mode_create_lease_ioctl(): fix open-coded filp_clone_open() + * Bionic update: upstream stable patchset 2019-01-15 (LP: #1811877) + - compiler-gcc.h: Add __attribute__((gnu_inline)) to all inline declarations + - x86/asm: Add _ASM_ARG* constants for argument registers to + - x86/paravirt: Make native_save_fl() extern inline + - Btrfs: fix duplicate extents after fsync of file with prealloc extents + - cpufreq / CPPC: Set platform specific transition_delay_us + - PCI: exynos: Fix a potential init_clk_resources NULL pointer dereference + - alx: take rtnl before calling __alx_open from resume + - atm: Preserve value of skb->truesize when accounting to vcc + - atm: zatm: Fix potential Spectre v1 + - ipv6: sr: fix passing wrong flags to crypto_alloc_shash() + - ipvlan: fix IFLA_MTU ignored on NEWLINK + - ixgbe: split XDP_TX tail and XDP_REDIRECT map flushing + - net: dccp: avoid crash in ccid3_hc_rx_send_feedback() + - net: dccp: switch rx_tstamp_last_feedback to monotonic clock + - net: fix use-after-free in GRO with ESP + - net: macb: Fix ptp time adjustment for large negative delta + - net/mlx5e: Avoid dealing with vport representors if not being e-switch + manager + - net/mlx5: E-Switch, Avoid setup attempt if not being e-switch manager + - net/mlx5: Fix command interface race in polling mode + - net/mlx5: Fix incorrect raw command length parsing + - net/mlx5: Fix required capability for manipulating MPFS + - net/mlx5: Fix wrong size allocation for QoS ETC TC regitster + - net: mvneta: fix the Rx desc DMA address in the Rx path + - net/packet: fix use-after-free + - net_sched: blackhole: tell upper qdisc about dropped packets + - net: sungem: fix rx checksum support + - net/tcp: Fix socket lookups with SO_BINDTODEVICE + - qede: Adverstise software timestamp caps when PHC is not available. + - qed: Fix setting of incorrect eswitch mode. + - qed: Fix use of incorrect size in memcpy call. + - qed: Limit msix vectors in kdump kernel to the minimum required count. + - r8152: napi hangup fix after disconnect + - stmmac: fix DMA channel hang in half-duplex mode + - strparser: Remove early eaten to fix full tcp receive buffer stall + - tcp: fix Fast Open key endianness + - tcp: prevent bogus FRTO undos with non-SACK flows + - vhost_net: validate sock before trying to put its fd + - VSOCK: fix loopback on big-endian systems + - net: cxgb3_main: fix potential Spectre v1 + - rtlwifi: Fix kernel Oops "Fw download fail!!" + - rtlwifi: rtl8821ae: fix firmware is not ready to run + - net: lan78xx: Fix race in tx pending skb size calculation + - crypto: af_alg - Initialize sg_num_bytes in error code path + - mtd: rawnand: denali_dt: set clk_x_rate to 200 MHz unconditionally + - PCI: hv: Disable/enable IRQs rather than BH in hv_compose_msi_msg() + - netfilter: ebtables: reject non-bridge targets + - reiserfs: fix buffer overflow with long warning messages + - KEYS: DNS: fix parsing multiple options + - tls: Stricter error checking in zerocopy sendmsg path + - autofs: fix slab out of bounds read in getname_kernel() + - nsh: set mac len based on inner packet + - bdi: Fix another oops in wb_workfn() + - rds: avoid unenecessary cong_update in loop transport + - net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL. + - string: drop __must_check from strscpy() and restore strscpy() usages in + cgroup + - nfsd: COPY and CLONE operations require the saved filehandle to be set + - net/sched: act_ife: fix recursive lock and idr leak + - net/sched: act_ife: preserve the action control in case of error + - hinic: reset irq affinity before freeing irq + - nfp: flower: fix mpls ether type detection + - net: macb: initialize bp->queues[0].bp for at91rm9200 + - enic: do not overwrite error code + - virtio_net: fix memory leak in XDP_REDIRECT + - netfilter: ipv6: nf_defrag: drop skb dst before queueing + - ipvs: initialize tbl->entries after allocation + - ipvs: initialize tbl->entries in ip_vs_lblc_init_svc() + - bpf: enforce correct alignment for instructions + - bpf, arm32: fix to use bpf_jit_binary_lock_ro api + * Fix non-working pinctrl-intel (LP: #1811777) + - pinctrl: intel: Implement intel_gpio_get_direction callback + - pinctrl: intel: Do pin translation in other GPIO operations as well + * ip6_gre: fix tunnel list corruption for x-netns (LP: #1812875) + - ip6_gre: fix tunnel list corruption for x-netns + * Userspace break as a result of missing patch backport (LP: #1813873) + - tty: Don't hold ldisc lock in tty_reopen() if ldisc present + * kvm_stat : missing python dependency (LP: #1798776) + - tools/kvm_stat: fix python3 issues + - tools/kvm_stat: switch to python3 + * [SRU] Fix Xorg crash with nomodeset when BIOS enable 64-bit fb addr + (LP: #1812797) + - vgaarb: Add support for 64-bit frame buffer address + - vgaarb: Keep adding VGA device in queue + * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812) + - USB: Add new USB LPM helpers + - USB: Consolidate LPM checks to avoid enabling LPM twice + * ptrace-tm-spd-gpr in powerpc/ptrace from ubuntu_kerenl_selftests failed on + Bionic P8 (LP: #1813127) + - selftests/powerpc: Fix ptrace tm failure + * [SRU] IO's are issued with incorrect Scatter Gather Buffer (LP: #1795453) + - scsi: megaraid_sas: Use 63-bit DMA addressing + * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816) + - [Config] Enable timestamping in network PHY devices + * CVE-2018-19854 + - crypto: user - fix leaking uninitialized memory to userspace + * x86/mm: Found insecure W+X mapping at address (ptrval)/0xc00a0000 + (LP: #1813532) + - x86/mm: Do not warn about PCI BIOS W+X mappings + * CVE-2019-6133 + - fork: record start_time late + * Fix not working Goodix touchpad (LP: #1811929) + - HID: i2c-hid: Disable runtime PM on Goodix touchpad + * bluetooth controller not detected with 4.15 kernel (LP: #1810797) + - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK + - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y + * X1 Extreme: only one of the two SSDs is loaded (LP: #1811755) + - nvme-core: rework a NQN copying operation + - nvme: pad fake subsys NQN vid and ssvid with zeros + - nvme: introduce NVME_QUIRK_IGNORE_DEV_SUBNQN + * Crash on "ip link add foo type ipip" (LP: #1811803) + - SAUCE: fan: Fix NULL pointer dereference + + [ Ubuntu: 4.15.0-45.48 ] + + * linux: 4.15.0-45.48 -proposed tracker (LP: #1813779) + * External monitors does not work anymore 4.15.0-44 (LP: #1813663) + - SAUCE: Revert "drm/i915/dp: Send DPCD ON for MST before phy_up" + * kernel 4.15.0-44 cannot mount ext4 fs with meta_bg enabled (LP: #1813727) + - ext4: fix false negatives *and* false positives in ext4_check_descriptors() + + -- Kleber Sacilotto de Souza Wed, 06 Feb 2019 14:11:18 +0000 + +linux-oracle (4.15.0-1008.10) bionic; urgency=medium + + * linux-oracle: 4.15.0-1008.10 -proposed tracker (LP: #1811427) + + * SATA device is not going to DEVSLP (LP: #1781533) + - [Config] set CONFIG_SATA_MOBILE_LPM_POLICY=0 + + * Bionic update: upstream stable patchset 2019-01-04 (LP: #1810554) + - [config] x86 CRYPTO_SALSA20 deprecated + + [ Ubuntu: 4.15.0-44.47 ] + + * linux: 4.15.0-44.47 -proposed tracker (LP: #1811419) + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + * CPU hard lockup with rigorous writes to NVMe drive (LP: #1810998) + - blk-wbt: pass in enum wbt_flags to get_rq_wait() + - blk-wbt: Avoid lock contention and thundering herd issue in wbt_wait + - blk-wbt: move disable check into get_limit() + - blk-wbt: use wq_has_sleeper() for wq active check + - blk-wbt: fix has-sleeper queueing check + - blk-wbt: abstract out end IO completion handler + - blk-wbt: improve waking of tasks + * To reduce the Realtek USB cardreader power consumption (LP: #1811337) + - mmc: sdhci: Disable 1.8v modes (HS200/HS400/UHS) if controller can't support + 1.8v + - mmc: core: Introduce MMC_CAP_SYNC_RUNTIME_PM + - mmc: rtsx_usb_sdmmc: Don't runtime resume the device while changing led + - mmc: rtsx_usb: Use MMC_CAP2_NO_SDIO + - mmc: rtsx_usb: Enable MMC_CAP_ERASE to allow erase/discard/trim requests + - mmc: rtsx_usb_sdmmc: Re-work runtime PM support + - mmc: rtsx_usb_sdmmc: Re-work card detection/removal support + - memstick: rtsx_usb_ms: Add missing pm_runtime_disable() in probe function + - misc: rtsx_usb: Use USB remote wakeup signaling for card insertion detection + - memstick: Prevent memstick host from getting runtime suspended during card + detection + - memstick: rtsx_usb_ms: Use ms_dev() helper + - memstick: rtsx_usb_ms: Support runtime power management + * Support non-strict iommu mode on arm64 (LP: #1806488) + - iommu/io-pgtable-arm: Fix race handling in split_blk_unmap() + - iommu/arm-smmu-v3: Implement flush_iotlb_all hook + - iommu/dma: Add support for non-strict mode + - iommu: Add "iommu.strict" command line option + - iommu/io-pgtable-arm: Add support for non-strict mode + - iommu/arm-smmu-v3: Add support for non-strict mode + - iommu/io-pgtable-arm-v7s: Add support for non-strict mode + - iommu/arm-smmu: Support non-strict mode + * ELAN900C:00 04F3:2844 touchscreen doesn't work (LP: #1811335) + - pinctrl: cannonlake: Fix community ordering for H variant + - pinctrl: cannonlake: Fix HOSTSW_OWN register offset of H variant + * Add Cavium ThunderX2 SoC UNCORE PMU driver (LP: #1811200) + - perf: Export perf_event_update_userpage + - Documentation: perf: Add documentation for ThunderX2 PMU uncore driver + - drivers/perf: Add Cavium ThunderX2 SoC UNCORE PMU driver + - [Config] New config CONFIG_THUNDERX2_PMU=m + * Update hisilicon SoC-specific drivers (LP: #1810457) + - SAUCE: Revert "net: hns3: Updates RX packet info fetch in case of multi BD" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when + resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce + callback function" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback + function when link status change" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying + roce client" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE" + - scsi: hisi_sas: Remove depends on HAS_DMA in case of platform dependency + - ethernet: hisilicon: hns: hns_dsaf_mac: Use generic eth_broadcast_addr + - scsi: hisi_sas: consolidate command check in hisi_sas_get_ata_protocol() + - scsi: hisi_sas: remove some unneeded structure members + - scsi: hisi_sas: Introduce hisi_sas_phy_set_linkrate() + - net: hns: Fix the process of adding broadcast addresses to tcam + - net: hns3: remove redundant variable 'protocol' + - scsi: hisi_sas: Drop hisi_sas_slot_abort() + - net: hns: Make many functions static + - net: hns: make hns_dsaf_roce_reset non static + - net: hisilicon: hns: Replace mdelay() with msleep() + - net: hns3: fix return value error while hclge_cmd_csq_clean failed + - net: hns: remove redundant variables 'max_frm' and 'tmp_mac_key' + - net: hns: Mark expected switch fall-through + - net: hns3: Mark expected switch fall-through + - net: hns3: Remove tx ring BD len register in hns3_enet + - net: hns: modify variable type in hns_nic_reuse_page + - net: hns: use eth_get_headlen interface instead of hns_nic_get_headlen + - net: hns3: modify variable type in hns3_nic_reuse_page + - net: hns3: Fix for vf vlan delete failed problem + - net: hns3: Fix for multicast failure + - net: hns3: Fix error of checking used vlan id + - net: hns3: Implement shutdown ops in hns3 pci driver + - net: hns3: Fix for loopback selftest failed problem + - net: hns3: Fix ping exited problem when doing lp selftest + - net: hns3: Preserve vlan 0 in hardware table + - net: hns3: Only update mac configuation when necessary + - net: hns3: Change the dst mac addr of loopback packet + - net: hns3: Remove redundant codes of query advertised flow control abilitiy + - net: hns3: Refine hns3_get_link_ksettings() + - net: hns: make function hns_gmac_wait_fifo_clean() static + - net: hns3: Add default irq affinity + - net: hns3: Add unlikely for buf_num check + - net: hns3: Remove tx budget to clean more TX descriptors in a napi + - net: hns3: Remove packet statistics of public + - net: hns3: Add support for hns3_nic_netdev_ops.ndo_do_ioctl + - net: hns3: Set STATE_DOWN bit of hdev state when stopping net + - net: hns3: Check hdev state when getting link status + - net: hns3: Fix for setting speed for phy failed problem + - net: hns3: Fix cmdq registers initialization issue for vf + - net: hns3: Clear client pointer when initialize client failed or unintialize + finished + - net: hns3: Fix client initialize state issue when roce client initialize + failed + - net: hns3: Fix parameter type for q_id in hclge_tm_q_to_qs_map_cfg() + - net: hns3: Fix ets validate issue + - net: hns3: Unify the type convert for desc.data + - net: hns3: Adjust prefix of tx/rx statistic names + - net: hns3: Fix tqp array traversal condition for vf + - net: hns3: Unify the prefix of vf functions + - net: hns3: Add handle for default case + - net: hns3: Add nic state check before calling netif_tx_wake_queue + - net: hns3: Add unlikely for dma_mapping_error check + - net: hns3: Remove print messages for error packet + - net: hns3: Add get_media_type ops support for VF + - net: hns3: Fix speed/duplex information loss problem when executing ethtool + ethx cmd of VF + - net: hns3: Remove redundant hclge_get_port_type() + - net: hns3: Add support for sctp checksum offload + - net: hns3: Set extra mac address of pause param for HW + - net: hns3: Rename loop mode + - net: hns3: Rename mac loopback to app loopback + - net: hns3: Add serdes parallel inner loopback support + - net: hns3: Fix for packet buffer setting bug + - net: hns3: Fix for netdev not up problem when setting mtu + - net: hns3: Change return type of hclge_tm_schd_info_update() + - net: hns3: Modify hns3_get_max_available_channels + - net: hns3: Fix loss of coal configuration while doing reset + - net: hns: remove ndo_poll_controller + - hns3: Fix the build. + - hns3: Another build fix. + - net: hns3: Add flow director initialization + - net: hns3: Add input key and action config support for flow director + - net: hns3: Add support for rule add/delete for flow director + - net: hns3: Add support for rule query of flow director + - net: hns3: Add reset handle for flow director + - net: hns3: Remove all flow director rules when unload hns3 driver + - net: hns3: Add support for enable/disable flow director + - net: hns3: Remove the default mask configuration for mac vlan table + - net: hns3: Clear mac vlan table entries when unload driver or function reset + - net: hns3: Optimize for unicast mac vlan table + - net: hns3: Drop depricated mta table support + - net: hns3: Add egress/ingress vlan filter for revision 0x21 + - net: hns3: Fix for rx vlan id handle to support Rev 0x21 hardware + - net: hns3: Add new RSS hash algorithm support for PF + - net: hns3: Add RSS general configuration support for VF + - net: hns3: Add RSS tuples support for VF + - net: hns3: Add HW RSS hash information to RX skb + - net: hns3: Enable promisc mode when mac vlan table is full + - net: hns3: Resume promisc mode and vlan filter status after reset + - net: hns3: Resume promisc mode and vlan filter status after loopback test + - scsi: hisi_sas: Feed back linkrate(max/min) when re-attached + - scsi: hisi_sas: Move evaluation of hisi_hba in hisi_sas_task_prep() + - scsi: hisi_sas: Fix the race between IO completion and timeout for + SMP/internal IO + - scsi: hisi_sas: Free slot later in slot_complete_vx_hw() + - scsi: hisi_sas: unmask interrupts ent72 and ent74 + - scsi: hisi_sas: Use block layer tag instead for IPTT + - scsi: hisi_sas: Update v3 hw AIP_LIMIT and CFG_AGING_TIME register values + - net: hns3: remove hns3_fill_desc_tso + - net: hns3: move DMA map into hns3_fill_desc + - net: hns3: add handling for big TX fragment + - net: hns3: rename hns_nic_dma_unmap + - net: hns3: fix for multiple unmapping DMA problem + - scsi: hisi_sas: Fix spin lock management in slot_index_alloc_quirk_v2_hw() + - scsi: hisi_sas: Fix NULL pointer dereference + - net: hns3: Add PCIe AER callback error_detected + - net: hns3: Add PCIe AER error recovery + - net: hns3: Add support to enable and disable hw errors + - net: hns3: Add enable and process common ecc errors + - net: hns3: Add enable and process hw errors from IGU, EGU and NCSI + - net: hns3: Add enable and process hw errors from PPP + - net: hns3: Add enable and process hw errors of TM scheduler + - net: hns3: Fix for warning uninitialized symbol hw_err_lst3 + - net: hns3: fix spelling mistake "intrerrupt" -> "interrupt" + - net: hns3: add error handler for hns3_nic_init_vector_data() + - net: hns3: bugfix for buffer not free problem during resetting + - net: hns3: bugfix for reporting unknown vector0 interrupt repeatly problem + - net: hns3: bugfix for the initialization of command queue's spin lock + - net: hns3: remove unnecessary queue reset in the hns3_uninit_all_ring() + - net: hns3: bugfix for is_valid_csq_clean_head() + - net: hns3: bugfix for hclge_mdio_write and hclge_mdio_read + - net: hns3: fix incorrect return value/type of some functions + - net: hns3: bugfix for handling mailbox while the command queue reinitialized + - net: hns3: bugfix for rtnl_lock's range in the hclge_reset() + - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset() + - net: hns3: Fix for out-of-bounds access when setting pfc back pressure + - scsi: hisi_sas: Remove set but not used variable 'dq_list' + - net: hns3: bugfix for not checking return value + - net: hns: Incorrect offset address used for some registers. + - net: hns: All ports can not work when insmod hns ko after rmmod. + - net: hns: Some registers use wrong address according to the datasheet. + - net: hns: Fixed bug that netdev was opened twice + - net: hns: Clean rx fbd when ae stopped. + - net: hns: Free irq when exit from abnormal branch + - net: hns: Avoid net reset caused by pause frames storm + - net: hns: Fix ntuple-filters status error. + - net: hns: Add mac pcs config when enable|disable mac + - net: hns: Fix ping failed when use net bridge and send multicast + - net: hns3: use HNS3_NIC_STATE_INITED to indicate the initialization state of + enet + - net: hns3: add set_default_reset_request in the hnae3_ae_ops + - net: hns3: provide some interface & information for the client + - net: hns3: adjust the location of clearing the table when doing reset + - net: hns3: enable/disable ring in the enet while doing UP/DOWN + - net: hns3: use HNS3_NIC_STATE_RESETTING to indicate resetting + - net: hns3: ignore new coming low-level reset while doing high-level reset + - net: hns3: move some reset information from hnae3_handle into + hclge_dev/hclgevf_dev + - net: hns3: adjust the process of PF reset + - net: hns3: call roce's reset notify callback when resetting + - net: hns3: add error handler for hclge_reset() + - net: hns3: fix for cmd queue memory not freed problem during reset + - net: hns3: Remove set but not used variable 'reset_level' + - net: hns3: fix spelling mistake, "assertting" -> "asserting" + - net: hns3: add reset_hdev to reinit the hdev in VF's reset process + - net: hns3: adjust VF's reset process + - net: hns3: add reset handling for VF when doing PF reset + - net: hns3: add reset handling for VF when doing Core/Global/IMP reset + - net: hns3: stop handling command queue while resetting VF + - net: hns3: add error handler for hclgevf_reset() + - net: hns3: stop napi polling when HNS3_NIC_STATE_DOWN is set + - net: hns3: implement the IMP reset processing for PF + - net: hns3: add PCIe FLR support for PF + - net: hns3: do VF's pci re-initialization while PF doing FLR + - net: hns3: add PCIe FLR support for VF + - net: hns3: Enable HW GRO for Rev B(=0x21) HNS3 hardware + - net: hns3: Add handling of GRO Pkts not fully RX'ed in NAPI poll + - net: hns3: Add skb chain when num of RX buf exceeds MAX_SKB_FRAGS + - net: hns3: Adds GRO params to SKB for the stack + - scsi: hisi_sas: use dma_set_mask_and_coherent + - scsi: hisi_sas: Create separate host attributes per HBA + - scsi: hisi_sas: Add support for interrupt converge for v3 hw + - scsi: hisi_sas: Add support for interrupt coalescing for v3 hw + - scsi: hisi_sas: Relocate some codes to avoid an unused check + - scsi: hisi_sas: change the time of SAS SSP connection + - net: hns3: fix spelling mistake "failded" -> "failed" + - net: hns3: Support two vlan header when setting mtu + - net: hns3: Refactor mac mtu setting related functions + - net: hns3: Add vport alive state checking support + - net: hns3: Add mtu setting support for vf + - net: hns3: up/down netdev in hclge module when setting mtu + - net: hns3: add common validation in hclge_dcb + - net: hns3: Add debugfs framework registration + - net: hns3: Add "queue info" query function + - net: hns3: Add "FD flow table" info query function + - net: hns3: Add "tc config" info query function + - net: hns3: Add "tm config" info query function + - net: hns3: Add "qos pause" config info query function + - net: hns3: Add "qos prio map" info query function + - net: hns3: Add "qos buffer" config info query function + - net: hns3: Support "ethtool -d" for HNS3 VF driver + - net: hns3: Adds support to dump(using ethool-d) PCIe regs in HNS3 PF driver + - net: hns3: remove existing process error functions and reorder hw_blk table + - net: hns3: rename enable error interrupt functions + - net: hns3: re-enable error interrupts on hw reset + - net: hns3: deletes unnecessary settings of the descriptor data + - net: hns3: rename process_hw_error function + - net: hns3: add optimization in the hclge_hw_error_set_state + - net: hns3: add handling of hw ras errors using new set of commands + - net: hns3: deleted logging 1 bit errors + - net: hns3: add handling of hw errors reported through MSIX + - net: hns3: add handling of hw errors of MAC + - net: hns3: handle hw errors of PPP PF + - net: hns3: handle hw errors of PPU(RCB) + - net: hns3: handle hw errors of SSU + - net: hns3: add handling of RDMA RAS errors + - net: hns3: fix spelling mistake "offser" -> "offset" + - scsi: hisi_sas: Fix warnings detected by sparse + - scsi: hisi_sas: Relocate some code to reduce complexity + - scsi: hisi_sas: Make sg_tablesize consistent value + - hns3: prevent building without CONFIG_INET + - net: hns3: Add "bd info" query function + - net: hns3: Add "manager table" information query function + - net: hns3: Add "status register" information query function + - net: hns3: Add "dcb register" status information query function + - net: hns3: Add "queue map" information query function + - net: hns3: Add "tm map" status information query function + - net: hns3: fix error handling int the hns3_get_vector_ring_chain + - net: hns3: uninitialize pci in the hclgevf_uninit + - net: hns3: fix napi_disable not return problem + - net: hns3: update some variables while hclge_reset()/hclgevf_reset() done + - net: hns3: remove unnecessary configuration recapture while resetting + - net: hns3: fix incomplete uninitialization of IRQ in the + hns3_nic_uninit_vector_data() + - net: hns3: update coalesce param per second + - net: hns3: remove 1000M/half support of phy + - net: hns3: synchronize speed and duplex from phy when phy link up + - net: hns3: getting tx and dv buffer size through firmware + - net: hns3: aligning buffer size in SSU to 256 bytes + - net: hns3: fix a SSU buffer checking bug + - scsi: hisi_sas: Add support for DIF feature for v2 hw + - net: hns3: refine the handle for hns3_nic_net_open/stop() + - net: hns3: change default tc state to close + - net: hns3: fix a bug caused by udelay + - net: hns3: add max vector number check for pf + - net: hns3: reset tqp while doing DOWN operation + - net: hns3: fix vf id check issue when add flow director rule + - net: hns3: don't restore rules when flow director is disabled + - net: hns3: fix the descriptor index when get rss type + - net: hns3: remove redundant variable initialization + - net: hns3: call hns3_nic_net_open() while doing HNAE3_UP_CLIENT + * iptables connlimit allows more connections than the limit when using + multiple CPUs (LP: #1811094) + - SAUCE: netfilter: xt_connlimit: remove the 'addr' parameter in add_hlist() + - netfilter: nf_conncount: expose connection list interface + - netfilter: nf_conncount: Fix garbage collection with zones + - netfilter: nf_conncount: fix garbage collection confirm race + - netfilter: nf_conncount: don't skip eviction when age is negative + * CVE-2018-16882 + - KVM: Fix UAF in nested posted interrupt processing + * Cannot initialize ATA disk if IDENTIFY command fails (LP: #1809046) + - scsi: libsas: check the ata device status by ata_dev_enabled() + * scsi: libsas: fix a race condition when smp task timeout (LP: #1808912) + - scsi: libsas: fix a race condition when smp task timeout + * CVE-2018-14625 + - vhost/vsock: fix use-after-free in network stack callers + * Fix and issue that LG I2C touchscreen stops working after reboot + (LP: #1805085) + - HID: i2c-hid: Disable runtime PM for LG touchscreen + * powerpc/powernv/pci: Work around races in PCI bridge enabling (LP: #1805245) + - powerpc/powernv/pci: Work around races in PCI bridge enabling + * Drivers: hv: vmbus: Offload the handling of channels to two workqueues + (LP: #1807757) + - hv_netvsc: fix network namespace issues with VF support + - hv_netvsc: split sub-channel setup into async and sync + - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer() + - hv_netvsc: Fix a deadlock by getting rtnl lock earlier in netvsc_probe() + - vmbus: don't return values for uninitalized channels + - Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl() + - Drivers: hv: vmbus: Offload the handling of channels to two workqueues + * Disable LPM for Raydium Touchscreens (LP: #1802248) + - USB: quirks: Add no-lpm quirk for Raydium touchscreens + * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network + Adapter (LP: #1805607) + - SAUCE: ath10k: provide reset function for QCA9377 chip + * CVE-2018-17972 + - proc: restrict kernel stack dumps to root + * CVE-2018-19407 + - KVM: X86: Fix scan ioapic use-before-initialization + * CVE-2018-18281 + - mremap: properly flush TLB before releasing the page + * Fix USB2 device wrongly detected as USB1 (LP: #1806534) + - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc + * armhf guests fail to boot in EFI mode (LP: #1809488) + - efi/arm: Revert deferred unmap of early memmap mapping + * Bionic shows incorrect warning about number of pointers in TFD + (LP: #1801102) + - iwlwifi: pcie: don't warn if we use all the transmit pointers + * audio output has constant noise on a Dell machine (LP: #1810891) + - ALSA: hda/realtek - Fixed headphone issue for ALC700 + * ldisc crash on reopened tty (LP: #1791758) + - tty: Drop tty->count on tty_reopen() failure + - tty: Hold tty_ldisc_lock() during tty_reopen() + - tty: Don't block on IO when ldisc change is pending + - tty: Simplify tty->count math in tty_reopen() + * SATA device is not going to DEVSLP (LP: #1781533) + - ahci: Allow setting a default LPM policy for mobile chipsets + - ata: libahci: Correct setting of DEVSLP register + - ata: libahci: Allow reconfigure of DEVSLP register + - ata: ahci: Support state with min power but Partial low power state + - ata: ahci: Enable DEVSLP by default on x86 with SLP_S0 + - [Config] set CONFIG_SATA_MOBILE_LPM_POLICY=0 + * Console got stuck using serial tty after logout (LP: #1808097) + - tty: do not set TTY_IO_ERROR flag if console port + * fanotify10 in ubuntu_ltp_syscalls failed (LP: #1802454) + - fsnotify: fix ignore mask logic in fsnotify() + * SRU: Fix kernel xhci hang when resume from S3 (LP: #1805344) + - usb: xhci: fix uninitialized completion when USB3 port got wrong status + - usb: xhci: fix timeout for transition from RExit to U0 + * Add pointstick support for Cirque Touchpad (LP: #1805081) + - HID: multitouch: Add pointstick support for Cirque Touchpad + * Intel NVMe drives timeout when nvme format is attempted (LP: #1797587) + - nvme: Use admin command effects for admin commands + * lineout jack can't work on a Dell machine (LP: #1810892) + - ALSA: hda/realtek - Support Dell headset mode for New AIO platform + * Bionic update: upstream stable patchset 2019-01-04 (LP: #1810554) + - MIPS: Call dump_stack() from show_regs() + - MIPS: Use async IPIs for arch_trigger_cpumask_backtrace() + - MIPS: Fix ioremap() RAM check + - mmc: sdhci-esdhc-imx: allow 1.8V modes without 100/200MHz pinctrl states + - mmc: dw_mmc: fix card threshold control configuration + - ibmasm: don't write out of bounds in read handler + - staging: rtl8723bs: Prevent an underflow in rtw_check_beacon_data(). + - staging: r8822be: Fix RTL8822be can't find any wireless AP + - ata: Fix ZBC_OUT command block check + - ata: Fix ZBC_OUT all bit handling + - vmw_balloon: fix inflation with batching + - ahci: Disable LPM on Lenovo 50 series laptops with a too old BIOS + - USB: serial: ch341: fix type promotion bug in ch341_control_in() + - USB: serial: cp210x: add another USB ID for Qivicon ZigBee stick + - USB: serial: keyspan_pda: fix modem-status error handling + - USB: serial: mos7840: fix status-register error handling + - usb: quirks: add delay quirks for Corsair Strafe + - xhci: xhci-mem: off by one in xhci_stream_id_to_ring() + - ALSA: hda - Handle pm failure during hotplug + - fs/proc/task_mmu.c: fix Locked field in /proc/pid/smaps* + - fs, elf: make sure to page align bss in load_elf_library + - mm: do not bug_on on incorrect length in __mm_populate() + - tracing: Reorder display of TGID to be after PID + - kbuild: delete INSTALL_FW_PATH from kbuild documentation + - arm64: neon: Fix function may_use_simd() return error status + - tools build: fix # escaping in .cmd files for future Make + - IB/hfi1: Fix incorrect mixing of ERR_PTR and NULL return values + - i2c: tegra: Fix NACK error handling + - iw_cxgb4: correctly enforce the max reg_mr depth + - xen: setup pv irq ops vector earlier + - nvme-pci: Remap CMB SQ entries on every controller reset + - crypto: x86/salsa20 - remove x86 salsa20 implementations + - uprobes/x86: Remove incorrect WARN_ON() in uprobe_init_insn() + - netfilter: nf_queue: augment nfqa_cfg_policy + - netfilter: x_tables: initialise match/target check parameter struct + - loop: add recursion validation to LOOP_CHANGE_FD + - PM / hibernate: Fix oops at snapshot_write() + - RDMA/ucm: Mark UCM interface as BROKEN + - loop: remember whether sysfs_create_group() was done + - f2fs: give message and set need_fsck given broken node id + - mm: do not drop unused pages when userfaultd is running + - bpf: reject passing modified ctx to helper functions + - mei: discard messages from not connected client during power down. + - mm: zero unavailable pages before memmap init + - xen: remove global bit from __default_kernel_pte_mask for pv guests + - f2fs: return error during fill_super + - f2fs: avoid bug_on on corrupted inode + - f2fs: sanity check on sit entry + - f2fs: sanity check for total valid node blocks + - ARM: dts: armada-38x: use the new thermal binding + - mm: don't do zero_resv_unavail if memmap is not allocated + * Blacklist Realtek Virtual IPMI device (LP: #1808353) + - ipmi:pci: Blacklist a Realtek "IPMI" device + * Ethernet[10ec:8136] doesn't work after S3 with kernel 4.15.0.43.64 + (LP: #1809847) + - SAUCE: Revert "r8169: don't use MSI-X on RTL8106e" + - r8169: re-enable MSI-X on RTL8168g + * Killer 802.11ac 2x2 (1550 or 1550i) [8086:2526][1a56:1550] is not supported + (LP: #1809219) + - iwlwifi: add more card IDs for 9000 series + * Support new Realtek ethernet chips (LP: #1811055) + - r8169: Add support for new Realtek Ethernet + * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle + (LP: #1805775) + - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being + disabled + * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF) + (LP: #1804588) + - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + * mpt3sas - driver using the wrong register to update a queue index in FW + (LP: #1810781) + - scsi: mpt3sas: As per MPI-spec, use combined reply queue for SAS3.5 + controllers when HBA supports more than 16 MSI-x vectors. + * HP mobile workstations with hybrid graphics support, can not directly output + to external monitors by dGPU (LP: #1810702) + - ACPI / OSI: Add OEM _OSI string to enable dGPU direct output + * broken touchpad after i2c-i801 blacklist change (LP: #1802135) + - i2c: i801: Don't restore config registers on runtime PM + * Enable new Realtek card reader (LP: #1806335) + - USB: usb-storage: Add new IDs to ums-realtek + - SAUCE: (noup) USB: usb-storage: Make MMC support optional on ums-realtek + * The line-out on the Dell Dock station can't work (LP: #1806532) + - ALSA: usb-audio: Allow to override the longname string + - ALSA: usb-audio: Give proper vendor/product name for Dell WD15 Dock + - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] getabis -- handle all known package combinations + - [Packaging] getabis -- support parsing a simple version + * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818) + - igb: Fix an issue that PME is not enabled during runtime suspend + * Fix Terminus USB hub that may breaks connected USB devices after S3 + (LP: #1806850) + - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub + * Add support for Dell DW5821e WWAN/GPS module (LP: #1807342) + - qmi_wwan: add support for the Dell Wireless 5821e module + - qmi_wwan: fix interface number for DW5821e production firmware + - USB: option: add support for DW5821e + * Add support for 0cf3:535b QCA_ROME device (LP: #1807333) + - Bluetooth: btusb: Add support for 0cf3:535b QCA_ROME device + * The mute led can't work anymore on the lenovo x1 carbon (LP: #1808465) + - ALSA: hda/realtek - Fix the mute LED regresion on Lenovo X1 Carbon + * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) // + click/pop noise in the headphone on several lenovo laptops (LP: #1805079) + - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops + * Touchpad stops working after reboot on Apollo Lake (LP: #1728244) + - HID: i2c-hid: disable runtime PM operations on hantick touchpad + * MAC address pass through on RTL8153-BND for docking station (LP: #1808729) + - r8152: Add support for MAC address pass through on RTL8153-BND + * [Ubuntu] kernel: zcrypt: reinit ap queue state machine (LP: #1805414) + - s390/zcrypt: reinit ap queue state machine during device probe + * [UBUNTU] qeth: fix length check in SNMP processing (LP: #1805802) + - s390/qeth: fix length check in SNMP processing + * ASPEED server console output extremely slow after upgrade to 18.04 + (LP: #1808183) + - drm/ast: Remove existing framebuffers before loading driver + * Bionic update: upstream stable patchset 2018-12-13 (LP: #1808399) + - userfaultfd: hugetlbfs: fix userfaultfd_huge_must_wait() pte access + - mm: hugetlb: yield when prepping struct pages + - tracing: Fix missing return symbol in function_graph output + - scsi: target: Fix truncated PR-in ReadKeys response + - s390: Correct register corruption in critical section cleanup + - drbd: fix access after free + - vfio: Use get_user_pages_longterm correctly + - cifs: Fix use after free of a mid_q_entry + - cifs: Fix memory leak in smb2_set_ea() + - cifs: Fix infinite loop when using hard mount option + - drm: Use kvzalloc for allocating blob property memory + - drm/udl: fix display corruption of the last line + - jbd2: don't mark block as modified if the handle is out of credits + - ext4: add corruption check in ext4_xattr_set_entry() + - ext4: always verify the magic number in xattr blocks + - ext4: make sure bitmaps and the inode table don't overlap with bg + descriptors + - ext4: always check block group bounds in ext4_init_block_bitmap() + - ext4: only look at the bg_flags field if it is valid + - ext4: verify the depth of extent tree in ext4_find_extent() + - ext4: include the illegal physical block in the bad map ext4_error msg + - ext4: never move the system.data xattr out of the inode body + - ext4: avoid running out of journal credits when appending to an inline file + - ext4: add more inode number paranoia checks + - ext4: add more mount time checks of the superblock + - ext4: check superblock mapped prior to committing + - HID: i2c-hid: Fix "incomplete report" noise + - HID: hiddev: fix potential Spectre v1 + - HID: debug: check length before copy_to_user() + - media: vb2: core: Finish buffers at the end of the stream + - f2fs: truncate preallocated blocks in error case + - Revert "dpaa_eth: fix error in dpaa_remove()" + - Kbuild: fix # escaping in .cmd files for future Make + - media: cx25840: Use subdev host data for PLL override + - fs: allow per-device dax status checking for filesystems + - dax: change bdev_dax_supported() to support boolean returns + - dax: check for QUEUE_FLAG_DAX in bdev_dax_supported() + - dm: set QUEUE_FLAG_DAX accordingly in dm_table_set_restrictions() + - dm: prevent DAX mounts if not supported + - mtd: cfi_cmdset_0002: Change definition naming to retry write operation + - mtd: cfi_cmdset_0002: Change erase functions to retry for error + - mtd: cfi_cmdset_0002: Change erase functions to check chip good only + - netfilter: nf_log: don't hold nf_log_mutex during user access + - staging: comedi: quatech_daqp_cs: fix no-op loop daqp_ao_insn_write() + - sched, tracing: Fix trace_sched_pi_setprio() for deboosting + - PCI / ACPI / PM: Resume bridges w/o drivers on suspend-to-RAM + - drm/amdgpu: Make struct amdgpu_atif private to amdgpu_acpi.c + - scsi: aacraid: Fix PD performance regression over incorrect qd being set + - ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl + - drm/amdgpu: Add amdgpu_atpx_get_dhandle() + - drm/amdgpu: Dynamically probe for ATIF handle (v2) + - i2c: core: smbus: fix a potential missing-check bug + * Bionic update: upstream stable patchset 2018-12-12 (LP: #1808185) + - usb: cdc_acm: Add quirk for Uniden UBC125 scanner + - USB: serial: cp210x: add CESINEL device ids + - USB: serial: cp210x: add Silicon Labs IDs for Windows Update + - usb: dwc2: fix the incorrect bitmaps for the ports of multi_tt hub + - acpi: Add helper for deactivating memory region + - usb: typec: ucsi: acpi: Workaround for cache mode issue + - usb: typec: ucsi: Fix for incorrect status data issue + - xhci: Fix kernel oops in trace_xhci_free_virt_device + - n_tty: Fix stall at n_tty_receive_char_special(). + - n_tty: Access echo_* variables carefully. + - staging: android: ion: Return an ERR_PTR in ion_map_kernel + - serial: 8250_pci: Remove stalled entries in blacklist + - serdev: fix memleak on module unload + - vt: prevent leaking uninitialized data to userspace via /dev/vcs* + - drm/amdgpu: Add APU support in vi_set_uvd_clocks + - drm/amdgpu: Add APU support in vi_set_vce_clocks + - drm/amdgpu: fix the missed vcn fw version report + - drm/qxl: Call qxl_bo_unref outside atomic context + - drm/atmel-hlcdc: check stride values in the first plane + - drm/amdgpu: Use kvmalloc_array for allocating VRAM manager nodes array + - drm/amdgpu: Refactor amdgpu_vram_mgr_bo_invisible_size helper + - drm/i915: Enable provoking vertex fix on Gen9 systems. + - netfilter: nf_tables: nft_compat: fix refcount leak on xt module + - netfilter: nft_compat: prepare for indirect info storage + - netfilter: nft_compat: fix handling of large matchinfo size + - netfilter: nf_tables: don't assume chain stats are set when jumplabel is set + - netfilter: nf_tables: bogus EBUSY in chain deletions + - netfilter: nft_meta: fix wrong value dereference in nft_meta_set_eval + - netfilter: nf_tables: disable preemption in nft_update_chain_stats() + - netfilter: nf_tables: increase nft_counters_enabled in + nft_chain_stats_replace() + - netfilter: nf_tables: fix memory leak on error exit return + - netfilter: nf_tables: add missing netlink attrs to policies + - netfilter: nf_tables: fix NULL-ptr in nf_tables_dump_obj() + - netfilter: don't set F_IFACE on ipv6 fib lookups + - netfilter: ip6t_rpfilter: provide input interface for route lookup + - netfilter: nf_tables: use WARN_ON_ONCE instead of BUG_ON in nft_do_chain() + - ARM: dts: imx6q: Use correct SDMA script for SPI5 core + - xfrm6: avoid potential infinite loop in _decode_session6() + - afs: Fix directory permissions check + - netfilter: ebtables: handle string from userspace with care + - s390/dasd: use blk_mq_rq_from_pdu for per request data + - netfilter: nft_limit: fix packet ratelimiting + - ipvs: fix buffer overflow with sync daemon and service + - iwlwifi: pcie: compare with number of IRQs requested for, not number of CPUs + - atm: zatm: fix memcmp casting + - net: qmi_wwan: Add Netgear Aircard 779S + - perf test: "Session topology" dumps core on s390 + - perf bpf: Fix NULL return handling in bpf__prepare_load() + - fs: clear writeback errors in inode_init_always + - sched/core: Fix rules for running on online && !active CPUs + - sched/core: Require cpu_active() in select_task_rq(), for user tasks + - platform/x86: asus-wmi: Fix NULL pointer dereference + - net/sonic: Use dma_mapping_error() + - net: dsa: b53: Add BCM5389 support + - usb: typec: tcpm: fix logbuffer index is wrong if _tcpm_log is re-entered + - iio: mma8452: Fix ignoring MMA8452_INT_DRDY + - drm/amdgpu: fix clear_all and replace handling in the VM (v2) + - drm/amd/display: Clear connector's edid pointer + - drm/i915/dp: Send DPCD ON for MST before phy_up + - drm/amdgpu: remove DC special casing for KB/ML + - drm/amdgpu: Don't default to DC support for Kaveri and older + - drm/amdgpu: GPU vs CPU page size fixes in amdgpu_vm_bo_split_mapping + - drm/amd/display: release spinlock before committing updates to stream + - drm/i915: Fix PIPESTAT irq ack on i965/g4x + - ARM64: dts: meson-gxl-s905x-p212: Add phy-supply for usb0 + - x86/mm: Don't free P4D table when it is folded at runtime + * Bionic update: upstream stable patchset 2018-12-07 (LP: #1807469) + - x86/spectre_v1: Disable compiler optimizations over + array_index_mask_nospec() + - x86/mce: Improve error message when kernel cannot recover + - x86/mce: Check for alternate indication of machine check recovery on Skylake + - x86/mce: Fix incorrect "Machine check from unknown source" message + - x86/mce: Do not overwrite MCi_STATUS in mce_no_way_out() + - x86: Call fixup_exception() before notify_die() in math_error() + - m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap() + - m68k/mac: Fix SWIM memory resource end address + - serial: sh-sci: Use spin_{try}lock_irqsave instead of open coding version + - signal/xtensa: Consistenly use SIGBUS in do_unaligned_user + - PM / Domains: Fix error path during attach in genpd + - PM / core: Fix supplier device runtime PM usage counter imbalance + - PM / OPP: Update voltage in case freq == old_freq + - usb: do not reset if a low-speed or full-speed device timed out + - 1wire: family module autoload fails because of upper/lower case mismatch. + - ASoC: dapm: delete dapm_kcontrol_data paths list before freeing it + - ASoC: cs35l35: Add use_single_rw to regmap config + - ASoC: cirrus: i2s: Fix LRCLK configuration + - ASoC: cirrus: i2s: Fix {TX|RX}LinCtrlData setup + - thermal: bcm2835: Stop using printk format %pCr + - clk: renesas: cpg-mssr: Stop using printk format %pCr + - lib/vsprintf: Remove atomic-unsafe support for %pCr + - ftrace/selftest: Have the reset_trigger code be a bit more careful + - mips: ftrace: fix static function graph tracing + - branch-check: fix long->int truncation when profiling branches + - ipmi:bt: Set the timeout before doing a capabilities check + - Bluetooth: hci_qca: Avoid missing rampatch failure with userspace fw loader + - printk: fix possible reuse of va_list variable + - fuse: fix congested state leak on aborted connections + - fuse: atomic_o_trunc should truncate pagecache + - fuse: don't keep dead fuse_conn at fuse_fill_super(). + - fuse: fix control dir setup and teardown + - powerpc/mm/hash: Add missing isync prior to kernel stack SLB switch + - powerpc/ptrace: Fix setting 512B aligned breakpoints with + PTRACE_SET_DEBUGREG + - powerpc/ptrace: Fix enforcement of DAWR constraints + - powerpc/powernv/ioda2: Remove redundant free of TCE pages + - powerpc/powernv: copy/paste - Mask SO bit in CR + - powerpc/fadump: Unregister fadump on kexec down path. + - soc: rockchip: power-domain: Fix wrong value when power up pd with writemask + - ARM: 8764/1: kgdb: fix NUMREGBYTES so that gdb_regs[] is the correct size + - ARM: dts: Fix SPI node for Arria10 + - ARM: dts: socfpga: Fix NAND controller node compatible + - ARM: dts: socfpga: Fix NAND controller clock supply + - ARM: dts: socfpga: Fix NAND controller node compatible for Arria10 + - arm64: Fix syscall restarting around signal suppressed by tracer + - arm64: kpti: Use early_param for kpti= command-line option + - arm64: mm: Ensure writes to swapper are ordered wrt subsequent cache + maintenance + - ARM64: dts: meson: disable sd-uhs modes on the libretech-cc + - of: overlay: validate offset from property fixups + - of: unittest: for strings, account for trailing \0 in property length field + - of: platform: stop accessing invalid dev in of_platform_device_destroy + - tpm: fix use after free in tpm2_load_context() + - tpm: fix race condition in tpm_common_write() + - IB/qib: Fix DMA api warning with debug kernel + - IB/{hfi1, qib}: Add handling of kernel restart + - IB/mlx4: Mark user MR as writable if actual virtual memory is writable + - IB/core: Make testing MR flags for writability a static inline function + - IB/mlx5: Fetch soft WQE's on fatal error state + - IB/isert: Fix for lib/dma_debug check_sync warning + - IB/isert: fix T10-pi check mask setting + - IB/hfi1: Fix fault injection init/exit issues + - IB/hfi1: Reorder incorrect send context disable + - IB/hfi1: Optimize kthread pointer locking when queuing CQ entries + - IB/hfi1: Fix user context tail allocation for DMA_RTAIL + - RDMA/mlx4: Discard unknown SQP work requests + - xprtrdma: Return -ENOBUFS when no pages are available + - mtd: cfi_cmdset_0002: Change write buffer to check correct value + - mtd: cfi_cmdset_0002: Use right chip in do_ppb_xxlock() + - mtd: cfi_cmdset_0002: fix SEGV unlocking multiple chips + - mtd: cfi_cmdset_0002: Fix unlocking requests crossing a chip boudary + - mtd: cfi_cmdset_0002: Avoid walking all chips when unlocking. + - PCI: hv: Make sure the bus domain is really unique + - PCI: Add ACS quirk for Intel 7th & 8th Gen mobile + - PCI: pciehp: Clear Presence Detect and Data Link Layer Status Changed on + resume + - auxdisplay: fix broken menu + - pinctrl: samsung: Correct EINTG banks order + - pinctrl: devicetree: Fix pctldev pointer overwrite + - cpufreq: intel_pstate: Fix scaling max/min limits with Turbo 3.0 + - MIPS: io: Add barrier after register read in inX() + - time: Make sure jiffies_to_msecs() preserves non-zero time periods + - irqchip/gic-v3-its: Don't bind LPI to unavailable NUMA node + - X.509: unpack RSA signatureValue field from BIT STRING + - Btrfs: fix return value on rename exchange failure + - iio: adc: ad7791: remove sample freq sysfs attributes + - iio: sca3000: Fix an error handling path in 'sca3000_probe()' + - mm: fix __gup_device_huge vs unmap + - scsi: qla2xxx: Fix setting lower transfer speed if GPSC fails + - scsi: qla2xxx: Mask off Scope bits in retry delay + - scsi: zfcp: fix missing SCSI trace for result of eh_host_reset_handler + - scsi: zfcp: fix missing SCSI trace for retry of abort / scsi_eh TMF + - scsi: zfcp: fix misleading REC trigger trace where erp_action setup failed + - scsi: zfcp: fix missing REC trigger trace on terminate_rport_io early return + - scsi: zfcp: fix missing REC trigger trace on terminate_rport_io for + ERP_FAILED + - scsi: zfcp: fix missing REC trigger trace for all objects in ERP_FAILED + - scsi: zfcp: fix missing REC trigger trace on enqueue without ERP thread + - linvdimm, pmem: Preserve read-only setting for pmem devices + - clk: at91: PLL recalc_rate() now using cached MUL and DIV values + - rtc: sun6i: Fix bit_idx value for clk_register_gate + - md: fix two problems with setting the "re-add" device state. + - rpmsg: smd: do not use mananged resources for endpoints and channels + - ubi: fastmap: Cancel work upon detach + - ubi: fastmap: Correctly handle interrupted erasures in EBA + - backlight: as3711_bl: Fix Device Tree node lookup + - backlight: max8925_bl: Fix Device Tree node lookup + - backlight: tps65217_bl: Fix Device Tree node lookup + - mfd: intel-lpss: Program REMAP register in PIO mode + - arm: dts: mt7623: fix invalid memory node being generated + - perf tools: Fix symbol and object code resolution for vdso32 and vdsox32 + - perf intel-pt: Fix sync_switch INTEL_PT_SS_NOT_TRACING + - perf intel-pt: Fix decoding to accept CBR between FUP and corresponding TIP + - perf intel-pt: Fix MTC timing after overflow + - perf intel-pt: Fix "Unexpected indirect branch" error + - perf intel-pt: Fix packet decoding of CYC packets + - media: vsp1: Release buffers for each video node + - media: v4l2-compat-ioctl32: prevent go past max size + - media: dvb_frontend: fix locking issues at dvb_frontend_get_event() + - nfsd: restrict rd_maxcount to svc_max_payload in nfsd_encode_readdir + - NFSv4: Fix possible 1-byte stack overflow in + nfs_idmap_read_and_verify_message + - NFSv4: Revert commit 5f83d86cf531d ("NFSv4.x: Fix wraparound issues..") + - NFSv4: Fix a typo in nfs41_sequence_process + - ACPI / LPSS: Add missing prv_offset setting for byt/cht PWM devices + - Input: elan_i2c - add ELAN0618 (Lenovo v330 15IKB) ACPI ID + - pwm: lpss: platform: Save/restore the ctrl register over a suspend/resume + - rbd: flush rbd_dev->watch_dwork after watch is unregistered + - mm/ksm.c: ignore STABLE_FLAG of rmap_item->address in rmap_walk_ksm() + - mm: fix devmem_is_allowed() for sub-page System RAM intersections + - xen: Remove unnecessary BUG_ON from __unbind_from_irq() + - udf: Detect incorrect directory size + - Input: xpad - fix GPD Win 2 controller name + - Input: elan_i2c_smbus - fix more potential stack buffer overflows + - ALSA: timer: Fix UBSAN warning at SNDRV_TIMER_IOCTL_NEXT_DEVICE ioctl + - ALSA: hda/realtek - Fix pop noise on Lenovo P50 & co + - ALSA: hda/realtek - Add a quirk for FSC ESPRIMO U9210 + - slub: fix failure when we delete and create a slab cache + - block: Fix transfer when chunk sectors exceeds max + - block: Fix cloning of requests with a special payload + - x86/efi: Fix efi_call_phys_epilog() with CONFIG_X86_5LEVEL=y + - dm zoned: avoid triggering reclaim from inside dmz_map() + - dm thin: handle running out of data space vs concurrent discard + - x86/platform/UV: Use new set memory block size function + - x86/platform/UV: Add kernel parameter to set memory block size + - platform/chrome: cros_ec_lpc: Register the driver if ACPI entry is missing. + - platform/chrome: cros_ec_lpc: do not try DMI match when ACPI device found + - hwmon: (k10temp) Add support for Stoney Ridge and Bristol Ridge CPUs + - spi-nor: intel-spi: Remove unused preopcodes field + - mtd: spi-nor: intel-spi: Fix atomic sequence handling + - PCI / PM: Do not clear state_saved for devices that remain suspended + - ASoC: mediatek: preallocate pages use platform device + - libnvdimm, pmem: Do not flush power-fail protected CPU caches + - powerpc/64s: Set assembler machine type to POWER4 + - powerpc/e500mc: Set assembler machine type to e500mc + - hwrng: core - Always drop the RNG in hwrng_unregister() + - softirq: Reorder trace_softirqs_on to prevent lockdep splat + - ARM64: dts: meson-gx: fix ATF reserved memory region + - mtd: rawnand: fix return value check for bad block status + - mtd: rawnand: mxc: set spare area size register explicitly + - PCI: Account for all bridges on bus when distributing bus numbers + - pinctrl: armada-37xx: Fix spurious irq management + - MIPS: pb44: Fix i2c-gpio GPIO descriptor table + - locking/rwsem: Fix up_read_non_owner() warning with DEBUG_RWSEMS + - scsi: scsi_debug: Fix memory leak on module unload + - scsi: qla2xxx: Spinlock recursion in qla_target + - libnvdimm, pmem: Unconditionally deep flush on *sync + - f2fs: don't use GFP_ZERO for page caches + - mfd: twl-core: Fix clock initialization + - remoteproc: Prevent incorrect rproc state on xfer mem ownership failure + - media: rc: mce_kbd decoder: fix stuck keys + - Input: silead - add Chuwi Hi8 support + - Input: silead - add MSSL0002 ACPI HID + - ALSA: hda - Force to link down at runtime suspend on ATI/AMD HDMI + - i2c: gpio: initialize SCL to HIGH again + - kasan: depend on CONFIG_SLUB_DEBUG + - dm: ensure bio submission follows a depth-first tree walk + - dm: rename 'bio' member of dm_io structure to 'orig_bio' + - dm: use bio_split() when splitting out the already processed bio + - x86/e820: put !E820_TYPE_RAM regions into memblock.reserved + * Support AverMedia DVD EZMaker 7 USB video capture dongle (LP: #1620762) // + Bionic update: upstream stable patchset 2018-12-07 (LP: #1807469) + - media: cx231xx: Add support for AverMedia DVD EZMaker 7 + + -- Kleber Sacilotto de Souza Tue, 15 Jan 2019 11:45:59 +0000 + +linux-oracle (4.15.0-1007.9) bionic; urgency=medium + + * linux-oracle: 4.15.0-1007.9 -proposed tracker (LP: #1807702) + + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Config] buildinfo -- add retpoline version markers + + * Skip enslaved devices during boot (LP: #1802591) + - [Packaging] initramfs-tools -- include custom hooks for a kernel + - [Packaging] linux-oracle: add initramfs hook to skip enslaved devices + - [Packaging] linux-oracle: Force initramfs-tools >= 0.130ubuntu3.6 + + * Packaging resync (LP: #1786013) + - [Packaging] update update.conf + + [ Ubuntu: 4.15.0-43.46 ] + + * linux: 4.15.0-43.46 -proposed tracker (LP: #1806659) + * System randomly hangs during suspend when mei_wdt is loaded (LP: #1803942) + - SAUCE: base/dd: limit release function changes to vfio driver only + * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838) + - xhci: Allow more than 32 quirks + - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC + * linux-buildinfo: pull out ABI information into its own package + (LP: #1806380) + - [Packaging] limit preparation to linux-libc-dev in headers + - [Packaging] commonise debhelper invocation + - [Packaging] ABI -- accumulate abi information at the end of the build + - [Packaging] buildinfo -- add basic build information + - [Packaging] buildinfo -- add firmware information to the flavour ABI + - [Packaging] buildinfo -- add compiler information to the flavour ABI + - [Packaging] buildinfo -- add buildinfo support to getabis + - [Config] buildinfo -- add retpoline version markers + * linux packages should own /usr/lib/linux/triggers (LP: #1770256) + - [Packaging] own /usr/lib/linux/triggers + * CVE-2018-12896 + - posix-timers: Sanitize overrun handling + * CVE-2018-16276 + - USB: yurex: fix out-of-bounds uaccess in read handler + * CVE-2018-10902 + - ALSA: rawmidi: Change resized buffers atomically + * CVE-2018-18710 + - cdrom: fix improper type cast, which can leat to information leak. + * CVE-2018-18690 + - xfs: don't fail when converting shortform attr to long form during + ATTR_REPLACE + * CVE-2018-14734 + - infiniband: fix a possible use-after-free bug + * CVE-2018-18445 + - bpf: 32-bit RSH verification must truncate input before the ALU op + * Packaging resync (LP: #1786013) + - [Packaging] update helper scripts + + -- Marcelo Henrique Cerri Wed, 12 Dec 2018 16:48:11 -0200 + +linux-oracle (4.15.0-1006.6) bionic; urgency=medium + + * linux-oracle: 4.15.0-1006.6 -proposed tracker (LP: #1806098) + + [ Ubuntu: 4.15.0-42.45 ] + + * linux: 4.15.0-42.45 -proposed tracker (LP: #1803592) + * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405) + - KVM: s390: reset crypto attributes for all vcpus + - KVM: s390: vsie: simulate VCPU SIE entry/exit + - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART + - KVM: s390: refactor crypto initialization + - s390: vfio-ap: base implementation of VFIO AP device driver + - s390: vfio-ap: register matrix device with VFIO mdev framework + - s390: vfio-ap: sysfs interfaces to configure adapters + - s390: vfio-ap: sysfs interfaces to configure domains + - s390: vfio-ap: sysfs interfaces to configure control domains + - s390: vfio-ap: sysfs interface to view matrix mdev matrix + - KVM: s390: interface to clear CRYCB masks + - s390: vfio-ap: implement mediated device open callback + - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl + - s390: vfio-ap: zeroize the AP queues + - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl + - KVM: s390: Clear Crypto Control Block when using vSIE + - KVM: s390: vsie: Do the CRYCB validation first + - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear + - KVM: s390: vsie: Allow CRYCB FORMAT-2 + - KVM: s390: vsie: allow CRYCB FORMAT-1 + - KVM: s390: vsie: allow CRYCB FORMAT-0 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1 + - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2 + - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2 + - KVM: s390: device attrs to enable/disable AP interpretation + - KVM: s390: CPU model support for AP virtualization + - s390: doc: detailed specifications for AP virtualization + - KVM: s390: fix locking for crypto setting error path + - KVM: s390: Tracing APCB changes + - s390: vfio-ap: setup APCB mask using KVM dedicated function + - s390/zcrypt: Add ZAPQ inline function. + - s390/zcrypt: Review inline assembler constraints. + - s390/zcrypt: Integrate ap_asm.h into include/asm/ap.h. + - s390/zcrypt: fix ap_instructions_available() returncodes + - s390/zcrypt: remove VLA usage from the AP bus + - s390/zcrypt: Remove deprecated ioctls. + - s390/zcrypt: Remove deprecated zcrypt proc interface. + - s390/zcrypt: Support up to 256 crypto adapters. + - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module. + * Bypass of mount visibility through userns + mount propagation (LP: #1789161) + - mount: Retest MNT_LOCKED in do_umount + - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts + * CVE-2018-18955: nested user namespaces with more than five extents + incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955 + - userns: also map extents in the reverse map to kernel IDs + * kdump fail due to an IRQ storm (LP: #1797990) + - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code + - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot + - SAUCE: x86/quirks: Scan all busses for early PCI quirks + + [ Ubuntu: 4.15.0-40.43 ] + + * linux: 4.15.0-40.43 -proposed tracker (LP: #1802554) + * crash in ENA driver on removing an interface (LP: #1802341) + - SAUCE: net: ena: fix crash during ena_remove() + * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding + (LP: #1797367) + - s390/qeth: don't keep track of MAC address's cast type + - s390/qeth: consolidate qeth MAC address helpers + - s390/qeth: avoid using is_multicast_ether_addr_64bits on (u8 *)[6] + - s390/qeth: remove outdated portname debug msg + - s390/qeth: reduce hard-coded access to ccw channels + - s390/qeth: sanitize strings in debug messages + * [18.04 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver + binding (LP: #1799184) + - s390/zcrypt: code beautify + - s390/zcrypt: AP bus support for alternate driver(s) + - s390/zcrypt: hex string mask improvements for apmask and aqmask. + - s390/zcrypt: remove unused functions and declarations + - s390/zcrypt: Show load of cards and queues in sysfs + * [GLK/CLX] Enhanced IBRS (LP: #1786139) + - x86/speculation: Remove SPECTRE_V2_IBRS in enum spectre_v2_mitigation + - x86/speculation: Support Enhanced IBRS on future CPUs + * Allow signed kernels to be kexec'ed under lockdown (LP: #1798441) + - Fix kexec forbidding kernels signed with keys in the secondary keyring to + boot + * Overlayfs in user namespace leaks directory content of inaccessible + directories (LP: #1793458) // CVE-2018-6559 + - SAUCE: overlayfs: ensure mounter privileges when reading directories + * Update ENA driver to version 2.0.1K (LP: #1798182) + - net: ena: remove ndo_poll_controller + - net: ena: fix warning in rmmod caused by double iounmap + - net: ena: fix rare bug when failed restart/resume is followed by driver + removal + - net: ena: fix NULL dereference due to untimely napi initialization + - net: ena: fix auto casting to boolean + - net: ena: minor performance improvement + - net: ena: complete host info to match latest ENA spec + - net: ena: introduce Low Latency Queues data structures according to ENA spec + - net: ena: add functions for handling Low Latency Queues in ena_com + - net: ena: add functions for handling Low Latency Queues in ena_netdev + - net: ena: use CSUM_CHECKED device indication to report skb's checksum status + - net: ena: explicit casting and initialization, and clearer error handling + - net: ena: limit refill Rx threshold to 256 to avoid latency issues + - net: ena: change rx copybreak default to reduce kernel memory pressure + - net: ena: remove redundant parameter in ena_com_admin_init() + - net: ena: update driver version to 2.0.1 + - net: ena: fix indentations in ena_defs for better readability + - net: ena: Fix Kconfig dependency on X86 + - net: ena: enable Low Latency Queues + - net: ena: fix compilation error in xtensa architecture + * Bionic update: upstream stable patchset 2018-10-29 (LP: #1800537) + - bonding: re-evaluate force_primary when the primary slave name changes + - cdc_ncm: avoid padding beyond end of skb + - ipv6: allow PMTU exceptions to local routes + - net: dsa: add error handling for pskb_trim_rcsum + - net/sched: act_simple: fix parsing of TCA_DEF_DATA + - tcp: verify the checksum of the first data segment in a new connection + - udp: fix rx queue len reported by diag and proc interface + - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds + vlan + - tls: fix use-after-free in tls_push_record + - ext4: fix hole length detection in ext4_ind_map_blocks() + - ext4: update mtime in ext4_punch_hole even if no blocks are released + - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget() + - ext4: fix fencepost error in check for inode count overflow during resize + - driver core: Don't ignore class_dir_create_and_add() failure. + - Btrfs: fix clone vs chattr NODATASUM race + - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2() + - btrfs: return error value if create_io_em failed in cow_file_range + - btrfs: scrub: Don't use inode pages for device replace + - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation + - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream() + - ALSA: hda: add dock and led support for HP EliteBook 830 G5 + - ALSA: hda: add dock and led support for HP ProBook 640 G4 + - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read() + - smb3: fix various xid leaks + - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session + expiry + - cifs: For SMB2 security informaion query, check for minimum sized security + descriptor instead of sizeof FileAllInformation class + - nbd: fix nbd device deletion + - nbd: update size when connected + - nbd: use bd_set_size when updating disk size + - blk-mq: reinit q->tag_set_list entry only after grace period + - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue + - cpufreq: Fix new policy initialization during limits updates via sysfs + - cpufreq: governors: Fix long idle detection logic in load calculation + - libata: zpodd: small read overflow in eject_tray() + - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk + - w1: mxc_w1: Enable clock before calling clk_get_rate() on it + - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping + - iwlwifi: fw: harden page loading code + - orangefs: set i_size on new symlink + - orangefs: report attributes_mask and attributes for statx + - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation + - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large + - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset + - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620 + - cpufreq: ti-cpufreq: Fix an incorrect error return value + - x86/vector: Fix the args of vector_alloc tracepoint + - x86/apic/vector: Prevent hlist corruption and leaks + - x86/apic: Provide apic_ack_irq() + - x86/ioapic: Use apic_ack_irq() + - x86/platform/uv: Use apic_ack_irq() + - irq_remapping: Use apic_ack_irq() + - genirq/generic_pending: Do not lose pending affinity update + - genirq/affinity: Defer affinity setting if irq chip is busy + - genirq/migration: Avoid out of line call if pending is not set + * [bionic]mlx5: reading SW stats through ifstat cause kernel crash + (LP: #1799049) + - net/mlx5e: Don't attempt to dereference the ppriv struct if not being + eswitch manager + * [Bionic][Cosmic] ipmi: Fix timer race with module unload (LP: #1799281) + - ipmi: Fix timer race with module unload + * [Bionic] ipmi: Remove ACPI SPMI probing from the SSIF (I2C) driver + (LP: #1799276) + - ipmi: Remove ACPI SPMI probing from the SSIF (I2C) driver + * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729) + - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias() + * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater + than 255 bytes (LP: #1799794) + - ipmi:ssif: Add support for multi-part transmit messages > 2 parts + * libvirtd is unable to configure bridge devices inside of LXD containers + (LP: #1784501) + - kernfs: allow creating kernfs objects with arbitrary uid/gid + - sysfs, kobject: allow creating kobject belonging to arbitrary users + - kobject: kset_create_and_add() - fetch ownership info from parent + - driver core: set up ownership of class devices in sysfs + - net-sysfs: require net admin in the init ns for setting tx_maxrate + - net-sysfs: make sure objects belong to container's owner + - net: create reusable function for getting ownership info of sysfs inodes + - bridge: make sure objects belong to container's owner + - sysfs: Fix regression when adding a file to an existing group + * [Ubuntu] kvm: fix deadlock when killed by oom (LP: #1800849) + - s390/kvm: fix deadlock when killed by oom + * [Ubuntu] net/af_iucv: fix skb leaks for HiperTransport (LP: #1800639) + - net/af_iucv: drop inbound packets with invalid flags + - net/af_iucv: fix skb handling on HiperTransport xmit error + * Power consumption during s2idle is higher than long idle(sk hynix) + (LP: #1801875) + - SAUCE: pci: prevent sk hynix nvme from entering D3 + - SAUCE: nvme: add quirk to not call disable function when suspending + * Enable keyboard wakeup for S2Idle laptops (LP: #1798552) + - Input: i8042 - enable keyboard wakeups by default when s2idle is used + * NULL pointer dereference at 0000000000000020 when access + dst_orig->ops->family in function xfrm_lookup_with_ifid() (LP: #1801878) + - xfrm: Fix NULL pointer dereference when skb_dst_force clears the dst_entry. + * [Ubuntu] qdio: reset old sbal_state flags (LP: #1801686) + - s390/qdio: reset old sbal_state flags + * hns3: map tx ring to tc (LP: #1802023) + - net: hns3: Set tx ring' tc info when netdev is up + * [Ubuntu] qeth: Fix potential array overrun in cmd/rc lookup (LP: #1800641) + - s390: qeth_core_mpc: Use ARRAY_SIZE instead of reimplementing its function + - s390: qeth: Fix potential array overrun in cmd/rc lookup + * Vulkan applications cause permanent memory leak with Intel GPU + (LP: #1798165) + - drm/syncobj: Don't leak fences when WAIT_FOR_SUBMIT is set + * Mounting SOFS SMB shares fails (LP: #1792580) + - cifs: connect to servername instead of IP for IPC$ share + * Packaging resync (LP: #1786013) + - [Package] add support for specifying the primary makefile + + -- Marcelo Henrique Cerri Fri, 30 Nov 2018 15:33:38 -0200 + +linux-oracle (4.15.0-1005.5) bionic; urgency=medium + + * linux-oracle: 4.15.0-1005.5 -proposed tracker (LP: #1799800) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to Ubuntu-4.15.0-39.42 + + [ Ubuntu: 4.15.0-39.42 ] + + * linux: 4.15.0-39.42 -proposed tracker (LP: #1799411) + * Linux: insufficient shootdown for paging-structure caches (LP: #1798897) + - mm: move tlb_table_flush to tlb_flush_mmu_free + - mm/tlb: Remove tlb_remove_table() non-concurrent condition + - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE + - [Config] CONFIG_HAVE_RCU_TABLE_INVALIDATE=y + * Ubuntu18.04: GPU total memory is reduced (LP: #1792102) + - Revert "powerpc/powernv: Increase memory block size to 1GB on radix" + * arm64: snapdragon: reduce boot noise (LP: #1797154) + - [Config] arm64: snapdragon: DRM_MSM=m + - [Config] arm64: snapdragon: SND*=m + - [Config] arm64: snapdragon: disable ARM_SDE_INTERFACE + - [Config] arm64: snapdragon: disable DRM_I2C_ADV7511_CEC + - [Config] arm64: snapdragon: disable VIDEO_ADV7511, VIDEO_COBALT + * [Bionic] CPPC bug fixes (LP: #1796949) + - ACPI / CPPC: Update all pr_(debug/err) messages to log the susbspace id + - cpufreq: CPPC: Don't set transition_latency + - ACPI / CPPC: Fix invalid PCC channel status errors + * regression in 'ip --family bridge neigh' since linux v4.12 (LP: #1796748) + - rtnetlink: fix rtnl_fdb_dump() for ndmsg header + * screen displays abnormally on the lenovo M715 with the AMD GPU (Radeon Vega + 8 Mobile, rev ca, 1002:15dd) (LP: #1796786) + - drm/amd/display: Fix takover from VGA mode + - drm/amd/display: early return if not in vga mode in disable_vga + - drm/amd/display: Refine disable VGA + * arm64: snapdragon: WARNING: CPU: 0 PID: 1 arch/arm64/kernel/setup.c:271 + reserve_memblock_reserved_regions (LP: #1797139) + - SAUCE: arm64: Fix /proc/iomem for reserved but not memory regions + * The front MIC can't work on the Lenovo M715 (LP: #1797292) + - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715 + * Keyboard backlight sysfs sometimes is missing on Dell laptops (LP: #1797304) + - platform/x86: dell-smbios: Correct some style warnings + - platform/x86: dell-smbios: Rename dell-smbios source to dell-smbios-base + - platform/x86: dell-smbios: Link all dell-smbios-* modules together + - [Config] CONFIG_DELL_SMBIOS_SMM=y, CONFIG_DELL_SMBIOS_WMI=y + * rpi3b+: ethernet not working (LP: #1797406) + - lan78xx: Don't reset the interface on open + * 87cdf3148b11 was never backported to 4.15 (LP: #1795653) + - xfrm: Verify MAC header exists before overwriting eth_hdr(skb)->h_proto + * [Ubuntu18.04][Power9][DD2.2]package installation segfaults inside debian + chroot env in P9 KVM guest with HTM enabled (kvm) (LP: #1792501) + - KVM: PPC: Book3S HV: Fix guest r11 corruption with POWER9 TM workarounds + * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957) + - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same + VM + * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314) + - SAUCE: fscache: Fix race in decrementing refcount of op->npages + * CVE-2018-9363 + - Bluetooth: hidp: buffer overflow in hidp_process_report + * CVE-2017-13168 + - scsi: sg: mitigate read/write abuse + * [Bionic] ACPI / PPTT: use ACPI ID whenever ACPI_PPTT_ACPI_PROCESSOR_ID_VALID + is set (LP: #1797200) + - ACPI / PPTT: use ACPI ID whenever ACPI_PPTT_ACPI_PROCESSOR_ID_VALID is set + * [Bionic] arm64: topology: Avoid checking numa mask for scheduler MC + selection (LP: #1797202) + - arm64: topology: Avoid checking numa mask for scheduler MC selection + * crypto/vmx - Backport of Fix sleep-in-atomic bugs patch for 18.04 + (LP: #1790832) + - crypto: vmx - Fix sleep-in-atomic bugs + * hns3: autoneg settings get lost on down/up (LP: #1797654) + - net: hns3: Fix for information of phydev lost problem when down/up + * not able to unwind the stack from within __kernel_clock_gettime in the Linux + vDSO (LP: #1797963) + - powerpc/vdso: Correct call frame information + * Signal 7 error when running GPFS tracing in cluster (LP: #1792195) + - powerpc/mm/books3s: Add new pte bit to mark pte temporarily invalid. + - powerpc/mm/radix: Only need the Nest MMU workaround for R -> RW transition + * Support Edge Gateway's WIFI LED (LP: #1798330) + - SAUCE: mwifiex: Switch WiFi LED state according to the device status + * Support Edge Gateway's Bluetooth LED (LP: #1798332) + - SAUCE: Bluetooth: Support for LED on Edge Gateways + * USB cardreader (0bda:0328) make the system can't enter s3 or hang + (LP: #1798328) + - usb: Don't disable Latency tolerance Messaging (LTM) before port reset + * CVE-2018-15471 + - xen-netback: fix input validation in xenvif_set_hash_mapping() + * CVE-2018-16658 + - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status + * [Bionic] Update ThunderX2 implementation defined pmu core events + (LP: #1796904) + - perf vendor events arm64: Update ThunderX2 implementation defined pmu core + events + * the machine of lenovo M715 with the AMD GPU (Radeon Vega 8 Mobile, rev ca, + 1002:15dd) often hangs randomly (LP: #1796789) + - drm/amd: Add missing fields in atom_integrated_system_info_v1_11 + * [18.04] GLK hang after a while (LP: #1760545) + - drm/i915/glk: Add MODULE_FIRMWARE for Geminilake + * Fix usbcore.quirks when used at boot (LP: #1795784) + - usb: core: safely deal with the dynamic quirk lists + + -- Marcelo Henrique Cerri Wed, 24 Oct 2018 20:56:51 -0300 + +linux-oracle (4.15.0-1004.4) bionic; urgency=medium + + * linux-oracle: 4.15.0-1004.4 -proposed tracker (LP: #1799093) + + * Miscellaneous Ubuntu changes + - [Config] updateconfigs after rebase to Ubuntu-4.15.0-38.41 + + [ Ubuntu: 4.15.0-38.41 ] + + * linux: 4.15.0-38.41 -proposed tracker (LP: #1797061) + * Silent data corruption in Linux kernel 4.15 (LP: #1796542) + - block: add a lower-level bio_add_page interface + - block: bio_iov_iter_get_pages: fix size of last iovec + - blkdev: __blkdev_direct_IO_simple: fix leak in error case + - block: bio_iov_iter_get_pages: pin more pages for multi-segment IOs + + [ Ubuntu: 4.15.0-37.40 ] + + * linux: 4.15.0-37.40 -proposed tracker (LP: #1795564) + * hns3: enable ethtool rx-vlan-filter on supported hw (LP: #1793394) + - net: hns3: Add vlan filter setting by ethtool command -K + * hns3: Modifying channel parameters will reset ring parameters back to + defaults (LP: #1793404) + - net: hns3: Fix desc num set to default when setting channel + * hisi_sas: Add SATA FIX check for v3 hw (LP: #1794151) + - scsi: hisi_sas: Add SATA FIS check for v3 hw + * Fix potential corruption using SAS controller on HiSilicon arm64 boards + (LP: #1794156) + - scsi: hisi_sas: add memory barrier in task delivery function + * hisi_sas: Reduce unnecessary spin lock contention (LP: #1794165) + - scsi: hisi_sas: Tidy hisi_sas_task_prep() + * Add functional level reset support for the SAS controller on HiSilicon D06 + systems (LP: #1794166) + - scsi: hisi_sas: tidy host controller reset function a bit + - scsi: hisi_sas: relocate some common code for v3 hw + - scsi: hisi_sas: Implement handlers of PCIe FLR for v3 hw + * HiSilicon SAS controller doesn't recover from PHY STP link timeout + (LP: #1794172) + - scsi: hisi_sas: tidy channel interrupt handler for v3 hw + - scsi: hisi_sas: Fix the failure of recovering PHY from STP link timeout + * getxattr: always handle namespaced attributes (LP: #1789746) + - getxattr: use correct xattr length + * Fix unusable NVIDIA GPU after S3 (LP: #1793338) + - PCI: Reprogram bridge prefetch registers on resume + * Fails to boot under Xen PV: BUG: unable to handle kernel paging request at + edc21fd9 (LP: #1789118) + - x86/EISA: Don't probe EISA bus for Xen PV guests + * qeth: use vzalloc for QUERY OAT buffer (LP: #1793086) + - s390/qeth: use vzalloc for QUERY OAT buffer + * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463) + - Input: elantech - enable middle button of touchpad on ThinkPad P72 + * Dell new AIO requires a new uart backlight driver (LP: #1727235) + - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO + - updateconfigs for Dell UART backlight driver + * [Ubuntu] s390/crypto: Fix return code checking in cbc_paes_crypt. + (LP: #1794294) + - s390/crypto: Fix return code checking in cbc_paes_crypt() + * hns3: Retrieve RoCE MSI-X config from firmware (LP: #1793221) + - net: hns3: Fix MSIX allocation issue for VF + - net: hns3: Refine the MSIX allocation for PF + * net: hns: Avoid hang when link is changed while handling packets + (LP: #1792209) + - net: hns: add the code for cleaning pkt in chip + - net: hns: add netif_carrier_off before change speed and duplex + * Page leaking in cachefiles_read_backing_file while vmscan is active + (LP: #1793430) + - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan + is active + * some nvidia p1000 graphic cards hang during the boot (LP: #1791569) + - drm/nouveau/gr/gf100-: virtualise tpc_mask + apply fixes from traces + * Error reported when creating ZFS pool with "-t" option, despite successful + pool creation (LP: #1769937) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.4 + * Fix I2C touchpanels' interrupt storms after system suspend (LP: #1792309) + - HID: i2c-hid: Fix flooded incomplete report after S3 on Rayd touchscreen + - HID: i2c-hid: Don't reset device upon system resume + * ipmmu is always registered (LP: #1783746) + - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU- + VMSA + * Bionic update: upstream stable patchset 2018-09-27 (LP: #1794889) + - clocksource/drivers/imx-tpm: Correct some registers operation flow + - Input: synaptics-rmi4 - fix an unchecked out of memory error path + - KVM: X86: fix incorrect reference of trace_kvm_pi_irte_update + - x86: Add check for APIC access address for vmentry of L2 guests + - MIPS: io: Prevent compiler reordering writeX() + - nfp: ignore signals when communicating with management FW + - perf report: Fix switching to another perf.data file + - fsnotify: fix ignore mask logic in send_to_group() + - MIPS: io: Add barrier after register read in readX() + - s390/smsgiucv: disable SMSG on module unload + - isofs: fix potential memory leak in mount option parsing + - MIPS: dts: Boston: Fix PCI bus dtc warnings: + - spi: sh-msiof: Fix bit field overflow writes to TSCR/RSCR + - doc: Add vendor prefix for Kieback & Peter GmbH + - dt-bindings: pinctrl: sunxi: Fix reference to driver + - dt-bindings: serial: sh-sci: Add support for r8a77965 (H)SCIF + - dt-bindings: dmaengine: rcar-dmac: document R8A77965 support + - clk: honor CLK_MUX_ROUND_CLOSEST in generic clk mux + - ASoC: rt5514: Add the missing register in the readable table + - eCryptfs: don't pass up plaintext names when using filename encryption + - soc: bcm: raspberrypi-power: Fix use of __packed + - soc: bcm2835: Make !RASPBERRYPI_FIRMWARE dummies return failure + - PCI: kirin: Fix reset gpio name + - ASoC: topology: Fix bugs of freeing soc topology + - xen: xenbus_dev_frontend: Really return response string + - ASoC: topology: Check widget kcontrols before deref. + - spi: cadence: Add usleep_range() for cdns_spi_fill_tx_fifo() + - blkcg: don't hold blkcg lock when deactivating policy + - tipc: fix infinite loop when dumping link monitor summary + - scsi: iscsi: respond to netlink with unicast when appropriate + - scsi: megaraid_sas: Do not log an error if FW successfully initializes. + - scsi: target: fix crash with iscsi target and dvd + - netfilter: nf_tables: NAT chain and extensions require NF_TABLES + - netfilter: nf_tables: fix out-of-bounds in nft_chain_commit_update + - ASoC: msm8916-wcd-analog: use threaded context for mbhc events + - drm/msm: Fix possible null dereference on failure of get_pages() + - drm/msm/dsi: use correct enum in dsi_get_cmd_fmt + - drm/msm: don't deref error pointer in the msm_fbdev_create error path + - blkcg: init root blkcg_gq under lock + - vfs: Undo an overly zealous MS_RDONLY -> SB_RDONLY conversion + - parisc: time: Convert read_persistent_clock() to read_persistent_clock64() + - scsi: storvsc: Set up correct queue depth values for IDE devices + - scsi: isci: Fix infinite loop in while loop + - mm, pagemap: fix swap offset value for PMD migration entry + - proc: revalidate kernel thread inodes to root:root + - kexec_file: do not add extra alignment to efi memmap + - mm: memcg: add __GFP_NOWARN in __memcg_schedule_kmem_cache_create() + - usb: typec: ucsi: fix tracepoint related build error + - ACPI / PM: Blacklist Low Power S0 Idle _DSM for ThinkPad X1 Tablet(2016) + - dt-bindings: meson-uart: DT fix s/clocks-names/clock-names/ + - net: phy: marvell: clear wol event before setting it + - ARM: dts: da850: fix W=1 warnings with pinmux node + - ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70 + - drm/amdkfd: fix clock counter retrieval for node without GPU + - thermal: int3403_thermal: Fix NULL pointer deref on module load / probe + - net: ethtool: Add missing kernel doc for FEC parameters + - arm64: ptrace: remove addr_limit manipulation + - HID: lenovo: Add support for IBM/Lenovo Scrollpoint mice + - HID: wacom: Release device resource data obtained by devres_alloc() + - selftests: ftrace: Add a testcase for multiple actions on trigger + - rds: ib: Fix missing call to rds_ib_dev_put in rds_ib_setup_qp + - perf/x86/intel: Don't enable freeze-on-smi for PerfMon V1 + - remoteproc: qcom: Fix potential device node leaks + - rpmsg: added MODULE_ALIAS for rpmsg_char + - HID: intel-ish-hid: use put_device() instead of kfree() + - blk-mq: fix sysfs inflight counter + - arm64: fix possible spectre-v1 in ptrace_hbp_get_event() + - KVM: arm/arm64: vgic: fix possible spectre-v1 in vgic_mmio_read_apr() + - libahci: Allow drivers to override stop_engine + - ata: ahci: mvebu: override ahci_stop_engine for mvebu AHCI + - x86/cpu/intel: Add missing TLB cpuid values + - bpf: fix uninitialized variable in bpf tools + - i2c: sprd: Prevent i2c accesses after suspend is called + - i2c: sprd: Fix the i2c count issue + - tipc: fix bug in function tipc_nl_node_dump_monitor + - nvme: depend on INFINIBAND_ADDR_TRANS + - nvmet-rdma: depend on INFINIBAND_ADDR_TRANS + - ib_srpt: depend on INFINIBAND_ADDR_TRANS + - ib_srp: depend on INFINIBAND_ADDR_TRANS + - IB: make INFINIBAND_ADDR_TRANS configurable + - IB/uverbs: Fix validating mandatory attributes + - RDMA/cma: Fix use after destroy access to net namespace for IPoIB + - RDMA/iwpm: fix memory leak on map_info + - IB/rxe: add RXE_START_MASK for rxe_opcode IB_OPCODE_RC_SEND_ONLY_INV + - IB/rxe: avoid double kfree_skb + - : fix end_name_hash() for 64bit long + - IB/core: Make ib_mad_client_id atomic + - ARM: davinci: board-da830-evm: fix GPIO lookup for MMC/SD + - ARM: davinci: board-da850-evm: fix GPIO lookup for MMC/SD + - ARM: davinci: board-omapl138-hawk: fix GPIO numbers for MMC/SD lookup + - ARM: davinci: board-dm355-evm: fix broken networking + - dt-bindings: panel: lvds: Fix path to display timing bindings + - ARM: OMAP2+: powerdomain: use raw_smp_processor_id() for trace + - ARM: dts: logicpd-som-lv: Fix WL127x Startup Issues + - ARM: dts: logicpd-som-lv: Fix Audio Mute + - Input: atmel_mxt_ts - fix the firmware update + - hexagon: add memset_io() helper + - hexagon: export csum_partial_copy_nocheck + - scsi: vmw-pvscsi: return DID_BUS_BUSY for adapter-initated aborts + - bpf, x64: fix memleak when not converging after image + - parisc: drivers.c: Fix section mismatches + - stop_machine, sched: Fix migrate_swap() vs. active_balance() deadlock + - kthread, sched/wait: Fix kthread_parkme() wait-loop + - arm64: tegra: Make BCM89610 PHY interrupt as active low + - iommu/vt-d: fix shift-out-of-bounds in bug checking + - nvme: fix potential memory leak in option parsing + - nvme: Set integrity flag for user passthrough commands + - ARM: OMAP1: ams-delta: fix deferred_fiq handler + - smc: fix sendpage() call + - IB/hfi1 Use correct type for num_user_context + - IB/hfi1: Fix memory leak in exception path in get_irq_affinity() + - RDMA/cma: Do not query GID during QP state transition to RTR + - spi: bcm2835aux: ensure interrupts are enabled for shared handler + - sched/core: Introduce set_special_state() + - sh: fix build failure for J2 cpu with SMP disabled + - tee: check shm references are consistent in offset/size + - mac80211: Adjust SAE authentication timeout + - drm/omap: silence unititialized variable warning + - drm/omap: fix uninitialized ret variable + - drm/omap: fix possible NULL ref issue in tiler_reserve_2d + - drm/omap: check return value from soc_device_match + - drm/omap: handle alloc failures in omap_connector + - driver core: add __printf verification to __ata_ehi_pushv_desc + - ARM: dts: cygnus: fix irq type for arm global timer + - mac80211: use timeout from the AddBA response instead of the request + - net: aquantia: driver should correctly declare vlan_features bits + - can: dev: increase bus-off message severity + - arm64: Add MIDR encoding for NVIDIA CPUs + - cifs: smb2ops: Fix listxattr() when there are no EAs + - agp: uninorth: make two functions static + - tipc: eliminate KMSAN uninit-value in strcmp complaint + - qed: Fix l2 initializations over iWARP personality + - qede: Fix gfp flags sent to rdma event node allocation + - rxrpc: Fix error reception on AF_INET6 sockets + - rxrpc: Fix the min security level for kernel calls + - KVM: Extend MAX_IRQ_ROUTES to 4096 for all archs + - x86: Delay skip of emulated hypercall instruction + - ixgbe: return error on unsupported SFP module when resetting + - net sched actions: fix invalid pointer dereferencing if skbedit flags + missing + - proc/kcore: don't bounds check against address 0 + - ocfs2: take inode cluster lock before moving reflinked inode from orphan dir + - kprobes/x86: Prohibit probing on exception masking instructions + - uprobes/x86: Prohibit probing on MOV SS instruction + - objtool, kprobes/x86: Sync the latest header with + tools/objtool/arch/x86/include/asm/insn.h + - x86/pkeys/selftests: Adjust the self-test to fresh distros that export the + pkeys ABI + - x86/mpx/selftests: Adjust the self-test to fresh distros that export the MPX + ABI + - x86/selftests: Add mov_to_ss test + - x86/pkeys/selftests: Give better unexpected fault error messages + - x86/pkeys/selftests: Stop using assert() + - x86/pkeys/selftests: Remove dead debugging code, fix dprint_in_signal + - x86/pkeys/selftests: Allow faults on unknown keys + - x86/pkeys/selftests: Factor out "instruction page" + - x86/pkeys/selftests: Add PROT_EXEC test + - x86/pkeys/selftests: Fix pkey exhaustion test off-by-one + - x86/pkeys/selftests: Fix pointer math + - x86/pkeys/selftests: Save off 'prot' for allocations + - x86/pkeys/selftests: Add a test for pkey 0 + - mtd: Fix comparison in map_word_andequal() + - afs: Fix the non-encryption of calls + - usb: musb: fix remote wakeup racing with suspend + - ARM: keystone: fix platform_domain_notifier array overrun + - i2c: pmcmsp: return message count on master_xfer success + - i2c: pmcmsp: fix error return from master_xfer + - i2c: viperboard: return message count on master_xfer success + - ARM: davinci: dm646x: fix timer interrupt generation + - ARM: davinci: board-dm646x-evm: pass correct I2C adapter id for VPIF + - ARM: davinci: board-dm646x-evm: set VPIF capture card name + - clk: imx6ull: use OSC clock during AXI rate change + - locking/rwsem: Add a new RWSEM_ANONYMOUSLY_OWNED flag + - locking/percpu-rwsem: Annotate rwsem ownership transfer by setting + RWSEM_OWNER_UNKNOWN + - drm/dumb-buffers: Integer overflow in drm_mode_create_ioctl() + - sched/debug: Move the print_rt_rq() and print_dl_rq() declarations to + kernel/sched/sched.h + - sched/deadline: Make the grub_reclaim() function static + - parisc: Move setup_profiling_timer() out of init section + - efi/libstub/arm64: Handle randomized TEXT_OFFSET + - ARM: 8753/1: decompressor: add a missing parameter to the addruart macro + - ARM: 8758/1: decompressor: restore r1 and r2 just before jumping to the + kernel + - ARM: kexec: fix kdump register saving on panic() + - Revert "Btrfs: fix scrub to repair raid6 corruption" + - Btrfs: fix scrub to repair raid6 corruption + - Btrfs: make raid6 rebuild retry more + - tcp: do not overshoot window_clamp in tcp_rcv_space_adjust() + - ibmvnic: Do not notify peers on parameter change resets + - dt-bindings: net: ravb: Add support for r8a77965 SoC + - X86/KVM: Properly update 'tsc_offset' to represent the running guest + - kvm: x86: move MSR_IA32_TSC handling to x86.c + - ARM: dts: Fix cm2 and prm sizes for omap4 + - powerpc/64s: Default l1d_size to 64K in RFI fallback flush + - KVM: arm/arm64: vgic: Kick new VCPU on interrupt migration + - arm64: kasan: avoid pfn_to_nid() before page array is initialized + - ARM64: dts: meson-gxl: add USB host support + - ARM64: dts: meson-gxm: add GXM specific USB host configuration + - ARM64: dts: meson-gxl-s905x-p212: enable the USB controller + - ARM64: dts: meson-gx-p23x-q20x: enable the USB controller + - ARM64: dts: meson-gxl-s905x-libretech-cc: enable the USB controller + - ARM64: dts: meson-gxl-nexbox-a95x: enable the USB controller + - ARM64: dts: meson-gxm-khadas-vim2: enable the USB controller + - arm64: dts: correct SATA addresses for Stingray + - afs: Fix server record deletion + - proc: fix /proc/loadavg regression + - s390/qeth: fix request-side race during cmd IO timeout + - ACPI / scan: Initialize watchdog before PNP + - CIFS: set *resp_buf_type to NO_BUFFER on error + - arm64: dts: uniphier: fix input delay value for legacy mode of eMMC + - igb: Fix the transmission mode of queue 0 for Qav mode + - RISC-V: build vdso-dummy.o with -no-pie + - arm64: only advance singlestep for user instruction traps + - perf pmu: Fix core PMU alias list for X86 platform + - bpf, x64: fix JIT emission for dead code + - powerpc/kvm/booke: Fix altivec related build break + - reset: uniphier: fix USB clock line for LD20 + - nfp: don't depend on eth_tbl being available + - net: mvpp2: Fix clk error path in mvpp2_probe + - kvm: apic: Flush TLB after APIC mode/address change if VPIDs are in use + - IB/uverbs: Fix validating mandatory attributes + - RDMA/hns: Intercept illegal RDMA operation when use inline data + - pinctrl: cherryview: Associate IRQ descriptors to irqdomain + - kthread, sched/wait: Fix kthread_parkme() completion issue + - iommu/vt-d: Fix usage of force parameter in intel_ir_reconfigure_irte() + - nvme/multipath: Disable runtime writable enabling parameter + - ARM: dts: correct missing "compatible" entry for ti81xx SoCs + - usb: typec: tps6598x: handle block reads separately with plain-I2C adapters + - IB/mlx4: Fix integer overflow when calculating optimal MTT size + - bpf: add map_alloc_check callback + - bpf: fix possible spectre-v1 in find_and_alloc_map() + - drm/exynos/mixer: fix synchronization check in interlaced mode + - drm/exynos: mixer: avoid Oops in vp_video_buffer() + - bpf: use array_index_nospec in find_prog_type + - gcc-plugins: fix build condition of SANCOV plugin + - drm/vc4: Fix oops dereferencing DPI's connector since panel_bridge. + - nvme: fix use-after-free in nvme_free_ns_head + - powerpc/pseries: Fix CONFIG_NUMA=n build + - HID: i2c-hid: Add RESEND_REPORT_DESCR quirk for Toshiba Click Mini L9W-B + - cifs: Allocate validate negotiation request through kmalloc + - drm/amdgpu: Switch to interruptable wait to recover from ring hang. + - rxrpc: Fix missing start of call timeout + - ARM: dts: imx51-zii-rdu1: fix touchscreen bindings + - sh: switch to NO_BOOTMEM + - lib/find_bit_benchmark.c: avoid soft lockup in test_find_first_bit() + - x86/pkeys/selftests: Avoid printf-in-signal deadlocks + - afs: Fix address list parsing + - afs: Fix refcounting in callback registration + - afs: Fix server rotation's handling of fileserver probe failure + - afs: Fix VNOVOL handling in address rotation + - afs: Fix the handling of CB.InitCallBackState3 to find the server by UUID + - afs: Fix afs_find_server search loop + - KVM: X86: Lower the default timer frequency limit to 200us + - platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS + - ARM: replace unnecessary perl with sed and the shell $(( )) operator + * Improvements to the kernel source package preparation (LP: #1793461) + - [Packaging] startnewrelease: add support for backport kernels + * Kernel 4.15.0-35.38 fails to build with CONFIG_XFS_ONLINE_SCRUB enabled + (LP: #1792393) + - SAUCE: xfs: fix build error with CONFIG_XFS_ONLINE_SCRUB enabled + * update ENA driver to latest mainline version (LP: #1792044) + - net: ena: add detection and recovery mechanism for handling missed/misrouted + MSI-X + - net: ena: increase ena driver version to 1.5.0 + - net: ena: Eliminate duplicate barriers on weakly-ordered archs + - SAUCE: ena: devm_kzalloc() -> devm_kcalloc() + - net: ena: Fix use of uninitialized DMA address bits field + - net: ena: fix surprise unplug NULL dereference kernel crash + - net: ena: fix driver when PAGE_SIZE == 64kB + - net: ena: fix device destruction to gracefully free resources + - net: ena: fix potential double ena_destroy_device() + - net: ena: fix missing lock during device destruction + - net: ena: fix missing calls to READ_ONCE + - net: ena: fix incorrect usage of memory barriers + + [ Ubuntu: 4.15.0-36.39 ] + + * CVE-2018-14633 + - iscsi target: Use hex2bin instead of a re-implementation + * CVE-2018-17182 + - mm: get rid of vmacache_flush_all() entirely + + [ Ubuntu: 4.15.0-35.38 ] + + * linux: 4.15.0-35.38 -proposed tracker (LP: #1791719) + * device hotplug of vfio devices can lead to deadlock in vfio_pci_release + (LP: #1792099) + - SAUCE: vfio -- release device lock before userspace requests + * L1TF mitigation not effective in some CPU and RAM combinations + (LP: #1788563) + - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit + - x86/speculation/l1tf: Fix off-by-one error when warning that system has too + much RAM + - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+ + * CVE-2018-15594 + - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests + * CVE-2017-5715 (Spectre v2 s390x) + - KVM: s390: implement CPU model only facilities + - s390: detect etoken facility + - KVM: s390: add etoken support for guests + - s390/lib: use expoline for all bcr instructions + - s390: fix br_r1_trampoline for machines without exrl + - SAUCE: s390: use expoline thunks for all branches generated by the BPF JIT + * Ubuntu18.04.1: cpuidle: powernv: Fix promotion from snooze if next state + disabled (performance) (LP: #1790602) + - cpuidle: powernv: Fix promotion from snooze if next state disabled + * Watchdog CPU:19 Hard LOCKUP when kernel crash was triggered (LP: #1790636) + - powerpc: hard disable irqs in smp_send_stop loop + - powerpc: Fix deadlock with multiple calls to smp_send_stop + - powerpc: smp_send_stop do not offline stopped CPUs + - powerpc/powernv: Fix opal_event_shutdown() called with interrupts disabled + * Security fix: check if IOMMU page is contained in the pinned physical page + (LP: #1785675) + - vfio/spapr: Use IOMMU pageshift rather than pagesize + - KVM: PPC: Check if IOMMU page is contained in the pinned physical page + * Missing Intel GPU pci-id's (LP: #1789924) + - drm/i915/kbl: Add KBL GT2 sku + - drm/i915/whl: Introducing Whiskey Lake platform + - drm/i915/aml: Introducing Amber Lake platform + - drm/i915/cfl: Add a new CFL PCI ID. + * CVE-2018-15572 + - x86/speculation: Protect against userspace-userspace spectreRSB + * Support Power Management for Thunderbolt Controller (LP: #1789358) + - thunderbolt: Handle NULL boot ACL entries properly + - thunderbolt: Notify userspace when boot_acl is changed + - thunderbolt: Use 64-bit DMA mask if supported by the platform + - thunderbolt: Do not unnecessarily call ICM get route + - thunderbolt: No need to take tb->lock in domain suspend/complete + - thunderbolt: Use correct ICM commands in system suspend + - thunderbolt: Add support for runtime PM + * random oopses on s390 systems using NVMe devices (LP: #1790480) + - s390/pci: fix out of bounds access during irq setup + * [Bionic] Spectre v4 mitigation (Speculative Store Bypass Disable) support + for arm64 using SMC firmware call to set a hardware chicken bit + (LP: #1787993) // CVE-2018-3639 (arm64) + - arm64: alternatives: Add dynamic patching feature + - KVM: arm/arm64: Do not use kern_hyp_va() with kvm_vgic_global_state + - KVM: arm64: Avoid storing the vcpu pointer on the stack + - arm/arm64: smccc: Add SMCCC-specific return codes + - arm64: Call ARCH_WORKAROUND_2 on transitions between EL0 and EL1 + - arm64: Add per-cpu infrastructure to call ARCH_WORKAROUND_2 + - arm64: Add ARCH_WORKAROUND_2 probing + - arm64: Add 'ssbd' command-line option + - arm64: ssbd: Add global mitigation state accessor + - arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation + - arm64: ssbd: Restore mitigation status on CPU resume + - arm64: ssbd: Introduce thread flag to control userspace mitigation + - arm64: ssbd: Add prctl interface for per-thread mitigation + - arm64: KVM: Add HYP per-cpu accessors + - arm64: KVM: Add ARCH_WORKAROUND_2 support for guests + - arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests + - arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID + - [Config] ARM64_SSBD=y + * Reconcile hns3 SAUCE patches with upstream (LP: #1787477) + - Revert "UBUNTU: SAUCE: net: hns3: Optimize PF CMDQ interrupt switching + process" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for VF mailbox receiving unknown + message" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF + response" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for + hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and + shift in hclge_get_ring_chain_from_mbx" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default + assignment probelm" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring + configuration operation while resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet" + - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell + phy driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when + resetting" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status + register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset + frequently" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing + command queue register" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during + global or core reset" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear + reset cause" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in + hclgevf_main module" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp + selftest" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal + frame size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated + problem" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting + correctly" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in + pfc mode" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first + up" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and + definition" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset + macros" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return + value" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unused function warning in VF + driver" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead + of kzalloc/dma_map_single" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while + dependency HNS3 set" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of + some structures" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant + hclge_cmd_csq_done" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters + in hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant + assignments" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in + hclge_cmd_send" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused + hclge_ring_to_dma_dir" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and + upper_32_bits" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector + in hns3_client_uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error + information" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state + state init|uninit" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in + hnae3.c" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4 + and ipv6" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before + free vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for + init_client_instance and uninit_client_instance" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index + from hclge_bind_ring_with_vector" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in + last BD except VLD bit and buffer size" + - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback + selftest" + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: remove unused hclgevf_cfg_func_mta_filter + - net: hns3: Fix for VF mailbox cannot receiving PF response + - net: hns3: Fix for VF mailbox receiving unknown message + - net: hns3: Optimize PF CMDQ interrupt switching process + - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector + - net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - net: hns3: add vector status check before free vector + - net: hns3: add l4_type check for both ipv4 and ipv6 + - net: hns3: add unlikely for error check + - net: hns3: remove unused head file in hnae3.c + - net: hns3: extraction an interface for state init|uninit + - net: hns3: print the ret value in error information + - net: hns3: remove the Redundant put_vector in hns3_client_uninit + - net: hns3: remove back in struct hclge_hw + - net: hns3: use lower_32_bits and upper_32_bits + - net: hns3: remove unused hclge_ring_to_dma_dir + - net: hns3: remove useless code in hclge_cmd_send + - net: hns3: remove some redundant assignments + - net: hns3: simplify hclge_cmd_csq_clean + - net: hns3: remove a redundant hclge_cmd_csq_done + - net: hns3: remove some unused members of some structures + - net: hns3: give default option while dependency HNS3 set + - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single + - net: hns3: modify hnae_ to hnae3_ + - net: hns3: Fix tc setup when netdev is first up + - net: hns3: Fix for mac pause not disable in pfc mode + - net: hns3: Fix for waterline not setting correctly + - net: hns3: Fix for l4 checksum offload bug + - net: hns3: Fix for mailbox message truncated problem + - net: hns3: Add configure for mac minimal frame size + - net: hns3: Fix warning bug when doing lp selftest + - net: hns3: Fix get_vector ops in hclgevf_main module + - net: hns3: Remove the warning when clear reset cause + - net: hns3: Prevent sending command during global or core reset + - net: hns3: Modify the order of initializing command queue register + - net: hns3: Reset net device with rtnl_lock + - net: hns3: Prevent to request reset frequently + - net: hns3: Correct reset event status register + - net: hns3: Fix return value error in hns3_reset_notify_down_enet + - net: hns3: remove unnecessary ring configuration operation while resetting + - net: hns3: Fix for reset_level default assignment probelm + - net: hns3: Fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx + - net: hns3: Remove some redundant assignments + - net: hns3: Standardize the handle of return value + - net: hns3: Remove extra space and brackets + - net: hns3: Correct unreasonable code comments + - net: hns3: Use decimal for bit offset macros + - net: hns3: Modify inconsistent bit mask macros + - net: hns3: Fix misleading parameter name + - net: hns3: Remove unused struct member and definition + - net: hns3: Add SPDX tags to HNS3 PF driver + - net: hns3: Add support for serdes loopback selftest + - net: hns3: Fix for phy link issue when using marvell phy driver + - SAUCE: {topost} net: hns3: separate roce from nic when resetting + * CVE-2018-6555 + - SAUCE: irda: Only insert new objects into the global database via setsockopt + * CVE-2018-6554 + - SAUCE: irda: Fix memory leak caused by repeated binds of irda socket + * Bionic update: upstream stable patchset 2018-08-31 (LP: #1790188) + - netfilter: nf_tables: fix NULL pointer dereference on + nft_ct_helper_obj_dump() + - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers + - af_key: Always verify length of provided sadb_key + - gpio: No NULL owner + - KVM: X86: Fix reserved bits check for MOV to CR3 + - KVM: x86: introduce linear_{read,write}_system + - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and + kvm_write_guest_virt_system + - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy + - NFC: pn533: don't send USB data off of the stack + - usbip: vhci_sysfs: fix potential Spectre v1 + - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver + - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive + - Input: xpad - add GPD Win 2 Controller USB IDs + - phy: qcom-qusb2: Fix crash if nvmem cell not specified + - usb: gadget: function: printer: avoid wrong list handling in printer_write() + - usb: gadget: udc: renesas_usb3: disable the controller's irqs for + reconnecting + - serial: sh-sci: Stop using printk format %pCr + - tty/serial: atmel: use port->name as name in request_irq() + - serial: samsung: fix maxburst parameter for DMA transactions + - serial: 8250: omap: Fix idling of clocks for unused uarts + - vmw_balloon: fixing double free when batching mode is off + - tty: pl011: Avoid spuriously stuck-off interrupts + - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access + - Input: goodix - add new ACPI id for GPD Win 2 touch screen + - crypto: caam - strip input zeros from RSA input buffer + - crypto: caam - fix DMA mapping dir for generated IV + - crypto: caam - fix IV DMA mapping and updating + - crypto: caam/qi - fix IV DMA mapping and updating + - crypto: caam - fix size of RSA prime factor q + - crypto: vmx - Remove overly verbose printk from AES init routines + - crypto: vmx - Remove overly verbose printk from AES XTS init + - crypto: omap-sham - fix memleak + - usb: typec: wcove: Remove dependency on HW FSM + - usb: gadget: udc: renesas_usb3: fix double phy_put() + - usb: gadget: udc: renesas_usb3: should remove debugfs + - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add + udc + - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc + - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error + * Bionic update: upstream stable patchset 2018-08-29 (LP: #1789666) + - scsi: sd_zbc: Avoid that resetting a zone fails sporadically + - mmap: introduce sane default mmap limits + - mmap: relax file size limit for regular files + - btrfs: define SUPER_FLAG_METADUMP_V2 + - kconfig: Avoid format overflow warning from GCC 8.1 + - be2net: Fix error detection logic for BE3 + - bnx2x: use the right constant + - dccp: don't free ccid2_hc_tx_sock struct in dccp_disconnect() + - enic: set DMA mask to 47 bit + - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds + - ip6_tunnel: remove magic mtu value 0xFFF8 + - ipmr: properly check rhltable_init() return value + - ipv4: remove warning in ip_recv_error + - ipv6: omit traffic class when calculating flow hash + - isdn: eicon: fix a missing-check bug + - kcm: Fix use-after-free caused by clonned sockets + - netdev-FAQ: clarify DaveM's position for stable backports + - net: ipv4: add missing RTA_TABLE to rtm_ipv4_policy + - net: metrics: add proper netlink validation + - net/packet: refine check for priv area size + - net: phy: broadcom: Fix bcm_write_exp() + - net: usb: cdc_mbim: add flag FLAG_SEND_ZLP + - packet: fix reserve calculation + - qed: Fix mask for physical address in ILT entry + - sctp: not allow transport timeout value less than HZ/5 for hb_timer + - team: use netdev_features_t instead of u32 + - vhost: synchronize IOTLB message with dev cleanup + - vrf: check the original netdevice for generating redirect + - ipv6: sr: fix memory OOB access in seg6_do_srh_encap/inline + - net: phy: broadcom: Fix auxiliary control register reads + - net-sysfs: Fix memory leak in XPS configuration + - virtio-net: correctly transmit XDP buff after linearizing + - net/mlx4: Fix irq-unsafe spinlock usage + - tun: Fix NULL pointer dereference in XDP redirect + - virtio-net: correctly check num_buf during err path + - net/mlx5e: When RXFCS is set, add FCS data into checksum calculation + - virtio-net: fix leaking page for gso packet during mergeable XDP + - rtnetlink: validate attributes in do_setlink() + - cls_flower: Fix incorrect idr release when failing to modify rule + - PCI: hv: Do not wait forever on a device that has disappeared + - drm: set FMODE_UNSIGNED_OFFSET for drm files + - l2tp: fix refcount leakage on PPPoL2TP sockets + - mlxsw: spectrum: Forbid creation of VLAN 1 over port/LAG + - net: ethernet: ti: cpdma: correct error handling for chan create + - net: ethernet: davinci_emac: fix error handling in probe() + - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC + - net : sched: cls_api: deal with egdev path only if needed + * Bionic update: upstream stable patchset 2018-08-24 (LP: #1788897) + - fix io_destroy()/aio_complete() race + - mm: fix the NULL mapping case in __isolate_lru_page() + - objtool: Support GCC 8's cold subfunctions + - objtool: Support GCC 8 switch tables + - objtool: Detect RIP-relative switch table references + - objtool: Detect RIP-relative switch table references, part 2 + - objtool: Fix "noreturn" detection for recursive sibling calls + - xfs: convert XFS_AGFL_SIZE to a helper function + - xfs: detect agfl count corruption and reset agfl + - Input: synaptics - Lenovo Carbon X1 Gen5 (2017) devices should use RMI + - Input: synaptics - add Lenovo 80 series ids to SMBus + - Input: elan_i2c_smbus - fix corrupted stack + - tracing: Fix crash when freeing instances with event triggers + - tracing: Make the snapshot trigger work with instances + - selinux: KASAN: slab-out-of-bounds in xattr_getsecurity + - cfg80211: further limit wiphy names to 64 bytes + - drm/amd/powerplay: Fix enum mismatch + - rtlwifi: rtl8192cu: Remove variable self-assignment in rf.c + - platform/chrome: cros_ec_lpc: remove redundant pointer request + - kbuild: clang: disable unused variable warnings only when constant + - tcp: avoid integer overflows in tcp_rcv_space_adjust() + - iio: ad7793: implement IIO_CHAN_INFO_SAMP_FREQ + - iio:buffer: make length types match kfifo types + - iio:kfifo_buf: check for uint overflow + - iio: adc: select buffer for at91-sama5d2_adc + - MIPS: lantiq: gphy: Drop reboot/remove reset asserts + - MIPS: ptrace: Fix PTRACE_PEEKUSR requests for 64-bit FGRs + - MIPS: prctl: Disallow FRE without FR with PR_SET_FP_MODE requests + - scsi: scsi_transport_srp: Fix shost to rport translation + - stm class: Use vmalloc for the master map + - hwtracing: stm: fix build error on some arches + - IB/core: Fix error code for invalid GID entry + - mm/huge_memory.c: __split_huge_page() use atomic ClearPageDirty() + - Revert "rt2800: use TXOP_BACKOFF for probe frames" + - intel_th: Use correct device when freeing buffers + - drm/psr: Fix missed entry in PSR setup time table. + - drm/i915/lvds: Move acpi lid notification registration to registration phase + - drm/i915: Disable LVDS on Radiant P845 + - drm/vmwgfx: Use kasprintf + - drm/vmwgfx: Fix host logging / guestinfo reading error paths + - nvme: fix extended data LBA supported setting + - iio: hid-sensor-trigger: Fix sometimes not powering up the sensor after + resume + - x86/MCE/AMD: Define a function to get SMCA bank type + - x86/mce/AMD: Pass the bank number to smca_get_bank_type() + - x86/mce/AMD, EDAC/mce_amd: Enumerate Reserved SMCA bank type + - x86/mce/AMD: Carve out SMCA get_block_address() code + - x86/MCE/AMD: Cache SMCA MISC block addresses + * errors when scanning partition table of corrupted AIX disk (LP: #1787281) + - partitions/aix: fix usage of uninitialized lv_info and lvname structures + - partitions/aix: append null character to print data from disk + * tlbie master timeout checkstop (using NVidia/GPU) (LP: #1789772) + - powerpc/mm/hugetlb: Update huge_ptep_set_access_flags to call + __ptep_set_access_flags directly + - powerpc/mm/radix: Move function from radix.h to pgtable-radix.c + - powerpc/mm: Change function prototype + - powerpc/mm/radix: Change pte relax sequence to handle nest MMU hang + * performance drop with ATS enabled (LP: #1788097) + - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage + * [Regression] kernel crashdump fails on arm64 (LP: #1786878) + - arm64: export memblock_reserve()d regions via /proc/iomem + - drivers: acpi: add dependency of EFI for arm64 + - efi/arm: preserve early mapping of UEFI memory map longer for BGRT + - efi/arm: map UEFI memory map even w/o runtime services enabled + - arm64: acpi: fix alignment fault in accessing ACPI + - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y + - arm64: fix ACPI dependencies + - ACPI: fix menuconfig presentation of ACPI submenu + * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780) + - r8152: disable RX aggregation on new Dell TB16 dock + * dell_wmi: Unknown key codes (LP: #1762385) + - platform/x86: dell-wmi: Ignore new rfkill and fn-lock events + * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940) + - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform + - SAUCE: i2c:amd move out pointer in union i2c_event_base + - SAUCE: i2c:amd Depends on ACPI + - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86 + * r8169 no internet after suspending (LP: #1779817) + - r8169: restore previous behavior to accept BIOS WoL settings + - r8169: don't use MSI-X on RTL8168g + - r8169: don't use MSI-X on RTL8106e + * Fix Intel Cannon Lake LPSS I2C input clock (LP: #1789790) + - mfd: intel-lpss: Fix Intel Cannon Lake LPSS I2C input clock + * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4 + machine (LP: #1789145) + - ALSA: hda/realtek - Fix HP Headset Mic can't record + * Tango platform uses __initcall without further checks (LP: #1787945) + - [Config] disable ARCH_TANGO + * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898) + - [Config] CONFIG_SCLP_OFB=y for s390x + + -- Marcelo Henrique Cerri Sun, 21 Oct 2018 18:16:29 -0300 + +linux-oracle (4.15.0-1003.3) bionic; urgency=medium + + [ Ubuntu: 4.15.0-34.37 ] + + * linux: 4.15.0-34.37 -proposed tracker (LP: #1788744) + * Bionic update: upstream stable patchset 2018-08-09 (LP: #1786352) + - MIPS: c-r4k: Fix data corruption related to cache coherence + - MIPS: ptrace: Expose FIR register through FP regset + - MIPS: Fix ptrace(2) PTRACE_PEEKUSR and PTRACE_POKEUSR accesses to o32 FGRs + - KVM: Fix spelling mistake: "cop_unsuable" -> "cop_unusable" + - affs_lookup(): close a race with affs_remove_link() + - fs: don't scan the inode cache before SB_BORN is set + - aio: fix io_destroy(2) vs. lookup_ioctx() race + - ALSA: timer: Fix pause event notification + - do d_instantiate/unlock_new_inode combinations safely + - mmc: sdhci-iproc: remove hard coded mmc cap 1.8v + - mmc: sdhci-iproc: fix 32bit writes for TRANSFER_MODE register + - mmc: sdhci-iproc: add SDHCI_QUIRK2_HOST_OFF_CARD_ON for cygnus + - libata: Blacklist some Sandisk SSDs for NCQ + - libata: blacklist Micron 500IT SSD with MU01 firmware + - xen-swiotlb: fix the check condition for xen_swiotlb_free_coherent + - drm/vmwgfx: Fix 32-bit VMW_PORT_HB_[IN|OUT] macros + - arm64: lse: Add early clobbers to some input/output asm operands + - powerpc/64s: Clear PCR on boot + - IB/hfi1: Use after free race condition in send context error path + - IB/umem: Use the correct mm during ib_umem_release + - idr: fix invalid ptr dereference on item delete + - Revert "ipc/shm: Fix shmat mmap nil-page protection" + - ipc/shm: fix shmat() nil address after round-down when remapping + - mm/kasan: don't vfree() nonexistent vm_area + - kasan: free allocated shadow memory on MEM_CANCEL_ONLINE + - kasan: fix memory hotplug during boot + - kernel/sys.c: fix potential Spectre v1 issue + - KVM: s390: vsie: fix < 8k check for the itdba + - KVM: x86: Update cpuid properly when CR4.OSXAVE or CR4.PKE is changed + - kvm: x86: IA32_ARCH_CAPABILITIES is always supported + - powerpc/64s: Improve RFI L1-D cache flush fallback + - powerpc/pseries: Restore default security feature flags on setup + - powerpc/64s: Fix section mismatch warnings from setup_rfi_flush() + - MIPS: generic: Fix machine compatible matching + - mac80211: mesh: fix wrong mesh TTL offset calculation + - ARC: Fix malformed ARC_EMUL_UNALIGNED default + - ptr_ring: prevent integer overflow when calculating size + - arm64: dts: rockchip: fix rock64 gmac2io stability issues + - arm64: dts: rockchip: correct ep-gpios for rk3399-sapphire + - libata: Fix compile warning with ATA_DEBUG enabled + - selftests: sync: missing CFLAGS while compiling + - selftest/vDSO: fix O= + - selftests: pstore: Adding config fragment CONFIG_PSTORE_RAM=m + - selftests: memfd: add config fragment for fuse + - ARM: OMAP2+: timer: fix a kmemleak caused in omap_get_timer_dt + - ARM: OMAP3: Fix prm wake interrupt for resume + - ARM: OMAP2+: Fix sar_base inititalization for HS omaps + - ARM: OMAP1: clock: Fix debugfs_create_*() usage + - tls: retrun the correct IV in getsockopt + - xhci: workaround for AMD Promontory disabled ports wakeup + - IB/uverbs: Fix method merging in uverbs_ioctl_merge + - IB/uverbs: Fix possible oops with duplicate ioctl attributes + - IB/uverbs: Fix unbalanced unlock on error path for rdma_explicit_destroy + - arm64: dts: rockchip: Fix DWMMC clocks + - ARM: dts: rockchip: Fix DWMMC clocks + - iwlwifi: mvm: fix security bug in PN checking + - iwlwifi: mvm: fix IBSS for devices that support station type API + - iwlwifi: mvm: always init rs with 20mhz bandwidth rates + - NFC: llcp: Limit size of SDP URI + - rxrpc: Work around usercopy check + - MD: Free bioset when md_run fails + - md: fix md_write_start() deadlock w/o metadata devices + - s390/dasd: fix handling of internal requests + - xfrm: do not call rcu_read_unlock when afinfo is NULL in xfrm_get_tos + - mac80211: round IEEE80211_TX_STATUS_HEADROOM up to multiple of 4 + - mac80211: fix a possible leak of station stats + - mac80211: fix calling sleeping function in atomic context + - cfg80211: clear wep keys after disconnection + - mac80211: Do not disconnect on invalid operating class + - mac80211: Fix sending ADDBA response for an ongoing session + - gpu: ipu-v3: pre: fix device node leak in ipu_pre_lookup_by_phandle + - gpu: ipu-v3: prg: fix device node leak in ipu_prg_lookup_by_phandle + - md raid10: fix NULL deference in handle_write_completed() + - drm/exynos: g2d: use monotonic timestamps + - drm/exynos: fix comparison to bitshift when dealing with a mask + - drm/meson: fix vsync buffer update + - arm64: perf: correct PMUVer probing + - RDMA/bnxt_re: Unpin SQ and RQ memory if QP create fails + - RDMA/bnxt_re: Fix system crash during load/unload + - net/mlx5e: Return error if prio is specified when offloading eswitch vlan + push + - locking/xchg/alpha: Add unconditional memory barrier to cmpxchg() + - md: raid5: avoid string overflow warning + - virtio_net: fix XDP code path in receive_small() + - kernel/relay.c: limit kmalloc size to KMALLOC_MAX_SIZE + - bug.h: work around GCC PR82365 in BUG() + - selftests/memfd: add run_fuse_test.sh to TEST_FILES + - seccomp: add a selftest for get_metadata + - soc: imx: gpc: de-register power domains only if initialized + - powerpc/bpf/jit: Fix 32-bit JIT for seccomp_data access + - s390/cio: fix ccw_device_start_timeout API + - s390/cio: fix return code after missing interrupt + - s390/cio: clear timer when terminating driver I/O + - selftests/bpf/test_maps: exit child process without error in ENOMEM case + - PKCS#7: fix direct verification of SignerInfo signature + - arm64: dts: cavium: fix PCI bus dtc warnings + - nfs: system crashes after NFS4ERR_MOVED recovery + - ARM: OMAP: Fix dmtimer init for omap1 + - smsc75xx: fix smsc75xx_set_features() + - regulatory: add NUL to request alpha2 + - integrity/security: fix digsig.c build error with header file + - x86/intel_rdt: Fix incorrect returned value when creating rdgroup sub- + directory in resctrl file system + - locking/xchg/alpha: Fix xchg() and cmpxchg() memory ordering bugs + - x86/topology: Update the 'cpu cores' field in /proc/cpuinfo correctly across + CPU hotplug operations + - mac80211: drop frames with unexpected DS bits from fast-rx to slow path + - arm64: fix unwind_frame() for filtered out fn for function graph tracing + - macvlan: fix use-after-free in macvlan_common_newlink() + - KVM: nVMX: Don't halt vcpu when L1 is injecting events to L2 + - kvm: fix warning for CONFIG_HAVE_KVM_EVENTFD builds + - ARM: dts: imx6dl: Include correct dtsi file for Engicam i.CoreM6 + DualLite/Solo RQS + - fs: dcache: Avoid livelock between d_alloc_parallel and __d_add + - fs: dcache: Use READ_ONCE when accessing i_dir_seq + - md: fix a potential deadlock of raid5/raid10 reshape + - md/raid1: fix NULL pointer dereference + - batman-adv: fix packet checksum in receive path + - batman-adv: invalidate checksum on fragment reassembly + - netfilter: ipt_CLUSTERIP: put config struct if we can't increment ct + refcount + - netfilter: ipt_CLUSTERIP: put config instead of freeing it + - netfilter: ebtables: convert BUG_ONs to WARN_ONs + - batman-adv: Ignore invalid batadv_iv_gw during netlink send + - batman-adv: Ignore invalid batadv_v_gw during netlink send + - batman-adv: Fix netlink dumping of BLA claims + - batman-adv: Fix netlink dumping of BLA backbones + - nvme-pci: Fix nvme queue cleanup if IRQ setup fails + - clocksource/drivers/fsl_ftm_timer: Fix error return checking + - libceph, ceph: avoid memory leak when specifying same option several times + - ceph: fix dentry leak when failing to init debugfs + - xen/pvcalls: fix null pointer dereference on map->sock + - ARM: orion5x: Revert commit 4904dbda41c8. + - qrtr: add MODULE_ALIAS macro to smd + - selftests/futex: Fix line continuation in Makefile + - r8152: fix tx packets accounting + - virtio-gpu: fix ioctl and expose the fixed status to userspace. + - dmaengine: rcar-dmac: fix max_chunk_size for R-Car Gen3 + - bcache: fix kcrashes with fio in RAID5 backend dev + - ip_gre: fix IFLA_MTU ignored on NEWLINK + - ip6_tunnel: fix IFLA_MTU ignored on NEWLINK + - sit: fix IFLA_MTU ignored on NEWLINK + - nbd: fix return value in error handling path + - ARM: dts: NSP: Fix amount of RAM on BCM958625HR + - ARM: dts: bcm283x: Fix unit address of local_intc + - powerpc/boot: Fix random libfdt related build errors + - clocksource/drivers/mips-gic-timer: Use correct shift count to extract data + - gianfar: Fix Rx byte accounting for ndev stats + - net/tcp/illinois: replace broken algorithm reference link + - nvmet: fix PSDT field check in command format + - net/smc: use link_id of server in confirm link reply + - mlxsw: core: Fix flex keys scratchpad offset conflict + - mlxsw: spectrum: Treat IPv6 unregistered multicast as broadcast + - spectrum: Reference count VLAN entries + - ARC: mcip: halt GFRC counter when ARC cores halt + - ARC: mcip: update MCIP debug mask when the new cpu came online + - ARC: setup cpu possible mask according to possible-cpus dts property + - ipvs: remove IPS_NAT_MASK check to fix passive FTP + - IB/mlx: Set slid to zero in Ethernet completion struct + - RDMA/bnxt_re: Unconditionly fence non wire memory operations + - RDMA/bnxt_re: Fix incorrect DB offset calculation + - RDMA/bnxt_re: Fix the ib_reg failure cleanup + - xen/pirq: fix error path cleanup when binding MSIs + - drm/amd/amdgpu: Correct VRAM width for APUs with GMC9 + - xfrm: Fix ESN sequence number handling for IPsec GSO packets. + - arm64: dts: rockchip: Fix rk3399-gru-* s2r (pinctrl hogs, wifi reset) + - drm/sun4i: Fix dclk_set_phase + - btrfs: use kvzalloc to allocate btrfs_fs_info + - Btrfs: send, fix issuing write op when processing hole in no data mode + - Btrfs: fix log replay failure after linking special file and fsync + - ceph: fix potential memory leak in init_caches() + - block: display the correct diskname for bio + - selftests/powerpc: Skip the subpage_prot tests if the syscall is unavailable + - net: ethtool: don't ignore return from driver get_fecparam method + - iwlwifi: mvm: fix TX of CCMP 256 + - iwlwifi: mvm: Fix channel switch for count 0 and 1 + - iwlwifi: mvm: fix assert 0x2B00 on older FWs + - iwlwifi: avoid collecting firmware dump if not loaded + - iwlwifi: mvm: Direct multicast frames to the correct station + - iwlwifi: mvm: Correctly set the tid for mcast queue + - rds: Incorrect reference counting in TCP socket creation + - watchdog: f71808e_wdt: Fix magic close handling + - batman-adv: Fix multicast packet loss with a single WANT_ALL_IPV4/6 flag + - hv_netvsc: use napi_schedule_irqoff + - hv_netvsc: filter multicast/broadcast + - hv_netvsc: propagate rx filters to VF + - ARM: dts: rockchip: Add missing #sound-dai-cells on rk3288 + - e1000e: Fix check_for_link return value with autoneg off + - e1000e: allocate ring descriptors with dma_zalloc_coherent + - ia64/err-inject: Use get_user_pages_fast() + - RDMA/qedr: Fix kernel panic when running fio over NFSoRDMA + - RDMA/qedr: Fix iWARP write and send with immediate + - IB/mlx4: Fix corruption of RoCEv2 IPv4 GIDs + - IB/mlx4: Include GID type when deleting GIDs from HW table under RoCE + - IB/mlx5: Fix an error code in __mlx5_ib_modify_qp() + - fbdev: Fixing arbitrary kernel leak in case FBIOGETCMAP_SPARC in + sbusfb_ioctl_helper(). + - fsl/fman: avoid sleeping in atomic context while adding an address + - qed: Free RoCE ILT Memory on rmmod qedr + - net: qcom/emac: Use proper free methods during TX + - net: smsc911x: Fix unload crash when link is up + - IB/core: Fix possible crash to access NULL netdev + - cxgb4: do not set needs_free_netdev for mgmt dev's + - xen-blkfront: move negotiate_mq to cover all cases of new VBDs + - xen: xenbus: use put_device() instead of kfree() + - hv_netvsc: fix filter flags + - hv_netvsc: fix locking for rx_mode + - hv_netvsc: fix locking during VF setup + - ARM: davinci: fix the GPIO lookup for omapl138-hawk + - arm64: Relax ARM_SMCCC_ARCH_WORKAROUND_1 discovery + - selftests/vm/run_vmtests: adjust hugetlb size according to nr_cpus + - lib/test_kmod.c: fix limit check on number of test devices created + - dmaengine: mv_xor_v2: Fix clock resource by adding a register clock + - netfilter: ebtables: fix erroneous reject of last rule + - can: m_can: change comparison to bitshift when dealing with a mask + - can: m_can: select pinctrl state in each suspend/resume function + - bnxt_en: Check valid VNIC ID in bnxt_hwrm_vnic_set_tpa(). + - workqueue: use put_device() instead of kfree() + - ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu + - sunvnet: does not support GSO for sctp + - KVM: arm/arm64: vgic: Add missing irq_lock to vgic_mmio_read_pending + - gpu: ipu-v3: prg: avoid possible array underflow + - drm/imx: move arming of the vblank event to atomic_flush + - drm/nouveau/bl: fix backlight regression + - xfrm: fix rcu_read_unlock usage in xfrm_local_error + - iwlwifi: mvm: set the correct tid when we flush the MCAST sta + - iwlwifi: mvm: Correctly set IGTK for AP + - iwlwifi: mvm: fix error checking for multi/broadcast sta + - net: Fix vlan untag for bridge and vlan_dev with reorder_hdr off + - vlan: Fix out of order vlan headers with reorder header off + - batman-adv: fix header size check in batadv_dbg_arp() + - batman-adv: Fix skbuff rcsum on packet reroute + - vti4: Don't count header length twice on tunnel setup + - ip_tunnel: Clamp MTU to bounds on new link + - vti6: Fix dev->max_mtu setting + - iwlwifi: mvm: Increase session protection time after CS + - iwlwifi: mvm: clear tx queue id when unreserving aggregation queue + - iwlwifi: mvm: make sure internal station has a valid id + - iwlwifi: mvm: fix array out of bounds reference + - drm/tegra: Shutdown on driver unbind + - perf/cgroup: Fix child event counting bug + - brcmfmac: Fix check for ISO3166 code + - kbuild: make scripts/adjust_autoksyms.sh robust against timestamp races + - RDMA/ucma: Correct option size check using optlen + - RDMA/qedr: fix QP's ack timeout configuration + - RDMA/qedr: Fix rc initialization on CNQ allocation failure + - RDMA/qedr: Fix QP state initialization race + - net/sched: fix idr leak on the error path of tcf_bpf_init() + - net/sched: fix idr leak in the error path of tcf_simp_init() + - net/sched: fix idr leak in the error path of tcf_act_police_init() + - net/sched: fix idr leak in the error path of tcp_pedit_init() + - net/sched: fix idr leak in the error path of __tcf_ipt_init() + - net/sched: fix idr leak in the error path of tcf_skbmod_init() + - net: dsa: Fix functional dsa-loop dependency on FIXED_PHY + - drm/ast: Fixed 1280x800 Display Issue + - mm/mempolicy.c: avoid use uninitialized preferred_node + - mm, thp: do not cause memcg oom for thp + - xfrm: Fix transport mode skb control buffer usage. + - selftests: ftrace: Add probe event argument syntax testcase + - selftests: ftrace: Add a testcase for string type with kprobe_event + - selftests: ftrace: Add a testcase for probepoint + - drm/amdkfd: Fix scratch memory with HWS enabled + - batman-adv: fix multicast-via-unicast transmission with AP isolation + - batman-adv: fix packet loss for broadcasted DHCP packets to a server + - ARM: 8748/1: mm: Define vdso_start, vdso_end as array + - lan78xx: Set ASD in MAC_CR when EEE is enabled. + - net: qmi_wwan: add BroadMobi BM806U 2020:2033 + - bonding: fix the err path for dev hwaddr sync in bond_enslave + - net: dsa: mt7530: fix module autoloading for OF platform drivers + - net/mlx5: Make eswitch support to depend on switchdev + - perf/x86/intel: Fix linear IP of PEBS real_ip on Haswell and later CPUs + - x86/alternatives: Fixup alternative_call_2 + - llc: properly handle dev_queue_xmit() return value + - builddeb: Fix header package regarding dtc source links + - qede: Fix barrier usage after tx doorbell write. + - mm, slab: memcg_link the SLAB's kmem_cache + - mm/page_owner: fix recursion bug after changing skip entries + - mm/kmemleak.c: wait for scan completion before disabling free + - hv_netvsc: enable multicast if necessary + - qede: Do not drop rx-checksum invalidated packets. + - net: Fix untag for vlan packets without ethernet header + - vlan: Fix vlan insertion for packets without ethernet header + - net: mvneta: fix enable of all initialized RXQs + - sh: fix debug trap failure to process signals before return to user + - firmware: dmi_scan: Fix UUID length safety check + - nvme: don't send keep-alives to the discovery controller + - Btrfs: clean up resources during umount after trans is aborted + - Btrfs: fix loss of prealloc extents past i_size after fsync log replay + - x86/pgtable: Don't set huge PUD/PMD on non-leaf entries + - fs/proc/proc_sysctl.c: fix potential page fault while unregistering sysctl + table + - swap: divide-by-zero when zero length swap file on ssd + - z3fold: fix memory leak + - sr: get/drop reference to device in revalidate and check_events + - Force log to disk before reading the AGF during a fstrim + - cpufreq: CPPC: Initialize shared perf capabilities of CPUs + - powerpc/fscr: Enable interrupts earlier before calling get_user() + - perf tools: Fix perf builds with clang support + - perf clang: Add support for recent clang versions + - dp83640: Ensure against premature access to PHY registers after reset + - ibmvnic: Zero used TX descriptor counter on reset + - mm/ksm: fix interaction with THP + - mm: fix races between address_space dereference and free in page_evicatable + - mm: thp: fix potential clearing to referenced flag in + page_idle_clear_pte_refs_one() + - Btrfs: bail out on error during replay_dir_deletes + - Btrfs: fix NULL pointer dereference in log_dir_items + - btrfs: Fix possible softlock on single core machines + - IB/rxe: Fix for oops in rxe_register_device on ppc64le arch + - ocfs2/dlm: don't handle migrate lockres if already in shutdown + - powerpc/64s/idle: Fix restore of AMOR on POWER9 after deep sleep + - sched/rt: Fix rq->clock_update_flags < RQCF_ACT_SKIP warning + - x86/mm: Fix bogus warning during EFI bootup, use boot_cpu_has() instead of + this_cpu_has() in build_cr3_noflush() + - KVM: VMX: raise internal error for exception during invalid protected mode + state + - lan78xx: Connect phy early + - sparc64: Make atomic_xchg() an inline function rather than a macro. + - net: bgmac: Fix endian access in bgmac_dma_tx_ring_free() + - net: bgmac: Correctly annotate register space + - btrfs: tests/qgroup: Fix wrong tree backref level + - Btrfs: fix copy_items() return value when logging an inode + - btrfs: fix lockdep splat in btrfs_alloc_subvolume_writers + - btrfs: qgroup: Fix root item corruption when multiple same source snapshots + are created with quota enabled + - rxrpc: Fix Tx ring annotation after initial Tx failure + - rxrpc: Don't treat call aborts as conn aborts + - xen/acpi: off by one in read_acpi_id() + - drivers: macintosh: rack-meter: really fix bogus memsets + - ACPI: acpi_pad: Fix memory leak in power saving threads + - powerpc/mpic: Check if cpu_possible() in mpic_physmask() + - ieee802154: ca8210: fix uninitialised data read + - ath10k: advertize beacon_int_min_gcd + - iommu/amd: Take into account that alloc_dev_data() may return NULL + - intel_th: Use correct method of finding hub + - m68k: set dma and coherent masks for platform FEC ethernets + - iwlwifi: mvm: check if mac80211_queue is valid in iwl_mvm_disable_txq + - parisc/pci: Switch LBA PCI bus from Hard Fail to Soft Fail mode + - hwmon: (nct6775) Fix writing pwmX_mode + - powerpc/perf: Prevent kernel address leak to userspace via BHRB buffer + - powerpc/perf: Fix kernel address leak via sampling registers + - rsi: fix kernel panic observed on 64bit machine + - tools/thermal: tmon: fix for segfault + - selftests: Print the test we're running to /dev/kmsg + - net/mlx5: Protect from command bit overflow + - watchdog: davinci_wdt: fix error handling in davinci_wdt_probe() + - ath10k: Fix kernel panic while using worker (ath10k_sta_rc_update_wk) + - nvme-pci: disable APST for Samsung NVMe SSD 960 EVO + ASUS PRIME Z370-A + - ath9k: fix crash in spectral scan + - cxgb4: Setup FW queues before registering netdev + - ima: Fix Kconfig to select TPM 2.0 CRB interface + - ima: Fallback to the builtin hash algorithm + - watchdog: aspeed: Allow configuring for alternate boot + - arm: dts: socfpga: fix GIC PPI warning + - ext4: don't complain about incorrect features when probing + - drm/vmwgfx: Unpin the screen object backup buffer when not used + - iommu/mediatek: Fix protect memory setting + - cpufreq: cppc_cpufreq: Fix cppc_cpufreq_init() failure path + - IB/mlx5: Set the default active rate and width to QDR and 4X + - zorro: Set up z->dev.dma_mask for the DMA API + - bcache: quit dc->writeback_thread when BCACHE_DEV_DETACHING is set + - remoteproc: imx_rproc: Fix an error handling path in 'imx_rproc_probe()' + - dt-bindings: add device tree binding for Allwinner H6 main CCU + - ACPICA: Events: add a return on failure from acpi_hw_register_read + - ACPICA: Fix memory leak on unusual memory leak + - ACPICA: acpi: acpica: fix acpi operand cache leak in nseval.c + - cxgb4: Fix queue free path of ULD drivers + - i2c: mv64xxx: Apply errata delay only in standard mode + - KVM: lapic: stop advertising DIRECTED_EOI when in-kernel IOAPIC is in use + - perf top: Fix top.call-graph config option reading + - perf stat: Fix core dump when flag T is used + - IB/core: Honor port_num while resolving GID for IB link layer + - drm/amdkfd: add missing include of mm.h + - coresight: Use %px to print pcsr instead of %p + - regulator: gpio: Fix some error handling paths in 'gpio_regulator_probe()' + - spi: bcm-qspi: fIX some error handling paths + - net/smc: pay attention to MAX_ORDER for CQ entries + - MIPS: ath79: Fix AR724X_PLL_REG_PCIE_CONFIG offset + - watchdog: dw: RMW the control register + - watchdog: aspeed: Fix translation of reset mode to ctrl register + - drm/meson: Fix some error handling paths in 'meson_drv_bind_master()' + - drm/meson: Fix an un-handled error path in 'meson_drv_bind_master()' + - powerpc: Add missing prototype for arch_irq_work_raise() + - f2fs: fix to set KEEP_SIZE bit in f2fs_zero_range + - f2fs: fix to clear CP_TRIMMED_FLAG + - f2fs: fix to check extent cache in f2fs_drop_extent_tree + - perf/core: Fix installing cgroup events on CPU + - max17042: propagate of_node to power supply device + - perf/core: Fix perf_output_read_group() + - drm/panel: simple: Fix the bus format for the Ontat panel + - hwmon: (pmbus/max8688) Accept negative page register values + - hwmon: (pmbus/adm1275) Accept negative page register values + - perf/x86/intel: Properly save/restore the PMU state in the NMI handler + - cdrom: do not call check_disk_change() inside cdrom_open() + - efi/arm*: Only register page tables when they exist + - perf/x86/intel: Fix large period handling on Broadwell CPUs + - perf/x86/intel: Fix event update for auto-reload + - arm64: dts: qcom: Fix SPI5 config on MSM8996 + - soc: qcom: wcnss_ctrl: Fix increment in NV upload + - gfs2: Fix fallocate chunk size + - x86/devicetree: Initialize device tree before using it + - x86/devicetree: Fix device IRQ settings in DT + - phy: rockchip-emmc: retry calpad busy trimming + - ALSA: vmaster: Propagate slave error + - phy: qcom-qmp: Fix phy pipe clock gating + - drm/bridge: sii902x: Retry status read after DDI I2C + - tools: hv: fix compiler warnings about major/target_fname + - block: null_blk: fix 'Invalid parameters' when loading module + - dmaengine: pl330: fix a race condition in case of threaded irqs + - dmaengine: rcar-dmac: Check the done lists in rcar_dmac_chan_get_residue() + - enic: enable rq before updating rq descriptors + - watchdog: asm9260_wdt: fix error handling in asm9260_wdt_probe() + - hwrng: stm32 - add reset during probe + - pinctrl: devicetree: Fix dt_to_map_one_config handling of hogs + - pinctrl: artpec6: dt: add missing pin group uart5nocts + - vfio-ccw: fence off transport mode + - dmaengine: qcom: bam_dma: get num-channels and num-ees from dt + - drm: omapdrm: dss: Move initialization code from component bind to probe + - ARM: dts: dra71-evm: Correct evm_sd regulator max voltage + - drm/amdgpu: disable GFX ring and disable PQ wptr in hw_fini + - drm/amdgpu: adjust timeout for ib_ring_tests(v2) + - net: stmmac: ensure that the device has released ownership before reading + data + - net: stmmac: ensure that the MSS desc is the last desc to set the own bit + - cpufreq: Reorder cpufreq_online() error code path + - dpaa_eth: fix SG mapping + - PCI: Add function 1 DMA alias quirk for Marvell 88SE9220 + - udf: Provide saner default for invalid uid / gid + - ixgbe: prevent ptp_rx_hang from running when in FILTER_ALL mode + - sh_eth: fix TSU init on SH7734/R8A7740 + - power: supply: ltc2941-battery-gauge: Fix temperature units + - ARM: dts: bcm283x: Fix probing of bcm2835-i2s + - ARM: dts: bcm283x: Fix pin function of JTAG pins + - PCMCIA / PM: Avoid noirq suspend aborts during suspend-to-idle + - audit: return on memory error to avoid null pointer dereference + - net: stmmac: call correct function in stmmac_mac_config_rx_queues_routing() + - rcu: Call touch_nmi_watchdog() while printing stall warnings + - pinctrl: sh-pfc: r8a7796: Fix MOD_SEL register pin assignment for SSI pins + group + - dpaa_eth: fix pause capability advertisement logic + - MIPS: Octeon: Fix logging messages with spurious periods after newlines + - drm/rockchip: Respect page offset for PRIME mmap calls + - x86/apic: Set up through-local-APIC mode on the boot CPU if 'noapic' + specified + - perf test: Fix test case inet_pton to accept inlines. + - perf report: Fix wrong jump arrow + - perf tests: Use arch__compare_symbol_names to compare symbols + - perf report: Fix memory corruption in --branch-history mode --branch-history + - perf tests: Fix dwarf unwind for stripped binaries + - selftests/net: fixes psock_fanout eBPF test case + - netlabel: If PF_INET6, check sk_buff ip header version + - drm: rcar-du: lvds: Fix LVDS startup on R-Car Gen3 + - drm: rcar-du: lvds: Fix LVDS startup on R-Car Gen2 + - ARM: dts: at91: tse850: use the correct compatible for the eeprom + - regmap: Correct comparison in regmap_cached + - i40e: Add delay after EMP reset for firmware to recover + - ARM: dts: imx7d: cl-som-imx7: fix pinctrl_enet + - ARM: dts: porter: Fix HDMI output routing + - regulator: of: Add a missing 'of_node_put()' in an error handling path of + 'of_regulator_match()' + - pinctrl: mcp23s08: spi: Fix regmap debugfs entries + - kdb: make "mdr" command repeat + - drm/vmwgfx: Set dmabuf_size when vmw_dmabuf_init is successful + - perf tools: Add trace/beauty/generated/ into .gitignore + - tools: sync up .h files with the repective arch and uapi .h files + - MIPS: xilfpga: Stop generating useless dtb.o + - MIPS: xilfpga: Actually include FDT in fitImage + - MIPS: Fix build with DEBUG_ZBOOT and MACH_JZ4770 + - fix breakage caused by d_find_alias() semantics change + - Btrfs: fix error handling in btrfs_truncate() + - mmc: block: propagate correct returned value in mmc_rpmb_ioctl + - arm64: export tishift functions to modules + - bcma: fix buffer size caused crash in bcma_core_mips_print_irq() + - PM / core: Fix direct_complete handling for devices with no callbacks + - ARM: dts: sun4i: Fix incorrect clocks for displays + - bnxt_en: Ignore src port field in decap filter nodes + - kasan, slub: fix handling of kasan_slab_free hook + - riscv/spinlock: Strengthen implementations with fences + - platform/x86: dell-smbios: Fix memory leaks in build_tokens_sysfs() + - rxrpc: Fix resend event time calculation + - i40e: hold the RTNL lock while changing interrupt schemes + - hv_netvsc: Fix the return status in RX path + - firmware: fix checking for return values for fw_add_devm_name() + - bcache: set writeback_rate_update_seconds in range [1, 60] seconds + - bcache: fix cached_dev->count usage for bch_cache_set_error() + - bcache: stop dc->writeback_rate_update properly + - ibmvnic: Fix reset return from closed state + - powerpc/vas: Fix cleanup when VAS is not configured + - f2fs: flush cp pack except cp pack 2 page at first + - drm/amdgpu: Clean sdma wptr register when only enable wptr polling + - powerpc/mm/slice: Remove intermediate bitmap copy + - powerpc/mm/slice: create header files dedicated to slices + - powerpc/mm/slice: Enhance for supporting PPC32 + - powerpc/mm/slice: Fix hugepage allocation at hint address on 8xx + - ibmvnic: Allocate statistics buffers during probe + - dt-bindings: display: msm/dsi: Fix the PHY regulator supply props + - drm/amd/display: Set vsc pack revision when DPCD revision is >= 1.2 + - soc: renesas: r8a77970-sysc: fix power area parents + - drm/vblank: Data type fixes for 64-bit vblank sequences. + - selftests: Add FIB onlink tests + - soc: amlogic: meson-gx-pwrc-vpu: fix error on shutdown when domain is + powered off + * arm-smmu-v3 arm-smmu-v3.1.auto: failed to allocate MSIs (LP: #1785282) + - ACPICA: iasl: Add SMMUv3 device ID mapping index support + - ACPI/IORT: Remove temporary iort_get_id_mapping_index() ACPICA guard + * Driver iwlwifi for Intel Wireless-AC 9560 is slow and unreliable in kernel + 4.15.0-20-generic (LP: #1772467) + - scsi: hpsa: disable device during shutdown + * [Bionic] i2c: xlp9xx: Add SMBAlert support (LP: #1786981) + - i2c: xlp9xx: Add support for SMBAlert + * qeth: don't clobber buffer on async TX completion (LP: #1786057) + - s390/qeth: don't clobber buffer on async TX completion + * Linux 4.15.0-23 crashes during the boot process with a "Unable to handle + kernel NULL pointer dereference" message (LP: #1777338) + - x86/xen: Add call of speculative_store_bypass_ht_init() to PV paths + * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058) + - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio + * [Bionic] i2c: xlp9xx: Fix case where SSIF read transaction completes early + (LP: #1787240) + - i2c: xlp9xx: Fix case where SSIF read transaction completes early + * [Bionic] integrate upstream fix for Cavium zram driver (LP: #1787469) + - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from + CONFIG_VMAP_STACK" + - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK + - crypto: cavium - Limit result reading attempts + - crypto: cavium - Prevent division by zero + - crypto: cavium - Fix statistics pending request value + - crypto: cavium - Fix smp_processor_id() warnings + * Bugfix for handling of shadow doorbell buffer (LP: #1788222) + - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event + * nvme devices namespace assigned to the wrong controller (LP: #1789227) + - nvme/multipath: Fix multipath disabled naming collisions + * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before + walinuxagent.service (LP: #1739107) + - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before + walinuxagent.service + * hinic interfaces aren't getting predictable names (LP: #1783138) + - hinic: Link the logical network device to the pci device in sysfs + * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and + Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950) + - ACPI / LPSS: Avoid PM quirks on suspend and resume from S3 + - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation + * [Bionic] Bluetooth: Support RTL8723D and RTL8821C Devices (LP: #1784835) + - Bluetooth: btrtl: Add RTL8723D and RTL8821C devices + * CacheFiles: Error: Overlong wait for old active object to go away. + (LP: #1776254) + - cachefiles: Fix missing clear of the CACHEFILES_OBJECT_ACTIVE flag + - cachefiles: Wait rather than BUG'ing on "Unexpected object collision" + * fscache cookie refcount updated incorrectly during fscache object allocation + (LP: #1776277) // fscache cookie refcount updated incorrectly during fscache + object allocation (LP: #1776277) + - fscache: Fix reference overput in fscache_attach_object() error handling + * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336) + - Revert "UBUNTU: SAUCE: CacheFiles: fix a read_waiter/read_copier race" + - fscache: Allow cancelled operations to be enqueued + - cachefiles: Fix refcounting bug in backing-file read monitoring + * SMB3: Fix regression in server reconnect detection (LP: #1786110) + - smb3: on reconnect set PreviousSessionId field + * CVE-2018-1118 + - vhost: fix info leak due to uninitialized memory + + [ Ubuntu: 4.15.0-33.36 ] + + * linux: 4.15.0-33.36 -proposed tracker (LP: #1787149) + * RTNL assertion failure on ipvlan (LP: #1776927) + - ipvlan: drop ipv6 dependency + - ipvlan: use per device spinlock to protect addrs list updates + - SAUCE: fix warning from "ipvlan: drop ipv6 dependency" + * ubuntu_bpf_jit test failed on Bionic s390x systems (LP: #1753941) + - test_bpf: flag tests that cannot be jited on s390 + * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689) + - drm/nouveau: fix nouveau_dsm_get_client_id()'s return type + - drm/radeon: fix radeon_atpx_get_client_id()'s return type + - drm/amdgpu: fix amdgpu_atpx_get_client_id()'s return type + - platform/x86: apple-gmux: fix gmux_get_client_id()'s return type + - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA + - vga_switcheroo: set audio client id according to bound GPU id + * locking sockets broken due to missing AppArmor socket mediation patches + (LP: #1780227) + - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets + * Update2 for ocxl driver (LP: #1781436) + - ocxl: Fix page fault handler in case of fault on dying process + * netns: unable to follow an interface that moves to another netns + (LP: #1774225) + - net: core: Expose number of link up/down transitions + - dev: always advertise the new nsid when the netns iface changes + - dev: advertise the new ifindex when the netns iface changes + * [Bionic] Disk IO hangs when using BFQ as io scheduler (LP: #1780066) + - block, bfq: fix occurrences of request finish method's old name + - block, bfq: remove batches of confusing ifdefs + - block, bfq: add requeue-request hook + * HP ProBook 455 G5 needs mute-led-gpio fixup (LP: #1781763) + - ALSA: hda: add mute led support for HP ProBook 455 G5 + * [Bionic] bug fixes to improve stability of the ThunderX2 i2c driver + (LP: #1781476) + - i2c: xlp9xx: Fix issue seen when updating receive length + - i2c: xlp9xx: Make sure the transfer size is not more than + I2C_SMBUS_BLOCK_SIZE + * x86/kvm: fix LAPIC timer drift when guest uses periodic mode (LP: #1778486) + - x86/kvm: fix LAPIC timer drift when guest uses periodic mode + * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823) + - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules + * Nvidia fails after switching its mode (LP: #1778658) + - PCI: Restore config space on runtime resume despite being unbound + * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364) + - SAUCE: (noup) zfs to 0.7.5-1ubuntu16.3 + * CVE-2018-12232 + - PATCH 1/1] socket: close race condition between sock_close() and + sockfs_setattr() + * CVE-2018-10323 + - xfs: set format back to extents if xfs_bmap_extents_to_btree + * change front mic location for more lenovo m7/8/9xx machines (LP: #1781316) + - ALSA: hda/realtek - Fix the problem of two front mics on more machines + - ALSA: hda/realtek - two more lenovo models need fixup of MIC_LOCATION + * Cephfs + fscache: unable to handle kernel NULL pointer dereference at + 0000000000000000 IP: jbd2__journal_start+0x22/0x1f0 (LP: #1783246) + - ceph: track read contexts in ceph_file_info + * Touchpad of ThinkPad P52 failed to work with message "lost sync at byte" + (LP: #1779802) + - Input: elantech - fix V4 report decoding for module with middle key + - Input: elantech - enable middle button of touchpads on ThinkPad P52 + * xhci_hcd 0000:00:14.0: Root hub is not suspended (LP: #1779823) + - usb: xhci: dbc: Fix lockdep warning + - usb: xhci: dbc: Don't decrement runtime PM counter if DBC is not started + * CVE-2018-13406 + - video: uvesafb: Fix integer overflow in allocation + * CVE-2018-10840 + - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs + * CVE-2018-11412 + - ext4: do not allow external inodes for inline data + * CVE-2018-10881 + - ext4: clear i_data in ext4_inode_info when removing inline data + * CVE-2018-12233 + - jfs: Fix inconsistency between memory allocation and ea_buf->max_size + * CVE-2018-12904 + - kvm: nVMX: Enforce cpl=0 for VMX instructions + * Error parsing PCC subspaces from PCCT (LP: #1528684) + - mailbox: PCC: erroneous error message when parsing ACPI PCCT + * CVE-2018-13094 + - xfs: don't call xfs_da_shrink_inode with NULL bp + * other users' coredumps can be read via setgid directory and killpriv bypass + (LP: #1779923) // CVE-2018-13405 + - Fix up non-directory creation in SGID directories + * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166) + - snapcraft.yaml: stop invoking the obsolete (and non-existing) + 'firmware_install' target + * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build + (LP: #1782116) + - snapcraft.yaml: copy retpoline-extract-one to scripts before build + * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540) + - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge + * CVE-2018-11506 + - sr: pass down correctly sized SCSI sense buffer + * Bionic update: upstream stable patchset 2018-07-24 (LP: #1783418) + - net: Fix a bug in removing queues from XPS map + - net/mlx4_core: Fix error handling in mlx4_init_port_info. + - net/sched: fix refcnt leak in the error path of tcf_vlan_init() + - net: sched: red: avoid hashing NULL child + - net/smc: check for missing nlattrs in SMC_PNETID messages + - net: test tailroom before appending to linear skb + - packet: in packet_snd start writing at link layer allocation + - sock_diag: fix use-after-free read in __sk_free + - tcp: purge write queue in tcp_connect_init() + - vmxnet3: set the DMA mask before the first DMA map operation + - vmxnet3: use DMA memory barriers where required + - hv_netvsc: empty current transmit aggregation if flow blocked + - hv_netvsc: Use the num_online_cpus() for channel limit + - hv_netvsc: avoid retry on send during shutdown + - hv_netvsc: only wake transmit queue if link is up + - hv_netvsc: fix error unwind handling if vmbus_open fails + - hv_netvsc: cancel subchannel setup before halting device + - hv_netvsc: fix race in napi poll when rescheduling + - hv_netvsc: defer queue selection to VF + - hv_netvsc: disable NAPI before channel close + - hv_netvsc: use RCU to fix concurrent rx and queue changes + - hv_netvsc: change GPAD teardown order on older versions + - hv_netvsc: common detach logic + - hv_netvsc: Use Windows version instead of NVSP version on GPAD teardown + - hv_netvsc: Split netvsc_revoke_buf() and netvsc_teardown_gpadl() + - hv_netvsc: Ensure correct teardown message sequence order + - hv_netvsc: Fix a network regression after ifdown/ifup + - sparc: vio: use put_device() instead of kfree() + - ext2: fix a block leak + - s390: add assembler macros for CPU alternatives + - s390: move expoline assembler macros to a header + - s390/crc32-vx: use expoline for indirect branches + - s390/lib: use expoline for indirect branches + - s390/ftrace: use expoline for indirect branches + - s390/kernel: use expoline for indirect branches + - s390: move spectre sysfs attribute code + - s390: extend expoline to BC instructions + - s390: use expoline thunks in the BPF JIT + - scsi: sg: allocate with __GFP_ZERO in sg_build_indirect() + - scsi: zfcp: fix infinite iteration on ERP ready list + - loop: don't call into filesystem while holding lo_ctl_mutex + - loop: fix LOOP_GET_STATUS lock imbalance + - cfg80211: limit wiphy names to 128 bytes + - hfsplus: stop workqueue when fill_super() failed + - x86/kexec: Avoid double free_page() upon do_kexec_load() failure + - usb: gadget: f_uac2: fix bFirstInterface in composite gadget + - usb: dwc3: Undo PHY init if soft reset fails + - usb: dwc3: omap: don't miss events during suspend/resume + - usb: gadget: core: Fix use-after-free of usb_request + - usb: gadget: fsl_udc_core: fix ep valid checks + - usb: dwc2: Fix dwc2_hsotg_core_init_disconnected() + - usb: cdc_acm: prevent race at write to acm while system resumes + - net: usbnet: fix potential deadlock on 32bit hosts + - ARM: dts: imx7d-sdb: Fix regulator-usb-otg2-vbus node name + - usb: host: xhci-plat: revert "usb: host: xhci-plat: enable clk in resume + timing" + - USB: OHCI: Fix NULL dereference in HCDs using HCD_LOCAL_MEM + - net/usb/qmi_wwan.c: Add USB id for lt4120 modem + - net-usb: add qmi_wwan if on lte modem wistron neweb d18q1 + - Bluetooth: btusb: Add USB ID 7392:a611 for Edimax EW-7611ULB + - ALSA: usb-audio: Add native DSD support for Luxman DA-06 + - usb: dwc3: Add SoftReset PHY synchonization delay + - usb: dwc3: Update DWC_usb31 GTXFIFOSIZ reg fields + - usb: dwc3: Makefile: fix link error on randconfig + - xhci: zero usb device slot_id member when disabling and freeing a xhci slot + - usb: dwc2: Fix interval type issue + - usb: dwc2: hcd: Fix host channel halt flow + - usb: dwc2: host: Fix transaction errors in host mode + - usb: gadget: ffs: Let setup() return USB_GADGET_DELAYED_STATUS + - usb: gadget: ffs: Execute copy_to_user() with USER_DS set + - usbip: Correct maximum value of CONFIG_USBIP_VHCI_HC_PORTS + - usb: gadget: udc: change comparison to bitshift when dealing with a mask + - usb: gadget: composite: fix incorrect handling of OS desc requests + - media: lgdt3306a: Fix module count mismatch on usb unplug + - media: em28xx: USB bulk packet size fix + - Bluetooth: btusb: Add device ID for RTL8822BE + - xhci: Show what USB release number the xHC supports from protocol capablity + - staging: bcm2835-audio: Release resources on module_exit() + - staging: lustre: fix bug in osc_enter_cache_try + - staging: fsl-dpaa2/eth: Fix incorrect casts + - staging: rtl8192u: return -ENOMEM on failed allocation of priv->oldaddr + - staging: ks7010: Use constants from ieee80211_eid instead of literal ints. + - staging: lustre: lmv: correctly iput lmo_root + - crypto: inside-secure - wait for the request to complete if in the backlog + - crypto: atmel-aes - fix the keys zeroing on errors + - crypto: ccp - don't disable interrupts while setting up debugfs + - crypto: inside-secure - do not process request if no command was issued + - crypto: inside-secure - fix the cache_len computation + - crypto: inside-secure - fix the extra cache computation + - crypto: sunxi-ss - Add MODULE_ALIAS to sun4i-ss + - crypto: inside-secure - fix the invalidation step during cra_exit + - scsi: mpt3sas: fix an out of bound write + - scsi: ufs: Enable quirk to ignore sending WRITE_SAME command + - scsi: bnx2fc: Fix check in SCSI completion handler for timed out request + - scsi: sym53c8xx_2: iterator underflow in sym_getsync() + - scsi: mptfusion: Add bounds check in mptctl_hp_targetinfo() + - scsi: qla2xxx: Avoid triggering undefined behavior in + qla2x00_mbx_completion() + - scsi: storvsc: Increase cmd_per_lun for higher speed devices + - scsi: qedi: Fix truncation of CHAP name and secret + - scsi: aacraid: fix shutdown crash when init fails + - scsi: qla4xxx: skip error recovery in case of register disconnect. + - scsi: qedi: Fix kernel crash during port toggle + - scsi: mpt3sas: Do not mark fw_event workqueue as WQ_MEM_RECLAIM + - scsi: sd: Keep disk read-only when re-reading partition + - scsi: iscsi_tcp: set BDI_CAP_STABLE_WRITES when data digest enabled + - scsi: aacraid: Insure command thread is not recursively stopped + - scsi: core: Make SCSI Status CONDITION MET equivalent to GOOD + - scsi: mvsas: fix wrong endianness of sgpio api + - ASoC: hdmi-codec: Fix module unloading caused kernel crash + - ASoC: rockchip: rk3288-hdmi-analog: Select needed codecs + - ASoC: samsung: odroid: Fix 32000 sample rate handling + - ASoC: topology: create TLV data for dapm widgets + - ASoC: samsung: i2s: Ensure the RCLK rate is properly determined + - clk: rockchip: Fix wrong parent for SDMMC phase clock for rk3228 + - clk: Don't show the incorrect clock phase + - clk: hisilicon: mark wdt_mux_p[] as const + - clk: tegra: Fix pll_u rate configuration + - clk: rockchip: Prevent calculating mmc phase if clock rate is zero + - clk: samsung: s3c2410: Fix PLL rates + - clk: samsung: exynos7: Fix PLL rates + - clk: samsung: exynos5260: Fix PLL rates + - clk: samsung: exynos5433: Fix PLL rates + - clk: samsung: exynos5250: Fix PLL rates + - clk: samsung: exynos3250: Fix PLL rates + - media: dmxdev: fix error code for invalid ioctls + - media: Don't let tvp5150_get_vbi() go out of vbi_ram_default array + - media: ov5645: add missing of_node_put() in error path + - media: cx23885: Override 888 ImpactVCBe crystal frequency + - media: cx23885: Set subdev host data to clk_freq pointer + - media: s3c-camif: fix out-of-bounds array access + - media: lgdt3306a: Fix a double kfree on i2c device remove + - media: em28xx: Add Hauppauge SoloHD/DualHD bulk models + - media: v4l: vsp1: Fix display stalls when requesting too many inputs + - media: i2c: adv748x: fix HDMI field heights + - media: vb2: Fix videobuf2 to map correct area + - media: vivid: fix incorrect capabilities for radio + - media: cx25821: prevent out-of-bounds read on array card + - serial: xuartps: Fix out-of-bounds access through DT alias + - serial: sh-sci: Fix out-of-bounds access through DT alias + - serial: samsung: Fix out-of-bounds access through serial port index + - serial: mxs-auart: Fix out-of-bounds access through serial port index + - serial: imx: Fix out-of-bounds access through serial port index + - serial: fsl_lpuart: Fix out-of-bounds access through DT alias + - serial: arc_uart: Fix out-of-bounds access through DT alias + - serial: 8250: Don't service RX FIFO if interrupts are disabled + - serial: altera: ensure port->regshift is honored consistently + - rtc: snvs: Fix usage of snvs_rtc_enable + - rtc: hctosys: Ensure system time doesn't overflow time_t + - rtc: rk808: fix possible race condition + - rtc: m41t80: fix race conditions + - rtc: tx4939: avoid unintended sign extension on a 24 bit shift + - rtc: rp5c01: fix possible race condition + - rtc: goldfish: Add missing MODULE_LICENSE + - cxgb4: Correct ntuple mask validation for hash filters + - net: dsa: bcm_sf2: Fix RX_CLS_LOC_ANY overwrite for last rule + - net: dsa: Do not register devlink for unused ports + - net: dsa: bcm_sf2: Fix IPv6 rules and chain ID + - net: dsa: bcm_sf2: Fix IPv6 rule half deletion + - 3c59x: convert to generic DMA API + - net: ip6_gre: Request headroom in __gre6_xmit() + - net: ip6_gre: Split up ip6gre_tnl_link_config() + - net: ip6_gre: Split up ip6gre_tnl_change() + - net: ip6_gre: Split up ip6gre_newlink() + - net: ip6_gre: Split up ip6gre_changelink() + - qed: LL2 flush isles when connection is closed + - qed: Fix possibility of list corruption during rmmod flows + - qed: Fix LL2 race during connection terminate + - powerpc: Move default security feature flags + - Bluetooth: btusb: Add support for Intel Bluetooth device 22560 [8087:0026] + - staging: fsl-dpaa2/eth: Fix incorrect kfree + - crypto: inside-secure - move the digest to the request context + - scsi: lpfc: Fix NVME Initiator FirstBurst + - serial: mvebu-uart: fix tx lost characters + * Bionic update: upstream stable patchset 2018-07-20 (LP: #1782846) + - usbip: usbip_host: refine probe and disconnect debug msgs to be useful + - usbip: usbip_host: delete device from busid_table after rebind + - usbip: usbip_host: run rebind from exit when module is removed + - usbip: usbip_host: fix NULL-ptr deref and use-after-free errors + - usbip: usbip_host: fix bad unlock balance during stub_probe() + - ALSA: usb: mixer: volume quirk for CM102-A+/102S+ + - ALSA: hda: Add Lenovo C50 All in one to the power_save blacklist + - ALSA: control: fix a redundant-copy issue + - spi: pxa2xx: Allow 64-bit DMA + - spi: bcm-qspi: Avoid setting MSPI_CDRAM_PCS for spi-nor master + - spi: bcm-qspi: Always read and set BSPI_MAST_N_BOOT_CTRL + - KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls + - KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock + - vfio: ccw: fix cleanup if cp_prefetch fails + - tracing/x86/xen: Remove zero data size trace events + trace_xen_mmu_flush_tlb{_all} + - tee: shm: fix use-after-free via temporarily dropped reference + - netfilter: nf_tables: free set name in error path + - netfilter: nf_tables: can't fail after linking rule into active rule list + - netfilter: nf_socket: Fix out of bounds access in nf_sk_lookup_slow_v{4,6} + - i2c: designware: fix poll-after-enable regression + - powerpc/powernv: Fix NVRAM sleep in invalid context when crashing + - drm: Match sysfs name in link removal to link creation + - lib/test_bitmap.c: fix bitmap optimisation tests to report errors correctly + - radix tree: fix multi-order iteration race + - mm: don't allow deferred pages with NEED_PER_CPU_KM + - drm/i915/gen9: Add WaClearHIZ_WM_CHICKEN3 for bxt and glk + - s390/qdio: fix access to uninitialized qdio_q fields + - s390/qdio: don't release memory in qdio_setup_irq() + - s390: remove indirect branch from do_softirq_own_stack + - x86/pkeys: Override pkey when moving away from PROT_EXEC + - x86/pkeys: Do not special case protection key 0 + - efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' + definition for mixed mode + - ARM: 8771/1: kprobes: Prohibit kprobes on do_undefinstr + - x86/mm: Drop TS_COMPAT on 64-bit exec() syscall + - tick/broadcast: Use for_each_cpu() specially on UP kernels + - ARM: 8769/1: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed + - ARM: 8770/1: kprobes: Prohibit probing on optimized_callback + - ARM: 8772/1: kprobes: Prohibit kprobes on get_user functions + - Btrfs: fix xattr loss after power failure + - Btrfs: send, fix invalid access to commit roots due to concurrent + snapshotting + - btrfs: property: Set incompat flag if lzo/zstd compression is set + - btrfs: fix crash when trying to resume balance without the resume flag + - btrfs: Split btrfs_del_delalloc_inode into 2 functions + - btrfs: Fix delalloc inodes invalidation during transaction abort + - btrfs: fix reading stale metadata blocks after degraded raid1 mounts + - xhci: Fix USB3 NULL pointer dereference at logical disconnect. + - KVM: arm/arm64: Properly protect VGIC locks from IRQs + - KVM: arm/arm64: VGIC/ITS: Promote irq_lock() in update_affinity + - hwmon: (k10temp) Fix reading critical temperature register + - hwmon: (k10temp) Use API function to access System Management Network + - vsprintf: Replace memory barrier with static_key for random_ptr_key update + - x86/amd_nb: Add support for Raven Ridge CPUs + - x86/apic/x2apic: Initialize cluster ID properly + * Bionic update: upstream stable patchset 2018-07-09 (LP: #1780858) + - 8139too: Use disable_irq_nosync() in rtl8139_poll_controller() + - bridge: check iface upper dev when setting master via ioctl + - dccp: fix tasklet usage + - ipv4: fix fnhe usage by non-cached routes + - ipv4: fix memory leaks in udp_sendmsg, ping_v4_sendmsg + - llc: better deal with too small mtu + - net: ethernet: sun: niu set correct packet size in skb + - net: ethernet: ti: cpsw: fix packet leaking in dual_mac mode + - net/mlx4_en: Fix an error handling path in 'mlx4_en_init_netdev()' + - net/mlx4_en: Verify coalescing parameters are in range + - net/mlx5e: Err if asked to offload TC match on frag being first + - net/mlx5: E-Switch, Include VF RDMA stats in vport statistics + - net sched actions: fix refcnt leak in skbmod + - net_sched: fq: take care of throttled flows before reuse + - net: support compat 64-bit time in {s,g}etsockopt + - net/tls: Don't recursively call push_record during tls_write_space callbacks + - net/tls: Fix connection stall on partial tls record + - openvswitch: Don't swap table in nlattr_set() after OVS_ATTR_NESTED is found + - qmi_wwan: do not steal interfaces from class drivers + - r8169: fix powering up RTL8168h + - rds: do not leak kernel memory to user land + - sctp: delay the authentication for the duplicated cookie-echo chunk + - sctp: fix the issue that the cookie-ack with auth can't get processed + - sctp: handle two v4 addrs comparison in sctp_inet6_cmp_addr + - sctp: remove sctp_chunk_put from fail_mark err path in + sctp_ulpevent_make_rcvmsg + - sctp: use the old asoc when making the cookie-ack chunk in dupcook_d + - tcp_bbr: fix to zero idle_restart only upon S/ACKed data + - tcp: ignore Fast Open on repair mode + - tg3: Fix vunmap() BUG_ON() triggered from tg3_free_consistent(). + - bonding: do not allow rlb updates to invalid mac + - bonding: send learning packets for vlans on slave + - net: sched: fix error path in tcf_proto_create() when modules are not + configured + - net/mlx5e: TX, Use correct counter in dma_map error flow + - net/mlx5: Avoid cleaning flow steering table twice during error flow + - hv_netvsc: set master device + - ipv6: fix uninit-value in ip6_multipath_l3_keys() + - net/mlx5e: Allow offloading ipv4 header re-write for icmp + - nsh: fix infinite loop + - udp: fix SO_BINDTODEVICE + - l2tp: revert "l2tp: fix missing print session offset info" + - proc: do not access cmdline nor environ from file-backed areas + - net/smc: restrict non-blocking connect finish + - mlxsw: spectrum_switchdev: Do not remove mrouter port from MDB's ports list + - net/mlx5e: DCBNL fix min inline header size for dscp + - net: systemport: Correclty disambiguate driver instances + - sctp: clear the new asoc's stream outcnt in sctp_stream_update + - tcp: restore autocorking + - tipc: fix one byte leak in tipc_sk_set_orig_addr() + - hv_netvsc: Fix net device attach on older Windows hosts + * Bionic update: upstream stable patchset 2018-07-06 (LP: #1780499) + - ext4: prevent right-shifting extents beyond EXT_MAX_BLOCKS + - ipvs: fix rtnl_lock lockups caused by start_sync_thread + - netfilter: ebtables: don't attempt to allocate 0-sized compat array + - kcm: Call strp_stop before strp_done in kcm_attach + - crypto: af_alg - fix possible uninit-value in alg_bind() + - netlink: fix uninit-value in netlink_sendmsg + - net: fix rtnh_ok() + - net: initialize skb->peeked when cloning + - net: fix uninit-value in __hw_addr_add_ex() + - dccp: initialize ireq->ir_mark + - ipv4: fix uninit-value in ip_route_output_key_hash_rcu() + - soreuseport: initialise timewait reuseport field + - inetpeer: fix uninit-value in inet_getpeer + - memcg: fix per_node_info cleanup + - perf: Remove superfluous allocation error check + - tcp: fix TCP_REPAIR_QUEUE bound checking + - bdi: wake up concurrent wb_shutdown() callers. + - bdi: Fix oops in wb_workfn() + - gpioib: do not free unrequested descriptors + - gpio: fix aspeed_gpio unmask irq + - gpio: fix error path in lineevent_create + - rfkill: gpio: fix memory leak in probe error path + - libata: Apply NOLPM quirk for SanDisk SD7UB3Q*G1001 SSDs + - dm integrity: use kvfree for kvmalloc'd memory + - tracing: Fix regex_match_front() to not over compare the test string + - z3fold: fix reclaim lock-ups + - mm: sections are not offlined during memory hotremove + - mm, oom: fix concurrent munlock and oom reaper unmap, v3 + - ceph: fix rsize/wsize capping in ceph_direct_read_write() + - can: kvaser_usb: Increase correct stats counter in kvaser_usb_rx_can_msg() + - can: hi311x: Acquire SPI lock on ->do_get_berr_counter + - can: hi311x: Work around TX complete interrupt erratum + - drm/vc4: Fix scaling of uni-planar formats + - drm/i915: Fix drm:intel_enable_lvds ERROR message in kernel log + - drm/atomic: Clean old_state/new_state in drm_atomic_state_default_clear() + - drm/atomic: Clean private obj old_state/new_state in + drm_atomic_state_default_clear() + - net: atm: Fix potential Spectre v1 + - atm: zatm: Fix potential Spectre v1 + - cpufreq: schedutil: Avoid using invalid next_freq + - Revert "Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174" + - Bluetooth: btusb: Only check needs_reset_resume DMI table for QCA rome + chipsets + - thermal: exynos: Reading temperature makes sense only when TMU is turned on + - thermal: exynos: Propagate error value from tmu_read() + - nvme: add quirk to force medium priority for SQ creation + - smb3: directory sync should not return an error + - sched/autogroup: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] + - tracing/uprobe_event: Fix strncpy corner case + - perf/x86: Fix possible Spectre-v1 indexing for hw_perf_event cache_* + - perf/x86/cstate: Fix possible Spectre-v1 indexing for pkg_msr + - perf/x86/msr: Fix possible Spectre-v1 indexing in the MSR driver + - perf/core: Fix possible Spectre-v1 indexing for ->aux_pages[] + - perf/x86: Fix possible Spectre-v1 indexing for x86_pmu::event_map() + - i2c: dev: prevent ZERO_SIZE_PTR deref in i2cdev_ioctl_rdwr() + - bdi: Fix use after free bug in debugfs_remove() + - drm/ttm: Use GFP_TRANSHUGE_LIGHT for allocating huge pages + - drm/i915: Adjust eDP's logical vco in a reliable place. + - drm/nouveau/ttm: don't dereference nvbo::cli, it can outlive client + - sched/core: Fix possible Spectre-v1 indexing for sched_prio_to_weight[] + * Bionic update: upstream stable patchset 2018-06-26 (LP: #1778759) + - percpu: include linux/sched.h for cond_resched() + - ACPI / button: make module loadable when booted in non-ACPI mode + - USB: serial: option: Add support for Quectel EP06 + - ALSA: hda - Fix incorrect usage of IS_REACHABLE() + - ALSA: pcm: Check PCM state at xfern compat ioctl + - ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger() + - ALSA: dice: fix kernel NULL pointer dereference due to invalid calculation + for array index + - ALSA: aloop: Mark paused device as inactive + - ALSA: aloop: Add missing cable lock to ctl API callbacks + - tracepoint: Do not warn on ENOMEM + - scsi: target: Fix fortify_panic kernel exception + - Input: leds - fix out of bound access + - Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro + - rtlwifi: btcoex: Add power_on_setting routine + - rtlwifi: cleanup 8723be ant_sel definition + - xfs: prevent creating negative-sized file via INSERT_RANGE + - RDMA/cxgb4: release hw resources on device removal + - RDMA/ucma: Allow resolving address w/o specifying source address + - RDMA/mlx5: Fix multiple NULL-ptr deref errors in rereg_mr flow + - RDMA/mlx5: Protect from shift operand overflow + - NET: usb: qmi_wwan: add support for ublox R410M PID 0x90b2 + - IB/mlx5: Use unlimited rate when static rate is not supported + - IB/hfi1: Fix handling of FECN marked multicast packet + - IB/hfi1: Fix loss of BECN with AHG + - IB/hfi1: Fix NULL pointer dereference when invalid num_vls is used + - iw_cxgb4: Atomically flush per QP HW CQEs + - drm/vmwgfx: Fix a buffer object leak + - drm/bridge: vga-dac: Fix edid memory leak + - test_firmware: fix setting old custom fw path back on exit, second try + - errseq: Always report a writeback error once + - USB: serial: visor: handle potential invalid device configuration + - usb: dwc3: gadget: Fix list_del corruption in dwc3_ep_dequeue + - USB: Accept bulk endpoints with 1024-byte maxpacket + - USB: serial: option: reimplement interface masking + - USB: serial: option: adding support for ublox R410M + - usb: musb: host: fix potential NULL pointer dereference + - usb: musb: trace: fix NULL pointer dereference in musb_g_tx() + - platform/x86: asus-wireless: Fix NULL pointer dereference + - irqchip/qcom: Fix check for spurious interrupts + - tracing: Fix bad use of igrab in trace_uprobe.c + - [Config] CONFIG_ARM64_ERRATUM_1024718=y + - arm64: Add work around for Arm Cortex-A55 Erratum 1024718 + - Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro + - infiniband: mlx5: fix build errors when INFINIBAND_USER_ACCESS=m + - btrfs: Take trans lock before access running trans in check_delayed_ref + - drm/vc4: Make sure vc4_bo_{inc,dec}_usecnt() calls are balanced + - xhci: Fix use-after-free in xhci_free_virt_device + - platform/x86: Kconfig: Fix dell-laptop dependency chain. + - KVM: x86: remove APIC Timer periodic/oneshot spikes + - clocksource: Allow clocksource_mark_unstable() on unregistered clocksources + - clocksource: Initialize cs->wd_list + - clocksource: Consistent de-rate when marking unstable + * Bionic update: upstream stable patchset 2018-06-22 (LP: #1778265) + - ext4: set h_journal if there is a failure starting a reserved handle + - ext4: add MODULE_SOFTDEP to ensure crc32c is included in the initramfs + - ext4: add validity checks for bitmap block numbers + - ext4: fix bitmap position validation + - random: fix possible sleeping allocation from irq context + - random: rate limit unseeded randomness warnings + - usbip: usbip_event: fix to not print kernel pointer address + - usbip: usbip_host: fix to hold parent lock for device_attach() calls + - usbip: vhci_hcd: Fix usb device and sockfd leaks + - usbip: vhci_hcd: check rhport before using in vhci_hub_control() + - Revert "xhci: plat: Register shutdown for xhci_plat" + - USB: serial: simple: add libtransistor console + - USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster + - USB: serial: cp210x: add ID for NI USB serial console + - usb: core: Add quirk for HP v222w 16GB Mini + - USB: Increment wakeup count on remote wakeup. + - ALSA: usb-audio: Skip broken EU on Dell dock USB-audio + - virtio: add ability to iterate over vqs + - virtio_console: don't tie bufs to a vq + - virtio_console: free buffers after reset + - virtio_console: drop custom control queue cleanup + - virtio_console: move removal code + - virtio_console: reset on out of memory + - drm/virtio: fix vq wait_event condition + - tty: Don't call panic() at tty_ldisc_init() + - tty: n_gsm: Fix long delays with control frame timeouts in ADM mode + - tty: n_gsm: Fix DLCI handling for ADM mode if debug & 2 is not set + - tty: Avoid possible error pointer dereference at tty_ldisc_restore(). + - tty: Use __GFP_NOFAIL for tty_ldisc_get() + - ALSA: dice: fix OUI for TC group + - ALSA: dice: fix error path to destroy initialized stream data + - ALSA: hda - Skip jack and others for non-existing PCM streams + - ALSA: opl3: Hardening for potential Spectre v1 + - ALSA: asihpi: Hardening for potential Spectre v1 + - ALSA: hdspm: Hardening for potential Spectre v1 + - ALSA: rme9652: Hardening for potential Spectre v1 + - ALSA: control: Hardening for potential Spectre v1 + - ALSA: pcm: Return negative delays from SNDRV_PCM_IOCTL_DELAY. + - ALSA: core: Report audio_tstamp in snd_pcm_sync_ptr + - ALSA: seq: oss: Fix unbalanced use lock for synth MIDI device + - ALSA: seq: oss: Hardening for potential Spectre v1 + - ALSA: hda: Hardening for potential Spectre v1 + - ALSA: hda/realtek - Add some fixes for ALC233 + - ALSA: hda/realtek - Update ALC255 depop optimize + - ALSA: hda/realtek - change the location for one of two front mics + - mtd: spi-nor: cadence-quadspi: Fix page fault kernel panic + - mtd: cfi: cmdset_0001: Do not allow read/write to suspend erase block. + - mtd: cfi: cmdset_0001: Workaround Micron Erase suspend bug. + - mtd: cfi: cmdset_0002: Do not allow read/write to suspend erase block. + - mtd: rawnand: tango: Fix struct clk memory leak + - kobject: don't use WARN for registration failures + - scsi: sd: Defer spinning up drive while SANITIZE is in progress + - bfq-iosched: ensure to clear bic/bfqq pointers when preparing request + - vfio: ccw: process ssch with interrupts disabled + - ANDROID: binder: prevent transactions into own process. + - PCI: aardvark: Fix logic in advk_pcie_{rd,wr}_conf() + - PCI: aardvark: Set PIO_ADDR_LS correctly in advk_pcie_rd_conf() + - PCI: aardvark: Use ISR1 instead of ISR0 interrupt in legacy irq mode + - PCI: aardvark: Fix PCIe Max Read Request Size setting + - ARM: amba: Make driver_override output consistent with other buses + - ARM: amba: Fix race condition with driver_override + - ARM: amba: Don't read past the end of sysfs "driver_override" buffer + - ARM: socfpga_defconfig: Remove QSPI Sector 4K size force + - KVM: arm/arm64: Close VMID generation race + - crypto: drbg - set freed buffers to NULL + - ASoC: fsl_esai: Fix divisor calculation failure at lower ratio + - libceph: un-backoff on tick when we have a authenticated session + - libceph: reschedule a tick in finish_hunting() + - libceph: validate con->state at the top of try_write() + - fpga-manager: altera-ps-spi: preserve nCONFIG state + - earlycon: Use a pointer table to fix __earlycon_table stride + - drm/amdgpu: set COMPUTE_PGM_RSRC1 for SGPR/VGPR clearing shaders + - drm/i915: Enable display WA#1183 from its correct spot + - objtool, perf: Fix GCC 8 -Wrestrict error + - tools/lib/subcmd/pager.c: do not alias select() params + - x86/ipc: Fix x32 version of shmid64_ds and msqid64_ds + - x86/smpboot: Don't use mwait_play_dead() on AMD systems + - x86/microcode/intel: Save microcode patch unconditionally + - x86/microcode: Do not exit early from __reload_late() + - tick/sched: Do not mess with an enqueued hrtimer + - arm/arm64: KVM: Add PSCI version selection API + - powerpc/eeh: Fix race with driver un/bind + - serial: mvebu-uart: Fix local flags handling on termios update + - block: do not use interruptible wait anywhere + - ASoC: dmic: Fix clock parenting + - PCI / PM: Do not clear state_saved in pci_pm_freeze() when smart suspend is + set + - module: Fix display of wrong module .text address + - drm/edid: Reset more of the display info + - drm/i915/fbdev: Enable late fbdev initial configuration + - drm/i915/audio: set minimum CD clock to twice the BCLK + - drm/amd/display: Fix deadlock when flushing irq + - drm/amd/display: Disallow enabling CRTC without primary plane with FB + * Bionic update: upstream stable patchset 2018-06-22 (LP: #1778265) // + CVE-2018-1108. + - random: set up the NUMA crng instances after the CRNG is fully initialized + * Ryzen/Raven Ridge USB ports do not work (LP: #1756700) + - xhci: Fix USB ports for Dell Inspiron 5775 + * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux- + jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389) + - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device + * Need fix to aacraid driver to prevent panic (LP: #1770095) + - scsi: aacraid: Correct hba_send to include iu_type + * kernel: Fix arch random implementation (LP: #1775391) + - s390/archrandom: Rework arch random implementation. + * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390) + - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak. + * Various fixes for CXL kernel module (LP: #1774471) + - cxl: Remove function write_timebase_ctrl_psl9() for PSL9 + - cxl: Set the PBCQ Tunnel BAR register when enabling capi mode + - cxl: Report the tunneled operations status + - cxl: Configure PSL to not use APC virtual machines + - cxl: Disable prefault_mode in Radix mode + * Bluetooth not working (LP: #1764645) + - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models + * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491) + - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y + - SAUCE: wcn36xx: read MAC from file or randomly generate one + * fscache: Fix hanging wait on page discarded by writeback (LP: #1777029) + - fscache: Fix hanging wait on page discarded by writeback + + [ Ubuntu: 4.15.0-32.35 ] + + * CVE-2018-3620 // CVE-2018-3646 + - x86/Centaur: Initialize supported CPU features properly + - x86/Centaur: Report correct CPU/cache topology + - x86/CPU/AMD: Have smp_num_siblings and cpu_llc_id always be present + - perf/events/amd/uncore: Fix amd_uncore_llc ID to use pre-defined cpu_llc_id + - x86/CPU: Rename intel_cacheinfo.c to cacheinfo.c + - x86/CPU/AMD: Calculate last level cache ID from number of sharing threads + - x86/CPU: Modify detect_extended_topology() to return result + - x86/CPU/AMD: Derive CPU topology from CPUID function 0xB when available + - x86/CPU: Move cpu local function declarations to local header + - x86/CPU: Make intel_num_cpu_cores() generic + - x86/CPU: Move cpu_detect_cache_sizes() into init_intel_cacheinfo() + - x86/CPU: Move x86_cpuinfo::x86_max_cores assignment to + detect_num_cpu_cores() + - x86/CPU/AMD: Fix LLC ID bit-shift calculation + - x86/mm: Factor out pageattr _PAGE_GLOBAL setting + - x86/mm: Undo double _PAGE_PSE clearing + - x86/mm: Introduce "default" kernel PTE mask + - x86/espfix: Document use of _PAGE_GLOBAL + - x86/mm: Do not auto-massage page protections + - x86/mm: Remove extra filtering in pageattr code + - x86/mm: Comment _PAGE_GLOBAL mystery + - x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init + - x86/ldt: Fix support_pte_mask filtering in map_ldt_struct() + - x86/power/64: Fix page-table setup for temporary text mapping + - x86/pti: Filter at vma->vm_page_prot population + - x86/boot/64/clang: Use fixup_pointer() to access '__supported_pte_mask' + - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT + - x86/speculation/l1tf: Change order of offset/type in swap entry + - x86/speculation/l1tf: Protect swap entries against L1TF + - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation + - x86/speculation/l1tf: Make sure the first page is always reserved + - x86/speculation/l1tf: Add sysfs reporting for l1tf + - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings + - x86/speculation/l1tf: Limit swap file size to MAX_PA/2 + - x86/bugs: Move the l1tf function and define pr_fmt properly + - sched/smt: Update sched_smt_present at runtime + - x86/smp: Provide topology_is_primary_thread() + - x86/topology: Provide topology_smt_supported() + - cpu/hotplug: Make bringup/teardown of smp threads symmetric + - cpu/hotplug: Split do_cpu_down() + - cpu/hotplug: Provide knobs to control SMT + - x86/cpu: Remove the pointless CPU printout + - x86/cpu/AMD: Remove the pointless detect_ht() call + - x86/cpu/common: Provide detect_ht_early() + - x86/cpu/topology: Provide detect_extended_topology_early() + - x86/cpu/intel: Evaluate smp_num_siblings early + - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info + - x86/cpu/AMD: Evaluate smp_num_siblings early + - x86/apic: Ignore secondary threads if nosmt=force + - x86/speculation/l1tf: Extend 64bit swap file size limit + - x86/cpufeatures: Add detection of L1D cache flush support. + - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings + - x86/speculation/l1tf: Protect PAE swap entries against L1TF + - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE + - Revert "x86/apic: Ignore secondary threads if nosmt=force" + - cpu/hotplug: Boot HT siblings at least once + - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present + - x86/KVM/VMX: Add module argument for L1TF mitigation + - x86/KVM/VMX: Add L1D flush algorithm + - x86/KVM/VMX: Add L1D MSR based flush + - x86/KVM/VMX: Add L1D flush logic + - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers + - x86/KVM/VMX: Add find_msr() helper function + - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting + - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs + - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required + - cpu/hotplug: Online siblings when SMT control is turned on + - x86/litf: Introduce vmx status variable + - x86/kvm: Drop L1TF MSR list approach + - x86/l1tf: Handle EPT disabled state proper + - x86/kvm: Move l1tf setup function + - x86/kvm: Add static key for flush always + - x86/kvm: Serialize L1D flush parameter setter + - x86/kvm: Allow runtime control of L1D flush + - cpu/hotplug: Expose SMT control init function + - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early + - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations + - Documentation: Add section about CPU vulnerabilities + - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures + - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content + - Documentation/l1tf: Fix typos + - cpu/hotplug: detect SMT disabled by BIOS + - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush() + - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond' + - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush() + - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16 + - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d + - x86: Don't include linux/irq.h from asm/hardirq.h + - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d + - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr() + - Documentation/l1tf: Remove Yonah processors from not vulnerable list + - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability + - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry + - KVM: x86: Add a framework for supporting MSR-based features + - KVM: X86: Introduce kvm_get_msr_feature() + - KVM: VMX: support MSR_IA32_ARCH_CAPABILITIES as a feature MSR + - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry + - cpu/hotplug: Fix SMT supported evaluation + - x86/speculation/l1tf: Invert all not present mappings + - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert + - x86/mm/pat: Make set_memory_np() L1TF safe + - cpu: Fix per-cpu regression on ARM64 + * CVE-2018-5391 + - Revert "net: increase fragment memory usage limits" + + -- Marcelo Henrique Cerri Mon, 10 Sep 2018 10:32:26 -0300 + +linux-oracle (4.15.0-1002.2) bionic; urgency=medium + + * Miscellaneous Ubuntu changes + - [Packaging] linux-oracle: Only build the tools package for amd64 + - [Packaging] linux-oracle: Add ckt/oracle PPA to getabis + + -- Marcelo Henrique Cerri Mon, 13 Aug 2018 09:06:17 -0300 + +linux-oracle (4.15.0-1001.1) bionic; urgency=medium + + * Miscellaneous Ubuntu changes + - linux-oracle packaging + - [Config] linux-oracle: Update configs for the net_failover driver + + * Miscellaneous upstream changes + - virtio_net: propagate linkspeed/duplex settings from the hypervisor + - virtio_net: Introduce VIRTIO_NET_F_STANDBY feature bit + - net: unpollute priv_flags space + - net: introduce IFF_NO_RX_HANDLER + - page_pool: refurbish version of page_pool code + - net: Introduce generic failover module + - net: Introduce net_failover driver + - virtio_net: Extend virtio to use VF datapath when available + - net_failover: Use netdev_features_t instead of u32 + - net: net_failover: fix typo in net_failover_slave_register() + + -- Marcelo Henrique Cerri Thu, 09 Aug 2018 09:55:51 -0300 + +linux-oracle (4.15.0-1000.0) bionic; urgency=low + + [ Marcelo Henrique Cerri ] + + * empty entry + + -- Marcelo Henrique Cerri Mon, 06 Aug 2018 09:50:39 -0300 + +linux (4.15.0-29.31) bionic; urgency=medium + + * linux: 4.15.0-29.31 -proposed tracker (LP: #1782173) + + * [SRU Bionic][Cosmic] kernel panic in ipmi_ssif at msg_done_handler + (LP: #1777716) + - ipmi_ssif: Fix kernel panic at msg_done_handler + + * Update to ocxl driver for 18.04.1 (LP: #1775786) + - misc: ocxl: use put_device() instead of device_unregister() + - powerpc: Add TIDR CPU feature for POWER9 + - powerpc: Use TIDR CPU feature to control TIDR allocation + - powerpc: use task_pid_nr() for TID allocation + - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action + - ocxl: Expose the thread_id needed for wait on POWER9 + - ocxl: Add an IOCTL so userspace knows what OCXL features are available + - ocxl: Document new OCXL IOCTLs + - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait() + + * Critical upstream bugfix missing in Ubuntu 18.04 - frequent Xorg crash after + suspend (LP: #1776887) + - ocxl: Document the OCXL_IOCTL_GET_METADATA IOCTL + + * Hard LOCKUP observed on stressing Ubuntu 18 04 (LP: #1777194) + - powerpc: use NMI IPI for smp_send_stop + - powerpc: Fix smp_send_stop NMI IPI handling + + * IPL: ppc64_cpu --frequency hang with INFO: rcu_sched detected stalls on + CPUs/tasks on w34 and wsbmc016 with 920.1714.20170330n (LP: #1773964) + - rtc: opal: Fix OPAL RTC driver OPAL_BUSY loops + + * [Regression] EXT4-fs error (device sda2): ext4_validate_block_bitmap:383: + comm stress-ng: bg 4705: bad block bitmap checksum (LP: #1781709) + - SAUCE: Revert "UBUNTU: SAUCE: ext4: fix ext4_validate_inode_bitmap: comm + stress-ng: Corrupt inode bitmap" + - SAUCE: ext4: check for allocation block validity with block group locked + + -- Stefan Bader Tue, 17 Jul 2018 10:57:50 +0200 + +linux (4.15.0-28.30) bionic; urgency=medium + + * linux: 4.15.0-28.30 -proposed tracker (LP: #1781433) + + * Cannot set MTU higher than 1500 in Xen instance (LP: #1781413) + - xen-netfront: Fix mismatched rtnl_unlock + - xen-netfront: Update features after registering netdev + + -- Kamal Mostafa Thu, 12 Jul 2018 09:47:07 -0700 + +linux (4.15.0-27.29) bionic; urgency=medium + + * linux: 4.15.0-27.29 -proposed tracker (LP: #1781062) + + * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99: + comm stress-ng: Corrupt inode bitmap (LP: #1780137) + - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode + bitmap + + -- Khalid Elmously Tue, 10 Jul 2018 19:05:00 -0400 + +linux (4.15.0-26.28) bionic; urgency=medium + + * linux: 4.15.0-26.28 -proposed tracker (LP: #1780112) + + * failure to boot with linux-image-4.15.0-24-generic (LP: #1779827) // Cloud- + init causes potentially huge boot delays with 4.15 kernels (LP: #1780062) + - random: Make getrandom() ready earlier + + -- Stefan Bader Wed, 04 Jul 2018 17:52:52 +0200 + +linux (4.15.0-25.27) bionic; urgency=medium + + * linux: 4.15.0-25.27 -proposed tracker (LP: #1779354) + + * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736) + - scsi: hisi_sas: Update a couple of register settings for v3 hw + + * hisi_sas: Add missing PHY spinlock init (LP: #1777734) + - scsi: hisi_sas: Add missing PHY spinlock init + + * hisi_sas: improve read performance by pre-allocating slot DMA buffers + (LP: #1777727) + - scsi: hisi_sas: use dma_zalloc_coherent() + - scsi: hisi_sas: Use dmam_alloc_coherent() + - scsi: hisi_sas: Pre-allocate slot DMA buffers + + * hisi_sas: Failures during host reset (LP: #1777696) + - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw() + - scsi: hisi_sas: Fix the conflict between dev gone and host reset + - scsi: hisi_sas: Adjust task reject period during host reset + - scsi: hisi_sas: Add a flag to filter PHY events during reset + - scsi: hisi_sas: Release all remaining resources in clear nexus ha + + * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique + (LP: #1776750) + - scsi: hisi_sas: make SAS address of SATA disks unique + + * Vcs-Git header on bionic linux source package points to zesty git tree + (LP: #1766055) + - [Packaging]: Update Vcs-Git + + * large KVM instances run out of IRQ routes (LP: #1778261) + - SAUCE: kvm -- increase KVM_MAX_IRQ_ROUTES to 2048 on x86 + + -- Khalid Elmously Sun, 01 Jul 2018 23:10:18 +0000 + +linux (4.15.0-24.26) bionic; urgency=medium + + * linux: 4.15.0-24.26 -proposed tracker (LP: #1776338) + + * Bionic update: upstream stable patchset 2018-06-06 (LP: #1775483) + - drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs + - i40e: Fix attach VF to VM issue + - tpm: cmd_ready command can be issued only after granting locality + - tpm: tpm-interface: fix tpm_transmit/_cmd kdoc + - tpm: add retry logic + - Revert "ath10k: send (re)assoc peer command when NSS changed" + - bonding: do not set slave_dev npinfo before slave_enable_netpoll in + bond_enslave + - ipv6: add RTA_TABLE and RTA_PREFSRC to rtm_ipv6_policy + - ipv6: sr: fix NULL pointer dereference in seg6_do_srh_encap()- v4 pkts + - KEYS: DNS: limit the length of option strings + - l2tp: check sockaddr length in pppol2tp_connect() + - net: validate attribute sizes in neigh_dump_table() + - llc: delete timers synchronously in llc_sk_free() + - tcp: don't read out-of-bounds opsize + - net: af_packet: fix race in PACKET_{R|T}X_RING + - tcp: md5: reject TCP_MD5SIG or TCP_MD5SIG_EXT on established sockets + - net: fix deadlock while clearing neighbor proxy table + - team: avoid adding twice the same option to the event list + - net/smc: fix shutdown in state SMC_LISTEN + - team: fix netconsole setup over team + - packet: fix bitfield update race + - tipc: add policy for TIPC_NLA_NET_ADDR + - pppoe: check sockaddr length in pppoe_connect() + - vlan: Fix reading memory beyond skb->tail in skb_vlan_tagged_multi + - amd-xgbe: Add pre/post auto-negotiation phy hooks + - sctp: do not check port in sctp_inet6_cmp_addr + - amd-xgbe: Improve KR auto-negotiation and training + - strparser: Do not call mod_delayed_work with a timeout of LONG_MAX + - amd-xgbe: Only use the SFP supported transceiver signals + - strparser: Fix incorrect strp->need_bytes value. + - net: sched: ife: signal not finding metaid + - tcp: clear tp->packets_out when purging write queue + - net: sched: ife: handle malformed tlv length + - net: sched: ife: check on metadata length + - llc: hold llc_sap before release_sock() + - llc: fix NULL pointer deref for SOCK_ZAPPED + - net: ethernet: ti: cpsw: fix tx vlan priority mapping + - virtio_net: split out ctrl buffer + - virtio_net: fix adding vids on big-endian + - KVM: s390: force bp isolation for VSIE + - s390: correct module section names for expoline code revert + - microblaze: Setup dependencies for ASM optimized lib functions + - commoncap: Handle memory allocation failure. + - scsi: mptsas: Disable WRITE SAME + - cdrom: information leak in cdrom_ioctl_media_changed() + - m68k/mac: Don't remap SWIM MMIO region + - block/swim: Check drive type + - block/swim: Don't log an error message for an invalid ioctl + - block/swim: Remove extra put_disk() call from error path + - block/swim: Rename macros to avoid inconsistent inverted logic + - block/swim: Select appropriate drive on device open + - block/swim: Fix array bounds check + - block/swim: Fix IO error at end of medium + - tracing: Fix missing tab for hwlat_detector print format + - s390/cio: update chpid descriptor after resource accessibility event + - s390/dasd: fix IO error for newly defined devices + - s390/uprobes: implement arch_uretprobe_is_alive() + - ACPI / video: Only default only_lcd to true on Win8-ready _desktops_ + - docs: ip-sysctl.txt: fix name of some ipv6 variables + - net: mvpp2: Fix DMA address mask size + - net: stmmac: Disable ACS Feature for GMAC >= 4 + - l2tp: hold reference on tunnels in netlink dumps + - l2tp: hold reference on tunnels printed in pppol2tp proc file + - l2tp: hold reference on tunnels printed in l2tp/tunnels debugfs file + - l2tp: fix {pppol2tp, l2tp_dfs}_seq_stop() in case of seq_file overflow + - s390/qeth: fix error handling in adapter command callbacks + - s390/qeth: avoid control IO completion stalls + - s390/qeth: handle failure on workqueue creation + - bnxt_en: Fix memory fault in bnxt_ethtool_init() + - virtio-net: add missing virtqueue kick when flushing packets + - VSOCK: make af_vsock.ko removable again + - hwmon: (k10temp) Add temperature offset for Ryzen 2700X + - hwmon: (k10temp) Add support for AMD Ryzen w/ Vega graphics + - s390/cpum_cf: rename IBM z13/z14 counter names + - kprobes: Fix random address output of blacklist file + - Revert "pinctrl: intel: Initialize GPIO properly when used through irqchip" + + * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636) + - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist + + * bluetooth controller fail after suspend with USB autosuspend on XPS 13 9360 + (LP: #1775217) + - Bluetooth: btusb: Add Dell XPS 13 9360 to btusb_needs_reset_resume_table + + * [Hyper-V] PCI: hv: Fix 2 hang issues in hv_compose_msi_msg (LP: #1758378) + - PCI: hv: Only queue new work items in hv_pci_devices_present() if necessary + - PCI: hv: Remove the bogus test in hv_eject_device_work() + - PCI: hv: Fix a comment typo in _hv_pcifront_read_config() + + * register on binfmt_misc may overflow and crash the system (LP: #1775856) + - fs/binfmt_misc.c: do not allow offset overflow + + * CVE-2018-11508 + - compat: fix 4-byte infoleak via uninitialized struct field + + * Network installs fail on SocioNext board (LP: #1775884) + - net: netsec: reduce DMA mask to 40 bits + - net: socionext: reset hardware in ndo_stop + - net: netsec: enable tx-irq during open callback + + * r8169 ethernet card don't work after returning from suspension + (LP: #1752772) + - PCI: Add pcim_set_mwi(), a device-managed pci_set_mwi() + - r8169: switch to device-managed functions in probe + - r8169: remove netif_napi_del in probe error path + - r8169: remove some WOL-related dead code + - r8169: disable WOL per default + - r8169: improve interrupt handling + - r8169: fix interrupt number after adding support for MSI-X interrupts + + * ISST-LTE:KVM:Ubuntu18.04:BostonLC:boslcp3:boslcp3g3:Guest conosle hangs + after hotplug CPU add operation. (LP: #1759723) + - genirq/affinity: assign vectors to all possible CPUs + - genirq/affinity: Don't return with empty affinity masks on error + - genirq/affinity: Rename *node_to_possible_cpumask as *node_to_cpumask + - genirq/affinity: Move actual irq vector spreading into a helper function + - genirq/affinity: Allow irq spreading from a given starting point + - genirq/affinity: Spread irq vectors among present CPUs as far as possible + - blk-mq: simplify queue mapping & schedule with each possisble CPU + - blk-mq: make sure hctx->next_cpu is set correctly + - blk-mq: Avoid that blk_mq_delay_run_hw_queue() introduces unintended delays + - blk-mq: make sure that correct hctx->next_cpu is set + - blk-mq: avoid to write intermediate result to hctx->next_cpu + - blk-mq: introduce blk_mq_hw_queue_first_cpu() to figure out first cpu + - blk-mq: don't check queue mapped in __blk_mq_delay_run_hw_queue() + - nvme: pci: pass max vectors as num_possible_cpus() to pci_alloc_irq_vectors + - scsi: hpsa: fix selection of reply queue + - scsi: megaraid_sas: fix selection of reply queue + - scsi: core: introduce force_blk_mq + - scsi: virtio_scsi: fix IO hang caused by automatic irq vector affinity + - scsi: virtio_scsi: unify scsi_host_template + + * Fix several bugs in RDMA/hns driver (LP: #1770974) + - RDMA/hns: Use structs to describe the uABI instead of opencoding + - RDMA/hns: Remove unnecessary platform_get_resource() error check + - RDMA/hns: Remove unnecessary operator + - RDMA/hns: Add names to function arguments in function pointers + - RDMA/hns: Fix misplaced call to hns_roce_cleanup_hem_table + - RDMA/hns: Fix a bug with modifying mac address + - RDMA/hns: Use free_pages function instead of free_page + - RDMA/hns: Replace __raw_write*(cpu_to_le*()) with LE write*() + - RDMA/hns: Bugfix for init hem table + - RDMA/hns: Intercept illegal RDMA operation when use inline data + - RDMA/hns: Fix the qp context state diagram + - RDMA/hns: Only assign mtu if IB_QP_PATH_MTU bit is set + - RDMA/hns: Remove some unnecessary attr_mask judgement + - RDMA/hns: Only assign dqpn if IB_QP_PATH_DEST_QPN bit is set + - RDMA/hns: Adjust the order of cleanup hem table + - RDMA/hns: Update assignment method for owner field of send wqe + - RDMA/hns: Submit bad wr + - RDMA/hns: Fix a couple misspellings + - RDMA/hns: Add rq inline flags judgement + - RDMA/hns: Bugfix for rq record db for kernel + - RDMA/hns: Load the RoCE dirver automatically + - RDMA/hns: Update convert function of endian format + - RDMA/hns: Add return operation when configured global param fail + - RDMA/hns: Not support qp transition from reset to reset for hip06 + - RDMA/hns: Fix the bug with rq sge + - RDMA/hns: Set desc_dma_addr for zero when free cmq desc + - RDMA/hns: Enable inner_pa_vld filed of mpt + - RDMA/hns: Set NULL for __internal_mr + - RDMA/hns: Fix the bug with NULL pointer + - RDMA/hns: Bugfix for cq record db for kernel + - RDMA/hns: Move the location for initializing tmp_len + - RDMA/hns: Drop local zgid in favor of core defined variable + - RDMA/hns: Add 64KB page size support for hip08 + - RDMA/hns: Rename the idx field of db + - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust + - RDMA/hns: Increase checking CMQ status timeout value + - RDMA/hns: Add reset process for RoCE in hip08 + - RDMA/hns: Fix the illegal memory operation when cross page + - RDMA/hns: Implement the disassociate_ucontext API + + * powerpc/livepatch: Implement reliable stack tracing for the consistency + model (LP: #1771844) + - powerpc/livepatch: Implement reliable stack tracing for the consistency + model + + * vmxnet3: update to latest ToT (LP: #1768143) + - vmxnet3: avoid xmit reset due to a race in vmxnet3 + - vmxnet3: use correct flag to indicate LRO feature + - vmxnet3: fix incorrect dereference when rxvlan is disabled + + * 4.15.0-22-generic fails to boot on IBM S822LC (POWER8 (raw), altivec + supported) (LP: #1773162) + - Revert "powerpc/64s: Add support for a store forwarding barrier at kernel + entry/exit" + - powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit + + * Decode ARM CPER records in kernel (LP: #1770244) + - [Config] CONFIG_UEFI_CPER_ARM=y + - efi: Move ARM CPER code to new file + - efi: Parse ARM error information value + + * Adding back alx WoL feature (LP: #1772610) + - SAUCE: Revert "alx: remove WoL support" + - SAUCE: alx: add enable_wol paramenter + + * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103) + - scsi: lpfc: Fix WQ/CQ creation for older asic's. + - scsi: lpfc: Fix 16gb hbas failing cq create. + + * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5 + idle states when all CORES are guarded (LP: #1771780) + - SAUCE: cpuidle/powernv : init all present cpus for deep states + + * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970) + - net-next/hinic: add pci device ids for 25ge and 100ge card + + * [Ubuntu 18.04.1] POWER9 - Nvidia Volta - Kernel changes to enable Nvidia + driver on bare metal (LP: #1772991) + - powerpc/powernv/npu: Fix deadlock in mmio_invalidate() + - powerpc/powernv/mce: Don't silently restart the machine + - powerpc/npu-dma.c: Fix crash after __mmu_notifier_register failure + - powerpc/mm: Flush cache on memory hot(un)plug + - powerpc/powernv/memtrace: Let the arch hotunplug code flush cache + - powerpc/powernv/npu: Add lock to prevent race in concurrent context + init/destroy + - powerpc/powernv/npu: Prevent overwriting of pnv_npu2_init_contex() callback + parameters + - powerpc/powernv/npu: Do a PID GPU TLB flush when invalidating a large + address range + - powerpc/mce: Fix a bug where mce loops on memory UE. + + * cpum_sf: ensure sample freq is non-zero (LP: #1772593) + - s390/cpum_sf: ensure sample frequency of perf event attributes is non-zero + + * PCIe link speeds of 16 GT/s are shown as "Unknown speed" (LP: #1773243) + - PCI: Add decoding for 16 GT/s link speed + + * False positive ACPI _PRS error messages (LP: #1773295) + - ACPI / PCI: pci_link: Allow the absence of _PRS and change log level + + * Dell systems crash when disabling Nvidia dGPU (LP: #1773299) + - ACPI / OSI: Add OEM _OSI strings to disable NVidia RTD3 + + * wlp3s0: failed to remove key (1, ff:ff:ff:ff:ff:ff) from hardware (-22) + (LP: #1720930) + - iwlwifi: mvm: fix "failed to remove key" message + + * Expose arm64 CPU topology to userspace (LP: #1770231) + - ACPICA: ACPI 6.2: Additional PPTT flags + - drivers: base: cacheinfo: move cache_setup_of_node() + - drivers: base: cacheinfo: setup DT cache properties early + - cacheinfo: rename of_node to fw_token + - arm64/acpi: Create arch specific cpu to acpi id helper + - ACPI/PPTT: Add Processor Properties Topology Table parsing + - [Config] CONFIG_ACPI_PPTT=y + - ACPI: Enable PPTT support on ARM64 + - drivers: base cacheinfo: Add support for ACPI based firmware tables + - arm64: Add support for ACPI based firmware tables + - arm64: topology: rename cluster_id + - arm64: topology: enable ACPI/PPTT based CPU topology + - ACPI: Add PPTT to injectable table list + - arm64: topology: divorce MC scheduling domain from core_siblings + + * hisi_sas robustness fixes (LP: #1774466) + - scsi: hisi_sas: delete timer when removing hisi_sas driver + - scsi: hisi_sas: print device id for errors + - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice + - scsi: hisi_sas: check host frozen before calling "done" function + - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task() + - scsi: hisi_sas: stop controller timer for reset + - scsi: hisi_sas: update PHY linkrate after a controller reset + - scsi: hisi_sas: change slot index allocation mode + - scsi: hisi_sas: Change common allocation mode of device id + - scsi: hisi_sas: Reset disks when discovered + - scsi: hisi_sas: Create a scsi_host_template per HW module + - scsi: hisi_sas: Init disks after controller reset + - scsi: hisi_sas: Try wait commands before before controller reset + - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot + - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command + - scsi: hisi_sas: Terminate STP reject quickly for v2 hw + - scsi: hisi_sas: Fix return value when get_free_slot() failed + - scsi: hisi_sas: Mark PHY as in reset for nexus reset + + * hisi_sas: Support newer v3 hardware (LP: #1774467) + - scsi: hisi_sas: update RAS feature for later revision of v3 HW + - scsi: hisi_sas: check IPTT is valid before using it for v3 hw + - scsi: hisi_sas: fix PI memory size + - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw + - scsi: hisi_sas: remove redundant handling to event95 for v3 + - scsi: hisi_sas: add readl poll timeout helper wrappers + - scsi: hisi_sas: workaround a v3 hw hilink bug + - scsi: hisi_sas: Add LED feature for v3 hw + + * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472) + - scsi: hisi_sas: initialize dq spinlock before use + - scsi: hisi_sas: optimise the usage of DQ locking + - scsi: hisi_sas: relocate smp sg map + - scsi: hisi_sas: make return type of prep functions void + - scsi: hisi_sas: allocate slot buffer earlier + - scsi: hisi_sas: Don't lock DQ for complete task sending + - scsi: hisi_sas: Use device lock to protect slot alloc/free + - scsi: hisi_sas: add check of device in hisi_sas_task_exec() + - scsi: hisi_sas: fix a typo in hisi_sas_task_prep() + + * Request to revert SAUCE patches in the 18.04 SRU and update with upstream + version (LP: #1768431) + - scsi: cxlflash: Handle spurious interrupts + - scsi: cxlflash: Remove commmands from pending list on timeout + - scsi: cxlflash: Synchronize reset and remove ops + - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3 + + * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520) + - SAUCE: Revert "drm/i915/edp: Allow alternate fixed mode for eDP if + available." + + * ELANPAD ELAN0612 does not work, patch available (LP: #1773509) + - SAUCE: Input: elan_i2c - add ELAN0612 to the ACPI table + + * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336) + - SAUCE: CacheFiles: fix a read_waiter/read_copier race + + * hns3 driver updates (LP: #1768670) + - net: hns3: VF should get the real rss_size instead of rss_size_max + - net: hns3: set the cmdq out_vld bit to 0 after used + - net: hns3: fix endian issue when PF get mbx message flag + - net: hns3: fix the queue id for tqp enable&&reset + - net: hns3: set the max ring num when alloc netdev + - net: hns3: add support for VF driver inner interface + hclgevf_ops.get_tqps_and_rss_info + - net: hns3: refactor the hclge_get/set_rss function + - net: hns3: refactor the hclge_get/set_rss_tuple function + - net: hns3: fix for RSS configuration loss problem during reset + - net: hns3: fix for pause configuration lost during reset + - net: hns3: fix for use-after-free when setting ring parameter + - net: hns3: refactor the get/put_vector function + - net: hns3: fix for coalesce configuration lost during reset + - net: hns3: refactor the coalesce related struct + - net: hns3: fix for coal configuation lost when setting the channel + - net: hns3: add existence check when remove old uc mac address + - net: hns3: fix for netdev not running problem after calling net_stop and + net_open + - net: hns3: fix for ipv6 address loss problem after setting channels + - net: hns3: unify the pause params setup function + - net: hns3: fix rx path skb->truesize reporting bug + - net: hns3: add support for querying pfc puase packets statistic + - net: hns3: fix for loopback failure when vlan filter is enable + - net: hns3: fix for buffer overflow smatch warning + - net: hns3: fix error type definition of return value + - net: hns3: fix return value error of hclge_get_mac_vlan_cmd_status() + - net: hns3: add existence checking before adding unicast mac address + - net: hns3: add result checking for VF when modify unicast mac address + - net: hns3: reallocate tx/rx buffer after changing mtu + - net: hns3: fix the VF queue reset flow error + - net: hns3: fix for vlan table lost problem when resetting + - net: hns3: increase the max time for IMP handle command + - net: hns3: change GL update rate + - net: hns3: change the time interval of int_gl calculating + - net: hns3: fix for getting wrong link mode problem + - net: hns3: add get_link support to VF + - net: hns3: add querying speed and duplex support to VF + - net: hns3: fix for not returning problem in get_link_ksettings when phy + exists + - net: hns3: Changes to make enet watchdog timeout func common for PF/VF + - net: hns3: Add VF Reset Service Task to support event handling + - net: hns3: Add VF Reset device state and its handling + - net: hns3: Add support to request VF Reset to PF + - net: hns3: Add support to reset the enet/ring mgmt layer + - net: hns3: Add support to re-initialize the hclge device + - net: hns3: Changes to support ARQ(Asynchronous Receive Queue) + - net: hns3: Add *Asserting Reset* mailbox message & handling in VF + - net: hns3: Changes required in PF mailbox to support VF reset + - net: hns3: hclge_inform_reset_assert_to_vf() can be static + - net: hns3: fix for returning wrong value problem in hns3_get_rss_key_size + - net: hns3: fix for returning wrong value problem in hns3_get_rss_indir_size + - net: hns3: fix for the wrong shift problem in hns3_set_txbd_baseinfo + - net: hns3: fix for not initializing VF rss_hash_key problem + - net: hns3: never send command queue message to IMP when reset + - net: hns3: remove unnecessary pci_set_drvdata() and devm_kfree() + - net: hns3: fix length overflow when CONFIG_ARM64_64K_PAGES + - net: hns3: Remove error log when getting pfc stats fails + - net: hns3: fix to correctly fetch l4 protocol outer header + - net: hns3: Fixes the out of bounds access in hclge_map_tqp + - net: hns3: Fixes the error legs in hclge_init_ae_dev function + - net: hns3: fix for phy_addr error in hclge_mac_mdio_config + - net: hns3: Fix to support autoneg only for port attached with phy + - net: hns3: fix a dead loop in hclge_cmd_csq_clean + - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls + - net: hns3: Remove packet statistics in the range of 8192~12287 + - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver + - net: hns3: Fix for setting mac address when resetting + - net: hns3: remove add/del_tunnel_udp in hns3_enet module + - net: hns3: fix for cleaning ring problem + - net: hns3: refactor the loopback related function + - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo + - net: hns3: Fix for the null pointer problem occurring when initializing + ae_dev failed + - net: hns3: Add a check for client instance init state + - net: hns3: Change return type of hnae3_register_ae_dev + - net: hns3: Change return type of hnae3_register_ae_algo + - net: hns3: Change return value in hnae3_register_client + - net: hns3: Fixes the back pressure setting when sriov is enabled + - net: hns3: Fix for fiber link up problem + - net: hns3: Add support of .sriov_configure in HNS3 driver + - net: hns3: Fixes the missing PCI iounmap for various legs + - net: hns3: Fixes error reported by Kbuild and internal review + - net: hns3: Fixes API to fetch ethernet header length with kernel default + - net: hns3: cleanup of return values in hclge_init_client_instance() + - net: hns3: Fix the missing client list node initialization + - net: hns3: Fix for hns3 module is loaded multiple times problem + - net: hns3: Use enums instead of magic number in hclge_is_special_opcode + - net: hns3: Fix for netdev not running problem after calling net_stop and + net_open + - net: hns3: Fixes kernel panic issue during rmmod hns3 driver + - net: hns3: Fix for CMDQ and Misc. interrupt init order problem + - net: hns3: Updates RX packet info fetch in case of multi BD + - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config + - net: hns3: Add STRP_TAGP field support for hardware revision 0x21 + - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21) + - net: hns3: Fix for PF mailbox receving unknown message + - net: hns3: Fixes the state to indicate client-type initialization + - net: hns3: Fixes the init of the VALID BD info in the descriptor + - net: hns3: Removes unnecessary check when clearing TX/RX rings + - net: hns3: Clear TX/RX rings when stopping port & un-initializing client + - net: hns3: Remove unused led control code + - net: hns3: Adds support for led locate command for copper port + - net: hns3: Fixes initalization of RoCE handle and makes it conditional + - net: hns3: Disable vf vlan filter when vf vlan table is full + - net: hns3: Add support for IFF_ALLMULTI flag + - net: hns3: Add repeat address checking for setting mac address + - net: hns3: Fix setting mac address error + - net: hns3: Fix for service_task not running problem after resetting + - net: hns3: Fix for hclge_reset running repeatly problem + - net: hns3: Fix for phy not link up problem after resetting + - net: hns3: Add missing break in misc_irq_handle + - net: hns3: Fix for vxlan tx checksum bug + - net: hns3: Optimize the PF's process of updating multicast MAC + - net: hns3: Optimize the VF's process of updating multicast MAC + - SAUCE: {topost} net: hns3: add support for serdes loopback selftest + - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except + VLD bit and buffer size + - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from + hclge_bind_ring_with_vector + - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and + uninit_client_instance + - SAUCE: {topost} net: hns3: add vector status check before free vector + - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6 + - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c + - SAUCE: {topost} net: hns3: extraction an interface for state state + init|uninit + - SAUCE: {topost} net: hns3: print the ret value in error information + - SAUCE: {topost} net: hns3: remove the Redundant put_vector in + hns3_client_uninit + - SAUCE: {topost} net: hns3: add unlikely for error check + - SAUCE: {topost} net: hns3: remove back in struct hclge_hw + - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits + - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir + - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean + - SAUCE: {topost} net: hns3: using modulo for cyclic counters in + hclge_cmd_send + - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done + - SAUCE: {topost} net: hns3: remove some unused members of some structures + - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set + - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of + kzalloc/dma_map_single + - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_ + - SAUCE: {topost} net: hns3: fix unused function warning in VF driver + - SAUCE: {topost} net: hns3: remove some redundant assignments + - SAUCE: {topost} net: hns3: standardize the handle of return value + - SAUCE: {topost} net: hns3: remove extra space and brackets + - SAUCE: {topost} net: hns3: fix unreasonable code comments + - SAUCE: {topost} net: hns3: use decimal for bit offset macros + - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros + - SAUCE: {topost} net: hns3: fix mislead parameter name + - SAUCE: {topost} net: hns3: remove unused struct member and definition + - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver + - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE + - SAUCE: {topost} net: hns3: optimize the process of notifying roce client + - SAUCE: {topost} net: hns3: Add calling roce callback function when link + status change + - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up + - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode + - SAUCE: {topost} net: hns3: fix for waterline not setting correctly + - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug + - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem + - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size + - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest + - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module + - SAUCE: {topost} net: hns3: remove the warning when clear reset cause + - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback + function + - SAUCE: {topost} net: hns3: prevent sending command during global or core + reset + - SAUCE: {topost} net: hns3: modify the order of initializeing command queue + register + - SAUCE: {topost} net: hns3: reset net device with rtnl_lock + - SAUCE: {topost} net: hns3: prevent to request reset frequently + - SAUCE: {topost} net: hns3: correct reset event status register + - SAUCE: {topost} net: hns3: separate roce from nic when resetting + - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver + - SAUCE: {topost} net: hns3: fix return value error in + hns3_reset_notify_down_enet + - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation + while resetting + - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm + - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in + hclge_get_ring_chain_from_mbx + - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx + - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response + - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message + - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process + + * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306) + - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs + + * Bionic update: upstream stable patchset 2018-05-29 (LP: #1774063) + - cifs: do not allow creating sockets except with SMB1 posix exensions + - btrfs: fix unaligned access in readdir + - x86/acpi: Prevent X2APIC id 0xffffffff from being accounted + - clocksource/imx-tpm: Correct -ETIME return condition check + - x86/tsc: Prevent 32bit truncation in calc_hpet_ref() + - drm/vc4: Fix memory leak during BO teardown + - drm/i915/gvt: throw error on unhandled vfio ioctls + - drm/i915/audio: Fix audio detection issue on GLK + - drm/i915: Do no use kfree() to free a kmem_cache_alloc() return value + - drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state + - drm/i915/bxt, glk: Increase PCODE timeouts during CDCLK freq changing + - usb: musb: fix enumeration after resume + - usb: musb: call pm_runtime_{get,put}_sync before reading vbus registers + - usb: musb: Fix external abort in musb_remove on omap2430 + - firewire-ohci: work around oversized DMA reads on JMicron controllers + - x86/tsc: Allow TSC calibration without PIT + - NFSv4: always set NFS_LOCK_LOST when a lock is lost. + - ACPI / LPSS: Do not instiate platform_dev for devs without MMIO resources + - ALSA: hda - Use IS_REACHABLE() for dependency on input + - ASoC: au1x: Fix timeout tests in au1xac97c_ac97_read() + - kvm: x86: fix KVM_XEN_HVM_CONFIG ioctl + - RDMA/core: Clarify rdma_ah_find_type + - KVM: PPC: Book3S HV: Enable migration of decrementer register + - netfilter: ipv6: nf_defrag: Pass on packets to stack per RFC2460 + - tracing/hrtimer: Fix tracing bugs by taking all clock bases and modes into + account + - KVM: s390: use created_vcpus in more places + - platform/x86: dell-laptop: Filter out spurious keyboard backlight change + events + - xprtrdma: Fix backchannel allocation of extra rpcrdma_reps + - selftest: ftrace: Fix to pick text symbols for kprobes + - PCI: Add function 1 DMA alias quirk for Marvell 9128 + - Input: psmouse - fix Synaptics detection when protocol is disabled + - libbpf: Makefile set specified permission mode + - Input: synaptics - reset the ABS_X/Y fuzz after initializing MT axes + - i40iw: Free IEQ resources + - i40iw: Zero-out consumer key on allocate stag for FMR + - perf unwind: Do not look just at the global callchain_param.record_mode + - tools lib traceevent: Simplify pointer print logic and fix %pF + - perf callchain: Fix attr.sample_max_stack setting + - tools lib traceevent: Fix get_field_str() for dynamic strings + - perf record: Fix failed memory allocation for get_cpuid_str + - iommu/exynos: Don't unconditionally steal bus ops + - powerpc: System reset avoid interleaving oops using die synchronisation + - iommu/vt-d: Use domain instead of cache fetching + - dm thin: fix documentation relative to low water mark threshold + - dm mpath: return DM_MAPIO_REQUEUE on blk-mq rq allocation failure + - ubifs: Fix uninitialized variable in search_dh_cookie() + - net: stmmac: dwmac-meson8b: fix setting the RGMII TX clock on Meson8b + - net: stmmac: dwmac-meson8b: propagate rate changes to the parent clock + - spi: a3700: Clear DATA_OUT when performing a read + - IB/cq: Don't force IB_POLL_DIRECT poll context for ib_process_cq_direct + - nfs: Do not convert nfs_idmap_cache_timeout to jiffies + - MIPS: Fix clean of vmlinuz.{32,ecoff,bin,srec} + - PCI: Add dummy pci_irqd_intx_xlate() for CONFIG_PCI=n build + - watchdog: sp5100_tco: Fix watchdog disable bit + - kconfig: Don't leak main menus during parsing + - kconfig: Fix automatic menu creation mem leak + - kconfig: Fix expr_free() E_NOT leak + - ipmi/powernv: Fix error return code in ipmi_powernv_probe() + - Btrfs: set plug for fsync + - btrfs: Fix out of bounds access in btrfs_search_slot + - Btrfs: fix scrub to repair raid6 corruption + - btrfs: fail mount when sb flag is not in BTRFS_SUPER_FLAG_SUPP + - Btrfs: fix unexpected EEXIST from btrfs_get_extent + - Btrfs: raid56: fix race between merge_bio and rbio_orig_end_io + - RDMA/cma: Check existence of netdevice during port validation + - f2fs: avoid hungtask when GC encrypted block if io_bits is set + - scsi: devinfo: fix format of the device list + - scsi: fas216: fix sense buffer initialization + - Input: stmfts - set IRQ_NOAUTOEN to the irq flag + - HID: roccat: prevent an out of bounds read in kovaplus_profile_activated() + - nfp: fix error return code in nfp_pci_probe() + - block: Set BIO_TRACE_COMPLETION on new bio during split + - bpf: test_maps: cleanup sockmaps when test ends + - i40evf: Don't schedule reset_task when device is being removed + - i40evf: ignore link up if not running + - platform/x86: thinkpad_acpi: suppress warning about palm detection + - KVM: s390: vsie: use READ_ONCE to access some SCB fields + - blk-mq-debugfs: don't allow write on attributes with seq_operations set + - ASoC: rockchip: Use dummy_dai for rt5514 dsp dailink + - igb: Allow to remove administratively set MAC on VFs + - igb: Clear TXSTMP when ptp_tx_work() is timeout + - fm10k: fix "failed to kill vid" message for VF + - x86/hyperv: Stop suppressing X86_FEATURE_PCID + - tty: serial: exar: Relocate sleep wake-up handling + - device property: Define type of PROPERTY_ENRTY_*() macros + - crypto: artpec6 - remove select on non-existing CRYPTO_SHA384 + - RDMA/uverbs: Use an unambiguous errno for method not supported + - jffs2: Fix use-after-free bug in jffs2_iget()'s error handling path + - ixgbe: don't set RXDCTL.RLPML for 82599 + - i40e: program fragmented IPv4 filter input set + - i40e: fix reported mask for ntuple filters + - samples/bpf: Partially fixes the bpf.o build + - powerpc/numa: Use ibm,max-associativity-domains to discover possible nodes + - powerpc/numa: Ensure nodes initialized for hotplug + - RDMA/mlx5: Avoid memory leak in case of XRCD dealloc failure + - ntb_transport: Fix bug with max_mw_size parameter + - gianfar: prevent integer wrapping in the rx handler + - x86/hyperv: Check for required priviliges in hyperv_init() + - netfilter: x_tables: fix pointer leaks to userspace + - tcp_nv: fix potential integer overflow in tcpnv_acked + - kvm: Map PFN-type memory regions as writable (if possible) + - x86/kvm/vmx: do not use vm-exit instruction length for fast MMIO when + running nested + - fs/dax.c: release PMD lock even when there is no PMD support in DAX + - ocfs2: return -EROFS to mount.ocfs2 if inode block is invalid + - ocfs2/acl: use 'ip_xattr_sem' to protect getting extended attribute + - ocfs2: return error when we attempt to access a dirty bh in jbd2 + - mm/mempolicy: fix the check of nodemask from user + - mm/mempolicy: add nodes_empty check in SYSC_migrate_pages + - asm-generic: provide generic_pmdp_establish() + - sparc64: update pmdp_invalidate() to return old pmd value + - mm: thp: use down_read_trylock() in khugepaged to avoid long block + - mm: pin address_space before dereferencing it while isolating an LRU page + - mm/fadvise: discard partial page if endbyte is also EOF + - openvswitch: Remove padding from packet before L3+ conntrack processing + - blk-mq: fix discard merge with scheduler attached + - IB/hfi1: Re-order IRQ cleanup to address driver cleanup race + - IB/hfi1: Fix for potential refcount leak in hfi1_open_file() + - IB/ipoib: Fix for potential no-carrier state + - IB/core: Map iWarp AH type to undefined in rdma_ah_find_type + - drm/nouveau/pmu/fuc: don't use movw directly anymore + - s390/eadm: fix CONFIG_BLOCK include dependency + - netfilter: ipv6: nf_defrag: Kill frag queue on RFC2460 failure + - x86/power: Fix swsusp_arch_resume prototype + - x86/dumpstack: Avoid uninitlized variable + - firmware: dmi_scan: Fix handling of empty DMI strings + - ACPI: processor_perflib: Do not send _PPC change notification if not ready + - ACPI / bus: Do not call _STA on battery devices with unmet dependencies + - ACPI / scan: Use acpi_bus_get_status() to initialize ACPI_TYPE_DEVICE devs + - MIPS: TXx9: use IS_BUILTIN() for CONFIG_LEDS_CLASS + - perf record: Fix period option handling + - MIPS: Generic: Support GIC in EIC mode + - perf evsel: Fix period/freq terms setup + - xen-netfront: Fix race between device setup and open + - xen/grant-table: Use put_page instead of free_page + - bpf: sockmap, fix leaking maps with attached but not detached progs + - RDS: IB: Fix null pointer issue + - arm64: spinlock: Fix theoretical trylock() A-B-A with LSE atomics + - proc: fix /proc/*/map_files lookup + - PM / domains: Fix up domain-idle-states OF parsing + - cifs: silence compiler warnings showing up with gcc-8.0.0 + - bcache: properly set task state in bch_writeback_thread() + - bcache: fix for allocator and register thread race + - bcache: fix for data collapse after re-attaching an attached device + - bcache: return attach error when no cache set exist + - cpufreq: intel_pstate: Enable HWP during system resume on CPU0 + - selftests/ftrace: Add some missing glob checks + - rxrpc: Don't put crypto buffers on the stack + - svcrdma: Fix Read chunk round-up + - net: Extra '_get' in declaration of arch_get_platform_mac_address + - tools/libbpf: handle issues with bpf ELF objects containing .eh_frames + - SUNRPC: Don't call __UDPX_INC_STATS() from a preemptible context + - net: stmmac: discard disabled flags in interrupt status register + - bpf: fix rlimit in reuseport net selftest + - ACPI / EC: Restore polling during noirq suspend/resume phases + - PM / wakeirq: Fix unbalanced IRQ enable for wakeirq + - vfs/proc/kcore, x86/mm/kcore: Fix SMAP fault when dumping vsyscall user page + - powerpc/mm/hash64: Zero PGD pages on allocation + - x86/platform/UV: Fix GAM Range Table entries less than 1GB + - locking/qspinlock: Ensure node->count is updated before initialising node + - powerpc/powernv: IMC fix out of bounds memory access at shutdown + - perf test: Fix test trace+probe_libc_inet_pton.sh for s390x + - irqchip/gic-v3: Ignore disabled ITS nodes + - cpumask: Make for_each_cpu_wrap() available on UP as well + - irqchip/gic-v3: Change pr_debug message to pr_devel + - RDMA/core: Reduce poll batch for direct cq polling + - alarmtimer: Init nanosleep alarm timer on stack + - netfilter: x_tables: cap allocations at 512 mbyte + - netfilter: x_tables: add counters allocation wrapper + - netfilter: compat: prepare xt_compat_init_offsets to return errors + - netfilter: compat: reject huge allocation requests + - netfilter: x_tables: limit allocation requests for blob rule heads + - perf: Fix sample_max_stack maximum check + - perf: Return proper values for user stack errors + - RDMA/mlx5: Fix NULL dereference while accessing XRC_TGT QPs + - Revert "KVM: X86: Fix SMRAM accessing even if VM is shutdown" + - mac80211_hwsim: fix use-after-free bug in hwsim_exit_net + - btrfs: Fix race condition between delayed refs and blockgroup removal + - mm,vmscan: Allow preallocating memory for register_shrinker(). + + * Bionic update: upstream stable patchset 2018-05-24 (LP: #1773233) + - tty: make n_tty_read() always abort if hangup is in progress + - cpufreq: CPPC: Use transition_delay_us depending transition_latency + - ubifs: Check ubifs_wbuf_sync() return code + - ubi: fastmap: Don't flush fastmap work on detach + - ubi: Fix error for write access + - ubi: Reject MLC NAND + - mm/ksm.c: fix inconsistent accounting of zero pages + - mm/hmm: hmm_pfns_bad() was accessing wrong struct + - task_struct: only use anon struct under randstruct plugin + - fs/reiserfs/journal.c: add missing resierfs_warning() arg + - resource: fix integer overflow at reallocation + - ipc/shm: fix use-after-free of shm file via remap_file_pages() + - mm, slab: reschedule cache_reap() on the same CPU + - usb: musb: gadget: misplaced out of bounds check + - phy: allwinner: sun4i-usb: poll vbus changes on A23/A33 when driving VBUS + - usb: gadget: udc: core: update usb_ep_queue() documentation + - ARM64: dts: meson: reduce odroid-c2 eMMC maximum rate + - KVM: arm/arm64: vgic-its: Fix potential overrun in vgic_copy_lpi_list + - ARM: EXYNOS: Fix coupled CPU idle freeze on Exynos4210 + - arm: dts: mt7623: fix USB initialization fails on bananapi-r2 + - ARM: dts: at91: at91sam9g25: fix mux-mask pinctrl property + - ARM: dts: exynos: Fix IOMMU support for GScaler devices on Exynos5250 + - ARM: dts: at91: sama5d4: fix pinctrl compatible string + - spi: atmel: init FIFOs before spi enable + - spi: Fix scatterlist elements size in spi_map_buf + - spi: Fix unregistration of controller with fixed SPI bus number + - media: atomisp_fops.c: disable atomisp_compat_ioctl32 + - media: vivid: check if the cec_adapter is valid + - media: vsp1: Fix BRx conditional path in WPF + - x86/xen: Delay get_cpu_cap until stack canary is established + - regmap: Fix reversed bounds check in regmap_raw_write() + - ACPI / video: Add quirk to force acpi-video backlight on Samsung 670Z5E + - ACPI / hotplug / PCI: Check presence of slot itself in get_slot_status() + - USB: gadget: f_midi: fixing a possible double-free in f_midi + - USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw + - usb: dwc3: prevent setting PRTCAP to OTG from debugfs + - usb: dwc3: pci: Properly cleanup resource + - usb: dwc3: gadget: never call ->complete() from ->ep_queue() + - cifs: fix memory leak in SMB2_open() + - fix smb3-encryption breakage when CONFIG_DEBUG_SG=y + - smb3: Fix root directory when server returns inode number of zero + - HID: i2c-hid: fix size check and type usage + - i2c: i801: Save register SMBSLVCMD value only once + - i2c: i801: Restore configuration at shutdown + - CIFS: refactor crypto shash/sdesc allocation&free + - CIFS: add sha512 secmech + - CIFS: fix sha512 check in cifs_crypto_secmech_release + - powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits + - powerpc/64: Call H_REGISTER_PROC_TBL when running as a HPT guest on POWER9 + - powerpc/64: Fix smp_wmb barrier definition use use lwsync consistently + - powerpc/kprobes: Fix call trace due to incorrect preempt count + - powerpc/kexec_file: Fix error code when trying to load kdump kernel + - powerpc/powernv: define a standard delay for OPAL_BUSY type retry loops + - powerpc/powernv: Fix OPAL NVRAM driver OPAL_BUSY loops + - HID: Fix hid_report_len usage + - HID: core: Fix size as type u32 + - soc: mediatek: fix the mistaken pointer accessed when subdomains are added + - ASoC: ssm2602: Replace reg_default_raw with reg_default + - ASoC: topology: Fix kcontrol name string handling + - irqchip/gic: Take lock when updating irq type + - random: use a tighter cap in credit_entropy_bits_safe() + - extcon: intel-cht-wc: Set direction and drv flags for V5 boost GPIO + - block: use 32-bit blk_status_t on Alpha + - jbd2: if the journal is aborted then don't allow update of the log tail + - ext4: shutdown should not prevent get_write_access + - ext4: eliminate sleep from shutdown ioctl + - ext4: pass -ESHUTDOWN code to jbd2 layer + - ext4: don't update checksum of new initialized bitmaps + - ext4: protect i_disksize update by i_data_sem in direct write path + - ext4: limit xattr size to INT_MAX + - ext4: always initialize the crc32c checksum driver + - ext4: don't allow r/w mounts if metadata blocks overlap the superblock + - ext4: move call to ext4_error() into ext4_xattr_check_block() + - ext4: add bounds checking to ext4_xattr_find_entry() + - ext4: add extra checks to ext4_xattr_block_get() + - dm crypt: limit the number of allocated pages + - RDMA/ucma: Don't allow setting RDMA_OPTION_IB_PATH without an RDMA device + - RDMA/mlx5: Protect from NULL pointer derefence + - RDMA/rxe: Fix an out-of-bounds read + - ALSA: pcm: Fix UAF at PCM release via PCM timer access + - IB/srp: Fix srp_abort() + - IB/srp: Fix completion vector assignment algorithm + - dmaengine: at_xdmac: fix rare residue corruption + - cxl: Fix possible deadlock when processing page faults from cxllib + - tpm: self test failure should not cause suspend to fail + - libnvdimm, dimm: fix dpa reservation vs uninitialized label area + - libnvdimm, namespace: use a safe lookup for dimm device name + - nfit, address-range-scrub: fix scrub in-progress reporting + - nfit: skip region registration for incomplete control regions + - ring-buffer: Check if memory is available before allocation + - um: Compile with modern headers + - um: Use POSIX ucontext_t instead of struct ucontext + - iommu/vt-d: Fix a potential memory leak + - mmc: jz4740: Fix race condition in IRQ mask update + - mmc: tmio: Fix error handling when issuing CMD23 + - PCI: Mark Broadcom HT1100 and HT2000 Root Port Extended Tags as broken + - clk: mvebu: armada-38x: add support for missing clocks + - clk: fix false-positive Wmaybe-uninitialized warning + - clk: mediatek: fix PWM clock source by adding a fixed-factor clock + - clk: bcm2835: De-assert/assert PLL reset signal when appropriate + - pwm: rcar: Fix a condition to prevent mismatch value setting to duty + - thermal: imx: Fix race condition in imx_thermal_probe() + - dt-bindings: clock: mediatek: add binding for fixed-factor clock axisel_d4 + - watchdog: f71808e_wdt: Fix WD_EN register read + - ALSA: pcm: Use ERESTARTSYS instead of EINTR in OSS emulation + - ALSA: pcm: Avoid potential races between OSS ioctls and read/write + - ALSA: pcm: Return -EBUSY for OSS ioctls changing busy streams + - ALSA: pcm: Fix mutex unbalance in OSS emulation ioctls + - ALSA: pcm: Fix endless loop for XRUN recovery in OSS emulation + - drm/amdgpu: Add an ATPX quirk for hybrid laptop + - drm/amdgpu: Fix always_valid bos multiple LRU insertions. + - drm/amdgpu/sdma: fix mask in emit_pipeline_sync + - drm/amdgpu: Fix PCIe lane width calculation + - drm/amdgpu/si: implement get/set pcie_lanes asic callback + - drm/rockchip: Clear all interrupts before requesting the IRQ + - drm/radeon: add PX quirk for Asus K73TK + - drm/radeon: Fix PCIe lane width calculation + - ALSA: line6: Use correct endpoint type for midi output + - ALSA: rawmidi: Fix missing input substream checks in compat ioctls + - ALSA: hda - New VIA controller suppor no-snoop path + - random: fix crng_ready() test + - random: use a different mixing algorithm for add_device_randomness() + - random: crng_reseed() should lock the crng instance that it is modifying + - random: add new ioctl RNDRESEEDCRNG + - HID: input: fix battery level reporting on BT mice + - HID: hidraw: Fix crash on HIDIOCGFEATURE with a destroyed device + - HID: wacom: bluetooth: send exit report for recent Bluetooth devices + - MIPS: uaccess: Add micromips clobbers to bzero invocation + - MIPS: memset.S: EVA & fault support for small_memset + - MIPS: memset.S: Fix return of __clear_user from Lpartial_fixup + - MIPS: memset.S: Fix clobber of v1 in last_fixup + - powerpc/eeh: Fix enabling bridge MMIO windows + - powerpc/lib: Fix off-by-one in alternate feature patching + - udf: Fix leak of UTF-16 surrogates into encoded strings + - fanotify: fix logic of events on child + - mmc: sdhci-pci: Only do AMD tuning for HS200 + - drm/i915: Correctly handle limited range YCbCr data on VLV/CHV + - jffs2_kill_sb(): deal with failed allocations + - hypfs_kill_super(): deal with failed allocations + - orangefs_kill_sb(): deal with allocation failures + - rpc_pipefs: fix double-dput() + - Don't leak MNT_INTERNAL away from internal mounts + - autofs: mount point create should honour passed in mode + - mm/filemap.c: fix NULL pointer in page_cache_tree_insert() + - Revert "media: lirc_zilog: driver only sends LIRCCODE" + - media: staging: lirc_zilog: incorrect reference counting + - writeback: safer lock nesting + - Bluetooth: hci_bcm: Add irq_polarity module option + - mm: hwpoison: disable memory error handling on 1GB hugepage + - media: rc: oops in ir_timer_keyup after device unplug + - acpi, nfit: rework NVDIMM leaf method detection + - ceph: always update atime/mtime/ctime for new inode + - ext4: fix offset overflow on 32-bit archs in ext4_iomap_begin() + - ext4: force revalidation of directory pointer after seekdir(2) + - RDMA/core: Avoid that ib_drain_qp() triggers an out-of-bounds stack access + - xprtrdma: Fix latency regression on NUMA NFS/RDMA clients + - xprtrdma: Fix corner cases when handling device removal + - IB/srpt: Fix an out-of-bounds stack access in srpt_zerolength_write() + - drivers/infiniband/core/verbs.c: fix build with gcc-4.4.4 + - drivers/infiniband/ulp/srpt/ib_srpt.c: fix build with gcc-4.4.4 + - mmc: core: Prevent bus reference leak in mmc_blk_init() + - drm/amd/display: HDMI has no sound after Panel power off/on + - trace_uprobe: Use %lx to display offset + - clk: tegra: Mark HCLK, SCLK and EMC as critical + - pwm: mediatek: Fix up PWM4 and PWM5 malfunction on MT7623 + - pwm: mediatek: Improve precision in rate calculation + - HID: i2c-hid: Fix resume issue on Raydium touchscreen device + - s390: add support for IBM z14 Model ZR1 + - drm/i915: Fix hibernation with ACPI S0 target state + - libnvdimm, dimm: handle EACCES failures from label reads + - device-dax: allow MAP_SYNC to succeed + - HID: i2c-hid: fix inverted return value from i2c_hid_command() + + * CVE-2018-7755 + - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl + + -- Kleber Sacilotto de Souza Tue, 12 Jun 2018 18:09:35 +0200 + +linux (4.15.0-23.25) bionic; urgency=medium + + * linux: 4.15.0-23.25 -proposed tracker (LP: #1772927) + + * arm64 SDEI support needs trampoline code for KPTI (LP: #1768630) + - arm64: mmu: add the entry trampolines start/end section markers into + sections.h + - arm64: sdei: Add trampoline code for remapping the kernel + + * Some PCIe errors not surfaced through rasdaemon (LP: #1769730) + - ACPI: APEI: handle PCIe AER errors in separate function + - ACPI: APEI: call into AER handling regardless of severity + + * qla2xxx: Fix page fault at kmem_cache_alloc_node() (LP: #1770003) + - scsi: qla2xxx: Fix session cleanup for N2N + - scsi: qla2xxx: Remove unused argument from qlt_schedule_sess_for_deletion() + - scsi: qla2xxx: Serialize session deletion by using work_lock + - scsi: qla2xxx: Serialize session free in qlt_free_session_done + - scsi: qla2xxx: Don't call dma_free_coherent with IRQ disabled. + - scsi: qla2xxx: Fix warning in qla2x00_async_iocb_timeout() + - scsi: qla2xxx: Prevent relogin trigger from sending too many commands + - scsi: qla2xxx: Fix double free bug after firmware timeout + - scsi: qla2xxx: Fixup locking for session deletion + + * Several hisi_sas bug fixes (LP: #1768974) + - scsi: hisi_sas: dt-bindings: add an property of signal attenuation + - scsi: hisi_sas: support the property of signal attenuation for v2 hw + - scsi: hisi_sas: fix the issue of link rate inconsistency + - scsi: hisi_sas: fix the issue of setting linkrate register + - scsi: hisi_sas: increase timer expire of internal abort task + - scsi: hisi_sas: remove unused variable hisi_sas_devices.running_req + - scsi: hisi_sas: fix return value of hisi_sas_task_prep() + - scsi: hisi_sas: Code cleanup and minor bug fixes + + * [bionic] machine stuck and bonding not working well when nvmet_rdma module + is loaded (LP: #1764982) + - nvmet-rdma: Don't flush system_wq by default during remove_one + - nvme-rdma: Don't flush delete_wq by default during remove_one + + * Warnings/hang during error handling of SATA disks on SAS controller + (LP: #1768971) + - scsi: libsas: defer ata device eh commands to libata + + * Hotplugging a SATA disk into a SAS controller may cause crash (LP: #1768948) + - ata: do not schedule hot plug if it is a sas host + + * ISST-LTE:pKVM:Ubuntu1804: rcu_sched self-detected stall on CPU follow by CPU + ATTEMPT TO RE-ENTER FIRMWARE! (LP: #1767927) + - powerpc/powernv: Handle unknown OPAL errors in opal_nvram_write() + - powerpc/64s: return more carefully from sreset NMI + - powerpc/64s: sreset panic if there is no debugger or crash dump handlers + + * fsnotify: Fix fsnotify_mark_connector race (LP: #1765564) + - fsnotify: Fix fsnotify_mark_connector race + + * Hang on network interface removal in Xen virtual machine (LP: #1771620) + - xen-netfront: Fix hang on device removal + + * HiSilicon HNS NIC names are truncated in /proc/interrupts (LP: #1765977) + - net: hns: Avoid action name truncation + + * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849) + - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on + num_possible_cpus() + + * Switch Build-Depends: transfig to fig2dev (LP: #1770770) + - [Config] update Build-Depends: transfig to fig2dev + + * smp_call_function_single/many core hangs with stop4 alone (LP: #1768898) + - cpufreq: powernv: Fix hardlockup due to synchronous smp_call in timer + interrupt + + * Add d-i support for Huawei NICs (LP: #1767490) + - d-i: add hinic to nic-modules udeb + + * unregister_netdevice: waiting for eth0 to become free. Usage count = 5 + (LP: #1746474) + - xfrm: reuse uncached_list to track xdsts + + * Include nfp driver in linux-modules (LP: #1768526) + - [Config] Add nfp.ko to generic inclusion list + + * Kernel panic on boot (m1.small in cn-north-1) (LP: #1771679) + - x86/xen: Reset VCPU0 info pointer after shared_info remap + + * CVE-2018-3639 (x86) + - x86/bugs: Fix the parameters alignment and missing void + - KVM: SVM: Move spec control call after restore of GS + - x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP + - x86/cpufeatures: Disentangle MSR_SPEC_CTRL enumeration from IBRS + - x86/cpufeatures: Disentangle SSBD enumeration + - x86/cpufeatures: Add FEATURE_ZEN + - x86/speculation: Handle HT correctly on AMD + - x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL + - x86/speculation: Add virtualized speculative store bypass disable support + - x86/speculation: Rework speculative_store_bypass_update() + - x86/bugs: Unify x86_spec_ctrl_{set_guest,restore_host} + - x86/bugs: Expose x86_spec_ctrl_base directly + - x86/bugs: Remove x86_spec_ctrl_set() + - x86/bugs: Rework spec_ctrl base and mask logic + - x86/speculation, KVM: Implement support for VIRT_SPEC_CTRL/LS_CFG + - KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD + - x86/bugs: Rename SSBD_NO to SSB_NO + - bpf: Prevent memory disambiguation attack + - KVM: VMX: Expose SSBD properly to guests. + + * Suspend to idle: Open lid didn't resume (LP: #1771542) + - ACPI / PM: Do not reconfigure GPEs for suspend-to-idle + + * Fix initialization failure detection in SDEI for device-tree based systems + (LP: #1768663) + - firmware: arm_sdei: Fix return value check in sdei_present_dt() + + * No driver for Huawei network adapters on arm64 (LP: #1769899) + - net-next/hinic: add arm64 support + + * CVE-2018-1092 + - ext4: fail ext4_iget for root directory if unallocated + + * kernel 4.15 breaks nouveau on Lenovo P50 (LP: #1763189) + - drm/nouveau: Fix deadlock in nv50_mstm_register_connector() + + * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails + to load (LP: #1728238) + - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for + unreleased firmware" + + * Battery drains when laptop is off (shutdown) (LP: #1745646) + - PCI / PM: Check device_may_wakeup() in pci_enable_wake() + + * Dell Latitude 5490/5590 BIOS update 1.1.9 causes black screen at boot + (LP: #1764194) + - drm/i915/bios: filter out invalid DDC pins from VBT child devices + + * Intel 9462 A370:42A4 doesn't work (LP: #1748853) + - iwlwifi: add shared clock PHY config flag for some devices + - iwlwifi: add a bunch of new 9000 PCI IDs + + * Fix an issue that some PCI devices get incorrectly suspended (LP: #1764684) + - PCI / PM: Always check PME wakeup capability for runtime wakeup support + + * [SRU][Bionic/Artful] fix false positives in W+X checking (LP: #1769696) + - init: fix false positives in W+X checking + + * Bionic update to v4.15.18 stable release (LP: #1769723) + - netfilter: ipset: Missing nfnl_lock()/nfnl_unlock() is added to + ip_set_net_exit() + - cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN + - rds: MP-RDS may use an invalid c_path + - slip: Check if rstate is initialized before uncompressing + - vhost: fix vhost_vq_access_ok() log check + - l2tp: fix races in tunnel creation + - l2tp: fix race in duplicate tunnel detection + - ip_gre: clear feature flags when incompatible o_flags are set + - vhost: Fix vhost_copy_to_user() + - lan78xx: Correctly indicate invalid OTP + - media: v4l2-compat-ioctl32: don't oops on overlay + - media: v4l: vsp1: Fix header display list status check in continuous mode + - ipmi: Fix some error cleanup issues + - parisc: Fix out of array access in match_pci_device() + - parisc: Fix HPMC handler by increasing size to multiple of 16 bytes + - Drivers: hv: vmbus: do not mark HV_PCIE as perf_device + - PCI: hv: Serialize the present and eject work items + - PCI: hv: Fix 2 hang issues in hv_compose_msi_msg() + - KVM: PPC: Book3S HV: trace_tlbie must not be called in realmode + - perf/core: Fix use-after-free in uprobe_perf_close() + - x86/mce/AMD: Get address from already initialized block + - hwmon: (ina2xx) Fix access to uninitialized mutex + - ath9k: Protect queue draining by rcu_read_lock() + - x86/apic: Fix signedness bug in APIC ID validity checks + - f2fs: fix heap mode to reset it back + - block: Change a rcu_read_{lock,unlock}_sched() pair into + rcu_read_{lock,unlock}() + - nvme: Skip checking heads without namespaces + - lib: fix stall in __bitmap_parselist() + - blk-mq: order getting budget and driver tag + - blk-mq: don't keep offline CPUs mapped to hctx 0 + - ovl: fix lookup with middle layer opaque dir and absolute path redirects + - xen: xenbus_dev_frontend: Fix XS_TRANSACTION_END handling + - hugetlbfs: fix bug in pgoff overflow checking + - nfsd: fix incorrect umasks + - scsi: qla2xxx: Fix small memory leak in qla2x00_probe_one on probe failure + - block/loop: fix deadlock after loop_set_status + - nfit: fix region registration vs block-data-window ranges + - s390/qdio: don't retry EQBS after CCQ 96 + - s390/qdio: don't merge ERROR output buffers + - s390/ipl: ensure loadparm valid flag is set + - get_user_pages_fast(): return -EFAULT on access_ok failure + - mm/gup_benchmark: handle gup failures + - getname_kernel() needs to make sure that ->name != ->iname in long case + - Bluetooth: Fix connection if directed advertising and privacy is used + - Bluetooth: hci_bcm: Treat Interrupt ACPI resources as always being active- + low + - rtl8187: Fix NULL pointer dereference in priv->conf_mutex + - ovl: set lower layer st_dev only if setting lower st_ino + - Linux 4.15.18 + + * Kernel bug when unplugging Thunderbolt 3 cable, leaves xHCI host controller + dead (LP: #1768852) + - xhci: Fix Kernel oops in xhci dbgtty + + * Incorrect blacklist of bcm2835_wdt (LP: #1766052) + - [Packaging] Fix missing watchdog for Raspberry Pi + + * CVE-2018-8087 + - mac80211_hwsim: fix possible memory leak in hwsim_new_radio_nl() + + * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in + DELL XPS 13 9370 with firmware 1.50 (LP: #1763748) + - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device + + * [ALSA] [PATCH] Clevo P950ER ALC1220 Fixup (LP: #1769721) + - SAUCE: ALSA: hda/realtek - Clevo P950ER ALC1220 Fixup + + * Bionic: Intermittently sent to Emergency Mode on boot with unhandled kernel + NULL pointer dereference at 0000000000000980 (LP: #1768292) + - thunderbolt: Prevent crash when ICM firmware is not running + + * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761) + - [Config] snapdragon: DRM_I2C_ADV7511=y + + * regression Aquantia Corp. AQC107 4.15.0-13-generic -> 4.15.0-20-generic ? + (LP: #1767088) + - net: aquantia: Regression on reset with 1.x firmware + - net: aquantia: oops when shutdown on already stopped device + + * e1000e msix interrupts broken in linux-image-4.15.0-15-generic + (LP: #1764892) + - e1000e: Remove Other from EIAC + + * Acer Swift sf314-52 power button not managed (LP: #1766054) + - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode + + * set PINCFG_HEADSET_MIC to parse_flags for Dell precision 3630 (LP: #1766398) + - ALSA: hda/realtek - set PINCFG_HEADSET_MIC to parse_flags + + * Change the location for one of two front mics on a lenovo thinkcentre + machine (LP: #1766477) + - ALSA: hda/realtek - adjust the location of one mic + + * SRU: bionic: apply 50 ZFS upstream bugfixes (LP: #1764690) + - SAUCE: (noup) Update zfs to 0.7.5-1ubuntu15 (LP: #1764690) + + * [8086:3e92] display becomes blank after S3 (LP: #1763271) + - drm/i915/edp: Do not do link training fallback or prune modes on EDP + + -- Stefan Bader Wed, 23 May 2018 18:54:55 +0200 + +linux (4.15.0-22.24) bionic; urgency=medium + + * CVE-2018-3639 (powerpc) + - powerpc/64s: Add support for a store forwarding barrier at kernel entry/exit + - stf-barrier: set eieio instruction bit 6 for future optimisations + + * CVE-2018-3639 (x86) + - x86/nospec: Simplify alternative_msr_write() + - x86/bugs: Concentrate bug detection into a separate function + - x86/bugs: Concentrate bug reporting into a separate function + - x86/bugs: Read SPEC_CTRL MSR during boot and re-use reserved bits + - x86/bugs, KVM: Support the combination of guest and host IBRS + - x86/bugs: Expose /sys/../spec_store_bypass + - x86/cpufeatures: Add X86_FEATURE_RDS + - x86/bugs: Provide boot parameters for the spec_store_bypass_disable + mitigation + - x86/bugs/intel: Set proper CPU features and setup RDS + - x86/bugs: Whitelist allowed SPEC_CTRL MSR values + - x86/bugs/AMD: Add support to disable RDS on Fam[15,16,17]h if requested + - x86/KVM/VMX: Expose SPEC_CTRL Bit(2) to the guest + - x86/speculation: Create spec-ctrl.h to avoid include hell + - prctl: Add speculation control prctls + - x86/process: Allow runtime control of Speculative Store Bypass + - x86/speculation: Add prctl for Speculative Store Bypass mitigation + - nospec: Allow getting/setting on non-current task + - proc: Provide details on speculation flaw mitigations + - seccomp: Enable speculation flaw mitigations + - x86/bugs: Make boot modes __ro_after_init + - prctl: Add force disable speculation + - seccomp: Use PR_SPEC_FORCE_DISABLE + - seccomp: Add filter flag to opt-out of SSB mitigation + - seccomp: Move speculation migitation control to arch code + - x86/speculation: Make "seccomp" the default mode for Speculative Store + Bypass + - x86/bugs: Rename _RDS to _SSBD + - proc: Use underscores for SSBD in 'status' + - Documentation/spec_ctrl: Do some minor cleanups + - x86/bugs: Fix __ssb_select_mitigation() return type + - x86/bugs: Make cpu_show_common() static + + * LSM Stacking prctl values should be redefined as to not collide with + upstream prctls (LP: #1769263) // CVE-2018-3639 + - SAUCE: LSM stacking: adjust prctl values + + -- Stefan Bader Tue, 15 May 2018 07:41:28 +0200 + +linux (4.15.0-21.22) bionic; urgency=medium + + * linux: 4.15.0-21.22 -proposed tracker (LP: #1767397) + + * initramfs-tools exception during pm.DoInstall with do-release-upgrade from + 16.04 to 18.04 (LP: #1766727) + - Add linux-image-* Breaks on s390-tools (<< 2.3.0-0ubuntu3) + + * linux-image-4.15.0-20-generic install after upgrade from xenial breaks + (LP: #1767133) + - Packaging: Depends on linux-base that provides the necessary tools + + * linux-image packages need to Breaks flash-kernel << 3.90ubuntu2 + (LP: #1766629) + - linux-image-* breaks on flash-kernel (<< 3.90ubuntu2) + + -- Thadeu Lima de Souza Cascardo Mon, 30 Apr 2018 14:58:35 -0300 + +linux (4.15.0-20.21) bionic; urgency=medium + + * linux: 4.15.0-20.21 -proposed tracker (LP: #1766452) + + * package shim-signed (not installed) failed to install/upgrade: installed + shim-signed package post-installation script subprocess returned error exit + status 5 (LP: #1766391) + - [Packaging] fix invocation of header postinst hooks + + -- Seth Forshee Mon, 23 Apr 2018 23:56:17 -0500 + +linux (4.15.0-19.20) bionic; urgency=medium + + * linux: 4.15.0-19.20 -proposed tracker (LP: #1766021) + + * Kernel 4.15.0-15 breaks Dell PowerEdge 12th Gen servers (LP: #1765232) + - Revert "blk-mq: simplify queue mapping & schedule with each possisble CPU" + - Revert "genirq/affinity: assign vectors to all possible CPUs" + + -- Seth Forshee Sat, 21 Apr 2018 17:19:00 -0500 + +linux (4.15.0-18.19) bionic; urgency=medium + + * linux: 4.15.0-18.19 -proposed tracker (LP: #1765490) + + * [regression] Ubuntu 18.04:[4.15.0-17-generic #18] KVM Guest Kernel: + meltdown: rfi/fallback displacement flush not enabled bydefault (kvm) + (LP: #1765429) + - powerpc/pseries: Fix clearing of security feature flags + + * signing: only install a signed kernel (LP: #1764794) + - [Packaging] update to Debian like control scripts + - [Packaging] switch to triggers for postinst.d postrm.d handling + - [Packaging] signing -- switch to raw-signing tarballs + - [Packaging] signing -- switch to linux-image as signed when available + - [Config] signing -- enable Opal signing for ppc64el + - [Packaging] printenv -- add signing options + + * [18.04 FEAT] Sign POWER host/NV kernels (LP: #1696154) + - [Packaging] signing -- add support for signing Opal kernel binaries + + * Please cherrypick s390 unwind fix (LP: #1765083) + - s390/compat: fix setup_frame32 + + * Ubuntu 18.04 installer does not detect any IPR based HDD/RAID array [S822L] + [ipr] (LP: #1751813) + - d-i: move ipr to storage-core-modules on ppc64el + + * drivers/gpu/drm/bridge/adv7511/adv7511.ko missing (LP: #1764816) + - SAUCE: (no-up) rename the adv7511 drm driver to adv7511_drm + + * Miscellaneous Ubuntu changes + - [Packaging] Add linux-oem to rebuild test blacklist. + + -- Thadeu Lima de Souza Cascardo Thu, 19 Apr 2018 18:06:46 -0300 + +linux (4.15.0-17.18) bionic; urgency=medium + + * linux: 4.15.0-17.18 -proposed tracker (LP: #1764498) + + * Eventual OOM with profile reloads (LP: #1750594) + - SAUCE: apparmor: fix memory leak when duplicate profile load + + -- Seth Forshee Mon, 16 Apr 2018 14:48:18 -0500 + +linux (4.15.0-16.17) bionic; urgency=medium + + * linux: 4.15.0-16.17 -proposed tracker (LP: #1763785) + + * [18.04] [bug] CFL-S(CNP)/CNL GPIO testing failed (LP: #1757346) + - [Config]: Set CONFIG_PINCTRL_CANNONLAKE=y + + * [Ubuntu 18.04] USB Type-C test failed on GLK (LP: #1758797) + - SAUCE: usb: typec: ucsi: Increase command completion timeout value + + * Fix trying to "push" an already active pool VP (LP: #1763386) + - SAUCE: powerpc/xive: Fix trying to "push" an already active pool VP + + * hisi_sas: Revert and replace SAUCE patches w/ upstream (LP: #1762824) + - Revert "UBUNTU: SAUCE: scsi: hisi_sas: export device table of v3 hw to + userspace" + - Revert "UBUNTU: SAUCE: scsi: hisi_sas: config for hip08 ES" + - scsi: hisi_sas: modify some register config for hip08 + - scsi: hisi_sas: add v3 hw MODULE_DEVICE_TABLE() + + * Realtek card reader - RTS5243 [VEN_10EC&DEV_5260] (LP: #1737673) + - misc: rtsx: Move Realtek Card Reader Driver to misc + - updateconfigs for Realtek Card Reader Driver + - misc: rtsx: Add support for RTS5260 + - misc: rtsx: Fix symbol clashes + + * Mellanox [mlx5] [bionic] UBSAN: Undefined behaviour in + ./include/linux/net_dim.h (LP: #1763269) + - net/mlx5e: Fix int overflow + + * apparmor bug fixes for bionic (LP: #1763427) + - apparmor: fix logging of the existence test for signals + - apparmor: make signal label match work when matching stacked labels + - apparmor: audit unknown signal numbers + - apparmor: fix memory leak on buffer on error exit path + - apparmor: fix mediation of prlimit + + * dangling symlinks to loaded apparmor policy (LP: #1755563) // apparmor bug + fixes for bionic (LP: #1763427) + - apparmor: fix dangling symlinks to policy rawdata after replacement + + * [OPAL] Assert fail: + core/mem_region.c:447:lock_held_by_me(®ion->free_list_lock) + (LP: #1762913) + - powerpc/watchdog: remove arch_trigger_cpumask_backtrace + + * [LTC Test] Ubuntu 18.04: tm_trap_test failed on P8 compat mode guest + (LP: #1762928) + - powerpc/tm: Fix endianness flip on trap + + * Add support for RT5660 codec based sound cards on Baytrail (LP: #1657674) + - SAUCE: (no-up) ASoC: Intel: Support machine driver for RT5660 on Baytrail + - SAUCE: (no-up) ASoC: rt5660: Add ACPI support + - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Add MCLK, quirks + - [Config] CONFIG_SND_SOC_INTEL_BYTCR_RT5660_MACH=m, CONFIG_SND_SOC_RT5660=m + + * /dev/ipmi enumeration flaky on Cavium Sabre nodes (LP: #1762812) + - i2c: xlp9xx: return ENXIO on slave address NACK + - i2c: xlp9xx: Handle transactions with I2C_M_RECV_LEN properly + - i2c: xlp9xx: Check for Bus state before every transfer + - i2c: xlp9xx: Handle NACK on DATA properly + + * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130) + - tools/kvm_stat: simplify the sortkey function + - tools/kvm_stat: use a namedtuple for storing the values + - tools/kvm_stat: use a more pythonic way to iterate over dictionaries + - tools/kvm_stat: avoid 'is' for equality checks + - tools/kvm_stat: fix crash when filtering out all non-child trace events + - tools/kvm_stat: print error on invalid regex + - tools/kvm_stat: fix debugfs handling + - tools/kvm_stat: mark private methods as such + - tools/kvm_stat: eliminate extra guest/pid selection dialog + - tools/kvm_stat: separate drilldown and fields filtering + - tools/kvm_stat: group child events indented after parent + - tools/kvm_stat: print 'Total' line for multiple events only + - tools/kvm_stat: Fix python3 syntax + - tools/kvm_stat: Don't use deprecated file() + - tools/kvm_stat: Remove unused function + - [Packaging] Add linux-tools-host package for VM host tools + - [Config] do_tools_host=true for amd64 + + * Bionic update to v4.15.17 stable release (LP: #1763366) + - i40iw: Fix sequence number for the first partial FPDU + - i40iw: Correct Q1/XF object count equation + - i40iw: Validate correct IRD/ORD connection parameters + - clk: meson: mpll: use 64-bit maths in params_from_rate + - ARM: dts: ls1021a: add "fsl,ls1021a-esdhc" compatible string to esdhc node + - Bluetooth: Add a new 04ca:3015 QCA_ROME device + - ipv6: Reinject IPv6 packets if IPsec policy matches after SNAT + - thermal: power_allocator: fix one race condition issue for thermal_instances + list + - perf probe: Find versioned symbols from map + - perf probe: Add warning message if there is unexpected event name + - perf evsel: Fix swap for samples with raw data + - perf evsel: Enable ignore_missing_thread for pid option + - l2tp: fix missing print session offset info + - rds; Reset rs->rs_bound_addr in rds_add_bound() failure path + - ACPI / video: Default lcd_only to true on Win8-ready and newer machines + - IB/mlx5: Report inner RSS capability + - VFS: close race between getcwd() and d_move() + - watchdog: dw_wdt: add stop watchdog operation + - clk: divider: fix incorrect usage of container_of + - PM / devfreq: Fix potential NULL pointer dereference in governor_store + - gpiolib: don't dereference a desc before validation + - net_sch: red: Fix the new offload indication + - selftests/net: fix bugs in address and port initialization + - thermal/drivers/hisi: Remove bogus const from function return type + - RDMA/cma: Mark end of CMA ID messages + - hwmon: (ina2xx) Make calibration register value fixed + - f2fs: fix lock dependency in between dio_rwsem & i_mmap_sem + - clk: sunxi-ng: a83t: Add M divider to TCON1 clock + - media: videobuf2-core: don't go out of the buffer range + - ASoC: Intel: Skylake: Disable clock gating during firmware and library + download + - ASoC: Intel: cht_bsw_rt5645: Analog Mic support + - drm/msm: Fix NULL deref in adreno_load_gpu + - IB/ipoib: Fix for notify send CQ failure messages + - spi: sh-msiof: Fix timeout failures for TX-only DMA transfers + - scsi: mpt3sas: Proper handling of set/clear of "ATA command pending" flag. + - irqchip/ompic: fix return value check in ompic_of_init() + - irqchip/gic-v3: Fix the driver probe() fail due to disabled GICC entry + - ACPI: EC: Fix debugfs_create_*() usage + - mac80211: Fix setting TX power on monitor interfaces + - vfb: fix video mode and line_length being set when loaded + - crypto: crypto4xx - perform aead icv check in the driver + - gpio: label descriptors using the device name + - arm64: asid: Do not replace active_asids if already 0 + - powernv-cpufreq: Add helper to extract pstate from PMSR + - IB/rdmavt: Allocate CQ memory on the correct node + - blk-mq: avoid to map CPU into stale hw queue + - blk-mq: fix race between updating nr_hw_queues and switching io sched + - backlight: tdo24m: Fix the SPI CS between transfers + - nvme-fabrics: protect against module unload during create_ctrl + - nvme-fabrics: don't check for non-NULL module in nvmf_register_transport + - pinctrl: baytrail: Enable glitch filter for GPIOs used as interrupts + - nvme_fcloop: disassocate local port structs + - nvme_fcloop: fix abort race condition + - tpm: return a TPM_RC_COMMAND_CODE response if command is not implemented + - perf report: Fix a no annotate browser displayed issue + - staging: lustre: disable preempt while sampling processor id. + - ASoC: Intel: sst: Fix the return value of 'sst_send_byte_stream_mrfld()' + - power: supply: axp288_charger: Properly stop work on probe-error / remove + - rt2x00: do not pause queue unconditionally on error path + - wl1251: check return from call to wl1251_acx_arp_ip_filter + - net/mlx5: Fix race for multiple RoCE enable + - bcache: ret IOERR when read meets metadata error + - bcache: stop writeback thread after detaching + - bcache: segregate flash only volume write streams + - net: Fix netdev_WARN_ONCE macro + - net/mlx5e: IPoIB, Use correct timestamp in child receive flow + - blk-mq: fix kernel oops in blk_mq_tag_idle() + - tty: n_gsm: Allow ADM response in addition to UA for control dlci + - block, bfq: put async queues for root bfq groups too + - serdev: Fix serdev_uevent failure on ACPI enumerated serdev-controllers + - EDAC, mv64x60: Fix an error handling path + - uio_hv_generic: check that host supports monitor page + - Bluetooth: hci_bcm: Mandate presence of shutdown and device wake GPIO + - Bluetooth: hci_bcm: Validate IRQ before using it + - Bluetooth: hci_bcm: Make shutdown and device wake GPIO optional + - i40evf: don't rely on netif_running() outside rtnl_lock() + - drm/amd/powerplay: fix memory leakage when reload (v2) + - cxgb4vf: Fix SGE FL buffer initialization logic for 64K pages + - PM / domains: Don't skip driver's ->suspend|resume_noirq() callbacks + - scsi: megaraid_sas: Error handling for invalid ldcount provided by firmware + in RAID map + - scsi: megaraid_sas: unload flag should be set after scsi_remove_host is + called + - RDMA/cma: Fix rdma_cm path querying for RoCE + - gpio: thunderx: fix error return code in thunderx_gpio_probe() + - x86/gart: Exclude GART aperture from vmcore + - sdhci: Advertise 2.0v supply on SDIO host controller + - Input: goodix - disable IRQs while suspended + - mtd: mtd_oobtest: Handle bitflips during reads + - crypto: aes-generic - build with -Os on gcc-7+ + - perf tools: Fix copyfile_offset update of output offset + - tcmu: release blocks for partially setup cmds + - thermal: int3400_thermal: fix error handling in int3400_thermal_probe() + - drm/i915/cnp: Ignore VBT request for know invalid DDC pin. + - drm/i915/cnp: Properly handle VBT ddc pin out of bounds. + - x86/microcode: Propagate return value from updating functions + - x86/CPU: Add a microcode loader callback + - x86/CPU: Check CPU feature bits after microcode upgrade + - x86/microcode: Get rid of struct apply_microcode_ctx + - x86/microcode/intel: Check microcode revision before updating sibling + threads + - x86/microcode/intel: Writeback and invalidate caches before updating + microcode + - x86/microcode: Do not upload microcode if CPUs are offline + - x86/microcode/intel: Look into the patch cache first + - x86/microcode: Request microcode on the BSP + - x86/microcode: Synchronize late microcode loading + - x86/microcode: Attempt late loading only when new microcode is present + - x86/microcode: Fix CPU synchronization routine + - arp: fix arp_filter on l3slave devices + - ipv6: the entire IPv6 header chain must fit the first fragment + - lan78xx: Crash in lan78xx_writ_reg (Workqueue: events + lan78xx_deferred_multicast_write) + - net: dsa: Discard frames from unused ports + - net: fix possible out-of-bound read in skb_network_protocol() + - net/ipv6: Fix route leaking between VRFs + - net/ipv6: Increment OUTxxx counters after netfilter hook + - netlink: make sure nladdr has correct size in netlink_connect() + - net/mlx5e: Verify coalescing parameters in range + - net sched actions: fix dumping which requires several messages to user space + - net/sched: fix NULL dereference in the error path of tcf_bpf_init() + - pptp: remove a buggy dst release in pptp_connect() + - r8169: fix setting driver_data after register_netdev + - sctp: do not leak kernel memory to user space + - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6 + - vhost: correctly remove wait queue during poll failure + - vlan: also check phy_driver ts_info for vlan's real device + - vrf: Fix use after free and double free in vrf_finish_output + - bonding: fix the err path for dev hwaddr sync in bond_enslave + - bonding: move dev_mc_sync after master_upper_dev_link in bond_enslave + - bonding: process the err returned by dev_set_allmulti properly in + bond_enslave + - net: fool proof dev_valid_name() + - ip_tunnel: better validate user provided tunnel names + - ipv6: sit: better validate user provided tunnel names + - ip6_gre: better validate user provided tunnel names + - ip6_tunnel: better validate user provided tunnel names + - vti6: better validate user provided tunnel names + - net/mlx5e: Set EQE based as default TX interrupt moderation mode + - net_sched: fix a missing idr_remove() in u32_delete_key() + - net/sched: fix NULL dereference in the error path of tcf_vlan_init() + - net/mlx5e: Avoid using the ipv6 stub in the TC offload neigh update path + - net/mlx5e: Fix memory usage issues in offloading TC flows + - net/sched: fix NULL dereference in the error path of tcf_sample_init() + - nfp: use full 40 bits of the NSP buffer address + - ipv6: sr: fix seg6 encap performances with TSO enabled + - net/mlx5e: Don't override vport admin link state in switchdev mode + - net/mlx5e: Sync netdev vxlan ports at open + - net/sched: fix NULL dereference in the error path of tunnel_key_init() + - net/sched: fix NULL dereference on the error path of tcf_skbmod_init() + - strparser: Fix sign of err codes + - net/mlx4_en: Fix mixed PFC and Global pause user control requests + - net/mlx5e: Fix traffic being dropped on VF representor + - vhost: validate log when IOTLB is enabled + - route: check sysctl_fib_multipath_use_neigh earlier than hash + - team: move dev_mc_sync after master_upper_dev_link in team_port_add + - vhost_net: add missing lock nesting notation + - net/mlx4_core: Fix memory leak while delete slave's resources + - Linux 4.15.17 + + * sky2 gigabit ethernet driver sometimes stops working after lid-open resume + from sleep (88E8055) (LP: #1758507) // Bionic update to v4.15.17 stable + release (LP: #1763366) + - sky2: Increase D3 delay to sky2 stops working after suspend + + * [Featire] CNL: Enable RAPL support (LP: #1685712) + - powercap: RAPL: Add support for Cannon Lake + + * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719) + - s390: move nobp parameter functions to nospec-branch.c + - s390: add automatic detection of the spectre defense + - s390: report spectre mitigation via syslog + - s390: add sysfs attributes for spectre + - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390 + - s390: correct nospec auto detection init order + + * Merge the linux-snapdragon kernel into bionic master/snapdragon + (LP: #1763040) + - drm/msm: fix spelling mistake: "ringubffer" -> "ringbuffer" + - drm/msm: fix msm_rd_dump_submit prototype + - drm/msm: gpu: Only sync fences on rings that exist + - wcn36xx: set default BTLE coexistence config + - wcn36xx: Add hardware scan offload support + - wcn36xx: Reduce spinlock in indication handler + - wcn36xx: fix incorrect assignment to msg_body.min_ch_time + - wcn36xx: release DMA memory in case of error + - mailbox: qcom: Convert APCS IPC driver to use regmap + - mailbox: qcom: Create APCS child device for clock controller + - clk: qcom: Add A53 PLL support + - clk: qcom: Add regmap mux-div clocks support + - clk: qcom: Add APCS clock controller support + - clk: qcom: msm8916: Fix return value check in qcom_apcs_msm8916_clk_probe() + - media: venus: venc: set correctly GOP size and number of B-frames + - media: venus: venc: configure entropy mode + - media: venus: venc: Apply inloop deblocking filter + - media: venus: cleanup set_property controls + - arm64: defconfig: enable REMOTEPROC + - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c + - kernel: configs; add distro.config + - arm64: configs: enable WCN36xx + - kernel: distro.config: enable debug friendly USB network adpater + - arm64: configs: enable QCOM Venus + - arm64: defconfig: Enable a53/apcs and avs + - arm64: defconfig: enable ondemand governor as default + - arm64: defconfig: enable QCOM_TSENS + - arm64: defconfig: enable new trigger modes for leds + - kernel: configs: enable dm_mod and dm_crypt + - Force the SMD regulator driver to be compiled-in + - arm64: defconfig: enable CFG80211_DEFAULT_PS by default + - arm64: configs: enable BT_QCOMSMD + - kernel: configs: add more USB net drivers + - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV + - arm64: configs: Enable camera drivers + - kernel: configs: add freq stat to sysfs + - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default + - arm64: defconfig: Enable QRTR features + - kernel: configs: set USB_CONFIG_F_FS in distro.config + - kernel: distro.config: enable 'schedutil' CPUfreq governor + - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs + - kernel: distro.config: enable 'BBR' TCP congestion algorithm + - arm64: defconfig: enable LEDS_QCOM_LPG + - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap + - power: avs: Add support for CPR (Core Power Reduction) + - power: avs: cpr: Use raw mem access for qfprom + - power: avs: cpr: fix with new reg_sequence structures + - power: avs: cpr: Register with cpufreq-dt + - regulator: smd: Add floor and corner operations + - PM / OPP: Support adjusting OPP voltages at runtime + - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage() + - PM / OPP: HACK: Allow to set regulator without opp_list + - PM / OPP: Add a helper to get an opp regulator for device + - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist + - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m + - ov5645: I2C address change + - i2c: Add Qualcomm Camera Control Interface driver + - camss: vfe: Skip first four frames from sensor + - camss: Do not register if no cameras are present + - i2c-qcom-cci: Fix run queue completion timeout + - i2c-qcom-cci: Fix I2C address bug + - media: ov5645: Fix I2C address + - drm/bridge/adv7511: Delay clearing of HPD interrupt status + - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing + - leds: Add driver for Qualcomm LPG + - wcn36xx: Fix warning due to duplicate scan_completed notification + - arm64: dts: Add CPR DT node for msm8916 + - arm64: dts: add spmi-regulator nodes + - arm64: dts: msm8916: Add cpufreq support + - arm64: dts: msm8916: Add a shared CPU opp table + - arm64: dts: msm8916: Add cpu cooling maps + - arm64: dts: pm8916: Mark the s2 regulator as always-on + - dt-bindings: mailbox: qcom: Document the APCS clock binding + - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node + - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver + - arm64: dts: qcom: msm8916: Add clock properties to the APCS node + - arm64: dts: qcom: apq8016-sbc: Allow USR4 LED to notify kernel panic + - dt-bindings: media: Binding document for Qualcomm Camera Control Interface + driver + - MAINTAINERS: Add Qualcomm Camera Control Interface driver + - DT: leds: Add Qualcomm Light Pulse Generator binding + - arm64: dts: qcom: msm8996: Add mpp and lpg blocks + - arm64: dts: qcom: Add pwm node for pm8916 + - arm64: dts: qcom: Add user LEDs on db820c + - arm64: dts: qcom: Add WiFI/BT LEDs on db820c + - ARM: dts: qcom: Add LPG node to pm8941 + - ARM: dts: qcom: honami: Add LPG node and RGB LED + - arm64: dts: qcom: Add Camera Control Interface support + - arm64: dts: qcom: Add apps_iommu vfe child node + - arm64: dts: qcom: Add camss device node + - arm64: dts: qcom: Add ov5645 device nodes + - arm64: dts: msm8916: Fix camera sensors I2C addresses + - arm: dts: qcom: db410c: Enable PWM signal on MPP4 + - packaging: arm64: add a uboot flavour - part1 + - packaging: arm64: add a uboot flavour - part2 + - packaging: arm64: add a uboot flavour - part3 + - packaging: arm64: add a uboot flavour - part4 + - packaging: arm64: add a uboot flavour - part5 + - packaging: arm64: rename uboot flavour to snapdragon + - [Config] updateconfigs after qcomlt import + - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y + - [Config] arm64: snapdragon: MSM_GCC_8916=y + - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y + - [Config] arm64: snapdragon: PINCTRL_MSM8916=y + - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y + - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y + - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y + - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y + - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y + - [Config] arm64: snapdragon: QCOM_SMEM=y + - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y + - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y + - [Config] arm64: snapdragon: QCOM_BAM_DMA=y + - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y + - [Config] arm64: snapdragon: QCOM_CPR=y + - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y + - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y + - [Config] turn off DRM_MSM_REGISTER_LOGGING + - [Config] arm64: snapdragon: I2C_QUP=y + - [Config] arm64: snapdragon: SPI_QUP=y + - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y + - [Config] arm64: snapdragon: QCOM_APCS_IPC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y + - [Config] arm64: snapdragon: QCOM_SMSM=y + - [Config] arm64: snapdragon: QCOM_SMP2P=y + - [Config] arm64: snapdragon: DRM_MSM=y + - [Config] arm64: snapdragon: SND_SOC=y + - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m + - [Config] arm64: snapdragon: QCOM_A53PLL=y, QCOM_CLK_APCS_MSM8916=y + - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y + - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m + - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y + - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y, + SND_SOC_MSM8916_WCD_DIGITAL=y + - SAUCE: media: ov5645: skip address change if dt addr == default addr + - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS + #ifdefs + - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y + - packaging: snapdragon: fixup ABI paths + + * LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: Manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: Manage task security blobs + - SAUCE: LSM stacking: LSM: Manage remaining security blobs + - SAUCE: LSM stacking: LSM: General stacking + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: add apparmor and selinux proc dirs + - SAUCE: LSM stacking: remove procfs context interface + + * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14 + (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062) + - SAUCE: LSM stacking: check for invalid zero sized writes + + * RDMA/hns: ensure for-loop actually iterates and free's buffers + (LP: #1762757) + - RDMA/hns: ensure for-loop actually iterates and free's buffers + + * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems + (LP: #1762755) + - RDMA/hns: Fix the endian problem for hns + - RDMA/hns: Support rq record doorbell for the user space + - RDMA/hns: Support cq record doorbell for the user space + - RDMA/hns: Support rq record doorbell for kernel space + - RDMA/hns: Support cq record doorbell for kernel space + - RDMA/hns: Fix cqn type and init resp + - RDMA/hns: Fix init resp when alloc ucontext + - RDMA/hns: Fix cq record doorbell enable in kernel + + * Replace LPC patchset with upstream version (LP: #1762758) + - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver" + - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support" + - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host + children" + - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT + bindings" + - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO + devices" + - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO + hosts" + - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in + pci_register_io_range()" + - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method" + - lib: Add generic PIO mapping method + - PCI: Remove __weak tag from pci_register_io_range() + - PCI: Add fwnode handler as input param of pci_register_io_range() + - PCI: Apply the new generic I/O management on PCI IO hosts + - of: Add missing I/O range exception for indirect-IO devices + - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use + - ACPI / scan: Do not enumerate Indirect IO host children + - HISI LPC: Add ACPI support + - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver + + * Enable Tunneled Operations on POWER9 (LP: #1762448) + - powerpc/powernv: Enable tunneled operations + - cxl: read PHB indications from the device tree + + * PSL traces reset after PERST for debug AFU image (LP: #1762462) + - cxl: Enable NORST bit in PSL_DEBUG register for PSL9 + + * NFS + sec=krb5 is broken (LP: #1759791) + - sunrpc: remove incorrect HMAC request initialization + + * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128) + - d-i: add bcm2835 to block-modules + + * Backport USB core quirks (LP: #1762695) + - usb: core: Add "quirks" parameter for usbcore + - usb: core: Copy parameter string correctly and remove superfluous null check + - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks + + * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on failed' when + setting up a second end-to-end encrypted disk (LP: #1762353) + - SAUCE: s390/crypto: Adjust s390 aes and paes cipher + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 + - powerpc/64s: Wire up cpu_show_spectre_v2() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753 + - powerpc/64s: Wire up cpu_show_spectre_v1() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754 + - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code + - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again + - powerpc/rfi-flush: Always enable fallback flush on pseries + - powerpc/rfi-flush: Differentiate enabled and patched flush types + - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration + - powerpc/64s: Move cpu_show_meltdown() + - powerpc/64s: Enhance the information in cpu_show_meltdown() + - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush() + - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush() + + * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 // + CVE-2017-5753 // CVE-2017-5754 + - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags + - powerpc: Add security feature flags for Spectre/Meltdown + - powerpc/pseries: Set or clear security feature flags + - powerpc/powernv: Set or clear security feature flags + + * Hisilicon network subsystem 3 support (LP: #1761610) + - net: hns3: export pci table of hclge and hclgevf to userspace + - d-i: Add hns3 drivers to nic-modules + + * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534) + - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS + + * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712) + - perf vendor events aarch64: Add JSON metrics for ARM Cortex-A53 Processor + - perf vendor events: Drop incomplete multiple mapfile support + - perf vendor events: Fix error code in json_events() + - perf vendor events: Drop support for unused topic directories + - perf vendor events: Add support for pmu events vendor subdirectory + - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory + - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory + - perf vendor events: Add support for arch standard events + - perf vendor events arm64: Add armv8-recommended.json + - perf vendor events arm64: Fixup ThunderX2 to use recommended events + - perf vendor events arm64: fixup A53 to use recommended events + - perf vendor events arm64: add HiSilicon hip08 JSON file + - perf vendor events arm64: Enable JSON events for ThunderX2 B0 + + * Warning "cache flush timed out!" seen when unloading the cxl driver + (LP: #1762367) + - cxl: Check if PSL data-cache is available before issue flush request + + * Bionic update to 4.15.16 stable release (LP: #1762370) + - ARM: OMAP: Fix SRAM W+X mapping + - ARM: 8746/1: vfp: Go back to clearing vfp_current_hw_state[] + - ARM: dts: sun6i: a31s: bpi-m2: improve pmic properties + - ARM: dts: sun6i: a31s: bpi-m2: add missing regulators + - mtd: jedec_probe: Fix crash in jedec_read_mfr() + - mtd: nand: atmel: Fix get_sectorsize() function + - ALSA: usb-audio: Add native DSD support for TEAC UD-301 + - ALSA: pcm: Use dma_bytes as size parameter in dma_mmap_coherent() + - ALSA: pcm: potential uninitialized return values + - x86/platform/uv/BAU: Add APIC idt entry + - perf/hwbp: Simplify the perf-hwbp code, fix documentation + - ceph: only dirty ITER_IOVEC pages for direct read + - ipc/shm.c: add split function to shm_vm_ops + - i2c: i2c-stm32f7: fix no check on returned setup + - powerpc/mm: Add tracking of the number of coprocessors using a context + - powerpc/mm: Workaround Nest MMU bug with TLB invalidations + - powerpc/64s: Fix i-side SLB miss bad address handler saving nonvolatile GPRs + - partitions/msdos: Unable to mount UFS 44bsd partitions + - xfrm_user: uncoditionally validate esn replay attribute struct + - RDMA/ucma: Check AF family prior resolving address + - RDMA/ucma: Fix use-after-free access in ucma_close + - RDMA/ucma: Ensure that CM_ID exists prior to access it + - RDMA/rdma_cm: Fix use after free race with process_one_req + - RDMA/ucma: Check that device is connected prior to access it + - RDMA/ucma: Check that device exists prior to accessing it + - RDMA/ucma: Introduce safer rdma_addr_size() variants + - ipv6: fix possible deadlock in rt6_age_examine_exception() + - net: xfrm: use preempt-safe this_cpu_read() in ipcomp_alloc_tfms() + - xfrm: Refuse to insert 32 bit userspace socket policies on 64 bit systems + - percpu: add __GFP_NORETRY semantics to the percpu balancing path + - netfilter: x_tables: make allocation less aggressive + - netfilter: bridge: ebt_among: add more missing match size checks + - l2tp: fix races with ipv4-mapped ipv6 addresses + - netfilter: drop template ct when conntrack is skipped. + - netfilter: x_tables: add and use xt_check_proc_name + - phy: qcom-ufs: add MODULE_LICENSE tag + - Bluetooth: Fix missing encryption refresh on Security Request + - drm/i915/dp: Write to SET_POWER dpcd to enable MST hub. + - bitmap: fix memset optimization on big-endian systems + - USB: serial: ftdi_sio: add RT Systems VX-8 cable + - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator + - USB: serial: cp210x: add ELDAT Easywave RX09 id + - serial: 8250: Add Nuvoton NPCM UART + - mei: remove dev_err message on an unsupported ioctl + - /dev/mem: Avoid overwriting "err" in read_mem() + - media: usbtv: prevent double free in error case + - parport_pc: Add support for WCH CH382L PCI-E single parallel port card. + - crypto: lrw - Free rctx->ext with kzfree + - crypto: talitos - don't persistently map req_ctx->hw_context and + req_ctx->buf + - crypto: inside-secure - fix clock management + - crypto: testmgr - Fix incorrect values in PKCS#1 test vector + - crypto: talitos - fix IPsec cipher in length + - crypto: ahash - Fix early termination in hash walk + - crypto: caam - Fix null dereference at error path + - crypto: ccp - return an actual key size from RSA max_size callback + - crypto: arm,arm64 - Fix random regeneration of S_shipped + - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one + - Btrfs: fix unexpected cow in run_delalloc_nocow + - staging: comedi: ni_mio_common: ack ai fifo error interrupts. + - Revert "base: arch_topology: fix section mismatch build warnings" + - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370 + - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list + - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad + - vt: change SGR 21 to follow the standards + - ARM: dts: DRA76-EVM: Set powerhold property for tps65917 + - net: hns: Fix ethtool private flags + - Fix slab name "biovec-(1<<(21-12))" + - Revert "ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin" + - Revert "ARM: dts: omap3-n900: Fix the audio CODEC's reset pin" + - Revert "cpufreq: Fix governor module removal race" + - Revert "ip6_vti: adjust vti mtu according to mtu of lower device" + - Linux 4.15.16 + + * [18.04][config] regression: nvme and nvme_core couldn't be built as modules + starting 4.15-rc2 (LP: #1759893) + - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for + build" + - [Config] CONFIG_BLK_DEV_NMVE=m + + * Miscellaneous Ubuntu changes + - [Packaging] Only install cloud init files when do_tools_common=true + + -- Thadeu Lima de Souza Cascardo Fri, 13 Apr 2018 14:40:52 -0300 + +linux (4.15.0-15.16) bionic; urgency=medium + + * linux: 4.15.0-15.16 -proposed tracker (LP: #1761177) + + * FFe: Enable configuring resume offset via sysfs (LP: #1760106) + - PM / hibernate: Make passing hibernate offsets more friendly + + * /dev/bcache/by-uuid links not created after reboot (LP: #1729145) + - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent + + * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine + type(pseries-bionic) complaining "KVM implementation does not support + Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026) + - powerpc: Use feature bit for RTC presence rather than timebase presence + - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit + - powerpc: Free up CPU feature bits on 64-bit machines + - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2 + - powerpc/powernv: Provide a way to force a core into SMT4 mode + - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9 + - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode + - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state + + * Important Kernel fixes to be backported for Power9 (kvm) (LP: #1758910) + - powerpc/mm: Fixup tlbie vs store ordering issue on POWER9 + + * Ubuntu 18.04 - IO Hang on some namespaces when running HTX with 16 + namespaces (Bolt / NVMe) (LP: #1757497) + - powerpc/64s: Fix lost pending interrupt due to race causing lost update to + irq_happened + + * fwts-efi-runtime-dkms 18.03.00-0ubuntu1: fwts-efi-runtime-dkms kernel module + failed to build (LP: #1760876) + - [Packaging] include the retpoline extractor in the headers + + -- Seth Forshee Wed, 04 Apr 2018 08:26:19 -0500 + +linux (4.15.0-14.15) bionic; urgency=medium + + * linux: 4.15.0-14.15 -proposed tracker (LP: #1760678) + + * [Bionic] mlx4 ETH - mlnx_qos failed when set some TC to vendor + (LP: #1758662) + - net/mlx4_en: Change default QoS settings + + * AT_BASE_PLATFORM in AUXV is absent on kernels available on Ubuntu 17.10 + (LP: #1759312) + - powerpc/64s: Fix NULL AT_BASE_PLATFORM when using DT CPU features + + * Bionic update to 4.15.15 stable release (LP: #1760585) + - net: dsa: Fix dsa_is_user_port() test inversion + - openvswitch: meter: fix the incorrect calculation of max delta_t + - qed: Fix MPA unalign flow in case header is split across two packets. + - tcp: purge write queue upon aborting the connection + - qed: Fix non TCP packets should be dropped on iWARP ll2 connection + - sysfs: symlink: export sysfs_create_link_nowarn() + - net: phy: relax error checking when creating sysfs link netdev->phydev + - devlink: Remove redundant free on error path + - macvlan: filter out unsupported feature flags + - net: ipv6: keep sk status consistent after datagram connect failure + - ipv6: old_dport should be a __be16 in __ip6_datagram_connect() + - ipv6: sr: fix NULL pointer dereference when setting encap source address + - ipv6: sr: fix scheduling in RCU when creating seg6 lwtunnel state + - mlxsw: spectrum_buffers: Set a minimum quota for CPU port traffic + - net: phy: Tell caller result of phy_change() + - ipv6: Reflect MTU changes on PMTU of exceptions for MTU-less routes + - net sched actions: return explicit error when tunnel_key mode is not + specified + - ppp: avoid loop in xmit recursion detection code + - rhashtable: Fix rhlist duplicates insertion + - test_rhashtable: add test case for rhltable with duplicate objects + - kcm: lock lower socket in kcm_attach + - sch_netem: fix skb leak in netem_enqueue() + - ieee802154: 6lowpan: fix possible NULL deref in lowpan_device_event() + - net: use skb_to_full_sk() in skb_update_prio() + - net: Fix hlist corruptions in inet_evict_bucket() + - s390/qeth: free netdevice when removing a card + - s390/qeth: when thread completes, wake up all waiters + - s390/qeth: lock read device while queueing next buffer + - s390/qeth: on channel error, reject further cmd requests + - soc/fsl/qbman: fix issue in qman_delete_cgr_safe() + - dpaa_eth: fix error in dpaa_remove() + - dpaa_eth: remove duplicate initialization + - dpaa_eth: increment the RX dropped counter when needed + - dpaa_eth: remove duplicate increment of the tx_errors counter + - dccp: check sk for closed state in dccp_sendmsg() + - ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option() + - l2tp: do not accept arbitrary sockets + - net: ethernet: arc: Fix a potential memory leak if an optional regulator is + deferred + - net: ethernet: ti: cpsw: add check for in-band mode setting with RGMII PHY + interface + - net: fec: Fix unbalanced PM runtime calls + - net/iucv: Free memory obtained by kzalloc + - netlink: avoid a double skb free in genlmsg_mcast() + - net: Only honor ifindex in IP_PKTINFO if non-0 + - net: systemport: Rewrite __bcm_sysport_tx_reclaim() + - qede: Fix qedr link update + - skbuff: Fix not waking applications when errors are enqueued + - team: Fix double free in error path + - Linux 4.15.15 + + * Ubuntu 18.04 [ WSP DD2.2 with stop4 and stop5 enabled ]: kdump fails to + capture dump when smt=2 or off. (LP: #1758206) + - powerpc/crash: Remove the test for cpu_online in the IPI callback + - powernv/kdump: Fix cases where the kdump kernel can get HMI's + - powerpc/kdump: Fix powernv build break when KEXEC_CORE=n + + * [Intel Ubuntu 18.04 Bug] Null pointer dereference, when disconnecting RAID + rebuild target (LP: #1759279) + - md: document lifetime of internal rdev pointer. + + * [Feature]Crystal Ridge:add support for the platform capabilities NFIT sub- + table in ACPI 6.2A (LP: #1730829) + - ACPICA: ACPI 6.0A: Changes to the NFIT ACPI table + - acpi: nfit: Add support for detect platform CPU cache flush on power loss + - acpi: nfit: add persistent memory control flag for nd_region + - libnvdimm: expose platform persistence attribute for nd_region + - libnvdimm: re-enable deep flush for pmem devices via fsync() + - libnvdimm, nfit: fix persistence domain reporting + + * Allow multiple mounts of zfs datasets (LP: #1759848) + - SAUCE: Allow mounting datasets more than once (LP: #1759848) + + * Update Aquantia driver to fix various issues (LP: #1759303) + - net: aquantia: Eliminate AQ_DIMOF, replace with ARRAY_SIZE + - net: aquantia: Cleanup status flags accesses + - net: aquantia: Cleanup hardware access modules + - net: aquantia: Remove duplicate hardware descriptors declarations + - net: aquantia: Add const qualifiers for hardware ops tables + - net: aquantia: Simplify dependencies between pci modules + - net: aquantia: Eliminate aq_nic structure abstraction + - net: aquantia: Fix register definitions to linux style + - net: aquantia: Prepend hw access functions declarations with prefix + - net: aquantia: Fix internal stats calculation on rx + - net: aquantia: Introduce new device ids and constants + - net: aquantia: Introduce new AQC devices and capabilities + - net: aquantia: Convert hw and caps structures to const static pointers + - net: aquantia: Cleanup pci functions module + - net: aquantia: Remove create/destroy from hw ops + - net: aquantia: Change confusing no_ff_addr to more meaningful name + - net: aquantia: Introduce firmware ops callbacks + - net: aquantia: Introduce support for new firmware on AQC cards + - net: aquantia: Introduce global AQC hardware reset sequence + - net: aquantia: Report correct mediatype via ethtool + - net: aquantia: bump driver version to match aquantia internal numbering + - net: aquantia: Fix hardware reset when SPI may rarely hangup + - net: aquantia: Fix a regression with reset on old firmware + - net: aquantia: Change inefficient wait loop on fw data reads + - net: aquantia: Add tx clean budget and valid budget handling logic + - net: aquantia: Allow live mac address changes + - net: aquantia: Implement pci shutdown callback + - net: aquantia: driver version bump + + * ISST-LTE:KVM:Ubuntu1804:BostonLC:boslcp3: cpu hotplug on boslcp3g4 guest + dumping call traces continuously. (LP: #1759722) + - blk-mq: turn WARN_ON in __blk_mq_run_hw_queue into printk + + * ISST-LTE:KVM:Ubuntu18.04:BostonLC:boslcp3:boslcp3g3:Guest conosle hangs + after hotplug CPU add operation. (LP: #1759723) + - genirq/affinity: assign vectors to all possible CPUs + - blk-mq: simplify queue mapping & schedule with each possisble CPU + + * test_bpf fails (LP: #1756150) + - test_bpf: Fix testing with CONFIG_BPF_JIT_ALWAYS_ON=y on other arches + + * Bionic update to v4.15.14 stable release (LP: #1759655) + - MIPS: ralink: Remove ralink_halt() + - MIPS: ralink: Fix booting on MT7621 + - MIPS: lantiq: Fix Danube USB clock + - MIPS: lantiq: Enable AHB Bus for USB + - MIPS: lantiq: ase: Enable MFD_SYSCON + - iio: chemical: ccs811: Corrected firmware boot/application mode transition + - iio: st_pressure: st_accel: pass correct platform data to init + - iio: adc: meson-saradc: unlock on error in meson_sar_adc_lock() + - ALSA: usb-audio: Fix parsing descriptor of UAC2 processing unit + - ALSA: aloop: Sync stale timer before release + - ALSA: aloop: Fix access to not-yet-ready substream via cable + - ALSA: hda - Force polling mode on CFL for fixing codec communication + - ALSA: hda/realtek - Fix speaker no sound after system resume + - ALSA: hda/realtek - Fix Dell headset Mic can't record + - ALSA: hda/realtek - Always immediately update mute LED with pin VREF + - mmc: core: Fix tracepoint print of blk_addr and blksz + - mmc: core: Disable HPI for certain Micron (Numonyx) eMMC cards + - mmc: block: fix updating ext_csd caches on ioctl call + - mmc: dw_mmc: Fix the DTO/CTO timeout overflow calculation for 32-bit systems + - mmc: dw_mmc: exynos: fix the suspend/resume issue for exynos5433 + - mmc: dw_mmc: fix falling from idmac to PIO mode when dw_mci_reset occurs + - PCI: Add function 1 DMA alias quirk for Highpoint RocketRAID 644L + - ahci: Add PCI-id for the Highpoint Rocketraid 644L card + - lockdep: fix fs_reclaim warning + - clk: bcm2835: Fix ana->maskX definitions + - clk: bcm2835: Protect sections updating shared registers + - clk: sunxi-ng: a31: Fix CLK_OUT_* clock ops + - RDMA/mlx5: Fix crash while accessing garbage pointer and freed memory + - Drivers: hv: vmbus: Fix ring buffer signaling + - pinctrl: samsung: Validate alias coming from DT + - Bluetooth: btusb: Remove Yoga 920 from the btusb_needs_reset_resume_table + - Bluetooth: btusb: Add Dell OptiPlex 3060 to btusb_needs_reset_resume_table + - Bluetooth: btusb: Fix quirk for Atheros 1525/QCA6174 + - libata: fix length validation of ATAPI-relayed SCSI commands + - libata: remove WARN() for DMA or PIO command without data + - libata: don't try to pass through NCQ commands to non-NCQ devices + - libata: Apply NOLPM quirk to Crucial MX100 512GB SSDs + - libata: Enable queued TRIM for Samsung SSD 860 + - libata: Apply NOLPM quirk to Crucial M500 480 and 960GB SSDs + - libata: Make Crucial BX100 500GB LPM quirk apply to all firmware versions + - libata: Modify quirks for MX100 to limit NCQ_TRIM quirk to MU01 version + - sched, cgroup: Don't reject lower cpu.max on ancestors + - cgroup: fix rule checking for threaded mode switching + - nfsd: remove blocked locks on client teardown + - media: tegra-cec: reset rx_buf_cnt when start bit detected + - hugetlbfs: check for pgoff value overflow + - h8300: remove extraneous __BIG_ENDIAN definition + - mm/vmalloc: add interfaces to free unmapped page table + - x86/mm: implement free pmd/pte page interfaces + - mm/khugepaged.c: convert VM_BUG_ON() to collapse fail + - mm/thp: do not wait for lock_page() in deferred_split_scan() + - mm/shmem: do not wait for lock_page() in shmem_unused_huge_shrink() + - Revert "mm: page_alloc: skip over regions of invalid pfns where possible" + - drm/vmwgfx: Fix black screen and device errors when running without fbdev + - drm/vmwgfx: Fix a destoy-while-held mutex problem. + - drm/radeon: Don't turn off DP sink when disconnected + - drm/amd/display: We shouldn't set format_default on plane as atomic driver + - drm/amd/display: Add one to EDID's audio channel count when passing to DC + - drm: Reject getfb for multi-plane framebuffers + - drm: udl: Properly check framebuffer mmap offsets + - mm/vmscan: wake up flushers for legacy cgroups too + - module: propagate error in modules_open() + - acpi, numa: fix pxm to online numa node associations + - ACPI / watchdog: Fix off-by-one error at resource assignment + - libnvdimm, {btt, blk}: do integrity setup before add_disk() + - brcmfmac: fix P2P_DEVICE ethernet address generation + - rtlwifi: rtl8723be: Fix loss of signal + - tracing: probeevent: Fix to support minus offset from symbol + - mtdchar: fix usage of mtd_ooblayout_ecc() + - mtd: nand: fsl_ifc: Fix nand waitfunc return value + - mtd: nand: fsl_ifc: Fix eccstat array overflow for IFC ver >= 2.0.0 + - mtd: nand: fsl_ifc: Read ECCSTAT0 and ECCSTAT1 registers for IFC 2.0 + - staging: ncpfs: memory corruption in ncp_read_kernel() + - can: peak/pcie_fd: fix echo_skb is occupied! bug + - can: peak/pcie_fd: remove useless code when interface starts + - can: ifi: Repair the error handling + - can: ifi: Check core revision upon probe + - can: cc770: Fix stalls on rt-linux, remove redundant IRQ ack + - can: cc770: Fix queue stall & dropped RTR reply + - can: cc770: Fix use after free in cc770_tx_interrupt() + - tty: vt: fix up tabstops properly + - x86/entry/64: Don't use IST entry for #BP stack + - selftests/x86/ptrace_syscall: Fix for yet more glibc interference + - x86/vsyscall/64: Use proper accessor to update P4D entry + - x86/efi: Free efi_pgd with free_pages() + - posix-timers: Protect posix clock array access against speculation + - kvm/x86: fix icebp instruction handling + - x86/build/64: Force the linker to use 2MB page size + - x86/boot/64: Verify alignment of the LOAD segment + - hwmon: (k10temp) Only apply temperature offset if result is positive + - hwmon: (k10temp) Add temperature offset for Ryzen 1900X + - perf/x86/intel/uncore: Fix Skylake UPI event format + - perf stat: Fix CVS output format for non-supported counters + - perf/core: Fix ctx_event_type in ctx_resched() + - trace/bpf: remove helper bpf_perf_prog_read_value from tracepoint type + programs + - perf/x86/intel: Don't accidentally clear high bits in bdw_limit_period() + - perf/x86/intel/uncore: Fix multi-domain PCI CHA enumeration bug on Skylake + servers + - iio: ABI: Fix name of timestamp sysfs file + - iio: imu: st_lsm6dsx: fix endianness in st_lsm6dsx_read_oneshot() + - iio: imu: st_lsm6dsx: introduce conf_lock mutex + - staging: android: ion: Zero CMA allocated memory + - kbuild: disable clang's default use of -fmerge-all-constants + - bpf: skip unnecessary capability check + - bpf, x64: increase number of passes + - Linux 4.15.14 + + * System fails to start (boot) on battery due to read-only root file-system + (LP: #1726930) // Bionic update to v4.15.14 stable release (LP: #1759655) + - libata: disable LPM for Crucial BX100 SSD 500GB drive + + * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775) + - thunderbolt: Resume control channel after hibernation image is created + - thunderbolt: Serialize PCIe tunnel creation with PCI rescan + - thunderbolt: Handle connecting device in place of host properly + - thunderbolt: Do not overwrite error code when domain adding fails + - thunderbolt: Wait a bit longer for root switch config space + - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM + - thunderbolt: Handle rejected Thunderbolt devices + - thunderbolt: Factor common ICM add and update operations out + - thunderbolt: Correct function name in kernel-doc comment + - thunderbolt: Add tb_switch_get() + - thunderbolt: Add tb_switch_find_by_route() + - thunderbolt: Add tb_xdomain_find_by_route() + - thunderbolt: Add constant for approval timeout + - thunderbolt: Move driver ready handling to struct icm + - thunderbolt: Add 'boot' attribute for devices + - thunderbolt: Add support for preboot ACL + - Documentation/admin-guide: fixes for thunderbolt.rst + - thunderbolt: Introduce USB only (SL4) security level + - thunderbolt: Add support for Intel Titan Ridge + + * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345) + - ath10k: update the IRAM bank number for QCA9377 + + * nfp: fix disabling on hw-tc-offload in flower (LP: #1752828) + - nfp: bpf: require ETH table + - nfp: don't advertise hw-tc-offload on non-port netdevs + - nfp: forbid disabling hw-tc-offload on representors while offload active + + * Fix an issue that when system in S3, USB keyboard can't wake up the system. + (LP: #1759511) + - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW + + * retpoline hints: primary infrastructure and initial hints (LP: #1758856) + - [Packaging] retpoline -- add safe usage hint support + - [Packaging] retpoline-check -- only report additions + - [Packaging] retpoline -- widen indirect call/jmp detection + - [Packaging] retpoline -- elide %rip relative indirections + - [Packaging] retpoline -- clear hint information from packages + - SAUCE: apm -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: EFI -- annotate indirect calls within + firmware_restrict_branch_speculation_{start,end} + - SAUCE: early/late -- annotate indirect calls in early/late initialisation + code + - SAUCE: vga_set_mode -- avoid jump tables + - [Config] retpoine -- switch to new format + + * zfs system process hung on container stop/delete (LP: #1754584) + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)" + - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584) + + * Important KVM fixes for ppc64el (LP: #1759045) + - KVM: PPC: Book3S HV: Do SLB load/unload with guest LPCR value loaded + - KVM: PPC: Book3S HV: Fix handling of secondary HPTEG in HPT resizing code + - KVM: PPC: Book3S HV: Make HPT resizing work on POWER9 + - KVM: PPC: Book3S: Add MMIO emulation for VMX instructions + - KVM: PPC: Book3S: Fix compile error that occurs with some gcc versions + - KVM: PPC: Book3S HV: Fix trap number return from __kvmppc_vcore_entry + - KVM: PPC: Book3S HV: Fix duplication of host SLB entries + + * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64 + (LP: #1755073) + - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK + + * Update to ocxl driver (LP: #1755161) + - ocxl: fix signed comparison with less than zero + - ocxl: Fix potential bad errno on irq allocation + - ocxl: Add get_metadata IOCTL to share OCXL information to userspace + + * CAPI Flash (cxlflash) update (LP: #1752672) + - scsi: cxlflash: Update cxl-specific arguments to generic cookie + - scsi: cxlflash: Explicitly cache number of interrupts per context + - scsi: cxlflash: Remove embedded CXL work structures + - scsi: cxlflash: Adapter context init can return error + - scsi: cxlflash: Staging to support future accelerators + - SAUCE: cxlflash: Preserve number of interrupts for master contexts + - SAUCE: cxlflash: Avoid clobbering context control register value + - SAUCE: cxlflash: Add argument identifier names + - SAUCE: cxlflash: Introduce OCXL backend + - SAUCE: cxlflash: Hardware AFU for OCXL + - SAUCE: cxlflash: Read host function configuration + - SAUCE: cxlflash: Setup function acTag range + - SAUCE: cxlflash: Read host AFU configuration + - SAUCE: cxlflash: Setup AFU acTag range + - SAUCE: cxlflash: Setup AFU PASID + - SAUCE: cxlflash: Adapter context support for OCXL + - SAUCE: cxlflash: Use IDR to manage adapter contexts + - SAUCE: cxlflash: Support adapter file descriptors for OCXL + - SAUCE: cxlflash: Support adapter context discovery + - SAUCE: cxlflash: Support image reload policy modification + - SAUCE: cxlflash: MMIO map the AFU + - SAUCE: cxlflash: Support starting an adapter context + - SAUCE: cxlflash: Support process specific mappings + - SAUCE: cxlflash: Support AFU state toggling + - SAUCE: cxlflash: Support reading adapter VPD data + - SAUCE: cxlflash: Setup function OCXL link + - SAUCE: cxlflash: Setup OCXL transaction layer + - SAUCE: cxlflash: Support process element lifecycle + - SAUCE: cxlflash: Support AFU interrupt management + - SAUCE: cxlflash: Support AFU interrupt mapping and registration + - SAUCE: cxlflash: Support starting user contexts + - SAUCE: cxlflash: Support adapter context polling + - SAUCE: cxlflash: Support adapter context reading + - SAUCE: cxlflash: Support adapter context mmap and release + - SAUCE: cxlflash: Support file descriptor mapping + - SAUCE: cxlflash: Introduce object handle fop + - SAUCE: cxlflash: Setup LISNs for user contexts + - SAUCE: cxlflash: Setup LISNs for master contexts + - SAUCE: cxlflash: Update synchronous interrupt status bits + - SAUCE: cxlflash: Introduce OCXL context state machine + - SAUCE: cxlflash: Register for translation errors + - SAUCE: cxlflash: Support AFU reset + - SAUCE: cxlflash: Enable OCXL operations + + * [Feature][CFL] Enable pmc_core driver for H, S, and U SKUs (LP: #1730770) + - platform/x86: intel_pmc_core: Remove unused EXPORTED API + - platform/x86: intel_pmc_core: Change driver to a module + - platform/x86: intel_pmc_core: Fix file permission warnings + - platform/x86: intel_pmc_core: Refactor debugfs entries + - platform/x86: intel_pmc_core: Substitute PCI with CPUID enumeration + - platform/x86: intel_pmc_core: Convert to ICPU macro + - platform/x86: intel_pmc_core: Remove unused header file + - ACPI / LPIT: Export lpit_read_residency_count_address() + - platform/x86: intel_pmc_core: Read base address from LPIT + - x86/cpu: Add Cannonlake to Intel family + - platform/x86: intel_pmc_core: Add CannonLake PCH support + - platform/x86: intel_pmc_core: Special case for Coffeelake + + * Cpu utilization showing system time for kvm guests (performance) (sysstat) + (LP: #1755979) + - KVM: PPC: Book3S HV: Fix guest time accounting with VIRT_CPU_ACCOUNTING_GEN + + * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core + (LP: #1736393) + - SAUCE: drm/i915:Don't set chip specific data + - SAUCE: drm/i915: make previous commit affects Wyse 3040 only + + * [Bug] ISH support for CFL-H (LP: #1739522) + - HID: intel-ish-hid: Enable Cannon Lake and Coffee Lake laptop/desktop + + * ath9k can't connect to wifi AP (LP: #1727228) + - ath9k: add MSI support + - ath9k: add a quirk to set use_msi automatically + + * [P9,Power NV][Witherspoon][Ubuntu 18.04][Perf] : PMU events by name it is + not listed under perf list (LP: #1755470) + - iperf vendor events: Use more flexible pattern matching for CPU + identification for mapfile.csv + + * zed process consuming 100% cpu (LP: #1751796) + - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796) + + * Bionic update to 4.15.13 stable release (LP: #1758886) + - scsi: megaraid_sas: Do not use 32-bit atomic request descriptor for Ventura + controllers + - staging: android: ashmem: Fix possible deadlock in ashmem_ioctl + - drm/amdgpu: use polling mem to set SDMA3 wptr for VF + - Bluetooth: hci_qca: Avoid setup failure on missing rampatch + - Bluetooth: btqcomsmd: Fix skb double free corruption + - cpufreq: longhaul: Revert transition_delay_us to 200 ms + - media: c8sectpfe: fix potential NULL pointer dereference in + c8sectpfe_timer_interrupt + - drm/msm: fix leak in failed get_pages + - IB/ipoib: Warn when one port fails to initialize + - RDMA/iwpm: Fix uninitialized error code in iwpm_send_mapinfo() + - hv_netvsc: Fix the receive buffer size limit + - hv_netvsc: Fix the TX/RX buffer default sizes + - tcp: allow TLP in ECN CWR + - spi: sh-msiof: Avoid writing to registers from spi_master.setup() + - libbpf: prefer global symbols as bpf program name source + - rtlwifi: rtl_pci: Fix the bug when inactiveps is enabled. + - rtlwifi: always initialize variables given to RT_TRACE() + - media: bt8xx: Fix err 'bt878_probe()' + - ath10k: handling qos at STA side based on AP WMM enable/disable + - media: [RESEND] media: dvb-frontends: Add delay to Si2168 restart + - qmi_wwan: set FLAG_SEND_ZLP to avoid network initiated disconnect + - tty: goldfish: Enable 'earlycon' only if built-in + - serial: 8250_dw: Disable clock on error + - cros_ec: fix nul-termination for firmware build info + - watchdog: Fix potential kref imbalance when opening watchdog + - watchdog: Fix kref imbalance seen if handle_boot_enabled=0 + - platform/chrome: Use proper protocol transfer function + - dmaengine: zynqmp_dma: Fix race condition in the probe + - drm/tilcdc: ensure nonatomic iowrite64 is not used + - mmc: avoid removing non-removable hosts during suspend + - mmc: block: fix logical error to avoid memory leak + - /dev/mem: Add bounce buffer for copy-out + - net: phy: meson-gxl: check phy_write return value + - sfp: fix EEPROM reading in the case of non-SFF8472 SFPs + - sfp: fix non-detection of PHY + - media: s5p-mfc: Fix lock contention - request_firmware() once + - rtc: ac100: Fix multiple race conditions + - IB/ipoib: Avoid memory leak if the SA returns a different DGID + - RDMA/cma: Use correct size when writing netlink stats + - IB/umem: Fix use of npages/nmap fields + - iser-target: avoid reinitializing rdma contexts for isert commands + - bpf/cgroup: fix a verification error for a CGROUP_DEVICE type prog + - vgacon: Set VGA struct resource types + - omapdrm: panel: fix compatible vendor string for td028ttec1 + - mmc: sdhci-xenon: wait 5ms after set 1.8V signal enable + - drm/omap: DMM: Check for DMM readiness after successful transaction commit + - pty: cancel pty slave port buf's work in tty_release + - coresight: Fix disabling of CoreSight TPIU + - PCI: designware-ep: Fix ->get_msi() to check MSI_EN bit + - PCI: endpoint: Fix find_first_zero_bit() usage + - PCI: rcar: Handle rcar_pcie_parse_request_of_pci_ranges() failures + - media: davinci: fix a debug printk + - clk: check ops pointer on clock register + - dt-bindings: display: panel: Fix compatible string for Toshiba LT089AC29000 + - clk: use round rate to bail out early in set_rate + - pinctrl: Really force states during suspend/resume + - pinctrl: rockchip: enable clock when reading pin direction register + - iommu/vt-d: clean up pr_irq if request_threaded_irq fails + - ip6_vti: adjust vti mtu according to mtu of lower device + - ip_gre: fix error path when erspan_rcv failed + - ip_gre: fix potential memory leak in erspan_rcv + - soc: qcom: smsm: fix child-node lookup + - RDMA/ocrdma: Fix permissions for OCRDMA_RESET_STATS + - ARM: dts: aspeed-evb: Add unit name to memory node + - nfsd4: permit layoutget of executable-only files + - clk: at91: pmc: Wait for clocks when resuming + - clk: Don't touch hardware when reparenting during registration + - clk: axi-clkgen: Correctly handle nocount bit in recalc_rate() + - clk: si5351: Rename internal plls to avoid name collisions + - crypto: artpec6 - set correct iv size for gcm(aes) + - hwrng: core - Clean up RNG list when last hwrng is unregistered + - dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63 + - IB/mlx5: Fix integer overflows in mlx5_ib_create_srq + - IB/mlx5: Fix out-of-bounds read in create_raw_packet_qp_rq + - RDMA/vmw_pvrdma: Fix usage of user response structures in ABI file + - serial: 8250_pci: Don't fail on multiport card class + - RDMA/core: Do not use invalid destination in determining port reuse + - clk: migrate the count of orphaned clocks at init + - RDMA/ucma: Fix access to non-initialized CM_ID object + - RDMA/ucma: Don't allow join attempts for unsupported AF family + - Linux 4.15.13 + + * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to + "always" (LP: #1753708) + - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el + + * Bionic update to 4.15.12 stable release (LP: #1757465) + - x86/cpufeatures: Add Intel Total Memory Encryption cpufeature + - x86/cpufeatures: Add Intel PCONFIG cpufeature + - selftests/x86/entry_from_vm86: Exit with 1 if we fail + - selftests/x86/entry_from_vm86: Add test cases for POPF + - x86/vm86/32: Fix POPF emulation + - x86/speculation, objtool: Annotate indirect calls/jumps for objtool on + 32-bit kernels + - x86/speculation: Remove Skylake C2 from Speculation Control microcode + blacklist + - KVM: x86: Fix device passthrough when SME is active + - x86/mm: Fix vmalloc_fault to use pXd_large + - parisc: Handle case where flush_cache_range is called with no context + - ALSA: pcm: Fix UAF in snd_pcm_oss_get_formats() + - ALSA: hda - Revert power_save option default value + - ALSA: seq: Fix possible UAF in snd_seq_check_queue() + - ALSA: seq: Clear client entry before deleting else at closing + - drm/nouveau/bl: Fix oops on driver unbind + - drm/nouveau/mmu: ALIGN_DOWN correct variable + - drm/amdgpu: fix prime teardown order + - drm/radeon: fix prime teardown order + - drm/amdgpu/dce: Don't turn off DP sink when disconnected + - fs: Teach path_connected to handle nfs filesystems with multiple roots. + - KVM: arm/arm64: Reduce verbosity of KVM init log + - KVM: arm/arm64: Reset mapped IRQs on VM reset + - kvm: arm/arm64: vgic-v3: Tighten synchronization for guests using v2 on v3 + - KVM: arm/arm64: vgic: Don't populate multiple LRs with the same vintid + - lock_parent() needs to recheck if dentry got __dentry_kill'ed under it + - fs/aio: Add explicit RCU grace period when freeing kioctx + - fs/aio: Use RCU accessors for kioctx_table->table[] + - RDMAVT: Fix synchronization around percpu_ref + - irqchip/gic-v3-its: Ensure nr_ites >= nr_lpis + - nvme: fix subsystem multiple controllers support check + - xfs: preserve i_rdev when recycling a reclaimable inode + - btrfs: Fix NULL pointer exception in find_bio_stripe + - btrfs: add missing initialization in btrfs_check_shared + - btrfs: alloc_chunk: fix DUP stripe size handling + - btrfs: Fix use-after-free when cleaning up fs_devs with a single stale + device + - btrfs: remove spurious WARN_ON(ref->count < 0) in find_parent_nodes + - btrfs: Fix memory barriers usage with device stats counters + - scsi: qla2xxx: Fix smatch warning in qla25xx_delete_{rsp|req}_que + - scsi: qla2xxx: Fix NULL pointer access for fcport structure + - scsi: qla2xxx: Fix logo flag for qlt_free_session_done() + - scsi: qla2xxx: Fix crashes in qla2x00_probe_one on probe failure + - usb: dwc2: fix STM32F7 USB OTG HS compatible + - dt-bindings: usb: fix the STM32F7 DWC2 OTG HS core binding + - USB: gadget: udc: Add missing platform_device_put() on error in + bdc_pci_probe() + - usb: dwc3: Fix GDBGFIFOSPACE_TYPE values + - usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode + - usb: dwc3: of-simple: fix oops by unbalanced clk disable call + - usb: gadget: udc: renesas_usb3: fix oops in renesas_usb3_remove() + - phy: phy-brcm-usb: Fix two DT properties to match bindings doc + - phy: phy-brcm-usb-init: Some Low Speed keyboards fail on 7271 + - phy: phy-brcm-usb-init: DRD mode can cause crash on startup + - phy: phy-brcm-usb-init: Power down USB 3.0 PHY when XHCI disabled + - Linux 4.15.12 + + * cxl: Fix timebase synchronization status on POWER9 missing (CAPI) + (LP: #1757228) + - cxl: Fix timebase synchronization status on P9 + + * [Feature][GLK] Enable L2 CDP (Code and Data Prioritization) (LP: #1737873) + - x86/intel_rdt: Enumerate L2 Code and Data Prioritization (CDP) feature + - x86/intel_rdt: Add command line parameter to control L2_CDP + + * [Feature] Crystal Ridge-Restrict DAX to configurations with struct page + (LP: #1751724) + - mm, dax: introduce pfn_t_special() + - ext2: auto disable dax instead of failing mount + - ext4: auto disable dax instead of failing mount + - dax: require 'struct page' by default for filesystem dax + - Config: Enable CONFIG_FS_DAX_LIMITED + + * Bionic update to 4.15.11 stable release (LP: #1756978) + - x86: Treat R_X86_64_PLT32 as R_X86_64_PC32 + - ASoC: sun4i-i2s: Fix RX slot number of SUN8I + - ASoC: sgtl5000: Fix suspend/resume + - ASoC: wm_adsp: For TLV controls only register TLV get/set + - ASoC: rt5651: Fix regcache sync errors on resume + - usb: host: xhci-rcar: add support for r8a77965 + - xhci: Fix front USB ports on ASUS PRIME B350M-A + - xhci: fix endpoint context tracer output + - serial: sh-sci: prevent lockup on full TTY buffers + - tty/serial: atmel: add new version check for usart + - uas: fix comparison for error code + - staging: comedi: fix comedi_nsamples_left. + - staging: android: ashmem: Fix lockdep issue during llseek + - scsi: sd_zbc: Fix potential memory leak + - USB: storage: Add JMicron bridge 152d:2567 to unusual_devs.h + - usbip: vudc: fix null pointer dereference on udc->lock + - usb: quirks: add control message delay for 1b1c:1b20 + - usb: usbmon: Read text within supplied buffer size + - usb: gadget: f_fs: Fix use-after-free in ffs_fs_kill_sb() + - usb: dwc3: Fix lock-up on ID change during system suspend/resume + - serial: 8250_pci: Add Brainboxes UC-260 4 port serial device + - serial: core: mark port as initialized in autoconfig + - earlycon: add reg-offset to physical address before mapping + - dm mpath: fix passing integrity data + - Revert "btrfs: use proper endianness accessors for super_copy" + - gfs2: Clean up {lookup,fillup}_metapath + - gfs2: Fixes to "Implement iomap for block_map" (2) + - drm/panel: rpi-touchscreen: propagate errors in rpi_touchscreen_i2c_read() + - spi: imx: Fix failure path leak on GPIO request error correctly + - HID: multitouch: Only look at non touch fields in first packet of a frame + - KVM: PPC: Book3S HV: Avoid shifts by negative amounts + - drm/edid: set ELD connector type in drm_edid_to_eld() + - dma-buf/fence: Fix lock inversion within dma-fence-array + - video/hdmi: Allow "empty" HDMI infoframes + - KVM: PPC: Book3S HV: Fix typo in kvmppc_hv_get_dirty_log_radix() + - HID: elo: clear BTN_LEFT mapping + - iwlwifi: mvm: rs: don't override the rate history in the search cycle + - ARM: dts: koelsch: Move cec_clock to root node + - clk: meson: gxbb: fix wrong clock for SARADC/SANA + - ARM: dts: exynos: Correct Trats2 panel reset line + - drm/amdgpu: fix get_max_engine_clock_in_mhz + - staging: rtl8822be: fix missing null check on dev_alloc_skb return + - typec: tcpm: fusb302: Resolve out of order messaging events + - USB: ledtrig-usbport: fix of-node leak + - dt-bindings: serial: Add common rs485 binding for RTS polarity + - sched: Stop switched_to_rt() from sending IPIs to offline CPUs + - sched: Stop resched_cpu() from sending IPIs to offline CPUs + - crypto: chelsio - Fix an error code in chcr_hash_dma_map() + - crypto: ecc - Fix NULL pointer deref. on no default_rng + - crypto: keywrap - Add missing ULL suffixes for 64-bit constants + - crypto: cavium - fix memory leak on info + - test_firmware: fix setting old custom fw path back on exit + - drm/vblank: Fix vblank timestamp debugs + - net: ieee802154: adf7242: Fix bug if defined DEBUG + - rtc: brcmstb-waketimer: fix error handling in brcmstb_waketmr_probe() + - perf report: Fix -D output for user metadata events + - net: xfrm: allow clearing socket xfrm policies. + - gpiolib: don't allow OPEN_DRAIN & OPEN_SOURCE flags simultaneously + - mtd: nand: fix interpretation of NAND_CMD_NONE in nand_command[_lp]() + - net: thunderx: Set max queue count taking XDP_TX into account + - ARM: dts: am335x-pepper: Fix the audio CODEC's reset pin + - ARM: dts: omap3-n900: Fix the audio CODEC's reset pin + - mtd: nand: ifc: update bufnum mask for ver >= 2.0.0 + - userns: Don't fail follow_automount based on s_user_ns + - xfrm: Fix xfrm_replay_overflow_offload_esn + - leds: pm8058: Silence pointer to integer size warning + - bpf: fix stack state printing in verifier log + - power: supply: sbs-message: double left shift bug in sbsm_select() + - power: supply: ab8500_charger: Fix an error handling path + - power: supply: ab8500_charger: Bail out in case of error in + 'ab8500_charger_init_hw_registers()' + - drm/etnaviv: make THERMAL selectable + - iio: adc: ina2xx: Shift bus voltage register to mask flag bits + - iio: health: max30102: Add power enable parameter to get_temp function + - ath10k: update tdls teardown state to target + - cpufreq: Fix governor module removal race + - KVM: X86: Restart the guest when insn_len is zero and SEV is enabled + - drm/amdgpu:fix random missing of FLR NOTIFY + - scsi: ses: don't ask for diagnostic pages repeatedly during probe + - pwm: stmpe: Fix wrong register offset for hwpwm=2 case + - drm/sun4i: Fix format mask in DE2 driver + - pinctrl: sh-pfc: r8a7791: Add can_clk function + - pinctrl: sh-pfc: r8a7795-es1: Fix MOD_SEL1 bit[25:24] to 0x3 when using + STP_ISEN_1_D + - perf annotate: Fix unnecessary memory allocation for s390x + - perf annotate: Fix objdump comment parsing for Intel mov dissassembly + - iwlwifi: mvm: avoid dumping assert log when device is stopped + - drm/amdgpu:fix virtual dce bug + - drm/amdgpu: fix amdgpu_sync_resv v2 + - bnxt_en: Uninitialized variable in bnxt_tc_parse_actions() + - clk: qcom: msm8916: fix mnd_width for codec_digcodec + - mwifiex: cfg80211: do not change virtual interface during scan processing + - ath10k: fix invalid STS_CAP_OFFSET_MASK + - tools/usbip: fixes build with musl libc toolchain + - spi: sun6i: disable/unprepare clocks on remove + - bnxt_en: Don't print "Link speed -1 no longer supported" messages. + - scsi: core: scsi_get_device_flags_keyed(): Always return device flags + - scsi: devinfo: apply to HP XP the same flags as Hitachi VSP + - scsi: dh: add new rdac devices + - clk: renesas: r8a77970: Add LVDS clock + - staging: fsl-dpaa2/eth: Fix access to FAS field + - media: vsp1: Prevent suspending and resuming DRM pipelines + - dm raid: fix raid set size revalidation + - media: cpia2: Fix a couple off by one bugs + - media: davinci: vpif_capture: add NULL check on devm_kzalloc return value + - virtio_net: Disable interrupts if napi_complete_done rescheduled napi + - net: sched: drop qdisc_reset from dev_graft_qdisc + - veth: set peer GSO values + - drm/amdkfd: Fix memory leaks in kfd topology + - powerpc/64: Don't trace irqs-off at interrupt return to soft-disabled + context + - arm64: dts: renesas: salvator-common: Add EthernetAVB PHY reset + - agp/intel: Flush all chipset writes after updating the GGTT + - mac80211_hwsim: enforce PS_MANUAL_POLL to be set after PS_ENABLED + - mac80211: remove BUG() when interface type is invalid + - crypto: caam/qi - use correct print specifier for size_t + - ASoC: nuc900: Fix a loop timeout test + - mmc: mmc_test: Ensure command queue is disabled for testing + - Fix misannotated out-of-line _copy_to_user() + - ipvlan: add L2 check for packets arriving via virtual devices + - rcutorture/configinit: Fix build directory error message + - locking/locktorture: Fix num reader/writer corner cases + - ima: relax requiring a file signature for new files with zero length + - IB/mlx5: revisit -Wmaybe-uninitialized warning + - dmaengine: qcom_hidma: check pending interrupts + - drm/i915/glk: Disable Guc and HuC on GLK + - Linux 4.15.11 + - Config: Enable CONFIG_DRM_ETNAVIV_THERMAL=y + + * [FFE][Feature] KVM CLX avx512_vnni (LP: #1739665) + - KVM: x86: add support for UMIP + - KVM: Expose new cpu features to guest + + * Ubuntu18.04[P9 DD2.2 Boston]:Unable to boot power8 compat mode + guests(ubuntu14.04.5) (kvm) (LP: #1756254) + - KVM: PPC: Book3S HV: Allow HPT and radix on the same core for POWER9 v2.2 + + * Allow hugepage backing for "p8compat" mode kvm guests (LP: #1754206) + - KVM: PPC: Book3S HV: Fix VRMA initialization with 2MB or 1GB memory backing + + * [Bug][KVM][Crystal Ridge] Terrible performance of vNVDIMM on QEMU with + device DAX backend (LP: #1745899) + - x86/mm: add a function to check if a pfn is UC/UC-/WC + - KVM: MMU: consider host cache mode in MMIO page check + + * nfp: read ME frequency from vNIC ctrl memory (LP: #1752818) + - nfp: add TLV capabilities to the BAR + - nfp: read ME frequency from vNIC ctrl memory + - nfp: fix TLV offset calculation + + * Miscellaneous Ubuntu changes + - [Packaging] skip cloud tools packaging when not building package + - [Packaging] final-checks -- remove check for empty retpoline files + + -- Thadeu Lima de Souza Cascardo Mon, 02 Apr 2018 15:43:20 -0300 + +linux (4.15.0-13.14) bionic; urgency=medium + + * linux: 4.15.0-13.14 -proposed tracker (LP: #1756408) + + * devpts: handle bind-mounts (LP: #1755857) + - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC + - SAUCE: devpts: resolve devpts bind-mounts + - SAUCE: devpts: comment devpts_mntget() + - SAUCE: selftests: add devpts selftests + + * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103) + - d-i: add hisi_sas_v3_hw to scsi-modules + + * [Bionic][ARM64] enable ROCE and HNS3 driver support for hip08 SoC + (LP: #1756097) + - RDMA/hns: Refactor eq code for hip06 + - RDMA/hns: Add eq support of hip08 + - RDMA/hns: Add detailed comments for mb() call + - RDMA/hns: Add rq inline data support for hip08 RoCE + - RDMA/hns: Update the usage of sr_max and rr_max field + - RDMA/hns: Set access flags of hip08 RoCE + - RDMA/hns: Filter for zero length of sge in hip08 kernel mode + - RDMA/hns: Fix QP state judgement before sending work requests + - RDMA/hns: Assign dest_qp when deregistering mr + - RDMA/hns: Fix endian problems around imm_data and rkey + - RDMA/hns: Assign the correct value for tx_cqn + - RDMA/hns: Create gsi qp in hip08 + - RDMA/hns: Add gsi qp support for modifying qp in hip08 + - RDMA/hns: Fill sq wqe context of ud type in hip08 + - RDMA/hns: Assign zero for pkey_index of wc in hip08 + - RDMA/hns: Update the verbs of polling for completion + - RDMA/hns: Set the guid for hip08 RoCE device + - net: hns3: Refactor of the reset interrupt handling logic + - net: hns3: Add reset service task for handling reset requests + - net: hns3: Refactors the requested reset & pending reset handling code + - net: hns3: Add HNS3 VF IMP(Integrated Management Proc) cmd interface + - net: hns3: Add mailbox support to VF driver + - net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support + - net: hns3: Add HNS3 VF driver to kernel build framework + - net: hns3: Unified HNS3 {VF|PF} Ethernet Driver for hip08 SoC + - net: hns3: Add mailbox support to PF driver + - net: hns3: Change PF to add ring-vect binding & resetQ to mailbox + - net: hns3: Add mailbox interrupt handling to PF driver + - net: hns3: add support to query tqps number + - net: hns3: add support to modify tqps number + - net: hns3: change the returned tqp number by ethtool -x + - net: hns3: free the ring_data structrue when change tqps + - net: hns3: get rss_size_max from configuration but not hardcode + - net: hns3: add a mask initialization for mac_vlan table + - net: hns3: add vlan offload config command + - net: hns3: add ethtool related offload command + - net: hns3: add handling vlan tag offload in bd + - net: hns3: cleanup mac auto-negotiation state query + - net: hns3: fix for getting auto-negotiation state in hclge_get_autoneg + - net: hns3: add support for set_pauseparam + - net: hns3: add support to update flow control settings after autoneg + - net: hns3: add Asym Pause support to phy default features + - net: hns3: add support for querying advertised pause frame by ethtool ethx + - net: hns3: Increase the default depth of bucket for TM shaper + - net: hns3: change TM sched mode to TC-based mode when SRIOV enabled + - net: hns3: hns3_get_channels() can be static + - net: hns3: Add ethtool interface for vlan filter + - net: hns3: Disable VFs change rxvlan offload status + - net: hns3: Unify the strings display of packet statistics + - net: hns3: Fix spelling errors + - net: hns3: Remove repeat statistic of rx_errors + - net: hns3: Modify the update period of packet statistics + - net: hns3: Mask the packet statistics query when NIC is down + - net: hns3: Fix an error of total drop packet statistics + - net: hns3: Fix a loop index error of tqp statistics query + - net: hns3: Fix an error macro definition of HNS3_TQP_STAT + - net: hns3: Remove a useless member of struct hns3_stats + - net: hns3: Add packet statistics of netdev + - net: hns3: Fix a response data read error of tqp statistics query + - net: hns3: fix for updating fc_mode_last_time + - net: hns3: fix for setting MTU + - net: hns3: fix for changing MTU + - net: hns3: add MTU initialization for hardware + - net: hns3: fix for not setting pause parameters + - net: hns3: remove redundant semicolon + - net: hns3: Add more packet size statisctics + - Revert "net: hns3: Add packet statistics of netdev" + - net: hns3: report the function type the same line with hns3_nic_get_stats64 + - net: hns3: add ethtool_ops.get_channels support for VF + - net: hns3: remove TSO config command from VF driver + - net: hns3: add ethtool_ops.get_coalesce support to PF + - net: hns3: add ethtool_ops.set_coalesce support to PF + - net: hns3: refactor interrupt coalescing init function + - net: hns3: refactor GL update function + - net: hns3: remove unused GL setup function + - net: hns3: change the unit of GL value macro + - net: hns3: add int_gl_idx setup for TX and RX queues + - net: hns3: add feature check when feature changed + - net: hns3: check for NULL function pointer in hns3_nic_set_features + - net: hns: Fix for variable may be used uninitialized warnings + - net: hns3: add support for get_regs + - net: hns3: add manager table initialization for hardware + - net: hns3: add ethtool -p support for fiber port + - net: hns3: add net status led support for fiber port + - net: hns3: converting spaces into tabs to avoid checkpatch.pl warning + - net: hns3: add get/set_coalesce support to VF + - net: hns3: add int_gl_idx setup for VF + - [Config]: enable CONFIG_HNS3_HCLGEVF as module. + + * [Bionic][ARM64] add RAS extension and SDEI features (LP: #1756096) + - KVM: arm64: Store vcpu on the stack during __guest_enter() + - KVM: arm/arm64: Convert kvm_host_cpu_state to a static per-cpu allocation + - KVM: arm64: Change hyp_panic()s dependency on tpidr_el2 + - arm64: alternatives: use tpidr_el2 on VHE hosts + - KVM: arm64: Stop save/restoring host tpidr_el1 on VHE + - Docs: dt: add devicetree binding for describing arm64 SDEI firmware + - firmware: arm_sdei: Add driver for Software Delegated Exceptions + - arm64: Add vmap_stack header file + - arm64: uaccess: Add PAN helper + - arm64: kernel: Add arch-specific SDEI entry code and CPU masking + - firmware: arm_sdei: Add support for CPU and system power states + - firmware: arm_sdei: add support for CPU private events + - arm64: acpi: Remove __init from acpi_psci_use_hvc() for use by SDEI + - firmware: arm_sdei: Discover SDEI support via ACPI + - arm64: sysreg: Move to use definitions for all the SCTLR bits + - arm64: cpufeature: Detect CPU RAS Extentions + - arm64: kernel: Survive corrected RAS errors notified by SError + - arm64: Unconditionally enable IESB on exception entry/return for firmware- + first + - arm64: kernel: Prepare for a DISR user + - KVM: arm/arm64: mask/unmask daif around VHE guests + - KVM: arm64: Set an impdef ESR for Virtual-SError using VSESR_EL2. + - KVM: arm64: Save/Restore guest DISR_EL1 + - KVM: arm64: Save ESR_EL2 on guest SError + - KVM: arm64: Handle RAS SErrors from EL1 on guest exit + - KVM: arm64: Handle RAS SErrors from EL2 on guest exit + - KVM: arm64: Emulate RAS error registers and set HCR_EL2's TERR & TEA + - [Config]: enable RAS_EXTN and ARM_SDE_INTERFACE + + * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094) + - scsi: hisi_sas: fix dma_unmap_sg() parameter + - scsi: ata: enhance the definition of SET MAX feature field value + - scsi: hisi_sas: relocate clearing ITCT and freeing device + - scsi: hisi_sas: optimise port id refresh function + - scsi: hisi_sas: some optimizations of host controller reset + - scsi: hisi_sas: modify hisi_sas_dev_gone() for reset + - scsi: hisi_sas: add an mechanism to do reset work synchronously + - scsi: hisi_sas: change ncq process for v3 hw + - scsi: hisi_sas: add RAS feature for v3 hw + - scsi: hisi_sas: add some print to enhance debugging + - scsi: hisi_sas: improve int_chnl_int_v2_hw() consistency with v3 hw + - scsi: hisi_sas: add v2 hw port AXI error handling support + - scsi: hisi_sas: use an general way to delay PHY work + - scsi: hisi_sas: do link reset for some CHL_INT2 ints + - scsi: hisi_sas: judge result of internal abort + - scsi: hisi_sas: add internal abort dev in some places + - scsi: hisi_sas: fix SAS_QUEUE_FULL problem while running IO + - scsi: hisi_sas: re-add the lldd_port_deformed() + - scsi: hisi_sas: add v3 hw suspend and resume + - scsi: hisi_sas: Change frame type for SET MAX commands + - scsi: hisi_sas: make local symbol host_attrs static + - scsi: hisi_sas: fix a bug in hisi_sas_dev_gone() + - SAUCE: scsi: hisi_sas: config for hip08 ES + - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace + - PM / core: Add LEAVE_SUSPENDED driver flag + - PCI / PM: Support for LEAVE_SUSPENDED driver flag + - PCI/AER: Skip recovery callbacks for correctable errors from ACPI APEI + - PCI/ASPM: Calculate LTR_L1.2_THRESHOLD from device characteristics + - PCI/ASPM: Enable Latency Tolerance Reporting when supported + - PCI/ASPM: Unexport internal ASPM interfaces + - PCI: Make PCI_SCAN_ALL_PCIE_DEVS work for Root as well as Downstream Ports + - PCI/AER: Return error if AER is not supported + - PCI/DPC: Enable DPC only if AER is available + + * [CVE] Spectre: System Z {kernel} UBUNTU18.04 (LP: #1754580) + - s390: scrub registers on kernel entry and KVM exit + - s390: add optimized array_index_mask_nospec + - s390/alternative: use a copy of the facility bit mask + - s390: add options to change branch prediction behaviour for the kernel + - s390: run user space and KVM guests with modified branch prediction + - s390: introduce execute-trampolines for branches + - s390: Replace IS_ENABLED(EXPOLINE_*) with IS_ENABLED(CONFIG_EXPOLINE_*) + - s390: do not bypass BPENTER for interrupt system calls + - s390/entry.S: fix spurious zeroing of r0 + + * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424) + - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove. + + * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug + fixes (LP: #1752182) + - scsi: lpfc: FLOGI failures are reported when connected to a private loop. + - scsi: lpfc: Expand WQE capability of every NVME hardware queue + - scsi: lpfc: Handle XRI_ABORTED_CQE in soft IRQ + - scsi: lpfc: Fix NVME LS abort_xri + - scsi: lpfc: Raise maximum NVME sg list size for 256 elements + - scsi: lpfc: Driver fails to detect direct attach storage array + - scsi: lpfc: Fix display for debugfs queInfo + - scsi: lpfc: Adjust default value of lpfc_nvmet_mrq + - scsi: lpfc: Fix ndlp ref count for pt2pt mode issue RSCN + - scsi: lpfc: Linux LPFC driver does not process all RSCNs + - scsi: lpfc: correct port registrations with nvme_fc + - scsi: lpfc: Correct driver deregistrations with host nvme transport + - scsi: lpfc: Fix crash during driver unload with running nvme traffic + - scsi: lpfc: Fix driver handling of nvme resources during unload + - scsi: lpfc: small sg cnt cleanup + - scsi: lpfc: Fix random heartbeat timeouts during heavy IO + - scsi: lpfc: update driver version to 11.4.0.5 + - scsi: lpfc: Fix -EOVERFLOW behavior for NVMET and defer_rcv + - scsi: lpfc: Fix receive PRLI handling + - scsi: lpfc: Increase SCSI CQ and WQ sizes. + - scsi: lpfc: Fix SCSI LUN discovery when SCSI and NVME enabled + - scsi: lpfc: Fix issues connecting with nvme initiator + - scsi: lpfc: Fix infinite wait when driver unregisters a remote NVME port. + - scsi: lpfc: Beef up stat counters for debug + - scsi: lpfc: update driver version to 11.4.0.6 + - scsi: lpfc: correct sg_seg_cnt attribute min vs default + - scsi: scsi_transport_fc: fix typos on 64/128 GBit define names + - scsi: lpfc: don't dereference localport before it has been null checked + - scsi: lpfc: fix a couple of minor indentation issues + - treewide: Use DEVICE_ATTR_RW + - treewide: Use DEVICE_ATTR_RO + - treewide: Use DEVICE_ATTR_WO + - scsi: lpfc: Fix frequency of Release WQE CQEs + - scsi: lpfc: Increase CQ and WQ sizes for SCSI + - scsi: lpfc: move placement of target destroy on driver detach + - scsi: lpfc: correct debug counters for abort + - scsi: lpfc: Add WQ Full Logic for NVME Target + - scsi: lpfc: Fix PRLI handling when topology type changes + - scsi: lpfc: Fix IO failure during hba reset testing with nvme io. + - scsi: lpfc: Fix RQ empty firmware trap + - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target + - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing + - scsi: lpfc: Fix issue_lip if link is disabled + - scsi: lpfc: Indicate CONF support in NVMe PRLI + - scsi: lpfc: Fix SCSI io host reset causing kernel crash + - scsi: lpfc: Validate adapter support for SRIU option + - scsi: lpfc: Fix header inclusion in lpfc_nvmet + - scsi: lpfc: Treat SCSI Write operation Underruns as an error + - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap. + - scsi: lpfc: update driver version to 11.4.0.7 + - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright + - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers + - scsi: lpfc: Rework sli4 doorbell infrastructure + - scsi: lpfc: Add SLI-4 if_type=6 support to the code base + - scsi: lpfc: Add push-to-adapter support to sli4 + - scsi: lpfc: Add PCI Ids for if_type=6 hardware + - scsi: lpfc: Add 64G link speed support + - scsi: lpfc: Add if_type=6 support for cycling valid bits + - scsi: lpfc: Enable fw download on if_type=6 devices + - scsi: lpfc: Add embedded data pointers for enhanced performance + - scsi: lpfc: Fix nvme embedded io length on new hardware + - scsi: lpfc: Work around NVME cmd iu SGL type + - scsi: lpfc: update driver version to 12.0.0.0 + - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018 + - scsi: lpfc: use __raw_writeX on DPP copies + - scsi: lpfc: Add missing unlock in WQ full logic + + * CVE-2018-8043 + - net: phy: mdio-bcm-unimac: fix potential NULL dereference in + unimac_mdio_probe() + + * Bionic update to 4.15.10 stable release (LP: #1756100) + - Revert "UBUNTU: SAUCE: ALSA: hda/realtek - Add support headset mode for DELL + WYSE" + - RDMA/ucma: Limit possible option size + - RDMA/ucma: Check that user doesn't overflow QP state + - RDMA/mlx5: Fix integer overflow while resizing CQ + - bpf: cpumap: use GFP_KERNEL instead of GFP_ATOMIC in __cpu_map_entry_alloc() + - IB/uverbs: Improve lockdep_check + - mac80211_hwsim: don't use WQ_MEM_RECLAIM + - net/smc: fix NULL pointer dereference on sock_create_kern() error path + - regulator: stm32-vrefbuf: fix check on ready flag + - drm/i915: Check for fused or unused pipes + - drm/i915/audio: fix check for av_enc_map overflow + - drm/i915: Fix rsvd2 mask when out-fence is returned + - drm/i915: Clear the in-use marker on execbuf failure + - drm/i915: Disable DC states around GMBUS on GLK + - drm/i915: Update watermark state correctly in sanitize_watermarks + - drm/i915: Try EDID bitbanging on HDMI after failed read + - drm/i915/perf: fix perf stream opening lock + - scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops + - scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS + - drm/i915: Always call to intel_display_set_init_power() in resume_early. + - workqueue: Allow retrieval of current task's work struct + - drm: Allow determining if current task is output poll worker + - drm/nouveau: Fix deadlock on runtime suspend + - drm/radeon: Fix deadlock on runtime suspend + - drm/amdgpu: Fix deadlock on runtime suspend + - drm/nouveau: prefer XBGR2101010 for addfb ioctl + - drm/amd/powerplay/smu7: allow mclk switching with no displays + - drm/amd/powerplay/vega10: allow mclk switching with no displays + - Revert "drm/radeon/pm: autoswitch power state when in balanced mode" + - drm/amd/display: check for ipp before calling cursor operations + - drm/radeon: insist on 32-bit DMA for Cedar on PPC64/PPC64LE + - drm/amd/powerplay: fix power over limit on Fiji + - drm/amd/display: Default HDMI6G support to true. Log VBIOS table error. + - drm/amdgpu: used cached pcie gen info for SI (v2) + - drm/amdgpu: Notify sbios device ready before send request + - drm/radeon: fix KV harvesting + - drm/amdgpu: fix KV harvesting + - drm/amdgpu:Correct max uvd handles + - drm/amdgpu:Always save uvd vcpu_bo in VM Mode + - ovl: redirect_dir=nofollow should not follow redirect for opaque lower + - MIPS: BMIPS: Do not mask IPIs during suspend + - MIPS: ath25: Check for kzalloc allocation failure + - MIPS: OCTEON: irq: Check for null return on kzalloc allocation + - PCI: dwc: Fix enumeration end when reaching root subordinate + - Input: matrix_keypad - fix race when disabling interrupts + - Revert "Input: synaptics - Lenovo Thinkpad T460p devices should use RMI" + - bug: use %pB in BUG and stack protector failure + - lib/bug.c: exclude non-BUG/WARN exceptions from report_bug() + - mm/memblock.c: hardcode the end_pfn being -1 + - Documentation/sphinx: Fix Directive import error + - loop: Fix lost writes caused by missing flag + - virtio_ring: fix num_free handling in error case + - KVM: s390: fix memory overwrites when not using SCA entries + - arm64: mm: fix thinko in non-global page table attribute check + - IB/core: Fix missing RDMA cgroups release in case of failure to register + device + - Revert "nvme: create 'slaves' and 'holders' entries for hidden controllers" + - kbuild: Handle builtin dtb file names containing hyphens + - dm bufio: avoid false-positive Wmaybe-uninitialized warning + - IB/mlx5: Fix incorrect size of klms in the memory region + - bcache: fix crashes in duplicate cache device register + - bcache: don't attach backing with duplicate UUID + - x86/MCE: Save microcode revision in machine check records + - x86/MCE: Serialize sysfs changes + - perf tools: Fix trigger class trigger_on() + - x86/spectre_v2: Don't check microcode versions when running under + hypervisors + - ALSA: hda/realtek - Add support headset mode for DELL WYSE + - ALSA: hda/realtek - Add headset mode support for Dell laptop + - ALSA: hda/realtek: Limit mic boost on T480 + - ALSA: hda/realtek - Fix dock line-out volume on Dell Precision 7520 + - ALSA: hda/realtek - Make dock sound work on ThinkPad L570 + - ALSA: seq: More protection for concurrent write and ioctl races + - ALSA: hda: add dock and led support for HP EliteBook 820 G3 + - ALSA: hda: add dock and led support for HP ProBook 640 G2 + - scsi: qla2xxx: Fix NULL pointer crash due to probe failure + - scsi: qla2xxx: Fix recursion while sending terminate exchange + - dt-bindings: Document mti,mips-cpc binding + - MIPS: CPC: Map registers using DT in mips_cpc_default_phys_base() + - nospec: Kill array_index_nospec_mask_check() + - nospec: Include dependency + - x86/entry: Reduce the code footprint of the 'idtentry' macro + - x86/entry/64: Use 'xorl' for faster register clearing + - x86/mm: Remove stale comment about KMEMCHECK + - x86/asm: Improve how GEN_*_SUFFIXED_RMWcc() specify clobbers + - x86/IO-APIC: Avoid warning in 32-bit builds + - x86/LDT: Avoid warning in 32-bit builds with older gcc + - x86-64/realmode: Add instruction suffix + - Revert "x86/retpoline: Simplify vmexit_fill_RSB()" + - x86/speculation: Use IBRS if available before calling into firmware + - x86/retpoline: Support retpoline builds with Clang + - x86/speculation, objtool: Annotate indirect calls/jumps for objtool + - x86/speculation: Move firmware_restrict_branch_speculation_*() from C to CPP + - x86/paravirt, objtool: Annotate indirect calls + - x86/boot, objtool: Annotate indirect jump in secondary_startup_64() + - x86/mm/sme, objtool: Annotate indirect call in sme_encrypt_execute() + - objtool: Use existing global variables for options + - objtool: Add retpoline validation + - objtool: Add module specific retpoline rules + - objtool, retpolines: Integrate objtool with retpoline support more closely + - objtool: Fix another switch table detection issue + - objtool: Fix 32-bit build + - x86/kprobes: Fix kernel crash when probing .entry_trampoline code + - watchdog: hpwdt: SMBIOS check + - watchdog: hpwdt: Check source of NMI + - watchdog: hpwdt: fix unused variable warning + - watchdog: hpwdt: Remove legacy NMI sourcing. + - netfilter: add back stackpointer size checks + - netfilter: ipt_CLUSTERIP: fix a race condition of proc file creation + - netfilter: xt_hashlimit: fix lock imbalance + - netfilter: x_tables: fix missing timer initialization in xt_LED + - netfilter: nat: cope with negative port range + - netfilter: IDLETIMER: be syzkaller friendly + - netfilter: ebtables: CONFIG_COMPAT: don't trust userland offsets + - netfilter: bridge: ebt_among: add missing match size checks + - netfilter: ipv6: fix use-after-free Write in nf_nat_ipv6_manip_pkt + - netfilter: use skb_to_full_sk in ip6_route_me_harder + - tpm_tis: Move ilb_base_addr to tpm_tis_data + - tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd() + - tpm: delete the TPM_TIS_CLK_ENABLE flag + - tpm: remove unused variables + - tpm: only attempt to disable the LPC CLKRUN if is already enabled + - x86/xen: Calculate __max_logical_packages on PV domains + - scsi: qla2xxx: Fix system crash for Notify ack timeout handling + - scsi: qla2xxx: Fix gpnid error processing + - scsi: qla2xxx: Move session delete to driver work queue + - scsi: qla2xxx: Skip IRQ affinity for Target QPairs + - scsi: qla2xxx: Fix re-login for Nport Handle in use + - scsi: qla2xxx: Retry switch command on time out + - scsi: qla2xxx: Serialize GPNID for multiple RSCN + - scsi: qla2xxx: Fix login state machine stuck at GPDB + - scsi: qla2xxx: Fix NPIV host cleanup in target mode + - scsi: qla2xxx: Relogin to target port on a cable swap + - scsi: qla2xxx: Fix Relogin being triggered too fast + - scsi: qla2xxx: Fix PRLI state check + - scsi: qla2xxx: Fix abort command deadlock due to spinlock + - scsi: qla2xxx: Replace fcport alloc with qla2x00_alloc_fcport + - scsi: qla2xxx: Fix scan state field for fcport + - scsi: qla2xxx: Clear loop id after delete + - scsi: qla2xxx: Defer processing of GS IOCB calls + - scsi: qla2xxx: Remove aborting ELS IOCB call issued as part of timeout. + - scsi: qla2xxx: Fix system crash in qlt_plogi_ack_unref + - scsi: qla2xxx: Fix memory leak in dual/target mode + - NFS: Fix an incorrect type in struct nfs_direct_req + - pNFS: Prevent the layout header refcount going to zero in pnfs_roc() + - NFS: Fix unstable write completion + - Linux 4.15.10 + + * Bionic update to 4.15.10 stable release (LP: #1756100) // CVE-2018-1000004. + - ALSA: seq: Don't allow resizing pool in use + + * nfp: prioritize stats updates (LP: #1752061) + - nfp: flower: prioritize stats updates + + * Ubuntu 18.04 - Kernel crash on nvme subsystem-reset /dev/nvme0 (Bolt / NVMe) + (LP: #1753371) + - nvme-pci: Fix EEH failure on ppc + + * sbsa watchdog crashes thunderx2 system (LP: #1755595) + - watchdog: sbsa: use 32-bit read for WCV + + * KVM: s390: add vcpu stat counters for many instruction (LP: #1755132) + - KVM: s390: diagnoses are instructions as well + - KVM: s390: add vcpu stat counters for many instruction + + * CIFS SMB2/SMB3 does not work for domain based DFS (LP: #1747572) + - CIFS: make IPC a regular tcon + - CIFS: use tcon_ipc instead of use_ipc parameter of SMB2_ioctl + - CIFS: dump IPC tcon in debug proc file + + * i2c-thunderx: erroneous error message "unhandled state: 0" (LP: #1754076) + - i2c: octeon: Prevent error message on bus error + + * Boston-LC:bos1u1: Stress test on Qlogic Fibre Channel on Ubuntu KVM guest + that caused KVM host crashed in qlt_free_session_done call (LP: #1750441) + - scsi: qla2xxx: Fix memory corruption during hba reset test + + * Ubuntu 18.04 - Performance: Radix page fault handler bug in KVM + (LP: #1752236) + - KVM: PPC: Book3S HV: Fix handling of large pages in radix page fault handler + + * Fix ARC hit rate (LP: #1755158) + - SAUCE: Fix ARC hit rate (LP: #1755158) + + * Bionic update to 4.15.9 stable release (LP: #1755275) + - bpf: fix mlock precharge on arraymaps + - bpf: fix memory leak in lpm_trie map_free callback function + - bpf: fix rcu lockdep warning for lpm_trie map_free callback + - bpf, x64: implement retpoline for tail call + - bpf, arm64: fix out of bounds access in tail call + - bpf: add schedule points in percpu arrays management + - bpf: allow xadd only on aligned memory + - bpf, ppc64: fix out of bounds access in tail call + - scsi: mpt3sas: fix oops in error handlers after shutdown/unload + - scsi: mpt3sas: wait for and flush running commands on shutdown/unload + - KVM: x86: fix backward migration with async_PF + - Linux 4.15.9 + + * Bionic update to 4.15.8 stable release (LP: #1755179) + - hrtimer: Ensure POSIX compliance (relative CLOCK_REALTIME hrtimers) + - ipmi_si: Fix error handling of platform device + - platform/x86: dell-laptop: Allocate buffer on heap rather than globally + - powerpc/pseries: Enable RAS hotplug events later + - Bluetooth: btusb: Use DMI matching for QCA reset_resume quirking + - ixgbe: fix crash in build_skb Rx code path + - tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the + bus + - tpm: fix potential buffer overruns caused by bit glitches on the bus + - tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on + the bus + - tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the + bus + - tpm_tis: fix potential buffer overruns caused by bit glitches on the bus + - ALSA: usb-audio: Add a quirck for B&W PX headphones + - ALSA: control: Fix memory corruption risk in snd_ctl_elem_read + - ALSA: x86: Fix missing spinlock and mutex initializations + - ALSA: hda: Add a power_save blacklist + - ALSA: hda - Fix pincfg at resume on Lenovo T470 dock + - mmc: sdhci-pci: Fix S0i3 for Intel BYT-based controllers + - mmc: dw_mmc-k3: Fix out-of-bounds access through DT alias + - mmc: dw_mmc: Avoid accessing registers in runtime suspended state + - mmc: dw_mmc: Factor out dw_mci_init_slot_caps + - mmc: dw_mmc: Fix out-of-bounds access for slot's caps + - timers: Forward timer base before migrating timers + - parisc: Use cr16 interval timers unconditionally on qemu + - parisc: Reduce irq overhead when run in qemu + - parisc: Fix ordering of cache and TLB flushes + - parisc: Hide virtual kernel memory layout + - btrfs: use proper endianness accessors for super_copy + - block: fix the count of PGPGOUT for WRITE_SAME + - block: kyber: fix domain token leak during requeue + - block: pass inclusive 'lend' parameter to truncate_inode_pages_range + - vfio: disable filesystem-dax page pinning + - cpufreq: s3c24xx: Fix broken s3c_cpufreq_init() + - dax: fix vma_is_fsdax() helper + - direct-io: Fix sleep in atomic due to sync AIO + - x86/xen: Zero MSR_IA32_SPEC_CTRL before suspend + - x86/platform/intel-mid: Handle Intel Edison reboot correctly + - x86/cpu_entry_area: Sync cpu_entry_area to initial_page_table + - bridge: check brport attr show in brport_show + - fib_semantics: Don't match route with mismatching tclassid + - hdlc_ppp: carrier detect ok, don't turn off negotiation + - ipv6 sit: work around bogus gcc-8 -Wrestrict warning + - net: amd-xgbe: fix comparison to bitshift when dealing with a mask + - net: ethernet: ti: cpsw: fix net watchdog timeout + - net: fix race on decreasing number of TX queues + - net: ipv4: don't allow setting net.ipv4.route.min_pmtu below 68 + - netlink: ensure to loop over all netns in genlmsg_multicast_allns() + - net: sched: report if filter is too large to dump + - ppp: prevent unregistered channels from connecting to PPP units + - sctp: verify size of a new chunk in _sctp_make_chunk() + - udplite: fix partial checksum initialization + - net/mlx5e: Fix TCP checksum in LRO buffers + - sctp: fix dst refcnt leak in sctp_v4_get_dst + - mlxsw: spectrum_switchdev: Check success of FDB add operation + - net/mlx5e: Specify numa node when allocating drop rq + - net: phy: fix phy_start to consider PHY_IGNORE_INTERRUPT + - tcp: Honor the eor bit in tcp_mtu_probe + - rxrpc: Fix send in rxrpc_send_data_packet() + - tcp_bbr: better deal with suboptimal GSO + - doc: Change the min default value of tcp_wmem/tcp_rmem. + - net/mlx5e: Fix loopback self test when GRO is off + - net_sched: gen_estimator: fix broken estimators based on percpu stats + - net/sched: cls_u32: fix cls_u32 on filter replace + - sctp: do not pr_err for the duplicated node in transport rhlist + - mlxsw: spectrum_router: Fix error path in mlxsw_sp_vr_create + - net: ipv4: Set addr_type in hash_keys for forwarded case + - sctp: fix dst refcnt leak in sctp_v6_get_dst() + - bridge: Fix VLAN reference count problem + - net/mlx5e: Verify inline header size do not exceed SKB linear size + - tls: Use correct sk->sk_prot for IPV6 + - amd-xgbe: Restore PCI interrupt enablement setting on resume + - cls_u32: fix use after free in u32_destroy_key() + - mlxsw: spectrum_router: Do not unconditionally clear route offload + indication + - netlink: put module reference if dump start fails + - tcp: purge write queue upon RST + - tuntap: correctly add the missing XDP flush + - tuntap: disable preemption during XDP processing + - virtio-net: disable NAPI only when enabled during XDP set + - cxgb4: fix trailing zero in CIM LA dump + - net/mlx5: Fix error handling when adding flow rules + - net: phy: Restore phy_resume() locking assumption + - tcp: tracepoint: only call trace_tcp_send_reset with full socket + - l2tp: don't use inet_shutdown on tunnel destroy + - l2tp: don't use inet_shutdown on ppp session destroy + - l2tp: fix races with tunnel socket close + - l2tp: fix race in pppol2tp_release with session object destroy + - l2tp: fix tunnel lookup use-after-free race + - s390/qeth: fix underestimated count of buffer elements + - s390/qeth: fix SETIP command handling + - s390/qeth: fix overestimated count of buffer elements + - s390/qeth: fix IP removal on offline cards + - s390/qeth: fix double-free on IP add/remove race + - Revert "s390/qeth: fix using of ref counter for rxip addresses" + - s390/qeth: fix IP address lookup for L3 devices + - s390/qeth: fix IPA command submission race + - tcp: revert F-RTO middle-box workaround + - tcp: revert F-RTO extension to detect more spurious timeouts + - blk-mq: don't call io sched's .requeue_request when requeueing rq to + ->dispatch + - media: m88ds3103: don't call a non-initalized function + - EDAC, sb_edac: Fix out of bound writes during DIMM configuration on KNL + - KVM: s390: take care of clock-comparator sign control + - KVM: s390: provide only a single function for setting the tod (fix SCK) + - KVM: s390: consider epoch index on hotplugged CPUs + - KVM: s390: consider epoch index on TOD clock syncs + - nospec: Allow index argument to have const-qualified type + - x86/mm: Fix {pmd,pud}_{set,clear}_flags() + - ARM: orion: fix orion_ge00_switch_board_info initialization + - ARM: dts: rockchip: Remove 1.8 GHz operation point from phycore som + - ARM: mvebu: Fix broken PL310_ERRATA_753970 selects + - ARM: kvm: fix building with gcc-8 + - KVM: X86: Fix SMRAM accessing even if VM is shutdown + - KVM: mmu: Fix overlap between public and private memslots + - KVM/x86: Remove indirect MSR op calls from SPEC_CTRL + - KVM: x86: move LAPIC initialization after VMCS creation + - KVM/VMX: Optimize vmx_vcpu_run() and svm_vcpu_run() by marking the RDMSR + path as unlikely() + - KVM: x86: fix vcpu initialization with userspace lapic + - KVM/x86: remove WARN_ON() for when vm_munmap() fails + - ACPI / bus: Parse tables as term_list for Dell XPS 9570 and Precision M5530 + - ARM: dts: LogicPD SOM-LV: Fix I2C1 pinmux + - ARM: dts: LogicPD Torpedo: Fix I2C1 pinmux + - powerpc/64s/radix: Boot-time NULL pointer protection using a guard-PID + - md: only allow remove_and_add_spares when no sync_thread running. + - platform/x86: dell-laptop: fix kbd_get_state's request value + - Linux 4.15.8 + + * ZFS setgid broken on 0.7 (LP: #1753288) + - SAUCE: Fix ZFS setgid + + * /proc/kallsyms prints "(null)" for null addresses in 4.15 (LP: #1754297) + - vsprintf: avoid misleading "(null)" for %px + + * Miscellaneous Ubuntu changes + - d-i: Add netsec to nic-modules + - [Config] fix up retpoline abi files + - [Config] set NOBP and expoline options for s390 + + -- Thadeu Lima de Souza Cascardo Fri, 16 Mar 2018 14:49:27 -0300 + +linux (4.15.0-12.13) bionic; urgency=medium + + * linux: 4.15.0-12.13 -proposed tracker (LP: #1754059) + + * CONFIG_EFI=y on armhf (LP: #1726362) + - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings + + * ppc64el: Support firmware disable of RFI flush (LP: #1751994) + - powerpc/pseries: Support firmware disable of RFI flush + - powerpc/powernv: Support firmware disable of RFI flush + + * [Feature] CFL/CNL (PCH:CNP-H): New GPIO Commit added (GPIO Driver needed) + (LP: #1751714) + - gpio / ACPI: Drop unnecessary ACPI GPIO to Linux GPIO translation + - pinctrl: intel: Allow custom GPIO base for pad groups + - pinctrl: cannonlake: Align GPIO number space with Windows + + * [Feature] Add xHCI debug device support in the driver (LP: #1730832) + - usb: xhci: Make some static functions global + - usb: xhci: Add DbC support in xHCI driver + - [Config] USB_XHCI_DBGCAP=y for commit mainline dfba2174dc42. + + * [SRU] Lenovo E41 Mic mute hotkey is not responding (LP: #1753347) + - platform/x86: ideapad-laptop: Increase timeout to wait for EC answer + + * headset mic can't be detected on two Dell machines (LP: #1748807) + - ALSA: hda - Fix a wrong FIXUP for alc289 on Dell machines + + * hisi_sas: Add disk LED support (LP: #1752695) + - scsi: hisi_sas: directly attached disk LED feature for v2 hw + + * [Feature] [Graphics]Whiskey Lake (Coffelake-U 4+2) new PCI Device ID adds + (LP: #1742561) + - drm/i915/cfl: Adding more Coffee Lake PCI IDs. + + * [Bug] [USB Function][CFL-CNL PCH]Stall Error and USB Transaction Error in + trace, Disable of device-initiated U1/U2 failed and rebind failed: -517 + during suspend/resume with usb storage. (LP: #1730599) + - usb: Don't print a warning if interface driver rebind is deferred at resume + + * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655) + - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386 + - [Config] retpoline -- clean up i386 retpoline files + + * hisilicon hibmc regression due to ea642c3216cb ("drm/ttm: add io_mem_pfn + callback") (LP: #1738334) + - drm/ttm: add ttm_bo_io_mem_pfn to check io_mem_pfn + + * [Asus UX360UA] battery status in unity-panel is not changing when battery is + being charged (LP: #1661876) // AC adapter status not detected on Asus + ZenBook UX410UAK (LP: #1745032) + - ACPI / battery: Add quirk for Asus UX360UA and UX410UAK + + * ASUS UX305LA - Battery state not detected correctly (LP: #1482390) + - ACPI / battery: Add quirk for Asus GL502VSK and UX305LA + + * [18.04 FEAT] Automatically detect layer2 setting in the qeth device driver + (LP: #1747639) + - s390/diag: add diag26c support for VNIC info + - s390/qeth: support early setup for z/VM NICs + + * Bionic update to v4.15.7 stable release (LP: #1752317) + - netfilter: drop outermost socket lock in getsockopt() + - arm64: mm: don't write garbage into TTBR1_EL1 register + - kconfig.h: Include compiler types to avoid missed struct attributes + - MIPS: boot: Define __ASSEMBLY__ for its.S build + - xtensa: fix high memory/reserved memory collision + - scsi: ibmvfc: fix misdefined reserved field in ibmvfc_fcp_rsp_info + - MIPS: Drop spurious __unused in struct compat_flock + - cfg80211: fix cfg80211_beacon_dup + - i2c: designware: must wait for enable + - i2c: bcm2835: Set up the rising/falling edge delays + - X.509: fix BUG_ON() when hash algorithm is unsupported + - X.509: fix NULL dereference when restricting key with unsupported_sig + - PKCS#7: fix certificate chain verification + - PKCS#7: fix certificate blacklisting + - extcon: int3496: process id-pin first so that we start with the right status + - genirq/matrix: Handle CPU offlining proper + - RDMA/uverbs: Protect from races between lookup and destroy of uobjects + - RDMA/uverbs: Protect from command mask overflow + - RDMA/uverbs: Fix bad unlock balance in ib_uverbs_close_xrcd + - RDMA/uverbs: Fix circular locking dependency + - RDMA/uverbs: Sanitize user entered port numbers prior to access it + - iio: adc: stm32: fix stm32h7_adc_enable error handling + - iio: srf08: fix link error "devm_iio_triggered_buffer_setup" undefined + - iio: buffer: check if a buffer has been set up when poll is called + - iio: adis_lib: Initialize trigger before requesting interrupt + - Kbuild: always define endianess in kconfig.h + - x86/apic/vector: Handle vector release on CPU unplug correctly + - x86/oprofile: Fix bogus GCC-8 warning in nmi_setup() + - mm, swap, frontswap: fix THP swap if frontswap enabled + - mm: don't defer struct page initialization for Xen pv guests + - uapi/if_ether.h: move __UAPI_DEF_ETHHDR libc define + - irqchip/gic-v3: Use wmb() instead of smb_wmb() in gic_raise_softirq() + - irqchip/mips-gic: Avoid spuriously handling masked interrupts + - PCI/cxgb4: Extend T3 PCI quirk to T4+ devices + - net: thunderbolt: Tear down connection properly on suspend + - net: thunderbolt: Run disconnect flow asynchronously when logout is received + - ohci-hcd: Fix race condition caused by ohci_urb_enqueue() and + io_watchdog_func() + - usb: ohci: Proper handling of ed_rm_list to handle race condition between + usb_kill_urb() and finish_unlinks() + - arm64: Remove unimplemented syscall log message + - arm64: Disable unhandled signal log messages by default + - arm64: cpufeature: Fix CTR_EL0 field definitions + - Add delay-init quirk for Corsair K70 RGB keyboards + - usb: host: ehci: use correct device pointer for dma ops + - usb: dwc3: gadget: Set maxpacket size for ep0 IN + - usb: dwc3: ep0: Reset TRB counter for ep0 IN + - usb: phy: mxs: Fix NULL pointer dereference on i.MX23/28 + - usb: ldusb: add PIDs for new CASSY devices supported by this driver + - Revert "usb: musb: host: don't start next rx urb if current one failed" + - usb: gadget: f_fs: Process all descriptors during bind + - usb: gadget: f_fs: Use config_ep_by_speed() + - usb: renesas_usbhs: missed the "running" flag in usb_dmac with rx path + - drm/cirrus: Load lut in crtc_commit + - drm/atomic: Fix memleak on ERESTARTSYS during non-blocking commits + - drm: Handle unexpected holes in color-eviction + - drm/amdgpu: disable MMHUB power gating on raven + - drm/amdgpu: fix VA hole handling on Vega10 v3 + - drm/amdgpu: Add dpm quirk for Jet PRO (v2) + - drm/amdgpu: only check mmBIF_IOV_FUNC_IDENTIFIER on tonga/fiji + - drm/amdgpu: Avoid leaking PM domain on driver unbind (v2) + - drm/amdgpu: add new device to use atpx quirk + - arm64: __show_regs: Only resolve kernel symbols when running at EL1 + - drm/i915/breadcrumbs: Ignore unsubmitted signalers + - microblaze: fix endian handling + - Linux 4.15.7 + + * [regression] Colour banding and artefacts appear system-wide on an Asus + Zenbook UX303LA with Intel HD 4400 graphics (LP: #1749420) // Bionic update + to v4.15.7 stable release (LP: #1752317) + - drm/edid: Add 6 bpc quirk for CPT panel in Asus UX303LA + + * errors with sas hotplug (LP: #1752146) + - scsi: libsas: fix memory leak in sas_smp_get_phy_events() + - scsi: libsas: fix error when getting phy events + - scsi: libsas: initialize sas_phy status according to response of DISCOVER + - scsi: libsas: Use dynamic alloced work to avoid sas event lost + - scsi: libsas: shut down the PHY if events reached the threshold + - scsi: libsas: make the event threshold configurable + - scsi: libsas: Use new workqueue to run sas event and disco event + - scsi: libsas: use flush_workqueue to process disco events synchronously + - scsi: libsas: direct call probe and destruct + - scsi: libsas: notify event PORTE_BROADCAST_RCVD in sas_enable_revalidation() + + * rtnetlink: enable namespace identifying properties in rtnetlink requests + (LP: #1748232) + - rtnetlink: enable IFLA_IF_NETNSID in do_setlink() + - rtnetlink: enable IFLA_IF_NETNSID for RTM_SETLINK + - rtnetlink: enable IFLA_IF_NETNSID for RTM_DELLINK + - rtnetlink: enable IFLA_IF_NETNSID for RTM_NEWLINK + - rtnetlink: remove check for IFLA_IF_NETNSID + - rtnetlink: require unique netns identifier + + * Bionic update to v4.15.6 stable release (LP: #1752119) + - tun: fix tun_napi_alloc_frags() frag allocator + - ptr_ring: fail early if queue occupies more than KMALLOC_MAX_SIZE + - ptr_ring: try vmalloc() when kmalloc() fails + - selinux: ensure the context is NUL terminated in + security_context_to_sid_core() + - selinux: skip bounded transition processing if the policy isn't loaded + - media: pvrusb2: properly check endpoint types + - crypto: x86/twofish-3way - Fix %rbp usage + - staging: android: ion: Add __GFP_NOWARN for system contig heap + - staging: android: ion: Switch from WARN to pr_warn + - blk_rq_map_user_iov: fix error override + - KVM: x86: fix escape of guest dr6 to the host + - kcov: detect double association with a single task + - netfilter: x_tables: fix int overflow in xt_alloc_table_info() + - netfilter: x_tables: avoid out-of-bounds reads in + xt_request_find_{match|target} + - netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check() + - netfilter: on sockopt() acquire sock lock only in the required scope + - netfilter: xt_cgroup: initialize info->priv in cgroup_mt_check_v1() + - netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert + - rds: tcp: correctly sequence cleanup on netns deletion. + - rds: tcp: atomically purge entries from rds_tcp_conn_list during netns + delete + - net: avoid skb_warn_bad_offload on IS_ERR + - net_sched: gen_estimator: fix lockdep splat + - soc: qcom: rmtfs_mem: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - ASoC: ux500: add MODULE_LICENSE tag + - video: fbdev/mmp: add MODULE_LICENSE + - ARM: 8743/1: bL_switcher: add MODULE_LICENSE tag + - arm64: dts: add #cooling-cells to CPU nodes + - dn_getsockoptdecnet: move nf_{get/set}sockopt outside sock lock + - ANDROID: binder: remove WARN() for redundant txn error + - ANDROID: binder: synchronize_rcu() when using POLLFREE. + - staging: android: ashmem: Fix a race condition in pin ioctls + - binder: check for binder_thread allocation failure in binder_poll() + - binder: replace "%p" with "%pK" + - staging: fsl-mc: fix build testing on x86 + - staging: iio: adc: ad7192: fix external frequency setting + - staging: iio: ad5933: switch buffer mode to software + - xhci: Fix NULL pointer in xhci debugfs + - xhci: Fix xhci debugfs devices node disappearance after hibernation + - xhci: xhci debugfs device nodes weren't removed after device plugged out + - xhci: fix xhci debugfs errors in xhci_stop + - usbip: keep usbip_device sockfd state in sync with tcp_socket + - crypto: s5p-sss - Fix kernel Oops in AES-ECB mode + - mei: me: add cannon point device ids + - mei: me: add cannon point device ids for 4th device + - vmalloc: fix __GFP_HIGHMEM usage for vmalloc_32 on 32b systems + - Linux 4.15.6 + + * Unable to insert test_bpf module on Bionic s390x (LP: #1751234) + - bpf: fix selftests/bpf test_kmod.sh failure when CONFIG_BPF_JIT_ALWAYS_ON=y + + * [Ubuntu 18.04 FEAT] OpenCAPI enabling (LP: #1746988) + - powerpc/powernv: Introduce new PHB type for opencapi links + - powerpc/powernv: Set correct configuration space size for opencapi devices + - powerpc/powernv: Add opal calls for opencapi + - powerpc/powernv: Add platform-specific services for opencapi + - powerpc/powernv: Capture actag information for the device + - ocxl: Driver code for 'generic' opencapi devices + - ocxl: Add AFU interrupt support + - ocxl: Add a kernel API for other opencapi drivers + - ocxl: Add trace points + - ocxl: Add Makefile and Kconfig + - [Config] CONFIG_OCXL=m for ppc64el + - cxl: Remove support for "Processing accelerators" class + - ocxl: Documentation + - ocxl: add MAINTAINERS entry + - cxl: Add support for ASB_Notify on POWER9 + + * Request to update 18.04 kernel aacraid to upstream 4.16 version + (LP: #1746801) + - scsi: aacraid: remove unused variable managed_request_id + - scsi: aacraid: Do not attempt abort when Fw panicked + - scsi: aacraid: Do not remove offlined devices + - scsi: aacraid: Fix ioctl reset hang + - scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw + - scsi: aacraid: Refactor reset_host store function + - scsi: aacraid: Move code to wait for IO completion to shutdown func + - scsi: aacraid: Create bmic submission function from bmic identify + - scsi: aacraid: Change phy luns function to use common bmic function + - scsi: aacraid: Refactor and rename to make mirror existing changes + - scsi: aacraid: Add target setup helper function + - scsi: aacraid: Untangle targets setup from report phy luns + - scsi: aacraid: Move function around to match existing code + - scsi: aacraid: Create helper functions to get lun info + - scsi: aacraid: Save bmic phy information for each phy + - scsi: aacraid: Add helper function to set queue depth + - scsi: aacraid: Merge func to get container information + - scsi: aacraid: Process hba and container hot plug events in single function + - scsi: aacraid: Added macros to help loop through known buses and targets + - scsi: aacraid: Refactor resolve luns code and scsi functions + - scsi: aacraid: Merge adapter setup with resolve luns + - scsi: aacraid: Block concurrent hotplug event handling + - scsi: aacraid: Use hotplug handling function in place of scsi_scan_host + - scsi: aacraid: Reschedule host scan in case of failure + - scsi: aacraid: Fix hang while scanning in eh recovery + - scsi: aacraid: Skip schedule rescan in case of kdump + - scsi: aacraid: Remove unused rescan variable + - scsi: aacraid: Remove AAC_HIDE_DISK check in queue command + - scsi: aacraid: Update driver version to 50877 + - scsi: aacraid: Fix driver oops with dead battery + - scsi: aacraid: remove redundant setting of variable c + - scsi: aacraid: Get correct lun count + - scsi: aacraid: Delay for rescan worker needs to be 10 seconds + + * [18.04] kpatch - Add livepatch hook support for ppc64le (LP: #1741992) + - powerpc/modules: Add REL24 relocation support of livepatch symbols + - powerpc/modules: Don't try to restore r2 after a sibling call + - powerpc/modules: Improve restore_r2() error message + + * Ubuntu 18.04 - Include latest ibmvnic fixes in Ubuntu kernel (LP: #1748517) + - ibmvnic: Rename IBMVNIC_MAX_TX_QUEUES to IBMVNIC_MAX_QUEUES + - ibmvnic: Increase maximum number of RX/TX queues + - ibmvnic: Include header descriptor support for ARP packets + - ibmvnic: Don't handle RX interrupts when not up. + - ibmvnic: Wait for device response when changing MAC + - ibmvnic: fix firmware version when no firmware level has been provided by + the VIOS server + - ibmvnic: fix empty firmware version and errors cleanup + - ibmvnic: Fix rx queue cleanup for non-fatal resets + - ibmvnic: Ensure that buffers are NULL after free + - ibmvnic: queue reset when CRQ gets closed during reset + - ibmvnic: Reset long term map ID counter + - ibmvnic: Remove skb->protocol checks in ibmvnic_xmit + - ibmvnic: Wait until reset is complete to set carrier on + - ibmvnic: Fix login buffer memory leaks + - ibmvnic: Fix NAPI structures memory leak + - ibmvnic: Free RX socket buffer in case of adapter error + - ibmvnic: Clean RX pool buffers during device close + - ibmvnic: Check for NULL skb's in NAPI poll routine + - ibmvnic: Fix early release of login buffer + + * Power9 DD 2.2 needs HMI fixup backport of upstream + patch(d075745d893c78730e4a3b7a60fca23c2f764081) into kernel (LP: #1751834) + - KVM: PPC: Book3S HV: Improve handling of debug-trigger HMIs on POWER9 + + * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927) + - d-i: add cxgb4 to nic-modules + + * BCM5719/tg3 loses connectivity due to missing heartbeats between fw and + driver (LP: #1751337) + - tg3: APE heartbeat changes + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.2.6-dfsg-5 + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - Revert "UBUNTU: SAUCE: (no-up) Convert bnx2x firmware files to ihex format" + - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches + - [Config] fix up retpoline abi files + - ubuntu: vbox -- update to 5.2.8-dfsg-2 + + -- Seth Forshee Wed, 07 Mar 2018 17:36:23 +0100 + +linux (4.15.0-11.12) bionic; urgency=medium + + * linux: 4.15.0-11.12 -proposed tracker (LP: #1751285) + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_INDIRECT_PIO=y + - SAUCE: LIB: Introduce a generic PIO mapping method + - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range() + - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range() + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings + - SAUCE: ACPI / scan: do not enumerate Indirect IO host children + - SAUCE: HISI LPC: Add ACPI support + - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver + + * Bionic update to v4.15.5 stable release (LP: #1751131) + - scsi: smartpqi: allow static build ("built-in") + - IB/umad: Fix use of unprotected device pointer + - IB/qib: Fix comparison error with qperf compare/swap test + - IB/mlx4: Fix incorrectly releasing steerable UD QPs when have only ETH ports + - IB/core: Fix two kernel warnings triggered by rxe registration + - IB/core: Fix ib_wc structure size to remain in 64 bytes boundary + - IB/core: Avoid a potential OOPs for an unused optional parameter + - selftests: seccomp: fix compile error seccomp_bpf + - kselftest: fix OOM in memory compaction test + - RDMA/rxe: Fix a race condition related to the QP error state + - RDMA/rxe: Fix a race condition in rxe_requester() + - RDMA/rxe: Fix rxe_qp_cleanup() + - cpufreq: powernv: Dont assume distinct pstate values for nominal and pmin + - PM / devfreq: Propagate error from devfreq_add_device() + - mwifiex: resolve reset vs. remove()/shutdown() deadlocks + - ocfs2: try a blocking lock before return AOP_TRUNCATED_PAGE + - trace_uprobe: Display correct offset in uprobe_events + - powerpc/radix: Remove trace_tlbie call from radix__flush_tlb_all + - powerpc/kernel: Block interrupts when updating TIDR + - powerpc/vas: Don't set uses_vas for kernel windows + - powerpc/numa: Invalidate numa_cpu_lookup_table on cpu remove + - powerpc/mm: Flush radix process translations when setting MMU type + - powerpc/xive: Use hw CPU ids when configuring the CPU queues + - dma-buf: fix reservation_object_wait_timeout_rcu once more v2 + - s390: fix handling of -1 in set{,fs}[gu]id16 syscalls + - arm64: dts: msm8916: Correct ipc references for smsm + - ARM: lpc3250: fix uda1380 gpio numbers + - ARM: dts: STi: Add gpio polarity for "hdmi,hpd-gpio" property + - ARM: dts: nomadik: add interrupt-parent for clcd + - arm: dts: mt7623: fix card detection issue on bananapi-r2 + - arm: spear600: Add missing interrupt-parent of rtc + - arm: spear13xx: Fix dmas cells + - arm: spear13xx: Fix spics gpio controller's warning + - x86/gpu: add CFL to early quirks + - x86/kexec: Make kexec (mostly) work in 5-level paging mode + - x86/xen: init %gs very early to avoid page faults with stack protector + - x86: PM: Make APM idle driver initialize polling state + - mm, memory_hotplug: fix memmap initialization + - x86/entry/64: Clear extra registers beyond syscall arguments, to reduce + speculation attack surface + - x86/entry/64/compat: Clear registers for compat syscalls, to reduce + speculation attack surface + - compiler-gcc.h: Introduce __optimize function attribute + - compiler-gcc.h: __nostackprotector needs gcc-4.4 and up + - crypto: sun4i_ss_prng - fix return value of sun4i_ss_prng_generate + - crypto: sun4i_ss_prng - convert lock to _bh in sun4i_ss_prng_generate + - powerpc/mm/radix: Split linear mapping on hot-unplug + - x86/mm/pti: Fix PTI comment in entry_SYSCALL_64() + - x86/speculation: Update Speculation Control microcode blacklist + - x86/speculation: Correct Speculation Control microcode blacklist again + - Revert "x86/speculation: Simplify indirect_branch_prediction_barrier()" + - KVM/x86: Reduce retpoline performance impact in slot_handle_level_range(), + by always inlining iterator helper methods + - X86/nVMX: Properly set spec_ctrl and pred_cmd before merging MSRs + - KVM/nVMX: Set the CPU_BASED_USE_MSR_BITMAPS if we have a valid L02 MSR + bitmap + - x86/speculation: Clean up various Spectre related details + - PM / runtime: Update links_count also if !CONFIG_SRCU + - PM: cpuidle: Fix cpuidle_poll_state_init() prototype + - platform/x86: wmi: fix off-by-one write in wmi_dev_probe() + - x86/entry/64: Clear registers for exceptions/interrupts, to reduce + speculation attack surface + - x86/entry/64: Merge SAVE_C_REGS and SAVE_EXTRA_REGS, remove unused + extensions + - x86/entry/64: Merge the POP_C_REGS and POP_EXTRA_REGS macros into a single + POP_REGS macro + - x86/entry/64: Interleave XOR register clearing with PUSH instructions + - x86/entry/64: Introduce the PUSH_AND_CLEAN_REGS macro + - x86/entry/64: Use PUSH_AND_CLEAN_REGS in more cases + - x86/entry/64: Get rid of the ALLOC_PT_GPREGS_ON_STACK and + SAVE_AND_CLEAR_REGS macros + - x86/entry/64: Indent PUSH_AND_CLEAR_REGS and POP_REGS properly + - x86/entry/64: Fix paranoid_entry() frame pointer warning + - x86/entry/64: Remove the unused 'icebp' macro + - selftests/x86: Fix vDSO selftest segfault for vsyscall=none + - selftests/x86: Clean up and document sscanf() usage + - selftests/x86/pkeys: Remove unused functions + - selftests/x86: Fix build bug caused by the 5lvl test which has been moved to + the VM directory + - selftests/x86: Do not rely on "int $0x80" in test_mremap_vdso.c + - gfs2: Fixes to "Implement iomap for block_map" + - selftests/x86: Do not rely on "int $0x80" in single_step_syscall.c + - selftests/x86: Disable tests requiring 32-bit support on pure 64-bit systems + - objtool: Fix segfault in ignore_unreachable_insn() + - x86/debug, objtool: Annotate WARN()-related UD2 as reachable + - x86/debug: Use UD2 for WARN() + - x86/speculation: Fix up array_index_nospec_mask() asm constraint + - nospec: Move array_index_nospec() parameter checking into separate macro + - x86/speculation: Add dependency + - x86/mm: Rename flush_tlb_single() and flush_tlb_one() to + __flush_tlb_one_[user|kernel]() + - selftests/x86/mpx: Fix incorrect bounds with old _sigfault + - x86/cpu: Rename cpu_data.x86_mask to cpu_data.x86_stepping + - x86/spectre: Fix an error message + - x86/cpu: Change type of x86_cache_size variable to unsigned int + - x86/entry/64: Fix CR3 restore in paranoid_exit() + - drm/ttm: Don't add swapped BOs to swap-LRU list + - drm/ttm: Fix 'buf' pointer update in ttm_bo_vm_access_kmap() (v2) + - drm/qxl: unref cursor bo when finished with it + - drm/qxl: reapply cursor after resetting primary + - drm/amd/powerplay: Fix smu_table_entry.handle type + - drm/ast: Load lut in crtc_commit + - drm: Check for lessee in DROP_MASTER ioctl + - arm64: Add missing Falkor part number for branch predictor hardening + - drm/radeon: Add dpm quirk for Jet PRO (v2) + - drm/radeon: adjust tested variable + - x86/smpboot: Fix uncore_pci_remove() indexing bug when hot-removing a + physical CPU + - rtc-opal: Fix handling of firmware error codes, prevent busy loops + - mbcache: initialize entry->e_referenced in mb_cache_entry_create() + - mmc: sdhci: Implement an SDHCI-specific bounce buffer + - mmc: bcm2835: Don't overwrite max frequency unconditionally + - Revert "mmc: meson-gx: include tx phase in the tuning process" + - mlx5: fix mlx5_get_vector_affinity to start from completion vector 0 + - Revert "apple-gmux: lock iGP IO to protect from vgaarb changes" + - jbd2: fix sphinx kernel-doc build warnings + - ext4: fix a race in the ext4 shutdown path + - ext4: save error to disk in __ext4_grp_locked_error() + - ext4: correct documentation for grpid mount option + - mm: hide a #warning for COMPILE_TEST + - mm: Fix memory size alignment in devm_memremap_pages_release() + - MIPS: Fix typo BIG_ENDIAN to CPU_BIG_ENDIAN + - MIPS: CPS: Fix MIPS_ISA_LEVEL_RAW fallout + - MIPS: Fix incorrect mem=X@Y handling + - PCI: Disable MSI for HiSilicon Hip06/Hip07 only in Root Port mode + - PCI: iproc: Fix NULL pointer dereference for BCMA + - PCI: pciehp: Assume NoCompl+ for Thunderbolt ports + - PCI: keystone: Fix interrupt-controller-node lookup + - video: fbdev: atmel_lcdfb: fix display-timings lookup + - console/dummy: leave .con_font_get set to NULL + - rbd: whitelist RBD_FEATURE_OPERATIONS feature bit + - xen: Fix {set,clear}_foreign_p2m_mapping on autotranslating guests + - xenbus: track caller request id + - seq_file: fix incomplete reset on read from zero offset + - tracing: Fix parsing of globs with a wildcard at the beginning + - mpls, nospec: Sanitize array index in mpls_label_ok() + - rtlwifi: rtl8821ae: Fix connection lost problem correctly + - arm64: proc: Set PTE_NG for table entries to avoid traversing them twice + - xprtrdma: Fix calculation of ri_max_send_sges + - xprtrdma: Fix BUG after a device removal + - blk-wbt: account flush requests correctly + - target/iscsi: avoid NULL dereference in CHAP auth error path + - iscsi-target: make sure to wake up sleeping login worker + - dm: correctly handle chained bios in dec_pending() + - Btrfs: fix deadlock in run_delalloc_nocow + - Btrfs: fix crash due to not cleaning up tree log block's dirty bits + - Btrfs: fix extent state leak from tree log + - Btrfs: fix btrfs_evict_inode to handle abnormal inodes correctly + - Btrfs: fix use-after-free on root->orphan_block_rsv + - Btrfs: fix unexpected -EEXIST when creating new inode + - 9p/trans_virtio: discard zero-length reply + - mtd: nand: vf610: set correct ooblayout + - ALSA: usb-audio: Fix UAC2 get_ctl request with a RANGE attribute + - ALSA: hda/realtek - Add headset mode support for Dell laptop + - ALSA: hda/realtek - Enable Thinkpad Dock device for ALC298 platform + - ALSA: hda/realtek: PCI quirk for Fujitsu U7x7 + - ALSA: usb-audio: add implicit fb quirk for Behringer UFX1204 + - ALSA: usb: add more device quirks for USB DSD devices + - ALSA: seq: Fix racy pool initializations + - mvpp2: fix multicast address filter + - usb: Move USB_UHCI_BIG_ENDIAN_* out of USB_SUPPORT + - x86/mm, mm/hwpoison: Don't unconditionally unmap kernel 1:1 pages + - ARM: dts: exynos: fix RTC interrupt for exynos5410 + - ARM: pxa/tosa-bt: add MODULE_LICENSE tag + - arm64: dts: msm8916: Add missing #phy-cells + - ARM: dts: s5pv210: add interrupt-parent for ohci + - arm: dts: mt7623: Update ethsys binding + - arm: dts: mt2701: Add reset-cells + - ARM: dts: Delete bogus reference to the charlcd + - media: r820t: fix r820t_write_reg for KASAN + - mmc: sdhci-of-esdhc: fix eMMC couldn't work after kexec + - mmc: sdhci-of-esdhc: fix the mmc error after sleep on ls1046ardb + - Linux 4.15.5 + + * retpoline abi files are empty on i386 (LP: #1751021) + - [Packaging] retpoline-extract -- instantiate retpoline files for i386 + - [Packaging] final-checks -- sanity checking ABI contents + - [Packaging] final-checks -- check for empty retpoline files + - [Config] Disable i386 retpoline check for next upload + + * Bionic update to v4.15.4 stable release (LP: #1751064) + - watchdog: indydog: Add dependency on SGI_HAS_INDYDOG + - cifs: Fix missing put_xid in cifs_file_strict_mmap + - cifs: Fix autonegotiate security settings mismatch + - CIFS: zero sensitive data when freeing + - cpufreq: mediatek: add mediatek related projects into blacklist + - dmaengine: dmatest: fix container_of member in dmatest_callback + - ssb: Do not disable PCI host on non-Mips + - watchdog: gpio_wdt: set WDOG_HW_RUNNING in gpio_wdt_stop + - Revert "drm/i915: mark all device info struct with __initconst" + - sched/rt: Use container_of() to get root domain in rto_push_irq_work_func() + - sched/rt: Up the root domain ref count when passing it around via IPIs + - media: dvb-usb-v2: lmedm04: Improve logic checking of warm start + - media: dvb-usb-v2: lmedm04: move ts2020 attach to dm04_lme2510_tuner + - media: hdpvr: Fix an error handling path in hdpvr_probe() + - arm64: mm: Use non-global mappings for kernel space + - arm64: mm: Temporarily disable ARM64_SW_TTBR0_PAN + - arm64: mm: Move ASID from TTBR0 to TTBR1 + - arm64: mm: Remove pre_ttbr0_update_workaround for Falkor erratum #E1003 + - arm64: mm: Rename post_ttbr0_update_workaround + - arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN + - arm64: mm: Allocate ASIDs in pairs + - arm64: mm: Add arm64_kernel_unmapped_at_el0 helper + - arm64: mm: Invalidate both kernel and user ASIDs when performing TLBI + - arm64: entry: Add exception trampoline page for exceptions from EL0 + - arm64: mm: Map entry trampoline into trampoline and kernel page tables + - arm64: entry: Explicitly pass exception level to kernel_ventry macro + - arm64: entry: Hook up entry trampoline to exception vectors + - arm64: erratum: Work around Falkor erratum #E1003 in trampoline code + - arm64: cpu_errata: Add Kryo to Falkor 1003 errata + - arm64: tls: Avoid unconditional zeroing of tpidrro_el0 for native tasks + - arm64: entry: Add fake CPU feature for unmapping the kernel at EL0 + - arm64: kaslr: Put kernel vectors address in separate data page + - arm64: use RET instruction for exiting the trampoline + - arm64: Kconfig: Add CONFIG_UNMAP_KERNEL_AT_EL0 + - arm64: Kconfig: Reword UNMAP_KERNEL_AT_EL0 kconfig entry + - arm64: Take into account ID_AA64PFR0_EL1.CSV3 + - arm64: capabilities: Handle duplicate entries for a capability + - arm64: mm: Introduce TTBR_ASID_MASK for getting at the ASID in the TTBR + - arm64: kpti: Fix the interaction between ASID switching and software PAN + - arm64: cputype: Add MIDR values for Cavium ThunderX2 CPUs + - arm64: kpti: Make use of nG dependent on arm64_kernel_unmapped_at_el0() + - arm64: mm: Permit transitioning from Global to Non-Global without BBM + - arm64: kpti: Add ->enable callback to remap swapper using nG mappings + - arm64: Force KPTI to be disabled on Cavium ThunderX + - arm64: entry: Reword comment about post_ttbr_update_workaround + - arm64: idmap: Use "awx" flags for .idmap.text .pushsection directives + - perf: arm_spe: Fail device probe when arm64_kernel_unmapped_at_el0() + - arm64: barrier: Add CSDB macros to control data-value prediction + - arm64: Implement array_index_mask_nospec() + - arm64: Make USER_DS an inclusive limit + - arm64: Use pointer masking to limit uaccess speculation + - arm64: entry: Ensure branch through syscall table is bounded under + speculation + - arm64: uaccess: Prevent speculative use of the current addr_limit + - arm64: uaccess: Don't bother eliding access_ok checks in __{get, put}_user + - arm64: uaccess: Mask __user pointers for __arch_{clear, copy_*}_user + - arm64: futex: Mask __user pointers prior to dereference + - arm64: cpufeature: __this_cpu_has_cap() shouldn't stop early + - arm64: Run enable method for errata work arounds on late CPUs + - arm64: cpufeature: Pass capability structure to ->enable callback + - drivers/firmware: Expose psci_get_version through psci_ops structure + - arm64: Move post_ttbr_update_workaround to C code + - arm64: Add skeleton to harden the branch predictor against aliasing attacks + - arm64: Move BP hardening to check_and_switch_context + - arm64: KVM: Use per-CPU vector when BP hardening is enabled + - arm64: entry: Apply BP hardening for high-priority synchronous exceptions + - arm64: entry: Apply BP hardening for suspicious interrupts from EL0 + - arm64: cputype: Add missing MIDR values for Cortex-A72 and Cortex-A75 + - arm64: Implement branch predictor hardening for affected Cortex-A CPUs + - arm64: Implement branch predictor hardening for Falkor + - arm64: Branch predictor hardening for Cavium ThunderX2 + - arm64: KVM: Increment PC after handling an SMC trap + - arm/arm64: KVM: Consolidate the PSCI include files + - arm/arm64: KVM: Add PSCI_VERSION helper + - arm/arm64: KVM: Add smccc accessors to PSCI code + - arm/arm64: KVM: Implement PSCI 1.0 support + - arm/arm64: KVM: Advertise SMCCC v1.1 + - arm64: KVM: Make PSCI_VERSION a fast path + - arm/arm64: KVM: Turn kvm_psci_version into a static inline + - arm64: KVM: Report SMCCC_ARCH_WORKAROUND_1 BP hardening support + - arm64: KVM: Add SMCCC_ARCH_WORKAROUND_1 fast handling + - firmware/psci: Expose PSCI conduit + - firmware/psci: Expose SMCCC version through psci_ops + - arm/arm64: smccc: Make function identifiers an unsigned quantity + - arm/arm64: smccc: Implement SMCCC v1.1 inline primitive + - arm64: Add ARM_SMCCC_ARCH_WORKAROUND_1 BP hardening support + - arm64: Kill PSCI_GET_VERSION as a variant-2 workaround + - mtd: cfi: convert inline functions to macros + - mtd: nand: brcmnand: Disable prefetch by default + - mtd: nand: Fix nand_do_read_oob() return value + - mtd: nand: sunxi: Fix ECC strength choice + - ubi: Fix race condition between ubi volume creation and udev + - ubi: fastmap: Erase outdated anchor PEBs during attach + - ubi: block: Fix locking for idr_alloc/idr_remove + - ubifs: free the encrypted symlink target + - nfs/pnfs: fix nfs_direct_req ref leak when i/o falls back to the mds + - nfs41: do not return ENOMEM on LAYOUTUNAVAILABLE + - NFS: Add a cond_resched() to nfs_commit_release_pages() + - NFS: Fix nfsstat breakage due to LOOKUPP + - NFS: commit direct writes even if they fail partially + - NFS: reject request for id_legacy key without auxdata + - NFS: Fix a race between mmap() and O_DIRECT + - nfsd: Detect unhashed stids in nfsd4_verify_open_stid() + - kernfs: fix regression in kernfs_fop_write caused by wrong type + - ahci: Annotate PCI ids for mobile Intel chipsets as such + - ahci: Add PCI ids for Intel Bay Trail, Cherry Trail and Apollo Lake AHCI + - ahci: Add Intel Cannon Lake PCH-H PCI ID + - crypto: hash - introduce crypto_hash_alg_has_setkey() + - crypto: cryptd - pass through absence of ->setkey() + - crypto: mcryptd - pass through absence of ->setkey() + - crypto: poly1305 - remove ->setkey() method + - crypto: hash - annotate algorithms taking optional key + - crypto: hash - prevent using keyed hashes without setting key + - media: v4l2-ioctl.c: use check_fmt for enum/g/s/try_fmt + - media: v4l2-ioctl.c: don't copy back the result for -ENOTTY + - media: v4l2-compat-ioctl32.c: add missing VIDIOC_PREPARE_BUF + - media: v4l2-compat-ioctl32.c: fix the indentation + - media: v4l2-compat-ioctl32.c: move 'helper' functions to + __get/put_v4l2_format32 + - media: v4l2-compat-ioctl32.c: avoid sizeof(type) + - media: v4l2-compat-ioctl32.c: copy m.userptr in put_v4l2_plane32 + - media: v4l2-compat-ioctl32.c: fix ctrl_is_pointer + - media: v4l2-compat-ioctl32.c: copy clip list in put_v4l2_window32 + - media: v4l2-compat-ioctl32.c: drop pr_info for unknown buffer type + - media: v4l2-compat-ioctl32.c: don't copy back the result for certain errors + - media: v4l2-compat-ioctl32.c: refactor compat ioctl32 logic + - media: v4l2-compat-ioctl32.c: make ctrl_is_pointer work for subdevs + - crypto: caam - fix endless loop when DECO acquire fails + - crypto: sha512-mb - initialize pending lengths correctly + - crypto: talitos - fix Kernel Oops on hashing an empty file + - arm: KVM: Fix SMCCC handling of unimplemented SMC/HVC calls + - KVM: nVMX: Fix races when sending nested PI while dest enters/leaves L2 + - KVM: nVMX: Fix bug of injecting L2 exception into L1 + - KVM: PPC: Book3S HV: Make sure we don't re-enter guest without XIVE loaded + - KVM: PPC: Book3S HV: Drop locks before reading guest memory + - KVM: arm/arm64: Handle CPU_PM_ENTER_FAILED + - KVM: PPC: Book3S PR: Fix broken select due to misspelling + - ASoC: acpi: fix machine driver selection based on quirk + - ASoC: rockchip: i2s: fix playback after runtime resume + - ASoC: skl: Fix kernel warning due to zero NHTL entry + - ASoC: compress: Correct handling of copy callback + - watchdog: imx2_wdt: restore previous timeout after suspend+resume + - afs: Add missing afs_put_cell() + - afs: Need to clear responded flag in addr cursor + - afs: Fix missing cursor clearance + - afs: Fix server list handling + - btrfs: Handle btrfs_set_extent_delalloc failure in fixup worker + - Btrfs: raid56: iterate raid56 internal bio with bio_for_each_segment_all + - kasan: don't emit builtin calls when sanitization is off + - kasan: rework Kconfig settings + - media: dvb_frontend: be sure to init dvb_frontend_handle_ioctl() return code + - media: dvb-frontends: fix i2c access helpers for KASAN + - media: dt-bindings/media/cec-gpio.txt: mention the CEC/HPD max voltages + - media: ts2020: avoid integer overflows on 32 bit machines + - media: vivid: fix module load error when enabling fb and no_error_inj=1 + - media: cxusb, dib0700: ignore XC2028_I2C_FLUSH + - fs/proc/kcore.c: use probe_kernel_read() instead of memcpy() + - kernel/async.c: revert "async: simplify lowest_in_progress()" + - kernel/relay.c: revert "kernel/relay.c: fix potential memory leak" + - pipe: actually allow root to exceed the pipe buffer limits + - pipe: fix off-by-one error when checking buffer limits + - HID: quirks: Fix keyboard + touchpad on Toshiba Click Mini not working + - Bluetooth: btsdio: Do not bind to non-removable BCM43341 + - ipmi: use dynamic memory for DMI driver override + - signal/openrisc: Fix do_unaligned_access to send the proper signal + - signal/sh: Ensure si_signo is initialized in do_divide_error + - alpha: fix crash if pthread_create races with signal delivery + - alpha: osf_sys.c: fix put_tv32 regression + - alpha: Fix mixed up args in EXC macro in futex operations + - alpha: fix reboot on Avanti platform + - alpha: fix formating of stack content + - xtensa: fix futex_atomic_cmpxchg_inatomic + - EDAC, octeon: Fix an uninitialized variable warning + - genirq: Make legacy autoprobing work again + - pinctrl: intel: Initialize GPIO properly when used through irqchip + - pinctrl: mcp23s08: fix irq setup order + - pinctrl: sx150x: Unregister the pinctrl on release + - pinctrl: sx150x: Register pinctrl before adding the gpiochip + - pinctrl: sx150x: Add a static gpio/pinctrl pin range mapping + - pktcdvd: Fix pkt_setup_dev() error path + - pktcdvd: Fix a recently introduced NULL pointer dereference + - blk-mq: quiesce queue before freeing queue + - clocksource/drivers/stm32: Fix kernel panic with multiple timers + - lib/ubsan.c: s/missaligned/misaligned/ + - lib/ubsan: add type mismatch handler for new GCC/Clang + - objtool: Fix switch-table detection + - arm64: dts: marvell: add Ethernet aliases + - drm/i915: Avoid PPS HW/SW state mismatch due to rounding + - ACPI: sbshc: remove raw pointer from printk() message + - acpi, nfit: fix register dimm error handling + - ovl: force r/o mount when index dir creation fails + - ovl: fix failure to fsync lower dir + - ovl: take mnt_want_write() for work/index dir setup + - ovl: take mnt_want_write() for removing impure xattr + - ovl: hash directory inodes for fsnotify + - mn10300/misalignment: Use SIGSEGV SEGV_MAPERR to report a failed user copy + - devpts: fix error handling in devpts_mntget() + - ftrace: Remove incorrect setting of glob search field + - scsi: core: Ensure that the SCSI error handler gets woken up + - scsi: lpfc: Fix crash after bad bar setup on driver attachment + - scsi: cxlflash: Reset command ioasc + - rcu: Export init_rcu_head() and destroy_rcu_head() to GPL modules + - Linux 4.15.4 + - updateconfigs after v4.14.4 stable updates + + * Bionic update to v4.15.4 stable release (LP: #1751064) // CVE-2017-5754 and + do not need KPTI when KASLR is off. + - arm64: Turn on KPTI only on CPUs that need it + + * Miscellaneous Ubuntu changes + - [Config] fix up removed retpoline call sites + + -- Seth Forshee Fri, 23 Feb 2018 08:31:06 -0600 + +linux (4.15.0-10.11) bionic; urgency=medium + + * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250) + + * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10 + (LP: #1749202) + - swiotlb: suppress warning when __GFP_NOWARN is set + - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools + + * linux-tools: perf incorrectly linking libbfd (LP: #1748922) + - SAUCE: tools -- add ability to disable libbfd + - [Packaging] correct disablement of libbfd + + * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in + (LP: #1744058) + - ALSA: hda/realtek - update ALC225 depop optimize + + * [Artful] Support headset mode for DELL WYSE (LP: #1723913) + - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE + + * headset mic can't be detected on two Dell machines (LP: #1748807) + - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289 + - ALSA: hda - Fix headset mic detection problem for two Dell machines + + * Bionic update to v4.15.3 stable release (LP: #1749191) + - ip6mr: fix stale iterator + - net: igmp: add a missing rcu locking section + - qlcnic: fix deadlock bug + - qmi_wwan: Add support for Quectel EP06 + - r8169: fix RTL8168EP take too long to complete driver initialization. + - tcp: release sk_frag.page in tcp_disconnect + - vhost_net: stop device during reset owner + - ipv6: addrconf: break critical section in addrconf_verify_rtnl() + - ipv6: change route cache aging logic + - Revert "defer call to mem_cgroup_sk_alloc()" + - net: ipv6: send unsolicited NA after DAD + - rocker: fix possible null pointer dereference in + rocker_router_fib_event_work + - tcp_bbr: fix pacing_gain to always be unity when using lt_bw + - cls_u32: add missing RCU annotation. + - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only + - soreuseport: fix mem leak in reuseport_add_sock() + - net_sched: get rid of rcu_barrier() in tcf_block_put_ext() + - net: sched: fix use-after-free in tcf_block_put_ext + - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION + - media: soc_camera: soc_scale_crop: add missing + MODULE_DESCRIPTION/AUTHOR/LICENSE + - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE + - crypto: tcrypt - fix S/G table for test_aead_speed() + - Linux 4.15.3 + + * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) // + CVE-2018-1000026 + - net: create skb_gso_validate_mac_len() + - bnx2x: disable GSO where gso_size is too big for hardware + + * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567) + - net: hns: add ACPI mode support for ethtool -p + + * CVE-2017-5715 (Spectre v2 Intel) + - [Packaging] retpoline files must be sorted + - [Packaging] pull in retpoline files + + * [Feature] PXE boot with Intel Omni-Path (LP: #1712031) + - d-i: Add hfi1 to nic-modules + + * CVE-2017-5715 (Spectre v2 retpoline) + - [Packaging] retpoline -- add call site validation + - [Config] disable retpoline checks for first upload + + * Do not duplicate changelog entries assigned to more than one bug or CVE + (LP: #1743383) + - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better + + -- Seth Forshee Tue, 13 Feb 2018 11:33:58 -0600 + +linux (4.15.0-9.10) bionic; urgency=medium + + * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244) + + * Miscellaneous Ubuntu changes + - [Debian] tests -- remove gcc-multilib dependency for arm64 + + -- Seth Forshee Thu, 08 Feb 2018 11:25:04 -0600 + +linux (4.15.0-8.9) bionic; urgency=medium + + * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075) + + * Bionic update to v4.15.2 stable release (LP: #1748072) + - KVM: x86: Make indirect calls in emulator speculation safe + - KVM: VMX: Make indirect call speculation safe + - module/retpoline: Warn about missing retpoline in module + - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf + - x86/cpufeatures: Add Intel feature bits for Speculation Control + - x86/cpufeatures: Add AMD feature bits for Speculation Control + - x86/msr: Add definitions for new speculation control MSRs + - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown + - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes + - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support + - x86/alternative: Print unadorned pointers + - x86/nospec: Fix header guards names + - x86/bugs: Drop one "mitigation" from dmesg + - x86/cpu/bugs: Make retpoline module warning conditional + - x86/cpufeatures: Clean up Spectre v2 related CPUID flags + - x86/retpoline: Simplify vmexit_fill_RSB() + - x86/speculation: Simplify indirect_branch_prediction_barrier() + - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - iio: adc/accel: Fix up module licenses + - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - KVM: nVMX: Eliminate vmcs02 pool + - KVM: VMX: introduce alloc_loaded_vmcs + - objtool: Improve retpoline alternative handling + - objtool: Add support for alternatives at the end of a section + - objtool: Warn on stripped section symbol + - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP + - x86/spectre: Check CONFIG_RETPOLINE in command line parser + - x86/entry/64: Remove the SYSCALL64 fast path + - x86/entry/64: Push extra regs right away + - x86/asm: Move 'status' from thread_struct to thread_info + - Documentation: Document array_index_nospec + - array_index_nospec: Sanitize speculative array de-references + - x86: Implement array_index_mask_nospec + - x86: Introduce barrier_nospec + - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec + - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end} + - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec + - x86/get_user: Use pointer masking to limit speculation + - x86/syscall: Sanitize syscall table de-references under speculation + - vfs, fdtable: Prevent bounds-check bypass via speculative execution + - nl80211: Sanitize array index in parse_txq_params + - x86/spectre: Report get_user mitigation for spectre_v1 + - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable" + - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel + - x86/speculation: Use Indirect Branch Prediction Barrier in context switch + - x86/paravirt: Remove 'noreplace-paravirt' cmdline option + - KVM: VMX: make MSR bitmaps per-VCPU + - x86/kvm: Update spectre-v1 mitigation + - x86/retpoline: Avoid retpolines for built-in __init functions + - x86/spectre: Simplify spectre_v2 command line parsing + - x86/pti: Mark constant arrays as __initconst + - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL + - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX + - KVM/x86: Add IBPB support + - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES + - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL + - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL + - serial: core: mark port as initialized after successful IRQ change + - fpga: region: release of_parse_phandle nodes after use + - Linux 4.15.2 + + * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792) + - net: phy: core: remove now uneeded disabling of interrupts + - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m + - net: socionext: Add Synquacer NetSec driver + - net: socionext: include linux/io.h to fix build + - net: socionext: Fix error return code in netsec_netdev_open() + + * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746) + - [Config] CONFIG_EDAC_GHES=y + + * support thunderx2 vendor pmu events (LP: #1747523) + - perf pmu: Pass pmu as a parameter to get_cpuid_str() + - perf tools arm64: Add support for get_cpuid_str function. + - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices + - perf vendor events arm64: Add ThunderX2 implementation defined pmu core + events + - perf pmu: Add check for valid cpuid in perf_pmu__find_map() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Miscellaneous Ubuntu changes + - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations + + -- Seth Forshee Wed, 07 Feb 2018 21:13:27 -0600 + +linux (4.15.0-7.8) bionic; urgency=medium + + * Bionic update to v4.15.1 stable release (LP: #1747169) + - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops + - tools/gpio: Fix build error with musl libc + - gpio: stmpe: i2c transfer are forbiden in atomic context + - gpio: Fix kernel stack leak to userspace + - ALSA: hda - Reduce the suspend time consumption for ALC256 + - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH + - crypto: aesni - handle zero length dst buffer + - crypto: aesni - fix typo in generic_gcmaes_decrypt + - crypto: aesni - add wrapper for generic gcm(aes) + - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm- + aesni + - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm- + aesni + - crypto: inside-secure - fix hash when length is a multiple of a block + - crypto: inside-secure - avoid unmapping DMA memory that was not mapped + - crypto: sha3-generic - fixes for alignment and big endian operation + - crypto: af_alg - whitelist mask and type + - HID: wacom: EKR: ensure devres groups at higher indexes are released + - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events + - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE + - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE + - igb: Free IRQs when device is hotplugged + - ima/policy: fix parsing of fsuuid + - scsi: aacraid: Fix udev inquiry race condition + - scsi: aacraid: Fix hang in kdump + - scsi: storvsc: missing error code in storvsc_probe() + - staging: lustre: separate a connection destroy from free struct kib_conn + - staging: ccree: NULLify backup_info when unused + - staging: ccree: fix fips event irq handling build + - tty: fix data race between tty_init_dev and flush of buf + - usb: option: Add support for FS040U modem + - USB: serial: pl2303: new device id for Chilitag + - USB: cdc-acm: Do not log urb submission errors on disconnect + - CDC-ACM: apply quirk for card reader + - USB: serial: io_edgeport: fix possible sleep-in-atomic + - usbip: prevent bind loops on devices attached to vhci_hcd + - usbip: list: don't list devices attached to vhci_hcd + - USB: serial: simple: add Motorola Tetra driver + - usb: f_fs: Prevent gadget unbind if it is already unbound + - usb: uas: unconditionally bring back host after reset + - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc() + - ANDROID: binder: remove waitqueue when thread exits. + - android: binder: use VM_ALLOC to get vm area + - mei: me: allow runtime pm for platform with D0i3 + - serial: 8250_of: fix return code when probe function fails to get reset + - serial: 8250_uniphier: fix error return code in uniphier_uart_probe() + - serial: 8250_dw: Revert "Improve clock rate setting" + - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS + - spi: imx: do not access registers while clocks disabled + - iio: adc: stm32: fix scan of multiple channels with DMA + - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels + - test_firmware: fix missing unlock on error in config_num_requests_store() + - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened + - Input: synaptics-rmi4 - do not delete interrupt memory too early + - x86/efi: Clarify that reset attack mitigation needs appropriate userspace + - Linux 4.15.1 + + * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume + (LP: #1744712) + - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume" + - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten" + version + + * apparmor profile load in stacked policy container fails (LP: #1746463) + - SAUCE: apparmor: fix display of .ns_name for containers + + -- Seth Forshee Sun, 04 Feb 2018 11:56:32 +0100 + +linux (4.15.0-6.7) bionic; urgency=low + + * upload urgency should be medium by default (LP: #1745338) + - [Packaging] update urgency to medium by default + + * Shutdown hang on 16.04 with iscsi targets (LP: #1569925) + - scsi: libiscsi: Allow sd_shutdown on bad transport + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1 + - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM" + - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default" + + [ Upstream Kernel Changes ] + + * Rebase to v4.15 + + -- Seth Forshee Mon, 29 Jan 2018 08:47:07 -0600 + +linux (4.15.0-5.6) bionic; urgency=low + + * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted + (LP: #1744077) + - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly + + * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC + (LP: #1743638) + - [d-i] Add qede to nic-modules udeb + + * boot failure on AMD Raven + WesternXT (LP: #1742759) + - SAUCE: drm/amdgpu: add atpx quirk handling (v2) + + * Unable to handle kernel NULL pointer dereference at isci_task_abort_task + (LP: #1726519) + - SAUCE: Revert "scsi: libsas: allow async aborts" + + * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939) + - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y + + * Miscellaneous Ubuntu changes + - Rebase to v4.15-rc7 + - [Config] CONFIG_CPU_ISOLATION=y + - [Config] Update annotations following config review + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - ubuntu: vbox -- update to 5.2.6-dfsg-1 + - ubuntu: vbox: build fixes for 4.15 + - ubuntu: vbox -- update to 5.2.6-dfsg-2 + - hio: updates for timer api changes in 4.15 + - enable hio build + - Rebase to v4.15-rc9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc9 + + -- Seth Forshee Mon, 22 Jan 2018 10:16:05 -0600 + +linux (4.15.0-4.5) bionic; urgency=low + + * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device (LP: #1741166) + - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010 + + * External HDMI monitor failed to show screen on Lenovo X1 series + (LP: #1738523) + - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series + + * Miscellaneous Ubuntu changes + - [Debian] autoreconstruct - add resoration of execute permissions + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Wed, 10 Jan 2018 10:24:22 -0600 + +linux (4.15.0-3.4) bionic; urgency=low + + * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281) + - SAUCE: make sure ubuntu/xr-usb-serial builds for x86 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc6 + + -- Seth Forshee Wed, 03 Jan 2018 20:20:43 -0600 + +linux (4.15.0-2.3) bionic; urgency=low + + * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux + 4.15.0-1.2 (LP: #1737752) + - x86/mm: Unbreak modules that use the DMA API + + * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147) + - [Config] CONFIG_SPI_INTEL_SPI_*=n + + * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image + and udebs (LP: #1521712) + - [Config] Include ibmvnic in nic-modules + + * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542) + - [Config] Enable support for emulation of deprecated ARMv8 instructions + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761) + - Enable zfs build + - [Debian] add icp to zfs-modules.ignore + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc4 + + -- Seth Forshee Mon, 18 Dec 2017 09:27:13 -0600 + +linux (4.15.0-1.2) bionic; urgency=low + + * Disabling zfs does not always disable module checks for the zfs modules + (LP: #1737176) + - [Packaging] disable zfs module checks when zfs is disabled + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64 + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc3 + + -- Seth Forshee Sun, 10 Dec 2017 22:07:19 -0600 + +linux (4.15.0-0.1) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.2.2-dfsg-2 + - ubuntu: vbox: build fixes for 4.15 + - disable hio build + - [Config] Update kernel lockdown options to fix build errors + - Disable zfs build + - SAUCE: Import aufs driver + - [Config] Enable AUFS config options + + [ Upstream Kernel Changes ] + + * Rebase to v4.15-rc2 + + -- Seth Forshee Fri, 08 Dec 2017 13:55:42 -0600 + +linux (4.14.0-11.13) bionic; urgency=low + + * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168) + + * CVE-2017-1000405 + - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d() + + * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463) + - SAUCE: mm: disable vma based swap readahead by default + - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM + + * Bionic update to v4.14.3 stable release (LP: #1735843) + - s390: fix transactional execution control register handling + - s390/noexec: execute kexec datamover without DAT + - s390/runtime instrumention: fix possible memory corruption + - s390/guarded storage: fix possible memory corruption + - s390/disassembler: add missing end marker for e7 table + - s390/disassembler: increase show_code buffer size + - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock + - ACPI / EC: Fix regression related to triggering source of EC event handling + - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq + - serdev: fix registration of second slave + - sched: Make resched_cpu() unconditional + - lib/mpi: call cond_resched() from mpi_powm() loop + - x86/boot: Fix boot failure when SMP MP-table is based at 0 + - x86/decoder: Add new TEST instruction pattern + - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing + - x86/entry/64: Add missing irqflags tracing to native_load_gs_index() + - perf/x86/intel: Hide TSX events when RTM is not supported + - arm64: Implement arch-specific pte_access_permitted() + - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE + - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE + - uapi: fix linux/tls.h userspace compilation error + - uapi: fix linux/rxrpc.h userspace compilation errors + - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP + - MIPS: ralink: Fix MT7628 pinmux + - MIPS: ralink: Fix typo in mt7628 pinmux function + - net: mvneta: fix handling of the Tx descriptor counter + - nbd: wait uninterruptible for the dead timeout + - nbd: don't start req until after the dead connection logic + - PM / OPP: Add missing of_node_put(np) + - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time + - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD + - PCI: hv: Use effective affinity mask + - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF + - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports + - ALSA: hda: Add Raven PCI ID + - dm integrity: allow unaligned bv_offset + - dm cache: fix race condition in the writeback mode overwrite_bio + optimisation + - dm crypt: allow unaligned bv_offset + - dm zoned: ignore last smaller runt zone + - dm mpath: remove annoying message of 'blk_get_request() returned -11' + - dm bufio: fix integer overflow when limiting maximum cache size + - ovl: Put upperdentry if ovl_check_origin() fails + - dm: allocate struct mapped_device with kvzalloc + - sched/rt: Simplify the IPI based RT balancing logic + - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver + - dm: fix race between dm_get_from_kobject() and __dm_destroy() + - dm: discard support requires all targets in a table support discards + - MIPS: Fix odd fp register warnings with MIPS64r2 + - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels + - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry + - MIPS: Fix an n32 core file generation regset support regression + - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1 + - MIPS: math-emu: Fix final emulation phase for certain instructions + - rt2x00usb: mark device removed when get ENOENT usb error + - mm/z3fold.c: use kref to prevent page free/compact race + - autofs: don't fail mount for transient error + - nilfs2: fix race condition that causes file system corruption + - fscrypt: lock mutex before checking for bounce page pool + - eCryptfs: use after free in ecryptfs_release_messaging() + - libceph: don't WARN() if user tries to add invalid key + - bcache: check ca->alloc_thread initialized before wake up it + - fs: guard_bio_eod() needs to consider partitions + - fanotify: fix fsnotify_prepare_user_wait() failure + - isofs: fix timestamps beyond 2027 + - btrfs: change how we decide to commit transactions during flushing + - f2fs: expose some sectors to user in inline data or dentry case + - NFS: Fix typo in nomigration mount option + - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()" + - nfs: Fix ugly referral attributes + - NFS: Avoid RCU usage in tracepoints + - NFS: revalidate "." etc correctly on "open". + - nfsd: deal with revoked delegations appropriately + - rtlwifi: rtl8192ee: Fix memory leak when loading firmware + - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time + - iwlwifi: fix firmware names for 9000 and A000 series hw + - md: fix deadlock error in recent patch. + - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write + - Bluetooth: btqcomsmd: Add support for BD address setup + - md/bitmap: revert a patch + - fsnotify: clean up fsnotify_prepare/finish_user_wait() + - fsnotify: pin both inode and vfsmount mark + - fsnotify: fix pinning group in fsnotify_prepare_user_wait() + - ata: fixes kernel crash while tracing ata_eh_link_autopsy event + - ext4: fix interaction between i_size, fallocate, and delalloc after a crash + - ext4: prevent data corruption with inline data + DAX + - ext4: prevent data corruption with journaling + DAX + - ALSA: pcm: update tstamp only if audio_tstamp changed + - ALSA: usb-audio: Add sanity checks to FE parser + - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU + - ALSA: usb-audio: Add sanity checks in v2 clock parsers + - ALSA: timer: Remove kernel warning at compat ioctl error paths + - ALSA: hda/realtek - Fix ALC275 no sound issue + - ALSA: hda: Fix too short HDMI/DP chmap reporting + - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization + - ALSA: hda/realtek - Fix ALC700 family no sound issue + - ASoC: sun8i-codec: Invert Master / Slave condition + - ASoC: sun8i-codec: Fix left and right channels inversion + - ASoC: sun8i-codec: Set the BCLK divider + - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method + - fix a page leak in vhost_scsi_iov_to_sgl() error recovery + - 9p: Fix missing commas in mount options + - fs/9p: Compare qid.path in v9fs_test_inode + - net/9p: Switch to wait_event_killable() + - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair() + - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics() + - scsi: lpfc: fix pci hot plug crash in timer management routines + - scsi: lpfc: fix pci hot plug crash in list_add call + - scsi: lpfc: Fix crash receiving ELS while detaching driver + - scsi: lpfc: Fix FCP hba_wqidx assignment + - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails + - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref + - iscsi-target: Fix non-immediate TMR reference leak + - target: fix null pointer regression in core_tmr_drain_tmr_list + - target: fix buffer offset in core_scsi3_pri_read_full_status + - target: Fix QUEUE_FULL + SCSI task attribute handling + - target: Fix caw_sem leak in transport_generic_request_failure + - target: Fix quiese during transport_write_pending_qf endless loop + - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK + - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid + - mtd: nand: Export nand_reset() symbol + - mtd: nand: atmel: Actually use the PM ops + - mtd: nand: omap2: Fix subpage write + - mtd: nand: Fix writing mtdoops to nand flash. + - mtd: nand: mtk: fix infinite ECC decode IRQ issue + - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence + - p54: don't unregister leds when they are not initialized + - block: Fix a race between blk_cleanup_queue() and timeout handling + - raid1: prevent freeze_array/wait_all_barriers deadlock + - genirq: Track whether the trigger type has been set + - irqchip/gic-v3: Fix ppi-partitions lookup + - lockd: double unregister of inetaddr notifiers + - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not + enabled + - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state + - KVM: SVM: obey guest PAT + - kvm: vmx: Reinstate support for CPUs without virtual NMI + - dax: fix PMD faults on zero-length files + - dax: fix general protection fault in dax_alloc_inode + - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status + - clk: ti: dra7-atl-clock: fix child-node lookups + - libnvdimm, dimm: clear 'locked' status on successful DIMM enable + - libnvdimm, pfn: make 'resource' attribute only readable by root + - libnvdimm, namespace: fix label initialization to use valid seq numbers + - libnvdimm, region : make 'resource' attribute only readable by root + - libnvdimm, namespace: make 'resource' attribute only readable by root + - svcrdma: Preserve CB send buffer across retransmits + - IB/srpt: Do not accept invalid initiator port names + - IB/cm: Fix memory corruption in handling CM request + - IB/hfi1: Fix incorrect available receive user context count + - IB/srp: Avoid that a cable pull can trigger a kernel crash + - IB/core: Avoid crash on pkey enforcement failed in received MADs + - IB/core: Only maintain real QPs in the security lists + - NFC: fix device-allocation error return + - spi-nor: intel-spi: Fix broken software sequencing codes + - i40e: Use smp_rmb rather than read_barrier_depends + - igb: Use smp_rmb rather than read_barrier_depends + - igbvf: Use smp_rmb rather than read_barrier_depends + - ixgbevf: Use smp_rmb rather than read_barrier_depends + - i40evf: Use smp_rmb rather than read_barrier_depends + - fm10k: Use smp_rmb rather than read_barrier_depends + - ixgbe: Fix skb list corruption on Power systems + - parisc: Fix validity check of pointer size argument in new CAS + implementation + - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX + - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX + - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id() + - powerpc/signal: Properly handle return value from uprobe_deny_signal() + - powerpc/64s: Fix masking of SRR1 bits on instruction fault + - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix 512T hint detection to use >= 128T + - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation + - powerpc/64s/hash: Fix fork() with 512TB process address space + - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary + - media: Don't do DMA on stack for firmware upload in the AS102 driver + - media: rc: check for integer overflow + - media: rc: nec decoder should not send both repeat and keycode + - cx231xx-cards: fix NULL-deref on missing association descriptor + - media: v4l2-ctrl: Fix flags field on Control events + - media: venus: fix wrong size on dma_free + - media: venus: venc: fix bytesused v4l2_plane field + - media: venus: reimplement decoder stop command + - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory + zone + - iwlwifi: fix wrong struct for a000 device + - iwlwifi: add a new a000 device + - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons + - iwlwifi: add new cards for a000 series + - iwlwifi: add new cards for 8265 series + - iwlwifi: add new cards for 8260 series + - iwlwifi: fix PCI IDs and configuration mapping for 9000 series + - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command + - e1000e: Fix error path in link detection + - e1000e: Fix return value test + - e1000e: Separate signaling for link check/link up + - e1000e: Avoid receiver overrun interrupt bursts + - e1000e: fix buffer overrun while the I219 is processing DMA transactions + - Linux 4.14.3 + + * Miscellaneous Ubuntu changes + - SAUCE: s390/topology: don't inline cpu_to_node + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 04 Dec 2017 09:08:07 -0600 + +linux (4.14.0-10.12) bionic; urgency=low + + * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901) + + * Miscellaneous Ubuntu changes + - SAUCE: Enable the ACPI kernel debugger and acpidbg tool + - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package + + -- Seth Forshee Tue, 28 Nov 2017 08:46:49 -0600 + +linux (4.14.0-9.11) bionic; urgency=low + + * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728) + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to + 0.7.3-1ubuntu1" + + -- Seth Forshee Mon, 27 Nov 2017 12:44:48 -0600 + +linux (4.14.0-8.10) bionic; urgency=low + + * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695) + + * Bionic update to v4.14.2 stable release (LP: #1734694) + - bio: ensure __bio_clone_fast copies bi_partno + - af_netlink: ensure that NLMSG_DONE never fails in dumps + - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets + - net: cdc_ncm: GetNtbFormat endian fix + - fealnx: Fix building error on MIPS + - net/sctp: Always set scope_id in sctp_inet6_skb_msgname + - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS + - serial: omap: Fix EFR write on RTS deassertion + - serial: 8250_fintek: Fix finding base_port with activated SuperIO + - tpm-dev-common: Reject too short writes + - rcu: Fix up pending cbs check in rcu_prepare_for_idle + - mm/pagewalk.c: report holes in hugetlb ranges + - ocfs2: fix cluster hang after a node dies + - ocfs2: should wait dio before inode lock in ocfs2_setattr() + - ipmi: fix unsigned long underflow + - mm/page_alloc.c: broken deferred calculation + - mm/page_ext.c: check if page_ext is not prepared + - coda: fix 'kernel memory exposure attempt' in fsync + - ipmi: Prefer ACPI system interfaces over SMBIOS ones + - Linux 4.14.2 + + * Bionic update to v4.14.1 stable release (LP: #1734693) + - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present + - dmaengine: dmatest: warn user when dma test times out + - media: imon: Fix null-ptr-deref in imon_probe + - media: dib0700: fix invalid dvb_detach argument + - crypto: dh - Fix double free of ctx->p + - crypto: dh - Don't permit 'p' to be 0 + - crypto: dh - Don't permit 'key' or 'g' size longer than 'p' + - crypto: brcm - Explicity ACK mailbox message + - USB: early: Use new USB product ID and strings for DbC device + - USB: usbfs: compute urb->actual_length for isochronous + - USB: Add delay-init quirk for Corsair K70 LUX keyboards + - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst + - USB: serial: metro-usb: stop I/O after failed open + - USB: serial: Change DbC debug device binding ID + - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update + - USB: serial: garmin_gps: fix I/O after failed probe and remove + - USB: serial: garmin_gps: fix memory leak on probe errors + - selftests/x86/protection_keys: Fix syscall NR redefinition warnings + - x86/MCE/AMD: Always give panic severity for UC errors in kernel context + - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface + - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table + - HID: cp2112: add HIDRAW dependency + - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection + - rpmsg: glink: Add missing MODULE_LICENSE + - staging: wilc1000: Fix bssid buffer offset in Txq + - staging: sm750fb: Fix parameter mistake in poke32 + - staging: ccree: fix 64 bit scatter/gather DMA ops + - staging: greybus: spilib: fix use-after-free after deregistration + - staging: rtl8188eu: Revert 4 commits breaking ARP + - spi: fix use-after-free at controller deregistration + - sparc32: Add cmpxchg64(). + - sparc64: mmu_context: Add missing include files + - sparc64: Fix page table walk for PUD hugepages + - Linux 4.14.1 + + * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660) + - [Config]: Set PANIC_TIMEOUT=10 on ppc64el + + * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users + (LP: #1732627) + - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1 + + -- Seth Forshee Mon, 27 Nov 2017 07:43:44 -0600 + +linux (4.14.0-7.9) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: add base infastructure for socket mediation + - SAUCE: apparmor: af_unix mediation + - SAUCE: LSM stacking: procfs: add smack subdir to attrs + - SAUCE: LSM stacking: LSM: manage credential security blobs + - SAUCE: LSM stacking: LSM: Manage file security blobs + - SAUCE: LSM stacking: LSM: manage task security blobs + - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs + - SAUCE: LSM stacking: LSM: general but not extreme module stacking + - SAUCE: LSM stacking: LSM: Complete task_alloc hook + - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs + - SAUCE: LSM stacking: fixup initialize task->security + - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code + - SAUCE: LSM stacking: add support for stacking getpeersec_stream + - SAUCE: LSM stacking: add stacking support to apparmor network hooks + - SAUCE: LSM stacking: fixup apparmor stacking enablement + - SAUCE: LSM stacking: fixup stacking kconfig + - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params + - SAUCE: LSM stacking: provide prctl interface for setting context + - SAUCE: LSM stacking: inherit current display LSM + - SAUCE: LSM stacking: keep an index for each registered LSM + - SAUCE: LSM stacking: verify display LSM + - SAUCE: LSM stacking: provide a way to specify the default display lsm + - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries + - SAUCE: LSM stacking: add /proc//attr/display_lsm + - SAUCE: LSM stacking: add Kconfig to set default display LSM + - SAUCE: LSM stacking: add configs for LSM stacking + - SAUCE: LSM stacking: check for invalid zero sized writes + - [Config] Run updateconfigs after merging LSM stacking + - [Config] CONFIG_AMD_MEM_ENCRYPT=y + + [ Upstream Kernel Changes ] + + * Rebase to v4.14 + + -- Seth Forshee Mon, 13 Nov 2017 08:12:08 -0600 + +linux (4.14.0-6.8) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - SAUCE: add workarounds to enable ZFS for 4.14 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc8 + + -- Seth Forshee Mon, 06 Nov 2017 11:39:00 -0600 + +linux (4.14.0-5.7) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Fix invocation of dh_prep for dbgsym packages + + -- Seth Forshee Tue, 31 Oct 2017 07:07:23 -0500 + +linux (4.14.0-4.5) bionic; urgency=low + + * Miscellaneous Ubuntu changes + - [Packaging] virtualbox -- reduce in kernel module versions + - vbox-update: Fix up KERN_DIR definitions + - ubuntu: vbox -- update to 5.2.0-dfsg-2 + - [Config] CONFIG_AMD_MEM_ENCRYPT=n + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc7 + + -- Seth Forshee Mon, 30 Oct 2017 13:29:20 -0500 + +linux (4.14.0-3.4) artful; urgency=low + + * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986) + - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3 + - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI + - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280 + + * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070) + - powerpc/64s: Add workaround for P9 vector CI load issue + + * Miscellaneous Ubuntu changes + - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties + - [Config] CONFIG_DRM_VBOXVIDEO=m + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Config] Reorder annotations file after enabling aufs + - vbox-update: Disable imported vboxvideo module + - ubuntu: vbox -- update to 5.1.30-dfsg-1 + - Enable vbox + - hio: Use correct sizes when initializing ssd_index_bits* arrays + - hio: Update io stat accounting for 4.14 + - Enable hio + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc5 + * Rebase to v4.14-rc6 + + -- Seth Forshee Mon, 23 Oct 2017 13:53:52 -0500 + +linux (4.14.0-2.3) artful; urgency=low + + * [Bug] USB controller failed to respond on Denverton after loading + intel_th_pci module (LP: #1715833) + - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH + + * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu + 17.10 (kernel 4.13) (LP: #1719290) + - SAUCE: s390: update zfcpdump_defconfig + + * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466) + - d-i: Add bnxt_en to nic-modules. + + * Miscellaneous Ubuntu changes + - [Config] Update annotations for 4.14-rc2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc3 + * Rebase to v4.14-rc4 + + -- Seth Forshee Wed, 11 Oct 2017 16:04:27 -0500 + +linux (4.14.0-1.2) artful; urgency=low + + * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045) + - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor + + * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091) + - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev + + * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland + (LP: #1718679) + - [Config] CONFIG_DRM_VBOXVIDEO=n + + * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734) + - [Config] Disable CONFIG_IPMMU_VMSA on arm64 + + * autopkgtest profile fails to build on armhf (LP: #1717920) + - [Packaging] autopkgtest -- disable d-i when dropping flavours + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_I2C_XLP9XX=m + - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc2 + + -- Seth Forshee Fri, 29 Sep 2017 09:09:11 -0400 + +linux (4.14.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable vbox build + - Disable hio build + - Disable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.14-rc1 + + -- Seth Forshee Tue, 19 Sep 2017 20:22:29 -0500 + +linux (4.13.0-11.12) artful; urgency=low + + * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699) + + * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399) + - s390/mm: fix local TLB flushing vs. detach of an mm address space + - s390/mm: fix race on mm->context.flush_mm + + * CVE-2017-1000251 + - Bluetooth: Properly check L2CAP config option output buffer length + + -- Seth Forshee Tue, 12 Sep 2017 10:18:38 -0500 + +linux (4.13.0-10.11) artful; urgency=low + + * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287) + + * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093) + - [Packaging] Add aufs-dkms to the Provides: for kernel packages + + * Artful update to v4.13.1 stable release (LP: #1716284) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + - USB: serial: option: add support for D-Link DWM-157 C1 + - usb: Add device quirk for Logitech HD Pro Webcam C920-C + - usb:xhci:Fix regression when ATI chipsets detected + - USB: musb: fix external abort on suspend + - ANDROID: binder: add padding to binder_fd_array_object. + - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES. + - USB: core: Avoid race of async_completed() w/ usbdev_release() + - staging/rts5208: fix incorrect shift to extract upper nybble + - staging: ccree: save ciphertext for CTS IV + - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks + - iio: adc: ti-ads1015: fix incorrect data rate setting update + - iio: adc: ti-ads1015: fix scale information for ADS1115 + - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set + - iio: adc: ti-ads1015: avoid getting stale result after runtime resume + - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks + - iio: adc: ti-ads1015: add adequate wait time to get correct conversion + - driver core: bus: Fix a potential double free + - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage + - binder: free memory on error + - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y + - crypto: caam/qi - fix compilation with DEBUG enabled + - thunderbolt: Fix reset response_type + - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock + - intel_th: pci: Add Cannon Lake PCH-H support + - intel_th: pci: Add Cannon Lake PCH-LP support + - ath10k: fix memory leak in rx ring buffer allocation + - drm/vgem: Pin our pages for dmabuf exports + - drm/ttm: Fix accounting error when fail to get pages for pool + - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly + - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter + - Bluetooth: Add support of 13d3:3494 RTL8723BE device + - iwlwifi: pci: add new PCI ID for 7265D + - dlm: avoid double-free on error path in dlm_device_{register,unregister} + - mwifiex: correct channel stat buffer overflows + - MCB: add support for SC31 to mcb-lpc + - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs + - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default + - drm/nouveau: Fix error handling in nv50_disp_atomic_commit + - workqueue: Fix flag collision + - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme + - cs5536: add support for IDE controller variant + - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE + - scsi: sg: recheck MMAP_IO request length with lock held + - of/device: Prevent buffer overflow in of_device_modalias() + - rtlwifi: Fix memory leak when firmware request fails + - rtlwifi: Fix fallback firmware loading + - Linux 4.13.1 + + * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477) + - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard + + * SRIOV: warning if unload VFs (LP: #1715073) + - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources + + * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578) + - i40e: avoid NVM acquire deadlock during NVM update + - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq + + * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted + twice when perf stat is done (perf:) (LP: #1714571) + - perf vendor events powerpc: Remove duplicate events + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Include vmd in storage-core-modules udeb + + * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064) + - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle + - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug + - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state + offline + + * Miscellaneous Ubuntu changes + - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + + -- Seth Forshee Sun, 10 Sep 2017 17:48:59 -0500 + +linux (4.13.0-9.10) artful; urgency=low + + * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145) + + * EDAC sbridge: Failed to register device with error -22. (LP: #1714112) + - [Config] CONFIG_EDAC_GHES=n + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-2 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13 + + -- Seth Forshee Tue, 05 Sep 2017 07:51:19 -0500 + +linux (4.13.0-8.9) artful; urgency=low + + * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103) + - SAUCE: apparmor: fix apparmorfs DAC access, permissions + + * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137) + - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64 + + * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping + Harrisonville SDP (LP: #1709257) + - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake + - EDAC, pnd2: Mask off the lower four bits of a BAR + - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR + - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device + - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after + reading BAR + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: Import aufs driver" + - SAUCE: Import aufs driver + - SAUCE: selftests/powerpc: Disable some ptrace selftests + - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x + - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el + - [Config] Disable CONFIG_MDIO_* options for s390x + - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x + - [Config] Update annotations for 4.13 + + -- Seth Forshee Thu, 31 Aug 2017 14:27:09 -0500 + +linux (4.13.0-7.8) artful; urgency=low + + * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904) + - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface + paths + + * Miscellaneous Ubuntu changes + - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled" + + * Miscellaneous upstream changes + - seccomp: Provide matching filter for introspection + - seccomp: Sysctl to display available actions + - seccomp: Operation for checking if an action is available + - seccomp: Sysctl to configure actions that are allowed to be logged + - seccomp: Selftest for detection of filter flag support + - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW + - seccomp: Action to log before allowing + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc7 + + -- Seth Forshee Mon, 28 Aug 2017 08:12:24 -0500 + +linux (4.13.0-6.7) artful; urgency=low + + * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481) + - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A + + * sort ABI files with C.UTF-8 locale (LP: #1712345) + - [Packaging] sort ABI files with C.UTF-8 locale + + * igb: Support using Broadcom 54616 as PHY (LP: #1712024) + - SAUCE: igb: add support for using Broadcom 54616 as PHY + + * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220) + - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes + - powerpc/mm/radix: Improve TLB/PWC flushes + - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range + + * Linux 4.12 refuses to load self-signed modules under Secure Boot with + properly enrolled keys (LP: #1712168) + - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification + + * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432) + - [Config] CONFIG_BLK_DEV_NVME=m for s390 + + * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0 + (LP: #1711298) + - [Config] CONFIG_INTEL_ATOMISP=n + + * Miscellaneous Ubuntu changes + - SAUCE: apparmor: af_unix mediation + + * Miscellaneous upstream changes + - apparmor: Fix shadowed local variable in unpack_trans_table() + - apparmor: Fix logical error in verify_header() + - apparmor: Fix an error code in aafs_create() + - apparmor: Redundant condition: prev_ns. in [label.c:1498] + - apparmor: add the ability to mediate signals + - apparmor: add mount mediation + - apparmor: cleanup conditional check for label in label_print + - apparmor: add support for absolute root view based labels + - apparmor: make policy_unpack able to audit different info messages + - apparmor: add more debug asserts to apparmorfs + - apparmor: add base infastructure for socket mediation + - apparmor: move new_null_profile to after profile lookup fns() + - apparmor: fix race condition in null profile creation + - apparmor: ensure unconfined profiles have dfas initialized + - apparmor: fix incorrect type assignment when freeing proxies + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc6 + + -- Seth Forshee Wed, 23 Aug 2017 08:10:38 -0500 + +linux (4.13.0-5.6) artful; urgency=low + + * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630) + - perf pmu-events: Support additional POWER8+ PVR in mapfile + - perf vendor events: Add POWER9 PMU events + - perf vendor events: Add POWER9 PVRs to mapfile + - SAUCE: perf vendor events powerpc: remove suffix in mapfile + - SAUCE: perf vendor events powerpc: Update POWER9 events + + * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171) + - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el + + * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for + kernels able to boot without initramfs (LP: #1700972) + - [Debian] Don't depend on initramfs-tools + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - SAUCE: aufs -- Add missing argument to loop_switch() call + - [Config] Enable aufs + - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3 + - Enable zfs build + - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall() + - [Packaging] switch up to debhelper 9 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc5 + + -- Seth Forshee Tue, 15 Aug 2017 09:24:16 -0500 + +linux (4.13.0-4.5) artful; urgency=low + + * Lenovo Yoga 910 Sensors (LP: #1708120) + - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips + + * Unable to install Ubuntu on the NVMe disk under VMD PCI domain + (LP: #1703339) + - [Config] Add vmd driver to generic inclusion list + + * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430) + - [Config] CONFIG_SATA_HIGHBANK=y + + * Miscellaneous Ubuntu changes + - ubuntu: vbox -- update to 5.1.26-dfsg-1 + - SAUCE: hio: Build fixes for 4.13 + - Enable hio build + - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1 + - [debian] use all rather than amd64 dkms debs for sync + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc4 + + -- Seth Forshee Tue, 08 Aug 2017 11:31:48 -0500 + +linux (4.13.0-3.4) artful; urgency=low + + * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495) + - [Packaging] tests -- reduce rebuild test to one flavour + - [Packaging] tests -- reduce rebuild test to one flavour -- use filter + + * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158) + - SAUCE: virtio_net: Revert mergeable buffer handling rework + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc3 + + -- Seth Forshee Mon, 31 Jul 2017 10:08:16 -0500 + +linux (4.13.0-2.3) artful; urgency=low + + * Change CONFIG_IBMVETH to module (LP: #1704479) + - [Config] CONFIG_IBMVETH=m + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc2 + + -- Seth Forshee Mon, 24 Jul 2017 13:58:08 -0500 + +linux (4.13.0-1.2) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Support sphinx-based kernel documentation + + -- Seth Forshee Thu, 20 Jul 2017 09:18:33 -0500 + +linux (4.13.0-0.1) artful; urgency=low + + * Miscellaneous Ubuntu changes + - Disable hio + - Disable zfs build + - ubuntu: vbox -- update to 5.1.24-dfsg-1 + + [ Upstream Kernel Changes ] + + * Rebase to v4.13-rc1 + + -- Seth Forshee Wed, 19 Jul 2017 15:09:31 -0500 + +linux (4.12.0-7.8) artful; urgency=low + + * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on + (LP: #1673564) + - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding + - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers + - KVM: arm64: Make kvm_condition_valid32() accessible from EL2 + - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2 + - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler + - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers + - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line + - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler + - KVM: arm64: vgic-v3: Add misc Group-0 handlers + - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers + - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line + - arm64: Add MIDR values for Cavium cn83XX SoCs + - arm64: Add workaround for Cavium Thunder erratum 30115 + - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler + - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler + - KVM: arm64: Enable GICv3 common sysreg trapping via command-line + - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped + - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access + - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access + + * hns: under heavy load, NIC may fail and require reboot (LP: #1704146) + - net: hns: Bugfix for Tx timeout handling in hns driver + + * New ACPI identifiers for ThunderX SMMU (LP: #1703437) + - iommu/arm-smmu: Plumb in new ACPI identifiers + + * Transparent hugepages should default to enabled=madvise (LP: #1703742) + - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default + + * Artful update to v4.12.1 stable release (LP: #1703858) + - driver core: platform: fix race condition with driver_override + - RDMA/uverbs: Check port number supplied by user verbs cmds + - usb: dwc3: replace %p with %pK + - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick + - usb: usbip: set buffer pointers to NULL after free + - Add USB quirk for HVR-950q to avoid intermittent device resets + - usb: Fix typo in the definition of Endpoint[out]Request + - USB: core: fix device node leak + - USB: serial: option: add two Longcheer device ids + - USB: serial: qcserial: new Sierra Wireless EM7305 device ID + - xhci: Limit USB2 port wake support for AMD Promontory hosts + - gfs2: Fix glock rhashtable rcu bug + - Add "shutdown" to "struct class". + - tpm: Issue a TPM2_Shutdown for TPM2 devices. + - tpm: fix a kernel memory leak in tpm-sysfs.c + - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error + - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings + - sched/fair, cpumask: Export for_each_cpu_wrap() + - sched/core: Implement new approach to scale select_idle_cpu() + - sched/numa: Use down_read_trylock() for the mmap_sem + - sched/numa: Override part of migrate_degrades_locality() when idle balancing + - sched/fair: Simplify wake_affine() for the single socket case + - sched/numa: Implement NUMA node level wake_affine() + - sched/fair: Remove effective_load() + - sched/numa: Hide numa_wake_affine() from UP build + - xen: avoid deadlock in xenbus driver + - crypto: drbg - Fixes panic in wait_for_completion call + - Linux 4.12.1 + + * cxlflash update request in the Xenial SRU stream (LP: #1702521) + - scsi: cxlflash: Combine the send queue locks + - scsi: cxlflash: Update cxlflash_afu_sync() to return errno + - scsi: cxlflash: Reset hardware queue context via specified register + - scsi: cxlflash: Schedule asynchronous reset of the host + - scsi: cxlflash: Handle AFU sync failures + - scsi: cxlflash: Track pending scsi commands in each hardware queue + - scsi: cxlflash: Flush pending commands in cleanup path + - scsi: cxlflash: Add scsi command abort handler + - scsi: cxlflash: Create character device to provide host management interface + - scsi: cxlflash: Separate AFU internal command handling from AFU sync + specifics + - scsi: cxlflash: Introduce host ioctl support + - scsi: cxlflash: Refactor AFU capability checking + - scsi: cxlflash: Support LUN provisioning + - scsi: cxlflash: Support AFU debug + - scsi: cxlflash: Support WS16 unmap + - scsi: cxlflash: Remove zeroing of private command data + - scsi: cxlflash: Update TMF command processing + - scsi: cxlflash: Avoid double free of character device + - scsi: cxlflash: Update send_tmf() parameters + - scsi: cxlflash: Update debug prints in reset handlers + + * make snap-pkg support (LP: #1700747) + - make snap-pkg support + + * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706) + - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge + + * arm64: fix crash reading /proc/kcore (LP: #1702749) + - fs/proc: kcore: use kcore_list type to check for vmalloc/module address + - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT + + * Opal and POWER9 DD2 (LP: #1702159) + - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9 + + * Data corruption with hio driver (LP: #1701316) + - SAUCE: hio: Fix incorrect use of enum req_opf values + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2 + - snapcraft.yaml: Sync with xenial + - [Config] CONFIG_CAVIUM_ERRATUM_30115=y + + * Miscellaneous upstream changes + - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and + MokSBState" + + -- Seth Forshee Fri, 14 Jul 2017 15:25:41 -0500 + +linux (4.12.0-6.7) artful; urgency=low + + * update ENA driver to 1.2.0k from net-next (LP: #1701575) + - net: ena: change return value for unsupported features unsupported return + value + - net: ena: add hardware hints capability to the driver + - net: ena: change sizeof() argument to be the type pointer + - net: ena: add reset reason for each device FLR + - net: ena: add support for out of order rx buffers refill + - net: ena: allow the driver to work with small number of msix vectors + - net: ena: use napi_schedule_irqoff when possible + - net: ena: separate skb allocation to dedicated function + - net: ena: use lower_32_bits()/upper_32_bits() to split dma address + - net: ena: update driver's rx drop statistics + - net: ena: update ena driver to version 1.2.0 + + * APST gets enabled against explicit kernel option (LP: #1699004) + - nvme: explicitly disable APST on quirked devices + + * Miscellaneous Ubuntu changes + - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40) + - SAUCE: hio updates for 4.12 + - SAUCE: Enable hio build + + -- Seth Forshee Wed, 05 Jul 2017 14:23:20 -0500 + +linux (4.12.0-5.6) artful; urgency=low + + * ERAT invalidate on context switch removal (LP: #1700819) + - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1 + + * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521) + - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9 + + * Miscellaneous Ubuntu changes + - d-i: Move qcom-emac from arm64 to shared nic-modules + + [ Upstream Kernel Changes ] + + * Rebase to v4.12 + + -- Seth Forshee Mon, 03 Jul 2017 07:52:02 -0500 + +linux (4.12.0-4.5) artful; urgency=low + + * aacraid driver may return uninitialized stack data to userspace + (LP: #1700077) + - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace + + * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651) + - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device + + * AACRAID for power9 platform (LP: #1689980) + - scsi: aacraid: Remove __GFP_DMA for raw srb memory + - scsi: aacraid: Fix DMAR issues with iommu=pt + - scsi: aacraid: Added 32 and 64 queue depth for arc natives + - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks + - scsi: aacraid: Remove reset support from check_health + - scsi: aacraid: Change wait time for fib completion + - scsi: aacraid: Log count info of scsi cmds before reset + - scsi: aacraid: Print ctrl status before eh reset + - scsi: aacraid: Using single reset mask for IOP reset + - scsi: aacraid: Rework IOP reset + - scsi: aacraid: Add periodic checks to see IOP reset status + - scsi: aacraid: Rework SOFT reset code + - scsi: aacraid: Rework aac_src_restart + - scsi: aacraid: Use correct function to get ctrl health + - scsi: aacraid: Make sure ioctl returns on controller reset + - scsi: aacraid: Enable ctrl reset for both hba and arc + - scsi: aacraid: Add reset debugging statements + - scsi: aacraid: Remove reference to Series-9 + - scsi: aacraid: Update driver version to 50834 + + * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700) + - SAUCE: drm: hibmc: Use set_busid function from drm core + + * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954) + - d-i: Add hibmc-drm to kernel-image udeb + + * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844) + - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2 + + * Miscellaneous Ubuntu changes + - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x + - [Config] CONFIG_ATA=n for s390x + - [Config] Update annotations for 4.12 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc7 + + -- Seth Forshee Mon, 26 Jun 2017 11:27:29 -0500 + +linux (4.12.0-3.4) artful; urgency=low + + * Miscellaneous upstream changes + - ufs: fix the logics for tail relocation + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc6 + + -- Seth Forshee Mon, 19 Jun 2017 14:50:39 -0500 + +linux (4.12.0-2.3) artful; urgency=low + + * CVE-2014-9900 + - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in + ethtool_get_wol() + + * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen) + (LP: #1671360) + - pinctrl/amd: Use regular interrupt instead of chained + + * extend-diff-ignore should use exact matches (LP: #1693504) + - [Packaging] exact extend-diff-ignore matches + + * Miscellaneous Ubuntu changes + - SAUCE: efi: Don't print secure boot state from the efi stub + - ubuntu: vbox -- Update to 5.1.22-dfsg-1 + - SAUCE: vbox fixes for 4.12 + - Re-enable virtualbox build + - [Config] CONFIG_ORANGEFS_FS=m + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7 + - Enable zfs build + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc4 + * Rebase to v4.12-rc5 + + -- Seth Forshee Sun, 11 Jun 2017 22:25:13 -0500 + +linux (4.12.0-1.2) artful; urgency=low + + * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337) + - [Config] Enable CONFIG_DRM_MGAG200 as module + + * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319) + - [Config] CONFIG_LIBIO=y on arm64 only + - SAUCE: LIBIO: Introduce a generic PIO mapping method + - SAUCE: OF: Add missing I/O range exception for indirect-IO devices + - [Config] CONFIG_HISILICON_LPC=y + - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07 + - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host + I/O + - SAUCE: LPC: Add the ACPI LPC support + - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts + - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO + + * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325) + - SAUCE: tty: Fix ldisc crash on reopened tty + + * Miscellaneous Ubuntu changes + - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa' + - Rebase to v4.12-rc3 + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc3 + + -- Seth Forshee Mon, 29 May 2017 20:56:29 -0500 + +linux (4.12.0-0.1) artful; urgency=low + + * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614) + - [Config] CONFIG_ARM64_LSE_ATOMICS=y + + * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914) + - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64 + + * exec'ing a setuid binary from a threaded program sometimes fails to setuid + (LP: #1672819) + - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct + + * Miscellaneous Ubuntu changes + - Update find-missing-sauce.sh to compare to artful + - Update dropped.txt + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring + - SAUCE: (efi-lockdown) efi: Add EFI signature data types + - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Disable virtualbox build + - Disable hio build + - SAUCE: securityfs: Replace CURRENT_TIME with current_time() + - Disable zfs build + - [Debian] Work out upstream tag for use with gen-auto-reconstruct + - SAUCE: Import aufs driver + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + - [Config] Enable aufs + - SAUCE: perf callchain: Include errno.h on x86 unconditinally + + [ Upstream Kernel Changes ] + + * Rebase to v4.12-rc2 + + -- Seth Forshee Sun, 21 May 2017 23:44:44 -0500 + +linux (4.11.0-3.8) artful; urgency=low + + [ Seth Forshee ] + + * Release Tracking Bug + - LP: #1690999 + + * apparmor_parser hangs indefinitely when called by multiple threads + (LP: #1645037) + - SAUCE: apparmor: fix lock ordering for mkdir + + * apparmor leaking securityfs pin count (LP: #1660846) + - SAUCE: apparmor: fix leak on securityfs pin count + + * apparmor reference count leak when securityfs_setup_d_inode\ () fails + (LP: #1660845) + - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode() + fails + + * apparmor not checking error if security_pin_fs() fails (LP: #1660842) + - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails + + * libvirt profile is blocking global setrlimit despite having no rlimit rule + (LP: #1679704) + - SAUCE: apparmor: fix complain mode failure for rlimit mediation + - apparmor: update auditing of rlimit check to provide capability information + + * apparmor: does not provide a way to detect policy updataes (LP: #1678032) + - SAUCE: apparmor: add policy revision file interface + + * apparmor does not make support of query data visible (LP: #1678023) + - SAUCE: apparmor: add label data availability to the feature set + + * apparmor query interface does not make supported query info available + (LP: #1678030) + - SAUCE: apparmor: add information about the query inteface to the feature set + + * change_profile incorrect when using namespaces with a compound stack + (LP: #1677959) + - SAUCE: apparmor: fix label parse for stacked labels + + * Regression in 4.4.0-65-generic causes very frequent system crashes + (LP: #1669611) + - apparmor: sync of apparmor 3.6+ (17.04) + + * Artful update to 4.11.1 stable release (LP: #1690814) + - dm ioctl: prevent stack leak in dm ioctl call + - drm/sti: fix GDP size to support up to UHD resolution + - power: supply: lp8788: prevent out of bounds array access + - brcmfmac: Ensure pointer correctly set if skb data location changes + - brcmfmac: Make skb header writable before use + - sparc64: fix fault handling in NGbzero.S and GENbzero.S + - refcount: change EXPORT_SYMBOL markings + - net: macb: fix phy interrupt parsing + - tcp: fix access to sk->sk_state in tcp_poll() + - geneve: fix incorrect setting of UDP checksum flag + - bpf: enhance verifier to understand stack pointer arithmetic + - bpf, arm64: fix jit branch offset related to ldimm64 + - tcp: fix wraparound issue in tcp_lp + - net: ipv6: Do not duplicate DAD on link up + - net: usb: qmi_wwan: add Telit ME910 support + - tcp: do not inherit fastopen_req from parent + - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header + - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string + - ipv6: initialize route null entry in addrconf_init() + - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf + - tcp: randomize timestamps on syncookies + - bnxt_en: allocate enough space for ->ntp_fltr_bmap + - bpf: don't let ldimm64 leak map addresses on unprivileged + - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path + - f2fs: sanity check segment count + - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..." + - xen: Revert commits da72ff5bfcb0 and 72a9b186292d + - block: get rid of blk_integrity_revalidate() + - Linux 4.11.1 + + * Module signing exclusion for staging drivers does not work properly + (LP: #1690908) + - SAUCE: Fix module signing exclusion in package builds + + * perf: qcom: Add L3 cache PMU driver (LP: #1689856) + - [Config] CONFIG_QCOM_L3_PMU=y + - perf: qcom: Add L3 cache PMU driver + + * No PMU support for ACPI-based arm64 systems (LP: #1689661) + - drivers/perf: arm_pmu: rework per-cpu allocation + - drivers/perf: arm_pmu: manage interrupts per-cpu + - drivers/perf: arm_pmu: split irq request from enable + - drivers/perf: arm_pmu: remove pointless PMU disabling + - drivers/perf: arm_pmu: define armpmu_init_fn + - drivers/perf: arm_pmu: fold init into alloc + - drivers/perf: arm_pmu: factor out pmu registration + - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs() + - drivers/perf: arm_pmu: handle no platform_device + - drivers/perf: arm_pmu: rename irq request/free functions + - drivers/perf: arm_pmu: split cpu-local irq request/free + - drivers/perf: arm_pmu: move irq request/free into probe + - drivers/perf: arm_pmu: split out platform device probe logic + - arm64: add function to get a cpu's MADT GICC table + - [Config] CONFIG_ARM_PMU_ACPI=y + - drivers/perf: arm_pmu: add ACPI framework + - arm64: pmuv3: handle !PMUv3 when probing + - arm64: pmuv3: use arm_pmu ACPI framework + + * Fix NVLINK2 TCE route (LP: #1690155) + - powerpc/powernv: Fix TCE kill on NVLink2 + + * CVE-2017-0605 + - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline() + + * Miscellaneous Ubuntu changes + - [Config] Restore powerpc arch to annotations file + - [Config] Disable runtime testing modules + - [Config] Disable drivers not needed on s390x + - [Config] Update annotations for 4.11 + - [Config] updateconfigs after apparmor updates + + * Miscellaneous upstream changes + - apparmor: use SHASH_DESC_ON_STACK + - apparmor: fix invalid reference to index variable of iterator line 836 + - apparmor: fix parameters so that the permission test is bypassed at boot + - apparmor: Make path_max parameter readonly + - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show() + - apparmorfs: Use seq_putc() in two functions + - apparmor: provide information about path buffer size at boot + - apparmor: add/use fns to print hash string hex value + + -- Seth Forshee Tue, 16 May 2017 00:39:13 -0500 + +linux (4.11.0-2.7) artful; urgency=low + + * kernel-wedge fails in artful due to leftover squashfs-modules d-i files + (LP: #1688259) + - Remove squashfs-modules files from d-i + - [Config] as squashfs-modules is builtin kernel-image must Provides: it + + * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297) + - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform." + - d-i: initrd needs qcom_emac on amberwing platform. + + * update for V3 kernel bits and improved multiple fan slice support + (LP: #1470091) + - SAUCE: fan: tunnel multiple mapping mode (v3) + + * Miscellaneous Ubuntu changes + - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5 + - Enable zfs + - SAUCE: fan: add VXLAN implementation + - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit + - SAUCE: (efi-lockdown) Add the ability to lock down access to the running + kernel image + - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot + mode + - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down + - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is + locked down + - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode + - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down + - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec + reboot + - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been + set + - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down + - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked + down + - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is + locked down + - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked + down + - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel + is locked down + - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel + has been locked down + - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is + locked down + - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is + locked down + - SAUCE: (efi-lockdown) Enable cold boot attack mitigation + - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the + kernel is locked down + - SAUCE: (efi-lockdown) scsi: Lock down the eata driver + - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked + down + - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL + - SAUCE: (efi-lockdown) Add EFI signature data types + - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader. + - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring + - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot + - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db + - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is + disabled + - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub + - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for + MokSBState + - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState + - [Config] Set values for UEFI secure boot lockdown options + - Update dropped.txt + + [ Upstream Kernel Changes ] + + * rebase to v4.11 + + -- Seth Forshee Fri, 05 May 2017 07:43:14 -0500 + +linux (4.11.0-1.6) artful; urgency=low + + * Miscellaneous Ubuntu changes + - [Debian] Use default compression for all packages + - SAUCE: (namespace) block_dev: Support checking inode permissions in + lookup_bdev() + - SAUCE: (namespace) block_dev: Check permissions towards block device inode + when mounting + - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode + when mounting + - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes + - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root + - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb() + - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set + security.* xattrs + - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw + filesystems + - SAUCE: (namespace) fuse: Add support for pid namespaces + - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns + - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace + or a descendant + - SAUCE: (namespace) fuse: Allow user namespace mounts + - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user + namespaces + - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts + - SAUCE: (namespace) ext4: Add module parameter to enable user namespace + mounts + - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is + opened for writing + + -- Seth Forshee Wed, 26 Apr 2017 10:08:29 -0500 + +linux (4.11.0-0.5) artful; urgency=low + + * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain + (LP: #1684971) + - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain + + * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups + (LP: #1470250) + - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails + + * Enable virtual scsi server driver for Power (LP: #1615665) + - SAUCE: Return TCMU-generated sense data to fabric module + + * include/linux/security.h header syntax error with !CONFIG_SECURITYFS + (LP: #1630990) + - SAUCE: (no-up) include/linux/security.h -- fix syntax error with + CONFIG_SECURITYFS=n + + * Miscellaneous Ubuntu changes + - SAUCE: Import aufs driver + - [Config] Enable aufs + - [Debian] Add script to update virtualbox + - ubuntu: vbox -- Update to 5.1.20-dfsg-2 + - Enable vbox + - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc8 + + -- Seth Forshee Tue, 25 Apr 2017 13:42:54 -0500 + +linux (4.11.0-0.4) zesty; urgency=low + + * POWER9: Improve performance on memory management (LP: #1681429) + - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm + flush + - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync + + * Miscellaneous Ubuntu changes + - find-missing-sauce.sh + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc7 + + -- Seth Forshee Tue, 18 Apr 2017 08:19:43 -0500 + +linux (4.11.0-0.3) zesty; urgency=low + + * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888) + - [Config] Disable CONFIG_HVC_UDBG on ppc64el + + * smartpqi driver needed in initram disk and installer (LP: #1680156) + - [Config] Add smartpqi to d-i + + * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315) + - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n + + * Miscellaneous Ubuntu changes + - [Config] flash-kernel should be a Breaks + - [Config] drop the info directory + - [Config] drop NOTES as obsolete + - [Config] drop changelog.historical as obsolete + - rebase to v4.11-rc6 + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc6 + + -- Tim Gardner Tue, 11 Apr 2017 07:16:52 -0600 + +linux (4.11.0-0.2) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc5 + + -- Tim Gardner Mon, 03 Apr 2017 08:26:07 +0100 + +linux (4.11.0-0.1) zesty; urgency=low + + [ Upstream Kernel Changes ] + + * rebase to v4.11-rc4 + - LP: #1591053 + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 + +linux (4.11.0-0.0) zesty; urgency=low + + * dummy entry + + -- Tim Gardner Mon, 20 Mar 2017 05:15:32 -0600 --- linux-oracle-5.4.0.orig/debian/cloud-tools/hv_get_dhcp_info +++ linux-oracle-5.4.0/debian/cloud-tools/hv_get_dhcp_info @@ -0,0 +1,55 @@ +#!/bin/bash + +# This example script retrieves the DHCP state of a given interface. +# In the interest of keeping the KVP daemon code free of distro specific +# information; the kvp daemon code invokes this external script to gather +# DHCP setting for the specific interface. +# +# Input: Name of the interface +# +# Output: The script prints the string "Enabled" to stdout to indicate +# that DHCP is enabled on the interface. If DHCP is not enabled, +# the script prints the string "Disabled" to stdout. +# +# Each Distro is expected to implement this script in a distro specific +# fashion. + +#set -x + +IF_FILE="/etc/network/interfaces" +NMCMD="nmcli" + +function checknetworkmanager { + #Assumes if $NMCMD exists, inteface exists and interface is not + # in $IF_FILE then dhcp is being used by NM + if hash $NMCMD >/dev/null 2>&1 ; then + if $NMCMD dev status |grep -q $1 ; then + echo "Enabled" + else + echo "Disabled" + fi + else + #Give up + echo "Disabled" + fi +} + +if [ -z $1 ] ; then echo "Disabled"; exit; fi + +if [ -e $IF_FILE ]; then + if grep -v -e "^#" $IF_FILE|grep -q $1 ; then + #interface exists so + if grep -q -e $1\.\*dhcp $IF_FILE; then + echo "Enabled"; exit; + else + echo "Disabled"; exit; + fi + else + checknetworkmanager $1 + exit + fi +else + checknetworkmanager $1 + exit +fi + --- linux-oracle-5.4.0.orig/debian/cloud-tools/hv_get_dns_info +++ linux-oracle-5.4.0/debian/cloud-tools/hv_get_dns_info @@ -0,0 +1,13 @@ +#!/bin/bash + +# This example script parses /etc/resolv.conf to retrive DNS information. +# In the interest of keeping the KVP daemon code free of distro specific +# information; the kvp daemon code invokes this external script to gather +# DNS information. +# This script is expected to print the nameserver values to stdout. +# Each Distro is expected to implement this script in a distro specific +# fashion. For instance on Distros that ship with Network Manager enabled, +# this script can be based on the Network Manager APIs for retrieving DNS +# entries. + +cat /etc/resolv.conf 2>/dev/null | awk '/^nameserver/ { print $2 }' --- linux-oracle-5.4.0.orig/debian/cloud-tools/hv_set_ifconfig +++ linux-oracle-5.4.0/debian/cloud-tools/hv_set_ifconfig @@ -0,0 +1,288 @@ +#!/usr/bin/python3 +# +# hv_set_ifconfig -- take the hv_kvp_daemon generated configuration +# file and apply it to the Ubuntu configuration. +# + +# CONFIG example: +# HWADDR=11:22:33:44:55:66 +# DEVICE=foo1 +# DHCP=yes + +# CONFIG example: +# HWADDR=11:22:33:44:55:66 +# DEVICE=foo1 +# IPADDR=192.168.99.10 +# GATEWAY=192.168.99.1 +# DNS1=192.168.88.250 +# IPADDR2=192.168.99.11 +# IPV6ADDR=2001:DB8:99::10 +# IPV6NETMASK=64 +# IPV6_DEFAULTGW=2001:DB8:99::10 + +# set interfaces in hv_kvp_daemon style +import fileinput +import sys +import errno +import os +import shutil +import tempfile +import subprocess + +if_filename="/etc/network/interfaces" + +# Drop our output (XXX?) +sys.stdout = open(os.devnull, 'w') +sys.stderr = open(os.devnull, 'w') + +# Confirm we can open the network configuration. +try: + if_file=open(if_filename,"r+") +except IOError as e: + exit(e.errno) +else: + if_file.close() + +# Usage: hv_set_ifconfig +if len(sys.argv) != 2 : + exit(errno.EINVAL) + +# +# Here is the format of the ip configuration file: +# +# HWADDR=macaddr +# DEVICE=interface name +# BOOTPROTO= (where is "dhcp" if DHCP is configured +# or "none" if no boot-time protocol should be used) +# +# IPADDR0=ipaddr1 +# IPADDR1=ipaddr2 +# IPADDRx=ipaddry (where y = x + 1) +# +# NETMASK0=netmask1 +# NETMASKx=netmasky (where y = x + 1) +# +# GATEWAY=ipaddr1 +# GATEWAYx=ipaddry (where y = x + 1) +# +# DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc) +# +# IPV6 addresses will be tagged as IPV6ADDR, IPV6 gateway will be +# tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as +# IPV6NETMASK. +# + +kvp=dict(line.strip().split("=") for line in fileinput.input()) + +# Setting the hwaddress to something azure is not expecting is fatal +# to networking. +if not "HWADDR" in kvp : + exit(errno.EPROTO) + +# Confirm we have a device specified. +if not "DEVICE" in kvp : + exit(1) + +autolist = [] +output=[] +basename=kvp["DEVICE"] + +# DNS entries will go with the first interface and there can be a max +# of three. These will be emitted with the first interface. +dns = [] +for count in (1, 2, 3): + key = "DNS" + str(count) + if key in kvp: + dns += [kvp[key]] +dns_emitted = False + +# IPV4 may either be dhcp or static. +if ("DHCP" in kvp and kvp["DHCP"] == "yes") or \ + ("BOOTPROTO" in kvp and kvp["BOOTPROTO"] == "dhcp"): + autolist.append(basename) + output += ["iface " + basename + " inet dhcp"] + output += [""] +else: + # Matchup the interface specific lines + + # No real max for the number of interface + aliases ... + # only required is the address (but mate everything up that comes in. + + # IPv4 -- ensure we sort by numeric suffixes. + v4names = [ int(name[6:]) for name in kvp.keys() if name.startswith("IPADDR") ] + v4names.sort() + + for if_count in v4names: + ifname = basename + which = str(if_count) + + if if_count: + ifname += ":" + str(if_count) + which_gw = which + else: + which_gw = "" + + if not ifname in autolist: + autolist += [ifname] + + output += [ "iface " + ifname + " inet static" ] + output += [ "\t" + "address " + kvp["IPADDR" + which] ] + if "NETMASK" + which in kvp: + output += [ "\tnetmask " + kvp["NETMASK" + which] ] + if "GATEWAY" + which_gw in kvp: + output += ["\tgateway " + kvp["GATEWAY" + which_gw]] + + if not dns_emitted: + dns_emitted = True + output += ["\tdns-nameservers " + ' '.join(dns)] + output += [""] + +# IPv6 requires a netmask +# If an ipv6 exists, you'll want to turn off /proc/sys/net/ipv6/conf/all/autoconf with +# echo 0 > /proc/sys/net/ipv6/conf/all/autoconf +v6names = [ int(name[8:]) for name in kvp.keys() if name.startswith("IPV6ADDR") ] +v6names.sort() + +for if6_count in v6names: + ifname = basename + which = str(if6_count) + + if if6_count: + ifname += ":" + str(if6_count) + which_gw = which + else: + which_gw = "" + + if not ifname in autolist: + autolist += [ifname] + + if "IPV6NETMASK" + which in kvp: + output += [ "iface " + ifname + " inet6 static"] + output += [ "\taddress " + kvp["IPV6ADDR" + which]] + output += [ "\tnetmask " + kvp["IPV6NETMASK" + which]] + if "IPV6_DEFAULTGW" + which_gw in kvp: + output += [ "\tgateway " + kvp["IPV6_DEFAULTGW" + which_gw] ] + if not dns_emitted: + dns_emitted = True + output += ["\tdns-nameservers " + ' '.join(dns)] + output += [""] + +# Mark this new interface for automatic up. +if len(autolist): + output = ["auto "+" ".join(autolist)] + output + +print("===================================") +print(output) +print("===================================") + + +# Time to clean out the existing interface file + +# Markers. +start_mark = "# The following stanza(s) added by hv_set_ifconfig" +end_mark = "#End of hv_set_ifconfig stanzas" + +f=open(if_filename,"r") +flines=f.readlines() +f.close() +newfile=[] +pitchstanza=0 +inastanza=0 +stanza=[] +prev_line=None +for line in flines: + if line.startswith("auto"): + if inastanza: + if not pitchstanza: + newfile.extend(stanza) + stanza=[] + inastanza=0 + newline="" + autoline=line.strip().split(" ") + for word in autoline: + if (not word == basename) and (not word.startswith(basename+":")): + newline+=word + " " + newline = newline.strip() + if not newline == "auto": + newfile += [newline.strip()] + elif line.startswith(("iface","mapping","source")): + '''Read a stanza''' + '''A Stanza can also start with allow- ie allow-hotplug''' + if inastanza: + if not pitchstanza: + newfile.extend(stanza) + stanza=[] + inastanza=1 + pitchstanza=0 + autoline=line.strip().split(" ") + for word in autoline: + if (word == basename) or (word.startswith(basename+":")): + pitchstanza=1 + if not pitchstanza: + stanza+=[line.strip()] + elif line.strip() in (start_mark, end_mark): + if inastanza: + if not pitchstanza: + newfile.extend(stanza) + stanza=[] + inastanza = 0 + pitchstanza = 0 + # Deduplicate markers. + if line != prev_line: + newfile += [line.strip()] + else: + if inastanza: + if not pitchstanza: + stanza+=[line.strip()] + else: + if not pitchstanza: + newfile += [line.strip()] + prev_line=line + +# Include pending stanza if any. +if inastanza and not pitchstanza: + newfile.extend(stanza) + + +def emit(line): + print(line) + output = line + "\n" + os.write(fd, output.encode('utf-8')) + +# Insert the new output at the end and inside the existing markers if found. +emitted = False +fd, path = tempfile.mkstemp() +for line in newfile: + if line == end_mark: + emit("\n".join(output)) + emitted = True + emit(line) +if not emitted: + emit(start_mark) + emit("\n".join(output)) + emit(end_mark) +os.close(fd) + +shutil.copy(path,if_filename) +os.chmod(if_filename,0o644) + +#print("TMPFILE is at: " + path) +#print("Copied file is at: " + if_filename) + +try: + retcode = subprocess.call("ifdown "+basename , shell=True) + if retcode < 0: + print("Child was terminated by signal", -retcode, file=sys.stderr) + else: + print("Child returned", retcode, file=sys.stderr) +except OSError as e: + print("Execution failed:", e, file=sys.stderr) + +try: + retcode = subprocess.call("ifup "+basename , shell=True) + if retcode < 0: + print("Child was terminated by signal", -retcode, file=sys.stderr) + else: + print("Child returned", retcode, file=sys.stderr) +except OSError as e: + print("Execution failed:", e, file=sys.stderr) --- linux-oracle-5.4.0.orig/debian/commit-templates/bumpabi +++ linux-oracle-5.4.0/debian/commit-templates/bumpabi @@ -0,0 +1,3 @@ +UBUNTU: Bump ABI + +Ignore: yes --- linux-oracle-5.4.0.orig/debian/commit-templates/config-updates +++ linux-oracle-5.4.0/debian/commit-templates/config-updates @@ -0,0 +1,15 @@ +# +# This template is used for commit messages that don't need to +# show up in debian/changelog. Administrative stuff like config +# updates, ABI bumps, etc. Setting 'Ignore: yes' prevents +# 'debian/rules insertchanges' from inserting this commit meesage +# as a changelog entry. +# +# Please give a one-line description of the config change followed +# by a detailed explanation if necessary + +UBUNTU: [Config] XXXX + +# BugLink: http://bugs.launchpad.net/bugs/ +# Ignore: yes +# Other text below here. --- linux-oracle-5.4.0.orig/debian/commit-templates/external-driver +++ linux-oracle-5.4.0/debian/commit-templates/external-driver @@ -0,0 +1,20 @@ +# Ubuntu external driver commit. +# +# NOTE: This gets reformatted for README.Ubuntu-External-Drivers and +# debian/changelog. +# +# This is only needed when a driver is added, updated or removed. It is +# not needed when patches or fixes are applied to the driver. If the +# driver is being removed, add the line: +# +# Removing: yes +# +# to the commit, and you can remove all other tags (except UBUNTU:). +# +UBUNTU: + +ExternalDriver: +Description: +Url: +Mask: +Version: --- linux-oracle-5.4.0.orig/debian/commit-templates/missing-modules +++ linux-oracle-5.4.0/debian/commit-templates/missing-modules @@ -0,0 +1,3 @@ +UBUNTU: build/modules: Add modules that have intentionally gone missing + +Ignore: yes --- linux-oracle-5.4.0.orig/debian/commit-templates/newrelease +++ linux-oracle-5.4.0/debian/commit-templates/newrelease @@ -0,0 +1,3 @@ +UBUNTU: Start new release + +Ignore: yes --- linux-oracle-5.4.0.orig/debian/commit-templates/sauce-patch +++ linux-oracle-5.4.0/debian/commit-templates/sauce-patch @@ -0,0 +1,40 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# +# SAUCE refers to the fact that this patch might not go upstream, but we need to +# carry it to successive releases. In most cases you DONOT want to use this +# template. +# +# An example of a SAUCE patch is the ACPI DSDT-in-initramfs patch which has been +# refused upstream, but still provides useful functionality to users with broken +# BIOSes. +# +#------------------------------------------------------------------------- +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# BugLink is a URL to a Malone bug. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: SAUCE: + + + +# OriginalAuthor: +# OriginalLocation: +# BugLink: http://bugs.launchpad.net/bugs/ +# Ignore: yes +# Other text below here. --- linux-oracle-5.4.0.orig/debian/commit-templates/upstream-patch +++ linux-oracle-5.4.0/debian/commit-templates/upstream-patch @@ -0,0 +1,27 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# BugLink is a URL to a Malone bug. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: [Upstream] + +# OriginalAuthor: +# OriginalLocation: +# BugLink: http://bugs.launchpad.net/bugs/ +# Ignore: yes +# Other text below here. --- linux-oracle-5.4.0.orig/debian/compat +++ linux-oracle-5.4.0/debian/compat @@ -0,0 +1 @@ +9 --- linux-oracle-5.4.0.orig/debian/control +++ linux-oracle-5.4.0/debian/control @@ -0,0 +1,216 @@ +Source: linux-oracle +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +XSC-Ubuntu-Compatible-Signing: ubuntu/4 pro/3 +Standards-Version: 3.9.4.0 +Build-Depends: + debhelper (>= 9), + dh-systemd, + cpio, + kernel-wedge, + kmod , + libcap-dev , + makedumpfile [amd64] , + libelf-dev , + libnewt-dev , + libiberty-dev , + default-jdk-headless , + java-common , + rsync , + libdw-dev , + libpci-dev , + pkg-config , + flex , + bison , + libunwind8-dev [amd64] , + liblzma-dev , + openssl , + libssl-dev , + libaudit-dev , + bc , + gawk , + libudev-dev , + autoconf , + automake , + libtool , + uuid-dev , + libnuma-dev [amd64] , + dkms , + dwarfdump , + curl , + lz4 [amd64] , + dwarves [amd64 arm64 armhf ppc64el s390x] , +Build-Depends-Indep: + xmlto , + docbook-utils , + ghostscript , + fig2dev , + bzip2 , + sharutils , + asciidoc , + python3-sphinx , + python3-sphinx-rtd-theme , + fontconfig , + python3-docutils , +Vcs-Git: git://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-oracle/+git/focal +XS-Testsuite: autopkgtest +#XS-Testsuite-Depends: gcc-4.7 binutils + +Package: linux-oracle-headers-5.4.0-1144 +Build-Profiles: +Architecture: all +Multi-Arch: foreign +Section: devel +Priority: optional +Depends: ${misc:Depends}, coreutils +Description: Header files related to Oracle Linux kernel version 5.4.0 + This package provides kernel header files for version 5.4.0, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-oracle-headers-5.4.0-1144/debian.README.gz for details + +Package: linux-oracle-tools-5.4.0-1144 +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common +Description: Oracle Linux kernel version specific tools for version 5.4.0-1144 + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version 5.4.0-1144 on + 64 bit x86. + You probably want to install linux-tools-5.4.0-1144-. + + +Package: linux-image-unsigned-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: kernel +Priority: optional +Provides: linux-image, fuse-module, aufs-dkms, kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64], ${linux:rprovides} +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-5.4.0-1144-oracle +Recommends: grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-ieee1275 [ppc64el] | grub-efi-arm64 [arm64] , initramfs-tools | linux-initramfs-tool +Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x], initramfs-tools (<< 0.130ubuntu3.6) +Conflicts: linux-image-5.4.0-1144-oracle +Suggests: fdutils, linux-oracle-doc-5.4.0 | linux-oracle-source-5.4.0, linux-oracle-tools, linux-headers-5.4.0-1144-oracle +Description: Oracle Linux kernel image for version 5.4.0 on 64 bit x86 SMP + This package contains the unsigned Oracle Linux kernel image for version 5.4.0 on + 64 bit x86 SMP. + . + Supports Oracle processors. + . + Geared toward Oracle Cloud systems. + . + You likely do not want to install this package directly. Instead, install + the linux-oracle meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${linux:BuiltUsing} +Description: Oracle Linux kernel extra modules for version 5.4.0 on 64 bit x86 SMP + Contains the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Oracle processors. + . + Geared toward Oracle Cloud systems. + . + You likely do not want to install this package directly. Instead, install + the linux-oracle meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-modules-extra-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-image-5.4.0-1144-oracle | linux-image-unsigned-5.4.0-1144-oracle, crda | wireless-crda +Description: Oracle Linux kernel extra modules for version 5.4.0 on 64 bit x86 SMP + This package contains the Oracle Linux kernel extra modules for version 5.4.0 on + 64 bit x86 SMP. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Oracle processors. + . + Geared toward Oracle Cloud systems. + . + You likely do not want to install this package directly. Instead, install + the linux-oracle meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends}, linux-oracle-headers-5.4.0-1144, ${shlibs:Depends} +Provides: linux-headers, linux-headers-3.0 +Description: Oracle Linux kernel headers for version 5.4.0 on 64 bit x86 SMP + This package provides kernel header files for version 5.4.0 on + 64 bit x86 SMP. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-5.4.0-1144/debian.README.gz for details. + +Package: linux-image-unsigned-5.4.0-1144-oracle-dbgsym +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends} +Provides: linux-debug +Description: Oracle Linux kernel debug image for version 5.4.0 on 64 bit x86 SMP + This package provides the unsigned kernel debug image for version 5.4.0 on + 64 bit x86 SMP. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-tools-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends}, linux-oracle-tools-5.4.0-1144 +Description: Oracle Linux kernel version specific tools for version 5.4.0-1144 + This package provides the architecture dependant parts for kernel + version locked tools (such as perf and x86_energy_perf_policy) for + version 5.4.0-1144 on + 64 bit x86. + +Package: linux-cloud-tools-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: devel +Priority: optional +Depends: ${misc:Depends}, linux-oracle-cloud-tools-5.4.0-1144 +Description: Oracle Linux kernel version specific cloud tools for version 5.4.0-1144 + This package provides the architecture dependant parts for kernel + version locked tools for cloud for version 5.4.0-1144 on + 64 bit x86. + +Package: linux-buildinfo-5.4.0-1144-oracle +Build-Profiles: +Architecture: amd64 arm64 +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${linux:BuiltUsing} +Description: Linux kernel buildinfo for version 5.4.0 on 64 bit x86 SMP + This package contains the Linux kernel buildinfo for version 5.4.0 on + 64 bit x86 SMP. + . + You likely do not want to install this package. --- linux-oracle-5.4.0.orig/debian/control.d/flavour-buildinfo.stub +++ linux-oracle-5.4.0/debian/control.d/flavour-buildinfo.stub @@ -0,0 +1,13 @@ + +Package: linux-buildinfo-PKGVER-ABINUM-FLAVOUR +Build-Profiles: +Architecture: ARCH +Section: kernel +Priority: optional +Depends: ${misc:Depends}, ${shlibs:Depends} +Built-Using: ${linux:BuiltUsing} +Description: Linux kernel buildinfo for version PKGVER on DESC + This package contains the Linux kernel buildinfo for version PKGVER on + DESC. + . + You likely do not want to install this package. --- linux-oracle-5.4.0.orig/debian/copyright +++ linux-oracle-5.4.0/debian/copyright @@ -0,0 +1,29 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-oracle-5.4.0.orig/debian/debian.env +++ linux-oracle-5.4.0/debian/debian.env @@ -0,0 +1 @@ +DEBIAN=debian.oracle --- linux-oracle-5.4.0.orig/debian/docs/README.inclusion-list +++ linux-oracle-5.4.0/debian/docs/README.inclusion-list @@ -0,0 +1,51 @@ +This README describes the reason for, and the use of, module +inclusion lists. + +The original Hardy release had the notion of sub-flavours, +e.g., a flavour that was constructed as a subset of an existing flavour. +For example, the virtual flavour was extracted from the server flavour using +a subset of the server flavour modules. However, there were some difficult +mainteneance issues with regard to packaging, make rules, and scripts. This +re-implementation of the sub-flavours philosophy is hopefully simpler, +and retrofitable to all releases. + +A module inclusion list looks at the problem of of constructing a package +from the perspective of what modules do we _want_ in the package, as opposed +to what modules we _don't_ want. As the kernel matures, more and more devices are added +which makes the problem of configuration maintenance a real pain in the ass. +If we took the approach of disabling all of the config options that we don't want, +then the differences between flavours will quickly become quite large, making +it difficult to quickly compare the individual flavour configs. Each time a +new config option is added then we also have to make a decision about disabling in +order to continue to keep the minimal number of modules. + +A module inclusion list is applied on a per-flavour basis. For example, +debian./control.d/${flavour}.inclusion-list. For example, the +config for virtual is very close to server and generic, but the inclusion list +causes the virtual package to be constructed with _only_ the modules described +in the inclusion list. + +The inclusion list format is a simple bash regular expression list of files. For example, + +arch/*/{crypto,kernel,oprofile} +drivers/acpi/* +drivers/ata/ahci.ko + +These 3 regular expression forms are suitable for expansion by bash and as inputs to 'find'. +See debian/scripts/module-inclusion for details. + +There are 2 log files created as a side effect of the application of the module +inclusion list; $(flavour).inclusion-list.log and $(flavour).depmod.log. + +$(flavour).inclusion-list.log : This log is created while the inclusion list +modules are being copied. If any are missing, then those warnings go in this log. +While its not considered a fatal error, you should endevour to correct your inclusion +list such that there are no missing modules. + +$(flavour).depmod.log : The log is created as a result of running depmod on the +resulting set of modules. If there are missing symbols then you'll find that information +here. Again, you should modify your inclusion list such that there are no missing +symbols. + +Tim Gardner +June 2, 2010 --- linux-oracle-5.4.0.orig/debian/gbp.conf +++ linux-oracle-5.4.0/debian/gbp.conf @@ -0,0 +1,2 @@ +[buildpackage] +debian-tag = Ubuntu-oracle-%(version)s --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.service +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.service @@ -0,0 +1,14 @@ +# On Azure/Hyper-V systems start the hv_fcopy_daemon +# +# author "Andy Whitcroft " +[Unit] +Description=Hyper-V File Copy Protocol Daemon +ConditionVirtualization=microsoft +ConditionPathExists=/dev/vmbus/hv_fcopy +BindsTo=sys-devices-virtual-misc-vmbus\x21hv_fcopy.device + +[Service] +ExecStart=/usr/sbin/hv_fcopy_daemon -n + +[Install] +WantedBy=multi-user.target --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.udev +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.udev @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="vmbus/hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-fcopy-daemon.service" --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.upstart +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.upstart @@ -0,0 +1,22 @@ +# On Azure/Hyper-V systems start the hv_fcopy_daemon +# +description "Hyper-V File Copy Protocol Daemon" +author "Andy Whitcroft " + +start on runlevel [2345] +stop on runlevel [!2345] +console log + +pre-start script + if [ -e "/etc/default/hv-kvp-daemon-init" ]; then + . /etc/default/hv-kvp-daemon-init + fi + [ "$RUN_FCOPY_DAEMON" -eq 0 ] && { stop; exit 0; } + if [ -d /sys/class/dmi/id/. ]; then + read company " +[Unit] +Description=Hyper-V KVP Protocol Daemon +ConditionVirtualization=microsoft +ConditionKernelCommandLine=!snapd_recovery_mode +DefaultDependencies=no +BindsTo=sys-devices-virtual-misc-vmbus\x21hv_kvp.device +After=sys-devices-virtual-misc-vmbus\x21hv_kvp.device systemd-remount-fs.service +Before=shutdown.target cloud-init-local.service walinuxagent.service +Conflicts=shutdown.target +RequiresMountsFor=/var/lib/hyperv +ConditionPathExists=/dev/vmbus/hv_kvp + +[Service] +ExecStart=/usr/sbin/hv_kvp_daemon -n + +[Install] +WantedBy=multi-user.target --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.udev +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-kvp-daemon.udev @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="vmbus/hv_kvp", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-kvp-daemon.service" --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart @@ -0,0 +1,22 @@ +# On Azure/Hyper-V systems start the hv_kvp_daemon +# +description "Hyper-V KVP Protocol Daemon" +author "Adam Conrad " + +start on runlevel [2345] +stop on runlevel [!2345] +console log + +pre-start script + if [ -e "/etc/default/hv-kvp-daemon-init" ]; then + . /etc/default/hv-kvp-daemon-init + fi + [ "$RUN_KVP_DAEMON" = 0 ] && { stop; exit 0; } + if [ -d /sys/class/dmi/id/. ]; then + read company " +[Unit] +Description=Hyper-V VSS Protocol Daemon +ConditionVirtualization=microsoft +ConditionPathExists=/dev/vmbus/hv_vss +BindsTo=sys-devices-virtual-misc-vmbus\x21hv_vss.device + +[Service] +ExecStart=/usr/sbin/hv_vss_daemon -n + +[Install] +WantedBy=multi-user.target --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.udev +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-vss-daemon.udev @@ -0,0 +1 @@ +SUBSYSTEM=="misc", KERNEL=="vmbus/hv_vss", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-vss-daemon.service" --- linux-oracle-5.4.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.upstart +++ linux-oracle-5.4.0/debian/linux-cloud-tools-common.hv-vss-daemon.upstart @@ -0,0 +1,22 @@ +# On Azure/Hyper-V systems start the hv_vss_daemon +# +description "Hyper-V VSS Protocol Daemon" +author "Ben Howard " + +start on runlevel [2345] +stop on runlevel [!2345] +console log + +pre-start script + if [ -e "/etc/default/hv-kvp-daemon-init" ]; then + . /etc/default/hv-kvp-daemon-init + fi + [ "$RUN_VSS_DAEMON" -eq 0 ] && { stop; exit 0; } + if [ -d /sys/class/dmi/id/. ]; then + read company +# + +DEBIAN=$(shell awk -F= '($$1 == "DEBIAN") { print $$2 }' $(DEBIAN)/control.stub; + flavours="$(sort $(wildcard $(DEBIAN)/control.d/vars.* $(DEBIAN)/sub-flavours/*.vars))";\ + for i in $$flavours; do \ + $(SHELL) $(DROOT)/scripts/control-create $$i "$(any_signed)" | \ + sed -e 's/PKGVER/$(release)/g' \ + -e 's/ABINUM/$(abinum)/g' \ + -e 's/SRCPKGNAME/$(src_pkg_name)/g' \ + -e 's/=HUMAN=/$(human_arch)/g' \ + -e 's/=SERIES=/$(series)/g' \ + >> $(DEBIAN)/control.stub; \ + done + +.PHONY: debian/control +debian/control: $(DEBIAN)/control.stub + echo "# placebo control.stub for kernel-wedge flow change" >debian/control.stub + cp $(DEBIAN)/control.stub debian/control + export KW_DEFCONFIG_DIR=$(DEBIAN)/d-i && \ + export KW_CONFIG_DIR=$(DEBIAN)/d-i && \ + LANG=C kernel-wedge gen-control $(release)-$(abinum) | \ + perl -f $(DROOT)/scripts/misc/kernel-wedge-arch.pl $(arch) \ + >>$(CURDIR)/debian/control + +debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DROOT)/certs/*-$(arch).pem) $(wildcard $(DEBIAN)/certs/*-all.pem) $(wildcard $(DEBIAN)/certs/*-$(arch).pem) + for cert in $(sort $(notdir $^)); \ + do \ + for dir in $(DEBIAN) $(DROOT); \ + do \ + if [ -f "$$dir/certs/$$cert" ]; then \ + cat "$$dir/certs/$$cert"; \ + break; \ + fi; \ + done; \ + done >"$@" + +debian/canonical-revoked-certs.pem: $(wildcard $(DROOT)/revoked-certs/*-all.pem) $(wildcard $(DROOT)/revoked-certs/*-$(arch).pem) $(wildcard $(DEBIAN)/revoked-certs/*-all.pem) $(wildcard $(DEBIAN)/revoked-certs/*-$(arch).pem) + for cert in $(sort $(notdir $^)); \ + do \ + for dir in $(DEBIAN) $(DROOT); \ + do \ + if [ -f "$$dir/revoked-certs/$$cert" ]; then \ + cat "$$dir/revoked-certs/$$cert"; \ + break; \ + fi; \ + done; \ + done >"$@" --- linux-oracle-5.4.0.orig/debian/rules.d/0-common-vars.mk +++ linux-oracle-5.4.0/debian/rules.d/0-common-vars.mk @@ -0,0 +1,278 @@ +# Used when you need to 'escape' a comma. +comma = , + +# +# The source package name will be the first token from $(DEBIAN)/changelog +# +src_pkg_name=$(shell sed -n '1s/^\(.*\) (.*).*$$/\1/p' $(DEBIAN)/changelog) + +# Get the series +series=$(shell dpkg-parsechangelog -l$(DEBIAN)/changelog | sed -ne 's/^Distribution: *//p' | sed -e 's/-\(security\|updates\|proposed\)$$//') + +# Get some version info +release := $(shell sed -n '1s/^$(src_pkg_name).*(\(.*\)-.*).*$$/\1/p' $(DEBIAN)/changelog) +revisions := $(shell sed -n 's/^$(src_pkg_name)\ .*($(release)-\(.*\)).*$$/\1/p' $(DEBIAN)/changelog | tac) +revision ?= $(word $(words $(revisions)),$(revisions)) +prev_revisions := $(filter-out $(revision),0.0 $(revisions)) +prev_revision := $(word $(words $(prev_revisions)),$(prev_revisions)) + +prev_fullver ?= $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -o1 -c1 | sed -ne 's/^Version: *//p') + +# Get variants. Assume primary if debian/variants is not present. +variants = -- +ifneq (,$(wildcard $(DEBIAN)/variants)) + variants := $(shell cat $(DEBIAN)/variants) +endif + +# Get upstream version info +upstream_version := $(shell sed -n 's/^VERSION = \(.*\)$$/\1/p' Makefile) +upstream_patchlevel := $(shell sed -n 's/^PATCHLEVEL = \(.*\)$$/\1/p' Makefile) +upstream_tag := "v$(upstream_version).$(upstream_patchlevel)" + +family=ubuntu + +# This is an internally used mechanism for the daily kernel builds. It +# creates packages whose ABI is suffixed with a minimal representation of +# the current git HEAD sha. If .git/HEAD is not present, then it uses the +# uuidgen program, +# +# AUTOBUILD can also be used by anyone wanting to build a custom kernel +# image, or rebuild the entire set of Ubuntu packages using custom patches +# or configs. +AUTOBUILD= + +ifneq ($(AUTOBUILD),) +skipabi = true +skipmodule = true +skipretpoline = true +skipdbg = true +gitver=$(shell if test -f .git/HEAD; then cat .git/HEAD; else uuidgen; fi) +gitverpre=$(shell echo $(gitver) | cut -b -3) +gitverpost=$(shell echo $(gitver) | cut -b 38-40) +abi_suffix = -$(gitverpre)$(gitverpost) +endif + +ifneq ($(NOKERNLOG),) +ubuntu_log_opts += --no-kern-log +endif +ifneq ($(PRINTSHAS),) +ubuntu_log_opts += --print-shas +endif + +# Get the kernels own extra version to be added to the release signature. +raw_kernelversion=$(shell make kernelversion) + +# +# full_build -- are we doing a full buildd style build +# +ifeq ($(wildcard /CurrentlyBuilding),) +full_build?=false +else +full_build?=true +endif + +# +# The debug packages are ginormous, so you probably want to skip +# building them (as a developer). +# +ifeq ($(full_build),false) +skipdbg=true +endif + +abinum := $(shell echo $(revision) | sed -r -e 's/([^\+~]*)\.[^\.]+(~.*)?(\+.*)?$$/\1/')$(abi_suffix) +prev_abinum := $(shell echo $(prev_revision) | sed -r -e 's/([^\+~]*)\.[^\.]+(~.*)?(\+.*)?$$/\1/')$(abi_suffix) +abi_release := $(release)-$(abinum) + +uploadnum := $(shell echo $(revision) | sed -r -e 's/[^\+~]*\.([^\.~]+(~.*)?(\+.*)?$$)/\1/') +ifneq ($(full_build),false) + uploadnum := $(uploadnum)-Ubuntu +endif + +# XXX: linux-libc-dev got bumped to -803.N inadvertantly by a ti-omap4 upload +# shift our version higher for this package only. Ensure this only +# occurs for the v2.6.35 kernel so that we do not propogate this into +# any other series. +raw_uploadnum := $(shell echo $(revision) | sed -e 's/.*\.//') +libc_dev_version := +ifeq ($(DEBIAN),debian.master) +ifeq ($(release),2.6.35) +libc_dev_version := -v$(release)-$(shell expr "$(abinum)" + 1000).$(raw_uploadnum) +endif +endif + +DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) +DEB_HOST_GNU_TYPE = $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE = $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_ARCH = $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH) + +# +# Detect invocations of the form 'fakeroot debian/rules binary arch=armhf' +# within an x86'en schroot. This only gets you part of the way since the +# packaging phase fails, but you can at least compile the kernel quickly. +# +arch := $(DEB_HOST_ARCH) +ifneq ($(arch),$(DEB_HOST_ARCH)) + CROSS_COMPILE ?= $(shell dpkg-architecture -a$(arch) -qDEB_HOST_GNU_TYPE -f 2>/dev/null)- +endif + +# +# Detect invocations of the form 'dpkg-buildpackage -B -aarmhf' within +# an x86'en schroot. This is the only way to build all of the packages +# (except for tools). +# +ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) + CROSS_COMPILE ?= $(DEB_HOST_GNU_TYPE)- +endif + +abidir := $(CURDIR)/$(DEBIAN)/abi/$(release)-$(revision)/$(arch) +commonconfdir := $(CURDIR)/$(DEBIAN)/config +archconfdir := $(CURDIR)/$(DEBIAN)/config/$(arch) +sharedconfdir := $(CURDIR)/debian.master/config +builddir := $(CURDIR)/debian/build +stampdir := $(CURDIR)/debian/stamps + +# +# The binary package name always starts with linux-image-$KVER-$ABI.$UPLOAD_NUM. There +# are places that you'll find linux-image hard coded, but I guess thats OK since the +# assumption that the binary package always starts with linux-image will never change. +# +bin_pkg_name_signed=linux-image-$(abi_release) +bin_pkg_name_unsigned=linux-image-unsigned-$(abi_release) +mods_pkg_name=linux-modules-$(abi_release) +mods_extra_pkg_name=linux-modules-extra-$(abi_release) +bldinfo_pkg_name=linux-buildinfo-$(abi_release) +hdrs_pkg_name=linux-headers-$(abi_release) +indep_hdrs_pkg_name=$(src_pkg_name)-headers-$(abi_release) + +# +# The generation of content in the doc package depends on both 'AUTOBUILD=' and +# 'do_doc_package_content=true'. There are usually build errors during the development +# cycle, so its OK to leave 'do_doc_package_content=false' until those build +# failures get sorted out. Finally, the doc package doesn't really need to be built +# for developer testing (its kind of slow), so only do it if on a buildd. +ifneq ($(filter --,$(variants)),) +do_doc_package=true +else +do_doc_package=false +endif +do_doc_package_content=true +ifeq ($(full_build),false) +do_doc_package_content=false +endif +doc_pkg_name=$(src_pkg_name)-doc + +# +# Similarly with the linux-source package, you need not build it as a developer. Its +# somewhat I/O intensive and utterly useless. +# +do_source_package=true +do_source_package_content=true +ifeq ($(full_build),false) +do_source_package_content=false +endif + +# linux-libc-dev may not be needed, default to building it only for the +# primary variant +ifneq ($(filter --,$(variants)),) +do_libc_dev_package=true +else +do_libc_dev_package=false +endif + +# common headers normally is built as an indep package, but may be arch +do_common_headers_indep=true + +# add a 'full source' mode +do_full_source=false + +# Add an option to enable special drivers which should only be build when +# explicitly enabled. +do_odm_drivers=false + +# build tools +ifneq ($(wildcard $(CURDIR)/tools),) + ifeq ($(do_tools),) + ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE)) + do_tools=false + endif + endif + do_tools?=true +else + do_tools?=false +endif +tools_pkg_name=$(src_pkg_name)-tools-$(abi_release) +tools_common_pkg_name=$(src_pkg_name)-tools-common +tools_flavour_pkg_name=linux-tools-$(abi_release) +cloud_pkg_name=$(src_pkg_name)-cloud-tools-$(abi_release) +cloud_common_pkg_name=$(src_pkg_name)-cloud-tools-common +cloud_flavour_pkg_name=linux-cloud-tools-$(abi_release) +hosttools_pkg_name=$(src_pkg_name)-tools-host + +# The general flavour specific image package. +do_flavour_image_package=true + +# The general flavour specific header package. +do_flavour_header_package=true + +# DTBs +do_dtbs=false + +# Support parallel= in DEB_BUILD_OPTIONS (see #209008) +# +# These 2 environment variables set the -j value of the kernel build. For example, +# CONCURRENCY_LEVEL=16 fakeroot $(DEBIAN)/rules binary-debs +# or +# DEB_BUILD_OPTIONS=parallel=16 fakeroot $(DEBIAN)/rules binary-debs +# +# The default is to use the number of CPUs. +# +COMMA=, +DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) +ifneq (,$(DEB_BUILD_OPTIONS_PARA)) + CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA) +endif + +ifeq ($(CONCURRENCY_LEVEL),) + # Check the environment + CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL) + # No? Then build with the number of CPUs on the host. + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 1) + endif + # Oh hell, give 'em one + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := 1 + endif +endif + +conc_level = -j$(CONCURRENCY_LEVEL) + +# target_flavour is filled in for each step +kmake = make ARCH=$(build_arch) \ + CROSS_COMPILE=$(CROSS_COMPILE) \ + KERNELVERSION=$(abi_release)-$(target_flavour) \ + CONFIG_DEBUG_SECTION_MISMATCH=y \ + KBUILD_BUILD_VERSION="$(uploadnum)" \ + LOCALVERSION= localver-extra= \ + CFLAGS_MODULE="-DPKG_ABI=$(abinum)" +ifneq ($(LOCAL_ENV_CC),) +kmake += CC="$(LOCAL_ENV_CC)" DISTCC_HOSTS="$(LOCAL_ENV_DISTCC_HOSTS)" +endif + +# Locking is required in parallel builds to prevent loss of contents +# of the debian/files. +lockme_file = $(CURDIR)/debian/.LOCK +lockme_cmd = flock -w 60 +lockme = $(lockme_cmd) $(lockme_file) + +# Don't fail if a link already exists. +LN = ln -sf + +# Checks if a var is overriden by the custom rules. Called with var and +# flavour as arguments. +custom_override = \ + $(shell if [ -n "$($(1)_$(2))" ]; then echo "$($(1)_$(2))"; else echo "$($(1))"; fi) + +# selftests that Ubuntu cares about +ubuntu_selftests = breakpoints bpf cpu-hotplug efivarfs memfd memory-hotplug mount net ptrace seccomp timers powerpc user ftrace --- linux-oracle-5.4.0.orig/debian/rules.d/1-maintainer.mk +++ linux-oracle-5.4.0/debian/rules.d/1-maintainer.mk @@ -0,0 +1,198 @@ +# The following targets are for the maintainer only! do not run if you don't +# know what they do. + +.PHONY: printenv updateconfigs migrateconfigs printchanges insertchanges startnewrelease diffupstream help updateportsconfigs editportsconfigs autoreconstruct finalchecks + +help: + @echo "These are the targets in addition to the normal $(DEBIAN) ones:" + @echo + @echo " printenv : Print some variables used in the build" + @echo + @echo " updateconfigs : Update core arch configs" + @echo + @echo " editconfigs : Update core arch configs interractively" + @echo " migrateconfigs : Automatically import old configs into annotations" + @echo " genconfigs : Generate core arch configs in CONFIGS/*" + @echo + @echo " updateportsconfigs : Update ports arch configs" + @echo + @echo " editportsconfigs : Update ports arch configs interactivly" + @echo " genportconfigs : Generate ports arch configs in CONFIGS/*" + @echo + @echo " printchanges : Print the current changelog entries (from git)" + @echo + @echo " insertchanges : Insert current changelog entries (from git)" + @echo + @echo " startnewrelease : Start a new changelog set" + @echo + @echo " diffupstream : Diff stock kernel code against upstream (git)" + @echo + @echo " compileselftests : Only compile the selftests listed on ubuntu_selftests variable" + @echo + @echo " runselftests : Run the selftests listed on ubuntu_selftests variable" + @echo + @echo " help : If you are kernel hacking, you need the professional" + @echo " version of this" + @echo + @echo "Environment variables:" + @echo + @echo " NOKERNLOG : Do not add upstream kernel commits to changelog" + @echo " CONCURRENCY_LEVEL=X" + @echo " : Use -jX for kernel compile" + @echo " PRINTSHAS : Include SHAs for commits in changelog" + +printdebian: + @echo "$(DEBIAN)" + +updateconfigs defaultconfigs editconfigs genconfigs dumpconfigs: + dh_testdir; +ifneq ($(wildcard $(DEBIAN)/config/config.common.ubuntu),) + $(SHELL) $(DROOT)/scripts/misc/old-kernelconfig $@ "$(do_enforce_all)" +else + kmake='$(kmake)' skip_checks=$(do_skip_checks) conc_level=$(conc_level) \ + $(SHELL) $(DROOT)/scripts/misc/kernelconfig $@ + @rm -rf build +endif + +migrateconfigs: +ifneq ($(wildcard $(DEBIAN)/config/config.common.ubuntu),) + dh_testdir + conc_level=$(conc_level) $(SHELL) $(DROOT)/scripts/misc/old-kernelconfig genconfigs + rm -rf build + mkdir build + mv $(DEBIAN)/config/annotations build/.annotations + mv $(DEBIAN)/config/README.rst build/.README.rst 2>/dev/null || true + rm -rf $(DEBIAN)/config + mkdir -p $(DEBIAN)/config + debian/scripts/misc/migrate-annotations < build/.annotations > $(DEBIAN)/config/annotations + mv build/.README.rst $(DEBIAN)/config/README.rst 2>/dev/null || true + rm -rf build + kmake='$(kmake)' conc_level=$(conc_level) $(SHELL) $(DROOT)/scripts/misc/kernelconfig updateconfigs +endif + +updateportsconfigs defaultportsconfigs editportsconfigs genportsconfigs askconfigs: + dh_testdir; + $(SHELL) $(DROOT)/scripts/misc/kernelconfig $@ ports + rm -rf build + +printenv: + dh_testdir + @echo "src package name = $(src_pkg_name)" + @echo "series = $(series)" + @echo "release = $(release)" + @echo "revisions = $(revisions)" + @echo "revision = $(revision)" + @echo "uploadnum = $(uploadnum)" + @echo "prev_revisions = $(prev_revisions)" + @echo "prev_revision = $(prev_revision)" + @echo "abinum = $(abinum)" + @echo "upstream_tag = $(upstream_tag)" + @echo "gitver = $(gitver)" + @echo "variants = $(variants)" + @echo "flavours = $(flavours)" + @echo "skipabi = $(skipabi)" + @echo "skipmodule = $(skipmodule)" + @echo "skipdbg = $(skipdbg)" + @echo "ubuntu_log_opts = $(ubuntu_log_opts)" + @echo "CONCURRENCY_LEVEL = $(CONCURRENCY_LEVEL)" + @echo "ubuntu_selftests = $(ubuntu_selftests)" + @echo "bin package name = $(bin_pkg_name)" + @echo "hdr package name = $(hdrs_pkg_name)" + @echo "doc package name = $(doc_pkg_name)" + @echo "do_doc_package = $(do_doc_package)" + @echo "do_doc_package_content = $(do_doc_package_content)" + @echo "do_source_package = $(do_source_package)" + @echo "do_source_package_content = $(do_source_package_content)" + @echo "do_libc_dev_package = $(do_libc_dev_package)" + @echo "do_flavour_image_package = $(do_flavour_image_package)" + @echo "do_flavour_header_package = $(do_flavour_header_package)" + @echo "do_common_headers_indep = $(do_common_headers_indep)" + @echo "do_full_source = $(do_full_source)" + @echo "do_odm_drivers = $(do_odm_drivers)" + @echo "do_tools = $(do_tools)" + @echo "do_any_tools = $(do_any_tools)" + @echo "do_linux_tools = $(do_linux_tools)" + @echo " do_tools_cpupower = $(do_tools_cpupower)" + @echo " do_tools_perf = $(do_tools_perf)" + @echo " do_tools_bpftool = $(do_tools_bpftool)" + @echo " do_tools_x86 = $(do_tools_x86)" + @echo " do_tools_host = $(do_tools_host)" + @echo "do_cloud_tools = $(do_cloud_tools)" + @echo " do_tools_hyperv = $(do_tools_hyperv)" + @echo "any_signed = $(any_signed)" + @echo " uefi_signed = $(uefi_signed)" + @echo " opal_signed = $(opal_signed)" + @echo " sipl_signed = $(sipl_signed)" + @echo "full_build = $(full_build)" + @echo "libc_dev_version = $(libc_dev_version)" + @echo "DEB_HOST_GNU_TYPE = $(DEB_HOST_GNU_TYPE)" + @echo "DEB_BUILD_GNU_TYPE = $(DEB_BUILD_GNU_TYPE)" + @echo "DEB_HOST_ARCH = $(DEB_HOST_ARCH)" + @echo "DEB_BUILD_ARCH = $(DEB_BUILD_ARCH)" + @echo "arch = $(arch)" + @echo "kmake = $(kmake)" + +printchanges: + @baseCommit=$$(git log --pretty=format:'%H %s' | \ + gawk '/UBUNTU: '".*Ubuntu-.*`echo $(prev_fullver) | sed 's/+/\\\\+/'`"'(~.*)?$$/ { print $$1; exit }'); \ + if [ -z "$$baseCommit" ]; then \ + echo "WARNING: couldn't find a commit for the previous version. Using the lastest one." >&2; \ + baseCommit=$$(git log --pretty=format:'%H %s' | \ + gawk '/UBUNTU:\s*Ubuntu-.*$$/ { print $$1; exit }'); \ + fi; \ + git log "$$baseCommit"..HEAD | \ + $(DROOT)/scripts/misc/git-ubuntu-log $(ubuntu_log_opts) + +insertchanges: autoreconstruct finalchecks + @perl -w -f $(DROOT)/scripts/misc/insert-changes.pl $(DROOT) $(DEBIAN) + +autoreconstruct: + # No need for reconstruct for -rc kernels since we don't upload an + # orig tarball, so just remove it. + if grep -q "^EXTRAVERSION = -rc[0-9]\+$$" Makefile; then \ + echo "exit 0" >$(DEBIAN)/reconstruct; \ + else \ + $(DROOT)/scripts/misc/gen-auto-reconstruct $(upstream_tag) $(DEBIAN)/reconstruct $(DROOT)/source/options; \ + fi + +finalchecks: debian/control + $(DROOT)/scripts/misc/final-checks "$(DEBIAN)" "$(prev_fullver)" + +diffupstream: + @git diff-tree -p refs/remotes/linux-2.6/master..HEAD $(shell ls | grep -vE '^(ubuntu|$(DEBIAN)|\.git.*)') + +startnewrelease: + dh_testdir + @[ -f "$(DEBIAN)/etc/update.conf" ] && . "$(DEBIAN)/etc/update.conf"; \ + if [ -n "$$BACKPORT_SUFFIX" ]; then \ + ver="$$(dpkg-parsechangelog -l"$$DEBIAN_MASTER/changelog" -SVersion)$${BACKPORT_SUFFIX}.1"; \ + prev_ver="$$(dpkg-parsechangelog -l"$(DEBIAN)/changelog" -SVersion)"; \ + if [ "$${ver%.*}" = "$${prev_ver%.*}" ]; then \ + ver="$${ver%.*}.$$(( $${prev_ver##*.} +1 ))"; \ + fi; \ + else \ + ver="$(release)-$$(echo "$(revision)" | \ + perl -ne 'if (/^(\d*)\.(\d*)(.*)?$$/) { printf("%d.%d%s\n", $$1 + 1, $$2 +1, $$3) }')"; \ + fi; \ + now="$(shell date -R)"; \ + echo "Creating new changelog set for $$ver..."; \ + echo -e "$(src_pkg_name) ($$ver) UNRELEASED; urgency=medium\n" > $(DEBIAN)/changelog.new; \ + echo " CHANGELOG: Do not edit directly. Autogenerated at release." >> \ + $(DEBIAN)/changelog.new; \ + echo " CHANGELOG: Use the printchanges target to see the curent changes." \ + >> $(DEBIAN)/changelog.new; \ + echo " CHANGELOG: Use the insertchanges target to create the final log." \ + >> $(DEBIAN)/changelog.new; \ + echo -e "\n -- $$DEBFULLNAME <$$DEBEMAIL> $$now\n" >> \ + $(DEBIAN)/changelog.new ; \ + cat $(DEBIAN)/changelog >> $(DEBIAN)/changelog.new; \ + mv $(DEBIAN)/changelog.new $(DEBIAN)/changelog + +compileselftests: + # a loop is needed here to fail on errors + for test in $(ubuntu_selftests); do \ + $(kmake) -C tools/testing/selftests TARGETS="$$test"; \ + done; + +runselftests: + $(kmake) -C tools/testing/selftests TARGETS="$(ubuntu_selftests)" run_tests --- linux-oracle-5.4.0.orig/debian/rules.d/2-binary-arch.mk +++ linux-oracle-5.4.0/debian/rules.d/2-binary-arch.mk @@ -0,0 +1,841 @@ +# We don't want make removing intermediary stamps +.SECONDARY : + +# Prepare the out-of-tree build directory +ifeq ($(do_full_source),true) +build_cd = cd $(builddir)/build-$*; # +build_O = +else +build_cd = +build_O = O=$(builddir)/build-$* +endif + +# Typically supplied from the arch makefile, e.g., debian.master/control.d/armhf.mk +ifneq ($(gcc),) +kmake += CC=$(CROSS_COMPILE)$(gcc) +endif + +shlibdeps_opts = $(if $(CROSS_COMPILE),-- -l$(CROSS_COMPILE:%-=/usr/%)/lib) + +debian/scripts/fix-filenames: debian/scripts/fix-filenames.c + $(CC) -o $@ $^ + +$(stampdir)/stamp-prepare-%: config-prepare-check-% + @echo Debug: $@ + @touch $@ +$(stampdir)/stamp-prepare-tree-%: target_flavour = $* +$(stampdir)/stamp-prepare-tree-%: debian/scripts/fix-filenames + @echo Debug: $@ + install -d $(builddir)/build-$* + touch $(builddir)/build-$*/ubuntu-build + [ "$(do_full_source)" != 'true' ] && true || \ + rsync -a --exclude debian --exclude debian.master --exclude $(DEBIAN) * $(builddir)/build-$* + if [ -e $(commonconfdir)/config.common.ubuntu ]; then \ + cat $(commonconfdir)/config.common.ubuntu $(archconfdir)/config.common.$(arch) $(archconfdir)/config.flavour.$(target_flavour) > $(builddir)/build-$*/.config; \ + else \ + python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(target_flavour) | sed -e 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$* $(raw_kernelversion)"/' > $(builddir)/build-$*/.config; \ + fi + sed -i 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$* $(raw_kernelversion)"/' $(builddir)/build-$*/.config + [ "$(do_odm_drivers)" = 'true' ] && true || \ + sed -ie 's/.*CONFIG_UBUNTU_ODM_DRIVERS.*/# CONFIG_UBUNTU_ODM_DRIVERS is not set/' \ + $(builddir)/build-$*/.config + find $(builddir)/build-$* -name "*.ko" | xargs rm -f + $(build_cd) $(kmake) $(build_O) -j1 syncconfig prepare scripts + touch $@ + +# Used by developers as a shortcut to prepare a tree for compilation. +prepare-%: $(stampdir)/stamp-prepare-% + @echo Debug: $@ +# Used by developers to allow efficient pre-building without fakeroot. +build-%: $(stampdir)/stamp-build-% + @echo Debug: $@ + +# Do the actual build, including image and modules +$(stampdir)/stamp-build-%: target_flavour = $* +$(stampdir)/stamp-build-%: bldimg = $(call custom_override,build_image,$*) +$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-% + @echo Debug: $@ build_image $(build_image) bldimg $(bldimg) + $(build_cd) $(kmake) $(build_O) $(conc_level) $(bldimg) modules $(if $(filter true,$(do_dtbs)),dtbs) + + # Collect the list of kernel source files used for this build. Need to do this early + # before modules are stripped. Fail if the resulting file is empty. + find $(builddir)/build-$* -name vmlinux -o -name \*.ko -exec dwarfdump -i {} \; | \ + grep -E 'DW_AT_(call|decl)_file' | sed -n 's|.*\s/|/|p' | sort -u > \ + $(builddir)/build-$*/sources.list + test -s $(builddir)/build-$*/sources.list + + @touch $@ + +define build_dkms_sign = + $(shell set -x; if grep -q CONFIG_MODULE_SIG=y $(1)/.config; then + echo $(1)/scripts/sign-file $(MODHASHALGO) $(MODSECKEY) $(MODPUBKEY); + else + echo "-"; + fi + ) +endef +define build_dkms = + CROSS_COMPILE=$(CROSS_COMPILE) $(SHELL) $(DROOT)/scripts/dkms-build $(dkms_dir) $(abi_release)-$* '$(call build_dkms_sign,$(builddir)/build-$*)' $(1) $(2) $(3) $(4) $(5) +endef + +# nvidia_build_payload 450 450 450_450.102.04-0ubuntu0.20.04.1 +# nvidia_build_payload 450-server 450srv 50.102.04-0ubuntu0.20.04.1 +define nvidia_build_payload = + $(call build_dkms, $(bldinfo_pkg_name)-$*, $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/signatures, "", nvidia-$(2), pool/restricted/n/nvidia-graphics-drivers-$(1)/nvidia-kernel-source-$(1)_$(3)_$(arch).deb pool/restricted/n/nvidia-graphics-drivers-$(1)/nvidia-dkms-$(1)_$(3)_$(arch).deb) +endef +# nvidia_build 450 +# nvidia_build 450-server +define nvidia_build = + $(call nvidia_build_payload,$(1),$(shell echo $(1) | sed -e 's/-server/srv/'),$(shell awk '/^nvidia-graphics-drivers-$(1) / {print($$2);}' $(DEBIAN)/dkms-versions)) + +endef + +define install_control = + for which in $(3); \ + do \ + template="$(DROOT)/templates/$(2).$$which.in"; \ + script="$(DROOT)/$(1).$$which"; \ + sed -e 's/@abiname@/$(abi_release)/g' \ + -e 's/@localversion@/-$*/g' \ + -e 's/@image-stem@/$(instfile)/g' \ + <"$$template" >"$$script"; \ + done +endef + +# Ensure the directory prefix is exactly 100 characters long so pathnames are the +# exact same length in any binary files produced by the builds. These will be +# commonised later. +dkms_20d=.................... +dkms_100d=$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d) +dkms_100c=$(shell echo '$(dkms_100d)' | sed -e 's/\./_/g') +define dkms_dir_prefix = +$(shell echo $(1)/$(dkms_100c) | \ + sed -e 's/\($(dkms_100d)\).*/\1/' -e 's/^\(.*\)....$$/\1dkms/') +endef + +# Install the finished build +install-%: pkgdir_bin = $(CURDIR)/debian/$(bin_pkg_name)-$* +install-%: pkgdir = $(CURDIR)/debian/$(mods_pkg_name)-$* +install-%: pkgdir_ex = $(CURDIR)/debian/$(mods_extra_pkg_name)-$* +install-%: pkgdir_bldinfo = $(CURDIR)/debian/$(bldinfo_pkg_name)-$* +install-%: bindoc = $(pkgdir)/usr/share/doc/$(bin_pkg_name)-$* +install-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym +install-%: signingv = $(CURDIR)/debian/$(bin_pkg_name)-signing/$(release)-$(revision) +install-%: toolspkgdir = $(CURDIR)/debian/$(tools_flavour_pkg_name)-$* +install-%: cloudpkgdir = $(CURDIR)/debian/$(cloud_flavour_pkg_name)-$* +install-%: basepkg = $(hdrs_pkg_name) +install-%: indeppkg = $(indep_hdrs_pkg_name) +install-%: kernfile = $(call custom_override,kernel_file,$*) +install-%: instfile = $(call custom_override,install_file,$*) +install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$* +install-%: target_flavour = $* +install-%: MODHASHALGO=sha512 +install-%: MODSECKEY=$(builddir)/build-$*/certs/signing_key.pem +install-%: MODPUBKEY=$(builddir)/build-$*/certs/signing_key.x509 +install-%: build_dir=$(builddir)/build-$* +install-%: dkms_dir=$(call dkms_dir_prefix,$(builddir)/build-$*) +install-%: enable_zfs = $(call custom_override,do_zfs,$*) +install-%: dbgpkgdir_zfs = $(if $(filter true,$(skipdbg)),"",$(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/kernel) +install-%: $(stampdir)/stamp-build-% install-headers + @echo Debug: $@ kernel_file $(kernel_file) kernfile $(kernfile) install_file $(install_file) instfile $(instfile) + dh_testdir + dh_testroot + dh_prep -p$(bin_pkg_name)-$* + dh_prep -p$(mods_pkg_name)-$* + dh_prep -p$(hdrs_pkg_name)-$* +ifneq ($(skipdbg),true) + dh_prep -p$(bin_pkg_name)-$*-dbgsym +endif + + # The main image + # compress_file logic required because not all architectures + # generate a zImage automatically out of the box +ifeq ($(compress_file),) + install -m600 -D $(builddir)/build-$*/$(kernfile) \ + $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* +else + install -d $(pkgdir_bin)/boot + gzip -c9v $(builddir)/build-$*/$(kernfile) > \ + $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* + chmod 600 $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* +endif + +ifeq ($(uefi_signed),true) + install -d $(signingv) + # gzipped kernel images must be decompressed for signing + if [[ "$(kernfile)" =~ \.gz$$ ]]; then \ + < $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* \ + gunzip -cv > $(signingv)/$(instfile)-$(abi_release)-$*.efi; \ + cp -p --attributes-only $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* \ + $(signingv)/$(instfile)-$(abi_release)-$*.efi; \ + echo "GZIP=1" >> $(signingv)/$(instfile)-$(abi_release)-$*.efi.vars; \ + else \ + cp -p $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* \ + $(signingv)/$(instfile)-$(abi_release)-$*.efi; \ + fi +endif +ifeq ($(opal_signed),true) + install -d $(signingv) + cp -p $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* \ + $(signingv)/$(instfile)-$(abi_release)-$*.opal; +endif +ifeq ($(sipl_signed),true) + install -d $(signingv) + cp -p $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$* \ + $(signingv)/$(instfile)-$(abi_release)-$*.sipl; +endif + + install -d $(pkgdir)/boot + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir)/boot/config-$(abi_release)-$* + install -m600 $(builddir)/build-$*/System.map \ + $(pkgdir)/boot/System.map-$(abi_release)-$* + if [ "$(filter true,$(do_dtbs))" ]; then \ + $(build_cd) $(kmake) $(build_O) $(conc_level) dtbs_install \ + INSTALL_DTBS_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$*/device-tree; \ + ( cd $(pkgdir)/lib/firmware/$(abi_release)-$*/ && find device-tree -print ) | \ + while read dtb_file; do \ + echo "$$dtb_file ?" >> $(DEBIAN)/d-i/firmware/$(arch)/kernel-image; \ + done; \ + fi + if [ -f '$(DEBIAN)/initramfs-tools.d/$(target_flavour).hook.in' ]; then \ + install -d $(pkgdir)/usr/share/initramfs-tools/hooks/; \ + sed -e 's/@abiname@/$(abi_release)/g' \ + -e 's/@localversion@/-$*/g' \ + < '$(DEBIAN)/initramfs-tools.d/$(target_flavour).hook.in' \ + > '$(pkgdir)/usr/share/initramfs-tools/hooks/linux-$(abi_release)-$*'; \ + chmod 0755 '$(pkgdir)/usr/share/initramfs-tools/hooks/linux-$(abi_release)-$*'; \ + fi +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux + chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* +endif + + $(build_cd) $(kmake) $(build_O) $(conc_level) modules_install $(vdso) \ + INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir)/ \ + INSTALL_FW_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$* + + # + # Build module blacklists: + # - blacklist all watchdog drivers (LP:1432837) + # + install -d $(pkgdir)/lib/modprobe.d + echo "# Kernel supplied blacklist for $(src_pkg_name) $(abi_release)-$* $(arch)" \ + >$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + for conf in $(arch)-$* $(arch) common.conf; do \ + if [ -f $(DEBIAN)/modprobe.d/$$conf ]; then \ + echo "# modprobe.d/$$conf"; \ + cat $(DEBIAN)/modprobe.d/$$conf; \ + fi; \ + done >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + echo "# Autogenerated watchdog blacklist" \ + >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + ls -1 $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/watchdog/ | \ + grep -v '^bcm2835_wdt$$' | \ + sed -e 's/^/blacklist /' -e 's/.ko$$//' | \ + sort -u \ + >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf + +ifeq ($(do_extras_package),true) + # + # Remove all modules not in the inclusion list. + # + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + /sbin/depmod -v -b $(pkgdir) $(abi_release)-$* | \ + sed -e "s@$(pkgdir)/lib/modules/$(abi_release)-$*/kernel/@@g" | \ + awk '{ print $$1 " " $$NF}' >$(build_dir)/module-inclusion.depmap; \ + mkdir -p $(pkgdir_ex)/lib/modules/$(abi_release)-$*; \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \ + $(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel; \ + $(SHELL) $(DROOT)/scripts/module-inclusion --master \ + $(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel \ + $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \ + $(DEBIAN)/control.d/$(target_flavour).inclusion-list \ + $(build_dir)/module-inclusion.depmap 2>&1 | \ + tee $(target_flavour).inclusion-list.log; \ + /sbin/depmod -b $(pkgdir) -ea -F $(pkgdir)/boot/System.map-$(abi_release)-$* \ + $(abi_release)-$* 2>&1 |tee $(target_flavour).depmod.log; \ + if [ `grep -c 'unknown symbol' $(target_flavour).depmod.log` -gt 0 ]; then \ + echo "EE: Unresolved module dependencies in base package!"; \ + exit 1; \ + fi \ + fi +endif + +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux + chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* +endif + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source + + # Some initramfs-tools specific modules + install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\ + $(LN) $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \ + $(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \ + fi + + echo "interest linux-update-$(abi_release)-$*" >"$(DROOT)/$(bin_pkg_name)-$*.triggers" + install -d $(pkgdir_bin)/usr/lib/linux/triggers + $(call install_control,$(bin_pkg_name)-$*,image,postinst postrm preinst prerm) + install -d $(pkgdir)/usr/lib/linux/triggers + $(call install_control,$(mods_pkg_name)-$*,extra,postinst postrm) +ifeq ($(do_extras_package),true) + # Install the postinit/postrm scripts in the extras package. + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + install -d $(pkgdir_ex)/usr/lib/linux/triggers; \ + $(call install_control,$(mods_extra_pkg_name)-$*,extra,postinst postrm); \ + fi +endif + + # Install the full changelog. +ifeq ($(do_doc_package),true) + install -d $(bindoc) + cat $(DEBIAN)/changelog $(DEBIAN)/changelog.historical | \ + gzip -9 >$(bindoc)/changelog.Debian.old.gz + chmod 644 $(bindoc)/changelog.Debian.old.gz +endif + +ifneq ($(skipsub),true) + for sub in $($(*)_sub); do \ + if ! (TO=$$sub FROM=$* ABI_RELEASE=$(abi_release) $(SHELL) \ + $(DROOT)/scripts/sub-flavour); then exit 1; fi; \ + /sbin/depmod -b debian/$(bin_pkg_name)-$$sub \ + -ea -F debian/$(bin_pkg_name)-$$sub/boot/System.map-$(abi_release)-$* \ + $(abi_release)-$*; \ + $(call install_control,$(bin_pkg_name)--$$sub,image,postinst postrm preinst prerm); \ + done +endif + +ifneq ($(skipdbg),true) + # Debug image is simple + install -m644 -D $(builddir)/build-$*/vmlinux \ + $(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$* + $(build_cd) $(kmake) $(build_O) modules_install $(vdso) \ + INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug + # Add .gnu_debuglink sections only after all/DKMS modules are built. + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.* + rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware +endif + + # The flavour specific headers image + # TODO: Would be nice if we didn't have to dupe the original builddir + install -d -m755 $(hdrdir) + cat $(builddir)/build-$*/.config | \ + sed -e 's/.*CONFIG_DEBUG_INFO=.*/# CONFIG_DEBUG_INFO is not set/g' > \ + $(hdrdir)/.config + chmod 644 $(hdrdir)/.config + $(kmake) O=$(hdrdir) -j1 syncconfig prepare scripts + # We'll symlink this stuff + rm -f $(hdrdir)/Makefile + rm -rf $(hdrdir)/include2 $(hdrdir)/source + # We do not need the retpoline information. + find $(hdrdir) -name \*.o.ur-\* | xargs rm -f + # Copy over the compilation version. + cp "$(builddir)/build-$*/include/generated/compile.h" \ + "$(hdrdir)/include/generated/compile.h" + # Add UTS_UBUNTU_RELEASE_ABI since UTS_RELEASE is difficult to parse. + echo "#define UTS_UBUNTU_RELEASE_ABI $(abinum)" >> $(hdrdir)/include/generated/utsrelease.h + # powerpc kernel arch seems to need some .o files for external module linking. Add them in. +ifeq ($(build_arch),powerpc) + mkdir -p $(hdrdir)/arch/powerpc/lib + cp $(builddir)/build-$*/arch/powerpc/lib/*.o $(hdrdir)/arch/powerpc/lib +endif + # Copy over the new retpoline extractor. + cp scripts/ubuntu-retpoline-extract-one $(hdrdir)/scripts + # Script to symlink everything up + $(SHELL) $(DROOT)/scripts/link-headers "$(hdrdir)" "$(indeppkg)" "$*" + # The build symlink + install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$* + $(LN) /usr/src/$(basepkg)-$* \ + debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build + # And finally the symvers + install -m644 $(builddir)/build-$*/Module.symvers \ + $(hdrdir)/Module.symvers + + # Now the header scripts + $(call install_control,$(hdrs_pkg_name)-$*,headers,postinst) + + # At the end of the package prep, call the tests + DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*" \ + VERSION="$(abi_release)" REVISION="$(revision)" \ + PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)" \ + PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*" \ + INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)" \ + run-parts -v $(DROOT)/tests-build + + # + # Remove files which are generated at installation by postinst, + # except for modules.order and modules.builtin + # + # NOTE: need to keep this list in sync with postrm + # + mkdir $(pkgdir)/lib/modules/$(abi_release)-$*/_ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_ + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_; \ + fi + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo ] ; then \ + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_; \ + fi + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.* + mv $(pkgdir)/lib/modules/$(abi_release)-$*/_/* \ + $(pkgdir)/lib/modules/$(abi_release)-$* + rmdir $(pkgdir)/lib/modules/$(abi_release)-$*/_ + +ifeq ($(do_linux_tools),true) + # Create the linux-tools tool links + install -d $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +ifeq ($(do_tools_usbip),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbip $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbipd $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_acpidbg),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/acpidbg $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_cpupower),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/cpupower $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_perf),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/perf $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +ifeq ($(do_tools_perf_jvmti),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/libperf-jvmti.so $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif +ifeq ($(do_tools_bpftool),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/bpftool $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +ifeq ($(do_tools_x86),true) + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/x86_energy_perf_policy $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/turbostat $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + # Create the linux-hyperv tool links + install -d $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_kvp_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_vss_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_fcopy_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* + $(LN) ../../$(src_pkg_name)-tools-$(abi_release)/lsvmbus $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$* +endif +endif + + # Build a temporary "installed headers" directory. + install -d $(dkms_dir) $(dkms_dir)/headers $(dkms_dir)/build $(dkms_dir)/source + cp -rp "$(hdrdir)" "$(indep_hdrdir)" "$(dkms_dir)/headers" + + $(if $(filter true,$(enable_zfs)),$(call build_dkms, $(mods_pkg_name)-$*, $(pkgdir)/lib/modules/$(abi_release)-$*/kernel, $(dbgpkgdir_zfs), zfs, pool/universe/z/zfs-linux/zfs-dkms_$(dkms_zfs_linux_version)_all.deb)) + + $(if $(filter true,$(do_dkms_wireguard)),$(call build_dkms, $(mods_pkg_name)-$*, $(pkgdir)/lib/modules/$(abi_release)-$*/kernel, "", wireguard, pool/universe/w/wireguard-linux-compat/wireguard-dkms_$(dkms_wireguard_version)_all.deb)) + +ifeq ($(do_dkms_nvidia),true) + $(foreach series,$(nvidia_desktop_series),$(call nvidia_build,$(series))) +endif +ifeq ($(do_dkms_nvidia_server),true) + $(foreach series,$(nvidia_server_series),$(call nvidia_build,$(series))) +endif + +ifeq ($(do_extras_package),true) + $(if $(filter true,$(do_dkms_vbox)),$(call build_dkms, $(mods_pkg_name)-$*, $(pkgdir)/lib/modules/$(abi_release)-$*/kernel, "", virtualbox-guest, pool/multiverse/v/virtualbox/virtualbox-guest-dkms_$(dkms_vbox_guest_version)_all.deb)) +endif + +ifneq ($(skipdbg),true) + # Add .gnu_debuglink sections to each stripped .ko + # pointing to unstripped verson + find $(pkgdir) \ + $(if $(filter true,$(do_extras_package)),$(pkgdir_ex)) \ + -name '*.ko' | while read path_module ; do \ + module="/lib/modules/$${path_module#*/lib/modules/}"; \ + if [[ -f "$(dbgpkgdir)/usr/lib/debug/$$module" ]] ; then \ + while IFS= read -r -d '' signature < <(tail -c 28 "$$path_module"); do \ + break; \ + done; \ + $(CROSS_COMPILE)objcopy \ + --add-gnu-debuglink=$(dbgpkgdir)/usr/lib/debug/$$module \ + $$path_module; \ + if grep -q CONFIG_MODULE_SIG=y $(builddir)/build-$*/.config && \ + [ "$$signature" = $$'~Module signature appended~\n' ]; then \ + $(builddir)/build-$*/scripts/sign-file $(MODHASHALGO) \ + $(MODSECKEY) \ + $(MODPUBKEY) \ + $$path_module; \ + fi; \ + else \ + echo "WARNING: Missing debug symbols for module '$$module'."; \ + fi; \ + done +endif + + # Build the final ABI information. + install -d $(abidir) + sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/' \ + $(builddir)/build-$*/Module.symvers | sort > $(abidir)/$* + + # Build the final ABI modules information. + find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > $(abidir)/$*.modules + + # Build the final ABI firmware information. + find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | \ + while read ko; do \ + /sbin/modinfo $$ko | grep ^firmware || true; \ + done | sort -u >$(abidir)/$*.fwinfo + + # Build the final ABI compiler information. + ko=$$(find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | head -1); \ + readelf -p .comment "$$ko" | gawk ' \ + ($$1 == "[") { \ + printf("%s", $$3); \ + for (n=4; n<=NF; n++) { \ + printf(" %s", $$n); \ + } \ + print "" \ + }' | sort -u >$(abidir)/$*.compiler + + # Build the final ABI retpoline information. + if grep -q CONFIG_RETPOLINE=y $(builddir)/build-$*/.config; then \ + echo "# retpoline v1.0" >$(abidir)/$*.retpoline; \ + $(SHELL) $(DROOT)/scripts/retpoline-extract $(builddir)/build-$* $(CURDIR) | \ + sort >>$(abidir)/$*.retpoline; \ + else \ + echo "# RETPOLINE NOT ENABLED" >$(abidir)/$*.retpoline; \ + fi + + # Build the buildinfo package content. + install -d $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$* + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/config + install -m644 $(abidir)/$* \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/abi + install -m644 $(abidir)/$*.modules \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/modules + install -m644 $(abidir)/$*.fwinfo \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/fwinfo + install -m644 $(abidir)/$*.retpoline \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/retpoline + install -m644 $(abidir)/$*.compiler \ + $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/compiler + install -m644 $(DROOT)/canonical-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-certs.pem + install -m644 $(DROOT)/canonical-revoked-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-revoked-certs.pem + # List of source files used for this build + install -m644 $(builddir)/build-$*/sources.list $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/sources + +headers_tmp := $(CURDIR)/debian/tmp-headers +headers_dir := $(CURDIR)/debian/linux-libc-dev + +hmake := $(MAKE) -C $(CURDIR) O=$(headers_tmp) \ + KERNELVERSION=$(abi_release) INSTALL_HDR_PATH=$(headers_tmp)/install \ + SHELL="$(SHELL)" ARCH=$(header_arch) + +install-arch-headers: + @echo Debug: $@ + dh_testdir + dh_testroot +ifeq ($(do_libc_dev_package),true) + dh_prep -plinux-libc-dev +endif + + rm -rf $(headers_tmp) + install -d $(headers_tmp) $(headers_dir)/usr/include/ + + $(hmake) $(defconfig) + mv $(headers_tmp)/.config $(headers_tmp)/.config.old + sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \ + -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \ + $(headers_tmp)/.config.old > $(headers_tmp)/.config + $(hmake) syncconfig + $(hmake) headers_install + + ( cd $(headers_tmp)/install/include/ && \ + find . -name '.' -o -name '.*' -prune -o -print | \ + cpio -pvd --preserve-modification-time \ + $(headers_dir)/usr/include/ ) + mkdir $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH) + mv $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/ + + rm -rf $(headers_tmp) + +define dh_all + dh_installchangelogs -p$(1) + dh_installdocs -p$(1) + dh_compress -p$(1) + dh_fixperms -p$(1) -X/boot/ + dh_shlibdeps -p$(1) $(shlibdeps_opts) + dh_installdeb -p$(1) + dh_installdebconf -p$(1) + $(lockme) dh_gencontrol -p$(1) -- -Vlinux:rprovides='$(rprovides)' + dh_md5sums -p$(1) + dh_builddeb -p$(1) +endef +define newline + + +endef +define dh_all_inline + $(subst ${newline},; \${newline},$(call dh_all,$(1))) +endef + +binary-arch-headers: install-arch-headers + @echo Debug: $@ + dh_testdir + dh_testroot +ifeq ($(do_libc_dev_package),true) +ifneq ($(DEBIAN),debian.master) + echo "non-master branch building linux-libc-dev, aborting" + exit 1 +endif + $(call dh_all,linux-libc-dev) +endif + +binary-%: pkgimg = $(bin_pkg_name)-$* +binary-%: pkgimg_mods = $(mods_pkg_name)-$* +binary-%: pkgimg_ex = $(mods_extra_pkg_name)-$* +binary-%: pkgdir_ex = $(CURDIR)/debian/$(extra_pkg_name)-$* +binary-%: pkgbldinfo = $(bldinfo_pkg_name)-$* +binary-%: pkghdr = $(hdrs_pkg_name)-$* +binary-%: dbgpkg = $(bin_pkg_name)-$*-dbgsym +binary-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym +binary-%: pkgtools = $(tools_flavour_pkg_name)-$* +binary-%: pkgcloud = $(cloud_flavour_pkg_name)-$* +binary-%: rprovides = $(if $(filter true,$(call custom_override,do_zfs,$*)),spl-modules$(comma) spl-dkms$(comma) zfs-modules$(comma) zfs-dkms$(comma)) +binary-%: rprovides += $(if $(filter true,$(call custom_override,do_dkms_vbox,$*)),virtualbox-guest-dkms$(comma)) +binary-%: target_flavour = $* +binary-%: checks-% + @echo Debug: $@ + dh_testdir + dh_testroot + + $(call dh_all,$(pkgimg)) + $(call dh_all,$(pkgimg_mods)) + +ifeq ($(do_extras_package),true) + ifeq ($(ship_extras_package),false) + # If $(ship_extras_package) is explicitly set to false, then do not + # construct the linux-image-extra package; instead just log all of the + # "extra" modules which were pointlessly built yet won't be shipped. + find $(pkgdir_ex) -name '*.ko' | sort \ + | sed 's|^$(pkgdir_ex)/|NOT-SHIPPED |' \ + | tee -a $(target_flavour).not-shipped.log; + else + if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \ + $(call dh_all_inline,$(pkgimg_ex)); \ + fi + endif +endif + + $(call dh_all,$(pkgbldinfo)) + $(call dh_all,$(pkghdr)) + +ifneq ($(skipsub),true) + @set -e; for sub in $($(*)_sub); do \ + pkg=$(bin_pkg_name)-$$sub; \ + $(call dh_all_inline,$$pkg); \ + done +endif + +ifneq ($(skipdbg),true) + $(call dh_all,$(dbgpkg)) + + # Hokay...here's where we do a little twiddling... + # Renaming the debug package prevents it from getting into + # the primary archive, and therefore prevents this very large + # package from being mirrored. It is instead, through some + # archive admin hackery, copied to http://ddebs.ubuntu.com. + # + mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \ + ../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb + set -e; \ + ( \ + $(lockme_cmd) 9 || exit 1; \ + if grep -qs '^Build-Debug-Symbols: yes$$' /CurrentlyBuilding; then \ + sed -i '/^$(dbgpkg)_/s/\.deb /.ddeb /' debian/files; \ + else \ + grep -v '^$(dbgpkg)_.*$$' debian/files > debian/files.new; \ + mv debian/files.new debian/files; \ + fi; \ + ) 9>$(lockme_file) + # Now, the package wont get into the archive, but it will get put + # into the debug system. +endif + +ifeq ($(do_linux_tools),true) + $(call dh_all,$(pkgtools)) +endif +ifeq ($(do_cloud_tools),true) + $(call dh_all,$(pkgcloud)) +endif + +ifneq ($(full_build),false) + # Clean out this flavours build directory. + rm -rf $(builddir)/build-$* + # Clean out the debugging package source directory. + rm -rf $(dbgpkgdir) +endif + +# +# per-architecture packages +# +builddirpa = $(builddir)/tools-perarch + +$(stampdir)/stamp-prepare-perarch: + @echo Debug: $@ +ifeq ($(do_any_tools),true) + rm -rf $(builddirpa) + install -d $(builddirpa) + rsync -a --exclude debian --exclude debian.master --exclude $(DEBIAN) --exclude .git -a ./ $(builddirpa)/ +endif + touch $@ + +$(stampdir)/stamp-build-perarch: $(stampdir)/stamp-prepare-perarch install-arch-headers + @echo Debug: $@ +ifeq ($(do_linux_tools),true) +ifeq ($(do_tools_usbip),true) + chmod 755 $(builddirpa)/tools/usb/usbip/autogen.sh + cd $(builddirpa)/tools/usb/usbip && ./autogen.sh + chmod 755 $(builddirpa)/tools/usb/usbip/configure + cd $(builddirpa)/tools/usb/usbip && ./configure --prefix=$(builddirpa)/tools/usb/usbip/bin + cd $(builddirpa)/tools/usb/usbip && make install CFLAGS="-g -O2 -static" CROSS_COMPILE=$(CROSS_COMPILE) +endif +ifeq ($(do_tools_acpidbg),true) + cd $(builddirpa)/tools/power/acpi && make clean && make CFLAGS="-g -O2 -static -I$(builddirpa)/include" CROSS_COMPILE=$(CROSS_COMPILE) acpidbg +endif +ifeq ($(do_tools_cpupower),true) + # Allow for multiple installed versions of cpupower and libcpupower.so: + # Override LIB_MIN in order to to generate a versioned .so named + # libcpupower.so.$(abi_release) and link cpupower with that. + make -C $(builddirpa)/tools/power/cpupower \ + CROSS_COMPILE=$(CROSS_COMPILE) \ + CROSS=$(CROSS_COMPILE) \ + LIB_MIN=$(abi_release) CPUFREQ_BENCH=false +endif +ifeq ($(do_tools_perf),true) + cd $(builddirpa) && $(kmake) $(defconfig) + mv $(builddirpa)/.config $(builddirpa)/.config.old + sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \ + -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \ + $(builddirpa)/.config.old > $(builddirpa)/.config + cd $(builddirpa) && $(kmake) syncconfig + cd $(builddirpa) && $(kmake) prepare + cd $(builddirpa)/tools/perf && \ + $(kmake) prefix=/usr HAVE_NO_LIBBFD=1 HAVE_CPLUS_DEMANGLE_SUPPORT=1 CROSS_COMPILE=$(CROSS_COMPILE) NO_LIBPYTHON=1 NO_LIBPERL=1 +endif +ifeq ($(do_tools_bpftool),true) + $(kmake) CROSS_COMPILE=$(CROSS_COMPILE) -C $(builddirpa)/tools/bpf/bpftool +endif +ifeq ($(do_tools_x86),true) + cd $(builddirpa)/tools/power/x86/x86_energy_perf_policy && make CROSS_COMPILE=$(CROSS_COMPILE) + cd $(builddirpa)/tools/power/x86/turbostat && make CROSS_COMPILE=$(CROSS_COMPILE) +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + cd $(builddirpa)/tools/hv && make CFLAGS="-I$(headers_dir)/usr/include -I$(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)" CROSS_COMPILE=$(CROSS_COMPILE) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon +endif +endif + @touch $@ + +install-perarch: toolspkgdir = $(CURDIR)/debian/$(tools_pkg_name) +install-perarch: cloudpkgdir = $(CURDIR)/debian/$(cloud_pkg_name) +install-perarch: $(stampdir)/stamp-build-perarch + @echo Debug: $@ + # Add the tools. +ifeq ($(do_linux_tools),true) + install -d $(toolspkgdir)/usr/lib + install -d $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +ifeq ($(do_tools_usbip),true) + install -m755 $(builddirpa)/tools/usb/usbip/bin/sbin/usbip \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/usb/usbip/bin/sbin/usbipd \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_acpidbg),true) + install -m755 $(builddirpa)/tools/power/acpi/acpidbg \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_cpupower),true) + install -m755 $(builddirpa)/tools/power/cpupower/cpupower \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + # Install only the full versioned libcpupower.so.$(abi_release), not + # the usual symlinks to it. + install -m644 $(builddirpa)/tools/power/cpupower/libcpupower.so.$(abi_release) \ + $(toolspkgdir)/usr/lib/ +endif +ifeq ($(do_tools_perf),true) + install -m755 $(builddirpa)/tools/perf/perf $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +ifeq ($(do_tools_perf_jvmti),true) + install -m755 $(builddirpa)/tools/perf/libperf-jvmti.so $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +endif +ifeq ($(do_tools_bpftool),true) + install -m755 $(builddirpa)/tools/bpf/bpftool/bpftool $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +ifeq ($(do_tools_x86),true) + install -m755 $(builddirpa)/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/power/x86/turbostat/turbostat \ + $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +endif +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + install -d $(cloudpkgdir)/usr/lib + install -d $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/hv/hv_kvp_daemon \ + $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/hv/hv_vss_daemon \ + $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/hv/hv_fcopy_daemon \ + $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) + install -m755 $(builddirpa)/tools/hv/lsvmbus \ + $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release) +endif +endif + +binary-perarch: toolspkg = $(tools_pkg_name) +binary-perarch: cloudpkg = $(cloud_pkg_name) +binary-perarch: install-perarch + @echo Debug: $@ +ifeq ($(do_linux_tools),true) + $(call dh_all,$(toolspkg)) +endif +ifeq ($(do_cloud_tools),true) + $(call dh_all,$(cloudpkg)) +endif + +binary-debs: signing = $(CURDIR)/debian/$(bin_pkg_name)-signing +binary-debs: signingv = $(CURDIR)/debian/$(bin_pkg_name)-signing/$(release)-$(revision) +binary-debs: signing_tar = $(src_pkg_name)_$(release)-$(revision)_$(arch).tar.gz +binary-debs: binary-perarch $(addprefix binary-,$(flavours)) + @echo Debug: $@ +ifeq ($(any_signed),true) + install -d $(signingv)/control + { echo "tarball"; } >$(signingv)/control/options + cd $(signing) && tar czvf ../../../$(signing_tar) . + dpkg-distaddfile $(signing_tar) raw-signing - +endif + +build-arch-deps-$(do_flavour_image_package) += $(addprefix $(stampdir)/stamp-build-,$(flavours)) +build-arch: $(build-arch-deps-true) + @echo Debug: $@ + +ifeq ($(AUTOBUILD),) +binary-arch-deps-$(do_flavour_image_package) += binary-udebs +else +binary-arch-deps-$(do_flavour_image_package) = binary-debs +endif +binary-arch-deps-$(do_libc_dev_package) += binary-arch-headers +ifneq ($(do_common_headers_indep),true) +binary-arch-deps-$(do_flavour_header_package) += binary-headers +endif +binary-arch: $(binary-arch-deps-true) + @echo Debug: $@ + --- linux-oracle-5.4.0.orig/debian/rules.d/3-binary-indep.mk +++ linux-oracle-5.4.0/debian/rules.d/3-binary-indep.mk @@ -0,0 +1,220 @@ +build-indep: + @echo Debug: $@ + +# The binary-indep dependency chain is: +# +# install-headers <- install-doc <- install-source <- install-tools <- install-indep <- binary-indep +# install-headers <- binary-headers +# +indep_hdrpkg = $(indep_hdrs_pkg_name) +indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg) +install-headers: prepare-indep + @echo Debug: $@ + dh_testdir + dh_testroot + +ifeq ($(do_flavour_header_package),true) + install -d $(indep_hdrdir) + find . -path './debian' -prune -o -path './$(DEBIAN)' -prune \ + -o -path './include/*' -prune \ + -o -path './scripts/*' -prune -o -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \ + -print | cpio -pd --preserve-modification-time $(indep_hdrdir) + cp -a scripts include $(indep_hdrdir) + (find arch -name include -type d -print | \ + xargs -n1 -i: find : -type f) | \ + cpio -pd --preserve-modification-time $(indep_hdrdir) +endif + +docpkg = $(doc_pkg_name) +docdir = $(CURDIR)/debian/$(docpkg)/usr/share/doc/$(docpkg) +install-doc: prepare-indep + @echo Debug: $@ +ifeq ($(do_doc_package),true) + dh_testdir + dh_testroot + + install -d $(docdir) +ifeq ($(do_doc_package_content),true) + # First the html docs. We skip these for autobuilds + if [ -z "$(AUTOBUILD)" ]; then \ + install -d $(docdir)/$(doc_pkg_name)-tmp; \ + $(kmake) O=$(docdir)/$(doc_pkg_name)-tmp htmldocs; \ + install -d $(docdir)/html; \ + rsync -aL $(docdir)/$(doc_pkg_name)-tmp/Documentation/output/ \ + $(docdir)/html/; \ + rm -rf $(docdir)/$(doc_pkg_name)-tmp; \ + fi +endif + # Copy the rest + cp -a Documentation/* $(docdir) + find $(docdir) -name .gitignore | xargs rm -f +endif + +srcpkg = linux-source-$(release) +srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg) +balldir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)/$(srcpkg) +install-source: prepare-indep + @echo Debug: $@ +ifeq ($(do_source_package),true) + + install -d $(srcdir) +ifeq ($(do_source_package_content),true) + find . -path './debian' -prune -o -path './$(DEBIAN)' -prune -o \ + -path './.*' -prune -o -print | \ + cpio -pd --preserve-modification-time $(balldir) + (cd $(srcdir); tar cf - $(srcpkg)) | bzip2 -9c > \ + $(srcdir)/$(srcpkg).tar.bz2 + rm -rf $(balldir) + find './debian' './$(DEBIAN)' \ + -path './debian/linux-*' -prune -o \ + -path './debian/$(src_pkg_name)-*' -prune -o \ + -path './debian/build' -prune -o \ + -path './debian/files' -prune -o \ + -path './debian/stamps' -prune -o \ + -path './debian/tmp' -prune -o \ + -print | \ + cpio -pd --preserve-modification-time $(srcdir) + $(LN) $(srcpkg)/$(srcpkg).tar.bz2 $(srcdir)/.. +endif +endif + +install-tools: toolspkg = $(tools_common_pkg_name) +install-tools: toolsbin = $(CURDIR)/debian/$(toolspkg)/usr/bin +install-tools: toolssbin = $(CURDIR)/debian/$(toolspkg)/usr/sbin +install-tools: toolsman = $(CURDIR)/debian/$(toolspkg)/usr/share/man +install-tools: toolsbashcomp = $(CURDIR)/debian/$(toolspkg)/usr/share/bash-completion/completions +install-tools: hosttoolspkg = $(hosttools_pkg_name) +install-tools: hosttoolsbin = $(CURDIR)/debian/$(hosttoolspkg)/usr/bin +install-tools: hosttoolsman = $(CURDIR)/debian/$(hosttoolspkg)/usr/share/man +install-tools: cloudpkg = $(cloud_common_pkg_name) +install-tools: cloudbin = $(CURDIR)/debian/$(cloudpkg)/usr/bin +install-tools: cloudsbin = $(CURDIR)/debian/$(cloudpkg)/usr/sbin +install-tools: cloudman = $(CURDIR)/debian/$(cloudpkg)/usr/share/man +install-tools: prepare-indep $(stampdir)/stamp-build-perarch + @echo Debug: $@ + +ifeq ($(do_tools_common),true) + rm -rf $(builddir)/tools + install -d $(builddir)/tools + for i in *; do $(LN) $(CURDIR)/$$i $(builddir)/tools/; done + rm $(builddir)/tools/tools + rsync -a tools/ $(builddir)/tools/tools/ + + install -d $(toolsbin) + install -d $(toolssbin) + install -d $(toolsman)/man1 + install -d $(toolsman)/man8 + install -d $(toolsbashcomp) + + install -m755 debian/tools/generic $(toolsbin)/usbip + install -m755 debian/tools/generic $(toolsbin)/usbipd + install -m644 $(CURDIR)/tools/usb/usbip/doc/*.8 $(toolsman)/man8/ + + install -m755 debian/tools/generic $(toolsbin)/cpupower + install -m644 $(CURDIR)/tools/power/cpupower/man/*.1 $(toolsman)/man1/ + + install -m755 debian/tools/generic $(toolsbin)/perf + + install -m755 debian/tools/generic $(toolssbin)/bpftool + make -C $(builddir)/tools/tools/bpf/bpftool doc + install -m644 $(builddir)/tools/tools/bpf/bpftool/Documentation/*.8 \ + $(toolsman)/man8 + install -m644 $(builddir)/tools/tools/bpf/bpftool/bash-completion/bpftool \ + $(toolsbashcomp) + + install -m755 debian/tools/generic $(toolsbin)/x86_energy_perf_policy + install -m755 debian/tools/generic $(toolsbin)/turbostat + + cd $(builddir)/tools/tools/perf && make man + install -m644 $(builddir)/tools/tools/perf/Documentation/*.1 \ + $(toolsman)/man1 + + install -m644 $(CURDIR)/tools/power/x86/x86_energy_perf_policy/*.8 $(toolsman)/man8 + install -m644 $(CURDIR)/tools/power/x86/turbostat/*.8 $(toolsman)/man8 + +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + install -d $(cloudsbin) + install -m755 debian/tools/generic $(cloudsbin)/hv_kvp_daemon + install -m755 debian/tools/generic $(cloudsbin)/hv_vss_daemon + install -m755 debian/tools/generic $(cloudsbin)/hv_fcopy_daemon + install -m755 debian/tools/generic $(cloudsbin)/lsvmbus + install -m755 debian/cloud-tools/hv_get_dhcp_info $(cloudsbin) + install -m755 debian/cloud-tools/hv_get_dns_info $(cloudsbin) + install -m755 debian/cloud-tools/hv_set_ifconfig $(cloudsbin) + + install -d $(cloudman)/man8 + install -m644 $(CURDIR)/tools/hv/*.8 $(cloudman)/man8 +endif +endif + +ifeq ($(do_tools_acpidbg),true) + install -m755 debian/tools/generic $(toolsbin)/acpidbg +endif + +endif + +ifeq ($(do_tools_host),true) + install -d $(hosttoolsbin) + install -d $(hosttoolsman)/man1 + + install -m 755 $(CURDIR)/tools/kvm/kvm_stat/kvm_stat $(hosttoolsbin)/ + + cd $(builddir)/tools/tools/kvm/kvm_stat && make man + install -m644 $(builddir)/tools/tools/kvm/kvm_stat/*.1 \ + $(hosttoolsman)/man1 +endif + +prepare-indep: + @echo Debug: $@ + dh_prep -i + +install-indep: install-headers install-doc install-source install-tools + @echo Debug: $@ + +# This is just to make it easy to call manually. Normally done in +# binary-indep target during builds. +binary-headers: prepare-indep install-headers + @echo Debug: $@ + dh_installchangelogs -p$(indep_hdrpkg) + dh_installdocs -p$(indep_hdrpkg) + dh_compress -p$(indep_hdrpkg) + dh_fixperms -p$(indep_hdrpkg) + dh_installdeb -p$(indep_hdrpkg) + $(lockme) dh_gencontrol -p$(indep_hdrpkg) + dh_md5sums -p$(indep_hdrpkg) + dh_builddeb -p$(indep_hdrpkg) + +binary-indep: cloudpkg = $(cloud_common_pkg_name) +binary-indep: install-indep + @echo Debug: $@ + dh_installchangelogs -i + dh_installdocs -i + dh_compress -i + dh_fixperms -i +ifeq ($(do_tools_common),true) +ifeq ($(do_cloud_tools),true) +ifeq ($(do_tools_hyperv),true) + dh_installinit -p$(cloudpkg) -n --name hv-kvp-daemon + dh_installinit -p$(cloudpkg) -n --name hv-vss-daemon + dh_installinit -p$(cloudpkg) -n --name hv-fcopy-daemon + dh_installudev -p$(cloudpkg) -n --name hv-kvp-daemon + dh_installudev -p$(cloudpkg) -n --name hv-vss-daemon + dh_installudev -p$(cloudpkg) -n --name hv-fcopy-daemon + dh_systemd_enable -p$(cloudpkg) + dh_installinit -p$(cloudpkg) -o --name hv-kvp-daemon + dh_installinit -p$(cloudpkg) -o --name hv-vss-daemon + dh_installinit -p$(cloudpkg) -o --name hv-fcopy-daemon + dh_systemd_start -p$(cloudpkg) +endif + # Keep intel_sgx service disabled by default, so add it after dh_systemd_enable + # and dh_systemd_start are called: + dh_installinit -p$(cloudpkg) --no-start --no-enable --name intel-sgx-load-module +endif +endif + dh_installdeb -i + $(lockme) dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i --- linux-oracle-5.4.0.orig/debian/rules.d/4-checks.mk +++ linux-oracle-5.4.0/debian/rules.d/4-checks.mk @@ -0,0 +1,14 @@ +checks-%: install-% + @echo Debug: $@ + +# Check the config against the known options list. +config-prepare-check-%: $(stampdir)/stamp-prepare-tree-% + @echo Debug: $@ + if [ -e $(commonconfdir)/config.common.ubuntu ]; then \ + perl -f $(DROOT)/scripts/config-check \ + $(builddir)/build-$*/.config "$(arch)" "$*" "$(commonconfdir)" \ + "$(skipconfig)" "$(do_enforce_all)"; \ + else \ + python3 $(DROOT)/scripts/misc/annotations -f $(commonconfdir)/annotations \ + --arch $(arch) --flavour $* --check $(builddir)/build-$*/.config; \ + fi --- linux-oracle-5.4.0.orig/debian/rules.d/5-udebs.mk +++ linux-oracle-5.4.0/debian/rules.d/5-udebs.mk @@ -0,0 +1,79 @@ +# Do udebs if not disabled in the arch-specific makefile +binary-udebs: binary-debs + @echo Debug: $@ +ifeq ($(disable_d_i),) + @$(MAKE) --no-print-directory -f $(DROOT)/rules DEBIAN=$(DEBIAN) \ + do-binary-udebs +endif + +do-binary-udebs: linux_udeb_name=$(shell if echo $(src_pkg_name)|egrep -q '(linux-lts|linux-hwe)'; then echo $(src_pkg_name); else echo linux; fi) +do-binary-udebs: debian/control + @echo Debug: $@ + dh_testdir + dh_testroot + + # unpack the kernels into a temporary directory + mkdir -p debian/d-i-${arch} + + imagelist=$$(cat $(CURDIR)/$(DEBIAN)/d-i/kernel-versions | grep ^${arch} | gawk '{print $$3}') && \ + for f in $$imagelist; do \ + i=$(release)-$(abinum)-$$f; \ + for f in \ + ../linux-image-$$i\_$(release)-$(revision)_${arch}.deb \ + ../linux-image-unsigned-$$i\_$(release)-$(revision)_${arch}.deb \ + ../linux-modules-$$i\_$(release)-$(revision)_${arch}.deb \ + ../linux-modules-extra-$$i\_$(release)-$(revision)_${arch}.deb; \ + do \ + [ -f $$f ] && dpkg -x $$f debian/d-i-${arch}; \ + done; \ + /sbin/depmod -b debian/d-i-${arch} $$i; \ + done + + # kernel-wedge will error if no modules unless this is touched + touch $(DEBIAN)/d-i/no-modules + + touch $(CURDIR)/$(DEBIAN)/d-i/ignore-dups + export KW_DEFCONFIG_DIR=$(CURDIR)/$(DEBIAN)/d-i && \ + export KW_CONFIG_DIR=$(CURDIR)/$(DEBIAN)/d-i && \ + export SOURCEDIR=$(CURDIR)/debian/d-i-${arch} && \ + kernel-wedge install-files $(release)-$(abinum) && \ + kernel-wedge check + + # Build just the udebs + dilist=$$(dh_listpackages -s | grep "\-di$$") && \ + [ -z "$dilist" ] || \ + for i in $$dilist; do \ + dh_fixperms -p$$i; \ + $(lockme) dh_gencontrol -p$$i; \ + dh_builddeb -p$$i; \ + done + + # Generate the meta-udeb dependancy lists. + @gawk ' \ + /^Package:/ { \ + package=$$2; flavour=""; parch="" } \ + (/Package-Type: udeb/ && package !~ /^$(linux_udeb_name)-udebs-/) { \ + match(package, "'$(release)'-'$(abinum)'-(.*)-di", bits); \ + flavour = bits[1]; \ + } \ + (/^Architecture:/ && $$0 " " ~ / '$(arch)'/) { \ + parch=$$0; \ + } \ + (flavour != "" && parch != "") { \ + udebs[flavour] = udebs[flavour] package ", "; \ + flavour=""; parch=""; \ + } \ + END { \ + for (flavour in udebs) { \ + package="$(linux_udeb_name)-udebs-" flavour; \ + file="debian/" package ".substvars"; \ + print("udeb:Depends=" udebs[flavour]) > file; \ + metas="'$(builddir)'/udeb-meta-packages"; \ + print(package) >metas \ + } \ + } \ + ' <$(CURDIR)/debian/control + @while read i; do \ + $(lockme) dh_gencontrol -p$$i; \ + dh_builddeb -p$$i; \ + done <$(builddir)/udeb-meta-packages --- linux-oracle-5.4.0.orig/debian/scripts/config-check +++ linux-oracle-5.4.0/debian/scripts/config-check @@ -0,0 +1,163 @@ +#!/usr/bin/perl +# +# check-config -- check the current config for issues +# +use strict; +use File::Basename; +use File::Spec; + +my $P = 'check-config'; + +my $test = -1; +if ($ARGV[0] eq '--test') { + $test = $ARGV[1] + 0; +} elsif ($#ARGV != 5) { + die "Usage: $P \n"; +} + +my ($configfile, $arch, $flavour, $commonconfig, $warn_only, $enforce_all) = @ARGV; + +my %values = (); + +# If we are in overridden then still perform the checks and emit the messages +# but do not return failure. Those items marked FATAL will alway trigger +# failure. +my $fail_exit = 1; +$fail_exit = 0 if ($warn_only eq 'true' || $warn_only eq '1'); +my $exit_val = 0; + +$enforce_all = 0 if $enforce_all eq "no" or $enforce_all eq "false"; + +# Load up the current configuration values -- FATAL if this fails +print "$P: $configfile: loading config\n"; +open(CONFIG, "<$configfile") || die "$P: $configfile: open failed -- $! -- aborting\n"; +while () { + # Pull out values. + /^#*\s*(CONFIG_\w+)[\s=](.*)$/ or next; + if ($2 eq 'is not set') { + $values{$1} = 'n'; + } else { + $values{$1} = $2; + } +} +close(CONFIG); + +sub read_annotations { + my ($filename) = @_; + my %annot; + my $form = 1; + my ($config, $value, $options); + + # Keep track of the configs that shouldn't be appended because + # they were include_annot from another annotations file. + # That's a hash of undefs, aka a set. + my %noappend; + + print "$P: $filename loading annotations\n"; + open(my $fd, "<$filename") || + die "$P: $filename: open failed -- $! -- aborting\n"; + while (<$fd>) { + if (/^# FORMAT: (\S+)/) { + die "$P: $1: unknown annotations format\n" if ($1 < 2 || $1 > 4); + $form = $1; + } + + # Format #3 and #4 add the include directive on top of format #2: + if ($form >= 3 && /^\s*include(\s|$)/) { + # Include quoted or unquoted files: + if (/^\s*include\s+"(.*)"\s*$/ || /^\s*include\s+(.*)$/) { + # The include is relative to the current file + my $include_filename = File::Spec->join(dirname($filename), $1); + # Append the include files + my %include_annot = read_annotations($include_filename); + %annot = ( %annot, %include_annot ); + # And marked them to not be appended: + my %included_noappend; + # Discard the values and keep only the keys + @included_noappend{keys %include_annot} = (); + %noappend = ( %noappend, %included_noappend ); + next; + } else { + die "$P: Invalid include: $_"; + } + } + + /^#/ && next; + chomp; + /^$/ && next; + /^CONFIG_/ || next; + + if ($form == 1) { + ($config, $value, $options) = split(' ', $_, 3); + } elsif ($form >= 2) { + ($config, $options) = split(' ', $_, 2); + } + + if (exists $noappend{$config}) { + delete $annot{$config}; + delete $noappend{$config}; + } + $annot{$config} = $annot{$config} . ' ' . $options; + } + close($fd); + return %annot; +} + +# ANNOTATIONS: check any annotations marked for enforcement +my $annotations = "$commonconfig/annotations"; +my %annot = read_annotations($annotations); + +my $pass = 0; +my $total = 0; +my ($config, $value, $options, $option, $check, $policy); +for $config (keys %annot) { + $check = $enforce_all; + $options = $annot{$config}; + + $policy = undef; + while ($options =~ /\s*([^\s<]+)<(.*?)?>/g) { + ($option, $value) = ($1, $2); + + if ($option eq 'mark' && $value eq 'ENFORCED') { + $check = 1; + + } elsif ($option eq 'policy') { + if ($value =~ /^{/) { + $value =~ s/:/=>/g; + $policy = eval($value); + warn "$config: $@" if ($@); + } else { + $policy = undef; + } + } + } + if ($check == 1 && !defined($policy)) { + print "$P: INVALID POLICY (use policy<{...}>) $config$options\n"; + $total++; + $check = 0; + } + if ($check) { + # CONFIG_VERSION_SIGNATURE is dynamically set during the build + next if ($config eq "CONFIG_VERSION_SIGNATURE"); + my $is = '-'; + $is = $values{$config} if (defined $values{$config}); + + my $value = '-'; + for my $which ("$arch-$flavour", "$arch-*", "*-$flavour", "$arch", "*") { + if (defined $policy->{$which}) { + $value = $policy->{$which}; + last; + } + } + if ($is eq $value) { + $pass++; + } else { + print "$P: FAIL ($is != $value): $config$options\n"; + $exit_val = $fail_exit; + } + $total++; + } +} + +print "$P: $pass/$total checks passed -- exit $exit_val\n"; +exit $exit_val; --- linux-oracle-5.4.0.orig/debian/scripts/control-create +++ linux-oracle-5.4.0/debian/scripts/control-create @@ -0,0 +1,40 @@ +#!/bin/bash + +. debian/debian.env + +vars=$1 +any_signed=$2 + +. $vars + +[ "$provides" != '' ] && provides="$provides, " + +if [ "$is_sub" = "" ]; then + flavour=$(basename $vars | sed 's/.*\.//') + stub="${DEBIAN}/control.d/flavour-control.stub debian/control.d/flavour-buildinfo.stub" + if [ "$any_signed" = 'true' ]; then + sign_me_pkg="-unsigned" + sign_me_txt=" unsigned" + sign_peer_pkg="" + else + sign_me_pkg="" + sign_me_txt="" + sign_peer_pkg="-unsigned" + fi +else + flavour=$(basename $vars .vars) + stub=${DEBIAN}/sub-flavours/control.stub +fi + +cat $stub | grep -v '^#' | sed \ + -e "s#FLAVOUR#$flavour#g" \ + -e "s#DESC#$desc#g" \ + -e "s#ARCH#$arch#g" \ + -e "s#SUPPORTED#$supported#g" \ + -e "s#TARGET#$target#g" \ + -e "s#BOOTLOADER#$bootloader#g" \ + -e "s#=PROVIDES=#$provides#g" \ + -e "s#=CONFLICTS=#$conflicts#g" \ + -e "s#=SIGN-ME-PKG=#$sign_me_pkg#g" \ + -e "s#=SIGN-ME-TXT=#$sign_me_txt#g" \ + -e "s#=SIGN-PEER-PKG=#$sign_peer_pkg#g" --- linux-oracle-5.4.0.orig/debian/scripts/dkms-build +++ linux-oracle-5.4.0/debian/scripts/dkms-build @@ -0,0 +1,261 @@ +#!/bin/sh +set -e + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +here=$(dirname "$(readlink -f "${0}")") + +srcdir=$(pwd) +cd "$dkms_dir" || exit 1 + +built_using_record() +{ + local subst="$1" + local built_using="$2" + if [ ! -f "$subst" ]; then + touch "$subst" + fi + if ! grep -q -s "^linux:BuiltUsing=" "$subst"; then + echo "linux:BuiltUsing=" >>"$subst" + fi + sed -i -e "s/^\(linux:BuiltUsing=.*\)/\1$built_using, /" "$subst" +} + +# ABI: returns present in $? and located path in lpackage_path when found. +package_present() +{ + for lpackage_path in "$1"_*.deb + do + break + done + [ -f "$lpackage_path" ] +} + +# Download and extract the DKMS package -- note there may be more +# than one package to install. +for package_path in "$@" +do + package_file=$(basename "$package_path") + echo "II: dkms-build downloading $package ($package_file)" + rpackage=$( echo "$package_path" | sed -e 's@.*/@@' -e 's@_.*@@' ) + lpackage=$( echo "$rpackage" | sed -e 's@=.*@@' ) + + while true + do + if package_present "$lpackage"; then + break + fi + case "$package_path" in + pool/*) + # Attempt download from the launchpad librarian first. + "$here/file-downloader" "https://launchpad.net/ubuntu/+archive/primary/+files/$package_file" || true + if package_present "$lpackage"; then + break + fi + + # Download from the available pools. + for pool in $( grep -h '^deb ' /etc/apt/sources.list /etc/apt/sources.list.d/*.list | awk '{print $2}' | sort -u ) + do + if package_present "$lpackage"; then + break + fi + url="$pool/$package_path" + "$here/file-downloader" "$url" && break || true + # No components in PPAs. + url=$(echo "$url" | sed -e 's@/pool/[^/]*/@/pool/main/@') + "$here/file-downloader" "$url" && break || true + done + ;; + http*:*) + "$here/file-downloader" "$package_path" + ;; + */*) + cp -p "$package_path" . + ;; + *) + apt-get download "$rpackage" + ;; + esac + break + done + if ! package_present "$lpackage"; then + echo "EE: $lpackage not found" + exit 1 + fi + + dpkg -x "$lpackage"_*.deb "$package" + + lversion=$( echo "$lpackage_path" | sed -e 's@.*/@@' -e 's@_[^_]*$@@' -e 's@.*_@@') + #built_using_record "$srcdir/debian/$pkgname.substvars" "$built_using$lpackage (= $lversion)" +done + +# Pick out the package/version from the dkms.conf. +for dkms_conf in "$package/usr/src"/*/"dkms.conf" +do + break +done + +# It seems some packages have a # in the name which works fine if the +# package is installed directly, but not so much if we build it out +# of the normal location. +sed -i -e '/^PACKAGE_NAME=/ s/#//g' "$dkms_conf" + +# Run any dkms-package specfic configuration steps +dkms_config_specific="$srcdir/$0-configure--$package" +dkms_config_generic=$(echo "$dkms_config_specific" | sed -e 's/-[0-9][0-9]*$/-N/') +for dkms_config in "$dkms_config_specific" "$dkms_config_generic" +do + if [ -z "$dkms_config" -o ! -e "$dkms_config" ]; then + continue + fi + echo "II: dkms-build-configure $(basename "$dkms_config") found, executing" + "$dkms_config" \ + "$srcdir" \ + "$dkms_conf" \ + "$dkms_dir" \ + "$abi_flavour" \ + "$sign" \ + "$pkgname" \ + "$pkgdir" \ + "$dbgpkgdir" \ + "$package" \ + "$@" || exit 1 + break +done + +cat - <<'EOF' >>"$dkms_conf" +POST_BUILD="ubuntu-save-objects ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/objects $POST_BUILD" +EOF +ubuntu_script="$(dirname "$dkms_conf")/ubuntu-save-objects" +cat - <<'EOF' >"$ubuntu_script" +#!/bin/sh +from="$1" +to="$2" +script="$3" +shift 2 + +# Copy the objects. +echo "II: copying objects to '$to'" +mkdir -p "$to" +(cd "$from" && find -name \*.o -o -name \*.o.ur-\* | cpio -Lpd "$to") + +# Call the original post_install script if there is one. +[ "$script" = '' ] && exit 0 + +shift +exec "$(dirname "$0")/$script" "$@" +EOF +chmod +x "$ubuntu_script" +dkms_package=$( sed -ne 's/PACKAGE_NAME="\(.*\)"/\1/p' "$dkms_conf" ) +dkms_version=$( sed -ne 's/PACKAGE_VERSION="\(.*\)"/\1/p' "$dkms_conf" ) + +# Build the DKMS binaries. +echo "II: dkms-build building $package" +fakeroot="" +[ $(id -u) -ne 0 ] && fakeroot="/usr/bin/fakeroot" +rc=0 +$fakeroot /usr/sbin/dkms build --no-prepare-kernel --no-clean-kernel \ + -k "$abi_flavour" \ + --sourcetree "$dkms_dir/source" \ + --dkmstree "$dkms_dir/build" \ + --kernelsourcedir "$dkms_dir/headers/linux-headers-$abi_flavour" \ + "$dkms_conf" || rc=1 + +# Find the log and add it to our own. +for log in "$dkms_dir/build/$dkms_package/$dkms_version/$abi_flavour"/*/"log/make.log" "$dkms_dir/build/$dkms_package/$dkms_version/build/make.log" +do + [ -f "$log" ] && break +done +sed -e "s@$dkms_dir@<>@g" <"$log" + +# If this build failed then exit here. +[ "$rc" != 0 ] && exit "$rc" + +# Install the modules with debug symbols we possibly built, +# and strip the original modules for the next install step. +if [ -n "$dbgpkgdir" ]; then + dbgpkgdir="$dbgpkgdir/$package" + echo "II: dkms-build installing $package into $dbgpkgdir (debug symbols)" + install -d "$dbgpkgdir" + find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko | + while read module; do + vmodule=$( basename "$module" ) + + # Check for '.debug_info' section in order to copy module. + # Useful if debug symbols are requested but not built for + # any reason (including not yet supported by DKMS package). + # Strip module just in case even if section isn't present. + if ${CROSS_COMPILE}objdump -h -j '.debug_info' "$module" >/dev/null 2>&1 + then + echo "copying $vmodule" + cp "$module" "$dbgpkgdir" + else + echo "ignoring $vmodule (missing debug symbols)" + fi + + # Just 'strip -g' as '/usr/sbin/dkms' does. + echo "stripping $vmodule" + strip -g "$module" + done +fi + +# Install and optionally sign the modules we have built. +pkgdir="$pkgdir/$package" +echo "II: dkms-build installing $package into $pkgdir" +install -d "$pkgdir" +find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko | +while read module; do + vmodule=$( basename "$module" ) + case "$sign" in + --*) + echo "copying $vmodule" + cp "$module" "$pkgdir" + ;; + *) + echo "signing $vmodule" + $sign "$module" "$pkgdir/$vmodule" + ;; + esac +done + +find "$dkms_dir/build/$dkms_package/$dkms_version/objects" -name \*.o -print | \ +while read object +do + "$srcdir/debian/scripts/fix-filenames" "$object" "$dkms_dir" +done + +# Finally see if there is a dkms-package specific post processor present. Hand +# it the original source directory, destination package directory, the objects +# as squirreled away, and the log in case it is useful. Finally pass a formed +# signing command line in case we need to do that. +dkms_build_specific="$srcdir/$0--$package" +dkms_build_generic=$(echo "$dkms_build_specific" | sed -n -e 's/-[0-9][0-9]*[a-z]*$/-N/p') +for dkms_build in "$dkms_build_specific" "$dkms_build_generic" +do + if [ -z "$dkms_build" -o ! -e "$dkms_build" ]; then + continue + fi + echo "II: dkms-build override $(basename "$dkms_build") found, executing" + "$dkms_build" \ + "$srcdir" \ + "$dkms_dir/build/$dkms_package/$dkms_version/objects" \ + "$log" \ + "$dkms_dir" \ + "$abi_flavour" \ + "$sign" \ + "$pkgname" \ + "$pkgdir" \ + "$dbgpkgdir" \ + "$package" \ + "$@" || exit 1 + break +done + +echo "II: dkms-build build $package complete" --- linux-oracle-5.4.0.orig/debian/scripts/dkms-build--nvidia-N +++ linux-oracle-5.4.0/debian/scripts/dkms-build--nvidia-N @@ -0,0 +1,113 @@ +#!/bin/sh +set -e + +srcdir="$1" +objects="$2" +log="$3" +shift 3 + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +build="$( dirname "$objects" )/build" + +# Copy over the objects ready for reconstruction. The objects copy contains +# the *.o files and the *.o-ur* retpoline files to allow the kernel to track +# any retpoline sequences therein. For our purposes we only want the *.o +# files, elide the rest. +mkdir -p "$pkgdir/bits/scripts" +( + gcc_variant1=$(gcc --version | head -1 | sed -e 's/^gcc/GCC:/') + gcc_variant2=$(gcc --version | head -1 | sed -e 's/^\(gcc\) \((.*)\) \(.*\)$/\1 version \3 \2/') + cd "$objects" || exit 1 + find -name \*.o | \ + while read file + do + cp --parents "$file" "$pkgdir/bits" + "$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant1" + "$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant2" + done +) + +# Install the support files we need. +echo "II: copying support files ..." +for lds_src in \ + "$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module.lds" \ + "/usr/src/linux-headers-$abi_flavour/scripts/module.lds" \ + "$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module-common.lds" \ + "/usr/src/linux-headers-$abi_flavour/scripts/module-common.lds" +do + [ ! -f "$lds_src" ] && continue + echo "II: copying support files ... found $lds_src" + cp "$lds_src" "$pkgdir/bits/scripts" + break +done + +# Build helper scripts. +cat - <<'EOL' >"$pkgdir/bits/BUILD" +[ "$1" = "unsigned" ] && { signed_only=:; shift; } +[ "$1" = "nocheck" ] && { check_only=:; shift; } +EOL +grep /usr/bin/ld.bfd "$log" | grep -v scripts/genksyms/genksyms | sed -e "s@$build/@@g" >>"$pkgdir/bits/BUILD" +sed -e 's/.*-o *\([^ ]*\) .*/rm -f \1/g' <"$pkgdir/bits/BUILD" >"$pkgdir/bits/CLEAN" + +# As the builds contain the absolute filenames as used. Use RECONSTRUCT to +# rebuild the .ko's, sign them, pull off the signatures and then finally clean +# up again. +( + cd "$pkgdir/bits" || exit 1 + + # Add checksum check. + echo "\$check_only sha256sum -c SHA256SUMS || exit 1" >>"$pkgdir/bits/BUILD" + + # Add .ko handling to the CLEAN/BUILD dance. + for ko in "$pkgdir"/*.ko + do + ko=$(basename "$ko") + echo "\$signed_only cat '$ko' '$ko.sig' >'../$ko'" >>"$pkgdir/bits/BUILD" + echo "\$signed_only rm -f '$ko'" >>"$pkgdir/bits/BUILD" + echo "rm -f '../$ko'" >>"$pkgdir/bits/CLEAN" + done + + # Clear out anything we are not going to distribute and build unsigned .kos. + sh ./CLEAN + sh ./BUILD unsigned nocheck + + if [ "$sign" = "--custom" ]; then + # We are building for and archive custom signing upload. Keep everything. + : + elif [ "$sign" = "--lrm" ]; then + # We are in the LRM build; grab sha256 checksums and clean up. + sha256sum -b *.ko >"SHA256SUMS" + sh ./CLEAN + + else + # We are in the main kernel, put the .kos together as we will + # on the users machine, sign them, and keep just the signature. + : >"SHA256SUMS" + for ko in *.ko + do + echo "detached-signature $ko" + $sign "$ko" "$ko.signed" + length=$( stat --format %s "$ko" ) + dd if="$ko.signed" of="$ko.sig" bs=1 skip="$length" 2>/dev/null + + rm -f "$ko.signed" + # Keep a checksum of the pre-signed object so we can check it is + # built correctly in LRM. + sha256sum -b "$ko" >>"SHA256SUMS" + done + + # Clean out anything which not a signature. + mv "$pkgdir/bits/"*.sig "$pkgdir" + mv "$pkgdir/bits/SHA256SUMS" "$pkgdir" + find "$pkgdir" -name \*.sig -prune -o -name SHA256SUMS -prune -o -type f -print | xargs rm -f + find "$pkgdir" -depth -type d -print | xargs rmdir --ignore-fail-on-non-empty + fi +) || exit "$?" --- linux-oracle-5.4.0.orig/debian/scripts/dkms-build--virtualbox-guest +++ linux-oracle-5.4.0/debian/scripts/dkms-build--virtualbox-guest @@ -0,0 +1,19 @@ +#!/bin/sh + +srcdir="$1" +objects="$2" +log="$3" +shift 3 + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +# We want to ship the vboxvideo.ko from the upstream staging tree, so +# remove the one built via dkms. +rm -f "$pkgdir/vboxvideo.ko" --- linux-oracle-5.4.0.orig/debian/scripts/dkms-build-configure--zfs +++ linux-oracle-5.4.0/debian/scripts/dkms-build-configure--zfs @@ -0,0 +1,23 @@ +#!/bin/sh + +srcdir="$1" +dkms_conf="$2" +shift 2 + +dkms_dir="$1" +abi_flavour="$2" +sign="$3" +pkgname="$4" +pkgdir="$5" +dbgpkgdir="$6" +package="$7" +shift 7 + +# ZFS debug symbols are enabled in dkms.conf via PACKAGE_CONFIG file. +if [ -n "$dbgpkgdir" ]; then + echo "enable zfs debug symbols" + pkg_cfg="$(dirname "$dkms_conf")/pkg_cfg" + echo 'ZFS_DKMS_ENABLE_DEBUGINFO=yes' >"$pkg_cfg" + echo 'ZFS_DKMS_DISABLE_STRIP=yes' >>"$pkg_cfg" + sed -i "s,^\(PACKAGE_CONFIG=\).*,\1$pkg_cfg," $dkms_conf +fi --- linux-oracle-5.4.0.orig/debian/scripts/file-downloader +++ linux-oracle-5.4.0/debian/scripts/file-downloader @@ -0,0 +1,34 @@ +#!/bin/sh + +if [ "$#" -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi +url="$1" + +to=$(basename "$url") + +count=0 +what='fetching' +while : +do + if [ "$count" -eq 20 ]; then + echo "EE: excessive redirects" 1>&2 + exit 1 + fi + count=$(($count+1)) + + echo "II: $what $url" + + curl --silent --fail --show-error "$url" -o "$to" -D "$to.hdr" || exit 1 + redirect=$(awk '/^Location: / {gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2); print $2;}' "$to.hdr") + [ -z "$redirect" ] && break + what=' following' + + url=$(echo "$redirect" | sed -e 's@https://launchpadlibrarian.net/@http://launchpadlibrarian.net/@') + if [ "$redirect" != "$url" ]; then + echo "II: fixing $redirect" + fi +done + +exit 0 --- linux-oracle-5.4.0.orig/debian/scripts/fix-filenames.c +++ linux-oracle-5.4.0/debian/scripts/fix-filenames.c @@ -0,0 +1,80 @@ +/* + * fix-filenames: find a specified pathname prefix and remove it from + * C strings. + * + * Copyright (C) 2018 Canonical Ltd. + * Author: Andy Whitcroft + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int rc; + char *in_name; + char *prefix; + int prefix_len; + int in_fd; + struct stat in_info; + char *in; + off_t size; + int length; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + in_name = argv[1]; + prefix = argv[2]; + prefix_len = strlen(prefix); + + in_fd = open(in_name, O_RDWR); + if (in_fd < 0) { + perror("open input failed"); + exit(1); + } + + rc = fstat(in_fd, &in_info); + if (rc < 0) { + perror("fstat input failed"); + exit(1); + } + size = in_info.st_size; + + in = mmap((void *)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, in_fd, (off_t)0); + if (!in) { + perror("mmap failed"); + exit(1); + } + + for (; size > 0; size--, in++) { + if (*in != *prefix) + continue; + if (strncmp(in, prefix, prefix_len) != 0) + continue; + /* In the case of an exact match there there is nothing to move. */ + if (in[prefix_len] == '\0') + length = 0; + /* If this is a filename, strip the leading slash. */ + else if (in[prefix_len] == '/') + length = strlen(in + prefix_len + 1) + 1; + /* Otherwise just keep the suffix. */ + else + length = strlen(in + prefix_len) + 1; + + /* + * Copy the suffix portion down to the start and clear + * the remainder of the space to 0. + */ + memmove(in, in + prefix_len + 1, length); + memset(in + length, '\0', prefix_len); + } +} --- linux-oracle-5.4.0.orig/debian/scripts/link-headers +++ linux-oracle-5.4.0/debian/scripts/link-headers @@ -0,0 +1,42 @@ +#!/bin/bash -e + +. debian/debian.env + +hdrdir="$1" +symdir="$2" +flavour="$3" + +echo "Symlinking and copying headers for $flavour..." + +excludes="( -path ./debian -prune -o -path ./${DEBIAN} -prune -o -path ./.git ) -prune -o" + +( +find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print +find ./include ./scripts -name .gitignore -prune -o -type f -print +find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print +) | ( +while read file; do + dir=$file + lastdir=$file + + if [ -e "$hdrdir/$file" -o -L "$hdrdir/$file" ]; then + continue + fi + + while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do + lastdir=$dir + dir=`dirname $dir` + done + # If the last item to exist is a symlink we assume all is good + if [ ! -L "$hdrdir/$dir" ]; then + # Turns things like "./foo" into "../" + deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`" + item="`echo -n $lastdir | sed -e 's/^\.\///'`" + ln -s $deref$symdir/$item $hdrdir/$item + fi +done +) + +exit --- linux-oracle-5.4.0.orig/debian/scripts/misc/annotations +++ linux-oracle-5.4.0/debian/scripts/misc/annotations @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# -*- mode: python -*- + +# This file is not installed; it's just to run annotations from inside a source +# distribution without installing it in the system. + +import sys + +# Prevent generating .pyc files on import +# +# We may end up adding these files to our git repos by mistake, so simply +# prevent generating them in advance. +# +# There's a tiny performance penalty with this, because python needs to +# re-generate the bytecode on-the-fly every time the script is executed, but +# this overhead is absolutely negligible compared the rest of the kernel build +# time. +sys.dont_write_bytecode = True + +import os # noqa: E402 Import not at top of file +from kconfig import run # noqa: E402 Import not at top of file + + +# Update PATH to make sure that annotations can be executed directly from the +# source directory. +def update_path(): + script_dir = os.path.dirname(os.path.abspath(__file__)) + current_path = os.environ.get("PATH", "") + new_path = f"{script_dir}:{current_path}" + os.environ["PATH"] = new_path + + +update_path() +exit(run.main()) --- linux-oracle-5.4.0.orig/debian/scripts/misc/arch-has-odm-enabled.sh +++ linux-oracle-5.4.0/debian/scripts/misc/arch-has-odm-enabled.sh @@ -0,0 +1,30 @@ +#!/bin/sh +# Evaluate whether arch ($1) will be built with do_odm_drivers set to true. +set -e + +if [ "$1" = "" ]; then + # This would be set doing the actual kernel build + if [ "$KBUILD_VERBOSE" = "" ]; then + return 1 + fi + case $ARCH in + x86) ARCH=amd64;; + *) ;; + esac +else + ARCH=$1 +fi + +TOPDIR=$(dirname $0)/../../.. +. $TOPDIR/debian/debian.env +RULESDIR=$TOPDIR/$DEBIAN/rules.d + +do_odm_drivers=false +for f in $ARCH.mk hooks.mk; do + eval $(cat $RULESDIR/$f | sed -n -e '/do_odm_drivers/s/ \+//gp') +done +if [ "$do_odm_drivers" != "true" ]; then + return 1 +fi + +return 0 --- linux-oracle-5.4.0.orig/debian/scripts/misc/final-checks +++ linux-oracle-5.4.0/debian/scripts/misc/final-checks @@ -0,0 +1,52 @@ +#!/bin/bash + +debian="$1" +abi="$2" +abi=${abi%~*} + +. "$debian/etc/kernelconfig" +archs=$( awk '/^Architecture:/ { $1=""; for (i=1; i<=NF; i++) { if ($i != "all") { print $i }}}' debian/control | sort -u) + +fail=0 + +failure() +{ + echo "EE: $@" 1>&2 + fail=1 +} + +if [ -e $debian/config/config.common.ubuntu ]; then + if [ -d debian/certs ]; then + if ! grep -q '^CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"$' $debian/config/config.common.ubuntu; then + failure "'CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"' is required" + fi + fi + + if [ -d debian/revoked-certs ]; then + if ! grep -q '^CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"$' $debian/config/config.common.ubuntu; then + failure "'CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"' is required" + fi + fi +fi + +for arch in $archs +do + image_pkg=$(awk -F '\\s*=\\s*' '$1 == "do_flavour_image_package" { print $2 }' $debian/rules.d/$arch.mk) + if [ "$image_pkg" = "false" ]; then + continue + fi + if [ ! -f "$debian/rules.d/$arch.mk" ]; then + continue + fi + flavours=$( + awk '/^\s*flavours\s*=/{ + sub(/^\s*flavours\s*=\s*/, ""); + print + }' "$debian/rules.d/$arch.mk") + for flavour in $flavours + do + flavour=$(echo "$flavour" | sed -e 's@.*/config.flavour.@@') + done +done + +exit "$fail" --- linux-oracle-5.4.0.orig/debian/scripts/misc/find-missing-sauce.sh +++ linux-oracle-5.4.0/debian/scripts/misc/find-missing-sauce.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# +# Find the 'UBUNTU: SAUCE:' patches that have been dropped from +# the previous release. +# +PREV_REL=artful +PREV_REPO=git://kernel.ubuntu.com/ubuntu/ubuntu-${PREV_REL}.git + +git fetch ${PREV_REPO} master-next +git log --pretty=oneline FETCH_HEAD|grep SAUCE|while read c m;do echo $m;done |sort > $$.prev-rel +git log --pretty=oneline |grep SAUCE|while read c m;do echo $m;done |sort > $$.curr-rel + +diff -u $$.prev-rel $$.curr-rel |grep "^-" +rm -f $$.prev-rel $$.curr-rel + --- linux-oracle-5.4.0.orig/debian/scripts/misc/find-obsolete-firmware +++ linux-oracle-5.4.0/debian/scripts/misc/find-obsolete-firmware @@ -0,0 +1,91 @@ +#!/bin/bash +# +# Find all duplicate or obsolete firmware that is being carried +# in the kernel firmware directory. Compare these files against +# the linux-firmware package for the approriate release. For example, +# assuming this is raring, then compare the kernel firmware files +# against the raring branch of linux-firmware. +# +# Example: $0 ~/ubuntu/linux-firmware-raring + +USEAGE="$0 LINUX-FIRMWARE" + +. debian/debian.env + +NFWINFO="`find $DEBIAN -name fwinfo|wc -l`" +if [ ! "$NFWINFO" = "1" ] +then + echo Your repo is hosed. There can only be one fwinfo file. + find $DEBIAN -name fwinfo + exit 1 +fi + +FWINFO="`pwd`/`find $DEBIAN -name fwinfo`" + +if [ "$1" = "" ] +then + echo $USEAGE + exit 1 +fi +FW="$1" + +if [ ! -f $FW/WHENCE ] +then + echo Bogus linux-firmware directory + exit 1 +fi +if ! egrep -q "^firmware:" $FWINFO +then + echo Bogus firmware info file + exit 1 +fi + +# +# Prepare the tree and make firmware. +# +TEE="tee -a" +LO=`pwd`/firmware.txt +LF=`pwd`/lib/firmware +rm -rf debian/build $LF $LO +fakeroot debian/rules clean prepare-generic +cp debian/build/build-generic/.config . +mkdir -p $LF +make firmware_install INSTALL_MOD_PATH=`pwd` + +(cd $LF +find . -type f | while read f +do + BN="`basename $f`" + + if ! grep -q $BN $FWINFO + then + echo "Unused firmware: $f" | $TEE $LO + else + if [ -f $FW/$f ] + then + if ! cmp $FW/$f $f + then + echo "$f differs" | $TEE $LO + else + echo "$f is duplicated" | $TEE $LO + fi + else + echo "$f does not exist in $FW" | $TEE $LO + fi + fi +done) + +# +# Check for firmware files referenced by the kernel +# that do not exist in either location. +# +cat $FWINFO | while read fwi f +do + if [ -s lib/firmware/$f ] || [ -s $FW/$f ] + then + continue + else + echo "Missing firmware $f" | $TEE $LO + fi +done + --- linux-oracle-5.4.0.orig/debian/scripts/misc/fw-to-ihex.sh +++ linux-oracle-5.4.0/debian/scripts/misc/fw-to-ihex.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +F=$1 +if [ "$F" = "" ] +then + echo You must supply a firmware file. + exit 1 +fi + +echo "unsigned char d[] = {" > $F.c +hexdump -v -e '"\t" 8/1 "0x%02x, " "\n"' $F >> $F.c +echo "};" >> $F.c +sed -i 's/0x .*$//' $F.c + +O="`dirname $F`/`basename $F`.o" +gcc -o $O -c $F.c +objcopy -Oihex $F.o $F.ihex + --- linux-oracle-5.4.0.orig/debian/scripts/misc/gen-auto-reconstruct +++ linux-oracle-5.4.0/debian/scripts/misc/gen-auto-reconstruct @@ -0,0 +1,89 @@ +#!/bin/bash + +if [ "$#" -ne 3 ]; then + echo "Usage: $0 | " 1>&2 + exit 1 +fi +tag="$1" +reconstruct="$2" +options="$3" + +case "$tag" in +v*) ;; +*) tag="v${tag%.*}" ;; +esac + +# Validate the tag. +count=$( git tag -l "$tag" | wc -l ) +if [ "$count" != 1 ]; then + echo "$0: $tag: tag invalid" 1>&2 + exit 1 +fi + +#git ls-tree -r --full-tree HEAD | grep ^120 | \ +#while read mode type blobid name + +( + # Identify all new symlinks since the proffered tag. + echo "# Recreate any symlinks created since the orig." + git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \ + while read name + do + link=$( readlink "$name" ) + + echo "[ ! -L '$name' ] && ln -sf '$link' '$name'" + done + + # Identify files with execute permissions added since the proffered tag. + git diff "$tag.." --raw --no-renames | awk -F '[: \t]' '{print $2, $3, $NF }' | \ + while IFS=" " read old new name + do + old=$( printf "0%s" $old ) + new=$( printf "0%s" $new ) + changed=$(( (old ^ new) & 0111 )) + if [ "$changed" -ne 0 ]; then + added=$(( new & 0111 )) + if [ "$added" -ne 0 ]; then + echo "chmod +x '$name'" + elif [ "$new" -ne 0 ]; then + echo "chmod -x '$name'" + fi + fi + done + + # Identify all removed files since the proffered tag. + echo "# Remove any files deleted from the orig." + git diff "$tag.." --raw --no-renames | awk '(/^:/ && $5 == "D") { print $NF }' | \ + while read name + do + echo "rm -f '$name'" + done + + # All done, make sure this does not complete in error. + echo "exit 0" +) >"$reconstruct" + +( + # Identify all new symlinks since the proffered tag. + echo "# Ignore any symlinks created since the orig which are rebuilt by reconstruct." + git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \ + while read name + do + echo "extend-diff-ignore=^$name\$" + done +) >"$options.update" + + +head='^## autoreconstruct -- begin$' +foot='^## autoreconstruct -- end$' +sed -i -e " + /$head/,/$foot/{ + /$head/{ + p; + r $options.update + }; + /$foot/p; + d + } +" "$options" +rm -f "$options.update" --- linux-oracle-5.4.0.orig/debian/scripts/misc/get-firmware +++ linux-oracle-5.4.0/debian/scripts/misc/get-firmware @@ -0,0 +1,62 @@ +#!/bin/bash +# +# Find all files in linux-firmware that are new or different since the previous release +# and copy them into the kernel firmware directory. You should only do this on the +# backport branch since it would be redundant on the released kernel. It assumed you've +# unpacked linux-firmware from each release into separate directories. +# +# Example: $0 ~/ubuntu/linux-firmware-precise ~/ubuntu/linux-firmware-quantal + +if [ "$1" = "" ] || [ "$2" = "" ] || [ ! -f $1/WHENCE ] || [ ! -f $2/WHENCE ] +then + echo You must supply 2 firmware directories. + exit 1 +fi + +if [ ! -f debian/debian.env ] +then + echo You must run this script from the root of the repo + exit 1 +fi +. debian/debian.env + +NFWINFO="`find $DEBIAN -name fwinfo|wc -l`" +if [ ! "$NFWINFO" = "1" ] +then + echo Your repo is hosed. There can only be one fwinfo file. + find $DEBIAN -name fwinfo + exit 1 +fi + +FWINFO="`pwd`/`find $DEBIAN -name fwinfo`" + +CDIR=`pwd` +OFW=$1 +NFW=$2 + +cd $NFW +# +# Find all files in $NFW that are new or different from $1 +# +(find . -type f | egrep -v "debian|git|LICEN|WHEN|READ|Make|configure" | sed 's;\./;;' | \ +while read f +do + if grep -q $f $FWINFO + then + if [ ! -f $OFW/$f ] + then + echo $f + elif ! cmp $f $OFW/$f > /dev/null + then + echo $f + fi + fi +done) |\ +while read f +do + mkdir -p $CDIR/firmware/`dirname $f` + if [ ! -f $CDIR/firmware/`dirname $f`/`basename $f`.ihex ] + then + cp -v $f $CDIR/firmware/`dirname $f` + fi +done --- linux-oracle-5.4.0.orig/debian/scripts/misc/git-ubuntu-log +++ linux-oracle-5.4.0/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +import sys + +import codecs +import urllib.request +import json + +import textwrap + +sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach()) +sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach()) + +entries = [] + + +def add_entry(entry): + global tracking_bug + + if entry and 'ignore' not in entry: + combo = [] + for bug in set(entry.get('bugs', [])): + combo.append(bug) + for cve in set(entry.get('cves', [])): + combo.append(cve) + combo = sorted(combo) + + if len(combo) == 0: + if entry.get('subject', "").startswith('UBUNTU'): + combo = '__packaging__' + else: + combo = '__mainline__' + else: + if entry.get('subject', "") == 'UBUNTU: link-to-tracker: update tracking bug': + tracking_bug = combo + if combo not in keys: + keys.append(combo) + + entry['key'] = combo + entries.append(entry) + + +# Suck up the git log output and extract the information we need. +keys = [] +tracking_bug = None +entry = None +subject_wait = False +for line in sys.stdin: + if line.startswith('commit '): + add_entry(entry) + entry = {} + subject_wait = True + + elif line.startswith('Author: '): + bits = line.strip().split(maxsplit=1) + entry['author'] = bits[1] + + elif subject_wait and line.startswith(' '): + subject_wait = False + entry['subject'] = line.strip() + + elif line.startswith(' BugLink: '): + bits = line.strip().split(maxsplit=2) + if len(bits) > 2: + # There is text after the URL, so use that (after stripping the + # enclosing characters) + entry.setdefault('bugs', []).append(bits[2][1:-1]) + elif 'launchpad.net' in bits[1]: + # Extract the bug number from the launchpad URL + bits = bits[1].split('/') + entry.setdefault('bugs', []).append(bits[-1]) + + elif line.startswith(' CVE-'): + entry.setdefault('cves', []).append(line.strip()) + + elif line.startswith(' Ignore:'): + entry['ignore'] = True + + elif line.startswith(' Properties:'): + for prop in line.strip().split()[1:]: + if prop in ('ignore', 'no-changelog'): + entry['ignore'] = True + +add_entry(entry) + +entries.reverse() + +# Go through the entries and clear out authors for upstream commits. +for entry in entries: + if entry['subject'].startswith('UBUNTU:'): + entry['subject'] = entry['subject'][7:].strip() + else: + del entry['author'] + +# Lump everything without a bug at the bottom. +keys.append('__packaging__') +keys.append('__mainline__') + +# Ensure we list the tracking bug updates first. +if tracking_bug is not None: + keys.remove(tracking_bug) + keys.insert(0, tracking_bug) + +emit_nl = False +for key in keys: + if key == '__packaging__': + title_set = ['Miscellaneous Ubuntu changes'] + elif key == '__mainline__': + title_set = ['Miscellaneous upstream changes'] + else: + title_set = [] + for bug in key: + if bug.startswith('CVE-'): + title_set.append(bug) + elif bug.isdigit(): + # Assume that it is an LP bug number if 'bug' contains only digits + bug_info = None + + try: + # urllib.request.urlcleanup() + request = urllib.request.Request('https://api.launchpad.net/devel/bugs/' + bug) + request.add_header('Cache-Control', 'no-cache') + with urllib.request.urlopen(request) as response: + data = response.read() + bug_info = json.loads(data.decode('utf-8')) + + title = bug_info['title'] + if 'description' in bug_info: + for line in bug_info['description'].split('\n'): + if line.startswith('Kernel-Description:'): + title = line.split(' ', 1)[1] + + except urllib.error.HTTPError: + title = 'INVALID or PRIVATE BUG' + + title += ' (LP###' + bug + ')' + title_set.append(title) + else: + # Finally treat 'bug' itself as the title + title_set.append(bug) + + emit_title = True + for entry in entries: + if entry['key'] != key: + continue + + if emit_title: + if emit_nl: + print('') + emit_nl = True + + title_lines = textwrap.wrap('#// '.join(title_set), 76) + print(' * ' + title_lines[0].replace('LP###', 'LP: #').replace('#//', ' //')) + for line in title_lines[1:]: + line = line.replace('LP###', 'LP: #').replace('#//', ' //') + print(' ' + line) + + emit_title = False + + if key != tracking_bug or (key == tracking_bug and entry['subject'] != "link-to-tracker: update tracking bug"): + title_lines = textwrap.wrap(entry['subject'], 76) + print(' - ' + title_lines[0]) + for line in title_lines[1:]: + line = line.replace('LP###', 'LP: #') + print(' ' + line) --- linux-oracle-5.4.0.orig/debian/scripts/misc/insert-changes.pl +++ linux-oracle-5.4.0/debian/scripts/misc/insert-changes.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl -w + +my $debian; +$droot = $ARGV[0] if (defined $ARGV[0]); +$droot = 'debian' if (!defined $droot); +$debian = $ARGV[1] if (defined $ARGV[1]); +$debian = 'debian.master' if (!defined $debian); + +system("make -s -f $droot/rules printchanges > $debian/changes"); + +open(CHANGELOG, "< $debian/changelog") or die "Cannot open changelog"; +open(CHANGES, "< $debian/changes") or die "Cannot open new changes"; +open(NEW, "> $debian/changelog.new") or die "Cannot open new changelog"; + +$printed = 0; +my $skip_newline = 0; + +while () { + if (/^ CHANGELOG: /) { + next if $printed; + + $skip_newline = 1; + while () { + $skip_newline = 0; + print NEW; + } + + $printed = 1; + } else { + if (/^$/ && $skip_newline == 1) { + $skip_newline = 0; + next; + } + print NEW; + } +} + +close(NEW); +close(CHANGES); +close(CHANGELOG); + +rename("$debian/changelog.new", "$debian/changelog"); +unlink("$debian/changes"); --- linux-oracle-5.4.0.orig/debian/scripts/misc/insert-mainline-changes +++ linux-oracle-5.4.0/debian/scripts/misc/insert-mainline-changes @@ -0,0 +1,42 @@ +#!/usr/bin/perl + +if ($#ARGV != 2) { + warn "Usage: $0 \n"; + die " $0 debian.master/changelog v3.2.3 v3.2.2..v3.2.3\n"; +} +my ($changelog, $to, $range) = @ARGV; + +my @changes = (); + +push(@changes, "\n"); +push(@changes, " [ Upstream Kernel Changes ]\n\n"); +push(@changes, " * rebase to $to\n"); + +open(LOG, "git log '$range'|") || die "$0: git log failed: - $!\n"; +while () { + if (m@BugLink: .*launchpad.net/.*/([0-9]+)\s$@) { + push(@changes, " - LP: #$1\n"); + } +} +close(LOG); + +open(CHANGELOG, "< $changelog") or die "Cannot open changelog"; +open(NEW, "> $changelog.new") or die "Cannot open new changelog"; + +$printed = 3; +while () { + if (/^ CHANGELOG: /) { + $printed--; + print NEW; + if ($printed == 0) { + print NEW @changes; + } + next; + } + print NEW; +} + +close(NEW); +close(CHANGELOG); + +rename("$changelog.new", "$changelog"); --- linux-oracle-5.4.0.orig/debian/scripts/misc/insert-ubuntu-changes +++ linux-oracle-5.4.0/debian/scripts/misc/insert-ubuntu-changes @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +if ($#ARGV != 2 && $#ARGV != 3) { + die "Usage: $0 []\n"; +} +if ($#ARGV == 2) { + push(@ARGV, "debian.master/changelog") +} +my ($changelog, $end, $start, $source_changelog) = @ARGV; + +$end =~ s/^\D+//; +$start =~ s/^\D+//; + +sub version_cmp($$) { + my @a = split(/[\.-]+/, $_[0]); + my @b = split(/[\.-]+/, $_[1]); + for (my $i = 1;; $i++) { + if (!defined $a[$i]) { + if (!defined $b[$i]) { + return 0; + } + return -1; + } + if (!defined $b[$i]) { + return 1; + } + if ($a[$i] < $b[$i]) { + return -1; + } + if ($a[$i] > $b[$i]) { + return 1; + } + } +} + +my @changes = (); +my $output = 0; +open(CHG, "<$source_changelog") || + open(CHG, ") { + if (/^\S+\s+\((.*)\)/) { + if (version_cmp($1, $end) <= 0) { + last; + } + if ($1 eq $start) { + $output = 1; + } + if ($output) { + push(@changes, "\n [ Ubuntu: $1 ]\n\n"); + next; + } + } + next if ($output == 0); + + next if (/^\s*$/); + next if (/^\s--/); + next if (/^\s\s[^\*\s]/); + + push(@changes, $_); +} +close(CHG); + +open(CHANGELOG, "< $changelog") or die "Cannot open changelog"; +open(NEW, "> $changelog.new") or die "Cannot open new changelog"; + +$printed = 3; +while () { + if (/^ CHANGELOG: /) { + $printed--; + print NEW; + if ($printed == 0) { + print NEW @changes; + } + next; + } + print NEW; +} + +close(NEW); +close(CHANGELOG); + +rename("$changelog.new", "$changelog"); --- linux-oracle-5.4.0.orig/debian/scripts/misc/kconfig/annotations.py +++ linux-oracle-5.4.0/debian/scripts/misc/kconfig/annotations.py @@ -0,0 +1,522 @@ +# -*- mode: python -*- +# python module to manage Ubuntu kernel .config and annotations +# Copyright © 2022 Canonical Ltd. + +import json +import re +import shutil +import tempfile + +from abc import abstractmethod +from ast import literal_eval +from os.path import dirname, abspath + +from kconfig.version import ANNOTATIONS_FORMAT_VERSION + + +class Config: + def __init__(self, fname, do_include=True): + """ + Basic configuration file object + """ + self.fname = fname + self.config = {} + self.do_include = do_include + + raw_data = self._load(fname) + self._parse(raw_data) + + @staticmethod + def _load(fname: str) -> str: + with open(fname, "rt", encoding="utf-8") as fd: + data = fd.read() + return data.rstrip() + + def __str__(self): + """Return a JSON representation of the config""" + return json.dumps(self.config, indent=4) + + @abstractmethod + def _parse(self, data: str): + pass + + +class KConfig(Config): + """ + Parse a .config file, individual config options can be accessed via + .config[] + """ + + def _parse(self, data: str): + self.config = {} + for line in data.splitlines(): + m = re.match(r"^# (CONFIG_.*) is not set$", line) + if m: + self.config[m.group(1)] = literal_eval("'n'") + continue + m = re.match(r"^(CONFIG_[A-Za-z0-9_]+)=(.*)$", line) + if m: + self.config[m.group(1)] = literal_eval("'" + m.group(2) + "'") + continue + + +class Annotation(Config): + """ + Parse body of annotations file + """ + + def __init__(self, fname, do_include=True, do_json=False): + self.do_json = do_json + super().__init__(fname, do_include=True) + + def _parse_body(self, data: str, parent=True): + for line in data.splitlines(): + # Replace tabs with spaces, squeeze multiple into singles and + # remove leading and trailing spaces + line = line.replace("\t", " ") + line = re.sub(r" +", " ", line) + line = line.strip() + + # Ignore empty lines + if not line: + continue + + # Catpure flavors of included files + if line.startswith("# FLAVOUR: "): + self.include_flavour += line.split(" ")[2:] + continue + + # Ignore comments + if line.startswith("#"): + continue + + # Handle includes (recursively) + m = re.match(r'^include\s+"?([^"]*)"?', line) + if m: + if parent: + self.include.append(m.group(1)) + if self.do_include: + include_fname = dirname(abspath(self.fname)) + "/" + m.group(1) + include_data = self._load(include_fname) + self._parse_body(include_data, parent=False) + continue + + # Handle policy and note lines + if re.match(r".* (policy|note)<", line): + try: + conf = line.split(" ")[0] + if conf in self.config: + entry = self.config[conf] + else: + entry = {"policy": {}} + + match = False + m = re.match(r".* policy<(.*?)>", line) + if m: + match = True + # Update the previous entry considering potential overrides: + # - if the new entry is adding a rule for a new + # arch/flavour, simply add that + # - if the new entry is overriding a previous + # arch-flavour item, then overwrite that item + # - if the new entry is overriding a whole arch, then + # remove all the previous flavour rules of that arch + new_entry = literal_eval(m.group(1)) + for key in new_entry: + if key in self.arch: + for flavour_key in list(entry["policy"].keys()): + if flavour_key.startswith(key): + del entry["policy"][flavour_key] + entry["policy"][key] = new_entry[key] + else: + entry["policy"][key] = new_entry[key] + + m = re.match(r".* note<(.*?)>", line) + if m: + entry["oneline"] = match + match = True + entry["note"] = "'" + m.group(1).replace("'", "") + "'" + + if not match: + raise SyntaxError("syntax error") + self.config[conf] = entry + except Exception as e: + raise SyntaxError(str(e) + f", line = {line}") from e + continue + + # Invalid line + raise SyntaxError(f"invalid line: {line}") + + def _legacy_parse(self, data: str): + """ + Parse main annotations file, individual config options can be accessed + via self.config[] + """ + self.config = {} + self.arch = [] + self.flavour = [] + self.flavour_dep = {} + self.include = [] + self.header = "" + self.include_flavour = [] + + # Parse header (only main header will considered, headers in includes + # will be treated as comments) + for line in data.splitlines(): + if re.match(r"^#.*", line): + m = re.match(r"^# ARCH: (.*)", line) + if m: + self.arch = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR: (.*)", line) + if m: + self.flavour = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR_DEP: (.*)", line) + if m: + self.flavour_dep = literal_eval(m.group(1)) + self.header += line + "\n" + else: + break + + # Return an error if architectures are not defined + if not self.arch: + raise SyntaxError("ARCH not defined in annotations") + # Return an error if flavours are not defined + if not self.flavour: + raise SyntaxError("FLAVOUR not defined in annotations") + + # Parse body + self._parse_body(data) + + # Sanity check: Verify that all FLAVOUR_DEP flavors are valid + if self.do_include: + for src, tgt in self.flavour_dep.items(): + if src not in self.flavour: + raise SyntaxError(f"Invalid source flavour in FLAVOUR_DEP: {src}") + if tgt not in self.include_flavour: + raise SyntaxError(f"Invalid target flavour in FLAVOUR_DEP: {tgt}") + + def _json_parse(self, data, is_included=False): + data = json.loads(data) + + # Check if version is supported + version = data["attributes"]["_version"] + if version > ANNOTATIONS_FORMAT_VERSION: + raise SyntaxError(f"annotations format version {version} not supported") + + # Check for top-level annotations vs imported annotations + if not is_included: + self.config = data["config"] + self.arch = data["attributes"]["arch"] + self.flavour = data["attributes"]["flavour"] + self.flavour_dep = data["attributes"]["flavour_dep"] + self.include = data["attributes"]["include"] + self.include_flavour = [] + else: + # We are procesing an imported annotations, so merge all the + # configs and attributes. + try: + self.config = data["config"] | self.config + except TypeError: + self.config = {**self.config, **data["config"]} + self.arch = list(set(self.arch) | set(data["attributes"]["arch"])) + self.flavour = list(set(self.flavour) | set(data["attributes"]["flavour"])) + self.include_flavour = list(set(self.include_flavour) | set(data["attributes"]["flavour"])) + self.flavour_dep = self.flavour_dep | data["attributes"]["flavour_dep"] + + # Handle recursive inclusions + if self.do_include: + for f in data["attributes"]["include"]: + include_fname = dirname(abspath(self.fname)) + "/" + f + data = self._load(include_fname) + self._json_parse(data, is_included=True) + + def _parse(self, data: str): + if self.do_json: + self._json_parse(data, is_included=False) + else: + self._legacy_parse(data) + + def _remove_entry(self, config: str): + if self.config[config]: + del self.config[config] + + def remove(self, config: str, arch: str = None, flavour: str = None): + if config not in self.config: + return + if arch is not None: + if flavour is not None: + flavour = f"{arch}-{flavour}" + else: + flavour = arch + del self.config[config]["policy"][flavour] + if not self.config[config]["policy"]: + self._remove_entry(config) + else: + self._remove_entry(config) + + def set( + self, + config: str, + arch: str = None, + flavour: str = None, + value: str = None, + note: str = None, + ): + if value is not None: + if config not in self.config: + self.config[config] = {"policy": {}} + if arch is not None: + if flavour is not None: + flavour = f"{arch}-{flavour}" + else: + flavour = arch + self.config[config]["policy"][flavour] = value + else: + for a in self.arch: + self.config[config]["policy"][a] = value + if note is not None: + self.config[config]["note"] = "'" + note.replace("'", "") + "'" + + def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = None): + """Merge configs from a Kconfig object into Annotation object""" + + # Determine if we need to import all configs or a single config + if not configs: + configs = c.config.keys() + try: + configs |= self.search_config(arch=arch, flavour=flavour).keys() + except TypeError: + configs = { + **configs, + **self.search_config(arch=arch, flavour=flavour).keys(), + } + + # Import configs from the Kconfig object into Annotations + flavour_arg = flavour + if flavour is not None: + flavour = arch + f"-{flavour}" + else: + flavour = arch + for conf in configs: + if conf in c.config: + val = c.config[conf] + else: + val = "-" + if conf in self.config: + if "policy" in self.config[conf]: + # Add a TODO if a config with a note is changing and print + # a warning + old_val = self.search_config(config=conf, arch=arch, flavour=flavour_arg) + if old_val: + old_val = old_val[conf] + if val != old_val and "note" in self.config[conf]: + self.config[conf]["note"] = "TODO: update note" + print(f"WARNING: {conf} changed from {old_val} to {val}, updating note") + self.config[conf]["policy"][flavour] = val + else: + self.config[conf]["policy"] = {flavour: val} + else: + self.config[conf] = {"policy": {flavour: val}} + + def _compact(self): + # Try to remove redundant settings: if the config value of a flavour is + # the same as the one of the main arch simply drop it. + for conf in self.config.copy(): + if "policy" not in self.config[conf]: + continue + for flavour in self.flavour: + if flavour not in self.config[conf]["policy"]: + continue + m = re.match(r"^(.*?)-(.*)$", flavour) + if not m: + continue + arch = m.group(1) + if arch in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][arch]: + del self.config[conf]["policy"][flavour] + continue + if flavour not in self.flavour_dep: + continue + generic = self.flavour_dep[flavour] + if generic in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][generic]: + del self.config[conf]["policy"][flavour] + continue + # Remove rules for flavours / arches that are not supported (not + # listed in the annotations header). + for flavour in self.config[conf]["policy"].copy(): + if flavour not in list(set(self.arch + self.flavour)): + del self.config[conf]["policy"][flavour] + # Remove configs that are all undefined across all arches/flavours + # (unless we have includes) + if not self.include: + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} + # Drop empty rules + if not self.config[conf]["policy"]: + del self.config[conf] + else: + # Compact same value across all flavour within the same arch + for arch in self.arch: + arch_flavours = [i for i in self.flavour if i.startswith(arch)] + value = None + for flavour in arch_flavours: + if flavour not in self.config[conf]["policy"]: + break + if value is None: + value = self.config[conf]["policy"][flavour] + elif value != self.config[conf]["policy"][flavour]: + break + else: + for flavour in arch_flavours: + del self.config[conf]["policy"][flavour] + self.config[conf]["policy"][arch] = value + # After the first round of compaction we may end up having configs that + # are undefined across all arches, so do another round of compaction to + # drop these settings that are not needed anymore + # (unless we have includes). + if not self.include: + for conf in self.config.copy(): + # Remove configs that are all undefined across all arches/flavours + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} + # Drop empty rules + if not self.config[conf]["policy"]: + del self.config[conf] + + @staticmethod + def _sorted(config): + """Sort configs alphabetically but return configs with a note first""" + w_note = [] + wo_note = [] + for c in sorted(config): + if "note" in config[c]: + w_note.append(c) + else: + wo_note.append(c) + return w_note + wo_note + + def save(self, fname: str): + """Save annotations data to the annotation file""" + # Compact annotations structure + self._compact() + + # Save annotations to disk + with tempfile.NamedTemporaryFile(mode="w+t", delete=False) as tmp: + # Write header + tmp.write(self.header + "\n") + + # Write includes + for i in self.include: + tmp.write(f'include "{i}"\n') + if self.include: + tmp.write("\n") + + # Write config annotations and notes + tmp.flush() + shutil.copy(tmp.name, fname) + tmp_a = Annotation(fname) + + # Only save local differences (preserve includes) + marker = False + for conf in self._sorted(self.config): + new_val = self.config[conf] + if "policy" not in new_val: + continue + + # If new_val is a subset of old_val, skip it unless there are + # new notes that are different than the old ones. + old_val = tmp_a.config.get(conf) + if old_val and "policy" in old_val: + try: + can_skip = old_val["policy"] == old_val["policy"] | new_val["policy"] + except TypeError: + can_skip = old_val["policy"] == { + **old_val["policy"], + **new_val["policy"], + } + if can_skip: + if "note" not in new_val: + continue + if "note" in old_val and "note" in new_val: + if old_val["note"] == new_val["note"]: + continue + + # Write out the policy (and note) line(s) + val = dict(sorted(new_val["policy"].items())) + line = f"{conf : <47} policy<{val}>" + if "note" in new_val: + val = new_val["note"] + if new_val.get("oneline", False): + # Single line + line += f" note<{val}>" + else: + # Separate policy and note lines, + # followed by an empty line + line += f"\n{conf : <47} note<{val}>\n" + elif not marker: + # Write out a marker indicating the start of annotations + # without notes + tmp.write("\n# ---- Annotations without notes ----\n\n") + marker = True + tmp.write(line + "\n") + + # Replace annotations with the updated version + tmp.flush() + shutil.move(tmp.name, fname) + + def search_config(self, config: str = None, arch: str = None, flavour: str = None) -> dict: + """Return config value of a specific config option or architecture""" + if flavour is None: + flavour = "generic" + flavour = f"{arch}-{flavour}" + if flavour in self.flavour_dep: + generic = self.flavour_dep[flavour] + else: + generic = flavour + if config is None and arch is None: + # Get all config options for all architectures + return self.config + if config is None and arch is not None: + # Get config options of a specific architecture + ret = {} + for c, val in self.config.items(): + if "policy" not in val: + continue + if flavour in val["policy"]: + ret[c] = val["policy"][flavour] + elif generic != flavour and generic in val["policy"]: + ret[c] = val["policy"][generic] + elif arch in val["policy"]: + ret[c] = val["policy"][arch] + return ret + if config is not None and arch is None: + # Get a specific config option for all architectures + return self.config[config] if config in self.config else None + if config is not None and arch is not None: + # Get a specific config option for a specific architecture + if config in self.config: + if "policy" in self.config[config]: + if flavour in self.config[config]["policy"]: + return {config: self.config[config]["policy"][flavour]} + if generic != flavour and generic in self.config[config]["policy"]: + return {config: self.config[config]["policy"][generic]} + if arch in self.config[config]["policy"]: + return {config: self.config[config]["policy"][arch]} + return None + + @staticmethod + def to_config(data: dict) -> str: + """Convert annotations data to .config format""" + s = "" + for c in data: + v = data[c] + if v == "n": + s += f"# {c} is not set\n" + elif v == "-": + pass + else: + s += f"{c}={v}\n" + return s.rstrip() --- linux-oracle-5.4.0.orig/debian/scripts/misc/kconfig/run.py +++ linux-oracle-5.4.0/debian/scripts/misc/kconfig/run.py @@ -0,0 +1,370 @@ +# -*- mode: python -*- +# Manage Ubuntu kernel .config and annotations +# Copyright © 2022 Canonical Ltd. + +import sys +import os +import argparse +import json +from signal import signal, SIGPIPE, SIG_DFL + +try: + from argcomplete import autocomplete +except ModuleNotFoundError: + # Allow to run this program also when argcomplete is not available + def autocomplete(_unused): + pass + + +from kconfig.annotations import Annotation, KConfig # noqa: E402 Import not at top of file +from kconfig.utils import autodetect_annotations, arg_fail # noqa: E402 Import not at top of file +from kconfig.version import VERSION, ANNOTATIONS_FORMAT_VERSION # noqa: E402 Import not at top of file + + +SKIP_CONFIGS = ( + # CONFIG_VERSION_SIGNATURE is dynamically set during the build + "CONFIG_VERSION_SIGNATURE", + # Allow to use a different versions of toolchain tools + "CONFIG_GCC_VERSION", + "CONFIG_CC_VERSION_TEXT", + "CONFIG_AS_VERSION", + "CONFIG_LD_VERSION", + "CONFIG_LLD_VERSION", + "CONFIG_CLANG_VERSION", + "CONFIG_PAHOLE_VERSION", + "CONFIG_RUSTC_VERSION_TEXT", + "CONFIG_BINDGEN_VERSION_TEXT", +) + + +def make_parser(): + parser = argparse.ArgumentParser( + description="Manage Ubuntu kernel .config and annotations", + ) + parser.add_argument("--version", "-v", action="version", version=f"%(prog)s {VERSION}") + + parser.add_argument( + "--file", + "-f", + action="store", + help="Pass annotations or .config file to be parsed", + ) + parser.add_argument("--arch", "-a", action="store", help="Select architecture") + parser.add_argument("--flavour", "-l", action="store", help='Select flavour (default is "generic")') + parser.add_argument("--config", "-c", action="store", help="Select a specific config option") + parser.add_argument("--query", "-q", action="store_true", help="Query annotations") + parser.add_argument( + "--note", + "-n", + action="store", + help="Write a specific note to a config option in annotations", + ) + parser.add_argument( + "--autocomplete", + action="store_true", + help="Enable config bash autocomplete: `source <(annotations --autocomplete)`", + ) + parser.add_argument( + "--source", + "-t", + action="store_true", + help="Jump to a config definition in the kernel source code", + ) + parser.add_argument( + "--no-include", + action="store_true", + help="Do not process included annotations (stop at the main file)", + ) + parser.add_argument( + "--json", + action="store_true", + help="Try to parse annotations file in pure JSON format", + ) + + ga = parser.add_argument_group(title="Action").add_mutually_exclusive_group(required=False) + ga.add_argument( + "--write", + "-w", + action="store", + metavar="VALUE", + dest="value", + help="Set a specific config value in annotations (use 'null' to remove)", + ) + ga.add_argument( + "--export", + "-e", + action="store_true", + help="Convert annotations to .config format", + ) + ga.add_argument( + "--import", + "-i", + action="store", + metavar="FILE", + dest="import_file", + help="Import a full .config for a specific arch and flavour into annotations", + ) + ga.add_argument( + "--update", + "-u", + action="store", + metavar="FILE", + dest="update_file", + help="Import a partial .config into annotations (only resync configs specified in FILE)", + ) + ga.add_argument( + "--check", + "-k", + action="store", + metavar="FILE", + dest="check_file", + help="Validate kernel .config with annotations", + ) + return parser + + +_ARGPARSER = make_parser() + + +def export_result(data): + # Dump metadata / attributes first + out = '{\n "attributes": {\n' + for key, value in sorted(data["attributes"].items()): + out += f' "{key}": {json.dumps(value)},\n' + out = out.rstrip(",\n") + out += "\n }," + print(out) + + configs_with_note = {key: value for key, value in data["config"].items() if "note" in value} + configs_without_note = {key: value for key, value in data["config"].items() if "note" not in value} + + # Dump configs, sorted alphabetically, showing items with a note first + out = ' "config": {\n' + for key in sorted(configs_with_note) + sorted(configs_without_note): + policy = data["config"][key]["policy"] + if "note" in data["config"][key]: + note = data["config"][key]["note"] + out += f' "{key}": {{"policy": {json.dumps(policy)}, "note": {json.dumps(note)}}},\n' + else: + out += f' "{key}": {{"policy": {json.dumps(policy)}}},\n' + out = out.rstrip(",\n") + out += "\n }\n}" + print(out) + + +def print_result(config, data): + if data is not None and config is not None and config not in data: + data = {config: data} + print(json.dumps(data, sort_keys=True, indent=2)) + + +def do_query(args): + if args.arch is None and args.flavour is not None: + arg_fail(_ARGPARSER, "error: --flavour requires --arch") + a = Annotation(args.file, do_include=(not args.no_include), do_json=args.json) + res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + # If no arguments are specified dump the whole annotations structure + if args.config is None and args.arch is None and args.flavour is None: + res = { + "attributes": { + "arch": a.arch, + "flavour": a.flavour, + "flavour_dep": a.flavour_dep, + "include": a.include, + "_version": ANNOTATIONS_FORMAT_VERSION, + }, + "config": res, + } + export_result(res) + else: + print_result(args.config, res) + + +def do_autocomplete(args): + a = Annotation(args.file) + res = (c.removeprefix("CONFIG_") for c in a.search_config()) + res_str = " ".join(res) + print(f'complete -W "{res_str}" annotations') + + +def do_source(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --source requires --config") + if not os.path.exists("tags"): + print("tags not found in the current directory, try: `make tags`") + sys.exit(1) + os.system(f"vim -t {args.config}") + + +def do_note(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --note requires --config") + + # Set the note in annotations + a = Annotation(args.file) + a.set(args.config, note=args.note) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_write(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --write requires --config") + + # Set the value in annotations ('null' means remove) + a = Annotation(args.file) + if args.value == "null": + a.remove(args.config, arch=args.arch, flavour=args.flavour) + else: + a.set( + args.config, + arch=args.arch, + flavour=args.flavour, + value=args.value, + note=args.note, + ) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_export(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --export requires --arch") + a = Annotation(args.file) + conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + if conf: + print(a.to_config(conf)) + + +def do_import(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --import") + if args.flavour is None: + arg_fail(_ARGPARSER, "error: --flavour is required with --import") + if args.config is not None: + arg_fail(_ARGPARSER, "error: --config cannot be used with --import (try --update)") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.import_file) + a.update(c, arch=args.arch, flavour=args.flavour) + + # Save back to annotations + a.save(args.file) + + +def do_update(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --update") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.update_file) + if args.config is None: + configs = list(set(c.config.keys()) - set(SKIP_CONFIGS)) + if configs: + a.update(c, arch=args.arch, flavour=args.flavour, configs=configs) + + # Save back to annotations + a.save(args.file) + + +def do_check(args): + # Determine arch and flavour + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --check") + + print(f"check-config: loading annotations from {args.file}") + total = good = ret = 0 + + # Load annotations settings + a = Annotation(args.file) + a_configs = a.search_config(arch=args.arch, flavour=args.flavour).keys() + + # Parse target .config + c = KConfig(args.check_file) + c_configs = c.config.keys() + + # Validate .config against annotations + for conf in sorted(a_configs | c_configs): + if conf in SKIP_CONFIGS: + continue + entry = a.search_config(config=conf, arch=args.arch, flavour=args.flavour) + expected = entry[conf] if entry else "-" + value = c.config[conf] if conf in c.config else "-" + if value != expected: + policy = a.config[conf] if conf in a.config else "undefined" + if "policy" in policy: + policy = f"policy<{policy['policy']}>" + print(f"check-config: {conf} changed from {expected} to {value}: {policy})") + ret = 1 + else: + good += 1 + total += 1 + + num = total - good + if ret: + if os.path.exists(".git"): + print(f"check-config: {num} config options have been changed, review them with `git diff`") + else: + print(f"check-config: {num} config options have changed") + else: + print("check-config: all good") + sys.exit(ret) + + +def main(): + # Prevent broken pipe errors when showing output in pipe to other tools + # (less for example) + signal(SIGPIPE, SIG_DFL) + + # Main annotations program + autocomplete(_ARGPARSER) + args = _ARGPARSER.parse_args() + + if args.file is None: + args.file = autodetect_annotations() + if args.file is None: + arg_fail( + _ARGPARSER, + "error: could not determine DEBDIR, try using: --file/-f", + show_usage=False, + ) + + if args.config and not args.config.startswith("CONFIG_"): + args.config = "CONFIG_" + args.config + + if args.value: + do_write(args) + elif args.note: + do_note(args) + elif args.export: + do_export(args) + elif args.import_file: + do_import(args) + elif args.update_file: + do_update(args) + elif args.check_file: + do_check(args) + elif args.autocomplete: + do_autocomplete(args) + elif args.source: + do_source(args) + else: + do_query(args) + + +if __name__ == "__main__": + main() --- linux-oracle-5.4.0.orig/debian/scripts/misc/kconfig/utils.py +++ linux-oracle-5.4.0/debian/scripts/misc/kconfig/utils.py @@ -0,0 +1,20 @@ +# -*- mode: python -*- +# Misc helpers for Kconfig and annotations +# Copyright © 2023 Canonical Ltd. + +import sys + + +def autodetect_annotations(): + try: + with open("debian/debian.env", "rt", encoding="utf-8") as fd: + return fd.read().rstrip().split("=")[1] + "/config/annotations" + except (FileNotFoundError, IndexError): + return None + + +def arg_fail(parser, message, show_usage=True): + print(message) + if show_usage: + parser.print_usage() + sys.exit(1) --- linux-oracle-5.4.0.orig/debian/scripts/misc/kconfig/version.py +++ linux-oracle-5.4.0/debian/scripts/misc/kconfig/version.py @@ -0,0 +1,10 @@ +# -*- mode: python -*- +# version of annotations module +# Copyright © 2022 Canonical Ltd. + +VERSION = "0.1" + +ANNOTATIONS_FORMAT_VERSION = 5 + +if __name__ == "__main__": + print(VERSION) --- linux-oracle-5.4.0.orig/debian/scripts/misc/kernel-wedge-arch.pl +++ linux-oracle-5.4.0/debian/scripts/misc/kernel-wedge-arch.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl +# +# kernel-wedge-arch.pl -- select only specifiers for the supplied arch. +# +use strict; + +require Dpkg::Control; +require Dpkg::Deps; + +my $fh = \*STDIN; + +my @entries; + +my $wanted = $ARGV[0]; + +my $entry; +while (!eof($fh)) { + $entry = Dpkg::Control->new(); + $entry->parse($fh, '???'); + + if ($entry->{'Architecture'} eq $wanted) { + print("\n" . $entry); + } +} + +close($fh); --- linux-oracle-5.4.0.orig/debian/scripts/misc/kernelconfig +++ linux-oracle-5.4.0/debian/scripts/misc/kernelconfig @@ -0,0 +1,178 @@ +#!/bin/bash -u +# +# Manage kernel config annotations +# +# Supported environment variales: +# conc_level : Concurrency level for upstream make (-jX) +# skip_checks : Skip config checks if set to 'true' +# gcc : Default gcc to use (mandatory) +# + +function cleanup() +{ + rm -rf build "${TMP_DIR}" +} + +# We have to be in the top level Ubuntu kernel source directory +if ! [ -e debian/debian.env ] ; then + echo "ERROR: This is not an Ubuntu kernel source directory" >&2 + exit 1 +fi + +if [ -z "${gcc:-}" ] ; then + gcc=gcc +fi + +if [ ${#} -ne 1 ] ; then + echo "Usage: $0 updateconfigs|defaultconfigs|genconfigs|editconfigs" + exit 2 +fi + +mode=${1} + +case "${mode}" in + updateconfigs) target="syncconfig" ;; + defaultconfigs) target="olddefconfig" ;; + genconfigs) target="oldconfig" ;; + editconfigs) ;; # Target is set later based on user input + *) echo "ERROR: Invalid mode: ${1}" >&2 + exit 1 ;; +esac + +. debian/debian.env + +annotations_file=${DEBIAN}/config/annotations +warning_partial=() + +TMP_DIR=$(mktemp -d) +trap cleanup EXIT + +# Use annotations to generate configs +FLAVOURS=$(sed -ne 's/^# FLAVOUR: //p' "${annotations_file}") + +for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + # Map debian archs to kernel archs + case "${arch}" in + amd64) kern_arch="x86_64" ;; + arm64) kern_arch="arm64" ;; + armhf) kern_arch="arm" ;; + i386) kern_arch="i386" ;; + ppc64el) kern_arch="powerpc" ;; + riscv64) kern_arch="riscv" ;; + s390x) kern_arch="s390" ;; + *) echo "WARNING: Unsupported architecture: ${arch}" + warning_partial+=("${arch}") + continue ;; + esac + + # Determine cross toolchain to use for Kconfig compiler tests + cross_compile="$(dpkg-architecture -qDEB_HOST_GNU_TYPE -a"${arch}" 2>/dev/null)-" + + # Arch-specific compiler, if any + arch_gcc=$(cat < build/.config + + # Environment variables for 'make *config' + env=(ARCH="${kern_arch}" + DEB_ARCH="${arch}" + CROSS_COMPILE="${cross_compile}" + CC="${gcc_path}") + + # Concurrency level + if [ -n "${conc_level:-}" ] ; then + env+=("${conc_level}") + fi + + # Call config target + echo + echo "* Run ${target} on ${arch}/${flavour} ..." + ${kmake} O=build "${env[@]}" "${target}" + + # Move config for further processing + mv build/.config "${tmp_conf_file}" +done + +rc=0 + +if [ "${skip_checks:-}" = "true" ] ; then + echo + echo "Skipping config-check (skip_checks=${skip_checks}) ..." +else + echo + echo "Running config-check for all configurations ..." + fail=0 + for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + echo + echo "* Run config-check for ${arch}-${flavour} ..." + python3 debian/scripts/misc/annotations -f "${annotations_file}" \ + --arch "${arch}" --flavour "${flavour}" --check "${tmp_conf_file}" || \ + fail=$((fail + 1)) + done + + if [ ${fail} -gt 0 ] ; then + rc=1 + echo "ERROR: ${fail} config-check failures detected" >&2 + fi +fi + +if [ ${#warning_partial[@]} -gt 0 ] ; then + rc=1 + echo "ERROR: Config operation not applied to all architectures (skipped ${warning_partial[*]})" >&2 +fi + +# Recreate the annotations file +if [ "${mode}" = "genconfigs" ] ; then + rm -rf CONFIGS + mv "${TMP_DIR}" CONFIGS +else + echo + echo "Importing all configurations ..." + echo + for arch_flavour in ${FLAVOURS} ; do + arch=${arch_flavour%%-*} + flavour=${arch_flavour#*-} + tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour} + + echo "* Import configs for ${arch}-${flavour} ..." + python3 debian/scripts/misc/annotations -f "${annotations_file}" \ + --arch "${arch}" --flavour "${flavour}" --import "${tmp_conf_file}" + done +fi + +exit "${rc}" --- linux-oracle-5.4.0.orig/debian/scripts/misc/migrate-annotations +++ linux-oracle-5.4.0/debian/scripts/misc/migrate-annotations @@ -0,0 +1,35 @@ +#!/bin/bash + +. debian/debian.env + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + +. ${DEBIAN}/etc/kernelconfig + +ARCH=$(echo $archs | tr " " "\n" | sort -u) +FLAVOUR=$(for arch in ${ARCH}; do + flavours=$(sed -ne 's/^flavours\s*=\s*\(.*\)$/\1/p' ${DEBIAN}/rules.d/${arch}.mk) + for flavour in ${flavours}; do + echo ${arch}-${flavour} + done +done | tr " " "\n" | sort -u) + +while read line; do + (echo $line | grep -q '^#') || break +done + +cat << EOF +# Menu: HEADER +# FORMAT: 4 +# ARCH: $(echo ${ARCH}) +# FLAVOUR: $(echo ${FLAVOUR}) + +EOF + +while read line; do + echo ${line} +done --- linux-oracle-5.4.0.orig/debian/scripts/misc/old-kernelconfig +++ linux-oracle-5.4.0/debian/scripts/misc/old-kernelconfig @@ -0,0 +1,207 @@ +#!/bin/bash + +. debian/debian.env + +# Script to merge all configs and run 'make syncconfig' on it to wade out bad juju. +# Then split the configs into distro-commmon and flavour-specific parts + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + +mode=${1:?"Usage: $0 (oldconfig|editconfig) [do_enforce_all]"} +do_enforce_all=${2:-0} +yes=0 +case "$mode" in + update*configs) mode='syncconfig' ;; + default*configs) mode='oldconfig'; yes=1 ;; + edit*configs) ;; # All is good + gen*configs) mode='genconfigs' ;; # All is good + dump*configs) mode='config'; yes=1 ;; + *) echo "$0 called with invalid mode" 1>&2 + exit 1 ;; +esac +kerneldir="`pwd`" +confdir="$kerneldir/${DEBIAN}/config" +variant="$2" + +. $DEBIAN/etc/kernelconfig + +bindir="`pwd`/${DROOT}/scripts/misc" +common_conf="$confdir/config.common.$family" +tmpdir=`mktemp -d` +mkdir "$tmpdir/CONFIGS" + +if [ "$mode" = "genconfigs" ]; then + keep=1 + mode="oldconfig" + test -d CONFIGS || mkdir CONFIGS +fi + +warning_partial= + +for arch in $archs; do + rm -rf build + mkdir build + + # Map debian archs to kernel archs + case "$arch" in + ppc64|ppc64el) kernarch="powerpc" ;; + amd64) kernarch="x86_64" ;; + lpia) kernarch="x86" ;; + sparc) kernarch="sparc64" ;; + armel|armhf) kernarch="arm" ;; + s390x) kernarch="s390" ;; + riscv64) kernarch="riscv" ;; + *) kernarch="$arch" ;; + esac + + # Determine cross toolchain to use for Kconfig compiler tests + cross_compile="" + deb_build_arch=$(dpkg-architecture -qDEB_BUILD_ARCH -a$arch 2>/dev/null) + deb_host_arch=$(dpkg-architecture -qDEB_HOST_ARCH -a$arch 2>/dev/null) + [ $deb_build_arch != $deb_host_arch ] && cross_compile="$(dpkg-architecture -qDEB_HOST_GNU_TYPE -a$arch 2>/dev/null)-" + + # Environment variables for 'make *config'. We omit CROSS_COMPILE + # for i386 since it is no longer supported after 19.04, however + # we maintain the configs for hwe. + modify_config=true + env="ARCH=$kernarch DEB_ARCH=$arch" + compiler_path=$(which "${cross_compile}gcc" || true) + if [ "$compiler_path" != '' ]; then + env="$env CROSS_COMPILE=$cross_compile" + else + echo "WARNING: ${cross_compile}gcc not installed" + modify_config= + warning_partial="$warning_partial $arch" + fi + + archconfdir=$confdir/$arch + flavourconfigs=$(cd $archconfdir && ls config.flavour.*) + + # Merge configs + # We merge config.common.ubuntu + config.common. + + # config.flavour. + + for config in $flavourconfigs; do + fullconf="$tmpdir/$arch-$config-full" + case $config in + *) + : >"$fullconf" + if [ -f $common_conf ]; then + cat $common_conf >> "$fullconf" + fi + if [ -f $archconfdir/config.common.$arch ]; then + cat $archconfdir/config.common.$arch >> "$fullconf" + fi + cat "$archconfdir/$config" >>"$fullconf" + if [ -f $confdir/OVERRIDES ]; then + cat $confdir/OVERRIDES >> "$fullconf" + fi + ;; + esac + done + + for config in $flavourconfigs; do + if [ -f $archconfdir/$config ]; then + fullconf="$tmpdir/$arch-$config-full" + cat "$fullconf" > build/.config + # Call oldconfig or menuconfig + if [ "$modify_config" ]; then + case "$mode" in + editconfigs) + # Interactively edit config parameters + while : ; do + echo -n "Do you want to edit config: $arch/$config? [Y/n] " + read choice + case "$choice" in + y* | Y* | "" ) + make O=`pwd`/build $env menuconfig + break ;; + n* | N* ) + # 'syncconfig' prevents + # errors for '-' options set + # in common config fragments + make O=`pwd`/build $env syncconfig + break ;; + *) + echo "Entry not valid" + esac + done + ;; + *) + echo "* Run $mode (yes=$yes) on $arch/$config ..." + if [ "$yes" -eq 1 ]; then + yes "" | make O=`pwd`/build $env "$mode" + else + make O=`pwd`/build $env "$mode" + fi ;; + esac + fi + cat build/.config > $archconfdir/$config + [ "$modify_config" ] && cat build/.config >"$tmpdir/CONFIGS/$arch-$config" + if [ "$keep" = "1" ]; then + cat build/.config > CONFIGS/$arch-$config + fi + else + echo "!! Config not found $archconfdir/$config..." + fi + done + + echo "Running splitconfig.pl for $arch" + echo + + # Can we make this more robust by avoiding $tmpdir completely? + # This approach was used for now because I didn't want to change + # splitconfig.pl + (cd $archconfdir; $bindir/splitconfig.pl config.flavour.*; mv config.common \ + config.common.$arch; cp config.common.$arch $tmpdir) +done + +rm -f $common_conf + +# Now run splitconfig.pl on all the config.common. copied to +# $tmpdir +(cd $tmpdir; $bindir/splitconfig.pl *) +( + cd $confdir; + rm -f *-full + grep -v 'is UNMERGABLE' <$tmpdir/config.common >$common_conf + for arch in $archs; do + grep -v 'is UNMERGABLE' <$tmpdir/config.common.$arch \ + >$arch/config.common.$arch + done +) + +echo "" +echo "Running config-check for all configurations ..." +echo "" +fail=0 +for arch in $archs; do + archconfdir=$confdir/$arch + flavourconfigs=$(cd $archconfdir && ls config.flavour.*) + for config in $flavourconfigs; do + flavour="${config##*.}" + if [ -f $archconfdir/$config ]; then + fullconf="$tmpdir/CONFIGS/$arch-$config" + [ ! -f "$fullconf" ] && continue + "$bindir/../config-check" "$fullconf" "$arch" "$flavour" "$confdir" "0" "$do_enforce_all" || let "fail=$fail+1" + fi + done +done + +if [ "$fail" != 0 ]; then + echo "" + echo "*** ERROR: $fail config-check failures detected" + echo "" +fi + +rm -rf build + +if [ "$warning_partial" ]; then + echo "" + echo "WARNING: configuration operation applied only to a subset of architectures (skipped$warning_partial)" 1>&2 + echo "" +fi --- linux-oracle-5.4.0.orig/debian/scripts/misc/retag +++ linux-oracle-5.4.0/debian/scripts/misc/retag @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w + +open(TAGS, "git tag -l |") or die "Could not get list of tags"; +@tags = ; +close(TAGS); + +open(LOGS, "git log --pretty=short |") or die "ERROR: Calling git log"; +my $commit = ""; + +while () { + my $origtag; + + if (m|^commit (.*)$|) { + $commit = $1; + next; + } + + m|\s*UBUNTU: (Ubuntu-2\.6\..*)| or next; + + $tag = $1; + + ($origtag) = grep(/^$tag.orig$/, @tags); + + if (!defined($origtag)) { + print "I: Adding original tag for $tag\n"; + system("git tag -m $tag $tag.orig $tag"); + } + + print "I: Tagging $tag => $commit\n"; + + system("git tag -f -m $tag $tag $commit"); +} + +close(LOGS); --- linux-oracle-5.4.0.orig/debian/scripts/misc/splitconfig.pl +++ linux-oracle-5.4.0/debian/scripts/misc/splitconfig.pl @@ -0,0 +1,107 @@ +#!/usr/bin/perl -w + +%allconfigs = (); +%common = (); + +print "Reading config's ...\n"; + +for $config (@ARGV) { + # Only config.* + next if $config !~ /^config\..*/; + # Nothing that is disabled, or remnant + next if $config =~ /.*\.(default|disabled|stub)$/; + + %{$allconfigs{$config}} = (); + + print " processing $config ... "; + + open(CONFIG, "< $config"); + + while () { + # Skip comments + /^#*\s*CONFIG_(\w+)[\s=](.*)$/ or next; + + ${$allconfigs{$config}}{$1} = $2; + + $common{$1} = $2; + } + + close(CONFIG); + + print "done.\n"; +} + +print "\n"; + +print "Merging lists ... \n"; + +# %options - pointer to flavour config inside the allconfigs array +for $config (keys(%allconfigs)) { + my %options = %{$allconfigs{$config}}; + + print " processing $config ... "; + + for $key (keys(%common)) { + next if not defined $common{$key}; + + # If we don't have the common option, then it isn't + # common. If we do have that option, it must have the same + # value. EXCEPT where this file does not have a value at all + # which may safely be merged with any other value; the value + # will be elided during recombination of the parts. + if (!defined($options{$key})) { + # Its ok really ... let it merge + } elsif (not defined($options{$key})) { + undef $common{$key}; + } elsif ($common{$key} ne $options{$key}) { + undef $common{$key}; + } + } + + print "done.\n"; +} + +print "\n"; + +print "Creating common config ... "; + +open(COMMON, "> config.common"); +print COMMON "#\n# Common config options automatically generated by splitconfig.pl\n#\n"; + +for $key (sort(keys(%common))) { + if (not defined $common{$key}) { + print COMMON "# CONFIG_$key is UNMERGABLE\n"; + } elsif ($common{$key} eq "is not set") { + print COMMON "# CONFIG_$key is not set\n"; + } else { + print COMMON "CONFIG_$key=$common{$key}\n"; + } +} +close(COMMON); + +print "done.\n\n"; + +print "Creating stub configs ...\n"; + +for $config (keys(%allconfigs)) { + my %options = %{$allconfigs{$config}}; + + print " processing $config ... "; + + open(STUB, "> $config"); + print STUB "#\n# Config options for $config automatically generated by splitconfig.pl\n#\n"; + + for $key (sort(keys(%options))) { + next if defined $common{$key}; + + if ($options{$key} =~ /^is /) { + print STUB "# CONFIG_$key $options{$key}\n"; + } else { + print STUB "CONFIG_$key=$options{$key}\n"; + } + } + + close(STUB); + + print "done.\n"; +} --- linux-oracle-5.4.0.orig/debian/scripts/misc/tristate.sh +++ linux-oracle-5.4.0/debian/scripts/misc/tristate.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# +# Find config variables that might be able to transition from =y to =m +# +# Example: debian/scripts/misc/tristate.sh debian.master/config/config.common.ubuntu +# + +KC=Kconfig.tmp +rm -f ${KC} +find .|grep Kconfig | while read f +do + cat $f >> ${KC} +done + +grep =y $1 | sed -e 's/CONFIG_//' -e 's/=y//' | while read c +do + cat < tristate.awk +BEGIN { tristate=0; } +/^config ${c}\$/ { tristate=1; next; } +/tristate/ { if (tristate == 1) printf("CONFIG_%s=m\n","${c}"); next; } +{ if (tristate == 1) exit; } +EOF + + gawk -f tristate.awk ${KC} +done --- linux-oracle-5.4.0.orig/debian/scripts/misc/update-aufs.sh +++ linux-oracle-5.4.0/debian/scripts/misc/update-aufs.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +AUFS=aufs4-standalone + +# +# Before you run this be sure you've removed or reverted the 'UBUNTU: SAUCE: AUFS" patch. +# +# +# Make sure the current working directory is at the top of the +# linux tree. +# +if ! grep PATCHLEVEL Makefile +then + echo "You must run this script from the top of the linux tree" + exit 1 +fi + +clean=0 +if [ "$#" = 1 ]; then + AUFS="$1" +else + clean=1 + rm -rf ${AUFS} + git clone https://github.com/sfjro/aufs5-standalone.git ${AUFS} + (cd ${AUFS}; git checkout -b aufs5.x-rcN remotes/origin/aufs5.x-rcN) +fi + +cp ${AUFS}/include/uapi/linux/aufs_type.h include/uapi/linux +rsync -av ${AUFS}/fs/ fs/ +rsync -av ${AUFS}/Documentation/ Documentation/ + +PATCHES="${PATCHES} aufs5-kbuild.patch" +PATCHES="${PATCHES} aufs5-base.patch" +PATCHES="${PATCHES} aufs5-mmap.patch" +PATCHES="${PATCHES} aufs5-standalone.patch" +PATCHES="${PATCHES} aufs5-loopback.patch" +#PATCHES="${PATCHES} vfs-ino.patch" +PATCHES="${PATCHES} tmpfs-idr.patch" + +for i in ${PATCHES} +do + patch -p1 < ${AUFS}/$i +done + +[ "$clean" = 1 ] && rm -rf ${AUFS} +git add mm/prfile.c +git add -u +find . -name "*.orig" | xargs rm +find . |grep aufs | xargs git add +git commit -s -m"UBUNTU: SAUCE: AUFS" --- linux-oracle-5.4.0.orig/debian/scripts/module-inclusion +++ linux-oracle-5.4.0/debian/scripts/module-inclusion @@ -0,0 +1,104 @@ +#!/bin/bash + +# +# Build a new directory of modules based on an inclusion list. +# The includsion list format must be a bash regular expression. +# +# usage: $0 ROOT INCLUSION_LIST +# example: $0 \ +# debian/build/build-virtual-ALL debian/build/build-virtual \ +# debian.master/control.d/virtual.inclusion-list \ +# virtual.depmap +master=0 +if [ "$1" = "--master" ]; then + master=1 + shift +fi + +ROOT=$1 +NROOT=$2 +ILIST=$3 +DEPMAP=$4 + +tmp="/tmp/module-inclusion.$$" + +# +# Prep a destination directory. +# +mkdir -p ${NROOT} + +{ + # Copy over the framework into the master package. + if [ "$master" -eq 1 ]; then + (cd ${ROOT}; find . ! -name "*.ko" -type f) + fi + + # Copy over modules by name or pattern. + while read -r i + do + # + # 'find' blurts a warning if it cannot find any ko files. + # + case "$i" in + \!*) + (cd ${ROOT}; ${i#!} || true) + ;; + *\**) + (cd ${ROOT}; eval find "${i}" -name "*.ko" || true) + ;; + *) + echo "$i" + ;; + esac + done <"${ILIST}" +} >"$tmp" + +# Copy over the listed modules. +while read i +do + # If this is already moved over, all is good. + if [ -f "${NROOT}/$i" ]; then + : + + # If present in the source, moved it over. + elif [ -f "${ROOT}/$i" ]; then + mkdir -p "${NROOT}/`dirname $i`" + mv "${ROOT}/$i" "${NROOT}/$i" + + # Otherwise, it is missing. + else + echo "Warning: Could not find ${ROOT}/$i" 1>&2 + fi +done <"$tmp" + +# Copy over any dependancies, note if those are missing +# we know they are in a pre-requisite package as they must +# have existed at depmap generation time, and can only have +# moved into a package. +let n=0 || true +while [ -s "$tmp" ] +do + let n="$n+1" || true + [ "$n" = "20" ] && break || true + + echo "NOTE: pass $n: dependency scan" 1>&2 + + while read i + do + grep "^$i " "$DEPMAP" | \ + while read m d + do + if [ -f "${ROOT}/$d" ]; then + echo "NOTE: pass $n: ${i} pulls in ${d}" 1>&2 + echo "$d" + mkdir -p "${NROOT}/`dirname $d`" + mv "${ROOT}/$d" "${NROOT}/$d" + fi + done + done <"$tmp" >"$tmp.new" + mv -f "$tmp.new" "$tmp" +done + +rm -f "$tmp" + +exit 0 --- linux-oracle-5.4.0.orig/debian/scripts/retpoline-extract +++ linux-oracle-5.4.0/debian/scripts/retpoline-extract @@ -0,0 +1,23 @@ +#!/bin/bash + +cd "$1" || exit 1 + +# Find all valid retpoline information, collate the detected and +# safe information together. Join the result to find the detected +# but non-safe elements. These are our concern. +ur_detected=$(mktemp --tmpdir "retpoline-check-XXXXXX.ur-detected") +ur_safe=$(mktemp --tmpdir "retpoline-check-XXXXXX.ur-safe") + +find "." -path './drivers/firmware/efi/libstub' -prune -o \ + -path './arch/x86/boot' -prune -o \ + -path './arch/x86/purgatory' -prune -o \ + -name \*.ur-detected -print0 | xargs -0 cat | \ + sed -e "s@^$1@@" -e "s@ $2/@ @" -e "s@^/@@" | \ + sort -k 1b,1 >"$ur_detected" +find "." -name \*.ur-safe -print0 | xargs -0 cat | \ + sed -e "s@^$1@@" -e "s@^/@@" | \ + sort -k 1b,1 >"$ur_safe" + +join -v 1 -j 1 "$ur_detected" "$ur_safe" | sed -s 's/[^ ]* *//' + +rm -f "$ur_detected" "$ur_safe" --- linux-oracle-5.4.0.orig/debian/scripts/retpoline-extract-one +++ linux-oracle-5.4.0/debian/scripts/retpoline-extract-one @@ -0,0 +1,270 @@ +#!/bin/bash + +exec &2 + exit 1 + fi +} + +# Form an associative lookup for the section numbers in the ELF symbol table. +# Uses 8 character 0 expanded hexadecimal key for ease of consumption. +__sectionmap_init() +{ + readelf -W --headers "$1" | \ + awk ' + { sub("\\[", ""); sub("\\]", ""); } + ($1 ~ /^[0-9][0-9]*/) { printf("%08x %s %s %s\n", int($1), $2, $3, $4); } + ' | \ + { + while read section_num section_name section_type section_vma + do + echo "sectionmap_$section_num='$section_name'" + echo "sectionvma_$section_num='$section_vma'" + case "$section_type" in + REL|RELA) section_relocation="$section_type" ;; + esac + done + echo "section_relocation='$section_relocation'" + } +} +sectionmap_init() +{ + eval $(__sectionmap_init "$1") +} +sectionmap() +{ + eval RET="\$sectionmap_$1" + if [ "$RET" = '' ]; then + echo "sectionmap: $1: invalid section" 1>&2 + exit 1 + fi +} +sectionvma() +{ + eval RET="\$sectionvma_$1" + if [ "$RET" = '' ]; then + echo "sectionvma: $1: invalid section" 1>&2 + exit 1 + fi +} + +# Read and parse the hex-dump output. +hex="[0-9a-f]" +hex_8="$hex$hex$hex$hex$hex$hex$hex$hex" +hexspc="[0-9a-f ]" +hexspc_8="$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc$hexspc" + +raw32() +{ + readelf --hex-dump "$2" "$1" 2>/dev/null | + sed \ + -e '/^Hex/d' -e '/^$/d' -e '/^ *NOTE/d' \ + -e 's/ *[^ ][^ ]* *\('"$hex_8"'\) \('"$hexspc_8"'\) \('"$hexspc_8"'\) \('"$hexspc_8"'\) .*/\1 \2 \3 \4 /' \ + -e 's/\('"$hex$hex"'\)\('"$hex$hex"'\)\('"$hex$hex"'\)\('"$hex$hex"'\) /\4\3\2\1 /g' \ + -e 's/ $//g' -e 's/ /\n/g' +} +#-e 's/\([^ ][^ ][^ ][^ ][^ ][^ ][^ ][^ ]\) \([^ ][^ ][^ ][^ ][^ ][^ ][^ ][^ ]\) /\2\1 /g' \ + +rela() +{ + #file="$(basename "$1")" + file="$1" + + # Read relocation information for a 64bit binary. Each relocation entry + # is 3 long longs so we collect 6 quads here. Note that the dump is in + # listed in increasing byte order not withstanding the quad split. + # + # The record says to take the value of add and + # shove that into in the segment of the . + # + # Format: + # 64 bits + # 32 bits + # 32 bits + # 64 bits + raw32 "$1" ".rela$SECTION" | \ + { + a1=''; a2=''; a3=''; a4=''; a5='' + while read a6 + do + [ "$a1" = '' ] && { a1="$a6"; continue; } + [ "$a2" = '' ] && { a2="$a6"; continue; } + [ "$a3" = '' ] && { a3="$a6"; continue; } + [ "$a4" = '' ] && { a4="$a6"; continue; } + [ "$a5" = '' ] && { a5="$a6"; continue; } + + #echo ">$a1< >$a2< >$a3< >$a4< >$a5< >$a6<" 1>&2 + #echo "type<$a3> symbol<$a4> offset<$a2$a1> addr<$a6a5>" 1>&2 + + symbolmap "$a4"; section_num="$RET" + #echo "section_num<$section_num>" 1>&2 + + sectionmap "$section_num"; section="$RET" + sectionvma "$section_num"; vma="$RET" + #echo "section<$section> vma<$vma>" 1>&2 + + # Adjust the segment addressing by the segment offset. + printf -v addr "%u" "0x$a6$a5" + printf -v vma "%u" "0x$vma" + let offset="$addr + $vma" + printf -v offset "%x" "$offset" + + echo "$file-$section-$offset" + + a1=''; a2=''; a3=''; a4=''; a5='' + done + } | sed -e 's/-00*\([0-9a-f]\)/-\1/' +} + +# Form an associative lookup for the raw contents for an ELF section. +# Uses 8 character 0 expanded hexadecimal key for ease of consumption. +contentmap_init() +{ + raw32 "$1" "$2" >"$tmp" + let offset=0 + while read value + do + printf -v offset_hex "%08x" $offset + eval contentmap_$offset_hex=\'$value\' + + let offset="$offset + 4" + done <"$tmp" + rm -f "$tmp" +} +contentmap() +{ + eval RET="\$contentmap_$1" + if [ "$RET" = '' ]; then + echo "contentmap: $1: invalid offset" 1>&2 + exit 1 + fi +} + +rel() +{ + # Load up the current contents of the $SECTION segment + # as the offsets (see below) are recorded there and we will need + # those to calculate the actuall address. + contentmap_init "$1" "$SECTION" + + #file="$(basename "$1")" + file="$1" + + # Read relocation information for a 32bit binary. Each relocation entry + # is 3 longs so we collect 3 quads here. Note that the dump is in + # listed in increasing byte order not withstanding the quad split. + # + # The record says to take the value of and add that to the + # existing contents of in the segment of the . + # + # Format: + # 32 bits + # 24 bits + # 8 bits + raw32 "$1" ".rel$SECTION" | \ + { + a1='' + while read a2 + do + [ "$a1" = '' ] && { a1="$a2"; continue; } + + #echo ">$a1< >$a2<" + contentmap "$a1"; offset="$RET" + symbolmap "00${a2%??}"; section_num="$RET" + + sectionmap "$section_num"; section="$RET" + sectionvma "$section_num"; vma="$RET" + #echo ">$a1< >$a2< >$offset< >$section<" + + echo "$file-$section-$offset" + + a1='' + done + } | sed -e 's/-00*\([0-9a-f]\)/-\1/' +} + +tmp=$(mktemp --tmpdir "retpoline-extract-XXXXXX") + +disassemble() +{ + local object="$1" + local src="$2" + local options="$3" + local selector="$4" + + objdump $options --disassemble --no-show-raw-insn "$object" | \ + awk -F' ' ' + BEGIN { file="'"$object"'"; src="'"$src"'"; } + /Disassembly of section/ { segment=$4; sub(":", "", segment); } + /^[0-9a-f][0-9a-f]* <.*>:/ { tag=$0; sub(".*<", "", tag); sub(">.*", "", tag); } + $0 ~ /(call|jmp)q? *\*0x[0-9a-f]*\(%rip\)/ { + next + } + $0 ~ /(call|jmp)q? *\*.*%/ { + sub(":", "", $1); + if ('"$selector"') { + offset=$1 + $1=tag + print(file "-" segment "-" offset " " src " " segment " " $0); + } + } + ' +} + +# Accumulate potentially vunerable indirect call/jmp sequences. We do this +# by examining the raw disassembly for affected forms, recording the location +# of each. +case "$bit16" in +'') disassemble "$object" "$src" '' 'segment != ".init.text"' ;; +*) disassemble "$object" "$src" '--disassembler-options=i8086' 'segment != ".init.text" && segment != ".text32" && segment != ".text64"' + disassemble "$object" "$src" '--disassembler-options=i386' 'segment == ".text32"' + disassemble "$object" "$src" '--disassembler-options=x86-64' 'segment == ".text64"' + ;; +esac | sort -k 1b,1 >"$object.ur-detected" +[ ! -s "$object.ur-detected" ] && rm -f "$object.ur-detected" + +# Load up the symbol table and section mappings. +symbolmap_init "$object" +sectionmap_init "$object" + +# Accumulate annotated safe indirect call/jmp sequences. We do this by examining +# the $SECTION sections (and their associated relocation information), +# each entry represents the address of an instruction which has been marked +# as ok. +case "$section_relocation" in +REL) rel "$object" ;; +RELA) rela "$object" ;; +esac | sort -k 1b,1 >"$object.ur-safe" +[ ! -s "$object.ur-safe" ] && rm -f "$object.ur-safe" + +# We will perform the below join on the summarised and sorted fragments +# formed above. This is performed in retpoline-check. +#join -v 1 -j 1 "$tmp.extracted" "$tmp.safe" | sed -s 's/[^ ]* *//' + +rm -f "$tmp" --- linux-oracle-5.4.0.orig/debian/scripts/sub-flavour +++ linux-oracle-5.4.0/debian/scripts/sub-flavour @@ -0,0 +1,69 @@ +#!/bin/bash + +. debian/debian.env + +echo "SUB_PROCESS $FROM => $TO" + +export from_pkg="linux-image-$ABI_RELEASE-$FROM" +export to_pkg="linux-image-$ABI_RELEASE-$TO" + +from_moddir="debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM" +to_moddir="debian/$to_pkg/lib/modules/$ABI_RELEASE-$FROM" + +install -d "debian/$to_pkg/boot" +install -m644 debian/$from_pkg/boot/config-$ABI_RELEASE-$FROM \ + debian/$to_pkg/boot/ +install -m600 debian/$from_pkg/boot/{vmlinuz,System.map}-$ABI_RELEASE-$FROM \ + debian/$to_pkg/boot/ + +# +# Print some warnings if there are files in the sub-flavours list +# that do not actually exist. +# +cat ${DEBIAN}/sub-flavours/$TO.list | while read line +do +( + cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel; + # + # If its a wildcard, then check that there are files that match. + # + if echo "$line" | grep '\*' > /dev/null + then + if [ `eval find "$line" -name '*.ko' 2>/dev/null|wc -l` -lt 1 ] + then + echo SUB_INST Warning - No files in $line + fi + # + # Else it should be a single file reference. + # + elif [ ! -f "$line" ] + then + echo SUB_INST Warning - could not find "$line" + fi +) +done + +cat ${DEBIAN}/sub-flavours/$TO.list | while read line; do + ( + cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel; + if echo "$line" | grep '\*' > /dev/null + then + eval find "$line" -name '*.ko' 2>/dev/null || true + elif [ -f "$line" ] + then + echo "$line" + fi + ); +done | while read mod; do + echo "SUB_INST checking: $mod" + fromdir="/lib/modules/$ABI_RELEASE-$FROM/" + egrep "^($fromdir)?kernel/$mod:" \ + $from_moddir/modules.dep | sed -e "s|^$fromdir||" -e 's/://' -e 's/ /\n/g' | \ + while read m; do + m="${fromdir}$m" + test -f debian/$to_pkg/$m && continue + echo "SUB_INST installing: $m" + install -D -m644 debian/$from_pkg/$m \ + debian/$to_pkg/$m + done +done --- linux-oracle-5.4.0.orig/debian/snapcraft.mk +++ linux-oracle-5.4.0/debian/snapcraft.mk @@ -0,0 +1,15 @@ +ifeq ($(ARCH),) + arch := $(shell uname -m | sed -e s/i.86/i386/ -e s/x86_64/amd64/ \ + -e s/arm.*/armhf/ -e s/s390/s390x/ -e s/ppc.*/powerpc/ \ + -e s/aarch64.*/arm64/ ) +else ifeq ($(ARCH),arm) + arch := armhf +else + arch := $(ARCH) +endif +config: + if [ -e debian/config/config.common.ubuntu ]; then \ + cat debian.$(branch)/config/config.common.ubuntu debian.$(branch)/config/$(arch)/config.common.$(arch) debian.$(branch)/config/$(arch)/config.flavour.$(flavour) >.config; \ + else \ + python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(flavour) >.config; \ + fi --- linux-oracle-5.4.0.orig/debian/source/format +++ linux-oracle-5.4.0/debian/source/format @@ -0,0 +1 @@ +1.0 --- linux-oracle-5.4.0.orig/debian/source/options +++ linux-oracle-5.4.0/debian/source/options @@ -0,0 +1,8 @@ +# Ignore vbox symlinks, we will regenerate these at clean (LP:1426113) +## autoreconstruct -- begin +# Ignore any symlinks created since the orig which are rebuilt by reconstruct. +## autoreconstruct -- end + +# force "dpkg-source -I -i" behavior +diff-ignore +tar-ignore --- linux-oracle-5.4.0.orig/debian/stamps/keep-dir +++ linux-oracle-5.4.0/debian/stamps/keep-dir @@ -0,0 +1 @@ +Place holder --- linux-oracle-5.4.0.orig/debian/templates/extra.postinst.in +++ linux-oracle-5.4.0/debian/templates/extra.postinst.in @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" != configure ]; then + exit 0 +fi + +depmod -a -F /boot/System.map-$version $version || true +if [ -d /etc/kernel/postinst.d ]; then + cat - >/usr/lib/linux/triggers/$version </dev/null || true +# +# We should be rebuilding the initramfs here on removal to pare down the +# initramfs if it contains any of the objects we just removed. But people +# commonly remove kernels in order to free space in /boot, and rebuilding the +# initramfs now risks ENOSPC when we are trying to make space. The files we +# leave lying about could be confusing, but we trade that against safety on +# removal. +# +#if [ -d /etc/kernel/postinst.d ]; then +# # We want to behave as if linux-image (without us) was installed, therefore +# # we do not want the postinst support to know we are being removed, claim +# # this is an installation event. +# cat - >/usr/lib/linux/triggers/$version </usr/lib/linux/triggers/$version </dev/null; then + linux-update-symlinks remove $version $image_path +fi + +if [ -d /etc/kernel/postrm.d ]; then + # We cannot trigger ourselves as at the end of this we will no longer + # exist and can no longer respond to the trigger. The trigger would + # then become lost. Therefore we clear any pending trigger and apply + # postrm directly. + if [ -f /usr/lib/linux/triggers/$version ]; then + echo "$0 ... removing pending trigger" + rm -f /usr/lib/linux/triggers/$version + fi + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/postrm.d +fi + +if [ "$1" = purge ]; then + for extra_file in modules.dep modules.isapnpmap modules.pcimap \ + modules.usbmap modules.parportmap \ + modules.generic_string modules.ieee1394map \ + modules.ieee1394map modules.pnpbiosmap \ + modules.alias modules.ccwmap modules.inputmap \ + modules.symbols modules.ofmap \ + modules.seriomap modules.\*.bin \ + modules.softdep modules.devname; do + eval rm -f /lib/modules/$version/$extra_file + done + rmdir /lib/modules/$version || true +fi + +exit 0 --- linux-oracle-5.4.0.orig/debian/templates/image.preinst.in +++ linux-oracle-5.4.0/debian/templates/image.preinst.in @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" = abort-upgrade ]; then + exit 0 +fi + +if [ "$1" = install ]; then + # Create a flag file for postinst + mkdir -p /lib/modules/$version + touch /lib/modules/$version/.fresh-install +fi + +if [ -d /etc/kernel/preinst.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/preinst.d +fi + +exit 0 --- linux-oracle-5.4.0.orig/debian/templates/image.prerm.in +++ linux-oracle-5.4.0/debian/templates/image.prerm.in @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" != remove ]; then + exit 0 +fi + +linux-check-removal $version + +if [ -d /etc/kernel/prerm.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/prerm.d +fi + +exit 0 --- linux-oracle-5.4.0.orig/debian/tests-build/README +++ linux-oracle-5.4.0/debian/tests-build/README @@ -0,0 +1,21 @@ +Scripts placed in this directory get called one at a time by run-parts(8). +The scripts are expected to perform some sort of sanity checks on the +finished build. Scripts will be called once for each flavour. + +Some environment variables are exported to make life a little easier: + +DPKG_ARCH : The dpkg architecture (e.g. "amd64") +KERN_ARCH : The kernel architecture (e.g. "x86_64") +FLAVOUR : The specific flavour for this run (e.g. "generic") +VERSION : The full version of this build (e.g. 2.6.22-1) +REVISION : The exact revision of this build (e.g. 1.3) +PREV_REVISION : The revision prior to this one +ABI_NUM : The specific ABI number for this build (e.g. 2) +PREV_ABI_NUM : The previous ABI number. Can be the same as ABI_NUM. +BUILD_DIR : The directory where this build took place +INSTALL_DIR : The directory where the package is prepared +SOURCE_DIR : Where the main kernel source is + +Scripts are expected to have a zero exit status when no problems occur, +and non-zero when an error occurs that should stop the build. Scripts +should print whatever info they deem needed to deduce the problem. --- linux-oracle-5.4.0.orig/debian/tests-build/check-aliases +++ linux-oracle-5.4.0/debian/tests-build/check-aliases @@ -0,0 +1,24 @@ +#!/usr/bin/perl -w + +my %map; + +print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n"; + +$aliases = + "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias"; + +open(ALIASES, "< $aliases") or die "Could not open $aliases"; + +while () { + chomp; + my ($junk, $alias, $module) = split; + + if (defined($map{$alias})) { + printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module") + ? "INT" : " ", $map{$alias}, $module, $alias); + } else { + $map{$alias} = $module; + } +} + +exit(0); --- linux-oracle-5.4.0.orig/debian/tests/control +++ linux-oracle-5.4.0/debian/tests/control @@ -0,0 +1,7 @@ +Tests: rebuild +Depends: @builddeps@, fakeroot +Restrictions: allow-stderr, skippable + +Tests: ubuntu-regression-suite +Depends: build-essential, gcc-multilib [amd64 armhf i386], gdb, git, python2 | python, bzr +Restrictions: allow-stderr, isolation-machine, breaks-testbed, skippable --- linux-oracle-5.4.0.orig/debian/tests/rebuild +++ linux-oracle-5.4.0/debian/tests/rebuild @@ -0,0 +1,20 @@ +#!/bin/sh + +# If we are triggering for just linux or linux-meta we know we have +# just built the kernel and there is no point in repeating that +# build, it just wastes time. (LP: #1498862) +build_needed=0 +for trigger in ${ADT_TEST_TRIGGERS:-force} +do + case "$trigger" in + linux/*|linux-lts-*/*|linux-meta*/*|linux-oem*/*|fakeroot/*|gdb/*|git/*|bzr/*|gcc-multilib/*) ;; + *) build_needed=1 ;; + esac +done +if [ "$build_needed" -eq 0 ]; then + echo "rebuild: short circuiting build for '${ADT_TEST_TRIGGERS}'" + exit 77 +fi + +set -e +dpkg-buildpackage -rfakeroot -us -uc -b -Pautopkgtest --- linux-oracle-5.4.0.orig/debian/tests/ubuntu-regression-suite +++ linux-oracle-5.4.0/debian/tests/ubuntu-regression-suite @@ -0,0 +1,45 @@ +#!/bin/sh +set -e + +# Only run regression-suite on kernels we can boot in canonistack +source=`dpkg-parsechangelog -SSource` +case $source in + linux|linux-hwe*|linux-kvm|linux-oem) + ;; + *) + echo "ubuntu-regression-suite is pointless, if one cannot boot the kernel" + exit 77 + ;; +esac + +# Only run regression-suite if we were requested to +have_meta=0 +for trigger in ${ADT_TEST_TRIGGERS} +do + case "$trigger" in + linux-meta/*|linux-meta-*/*) + have_meta=1 + ;; + esac +done +if [ -n "$ADT_TEST_TRIGGERS" ] && [ "$have_meta" -eq 0 ]; then + echo "ubuntu-regression-suite is not requested, as there is no linux-meta trigger" + exit 77 +fi + +sver=`dpkg-parsechangelog -SVersion` +read x rver x &2 + exit 1 +fi + +git clone --depth=1 git://git.launchpad.net/~canonical-kernel-team/+git/kernel-testing +kernel-testing/run-dep8-tests --- linux-oracle-5.4.0.orig/debian/tools/generic +++ linux-oracle-5.4.0/debian/tools/generic @@ -0,0 +1,60 @@ +#!/bin/bash +full_version=`uname -r` + +# First check for a fully qualified version. +this="/usr/lib/linux-tools/$full_version/`basename $0`" +if [ -f "$this" ]; then + exec "$this" "$@" +fi + +# Removing flavour from version i.e. generic or server. +flavour_abi=${full_version#*-} +flavour=${flavour_abi#*-} +version=${full_version%-$flavour} +this="$0_$version" +if [ -f "$this" ]; then + exec "$this" "$@" +fi + +# Before saucy kernels we had no flavour linkage. +if dpkg --compare-versions "$version" lt "3.11.0"; then + flavour='' +else + flavour="-$flavour" +fi +# Hint at the cloud tools if they exist (trusty and later) +if dpkg --compare-versions "$version" ge "3.13.0"; then + cld="" +else + cld=":" +fi +# Work out if this is an LTS backport or not. +codename=`lsb_release -cs` +case "$codename" in +precise) base='3.2.0-9999' ;; +trusty) base='3.13.0-9999' ;; +*) base='' ;; +esac +std="" +lts=":" +if [ "$base" != "" ]; then + if dpkg --compare-versions "$version" gt "$base"; then + std=":" + lts="" + fi +fi + +# Give them a hint as to what to install. + echo "WARNING: `basename $0` not found for kernel $version" >&2 + echo "" >&2 + echo " You may need to install the following packages for this specific kernel:" >&2 + echo " linux-tools-$version$flavour" >&2 +$cld echo " linux-cloud-tools-$version$flavour" >&2 + echo "" >&2 + echo " You may also want to install one of the following packages to keep up to date:" >&2 +$std echo " linux-tools$flavour" >&2 +$std $cld echo " linux-cloud-tools$flavour" >&2 +$lts echo " linux-tools$flavour-lts-" >&2 +$lts $cld echo " linux-cloud-tools$flavour-lts-" >&2 + +exit 2 --- linux-oracle-5.4.0.orig/debian/vbox-modules.ignore +++ linux-oracle-5.4.0/debian/vbox-modules.ignore @@ -0,0 +1,2 @@ +vboxguest +vboxsf --- linux-oracle-5.4.0.orig/debian/wireguard-modules.ignore +++ linux-oracle-5.4.0/debian/wireguard-modules.ignore @@ -0,0 +1 @@ +wireguard --- linux-oracle-5.4.0.orig/debian/zfs-modules.ignore +++ linux-oracle-5.4.0/debian/zfs-modules.ignore @@ -0,0 +1,10 @@ +icp +spl +splat +zavl +zcommon +zfs +zlua +znvpair +zpios +zunicode --- linux-oracle-5.4.0.orig/drivers/Makefile +++ linux-oracle-5.4.0/drivers/Makefile @@ -58,14 +58,9 @@ # iommu/ comes before gpu as gpu are using iommu controllers obj-y += iommu/ -# gpu/ comes after char for AGP vs DRM startup and after iommu -obj-y += gpu/ obj-$(CONFIG_CONNECTOR) += connector/ -# i810fb and intelfb depend on char/agp/ -obj-$(CONFIG_FB_I810) += video/fbdev/i810/ -obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/ obj-$(CONFIG_PARPORT) += parport/ obj-$(CONFIG_NVM) += lightnvm/ @@ -79,6 +74,12 @@ obj-y += scsi/ obj-y += nvme/ obj-$(CONFIG_ATA) += ata/ + +# gpu/ comes after char for AGP vs DRM startup and after iommu +obj-y += gpu/ +# i810fb and intelfb depend on char/agp/ +obj-$(CONFIG_FB_I810) += video/fbdev/i810/ +obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/ obj-$(CONFIG_TARGET_CORE) += target/ obj-$(CONFIG_MTD) += mtd/ obj-$(CONFIG_SPI) += spi/ --- linux-oracle-5.4.0.orig/drivers/acpi/Makefile +++ linux-oracle-5.4.0/drivers/acpi/Makefile @@ -8,6 +8,11 @@ # # ACPI Boot-Time Table Parsing # +ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y) +tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ; + +endif + obj-$(CONFIG_ACPI) += tables.o obj-$(CONFIG_X86) += blacklist.o @@ -48,7 +53,7 @@ acpi-$(CONFIG_ARM_AMBA) += acpi_amba.o acpi-y += power.o acpi-y += event.o -acpi-$(CONFIG_ACPI_REDUCED_HARDWARE_ONLY) += evged.o +acpi-y += evged.o acpi-y += sysfs.o acpi-y += property.o acpi-$(CONFIG_X86) += acpi_cmos_rtc.o --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_amba.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_amba.c @@ -76,6 +76,7 @@ case IORESOURCE_MEM: if (!address_found) { dev->res = *rentry->res; + dev->res.name = dev_name(&dev->dev); address_found = true; } break; --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_configfs.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_configfs.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "acpica/accommon.h" #include "acpica/actables.h" @@ -28,7 +29,10 @@ { const struct acpi_table_header *header = data; struct acpi_table *table; - int ret; + int ret = security_locked_down(LOCKDOWN_ACPI_TABLES); + + if (ret) + return ret; table = container_of(cfg, struct acpi_table, cfg); @@ -263,7 +267,12 @@ acpi_table_group = configfs_register_default_group(root, "table", &acpi_tables_type); - return PTR_ERR_OR_ZERO(acpi_table_group); + if (IS_ERR(acpi_table_group)) { + configfs_unregister_subsystem(&acpi_configfs); + return PTR_ERR(acpi_table_group); + } + + return 0; } module_init(acpi_configfs_init); --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_dbg.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_dbg.c @@ -749,6 +749,9 @@ { int ret; + if (acpi_disabled) + return -ENODEV; + /* Initialize AML IO interface */ mutex_init(&acpi_aml_io.lock); init_waitqueue_head(&acpi_aml_io.wait); --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_extlog.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_extlog.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -140,8 +141,8 @@ int cpu = mce->extcpu; struct acpi_hest_generic_status *estatus, *tmp; struct acpi_hest_generic_data *gdata; - const guid_t *fru_id = &guid_null; - char *fru_text = ""; + const guid_t *fru_id; + char *fru_text; guid_t *sec_type; static u32 err_seq; @@ -162,17 +163,23 @@ /* log event via trace */ err_seq++; - gdata = (struct acpi_hest_generic_data *)(tmp + 1); - if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) - fru_id = (guid_t *)gdata->fru_id; - if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) - fru_text = gdata->fru_text; - sec_type = (guid_t *)gdata->section_type; - if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { - struct cper_sec_mem_err *mem = (void *)(gdata + 1); - if (gdata->error_data_length >= sizeof(*mem)) - trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, - (u8)gdata->error_severity); + apei_estatus_for_each_section(tmp, gdata) { + if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) + fru_id = (guid_t *)gdata->fru_id; + else + fru_id = &guid_null; + if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) + fru_text = gdata->fru_text; + else + fru_text = ""; + sec_type = (guid_t *)gdata->section_type; + if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { + struct cper_sec_mem_err *mem = (void *)(gdata + 1); + + if (gdata->error_data_length >= sizeof(*mem)) + trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, + (u8)gdata->error_severity); + } } out: @@ -223,9 +230,9 @@ u64 cap; int rc; - rdmsrl(MSR_IA32_MCG_CAP, cap); - - if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr()) + if (rdmsrl_safe(MSR_IA32_MCG_CAP, &cap) || + !(cap & MCG_ELOG_P) || + !extlog_get_l1addr()) return -ENODEV; if (edac_get_report_status() == EDAC_REPORTING_FORCE) { @@ -309,9 +316,10 @@ { edac_set_report_status(old_edac_report_status); mce_unregister_decode_chain(&extlog_mce_dec); - ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; - if (extlog_l1_addr) + if (extlog_l1_addr) { + ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; acpi_os_unmap_iomem(extlog_l1_addr, l1_size); + } if (elog_addr) acpi_os_unmap_iomem(elog_addr, elog_size); release_mem_region(elog_base, elog_size); --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_lpit.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_lpit.c @@ -98,7 +98,7 @@ struct acpi_lpit_native *lpit_native) { info->frequency = lpit_native->counter_frequency ? - lpit_native->counter_frequency : tsc_khz * 1000; + lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U); if (!info->frequency) info->frequency = 1; --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_lpss.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_lpss.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -400,6 +401,9 @@ if (!lpss_clk_dev) lpt_register_clock_device(); + if (IS_ERR(lpss_clk_dev)) + return PTR_ERR(lpss_clk_dev); + clk_data = platform_get_drvdata(lpss_clk_dev); if (!clk_data) return -ENODEV; @@ -463,6 +467,18 @@ const char *consumer_hid; const char *consumer_uid; u32 flags; + const struct dmi_system_id *dep_missing_ids; +}; + +/* Please keep this list sorted alphabetically by vendor and model */ +static const struct dmi_system_id i2c1_dep_missing_dmi_ids[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "T200TA"), + }, + }, + {} }; /* @@ -473,9 +489,17 @@ * the supplier is not enumerated until after the consumer is probed. */ static const struct lpss_device_links lpss_device_links[] = { + /* CHT External sdcard slot controller depends on PMIC I2C ctrl */ {"808622C1", "7", "80860F14", "3", DL_FLAG_PM_RUNTIME}, + /* CHT iGPU depends on PMIC I2C controller */ {"808622C1", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, + /* BYT iGPU depends on the Embedded Controller I2C controller (UID 1) */ + {"80860F41", "1", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME, + i2c1_dep_missing_dmi_ids}, + /* BYT CR iGPU depends on PMIC I2C controller (UID 5 on CR) */ {"80860F41", "5", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, + /* BYT iGPU depends on PMIC I2C controller (UID 7 on non CR) */ + {"80860F41", "7", "LNXVIDEO", NULL, DL_FLAG_PM_RUNTIME}, }; static bool hid_uid_match(struct acpi_device *adev, @@ -570,7 +594,8 @@ if (!dev2) return; - if (acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1))) + if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids)) + || acpi_lpss_dep(ACPI_COMPANION(dev2), ACPI_HANDLE(dev1))) device_link_add(dev2, dev1, link->flags); put_device(dev2); @@ -585,7 +610,8 @@ if (!dev2) return; - if (acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2))) + if ((link->dep_missing_ids && dmi_check_system(link->dep_missing_ids)) + || acpi_lpss_dep(ACPI_COMPANION(dev1), ACPI_HANDLE(dev2))) device_link_add(dev1, dev2, link->flags); put_device(dev2); --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_pad.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_pad.c @@ -88,7 +88,7 @@ cpumask_var_t tmp; int cpu; unsigned long min_weight = -1; - unsigned long uninitialized_var(preferred_cpu); + unsigned long preferred_cpu; if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; @@ -262,7 +262,7 @@ return ps_tsk_num; } -static ssize_t acpi_pad_rrtime_store(struct device *dev, +static ssize_t rrtime_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -276,16 +276,14 @@ return count; } -static ssize_t acpi_pad_rrtime_show(struct device *dev, +static ssize_t rrtime_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time); } -static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, - acpi_pad_rrtime_show, - acpi_pad_rrtime_store); +static DEVICE_ATTR_RW(rrtime); -static ssize_t acpi_pad_idlepct_store(struct device *dev, +static ssize_t idlepct_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -299,16 +297,14 @@ return count; } -static ssize_t acpi_pad_idlepct_show(struct device *dev, +static ssize_t idlepct_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct); } -static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, - acpi_pad_idlepct_show, - acpi_pad_idlepct_store); +static DEVICE_ATTR_RW(idlepct); -static ssize_t acpi_pad_idlecpus_store(struct device *dev, +static ssize_t idlecpus_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -320,16 +316,14 @@ return count; } -static ssize_t acpi_pad_idlecpus_show(struct device *dev, +static ssize_t idlecpus_show(struct device *dev, struct device_attribute *attr, char *buf) { return cpumap_print_to_pagebuf(false, buf, to_cpumask(pad_busy_cpus_bits)); } -static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, - acpi_pad_idlecpus_show, - acpi_pad_idlecpus_store); +static DEVICE_ATTR_RW(idlecpus); static int acpi_pad_add_sysfs(struct acpi_device *device) { --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_platform.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_platform.c @@ -31,6 +31,44 @@ {"", 0}, }; +static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev) +{ + struct device *dev; + + dev = bus_find_device_by_acpi_dev(&platform_bus_type, adev); + return dev ? to_platform_device(dev) : NULL; +} + +static int acpi_platform_device_remove_notify(struct notifier_block *nb, + unsigned long value, void *arg) +{ + struct acpi_device *adev = arg; + struct platform_device *pdev; + + switch (value) { + case ACPI_RECONFIG_DEVICE_ADD: + /* Nothing to do here */ + break; + case ACPI_RECONFIG_DEVICE_REMOVE: + if (!acpi_device_enumerated(adev)) + break; + + pdev = acpi_platform_device_find_by_companion(adev); + if (!pdev) + break; + + platform_device_unregister(pdev); + put_device(&pdev->dev); + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block acpi_platform_notifier = { + .notifier_call = acpi_platform_device_remove_notify, +}; + static void acpi_platform_fill_resource(struct acpi_device *adev, const struct resource *src, struct resource *dest) { @@ -130,3 +168,8 @@ return pdev; } EXPORT_SYMBOL_GPL(acpi_create_platform_device); + +void __init acpi_platform_init(void) +{ + acpi_reconfig_notifier_register(&acpi_platform_notifier); +} --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_pnp.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_pnp.c @@ -317,6 +317,9 @@ { int i; + if (strlen(idstr) != strlen(list_id)) + return false; + if (memcmp(idstr, list_id, 3)) return false; --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_processor.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_processor.c @@ -388,7 +388,7 @@ result = acpi_processor_get_info(device); if (result) /* Processor is not physically present or unavailable */ - return 0; + goto err_clear_driver_data; BUG_ON(pr->id >= nr_cpu_ids); @@ -403,7 +403,7 @@ "BIOS reported wrong ACPI id %d for the processor\n", pr->id); /* Give up, but do not abort the namespace scan. */ - goto err; + goto err_clear_driver_data; } /* * processor_device_array is not cleared on errors to allow buggy BIOS @@ -415,12 +415,12 @@ dev = get_cpu_device(pr->id); if (!dev) { result = -ENODEV; - goto err; + goto err_clear_per_cpu; } result = acpi_bind_one(dev, device); if (result) - goto err; + goto err_clear_per_cpu; pr->dev = dev; @@ -431,10 +431,11 @@ dev_err(dev, "Processor driver could not be attached\n"); acpi_unbind_one(dev); - err: - free_cpumask_var(pr->throttling.shared_cpu_map); - device->driver_data = NULL; + err_clear_per_cpu: per_cpu(processors, pr->id) = NULL; + err_clear_driver_data: + device->driver_data = NULL; + free_cpumask_var(pr->throttling.shared_cpu_map); err_free_pr: kfree(pr); return result; --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_tad.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_tad.c @@ -237,7 +237,7 @@ rt.tz, rt.daylight); } -static DEVICE_ATTR(time, S_IRUSR | S_IWUSR, time_show, time_store); +static DEVICE_ATTR_RW(time); static struct attribute *acpi_tad_time_attrs[] = { &dev_attr_time.attr, @@ -446,7 +446,7 @@ return acpi_tad_alarm_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_alarm, S_IRUSR | S_IWUSR, ac_alarm_show, ac_alarm_store); +static DEVICE_ATTR_RW(ac_alarm); static ssize_t ac_policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -462,7 +462,7 @@ return acpi_tad_policy_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_policy, S_IRUSR | S_IWUSR, ac_policy_show, ac_policy_store); +static DEVICE_ATTR_RW(ac_policy); static ssize_t ac_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -478,7 +478,7 @@ return acpi_tad_status_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_status, S_IRUSR | S_IWUSR, ac_status_show, ac_status_store); +static DEVICE_ATTR_RW(ac_status); static struct attribute *acpi_tad_attrs[] = { &dev_attr_caps.attr, @@ -505,7 +505,7 @@ return acpi_tad_alarm_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_alarm, S_IRUSR | S_IWUSR, dc_alarm_show, dc_alarm_store); +static DEVICE_ATTR_RW(dc_alarm); static ssize_t dc_policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -521,7 +521,7 @@ return acpi_tad_policy_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_policy, S_IRUSR | S_IWUSR, dc_policy_show, dc_policy_store); +static DEVICE_ATTR_RW(dc_policy); static ssize_t dc_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -537,7 +537,7 @@ return acpi_tad_status_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_status, S_IRUSR | S_IWUSR, dc_status_show, dc_status_store); +static DEVICE_ATTR_RW(dc_status); static struct attribute *acpi_tad_dc_attrs[] = { &dev_attr_dc_alarm.attr, --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_video.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_video.c @@ -498,6 +498,22 @@ DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE R830"), }, }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Satellite Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Z830"), + }, + }, + { + .callback = video_disable_backlight_sysfs_if, + .ident = "Toshiba Portege Z830", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE Z830"), + }, + }, /* * Some machine's _DOD IDs don't have bit 31(Device ID Scheme) set * but the IDs actually follow the Device ID Scheme. @@ -543,6 +559,24 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), }, }, + { + .callback = video_set_report_key_events, + .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS), + .ident = "Dell Vostro 3350", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"), + }, + }, + { + .callback = video_set_report_key_events, + .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS), + .ident = "COLORFUL X15 AT 23", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "COLORFUL"), + DMI_MATCH(DMI_PRODUCT_NAME, "X15 AT 23"), + }, + }, /* * Some machines change the brightness themselves when a brightness * hotkey gets pressed, despite us telling them not to. In this case @@ -1759,12 +1793,12 @@ return; count++; - acpi_get_parent(device->dev->handle, &acpi_parent); - - pdev = acpi_get_pci_dev(acpi_parent); - if (pdev) { - parent = &pdev->dev; - pci_dev_put(pdev); + if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) { + pdev = acpi_get_pci_dev(acpi_parent); + if (pdev) { + parent = &pdev->dev; + pci_dev_put(pdev); + } } memset(&props, 0, sizeof(struct backlight_properties)); --- linux-oracle-5.4.0.orig/drivers/acpi/acpi_watchdog.c +++ linux-oracle-5.4.0/drivers/acpi/acpi_watchdog.c @@ -55,12 +55,14 @@ } #endif +static bool acpi_no_watchdog; + static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) { const struct acpi_table_wdat *wdat = NULL; acpi_status status; - if (acpi_disabled) + if (acpi_disabled || acpi_no_watchdog) return NULL; status = acpi_get_table(ACPI_SIG_WDAT, 0, @@ -88,6 +90,14 @@ } EXPORT_SYMBOL_GPL(acpi_has_watchdog); +/* ACPI watchdog can be disabled on boot command line */ +static int __init disable_acpi_watchdog(char *str) +{ + acpi_no_watchdog = true; + return 1; +} +__setup("acpi_no_watchdog", disable_acpi_watchdog); + void __init acpi_watchdog_init(void) { const struct acpi_wdat_entry *entries; @@ -126,12 +136,11 @@ gas = &entries[i].register_region; res.start = gas->address; + res.end = res.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { res.flags = IORESOURCE_MEM; - res.end = res.start + ALIGN(gas->access_width, 4) - 1; } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { res.flags = IORESOURCE_IO; - res.end = res.start + gas->access_width - 1; } else { pr_warn("Unsupported address space: %u\n", gas->space_id); --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/Makefile +++ linux-oracle-5.4.0/drivers/acpi/acpica/Makefile @@ -3,8 +3,9 @@ # Makefile for ACPICA Core interpreter # -ccflags-y := -Os -D_LINUX -DBUILDING_ACPICA +ccflags-y := -D_LINUX -DBUILDING_ACPICA ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT +CFLAGS_tbfind.o += $(call cc-disable-warning, stringop-truncation) # use acpi.o to put all files here into acpi.o modparam namespace obj-y += acpi.o --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/acglobal.h +++ linux-oracle-5.4.0/drivers/acpi/acpica/acglobal.h @@ -220,6 +220,8 @@ acpi_gbl_bit_register_info[ACPI_NUM_BITREG]; ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a); ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b); +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_a_s0); +ACPI_GLOBAL(u8, acpi_gbl_sleep_type_b_s0); /***************************************************************************** * --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/achware.h +++ linux-oracle-5.4.0/drivers/acpi/acpica/achware.h @@ -101,6 +101,8 @@ acpi_status acpi_hw_enable_all_wakeup_gpes(void); +u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number); + acpi_status acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, struct acpi_gpe_block_info *gpe_block, --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/acnamesp.h +++ linux-oracle-5.4.0/drivers/acpi/acpica/acnamesp.h @@ -256,6 +256,8 @@ acpi_ns_build_normalized_path(struct acpi_namespace_node *node, char *full_path, u32 path_size, u8 no_trailing); +void acpi_ns_normalize_pathname(char *original_path); + char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node, u8 no_trailing); --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/acobject.h +++ linux-oracle-5.4.0/drivers/acpi/acpica/acobject.h @@ -283,6 +283,7 @@ acpi_adr_space_handler handler; struct acpi_namespace_node *node; /* Parent device */ void *context; + acpi_mutex context_mutex; acpi_adr_space_setup setup; union acpi_operand_object *region_list; /* Regions using this handler */ union acpi_operand_object *next; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dbconvert.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dbconvert.c @@ -170,6 +170,8 @@ elements = ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS * sizeof(union acpi_object)); + if (!elements) + return (AE_NO_MEMORY); this = string; for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) { --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dbinput.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dbinput.c @@ -464,16 +464,14 @@ return (NULL); } - /* Remove any spaces at the beginning */ + /* Remove any spaces at the beginning, ignore blank lines */ - if (*string == ' ') { - while (*string && (*string == ' ')) { - string++; - } + while (*string && isspace(*string)) { + string++; + } - if (!(*string)) { - return (NULL); - } + if (!(*string)) { + return (NULL); } switch (*string) { @@ -551,7 +549,7 @@ /* Find end of token */ - while (*string && (*string != ' ')) { + while (*string && !isspace(*string)) { string++; } break; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dbnames.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dbnames.c @@ -571,6 +571,9 @@ object_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info)); + if (!object_info) + return (AE_NO_MEMORY); + /* Walk the namespace from the root */ (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dsfield.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dsfield.c @@ -244,7 +244,7 @@ * FUNCTION: acpi_ds_get_field_names * * PARAMETERS: info - create_field info structure - * ` walk_state - Current method state + * walk_state - Current method state * arg - First parser arg for the field name list * * RETURN: Status @@ -518,13 +518,20 @@ info.region_node = region_node; status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + if (info.region_node->object->region.space_id == - ACPI_ADR_SPACE_PLATFORM_COMM - && !(region_node->object->field.internal_pcc_buffer = - ACPI_ALLOCATE_ZEROED(info.region_node->object->region. - length))) { - return_ACPI_STATUS(AE_NO_MEMORY); + ACPI_ADR_SPACE_PLATFORM_COMM) { + region_node->object->field.internal_pcc_buffer = + ACPI_ALLOCATE_ZEROED(info.region_node->object->region. + length); + if (!region_node->object->field.internal_pcc_buffer) { + return_ACPI_STATUS(AE_NO_MEMORY); + } } + return_ACPI_STATUS(status); } --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dsmethod.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dsmethod.c @@ -517,7 +517,7 @@ info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info)); if (!info) { status = AE_NO_MEMORY; - goto cleanup; + goto pop_walk_state; } info->parameters = &this_walk_state->operands[0]; @@ -529,7 +529,7 @@ ACPI_FREE(info); if (ACPI_FAILURE(status)) { - goto cleanup; + goto pop_walk_state; } next_walk_state->method_nesting_depth = @@ -575,6 +575,12 @@ return_ACPI_STATUS(status); +pop_walk_state: + + /* On error, pop the walk state to be deleted from thread */ + + acpi_ds_pop_walk_state(thread); + cleanup: /* On error, we must terminate the method properly */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dswexec.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dswexec.c @@ -16,6 +16,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acdebug.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswexec") @@ -329,6 +332,10 @@ u32 op_class; union acpi_parse_object *next_op; union acpi_parse_object *first_arg; +#ifdef ACPI_EXEC_APP + char *namepath; + union acpi_operand_object *obj_desc; +#endif ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state); @@ -537,6 +544,32 @@ status = acpi_ds_eval_buffer_field_operands(walk_state, op); + if (ACPI_FAILURE(status)) { + break; + } +#ifdef ACPI_EXEC_APP + /* + * acpi_exec support for namespace initialization file (initialize + * buffer_fields in this code.) + */ + namepath = + acpi_ns_get_external_pathname(op->common.node); + status = ae_lookup_init_file_entry(namepath, &obj_desc); + if (ACPI_SUCCESS(status)) { + status = + acpi_ex_write_data_to_field(obj_desc, + op->common. + node->object, + NULL); + if ACPI_FAILURE + (status) { + ACPI_EXCEPTION((AE_INFO, status, + "While writing to buffer field")); + } + } + ACPI_FREE(namepath); + status = AE_OK; +#endif break; case AML_TYPE_CREATE_OBJECT: --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dswload.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dswload.c @@ -14,7 +14,6 @@ #include "acdispat.h" #include "acinterp.h" #include "acnamesp.h" - #ifdef ACPI_ASL_COMPILER #include "acdisasm.h" #endif @@ -399,7 +398,6 @@ union acpi_parse_object *op; acpi_object_type object_type; acpi_status status = AE_OK; - #ifdef ACPI_ASL_COMPILER u8 param_count; #endif @@ -410,6 +408,27 @@ ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); + /* + * Disassembler: handle create field operators here. + * + * create_buffer_field is a deferred op that is typically processed in load + * pass 2. However, disassembly of control method contents walk the parse + * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed + * in a later walk. This is a problem when there is a control method that + * has the same name as the AML_CREATE object. In this case, any use of the + * name segment will be detected as a method call rather than a reference + * to a buffer field. + * + * This earlier creation during disassembly solves this issue by inserting + * the named object in the ACPI namespace so that references to this name + * would be a name string rather than a method call. + */ + if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) && + (walk_state->op_info->flags & AML_CREATE)) { + status = acpi_ds_create_buffer_field(op, walk_state); + return_ACPI_STATUS(status); + } + /* We are only interested in opcodes that have an associated name */ if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) { --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dswload2.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dswload2.c @@ -15,6 +15,9 @@ #include "acinterp.h" #include "acnamesp.h" #include "acevents.h" +#ifdef ACPI_EXEC_APP +#include "aecommon.h" +#endif #define _COMPONENT ACPI_DISPATCHER ACPI_MODULE_NAME("dswload2") @@ -373,6 +376,10 @@ struct acpi_namespace_node *new_node; u32 i; u8 region_space; +#ifdef ACPI_EXEC_APP + union acpi_operand_object *obj_desc; + char *namepath; +#endif ACPI_FUNCTION_TRACE(ds_load2_end_op); @@ -466,6 +473,11 @@ * be evaluated later during the execution phase */ status = acpi_ds_create_buffer_field(op, walk_state); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "CreateBufferField failure")); + goto cleanup; + } break; case AML_TYPE_NAMED_FIELD: @@ -604,6 +616,29 @@ case AML_NAME_OP: status = acpi_ds_create_node(walk_state, node, op); + if (ACPI_FAILURE(status)) { + goto cleanup; + } +#ifdef ACPI_EXEC_APP + /* + * acpi_exec support for namespace initialization file (initialize + * Name opcodes in this code.) + */ + namepath = acpi_ns_get_external_pathname(node); + status = ae_lookup_init_file_entry(namepath, &obj_desc); + if (ACPI_SUCCESS(status)) { + + /* Detach any existing object, attach new object */ + + if (node->object) { + acpi_ns_detach_object(node); + } + acpi_ns_attach_object(node, obj_desc, + obj_desc->common.type); + } + ACPI_FREE(namepath); + status = AE_OK; +#endif break; case AML_METHOD_OP: --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/dswstate.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/dswstate.c @@ -576,9 +576,14 @@ ACPI_FUNCTION_TRACE(ds_init_aml_walk); walk_state->parser_state.aml = - walk_state->parser_state.aml_start = aml_start; - walk_state->parser_state.aml_end = - walk_state->parser_state.pkg_end = aml_start + aml_length; + walk_state->parser_state.aml_start = + walk_state->parser_state.aml_end = + walk_state->parser_state.pkg_end = aml_start; + /* Avoid undefined behavior: applying zero offset to null pointer */ + if (aml_length != 0) { + walk_state->parser_state.aml_end += aml_length; + walk_state->parser_state.pkg_end += aml_length; + } /* The next_op of the next_walk will be the beginning of the method */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/evevent.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/evevent.c @@ -265,4 +265,49 @@ handler) (acpi_gbl_fixed_event_handlers[event].context)); } +/******************************************************************************* + * + * FUNCTION: acpi_any_fixed_event_status_set + * + * PARAMETERS: None + * + * RETURN: TRUE or FALSE + * + * DESCRIPTION: Checks the PM status register for active fixed events + * + ******************************************************************************/ + +u32 acpi_any_fixed_event_status_set(void) +{ + acpi_status status; + u32 in_status; + u32 in_enable; + u32 i; + + status = acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &in_enable); + if (ACPI_FAILURE(status)) { + return (FALSE); + } + + status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &in_status); + if (ACPI_FAILURE(status)) { + return (FALSE); + } + + /* + * Check for all possible Fixed Events and dispatch those that are active + */ + for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { + + /* Both the status and enable bits must be on for this event */ + + if ((in_status & acpi_gbl_fixed_event_info[i].status_bit_mask) && + (in_enable & acpi_gbl_fixed_event_info[i].enable_bit_mask)) { + return (TRUE); + } + } + + return (FALSE); +} + #endif /* !ACPI_REDUCED_HARDWARE */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/evhandler.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/evhandler.c @@ -489,6 +489,13 @@ /* Init handler obj */ + status = + acpi_os_create_mutex(&handler_obj->address_space.context_mutex); + if (ACPI_FAILURE(status)) { + acpi_ut_remove_reference(handler_obj); + goto unlock_and_exit; + } + handler_obj->address_space.space_id = (u8)space_id; handler_obj->address_space.handler_flags = flags; handler_obj->address_space.region_list = NULL; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/evregion.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/evregion.c @@ -111,6 +111,8 @@ union acpi_operand_object *region_obj2; void *region_context = NULL; struct acpi_connection_info *context; + acpi_mutex context_mutex; + u8 context_locked; acpi_physical_address address; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); @@ -135,6 +137,8 @@ } context = handler_desc->address_space.context; + context_mutex = handler_desc->address_space.context_mutex; + context_locked = FALSE; /* * It may be the case that the region has never been initialized. @@ -203,6 +207,23 @@ handler = handler_desc->address_space.handler; address = (region_obj->region.address + region_offset); + ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, + "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", + ®ion_obj->region.handler->address_space, handler, + ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(region_obj->region. + space_id))); + + if (!(handler_desc->address_space.handler_flags & + ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + /* + * For handlers other than the default (supplied) handlers, we must + * exit the interpreter because the handler *might* block -- we don't + * know what it will do, so we can't hold the lock on the interpreter. + */ + acpi_ex_exit_interpreter(); + } + /* * Special handling for generic_serial_bus and general_purpose_io: * There are three extra parameters that must be passed to the @@ -211,6 +232,11 @@ * 2) Length of the above buffer * 3) Actual access length from the access_as() op * + * Since we pass these extra parameters via the context, which is + * shared between threads, we must lock the context to avoid these + * parameters being changed from another thread before the handler + * has completed running. + * * In addition, for general_purpose_io, the Address and bit_width fields * are defined as follows: * 1) Address is the pin number index of the field (bit offset from @@ -220,6 +246,14 @@ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && context && field_obj) { + status = + acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE(status)) { + goto re_enter_interpreter; + } + + context_locked = TRUE; + /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; @@ -229,6 +263,14 @@ if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && context && field_obj) { + status = + acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE(status)) { + goto re_enter_interpreter; + } + + context_locked = TRUE; + /* Get the Connection (resource_template) buffer */ context->connection = field_obj->field.resource_buffer; @@ -238,28 +280,15 @@ bit_width = field_obj->field.bit_length; } - ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, - "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", - ®ion_obj->region.handler->address_space, handler, - ACPI_FORMAT_UINT64(address), - acpi_ut_get_region_name(region_obj->region. - space_id))); - - if (!(handler_desc->address_space.handler_flags & - ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { - /* - * For handlers other than the default (supplied) handlers, we must - * exit the interpreter because the handler *might* block -- we don't - * know what it will do, so we can't hold the lock on the interpreter. - */ - acpi_ex_exit_interpreter(); - } - /* Call the handler */ status = handler(function, address, bit_width, value, context, region_obj2->extra.region_context); + if (context_locked) { + acpi_os_release_mutex(context_mutex); + } + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. @@ -276,6 +305,7 @@ } } +re_enter_interpreter: if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/evxfgpe.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/evxfgpe.c @@ -795,6 +795,45 @@ ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes) +/****************************************************************************** + * + * FUNCTION: acpi_any_gpe_status_set + * + * PARAMETERS: gpe_skip_number - Number of the GPE to skip + * + * RETURN: Whether or not the status bit is set for any GPE + * + * DESCRIPTION: Check the status bits of all enabled GPEs, except for the one + * represented by the "skip" argument, and return TRUE if any of + * them is set or FALSE otherwise. + * + ******************************************************************************/ +u32 acpi_any_gpe_status_set(u32 gpe_skip_number) +{ + acpi_status status; + acpi_handle gpe_device; + u8 ret; + + ACPI_FUNCTION_TRACE(acpi_any_gpe_status_set); + + status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); + if (ACPI_FAILURE(status)) { + return (FALSE); + } + + status = acpi_get_gpe_device(gpe_skip_number, &gpe_device); + if (ACPI_FAILURE(status)) { + gpe_device = NULL; + } + + ret = acpi_hw_check_all_gpes(gpe_device, gpe_skip_number); + (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + + return (ret); +} + +ACPI_EXPORT_SYMBOL(acpi_any_gpe_status_set) + /******************************************************************************* * * FUNCTION: acpi_install_gpe_block --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/exfield.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/exfield.c @@ -320,12 +320,7 @@ obj_desc->field.base_byte_offset, source_desc->buffer.pointer, data_length); - if ((obj_desc->field.region_obj->region.address == - PCC_MASTER_SUBSPACE - && MASTER_SUBSPACE_COMMAND(obj_desc->field. - base_byte_offset)) - || GENERIC_SUBSPACE_COMMAND(obj_desc->field. - base_byte_offset)) { + if (MASTER_SUBSPACE_COMMAND(obj_desc->field.base_byte_offset)) { /* Perform the write */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/exoparg1.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/exoparg1.c @@ -1007,7 +1007,8 @@ (walk_state, return_desc, &temp_desc); if (ACPI_FAILURE(status)) { - goto cleanup; + return_ACPI_STATUS + (status); } return_desc = temp_desc; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/exprep.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/exprep.c @@ -437,6 +437,9 @@ if (info->connection_node) { second_desc = info->connection_node->object; + if (second_desc == NULL) { + break; + } if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) { status = acpi_ds_get_buffer_arguments(second_desc); @@ -473,10 +476,6 @@ (u8)access_byte_width; } } - /* An additional reference for the container */ - - acpi_ut_add_reference(obj_desc->field.region_obj); - ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, "RegionField: BitOff %X, Off %X, Gran %X, Region %p\n", obj_desc->field.start_field_bit_offset, --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/exregion.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/exregion.c @@ -43,7 +43,6 @@ struct acpi_mem_space_context *mem_info = region_context; u32 length; acpi_size map_length; - acpi_size page_boundary_map_length; #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED u32 remainder; #endif @@ -120,26 +119,8 @@ map_length = (acpi_size) ((mem_info->address + mem_info->length) - address); - /* - * If mapping the entire remaining portion of the region will cross - * a page boundary, just map up to the page boundary, do not cross. - * On some systems, crossing a page boundary while mapping regions - * can cause warnings if the pages have different attributes - * due to resource management. - * - * This has the added benefit of constraining a single mapping to - * one page, which is similar to the original code that used a 4k - * maximum window. - */ - page_boundary_map_length = (acpi_size) - (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address); - if (page_boundary_map_length == 0) { - page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE; - } - - if (map_length > page_boundary_map_length) { - map_length = page_boundary_map_length; - } + if (map_length > ACPI_DEFAULT_PAGE_SIZE) + map_length = ACPI_DEFAULT_PAGE_SIZE; /* Create a new mapping starting at the address given */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/hwesleep.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/hwesleep.c @@ -104,7 +104,9 @@ /* Flush caches, as per ACPI specification */ - ACPI_FLUSH_CPU_CACHE(); + if (sleep_state < ACPI_STATE_S4) { + ACPI_FLUSH_CPU_CACHE(); + } status = acpi_os_enter_sleep(sleep_state, sleep_control, 0); if (status == AE_CTRL_TERMINATE) { @@ -147,17 +149,13 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) { - acpi_status status; u8 sleep_type_value; ACPI_FUNCTION_TRACE(hw_extended_wake_prep); - status = acpi_get_sleep_type_data(ACPI_STATE_S0, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_SUCCESS(status)) { + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { sleep_type_value = - ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) & + ((acpi_gbl_sleep_type_a_s0 << ACPI_X_SLEEP_TYPE_POSITION) & ACPI_X_SLEEP_TYPE_MASK); (void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE), --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/hwgpe.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/hwgpe.c @@ -444,6 +444,65 @@ return (AE_OK); } +struct acpi_gpe_block_status_context { + struct acpi_gpe_register_info *gpe_skip_register_info; + u8 gpe_skip_mask; + u8 retval; +}; + +/****************************************************************************** + * + * FUNCTION: acpi_hw_get_gpe_block_status + * + * PARAMETERS: gpe_xrupt_info - GPE Interrupt info + * gpe_block - Gpe Block info + * context - GPE list walk context data + * + * RETURN: Success + * + * DESCRIPTION: Produce a combined GPE status bits mask for the given block. + * + ******************************************************************************/ + +static acpi_status +acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info, + struct acpi_gpe_block_info *gpe_block, + void *context) +{ + struct acpi_gpe_block_status_context *c = context; + struct acpi_gpe_register_info *gpe_register_info; + u64 in_enable, in_status; + acpi_status status; + u8 ret_mask; + u32 i; + + /* Examine each GPE Register within the block */ + + for (i = 0; i < gpe_block->register_count; i++) { + gpe_register_info = &gpe_block->register_info[i]; + + status = acpi_hw_read(&in_enable, + &gpe_register_info->enable_address); + if (ACPI_FAILURE(status)) { + continue; + } + + status = acpi_hw_read(&in_status, + &gpe_register_info->status_address); + if (ACPI_FAILURE(status)) { + continue; + } + + ret_mask = in_enable & in_status; + if (ret_mask && c->gpe_skip_register_info == gpe_register_info) { + ret_mask &= ~c->gpe_skip_mask; + } + c->retval |= ret_mask; + } + + return (AE_OK); +} + /****************************************************************************** * * FUNCTION: acpi_hw_disable_all_gpes @@ -510,4 +569,45 @@ return_ACPI_STATUS(status); } +/****************************************************************************** + * + * FUNCTION: acpi_hw_check_all_gpes + * + * PARAMETERS: gpe_skip_device - GPE devoce of the GPE to skip + * gpe_skip_number - Number of the GPE to skip + * + * RETURN: Combined status of all GPEs + * + * DESCRIPTION: Check all enabled GPEs in all GPE blocks, except for the one + * represented by the "skip" arguments, and return TRUE if the + * status bit is set for at least one of them of FALSE otherwise. + * + ******************************************************************************/ + +u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number) +{ + struct acpi_gpe_block_status_context context = { + .gpe_skip_register_info = NULL, + .retval = 0, + }; + struct acpi_gpe_event_info *gpe_event_info; + acpi_cpu_flags flags; + + ACPI_FUNCTION_TRACE(acpi_hw_check_all_gpes); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_skip_device, + gpe_skip_number); + if (gpe_event_info) { + context.gpe_skip_register_info = gpe_event_info->register_info; + context.gpe_skip_mask = acpi_hw_get_gpe_register_bit(gpe_event_info); + } + + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + + (void)acpi_ev_walk_gpe_list(acpi_hw_get_gpe_block_status, &context); + return (context.retval != 0); +} + #endif /* !ACPI_REDUCED_HARDWARE */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/hwsleep.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/hwsleep.c @@ -110,7 +110,9 @@ /* Flush caches, as per ACPI specification */ - ACPI_FLUSH_CPU_CACHE(); + if (sleep_state < ACPI_STATE_S4) { + ACPI_FLUSH_CPU_CACHE(); + } status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control); if (status == AE_CTRL_TERMINATE) { @@ -179,7 +181,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) { - acpi_status status; + acpi_status status = AE_OK; struct acpi_bit_register_info *sleep_type_reg_info; struct acpi_bit_register_info *sleep_enable_reg_info; u32 pm1a_control; @@ -192,10 +194,7 @@ * This is unclear from the ACPI Spec, but it is required * by some machines. */ - status = acpi_get_sleep_type_data(ACPI_STATE_S0, - &acpi_gbl_sleep_type_a, - &acpi_gbl_sleep_type_b); - if (ACPI_SUCCESS(status)) { + if (acpi_gbl_sleep_type_a_s0 != ACPI_SLEEP_TYPE_INVALID) { sleep_type_reg_info = acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE); sleep_enable_reg_info = @@ -216,9 +215,9 @@ /* Insert the SLP_TYP bits */ - pm1a_control |= (acpi_gbl_sleep_type_a << + pm1a_control |= (acpi_gbl_sleep_type_a_s0 << sleep_type_reg_info->bit_position); - pm1b_control |= (acpi_gbl_sleep_type_b << + pm1b_control |= (acpi_gbl_sleep_type_b_s0 << sleep_type_reg_info->bit_position); /* Write the control registers and ignore any errors */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/hwvalid.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/hwvalid.c @@ -23,8 +23,8 @@ * * The table is used to implement the Microsoft port access rules that * first appeared in Windows XP. Some ports are always illegal, and some - * ports are only illegal if the BIOS calls _OSI with a win_XP string or - * later (meaning that the BIOS itelf is post-XP.) + * ports are only illegal if the BIOS calls _OSI with nothing newer than + * the specific _OSI strings. * * This provides ACPICA with the desired port protections and * Microsoft compatibility. @@ -145,7 +145,8 @@ /* Port illegality may depend on the _OSI calls made by the BIOS */ - if (acpi_gbl_osi_data >= port_info->osi_dependency) { + if (port_info->osi_dependency == ACPI_ALWAYS_ILLEGAL || + acpi_gbl_osi_data == port_info->osi_dependency) { ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "Denied AML access to port 0x%8.8X%8.8X/%X (%s 0x%.4X-0x%.4X)\n", ACPI_FORMAT_UINT64(address), --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/hwxfsleep.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/hwxfsleep.c @@ -162,8 +162,6 @@ return_ACPI_STATUS(status); } - ACPI_FLUSH_CPU_CACHE(); - status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, (u32)acpi_gbl_FADT.s4_bios_request, 8); @@ -214,6 +212,13 @@ return_ACPI_STATUS(status); } + status = acpi_get_sleep_type_data(ACPI_STATE_S0, + &acpi_gbl_sleep_type_a_s0, + &acpi_gbl_sleep_type_b_s0); + if (ACPI_FAILURE(status)) { + acpi_gbl_sleep_type_a_s0 = ACPI_SLEEP_TYPE_INVALID; + } + /* Execute the _PTS method (Prepare To Sleep) */ arg_list.count = 1; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/nsaccess.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/nsaccess.c @@ -99,13 +99,12 @@ * just create and link the new node(s) here. */ new_node = - ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_namespace_node)); + acpi_ns_create_node(*ACPI_CAST_PTR(u32, init_val->name)); if (!new_node) { status = AE_NO_MEMORY; goto unlock_and_exit; } - ACPI_COPY_NAMESEG(new_node->name.ascii, init_val->name); new_node->descriptor_type = ACPI_DESC_TYPE_NAMED; new_node->type = init_val->type; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/nsnames.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/nsnames.c @@ -13,9 +13,6 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsnames") -/* Local Prototypes */ -static void acpi_ns_normalize_pathname(char *original_path); - /******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname @@ -30,7 +27,6 @@ * for error and debug statements. * ******************************************************************************/ - char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) { char *name_buffer; @@ -411,7 +407,7 @@ * ******************************************************************************/ -static void acpi_ns_normalize_pathname(char *original_path) +void acpi_ns_normalize_pathname(char *original_path) { char *input_path = original_path; char *new_path_buffer; --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/nsrepair.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/nsrepair.c @@ -181,8 +181,9 @@ * Try to fix if there was no return object. Warning if failed to fix. */ if (!return_object) { - if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) { - if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { + if (expected_btypes) { + if (!(expected_btypes & ACPI_RTYPE_NONE) && + package_index != ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, ACPI_WARN_ALWAYS, @@ -196,14 +197,15 @@ if (ACPI_SUCCESS(status)) { return (AE_OK); /* Repair was successful */ } - } else { + } + + if (expected_btypes != ACPI_RTYPE_NONE) { ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, ACPI_WARN_ALWAYS, "Missing expected return value")); + return (AE_AML_NO_RETURN_VALUE); } - - return (AE_AML_NO_RETURN_VALUE); } } --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/nswalk.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/nswalk.c @@ -169,6 +169,9 @@ if (start_node == ACPI_ROOT_OBJECT) { start_node = acpi_gbl_root_node; + if (!start_node) { + return_ACPI_STATUS(AE_NO_NAMESPACE); + } } /* Null child means "get first node" */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/psargs.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/psargs.c @@ -25,6 +25,8 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state *parser_state); +static void acpi_ps_free_field_list(union acpi_parse_object *start); + /******************************************************************************* * * FUNCTION: acpi_ps_get_next_package_length @@ -685,6 +687,39 @@ /******************************************************************************* * + * FUNCTION: acpi_ps_free_field_list + * + * PARAMETERS: start - First Op in field list + * + * RETURN: None. + * + * DESCRIPTION: Free all Op objects inside a field list. + * + ******************************************************************************/ + +static void acpi_ps_free_field_list(union acpi_parse_object *start) +{ + union acpi_parse_object *cur = start; + union acpi_parse_object *next; + union acpi_parse_object *arg; + + while (cur) { + next = cur->common.next; + + /* AML_INT_CONNECTION_OP can have a single argument */ + + arg = acpi_ps_get_arg(cur, 0); + if (arg) { + acpi_ps_free_op(arg); + } + + acpi_ps_free_op(cur); + cur = next; + } +} + +/******************************************************************************* + * * FUNCTION: acpi_ps_get_next_arg * * PARAMETERS: walk_state - Current state @@ -751,6 +786,10 @@ while (parser_state->aml < parser_state->pkg_end) { field = acpi_ps_get_next_field(parser_state); if (!field) { + if (arg) { + acpi_ps_free_field_list(arg); + } + return_ACPI_STATUS(AE_NO_MEMORY); } @@ -820,6 +859,10 @@ acpi_ps_get_next_namepath(walk_state, parser_state, arg, ACPI_NOT_METHOD_CALL); + if (ACPI_FAILURE(status)) { + acpi_ps_free_op(arg); + return_ACPI_STATUS(status); + } } else { /* Single complex argument, nothing returned */ @@ -854,6 +897,10 @@ acpi_ps_get_next_namepath(walk_state, parser_state, arg, ACPI_POSSIBLE_METHOD_CALL); + if (ACPI_FAILURE(status)) { + acpi_ps_free_op(arg); + return_ACPI_STATUS(status); + } if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) { --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/psopcode.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/psopcode.c @@ -603,7 +603,7 @@ /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, - AML_FLAGS_EXEC_0A_0T_1R), + AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE), /* ACPI 5.0 opcodes */ --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/utcopy.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/utcopy.c @@ -916,13 +916,6 @@ status = acpi_ut_walk_package_tree(source_obj, dest_obj, acpi_ut_copy_ielement_to_ielement, walk_state); - if (ACPI_FAILURE(status)) { - - /* On failure, delete the destination package object */ - - acpi_ut_remove_reference(dest_obj); - } - return_ACPI_STATUS(status); } --- linux-oracle-5.4.0.orig/drivers/acpi/acpica/utdelete.c +++ linux-oracle-5.4.0/drivers/acpi/acpica/utdelete.c @@ -285,6 +285,14 @@ } break; + case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: + + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, + "***** Address handler %p\n", object)); + + acpi_os_delete_mutex(object->address_space.context_mutex); + break; + default: break; @@ -414,6 +422,7 @@ ACPI_WARNING((AE_INFO, "Obj %p, Reference Count is already zero, cannot decrement\n", object)); + return; } ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS, @@ -452,13 +461,13 @@ * * FUNCTION: acpi_ut_update_object_reference * - * PARAMETERS: object - Increment ref count for this object - * and all sub-objects + * PARAMETERS: object - Increment or decrement the ref count for + * this object and all sub-objects * action - Either REF_INCREMENT or REF_DECREMENT * * RETURN: Status * - * DESCRIPTION: Increment the object reference count + * DESCRIPTION: Increment or decrement the object reference count * * Object references are incremented when: * 1) An object is attached to a Node (namespace object) @@ -492,7 +501,7 @@ } /* - * All sub-objects must have their reference count incremented + * All sub-objects must have their reference count updated * also. Different object types have different subobjects. */ switch (object->common.type) { @@ -559,6 +568,7 @@ break; } } + next_object = NULL; break; @@ -567,11 +577,6 @@ next_object = object->buffer_field.buffer_obj; break; - case ACPI_TYPE_LOCAL_REGION_FIELD: - - next_object = object->field.region_obj; - break; - case ACPI_TYPE_LOCAL_BANK_FIELD: next_object = object->bank_field.bank_obj; @@ -612,6 +617,7 @@ } break; + case ACPI_TYPE_LOCAL_REGION_FIELD: case ACPI_TYPE_REGION: default: --- linux-oracle-5.4.0.orig/drivers/acpi/apei/bert.c +++ linux-oracle-5.4.0/drivers/acpi/apei/bert.c @@ -30,14 +30,25 @@ #undef pr_fmt #define pr_fmt(fmt) "BERT: " fmt +#define ACPI_BERT_PRINT_MAX_RECORDS 5 +#define ACPI_BERT_PRINT_MAX_LEN 1024 + static int bert_disable; +/* + * Print "all" the error records in the BERT table, but avoid huge spam to + * the console if the BIOS included oversize records, or too many records. + * Skipping some records here does not lose anything because the full + * data is available to user tools in: + * /sys/firmware/acpi/tables/data/BERT + */ static void __init bert_print_all(struct acpi_bert_region *region, unsigned int region_len) { struct acpi_hest_generic_status *estatus = (struct acpi_hest_generic_status *)region; int remain = region_len; + int printed = 0, skipped = 0; u32 estatus_len; while (remain >= sizeof(struct acpi_bert_region)) { @@ -45,21 +56,26 @@ if (remain < estatus_len) { pr_err(FW_BUG "Truncated status block (length: %u).\n", estatus_len); - return; + break; } /* No more error records. */ if (!estatus->block_status) - return; + break; if (cper_estatus_check(estatus)) { pr_err(FW_BUG "Invalid error record.\n"); - return; + break; } - pr_info_once("Error records from previous boot:\n"); - - cper_estatus_print(KERN_INFO HW_ERR, estatus); + if (estatus_len < ACPI_BERT_PRINT_MAX_LEN && + printed < ACPI_BERT_PRINT_MAX_RECORDS) { + pr_info_once("Error records from previous boot:\n"); + cper_estatus_print(KERN_INFO HW_ERR, estatus); + printed++; + } else { + skipped++; + } /* * Because the boot error source is "one-time polled" type, @@ -71,13 +87,16 @@ estatus = (void *)estatus + estatus_len; remain -= estatus_len; } + + if (skipped) + pr_info(HW_ERR "Skipped %d error records\n", skipped); } static int __init setup_bert_disable(char *str) { bert_disable = 1; - return 0; + return 1; } __setup("bert_disable", setup_bert_disable); --- linux-oracle-5.4.0.orig/drivers/acpi/apei/erst.c +++ linux-oracle-5.4.0/drivers/acpi/apei/erst.c @@ -891,7 +891,7 @@ static int __init setup_erst_disable(char *str) { erst_disable = 1; - return 0; + return 1; } __setup("erst_disable", setup_erst_disable); --- linux-oracle-5.4.0.orig/drivers/acpi/apei/ghes.c +++ linux-oracle-5.4.0/drivers/acpi/apei/ghes.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -128,8 +129,6 @@ static struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; static atomic_t ghes_estatus_cache_alloced; -static int ghes_panic_timeout __read_mostly = 30; - static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx) { phys_addr_t paddr; @@ -171,7 +170,7 @@ * New allocation must be visible in all pgd before it can be found by * an NMI allocating from the pool. */ - vmalloc_sync_all(); + vmalloc_sync_mappings(); rc = gen_pool_add(ghes_estatus_pool, addr, PAGE_ALIGN(len), -1); if (rc) @@ -414,23 +413,46 @@ ghes_ack_error(ghes->generic_v2); } -static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) +/* + * Called as task_work before returning to user-space. + * Ensure any queued work has been done before we return to the context that + * triggered the notification. + */ +static void ghes_kick_task_work(struct callback_head *head) +{ + struct acpi_hest_generic_status *estatus; + struct ghes_estatus_node *estatus_node; + u32 node_len; + + estatus_node = container_of(head, struct ghes_estatus_node, task_work); + if (IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE)) + memory_failure_queue_kick(estatus_node->task_work_cpu); + + estatus = GHES_ESTATUS_FROM_NODE(estatus_node); + node_len = GHES_ESTATUS_NODE_LEN(cper_estatus_len(estatus)); + gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len); +} + +static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + int sev) { -#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE unsigned long pfn; int flags = -1; int sec_sev = ghes_severity(gdata->error_severity); struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); + if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE)) + return false; + if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) - return; + return false; pfn = mem_err->physical_addr >> PAGE_SHIFT; if (!pfn_valid(pfn)) { pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid address in generic error data: %#llx\n", mem_err->physical_addr); - return; + return false; } /* iff following two events can be handled properly by now */ @@ -440,9 +462,12 @@ if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) flags = 0; - if (flags != -1) + if (flags != -1) { memory_failure_queue(pfn, flags); -#endif + return true; + } + + return false; } /* @@ -490,7 +515,7 @@ #endif } -static void ghes_do_proc(struct ghes *ghes, +static bool ghes_do_proc(struct ghes *ghes, const struct acpi_hest_generic_status *estatus) { int sev, sec_sev; @@ -498,6 +523,7 @@ guid_t *sec_type; const guid_t *fru_id = &guid_null; char *fru_text = ""; + bool queued = false; sev = ghes_severity(estatus->error_severity); apei_estatus_for_each_section(estatus, gdata) { @@ -515,7 +541,7 @@ ghes_edac_report_mem_error(sev, mem_err); arch_apei_report_mem_error(sev, mem_err); - ghes_handle_memory_failure(gdata, sev); + queued = ghes_handle_memory_failure(gdata, sev); } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ghes_handle_aer(gdata); @@ -532,6 +558,8 @@ gdata->error_data_length); } } + + return queued; } static void __ghes_print_estatus(const char *pfx, @@ -707,14 +735,16 @@ struct acpi_hest_generic_status *estatus, u64 buf_paddr, enum fixed_addresses fixmap_idx) { + const char *msg = GHES_PFX "Fatal hardware error"; + __ghes_print_estatus(KERN_EMERG, ghes->generic, estatus); ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx); - /* reboot to log the error! */ if (!panic_timeout) - panic_timeout = ghes_panic_timeout; - panic("Fatal hardware error!"); + pr_emerg("%s but panic disabled\n", msg); + + panic(msg); } static int ghes_proc(struct ghes *ghes) @@ -827,7 +857,9 @@ struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; struct acpi_hest_generic_status *estatus; + bool task_work_pending; u32 len, node_len; + int ret; llnode = llist_del_all(&ghes_estatus_llist); /* @@ -842,14 +874,26 @@ estatus = GHES_ESTATUS_FROM_NODE(estatus_node); len = cper_estatus_len(estatus); node_len = GHES_ESTATUS_NODE_LEN(len); - ghes_do_proc(estatus_node->ghes, estatus); + task_work_pending = ghes_do_proc(estatus_node->ghes, estatus); if (!ghes_estatus_cached(estatus)) { generic = estatus_node->generic; if (ghes_print_estatus(NULL, generic, estatus)) ghes_estatus_cache_add(generic, estatus); } - gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, - node_len); + + if (task_work_pending && current->mm != &init_mm) { + estatus_node->task_work.func = ghes_kick_task_work; + estatus_node->task_work_cpu = smp_processor_id(); + ret = task_work_add(current, &estatus_node->task_work, + true); + if (ret) + estatus_node->task_work.func = NULL; + } + + if (!estatus_node->task_work.func) + gen_pool_free(ghes_estatus_pool, + (unsigned long)estatus_node, node_len); + llnode = next; } } @@ -909,6 +953,7 @@ estatus_node->ghes = ghes; estatus_node->generic = ghes->generic; + estatus_node->task_work.func = NULL; estatus = GHES_ESTATUS_FROM_NODE(estatus_node); if (__ghes_read_estatus(estatus, buf_paddr, fixmap_idx, len)) { --- linux-oracle-5.4.0.orig/drivers/acpi/apei/hest.c +++ linux-oracle-5.4.0/drivers/acpi/apei/hest.c @@ -219,7 +219,7 @@ static int __init setup_hest_disable(char *str) { hest_disable = HEST_DISABLED; - return 0; + return 1; } __setup("hest_disable", setup_hest_disable); --- linux-oracle-5.4.0.orig/drivers/acpi/arm64/gtdt.c +++ linux-oracle-5.4.0/drivers/acpi/arm64/gtdt.c @@ -36,7 +36,7 @@ static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata; -static inline void *next_platform_timer(void *platform_timer) +static inline __init void *next_platform_timer(void *platform_timer) { struct acpi_gtdt_header *gh = platform_timer; @@ -283,7 +283,7 @@ if (frame->virt_irq > 0) acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt); frame->virt_irq = 0; - } while (i-- >= 0 && gtdt_frame--); + } while (i-- > 0 && gtdt_frame--); return -EINVAL; } @@ -329,7 +329,7 @@ int index) { struct platform_device *pdev; - int irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags); + int irq; /* * According to SBSA specification the size of refresh and control @@ -338,7 +338,7 @@ struct resource res[] = { DEFINE_RES_MEM(wd->control_frame_address, SZ_4K), DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K), - DEFINE_RES_IRQ(irq), + {}, }; int nr_res = ARRAY_SIZE(res); @@ -348,10 +348,11 @@ if (!(wd->refresh_frame_address && wd->control_frame_address)) { pr_err(FW_BUG "failed to get the Watchdog base address.\n"); - acpi_unregister_gsi(wd->timer_interrupt); return -EINVAL; } + irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags); + res[2] = (struct resource)DEFINE_RES_IRQ(irq); if (irq <= 0) { pr_warn("failed to map the Watchdog interrupt.\n"); nr_res--; @@ -364,7 +365,8 @@ */ pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res); if (IS_ERR(pdev)) { - acpi_unregister_gsi(wd->timer_interrupt); + if (irq > 0) + acpi_unregister_gsi(wd->timer_interrupt); return PTR_ERR(pdev); } --- linux-oracle-5.4.0.orig/drivers/acpi/arm64/iort.c +++ linux-oracle-5.4.0/drivers/acpi/arm64/iort.c @@ -361,6 +361,7 @@ static int iort_get_id_mapping_index(struct acpi_iort_node *node) { struct acpi_iort_smmu_v3 *smmu; + struct acpi_iort_pmcg *pmcg; switch (node->type) { case ACPI_IORT_NODE_SMMU_V3: @@ -388,6 +389,10 @@ return smmu->id_mapping_index; case ACPI_IORT_NODE_PMCG: + pmcg = (struct acpi_iort_pmcg *)node->node_data; + if (pmcg->overflow_gsiv || node->mapping_count == 0) + return -EINVAL; + return 0; default: return -EINVAL; @@ -498,7 +503,6 @@ node = iort_get_iort_node(dev->fwnode); if (node) return node; - /* * if not, then it should be a platform device defined in * DSDT/SSDT (with Named Component node in IORT) @@ -517,22 +521,22 @@ } /** - * iort_msi_map_rid() - Map a MSI requester ID for a device + * iort_msi_map_id() - Map a MSI input ID for a device * @dev: The device for which the mapping is to be done. - * @req_id: The device requester ID. + * @input_id: The device input ID. * - * Returns: mapped MSI RID on success, input requester ID otherwise + * Returns: mapped MSI ID on success, input ID otherwise */ -u32 iort_msi_map_rid(struct device *dev, u32 req_id) +u32 iort_msi_map_id(struct device *dev, u32 input_id) { struct acpi_iort_node *node; u32 dev_id; node = iort_find_dev_node(dev); if (!node) - return req_id; + return input_id; - iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE); + iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE); return dev_id; } @@ -589,13 +593,13 @@ /** * iort_dev_find_its_id() - Find the ITS identifier for a device * @dev: The device. - * @req_id: Device's requester ID + * @id: Device's ID * @idx: Index of the ITS identifier list. * @its_id: ITS identifier. * * Returns: 0 on success, appropriate error value otherwise */ -static int iort_dev_find_its_id(struct device *dev, u32 req_id, +static int iort_dev_find_its_id(struct device *dev, u32 id, unsigned int idx, int *its_id) { struct acpi_iort_its_group *its; @@ -605,7 +609,7 @@ if (!node) return -ENXIO; - node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE); + node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE); if (!node) return -ENXIO; @@ -628,19 +632,20 @@ * * Returns: the MSI domain for this device, NULL otherwise */ -struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) +struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, + enum irq_domain_bus_token bus_token) { struct fwnode_handle *handle; int its_id; - if (iort_dev_find_its_id(dev, req_id, 0, &its_id)) + if (iort_dev_find_its_id(dev, id, 0, &its_id)) return NULL; handle = iort_find_domain_token(its_id); if (!handle) return NULL; - return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); + return irq_find_matching_fwnode(handle, bus_token); } static void iort_set_device_domain(struct device *dev, @@ -1368,9 +1373,17 @@ res[0].start = pmcg->page0_base_address; res[0].end = pmcg->page0_base_address + SZ_4K - 1; res[0].flags = IORESOURCE_MEM; - res[1].start = pmcg->page1_base_address; - res[1].end = pmcg->page1_base_address + SZ_4K - 1; - res[1].flags = IORESOURCE_MEM; + /* + * The initial version in DEN0049C lacked a way to describe register + * page 1, which makes it broken for most PMCG implementations; in + * that case, just let the driver fail gracefully if it expects to + * find a second memory resource. + */ + if (node->revision > 0) { + res[1].start = pmcg->page1_base_address; + res[1].end = pmcg->page1_base_address + SZ_4K - 1; + res[1].flags = IORESOURCE_MEM; + } if (pmcg->overflow_gsiv) acpi_iort_register_irq(pmcg->overflow_gsiv, "overflow", @@ -1380,7 +1393,10 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = { /* HiSilicon Hip08 Platform */ {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal, - "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08}, + "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08}, + /* HiSilicon Hip09 Platform */ + {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, { } }; --- linux-oracle-5.4.0.orig/drivers/acpi/battery.c +++ linux-oracle-5.4.0/drivers/acpi/battery.c @@ -38,6 +38,8 @@ #define PREFIX "ACPI: " #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF +#define ACPI_BATTERY_CAPACITY_VALID(capacity) \ + ((capacity) != 0 && (capacity) != ACPI_BATTERY_VALUE_UNKNOWN) #define ACPI_BATTERY_DEVICE_NAME "Battery" @@ -63,6 +65,7 @@ static int battery_notification_delay_ms; static int battery_ac_is_broken; static int battery_check_pmic = 1; +static int battery_quirk_notcharging; static unsigned int cache_time = 1000; module_param(cache_time, uint, 0644); MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); @@ -74,6 +77,10 @@ static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A", 0}, + + /* Microsoft Surface Go 3 */ + {"MSHW0146", 0}, + {"", 0}, }; @@ -183,7 +190,7 @@ return 1; /* fallback to using design values for broken batteries */ - if (battery->design_capacity == battery->capacity_now) + if (battery->design_capacity <= battery->capacity_now) return 1; /* we don't do any sort of metric based on percentages */ @@ -192,7 +199,8 @@ static bool acpi_battery_is_degraded(struct acpi_battery *battery) { - return battery->full_charge_capacity && battery->design_capacity && + return ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && + ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity) && battery->full_charge_capacity < battery->design_capacity; } @@ -214,7 +222,7 @@ enum power_supply_property psp, union power_supply_propval *val) { - int ret = 0; + int full_capacity = ACPI_BATTERY_VALUE_UNKNOWN, ret = 0; struct acpi_battery *battery = to_acpi_battery(psy); if (acpi_battery_present(battery)) { @@ -230,6 +238,8 @@ val->intval = POWER_SUPPLY_STATUS_CHARGING; else if (acpi_battery_is_charged(battery)) val->intval = POWER_SUPPLY_STATUS_FULL; + else if (battery_quirk_notcharging) + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; else val->intval = POWER_SUPPLY_STATUS_UNKNOWN; break; @@ -263,14 +273,14 @@ break; case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: - if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + if (!ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) ret = -ENODEV; else val->intval = battery->design_capacity * 1000; break; case POWER_SUPPLY_PROP_CHARGE_FULL: case POWER_SUPPLY_PROP_ENERGY_FULL: - if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) ret = -ENODEV; else val->intval = battery->full_charge_capacity * 1000; @@ -283,11 +293,17 @@ val->intval = battery->capacity_now * 1000; break; case POWER_SUPPLY_PROP_CAPACITY: - if (battery->capacity_now && battery->full_charge_capacity) - val->intval = battery->capacity_now * 100/ - battery->full_charge_capacity; + if (ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity)) + full_capacity = battery->full_charge_capacity; + else if (ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) + full_capacity = battery->design_capacity; + + if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN || + full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + ret = -ENODEV; else - val->intval = 0; + val->intval = battery->capacity_now * 100/ + full_capacity; break; case POWER_SUPPLY_PROP_CAPACITY_LEVEL: if (battery->state & ACPI_BATTERY_STATE_CRITICAL) @@ -333,6 +349,20 @@ POWER_SUPPLY_PROP_SERIAL_NUMBER, }; +static enum power_supply_property charge_battery_full_cap_broken_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_CYCLE_COUNT, + POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_CHARGE_NOW, + POWER_SUPPLY_PROP_MODEL_NAME, + POWER_SUPPLY_PROP_MANUFACTURER, + POWER_SUPPLY_PROP_SERIAL_NUMBER, +}; + static enum power_supply_property energy_battery_props[] = { POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_PRESENT, @@ -435,7 +465,7 @@ u8 *ptr = (u8 *)battery + offsets[i].offset; if (element->type == ACPI_TYPE_STRING || element->type == ACPI_TYPE_BUFFER) - strncpy(ptr, element->string.pointer, 32); + strscpy(ptr, element->string.pointer, 32); else if (element->type == ACPI_TYPE_INTEGER) { strncpy(ptr, (u8 *)&element->integer.value, sizeof(u64)); @@ -651,12 +681,18 @@ return count; } -static const struct device_attribute alarm_attr = { +static struct device_attribute alarm_attr = { .attr = {.name = "alarm", .mode = 0644}, .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +static struct attribute *acpi_battery_attrs[] = { + &alarm_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(acpi_battery); + /* * The Battery Hooking API * @@ -670,27 +706,34 @@ static LIST_HEAD(battery_hook_list); static DEFINE_MUTEX(hook_mutex); -static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock) +static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook) { struct acpi_battery *battery; + /* * In order to remove a hook, we first need to * de-register all the batteries that are registered. */ - if (lock) - mutex_lock(&hook_mutex); list_for_each_entry(battery, &acpi_battery_list, list) { hook->remove_battery(battery->bat); } - list_del(&hook->list); - if (lock) - mutex_unlock(&hook_mutex); + list_del_init(&hook->list); + pr_info("extension unregistered: %s\n", hook->name); } void battery_hook_unregister(struct acpi_battery_hook *hook) { - __battery_hook_unregister(hook, 1); + mutex_lock(&hook_mutex); + /* + * Ignore already unregistered battery hooks. This might happen + * if a battery hook was previously unloaded due to an error when + * adding a new battery. + */ + if (!list_empty(&hook->list)) + battery_hook_unregister_unlocked(hook); + + mutex_unlock(&hook_mutex); } EXPORT_SYMBOL_GPL(battery_hook_unregister); @@ -699,7 +742,6 @@ struct acpi_battery *battery; mutex_lock(&hook_mutex); - INIT_LIST_HEAD(&hook->list); list_add(&hook->list, &battery_hook_list); /* * Now that the driver is registered, we need @@ -716,7 +758,7 @@ * hooks. */ pr_err("extension failed to load: %s", hook->name); - __battery_hook_unregister(hook, 0); + battery_hook_unregister_unlocked(hook); goto end; } } @@ -753,7 +795,7 @@ */ pr_err("error in extension, unloading: %s", hook_node->name); - __battery_hook_unregister(hook_node, 0); + battery_hook_unregister_unlocked(hook_node); } } mutex_unlock(&hook_mutex); @@ -786,28 +828,45 @@ * need to remove the hooks. */ list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) { - __battery_hook_unregister(hook, 1); + battery_hook_unregister(hook); } mutex_destroy(&hook_mutex); } static int sysfs_add_battery(struct acpi_battery *battery) { - struct power_supply_config psy_cfg = { .drv_data = battery, }; + struct power_supply_config psy_cfg = { + .drv_data = battery, + .attr_grp = acpi_battery_groups, + }; + bool full_cap_broken = false; + + if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) && + !ACPI_BATTERY_CAPACITY_VALID(battery->design_capacity)) + full_cap_broken = true; if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { - battery->bat_desc.properties = charge_battery_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(charge_battery_props); - } else if (battery->full_charge_capacity == 0) { - battery->bat_desc.properties = - energy_battery_full_cap_broken_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(energy_battery_full_cap_broken_props); + if (full_cap_broken) { + battery->bat_desc.properties = + charge_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_full_cap_broken_props); + } else { + battery->bat_desc.properties = charge_battery_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(charge_battery_props); + } } else { - battery->bat_desc.properties = energy_battery_props; - battery->bat_desc.num_properties = - ARRAY_SIZE(energy_battery_props); + if (full_cap_broken) { + battery->bat_desc.properties = + energy_battery_full_cap_broken_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_full_cap_broken_props); + } else { + battery->bat_desc.properties = energy_battery_props; + battery->bat_desc.num_properties = + ARRAY_SIZE(energy_battery_props); + } } battery->bat_desc.name = acpi_device_bid(battery->device); @@ -824,7 +883,7 @@ return result; } battery_hook_add_battery(battery); - return device_create_file(&battery->bat->dev, &alarm_attr); + return 0; } static void sysfs_remove_battery(struct acpi_battery *battery) @@ -835,7 +894,6 @@ return; } battery_hook_remove_battery(battery); - device_remove_file(&battery->bat->dev, &alarm_attr); power_supply_unregister(battery->bat); battery->bat = NULL; mutex_unlock(&battery->sysfs_lock); @@ -1300,6 +1358,12 @@ return 0; } +static int __init battery_quirk_not_charging(const struct dmi_system_id *d) +{ + battery_quirk_notcharging = 1; + return 0; +} + static const struct dmi_system_id bat_dmi_table[] __initconst = { { /* NEC LZ750/LS */ @@ -1344,6 +1408,27 @@ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), }, }, + { + /* + * On Lenovo ThinkPads the BIOS specification defines + * a state when the bits for charging and discharging + * are both set to 0. That state is "Not Charging". + */ + .callback = battery_quirk_not_charging, + .ident = "Lenovo ThinkPad", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), + }, + }, + { + /* Microsoft Surface Go 3 */ + .callback = battery_notification_delay_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"), + }, + }, {}, }; --- linux-oracle-5.4.0.orig/drivers/acpi/bgrt.c +++ linux-oracle-5.4.0/drivers/acpi/bgrt.c @@ -15,40 +15,19 @@ static void *bgrt_image; static struct kobject *bgrt_kobj; -static ssize_t show_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version); -} -static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); - -static ssize_t show_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status); -} -static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); - -static ssize_t show_type(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type); -} -static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); - -static ssize_t show_xoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x); -} -static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); - -static ssize_t show_yoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y); -} -static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); +#define BGRT_SHOW(_name, _member) \ + static ssize_t _name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab._member); \ + } \ + struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) + +BGRT_SHOW(version, version); +BGRT_SHOW(status, status); +BGRT_SHOW(type, image_type); +BGRT_SHOW(xoffset, image_offset_x); +BGRT_SHOW(yoffset, image_offset_y); static ssize_t image_read(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -60,11 +39,11 @@ static BIN_ATTR_RO(image, 0); /* size gets filled in later */ static struct attribute *bgrt_attributes[] = { - &dev_attr_version.attr, - &dev_attr_status.attr, - &dev_attr_type.attr, - &dev_attr_xoffset.attr, - &dev_attr_yoffset.attr, + &bgrt_attr_version.attr, + &bgrt_attr_status.attr, + &bgrt_attr_type.attr, + &bgrt_attr_xoffset.attr, + &bgrt_attr_yoffset.attr, NULL, }; --- linux-oracle-5.4.0.orig/drivers/acpi/bus.c +++ linux-oracle-5.4.0/drivers/acpi/bus.c @@ -153,7 +153,7 @@ { acpi_status status; - if (!*data) + if (!data) return -EINVAL; status = acpi_get_data(handle, acpi_bus_private_data_handler, data); @@ -1240,6 +1240,7 @@ result = acpi_bus_init(); if (result) { + kobject_put(acpi_kobj); disable_acpi(); return result; } --- linux-oracle-5.4.0.orig/drivers/acpi/button.c +++ linux-oracle-5.4.0/drivers/acpi/button.c @@ -78,6 +78,50 @@ DMI_MATCH(DMI_BIOS_VERSION, "BYT70A.YNCHENG.WIN.007"), }, }, + { + /* + * Medion Akoya E2215T, notification of the LID device only + * happens on close, not on open and _LID always returns closed. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E2215T"), + }, + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, + }, + { + /* + * Medion Akoya E2228T, notification of the LID device only + * happens on close, not on open and _LID always returns closed. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E2228T"), + }, + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, + }, + { + /* + * Razer Blade Stealth 13 late 2019, notification of the LID device + * only happens on close, not on open and _LID always returns closed. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Razer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Razer Blade Stealth 13 Late 2019"), + }, + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, + }, + { + /* + * Samsung galaxybook2 ,initial _LID device notification returns + * lid closed. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "750XED"), + }, + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, + }, {} }; @@ -114,6 +158,7 @@ int last_state; ktime_t last_time; bool suspended; + bool lid_state_initialized; }; static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); @@ -369,6 +414,8 @@ static void acpi_lid_initialize_state(struct acpi_device *device) { + struct acpi_button *button = acpi_driver_data(device); + switch (lid_init_state) { case ACPI_BUTTON_LID_INIT_OPEN: (void)acpi_lid_notify_state(device, 1); @@ -380,13 +427,14 @@ default: break; } + + button->lid_state_initialized = true; } static void acpi_button_notify(struct acpi_device *device, u32 event) { struct acpi_button *button = acpi_driver_data(device); struct input_dev *input; - int users; switch (event) { case ACPI_FIXED_HARDWARE_EVENT: @@ -395,10 +443,7 @@ case ACPI_BUTTON_NOTIFY_STATUS: input = button->input; if (button->type == ACPI_BUTTON_TYPE_LID) { - mutex_lock(&button->input->mutex); - users = button->input->users; - mutex_unlock(&button->input->mutex); - if (users) + if (button->lid_state_initialized) acpi_lid_update_state(device, true); } else { int keycode; @@ -443,7 +488,7 @@ struct acpi_button *button = acpi_driver_data(device); button->suspended = false; - if (button->type == ACPI_BUTTON_TYPE_LID && button->input->users) { + if (button->type == ACPI_BUTTON_TYPE_LID) { button->last_state = !!acpi_lid_evaluate_state(device); button->last_time = ktime_get(); acpi_lid_initialize_state(device); --- linux-oracle-5.4.0.orig/drivers/acpi/cppc_acpi.c +++ linux-oracle-5.4.0/drivers/acpi/cppc_acpi.c @@ -118,23 +118,15 @@ */ #define NUM_RETRIES 500ULL -struct cppc_attr { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, - struct attribute *attr, char *buf); - ssize_t (*store)(struct kobject *kobj, - struct attribute *attr, const char *c, ssize_t count); -}; - #define define_one_cppc_ro(_name) \ -static struct cppc_attr _name = \ +static struct kobj_attribute _name = \ __ATTR(_name, 0444, show_##_name, NULL) #define to_cpc_desc(a) container_of(a, struct cpc_desc, kobj) #define show_cppc_data(access_fn, struct_name, member_name) \ static ssize_t show_##member_name(struct kobject *kobj, \ - struct attribute *attr, char *buf) \ + struct kobj_attribute *attr, char *buf) \ { \ struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); \ struct struct_name st_name = {0}; \ @@ -160,7 +152,7 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); static ssize_t show_feedback_ctrs(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { struct cpc_desc *cpc_ptr = to_cpc_desc(kobj); struct cppc_perf_fb_ctrs fb_ctrs = {0}; @@ -634,33 +626,6 @@ return 0; } -/* Check if CPPC revision + num_ent combination is supported */ -static bool is_cppc_supported(int revision, int num_ent) -{ - int expected_num_ent; - - switch (revision) { - case CPPC_V2_REV: - expected_num_ent = CPPC_V2_NUM_ENT; - break; - case CPPC_V3_REV: - expected_num_ent = CPPC_V3_NUM_ENT; - break; - default: - pr_debug("Firmware exports unsupported CPPC revision: %d\n", - revision); - return false; - } - - if (expected_num_ent != num_ent) { - pr_debug("Firmware exports %d entries. Expected: %d for CPPC rev:%d\n", - num_ent, expected_num_ent, revision); - return false; - } - - return true; -} - /* * An example CPC table looks like the following. * @@ -746,12 +711,16 @@ cpc_obj = &out_obj->package.elements[0]; if (cpc_obj->type == ACPI_TYPE_INTEGER) { num_ent = cpc_obj->integer.value; + if (num_ent <= 1) { + pr_debug("Unexpected _CPC NumEntries value (%d) for CPU:%d\n", + num_ent, pr->id); + goto out_free; + } } else { pr_debug("Unexpected entry type(%d) for NumEntries\n", cpc_obj->type); goto out_free; } - cpc_ptr->num_entries = num_ent; /* Second entry should be revision. */ cpc_obj = &out_obj->package.elements[1]; @@ -762,10 +731,32 @@ cpc_obj->type); goto out_free; } - cpc_ptr->version = cpc_rev; - if (!is_cppc_supported(cpc_rev, num_ent)) + if (cpc_rev < CPPC_V2_REV) { + pr_debug("Unsupported _CPC Revision (%d) for CPU:%d\n", cpc_rev, + pr->id); + goto out_free; + } + + /* + * Disregard _CPC if the number of entries in the return pachage is not + * as expected, but support future revisions being proper supersets of + * the v3 and only causing more entries to be returned by _CPC. + */ + if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) || + (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) || + (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) { + pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n", + num_ent, pr->id); goto out_free; + } + if (cpc_rev > CPPC_V3_REV) { + num_ent = CPPC_V3_NUM_ENT; + cpc_rev = CPPC_V3_REV; + } + + cpc_ptr->num_entries = num_ent; + cpc_ptr->version = cpc_rev; /* Iterate through remaining entries in _CPC */ for (i = 2; i < num_ent; i++) { @@ -865,6 +856,7 @@ "acpi_cppc"); if (ret) { per_cpu(cpc_desc_ptr, pr->id) = NULL; + kobject_put(&cpc_ptr->kobj); goto out_free; } --- linux-oracle-5.4.0.orig/drivers/acpi/custom_method.c +++ linux-oracle-5.4.0/drivers/acpi/custom_method.c @@ -44,6 +44,8 @@ sizeof(struct acpi_table_header))) return -EFAULT; uncopied_bytes = max_size = table.length; + /* make sure the buf is not allocated */ + kfree(buf); buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -57,6 +59,7 @@ (*ppos + count < count) || (count > uncopied_bytes)) { kfree(buf); + buf = NULL; return -EINVAL; } @@ -78,7 +81,6 @@ add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); } - kfree(buf); return count; } --- linux-oracle-5.4.0.orig/drivers/acpi/device_pm.c +++ linux-oracle-5.4.0/drivers/acpi/device_pm.c @@ -186,7 +186,7 @@ * possibly drop references to the power resources in use. */ state = ACPI_STATE_D3_HOT; - /* If _PR3 is not available, use D3hot as the target state. */ + /* If D3cold is not supported, use D3hot as the target state. */ if (!device->power.states[ACPI_STATE_D3_COLD].flags.valid) target_state = state; } else if (!device->power.states[state].flags.valid) { @@ -273,13 +273,13 @@ end: if (result) { dev_warn(&device->dev, "Failed to change power state to %s\n", - acpi_power_state_string(state)); + acpi_power_state_string(target_state)); } else { device->power.state = target_state; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] transitioned to %s\n", device->pnp.bus_id, - acpi_power_state_string(state))); + acpi_power_state_string(target_state))); } return result; @@ -749,7 +749,7 @@ static DEFINE_MUTEX(acpi_wakeup_lock); static int __acpi_device_wakeup_enable(struct acpi_device *adev, - u32 target_state, int max_count) + u32 target_state) { struct acpi_device_wakeup *wakeup = &adev->wakeup; acpi_status status; @@ -757,15 +757,26 @@ mutex_lock(&acpi_wakeup_lock); - if (wakeup->enable_count >= max_count) - goto out; - + /* + * If the device wakeup power is already enabled, disable it and enable + * it again in case it depends on the configuration of subordinate + * devices and the conditions have changed since it was enabled last + * time. + */ if (wakeup->enable_count > 0) - goto inc; + acpi_disable_wakeup_device_power(adev); error = acpi_enable_wakeup_device_power(adev, target_state); - if (error) + if (error) { + if (wakeup->enable_count > 0) { + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + wakeup->enable_count = 0; + } goto out; + } + + if (wakeup->enable_count > 0) + goto inc; status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); if (ACPI_FAILURE(status)) { @@ -778,7 +789,10 @@ (unsigned int)wakeup->gpe_number); inc: - wakeup->enable_count++; + if (wakeup->enable_count < INT_MAX) + wakeup->enable_count++; + else + acpi_handle_info(adev->handle, "Wakeup enable count out of bounds!\n"); out: mutex_unlock(&acpi_wakeup_lock); @@ -799,7 +813,7 @@ */ static int acpi_device_wakeup_enable(struct acpi_device *adev, u32 target_state) { - return __acpi_device_wakeup_enable(adev, target_state, 1); + return __acpi_device_wakeup_enable(adev, target_state); } /** @@ -829,8 +843,12 @@ mutex_unlock(&acpi_wakeup_lock); } -static int __acpi_pm_set_device_wakeup(struct device *dev, bool enable, - int max_count) +/** + * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device. + * @dev: Device to enable/disable to generate wakeup events. + * @enable: Whether to enable or disable the wakeup functionality. + */ +int acpi_pm_set_device_wakeup(struct device *dev, bool enable) { struct acpi_device *adev; int error; @@ -850,37 +868,15 @@ return 0; } - error = __acpi_device_wakeup_enable(adev, acpi_target_system_state(), - max_count); + error = __acpi_device_wakeup_enable(adev, acpi_target_system_state()); if (!error) dev_dbg(dev, "Wakeup enabled by ACPI\n"); return error; } - -/** - * acpi_pm_set_device_wakeup - Enable/disable remote wakeup for given device. - * @dev: Device to enable/disable to generate wakeup events. - * @enable: Whether to enable or disable the wakeup functionality. - */ -int acpi_pm_set_device_wakeup(struct device *dev, bool enable) -{ - return __acpi_pm_set_device_wakeup(dev, enable, 1); -} EXPORT_SYMBOL_GPL(acpi_pm_set_device_wakeup); /** - * acpi_pm_set_bridge_wakeup - Enable/disable remote wakeup for given bridge. - * @dev: Bridge device to enable/disable to generate wakeup events. - * @enable: Whether to enable or disable the wakeup functionality. - */ -int acpi_pm_set_bridge_wakeup(struct device *dev, bool enable) -{ - return __acpi_pm_set_device_wakeup(dev, enable, INT_MAX); -} -EXPORT_SYMBOL_GPL(acpi_pm_set_bridge_wakeup); - -/** * acpi_dev_pm_low_power - Put ACPI device into a low-power state. * @dev: Device to put into a low-power state. * @adev: ACPI device node corresponding to @dev. @@ -1314,9 +1310,19 @@ */ int acpi_dev_pm_attach(struct device *dev, bool power_on) { + /* + * Skip devices whose ACPI companions match the device IDs below, + * because they require special power management handling incompatible + * with the generic ACPI PM domain. + */ + static const struct acpi_device_id special_pm_ids[] = { + {"PNP0C0B", }, /* Generic ACPI fan */ + {"INT3404", }, /* Fan */ + {} + }; struct acpi_device *adev = ACPI_COMPANION(dev); - if (!adev) + if (!adev || !acpi_match_device_ids(adev, special_pm_ids)) return 0; /* --- linux-oracle-5.4.0.orig/drivers/acpi/device_sysfs.c +++ linux-oracle-5.4.0/drivers/acpi/device_sysfs.c @@ -156,8 +156,8 @@ return 0; len = snprintf(modalias, size, "acpi:"); - if (len <= 0) - return len; + if (len >= size) + return -ENOMEM; size -= len; @@ -210,8 +210,10 @@ len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer); ACPI_FREE(buf.pointer); - if (len <= 0) - return len; + if (len >= size) + return -ENOMEM; + + size -= len; of_compatible = acpi_dev->data.of_compatible; if (of_compatible->type == ACPI_TYPE_PACKAGE) { @@ -251,20 +253,12 @@ if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; - len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); - if (len < 0) - return len; - - env->buflen += len; - if (!adev->data.of_compatible) - return 0; - - if (len > 0 && add_uevent_var(env, "MODALIAS=")) - return -ENOMEM; - - len = create_of_modalias(adev, &env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen); + if (adev->data.of_compatible) + len = create_of_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); + else + len = create_pnp_modalias(adev, &env->buf[env->buflen - 1], + sizeof(env->buf) - env->buflen); if (len < 0) return len; @@ -333,11 +327,11 @@ EXPORT_SYMBOL_GPL(acpi_device_modalias); static ssize_t -acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) +modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { return __acpi_device_modalias(to_acpi_device(dev), buf, 1024); } -static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); +static DEVICE_ATTR_RO(modalias); static ssize_t real_power_state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -366,8 +360,8 @@ static DEVICE_ATTR_RO(power_state); static ssize_t -acpi_eject_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t count) +eject_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) { struct acpi_device *acpi_device = to_acpi_device(d); acpi_object_type not_used; @@ -395,28 +389,28 @@ return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; } -static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); +static DEVICE_ATTR_WO(eject); static ssize_t -acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) +hid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); } -static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); +static DEVICE_ATTR_RO(hid); -static ssize_t acpi_device_uid_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uid_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); } -static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); +static DEVICE_ATTR_RO(uid); -static ssize_t acpi_device_adr_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t adr_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -425,16 +419,16 @@ else return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address); } -static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); +static DEVICE_ATTR_RO(adr); -static ssize_t acpi_device_path_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t path_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return acpi_object_path(acpi_dev->handle, buf); } -static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); +static DEVICE_ATTR_RO(path); /* sysfs file that shows description text from the ACPI _STR method */ static ssize_t description_show(struct device *dev, @@ -454,7 +448,7 @@ (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, acpi_dev->pnp.str_obj->buffer.length, UTF16_LITTLE_ENDIAN, buf, - PAGE_SIZE); + PAGE_SIZE - 1); buf[result++] = '\n'; @@ -463,8 +457,8 @@ static DEVICE_ATTR_RO(description); static ssize_t -acpi_device_sun_show(struct device *dev, struct device_attribute *attr, - char *buf) { +sun_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); acpi_status status; unsigned long long sun; @@ -475,11 +469,11 @@ return sprintf(buf, "%llu\n", sun); } -static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); +static DEVICE_ATTR_RO(sun); static ssize_t -acpi_device_hrv_show(struct device *dev, struct device_attribute *attr, - char *buf) { +hrv_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); acpi_status status; unsigned long long hrv; @@ -490,7 +484,7 @@ return sprintf(buf, "%llu\n", hrv); } -static DEVICE_ATTR(hrv, 0444, acpi_device_hrv_show, NULL); +static DEVICE_ATTR_RO(hrv); static ssize_t status_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -539,8 +533,9 @@ * If device has _STR, 'description' file is created */ if (acpi_has_method(dev->handle, "_STR")) { - status = acpi_evaluate_object(dev->handle, "_STR", - NULL, &buffer); + status = acpi_evaluate_object_typed(dev->handle, "_STR", + NULL, &buffer, + ACPI_TYPE_BUFFER); if (ACPI_FAILURE(status)) buffer.pointer = NULL; dev->pnp.str_obj = buffer.pointer; --- linux-oracle-5.4.0.orig/drivers/acpi/dock.c +++ linux-oracle-5.4.0/drivers/acpi/dock.c @@ -485,7 +485,7 @@ /* * show_docked - read method for "docked" file in sysfs */ -static ssize_t show_docked(struct device *dev, +static ssize_t docked_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; @@ -494,25 +494,25 @@ acpi_bus_get_device(dock_station->handle, &adev); return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); } -static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); +static DEVICE_ATTR_RO(docked); /* * show_flags - read method for flags file in sysfs */ -static ssize_t show_flags(struct device *dev, +static ssize_t flags_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); } -static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); +static DEVICE_ATTR_RO(flags); /* * write_undock - write method for "undock" file in sysfs */ -static ssize_t write_undock(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t undock_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int ret; struct dock_station *dock_station = dev->platform_data; @@ -526,13 +526,13 @@ acpi_scan_lock_release(); return ret ? ret: count; } -static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); +static DEVICE_ATTR_WO(undock); /* * show_dock_uid - read method for "uid" file in sysfs */ -static ssize_t show_dock_uid(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uid_show(struct device *dev, + struct device_attribute *attr, char *buf) { unsigned long long lbuf; struct dock_station *dock_station = dev->platform_data; @@ -543,10 +543,10 @@ return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf); } -static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); +static DEVICE_ATTR_RO(uid); -static ssize_t show_dock_type(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; char *type; @@ -562,7 +562,7 @@ return snprintf(buf, PAGE_SIZE, "%s\n", type); } -static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); +static DEVICE_ATTR_RO(type); static struct attribute *dock_attributes[] = { &dev_attr_docked.attr, --- linux-oracle-5.4.0.orig/drivers/acpi/ec.c +++ linux-oracle-5.4.0/drivers/acpi/ec.c @@ -95,12 +95,12 @@ EC_FLAGS_QUERY_ENABLED, /* Query is enabled */ EC_FLAGS_QUERY_PENDING, /* Query is pending */ EC_FLAGS_QUERY_GUARDING, /* Guard for SCI_EVT check */ - EC_FLAGS_GPE_HANDLER_INSTALLED, /* GPE handler installed */ + EC_FLAGS_EVENT_HANDLER_INSTALLED, /* Event handler installed */ EC_FLAGS_EC_HANDLER_INSTALLED, /* OpReg handler installed */ - EC_FLAGS_EVT_HANDLER_INSTALLED, /* _Qxx handlers installed */ + EC_FLAGS_QUERY_METHODS_INSTALLED, /* _Qxx handlers installed */ EC_FLAGS_STARTED, /* Driver is started */ EC_FLAGS_STOPPED, /* Driver is stopped */ - EC_FLAGS_GPE_MASKED, /* GPE masked */ + EC_FLAGS_EVENTS_MASKED, /* Events masked */ }; #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ @@ -167,6 +167,7 @@ struct transaction transaction; struct work_struct work; struct acpi_ec_query_handler *handler; + struct acpi_ec *ec; }; static int acpi_ec_query(struct acpi_ec *ec, u8 *data); @@ -179,6 +180,7 @@ static struct acpi_ec *boot_ec; static bool boot_ec_is_ecdt = false; +static struct workqueue_struct *ec_wq; static struct workqueue_struct *ec_query_wq; static int EC_FLAGS_QUERY_HANDSHAKE; /* Needs QR_EC issued when SCI_EVT set */ @@ -397,8 +399,8 @@ static void acpi_ec_submit_request(struct acpi_ec *ec) { ec->reference_count++; - if (test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags) && - ec->reference_count == 1) + if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags) && + ec->gpe >= 0 && ec->reference_count == 1) acpi_ec_enable_gpe(ec, true); } @@ -407,28 +409,36 @@ bool flushed = false; ec->reference_count--; - if (test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags) && - ec->reference_count == 0) + if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags) && + ec->gpe >= 0 && ec->reference_count == 0) acpi_ec_disable_gpe(ec, true); flushed = acpi_ec_flushed(ec); if (flushed) wake_up(&ec->wait); } -static void acpi_ec_mask_gpe(struct acpi_ec *ec) +static void acpi_ec_mask_events(struct acpi_ec *ec) { - if (!test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) { - acpi_ec_disable_gpe(ec, false); + if (!test_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags)) { + if (ec->gpe >= 0) + acpi_ec_disable_gpe(ec, false); + else + disable_irq_nosync(ec->irq); + ec_dbg_drv("Polling enabled"); - set_bit(EC_FLAGS_GPE_MASKED, &ec->flags); + set_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags); } } -static void acpi_ec_unmask_gpe(struct acpi_ec *ec) +static void acpi_ec_unmask_events(struct acpi_ec *ec) { - if (test_bit(EC_FLAGS_GPE_MASKED, &ec->flags)) { - clear_bit(EC_FLAGS_GPE_MASKED, &ec->flags); - acpi_ec_enable_gpe(ec, false); + if (test_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags)) { + clear_bit(EC_FLAGS_EVENTS_MASKED, &ec->flags); + if (ec->gpe >= 0) + acpi_ec_enable_gpe(ec, false); + else + enable_irq(ec->irq); + ec_dbg_drv("Polling disabled"); } } @@ -454,14 +464,15 @@ static void acpi_ec_submit_query(struct acpi_ec *ec) { - acpi_ec_mask_gpe(ec); + acpi_ec_mask_events(ec); if (!acpi_ec_event_enabled(ec)) return; if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { ec_dbg_evt("Command(%s) submitted/blocked", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); ec->nr_pending_queries++; - schedule_work(&ec->work); + ec->events_in_progress++; + queue_work(ec_wq, &ec->work); } } @@ -470,7 +481,7 @@ if (test_and_clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) ec_dbg_evt("Command(%s) unblocked", acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); - acpi_ec_unmask_gpe(ec); + acpi_ec_unmask_events(ec); } static inline void __acpi_ec_enable_event(struct acpi_ec *ec) @@ -525,26 +536,10 @@ } #ifdef CONFIG_PM_SLEEP -static bool acpi_ec_query_flushed(struct acpi_ec *ec) +static void __acpi_ec_flush_work(void) { - bool flushed; - unsigned long flags; - - spin_lock_irqsave(&ec->lock, flags); - flushed = !ec->nr_pending_queries; - spin_unlock_irqrestore(&ec->lock, flags); - return flushed; -} - -static void __acpi_ec_flush_event(struct acpi_ec *ec) -{ - /* - * When ec_freeze_events is true, we need to flush events in - * the proper position before entering the noirq stage. - */ - wait_event(ec->wait, acpi_ec_query_flushed(ec)); - if (ec_query_wq) - flush_workqueue(ec_query_wq); + flush_workqueue(ec_wq); /* flush ec->work */ + flush_workqueue(ec_query_wq); /* flush queries */ } static void acpi_ec_disable_event(struct acpi_ec *ec) @@ -554,15 +549,21 @@ spin_lock_irqsave(&ec->lock, flags); __acpi_ec_disable_event(ec); spin_unlock_irqrestore(&ec->lock, flags); - __acpi_ec_flush_event(ec); + + /* + * When ec_freeze_events is true, we need to flush events in + * the proper position before entering the noirq stage. + */ + __acpi_ec_flush_work(); } void acpi_ec_flush_work(void) { - if (first_ec) - __acpi_ec_flush_event(first_ec); + /* Without ec_wq there is nothing to flush. */ + if (!ec_wq) + return; - flush_scheduled_work(); + __acpi_ec_flush_work(); } #endif /* CONFIG_PM_SLEEP */ @@ -648,7 +649,9 @@ * ensure a hardware STS 0->1 change after this clearing can always * trigger a GPE interrupt. */ - acpi_ec_clear_gpe(ec); + if (ec->gpe >= 0) + acpi_ec_clear_gpe(ec); + status = acpi_ec_read_status(ec); t = ec->curr; /* @@ -717,7 +720,7 @@ ++t->irq_count; /* Allow triggering on 0 threshold */ if (t->irq_count == ec_storm_threshold) - acpi_ec_mask_gpe(ec); + acpi_ec_mask_events(ec); } } out: @@ -797,6 +800,9 @@ unsigned long tmp; int ret = 0; + if (t->rdata) + memset(t->rdata, 0, t->rlen); + /* start transaction */ spin_lock_irqsave(&ec->lock, tmp); /* Enable GPE for command processing (IBF=0/OBF=1) */ @@ -815,7 +821,7 @@ spin_lock_irqsave(&ec->lock, tmp); if (t->irq_count == ec_storm_threshold) - acpi_ec_unmask_gpe(ec); + acpi_ec_unmask_events(ec); ec_dbg_req("Command(%s) stopped", acpi_ec_cmd_string(t->command)); ec->curr = NULL; /* Disable GPE for command processing (IBF=0/OBF=1) */ @@ -833,8 +839,6 @@ if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata)) return -EINVAL; - if (t->rdata) - memset(t->rdata, 0, t->rlen); mutex_lock(&ec->mutex); if (ec->global_lock) { @@ -861,7 +865,7 @@ .wdata = NULL, .rdata = &d, .wlen = 0, .rlen = 1}; - return acpi_ec_transaction(ec, &t); + return acpi_ec_transaction_unlocked(ec, &t); } static int acpi_ec_burst_disable(struct acpi_ec *ec) @@ -871,7 +875,7 @@ .wlen = 0, .rlen = 0}; return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ? - acpi_ec_transaction(ec, &t) : 0; + acpi_ec_transaction_unlocked(ec, &t) : 0; } static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data) @@ -887,6 +891,19 @@ return result; } +static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data) +{ + int result; + u8 d; + struct transaction t = {.command = ACPI_EC_COMMAND_READ, + .wdata = &address, .rdata = &d, + .wlen = 1, .rlen = 1}; + + result = acpi_ec_transaction_unlocked(ec, &t); + *data = d; + return result; +} + static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data) { u8 wdata[2] = { address, data }; @@ -897,6 +914,16 @@ return acpi_ec_transaction(ec, &t); } +static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data) +{ + u8 wdata[2] = { address, data }; + struct transaction t = {.command = ACPI_EC_COMMAND_WRITE, + .wdata = wdata, .rdata = NULL, + .wlen = 2, .rlen = 0}; + + return acpi_ec_transaction_unlocked(ec, &t); +} + int ec_read(u8 addr, u8 *val) { int err; @@ -1053,28 +1080,20 @@ Event Management -------------------------------------------------------------------------- */ static struct acpi_ec_query_handler * -acpi_ec_get_query_handler(struct acpi_ec_query_handler *handler) -{ - if (handler) - kref_get(&handler->kref); - return handler; -} - -static struct acpi_ec_query_handler * acpi_ec_get_query_handler_by_value(struct acpi_ec *ec, u8 value) { struct acpi_ec_query_handler *handler; - bool found = false; mutex_lock(&ec->mutex); list_for_each_entry(handler, &ec->list, node) { if (value == handler->query_bit) { - found = true; - break; + kref_get(&handler->kref); + mutex_unlock(&ec->mutex); + return handler; } } mutex_unlock(&ec->mutex); - return found ? acpi_ec_get_query_handler(handler) : NULL; + return NULL; } static void acpi_ec_query_handler_release(struct kref *kref) @@ -1133,10 +1152,11 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) { acpi_ec_remove_query_handlers(ec, false, query_bit); + flush_workqueue(ec_query_wq); } EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); -static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) +static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) { struct acpi_ec_query *q; struct transaction *t; @@ -1144,11 +1164,13 @@ q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); if (!q) return NULL; + INIT_WORK(&q->work, acpi_ec_event_processor); t = &q->transaction; t->command = ACPI_EC_COMMAND_QUERY; t->rdata = pval; t->rlen = 1; + q->ec = ec; return q; } @@ -1165,13 +1187,21 @@ { struct acpi_ec_query *q = container_of(work, struct acpi_ec_query, work); struct acpi_ec_query_handler *handler = q->handler; + struct acpi_ec *ec = q->ec; ec_dbg_evt("Query(0x%02x) started", handler->query_bit); + if (handler->func) handler->func(handler->data); else if (handler->handle) acpi_evaluate_object(handler->handle, NULL, NULL, NULL); + ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); + + spin_lock_irq(&ec->lock); + ec->queries_in_progress--; + spin_unlock_irq(&ec->lock); + acpi_ec_delete_query(q); } @@ -1181,7 +1211,7 @@ int result; struct acpi_ec_query *q; - q = acpi_ec_create_query(&value); + q = acpi_ec_create_query(ec, &value); if (!q) return -ENOMEM; @@ -1203,19 +1233,20 @@ } /* - * It is reported that _Qxx are evaluated in a parallel way on - * Windows: + * It is reported that _Qxx are evaluated in a parallel way on Windows: * https://bugzilla.kernel.org/show_bug.cgi?id=94411 * - * Put this log entry before schedule_work() in order to make - * it appearing before any other log entries occurred during the - * work queue execution. + * Put this log entry before queue_work() to make it appear in the log + * before any other messages emitted during workqueue handling. */ ec_dbg_evt("Query(0x%02x) scheduled", value); - if (!queue_work(ec_query_wq, &q->work)) { - ec_dbg_evt("Query(0x%02x) overlapped", value); - result = -EBUSY; - } + + spin_lock_irq(&ec->lock); + + ec->queries_in_progress++; + queue_work(ec_query_wq, &q->work); + + spin_unlock_irq(&ec->lock); err_exit: if (result) @@ -1273,20 +1304,34 @@ ec_dbg_evt("Event stopped"); acpi_ec_check_event(ec); + + spin_lock_irqsave(&ec->lock, flags); + ec->events_in_progress--; + spin_unlock_irqrestore(&ec->lock, flags); } -static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, - u32 gpe_number, void *data) +static void acpi_ec_handle_interrupt(struct acpi_ec *ec) { unsigned long flags; - struct acpi_ec *ec = data; spin_lock_irqsave(&ec->lock, flags); advance_transaction(ec); spin_unlock_irqrestore(&ec->lock, flags); +} + +static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, + u32 gpe_number, void *data) +{ + acpi_ec_handle_interrupt(data); return ACPI_INTERRUPT_HANDLED; } +static irqreturn_t acpi_ec_irq_handler(int irq, void *data) +{ + acpi_ec_handle_interrupt(data); + return IRQ_HANDLED; +} + /* -------------------------------------------------------------------------- * Address Space Management * -------------------------------------------------------------------------- */ @@ -1299,6 +1344,7 @@ struct acpi_ec *ec = handler_context; int result = 0, i, bytes = bits / 8; u8 *value = (u8 *)value64; + u32 glk; if ((address > 0xFF) || !value || !handler_context) return AE_BAD_PARAMETER; @@ -1306,17 +1352,38 @@ if (function != ACPI_READ && function != ACPI_WRITE) return AE_BAD_PARAMETER; + mutex_lock(&ec->mutex); + + if (ec->global_lock) { + acpi_status status; + + status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); + if (ACPI_FAILURE(status)) { + result = -ENODEV; + goto unlock; + } + } + if (ec->busy_polling || bits > 8) acpi_ec_burst_enable(ec); - for (i = 0; i < bytes; ++i, ++address, ++value) + for (i = 0; i < bytes; ++i, ++address, ++value) { result = (function == ACPI_READ) ? - acpi_ec_read(ec, address, value) : - acpi_ec_write(ec, address, *value); + acpi_ec_read_unlocked(ec, address, value) : + acpi_ec_write_unlocked(ec, address, *value); + if (result < 0) + break; + } if (ec->busy_polling || bits > 8) acpi_ec_burst_disable(ec); + if (ec->global_lock) + acpi_release_global_lock(glk); + +unlock: + mutex_unlock(&ec->mutex); + switch (result) { case -EINVAL: return AE_BAD_PARAMETER; @@ -1324,8 +1391,10 @@ return AE_NOT_FOUND; case -ETIME: return AE_TIME; - default: + case 0: return AE_OK; + default: + return AE_ERROR; } } @@ -1359,6 +1428,8 @@ ec->timestamp = jiffies; ec->busy_polling = true; ec->polling_guard = 0; + ec->gpe = -1; + ec->irq = -1; return ec; } @@ -1406,9 +1477,13 @@ /* Get GPE bit assignment (EC events). */ /* TODO: Add support for _GPE returning a package */ status = acpi_evaluate_integer(handle, "_GPE", NULL, &tmp); - if (ACPI_FAILURE(status)) - return status; - ec->gpe = tmp; + if (ACPI_SUCCESS(status)) + ec->gpe = tmp; + + /* + * Errors are non-fatal, allowing for ACPI Reduced Hardware + * platforms which use GpioInt instead of GPE. + */ } /* Use the global lock for all EC transactions? */ tmp = 0; @@ -1418,12 +1493,45 @@ return AE_CTRL_TERMINATE; } -/* - * Note: This function returns an error code only when the address space - * handler is not installed, which means "not able to handle - * transactions". +static bool install_gpe_event_handler(struct acpi_ec *ec) +{ + acpi_status status; + + status = acpi_install_gpe_raw_handler(NULL, ec->gpe, + ACPI_GPE_EDGE_TRIGGERED, + &acpi_ec_gpe_handler, ec); + if (ACPI_FAILURE(status)) + return false; + + if (test_bit(EC_FLAGS_STARTED, &ec->flags) && ec->reference_count >= 1) + acpi_ec_enable_gpe(ec, true); + + return true; +} + +static bool install_gpio_irq_event_handler(struct acpi_ec *ec) +{ + return request_irq(ec->irq, acpi_ec_irq_handler, IRQF_SHARED, + "ACPI EC", ec) >= 0; +} + +/** + * ec_install_handlers - Install service callbacks and register query methods. + * @ec: Target EC. + * @device: ACPI device object corresponding to @ec. + * + * Install a handler for the EC address space type unless it has been installed + * already. If @device is not NULL, also look for EC query methods in the + * namespace and register them, and install an event (either GPE or GPIO IRQ) + * handler for the EC, if possible. + * + * Return: + * -ENODEV if the address space handler cannot be installed, which means + * "unable to handle transactions", + * -EPROBE_DEFER if GPIO IRQ acquisition needs to be deferred, + * or 0 (success) otherwise. */ -static int ec_install_handlers(struct acpi_ec *ec, bool handle_events) +static int ec_install_handlers(struct acpi_ec *ec, struct acpi_device *device) { acpi_status status; @@ -1453,28 +1561,45 @@ set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags); } - if (!handle_events) + if (!device) return 0; - if (!test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) { + if (ec->gpe < 0) { + /* ACPI reduced hardware platforms use a GpioInt from _CRS. */ + int irq = acpi_dev_gpio_irq_get(device, 0); + /* + * Bail out right away for deferred probing or complete the + * initialization regardless of any other errors. + */ + if (irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + else if (irq >= 0) + ec->irq = irq; + } + + if (!test_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags)) { /* Find and register all query methods */ acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1, acpi_ec_register_query_methods, NULL, ec, NULL); - set_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags); + set_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags); } - if (!test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) { - status = acpi_install_gpe_raw_handler(NULL, ec->gpe, - ACPI_GPE_EDGE_TRIGGERED, - &acpi_ec_gpe_handler, ec); - /* This is not fatal as we can poll EC events */ - if (ACPI_SUCCESS(status)) { - set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); + if (!test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags)) { + bool ready = false; + + if (ec->gpe >= 0) + ready = install_gpe_event_handler(ec); + else if (ec->irq >= 0) + ready = install_gpio_irq_event_handler(ec); + + if (ready) { + set_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags); acpi_ec_leave_noirq(ec); - if (test_bit(EC_FLAGS_STARTED, &ec->flags) && - ec->reference_count >= 1) - acpi_ec_enable_gpe(ec, true); } + /* + * Failures to install an event handler are not fatal, because + * the EC can be polled for events. + */ } /* EC is fully operational, allow queries */ acpi_ec_enable_event(ec); @@ -1504,23 +1629,28 @@ */ acpi_ec_stop(ec, false); - if (test_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags)) { - if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, - &acpi_ec_gpe_handler))) + if (test_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags)) { + if (ec->gpe >= 0 && + ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, + &acpi_ec_gpe_handler))) pr_err("failed to remove gpe handler\n"); - clear_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags); + + if (ec->irq >= 0) + free_irq(ec->irq, ec); + + clear_bit(EC_FLAGS_EVENT_HANDLER_INSTALLED, &ec->flags); } - if (test_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags)) { + if (test_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags)) { acpi_ec_remove_query_handlers(ec, true, 0); - clear_bit(EC_FLAGS_EVT_HANDLER_INSTALLED, &ec->flags); + clear_bit(EC_FLAGS_QUERY_METHODS_INSTALLED, &ec->flags); } } -static int acpi_ec_setup(struct acpi_ec *ec, bool handle_events) +static int acpi_ec_setup(struct acpi_ec *ec, struct acpi_device *device) { int ret; - ret = ec_install_handlers(ec, handle_events); + ret = ec_install_handlers(ec, device); if (ret) return ret; @@ -1531,8 +1661,8 @@ } acpi_handle_info(ec->handle, - "GPE=0x%x, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", - ec->gpe, ec->command_addr, ec->data_addr); + "GPE=0x%x, IRQ=%d, EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", + ec->gpe, ec->irq, ec->command_addr, ec->data_addr); return ret; } @@ -1577,7 +1707,7 @@ status = ec_parse_device(device->handle, 0, ec, NULL); if (status != AE_CTRL_TERMINATE) { ret = -EINVAL; - goto err_alloc; + goto err; } if (boot_ec && ec->command_addr == boot_ec->command_addr && @@ -1596,9 +1726,9 @@ } } - ret = acpi_ec_setup(ec, true); + ret = acpi_ec_setup(ec, device); if (ret) - goto err_query; + goto err; if (ec == boot_ec) acpi_handle_info(boot_ec->handle, @@ -1619,12 +1749,10 @@ acpi_handle_debug(ec->handle, "enumerated.\n"); return 0; -err_query: - if (ec != boot_ec) - acpi_ec_remove_query_handlers(ec, true, 0); -err_alloc: +err: if (ec != boot_ec) acpi_ec_free(ec); + return ret; } @@ -1716,7 +1844,7 @@ * At this point, the GPE is not fully initialized, so do not to * handle the events. */ - ret = acpi_ec_setup(ec, false); + ret = acpi_ec_setup(ec, NULL); if (ret) { acpi_ec_free(ec); return; @@ -1843,6 +1971,22 @@ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL}, { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL}, + { ec_honor_ecdt_gpe, "ASUS X550VXK", { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL}, @@ -1889,14 +2033,21 @@ ec->command_addr = ecdt_ptr->control.address; ec->data_addr = ecdt_ptr->data.address; } - ec->gpe = ecdt_ptr->gpe; + + /* + * Ignore the GPE value on Reduced Hardware platforms. + * Some products have this set to an erroneous value. + */ + if (!acpi_gbl_reduced_hardware) + ec->gpe = ecdt_ptr->gpe; + ec->handle = ACPI_ROOT_OBJECT; /* * At this point, the namespace is not initialized, so do not find * the namespace objects, or handle the events. */ - ret = acpi_ec_setup(ec, false); + ret = acpi_ec_setup(ec, NULL); if (ret) { acpi_ec_free(ec); return; @@ -1928,7 +2079,7 @@ * masked at the low level without side effects. */ if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) && - ec->reference_count >= 1) + ec->gpe >= 0 && ec->reference_count >= 1) acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); acpi_ec_enter_noirq(ec); @@ -1943,7 +2094,7 @@ acpi_ec_leave_noirq(ec); if (ec_no_wakeup && test_bit(EC_FLAGS_STARTED, &ec->flags) && - ec->reference_count >= 1) + ec->gpe >= 0 && ec->reference_count >= 1) acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); return 0; @@ -1973,16 +2124,41 @@ bool acpi_ec_dispatch_gpe(void) { + bool work_in_progress; u32 ret; if (!first_ec) - return false; + return acpi_any_gpe_status_set(U32_MAX); + /* + * Report wakeup if the status bit is set for any enabled GPE other + * than the EC one. + */ + if (acpi_any_gpe_status_set(first_ec->gpe)) + return true; + + /* + * Dispatch the EC GPE in-band, but do not report wakeup in any case + * to allow the caller to process events properly after that. + */ ret = acpi_dispatch_gpe(NULL, first_ec->gpe); - if (ret == ACPI_INTERRUPT_HANDLED) { + if (ret == ACPI_INTERRUPT_HANDLED) pm_pr_dbg("EC GPE dispatched\n"); - return true; - } + + /* Drain EC work. */ + do { + acpi_ec_flush_work(); + + pm_pr_dbg("ACPI EC work flushed\n"); + + spin_lock_irq(&first_ec->lock); + + work_in_progress = first_ec->events_in_progress + + first_ec->queries_in_progress > 0; + + spin_unlock_irq(&first_ec->lock); + } while (work_in_progress && !pm_wakeup_pending()); + return false; } #endif /* CONFIG_PM_SLEEP */ @@ -2042,25 +2218,33 @@ .drv.pm = &acpi_ec_pm, }; -static inline int acpi_ec_query_init(void) +static void acpi_ec_destroy_workqueues(void) { - if (!ec_query_wq) { - ec_query_wq = alloc_workqueue("kec_query", 0, - ec_max_queries); - if (!ec_query_wq) - return -ENODEV; + if (ec_wq) { + destroy_workqueue(ec_wq); + ec_wq = NULL; } - return 0; -} - -static inline void acpi_ec_query_exit(void) -{ if (ec_query_wq) { destroy_workqueue(ec_query_wq); ec_query_wq = NULL; } } +static int acpi_ec_init_workqueues(void) +{ + if (!ec_wq) + ec_wq = alloc_ordered_workqueue("kec", 0); + + if (!ec_query_wq) + ec_query_wq = alloc_workqueue("kec_query", 0, ec_max_queries); + + if (!ec_wq || !ec_query_wq) { + acpi_ec_destroy_workqueues(); + return -ENODEV; + } + return 0; +} + static const struct dmi_system_id acpi_ec_no_wakeup[] = { { .ident = "Thinkpad X1 Carbon 6th", @@ -2070,13 +2254,6 @@ }, }, { - .ident = "ThinkPad X1 Carbon 6th", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Carbon 6th"), - }, - }, - { .ident = "ThinkPad X1 Yoga 3rd", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), @@ -2091,8 +2268,7 @@ int result; int ecdt_fail, dsdt_fail; - /* register workqueue for _Qxx evaluations */ - result = acpi_ec_query_init(); + result = acpi_ec_init_workqueues(); if (result) return result; @@ -2123,6 +2299,6 @@ { acpi_bus_unregister_driver(&acpi_ec_driver); - acpi_ec_query_exit(); + acpi_ec_destroy_workqueues(); } #endif /* 0 */ --- linux-oracle-5.4.0.orig/drivers/acpi/evged.c +++ linux-oracle-5.4.0/drivers/acpi/evged.c @@ -79,6 +79,8 @@ struct resource r; struct acpi_resource_irq *p = &ares->data.irq; struct acpi_resource_extended_irq *pext = &ares->data.extended_irq; + char ev_name[5]; + u8 trigger; if (ares->type == ACPI_RESOURCE_TYPE_END_TAG) return AE_OK; @@ -87,14 +89,28 @@ dev_err(dev, "unable to parse IRQ resource\n"); return AE_ERROR; } - if (ares->type == ACPI_RESOURCE_TYPE_IRQ) + if (ares->type == ACPI_RESOURCE_TYPE_IRQ) { gsi = p->interrupts[0]; - else + trigger = p->triggering; + } else { gsi = pext->interrupts[0]; + trigger = pext->triggering; + } irq = r.start; - if (ACPI_FAILURE(acpi_get_handle(handle, "_EVT", &evt_handle))) { + switch (gsi) { + case 0 ... 255: + sprintf(ev_name, "_%c%02X", + trigger == ACPI_EDGE_SENSITIVE ? 'E' : 'L', gsi); + + if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle))) + break; + /* fall through */ + default: + if (ACPI_SUCCESS(acpi_get_handle(handle, "_EVT", &evt_handle))) + break; + dev_err(dev, "cannot locate _EVT method\n"); return AE_ERROR; } --- linux-oracle-5.4.0.orig/drivers/acpi/hmat/hmat.c +++ linux-oracle-5.4.0/drivers/acpi/hmat/hmat.c @@ -403,7 +403,8 @@ pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", p->flags, p->processor_PD, p->memory_PD); - if (p->flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1) { + if ((hmat_revision == 1 && p->flags & ACPI_HMAT_MEMORY_PD_VALID) || + hmat_revision > 1) { target = find_mem_target(p->memory_PD); if (!target) { pr_debug("HMAT: Memory Domain missing from SRAT\n"); --- linux-oracle-5.4.0.orig/drivers/acpi/internal.h +++ linux-oracle-5.4.0/drivers/acpi/internal.h @@ -9,6 +9,8 @@ #ifndef _ACPI_INTERNAL_H_ #define _ACPI_INTERNAL_H_ +#include + #define PREFIX "ACPI: " int early_acpi_osi_init(void); @@ -96,9 +98,11 @@ extern struct list_head acpi_bus_id_list; +#define ACPI_MAX_DEVICE_INSTANCES 4096 + struct acpi_device_bus_id { - char bus_id[15]; - unsigned int instance_no; + const char *bus_id; + struct ida instance_ida; struct list_head node; }; @@ -165,7 +169,8 @@ -------------------------------------------------------------------------- */ struct acpi_ec { acpi_handle handle; - u32 gpe; + int gpe; + int irq; unsigned long command_addr; unsigned long data_addr; bool global_lock; @@ -179,6 +184,8 @@ struct work_struct work; unsigned long timestamp; unsigned long nr_pending_queries; + unsigned int events_in_progress; + unsigned int queries_in_progress; bool busy_polling; unsigned int polling_guard; }; --- linux-oracle-5.4.0.orig/drivers/acpi/irq.c +++ linux-oracle-5.4.0/drivers/acpi/irq.c @@ -52,6 +52,7 @@ int polarity) { struct irq_fwspec fwspec; + unsigned int irq; if (WARN_ON(!acpi_gsi_domain_id)) { pr_warn("GSI: No registered irqchip, giving up\n"); @@ -63,7 +64,11 @@ fwspec.param[1] = acpi_dev_get_irq_type(trigger, polarity); fwspec.param_count = 2; - return irq_create_fwspec_mapping(&fwspec); + irq = irq_create_fwspec_mapping(&fwspec); + if (!irq) + return -EINVAL; + + return irq; } EXPORT_SYMBOL_GPL(acpi_register_gsi); --- linux-oracle-5.4.0.orig/drivers/acpi/nfit/core.c +++ linux-oracle-5.4.0/drivers/acpi/nfit/core.c @@ -360,7 +360,7 @@ static u8 nfit_dsm_revid(unsigned family, unsigned func) { - static const u8 revid_table[NVDIMM_FAMILY_MAX+1][32] = { + static const u8 revid_table[NVDIMM_FAMILY_MAX+1][NVDIMM_CMD_MAX+1] = { [NVDIMM_FAMILY_INTEL] = { [NVDIMM_INTEL_GET_MODES] = 2, [NVDIMM_INTEL_GET_FWINFO] = 2, @@ -386,7 +386,7 @@ if (family > NVDIMM_FAMILY_MAX) return 0; - if (func > 31) + if (func > NVDIMM_CMD_MAX) return 0; id = revid_table[family][func]; if (id == 0) @@ -492,7 +492,8 @@ * Check for a valid command. For ND_CMD_CALL, we also have to * make sure that the DSM function is supported. */ - if (cmd == ND_CMD_CALL && !test_bit(func, &dsm_mask)) + if (cmd == ND_CMD_CALL && + (func > NVDIMM_CMD_MAX || !test_bit(func, &dsm_mask))) return -ENOTTY; else if (!test_bit(cmd, &cmd_mask)) return -ENOTTY; @@ -1552,7 +1553,7 @@ le16_to_cpu(nfit_dcr->dcr->code)); break; } - if (rc != ENXIO) + if (rc != -ENXIO) break; } mutex_unlock(&acpi_desc->init_mutex); @@ -2972,6 +2973,9 @@ struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev; struct nd_mapping_desc *mapping; + /* range index 0 == unmapped in SPA or invalid-SPA */ + if (memdev->range_index == 0 || spa->range_index == 0) + continue; if (memdev->range_index != spa->range_index) continue; if (count >= ND_MAX_MAPPINGS) { @@ -3499,7 +3503,8 @@ if (nvdimm && cmd == ND_CMD_CALL && call_pkg->nd_family == NVDIMM_FAMILY_INTEL) { func = call_pkg->nd_command; - if ((1 << func) & NVDIMM_INTEL_SECURITY_CMDMASK) + if (func > NVDIMM_CMD_MAX || + (1 << func) & NVDIMM_INTEL_SECURITY_CMDMASK) return -EOPNOTSUPP; } @@ -3594,8 +3599,8 @@ mutex_lock(&acpi_desc->init_mutex); set_bit(ARS_CANCEL, &acpi_desc->scrub_flags); - cancel_delayed_work_sync(&acpi_desc->dwork); mutex_unlock(&acpi_desc->init_mutex); + cancel_delayed_work_sync(&acpi_desc->dwork); /* * Bounce the nvdimm bus lock to make sure any in-flight --- linux-oracle-5.4.0.orig/drivers/acpi/nfit/nfit.h +++ linux-oracle-5.4.0/drivers/acpi/nfit/nfit.h @@ -34,6 +34,7 @@ | ACPI_NFIT_MEM_NOT_ARMED | ACPI_NFIT_MEM_MAP_FAILED) #define NVDIMM_FAMILY_MAX NVDIMM_FAMILY_HYPERV +#define NVDIMM_CMD_MAX 31 #define NVDIMM_STANDARD_CMDMASK \ (1 << ND_CMD_SMART | 1 << ND_CMD_SMART_THRESHOLD | 1 << ND_CMD_DIMM_FLAGS \ --- linux-oracle-5.4.0.orig/drivers/acpi/numa.c +++ linux-oracle-5.4.0/drivers/acpi/numa.c @@ -31,7 +31,7 @@ int pxm_to_node(int pxm) { - if (pxm < 0) + if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off) return NUMA_NO_NODE; return pxm_to_node_map[pxm]; } --- linux-oracle-5.4.0.orig/drivers/acpi/osi.c +++ linux-oracle-5.4.0/drivers/acpi/osi.c @@ -468,6 +468,77 @@ }, /* + * The following Lenovo models have a broken workaround in the + * acpi_video backlight implementation to meet the Windows 8 + * requirement of 101 backlight levels. Reverting to pre-Win8 + * behavior fixes the problem. + */ + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad L430", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T430", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T430s", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad T530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad W530", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad X1 Carbon", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad X230", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), + }, + }, + { + .callback = dmi_disable_osi_win8, + .ident = "Lenovo ThinkPad Edge E330", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E330"), + }, + }, + + /* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. * Linux ignores it, except for the machines enumerated below. */ --- linux-oracle-5.4.0.orig/drivers/acpi/osl.c +++ linux-oracle-5.4.0/drivers/acpi/osl.c @@ -374,19 +374,21 @@ } EXPORT_SYMBOL_GPL(acpi_os_map_memory); -static void acpi_os_drop_map_ref(struct acpi_ioremap *map) +/* Must be called with mutex_lock(&acpi_ioremap_lock) */ +static unsigned long acpi_os_drop_map_ref(struct acpi_ioremap *map) { - if (!--map->refcount) + unsigned long refcount = --map->refcount; + + if (!refcount) list_del_rcu(&map->list); + return refcount; } static void acpi_os_map_cleanup(struct acpi_ioremap *map) { - if (!map->refcount) { - synchronize_rcu_expedited(); - acpi_unmap(map->phys, map->virt); - kfree(map); - } + synchronize_rcu_expedited(); + acpi_unmap(map->phys, map->virt); + kfree(map); } /** @@ -406,6 +408,7 @@ void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size) { struct acpi_ioremap *map; + unsigned long refcount; if (!acpi_permanent_mmap) { __acpi_unmap_table(virt, size); @@ -419,10 +422,11 @@ WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); return; } - acpi_os_drop_map_ref(map); + refcount = acpi_os_drop_map_ref(map); mutex_unlock(&acpi_ioremap_lock); - acpi_os_map_cleanup(map); + if (!refcount) + acpi_os_map_cleanup(map); } EXPORT_SYMBOL_GPL(acpi_os_unmap_iomem); @@ -457,6 +461,7 @@ { u64 addr; struct acpi_ioremap *map; + unsigned long refcount; if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) return; @@ -472,10 +477,11 @@ mutex_unlock(&acpi_ioremap_lock); return; } - acpi_os_drop_map_ref(map); + refcount = acpi_os_drop_map_ref(map); mutex_unlock(&acpi_ioremap_lock); - acpi_os_map_cleanup(map); + if (!refcount) + acpi_os_map_cleanup(map); } EXPORT_SYMBOL(acpi_os_unmap_generic_address); --- linux-oracle-5.4.0.orig/drivers/acpi/pci_mcfg.c +++ linux-oracle-5.4.0/drivers/acpi/pci_mcfg.c @@ -41,6 +41,8 @@ static struct mcfg_fixup mcfg_quirks[] = { /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ +#ifdef CONFIG_ARM64 + #define AL_ECAM(table_id, rev, seg, ops) \ { "AMAZON", table_id, rev, seg, MCFG_BUS_ANY, ops } @@ -142,6 +144,27 @@ XGENE_V2_ECAM_MCFG(4, 0), XGENE_V2_ECAM_MCFG(4, 1), XGENE_V2_ECAM_MCFG(4, 2), + +#define ALTRA_ECAM_QUIRK(rev, seg) \ + { "Ampere", "Altra ", rev, seg, MCFG_BUS_ANY, &pci_32b_read_ops } + + ALTRA_ECAM_QUIRK(1, 0), + ALTRA_ECAM_QUIRK(1, 1), + ALTRA_ECAM_QUIRK(1, 2), + ALTRA_ECAM_QUIRK(1, 3), + ALTRA_ECAM_QUIRK(1, 4), + ALTRA_ECAM_QUIRK(1, 5), + ALTRA_ECAM_QUIRK(1, 6), + ALTRA_ECAM_QUIRK(1, 7), + ALTRA_ECAM_QUIRK(1, 8), + ALTRA_ECAM_QUIRK(1, 9), + ALTRA_ECAM_QUIRK(1, 10), + ALTRA_ECAM_QUIRK(1, 11), + ALTRA_ECAM_QUIRK(1, 12), + ALTRA_ECAM_QUIRK(1, 13), + ALTRA_ECAM_QUIRK(1, 14), + ALTRA_ECAM_QUIRK(1, 15), +#endif /* ARM64 */ }; static char mcfg_oem_id[ACPI_OEM_ID_SIZE]; --- linux-oracle-5.4.0.orig/drivers/acpi/pmic/intel_pmic.c +++ linux-oracle-5.4.0/drivers/acpi/pmic/intel_pmic.c @@ -211,31 +211,36 @@ void *handler_context, void *region_context) { struct intel_pmic_opregion *opregion = region_context; - int result = 0; + int result = -EINVAL; - switch (address) { - case 0: - return AE_OK; - case 1: - opregion->ctx.addr |= (*value64 & 0xff) << 8; - return AE_OK; - case 2: - opregion->ctx.addr |= *value64 & 0xff; - return AE_OK; - case 3: - opregion->ctx.val = *value64 & 0xff; - return AE_OK; - case 4: - if (*value64) { - result = regmap_write(opregion->regmap, opregion->ctx.addr, - opregion->ctx.val); - } else { - result = regmap_read(opregion->regmap, opregion->ctx.addr, - &opregion->ctx.val); - if (result == 0) - *value64 = opregion->ctx.val; + if (function == ACPI_WRITE) { + switch (address) { + case 0: + return AE_OK; + case 1: + opregion->ctx.addr |= (*value64 & 0xff) << 8; + return AE_OK; + case 2: + opregion->ctx.addr |= *value64 & 0xff; + return AE_OK; + case 3: + opregion->ctx.val = *value64 & 0xff; + return AE_OK; + case 4: + if (*value64) { + result = regmap_write(opregion->regmap, opregion->ctx.addr, + opregion->ctx.val); + } else { + result = regmap_read(opregion->regmap, opregion->ctx.addr, + &opregion->ctx.val); + } + opregion->ctx.addr = 0; } - memset(&opregion->ctx, 0x00, sizeof(opregion->ctx)); + } + + if (function == ACPI_READ && address == 3) { + *value64 = opregion->ctx.val; + return AE_OK; } if (result < 0) { --- linux-oracle-5.4.0.orig/drivers/acpi/pmic/tps68470_pmic.c +++ linux-oracle-5.4.0/drivers/acpi/pmic/tps68470_pmic.c @@ -376,10 +376,8 @@ struct tps68470_pmic_opregion *opregion; acpi_status status; - if (!dev || !tps68470_regmap) { - dev_warn(dev, "dev or regmap is NULL\n"); - return -EINVAL; - } + if (!tps68470_regmap) + return dev_err_probe(dev, -EINVAL, "regmap is missing\n"); if (!handle) { dev_warn(dev, "acpi handle is NULL\n"); --- linux-oracle-5.4.0.orig/drivers/acpi/power.c +++ linux-oracle-5.4.0/drivers/acpi/power.c @@ -888,15 +888,16 @@ kfree(resource); } -static ssize_t acpi_power_in_use_show(struct device *dev, - struct device_attribute *attr, - char *buf) { +static ssize_t resource_in_use_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ struct acpi_power_resource *resource; resource = to_power_resource(to_acpi_device(dev)); return sprintf(buf, "%u\n", !!resource->ref_count); } -static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL); +static DEVICE_ATTR_RO(resource_in_use); static void acpi_power_sysfs_remove(struct acpi_device *device) { --- linux-oracle-5.4.0.orig/drivers/acpi/processor_idle.c +++ linux-oracle-5.4.0/drivers/acpi/processor_idle.c @@ -540,10 +540,33 @@ return; } +static void acpi_cst_latency_sort(struct acpi_processor_cx *states, size_t length) +{ + int i, j, k; + + for (i = 1; i < length; i++) { + if (!states[i].valid) + continue; + + for (j = i - 1, k = i; j >= 0; j--) { + if (!states[j].valid) + continue; + + if (states[j].latency > states[k].latency) + swap(states[j].latency, states[k].latency); + + k = j; + } + } +} + static int acpi_processor_power_verify(struct acpi_processor *pr) { unsigned int i; unsigned int working = 0; + unsigned int last_latency = 0; + unsigned int last_type = 0; + bool buggy_latency = false; pr->power.timer_broadcast_on_state = INT_MAX; @@ -567,12 +590,21 @@ } if (!cx->valid) continue; + if (cx->type >= last_type && cx->latency < last_latency) + buggy_latency = true; + last_latency = cx->latency; + last_type = cx->type; lapic_timer_check_state(i, pr, cx); tsc_check_state(cx->type); working++; } + if (buggy_latency) { + pr_notice("FW issue: working around C-state latencies out of order\n"); + acpi_cst_latency_sort(&pr->power.states[1], max_cstate); + } + lapic_timer_propagate_broadcast(pr); return (working); @@ -642,6 +674,36 @@ return bm_status; } +static void wait_for_freeze(void) +{ +#ifdef CONFIG_X86 + /* No delay is needed if we are in guest */ + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return; + /* + * Modern (>=Nehalem) Intel systems use ACPI via intel_idle, + * not this code. Assume that any Intel systems using this + * are ancient and may need the dummy wait. This also assumes + * that the motivating chipset issue was Intel-only. + */ + if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + return; +#endif + /* + * Dummy wait op - must do something useless after P_LVL2 read + * because chipsets cannot guarantee that STPCLK# signal gets + * asserted in time to freeze execution properly + * + * This workaround has been in place since the original ACPI + * implementation was merged, circa 2002. + * + * If a profile is pointing to this instruction, please first + * consider moving your system to a more modern idle + * mechanism. + */ + inl(acpi_gbl_FADT.xpm_timer_block.address); +} + /** * acpi_idle_do_entry - enter idle state using the appropriate method * @cx: cstate data @@ -658,10 +720,7 @@ } else { /* IO port based C-state */ inb(cx->address); - /* Dummy wait op - must do something useless after P_LVL2 read - because chipsets cannot guarantee that STPCLK# signal - gets asserted in time to freeze execution properly. */ - inl(acpi_gbl_FADT.xpm_timer_block.address); + wait_for_freeze(); } } @@ -682,8 +741,7 @@ safe_halt(); else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { inb(cx->address); - /* See comment in acpi_idle_do_entry() */ - inl(acpi_gbl_FADT.xpm_timer_block.address); + wait_for_freeze(); } else return -ENODEV; } @@ -1161,6 +1219,11 @@ return 0; } +int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) +{ + return -EOPNOTSUPP; +} + static int acpi_processor_get_lpi_info(struct acpi_processor *pr) { int ret, i; @@ -1169,6 +1232,11 @@ struct acpi_device *d = NULL; struct acpi_lpi_states_array info[2], *tmp, *prev, *curr; + /* make sure our architecture has support */ + ret = acpi_processor_ffh_lpi_probe(pr->id); + if (ret == -EOPNOTSUPP) + return ret; + if (!osc_pc_lpi_support_confirmed) return -EOPNOTSUPP; @@ -1220,11 +1288,6 @@ return 0; } -int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu) -{ - return -ENODEV; -} - int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi) { return -ENODEV; @@ -1486,6 +1549,8 @@ acpi_processor_registered--; if (acpi_processor_registered == 0) cpuidle_unregister_driver(&acpi_idle_driver); + + kfree(dev); } pr->flags.power_setup_done = 0; --- linux-oracle-5.4.0.orig/drivers/acpi/processor_perflib.c +++ linux-oracle-5.4.0/drivers/acpi/processor_perflib.c @@ -56,6 +56,8 @@ { acpi_status status = 0; unsigned long long ppc = 0; + s32 qos_value; + int index; int ret; if (!pr) @@ -75,17 +77,30 @@ return -ENODEV; } + index = ppc; + + if (pr->performance_platform_limit == index || + ppc >= pr->performance->state_count) + return 0; + pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id, - (int)ppc, ppc ? "" : "not"); + index, index ? "is" : "is not"); - pr->performance_platform_limit = (int)ppc; + pr->performance_platform_limit = index; - if (ppc >= pr->performance->state_count || - unlikely(!freq_qos_request_active(&pr->perflib_req))) + if (unlikely(!freq_qos_request_active(&pr->perflib_req))) return 0; - ret = freq_qos_update_request(&pr->perflib_req, - pr->performance->states[ppc].core_frequency * 1000); + /* + * If _PPC returns 0, it means that all of the available states can be + * used ("no limit"). + */ + if (index == 0) + qos_value = FREQ_QOS_MAX_DEFAULT_VALUE; + else + qos_value = pr->performance->states[index].core_frequency * 1000; + + ret = freq_qos_update_request(&pr->perflib_req, qos_value); if (ret < 0) { pr_warn("Failed to update perflib freq constraint: CPU%d (%d)\n", pr->id, ret); @@ -168,9 +183,16 @@ if (!pr) continue; + /* + * Reset performance_platform_limit in case there is a stale + * value in it, so as to make it match the "no limit" QoS value + * below. + */ + pr->performance_platform_limit = 0; + ret = freq_qos_add_request(&policy->constraints, - &pr->perflib_req, - FREQ_QOS_MAX, INT_MAX); + &pr->perflib_req, FREQ_QOS_MAX, + FREQ_QOS_MAX_DEFAULT_VALUE); if (ret < 0) pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, ret); --- linux-oracle-5.4.0.orig/drivers/acpi/processor_thermal.c +++ linux-oracle-5.4.0/drivers/acpi/processor_thermal.c @@ -150,7 +150,7 @@ unsigned int cpu; for_each_cpu(cpu, policy->related_cpus) { - struct acpi_processor *pr = per_cpu(processors, policy->cpu); + struct acpi_processor *pr = per_cpu(processors, cpu); if (pr) freq_qos_remove_request(&pr->thermal_req); --- linux-oracle-5.4.0.orig/drivers/acpi/processor_throttling.c +++ linux-oracle-5.4.0/drivers/acpi/processor_throttling.c @@ -897,13 +897,6 @@ return pr->throttling.acpi_processor_get_throttling(pr); } -static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) -{ - if (direct || (is_percpu_thread() && cpu == smp_processor_id())) - return fn(arg); - return work_on_cpu(cpu, fn, arg); -} - static int acpi_processor_get_throttling(struct acpi_processor *pr) { if (!pr) --- linux-oracle-5.4.0.orig/drivers/acpi/property.c +++ linux-oracle-5.4.0/drivers/acpi/property.c @@ -152,10 +152,10 @@ return acpi_nondev_subnode_data_ok(handle, link, list, parent); } -static int acpi_add_nondev_subnodes(acpi_handle scope, - const union acpi_object *links, - struct list_head *list, - struct fwnode_handle *parent) +static bool acpi_add_nondev_subnodes(acpi_handle scope, + const union acpi_object *links, + struct list_head *list, + struct fwnode_handle *parent) { bool ret = false; int i; @@ -430,6 +430,16 @@ acpi_extract_apple_properties(adev); } +static void acpi_free_device_properties(struct list_head *list) +{ + struct acpi_device_properties *props, *tmp; + + list_for_each_entry_safe(props, tmp, list, list) { + list_del(&props->list); + kfree(props); + } +} + static void acpi_destroy_nondev_subnodes(struct list_head *list) { struct acpi_data_node *dn, *next; @@ -442,22 +452,18 @@ wait_for_completion(&dn->kobj_done); list_del(&dn->sibling); ACPI_FREE((void *)dn->data.pointer); + acpi_free_device_properties(&dn->data.properties); kfree(dn); } } void acpi_free_properties(struct acpi_device *adev) { - struct acpi_device_properties *props, *tmp; - acpi_destroy_nondev_subnodes(&adev->data.subnodes); ACPI_FREE((void *)adev->data.pointer); adev->data.of_compatible = NULL; adev->data.pointer = NULL; - list_for_each_entry_safe(props, tmp, &adev->data.properties, list) { - list_del(&props->list); - kfree(props); - } + acpi_free_device_properties(&adev->data.properties); } /** @@ -640,6 +646,7 @@ * @index: Index of the reference to return * @num_args: Maximum number of arguments after each reference * @args: Location to store the returned reference with optional arguments + * (may be NULL) * * Find property with @name, verifify that it is a package containing at least * one object reference and if so, store the ACPI device object pointer to the @@ -692,12 +699,15 @@ */ if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) { if (index) - return -EINVAL; + return -ENOENT; ret = acpi_bus_get_device(obj->reference.handle, &device); if (ret) return ret == -ENODEV ? -EINVAL : ret; + if (!args) + return 0; + args->fwnode = acpi_fwnode_handle(device); args->nargs = 0; return 0; @@ -794,9 +804,6 @@ const union acpi_object *obj; int ret; - if (!val) - return -EINVAL; - if (proptype >= DEV_PROP_U8 && proptype <= DEV_PROP_U64) { ret = acpi_data_get_property(data, propname, ACPI_TYPE_INTEGER, &obj); if (ret) @@ -806,28 +813,43 @@ case DEV_PROP_U8: if (obj->integer.value > U8_MAX) return -EOVERFLOW; - *(u8 *)val = obj->integer.value; + + if (val) + *(u8 *)val = obj->integer.value; + break; case DEV_PROP_U16: if (obj->integer.value > U16_MAX) return -EOVERFLOW; - *(u16 *)val = obj->integer.value; + + if (val) + *(u16 *)val = obj->integer.value; + break; case DEV_PROP_U32: if (obj->integer.value > U32_MAX) return -EOVERFLOW; - *(u32 *)val = obj->integer.value; + + if (val) + *(u32 *)val = obj->integer.value; + break; default: - *(u64 *)val = obj->integer.value; + if (val) + *(u64 *)val = obj->integer.value; + break; } + + if (!val) + return 1; } else if (proptype == DEV_PROP_STRING) { ret = acpi_data_get_property(data, propname, ACPI_TYPE_STRING, &obj); if (ret) return ret; - *(char **)val = obj->string.pointer; + if (val) + *(char **)val = obj->string.pointer; return 1; } else { @@ -841,7 +863,7 @@ { int ret; - if (!adev) + if (!adev || !val) return -EINVAL; ret = acpi_data_prop_read_single(&adev->data, propname, proptype, val); @@ -935,10 +957,20 @@ const union acpi_object *items; int ret; - if (val && nval == 1) { + if (nval == 1 || !val) { ret = acpi_data_prop_read_single(data, propname, proptype, val); - if (ret >= 0) + /* + * The overflow error means that the property is there and it is + * single-value, but its type does not match, so return. + */ + if (ret >= 0 || ret == -EOVERFLOW) return ret; + + /* + * Reading this property as a single-value one failed, but its + * value may still be represented as one-element array, so + * continue. + */ } ret = acpi_data_get_property_array(data, propname, ACPI_TYPE_ANY, &obj); --- linux-oracle-5.4.0.orig/drivers/acpi/resource.c +++ linux-oracle-5.4.0/drivers/acpi/resource.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_X86 #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) @@ -249,6 +250,9 @@ switch (addr->resource_type) { case ACPI_MEMORY_RANGE: acpi_dev_memresource_flags(res, len, wp); + + if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY) + res->flags |= IORESOURCE_PREFETCH; break; case ACPI_IO_RANGE: acpi_dev_ioresource_flags(res, len, iodec, @@ -264,9 +268,6 @@ if (addr->producer_consumer == ACPI_PRODUCER) res->flags |= IORESOURCE_WINDOW; - if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY) - res->flags |= IORESOURCE_PREFETCH; - return !(res->flags & IORESOURCE_DISABLED); } @@ -380,21 +381,207 @@ } EXPORT_SYMBOL_GPL(acpi_dev_get_irq_type); -static void acpi_dev_irqresource_disabled(struct resource *res, u32 gsi) +static const struct dmi_system_id medion_laptop[] = { + { + .ident = "MEDION P15651", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_BOARD_NAME, "M15T"), + }, + }, + { + .ident = "MEDION S17405", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_BOARD_NAME, "M17T"), + }, + }, + { } +}; + +static const struct dmi_system_id asus_laptop[] = { + { + .ident = "Asus Vivobook K3402ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "K3402ZA"), + }, + }, + { + .ident = "Asus Vivobook K3502ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "K3502ZA"), + }, + }, + { + .ident = "Asus Vivobook S5402ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "S5402ZA"), + }, + }, + { + .ident = "Asus Vivobook S5602ZA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "S5602ZA"), + }, + }, + { + .ident = "Asus ExpertBook B1402CBA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), + }, + }, + { + .ident = "Asus ExpertBook B1502CBA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"), + }, + }, + { + .ident = "Asus ExpertBook B2402CBA", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), + }, + }, + { + /* Asus Vivobook X1504VAP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "X1504VAP"), + }, + }, + { + /* Asus Vivobook X1704VAP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"), + }, + }, + { + /* TongFang GMxXGxx/TUXEDO Polaris 15 Gen5 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"), + }, + }, + { + /* Asus ExpertBook B1402CVA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), + }, + }, + { + /* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"), + }, + }, + { + /* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Eluktronics Inc."), + DMI_MATCH(DMI_BOARD_NAME, "RP-15"), + }, + }, + { + /* TongFang GM6XGxX/TUXEDO Stellaris 16 Gen5 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"), + }, + }, + { + .ident = "Asus ExpertBook B2502", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), + }, + }, + { + /* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"), + }, + }, + { + /* Asus ExpertBook B2502CVA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), + }, + }, + { + /* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"), + }, + }, + { + /* LG Electronics 16T90SP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), + DMI_MATCH(DMI_BOARD_NAME, "16T90SP"), + }, + }, + { + /* + * TongFang GM5HG0A in case of the SKIKK Vanaheim relabel the + * board-name is changed, so check OEM strings instead. Note + * OEM string matches are always exact matches. + * https://bugzilla.kernel.org/show_bug.cgi?id=219614 + */ + .matches = { + DMI_EXACT_MATCH(DMI_OEM_STRING, "GM5HG0A"), + }, + }, + { } +}; + +struct irq_override_cmp { + const struct dmi_system_id *system; + unsigned char irq; + unsigned char triggering; + unsigned char polarity; + unsigned char shareable; +}; + +static const struct irq_override_cmp skip_override_table[] = { + { medion_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, + { asus_laptop, 1, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW, 0 }, +}; + +static bool acpi_dev_irq_override(u32 gsi, u8 triggering, u8 polarity, + u8 shareable) { - res->start = gsi; - res->end = gsi; - res->flags = IORESOURCE_IRQ | IORESOURCE_DISABLED | IORESOURCE_UNSET; + int i; + + for (i = 0; i < ARRAY_SIZE(skip_override_table); i++) { + const struct irq_override_cmp *entry = &skip_override_table[i]; + + if (dmi_check_system(entry->system) && + entry->irq == gsi && + entry->triggering == triggering && + entry->polarity == polarity && + entry->shareable == shareable) + return false; + } + + return true; } static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, u8 triggering, u8 polarity, u8 shareable, - bool legacy) + bool check_override) { int irq, p, t; if (!valid_IRQ(gsi)) { - acpi_dev_irqresource_disabled(res, gsi); + irqresource_disabled(res, gsi); return; } @@ -408,7 +595,9 @@ * using extended IRQ descriptors we take the IRQ configuration * from _CRS directly. */ - if (legacy && !acpi_get_override_irq(gsi, &t, &p)) { + if (check_override && + acpi_dev_irq_override(gsi, triggering, polarity, shareable) && + !acpi_get_override_irq(gsi, &t, &p)) { u8 trig = t ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; u8 pol = p ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; @@ -426,7 +615,7 @@ res->start = irq; res->end = irq; } else { - acpi_dev_irqresource_disabled(res, gsi); + irqresource_disabled(res, gsi); } } @@ -463,7 +652,7 @@ */ irq = &ares->data.irq; if (index >= irq->interrupt_count) { - acpi_dev_irqresource_disabled(res, 0); + irqresource_disabled(res, 0); return false; } acpi_dev_get_irqresource(res, irq->interrupts[index], @@ -473,7 +662,7 @@ case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: ext_irq = &ares->data.extended_irq; if (index >= ext_irq->interrupt_count) { - acpi_dev_irqresource_disabled(res, 0); + irqresource_disabled(res, 0); return false; } if (is_gsi(ext_irq)) @@ -481,7 +670,7 @@ ext_irq->triggering, ext_irq->polarity, ext_irq->shareable, false); else - acpi_dev_irqresource_disabled(res, 0); + irqresource_disabled(res, 0); break; default: res->flags = 0; @@ -541,7 +730,7 @@ ret = c->preproc(ares, c->preproc_data); if (ret < 0) { c->error = ret; - return AE_CTRL_TERMINATE; + return AE_ABORT_METHOD; } else if (ret > 0) { return AE_OK; } --- linux-oracle-5.4.0.orig/drivers/acpi/sbs.c +++ linux-oracle-5.4.0/drivers/acpi/sbs.c @@ -80,7 +80,6 @@ u16 spec; u8 id; u8 present:1; - u8 have_sysfs_alarm:1; }; #define to_acpi_battery(x) power_supply_get_drvdata(x) @@ -465,12 +464,18 @@ return count; } -static const struct device_attribute alarm_attr = { +static struct device_attribute alarm_attr = { .attr = {.name = "alarm", .mode = 0644}, .show = acpi_battery_alarm_show, .store = acpi_battery_alarm_store, }; +static struct attribute *acpi_battery_attrs[] = { + &alarm_attr.attr, + NULL +}; +ATTRIBUTE_GROUPS(acpi_battery); + /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -512,7 +517,10 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) { struct acpi_battery *battery = &sbs->battery[id]; - struct power_supply_config psy_cfg = { .drv_data = battery, }; + struct power_supply_config psy_cfg = { + .drv_data = battery, + .attr_grp = acpi_battery_groups, + }; int result; battery->id = id; @@ -542,10 +550,6 @@ goto end; } - result = device_create_file(&battery->bat->dev, &alarm_attr); - if (result) - goto end; - battery->have_sysfs_alarm = 1; end: printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), @@ -557,11 +561,8 @@ { struct acpi_battery *battery = &sbs->battery[id]; - if (battery->bat) { - if (battery->have_sysfs_alarm) - device_remove_file(&battery->bat->dev, &alarm_attr); + if (battery->bat) power_supply_unregister(battery->bat); - } } static int acpi_charger_add(struct acpi_sbs *sbs) --- linux-oracle-5.4.0.orig/drivers/acpi/scan.c +++ linux-oracle-5.4.0/drivers/acpi/scan.c @@ -322,18 +322,14 @@ * again). */ if (adev->handler) { - dev_warn(&adev->dev, "Already enumerated\n"); - return -EALREADY; + dev_dbg(&adev->dev, "Already enumerated\n"); + return 0; } error = acpi_bus_scan(adev->handle); if (error) { dev_warn(&adev->dev, "Namespace scan failure\n"); return error; } - if (!adev->handler) { - dev_warn(&adev->dev, "Enumeration failure\n"); - error = -ENODEV; - } } else { error = acpi_scan_device_not_present(adev); } @@ -483,10 +479,10 @@ list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) if (!strcmp(acpi_device_bus_id->bus_id, acpi_device_hid(device))) { - if (acpi_device_bus_id->instance_no > 0) - acpi_device_bus_id->instance_no--; - else { + ida_simple_remove(&acpi_device_bus_id->instance_ida, device->pnp.instance_no); + if (ida_is_empty(&acpi_device_bus_id->instance_ida)) { list_del(&acpi_device_bus_id->node); + kfree_const(acpi_device_bus_id->bus_id); kfree(acpi_device_bus_id); } break; @@ -586,6 +582,8 @@ if (!device) return -EINVAL; + *device = NULL; + status = acpi_get_data_full(handle, acpi_scan_drop_device, (void **)device, callback); if (ACPI_FAILURE(status) || !*device) { @@ -621,12 +619,38 @@ put_device(&adev->dev); } +static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id) +{ + struct acpi_device_bus_id *acpi_device_bus_id; + + /* Find suitable bus_id and instance number in acpi_bus_id_list. */ + list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { + if (!strcmp(acpi_device_bus_id->bus_id, dev_id)) + return acpi_device_bus_id; + } + return NULL; +} + +static int acpi_device_set_name(struct acpi_device *device, + struct acpi_device_bus_id *acpi_device_bus_id) +{ + struct ida *instance_ida = &acpi_device_bus_id->instance_ida; + int result; + + result = ida_simple_get(instance_ida, 0, ACPI_MAX_DEVICE_INSTANCES, GFP_KERNEL); + if (result < 0) + return result; + + device->pnp.instance_no = result; + dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, result); + return 0; +} + int acpi_device_add(struct acpi_device *device, void (*release)(struct device *)) { + struct acpi_device_bus_id *acpi_device_bus_id; int result; - struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; - int found = 0; if (device->handle) { acpi_status status; @@ -652,34 +676,39 @@ INIT_LIST_HEAD(&device->del_list); mutex_init(&device->physical_node_lock); - new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); - if (!new_bus_id) { - pr_err(PREFIX "Memory allocation error\n"); - result = -ENOMEM; - goto err_detach; - } - mutex_lock(&acpi_device_lock); - /* - * Find suitable bus_id and instance number in acpi_bus_id_list - * If failed, create one and link it into acpi_bus_id_list - */ - list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) { - if (!strcmp(acpi_device_bus_id->bus_id, - acpi_device_hid(device))) { - acpi_device_bus_id->instance_no++; - found = 1; - kfree(new_bus_id); - break; + + acpi_device_bus_id = acpi_device_bus_id_match(acpi_device_hid(device)); + if (acpi_device_bus_id) { + result = acpi_device_set_name(device, acpi_device_bus_id); + if (result) + goto err_unlock; + } else { + acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id), + GFP_KERNEL); + if (!acpi_device_bus_id) { + result = -ENOMEM; + goto err_unlock; + } + acpi_device_bus_id->bus_id = + kstrdup_const(acpi_device_hid(device), GFP_KERNEL); + if (!acpi_device_bus_id->bus_id) { + kfree(acpi_device_bus_id); + result = -ENOMEM; + goto err_unlock; + } + + ida_init(&acpi_device_bus_id->instance_ida); + + result = acpi_device_set_name(device, acpi_device_bus_id); + if (result) { + kfree_const(acpi_device_bus_id->bus_id); + kfree(acpi_device_bus_id); + goto err_unlock; } - } - if (!found) { - acpi_device_bus_id = new_bus_id; - strcpy(acpi_device_bus_id->bus_id, acpi_device_hid(device)); - acpi_device_bus_id->instance_no = 0; + list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); } - dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); if (device->parent) list_add_tail(&device->node, &device->parent->children); @@ -710,9 +739,10 @@ if (device->parent) list_del(&device->node); list_del(&device->wakeup_list); + + err_unlock: mutex_unlock(&acpi_device_lock); - err_detach: acpi_detach_data(device->handle, acpi_scan_drop_device); return result; } @@ -919,12 +949,9 @@ if (buffer.length && package && package->type == ACPI_TYPE_PACKAGE - && package->package.count) { - int err = acpi_extract_power_resources(package, 0, - &ps->resources); - if (!err) - device->power.flags.power_resources = 1; - } + && package->package.count) + acpi_extract_power_resources(package, 0, &ps->resources); + ACPI_FREE(buffer.pointer); } @@ -971,14 +998,27 @@ acpi_bus_init_power_state(device, i); INIT_LIST_HEAD(&device->power.states[ACPI_STATE_D3_COLD].resources); - if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources)) - device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; - /* Set defaults for D0 and D3hot states (always valid) */ + /* Set the defaults for D0 and D3hot (always supported). */ device->power.states[ACPI_STATE_D0].flags.valid = 1; device->power.states[ACPI_STATE_D0].power = 100; device->power.states[ACPI_STATE_D3_HOT].flags.valid = 1; + /* + * Use power resources only if the D0 list of them is populated, because + * some platforms may provide _PR3 only to indicate D3cold support and + * in those cases the power resources list returned by it may be bogus. + */ + if (!list_empty(&device->power.states[ACPI_STATE_D0].resources)) { + device->power.flags.power_resources = 1; + /* + * D3cold is supported if the D3hot list of power resources is + * not empty. + */ + if (!list_empty(&device->power.states[ACPI_STATE_D3_HOT].resources)) + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; + } + if (acpi_bus_init_power(device)) device->flags.power_manageable = 0; } @@ -1533,6 +1573,7 @@ { struct list_head resource_list; bool is_serial_bus_slave = false; + static const struct acpi_device_id ignore_serial_bus_ids[] = { /* * These devices have multiple I2cSerialBus resources and an i2c-client * must be instantiated for each, each with its own i2c_device_id. @@ -1541,11 +1582,18 @@ * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows * which i2c_device_id to use for each resource. */ - static const struct acpi_device_id i2c_multi_instantiate_ids[] = { {"BSG1160", }, {"BSG2150", }, {"INT33FE", }, {"INT3515", }, + /* + * HIDs of device with an UartSerialBusV2 resource for which userspace + * expects a regular tty cdev to be created (instead of the in kernel + * serdev) and which have a kernel driver which expects a platform_dev + * such as the rfkill-gpio driver. + */ + {"BCM4752", }, + {"LNV4752", }, {} }; @@ -1559,8 +1607,7 @@ fwnode_property_present(&device->fwnode, "baud"))) return true; - /* Instantiate a pdev for the i2c-multi-instantiate drv to bind to */ - if (!acpi_match_device_ids(device, i2c_multi_instantiate_ids)) + if (!acpi_match_device_ids(device, ignore_serial_bus_ids)) return false; INIT_LIST_HEAD(&resource_list); @@ -2174,6 +2221,7 @@ acpi_pci_root_init(); acpi_pci_link_init(); acpi_processor_init(); + acpi_platform_init(); acpi_lpss_init(); acpi_apd_init(); acpi_cmos_rtc_init(); --- linux-oracle-5.4.0.orig/drivers/acpi/sleep.c +++ linux-oracle-5.4.0/drivers/acpi/sleep.c @@ -361,6 +361,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Lenovo G40-45", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80E1"), + }, + }, /* * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using * the Low Power S0 Idle firmware interface (see @@ -977,23 +985,38 @@ return 0; } -static void acpi_s2idle_wake(void) +static bool acpi_s2idle_wake(void) { - /* - * If IRQD_WAKEUP_ARMED is set for the SCI at this point, the SCI has - * not triggered while suspended, so bail out. - */ - if (!acpi_sci_irq_valid() || - irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) - return; + if (!acpi_sci_irq_valid()) + return pm_wakeup_pending(); + + while (pm_wakeup_pending()) { + /* + * If IRQD_WAKEUP_ARMED is set for the SCI at this point, the + * SCI has not triggered while suspended, so bail out (the + * wakeup is pending anyway and the SCI is not the source of + * it). + */ + if (irqd_is_wakeup_armed(irq_get_irq_data(acpi_sci_irq))) + return true; + + /* + * If the status bit of any enabled fixed event is set, the + * wakeup is regarded as valid. + */ + if (acpi_any_fixed_event_status_set()) + return true; + + /* Check wakeups from drivers sharing the SCI. */ + if (acpi_check_wakeup_handlers()) + return true; + + /* Check non-EC GPE wakeups and dispatch the EC GPE. */ + if (acpi_ec_dispatch_gpe()) + return true; - /* - * If there are EC events to process, the wakeup may be a spurious one - * coming from the EC. - */ - if (acpi_ec_dispatch_gpe()) { /* - * Cancel the wakeup and process all pending events in case + * Cancel the SCI wakeup and process all pending events in case * there are any wakeup ones in there. * * Note that if any non-EC GPEs are active at this point, the @@ -1001,16 +1024,22 @@ * should be missed by canceling the wakeup here. */ pm_system_cancel_wakeup(); + acpi_os_wait_events_complete(); + /* - * The EC driver uses the system workqueue and an additional - * special one, so those need to be flushed too. + * The SCI is in the "suspended" state now and it cannot produce + * new wakeup events till the rearming below, so if any of them + * are pending here, they must be resulting from the processing + * of EC events above or coming from somewhere else. */ - acpi_os_wait_events_complete(); /* synchronize EC GPE processing */ - acpi_ec_flush_work(); - acpi_os_wait_events_complete(); /* synchronize Notify handling */ + if (pm_wakeup_pending()) + return true; + pm_wakeup_clear(acpi_sci_irq); rearm_wake_irq(acpi_sci_irq); } + + return false; } static void acpi_s2idle_restore_early(void) @@ -1024,6 +1053,14 @@ static void acpi_s2idle_restore(void) { + /* + * Drain pending events before restoring the working-state configuration + * of GPEs. + */ + acpi_os_wait_events_complete(); /* synchronize GPE processing */ + acpi_ec_flush_work(); /* flush the EC driver's workqueues */ + acpi_os_wait_events_complete(); /* synchronize Notify handling */ + s2idle_wakeup = false; acpi_enable_all_runtime_gpes(); --- linux-oracle-5.4.0.orig/drivers/acpi/sleep.h +++ linux-oracle-5.4.0/drivers/acpi/sleep.h @@ -2,6 +2,7 @@ extern void acpi_enable_wakeup_devices(u8 sleep_state); extern void acpi_disable_wakeup_devices(u8 sleep_state); +extern bool acpi_check_wakeup_handlers(void); extern struct list_head acpi_wakeup_device_list; extern struct mutex acpi_device_lock; --- linux-oracle-5.4.0.orig/drivers/acpi/sysfs.c +++ linux-oracle-5.4.0/drivers/acpi/sysfs.c @@ -439,18 +439,29 @@ { struct acpi_data_attr *data_attr; void __iomem *base; - ssize_t rc; + ssize_t size; data_attr = container_of(bin_attr, struct acpi_data_attr, attr); + size = data_attr->attr.size; - base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size); + if (offset < 0) + return -EINVAL; + + if (offset >= size) + return 0; + + if (count > size - offset) + count = size - offset; + + base = acpi_os_map_iomem(data_attr->addr, size); if (!base) return -ENOMEM; - rc = memory_read_from_buffer(buf, count, &offset, base, - data_attr->attr.size); - acpi_os_unmap_memory(base, data_attr->attr.size); - return rc; + memcpy_fromio(buf, base + offset, count); + + acpi_os_unmap_iomem(base, size); + + return count; } static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr) @@ -819,14 +830,14 @@ * interface: * echo unmask > /sys/firmware/acpi/interrupts/gpe00 */ -#define ACPI_MASKABLE_GPE_MAX 0xFF +#define ACPI_MASKABLE_GPE_MAX 0x100 static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata; static int __init acpi_gpe_set_masked_gpes(char *val) { u8 gpe; - if (kstrtou8(val, 0, &gpe) || gpe > ACPI_MASKABLE_GPE_MAX) + if (kstrtou8(val, 0, &gpe)) return -EINVAL; set_bit(gpe, acpi_masked_gpes_map); @@ -838,7 +849,7 @@ { acpi_handle handle; acpi_status status; - u8 gpe; + u16 gpe; for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) { status = acpi_get_gpe_device(gpe, &handle); @@ -938,13 +949,13 @@ } static ssize_t -acpi_show_profile(struct device *dev, struct device_attribute *attr, +acpi_show_profile(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile); } -static const struct device_attribute pm_profile_attr = +static const struct kobj_attribute pm_profile_attr = __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL); static ssize_t hotplug_enabled_show(struct kobject *kobj, @@ -993,8 +1004,10 @@ error = kobject_init_and_add(&hotplug->kobj, &acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name); - if (error) + if (error) { + kobject_put(&hotplug->kobj); goto err_out; + } kobject_uevent(&hotplug->kobj, KOBJ_ADD); return; --- linux-oracle-5.4.0.orig/drivers/acpi/tables.c +++ linux-oracle-5.4.0/drivers/acpi/tables.c @@ -791,7 +791,7 @@ } /* - * acpi_table_init() + * acpi_locate_initial_tables() * * find RSDP, find and checksum SDT/XSDT. * checksum all tables, print SDT/XSDT @@ -799,7 +799,7 @@ * result: sdt_entry[] is initialized */ -int __init acpi_table_init(void) +int __init acpi_locate_initial_tables(void) { acpi_status status; @@ -814,9 +814,45 @@ status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); if (ACPI_FAILURE(status)) return -EINVAL; - acpi_table_initrd_scan(); + return 0; +} + +void __init acpi_reserve_initial_tables(void) +{ + int i; + + for (i = 0; i < ACPI_MAX_TABLES; i++) { + struct acpi_table_desc *table_desc = &initial_tables[i]; + u64 start = table_desc->address; + u64 size = table_desc->length; + + if (!start || !size) + break; + + pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n", + table_desc->signature.ascii, start, start + size - 1); + + memblock_reserve(start, size); + } +} + +void __init acpi_table_init_complete(void) +{ + acpi_table_initrd_scan(); check_multiple_madt(); +} + +int __init acpi_table_init(void) +{ + int ret; + + ret = acpi_locate_initial_tables(); + if (ret) + return ret; + + acpi_table_init_complete(); + return 0; } --- linux-oracle-5.4.0.orig/drivers/acpi/thermal.c +++ linux-oracle-5.4.0/drivers/acpi/thermal.c @@ -174,6 +174,8 @@ int tz_enabled; int kelvin_offset; struct work_struct thermal_check_work; + struct mutex thermal_check_lock; + refcount_t thermal_check_count; }; /* -------------------------------------------------------------------------- @@ -494,17 +496,6 @@ return 0; } -static void acpi_thermal_check(void *data) -{ - struct acpi_thermal *tz = data; - - if (!tz->tz_enabled) - return; - - thermal_zone_device_update(tz->thermal_zone, - THERMAL_EVENT_UNSPECIFIED); -} - /* sys I/F for generic thermal sysfs support */ static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) @@ -538,6 +529,8 @@ return 0; } +static void acpi_thermal_check_fn(struct work_struct *work); + static int thermal_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode) { @@ -563,7 +556,7 @@ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s kernel ACPI thermal control\n", tz->tz_enabled ? "Enable" : "Disable")); - acpi_thermal_check(tz); + acpi_thermal_check_fn(&tz->thermal_check_work); } return 0; } @@ -932,6 +925,12 @@ Driver Interface -------------------------------------------------------------------------- */ +static void acpi_queue_thermal_check(struct acpi_thermal *tz) +{ + if (!work_pending(&tz->thermal_check_work)) + queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); +} + static void acpi_thermal_notify(struct acpi_device *device, u32 event) { struct acpi_thermal *tz = acpi_driver_data(device); @@ -942,17 +941,17 @@ switch (event) { case ACPI_THERMAL_NOTIFY_TEMPERATURE: - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); break; case ACPI_THERMAL_NOTIFY_THRESHOLDS: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); - acpi_thermal_check(tz); + acpi_queue_thermal_check(tz); acpi_bus_generate_netlink_event(device->pnp.device_class, dev_name(&device->dev), event, 0); break; @@ -1052,7 +1051,27 @@ { struct acpi_thermal *tz = container_of(work, struct acpi_thermal, thermal_check_work); - acpi_thermal_check(tz); + + if (!tz->tz_enabled) + return; + /* + * In general, it is not sufficient to check the pending bit, because + * subsequent instances of this function may be queued after one of them + * has started running (e.g. if _TMP sleeps). Avoid bailing out if just + * one of them is running, though, because it may have done the actual + * check some time ago, so allow at least one of them to block on the + * mutex while another one is running the update. + */ + if (!refcount_dec_not_one(&tz->thermal_check_count)) + return; + + mutex_lock(&tz->thermal_check_lock); + + thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); + + refcount_inc(&tz->thermal_check_count); + + mutex_unlock(&tz->thermal_check_lock); } static int acpi_thermal_add(struct acpi_device *device) @@ -1084,6 +1103,8 @@ if (result) goto free_memory; + refcount_set(&tz->thermal_check_count, 3); + mutex_init(&tz->thermal_check_lock); INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), @@ -1132,8 +1153,6 @@ return -EINVAL; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { - if (!(&tz->trips.active[i])) - break; if (!tz->trips.active[i].flags.valid) break; tz->trips.active[i].flags.enabled = 1; @@ -1149,7 +1168,7 @@ tz->state.active |= tz->trips.active[i].flags.enabled; } - queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); + acpi_queue_thermal_check(tz); return AE_OK; } --- linux-oracle-5.4.0.orig/drivers/acpi/video_detect.c +++ linux-oracle-5.4.0/drivers/acpi/video_detect.c @@ -143,6 +143,14 @@ }, { .callback = video_detect_force_vendor, + .ident = "GIGABYTE GB-BXBT-2807", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), + }, + }, + { + .callback = video_detect_force_vendor, .ident = "Sony VPCEH3U1E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), @@ -282,6 +290,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"), }, }, + /* https://bugs.launchpad.net/bugs/1894667 */ + { + .callback = video_detect_force_video, + .ident = "HP 635 Notebook", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"), + }, + }, /* Non win8 machines which need native backlight nevertheless */ { @@ -294,12 +311,37 @@ }, }, { + /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */ + .callback = video_detect_force_native, + /* Lenovo Ideapad Z470 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"), + }, + }, + { /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ .callback = video_detect_force_native, .ident = "Lenovo Ideapad Z570", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "102434U"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Ideapad Z570"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "Lenovo E41-25", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "81FS"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "Lenovo E41-45", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82BK"), }, }, { @@ -337,6 +379,184 @@ }, }, { + .callback = video_detect_force_native, + .ident = "Acer Aspire 5738z", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), + DMI_MATCH(DMI_BOARD_NAME, "JV50"), + }, + }, + { + /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */ + .callback = video_detect_force_native, + .ident = "Acer TravelMate 5735Z", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5735Z"), + DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"), + }, + }, + /* + * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a + * working native and video interface. However the default detection + * mechanism first registers the video interface before unregistering + * it again and switching to the native interface during boot. This + * results in a dangling SBIOS request for backlight change for some + * reason, causing the backlight to switch to ~2% once per boot on the + * first power cord connect or disconnect event. Setting the native + * interface explicitly circumvents this buggy behaviour, by avoiding + * the unregistering process. + */ + { + .callback = video_detect_force_native, + .ident = "Clevo NL5xRU", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "Clevo NL5xRU", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "Clevo NL5xRU", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "Clevo NL5xNU", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), + }, + }, + /* + * The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 Gen10, + * Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the Clevo + * NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description + * above. + */ + { + .callback = video_detect_force_native, + .ident = "TongFang PF5PU1G", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang PF4NU1F", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang PF4NU1F", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang PF5NU1G", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang PF5NU1G", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang PF5LUXG", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"), + }, + }, + /* + * More Tongfang devices with the same issue as the Clevo NL5xRU and + * NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description above. + */ + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GKxNRxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A1650TI"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1501A2060"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A1650TI"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GKxNRxx", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "POLARIS1701A2060"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxNGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxNGxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxZGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxZGxx"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "TongFang GMxRGxx", + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"), + }, + }, + /* + * Desktops which falsely report a backlight and which our heuristics + * for this do not catch. + */ + { .callback = video_detect_force_none, .ident = "Dell OptiPlex 9020M", .matches = { @@ -344,6 +564,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 9020M"), }, }, + { + .callback = video_detect_force_none, + .ident = "MSI MS-7721", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MSI"), + DMI_MATCH(DMI_PRODUCT_NAME, "MS-7721"), + }, + }, { }, }; --- linux-oracle-5.4.0.orig/drivers/acpi/wakeup.c +++ linux-oracle-5.4.0/drivers/acpi/wakeup.c @@ -12,6 +12,15 @@ #include "internal.h" #include "sleep.h" +struct acpi_wakeup_handler { + struct list_head list_node; + bool (*wakeup)(void *context); + void *context; +}; + +static LIST_HEAD(acpi_wakeup_handler_head); +static DEFINE_MUTEX(acpi_wakeup_handler_mutex); + /* * We didn't lock acpi_device_lock in the file, because it invokes oops in * suspend/resume and isn't really required as this is called in S-state. At @@ -96,3 +105,75 @@ mutex_unlock(&acpi_device_lock); return 0; } + +/** + * acpi_register_wakeup_handler - Register wakeup handler + * @wake_irq: The IRQ through which the device may receive wakeups + * @wakeup: Wakeup-handler to call when the SCI has triggered a wakeup + * @context: Context to pass to the handler when calling it + * + * Drivers which may share an IRQ with the SCI can use this to register + * a handler which returns true when the device they are managing wants + * to trigger a wakeup. + */ +int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context), + void *context) +{ + struct acpi_wakeup_handler *handler; + + /* + * If the device is not sharing its IRQ with the SCI, there is no + * need to register the handler. + */ + if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq) + return 0; + + handler = kmalloc(sizeof(*handler), GFP_KERNEL); + if (!handler) + return -ENOMEM; + + handler->wakeup = wakeup; + handler->context = context; + + mutex_lock(&acpi_wakeup_handler_mutex); + list_add(&handler->list_node, &acpi_wakeup_handler_head); + mutex_unlock(&acpi_wakeup_handler_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(acpi_register_wakeup_handler); + +/** + * acpi_unregister_wakeup_handler - Unregister wakeup handler + * @wakeup: Wakeup-handler passed to acpi_register_wakeup_handler() + * @context: Context passed to acpi_register_wakeup_handler() + */ +void acpi_unregister_wakeup_handler(bool (*wakeup)(void *context), + void *context) +{ + struct acpi_wakeup_handler *handler; + + mutex_lock(&acpi_wakeup_handler_mutex); + list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) { + if (handler->wakeup == wakeup && handler->context == context) { + list_del(&handler->list_node); + kfree(handler); + break; + } + } + mutex_unlock(&acpi_wakeup_handler_mutex); +} +EXPORT_SYMBOL_GPL(acpi_unregister_wakeup_handler); + +bool acpi_check_wakeup_handlers(void) +{ + struct acpi_wakeup_handler *handler; + + /* No need to lock, nothing else is running when we're called. */ + list_for_each_entry(handler, &acpi_wakeup_handler_head, list_node) { + if (handler->wakeup(handler->context)) + return true; + } + + return false; +} --- linux-oracle-5.4.0.orig/drivers/amba/bus.c +++ linux-oracle-5.4.0/drivers/amba/bus.c @@ -299,10 +299,11 @@ { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *drv = to_amba_driver(dev->driver); - int ret; + int ret = 0; pm_runtime_get_sync(dev); - ret = drv->remove(pcdev); + if (drv->remove) + ret = drv->remove(pcdev); pm_runtime_put_noidle(dev); /* Undo the runtime PM settings in amba_probe() */ @@ -319,7 +320,9 @@ static void amba_shutdown(struct device *dev) { struct amba_driver *drv = to_amba_driver(dev->driver); - drv->shutdown(to_amba_device(dev)); + + if (drv->shutdown) + drv->shutdown(to_amba_device(dev)); } /** @@ -332,12 +335,13 @@ */ int amba_driver_register(struct amba_driver *drv) { - drv->drv.bus = &amba_bustype; + if (!drv->probe) + return -EINVAL; -#define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn - SETFN(probe); - SETFN(remove); - SETFN(shutdown); + drv->drv.bus = &amba_bustype; + drv->drv.probe = amba_probe; + drv->drv.remove = amba_remove; + drv->drv.shutdown = amba_shutdown; return driver_register(&drv->drv); } @@ -360,6 +364,7 @@ { struct amba_device *d = to_amba_device(dev); + of_node_put(d->dev.of_node); if (d->res.parent) release_resource(&d->res); kfree(d); @@ -371,9 +376,6 @@ void __iomem *tmp; int i, ret; - WARN_ON(dev->irq[0] == (unsigned int)-1); - WARN_ON(dev->irq[1] == (unsigned int)-1); - ret = request_resource(parent, &dev->res); if (ret) goto err_out; --- linux-oracle-5.4.0.orig/drivers/android/Kconfig +++ linux-oracle-5.4.0/drivers/android/Kconfig @@ -9,7 +9,7 @@ if ANDROID config ANDROID_BINDER_IPC - bool "Android Binder IPC Driver" + tristate "Android Binder IPC Driver" depends on MMU default n ---help--- @@ -21,8 +21,8 @@ between said processes. config ANDROID_BINDERFS - bool "Android Binderfs filesystem" - depends on ANDROID_BINDER_IPC + tristate "Android Binderfs filesystem" + depends on (ANDROID_BINDER_IPC=y) || (ANDROID_BINDER_IPC=m && m) default n ---help--- Binderfs is a pseudo-filesystem for the Android Binder IPC driver --- linux-oracle-5.4.0.orig/drivers/android/Makefile +++ linux-oracle-5.4.0/drivers/android/Makefile @@ -1,6 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only ccflags-y += -I$(src) # needed for trace events -obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o -obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o -obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +binder_linux-y := binder.o binder_alloc.o +obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o +binder_linux-$(CONFIG_ANDROID_BINDERFS) += binderfs.o +binder_linux-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o + +# binder-$(CONFIG_ANDROID_BINDER_IPC) := binder.o binder_alloc.o +# binder-$(CONFIG_ANDROID_BINDERFS) += binderfs.o --- linux-oracle-5.4.0.orig/drivers/android/binder.c +++ linux-oracle-5.4.0/drivers/android/binder.c @@ -227,7 +227,7 @@ struct binder_work { struct list_head entry; - enum { + enum binder_work_type { BINDER_WORK_TRANSACTION = 1, BINDER_WORK_TRANSACTION_COMPLETE, BINDER_WORK_RETURN_ERROR, @@ -424,6 +424,9 @@ * (invariant after initialized) * @tsk task_struct for group_leader of process * (invariant after initialized) + * @cred struct cred associated with the `struct file` + * in binder_open() + * (invariant after initialized) * @deferred_work_node: element for binder_deferred_list * (protected by binder_deferred_lock) * @deferred_work: bitmap of deferred work to perform @@ -469,6 +472,7 @@ struct list_head waiting_threads; int pid; struct task_struct *tsk; + const struct cred *cred; struct hlist_node deferred_work_node; int deferred_work; bool is_dead; @@ -476,7 +480,7 @@ struct list_head todo; struct binder_stats stats; struct list_head delivered_death; - int max_threads; + u32 max_threads; int requested_threads; int requested_threads_started; int tmp_ref; @@ -836,6 +840,16 @@ { WARN_ON(!list_empty(&thread->waiting_thread_node)); binder_enqueue_work_ilocked(work, &thread->todo); + + /* (e)poll-based threads require an explicit wakeup signal when + * queuing their own work; they rely on these events to consume + * messages without I/O block. Without it, threads risk waiting + * indefinitely without handling the work. + */ + if (thread->looper & BINDER_LOOPER_STATE_POLL && + thread->pid == current->pid && !thread->process_todo) + wake_up_interruptible_sync(&thread->wait); + thread->process_todo = true; } @@ -889,27 +903,6 @@ return w; } -/** - * binder_dequeue_work_head() - Dequeues the item at head of list - * @proc: binder_proc associated with list - * @list: list to dequeue head - * - * Removes the head of the list if there are items on the list - * - * Return: pointer dequeued binder_work, NULL if list was empty - */ -static struct binder_work *binder_dequeue_work_head( - struct binder_proc *proc, - struct list_head *list) -{ - struct binder_work *w; - - binder_inner_proc_lock(proc); - w = binder_dequeue_work_head_ilocked(list); - binder_inner_proc_unlock(proc); - return w; -} - static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); static void binder_free_thread(struct binder_thread *thread); @@ -939,9 +932,7 @@ static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread) { return !thread->transaction_stack && - binder_worklist_empty_ilocked(&thread->todo) && - (thread->looper & (BINDER_LOOPER_STATE_ENTERED | - BINDER_LOOPER_STATE_REGISTERED)); + binder_worklist_empty_ilocked(&thread->todo); } static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc, @@ -1765,6 +1756,18 @@ } ret = binder_inc_ref_olocked(ref, strong, target_list); *rdata = ref->data; + if (ret && ref == new_ref) { + /* + * Cleanup the failed reference here as the target + * could now be dead and have already released its + * references by now. Calling on the new reference + * with strong=0 and a tmp_refs will not decrement + * the node. The new_ref gets kfree'd below. + */ + binder_cleanup_ref_olocked(new_ref); + ref = NULL; + } + binder_proc_unlock(proc); if (new_ref && ref != new_ref) /* @@ -2018,15 +2021,21 @@ /** * binder_get_object() - gets object and checks for valid metadata * @proc: binder_proc owning the buffer + * @u: sender's user pointer to base of buffer * @buffer: binder_buffer that we're parsing. * @offset: offset in the @buffer at which to validate an object. * @object: struct binder_object to read into * - * Return: If there's a valid metadata object at @offset in @buffer, the + * Copy the binder object at the given offset into @object. If @u is + * provided then the copy is from the sender's buffer. If not, then + * it is copied from the target's @buffer. + * + * Return: If there's a valid metadata object at @offset, the * size of that object. Otherwise, it returns zero. The object * is read into the struct binder_object pointed to by @object. */ static size_t binder_get_object(struct binder_proc *proc, + const void __user *u, struct binder_buffer *buffer, unsigned long offset, struct binder_object *object) @@ -2037,10 +2046,18 @@ read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); if (offset > buffer->data_size || read_size < sizeof(*hdr) || - binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, - offset, read_size)) + !IS_ALIGNED(offset, sizeof(u32))) return 0; + if (u) { + if (copy_from_user(object, u + offset, read_size)) + return 0; + } else { + if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, + offset, read_size)) + return 0; + } + /* Ok, now see if we read a complete object. */ hdr = &object->hdr; switch (hdr->type) { @@ -2112,7 +2129,7 @@ b, buffer_offset, sizeof(object_offset))) return NULL; - object_size = binder_get_object(proc, b, object_offset, object); + object_size = binder_get_object(proc, NULL, b, object_offset, object); if (!object_size || object->hdr.type != BINDER_TYPE_PTR) return NULL; if (object_offsetp) @@ -2177,7 +2194,8 @@ unsigned long buffer_offset; struct binder_object last_object; struct binder_buffer_object *last_bbo; - size_t object_size = binder_get_object(proc, b, last_obj_offset, + size_t object_size = binder_get_object(proc, NULL, b, + last_obj_offset, &last_object); if (object_size != sizeof(*last_bbo)) return false; @@ -2260,25 +2278,25 @@ } static void binder_transaction_buffer_release(struct binder_proc *proc, + struct binder_thread *thread, struct binder_buffer *buffer, - binder_size_t failed_at, + binder_size_t off_end_offset, bool is_failure) { int debug_id = buffer->debug_id; - binder_size_t off_start_offset, buffer_offset, off_end_offset; + binder_size_t off_start_offset, buffer_offset; binder_debug(BINDER_DEBUG_TRANSACTION, "%d buffer release %d, size %zd-%zd, failed at %llx\n", proc->pid, buffer->debug_id, buffer->data_size, buffer->offsets_size, - (unsigned long long)failed_at); + (unsigned long long)off_end_offset); if (buffer->target_node) binder_dec_node(buffer->target_node, 1, 0); off_start_offset = ALIGN(buffer->data_size, sizeof(void *)); - off_end_offset = is_failure ? failed_at : - off_start_offset + buffer->offsets_size; + for (buffer_offset = off_start_offset; buffer_offset < off_end_offset; buffer_offset += sizeof(binder_size_t)) { struct binder_object_header *hdr; @@ -2289,7 +2307,7 @@ if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, buffer, buffer_offset, sizeof(object_offset))) - object_size = binder_get_object(proc, buffer, + object_size = binder_get_object(proc, NULL, buffer, object_offset, &object); if (object_size == 0) { pr_err("transaction release %d bad object at offset %lld, size %zd\n", @@ -2347,8 +2365,6 @@ * file is done when the transaction is torn * down. */ - WARN_ON(failed_at && - proc->tsk == current->group_leader); } break; case BINDER_TYPE_PTR: /* @@ -2365,9 +2381,8 @@ binder_size_t fd_buf_size; binder_size_t num_valid; - if (proc->tsk != current->group_leader) { + if (is_failure) { /* - * Nothing to do if running in sender context * The fd fixups have not been applied so no * fds need to be closed. */ @@ -2421,8 +2436,16 @@ &proc->alloc, &fd, buffer, offset, sizeof(fd)); WARN_ON(err); - if (!err) + if (!err) { binder_deferred_fd_close(fd); + /* + * Need to make sure the thread goes + * back to userspace to complete the + * deferred close + */ + if (thread) + thread->looper_need_return = true; + } } } break; default: @@ -2433,6 +2456,21 @@ } } +/* Clean up all the objects in the buffer */ +static inline void binder_release_entire_buffer(struct binder_proc *proc, + struct binder_thread *thread, + struct binder_buffer *buffer, + bool is_failure) +{ + binder_size_t off_end_offset; + + off_end_offset = ALIGN(buffer->data_size, sizeof(void *)); + off_end_offset += buffer->offsets_size; + + binder_transaction_buffer_release(proc, thread, buffer, + off_end_offset, is_failure); +} + static int binder_translate_binder(struct flat_binder_object *fp, struct binder_transaction *t, struct binder_thread *thread) @@ -2457,7 +2495,7 @@ ret = -EINVAL; goto done; } - if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { + if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { ret = -EPERM; goto done; } @@ -2503,7 +2541,7 @@ proc->pid, thread->pid, fp->handle); return -EINVAL; } - if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { + if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { ret = -EPERM; goto done; } @@ -2591,7 +2629,7 @@ ret = -EBADF; goto err_fget; } - ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file); + ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); if (ret < 0) { ret = -EPERM; goto err_security; @@ -2622,16 +2660,266 @@ return ret; } -static int binder_translate_fd_array(struct binder_fd_array_object *fda, +/** + * struct binder_ptr_fixup - data to be fixed-up in target buffer + * @offset offset in target buffer to fixup + * @skip_size bytes to skip in copy (fixup will be written later) + * @fixup_data data to write at fixup offset + * @node list node + * + * This is used for the pointer fixup list (pf) which is created and consumed + * during binder_transaction() and is only accessed locally. No + * locking is necessary. + * + * The list is ordered by @offset. + */ +struct binder_ptr_fixup { + binder_size_t offset; + size_t skip_size; + binder_uintptr_t fixup_data; + struct list_head node; +}; + +/** + * struct binder_sg_copy - scatter-gather data to be copied + * @offset offset in target buffer + * @sender_uaddr user address in source buffer + * @length bytes to copy + * @node list node + * + * This is used for the sg copy list (sgc) which is created and consumed + * during binder_transaction() and is only accessed locally. No + * locking is necessary. + * + * The list is ordered by @offset. + */ +struct binder_sg_copy { + binder_size_t offset; + const void __user *sender_uaddr; + size_t length; + struct list_head node; +}; + +/** + * binder_do_deferred_txn_copies() - copy and fixup scatter-gather data + * @alloc: binder_alloc associated with @buffer + * @buffer: binder buffer in target process + * @sgc_head: list_head of scatter-gather copy list + * @pf_head: list_head of pointer fixup list + * + * Processes all elements of @sgc_head, applying fixups from @pf_head + * and copying the scatter-gather data from the source process' user + * buffer to the target's buffer. It is expected that the list creation + * and processing all occurs during binder_transaction() so these lists + * are only accessed in local context. + * + * Return: 0=success, else -errno + */ +static int binder_do_deferred_txn_copies(struct binder_alloc *alloc, + struct binder_buffer *buffer, + struct list_head *sgc_head, + struct list_head *pf_head) +{ + int ret = 0; + struct binder_sg_copy *sgc, *tmpsgc; + struct binder_ptr_fixup *tmppf; + struct binder_ptr_fixup *pf = + list_first_entry_or_null(pf_head, struct binder_ptr_fixup, + node); + + list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { + size_t bytes_copied = 0; + + while (bytes_copied < sgc->length) { + size_t copy_size; + size_t bytes_left = sgc->length - bytes_copied; + size_t offset = sgc->offset + bytes_copied; + + /* + * We copy up to the fixup (pointed to by pf) + */ + copy_size = pf ? min(bytes_left, (size_t)pf->offset - offset) + : bytes_left; + if (!ret && copy_size) + ret = binder_alloc_copy_user_to_buffer( + alloc, buffer, + offset, + sgc->sender_uaddr + bytes_copied, + copy_size); + bytes_copied += copy_size; + if (copy_size != bytes_left) { + BUG_ON(!pf); + /* we stopped at a fixup offset */ + if (pf->skip_size) { + /* + * we are just skipping. This is for + * BINDER_TYPE_FDA where the translated + * fds will be fixed up when we get + * to target context. + */ + bytes_copied += pf->skip_size; + } else { + /* apply the fixup indicated by pf */ + if (!ret) + ret = binder_alloc_copy_to_buffer( + alloc, buffer, + pf->offset, + &pf->fixup_data, + sizeof(pf->fixup_data)); + bytes_copied += sizeof(pf->fixup_data); + } + list_del(&pf->node); + kfree(pf); + pf = list_first_entry_or_null(pf_head, + struct binder_ptr_fixup, node); + } + } + list_del(&sgc->node); + kfree(sgc); + } + list_for_each_entry_safe(pf, tmppf, pf_head, node) { + BUG_ON(pf->skip_size == 0); + list_del(&pf->node); + kfree(pf); + } + BUG_ON(!list_empty(sgc_head)); + + return ret > 0 ? -EINVAL : ret; +} + +/** + * binder_cleanup_deferred_txn_lists() - free specified lists + * @sgc_head: list_head of scatter-gather copy list + * @pf_head: list_head of pointer fixup list + * + * Called to clean up @sgc_head and @pf_head if there is an + * error. + */ +static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head, + struct list_head *pf_head) +{ + struct binder_sg_copy *sgc, *tmpsgc; + struct binder_ptr_fixup *pf, *tmppf; + + list_for_each_entry_safe(sgc, tmpsgc, sgc_head, node) { + list_del(&sgc->node); + kfree(sgc); + } + list_for_each_entry_safe(pf, tmppf, pf_head, node) { + list_del(&pf->node); + kfree(pf); + } +} + +/** + * binder_defer_copy() - queue a scatter-gather buffer for copy + * @sgc_head: list_head of scatter-gather copy list + * @offset: binder buffer offset in target process + * @sender_uaddr: user address in source process + * @length: bytes to copy + * + * Specify a scatter-gather block to be copied. The actual copy must + * be deferred until all the needed fixups are identified and queued. + * Then the copy and fixups are done together so un-translated values + * from the source are never visible in the target buffer. + * + * We are guaranteed that repeated calls to this function will have + * monotonically increasing @offset values so the list will naturally + * be ordered. + * + * Return: 0=success, else -errno + */ +static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset, + const void __user *sender_uaddr, size_t length) +{ + struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL); + + if (!bc) + return -ENOMEM; + + bc->offset = offset; + bc->sender_uaddr = sender_uaddr; + bc->length = length; + INIT_LIST_HEAD(&bc->node); + + /* + * We are guaranteed that the deferred copies are in-order + * so just add to the tail. + */ + list_add_tail(&bc->node, sgc_head); + + return 0; +} + +/** + * binder_add_fixup() - queue a fixup to be applied to sg copy + * @pf_head: list_head of binder ptr fixup list + * @offset: binder buffer offset in target process + * @fixup: bytes to be copied for fixup + * @skip_size: bytes to skip when copying (fixup will be applied later) + * + * Add the specified fixup to a list ordered by @offset. When copying + * the scatter-gather buffers, the fixup will be copied instead of + * data from the source buffer. For BINDER_TYPE_FDA fixups, the fixup + * will be applied later (in target process context), so we just skip + * the bytes specified by @skip_size. If @skip_size is 0, we copy the + * value in @fixup. + * + * This function is called *mostly* in @offset order, but there are + * exceptions. Since out-of-order inserts are relatively uncommon, + * we insert the new element by searching backward from the tail of + * the list. + * + * Return: 0=success, else -errno + */ +static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset, + binder_uintptr_t fixup, size_t skip_size) +{ + struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL); + struct binder_ptr_fixup *tmppf; + + if (!pf) + return -ENOMEM; + + pf->offset = offset; + pf->fixup_data = fixup; + pf->skip_size = skip_size; + INIT_LIST_HEAD(&pf->node); + + /* Fixups are *mostly* added in-order, but there are some + * exceptions. Look backwards through list for insertion point. + */ + list_for_each_entry_reverse(tmppf, pf_head, node) { + if (tmppf->offset < pf->offset) { + list_add(&pf->node, &tmppf->node); + return 0; + } + } + /* + * if we get here, then the new offset is the lowest so + * insert at the head + */ + list_add(&pf->node, pf_head); + return 0; +} + +static int binder_translate_fd_array(struct list_head *pf_head, + struct binder_fd_array_object *fda, + const void __user *sender_ubuffer, struct binder_buffer_object *parent, + struct binder_buffer_object *sender_uparent, struct binder_transaction *t, struct binder_thread *thread, struct binder_transaction *in_reply_to) { binder_size_t fdi, fd_buf_size; binder_size_t fda_offset; + const void __user *sender_ufda_base; struct binder_proc *proc = thread->proc; - struct binder_proc *target_proc = t->to_proc; + int ret; + + if (fda->num_fds == 0) + return 0; fd_buf_size = sizeof(u32) * fda->num_fds; if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { @@ -2655,29 +2943,36 @@ */ fda_offset = (parent->buffer - (uintptr_t)t->buffer->user_data) + fda->parent_offset; - if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32))) { + sender_ufda_base = (void __user *)(uintptr_t)sender_uparent->buffer + + fda->parent_offset; + + if (!IS_ALIGNED((unsigned long)fda_offset, sizeof(u32)) || + !IS_ALIGNED((unsigned long)sender_ufda_base, sizeof(u32))) { binder_user_error("%d:%d parent offset not aligned correctly.\n", proc->pid, thread->pid); return -EINVAL; } + ret = binder_add_fixup(pf_head, fda_offset, 0, fda->num_fds * sizeof(u32)); + if (ret) + return ret; + for (fdi = 0; fdi < fda->num_fds; fdi++) { u32 fd; - int ret; binder_size_t offset = fda_offset + fdi * sizeof(fd); + binder_size_t sender_uoffset = fdi * sizeof(fd); - ret = binder_alloc_copy_from_buffer(&target_proc->alloc, - &fd, t->buffer, - offset, sizeof(fd)); + ret = copy_from_user(&fd, sender_ufda_base + sender_uoffset, sizeof(fd)); if (!ret) ret = binder_translate_fd(fd, offset, t, thread, in_reply_to); - if (ret < 0) - return ret; + if (ret) + return ret > 0 ? -EINVAL : ret; } return 0; } -static int binder_fixup_parent(struct binder_transaction *t, +static int binder_fixup_parent(struct list_head *pf_head, + struct binder_transaction *t, struct binder_thread *thread, struct binder_buffer_object *bp, binder_size_t off_start_offset, @@ -2723,14 +3018,7 @@ } buffer_offset = bp->parent_offset + (uintptr_t)parent->buffer - (uintptr_t)b->user_data; - if (binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset, - &bp->buffer, sizeof(bp->buffer))) { - binder_user_error("%d:%d got transaction with invalid parent offset\n", - proc->pid, thread->pid); - return -EINVAL; - } - - return 0; + return binder_add_fixup(pf_head, buffer_offset, bp->buffer, 0); } /** @@ -2851,6 +3139,7 @@ binder_size_t off_start_offset, off_end_offset; binder_size_t off_min; binder_size_t sg_buf_offset, sg_buf_end_offset; + binder_size_t user_offset = 0; struct binder_proc *target_proc = NULL; struct binder_thread *target_thread = NULL; struct binder_node *target_node = NULL; @@ -2865,6 +3154,12 @@ int t_debug_id = atomic_inc_return(&binder_last_id); char *secctx = NULL; u32 secctx_sz = 0; + struct list_head sgc_head; + struct list_head pf_head; + const void __user *user_buffer = (const void __user *) + (uintptr_t)tr->data.ptr.buffer; + INIT_LIST_HEAD(&sgc_head); + INIT_LIST_HEAD(&pf_head); e = binder_transaction_log_add(&binder_transaction_log); e->debug_id = t_debug_id; @@ -2984,8 +3279,14 @@ goto err_dead_binder; } e->to_node = target_node->debug_id; - if (security_binder_transaction(proc->tsk, - target_proc->tsk) < 0) { + if (WARN_ON(proc == target_proc)) { + return_error = BR_FAILED_REPLY; + return_error_param = -EINVAL; + return_error_line = __LINE__; + goto err_invalid_target_handle; + } + if (security_binder_transaction(proc->cred, + target_proc->cred) < 0) { return_error = BR_FAILED_REPLY; return_error_param = -EPERM; return_error_line = __LINE__; @@ -3111,7 +3412,7 @@ u32 secid; size_t added_size; - security_task_getsecid(proc->tsk, &secid); + security_cred_getsecid(proc->cred, &secid); ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); if (ret) { return_error = BR_FAILED_REPLY; @@ -3167,23 +3468,11 @@ t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; + t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); trace_binder_transaction_alloc_buf(t->buffer); if (binder_alloc_copy_user_to_buffer( &target_proc->alloc, - t->buffer, 0, - (const void __user *) - (uintptr_t)tr->data.ptr.buffer, - tr->data_size)) { - binder_user_error("%d:%d got transaction with invalid data ptr\n", - proc->pid, thread->pid); - return_error = BR_FAILED_REPLY; - return_error_param = -EFAULT; - return_error_line = __LINE__; - goto err_copy_data_failed; - } - if (binder_alloc_copy_user_to_buffer( - &target_proc->alloc, t->buffer, ALIGN(tr->data_size, sizeof(void *)), (const void __user *) @@ -3226,6 +3515,7 @@ size_t object_size; struct binder_object object; binder_size_t object_offset; + binder_size_t copy_size; if (binder_alloc_copy_from_buffer(&target_proc->alloc, &object_offset, @@ -3237,8 +3527,28 @@ return_error_line = __LINE__; goto err_bad_offset; } - object_size = binder_get_object(target_proc, t->buffer, - object_offset, &object); + + /* + * Copy the source user buffer up to the next object + * that will be processed. + */ + copy_size = object_offset - user_offset; + if (copy_size && (user_offset > object_offset || + object_offset > tr->data_size || + binder_alloc_copy_user_to_buffer( + &target_proc->alloc, + t->buffer, user_offset, + user_buffer + user_offset, + copy_size))) { + binder_user_error("%d:%d got transaction with invalid data ptr\n", + proc->pid, thread->pid); + return_error = BR_FAILED_REPLY; + return_error_param = -EFAULT; + return_error_line = __LINE__; + goto err_copy_data_failed; + } + object_size = binder_get_object(target_proc, user_buffer, + t->buffer, object_offset, &object); if (object_size == 0 || object_offset < off_min) { binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n", proc->pid, thread->pid, @@ -3250,6 +3560,11 @@ return_error_line = __LINE__; goto err_bad_offset; } + /* + * Set offset to the next buffer fragment to be + * copied + */ + user_offset = object_offset + object_size; hdr = &object.hdr; off_min = object_offset + object_size; @@ -3312,9 +3627,11 @@ case BINDER_TYPE_FDA: { struct binder_object ptr_object; binder_size_t parent_offset; + struct binder_object user_object; + size_t user_parent_size; struct binder_fd_array_object *fda = to_binder_fd_array_object(hdr); - size_t num_valid = (buffer_offset - off_start_offset) * + size_t num_valid = (buffer_offset - off_start_offset) / sizeof(binder_size_t); struct binder_buffer_object *parent = binder_validate_ptr(target_proc, t->buffer, @@ -3343,11 +3660,35 @@ return_error_line = __LINE__; goto err_bad_parent; } - ret = binder_translate_fd_array(fda, parent, t, thread, - in_reply_to); - if (ret < 0) { + /* + * We need to read the user version of the parent + * object to get the original user offset + */ + user_parent_size = + binder_get_object(proc, user_buffer, t->buffer, + parent_offset, &user_object); + if (user_parent_size != sizeof(user_object.bbo)) { + binder_user_error("%d:%d invalid ptr object size: %zd vs %zd\n", + proc->pid, thread->pid, + user_parent_size, + sizeof(user_object.bbo)); return_error = BR_FAILED_REPLY; - return_error_param = ret; + return_error_param = -EINVAL; + return_error_line = __LINE__; + goto err_bad_parent; + } + ret = binder_translate_fd_array(&pf_head, fda, + user_buffer, parent, + &user_object.bbo, t, + thread, in_reply_to); + if (!ret) + ret = binder_alloc_copy_to_buffer(&target_proc->alloc, + t->buffer, + object_offset, + fda, sizeof(*fda)); + if (ret) { + return_error = BR_FAILED_REPLY; + return_error_param = ret > 0 ? -EINVAL : ret; return_error_line = __LINE__; goto err_translate_failed; } @@ -3369,28 +3710,24 @@ return_error_line = __LINE__; goto err_bad_offset; } - if (binder_alloc_copy_user_to_buffer( - &target_proc->alloc, - t->buffer, - sg_buf_offset, - (const void __user *) - (uintptr_t)bp->buffer, - bp->length)) { - binder_user_error("%d:%d got transaction with invalid offsets ptr\n", - proc->pid, thread->pid); - return_error_param = -EFAULT; + ret = binder_defer_copy(&sgc_head, sg_buf_offset, + (const void __user *)(uintptr_t)bp->buffer, + bp->length); + if (ret) { return_error = BR_FAILED_REPLY; + return_error_param = ret; return_error_line = __LINE__; - goto err_copy_data_failed; + goto err_translate_failed; } /* Fixup buffer pointer to target proc address space */ bp->buffer = (uintptr_t) t->buffer->user_data + sg_buf_offset; sg_buf_offset += ALIGN(bp->length, sizeof(u64)); - num_valid = (buffer_offset - off_start_offset) * + num_valid = (buffer_offset - off_start_offset) / sizeof(binder_size_t); - ret = binder_fixup_parent(t, thread, bp, + ret = binder_fixup_parent(&pf_head, t, + thread, bp, off_start_offset, num_valid, last_fixup_obj_off, @@ -3417,6 +3754,30 @@ goto err_bad_object_type; } } + /* Done processing objects, copy the rest of the buffer */ + if (binder_alloc_copy_user_to_buffer( + &target_proc->alloc, + t->buffer, user_offset, + user_buffer + user_offset, + tr->data_size - user_offset)) { + binder_user_error("%d:%d got transaction with invalid data ptr\n", + proc->pid, thread->pid); + return_error = BR_FAILED_REPLY; + return_error_param = -EFAULT; + return_error_line = __LINE__; + goto err_copy_data_failed; + } + + ret = binder_do_deferred_txn_copies(&target_proc->alloc, t->buffer, + &sgc_head, &pf_head); + if (ret) { + binder_user_error("%d:%d got transaction with invalid offsets ptr\n", + proc->pid, thread->pid); + return_error = BR_FAILED_REPLY; + return_error_param = ret; + return_error_line = __LINE__; + goto err_copy_data_failed; + } tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE; t->work.type = BINDER_WORK_TRANSACTION; @@ -3483,9 +3844,10 @@ err_bad_offset: err_bad_parent: err_copy_data_failed: + binder_cleanup_deferred_txn_lists(&sgc_head, &pf_head); binder_free_txn_fixups(t); trace_binder_transaction_failed_buffer_release(t->buffer); - binder_transaction_buffer_release(target_proc, t->buffer, + binder_transaction_buffer_release(target_proc, NULL, t->buffer, buffer_offset, true); if (target_node) binder_dec_node_tmpref(target_node); @@ -3555,6 +3917,7 @@ * binder_free_buf() - free the specified buffer * @proc: binder proc that owns buffer * @buffer: buffer to be freed + * @is_failure: failed to send transaction * * If buffer for an async transaction, enqueue the next async * transaction from the node. @@ -3562,7 +3925,9 @@ * Cleanup buffer and free it. */ static void -binder_free_buf(struct binder_proc *proc, struct binder_buffer *buffer) +binder_free_buf(struct binder_proc *proc, + struct binder_thread *thread, + struct binder_buffer *buffer, bool is_failure) { binder_inner_proc_lock(proc); if (buffer->transaction) { @@ -3590,7 +3955,7 @@ binder_node_inner_unlock(buf_node); } trace_binder_transaction_buffer_release(buffer); - binder_transaction_buffer_release(proc, buffer, 0, false); + binder_release_entire_buffer(proc, thread, buffer, is_failure); binder_alloc_free_buf(&proc->alloc, buffer); } @@ -3637,10 +4002,17 @@ struct binder_node *ctx_mgr_node; mutex_lock(&context->context_mgr_node_lock); ctx_mgr_node = context->binder_context_mgr_node; - if (ctx_mgr_node) + if (ctx_mgr_node) { + if (ctx_mgr_node->proc == proc) { + binder_user_error("%d:%d context manager tried to acquire desc 0\n", + proc->pid, thread->pid); + mutex_unlock(&context->context_mgr_node_lock); + return -EINVAL; + } ret = binder_inc_ref_for_node( proc, ctx_mgr_node, strong, NULL, &rdata); + } mutex_unlock(&context->context_mgr_node_lock); } if (ret) @@ -3784,7 +4156,7 @@ proc->pid, thread->pid, (u64)data_ptr, buffer->debug_id, buffer->transaction ? "active" : "finished"); - binder_free_buf(proc, buffer); + binder_free_buf(proc, thread, buffer, false); break; } @@ -4472,7 +4844,7 @@ buffer->transaction = NULL; binder_cleanup_transaction(t, "fd fixups failed", BR_FAILED_REPLY); - binder_free_buf(proc, buffer); + binder_free_buf(proc, thread, buffer, true); binder_debug(BINDER_DEBUG_FAILED_TRANSACTION, "%d:%d %stransaction %d fd fixups failed %d/%d, line %d\n", proc->pid, thread->pid, @@ -4578,13 +4950,17 @@ struct list_head *list) { struct binder_work *w; + enum binder_work_type wtype; while (1) { - w = binder_dequeue_work_head(proc, list); + binder_inner_proc_lock(proc); + w = binder_dequeue_work_head_ilocked(list); + wtype = w ? w->type : 0; + binder_inner_proc_unlock(proc); if (!w) return; - switch (w->type) { + switch (wtype) { case BINDER_WORK_TRANSACTION: { struct binder_transaction *t; @@ -4618,9 +4994,11 @@ kfree(death); binder_stats_deleted(BINDER_STAT_DEATH); } break; + case BINDER_WORK_NODE: + break; default: pr_err("unexpected work type, %d, not freed\n", - w->type); + wtype); break; } } @@ -4688,10 +5066,18 @@ static void binder_free_proc(struct binder_proc *proc) { + struct binder_device *device; + BUG_ON(!list_empty(&proc->todo)); BUG_ON(!list_empty(&proc->delivered_death)); + device = container_of(proc->context, struct binder_device, context); + if (refcount_dec_and_test(&device->ref)) { + kfree(proc->context->name); + kfree(device); + } binder_alloc_deferred_release(&proc->alloc); put_task_struct(proc->tsk); + put_cred(proc->cred); binder_stats_deleted(BINDER_STAT_PROC); kfree(proc); } @@ -4768,23 +5154,20 @@ __release(&t->lock); /* - * If this thread used poll, make sure we remove the waitqueue - * from any epoll data structures holding it with POLLFREE. - * waitqueue_active() is safe to use here because we're holding - * the inner lock. + * If this thread used poll, make sure we remove the waitqueue from any + * poll data structures holding it. */ - if ((thread->looper & BINDER_LOOPER_STATE_POLL) && - waitqueue_active(&thread->wait)) { - wake_up_poll(&thread->wait, EPOLLHUP | POLLFREE); - } + if (thread->looper & BINDER_LOOPER_STATE_POLL) + wake_up_pollfree(&thread->wait); binder_inner_proc_unlock(thread->proc); /* - * This is needed to avoid races between wake_up_poll() above and - * and ep_remove_waitqueue() called for other reasons (eg the epoll file - * descriptor being closed); ep_remove_waitqueue() holds an RCU read - * lock, so we can be sure it's done after calling synchronize_rcu(). + * This is needed to avoid races between wake_up_pollfree() above and + * someone else removing the last entry from the queue for other reasons + * (e.g. ep_remove_wait_queue() being called due to an epoll file + * descriptor being closed). Such other users hold an RCU read lock, so + * we can be sure they're done after we call synchronize_rcu(). */ if (thread->looper & BINDER_LOOPER_STATE_POLL) synchronize_rcu(); @@ -4805,7 +5188,7 @@ thread = binder_get_thread(proc); if (!thread) - return POLLERR; + return EPOLLERR; binder_inner_proc_lock(thread->proc); thread->looper |= BINDER_LOOPER_STATE_POLL; @@ -4902,7 +5285,7 @@ ret = -EBUSY; goto out; } - ret = security_binder_set_context_mgr(proc->tsk); + ret = security_binder_set_context_mgr(proc->cred); if (ret < 0) goto out; if (uid_valid(context->binder_context_mgr_uid)) { @@ -5028,7 +5411,7 @@ goto err; break; case BINDER_SET_MAX_THREADS: { - int max_threads; + u32 max_threads; if (copy_from_user(&max_threads, ubuf, sizeof(max_threads))) { @@ -5203,10 +5586,11 @@ static int binder_open(struct inode *nodp, struct file *filp) { - struct binder_proc *proc; + struct binder_proc *proc, *itr; struct binder_device *binder_dev; struct binderfs_info *info; struct dentry *binder_binderfs_dir_entry_proc = NULL; + bool existing_pid = false; binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__, current->group_leader->pid, current->pid); @@ -5218,6 +5602,7 @@ spin_lock_init(&proc->outer_lock); get_task_struct(current->group_leader); proc->tsk = current->group_leader; + proc->cred = get_cred(filp->f_cred); INIT_LIST_HEAD(&proc->todo); proc->default_priority = task_nice(current); /* binderfs stashes devices in i_private */ @@ -5229,6 +5614,7 @@ binder_dev = container_of(filp->private_data, struct binder_device, miscdev); } + refcount_inc(&binder_dev->ref); proc->context = &binder_dev->context; binder_alloc_init(&proc->alloc); @@ -5239,19 +5625,24 @@ filp->private_data = proc; mutex_lock(&binder_procs_lock); + hlist_for_each_entry(itr, &binder_procs, proc_node) { + if (itr->pid == proc->pid) { + existing_pid = true; + break; + } + } hlist_add_head(&proc->proc_node, &binder_procs); mutex_unlock(&binder_procs_lock); - if (binder_debugfs_dir_entry_proc) { + if (binder_debugfs_dir_entry_proc && !existing_pid) { char strbuf[11]; snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); /* - * proc debug entries are shared between contexts, so - * this will fail if the process tries to open the driver - * again with a different context. The priting code will - * anyway print all contexts that a given PID has, so this - * is not a problem. + * proc debug entries are shared between contexts. + * Only create for the first PID to avoid debugfs log spamming + * The printing code will anyway print all contexts for a given + * PID so this is not a problem. */ proc->debugfs_entry = debugfs_create_file(strbuf, 0444, binder_debugfs_dir_entry_proc, @@ -5259,19 +5650,16 @@ &proc_fops); } - if (binder_binderfs_dir_entry_proc) { + if (binder_binderfs_dir_entry_proc && !existing_pid) { char strbuf[11]; struct dentry *binderfs_entry; snprintf(strbuf, sizeof(strbuf), "%u", proc->pid); /* * Similar to debugfs, the process specific log file is shared - * between contexts. If the file has already been created for a - * process, the following binderfs_create_file() call will - * fail with error code EEXIST if another context of the same - * process invoked binder_open(). This is ok since same as - * debugfs, the log file will contain information on all - * contexts of a given PID. + * between contexts. Only create for the first PID. + * This is ok since same as debugfs, the log file will contain + * information on all contexts of a given PID. */ binderfs_entry = binderfs_create_file(binder_binderfs_dir_entry_proc, strbuf, &proc_fops, (void *)(unsigned long)proc->pid); @@ -5281,10 +5669,8 @@ int error; error = PTR_ERR(binderfs_entry); - if (error != -EEXIST) { - pr_warn("Unable to create file %s in binderfs (error %d)\n", - strbuf, error); - } + pr_warn("Unable to create file %s in binderfs (error %d)\n", + strbuf, error); } } @@ -6063,6 +6449,7 @@ .open = binder_open, .flush = binder_flush, .release = binder_release, + .may_pollfree = true, }; static int __init init_binder_device(const char *name) @@ -6078,6 +6465,7 @@ binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; binder_device->miscdev.name = name; + refcount_set(&binder_device->ref, 1); binder_device->context.binder_context_mgr_uid = INVALID_UID; binder_device->context.name = name; mutex_init(&binder_device->context.context_mgr_node_lock); @@ -6178,13 +6566,25 @@ err_alloc_device_names_failed: debugfs_remove_recursive(binder_debugfs_dir_entry_root); + binder_alloc_shrinker_exit(); return ret; } -device_initcall(binder_init); +module_init(binder_init); +/* + * binder will have no exit function since binderfs instances can be mounted + * multiple times and also in user namespaces finding and destroying them all + * is not feasible without introducing insane locking. Just ignoring existing + * instances on module unload also wouldn't work since we would loose track of + * what major numer was dynamically allocated and also what minor numbers are + * already given out. So this would get us into all kinds of issues with device + * number reuse. So simply don't allow unloading unless we are forced to do so. + */ + +MODULE_AUTHOR("Google, Inc."); +MODULE_DESCRIPTION("Driver for Android binder device"); +MODULE_LICENSE("GPL v2"); #define CREATE_TRACE_POINTS #include "binder_trace.h" - -MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/android/binder_alloc.c +++ linux-oracle-5.4.0/drivers/android/binder_alloc.c @@ -38,8 +38,7 @@ }; static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR; -module_param_named(debug_mask, binder_alloc_debug_mask, - uint, 0644); +module_param_named(alloc_debug_mask, binder_alloc_debug_mask, uint, 0644); #define binder_alloc_debug(mask, x...) \ do { \ @@ -212,7 +211,7 @@ mm = alloc->vma_vm_mm; if (mm) { - down_read(&mm->mmap_sem); + down_write(&mm->mmap_sem); vma = alloc->vma; } @@ -271,14 +270,13 @@ /* vm_insert_page does not seem to increment the refcount */ } if (mm) { - up_read(&mm->mmap_sem); - mmput(mm); + up_write(&mm->mmap_sem); + mmput_async(mm); } return 0; free_range: - for (page_addr = end - PAGE_SIZE; page_addr >= start; - page_addr -= PAGE_SIZE) { + for (page_addr = end - PAGE_SIZE; 1; page_addr -= PAGE_SIZE) { bool ret; size_t index; @@ -291,6 +289,8 @@ WARN_ON(!ret); trace_binder_free_lru_end(alloc, index); + if (page_addr == start) + break; continue; err_vm_insert_page_failed: @@ -298,12 +298,13 @@ page->page_ptr = NULL; err_alloc_page_failed: err_page_ptr_cleared: - ; + if (page_addr == start) + break; } err_no_vma: if (mm) { - up_read(&mm->mmap_sem); - mmput(mm); + up_write(&mm->mmap_sem); + mmput_async(mm); } return vma ? -ENOMEM : -ESRCH; } @@ -376,17 +377,17 @@ alloc->pid, extra_buffers_size); return ERR_PTR(-EINVAL); } - if (is_async && - alloc->free_async_space < size + sizeof(struct binder_buffer)) { + + /* Pad 0-size buffers so they get assigned unique addresses */ + size = max(size, sizeof(void *)); + + if (is_async && alloc->free_async_space < size) { binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: binder_alloc_buf size %zd failed, no async space left\n", alloc->pid, size); return ERR_PTR(-ENOSPC); } - /* Pad 0-size buffers so they get assigned unique addresses */ - size = max(size, sizeof(void *)); - while (n) { buffer = rb_entry(n, struct binder_buffer, rb_node); BUG_ON(!buffer->free); @@ -486,7 +487,7 @@ buffer->async_transaction = is_async; buffer->extra_buffers_size = extra_buffers_size; if (is_async) { - alloc->free_async_space -= size + sizeof(struct binder_buffer); + alloc->free_async_space -= size; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, "%d: binder_alloc_buf size %zd async free %zd\n", alloc->pid, size, alloc->free_async_space); @@ -513,7 +514,7 @@ * is the sum of the three given sizes (each rounded up to * pointer-sized boundary) * - * Return: The allocated buffer or %NULL if error + * Return: The allocated buffer or %ERR_PTR(-errno) if error */ struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, size_t data_size, @@ -611,8 +612,7 @@ BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); if (buffer->async_transaction) { - alloc->free_async_space += size + sizeof(struct binder_buffer); - + alloc->free_async_space += buffer_size; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, "%d: binder_free_buf size %zd async free %zd\n", alloc->pid, size, alloc->free_async_space); @@ -645,6 +645,8 @@ binder_insert_free_buffer(alloc, buffer); } +static void binder_alloc_clear_buf(struct binder_alloc *alloc, + struct binder_buffer *buffer); /** * binder_alloc_free_buf() - free a binder buffer * @alloc: binder_alloc for this proc @@ -655,6 +657,18 @@ void binder_alloc_free_buf(struct binder_alloc *alloc, struct binder_buffer *buffer) { + /* + * We could eliminate the call to binder_alloc_clear_buf() + * from binder_alloc_deferred_release() by moving this to + * binder_free_buf_locked(). However, that could + * increase contention for the alloc mutex if clear_on_free + * is used frequently for large buffers. The mutex is not + * needed for correctness here. + */ + if (buffer->clear_on_free) { + binder_alloc_clear_buf(alloc, buffer); + buffer->clear_on_free = false; + } mutex_lock(&alloc->mutex); binder_free_buf_locked(alloc, buffer); mutex_unlock(&alloc->mutex); @@ -681,17 +695,17 @@ struct binder_buffer *buffer; mutex_lock(&binder_alloc_mmap_lock); - if (alloc->buffer) { + if (alloc->buffer_size) { ret = -EBUSY; failure_string = "already mapped"; goto err_already_mapped; } + alloc->buffer_size = min_t(unsigned long, vma->vm_end - vma->vm_start, + SZ_4M); + mutex_unlock(&binder_alloc_mmap_lock); alloc->buffer = (void __user *)vma->vm_start; - mutex_unlock(&binder_alloc_mmap_lock); - alloc->buffer_size = min_t(unsigned long, vma->vm_end - vma->vm_start, - SZ_4M); alloc->pages = kcalloc(alloc->buffer_size / PAGE_SIZE, sizeof(alloc->pages[0]), GFP_KERNEL); @@ -722,8 +736,9 @@ kfree(alloc->pages); alloc->pages = NULL; err_alloc_pages_failed: - mutex_lock(&binder_alloc_mmap_lock); alloc->buffer = NULL; + mutex_lock(&binder_alloc_mmap_lock); + alloc->buffer_size = 0; err_already_mapped: mutex_unlock(&binder_alloc_mmap_lock); binder_alloc_debug(BINDER_DEBUG_USER_ERROR, @@ -750,6 +765,10 @@ /* Transaction should already have been freed */ BUG_ON(buffer->transaction); + if (buffer->clear_on_free) { + binder_alloc_clear_buf(alloc, buffer); + buffer->clear_on_free = false; + } binder_free_buf_locked(alloc, buffer); buffers++; } @@ -841,14 +860,20 @@ int free = 0; mutex_lock(&alloc->mutex); - for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { - page = &alloc->pages[i]; - if (!page->page_ptr) - free++; - else if (list_empty(&page->lru)) - active++; - else - lru++; + /* + * Make sure the binder_alloc is fully initialized, otherwise we might + * read inconsistent state. + */ + if (binder_alloc_get_vma(alloc) != NULL) { + for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) { + page = &alloc->pages[i]; + if (!page->page_ptr) + free++; + else if (list_empty(&page->lru)) + active++; + else + lru++; + } } mutex_unlock(&alloc->mutex); seq_printf(m, " pages: %d:%d:%d\n", active, lru, free); @@ -926,7 +951,9 @@ goto err_mmget; if (!down_read_trylock(&mm->mmap_sem)) goto err_down_read_mmap_sem_failed; - vma = binder_alloc_get_vma(alloc); + vma = find_vma(mm, page_addr); + if (vma && vma != binder_alloc_get_vma(alloc)) + goto err_invalid_vma; list_lru_isolate(lru, item); spin_unlock(lock); @@ -939,7 +966,7 @@ trace_binder_unmap_user_end(alloc, index); } up_read(&mm->mmap_sem); - mmput(mm); + mmput_async(mm); trace_binder_unmap_kernel_start(alloc, index); @@ -952,6 +979,8 @@ mutex_unlock(&alloc->mutex); return LRU_REMOVED_RETRY; +err_invalid_vma: + up_read(&mm->mmap_sem); err_down_read_mmap_sem_failed: mmput_async(mm); err_mmget: @@ -1010,6 +1039,12 @@ return ret; } +void binder_alloc_shrinker_exit(void) +{ + unregister_shrinker(&binder_shrinker); + list_lru_destroy(&binder_alloc_lru); +} + /** * check_buffer() - verify that buffer/offset is safe to access * @alloc: binder_alloc for this proc @@ -1078,6 +1113,36 @@ } /** + * binder_alloc_clear_buf() - zero out buffer + * @alloc: binder_alloc for this proc + * @buffer: binder buffer to be cleared + * + * memset the given buffer to 0 + */ +static void binder_alloc_clear_buf(struct binder_alloc *alloc, + struct binder_buffer *buffer) +{ + size_t bytes = binder_alloc_buffer_size(alloc, buffer); + binder_size_t buffer_offset = 0; + + while (bytes) { + unsigned long size; + struct page *page; + pgoff_t pgoff; + void *kptr; + + page = binder_alloc_get_page(alloc, buffer, + buffer_offset, &pgoff); + size = min_t(size_t, bytes, PAGE_SIZE - pgoff); + kptr = kmap(page) + pgoff; + memset(kptr, 0, size); + kunmap(page); + bytes -= size; + buffer_offset += size; + } +} + +/** * binder_alloc_copy_user_to_buffer() - copy src user to tgt user * @alloc: binder_alloc for this proc * @buffer: binder buffer to be accessed --- linux-oracle-5.4.0.orig/drivers/android/binder_alloc.h +++ linux-oracle-5.4.0/drivers/android/binder_alloc.h @@ -6,6 +6,7 @@ #ifndef _LINUX_BINDER_ALLOC_H #define _LINUX_BINDER_ALLOC_H +#include #include #include #include @@ -23,6 +24,7 @@ * @entry: entry alloc->buffers * @rb_node: node for allocated_buffers/free_buffers rb trees * @free: %true if buffer is free + * @clear_on_free: %true if buffer must be zeroed after use * @allow_user_free: %true if user is allowed to free buffer * @async_transaction: %true if buffer is in use for an async txn * @debug_id: unique ID for debugging @@ -40,9 +42,10 @@ struct rb_node rb_node; /* free entry by size or allocated entry */ /* by address */ unsigned free:1; + unsigned clear_on_free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned debug_id:29; + unsigned debug_id:28; struct binder_transaction *transaction; @@ -105,7 +108,7 @@ size_t pages_high; }; -#ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST +#if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_SELFTEST) void binder_selftest_alloc(struct binder_alloc *alloc); #else static inline void binder_selftest_alloc(struct binder_alloc *alloc) {} @@ -120,6 +123,7 @@ int is_async); extern void binder_alloc_init(struct binder_alloc *alloc); extern int binder_alloc_shrinker_init(void); +extern void binder_alloc_shrinker_exit(void); extern void binder_alloc_vma_close(struct binder_alloc *alloc); extern struct binder_buffer * binder_alloc_prepare_to_free(struct binder_alloc *alloc, --- linux-oracle-5.4.0.orig/drivers/android/binder_internal.h +++ linux-oracle-5.4.0/drivers/android/binder_internal.h @@ -5,9 +5,11 @@ #include #include +#include #include #include #include +#include #include #include #include @@ -33,6 +35,7 @@ struct miscdevice miscdev; struct binder_context context; struct inode *binderfs_inode; + refcount_t ref; }; /** @@ -73,7 +76,7 @@ extern char *binder_devices_param; -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern bool is_binderfs_device(const struct inode *inode); extern struct dentry *binderfs_create_file(struct dentry *dir, const char *name, const struct file_operations *fops, @@ -94,7 +97,7 @@ static inline void binderfs_remove_file(struct dentry *dentry) {} #endif -#ifdef CONFIG_ANDROID_BINDERFS +#if IS_ENABLED(CONFIG_ANDROID_BINDERFS) extern int __init init_binderfs(void); #else static inline int __init init_binderfs(void) --- linux-oracle-5.4.0.orig/drivers/android/binderfs.c +++ linux-oracle-5.4.0/drivers/android/binderfs.c @@ -109,7 +109,7 @@ struct super_block *sb = ref_inode->i_sb; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -154,6 +154,7 @@ if (!name) goto err; + refcount_set(&device->ref, 1); device->binderfs_inode = inode; device->context.binder_context_mgr_uid = INVALID_UID; device->context.name = name; @@ -257,8 +258,10 @@ ida_free(&binderfs_minors, device->miscdev.minor); mutex_unlock(&binderfs_minors_mutex); - kfree(device->context.name); - kfree(device); + if (refcount_dec_and_test(&device->ref)) { + kfree(device->context.name); + kfree(device); + } } /** @@ -405,7 +408,7 @@ struct dentry *root = sb->s_root; struct binderfs_info *info = sb->s_fs_info; #if defined(CONFIG_IPC_NS) - bool use_reserve = (info->ipc_ns == &init_ipc_ns); + bool use_reserve = (info->ipc_ns == show_init_ipc_ns()); #else bool use_reserve = true; #endif @@ -445,6 +448,7 @@ inode->i_uid = info->root_uid; inode->i_gid = info->root_gid; + refcount_set(&device->ref, 1); device->binderfs_inode = inode; device->miscdev.minor = minor; @@ -683,7 +687,7 @@ return -ENOMEM; info = sb->s_fs_info; - info->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); + info->ipc_ns = get_ipc_ns_exported(current->nsproxy->ipc_ns); ret = binderfs_parse_mount_opts(data, &info->mount_opts); if (ret) --- linux-oracle-5.4.0.orig/drivers/ata/acard-ahci.c +++ linux-oracle-5.4.0/drivers/ata/acard-ahci.c @@ -56,7 +56,7 @@ __le32 size; /* bit 31 (EOT) max==0x10000 (64k) */ }; -static void acard_ahci_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors acard_ahci_qc_prep(struct ata_queued_cmd *qc); static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc); static int acard_ahci_port_start(struct ata_port *ap); static int acard_ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -210,7 +210,7 @@ return si; } -static void acard_ahci_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors acard_ahci_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ahci_port_priv *pp = ap->private_data; @@ -248,6 +248,8 @@ opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; ahci_fill_cmd_slot(pp, qc->hw_tag, opts); + + return AC_ERR_OK; } static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc) --- linux-oracle-5.4.0.orig/drivers/ata/ahci.c +++ linux-oracle-5.4.0/drivers/ata/ahci.c @@ -48,6 +48,7 @@ enum board_ids { /* board IDs by feature in alphabetical order */ board_ahci, + board_ahci_43bit_dma, board_ahci_ign_iferr, board_ahci_mobile, board_ahci_nomsi, @@ -80,6 +81,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static void ahci_remove_one(struct pci_dev *dev); +static void ahci_shutdown_one(struct pci_dev *dev); +static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv); static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, @@ -124,6 +127,13 @@ .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, + [board_ahci_43bit_dma] = { + AHCI_HFLAGS (AHCI_HFLAG_43BIT_ONLY), + .flags = AHCI_FLAG_COMMON, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, [board_ahci_ign_iferr] = { AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), .flags = AHCI_FLAG_COMMON, @@ -236,6 +246,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* Intel */ + { PCI_VDEVICE(INTEL, 0x06d6), board_ahci }, /* Comet Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */ { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */ { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */ @@ -392,11 +403,13 @@ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ + { PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */ { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */ { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */ + { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -418,6 +431,7 @@ /* AMD */ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ + { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ /* AMD is using RAID class only for ahci controllers */ { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, @@ -557,11 +571,11 @@ { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */ - /* Asmedia */ + /* ASMedia */ { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ - { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ - { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ + { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci_43bit_dma }, /* ASM1061 */ + { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci_43bit_dma }, /* ASM1061/1062 */ { PCI_VDEVICE(ASMEDIA, 0x0621), board_ahci }, /* ASM1061R */ { PCI_VDEVICE(ASMEDIA, 0x0622), board_ahci }, /* ASM1062R */ @@ -593,6 +607,7 @@ .id_table = ahci_pci_tbl, .probe = ahci_init_one, .remove = ahci_remove_one, + .shutdown = ahci_shutdown_one, .driver = { .pm = &ahci_pci_pm_ops, }, @@ -635,6 +650,25 @@ ahci_save_initial_config(&pdev->dev, hpriv); } +static int ahci_pci_reset_controller(struct ata_host *host) +{ + struct pci_dev *pdev = to_pci_dev(host->dev); + struct ahci_host_priv *hpriv = host->private_data; + int rc; + + rc = ahci_reset_controller(host); + if (rc) + return rc; + + /* + * If platform firmware failed to enable ports, try to enable + * them here. + */ + ahci_intel_pcs_quirk(pdev, hpriv); + + return 0; +} + static void ahci_pci_init_controller(struct ata_host *host) { struct ahci_host_priv *hpriv = host->private_data; @@ -837,7 +871,7 @@ struct ata_host *host = pci_get_drvdata(pdev); int rc; - rc = ahci_reset_controller(host); + rc = ahci_pci_reset_controller(host); if (rc) return rc; ahci_pci_init_controller(host); @@ -872,7 +906,7 @@ ahci_mcp89_apple_enable(pdev); if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = ahci_reset_controller(host); + rc = ahci_pci_reset_controller(host); if (rc) return rc; @@ -887,11 +921,20 @@ #endif /* CONFIG_PM */ -static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) +static int ahci_configure_dma_masks(struct pci_dev *pdev, + struct ahci_host_priv *hpriv) { - const int dma_bits = using_dac ? 64 : 32; + int dma_bits; int rc; + if (hpriv->cap & HOST_CAP_64) { + dma_bits = 64; + if (hpriv->flags & AHCI_HFLAG_43BIT_ONLY) + dma_bits = 43; + } else { + dma_bits = 32; + } + /* * If the device fixup already set the dma_mask to some non-standard * value, don't extend it here. This happens on STA2X11, for example. @@ -1473,7 +1516,7 @@ static void ahci_remap_check(struct pci_dev *pdev, int bar, struct ahci_host_priv *hpriv) { - int i, count = 0; + int i; u32 cap; /* @@ -1494,13 +1537,14 @@ continue; /* We've found a remapped device */ - count++; + hpriv->remapped_nvme++; } - if (!count) + if (!hpriv->remapped_nvme) return; - dev_warn(&pdev->dev, "Found %d remapped NVMe devices.\n", count); + dev_warn(&pdev->dev, "Found %u remapped NVMe devices.\n", + hpriv->remapped_nvme); dev_warn(&pdev->dev, "Switch your BIOS from RAID to AHCI mode to use them.\n"); @@ -1620,6 +1664,18 @@ } } +static ssize_t remapped_nvme_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + + return sprintf(buf, "%u\n", hpriv->remapped_nvme); +} + +static DEVICE_ATTR_RO(remapped_nvme); + static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { unsigned int board_id = ent->driver_data; @@ -1720,11 +1776,20 @@ /* detect remapped nvme devices */ ahci_remap_check(pdev, ahci_pci_bar, hpriv); + sysfs_add_file_to_group(&pdev->dev.kobj, + &dev_attr_remapped_nvme.attr, + NULL); + /* must set flag prior to save config in order to take effect */ if (ahci_broken_devslp(pdev)) hpriv->flags |= AHCI_HFLAG_NO_DEVSLP; #ifdef CONFIG_ARM64 + if (pdev->vendor == PCI_VENDOR_ID_HUAWEI && + pdev->device == 0xa235 && + pdev->revision < 0x30) + hpriv->flags |= AHCI_HFLAG_NO_SXS; + if (pdev->vendor == 0x177d && pdev->device == 0xa01c) hpriv->irq_handler = ahci_thunderx_irq_handler; #endif @@ -1732,12 +1797,6 @@ /* save initial config */ ahci_pci_save_initial_config(pdev, hpriv); - /* - * If platform firmware failed to enable ports, try to enable - * them here. - */ - ahci_intel_pcs_quirk(pdev, hpriv); - /* prepare host */ if (hpriv->cap & HOST_CAP_NCQ) { pi.flags |= ATA_FLAG_NCQ; @@ -1815,6 +1874,15 @@ else dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); + if (!(hpriv->cap & HOST_CAP_PART)) + host->flags |= ATA_HOST_NO_PART; + + if (!(hpriv->cap & HOST_CAP_SSC)) + host->flags |= ATA_HOST_NO_SSC; + + if (!(hpriv->cap2 & HOST_CAP2_SDS)) + host->flags |= ATA_HOST_NO_DEVSLP; + if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); @@ -1843,11 +1911,11 @@ ahci_gtf_filter_workaround(host); /* initialize adapter */ - rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); + rc = ahci_configure_dma_masks(pdev, hpriv); if (rc) return rc; - rc = ahci_reset_controller(host); + rc = ahci_pci_reset_controller(host); if (rc) return rc; @@ -1864,8 +1932,16 @@ return 0; } +static void ahci_shutdown_one(struct pci_dev *pdev) +{ + ata_pci_shutdown_one(pdev); +} + static void ahci_remove_one(struct pci_dev *pdev) { + sysfs_remove_file_from_group(&pdev->dev.kobj, + &dev_attr_remapped_nvme.attr, + NULL); pm_runtime_get_noresume(&pdev->dev); ata_pci_remove_one(pdev); } --- linux-oracle-5.4.0.orig/drivers/ata/ahci.h +++ linux-oracle-5.4.0/drivers/ata/ahci.h @@ -24,6 +24,7 @@ #include #include #include +#include /* Enclosure Management Control */ #define EM_CTRL_MSG_TYPE 0x000f0000 @@ -54,12 +55,12 @@ AHCI_PORT_PRIV_FBS_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + (AHCI_RX_FIS_SZ * 16), - AHCI_IRQ_ON_SG = (1 << 31), - AHCI_CMD_ATAPI = (1 << 5), - AHCI_CMD_WRITE = (1 << 6), - AHCI_CMD_PREFETCH = (1 << 7), - AHCI_CMD_RESET = (1 << 8), - AHCI_CMD_CLR_BUSY = (1 << 10), + AHCI_IRQ_ON_SG = BIT(31), + AHCI_CMD_ATAPI = BIT(5), + AHCI_CMD_WRITE = BIT(6), + AHCI_CMD_PREFETCH = BIT(7), + AHCI_CMD_RESET = BIT(8), + AHCI_CMD_CLR_BUSY = BIT(10), RX_FIS_PIO_SETUP = 0x20, /* offset of PIO Setup FIS data */ RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ @@ -77,37 +78,37 @@ HOST_CAP2 = 0x24, /* host capabilities, extended */ /* HOST_CTL bits */ - HOST_RESET = (1 << 0), /* reset controller; self-clear */ - HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ - HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */ - HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ + HOST_RESET = BIT(0), /* reset controller; self-clear */ + HOST_IRQ_EN = BIT(1), /* global IRQ enable */ + HOST_MRSM = BIT(2), /* MSI Revert to Single Message */ + HOST_AHCI_EN = BIT(31), /* AHCI enabled */ /* HOST_CAP bits */ - HOST_CAP_SXS = (1 << 5), /* Supports External SATA */ - HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ - HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */ - HOST_CAP_PART = (1 << 13), /* Partial state capable */ - HOST_CAP_SSC = (1 << 14), /* Slumber state capable */ - HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */ - HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */ - HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ - HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */ - HOST_CAP_CLO = (1 << 24), /* Command List Override support */ - HOST_CAP_LED = (1 << 25), /* Supports activity LED */ - HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */ - HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */ - HOST_CAP_SNTF = (1 << 29), /* SNotification register */ - HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ - HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ + HOST_CAP_SXS = BIT(5), /* Supports External SATA */ + HOST_CAP_EMS = BIT(6), /* Enclosure Management support */ + HOST_CAP_CCC = BIT(7), /* Command Completion Coalescing */ + HOST_CAP_PART = BIT(13), /* Partial state capable */ + HOST_CAP_SSC = BIT(14), /* Slumber state capable */ + HOST_CAP_PIO_MULTI = BIT(15), /* PIO multiple DRQ support */ + HOST_CAP_FBS = BIT(16), /* FIS-based switching support */ + HOST_CAP_PMP = BIT(17), /* Port Multiplier support */ + HOST_CAP_ONLY = BIT(18), /* Supports AHCI mode only */ + HOST_CAP_CLO = BIT(24), /* Command List Override support */ + HOST_CAP_LED = BIT(25), /* Supports activity LED */ + HOST_CAP_ALPM = BIT(26), /* Aggressive Link PM support */ + HOST_CAP_SSS = BIT(27), /* Staggered Spin-up */ + HOST_CAP_MPS = BIT(28), /* Mechanical presence switch */ + HOST_CAP_SNTF = BIT(29), /* SNotification register */ + HOST_CAP_NCQ = BIT(30), /* Native Command Queueing */ + HOST_CAP_64 = BIT(31), /* PCI DAC (64-bit DMA) support */ /* HOST_CAP2 bits */ - HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */ - HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */ - HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */ - HOST_CAP2_SDS = (1 << 3), /* Support device sleep */ - HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */ - HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */ + HOST_CAP2_BOH = BIT(0), /* BIOS/OS handoff supported */ + HOST_CAP2_NVMHCI = BIT(1), /* NVMHCI supported */ + HOST_CAP2_APST = BIT(2), /* Automatic partial to slumber */ + HOST_CAP2_SDS = BIT(3), /* Support device sleep */ + HOST_CAP2_SADM = BIT(4), /* Support aggressive DevSlp */ + HOST_CAP2_DESO = BIT(5), /* DevSlp from slumber only */ /* registers for each SATA port */ PORT_LST_ADDR = 0x00, /* command list DMA addr */ @@ -129,24 +130,24 @@ PORT_DEVSLP = 0x44, /* device sleep */ /* PORT_IRQ_{STAT,MASK} bits */ - PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */ - PORT_IRQ_TF_ERR = (1 << 30), /* task file error */ - PORT_IRQ_HBUS_ERR = (1 << 29), /* host bus fatal error */ - PORT_IRQ_HBUS_DATA_ERR = (1 << 28), /* host bus data error */ - PORT_IRQ_IF_ERR = (1 << 27), /* interface fatal error */ - PORT_IRQ_IF_NONFATAL = (1 << 26), /* interface non-fatal error */ - PORT_IRQ_OVERFLOW = (1 << 24), /* xfer exhausted available S/G */ - PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */ - - PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */ - PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */ - PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */ - PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */ - PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */ - PORT_IRQ_SDB_FIS = (1 << 3), /* Set Device Bits FIS rx'd */ - PORT_IRQ_DMAS_FIS = (1 << 2), /* DMA Setup FIS rx'd */ - PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ - PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */ + PORT_IRQ_COLD_PRES = BIT(31), /* cold presence detect */ + PORT_IRQ_TF_ERR = BIT(30), /* task file error */ + PORT_IRQ_HBUS_ERR = BIT(29), /* host bus fatal error */ + PORT_IRQ_HBUS_DATA_ERR = BIT(28), /* host bus data error */ + PORT_IRQ_IF_ERR = BIT(27), /* interface fatal error */ + PORT_IRQ_IF_NONFATAL = BIT(26), /* interface non-fatal error */ + PORT_IRQ_OVERFLOW = BIT(24), /* xfer exhausted available S/G */ + PORT_IRQ_BAD_PMP = BIT(23), /* incorrect port multiplier */ + + PORT_IRQ_PHYRDY = BIT(22), /* PhyRdy changed */ + PORT_IRQ_DEV_ILCK = BIT(7), /* device interlock */ + PORT_IRQ_CONNECT = BIT(6), /* port connect change status */ + PORT_IRQ_SG_DONE = BIT(5), /* descriptor processed */ + PORT_IRQ_UNK_FIS = BIT(4), /* unknown FIS rx'd */ + PORT_IRQ_SDB_FIS = BIT(3), /* Set Device Bits FIS rx'd */ + PORT_IRQ_DMAS_FIS = BIT(2), /* DMA Setup FIS rx'd */ + PORT_IRQ_PIOS_FIS = BIT(1), /* PIO Setup FIS rx'd */ + PORT_IRQ_D2H_REG_FIS = BIT(0), /* D2H Register FIS rx'd */ PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR | @@ -162,34 +163,34 @@ PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS, /* PORT_CMD bits */ - PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */ - PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */ - PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ - PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */ - PORT_CMD_ESP = (1 << 21), /* External Sata Port */ - PORT_CMD_HPCP = (1 << 18), /* HotPlug Capable Port */ - PORT_CMD_PMP = (1 << 17), /* PMP attached */ - PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ - PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ - PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ - PORT_CMD_CLO = (1 << 3), /* Command list override */ - PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ - PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ - PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ - - PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */ - PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ - PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ - PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ + PORT_CMD_ASP = BIT(27), /* Aggressive Slumber/Partial */ + PORT_CMD_ALPE = BIT(26), /* Aggressive Link PM enable */ + PORT_CMD_ATAPI = BIT(24), /* Device is ATAPI */ + PORT_CMD_FBSCP = BIT(22), /* FBS Capable Port */ + PORT_CMD_ESP = BIT(21), /* External Sata Port */ + PORT_CMD_HPCP = BIT(18), /* HotPlug Capable Port */ + PORT_CMD_PMP = BIT(17), /* PMP attached */ + PORT_CMD_LIST_ON = BIT(15), /* cmd list DMA engine running */ + PORT_CMD_FIS_ON = BIT(14), /* FIS DMA engine running */ + PORT_CMD_FIS_RX = BIT(4), /* Enable FIS receive DMA engine */ + PORT_CMD_CLO = BIT(3), /* Command list override */ + PORT_CMD_POWER_ON = BIT(2), /* Power up device */ + PORT_CMD_SPIN_UP = BIT(1), /* Spin up device */ + PORT_CMD_START = BIT(0), /* Enable port DMA engine */ + + PORT_CMD_ICC_MASK = (0xfu << 28), /* i/f ICC state mask */ + PORT_CMD_ICC_ACTIVE = (0x1u << 28), /* Put i/f in active state */ + PORT_CMD_ICC_PARTIAL = (0x2u << 28), /* Put i/f in partial state */ + PORT_CMD_ICC_SLUMBER = (0x6u << 28), /* Put i/f in slumber state */ /* PORT_FBS bits */ PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */ PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */ PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */ PORT_FBS_DEV_MASK = (0xf << PORT_FBS_DEV_OFFSET), /* FBS.DEV */ - PORT_FBS_SDE = (1 << 2), /* FBS single device error */ - PORT_FBS_DEC = (1 << 1), /* FBS device error clear */ - PORT_FBS_EN = (1 << 0), /* Enable FBS */ + PORT_FBS_SDE = BIT(2), /* FBS single device error */ + PORT_FBS_DEC = BIT(1), /* FBS device error clear */ + PORT_FBS_EN = BIT(0), /* Enable FBS */ /* PORT_DEVSLP bits */ PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */ @@ -197,49 +198,53 @@ PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */ PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */ PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */ - PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */ - PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */ + PORT_DEVSLP_DSP = BIT(1), /* DevSlp present */ + PORT_DEVSLP_ADSE = BIT(0), /* Aggressive DevSlp enable */ /* hpriv->flags bits */ #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) - AHCI_HFLAG_NO_NCQ = (1 << 0), - AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */ - AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */ - AHCI_HFLAG_32BIT_ONLY = (1 << 3), /* force 32bit */ - AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */ - AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */ - AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ - AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ - AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ - AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ - AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as - link offline */ - AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ - AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ - AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ - AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on - port start (wait until - error-handling stage) */ - AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */ - AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */ + AHCI_HFLAG_NO_NCQ = BIT(0), + AHCI_HFLAG_IGN_IRQ_IF_ERR = BIT(1), /* ignore IRQ_IF_ERR */ + AHCI_HFLAG_IGN_SERR_INTERNAL = BIT(2), /* ignore SERR_INTERNAL */ + AHCI_HFLAG_32BIT_ONLY = BIT(3), /* force 32bit */ + AHCI_HFLAG_MV_PATA = BIT(4), /* PATA port */ + AHCI_HFLAG_NO_MSI = BIT(5), /* no PCI MSI */ + AHCI_HFLAG_NO_PMP = BIT(6), /* no PMP */ + AHCI_HFLAG_SECT255 = BIT(8), /* max 255 sectors */ + AHCI_HFLAG_YES_NCQ = BIT(9), /* force NCQ cap on */ + AHCI_HFLAG_NO_SUSPEND = BIT(10), /* don't suspend */ + AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = BIT(11), /* treat SRST timeout as + link offline */ + AHCI_HFLAG_NO_SNTF = BIT(12), /* no sntf */ + AHCI_HFLAG_NO_FPDMA_AA = BIT(13), /* no FPDMA AA */ + AHCI_HFLAG_YES_FBS = BIT(14), /* force FBS cap on */ + AHCI_HFLAG_DELAY_ENGINE = BIT(15), /* do not start engine on + port start (wait until + error-handling stage) */ + AHCI_HFLAG_NO_DEVSLP = BIT(17), /* no device sleep */ + AHCI_HFLAG_NO_FBS = BIT(18), /* no FBS */ #ifdef CONFIG_PCI_MSI - AHCI_HFLAG_MULTI_MSI = (1 << 20), /* per-port MSI(-X) */ + AHCI_HFLAG_MULTI_MSI = BIT(20), /* per-port MSI(-X) */ #else /* compile out MSI infrastructure */ AHCI_HFLAG_MULTI_MSI = 0, #endif - AHCI_HFLAG_WAKE_BEFORE_STOP = (1 << 22), /* wake before DMA stop */ - AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */ - AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read - only registers */ - AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use - SATA_MOBILE_LPM_POLICY - as default lpm_policy */ - AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during - suspend/resume */ + AHCI_HFLAG_WAKE_BEFORE_STOP = BIT(22), /* wake before DMA stop */ + AHCI_HFLAG_YES_ALPM = BIT(23), /* force ALPM cap on */ + AHCI_HFLAG_NO_WRITE_TO_RO = BIT(24), /* don't write to read + only registers */ + AHCI_HFLAG_IS_MOBILE = BIT(25), /* mobile chipset, use + SATA_MOBILE_LPM_POLICY + as default lpm_policy */ + AHCI_HFLAG_SUSPEND_PHYS = BIT(26), /* handle PHYs during + suspend/resume */ + AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = BIT(27), /* ignore -EOPNOTSUPP + from phy_power_on() */ + AHCI_HFLAG_NO_SXS = BIT(28), /* SXS not supported */ + AHCI_HFLAG_43BIT_ONLY = BIT(29), /* 43bit DMA addr limit */ /* ap->flags bits */ @@ -251,26 +256,26 @@ PCS_7 = 0x94, /* 7+ port PCS (Denverton) */ /* em constants */ - EM_MAX_SLOTS = 8, + EM_MAX_SLOTS = SATA_PMP_MAX_PORTS, EM_MAX_RETRY = 5, /* em_ctl bits */ - EM_CTL_RST = (1 << 9), /* Reset */ - EM_CTL_TM = (1 << 8), /* Transmit Message */ - EM_CTL_MR = (1 << 0), /* Message Received */ - EM_CTL_ALHD = (1 << 26), /* Activity LED */ - EM_CTL_XMT = (1 << 25), /* Transmit Only */ - EM_CTL_SMB = (1 << 24), /* Single Message Buffer */ - EM_CTL_SGPIO = (1 << 19), /* SGPIO messages supported */ - EM_CTL_SES = (1 << 18), /* SES-2 messages supported */ - EM_CTL_SAFTE = (1 << 17), /* SAF-TE messages supported */ - EM_CTL_LED = (1 << 16), /* LED messages supported */ + EM_CTL_RST = BIT(9), /* Reset */ + EM_CTL_TM = BIT(8), /* Transmit Message */ + EM_CTL_MR = BIT(0), /* Message Received */ + EM_CTL_ALHD = BIT(26), /* Activity LED */ + EM_CTL_XMT = BIT(25), /* Transmit Only */ + EM_CTL_SMB = BIT(24), /* Single Message Buffer */ + EM_CTL_SGPIO = BIT(19), /* SGPIO messages supported */ + EM_CTL_SES = BIT(18), /* SES-2 messages supported */ + EM_CTL_SAFTE = BIT(17), /* SAF-TE messages supported */ + EM_CTL_LED = BIT(16), /* LED messages supported */ /* em message type */ - EM_MSG_TYPE_LED = (1 << 0), /* LED */ - EM_MSG_TYPE_SAFTE = (1 << 1), /* SAF-TE */ - EM_MSG_TYPE_SES2 = (1 << 2), /* SES-2 */ - EM_MSG_TYPE_SGPIO = (1 << 3), /* SGPIO */ + EM_MSG_TYPE_LED = BIT(0), /* LED */ + EM_MSG_TYPE_SAFTE = BIT(1), /* SAF-TE */ + EM_MSG_TYPE_SES2 = BIT(2), /* SES-2 */ + EM_MSG_TYPE_SGPIO = BIT(3), /* SGPIO */ }; struct ahci_cmd_hdr { @@ -336,6 +341,7 @@ u32 em_loc; /* enclosure management location */ u32 em_buf_sz; /* EM buffer size in byte */ u32 em_msg_type; /* EM message type */ + u32 remapped_nvme; /* NVMe remapped device count */ bool got_runtime_pm; /* Did we do pm_runtime_get? */ struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ struct reset_control *rsts; /* Optional */ --- linux-oracle-5.4.0.orig/drivers/ata/ahci_brcm.c +++ linux-oracle-5.4.0/drivers/ata/ahci_brcm.c @@ -76,8 +76,7 @@ }; enum brcm_ahci_quirks { - BRCM_AHCI_QUIRK_NO_NCQ = BIT(0), - BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(1), + BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE = BIT(0), }; struct brcm_ahci_priv { @@ -213,19 +212,12 @@ brcm_sata_phy_disable(priv, i); } -static u32 brcm_ahci_get_portmask(struct platform_device *pdev, +static u32 brcm_ahci_get_portmask(struct ahci_host_priv *hpriv, struct brcm_ahci_priv *priv) { - void __iomem *ahci; - struct resource *res; u32 impl; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ahci"); - ahci = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(ahci)) - return 0; - - impl = readl(ahci + HOST_PORTS_IMPL); + impl = readl(hpriv->mmio + HOST_PORTS_IMPL); if (fls(impl) > SATA_TOP_MAX_PHYS) dev_warn(priv->dev, "warning: more ports than PHYs (%#x)\n", @@ -233,9 +225,6 @@ else if (!impl) dev_info(priv->dev, "no ports found\n"); - devm_iounmap(&pdev->dev, ahci); - devm_release_mem_region(&pdev->dev, res->start, resource_size(res)); - return impl; } @@ -285,6 +274,13 @@ /* Perform the SATA PHY reset sequence */ brcm_sata_phy_disable(priv, ap->port_no); + /* Reset the SATA clock */ + ahci_platform_disable_clks(hpriv); + msleep(10); + + ahci_platform_enable_clks(hpriv); + msleep(10); + /* Bring the PHY back on */ brcm_sata_phy_enable(priv, ap->port_no); @@ -347,11 +343,10 @@ struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; struct brcm_ahci_priv *priv = hpriv->plat_data; - int ret; - ret = ahci_platform_suspend(dev); brcm_sata_phys_disable(priv); - return ret; + + return ahci_platform_suspend(dev); } static int brcm_ahci_resume(struct device *dev) @@ -359,11 +354,50 @@ struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; struct brcm_ahci_priv *priv = hpriv->plat_data; + int ret; + + /* Make sure clocks are turned on before re-configuration */ + ret = ahci_platform_enable_clks(hpriv); + if (ret) + return ret; + + ret = ahci_platform_enable_regulators(hpriv); + if (ret) + goto out_disable_clks; brcm_sata_init(priv); brcm_sata_phys_enable(priv); brcm_sata_alpm_init(hpriv); - return ahci_platform_resume(dev); + + /* Since we had to enable clocks earlier on, we cannot use + * ahci_platform_resume() as-is since a second call to + * ahci_platform_enable_resources() would bump up the resources + * (regulators, clocks, PHYs) count artificially so we copy the part + * after ahci_platform_enable_resources(). + */ + ret = ahci_platform_enable_phys(hpriv); + if (ret) + goto out_disable_phys; + + ret = ahci_platform_resume_host(dev); + if (ret) + goto out_disable_platform_phys; + + /* We resumed so update PM runtime state */ + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + return 0; + +out_disable_platform_phys: + ahci_platform_disable_phys(hpriv); +out_disable_phys: + brcm_sata_phys_disable(priv); + ahci_platform_disable_regulators(hpriv); +out_disable_clks: + ahci_platform_disable_clks(hpriv); + return ret; } #endif @@ -410,44 +444,77 @@ if (!IS_ERR_OR_NULL(priv->rcdev)) reset_control_deassert(priv->rcdev); - if ((priv->version == BRCM_SATA_BCM7425) || - (priv->version == BRCM_SATA_NSP)) { - priv->quirks |= BRCM_AHCI_QUIRK_NO_NCQ; + hpriv = ahci_platform_get_resources(pdev, 0); + if (IS_ERR(hpriv)) { + ret = PTR_ERR(hpriv); + goto out_reset; + } + + hpriv->plat_data = priv; + hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP | AHCI_HFLAG_NO_WRITE_TO_RO; + + switch (priv->version) { + case BRCM_SATA_BCM7425: + hpriv->flags |= AHCI_HFLAG_DELAY_ENGINE; + /* fall through */ + case BRCM_SATA_NSP: + hpriv->flags |= AHCI_HFLAG_NO_NCQ; priv->quirks |= BRCM_AHCI_QUIRK_SKIP_PHY_ENABLE; + break; + default: + break; } + ret = ahci_platform_enable_clks(hpriv); + if (ret) + goto out_reset; + + ret = ahci_platform_enable_regulators(hpriv); + if (ret) + goto out_disable_clks; + + /* Must be first so as to configure endianness including that + * of the standard AHCI register space. + */ brcm_sata_init(priv); - priv->port_mask = brcm_ahci_get_portmask(pdev, priv); - if (!priv->port_mask) - return -ENODEV; + /* Initializes priv->port_mask which is used below */ + priv->port_mask = brcm_ahci_get_portmask(hpriv, priv); + if (!priv->port_mask) { + ret = -ENODEV; + goto out_disable_regulators; + } + /* Must be done before ahci_platform_enable_phys() */ brcm_sata_phys_enable(priv); - hpriv = ahci_platform_get_resources(pdev, 0); - if (IS_ERR(hpriv)) - return PTR_ERR(hpriv); - hpriv->plat_data = priv; - hpriv->flags = AHCI_HFLAG_WAKE_BEFORE_STOP; - brcm_sata_alpm_init(hpriv); - ret = ahci_platform_enable_resources(hpriv); + ret = ahci_platform_enable_phys(hpriv); if (ret) - return ret; - - if (priv->quirks & BRCM_AHCI_QUIRK_NO_NCQ) - hpriv->flags |= AHCI_HFLAG_NO_NCQ; - hpriv->flags |= AHCI_HFLAG_NO_WRITE_TO_RO; + goto out_disable_phys; ret = ahci_platform_init_host(pdev, hpriv, &ahci_brcm_port_info, &ahci_platform_sht); if (ret) - return ret; + goto out_disable_platform_phys; dev_info(dev, "Broadcom AHCI SATA3 registered\n"); return 0; + +out_disable_platform_phys: + ahci_platform_disable_phys(hpriv); +out_disable_phys: + brcm_sata_phys_disable(priv); +out_disable_regulators: + ahci_platform_disable_regulators(hpriv); +out_disable_clks: + ahci_platform_disable_clks(hpriv); +out_reset: + if (!IS_ERR_OR_NULL(priv->rcdev)) + reset_control_assert(priv->rcdev); + return ret; } static int brcm_ahci_remove(struct platform_device *pdev) @@ -457,12 +524,12 @@ struct brcm_ahci_priv *priv = hpriv->plat_data; int ret; + brcm_sata_phys_disable(priv); + ret = ata_platform_remove_one(pdev); if (ret) return ret; - brcm_sata_phys_disable(priv); - return 0; } --- linux-oracle-5.4.0.orig/drivers/ata/ahci_imx.c +++ linux-oracle-5.4.0/drivers/ata/ahci_imx.c @@ -1239,4 +1239,4 @@ MODULE_DESCRIPTION("Freescale i.MX AHCI SATA platform driver"); MODULE_AUTHOR("Richard Zhu "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("ahci:imx"); +MODULE_ALIAS("platform:" DRV_NAME); --- linux-oracle-5.4.0.orig/drivers/ata/ahci_mvebu.c +++ linux-oracle-5.4.0/drivers/ata/ahci_mvebu.c @@ -227,7 +227,7 @@ static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = { .plat_config = ahci_mvebu_armada_3700_config, - .flags = AHCI_HFLAG_SUSPEND_PHYS, + .flags = AHCI_HFLAG_SUSPEND_PHYS | AHCI_HFLAG_IGN_NOTSUPP_POWER_ON, }; static const struct of_device_id ahci_mvebu_of_match[] = { --- linux-oracle-5.4.0.orig/drivers/ata/ahci_sunxi.c +++ linux-oracle-5.4.0/drivers/ata/ahci_sunxi.c @@ -200,7 +200,7 @@ } static const struct ata_port_info ahci_sunxi_port_info = { - .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ | ATA_FLAG_NO_DIPM, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_platform_ops, --- linux-oracle-5.4.0.orig/drivers/ata/libahci.c +++ linux-oracle-5.4.0/drivers/ata/libahci.c @@ -57,7 +57,7 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc); static int ahci_port_start(struct ata_port *ap); static void ahci_port_stop(struct ata_port *ap); -static void ahci_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc); static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc); static void ahci_freeze(struct ata_port *ap); static void ahci_thaw(struct ata_port *ap); @@ -493,6 +493,11 @@ cap |= HOST_CAP_ALPM; } + if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) { + dev_info(dev, "controller does not support SXS, disabling CAP_SXS\n"); + cap &= ~HOST_CAP_SXS; + } + if (hpriv->force_port_map && port_map != hpriv->force_port_map) { dev_info(dev, "forcing port_map 0x%x -> 0x%x\n", port_map, hpriv->force_port_map); @@ -1194,6 +1199,26 @@ return sprintf(buf, "%d\n", emp->blink_policy); } +static void ahci_port_clear_pending_irq(struct ata_port *ap) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + void __iomem *port_mmio = ahci_port_base(ap); + u32 tmp; + + /* clear SError */ + tmp = readl(port_mmio + PORT_SCR_ERR); + dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); + writel(tmp, port_mmio + PORT_SCR_ERR); + + /* clear port IRQ */ + tmp = readl(port_mmio + PORT_IRQ_STAT); + dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + + writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); +} + static void ahci_port_init(struct device *dev, struct ata_port *ap, int port_no, void __iomem *mmio, void __iomem *port_mmio) @@ -1208,18 +1233,7 @@ if (rc) dev_warn(dev, "%s (%d)\n", emsg, rc); - /* clear SError */ - tmp = readl(port_mmio + PORT_SCR_ERR); - VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); - writel(tmp, port_mmio + PORT_SCR_ERR); - - /* clear port IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); - if (tmp) - writel(tmp, port_mmio + PORT_IRQ_STAT); - - writel(1 << port_no, mmio + HOST_IRQ_STAT); + ahci_port_clear_pending_irq(ap); /* mark esata ports */ tmp = readl(port_mmio + PORT_CMD); @@ -1549,6 +1563,8 @@ tf.command = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ahci_port_clear_pending_irq(ap); + rc = sata_link_hardreset(link, timing, deadline, online, ahci_check_ready); @@ -1624,7 +1640,7 @@ return sata_pmp_qc_defer_cmd_switch(qc); } -static void ahci_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ahci_port_priv *pp = ap->private_data; @@ -1660,6 +1676,8 @@ opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; ahci_fill_cmd_slot(pp, qc->hw_tag, opts); + + return AC_ERR_OK; } static void ahci_fbs_dec_intr(struct ata_port *ap) --- linux-oracle-5.4.0.orig/drivers/ata/libahci_platform.c +++ linux-oracle-5.4.0/drivers/ata/libahci_platform.c @@ -43,7 +43,7 @@ * RETURNS: * 0 on success otherwise a negative error code */ -static int ahci_platform_enable_phys(struct ahci_host_priv *hpriv) +int ahci_platform_enable_phys(struct ahci_host_priv *hpriv) { int rc, i; @@ -59,7 +59,7 @@ } rc = phy_power_on(hpriv->phys[i]); - if (rc) { + if (rc && !(rc == -EOPNOTSUPP && (hpriv->flags & AHCI_HFLAG_IGN_NOTSUPP_POWER_ON))) { phy_exit(hpriv->phys[i]); goto disable_phys; } @@ -74,6 +74,7 @@ } return rc; } +EXPORT_SYMBOL_GPL(ahci_platform_enable_phys); /** * ahci_platform_disable_phys - Disable PHYs @@ -81,7 +82,7 @@ * * This function disables all PHYs found in hpriv->phys. */ -static void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) +void ahci_platform_disable_phys(struct ahci_host_priv *hpriv) { int i; @@ -90,6 +91,7 @@ phy_exit(hpriv->phys[i]); } } +EXPORT_SYMBOL_GPL(ahci_platform_disable_phys); /** * ahci_platform_enable_clks - Enable platform clocks @@ -438,10 +440,7 @@ hpriv->phy_regulator = devm_regulator_get(dev, "phy"); if (IS_ERR(hpriv->phy_regulator)) { rc = PTR_ERR(hpriv->phy_regulator); - if (rc == -EPROBE_DEFER) - goto err_out; - rc = 0; - hpriv->phy_regulator = NULL; + goto err_out; } if (flags & AHCI_PLATFORM_GET_RESETS) { @@ -452,14 +451,24 @@ } } - hpriv->nports = child_nodes = of_get_child_count(dev->of_node); + /* + * Too many sub-nodes most likely means having something wrong with + * the firmware. + */ + child_nodes = of_get_child_count(dev->of_node); + if (child_nodes > AHCI_MAX_PORTS) { + rc = -EINVAL; + goto err_out; + } /* * If no sub-node was found, we still need to set nports to * one in order to be able to use the * ahci_platform_[en|dis]able_[phys|regulators] functions. */ - if (!child_nodes) + if (child_nodes) + hpriv->nports = child_nodes; + else hpriv->nports = 1; hpriv->phys = devm_kcalloc(dev, hpriv->nports, sizeof(*hpriv->phys), GFP_KERNEL); @@ -580,11 +589,13 @@ int i, irq, n_ports, rc; irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { if (irq != -EPROBE_DEFER) dev_err(dev, "no irq\n"); return irq; } + if (!irq) + return -EINVAL; hpriv->irq = irq; --- linux-oracle-5.4.0.orig/drivers/ata/libata-core.c +++ linux-oracle-5.4.0/drivers/ata/libata-core.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -2058,7 +2057,7 @@ retry: ata_tf_init(dev, &tf); - if (dev->dma_mode && ata_id_has_read_log_dma_ext(dev->id) && + if (ata_dma_enabled(dev) && ata_id_has_read_log_dma_ext(dev->id) && !(dev->horkage & ATA_HORKAGE_NO_DMA_LOG)) { tf.command = ATA_CMD_READ_LOG_DMA_EXT; tf.protocol = ATA_PROT_DMA; @@ -2253,6 +2252,25 @@ } +static bool ata_dev_check_adapter(struct ata_device *dev, + unsigned short vendor_id) +{ + struct pci_dev *pcidev = NULL; + struct device *parent_dev = NULL; + + for (parent_dev = dev->tdev.parent; parent_dev != NULL; + parent_dev = parent_dev->parent) { + if (dev_is_pci(parent_dev)) { + pcidev = to_pci_dev(parent_dev); + if (pcidev->vendor == vendor_id) + return true; + break; + } + } + + return false; +} + static int ata_dev_config_ncq(struct ata_device *dev, char *desc, size_t desc_sz) { @@ -2269,6 +2287,13 @@ snprintf(desc, desc_sz, "NCQ (not used)"); return 0; } + + if (dev->horkage & ATA_HORKAGE_NO_NCQ_ON_ATI && + ata_dev_check_adapter(dev, PCI_VENDOR_ID_ATI)) { + snprintf(desc, desc_sz, "NCQ (not used)"); + return 0; + } + if (ap->flags & ATA_FLAG_NCQ) { hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE); dev->flags |= ATA_DFLAG_NCQ; @@ -3071,7 +3096,7 @@ */ if (spd > 1) mask &= (1 << (spd - 1)) - 1; - else + else if (link->sata_spd) return -EINVAL; /* were we already at the bottom? */ @@ -3956,10 +3981,23 @@ case ATA_LPM_MED_POWER_WITH_DIPM: case ATA_LPM_MIN_POWER_WITH_PARTIAL: case ATA_LPM_MIN_POWER: - if (ata_link_nr_enabled(link) > 0) - /* no restrictions on LPM transitions */ + if (ata_link_nr_enabled(link) > 0) { + /* assume no restrictions on LPM transitions */ scontrol &= ~(0x7 << 8); - else { + + /* + * If the controller does not support partial, slumber, + * or devsleep, then disallow these transitions. + */ + if (link->ap->host->flags & ATA_HOST_NO_PART) + scontrol |= (0x1 << 8); + + if (link->ap->host->flags & ATA_HOST_NO_SSC) + scontrol |= (0x2 << 8); + + if (link->ap->host->flags & ATA_HOST_NO_DEVSLP) + scontrol |= (0x4 << 8); + } else { /* empty port, power off */ scontrol &= ~0xf; scontrol |= (0x1 << 2); @@ -4412,6 +4450,8 @@ { "VRFDFC22048UCHC-TE*", NULL, ATA_HORKAGE_NODMA }, /* Odd clown on sil3726/4726 PMPs */ { "Config Disk", NULL, ATA_HORKAGE_DISABLE }, + /* Similar story with ASMedia 1092 */ + { "ASMT109x- Config", NULL, ATA_HORKAGE_DISABLE }, /* Weird ATAPI devices */ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, @@ -4475,9 +4515,8 @@ /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, - /* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on - SD7SN6S256G and SD8SN8U256G */ - { "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, }, + /* Sandisk SD7/8/9s lock up hard on large trims */ + { "SanDisk SD[789]*", NULL, ATA_HORKAGE_MAX_TRIM_128M, }, /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, @@ -4516,6 +4555,10 @@ { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, + /* These specific Pioneer models have LPM issues */ + { "PIONEER BD-RW BDR-207M", NULL, ATA_HORKAGE_NOLPM }, + { "PIONEER BD-RW BDR-205", NULL, ATA_HORKAGE_NOLPM }, + /* Crucial BX100 SSD 500GB has broken LPM support */ { "CT500BX100SSD1", NULL, ATA_HORKAGE_NOLPM }, @@ -4554,15 +4597,25 @@ ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Crucial_CT*MX100*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 840 EVO*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_NO_DMA_LOG | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Samsung SSD 840*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 860*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NO_NCQ_ON_ATI, }, + { "Samsung SSD 870*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM | + ATA_HORKAGE_NO_NCQ_ON_ATI, }, { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, /* devices that don't properly handle TRIM commands */ { "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM, }, + { "M88V29*", NULL, ATA_HORKAGE_NOTRIM, }, /* * As defined, the DRAT (Deterministic Read After Trim) and RZAT @@ -4980,7 +5033,10 @@ return ATA_DEFER_LINK; } -void ata_noop_qc_prep(struct ata_queued_cmd *qc) { } +enum ata_completion_errors ata_noop_qc_prep(struct ata_queued_cmd *qc) +{ + return AC_ERR_OK; +} /** * ata_sg_init - Associate command with scatter-gather table. @@ -5326,6 +5382,30 @@ } /** + * ata_qc_get_active - get bitmask of active qcs + * @ap: port in question + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * Bitmask of active qcs + */ +u64 ata_qc_get_active(struct ata_port *ap) +{ + u64 qc_active = ap->qc_active; + + /* ATA_TAG_INTERNAL is sent to hw as tag 0 */ + if (qc_active & (1ULL << ATA_TAG_INTERNAL)) { + qc_active |= (1 << 0); + qc_active &= ~(1ULL << ATA_TAG_INTERNAL); + } + + return qc_active; +} +EXPORT_SYMBOL_GPL(ata_qc_get_active); + +/** * ata_qc_complete_multiple - Complete multiple qcs successfully * @ap: port in question * @qc_active: new qc_active mask @@ -5443,7 +5523,9 @@ return; } - ap->ops->qc_prep(qc); + qc->err_mask |= ap->ops->qc_prep(qc); + if (unlikely(qc->err_mask)) + goto err; trace_ata_qc_issue(qc); qc->err_mask |= ap->ops->qc_issue(qc); if (unlikely(qc->err_mask)) @@ -5669,17 +5751,19 @@ struct ata_link *link; unsigned long flags; - /* Previous resume operation might still be in - * progress. Wait for PM_PENDING to clear. + spin_lock_irqsave(ap->lock, flags); + + /* + * A previous PM operation might still be in progress. Wait for + * ATA_PFLAG_PM_PENDING to clear. */ if (ap->pflags & ATA_PFLAG_PM_PENDING) { + spin_unlock_irqrestore(ap->lock, flags); ata_port_wait_eh(ap); - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); + spin_lock_irqsave(ap->lock, flags); } - /* request PM ops to EH */ - spin_lock_irqsave(ap->lock, flags); - + /* Request PM operation to EH */ ap->pm_mesg = mesg; ap->pflags |= ATA_PFLAG_PM_PENDING; ata_for_each_link(link, ap, HOST_FIRST) { @@ -5691,10 +5775,8 @@ spin_unlock_irqrestore(ap->lock, flags); - if (!async) { + if (!async) ata_port_wait_eh(ap); - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); - } } /* @@ -5860,7 +5942,7 @@ #endif const struct device_type ata_port_type = { - .name = "ata_port", + .name = ATA_PORT_TYPE_NAME, #ifdef CONFIG_PM .pm = &ata_port_pm_ops, #endif @@ -6059,6 +6141,9 @@ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; + if (!ap) + continue; + kfree(ap->pmp_link); kfree(ap->slave_link); kfree(ap); @@ -6112,12 +6197,16 @@ if (!host) return NULL; - if (!devres_open_group(dev, NULL, GFP_KERNEL)) - goto err_free; + if (!devres_open_group(dev, NULL, GFP_KERNEL)) { + kfree(host); + return NULL; + } dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL); - if (!dr) + if (!dr) { + kfree(host); goto err_out; + } devres_add(dev, dr); dev_set_drvdata(dev, host); @@ -6145,8 +6234,6 @@ err_out: devres_release_group(dev, NULL); - err_free: - kfree(host); return NULL; } @@ -6170,7 +6257,7 @@ const struct ata_port_info * const * ppi, int n_ports) { - const struct ata_port_info *pi; + const struct ata_port_info *pi = &ata_dummy_port_info; struct ata_host *host; int i, j; @@ -6178,7 +6265,7 @@ if (!host) return NULL; - for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) { + for (i = 0, j = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; if (ppi[j]) @@ -6367,7 +6454,7 @@ have_stop = 1; } - if (host->ops->host_stop) + if (host->ops && host->ops->host_stop) have_stop = 1; if (have_stop) { @@ -6568,7 +6655,7 @@ /* perform each probe asynchronously */ for (i = 0; i < host->n_ports; i++) { struct ata_port *ap = host->ports[i]; - async_schedule(async_port_probe, ap); + ap->cookie = async_schedule(async_port_probe, ap); } return 0; @@ -6663,11 +6750,30 @@ if (!ap->ops->error_handler) goto skip_eh; - /* tell EH we're leaving & flush EH */ + /* Wait for any ongoing EH */ + ata_port_wait_eh(ap); + + mutex_lock(&ap->scsi_scan_mutex); spin_lock_irqsave(ap->lock, flags); + + /* Remove scsi devices */ + ata_for_each_link(link, ap, HOST_FIRST) { + ata_for_each_dev(dev, link, ALL) { + if (dev->sdev) { + spin_unlock_irqrestore(ap->lock, flags); + scsi_remove_device(dev->sdev); + spin_lock_irqsave(ap->lock, flags); + dev->sdev = NULL; + } + } + } + + /* Tell EH to disable all devices */ ap->pflags |= ATA_PFLAG_UNLOADING; ata_port_schedule_eh(ap); + spin_unlock_irqrestore(ap->lock, flags); + mutex_unlock(&ap->scsi_scan_mutex); /* wait till EH commits suicide */ ata_port_wait_eh(ap); @@ -6708,8 +6814,11 @@ { int i; - for (i = 0; i < host->n_ports; i++) + for (i = 0; i < host->n_ports; i++) { + /* Ensure ata_port probe has completed */ + async_synchronize_cookie(host->ports[i]->cookie + 1); ata_port_detach(host->ports[i]); + } /* the host is dead now, dissociate ACPI */ ata_acpi_dissociate(host); @@ -6735,6 +6844,26 @@ ata_host_detach(host); } +void ata_pci_shutdown_one(struct pci_dev *pdev) +{ + struct ata_host *host = pci_get_drvdata(pdev); + int i; + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap = host->ports[i]; + + ap->pflags |= ATA_PFLAG_FROZEN; + + /* Disable port interrupts */ + if (ap->ops->freeze) + ap->ops->freeze(ap); + + /* Stop the port DMA engines */ + if (ap->ops->port_stop) + ap->ops->port_stop(ap); + } +} + /* move to PCI subsystem */ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) { @@ -6862,6 +6991,8 @@ { "ncq", .horkage_off = ATA_HORKAGE_NONCQ }, { "noncqtrim", .horkage_on = ATA_HORKAGE_NO_NCQ_TRIM }, { "ncqtrim", .horkage_off = ATA_HORKAGE_NO_NCQ_TRIM }, + { "noncqati", .horkage_on = ATA_HORKAGE_NO_NCQ_ON_ATI }, + { "ncqati", .horkage_off = ATA_HORKAGE_NO_NCQ_ON_ATI }, { "dump_id", .horkage_on = ATA_HORKAGE_DUMP_ID }, { "pio0", .xfer_mask = 1 << (ATA_SHIFT_PIO + 0) }, { "pio1", .xfer_mask = 1 << (ATA_SHIFT_PIO + 1) }, @@ -7355,6 +7486,7 @@ #ifdef CONFIG_PCI EXPORT_SYMBOL_GPL(pci_test_config_bits); +EXPORT_SYMBOL_GPL(ata_pci_shutdown_one); EXPORT_SYMBOL_GPL(ata_pci_remove_one); #ifdef CONFIG_PM EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend); --- linux-oracle-5.4.0.orig/drivers/ata/libata-eh.c +++ linux-oracle-5.4.0/drivers/ata/libata-eh.c @@ -97,6 +97,12 @@ ULONG_MAX, }; +static const unsigned long ata_eh_revalidate_timeouts[] = { + 15000, /* Some drives are slow to read log pages when waking-up */ + 15000, /* combined time till here is enough even for media access */ + ULONG_MAX, +}; + static const unsigned long ata_eh_flush_timeouts[] = { 15000, /* be generous with flush */ 15000, /* ditto */ @@ -133,6 +139,8 @@ ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), .timeouts = ata_eh_identify_timeouts, }, + { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), + .timeouts = ata_eh_revalidate_timeouts, }, { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), .timeouts = ata_eh_other_timeouts, }, { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), @@ -2321,6 +2329,7 @@ { ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" }, { ATA_CMD_FPDMA_READ, "READ FPDMA QUEUED" }, { ATA_CMD_FPDMA_WRITE, "WRITE FPDMA QUEUED" }, + { ATA_CMD_NCQ_NON_DATA, "NCQ NON-DATA" }, { ATA_CMD_FPDMA_SEND, "SEND FPDMA QUEUED" }, { ATA_CMD_FPDMA_RECV, "RECEIVE FPDMA QUEUED" }, { ATA_CMD_PIO_READ, "READ SECTOR(S)" }, @@ -2413,7 +2422,7 @@ struct ata_eh_context *ehc = &link->eh_context; struct ata_queued_cmd *qc; const char *frozen, *desc; - char tries_buf[6] = ""; + char tries_buf[16] = ""; int tag, nr_failed = 0; if (ehc->i.flags & ATA_EHI_QUIET) @@ -2892,18 +2901,11 @@ postreset(slave, classes); } - /* - * Some controllers can't be frozen very well and may set spurious - * error conditions during reset. Clear accumulated error - * information and re-thaw the port if frozen. As reset is the - * final recovery action and we cross check link onlineness against - * device classification later, no hotplug event is lost by this. - */ + /* clear cached SError */ spin_lock_irqsave(link->ap->lock, flags); - memset(&link->eh_info, 0, sizeof(link->eh_info)); + link->eh_info.serror = 0; if (slave) - memset(&slave->eh_info, 0, sizeof(link->eh_info)); - ap->pflags &= ~ATA_PFLAG_EH_PENDING; + slave->eh_info.serror = 0; spin_unlock_irqrestore(link->ap->lock, flags); if (ap->pflags & ATA_PFLAG_FROZEN) --- linux-oracle-5.4.0.orig/drivers/ata/libata-pmp.c +++ linux-oracle-5.4.0/drivers/ata/libata-pmp.c @@ -763,6 +763,7 @@ if (dev->flags & ATA_DFLAG_DETACH) { detach = 1; + rc = -ENODEV; goto fail; } --- linux-oracle-5.4.0.orig/drivers/ata/libata-scsi.c +++ linux-oracle-5.4.0/drivers/ata/libata-scsi.c @@ -162,7 +162,7 @@ struct ata_link *link; struct ata_device *dev; unsigned long now; - unsigned int uninitialized_var(msecs); + unsigned int msecs; int rc = 0; ap = ata_shost_to_port(sdev->host); @@ -2374,6 +2374,7 @@ static unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) { + struct ata_device *dev = args->dev; u16 min_io_sectors; rbuf[1] = 0xb0; @@ -2399,7 +2400,12 @@ * with the unmap bit set. */ if (ata_id_has_trim(args->id)) { - put_unaligned_be64(65535 * ATA_MAX_TRIM_RNUM, &rbuf[36]); + u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM; + + if (dev->horkage & ATA_HORKAGE_MAX_TRIM_128M) + max_blocks = 128 << (20 - SECTOR_SHIFT); + + put_unaligned_be64(max_blocks, &rbuf[36]); put_unaligned_be32(1, &rbuf[28]); } @@ -3030,18 +3036,36 @@ return 0; } -static struct ata_device *ata_find_dev(struct ata_port *ap, int devno) +static struct ata_device *ata_find_dev(struct ata_port *ap, unsigned int devno) { - if (!sata_pmp_attached(ap)) { - if (likely(devno >= 0 && - devno < ata_link_max_devices(&ap->link))) + /* + * For the non-PMP case, ata_link_max_devices() returns 1 (SATA case), + * or 2 (IDE master + slave case). However, the former case includes + * libsas hosted devices which are numbered per scsi host, leading + * to devno potentially being larger than 0 but with each struct + * ata_device having its own struct ata_port and struct ata_link. + * To accommodate these, ignore devno and always use device number 0. + */ + if (likely(!sata_pmp_attached(ap))) { + int link_max_devices = ata_link_max_devices(&ap->link); + + if (link_max_devices == 1) + return &ap->link.device[0]; + + if (devno < link_max_devices) return &ap->link.device[devno]; - } else { - if (likely(devno >= 0 && - devno < ap->nr_pmp_links)) - return &ap->pmp_link[devno].device[0]; + + return NULL; } + /* + * For PMP-attached devices, the device number corresponds to C + * (channel) of SCSI [H:C:I:L], indicating the port pmp link + * for the device. + */ + if (devno < ap->nr_pmp_links) + return &ap->pmp_link[devno].device[0]; + return NULL; } @@ -3158,8 +3182,19 @@ goto invalid_fld; } - if (ata_is_ncq(tf->protocol) && (cdb[2 + cdb_offset] & 0x3) == 0) - tf->protocol = ATA_PROT_NCQ_NODATA; + if ((cdb[2 + cdb_offset] & 0x3) == 0) { + /* + * When T_LENGTH is zero (No data is transferred), dir should + * be DMA_NONE. + */ + if (scmd->sc_data_direction != DMA_NONE) { + fp = 2 + cdb_offset; + goto invalid_fld; + } + + if (ata_is_ncq(tf->protocol)) + tf->protocol = ATA_PROT_NCQ_NODATA; + } /* enable LBA */ tf->flags |= ATA_TFLAG_LBA; @@ -3978,12 +4013,13 @@ { struct scsi_cmnd *scmd = qc->scsicmd; const u8 *cdb = scmd->cmnd; - const u8 *p; u8 pg, spg; unsigned six_byte, pg_len, hdr_len, bd_len; int len; u16 fp = (u16)-1; u8 bp = 0xff; + u8 buffer[64]; + const u8 *p = buffer; VPRINTK("ENTER\n"); @@ -4017,12 +4053,14 @@ if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len) goto invalid_param_len; - p = page_address(sg_page(scsi_sglist(scmd))); - /* Move past header and block descriptors. */ if (len < hdr_len) goto invalid_param_len; + if (!sg_copy_to_buffer(scsi_sglist(scmd), scsi_sg_count(scmd), + buffer, sizeof(buffer))) + goto invalid_param_len; + if (six_byte) bd_len = p[3]; else @@ -4506,7 +4544,7 @@ break; case MAINTENANCE_IN: - if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) + if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); else ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); @@ -4553,22 +4591,19 @@ */ shost->max_host_blocked = 1; - rc = scsi_add_host_with_dma(ap->scsi_host, - &ap->tdev, ap->host->dev); + rc = scsi_add_host_with_dma(shost, &ap->tdev, ap->host->dev); if (rc) - goto err_add; + goto err_alloc; } return 0; - err_add: - scsi_host_put(host->ports[i]->scsi_host); err_alloc: while (--i >= 0) { struct Scsi_Host *shost = host->ports[i]->scsi_host; + /* scsi_host_put() is in ata_devres_release() */ scsi_remove_host(shost); - scsi_host_put(shost); } return rc; } --- linux-oracle-5.4.0.orig/drivers/ata/libata-sff.c +++ linux-oracle-5.4.0/drivers/ata/libata-sff.c @@ -641,6 +641,20 @@ } EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); +static void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page, + unsigned int offset, size_t xfer_size) +{ + bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE); + unsigned char *buf; + + buf = kmap_atomic(page); + qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write); + kunmap_atomic(buf); + + if (!do_write && !PageSlab(page)) + flush_dcache_page(page); +} + /** * ata_pio_sector - Transfer a sector of data. * @qc: Command on going @@ -652,11 +666,9 @@ */ static void ata_pio_sector(struct ata_queued_cmd *qc) { - int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); struct ata_port *ap = qc->ap; struct page *page; unsigned int offset; - unsigned char *buf; if (!qc->cursg) { qc->curbytes = qc->nbytes; @@ -674,13 +686,20 @@ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - /* do the actual data transfer */ - buf = kmap_atomic(page); - ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); - kunmap_atomic(buf); - - if (!do_write && !PageSlab(page)) - flush_dcache_page(page); + /* + * Split the transfer when it splits a page boundary. Note that the + * split still has to be dword aligned like all ATA data transfers. + */ + WARN_ON_ONCE(offset % 4); + if (offset + qc->sect_size > PAGE_SIZE) { + unsigned int split_len = PAGE_SIZE - offset; + + ata_pio_xfer(qc, page, offset, split_len); + ata_pio_xfer(qc, nth_page(page, 1), 0, + qc->sect_size - split_len); + } else { + ata_pio_xfer(qc, page, offset, qc->sect_size); + } qc->curbytes += qc->sect_size; qc->cursg_ofs += qc->sect_size; @@ -2679,12 +2698,14 @@ * LOCKING: * spin_lock_irqsave(host lock) */ -void ata_bmdma_qc_prep(struct ata_queued_cmd *qc) +enum ata_completion_errors ata_bmdma_qc_prep(struct ata_queued_cmd *qc) { if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; ata_bmdma_fill_sg(qc); + + return AC_ERR_OK; } EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep); @@ -2697,12 +2718,14 @@ * LOCKING: * spin_lock_irqsave(host lock) */ -void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc) +enum ata_completion_errors ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc) { if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; ata_bmdma_fill_sg_dumb(qc); + + return AC_ERR_OK; } EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep); --- linux-oracle-5.4.0.orig/drivers/ata/libata-transport.c +++ linux-oracle-5.4.0/drivers/ata/libata-transport.c @@ -196,7 +196,7 @@ { XFER_PIO_0, "XFER_PIO_0" }, { XFER_PIO_SLOW, "XFER_PIO_SLOW" } }; -ata_bitfield_name_match(xfer,ata_xfer_names) +ata_bitfield_name_search(xfer, ata_xfer_names) /* * ATA Port attributes @@ -266,6 +266,10 @@ put_device(dev); } +static const struct device_type ata_port_sas_type = { + .name = ATA_PORT_TYPE_NAME, +}; + /** ata_tport_add - initialize a transport ATA port structure * * @parent: parent device @@ -283,7 +287,10 @@ struct device *dev = &ap->tdev; device_initialize(dev); - dev->type = &ata_port_type; + if (ap->flags & ATA_FLAG_SAS_HOST) + dev->type = &ata_port_sas_type; + else + dev->type = &ata_port_type; dev->parent = parent; ata_host_get(ap->host); @@ -317,7 +324,6 @@ tport_err: transport_destroy_device(dev); put_device(dev); - ata_host_put(ap->host); return error; } --- linux-oracle-5.4.0.orig/drivers/ata/libata.h +++ linux-oracle-5.4.0/drivers/ata/libata.h @@ -30,6 +30,8 @@ ATA_DNXFER_QUIET = (1 << 31), }; +#define ATA_PORT_TYPE_NAME "ata_port" + extern atomic_t ata_print_id; extern int atapi_passthru16; extern int libata_fua; --- linux-oracle-5.4.0.orig/drivers/ata/pata_arasan_cf.c +++ linux-oracle-5.4.0/drivers/ata/pata_arasan_cf.c @@ -817,12 +817,19 @@ else quirk = CF_BROKEN_UDMA; /* as it is on spear1340 */ - /* if irq is 0, support only PIO */ - acdev->irq = platform_get_irq(pdev, 0); - if (acdev->irq) + /* + * If there's an error getting IRQ (or we do get IRQ0), + * support only PIO + */ + ret = platform_get_irq(pdev, 0); + if (ret > 0) { + acdev->irq = ret; irq_handler = arasan_cf_interrupt; - else + } else if (ret == -EPROBE_DEFER) { + return ret; + } else { quirk |= CF_BROKEN_MWDMA | CF_BROKEN_UDMA; + } acdev->pbase = res->start; acdev->vbase = devm_ioremap_nocache(&pdev->dev, res->start, --- linux-oracle-5.4.0.orig/drivers/ata/pata_ep93xx.c +++ linux-oracle-5.4.0/drivers/ata/pata_ep93xx.c @@ -928,7 +928,7 @@ /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */ irq = platform_get_irq(pdev, 0); if (irq < 0) { - err = -ENXIO; + err = irq; goto err_rel_gpio; } --- linux-oracle-5.4.0.orig/drivers/ata/pata_ftide010.c +++ linux-oracle-5.4.0/drivers/ata/pata_ftide010.c @@ -570,6 +570,7 @@ }; module_platform_driver(pata_ftide010_driver); +MODULE_DESCRIPTION("low level driver for Faraday Technology FTIDE010"); MODULE_AUTHOR("Linus Walleij "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); --- linux-oracle-5.4.0.orig/drivers/ata/pata_hpt37x.c +++ linux-oracle-5.4.0/drivers/ata/pata_hpt37x.c @@ -918,6 +918,20 @@ pci_write_config_byte(dev, 0x5a, irqmask); /* + * HPT371 chips physically have only one channel, the secondary one, + * but the primary channel registers do exist! Go figure... + * So, we manually disable the non-existing channel here + * (if the BIOS hasn't done this already). + */ + if (dev->device == PCI_DEVICE_ID_TTI_HPT371) { + u8 mcr1; + + pci_read_config_byte(dev, 0x50, &mcr1); + mcr1 &= ~0x04; + pci_write_config_byte(dev, 0x50, mcr1); + } + + /* * default to pci clock. make sure MA15/16 are set to output * to prevent drives having problems with 40-pin cables. Needed * for some drives such as IBM-DTLA which will not enter ready @@ -948,14 +962,14 @@ if ((freq >> 12) != 0xABCDE) { int i; - u8 sr; + u16 sr; u32 total = 0; pr_warn("BIOS has not set timing clocks\n"); /* This is the process the HPT371 BIOS is reported to use */ for (i = 0; i < 128; i++) { - pci_read_config_byte(dev, 0x78, &sr); + pci_read_config_word(dev, 0x78, &sr); total += sr & 0x1FF; udelay(15); } --- linux-oracle-5.4.0.orig/drivers/ata/pata_isapnp.c +++ linux-oracle-5.4.0/drivers/ata/pata_isapnp.c @@ -82,6 +82,9 @@ if (pnp_port_valid(idev, 1)) { ctl_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 1), 1); + if (!ctl_addr) + return -ENOMEM; + ap->ioaddr.altstatus_addr = ctl_addr; ap->ioaddr.ctl_addr = ctl_addr; ap->ops = &isapnp_port_ops; --- linux-oracle-5.4.0.orig/drivers/ata/pata_ixp4xx_cf.c +++ linux-oracle-5.4.0/drivers/ata/pata_ixp4xx_cf.c @@ -135,12 +135,12 @@ static int ixp4xx_pata_probe(struct platform_device *pdev) { - unsigned int irq; struct resource *cs0, *cs1; struct ata_host *host; struct ata_port *ap; struct ixp4xx_pata_data *data = dev_get_platdata(&pdev->dev); int ret; + int irq; cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -165,8 +165,12 @@ return -ENOMEM; irq = platform_get_irq(pdev, 0); - if (irq) + if (irq > 0) irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + else if (irq < 0) + return irq; + else + return -EINVAL; /* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits; --- linux-oracle-5.4.0.orig/drivers/ata/pata_legacy.c +++ linux-oracle-5.4.0/drivers/ata/pata_legacy.c @@ -114,8 +114,6 @@ static struct legacy_probe probe_list[NR_HOST]; static struct legacy_data legacy_data[NR_HOST]; static struct ata_host *legacy_host[NR_HOST]; -static int nr_legacy_host; - static int probe_all; /* Set to check all ISA port ranges */ static int ht6560a; /* HT 6560A on primary 1, second 2, both 3 */ @@ -278,9 +276,10 @@ outb(inb(0x1F4) & 0x07, 0x1F4); rt = inb(0x1F3); - rt &= 0x07 << (3 * adev->devno); + rt &= ~(0x07 << (3 * !adev->devno)); if (pio) - rt |= (1 + 3 * pio) << (3 * adev->devno); + rt |= (1 + 3 * pio) << (3 * !adev->devno); + outb(rt, 0x1F3); udelay(100); outb(inb(0x1F2) | 0x01, 0x1F2); @@ -315,7 +314,8 @@ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - __le32 pad; + __le32 pad = 0; + if (rw == READ) { pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); memcpy(buf + buflen - slop, &pad, slop); @@ -705,7 +705,8 @@ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); if (unlikely(slop)) { - __le32 pad; + __le32 pad = 0; + if (rw == WRITE) { memcpy(&pad, buf + buflen - slop, slop); iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); @@ -1236,9 +1237,11 @@ { int i; - for (i = 0; i < nr_legacy_host; i++) { + for (i = 0; i < NR_HOST; i++) { struct legacy_data *ld = &legacy_data[i]; - ata_host_detach(legacy_host[i]); + + if (legacy_host[i]) + ata_host_detach(legacy_host[i]); platform_device_unregister(ld->platform_dev); } } --- linux-oracle-5.4.0.orig/drivers/ata/pata_macio.c +++ linux-oracle-5.4.0/drivers/ata/pata_macio.c @@ -510,7 +510,7 @@ return ATA_CBL_PATA40; } -static void pata_macio_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors pata_macio_qc_prep(struct ata_queued_cmd *qc) { unsigned int write = (qc->tf.flags & ATA_TFLAG_WRITE); struct ata_port *ap = qc->ap; @@ -523,7 +523,7 @@ __func__, qc, qc->flags, write, qc->dev->devno); if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; table = (struct dbdma_cmd *) priv->dma_table_cpu; @@ -540,7 +540,8 @@ while (sg_len) { /* table overflow should never happen */ - BUG_ON (pi++ >= MAX_DCMDS); + if (WARN_ON_ONCE(pi >= MAX_DCMDS)) + return AC_ERR_SYSTEM; len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG; table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE); @@ -552,11 +553,13 @@ addr += len; sg_len -= len; ++table; + ++pi; } } /* Should never happen according to Tejun */ - BUG_ON(!pi); + if (WARN_ON_ONCE(!pi)) + return AC_ERR_SYSTEM; /* Convert the last command to an input/output */ table--; @@ -568,6 +571,8 @@ table->command = cpu_to_le16(DBDMA_STOP); dev_dbgdma(priv->dev, "%s: %d DMA list entries\n", __func__, pi); + + return AC_ERR_OK; } --- linux-oracle-5.4.0.orig/drivers/ata/pata_marvell.c +++ linux-oracle-5.4.0/drivers/ata/pata_marvell.c @@ -83,6 +83,8 @@ switch(ap->port_no) { case 0: + if (!ap->ioaddr.bmdma_addr) + return ATA_CBL_PATA_UNK; if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1) return ATA_CBL_PATA40; return ATA_CBL_PATA80; --- linux-oracle-5.4.0.orig/drivers/ata/pata_ns87415.c +++ linux-oracle-5.4.0/drivers/ata/pata_ns87415.c @@ -261,7 +261,7 @@ * LOCKING: * Inherited from caller. */ -void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; --- linux-oracle-5.4.0.orig/drivers/ata/pata_octeon_cf.c +++ linux-oracle-5.4.0/drivers/ata/pata_octeon_cf.c @@ -888,20 +888,24 @@ int i; res_dma = platform_get_resource(dma_dev, IORESOURCE_MEM, 0); if (!res_dma) { + put_device(&dma_dev->dev); of_node_put(dma_node); return -EINVAL; } cf_port->dma_base = (u64)devm_ioremap_nocache(&pdev->dev, res_dma->start, resource_size(res_dma)); if (!cf_port->dma_base) { + put_device(&dma_dev->dev); of_node_put(dma_node); return -EINVAL; } - irq_handler = octeon_cf_interrupt; i = platform_get_irq(dma_dev, 0); - if (i > 0) + if (i > 0) { irq = i; + irq_handler = octeon_cf_interrupt; + } + put_device(&dma_dev->dev); } of_node_put(dma_node); } --- linux-oracle-5.4.0.orig/drivers/ata/pata_pxa.c +++ linux-oracle-5.4.0/drivers/ata/pata_pxa.c @@ -44,25 +44,27 @@ /* * Prepare taskfile for submission. */ -static void pxa_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors pxa_qc_prep(struct ata_queued_cmd *qc) { struct pata_pxa_data *pd = qc->ap->private_data; struct dma_async_tx_descriptor *tx; enum dma_transfer_direction dir; if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; dir = (qc->dma_dir == DMA_TO_DEVICE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); tx = dmaengine_prep_slave_sg(pd->dma_chan, qc->sg, qc->n_elem, dir, DMA_PREP_INTERRUPT); if (!tx) { ata_dev_err(qc->dev, "prep_slave_sg() failed\n"); - return; + return AC_ERR_OK; } tx->callback = pxa_ata_dma_irq; tx->callback_param = pd; pd->dma_cookie = dmaengine_submit(tx); + + return AC_ERR_OK; } /* --- linux-oracle-5.4.0.orig/drivers/ata/pata_rb532_cf.c +++ linux-oracle-5.4.0/drivers/ata/pata_rb532_cf.c @@ -115,10 +115,12 @@ } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(&pdev->dev, "no IRQ resource found\n"); - return -ENOENT; + return irq; } + if (!irq) + return -EINVAL; gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN); if (IS_ERR(gpiod)) { --- linux-oracle-5.4.0.orig/drivers/ata/pdc_adma.c +++ linux-oracle-5.4.0/drivers/ata/pdc_adma.c @@ -116,7 +116,7 @@ const struct pci_device_id *ent); static int adma_port_start(struct ata_port *ap); static void adma_port_stop(struct ata_port *ap); -static void adma_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors adma_qc_prep(struct ata_queued_cmd *qc); static unsigned int adma_qc_issue(struct ata_queued_cmd *qc); static int adma_check_atapi_dma(struct ata_queued_cmd *qc); static void adma_freeze(struct ata_port *ap); @@ -295,7 +295,7 @@ return i; } -static void adma_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors adma_qc_prep(struct ata_queued_cmd *qc) { struct adma_port_priv *pp = qc->ap->private_data; u8 *buf = pp->pkt; @@ -306,7 +306,7 @@ adma_enter_reg_mode(qc->ap); if (qc->tf.protocol != ATA_PROT_DMA) - return; + return AC_ERR_OK; buf[i++] = 0; /* Response flags */ buf[i++] = 0; /* reserved */ @@ -371,6 +371,7 @@ printk("%s\n", obuf); } #endif + return AC_ERR_OK; } static inline void adma_packet_start(struct ata_queued_cmd *qc) --- linux-oracle-5.4.0.orig/drivers/ata/sata_dwc_460ex.c +++ linux-oracle-5.4.0/drivers/ata/sata_dwc_460ex.c @@ -145,7 +145,11 @@ #endif }; -#define SATA_DWC_QCMD_MAX 32 +/* + * Allow one extra special slot for commands and DMA management + * to account for libata internal commands. + */ +#define SATA_DWC_QCMD_MAX (ATA_MAX_QUEUE + 1) struct sata_dwc_device_port { struct sata_dwc_device *hsdev; @@ -1249,24 +1253,20 @@ irq = irq_of_parse_and_map(np, 0); if (irq == NO_IRQ) { dev_err(&ofdev->dev, "no SATA DMA irq\n"); - err = -ENODEV; - goto error_out; + return -ENODEV; } #ifdef CONFIG_SATA_DWC_OLD_DMA if (!of_find_property(np, "dmas", NULL)) { err = sata_dwc_dma_init_old(ofdev, hsdev); if (err) - goto error_out; + return err; } #endif hsdev->phy = devm_phy_optional_get(hsdev->dev, "sata-phy"); - if (IS_ERR(hsdev->phy)) { - err = PTR_ERR(hsdev->phy); - hsdev->phy = NULL; - goto error_out; - } + if (IS_ERR(hsdev->phy)) + return PTR_ERR(hsdev->phy); err = phy_init(hsdev->phy); if (err) --- linux-oracle-5.4.0.orig/drivers/ata/sata_fsl.c +++ linux-oracle-5.4.0/drivers/ata/sata_fsl.c @@ -502,7 +502,7 @@ return num_prde; } -static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors sata_fsl_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct sata_fsl_port_priv *pp = ap->private_data; @@ -548,6 +548,8 @@ VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n", desc_info, ttl_dwords, num_prde); + + return AC_ERR_OK; } static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) @@ -1278,7 +1280,7 @@ i, ioread32(hcr_base + CC), ioread32(hcr_base + CA)); } - ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); + ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); return; } else if ((ap->qc_active & (1ULL << ATA_TAG_INTERNAL))) { @@ -1392,6 +1394,14 @@ return 0; } +static void sata_fsl_host_stop(struct ata_host *host) +{ + struct sata_fsl_host_priv *host_priv = host->private_data; + + iounmap(host_priv->hcr_base); + kfree(host_priv); +} + /* * scsi mid-layer and libata interface structures */ @@ -1424,6 +1434,8 @@ .port_start = sata_fsl_port_start, .port_stop = sata_fsl_port_stop, + .host_stop = sata_fsl_host_stop, + .pmp_attach = sata_fsl_pmp_attach, .pmp_detach = sata_fsl_pmp_detach, }; @@ -1478,9 +1490,9 @@ host_priv->ssr_base = ssr_base; host_priv->csr_base = csr_base; - irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); - if (!irq) { - dev_err(&ofdev->dev, "invalid irq from platform\n"); + irq = platform_get_irq(ofdev, 0); + if (irq < 0) { + retval = irq; goto error_exit_with_cleanup; } host_priv->irq = irq; @@ -1555,10 +1567,6 @@ ata_host_detach(host); - irq_dispose_mapping(host_priv->irq); - iounmap(host_priv->hcr_base); - kfree(host_priv); - return 0; } --- linux-oracle-5.4.0.orig/drivers/ata/sata_gemini.c +++ linux-oracle-5.4.0/drivers/ata/sata_gemini.c @@ -201,7 +201,10 @@ pclk = sg->sata0_pclk; else pclk = sg->sata1_pclk; - clk_enable(pclk); + ret = clk_enable(pclk); + if (ret) + return ret; + msleep(10); /* Do not keep clocking a bridge that is not online */ @@ -435,6 +438,7 @@ }; module_platform_driver(gemini_sata_driver); +MODULE_DESCRIPTION("low level driver for Cortina Systems Gemini SATA bridge"); MODULE_AUTHOR("Linus Walleij "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); --- linux-oracle-5.4.0.orig/drivers/ata/sata_highbank.c +++ linux-oracle-5.4.0/drivers/ata/sata_highbank.c @@ -348,6 +348,7 @@ phy_nodes[phy] = phy_data.np; cphy_base[phy] = of_iomap(phy_nodes[phy], 0); if (cphy_base[phy] == NULL) { + of_node_put(phy_data.np); return 0; } phy_count += 1; @@ -469,10 +470,12 @@ } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(dev, "no irq\n"); - return -EINVAL; + return irq; } + if (!irq) + return -EINVAL; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { --- linux-oracle-5.4.0.orig/drivers/ata/sata_inic162x.c +++ linux-oracle-5.4.0/drivers/ata/sata_inic162x.c @@ -478,7 +478,7 @@ prd[-1].flags |= PRD_END; } -static void inic_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors inic_qc_prep(struct ata_queued_cmd *qc) { struct inic_port_priv *pp = qc->ap->private_data; struct inic_pkt *pkt = pp->pkt; @@ -538,6 +538,8 @@ inic_fill_sg(prd, qc); pp->cpb_tbl[0] = pp->pkt_dma; + + return AC_ERR_OK; } static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) --- linux-oracle-5.4.0.orig/drivers/ata/sata_mv.c +++ linux-oracle-5.4.0/drivers/ata/sata_mv.c @@ -592,8 +592,8 @@ static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); static int mv_qc_defer(struct ata_queued_cmd *qc); -static void mv_qc_prep(struct ata_queued_cmd *qc); -static void mv_qc_prep_iie(struct ata_queued_cmd *qc); +static enum ata_completion_errors mv_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors mv_qc_prep_iie(struct ata_queued_cmd *qc); static unsigned int mv_qc_issue(struct ata_queued_cmd *qc); static int mv_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); @@ -783,37 +783,6 @@ }, }; -static const struct pci_device_id mv_pci_tbl[] = { - { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, - { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, - { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, - /* RocketRAID 1720/174x have different identifiers */ - { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, - - { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, - { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, - { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, - { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, - - { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, - - /* Adaptec 1430SA */ - { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, - - /* Marvell 7042 support */ - { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, - - /* Highpoint RocketRAID PCIe series */ - { PCI_VDEVICE(TTI, 0x2300), chip_7042 }, - { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, - - { } /* terminate list */ -}; - static const struct mv_hw_ops mv5xxx_ops = { .phy_errata = mv5_phy_errata, .enable_leds = mv5_enable_leds, @@ -2031,7 +2000,7 @@ * LOCKING: * Inherited from caller. */ -static void mv_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors mv_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct mv_port_priv *pp = ap->private_data; @@ -2043,15 +2012,15 @@ switch (tf->protocol) { case ATA_PROT_DMA: if (tf->command == ATA_CMD_DSM) - return; + return AC_ERR_OK; /* fall-thru */ case ATA_PROT_NCQ: break; /* continue below */ case ATA_PROT_PIO: mv_rw_multi_errata_sata24(qc); - return; + return AC_ERR_OK; default: - return; + return AC_ERR_OK; } /* Fill in command request block @@ -2098,12 +2067,10 @@ * non-NCQ mode are: [RW] STREAM DMA and W DMA FUA EXT, none * of which are defined/used by Linux. If we get here, this * driver needs work. - * - * FIXME: modify libata to give qc_prep a return value and - * return error here. */ - BUG_ON(tf->command); - break; + ata_port_err(ap, "%s: unsupported command: %.2x\n", __func__, + tf->command); + return AC_ERR_INVALID; } mv_crqb_pack_cmd(cw++, tf->nsect, ATA_REG_NSECT, 0); mv_crqb_pack_cmd(cw++, tf->hob_lbal, ATA_REG_LBAL, 0); @@ -2116,8 +2083,10 @@ mv_crqb_pack_cmd(cw++, tf->command, ATA_REG_CMD, 1); /* last */ if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; mv_fill_sg(qc); + + return AC_ERR_OK; } /** @@ -2132,7 +2101,7 @@ * LOCKING: * Inherited from caller. */ -static void mv_qc_prep_iie(struct ata_queued_cmd *qc) +static enum ata_completion_errors mv_qc_prep_iie(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct mv_port_priv *pp = ap->private_data; @@ -2143,9 +2112,9 @@ if ((tf->protocol != ATA_PROT_DMA) && (tf->protocol != ATA_PROT_NCQ)) - return; + return AC_ERR_OK; if (tf->command == ATA_CMD_DSM) - return; /* use bmdma for this */ + return AC_ERR_OK; /* use bmdma for this */ /* Fill in Gen IIE command request block */ if (!(tf->flags & ATA_TFLAG_WRITE)) @@ -2186,8 +2155,10 @@ ); if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; mv_fill_sg(qc); + + return AC_ERR_OK; } /** @@ -2827,7 +2798,7 @@ } if (work_done) { - ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); + ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); /* Update the software queue position index in hardware */ writelfl((pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK) | @@ -3890,8 +3861,8 @@ break; default: - dev_err(host->dev, "BUG: invalid board index %u\n", board_idx); - return 1; + dev_alert(host->dev, "BUG: invalid board index %u\n", board_idx); + return -EINVAL; } hpriv->hp_flags = hp_flags; @@ -4095,6 +4066,10 @@ n_ports = mv_platform_data->n_ports; irq = platform_get_irq(pdev, 0); } + if (irq < 0) + return irq; + if (!irq) + return -EINVAL; host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); @@ -4301,6 +4276,36 @@ static int mv_pci_device_resume(struct pci_dev *pdev); #endif +static const struct pci_device_id mv_pci_tbl[] = { + { PCI_VDEVICE(MARVELL, 0x5040), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, + { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, + { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1720/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, + + { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, + { PCI_VDEVICE(MARVELL, 0x6042), chip_6042 }, + { PCI_VDEVICE(MARVELL, 0x6080), chip_608x }, + { PCI_VDEVICE(MARVELL, 0x6081), chip_608x }, + + { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + + /* Adaptec 1430SA */ + { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, + + /* Marvell 7042 support */ + { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 }, + + /* Highpoint RocketRAID PCIe series */ + { PCI_VDEVICE(TTI, 0x2300), chip_7042 }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, + + { } /* terminate list */ +}; static struct pci_driver mv_pci_driver = { .name = DRV_NAME, @@ -4313,6 +4318,7 @@ #endif }; +MODULE_DEVICE_TABLE(pci, mv_pci_tbl); /** * mv_print_info - Dump key info to kernel log for perusal. @@ -4485,7 +4491,6 @@ MODULE_AUTHOR("Brett Russ"); MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers"); MODULE_LICENSE("GPL v2"); -MODULE_DEVICE_TABLE(pci, mv_pci_tbl); MODULE_VERSION(DRV_VERSION); MODULE_ALIAS("platform:" DRV_NAME); --- linux-oracle-5.4.0.orig/drivers/ata/sata_nv.c +++ linux-oracle-5.4.0/drivers/ata/sata_nv.c @@ -297,7 +297,7 @@ static void nv_ck804_thaw(struct ata_port *ap); static int nv_adma_slave_config(struct scsi_device *sdev); static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); -static void nv_adma_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors nv_adma_qc_prep(struct ata_queued_cmd *qc); static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc); static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance); static void nv_adma_irq_clear(struct ata_port *ap); @@ -319,7 +319,7 @@ static void nv_swncq_error_handler(struct ata_port *ap); static int nv_swncq_slave_config(struct scsi_device *sdev); static int nv_swncq_port_start(struct ata_port *ap); -static void nv_swncq_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors nv_swncq_qc_prep(struct ata_queued_cmd *qc); static void nv_swncq_fill_sg(struct ata_queued_cmd *qc); static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc); static void nv_swncq_irq_clear(struct ata_port *ap, u16 fis); @@ -984,7 +984,7 @@ check_commands = 0; check_commands &= ~(1 << pos); } - ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); + ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); } } @@ -1344,7 +1344,7 @@ return 1; } -static void nv_adma_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors nv_adma_qc_prep(struct ata_queued_cmd *qc) { struct nv_adma_port_priv *pp = qc->ap->private_data; struct nv_adma_cpb *cpb = &pp->cpb[qc->hw_tag]; @@ -1356,7 +1356,7 @@ (qc->flags & ATA_QCFLAG_DMAMAP)); nv_adma_register_mode(qc->ap); ata_bmdma_qc_prep(qc); - return; + return AC_ERR_OK; } cpb->resp_flags = NV_CPB_RESP_DONE; @@ -1388,6 +1388,8 @@ cpb->ctl_flags = ctl_flags; wmb(); cpb->resp_flags = 0; + + return AC_ERR_OK; } static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) @@ -1950,17 +1952,19 @@ return 0; } -static void nv_swncq_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors nv_swncq_qc_prep(struct ata_queued_cmd *qc) { if (qc->tf.protocol != ATA_PROT_NCQ) { ata_bmdma_qc_prep(qc); - return; + return AC_ERR_OK; } if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; nv_swncq_fill_sg(qc); + + return AC_ERR_OK; } static void nv_swncq_fill_sg(struct ata_queued_cmd *qc) @@ -2096,7 +2100,7 @@ pp->dhfis_bits &= ~done_mask; pp->dmafis_bits &= ~done_mask; pp->sdbfis_bits |= done_mask; - ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); + ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); if (!ap->qc_active) { DPRINTK("over\n"); --- linux-oracle-5.4.0.orig/drivers/ata/sata_promise.c +++ linux-oracle-5.4.0/drivers/ata/sata_promise.c @@ -139,7 +139,7 @@ static int pdc_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int pdc_common_port_start(struct ata_port *ap); static int pdc_sata_port_start(struct ata_port *ap); -static void pdc_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors pdc_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static int pdc_check_atapi_dma(struct ata_queued_cmd *qc); @@ -633,7 +633,7 @@ prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } -static void pdc_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors pdc_qc_prep(struct ata_queued_cmd *qc) { struct pdc_port_priv *pp = qc->ap->private_data; unsigned int i; @@ -665,6 +665,8 @@ default: break; } + + return AC_ERR_OK; } static int pdc_is_sataii_tx4(unsigned long flags) --- linux-oracle-5.4.0.orig/drivers/ata/sata_qstor.c +++ linux-oracle-5.4.0/drivers/ata/sata_qstor.c @@ -100,7 +100,7 @@ static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); -static void qs_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors qs_qc_prep(struct ata_queued_cmd *qc); static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); static int qs_check_atapi_dma(struct ata_queued_cmd *qc); static void qs_freeze(struct ata_port *ap); @@ -260,7 +260,7 @@ return si; } -static void qs_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors qs_qc_prep(struct ata_queued_cmd *qc) { struct qs_port_priv *pp = qc->ap->private_data; u8 dflags = QS_DF_PORD, *buf = pp->pkt; @@ -272,7 +272,7 @@ qs_enter_reg_mode(qc->ap); if (qc->tf.protocol != ATA_PROT_DMA) - return; + return AC_ERR_OK; nelem = qs_fill_sg(qc); @@ -295,6 +295,8 @@ /* frame information structure (FIS) */ ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); + + return AC_ERR_OK; } static inline void qs_packet_start(struct ata_queued_cmd *qc) --- linux-oracle-5.4.0.orig/drivers/ata/sata_rcar.c +++ linux-oracle-5.4.0/drivers/ata/sata_rcar.c @@ -120,7 +120,7 @@ /* Descriptor table word 0 bit (when DTA32M = 1) */ #define SATA_RCAR_DTEND BIT(0) -#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFEUL +#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFFUL /* Gen2 Physical Layer Control Registers */ #define RCAR_GEN2_PHY_CTL1_REG 0x1704 @@ -550,12 +550,14 @@ prd[si - 1].addr |= cpu_to_le32(SATA_RCAR_DTEND); } -static void sata_rcar_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors sata_rcar_qc_prep(struct ata_queued_cmd *qc) { if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; sata_rcar_bmdma_fill_sg(qc); + + return AC_ERR_OK; } static void sata_rcar_bmdma_setup(struct ata_queued_cmd *qc) @@ -905,7 +907,7 @@ pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) - goto err_pm_disable; + goto err_pm_put; host = ata_host_alloc(dev, 1); if (!host) { @@ -935,7 +937,6 @@ err_pm_put: pm_runtime_put(dev); -err_pm_disable: pm_runtime_disable(dev); return ret; } @@ -989,8 +990,10 @@ int ret; ret = pm_runtime_get_sync(dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(dev); return ret; + } if (priv->type == RCAR_GEN3_SATA) { sata_rcar_init_module(priv); @@ -1015,8 +1018,10 @@ int ret; ret = pm_runtime_get_sync(dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(dev); return ret; + } sata_rcar_setup_port(host); --- linux-oracle-5.4.0.orig/drivers/ata/sata_sil.c +++ linux-oracle-5.4.0/drivers/ata/sata_sil.c @@ -103,7 +103,7 @@ static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed); -static void sil_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors sil_qc_prep(struct ata_queued_cmd *qc); static void sil_bmdma_setup(struct ata_queued_cmd *qc); static void sil_bmdma_start(struct ata_queued_cmd *qc); static void sil_bmdma_stop(struct ata_queued_cmd *qc); @@ -128,7 +128,7 @@ static const struct sil_drivelist { const char *product; unsigned int quirk; -} sil_blacklist [] = { +} sil_quirks[] = { { "ST320012AS", SIL_QUIRK_MOD15WRITE }, { "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE }, @@ -317,12 +317,14 @@ last_prd->flags_len |= cpu_to_le32(ATA_PRD_EOT); } -static void sil_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors sil_qc_prep(struct ata_queued_cmd *qc) { if (!(qc->flags & ATA_QCFLAG_DMAMAP)) - return; + return AC_ERR_OK; sil_fill_sg(qc); + + return AC_ERR_OK; } static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) @@ -599,8 +601,8 @@ * list, and apply the fixups to only the specific * devices/hosts/firmwares that need it. * - * 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted - * The Maxtor quirk is in the blacklist, but I'm keeping the original + * 20040111 - Seagate drives affected by the Mod15Write bug are quirked + * The Maxtor quirk is in sil_quirks, but I'm keeping the original * pessimistic fix for the following reasons... * - There seems to be less info on it, only one device gleaned off the * Windows driver, maybe only one is affected. More info would be greatly @@ -619,9 +621,9 @@ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); - for (n = 0; sil_blacklist[n].product; n++) - if (!strcmp(sil_blacklist[n].product, model_num)) { - quirks = sil_blacklist[n].quirk; + for (n = 0; sil_quirks[n].product; n++) + if (!strcmp(sil_quirks[n].product, model_num)) { + quirks = sil_quirks[n].quirk; break; } --- linux-oracle-5.4.0.orig/drivers/ata/sata_sil24.c +++ linux-oracle-5.4.0/drivers/ata/sata_sil24.c @@ -326,7 +326,7 @@ static int sil24_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val); static int sil24_scr_write(struct ata_link *link, unsigned sc_reg, u32 val); static int sil24_qc_defer(struct ata_queued_cmd *qc); -static void sil24_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors sil24_qc_prep(struct ata_queued_cmd *qc); static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc); static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc); static void sil24_pmp_attach(struct ata_port *ap); @@ -830,7 +830,7 @@ return ata_std_qc_defer(qc); } -static void sil24_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors sil24_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct sil24_port_priv *pp = ap->private_data; @@ -874,6 +874,8 @@ if (qc->flags & ATA_QCFLAG_DMAMAP) sil24_fill_sg(qc, sge); + + return AC_ERR_OK; } static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) --- linux-oracle-5.4.0.orig/drivers/ata/sata_sx4.c +++ linux-oracle-5.4.0/drivers/ata/sata_sx4.c @@ -202,7 +202,7 @@ static void pdc_freeze(struct ata_port *ap); static void pdc_thaw(struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); -static void pdc20621_qc_prep(struct ata_queued_cmd *qc); +static enum ata_completion_errors pdc20621_qc_prep(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf); static unsigned int pdc20621_dimm_init(struct ata_host *host); @@ -530,7 +530,7 @@ VPRINTK("ata pkt buf ofs %u, mmio copied\n", i); } -static void pdc20621_qc_prep(struct ata_queued_cmd *qc) +static enum ata_completion_errors pdc20621_qc_prep(struct ata_queued_cmd *qc) { switch (qc->tf.protocol) { case ATA_PROT_DMA: @@ -542,6 +542,8 @@ default: break; } + + return AC_ERR_OK; } static void __pdc20621_push_hdma(struct ata_queued_cmd *qc, @@ -1002,8 +1004,7 @@ offset -= (idx * window_size); idx++; - dist = ((long) (window_size - (offset + size))) >= 0 ? size : - (long) (window_size - offset); + dist = min(size, window_size - offset); memcpy_fromio(psource, dimm_mmio + offset / 4, dist); psource += dist; @@ -1051,8 +1052,7 @@ readl(mmio + PDC_DIMM_WINDOW_CTLR); offset -= (idx * window_size); idx++; - dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : - (long) (window_size - offset); + dist = min(size, window_size - offset); memcpy_toio(dimm_mmio + offset / 4, psource, dist); writel(0x01, mmio + PDC_GENERAL_CTLR); readl(mmio + PDC_GENERAL_CTLR); --- linux-oracle-5.4.0.orig/drivers/atm/atmtcp.c +++ linux-oracle-5.4.0/drivers/atm/atmtcp.c @@ -433,9 +433,15 @@ return -EMEDIUMTYPE; } dev_data = PRIV(dev); - if (!dev_data->persist) return 0; + if (!dev_data->persist) { + atm_dev_put(dev); + return 0; + } dev_data->persist = 0; - if (PRIV(dev)->vcc) return 0; + if (PRIV(dev)->vcc) { + atm_dev_put(dev); + return 0; + } kfree(dev_data); atm_dev_put(dev); atm_dev_deregister(dev); --- linux-oracle-5.4.0.orig/drivers/atm/eni.c +++ linux-oracle-5.4.0/drivers/atm/eni.c @@ -374,7 +374,7 @@ here = (eni_vcc->descr+skip) & (eni_vcc->words-1); dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK; - j++; + dma[j++] = 0; } here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1); if (!eff) size += skip; @@ -447,7 +447,7 @@ if (size != eff) { dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK; - j++; + dma[j++] = 0; } if (!j || j > 2*RX_DMA_BUF) { printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n"); @@ -1116,6 +1116,8 @@ } paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr)) + return enq_next; ENI_PRV_PADDR(skb) = paddr; /* prepare DMA queue entries */ j = 0; @@ -2245,7 +2247,7 @@ rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); if (rc < 0) - goto out; + goto err_disable; rc = -ENOMEM; eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL); @@ -2281,7 +2283,8 @@ return rc; err_eni_release: - eni_do_release(dev); + dev->phy = NULL; + iounmap(ENI_DEV(dev)->ioaddr); err_unregister: atm_dev_deregister(dev); err_free_consistent: --- linux-oracle-5.4.0.orig/drivers/atm/firestream.c +++ linux-oracle-5.4.0/drivers/atm/firestream.c @@ -912,6 +912,7 @@ } if (!to) { printk ("No more free channels for FS50..\n"); + kfree(vcc); return -EBUSY; } vcc->channo = dev->channo; @@ -922,6 +923,7 @@ if (((DO_DIRECTION(rxtp) && dev->atm_vccs[vcc->channo])) || ( DO_DIRECTION(txtp) && test_bit (vcc->channo, dev->tx_inuse))) { printk ("Channel is in use for FS155.\n"); + kfree(vcc); return -EBUSY; } } @@ -935,6 +937,7 @@ tc, sizeof (struct fs_transmit_config)); if (!tc) { fs_dprintk (FS_DEBUG_OPEN, "fs: can't alloc transmit_config.\n"); + kfree(vcc); return -ENOMEM; } @@ -995,6 +998,7 @@ error = make_rate (pcr, r, &tmc0, NULL); if (error) { kfree(tc); + kfree(vcc); return error; } } @@ -1673,6 +1677,8 @@ dev->hw_base = pci_resource_start(pci_dev, 0); dev->base = ioremap(dev->hw_base, 0x1000); + if (!dev->base) + return 1; reset_chip (dev); --- linux-oracle-5.4.0.orig/drivers/atm/fore200e.c +++ linux-oracle-5.4.0/drivers/atm/fore200e.c @@ -1414,12 +1414,14 @@ static void fore200e_close(struct atm_vcc* vcc) { - struct fore200e* fore200e = FORE200E_DEV(vcc->dev); struct fore200e_vcc* fore200e_vcc; + struct fore200e* fore200e; struct fore200e_vc_map* vc_map; unsigned long flags; ASSERT(vcc); + fore200e = FORE200E_DEV(vcc->dev); + ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<vci >= 0) && (vcc->vci < 1<dev); - struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc); + struct fore200e* fore200e; + struct fore200e_vcc* fore200e_vcc; struct fore200e_vc_map* vc_map; - struct host_txq* txq = &fore200e->host_txq; + struct host_txq* txq; struct host_txq_entry* entry; struct tpd* tpd; struct tpd_haddr tpd_haddr; @@ -1480,9 +1482,18 @@ unsigned char* data; unsigned long flags; - ASSERT(vcc); - ASSERT(fore200e); - ASSERT(fore200e_vcc); + if (!vcc) + return -EINVAL; + + fore200e = FORE200E_DEV(vcc->dev); + fore200e_vcc = FORE200E_VCC(vcc); + + if (!fore200e) + return -EINVAL; + + txq = &fore200e->host_txq; + if (!fore200e_vcc) + return -EINVAL; if (!test_bit(ATM_VF_READY, &vcc->flags)) { DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi); --- linux-oracle-5.4.0.orig/drivers/atm/idt77105.c +++ linux-oracle-5.4.0/drivers/atm/idt77105.c @@ -262,7 +262,7 @@ { unsigned long flags; - if (!(dev->dev_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) + if (!(dev->phy_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) return -ENOMEM; PRIV(dev)->dev = dev; spin_lock_irqsave(&idt77105_priv_lock, flags); @@ -337,7 +337,7 @@ else idt77105_all = walk->next; dev->phy = NULL; - dev->dev_data = NULL; + dev->phy_data = NULL; kfree(walk); break; } --- linux-oracle-5.4.0.orig/drivers/atm/idt77252.c +++ linux-oracle-5.4.0/drivers/atm/idt77252.c @@ -1117,8 +1117,8 @@ rpp->len += skb->len; if (stat & SAR_RSQE_EPDU) { + unsigned int len, truesize; unsigned char *l1l2; - unsigned int len; l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6); @@ -1188,14 +1188,15 @@ ATM_SKB(skb)->vcc = vcc; __net_timestamp(skb); + truesize = skb->truesize; vcc->push(vcc, skb); atomic_inc(&vcc->stats->rx); - if (skb->truesize > SAR_FB_SIZE_3) + if (truesize > SAR_FB_SIZE_3) add_rx_skb(card, 3, SAR_FB_SIZE_3, 1); - else if (skb->truesize > SAR_FB_SIZE_2) + else if (truesize > SAR_FB_SIZE_2) add_rx_skb(card, 2, SAR_FB_SIZE_2, 1); - else if (skb->truesize > SAR_FB_SIZE_1) + else if (truesize > SAR_FB_SIZE_1) add_rx_skb(card, 1, SAR_FB_SIZE_1, 1); else add_rx_skb(card, 0, SAR_FB_SIZE_0, 1); @@ -2914,6 +2915,7 @@ recycle_rx_pool_skb(card, &vc->rcv.rx_pool); } + kfree(vc); } } } @@ -2934,6 +2936,8 @@ vc->scq = alloc_scq(card, vc->class); if (!vc->scq) { printk("%s: can't get SCQ.\n", card->name); + kfree(card->vcs[0]); + card->vcs[0] = NULL; return -ENOMEM; } @@ -2957,6 +2961,15 @@ return 0; } +static void +close_card_ubr0(struct idt77252_dev *card) +{ + struct vc_map *vc = card->vcs[0]; + + free_scq(card, vc->scq); + kfree(vc); +} + static int idt77252_dev_open(struct idt77252_dev *card) { @@ -3006,6 +3019,7 @@ struct idt77252_dev *card = dev->dev_data; u32 conf; + close_card_ubr0(card); close_card_oam(card); conf = SAR_CFG_RXPTH | /* enable receive path */ @@ -3606,7 +3620,7 @@ if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); - return err; + goto err_out_disable_pdev; } card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); @@ -3766,6 +3780,7 @@ card = idt77252_chain; dev = card->atmdev; idt77252_chain = card->next; + del_timer_sync(&card->tst_timer); if (dev->phy->stop) dev->phy->stop(dev); --- linux-oracle-5.4.0.orig/drivers/atm/iphase.c +++ linux-oracle-5.4.0/drivers/atm/iphase.c @@ -2290,19 +2290,21 @@ static int reset_sar(struct atm_dev *dev) { IADEV *iadev; - int i, error = 1; + int i, error; unsigned int pci[64]; iadev = INPH_IA_DEV(dev); - for(i=0; i<64; i++) - if ((error = pci_read_config_dword(iadev->pci, - i*4, &pci[i])) != PCIBIOS_SUCCESSFUL) - return error; + for (i = 0; i < 64; i++) { + error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]); + if (error != PCIBIOS_SUCCESSFUL) + return error; + } writel(0, iadev->reg+IPHASE5575_EXT_RESET); - for(i=0; i<64; i++) - if ((error = pci_write_config_dword(iadev->pci, - i*4, pci[i])) != PCIBIOS_SUCCESSFUL) - return error; + for (i = 0; i < 64; i++) { + error = pci_write_config_dword(iadev->pci, i * 4, pci[i]); + if (error != PCIBIOS_SUCCESSFUL) + return error; + } udelay(5); return 0; } @@ -3295,7 +3297,7 @@ { pci_unregister_driver(&ia_driver); - del_timer(&ia_timer); + del_timer_sync(&ia_timer); } module_init(ia_module_init); --- linux-oracle-5.4.0.orig/drivers/atm/lanai.c +++ linux-oracle-5.4.0/drivers/atm/lanai.c @@ -2234,6 +2234,7 @@ conf1_write(lanai); #endif iounmap(lanai->base); + lanai->base = NULL; error_pci: pci_disable_device(lanai->pci); error: @@ -2246,6 +2247,8 @@ static void lanai_dev_close(struct atm_dev *atmdev) { struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data; + if (lanai->base==NULL) + return; printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n", lanai->number); lanai_timed_poll_stop(lanai); @@ -2555,7 +2558,7 @@ struct atm_dev *atmdev; int result; - lanai = kmalloc(sizeof(*lanai), GFP_KERNEL); + lanai = kzalloc(sizeof(*lanai), GFP_KERNEL); if (lanai == NULL) { printk(KERN_ERR DEV_LABEL ": couldn't allocate dev_data structure!\n"); --- linux-oracle-5.4.0.orig/drivers/atm/nicstar.c +++ linux-oracle-5.4.0/drivers/atm/nicstar.c @@ -297,7 +297,7 @@ { XPRINTK("nicstar: nicstar_cleanup() called.\n"); - del_timer(&ns_timer); + del_timer_sync(&ns_timer); pci_unregister_driver(&nicstar_driver); @@ -525,6 +525,15 @@ /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ writel(0x00000000, card->membase + VPM); + card->intcnt = 0; + if (request_irq + (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { + pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); + error = 9; + ns_init_card_error(card, error); + return error; + } + /* Initialize TSQ */ card->tsq.org = dma_alloc_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, @@ -751,15 +760,6 @@ card->efbie = 1; - card->intcnt = 0; - if (request_irq - (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { - printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); - error = 9; - ns_init_card_error(card, error); - return error; - } - /* Register device */ card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, -1, NULL); @@ -837,10 +837,12 @@ dev_kfree_skb_any(hb); } if (error >= 12) { - kfree(card->rsq.org); + dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT, + card->rsq.org, card->rsq.dma); } if (error >= 11) { - kfree(card->tsq.org); + dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, + card->tsq.org, card->tsq.dma); } if (error >= 10) { free_irq(card->pcidev->irq, card); @@ -1706,6 +1708,8 @@ if (push_scqe(card, vc, scq, &scqe, skb) != 0) { atomic_inc(&vcc->stats->tx_err); + dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len, + DMA_TO_DEVICE); dev_kfree_skb_any(skb); return -EIO; } --- linux-oracle-5.4.0.orig/drivers/atm/solos-pci.c +++ linux-oracle-5.4.0/drivers/atm/solos-pci.c @@ -449,9 +449,9 @@ struct sk_buff *skb; unsigned int len; - spin_lock(&card->cli_queue_lock); + spin_lock_bh(&card->cli_queue_lock); skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); - spin_unlock(&card->cli_queue_lock); + spin_unlock_bh(&card->cli_queue_lock); if(skb == NULL) return sprintf(buf, "No data.\n"); @@ -956,14 +956,14 @@ struct pkt_hdr *header; /* Remove any yet-to-be-transmitted packets from the pending queue */ - spin_lock(&card->tx_queue_lock); + spin_lock_bh(&card->tx_queue_lock); skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) { if (SKB_CB(skb)->vcc == vcc) { skb_unlink(skb, &card->tx_queue[port]); solos_pop(vcc, skb); } } - spin_unlock(&card->tx_queue_lock); + spin_unlock_bh(&card->tx_queue_lock); skb = alloc_skb(sizeof(*header), GFP_KERNEL); if (!skb) { --- linux-oracle-5.4.0.orig/drivers/atm/uPD98402.c +++ linux-oracle-5.4.0/drivers/atm/uPD98402.c @@ -211,7 +211,7 @@ static int uPD98402_start(struct atm_dev *dev) { DPRINTK("phy_start\n"); - if (!(dev->dev_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) + if (!(dev->phy_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL))) return -ENOMEM; spin_lock_init(&PRIV(dev)->lock); memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats)); --- linux-oracle-5.4.0.orig/drivers/atm/zatm.c +++ linux-oracle-5.4.0/drivers/atm/zatm.c @@ -940,7 +940,7 @@ vcc->qos.txtp.max_pcr >= ATM_OC3_PCR); if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr; else { - int uninitialized_var(pcr); + int pcr; if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU; if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr, --- linux-oracle-5.4.0.orig/drivers/auxdisplay/ht16k33.c +++ linux-oracle-5.4.0/drivers/auxdisplay/ht16k33.c @@ -117,8 +117,7 @@ { struct ht16k33_fbdev *fbdev = &priv->fbdev; - schedule_delayed_work(&fbdev->work, - msecs_to_jiffies(HZ / fbdev->refresh_rate)); + schedule_delayed_work(&fbdev->work, HZ / fbdev->refresh_rate); } /* @@ -220,6 +219,15 @@ .check_fb = ht16k33_bl_check_fb, }; +/* + * Blank events will be passed to the actual device handling the backlight when + * we return zero here. + */ +static int ht16k33_blank(int blank, struct fb_info *info) +{ + return 0; +} + static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct ht16k33_priv *priv = info->par; @@ -232,6 +240,7 @@ .owner = THIS_MODULE, .fb_read = fb_sys_read, .fb_write = fb_sys_write, + .fb_blank = ht16k33_blank, .fb_fillrect = sys_fillrect, .fb_copyarea = sys_copyarea, .fb_imageblit = sys_imageblit, @@ -419,6 +428,33 @@ if (err) return err; + /* Backlight */ + memset(&bl_props, 0, sizeof(struct backlight_properties)); + bl_props.type = BACKLIGHT_RAW; + bl_props.max_brightness = MAX_BRIGHTNESS; + + bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", + &client->dev, priv, + &ht16k33_bl_ops, &bl_props); + if (IS_ERR(bl)) { + dev_err(&client->dev, "failed to register backlight\n"); + return PTR_ERR(bl); + } + + err = of_property_read_u32(node, "default-brightness-level", + &dft_brightness); + if (err) { + dft_brightness = MAX_BRIGHTNESS; + } else if (dft_brightness > MAX_BRIGHTNESS) { + dev_warn(&client->dev, + "invalid default brightness level: %u, using %u\n", + dft_brightness, MAX_BRIGHTNESS); + dft_brightness = MAX_BRIGHTNESS; + } + + bl->props.brightness = dft_brightness; + ht16k33_bl_update_status(bl); + /* Framebuffer (2 bytes per column) */ BUILD_BUG_ON(PAGE_SIZE < HT16K33_FB_SIZE); fbdev->buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL); @@ -451,6 +487,7 @@ fbdev->info->screen_size = HT16K33_FB_SIZE; fbdev->info->fix = ht16k33_fb_fix; fbdev->info->var = ht16k33_fb_var; + fbdev->info->bl_dev = bl; fbdev->info->pseudo_palette = NULL; fbdev->info->flags = FBINFO_FLAG_DEFAULT; fbdev->info->par = priv; @@ -463,34 +500,6 @@ if (err) goto err_fbdev_unregister; - /* Backlight */ - memset(&bl_props, 0, sizeof(struct backlight_properties)); - bl_props.type = BACKLIGHT_RAW; - bl_props.max_brightness = MAX_BRIGHTNESS; - - bl = devm_backlight_device_register(&client->dev, DRIVER_NAME"-bl", - &client->dev, priv, - &ht16k33_bl_ops, &bl_props); - if (IS_ERR(bl)) { - dev_err(&client->dev, "failed to register backlight\n"); - err = PTR_ERR(bl); - goto err_fbdev_unregister; - } - - err = of_property_read_u32(node, "default-brightness-level", - &dft_brightness); - if (err) { - dft_brightness = MAX_BRIGHTNESS; - } else if (dft_brightness > MAX_BRIGHTNESS) { - dev_warn(&client->dev, - "invalid default brightness level: %u, using %u\n", - dft_brightness, MAX_BRIGHTNESS); - dft_brightness = MAX_BRIGHTNESS; - } - - bl->props.brightness = dft_brightness; - ht16k33_bl_update_status(bl); - ht16k33_fb_queue(priv); return 0; --- linux-oracle-5.4.0.orig/drivers/auxdisplay/img-ascii-lcd.c +++ linux-oracle-5.4.0/drivers/auxdisplay/img-ascii-lcd.c @@ -280,6 +280,16 @@ if (msg[count - 1] == '\n') count--; + if (!count) { + /* clear the LCD */ + devm_kfree(&ctx->pdev->dev, ctx->message); + ctx->message = NULL; + ctx->message_len = 0; + memset(ctx->curr, ' ', ctx->cfg->num_chars); + ctx->cfg->update(ctx); + return 0; + } + new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); if (!new_msg) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/base/arch_topology.c +++ linux-oracle-5.4.0/drivers/base/arch_topology.c @@ -48,7 +48,7 @@ { struct cpu *cpu = container_of(dev, struct cpu, dev); - return sprintf(buf, "%lu\n", topology_get_cpu_scale(cpu->dev.id)); + return sysfs_emit(buf, "%lu\n", topology_get_cpu_scale(cpu->dev.id)); } static void update_topology_flags_workfn(struct work_struct *work); @@ -270,7 +270,7 @@ static int __init parse_core(struct device_node *core, int package_id, int core_id) { - char name[10]; + char name[20]; bool leaf = true; int i = 0; int cpu; @@ -317,7 +317,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth) { - char name[10]; + char name[20]; bool leaf = true; bool has_cores = false; struct device_node *c; @@ -457,7 +457,7 @@ for_each_online_cpu(cpu) { cpu_topo = &cpu_topology[cpu]; - if (cpuid_topo->llc_id == cpu_topo->llc_id) { + if (cpu_topo->llc_id != -1 && cpuid_topo->llc_id == cpu_topo->llc_id) { cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling); cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling); } @@ -538,4 +538,23 @@ else if (of_have_populated_dt() && parse_dt_topology()) reset_cpu_topology(); } + +void store_cpu_topology(unsigned int cpuid) +{ + struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; + + if (cpuid_topo->package_id != -1) + goto topology_populated; + + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = cpuid; + cpuid_topo->package_id = cpu_to_node(cpuid); + + pr_debug("CPU%u: package %d core %d thread %d\n", + cpuid, cpuid_topo->package_id, cpuid_topo->core_id, + cpuid_topo->thread_id); + +topology_populated: + update_siblings_masks(cpuid); +} #endif --- linux-oracle-5.4.0.orig/drivers/base/bus.c +++ linux-oracle-5.4.0/drivers/base/bus.c @@ -103,7 +103,8 @@ { struct bus_attribute *bus_attr = to_bus_attr(attr); struct subsys_private *subsys_priv = to_subsys_private(kobj); - ssize_t ret = 0; + /* return -EIO for reading a bus attribute without show() */ + ssize_t ret = -EIO; if (bus_attr->show) ret = bus_attr->show(subsys_priv->bus, buf); @@ -115,7 +116,8 @@ { struct bus_attribute *bus_attr = to_bus_attr(attr); struct subsys_private *subsys_priv = to_subsys_private(kobj); - ssize_t ret = 0; + /* return -EIO for writing a bus attribute without store() */ + ssize_t ret = -EIO; if (bus_attr->store) ret = bus_attr->store(subsys_priv->bus, buf, count); @@ -620,7 +622,7 @@ if (drv->bus->p->drivers_autoprobe) { error = driver_attach(drv); if (error) - goto out_unregister; + goto out_del_list; } module_add_driver(drv->owner, drv); @@ -647,6 +649,8 @@ return 0; +out_del_list: + klist_del(&priv->knode_bus); out_unregister: kobject_put(&priv->kobj); /* drv->p is freed in driver_release() */ @@ -869,6 +873,8 @@ bus_remove_file(bus, &bus_attr_uevent); bus_uevent_fail: kset_unregister(&bus->p->subsys); + /* Above kset_unregister() will kfree @bus->p */ + bus->p = NULL; out: kfree(bus->p); bus->p = NULL; --- linux-oracle-5.4.0.orig/drivers/base/cacheinfo.c +++ linux-oracle-5.4.0/drivers/base/cacheinfo.c @@ -377,7 +377,7 @@ { struct cacheinfo *this_leaf = dev_get_drvdata(dev); - return sprintf(buf, "%uK\n", this_leaf->size >> 10); + return sysfs_emit(buf, "%uK\n", this_leaf->size >> 10); } static ssize_t shared_cpumap_show_func(struct device *dev, bool list, char *buf) @@ -407,11 +407,11 @@ switch (this_leaf->type) { case CACHE_TYPE_DATA: - return sprintf(buf, "Data\n"); + return sysfs_emit(buf, "Data\n"); case CACHE_TYPE_INST: - return sprintf(buf, "Instruction\n"); + return sysfs_emit(buf, "Instruction\n"); case CACHE_TYPE_UNIFIED: - return sprintf(buf, "Unified\n"); + return sysfs_emit(buf, "Unified\n"); default: return -EINVAL; } @@ -425,11 +425,11 @@ int n = 0; if ((ci_attr & CACHE_READ_ALLOCATE) && (ci_attr & CACHE_WRITE_ALLOCATE)) - n = sprintf(buf, "ReadWriteAllocate\n"); + n = sysfs_emit(buf, "ReadWriteAllocate\n"); else if (ci_attr & CACHE_READ_ALLOCATE) - n = sprintf(buf, "ReadAllocate\n"); + n = sysfs_emit(buf, "ReadAllocate\n"); else if (ci_attr & CACHE_WRITE_ALLOCATE) - n = sprintf(buf, "WriteAllocate\n"); + n = sysfs_emit(buf, "WriteAllocate\n"); return n; } @@ -441,9 +441,9 @@ int n = 0; if (ci_attr & CACHE_WRITE_THROUGH) - n = sprintf(buf, "WriteThrough\n"); + n = sysfs_emit(buf, "WriteThrough\n"); else if (ci_attr & CACHE_WRITE_BACK) - n = sprintf(buf, "WriteBack\n"); + n = sysfs_emit(buf, "WriteBack\n"); return n; } --- linux-oracle-5.4.0.orig/drivers/base/class.c +++ linux-oracle-5.4.0/drivers/base/class.c @@ -191,6 +191,11 @@ } error = class_add_groups(class_get(cls), cls->class_groups); class_put(cls); + if (error) { + kobject_del(&cp->subsys.kobj); + kfree_const(cp->subsys.kobj.name); + kfree(cp); + } return error; } EXPORT_SYMBOL_GPL(__class_register); --- linux-oracle-5.4.0.orig/drivers/base/component.c +++ linux-oracle-5.4.0/drivers/base/component.c @@ -102,11 +102,11 @@ seq_printf(s, "%-40s %20s\n", "device name", "status"); seq_puts(s, "-------------------------------------------------------------\n"); for (i = 0; i < match->num; i++) { - struct device *d = (struct device *)match->compare[i].data; + struct component *component = match->compare[i].component; - seq_printf(s, "%-40s %20s\n", dev_name(d), - match->compare[i].component ? - "registered" : "not registered"); + seq_printf(s, "%-40s %20s\n", + component ? dev_name(component->dev) : "(unknown)", + component ? (component->bound ? "bound" : "not bound") : "not registered"); } mutex_unlock(&component_mutex); @@ -257,7 +257,8 @@ ret = master->ops->bind(master->dev); if (ret < 0) { devres_release_group(master->dev, NULL); - dev_info(master->dev, "master bind failed: %d\n", ret); + if (ret != -EPROBE_DEFER) + dev_info(master->dev, "master bind failed: %d\n", ret); return ret; } @@ -611,8 +612,9 @@ devres_release_group(component->dev, NULL); devres_release_group(master->dev, NULL); - dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", - dev_name(component->dev), component->ops, ret); + if (ret != -EPROBE_DEFER) + dev_err(master->dev, "failed to bind %s (ops %ps): %d\n", + dev_name(component->dev), component->ops, ret); } return ret; --- linux-oracle-5.4.0.orig/drivers/base/core.c +++ linux-oracle-5.4.0/drivers/base/core.c @@ -106,6 +106,16 @@ #endif #endif /* !CONFIG_SRCU */ +static bool device_is_ancestor(struct device *dev, struct device *target) +{ + while (target->parent) { + target = target->parent; + if (dev == target) + return true; + } + return false; +} + /** * device_is_dependent - Check if one device depends on another one * @dev: Device to check dependencies for. @@ -119,7 +129,12 @@ struct device_link *link; int ret; - if (dev == target) + /* + * The "ancestors" check is needed to catch the case when the target + * device has not been completely initialized yet and it is still + * missing from the list of children of its parent device. + */ + if (dev == target || device_is_ancestor(dev, target)) return 1; ret = device_for_each_child(dev, target, device_is_dependent); @@ -454,8 +469,7 @@ dev_dbg(link->consumer, "Dropping the link to %s\n", dev_name(link->supplier)); - if (link->flags & DL_FLAG_PM_RUNTIME) - pm_runtime_drop_link(link->consumer); + pm_runtime_drop_link(link); list_del_rcu(&link->s_node); list_del_rcu(&link->c_node); @@ -469,8 +483,7 @@ dev_info(link->consumer, "Dropping the link to %s\n", dev_name(link->supplier)); - if (link->flags & DL_FLAG_PM_RUNTIME) - pm_runtime_drop_link(link->consumer); + pm_runtime_drop_link(link); list_del(&link->s_node); list_del(&link->c_node); @@ -1014,7 +1027,7 @@ char *buf) { struct dev_ext_attribute *ea = to_ext_attr(attr); - return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var)); + return sysfs_emit(buf, "%lx\n", *(unsigned long *)(ea->var)); } EXPORT_SYMBOL_GPL(device_show_ulong); @@ -1044,7 +1057,7 @@ { struct dev_ext_attribute *ea = to_ext_attr(attr); - return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var)); + return sysfs_emit(buf, "%d\n", *(int *)(ea->var)); } EXPORT_SYMBOL_GPL(device_show_int); @@ -1065,7 +1078,7 @@ { struct dev_ext_attribute *ea = to_ext_attr(attr); - return snprintf(buf, PAGE_SIZE, "%d\n", *(bool *)(ea->var)); + return sysfs_emit(buf, "%d\n", *(bool *)(ea->var)); } EXPORT_SYMBOL_GPL(device_show_bool); @@ -1260,8 +1273,11 @@ if (!env) return -ENOMEM; + /* Synchronize with really_probe() */ + device_lock(dev); /* let the kset specific function add its keys */ retval = kset->uevent_ops->uevent(kset, &dev->kobj, env); + device_unlock(dev); if (retval) goto out; @@ -1297,7 +1313,7 @@ device_lock(dev); val = !dev->offline; device_unlock(dev); - return sprintf(buf, "%u\n", val); + return sysfs_emit(buf, "%u\n", val); } static ssize_t online_store(struct device *dev, struct device_attribute *attr, @@ -1709,6 +1725,7 @@ device_pm_init(dev); set_dev_node(dev, -1); #ifdef CONFIG_GENERIC_MSI_IRQ + raw_spin_lock_init(&dev->msi_lock); INIT_LIST_HEAD(&dev->msi_list); #endif INIT_LIST_HEAD(&dev->links.consumers); @@ -2604,6 +2621,26 @@ } EXPORT_SYMBOL_GPL(device_find_child_by_name); +static int match_any(struct device *dev, void *unused) +{ + return 1; +} + +/** + * device_find_any_child - device iterator for locating a child device, if any. + * @parent: parent struct device + * + * This is similar to the device_find_child() function above, but it + * returns a reference to a child device, if any. + * + * NOTE: you will need to drop the reference with put_device() after use. + */ +struct device *device_find_any_child(struct device *parent) +{ + return device_find_child(parent, NULL, match_any); +} +EXPORT_SYMBOL_GPL(device_find_any_child); + int __init devices_init(void) { devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL); @@ -3170,6 +3207,126 @@ } EXPORT_SYMBOL_GPL(device_move); +static int device_attrs_change_owner(struct device *dev, kuid_t kuid, + kgid_t kgid) +{ + struct kobject *kobj = &dev->kobj; + struct class *class = dev->class; + const struct device_type *type = dev->type; + int error; + + if (class) { + /* + * Change the device groups of the device class for @dev to + * @kuid/@kgid. + */ + error = sysfs_groups_change_owner(kobj, class->dev_groups, kuid, + kgid); + if (error) + return error; + } + + if (type) { + /* + * Change the device groups of the device type for @dev to + * @kuid/@kgid. + */ + error = sysfs_groups_change_owner(kobj, type->groups, kuid, + kgid); + if (error) + return error; + } + + /* Change the device groups of @dev to @kuid/@kgid. */ + error = sysfs_groups_change_owner(kobj, dev->groups, kuid, kgid); + if (error) + return error; + + if (device_supports_offline(dev) && !dev->offline_disabled) { + /* Change online device attributes of @dev to @kuid/@kgid. */ + error = sysfs_file_change_owner(kobj, dev_attr_online.attr.name, + kuid, kgid); + if (error) + return error; + } + + return 0; +} + +/** + * device_change_owner - change the owner of an existing device. + * @dev: device. + * @kuid: new owner's kuid + * @kgid: new owner's kgid + * + * This changes the owner of @dev and its corresponding sysfs entries to + * @kuid/@kgid. This function closely mirrors how @dev was added via driver + * core. + * + * Returns 0 on success or error code on failure. + */ +int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) +{ + int error; + struct kobject *kobj = &dev->kobj; + + dev = get_device(dev); + if (!dev) + return -EINVAL; + + /* + * Change the kobject and the default attributes and groups of the + * ktype associated with it to @kuid/@kgid. + */ + error = sysfs_change_owner(kobj, kuid, kgid); + if (error) + goto out; + + /* + * Change the uevent file for @dev to the new owner. The uevent file + * was created in a separate step when @dev got added and we mirror + * that step here. + */ + error = sysfs_file_change_owner(kobj, dev_attr_uevent.attr.name, kuid, + kgid); + if (error) + goto out; + + /* + * Change the device groups, the device groups associated with the + * device class, and the groups associated with the device type of @dev + * to @kuid/@kgid. + */ + error = device_attrs_change_owner(dev, kuid, kgid); + if (error) + goto out; + + error = dpm_sysfs_change_owner(dev, kuid, kgid); + if (error) + goto out; + +#ifdef CONFIG_BLOCK + if (sysfs_deprecated && dev->class == &block_class) + goto out; +#endif + + /* + * Change the owner of the symlink located in the class directory of + * the device class associated with @dev which points to the actual + * directory entry for @dev to @kuid/@kgid. This ensures that the + * symlink shows the same permissions as its target. + */ + error = sysfs_link_change_owner(&dev->class->p->subsys.kobj, &dev->kobj, + dev_name(dev), kuid, kgid); + if (error) + goto out; + +out: + put_device(dev); + return error; +} +EXPORT_SYMBOL_GPL(device_change_owner); + /** * device_shutdown - call ->shutdown() on each device to shutdown. */ @@ -3385,6 +3542,50 @@ #endif +/** + * dev_err_probe - probe error check and log helper + * @dev: the pointer to the struct device + * @err: error value to test + * @fmt: printf-style format string + * @...: arguments as specified in the format string + * + * This helper implements common pattern present in probe functions for error + * checking: print debug or error message depending if the error value is + * -EPROBE_DEFER and propagate error upwards. + * It replaces code sequence:: + * if (err != -EPROBE_DEFER) + * dev_err(dev, ...); + * else + * dev_dbg(dev, ...); + * return err; + * + * with:: + * + * return dev_err_probe(dev, err, ...); + * + * Returns @err. + * + */ +int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; + + if (err != -EPROBE_DEFER) + dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + else + dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf); + + va_end(args); + + return err; +} +EXPORT_SYMBOL_GPL(dev_err_probe); + static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) { return fwnode && !IS_ERR(fwnode->secondary); @@ -3400,9 +3601,10 @@ */ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode) { - if (fwnode) { - struct fwnode_handle *fn = dev->fwnode; + struct device *parent = dev->parent; + struct fwnode_handle *fn = dev->fwnode; + if (fwnode) { if (fwnode_is_primary(fn)) fn = fn->secondary; @@ -3412,8 +3614,13 @@ } dev->fwnode = fwnode; } else { - dev->fwnode = fwnode_is_primary(dev->fwnode) ? - dev->fwnode->secondary : NULL; + if (fwnode_is_primary(fn)) { + dev->fwnode = fn->secondary; + if (!(parent && fn == parent->fwnode)) + fn->secondary = NULL; + } else { + dev->fwnode = NULL; + } } } EXPORT_SYMBOL_GPL(set_primary_fwnode); @@ -3454,6 +3661,13 @@ } EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); +void device_set_node(struct device *dev, struct fwnode_handle *fwnode) +{ + dev->fwnode = fwnode; + dev->of_node = to_of_node(fwnode); +} +EXPORT_SYMBOL_GPL(device_set_node); + int device_match_name(struct device *dev, const void *name) { return sysfs_streq(dev_name(dev), name); --- linux-oracle-5.4.0.orig/drivers/base/cpu.c +++ linux-oracle-5.4.0/drivers/base/cpu.c @@ -156,7 +156,7 @@ * operation should be safe. No locking required. */ addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum)); - rc = sprintf(buf, "%Lx\n", addr); + rc = sysfs_emit(buf, "%Lx\n", addr); return rc; } static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); @@ -167,7 +167,7 @@ { ssize_t rc; - rc = sprintf(buf, "%zu\n", sizeof(note_buf_t)); + rc = sysfs_emit(buf, "%zu\n", sizeof(note_buf_t)); return rc; } static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL); @@ -231,8 +231,7 @@ static ssize_t print_cpus_kernel_max(struct device *dev, struct device_attribute *attr, char *buf) { - int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1); - return n; + return sprintf(buf, "%d\n", NR_CPUS - 1); } static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL); @@ -272,7 +271,7 @@ static ssize_t print_cpus_isolated(struct device *dev, struct device_attribute *attr, char *buf) { - int n = 0, len = PAGE_SIZE-2; + int n; cpumask_var_t isolated; if (!alloc_cpumask_var(&isolated, GFP_KERNEL)) @@ -280,7 +279,7 @@ cpumask_andnot(isolated, cpu_possible_mask, housekeeping_cpumask(HK_FLAG_DOMAIN)); - n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(isolated)); + n = sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(isolated)); free_cpumask_var(isolated); @@ -292,11 +291,7 @@ static ssize_t print_cpus_nohz_full(struct device *dev, struct device_attribute *attr, char *buf) { - int n = 0, len = PAGE_SIZE-2; - - n = scnprintf(buf, len, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); - - return n; + return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask)); } static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL); #endif @@ -328,8 +323,8 @@ ssize_t n; u32 i; - n = sprintf(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:", - CPU_FEATURE_TYPEVAL); + n = sysfs_emit(buf, "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:", + CPU_FEATURE_TYPEVAL); for (i = 0; i < MAX_CPU_FEATURES; i++) if (cpu_have_feature(i)) { @@ -496,7 +491,8 @@ bool cpu_is_hotpluggable(unsigned cpu) { struct device *dev = get_cpu_device(cpu); - return dev && container_of(dev, struct cpu, dev)->hotpluggable; + return dev && container_of(dev, struct cpu, dev)->hotpluggable + && tick_nohz_cpu_hotpluggable(cpu); } EXPORT_SYMBOL_GPL(cpu_is_hotpluggable); @@ -521,50 +517,74 @@ ssize_t __weak cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_mds(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_tsx_async_abort(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); } ssize_t __weak cpu_show_itlb_multihit(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "Not affected\n"); + return sysfs_emit(buf, "Not affected\n"); +} + +ssize_t __weak cpu_show_srbds(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "Not affected\n"); +} + +ssize_t __weak cpu_show_mmio_stale_data(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "Not affected\n"); +} + +ssize_t __weak cpu_show_retbleed(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "Not affected\n"); +} + +ssize_t __weak cpu_show_gds(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "Not affected\n"); } static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); @@ -575,6 +595,10 @@ static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); static DEVICE_ATTR(tsx_async_abort, 0444, cpu_show_tsx_async_abort, NULL); static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); +static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL); +static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL); +static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL); +static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, @@ -585,6 +609,10 @@ &dev_attr_mds.attr, &dev_attr_tsx_async_abort.attr, &dev_attr_itlb_multihit.attr, + &dev_attr_srbds.attr, + &dev_attr_mmio_stale_data.attr, + &dev_attr_retbleed.attr, + &dev_attr_gather_data_sampling.attr, NULL }; --- linux-oracle-5.4.0.orig/drivers/base/dd.c +++ linux-oracle-5.4.0/drivers/base/dd.c @@ -300,14 +300,16 @@ static void deferred_probe_timeout_work_func(struct work_struct *work) { - struct device_private *private, *p; + struct device_private *p; deferred_probe_timeout = 0; driver_deferred_probe_trigger(); flush_work(&deferred_probe_work); - list_for_each_entry_safe(private, p, &deferred_probe_pending_list, deferred_probe) - dev_info(private->device, "deferred probe pending"); + mutex_lock(&deferred_probe_mutex); + list_for_each_entry(p, &deferred_probe_pending_list, deferred_probe) + dev_info(p->device, "deferred probe pending\n"); + mutex_unlock(&deferred_probe_mutex); } static DECLARE_DELAYED_WORK(deferred_probe_timeout_work, deferred_probe_timeout_work_func); @@ -516,7 +518,11 @@ atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", drv->bus->name, __func__, drv->name, dev_name(dev)); - WARN_ON(!list_empty(&dev->devres_head)); + if (!list_empty(&dev->devres_head)) { + dev_crit(dev, "Resources present before probing\n"); + ret = -EBUSY; + goto done; + } re_probe: dev->driver = drv; @@ -636,7 +642,7 @@ ret = 0; done: atomic_dec(&probe_count); - wake_up(&probe_waitqueue); + wake_up_all(&probe_waitqueue); return ret; } @@ -741,7 +747,7 @@ "Too long list of driver names for 'driver_async_probe'!\n"); strlcpy(async_probe_drv_names, buf, ASYNC_DRV_NAMES_MAX_LEN); - return 0; + return 1; } __setup("driver_async_probe=", save_async_options); @@ -812,6 +818,11 @@ } else if (ret == -EPROBE_DEFER) { dev_dbg(dev, "Device match requests probe deferral\n"); driver_deferred_probe_add(dev); + /* + * Device can't match with a driver right now, so don't attempt + * to match or bind with other drivers on the bus. + */ + return ret; } else if (ret < 0) { dev_dbg(dev, "Bus failed to match device: %d", ret); return ret; @@ -867,9 +878,12 @@ static int __device_attach(struct device *dev, bool allow_async) { int ret = 0; + bool async = false; device_lock(dev); - if (dev->driver) { + if (dev->p->dead) { + goto out_unlock; + } else if (dev->driver) { if (device_is_bound(dev)) { ret = 1; goto out_unlock; @@ -903,7 +917,7 @@ */ dev_dbg(dev, "scheduling asynchronous probe\n"); get_device(dev); - async_schedule_dev(__device_attach_async_helper, dev); + async = true; } else { pm_request_idle(dev); } @@ -913,6 +927,8 @@ } out_unlock: device_unlock(dev); + if (async) + async_schedule_dev(__device_attach_async_helper, dev); return ret; } @@ -1026,6 +1042,7 @@ static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; + bool async = false; int ret; /* @@ -1045,9 +1062,18 @@ } else if (ret == -EPROBE_DEFER) { dev_dbg(dev, "Device match requests probe deferral\n"); driver_deferred_probe_add(dev); + /* + * Driver could not match with device, but may match with + * another device on the bus. + */ + return 0; } else if (ret < 0) { - dev_dbg(dev, "Bus failed to match device: %d", ret); - return ret; + dev_dbg(dev, "Bus failed to match device: %d\n", ret); + /* + * Driver could not match with device, but may match with + * another device on the bus. + */ + return 0; } /* ret > 0 means positive match */ if (driver_allows_async_probing(drv)) { @@ -1063,9 +1089,11 @@ if (!dev->driver) { get_device(dev); dev->p->async_driver = drv; - async_schedule_dev(__driver_attach_async_helper, dev); + async = true; } device_unlock(dev); + if (async) + async_schedule_dev(__driver_attach_async_helper, dev); return 0; } @@ -1099,6 +1127,8 @@ drv = dev->driver; if (drv) { + pm_runtime_get_sync(dev); + while (device_links_busy(dev)) { __device_driver_unlock(dev, parent); @@ -1110,13 +1140,12 @@ * have released the driver successfully while this one * was waiting, so check for that. */ - if (dev->driver != drv) + if (dev->driver != drv) { + pm_runtime_put(dev); return; + } } - pm_runtime_get_sync(dev); - pm_runtime_clean_up_links(dev); - driver_sysfs_remove(dev); if (dev->bus) @@ -1132,8 +1161,13 @@ dev->bus->remove(dev); else if (drv->remove) drv->remove(dev); - - device_links_driver_cleanup(dev); + /* + * A concurrent invocation of the same function might + * have released the driver successfully while this one + * was waiting, so check for that. + */ + if (dev->driver != drv) + return; devres_release_all(dev); arch_teardown_dma_ops(dev); @@ -1144,6 +1178,8 @@ pm_runtime_reinit(dev); dev_pm_set_driver_flags(dev, 0); + device_links_driver_cleanup(dev); + klist_remove(&dev->p->knode_driver); device_pm_check_callbacks(dev); if (dev->bus) --- linux-oracle-5.4.0.orig/drivers/base/devcoredump.c +++ linux-oracle-5.4.0/drivers/base/devcoredump.c @@ -29,6 +29,47 @@ struct device devcd_dev; void *data; size_t datalen; + /* + * Here, mutex is required to serialize the calls to del_wk work between + * user/kernel space which happens when devcd is added with device_add() + * and that sends uevent to user space. User space reads the uevents, + * and calls to devcd_data_write() which try to modify the work which is + * not even initialized/queued from devcoredump. + * + * + * + * cpu0(X) cpu1(Y) + * + * dev_coredump() uevent sent to user space + * device_add() ======================> user space process Y reads the + * uevents writes to devcd fd + * which results into writes to + * + * devcd_data_write() + * mod_delayed_work() + * try_to_grab_pending() + * del_timer() + * debug_assert_init() + * INIT_DELAYED_WORK() + * schedule_delayed_work() + * + * + * Also, mutex alone would not be enough to avoid scheduling of + * del_wk work after it get flush from a call to devcd_free() + * mentioned as below. + * + * disabled_store() + * devcd_free() + * mutex_lock() devcd_data_write() + * flush_delayed_work() + * mutex_unlock() + * mutex_lock() + * mod_delayed_work() + * mutex_unlock() + * So, delete_work flag is required. + */ + struct mutex mutex; + bool delete_work; struct module *owner; ssize_t (*read)(char *buffer, loff_t offset, size_t count, void *data, size_t datalen); @@ -88,7 +129,12 @@ struct device *dev = kobj_to_dev(kobj); struct devcd_entry *devcd = dev_to_devcd(dev); - mod_delayed_work(system_wq, &devcd->del_wk, 0); + mutex_lock(&devcd->mutex); + if (!devcd->delete_work) { + devcd->delete_work = true; + mod_delayed_work(system_wq, &devcd->del_wk, 0); + } + mutex_unlock(&devcd->mutex); return count; } @@ -116,7 +162,12 @@ { struct devcd_entry *devcd = dev_to_devcd(dev); + mutex_lock(&devcd->mutex); + if (!devcd->delete_work) + devcd->delete_work = true; + flush_delayed_work(&devcd->del_wk); + mutex_unlock(&devcd->mutex); return 0; } @@ -126,6 +177,30 @@ return sprintf(buf, "%d\n", devcd_disabled); } +/* + * + * disabled_store() worker() + * class_for_each_device(&devcd_class, + * NULL, NULL, devcd_free) + * ... + * ... + * while ((dev = class_dev_iter_next(&iter)) + * devcd_del() + * device_del() + * put_device() <- last reference + * error = fn(dev, data) devcd_dev_release() + * devcd_free(dev, data) kfree(devcd) + * mutex_lock(&devcd->mutex); + * + * + * In the above diagram, It looks like disabled_store() would be racing with parallely + * running devcd_del() and result in memory abort while acquiring devcd->mutex which + * is called after kfree of devcd memory after dropping its last reference with + * put_device(). However, this will not happens as fn(dev, data) runs + * with its own reference to device via klist_node so it is not its last reference. + * so, above situation would not occur. + */ + static ssize_t disabled_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { @@ -282,13 +357,17 @@ devcd->read = read; devcd->free = free; devcd->failing_dev = get_device(dev); + devcd->delete_work = false; + mutex_init(&devcd->mutex); device_initialize(&devcd->devcd_dev); dev_set_name(&devcd->devcd_dev, "devcd%d", atomic_inc_return(&devcd_count)); devcd->devcd_dev.class = &devcd_class; + mutex_lock(&devcd->mutex); + dev_set_uevent_suppress(&devcd->devcd_dev, true); if (device_add(&devcd->devcd_dev)) goto put_device; @@ -300,12 +379,15 @@ "devcoredump")) /* nothing - symlink will be missing */; + dev_set_uevent_suppress(&devcd->devcd_dev, false); + kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); - + mutex_unlock(&devcd->mutex); return; put_device: put_device(&devcd->devcd_dev); + mutex_unlock(&devcd->mutex); put_module: module_put(owner); free: --- linux-oracle-5.4.0.orig/drivers/base/devres.c +++ linux-oracle-5.4.0/drivers/base/devres.c @@ -561,6 +561,7 @@ grp->id = grp; if (id) grp->id = id; + grp->color = 0; spin_lock_irqsave(&dev->devres_lock, flags); add_dr(dev, &grp->node[0]); @@ -1111,7 +1112,11 @@ */ void devm_free_percpu(struct device *dev, void __percpu *pdata) { - WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, - (void *)pdata)); + /* + * Use devres_release() to prevent memory leakage as + * devm_free_pages() does. + */ + WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match, + (__force void *)pdata)); } EXPORT_SYMBOL_GPL(devm_free_percpu); --- linux-oracle-5.4.0.orig/drivers/base/devtmpfs.c +++ linux-oracle-5.4.0/drivers/base/devtmpfs.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "base.h" @@ -62,8 +63,15 @@ const char *dev_name, void *data) { struct super_block *s = mnt->mnt_sb; + int err; + atomic_inc(&s->s_active); down_write(&s->s_umount); + err = reconfigure_single(s, flags, data); + if (err < 0) { + deactivate_locked_super(s); + return ERR_PTR(err); + } return dget(s->s_root); } --- linux-oracle-5.4.0.orig/drivers/base/driver.c +++ linux-oracle-5.4.0/drivers/base/driver.c @@ -30,6 +30,75 @@ } /** + * driver_set_override() - Helper to set or clear driver override. + * @dev: Device to change + * @override: Address of string to change (e.g. &device->driver_override); + * The contents will be freed and hold newly allocated override. + * @s: NUL-terminated string, new driver name to force a match, pass empty + * string to clear it ("" or "\n", where the latter is only for sysfs + * interface). + * @len: length of @s + * + * Helper to set or clear driver override in a device, intended for the cases + * when the driver_override field is allocated by driver/bus code. + * + * Returns: 0 on success or a negative error code on failure. + */ +int driver_set_override(struct device *dev, const char **override, + const char *s, size_t len) +{ + const char *new, *old; + char *cp; + + if (!override || !s) + return -EINVAL; + + /* + * The stored value will be used in sysfs show callback (sysfs_emit()), + * which has a length limit of PAGE_SIZE and adds a trailing newline. + * Thus we can store one character less to avoid truncation during sysfs + * show. + */ + if (len >= (PAGE_SIZE - 1)) + return -EINVAL; + + if (!len) { + /* Empty string passed - clear override */ + device_lock(dev); + old = *override; + *override = NULL; + device_unlock(dev); + kfree(old); + + return 0; + } + + cp = strnchr(s, len, '\n'); + if (cp) + len = cp - s; + + new = kstrndup(s, len, GFP_KERNEL); + if (!new) + return -ENOMEM; + + device_lock(dev); + old = *override; + if (cp != s) { + *override = new; + } else { + /* "\n" passed - clear override */ + kfree(new); + *override = NULL; + } + device_unlock(dev); + + kfree(old); + + return 0; +} +EXPORT_SYMBOL_GPL(driver_set_override); + +/** * driver_for_each_device - Iterator for devices bound to a driver. * @drv: Driver we're iterating. * @start: Device to begin with --- linux-oracle-5.4.0.orig/drivers/base/firmware_loader/builtin/Makefile +++ linux-oracle-5.4.0/drivers/base/firmware_loader/builtin/Makefile @@ -8,7 +8,8 @@ obj-y := $(addsuffix .gen.o, $(subst $(quote),,$(CONFIG_EXTRA_FIRMWARE))) FWNAME = $(patsubst $(obj)/%.gen.S,%,$@) -FWSTR = $(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME)))) +comma := , +FWSTR = $(subst $(comma),_,$(subst /,_,$(subst .,_,$(subst -,_,$(FWNAME))))) ASM_WORD = $(if $(CONFIG_64BIT),.quad,.long) ASM_ALIGN = $(if $(CONFIG_64BIT),3,2) PROGBITS = $(if $(CONFIG_ARM),%,@)progbits @@ -16,7 +17,7 @@ filechk_fwbin = \ echo "/* Generated by $(src)/Makefile */" ;\ echo " .section .rodata" ;\ - echo " .p2align $(ASM_ALIGN)" ;\ + echo " .p2align 4" ;\ echo "_fw_$(FWSTR)_bin:" ;\ echo " .incbin \"$(fwdir)/$(FWNAME)\"" ;\ echo "_fw_end:" ;\ --- linux-oracle-5.4.0.orig/drivers/base/firmware_loader/fallback.c +++ linux-oracle-5.4.0/drivers/base/firmware_loader/fallback.c @@ -86,12 +86,11 @@ { /* * There is a small window in which user can write to 'loading' - * between loading done and disappearance of 'loading' + * between loading done/aborted and disappearance of 'loading' */ - if (fw_sysfs_done(fw_priv)) + if (fw_state_is_aborted(fw_priv) || fw_sysfs_done(fw_priv)) return; - list_del_init(&fw_priv->pending_list); fw_state_aborted(fw_priv); } @@ -216,7 +215,7 @@ loading = fw_sysfs_loading(fw_sysfs->fw_priv); mutex_unlock(&fw_lock); - return sprintf(buf, "%d\n", loading); + return sysfs_emit(buf, "%d\n", loading); } /** @@ -277,7 +276,6 @@ * Same logic as fw_load_abort, only the DONE bit * is ignored and we set ABORT only on failure. */ - list_del_init(&fw_priv->pending_list); if (rc) { fw_state_aborted(fw_priv); written = rc; @@ -512,6 +510,11 @@ } mutex_lock(&fw_lock); + if (fw_state_is_aborted(fw_priv)) { + mutex_unlock(&fw_lock); + retval = -EINTR; + goto out; + } list_add(&fw_priv->pending_list, &pending_fw_head); mutex_unlock(&fw_lock); @@ -525,7 +528,7 @@ } retval = fw_sysfs_wait_timeout(fw_priv, timeout); - if (retval < 0) { + if (retval < 0 && retval != -ENOENT) { mutex_lock(&fw_lock); fw_load_abort(fw_sysfs); mutex_unlock(&fw_lock); @@ -534,11 +537,10 @@ if (fw_state_is_aborted(fw_priv)) { if (retval == -ERESTARTSYS) retval = -EINTR; - else - retval = -EAGAIN; } else if (fw_priv->is_paged_buf && !fw_priv->data) retval = -ENOMEM; +out: device_del(f_dev); err_put_dev: put_device(f_dev); --- linux-oracle-5.4.0.orig/drivers/base/firmware_loader/firmware.h +++ linux-oracle-5.4.0/drivers/base/firmware_loader/firmware.h @@ -108,8 +108,16 @@ WRITE_ONCE(fw_st->status, status); - if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) + if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) { +#ifdef CONFIG_FW_LOADER_USER_HELPER + /* + * Doing this here ensures that the fw_priv is deleted from + * the pending list in all abort/done paths. + */ + list_del_init(&fw_priv->pending_list); +#endif complete_all(&fw_st->completion); + } } static inline void fw_state_aborted(struct fw_priv *fw_priv) @@ -139,10 +147,12 @@ void fw_free_paged_buf(struct fw_priv *fw_priv); int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed); int fw_map_paged_buf(struct fw_priv *fw_priv); +bool fw_is_paged_buf(struct fw_priv *fw_priv); #else static inline void fw_free_paged_buf(struct fw_priv *fw_priv) {} static inline int fw_grow_paged_buf(struct fw_priv *fw_priv, int pages_needed) { return -ENXIO; } static inline int fw_map_paged_buf(struct fw_priv *fw_priv) { return -ENXIO; } +static inline bool fw_is_paged_buf(struct fw_priv *fw_priv) { return false; } #endif #endif /* __FIRMWARE_LOADER_H */ --- linux-oracle-5.4.0.orig/drivers/base/firmware_loader/main.c +++ linux-oracle-5.4.0/drivers/base/firmware_loader/main.c @@ -98,12 +98,15 @@ extern struct builtin_fw __start_builtin_fw[]; extern struct builtin_fw __end_builtin_fw[]; -static void fw_copy_to_prealloc_buf(struct firmware *fw, +static bool fw_copy_to_prealloc_buf(struct firmware *fw, void *buf, size_t size) { - if (!buf || size < fw->size) - return; + if (!buf) + return true; + if (size < fw->size) + return false; memcpy(buf, fw->data, fw->size); + return true; } static bool fw_get_builtin_firmware(struct firmware *fw, const char *name, @@ -115,9 +118,7 @@ if (strcmp(name, b_fw->name) == 0) { fw->size = b_fw->size; fw->data = b_fw->data; - fw_copy_to_prealloc_buf(fw, buf, size); - - return true; + return fw_copy_to_prealloc_buf(fw, buf, size); } } @@ -252,9 +253,11 @@ list_del(&fw_priv->list); spin_unlock(&fwc->lock); - fw_free_paged_buf(fw_priv); /* free leftover pages */ - if (!fw_priv->allocated_size) + if (fw_is_paged_buf(fw_priv)) + fw_free_paged_buf(fw_priv); + else if (!fw_priv->allocated_size) vfree(fw_priv->data); + kfree_const(fw_priv->fw_name); kfree(fw_priv); } @@ -268,6 +271,11 @@ } #ifdef CONFIG_FW_LOADER_PAGED_BUF +bool fw_is_paged_buf(struct fw_priv *fw_priv) +{ + return fw_priv->is_paged_buf; +} + void fw_free_paged_buf(struct fw_priv *fw_priv) { int i; @@ -275,6 +283,8 @@ if (!fw_priv->pages) return; + vunmap(fw_priv->data); + for (i = 0; i < fw_priv->nr_pages; i++) __free_page(fw_priv->pages[i]); kvfree(fw_priv->pages); @@ -328,10 +338,6 @@ if (!fw_priv->data) return -ENOMEM; - /* page table is no longer needed after mapping, let's free */ - kvfree(fw_priv->pages); - fw_priv->pages = NULL; - return 0; } #endif @@ -742,8 +748,30 @@ return; fw_priv = fw->priv; + mutex_lock(&fw_lock); if (!fw_state_is_aborted(fw_priv)) fw_state_aborted(fw_priv); + mutex_unlock(&fw_lock); +} + +/* + * Reject firmware file names with ".." path components. + * There are drivers that construct firmware file names from device-supplied + * strings, and we don't want some device to be able to tell us "I would like to + * be sent my firmware from ../../../etc/shadow, please". + * + * Search for ".." surrounded by either '/' or start/end of string. + * + * This intentionally only looks at the firmware name, not at the firmware base + * directory or at symlink contents. + */ +static bool name_contains_dotdot(const char *name) +{ + size_t name_len = strlen(name); + + return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 || + strstr(name, "/../") != NULL || + (name_len >= 3 && strcmp(name+name_len-3, "/..") == 0); } /* called from request_firmware() and request_firmware_work_func() */ @@ -753,6 +781,8 @@ enum fw_opt opt_flags) { struct firmware *fw = NULL; + struct cred *kern_cred = NULL; + const struct cred *old_cred; int ret; if (!firmware_p) @@ -763,11 +793,31 @@ goto out; } + if (name_contains_dotdot(name)) { + dev_warn(device, + "Firmware load for '%s' refused, path contains '..' component\n", + name); + ret = -EINVAL; + goto out; + } + ret = _request_firmware_prepare(&fw, name, device, buf, size, opt_flags); if (ret <= 0) /* error or already assigned */ goto out; + /* + * We are about to try to access the firmware file. Because we may have been + * called by a driver when serving an unrelated request from userland, we use + * the kernel credentials to read the file. + */ + kern_cred = prepare_kernel_cred(NULL); + if (!kern_cred) { + ret = -ENOMEM; + goto out; + } + old_cred = override_creds(kern_cred); + ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); #ifdef CONFIG_FW_LOADER_COMPRESS if (ret == -ENOENT) @@ -784,6 +834,9 @@ } else ret = assign_fw(fw, device, opt_flags); + revert_creds(old_cred); + put_cred(kern_cred); + out: if (ret < 0) { fw_abort_batch_reqs(fw); @@ -809,6 +862,8 @@ * @name will be used as $FIRMWARE in the uevent environment and * should be distinctive enough not to be confused with any other * firmware image for this or any other device. + * It must not contain any ".." path components - "foo/bar..bin" is + * allowed, but "foo/../bar.bin" is not. * * Caller must hold the reference count of @device. * --- linux-oracle-5.4.0.orig/drivers/base/memory.c +++ linux-oracle-5.4.0/drivers/base/memory.c @@ -110,34 +110,17 @@ unsigned long phys_index; phys_index = mem->start_section_nr / sections_per_block; - return sprintf(buf, "%08lx\n", phys_index); + return sysfs_emit(buf, "%08lx\n", phys_index); } /* - * Show whether the memory block is likely to be offlineable (or is already - * offline). Once offline, the memory block could be removed. The return - * value does, however, not indicate that there is a way to remove the - * memory block. + * Legacy interface that we cannot remove. Always indicate "removable" + * with CONFIG_MEMORY_HOTREMOVE - bad heuristic. */ static ssize_t removable_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct memory_block *mem = to_memory_block(dev); - unsigned long pfn; - int ret = 1, i; - - if (mem->state != MEM_ONLINE) - goto out; - - for (i = 0; i < sections_per_block; i++) { - if (!present_section_nr(mem->start_section_nr + i)) - continue; - pfn = section_nr_to_pfn(mem->start_section_nr + i); - ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); - } - -out: - return sprintf(buf, "%d\n", ret); + return sysfs_emit(buf, "%d\n", (int)IS_ENABLED(CONFIG_MEMORY_HOTREMOVE)); } /* @@ -155,17 +138,17 @@ */ switch (mem->state) { case MEM_ONLINE: - len = sprintf(buf, "online\n"); + len = sysfs_emit(buf, "online\n"); break; case MEM_OFFLINE: - len = sprintf(buf, "offline\n"); + len = sysfs_emit(buf, "offline\n"); break; case MEM_GOING_OFFLINE: - len = sprintf(buf, "going-offline\n"); + len = sysfs_emit(buf, "going-offline\n"); break; default: - len = sprintf(buf, "ERROR-UNKNOWN-%ld\n", - mem->state); + len = sysfs_emit(buf, "ERROR-UNKNOWN-%ld\n", + mem->state); WARN_ON(1); break; } @@ -375,7 +358,7 @@ struct device_attribute *attr, char *buf) { struct memory_block *mem = to_memory_block(dev); - return sprintf(buf, "%d\n", mem->phys_device); + return sysfs_emit(buf, "%d\n", mem->phys_device); } #ifdef CONFIG_MEMORY_HOTREMOVE @@ -413,7 +396,7 @@ */ if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages, &valid_start_pfn, &valid_end_pfn)) - return sprintf(buf, "none\n"); + return sysfs_emit(buf, "none\n"); start_pfn = valid_start_pfn; strcat(buf, page_zone(pfn_to_page(start_pfn))->name); goto out; @@ -446,7 +429,7 @@ static ssize_t block_size_bytes_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%lx\n", memory_block_size_bytes()); + return sysfs_emit(buf, "%lx\n", memory_block_size_bytes()); } static DEVICE_ATTR_RO(block_size_bytes); @@ -459,9 +442,9 @@ struct device_attribute *attr, char *buf) { if (memhp_auto_online) - return sprintf(buf, "online\n"); + return sysfs_emit(buf, "online\n"); else - return sprintf(buf, "offline\n"); + return sysfs_emit(buf, "offline\n"); } static ssize_t auto_online_blocks_store(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/base/node.c +++ linux-oracle-5.4.0/drivers/base/node.c @@ -262,21 +262,20 @@ if (!dev) return; + device_initialize(dev); dev->parent = &node->dev; dev->release = node_cache_release; if (dev_set_name(dev, "memory_side_cache")) - goto free_dev; + goto put_device; - if (device_register(dev)) - goto free_name; + if (device_add(dev)) + goto put_device; pm_runtime_no_callbacks(dev); node->cache_dev = dev; return; -free_name: - kfree_const(dev->kobj.name); -free_dev: - kfree(dev); +put_device: + put_device(dev); } /** @@ -313,25 +312,24 @@ return; dev = &info->dev; + device_initialize(dev); dev->parent = node->cache_dev; dev->release = node_cacheinfo_release; dev->groups = cache_groups; if (dev_set_name(dev, "index%d", cache_attrs->level)) - goto free_cache; + goto put_device; info->cache_attrs = *cache_attrs; - if (device_register(dev)) { + if (device_add(dev)) { dev_warn(&node->dev, "failed to add cache level:%d\n", cache_attrs->level); - goto free_name; + goto put_device; } pm_runtime_no_callbacks(dev); list_add_tail(&info->node, &node->cache_attrs); return; -free_name: - kfree_const(dev->kobj.name); -free_cache: - kfree(info); +put_device: + put_device(dev); } static void node_remove_caches(struct node *node) @@ -370,7 +368,7 @@ si_meminfo_node(&i, nid); sreclaimable = node_page_state(pgdat, NR_SLAB_RECLAIMABLE); sunreclaimable = node_page_state(pgdat, NR_SLAB_UNRECLAIMABLE); - n = sprintf(buf, + n = sysfs_emit(buf, "Node %d MemTotal: %8lu kB\n" "Node %d MemFree: %8lu kB\n" "Node %d MemUsed: %8lu kB\n" @@ -471,19 +469,19 @@ static ssize_t node_read_numastat(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, - "numa_hit %lu\n" - "numa_miss %lu\n" - "numa_foreign %lu\n" - "interleave_hit %lu\n" - "local_node %lu\n" - "other_node %lu\n", - sum_zone_numa_state(dev->id, NUMA_HIT), - sum_zone_numa_state(dev->id, NUMA_MISS), - sum_zone_numa_state(dev->id, NUMA_FOREIGN), - sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT), - sum_zone_numa_state(dev->id, NUMA_LOCAL), - sum_zone_numa_state(dev->id, NUMA_OTHER)); + return sysfs_emit(buf, + "numa_hit %lu\n" + "numa_miss %lu\n" + "numa_foreign %lu\n" + "interleave_hit %lu\n" + "local_node %lu\n" + "other_node %lu\n", + sum_zone_numa_state(dev->id, NUMA_HIT), + sum_zone_numa_state(dev->id, NUMA_MISS), + sum_zone_numa_state(dev->id, NUMA_FOREIGN), + sum_zone_numa_state(dev->id, NUMA_INTERLEAVE_HIT), + sum_zone_numa_state(dev->id, NUMA_LOCAL), + sum_zone_numa_state(dev->id, NUMA_OTHER)); } static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); @@ -643,6 +641,7 @@ */ void unregister_node(struct node *node) { + compaction_unregister_node(node); hugetlb_unregister_node(node); /* no-op, if memoryless node */ node_remove_accesses(node); node_remove_caches(node); @@ -758,14 +757,36 @@ return pfn_to_nid(pfn); } +static int do_register_memory_block_under_node(int nid, + struct memory_block *mem_blk) +{ + int ret; + + /* + * If this memory block spans multiple nodes, we only indicate + * the last processed node. + */ + mem_blk->nid = nid; + + ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, + &mem_blk->dev.kobj, + kobject_name(&mem_blk->dev.kobj)); + if (ret) + return ret; + + return sysfs_create_link_nowarn(&mem_blk->dev.kobj, + &node_devices[nid]->dev.kobj, + kobject_name(&node_devices[nid]->dev.kobj)); +} + /* register memory section under specified node if it spans that node */ -static int register_mem_sect_under_node(struct memory_block *mem_blk, - void *arg) +static int register_mem_block_under_node_early(struct memory_block *mem_blk, + void *arg) { unsigned long memory_block_pfns = memory_block_size_bytes() / PAGE_SIZE; unsigned long start_pfn = section_nr_to_pfn(mem_blk->start_section_nr); unsigned long end_pfn = start_pfn + memory_block_pfns - 1; - int ret, nid = *(int *)arg; + int nid = *(int *)arg; unsigned long pfn; for (pfn = start_pfn; pfn <= end_pfn; pfn++) { @@ -782,39 +803,34 @@ } /* - * We need to check if page belongs to nid only for the boot - * case, during hotplug we know that all pages in the memory - * block belong to the same node. - */ - if (system_state == SYSTEM_BOOTING) { - page_nid = get_nid_for_pfn(pfn); - if (page_nid < 0) - continue; - if (page_nid != nid) - continue; - } - - /* - * If this memory block spans multiple nodes, we only indicate - * the last processed node. + * We need to check if page belongs to nid only at the boot + * case because node's ranges can be interleaved. */ - mem_blk->nid = nid; - - ret = sysfs_create_link_nowarn(&node_devices[nid]->dev.kobj, - &mem_blk->dev.kobj, - kobject_name(&mem_blk->dev.kobj)); - if (ret) - return ret; + page_nid = get_nid_for_pfn(pfn); + if (page_nid < 0) + continue; + if (page_nid != nid) + continue; - return sysfs_create_link_nowarn(&mem_blk->dev.kobj, - &node_devices[nid]->dev.kobj, - kobject_name(&node_devices[nid]->dev.kobj)); + return do_register_memory_block_under_node(nid, mem_blk); } /* mem section does not span the specified node */ return 0; } /* + * During hotplug we know that all pages in the memory block belong to the same + * node. + */ +static int register_mem_block_under_node_hotplug(struct memory_block *mem_blk, + void *arg) +{ + int nid = *(int *)arg; + + return do_register_memory_block_under_node(nid, mem_blk); +} + +/* * Unregister a memory block device under the node it spans. Memory blocks * with multiple nodes cannot be offlined and therefore also never be removed. */ @@ -829,11 +845,19 @@ kobject_name(&node_devices[mem_blk->nid]->dev.kobj)); } -int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) +int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn, + enum meminit_context context) { + walk_memory_blocks_func_t func; + + if (context == MEMINIT_HOTPLUG) + func = register_mem_block_under_node_hotplug; + else + func = register_mem_block_under_node_early; + return walk_memory_blocks(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn), (void *)&nid, - register_mem_sect_under_node); + func); } #ifdef CONFIG_HUGETLBFS --- linux-oracle-5.4.0.orig/drivers/base/platform.c +++ linux-oracle-5.4.0/drivers/base/platform.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "base.h" #include "power/power.h" @@ -48,7 +49,7 @@ struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -226,7 +227,7 @@ unsigned int type, const char *name) { - int i; + u32 i; for (i = 0; i < dev->num_resources; i++) { struct resource *r = &dev->resource[i]; @@ -334,10 +335,10 @@ { if (!pdev->dev.coherent_dma_mask) pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - if (!pdev->dma_mask) - pdev->dma_mask = DMA_BIT_MASK(32); - if (!pdev->dev.dma_mask) - pdev->dev.dma_mask = &pdev->dma_mask; + if (!pdev->dev.dma_mask) { + pdev->platform_dma_mask = DMA_BIT_MASK(32); + pdev->dev.dma_mask = &pdev->platform_dma_mask; + } }; /** @@ -473,7 +474,8 @@ */ int platform_device_add(struct platform_device *pdev) { - int i, ret; + u32 i; + int ret; if (!pdev) return -EINVAL; @@ -541,7 +543,7 @@ pdev->id = PLATFORM_DEVID_AUTO; } - while (--i >= 0) { + while (i--) { struct resource *r = &pdev->resource[i]; if (r->parent) release_resource(r); @@ -562,7 +564,7 @@ */ void platform_device_del(struct platform_device *pdev) { - int i; + u32 i; if (!IS_ERR_OR_NULL(pdev)) { device_del(&pdev->dev); @@ -632,20 +634,8 @@ pdev->dev.of_node_reused = pdevinfo->of_node_reused; if (pdevinfo->dma_mask) { - /* - * This memory isn't freed when the device is put, - * I don't have a nice idea for that though. Conceptually - * dma_mask in struct device should not be a pointer. - * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 - */ - pdev->dev.dma_mask = - kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); - if (!pdev->dev.dma_mask) - goto err; - - kmemleak_ignore(pdev->dev.dma_mask); - - *pdev->dev.dma_mask = pdevinfo->dma_mask; + pdev->platform_dma_mask = pdevinfo->dma_mask; + pdev->dev.dma_mask = &pdev->platform_dma_mask; pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; } @@ -670,7 +660,6 @@ if (ret) { err: ACPI_COMPANION_SET(&pdev->dev, NULL); - kfree(pdev->dev.dma_mask); platform_device_put(pdev); return ERR_PTR(ret); } @@ -813,6 +802,8 @@ /* temporary section violation during probe() */ drv->probe = probe; retval = code = __platform_driver_register(drv, module); + if (retval) + return retval; /* * Fixup that section violation, being paranoid about code scanning @@ -982,31 +973,11 @@ const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); - char *driver_override, *old, *cp; - - /* We need to keep extra room for a newline */ - if (count >= (PAGE_SIZE - 1)) - return -EINVAL; - - driver_override = kstrndup(buf, count, GFP_KERNEL); - if (!driver_override) - return -ENOMEM; - - cp = strchr(driver_override, '\n'); - if (cp) - *cp = '\0'; - - device_lock(dev); - old = pdev->driver_override; - if (strlen(driver_override)) { - pdev->driver_override = driver_override; - } else { - kfree(driver_override); - pdev->driver_override = NULL; - } - device_unlock(dev); + int ret; - kfree(old); + ret = driver_set_override(dev, &pdev->driver_override, buf, count); + if (ret) + return ret; return count; } @@ -1018,7 +989,7 @@ ssize_t len; device_lock(dev); - len = sprintf(buf, "%s\n", pdev->driver_override); + len = sysfs_emit(buf, "%s\n", pdev->driver_override); device_unlock(dev); return len; } @@ -1278,6 +1249,11 @@ }; EXPORT_SYMBOL_GPL(platform_bus_type); +static inline int __platform_match(struct device *dev, const void *drv) +{ + return platform_match(dev, (struct device_driver *)drv); +} + /** * platform_find_device_by_driver - Find a platform device with a given * driver. @@ -1288,7 +1264,7 @@ const struct device_driver *drv) { return bus_find_device(&platform_bus_type, start, drv, - (void *)platform_match); + __platform_match); } EXPORT_SYMBOL_GPL(platform_find_device_by_driver); --- linux-oracle-5.4.0.orig/drivers/base/power/domain.c +++ linux-oracle-5.4.0/drivers/base/power/domain.c @@ -263,18 +263,18 @@ /* * Traverse all sub-domains within the domain. This can be * done without any additional locking as the link->performance_state - * field is protected by the master genpd->lock, which is already taken. + * field is protected by the parent genpd->lock, which is already taken. * * Also note that link->performance_state (subdomain's performance state - * requirement to master domain) is different from - * link->slave->performance_state (current performance state requirement + * requirement to parent domain) is different from + * link->child->performance_state (current performance state requirement * of the devices/sub-domains of the subdomain) and so can have a * different value. * * Note that we also take vote from powered-off sub-domains into account * as the same is done for devices right now. */ - list_for_each_entry(link, &genpd->master_links, master_node) { + list_for_each_entry(link, &genpd->parent_links, parent_node) { if (link->performance_state > state) state = link->performance_state; } @@ -285,40 +285,40 @@ static int _genpd_set_performance_state(struct generic_pm_domain *genpd, unsigned int state, int depth) { - struct generic_pm_domain *master; + struct generic_pm_domain *parent; struct gpd_link *link; - int master_state, ret; + int parent_state, ret; if (state == genpd->performance_state) return 0; - /* Propagate to masters of genpd */ - list_for_each_entry(link, &genpd->slave_links, slave_node) { - master = link->master; + /* Propagate to parents of genpd */ + list_for_each_entry(link, &genpd->child_links, child_node) { + parent = link->parent; - if (!master->set_performance_state) + if (!parent->set_performance_state) continue; - /* Find master's performance state */ + /* Find parent's performance state */ ret = dev_pm_opp_xlate_performance_state(genpd->opp_table, - master->opp_table, + parent->opp_table, state); if (unlikely(ret < 0)) goto err; - master_state = ret; + parent_state = ret; - genpd_lock_nested(master, depth + 1); + genpd_lock_nested(parent, depth + 1); link->prev_performance_state = link->performance_state; - link->performance_state = master_state; - master_state = _genpd_reeval_performance_state(master, - master_state); - ret = _genpd_set_performance_state(master, master_state, depth + 1); + link->performance_state = parent_state; + parent_state = _genpd_reeval_performance_state(parent, + parent_state); + ret = _genpd_set_performance_state(parent, parent_state, depth + 1); if (ret) link->performance_state = link->prev_performance_state; - genpd_unlock(master); + genpd_unlock(parent); if (ret) goto err; @@ -333,26 +333,26 @@ err: /* Encountered an error, lets rollback */ - list_for_each_entry_continue_reverse(link, &genpd->slave_links, - slave_node) { - master = link->master; + list_for_each_entry_continue_reverse(link, &genpd->child_links, + child_node) { + parent = link->parent; - if (!master->set_performance_state) + if (!parent->set_performance_state) continue; - genpd_lock_nested(master, depth + 1); + genpd_lock_nested(parent, depth + 1); - master_state = link->prev_performance_state; - link->performance_state = master_state; + parent_state = link->prev_performance_state; + link->performance_state = parent_state; - master_state = _genpd_reeval_performance_state(master, - master_state); - if (_genpd_set_performance_state(master, master_state, depth + 1)) { + parent_state = _genpd_reeval_performance_state(parent, + parent_state); + if (_genpd_set_performance_state(parent, parent_state, depth + 1)) { pr_err("%s: Failed to roll back to %d performance state\n", - master->name, master_state); + parent->name, parent_state); } - genpd_unlock(master); + genpd_unlock(parent); } return ret; @@ -552,7 +552,7 @@ /* * If sd_count > 0 at this point, one of the subdomains hasn't - * managed to call genpd_power_on() for the master yet after + * managed to call genpd_power_on() for the parent yet after * incrementing it. In that case genpd_power_on() will wait * for us to drop the lock, so we can call .power_off() and let * the genpd_power_on() restore power for us (this shouldn't @@ -566,22 +566,22 @@ genpd->status = GPD_STATE_POWER_OFF; genpd_update_accounting(genpd); - list_for_each_entry(link, &genpd->slave_links, slave_node) { - genpd_sd_counter_dec(link->master); - genpd_lock_nested(link->master, depth + 1); - genpd_power_off(link->master, false, depth + 1); - genpd_unlock(link->master); + list_for_each_entry(link, &genpd->child_links, child_node) { + genpd_sd_counter_dec(link->parent); + genpd_lock_nested(link->parent, depth + 1); + genpd_power_off(link->parent, false, depth + 1); + genpd_unlock(link->parent); } return 0; } /** - * genpd_power_on - Restore power to a given PM domain and its masters. + * genpd_power_on - Restore power to a given PM domain and its parents. * @genpd: PM domain to power up. * @depth: nesting count for lockdep. * - * Restore power to @genpd and all of its masters so that it is possible to + * Restore power to @genpd and all of its parents so that it is possible to * resume a device belonging to it. */ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) @@ -594,20 +594,20 @@ /* * The list is guaranteed not to change while the loop below is being - * executed, unless one of the masters' .power_on() callbacks fiddles + * executed, unless one of the parents' .power_on() callbacks fiddles * with it. */ - list_for_each_entry(link, &genpd->slave_links, slave_node) { - struct generic_pm_domain *master = link->master; + list_for_each_entry(link, &genpd->child_links, child_node) { + struct generic_pm_domain *parent = link->parent; - genpd_sd_counter_inc(master); + genpd_sd_counter_inc(parent); - genpd_lock_nested(master, depth + 1); - ret = genpd_power_on(master, depth + 1); - genpd_unlock(master); + genpd_lock_nested(parent, depth + 1); + ret = genpd_power_on(parent, depth + 1); + genpd_unlock(parent); if (ret) { - genpd_sd_counter_dec(master); + genpd_sd_counter_dec(parent); goto err; } } @@ -623,12 +623,12 @@ err: list_for_each_entry_continue_reverse(link, - &genpd->slave_links, - slave_node) { - genpd_sd_counter_dec(link->master); - genpd_lock_nested(link->master, depth + 1); - genpd_power_off(link->master, false, depth + 1); - genpd_unlock(link->master); + &genpd->child_links, + child_node) { + genpd_sd_counter_dec(link->parent); + genpd_lock_nested(link->parent, depth + 1); + genpd_power_off(link->parent, false, depth + 1); + genpd_unlock(link->parent); } return ret; @@ -920,7 +920,7 @@ return 0; } -late_initcall(genpd_power_off_unused); +late_initcall_sync(genpd_power_off_unused); #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_GENERIC_DOMAINS_OF) @@ -943,13 +943,13 @@ #ifdef CONFIG_PM_SLEEP /** - * genpd_sync_power_off - Synchronously power off a PM domain and its masters. + * genpd_sync_power_off - Synchronously power off a PM domain and its parents. * @genpd: PM domain to power off, if possible. * @use_lock: use the lock. * @depth: nesting count for lockdep. * * Check if the given PM domain can be powered off (during system suspend or - * hibernation) and do that if so. Also, in that case propagate to its masters. + * hibernation) and do that if so. Also, in that case propagate to its parents. * * This function is only called in "noirq" and "syscore" stages of system power * transitions. The "noirq" callbacks may be executed asynchronously, thus in @@ -974,21 +974,21 @@ genpd->status = GPD_STATE_POWER_OFF; - list_for_each_entry(link, &genpd->slave_links, slave_node) { - genpd_sd_counter_dec(link->master); + list_for_each_entry(link, &genpd->child_links, child_node) { + genpd_sd_counter_dec(link->parent); if (use_lock) - genpd_lock_nested(link->master, depth + 1); + genpd_lock_nested(link->parent, depth + 1); - genpd_sync_power_off(link->master, use_lock, depth + 1); + genpd_sync_power_off(link->parent, use_lock, depth + 1); if (use_lock) - genpd_unlock(link->master); + genpd_unlock(link->parent); } } /** - * genpd_sync_power_on - Synchronously power on a PM domain and its masters. + * genpd_sync_power_on - Synchronously power on a PM domain and its parents. * @genpd: PM domain to power on. * @use_lock: use the lock. * @depth: nesting count for lockdep. @@ -1005,16 +1005,16 @@ if (genpd_status_on(genpd)) return; - list_for_each_entry(link, &genpd->slave_links, slave_node) { - genpd_sd_counter_inc(link->master); + list_for_each_entry(link, &genpd->child_links, child_node) { + genpd_sd_counter_inc(link->parent); if (use_lock) - genpd_lock_nested(link->master, depth + 1); + genpd_lock_nested(link->parent, depth + 1); - genpd_sync_power_on(link->master, use_lock, depth + 1); + genpd_sync_power_on(link->parent, use_lock, depth + 1); if (use_lock) - genpd_unlock(link->master); + genpd_unlock(link->parent); } _genpd_power_on(genpd, false); @@ -1454,12 +1454,12 @@ if (!genpd_is_cpu_domain(genpd)) return; - list_for_each_entry(link, &genpd->slave_links, slave_node) { - struct generic_pm_domain *master = link->master; + list_for_each_entry(link, &genpd->child_links, child_node) { + struct generic_pm_domain *parent = link->parent; - genpd_lock_nested(master, depth + 1); - genpd_update_cpumask(master, cpu, set, depth + 1); - genpd_unlock(master); + genpd_lock_nested(parent, depth + 1); + genpd_update_cpumask(parent, cpu, set, depth + 1); + genpd_unlock(parent); } if (set) @@ -1647,17 +1647,17 @@ goto out; } - list_for_each_entry(itr, &genpd->master_links, master_node) { - if (itr->slave == subdomain && itr->master == genpd) { + list_for_each_entry(itr, &genpd->parent_links, parent_node) { + if (itr->child == subdomain && itr->parent == genpd) { ret = -EINVAL; goto out; } } - link->master = genpd; - list_add_tail(&link->master_node, &genpd->master_links); - link->slave = subdomain; - list_add_tail(&link->slave_node, &subdomain->slave_links); + link->parent = genpd; + list_add_tail(&link->parent_node, &genpd->parent_links); + link->child = subdomain; + list_add_tail(&link->child_node, &subdomain->child_links); if (genpd_status_on(subdomain)) genpd_sd_counter_inc(genpd); @@ -1671,7 +1671,7 @@ /** * pm_genpd_add_subdomain - Add a subdomain to an I/O PM domain. - * @genpd: Master PM domain to add the subdomain to. + * @genpd: Leader PM domain to add the subdomain to. * @subdomain: Subdomain to be added. */ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, @@ -1689,7 +1689,7 @@ /** * pm_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain. - * @genpd: Master PM domain to remove the subdomain from. + * @genpd: Leader PM domain to remove the subdomain from. * @subdomain: Subdomain to be removed. */ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, @@ -1704,19 +1704,19 @@ genpd_lock(subdomain); genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); - if (!list_empty(&subdomain->master_links) || subdomain->device_count) { + if (!list_empty(&subdomain->parent_links) || subdomain->device_count) { pr_warn("%s: unable to remove subdomain %s\n", genpd->name, subdomain->name); ret = -EBUSY; goto out; } - list_for_each_entry_safe(link, l, &genpd->master_links, master_node) { - if (link->slave != subdomain) + list_for_each_entry_safe(link, l, &genpd->parent_links, parent_node) { + if (link->child != subdomain) continue; - list_del(&link->master_node); - list_del(&link->slave_node); + list_del(&link->parent_node); + list_del(&link->child_node); kfree(link); if (genpd_status_on(subdomain)) genpd_sd_counter_dec(genpd); @@ -1781,8 +1781,8 @@ if (IS_ERR_OR_NULL(genpd)) return -EINVAL; - INIT_LIST_HEAD(&genpd->master_links); - INIT_LIST_HEAD(&genpd->slave_links); + INIT_LIST_HEAD(&genpd->parent_links); + INIT_LIST_HEAD(&genpd->child_links); INIT_LIST_HEAD(&genpd->dev_list); genpd_lock_init(genpd); genpd->gov = gov; @@ -1858,15 +1858,15 @@ return -EBUSY; } - if (!list_empty(&genpd->master_links) || genpd->device_count) { + if (!list_empty(&genpd->parent_links) || genpd->device_count) { genpd_unlock(genpd); pr_err("%s: unable to remove %s\n", __func__, genpd->name); return -EBUSY; } - list_for_each_entry_safe(link, l, &genpd->slave_links, slave_node) { - list_del(&link->master_node); - list_del(&link->slave_node); + list_for_each_entry_safe(link, l, &genpd->child_links, child_node) { + list_del(&link->parent_node); + list_del(&link->child_node); kfree(link); } @@ -2596,10 +2596,10 @@ err = of_property_read_u32(state_node, "min-residency-us", &residency); if (!err) - genpd_state->residency_ns = 1000 * residency; + genpd_state->residency_ns = 1000LL * residency; - genpd_state->power_on_latency_ns = 1000 * exit_latency; - genpd_state->power_off_latency_ns = 1000 * entry_latency; + genpd_state->power_on_latency_ns = 1000LL * exit_latency; + genpd_state->power_off_latency_ns = 1000LL * entry_latency; genpd_state->fwnode = &state_node->fwnode; return 0; @@ -2615,13 +2615,17 @@ ret = of_count_phandle_with_args(dn, "domain-idle-states", NULL); if (ret <= 0) - return ret; + return ret == -ENOENT ? 0 : ret; /* Loop over the phandles until all the requested entry is found */ of_for_each_phandle(&it, ret, dn, "domain-idle-states", NULL, 0) { np = it.node; if (!of_match_node(idle_state_match, np)) continue; + + if (!of_device_is_available(np)) + continue; + if (states) { ret = genpd_parse_state(&states[i], np); if (ret) { @@ -2789,12 +2793,12 @@ /* * Modifications on the list require holding locks on both - * master and slave, so we are safe. + * parent and child, so we are safe. * Also genpd->name is immutable. */ - list_for_each_entry(link, &genpd->master_links, master_node) { - seq_printf(s, "%s", link->slave->name); - if (!list_is_last(&link->master_node, &genpd->master_links)) + list_for_each_entry(link, &genpd->parent_links, parent_node) { + seq_printf(s, "%s", link->child->name); + if (!list_is_last(&link->parent_node, &genpd->parent_links)) seq_puts(s, ", "); } @@ -2822,7 +2826,7 @@ struct generic_pm_domain *genpd; int ret = 0; - seq_puts(s, "domain status slaves\n"); + seq_puts(s, "domain status children\n"); seq_puts(s, " /device runtime status\n"); seq_puts(s, "----------------------------------------------------------------------\n"); @@ -2877,8 +2881,8 @@ if (ret) return -ERESTARTSYS; - list_for_each_entry(link, &genpd->master_links, master_node) - seq_printf(s, "%s\n", link->slave->name); + list_for_each_entry(link, &genpd->parent_links, parent_node) + seq_printf(s, "%s\n", link->child->name); genpd_unlock(genpd); return ret; --- linux-oracle-5.4.0.orig/drivers/base/power/domain_governor.c +++ linux-oracle-5.4.0/drivers/base/power/domain_governor.c @@ -135,8 +135,8 @@ * * All subdomains have been powered off already at this point. */ - list_for_each_entry(link, &genpd->master_links, master_node) { - struct generic_pm_domain *sd = link->slave; + list_for_each_entry(link, &genpd->parent_links, parent_node) { + struct generic_pm_domain *sd = link->child; s64 sd_max_off_ns = sd->max_off_time_ns; if (sd_max_off_ns < 0) @@ -217,13 +217,13 @@ } /* - * We have to invalidate the cached results for the masters, so + * We have to invalidate the cached results for the parents, so * use the observation that default_power_down_ok() is not - * going to be called for any master until this instance + * going to be called for any parent until this instance * returns. */ - list_for_each_entry(link, &genpd->slave_links, slave_node) - link->master->max_off_time_changed = true; + list_for_each_entry(link, &genpd->child_links, child_node) + link->parent->max_off_time_changed = true; genpd->max_off_time_ns = -1; genpd->max_off_time_changed = false; --- linux-oracle-5.4.0.orig/drivers/base/power/main.c +++ linux-oracle-5.4.0/drivers/base/power/main.c @@ -273,10 +273,38 @@ device_links_read_unlock(idx); } -static void dpm_wait_for_superior(struct device *dev, bool async) +static bool dpm_wait_for_superior(struct device *dev, bool async) { - dpm_wait(dev->parent, async); + struct device *parent; + + /* + * If the device is resumed asynchronously and the parent's callback + * deletes both the device and the parent itself, the parent object may + * be freed while this function is running, so avoid that by reference + * counting the parent once more unless the device has been deleted + * already (in which case return right away). + */ + mutex_lock(&dpm_list_mtx); + + if (!device_pm_initialized(dev)) { + mutex_unlock(&dpm_list_mtx); + return false; + } + + parent = get_device(dev->parent); + + mutex_unlock(&dpm_list_mtx); + + dpm_wait(parent, async); + put_device(parent); + dpm_wait_for_suppliers(dev, async); + + /* + * If the parent's callback has deleted the device, attempting to resume + * it would be invalid, so avoid doing that then. + */ + return device_pm_initialized(dev); } static void dpm_wait_for_consumers(struct device *dev, bool async) @@ -597,7 +625,7 @@ const char **info_p); /** - * device_resume_noirq - Execute a "noirq resume" callback for given device. + * __device_resume_noirq - Execute a "noirq resume" callback for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. @@ -605,7 +633,7 @@ * The driver of @dev will not receive interrupts while this function is being * executed. */ -static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) +static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback; const char *info; @@ -621,7 +649,8 @@ if (!dev->power.is_noirq_suspended) goto Out; - dpm_wait_for_superior(dev, async); + if (!dpm_wait_for_superior(dev, async)) + goto Out; skip_resume = dev_pm_may_skip_resume(dev); @@ -682,7 +711,13 @@ Out: complete_all(&dev->power.completion); TRACE_RESUME(error); - return error; + + if (error) { + suspend_stats.failed_resume_noirq++; + dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async noirq" : " noirq", error); + } } static bool is_async(struct device *dev) @@ -695,11 +730,15 @@ { reinit_completion(&dev->power.completion); - if (is_async(dev)) { - get_device(dev); - async_schedule(func, dev); + if (!is_async(dev)) + return false; + + get_device(dev); + + if (async_schedule_dev_nocall(func, dev)) return true; - } + + put_device(dev); return false; } @@ -707,15 +746,19 @@ static void async_resume_noirq(void *data, async_cookie_t cookie) { struct device *dev = (struct device *)data; - int error; - - error = device_resume_noirq(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume_noirq(dev, pm_transition, true); put_device(dev); } +static void device_resume_noirq(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume_noirq)) + return; + + __device_resume_noirq(dev, pm_transition, false); +} + static void dpm_noirq_resume_devices(pm_message_t state) { struct device *dev; @@ -725,34 +768,18 @@ mutex_lock(&dpm_list_mtx); pm_transition = state; - /* - * Advanced the async threads upfront, - * in case the starting of async threads is - * delayed by non-async resuming devices. - */ - list_for_each_entry(dev, &dpm_noirq_list, power.entry) - dpm_async_fn(dev, async_resume_noirq); - while (!list_empty(&dpm_noirq_list)) { dev = to_device(dpm_noirq_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_late_early_list); + mutex_unlock(&dpm_list_mtx); - if (!is_async(dev)) { - int error; + device_resume_noirq(dev); - error = device_resume_noirq(dev, state, false); - if (error) { - suspend_stats.failed_resume_noirq++; - dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " noirq", error); - } - } + put_device(dev); mutex_lock(&dpm_list_mtx); - put_device(dev); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -807,14 +834,14 @@ } /** - * device_resume_early - Execute an "early resume" callback for given device. + * __device_resume_early - Execute an "early resume" callback for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. * * Runtime PM is disabled for @dev while this function is being executed. */ -static int device_resume_early(struct device *dev, pm_message_t state, bool async) +static void __device_resume_early(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback; const char *info; @@ -829,7 +856,8 @@ if (!dev->power.is_late_suspended) goto Out; - dpm_wait_for_superior(dev, async); + if (!dpm_wait_for_superior(dev, async)) + goto Out; callback = dpm_subsys_resume_early_cb(dev, state, &info); @@ -846,21 +874,31 @@ pm_runtime_enable(dev); complete_all(&dev->power.completion); - return error; + + if (error) { + suspend_stats.failed_resume_early++; + dpm_save_failed_step(SUSPEND_RESUME_EARLY); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async early" : " early", error); + } } static void async_resume_early(void *data, async_cookie_t cookie) { struct device *dev = (struct device *)data; - int error; - - error = device_resume_early(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume_early(dev, pm_transition, true); put_device(dev); } +static void device_resume_early(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume_early)) + return; + + __device_resume_early(dev, pm_transition, false); +} + /** * dpm_resume_early - Execute "early resume" callbacks for all devices. * @state: PM transition of the system being carried out. @@ -874,33 +912,18 @@ mutex_lock(&dpm_list_mtx); pm_transition = state; - /* - * Advanced the async threads upfront, - * in case the starting of async threads is - * delayed by non-async resuming devices. - */ - list_for_each_entry(dev, &dpm_late_early_list, power.entry) - dpm_async_fn(dev, async_resume_early); - while (!list_empty(&dpm_late_early_list)) { dev = to_device(dpm_late_early_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_unlock(&dpm_list_mtx); - if (!is_async(dev)) { - int error; + device_resume_early(dev); - error = device_resume_early(dev, state, false); - if (error) { - suspend_stats.failed_resume_early++; - dpm_save_failed_step(SUSPEND_RESUME_EARLY); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " early", error); - } - } - mutex_lock(&dpm_list_mtx); put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -920,12 +943,12 @@ EXPORT_SYMBOL_GPL(dpm_resume_start); /** - * device_resume - Execute "resume" callbacks for given device. + * __device_resume - Execute "resume" callbacks for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. */ -static int device_resume(struct device *dev, pm_message_t state, bool async) +static void __device_resume(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; const char *info = NULL; @@ -944,7 +967,9 @@ goto Complete; } - dpm_wait_for_superior(dev, async); + if (!dpm_wait_for_superior(dev, async)) + goto Complete; + dpm_watchdog_set(&wd, dev); device_lock(dev); @@ -1005,20 +1030,30 @@ TRACE_RESUME(error); - return error; + if (error) { + suspend_stats.failed_resume++; + dpm_save_failed_step(SUSPEND_RESUME); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async" : "", error); + } } static void async_resume(void *data, async_cookie_t cookie) { struct device *dev = (struct device *)data; - int error; - error = device_resume(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume(dev, pm_transition, true); put_device(dev); } +static void device_resume(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume)) + return; + + __device_resume(dev, pm_transition, false); +} + /** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. @@ -1038,30 +1073,25 @@ pm_transition = state; async_error = 0; - list_for_each_entry(dev, &dpm_suspended_list, power.entry) - dpm_async_fn(dev, async_resume); - while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); + get_device(dev); - if (!is_async(dev)) { - int error; - mutex_unlock(&dpm_list_mtx); + mutex_unlock(&dpm_list_mtx); - error = device_resume(dev, state, false); - if (error) { - suspend_stats.failed_resume++; - dpm_save_failed_step(SUSPEND_RESUME); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, "", error); - } + device_resume(dev); + + mutex_lock(&dpm_list_mtx); - mutex_lock(&dpm_list_mtx); - } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); + + mutex_unlock(&dpm_list_mtx); + put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); async_synchronize_full(); @@ -1138,14 +1168,16 @@ get_device(dev); dev->power.is_prepared = false; list_move(&dev->power.entry, &list); + mutex_unlock(&dpm_list_mtx); trace_device_pm_callback_start(dev, "", state.event); device_complete(dev, state); trace_device_pm_callback_end(dev, 0); - mutex_lock(&dpm_list_mtx); put_device(dev); + + mutex_lock(&dpm_list_mtx); } list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); @@ -1373,17 +1405,21 @@ error = device_suspend_noirq(dev); mutex_lock(&dpm_list_mtx); + if (error) { pm_dev_err(dev, state, " noirq", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; - } - if (!list_empty(&dev->power.entry)) + } else if (!list_empty(&dev->power.entry)) { list_move(&dev->power.entry, &dpm_noirq_list); + } + + mutex_unlock(&dpm_list_mtx); + put_device(dev); - if (async_error) + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1568,23 +1604,28 @@ struct device *dev = to_device(dpm_suspended_list.prev); get_device(dev); + mutex_unlock(&dpm_list_mtx); error = device_suspend_late(dev); mutex_lock(&dpm_list_mtx); + if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_late_early_list); if (error) { pm_dev_err(dev, state, " late", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; } + + mutex_unlock(&dpm_list_mtx); + put_device(dev); - if (async_error) + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1696,13 +1737,17 @@ } /* - * If a device configured to wake up the system from sleep states - * has been suspended at run time and there's a resume request pending - * for it, this is equivalent to the device signaling wakeup, so the - * system suspend operation should be aborted. + * Wait for possible runtime PM transitions of the device in progress + * to complete and if there's a runtime resume request pending for it, + * resume it before proceeding with invoking the system-wide suspend + * callbacks for it. + * + * If the system-wide suspend callbacks below change the configuration + * of the device, they must disable runtime PM for it or otherwise + * ensure that its runtime-resume callbacks will not be confused by that + * change in case they are invoked going forward. */ - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) - pm_wakeup_event(dev, 0); + pm_runtime_barrier(dev); if (pm_wakeup_pending()) { dev->power.direct_complete = false; @@ -1840,21 +1885,27 @@ struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); + mutex_unlock(&dpm_list_mtx); error = device_suspend(dev); mutex_lock(&dpm_list_mtx); + if (error) { pm_dev_err(dev, state, "", error); dpm_save_failed_dev(dev_name(dev)); - put_device(dev); - break; - } - if (!list_empty(&dev->power.entry)) + } else if (!list_empty(&dev->power.entry)) { list_move(&dev->power.entry, &dpm_suspended_list); + } + + mutex_unlock(&dpm_list_mtx); + put_device(dev); - if (async_error) + + mutex_lock(&dpm_list_mtx); + + if (error || async_error) break; } mutex_unlock(&dpm_list_mtx); @@ -1972,10 +2023,11 @@ device_block_probing(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_list)) { + while (!list_empty(&dpm_list) && !error) { struct device *dev = to_device(dpm_list.next); get_device(dev); + mutex_unlock(&dpm_list_mtx); trace_device_pm_callback_start(dev, "", state.event); @@ -1983,21 +2035,22 @@ trace_device_pm_callback_end(dev, error); mutex_lock(&dpm_list_mtx); - if (error) { - if (error == -EAGAIN) { - put_device(dev); - error = 0; - continue; - } + if (!error) { + dev->power.is_prepared = true; + if (!list_empty(&dev->power.entry)) + list_move_tail(&dev->power.entry, &dpm_prepared_list); + } else if (error == -EAGAIN) { + error = 0; + } else { pr_info("Device %s not prepared for power transition: code %d\n", dev_name(dev), error); - put_device(dev); - break; } - dev->power.is_prepared = true; - if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_prepared_list); + + mutex_unlock(&dpm_list_mtx); + put_device(dev); + + mutex_lock(&dpm_list_mtx); } mutex_unlock(&dpm_list_mtx); trace_suspend_resume(TPS("dpm_prepare"), state.event, false); @@ -2085,7 +2138,9 @@ void device_pm_check_callbacks(struct device *dev) { - spin_lock_irq(&dev->power.lock); + unsigned long flags; + + spin_lock_irqsave(&dev->power.lock, flags); dev->power.no_pm_callbacks = (!dev->bus || (pm_ops_is_empty(dev->bus->pm) && !dev->bus->suspend && !dev->bus->resume)) && @@ -2094,7 +2149,7 @@ (!dev->pm_domain || pm_ops_is_empty(&dev->pm_domain->ops)) && (!dev->driver || (pm_ops_is_empty(dev->driver->pm) && !dev->driver->suspend && !dev->driver->resume)); - spin_unlock_irq(&dev->power.lock); + spin_unlock_irqrestore(&dev->power.lock, flags); } bool dev_pm_smart_suspend_and_suspended(struct device *dev) --- linux-oracle-5.4.0.orig/drivers/base/power/power.h +++ linux-oracle-5.4.0/drivers/base/power/power.h @@ -25,8 +25,11 @@ #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) +#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ - WAKE_IRQ_DEDICATED_MANAGED) + WAKE_IRQ_DEDICATED_MANAGED | \ + WAKE_IRQ_DEDICATED_REVERSE) +#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) struct wake_irq { struct device *dev; @@ -39,7 +42,8 @@ extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); extern void dev_pm_enable_wake_irq_check(struct device *dev, bool can_change_status); -extern void dev_pm_disable_wake_irq_check(struct device *dev); +extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); +extern void dev_pm_enable_wake_irq_complete(struct device *dev); #ifdef CONFIG_PM_SLEEP @@ -74,6 +78,7 @@ extern void pm_qos_sysfs_remove_flags(struct device *dev); extern int pm_qos_sysfs_add_latency_tolerance(struct device *dev); extern void pm_qos_sysfs_remove_latency_tolerance(struct device *dev); +extern int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid); #else /* CONFIG_PM */ @@ -88,6 +93,8 @@ static inline int dpm_sysfs_add(struct device *dev) { return 0; } static inline void dpm_sysfs_remove(struct device *dev) {} +static inline int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, + kgid_t kgid) { return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/base/power/runtime.c +++ linux-oracle-5.4.0/drivers/base/power/runtime.c @@ -291,8 +291,7 @@ device_links_read_lock_held()) { int retval; - if (!(link->flags & DL_FLAG_PM_RUNTIME) || - READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) + if (!(link->flags & DL_FLAG_PM_RUNTIME)) continue; retval = pm_runtime_get_sync(link->supplier); @@ -306,20 +305,38 @@ return 0; } -static void rpm_put_suppliers(struct device *dev) +static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) { struct device_link *link; list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, device_links_read_lock_held()) { - if (READ_ONCE(link->status) == DL_STATE_SUPPLIER_UNBIND) - continue; while (refcount_dec_not_one(&link->rpm_active)) - pm_runtime_put(link->supplier); + pm_runtime_put_noidle(link->supplier); + + if (try_to_suspend) + pm_request_idle(link->supplier); } } +static void rpm_put_suppliers(struct device *dev) +{ + __rpm_put_suppliers(dev, true); +} + +static void rpm_suspend_suppliers(struct device *dev) +{ + struct device_link *link; + int idx = device_links_read_lock(); + + list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, + device_links_read_lock_held()) + pm_request_idle(link->supplier); + + device_links_read_unlock(idx); +} + /** * __rpm_callback - Run a given runtime PM callback for a given device. * @cb: Runtime PM callback to run. @@ -347,8 +364,10 @@ idx = device_links_read_lock(); retval = rpm_get_suppliers(dev); - if (retval) + if (retval) { + rpm_put_suppliers(dev); goto fail; + } device_links_read_unlock(idx); } @@ -371,9 +390,9 @@ || (dev->power.runtime_status == RPM_RESUMING && retval))) { idx = device_links_read_lock(); - fail: - rpm_put_suppliers(dev); + __rpm_put_suppliers(dev, false); +fail: device_links_read_unlock(idx); } @@ -427,7 +446,10 @@ /* Pending requests need to be canceled. */ dev->power.request = RPM_REQ_NONE; - if (dev->power.no_callbacks) + callback = RPM_GET_CALLBACK(dev, runtime_idle); + + /* If no callback assume success. */ + if (!callback || dev->power.no_callbacks) goto out; /* Carry out an asynchronous or a synchronous idle notification. */ @@ -443,10 +465,17 @@ dev->power.idle_notification = true; - callback = RPM_GET_CALLBACK(dev, runtime_idle); + if (dev->power.irq_safe) + spin_unlock(&dev->power.lock); + else + spin_unlock_irq(&dev->power.lock); - if (callback) - retval = __rpm_callback(callback, dev); + retval = callback(dev); + + if (dev->power.irq_safe) + spin_lock(&dev->power.lock); + else + spin_lock_irq(&dev->power.lock); dev->power.idle_notification = false; wake_up_all(&dev->power.wait_queue); @@ -630,6 +659,8 @@ if (retval) goto fail; + dev_pm_enable_wake_irq_complete(dev); + no_callback: __update_runtime_status(dev, RPM_SUSPENDED); pm_runtime_deactivate_timer(dev); @@ -647,8 +678,11 @@ goto out; } + if (dev->power.irq_safe) + goto out; + /* Maybe the parent is now able to suspend. */ - if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { + if (parent && !parent->power.ignore_children) { spin_unlock(&dev->power.lock); spin_lock(&parent->power.lock); @@ -657,6 +691,14 @@ spin_lock(&dev->power.lock); } + /* Maybe the suppliers are now able to suspend. */ + if (dev->power.links_count > 0) { + spin_unlock_irq(&dev->power.lock); + + rpm_suspend_suppliers(dev); + + spin_lock_irq(&dev->power.lock); + } out: trace_rpm_return_int_rcuidle(dev, _THIS_IP_, retval); @@ -664,7 +706,7 @@ return retval; fail: - dev_pm_disable_wake_irq_check(dev); + dev_pm_disable_wake_irq_check(dev, true); __update_runtime_status(dev, RPM_ACTIVE); dev->power.deferred_resume = false; wake_up_all(&dev->power.wait_queue); @@ -847,7 +889,7 @@ callback = RPM_GET_CALLBACK(dev, runtime_resume); - dev_pm_disable_wake_irq_check(dev); + dev_pm_disable_wake_irq_check(dev, false); retval = rpm_callback(callback, dev); if (retval) { __update_runtime_status(dev, RPM_SUSPENDED); @@ -1006,8 +1048,10 @@ int retval; if (rpmflags & RPM_GET_PUT) { - if (!atomic_dec_and_test(&dev->power.usage_count)) + if (!atomic_dec_and_test(&dev->power.usage_count)) { + trace_rpm_usage_rcuidle(dev, rpmflags); return 0; + } } might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); @@ -1038,8 +1082,10 @@ int retval; if (rpmflags & RPM_GET_PUT) { - if (!atomic_dec_and_test(&dev->power.usage_count)) + if (!atomic_dec_and_test(&dev->power.usage_count)) { + trace_rpm_usage_rcuidle(dev, rpmflags); return 0; + } } might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe); @@ -1083,28 +1129,47 @@ EXPORT_SYMBOL_GPL(__pm_runtime_resume); /** - * pm_runtime_get_if_in_use - Conditionally bump up the device's usage counter. + * pm_runtime_get_if_active - Conditionally bump up the device's usage counter. * @dev: Device to handle. * * Return -EINVAL if runtime PM is disabled for the device. * - * If that's not the case and if the device's runtime PM status is RPM_ACTIVE - * and the runtime PM usage counter is nonzero, increment the counter and - * return 1. Otherwise return 0 without changing the counter. + * Otherwise, if the device's runtime PM status is RPM_ACTIVE and either + * ign_usage_count is true or the device's usage_count is non-zero, increment + * the counter and return 1. Otherwise return 0 without changing the counter. + * + * If ign_usage_count is true, the function can be used to prevent suspending + * the device when its runtime PM status is RPM_ACTIVE. + * + * If ign_usage_count is false, the function can be used to prevent suspending + * the device when both its runtime PM status is RPM_ACTIVE and its usage_count + * is non-zero. + * + * The caller is resposible for putting the device's usage count when ther + * return value is greater than zero. */ -int pm_runtime_get_if_in_use(struct device *dev) +int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count) { unsigned long flags; int retval; spin_lock_irqsave(&dev->power.lock, flags); - retval = dev->power.disable_depth > 0 ? -EINVAL : - dev->power.runtime_status == RPM_ACTIVE - && atomic_inc_not_zero(&dev->power.usage_count); + if (dev->power.disable_depth > 0) { + retval = -EINVAL; + } else if (dev->power.runtime_status != RPM_ACTIVE) { + retval = 0; + } else if (ign_usage_count) { + retval = 1; + atomic_inc(&dev->power.usage_count); + } else { + retval = atomic_inc_not_zero(&dev->power.usage_count); + } + trace_rpm_usage_rcuidle(dev, 0); spin_unlock_irqrestore(&dev->power.lock, flags); + return retval; } -EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use); +EXPORT_SYMBOL_GPL(pm_runtime_get_if_active); /** * __pm_runtime_set_status - Set runtime PM status of a device. @@ -1396,6 +1461,28 @@ } EXPORT_SYMBOL_GPL(pm_runtime_enable); +static void pm_runtime_disable_action(void *data) +{ + pm_runtime_dont_use_autosuspend(data); + pm_runtime_disable(data); +} + +/** + * devm_pm_runtime_enable - devres-enabled version of pm_runtime_enable. + * + * NOTE: this will also handle calling pm_runtime_dont_use_autosuspend() for + * you at driver exit time if needed. + * + * @dev: Device to handle. + */ +int devm_pm_runtime_enable(struct device *dev) +{ + pm_runtime_enable(dev); + + return devm_add_action_or_reset(dev, pm_runtime_disable_action, dev); +} +EXPORT_SYMBOL_GPL(devm_pm_runtime_enable); + /** * pm_runtime_forbid - Block runtime PM of a device. * @dev: Device to handle. @@ -1434,6 +1521,8 @@ dev->power.runtime_auto = true; if (atomic_dec_and_test(&dev->power.usage_count)) rpm_idle(dev, RPM_AUTO | RPM_ASYNC); + else + trace_rpm_usage_rcuidle(dev, RPM_AUTO | RPM_ASYNC); out: spin_unlock_irq(&dev->power.lock); @@ -1501,6 +1590,8 @@ if (!old_use || old_delay >= 0) { atomic_inc(&dev->power.usage_count); rpm_resume(dev, 0); + } else { + trace_rpm_usage_rcuidle(dev, 0); } } @@ -1580,6 +1671,7 @@ dev->power.request_pending = false; dev->power.request = RPM_REQ_NONE; dev->power.deferred_resume = false; + dev->power.needs_force_resume = 0; INIT_WORK(&dev->power.work, pm_runtime_work); dev->power.timer_expires = 0; @@ -1619,42 +1711,6 @@ } /** - * pm_runtime_clean_up_links - Prepare links to consumers for driver removal. - * @dev: Device whose driver is going to be removed. - * - * Check links from this device to any consumers and if any of them have active - * runtime PM references to the device, drop the usage counter of the device - * (as many times as needed). - * - * Links with the DL_FLAG_MANAGED flag unset are ignored. - * - * Since the device is guaranteed to be runtime-active at the point this is - * called, nothing else needs to be done here. - * - * Moreover, this is called after device_links_busy() has returned 'false', so - * the status of each link is guaranteed to be DL_STATE_SUPPLIER_UNBIND and - * therefore rpm_active can't be manipulated concurrently. - */ -void pm_runtime_clean_up_links(struct device *dev) -{ - struct device_link *link; - int idx; - - idx = device_links_read_lock(); - - list_for_each_entry_rcu(link, &dev->links.consumers, s_node, - device_links_read_lock_held()) { - if (!(link->flags & DL_FLAG_MANAGED)) - continue; - - while (refcount_dec_not_one(&link->rpm_active)) - pm_runtime_put_noidle(dev); - } - - device_links_read_unlock(idx); -} - -/** * pm_runtime_get_suppliers - Resume and reference-count supplier devices. * @dev: Consumer device. */ @@ -1669,8 +1725,8 @@ device_links_read_lock_held()) if (link->flags & DL_FLAG_PM_RUNTIME) { link->supplier_preactivated = true; - refcount_inc(&link->rpm_active); pm_runtime_get_sync(link->supplier); + refcount_inc(&link->rpm_active); } device_links_read_unlock(idx); @@ -1683,6 +1739,8 @@ void pm_runtime_put_suppliers(struct device *dev) { struct device_link *link; + unsigned long flags; + bool put; int idx; idx = device_links_read_lock(); @@ -1691,7 +1749,11 @@ device_links_read_lock_held()) if (link->supplier_preactivated) { link->supplier_preactivated = false; - if (refcount_dec_not_one(&link->rpm_active)) + spin_lock_irqsave(&dev->power.lock, flags); + put = pm_runtime_status_suspended(dev) && + refcount_dec_not_one(&link->rpm_active); + spin_unlock_irqrestore(&dev->power.lock, flags); + if (put) pm_runtime_put(link->supplier); } @@ -1705,7 +1767,7 @@ spin_unlock_irq(&dev->power.lock); } -void pm_runtime_drop_link(struct device *dev) +static void pm_runtime_drop_link_count(struct device *dev) { spin_lock_irq(&dev->power.lock); WARN_ON(dev->power.links_count == 0); @@ -1713,6 +1775,25 @@ spin_unlock_irq(&dev->power.lock); } +/** + * pm_runtime_drop_link - Prepare for device link removal. + * @link: Device link going away. + * + * Drop the link count of the consumer end of @link and decrement the supplier + * device's runtime PM usage counter as many times as needed to drop all of the + * PM runtime reference to it from the consumer. + */ +void pm_runtime_drop_link(struct device_link *link) +{ + if (!(link->flags & DL_FLAG_PM_RUNTIME)) + return; + + pm_runtime_drop_link_count(link->consumer); + + while (refcount_dec_not_one(&link->rpm_active)) + pm_runtime_put(link->supplier); +} + static bool pm_runtime_need_not_resume(struct device *dev) { return atomic_read(&dev->power.usage_count) <= 1 && @@ -1758,10 +1839,12 @@ * its parent, but set its status to RPM_SUSPENDED anyway in case this * function will be called again for it in the meantime. */ - if (pm_runtime_need_not_resume(dev)) + if (pm_runtime_need_not_resume(dev)) { pm_runtime_set_suspended(dev); - else + } else { __update_runtime_status(dev, RPM_SUSPENDED); + dev->power.needs_force_resume = 1; + } return 0; @@ -1788,7 +1871,7 @@ int (*callback)(struct device *); int ret = 0; - if (!pm_runtime_status_suspended(dev) || pm_runtime_need_not_resume(dev)) + if (!pm_runtime_status_suspended(dev) || !dev->power.needs_force_resume) goto out; /* @@ -1807,6 +1890,7 @@ pm_runtime_mark_last_busy(dev); out: + dev->power.needs_force_resume = 0; pm_runtime_enable(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/base/power/sysfs.c +++ linux-oracle-5.4.0/drivers/base/power/sysfs.c @@ -100,7 +100,7 @@ static ssize_t control_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", + return sysfs_emit(buf, "%s\n", dev->power.runtime_auto ? ctrl_auto : ctrl_on); } @@ -126,7 +126,7 @@ int ret; u64 tmp = pm_runtime_active_time(dev); do_div(tmp, NSEC_PER_MSEC); - ret = sprintf(buf, "%llu\n", tmp); + ret = sysfs_emit(buf, "%llu\n", tmp); return ret; } @@ -138,7 +138,7 @@ int ret; u64 tmp = pm_runtime_suspended_time(dev); do_div(tmp, NSEC_PER_MSEC); - ret = sprintf(buf, "%llu\n", tmp); + ret = sysfs_emit(buf, "%llu\n", tmp); return ret; } @@ -171,7 +171,7 @@ return -EIO; } } - return sprintf(buf, p); + return sysfs_emit(buf, p); } static DEVICE_ATTR_RO(runtime_status); @@ -181,7 +181,7 @@ { if (!dev->power.use_autosuspend) return -EIO; - return sprintf(buf, "%d\n", dev->power.autosuspend_delay); + return sysfs_emit(buf, "%d\n", dev->power.autosuspend_delay); } static ssize_t autosuspend_delay_ms_store(struct device *dev, @@ -210,11 +210,11 @@ s32 value = dev_pm_qos_requested_resume_latency(dev); if (value == 0) - return sprintf(buf, "n/a\n"); + return sysfs_emit(buf, "n/a\n"); if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) value = 0; - return sprintf(buf, "%d\n", value); + return sysfs_emit(buf, "%d\n", value); } static ssize_t pm_qos_resume_latency_us_store(struct device *dev, @@ -254,11 +254,11 @@ s32 value = dev_pm_qos_get_user_latency_tolerance(dev); if (value < 0) - return sprintf(buf, "auto\n"); + return sysfs_emit(buf, "auto\n"); if (value == PM_QOS_LATENCY_ANY) - return sprintf(buf, "any\n"); + return sysfs_emit(buf, "any\n"); - return sprintf(buf, "%d\n", value); + return sysfs_emit(buf, "%d\n", value); } static ssize_t pm_qos_latency_tolerance_us_store(struct device *dev, @@ -290,8 +290,8 @@ struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) - & PM_QOS_FLAG_NO_POWER_OFF)); + return sysfs_emit(buf, "%d\n", !!(dev_pm_qos_requested_flags(dev) + & PM_QOS_FLAG_NO_POWER_OFF)); } static ssize_t pm_qos_no_power_off_store(struct device *dev, @@ -319,9 +319,9 @@ static ssize_t wakeup_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", device_can_wakeup(dev) - ? (device_may_wakeup(dev) ? _enabled : _disabled) - : ""); + return sysfs_emit(buf, "%s\n", device_can_wakeup(dev) + ? (device_may_wakeup(dev) ? _enabled : _disabled) + : ""); } static ssize_t wakeup_store(struct device *dev, struct device_attribute *attr, @@ -480,6 +480,14 @@ return enabled ? sprintf(buf, "%lld\n", msec) : sprintf(buf, "\n"); } +static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, + kgid_t kgid) +{ + if (dev->power.wakeup && dev->power.wakeup->dev) + return device_change_owner(dev->power.wakeup->dev, kuid, kgid); + return 0; +} + static DEVICE_ATTR_RO(wakeup_last_time_ms); #ifdef CONFIG_PM_AUTOSLEEP @@ -501,13 +509,19 @@ static DEVICE_ATTR_RO(wakeup_prevent_sleep_time_ms); #endif /* CONFIG_PM_AUTOSLEEP */ -#endif /* CONFIG_PM_SLEEP */ +#else /* CONFIG_PM_SLEEP */ +static inline int dpm_sysfs_wakeup_change_owner(struct device *dev, kuid_t kuid, + kgid_t kgid) +{ + return 0; +} +#endif #ifdef CONFIG_PM_ADVANCED_DEBUG static ssize_t runtime_usage_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", atomic_read(&dev->power.usage_count)); + return sysfs_emit(buf, "%d\n", atomic_read(&dev->power.usage_count)); } static DEVICE_ATTR_RO(runtime_usage); @@ -515,8 +529,8 @@ struct device_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", dev->power.ignore_children ? - 0 : atomic_read(&dev->power.child_count)); + return sysfs_emit(buf, "%d\n", dev->power.ignore_children ? + 0 : atomic_read(&dev->power.child_count)); } static DEVICE_ATTR_RO(runtime_active_kids); @@ -524,12 +538,12 @@ struct device_attribute *attr, char *buf) { if (dev->power.disable_depth && (dev->power.runtime_auto == false)) - return sprintf(buf, "disabled & forbidden\n"); + return sysfs_emit(buf, "disabled & forbidden\n"); if (dev->power.disable_depth) - return sprintf(buf, "disabled\n"); + return sysfs_emit(buf, "disabled\n"); if (dev->power.runtime_auto == false) - return sprintf(buf, "forbidden\n"); - return sprintf(buf, "enabled\n"); + return sysfs_emit(buf, "forbidden\n"); + return sysfs_emit(buf, "enabled\n"); } static DEVICE_ATTR_RO(runtime_enabled); @@ -537,9 +551,9 @@ static ssize_t async_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", - device_async_suspend_enabled(dev) ? - _enabled : _disabled); + return sysfs_emit(buf, "%s\n", + device_async_suspend_enabled(dev) ? + _enabled : _disabled); } static ssize_t async_store(struct device *dev, struct device_attribute *attr, @@ -684,6 +698,45 @@ return rc; } +int dpm_sysfs_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid) +{ + int rc; + + if (device_pm_not_required(dev)) + return 0; + + rc = sysfs_group_change_owner(&dev->kobj, &pm_attr_group, kuid, kgid); + if (rc) + return rc; + + if (pm_runtime_callbacks_present(dev)) { + rc = sysfs_group_change_owner( + &dev->kobj, &pm_runtime_attr_group, kuid, kgid); + if (rc) + return rc; + } + + if (device_can_wakeup(dev)) { + rc = sysfs_group_change_owner(&dev->kobj, &pm_wakeup_attr_group, + kuid, kgid); + if (rc) + return rc; + + rc = dpm_sysfs_wakeup_change_owner(dev, kuid, kgid); + if (rc) + return rc; + } + + if (dev->power.set_latency_tolerance) { + rc = sysfs_group_change_owner( + &dev->kobj, &pm_qos_latency_tolerance_attr_group, kuid, + kgid); + if (rc) + return rc; + } + return 0; +} + int wakeup_sysfs_add(struct device *dev) { return sysfs_merge_group(&dev->kobj, &pm_wakeup_attr_group); --- linux-oracle-5.4.0.orig/drivers/base/power/trace.c +++ linux-oracle-5.4.0/drivers/base/power/trace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -165,6 +166,9 @@ const char *file = *(const char **)(tracedata + 2); unsigned int user_hash_value, file_hash_value; + if (!x86_platform.legacy.rtc) + return; + user_hash_value = user % USERHASH; file_hash_value = hash_string(lineno, file, FILEHASH); set_magic_time(user_hash_value, file_hash_value, dev_hash_value); @@ -267,6 +271,9 @@ static int early_resume_init(void) { + if (!x86_platform.legacy.rtc) + return 0; + hash_value_early_read = read_magic_time(); register_pm_notifier(&pm_trace_nb); return 0; @@ -277,6 +284,9 @@ unsigned int val = hash_value_early_read; unsigned int user, file, dev; + if (!x86_platform.legacy.rtc) + return 0; + user = val % USERHASH; val = val / USERHASH; file = val % FILEHASH; --- linux-oracle-5.4.0.orig/drivers/base/power/wakeirq.c +++ linux-oracle-5.4.0/drivers/base/power/wakeirq.c @@ -145,24 +145,7 @@ return IRQ_HANDLED; } -/** - * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt - * @dev: Device entry - * @irq: Device wake-up interrupt - * - * Unless your hardware has separate wake-up interrupts in addition - * to the device IO interrupts, you don't need this. - * - * Sets up a threaded interrupt handler for a device that has - * a dedicated wake-up interrupt in addition to the device IO - * interrupt. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() - * functions. - */ -int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) +static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) { struct wake_irq *wirq; int err; @@ -200,7 +183,7 @@ if (err) goto err_free_irq; - wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; + wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; return err; @@ -213,9 +196,58 @@ return err; } + + +/** + * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt + * @dev: Device entry + * @irq: Device wake-up interrupt + * + * Unless your hardware has separate wake-up interrupts in addition + * to the device IO interrupts, you don't need this. + * + * Sets up a threaded interrupt handler for a device that has + * a dedicated wake-up interrupt in addition to the device IO + * interrupt. + * + * The interrupt starts disabled, and needs to be managed for + * the device by the bus code or the device driver using + * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() + * functions. + */ +int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) +{ + return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); +} EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); /** + * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt + * with reverse enable ordering + * @dev: Device entry + * @irq: Device wake-up interrupt + * + * Unless your hardware has separate wake-up interrupts in addition + * to the device IO interrupts, you don't need this. + * + * Sets up a threaded interrupt handler for a device that has a dedicated + * wake-up interrupt in addition to the device IO interrupt. It sets + * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() + * to enable dedicated wake-up interrupt after running the runtime suspend + * callback for @dev. + * + * The interrupt starts disabled, and needs to be managed for + * the device by the bus code or the device driver using + * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() + * functions. + */ +int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) +{ + return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); +} +EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); + +/** * dev_pm_enable_wake_irq - Enable device wake-up interrupt * @dev: Device * @@ -285,25 +317,58 @@ return; enable: - enable_irq(wirq->irq); + if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { + enable_irq(wirq->irq); + wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; + } } /** * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt * @dev: Device + * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE * * Disables wake-up interrupt conditionally based on status. * Should be only called from rpm_suspend() and rpm_resume() path. */ -void dev_pm_disable_wake_irq_check(struct device *dev) +void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) { struct wake_irq *wirq = dev->power.wakeirq; if (!wirq || !((wirq->status & WAKE_IRQ_DEDICATED_MASK))) return; - if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) + if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) + return; + + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { + wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; disable_irq_nosync(wirq->irq); + } +} + +/** + * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before + * @dev: Device using the wake IRQ + * + * Enable wake IRQ conditionally based on status, mainly used if want to + * enable wake IRQ after running ->runtime_suspend() which depends on + * WAKE_IRQ_DEDICATED_REVERSE. + * + * Should be only called from rpm_suspend() path. + */ +void dev_pm_enable_wake_irq_complete(struct device *dev) +{ + struct wake_irq *wirq = dev->power.wakeirq; + + if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) + return; + + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && + wirq->status & WAKE_IRQ_DEDICATED_REVERSE) { + enable_irq(wirq->irq); + wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; + } } /** @@ -320,7 +385,7 @@ if (device_may_wakeup(wirq->dev)) { if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended(wirq->dev)) + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) enable_irq(wirq->irq); enable_irq_wake(wirq->irq); @@ -343,7 +408,7 @@ disable_irq_wake(wirq->irq); if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended(wirq->dev)) + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) disable_irq_nosync(wirq->irq); } } --- linux-oracle-5.4.0.orig/drivers/base/power/wakeup.c +++ linux-oracle-5.4.0/drivers/base/power/wakeup.c @@ -31,7 +31,8 @@ bool events_check_enabled __read_mostly; /* First wakeup IRQ seen by the kernel in the last cycle. */ -unsigned int pm_wakeup_irq __read_mostly; +static unsigned int wakeup_irq[2] __read_mostly; +static DEFINE_RAW_SPINLOCK(wakeup_irq_lock); /* If greater than 0 and the system is suspending, terminate the suspend. */ static atomic_t pm_abort_suspend __read_mostly; @@ -241,7 +242,9 @@ { if (ws) { wakeup_source_remove(ws); - wakeup_source_sysfs_remove(ws); + if (ws->dev) + wakeup_source_sysfs_remove(ws); + wakeup_source_destroy(ws); } } @@ -882,19 +885,45 @@ atomic_dec_if_positive(&pm_abort_suspend); } -void pm_wakeup_clear(bool reset) +void pm_wakeup_clear(unsigned int irq_number) { - pm_wakeup_irq = 0; - if (reset) + raw_spin_lock_irq(&wakeup_irq_lock); + + if (irq_number && wakeup_irq[0] == irq_number) + wakeup_irq[0] = wakeup_irq[1]; + else + wakeup_irq[0] = 0; + + wakeup_irq[1] = 0; + + raw_spin_unlock_irq(&wakeup_irq_lock); + + if (!irq_number) atomic_set(&pm_abort_suspend, 0); } void pm_system_irq_wakeup(unsigned int irq_number) { - if (pm_wakeup_irq == 0) { - pm_wakeup_irq = irq_number; + unsigned long flags; + + raw_spin_lock_irqsave(&wakeup_irq_lock, flags); + + if (wakeup_irq[0] == 0) + wakeup_irq[0] = irq_number; + else if (wakeup_irq[1] == 0) + wakeup_irq[1] = irq_number; + else + irq_number = 0; + + raw_spin_unlock_irqrestore(&wakeup_irq_lock, flags); + + if (irq_number) pm_system_wakeup(); - } +} + +unsigned int pm_wakeup_irq(void) +{ + return wakeup_irq[0]; } /** @@ -1071,6 +1100,9 @@ break; } + if (!next_ws) + print_wakeup_source_stats(m, &deleted_ws); + return next_ws; } --- linux-oracle-5.4.0.orig/drivers/base/power/wakeup_stats.c +++ linux-oracle-5.4.0/drivers/base/power/wakeup_stats.c @@ -42,7 +42,7 @@ ktime_t active_time = ws->active ? ktime_sub(ktime_get(), ws->last_time) : 0; - return sprintf(buf, "%lld\n", ktime_to_ms(active_time)); + return sysfs_emit(buf, "%lld\n", ktime_to_ms(active_time)); } static DEVICE_ATTR_RO(active_time_ms); @@ -57,7 +57,7 @@ active_time = ktime_sub(ktime_get(), ws->last_time); total_time = ktime_add(total_time, active_time); } - return sprintf(buf, "%lld\n", ktime_to_ms(total_time)); + return sysfs_emit(buf, "%lld\n", ktime_to_ms(total_time)); } static DEVICE_ATTR_RO(total_time_ms); @@ -73,7 +73,7 @@ if (active_time > max_time) max_time = active_time; } - return sprintf(buf, "%lld\n", ktime_to_ms(max_time)); + return sysfs_emit(buf, "%lld\n", ktime_to_ms(max_time)); } static DEVICE_ATTR_RO(max_time_ms); @@ -82,7 +82,7 @@ { struct wakeup_source *ws = dev_get_drvdata(dev); - return sprintf(buf, "%lld\n", ktime_to_ms(ws->last_time)); + return sysfs_emit(buf, "%lld\n", ktime_to_ms(ws->last_time)); } static DEVICE_ATTR_RO(last_change_ms); @@ -91,7 +91,7 @@ { struct wakeup_source *ws = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", ws->name); + return sysfs_emit(buf, "%s\n", ws->name); } static DEVICE_ATTR_RO(name); @@ -106,7 +106,7 @@ prevent_sleep_time = ktime_add(prevent_sleep_time, ktime_sub(ktime_get(), ws->start_prevent_time)); } - return sprintf(buf, "%lld\n", ktime_to_ms(prevent_sleep_time)); + return sysfs_emit(buf, "%lld\n", ktime_to_ms(prevent_sleep_time)); } static DEVICE_ATTR_RO(prevent_suspend_time_ms); --- linux-oracle-5.4.0.orig/drivers/base/regmap/internal.h +++ linux-oracle-5.4.0/drivers/base/regmap/internal.h @@ -104,6 +104,10 @@ int (*reg_write)(void *context, unsigned int reg, unsigned int val); int (*reg_update_bits)(void *context, unsigned int reg, unsigned int mask, unsigned int val); + /* Bulk read/write */ + int (*read)(void *context, const void *reg_buf, size_t reg_size, + void *val_buf, size_t val_size); + int (*write)(void *context, const void *data, size_t count); bool defer_caching; @@ -259,7 +263,7 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg); int _regmap_raw_write(struct regmap *map, unsigned int reg, - const void *val, size_t val_len); + const void *val, size_t val_len, bool noinc); void regmap_async_complete_cb(struct regmap_async *async, int ret); --- linux-oracle-5.4.0.orig/drivers/base/regmap/regcache-rbtree.c +++ linux-oracle-5.4.0/drivers/base/regmap/regcache-rbtree.c @@ -277,18 +277,18 @@ blk = krealloc(rbnode->block, blklen * map->cache_word_size, - GFP_KERNEL); + map->alloc_flags); if (!blk) return -ENOMEM; + rbnode->block = blk; + if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) { present = krealloc(rbnode->cache_present, BITS_TO_LONGS(blklen) * sizeof(*present), - GFP_KERNEL); - if (!present) { - kfree(blk); + map->alloc_flags); + if (!present) return -ENOMEM; - } memset(present + BITS_TO_LONGS(rbnode->blklen), 0, (BITS_TO_LONGS(blklen) - BITS_TO_LONGS(rbnode->blklen)) @@ -305,7 +305,6 @@ } /* update the rbnode block, its size and the base register */ - rbnode->block = blk; rbnode->blklen = blklen; rbnode->base_reg = base_reg; rbnode->cache_present = present; @@ -321,7 +320,7 @@ const struct regmap_range *range; int i; - rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL); + rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags); if (!rbnode) return NULL; @@ -347,13 +346,13 @@ } rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size, - GFP_KERNEL); + map->alloc_flags); if (!rbnode->block) goto err_free; rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen), sizeof(*rbnode->cache_present), - GFP_KERNEL); + map->alloc_flags); if (!rbnode->cache_present) goto err_free_block; @@ -454,7 +453,8 @@ if (!rbnode) return -ENOMEM; regcache_rbtree_set_register(map, rbnode, - reg - rbnode->base_reg, value); + (reg - rbnode->base_reg) / map->reg_stride, + value); regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); rbtree_ctx->cached_rbnode = rbnode; } --- linux-oracle-5.4.0.orig/drivers/base/regmap/regcache.c +++ linux-oracle-5.4.0/drivers/base/regmap/regcache.c @@ -343,6 +343,9 @@ const char *name; bool bypass; + if (WARN_ON(map->cache_type == REGCACHE_NONE)) + return -EINVAL; + BUG_ON(!map->cache_ops); map->lock(map->lock_arg); @@ -412,6 +415,9 @@ const char *name; bool bypass; + if (WARN_ON(map->cache_type == REGCACHE_NONE)) + return -EINVAL; + BUG_ON(!map->cache_ops); map->lock(map->lock_arg); @@ -717,7 +723,7 @@ map->cache_bypass = true; - ret = _regmap_raw_write(map, base, *data, count * val_bytes); + ret = _regmap_raw_write(map, base, *data, count * val_bytes, false); if (ret) dev_err(map->dev, "Unable to sync registers %#x-%#x. %d\n", base, cur - map->reg_stride, ret); --- linux-oracle-5.4.0.orig/drivers/base/regmap/regmap-debugfs.c +++ linux-oracle-5.4.0/drivers/base/regmap/regmap-debugfs.c @@ -49,7 +49,7 @@ name = map->dev->driver->name; ret = snprintf(buf, PAGE_SIZE, "%s\n", name); - if (ret < 0) { + if (ret >= PAGE_SIZE) { kfree(buf); return ret; } @@ -227,6 +227,9 @@ if (*ppos < 0 || !count) return -EINVAL; + if (count > (PAGE_SIZE << (MAX_ORDER - 1))) + count = PAGE_SIZE << (MAX_ORDER - 1); + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -371,6 +374,9 @@ if (*ppos < 0 || !count) return -EINVAL; + if (count > (PAGE_SIZE << (MAX_ORDER - 1))) + count = PAGE_SIZE << (MAX_ORDER - 1); + buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -457,29 +463,31 @@ { struct regmap *map = container_of(file->private_data, struct regmap, cache_only); - ssize_t result; - bool was_enabled, require_sync = false; + bool new_val, require_sync = false; int err; - map->lock(map->lock_arg); - - was_enabled = map->cache_only; + err = kstrtobool_from_user(user_buf, count, &new_val); + /* Ignore malforned data like debugfs_write_file_bool() */ + if (err) + return count; + + err = debugfs_file_get(file->f_path.dentry); + if (err) + return err; - result = debugfs_write_file_bool(file, user_buf, count, ppos); - if (result < 0) { - map->unlock(map->lock_arg); - return result; - } + map->lock(map->lock_arg); - if (map->cache_only && !was_enabled) { + if (new_val && !map->cache_only) { dev_warn(map->dev, "debugfs cache_only=Y forced\n"); add_taint(TAINT_USER, LOCKDEP_STILL_OK); - } else if (!map->cache_only && was_enabled) { + } else if (!new_val && map->cache_only) { dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n"); require_sync = true; } + map->cache_only = new_val; map->unlock(map->lock_arg); + debugfs_file_put(file->f_path.dentry); if (require_sync) { err = regcache_sync(map); @@ -487,7 +495,7 @@ dev_err(map->dev, "Failed to sync cache %d\n", err); } - return result; + return count; } static const struct file_operations regmap_cache_only_fops = { @@ -502,28 +510,32 @@ { struct regmap *map = container_of(file->private_data, struct regmap, cache_bypass); - ssize_t result; - bool was_enabled; - - map->lock(map->lock_arg); + bool new_val; + int err; - was_enabled = map->cache_bypass; + err = kstrtobool_from_user(user_buf, count, &new_val); + /* Ignore malforned data like debugfs_write_file_bool() */ + if (err) + return count; + + err = debugfs_file_get(file->f_path.dentry); + if (err) + return err; - result = debugfs_write_file_bool(file, user_buf, count, ppos); - if (result < 0) - goto out; + map->lock(map->lock_arg); - if (map->cache_bypass && !was_enabled) { + if (new_val && !map->cache_bypass) { dev_warn(map->dev, "debugfs cache_bypass=Y forced\n"); add_taint(TAINT_USER, LOCKDEP_STILL_OK); - } else if (!map->cache_bypass && was_enabled) { + } else if (!new_val && map->cache_bypass) { dev_warn(map->dev, "debugfs cache_bypass=N forced\n"); } + map->cache_bypass = new_val; -out: map->unlock(map->lock_arg); + debugfs_file_put(file->f_path.dentry); - return result; + return count; } static const struct file_operations regmap_cache_bypass_fops = { @@ -571,8 +583,12 @@ devname = dev_name(map->dev); if (name) { - map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", + if (!map->debugfs_name) { + map->debugfs_name = kasprintf(GFP_KERNEL, "%s-%s", devname, name); + if (!map->debugfs_name) + return; + } name = map->debugfs_name; } else { name = devname; @@ -580,9 +596,10 @@ if (!strcmp(name, "dummy")) { kfree(map->debugfs_name); - map->debugfs_name = kasprintf(GFP_KERNEL, "dummy%d", dummy_index); + if (!map->debugfs_name) + return; name = map->debugfs_name; dummy_index++; } @@ -644,6 +661,7 @@ regmap_debugfs_free_dump_cache(map); mutex_unlock(&map->cache_lock); kfree(map->debugfs_name); + map->debugfs_name = NULL; } else { struct regmap_debugfs_node *node, *tmp; --- linux-oracle-5.4.0.orig/drivers/base/regmap/regmap-i2c.c +++ linux-oracle-5.4.0/drivers/base/regmap/regmap-i2c.c @@ -242,6 +242,63 @@ static struct regmap_bus regmap_i2c_smbus_i2c_block = { .write = regmap_i2c_smbus_i2c_write, .read = regmap_i2c_smbus_i2c_read, + .max_raw_read = I2C_SMBUS_BLOCK_MAX - 1, + .max_raw_write = I2C_SMBUS_BLOCK_MAX - 1, +}; + +static int regmap_i2c_smbus_i2c_write_reg16(void *context, const void *data, + size_t count) +{ + struct device *dev = context; + struct i2c_client *i2c = to_i2c_client(dev); + + if (count < 2) + return -EINVAL; + + count--; + return i2c_smbus_write_i2c_block_data(i2c, ((u8 *)data)[0], count, + (u8 *)data + 1); +} + +static int regmap_i2c_smbus_i2c_read_reg16(void *context, const void *reg, + size_t reg_size, void *val, + size_t val_size) +{ + struct device *dev = context; + struct i2c_client *i2c = to_i2c_client(dev); + int ret, count, len = val_size; + + if (reg_size != 2) + return -EINVAL; + + ret = i2c_smbus_write_byte_data(i2c, ((u16 *)reg)[0] & 0xff, + ((u16 *)reg)[0] >> 8); + if (ret < 0) + return ret; + + count = 0; + do { + /* Current Address Read */ + ret = i2c_smbus_read_byte(i2c); + if (ret < 0) + break; + + *((u8 *)val++) = ret; + count++; + len--; + } while (len > 0); + + if (count == val_size) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = { + .write = regmap_i2c_smbus_i2c_write_reg16, + .read = regmap_i2c_smbus_i2c_read_reg16, .max_raw_read = I2C_SMBUS_BLOCK_MAX, .max_raw_write = I2C_SMBUS_BLOCK_MAX, }; @@ -255,6 +312,10 @@ i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) return ®map_i2c_smbus_i2c_block; + else if (config->val_bits == 8 && config->reg_bits == 16 && + i2c_check_functionality(i2c->adapter, + I2C_FUNC_SMBUS_I2C_BLOCK)) + return ®map_i2c_smbus_i2c_block_reg16; else if (config->val_bits == 16 && config->reg_bits == 8 && i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_WORD_DATA)) --- linux-oracle-5.4.0.orig/drivers/base/regmap/regmap-irq.c +++ linux-oracle-5.4.0/drivers/base/regmap/regmap-irq.c @@ -214,6 +214,7 @@ struct regmap_irq_chip_data *d = irq_data_get_irq_chip_data(data); struct regmap *map = d->map; const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq); + unsigned int reg = irq_data->reg_offset / map->reg_stride; unsigned int mask, type; type = irq_data->type.type_falling_val | irq_data->type.type_rising_val; @@ -230,14 +231,14 @@ * at the corresponding offset in regmap_irq_set_type(). */ if (d->chip->type_in_mask && type) - mask = d->type_buf[irq_data->reg_offset / map->reg_stride]; + mask = d->type_buf[reg] & irq_data->mask; else mask = irq_data->mask; if (d->chip->clear_on_unmask) d->clear_status = true; - d->mask_buf[irq_data->reg_offset / map->reg_stride] &= ~mask; + d->mask_buf[reg] &= ~mask; } static void regmap_irq_disable(struct irq_data *data) @@ -521,12 +522,16 @@ return IRQ_NONE; } +static struct lock_class_key regmap_irq_lock_class; +static struct lock_class_key regmap_irq_request_class; + static int regmap_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { struct regmap_irq_chip_data *data = h->host_data; irq_set_chip_data(virq, data); + irq_set_lockdep_class(virq, ®map_irq_lock_class, ®map_irq_request_class); irq_set_chip(virq, &data->irq_chip); irq_set_nested_thread(virq, 1); irq_set_parent(virq, data->irq); @@ -803,6 +808,7 @@ kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); + kfree(d->main_status_buf); kfree(d->status_buf); kfree(d->status_reg_buf); kfree(d); @@ -849,6 +855,7 @@ kfree(d->wake_buf); kfree(d->mask_buf_def); kfree(d->mask_buf); + kfree(d->main_status_buf); kfree(d->status_reg_buf); kfree(d->status_buf); kfree(d); --- linux-oracle-5.4.0.orig/drivers/base/regmap/regmap-sdw.c +++ linux-oracle-5.4.0/drivers/base/regmap/regmap-sdw.c @@ -12,7 +12,7 @@ struct device *dev = context; struct sdw_slave *slave = dev_to_sdw_dev(dev); - return sdw_write(slave, reg, val); + return sdw_write_no_pm(slave, reg, val); } static int regmap_sdw_read(void *context, unsigned int reg, unsigned int *val) @@ -21,7 +21,7 @@ struct sdw_slave *slave = dev_to_sdw_dev(dev); int read; - read = sdw_read(slave, reg); + read = sdw_read_no_pm(slave, reg); if (read < 0) return read; --- linux-oracle-5.4.0.orig/drivers/base/regmap/regmap.c +++ linux-oracle-5.4.0/drivers/base/regmap/regmap.c @@ -17,6 +17,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include "trace.h" @@ -249,22 +250,20 @@ static void regmap_format_16_be(void *buf, unsigned int val, unsigned int shift) { - __be16 *b = buf; - - b[0] = cpu_to_be16(val << shift); + put_unaligned_be16(val << shift, buf); } static void regmap_format_16_le(void *buf, unsigned int val, unsigned int shift) { - __le16 *b = buf; - - b[0] = cpu_to_le16(val << shift); + put_unaligned_le16(val << shift, buf); } static void regmap_format_16_native(void *buf, unsigned int val, unsigned int shift) { - *(u16 *)buf = val << shift; + u16 v = val << shift; + + memcpy(buf, &v, sizeof(v)); } static void regmap_format_24(void *buf, unsigned int val, unsigned int shift) @@ -280,43 +279,39 @@ static void regmap_format_32_be(void *buf, unsigned int val, unsigned int shift) { - __be32 *b = buf; - - b[0] = cpu_to_be32(val << shift); + put_unaligned_be32(val << shift, buf); } static void regmap_format_32_le(void *buf, unsigned int val, unsigned int shift) { - __le32 *b = buf; - - b[0] = cpu_to_le32(val << shift); + put_unaligned_le32(val << shift, buf); } static void regmap_format_32_native(void *buf, unsigned int val, unsigned int shift) { - *(u32 *)buf = val << shift; + u32 v = val << shift; + + memcpy(buf, &v, sizeof(v)); } #ifdef CONFIG_64BIT static void regmap_format_64_be(void *buf, unsigned int val, unsigned int shift) { - __be64 *b = buf; - - b[0] = cpu_to_be64((u64)val << shift); + put_unaligned_be64((u64) val << shift, buf); } static void regmap_format_64_le(void *buf, unsigned int val, unsigned int shift) { - __le64 *b = buf; - - b[0] = cpu_to_le64((u64)val << shift); + put_unaligned_le64((u64) val << shift, buf); } static void regmap_format_64_native(void *buf, unsigned int val, unsigned int shift) { - *(u64 *)buf = (u64)val << shift; + u64 v = (u64) val << shift; + + memcpy(buf, &v, sizeof(v)); } #endif @@ -333,35 +328,34 @@ static unsigned int regmap_parse_16_be(const void *buf) { - const __be16 *b = buf; - - return be16_to_cpu(b[0]); + return get_unaligned_be16(buf); } static unsigned int regmap_parse_16_le(const void *buf) { - const __le16 *b = buf; - - return le16_to_cpu(b[0]); + return get_unaligned_le16(buf); } static void regmap_parse_16_be_inplace(void *buf) { - __be16 *b = buf; + u16 v = get_unaligned_be16(buf); - b[0] = be16_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_16_le_inplace(void *buf) { - __le16 *b = buf; + u16 v = get_unaligned_le16(buf); - b[0] = le16_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_16_native(const void *buf) { - return *(u16 *)buf; + u16 v; + + memcpy(&v, buf, sizeof(v)); + return v; } static unsigned int regmap_parse_24(const void *buf) @@ -376,69 +370,67 @@ static unsigned int regmap_parse_32_be(const void *buf) { - const __be32 *b = buf; - - return be32_to_cpu(b[0]); + return get_unaligned_be32(buf); } static unsigned int regmap_parse_32_le(const void *buf) { - const __le32 *b = buf; - - return le32_to_cpu(b[0]); + return get_unaligned_le32(buf); } static void regmap_parse_32_be_inplace(void *buf) { - __be32 *b = buf; + u32 v = get_unaligned_be32(buf); - b[0] = be32_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_32_le_inplace(void *buf) { - __le32 *b = buf; + u32 v = get_unaligned_le32(buf); - b[0] = le32_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_32_native(const void *buf) { - return *(u32 *)buf; + u32 v; + + memcpy(&v, buf, sizeof(v)); + return v; } #ifdef CONFIG_64BIT static unsigned int regmap_parse_64_be(const void *buf) { - const __be64 *b = buf; - - return be64_to_cpu(b[0]); + return get_unaligned_be64(buf); } static unsigned int regmap_parse_64_le(const void *buf) { - const __le64 *b = buf; - - return le64_to_cpu(b[0]); + return get_unaligned_le64(buf); } static void regmap_parse_64_be_inplace(void *buf) { - __be64 *b = buf; + u64 v = get_unaligned_be64(buf); - b[0] = be64_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static void regmap_parse_64_le_inplace(void *buf) { - __le64 *b = buf; + u64 v = get_unaligned_le64(buf); - b[0] = le64_to_cpu(b[0]); + memcpy(buf, &v, sizeof(v)); } static unsigned int regmap_parse_64_native(const void *buf) { - return *(u64 *)buf; + u64 v; + + memcpy(&v, buf, sizeof(v)); + return v; } #endif @@ -611,6 +603,17 @@ } EXPORT_SYMBOL_GPL(regmap_attach_dev); +static int dev_get_regmap_match(struct device *dev, void *res, void *data); + +static int regmap_detach_dev(struct device *dev, struct regmap *map) +{ + if (!dev) + return 0; + + return devres_release(dev, dev_get_regmap_release, + dev_get_regmap_match, (void *)map->name); +} + static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus, const struct regmap_config *config) { @@ -779,12 +782,15 @@ map->reg_stride_order = ilog2(map->reg_stride); else map->reg_stride_order = -1; - map->use_single_read = config->use_single_read || !bus || !bus->read; - map->use_single_write = config->use_single_write || !bus || !bus->write; - map->can_multi_write = config->can_multi_write && bus && bus->write; + map->use_single_read = config->use_single_read || !(config->read || (bus && bus->read)); + map->use_single_write = config->use_single_write || !(config->write || (bus && bus->write)); + map->can_multi_write = config->can_multi_write && (config->write || (bus && bus->write)); if (bus) { map->max_raw_read = bus->max_raw_read; map->max_raw_write = bus->max_raw_write; + } else if (config->max_raw_read && config->max_raw_write) { + map->max_raw_read = config->max_raw_read; + map->max_raw_write = config->max_raw_write; } map->dev = dev; map->bus = bus; @@ -818,9 +824,19 @@ map->read_flag_mask = bus->read_flag_mask; } - if (!bus) { + if (config && config->read && config->write) { + map->reg_read = _regmap_bus_read; + + /* Bulk read/write */ + map->read = config->read; + map->write = config->write; + + reg_endian = REGMAP_ENDIAN_NATIVE; + val_endian = REGMAP_ENDIAN_NATIVE; + } else if (!bus) { map->reg_read = config->reg_read; map->reg_write = config->reg_write; + map->reg_update_bits = config->reg_update_bits; map->defer_caching = false; goto skip_format_initialization; @@ -833,10 +849,13 @@ } else { map->reg_read = _regmap_bus_read; map->reg_update_bits = bus->reg_update_bits; - } + /* Bulk read/write */ + map->read = bus->read; + map->write = bus->write; - reg_endian = regmap_get_reg_endian(bus, config); - val_endian = regmap_get_val_endian(dev, bus, config); + reg_endian = regmap_get_reg_endian(bus, config); + val_endian = regmap_get_val_endian(dev, bus, config); + } switch (config->reg_bits + map->reg_shift) { case 2: @@ -1056,13 +1075,13 @@ /* Sanity check */ if (range_cfg->range_max < range_cfg->range_min) { - dev_err(map->dev, "Invalid range %d: %d < %d\n", i, + dev_err(map->dev, "Invalid range %d: %u < %u\n", i, range_cfg->range_max, range_cfg->range_min); goto err_range; } if (range_cfg->range_max > map->max_register) { - dev_err(map->dev, "Invalid range %d: %d > %d\n", i, + dev_err(map->dev, "Invalid range %d: %u > %u\n", i, range_cfg->range_max, map->max_register); goto err_range; } @@ -1339,6 +1358,7 @@ { struct regmap_async *async; + regmap_detach_dev(map->dev, map); regcache_exit(map); regmap_debugfs_exit(map); regmap_range_exit(map); @@ -1356,6 +1376,7 @@ if (map->hwlock) hwspin_lock_free(map->hwlock); kfree_const(map->name); + kfree(map->patch); kfree(map); } EXPORT_SYMBOL_GPL(regmap_exit); @@ -1370,7 +1391,7 @@ /* If the user didn't specify a name match any */ if (data) - return (*r)->name == data; + return (*r)->name && !strcmp((*r)->name, data); else return 1; } @@ -1475,7 +1496,7 @@ } static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg, - const void *val, size_t val_len) + const void *val, size_t val_len, bool noinc) { struct regmap_range_node *range; unsigned long flags; @@ -1486,26 +1507,33 @@ size_t len; int i; - WARN_ON(!map->bus); - - /* Check for unwritable registers before we start */ - for (i = 0; i < val_len / map->format.val_bytes; i++) - if (!regmap_writeable(map, - reg + regmap_get_offset(map, i))) - return -EINVAL; + /* Check for unwritable or noinc registers in range + * before we start + */ + if (!regmap_writeable_noinc(map, reg)) { + for (i = 0; i < val_len / map->format.val_bytes; i++) { + unsigned int element = + reg + regmap_get_offset(map, i); + if (!regmap_writeable(map, element) || + regmap_writeable_noinc(map, element)) + return -EINVAL; + } + } if (!map->cache_bypass && map->format.parse_val) { - unsigned int ival; + unsigned int ival, offset; int val_bytes = map->format.val_bytes; - for (i = 0; i < val_len / val_bytes; i++) { - ival = map->format.parse_val(val + (i * val_bytes)); - ret = regcache_write(map, - reg + regmap_get_offset(map, i), - ival); + + /* Cache the last written value for noinc writes */ + i = noinc ? val_len - val_bytes : 0; + for (; i < val_len; i += val_bytes) { + ival = map->format.parse_val(val + i); + offset = noinc ? 0 : regmap_get_offset(map, i / val_bytes); + ret = regcache_write(map, reg + offset, ival); if (ret) { dev_err(map->dev, "Error in caching of register: %x ret: %d\n", - reg + i, ret); + reg + offset, ret); return ret; } } @@ -1527,7 +1555,7 @@ win_residue, val_len / map->format.val_bytes); ret = _regmap_raw_write_impl(map, reg, val, win_residue * - map->format.val_bytes); + map->format.val_bytes, noinc); if (ret != 0) return ret; @@ -1541,7 +1569,7 @@ win_residue = range->window_len - win_offset; } - ret = _regmap_select_page(map, ®, range, val_num); + ret = _regmap_select_page(map, ®, range, noinc ? 1 : val_num); if (ret != 0) return ret; } @@ -1560,7 +1588,7 @@ val = work_val; } - if (map->async && map->bus->async_write) { + if (map->async && map->bus && map->bus->async_write) { struct regmap_async *async; trace_regmap_async_write_start(map, reg, val_len); @@ -1628,11 +1656,11 @@ * write. */ if (val == work_val) - ret = map->bus->write(map->bus_context, map->work_buf, - map->format.reg_bytes + - map->format.pad_bytes + - val_len); - else if (map->bus->gather_write) + ret = map->write(map->bus_context, map->work_buf, + map->format.reg_bytes + + map->format.pad_bytes + + val_len); + else if (map->bus && map->bus->gather_write) ret = map->bus->gather_write(map->bus_context, map->work_buf, map->format.reg_bytes + map->format.pad_bytes, @@ -1650,7 +1678,7 @@ memcpy(buf, map->work_buf, map->format.reg_bytes); memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, val, val_len); - ret = map->bus->write(map->bus_context, buf, len); + ret = map->write(map->bus_context, buf, len); kfree(buf); } else if (ret != 0 && !map->cache_bypass && map->format.parse_val) { @@ -1707,7 +1735,7 @@ struct regmap_range_node *range; struct regmap *map = context; - WARN_ON(!map->bus || !map->format.format_write); + WARN_ON(!map->format.format_write); range = _regmap_range_lookup(map, reg); if (range) { @@ -1720,8 +1748,7 @@ trace_regmap_hw_write_start(map, reg, 1); - ret = map->bus->write(map->bus_context, map->work_buf, - map->format.buf_size); + ret = map->write(map->bus_context, map->work_buf, map->format.buf_size); trace_regmap_hw_write_done(map, reg, 1); @@ -1741,7 +1768,7 @@ { struct regmap *map = context; - WARN_ON(!map->bus || !map->format.format_val); + WARN_ON(!map->format.format_val); map->format.format_val(map->work_buf + map->format.reg_bytes + map->format.pad_bytes, val, 0); @@ -1749,12 +1776,13 @@ map->work_buf + map->format.reg_bytes + map->format.pad_bytes, - map->format.val_bytes); + map->format.val_bytes, + false); } static inline void *_regmap_map_get_context(struct regmap *map) { - return (map->bus) ? map : map->bus_context; + return (map->bus || (!map->bus && map->read)) ? map : map->bus_context; } int _regmap_write(struct regmap *map, unsigned int reg, @@ -1843,12 +1871,14 @@ EXPORT_SYMBOL_GPL(regmap_write_async); int _regmap_raw_write(struct regmap *map, unsigned int reg, - const void *val, size_t val_len) + const void *val, size_t val_len, bool noinc) { size_t val_bytes = map->format.val_bytes; size_t val_count = val_len / val_bytes; size_t chunk_count, chunk_bytes; size_t chunk_regs = val_count; + size_t max_data = map->max_raw_write - map->format.reg_bytes - + map->format.pad_bytes; int ret, i; if (!val_count) @@ -1856,15 +1886,15 @@ if (map->use_single_write) chunk_regs = 1; - else if (map->max_raw_write && val_len > map->max_raw_write) - chunk_regs = map->max_raw_write / val_bytes; + else if (map->max_raw_write && val_len > max_data) + chunk_regs = max_data / val_bytes; chunk_count = val_count / chunk_regs; chunk_bytes = chunk_regs * val_bytes; /* Write as many bytes as possible with chunk_size */ for (i = 0; i < chunk_count; i++) { - ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes); + ret = _regmap_raw_write_impl(map, reg, val, chunk_bytes, noinc); if (ret) return ret; @@ -1875,7 +1905,7 @@ /* Write remaining bytes */ if (val_len) - ret = _regmap_raw_write_impl(map, reg, val, val_len); + ret = _regmap_raw_write_impl(map, reg, val, val_len, noinc); return ret; } @@ -1908,7 +1938,7 @@ map->lock(map->lock_arg); - ret = _regmap_raw_write(map, reg, val, val_len); + ret = _regmap_raw_write(map, reg, val, val_len, false); map->unlock(map->lock_arg); @@ -1966,7 +1996,7 @@ write_len = map->max_raw_write; else write_len = val_len; - ret = _regmap_raw_write(map, reg, val, write_len); + ret = _regmap_raw_write(map, reg, val, write_len, true); if (ret) goto out_unlock; val = ((u8 *)val) + write_len; @@ -2161,7 +2191,7 @@ u8 = buf; *u8 |= map->write_flag_mask; - ret = map->bus->write(map->bus_context, buf, len); + ret = map->write(map->bus_context, buf, len); kfree(buf); @@ -2443,7 +2473,7 @@ map->async = true; - ret = _regmap_raw_write(map, reg, val, val_len); + ret = _regmap_raw_write(map, reg, val, val_len, false); map->async = false; @@ -2454,20 +2484,18 @@ EXPORT_SYMBOL_GPL(regmap_raw_write_async); static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, - unsigned int val_len) + unsigned int val_len, bool noinc) { struct regmap_range_node *range; int ret; - WARN_ON(!map->bus); - - if (!map->bus || !map->bus->read) + if (!map->read) return -EINVAL; range = _regmap_range_lookup(map, reg); if (range) { ret = _regmap_select_page(map, ®, range, - val_len / map->format.val_bytes); + noinc ? 1 : val_len / map->format.val_bytes); if (ret != 0) return ret; } @@ -2477,9 +2505,9 @@ map->read_flag_mask); trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes); - ret = map->bus->read(map->bus_context, map->work_buf, - map->format.reg_bytes + map->format.pad_bytes, - val, val_len); + ret = map->read(map->bus_context, map->work_buf, + map->format.reg_bytes + map->format.pad_bytes, + val, val_len); trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes); @@ -2505,7 +2533,7 @@ if (!map->format.parse_val) return -EINVAL; - ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes); + ret = _regmap_raw_read(map, reg, work_val, map->format.val_bytes, false); if (ret == 0) *val = map->format.parse_val(work_val); @@ -2590,8 +2618,6 @@ unsigned int v; int ret, i; - if (!map->bus) - return -EINVAL; if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) @@ -2606,7 +2632,7 @@ size_t chunk_count, chunk_bytes; size_t chunk_regs = val_count; - if (!map->bus->read) { + if (!map->read) { ret = -ENOTSUPP; goto out; } @@ -2621,7 +2647,7 @@ /* Read bytes that fit into whole chunks */ for (i = 0; i < chunk_count; i++) { - ret = _regmap_raw_read(map, reg, val, chunk_bytes); + ret = _regmap_raw_read(map, reg, val, chunk_bytes, false); if (ret != 0) goto out; @@ -2632,7 +2658,7 @@ /* Read remaining bytes */ if (val_len) { - ret = _regmap_raw_read(map, reg, val, val_len); + ret = _regmap_raw_read(map, reg, val, val_len, false); if (ret != 0) goto out; } @@ -2666,7 +2692,7 @@ * @val: Pointer to data buffer * @val_len: Length of output buffer in bytes. * - * The regmap API usually assumes that bulk bus read operations will read a + * The regmap API usually assumes that bulk read operations will read a * range of registers. Some devices have certain registers for which a read * operation read will read from an internal FIFO. * @@ -2684,10 +2710,6 @@ size_t read_len; int ret; - if (!map->bus) - return -EINVAL; - if (!map->bus->read) - return -ENOTSUPP; if (val_len % map->format.val_bytes) return -EINVAL; if (!IS_ALIGNED(reg, map->reg_stride)) @@ -2707,7 +2729,7 @@ read_len = map->max_raw_read; else read_len = val_len; - ret = _regmap_raw_read(map, reg, val, read_len); + ret = _regmap_raw_read(map, reg, val, read_len, true); if (ret) goto out_unlock; val = ((u8 *)val) + read_len; @@ -2801,7 +2823,7 @@ if (val_count == 0) return -EINVAL; - if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { + if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) { ret = regmap_raw_read(map, reg, val, val_bytes * val_count); if (ret != 0) return ret; --- linux-oracle-5.4.0.orig/drivers/base/soc.c +++ linux-oracle-5.4.0/drivers/base/soc.c @@ -76,15 +76,15 @@ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); if (attr == &dev_attr_machine) - return sprintf(buf, "%s\n", soc_dev->attr->machine); + return sysfs_emit(buf, "%s\n", soc_dev->attr->machine); if (attr == &dev_attr_family) - return sprintf(buf, "%s\n", soc_dev->attr->family); + return sysfs_emit(buf, "%s\n", soc_dev->attr->family); if (attr == &dev_attr_revision) - return sprintf(buf, "%s\n", soc_dev->attr->revision); + return sysfs_emit(buf, "%s\n", soc_dev->attr->revision); if (attr == &dev_attr_serial_number) - return sprintf(buf, "%s\n", soc_dev->attr->serial_number); + return sysfs_emit(buf, "%s\n", soc_dev->attr->serial_number); if (attr == &dev_attr_soc_id) - return sprintf(buf, "%s\n", soc_dev->attr->soc_id); + return sysfs_emit(buf, "%s\n", soc_dev->attr->soc_id); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/base/swnode.c +++ linux-oracle-5.4.0/drivers/base/swnode.c @@ -520,7 +520,10 @@ { struct swnode *swnode = to_swnode(fwnode); - return swnode ? (swnode->parent ? &swnode->parent->fwnode : NULL) : NULL; + if (!swnode || !swnode->parent) + return NULL; + + return fwnode_handle_get(&swnode->parent->fwnode); } static struct fwnode_handle * @@ -531,14 +534,18 @@ struct swnode *c = to_swnode(child); if (!p || list_empty(&p->children) || - (c && list_is_last(&c->entry, &p->children))) + (c && list_is_last(&c->entry, &p->children))) { + fwnode_handle_put(child); return NULL; + } if (c) c = list_next_entry(c, entry); else c = list_first_entry(&p->children, struct swnode, entry); - return &c->fwnode; + + fwnode_handle_put(child); + return fwnode_handle_get(&c->fwnode); } static struct fwnode_handle * @@ -597,6 +604,9 @@ if (nargs > NR_FWNODE_REFERENCE_ARGS) return -EINVAL; + if (!args) + return 0; + args->fwnode = software_node_get(refnode); args->nargs = nargs; @@ -676,6 +686,13 @@ { struct swnode *swnode = kobj_to_swnode(kobj); + if (swnode->parent) { + ida_simple_remove(&swnode->parent->child_ids, swnode->id); + list_del(&swnode->entry); + } else { + ida_simple_remove(&swnode_root_ids, swnode->id); + } + if (swnode->allocated) { property_entries_free(swnode->node->properties); kfree(swnode->node); @@ -798,6 +815,9 @@ if (software_node_to_swnode(node)) return -EEXIST; + if (node->parent && !parent) + return -EINVAL; + return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); } EXPORT_SYMBOL_GPL(software_node_register); @@ -841,13 +861,6 @@ if (!swnode) return; - if (swnode->parent) { - ida_simple_remove(&swnode->parent->child_ids, swnode->id); - list_del(&swnode->entry); - } else { - ida_simple_remove(&swnode_root_ids, swnode->id); - } - kobject_put(&swnode->kobj); } EXPORT_SYMBOL_GPL(fwnode_remove_software_node); --- linux-oracle-5.4.0.orig/drivers/base/test/test_async_driver_probe.c +++ linux-oracle-5.4.0/drivers/base/test/test_async_driver_probe.c @@ -44,7 +44,8 @@ * performing an async init on that node. */ if (dev->driver->probe_type == PROBE_PREFER_ASYNCHRONOUS) { - if (dev_to_node(dev) != numa_node_id()) { + if (IS_ENABLED(CONFIG_NUMA) && + dev_to_node(dev) != numa_node_id()) { dev_warn(dev, "NUMA node mismatch %d != %d\n", dev_to_node(dev), numa_node_id()); atomic_inc(&warnings); @@ -83,7 +84,7 @@ pdev = platform_device_alloc(name, id); if (!pdev) - return NULL; + return ERR_PTR(-ENOMEM); if (nid != NUMA_NO_NODE) set_dev_node(&pdev->dev, nid); @@ -145,7 +146,7 @@ calltime = ktime_get(); for_each_online_cpu(cpu) { nid = cpu_to_node(cpu); - pdev = &sync_dev[sync_id]; + pdev = &async_dev[async_id]; *pdev = test_platform_device_register_node("test_async_driver", async_id, --- linux-oracle-5.4.0.orig/drivers/bcma/main.c +++ linux-oracle-5.4.0/drivers/bcma/main.c @@ -236,6 +236,7 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) { + device_initialize(&core->dev); core->dev.release = bcma_release_core_dev; core->dev.bus = &bcma_bus_type; dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); @@ -277,11 +278,10 @@ { int err; - err = device_register(&core->dev); + err = device_add(&core->dev); if (err) { bcma_err(bus, "Could not register dev for core 0x%03X\n", core->id.id); - put_device(&core->dev); return; } core->dev_registered = true; @@ -372,7 +372,7 @@ /* Now noone uses internally-handled cores, we can free them */ list_for_each_entry_safe(core, tmp, &bus->cores, list) { list_del(&core->list); - kfree(core); + put_device(&core->dev); } } --- linux-oracle-5.4.0.orig/drivers/block/Kconfig +++ linux-oracle-5.4.0/drivers/block/Kconfig @@ -39,6 +39,22 @@ To compile this driver as a module, choose M here: the module will be called floppy. +config BLK_DEV_FD_RAWCMD + bool "Support for raw floppy disk commands (DEPRECATED)" + depends on BLK_DEV_FD + help + If you want to use actual physical floppies and expect to do + special low-level hardware accesses to them (access and use + non-standard formats, for example), then enable this. + + Note that the code enabled by this option is rarely used and + might be unstable or insecure, and distros should not enable it. + + Note: FDRAWCMD is deprecated and will be removed from the kernel + in the near future. + + If unsure, say N. + config AMIGA_FLOPPY tristate "Amiga floppy support" depends on AMIGA @@ -230,7 +246,7 @@ dynamically allocated with the /dev/loop-control interface. config BLK_DEV_CRYPTOLOOP - tristate "Cryptoloop Support" + tristate "Cryptoloop Support (DEPRECATED)" select CRYPTO select CRYPTO_CBC depends on BLK_DEV_LOOP @@ -242,7 +258,7 @@ WARNING: This device is not safe for journaled file systems like ext3 or Reiserfs. Please use the Device Mapper crypto module instead, which can be configured to be on-disk compatible with the - cryptoloop device. + cryptoloop device. cryptoloop support will be removed in Linux 5.16. source "drivers/block/drbd/Kconfig" @@ -283,15 +299,6 @@ Use device /dev/skd$N amd /dev/skd$Np$M. -config BLK_DEV_SX8 - tristate "Promise SATA SX8 support" - depends on PCI - ---help--- - Saying Y or M here will enable support for the - Promise SATA SX8 controllers. - - Use devices /dev/sx8/$N and /dev/sx8/$Np$M. - config BLK_DEV_RAM tristate "RAM block device support" ---help--- @@ -461,6 +468,7 @@ config BLK_DEV_RSXX tristate "IBM Flash Adapter 900GB Full Height PCIe Device Driver" depends on PCI + select CRC32 help Device driver for IBM's high speed PCIe SSD storage device: Flash Adapter 900GB Full Height. --- linux-oracle-5.4.0.orig/drivers/block/Makefile +++ linux-oracle-5.4.0/drivers/block/Makefile @@ -26,8 +26,6 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o -obj-$(CONFIG_BLK_DEV_SX8) += sx8.o - obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o obj-$(CONFIG_XEN_BLKDEV_BACKEND) += xen-blkback/ obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ --- linux-oracle-5.4.0.orig/drivers/block/aoe/aoecmd.c +++ linux-oracle-5.4.0/drivers/block/aoe/aoecmd.c @@ -362,6 +362,7 @@ } ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit; + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; } @@ -402,6 +403,8 @@ __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); aoenet_xmit(&queue); + } else { + dev_put(f->t->ifp->nd); } return 1; } @@ -420,13 +423,16 @@ rcu_read_lock(); for_each_netdev_rcu(&init_net, ifp) { dev_hold(ifp); - if (!is_aoe_netif(ifp)) - goto cont; + if (!is_aoe_netif(ifp)) { + dev_put(ifp); + continue; + } skb = new_skb(sizeof *h + sizeof *ch); if (skb == NULL) { printk(KERN_INFO "aoe: skb alloc failure\n"); - goto cont; + dev_put(ifp); + continue; } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; @@ -441,9 +447,6 @@ h->major = cpu_to_be16(aoemajor); h->minor = aoeminor; h->cmd = AOECMD_CFG; - -cont: - dev_put(ifp); } rcu_read_unlock(); } @@ -484,10 +487,13 @@ memcpy(h->dst, t->addr, sizeof h->dst); memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src); + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; skb = skb_clone(skb, GFP_ATOMIC); - if (skb == NULL) + if (skb == NULL) { + dev_put(t->ifp->nd); return; + } f->sent = ktime_get(); __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); @@ -618,6 +624,8 @@ __skb_queue_head_init(&queue); __skb_queue_tail(&queue, skb); aoenet_xmit(&queue); + } else { + dev_put(f->t->ifp->nd); } } @@ -1405,6 +1413,7 @@ ah->cmdstat = ATA_CMD_ID_ATA; ah->lba3 = 0xa0; + dev_hold(t->ifp->nd); skb->dev = t->ifp->nd; d->rttavg = RTTAVG_INIT; @@ -1414,6 +1423,8 @@ skb = skb_clone(skb, GFP_ATOMIC); if (skb) f->sent = ktime_get(); + else + dev_put(t->ifp->nd); return skb; } --- linux-oracle-5.4.0.orig/drivers/block/aoe/aoenet.c +++ linux-oracle-5.4.0/drivers/block/aoe/aoenet.c @@ -64,6 +64,7 @@ pr_warn("aoe: packet could not be sent on %s. %s\n", ifp ? ifp->name : "netif", "consider increasing tx_queue_len"); + dev_put(ifp); spin_lock_irq(&txlock); } return 0; --- linux-oracle-5.4.0.orig/drivers/block/ataflop.c +++ linux-oracle-5.4.0/drivers/block/ataflop.c @@ -653,9 +653,6 @@ *p2++ = *p1++; } - - - /* General Interrupt Handling */ static void (*FloppyIRQHandler)( int status ) = NULL; @@ -1225,6 +1222,7 @@ } else { /* all sectors finished */ + finish_fdc(); fd_end_request_cur(BLK_STS_OK); } return; @@ -1472,15 +1470,6 @@ ReqTrack, ReqSector, (unsigned long)ReqData )); } -static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx) -{ - spin_lock_irq(&ataflop_lock); - atari_disable_irq(IRQ_MFP_FDC); - finish_fdc(); - atari_enable_irq(IRQ_MFP_FDC); - spin_unlock_irq(&ataflop_lock); -} - static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1488,6 +1477,8 @@ int drive = floppy - unit; int type = floppy->type; + DPRINT(("Queue request: drive %d type %d last %d\n", drive, type, bd->last)); + spin_lock_irq(&ataflop_lock); if (fd_request) { spin_unlock_irq(&ataflop_lock); @@ -1547,8 +1538,6 @@ setup_req_params( drive ); do_fd_action( drive ); - if (bd->last) - finish_fdc(); atari_enable_irq( IRQ_MFP_FDC ); out: @@ -1958,7 +1947,6 @@ static const struct blk_mq_ops ataflop_mq_ops = { .queue_rq = ataflop_queue_rq, - .commit_rqs = ataflop_commit_rqs, }; static struct kobject *floppy_find(dev_t dev, int *part, void *data) --- linux-oracle-5.4.0.orig/drivers/block/brd.c +++ linux-oracle-5.4.0/drivers/block/brd.c @@ -470,6 +470,25 @@ return kobj; } +static inline void brd_check_and_reset_par(void) +{ + if (unlikely(!max_part)) + max_part = 1; + + /* + * make sure 'max_part' can be divided exactly by (1U << MINORBITS), + * otherwise, it is possiable to get same dev_t when adding partitions. + */ + if ((1U << MINORBITS) % max_part != 0) + max_part = 1UL << fls(max_part); + + if (max_part > DISK_MAX_PARTS) { + pr_info("brd: max_part can't be larger than %d, reset max_part = %d.\n", + DISK_MAX_PARTS, DISK_MAX_PARTS); + max_part = DISK_MAX_PARTS; + } +} + static int __init brd_init(void) { struct brd_device *brd, *next; @@ -493,8 +512,7 @@ if (register_blkdev(RAMDISK_MAJOR, "ramdisk")) return -EIO; - if (unlikely(!max_part)) - max_part = 1; + brd_check_and_reset_par(); for (i = 0; i < rd_nr; i++) { brd = brd_alloc(i); --- linux-oracle-5.4.0.orig/drivers/block/cryptoloop.c +++ linux-oracle-5.4.0/drivers/block/cryptoloop.c @@ -189,6 +189,8 @@ if (rc) printk(KERN_ERR "cryptoloop: loop_register_transfer failed\n"); + else + pr_warn("the cryptoloop driver has been deprecated and will be removed in in Linux 5.16\n"); return rc; } --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_int.h +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_int.h @@ -1673,22 +1673,22 @@ }; void drbd_bcast_event(struct drbd_device *device, const struct sib_info *sib); -extern void notify_resource_state(struct sk_buff *, +extern int notify_resource_state(struct sk_buff *, unsigned int, struct drbd_resource *, struct resource_info *, enum drbd_notification_type); -extern void notify_device_state(struct sk_buff *, +extern int notify_device_state(struct sk_buff *, unsigned int, struct drbd_device *, struct device_info *, enum drbd_notification_type); -extern void notify_connection_state(struct sk_buff *, +extern int notify_connection_state(struct sk_buff *, unsigned int, struct drbd_connection *, struct connection_info *, enum drbd_notification_type); -extern void notify_peer_device_state(struct sk_buff *, +extern int notify_peer_device_state(struct sk_buff *, unsigned int, struct drbd_peer_device *, struct peer_device_info *, --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_main.c +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_main.c @@ -183,7 +183,7 @@ unsigned int set_size) { struct drbd_request *r; - struct drbd_request *req = NULL; + struct drbd_request *req = NULL, *tmp = NULL; int expect_epoch = 0; int expect_size = 0; @@ -237,8 +237,11 @@ * to catch requests being barrier-acked "unexpectedly". * It usually should find the same req again, or some READ preceding it. */ list_for_each_entry(req, &connection->transfer_log, tl_requests) - if (req->epoch == expect_epoch) + if (req->epoch == expect_epoch) { + tmp = req; break; + } + req = list_prepare_entry(tmp, &connection->transfer_log, tl_requests); list_for_each_entry_safe_from(req, r, &connection->transfer_log, tl_requests) { if (req->epoch != expect_epoch) break; @@ -2775,7 +2778,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor) { struct drbd_resource *resource = adm_ctx->resource; - struct drbd_connection *connection; + struct drbd_connection *connection, *n; struct drbd_device *device; struct drbd_peer_device *peer_device, *tmp_peer_device; struct gendisk *disk; @@ -2903,7 +2906,7 @@ out_idr_remove_vol: idr_remove(&connection->peer_devices, vnr); out_idr_remove_from_resource: - for_each_connection(connection, resource) { + for_each_connection_safe(connection, n, resource) { peer_device = idr_remove(&connection->peer_devices, vnr); if (peer_device) kref_put(&connection->kref, drbd_destroy_connection); @@ -3506,10 +3509,12 @@ void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local) { unsigned long flags; - if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) + spin_lock_irqsave(&device->ldev->md.uuid_lock, flags); + if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) { + spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags); return; + } - spin_lock_irqsave(&device->ldev->md.uuid_lock, flags); if (val == 0) { drbd_uuid_move_history(device); device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP]; @@ -3706,9 +3711,8 @@ * when we want to support more than * one PRO_VERSION */ static const char *cmdnames[] = { + [P_DATA] = "Data", - [P_WSAME] = "WriteSame", - [P_TRIM] = "Trim", [P_DATA_REPLY] = "DataReply", [P_RS_DATA_REPLY] = "RSDataReply", [P_BARRIER] = "Barrier", @@ -3719,7 +3723,6 @@ [P_DATA_REQUEST] = "DataRequest", [P_RS_DATA_REQUEST] = "RSDataRequest", [P_SYNC_PARAM] = "SyncParam", - [P_SYNC_PARAM89] = "SyncParam89", [P_PROTOCOL] = "ReportProtocol", [P_UUIDS] = "ReportUUIDs", [P_SIZES] = "ReportSizes", @@ -3727,6 +3730,7 @@ [P_SYNC_UUID] = "ReportSyncUUID", [P_AUTH_CHALLENGE] = "AuthChallenge", [P_AUTH_RESPONSE] = "AuthResponse", + [P_STATE_CHG_REQ] = "StateChgRequest", [P_PING] = "Ping", [P_PING_ACK] = "PingAck", [P_RECV_ACK] = "RecvAck", @@ -3737,24 +3741,26 @@ [P_NEG_DREPLY] = "NegDReply", [P_NEG_RS_DREPLY] = "NegRSDReply", [P_BARRIER_ACK] = "BarrierAck", - [P_STATE_CHG_REQ] = "StateChgRequest", [P_STATE_CHG_REPLY] = "StateChgReply", [P_OV_REQUEST] = "OVRequest", [P_OV_REPLY] = "OVReply", [P_OV_RESULT] = "OVResult", [P_CSUM_RS_REQUEST] = "CsumRSRequest", [P_RS_IS_IN_SYNC] = "CsumRSIsInSync", + [P_SYNC_PARAM89] = "SyncParam89", [P_COMPRESSED_BITMAP] = "CBitmap", [P_DELAY_PROBE] = "DelayProbe", [P_OUT_OF_SYNC] = "OutOfSync", - [P_RETRY_WRITE] = "RetryWrite", [P_RS_CANCEL] = "RSCancel", [P_CONN_ST_CHG_REQ] = "conn_st_chg_req", [P_CONN_ST_CHG_REPLY] = "conn_st_chg_reply", [P_RETRY_WRITE] = "retry_write", [P_PROTOCOL_UPDATE] = "protocol_update", + [P_TRIM] = "Trim", [P_RS_THIN_REQ] = "rs_thin_req", [P_RS_DEALLOCATED] = "rs_deallocated", + [P_WSAME] = "WriteSame", + [P_ZEROES] = "Zeroes", /* enum drbd_packet, but not commands - obsoleted flags: * P_MAY_IGNORE --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_nl.c +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_nl.c @@ -791,9 +791,11 @@ mutex_lock(&adm_ctx.resource->adm_mutex); if (info->genlhdr->cmd == DRBD_ADM_PRIMARY) - retcode = drbd_set_role(adm_ctx.device, R_PRIMARY, parms.assume_uptodate); + retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device, + R_PRIMARY, parms.assume_uptodate); else - retcode = drbd_set_role(adm_ctx.device, R_SECONDARY, 0); + retcode = (enum drbd_ret_code)drbd_set_role(adm_ctx.device, + R_SECONDARY, 0); mutex_unlock(&adm_ctx.resource->adm_mutex); genl_lock(); @@ -1971,7 +1973,7 @@ drbd_flush_workqueue(&connection->sender_work); rv = _drbd_request_state(device, NS(disk, D_ATTACHING), CS_VERBOSE); - retcode = rv; /* FIXME: Type mismatch. */ + retcode = (enum drbd_ret_code)rv; drbd_resume_io(device); if (rv < SS_SUCCESS) goto fail; @@ -2696,7 +2698,8 @@ } rcu_read_unlock(); - retcode = conn_request_state(connection, NS(conn, C_UNCONNECTED), CS_VERBOSE); + retcode = (enum drbd_ret_code)conn_request_state(connection, + NS(conn, C_UNCONNECTED), CS_VERBOSE); conn_reconfig_done(connection); mutex_unlock(&adm_ctx.resource->adm_mutex); @@ -2809,7 +2812,7 @@ mutex_lock(&adm_ctx.resource->adm_mutex); rv = conn_try_disconnect(connection, parms.force_disconnect); if (rv < SS_SUCCESS) - retcode = rv; /* FIXME: Type mismatch. */ + retcode = (enum drbd_ret_code)rv; else retcode = NO_ERROR; mutex_unlock(&adm_ctx.resource->adm_mutex); @@ -3423,7 +3426,7 @@ { struct nlattr *resource_filter; struct drbd_resource *resource; - struct drbd_device *uninitialized_var(device); + struct drbd_device *device; int minor, err, retcode; struct drbd_genlmsghdr *dh; struct device_info device_info; @@ -3512,7 +3515,7 @@ { struct nlattr *resource_filter; struct drbd_resource *resource = NULL, *next_resource; - struct drbd_connection *uninitialized_var(connection); + struct drbd_connection *connection; int err = 0, retcode; struct drbd_genlmsghdr *dh; struct connection_info connection_info; @@ -3674,7 +3677,7 @@ { struct nlattr *resource_filter; struct drbd_resource *resource; - struct drbd_device *uninitialized_var(device); + struct drbd_device *device; struct drbd_peer_device *peer_device = NULL; int minor, err, retcode; struct drbd_genlmsghdr *dh; @@ -4630,7 +4633,7 @@ return drbd_notification_header_to_skb(msg, &nh, true); } -void notify_resource_state(struct sk_buff *skb, +int notify_resource_state(struct sk_buff *skb, unsigned int seq, struct drbd_resource *resource, struct resource_info *resource_info, @@ -4672,16 +4675,17 @@ if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(resource, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_device_state(struct sk_buff *skb, +int notify_device_state(struct sk_buff *skb, unsigned int seq, struct drbd_device *device, struct device_info *device_info, @@ -4721,16 +4725,17 @@ if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(device, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_connection_state(struct sk_buff *skb, +int notify_connection_state(struct sk_buff *skb, unsigned int seq, struct drbd_connection *connection, struct connection_info *connection_info, @@ -4770,16 +4775,17 @@ if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(connection, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } -void notify_peer_device_state(struct sk_buff *skb, +int notify_peer_device_state(struct sk_buff *skb, unsigned int seq, struct drbd_peer_device *peer_device, struct peer_device_info *peer_device_info, @@ -4820,13 +4826,14 @@ if (err && err != -ESRCH) goto failed; } - return; + return 0; nla_put_failure: nlmsg_free(skb); failed: drbd_err(peer_device, "Error %d while broadcasting event. Event seq:%u\n", err, seq); + return err; } void notify_helper(enum drbd_notification_type type, @@ -4877,7 +4884,7 @@ err, seq); } -static void notify_initial_state_done(struct sk_buff *skb, unsigned int seq) +static int notify_initial_state_done(struct sk_buff *skb, unsigned int seq) { struct drbd_genlmsghdr *dh; int err; @@ -4891,11 +4898,12 @@ if (nla_put_notification_header(skb, NOTIFY_EXISTS)) goto nla_put_failure; genlmsg_end(skb, dh); - return; + return 0; nla_put_failure: nlmsg_free(skb); pr_err("Error %d sending event. Event seq:%u\n", err, seq); + return err; } static void free_state_changes(struct list_head *list) @@ -4922,6 +4930,7 @@ unsigned int seq = cb->args[2]; unsigned int n; enum drbd_notification_type flags = 0; + int err = 0; /* There is no need for taking notification_mutex here: it doesn't matter if the initial state events mix with later state chage @@ -4930,32 +4939,32 @@ cb->args[5]--; if (cb->args[5] == 1) { - notify_initial_state_done(skb, seq); + err = notify_initial_state_done(skb, seq); goto out; } n = cb->args[4]++; if (cb->args[4] < cb->args[3]) flags |= NOTIFY_CONTINUES; if (n < 1) { - notify_resource_state_change(skb, seq, state_change->resource, + err = notify_resource_state_change(skb, seq, state_change->resource, NOTIFY_EXISTS | flags); goto next; } n--; if (n < state_change->n_connections) { - notify_connection_state_change(skb, seq, &state_change->connections[n], + err = notify_connection_state_change(skb, seq, &state_change->connections[n], NOTIFY_EXISTS | flags); goto next; } n -= state_change->n_connections; if (n < state_change->n_devices) { - notify_device_state_change(skb, seq, &state_change->devices[n], + err = notify_device_state_change(skb, seq, &state_change->devices[n], NOTIFY_EXISTS | flags); goto next; } n -= state_change->n_devices; if (n < state_change->n_devices * state_change->n_connections) { - notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], + err = notify_peer_device_state_change(skb, seq, &state_change->peer_devices[n], NOTIFY_EXISTS | flags); goto next; } @@ -4970,7 +4979,10 @@ cb->args[4] = 0; } out: - return skb->len; + if (err) + return err; + else + return skb->len; } int drbd_adm_get_initial_state(struct sk_buff *skb, struct netlink_callback *cb) --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_receiver.c +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_receiver.c @@ -1298,7 +1298,7 @@ bio_set_dev(bio, device->ldev->backing_bdev); bio->bi_private = octx; bio->bi_end_io = one_flush_endio; - bio->bi_opf = REQ_OP_FLUSH | REQ_PREFLUSH; + bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; device->flush_jif = jiffies; set_bit(FLUSH_PENDING, &device->flags); --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_req.c +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_req.c @@ -195,7 +195,8 @@ void complete_master_bio(struct drbd_device *device, struct bio_and_error *m) { - m->bio->bi_status = errno_to_blk_status(m->error); + if (unlikely(m->error)) + m->bio->bi_status = errno_to_blk_status(m->error); bio_endio(m->bio); dec_ap_bio(device); } --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_state.c +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_state.c @@ -876,7 +876,7 @@ ns.disk == D_OUTDATED) rv = SS_CONNECTED_OUTDATES; - else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && + else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) && (nc->verify_alg[0] == 0)) rv = SS_NO_VERIFY_ALG; @@ -1537,7 +1537,7 @@ return rv; } -void notify_resource_state_change(struct sk_buff *skb, +int notify_resource_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_resource_state_change *resource_state_change, enum drbd_notification_type type) @@ -1550,10 +1550,10 @@ .res_susp_fen = resource_state_change->susp_fen[NEW], }; - notify_resource_state(skb, seq, resource, &resource_info, type); + return notify_resource_state(skb, seq, resource, &resource_info, type); } -void notify_connection_state_change(struct sk_buff *skb, +int notify_connection_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_connection_state_change *connection_state_change, enum drbd_notification_type type) @@ -1564,10 +1564,10 @@ .conn_role = connection_state_change->peer_role[NEW], }; - notify_connection_state(skb, seq, connection, &connection_info, type); + return notify_connection_state(skb, seq, connection, &connection_info, type); } -void notify_device_state_change(struct sk_buff *skb, +int notify_device_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_device_state_change *device_state_change, enum drbd_notification_type type) @@ -1577,10 +1577,10 @@ .dev_disk_state = device_state_change->disk_state[NEW], }; - notify_device_state(skb, seq, device, &device_info, type); + return notify_device_state(skb, seq, device, &device_info, type); } -void notify_peer_device_state_change(struct sk_buff *skb, +int notify_peer_device_state_change(struct sk_buff *skb, unsigned int seq, struct drbd_peer_device_state_change *p, enum drbd_notification_type type) @@ -1594,7 +1594,7 @@ .peer_resync_susp_dependency = p->resync_susp_dependency[NEW], }; - notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type); + return notify_peer_device_state(skb, seq, peer_device, &peer_device_info, type); } static void broadcast_state_change(struct drbd_state_change *state_change) @@ -1602,7 +1602,7 @@ struct drbd_resource_state_change *resource_state_change = &state_change->resource[0]; bool resource_state_has_changed; unsigned int n_device, n_connection, n_peer_device, n_peer_devices; - void (*last_func)(struct sk_buff *, unsigned int, void *, + int (*last_func)(struct sk_buff *, unsigned int, void *, enum drbd_notification_type) = NULL; void *uninitialized_var(last_arg); --- linux-oracle-5.4.0.orig/drivers/block/drbd/drbd_state_change.h +++ linux-oracle-5.4.0/drivers/block/drbd/drbd_state_change.h @@ -44,19 +44,19 @@ extern void copy_old_to_new_state_change(struct drbd_state_change *); extern void forget_state_change(struct drbd_state_change *); -extern void notify_resource_state_change(struct sk_buff *, +extern int notify_resource_state_change(struct sk_buff *, unsigned int, struct drbd_resource_state_change *, enum drbd_notification_type type); -extern void notify_connection_state_change(struct sk_buff *, +extern int notify_connection_state_change(struct sk_buff *, unsigned int, struct drbd_connection_state_change *, enum drbd_notification_type type); -extern void notify_device_state_change(struct sk_buff *, +extern int notify_device_state_change(struct sk_buff *, unsigned int, struct drbd_device_state_change *, enum drbd_notification_type type); -extern void notify_peer_device_state_change(struct sk_buff *, +extern int notify_peer_device_state_change(struct sk_buff *, unsigned int, struct drbd_peer_device_state_change *, enum drbd_notification_type type); --- linux-oracle-5.4.0.orig/drivers/block/floppy.c +++ linux-oracle-5.4.0/drivers/block/floppy.c @@ -521,8 +521,8 @@ static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); static DECLARE_WAIT_QUEUE_HEAD(command_done); -/* Errors during formatting are counted here. */ -static int format_errors; +/* errors encountered on the current (or last) request */ +static int floppy_errors; /* Format request descriptor. */ static struct format_descr format_req; @@ -542,7 +542,6 @@ static char *floppy_track_buffer; static int max_buffer_sectors; -static int *errors; typedef void (*done_f)(int); static const struct cont_t { void (*interrupt)(void); @@ -853,14 +852,17 @@ /* selects the fdc and drive, and enables the fdc's input/dma. */ static void set_fdc(int drive) { + unsigned int new_fdc = fdc; + if (drive >= 0 && drive < N_DRIVE) { - fdc = FDC(drive); + new_fdc = FDC(drive); current_drive = drive; } - if (fdc != 1 && fdc != 0) { + if (new_fdc >= N_FDC) { pr_info("bad fdc value\n"); return; } + fdc = new_fdc; set_dor(fdc, ~0, 8); #if N_FDC > 1 set_dor(1 - fdc, ~8, 0); @@ -1000,7 +1002,7 @@ static void cancel_activity(void) { do_floppy = NULL; - cancel_delayed_work_sync(&fd_timer); + cancel_delayed_work(&fd_timer); cancel_work_sync(&floppy_work); } @@ -1432,7 +1434,7 @@ if (DP->flags & FTD_MSG) DPRINT("Over/Underrun - retrying\n"); bad = 0; - } else if (*errors >= DP->max_errors.reporting) { + } else if (floppy_errors >= DP->max_errors.reporting) { print_errors(); } if (ST2 & ST2_WC || ST2 & ST2_BC) @@ -2052,7 +2054,7 @@ if (!next_valid_format()) return; } - err_count = ++(*errors); + err_count = ++floppy_errors; INFBOUND(DRWE->badness, err_count); if (err_count > DP->max_errors.abort) cont->done(0); @@ -2197,9 +2199,8 @@ return -EINVAL; } format_req = *tmp_format_req; - format_errors = 0; cont = &format_cont; - errors = &format_errors; + floppy_errors = 0; ret = wait_til_done(redo_format, true); if (ret == -EINTR) return -EINTR; @@ -2674,7 +2675,7 @@ */ if (!direct || (indirect * 2 > direct * 3 && - *errors < DP->max_errors.read_track && + floppy_errors < DP->max_errors.read_track && ((!probing || (DP->read_track & (1 << DRS->probed_format)))))) { max_size = blk_rq_sectors(current_req); @@ -2798,10 +2799,11 @@ current_req = list_first_entry_or_null(&floppy_reqs, struct request, queuelist); if (current_req) { - current_req->error_count = 0; + floppy_errors = 0; list_del_init(¤t_req->queuelist); + return 1; } - return current_req != NULL; + return 0; } static void redo_fd_request(void) @@ -2857,7 +2859,6 @@ _floppy = floppy_type + DP->autodetect[DRS->probed_format]; } else probing = 0; - errors = &(current_req->error_count); tmp = make_raw_rw_request(); if (tmp < 2) { request_done(tmp); @@ -2899,17 +2900,17 @@ (unsigned long long) current_req->cmd_flags)) return BLK_STS_IOERR; - spin_lock_irq(&floppy_lock); - list_add_tail(&bd->rq->queuelist, &floppy_reqs); - spin_unlock_irq(&floppy_lock); - if (test_and_set_bit(0, &fdc_busy)) { /* fdc busy, this new request will be treated when the current one is done */ is_alive(__func__, "old request running"); - return BLK_STS_OK; + return BLK_STS_RESOURCE; } + spin_lock_irq(&floppy_lock); + list_add_tail(&bd->rq->queuelist, &floppy_reqs); + spin_unlock_irq(&floppy_lock); + command_status = FD_COMMAND_NONE; __reschedule_timeout(MAXTIMEOUT, "fd_request"); set_fdc(0); @@ -3009,6 +3010,8 @@ return "(null)"; } +#ifdef CONFIG_BLK_DEV_FD_RAWCMD + /* raw commands */ static void raw_cmd_done(int flag) { @@ -3109,6 +3112,8 @@ } } +#define MAX_LEN (1UL << MAX_ORDER << PAGE_SHIFT) + static int raw_cmd_copyin(int cmd, void __user *param, struct floppy_raw_cmd **rcmd) { @@ -3146,7 +3151,7 @@ ptr->resultcode = 0; if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { - if (ptr->length <= 0) + if (ptr->length <= 0 || ptr->length >= MAX_LEN) return -EINVAL; ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); @@ -3218,6 +3223,35 @@ return ret; } +static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, + void __user *param) +{ + int ret; + + pr_warn_once("Note: FDRAWCMD is deprecated and will be removed from the kernel in the near future.\n"); + + if (type) + return -EINVAL; + if (lock_fdc(drive)) + return -EINTR; + set_floppy(drive); + ret = raw_cmd_ioctl(cmd, param); + if (ret == -EINTR) + return -EINTR; + process_fd_request(); + return ret; +} + +#else /* CONFIG_BLK_DEV_FD_RAWCMD */ + +static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, + void __user *param) +{ + return -EOPNOTSUPP; +} + +#endif + static int invalidate_drive(struct block_device *bdev) { /* invalidate the buffer track to force a reread */ @@ -3405,7 +3439,6 @@ { int drive = (long)bdev->bd_disk->private_data; int type = ITYPE(UDRS->fd_device); - int i; int ret; int size; union inparam { @@ -3556,16 +3589,7 @@ outparam = UDRWE; break; case FDRAWCMD: - if (type) - return -EINVAL; - if (lock_fdc(drive)) - return -EINTR; - set_floppy(drive); - i = raw_cmd_ioctl(cmd, (void __user *)param); - if (i == -EINTR) - return -EINTR; - process_fd_request(); - return i; + return floppy_raw_cmd_ioctl(type, drive, cmd, (void __user *)param); case FDTWADDLE: if (lock_fdc(drive)) return -EINTR; --- linux-oracle-5.4.0.orig/drivers/block/loop.c +++ linux-oracle-5.4.0/drivers/block/loop.c @@ -226,24 +226,30 @@ blk_mq_unfreeze_queue(lo->lo_queue); } -static int -figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) +/** + * loop_set_size() - sets device size and notifies userspace + * @lo: struct loop_device to set the size for + * @size: new size of the loop device + * + * Callers must validate that the size passed into this function fits into + * a sector_t, eg using loop_validate_size() + */ +static void loop_set_size(struct loop_device *lo, loff_t size) { - loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); - sector_t x = (sector_t)size; struct block_device *bdev = lo->lo_device; - if (unlikely((loff_t)x != size)) - return -EFBIG; - if (lo->lo_offset != offset) - lo->lo_offset = offset; - if (lo->lo_sizelimit != sizelimit) - lo->lo_sizelimit = sizelimit; - set_capacity(lo->lo_disk, x); - bd_set_size(bdev, (loff_t)get_capacity(bdev->bd_disk) << 9); + set_capacity(lo->lo_disk, size); + bd_set_size(bdev, size << SECTOR_SHIFT); /* let user-space know about the new size */ kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - return 0; +} + +static void +figure_loop_size(struct loop_device *lo, loff_t offset, loff_t sizelimit) +{ + loff_t size = get_size(offset, sizelimit, lo->lo_backing_file); + + loop_set_size(lo, size); } static inline int @@ -417,19 +423,22 @@ return ret; } -static int lo_discard(struct loop_device *lo, struct request *rq, loff_t pos) +static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos, + int mode) { /* - * We use punch hole to reclaim the free space used by the - * image a.k.a. discard. However we do not support discard if - * encryption is enabled, because it may give an attacker - * useful information. + * We use fallocate to manipulate the space mappings used by the image + * a.k.a. discard/zerorange. However we do not support this if + * encryption is enabled, because it may give an attacker useful + * information. */ struct file *file = lo->lo_backing_file; - int mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE; + struct request_queue *q = lo->lo_queue; int ret; - if ((!file->f_op->fallocate) || lo->lo_encrypt_key_size) { + mode |= FALLOC_FL_KEEP_SIZE; + + if (!blk_queue_discard(q)) { ret = -EOPNOTSUPP; goto out; } @@ -494,7 +503,8 @@ return; kfree(cmd->bvec); cmd->bvec = NULL; - blk_mq_complete_request(rq); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); } static void lo_rw_aio_complete(struct kiocb *iocb, long ret, long ret2) @@ -596,9 +606,17 @@ switch (req_op(rq)) { case REQ_OP_FLUSH: return lo_req_flush(lo, rq); - case REQ_OP_DISCARD: case REQ_OP_WRITE_ZEROES: - return lo_discard(lo, rq, pos); + /* + * If the caller doesn't want deallocation, call zeroout to + * write zeroes the range. Otherwise, punch them out. + */ + return lo_fallocate(lo, rq, pos, + (rq->cmd_flags & REQ_NOUNMAP) ? + FALLOC_FL_ZERO_RANGE : + FALLOC_FL_PUNCH_HOLE); + case REQ_OP_DISCARD: + return lo_fallocate(lo, rq, pos, FALLOC_FL_PUNCH_HOLE); case REQ_OP_WRITE: if (lo->transfer) return lo_write_transfer(lo, rq, pos); @@ -625,6 +643,15 @@ lo->use_dio); } +static struct file *loop_real_file(struct file *file) +{ + struct file *f = NULL; + + if (file->f_path.dentry->d_sb->s_op->real_loop) + f = file->f_path.dentry->d_sb->s_op->real_loop(file); + return f; +} + static void loop_reread_partitions(struct loop_device *lo, struct block_device *bdev) { @@ -678,6 +705,7 @@ unsigned int arg) { struct file *file = NULL, *old_file; + struct file *f, *virt_file = NULL, *old_virt_file; int error; bool partscan; @@ -697,12 +725,19 @@ file = fget(arg); if (!file) goto out_err; + f = loop_real_file(file); + if (f) { + virt_file = file; + file = f; + get_file(file); + } error = loop_validate_file(file, bdev); if (error) goto out_err; old_file = lo->lo_backing_file; + old_virt_file = lo->lo_backing_virt_file; error = -EINVAL; @@ -714,6 +749,7 @@ blk_mq_freeze_queue(lo->lo_queue); mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; + lo->lo_backing_virt_file = virt_file; lo->old_gfp_mask = mapping_gfp_mask(file->f_mapping); mapping_set_gfp_mask(file->f_mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); @@ -727,6 +763,8 @@ * dependency. */ fput(old_file); + if (old_virt_file) + fput(old_virt_file); if (partscan) loop_reread_partitions(lo, bdev); return 0; @@ -735,9 +773,29 @@ mutex_unlock(&loop_ctl_mutex); if (file) fput(file); + if (virt_file) + fput(virt_file); return error; } +/* + * for AUFS + * no get/put for file. + */ +struct file *loop_backing_file(struct super_block *sb) +{ + struct file *ret; + struct loop_device *l; + + ret = NULL; + if (MAJOR(sb->s_dev) == LOOP_MAJOR) { + l = sb->s_bdev->bd_disk->private_data; + ret = l->lo_backing_file; + } + return ret; +} +EXPORT_SYMBOL_GPL(loop_backing_file); + /* loop sysfs attributes */ static ssize_t loop_attr_show(struct device *dev, char *page, @@ -783,33 +841,33 @@ static ssize_t loop_attr_offset_show(struct loop_device *lo, char *buf) { - return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_offset); + return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_offset); } static ssize_t loop_attr_sizelimit_show(struct loop_device *lo, char *buf) { - return sprintf(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit); + return sysfs_emit(buf, "%llu\n", (unsigned long long)lo->lo_sizelimit); } static ssize_t loop_attr_autoclear_show(struct loop_device *lo, char *buf) { int autoclear = (lo->lo_flags & LO_FLAGS_AUTOCLEAR); - return sprintf(buf, "%s\n", autoclear ? "1" : "0"); + return sysfs_emit(buf, "%s\n", autoclear ? "1" : "0"); } static ssize_t loop_attr_partscan_show(struct loop_device *lo, char *buf) { int partscan = (lo->lo_flags & LO_FLAGS_PARTSCAN); - return sprintf(buf, "%s\n", partscan ? "1" : "0"); + return sysfs_emit(buf, "%s\n", partscan ? "1" : "0"); } static ssize_t loop_attr_dio_show(struct loop_device *lo, char *buf) { int dio = (lo->lo_flags & LO_FLAGS_DIRECT_IO); - return sprintf(buf, "%s\n", dio ? "1" : "0"); + return sysfs_emit(buf, "%s\n", dio ? "1" : "0"); } LOOP_ATTR_RO(backing_file); @@ -852,6 +910,23 @@ struct file *file = lo->lo_backing_file; struct inode *inode = file->f_mapping->host; struct request_queue *q = lo->lo_queue; + u32 granularity, max_discard_sectors; + + /* + * If the backing device is a block device, mirror its zeroing + * capability. Set the discard sectors to the block device's zeroing + * capabilities because loop discards result in blkdev_issue_zeroout(), + * not blkdev_issue_discard(). This maintains consistent behavior with + * file-backed loop devices: discarded regions read back as zero. + */ + if (S_ISBLK(inode->i_mode) && !lo->lo_encrypt_key_size) { + struct request_queue *backingq; + + backingq = bdev_get_queue(inode->i_bdev); + + max_discard_sectors = backingq->limits.max_write_zeroes_sectors; + granularity = backingq->limits.discard_granularity ?: + queue_physical_block_size(backingq); /* * We use punch hole to reclaim the free space used by the @@ -859,22 +934,27 @@ * encryption is enabled, because it may give an attacker * useful information. */ - if ((!file->f_op->fallocate) || - lo->lo_encrypt_key_size) { + } else if (!file->f_op->fallocate || lo->lo_encrypt_key_size) { + max_discard_sectors = 0; + granularity = 0; + + } else { + max_discard_sectors = UINT_MAX >> 9; + granularity = inode->i_sb->s_blocksize; + } + + if (max_discard_sectors) { + q->limits.discard_granularity = granularity; + blk_queue_max_discard_sectors(q, max_discard_sectors); + blk_queue_max_write_zeroes_sectors(q, max_discard_sectors); + blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); + } else { q->limits.discard_granularity = 0; - q->limits.discard_alignment = 0; blk_queue_max_discard_sectors(q, 0); blk_queue_max_write_zeroes_sectors(q, 0); blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q); - return; } - - q->limits.discard_granularity = inode->i_sb->s_blocksize; q->limits.discard_alignment = 0; - - blk_queue_max_discard_sectors(q, UINT_MAX >> 9); - blk_queue_max_write_zeroes_sectors(q, UINT_MAX >> 9); - blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } static void loop_unprepare_queue(struct loop_device *lo) @@ -921,7 +1001,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { - struct file *file; + struct file *file, *f, *virt_file = NULL; struct inode *inode; struct address_space *mapping; struct block_device *claimed_bdev = NULL; @@ -937,6 +1017,12 @@ file = fget(arg); if (!file) goto out; + f = loop_real_file(file); + if (f) { + virt_file = file; + file = f; + get_file(file); + } /* * If we don't hold exclusive handle for the device, upgrade to it @@ -969,10 +1055,8 @@ !file->f_op->write_iter) lo_flags |= LO_FLAGS_READ_ONLY; - error = -EFBIG; size = get_loop_size(lo, file); - if ((loff_t)(sector_t)size != size) - goto out_unlock; + error = loop_prepare_queue(lo); if (error) goto out_unlock; @@ -985,6 +1069,7 @@ lo->lo_device = bdev; lo->lo_flags = lo_flags; lo->lo_backing_file = file; + lo->lo_backing_virt_file = virt_file; lo->transfer = NULL; lo->ioctl = NULL; lo->lo_sizelimit = 0; @@ -1006,11 +1091,8 @@ loop_update_rotational(lo); loop_update_dio(lo); - set_capacity(lo->lo_disk, size); - bd_set_size(bdev, size << 9); loop_sysfs_init(lo); - /* let user-space know about the new size */ - kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); + loop_set_size(lo, size); set_blocksize(bdev, S_ISBLK(inode->i_mode) ? block_size(inode->i_bdev) : PAGE_SIZE); @@ -1038,6 +1120,8 @@ bd_abort_claiming(bdev, claimed_bdev, loop_set_fd); out_putf: fput(file); + if (virt_file) + fput(virt_file); out: /* This is safe: open() is still holding a reference. */ module_put(THIS_MODULE); @@ -1084,6 +1168,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) { struct file *filp = NULL; + struct file *virt_filp = lo->lo_backing_virt_file; gfp_t gfp = lo->old_gfp_mask; struct block_device *bdev = lo->lo_device; int err = 0; @@ -1102,11 +1187,15 @@ goto out_unlock; } + if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags)) + blk_queue_write_cache(lo->lo_queue, false, false); + /* freeze request queue during the transition */ blk_mq_freeze_queue(lo->lo_queue); spin_lock_irq(&lo->lo_lock); lo->lo_backing_file = NULL; + lo->lo_backing_virt_file = NULL; spin_unlock_irq(&lo->lo_lock); loop_release_xfer(lo); @@ -1189,6 +1278,8 @@ */ if (filp) fput(filp); + if (virt_filp) + fput(virt_filp); return err; } @@ -1224,82 +1315,50 @@ return __loop_clr_fd(lo, false); } +/** + * loop_set_status_from_info - configure device from loop_info + * @lo: struct loop_device to configure + * @info: struct loop_info64 to configure the device with + * + * Configures the loop device parameters according to the passed + * in loop_info64 configuration. + */ static int -loop_set_status(struct loop_device *lo, const struct loop_info64 *info) +loop_set_status_from_info(struct loop_device *lo, + const struct loop_info64 *info) { int err; struct loop_func_table *xfer; kuid_t uid = current_uid(); - struct block_device *bdev; - bool partscan = false; - - err = mutex_lock_killable(&loop_ctl_mutex); - if (err) - return err; - if (lo->lo_encrypt_key_size && - !uid_eq(lo->lo_key_owner, uid) && - !capable(CAP_SYS_ADMIN)) { - err = -EPERM; - goto out_unlock; - } - if (lo->lo_state != Lo_bound) { - err = -ENXIO; - goto out_unlock; - } - if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) { - err = -EINVAL; - goto out_unlock; - } - if (lo->lo_offset != info->lo_offset || - lo->lo_sizelimit != info->lo_sizelimit) { - sync_blockdev(lo->lo_device); - kill_bdev(lo->lo_device); - } - - /* I/O need to be drained during transfer transition */ - blk_mq_freeze_queue(lo->lo_queue); + if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) + return -EINVAL; err = loop_release_xfer(lo); if (err) - goto out_unfreeze; + return err; if (info->lo_encrypt_type) { unsigned int type = info->lo_encrypt_type; - if (type >= MAX_LO_CRYPT) { - err = -EINVAL; - goto out_unfreeze; - } + if (type >= MAX_LO_CRYPT) + return -EINVAL; xfer = xfer_funcs[type]; - if (xfer == NULL) { - err = -EINVAL; - goto out_unfreeze; - } + if (xfer == NULL) + return -EINVAL; } else xfer = NULL; err = loop_init_xfer(lo, xfer, info); if (err) - goto out_unfreeze; + return err; - if (lo->lo_offset != info->lo_offset || - lo->lo_sizelimit != info->lo_sizelimit) { - /* kill_bdev should have truncated all the pages */ - if (lo->lo_device->bd_inode->i_mapping->nrpages) { - err = -EAGAIN; - pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", - __func__, lo->lo_number, lo->lo_file_name, - lo->lo_device->bd_inode->i_mapping->nrpages); - goto out_unfreeze; - } - if (figure_loop_size(lo, info->lo_offset, info->lo_sizelimit)) { - err = -EFBIG; - goto out_unfreeze; - } - } + /* Avoid assigning overflow values */ + if (info->lo_offset > LLONG_MAX || info->lo_sizelimit > LLONG_MAX) + return -EOVERFLOW; - loop_config_discard(lo); + lo->lo_offset = info->lo_offset; + lo->lo_sizelimit = info->lo_sizelimit; memcpy(lo->lo_file_name, info->lo_file_name, LO_NAME_SIZE); memcpy(lo->lo_crypt_name, info->lo_crypt_name, LO_NAME_SIZE); @@ -1324,6 +1383,63 @@ lo->lo_key_owner = uid; } + return 0; +} + +static int +loop_set_status(struct loop_device *lo, const struct loop_info64 *info) +{ + int err; + struct block_device *bdev; + kuid_t uid = current_uid(); + bool partscan = false; + bool size_changed = false; + + err = mutex_lock_killable(&loop_ctl_mutex); + if (err) + return err; + if (lo->lo_encrypt_key_size && + !uid_eq(lo->lo_key_owner, uid) && + !capable(CAP_SYS_ADMIN)) { + err = -EPERM; + goto out_unlock; + } + if (lo->lo_state != Lo_bound) { + err = -ENXIO; + goto out_unlock; + } + + if (lo->lo_offset != info->lo_offset || + lo->lo_sizelimit != info->lo_sizelimit) { + size_changed = true; + sync_blockdev(lo->lo_device); + invalidate_bdev(lo->lo_device); + } + + /* I/O need to be drained during transfer transition */ + blk_mq_freeze_queue(lo->lo_queue); + + if (size_changed && lo->lo_device->bd_inode->i_mapping->nrpages) { + /* If any pages were dirtied after invalidate_bdev(), try again */ + err = -EAGAIN; + pr_warn("%s: loop%d (%s) has still dirty pages (nrpages=%lu)\n", + __func__, lo->lo_number, lo->lo_file_name, + lo->lo_device->bd_inode->i_mapping->nrpages); + goto out_unfreeze; + } + + err = loop_set_status_from_info(lo, info); + if (err) + goto out_unfreeze; + + if (size_changed) { + loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit, + lo->lo_backing_file); + loop_set_size(lo, new_size); + } + + loop_config_discard(lo); + /* update dio if lo_offset or transfer is changed */ __loop_update_dio(lo, lo->use_dio); @@ -1499,7 +1615,9 @@ if (unlikely(lo->lo_state != Lo_bound)) return -ENXIO; - return figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); + figure_loop_size(lo, lo->lo_offset, lo->lo_sizelimit); + + return 0; } static int loop_set_dio(struct loop_device *lo, unsigned long arg) @@ -1528,12 +1646,12 @@ if (lo->lo_queue->limits.logical_block_size != arg) { sync_blockdev(lo->lo_device); - kill_bdev(lo->lo_device); + invalidate_bdev(lo->lo_device); } blk_mq_freeze_queue(lo->lo_queue); - /* kill_bdev should have truncated all the pages */ + /* invalidate_bdev should have truncated all the pages */ if (lo->lo_queue->limits.logical_block_size != arg && lo->lo_device->bd_inode->i_mapping->nrpages) { err = -EAGAIN; @@ -1941,7 +2059,8 @@ /* complete non-aio request */ if (!cmd->use_aio || ret) { cmd->ret = ret ? -EIO : 0; - blk_mq_complete_request(rq); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); } } @@ -1999,7 +2118,7 @@ lo->tag_set.queue_depth = 128; lo->tag_set.numa_node = NUMA_NO_NODE; lo->tag_set.cmd_size = sizeof(struct loop_cmd); - lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE; + lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_NO_SCHED; lo->tag_set.driver_data = lo; err = blk_mq_alloc_tag_set(&lo->tag_set); @@ -2295,6 +2414,8 @@ range = max_loop ? max_loop << part_shift : 1UL << MINORBITS; + mutex_lock(&loop_ctl_mutex); + idr_for_each(&loop_index_idr, &loop_exit_cb, NULL); idr_destroy(&loop_index_idr); @@ -2302,6 +2423,8 @@ unregister_blkdev(LOOP_MAJOR, "loop"); misc_deregister(&loop_misc); + + mutex_unlock(&loop_ctl_mutex); } module_init(loop_init); --- linux-oracle-5.4.0.orig/drivers/block/loop.h +++ linux-oracle-5.4.0/drivers/block/loop.h @@ -46,7 +46,7 @@ int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); - struct file * lo_backing_file; + struct file *lo_backing_file, *lo_backing_virt_file; struct block_device *lo_device; void *key_data; --- linux-oracle-5.4.0.orig/drivers/block/mtip32xx/mtip32xx.c +++ linux-oracle-5.4.0/drivers/block/mtip32xx/mtip32xx.c @@ -492,7 +492,8 @@ struct request *req = blk_mq_rq_from_pdu(cmd); cmd->status = status; - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); } /* --- linux-oracle-5.4.0.orig/drivers/block/nbd.c +++ linux-oracle-5.4.0/drivers/block/nbd.c @@ -78,8 +78,7 @@ #define NBD_RT_HAS_PID_FILE 3 #define NBD_RT_HAS_CONFIG_REF 4 #define NBD_RT_BOUND 5 -#define NBD_RT_DESTROY_ON_DISCONNECT 6 -#define NBD_RT_DISCONNECT_ON_CLOSE 7 +#define NBD_RT_DISCONNECT_ON_CLOSE 6 #define NBD_DESTROY_ON_DISCONNECT 0 #define NBD_DISCONNECT_REQUESTED 1 @@ -123,6 +122,12 @@ }; #define NBD_CMD_REQUEUED 1 +/* + * This flag will be set if nbd_queue_rq() succeed, and will be checked and + * cleared in completion. Both setting and clearing of the flag are protected + * by cmd->lock. + */ +#define NBD_CMD_INFLIGHT 2 struct nbd_cmd { struct nbd_device *nbd; @@ -296,7 +301,7 @@ } } -static void nbd_size_update(struct nbd_device *nbd) +static void nbd_size_update(struct nbd_device *nbd, bool start) { struct nbd_config *config = nbd->config; struct block_device *bdev = bdget_disk(nbd->disk, 0); @@ -312,7 +317,8 @@ if (bdev) { if (bdev->bd_disk) { bd_set_size(bdev, config->bytesize); - set_blocksize(bdev, config->blksize); + if (start) + set_blocksize(bdev, config->blksize); } else bdev->bd_invalidated = 1; bdput(bdev); @@ -327,7 +333,7 @@ config->blksize = blocksize; config->bytesize = blocksize * nr_blocks; if (nbd->task_recv != NULL) - nbd_size_update(nbd); + nbd_size_update(nbd, false); } static void nbd_complete_rq(struct request *req) @@ -388,8 +394,14 @@ if (!mutex_trylock(&cmd->lock)) return BLK_EH_RESET_TIMER; + if (!test_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { + mutex_unlock(&cmd->lock); + return BLK_EH_DONE; + } + if (!refcount_inc_not_zero(&nbd->config_refs)) { cmd->status = BLK_STS_TIMEOUT; + __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags); mutex_unlock(&cmd->lock); goto done; } @@ -445,6 +457,7 @@ dev_err_ratelimited(nbd_to_dev(nbd), "Connection timed out\n"); set_bit(NBD_RT_TIMEDOUT, &config->runtime_flags); cmd->status = BLK_STS_IOERR; + __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags); mutex_unlock(&cmd->lock); sock_shutdown(nbd); nbd_config_put(nbd); @@ -704,6 +717,12 @@ cmd = blk_mq_rq_to_pdu(req); mutex_lock(&cmd->lock); + if (!test_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { + dev_err(disk_to_dev(nbd->disk), "Suspicious reply %d (status %u flags %lu)", + tag, cmd->status, cmd->flags); + ret = -ENOENT; + goto out; + } if (cmd->cmd_cookie != nbd_handle_to_cookie(handle)) { dev_err(disk_to_dev(nbd->disk), "Double reply on req %p, cmd_cookie %u, handle cookie %u\n", req, cmd->cmd_cookie, nbd_handle_to_cookie(handle)); @@ -773,6 +792,7 @@ struct nbd_device *nbd = args->nbd; struct nbd_config *config = nbd->config; struct nbd_cmd *cmd; + struct request *rq; while (1) { cmd = nbd_read_stat(nbd, args->index); @@ -785,11 +805,21 @@ break; } - blk_mq_complete_request(blk_mq_rq_from_pdu(cmd)); + rq = blk_mq_rq_from_pdu(cmd); + if (likely(!blk_should_fake_timeout(rq->q))) { + bool complete; + + mutex_lock(&cmd->lock); + complete = __test_and_clear_bit(NBD_CMD_INFLIGHT, + &cmd->flags); + mutex_unlock(&cmd->lock); + if (complete) + blk_mq_complete_request(rq); + } } + nbd_config_put(nbd); atomic_dec(&config->recv_threads); wake_up(&config->recv_wq); - nbd_config_put(nbd); kfree(args); } @@ -797,7 +827,15 @@ { struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); + /* don't abort one completed request */ + if (blk_mq_request_completed(req)) + return true; + mutex_lock(&cmd->lock); + if (!__test_and_clear_bit(NBD_CMD_INFLIGHT, &cmd->flags)) { + mutex_unlock(&cmd->lock); + return true; + } cmd->status = BLK_STS_IOERR; mutex_unlock(&cmd->lock); @@ -861,11 +899,15 @@ struct nbd_config *config = nbd->config; if (!config->dead_conn_timeout) return 0; - if (test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags)) + + if (!wait_event_timeout(config->conn_wait, + test_bit(NBD_RT_DISCONNECTED, + &config->runtime_flags) || + atomic_read(&config->live_connections) > 0, + config->dead_conn_timeout)) return 0; - return wait_event_timeout(config->conn_wait, - atomic_read(&config->live_connections) > 0, - config->dead_conn_timeout) > 0; + + return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags); } static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) @@ -934,7 +976,13 @@ * returns EAGAIN can be retried on a different socket. */ ret = nbd_send_cmd(nbd, cmd, index); - if (ret == -EAGAIN) { + /* + * Access to this flag is protected by cmd->lock, thus it's safe to set + * the flag after nbd_send_cmd() succeed to send request to server. + */ + if (!ret) + __set_bit(NBD_CMD_INFLIGHT, &cmd->flags); + else if (ret == -EAGAIN) { dev_err_ratelimited(disk_to_dev(nbd->disk), "Request send failed, requeueing\n"); nbd_mark_nsock_dead(nbd, nsock, 1); @@ -1013,6 +1061,12 @@ if (!sock) return err; + /* + * We need to make sure we don't get any errant requests while we're + * reallocating the ->socks array. + */ + blk_mq_freeze_queue(nbd->disk->queue); + if (!netlink && !nbd->task_setup && !test_bit(NBD_RT_BOUND, &config->runtime_flags)) nbd->task_setup = current; @@ -1022,20 +1076,22 @@ test_bit(NBD_RT_BOUND, &config->runtime_flags))) { dev_err(disk_to_dev(nbd->disk), "Device being setup by another task"); - sockfd_put(sock); - return -EBUSY; + err = -EBUSY; + goto put_socket; + } + + nsock = kzalloc(sizeof(*nsock), GFP_KERNEL); + if (!nsock) { + err = -ENOMEM; + goto put_socket; } socks = krealloc(config->socks, (config->num_connections + 1) * sizeof(struct nbd_sock *), GFP_KERNEL); if (!socks) { - sockfd_put(sock); - return -ENOMEM; - } - nsock = kzalloc(sizeof(struct nbd_sock), GFP_KERNEL); - if (!nsock) { - sockfd_put(sock); - return -ENOMEM; + kfree(nsock); + err = -ENOMEM; + goto put_socket; } config->socks = socks; @@ -1049,8 +1105,14 @@ nsock->cookie = 0; socks[config->num_connections++] = nsock; atomic_inc(&config->live_connections); + blk_mq_unfreeze_queue(nbd->disk->queue); return 0; + +put_socket: + blk_mq_unfreeze_queue(nbd->disk->queue); + sockfd_put(sock); + return err; } static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) @@ -1264,6 +1326,16 @@ args = kzalloc(sizeof(*args), GFP_KERNEL); if (!args) { sock_shutdown(nbd); + /* + * If num_connections is m (2 < m), + * and NO.1 ~ NO.n(1 < n < m) kzallocs are successful. + * But NO.(n + 1) failed. We still have n recv threads. + * So, add flush_workqueue here to prevent recv threads + * dropping the last config_refs and trying to destroy + * the workqueue from inside the workqueue. + */ + if (i) + flush_workqueue(nbd->recv_workq); return -ENOMEM; } sk_set_memalloc(config->socks[i]->sock->sk); @@ -1277,7 +1349,7 @@ args->index = i; queue_work(nbd->recv_workq, &args->work); } - nbd_size_update(nbd); + nbd_size_update(nbd, true); return error; } @@ -1297,8 +1369,10 @@ atomic_read(&config->recv_threads) == 0); if (ret) { sock_shutdown(nbd); - flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); } + + flush_workqueue(nbd->recv_workq); mutex_lock(&nbd->config_lock); nbd_bdev_reset(bdev); /* user requested, ignore socket errors */ @@ -1312,7 +1386,7 @@ static void nbd_clear_sock_ioctl(struct nbd_device *nbd, struct block_device *bdev) { - sock_shutdown(nbd); + nbd_clear_sock(nbd); __invalidate_device(bdev, true); nbd_bdev_reset(bdev); if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, @@ -1333,6 +1407,8 @@ nbd->tag_set.timeout = timeout * HZ; if (timeout) blk_queue_rq_timeout(nbd->disk->queue, timeout * HZ); + else + blk_queue_rq_timeout(nbd->disk->queue, 30 * HZ); } /* Must be called with config_lock held */ @@ -1423,15 +1499,20 @@ { struct nbd_config *config; + if (!try_module_get(THIS_MODULE)) + return ERR_PTR(-ENODEV); + config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); - if (!config) - return NULL; + if (!config) { + module_put(THIS_MODULE); + return ERR_PTR(-ENOMEM); + } + atomic_set(&config->recv_threads, 0); init_waitqueue_head(&config->recv_wq); init_waitqueue_head(&config->conn_wait); config->blksize = NBD_DEF_BLKSIZE; atomic_set(&config->live_connections, 0); - try_module_get(THIS_MODULE); return config; } @@ -1458,12 +1539,13 @@ mutex_unlock(&nbd->config_lock); goto out; } - config = nbd->config = nbd_alloc_config(); - if (!config) { - ret = -ENOMEM; + config = nbd_alloc_config(); + if (IS_ERR(config)) { + ret = PTR_ERR(config); mutex_unlock(&nbd->config_lock); goto out; } + nbd->config = config; refcount_set(&nbd->config_refs, 1); refcount_inc(&nbd->refs); mutex_unlock(&nbd->config_lock); @@ -1484,6 +1566,7 @@ if (test_bit(NBD_RT_DISCONNECT_ON_CLOSE, &nbd->config->runtime_flags) && bdev->bd_openers == 0) nbd_disconnect_and_put(nbd); + bdput(bdev); nbd_config_put(nbd); nbd_put(nbd); @@ -1566,7 +1649,7 @@ return -EIO; dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir); - if (!dir) { + if (IS_ERR(dir)) { dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n", nbd_name(nbd)); return -EIO; @@ -1592,7 +1675,7 @@ struct dentry *dbg_dir; dbg_dir = debugfs_create_dir("nbd", NULL); - if (!dbg_dir) + if (IS_ERR(dbg_dir)) return -EIO; nbd_dbg_dir = dbg_dir; @@ -1665,7 +1748,8 @@ if (err == -ENOSPC) err = -EEXIST; } else { - err = idr_alloc(&nbd_index_idr, nbd, 0, 0, GFP_KERNEL); + err = idr_alloc(&nbd_index_idr, nbd, 0, + (MINORMASK >> part_shift) + 1, GFP_KERNEL); if (err >= 0) index = err; } @@ -1884,13 +1968,14 @@ nbd_put(nbd); return -EINVAL; } - config = nbd->config = nbd_alloc_config(); - if (!nbd->config) { + config = nbd_alloc_config(); + if (IS_ERR(config)) { mutex_unlock(&nbd->config_lock); nbd_put(nbd); printk(KERN_ERR "nbd: couldn't allocate config\n"); - return -ENOMEM; + return PTR_ERR(config); } + nbd->config = config; refcount_set(&nbd->config_refs, 1); set_bit(NBD_RT_BOUND, &config->runtime_flags); @@ -1912,12 +1997,21 @@ if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) { u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]); if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) { - set_bit(NBD_RT_DESTROY_ON_DISCONNECT, - &config->runtime_flags); - set_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags); - put_dev = true; + /* + * We have 1 ref to keep the device around, and then 1 + * ref for our current operation here, which will be + * inherited by the config. If we already have + * DESTROY_ON_DISCONNECT set then we know we don't have + * that extra ref already held so we don't need the + * put_dev. + */ + if (!test_and_set_bit(NBD_DESTROY_ON_DISCONNECT, + &nbd->flags)) + put_dev = true; } else { - clear_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags); + if (test_and_clear_bit(NBD_DESTROY_ON_DISCONNECT, + &nbd->flags)) + refcount_inc(&nbd->refs); } if (flags & NBD_CFLAG_DISCONNECT_ON_CLOSE) { set_bit(NBD_RT_DISCONNECT_ON_CLOSE, @@ -1973,14 +2067,21 @@ { mutex_lock(&nbd->config_lock); nbd_disconnect(nbd); - nbd_clear_sock(nbd); - mutex_unlock(&nbd->config_lock); + sock_shutdown(nbd); + wake_up(&nbd->config->conn_wait); /* * Make sure recv thread has finished, so it does not drop the last * config ref and try to destroy the workqueue from inside the work - * queue. + * queue. And this also ensure that we can safely call nbd_clear_que() + * to cancel the inflight I/Os. */ - flush_workqueue(nbd->recv_workq); + if (nbd->recv_workq) + flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); + nbd->task_setup = NULL; + clear_bit(NBD_RT_BOUND, &nbd->config->runtime_flags); + mutex_unlock(&nbd->config_lock); + if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, &nbd->config->runtime_flags)) nbd_config_put(nbd); @@ -2088,15 +2189,13 @@ if (info->attrs[NBD_ATTR_CLIENT_FLAGS]) { u64 flags = nla_get_u64(info->attrs[NBD_ATTR_CLIENT_FLAGS]); if (flags & NBD_CFLAG_DESTROY_ON_DISCONNECT) { - if (!test_and_set_bit(NBD_RT_DESTROY_ON_DISCONNECT, - &config->runtime_flags)) + if (!test_and_set_bit(NBD_DESTROY_ON_DISCONNECT, + &nbd->flags)) put_dev = true; - set_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags); } else { - if (test_and_clear_bit(NBD_RT_DESTROY_ON_DISCONNECT, - &config->runtime_flags)) + if (test_and_clear_bit(NBD_DESTROY_ON_DISCONNECT, + &nbd->flags)) refcount_inc(&nbd->refs); - clear_bit(NBD_DESTROY_ON_DISCONNECT, &nbd->flags); } if (flags & NBD_CFLAG_DISCONNECT_ON_CLOSE) { @@ -2255,6 +2354,12 @@ } dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST); + if (!dev_list) { + nlmsg_free(reply); + ret = -EMSGSIZE; + goto out; + } + if (index == -1) { ret = idr_for_each(&nbd_index_idr, &status_cb, reply); if (ret) { @@ -2398,6 +2503,12 @@ struct nbd_device *nbd; LIST_HEAD(del_list); + /* + * Unregister netlink interface prior to waiting + * for the completion of netlink commands. + */ + genl_unregister_family(&nbd_genl_family); + nbd_dbg_close(); mutex_lock(&nbd_index_mutex); @@ -2407,13 +2518,15 @@ while (!list_empty(&del_list)) { nbd = list_first_entry(&del_list, struct nbd_device, list); list_del_init(&nbd->list); + if (refcount_read(&nbd->config_refs)) + printk(KERN_ERR "nbd: possibly leaking nbd_config (ref %d)\n", + refcount_read(&nbd->config_refs)); if (refcount_read(&nbd->refs) != 1) printk(KERN_ERR "nbd: possibly leaking a device\n"); nbd_put(nbd); } idr_destroy(&nbd_index_idr); - genl_unregister_family(&nbd_genl_family); unregister_blkdev(NBD_MAJOR, "nbd"); } --- linux-oracle-5.4.0.orig/drivers/block/null_blk_main.c +++ linux-oracle-5.4.0/drivers/block/null_blk_main.c @@ -579,6 +579,7 @@ if (tag != -1U) { cmd = &nq->cmds[tag]; cmd->tag = tag; + cmd->error = BLK_STS_OK; cmd->nq = nq; if (nq->dev->irqmode == NULL_IRQ_TIMER) { hrtimer_init(&cmd->timer, CLOCK_MONOTONIC, @@ -1071,7 +1072,7 @@ len = bvec.bv_len; err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset, op_is_write(req_op(rq)), sector, - req_op(rq) & REQ_FUA); + rq->cmd_flags & REQ_FUA); if (err) { spin_unlock_irq(&nullb->lock); return err; @@ -1189,7 +1190,8 @@ case NULL_IRQ_SOFTIRQ: switch (cmd->nq->dev->queue_mode) { case NULL_Q_MQ: - blk_mq_complete_request(cmd->rq); + if (likely(!blk_should_fake_timeout(cmd->rq->q))) + blk_mq_complete_request(cmd->rq); break; case NULL_Q_BIO: /* @@ -1335,6 +1337,7 @@ cmd->timer.function = null_cmd_timer_expired; } cmd->rq = bd->rq; + cmd->error = BLK_STS_OK; cmd->nq = nq; blk_mq_start_request(bd->rq); @@ -1382,7 +1385,12 @@ static void null_del_dev(struct nullb *nullb) { - struct nullb_device *dev = nullb->dev; + struct nullb_device *dev; + + if (!nullb) + return; + + dev = nullb->dev; ida_simple_remove(&nullb_indexes, nullb->index); @@ -1704,8 +1712,13 @@ blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, nullb->q); mutex_lock(&lock); - nullb->index = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL); - dev->index = nullb->index; + rv = ida_simple_get(&nullb_indexes, 0, 0, GFP_KERNEL); + if (rv < 0) { + mutex_unlock(&lock); + goto out_cleanup_zone; + } + nullb->index = rv; + dev->index = rv; mutex_unlock(&lock); blk_queue_logical_block_size(nullb->q, dev->blocksize); @@ -1717,13 +1730,16 @@ rv = null_gendisk_register(nullb); if (rv) - goto out_cleanup_zone; + goto out_ida_free; mutex_lock(&lock); list_add_tail(&nullb->list, &nullb_list); mutex_unlock(&lock); return 0; + +out_ida_free: + ida_free(&nullb_indexes, nullb->index); out_cleanup_zone: if (dev->zoned) null_zone_exit(dev); @@ -1736,6 +1752,7 @@ cleanup_queues(nullb); out_free_nullb: kfree(nullb); + dev->nullb = NULL; out: return rv; } @@ -1852,10 +1869,13 @@ if (g_queue_mode == NULL_Q_MQ && shared_tags) blk_mq_free_tag_set(&tag_set); + + mutex_destroy(&lock); } module_init(null_init); module_exit(null_exit); MODULE_AUTHOR("Jens Axboe "); +MODULE_DESCRIPTION("multi queue aware block test driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/block/null_blk_zoned.c +++ linux-oracle-5.4.0/drivers/block/null_blk_zoned.c @@ -2,8 +2,7 @@ #include #include "null_blk.h" -/* zone_size in MBs to sectors. */ -#define ZONE_SIZE_SHIFT 11 +#define MB_TO_SECTS(mb) (((sector_t)mb * SZ_1M) >> SECTOR_SHIFT) static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) { @@ -12,7 +11,7 @@ int null_zone_init(struct nullb_device *dev) { - sector_t dev_size = (sector_t)dev->size * 1024 * 1024; + sector_t dev_capacity_sects; sector_t sector = 0; unsigned int i; @@ -20,10 +19,17 @@ pr_err("zone_size must be power-of-two\n"); return -EINVAL; } + if (dev->zone_size > dev->size) { + pr_err("Zone size larger than device capacity\n"); + return -EINVAL; + } + + dev_capacity_sects = MB_TO_SECTS(dev->size); + dev->zone_size_sects = MB_TO_SECTS(dev->zone_size); + dev->nr_zones = dev_capacity_sects >> ilog2(dev->zone_size_sects); + if (dev_capacity_sects & (dev->zone_size_sects - 1)) + dev->nr_zones++; - dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT; - dev->nr_zones = dev_size >> - (SECTOR_SHIFT + ilog2(dev->zone_size_sects)); dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct blk_zone), GFP_KERNEL | __GFP_ZERO); if (!dev->zones) @@ -51,7 +57,10 @@ struct blk_zone *zone = &dev->zones[i]; zone->start = zone->wp = sector; - zone->len = dev->zone_size_sects; + if (zone->start + dev->zone_size_sects > dev_capacity_sects) + zone->len = dev_capacity_sects - zone->start; + else + zone->len = dev->zone_size_sects; zone->type = BLK_ZONE_TYPE_SEQWRITE_REQ; zone->cond = BLK_ZONE_COND_EMPTY; @@ -64,6 +73,7 @@ void null_zone_exit(struct nullb_device *dev) { kvfree(dev->zones); + dev->zones = NULL; } int null_zone_report(struct gendisk *disk, sector_t sector, --- linux-oracle-5.4.0.orig/drivers/block/ps3disk.c +++ linux-oracle-5.4.0/drivers/block/ps3disk.c @@ -454,7 +454,6 @@ queue->queuedata = dev; blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9); - blk_queue_segment_boundary(queue, -1UL); blk_queue_dma_alignment(queue, dev->blk_size-1); blk_queue_logical_block_size(queue, dev->blk_size); --- linux-oracle-5.4.0.orig/drivers/block/rbd.c +++ linux-oracle-5.4.0/drivers/block/rbd.c @@ -366,7 +366,7 @@ enum rbd_lock_state { RBD_LOCK_STATE_UNLOCKED, RBD_LOCK_STATE_LOCKED, - RBD_LOCK_STATE_RELEASING, + RBD_LOCK_STATE_QUIESCING, }; /* WatchNotify::ClientId */ @@ -427,7 +427,7 @@ struct list_head running_list; struct completion acquire_wait; int acquire_err; - struct completion releasing_wait; + struct completion quiescing_wait; spinlock_t object_map_lock; u8 *object_map; @@ -519,7 +519,7 @@ lockdep_assert_held(&rbd_dev->lock_rwsem); return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED || - rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING; + rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING; } static bool rbd_is_lock_owner(struct rbd_device *rbd_dev) @@ -626,9 +626,8 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); static int rbd_dev_refresh(struct rbd_device *rbd_dev); -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); -static int rbd_dev_header_info(struct rbd_device *rbd_dev); -static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); +static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, + struct rbd_image_header *header); static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u64 snap_id); static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, @@ -1098,15 +1097,24 @@ RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); } +static void rbd_image_header_cleanup(struct rbd_image_header *header) +{ + kfree(header->object_prefix); + ceph_put_snap_context(header->snapc); + kfree(header->snap_sizes); + kfree(header->snap_names); + + memset(header, 0, sizeof(*header)); +} + /* * Fill an rbd image header with information from the given format 1 * on-disk header. */ -static int rbd_header_from_disk(struct rbd_device *rbd_dev, - struct rbd_image_header_ondisk *ondisk) +static int rbd_header_from_disk(struct rbd_image_header *header, + struct rbd_image_header_ondisk *ondisk, + bool first_time) { - struct rbd_image_header *header = &rbd_dev->header; - bool first_time = header->object_prefix == NULL; struct ceph_snap_context *snapc; char *object_prefix = NULL; char *snap_names = NULL; @@ -1173,11 +1181,6 @@ if (first_time) { header->object_prefix = object_prefix; header->obj_order = ondisk->options.order; - rbd_init_layout(rbd_dev); - } else { - ceph_put_snap_context(header->snapc); - kfree(header->snap_names); - kfree(header->snap_sizes); } /* The remaining fields always get updated (when we refresh) */ @@ -1493,14 +1496,30 @@ /* * Must be called after rbd_obj_calc_img_extents(). */ -static bool rbd_obj_copyup_enabled(struct rbd_obj_request *obj_req) +static void rbd_obj_set_copyup_enabled(struct rbd_obj_request *obj_req) { - if (!obj_req->num_img_extents || - (rbd_obj_is_entire(obj_req) && - !obj_req->img_request->snapc->num_snaps)) - return false; + rbd_assert(obj_req->img_request->snapc); - return true; + if (obj_req->img_request->op_type == OBJ_OP_DISCARD) { + dout("%s %p objno %llu discard\n", __func__, obj_req, + obj_req->ex.oe_objno); + return; + } + + if (!obj_req->num_img_extents) { + dout("%s %p objno %llu not overlapping\n", __func__, obj_req, + obj_req->ex.oe_objno); + return; + } + + if (rbd_obj_is_entire(obj_req) && + !obj_req->img_request->snapc->num_snaps) { + dout("%s %p objno %llu entire\n", __func__, obj_req, + obj_req->ex.oe_objno); + return; + } + + obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; } static u64 rbd_obj_img_extents_bytes(struct rbd_obj_request *obj_req) @@ -1599,6 +1618,7 @@ static struct ceph_osd_request * rbd_obj_add_osd_request(struct rbd_obj_request *obj_req, int num_ops) { + rbd_assert(obj_req->img_request->snapc); return __rbd_obj_add_osd_request(obj_req, obj_req->img_request->snapc, num_ops); } @@ -1727,11 +1747,14 @@ * Caller is responsible for filling in the list of object requests * that comprises the image request, and the Linux request pointer * (if there is one). + * + * Only snap_id is captured here, for reads. For writes, snapshot + * context is captured in rbd_img_object_requests() after exclusive + * lock is ensured to be held. */ static struct rbd_img_request *rbd_img_request_create( struct rbd_device *rbd_dev, - enum obj_operation_type op_type, - struct ceph_snap_context *snapc) + enum obj_operation_type op_type) { struct rbd_img_request *img_request; @@ -1743,8 +1766,6 @@ img_request->op_type = op_type; if (!rbd_img_is_write(img_request)) img_request->snap_id = rbd_dev->spec->snap_id; - else - img_request->snapc = snapc; if (rbd_dev_parent_get(rbd_dev)) img_request_layered_set(img_request); @@ -2087,7 +2108,7 @@ struct rbd_device *rbd_dev = obj_req->img_request->rbd_dev; struct ceph_osd_data *osd_data; u64 objno; - u8 state, new_state, uninitialized_var(current_state); + u8 state, new_state, current_state; bool has_current_state; void *p; @@ -2389,9 +2410,6 @@ if (ret) return ret; - if (rbd_obj_copyup_enabled(obj_req)) - obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; - obj_req->write_state = RBD_OBJ_WRITE_START; return 0; } @@ -2497,8 +2515,6 @@ if (ret) return ret; - if (rbd_obj_copyup_enabled(obj_req)) - obj_req->flags |= RBD_OBJ_FLAG_COPYUP_ENABLED; if (!obj_req->num_img_extents) { obj_req->flags |= RBD_OBJ_FLAG_NOOP_FOR_NONEXISTENT; if (rbd_obj_is_entire(obj_req)) @@ -2739,7 +2755,7 @@ u64 off, u64 len) { struct ceph_file_extent ex = { off, len }; - union rbd_img_fill_iter dummy; + union rbd_img_fill_iter dummy = {}; struct rbd_img_fill_ctx fctx = { .pos_type = OBJ_REQUEST_NODATA, .pos = &dummy, @@ -2935,7 +2951,7 @@ int ret; child_img_req = rbd_img_request_create(img_req->rbd_dev->parent, - OBJ_OP_READ, NULL); + OBJ_OP_READ); if (!child_img_req) return -ENOMEM; @@ -3439,6 +3455,7 @@ case RBD_OBJ_WRITE_START: rbd_assert(!*result); + rbd_obj_set_copyup_enabled(obj_req); if (rbd_obj_write_is_noop(obj_req)) return true; @@ -3586,17 +3603,19 @@ static void rbd_lock_del_request(struct rbd_img_request *img_req) { struct rbd_device *rbd_dev = img_req->rbd_dev; - bool need_wakeup; + bool need_wakeup = false; lockdep_assert_held(&rbd_dev->lock_rwsem); spin_lock(&rbd_dev->lock_lists_lock); - rbd_assert(!list_empty(&img_req->lock_item)); - list_del_init(&img_req->lock_item); - need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && - list_empty(&rbd_dev->running_list)); + if (!list_empty(&img_req->lock_item)) { + rbd_assert(!list_empty(&rbd_dev->running_list)); + list_del_init(&img_req->lock_item); + need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING && + list_empty(&rbd_dev->running_list)); + } spin_unlock(&rbd_dev->lock_lists_lock); if (need_wakeup) - complete(&rbd_dev->releasing_wait); + complete(&rbd_dev->quiescing_wait); } static int rbd_img_exclusive_lock(struct rbd_img_request *img_req) @@ -3609,11 +3628,6 @@ if (rbd_lock_add_request(img_req)) return 1; - if (rbd_dev->opts->exclusive) { - WARN_ON(1); /* lock got released? */ - return -EROFS; - } - /* * Note the use of mod_delayed_work() in rbd_acquire_lock() * and cancel_delayed_work() in wake_lock_waiters(). @@ -3625,9 +3639,19 @@ static void rbd_img_object_requests(struct rbd_img_request *img_req) { + struct rbd_device *rbd_dev = img_req->rbd_dev; struct rbd_obj_request *obj_req; rbd_assert(!img_req->pending.result && !img_req->pending.num_pending); + rbd_assert(!need_exclusive_lock(img_req) || + __rbd_is_lock_owner(rbd_dev)); + + if (rbd_img_is_write(img_req)) { + rbd_assert(!img_req->snapc); + down_read(&rbd_dev->header_rwsem); + img_req->snapc = ceph_get_snap_context(rbd_dev->header.snapc); + up_read(&rbd_dev->header_rwsem); + } for_each_obj_request(img_req, obj_req) { int result = 0; @@ -3645,7 +3669,6 @@ static bool rbd_img_advance(struct rbd_img_request *img_req, int *result) { - struct rbd_device *rbd_dev = img_req->rbd_dev; int ret; again: @@ -3666,9 +3689,6 @@ if (*result) return true; - rbd_assert(!need_exclusive_lock(img_req) || - __rbd_is_lock_owner(rbd_dev)); - rbd_img_object_requests(img_req); if (!img_req->pending.num_pending) { *result = img_req->pending.result; @@ -3974,14 +3994,19 @@ return; } - list_for_each_entry(img_req, &rbd_dev->acquiring_list, lock_item) { + while (!list_empty(&rbd_dev->acquiring_list)) { + img_req = list_first_entry(&rbd_dev->acquiring_list, + struct rbd_img_request, lock_item); mutex_lock(&img_req->state_mutex); rbd_assert(img_req->state == RBD_IMG_EXCLUSIVE_LOCK); + if (!result) + list_move_tail(&img_req->lock_item, + &rbd_dev->running_list); + else + list_del_init(&img_req->lock_item); rbd_img_schedule(img_req, result); mutex_unlock(&img_req->state_mutex); } - - list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); } static int get_lock_owner_info(struct rbd_device *rbd_dev, @@ -4130,6 +4155,10 @@ { int ret; + ret = rbd_dev_refresh(rbd_dev); + if (ret) + return ret; + if (rbd_dev->header.features & RBD_FEATURE_OBJECT_MAP) { ret = rbd_object_map_open(rbd_dev); if (ret) @@ -4239,8 +4268,6 @@ static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) { - bool need_wait; - dout("%s rbd_dev %p\n", __func__, rbd_dev); lockdep_assert_held_write(&rbd_dev->lock_rwsem); @@ -4250,16 +4277,16 @@ /* * Ensure that all in-flight IO is flushed. */ - rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; - rbd_assert(!completion_done(&rbd_dev->releasing_wait)); - need_wait = !list_empty(&rbd_dev->running_list); - downgrade_write(&rbd_dev->lock_rwsem); - if (need_wait) - wait_for_completion(&rbd_dev->releasing_wait); - up_read(&rbd_dev->lock_rwsem); + rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING; + rbd_assert(!completion_done(&rbd_dev->quiescing_wait)); + if (list_empty(&rbd_dev->running_list)) + return true; + + up_write(&rbd_dev->lock_rwsem); + wait_for_completion(&rbd_dev->quiescing_wait); down_write(&rbd_dev->lock_rwsem); - if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) + if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING) return false; rbd_assert(list_empty(&rbd_dev->running_list)); @@ -4342,15 +4369,11 @@ if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { down_write(&rbd_dev->lock_rwsem); if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { - /* - * we already know that the remote client is - * the owner - */ - up_write(&rbd_dev->lock_rwsem); - return; + dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n", + __func__, rbd_dev, cid.gid, cid.handle); + } else { + rbd_set_owner_cid(rbd_dev, &cid); } - - rbd_set_owner_cid(rbd_dev, &cid); downgrade_write(&rbd_dev->lock_rwsem); } else { down_read(&rbd_dev->lock_rwsem); @@ -4375,14 +4398,12 @@ if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { down_write(&rbd_dev->lock_rwsem); if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { - dout("%s rbd_dev %p unexpected owner, cid %llu-%llu != owner_cid %llu-%llu\n", + dout("%s rbd_dev %p cid %llu-%llu != owner_cid %llu-%llu\n", __func__, rbd_dev, cid.gid, cid.handle, rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); - up_write(&rbd_dev->lock_rwsem); - return; + } else { + rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); } - - rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); downgrade_write(&rbd_dev->lock_rwsem); } else { down_read(&rbd_dev->lock_rwsem); @@ -4636,6 +4657,10 @@ cancel_work_sync(&rbd_dev->unlock_work); } +/* + * header_rwsem must not be held to avoid a deadlock with + * rbd_dev_refresh() when flushing notifies. + */ static void rbd_unregister_watch(struct rbd_device *rbd_dev) { cancel_tasks_sync(rbd_dev); @@ -4672,6 +4697,10 @@ rbd_warn(rbd_dev, "failed to update lock cookie: %d", ret); + if (rbd_dev->opts->exclusive) + rbd_warn(rbd_dev, + "temporarily releasing lock on exclusive mapping"); + /* * Lock cookie cannot be updated on older OSDs, so do * a manual release and queue an acquire. @@ -4792,7 +4821,6 @@ struct request *rq = blk_mq_rq_from_pdu(work); struct rbd_device *rbd_dev = rq->q->queuedata; struct rbd_img_request *img_request; - struct ceph_snap_context *snapc = NULL; u64 offset = (u64)blk_rq_pos(rq) << SECTOR_SHIFT; u64 length = blk_rq_bytes(rq); enum obj_operation_type op_type; @@ -4857,10 +4885,6 @@ down_read(&rbd_dev->header_rwsem); mapping_size = rbd_dev->mapping.size; - if (op_type != OBJ_OP_READ) { - snapc = rbd_dev->header.snapc; - ceph_get_snap_context(snapc); - } up_read(&rbd_dev->header_rwsem); if (offset + length > mapping_size) { @@ -4870,13 +4894,12 @@ goto err_rq; } - img_request = rbd_img_request_create(rbd_dev, op_type, snapc); + img_request = rbd_img_request_create(rbd_dev, op_type); if (!img_request) { result = -ENOMEM; goto err_rq; } img_request->rq = rq; - snapc = NULL; /* img_request consumes a ref */ dout("%s rbd_dev %p img_req %p %s %llu~%llu\n", __func__, rbd_dev, img_request, obj_op_name(op_type), offset, length); @@ -4898,7 +4921,6 @@ if (result) rbd_warn(rbd_dev, "%s %llx at %llx result %d", obj_op_name(op_type), length, offset, result); - ceph_put_snap_context(snapc); err: blk_mq_end_request(rq, errno_to_blk_status(result)); } @@ -4970,7 +4992,9 @@ * return, the rbd_dev->header field will contain up-to-date * information about the image. */ -static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { struct rbd_image_header_ondisk *ondisk = NULL; u32 snap_count = 0; @@ -5018,7 +5042,7 @@ snap_count = le32_to_cpu(ondisk->snap_count); } while (snap_count != want_count); - ret = rbd_header_from_disk(rbd_dev, ondisk); + ret = rbd_header_from_disk(header, ondisk, first_time); out: kfree(ondisk); @@ -5062,43 +5086,6 @@ } } -static int rbd_dev_refresh(struct rbd_device *rbd_dev) -{ - u64 mapping_size; - int ret; - - down_write(&rbd_dev->header_rwsem); - mapping_size = rbd_dev->mapping.size; - - ret = rbd_dev_header_info(rbd_dev); - if (ret) - goto out; - - /* - * If there is a parent, see if it has disappeared due to the - * mapped image getting flattened. - */ - if (rbd_dev->parent) { - ret = rbd_dev_v2_parent_info(rbd_dev); - if (ret) - goto out; - } - - if (rbd_dev->spec->snap_id == CEPH_NOSNAP) { - rbd_dev->mapping.size = rbd_dev->header.image_size; - } else { - /* validate mapped snapshot's EXISTS flag */ - rbd_exists_validate(rbd_dev); - } - -out: - up_write(&rbd_dev->header_rwsem); - if (!ret && mapping_size != rbd_dev->mapping.size) - rbd_dev_update_size(rbd_dev); - - return ret; -} - static int rbd_init_request(struct blk_mq_tag_set *set, struct request *rq, unsigned int hctx_idx, unsigned int numa_node) { @@ -5276,6 +5263,9 @@ { struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + return sprintf(buf, "%s\n", rbd_dev->config_info); } @@ -5387,6 +5377,9 @@ struct rbd_device *rbd_dev = dev_to_rbd_dev(dev); int ret; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + ret = rbd_dev_refresh(rbd_dev); if (ret) return ret; @@ -5527,8 +5520,7 @@ module_put(THIS_MODULE); } -static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc, - struct rbd_spec *spec) +static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec) { struct rbd_device *rbd_dev; @@ -5564,7 +5556,7 @@ INIT_LIST_HEAD(&rbd_dev->acquiring_list); INIT_LIST_HEAD(&rbd_dev->running_list); init_completion(&rbd_dev->acquire_wait); - init_completion(&rbd_dev->releasing_wait); + init_completion(&rbd_dev->quiescing_wait); spin_lock_init(&rbd_dev->object_map_lock); @@ -5573,9 +5565,6 @@ rbd_dev->dev.parent = &rbd_root_dev; device_initialize(&rbd_dev->dev); - rbd_dev->rbd_client = rbdc; - rbd_dev->spec = spec; - return rbd_dev; } @@ -5588,12 +5577,10 @@ { struct rbd_device *rbd_dev; - rbd_dev = __rbd_dev_create(rbdc, spec); + rbd_dev = __rbd_dev_create(spec); if (!rbd_dev) return NULL; - rbd_dev->opts = opts; - /* get an id and fill in device name */ rbd_dev->dev_id = ida_simple_get(&rbd_dev_id_ida, 0, minor_to_rbd_dev_id(1 << MINORBITS), @@ -5610,6 +5597,10 @@ /* we have a ref from do_rbd_add() */ __module_get(THIS_MODULE); + rbd_dev->rbd_client = rbdc; + rbd_dev->spec = spec; + rbd_dev->opts = opts; + dout("%s rbd_dev %p dev_id %d\n", __func__, rbd_dev, rbd_dev->dev_id); return rbd_dev; @@ -5664,17 +5655,12 @@ return 0; } -static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) -{ - return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, - &rbd_dev->header.obj_order, - &rbd_dev->header.image_size); -} - -static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) +static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, + char **pobject_prefix) { size_t size; void *reply_buf; + char *object_prefix; int ret; void *p; @@ -5692,16 +5678,16 @@ goto out; p = reply_buf; - rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, - p + ret, NULL, GFP_NOIO); + object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, + GFP_NOIO); + if (IS_ERR(object_prefix)) { + ret = PTR_ERR(object_prefix); + goto out; + } ret = 0; - if (IS_ERR(rbd_dev->header.object_prefix)) { - ret = PTR_ERR(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - } else { - dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); - } + *pobject_prefix = object_prefix; + dout(" object_prefix = %s\n", object_prefix); out: kfree(reply_buf); @@ -5746,12 +5732,6 @@ return 0; } -static int rbd_dev_v2_features(struct rbd_device *rbd_dev) -{ - return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, - &rbd_dev->header.features); -} - /* * These are generic image flags, but since they are used only for * object map, store them in rbd_dev->object_map_flags. @@ -5788,6 +5768,14 @@ u64 overlap; }; +static void rbd_parent_info_cleanup(struct parent_image_info *pii) +{ + kfree(pii->pool_ns); + kfree(pii->image_id); + + memset(pii, 0, sizeof(*pii)); +} + /* * The caller is responsible for @pii. */ @@ -5857,6 +5845,9 @@ if (pii->has_overlap) ceph_decode_64_safe(&p, end, pii->overlap, e_inval); + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, + pii->has_overlap, pii->overlap); return 0; e_inval: @@ -5895,14 +5886,17 @@ pii->has_overlap = true; ceph_decode_64_safe(&p, end, pii->overlap, e_inval); + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, + pii->has_overlap, pii->overlap); return 0; e_inval: return -EINVAL; } -static int get_parent_info(struct rbd_device *rbd_dev, - struct parent_image_info *pii) +static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, + struct parent_image_info *pii) { struct page *req_page, *reply_page; void *p; @@ -5930,7 +5924,7 @@ return ret; } -static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) +static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) { struct rbd_spec *parent_spec; struct parent_image_info pii = { 0 }; @@ -5940,37 +5934,12 @@ if (!parent_spec) return -ENOMEM; - ret = get_parent_info(rbd_dev, &pii); + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); if (ret) goto out_err; - dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", - __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, - pii.has_overlap, pii.overlap); - - if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { - /* - * Either the parent never existed, or we have - * record of it but the image got flattened so it no - * longer has a parent. When the parent of a - * layered image disappears we immediately set the - * overlap to 0. The effect of this is that all new - * requests will be treated as if the image had no - * parent. - * - * If !pii.has_overlap, the parent image spec is not - * applicable. It's there to avoid duplication in each - * snapshot record. - */ - if (rbd_dev->parent_overlap) { - rbd_dev->parent_overlap = 0; - rbd_dev_parent_put(rbd_dev); - pr_info("%s: clone image has been flattened\n", - rbd_dev->disk->disk_name); - } - + if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) goto out; /* No parent? No problem. */ - } /* The ceph file layout needs to fit pool id in 32 bits */ @@ -5982,58 +5951,46 @@ } /* - * The parent won't change (except when the clone is - * flattened, already handled that). So we only need to - * record the parent spec we have not already done so. + * The parent won't change except when the clone is flattened, + * so we only need to record the parent image spec once. */ - if (!rbd_dev->parent_spec) { - parent_spec->pool_id = pii.pool_id; - if (pii.pool_ns && *pii.pool_ns) { - parent_spec->pool_ns = pii.pool_ns; - pii.pool_ns = NULL; - } - parent_spec->image_id = pii.image_id; - pii.image_id = NULL; - parent_spec->snap_id = pii.snap_id; - - rbd_dev->parent_spec = parent_spec; - parent_spec = NULL; /* rbd_dev now owns this */ - } + parent_spec->pool_id = pii.pool_id; + if (pii.pool_ns && *pii.pool_ns) { + parent_spec->pool_ns = pii.pool_ns; + pii.pool_ns = NULL; + } + parent_spec->image_id = pii.image_id; + pii.image_id = NULL; + parent_spec->snap_id = pii.snap_id; + + rbd_assert(!rbd_dev->parent_spec); + rbd_dev->parent_spec = parent_spec; + parent_spec = NULL; /* rbd_dev now owns this */ /* - * We always update the parent overlap. If it's zero we issue - * a warning, as we will proceed as if there was no parent. + * Record the parent overlap. If it's zero, issue a warning as + * we will proceed as if there is no parent. */ - if (!pii.overlap) { - if (parent_spec) { - /* refresh, careful to warn just once */ - if (rbd_dev->parent_overlap) - rbd_warn(rbd_dev, - "clone now standalone (overlap became 0)"); - } else { - /* initial probe */ - rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); - } - } + if (!pii.overlap) + rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); rbd_dev->parent_overlap = pii.overlap; out: ret = 0; out_err: - kfree(pii.pool_ns); - kfree(pii.image_id); + rbd_parent_info_cleanup(&pii); rbd_spec_put(parent_spec); return ret; } -static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) +static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, + u64 *stripe_unit, u64 *stripe_count) { struct { __le64 stripe_unit; __le64 stripe_count; } __attribute__ ((packed)) striping_info_buf = { 0 }; size_t size = sizeof (striping_info_buf); - void *p; int ret; ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, @@ -6045,27 +6002,33 @@ if (ret < size) return -ERANGE; - p = &striping_info_buf; - rbd_dev->header.stripe_unit = ceph_decode_64(&p); - rbd_dev->header.stripe_count = ceph_decode_64(&p); + *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); + *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); + dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, + *stripe_count); + return 0; } -static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) +static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) { - __le64 data_pool_id; + __le64 data_pool_buf; int ret; ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, &rbd_dev->header_oloc, "get_data_pool", - NULL, 0, &data_pool_id, sizeof(data_pool_id)); + NULL, 0, &data_pool_buf, + sizeof(data_pool_buf)); + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; - if (ret < sizeof(data_pool_id)) + if (ret < sizeof(data_pool_buf)) return -EBADMSG; - rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); - WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); + *data_pool_id = le64_to_cpu(data_pool_buf); + dout(" data_pool_id = %lld\n", *data_pool_id); + WARN_ON(*data_pool_id == CEPH_NOPOOL); + return 0; } @@ -6257,7 +6220,8 @@ return ret; } -static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) +static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, + struct ceph_snap_context **psnapc) { size_t size; int ret; @@ -6318,9 +6282,7 @@ for (i = 0; i < snap_count; i++) snapc->snaps[i] = ceph_decode_64(&p); - ceph_put_snap_context(rbd_dev->header.snapc); - rbd_dev->header.snapc = snapc; - + *psnapc = snapc; dout(" snap context seq = %llu, snap_count = %u\n", (unsigned long long)seq, (unsigned int)snap_count); out: @@ -6369,38 +6331,42 @@ return snap_name; } -static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { - bool first_time = rbd_dev->header.object_prefix == NULL; int ret; - ret = rbd_dev_v2_image_size(rbd_dev); + ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, + first_time ? &header->obj_order : NULL, + &header->image_size); if (ret) return ret; if (first_time) { - ret = rbd_dev_v2_header_onetime(rbd_dev); + ret = rbd_dev_v2_header_onetime(rbd_dev, header); if (ret) return ret; } - ret = rbd_dev_v2_snap_context(rbd_dev); - if (ret && first_time) { - kfree(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - } + ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); + if (ret) + return ret; - return ret; + return 0; } -static int rbd_dev_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); + rbd_assert(!header->object_prefix && !header->snapc); if (rbd_dev->image_format == 1) - return rbd_dev_v1_header_info(rbd_dev); + return rbd_dev_v1_header_info(rbd_dev, header, first_time); - return rbd_dev_v2_header_info(rbd_dev); + return rbd_dev_v2_header_info(rbd_dev, header, first_time); } /* @@ -6652,11 +6618,6 @@ return ret; } - /* - * The lock may have been released by now, unless automatic lock - * transitions are disabled. - */ - rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev)); return 0; } @@ -6750,60 +6711,49 @@ */ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) { - struct rbd_image_header *header; - rbd_dev_parent_put(rbd_dev); rbd_object_map_free(rbd_dev); rbd_dev_mapping_clear(rbd_dev); /* Free dynamic fields from the header, then zero it out */ - header = &rbd_dev->header; - ceph_put_snap_context(header->snapc); - kfree(header->snap_sizes); - kfree(header->snap_names); - kfree(header->object_prefix); - memset(header, 0, sizeof (*header)); + rbd_image_header_cleanup(&rbd_dev->header); } -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, + struct rbd_image_header *header) { int ret; - ret = rbd_dev_v2_object_prefix(rbd_dev); + ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); if (ret) - goto out_err; + return ret; /* * Get the and check features for the image. Currently the * features are assumed to never change. */ - ret = rbd_dev_v2_features(rbd_dev); + ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, + &header->features); if (ret) - goto out_err; + return ret; /* If the image supports fancy striping, get its parameters */ - if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { - ret = rbd_dev_v2_striping_info(rbd_dev); - if (ret < 0) - goto out_err; + if (header->features & RBD_FEATURE_STRIPINGV2) { + ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, + &header->stripe_count); + if (ret) + return ret; } - if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { - ret = rbd_dev_v2_data_pool(rbd_dev); + if (header->features & RBD_FEATURE_DATA_POOL) { + ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); if (ret) - goto out_err; + return ret; } - rbd_init_layout(rbd_dev); return 0; - -out_err: - rbd_dev->header.features = 0; - kfree(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - return ret; } /* @@ -6825,7 +6775,7 @@ goto out_err; } - parent = __rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec); + parent = __rbd_dev_create(rbd_dev->parent_spec); if (!parent) { ret = -ENOMEM; goto out_err; @@ -6835,8 +6785,8 @@ * Images related by parent/child relationships always share * rbd_client and spec/parent_spec, so bump their refcounts. */ - __rbd_get_client(rbd_dev->rbd_client); - rbd_spec_get(rbd_dev->parent_spec); + parent->rbd_client = __rbd_get_client(rbd_dev->rbd_client); + parent->spec = rbd_spec_get(rbd_dev->parent_spec); ret = rbd_dev_image_probe(parent, depth); if (ret < 0) @@ -6929,9 +6879,10 @@ static void rbd_dev_image_release(struct rbd_device *rbd_dev) { - rbd_dev_unprobe(rbd_dev); if (rbd_dev->opts) rbd_unregister_watch(rbd_dev); + + rbd_dev_unprobe(rbd_dev); rbd_dev->image_format = 0; kfree(rbd_dev->spec->image_id); rbd_dev->spec->image_id = NULL; @@ -6942,6 +6893,9 @@ * device. If this image is the one being mapped (i.e., not a * parent), initiate a watch on its header object before using that * object to get detailed information about the rbd image. + * + * On success, returns with header_rwsem held for write if called + * with @depth == 0. */ static int rbd_dev_image_probe(struct rbd_device *rbd_dev, int depth) { @@ -6974,9 +6928,14 @@ } } - ret = rbd_dev_header_info(rbd_dev); + if (!depth) + down_write(&rbd_dev->header_rwsem); + + ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); if (ret) - goto err_out_watch; + goto err_out_probe; + + rbd_init_layout(rbd_dev); /* * If this image is the one being mapped, we have pool name and @@ -7011,7 +6970,7 @@ } if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { - ret = rbd_dev_v2_parent_info(rbd_dev); + ret = rbd_dev_setup_parent(rbd_dev); if (ret) goto err_out_probe; } @@ -7025,10 +6984,11 @@ return 0; err_out_probe: - rbd_dev_unprobe(rbd_dev); -err_out_watch: + if (!depth) + up_write(&rbd_dev->header_rwsem); if (!depth) rbd_unregister_watch(rbd_dev); + rbd_dev_unprobe(rbd_dev); err_out_format: rbd_dev->image_format = 0; kfree(rbd_dev->spec->image_id); @@ -7036,6 +6996,112 @@ return ret; } +static void rbd_dev_update_header(struct rbd_device *rbd_dev, + struct rbd_image_header *header) +{ + rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); + rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ + + if (rbd_dev->header.image_size != header->image_size) { + rbd_dev->header.image_size = header->image_size; + + if (rbd_dev->spec->snap_id == CEPH_NOSNAP) { + rbd_dev->mapping.size = header->image_size; + rbd_dev_update_size(rbd_dev); + } + } + + if (rbd_dev->spec->snap_id != CEPH_NOSNAP) { + /* validate mapped snapshot's EXISTS flag */ + rbd_exists_validate(rbd_dev); + } + + ceph_put_snap_context(rbd_dev->header.snapc); + rbd_dev->header.snapc = header->snapc; + header->snapc = NULL; + + if (rbd_dev->image_format == 1) { + kfree(rbd_dev->header.snap_names); + rbd_dev->header.snap_names = header->snap_names; + header->snap_names = NULL; + + kfree(rbd_dev->header.snap_sizes); + rbd_dev->header.snap_sizes = header->snap_sizes; + header->snap_sizes = NULL; + } +} + +static void rbd_dev_update_parent(struct rbd_device *rbd_dev, + struct parent_image_info *pii) +{ + if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { + /* + * Either the parent never existed, or we have + * record of it but the image got flattened so it no + * longer has a parent. When the parent of a + * layered image disappears we immediately set the + * overlap to 0. The effect of this is that all new + * requests will be treated as if the image had no + * parent. + * + * If !pii.has_overlap, the parent image spec is not + * applicable. It's there to avoid duplication in each + * snapshot record. + */ + if (rbd_dev->parent_overlap) { + rbd_dev->parent_overlap = 0; + rbd_dev_parent_put(rbd_dev); + pr_info("%s: clone has been flattened\n", + rbd_dev->disk->disk_name); + } + } else { + rbd_assert(rbd_dev->parent_spec); + + /* + * Update the parent overlap. If it became zero, issue + * a warning as we will proceed as if there is no parent. + */ + if (!pii->overlap && rbd_dev->parent_overlap) + rbd_warn(rbd_dev, + "clone has become standalone (overlap 0)"); + rbd_dev->parent_overlap = pii->overlap; + } +} + +static int rbd_dev_refresh(struct rbd_device *rbd_dev) +{ + struct rbd_image_header header = { 0 }; + struct parent_image_info pii = { 0 }; + int ret; + + dout("%s rbd_dev %p\n", __func__, rbd_dev); + + ret = rbd_dev_header_info(rbd_dev, &header, false); + if (ret) + goto out; + + /* + * If there is a parent, see if it has disappeared due to the + * mapped image getting flattened. + */ + if (rbd_dev->parent) { + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); + if (ret) + goto out; + } + + down_write(&rbd_dev->header_rwsem); + rbd_dev_update_header(rbd_dev, &header); + if (rbd_dev->parent) + rbd_dev_update_parent(rbd_dev, &pii); + up_write(&rbd_dev->header_rwsem); + +out: + rbd_parent_info_cleanup(&pii); + rbd_image_header_cleanup(&header); + return ret; +} + static ssize_t do_rbd_add(struct bus_type *bus, const char *buf, size_t count) @@ -7047,6 +7113,9 @@ struct rbd_client *rbdc; int rc; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (!try_module_get(THIS_MODULE)) return -ENODEV; @@ -7085,12 +7154,9 @@ goto err_out_rbd_dev; } - down_write(&rbd_dev->header_rwsem); rc = rbd_dev_image_probe(rbd_dev, 0); - if (rc < 0) { - up_write(&rbd_dev->header_rwsem); + if (rc < 0) goto err_out_rbd_dev; - } /* If we are mapping a snapshot it must be marked read-only */ if (rbd_dev->spec->snap_id != CEPH_NOSNAP) @@ -7199,6 +7265,9 @@ bool force = false; int ret; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + dev_id = -1; opt_buf[0] = '\0'; sscanf(buf, "%d %5s", &dev_id, opt_buf); --- linux-oracle-5.4.0.orig/drivers/block/rsxx/core.c +++ linux-oracle-5.4.0/drivers/block/rsxx/core.c @@ -165,15 +165,17 @@ { struct rsxx_cardinfo *card = file_inode(fp)->i_private; char *buf; - ssize_t st; + int st; buf = kzalloc(cnt, GFP_KERNEL); if (!buf) return -ENOMEM; st = rsxx_creg_read(card, CREG_ADD_CRAM + (u32)*ppos, cnt, buf, 1); - if (!st) - st = copy_to_user(ubuf, buf, cnt); + if (!st) { + if (copy_to_user(ubuf, buf, cnt)) + st = -EFAULT; + } kfree(buf); if (st) return st; @@ -867,6 +869,7 @@ card->event_wq = create_singlethread_workqueue(DRIVER_NAME"_event"); if (!card->event_wq) { dev_err(CARD_TO_DEV(card), "Failed card event setup.\n"); + st = -ENOMEM; goto failed_event_handler; } --- linux-oracle-5.4.0.orig/drivers/block/skd_main.c +++ linux-oracle-5.4.0/drivers/block/skd_main.c @@ -1417,7 +1417,8 @@ case SKD_CHECK_STATUS_REPORT_GOOD: case SKD_CHECK_STATUS_REPORT_SMART_ALERT: skreq->status = BLK_STS_OK; - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); break; case SKD_CHECK_STATUS_BUSY_IMMINENT: @@ -1440,7 +1441,8 @@ case SKD_CHECK_STATUS_REPORT_ERROR: default: skreq->status = BLK_STS_IOERR; - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); break; } } @@ -1560,7 +1562,8 @@ */ if (likely(cmp_status == SAM_STAT_GOOD)) { skreq->status = BLK_STS_OK; - blk_mq_complete_request(rq); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); } else { skd_resolve_req_exception(skdev, skreq, rq); } --- linux-oracle-5.4.0.orig/drivers/block/sunvdc.c +++ linux-oracle-5.4.0/drivers/block/sunvdc.c @@ -983,6 +983,8 @@ print_version(); hp = mdesc_grab(); + if (!hp) + return -ENODEV; err = -ENODEV; if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) { --- linux-oracle-5.4.0.orig/drivers/block/virtio_blk.c +++ linux-oracle-5.4.0/drivers/block/virtio_blk.c @@ -33,6 +33,15 @@ } ____cacheline_aligned_in_smp; struct virtio_blk { + /* + * This mutex must be held by anything that may run after + * virtblk_remove() sets vblk->vdev to NULL. + * + * blk-mq, virtqueue processing, and sysfs attribute code paths are + * shut down before vblk->vdev is set to NULL and therefore do not need + * to hold this mutex. + */ + struct mutex vdev_mutex; struct virtio_device *vdev; /* The disk structure for the kernel. */ @@ -44,6 +53,13 @@ /* Process context for config space updates */ struct work_struct config_work; + /* + * Tracks references from block_device_operations open/release and + * virtio_driver probe/remove so this object can be freed once no + * longer in use. + */ + refcount_t refs; + /* What host tells us, plus 2 for header & tailer. */ unsigned int sg_elems; @@ -189,16 +205,31 @@ if (!range) return -ENOMEM; - __rq_for_each_bio(bio, req) { - u64 sector = bio->bi_iter.bi_sector; - u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT; - - range[n].flags = cpu_to_le32(flags); - range[n].num_sectors = cpu_to_le32(num_sectors); - range[n].sector = cpu_to_le64(sector); - n++; + /* + * Single max discard segment means multi-range discard isn't + * supported, and block layer only runs contiguity merge like + * normal RW request. So we can't reply on bio for retrieving + * each range info. + */ + if (queue_max_discard_segments(req->q) == 1) { + range[0].flags = cpu_to_le32(flags); + range[0].num_sectors = cpu_to_le32(blk_rq_sectors(req)); + range[0].sector = cpu_to_le64(blk_rq_pos(req)); + n = 1; + } else { + __rq_for_each_bio(bio, req) { + u64 sector = bio->bi_iter.bi_sector; + u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT; + + range[n].flags = cpu_to_le32(flags); + range[n].num_sectors = cpu_to_le32(num_sectors); + range[n].sector = cpu_to_le64(sector); + n++; + } } + WARN_ON_ONCE(n != segments); + req->special_vec.bv_page = virt_to_page(range); req->special_vec.bv_offset = offset_in_page(range); req->special_vec.bv_len = sizeof(*range) * segments; @@ -241,7 +272,8 @@ while ((vbr = virtqueue_get_buf(vblk->vqs[qid].vq, &len)) != NULL) { struct request *req = blk_mq_rq_from_pdu(vbr); - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); req_done = true; } if (unlikely(virtqueue_is_broken(vq))) @@ -339,13 +371,20 @@ err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); if (err) { virtqueue_kick(vblk->vqs[qid].vq); - blk_mq_stop_hw_queue(hctx); + /* Don't stop the queue if -ENOMEM: we may have failed to + * bounce the buffer due to global resource outage. + */ + if (err == -ENOSPC) + blk_mq_stop_hw_queue(hctx); spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); - /* Out of mem doesn't actually happen, since we fall back - * to direct descriptors */ - if (err == -ENOMEM || err == -ENOSPC) + switch (err) { + case -ENOSPC: return BLK_STS_DEV_RESOURCE; - return BLK_STS_IOERR; + case -ENOMEM: + return BLK_STS_RESOURCE; + default: + return BLK_STS_IOERR; + } } if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) @@ -381,10 +420,55 @@ return err; } +static void virtblk_get(struct virtio_blk *vblk) +{ + refcount_inc(&vblk->refs); +} + +static void virtblk_put(struct virtio_blk *vblk) +{ + if (refcount_dec_and_test(&vblk->refs)) { + ida_simple_remove(&vd_index_ida, vblk->index); + mutex_destroy(&vblk->vdev_mutex); + kfree(vblk); + } +} + +static int virtblk_open(struct block_device *bd, fmode_t mode) +{ + struct virtio_blk *vblk = bd->bd_disk->private_data; + int ret = 0; + + mutex_lock(&vblk->vdev_mutex); + + if (vblk->vdev) + virtblk_get(vblk); + else + ret = -ENXIO; + + mutex_unlock(&vblk->vdev_mutex); + return ret; +} + +static void virtblk_release(struct gendisk *disk, fmode_t mode) +{ + struct virtio_blk *vblk = disk->private_data; + + virtblk_put(vblk); +} + /* We provide getgeo only to please some old bootloader/partitioning tools */ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) { struct virtio_blk *vblk = bd->bd_disk->private_data; + int ret = 0; + + mutex_lock(&vblk->vdev_mutex); + + if (!vblk->vdev) { + ret = -ENXIO; + goto out; + } /* see if the host passed in geometry config */ if (virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_GEOMETRY)) { @@ -400,12 +484,16 @@ geo->sectors = 1 << 5; geo->cylinders = get_capacity(bd->bd_disk) >> 11; } - return 0; +out: + mutex_unlock(&vblk->vdev_mutex); + return ret; } static const struct block_device_operations virtblk_fops = { .ioctl = virtblk_ioctl, .owner = THIS_MODULE, + .open = virtblk_open, + .release = virtblk_release, .getgeo = virtblk_getgeo, }; @@ -760,6 +848,10 @@ goto out_free_index; } + /* This reference is dropped in virtblk_remove(). */ + refcount_set(&vblk->refs, 1); + mutex_init(&vblk->vdev_mutex); + vblk->vdev = vdev; vblk->sg_elems = sg_elems; @@ -845,9 +937,17 @@ err = virtio_cread_feature(vdev, VIRTIO_BLK_F_BLK_SIZE, struct virtio_blk_config, blk_size, &blk_size); - if (!err) + if (!err) { + err = blk_validate_block_size(blk_size); + if (err) { + dev_err(&vdev->dev, + "virtio_blk: invalid block size: 0x%x\n", + blk_size); + goto out_free_tags; + } + blk_queue_logical_block_size(q, blk_size); - else + } else blk_size = queue_logical_block_size(q); /* Use topology information if available */ @@ -877,11 +977,12 @@ blk_queue_io_opt(q, blk_size * opt_io_size); if (virtio_has_feature(vdev, VIRTIO_BLK_F_DISCARD)) { - q->limits.discard_granularity = blk_size; - virtio_cread(vdev, struct virtio_blk_config, discard_sector_alignment, &v); - q->limits.discard_alignment = v ? v << SECTOR_SHIFT : 0; + if (v) + q->limits.discard_granularity = v << SECTOR_SHIFT; + else + q->limits.discard_granularity = blk_size; virtio_cread(vdev, struct virtio_blk_config, max_discard_sectors, &v); @@ -889,9 +990,15 @@ virtio_cread(vdev, struct virtio_blk_config, max_discard_seg, &v); + + /* + * max_discard_seg == 0 is out of spec but we always + * handled it. + */ + if (!v) + v = sg_elems - 2; blk_queue_max_discard_segments(q, - min_not_zero(v, - MAX_DISCARD_SEGMENTS)); + min(v, MAX_DISCARD_SEGMENTS)); blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } @@ -914,6 +1021,7 @@ put_disk(vblk->disk); out_free_vq: vdev->config->del_vqs(vdev); + kfree(vblk->vqs); out_free_vblk: kfree(vblk); out_free_index: @@ -925,8 +1033,6 @@ static void virtblk_remove(struct virtio_device *vdev) { struct virtio_blk *vblk = vdev->priv; - int index = vblk->index; - int refc; /* Make sure no work handler is accessing the device. */ flush_work(&vblk->config_work); @@ -936,24 +1042,33 @@ blk_mq_free_tag_set(&vblk->tag_set); + mutex_lock(&vblk->vdev_mutex); + /* Stop all the virtqueues. */ vdev->config->reset(vdev); - refc = kref_read(&disk_to_dev(vblk->disk)->kobj.kref); + /* Virtqueues are stopped, nothing can use vblk->vdev anymore. */ + vblk->vdev = NULL; + put_disk(vblk->disk); vdev->config->del_vqs(vdev); kfree(vblk->vqs); - kfree(vblk); - /* Only free device id if we don't have any users */ - if (refc == 1) - ida_simple_remove(&vd_index_ida, index); + mutex_unlock(&vblk->vdev_mutex); + + virtblk_put(vblk); } #ifdef CONFIG_PM_SLEEP static int virtblk_freeze(struct virtio_device *vdev) { struct virtio_blk *vblk = vdev->priv; + struct request_queue *q = vblk->disk->queue; + + /* Ensure no requests in virtqueues before deleting vqs. */ + blk_mq_freeze_queue(q); + blk_mq_quiesce_queue_nowait(q); + blk_mq_unfreeze_queue(q); /* Ensure we don't receive any more interrupts */ vdev->config->reset(vdev); @@ -961,9 +1076,9 @@ /* Make sure no work handler is accessing the device. */ flush_work(&vblk->config_work); - blk_mq_quiesce_queue(vblk->disk->queue); - vdev->config->del_vqs(vdev); + kfree(vblk->vqs); + return 0; } @@ -977,8 +1092,8 @@ return ret; virtio_device_ready(vdev); - blk_mq_unquiesce_queue(vblk->disk->queue); + return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/block/xen-blkback/blkback.c +++ linux-oracle-5.4.0/drivers/block/xen-blkback/blkback.c @@ -202,7 +202,7 @@ #define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page))) -static int do_block_io_op(struct xen_blkif_ring *ring); +static int do_block_io_op(struct xen_blkif_ring *ring, unsigned int *eoi_flags); static int dispatch_rw_block_io(struct xen_blkif_ring *ring, struct blkif_request *req, struct pending_req *pending_req); @@ -615,6 +615,8 @@ struct xen_vbd *vbd = &blkif->vbd; unsigned long timeout; int ret; + bool do_eoi; + unsigned int eoi_flags = XEN_EOI_FLAG_SPURIOUS; set_freezable(); while (!kthread_should_stop()) { @@ -639,16 +641,23 @@ if (timeout == 0) goto purge_gnt_list; + do_eoi = ring->waiting_reqs; + ring->waiting_reqs = 0; smp_mb(); /* clear flag *before* checking for work */ - ret = do_block_io_op(ring); + ret = do_block_io_op(ring, &eoi_flags); if (ret > 0) ring->waiting_reqs = 1; if (ret == -EACCES) wait_event_interruptible(ring->shutdown_wq, kthread_should_stop()); + if (do_eoi && !ring->waiting_reqs) { + xen_irq_lateeoi(ring->irq, eoi_flags); + eoi_flags |= XEN_EOI_FLAG_SPURIOUS; + } + purge_gnt_list: if (blkif->vbd.feature_gnt_persistent && time_after(jiffies, ring->next_lru)) { @@ -841,8 +850,11 @@ pages[i]->page = persistent_gnt->page; pages[i]->persistent_gnt = persistent_gnt; } else { - if (get_free_page(ring, &pages[i]->page)) - goto out_of_memory; + if (get_free_page(ring, &pages[i]->page)) { + put_free_pages(ring, pages_to_gnt, segs_to_map); + ret = -ENOMEM; + goto out; + } addr = vaddr(pages[i]->page); pages_to_gnt[segs_to_map] = pages[i]->page; pages[i]->persistent_gnt = NULL; @@ -858,10 +870,8 @@ break; } - if (segs_to_map) { + if (segs_to_map) ret = gnttab_map_refs(map, NULL, pages_to_gnt, segs_to_map); - BUG_ON(ret); - } /* * Now swizzle the MFN in our domain with the MFN from the other domain @@ -876,7 +886,7 @@ pr_debug("invalid buffer -- could not remap it\n"); put_free_pages(ring, &pages[seg_idx]->page, 1); pages[seg_idx]->handle = BLKBACK_INVALID_HANDLE; - ret |= 1; + ret |= !ret; goto next; } pages[seg_idx]->handle = map[new_map_idx].handle; @@ -928,15 +938,18 @@ } segs_to_map = 0; last_map = map_until; - if (map_until != num) + if (!ret && map_until != num) goto again; - return ret; +out: + for (i = last_map; i < num; i++) { + /* Don't zap current batch's valid persistent grants. */ + if(i >= map_until) + pages[i]->persistent_gnt = NULL; + pages[i]->handle = BLKBACK_INVALID_HANDLE; + } -out_of_memory: - pr_alert("%s: out of memory\n", __func__); - put_free_pages(ring, pages_to_gnt, segs_to_map); - return -ENOMEM; + return ret; } static int xen_blkbk_map_seg(struct pending_req *pending_req) @@ -1119,7 +1132,7 @@ * and transmute it to the block API to hand it over to the proper block disk. */ static int -__do_block_io_op(struct xen_blkif_ring *ring) +__do_block_io_op(struct xen_blkif_ring *ring, unsigned int *eoi_flags) { union blkif_back_rings *blk_rings = &ring->blk_rings; struct blkif_request req; @@ -1142,6 +1155,9 @@ if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) break; + /* We've seen a request, so clear spurious eoi flag. */ + *eoi_flags &= ~XEN_EOI_FLAG_SPURIOUS; + if (kthread_should_stop()) { more_to_do = 1; break; @@ -1200,13 +1216,13 @@ } static int -do_block_io_op(struct xen_blkif_ring *ring) +do_block_io_op(struct xen_blkif_ring *ring, unsigned int *eoi_flags) { union blkif_back_rings *blk_rings = &ring->blk_rings; int more_to_do; do { - more_to_do = __do_block_io_op(ring); + more_to_do = __do_block_io_op(ring, eoi_flags); if (more_to_do) break; --- linux-oracle-5.4.0.orig/drivers/block/xen-blkback/common.h +++ linux-oracle-5.4.0/drivers/block/xen-blkback/common.h @@ -316,6 +316,7 @@ struct work_struct free_work; unsigned int nr_ring_pages; + bool multi_ref; /* All rings for this device. */ struct xen_blkif_ring *rings; unsigned int nr_rings; --- linux-oracle-5.4.0.orig/drivers/block/xen-blkback/xenbus.c +++ linux-oracle-5.4.0/drivers/block/xen-blkback/xenbus.c @@ -171,6 +171,15 @@ blkif->domid = domid; atomic_set(&blkif->refcnt, 1); init_completion(&blkif->drain_complete); + + /* + * Because freeing back to the cache may be deferred, it is not + * safe to unload the module (and hence destroy the cache) until + * this has completed. To prevent premature unloading, take an + * extra module reference here and release only when the object + * has been freed back to the cache. + */ + __module_get(THIS_MODULE); INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); return blkif; @@ -220,9 +229,8 @@ BUG(); } - err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn, - xen_blkif_be_int, 0, - "blkif-backend", ring); + err = bind_interdomain_evtchn_to_irqhandler_lateeoi(blkif->domid, + evtchn, xen_blkif_be_int, 0, "blkif-backend", ring); if (err < 0) { xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring); ring->blk_rings.common.sring = NULL; @@ -248,6 +256,7 @@ if (ring->xenblkd) { kthread_stop(ring->xenblkd); + ring->xenblkd = NULL; wake_up(&ring->shutdown_wq); } @@ -320,6 +329,7 @@ /* Make sure everything is drained before shutting down */ kmem_cache_free(xen_blkif_cachep, blkif); + module_put(THIS_MODULE); } int __init xen_blkif_interface_init(void) @@ -634,7 +644,8 @@ /* setup back pointer */ be->blkif->be = be; - err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed, + err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL, + backend_changed, "%s/%s", dev->nodename, "physical-device"); if (err) goto fail; @@ -938,14 +949,17 @@ for (i = 0; i < nr_grefs; i++) { char ring_ref_name[RINGREF_NAME_LEN]; - snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); + if (blkif->multi_ref) + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); + else { + WARN_ON(i != 0); + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref"); + } + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, "%u", &ring_ref[i]); if (err != 1) { - if (nr_grefs == 1) - break; - err = -EINVAL; xenbus_dev_fatal(dev, err, "reading %s/%s", dir, ring_ref_name); @@ -953,18 +967,6 @@ } } - if (err != 1) { - WARN_ON(nr_grefs != 1); - - err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", - &ring_ref[0]); - if (err != 1) { - err = -EINVAL; - xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); - return err; - } - } - err = -ENOMEM; for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { req = kzalloc(sizeof(*req), GFP_KERNEL); @@ -1068,10 +1070,15 @@ blkif->nr_rings, blkif->blk_protocol, protocol, pers_grants ? "persistent grants" : ""); - ring_page_order = xenbus_read_unsigned(dev->otherend, - "ring-page-order", 0); - - if (ring_page_order > xen_blkif_max_ring_order) { + err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", + &ring_page_order); + if (err != 1) { + blkif->nr_ring_pages = 1; + blkif->multi_ref = false; + } else if (ring_page_order <= xen_blkif_max_ring_order) { + blkif->nr_ring_pages = 1 << ring_page_order; + blkif->multi_ref = true; + } else { err = -EINVAL; xenbus_dev_fatal(dev, err, "requested ring page order %d exceed max:%d", @@ -1080,8 +1087,6 @@ return err; } - blkif->nr_ring_pages = 1 << ring_page_order; - if (blkif->nr_rings == 1) return read_per_ring_refs(&blkif->rings[0], dev->otherend); else { --- linux-oracle-5.4.0.orig/drivers/block/xen-blkfront.c +++ linux-oracle-5.4.0/drivers/block/xen-blkfront.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,7 @@ BLKIF_STATE_DISCONNECTED, BLKIF_STATE_CONNECTED, BLKIF_STATE_SUSPENDED, + BLKIF_STATE_ERROR, }; struct grant { @@ -88,6 +90,7 @@ }; enum blk_req_status { + REQ_PROCESSING, REQ_WAITING, REQ_DONE, REQ_ERROR, @@ -148,6 +151,10 @@ module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); +static bool __read_mostly xen_blkif_trusted = true; +module_param_named(trusted, xen_blkif_trusted, bool, 0644); +MODULE_PARM_DESC(trusted, "Is the backend trusted"); + #define BLK_RING_SIZE(info) \ __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) @@ -208,6 +215,7 @@ unsigned int feature_discard:1; unsigned int feature_secdiscard:1; unsigned int feature_persistent:1; + unsigned int bounce:1; unsigned int discard_granularity; unsigned int discard_alignment; /* Number of 4KB segments handled */ @@ -297,8 +305,8 @@ if (!gnt_list_entry) goto out_of_memory; - if (info->feature_persistent) { - granted_page = alloc_page(GFP_NOIO); + if (info->bounce) { + granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); if (!granted_page) { kfree(gnt_list_entry); goto out_of_memory; @@ -317,7 +325,7 @@ list_for_each_entry_safe(gnt_list_entry, n, &rinfo->grants, node) { list_del(&gnt_list_entry->node); - if (info->feature_persistent) + if (info->bounce) __free_page(gnt_list_entry->page); kfree(gnt_list_entry); i--; @@ -363,7 +371,7 @@ /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); - if (info->feature_persistent) + if (info->bounce) grant_foreign_access(gnt_list_entry, info); else { /* Grant access to the GFN passed by the caller */ @@ -387,7 +395,7 @@ /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); - if (!info->feature_persistent) { + if (!info->bounce) { struct page *indirect_page; /* Fetch a pre-allocated page to use for indirect grefs */ @@ -532,10 +540,10 @@ id = get_id_from_freelist(rinfo); rinfo->shadow[id].request = req; - rinfo->shadow[id].status = REQ_WAITING; + rinfo->shadow[id].status = REQ_PROCESSING; rinfo->shadow[id].associated_id = NO_ASSOCIATED_ID; - (*ring_req)->u.rw.id = id; + rinfo->shadow[id].req.u.rw.id = id; return id; } @@ -543,11 +551,12 @@ static int blkif_queue_discard_req(struct request *req, struct blkfront_ring_info *rinfo) { struct blkfront_info *info = rinfo->dev_info; - struct blkif_request *ring_req; + struct blkif_request *ring_req, *final_ring_req; unsigned long id; /* Fill out a communications ring structure. */ - id = blkif_ring_get_request(rinfo, req, &ring_req); + id = blkif_ring_get_request(rinfo, req, &final_ring_req); + ring_req = &rinfo->shadow[id].req; ring_req->operation = BLKIF_OP_DISCARD; ring_req->u.discard.nr_sectors = blk_rq_sectors(req); @@ -558,8 +567,9 @@ else ring_req->u.discard.flag = 0; - /* Keep a private copy so we can reissue requests when recovering. */ - rinfo->shadow[id].req = *ring_req; + /* Copy the request to the ring page. */ + *final_ring_req = *ring_req; + rinfo->shadow[id].status = REQ_WAITING; return 0; } @@ -692,6 +702,7 @@ { struct blkfront_info *info = rinfo->dev_info; struct blkif_request *ring_req, *extra_ring_req = NULL; + struct blkif_request *final_ring_req, *final_extra_ring_req = NULL; unsigned long id, extra_id = NO_ASSOCIATED_ID; bool require_extra_req = false; int i; @@ -699,7 +710,7 @@ .grant_idx = 0, .segments = NULL, .rinfo = rinfo, - .need_copy = rq_data_dir(req) && info->feature_persistent, + .need_copy = rq_data_dir(req) && info->bounce, }; /* @@ -736,7 +747,8 @@ } /* Fill out a communications ring structure. */ - id = blkif_ring_get_request(rinfo, req, &ring_req); + id = blkif_ring_get_request(rinfo, req, &final_ring_req); + ring_req = &rinfo->shadow[id].req; num_sg = blk_rq_map_sg(req->q, req, rinfo->shadow[id].sg); num_grant = 0; @@ -767,7 +779,8 @@ ring_req->u.rw.handle = info->handle; ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; - if (req_op(req) == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) { + if (req_op(req) == REQ_OP_FLUSH || + (req_op(req) == REQ_OP_WRITE && (req->cmd_flags & REQ_FUA))) { /* * Ideally we can do an unordered flush-to-disk. * In case the backend onlysupports barriers, use that. @@ -787,7 +800,9 @@ ring_req->u.rw.nr_segments = num_grant; if (unlikely(require_extra_req)) { extra_id = blkif_ring_get_request(rinfo, req, - &extra_ring_req); + &final_extra_ring_req); + extra_ring_req = &rinfo->shadow[extra_id].req; + /* * Only the first request contains the scatter-gather * list. @@ -829,10 +844,13 @@ if (setup.segments) kunmap_atomic(setup.segments); - /* Keep a private copy so we can reissue requests when recovering. */ - rinfo->shadow[id].req = *ring_req; - if (unlikely(require_extra_req)) - rinfo->shadow[extra_id].req = *extra_ring_req; + /* Copy request(s) to the ring page. */ + *final_ring_req = *ring_req; + rinfo->shadow[id].status = REQ_WAITING; + if (unlikely(require_extra_req)) { + *final_extra_ring_req = *extra_ring_req; + rinfo->shadow[extra_id].status = REQ_WAITING; + } if (new_persistent_gnts) gnttab_free_grant_references(setup.gref_head); @@ -935,7 +953,8 @@ if (info->feature_discard) { blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq); blk_queue_max_discard_sectors(rq, get_capacity(gd)); - rq->limits.discard_granularity = info->discard_granularity; + rq->limits.discard_granularity = info->discard_granularity ?: + info->physical_sector_size; rq->limits.discard_alignment = info->discard_alignment; if (info->feature_secdiscard) blk_queue_flag_set(QUEUE_FLAG_SECERASE, rq); @@ -1013,11 +1032,12 @@ { blk_queue_write_cache(info->rq, info->feature_flush ? true : false, info->feature_fua ? true : false); - pr_info("blkfront: %s: %s %s %s %s %s\n", + pr_info("blkfront: %s: %s %s %s %s %s %s %s\n", info->gd->disk_name, flush_info(info), "persistent grants:", info->feature_persistent ? "enabled;" : "disabled;", "indirect descriptors:", - info->max_indirect_segments ? "enabled;" : "disabled;"); + info->max_indirect_segments ? "enabled;" : "disabled;", + "bounce buffer:", info->bounce ? "enabled" : "disabled;"); } static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) @@ -1113,8 +1133,8 @@ if (!VDEV_IS_EXTENDED(info->vdevice)) { err = xen_translate_vdev(info->vdevice, &minor, &offset); if (err) - return err; - nr_parts = PARTS_PER_DISK; + return err; + nr_parts = PARTS_PER_DISK; } else { minor = BLKIF_MINOR_EXT(info->vdevice); nr_parts = PARTS_PER_EXT_DISK; @@ -1252,7 +1272,7 @@ if (!list_empty(&rinfo->indirect_pages)) { struct page *indirect_page, *n; - BUG_ON(info->feature_persistent); + BUG_ON(info->bounce); list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { list_del(&indirect_page->lru); __free_page(indirect_page); @@ -1269,7 +1289,7 @@ 0, 0UL); rinfo->persistent_gnts_c--; } - if (info->feature_persistent) + if (info->bounce) __free_page(persistent_gnt->page); kfree(persistent_gnt); } @@ -1290,7 +1310,7 @@ for (j = 0; j < segs; j++) { persistent_gnt = rinfo->shadow[i].grants_used[j]; gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); - if (info->feature_persistent) + if (info->bounce) __free_page(persistent_gnt->page); kfree(persistent_gnt); } @@ -1331,7 +1351,8 @@ rinfo->ring_ref[i] = GRANT_INVALID_REF; } } - free_pages((unsigned long)rinfo->ring.sring, get_order(info->nr_ring_pages * XEN_PAGE_SIZE)); + free_pages_exact(rinfo->ring.sring, + info->nr_ring_pages * XEN_PAGE_SIZE); rinfo->ring.sring = NULL; if (rinfo->irq) @@ -1405,8 +1426,8 @@ static int blkif_get_final_status(enum blk_req_status s1, enum blk_req_status s2) { - BUG_ON(s1 == REQ_WAITING); - BUG_ON(s2 == REQ_WAITING); + BUG_ON(s1 < REQ_DONE); + BUG_ON(s2 < REQ_DONE); if (s1 == REQ_ERROR || s2 == REQ_ERROR) return BLKIF_RSP_ERROR; @@ -1415,9 +1436,15 @@ return BLKIF_RSP_OKAY; } -static bool blkif_completion(unsigned long *id, - struct blkfront_ring_info *rinfo, - struct blkif_response *bret) +/* + * Return values: + * 1 response processed. + * 0 missing further responses. + * -1 error while processing. + */ +static int blkif_completion(unsigned long *id, + struct blkfront_ring_info *rinfo, + struct blkif_response *bret) { int i = 0; struct scatterlist *sg; @@ -1439,8 +1466,8 @@ s->status = blkif_rsp_to_req_status(bret->status); /* Wait the second response if not yet here. */ - if (s2->status == REQ_WAITING) - return false; + if (s2->status < REQ_DONE) + return 0; bret->status = blkif_get_final_status(s->status, s2->status); @@ -1473,7 +1500,7 @@ data.s = s; num_sg = s->num_sg; - if (bret->operation == BLKIF_OP_READ && info->feature_persistent) { + if (bret->operation == BLKIF_OP_READ && info->bounce) { for_each_sg(s->sg, sg, num_sg, i) { BUG_ON(sg->offset + sg->length > PAGE_SIZE); @@ -1491,47 +1518,48 @@ } /* Add the persistent grant into the list of free grants */ for (i = 0; i < num_grant; i++) { - if (gnttab_query_foreign_access(s->grants_used[i]->gref)) { + if (!gnttab_try_end_foreign_access(s->grants_used[i]->gref)) { /* * If the grant is still mapped by the backend (the * backend has chosen to make this grant persistent) * we add it at the head of the list, so it will be * reused first. */ - if (!info->feature_persistent) - pr_alert_ratelimited("backed has not unmapped grant: %u\n", - s->grants_used[i]->gref); + if (!info->feature_persistent) { + pr_alert("backed has not unmapped grant: %u\n", + s->grants_used[i]->gref); + return -1; + } list_add(&s->grants_used[i]->node, &rinfo->grants); rinfo->persistent_gnts_c++; } else { /* - * If the grant is not mapped by the backend we end the - * foreign access and add it to the tail of the list, - * so it will not be picked again unless we run out of - * persistent grants. + * If the grant is not mapped by the backend we add it + * to the tail of the list, so it will not be picked + * again unless we run out of persistent grants. */ - gnttab_end_foreign_access(s->grants_used[i]->gref, 0, 0UL); s->grants_used[i]->gref = GRANT_INVALID_REF; list_add_tail(&s->grants_used[i]->node, &rinfo->grants); } } if (s->req.operation == BLKIF_OP_INDIRECT) { for (i = 0; i < INDIRECT_GREFS(num_grant); i++) { - if (gnttab_query_foreign_access(s->indirect_grants[i]->gref)) { - if (!info->feature_persistent) - pr_alert_ratelimited("backed has not unmapped grant: %u\n", - s->indirect_grants[i]->gref); + if (!gnttab_try_end_foreign_access(s->indirect_grants[i]->gref)) { + if (!info->feature_persistent) { + pr_alert("backed has not unmapped grant: %u\n", + s->indirect_grants[i]->gref); + return -1; + } list_add(&s->indirect_grants[i]->node, &rinfo->grants); rinfo->persistent_gnts_c++; } else { struct page *indirect_page; - gnttab_end_foreign_access(s->indirect_grants[i]->gref, 0, 0UL); /* * Add the used indirect page back to the list of * available pages for indirect grefs. */ - if (!info->feature_persistent) { + if (!info->bounce) { indirect_page = s->indirect_grants[i]->page; list_add(&indirect_page->lru, &rinfo->indirect_pages); } @@ -1541,71 +1569,103 @@ } } - return true; + return 1; } static irqreturn_t blkif_interrupt(int irq, void *dev_id) { struct request *req; - struct blkif_response *bret; + struct blkif_response bret; RING_IDX i, rp; unsigned long flags; struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)dev_id; struct blkfront_info *info = rinfo->dev_info; + unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; - if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) + if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) { + xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); return IRQ_HANDLED; + } spin_lock_irqsave(&rinfo->ring_lock, flags); again: - rp = rinfo->ring.sring->rsp_prod; - rmb(); /* Ensure we see queued responses up to 'rp'. */ + rp = READ_ONCE(rinfo->ring.sring->rsp_prod); + virt_rmb(); /* Ensure we see queued responses up to 'rp'. */ + if (RING_RESPONSE_PROD_OVERFLOW(&rinfo->ring, rp)) { + pr_alert("%s: illegal number of responses %u\n", + info->gd->disk_name, rp - rinfo->ring.rsp_cons); + goto err; + } for (i = rinfo->ring.rsp_cons; i != rp; i++) { unsigned long id; + unsigned int op; + + eoiflag = 0; + + RING_COPY_RESPONSE(&rinfo->ring, i, &bret); + id = bret.id; - bret = RING_GET_RESPONSE(&rinfo->ring, i); - id = bret->id; /* * The backend has messed up and given us an id that we would * never have given to it (we stamp it up to BLK_RING_SIZE - * look in get_id_from_freelist. */ if (id >= BLK_RING_SIZE(info)) { - WARN(1, "%s: response to %s has incorrect id (%ld)\n", - info->gd->disk_name, op_name(bret->operation), id); - /* We can't safely get the 'struct request' as - * the id is busted. */ - continue; + pr_alert("%s: response has incorrect id (%ld)\n", + info->gd->disk_name, id); + goto err; } + if (rinfo->shadow[id].status != REQ_WAITING) { + pr_alert("%s: response references no pending request\n", + info->gd->disk_name); + goto err; + } + + rinfo->shadow[id].status = REQ_PROCESSING; req = rinfo->shadow[id].request; - if (bret->operation != BLKIF_OP_DISCARD) { + op = rinfo->shadow[id].req.operation; + if (op == BLKIF_OP_INDIRECT) + op = rinfo->shadow[id].req.u.indirect.indirect_op; + if (bret.operation != op) { + pr_alert("%s: response has wrong operation (%u instead of %u)\n", + info->gd->disk_name, bret.operation, op); + goto err; + } + + if (bret.operation != BLKIF_OP_DISCARD) { + int ret; + /* * We may need to wait for an extra response if the * I/O request is split in 2 */ - if (!blkif_completion(&id, rinfo, bret)) + ret = blkif_completion(&id, rinfo, &bret); + if (!ret) continue; + if (unlikely(ret < 0)) + goto err; } if (add_id_to_freelist(rinfo, id)) { WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n", - info->gd->disk_name, op_name(bret->operation), id); + info->gd->disk_name, op_name(bret.operation), id); continue; } - if (bret->status == BLKIF_RSP_OKAY) + if (bret.status == BLKIF_RSP_OKAY) blkif_req(req)->error = BLK_STS_OK; else blkif_req(req)->error = BLK_STS_IOERR; - switch (bret->operation) { + switch (bret.operation) { case BLKIF_OP_DISCARD: - if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { + if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) { struct request_queue *rq = info->rq; - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + + pr_warn_ratelimited("blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret.operation)); blkif_req(req)->error = BLK_STS_NOTSUPP; info->feature_discard = 0; info->feature_secdiscard = 0; @@ -1615,15 +1675,15 @@ break; case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_WRITE_BARRIER: - if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { - printk(KERN_WARNING "blkfront: %s: %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + if (unlikely(bret.status == BLKIF_RSP_EOPNOTSUPP)) { + pr_warn_ratelimited("blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret.operation)); blkif_req(req)->error = BLK_STS_NOTSUPP; } - if (unlikely(bret->status == BLKIF_RSP_ERROR && + if (unlikely(bret.status == BLKIF_RSP_ERROR && rinfo->shadow[id].req.u.rw.nr_segments == 0)) { - printk(KERN_WARNING "blkfront: %s: empty %s op failed\n", - info->gd->disk_name, op_name(bret->operation)); + pr_warn_ratelimited("blkfront: %s: empty %s op failed\n", + info->gd->disk_name, op_name(bret.operation)); blkif_req(req)->error = BLK_STS_NOTSUPP; } if (unlikely(blkif_req(req)->error)) { @@ -1636,16 +1696,18 @@ /* fall through */ case BLKIF_OP_READ: case BLKIF_OP_WRITE: - if (unlikely(bret->status != BLKIF_RSP_OKAY)) - dev_dbg(&info->xbdev->dev, "Bad return from blkdev data " - "request: %x\n", bret->status); + if (unlikely(bret.status != BLKIF_RSP_OKAY)) + dev_dbg_ratelimited(&info->xbdev->dev, + "Bad return from blkdev data request: %#x\n", + bret.status); break; default: BUG(); } - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); } rinfo->ring.rsp_cons = i; @@ -1662,6 +1724,18 @@ spin_unlock_irqrestore(&rinfo->ring_lock, flags); + xen_irq_lateeoi(irq, eoiflag); + + return IRQ_HANDLED; + + err: + info->connected = BLKIF_STATE_ERROR; + + spin_unlock_irqrestore(&rinfo->ring_lock, flags); + + /* No EOI in order to avoid further interrupts. */ + + pr_alert("%s disabled for further use\n", info->gd->disk_name); return IRQ_HANDLED; } @@ -1678,8 +1752,7 @@ for (i = 0; i < info->nr_ring_pages; i++) rinfo->ring_ref[i] = GRANT_INVALID_REF; - sring = (struct blkif_sring *)__get_free_pages(GFP_NOIO | __GFP_HIGH, - get_order(ring_size)); + sring = alloc_pages_exact(ring_size, GFP_NOIO | __GFP_ZERO); if (!sring) { xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); return -ENOMEM; @@ -1689,7 +1762,7 @@ err = xenbus_grant_ring(dev, rinfo->ring.sring, info->nr_ring_pages, gref); if (err < 0) { - free_pages((unsigned long)sring, get_order(ring_size)); + free_pages_exact(sring, ring_size); rinfo->ring.sring = NULL; goto fail; } @@ -1700,8 +1773,8 @@ if (err) goto fail; - err = bind_evtchn_to_irqhandler(rinfo->evtchn, blkif_interrupt, 0, - "blkif", rinfo); + err = bind_evtchn_to_irqhandler_lateeoi(rinfo->evtchn, blkif_interrupt, + 0, "blkif", rinfo); if (err <= 0) { xenbus_dev_fatal(dev, err, "bind_evtchn_to_irqhandler failed"); @@ -1782,6 +1855,10 @@ if (!info) return -ENODEV; + /* Check if backend is trusted. */ + info->bounce = !xen_blkif_trusted || + !xenbus_read_unsigned(dev->nodename, "trusted", 1); + max_page_order = xenbus_read_unsigned(info->xbdev->otherend, "max-ring-page-order", 0); ring_page_order = min(xen_blkif_max_ring_order, max_page_order); @@ -2168,19 +2245,12 @@ static void blkfront_setup_discard(struct blkfront_info *info) { - int err; - unsigned int discard_granularity; - unsigned int discard_alignment; - info->feature_discard = 1; - err = xenbus_gather(XBT_NIL, info->xbdev->otherend, - "discard-granularity", "%u", &discard_granularity, - "discard-alignment", "%u", &discard_alignment, - NULL); - if (!err) { - info->discard_granularity = discard_granularity; - info->discard_alignment = discard_alignment; - } + info->discard_granularity = xenbus_read_unsigned(info->xbdev->otherend, + "discard-granularity", + 0); + info->discard_alignment = xenbus_read_unsigned(info->xbdev->otherend, + "discard-alignment", 0); info->feature_secdiscard = !!xenbus_read_unsigned(info->xbdev->otherend, "discard-secure", 0); @@ -2188,10 +2258,12 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) { - unsigned int psegs, grants; + unsigned int psegs, grants, memflags; int err, i; struct blkfront_info *info = rinfo->dev_info; + memflags = memalloc_noio_save(); + if (info->max_indirect_segments == 0) { if (!HAS_EXTRA_REQ) grants = BLKIF_MAX_SEGMENTS_PER_REQUEST; @@ -2213,17 +2285,18 @@ if (err) goto out_of_memory; - if (!info->feature_persistent && info->max_indirect_segments) { + if (!info->bounce && info->max_indirect_segments) { /* - * We are using indirect descriptors but not persistent - * grants, we need to allocate a set of pages that can be + * We are using indirect descriptors but don't have a bounce + * buffer, we need to allocate a set of pages that can be * used for mapping indirect grefs */ int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); BUG_ON(!list_empty(&rinfo->indirect_pages)); for (i = 0; i < num; i++) { - struct page *indirect_page = alloc_page(GFP_NOIO); + struct page *indirect_page = alloc_page(GFP_KERNEL | + __GFP_ZERO); if (!indirect_page) goto out_of_memory; list_add(&indirect_page->lru, &rinfo->indirect_pages); @@ -2234,15 +2307,15 @@ rinfo->shadow[i].grants_used = kvcalloc(grants, sizeof(rinfo->shadow[i].grants_used[0]), - GFP_NOIO); + GFP_KERNEL); rinfo->shadow[i].sg = kvcalloc(psegs, sizeof(rinfo->shadow[i].sg[0]), - GFP_NOIO); + GFP_KERNEL); if (info->max_indirect_segments) rinfo->shadow[i].indirect_grants = kvcalloc(INDIRECT_GREFS(grants), sizeof(rinfo->shadow[i].indirect_grants[0]), - GFP_NOIO); + GFP_KERNEL); if ((rinfo->shadow[i].grants_used == NULL) || (rinfo->shadow[i].sg == NULL) || (info->max_indirect_segments && @@ -2251,6 +2324,7 @@ sg_init_table(rinfo->shadow[i].sg, psegs); } + memalloc_noio_restore(memflags); return 0; @@ -2270,6 +2344,9 @@ __free_page(indirect_page); } } + + memalloc_noio_restore(memflags); + return -ENOMEM; } @@ -2311,6 +2388,8 @@ info->feature_persistent = !!xenbus_read_unsigned(info->xbdev->otherend, "feature-persistent", 0); + if (info->feature_persistent) + info->bounce = true; indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, "feature-max-indirect-segments", 0); @@ -2668,11 +2747,10 @@ list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants, node) { if (gnt_list_entry->gref == GRANT_INVALID_REF || - gnttab_query_foreign_access(gnt_list_entry->gref)) + !gnttab_try_end_foreign_access(gnt_list_entry->gref)) continue; list_del(&gnt_list_entry->node); - gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL); rinfo->persistent_gnts_c--; gnt_list_entry->gref = GRANT_INVALID_REF; list_add_tail(&gnt_list_entry->node, &rinfo->grants); @@ -2687,6 +2765,13 @@ struct blkfront_info *info; bool need_schedule_work = false; + /* + * Note that when using bounce buffers but not persistent grants + * there's no need to run blkfront_delay_work because grants are + * revoked in blkif_completion or else an error is reported and the + * connection is closed. + */ + mutex_lock(&blkfront_mutex); list_for_each_entry(info, &info_list, info_list) { --- linux-oracle-5.4.0.orig/drivers/block/zram/zram_drv.c +++ linux-oracle-5.4.0/drivers/block/zram/zram_drv.c @@ -495,6 +495,12 @@ } nr_pages = i_size_read(inode) >> PAGE_SHIFT; + /* Refuse to use zero sized device (also prevents self reference) */ + if (!nr_pages) { + err = -EINVAL; + goto out; + } + bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long); bitmap = kvzalloc(bitmap_sz, GFP_KERNEL); if (!bitmap) { @@ -626,8 +632,8 @@ struct bio bio; struct bio_vec bio_vec; struct page *page; - ssize_t ret; - int mode; + ssize_t ret = len; + int mode, err; unsigned long blk_idx = 0; if (sysfs_streq(buf, "idle")) @@ -719,12 +725,17 @@ * XXX: A single page IO would be inefficient for write * but it would be not bad as starter. */ - ret = submit_bio_wait(&bio); - if (ret) { + err = submit_bio_wait(&bio); + if (err) { zram_slot_lock(zram, index); zram_clear_flag(zram, index, ZRAM_UNDER_WB); zram_clear_flag(zram, index, ZRAM_IDLE); zram_slot_unlock(zram, index); + /* + * Return last IO error unless every IO were + * not suceeded. + */ + ret = err; continue; } @@ -762,7 +773,6 @@ if (blk_idx) free_block_bdev(zram, blk_idx); - ret = len; __free_page(page); release_init_lock: up_read(&zram->init_lock); @@ -897,7 +907,7 @@ zram_test_flag(zram, index, ZRAM_HUGE) ? 'h' : '.', zram_test_flag(zram, index, ZRAM_IDLE) ? 'i' : '.'); - if (count < copied) { + if (count <= copied) { zram_slot_unlock(zram, index); break; } @@ -1073,7 +1083,7 @@ zram->limit_pages << PAGE_SHIFT, max_used << PAGE_SHIFT, (u64)atomic64_read(&zram->stats.same_pages), - pool_stats.pages_compacted, + atomic_long_read(&pool_stats.pages_compacted), (u64)atomic64_read(&zram->stats.huge_pages)); up_read(&zram->init_lock); @@ -2024,7 +2034,8 @@ return ret; return scnprintf(buf, PAGE_SIZE, "%d\n", ret); } -static CLASS_ATTR_RO(hot_add); +static struct class_attribute class_attr_hot_add = + __ATTR(hot_add, 0400, hot_add_show, NULL); static ssize_t hot_remove_store(struct class *class, struct class_attribute *attr, --- linux-oracle-5.4.0.orig/drivers/bluetooth/ath3k.c +++ linux-oracle-5.4.0/drivers/bluetooth/ath3k.c @@ -3,7 +3,6 @@ * Copyright (c) 2008-2009 Atheros Communications Inc. */ - #include #include #include @@ -129,7 +128,6 @@ * for AR3012 */ static const struct usb_device_id ath3k_blist_tbl[] = { - /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 }, @@ -203,7 +201,7 @@ #define TIMEGAP_USEC_MAX 100 static int ath3k_load_firmware(struct usb_device *udev, - const struct firmware *firmware) + const struct firmware *firmware) { u8 *send_buf; int len = 0; @@ -241,9 +239,9 @@ memcpy(send_buf, firmware->data + sent, size); err = usb_bulk_msg(udev, pipe, send_buf, size, - &len, 3000); + &len, 3000); - if (err || (len != size)) { + if (err || len != size) { ath3k_log_failed_loading(err, len, size, count); goto error; } @@ -278,7 +276,7 @@ } static int ath3k_get_version(struct usb_device *udev, - struct ath3k_version *version) + struct ath3k_version *version) { int ret, pipe = 0; struct ath3k_version *buf; @@ -300,7 +298,7 @@ } static int ath3k_load_fwfile(struct usb_device *udev, - const struct firmware *firmware) + const struct firmware *firmware) { u8 *send_buf; int len = 0; @@ -341,8 +339,8 @@ memcpy(send_buf, firmware->data + sent, size); err = usb_bulk_msg(udev, pipe, send_buf, size, - &len, 3000); - if (err || (len != size)) { + &len, 3000); + if (err || len != size) { ath3k_log_failed_loading(err, len, size, count); kfree(send_buf); return err; @@ -461,7 +459,6 @@ } switch (fw_version.ref_clock) { - case ATH3K_XTAL_FREQ_26M: clk_value = 26; break; @@ -477,7 +474,7 @@ } snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", - le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { @@ -492,7 +489,7 @@ } static int ath3k_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); @@ -541,10 +538,10 @@ if (ret < 0) { if (ret == -ENOENT) BT_ERR("Firmware file \"%s\" not found", - ATH3K_FIRMWARE); + ATH3K_FIRMWARE); else BT_ERR("Firmware file \"%s\" request failed (err=%d)", - ATH3K_FIRMWARE, ret); + ATH3K_FIRMWARE, ret); return ret; } --- linux-oracle-5.4.0.orig/drivers/bluetooth/bfusb.c +++ linux-oracle-5.4.0/drivers/bluetooth/bfusb.c @@ -629,6 +629,9 @@ data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); + if (!data->bulk_pkt_size) + goto done; + rwlock_init(&data->lock); data->reassembly = NULL; --- linux-oracle-5.4.0.orig/drivers/bluetooth/btbcm.c +++ linux-oracle-5.4.0/drivers/bluetooth/btbcm.c @@ -329,6 +329,7 @@ { 0x410e, "BCM43341B0" }, /* 002.001.014 */ { 0x4204, "BCM2076B1" }, /* 002.002.004 */ { 0x4406, "BCM4324B3" }, /* 002.004.006 */ + { 0x4606, "BCM4324B5" }, /* 002.006.006 */ { 0x6109, "BCM4335C0" }, /* 003.001.009 */ { 0x610c, "BCM4354" }, /* 003.001.012 */ { 0x2122, "BCM4343A0" }, /* 001.001.034 */ @@ -343,6 +344,7 @@ }; static const struct bcm_subver_table bcm_usb_subver_table[] = { + { 0x2105, "BCM20703A1" }, /* 001.001.005 */ { 0x210b, "BCM43142A0" }, /* 001.001.011 */ { 0x2112, "BCM4314A0" }, /* 001.001.018 */ { 0x2118, "BCM20702A0" }, /* 001.001.024 */ @@ -440,6 +442,12 @@ set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); + /* Some devices ship with the controller default address. + * Allow the bootloader to set a valid address through the + * device tree. + */ + set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks); + return 0; } EXPORT_SYMBOL_GPL(btbcm_finalize); --- linux-oracle-5.4.0.orig/drivers/bluetooth/btintel.c +++ linux-oracle-5.4.0/drivers/bluetooth/btintel.c @@ -346,7 +346,7 @@ return PTR_ERR(skb); } - if (skb->len != sizeof(*ver)) { + if (!skb || skb->len != sizeof(*ver)) { bt_dev_err(hdev, "Intel version event size mismatch"); kfree_skb(skb); return -EILSEQ; --- linux-oracle-5.4.0.orig/drivers/bluetooth/btmrvl_sdio.c +++ linux-oracle-5.4.0/drivers/bluetooth/btmrvl_sdio.c @@ -105,13 +105,15 @@ } else { ret = devm_request_irq(dev, cfg->irq_bt, btmrvl_wake_irq_bt, - 0, "bt_wake", card); + IRQF_NO_AUTOEN, "bt_wake", card); if (ret) { dev_err(dev, "Failed to request irq_bt %d (%d)\n", cfg->irq_bt, ret); } - disable_irq(cfg->irq_bt); + + /* Configure wakeup (enabled by default) */ + device_init_wakeup(dev, true); } } @@ -328,7 +330,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = { .helper = NULL, - .firmware = "mrvl/sd8977_uapsta.bin", + .firmware = "mrvl/sdsd8977_combo_v2.bin", .reg = &btmrvl_reg_8977, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, @@ -346,7 +348,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = { .helper = NULL, - .firmware = "mrvl/sd8997_uapsta.bin", + .firmware = "mrvl/sdsd8997_combo_v4.bin", .reg = &btmrvl_reg_8997, .support_pscan_win_report = true, .sd_blksz_fw_dl = 256, @@ -1654,6 +1656,7 @@ MODULE_SHUTDOWN_REQ); btmrvl_sdio_disable_host_int(card); } + BT_DBG("unregister dev"); card->priv->surprise_removed = true; btmrvl_sdio_unregister_dev(card); @@ -1690,7 +1693,8 @@ } /* Enable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { + if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { card->plt_wake_cfg->wake_by_bt = false; enable_irq(card->plt_wake_cfg->irq_bt); enable_irq_wake(card->plt_wake_cfg->irq_bt); @@ -1707,7 +1711,8 @@ BT_ERR("HS not activated, suspend failed!"); /* Disable platform specific wakeup interrupt */ if (card->plt_wake_cfg && - card->plt_wake_cfg->irq_bt >= 0) { + card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt); } @@ -1767,7 +1772,8 @@ hci_resume_dev(hcidev); /* Disable platform specific wakeup interrupt */ - if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0) { + if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 && + device_may_wakeup(dev)) { disable_irq_wake(card->plt_wake_cfg->irq_bt); disable_irq(card->plt_wake_cfg->irq_bt); if (card->plt_wake_cfg->wake_by_bt) @@ -1831,6 +1837,6 @@ MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); -MODULE_FIRMWARE("mrvl/sd8977_uapsta.bin"); +MODULE_FIRMWARE("mrvl/sdsd8977_combo_v2.bin"); MODULE_FIRMWARE("mrvl/sd8987_uapsta.bin"); -MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin"); +MODULE_FIRMWARE("mrvl/sdsd8997_combo_v4.bin"); --- linux-oracle-5.4.0.orig/drivers/bluetooth/btmtksdio.c +++ linux-oracle-5.4.0/drivers/bluetooth/btmtksdio.c @@ -684,7 +684,7 @@ const u8 *fw_ptr; size_t fw_size; int err, dlen; - u8 flag; + u8 flag, param; err = request_firmware(&fw, fwname, &hdev->dev); if (err < 0) { @@ -692,6 +692,20 @@ return err; } + /* Power on data RAM the firmware relies on. */ + param = 1; + wmt_params.op = MTK_WMT_FUNC_CTRL; + wmt_params.flag = 3; + wmt_params.dlen = sizeof(param); + wmt_params.data = ¶m; + wmt_params.status = NULL; + + err = mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); + goto free_fw; + } + fw_ptr = fw->data; fw_size = fw->size; @@ -966,6 +980,8 @@ hdev->manufacturer = 70; set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); + sdio_set_drvdata(func, bdev); + err = hci_register_dev(hdev); if (err < 0) { dev_err(&func->dev, "Can't register HCI device\n"); @@ -973,8 +989,6 @@ return err; } - sdio_set_drvdata(func, bdev); - /* pm_runtime_enable would be done after the firmware is being * downloaded because the core layer probably already enables * runtime PM for this func such as the case host->caps & @@ -1027,6 +1041,8 @@ if (!bdev) return 0; + sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); + sdio_claim_host(bdev->func); sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err); --- linux-oracle-5.4.0.orig/drivers/bluetooth/btmtkuart.c +++ linux-oracle-5.4.0/drivers/bluetooth/btmtkuart.c @@ -158,8 +158,10 @@ int err; hlen = sizeof(*hdr) + wmt_params->dlen; - if (hlen > 255) - return -EINVAL; + if (hlen > 255) { + err = -EINVAL; + goto err_free_skb; + } hdr = (struct mtk_wmt_hdr *)&wc; hdr->dir = 1; @@ -173,7 +175,7 @@ err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); if (err < 0) { clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return err; + goto err_free_skb; } /* The vendor specific WMT commands are all answered by a vendor @@ -190,13 +192,14 @@ if (err == -EINTR) { bt_dev_err(hdev, "Execution of wmt command interrupted"); clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return err; + goto err_free_skb; } if (err) { bt_dev_err(hdev, "Execution of wmt command timed out"); clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); - return -ETIMEDOUT; + err = -ETIMEDOUT; + goto err_free_skb; } /* Parse and handle the return WMT event */ @@ -468,7 +471,7 @@ return data; } -static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) +static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) { struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); const unsigned char *p_left = data, *p_h4; @@ -507,25 +510,20 @@ bt_dev_err(bdev->hdev, "Frame reassembly failed (%d)", err); bdev->rx_skb = NULL; - return err; + return; } sz_left -= sz_h4; p_left += sz_h4; } - - return 0; } static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, size_t count) { struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); - int err; - err = btmtkuart_recv(bdev->hdev, data, count); - if (err < 0) - return err; + btmtkuart_recv(bdev->hdev, data, count); bdev->hdev->stat.byte_rx += count; @@ -1015,7 +1013,7 @@ if (btmtkuart_is_standalone(bdev)) { err = clk_prepare_enable(bdev->osc); if (err < 0) - return err; + goto err_hci_free_dev; if (bdev->boot) { gpiod_set_value_cansleep(bdev->boot, 1); @@ -1028,10 +1026,8 @@ /* Power on */ err = regulator_enable(bdev->vcc); - if (err < 0) { - clk_disable_unprepare(bdev->osc); - return err; - } + if (err < 0) + goto err_clk_disable_unprepare; /* Reset if the reset-gpios is available otherwise the board * -level design should be guaranteed. @@ -1063,7 +1059,6 @@ err = hci_register_dev(hdev); if (err < 0) { dev_err(&serdev->dev, "Can't register HCI device\n"); - hci_free_dev(hdev); goto err_regulator_disable; } @@ -1072,6 +1067,11 @@ err_regulator_disable: if (btmtkuart_is_standalone(bdev)) regulator_disable(bdev->vcc); +err_clk_disable_unprepare: + if (btmtkuart_is_standalone(bdev)) + clk_disable_unprepare(bdev->osc); +err_hci_free_dev: + hci_free_dev(hdev); return err; } --- linux-oracle-5.4.0.orig/drivers/bluetooth/btqcomsmd.c +++ linux-oracle-5.4.0/drivers/bluetooth/btqcomsmd.c @@ -122,6 +122,21 @@ return 0; } +static int btqcomsmd_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) +{ + int ret; + + ret = qca_set_bdaddr_rome(hdev, bdaddr); + if (ret) + return ret; + + /* The firmware stops responding for a while after setting the bdaddr, + * causing timeouts for subsequent commands. Sleep a bit to avoid this. + */ + usleep_range(1000, 10000); + return 0; +} + static int btqcomsmd_probe(struct platform_device *pdev) { struct btqcomsmd *btq; @@ -142,12 +157,16 @@ btq->cmd_channel = qcom_wcnss_open_channel(wcnss, "APPS_RIVA_BT_CMD", btqcomsmd_cmd_callback, btq); - if (IS_ERR(btq->cmd_channel)) - return PTR_ERR(btq->cmd_channel); + if (IS_ERR(btq->cmd_channel)) { + ret = PTR_ERR(btq->cmd_channel); + goto destroy_acl_channel; + } hdev = hci_alloc_dev(); - if (!hdev) - return -ENOMEM; + if (!hdev) { + ret = -ENOMEM; + goto destroy_cmd_channel; + } hci_set_drvdata(hdev, btq); btq->hdev = hdev; @@ -158,17 +177,24 @@ hdev->close = btqcomsmd_close; hdev->send = btqcomsmd_send; hdev->setup = btqcomsmd_setup; - hdev->set_bdaddr = qca_set_bdaddr_rome; + hdev->set_bdaddr = btqcomsmd_set_bdaddr; ret = hci_register_dev(hdev); - if (ret < 0) { - hci_free_dev(hdev); - return ret; - } + if (ret < 0) + goto hci_free_dev; platform_set_drvdata(pdev, btq); return 0; + +hci_free_dev: + hci_free_dev(hdev); +destroy_cmd_channel: + rpmsg_destroy_ept(btq->cmd_channel); +destroy_acl_channel: + rpmsg_destroy_ept(btq->acl_channel); + + return ret; } static int btqcomsmd_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/bluetooth/btrtl.c +++ linux-oracle-5.4.0/drivers/bluetooth/btrtl.c @@ -55,6 +55,7 @@ int fw_len; u8 *cfg_data; int cfg_len; + bool drop_fw; }; static const struct id_table ic_id_table[] = { @@ -130,12 +131,19 @@ .cfg_name = "rtl_bt/rtl8821c_config" }, /* 8761A */ - { IC_MATCH_FL_LMPSUBV, RTL_ROM_LMP_8761A, 0x0, + { IC_INFO(RTL_ROM_LMP_8761A, 0xa), .config_needed = false, .has_rom_version = true, .fw_name = "rtl_bt/rtl8761a_fw.bin", .cfg_name = "rtl_bt/rtl8761a_config" }, + /* 8761B */ + { IC_INFO(RTL_ROM_LMP_8761A, 0xb), + .config_needed = false, + .has_rom_version = true, + .fw_name = "rtl_bt/rtl8761b_fw.bin", + .cfg_name = "rtl_bt/rtl8761b_config" }, + /* 8822C with USB interface */ { IC_INFO(RTL_ROM_LMP_8822B, 0xc), .config_needed = false, @@ -255,6 +263,7 @@ { RTL_ROM_LMP_8723B, 9 }, /* 8723D */ { RTL_ROM_LMP_8821A, 10 }, /* 8821C */ { RTL_ROM_LMP_8822B, 13 }, /* 8822C */ + { RTL_ROM_LMP_8761A, 14 }, /* 8761B */ }; min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3; @@ -370,11 +379,11 @@ * the end. */ len = patch_length; - buf = kmemdup(btrtl_dev->fw_data + patch_offset, patch_length, - GFP_KERNEL); + buf = kvmalloc(patch_length, GFP_KERNEL); if (!buf) return -ENOMEM; + memcpy(buf, btrtl_dev->fw_data + patch_offset, patch_length - 4); memcpy(buf + patch_length - 4, &epatch_info->fw_version, 4); *_buf = buf; @@ -460,8 +469,10 @@ if (ret < 0) return ret; ret = fw->size; - *buff = kmemdup(fw->data, ret, GFP_KERNEL); - if (!*buff) + *buff = kvmalloc(fw->size, GFP_KERNEL); + if (*buff) + memcpy(*buff, fw->data, ret); + else ret = -ENOMEM; release_firmware(fw); @@ -499,14 +510,14 @@ goto out; if (btrtl_dev->cfg_len > 0) { - tbuff = kzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL); + tbuff = kvzalloc(ret + btrtl_dev->cfg_len, GFP_KERNEL); if (!tbuff) { ret = -ENOMEM; goto out; } memcpy(tbuff, fw_data, ret); - kfree(fw_data); + kvfree(fw_data); memcpy(tbuff + ret, btrtl_dev->cfg_data, btrtl_dev->cfg_len); ret += btrtl_dev->cfg_len; @@ -519,14 +530,14 @@ ret = rtl_download_firmware(hdev, fw_data, ret); out: - kfree(fw_data); + kvfree(fw_data); return ret; } void btrtl_free(struct btrtl_device_info *btrtl_dev) { - kfree(btrtl_dev->fw_data); - kfree(btrtl_dev->cfg_data); + kvfree(btrtl_dev->fw_data); + kvfree(btrtl_dev->cfg_data); kfree(btrtl_dev); } EXPORT_SYMBOL_GPL(btrtl_free); @@ -541,6 +552,8 @@ u16 hci_rev, lmp_subver; u8 hci_ver; int ret; + u16 opcode; + u8 cmd[2]; btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); if (!btrtl_dev) { @@ -562,6 +575,49 @@ hci_ver = resp->hci_ver; hci_rev = le16_to_cpu(resp->hci_rev); lmp_subver = le16_to_cpu(resp->lmp_subver); + + if (resp->hci_ver == 0x8 && le16_to_cpu(resp->hci_rev) == 0x826c && + resp->lmp_ver == 0x8 && le16_to_cpu(resp->lmp_subver) == 0xa99e) + btrtl_dev->drop_fw = true; + + if (btrtl_dev->drop_fw) { + opcode = hci_opcode_pack(0x3f, 0x66); + cmd[0] = opcode & 0xff; + cmd[1] = opcode >> 8; + + skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); + if (!skb) + goto out_free; + + skb_put_data(skb, cmd, sizeof(cmd)); + hci_skb_pkt_type(skb) = HCI_COMMAND_PKT; + + hdev->send(hdev, skb); + + /* Ensure the above vendor command is sent to controller and + * process has done. + */ + msleep(200); + + /* Read the local version again. Expect to have the vanilla + * version as cold boot. + */ + skb = btrtl_read_local_version(hdev); + if (IS_ERR(skb)) { + ret = PTR_ERR(skb); + goto err_free; + } + + resp = (struct hci_rp_read_local_version *)skb->data; + rtl_dev_info(hdev, "examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x lmp_subver=%04x", + resp->hci_ver, resp->hci_rev, + resp->lmp_ver, resp->lmp_subver); + + hci_ver = resp->hci_ver; + hci_rev = le16_to_cpu(resp->hci_rev); + lmp_subver = le16_to_cpu(resp->lmp_subver); + } +out_free: kfree_skb(skb); btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver, --- linux-oracle-5.4.0.orig/drivers/bluetooth/btsdio.c +++ linux-oracle-5.4.0/drivers/bluetooth/btsdio.c @@ -346,6 +346,7 @@ if (!data) return; + cancel_work_sync(&data->work); hdev = data->hdev; sdio_set_drvdata(func, NULL); --- linux-oracle-5.4.0.orig/drivers/bluetooth/btusb.c +++ linux-oracle-5.4.0/drivers/bluetooth/btusb.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #define BTUSB_IFNUM_2 0x80000 #define BTUSB_CW6622 0x100000 #define BTUSB_MEDIATEK 0x200000 +#define BTUSB_WIDEBAND_SPEECH 0x400000 static const struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ @@ -332,20 +334,50 @@ { USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL }, /* Intel Bluetooth devices */ - { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW }, - { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW }, - { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW }, + { USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_NEW | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_NEW | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x8087, 0x0029), .driver_info = BTUSB_INTEL_NEW | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL }, - { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW }, - { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL }, - { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW }, + { USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_NEW | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_NEW | + BTUSB_WIDEBAND_SPEECH }, /* Other Intel Bluetooth devices */ { USB_VENDOR_AND_INTERFACE_INFO(0x8087, 0xe0, 0x01, 0x01), .driver_info = BTUSB_IGNORE }, + /* Realtek 8822CE Bluetooth devices */ + { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + + /* Realtek 8852BE Bluetooth devices */ + { USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0x4853), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe123), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + /* Realtek Bluetooth devices */ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), .driver_info = BTUSB_REALTEK }, @@ -373,6 +405,10 @@ { USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK }, + /* Additional Realtek 8761BU Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x190e), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + /* Additional Realtek 8821AE Bluetooth devices */ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK }, @@ -563,13 +599,13 @@ spin_lock_irqsave(&data->rxlock, flags); - kfree_skb(data->evt_skb); + dev_kfree_skb_irq(data->evt_skb); data->evt_skb = NULL; - kfree_skb(data->acl_skb); + dev_kfree_skb_irq(data->acl_skb); data->acl_skb = NULL; - kfree_skb(data->sco_skb); + dev_kfree_skb_irq(data->sco_skb); data->sco_skb = NULL; spin_unlock_irqrestore(&data->rxlock, flags); @@ -805,7 +841,15 @@ if (!urb) return -ENOMEM; - size = le16_to_cpu(data->intr_ep->wMaxPacketSize); + if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && + le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) + /* Fake CSR devices don't seem to support sort-transter */ + size = le16_to_cpu(data->intr_ep->wMaxPacketSize); + else + /* Use maximum HCI Event size so the USB stack handles + * ZPL/short-transfer automatically. + */ + size = HCI_MAX_EVENT_SIZE; buf = kmalloc(size, mem_flags); if (!buf) { @@ -1200,7 +1244,7 @@ if (data->setup_on_usb) { err = data->setup_on_usb(hdev); if (err < 0) - return err; + goto setup_fail; } data->intf->needs_remote_wakeup = 1; @@ -1239,6 +1283,7 @@ failed: clear_bit(BTUSB_INTR_RUNNING, &data->flags); +setup_fail: usb_autopm_put_interface(data->intf); return err; } @@ -2567,7 +2612,8 @@ skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC); if (!skb) { hdev->stat.err_rx++; - goto err_out; + kfree(urb->setup_packet); + return; } hci_skb_pkt_type(skb) = HCI_EVENT_PKT; @@ -2584,14 +2630,21 @@ * and being processed the events from there then. */ if (test_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags)) { - data->evt_skb = skb_clone(skb, GFP_KERNEL); - if (!data->evt_skb) - goto err_out; + data->evt_skb = skb_clone(skb, GFP_ATOMIC); + if (!data->evt_skb) { + kfree_skb(skb); + kfree(urb->setup_packet); + return; + } } err = hci_recv_frame(hdev, skb); - if (err < 0) - goto err_free_skb; + if (err < 0) { + kfree_skb(data->evt_skb); + data->evt_skb = NULL; + kfree(urb->setup_packet); + return; + } if (test_and_clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags)) { @@ -2600,11 +2653,7 @@ wake_up_bit(&data->flags, BTUSB_TX_WAIT_VND_EVT); } -err_out: - return; -err_free_skb: - kfree_skb(data->evt_skb); - data->evt_skb = NULL; + kfree(urb->setup_packet); return; } else if (urb->status == -ENOENT) { /* Avoid suspend failed when usb_kill_urb */ @@ -2625,6 +2674,7 @@ usb_anchor_urb(urb, &data->ctrl_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { + kfree(urb->setup_packet); /* -EPERM: urb is being killed; * -ENODEV: device got disconnected */ @@ -2663,6 +2713,7 @@ buf = kmalloc(size, GFP_KERNEL); if (!buf) { kfree(dr); + usb_free_urb(urb); return -ENOMEM; } @@ -2698,11 +2749,6 @@ struct btmtk_wmt_hdr *hdr; int err; - /* Submit control IN URB on demand to process the WMT event */ - err = btusb_mtk_submit_wmt_recv_urb(hdev); - if (err < 0) - return err; - /* Send the WMT command and wait until the WMT event returns */ hlen = sizeof(*hdr) + wmt_params->dlen; if (hlen > 255) @@ -2724,6 +2770,11 @@ return err; } + /* Submit control IN URB on demand to process the WMT event */ + err = btusb_mtk_submit_wmt_recv_urb(hdev); + if (err < 0) + return err; + /* The vendor specific WMT commands are all answered by a vendor * specific event and will have the Command Status or Command * Complete as with usual HCI command flow control. @@ -2791,7 +2842,7 @@ const u8 *fw_ptr; size_t fw_size; int err, dlen; - u8 flag; + u8 flag, param; err = request_firmware(&fw, fwname, &hdev->dev); if (err < 0) { @@ -2799,6 +2850,20 @@ return err; } + /* Power on data RAM the firmware relies on. */ + param = 1; + wmt_params.op = BTMTK_WMT_FUNC_CTRL; + wmt_params.flag = 3; + wmt_params.dlen = sizeof(param); + wmt_params.data = ¶m; + wmt_params.status = NULL; + + err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); + if (err < 0) { + bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); + goto err_release_fw; + } + fw_ptr = fw->data; fw_size = fw->size; @@ -2849,7 +2914,7 @@ err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); if (err < 0) { bt_dev_err(hdev, "Failed to send wmt rst (%d)", err); - return err; + goto err_release_fw; } /* Wait a few moments for firmware activation done */ @@ -3120,6 +3185,35 @@ return 0; } +#define BTUSB_EDGE_LED_COMMAND 0xfc77 + +static void btusb_edge_set_led(struct hci_dev *hdev, bool state) +{ + struct sk_buff *skb; + u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 }; + + if (state) + config_led[1] = 0x01; + + skb = __hci_cmd_sync(hdev, BTUSB_EDGE_LED_COMMAND, sizeof(config_led), config_led, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) + BT_ERR("%s fail to set LED (%ld)", hdev->name, PTR_ERR(skb)); + else + kfree_skb(skb); +} + +static int btusb_edge_post_init(struct hci_dev *hdev) +{ + btusb_edge_set_led(hdev, true); + return 0; +} + +static int btusb_edge_shutdown(struct hci_dev *hdev) +{ + btusb_edge_set_led(hdev, false); + return 0; +} + static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev, const bdaddr_t *bdaddr) { @@ -3247,6 +3341,11 @@ sent += size; count -= size; + /* ep2 need time to switch from function acl to function dfu, + * so we add 20ms delay here. + */ + msleep(20); + while (count) { size = min_t(size_t, count, QCA_DFU_PACKET_LEN); @@ -3771,8 +3870,18 @@ set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks); } - if (id->driver_info & BTUSB_MARVELL) + if (id->driver_info & BTUSB_MARVELL) { + struct pci_dev *pdev; hdev->set_bdaddr = btusb_set_bdaddr_marvell; + pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); + if (!pdev) + pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); + if (pdev) { + pci_dev_put(pdev); + hdev->post_init = btusb_edge_post_init; + hdev->shutdown = btusb_edge_shutdown; + } + } #ifdef CONFIG_BT_HCIBTUSB_MTK if (id->driver_info & BTUSB_MEDIATEK) { @@ -3807,8 +3916,8 @@ btusb_check_needs_reset_resume(intf); } -#ifdef CONFIG_BT_HCIBTUSB_RTL - if (id->driver_info & BTUSB_REALTEK) { + if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) && + (id->driver_info & BTUSB_REALTEK)) { hdev->setup = btrtl_setup_realtek; hdev->shutdown = btrtl_shutdown_realtek; hdev->cmd_timeout = btusb_rtl_cmd_timeout; @@ -3818,8 +3927,11 @@ * (DEVICE_REMOTE_WAKEUP) */ set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); + + err = usb_autopm_get_interface(intf); + if (err < 0) + goto out_free_dev; } -#endif if (id->driver_info & BTUSB_AMP) { /* AMP controllers do not support SCO packets */ --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_bcm.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_bcm.c @@ -107,6 +107,7 @@ u32 oper_speed; int irq; bool irq_active_low; + bool irq_acquired; #ifdef CONFIG_PM struct hci_uart *hu; @@ -319,6 +320,8 @@ goto unlock; } + bdev->irq_acquired = true; + device_init_wakeup(bdev->dev, true); pm_runtime_set_autosuspend_delay(bdev->dev, @@ -487,7 +490,7 @@ } if (bdev) { - if (IS_ENABLED(CONFIG_PM) && bdev->irq > 0) { + if (IS_ENABLED(CONFIG_PM) && bdev->irq_acquired) { devm_free_irq(bdev->dev, bdev->irq, bdev); device_init_wakeup(bdev->dev, false); pm_runtime_disable(bdev->dev); @@ -1124,7 +1127,12 @@ return -ENOMEM; dev->dev = &pdev->dev; - dev->irq = platform_get_irq(pdev, 0); + + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + + dev->irq = ret; if (has_acpi_companion(&pdev->dev)) { ret = bcm_acpi_probe(dev); --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_bcsp.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_bcsp.c @@ -378,7 +378,7 @@ i++; __skb_unlink(skb, &bcsp->unack); - kfree_skb(skb); + dev_kfree_skb_irq(skb); } if (skb_queue_empty(&bcsp->unack)) @@ -591,6 +591,7 @@ if (*ptr == 0xc0) { BT_ERR("Short BCSP packet"); kfree_skb(bcsp->rx_skb); + bcsp->rx_skb = NULL; bcsp->rx_state = BCSP_W4_PKT_START; bcsp->rx_count = 0; } else @@ -606,6 +607,7 @@ bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) { BT_ERR("Error in BCSP hdr checksum"); kfree_skb(bcsp->rx_skb); + bcsp->rx_skb = NULL; bcsp->rx_state = BCSP_W4_PKT_DELIMITER; bcsp->rx_count = 0; continue; @@ -630,6 +632,7 @@ bscp_get_crc(bcsp)); kfree_skb(bcsp->rx_skb); + bcsp->rx_skb = NULL; bcsp->rx_state = BCSP_W4_PKT_DELIMITER; bcsp->rx_count = 0; continue; --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_h5.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_h5.c @@ -244,6 +244,9 @@ skb_queue_purge(&h5->rel); skb_queue_purge(&h5->unrel); + kfree_skb(h5->rx_skb); + h5->rx_skb = NULL; + if (h5->vnd && h5->vnd->close) h5->vnd->close(h5); @@ -295,7 +298,7 @@ break; __skb_unlink(skb, &h5->unack); - kfree_skb(skb); + dev_kfree_skb_irq(skb); } if (skb_queue_empty(&h5->unack)) @@ -790,7 +793,7 @@ if (!h5) return -ENOMEM; - set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.flags); + set_bit(HCI_UART_RESET_ON_INIT, &h5->serdev_hu.hdev_flags); h5->hu = &h5->serdev_hu; h5->serdev_hu.serdev = serdev; @@ -891,6 +894,11 @@ /* Give the device some time before the hci-core sends it a reset */ usleep_range(10000, 20000); + /* Enable controller to do both LE scan and BR/EDR inquiry + * simultaneously. + */ + set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &h5->hu->hdev->quirks); + out_free: btrtl_free(btrtl_dev); --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_intel.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_intel.c @@ -1230,7 +1230,11 @@ int __init intel_init(void) { - platform_driver_register(&intel_driver); + int err; + + err = platform_driver_register(&intel_driver); + if (err) + return err; return hci_uart_register_proto(&intel_proto); } --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_ldisc.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_ldisc.c @@ -127,10 +127,9 @@ if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) goto no_schedule; - if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) { - set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); + set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state); + if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) goto no_schedule; - } BT_DBG(""); @@ -174,10 +173,10 @@ kfree_skb(skb); } + clear_bit(HCI_UART_SENDING, &hu->tx_state); if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)) goto restart; - clear_bit(HCI_UART_SENDING, &hu->tx_state); wake_up_bit(&hu->tx_state, HCI_UART_SENDING); } @@ -480,6 +479,9 @@ BT_DBG("tty %p", tty); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + /* Error if the tty has no write op instead of leaving an exploitable * hole */ @@ -538,6 +540,7 @@ clear_bit(HCI_UART_PROTO_READY, &hu->flags); percpu_up_write(&hu->proto_lock); + cancel_work_sync(&hu->init_ready); cancel_work_sync(&hu->write_work); if (hdev) { @@ -765,7 +768,8 @@ break; case HCIUARTGETPROTO: - if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) + if (test_bit(HCI_UART_PROTO_SET, &hu->flags) && + test_bit(HCI_UART_PROTO_READY, &hu->flags)) err = hu->proto->id; else err = -EUNATCH; --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_ll.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_ll.c @@ -345,7 +345,7 @@ default: BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; } @@ -621,13 +621,6 @@ serdev_device_set_flow_control(serdev, true); - if (hu->oper_speed) - speed = hu->oper_speed; - else if (hu->proto->oper_speed) - speed = hu->proto->oper_speed; - else - speed = 0; - do { /* Reset the Bluetooth device */ gpiod_set_value_cansleep(lldev->enable_gpio, 0); @@ -639,20 +632,6 @@ return err; } - if (speed) { - __le32 speed_le = cpu_to_le32(speed); - struct sk_buff *skb; - - skb = __hci_cmd_sync(hu->hdev, - HCI_VS_UPDATE_UART_HCI_BAUDRATE, - sizeof(speed_le), &speed_le, - HCI_INIT_TIMEOUT); - if (!IS_ERR(skb)) { - kfree_skb(skb); - serdev_device_set_baudrate(serdev, speed); - } - } - err = download_firmware(lldev); if (!err) break; @@ -677,7 +656,25 @@ } /* Operational speed if any */ + if (hu->oper_speed) + speed = hu->oper_speed; + else if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; + else + speed = 0; + if (speed) { + __le32 speed_le = cpu_to_le32(speed); + struct sk_buff *skb; + + skb = __hci_cmd_sync(hu->hdev, HCI_VS_UPDATE_UART_HCI_BAUDRATE, + sizeof(speed_le), &speed_le, + HCI_INIT_TIMEOUT); + if (!IS_ERR(skb)) { + kfree_skb(skb); + serdev_device_set_baudrate(serdev, speed); + } + } return 0; } --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_nokia.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_nokia.c @@ -734,7 +734,11 @@ return err; } - clk_prepare_enable(sysclk); + err = clk_prepare_enable(sysclk); + if (err) { + dev_err(dev, "could not enable sysclk: %d", err); + return err; + } btdev->sysclk_speed = clk_get_rate(sysclk); clk_disable_unprepare(sysclk); --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_qca.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_qca.c @@ -816,7 +816,7 @@ default: BT_ERR("Illegal tx state: %d (losing packet)", qca->tx_ibs_state); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; } --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_serdev.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_serdev.c @@ -85,9 +85,9 @@ hci_uart_tx_complete(hu, hci_skb_pkt_type(skb)); kfree_skb(skb); } - } while (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)); - clear_bit(HCI_UART_SENDING, &hu->tx_state); + clear_bit(HCI_UART_SENDING, &hu->tx_state); + } while (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state)); } /* ------- Interface to HCI layer ------ */ @@ -279,6 +279,8 @@ if (err) return err; + percpu_init_rwsem(&hu->proto_lock); + err = p->open(hu); if (err) goto err_open; @@ -301,7 +303,6 @@ INIT_WORK(&hu->init_ready, hci_uart_init_work); INIT_WORK(&hu->write_work, hci_uart_write_work); - percpu_init_rwsem(&hu->proto_lock); /* Only when vendor specific setup callback is provided, consider * the manufacturer information valid. This avoids filling in the @@ -357,7 +358,10 @@ struct hci_dev *hdev = hu->hdev; clear_bit(HCI_UART_PROTO_READY, &hu->flags); - hci_unregister_dev(hdev); + + cancel_work_sync(&hu->init_ready); + if (test_bit(HCI_UART_REGISTERED, &hu->flags)) + hci_unregister_dev(hdev); hci_free_dev(hdev); cancel_work_sync(&hu->write_work); --- linux-oracle-5.4.0.orig/drivers/bluetooth/hci_vhci.c +++ linux-oracle-5.4.0/drivers/bluetooth/hci_vhci.c @@ -67,7 +67,10 @@ struct vhci_data *data = hci_get_drvdata(hdev); memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1); + + mutex_lock(&data->open_mutex); skb_queue_tail(&data->readq, skb); + mutex_unlock(&data->open_mutex); wake_up_interruptible(&data->read_wait); return 0; --- linux-oracle-5.4.0.orig/drivers/bus/Kconfig +++ linux-oracle-5.4.0/drivers/bus/Kconfig @@ -136,12 +136,12 @@ config TEGRA_ACONNECT tristate "Tegra ACONNECT Bus Driver" - depends on ARCH_TEGRA_210_SOC + depends on ARCH_TEGRA depends on OF && PM - select PM_CLK help Driver for the Tegra ACONNECT bus which is used to interface with - the devices inside the Audio Processing Engine (APE) for Tegra210. + the devices inside the Audio Processing Engine (APE) for + Tegra210 and later. config TEGRA_GMI tristate "Tegra Generic Memory Interface bus driver" --- linux-oracle-5.4.0.orig/drivers/bus/fsl-mc/fsl-mc-allocator.c +++ linux-oracle-5.4.0/drivers/bus/fsl-mc/fsl-mc-allocator.c @@ -292,8 +292,10 @@ goto error; mc_adev = resource->data; - if (!mc_adev) + if (!mc_adev) { + error = -EINVAL; goto error; + } mc_adev->consumer_link = device_link_add(&mc_dev->dev, &mc_adev->dev, --- linux-oracle-5.4.0.orig/drivers/bus/fsl-mc/mc-io.c +++ linux-oracle-5.4.0/drivers/bus/fsl-mc/mc-io.c @@ -129,7 +129,12 @@ */ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io) { - struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev; + struct fsl_mc_device *dpmcp_dev; + + if (!mc_io) + return; + + dpmcp_dev = mc_io->dpmcp_dev; if (dpmcp_dev) fsl_mc_io_unset_dpmcp(mc_io); --- linux-oracle-5.4.0.orig/drivers/bus/hisi_lpc.c +++ linux-oracle-5.4.0/drivers/bus/hisi_lpc.c @@ -359,6 +359,26 @@ } /* + * Released firmware describes the IO port max address as 0x3fff, which is + * the max host bus address. Fixup to a proper range. This will probably + * never be fixed in firmware. + */ +static void hisi_lpc_acpi_fixup_child_resource(struct device *hostdev, + struct resource *r) +{ + if (r->end != 0x3fff) + return; + + if (r->start == 0xe4) + r->end = 0xe4 + 0x04 - 1; + else if (r->start == 0x2f8) + r->end = 0x2f8 + 0x08 - 1; + else + dev_warn(hostdev, "unrecognised resource %pR to fixup, ignoring\n", + r); +} + +/* * hisi_lpc_acpi_set_io_res - set the resources for a child * @child: the device node to be updated the I/O resource * @hostdev: the device node associated with host controller @@ -419,8 +439,11 @@ return -ENOMEM; } count = 0; - list_for_each_entry(rentry, &resource_list, node) - resources[count++] = *rentry->res; + list_for_each_entry(rentry, &resource_list, node) { + resources[count] = *rentry->res; + hisi_lpc_acpi_fixup_child_resource(hostdev, &resources[count]); + count++; + } acpi_dev_free_resource_list(&resource_list); @@ -481,13 +504,13 @@ { struct acpi_device *adev = ACPI_COMPANION(hostdev); struct acpi_device *child; + struct platform_device *pdev; int ret; /* Only consider the children of the host */ list_for_each_entry(child, &adev->children, node) { const char *hid = acpi_device_hid(child); const struct hisi_lpc_acpi_cell *cell; - struct platform_device *pdev; const struct resource *res; bool found = false; int num_res; @@ -549,22 +572,24 @@ ret = platform_device_add_resources(pdev, res, num_res); if (ret) - goto fail; + goto fail_put_device; ret = platform_device_add_data(pdev, cell->pdata, cell->pdata_size); if (ret) - goto fail; + goto fail_put_device; ret = platform_device_add(pdev); if (ret) - goto fail; + goto fail_put_device; acpi_device_set_enumerated(child); } return 0; +fail_put_device: + platform_device_put(pdev); fail: hisi_lpc_acpi_remove(hostdev); return ret; --- linux-oracle-5.4.0.orig/drivers/bus/imx-weim.c +++ linux-oracle-5.4.0/drivers/bus/imx-weim.c @@ -192,8 +192,8 @@ const struct of_device_id *of_id = of_match_device(weim_id_table, &pdev->dev); const struct imx_weim_devtype *devtype = of_id->data; + int ret = 0, have_child = 0; struct device_node *child; - int ret, have_child = 0; struct cs_timing_state ts = {}; u32 reg; --- linux-oracle-5.4.0.orig/drivers/bus/mips_cdmm.c +++ linux-oracle-5.4.0/drivers/bus/mips_cdmm.c @@ -544,10 +544,8 @@ dev_set_name(&dev->dev, "cdmm%u-%u", cpu, id); ++id; ret = device_register(&dev->dev); - if (ret) { + if (ret) put_device(&dev->dev); - kfree(dev); - } } } --- linux-oracle-5.4.0.orig/drivers/bus/moxtet.c +++ linux-oracle-5.4.0/drivers/bus/moxtet.c @@ -466,7 +466,7 @@ { struct moxtet *moxtet = file->private_data; u8 bin[TURRIS_MOX_MAX_MODULES]; - u8 hex[sizeof(buf) * 2 + 1]; + u8 hex[sizeof(bin) * 2 + 1]; int ret, n; ret = moxtet_spi_read(moxtet, bin); @@ -833,6 +833,12 @@ return 0; } +static const struct spi_device_id moxtet_spi_ids[] = { + { "moxtet" }, + { }, +}; +MODULE_DEVICE_TABLE(spi, moxtet_spi_ids); + static const struct of_device_id moxtet_dt_ids[] = { { .compatible = "cznic,moxtet" }, {}, @@ -844,6 +850,7 @@ .name = "moxtet", .of_match_table = moxtet_dt_ids, }, + .id_table = moxtet_spi_ids, .probe = moxtet_probe, .remove = moxtet_remove, }; --- linux-oracle-5.4.0.orig/drivers/bus/omap_l3_noc.c +++ linux-oracle-5.4.0/drivers/bus/omap_l3_noc.c @@ -285,7 +285,7 @@ */ l3->debug_irq = platform_get_irq(pdev, 0); ret = devm_request_irq(l3->dev, l3->debug_irq, l3_interrupt_handler, - 0x0, "l3-dbg-irq", l3); + IRQF_NO_THREAD, "l3-dbg-irq", l3); if (ret) { dev_err(l3->dev, "request_irq failed for %d\n", l3->debug_irq); @@ -294,7 +294,7 @@ l3->app_irq = platform_get_irq(pdev, 1); ret = devm_request_irq(l3->dev, l3->app_irq, l3_interrupt_handler, - 0x0, "l3-app-irq", l3); + IRQF_NO_THREAD, "l3-app-irq", l3); if (ret) dev_err(l3->dev, "request_irq failed for %d\n", l3->app_irq); --- linux-oracle-5.4.0.orig/drivers/bus/qcom-ebi2.c +++ linux-oracle-5.4.0/drivers/bus/qcom-ebi2.c @@ -353,8 +353,10 @@ /* Figure out the chipselect */ ret = of_property_read_u32(child, "reg", &csindex); - if (ret) + if (ret) { + of_node_put(child); return ret; + } if (csindex > 5) { dev_err(dev, --- linux-oracle-5.4.0.orig/drivers/bus/sunxi-rsb.c +++ linux-oracle-5.4.0/drivers/bus/sunxi-rsb.c @@ -224,6 +224,8 @@ dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev)); + return rdev; + err_device_add: put_device(&rdev->dev); @@ -266,6 +268,9 @@ /* common code that starts a transfer */ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) { + u32 int_mask, status; + bool timeout; + if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { dev_dbg(rsb->dev, "RSB transfer still in progress\n"); return -EBUSY; @@ -273,13 +278,23 @@ reinit_completion(&rsb->complete); - writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, - rsb->regs + RSB_INTE); + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; + writel(int_mask, rsb->regs + RSB_INTE); writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, rsb->regs + RSB_CTRL); - if (!wait_for_completion_io_timeout(&rsb->complete, - msecs_to_jiffies(100))) { + if (irqs_disabled()) { + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, + status, (status & int_mask), + 10, 100000); + writel(status, rsb->regs + RSB_INTS); + } else { + timeout = !wait_for_completion_io_timeout(&rsb->complete, + msecs_to_jiffies(100)); + status = rsb->status; + } + + if (timeout) { dev_dbg(rsb->dev, "RSB timeout\n"); /* abort the transfer */ @@ -291,18 +306,18 @@ return -ETIMEDOUT; } - if (rsb->status & RSB_INTS_LOAD_BSY) { + if (status & RSB_INTS_LOAD_BSY) { dev_dbg(rsb->dev, "RSB busy\n"); return -EBUSY; } - if (rsb->status & RSB_INTS_TRANS_ERR) { - if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { + if (status & RSB_INTS_TRANS_ERR) { + if (status & RSB_INTS_TRANS_ERR_ACK) { dev_dbg(rsb->dev, "RSB slave nack\n"); return -EINVAL; } - if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { + if (status & RSB_INTS_TRANS_ERR_DATA) { dev_dbg(rsb->dev, "RSB transfer data error\n"); return -EIO; } @@ -345,7 +360,7 @@ if (ret) goto unlock; - *buf = readl(rsb->regs + RSB_DATA); + *buf = readl(rsb->regs + RSB_DATA) & GENMASK(len * 8 - 1, 0); unlock: mutex_unlock(&rsb->lock); @@ -766,7 +781,13 @@ return ret; } - return platform_driver_register(&sunxi_rsb_driver); + ret = platform_driver_register(&sunxi_rsb_driver); + if (ret) { + bus_unregister(&sunxi_rsb_bus); + return ret; + } + + return 0; } module_init(sunxi_rsb_init); --- linux-oracle-5.4.0.orig/drivers/bus/ti-sysc.c +++ linux-oracle-5.4.0/drivers/bus/ti-sysc.c @@ -70,11 +70,13 @@ * @child_needs_resume: runtime resume needed for child on resume from suspend * @disable_on_idle: status flag used for disabling modules with resets * @idle_work: work structure used to perform delayed idle on a module - * @clk_enable_quirk: module specific clock enable quirk - * @clk_disable_quirk: module specific clock disable quirk + * @pre_reset_quirk: module specific pre-reset quirk + * @post_reset_quirk: module specific post-reset quirk * @reset_done_quirk: module specific reset done quirk * @module_enable_quirk: module specific enable quirk * @module_disable_quirk: module specific disable quirk + * @module_unlock_quirk: module specific sysconfig unlock quirk + * @module_lock_quirk: module specific sysconfig lock quirk */ struct sysc { struct device *dev; @@ -97,11 +99,13 @@ unsigned int needs_resume:1; unsigned int child_needs_resume:1; struct delayed_work idle_work; - void (*clk_enable_quirk)(struct sysc *sysc); - void (*clk_disable_quirk)(struct sysc *sysc); + void (*pre_reset_quirk)(struct sysc *sysc); + void (*post_reset_quirk)(struct sysc *sysc); void (*reset_done_quirk)(struct sysc *sysc); void (*module_enable_quirk)(struct sysc *sysc); void (*module_disable_quirk)(struct sysc *sysc); + void (*module_unlock_quirk)(struct sysc *sysc); + void (*module_lock_quirk)(struct sysc *sysc); }; static void sysc_parse_dts_quirks(struct sysc *ddata, struct device_node *np, @@ -182,6 +186,37 @@ return sysc_read(ddata, offset); } +/* Poll on reset status */ +static int sysc_wait_softreset(struct sysc *ddata) +{ + u32 sysc_mask, syss_done, rstval; + int syss_offset, error = 0; + + if (ddata->cap->regbits->srst_shift < 0) + return 0; + + syss_offset = ddata->offsets[SYSC_SYSSTATUS]; + sysc_mask = BIT(ddata->cap->regbits->srst_shift); + + if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) + syss_done = 0; + else + syss_done = ddata->cfg.syss_mask; + + if (syss_offset >= 0) { + error = readx_poll_timeout_atomic(sysc_read_sysstatus, ddata, + rstval, (rstval & ddata->cfg.syss_mask) == + syss_done, 100, MAX_MODULE_SOFTRESET_WAIT); + + } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { + error = readx_poll_timeout_atomic(sysc_read_sysconfig, ddata, + rstval, !(rstval & sysc_mask), + 100, MAX_MODULE_SOFTRESET_WAIT); + } + + return error; +} + static int sysc_add_named_clock_from_child(struct sysc *ddata, const char *name, const char *optfck_name) @@ -343,6 +378,12 @@ return -EINVAL; } + /* Always add a slot for main clocks fck and ick even if unused */ + if (!nr_fck) + ddata->nr_clocks++; + if (!nr_ick) + ddata->nr_clocks++; + ddata->clocks = devm_kcalloc(ddata->dev, ddata->nr_clocks, sizeof(*ddata->clocks), GFP_KERNEL); @@ -421,7 +462,7 @@ struct clk *clock; int i, error; - if (!ddata->clocks) + if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1) return 0; for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) { @@ -455,7 +496,7 @@ struct clk *clock; int i; - if (!ddata->clocks) + if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1) return; for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) { @@ -473,7 +514,7 @@ { struct ti_sysc_platform_data *pdata; - if (ddata->legacy_mode) + if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO)) return; pdata = dev_get_platdata(ddata->dev); @@ -485,7 +526,7 @@ { struct ti_sysc_platform_data *pdata; - if (ddata->legacy_mode) + if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO)) return; pdata = dev_get_platdata(ddata->dev); @@ -561,6 +602,51 @@ return 0; } +/* Interconnect instances to probe before l4_per instances */ +static struct resource early_bus_ranges[] = { + /* am3/4 l4_wkup */ + { .start = 0x44c00000, .end = 0x44c00000 + 0x300000, }, + /* omap4/5 and dra7 l4_cfg */ + { .start = 0x4a000000, .end = 0x4a000000 + 0x300000, }, + /* omap4 l4_wkup */ + { .start = 0x4a300000, .end = 0x4a300000 + 0x30000, }, + /* omap5 and dra7 l4_wkup without dra7 dcan segment */ + { .start = 0x4ae00000, .end = 0x4ae00000 + 0x30000, }, +}; + +static atomic_t sysc_defer = ATOMIC_INIT(10); + +/** + * sysc_defer_non_critical - defer non_critical interconnect probing + * @ddata: device driver data + * + * We want to probe l4_cfg and l4_wkup interconnect instances before any + * l4_per instances as l4_per instances depend on resources on l4_cfg and + * l4_wkup interconnects. + */ +static int sysc_defer_non_critical(struct sysc *ddata) +{ + struct resource *res; + int i; + + if (!atomic_read(&sysc_defer)) + return 0; + + for (i = 0; i < ARRAY_SIZE(early_bus_ranges); i++) { + res = &early_bus_ranges[i]; + if (ddata->module_pa >= res->start && + ddata->module_pa <= res->end) { + atomic_set(&sysc_defer, 0); + + return 0; + } + } + + atomic_dec_if_positive(&sysc_defer); + + return -EPROBE_DEFER; +} + static struct device_node *stdout_path; static void sysc_init_stdout_path(struct sysc *ddata) @@ -785,6 +871,10 @@ if (error) return error; + error = sysc_defer_non_critical(ddata); + if (error) + return error; + sysc_check_children(ddata); error = sysc_parse_registers(ddata); @@ -857,6 +947,22 @@ buf); } +/** + * sysc_write_sysconfig - handle sysconfig quirks for register write + * @ddata: device driver data + * @value: register value + */ +static void sysc_write_sysconfig(struct sysc *ddata, u32 value) +{ + if (ddata->module_unlock_quirk) + ddata->module_unlock_quirk(ddata); + + sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], value); + + if (ddata->module_lock_quirk) + ddata->module_lock_quirk(ddata); +} + #define SYSC_IDLE_MASK (SYSC_NR_IDLEMODES - 1) #define SYSC_CLOCACT_ICK 2 @@ -866,18 +972,47 @@ struct sysc *ddata; const struct sysc_regbits *regbits; u32 reg, idlemodes, best_mode; + int error; ddata = dev_get_drvdata(dev); + + /* + * Some modules like DSS reset automatically on idle. Enable optional + * reset clocks and wait for OCP softreset to complete. + */ + if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) { + error = sysc_enable_opt_clocks(ddata); + if (error) { + dev_err(ddata->dev, + "Optional clocks failed for enable: %i\n", + error); + return error; + } + } + error = sysc_wait_softreset(ddata); + if (error) + dev_warn(ddata->dev, "OCP softreset timed out\n"); + if (ddata->cfg.quirks & SYSC_QUIRK_OPT_CLKS_IN_RESET) + sysc_disable_opt_clocks(ddata); + + /* + * Some subsystem private interconnects, like DSS top level module, + * need only the automatic OCP softreset handling with no sysconfig + * register bits to configure. + */ if (ddata->offsets[SYSC_SYSCONFIG] == -ENODEV) return 0; regbits = ddata->cap->regbits; reg = sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); - /* Set CLOCKACTIVITY, we only use it for ick */ + /* + * Set CLOCKACTIVITY, we only use it for ick. And we only configure it + * based on the SYSC_QUIRK_USE_CLOCKACT flag, not based on the hardware + * capabilities. See the old HWMOD_SET_DEFAULT_CLOCKACT flag. + */ if (regbits->clkact_shift >= 0 && - (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT || - ddata->cfg.sysc_val & BIT(regbits->clkact_shift))) + (ddata->cfg.quirks & SYSC_QUIRK_USE_CLOCKACT)) reg |= SYSC_CLOCACT_ICK << regbits->clkact_shift; /* Set SIDLE mode */ @@ -888,6 +1023,11 @@ if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { best_mode = SYSC_IDLE_NO; + + /* Clear WAKEUP */ + if (regbits->enwkup_shift >= 0 && + ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) + reg &= ~BIT(regbits->enwkup_shift); } else { best_mode = fls(ddata->cfg.sidlemodes) - 1; if (best_mode > SYSC_IDLE_MASK) { @@ -903,7 +1043,7 @@ reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); reg |= best_mode << regbits->sidle_shift; - sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); + sysc_write_sysconfig(ddata, reg); set_midle: /* Set MIDLE mode */ @@ -917,18 +1057,24 @@ return -EINVAL; } + if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_MSTANDBY) + best_mode = SYSC_IDLE_NO; + reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift); reg |= best_mode << regbits->midle_shift; - sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); + sysc_write_sysconfig(ddata, reg); set_autoidle: /* Autoidle bit must enabled separately if available */ if (regbits->autoidle_shift >= 0 && ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) { reg |= 1 << regbits->autoidle_shift; - sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); + sysc_write_sysconfig(ddata, reg); } + /* Flush posted write */ + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); + if (ddata->module_enable_quirk) ddata->module_enable_quirk(ddata); @@ -978,9 +1124,13 @@ return ret; } + if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_MSTANDBY) || + ddata->cfg.quirks & (SYSC_QUIRK_FORCE_MSTANDBY)) + best_mode = SYSC_IDLE_FORCE; + reg &= ~(SYSC_IDLE_MASK << regbits->midle_shift); reg |= best_mode << regbits->midle_shift; - sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); + sysc_write_sysconfig(ddata, reg); set_sidle: /* Set SIDLE mode */ @@ -998,12 +1148,22 @@ } } + if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { + /* Set WAKEUP */ + if (regbits->enwkup_shift >= 0 && + ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) + reg |= BIT(regbits->enwkup_shift); + } + reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); reg |= best_mode << regbits->sidle_shift; if (regbits->autoidle_shift >= 0 && ddata->cfg.sysc_val & BIT(regbits->autoidle_shift)) reg |= 1 << regbits->autoidle_shift; - sysc_write(ddata, ddata->offsets[SYSC_SYSCONFIG], reg); + sysc_write_sysconfig(ddata, reg); + + /* Flush posted write */ + sysc_read(ddata, ddata->offsets[SYSC_SYSCONFIG]); return 0; } @@ -1149,7 +1309,8 @@ ddata = dev_get_drvdata(dev); - if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) + if (ddata->cfg.quirks & + (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE)) return 0; return pm_runtime_force_suspend(dev); @@ -1161,7 +1322,8 @@ ddata = dev_get_drvdata(dev); - if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) + if (ddata->cfg.quirks & + (SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_NO_IDLE)) return 0; return pm_runtime_force_resume(dev); @@ -1209,33 +1371,54 @@ SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("smartreflex", 0, -1, 0x24, -1, 0x00000000, 0xffffffff, + SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x24, -ENODEV, 0x00000000, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), - SYSC_QUIRK("smartreflex", 0, -1, 0x38, -1, 0x00000000, 0xffffffff, + SYSC_QUIRK("smartreflex", 0, -ENODEV, 0x38, -ENODEV, 0x00000000, 0xffffffff, SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff, 0), /* Some timers on omap4 and later */ - SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x50002100, 0xffffffff, + SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x50002100, 0xffffffff, 0), - SYSC_QUIRK("timer", 0, 0, 0x10, -1, 0x4fff1301, 0xffff00ff, + SYSC_QUIRK("timer", 0, 0, 0x10, -ENODEV, 0x4fff1301, 0xffff00ff, 0), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), /* Uarts on omap4 and later */ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), /* Quirks that need to be set based on the module address */ - SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -1, 0x50000800, 0xffffffff, + SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, SYSC_QUIRK_EXT_OPT_CLOCK | SYSC_QUIRK_NO_RESET_ON_INIT | SYSC_QUIRK_SWSUP_SIDLE), /* Quirks that need to be set based on detected module */ + SYSC_QUIRK("aess", 0, 0, 0x10, -ENODEV, 0x40000000, 0xffffffff, + SYSC_MODULE_QUIRK_AESS), + /* Errata i893 handling for dra7 dcan1 and 2 */ + SYSC_QUIRK("dcan", 0x4ae3c000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dcan", 0x48480000, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dss", 0x4832a000, 0, 0x10, 0x14, 0x00000020, 0xffffffff, + SYSC_QUIRK_OPT_CLKS_IN_RESET), + SYSC_QUIRK("dss", 0x58000000, 0, -ENODEV, 0x14, 0x00000040, 0xffffffff, + SYSC_QUIRK_OPT_CLKS_IN_RESET), + SYSC_QUIRK("dss", 0x58000000, 0, -ENODEV, 0x14, 0x00000061, 0xffffffff, + SYSC_QUIRK_OPT_CLKS_IN_RESET), + SYSC_QUIRK("dwc3", 0x48880000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, + SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, + SYSC_QUIRK_OPT_CLKS_NEEDED), SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, SYSC_MODULE_QUIRK_HDQ1W), SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff, @@ -1248,9 +1431,23 @@ SYSC_MODULE_QUIRK_I2C), SYSC_QUIRK("i2c", 0, 0, 0x10, 0x90, 0x5040000a, 0xfffff0f0, SYSC_MODULE_QUIRK_I2C), - SYSC_QUIRK("gpu", 0x50000000, 0x14, -1, -1, 0x00010201, 0xffffffff, 0), - SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff, + SYSC_QUIRK("gpu", 0x50000000, 0x14, -ENODEV, -ENODEV, 0x00010201, 0xffffffff, 0), + SYSC_QUIRK("gpu", 0x50000000, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, SYSC_MODULE_QUIRK_SGX), + SYSC_QUIRK("rtc", 0, 0x74, 0x78, -ENODEV, 0x4eb01908, 0xffff00f0, + SYSC_MODULE_QUIRK_RTC_UNLOCK), + SYSC_QUIRK("tptc", 0, 0, 0x10, -ENODEV, 0x40006c00, 0xffffefff, + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("tptc", 0, 0, -ENODEV, -ENODEV, 0x40007c00, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -ENODEV, 0x50700101, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, + 0xffffffff, SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), + SYSC_QUIRK("usb_otg_hs", 0, 0, 0x10, -ENODEV, 0x4ea2080d, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_MSTANDBY), SYSC_QUIRK("wdt", 0, 0, 0x10, 0x14, 0x502a0500, 0xfffff0f0, SYSC_MODULE_QUIRK_WDT), /* Watchdog on am3 and am4 */ @@ -1258,60 +1455,66 @@ SYSC_MODULE_QUIRK_WDT | SYSC_QUIRK_SWSUP_SIDLE), #ifdef DEBUG - SYSC_QUIRK("adc", 0, 0, 0x10, -1, 0x47300001, 0xffffffff, 0), - SYSC_QUIRK("atl", 0, 0, -1, -1, 0x0a070100, 0xffffffff, 0), - SYSC_QUIRK("aess", 0, 0, 0x10, -1, 0x40000000, 0xffffffff, 0), - SYSC_QUIRK("cm", 0, 0, -1, -1, 0x40000301, 0xffffffff, 0), - SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0), + SYSC_QUIRK("adc", 0, 0, 0x10, -ENODEV, 0x47300001, 0xffffffff, 0), + SYSC_QUIRK("atl", 0, 0, -ENODEV, -ENODEV, 0x0a070100, 0xffffffff, 0), + SYSC_QUIRK("cm", 0, 0, -ENODEV, -ENODEV, 0x40000301, 0xffffffff, 0), + SYSC_QUIRK("control", 0, 0, 0x10, -ENODEV, 0x40000900, 0xffffffff, 0), SYSC_QUIRK("cpgmac", 0, 0x1200, 0x1208, 0x1204, 0x4edb1902, 0xffff00f0, 0), - SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0xa3170504, 0xffffffff, 0), - SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0x4edb1902, 0xffffffff, 0), - SYSC_QUIRK("dmic", 0, 0, 0x10, -1, 0x50010000, 0xffffffff, 0), - SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0), + SYSC_QUIRK("dcan", 0, 0x20, -ENODEV, -ENODEV, 0xa3170504, 0xffffffff, 0), + SYSC_QUIRK("dcan", 0, 0x20, -ENODEV, -ENODEV, 0x4edb1902, 0xffffffff, 0), + SYSC_QUIRK("dispc", 0x4832a400, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0), + SYSC_QUIRK("dispc", 0x58001000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0), + SYSC_QUIRK("dispc", 0x58001000, 0, 0x10, 0x14, 0x00000051, 0xffffffff, 0), + SYSC_QUIRK("dmic", 0, 0, 0x10, -ENODEV, 0x50010000, 0xffffffff, 0), + SYSC_QUIRK("dsi", 0x58004000, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0), + SYSC_QUIRK("dsi", 0x58005000, 0, 0x10, 0x14, 0x00000030, 0xffffffff, 0), + SYSC_QUIRK("dsi", 0x58005000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0), + SYSC_QUIRK("dsi", 0x58009000, 0, 0x10, 0x14, 0x00000040, 0xffffffff, 0), + SYSC_QUIRK("dwc3", 0, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, 0), SYSC_QUIRK("d2d", 0x4a0b6000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0), SYSC_QUIRK("d2d", 0x4a0cd000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0), - SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0), - SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -1, 0, 0, 0), - SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -1, 0x40000000 , 0xffffffff, 0), + SYSC_QUIRK("epwmss", 0, 0, 0x4, -ENODEV, 0x47400001, 0xffffffff, 0), + SYSC_QUIRK("gpu", 0, 0x1fc00, 0x1fc10, -ENODEV, 0, 0, 0), + SYSC_QUIRK("gpu", 0, 0xfe00, 0xfe10, -ENODEV, 0x40000000 , 0xffffffff, 0), + SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50031d00, 0xffffffff, 0), SYSC_QUIRK("hsi", 0, 0, 0x10, 0x14, 0x50043101, 0xffffffff, 0), - SYSC_QUIRK("iss", 0, 0, 0x10, -1, 0x40000101, 0xffffffff, 0), - SYSC_QUIRK("lcdc", 0, 0, 0x54, -1, 0x4f201000, 0xffffffff, 0), - SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44306302, 0xffffffff, 0), - SYSC_QUIRK("mcasp", 0, 0, 0x4, -1, 0x44307b02, 0xffffffff, 0), - SYSC_QUIRK("mcbsp", 0, -1, 0x8c, -1, 0, 0, 0), - SYSC_QUIRK("mcspi", 0, 0, 0x10, -1, 0x40300a0b, 0xffff00ff, 0), + SYSC_QUIRK("iss", 0, 0, 0x10, -ENODEV, 0x40000101, 0xffffffff, 0), + SYSC_QUIRK("lcdc", 0, 0, 0x54, -ENODEV, 0x4f201000, 0xffffffff, 0), + SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44306302, 0xffffffff, 0), + SYSC_QUIRK("mcasp", 0, 0, 0x4, -ENODEV, 0x44307b02, 0xffffffff, 0), + SYSC_QUIRK("mcbsp", 0, -ENODEV, 0x8c, -ENODEV, 0, 0, 0), + SYSC_QUIRK("mcspi", 0, 0, 0x10, -ENODEV, 0x40300a0b, 0xffff00ff, 0), SYSC_QUIRK("mcspi", 0, 0, 0x110, 0x114, 0x40300a0b, 0xffffffff, 0), - SYSC_QUIRK("mailbox", 0, 0, 0x10, -1, 0x00000400, 0xffffffff, 0), - SYSC_QUIRK("m3", 0, 0, -1, -1, 0x5f580105, 0x0fff0f00, 0), + SYSC_QUIRK("mailbox", 0, 0, 0x10, -ENODEV, 0x00000400, 0xffffffff, 0), + SYSC_QUIRK("m3", 0, 0, -ENODEV, -ENODEV, 0x5f580105, 0x0fff0f00, 0), SYSC_QUIRK("ocp2scp", 0, 0, 0x10, 0x14, 0x50060005, 0xfffffff0, 0), - SYSC_QUIRK("ocp2scp", 0, 0, -1, -1, 0x50060007, 0xffffffff, 0), - SYSC_QUIRK("padconf", 0, 0, 0x10, -1, 0x4fff0800, 0xffffffff, 0), - SYSC_QUIRK("padconf", 0, 0, -1, -1, 0x40001100, 0xffffffff, 0), - SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000100, 0xffffffff, 0), - SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x00004102, 0xffffffff, 0), - SYSC_QUIRK("prcm", 0, 0, -1, -1, 0x40000400, 0xffffffff, 0), - SYSC_QUIRK("scm", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0), - SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4e8b0100, 0xffffffff, 0), - SYSC_QUIRK("scm", 0, 0, -1, -1, 0x4f000100, 0xffffffff, 0), - SYSC_QUIRK("scm", 0, 0, -1, -1, 0x40000900, 0xffffffff, 0), - SYSC_QUIRK("scrm", 0, 0, -1, -1, 0x00000010, 0xffffffff, 0), - SYSC_QUIRK("sdio", 0, 0, 0x10, -1, 0x40202301, 0xffff0ff0, 0), + SYSC_QUIRK("ocp2scp", 0, 0, -ENODEV, -ENODEV, 0x50060007, 0xffffffff, 0), + SYSC_QUIRK("padconf", 0, 0, 0x10, -ENODEV, 0x4fff0800, 0xffffffff, 0), + SYSC_QUIRK("padconf", 0, 0, -ENODEV, -ENODEV, 0x40001100, 0xffffffff, 0), + SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000100, 0xffffffff, 0), + SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x00004102, 0xffffffff, 0), + SYSC_QUIRK("prcm", 0, 0, -ENODEV, -ENODEV, 0x40000400, 0xffffffff, 0), + SYSC_QUIRK("rfbi", 0x4832a800, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0), + SYSC_QUIRK("rfbi", 0x58002000, 0, 0x10, 0x14, 0x00000010, 0xffffffff, 0), + SYSC_QUIRK("scm", 0, 0, 0x10, -ENODEV, 0x40000900, 0xffffffff, 0), + SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4e8b0100, 0xffffffff, 0), + SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x4f000100, 0xffffffff, 0), + SYSC_QUIRK("scm", 0, 0, -ENODEV, -ENODEV, 0x40000900, 0xffffffff, 0), + SYSC_QUIRK("scrm", 0, 0, -ENODEV, -ENODEV, 0x00000010, 0xffffffff, 0), + SYSC_QUIRK("sdio", 0, 0, 0x10, -ENODEV, 0x40202301, 0xffff0ff0, 0), SYSC_QUIRK("sdio", 0, 0x2fc, 0x110, 0x114, 0x31010000, 0xffffffff, 0), SYSC_QUIRK("sdma", 0, 0, 0x2c, 0x28, 0x00010900, 0xffffffff, 0), - SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40000902, 0xffffffff, 0), - SYSC_QUIRK("slimbus", 0, 0, 0x10, -1, 0x40002903, 0xffffffff, 0), - SYSC_QUIRK("spinlock", 0, 0, 0x10, -1, 0x50020000, 0xffffffff, 0), - SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -1, 0x00000020, 0xffffffff, 0), - SYSC_QUIRK("rtc", 0, 0x74, 0x78, -1, 0x4eb01908, 0xffff00f0, 0), - SYSC_QUIRK("timer32k", 0, 0, 0x4, -1, 0x00000060, 0xffffffff, 0), + SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40000902, 0xffffffff, 0), + SYSC_QUIRK("slimbus", 0, 0, 0x10, -ENODEV, 0x40002903, 0xffffffff, 0), + SYSC_QUIRK("spinlock", 0, 0, 0x10, -ENODEV, 0x50020000, 0xffffffff, 0), + SYSC_QUIRK("rng", 0, 0x1fe0, 0x1fe4, -ENODEV, 0x00000020, 0xffffffff, 0), + SYSC_QUIRK("timer32k", 0, 0, 0x4, -ENODEV, 0x00000060, 0xffffffff, 0), + SYSC_QUIRK("tpcc", 0, 0, -ENODEV, -ENODEV, 0x40014c00, 0xffffffff, 0), SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000004, 0xffffffff, 0), SYSC_QUIRK("usbhstll", 0, 0, 0x10, 0x14, 0x00000008, 0xffffffff, 0), - SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, 0x14, 0x50700100, 0xffffffff, 0), - SYSC_QUIRK("usb_host_hs", 0, 0, 0x10, -1, 0x50700101, 0xffffffff, 0), - SYSC_QUIRK("usb_otg_hs", 0, 0x400, 0x404, 0x408, 0x00000050, - 0xffffffff, 0), - SYSC_QUIRK("vfpe", 0, 0, 0x104, -1, 0x4d001200, 0xffffffff, 0), + SYSC_QUIRK("venc", 0x58003000, 0, -ENODEV, -ENODEV, 0x00000002, 0xffffffff, 0), + SYSC_QUIRK("vfpe", 0, 0, 0x104, -ENODEV, 0x4d001200, 0xffffffff, 0), #endif }; @@ -1333,16 +1536,13 @@ if (q->base != ddata->module_pa) continue; - if (q->rev_offset >= 0 && - q->rev_offset != ddata->offsets[SYSC_REVISION]) + if (q->rev_offset != ddata->offsets[SYSC_REVISION]) continue; - if (q->sysc_offset >= 0 && - q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG]) + if (q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG]) continue; - if (q->syss_offset >= 0 && - q->syss_offset != ddata->offsets[SYSC_SYSSTATUS]) + if (q->syss_offset != ddata->offsets[SYSC_SYSSTATUS]) continue; ddata->name = q->name; @@ -1362,16 +1562,13 @@ if (q->base && q->base != ddata->module_pa) continue; - if (q->rev_offset >= 0 && - q->rev_offset != ddata->offsets[SYSC_REVISION]) + if (q->rev_offset != ddata->offsets[SYSC_REVISION]) continue; - if (q->sysc_offset >= 0 && - q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG]) + if (q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG]) continue; - if (q->syss_offset >= 0 && - q->syss_offset != ddata->offsets[SYSC_SYSSTATUS]) + if (q->syss_offset != ddata->offsets[SYSC_SYSSTATUS]) continue; if (q->revision == ddata->revision || @@ -1384,7 +1581,7 @@ } /* 1-wire needs module's internal clocks enabled for reset */ -static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata) +static void sysc_pre_reset_quirk_hdq1w(struct sysc *ddata) { int offset = 0x0c; /* HDQ_CTRL_STATUS */ u16 val; @@ -1394,7 +1591,15 @@ sysc_write(ddata, offset, val); } -/* I2C needs extra enable bit toggling for reset */ +/* AESS (Audio Engine SubSystem) needs autogating set after enable */ +static void sysc_module_enable_quirk_aess(struct sysc *ddata) +{ + int offset = 0x7c; /* AESS_AUTO_GATING_ENABLE */ + + sysc_write(ddata, offset, 1); +} + +/* I2C needs to be disabled for reset */ static void sysc_clk_quirk_i2c(struct sysc *ddata, bool enable) { int offset; @@ -1415,14 +1620,48 @@ sysc_write(ddata, offset, val); } -static void sysc_clk_enable_quirk_i2c(struct sysc *ddata) +static void sysc_pre_reset_quirk_i2c(struct sysc *ddata) +{ + sysc_clk_quirk_i2c(ddata, false); +} + +static void sysc_post_reset_quirk_i2c(struct sysc *ddata) { sysc_clk_quirk_i2c(ddata, true); } -static void sysc_clk_disable_quirk_i2c(struct sysc *ddata) +/* RTC on am3 and 4 needs to be unlocked and locked for sysconfig */ +static void sysc_quirk_rtc(struct sysc *ddata, bool lock) { - sysc_clk_quirk_i2c(ddata, false); + u32 val, kick0_val = 0, kick1_val = 0; + unsigned long flags; + int error; + + if (!lock) { + kick0_val = 0x83e70b13; + kick1_val = 0x95a4f1e0; + } + + local_irq_save(flags); + /* RTC_STATUS BUSY bit may stay active for 1/32768 seconds (~30 usec) */ + error = readl_poll_timeout_atomic(ddata->module_va + 0x44, val, + !(val & BIT(0)), 100, 50); + if (error) + dev_warn(ddata->dev, "rtc busy timeout\n"); + /* Now we have ~15 microseconds to read/write various registers */ + sysc_write(ddata, 0x6c, kick0_val); + sysc_write(ddata, 0x70, kick1_val); + local_irq_restore(flags); +} + +static void sysc_module_unlock_quirk_rtc(struct sysc *ddata) +{ + sysc_quirk_rtc(ddata, false); +} + +static void sysc_module_lock_quirk_rtc(struct sysc *ddata) +{ + sysc_quirk_rtc(ddata, true); } /* 36xx SGX needs a quirk for to bypass OCP IPG interrupt logic */ @@ -1464,14 +1703,24 @@ return; if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) { - ddata->clk_enable_quirk = sysc_clk_enable_quirk_hdq1w; + ddata->pre_reset_quirk = sysc_pre_reset_quirk_hdq1w; return; } if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) { - ddata->clk_enable_quirk = sysc_clk_enable_quirk_i2c; - ddata->clk_disable_quirk = sysc_clk_disable_quirk_i2c; + ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c; + ddata->post_reset_quirk = sysc_post_reset_quirk_i2c; + + return; + } + + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_AESS) + ddata->module_enable_quirk = sysc_module_enable_quirk_aess; + + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_RTC_UNLOCK) { + ddata->module_unlock_quirk = sysc_module_unlock_quirk_rtc; + ddata->module_lock_quirk = sysc_module_lock_quirk_rtc; return; } @@ -1569,46 +1818,39 @@ */ static int sysc_reset(struct sysc *ddata) { - int sysc_offset, syss_offset, sysc_val, rstval, error = 0; - u32 sysc_mask, syss_done; + int sysc_offset, sysc_val, error; + u32 sysc_mask; sysc_offset = ddata->offsets[SYSC_SYSCONFIG]; - syss_offset = ddata->offsets[SYSC_SYSSTATUS]; - if (ddata->legacy_mode || sysc_offset < 0 || + if (ddata->legacy_mode || ddata->cap->regbits->srst_shift < 0 || ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) return 0; sysc_mask = BIT(ddata->cap->regbits->srst_shift); - if (ddata->cfg.quirks & SYSS_QUIRK_RESETDONE_INVERTED) - syss_done = 0; - else - syss_done = ddata->cfg.syss_mask; - - if (ddata->clk_disable_quirk) - ddata->clk_disable_quirk(ddata); + if (ddata->pre_reset_quirk) + ddata->pre_reset_quirk(ddata); - sysc_val = sysc_read_sysconfig(ddata); - sysc_val |= sysc_mask; - sysc_write(ddata, sysc_offset, sysc_val); + if (sysc_offset >= 0) { + sysc_val = sysc_read_sysconfig(ddata); + sysc_val |= sysc_mask; + sysc_write(ddata, sysc_offset, sysc_val); + /* Flush posted write */ + sysc_val = sysc_read_sysconfig(ddata); + } - if (ddata->clk_enable_quirk) - ddata->clk_enable_quirk(ddata); + if (ddata->cfg.srst_udelay) + usleep_range(ddata->cfg.srst_udelay, + ddata->cfg.srst_udelay * 2); - /* Poll on reset status */ - if (syss_offset >= 0) { - error = readx_poll_timeout(sysc_read_sysstatus, ddata, rstval, - (rstval & ddata->cfg.syss_mask) == - syss_done, - 100, MAX_MODULE_SOFTRESET_WAIT); + if (ddata->post_reset_quirk) + ddata->post_reset_quirk(ddata); - } else if (ddata->cfg.quirks & SYSC_QUIRK_RESET_STATUS) { - error = readx_poll_timeout(sysc_read_sysconfig, ddata, rstval, - !(rstval & sysc_mask), - 100, MAX_MODULE_SOFTRESET_WAIT); - } + error = sysc_wait_softreset(ddata); + if (error) + dev_warn(ddata->dev, "OCP softreset timed out\n"); if (ddata->reset_done_quirk) ddata->reset_done_quirk(ddata); @@ -2500,7 +2742,9 @@ struct sysc *ddata = platform_get_drvdata(pdev); int error; - cancel_delayed_work_sync(&ddata->idle_work); + /* Device can still be enabled, see deferred idle quirk in probe */ + if (cancel_delayed_work_sync(&ddata->idle_work)) + ti_sysc_idle(&ddata->idle_work.work); error = pm_runtime_get_sync(ddata->dev); if (error < 0) { @@ -2513,7 +2757,9 @@ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - reset_control_assert(ddata->rsts); + + if (!reset_control_status(ddata->rsts)) + reset_control_assert(ddata->rsts); unprepare: sysc_unprepare(ddata); --- linux-oracle-5.4.0.orig/drivers/cdrom/cdrom.c +++ linux-oracle-5.4.0/drivers/cdrom/cdrom.c @@ -291,7 +291,7 @@ /* default compatibility mode */ static bool autoclose=1; static bool autoeject; -static bool lockdoor = 1; +static bool lockdoor = 0; /* will we ever get to use this... sigh. */ static bool check_media_type; /* automatically restart mrw format */ @@ -996,6 +996,12 @@ tracks->xa = 0; tracks->error = 0; cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n"); + + if (!CDROM_CAN(CDC_PLAY_AUDIO)) { + tracks->error = CDS_NO_INFO; + return; + } + /* Grab the TOC header so we can see how many tracks there are */ ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header); if (ret) { @@ -1162,7 +1168,8 @@ ret = open_for_data(cdi); if (ret) goto err; - cdrom_mmc3_profile(cdi); + if (CDROM_CAN(CDC_GENERIC_PACKET)) + cdrom_mmc3_profile(cdi); if (mode & FMODE_WRITE) { ret = -EROFS; if (cdrom_open_write(cdi)) @@ -2882,6 +2889,9 @@ it doesn't give enough information or fails. then we return the toc contents. */ use_toc: + if (!CDROM_CAN(CDC_PLAY_AUDIO)) + return -ENOSYS; + toc.cdte_format = CDROM_MSF; toc.cdte_track = CDROM_LEADOUT; if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc))) --- linux-oracle-5.4.0.orig/drivers/cdrom/gdrom.c +++ linux-oracle-5.4.0/drivers/cdrom/gdrom.c @@ -740,6 +740,13 @@ static int probe_gdrom(struct platform_device *devptr) { int err; + + /* + * Ensure our "one" device is initialized properly in case of previous + * usages of it + */ + memset(&gd, 0, sizeof(gd)); + /* Start the device */ if (gdrom_execute_diagnostic() != 1) { pr_warning("ATA Probe for GDROM failed\n"); @@ -828,6 +835,8 @@ if (gdrom_major) unregister_blkdev(gdrom_major, GDROM_DEV_NAME); unregister_cdrom(gd.cd_info); + kfree(gd.cd_info); + kfree(gd.toc); return 0; } @@ -843,7 +852,7 @@ static int __init init_gdrom(void) { int rc; - gd.toc = NULL; + rc = platform_driver_register(&gdrom_driver); if (rc) return rc; @@ -859,8 +868,6 @@ { platform_device_unregister(pd); platform_driver_unregister(&gdrom_driver); - kfree(gd.toc); - kfree(gd.cd_info); } module_init(init_gdrom); --- linux-oracle-5.4.0.orig/drivers/char/Kconfig +++ linux-oracle-5.4.0/drivers/char/Kconfig @@ -535,28 +535,41 @@ and SSM (Silicon Secured Memory). Intended consumers of this driver include crash and makedumpfile. -endmenu - config RANDOM_TRUST_CPU - bool "Trust the CPU manufacturer to initialize Linux's CRNG" - depends on X86 || S390 || PPC - default n + bool "Initialize RNG using CPU RNG instructions" + default y + depends on ARCH_RANDOM help - Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or - RDRAND, IBM for the S390 and Power PC architectures) is trustworthy - for the purposes of initializing Linux's CRNG. Since this is not - something that can be independently audited, this amounts to trusting - that CPU manufacturer (perhaps with the insistence or mandate - of a Nation State's intelligence or law enforcement agencies) - has not installed a hidden back door to compromise the CPU's - random number generation facilities. This can also be configured - at boot with "random.trust_cpu=on/off". + Initialize the RNG using random numbers supplied by the CPU's + RNG instructions (e.g. RDRAND), if supported and available. These + random numbers are never used directly, but are rather hashed into + the main input pool, and this happens regardless of whether or not + this option is enabled. Instead, this option controls whether the + they are credited and hence can initialize the RNG. Additionally, + other sources of randomness are always used, regardless of this + setting. Enabling this implies trusting that the CPU can supply high + quality and non-backdoored random numbers. + + Say Y here unless you have reason to mistrust your CPU or believe + its RNG facilities may be faulty. This may also be configured at + boot time with "random.trust_cpu=on/off". config RANDOM_TRUST_BOOTLOADER - bool "Trust the bootloader to initialize Linux's CRNG" + bool "Initialize RNG using bootloader-supplied seed" + default y help - Some bootloaders can provide entropy to increase the kernel's initial - device randomness. Say Y here to assume the entropy provided by the - booloader is trustworthy so it will be added to the kernel's entropy - pool. Otherwise, say N here so it will be regarded as device input that - only mixes the entropy pool. \ No newline at end of file + Initialize the RNG using a seed supplied by the bootloader or boot + environment (e.g. EFI or a bootloader-generated device tree). This + seed is not used directly, but is rather hashed into the main input + pool, and this happens regardless of whether or not this option is + enabled. Instead, this option controls whether the seed is credited + and hence can initialize the RNG. Additionally, other sources of + randomness are always used, regardless of this setting. Enabling + this implies trusting that the bootloader can supply high quality and + non-backdoored seeds. + + Say Y here unless you have reason to mistrust your bootloader or + believe its RNG facilities may be faulty. This may also be configured + at boot time with "random.trust_bootloader=on/off". + +endmenu --- linux-oracle-5.4.0.orig/drivers/char/agp/Kconfig +++ linux-oracle-5.4.0/drivers/char/agp/Kconfig @@ -125,7 +125,7 @@ config AGP_PARISC tristate "HP Quicksilver AGP support" - depends on AGP && PARISC && 64BIT + depends on AGP && PARISC && 64BIT && IOMMU_SBA help This option gives you AGP GART support for the HP Quicksilver AGP bus adapter on HP PA-RISC machines (Ok, just on the C8000 --- linux-oracle-5.4.0.orig/drivers/char/agp/intel-gtt.c +++ linux-oracle-5.4.0/drivers/char/agp/intel-gtt.c @@ -304,8 +304,10 @@ if (intel_private.needs_dmar) { dma_addr = pci_map_page(intel_private.pcidev, page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) + if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) { + __free_page(page); return -EINVAL; + } intel_private.scratch_page_dma = dma_addr; } else @@ -846,6 +848,7 @@ unsigned int flags) { intel_private.driver->write_entry(addr, pg, flags); + readl(intel_private.gtt + pg); if (intel_private.driver->chipset_flush) intel_private.driver->chipset_flush(); } @@ -871,7 +874,7 @@ j++; } } - wmb(); + readl(intel_private.gtt + j - 1); if (intel_private.driver->chipset_flush) intel_private.driver->chipset_flush(); } @@ -1105,6 +1108,7 @@ static void i9xx_chipset_flush(void) { + wmb(); if (intel_private.i9xx_flush_page) writel(1, intel_private.i9xx_flush_page); } --- linux-oracle-5.4.0.orig/drivers/char/agp/parisc-agp.c +++ linux-oracle-5.4.0/drivers/char/agp/parisc-agp.c @@ -90,6 +90,9 @@ { struct _parisc_agp_info *info = &parisc_agp_info; + /* force fdc ops to be visible to IOMMU */ + asm_io_sync(); + writeq(info->gart_base | ilog2(info->gart_size), info->ioc_regs+IOC_PCOM); readq(info->ioc_regs+IOC_PCOM); /* flush */ } @@ -158,6 +161,7 @@ info->gatt[j] = parisc_agp_mask_memory(agp_bridge, paddr, type); + asm_io_fdc(&info->gatt[j]); } } @@ -191,7 +195,16 @@ parisc_agp_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr, int type) { - return SBA_PDIR_VALID_BIT | addr; + unsigned ci; /* coherent index */ + dma_addr_t pa; + + pa = addr & IOVP_MASK; + asm("lci 0(%1), %0" : "=r" (ci) : "r" (phys_to_virt(pa))); + + pa |= (ci >> PAGE_SHIFT) & 0xff;/* move CI (8 bits) into lowest byte */ + pa |= SBA_PDIR_VALID_BIT; /* set "valid" bit */ + + return cpu_to_le64(pa); } static void @@ -281,7 +294,7 @@ return 0; } -static int +static int __init lba_find_capability(int cap) { struct _parisc_agp_info *info = &parisc_agp_info; @@ -366,7 +379,7 @@ return error; } -static int +static int __init find_quicksilver(struct device *dev, void *data) { struct parisc_device **lba = data; @@ -378,11 +391,9 @@ return 0; } -static int +static int __init parisc_agp_init(void) { - extern struct sba_device *sba_list; - int err = -1; struct parisc_device *sba = NULL, *lba = NULL; struct lba_device *lbadev = NULL; --- linux-oracle-5.4.0.orig/drivers/char/hpet.c +++ linux-oracle-5.4.0/drivers/char/hpet.c @@ -304,8 +304,13 @@ if (!devp->hd_ireqfreq) return -EIO; - if (count < sizeof(unsigned long)) - return -EINVAL; + if (in_compat_syscall()) { + if (count < sizeof(compat_ulong_t)) + return -EINVAL; + } else { + if (count < sizeof(unsigned long)) + return -EINVAL; + } add_wait_queue(&devp->hd_waitqueue, &wait); @@ -329,9 +334,16 @@ schedule(); } - retval = put_user(data, (unsigned long __user *)buf); - if (!retval) - retval = sizeof(unsigned long); + if (in_compat_syscall()) { + retval = put_user(data, (compat_ulong_t __user *)buf); + if (!retval) + retval = sizeof(compat_ulong_t); + } else { + retval = put_user(data, (unsigned long __user *)buf); + if (!retval) + retval = sizeof(unsigned long); + } + out: __set_current_state(TASK_RUNNING); remove_wait_queue(&devp->hd_waitqueue, &wait); @@ -686,12 +698,24 @@ unsigned short hi_timer; }; +/* 32-bit types would lead to different command codes which should be + * translated into 64-bit ones before passed to hpet_ioctl_common + */ +#define COMPAT_HPET_INFO _IOR('h', 0x03, struct compat_hpet_info) +#define COMPAT_HPET_IRQFREQ _IOW('h', 0x6, compat_ulong_t) + static long hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hpet_info info; int err; + if (cmd == COMPAT_HPET_INFO) + cmd = HPET_INFO; + + if (cmd == COMPAT_HPET_IRQFREQ) + cmd = HPET_IRQFREQ; + mutex_lock(&hpet_mutex); err = hpet_ioctl_common(file->private_data, cmd, arg, &info); mutex_unlock(&hpet_mutex); @@ -855,7 +879,7 @@ return 0; } - hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs - 1), + hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs), GFP_KERNEL); if (!hpetp) @@ -984,6 +1008,8 @@ hdp->hd_phys_address = fixmem32->address; hdp->hd_address = ioremap(fixmem32->address, HPET_RANGE_SIZE); + if (!hdp->hd_address) + return AE_ERROR; if (hpet_is_known(hdp)) { iounmap(hdp->hd_address); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/Kconfig +++ linux-oracle-5.4.0/drivers/char/hw_random/Kconfig @@ -308,6 +308,19 @@ If unsure, say Y. +config HW_RANDOM_HISI_V2 + tristate "HiSilicon True Random Number Generator V2 support" + depends on HW_RANDOM && ARM64 && ACPI + default HW_RANDOM + help + This driver provides kernel-side support for the True Random Number + Generator V2 hardware found on HiSilicon Hi1620 SoC. + + To compile this driver as a module, choose M here: the + module will be called hisi-trng-v2. + + If unsure, say Y. + config HW_RANDOM_ST tristate "ST Microelectronics HW Random Number Generator support" depends on HW_RANDOM && ARCH_STI --- linux-oracle-5.4.0.orig/drivers/char/hw_random/Makefile +++ linux-oracle-5.4.0/drivers/char/hw_random/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o +obj-$(CONFIG_HW_RANDOM_HISI_V2) += hisi-trng-v2.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o --- linux-oracle-5.4.0.orig/drivers/char/hw_random/amd-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/amd-rng.c @@ -142,16 +142,22 @@ found: err = pci_read_config_dword(pdev, 0x58, &pmbase); - if (err) - return err; + if (err) { + err = pcibios_err_to_errno(err); + goto put_dev; + } pmbase &= 0x0000FF00; - if (pmbase == 0) - return -EIO; + if (pmbase == 0) { + err = -EIO; + goto put_dev; + } priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + if (!priv) { + err = -ENOMEM; + goto put_dev; + } if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", @@ -185,6 +191,8 @@ release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE); out: kfree(priv); +put_dev: + pci_dev_put(pdev); return err; } @@ -200,6 +208,8 @@ release_region(priv->pmbase + PMBASE_OFFSET, PMBASE_SIZE); + pci_dev_put(priv->pcidev); + kfree(priv); } --- linux-oracle-5.4.0.orig/drivers/char/hw_random/atmel-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/atmel-rng.c @@ -96,6 +96,7 @@ err_register: clk_disable_unprepare(trng->clk); + atmel_trng_disable(trng); return ret; } --- linux-oracle-5.4.0.orig/drivers/char/hw_random/core.c +++ linux-oracle-5.4.0/drivers/char/hw_random/core.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -23,10 +24,13 @@ #include #include #include +#include #include #define RNG_MODULE_NAME "hw_random" +#define RNG_BUFFER_SIZE (SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES) + static struct hwrng *current_rng; /* the current rng has been explicitly chosen by user via sysfs */ static int cur_rng_set_by_user; @@ -58,7 +62,7 @@ static size_t rng_buffer_size(void) { - return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; + return RNG_BUFFER_SIZE; } static void add_early_randomness(struct hwrng *rng) @@ -201,6 +205,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, size_t size, loff_t *offp) { + u8 buffer[RNG_BUFFER_SIZE]; ssize_t ret = 0; int err = 0; int bytes_read, len; @@ -228,34 +233,37 @@ if (bytes_read < 0) { err = bytes_read; goto out_unlock_reading; + } else if (bytes_read == 0 && + (filp->f_flags & O_NONBLOCK)) { + err = -EAGAIN; + goto out_unlock_reading; } + data_avail = bytes_read; } - if (!data_avail) { - if (filp->f_flags & O_NONBLOCK) { - err = -EAGAIN; - goto out_unlock_reading; - } - } else { - len = data_avail; + len = data_avail; + if (len) { if (len > size) len = size; data_avail -= len; - if (copy_to_user(buf + ret, rng_buffer + data_avail, - len)) { + memcpy(buffer, rng_buffer + data_avail, len); + } + mutex_unlock(&reading_mutex); + put_rng(rng); + + if (len) { + if (copy_to_user(buf + ret, buffer, len)) { err = -EFAULT; - goto out_unlock_reading; + goto out; } size -= len; ret += len; } - mutex_unlock(&reading_mutex); - put_rng(rng); if (need_resched()) schedule_timeout_interruptible(1); @@ -266,6 +274,7 @@ } } out: + memzero_explicit(buffer, sizeof(buffer)); return ret ? : err; out_unlock_reading: --- linux-oracle-5.4.0.orig/drivers/char/hw_random/exynos-trng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/exynos-trng.c @@ -134,7 +134,7 @@ return PTR_ERR(trng->mem); pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "Could not get runtime PM.\n"); goto err_pm_get; @@ -167,7 +167,7 @@ clk_disable_unprepare(trng->clk); err_clock: - pm_runtime_put_sync(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); err_pm_get: pm_runtime_disable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/geode-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/geode-rng.c @@ -51,10 +51,15 @@ }; MODULE_DEVICE_TABLE(pci, pci_tbl); +struct amd_geode_priv { + struct pci_dev *pcidev; + void __iomem *membase; +}; static int geode_rng_data_read(struct hwrng *rng, u32 *data) { - void __iomem *mem = (void __iomem *)rng->priv; + struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; + void __iomem *mem = priv->membase; *data = readl(mem + GEODE_RNG_DATA_REG); @@ -63,7 +68,8 @@ static int geode_rng_data_present(struct hwrng *rng, int wait) { - void __iomem *mem = (void __iomem *)rng->priv; + struct amd_geode_priv *priv = (struct amd_geode_priv *)rng->priv; + void __iomem *mem = priv->membase; int data, i; for (i = 0; i < 20; i++) { @@ -90,6 +96,7 @@ const struct pci_device_id *ent; void __iomem *mem; unsigned long rng_base; + struct amd_geode_priv *priv; for_each_pci_dev(pdev) { ent = pci_match_id(pci_tbl, pdev); @@ -97,17 +104,26 @@ goto found; } /* Device not found. */ - goto out; + return err; found: + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + err = -ENOMEM; + goto put_dev; + } + rng_base = pci_resource_start(pdev, 0); if (rng_base == 0) - goto out; + goto free_priv; err = -ENOMEM; mem = ioremap(rng_base, 0x58); if (!mem) - goto out; - geode_rng.priv = (unsigned long)mem; + goto free_priv; + + geode_rng.priv = (unsigned long)priv; + priv->membase = mem; + priv->pcidev = pdev; pr_info("AMD Geode RNG detected\n"); err = hwrng_register(&geode_rng); @@ -116,20 +132,26 @@ err); goto err_unmap; } -out: return err; err_unmap: iounmap(mem); - goto out; +free_priv: + kfree(priv); +put_dev: + pci_dev_put(pdev); + return err; } static void __exit mod_exit(void) { - void __iomem *mem = (void __iomem *)geode_rng.priv; + struct amd_geode_priv *priv; + priv = (struct amd_geode_priv *)geode_rng.priv; hwrng_unregister(&geode_rng); - iounmap(mem); + iounmap(priv->membase); + pci_dev_put(priv->pcidev); + kfree(priv); } module_init(mod_init); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/hisi-trng-v2.c +++ linux-oracle-5.4.0/drivers/char/hw_random/hisi-trng-v2.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 HiSilicon Limited. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HISI_TRNG_REG 0x00F0 +#define HISI_TRNG_BYTES 4 +#define HISI_TRNG_QUALITY 512 +#define SLEEP_US 10 +#define TIMEOUT_US 10000 + +struct hisi_trng { + void __iomem *base; + struct hwrng rng; +}; + +static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + struct hisi_trng *trng; + int currsize = 0; + u32 val = 0; + u32 ret; + + trng = container_of(rng, struct hisi_trng, rng); + + do { + ret = readl_poll_timeout(trng->base + HISI_TRNG_REG, val, + val, SLEEP_US, TIMEOUT_US); + if (ret) + return currsize; + + if (max - currsize >= HISI_TRNG_BYTES) { + memcpy(buf + currsize, &val, HISI_TRNG_BYTES); + currsize += HISI_TRNG_BYTES; + if (currsize == max) + return currsize; + continue; + } + + /* copy remaining bytes */ + memcpy(buf + currsize, &val, max - currsize); + currsize = max; + } while (currsize < max); + + return currsize; +} + +static int hisi_trng_probe(struct platform_device *pdev) +{ + struct hisi_trng *trng; + int ret; + + trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); + if (!trng) + return -ENOMEM; + + trng->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(trng->base)) + return PTR_ERR(trng->base); + + trng->rng.name = pdev->name; + trng->rng.read = hisi_trng_read; + trng->rng.quality = HISI_TRNG_QUALITY; + + ret = devm_hwrng_register(&pdev->dev, &trng->rng); + if (ret) + dev_err(&pdev->dev, "failed to register hwrng!\n"); + + return ret; +} + +static const struct acpi_device_id hisi_trng_acpi_match[] = { + { "HISI02B3", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, hisi_trng_acpi_match); + +static struct platform_driver hisi_trng_driver = { + .probe = hisi_trng_probe, + .driver = { + .name = "hisi-trng-v2", + .acpi_match_table = ACPI_PTR(hisi_trng_acpi_match), + }, +}; + +module_platform_driver(hisi_trng_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Weili Qian "); +MODULE_AUTHOR("Zaibo Xu "); +MODULE_DESCRIPTION("HiSilicon true random number generator V2 driver"); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/imx-rngc.c +++ linux-oracle-5.4.0/drivers/char/hw_random/imx-rngc.c @@ -99,14 +99,16 @@ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND); - ret = wait_for_completion_timeout(&rngc->rng_op_done, RNGC_TIMEOUT); + ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); if (!ret) { imx_rngc_irq_mask_clear(rngc); return -ETIMEDOUT; } - if (rngc->err_reg != 0) + if (rngc->err_reg != 0) { + imx_rngc_irq_mask_clear(rngc); return -EIO; + } return 0; } @@ -180,9 +182,7 @@ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND); - ret = wait_for_completion_timeout(&rngc->rng_op_done, - RNGC_TIMEOUT); - + ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); if (!ret) { imx_rngc_irq_mask_clear(rngc); return -ETIMEDOUT; --- linux-oracle-5.4.0.orig/drivers/char/hw_random/iproc-rng200.c +++ linux-oracle-5.4.0/drivers/char/hw_random/iproc-rng200.c @@ -202,10 +202,12 @@ return PTR_ERR(priv->base); } - priv->rng.name = "iproc-rng200", - priv->rng.read = iproc_rng200_read, - priv->rng.init = iproc_rng200_init, - priv->rng.cleanup = iproc_rng200_cleanup, + dev_set_drvdata(dev, priv); + + priv->rng.name = "iproc-rng200"; + priv->rng.read = iproc_rng200_read; + priv->rng.init = iproc_rng200_init; + priv->rng.cleanup = iproc_rng200_cleanup; /* Register driver */ ret = devm_hwrng_register(dev, &priv->rng); @@ -219,6 +221,28 @@ return 0; } +static int __maybe_unused iproc_rng200_suspend(struct device *dev) +{ + struct iproc_rng200_dev *priv = dev_get_drvdata(dev); + + iproc_rng200_cleanup(&priv->rng); + + return 0; +} + +static int __maybe_unused iproc_rng200_resume(struct device *dev) +{ + struct iproc_rng200_dev *priv = dev_get_drvdata(dev); + + iproc_rng200_init(&priv->rng); + + return 0; +} + +static const struct dev_pm_ops iproc_rng200_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(iproc_rng200_suspend, iproc_rng200_resume) +}; + static const struct of_device_id iproc_rng200_of_match[] = { { .compatible = "brcm,bcm7211-rng200", }, { .compatible = "brcm,bcm7278-rng200", }, @@ -231,6 +255,7 @@ .driver = { .name = "iproc-rng200", .of_match_table = iproc_rng200_of_match, + .pm = &iproc_rng200_pm_ops, }, .probe = iproc_rng200_probe, }; --- linux-oracle-5.4.0.orig/drivers/char/hw_random/ks-sa-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/ks-sa-rng.c @@ -208,6 +208,7 @@ ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "Failed to enable SA power-domain\n"); + pm_runtime_put_noidle(dev); pm_runtime_disable(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/char/hw_random/mtk-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/mtk-rng.c @@ -149,7 +149,7 @@ dev_set_drvdata(&pdev->dev, priv); pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(&pdev->dev); + devm_pm_runtime_enable(&pdev->dev); dev_info(&pdev->dev, "registered RNG driver\n"); @@ -173,8 +173,13 @@ return mtk_rng_init(&priv->rng); } -static UNIVERSAL_DEV_PM_OPS(mtk_rng_pm_ops, mtk_rng_runtime_suspend, - mtk_rng_runtime_resume, NULL); +static const struct dev_pm_ops mtk_rng_pm_ops = { + SET_RUNTIME_PM_OPS(mtk_rng_runtime_suspend, + mtk_rng_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + #define MTK_RNG_PM_OPS (&mtk_rng_pm_ops) #else /* CONFIG_PM */ #define MTK_RNG_PM_OPS NULL --- linux-oracle-5.4.0.orig/drivers/char/hw_random/omap-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/omap-rng.c @@ -66,6 +66,13 @@ #define OMAP4_RNG_OUTPUT_SIZE 0x8 #define EIP76_RNG_OUTPUT_SIZE 0x10 +/* + * EIP76 RNG takes approx. 700us to produce 16 bytes of output data + * as per testing results. And to account for the lack of udelay()'s + * reliability, we keep the timeout as 1000us. + */ +#define RNG_DATA_FILL_TIMEOUT 100 + enum { RNG_OUTPUT_0_REG = 0, RNG_OUTPUT_1_REG, @@ -176,7 +183,7 @@ if (max < priv->pdata->data_size) return 0; - for (i = 0; i < 20; i++) { + for (i = 0; i < RNG_DATA_FILL_TIMEOUT; i++) { present = priv->pdata->data_present(priv); if (present || !wait) break; --- linux-oracle-5.4.0.orig/drivers/char/hw_random/omap3-rom-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/omap3-rom-rng.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #define RNG_RESET 0x01 @@ -86,14 +88,18 @@ static struct hwrng omap3_rom_rng_ops = { .name = "omap3-rom", - .read = omap3_rom_rng_read, }; static int omap3_rom_rng_probe(struct platform_device *pdev) { int ret = 0; - pr_info("initializing\n"); + omap3_rom_rng_ops.read = of_device_get_match_data(&pdev->dev); + if (!omap3_rom_rng_ops.read) { + dev_err(&pdev->dev, "missing rom code handler\n"); + + return -ENODEV; + } omap3_rom_rng_call = pdev->dev.platform_data; if (!omap3_rom_rng_call) { @@ -121,13 +127,21 @@ { cancel_delayed_work_sync(&idle_work); hwrng_unregister(&omap3_rom_rng_ops); - clk_disable_unprepare(rng_clk); + if (!rng_idle) + clk_disable_unprepare(rng_clk); return 0; } +static const struct of_device_id omap_rom_rng_match[] = { + { .compatible = "nokia,n900-rom-rng", .data = omap3_rom_rng_read, }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, omap_rom_rng_match); + static struct platform_driver omap3_rom_rng_driver = { .driver = { .name = "omap3-rom-rng", + .of_match_table = omap_rom_rng_match, }, .probe = omap3_rom_rng_probe, .remove = omap3_rom_rng_remove, --- linux-oracle-5.4.0.orig/drivers/char/hw_random/st-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/st-rng.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -41,7 +42,6 @@ struct st_rng_data { void __iomem *base; - struct clk *clk; struct hwrng ops; }; @@ -86,26 +86,18 @@ if (IS_ERR(base)) return PTR_ERR(base); - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); - ret = clk_prepare_enable(clk); - if (ret) - return ret; - ddata->ops.priv = (unsigned long)ddata; ddata->ops.read = st_rng_read; ddata->ops.name = pdev->name; ddata->base = base; - ddata->clk = clk; - - dev_set_drvdata(&pdev->dev, ddata); ret = devm_hwrng_register(&pdev->dev, &ddata->ops); if (ret) { dev_err(&pdev->dev, "Failed to register HW RNG\n"); - clk_disable_unprepare(clk); return ret; } @@ -114,16 +106,7 @@ return 0; } -static int st_rng_remove(struct platform_device *pdev) -{ - struct st_rng_data *ddata = dev_get_drvdata(&pdev->dev); - - clk_disable_unprepare(ddata->clk); - - return 0; -} - -static const struct of_device_id st_rng_match[] = { +static const struct of_device_id st_rng_match[] __maybe_unused = { { .compatible = "st,rng" }, {}, }; @@ -135,7 +118,6 @@ .of_match_table = of_match_ptr(st_rng_match), }, .probe = st_rng_probe, - .remove = st_rng_remove }; module_platform_driver(st_rng_driver); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/timeriomem-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/timeriomem-rng.c @@ -69,7 +69,7 @@ */ if (retval > 0) usleep_range(period_us, - period_us + min(1, period_us / 100)); + period_us + max(1, period_us / 100)); *(u32 *)data = readl(priv->io_base); retval += sizeof(u32); --- linux-oracle-5.4.0.orig/drivers/char/hw_random/virtio-rng.c +++ linux-oracle-5.4.0/drivers/char/hw_random/virtio-rng.c @@ -4,6 +4,7 @@ * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation */ +#include #include #include #include @@ -17,71 +18,111 @@ struct virtrng_info { struct hwrng hwrng; struct virtqueue *vq; - struct completion have_data; char name[25]; - unsigned int data_avail; int index; - bool busy; bool hwrng_register_done; bool hwrng_removed; + /* data transfer */ + struct completion have_data; + unsigned int data_avail; + unsigned int data_idx; + /* minimal size returned by rng_buffer_size() */ +#if SMP_CACHE_BYTES < 32 + u8 data[32]; +#else + u8 data[SMP_CACHE_BYTES]; +#endif }; static void random_recv_done(struct virtqueue *vq) { struct virtrng_info *vi = vq->vdev->priv; + unsigned int len; /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */ - if (!virtqueue_get_buf(vi->vq, &vi->data_avail)) + if (!virtqueue_get_buf(vi->vq, &len)) return; + smp_store_release(&vi->data_avail, len); complete(&vi->have_data); } -/* The host will fill any buffer we give it with sweet, sweet randomness. */ -static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size) +static void request_entropy(struct virtrng_info *vi) { struct scatterlist sg; - sg_init_one(&sg, buf, size); + reinit_completion(&vi->have_data); + vi->data_idx = 0; + + sg_init_one(&sg, vi->data, sizeof(vi->data)); /* There should always be room for one buffer. */ - virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL); + virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL); virtqueue_kick(vi->vq); } +static unsigned int copy_data(struct virtrng_info *vi, void *buf, + unsigned int size) +{ + size = min_t(unsigned int, size, vi->data_avail); + memcpy(buf, vi->data + vi->data_idx, size); + vi->data_idx += size; + vi->data_avail -= size; + if (vi->data_avail == 0) + request_entropy(vi); + return size; +} + static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) { int ret; struct virtrng_info *vi = (struct virtrng_info *)rng->priv; + unsigned int chunk; + size_t read; if (vi->hwrng_removed) return -ENODEV; - if (!vi->busy) { - vi->busy = true; - reinit_completion(&vi->have_data); - register_buffer(vi, buf, size); + read = 0; + + /* copy available data */ + if (smp_load_acquire(&vi->data_avail)) { + chunk = copy_data(vi, buf, size); + size -= chunk; + read += chunk; } if (!wait) - return 0; - - ret = wait_for_completion_killable(&vi->have_data); - if (ret < 0) - return ret; + return read; - vi->busy = false; + /* We have already copied available entropy, + * so either size is 0 or data_avail is 0 + */ + while (size != 0) { + /* data_avail is 0 but a request is pending */ + ret = wait_for_completion_killable(&vi->have_data); + if (ret < 0) + return ret; + /* if vi->data_avail is 0, we have been interrupted + * by a cleanup, but buffer stays in the queue + */ + if (vi->data_avail == 0) + return read; + + chunk = copy_data(vi, buf + read, size); + size -= chunk; + read += chunk; + } - return vi->data_avail; + return read; } static void virtio_cleanup(struct hwrng *rng) { struct virtrng_info *vi = (struct virtrng_info *)rng->priv; - if (vi->busy) - wait_for_completion(&vi->have_data); + complete(&vi->have_data); } static int probe_common(struct virtio_device *vdev) @@ -117,6 +158,9 @@ goto err_find; } + /* we always have a pending entropy request */ + request_entropy(vi); + return 0; err_find: @@ -132,9 +176,9 @@ vi->hwrng_removed = true; vi->data_avail = 0; + vi->data_idx = 0; complete(&vi->have_data); vdev->config->reset(vdev); - vi->busy = false; if (vi->hwrng_register_done) hwrng_unregister(&vi->hwrng); vdev->config->del_vqs(vdev); --- linux-oracle-5.4.0.orig/drivers/char/ipmi/bt-bmc.c +++ linux-oracle-5.4.0/drivers/char/ipmi/bt-bmc.c @@ -399,15 +399,15 @@ struct device *dev = &pdev->dev; int rc; - bt_bmc->irq = platform_get_irq(pdev, 0); - if (!bt_bmc->irq) - return -ENODEV; + bt_bmc->irq = platform_get_irq_optional(pdev, 0); + if (bt_bmc->irq < 0) + return bt_bmc->irq; rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED, DEVICE_NAME, bt_bmc); if (rc < 0) { dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq); - bt_bmc->irq = 0; + bt_bmc->irq = rc; return rc; } @@ -479,7 +479,7 @@ bt_bmc_config_irq(bt_bmc, pdev); - if (bt_bmc->irq) { + if (bt_bmc->irq >= 0) { dev_info(dev, "Using IRQ %d\n", bt_bmc->irq); } else { dev_info(dev, "No IRQ; using timer\n"); @@ -505,7 +505,7 @@ struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev); misc_deregister(&bt_bmc->miscdev); - if (!bt_bmc->irq) + if (bt_bmc->irq < 0) del_timer_sync(&bt_bmc->poll_timer); return 0; } --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmb_dev_int.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmb_dev_int.c @@ -265,7 +265,7 @@ break; case I2C_SLAVE_WRITE_RECEIVED: - if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg)) + if (ipmb_dev->msg_idx >= sizeof(struct ipmb_msg) - 1) break; buf[++ipmb_dev->msg_idx] = *val; @@ -309,6 +309,9 @@ ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL, "%s%d", "ipmb-", client->adapter->nr); + if (!ipmb_dev->miscdev.name) + return -ENOMEM; + ipmb_dev->miscdev.fops = &ipmb_fops; ipmb_dev->miscdev.parent = &client->dev; ret = misc_register(&ipmb_dev->miscdev); --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmi_msghandler.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmi_msghandler.c @@ -11,8 +11,8 @@ * Copyright 2002 MontaVista Software Inc. */ -#define pr_fmt(fmt) "%s" fmt, "IPMI message handler: " -#define dev_fmt pr_fmt +#define pr_fmt(fmt) "IPMI message handler: " fmt +#define dev_fmt(fmt) pr_fmt(fmt) #include #include @@ -33,6 +33,7 @@ #include #include #include +#include #define IPMI_DRIVER_VERSION "39.2" @@ -219,6 +220,8 @@ struct work_struct remove_work; }; +static struct workqueue_struct *remove_work_wq; + static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) __acquires(user->release_barrier) { @@ -448,6 +451,8 @@ #define IPMI_IPMB_NUM_SEQ 64 struct ipmi_smi { + struct module *owner; + /* What interface number are we? */ int intf_num; @@ -1168,7 +1173,7 @@ remove_work); cleanup_srcu_struct(&user->release_barrier); - kfree(user); + vfree(user); } int ipmi_create_user(unsigned int if_num, @@ -1200,7 +1205,7 @@ if (rv) return rv; - new_user = kmalloc(sizeof(*new_user), GFP_KERNEL); + new_user = vzalloc(sizeof(*new_user)); if (!new_user) return -ENOMEM; @@ -1220,6 +1225,11 @@ if (rv) goto out_kfree; + if (!try_module_get(intf->owner)) { + rv = -ENODEV; + goto out_kfree; + } + /* Note that each existing user holds a refcount to the interface. */ kref_get(&intf->refcount); @@ -1242,7 +1252,7 @@ out_kfree: srcu_read_unlock(&ipmi_interfaces_srcu, index); - kfree(new_user); + vfree(new_user); return rv; } EXPORT_SYMBOL(ipmi_create_user); @@ -1278,7 +1288,7 @@ struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); /* SRCU cleanup must happen in task context. */ - schedule_work(&user->remove_work); + queue_work(remove_work_wq, &user->remove_work); } static void _ipmi_destroy_user(struct ipmi_user *user) @@ -1288,6 +1298,7 @@ unsigned long flags; struct cmd_rcvr *rcvr; struct cmd_rcvr *rcvrs = NULL; + struct module *owner; if (!acquire_ipmi_user(user, &i)) { /* @@ -1348,7 +1359,9 @@ kfree(rcvr); } + owner = intf->owner; kref_put(&intf->refcount, intf_free); + module_put(owner); } int ipmi_destroy_user(struct ipmi_user *user) @@ -2459,7 +2472,7 @@ * been recently fetched, this will just use the cached data. Otherwise * it will run a new fetch. * - * Except for the first time this is called (in ipmi_register_smi()), + * Except for the first time this is called (in ipmi_add_smi()), * this will always return good data; */ static int __bmc_get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc, @@ -2927,7 +2940,7 @@ * with removing the device attributes while reading a device * attribute. */ - schedule_work(&bmc->remove_work); + queue_work(remove_work_wq, &bmc->remove_work); } /* @@ -3031,8 +3044,11 @@ bmc->pdev.name = "ipmi_bmc"; rv = ida_simple_get(&ipmi_bmc_ida, 0, 0, GFP_KERNEL); - if (rv < 0) + if (rv < 0) { + kfree(bmc); goto out; + } + bmc->pdev.dev.driver = &ipmidriver.driver; bmc->pdev.id = rv; bmc->pdev.dev.release = release_bmc_device; @@ -3196,8 +3212,8 @@ if (rv) /* Send failed, no GUID available. */ bmc->dyn_guid_set = 0; - - wait_event(intf->waitq, bmc->dyn_guid_set != 2); + else + wait_event(intf->waitq, bmc->dyn_guid_set != 2); /* dyn_guid_set makes the guid data available. */ smp_rmb(); @@ -3377,10 +3393,11 @@ kref_put(&intf->refcount, intf_free); } -int ipmi_register_smi(const struct ipmi_smi_handlers *handlers, - void *send_info, - struct device *si_dev, - unsigned char slave_addr) +int ipmi_add_smi(struct module *owner, + const struct ipmi_smi_handlers *handlers, + void *send_info, + struct device *si_dev, + unsigned char slave_addr) { int i, j; int rv; @@ -3406,7 +3423,7 @@ return rv; } - + intf->owner = owner; intf->bmc = &intf->tmp_bmc; INIT_LIST_HEAD(&intf->bmc->intfs); mutex_init(&intf->bmc->dyn_mutex); @@ -3514,18 +3531,22 @@ return rv; } -EXPORT_SYMBOL(ipmi_register_smi); +EXPORT_SYMBOL(ipmi_add_smi); static void deliver_smi_err_response(struct ipmi_smi *intf, struct ipmi_smi_msg *msg, unsigned char err) { + int rv; msg->rsp[0] = msg->data[0] | 4; msg->rsp[1] = msg->data[1]; msg->rsp[2] = err; msg->rsp_size = 3; - /* It's an error, so it will never requeue, no need to check return. */ - handle_one_recv_msg(intf, msg); + + /* This will never requeue, but it may ask us to free the message. */ + rv = handle_one_recv_msg(intf, msg); + if (rv == 0) + ipmi_free_smi_msg(msg); } static void cleanup_smi_msgs(struct ipmi_smi *intf) @@ -4784,7 +4805,9 @@ static void free_smi_msg(struct ipmi_smi_msg *msg) { atomic_dec(&smi_msg_inuse_count); - kfree(msg); + /* Try to keep as much stuff out of the panic path as possible. */ + if (!oops_in_progress) + kfree(msg); } struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) @@ -4803,7 +4826,9 @@ static void free_recv_msg(struct ipmi_recv_msg *msg) { atomic_dec(&recv_msg_inuse_count); - kfree(msg); + /* Try to keep as much stuff out of the panic path as possible. */ + if (!oops_in_progress) + kfree(msg); } static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) @@ -4821,7 +4846,7 @@ void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) { - if (msg->user) + if (msg->user && !oops_in_progress) kref_put(&msg->user->refcount, free_user); msg->done(msg); } @@ -5137,7 +5162,16 @@ if (initialized) goto out; - init_srcu_struct(&ipmi_interfaces_srcu); + rv = init_srcu_struct(&ipmi_interfaces_srcu); + if (rv) + goto out; + + remove_work_wq = create_singlethread_workqueue("ipmi-msghandler-remove-wq"); + if (!remove_work_wq) { + pr_err("unable to create ipmi-msghandler-remove-wq workqueue"); + rv = -ENOMEM; + goto out_wq; + } timer_setup(&ipmi_timer, ipmi_timeout, 0); mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); @@ -5146,6 +5180,9 @@ initialized = true; +out_wq: + if (rv) + cleanup_srcu_struct(&ipmi_interfaces_srcu); out: mutex_unlock(&ipmi_interfaces_mutex); return rv; @@ -5169,6 +5206,8 @@ int count; if (initialized) { + destroy_workqueue(remove_work_wq); + atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block); --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmi_si_intf.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmi_si_intf.c @@ -1977,7 +1977,7 @@ /* Do this early so it's available for logs. */ if (!new_smi->io.dev) { pr_err("IPMI interface added with no device\n"); - rv = EIO; + rv = -EIO; goto out_err; } @@ -2086,6 +2086,11 @@ new_smi->io.io_cleanup = NULL; } + if (rv && new_smi->si_sm) { + kfree(new_smi->si_sm); + new_smi->si_sm = NULL; + } + return rv; } @@ -2157,6 +2162,20 @@ } module_init(init_ipmi_si); +static void wait_msg_processed(struct smi_info *smi_info) +{ + unsigned long jiffies_now; + long time_diff; + + while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { + jiffies_now = jiffies; + time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies) + * SI_USEC_PER_JIFFY); + smi_event_handler(smi_info, time_diff); + schedule_timeout_uninterruptible(1); + } +} + static void shutdown_smi(void *send_info) { struct smi_info *smi_info = send_info; @@ -2191,16 +2210,13 @@ * in the BMC. Note that timers and CPU interrupts are off, * so no need for locks. */ - while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { - poll(smi_info); - schedule_timeout_uninterruptible(1); - } + wait_msg_processed(smi_info); + if (smi_info->handlers) disable_si_irq(smi_info); - while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { - poll(smi_info); - schedule_timeout_uninterruptible(1); - } + + wait_msg_processed(smi_info); + if (smi_info->handlers) smi_info->handlers->cleanup(smi_info->si_sm); --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmi_si_platform.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmi_si_platform.c @@ -194,7 +194,7 @@ else io.slave_addr = slave_addr; - io.irq = platform_get_irq(pdev, 0); + io.irq = platform_get_irq_optional(pdev, 0); if (io.irq > 0) io.irq_setup = ipmi_std_irq_setup; else @@ -378,7 +378,7 @@ io.irq = tmp; io.irq_setup = acpi_gpe_irq_setup; } else { - int irq = platform_get_irq(pdev, 0); + int irq = platform_get_irq_optional(pdev, 0); if (irq > 0) { io.irq = irq; --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmi_ssif.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmi_ssif.c @@ -79,7 +79,8 @@ /* * Timer values */ -#define SSIF_MSG_USEC 20000 /* 20ms between message tries. */ +#define SSIF_MSG_USEC 60000 /* 60ms between message tries (T3). */ +#define SSIF_REQ_RETRY_USEC 60000 /* 60ms between send retries (T6). */ #define SSIF_MSG_PART_USEC 5000 /* 5ms for a message part */ /* How many times to we retry sending/receiving the message. */ @@ -87,7 +88,9 @@ #define SSIF_RECV_RETRIES 250 #define SSIF_MSG_MSEC (SSIF_MSG_USEC / 1000) +#define SSIF_REQ_RETRY_MSEC (SSIF_REQ_RETRY_USEC / 1000) #define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC) +#define SSIF_REQ_RETRY_JIFFIES ((SSIF_REQ_RETRY_USEC * 1000) / TICK_NSEC) #define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC) /* @@ -97,7 +100,7 @@ #define SSIF_WATCH_WATCHDOG_TIMEOUT msecs_to_jiffies(250) enum ssif_intf_state { - SSIF_NORMAL, + SSIF_IDLE, SSIF_GETTING_FLAGS, SSIF_GETTING_EVENTS, SSIF_CLEARING_FLAGS, @@ -105,8 +108,8 @@ /* FIXME - add watchdog stuff. */ }; -#define SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_NORMAL \ - && (ssif)->curr_msg == NULL) +#define IS_SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_IDLE \ + && (ssif)->curr_msg == NULL) /* * Indexes into stats[] in ssif_info below. @@ -236,6 +239,9 @@ bool got_alert; bool waiting_alert; + /* Used to inform the timeout that it should do a resend. */ + bool do_resend; + /* * If set to true, this will request events the next time the * state machine is idle. @@ -248,12 +254,6 @@ */ bool req_flags; - /* - * Used to perform timer operations when run-to-completion - * mode is on. This is a countdown timer. - */ - int rtc_us_timer; - /* Used for sending/receiving data. +1 for the length. */ unsigned char data[IPMI_MAX_MSG_LENGTH + 1]; unsigned int data_len; @@ -353,9 +353,9 @@ /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -372,7 +372,7 @@ if (start_send(ssif_info, msg, 3) != 0) { /* Error, just go to normal state. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } } @@ -387,7 +387,7 @@ mb[0] = (IPMI_NETFN_APP_REQUEST << 2); mb[1] = IPMI_GET_MSG_FLAGS_CMD; if (start_send(ssif_info, mb, 2) != 0) - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; } static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, @@ -398,7 +398,7 @@ flags = ipmi_ssif_lock_cond(ssif_info, &oflags); ssif_info->curr_msg = NULL; - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); ipmi_free_smi_msg(msg); } @@ -412,7 +412,7 @@ msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -435,7 +435,7 @@ msg = ipmi_alloc_smi_msg(); if (!msg) { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -453,9 +453,9 @@ /* * Must be called with the message lock held. This will release the - * message lock. Note that the caller will check SSIF_IDLE and start a - * new operation, so there is no need to check for new messages to - * start in here. + * message lock. Note that the caller will check IS_SSIF_IDLE and + * start a new operation, so there is no need to check for new + * messages to start in here. */ static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) { @@ -471,7 +471,7 @@ /* Events available. */ start_event_fetch(ssif_info, flags); else { - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); } } @@ -515,7 +515,7 @@ return 0; } -static int ssif_i2c_send(struct ssif_info *ssif_info, +static void ssif_i2c_send(struct ssif_info *ssif_info, ssif_i2c_done handler, int read_write, int command, unsigned char *data, unsigned int size) @@ -527,7 +527,6 @@ ssif_info->i2c_data = data; ssif_info->i2c_size = size; complete(&ssif_info->wake_thread); - return 0; } @@ -536,40 +535,37 @@ static void start_get(struct ssif_info *ssif_info) { - int rv; - - ssif_info->rtc_us_timer = 0; ssif_info->multi_pos = 0; - rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, - SSIF_IPMI_RESPONSE, - ssif_info->recv, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - /* request failed, just return the error. */ - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(5)\n"); - - msg_done_handler(ssif_info, -EIO, NULL, 0); - } + ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, + SSIF_IPMI_RESPONSE, + ssif_info->recv, I2C_SMBUS_BLOCK_DATA); } +static void start_resend(struct ssif_info *ssif_info); + static void retry_timeout(struct timer_list *t) { struct ssif_info *ssif_info = from_timer(ssif_info, t, retry_timer); unsigned long oflags, *flags; - bool waiting; + bool waiting, resend; if (ssif_info->stopping) return; flags = ipmi_ssif_lock_cond(ssif_info, &oflags); + resend = ssif_info->do_resend; + ssif_info->do_resend = false; waiting = ssif_info->waiting_alert; ssif_info->waiting_alert = false; ipmi_ssif_unlock_cond(ssif_info, flags); if (waiting) start_get(ssif_info); + if (resend) { + start_resend(ssif_info); + ssif_inc_stat(ssif_info, send_retries); + } } static void watch_timeout(struct timer_list *t) @@ -584,7 +580,7 @@ if (ssif_info->watch_timeout) { mod_timer(&ssif_info->watch_timer, jiffies + ssif_info->watch_timeout); - if (SSIF_IDLE(ssif_info)) { + if (IS_SSIF_IDLE(ssif_info)) { start_flag_fetch(ssif_info, flags); /* Releases lock */ return; } @@ -618,14 +614,11 @@ start_get(ssif_info); } -static int start_resend(struct ssif_info *ssif_info); - static void msg_done_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len) { struct ipmi_smi_msg *msg; unsigned long oflags, *flags; - int rv; /* * We are single-threaded here, so no need for a lock until we @@ -639,7 +632,6 @@ flags = ipmi_ssif_lock_cond(ssif_info, &oflags); ssif_info->waiting_alert = true; - ssif_info->rtc_us_timer = SSIF_MSG_USEC; if (!ssif_info->stopping) mod_timer(&ssif_info->retry_timer, jiffies + SSIF_MSG_JIFFIES); @@ -671,17 +663,10 @@ ssif_info->multi_len = len; ssif_info->multi_pos = 1; - rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, - SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, - ssif_info->recv, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(1)\n"); - - result = -EIO; - } else - return; + ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, + SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, + ssif_info->recv, I2C_SMBUS_BLOCK_DATA); + return; } else if (ssif_info->multi_pos) { /* Middle of multi-part read. Start the next transaction. */ int i; @@ -743,19 +728,12 @@ ssif_info->multi_pos++; - rv = ssif_i2c_send(ssif_info, msg_done_handler, - I2C_SMBUS_READ, - SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, - ssif_info->recv, - I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from ssif_i2c_send\n"); - - result = -EIO; - } else - return; + ssif_i2c_send(ssif_info, msg_done_handler, + I2C_SMBUS_READ, + SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, + ssif_info->recv, + I2C_SMBUS_BLOCK_DATA); + return; } } @@ -775,15 +753,19 @@ flags = ipmi_ssif_lock_cond(ssif_info, &oflags); msg = ssif_info->curr_msg; if (msg) { + if (data) { + if (len > IPMI_MAX_MSG_LENGTH) + len = IPMI_MAX_MSG_LENGTH; + memcpy(msg->rsp, data, len); + } else { + len = 0; + } msg->rsp_size = len; - if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) - msg->rsp_size = IPMI_MAX_MSG_LENGTH; - memcpy(msg->rsp, data, msg->rsp_size); ssif_info->curr_msg = NULL; } switch (ssif_info->ssif_state) { - case SSIF_NORMAL: + case SSIF_IDLE: ipmi_ssif_unlock_cond(ssif_info, flags); if (!msg) break; @@ -801,7 +783,7 @@ * Error fetching flags, or invalid length, * just give up for now. */ - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); dev_warn(&ssif_info->client->dev, "Error getting flags: %d %d, %x\n", @@ -809,9 +791,9 @@ } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || data[1] != IPMI_GET_MSG_FLAGS_CMD) { /* - * Don't abort here, maybe it was a queued - * response to a previous command. + * Recv error response, give up. */ + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); dev_warn(&ssif_info->client->dev, "Invalid response getting flags: %x %x\n", @@ -836,11 +818,19 @@ "Invalid response clearing flags: %x %x\n", data[0], data[1]); } - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; ipmi_ssif_unlock_cond(ssif_info, flags); break; case SSIF_GETTING_EVENTS: + if (!msg) { + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "No message set while getting events\n"); + ipmi_ssif_unlock_cond(ssif_info, flags); + break; + } + if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { /* Error getting event, probably done. */ msg->done(msg); @@ -865,6 +855,14 @@ break; case SSIF_GETTING_MESSAGES: + if (!msg) { + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "No message set while getting messages\n"); + ipmi_ssif_unlock_cond(ssif_info, flags); + break; + } + if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { /* Error getting event, probably done. */ msg->done(msg); @@ -888,10 +886,17 @@ deliver_recv_msg(ssif_info, msg); } break; + + default: + /* Should never happen, but just in case. */ + dev_warn(&ssif_info->client->dev, + "Invalid state in message done handling: %d\n", + ssif_info->ssif_state); + ipmi_ssif_unlock_cond(ssif_info, flags); } flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) { + if (IS_SSIF_IDLE(ssif_info) && !ssif_info->stopping) { if (ssif_info->req_events) start_event_fetch(ssif_info, flags); else if (ssif_info->req_flags) @@ -909,37 +914,27 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, unsigned char *data, unsigned int len) { - int rv; - /* We are single-threaded here, so no need for a lock. */ if (result < 0) { ssif_info->retries_left--; if (ssif_info->retries_left > 0) { - if (!start_resend(ssif_info)) { - ssif_inc_stat(ssif_info, send_retries); - return; - } - /* request failed, just return the error. */ - ssif_inc_stat(ssif_info, send_errors); - - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "%s: Out of retries\n", __func__); - msg_done_handler(ssif_info, -EIO, NULL, 0); + /* + * Wait the retry timeout time per the spec, + * then redo the send. + */ + ssif_info->do_resend = true; + mod_timer(&ssif_info->retry_timer, + jiffies + SSIF_REQ_RETRY_JIFFIES); return; } ssif_inc_stat(ssif_info, send_errors); - /* - * Got an error on transmit, let the done routine - * handle it. - */ if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) dev_dbg(&ssif_info->client->dev, - "%s: Error %d\n", __func__, result); + "%s: Out of retries\n", __func__); - msg_done_handler(ssif_info, result, NULL, 0); + msg_done_handler(ssif_info, -EIO, NULL, 0); return; } @@ -973,18 +968,9 @@ ssif_info->multi_data = NULL; } - rv = ssif_i2c_send(ssif_info, msg_written_handler, - I2C_SMBUS_WRITE, cmd, - data_to_send, I2C_SMBUS_BLOCK_DATA); - if (rv < 0) { - /* request failed, just return the error. */ - ssif_inc_stat(ssif_info, send_errors); - - if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(3)\n"); - msg_done_handler(ssif_info, -EIO, NULL, 0); - } + ssif_i2c_send(ssif_info, msg_written_handler, + I2C_SMBUS_WRITE, cmd, + data_to_send, I2C_SMBUS_BLOCK_DATA); } else { /* Ready to request the result. */ unsigned long oflags, *flags; @@ -1002,7 +988,6 @@ /* Wait a jiffie then request the next message */ ssif_info->waiting_alert = true; ssif_info->retries_left = SSIF_RECV_RETRIES; - ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; if (!ssif_info->stopping) mod_timer(&ssif_info->retry_timer, jiffies + SSIF_MSG_PART_JIFFIES); @@ -1011,9 +996,8 @@ } } -static int start_resend(struct ssif_info *ssif_info) +static void start_resend(struct ssif_info *ssif_info) { - int rv; int command; ssif_info->got_alert = false; @@ -1035,12 +1019,8 @@ ssif_info->data[0] = ssif_info->data_len; } - rv = ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, - command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); - if (rv && (ssif_info->ssif_debug & SSIF_DEBUG_MSG)) - dev_dbg(&ssif_info->client->dev, - "Error from i2c_non_blocking_op(4)\n"); - return rv; + ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, + command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); } static int start_send(struct ssif_info *ssif_info, @@ -1055,7 +1035,8 @@ ssif_info->retries_left = SSIF_SEND_RETRIES; memcpy(ssif_info->data + 1, data, len); ssif_info->data_len = len; - return start_resend(ssif_info); + start_resend(ssif_info); + return 0; } /* Must be called with the message lock held. */ @@ -1065,7 +1046,7 @@ unsigned long oflags; restart: - if (!SSIF_IDLE(ssif_info)) { + if (!IS_SSIF_IDLE(ssif_info)) { ipmi_ssif_unlock_cond(ssif_info, flags); return; } @@ -1288,7 +1269,7 @@ dev_set_drvdata(&ssif_info->client->dev, NULL); /* make sure the driver is not looking for flags any more. */ - while (ssif_info->ssif_state != SSIF_NORMAL) + while (ssif_info->ssif_state != SSIF_IDLE) schedule_timeout(1); ssif_info->stopping = true; @@ -1355,8 +1336,10 @@ ret = i2c_smbus_write_block_data(client, SSIF_IPMI_REQUEST, len, msg); if (ret) { retry_cnt--; - if (retry_cnt > 0) + if (retry_cnt > 0) { + msleep(SSIF_REQ_RETRY_MSEC); goto retry1; + } return -ENODEV; } @@ -1427,7 +1410,7 @@ restart: list_for_each_entry(info, &ssif_infos, link) { if (info->binfo.addr == addr) { - if (info->addr_src == SI_SMBIOS) + if (info->addr_src == SI_SMBIOS && !info->adapter_name) info->adapter_name = kstrdup(adapter_name, GFP_KERNEL); @@ -1496,8 +1479,10 @@ 32, msg); if (ret) { retry_cnt--; - if (retry_cnt > 0) + if (retry_cnt > 0) { + msleep(SSIF_REQ_RETRY_MSEC); goto retry_write; + } dev_err(&client->dev, "Could not write multi-part start, though the BMC said it could handle it. Just limit sends to one part.\n"); return ret; } @@ -1624,6 +1609,11 @@ info->addr_src = SI_ACPI; info->client = client; info->adapter_name = kstrdup(client->adapter->name, GFP_KERNEL); + if (!info->adapter_name) { + kfree(info); + return -ENOMEM; + } + info->binfo.addr = client->addr; list_add_tail(&info->link, &ssif_infos); return 0; @@ -1700,6 +1690,9 @@ } } + ssif_info->client = client; + i2c_set_clientdata(client, ssif_info); + rv = ssif_check_and_remove(client, ssif_info); /* If rv is 0 and addr source is not SI_ACPI, continue probing */ if (!rv && ssif_info->addr_source == SI_ACPI) { @@ -1720,9 +1713,6 @@ ipmi_addr_src_to_str(ssif_info->addr_source), client->addr, client->adapter->name, slave_addr); - ssif_info->client = client; - i2c_set_clientdata(client, ssif_info); - /* Now check for system interface capabilities */ msg[0] = IPMI_NETFN_APP_REQUEST << 2; msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD; @@ -1859,7 +1849,7 @@ } spin_lock_init(&ssif_info->lock); - ssif_info->ssif_state = SSIF_NORMAL; + ssif_info->ssif_state = SSIF_IDLE; timer_setup(&ssif_info->retry_timer, retry_timeout, 0); timer_setup(&ssif_info->watch_timer, watch_timeout, 0); @@ -1922,6 +1912,7 @@ dev_err(&ssif_info->client->dev, "Unable to start IPMI SSIF: %d\n", rv); + i2c_set_clientdata(client, NULL); kfree(ssif_info); } kfree(resp); --- linux-oracle-5.4.0.orig/drivers/char/ipmi/ipmi_watchdog.c +++ linux-oracle-5.4.0/drivers/char/ipmi/ipmi_watchdog.c @@ -337,13 +337,17 @@ static DECLARE_COMPLETION(msg_wait); static void msg_free_smi(struct ipmi_smi_msg *msg) { - if (atomic_dec_and_test(&msg_tofree)) - complete(&msg_wait); + if (atomic_dec_and_test(&msg_tofree)) { + if (!oops_in_progress) + complete(&msg_wait); + } } static void msg_free_recv(struct ipmi_recv_msg *msg) { - if (atomic_dec_and_test(&msg_tofree)) - complete(&msg_wait); + if (atomic_dec_and_test(&msg_tofree)) { + if (!oops_in_progress) + complete(&msg_wait); + } } static struct ipmi_smi_msg smi_msg = { .done = msg_free_smi @@ -366,16 +370,18 @@ data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); - if ((ipmi_version_major > 1) - || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { - /* This is an IPMI 1.5-only feature. */ - data[0] |= WDOG_DONT_STOP_ON_SET; - } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { - /* - * In ipmi 1.0, setting the timer stops the watchdog, we - * need to start it back up again. - */ - hbnow = 1; + if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { + if ((ipmi_version_major > 1) || + ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { + /* This is an IPMI 1.5-only feature. */ + data[0] |= WDOG_DONT_STOP_ON_SET; + } else { + /* + * In ipmi 1.0, setting the timer stops the watchdog, we + * need to start it back up again. + */ + hbnow = 1; + } } data[1] = 0; @@ -427,8 +433,10 @@ rv = __ipmi_set_timeout(&smi_msg, &recv_msg, &send_heartbeat_now); - if (rv) + if (rv) { + atomic_set(&msg_tofree, 0); return rv; + } wait_for_completion(&msg_wait); @@ -490,7 +498,7 @@ msg.cmd = IPMI_WDOG_RESET_TIMER; msg.data = NULL; msg.data_len = 0; - atomic_add(1, &panic_done_count); + atomic_add(2, &panic_done_count); rv = ipmi_request_supply_msgs(watchdog_user, (struct ipmi_addr *) &addr, 0, @@ -500,7 +508,7 @@ &panic_halt_heartbeat_recv_msg, 1); if (rv) - atomic_sub(1, &panic_done_count); + atomic_sub(2, &panic_done_count); } static struct ipmi_smi_msg panic_halt_smi_msg = { @@ -524,12 +532,12 @@ /* Wait for the messages to be free. */ while (atomic_read(&panic_done_count) != 0) ipmi_poll_interface(watchdog_user); - atomic_add(1, &panic_done_count); + atomic_add(2, &panic_done_count); rv = __ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (rv) { - atomic_sub(1, &panic_done_count); + atomic_sub(2, &panic_done_count); pr_warn("Unable to extend the watchdog timeout\n"); } else { if (send_heartbeat_now) @@ -573,6 +581,7 @@ &recv_msg, 1); if (rv) { + atomic_set(&msg_tofree, 0); pr_warn("heartbeat send failure: %d\n", rv); return rv; } --- linux-oracle-5.4.0.orig/drivers/char/lp.c +++ linux-oracle-5.4.0/drivers/char/lp.c @@ -713,6 +713,10 @@ if (copy_from_user(karg, arg, sizeof(karg))) return -EFAULT; + /* sparc64 suseconds_t is 32-bit only */ + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) + karg[1] >>= 32; + return lp_set_timeout(minor, karg[0], karg[1]); } --- linux-oracle-5.4.0.orig/drivers/char/mem.c +++ linux-oracle-5.4.0/drivers/char/mem.c @@ -31,11 +31,15 @@ #include #include #include +#include +#include +#include #ifdef CONFIG_IA64 # include #endif +#define DEVMEM_MINOR 1 #define DEVPORT_MINOR 4 static inline unsigned long size_inside_page(unsigned long start, @@ -805,12 +809,65 @@ return ret; } +static struct inode *devmem_inode; + +#ifdef CONFIG_IO_STRICT_DEVMEM +void revoke_devmem(struct resource *res) +{ + /* pairs with smp_store_release() in devmem_init_inode() */ + struct inode *inode = smp_load_acquire(&devmem_inode); + + /* + * Check that the initialization has completed. Losing the race + * is ok because it means drivers are claiming resources before + * the fs_initcall level of init and prevent /dev/mem from + * establishing mappings. + */ + if (!inode) + return; + + /* + * The expectation is that the driver has successfully marked + * the resource busy by this point, so devmem_is_allowed() + * should start returning false, however for performance this + * does not iterate the entire resource range. + */ + if (devmem_is_allowed(PHYS_PFN(res->start)) && + devmem_is_allowed(PHYS_PFN(res->end))) { + /* + * *cringe* iomem=relaxed says "go ahead, what's the + * worst that can happen?" + */ + return; + } + + unmap_mapping_range(inode->i_mapping, res->start, resource_size(res), 1); +} +#endif + static int open_port(struct inode *inode, struct file *filp) { + int rc; + if (!capable(CAP_SYS_RAWIO)) return -EPERM; - return security_locked_down(LOCKDOWN_DEV_MEM); + rc = security_locked_down(LOCKDOWN_DEV_MEM); + if (rc) + return rc; + + if (iminor(inode) != DEVMEM_MINOR) + return 0; + + /* + * Use a unified address space to have a single point to manage + * revocations when drivers want to take over a /dev/mem mapped + * range. + */ + inode->i_mapping = devmem_inode->i_mapping; + filp->f_mapping = inode->i_mapping; + + return 0; } #define zero_lseek null_lseek @@ -885,7 +942,7 @@ fmode_t fmode; } devlist[] = { #ifdef CONFIG_DEVMEM - [1] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, + [DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, #endif #ifdef CONFIG_DEVKMEM [2] = { "kmem", 0, &kmem_fops, FMODE_UNSIGNED_OFFSET }, @@ -896,8 +953,8 @@ #endif [5] = { "zero", 0666, &zero_fops, 0 }, [7] = { "full", 0666, &full_fops, 0 }, - [8] = { "random", 0666, &random_fops, 0 }, - [9] = { "urandom", 0666, &urandom_fops, 0 }, + [8] = { "random", 0666, &random_fops, FMODE_NOWAIT }, + [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT }, #ifdef CONFIG_PRINTK [11] = { "kmsg", 0644, &kmsg_fops, 0 }, #endif @@ -939,6 +996,48 @@ static struct class *mem_class; +static int devmem_fs_init_fs_context(struct fs_context *fc) +{ + return init_pseudo(fc, DEVMEM_MAGIC) ? 0 : -ENOMEM; +} + +static struct file_system_type devmem_fs_type = { + .name = "devmem", + .owner = THIS_MODULE, + .init_fs_context = devmem_fs_init_fs_context, + .kill_sb = kill_anon_super, +}; + +static int devmem_init_inode(void) +{ + static struct vfsmount *devmem_vfs_mount; + static int devmem_fs_cnt; + struct inode *inode; + int rc; + + rc = simple_pin_fs(&devmem_fs_type, &devmem_vfs_mount, &devmem_fs_cnt); + if (rc < 0) { + pr_err("Cannot mount /dev/mem pseudo filesystem: %d\n", rc); + return rc; + } + + inode = alloc_anon_inode(devmem_vfs_mount->mnt_sb); + if (IS_ERR(inode)) { + rc = PTR_ERR(inode); + pr_err("Cannot allocate inode for /dev/mem: %d\n", rc); + simple_release_fs(&devmem_vfs_mount, &devmem_fs_cnt); + return rc; + } + + /* + * Publish /dev/mem initialized. + * Pairs with smp_load_acquire() in revoke_devmem(). + */ + smp_store_release(&devmem_inode, inode); + + return 0; +} + static int __init chr_dev_init(void) { int minor; @@ -960,6 +1059,8 @@ */ if ((minor == DEVPORT_MINOR) && !arch_has_dev_port()) continue; + if ((minor == DEVMEM_MINOR) && devmem_init_inode() != 0) + continue; device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor), NULL, devlist[minor].name); --- linux-oracle-5.4.0.orig/drivers/char/mwave/3780i.h +++ linux-oracle-5.4.0/drivers/char/mwave/3780i.h @@ -68,7 +68,7 @@ unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ - unsigned char Reserved:5; /* 0: Reserved */ + unsigned short Reserved:13; /* 0: Reserved */ } DSP_ISA_SLAVE_CONTROL; --- linux-oracle-5.4.0.orig/drivers/char/pcmcia/cm4000_cs.c +++ linux-oracle-5.4.0/drivers/char/pcmcia/cm4000_cs.c @@ -544,6 +544,10 @@ io_read_num_rec_bytes(iobase, &num_bytes_read); if (num_bytes_read >= 4) { DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read); + if (num_bytes_read > 4) { + rc = -EIO; + goto exit_setprotocol; + } break; } usleep_range(10000, 11000); --- linux-oracle-5.4.0.orig/drivers/char/ppdev.c +++ linux-oracle-5.4.0/drivers/char/ppdev.c @@ -296,28 +296,35 @@ if (!port) { pr_warn("%s: no associated port!\n", name); rc = -ENXIO; - goto err; + goto err_free_name; + } + + index = ida_alloc(&ida_index, GFP_KERNEL); + if (index < 0) { + pr_warn("%s: failed to get index!\n", name); + rc = index; + goto err_put_port; } - index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); memset(&ppdev_cb, 0, sizeof(ppdev_cb)); ppdev_cb.irq_func = pp_irq; ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; ppdev_cb.private = pp; pdev = parport_register_dev_model(port, name, &ppdev_cb, index); - parport_put_port(port); if (!pdev) { pr_warn("%s: failed to register device!\n", name); rc = -ENXIO; - ida_simple_remove(&ida_index, index); - goto err; + ida_free(&ida_index, index); + goto err_put_port; } pp->pdev = pdev; pp->index = index; dev_dbg(&pdev->dev, "registered pardevice\n"); -err: +err_put_port: + parport_put_port(port); +err_free_name: kfree(name); return rc; } @@ -619,20 +626,27 @@ if (copy_from_user(time32, argp, sizeof(time32))) return -EFAULT; + if ((time32[0] < 0) || (time32[1] < 0)) + return -EINVAL; + return pp_set_timeout(pp->pdev, time32[0], time32[1]); case PPSETTIME64: if (copy_from_user(time64, argp, sizeof(time64))) return -EFAULT; + if ((time64[0] < 0) || (time64[1] < 0)) + return -EINVAL; + + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) + time64[1] >>= 32; + return pp_set_timeout(pp->pdev, time64[0], time64[1]); case PPGETTIME32: jiffies_to_timespec64(pp->pdev->timeout, &ts); time32[0] = ts.tv_sec; time32[1] = ts.tv_nsec / NSEC_PER_USEC; - if ((time32[0] < 0) || (time32[1] < 0)) - return -EINVAL; if (copy_to_user(argp, time32, sizeof(time32))) return -EFAULT; @@ -643,8 +657,9 @@ jiffies_to_timespec64(pp->pdev->timeout, &ts); time64[0] = ts.tv_sec; time64[1] = ts.tv_nsec / NSEC_PER_USEC; - if ((time64[0] < 0) || (time64[1] < 0)) - return -EINVAL; + + if (IS_ENABLED(CONFIG_SPARC64) && !in_compat_syscall()) + time64[1] <<= 32; if (copy_to_user(argp, time64, sizeof(time64))) return -EFAULT; @@ -754,7 +769,7 @@ if (pp->pdev) { parport_unregister_device(pp->pdev); - ida_simple_remove(&ida_index, pp->index); + ida_free(&ida_index, pp->index); pp->pdev = NULL; pr_debug(CHRDEV "%x: unregistered pardevice\n", minor); } --- linux-oracle-5.4.0.orig/drivers/char/random.c +++ linux-oracle-5.4.0/drivers/char/random.c @@ -1,312 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) /* - * random.c -- A strong random number generator - * - * Copyright (C) 2017 Jason A. Donenfeld . All - * Rights Reserved. - * + * Copyright (C) 2017-2022 Jason A. Donenfeld . All Rights Reserved. * Copyright Matt Mackall , 2003, 2004, 2005 + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All rights reserved. * - * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All - * rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU General Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF - * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - */ - -/* - * (now, with legal B.S. out of the way.....) - * - * This routine gathers environmental noise from device drivers, etc., - * and returns good random numbers, suitable for cryptographic use. - * Besides the obvious cryptographic uses, these numbers are also good - * for seeding TCP sequence numbers, and other places where it is - * desirable to have numbers which are not only random, but hard to - * predict by an attacker. - * - * Theory of operation - * =================== - * - * Computers are very predictable devices. Hence it is extremely hard - * to produce truly random numbers on a computer --- as opposed to - * pseudo-random numbers, which can easily generated by using a - * algorithm. Unfortunately, it is very easy for attackers to guess - * the sequence of pseudo-random number generators, and for some - * applications this is not acceptable. So instead, we must try to - * gather "environmental noise" from the computer's environment, which - * must be hard for outside attackers to observe, and use that to - * generate random numbers. In a Unix environment, this is best done - * from inside the kernel. - * - * Sources of randomness from the environment include inter-keyboard - * timings, inter-interrupt timings from some interrupts, and other - * events which are both (a) non-deterministic and (b) hard for an - * outside observer to measure. Randomness from these sources are - * added to an "entropy pool", which is mixed using a CRC-like function. - * This is not cryptographically strong, but it is adequate assuming - * the randomness is not chosen maliciously, and it is fast enough that - * the overhead of doing it on every interrupt is very reasonable. - * As random bytes are mixed into the entropy pool, the routines keep - * an *estimate* of how many bits of randomness have been stored into - * the random number generator's internal state. - * - * When random bytes are desired, they are obtained by taking the SHA - * hash of the contents of the "entropy pool". The SHA hash avoids - * exposing the internal state of the entropy pool. It is believed to - * be computationally infeasible to derive any useful information - * about the input of SHA from its output. Even if it is possible to - * analyze SHA in some clever way, as long as the amount of data - * returned from the generator is less than the inherent entropy in - * the pool, the output data is totally unpredictable. For this - * reason, the routine decreases its internal estimate of how many - * bits of "true randomness" are contained in the entropy pool as it - * outputs random numbers. - * - * If this estimate goes to zero, the routine can still generate - * random numbers; however, an attacker may (at least in theory) be - * able to infer the future output of the generator from prior - * outputs. This requires successful cryptanalysis of SHA, which is - * not believed to be feasible, but there is a remote possibility. - * Nonetheless, these numbers should be useful for the vast majority - * of purposes. - * - * Exported interfaces ---- output - * =============================== - * - * There are four exported interfaces; two for use within the kernel, - * and two or use from userspace. - * - * Exported interfaces ---- userspace output - * ----------------------------------------- - * - * The userspace interfaces are two character devices /dev/random and - * /dev/urandom. /dev/random is suitable for use when very high - * quality randomness is desired (for example, for key generation or - * one-time pads), as it will only return a maximum of the number of - * bits of randomness (as estimated by the random number generator) - * contained in the entropy pool. - * - * The /dev/urandom device does not have this limit, and will return - * as many bytes as are requested. As more and more random bytes are - * requested without giving time for the entropy pool to recharge, - * this will result in random numbers that are merely cryptographically - * strong. For many applications, however, this is acceptable. - * - * Exported interfaces ---- kernel output - * -------------------------------------- - * - * The primary kernel interface is - * - * void get_random_bytes(void *buf, int nbytes); - * - * This interface will return the requested number of random bytes, - * and place it in the requested buffer. This is equivalent to a - * read from /dev/urandom. - * - * For less critical applications, there are the functions: - * - * u32 get_random_u32() - * u64 get_random_u64() - * unsigned int get_random_int() - * unsigned long get_random_long() - * - * These are produced by a cryptographic RNG seeded from get_random_bytes, - * and so do not deplete the entropy pool as much. These are recommended - * for most in-kernel operations *if the result is going to be stored in - * the kernel*. - * - * Specifically, the get_random_int() family do not attempt to do - * "anti-backtracking". If you capture the state of the kernel (e.g. - * by snapshotting the VM), you can figure out previous get_random_int() - * return values. But if the value is stored in the kernel anyway, - * this is not a problem. - * - * It *is* safe to expose get_random_int() output to attackers (e.g. as - * network cookies); given outputs 1..n, it's not feasible to predict - * outputs 0 or n+1. The only concern is an attacker who breaks into - * the kernel later; the get_random_int() engine is not reseeded as - * often as the get_random_bytes() one. - * - * get_random_bytes() is needed for keys that need to stay secret after - * they are erased from the kernel. For example, any key that will - * be wrapped and stored encrypted. And session encryption keys: we'd - * like to know that after the session is closed and the keys erased, - * the plaintext is unrecoverable to someone who recorded the ciphertext. - * - * But for network ports/cookies, stack canaries, PRNG seeds, address - * space layout randomization, session *authentication* keys, or other - * applications where the sensitive data is stored in the kernel in - * plaintext for as long as it's sensitive, the get_random_int() family - * is just fine. - * - * Consider ASLR. We want to keep the address space secret from an - * outside attacker while the process is running, but once the address - * space is torn down, it's of no use to an attacker any more. And it's - * stored in kernel data structures as long as it's alive, so worrying - * about an attacker's ability to extrapolate it from the get_random_int() - * CRNG is silly. - * - * Even some cryptographic keys are safe to generate with get_random_int(). - * In particular, keys for SipHash are generally fine. Here, knowledge - * of the key authorizes you to do something to a kernel object (inject - * packets to a network connection, or flood a hash table), and the - * key is stored with the object being protected. Once it goes away, - * we no longer care if anyone knows the key. - * - * prandom_u32() - * ------------- - * - * For even weaker applications, see the pseudorandom generator - * prandom_u32(), prandom_max(), and prandom_bytes(). If the random - * numbers aren't security-critical at all, these are *far* cheaper. - * Useful for self-tests, random error simulation, randomized backoffs, - * and any other application where you trust that nobody is trying to - * maliciously mess with you by guessing the "random" numbers. - * - * Exported interfaces ---- input - * ============================== - * - * The current exported interfaces for gathering environmental noise - * from the devices are: - * - * void add_device_randomness(const void *buf, unsigned int size); - * void add_input_randomness(unsigned int type, unsigned int code, - * unsigned int value); - * void add_interrupt_randomness(int irq, int irq_flags); - * void add_disk_randomness(struct gendisk *disk); - * - * add_device_randomness() is for adding data to the random pool that - * is likely to differ between two devices (or possibly even per boot). - * This would be things like MAC addresses or serial numbers, or the - * read-out of the RTC. This does *not* add any actual entropy to the - * pool, but it initializes the pool to different values for devices - * that might otherwise be identical and have very little entropy - * available to them (particularly common in the embedded world). - * - * add_input_randomness() uses the input layer interrupt timing, as well as - * the event type information from the hardware. - * - * add_interrupt_randomness() uses the interrupt timing as random - * inputs to the entropy pool. Using the cycle counters and the irq source - * as inputs, it feeds the randomness roughly once a second. - * - * add_disk_randomness() uses what amounts to the seek time of block - * layer request events, on a per-disk_devt basis, as input to the - * entropy pool. Note that high-speed solid state drives with very low - * seek times do not make for good sources of entropy, as their seek - * times are usually fairly consistent. + * This driver produces cryptographically secure pseudorandom data. It is divided + * into roughly six sections, each with a section header: * - * All of these routines try to estimate how many bits of randomness a - * particular randomness source. They do this by keeping track of the - * first and second order deltas of the event timings. - * - * Ensuring unpredictability at system startup - * ============================================ - * - * When any operating system starts up, it will go through a sequence - * of actions that are fairly predictable by an adversary, especially - * if the start-up does not involve interaction with a human operator. - * This reduces the actual number of bits of unpredictability in the - * entropy pool below the value in entropy_count. In order to - * counteract this effect, it helps to carry information in the - * entropy pool across shut-downs and start-ups. To do this, put the - * following lines an appropriate script which is run during the boot - * sequence: - * - * echo "Initializing random number generator..." - * random_seed=/var/run/random-seed - * # Carry a random seed from start-up to start-up - * # Load and then save the whole entropy pool - * if [ -f $random_seed ]; then - * cat $random_seed >/dev/urandom - * else - * touch $random_seed - * fi - * chmod 600 $random_seed - * dd if=/dev/urandom of=$random_seed count=1 bs=512 - * - * and the following lines in an appropriate script which is run as - * the system is shutdown: - * - * # Carry a random seed from shut-down to start-up - * # Save the whole entropy pool - * echo "Saving random seed..." - * random_seed=/var/run/random-seed - * touch $random_seed - * chmod 600 $random_seed - * dd if=/dev/urandom of=$random_seed count=1 bs=512 - * - * For example, on most modern systems using the System V init - * scripts, such code fragments would be found in - * /etc/rc.d/init.d/random. On older Linux systems, the correct script - * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0. - * - * Effectively, these commands cause the contents of the entropy pool - * to be saved at shut-down time and reloaded into the entropy pool at - * start-up. (The 'dd' in the addition to the bootup script is to - * make sure that /etc/random-seed is different for every start-up, - * even if the system crashes without executing rc.0.) Even with - * complete knowledge of the start-up activities, predicting the state - * of the entropy pool requires knowledge of the previous history of - * the system. - * - * Configuring the /dev/random driver under Linux - * ============================================== - * - * The /dev/random driver under Linux uses minor numbers 8 and 9 of - * the /dev/mem major number (#1). So if your system does not have - * /dev/random and /dev/urandom created already, they can be created - * by using the commands: - * - * mknod /dev/random c 1 8 - * mknod /dev/urandom c 1 9 - * - * Acknowledgements: - * ================= - * - * Ideas for constructing this random number generator were derived - * from Pretty Good Privacy's random number generator, and from private - * discussions with Phil Karn. Colin Plumb provided a faster random - * number generator, which speed up the mixing function of the entropy - * pool, taken from PGPfone. Dale Worley has also contributed many - * useful ideas and suggestions to improve this driver. - * - * Any flaws in the design are solely my responsibility, and should - * not be attributed to the Phil, Colin, or any of authors of PGP. - * - * Further background information on this topic may be obtained from - * RFC 1750, "Randomness Recommendations for Security", by Donald - * Eastlake, Steve Crocker, and Jeff Schiller. + * - Initialization and readiness waiting. + * - Fast key erasure RNG, the "crng". + * - Entropy accumulation and extraction routines. + * - Entropy collection routines. + * - Userspace reader/writer interfaces. + * - Sysctl interface. + * + * The high level overview is that there is one input pool, into which + * various pieces of data are hashed. Prior to initialization, some of that + * data is then "credited" as having a certain number of bits of entropy. + * When enough bits of entropy are available, the hash is finalized and + * handed as a key to a stream cipher that expands it indefinitely for + * various consumers. This key is periodically refreshed as the various + * entropy collectors, described below, add data to the input pool. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -325,8 +43,6 @@ #include #include #include -#include -#include #include #include #include @@ -334,1403 +50,1085 @@ #include #include #include +#include +#include +#include #include - +#include #include -#include #include #include #include -#define CREATE_TRACE_POINTS -#include - -/* #define ADD_INTERRUPT_BENCH */ - -/* - * Configuration information - */ -#define INPUT_POOL_SHIFT 12 -#define INPUT_POOL_WORDS (1 << (INPUT_POOL_SHIFT-5)) -#define OUTPUT_POOL_SHIFT 10 -#define OUTPUT_POOL_WORDS (1 << (OUTPUT_POOL_SHIFT-5)) -#define SEC_XFER_SIZE 512 -#define EXTRACT_SIZE 10 - - -#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long)) - -/* - * To allow fractional bits to be tracked, the entropy_count field is - * denominated in units of 1/8th bits. - * - * 2*(ENTROPY_SHIFT + poolbitshift) must <= 31, or the multiply in - * credit_entropy_bits() needs to be 64 bits wide. - */ -#define ENTROPY_SHIFT 3 -#define ENTROPY_BITS(r) ((r)->entropy_count >> ENTROPY_SHIFT) - -/* - * The minimum number of bits of entropy before we wake up a read on - * /dev/random. Should be enough to do a significant reseed. - */ -static int random_read_wakeup_bits = 64; - -/* - * If the entropy count falls under this number of bits, then we - * should wake up processes which are selecting or polling on write - * access to /dev/random. - */ -static int random_write_wakeup_bits = 28 * OUTPUT_POOL_WORDS; - -/* - * Originally, we used a primitive polynomial of degree .poolwords - * over GF(2). The taps for various sizes are defined below. They - * were chosen to be evenly spaced except for the last tap, which is 1 - * to get the twisting happening as fast as possible. - * - * For the purposes of better mixing, we use the CRC-32 polynomial as - * well to make a (modified) twisted Generalized Feedback Shift - * Register. (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR - * generators. ACM Transactions on Modeling and Computer Simulation - * 2(3):179-194. Also see M. Matsumoto & Y. Kurita, 1994. Twisted - * GFSR generators II. ACM Transactions on Modeling and Computer - * Simulation 4:254-266) - * - * Thanks to Colin Plumb for suggesting this. - * - * The mixing operation is much less sensitive than the output hash, - * where we use SHA-1. All that we want of mixing operation is that - * it be a good non-cryptographic hash; i.e. it not produce collisions - * when fed "random" data of the sort we expect to see. As long as - * the pool state differs for different inputs, we have preserved the - * input entropy and done a good job. The fact that an intelligent - * attacker can construct inputs that will produce controlled - * alterations to the pool's state is not important because we don't - * consider such inputs to contribute any randomness. The only - * property we need with respect to them is that the attacker can't - * increase his/her knowledge of the pool's state. Since all - * additions are reversible (knowing the final state and the input, - * you can reconstruct the initial state), if an attacker has any - * uncertainty about the initial state, he/she can only shuffle that - * uncertainty about, but never cause any collisions (which would - * decrease the uncertainty). - * - * Our mixing functions were analyzed by Lacharme, Roeck, Strubel, and - * Videau in their paper, "The Linux Pseudorandom Number Generator - * Revisited" (see: http://eprint.iacr.org/2012/251.pdf). In their - * paper, they point out that we are not using a true Twisted GFSR, - * since Matsumoto & Kurita used a trinomial feedback polynomial (that - * is, with only three taps, instead of the six that we are using). - * As a result, the resulting polynomial is neither primitive nor - * irreducible, and hence does not have a maximal period over - * GF(2**32). They suggest a slight change to the generator - * polynomial which improves the resulting TGFSR polynomial to be - * irreducible, which we have made here. - */ -static const struct poolinfo { - int poolbitshift, poolwords, poolbytes, poolfracbits; -#define S(x) ilog2(x)+5, (x), (x)*4, (x) << (ENTROPY_SHIFT+5) - int tap1, tap2, tap3, tap4, tap5; -} poolinfo_table[] = { - /* was: x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 */ - /* x^128 + x^104 + x^76 + x^51 +x^25 + x + 1 */ - { S(128), 104, 76, 51, 25, 1 }, - /* was: x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 */ - /* x^32 + x^26 + x^19 + x^14 + x^7 + x + 1 */ - { S(32), 26, 19, 14, 7, 1 }, -#if 0 - /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ - { S(2048), 1638, 1231, 819, 411, 1 }, - - /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */ - { S(1024), 817, 615, 412, 204, 1 }, - - /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */ - { S(1024), 819, 616, 410, 207, 2 }, - - /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */ - { S(512), 411, 308, 208, 104, 1 }, - - /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */ - { S(512), 409, 307, 206, 102, 2 }, - /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */ - { S(512), 409, 309, 205, 103, 2 }, - - /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */ - { S(256), 205, 155, 101, 52, 1 }, - - /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */ - { S(128), 103, 78, 51, 27, 2 }, - - /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */ - { S(64), 52, 39, 26, 14, 1 }, -#endif -}; +/********************************************************************* + * + * Initialization and readiness waiting. + * + * Much of the RNG infrastructure is devoted to various dependencies + * being able to wait until the RNG has collected enough entropy and + * is ready for safe consumption. + * + *********************************************************************/ /* - * Static global variables + * crng_init is protected by base_crng->lock, and only increases + * its value (from empty->early->ready). */ -static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); -static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); +static enum { + CRNG_EMPTY = 0, /* Little to no entropy collected */ + CRNG_EARLY = 1, /* At least POOL_EARLY_BITS collected */ + CRNG_READY = 2 /* Fully initialized with POOL_READY_BITS collected */ +} crng_init __read_mostly = CRNG_EMPTY; +#define crng_ready() (likely(crng_init >= CRNG_READY)) +/* Various types of waiters for crng_init->CRNG_READY transition. */ +static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); static struct fasync_struct *fasync; +static DEFINE_SPINLOCK(random_ready_chain_lock); +static RAW_NOTIFIER_HEAD(random_ready_chain); -static DEFINE_SPINLOCK(random_ready_list_lock); -static LIST_HEAD(random_ready_list); - -struct crng_state { - __u32 state[16]; - unsigned long init_time; - spinlock_t lock; -}; - -static struct crng_state primary_crng = { - .lock = __SPIN_LOCK_UNLOCKED(primary_crng.lock), -}; - -/* - * crng_init = 0 --> Uninitialized - * 1 --> Initialized - * 2 --> Initialized from input_pool - * - * crng_init is protected by primary_crng->lock, and only increases - * its value (from 0->1->2). - */ -static int crng_init = 0; -#define crng_ready() (likely(crng_init > 1)) -static int crng_init_cnt = 0; -static unsigned long crng_global_init_time = 0; -#define CRNG_INIT_CNT_THRESH (2*CHACHA_KEY_SIZE) -static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA_BLOCK_SIZE]); -static void _crng_backtrack_protect(struct crng_state *crng, - __u8 tmp[CHACHA_BLOCK_SIZE], int used); -static void process_random_ready_list(void); -static void _get_random_bytes(void *buf, int nbytes); - -static struct ratelimit_state unseeded_warning = - RATELIMIT_STATE_INIT("warn_unseeded_randomness", HZ, 3); +/* Control how we warn userspace. */ static struct ratelimit_state urandom_warning = - RATELIMIT_STATE_INIT("warn_urandom_randomness", HZ, 3); - -static int ratelimit_disable __read_mostly; - + RATELIMIT_STATE_INIT_FLAGS("urandom_warning", HZ, 3, RATELIMIT_MSG_ON_RELEASE); +static int ratelimit_disable __read_mostly = + IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM); module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression"); -/********************************************************************** - * - * OS independent entropy store. Here are the functions which handle - * storing entropy in an entropy pool. +/* + * Returns whether or not the input pool has been seeded and thus guaranteed + * to supply cryptographically secure random numbers. This applies to: the + * /dev/urandom device, the get_random_bytes function, and the get_random_{u32, + * ,u64,int,long} family of functions. * - **********************************************************************/ - -struct entropy_store; -struct entropy_store { - /* read-only data: */ - const struct poolinfo *poolinfo; - __u32 *pool; - const char *name; - struct entropy_store *pull; - struct work_struct push_work; - - /* read-write data: */ - unsigned long last_pulled; - spinlock_t lock; - unsigned short add_ptr; - unsigned short input_rotate; - int entropy_count; - unsigned int initialized:1; - unsigned int last_data_init:1; - __u8 last_data[EXTRACT_SIZE]; -}; - -static ssize_t extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int min, int rsvd); -static ssize_t _extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int fips); - -static void crng_reseed(struct crng_state *crng, struct entropy_store *r); -static void push_to_pool(struct work_struct *work); -static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; -static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; - -static struct entropy_store input_pool = { - .poolinfo = &poolinfo_table[0], - .name = "input", - .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock), - .pool = input_pool_data -}; - -static struct entropy_store blocking_pool = { - .poolinfo = &poolinfo_table[1], - .name = "blocking", - .pull = &input_pool, - .lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock), - .pool = blocking_pool_data, - .push_work = __WORK_INITIALIZER(blocking_pool.push_work, - push_to_pool), -}; + * Returns: true if the input pool has been seeded. + * false if the input pool has not been seeded. + */ +bool rng_is_initialized(void) +{ + return crng_ready(); +} +EXPORT_SYMBOL(rng_is_initialized); -static __u32 const twist_table[8] = { - 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158, - 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 }; +/* Used by wait_for_random_bytes(), and considered an entropy collector, below. */ +static void try_to_generate_entropy(void); /* - * This function adds bytes into the entropy "pool". It does not - * update the entropy estimate. The caller should call - * credit_entropy_bits if this is appropriate. + * Wait for the input pool to be seeded and thus guaranteed to supply + * cryptographically secure random numbers. This applies to: the /dev/urandom + * device, the get_random_bytes function, and the get_random_{u32,u64,int,long} + * family of functions. Using any of these functions without first calling + * this function forfeits the guarantee of security. * - * The pool is stirred with a primitive polynomial of the appropriate - * degree, and then twisted. We twist by three bits at a time because - * it's cheap to do so and helps slightly in the expected case where - * the entropy is concentrated in the low-order bits. + * Returns: 0 if the input pool has been seeded. + * -ERESTARTSYS if the function was interrupted by a signal. */ -static void _mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes) +int wait_for_random_bytes(void) { - unsigned long i, tap1, tap2, tap3, tap4, tap5; - int input_rotate; - int wordmask = r->poolinfo->poolwords - 1; - const char *bytes = in; - __u32 w; - - tap1 = r->poolinfo->tap1; - tap2 = r->poolinfo->tap2; - tap3 = r->poolinfo->tap3; - tap4 = r->poolinfo->tap4; - tap5 = r->poolinfo->tap5; - - input_rotate = r->input_rotate; - i = r->add_ptr; - - /* mix one byte at a time to simplify size handling and churn faster */ - while (nbytes--) { - w = rol32(*bytes++, input_rotate); - i = (i - 1) & wordmask; + while (!crng_ready()) { + int ret; - /* XOR in the various taps */ - w ^= r->pool[i]; - w ^= r->pool[(i + tap1) & wordmask]; - w ^= r->pool[(i + tap2) & wordmask]; - w ^= r->pool[(i + tap3) & wordmask]; - w ^= r->pool[(i + tap4) & wordmask]; - w ^= r->pool[(i + tap5) & wordmask]; + try_to_generate_entropy(); + ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ); + if (ret) + return ret > 0 ? 0 : ret; + } + return 0; +} +EXPORT_SYMBOL(wait_for_random_bytes); - /* Mix the result back in with a twist */ - r->pool[i] = (w >> 3) ^ twist_table[w & 7]; +/* + * Add a callback function that will be invoked when the input + * pool is initialised. + * + * returns: 0 if callback is successfully added + * -EALREADY if pool is already initialised (callback not called) + */ +int __cold register_random_ready_notifier(struct notifier_block *nb) +{ + unsigned long flags; + int ret = -EALREADY; - /* - * Normally, we add 7 bits of rotation to the pool. - * At the beginning of the pool, add an extra 7 bits - * rotation, so that successive passes spread the - * input bits across the pool evenly. - */ - input_rotate = (input_rotate + (i ? 7 : 14)) & 31; - } + if (crng_ready()) + return ret; - r->input_rotate = input_rotate; - r->add_ptr = i; + spin_lock_irqsave(&random_ready_chain_lock, flags); + if (!crng_ready()) + ret = raw_notifier_chain_register(&random_ready_chain, nb); + spin_unlock_irqrestore(&random_ready_chain_lock, flags); + return ret; } -static void __mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes) +/* + * Delete a previously registered readiness callback function. + */ +int __cold unregister_random_ready_notifier(struct notifier_block *nb) { - trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_); - _mix_pool_bytes(r, in, nbytes); + unsigned long flags; + int ret; + + spin_lock_irqsave(&random_ready_chain_lock, flags); + ret = raw_notifier_chain_unregister(&random_ready_chain, nb); + spin_unlock_irqrestore(&random_ready_chain_lock, flags); + return ret; } -static void mix_pool_bytes(struct entropy_store *r, const void *in, - int nbytes) +static void __cold process_random_ready_list(void) { unsigned long flags; - trace_mix_pool_bytes(r->name, nbytes, _RET_IP_); - spin_lock_irqsave(&r->lock, flags); - _mix_pool_bytes(r, in, nbytes); - spin_unlock_irqrestore(&r->lock, flags); + spin_lock_irqsave(&random_ready_chain_lock, flags); + raw_notifier_call_chain(&random_ready_chain, 0, NULL); + spin_unlock_irqrestore(&random_ready_chain_lock, flags); } -struct fast_pool { - __u32 pool[4]; - unsigned long last; - unsigned short reg_idx; - unsigned char count; -}; +#define warn_unseeded_randomness() \ + if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \ + printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \ + __func__, (void *)_RET_IP_, crng_init) -/* - * This is a fast mixing routine used by the interrupt randomness - * collector. It's hardcoded for an 128 bit pool and assumes that any - * locks that might be needed are taken by the caller. - */ -static void fast_mix(struct fast_pool *f) -{ - __u32 a = f->pool[0], b = f->pool[1]; - __u32 c = f->pool[2], d = f->pool[3]; - a += b; c += d; - b = rol32(b, 6); d = rol32(d, 27); - d ^= a; b ^= c; +/********************************************************************* + * + * Fast key erasure RNG, the "crng". + * + * These functions expand entropy from the entropy extractor into + * long streams for external consumption using the "fast key erasure" + * RNG described at . + * + * There are a few exported interfaces for use by other drivers: + * + * void get_random_bytes(void *buf, size_t len) + * u32 get_random_u32() + * u64 get_random_u64() + * unsigned int get_random_int() + * unsigned long get_random_long() + * + * These interfaces will return the requested number of random bytes + * into the given buffer or as a return value. This is equivalent to + * a read from /dev/urandom. The u32, u64, int, and long family of + * functions may be higher performance for one-off random integers, + * because they do a bit of buffering and do not invoke reseeding + * until the buffer is emptied. + * + *********************************************************************/ + +enum { + CRNG_RESEED_START_INTERVAL = HZ, + CRNG_RESEED_INTERVAL = 60 * HZ +}; - a += b; c += d; - b = rol32(b, 16); d = rol32(d, 14); - d ^= a; b ^= c; +static struct { + u8 key[CHACHA_KEY_SIZE] __aligned(__alignof__(long)); + unsigned long birth; + unsigned long generation; + spinlock_t lock; +} base_crng = { + .lock = __SPIN_LOCK_UNLOCKED(base_crng.lock) +}; - a += b; c += d; - b = rol32(b, 6); d = rol32(d, 27); - d ^= a; b ^= c; +struct crng { + u8 key[CHACHA_KEY_SIZE]; + unsigned long generation; +}; - a += b; c += d; - b = rol32(b, 16); d = rol32(d, 14); - d ^= a; b ^= c; +static DEFINE_PER_CPU(struct crng, crngs) = { + .generation = ULONG_MAX +}; - f->pool[0] = a; f->pool[1] = b; - f->pool[2] = c; f->pool[3] = d; - f->count++; -} +/* Used by crng_reseed() and crng_make_state() to extract a new seed from the input pool. */ +static void extract_entropy(void *buf, size_t len); -static void process_random_ready_list(void) +/* This extracts a new crng key from the input pool. */ +static void crng_reseed(void) { unsigned long flags; - struct random_ready_callback *rdy, *tmp; + unsigned long next_gen; + u8 key[CHACHA_KEY_SIZE]; - spin_lock_irqsave(&random_ready_list_lock, flags); - list_for_each_entry_safe(rdy, tmp, &random_ready_list, list) { - struct module *owner = rdy->owner; + extract_entropy(key, sizeof(key)); - list_del_init(&rdy->list); - rdy->func(rdy); - module_put(owner); - } - spin_unlock_irqrestore(&random_ready_list_lock, flags); + /* + * We copy the new key into the base_crng, overwriting the old one, + * and update the generation counter. We avoid hitting ULONG_MAX, + * because the per-cpu crngs are initialized to ULONG_MAX, so this + * forces new CPUs that come online to always initialize. + */ + spin_lock_irqsave(&base_crng.lock, flags); + memcpy(base_crng.key, key, sizeof(base_crng.key)); + next_gen = base_crng.generation + 1; + if (next_gen == ULONG_MAX) + ++next_gen; + WRITE_ONCE(base_crng.generation, next_gen); + WRITE_ONCE(base_crng.birth, jiffies); + if (!crng_ready()) + crng_init = CRNG_READY; + spin_unlock_irqrestore(&base_crng.lock, flags); + memzero_explicit(key, sizeof(key)); } /* - * Credit (or debit) the entropy store with n bits of entropy. - * Use credit_entropy_bits_safe() if the value comes from userspace - * or otherwise should be checked for extreme values. + * This generates a ChaCha block using the provided key, and then + * immediately overwites that key with half the block. It returns + * the resultant ChaCha state to the user, along with the second + * half of the block containing 32 bytes of random data that may + * be used; random_data_len may not be greater than 32. + * + * The returned ChaCha state contains within it a copy of the old + * key value, at index 4, so the state should always be zeroed out + * immediately after using in order to maintain forward secrecy. + * If the state cannot be erased in a timely manner, then it is + * safer to set the random_data parameter to &chacha_state[4] so + * that this function overwrites it before returning. */ -static void credit_entropy_bits(struct entropy_store *r, int nbits) +static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE], + u32 chacha_state[CHACHA_BLOCK_SIZE / sizeof(u32)], + u8 *random_data, size_t random_data_len) { - int entropy_count, orig, has_initialized = 0; - const int pool_size = r->poolinfo->poolfracbits; - int nfrac = nbits << ENTROPY_SHIFT; + u8 first_block[CHACHA_BLOCK_SIZE]; - if (!nbits) - return; + BUG_ON(random_data_len > 32); -retry: - entropy_count = orig = READ_ONCE(r->entropy_count); - if (nfrac < 0) { - /* Debit */ - entropy_count += nfrac; - } else { - /* - * Credit: we have to account for the possibility of - * overwriting already present entropy. Even in the - * ideal case of pure Shannon entropy, new contributions - * approach the full value asymptotically: - * - * entropy <- entropy + (pool_size - entropy) * - * (1 - exp(-add_entropy/pool_size)) - * - * For add_entropy <= pool_size/2 then - * (1 - exp(-add_entropy/pool_size)) >= - * (add_entropy/pool_size)*0.7869... - * so we can approximate the exponential with - * 3/4*add_entropy/pool_size and still be on the - * safe side by adding at most pool_size/2 at a time. - * - * The use of pool_size-2 in the while statement is to - * prevent rounding artifacts from making the loop - * arbitrarily long; this limits the loop to log2(pool_size)*2 - * turns no matter how large nbits is. - */ - int pnfrac = nfrac; - const int s = r->poolinfo->poolbitshift + ENTROPY_SHIFT + 2; - /* The +2 corresponds to the /4 in the denominator */ - - do { - unsigned int anfrac = min(pnfrac, pool_size/2); - unsigned int add = - ((pool_size - entropy_count)*anfrac*3) >> s; - - entropy_count += add; - pnfrac -= anfrac; - } while (unlikely(entropy_count < pool_size-2 && pnfrac)); - } - - if (unlikely(entropy_count < 0)) { - pr_warn("random: negative entropy/overflow: pool %s count %d\n", - r->name, entropy_count); - WARN_ON(1); - entropy_count = 0; - } else if (entropy_count > pool_size) - entropy_count = pool_size; - if ((r == &blocking_pool) && !r->initialized && - (entropy_count >> ENTROPY_SHIFT) > 128) - has_initialized = 1; - if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) - goto retry; - - if (has_initialized) { - r->initialized = 1; - wake_up_interruptible(&random_read_wait); - kill_fasync(&fasync, SIGIO, POLL_IN); - } + chacha_init_consts(chacha_state); + memcpy(&chacha_state[4], key, CHACHA_KEY_SIZE); + memset(&chacha_state[12], 0, sizeof(u32) * 4); + chacha20_block(chacha_state, first_block); - trace_credit_entropy_bits(r->name, nbits, - entropy_count >> ENTROPY_SHIFT, _RET_IP_); - - if (r == &input_pool) { - int entropy_bits = entropy_count >> ENTROPY_SHIFT; - struct entropy_store *other = &blocking_pool; - - if (crng_init < 2) { - if (entropy_bits < 128) - return; - crng_reseed(&primary_crng, r); - entropy_bits = r->entropy_count >> ENTROPY_SHIFT; - } - - /* initialize the blocking pool if necessary */ - if (entropy_bits >= random_read_wakeup_bits && - !other->initialized) { - schedule_work(&other->push_work); - return; - } - - /* should we wake readers? */ - if (entropy_bits >= random_read_wakeup_bits && - wq_has_sleeper(&random_read_wait)) { - wake_up_interruptible(&random_read_wait); - kill_fasync(&fasync, SIGIO, POLL_IN); - } - /* If the input pool is getting full, and the blocking - * pool has room, send some entropy to the blocking - * pool. - */ - if (!work_pending(&other->push_work) && - (ENTROPY_BITS(r) > 6 * r->poolinfo->poolbytes) && - (ENTROPY_BITS(other) <= 6 * other->poolinfo->poolbytes)) - schedule_work(&other->push_work); - } + memcpy(key, first_block, CHACHA_KEY_SIZE); + memcpy(random_data, first_block + CHACHA_KEY_SIZE, random_data_len); + memzero_explicit(first_block, sizeof(first_block)); } -static int credit_entropy_bits_safe(struct entropy_store *r, int nbits) +/* + * Return whether the crng seed is considered to be sufficiently old + * that a reseeding is needed. This happens if the last reseeding + * was CRNG_RESEED_INTERVAL ago, or during early boot, at an interval + * proportional to the uptime. + */ +static bool crng_has_old_seed(void) { - const int nbits_max = r->poolinfo->poolwords * 32; + static bool early_boot = true; + unsigned long interval = CRNG_RESEED_INTERVAL; - if (nbits < 0) - return -EINVAL; - - /* Cap the value to avoid overflows */ - nbits = min(nbits, nbits_max); - - credit_entropy_bits(r, nbits); - return 0; + if (unlikely(READ_ONCE(early_boot))) { + time64_t uptime = ktime_get_seconds(); + if (uptime >= CRNG_RESEED_INTERVAL / HZ * 2) + WRITE_ONCE(early_boot, false); + else + interval = max_t(unsigned int, CRNG_RESEED_START_INTERVAL, + (unsigned int)uptime / 2 * HZ); + } + return time_is_before_jiffies(READ_ONCE(base_crng.birth) + interval); } -/********************************************************************* - * - * CRNG using CHACHA20 - * - *********************************************************************/ - -#define CRNG_RESEED_INTERVAL (300*HZ) - -static DECLARE_WAIT_QUEUE_HEAD(crng_init_wait); - -#ifdef CONFIG_NUMA /* - * Hack to deal with crazy userspace progams when they are all trying - * to access /dev/urandom in parallel. The programs are almost - * certainly doing something terribly wrong, but we'll work around - * their brain damage. + * This function returns a ChaCha state that you may use for generating + * random data. It also returns up to 32 bytes on its own of random data + * that may be used; random_data_len may not be greater than 32. */ -static struct crng_state **crng_node_pool __read_mostly; -#endif +static void crng_make_state(u32 chacha_state[CHACHA_BLOCK_SIZE / sizeof(u32)], + u8 *random_data, size_t random_data_len) +{ + unsigned long flags; + struct crng *crng; -static void invalidate_batched_entropy(void); -static void numa_crng_init(void); + BUG_ON(random_data_len > 32); -static bool trust_cpu __ro_after_init = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); -static int __init parse_trust_cpu(char *arg) -{ - return kstrtobool(arg, &trust_cpu); -} -early_param("random.trust_cpu", parse_trust_cpu); + /* + * For the fast path, we check whether we're ready, unlocked first, and + * then re-check once locked later. In the case where we're really not + * ready, we do fast key erasure with the base_crng directly, extracting + * when crng_init is CRNG_EMPTY. + */ + if (!crng_ready()) { + bool ready; -static void crng_initialize(struct crng_state *crng) -{ - int i; - int arch_init = 1; - unsigned long rv; - - memcpy(&crng->state[0], "expand 32-byte k", 16); - if (crng == &primary_crng) - _extract_entropy(&input_pool, &crng->state[4], - sizeof(__u32) * 12, 0); - else - _get_random_bytes(&crng->state[4], sizeof(__u32) * 12); - for (i = 4; i < 16; i++) { - if (!arch_get_random_seed_long(&rv) && - !arch_get_random_long(&rv)) { - rv = random_get_entropy(); - arch_init = 0; + spin_lock_irqsave(&base_crng.lock, flags); + ready = crng_ready(); + if (!ready) { + if (crng_init == CRNG_EMPTY) + extract_entropy(base_crng.key, sizeof(base_crng.key)); + crng_fast_key_erasure(base_crng.key, chacha_state, + random_data, random_data_len); } - crng->state[i] ^= rv; + spin_unlock_irqrestore(&base_crng.lock, flags); + if (!ready) + return; } - if (trust_cpu && arch_init && crng == &primary_crng) { - invalidate_batched_entropy(); - numa_crng_init(); - crng_init = 2; - pr_notice("random: crng done (trusting CPU's manufacturer)\n"); + + /* + * If the base_crng is old enough, we reseed, which in turn bumps the + * generation counter that we check below. + */ + if (unlikely(crng_has_old_seed())) + crng_reseed(); + + local_irq_save(flags); + crng = raw_cpu_ptr(&crngs); + + /* + * If our per-cpu crng is older than the base_crng, then it means + * somebody reseeded the base_crng. In that case, we do fast key + * erasure on the base_crng, and use its output as the new key + * for our per-cpu crng. This brings us up to date with base_crng. + */ + if (unlikely(crng->generation != READ_ONCE(base_crng.generation))) { + spin_lock(&base_crng.lock); + crng_fast_key_erasure(base_crng.key, chacha_state, + crng->key, sizeof(crng->key)); + crng->generation = base_crng.generation; + spin_unlock(&base_crng.lock); } - crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1; + + /* + * Finally, when we've made it this far, our per-cpu crng has an up + * to date key, and we can do fast key erasure with it to produce + * some random data and a ChaCha state for the caller. All other + * branches of this function are "unlikely", so most of the time we + * should wind up here immediately. + */ + crng_fast_key_erasure(crng->key, chacha_state, random_data, random_data_len); + local_irq_restore(flags); } -#ifdef CONFIG_NUMA -static void do_numa_crng_init(struct work_struct *work) +static void _get_random_bytes(void *buf, size_t len) { - int i; - struct crng_state *crng; - struct crng_state **pool; + u32 chacha_state[CHACHA_BLOCK_SIZE / sizeof(u32)]; + u8 tmp[CHACHA_BLOCK_SIZE]; + size_t first_block_len; - pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL); - for_each_online_node(i) { - crng = kmalloc_node(sizeof(struct crng_state), - GFP_KERNEL | __GFP_NOFAIL, i); - spin_lock_init(&crng->lock); - crng_initialize(crng); - pool[i] = crng; - } - mb(); - if (cmpxchg(&crng_node_pool, NULL, pool)) { - for_each_node(i) - kfree(pool[i]); - kfree(pool); - } -} + if (!len) + return; -static DECLARE_WORK(numa_crng_init_work, do_numa_crng_init); + first_block_len = min_t(size_t, 32, len); + crng_make_state(chacha_state, buf, first_block_len); + len -= first_block_len; + buf += first_block_len; + + while (len) { + if (len < CHACHA_BLOCK_SIZE) { + chacha20_block(chacha_state, tmp); + memcpy(buf, tmp, len); + memzero_explicit(tmp, sizeof(tmp)); + break; + } -static void numa_crng_init(void) -{ - schedule_work(&numa_crng_init_work); + chacha20_block(chacha_state, buf); + if (unlikely(chacha_state[12] == 0)) + ++chacha_state[13]; + len -= CHACHA_BLOCK_SIZE; + buf += CHACHA_BLOCK_SIZE; + } + + memzero_explicit(chacha_state, sizeof(chacha_state)); } -#else -static void numa_crng_init(void) {} -#endif /* - * crng_fast_load() can be called by code in the interrupt service - * path. So we can't afford to dilly-dally. + * This function is the exported kernel interface. It returns some + * number of good random numbers, suitable for key generation, seeding + * TCP sequence numbers, etc. It does not rely on the hardware random + * number generator. For random bytes direct from the hardware RNG + * (when available), use get_random_bytes_arch(). In order to ensure + * that the randomness provided by this function is okay, the function + * wait_for_random_bytes() should be called and return 0 at least once + * at any point prior. */ -static int crng_fast_load(const char *cp, size_t len) +void get_random_bytes(void *buf, size_t len) { - unsigned long flags; - char *p; - - if (!spin_trylock_irqsave(&primary_crng.lock, flags)) - return 0; - if (crng_init != 0) { - spin_unlock_irqrestore(&primary_crng.lock, flags); - return 0; - } - p = (unsigned char *) &primary_crng.state[4]; - while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) { - p[crng_init_cnt % CHACHA_KEY_SIZE] ^= *cp; - cp++; crng_init_cnt++; len--; - } - spin_unlock_irqrestore(&primary_crng.lock, flags); - if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { - invalidate_batched_entropy(); - crng_init = 1; - wake_up_interruptible(&crng_init_wait); - pr_notice("random: fast init done\n"); - } - return 1; + warn_unseeded_randomness(); + _get_random_bytes(buf, len); } +EXPORT_SYMBOL(get_random_bytes); -/* - * crng_slow_load() is called by add_device_randomness, which has two - * attributes. (1) We can't trust the buffer passed to it is - * guaranteed to be unpredictable (so it might not have any entropy at - * all), and (2) it doesn't have the performance constraints of - * crng_fast_load(). - * - * So we do something more comprehensive which is guaranteed to touch - * all of the primary_crng's state, and which uses a LFSR with a - * period of 255 as part of the mixing algorithm. Finally, we do - * *not* advance crng_init_cnt since buffer we may get may be something - * like a fixed DMI table (for example), which might very well be - * unique to the machine, but is otherwise unvarying. - */ -static int crng_slow_load(const char *cp, size_t len) +static ssize_t get_random_bytes_user(struct iov_iter *iter) { - unsigned long flags; - static unsigned char lfsr = 1; - unsigned char tmp; - unsigned i, max = CHACHA_KEY_SIZE; - const char * src_buf = cp; - char * dest_buf = (char *) &primary_crng.state[4]; + u32 chacha_state[CHACHA_BLOCK_SIZE / sizeof(u32)]; + u8 block[CHACHA_BLOCK_SIZE]; + size_t ret = 0, copied; - if (!spin_trylock_irqsave(&primary_crng.lock, flags)) - return 0; - if (crng_init != 0) { - spin_unlock_irqrestore(&primary_crng.lock, flags); + if (unlikely(!iov_iter_count(iter))) return 0; + + /* + * Immediately overwrite the ChaCha key at index 4 with random + * bytes, in case userspace causes copy_to_iter() below to sleep + * forever, so that we still retain forward secrecy in that case. + */ + crng_make_state(chacha_state, (u8 *)&chacha_state[4], CHACHA_KEY_SIZE); + /* + * However, if we're doing a read of len <= 32, we don't need to + * use chacha_state after, so we can simply return those bytes to + * the user directly. + */ + if (iov_iter_count(iter) <= CHACHA_KEY_SIZE) { + ret = copy_to_iter(&chacha_state[4], CHACHA_KEY_SIZE, iter); + goto out_zero_chacha; } - if (len > max) - max = len; - for (i = 0; i < max ; i++) { - tmp = lfsr; - lfsr >>= 1; - if (tmp & 1) - lfsr ^= 0xE1; - tmp = dest_buf[i % CHACHA_KEY_SIZE]; - dest_buf[i % CHACHA_KEY_SIZE] ^= src_buf[i % len] ^ lfsr; - lfsr += (tmp << 3) | (tmp >> 5); - } - spin_unlock_irqrestore(&primary_crng.lock, flags); - return 1; -} - -static void crng_reseed(struct crng_state *crng, struct entropy_store *r) -{ - unsigned long flags; - int i, num; - union { - __u8 block[CHACHA_BLOCK_SIZE]; - __u32 key[8]; - } buf; - - if (r) { - num = extract_entropy(r, &buf, 32, 16, 0); - if (num == 0) - return; - } else { - _extract_crng(&primary_crng, buf.block); - _crng_backtrack_protect(&primary_crng, buf.block, - CHACHA_KEY_SIZE); - } - spin_lock_irqsave(&crng->lock, flags); - for (i = 0; i < 8; i++) { - unsigned long rv; - if (!arch_get_random_seed_long(&rv) && - !arch_get_random_long(&rv)) - rv = random_get_entropy(); - crng->state[i+4] ^= buf.key[i] ^ rv; - } - memzero_explicit(&buf, sizeof(buf)); - crng->init_time = jiffies; - spin_unlock_irqrestore(&crng->lock, flags); - if (crng == &primary_crng && crng_init < 2) { - invalidate_batched_entropy(); - numa_crng_init(); - crng_init = 2; - process_random_ready_list(); - wake_up_interruptible(&crng_init_wait); - pr_notice("random: crng init done\n"); - if (unseeded_warning.missed) { - pr_notice("random: %d get_random_xx warning(s) missed " - "due to ratelimiting\n", - unseeded_warning.missed); - unseeded_warning.missed = 0; - } - if (urandom_warning.missed) { - pr_notice("random: %d urandom warning(s) missed " - "due to ratelimiting\n", - urandom_warning.missed); - urandom_warning.missed = 0; + for (;;) { + chacha20_block(chacha_state, block); + if (unlikely(chacha_state[12] == 0)) + ++chacha_state[13]; + + copied = copy_to_iter(block, sizeof(block), iter); + ret += copied; + if (!iov_iter_count(iter) || copied != sizeof(block)) + break; + + BUILD_BUG_ON(PAGE_SIZE % sizeof(block) != 0); + if (ret % PAGE_SIZE == 0) { + if (signal_pending(current)) + break; + cond_resched(); } } -} -static void _extract_crng(struct crng_state *crng, - __u8 out[CHACHA_BLOCK_SIZE]) -{ - unsigned long v, flags; - - if (crng_ready() && - (time_after(crng_global_init_time, crng->init_time) || - time_after(jiffies, crng->init_time + CRNG_RESEED_INTERVAL))) - crng_reseed(crng, crng == &primary_crng ? &input_pool : NULL); - spin_lock_irqsave(&crng->lock, flags); - if (arch_get_random_long(&v)) - crng->state[14] ^= v; - chacha20_block(&crng->state[0], out); - if (crng->state[12] == 0) - crng->state[13]++; - spin_unlock_irqrestore(&crng->lock, flags); -} - -static void extract_crng(__u8 out[CHACHA_BLOCK_SIZE]) -{ - struct crng_state *crng = NULL; - -#ifdef CONFIG_NUMA - if (crng_node_pool) - crng = crng_node_pool[numa_node_id()]; - if (crng == NULL) -#endif - crng = &primary_crng; - _extract_crng(crng, out); -} + memzero_explicit(block, sizeof(block)); +out_zero_chacha: + memzero_explicit(chacha_state, sizeof(chacha_state)); + return ret ? ret : -EFAULT; +} + +/* + * Batched entropy returns random integers. The quality of the random + * number is good as /dev/urandom. In order to ensure that the randomness + * provided by this function is okay, the function wait_for_random_bytes() + * should be called and return 0 at least once at any point prior. + */ + +#define DEFINE_BATCHED_ENTROPY(type) \ +struct batch_ ##type { \ + /* \ + * We make this 1.5x a ChaCha block, so that we get the \ + * remaining 32 bytes from fast key erasure, plus one full \ + * block from the detached ChaCha state. We can increase \ + * the size of this later if needed so long as we keep the \ + * formula of (integer_blocks + 0.5) * CHACHA_BLOCK_SIZE. \ + */ \ + type entropy[CHACHA_BLOCK_SIZE * 3 / (2 * sizeof(type))]; \ + unsigned long generation; \ + unsigned int position; \ +}; \ + \ +static DEFINE_PER_CPU(struct batch_ ##type, batched_entropy_ ##type) = { \ + .position = UINT_MAX \ +}; \ + \ +type get_random_ ##type(void) \ +{ \ + type ret; \ + unsigned long flags; \ + struct batch_ ##type *batch; \ + unsigned long next_gen; \ + \ + warn_unseeded_randomness(); \ + \ + if (!crng_ready()) { \ + _get_random_bytes(&ret, sizeof(ret)); \ + return ret; \ + } \ + \ + local_irq_save(flags); \ + batch = raw_cpu_ptr(&batched_entropy_##type); \ + \ + next_gen = READ_ONCE(base_crng.generation); \ + if (batch->position >= ARRAY_SIZE(batch->entropy) || \ + next_gen != batch->generation) { \ + _get_random_bytes(batch->entropy, sizeof(batch->entropy)); \ + batch->position = 0; \ + batch->generation = next_gen; \ + } \ + \ + ret = batch->entropy[batch->position]; \ + batch->entropy[batch->position] = 0; \ + ++batch->position; \ + local_irq_restore(flags); \ + return ret; \ +} \ +EXPORT_SYMBOL(get_random_ ##type); + +DEFINE_BATCHED_ENTROPY(u64) +DEFINE_BATCHED_ENTROPY(u32) +#ifdef CONFIG_SMP /* - * Use the leftover bytes from the CRNG block output (if there is - * enough) to mutate the CRNG key to provide backtracking protection. + * This function is called when the CPU is coming up, with entry + * CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP. */ -static void _crng_backtrack_protect(struct crng_state *crng, - __u8 tmp[CHACHA_BLOCK_SIZE], int used) +int __cold random_prepare_cpu(unsigned int cpu) { - unsigned long flags; - __u32 *s, *d; - int i; - - used = round_up(used, sizeof(__u32)); - if (used + CHACHA_KEY_SIZE > CHACHA_BLOCK_SIZE) { - extract_crng(tmp); - used = 0; - } - spin_lock_irqsave(&crng->lock, flags); - s = (__u32 *) &tmp[used]; - d = &crng->state[4]; - for (i=0; i < 8; i++) - *d++ ^= *s++; - spin_unlock_irqrestore(&crng->lock, flags); + /* + * When the cpu comes back online, immediately invalidate both + * the per-cpu crng and all batches, so that we serve fresh + * randomness. + */ + per_cpu_ptr(&crngs, cpu)->generation = ULONG_MAX; + per_cpu_ptr(&batched_entropy_u32, cpu)->position = UINT_MAX; + per_cpu_ptr(&batched_entropy_u64, cpu)->position = UINT_MAX; + return 0; } - -static void crng_backtrack_protect(__u8 tmp[CHACHA_BLOCK_SIZE], int used) -{ - struct crng_state *crng = NULL; - -#ifdef CONFIG_NUMA - if (crng_node_pool) - crng = crng_node_pool[numa_node_id()]; - if (crng == NULL) #endif - crng = &primary_crng; - _crng_backtrack_protect(crng, tmp, used); -} -static ssize_t extract_crng_user(void __user *buf, size_t nbytes) +/* + * This function will use the architecture-specific hardware random + * number generator if it is available. It is not recommended for + * use. Use get_random_bytes() instead. It returns the number of + * bytes filled in. + */ +size_t __must_check get_random_bytes_arch(void *buf, size_t len) { - ssize_t ret = 0, i = CHACHA_BLOCK_SIZE; - __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); - int large_request = (nbytes > 256); + size_t left = len; + u8 *p = buf; - while (nbytes) { - if (large_request && need_resched()) { - if (signal_pending(current)) { - if (ret == 0) - ret = -ERESTARTSYS; - break; - } - schedule(); - } + while (left) { + unsigned long v; + size_t block_len = min_t(size_t, left, sizeof(unsigned long)); - extract_crng(tmp); - i = min_t(int, nbytes, CHACHA_BLOCK_SIZE); - if (copy_to_user(buf, tmp, i)) { - ret = -EFAULT; + if (!arch_get_random_long(&v)) break; - } - nbytes -= i; - buf += i; - ret += i; + memcpy(p, &v, block_len); + p += block_len; + left -= block_len; } - crng_backtrack_protect(tmp, i); - - /* Wipe data just written to memory */ - memzero_explicit(tmp, sizeof(tmp)); - return ret; + return len - left; } +EXPORT_SYMBOL(get_random_bytes_arch); -/********************************************************************* +/********************************************************************** * - * Entropy input management + * Entropy accumulation and extraction routines. * - *********************************************************************/ + * Callers may add entropy via: + * + * static void mix_pool_bytes(const void *buf, size_t len) + * + * After which, if added entropy should be credited: + * + * static void credit_init_bits(size_t bits) + * + * Finally, extract entropy via: + * + * static void extract_entropy(void *buf, size_t len) + * + **********************************************************************/ -/* There is one of these per entropy source */ -struct timer_rand_state { - cycles_t last_time; - long last_delta, last_delta2; +enum { + POOL_BITS = BLAKE2S_HASH_SIZE * 8, + POOL_READY_BITS = POOL_BITS, /* When crng_init->CRNG_READY */ + POOL_EARLY_BITS = POOL_READY_BITS / 2 /* When crng_init->CRNG_EARLY */ +}; + +static struct { + struct blake2s_state hash; + spinlock_t lock; + unsigned int init_bits; +} input_pool = { + .hash.h = { BLAKE2S_IV0 ^ (0x01010000 | BLAKE2S_HASH_SIZE), + BLAKE2S_IV1, BLAKE2S_IV2, BLAKE2S_IV3, BLAKE2S_IV4, + BLAKE2S_IV5, BLAKE2S_IV6, BLAKE2S_IV7 }, + .hash.outlen = BLAKE2S_HASH_SIZE, + .lock = __SPIN_LOCK_UNLOCKED(input_pool.lock), }; -#define INIT_TIMER_RAND_STATE { INITIAL_JIFFIES, }; +static void _mix_pool_bytes(const void *buf, size_t len) +{ + blake2s_update(&input_pool.hash, buf, len); +} /* - * Add device- or boot-specific data to the input pool to help - * initialize it. - * - * None of this adds any entropy; it is meant to avoid the problem of - * the entropy pool having similar initial state across largely - * identical devices. + * This function adds bytes into the input pool. It does not + * update the initialization bit counter; the caller should call + * credit_init_bits if this is appropriate. */ -void add_device_randomness(const void *buf, unsigned int size) +static void mix_pool_bytes(const void *buf, size_t len) { - unsigned long time = random_get_entropy() ^ jiffies; unsigned long flags; - if (!crng_ready() && size) - crng_slow_load(buf, size); - - trace_add_device_randomness(size, _RET_IP_); spin_lock_irqsave(&input_pool.lock, flags); - _mix_pool_bytes(&input_pool, buf, size); - _mix_pool_bytes(&input_pool, &time, sizeof(time)); + _mix_pool_bytes(buf, len); spin_unlock_irqrestore(&input_pool.lock, flags); } -EXPORT_SYMBOL(add_device_randomness); - -static struct timer_rand_state input_timer_state = INIT_TIMER_RAND_STATE; /* - * This function adds entropy to the entropy "pool" by using timing - * delays. It uses the timer_rand_state structure to make an estimate - * of how many bits of entropy this call has added to the pool. - * - * The number "num" is also added to the pool - it should somehow describe - * the type of event which just happened. This is currently 0-255 for - * keyboard scan codes, and 256 upwards for interrupts. - * + * This is an HKDF-like construction for using the hashed collected entropy + * as a PRF key, that's then expanded block-by-block. */ -static void add_timer_randomness(struct timer_rand_state *state, unsigned num) +static void extract_entropy(void *buf, size_t len) { - struct entropy_store *r; + unsigned long flags; + u8 seed[BLAKE2S_HASH_SIZE], next_key[BLAKE2S_HASH_SIZE]; struct { - long jiffies; - unsigned cycles; - unsigned num; - } sample; - long delta, delta2, delta3; - - sample.jiffies = jiffies; - sample.cycles = random_get_entropy(); - sample.num = num; - r = &input_pool; - mix_pool_bytes(r, &sample, sizeof(sample)); - - /* - * Calculate number of bits of randomness we probably added. - * We take into account the first, second and third-order deltas - * in order to make our estimate. - */ - delta = sample.jiffies - state->last_time; - state->last_time = sample.jiffies; + unsigned long rdseed[32 / sizeof(long)]; + size_t counter; + } block; + size_t i; + + for (i = 0; i < ARRAY_SIZE(block.rdseed); ++i) { + if (!arch_get_random_seed_long(&block.rdseed[i]) && + !arch_get_random_long(&block.rdseed[i])) + block.rdseed[i] = random_get_entropy(); + } - delta2 = delta - state->last_delta; - state->last_delta = delta; + spin_lock_irqsave(&input_pool.lock, flags); - delta3 = delta2 - state->last_delta2; - state->last_delta2 = delta2; + /* seed = HASHPRF(last_key, entropy_input) */ + blake2s_final(&input_pool.hash, seed); - if (delta < 0) - delta = -delta; - if (delta2 < 0) - delta2 = -delta2; - if (delta3 < 0) - delta3 = -delta3; - if (delta > delta2) - delta = delta2; - if (delta > delta3) - delta = delta3; - - /* - * delta is now minimum absolute delta. - * Round down by 1 bit on general principles, - * and limit entropy entimate to 12 bits. - */ - credit_entropy_bits(r, min_t(int, fls(delta>>1), 11)); -} + /* next_key = HASHPRF(seed, RDSEED || 0) */ + block.counter = 0; + blake2s(next_key, (u8 *)&block, seed, sizeof(next_key), sizeof(block), sizeof(seed)); + blake2s_init_key(&input_pool.hash, BLAKE2S_HASH_SIZE, next_key, sizeof(next_key)); -void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value) -{ - static unsigned char last_value; + spin_unlock_irqrestore(&input_pool.lock, flags); + memzero_explicit(next_key, sizeof(next_key)); - /* ignore autorepeat and the like */ - if (value == last_value) - return; + while (len) { + i = min_t(size_t, len, BLAKE2S_HASH_SIZE); + /* output = HASHPRF(seed, RDSEED || ++counter) */ + ++block.counter; + blake2s(buf, (u8 *)&block, seed, i, sizeof(block), sizeof(seed)); + len -= i; + buf += i; + } - last_value = value; - add_timer_randomness(&input_timer_state, - (type << 4) ^ code ^ (code >> 4) ^ value); - trace_add_input_randomness(ENTROPY_BITS(&input_pool)); + memzero_explicit(seed, sizeof(seed)); + memzero_explicit(&block, sizeof(block)); } -EXPORT_SYMBOL_GPL(add_input_randomness); - -static DEFINE_PER_CPU(struct fast_pool, irq_randomness); - -#ifdef ADD_INTERRUPT_BENCH -static unsigned long avg_cycles, avg_deviation; -#define AVG_SHIFT 8 /* Exponential average factor k=1/256 */ -#define FIXED_1_2 (1 << (AVG_SHIFT-1)) +#define credit_init_bits(bits) if (!crng_ready()) _credit_init_bits(bits) -static void add_interrupt_bench(cycles_t start) +static void __cold _credit_init_bits(size_t bits) { - long delta = random_get_entropy() - start; - - /* Use a weighted moving average */ - delta = delta - ((avg_cycles + FIXED_1_2) >> AVG_SHIFT); - avg_cycles += delta; - /* And average deviation */ - delta = abs(delta) - ((avg_deviation + FIXED_1_2) >> AVG_SHIFT); - avg_deviation += delta; -} -#else -#define add_interrupt_bench(x) -#endif - -static __u32 get_reg(struct fast_pool *f, struct pt_regs *regs) -{ - __u32 *ptr = (__u32 *) regs; - unsigned int idx; - - if (regs == NULL) - return 0; - idx = READ_ONCE(f->reg_idx); - if (idx >= sizeof(struct pt_regs) / sizeof(__u32)) - idx = 0; - ptr += idx++; - WRITE_ONCE(f->reg_idx, idx); - return *ptr; -} - -void add_interrupt_randomness(int irq, int irq_flags) -{ - struct entropy_store *r; - struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness); - struct pt_regs *regs = get_irq_regs(); - unsigned long now = jiffies; - cycles_t cycles = random_get_entropy(); - __u32 c_high, j_high; - __u64 ip; - unsigned long seed; - int credit = 0; - - if (cycles == 0) - cycles = get_reg(fast_pool, regs); - c_high = (sizeof(cycles) > 4) ? cycles >> 32 : 0; - j_high = (sizeof(now) > 4) ? now >> 32 : 0; - fast_pool->pool[0] ^= cycles ^ j_high ^ irq; - fast_pool->pool[1] ^= now ^ c_high; - ip = regs ? instruction_pointer(regs) : _RET_IP_; - fast_pool->pool[2] ^= ip; - fast_pool->pool[3] ^= (sizeof(ip) > 4) ? ip >> 32 : - get_reg(fast_pool, regs); - - fast_mix(fast_pool); - add_interrupt_bench(cycles); - - if (unlikely(crng_init == 0)) { - if ((fast_pool->count >= 64) && - crng_fast_load((char *) fast_pool->pool, - sizeof(fast_pool->pool))) { - fast_pool->count = 0; - fast_pool->last = now; - } - return; - } + unsigned int new, orig, add; + unsigned long flags; - if ((fast_pool->count < 64) && - !time_after(now, fast_pool->last + HZ)) + if (!bits) return; - r = &input_pool; - if (!spin_trylock(&r->lock)) - return; + add = min_t(size_t, bits, POOL_BITS); - fast_pool->last = now; - __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool)); + do { + orig = READ_ONCE(input_pool.init_bits); + new = min_t(unsigned int, POOL_BITS, orig + add); + } while (cmpxchg(&input_pool.init_bits, orig, new) != orig); - /* - * If we have architectural seed generator, produce a seed and - * add it to the pool. For the sake of paranoia don't let the - * architectural seed generator dominate the input from the - * interrupt noise. - */ - if (arch_get_random_seed_long(&seed)) { - __mix_pool_bytes(r, &seed, sizeof(seed)); - credit = 1; + if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) { + crng_reseed(); /* Sets crng_init to CRNG_READY under base_crng.lock. */ + process_random_ready_list(); + wake_up_interruptible(&crng_init_wait); + kill_fasync(&fasync, SIGIO, POLL_IN); + pr_notice("crng init done\n"); + if (urandom_warning.missed) + pr_notice("%d urandom warning(s) missed due to ratelimiting\n", + urandom_warning.missed); + } else if (orig < POOL_EARLY_BITS && new >= POOL_EARLY_BITS) { + spin_lock_irqsave(&base_crng.lock, flags); + /* Check if crng_init is CRNG_EMPTY, to avoid race with crng_reseed(). */ + if (crng_init == CRNG_EMPTY) { + extract_entropy(base_crng.key, sizeof(base_crng.key)); + crng_init = CRNG_EARLY; + } + spin_unlock_irqrestore(&base_crng.lock, flags); } - spin_unlock(&r->lock); - - fast_pool->count = 0; - - /* award one bit for the contents of the fast pool */ - credit_entropy_bits(r, credit + 1); } -EXPORT_SYMBOL_GPL(add_interrupt_randomness); -#ifdef CONFIG_BLOCK -void add_disk_randomness(struct gendisk *disk) -{ - if (!disk || !disk->random) - return; - /* first major is 1, so we get >= 0x200 here */ - add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); - trace_add_disk_randomness(disk_devt(disk), ENTROPY_BITS(&input_pool)); -} -EXPORT_SYMBOL_GPL(add_disk_randomness); -#endif -/********************************************************************* +/********************************************************************** * - * Entropy extraction routines + * Entropy collection routines. * - *********************************************************************/ - -/* - * This utility inline function is responsible for transferring entropy - * from the primary pool to the secondary extraction pool. We make - * sure we pull enough for a 'catastrophic reseed'. - */ -static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes); -static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) -{ - if (!r->pull || - r->entropy_count >= (nbytes << (ENTROPY_SHIFT + 3)) || - r->entropy_count > r->poolinfo->poolfracbits) - return; + * The following exported functions are used for pushing entropy into + * the above entropy accumulation routines: + * + * void add_device_randomness(const void *buf, size_t len); + * void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy); + * void add_bootloader_randomness(const void *buf, size_t len); + * void add_interrupt_randomness(int irq); + * void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); + * void add_disk_randomness(struct gendisk *disk); + * + * add_device_randomness() adds data to the input pool that + * is likely to differ between two devices (or possibly even per boot). + * This would be things like MAC addresses or serial numbers, or the + * read-out of the RTC. This does *not* credit any actual entropy to + * the pool, but it initializes the pool to different values for devices + * that might otherwise be identical and have very little entropy + * available to them (particularly common in the embedded world). + * + * add_hwgenerator_randomness() is for true hardware RNGs, and will credit + * entropy as specified by the caller. If the entropy pool is full it will + * block until more entropy is needed. + * + * add_bootloader_randomness() is called by bootloader drivers, such as EFI + * and device tree, and credits its input depending on whether or not the + * configuration option CONFIG_RANDOM_TRUST_BOOTLOADER is set. + * + * add_interrupt_randomness() uses the interrupt timing as random + * inputs to the entropy pool. Using the cycle counters and the irq source + * as inputs, it feeds the input pool roughly once a second or after 64 + * interrupts, crediting 1 bit of entropy for whichever comes first. + * + * add_input_randomness() uses the input layer interrupt timing, as well + * as the event type information from the hardware. + * + * add_disk_randomness() uses what amounts to the seek time of block + * layer request events, on a per-disk_devt basis, as input to the + * entropy pool. Note that high-speed solid state drives with very low + * seek times do not make for good sources of entropy, as their seek + * times are usually fairly consistent. + * + * The last two routines try to estimate how many bits of entropy + * to credit. They do this by keeping track of the first and second + * order deltas of the event timings. + * + **********************************************************************/ - _xfer_secondary_pool(r, nbytes); +static bool trust_cpu __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_CPU); +static bool trust_bootloader __initdata = IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER); +static int __init parse_trust_cpu(char *arg) +{ + return kstrtobool(arg, &trust_cpu); } +static int __init parse_trust_bootloader(char *arg) +{ + return kstrtobool(arg, &trust_bootloader); +} +early_param("random.trust_cpu", parse_trust_cpu); +early_param("random.trust_bootloader", parse_trust_bootloader); -static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes) +/* + * The first collection of entropy occurs at system boot while interrupts + * are still turned off. Here we push in latent entropy, RDSEED, a timestamp, + * utsname(), and the command line. Depending on the above configuration knob, + * RDSEED may be considered sufficient for initialization. Note that much + * earlier setup may already have pushed entropy into the input pool by the + * time we get here. + */ +int __init random_init(const char *command_line) { - __u32 tmp[OUTPUT_POOL_WORDS]; + ktime_t now = ktime_get_real(); + unsigned int i, arch_bits; + unsigned long entropy; - int bytes = nbytes; +#if defined(LATENT_ENTROPY_PLUGIN) + static const u8 compiletime_seed[BLAKE2S_BLOCK_SIZE] __initconst __latent_entropy; + _mix_pool_bytes(compiletime_seed, sizeof(compiletime_seed)); +#endif - /* pull at least as much as a wakeup */ - bytes = max_t(int, bytes, random_read_wakeup_bits / 8); - /* but never more than the buffer size */ - bytes = min_t(int, bytes, sizeof(tmp)); + for (i = 0, arch_bits = BLAKE2S_BLOCK_SIZE * 8; + i < BLAKE2S_BLOCK_SIZE; i += sizeof(entropy)) { + if (!arch_get_random_seed_long_early(&entropy) && + !arch_get_random_long_early(&entropy)) { + entropy = random_get_entropy(); + arch_bits -= sizeof(entropy) * 8; + } + _mix_pool_bytes(&entropy, sizeof(entropy)); + } + _mix_pool_bytes(&now, sizeof(now)); + _mix_pool_bytes(utsname(), sizeof(*(utsname()))); + _mix_pool_bytes(command_line, strlen(command_line)); + add_latent_entropy(); + + if (crng_ready()) + crng_reseed(); + else if (trust_cpu) + _credit_init_bits(arch_bits); - trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8, - ENTROPY_BITS(r), ENTROPY_BITS(r->pull)); - bytes = extract_entropy(r->pull, tmp, bytes, - random_read_wakeup_bits / 8, 0); - mix_pool_bytes(r, tmp, bytes); - credit_entropy_bits(r, bytes*8); + return 0; } /* - * Used as a workqueue function so that when the input pool is getting - * full, we can "spill over" some entropy to the output pools. That - * way the output pools can store some of the excess entropy instead - * of letting it go to waste. + * Add device- or boot-specific data to the input pool to help + * initialize it. + * + * None of this adds any entropy; it is meant to avoid the problem of + * the entropy pool having similar initial state across largely + * identical devices. */ -static void push_to_pool(struct work_struct *work) +void add_device_randomness(const void *buf, size_t len) { - struct entropy_store *r = container_of(work, struct entropy_store, - push_work); - BUG_ON(!r); - _xfer_secondary_pool(r, random_read_wakeup_bits/8); - trace_push_to_pool(r->name, r->entropy_count >> ENTROPY_SHIFT, - r->pull->entropy_count >> ENTROPY_SHIFT); + unsigned long entropy = random_get_entropy(); + unsigned long flags; + + spin_lock_irqsave(&input_pool.lock, flags); + _mix_pool_bytes(&entropy, sizeof(entropy)); + _mix_pool_bytes(buf, len); + spin_unlock_irqrestore(&input_pool.lock, flags); } +EXPORT_SYMBOL(add_device_randomness); /* - * This function decides how many bytes to actually take from the - * given pool, and also debits the entropy count accordingly. + * Interface for in-kernel drivers of true hardware RNGs. + * Those devices may produce endless random bits and will be throttled + * when our pool is full. */ -static size_t account(struct entropy_store *r, size_t nbytes, int min, - int reserved) +void add_hwgenerator_randomness(const void *buf, size_t len, size_t entropy) { - int entropy_count, orig, have_bytes; - size_t ibytes, nfrac; - - BUG_ON(r->entropy_count > r->poolinfo->poolfracbits); + mix_pool_bytes(buf, len); + credit_init_bits(entropy); - /* Can we pull enough? */ -retry: - entropy_count = orig = READ_ONCE(r->entropy_count); - ibytes = nbytes; - /* never pull more than available */ - have_bytes = entropy_count >> (ENTROPY_SHIFT + 3); + /* + * Throttle writing to once every CRNG_RESEED_INTERVAL, unless + * we're not yet initialized. + */ + if (!kthread_should_stop() && crng_ready()) + schedule_timeout_interruptible(CRNG_RESEED_INTERVAL); +} +EXPORT_SYMBOL_GPL(add_hwgenerator_randomness); - if ((have_bytes -= reserved) < 0) - have_bytes = 0; - ibytes = min_t(size_t, ibytes, have_bytes); - if (ibytes < min) - ibytes = 0; +/* + * Handle random seed passed by bootloader, and credit it if + * CONFIG_RANDOM_TRUST_BOOTLOADER is set. + */ +void __init add_bootloader_randomness(const void *buf, size_t len) +{ + mix_pool_bytes(buf, len); + if (trust_bootloader) + credit_init_bits(len * 8); +} - if (unlikely(entropy_count < 0)) { - pr_warn("random: negative entropy count: pool %s count %d\n", - r->name, entropy_count); - WARN_ON(1); - entropy_count = 0; - } - nfrac = ibytes << (ENTROPY_SHIFT + 3); - if ((size_t) entropy_count > nfrac) - entropy_count -= nfrac; - else - entropy_count = 0; +struct fast_pool { + unsigned long pool[4]; + unsigned long last; + unsigned int count; + struct timer_list mix; +}; - if (cmpxchg(&r->entropy_count, orig, entropy_count) != orig) - goto retry; +static void mix_interrupt_randomness(struct timer_list *work); - trace_debit_entropy(r->name, 8 * ibytes); - if (ibytes && - (r->entropy_count >> ENTROPY_SHIFT) < random_write_wakeup_bits) { - wake_up_interruptible(&random_write_wait); - kill_fasync(&fasync, SIGIO, POLL_OUT); - } +static DEFINE_PER_CPU(struct fast_pool, irq_randomness) = { +#ifdef CONFIG_64BIT +#define FASTMIX_PERM SIPHASH_PERMUTATION + .pool = { SIPHASH_CONST_0, SIPHASH_CONST_1, SIPHASH_CONST_2, SIPHASH_CONST_3 }, +#else +#define FASTMIX_PERM HSIPHASH_PERMUTATION + .pool = { HSIPHASH_CONST_0, HSIPHASH_CONST_1, HSIPHASH_CONST_2, HSIPHASH_CONST_3 }, +#endif + .mix = __TIMER_INITIALIZER(mix_interrupt_randomness, 0) +}; - return ibytes; +/* + * This is [Half]SipHash-1-x, starting from an empty key. Because + * the key is fixed, it assumes that its inputs are non-malicious, + * and therefore this has no security on its own. s represents the + * four-word SipHash state, while v represents a two-word input. + */ +static void fast_mix(unsigned long s[4], unsigned long v1, unsigned long v2) +{ + s[3] ^= v1; + FASTMIX_PERM(s[0], s[1], s[2], s[3]); + s[0] ^= v1; + s[3] ^= v2; + FASTMIX_PERM(s[0], s[1], s[2], s[3]); + s[0] ^= v2; } +#ifdef CONFIG_SMP /* - * This function does the actual extraction for extract_entropy and - * extract_entropy_user. - * - * Note: we assume that .poolwords is a multiple of 16 words. + * This function is called when the CPU has just come online, with + * entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE. */ -static void extract_buf(struct entropy_store *r, __u8 *out) +int __cold random_online_cpu(unsigned int cpu) { - int i; - union { - __u32 w[5]; - unsigned long l[LONGS(20)]; - } hash; - __u32 workspace[SHA_WORKSPACE_WORDS]; - unsigned long flags; - /* - * If we have an architectural hardware random number - * generator, use it for SHA's initial vector + * During CPU shutdown and before CPU onlining, add_interrupt_ + * randomness() may schedule mix_interrupt_randomness(), and + * set the MIX_INFLIGHT flag. However, because the worker can + * be scheduled on a different CPU during this period, that + * flag will never be cleared. For that reason, we zero out + * the flag here, which runs just after workqueues are onlined + * for the CPU again. This also has the effect of setting the + * irq randomness count to zero so that new accumulated irqs + * are fresh. */ - sha_init(hash.w); - for (i = 0; i < LONGS(20); i++) { - unsigned long v; - if (!arch_get_random_long(&v)) - break; - hash.l[i] = v; - } - - /* Generate a hash across the pool, 16 words (512 bits) at a time */ - spin_lock_irqsave(&r->lock, flags); - for (i = 0; i < r->poolinfo->poolwords; i += 16) - sha_transform(hash.w, (__u8 *)(r->pool + i), workspace); + per_cpu_ptr(&irq_randomness, cpu)->count = 0; + return 0; +} +#endif +static void mix_interrupt_randomness(struct timer_list *work) +{ + struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix); /* - * We mix the hash back into the pool to prevent backtracking - * attacks (where the attacker knows the state of the pool - * plus the current outputs, and attempts to find previous - * ouputs), unless the hash function can be inverted. By - * mixing at least a SHA1 worth of hash data back, we make - * brute-forcing the feedback as hard as brute-forcing the - * hash. + * The size of the copied stack pool is explicitly 2 longs so that we + * only ever ingest half of the siphash output each time, retaining + * the other half as the next "key" that carries over. The entropy is + * supposed to be sufficiently dispersed between bits so on average + * we don't wind up "losing" some. */ - __mix_pool_bytes(r, hash.w, sizeof(hash.w)); - spin_unlock_irqrestore(&r->lock, flags); + unsigned long pool[2]; + unsigned int count; - memzero_explicit(workspace, sizeof(workspace)); + /* Check to see if we're running on the wrong CPU due to hotplug. */ + local_irq_disable(); + if (fast_pool != this_cpu_ptr(&irq_randomness)) { + local_irq_enable(); + return; + } /* - * In case the hash function has some recognizable output - * pattern, we fold it in half. Thus, we always feed back - * twice as much data as we output. + * Copy the pool to the stack so that the mixer always has a + * consistent view, before we reenable irqs again. */ - hash.w[0] ^= hash.w[3]; - hash.w[1] ^= hash.w[4]; - hash.w[2] ^= rol32(hash.w[2], 16); + memcpy(pool, fast_pool->pool, sizeof(pool)); + count = fast_pool->count; + fast_pool->count = 0; + fast_pool->last = jiffies; + local_irq_enable(); + + mix_pool_bytes(pool, sizeof(pool)); + credit_init_bits(clamp_t(unsigned int, (count & U16_MAX) / 64, 1, sizeof(pool) * 8)); - memcpy(out, &hash, EXTRACT_SIZE); - memzero_explicit(&hash, sizeof(hash)); + memzero_explicit(pool, sizeof(pool)); } -static ssize_t _extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int fips) +void add_interrupt_randomness(int irq) { - ssize_t ret = 0, i; - __u8 tmp[EXTRACT_SIZE]; - unsigned long flags; + enum { MIX_INFLIGHT = 1U << 31 }; + unsigned long entropy = random_get_entropy(); + struct fast_pool *fast_pool = this_cpu_ptr(&irq_randomness); + struct pt_regs *regs = get_irq_regs(); + unsigned int new_count; - while (nbytes) { - extract_buf(r, tmp); + fast_mix(fast_pool->pool, entropy, + (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq)); + new_count = ++fast_pool->count; - if (fips) { - spin_lock_irqsave(&r->lock, flags); - if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) - panic("Hardware RNG duplicated output!\n"); - memcpy(r->last_data, tmp, EXTRACT_SIZE); - spin_unlock_irqrestore(&r->lock, flags); - } - i = min_t(int, nbytes, EXTRACT_SIZE); - memcpy(buf, tmp, i); - nbytes -= i; - buf += i; - ret += i; - } + if (new_count & MIX_INFLIGHT) + return; - /* Wipe data just returned from memory */ - memzero_explicit(tmp, sizeof(tmp)); + if (new_count < 1024 && !time_is_before_jiffies(fast_pool->last + HZ)) + return; - return ret; + fast_pool->count |= MIX_INFLIGHT; + if (!timer_pending(&fast_pool->mix)) { + fast_pool->mix.expires = jiffies; + add_timer_on(&fast_pool->mix, raw_smp_processor_id()); + } } +EXPORT_SYMBOL_GPL(add_interrupt_randomness); + +/* There is one of these per entropy source */ +struct timer_rand_state { + unsigned long last_time; + long last_delta, last_delta2; +}; /* - * This function extracts randomness from the "entropy pool", and - * returns it in a buffer. - * - * The min parameter specifies the minimum amount we can pull before - * failing to avoid races that defeat catastrophic reseeding while the - * reserved parameter indicates how much entropy we must leave in the - * pool after each pull to avoid starving other readers. + * This function adds entropy to the entropy "pool" by using timing + * delays. It uses the timer_rand_state structure to make an estimate + * of how many bits of entropy this call has added to the pool. The + * value "num" is also added to the pool; it should somehow describe + * the type of event that just happened. */ -static ssize_t extract_entropy(struct entropy_store *r, void *buf, - size_t nbytes, int min, int reserved) +static void add_timer_randomness(struct timer_rand_state *state, unsigned int num) { - __u8 tmp[EXTRACT_SIZE]; - unsigned long flags; + unsigned long entropy = random_get_entropy(), now = jiffies, flags; + long delta, delta2, delta3; + unsigned int bits; - /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ - if (fips_enabled) { - spin_lock_irqsave(&r->lock, flags); - if (!r->last_data_init) { - r->last_data_init = 1; - spin_unlock_irqrestore(&r->lock, flags); - trace_extract_entropy(r->name, EXTRACT_SIZE, - ENTROPY_BITS(r), _RET_IP_); - xfer_secondary_pool(r, EXTRACT_SIZE); - extract_buf(r, tmp); - spin_lock_irqsave(&r->lock, flags); - memcpy(r->last_data, tmp, EXTRACT_SIZE); - } - spin_unlock_irqrestore(&r->lock, flags); + /* + * If we're in a hard IRQ, add_interrupt_randomness() will be called + * sometime after, so mix into the fast pool. + */ + if (in_irq()) { + fast_mix(this_cpu_ptr(&irq_randomness)->pool, entropy, num); + } else { + spin_lock_irqsave(&input_pool.lock, flags); + _mix_pool_bytes(&entropy, sizeof(entropy)); + _mix_pool_bytes(&num, sizeof(num)); + spin_unlock_irqrestore(&input_pool.lock, flags); } - trace_extract_entropy(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); - xfer_secondary_pool(r, nbytes); - nbytes = account(r, nbytes, min, reserved); - - return _extract_entropy(r, buf, nbytes, fips_enabled); -} - -/* - * This function extracts randomness from the "entropy pool", and - * returns it in a userspace buffer. - */ -static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, - size_t nbytes) -{ - ssize_t ret = 0, i; - __u8 tmp[EXTRACT_SIZE]; - int large_request = (nbytes > 256); + if (crng_ready()) + return; - trace_extract_entropy_user(r->name, nbytes, ENTROPY_BITS(r), _RET_IP_); - if (!r->initialized && r->pull) { - xfer_secondary_pool(r, ENTROPY_BITS(r->pull)/8); - if (!r->initialized) - return 0; - } - xfer_secondary_pool(r, nbytes); - nbytes = account(r, nbytes, 0, 0); + /* + * Calculate number of bits of randomness we probably added. + * We take into account the first, second and third-order deltas + * in order to make our estimate. + */ + delta = now - READ_ONCE(state->last_time); + WRITE_ONCE(state->last_time, now); - while (nbytes) { - if (large_request && need_resched()) { - if (signal_pending(current)) { - if (ret == 0) - ret = -ERESTARTSYS; - break; - } - schedule(); - } + delta2 = delta - READ_ONCE(state->last_delta); + WRITE_ONCE(state->last_delta, delta); - extract_buf(r, tmp); - i = min_t(int, nbytes, EXTRACT_SIZE); - if (copy_to_user(buf, tmp, i)) { - ret = -EFAULT; - break; - } + delta3 = delta2 - READ_ONCE(state->last_delta2); + WRITE_ONCE(state->last_delta2, delta2); - nbytes -= i; - buf += i; - ret += i; - } + if (delta < 0) + delta = -delta; + if (delta2 < 0) + delta2 = -delta2; + if (delta3 < 0) + delta3 = -delta3; + if (delta > delta2) + delta = delta2; + if (delta > delta3) + delta = delta3; - /* Wipe data just returned from memory */ - memzero_explicit(tmp, sizeof(tmp)); + /* + * delta is now minimum absolute delta. Round down by 1 bit + * on general principles, and limit entropy estimate to 11 bits. + */ + bits = min(fls(delta >> 1), 11); - return ret; + /* + * As mentioned above, if we're in a hard IRQ, add_interrupt_randomness() + * will run after this, which uses a different crediting scheme of 1 bit + * per every 64 interrupts. In order to let that function do accounting + * close to the one in this function, we credit a full 64/64 bit per bit, + * and then subtract one to account for the extra one added. + */ + if (in_irq()) + this_cpu_ptr(&irq_randomness)->count += max(1u, bits * 64) - 1; + else + _credit_init_bits(bits); } -#define warn_unseeded_randomness(previous) \ - _warn_unseeded_randomness(__func__, (void *) _RET_IP_, (previous)) - -static void _warn_unseeded_randomness(const char *func_name, void *caller, - void **previous) +void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) { -#ifdef CONFIG_WARN_ALL_UNSEEDED_RANDOM - const bool print_once = false; -#else - static bool print_once __read_mostly; -#endif + static unsigned char last_value; + static struct timer_rand_state input_timer_state = { INITIAL_JIFFIES }; - if (print_once || - crng_ready() || - (previous && (caller == READ_ONCE(*previous)))) + /* Ignore autorepeat and the like. */ + if (value == last_value) return; - WRITE_ONCE(*previous, caller); -#ifndef CONFIG_WARN_ALL_UNSEEDED_RANDOM - print_once = true; -#endif - if (__ratelimit(&unseeded_warning)) - pr_notice("random: %s called from %pS with crng_init=%d\n", - func_name, caller, crng_init); + + last_value = value; + add_timer_randomness(&input_timer_state, + (type << 4) ^ code ^ (code >> 4) ^ value); } +EXPORT_SYMBOL_GPL(add_input_randomness); -/* - * This function is the exported kernel interface. It returns some - * number of good random numbers, suitable for key generation, seeding - * TCP sequence numbers, etc. It does not rely on the hardware random - * number generator. For random bytes direct from the hardware RNG - * (when available), use get_random_bytes_arch(). In order to ensure - * that the randomness provided by this function is okay, the function - * wait_for_random_bytes() should be called and return 0 at least once - * at any point prior. - */ -static void _get_random_bytes(void *buf, int nbytes) +#ifdef CONFIG_BLOCK +void add_disk_randomness(struct gendisk *disk) { - __u8 tmp[CHACHA_BLOCK_SIZE] __aligned(4); - - trace_get_random_bytes(nbytes, _RET_IP_); - - while (nbytes >= CHACHA_BLOCK_SIZE) { - extract_crng(buf); - buf += CHACHA_BLOCK_SIZE; - nbytes -= CHACHA_BLOCK_SIZE; - } - - if (nbytes > 0) { - extract_crng(tmp); - memcpy(buf, tmp, nbytes); - crng_backtrack_protect(tmp, nbytes); - } else - crng_backtrack_protect(tmp, CHACHA_BLOCK_SIZE); - memzero_explicit(tmp, sizeof(tmp)); + if (!disk || !disk->random) + return; + /* First major is 1, so we get >= 0x200 here. */ + add_timer_randomness(disk->random, 0x100 + disk_devt(disk)); } +EXPORT_SYMBOL_GPL(add_disk_randomness); -void get_random_bytes(void *buf, int nbytes) +void __cold rand_initialize_disk(struct gendisk *disk) { - static void *previous; + struct timer_rand_state *state; - warn_unseeded_randomness(&previous); - _get_random_bytes(buf, nbytes); + /* + * If kzalloc returns null, we just won't use that entropy + * source. + */ + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); + if (state) { + state->last_time = INITIAL_JIFFIES; + disk->random = state; + } } -EXPORT_SYMBOL(get_random_bytes); - +#endif /* * Each time the timer fires, we expect that we got an unpredictable @@ -1745,371 +1143,181 @@ * * So the re-arming always happens in the entropy loop itself. */ -static void entropy_timer(struct timer_list *t) +static void __cold entropy_timer(struct timer_list *t) { - credit_entropy_bits(&input_pool, 1); + credit_init_bits(1); } /* * If we have an actual cycle counter, see if we can * generate enough entropy with timing noise */ -static void try_to_generate_entropy(void) +static void __cold try_to_generate_entropy(void) { struct { - unsigned long now; + unsigned long entropy; struct timer_list timer; } stack; - stack.now = random_get_entropy(); + stack.entropy = random_get_entropy(); /* Slow counter - or none. Don't even bother */ - if (stack.now == random_get_entropy()) + if (stack.entropy == random_get_entropy()) return; timer_setup_on_stack(&stack.timer, entropy_timer, 0); - while (!crng_ready()) { + while (!crng_ready() && !signal_pending(current)) { if (!timer_pending(&stack.timer)) - mod_timer(&stack.timer, jiffies+1); - mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now)); + mod_timer(&stack.timer, jiffies + 1); + mix_pool_bytes(&stack.entropy, sizeof(stack.entropy)); schedule(); - stack.now = random_get_entropy(); + stack.entropy = random_get_entropy(); } del_timer_sync(&stack.timer); destroy_timer_on_stack(&stack.timer); - mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now)); + mix_pool_bytes(&stack.entropy, sizeof(stack.entropy)); } -/* - * Wait for the urandom pool to be seeded and thus guaranteed to supply - * cryptographically secure random numbers. This applies to: the /dev/urandom - * device, the get_random_bytes function, and the get_random_{u32,u64,int,long} - * family of functions. Using any of these functions without first calling - * this function forfeits the guarantee of security. - * - * Returns: 0 if the urandom pool has been seeded. - * -ERESTARTSYS if the function was interrupted by a signal. - */ -int wait_for_random_bytes(void) -{ - if (likely(crng_ready())) - return 0; - - do { - int ret; - ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ); - if (ret) - return ret > 0 ? 0 : ret; - - try_to_generate_entropy(); - } while (!crng_ready()); - return 0; -} -EXPORT_SYMBOL(wait_for_random_bytes); - -/* - * Returns whether or not the urandom pool has been seeded and thus guaranteed - * to supply cryptographically secure random numbers. This applies to: the - * /dev/urandom device, the get_random_bytes function, and the get_random_{u32, - * ,u64,int,long} family of functions. +/********************************************************************** * - * Returns: true if the urandom pool has been seeded. - * false if the urandom pool has not been seeded. - */ -bool rng_is_initialized(void) -{ - return crng_ready(); -} -EXPORT_SYMBOL(rng_is_initialized); - -/* - * Add a callback function that will be invoked when the nonblocking - * pool is initialised. + * Userspace reader/writer interfaces. * - * returns: 0 if callback is successfully added - * -EALREADY if pool is already initialised (callback not called) - * -ENOENT if module for callback is not alive - */ -int add_random_ready_callback(struct random_ready_callback *rdy) -{ - struct module *owner; - unsigned long flags; - int err = -EALREADY; - - if (crng_ready()) - return err; - - owner = rdy->owner; - if (!try_module_get(owner)) - return -ENOENT; - - spin_lock_irqsave(&random_ready_list_lock, flags); - if (crng_ready()) - goto out; - - owner = NULL; - - list_add(&rdy->list, &random_ready_list); - err = 0; - -out: - spin_unlock_irqrestore(&random_ready_list_lock, flags); - - module_put(owner); - - return err; -} -EXPORT_SYMBOL(add_random_ready_callback); - -/* - * Delete a previously registered readiness callback function. - */ -void del_random_ready_callback(struct random_ready_callback *rdy) -{ - unsigned long flags; - struct module *owner = NULL; - - spin_lock_irqsave(&random_ready_list_lock, flags); - if (!list_empty(&rdy->list)) { - list_del_init(&rdy->list); - owner = rdy->owner; - } - spin_unlock_irqrestore(&random_ready_list_lock, flags); - - module_put(owner); -} -EXPORT_SYMBOL(del_random_ready_callback); - -/* - * This function will use the architecture-specific hardware random - * number generator if it is available. The arch-specific hw RNG will - * almost certainly be faster than what we can do in software, but it - * is impossible to verify that it is implemented securely (as - * opposed, to, say, the AES encryption of a sequence number using a - * key known by the NSA). So it's useful if we need the speed, but - * only if we're willing to trust the hardware manufacturer not to - * have put in a back door. + * getrandom(2) is the primary modern interface into the RNG and should + * be used in preference to anything else. * - * Return number of bytes filled in. - */ -int __must_check get_random_bytes_arch(void *buf, int nbytes) -{ - int left = nbytes; - char *p = buf; - - trace_get_random_bytes_arch(left, _RET_IP_); - while (left) { - unsigned long v; - int chunk = min_t(int, left, sizeof(unsigned long)); - - if (!arch_get_random_long(&v)) - break; - - memcpy(p, &v, chunk); - p += chunk; - left -= chunk; - } - - return nbytes - left; -} -EXPORT_SYMBOL(get_random_bytes_arch); - -/* - * init_std_data - initialize pool with system data + * Reading from /dev/random has the same functionality as calling + * getrandom(2) with flags=0. In earlier versions, however, it had + * vastly different semantics and should therefore be avoided, to + * prevent backwards compatibility issues. * - * @r: pool to initialize + * Reading from /dev/urandom has the same functionality as calling + * getrandom(2) with flags=GRND_INSECURE. Because it does not block + * waiting for the RNG to be ready, it should not be used. * - * This function clears the pool's entropy count and mixes some system - * data into the pool to prepare it for use. The pool is not cleared - * as that can only decrease the entropy in the pool. - */ -static void __init init_std_data(struct entropy_store *r) + * Writing to either /dev/random or /dev/urandom adds entropy to + * the input pool but does not credit it. + * + * Polling on /dev/random indicates when the RNG is initialized, on + * the read side, and when it wants new entropy, on the write side. + * + * Both /dev/random and /dev/urandom have the same set of ioctls for + * adding entropy, getting the entropy count, zeroing the count, and + * reseeding the crng. + * + **********************************************************************/ + +SYSCALL_DEFINE3(getrandom, char __user *, ubuf, size_t, len, unsigned int, flags) { - int i; - ktime_t now = ktime_get_real(); - unsigned long rv; + struct iov_iter iter; + struct iovec iov; + int ret; - r->last_pulled = jiffies; - mix_pool_bytes(r, &now, sizeof(now)); - for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { - if (!arch_get_random_seed_long(&rv) && - !arch_get_random_long(&rv)) - rv = random_get_entropy(); - mix_pool_bytes(r, &rv, sizeof(rv)); - } - mix_pool_bytes(r, utsname(), sizeof(*(utsname()))); -} + if (flags & ~(GRND_NONBLOCK | GRND_RANDOM | GRND_INSECURE)) + return -EINVAL; -/* - * Note that setup_arch() may call add_device_randomness() - * long before we get here. This allows seeding of the pools - * with some platform dependent data very early in the boot - * process. But it limits our options here. We must use - * statically allocated structures that already have all - * initializations complete at compile time. We should also - * take care not to overwrite the precious per platform data - * we were given. - */ -int __init rand_initialize(void) -{ - init_std_data(&input_pool); - init_std_data(&blocking_pool); - crng_initialize(&primary_crng); - crng_global_init_time = jiffies; - if (ratelimit_disable) { - urandom_warning.interval = 0; - unseeded_warning.interval = 0; + /* + * Requesting insecure and blocking randomness at the same time makes + * no sense. + */ + if ((flags & (GRND_INSECURE | GRND_RANDOM)) == (GRND_INSECURE | GRND_RANDOM)) + return -EINVAL; + + if (!crng_ready() && !(flags & GRND_INSECURE)) { + if (flags & GRND_NONBLOCK) + return -EAGAIN; + ret = wait_for_random_bytes(); + if (unlikely(ret)) + return ret; } - return 0; + + ret = import_single_range(READ, ubuf, len, &iov, &iter); + if (unlikely(ret)) + return ret; + return get_random_bytes_user(&iter); } -#ifdef CONFIG_BLOCK -void rand_initialize_disk(struct gendisk *disk) +static __poll_t random_poll(struct file *file, poll_table *wait) { - struct timer_rand_state *state; - - /* - * If kzalloc returns null, we just won't use that entropy - * source. - */ - state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); - if (state) { - state->last_time = INITIAL_JIFFIES; - disk->random = state; - } + poll_wait(file, &crng_init_wait, wait); + return crng_ready() ? EPOLLIN | EPOLLRDNORM : EPOLLOUT | EPOLLWRNORM; } -#endif -static ssize_t -_random_read(int nonblock, char __user *buf, size_t nbytes) +static ssize_t write_pool_user(struct iov_iter *iter) { - ssize_t n; + u8 block[BLAKE2S_BLOCK_SIZE]; + ssize_t ret = 0; + size_t copied; - if (nbytes == 0) + if (unlikely(!iov_iter_count(iter))) return 0; - nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE); - while (1) { - n = extract_entropy_user(&blocking_pool, buf, nbytes); - if (n < 0) - return n; - trace_random_read(n*8, (nbytes-n)*8, - ENTROPY_BITS(&blocking_pool), - ENTROPY_BITS(&input_pool)); - if (n > 0) - return n; - - /* Pool is (near) empty. Maybe wait and retry. */ - if (nonblock) - return -EAGAIN; + for (;;) { + copied = copy_from_iter(block, sizeof(block), iter); + ret += copied; + mix_pool_bytes(block, copied); + if (!iov_iter_count(iter) || copied != sizeof(block)) + break; - wait_event_interruptible(random_read_wait, - blocking_pool.initialized && - (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits)); - if (signal_pending(current)) - return -ERESTARTSYS; + BUILD_BUG_ON(PAGE_SIZE % sizeof(block) != 0); + if (ret % PAGE_SIZE == 0) { + if (signal_pending(current)) + break; + cond_resched(); + } } -} - -static ssize_t -random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) -{ - return _random_read(file->f_flags & O_NONBLOCK, buf, nbytes); -} - -static ssize_t -urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) -{ - unsigned long flags; - static int maxwarn = 10; - int ret; - if (!crng_ready() && maxwarn > 0) { - maxwarn--; - if (__ratelimit(&urandom_warning)) - printk(KERN_NOTICE "random: %s: uninitialized " - "urandom read (%zd bytes read)\n", - current->comm, nbytes); - spin_lock_irqsave(&primary_crng.lock, flags); - crng_init_cnt = 0; - spin_unlock_irqrestore(&primary_crng.lock, flags); - } - nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3)); - ret = extract_crng_user(buf, nbytes); - trace_urandom_read(8 * nbytes, 0, ENTROPY_BITS(&input_pool)); - return ret; + memzero_explicit(block, sizeof(block)); + return ret ? ret : -EFAULT; } -static __poll_t -random_poll(struct file *file, poll_table * wait) +static ssize_t random_write_iter(struct kiocb *kiocb, struct iov_iter *iter) { - __poll_t mask; - - poll_wait(file, &random_read_wait, wait); - poll_wait(file, &random_write_wait, wait); - mask = 0; - if (ENTROPY_BITS(&input_pool) >= random_read_wakeup_bits) - mask |= EPOLLIN | EPOLLRDNORM; - if (ENTROPY_BITS(&input_pool) < random_write_wakeup_bits) - mask |= EPOLLOUT | EPOLLWRNORM; - return mask; + return write_pool_user(iter); } -static int -write_pool(struct entropy_store *r, const char __user *buffer, size_t count) +static ssize_t urandom_read_iter(struct kiocb *kiocb, struct iov_iter *iter) { - size_t bytes; - __u32 t, buf[16]; - const char __user *p = buffer; - - while (count > 0) { - int b, i = 0; - - bytes = min(count, sizeof(buf)); - if (copy_from_user(&buf, p, bytes)) - return -EFAULT; + static int maxwarn = 10; - for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) { - if (!arch_get_random_int(&t)) - break; - buf[i] ^= t; + if (!crng_ready()) { + if (!ratelimit_disable && maxwarn <= 0) + ++urandom_warning.missed; + else if (ratelimit_disable || __ratelimit(&urandom_warning)) { + --maxwarn; + pr_notice("%s: uninitialized urandom read (%zu bytes read)\n", + current->comm, iov_iter_count(iter)); } - - count -= bytes; - p += bytes; - - mix_pool_bytes(r, buf, bytes); - cond_resched(); } - return 0; + return get_random_bytes_user(iter); } -static ssize_t random_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) +static ssize_t random_read_iter(struct kiocb *kiocb, struct iov_iter *iter) { - size_t ret; + int ret; - ret = write_pool(&input_pool, buffer, count); - if (ret) - return ret; + if (!crng_ready() && + ((kiocb->ki_flags & IOCB_NOWAIT) || + (kiocb->ki_filp->f_flags & O_NONBLOCK))) + return -EAGAIN; - return (ssize_t)count; + ret = wait_for_random_bytes(); + if (ret != 0) + return ret; + return get_random_bytes_user(iter); } static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg) { - int size, ent_count; int __user *p = (int __user *)arg; - int retval; + int ent_count; switch (cmd) { case RNDGETENTCNT: - /* inherently racy, no point locking */ - ent_count = ENTROPY_BITS(&input_pool); - if (put_user(ent_count, p)) + /* Inherently racy, no point locking. */ + if (put_user(input_pool.init_bits, p)) return -EFAULT; return 0; case RNDADDTOENTCNT: @@ -2117,39 +1325,48 @@ return -EPERM; if (get_user(ent_count, p)) return -EFAULT; - return credit_entropy_bits_safe(&input_pool, ent_count); - case RNDADDENTROPY: + if (ent_count < 0) + return -EINVAL; + credit_init_bits(ent_count); + return 0; + case RNDADDENTROPY: { + struct iov_iter iter; + struct iovec iov; + ssize_t ret; + int len; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (get_user(ent_count, p++)) return -EFAULT; if (ent_count < 0) return -EINVAL; - if (get_user(size, p++)) + if (get_user(len, p++)) return -EFAULT; - retval = write_pool(&input_pool, (const char __user *)p, - size); - if (retval < 0) - return retval; - return credit_entropy_bits_safe(&input_pool, ent_count); + ret = import_single_range(WRITE, p, len, &iov, &iter); + if (unlikely(ret)) + return ret; + ret = write_pool_user(&iter); + if (unlikely(ret < 0)) + return ret; + /* Since we're crediting, enforce that it was all written into the pool. */ + if (unlikely(ret != len)) + return -EFAULT; + credit_init_bits(ent_count); + return 0; + } case RNDZAPENTCNT: case RNDCLEARPOOL: - /* - * Clear the entropy pool counters. We no longer clear - * the entropy pool, as that's silly. - */ + /* No longer has any effect. */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; - input_pool.entropy_count = 0; - blocking_pool.entropy_count = 0; return 0; case RNDRESEEDCRNG: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if (crng_init < 2) + if (!crng_ready()) return -ENODATA; - crng_reseed(&primary_crng, NULL); - crng_global_init_time = jiffies - 1; + crng_reseed(); return 0; default: return -EINVAL; @@ -2162,49 +1379,56 @@ } const struct file_operations random_fops = { - .read = random_read, - .write = random_write, - .poll = random_poll, + .read_iter = random_read_iter, + .write_iter = random_write_iter, + .poll = random_poll, .unlocked_ioctl = random_ioctl, + .compat_ioctl = compat_ptr_ioctl, .fasync = random_fasync, .llseek = noop_llseek, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, }; const struct file_operations urandom_fops = { - .read = urandom_read, - .write = random_write, + .read_iter = urandom_read_iter, + .write_iter = random_write_iter, .unlocked_ioctl = random_ioctl, + .compat_ioctl = compat_ptr_ioctl, .fasync = random_fasync, .llseek = noop_llseek, + .splice_read = generic_file_splice_read, + .splice_write = iter_file_splice_write, }; -SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, - unsigned int, flags) -{ - int ret; - - if (flags & ~(GRND_NONBLOCK|GRND_RANDOM)) - return -EINVAL; - - if (count > INT_MAX) - count = INT_MAX; - - if (flags & GRND_RANDOM) - return _random_read(flags & GRND_NONBLOCK, buf, count); - - if (!crng_ready()) { - if (flags & GRND_NONBLOCK) - return -EAGAIN; - ret = wait_for_random_bytes(); - if (unlikely(ret)) - return ret; - } - return urandom_read(NULL, buf, count, NULL); -} /******************************************************************** * - * Sysctl interface + * Sysctl interface. + * + * These are partly unused legacy knobs with dummy values to not break + * userspace and partly still useful things. They are usually accessible + * in /proc/sys/kernel/random/ and are as follows: + * + * - boot_id - a UUID representing the current boot. + * + * - uuid - a random UUID, different each time the file is read. + * + * - poolsize - the number of bits of entropy that the input pool can + * hold, tied to the POOL_BITS constant. + * + * - entropy_avail - the number of bits of entropy currently in the + * input pool. Always <= poolsize. + * + * - write_wakeup_threshold - the amount of entropy in the input pool + * below which write polls to /dev/random will unblock, requesting + * more entropy, tied to the POOL_READY_BITS constant. It is writable + * to avoid breaking old userspaces, but writing to it does not + * change any behavior of the RNG. + * + * - urandom_min_reseed_secs - fixed to the value CRNG_RESEED_INTERVAL. + * It is writable to avoid breaking old userspaces, but writing + * to it does not change any behavior of the RNG. * ********************************************************************/ @@ -2212,26 +1436,28 @@ #include -static int min_read_thresh = 8, min_write_thresh; -static int max_read_thresh = OUTPUT_POOL_WORDS * 32; -static int max_write_thresh = INPUT_POOL_WORDS * 32; -static int random_min_urandom_seed = 60; -static char sysctl_bootid[16]; +static int sysctl_random_min_urandom_seed = CRNG_RESEED_INTERVAL / HZ; +static int sysctl_random_write_wakeup_bits = POOL_READY_BITS; +static int sysctl_poolsize = POOL_BITS; +static u8 sysctl_bootid[UUID_SIZE]; /* * This function is used to return both the bootid UUID, and random - * UUID. The difference is in whether table->data is NULL; if it is, + * UUID. The difference is in whether table->data is NULL; if it is, * then a new UUID is generated and returned to the user. - * - * If the user accesses this via the proc interface, the UUID will be - * returned as an ASCII string in the standard UUID format; if via the - * sysctl system call, as 16 bytes of binary data. */ -static int proc_do_uuid(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) +static int proc_do_uuid(struct ctl_table *table, int write, void __user *buf, + size_t *lenp, loff_t *ppos) { - struct ctl_table fake_table; - unsigned char buf[64], tmp_uuid[16], *uuid; + u8 tmp_uuid[UUID_SIZE], *uuid; + char uuid_string[UUID_STRING_LEN + 1]; + struct ctl_table fake_table = { + .data = uuid_string, + .maxlen = UUID_STRING_LEN + }; + + if (write) + return -EPERM; uuid = table->data; if (!uuid) { @@ -2246,32 +1472,17 @@ spin_unlock(&bootid_spinlock); } - sprintf(buf, "%pU", uuid); - - fake_table.data = buf; - fake_table.maxlen = sizeof(buf); - - return proc_dostring(&fake_table, write, buffer, lenp, ppos); + snprintf(uuid_string, sizeof(uuid_string), "%pU", uuid); + return proc_dostring(&fake_table, 0, buf, lenp, ppos); } -/* - * Return entropy available scaled to integral bits - */ -static int proc_do_entropy(struct ctl_table *table, int write, - void __user *buffer, size_t *lenp, loff_t *ppos) +/* The same as proc_dointvec, but writes don't change anything. */ +static int proc_do_rointvec(struct ctl_table *table, int write, void __user *buf, + size_t *lenp, loff_t *ppos) { - struct ctl_table fake_table; - int entropy_count; - - entropy_count = *(int *)table->data >> ENTROPY_SHIFT; - - fake_table.data = &entropy_count; - fake_table.maxlen = sizeof(entropy_count); - - return proc_dointvec(&fake_table, write, buffer, lenp, ppos); + return write ? 0 : proc_dointvec(table, 0, buf, lenp, ppos); } -static int sysctl_poolsize = INPUT_POOL_WORDS * 32; extern struct ctl_table random_table[]; struct ctl_table random_table[] = { { @@ -2283,239 +1494,36 @@ }, { .procname = "entropy_avail", + .data = &input_pool.init_bits, .maxlen = sizeof(int), .mode = 0444, - .proc_handler = proc_do_entropy, - .data = &input_pool.entropy_count, - }, - { - .procname = "read_wakeup_threshold", - .data = &random_read_wakeup_bits, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &min_read_thresh, - .extra2 = &max_read_thresh, + .proc_handler = proc_dointvec, }, { .procname = "write_wakeup_threshold", - .data = &random_write_wakeup_bits, + .data = &sysctl_random_write_wakeup_bits, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = &min_write_thresh, - .extra2 = &max_write_thresh, + .proc_handler = proc_do_rointvec, }, { .procname = "urandom_min_reseed_secs", - .data = &random_min_urandom_seed, + .data = &sysctl_random_min_urandom_seed, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_do_rointvec, }, { .procname = "boot_id", .data = &sysctl_bootid, - .maxlen = 16, .mode = 0444, .proc_handler = proc_do_uuid, }, { .procname = "uuid", - .maxlen = 16, .mode = 0444, .proc_handler = proc_do_uuid, }, -#ifdef ADD_INTERRUPT_BENCH - { - .procname = "add_interrupt_avg_cycles", - .data = &avg_cycles, - .maxlen = sizeof(avg_cycles), - .mode = 0444, - .proc_handler = proc_doulongvec_minmax, - }, - { - .procname = "add_interrupt_avg_deviation", - .data = &avg_deviation, - .maxlen = sizeof(avg_deviation), - .mode = 0444, - .proc_handler = proc_doulongvec_minmax, - }, -#endif { } }; -#endif /* CONFIG_SYSCTL */ - -struct batched_entropy { - union { - u64 entropy_u64[CHACHA_BLOCK_SIZE / sizeof(u64)]; - u32 entropy_u32[CHACHA_BLOCK_SIZE / sizeof(u32)]; - }; - unsigned int position; - spinlock_t batch_lock; -}; - -/* - * Get a random word for internal kernel use only. The quality of the random - * number is either as good as RDRAND or as good as /dev/urandom, with the - * goal of being quite fast and not depleting entropy. In order to ensure - * that the randomness provided by this function is okay, the function - * wait_for_random_bytes() should be called and return 0 at least once - * at any point prior. - */ -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64) = { - .batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u64.lock), -}; - -u64 get_random_u64(void) -{ - u64 ret; - unsigned long flags; - struct batched_entropy *batch; - static void *previous; - -#if BITS_PER_LONG == 64 - if (arch_get_random_long((unsigned long *)&ret)) - return ret; -#else - if (arch_get_random_long((unsigned long *)&ret) && - arch_get_random_long((unsigned long *)&ret + 1)) - return ret; -#endif - - warn_unseeded_randomness(&previous); - - batch = raw_cpu_ptr(&batched_entropy_u64); - spin_lock_irqsave(&batch->batch_lock, flags); - if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) { - extract_crng((u8 *)batch->entropy_u64); - batch->position = 0; - } - ret = batch->entropy_u64[batch->position++]; - spin_unlock_irqrestore(&batch->batch_lock, flags); - return ret; -} -EXPORT_SYMBOL(get_random_u64); - -static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u32) = { - .batch_lock = __SPIN_LOCK_UNLOCKED(batched_entropy_u32.lock), -}; -u32 get_random_u32(void) -{ - u32 ret; - unsigned long flags; - struct batched_entropy *batch; - static void *previous; - - if (arch_get_random_int(&ret)) - return ret; - - warn_unseeded_randomness(&previous); - - batch = raw_cpu_ptr(&batched_entropy_u32); - spin_lock_irqsave(&batch->batch_lock, flags); - if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) { - extract_crng((u8 *)batch->entropy_u32); - batch->position = 0; - } - ret = batch->entropy_u32[batch->position++]; - spin_unlock_irqrestore(&batch->batch_lock, flags); - return ret; -} -EXPORT_SYMBOL(get_random_u32); - -/* It's important to invalidate all potential batched entropy that might - * be stored before the crng is initialized, which we can do lazily by - * simply resetting the counter to zero so that it's re-extracted on the - * next usage. */ -static void invalidate_batched_entropy(void) -{ - int cpu; - unsigned long flags; - - for_each_possible_cpu (cpu) { - struct batched_entropy *batched_entropy; - - batched_entropy = per_cpu_ptr(&batched_entropy_u32, cpu); - spin_lock_irqsave(&batched_entropy->batch_lock, flags); - batched_entropy->position = 0; - spin_unlock(&batched_entropy->batch_lock); - - batched_entropy = per_cpu_ptr(&batched_entropy_u64, cpu); - spin_lock(&batched_entropy->batch_lock); - batched_entropy->position = 0; - spin_unlock_irqrestore(&batched_entropy->batch_lock, flags); - } -} - -/** - * randomize_page - Generate a random, page aligned address - * @start: The smallest acceptable address the caller will take. - * @range: The size of the area, starting at @start, within which the - * random address must fall. - * - * If @start + @range would overflow, @range is capped. - * - * NOTE: Historical use of randomize_range, which this replaces, presumed that - * @start was already page aligned. We now align it regardless. - * - * Return: A page aligned address within [start, start + range). On error, - * @start is returned. - */ -unsigned long -randomize_page(unsigned long start, unsigned long range) -{ - if (!PAGE_ALIGNED(start)) { - range -= PAGE_ALIGN(start) - start; - start = PAGE_ALIGN(start); - } - - if (start > ULONG_MAX - range) - range = ULONG_MAX - start; - - range >>= PAGE_SHIFT; - - if (range == 0) - return start; - - return start + (get_random_long() % range << PAGE_SHIFT); -} - -/* Interface for in-kernel drivers of true hardware RNGs. - * Those devices may produce endless random bits and will be throttled - * when our pool is full. - */ -void add_hwgenerator_randomness(const char *buffer, size_t count, - size_t entropy) -{ - struct entropy_store *poolp = &input_pool; - - if (unlikely(crng_init == 0)) { - crng_fast_load(buffer, count); - return; - } - - /* Suspend writing if we're above the trickle threshold. - * We'll be woken up again once below random_write_wakeup_thresh, - * or when the calling thread is about to terminate. - */ - wait_event_interruptible(random_write_wait, kthread_should_stop() || - ENTROPY_BITS(&input_pool) <= random_write_wakeup_bits); - mix_pool_bytes(poolp, buffer, count); - credit_entropy_bits(poolp, entropy); -} -EXPORT_SYMBOL_GPL(add_hwgenerator_randomness); - -/* Handle random seed passed by bootloader. - * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise - * it would be regarded as device data. - * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER. - */ -void add_bootloader_randomness(const void *buf, unsigned int size) -{ - if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER)) - add_hwgenerator_randomness(buf, size, size * 8); - else - add_device_randomness(buf, size); -} -EXPORT_SYMBOL_GPL(add_bootloader_randomness); +#endif /* CONFIG_SYSCTL */ --- linux-oracle-5.4.0.orig/drivers/char/tlclk.c +++ linux-oracle-5.4.0/drivers/char/tlclk.c @@ -777,17 +777,21 @@ { int ret; + telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); + + alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); + if (!alarm_events) { + ret = -ENOMEM; + goto out1; + } + ret = register_chrdev(tlclk_major, "telco_clock", &tlclk_fops); if (ret < 0) { printk(KERN_ERR "tlclk: can't get major %d.\n", tlclk_major); + kfree(alarm_events); return ret; } tlclk_major = ret; - alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); - if (!alarm_events) { - ret = -ENOMEM; - goto out1; - } /* Read telecom clock IRQ number (Set by BIOS) */ if (!request_region(TLCLK_BASE, 8, "telco_clock")) { @@ -796,7 +800,6 @@ ret = -EBUSY; goto out2; } - telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); if (0x0F == telclk_interrupt ) { /* not MCPBL0010 ? */ printk(KERN_ERR "telclk_interrupt = 0x%x non-mcpbl0010 hw.\n", @@ -837,8 +840,8 @@ release_region(TLCLK_BASE, 8); out2: kfree(alarm_events); -out1: unregister_chrdev(tlclk_major, "telco_clock"); +out1: return ret; } --- linux-oracle-5.4.0.orig/drivers/char/tpm/eventlog/common.c +++ linux-oracle-5.4.0/drivers/char/tpm/eventlog/common.c @@ -47,6 +47,8 @@ if (!err) { seq = file->private_data; seq->private = chip; + } else { + put_device(&chip->dev); } return err; @@ -99,20 +101,20 @@ * * If an event log is found then the securityfs files are setup to * export it to userspace, otherwise nothing is done. - * - * Returns -ENODEV if the firmware has no event log or securityfs is not - * supported. */ -int tpm_bios_log_setup(struct tpm_chip *chip) +void tpm_bios_log_setup(struct tpm_chip *chip) { const char *name = dev_name(&chip->dev); unsigned int cnt; int log_version; int rc = 0; + if (chip->flags & TPM_CHIP_FLAG_VIRTUAL) + return; + rc = tpm_read_log(chip); if (rc < 0) - return rc; + return; log_version = rc; cnt = 0; @@ -158,13 +160,12 @@ cnt++; } - return 0; + return; err: - rc = PTR_ERR(chip->bios_dir[cnt]); chip->bios_dir[cnt] = NULL; tpm_bios_log_teardown(chip); - return rc; + return; } void tpm_bios_log_teardown(struct tpm_chip *chip) --- linux-oracle-5.4.0.orig/drivers/char/tpm/eventlog/efi.c +++ linux-oracle-5.4.0/drivers/char/tpm/eventlog/efi.c @@ -17,6 +17,7 @@ { struct efi_tcg2_final_events_table *final_tbl = NULL; + int final_events_log_size = efi_tpm_final_log_size; struct linux_efi_tpm_eventlog *log_tbl; struct tpm_bios_log *log; u32 log_size; @@ -41,6 +42,11 @@ log_size = log_tbl->size; memunmap(log_tbl); + if (!log_size) { + pr_warn("UEFI TPM log area empty\n"); + return -EIO; + } + log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size, MEMREMAP_WB); if (!log_tbl) { @@ -61,12 +67,12 @@ ret = tpm_log_version; if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || - efi_tpm_final_log_size == 0 || + final_events_log_size == 0 || tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) goto out; final_tbl = memremap(efi.tpm_final_log, - sizeof(*final_tbl) + efi_tpm_final_log_size, + sizeof(*final_tbl) + final_events_log_size, MEMREMAP_WB); if (!final_tbl) { pr_err("Could not map UEFI TPM final log\n"); @@ -75,10 +81,18 @@ goto out; } - efi_tpm_final_log_size -= log_tbl->final_events_preboot_size; + /* + * The 'final events log' size excludes the 'final events preboot log' + * at its beginning. + */ + final_events_log_size -= log_tbl->final_events_preboot_size; + /* + * Allocate memory for the 'combined log' where we will append the + * 'final events log' to. + */ tmp = krealloc(log->bios_event_log, - log_size + efi_tpm_final_log_size, + log_size + final_events_log_size, GFP_KERNEL); if (!tmp) { kfree(log->bios_event_log); @@ -89,15 +103,19 @@ log->bios_event_log = tmp; /* - * Copy any of the final events log that didn't also end up in the - * main log. Events can be logged in both if events are generated + * Append any of the 'final events log' that didn't also end up in the + * 'main log'. Events can be logged in both if events are generated * between GetEventLog() and ExitBootServices(). */ memcpy((void *)log->bios_event_log + log_size, final_tbl->events + log_tbl->final_events_preboot_size, - efi_tpm_final_log_size); + final_events_log_size); + /* + * The size of the 'combined log' is the size of the 'main log' plus + * the size of the 'final events log'. + */ log->bios_event_log_end = log->bios_event_log + - log_size + efi_tpm_final_log_size; + log_size + final_events_log_size; out: memunmap(final_tbl); --- linux-oracle-5.4.0.orig/drivers/char/tpm/eventlog/tpm1.c +++ linux-oracle-5.4.0/drivers/char/tpm/eventlog/tpm1.c @@ -115,6 +115,7 @@ u32 converted_event_size; u32 converted_event_type; + (*pos)++; converted_event_size = do_endian_conversion(event->event_size); v += sizeof(struct tcpa_event) + converted_event_size; @@ -132,7 +133,6 @@ ((v + sizeof(struct tcpa_event) + converted_event_size) > limit)) return NULL; - (*pos)++; return v; } --- linux-oracle-5.4.0.orig/drivers/char/tpm/eventlog/tpm2.c +++ linux-oracle-5.4.0/drivers/char/tpm/eventlog/tpm2.c @@ -94,6 +94,7 @@ size_t event_size; void *marker; + (*pos)++; event_header = log->bios_event_log; if (v == SEQ_START_TOKEN) { @@ -118,7 +119,6 @@ if (((v + event_size) >= limit) || (event_size == 0)) return NULL; - (*pos)++; return v; } --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm-chip.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm-chip.c @@ -274,14 +274,6 @@ kfree(chip); } -static void tpm_devs_release(struct device *dev) -{ - struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs); - - /* release the master device reference */ - put_device(&chip->dev); -} - /** * tpm_class_shutdown() - prepare the TPM device for loss of power. * @dev: device to which the chip is associated. @@ -344,7 +336,6 @@ chip->dev_num = rc; device_initialize(&chip->dev); - device_initialize(&chip->devs); chip->dev.class = tpm_class; chip->dev.class->shutdown_pre = tpm_class_shutdown; @@ -352,47 +343,23 @@ chip->dev.parent = pdev; chip->dev.groups = chip->groups; - chip->devs.parent = pdev; - chip->devs.class = tpmrm_class; - chip->devs.release = tpm_devs_release; - /* get extra reference on main device to hold on - * behalf of devs. This holds the chip structure - * while cdevs is in use. The corresponding put - * is in the tpm_devs_release (TPM2 only) - */ - if (chip->flags & TPM_CHIP_FLAG_TPM2) - get_device(&chip->dev); - if (chip->dev_num == 0) chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); else chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num); - chip->devs.devt = - MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES); - rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num); if (rc) goto out; - rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num); - if (rc) - goto out; if (!pdev) chip->flags |= TPM_CHIP_FLAG_VIRTUAL; cdev_init(&chip->cdev, &tpm_fops); - cdev_init(&chip->cdevs, &tpmrm_fops); chip->cdev.owner = THIS_MODULE; - chip->cdevs.owner = THIS_MODULE; - chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!chip->work_space.context_buf) { - rc = -ENOMEM; - goto out; - } - chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!chip->work_space.session_buf) { + rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE); + if (rc) { rc = -ENOMEM; goto out; } @@ -401,7 +368,6 @@ return chip; out: - put_device(&chip->devs); put_device(&chip->dev); return ERR_PTR(rc); } @@ -450,14 +416,9 @@ } if (chip->flags & TPM_CHIP_FLAG_TPM2) { - rc = cdev_device_add(&chip->cdevs, &chip->devs); - if (rc) { - dev_err(&chip->devs, - "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n", - dev_name(&chip->devs), MAJOR(chip->devs.devt), - MINOR(chip->devs.devt), rc); - return rc; - } + rc = tpm_devs_add(chip); + if (rc) + goto err_del_cdev; } /* Make the chip available. */ @@ -465,6 +426,10 @@ idr_replace(&dev_nums_idr, chip, chip->dev_num); mutex_unlock(&idr_lock); + return 0; + +err_del_cdev: + cdev_device_del(&chip->cdev, &chip->dev); return rc; } @@ -596,9 +561,7 @@ tpm_sysfs_add_device(chip); - rc = tpm_bios_log_setup(chip); - if (rc != 0 && rc != -ENODEV) - return rc; + tpm_bios_log_setup(chip); tpm_add_ppi(chip); @@ -648,7 +611,7 @@ hwrng_unregister(&chip->hwrng); tpm_bios_log_teardown(chip); if (chip->flags & TPM_CHIP_FLAG_TPM2) - cdev_device_del(&chip->cdevs, &chip->devs); + tpm_devs_remove(chip); tpm_del_char_device(chip); } EXPORT_SYMBOL_GPL(tpm_chip_unregister); --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm-dev-common.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm-dev-common.c @@ -48,6 +48,8 @@ if (!ret) ret = tpm2_commit_space(chip, space, buf, &len); + else + tpm2_flush_space(chip); out_rc: return ret ? ret : len; @@ -61,13 +63,26 @@ mutex_lock(&priv->buffer_mutex); priv->command_enqueued = false; + ret = tpm_try_get_ops(priv->chip); + if (ret) { + priv->response_length = ret; + goto out; + } + ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, sizeof(priv->data_buffer)); tpm_put_ops(priv->chip); - if (ret > 0) { + + /* + * If ret is > 0 then tpm_dev_transmit returned the size of the + * response. If ret is < 0 then tpm_dev_transmit failed and + * returned an error code. + */ + if (ret != 0) { priv->response_length = ret; mod_timer(&priv->user_read_timer, jiffies + (120 * HZ)); } +out: mutex_unlock(&priv->buffer_mutex); wake_up_interruptible(&priv->async_wait); } @@ -123,7 +138,7 @@ priv->response_read = true; ret_size = min_t(ssize_t, size, priv->response_length); - if (!ret_size) { + if (ret_size <= 0) { priv->response_length = 0; goto out; } @@ -143,7 +158,7 @@ out: if (!priv->response_length) { *off = 0; - del_singleshot_timer_sync(&priv->user_read_timer); + del_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); } mutex_unlock(&priv->buffer_mutex); @@ -182,15 +197,6 @@ goto out; } - /* atomic tpm command send and result receive. We only hold the ops - * lock during this period so that the tpm can be unregistered even if - * the char dev is held open. - */ - if (tpm_try_get_ops(priv->chip)) { - ret = -EPIPE; - goto out; - } - priv->response_length = 0; priv->response_read = false; *off = 0; @@ -208,6 +214,15 @@ return size; } + /* atomic tpm command send and result receive. We only hold the ops + * lock during this period so that the tpm can be unregistered even if + * the char dev is held open. + */ + if (tpm_try_get_ops(priv->chip)) { + ret = -EPIPE; + goto out; + } + ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer, sizeof(priv->data_buffer)); tpm_put_ops(priv->chip); @@ -250,7 +265,7 @@ void tpm_common_release(struct file *file, struct file_priv *priv) { flush_work(&priv->async_work); - del_singleshot_timer_sync(&priv->user_read_timer); + del_timer_sync(&priv->user_read_timer); flush_work(&priv->timeout_work); file->private_data = NULL; priv->response_length = 0; --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm-dev.h +++ linux-oracle-5.4.0/drivers/char/tpm/tpm-dev.h @@ -14,7 +14,7 @@ struct work_struct timeout_work; struct work_struct async_work; wait_queue_head_t async_wait; - size_t response_length; + ssize_t response_length; bool response_read; bool command_enqueued; --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm-interface.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm-interface.c @@ -322,7 +322,7 @@ for (i = 0; i < chip->nr_allocated_banks; i++) { if (digests[i].alg_id != chip->allocated_banks[i].alg_id) { - rc = EINVAL; + rc = -EINVAL; goto out; } } @@ -396,13 +396,14 @@ if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) return 0; - if (!tpm_chip_start(chip)) { + rc = tpm_try_get_ops(chip); + if (!rc) { if (chip->flags & TPM_CHIP_FLAG_TPM2) tpm2_shutdown(chip, TPM2_SU_STATE); else rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); - tpm_chip_stop(chip); + tpm_put_ops(chip); } return rc; --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm.h +++ linux-oracle-5.4.0/drivers/char/tpm/tpm.h @@ -177,6 +177,9 @@ #define TPM_TAG_RQU_COMMAND 193 +/* TPM2 specific constants. */ +#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */ + struct stclear_flags_t { __be16 tag; u8 deactivated; @@ -456,15 +459,17 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); int tpm2_probe(struct tpm_chip *chip); int tpm2_find_cc(struct tpm_chip *chip, u32 cc); -int tpm2_init_space(struct tpm_space *space); +int tpm2_init_space(struct tpm_space *space, unsigned int buf_size); void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space); void tpm2_flush_space(struct tpm_chip *chip); int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd, size_t cmdsiz); int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf, size_t *bufsiz); +int tpm_devs_add(struct tpm_chip *chip); +void tpm_devs_remove(struct tpm_chip *chip); -int tpm_bios_log_setup(struct tpm_chip *chip); +void tpm_bios_log_setup(struct tpm_chip *chip); void tpm_bios_log_teardown(struct tpm_chip *chip); int tpm_dev_common_init(void); void tpm_dev_common_exit(void); --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm2-cmd.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm2-cmd.c @@ -706,7 +706,16 @@ if (!rc) { out = (struct tpm2_get_cap_out *) &buf.data[TPM_HEADER_SIZE]; - *value = be32_to_cpu(out->value); + /* + * To prevent failing boot up of some systems, Infineon TPM2.0 + * returns SUCCESS on TPM2_Startup in field upgrade mode. Also + * the TPM2_Getcapability command returns a zero length list + * in field upgrade mode. + */ + if (be32_to_cpu(out->property_cnt) > 0) + *value = be32_to_cpu(out->value); + else + rc = -ENODATA; } tpm_buf_destroy(&buf); return rc; @@ -831,6 +840,8 @@ return 0; } + bank->crypto_id = HASH_ALGO__LAST; + return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size); } @@ -939,6 +950,10 @@ chip->cc_attrs_tbl = devm_kcalloc(&chip->dev, 4, nr_commands, GFP_KERNEL); + if (!chip->cc_attrs_tbl) { + rc = -ENOMEM; + goto out; + } rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY); if (rc) @@ -956,6 +971,7 @@ if (nr_commands != be32_to_cpup((__be32 *)&buf.data[TPM_HEADER_SIZE + 5])) { + rc = -EFAULT; tpm_buf_destroy(&buf); goto out; } --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm2-space.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm2-space.c @@ -38,29 +38,32 @@ } } -int tpm2_init_space(struct tpm_space *space) +int tpm2_init_space(struct tpm_space *space, unsigned int buf_size) { - space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + space->context_buf = kzalloc(buf_size, GFP_KERNEL); if (!space->context_buf) return -ENOMEM; - space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + space->session_buf = kzalloc(buf_size, GFP_KERNEL); if (space->session_buf == NULL) { kfree(space->context_buf); + /* Prevent caller getting a dangling pointer. */ + space->context_buf = NULL; return -ENOMEM; } + space->buf_size = buf_size; return 0; } void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space) { - mutex_lock(&chip->tpm_mutex); - if (!tpm_chip_start(chip)) { + + if (tpm_try_get_ops(chip) == 0) { tpm2_flush_sessions(chip, space); - tpm_chip_stop(chip); + tpm_put_ops(chip); } - mutex_unlock(&chip->tpm_mutex); + kfree(space->context_buf); kfree(space->session_buf); } @@ -163,6 +166,9 @@ struct tpm_space *space = &chip->work_space; int i; + if (!space) + return; + for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++) if (space->context_tbl[i] && ~space->context_tbl[i]) tpm2_flush_context(chip, space->context_tbl[i]); @@ -311,8 +317,10 @@ sizeof(space->context_tbl)); memcpy(&chip->work_space.session_tbl, &space->session_tbl, sizeof(space->session_tbl)); - memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE); - memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE); + memcpy(chip->work_space.context_buf, space->context_buf, + space->buf_size); + memcpy(chip->work_space.session_buf, space->session_buf, + space->buf_size); rc = tpm2_load_space(chip); if (rc) { @@ -450,6 +458,9 @@ if (be32_to_cpu(data->capability) != TPM2_CAP_HANDLES) return 0; + if (be32_to_cpu(data->count) > (UINT_MAX - TPM_HEADER_SIZE - 9) / 4) + return -EFAULT; + if (len != TPM_HEADER_SIZE + 9 + 4 * be32_to_cpu(data->count)) return -EFAULT; @@ -492,7 +503,7 @@ continue; rc = tpm2_save_context(chip, space->context_tbl[i], - space->context_buf, PAGE_SIZE, + space->context_buf, space->buf_size, &offset); if (rc == -ENOENT) { space->context_tbl[i] = 0; @@ -509,9 +520,8 @@ continue; rc = tpm2_save_context(chip, space->session_tbl[i], - space->session_buf, PAGE_SIZE, + space->session_buf, space->buf_size, &offset); - if (rc == -ENOENT) { /* handle error saving session, just forget it */ space->session_tbl[i] = 0; @@ -557,11 +567,78 @@ sizeof(space->context_tbl)); memcpy(&space->session_tbl, &chip->work_space.session_tbl, sizeof(space->session_tbl)); - memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE); - memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE); + memcpy(space->context_buf, chip->work_space.context_buf, + space->buf_size); + memcpy(space->session_buf, chip->work_space.session_buf, + space->buf_size); return 0; out: dev_err(&chip->dev, "%s: error %d\n", __func__, rc); return rc; } + +/* + * Put the reference to the main device. + */ +static void tpm_devs_release(struct device *dev) +{ + struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs); + + /* release the master device reference */ + put_device(&chip->dev); +} + +/* + * Remove the device file for exposed TPM spaces and release the device + * reference. This may also release the reference to the master device. + */ +void tpm_devs_remove(struct tpm_chip *chip) +{ + cdev_device_del(&chip->cdevs, &chip->devs); + put_device(&chip->devs); +} + +/* + * Add a device file to expose TPM spaces. Also take a reference to the + * main device. + */ +int tpm_devs_add(struct tpm_chip *chip) +{ + int rc; + + device_initialize(&chip->devs); + chip->devs.parent = chip->dev.parent; + chip->devs.class = tpmrm_class; + + /* + * Get extra reference on main device to hold on behalf of devs. + * This holds the chip structure while cdevs is in use. The + * corresponding put is in the tpm_devs_release. + */ + get_device(&chip->dev); + chip->devs.release = tpm_devs_release; + chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES); + cdev_init(&chip->cdevs, &tpmrm_fops); + chip->cdevs.owner = THIS_MODULE; + + rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num); + if (rc) + goto err_put_devs; + + rc = cdev_device_add(&chip->cdevs, &chip->devs); + if (rc) { + dev_err(&chip->devs, + "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n", + dev_name(&chip->devs), MAJOR(chip->devs.devt), + MINOR(chip->devs.devt), rc); + goto err_put_devs; + } + + return 0; + +err_put_devs: + put_device(&chip->devs); + + return rc; +} --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_crb.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_crb.c @@ -22,6 +22,7 @@ #include "tpm.h" #define ACPI_SIG_TPM2 "TPM2" +#define TPM_CRB_MAX_RESOURCES 3 static const guid_t crb_acpi_start_guid = GUID_INIT(0x6BBF6CAB, 0x5463, 0x4714, @@ -91,7 +92,6 @@ struct crb_priv { u32 sm; const char *hid; - void __iomem *iobase; struct crb_regs_head __iomem *regs_h; struct crb_regs_tail __iomem *regs_t; u8 __iomem *cmd; @@ -252,7 +252,7 @@ iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, TPM2_TIMEOUT_C)) { - dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); + dev_warn(dev, "TPM_LOC_STATE_x.Relinquish timed out\n"); return -ETIME; } @@ -434,21 +434,27 @@ static int crb_check_resource(struct acpi_resource *ares, void *data) { - struct resource *io_res = data; + struct resource *iores_array = data; struct resource_win win; struct resource *res = &(win.res); + int i; if (acpi_dev_resource_memory(ares, res) || acpi_dev_resource_address_space(ares, &win)) { - *io_res = *res; - io_res->name = NULL; + for (i = 0; i < TPM_CRB_MAX_RESOURCES + 1; ++i) { + if (resource_type(iores_array + i) != IORESOURCE_MEM) { + iores_array[i] = *res; + iores_array[i].name = NULL; + break; + } + } } return 1; } -static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv, - struct resource *io_res, u64 start, u32 size) +static void __iomem *crb_map_res(struct device *dev, struct resource *iores, + void __iomem **iobase_ptr, u64 start, u32 size) { struct resource new_res = { .start = start, @@ -460,10 +466,16 @@ if (start != new_res.start) return (void __iomem *) ERR_PTR(-EINVAL); - if (!resource_contains(io_res, &new_res)) + if (!iores) return devm_ioremap_resource(dev, &new_res); - return priv->iobase + (new_res.start - io_res->start); + if (!*iobase_ptr) { + *iobase_ptr = devm_ioremap_resource(dev, iores); + if (IS_ERR(*iobase_ptr)) + return *iobase_ptr; + } + + return *iobase_ptr + (new_res.start - iores->start); } /* @@ -490,9 +502,13 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, struct acpi_table_tpm2 *buf) { - struct list_head resources; - struct resource io_res; + struct list_head acpi_resource_list; + struct resource iores_array[TPM_CRB_MAX_RESOURCES + 1] = { {0} }; + void __iomem *iobase_array[TPM_CRB_MAX_RESOURCES] = {NULL}; struct device *dev = &device->dev; + struct resource *iores; + void __iomem **iobase_ptr; + int i; u32 pa_high, pa_low; u64 cmd_pa; u32 cmd_size; @@ -501,21 +517,41 @@ u32 rsp_size; int ret; - INIT_LIST_HEAD(&resources); - ret = acpi_dev_get_resources(device, &resources, crb_check_resource, - &io_res); + INIT_LIST_HEAD(&acpi_resource_list); + ret = acpi_dev_get_resources(device, &acpi_resource_list, + crb_check_resource, iores_array); if (ret < 0) return ret; - acpi_dev_free_resource_list(&resources); + acpi_dev_free_resource_list(&acpi_resource_list); - if (resource_type(&io_res) != IORESOURCE_MEM) { + if (resource_type(iores_array) != IORESOURCE_MEM) { dev_err(dev, FW_BUG "TPM2 ACPI table does not define a memory resource\n"); return -EINVAL; + } else if (resource_type(iores_array + TPM_CRB_MAX_RESOURCES) == + IORESOURCE_MEM) { + dev_warn(dev, "TPM2 ACPI table defines too many memory resources\n"); + memset(iores_array + TPM_CRB_MAX_RESOURCES, + 0, sizeof(*iores_array)); + iores_array[TPM_CRB_MAX_RESOURCES].flags = 0; + } + + iores = NULL; + iobase_ptr = NULL; + for (i = 0; resource_type(iores_array + i) == IORESOURCE_MEM; ++i) { + if (buf->control_address >= iores_array[i].start && + buf->control_address + sizeof(struct crb_regs_tail) - 1 <= + iores_array[i].end) { + iores = iores_array + i; + iobase_ptr = iobase_array + i; + break; + } } - priv->iobase = devm_ioremap_resource(dev, &io_res); - if (IS_ERR(priv->iobase)) - return PTR_ERR(priv->iobase); + priv->regs_t = crb_map_res(dev, iores, iobase_ptr, buf->control_address, + sizeof(struct crb_regs_tail)); + + if (IS_ERR(priv->regs_t)) + return PTR_ERR(priv->regs_t); /* The ACPI IO region starts at the head area and continues to include * the control area, as one nice sane region except for some older @@ -523,9 +559,10 @@ */ if ((priv->sm == ACPI_TPM2_COMMAND_BUFFER) || (priv->sm == ACPI_TPM2_MEMORY_MAPPED)) { - if (buf->control_address == io_res.start + + if (iores && + buf->control_address == iores->start + sizeof(*priv->regs_h)) - priv->regs_h = priv->iobase; + priv->regs_h = *iobase_ptr; else dev_warn(dev, FW_BUG "Bad ACPI memory layout"); } @@ -534,13 +571,6 @@ if (ret) return ret; - priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, - sizeof(struct crb_regs_tail)); - if (IS_ERR(priv->regs_t)) { - ret = PTR_ERR(priv->regs_t); - goto out_relinquish_locality; - } - /* * PTT HW bug w/a: wake up the device to access * possibly not retained registers. @@ -552,13 +582,26 @@ pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high); pa_low = ioread32(&priv->regs_t->ctrl_cmd_pa_low); cmd_pa = ((u64)pa_high << 32) | pa_low; - cmd_size = crb_fixup_cmd_size(dev, &io_res, cmd_pa, - ioread32(&priv->regs_t->ctrl_cmd_size)); + cmd_size = ioread32(&priv->regs_t->ctrl_cmd_size); + + iores = NULL; + iobase_ptr = NULL; + for (i = 0; iores_array[i].end; ++i) { + if (cmd_pa >= iores_array[i].start && + cmd_pa <= iores_array[i].end) { + iores = iores_array + i; + iobase_ptr = iobase_array + i; + break; + } + } + + if (iores) + cmd_size = crb_fixup_cmd_size(dev, iores, cmd_pa, cmd_size); dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n", pa_high, pa_low, cmd_size); - priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size); + priv->cmd = crb_map_res(dev, iores, iobase_ptr, cmd_pa, cmd_size); if (IS_ERR(priv->cmd)) { ret = PTR_ERR(priv->cmd); goto out; @@ -566,11 +609,25 @@ memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8); rsp_pa = le64_to_cpu(__rsp_pa); - rsp_size = crb_fixup_cmd_size(dev, &io_res, rsp_pa, - ioread32(&priv->regs_t->ctrl_rsp_size)); + rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size); + + iores = NULL; + iobase_ptr = NULL; + for (i = 0; resource_type(iores_array + i) == IORESOURCE_MEM; ++i) { + if (rsp_pa >= iores_array[i].start && + rsp_pa <= iores_array[i].end) { + iores = iores_array + i; + iobase_ptr = iobase_array + i; + break; + } + } + + if (iores) + rsp_size = crb_fixup_cmd_size(dev, iores, rsp_pa, rsp_size); if (cmd_pa != rsp_pa) { - priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size); + priv->rsp = crb_map_res(dev, iores, iobase_ptr, + rsp_pa, rsp_size); ret = PTR_ERR_OR_ZERO(priv->rsp); goto out; } @@ -619,12 +676,16 @@ /* Should the FIFO driver handle this? */ sm = buf->start_method; - if (sm == ACPI_TPM2_MEMORY_MAPPED) - return -ENODEV; + if (sm == ACPI_TPM2_MEMORY_MAPPED) { + rc = -ENODEV; + goto out; + } priv = devm_kzalloc(dev, sizeof(struct crb_priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; + if (!priv) { + rc = -ENOMEM; + goto out; + } if (sm == ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC) { if (buf->header.length < (sizeof(*buf) + sizeof(*crb_smc))) { @@ -632,7 +693,8 @@ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", buf->header.length, ACPI_TPM2_COMMAND_BUFFER_WITH_ARM_SMC); - return -EINVAL; + rc = -EINVAL; + goto out; } crb_smc = ACPI_ADD_PTR(struct tpm2_crb_smc, buf, sizeof(*buf)); priv->smc_func_id = crb_smc->smc_func_id; @@ -643,17 +705,23 @@ rc = crb_map_io(device, priv, buf); if (rc) - return rc; + goto out; chip = tpmm_chip_alloc(dev, &tpm_crb); - if (IS_ERR(chip)) - return PTR_ERR(chip); + if (IS_ERR(chip)) { + rc = PTR_ERR(chip); + goto out; + } dev_set_drvdata(&chip->dev, priv); chip->acpi_dev_handle = device->handle; chip->flags = TPM_CHIP_FLAG_TPM2; - return tpm_chip_register(chip); + rc = tpm_chip_register(chip); + +out: + acpi_put_table((struct acpi_table_header *)buf); + return rc; } static int crb_acpi_remove(struct acpi_device *device) --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_ftpm_tee.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_ftpm_tee.c @@ -32,7 +32,7 @@ 0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96); /** - * ftpm_tee_tpm_op_recv - retrieve fTPM response. + * ftpm_tee_tpm_op_recv() - retrieve fTPM response. * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h. * @buf: the buffer to store data. * @count: the number of bytes to read. @@ -61,7 +61,7 @@ } /** - * ftpm_tee_tpm_op_send - send TPM commands through the TEE shared memory. + * ftpm_tee_tpm_op_send() - send TPM commands through the TEE shared memory. * @chip: the tpm_chip description as specified in driver/char/tpm/tpm.h * @buf: the buffer to send. * @len: the number of bytes to send. @@ -208,7 +208,7 @@ } /** - * ftpm_tee_probe - initialize the fTPM + * ftpm_tee_probe() - initialize the fTPM * @pdev: the platform_device description. * * Return: @@ -255,11 +255,11 @@ pvt_data->session = sess_arg.session; /* Allocate dynamic shared memory with fTPM TA */ - pvt_data->shm = tee_shm_alloc(pvt_data->ctx, - MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE, - TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + pvt_data->shm = tee_shm_alloc_kernel_buf(pvt_data->ctx, + MAX_COMMAND_SIZE + + MAX_RESPONSE_SIZE); if (IS_ERR(pvt_data->shm)) { - dev_err(dev, "%s: tee_shm_alloc failed\n", __func__); + dev_err(dev, "%s: tee_shm_alloc_kernel_buf failed\n", __func__); rc = -ENOMEM; goto out_shm_alloc; } @@ -298,7 +298,7 @@ } /** - * ftpm_tee_remove - remove the TPM device + * ftpm_tee_remove() - remove the TPM device * @pdev: the platform_device description. * * Return: @@ -328,6 +328,19 @@ return 0; } +/** + * ftpm_tee_shutdown() - shutdown the TPM device + * @pdev: the platform_device description. + */ +static void ftpm_tee_shutdown(struct platform_device *pdev) +{ + struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev); + + tee_shm_free(pvt_data->shm); + tee_client_close_session(pvt_data->ctx, pvt_data->session); + tee_client_close_context(pvt_data->ctx); +} + static const struct of_device_id of_ftpm_tee_ids[] = { { .compatible = "microsoft,ftpm" }, { } @@ -341,6 +354,7 @@ }, .probe = ftpm_tee_probe, .remove = ftpm_tee_remove, + .shutdown = ftpm_tee_shutdown, }; module_platform_driver(ftpm_tee_driver); --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_ibmvtpm.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_ibmvtpm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2012 IBM Corporation + * Copyright (C) 2012-2020 IBM Corporation * * Author: Ashley Lai * @@ -134,6 +134,64 @@ } /** + * ibmvtpm_crq_send_init - Send a CRQ initialize message + * @ibmvtpm: vtpm device struct + * + * Return: + * 0 on success. + * Non-zero on failure. + */ +static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) +{ + int rc; + + rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD); + if (rc != H_SUCCESS) + dev_err(ibmvtpm->dev, + "%s failed rc=%d\n", __func__, rc); + + return rc; +} + +/** + * tpm_ibmvtpm_resume - Resume from suspend + * + * @dev: device struct + * + * Return: Always 0. + */ +static int tpm_ibmvtpm_resume(struct device *dev) +{ + struct tpm_chip *chip = dev_get_drvdata(dev); + struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); + int rc = 0; + + do { + if (rc) + msleep(100); + rc = plpar_hcall_norets(H_ENABLE_CRQ, + ibmvtpm->vdev->unit_address); + } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc)); + + if (rc) { + dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc); + return rc; + } + + rc = vio_enable_interrupts(ibmvtpm->vdev); + if (rc) { + dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc); + return rc; + } + + rc = ibmvtpm_crq_send_init(ibmvtpm); + if (rc) + dev_err(dev, "Error send_init rc=%d\n", rc); + + return rc; +} + +/** * tpm_ibmvtpm_send() - Send a TPM command * @chip: tpm chip struct * @buf: buffer contains data to send @@ -146,6 +204,7 @@ static int tpm_ibmvtpm_send(struct tpm_chip *chip, u8 *buf, size_t count) { struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); + bool retry = true; int rc, sig; if (!ibmvtpm->rtce_buf) { @@ -179,18 +238,27 @@ */ ibmvtpm->tpm_processing_cmd = true; +again: rc = ibmvtpm_send_crq(ibmvtpm->vdev, IBMVTPM_VALID_CMD, VTPM_TPM_COMMAND, count, ibmvtpm->rtce_dma_handle); if (rc != H_SUCCESS) { + /* + * H_CLOSED can be returned after LPM resume. Call + * tpm_ibmvtpm_resume() to re-enable the CRQ then retry + * ibmvtpm_send_crq() once before failing. + */ + if (rc == H_CLOSED && retry) { + tpm_ibmvtpm_resume(ibmvtpm->dev); + retry = false; + goto again; + } dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); - rc = 0; ibmvtpm->tpm_processing_cmd = false; - } else - rc = 0; + } spin_unlock(&ibmvtpm->rtce_lock); - return rc; + return 0; } static void tpm_ibmvtpm_cancel(struct tpm_chip *chip) @@ -269,26 +337,6 @@ } /** - * ibmvtpm_crq_send_init - Send a CRQ initialize message - * @ibmvtpm: vtpm device struct - * - * Return: - * 0 on success. - * Non-zero on failure. - */ -static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) -{ - int rc; - - rc = ibmvtpm_send_crq_word(ibmvtpm->vdev, INIT_CRQ_CMD); - if (rc != H_SUCCESS) - dev_err(ibmvtpm->dev, - "ibmvtpm_crq_send_init failed rc=%d\n", rc); - - return rc; -} - -/** * tpm_ibmvtpm_remove - ibm vtpm remove entry point * @vdev: vio device struct * @@ -400,44 +448,6 @@ ibmvtpm->crq_dma_handle, CRQ_RES_BUF_SIZE); } -/** - * tpm_ibmvtpm_resume - Resume from suspend - * - * @dev: device struct - * - * Return: Always 0. - */ -static int tpm_ibmvtpm_resume(struct device *dev) -{ - struct tpm_chip *chip = dev_get_drvdata(dev); - struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); - int rc = 0; - - do { - if (rc) - msleep(100); - rc = plpar_hcall_norets(H_ENABLE_CRQ, - ibmvtpm->vdev->unit_address); - } while (rc == H_IN_PROGRESS || rc == H_BUSY || H_IS_LONG_BUSY(rc)); - - if (rc) { - dev_err(dev, "Error enabling ibmvtpm rc=%d\n", rc); - return rc; - } - - rc = vio_enable_interrupts(ibmvtpm->vdev); - if (rc) { - dev_err(dev, "Error vio_enable_interrupts rc=%d\n", rc); - return rc; - } - - rc = ibmvtpm_crq_send_init(ibmvtpm); - if (rc) - dev_err(dev, "Error send_init rc=%d\n", rc); - - return rc; -} - static bool tpm_ibmvtpm_req_canceled(struct tpm_chip *chip, u8 status) { return (status == 0); @@ -571,6 +581,7 @@ */ while ((crq = ibmvtpm_crq_get_next(ibmvtpm)) != NULL) { ibmvtpm_crq_process(crq, ibmvtpm); + wake_up_interruptible(&ibmvtpm->crq_queue.wq); crq->valid = 0; smp_wmb(); } @@ -618,6 +629,7 @@ } crq_q->num_entry = CRQ_RES_BUF_SIZE / sizeof(*crq_q->crq_addr); + init_waitqueue_head(&crq_q->wq); ibmvtpm->crq_dma_handle = dma_map_single(dev, crq_q->crq_addr, CRQ_RES_BUF_SIZE, DMA_BIDIRECTIONAL); @@ -670,6 +682,14 @@ if (rc) goto init_irq_cleanup; + if (!wait_event_timeout(ibmvtpm->crq_queue.wq, + ibmvtpm->rtce_buf != NULL, + HZ)) { + rc = -ENODEV; + dev_err(dev, "CRQ response timed out\n"); + goto init_irq_cleanup; + } + return tpm_chip_register(chip); init_irq_cleanup: do { --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_ibmvtpm.h +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_ibmvtpm.h @@ -26,6 +26,7 @@ struct ibmvtpm_crq *crq_addr; u32 index; u32 num_entry; + wait_queue_head_t wq; }; struct ibmvtpm_dev { --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_tis.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_tis.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "tpm.h" #include "tpm_tis_core.h" @@ -49,8 +50,8 @@ return container_of(data, struct tpm_tis_tcg_phy, priv); } -static bool interrupts = true; -module_param(interrupts, bool, 0444); +static int interrupts = -1; +module_param(interrupts, int, 0444); MODULE_PARM_DESC(interrupts, "Enable interrupts"); static bool itpm; @@ -63,6 +64,44 @@ MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); #endif +static int tpm_tis_disable_irq(const struct dmi_system_id *d) +{ + if (interrupts == -1) { + pr_notice("tpm_tis: %s detected: disabling interrupts.\n", d->ident); + interrupts = 0; + } + + return 0; +} + +static const struct dmi_system_id tpm_tis_dmi_table[] = { + { + .callback = tpm_tis_disable_irq, + .ident = "ThinkPad T490s", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T490s"), + }, + }, + { + .callback = tpm_tis_disable_irq, + .ident = "ThinkStation P360 Tiny", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkStation P360 Tiny"), + }, + }, + { + .callback = tpm_tis_disable_irq, + .ident = "ThinkPad L490", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L490"), + }, + }, + {} +}; + #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) static int has_hid(struct acpi_device *dev, const char *hid) { @@ -102,6 +141,7 @@ const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev); struct acpi_table_tpm2 *tbl; acpi_status st; + int ret = 0; if (!aid || aid->driver_data != DEVICE_IS_TPM2) return 0; @@ -109,8 +149,7 @@ /* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2 * table is mandatory */ - st = - acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl); + st = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl); if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) { dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n"); return -EINVAL; @@ -118,9 +157,10 @@ /* The tpm2_crb driver handles this device */ if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED) - return -ENODEV; + ret = -ENODEV; - return 0; + acpi_put_table((struct acpi_table_header *)tbl); + return ret; } #else static int check_acpi_tpm2(struct device *dev) @@ -192,6 +232,8 @@ int irq = -1; int rc; + dmi_check_system(tpm_tis_dmi_table); + rc = check_acpi_tpm2(dev); if (rc) return rc; @@ -286,7 +328,7 @@ } tpm_info.res = *res; - tpm_info.irq = platform_get_irq(pdev, 0); + tpm_info.irq = platform_get_irq_optional(pdev, 0); if (tpm_info.irq <= 0) { if (pdev != force_pdev) tpm_info.irq = -1; --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_tis_core.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_tis_core.c @@ -125,7 +125,8 @@ if (rc < 0) return false; - if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == + if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID + | TPM_ACCESS_REQUEST_USE)) == (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) { priv->locality = l; return true; @@ -134,58 +135,13 @@ return false; } -static bool locality_inactive(struct tpm_chip *chip, int l) -{ - struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); - int rc; - u8 access; - - rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access); - if (rc < 0) - return false; - - if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) - == TPM_ACCESS_VALID) - return true; - - return false; -} - static int release_locality(struct tpm_chip *chip, int l) { struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); - unsigned long stop, timeout; - long rc; tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); - stop = jiffies + chip->timeout_a; - - if (chip->flags & TPM_CHIP_FLAG_IRQ) { -again: - timeout = stop - jiffies; - if ((long)timeout <= 0) - return -1; - - rc = wait_event_interruptible_timeout(priv->int_queue, - (locality_inactive(chip, l)), - timeout); - - if (rc > 0) - return 0; - - if (rc == -ERESTARTSYS && freezing(current)) { - clear_thread_flag(TIF_SIGPENDING); - goto again; - } - } else { - do { - if (locality_inactive(chip, l)) - return 0; - tpm_msleep(TPM_TIMEOUT); - } while (time_before(jiffies, stop)); - } - return -1; + return 0; } static int request_locality(struct tpm_chip *chip, int l) @@ -310,6 +266,7 @@ int size = 0; int status; u32 expected; + int rc; if (count < TPM_HEADER_SIZE) { size = -EIO; @@ -329,8 +286,13 @@ goto out; } - size += recv_data(chip, &buf[TPM_HEADER_SIZE], - expected - TPM_HEADER_SIZE); + rc = recv_data(chip, &buf[TPM_HEADER_SIZE], + expected - TPM_HEADER_SIZE); + if (rc < 0) { + size = rc; + goto out; + } + size += rc; if (size < expected) { dev_err(&chip->dev, "Unable to read remainder of result\n"); size = -ETIME; @@ -433,6 +395,9 @@ u32 intmask; int rc; + if (priv->irq == 0) + return; + rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); if (rc < 0) intmask = 0; @@ -456,10 +421,17 @@ int rc; u32 ordinal; unsigned long dur; + unsigned int try; - rc = tpm_tis_send_data(chip, buf, len); - if (rc < 0) - return rc; + for (try = 0; try < TPM_RETRY; try++) { + rc = tpm_tis_send_data(chip, buf, len); + if (rc >= 0) + /* Data transfer done successfully */ + break; + else if (rc != -EIO) + /* Data transfer failed, not recoverable */ + return rc; + } /* go and do it */ rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO); @@ -654,17 +626,23 @@ return IRQ_HANDLED; } -static int tpm_tis_gen_interrupt(struct tpm_chip *chip) +static void tpm_tis_gen_interrupt(struct tpm_chip *chip) { const char *desc = "attempting to generate an interrupt"; u32 cap2; cap_t cap; + int ret; + + ret = request_locality(chip, 0); + if (ret < 0) + return; if (chip->flags & TPM_CHIP_FLAG_TPM2) - return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); + ret = tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); else - return tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, - 0); + ret = tpm1_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc, 0); + + release_locality(chip, 0); } /* Register the IRQ and issue a command that will cause an interrupt. If an @@ -694,42 +672,37 @@ rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); if (rc < 0) - return rc; + goto restore_irqs; rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status); if (rc < 0) - return rc; + goto restore_irqs; /* Clear all existing */ rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status); if (rc < 0) - return rc; - + goto restore_irqs; /* Turn on */ rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask | TPM_GLOBAL_INT_ENABLE); if (rc < 0) - return rc; + goto restore_irqs; priv->irq_tested = false; /* Generate an interrupt by having the core call through to * tpm_tis_send */ - rc = tpm_tis_gen_interrupt(chip); - if (rc < 0) - return rc; + tpm_tis_gen_interrupt(chip); +restore_irqs: /* tpm_tis_send will either confirm the interrupt is working or it * will call disable_irq which undoes all of the above. */ if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { - rc = tpm_tis_write8(priv, original_int_vec, - TPM_INT_VECTOR(priv->locality)); - if (rc < 0) - return rc; - - return 1; + tpm_tis_write8(priv, original_int_vec, + TPM_INT_VECTOR(priv->locality)); + return -1; } return 0; @@ -910,7 +883,15 @@ intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; intmask &= ~TPM_GLOBAL_INT_ENABLE; + + rc = request_locality(chip, 0); + if (rc < 0) { + rc = -ENODEV; + goto out_err; + } + tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); + release_locality(chip, 0); rc = tpm_chip_start(chip); if (rc) @@ -970,28 +951,38 @@ init_waitqueue_head(&priv->read_queue); init_waitqueue_head(&priv->int_queue); if (irq != -1) { - /* Before doing irq testing issue a command to the TPM in polling mode + /* + * Before doing irq testing issue a command to the TPM in polling mode * to make sure it works. May as well use that command to set the * proper timeouts for the driver. */ - if (tpm_get_timeouts(chip)) { + + rc = request_locality(chip, 0); + if (rc < 0) + goto out_err; + + rc = tpm_get_timeouts(chip); + + release_locality(chip, 0); + + if (rc) { dev_err(dev, "Could not get TPM timeouts and durations\n"); rc = -ENODEV; goto out_err; } - tpm_chip_start(chip); - chip->flags |= TPM_CHIP_FLAG_IRQ; if (irq) { tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, irq); - if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) + if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { dev_err(&chip->dev, FW_BUG "TPM interrupt not working, polling instead\n"); + + disable_interrupts(chip); + } } else { tpm_tis_probe_irq(chip, intmask); } - tpm_chip_stop(chip); } rc = tpm_chip_register(chip); @@ -1003,7 +994,7 @@ return 0; out_err: - if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) + if (chip->ops->clk_enable != NULL) chip->ops->clk_enable(chip, false); tpm_tis_remove(chip); @@ -1058,12 +1049,20 @@ if (ret) return ret; - /* TPM 1.2 requires self-test on resume. This function actually returns + /* + * TPM 1.2 requires self-test on resume. This function actually returns * an error code but for unknown reason it isn't handled. */ - if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) + if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { + ret = request_locality(chip, 0); + if (ret < 0) + return ret; + tpm1_do_selftest(chip); + release_locality(chip, 0); + } + return 0; } EXPORT_SYMBOL_GPL(tpm_tis_resume); --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpm_vtpm_proxy.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpm_vtpm_proxy.c @@ -693,37 +693,21 @@ .fops = &vtpmx_fops, }; -static int vtpmx_init(void) -{ - return misc_register(&vtpmx_miscdev); -} - -static void vtpmx_cleanup(void) -{ - misc_deregister(&vtpmx_miscdev); -} - static int __init vtpm_module_init(void) { int rc; - rc = vtpmx_init(); - if (rc) { - pr_err("couldn't create vtpmx device\n"); - return rc; - } - workqueue = create_workqueue("tpm-vtpm"); if (!workqueue) { pr_err("couldn't create workqueue\n"); - rc = -ENOMEM; - goto err_vtpmx_cleanup; + return -ENOMEM; } - return 0; - -err_vtpmx_cleanup: - vtpmx_cleanup(); + rc = misc_register(&vtpmx_miscdev); + if (rc) { + pr_err("couldn't create vtpmx device\n"); + destroy_workqueue(workqueue); + } return rc; } @@ -731,7 +715,7 @@ static void __exit vtpm_module_exit(void) { destroy_workqueue(workqueue); - vtpmx_cleanup(); + misc_deregister(&vtpmx_miscdev); } module_init(vtpm_module_init); --- linux-oracle-5.4.0.orig/drivers/char/tpm/tpmrm-dev.c +++ linux-oracle-5.4.0/drivers/char/tpm/tpmrm-dev.c @@ -21,7 +21,7 @@ if (priv == NULL) return -ENOMEM; - rc = tpm2_init_space(&priv->space); + rc = tpm2_init_space(&priv->space, TPM2_SPACE_BUFFER_SIZE); if (rc) { kfree(priv); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/char/ttyprintk.c +++ linux-oracle-5.4.0/drivers/char/ttyprintk.c @@ -15,10 +15,11 @@ #include #include #include +#include struct ttyprintk_port { struct tty_port port; - struct mutex port_write_mutex; + spinlock_t spinlock; }; static struct ttyprintk_port tpk_port; @@ -99,11 +100,12 @@ static void tpk_close(struct tty_struct *tty, struct file *filp) { struct ttyprintk_port *tpkp = tty->driver_data; + unsigned long flags; - mutex_lock(&tpkp->port_write_mutex); + spin_lock_irqsave(&tpkp->spinlock, flags); /* flush tpk_printk buffer */ tpk_printk(NULL, 0); - mutex_unlock(&tpkp->port_write_mutex); + spin_unlock_irqrestore(&tpkp->spinlock, flags); tty_port_close(&tpkp->port, tty, filp); } @@ -115,13 +117,14 @@ const unsigned char *buf, int count) { struct ttyprintk_port *tpkp = tty->driver_data; + unsigned long flags; int ret; /* exclusive use of tpk_printk within this tty */ - mutex_lock(&tpkp->port_write_mutex); + spin_lock_irqsave(&tpkp->spinlock, flags); ret = tpk_printk(buf, count); - mutex_unlock(&tpkp->port_write_mutex); + spin_unlock_irqrestore(&tpkp->spinlock, flags); return ret; } @@ -155,12 +158,23 @@ return 0; } +/* + * TTY operations hangup function. + */ +static void tpk_hangup(struct tty_struct *tty) +{ + struct ttyprintk_port *tpkp = tty->driver_data; + + tty_port_hangup(&tpkp->port); +} + static const struct tty_operations ttyprintk_ops = { .open = tpk_open, .close = tpk_close, .write = tpk_write, .write_room = tpk_write_room, .ioctl = tpk_ioctl, + .hangup = tpk_hangup, }; static const struct tty_port_operations null_ops = { }; @@ -171,7 +185,7 @@ { int ret = -ENOMEM; - mutex_init(&tpk_port.port_write_mutex); + spin_lock_init(&tpk_port.spinlock); ttyprintk_driver = tty_alloc_driver(1, TTY_DRIVER_RESET_TERMIOS | --- linux-oracle-5.4.0.orig/drivers/char/virtio_console.c +++ linux-oracle-5.4.0/drivers/char/virtio_console.c @@ -435,12 +435,12 @@ /* * Allocate DMA memory from ancestor. When a virtio * device is created by remoteproc, the DMA memory is - * associated with the grandparent device: - * vdev => rproc => platform-dev. + * associated with the parent device: + * virtioY => remoteprocX#vdevYbuffer. */ - if (!vdev->dev.parent || !vdev->dev.parent->parent) + buf->dev = vdev->dev.parent; + if (!buf->dev) goto free_buf; - buf->dev = vdev->dev.parent->parent; /* Increase device refcnt to avoid freeing it */ get_device(buf->dev); @@ -475,7 +475,7 @@ buf = virtqueue_get_buf(port->in_vq, &len); if (buf) { - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; port->stats.bytes_received += len; } @@ -1714,7 +1714,7 @@ while ((buf = virtqueue_get_buf(vq, &len))) { spin_unlock(&portdev->c_ivq_lock); - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; handle_control_message(vq->vdev, portdev, buf); @@ -1961,6 +1961,13 @@ list_del(&portdev->list); spin_unlock_irq(&pdrvdata_lock); + /* Device is going away, exit any polling for buffers */ + virtio_break_device(vdev); + if (use_multiport(portdev)) + flush_work(&portdev->control_work); + else + flush_work(&portdev->config_work); + /* Disable interrupts for vqs */ vdev->config->reset(vdev); /* Finish up work that's lined up */ @@ -2044,25 +2051,27 @@ multiport = true; } - err = init_vqs(portdev); - if (err < 0) { - dev_err(&vdev->dev, "Error %d initializing vqs\n", err); - goto free_chrdev; - } - spin_lock_init(&portdev->ports_lock); INIT_LIST_HEAD(&portdev->ports); INIT_LIST_HEAD(&portdev->list); - virtio_device_ready(portdev->vdev); - INIT_WORK(&portdev->config_work, &config_work_handler); INIT_WORK(&portdev->control_work, &control_work_handler); if (multiport) { spin_lock_init(&portdev->c_ivq_lock); spin_lock_init(&portdev->c_ovq_lock); + } + err = init_vqs(portdev); + if (err < 0) { + dev_err(&vdev->dev, "Error %d initializing vqs\n", err); + goto free_chrdev; + } + + virtio_device_ready(portdev->vdev); + + if (multiport) { err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); if (err < 0) { dev_err(&vdev->dev, @@ -2118,6 +2127,7 @@ { VIRTIO_ID_CONSOLE, VIRTIO_DEV_ANY_ID }, { 0 }, }; +MODULE_DEVICE_TABLE(virtio, id_table); static unsigned int features[] = { VIRTIO_CONSOLE_F_SIZE, @@ -2130,6 +2140,7 @@ #endif { 0 }, }; +MODULE_DEVICE_TABLE(virtio, rproc_serial_id_table); static unsigned int rproc_serial_features[] = { }; @@ -2232,7 +2243,7 @@ .remove = virtcons_remove, }; -static int __init init(void) +static int __init virtio_console_init(void) { int err; @@ -2269,7 +2280,7 @@ return err; } -static void __exit fini(void) +static void __exit virtio_console_fini(void) { reclaim_dma_bufs(); @@ -2279,9 +2290,8 @@ class_destroy(pdrvdata.class); debugfs_remove_recursive(pdrvdata.debugfs_dir); } -module_init(init); -module_exit(fini); +module_init(virtio_console_init); +module_exit(virtio_console_fini); -MODULE_DEVICE_TABLE(virtio, id_table); MODULE_DESCRIPTION("Virtio console driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/clk/Kconfig +++ linux-oracle-5.4.0/drivers/clk/Kconfig @@ -63,7 +63,7 @@ config COMMON_CLK_HI655X tristate "Clock driver for Hi655x" if EXPERT depends on (MFD_HI655X_PMIC || COMPILE_TEST) - depends on REGMAP + select REGMAP default MFD_HI655X_PMIC ---help--- This driver supports the hi655x PMIC clock. This @@ -302,6 +302,7 @@ config COMMON_CLK_FIXED_MMIO bool "Clock driver for Memory Mapped Fixed values" depends on COMMON_CLK && OF + depends on HAS_IOMEM help Support for Memory Mapped IO Fixed clocks --- linux-oracle-5.4.0.orig/drivers/clk/actions/owl-s500.c +++ linux-oracle-5.4.0/drivers/clk/actions/owl-s500.c @@ -125,8 +125,7 @@ { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 }, { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 }, { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 }, - { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 }, - { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 }, + { 24, 1, 25 }, /* bit8: /128 */ { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 }, @@ -135,14 +134,20 @@ { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 }, { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 }, { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 }, - { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 }, - { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 }, + { 280, 1, 25 * 128 }, { 0, 0, 0 }, }; -static struct clk_factor_table bisp_factor_table[] = { - { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, - { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, +static struct clk_factor_table de_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, + { 8, 1, 12 }, + { 0, 0, 0 }, +}; + +static struct clk_factor_table hde_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, { 0, 0, 0 }, }; @@ -156,6 +161,13 @@ { 0, 0 }, }; +static struct clk_div_table std12rate_div_table[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 0, 0 }, +}; + static struct clk_div_table i2s_div_table[] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 }, @@ -183,44 +195,44 @@ static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); /* divider clocks */ -static OWL_DIVIDER(h_clk, "h_clk", "ahbprevdiv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); +static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); /* factor clocks */ static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); -static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0); -static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0); +static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0); +static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0); /* composite clocks */ static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VCECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0), - OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), 0); static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VDECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0), - OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), 0); -static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p, +static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p, OWL_MUX_HW(CMU_BISPCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table), + OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table), 0); -static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table), + 0); -static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table), + 0); static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p, OWL_MUX_HW(CMU_SD0CLK, 9, 1), @@ -300,7 +312,7 @@ static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART0CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, @@ -312,31 +324,31 @@ static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART2CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART3CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART4CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART5CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART6CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p, --- linux-oracle-5.4.0.orig/drivers/clk/actions/owl-s700.c +++ linux-oracle-5.4.0/drivers/clk/actions/owl-s700.c @@ -162,6 +162,7 @@ static struct clk_div_table rmii_div_table[] = { {0, 4}, {1, 10}, + {0, 0} }; /* divider clocks */ --- linux-oracle-5.4.0.orig/drivers/clk/actions/owl-s900.c +++ linux-oracle-5.4.0/drivers/clk/actions/owl-s900.c @@ -140,7 +140,7 @@ static struct clk_div_table usb3_mac_div_table[] = { { 1, 2 }, { 2, 3 }, { 3, 4 }, - { 0, 8 }, + { 0, 0 } }; static struct clk_div_table i2s_div_table[] = { --- linux-oracle-5.4.0.orig/drivers/clk/analogbits/wrpll-cln28hpc.c +++ linux-oracle-5.4.0/drivers/clk/analogbits/wrpll-cln28hpc.c @@ -287,7 +287,7 @@ vco = vco_pre * f; } - delta = abs(target_rate - vco); + delta = abs(target_vco_rate - vco); if (delta < best_delta) { best_delta = delta; best_r = r; --- linux-oracle-5.4.0.orig/drivers/clk/at91/at91sam9260.c +++ linux-oracle-5.4.0/drivers/clk/at91/at91sam9260.c @@ -348,7 +348,7 @@ return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; --- linux-oracle-5.4.0.orig/drivers/clk/at91/at91sam9rl.c +++ linux-oracle-5.4.0/drivers/clk/at91/at91sam9rl.c @@ -83,7 +83,7 @@ return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; --- linux-oracle-5.4.0.orig/drivers/clk/at91/at91sam9x5.c +++ linux-oracle-5.4.0/drivers/clk/at91/at91sam9x5.c @@ -146,7 +146,7 @@ return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; --- linux-oracle-5.4.0.orig/drivers/clk/at91/clk-generated.c +++ linux-oracle-5.4.0/drivers/clk/at91/clk-generated.c @@ -18,8 +18,6 @@ #define GENERATED_MAX_DIV 255 -#define GCK_INDEX_DT_AUDIO_PLL 5 - struct clk_generated { struct clk_hw hw; struct regmap *regmap; @@ -29,7 +27,7 @@ u32 gckdiv; const struct clk_pcr_layout *layout; u8 parent_id; - bool audio_pll_allowed; + int chg_pid; }; #define to_clk_generated(hw) \ @@ -107,9 +105,13 @@ tmp_rate = parent_rate; else tmp_rate = parent_rate / div; + + if (tmp_rate < req->min_rate || tmp_rate > req->max_rate) + return; + tmp_diff = abs(req->rate - tmp_rate); - if (*best_diff < 0 || *best_diff > tmp_diff) { + if (*best_diff < 0 || *best_diff >= tmp_diff) { *best_rate = tmp_rate; *best_diff = tmp_diff; req->best_parent_rate = parent_rate; @@ -129,7 +131,16 @@ int i; u32 div; - for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { + /* do not look for a rate that is outside of our range */ + if (gck->range.max && req->rate > gck->range.max) + req->rate = gck->range.max; + if (gck->range.min && req->rate < gck->range.min) + req->rate = gck->range.min; + + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { + if (gck->chg_pid == i) + continue; + parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -161,10 +172,10 @@ * that the only clks able to modify gck rate are those of audio IPs. */ - if (!gck->audio_pll_allowed) + if (gck->chg_pid < 0) goto end; - parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); + parent = clk_hw_get_parent_by_index(hw, gck->chg_pid); if (!parent) goto end; @@ -271,8 +282,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const struct clk_pcr_layout *layout, const char *name, const char **parent_names, - u8 num_parents, u8 id, bool pll_audio, - const struct clk_range *range) + u8 num_parents, u8 id, + const struct clk_range *range, int chg_pid) { struct clk_generated *gck; struct clk_init_data init; @@ -287,15 +298,16 @@ init.ops = &generated_ops; init.parent_names = parent_names; init.num_parents = num_parents; - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | - CLK_SET_RATE_PARENT; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + if (chg_pid >= 0) + init.flags |= CLK_SET_RATE_PARENT; gck->id = id; gck->hw.init = &init; gck->regmap = regmap; gck->lock = lock; gck->range = *range; - gck->audio_pll_allowed = pll_audio; + gck->chg_pid = chg_pid; gck->layout = layout; clk_generated_startup(gck); --- linux-oracle-5.4.0.orig/drivers/clk/at91/clk-main.c +++ linux-oracle-5.4.0/drivers/clk/at91/clk-main.c @@ -437,12 +437,17 @@ return -EINVAL; regmap_read(regmap, AT91_CKGR_MOR, &tmp); - tmp &= ~MOR_KEY_MASK; if (index && !(tmp & AT91_PMC_MOSCSEL)) - regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); + tmp = AT91_PMC_MOSCSEL; else if (!index && (tmp & AT91_PMC_MOSCSEL)) - regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); + tmp = 0; + else + return 0; + + regmap_update_bits(regmap, AT91_CKGR_MOR, + AT91_PMC_MOSCSEL | MOR_KEY_MASK, + tmp | AT91_PMC_KEY); while (!clk_sam9x5_main_ready(regmap)) cpu_relax(); --- linux-oracle-5.4.0.orig/drivers/clk/at91/clk-usb.c +++ linux-oracle-5.4.0/drivers/clk/at91/clk-usb.c @@ -75,6 +75,9 @@ tmp_parent_rate = req->rate * div; tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate); + if (!tmp_parent_rate) + continue; + tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div); if (tmp_rate < req->rate) tmp_diff = req->rate - tmp_rate; @@ -211,7 +214,7 @@ usb->hw.init = &init; usb->regmap = regmap; - usb->usbs_mask = SAM9X5_USBS_MASK; + usb->usbs_mask = usbs_mask; hw = &usb->hw; ret = clk_hw_register(NULL, &usb->hw); --- linux-oracle-5.4.0.orig/drivers/clk/at91/dt-compat.c +++ linux-oracle-5.4.0/drivers/clk/at91/dt-compat.c @@ -22,6 +22,8 @@ #define SYSTEM_MAX_ID 31 +#define GCK_INDEX_DT_AUDIO_PLL 5 + #ifdef CONFIG_HAVE_AT91_AUDIO_PLL static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) { @@ -135,7 +137,7 @@ return; for_each_child_of_node(np, gcknp) { - bool pll_audio = false; + int chg_pid = INT_MIN; if (of_property_read_u32(gcknp, "reg", &id)) continue; @@ -152,12 +154,12 @@ if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") && (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 || id == GCK_ID_CLASSD)) - pll_audio = true; + chg_pid = GCK_INDEX_DT_AUDIO_PLL; hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, &dt_pcr_layout, name, parent_names, num_parents, - id, pll_audio, &range); + id, &range, chg_pid); if (IS_ERR(hw)) continue; --- linux-oracle-5.4.0.orig/drivers/clk/at91/pmc.c +++ linux-oracle-5.4.0/drivers/clk/at91/pmc.c @@ -275,7 +275,12 @@ np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); - pmcreg = syscon_node_to_regmap(np); + if (!of_device_is_available(np)) { + of_node_put(np); + return -ENODEV; + } + + pmcreg = device_node_to_regmap(np); if (IS_ERR(pmcreg)) return PTR_ERR(pmcreg); --- linux-oracle-5.4.0.orig/drivers/clk/at91/pmc.h +++ linux-oracle-5.4.0/drivers/clk/at91/pmc.h @@ -118,8 +118,8 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const struct clk_pcr_layout *layout, const char *name, const char **parent_names, - u8 num_parents, u8 id, bool pll_audio, - const struct clk_range *range); + u8 num_parents, u8 id, + const struct clk_range *range, int chg_pid); struct clk_hw * __init at91_clk_register_h32mx(struct regmap *regmap, const char *name, --- linux-oracle-5.4.0.orig/drivers/clk/at91/sam9x60.c +++ linux-oracle-5.4.0/drivers/clk/at91/sam9x60.c @@ -47,6 +47,7 @@ .pres_shift = 8, .css_mask = 0x1f, .have_slck_mck = 0, + .is_pres_direct = 1, }; static const struct clk_pcr_layout sam9x60_pcr_layout = { @@ -123,7 +124,6 @@ char *n; u8 id; struct clk_range r; - bool pll; } sam9x60_gck[] = { { .n = "flex0_gclk", .id = 5, }, { .n = "flex1_gclk", .id = 6, }, @@ -143,11 +143,9 @@ { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, }, { .n = "flex11_gclk", .id = 32, }, { .n = "flex12_gclk", .id = 33, }, - { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, - .pll = true, }, + { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, }, { .n = "pit64b_gclk", .id = 37, }, - { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, - .pll = true, }, + { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, }, { .n = "tcb1_gclk", .id = 45, }, { .n = "dbgu_gclk", .id = 47, }, }; @@ -161,7 +159,6 @@ struct regmap *regmap; struct clk_hw *hw; int i; - bool bypass; i = of_property_match_string(np, "clock-names", "td_slck"); if (i < 0) @@ -196,10 +193,7 @@ if (IS_ERR(hw)) goto err_free; - bypass = of_property_read_bool(np, "atmel,osc-bypass"); - - hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, - bypass); + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, 0); if (IS_ERR(hw)) goto err_free; @@ -236,9 +230,8 @@ parent_names[0] = "pllack"; parent_names[1] = "upllck"; - parent_names[2] = "mainck"; - parent_names[3] = "mainck"; - hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4); + parent_names[2] = "main_osc"; + hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3); if (IS_ERR(hw)) goto err_free; @@ -289,8 +282,7 @@ sam9x60_gck[i].n, parent_names, 6, sam9x60_gck[i].id, - sam9x60_gck[i].pll, - &sam9x60_gck[i].r); + &sam9x60_gck[i].r, INT_MIN); if (IS_ERR(hw)) goto err_free; --- linux-oracle-5.4.0.orig/drivers/clk/at91/sama5d2.c +++ linux-oracle-5.4.0/drivers/clk/at91/sama5d2.c @@ -115,21 +115,20 @@ char *n; u8 id; struct clk_range r; - bool pll; + int chg_pid; } sama5d2_gck[] = { - { .n = "sdmmc0_gclk", .id = 31, }, - { .n = "sdmmc1_gclk", .id = 32, }, - { .n = "tcb0_gclk", .id = 35, .r = { .min = 0, .max = 83000000 }, }, - { .n = "tcb1_gclk", .id = 36, .r = { .min = 0, .max = 83000000 }, }, - { .n = "pwm_gclk", .id = 38, .r = { .min = 0, .max = 83000000 }, }, - { .n = "isc_gclk", .id = 46, }, - { .n = "pdmic_gclk", .id = 48, }, - { .n = "i2s0_gclk", .id = 54, .pll = true }, - { .n = "i2s1_gclk", .id = 55, .pll = true }, - { .n = "can0_gclk", .id = 56, .r = { .min = 0, .max = 80000000 }, }, - { .n = "can1_gclk", .id = 57, .r = { .min = 0, .max = 80000000 }, }, - { .n = "classd_gclk", .id = 59, .r = { .min = 0, .max = 100000000 }, - .pll = true }, + { .n = "sdmmc0_gclk", .id = 31, .chg_pid = INT_MIN, }, + { .n = "sdmmc1_gclk", .id = 32, .chg_pid = INT_MIN, }, + { .n = "tcb0_gclk", .id = 35, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, + { .n = "tcb1_gclk", .id = 36, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, + { .n = "pwm_gclk", .id = 38, .chg_pid = INT_MIN, .r = { .min = 0, .max = 83000000 }, }, + { .n = "isc_gclk", .id = 46, .chg_pid = INT_MIN, }, + { .n = "pdmic_gclk", .id = 48, .chg_pid = INT_MIN, }, + { .n = "i2s0_gclk", .id = 54, .chg_pid = 5, }, + { .n = "i2s1_gclk", .id = 55, .chg_pid = 5, }, + { .n = "can0_gclk", .id = 56, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, }, + { .n = "can1_gclk", .id = 57, .chg_pid = INT_MIN, .r = { .min = 0, .max = 80000000 }, }, + { .n = "classd_gclk", .id = 59, .chg_pid = 5, .r = { .min = 0, .max = 100000000 }, }, }; static const struct clk_programmable_layout sama5d2_programmable_layout = { @@ -162,7 +161,7 @@ return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; @@ -317,8 +316,8 @@ sama5d2_gck[i].n, parent_names, 6, sama5d2_gck[i].id, - sama5d2_gck[i].pll, - &sama5d2_gck[i].r); + &sama5d2_gck[i].r, + sama5d2_gck[i].chg_pid); if (IS_ERR(hw)) goto err_free; --- linux-oracle-5.4.0.orig/drivers/clk/at91/sama5d4.c +++ linux-oracle-5.4.0/drivers/clk/at91/sama5d4.c @@ -136,7 +136,7 @@ return; mainxtal_name = of_clk_get_parent_name(np, i); - regmap = syscon_node_to_regmap(np); + regmap = device_node_to_regmap(np); if (IS_ERR(regmap)) return; --- linux-oracle-5.4.0.orig/drivers/clk/bcm/clk-bcm2835.c +++ linux-oracle-5.4.0/drivers/clk/bcm/clk-bcm2835.c @@ -314,6 +314,7 @@ struct device *dev; void __iomem *regs; spinlock_t regs_lock; /* spinlock for all clocks */ + unsigned int soc; /* * Real names of cprman clock parents looked up through @@ -525,6 +526,20 @@ A2W_PLL_CTRL_PRST_DISABLE; } +static u32 bcm2835_pll_get_prediv_mask(struct bcm2835_cprman *cprman, + const struct bcm2835_pll_data *data) +{ + /* + * On BCM2711 there isn't a pre-divisor available in the PLL feedback + * loop. Bits 13:14 of ANA1 (PLLA,PLLB,PLLC,PLLD) have been re-purposed + * for to for VCO RANGE bits. + */ + if (cprman->soc & SOC_BCM2711) + return 0; + + return data->ana->fb_prediv_mask; +} + static void bcm2835_pll_choose_ndiv_and_fdiv(unsigned long rate, unsigned long parent_rate, u32 *ndiv, u32 *fdiv) @@ -582,7 +597,7 @@ ndiv = (a2wctrl & A2W_PLL_CTRL_NDIV_MASK) >> A2W_PLL_CTRL_NDIV_SHIFT; pdiv = (a2wctrl & A2W_PLL_CTRL_PDIV_MASK) >> A2W_PLL_CTRL_PDIV_SHIFT; using_prediv = cprman_read(cprman, data->ana_reg_base + 4) & - data->ana->fb_prediv_mask; + bcm2835_pll_get_prediv_mask(cprman, data); if (using_prediv) { ndiv *= 2; @@ -665,6 +680,7 @@ struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); struct bcm2835_cprman *cprman = pll->cprman; const struct bcm2835_pll_data *data = pll->data; + u32 prediv_mask = bcm2835_pll_get_prediv_mask(cprman, data); bool was_using_prediv, use_fb_prediv, do_ana_setup_first; u32 ndiv, fdiv, a2w_ctl; u32 ana[4]; @@ -682,7 +698,7 @@ for (i = 3; i >= 0; i--) ana[i] = cprman_read(cprman, data->ana_reg_base + i * 4); - was_using_prediv = ana[1] & data->ana->fb_prediv_mask; + was_using_prediv = ana[1] & prediv_mask; ana[0] &= ~data->ana->mask0; ana[0] |= data->ana->set0; @@ -692,10 +708,10 @@ ana[3] |= data->ana->set3; if (was_using_prediv && !use_fb_prediv) { - ana[1] &= ~data->ana->fb_prediv_mask; + ana[1] &= ~prediv_mask; do_ana_setup_first = true; } else if (!was_using_prediv && use_fb_prediv) { - ana[1] |= data->ana->fb_prediv_mask; + ana[1] |= prediv_mask; do_ana_setup_first = false; } else { do_ana_setup_first = true; @@ -916,8 +932,7 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate, - bool round_up) + unsigned long parent_rate) { struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); const struct bcm2835_clock_data *data = clock->data; @@ -929,10 +944,6 @@ rem = do_div(temp, rate); div = temp; - - /* Round up and mask off the unused bits */ - if (round_up && ((div & unused_frac_mask) != 0 || rem != 0)) - div += unused_frac_mask + 1; div &= ~unused_frac_mask; /* different clamping limits apply for a mash clock */ @@ -956,9 +967,9 @@ return div; } -static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, - unsigned long parent_rate, - u32 div) +static unsigned long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, + unsigned long parent_rate, + u32 div) { const struct bcm2835_clock_data *data = clock->data; u64 temp; @@ -1063,7 +1074,7 @@ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); struct bcm2835_cprman *cprman = clock->cprman; const struct bcm2835_clock_data *data = clock->data; - u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); + u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate); u32 ctl; spin_lock(&cprman->regs_lock); @@ -1114,7 +1125,7 @@ if (!(BIT(parent_idx) & data->set_rate_parent)) { *prate = clk_hw_get_rate(parent); - *div = bcm2835_clock_choose_div(hw, rate, *prate, true); + *div = bcm2835_clock_choose_div(hw, rate, *prate); *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); @@ -1200,7 +1211,7 @@ rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, &div, &prate, &avgrate); - if (rate > best_rate && rate <= req->rate) { + if (abs(req->rate - rate) < abs(req->rate - best_rate)) { best_parent = parent; best_prate = prate; best_rate = rate; @@ -1320,8 +1331,10 @@ pll->hw.init = &init; ret = devm_clk_hw_register(cprman->dev, &pll->hw); - if (ret) + if (ret) { + kfree(pll); return NULL; + } return &pll->hw; } @@ -1448,13 +1461,13 @@ return &clock->hw; } -static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman, +static struct clk_hw *bcm2835_register_gate(struct bcm2835_cprman *cprman, const struct bcm2835_gate_data *data) { - return clk_register_gate(cprman->dev, data->name, data->parent, - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, - cprman->regs + data->ctl_reg, - CM_GATE_BIT, 0, &cprman->regs_lock); + return clk_hw_register_gate(cprman->dev, data->name, data->parent, + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, + cprman->regs + data->ctl_reg, + CM_GATE_BIT, 0, &cprman->regs_lock); } typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, @@ -1743,7 +1756,7 @@ .load_mask = CM_PLLC_LOADPER, .hold_mask = CM_PLLC_HOLDPER, .fixed_divider = 1, - .flags = CLK_SET_RATE_PARENT), + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT), /* * PLLD is the display PLL, used to drive DSI display panels. @@ -2234,6 +2247,7 @@ platform_set_drvdata(pdev, cprman); cprman->onecell.num = asize; + cprman->soc = pdata->soc; hws = cprman->onecell.hws; for (i = 0; i < asize; i++) { --- linux-oracle-5.4.0.orig/drivers/clk/bcm/clk-bcm53573-ilp.c +++ linux-oracle-5.4.0/drivers/clk/bcm/clk-bcm53573-ilp.c @@ -112,7 +112,7 @@ goto err_free_ilp; } - ilp->regmap = syscon_node_to_regmap(of_get_parent(np)); + ilp->regmap = syscon_node_to_regmap(np->parent); if (IS_ERR(ilp->regmap)) { err = PTR_ERR(ilp->regmap); goto err_free_ilp; --- linux-oracle-5.4.0.orig/drivers/clk/bcm/clk-bcm63xx-gate.c +++ linux-oracle-5.4.0/drivers/clk/bcm/clk-bcm63xx-gate.c @@ -155,6 +155,7 @@ for (entry = table; entry->name; entry++) maxbit = max_t(u8, maxbit, entry->bit); + maxbit++; hw = devm_kzalloc(&pdev->dev, struct_size(hw, data.hws, maxbit), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/clk/bcm/clk-iproc-pll.c +++ linux-oracle-5.4.0/drivers/clk/bcm/clk-iproc-pll.c @@ -736,6 +736,7 @@ const char *parent_name; struct iproc_clk *iclk_array; struct clk_hw_onecell_data *clk_data; + const char *clk_name; if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl)) return; @@ -783,7 +784,12 @@ iclk = &iclk_array[0]; iclk->pll = pll; - init.name = node->name; + ret = of_property_read_string_index(node, "clock-output-names", + 0, &clk_name); + if (WARN_ON(ret)) + goto err_pll_register; + + init.name = clk_name; init.ops = &iproc_pll_ops; init.flags = 0; parent_name = of_clk_get_parent_name(node, 0); @@ -803,13 +809,11 @@ goto err_pll_register; clk_data->hws[0] = &iclk->hw; + parent_name = clk_name; /* now initialize and register all leaf clocks */ for (i = 1; i < num_clks; i++) { - const char *clk_name; - memset(&init, 0, sizeof(init)); - parent_name = node->name; ret = of_property_read_string_index(node, "clock-output-names", i, &clk_name); --- linux-oracle-5.4.0.orig/drivers/clk/bcm/clk-raspberrypi.c +++ linux-oracle-5.4.0/drivers/clk/bcm/clk-raspberrypi.c @@ -113,7 +113,7 @@ RPI_FIRMWARE_ARM_CLK_ID, &val); if (ret) - return ret; + return 0; return val * RPI_FIRMWARE_PLLB_ARM_DIV_RATE; } --- linux-oracle-5.4.0.orig/drivers/clk/berlin/bg2.c +++ linux-oracle-5.4.0/drivers/clk/berlin/bg2.c @@ -500,12 +500,15 @@ int n, ret; clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); - if (!clk_data) + if (!clk_data) { + of_node_put(parent_np); return; + } clk_data->num = MAX_CLKS; hws = clk_data->hws; gbase = of_iomap(parent_np, 0); + of_node_put(parent_np); if (!gbase) return; --- linux-oracle-5.4.0.orig/drivers/clk/berlin/bg2q.c +++ linux-oracle-5.4.0/drivers/clk/berlin/bg2q.c @@ -286,19 +286,23 @@ int n, ret; clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); - if (!clk_data) + if (!clk_data) { + of_node_put(parent_np); return; + } clk_data->num = MAX_CLKS; hws = clk_data->hws; gbase = of_iomap(parent_np, 0); if (!gbase) { + of_node_put(parent_np); pr_err("%pOF: Unable to map global base\n", np); return; } /* BG2Q CPU PLL is not part of global registers */ cpupll_base = of_iomap(parent_np, 1); + of_node_put(parent_np); if (!cpupll_base) { pr_err("%pOF: Unable to map cpupll base\n", np); iounmap(gbase); --- linux-oracle-5.4.0.orig/drivers/clk/clk-ast2600.c +++ linux-oracle-5.4.0/drivers/clk/clk-ast2600.c @@ -17,7 +17,8 @@ #define ASPEED_G6_NUM_CLKS 67 -#define ASPEED_G6_SILICON_REV 0x004 +#define ASPEED_G6_SILICON_REV 0x014 +#define CHIP_REVISION_ID GENMASK(23, 16) #define ASPEED_G6_RESET_CTRL 0x040 #define ASPEED_G6_RESET_CTRL2 0x050 @@ -47,6 +48,8 @@ static struct clk_hw_onecell_data *aspeed_g6_clk_data; static void __iomem *scu_g6_base; +/* AST2600 revision: A0, A1, A2, etc */ +static u8 soc_rev; /* * Clocks marked with CLK_IS_CRITICAL: @@ -57,10 +60,10 @@ static const struct aspeed_gate_data aspeed_g6_gates[] = { /* clk rst name parent flags */ [ASPEED_CLK_GATE_MCLK] = { 0, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */ - [ASPEED_CLK_GATE_ECLK] = { 1, -1, "eclk-gate", "eclk", 0 }, /* Video Engine */ + [ASPEED_CLK_GATE_ECLK] = { 1, 6, "eclk-gate", "eclk", 0 }, /* Video Engine */ [ASPEED_CLK_GATE_GCLK] = { 2, 7, "gclk-gate", NULL, 0 }, /* 2D engine */ /* vclk parent - dclk/d1clk/hclk/mclk */ - [ASPEED_CLK_GATE_VCLK] = { 3, 6, "vclk-gate", NULL, 0 }, /* Video Capture */ + [ASPEED_CLK_GATE_VCLK] = { 3, -1, "vclk-gate", NULL, 0 }, /* Video Capture */ [ASPEED_CLK_GATE_BCLK] = { 4, 8, "bclk-gate", "bclk", 0 }, /* PCIe/PCI */ /* From dpll */ [ASPEED_CLK_GATE_DCLK] = { 5, -1, "dclk-gate", NULL, CLK_IS_CRITICAL }, /* DAC */ @@ -130,6 +133,18 @@ { 0 } }; +static const struct clk_div_table ast2600_emmc_extclk_div_table[] = { + { 0x0, 2 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + static const struct clk_div_table ast2600_mac_div_table[] = { { 0x0, 4 }, { 0x1, 4 }, @@ -178,17 +193,32 @@ { unsigned int mult, div; - if (val & BIT(20)) { - /* Pass through mode */ - mult = div = 1; + if (soc_rev >= 2) { + if (val & BIT(24)) { + /* Pass through mode */ + mult = div = 1; + } else { + /* F = 25Mhz * [(m + 1) / (n + 1)] / (p + 1) */ + u32 m = val & 0x1fff; + u32 n = (val >> 13) & 0x3f; + u32 p = (val >> 19) & 0xf; + + mult = (m + 1); + div = (n + 1) * (p + 1); + } } else { - /* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */ - u32 m = (val >> 5) & 0x3f; - u32 od = (val >> 4) & 0x1; - u32 n = val & 0xf; - - mult = (2 - od) * (m + 2); - div = n + 1; + if (val & BIT(20)) { + /* Pass through mode */ + mult = div = 1; + } else { + /* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */ + u32 m = (val >> 5) & 0x3f; + u32 od = (val >> 4) & 0x1; + u32 n = val & 0xf; + + mult = (2 - od) * (m + 2); + div = n + 1; + } } return clk_hw_register_fixed_factor(NULL, name, "clkin", 0, mult, div); @@ -389,6 +419,11 @@ return hw; } +static const char *const emmc_extclk_parent_names[] = { + "emmc_extclk_hpll_in", + "mpll", +}; + static const char * const vclk_parent_names[] = { "dpll", "d1pll", @@ -458,16 +493,32 @@ return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_UARTX] = hw; - /* EMMC ext clock divider */ - hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "hpll", 0, - scu_g6_base + ASPEED_G6_CLK_SELECTION1, 15, 0, - &aspeed_g6_clk_lock); + /* EMMC ext clock */ + hw = clk_hw_register_fixed_factor(dev, "emmc_extclk_hpll_in", "hpll", + 0, 1, 2); if (IS_ERR(hw)) return PTR_ERR(hw); - hw = clk_hw_register_divider_table(dev, "emmc_extclk", "emmc_extclk_gate", 0, - scu_g6_base + ASPEED_G6_CLK_SELECTION1, 12, 3, 0, - ast2600_div_table, - &aspeed_g6_clk_lock); + + hw = clk_hw_register_mux(dev, "emmc_extclk_mux", + emmc_extclk_parent_names, + ARRAY_SIZE(emmc_extclk_parent_names), 0, + scu_g6_base + ASPEED_G6_CLK_SELECTION1, 11, 1, + 0, &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hw = clk_hw_register_gate(dev, "emmc_extclk_gate", "emmc_extclk_mux", + 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, + 15, 0, &aspeed_g6_clk_lock); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hw = clk_hw_register_divider_table(dev, "emmc_extclk", + "emmc_extclk_gate", 0, + scu_g6_base + + ASPEED_G6_CLK_SELECTION1, 12, + 3, 0, ast2600_emmc_extclk_div_table, + &aspeed_g6_clk_lock); if (IS_ERR(hw)) return PTR_ERR(hw); aspeed_g6_clk_data->hws[ASPEED_CLK_EMMC] = hw; @@ -528,7 +579,7 @@ regmap_write(map, 0x308, 0x12000); /* 3x3 = 9 */ /* P-Bus (BCLK) clock divider */ - hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0, + hw = clk_hw_register_divider_table(dev, "bclk", "epll", 0, scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0, ast2600_div_table, &aspeed_g6_clk_lock); @@ -599,14 +650,22 @@ 2, 2, 3, 5, }; -static const u32 ast2600_a1_axi_ahb_div_table[] = { - 4, 6, 2, 4, +static const u32 ast2600_a1_axi_ahb_div0_tbl[] = { + 3, 2, 3, 4, +}; + +static const u32 ast2600_a1_axi_ahb_div1_tbl[] = { + 3, 4, 6, 8, +}; + +static const u32 ast2600_a1_axi_ahb200_tbl[] = { + 3, 4, 3, 4, 2, 2, 2, 2, }; static void __init aspeed_g6_cc(struct regmap *map) { struct clk_hw *hw; - u32 val, div, chip_id, axi_div, ahb_div; + u32 val, div, divbits, axi_div, ahb_div; clk_hw_register_fixed_rate(NULL, "clkin", NULL, 0, 25000000); @@ -636,11 +695,21 @@ else axi_div = 2; - regmap_read(map, ASPEED_G6_SILICON_REV, &chip_id); - if (chip_id & BIT(16)) - ahb_div = ast2600_a1_axi_ahb_div_table[(val >> 11) & 0x3]; - else + divbits = (val >> 11) & 0x3; + if (soc_rev >= 1) { + if (!divbits) { + ahb_div = ast2600_a1_axi_ahb200_tbl[(val >> 8) & 0x3]; + if (val & BIT(16)) + ahb_div *= 2; + } else { + if (val & BIT(16)) + ahb_div = ast2600_a1_axi_ahb_div1_tbl[divbits]; + else + ahb_div = ast2600_a1_axi_ahb_div0_tbl[divbits]; + } + } else { ahb_div = ast2600_a0_axi_ahb_div_table[(val >> 11) & 0x3]; + } hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, axi_div * ahb_div); aspeed_g6_clk_data->hws[ASPEED_CLK_AHB] = hw; @@ -672,6 +741,8 @@ if (!scu_g6_base) return; + soc_rev = (readl(scu_g6_base + ASPEED_G6_SILICON_REV) & CHIP_REVISION_ID) >> 16; + aspeed_g6_clk_data = kzalloc(struct_size(aspeed_g6_clk_data, hws, ASPEED_G6_NUM_CLKS), GFP_KERNEL); if (!aspeed_g6_clk_data) --- linux-oracle-5.4.0.orig/drivers/clk/clk-axi-clkgen.c +++ linux-oracle-5.4.0/drivers/clk/clk-axi-clkgen.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -412,7 +413,7 @@ struct clk_init_data init; const char *parent_names[2]; const char *clk_name; - struct resource *mem; + struct clk *axi_clk; unsigned int i; int ret; @@ -427,14 +428,29 @@ if (!axi_clkgen) return -ENOMEM; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); + axi_clkgen->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(axi_clkgen->base)) return PTR_ERR(axi_clkgen->base); init.num_parents = of_clk_get_parent_count(pdev->dev.of_node); - if (init.num_parents < 1 || init.num_parents > 2) - return -EINVAL; + + axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (!IS_ERR(axi_clk)) { + if (init.num_parents < 2 || init.num_parents > 3) + return -EINVAL; + + init.num_parents -= 1; + } else { + /* + * Legacy... So that old DTs which do not have clock-names still + * work. In this case we don't explicitly enable the AXI bus + * clock. + */ + if (PTR_ERR(axi_clk) != -ENOENT) + return PTR_ERR(axi_clk); + if (init.num_parents < 1 || init.num_parents > 2) + return -EINVAL; + } for (i = 0; i < init.num_parents; i++) { parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i); --- linux-oracle-5.4.0.orig/drivers/clk/clk-cdce925.c +++ linux-oracle-5.4.0/drivers/clk/clk-cdce925.c @@ -705,6 +705,10 @@ for (i = 0; i < data->chip_info->num_plls; ++i) { pll_clk_name[i] = kasprintf(GFP_KERNEL, "%pOFn.pll%d", client->dev.of_node, i); + if (!pll_clk_name[i]) { + err = -ENOMEM; + goto error; + } init.name = pll_clk_name[i]; data->pll[i].chip = data; data->pll[i].hw.init = &init; @@ -746,6 +750,10 @@ init.num_parents = 1; init.parent_names = &parent_name; /* Mux Y1 to input */ init.name = kasprintf(GFP_KERNEL, "%pOFn.Y1", client->dev.of_node); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[0].chip = data; data->clk[0].hw.init = &init; data->clk[0].index = 0; @@ -764,6 +772,10 @@ for (i = 1; i < data->chip_info->num_outputs; ++i) { init.name = kasprintf(GFP_KERNEL, "%pOFn.Y%d", client->dev.of_node, i+1); + if (!init.name) { + err = -ENOMEM; + goto error; + } data->clk[i].chip = data; data->clk[i].hw.init = &init; data->clk[i].index = i; --- linux-oracle-5.4.0.orig/drivers/clk/clk-clps711x.c +++ linux-oracle-5.4.0/drivers/clk/clk-clps711x.c @@ -28,11 +28,13 @@ { .val = 1, .div = 8, }, { .val = 2, .div = 2, }, { .val = 3, .div = 1, }, + { /* sentinel */ } }; static const struct clk_div_table timer_div_table[] = { { .val = 0, .div = 256, }, { .val = 1, .div = 1, }, + { /* sentinel */ } }; struct clps711x_clk { --- linux-oracle-5.4.0.orig/drivers/clk/clk-conf.c +++ linux-oracle-5.4.0/drivers/clk/clk-conf.c @@ -33,9 +33,12 @@ else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + } pclk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(pclk)) { if (PTR_ERR(pclk) != -EPROBE_DEFER) pr_warn("clk: couldn't get parent clock %d for %pOF\n", @@ -48,10 +51,12 @@ if (rc < 0) goto err; if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); rc = 0; goto err; } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get assigned clock %d for %pOF\n", @@ -93,10 +98,13 @@ else return rc; } - if (clkspec.np == node && !clk_supplier) + if (clkspec.np == node && !clk_supplier) { + of_node_put(clkspec.np); return 0; + } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { if (PTR_ERR(clk) != -EPROBE_DEFER) pr_warn("clk: couldn't get clock %d for %pOF\n", --- linux-oracle-5.4.0.orig/drivers/clk/clk-devres.c +++ linux-oracle-5.4.0/drivers/clk/clk-devres.c @@ -4,42 +4,101 @@ #include #include +struct devm_clk_state { + struct clk *clk; + void (*exit)(struct clk *clk); +}; + static void devm_clk_release(struct device *dev, void *res) { - clk_put(*(struct clk **)res); + struct devm_clk_state *state = res; + + if (state->exit) + state->exit(state->clk); + + clk_put(state->clk); } -struct clk *devm_clk_get(struct device *dev, const char *id) +static struct clk *__devm_clk_get(struct device *dev, const char *id, + struct clk *(*get)(struct device *dev, const char *id), + int (*init)(struct clk *clk), + void (*exit)(struct clk *clk)) { - struct clk **ptr, *clk; + struct devm_clk_state *state; + struct clk *clk; + int ret; - ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) + state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL); + if (!state) return ERR_PTR(-ENOMEM); - clk = clk_get(dev, id); - if (!IS_ERR(clk)) { - *ptr = clk; - devres_add(dev, ptr); - } else { - devres_free(ptr); + clk = get(dev, id); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto err_clk_get; + } + + if (init) { + ret = init(clk); + if (ret) + goto err_clk_init; } + state->clk = clk; + state->exit = exit; + + devres_add(dev, state); + return clk; + +err_clk_init: + + clk_put(clk); +err_clk_get: + + devres_free(state); + return ERR_PTR(ret); +} + +struct clk *devm_clk_get(struct device *dev, const char *id) +{ + return __devm_clk_get(dev, id, clk_get, NULL, NULL); } EXPORT_SYMBOL(devm_clk_get); -struct clk *devm_clk_get_optional(struct device *dev, const char *id) +struct clk *devm_clk_get_prepared(struct device *dev, const char *id) { - struct clk *clk = devm_clk_get(dev, id); + return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare); +} +EXPORT_SYMBOL_GPL(devm_clk_get_prepared); - if (clk == ERR_PTR(-ENOENT)) - return NULL; +struct clk *devm_clk_get_enabled(struct device *dev, const char *id) +{ + return __devm_clk_get(dev, id, clk_get, + clk_prepare_enable, clk_disable_unprepare); +} +EXPORT_SYMBOL_GPL(devm_clk_get_enabled); - return clk; +struct clk *devm_clk_get_optional(struct device *dev, const char *id) +{ + return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL); } EXPORT_SYMBOL(devm_clk_get_optional); +struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id) +{ + return __devm_clk_get(dev, id, clk_get_optional, + clk_prepare, clk_unprepare); +} +EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared); + +struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id) +{ + return __devm_clk_get(dev, id, clk_get_optional, + clk_prepare_enable, clk_disable_unprepare); +} +EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled); + struct clk_bulk_devres { struct clk_bulk_data *clks; int num_clks; @@ -92,13 +151,20 @@ } EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional); +static void devm_clk_bulk_release_all(struct device *dev, void *res) +{ + struct clk_bulk_devres *devres = res; + + clk_bulk_put_all(devres->num_clks, devres->clks); +} + int __must_check devm_clk_bulk_get_all(struct device *dev, struct clk_bulk_data **clks) { struct clk_bulk_devres *devres; int ret; - devres = devres_alloc(devm_clk_bulk_release, + devres = devres_alloc(devm_clk_bulk_release_all, sizeof(*devres), GFP_KERNEL); if (!devres) return -ENOMEM; @@ -139,18 +205,19 @@ struct clk *devm_get_clk_from_child(struct device *dev, struct device_node *np, const char *con_id) { - struct clk **ptr, *clk; + struct devm_clk_state *state; + struct clk *clk; - ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) + state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL); + if (!state) return ERR_PTR(-ENOMEM); clk = of_clk_get_by_name(np, con_id); if (!IS_ERR(clk)) { - *ptr = clk; - devres_add(dev, ptr); + state->clk = clk; + devres_add(dev, state); } else { - devres_free(ptr); + devres_free(state); } return clk; --- linux-oracle-5.4.0.orig/drivers/clk/clk-gate.c +++ linux-oracle-5.4.0/drivers/clk/clk-gate.c @@ -56,7 +56,7 @@ { struct clk_gate *gate = to_clk_gate(hw); int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; - unsigned long uninitialized_var(flags); + unsigned long flags; u32 reg; set ^= enable; --- linux-oracle-5.4.0.orig/drivers/clk/clk-gpio.c +++ linux-oracle-5.4.0/drivers/clk/clk-gpio.c @@ -280,7 +280,7 @@ else clk = clk_register_gpio_gate(&pdev->dev, node->name, parent_names ? parent_names[0] : NULL, gpiod, - 0); + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) return PTR_ERR(clk); --- linux-oracle-5.4.0.orig/drivers/clk/clk-npcm7xx.c +++ linux-oracle-5.4.0/drivers/clk/clk-npcm7xx.c @@ -647,7 +647,7 @@ return; npcm7xx_init_fail: - kfree(npcm7xx_clk_data->hws); + kfree(npcm7xx_clk_data); npcm7xx_init_np_err: iounmap(clk_base); npcm7xx_init_error: --- linux-oracle-5.4.0.orig/drivers/clk/clk-oxnas.c +++ linux-oracle-5.4.0/drivers/clk/clk-oxnas.c @@ -207,7 +207,7 @@ static int oxnas_stdclk_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node, *parent_np; const struct oxnas_stdclk_data *data; const struct of_device_id *id; struct regmap *regmap; @@ -219,7 +219,9 @@ return -ENODEV; data = id->data; - regmap = syscon_node_to_regmap(of_get_parent(np)); + parent_np = of_get_parent(np); + regmap = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); if (IS_ERR(regmap)) { dev_err(&pdev->dev, "failed to have parent regmap\n"); return PTR_ERR(regmap); --- linux-oracle-5.4.0.orig/drivers/clk/clk-s2mps11.c +++ linux-oracle-5.4.0/drivers/clk/clk-s2mps11.c @@ -195,6 +195,7 @@ return ret; err_reg: + of_node_put(s2mps11_clks[0].clk_np); while (--i >= 0) clkdev_drop(s2mps11_clks[i].lookup); --- linux-oracle-5.4.0.orig/drivers/clk/clk-scmi.c +++ linux-oracle-5.4.0/drivers/clk/clk-scmi.c @@ -103,6 +103,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk) { int ret; + unsigned long min_rate, max_rate; + struct clk_init_data init = { .flags = CLK_GET_RATE_NOCACHE, .num_parents = 0, @@ -112,9 +114,23 @@ sclk->hw.init = &init; ret = devm_clk_hw_register(dev, &sclk->hw); - if (!ret) - clk_hw_set_rate_range(&sclk->hw, sclk->info->range.min_rate, - sclk->info->range.max_rate); + if (ret) + return ret; + + if (sclk->info->rate_discrete) { + int num_rates = sclk->info->list.num_rates; + + if (num_rates <= 0) + return -EINVAL; + + min_rate = sclk->info->list.rates[0]; + max_rate = sclk->info->list.rates[num_rates - 1]; + } else { + min_rate = sclk->info->range.min_rate; + max_rate = sclk->info->range.max_rate; + } + + clk_hw_set_rate_range(&sclk->hw, min_rate, max_rate); return ret; } @@ -154,6 +170,7 @@ sclk->info = handle->clk_ops->info_get(handle, idx); if (!sclk->info) { dev_dbg(dev, "invalid clock info for idx %d\n", idx); + devm_kfree(dev, sclk); continue; } --- linux-oracle-5.4.0.orig/drivers/clk/clk-si5341.c +++ linux-oracle-5.4.0/drivers/clk/clk-si5341.c @@ -304,6 +304,8 @@ { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */ { 0x0A02, 0x00 }, /* Not in datasheet */ { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */ + { 0x0B57, 0x10 }, /* VCO_RESET_CALCODE (not described in datasheet) */ + { 0x0B58, 0x05 }, /* VCO_RESET_CALCODE (not described in datasheet) */ }; /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */ @@ -482,6 +484,9 @@ SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den); if (err < 0) return err; + /* Check for bogus/uninitialized settings */ + if (!n_num || !n_den) + return 0; /* * n_num and n_den are shifted left as much as possible, so to prevent @@ -633,6 +638,15 @@ u32 r_divider; u8 r[3]; + err = regmap_read(output->data->regmap, + SI5341_OUT_CONFIG(output), &val); + if (err < 0) + return err; + + /* If SI5341_OUT_CFG_RDIV_FORCE2 is set, r_divider is 2 */ + if (val & SI5341_OUT_CFG_RDIV_FORCE2) + return parent_rate / 2; + err = regmap_bulk_read(output->data->regmap, SI5341_OUT_R_REG(output), r, 3); if (err < 0) @@ -649,13 +663,6 @@ r_divider += 1; r_divider <<= 1; - err = regmap_read(output->data->regmap, - SI5341_OUT_CONFIG(output), &val); - if (err < 0) - return err; - - if (val & SI5341_OUT_CFG_RDIV_FORCE2) - r_divider = 2; return parent_rate / r_divider; } @@ -665,6 +672,9 @@ { unsigned long r; + if (!rate) + return 0; + r = *parent_rate >> 1; /* If rate is an even divisor, no changes to parent required */ @@ -693,11 +703,16 @@ unsigned long parent_rate) { struct clk_si5341_output *output = to_clk_si5341_output(hw); - /* Frequency divider is (r_div + 1) * 2 */ - u32 r_div = (parent_rate / rate) >> 1; + u32 r_div; int err; u8 r[3]; + if (!rate) + return -EINVAL; + + /* Frequency divider is (r_div + 1) * 2 */ + r_div = (parent_rate / rate) >> 1; + if (r_div <= 1) r_div = 0; else if (r_div >= BIT(24)) @@ -717,10 +732,8 @@ r[0] = r_div ? (r_div & 0xff) : 1; r[1] = (r_div >> 8) & 0xff; r[2] = (r_div >> 16) & 0xff; - err = regmap_bulk_write(output->data->regmap, + return regmap_bulk_write(output->data->regmap, SI5341_OUT_R_REG(output), r, 3); - - return 0; } static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) @@ -924,7 +937,7 @@ { 0x0B25, 0x00 }, { 0x0502, 0x01 }, { 0x0505, 0x03 }, - { 0x0957, 0x1F }, + { 0x0957, 0x17 }, { 0x0B4E, 0x1A }, }; @@ -1290,7 +1303,7 @@ clk_prepare(data->clk[i].hw.clk); } - err = of_clk_add_hw_provider(client->dev.of_node, of_clk_si5341_get, + err = devm_of_clk_add_hw_provider(&client->dev, of_clk_si5341_get, data); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); --- linux-oracle-5.4.0.orig/drivers/clk/clk-stm32f4.c +++ linux-oracle-5.4.0/drivers/clk/clk-stm32f4.c @@ -129,7 +129,6 @@ { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { @@ -211,7 +210,6 @@ { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { @@ -286,7 +284,6 @@ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, }; static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { @@ -364,7 +361,6 @@ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" }, }; @@ -526,7 +522,7 @@ struct stm32f4_pll_post_div_data { int idx; - u8 pll_num; + int pll_idx; const char *name; const char *parent; u8 flag; @@ -557,13 +553,13 @@ #define MAX_POST_DIV 3 static const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = { - { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q", + { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL}, - { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q", + { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL }, - { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, + { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table }, }; @@ -1774,7 +1770,7 @@ post_div->width, post_div->flag_div, post_div->div_table, - clks[post_div->pll_num], + clks[post_div->pll_idx], &stm32f4_clk_lock); if (post_div->idx != NO_IDX) --- linux-oracle-5.4.0.orig/drivers/clk/clk.c +++ linux-oracle-5.4.0/drivers/clk/clk.c @@ -37,7 +37,11 @@ static HLIST_HEAD(clk_orphan_list); static LIST_HEAD(clk_notifier_list); -static struct hlist_head *all_lists[] = { +/* List of registered clks that use runtime PM */ +static HLIST_HEAD(clk_rpm_list); +static DEFINE_MUTEX(clk_rpm_list_lock); + +static const struct hlist_head *all_lists[] = { &clk_root_list, &clk_orphan_list, NULL, @@ -59,6 +63,7 @@ struct clk_hw *hw; struct module *owner; struct device *dev; + struct hlist_node rpm_node; struct device_node *of_node; struct clk_core *parent; struct clk_parent_map *parents; @@ -114,7 +119,11 @@ return 0; ret = pm_runtime_get_sync(core->dev); - return ret < 0 ? ret : 0; + if (ret < 0) { + pm_runtime_put_noidle(core->dev); + return ret; + } + return 0; } static void clk_pm_runtime_put(struct clk_core *core) @@ -125,6 +134,89 @@ pm_runtime_put_sync(core->dev); } +/** + * clk_pm_runtime_get_all() - Runtime "get" all clk provider devices + * + * Call clk_pm_runtime_get() on all runtime PM enabled clks in the clk tree so + * that disabling unused clks avoids a deadlock where a device is runtime PM + * resuming/suspending and the runtime PM callback is trying to grab the + * prepare_lock for something like clk_prepare_enable() while + * clk_disable_unused_subtree() holds the prepare_lock and is trying to runtime + * PM resume/suspend the device as well. + * + * Context: Acquires the 'clk_rpm_list_lock' and returns with the lock held on + * success. Otherwise the lock is released on failure. + * + * Return: 0 on success, negative errno otherwise. + */ +static int clk_pm_runtime_get_all(void) +{ + int ret; + struct clk_core *core, *failed; + + /* + * Grab the list lock to prevent any new clks from being registered + * or unregistered until clk_pm_runtime_put_all(). + */ + mutex_lock(&clk_rpm_list_lock); + + /* + * Runtime PM "get" all the devices that are needed for the clks + * currently registered. Do this without holding the prepare_lock, to + * avoid the deadlock. + */ + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) { + ret = clk_pm_runtime_get(core); + if (ret) { + failed = core; + pr_err("clk: Failed to runtime PM get '%s' for clk '%s'\n", + dev_name(failed->dev), failed->name); + goto err; + } + } + + return 0; + +err: + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) { + if (core == failed) + break; + + clk_pm_runtime_put(core); + } + mutex_unlock(&clk_rpm_list_lock); + + return ret; +} + +/** + * clk_pm_runtime_put_all() - Runtime "put" all clk provider devices + * + * Put the runtime PM references taken in clk_pm_runtime_get_all() and release + * the 'clk_rpm_list_lock'. + */ +static void clk_pm_runtime_put_all(void) +{ + struct clk_core *core; + + hlist_for_each_entry(core, &clk_rpm_list, rpm_node) + clk_pm_runtime_put(core); + mutex_unlock(&clk_rpm_list_lock); +} + +static void clk_pm_runtime_init(struct clk_core *core) +{ + struct device *dev = core->dev; + + if (dev && pm_runtime_enabled(dev)) { + core->rpm_enabled = true; + + mutex_lock(&clk_rpm_list_lock); + hlist_add_head(&core->rpm_node, &clk_rpm_list); + mutex_unlock(&clk_rpm_list_lock); + } +} + /*** locking ***/ static void clk_prepare_lock(void) { @@ -247,6 +339,17 @@ } } + /* + * This could be called with the enable lock held, or from atomic + * context. If the parent isn't enabled already, we can't do + * anything here. We can also assume this clock isn't enabled. + */ + if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent) + if (!clk_core_is_enabled(core->parent)) { + ret = false; + goto done; + } + ret = core->ops->is_enabled(core->hw); done: if (core->rpm_enabled) @@ -410,6 +513,9 @@ if (IS_ERR(hw)) return ERR_CAST(hw); + if (!hw) + return NULL; + return hw->core; } @@ -633,6 +739,24 @@ *max_rate = min(*max_rate, clk_user->max_rate); } +static bool clk_core_check_boundaries(struct clk_core *core, + unsigned long min_rate, + unsigned long max_rate) +{ + struct clk *user; + + lockdep_assert_held(&prepare_lock); + + if (min_rate > core->max_rate || max_rate < core->min_rate) + return false; + + hlist_for_each_entry(user, &core->clks, clks_node) + if (min_rate > user->max_rate || max_rate < user->min_rate) + return false; + + return true; +} + void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate, unsigned long max_rate) { @@ -802,6 +926,25 @@ } EXPORT_SYMBOL_GPL(clk_rate_exclusive_get); +static void devm_clk_rate_exclusive_put(void *data) +{ + struct clk *clk = data; + + clk_rate_exclusive_put(clk); +} + +int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk) +{ + int ret; + + ret = clk_rate_exclusive_get(clk); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, devm_clk_rate_exclusive_put, clk); +} +EXPORT_SYMBOL_GPL(devm_clk_rate_exclusive_get); + static void clk_core_unprepare(struct clk_core *core) { lockdep_assert_held(&prepare_lock); @@ -830,10 +973,9 @@ if (core->ops->unprepare) core->ops->unprepare(core->hw); - clk_pm_runtime_put(core); - trace_clk_unprepare_complete(core); clk_core_unprepare(core->parent); + clk_pm_runtime_put(core); } static void clk_core_unprepare_lock(struct clk_core *core) @@ -1202,9 +1344,6 @@ if (core->flags & CLK_IGNORE_UNUSED) return; - if (clk_pm_runtime_get(core)) - return; - if (clk_core_is_prepared(core)) { trace_clk_unprepare(core); if (core->ops->unprepare_unused) @@ -1213,8 +1352,6 @@ core->ops->unprepare(core->hw); trace_clk_unprepare_complete(core); } - - clk_pm_runtime_put(core); } static void clk_disable_unused_subtree(struct clk_core *core) @@ -1230,9 +1367,6 @@ if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_prepare_enable(core->parent); - if (clk_pm_runtime_get(core)) - goto unprepare_out; - flags = clk_enable_lock(); if (core->enable_count) @@ -1257,8 +1391,6 @@ unlock_out: clk_enable_unlock(flags); - clk_pm_runtime_put(core); -unprepare_out: if (core->flags & CLK_OPS_PARENT_ENABLE) clk_core_disable_unprepare(core->parent); } @@ -1274,12 +1406,22 @@ static int clk_disable_unused(void) { struct clk_core *core; + int ret; if (clk_ignore_unused) { pr_warn("clk: Not disabling unused clocks\n"); return 0; } + pr_info("clk: Disabling unused clocks\n"); + + ret = clk_pm_runtime_get_all(); + if (ret) + return ret; + /* + * Grab the prepare lock to keep the clk topology stable while iterating + * over clks. + */ clk_prepare_lock(); hlist_for_each_entry(core, &clk_root_list, child_node) @@ -1296,6 +1438,8 @@ clk_prepare_unlock(); + clk_pm_runtime_put_all(); + return 0; } late_initcall_sync(clk_disable_unused); @@ -2302,6 +2446,11 @@ clk->min_rate = min; clk->max_rate = max; + if (!clk_core_check_boundaries(clk->core, min, max)) { + ret = -EINVAL; + goto out; + } + rate = clk_core_get_rate_nolock(clk->core); if (rate < min || rate > max) { /* @@ -2330,6 +2479,7 @@ } } +out: if (clk->exclusive_count) clk_core_rate_protect(clk->core); @@ -2642,12 +2792,14 @@ { int ret; - clk_prepare_lock(); + lockdep_assert_held(&prepare_lock); + if (!core->ops->get_phase) + return 0; + /* Always try to update cached phase if possible */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - ret = core->phase; - clk_prepare_unlock(); + ret = core->ops->get_phase(core->hw); + if (ret >= 0) + core->phase = ret; return ret; } @@ -2661,10 +2813,16 @@ */ int clk_get_phase(struct clk *clk) { + int ret; + if (!clk) return 0; - return clk_core_get_phase(clk->core); + clk_prepare_lock(); + ret = clk_core_get_phase(clk->core); + clk_prepare_unlock(); + + return ret; } EXPORT_SYMBOL_GPL(clk_get_phase); @@ -2878,13 +3036,21 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level) { - seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", + int phase; + + seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ", level * 3 + 1, "", 30 - level * 3, c->name, c->enable_count, c->prepare_count, c->protect_count, - clk_core_get_rate(c), clk_core_get_accuracy(c), - clk_core_get_phase(c), - clk_core_get_scaled_duty_cycle(c, 100000)); + clk_core_get_rate(c), clk_core_get_accuracy(c)); + + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "%5d", phase); + else + seq_puts(s, "-----"); + + seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000)); } static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, @@ -2921,6 +3087,7 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) { + int phase; unsigned long min_rate, max_rate; clk_core_get_boundaries(c, &min_rate, &max_rate); @@ -2934,7 +3101,9 @@ seq_printf(s, "\"min_rate\": %lu,", min_rate); seq_printf(s, "\"max_rate\": %lu,", max_rate); seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); - seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c)); + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "\"phase\": %d,", phase); seq_printf(s, "\"duty_cycle\": %u", clk_core_get_scaled_duty_cycle(c, 100000)); } @@ -3023,6 +3192,7 @@ unsigned int i, char terminator) { struct clk_core *parent; + const char *name = NULL; /* * Go through the following options to fetch a parent's name. @@ -3037,18 +3207,20 @@ * registered (yet). */ parent = clk_core_get_parent_by_index(core, i); - if (parent) + if (parent) { seq_puts(s, parent->name); - else if (core->parents[i].name) + } else if (core->parents[i].name) { seq_puts(s, core->parents[i].name); - else if (core->parents[i].fw_name) + } else if (core->parents[i].fw_name) { seq_printf(s, "<%s>(fw)", core->parents[i].fw_name); - else if (core->parents[i].index >= 0) - seq_puts(s, - of_clk_get_parent_name(core->of_node, - core->parents[i].index)); - else - seq_puts(s, "(missing)"); + } else { + if (core->parents[i].index >= 0) + name = of_clk_get_parent_name(core->of_node, core->parents[i].index); + if (!name) + name = "(missing)"; + + seq_puts(s, name); + } seq_putc(s, terminator); } @@ -3231,6 +3403,47 @@ } #endif +static void clk_core_reparent_orphans_nolock(void) +{ + struct clk_core *orphan; + struct hlist_node *tmp2; + + /* + * walk the list of orphan clocks and reparent any that newly finds a + * parent. + */ + hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { + struct clk_core *parent = __clk_init_parent(orphan); + + /* + * We need to use __clk_set_parent_before() and _after() to + * to properly migrate any prepare/enable count of the orphan + * clock. This is important for CLK_IS_CRITICAL clocks, which + * are enabled during init but might not have a parent yet. + */ + if (parent) { + /* update the clk tree topology */ + __clk_set_parent_before(orphan, parent); + __clk_set_parent_after(orphan, parent, NULL); + __clk_recalc_accuracies(orphan); + __clk_recalc_rates(orphan, 0); + + /* + * __clk_init_parent() will set the initial req_rate to + * 0 if the clock doesn't have clk_ops::recalc_rate and + * is an orphan when it's registered. + * + * 'req_rate' is used by clk_set_rate_range() and + * clk_put() to trigger a clk_set_rate() call whenever + * the boundaries are modified. Let's make sure + * 'req_rate' is set to something non-zero so that + * clk_set_rate_range() doesn't drop the frequency. + */ + orphan->req_rate = orphan->rate; + } + } +} + /** * __clk_core_init - initialize the data structures in a struct clk_core * @core: clk_core being initialized @@ -3241,8 +3454,6 @@ static int __clk_core_init(struct clk_core *core) { int ret; - struct clk_core *orphan; - struct hlist_node *tmp2; unsigned long rate; if (!core) @@ -3250,6 +3461,14 @@ clk_prepare_lock(); + /* + * Set hw->core after grabbing the prepare_lock to synchronize with + * callers of clk_core_fill_parent_index() where we treat hw->core + * being NULL as the clk not being registered yet. This is crucial so + * that clks aren't parented until their parent is fully registered. + */ + core->hw->core = core; + ret = clk_pm_runtime_get(core); if (ret) goto unlock; @@ -3294,6 +3513,21 @@ goto out; } + /* + * optional platform-specific magic + * + * The .init callback is not used by any of the basic clock types, but + * exists for weird hardware that must perform initialization magic. + * Please consider other ways of solving initialization problems before + * using this callback, as its use is discouraged. + * + * If it exist, this callback should called before any other callback of + * the clock + */ + if (core->ops->init) + core->ops->init(core->hw); + + core->parent = __clk_init_parent(core); /* @@ -3319,17 +3553,6 @@ } /* - * optional platform-specific magic - * - * The .init callback is not used by any of the basic clock types, but - * exists for weird hardware that must perform initialization magic. - * Please consider other ways of solving initialization problems before - * using this callback, as its use is discouraged. - */ - if (core->ops->init) - core->ops->init(core->hw); - - /* * Set clk's accuracy. The preferred method is to use * .recalc_accuracy. For simple clocks and lazy developers the default * fallback is to use the parent's accuracy. If a clock doesn't have a @@ -3345,14 +3568,11 @@ core->accuracy = 0; /* - * Set clk's phase. + * Set clk's phase by clk_core_get_phase() caching the phase. * Since a phase is by definition relative to its parent, just * query the current clock phase, or just assume it's in phase. */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - else - core->phase = 0; + clk_core_get_phase(core); /* * Set clk's duty cycle. @@ -3382,39 +3602,28 @@ if (core->flags & CLK_IS_CRITICAL) { unsigned long flags; - clk_core_prepare(core); + ret = clk_core_prepare(core); + if (ret) + goto out; flags = clk_enable_lock(); - clk_core_enable(core); + ret = clk_core_enable(core); clk_enable_unlock(flags); - } - - /* - * walk the list of orphan clocks and reparent any that newly finds a - * parent. - */ - hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { - struct clk_core *parent = __clk_init_parent(orphan); - - /* - * We need to use __clk_set_parent_before() and _after() to - * to properly migrate any prepare/enable count of the orphan - * clock. This is important for CLK_IS_CRITICAL clocks, which - * are enabled during init but might not have a parent yet. - */ - if (parent) { - /* update the clk tree topology */ - __clk_set_parent_before(orphan, parent); - __clk_set_parent_after(orphan, parent, NULL); - __clk_recalc_accuracies(orphan); - __clk_recalc_rates(orphan, 0); + if (ret) { + clk_core_unprepare(core); + goto out; } } - kref_init(&core->ref); + clk_core_reparent_orphans_nolock(); out: clk_pm_runtime_put(core); unlock: + if (ret) { + hlist_del_init(&core->child_node); + core->hw->core = NULL; + } + clk_prepare_unlock(); if (!ret) @@ -3616,6 +3825,22 @@ kfree(core->parents); } +/* Free memory allocated for a struct clk_core */ +static void __clk_release(struct kref *ref) +{ + struct clk_core *core = container_of(ref, struct clk_core, ref); + + if (core->rpm_enabled) { + mutex_lock(&clk_rpm_list_lock); + hlist_del(&core->rpm_node); + mutex_unlock(&clk_rpm_list_lock); + } + + clk_core_free_parent_map(core); + kfree_const(core->name); + kfree(core); +} + static struct clk * __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) { @@ -3636,6 +3861,8 @@ goto fail_out; } + kref_init(&core->ref); + core->name = kstrdup_const(init->name, GFP_KERNEL); if (!core->name) { ret = -ENOMEM; @@ -3648,9 +3875,8 @@ } core->ops = init->ops; - if (dev && pm_runtime_enabled(dev)) - core->rpm_enabled = true; core->dev = dev; + clk_pm_runtime_init(core); core->of_node = np; if (dev && dev->driver) core->owner = dev->driver->owner; @@ -3659,7 +3885,6 @@ core->num_parents = init->num_parents; core->min_rate = 0; core->max_rate = ULONG_MAX; - hw->core = core; ret = clk_core_populate_parent_map(core, init); if (ret) @@ -3677,7 +3902,7 @@ goto fail_create_clk; } - clk_core_link_consumer(hw->core, hw->clk); + clk_core_link_consumer(core, hw->clk); ret = __clk_core_init(core); if (!ret) @@ -3691,17 +3916,37 @@ hw->clk = NULL; fail_create_clk: - clk_core_free_parent_map(core); fail_parents: fail_ops: - kfree_const(core->name); fail_name: - kfree(core); + kref_put(&core->ref, __clk_release); fail_out: return ERR_PTR(ret); } /** + * dev_or_parent_of_node() - Get device node of @dev or @dev's parent + * @dev: Device to get device node of + * + * Return: device node pointer of @dev, or the device node pointer of + * @dev->parent if dev doesn't have a device node, or NULL if neither + * @dev or @dev->parent have a device node. + */ +static struct device_node *dev_or_parent_of_node(struct device *dev) +{ + struct device_node *np; + + if (!dev) + return NULL; + + np = dev_of_node(dev); + if (!np) + np = dev_of_node(dev->parent); + + return np; +} + +/** * clk_register - allocate a new clock, register it and return an opaque cookie * @dev: device that is registering this clock * @hw: link to hardware-specific clock data @@ -3716,7 +3961,7 @@ */ struct clk *clk_register(struct device *dev, struct clk_hw *hw) { - return __clk_register(dev, dev_of_node(dev), hw); + return __clk_register(dev, dev_or_parent_of_node(dev), hw); } EXPORT_SYMBOL_GPL(clk_register); @@ -3732,7 +3977,8 @@ */ int clk_hw_register(struct device *dev, struct clk_hw *hw) { - return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw)); + return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev), + hw)); } EXPORT_SYMBOL_GPL(clk_hw_register); @@ -3753,18 +3999,6 @@ } EXPORT_SYMBOL_GPL(of_clk_hw_register); -/* Free memory allocated for a clock. */ -static void __clk_release(struct kref *ref) -{ - struct clk_core *core = container_of(ref, struct clk_core, ref); - - lockdep_assert_held(&prepare_lock); - - clk_core_free_parent_map(core); - kfree_const(core->name); - kfree(core); -} - /* * Empty clk_ops for unregistered clocks. These are used temporarily * after clk_unregister() was called on a clock and until last clock @@ -3817,7 +4051,7 @@ /* Remove this clk from all parent caches */ static void clk_core_evict_parent_cache(struct clk_core *core) { - struct hlist_head **lists; + const struct hlist_head **lists; struct clk_core *root; lockdep_assert_held(&prepare_lock); @@ -3846,7 +4080,8 @@ if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - goto unlock; + clk_prepare_unlock(); + return; } /* * Assign empty clock ops for consumers that might still hold @@ -3877,10 +4112,10 @@ if (clk->core->protect_count) pr_warn("%s: unregistering protected clock: %s\n", __func__, clk->core->name); + clk_prepare_unlock(); kref_put(&clk->core->ref, __clk_release); -unlock: - clk_prepare_unlock(); + free_clk(clk); } EXPORT_SYMBOL_GPL(clk_unregister); @@ -4042,13 +4277,11 @@ clk->max_rate < clk->core->req_rate) clk_core_set_rate_nolock(clk->core, clk->core->req_rate); - owner = clk->core->owner; - kref_put(&clk->core->ref, __clk_release); - clk_prepare_unlock(); + owner = clk->core->owner; + kref_put(&clk->core->ref, __clk_release); module_put(owner); - free_clk(clk); } @@ -4087,20 +4320,19 @@ /* search the list of notifiers for this clk */ list_for_each_entry(cn, &clk_notifier_list, node) if (cn->clk == clk) - break; + goto found; /* if clk wasn't in the notifier list, allocate new clk_notifier */ - if (cn->clk != clk) { - cn = kzalloc(sizeof(*cn), GFP_KERNEL); - if (!cn) - goto out; + cn = kzalloc(sizeof(*cn), GFP_KERNEL); + if (!cn) + goto out; - cn->clk = clk; - srcu_init_notifier_head(&cn->notifier_head); + cn->clk = clk; + srcu_init_notifier_head(&cn->notifier_head); - list_add(&cn->node, &clk_notifier_list); - } + list_add(&cn->node, &clk_notifier_list); +found: ret = srcu_notifier_chain_register(&cn->notifier_head, nb); clk->core->notifier_count++; @@ -4125,32 +4357,28 @@ */ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb) { - struct clk_notifier *cn = NULL; - int ret = -EINVAL; + struct clk_notifier *cn; + int ret = -ENOENT; if (!clk || !nb) return -EINVAL; clk_prepare_lock(); - list_for_each_entry(cn, &clk_notifier_list, node) - if (cn->clk == clk) - break; - - if (cn->clk == clk) { - ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb); + list_for_each_entry(cn, &clk_notifier_list, node) { + if (cn->clk == clk) { + ret = srcu_notifier_chain_unregister(&cn->notifier_head, nb); - clk->core->notifier_count--; + clk->core->notifier_count--; - /* XXX the notifier code should handle this better */ - if (!cn->notifier_head.head) { - srcu_cleanup_notifier_head(&cn->notifier_head); - list_del(&cn->node); - kfree(cn); + /* XXX the notifier code should handle this better */ + if (!cn->notifier_head.head) { + srcu_cleanup_notifier_head(&cn->notifier_head); + list_del(&cn->node); + kfree(cn); + } + break; } - - } else { - ret = -ENOENT; } clk_prepare_unlock(); @@ -4160,6 +4388,13 @@ EXPORT_SYMBOL_GPL(clk_notifier_unregister); #ifdef CONFIG_OF +static void clk_core_reparent_orphans(void) +{ + clk_prepare_lock(); + clk_core_reparent_orphans_nolock(); + clk_prepare_unlock(); +} + /** * struct of_clk_provider - Clock provider registration structure * @link: Entry in global list of clock providers @@ -4255,6 +4490,8 @@ mutex_unlock(&of_clk_mutex); pr_debug("Added clock from %pOF\n", np); + clk_core_reparent_orphans(); + ret = of_clk_set_defaults(np, true); if (ret < 0) of_clk_del_provider(np); @@ -4290,6 +4527,8 @@ mutex_unlock(&of_clk_mutex); pr_debug("Added clk_hw provider from %pOF\n", np); + clk_core_reparent_orphans(); + ret = of_clk_set_defaults(np, true); if (ret < 0) of_clk_del_provider(np); --- linux-oracle-5.4.0.orig/drivers/clk/davinci/da8xx-cfgchip.c +++ linux-oracle-5.4.0/drivers/clk/davinci/da8xx-cfgchip.c @@ -505,7 +505,7 @@ const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" }; struct clk *fck_clk; struct da8xx_usb0_clk48 *usb0; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; fck_clk = devm_clk_get(dev, "fck"); @@ -579,7 +579,7 @@ { const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" }; struct da8xx_usb1_clk48 *usb1; - struct clk_init_data init; + struct clk_init_data init = {}; int ret; usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/clk/davinci/pll.c +++ linux-oracle-5.4.0/drivers/clk/davinci/pll.c @@ -491,7 +491,7 @@ parent_name = postdiv_name; } - pllen = kzalloc(sizeof(*pllout), GFP_KERNEL); + pllen = kzalloc(sizeof(*pllen), GFP_KERNEL); if (!pllen) { ret = -ENOMEM; goto err_unregister_postdiv; --- linux-oracle-5.4.0.orig/drivers/clk/hisilicon/clk-hi3519.c +++ linux-oracle-5.4.0/drivers/clk/hisilicon/clk-hi3519.c @@ -130,7 +130,7 @@ of_clk_del_provider(pdev->dev.of_node); hisi_clk_unregister_gate(hi3519_gate_clks, - ARRAY_SIZE(hi3519_mux_clks), + ARRAY_SIZE(hi3519_gate_clks), crg->clk_data); hisi_clk_unregister_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks), --- linux-oracle-5.4.0.orig/drivers/clk/hisilicon/clk-hi3620.c +++ linux-oracle-5.4.0/drivers/clk/hisilicon/clk-hi3620.c @@ -467,8 +467,10 @@ return; clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL); - if (!clk_data->clks) + if (!clk_data->clks) { + kfree(clk_data); return; + } for (i = 0; i < num; i++) { struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i]; --- linux-oracle-5.4.0.orig/drivers/clk/hisilicon/clk-hi6220.c +++ linux-oracle-5.4.0/drivers/clk/hisilicon/clk-hi6220.c @@ -86,7 +86,8 @@ hisi_clk_register_gate_sep(hi6220_separated_gate_clks_ao, ARRAY_SIZE(hi6220_separated_gate_clks_ao), clk_data_ao); } -CLK_OF_DECLARE(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); +/* Allow reset driver to probe as well */ +CLK_OF_DECLARE_DRIVER(hi6220_clk_ao, "hisilicon,hi6220-aoctrl", hi6220_clk_ao_init); /* clocks in sysctrl */ --- linux-oracle-5.4.0.orig/drivers/clk/imx/Kconfig +++ linux-oracle-5.4.0/drivers/clk/imx/Kconfig @@ -30,5 +30,6 @@ bool "IMX8QXP SCU Clock" depends on ARCH_MXC && IMX_SCU && ARM64 select MXC_CLK_SCU + select MXC_CLK help Build the driver for IMX8QXP SCU based clocks. --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-composite-8m.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-composite-8m.c @@ -95,7 +95,7 @@ int prediv_value; int div_value; int ret; - u32 val; + u32 orig, val; ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, &prediv_value, &div_value); @@ -104,13 +104,15 @@ spin_lock_irqsave(divider->lock, flags); - val = readl(divider->reg); - val &= ~((clk_div_mask(divider->width) << divider->shift) | - (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); + orig = readl(divider->reg); + val = orig & ~((clk_div_mask(divider->width) << divider->shift) | + (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); val |= (u32)(prediv_value - 1) << divider->shift; val |= (u32)(div_value - 1) << PCG_DIV_SHIFT; - writel(val, divider->reg); + + if (val != orig) + writel(val, divider->reg); spin_unlock_irqrestore(divider->lock, flags); @@ -142,6 +144,7 @@ mux->reg = reg; mux->shift = PCG_PCS_SHIFT; mux->mask = PCG_PCS_MASK; + mux->lock = &imx_ccm_lock; div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) @@ -161,6 +164,7 @@ gate_hw = &gate->hw; gate->reg = reg; gate->bit_idx = PCG_CGC_SHIFT; + gate->lock = &imx_ccm_lock; hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, mux_hw, &clk_mux_ops, div_hw, --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx6sx.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx6sx.c @@ -287,13 +287,13 @@ hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); - hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); + hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); - hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); + hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels)); hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx6ul.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx6ul.c @@ -161,7 +161,6 @@ hws[IMX6UL_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_PLL6_BYPASS] = imx_clk_hw_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_PLL7_BYPASS] = imx_clk_hw_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux_flags("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels), CLK_SET_RATE_PARENT); /* Do not bypass PLLs initially */ clk_set_parent(hws[IMX6UL_PLL1_BYPASS]->clk, hws[IMX6UL_CLK_PLL1]->clk); @@ -270,6 +269,7 @@ hws[IMX6UL_CLK_ECSPI_SEL] = imx_clk_hw_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); hws[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_hw_mux_flags("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels), CLK_SET_RATE_PARENT); hws[IMX6UL_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); + hws[IMX6UL_CLK_CSI_SEL] = imx_clk_hw_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); hws[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_hw_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); hws[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_hw_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx7d.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx7d.c @@ -859,7 +859,6 @@ hws[IMX7D_WDOG4_ROOT_CLK] = imx_clk_hw_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0); hws[IMX7D_KPP_ROOT_CLK] = imx_clk_hw_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0); hws[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_hw_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0); - hws[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_hw_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0); hws[IMX7D_WRCLK_ROOT_CLK] = imx_clk_hw_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0); hws[IMX7D_USB_CTRL_CLK] = imx_clk_hw_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0); hws[IMX7D_USB_PHY1_CLK] = imx_clk_hw_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx7ulp.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx7ulp.c @@ -24,8 +24,8 @@ static const char * const spll_sels[] = { "spll", "spll_pfd_sel", }; static const char * const apll_pfd_sels[] = { "apll_pfd0", "apll_pfd1", "apll_pfd2", "apll_pfd3", }; static const char * const apll_sels[] = { "apll", "apll_pfd_sel", }; -static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "upll", }; -static const char * const ddr_sels[] = { "apll_pfd_sel", "upll", }; +static const char * const scs_sels[] = { "dummy", "sosc", "sirc", "firc", "dummy", "apll_sel", "spll_sel", "dummy", }; +static const char * const ddr_sels[] = { "apll_pfd_sel", "dummy", "dummy", "dummy", }; static const char * const nic_sels[] = { "firc", "ddr_clk", }; static const char * const periph_plat_sels[] = { "dummy", "nic1_bus_clk", "nic1_clk", "ddr_clk", "apll_pfd2", "apll_pfd1", "apll_pfd0", "upll", }; static const char * const periph_bus_sels[] = { "dummy", "sosc_bus_clk", "mpll", "firc_bus_clk", "rosc", "nic1_bus_clk", "nic1_clk", "spll_bus_clk", }; @@ -40,6 +40,7 @@ { .val = 5, .div = 16, }, { .val = 6, .div = 32, }, { .val = 7, .div = 64, }, + { /* sentinel */ }, }; static const int pcc2_uart_clk_ids[] __initconst = { @@ -118,7 +119,7 @@ clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels)); clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels)); - clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 1, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); + clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT); clks[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx8mm.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx8mm.c @@ -26,73 +26,6 @@ static u32 share_count_pdm; static u32 share_count_nand; -static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = { - PLL_1416X_RATE(1800000000U, 225, 3, 0), - PLL_1416X_RATE(1600000000U, 200, 3, 0), - PLL_1416X_RATE(1200000000U, 300, 3, 1), - PLL_1416X_RATE(1000000000U, 250, 3, 1), - PLL_1416X_RATE(800000000U, 200, 3, 1), - PLL_1416X_RATE(750000000U, 250, 2, 2), - PLL_1416X_RATE(700000000U, 350, 3, 2), - PLL_1416X_RATE(600000000U, 300, 3, 2), -}; - -static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = { - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), -}; - -static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), - PLL_1443X_RATE(594000000U, 198, 2, 2, 0), -}; - -static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = { - PLL_1443X_RATE(650000000U, 325, 3, 2, 0), -}; - -static struct imx_pll14xx_clk imx8mm_audio_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_audiopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_video_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_videopll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_dram_pll = { - .type = PLL_1443X, - .rate_table = imx8mm_drampll_tbl, - .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_arm_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_gpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_vpu_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - -static struct imx_pll14xx_clk imx8mm_sys_pll = { - .type = PLL_1416X, - .rate_table = imx8mm_pll1416x_tbl, - .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), -}; - static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; @@ -396,16 +329,16 @@ clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll); - clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll); - clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll); - clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll); - clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll); - clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll); - clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll); - clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll); - clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll); + clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll); + clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll); + clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll); + clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll); + clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll); + clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll); + clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx_1416x_pll); + clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll); /* PLL bypass out */ clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx8mn.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx8mn.c @@ -189,27 +189,27 @@ "sys_pll3_out", "clk_ext4", }; static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext3", "clk_ext4", }; static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext3", "clk_ext4", }; static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext2", "clk_ext3", }; static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext3", "clk_ext4", }; static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext3", "clk_ext4", }; static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", + "video_pll1_out", "sys_pll1_133m", "dummy", "clk_ext2", "clk_ext3", }; static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", @@ -358,9 +358,9 @@ static const char * const imx8mn_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; -static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", - "sys_pll1_200m", "audio_pll2_out", "vpu_pll", - "sys_pll1_80m", }; +static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", + "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m", + "dummy", "sys_pll1_80m", }; static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", }; @@ -582,7 +582,7 @@ clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); - clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0); + clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0); clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0); clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-imx8mq.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-imx8mq.c @@ -157,10 +157,10 @@ "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", }; static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", - "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", }; + "sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", }; static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m", - "audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", }; + "sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", }; static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", "sys1_pll_133m", }; --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-pfdv2.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-pfdv2.c @@ -139,6 +139,12 @@ u32 val; u8 frac; + if (!rate) + return -EINVAL; + + /* PFD can NOT change rate without gating */ + WARN_ON(clk_pfdv2_is_enabled(hw)); + tmp = tmp * 18 + rate / 2; do_div(tmp, rate); frac = tmp; --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-pll14xx.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-pll14xx.c @@ -41,6 +41,36 @@ #define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) +const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = { + PLL_1416X_RATE(1800000000U, 225, 3, 0), + PLL_1416X_RATE(1600000000U, 200, 3, 0), + PLL_1416X_RATE(1200000000U, 300, 3, 1), + PLL_1416X_RATE(1000000000U, 250, 3, 1), + PLL_1416X_RATE(800000000U, 200, 3, 1), + PLL_1416X_RATE(750000000U, 250, 2, 2), + PLL_1416X_RATE(700000000U, 350, 3, 2), + PLL_1416X_RATE(600000000U, 300, 3, 2), +}; + +const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = { + PLL_1443X_RATE(650000000U, 325, 3, 2, 0), + PLL_1443X_RATE(594000000U, 198, 2, 2, 0), + PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), + PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), +}; + +struct imx_pll14xx_clk imx_1443x_pll = { + .type = PLL_1443X, + .rate_table = imx_pll1443x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1443x_tbl), +}; + +struct imx_pll14xx_clk imx_1416x_pll = { + .type = PLL_1416X, + .rate_table = imx_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx_pll1416x_tbl), +}; + static const struct imx_pll14xx_rate_table *imx_get_pll_settings( struct clk_pll14xx *pll, unsigned long rate) { @@ -112,48 +142,22 @@ return fvco; } -static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate, +static inline bool clk_pll14xx_mp_change(const struct imx_pll14xx_rate_table *rate, u32 pll_div) { u32 old_mdiv, old_pdiv; - old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK; + old_mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; + old_pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv; } -static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - -static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate, - u32 pll_div_ctl0, u32 pll_div_ctl1) -{ - u32 old_mdiv, old_pdiv, old_kdiv; - - old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; - old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; - old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; - - return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || - rate->kdiv != old_kdiv; -} - static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) { u32 val; - return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0, + return readl_poll_timeout(pll->base, val, val & LOCK_STATUS, 0, LOCK_TIMEOUT_US); } @@ -174,7 +178,7 @@ tmp = readl_relaxed(pll->base + 4); - if (!clk_pll1416x_mp_change(rate, tmp)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); @@ -239,13 +243,15 @@ } tmp = readl_relaxed(pll->base + 4); - div_val = readl_relaxed(pll->base + 8); - if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) { + if (!clk_pll14xx_mp_change(rate, tmp)) { tmp &= ~(SDIV_MASK) << SDIV_SHIFT; tmp |= rate->sdiv << SDIV_SHIFT; writel_relaxed(tmp, pll->base + 4); + tmp = rate->kdiv << KDIV_SHIFT; + writel_relaxed(tmp, pll->base + 8); + return 0; } --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk-scu.c +++ linux-oracle-5.4.0/drivers/clk/imx/clk-scu.c @@ -43,12 +43,12 @@ __le32 rate; __le16 resource; u8 clk; -} __packed; +} __packed __aligned(4); struct req_get_clock_rate { __le16 resource; u8 clk; -} __packed; +} __packed __aligned(4); struct resp_get_clock_rate { __le32 rate; @@ -84,7 +84,7 @@ struct req_get_clock_parent { __le16 resource; u8 clk; - } __packed req; + } __packed __aligned(4) req; struct resp_get_clock_parent { u8 parent; } resp; @@ -121,7 +121,7 @@ u8 clk; u8 enable; u8 autog; -} __packed; +} __packed __aligned(4); static inline struct clk_scu *to_clk_scu(struct clk_hw *hw) { --- linux-oracle-5.4.0.orig/drivers/clk/imx/clk.h +++ linux-oracle-5.4.0/drivers/clk/imx/clk.h @@ -50,49 +50,52 @@ int flags; }; +extern struct imx_pll14xx_clk imx_1416x_pll; +extern struct imx_pll14xx_clk imx_1443x_pll; + #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \ - imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk + to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ cgr_val, clk_gate_flags, lock, share_count) \ - clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ - cgr_val, clk_gate_flags, lock, share_count)->clk + to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ + cgr_val, clk_gate_flags, lock, share_count)) #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ - imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk + to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)) #define imx_clk_pfd(name, parent_name, reg, idx) \ - imx_clk_hw_pfd(name, parent_name, reg, idx)->clk + to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx)) #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \ - imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk + to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)) #define imx_clk_fixed_factor(name, parent, mult, div) \ - imx_clk_hw_fixed_factor(name, parent, mult, div)->clk + to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div)) #define imx_clk_divider2(name, parent, reg, shift, width) \ - imx_clk_hw_divider2(name, parent, reg, shift, width)->clk + to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width)) #define imx_clk_gate_dis(name, parent, reg, shift) \ - imx_clk_hw_gate_dis(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift)) #define imx_clk_gate2(name, parent, reg, shift) \ - imx_clk_hw_gate2(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate2(name, parent, reg, shift)) #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \ - imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk + to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)) #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \ - imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk + to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)) #define imx_clk_gate3(name, parent, reg, shift) \ - imx_clk_hw_gate3(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate3(name, parent, reg, shift)) #define imx_clk_gate4(name, parent, reg, shift) \ - imx_clk_hw_gate4(name, parent, reg, shift)->clk + to_clk(imx_clk_hw_gate4(name, parent, reg, shift)) #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \ - imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk + to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)) struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, void __iomem *base, const struct imx_pll14xx_clk *pll_clk); @@ -195,6 +198,13 @@ u8 shift, u8 width, const char * const *parents, int num_parents, void (*fixup)(u32 *val)); +static inline struct clk *to_clk(struct clk_hw *hw) +{ + if (IS_ERR_OR_NULL(hw)) + return ERR_CAST(hw); + return hw->clk; +} + static inline struct clk *imx_clk_fixed(const char *name, int rate) { return clk_register_fixed_rate(NULL, name, NULL, 0, rate); --- linux-oracle-5.4.0.orig/drivers/clk/ingenic/cgu.c +++ linux-oracle-5.4.0/drivers/clk/ingenic/cgu.c @@ -393,15 +393,21 @@ ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info, unsigned int div) { - unsigned int i; + unsigned int i, best_i = 0, best = (unsigned int)-1; for (i = 0; i < (1 << clk_info->div.bits) && clk_info->div.div_table[i]; i++) { - if (clk_info->div.div_table[i] >= div) - return i; + if (clk_info->div.div_table[i] >= div && + clk_info->div.div_table[i] < best) { + best = clk_info->div.div_table[i]; + best_i = i; + + if (div == best) + break; + } } - return i - 1; + return best_i; } static unsigned @@ -420,15 +426,15 @@ } /* Impose hardware constraints */ - div = min_t(unsigned, div, 1 << clk_info->div.bits); - div = max_t(unsigned, div, 1); + div = clamp_t(unsigned int, div, clk_info->div.div, + clk_info->div.div << clk_info->div.bits); /* * If the divider value itself must be divided before being written to * the divider register, we must ensure we don't have any bits set that * would be lost as a result of doing so. */ - div /= clk_info->div.div; + div = DIV_ROUND_UP(div, clk_info->div.div); div *= clk_info->div.div; return div; --- linux-oracle-5.4.0.orig/drivers/clk/ingenic/jz4725b-cgu.c +++ linux-oracle-5.4.0/drivers/clk/ingenic/jz4725b-cgu.c @@ -135,11 +135,10 @@ }, [JZ4725B_CLK_I2S] = { - "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, + "i2s", CGU_CLK_MUX | CGU_CLK_DIV, .parents = { JZ4725B_CLK_EXT, JZ4725B_CLK_PLL_HALF, -1, -1 }, .mux = { CGU_REG_CPCCR, 31, 1 }, .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, - .gate = { CGU_REG_CLKGR, 6 }, }, [JZ4725B_CLK_SPI] = { --- linux-oracle-5.4.0.orig/drivers/clk/ingenic/jz4770-cgu.c +++ linux-oracle-5.4.0/drivers/clk/ingenic/jz4770-cgu.c @@ -432,8 +432,10 @@ cgu = ingenic_cgu_new(jz4770_cgu_clocks, ARRAY_SIZE(jz4770_cgu_clocks), np); - if (!cgu) + if (!cgu) { pr_err("%s: failed to initialise CGU\n", __func__); + return; + } retval = ingenic_cgu_register_clocks(cgu); if (retval) --- linux-oracle-5.4.0.orig/drivers/clk/ingenic/tcu.c +++ linux-oracle-5.4.0/drivers/clk/ingenic/tcu.c @@ -100,15 +100,11 @@ bool enabled = false; /* - * If the SoC has no global TCU clock, we must ungate the channel's - * clock to be able to access its registers. - * If we have a TCU clock, it will be enabled automatically as it has - * been attached to the regmap. + * According to the programming manual, a timer channel's registers can + * only be accessed when the channel's stop bit is clear. */ - if (!tcu->clk) { - enabled = !!ingenic_tcu_is_enabled(hw); - regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); - } + enabled = !!ingenic_tcu_is_enabled(hw); + regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); return enabled; } @@ -119,8 +115,7 @@ const struct ingenic_tcu_clk_info *info = tcu_clk->info; struct ingenic_tcu *tcu = tcu_clk->tcu; - if (!tcu->clk) - regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); + regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); } static u8 ingenic_tcu_get_parent(struct clk_hw *hw) @@ -189,7 +184,7 @@ u8 prescale; if (req_rate > rate) - return -EINVAL; + return rate; prescale = ingenic_tcu_get_prescale(rate, req_rate); --- linux-oracle-5.4.0.orig/drivers/clk/keystone/pll.c +++ linux-oracle-5.4.0/drivers/clk/keystone/pll.c @@ -209,7 +209,7 @@ } clk = clk_register_pll(NULL, node->name, parent_name, pll_data); - if (clk) { + if (!IS_ERR_OR_NULL(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); return; } @@ -281,12 +281,13 @@ clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift, mask, 0, NULL); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - } else { + if (IS_ERR(clk)) { pr_err("%s: error registering divider %s\n", __func__, clk_name); iounmap(reg); + return; } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); } CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init); @@ -328,10 +329,12 @@ clk = clk_register_mux(NULL, clk_name, (const char **)&parents, ARRAY_SIZE(parents) , 0, reg, shift, mask, 0, NULL); - if (clk) - of_clk_add_provider(node, of_clk_src_simple_get, clk); - else + if (IS_ERR(clk)) { pr_err("%s: error registering mux %s\n", __func__, clk_name); + return; + } + + of_clk_add_provider(node, of_clk_src_simple_get, clk); } CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init); --- linux-oracle-5.4.0.orig/drivers/clk/keystone/sci-clk.c +++ linux-oracle-5.4.0/drivers/clk/keystone/sci-clk.c @@ -287,6 +287,8 @@ name = kasprintf(GFP_KERNEL, "clk:%d:%d", sci_clk->dev_id, sci_clk->clk_id); + if (!name) + return -ENOMEM; init.name = name; @@ -522,7 +524,7 @@ np = of_find_node_with_property(np, *clk_name); if (!np) { clk_name++; - break; + continue; } if (!of_device_is_available(np)) --- linux-oracle-5.4.0.orig/drivers/clk/loongson1/clk-loongson1c.c +++ linux-oracle-5.4.0/drivers/clk/loongson1/clk-loongson1c.c @@ -37,6 +37,7 @@ [1] = { .val = 1, .div = 4 }, [2] = { .val = 2, .div = 3 }, [3] = { .val = 3, .div = 3 }, + [4] = { /* sentinel */ } }; void __init ls1x_clk_init(void) --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt2701.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt2701.c @@ -675,6 +675,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_TOP_NR); + if (!clk_data) + return -ENOMEM; mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), clk_data); @@ -742,6 +744,8 @@ if (!infra_clk_data) { infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); + if (!infra_clk_data) + return; for (i = 0; i < CLK_INFRA_NR; i++) infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER); @@ -768,6 +772,8 @@ if (!infra_clk_data) { infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); + if (!infra_clk_data) + return -ENOMEM; } else { for (i = 0; i < CLK_INFRA_NR; i++) { if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER)) @@ -896,6 +902,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_PERI_NR); + if (!clk_data) + return -ENOMEM; mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data); --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt6779.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt6779.c @@ -919,6 +919,8 @@ "pwm_sel", 19), GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm", "pwm_sel", 21), + GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0", + "uart_sel", 22), GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1", "uart_sel", 23), GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2", @@ -1214,6 +1216,8 @@ struct device_node *node = pdev->dev.of_node; clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); @@ -1235,6 +1239,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), clk_data); --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt6797.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt6797.c @@ -392,6 +392,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_TOP_NR); + if (!clk_data) + return -ENOMEM; mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs), clk_data); @@ -564,6 +566,8 @@ if (!infra_clk_data) { infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); + if (!infra_clk_data) + return; for (i = 0; i < CLK_INFRA_NR; i++) infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER); @@ -588,6 +592,8 @@ if (!infra_clk_data) { infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR); + if (!infra_clk_data) + return -ENOMEM; } else { for (i = 0; i < CLK_INFRA_NR; i++) { if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER)) --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt7629-eth.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt7629-eth.c @@ -83,6 +83,8 @@ int r; clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_gates(node, eth_clks, CLK_ETH_NR_CLK, clk_data); @@ -105,6 +107,8 @@ int r; clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_gates(node, sgmii_clks[id++], CLK_SGMII_NR_CLK, clk_data); --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt7629.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt7629.c @@ -581,6 +581,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), clk_data); @@ -605,6 +607,8 @@ int r; clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data); @@ -633,6 +637,8 @@ return PTR_ERR(base); clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); + if (!clk_data) + return -ENOMEM; mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data); --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mt8183-mfgcfg.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mt8183-mfgcfg.c @@ -18,9 +18,9 @@ .sta_ofs = 0x0, }; -#define GATE_MFG(_id, _name, _parent, _shift) \ - GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, \ - &mtk_clk_gate_ops_setclr) +#define GATE_MFG(_id, _name, _parent, _shift) \ + GATE_MTK_FLAGS(_id, _name, _parent, &mfg_cg_regs, _shift, \ + &mtk_clk_gate_ops_setclr, CLK_SET_RATE_PARENT) static const struct mtk_gate mfg_clks[] = { GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_sel", 0) --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/clk-mux.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/clk-mux.c @@ -160,7 +160,7 @@ spinlock_t *lock) { struct mtk_clk_mux *clk_mux; - struct clk_init_data init; + struct clk_init_data init = {}; struct clk *clk; clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/clk/mediatek/reset.c +++ linux-oracle-5.4.0/drivers/clk/mediatek/reset.c @@ -25,7 +25,7 @@ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); unsigned int reg = data->regofs + ((id / 32) << 4); - return regmap_write(data->regmap, reg, 1); + return regmap_write(data->regmap, reg, BIT(id % 32)); } static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, @@ -34,7 +34,7 @@ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4; - return regmap_write(data->regmap, reg, 1); + return regmap_write(data->regmap, reg, BIT(id % 32)); } static int mtk_reset_assert(struct reset_controller_dev *rcdev, --- linux-oracle-5.4.0.orig/drivers/clk/meson/Kconfig +++ linux-oracle-5.4.0/drivers/clk/meson/Kconfig @@ -103,6 +103,7 @@ select COMMON_CLK_MESON_AO_CLKC select COMMON_CLK_MESON_EE_CLKC select COMMON_CLK_MESON_CPU_DYNDIV + select COMMON_CLK_MESON_VID_PLL_DIV select MFD_SYSCON help Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2 --- linux-oracle-5.4.0.orig/drivers/clk/meson/axg-audio.c +++ linux-oracle-5.4.0/drivers/clk/meson/axg-audio.c @@ -1001,7 +1001,7 @@ .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .max_register = AUDIO_CLK_PDMIN_CTRL1, + .max_register = AUDIO_CLK_SPDIFOUT_B_CTRL, }; struct audioclk_data { --- linux-oracle-5.4.0.orig/drivers/clk/meson/clk-pll.c +++ linux-oracle-5.4.0/drivers/clk/meson/clk-pll.c @@ -77,6 +77,15 @@ unsigned int m, n, frac; n = meson_parm_read(clk->map, &pll->n); + + /* + * On some HW, N is set to zero on init. This value is invalid as + * it would result in a division by zero. The rate can't be + * calculated in this case + */ + if (n == 0) + return 0; + m = meson_parm_read(clk->map, &pll->m); frac = MESON_PARM_APPLICABLE(&pll->frac) ? @@ -354,13 +363,14 @@ { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); - unsigned int enabled, m, n, frac = 0, ret; + unsigned int enabled, m, n, frac = 0; unsigned long old_rate; + int ret; if (parent_rate == 0 || rate == 0) return -EINVAL; - old_rate = rate; + old_rate = clk_hw_get_rate(hw); ret = meson_clk_get_pll_settings(rate, parent_rate, &m, &n, pll); if (ret) @@ -382,7 +392,8 @@ if (!enabled) return 0; - if (meson_clk_pll_enable(hw)) { + ret = meson_clk_pll_enable(hw); + if (ret) { pr_warn("%s: pll did not lock, trying to restore old rate %lu\n", __func__, old_rate); /* @@ -394,7 +405,7 @@ meson_clk_pll_set_rate(hw, old_rate, parent_rate); } - return 0; + return ret; } /* --- linux-oracle-5.4.0.orig/drivers/clk/meson/g12a.c +++ linux-oracle-5.4.0/drivers/clk/meson/g12a.c @@ -298,6 +298,17 @@ &g12a_fclk_div2_div.hw }, .num_parents = 1, + /* + * Similar to fclk_div3, it seems that this clock is used by + * the resident firmware and is required by the platform to + * operate correctly. + * Until the following condition are met, we need this clock to + * be marked as critical: + * a) Mark the clock used by a firmware resource, if possible + * b) CCF has a clock hand-off mechanism to make the sure the + * clock stays on until the proper driver comes along + */ + .flags = CLK_IS_CRITICAL, }, }; @@ -1591,7 +1602,7 @@ }; static const struct pll_mult_range g12a_gp0_pll_mult_range = { - .min = 55, + .min = 125, .max = 255, }; @@ -4692,6 +4703,7 @@ &g12a_bt656, &g12a_usb1_to_ddr, &g12a_mmc_pclk, + &g12a_uart2, &g12a_vpu_intr, &g12a_gic, &g12a_sd_emmc_a_clk0, --- linux-oracle-5.4.0.orig/drivers/clk/meson/gxbb.c +++ linux-oracle-5.4.0/drivers/clk/meson/gxbb.c @@ -719,6 +719,35 @@ .width = 14, }, .sdm_en = { + .reg_off = HHI_MPLL_CNTL, + .shift = 25, + .width = 1, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 16, + .width = 9, + }, + .lock = &meson_clk_lock, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &gxbb_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap gxl_mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { .reg_off = HHI_MPLL_CNTL7, .shift = 15, .width = 1, @@ -748,7 +777,16 @@ .hw.init = &(struct clk_init_data){ .name = "mpll0", .ops = &clk_regmap_gate_ops, - .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw }, + .parent_data = &(const struct clk_parent_data) { + /* + * Note: + * GXL and GXBB have different SDM_EN registers. We + * fallback to the global naming string mechanism so + * mpll0_div picks up the appropriate one. + */ + .name = "mpll0_div", + .index = -1, + }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, }, @@ -3036,7 +3074,7 @@ [CLKID_VAPB_1] = &gxbb_vapb_1.hw, [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, [CLKID_VAPB] = &gxbb_vapb.hw, - [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw, + [CLKID_MPLL0_DIV] = &gxl_mpll0_div.hw, [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw, [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw, [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw, @@ -3430,7 +3468,7 @@ &gxbb_mpll0, &gxbb_mpll1, &gxbb_mpll2, - &gxbb_mpll0_div, + &gxl_mpll0_div, &gxbb_mpll1_div, &gxbb_mpll2_div, &gxbb_cts_amclk_div, --- linux-oracle-5.4.0.orig/drivers/clk/meson/meson-aoclk.c +++ linux-oracle-5.4.0/drivers/clk/meson/meson-aoclk.c @@ -36,6 +36,7 @@ struct meson_aoclk_reset_controller *rstc; struct meson_aoclk_data *data; struct device *dev = &pdev->dev; + struct device_node *np; struct regmap *regmap; int ret, clkid; @@ -47,7 +48,9 @@ if (!rstc) return -ENOMEM; - regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); + np = of_get_parent(dev->of_node); + regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap\n"); return PTR_ERR(regmap); --- linux-oracle-5.4.0.orig/drivers/clk/meson/meson-eeclk.c +++ linux-oracle-5.4.0/drivers/clk/meson/meson-eeclk.c @@ -17,6 +17,7 @@ { const struct meson_eeclkc_data *data; struct device *dev = &pdev->dev; + struct device_node *np; struct regmap *map; int ret, i; @@ -25,7 +26,9 @@ return -EINVAL; /* Get the hhi system controller node */ - map = syscon_node_to_regmap(of_get_parent(dev->of_node)); + np = of_get_parent(dev->of_node); + map = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(map)) { dev_err(dev, "failed to get HHI regmap\n"); --- linux-oracle-5.4.0.orig/drivers/clk/meson/meson8b.c +++ linux-oracle-5.4.0/drivers/clk/meson/meson8b.c @@ -1071,7 +1071,7 @@ * Meson8m2: vid2_pll */ .parent_hws = (const struct clk_hw *[]) { - &meson8b_hdmi_pll_dco.hw + &meson8b_hdmi_pll_lvds_out.hw }, .num_parents = 1, .flags = CLK_SET_RATE_PARENT, @@ -1207,7 +1207,7 @@ static struct clk_regmap meson8b_vclk_div1_gate = { .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_CLK_DIV, + .offset = HHI_VID_CLK_CNTL, .bit_idx = 0, }, .hw.init = &(struct clk_init_data){ @@ -1237,7 +1237,7 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = { .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_CLK_DIV, + .offset = HHI_VID_CLK_CNTL, .bit_idx = 1, }, .hw.init = &(struct clk_init_data){ @@ -1267,7 +1267,7 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = { .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_CLK_DIV, + .offset = HHI_VID_CLK_CNTL, .bit_idx = 2, }, .hw.init = &(struct clk_init_data){ @@ -1297,7 +1297,7 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = { .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_CLK_DIV, + .offset = HHI_VID_CLK_CNTL, .bit_idx = 3, }, .hw.init = &(struct clk_init_data){ @@ -1327,7 +1327,7 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = { .data = &(struct clk_regmap_gate_data){ - .offset = HHI_VID_CLK_DIV, + .offset = HHI_VID_CLK_CNTL, .bit_idx = 4, }, .hw.init = &(struct clk_init_data){ @@ -1764,8 +1764,11 @@ /* * The MALI IP is clocked by two identical clocks (mali_0 and mali_1) - * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only - * has mali_0 and no glitch-free mux. + * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can + * actually manage this glitch-free mux because it does top-to-bottom + * updates the each clock tree and switches to the "inactive" one when + * CLK_SET_RATE_GATE is set. + * Meson8 only has mali_0 and no glitch-free mux. */ static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = { &meson8b_xtal.hw, @@ -1830,7 +1833,7 @@ &meson8b_mali_0_div.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, }, }; @@ -1885,7 +1888,7 @@ &meson8b_mali_1_div.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT, }, }; @@ -1907,6 +1910,13 @@ }, }; +static const struct reg_sequence meson8m2_gp_pll_init_regs[] = { + { .reg = HHI_GP_PLL_CNTL2, .def = 0x59c88000 }, + { .reg = HHI_GP_PLL_CNTL3, .def = 0xca463823 }, + { .reg = HHI_GP_PLL_CNTL4, .def = 0x0286a027 }, + { .reg = HHI_GP_PLL_CNTL5, .def = 0x00003000 }, +}; + static const struct pll_params_table meson8m2_gp_pll_params_table[] = { PLL_PARAMS(182, 3), { /* sentinel */ }, @@ -1940,6 +1950,8 @@ .width = 1, }, .table = meson8m2_gp_pll_params_table, + .init_regs = meson8m2_gp_pll_init_regs, + .init_count = ARRAY_SIZE(meson8m2_gp_pll_init_regs), }, .hw.init = &(struct clk_init_data){ .name = "gp_pll_dco", @@ -3488,54 +3500,87 @@ static const struct meson8b_clk_reset_line { u32 reg; u8 bit_idx; + bool active_low; } meson8b_clk_reset_bits[] = { [CLKC_RESET_L2_CACHE_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 30, + .active_low = false, }, [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 29, + .active_low = false, }, [CLKC_RESET_SCU_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 28, + .active_low = false, }, [CLKC_RESET_CPU3_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 27, + .active_low = false, }, [CLKC_RESET_CPU2_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 26, + .active_low = false, }, [CLKC_RESET_CPU1_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 25, + .active_low = false, }, [CLKC_RESET_CPU0_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 24, + .active_low = false, }, [CLKC_RESET_A5_GLOBAL_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 18, + .active_low = false, }, [CLKC_RESET_A5_AXI_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 17, + .active_low = false, }, [CLKC_RESET_A5_ABP_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16 + .reg = HHI_SYS_CPU_CLK_CNTL0, + .bit_idx = 16, + .active_low = false, }, [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = { - .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30 + .reg = HHI_SYS_CPU_CLK_CNTL1, + .bit_idx = 30, + .active_low = false, }, [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = { - .reg = HHI_VID_CLK_CNTL, .bit_idx = 15 + .reg = HHI_VID_CLK_CNTL, + .bit_idx = 15, + .active_low = false, }, [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = { - .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7 + .reg = HHI_VID_DIVIDER_CNTL, + .bit_idx = 7, + .active_low = false, }, [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = { - .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3 + .reg = HHI_VID_DIVIDER_CNTL, + .bit_idx = 3, + .active_low = false, }, [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = { - .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1 + .reg = HHI_VID_DIVIDER_CNTL, + .bit_idx = 1, + .active_low = true, }, [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = { - .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0 + .reg = HHI_VID_DIVIDER_CNTL, + .bit_idx = 0, + .active_low = true, }, }; @@ -3544,22 +3589,22 @@ { struct meson8b_clk_reset *meson8b_clk_reset = container_of(rcdev, struct meson8b_clk_reset, reset); - unsigned long flags; const struct meson8b_clk_reset_line *reset; + unsigned int value = 0; + unsigned long flags; if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) return -EINVAL; reset = &meson8b_clk_reset_bits[id]; + if (assert != reset->active_low) + value = BIT(reset->bit_idx); + spin_lock_irqsave(&meson_clk_lock, flags); - if (assert) - regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, - BIT(reset->bit_idx), BIT(reset->bit_idx)); - else - regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, - BIT(reset->bit_idx), 0); + regmap_update_bits(meson8b_clk_reset->regmap, reset->reg, + BIT(reset->bit_idx), value); spin_unlock_irqrestore(&meson_clk_lock, flags); @@ -3639,13 +3684,16 @@ struct clk_hw_onecell_data *clk_hw_onecell_data) { struct meson8b_clk_reset *rstc; + struct device_node *parent_np; const char *notifier_clk_name; struct clk *notifier_clk; void __iomem *clk_base; struct regmap *map; int i, ret; - map = syscon_node_to_regmap(of_get_parent(np)); + parent_np = of_get_parent(np); + map = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); if (IS_ERR(map)) { pr_info("failed to get HHI regmap - Trying obsolete regs\n"); --- linux-oracle-5.4.0.orig/drivers/clk/meson/meson8b.h +++ linux-oracle-5.4.0/drivers/clk/meson/meson8b.h @@ -20,6 +20,10 @@ * [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf */ #define HHI_GP_PLL_CNTL 0x40 /* 0x10 offset in data sheet */ +#define HHI_GP_PLL_CNTL2 0x44 /* 0x11 offset in data sheet */ +#define HHI_GP_PLL_CNTL3 0x48 /* 0x12 offset in data sheet */ +#define HHI_GP_PLL_CNTL4 0x4C /* 0x13 offset in data sheet */ +#define HHI_GP_PLL_CNTL5 0x50 /* 0x14 offset in data sheet */ #define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */ #define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */ #define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */ --- linux-oracle-5.4.0.orig/drivers/clk/mmp/clk-of-mmp2.c +++ linux-oracle-5.4.0/drivers/clk/mmp/clk-of-mmp2.c @@ -134,7 +134,7 @@ static const char *ssp_parent_names[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; static DEFINE_SPINLOCK(timer_lock); -static const char *timer_parent_names[] = {"clk32", "vctcxo_2", "vctcxo_4", "vctcxo"}; +static const char *timer_parent_names[] = {"clk32", "vctcxo_4", "vctcxo_2", "vctcxo"}; static DEFINE_SPINLOCK(reset_lock); --- linux-oracle-5.4.0.orig/drivers/clk/mmp/clk-of-pxa168.c +++ linux-oracle-5.4.0/drivers/clk/mmp/clk-of-pxa168.c @@ -258,18 +258,21 @@ pxa_unit->mpmu_base = of_iomap(np, 0); if (!pxa_unit->mpmu_base) { pr_err("failed to map mpmu registers\n"); + kfree(pxa_unit); return; } pxa_unit->apmu_base = of_iomap(np, 1); if (!pxa_unit->apmu_base) { pr_err("failed to map apmu registers\n"); + kfree(pxa_unit); return; } pxa_unit->apbc_base = of_iomap(np, 2); if (!pxa_unit->apbc_base) { pr_err("failed to map apbc registers\n"); + kfree(pxa_unit); return; } --- linux-oracle-5.4.0.orig/drivers/clk/mvebu/Kconfig +++ linux-oracle-5.4.0/drivers/clk/mvebu/Kconfig @@ -42,6 +42,7 @@ config ARMADA_AP_CPU_CLK bool + select ARMADA_AP_CP_HELPER config ARMADA_CP110_SYSCON bool --- linux-oracle-5.4.0.orig/drivers/clk/mvebu/ap-cpu-clk.c +++ linux-oracle-5.4.0/drivers/clk/mvebu/ap-cpu-clk.c @@ -256,12 +256,15 @@ int cpu, err; err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) + if (WARN_ON(err)) { + of_node_put(dn); return err; + } /* If cpu2 or cpu3 is enabled */ if (cpu & APN806_CLUSTER_NUM_MASK) { nclusters = 2; + of_node_put(dn); break; } } @@ -288,8 +291,10 @@ int cpu, err; err = of_property_read_u32(dn, "reg", &cpu); - if (WARN_ON(err)) + if (WARN_ON(err)) { + of_node_put(dn); return err; + } cluster_index = cpu & APN806_CLUSTER_NUM_MASK; cluster_index >>= APN806_CLUSTER_NUM_OFFSET; @@ -301,6 +306,7 @@ parent = of_clk_get(np, cluster_index); if (IS_ERR(parent)) { dev_err(dev, "Could not get the clock parent\n"); + of_node_put(dn); return -EINVAL; } parent_name = __clk_get_name(parent); @@ -319,8 +325,10 @@ init.parent_names = &parent_name; ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw); - if (ret) + if (ret) { + of_node_put(dn); return ret; + } ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw; } --- linux-oracle-5.4.0.orig/drivers/clk/mvebu/armada-37xx-periph.c +++ linux-oracle-5.4.0/drivers/clk/mvebu/armada-37xx-periph.c @@ -84,6 +84,7 @@ void __iomem *reg_div; u8 shift_div; struct regmap *nb_pm_base; + unsigned long l1_expiration; }; #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw) @@ -438,33 +439,6 @@ return val; } -static int clk_pm_cpu_set_parent(struct clk_hw *hw, u8 index) -{ - struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); - struct regmap *base = pm_cpu->nb_pm_base; - int load_level; - - /* - * We set the clock parent only if the DVFS is available but - * not enabled. - */ - if (IS_ERR(base) || armada_3700_pm_dvfs_is_enabled(base)) - return -EINVAL; - - /* Set the parent clock for all the load level */ - for (load_level = 0; load_level < LOAD_LEVEL_NR; load_level++) { - unsigned int reg, mask, val, - offset = ARMADA_37XX_NB_TBG_SEL_OFF; - - armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); - - val = index << offset; - mask = ARMADA_37XX_NB_TBG_SEL_MASK << offset; - regmap_update_bits(base, reg, mask, val); - } - return 0; -} - static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -512,8 +486,10 @@ } /* - * Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz - * respectively) to L0 frequency (1.2 Ghz) requires a significant + * Workaround when base CPU frequnecy is 1000 or 1200 MHz + * + * Switching the CPU from the L2 or L3 frequencies (250/300 or 200 MHz + * respectively) to L0 frequency (1/1.2 GHz) requires a significant * amount of time to let VDD stabilize to the appropriate * voltage. This amount of time is large enough that it cannot be * covered by the hardware countdown register. Due to this, the CPU @@ -523,26 +499,56 @@ * To work around this problem, we prevent switching directly from the * L2/L3 frequencies to the L0 frequency, and instead switch to the L1 * frequency in-between. The sequence therefore becomes: - * 1. First switch from L2/L3(200/300MHz) to L1(600MHZ) + * 1. First switch from L2/L3 (200/250/300 MHz) to L1 (500/600 MHz) * 2. Sleep 20ms for stabling VDD voltage - * 3. Then switch from L1(600MHZ) to L0(1200Mhz). + * 3. Then switch from L1 (500/600 MHz) to L0 (1000/1200 MHz). */ -static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base) +static void clk_pm_cpu_set_rate_wa(struct clk_pm_cpu *pm_cpu, + unsigned int new_level, unsigned long rate, + struct regmap *base) { unsigned int cur_level; - if (rate != 1200 * 1000 * 1000) - return; - regmap_read(base, ARMADA_37XX_NB_CPU_LOAD, &cur_level); cur_level &= ARMADA_37XX_NB_CPU_LOAD_MASK; - if (cur_level <= ARMADA_37XX_DVFS_LOAD_1) + + if (cur_level == new_level) + return; + + /* + * System wants to go to L1 on its own. If we are going from L2/L3, + * remember when 20ms will expire. If from L0, set the value so that + * next switch to L0 won't have to wait. + */ + if (new_level == ARMADA_37XX_DVFS_LOAD_1) { + if (cur_level == ARMADA_37XX_DVFS_LOAD_0) + pm_cpu->l1_expiration = jiffies; + else + pm_cpu->l1_expiration = jiffies + msecs_to_jiffies(20); return; + } + + /* + * If we are setting to L2/L3, just invalidate L1 expiration time, + * sleeping is not needed. + */ + if (rate < 1000*1000*1000) + goto invalidate_l1_exp; + + /* + * We are going to L0 with rate >= 1GHz. Check whether we have been at + * L1 for long enough time. If not, go to L1 for 20ms. + */ + if (pm_cpu->l1_expiration && jiffies >= pm_cpu->l1_expiration) + goto invalidate_l1_exp; regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD, ARMADA_37XX_NB_CPU_LOAD_MASK, ARMADA_37XX_DVFS_LOAD_1); msleep(20); + +invalidate_l1_exp: + pm_cpu->l1_expiration = 0; } static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, @@ -576,7 +582,9 @@ reg = ARMADA_37XX_NB_CPU_LOAD; mask = ARMADA_37XX_NB_CPU_LOAD_MASK; - clk_pm_cpu_set_rate_wa(rate, base); + /* Apply workaround when base CPU frequency is 1000 or 1200 MHz */ + if (parent_rate >= 1000*1000*1000) + clk_pm_cpu_set_rate_wa(pm_cpu, load_level, rate, base); regmap_update_bits(base, reg, mask, load_level); @@ -590,7 +598,6 @@ static const struct clk_ops clk_pm_cpu_ops = { .get_parent = clk_pm_cpu_get_parent, - .set_parent = clk_pm_cpu_set_parent, .round_rate = clk_pm_cpu_round_rate, .set_rate = clk_pm_cpu_set_rate, .recalc_rate = clk_pm_cpu_recalc_rate, --- linux-oracle-5.4.0.orig/drivers/clk/mvebu/armada-37xx-xtal.c +++ linux-oracle-5.4.0/drivers/clk/mvebu/armada-37xx-xtal.c @@ -13,8 +13,8 @@ #include #include -#define NB_GPIO1_LATCH 0xC -#define XTAL_MODE BIT(31) +#define NB_GPIO1_LATCH 0x8 +#define XTAL_MODE BIT(9) static int armada_3700_xtal_clock_probe(struct platform_device *pdev) { --- linux-oracle-5.4.0.orig/drivers/clk/mvebu/kirkwood.c +++ linux-oracle-5.4.0/drivers/clk/mvebu/kirkwood.c @@ -265,6 +265,7 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { { "powersave", powersave_parents, ARRAY_SIZE(powersave_parents), 11, 1, 0 }, + { } }; static struct clk *clk_muxing_get_src( --- linux-oracle-5.4.0.orig/drivers/clk/pxa/clk-pxa27x.c +++ linux-oracle-5.4.0/drivers/clk/pxa/clk-pxa27x.c @@ -459,6 +459,7 @@ }; static struct dummy_clk dummy_clks[] __initdata = { DUMMY_CLK(NULL, "pxa27x-gpio", "osc_32_768khz"), + DUMMY_CLK(NULL, "pxa-rtc", "osc_32_768khz"), DUMMY_CLK(NULL, "sa1100-rtc", "osc_32_768khz"), DUMMY_CLK("UARTCLK", "pxa2xx-ir", "STUART"), }; --- linux-oracle-5.4.0.orig/drivers/clk/qcom/a53-pll.c +++ linux-oracle-5.4.0/drivers/clk/qcom/a53-pll.c @@ -93,6 +93,7 @@ { .compatible = "qcom,msm8916-a53pll" }, { } }; +MODULE_DEVICE_TABLE(of, qcom_a53pll_match_table); static struct platform_driver qcom_a53pll_driver = { .probe = qcom_a53pll_probe, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/camcc-sdm845.c +++ linux-oracle-5.4.0/drivers/clk/qcom/camcc-sdm845.c @@ -1521,6 +1521,8 @@ }, }; +static struct gdsc titan_top_gdsc; + static struct gdsc bps_gdsc = { .gdscr = 0x6004, .pd = { @@ -1554,6 +1556,7 @@ .name = "ife_0_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -1563,6 +1566,7 @@ .name = "ife_1_gdsc", }, .flags = POLL_CFG_GDSCR, + .parent = &titan_top_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-alpha-pll.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-alpha-pll.c @@ -38,7 +38,7 @@ #define PLL_USER_CTL(p) ((p)->offset + (p)->regs[PLL_OFF_USER_CTL]) # define PLL_POST_DIV_SHIFT 8 -# define PLL_POST_DIV_MASK(p) GENMASK((p)->width, 0) +# define PLL_POST_DIV_MASK(p) GENMASK((p)->width - 1, 0) # define PLL_ALPHA_EN BIT(24) # define PLL_ALPHA_MODE BIT(25) # define PLL_VCO_SHIFT 20 @@ -55,7 +55,6 @@ #define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS]) #define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE]) #define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC]) -#define PLL_CAL_VAL(p) ((p)->offset + (p)->regs[PLL_OFF_CAL_VAL]) const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [CLK_ALPHA_PLL_TYPE_DEFAULT] = { @@ -114,7 +113,6 @@ [PLL_OFF_STATUS] = 0x30, [PLL_OFF_OPMODE] = 0x38, [PLL_OFF_ALPHA_VAL] = 0x40, - [PLL_OFF_CAL_VAL] = 0x44, }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -238,6 +236,8 @@ mask |= config->pre_div_mask; mask |= config->post_div_mask; mask |= config->vco_mask; + mask |= config->alpha_en_mask; + mask |= config->alpha_mode_mask; regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val); @@ -1259,8 +1259,8 @@ } return regmap_update_bits(regmap, PLL_USER_CTL(pll), - PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT, - val << PLL_POST_DIV_SHIFT); + PLL_POST_DIV_MASK(pll) << pll->post_div_shift, + val << pll->post_div_shift); } const struct clk_ops clk_trion_pll_postdiv_ops = { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-krait.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-krait.c @@ -32,11 +32,16 @@ regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT); } krait_set_l2_indirect_reg(mux->offset, regval); - spin_unlock_irqrestore(&krait_clock_reg_lock, flags); /* Wait for switch to complete. */ mb(); udelay(1); + + /* + * Unlock now to make sure the mux register is not + * modified while switching to the new parent. + */ + spin_unlock_irqrestore(&krait_clock_reg_lock, flags); } static int krait_mux_set_parent(struct clk_hw *hw, u8 index) @@ -93,6 +98,8 @@ if (d->lpl) mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift; + else + mask <<= d->shift; spin_lock_irqsave(&krait_clock_reg_lock, flags); val = krait_get_l2_indirect_reg(d->offset); --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-rcg2.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-rcg2.c @@ -146,17 +146,11 @@ static unsigned long calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div) { - if (hid_div) { - rate *= 2; - rate /= hid_div + 1; - } + if (hid_div) + rate = mult_frac(rate, 2, hid_div + 1); - if (mode) { - u64 tmp = rate; - tmp *= m; - do_div(tmp, n); - rate = tmp; - } + if (mode) + rate = mult_frac(rate, m, n); return rate; } @@ -217,9 +211,14 @@ clk_flags = clk_hw_get_flags(hw); p = clk_hw_get_parent_by_index(hw, index); + if (!p) + return -EINVAL; + if (clk_flags & CLK_SET_RATE_PARENT) { rate = f->freq; if (f->pre_div) { + if (!rate) + rate = req->rate; rate /= 2; rate *= f->pre_div + 1; } @@ -258,7 +257,7 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { - u32 cfg, mask; + u32 cfg, mask, d_val, not2d_val, n_minus_m; struct clk_hw *hw = &rcg->clkr.hw; int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src); @@ -277,8 +276,17 @@ if (ret) return ret; + /* Calculate 2d value */ + d_val = f->n; + + n_minus_m = f->n - f->m; + n_minus_m *= 2; + + d_val = clamp_t(u32, d_val, f->m, n_minus_m); + not2d_val = ~d_val & mask; + ret = regmap_update_bits(rcg->clkr.regmap, - RCG_D_OFFSET(rcg), mask, ~f->n); + RCG_D_OFFSET(rcg), mask, not2d_val); if (ret) return ret; } @@ -633,6 +641,7 @@ { 2, 9 }, { 4, 9 }, { 1, 1 }, + { 2, 3 }, { } }; @@ -950,7 +959,7 @@ struct clk_rcg2 *rcg = to_clk_rcg2(hw); struct clk_hw *p; unsigned long prate = 0; - u32 val, mask, cfg, mode; + u32 val, mask, cfg, mode, src; int i, num_parents; regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg); @@ -960,12 +969,12 @@ if (cfg & mask) f->pre_div = cfg & mask; - cfg &= CFG_SRC_SEL_MASK; - cfg >>= CFG_SRC_SEL_SHIFT; + src = cfg & CFG_SRC_SEL_MASK; + src >>= CFG_SRC_SEL_SHIFT; num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { - if (cfg == rcg->parent_map[i].cfg) { + if (src == rcg->parent_map[i].cfg) { f->src = rcg->parent_map[i].src; p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i); prate = clk_hw_get_rate(p); --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-regmap-mux.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-regmap-mux.c @@ -28,7 +28,7 @@ val &= mask; if (mux->parent_map) - return qcom_find_src_index(hw, mux->parent_map, val); + return qcom_find_cfg_index(hw, mux->parent_map, val); return val; } --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-rpmh.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-rpmh.c @@ -143,12 +143,22 @@ != (c->aggr_state & BIT(state)); } +static int clk_rpmh_send(struct clk_rpmh *c, enum rpmh_state state, + struct tcs_cmd *cmd, bool wait) +{ + if (wait) + return rpmh_write(c->dev, state, cmd, 1); + + return rpmh_write_async(c->dev, state, cmd, 1); +} + static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) { struct tcs_cmd cmd = { 0 }; u32 cmd_state, on_val; enum rpmh_state state = RPMH_SLEEP_STATE; int ret; + bool wait; cmd.addr = c->res_addr; cmd_state = c->aggr_state; @@ -159,7 +169,8 @@ if (cmd_state & BIT(state)) cmd.data = on_val; - ret = rpmh_write_async(c->dev, state, &cmd, 1); + wait = cmd_state && state == RPMH_ACTIVE_ONLY_STATE; + ret = clk_rpmh_send(c, state, &cmd, wait); if (ret) { dev_err(c->dev, "set %s state of %s failed: (%d)\n", !state ? "sleep" : @@ -248,38 +259,35 @@ { struct tcs_cmd cmd = { 0 }; u32 cmd_state; - int ret; + int ret = 0; mutex_lock(&rpmh_clk_lock); - - cmd_state = 0; if (enable) { cmd_state = 1; if (c->aggr_state) cmd_state = c->aggr_state; + } else { + cmd_state = 0; } - if (c->last_sent_aggr_state == cmd_state) { - mutex_unlock(&rpmh_clk_lock); - return 0; - } - - cmd.addr = c->res_addr; - cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state); + cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK); - ret = rpmh_write_async(c->dev, RPMH_ACTIVE_ONLY_STATE, &cmd, 1); - if (ret) { - dev_err(c->dev, "set active state of %s failed: (%d)\n", - c->res_name, ret); - mutex_unlock(&rpmh_clk_lock); - return ret; + if (c->last_sent_aggr_state != cmd_state) { + cmd.addr = c->res_addr; + cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state); + + ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable); + if (ret) { + dev_err(c->dev, "set active state of %s failed: (%d)\n", + c->res_name, ret); + } else { + c->last_sent_aggr_state = cmd_state; + } } - c->last_sent_aggr_state = cmd_state; - mutex_unlock(&rpmh_clk_lock); - return 0; + return ret; } static int clk_rpmh_bcm_prepare(struct clk_hw *hw) @@ -323,7 +331,7 @@ { struct clk_rpmh *c = to_clk_rpmh(hw); - return c->aggr_state * c->unit; + return (unsigned long)c->aggr_state * c->unit; } static const struct clk_ops clk_rpmh_bcm_ops = { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/clk-smd-rpm.c +++ linux-oracle-5.4.0/drivers/clk/qcom/clk-smd-rpm.c @@ -648,6 +648,8 @@ }; /* msm8998 */ +DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); +DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); @@ -670,6 +672,10 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); static struct clk_smd_rpm *msm8998_clks[] = { + [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk, + [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk, [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/common.c +++ linux-oracle-5.4.0/drivers/clk/qcom/common.c @@ -29,6 +29,9 @@ if (!f) return NULL; + if (!f->freq) + return f; + for (; f->freq; f++) if (rate <= f->freq) return f; @@ -66,6 +69,18 @@ } EXPORT_SYMBOL_GPL(qcom_find_src_index); +int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, u8 cfg) +{ + int i, num_parents = clk_hw_get_num_parents(hw); + + for (i = 0; i < num_parents; i++) + if (cfg == map[i].cfg) + return i; + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(qcom_find_cfg_index); + struct regmap * qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc) { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/common.h +++ linux-oracle-5.4.0/drivers/clk/qcom/common.h @@ -49,6 +49,8 @@ qcom_pll_set_fsm_mode(struct regmap *m, u32 reg, u8 bias_count, u8 lock_count); extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src); +extern int qcom_find_cfg_index(struct clk_hw *hw, const struct parent_map *map, + u8 cfg); extern int qcom_cc_register_board_clk(struct device *dev, const char *path, const char *name, unsigned long rate); --- linux-oracle-5.4.0.orig/drivers/clk/qcom/dispcc-sdm845.c +++ linux-oracle-5.4.0/drivers/clk/qcom/dispcc-sdm845.c @@ -569,6 +569,8 @@ static struct gdsc mdss_gdsc = { .gdscr = 0x3000, + .en_few_wait_val = 0x6, + .en_rest_wait_val = 0x5, .pd = { .name = "mdss_gdsc", }, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-ipq8074.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-ipq8074.c @@ -423,7 +423,6 @@ }, .num_parents = 1, .ops = &clk_fixed_factor_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -470,7 +469,6 @@ }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -503,7 +501,6 @@ }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -537,7 +534,6 @@ }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -551,7 +547,6 @@ }, .num_parents = 1, .ops = &clk_fixed_factor_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -616,7 +611,6 @@ }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, }; @@ -667,6 +661,7 @@ }, .num_parents = 1, .ops = &clk_branch2_ops, + .flags = CLK_IS_CRITICAL, }, }, }; @@ -977,6 +972,7 @@ static const struct freq_tbl ftbl_pcie_aux_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + { } }; static struct clk_rcg2 pcie0_aux_clk_src = { @@ -1074,7 +1070,7 @@ .name = "sdcc1_apps_clk_src", .parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2, .num_parents = 4, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -1082,6 +1078,7 @@ F(19200000, P_XO, 1, 0, 0), F(160000000, P_GPLL0, 5, 0, 0), F(308570000, P_GPLL6, 3.5, 0, 0), + { } }; static struct clk_rcg2 sdcc1_ice_core_clk_src = { @@ -1788,8 +1785,10 @@ static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), F(25000000, P_UNIPHY1_RX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_RX, 5, 0, 0), F(78125000, P_UNIPHY1_RX, 4, 0, 0), F(125000000, P_UNIPHY1_RX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_RX, 1, 0, 0), F(156250000, P_UNIPHY1_RX, 2, 0, 0), F(312500000, P_UNIPHY1_RX, 1, 0, 0), { } @@ -1828,8 +1827,10 @@ static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), F(25000000, P_UNIPHY1_TX, 12.5, 0, 0), + F(25000000, P_UNIPHY0_TX, 5, 0, 0), F(78125000, P_UNIPHY1_TX, 4, 0, 0), F(125000000, P_UNIPHY1_TX, 2.5, 0, 0), + F(125000000, P_UNIPHY0_TX, 1, 0, 0), F(156250000, P_UNIPHY1_TX, 2, 0, 0), F(312500000, P_UNIPHY1_TX, 1, 0, 0), { } @@ -1867,8 +1868,10 @@ static const struct freq_tbl ftbl_nss_port6_rx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY2_RX, 5, 0, 0), F(25000000, P_UNIPHY2_RX, 12.5, 0, 0), F(78125000, P_UNIPHY2_RX, 4, 0, 0), + F(125000000, P_UNIPHY2_RX, 1, 0, 0), F(125000000, P_UNIPHY2_RX, 2.5, 0, 0), F(156250000, P_UNIPHY2_RX, 2, 0, 0), F(312500000, P_UNIPHY2_RX, 1, 0, 0), @@ -1907,8 +1910,10 @@ static const struct freq_tbl ftbl_nss_port6_tx_clk_src[] = { F(19200000, P_XO, 1, 0, 0), + F(25000000, P_UNIPHY2_TX, 5, 0, 0), F(25000000, P_UNIPHY2_TX, 12.5, 0, 0), F(78125000, P_UNIPHY2_TX, 4, 0, 0), + F(125000000, P_UNIPHY2_TX, 1, 0, 0), F(125000000, P_UNIPHY2_TX, 2.5, 0, 0), F(156250000, P_UNIPHY2_TX, 2, 0, 0), F(312500000, P_UNIPHY2_TX, 1, 0, 0), @@ -3346,6 +3351,7 @@ static struct clk_branch gcc_ubi0_ahb_clk = { .halt_reg = 0x6820c, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x6820c, .enable_mask = BIT(0), @@ -3363,6 +3369,7 @@ static struct clk_branch gcc_ubi0_axi_clk = { .halt_reg = 0x68200, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68200, .enable_mask = BIT(0), @@ -3380,6 +3387,7 @@ static struct clk_branch gcc_ubi0_nc_axi_clk = { .halt_reg = 0x68204, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68204, .enable_mask = BIT(0), @@ -3397,6 +3405,7 @@ static struct clk_branch gcc_ubi0_core_clk = { .halt_reg = 0x68210, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68210, .enable_mask = BIT(0), @@ -3414,6 +3423,7 @@ static struct clk_branch gcc_ubi0_mpt_clk = { .halt_reg = 0x68208, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68208, .enable_mask = BIT(0), @@ -3431,6 +3441,7 @@ static struct clk_branch gcc_ubi1_ahb_clk = { .halt_reg = 0x6822c, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x6822c, .enable_mask = BIT(0), @@ -3448,6 +3459,7 @@ static struct clk_branch gcc_ubi1_axi_clk = { .halt_reg = 0x68220, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68220, .enable_mask = BIT(0), @@ -3465,6 +3477,7 @@ static struct clk_branch gcc_ubi1_nc_axi_clk = { .halt_reg = 0x68224, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68224, .enable_mask = BIT(0), @@ -3482,6 +3495,7 @@ static struct clk_branch gcc_ubi1_core_clk = { .halt_reg = 0x68230, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68230, .enable_mask = BIT(0), @@ -3499,6 +3513,7 @@ static struct clk_branch gcc_ubi1_mpt_clk = { .halt_reg = 0x68228, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x68228, .enable_mask = BIT(0), --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-mdm9615.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-mdm9615.c @@ -58,7 +58,7 @@ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "pll0_vote", - .parent_names = (const char *[]){ "pll8" }, + .parent_names = (const char *[]){ "pll0" }, .num_parents = 1, .ops = &clk_pll_vote_ops, }, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-msm8916.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-msm8916.c @@ -260,7 +260,7 @@ .l_reg = 0x21004, .m_reg = 0x21008, .n_reg = 0x2100c, - .config_reg = 0x21014, + .config_reg = 0x21010, .mode_reg = 0x21000, .status_reg = 0x2101c, .status_bit = 17, @@ -287,7 +287,7 @@ .l_reg = 0x20004, .m_reg = 0x20008, .n_reg = 0x2000c, - .config_reg = 0x20014, + .config_reg = 0x20010, .mode_reg = 0x20000, .status_reg = 0x2001c, .status_bit = 17, @@ -314,7 +314,7 @@ .l_reg = 0x4a004, .m_reg = 0x4a008, .n_reg = 0x4a00c, - .config_reg = 0x4a014, + .config_reg = 0x4a010, .mode_reg = 0x4a000, .status_reg = 0x4a01c, .status_bit = 17, @@ -341,7 +341,7 @@ .l_reg = 0x23004, .m_reg = 0x23008, .n_reg = 0x2300c, - .config_reg = 0x23014, + .config_reg = 0x23010, .mode_reg = 0x23000, .status_reg = 0x2301c, .status_bit = 17, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-msm8994.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-msm8994.c @@ -107,6 +107,7 @@ static struct clk_alpha_pll_postdiv gpll4 = { .offset = 0x1dc0, + .width = 4, .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], .clkr.hw.init = &(struct clk_init_data) { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-msm8996.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-msm8996.c @@ -2937,20 +2937,6 @@ }, }; -static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { - .halt_reg = 0x82014, - .clkr = { - .enable_reg = 0x82014, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre1_pnoc_ahb_clk", - .parent_names = (const char *[]){ "periph_noc_clk_src" }, - .num_parents = 1, - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -3453,7 +3439,6 @@ [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, - [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-msm8998.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-msm8998.c @@ -135,7 +135,7 @@ static struct clk_alpha_pll gpll0 = { .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .vco_table = fabia_vco, .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { @@ -145,58 +145,58 @@ .name = "gpll0", .parent_names = (const char *[]){ "xo" }, .num_parents = 1, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_fabia_ops, } }, }; static struct clk_alpha_pll_postdiv gpll0_out_even = { .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_even", .parent_names = (const char *[]){ "gpll0" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll0_out_main = { .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_main", .parent_names = (const char *[]){ "gpll0" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll0_out_odd = { .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_odd", .parent_names = (const char *[]){ "gpll0" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll0_out_test = { .offset = 0x0, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_test", .parent_names = (const char *[]){ "gpll0" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll gpll1 = { .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .vco_table = fabia_vco, .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { @@ -206,58 +206,58 @@ .name = "gpll1", .parent_names = (const char *[]){ "xo" }, .num_parents = 1, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_fabia_ops, } }, }; static struct clk_alpha_pll_postdiv gpll1_out_even = { .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll1_out_even", .parent_names = (const char *[]){ "gpll1" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll1_out_main = { .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll1_out_main", .parent_names = (const char *[]){ "gpll1" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll1_out_odd = { .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll1_out_odd", .parent_names = (const char *[]){ "gpll1" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll1_out_test = { .offset = 0x1000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll1_out_test", .parent_names = (const char *[]){ "gpll1" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll gpll2 = { .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .vco_table = fabia_vco, .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { @@ -267,58 +267,58 @@ .name = "gpll2", .parent_names = (const char *[]){ "xo" }, .num_parents = 1, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_fabia_ops, } }, }; static struct clk_alpha_pll_postdiv gpll2_out_even = { .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll2_out_even", .parent_names = (const char *[]){ "gpll2" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll2_out_main = { .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll2_out_main", .parent_names = (const char *[]){ "gpll2" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll2_out_odd = { .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll2_out_odd", .parent_names = (const char *[]){ "gpll2" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll2_out_test = { .offset = 0x2000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll2_out_test", .parent_names = (const char *[]){ "gpll2" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll gpll3 = { .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .vco_table = fabia_vco, .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { @@ -328,58 +328,58 @@ .name = "gpll3", .parent_names = (const char *[]){ "xo" }, .num_parents = 1, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_fabia_ops, } }, }; static struct clk_alpha_pll_postdiv gpll3_out_even = { .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll3_out_even", .parent_names = (const char *[]){ "gpll3" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll3_out_main = { .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll3_out_main", .parent_names = (const char *[]){ "gpll3" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll3_out_odd = { .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll3_out_odd", .parent_names = (const char *[]){ "gpll3" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll3_out_test = { .offset = 0x3000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll3_out_test", .parent_names = (const char *[]){ "gpll3" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll gpll4 = { .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .vco_table = fabia_vco, .num_vco = ARRAY_SIZE(fabia_vco), .clkr = { @@ -389,52 +389,52 @@ .name = "gpll4", .parent_names = (const char *[]){ "xo" }, .num_parents = 1, - .ops = &clk_alpha_pll_ops, + .ops = &clk_alpha_pll_fixed_fabia_ops, } }, }; static struct clk_alpha_pll_postdiv gpll4_out_even = { .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll4_out_even", .parent_names = (const char *[]){ "gpll4" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll4_out_main = { .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll4_out_main", .parent_names = (const char *[]){ "gpll4" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll4_out_odd = { .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll4_out_odd", .parent_names = (const char *[]){ "gpll4" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; static struct clk_alpha_pll_postdiv gpll4_out_test = { .offset = 0x77000, - .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], .clkr.hw.init = &(struct clk_init_data){ .name = "gpll4_out_test", .parent_names = (const char *[]){ "gpll4" }, .num_parents = 1, - .ops = &clk_alpha_pll_postdiv_ops, + .ops = &clk_alpha_pll_postdiv_fabia_ops, }, }; --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-qcs404.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-qcs404.c @@ -25,11 +25,9 @@ P_CORE_BI_PLL_TEST_SE, P_DSI0_PHY_PLL_OUT_BYTECLK, P_DSI0_PHY_PLL_OUT_DSICLK, - P_GPLL0_OUT_AUX, P_GPLL0_OUT_MAIN, P_GPLL1_OUT_MAIN, P_GPLL3_OUT_MAIN, - P_GPLL4_OUT_AUX, P_GPLL4_OUT_MAIN, P_GPLL6_OUT_AUX, P_HDMI_PHY_PLL_CLK, @@ -109,28 +107,24 @@ static const struct parent_map gcc_parent_map_5[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_5[] = { "cxo", - "dsi0pll_byteclk_src", - "gpll0_out_aux", + "dsi0pllbyte", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_6[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, - { P_GPLL0_OUT_AUX, 3 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_6[] = { "cxo", - "dsi0_phy_pll_out_byteclk", - "gpll0_out_aux", + "dsi0pllbyte", "core_bi_pll_test_se", }; @@ -139,7 +133,6 @@ { P_GPLL0_OUT_MAIN, 1 }, { P_GPLL3_OUT_MAIN, 2 }, { P_GPLL6_OUT_AUX, 3 }, - { P_GPLL4_OUT_AUX, 4 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; @@ -148,7 +141,6 @@ "gpll0_out_main", "gpll3_out_main", "gpll6_out_aux", - "gpll4_out_aux", "core_bi_pll_test_se", }; @@ -175,7 +167,7 @@ static const char * const gcc_parent_names_9[] = { "cxo", "gpll0_out_main", - "dsi0_phy_pll_out_dsiclk", + "dsi0pll", "gpll6_out_aux", "core_bi_pll_test_se", }; @@ -207,14 +199,12 @@ static const struct parent_map gcc_parent_map_12[] = { { P_XO, 0 }, { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_12[] = { "cxo", - "dsi0pll_pclk_src", - "gpll0_out_aux", + "dsi0pll", "core_bi_pll_test_se", }; @@ -237,40 +227,34 @@ static const struct parent_map gcc_parent_map_14[] = { { P_XO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, - { P_GPLL4_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_14[] = { "cxo", "gpll0_out_main", - "gpll4_out_aux", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_15[] = { { P_XO, 0 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_15[] = { "cxo", - "gpll0_out_aux", "core_bi_pll_test_se", }; static const struct parent_map gcc_parent_map_16[] = { { P_XO, 0 }, { P_GPLL0_OUT_MAIN, 1 }, - { P_GPLL0_OUT_AUX, 2 }, { P_CORE_BI_PLL_TEST_SE, 7 }, }; static const char * const gcc_parent_names_16[] = { "cxo", "gpll0_out_main", - "gpll0_out_aux", "core_bi_pll_test_se", }; @@ -353,6 +337,7 @@ /* 930MHz configuration */ static const struct alpha_pll_config gpll3_config = { .l = 48, + .alpha_hi = 0x70, .alpha = 0x0, .alpha_en_mask = BIT(24), .post_div_mask = 0xf << 8, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-sdm660.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-sdm660.c @@ -666,7 +666,7 @@ .cmd_rcgr = 0x48044, .mnd_width = 0, .hid_width = 5, - .parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div, + .parent_map = gcc_parent_map_xo_gpll0, .freq_tbl = ftbl_hmss_rbcpr_clk_src, .clkr.hw.init = &(struct clk_init_data){ .name = "hmss_rbcpr_clk_src", @@ -1715,6 +1715,9 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { .halt_reg = 0x8a004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x8a004, + .hwcg_bit = 1, .clkr = { .enable_reg = 0x8a004, .enable_mask = BIT(0), --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-sdm845.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-sdm845.c @@ -3255,6 +3255,7 @@ .name = "hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = { @@ -3263,6 +3264,7 @@ .name = "hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = { @@ -3271,6 +3273,7 @@ .name = "hlos1_vote_aggre_noc_mmu_tbu1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = { @@ -3279,6 +3282,7 @@ .name = "hlos1_vote_aggre_noc_mmu_tbu2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { @@ -3287,6 +3291,7 @@ .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = { @@ -3295,6 +3300,7 @@ .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = { @@ -3303,6 +3309,7 @@ .name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct clk_regmap *gcc_sdm845_clocks[] = { @@ -3639,3 +3646,4 @@ MODULE_DESCRIPTION("QTI GCC SDM845 Driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:gcc-sdm845"); +MODULE_SOFTDEP("pre: rpmhpd"); --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gcc-sm8150.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gcc-sm8150.c @@ -75,8 +75,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gpll0_out_even", .parent_data = &(const struct clk_parent_data){ - .fw_name = "bi_tcxo", - .name = "bi_tcxo", + .hw = &gpll0.clkr.hw, }, .num_parents = 1, .ops = &clk_trion_pll_postdiv_ops, @@ -251,7 +250,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_cpuss_ahb_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -274,7 +273,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_emac_ptp_clk_src", .parent_data = gcc_parents_5, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_5), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -300,7 +299,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_emac_rgmii_clk_src", .parent_data = gcc_parents_5, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_5), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -324,7 +323,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_gp1_clk_src", .parent_data = gcc_parents_1, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_1), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -339,7 +338,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_gp2_clk_src", .parent_data = gcc_parents_1, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_1), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -354,7 +353,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_gp3_clk_src", .parent_data = gcc_parents_1, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_1), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -375,7 +374,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pcie_0_aux_clk_src", .parent_data = gcc_parents_2, - .num_parents = 3, + .num_parents = ARRAY_SIZE(gcc_parents_2), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -390,7 +389,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pcie_1_aux_clk_src", .parent_data = gcc_parents_2, - .num_parents = 3, + .num_parents = ARRAY_SIZE(gcc_parents_2), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -411,7 +410,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pcie_phy_refgen_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -433,7 +432,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_pdm2_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -456,7 +455,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qspi_core_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -490,7 +489,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s0_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -505,7 +504,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s1_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -520,7 +519,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s2_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -535,7 +534,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s3_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -550,7 +549,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s4_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -565,7 +564,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s5_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -580,7 +579,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s6_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -595,7 +594,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap0_s7_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -610,7 +609,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s0_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -625,7 +624,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s1_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -640,7 +639,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s2_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -655,7 +654,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s3_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -670,7 +669,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s4_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -685,7 +684,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap1_s5_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -700,7 +699,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s0_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -715,7 +714,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s1_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -730,7 +729,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s2_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -745,7 +744,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s3_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -760,7 +759,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s4_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -775,7 +774,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_qupv3_wrap2_s5_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -801,8 +800,8 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parents_6, - .num_parents = 5, - .flags = CLK_SET_RATE_PARENT, + .num_parents = ARRAY_SIZE(gcc_parents_6), + .flags = CLK_OPS_PARENT_ENABLE, .ops = &clk_rcg2_floor_ops, }, }; @@ -826,7 +825,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_sdcc4_apps_clk_src", .parent_data = gcc_parents_3, - .num_parents = 3, + .num_parents = ARRAY_SIZE(gcc_parents_3), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_floor_ops, }, @@ -846,7 +845,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_tsif_ref_clk_src", .parent_data = gcc_parents_7, - .num_parents = 5, + .num_parents = ARRAY_SIZE(gcc_parents_7), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -870,7 +869,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_axi_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -893,7 +892,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_ice_core_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -913,7 +912,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_phy_aux_clk_src", .parent_data = gcc_parents_4, - .num_parents = 2, + .num_parents = ARRAY_SIZE(gcc_parents_4), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -935,7 +934,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_card_unipro_core_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -959,7 +958,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_axi_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -974,7 +973,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_ice_core_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -989,7 +988,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_phy_aux_clk_src", .parent_data = gcc_parents_4, - .num_parents = 2, + .num_parents = ARRAY_SIZE(gcc_parents_4), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1004,7 +1003,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_ufs_phy_unipro_core_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1028,7 +1027,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_master_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1050,7 +1049,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_prim_mock_utmi_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1065,7 +1064,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_sec_master_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1080,7 +1079,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb30_sec_mock_utmi_clk_src", .parent_data = gcc_parents_0, - .num_parents = 4, + .num_parents = ARRAY_SIZE(gcc_parents_0), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1095,7 +1094,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb3_prim_phy_aux_clk_src", .parent_data = gcc_parents_2, - .num_parents = 3, + .num_parents = ARRAY_SIZE(gcc_parents_2), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1110,7 +1109,7 @@ .clkr.hw.init = &(struct clk_init_data){ .name = "gcc_usb3_sec_phy_aux_clk_src", .parent_data = gcc_parents_2, - .num_parents = 3, + .num_parents = ARRAY_SIZE(gcc_parents_2), .flags = CLK_SET_RATE_PARENT, .ops = &clk_rcg2_ops, }, @@ -1616,6 +1615,38 @@ }, }; +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gpll0.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gpll0_out_even.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_gpu_iref_clk = { .halt_reg = 0x8c010, .halt_check = BRANCH_HALT, @@ -1698,6 +1729,38 @@ }, }; +static struct clk_branch gcc_npu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gpll0.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_npu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52004, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_npu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw *[]){ + &gpll0_out_even.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_npu_trig_clk = { .halt_reg = 0x4d00c, .halt_check = BRANCH_VOTED, @@ -2812,6 +2875,45 @@ }, }; +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x750ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x75018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_card_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ufs_card_unipro_core_clk = { .halt_reg = 0x75058, .halt_check = BRANCH_HALT, @@ -2992,6 +3094,45 @@ }, }; +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x7701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x770ac, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +/* external clocks so add BRANCH_HALT_SKIP */ +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_ufs_phy_unipro_core_clk = { .halt_reg = 0x77058, .halt_check = BRANCH_HALT, @@ -3332,12 +3473,16 @@ [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, [GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr, [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, [GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr, [GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr, [GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr, + [GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr, + [GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr, [GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr, [GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr, [GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr, @@ -3442,6 +3587,9 @@ [GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr, [GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_card_phy_aux_hw_ctl_clk.clkr, + [GCC_UFS_CARD_RX_SYMBOL_0_CLK] = &gcc_ufs_card_rx_symbol_0_clk.clkr, + [GCC_UFS_CARD_RX_SYMBOL_1_CLK] = &gcc_ufs_card_rx_symbol_1_clk.clkr, + [GCC_UFS_CARD_TX_SYMBOL_0_CLK] = &gcc_ufs_card_tx_symbol_0_clk.clkr, [GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr, [GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_card_unipro_core_clk_src.clkr, @@ -3459,6 +3607,9 @@ [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, [GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr, --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gdsc.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gdsc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved. */ #include @@ -31,9 +31,14 @@ #define CFG_GDSCR_OFFSET 0x4 /* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */ -#define EN_REST_WAIT_VAL (0x2 << 20) -#define EN_FEW_WAIT_VAL (0x8 << 16) -#define CLK_DIS_WAIT_VAL (0x2 << 12) +#define EN_REST_WAIT_VAL 0x2 +#define EN_FEW_WAIT_VAL 0x8 +#define CLK_DIS_WAIT_VAL 0x2 + +/* Transition delay shifts */ +#define EN_REST_WAIT_SHIFT 20 +#define EN_FEW_WAIT_SHIFT 16 +#define CLK_DIS_WAIT_SHIFT 12 #define RETAIN_MEM BIT(14) #define RETAIN_PERIPH BIT(13) @@ -308,7 +313,18 @@ */ mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK | EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK; - val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL; + + if (!sc->en_rest_wait_val) + sc->en_rest_wait_val = EN_REST_WAIT_VAL; + if (!sc->en_few_wait_val) + sc->en_few_wait_val = EN_FEW_WAIT_VAL; + if (!sc->clk_dis_wait_val) + sc->clk_dis_wait_val = CLK_DIS_WAIT_VAL; + + val = sc->en_rest_wait_val << EN_REST_WAIT_SHIFT | + sc->en_few_wait_val << EN_FEW_WAIT_SHIFT | + sc->clk_dis_wait_val << CLK_DIS_WAIT_SHIFT; + ret = regmap_update_bits(sc->regmap, sc->gdscr, mask, val); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gdsc.h +++ linux-oracle-5.4.0/drivers/clk/qcom/gdsc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015, 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved. */ #ifndef __QCOM_GDSC_H__ @@ -21,6 +21,9 @@ * @cxcs: offsets of branch registers to toggle mem/periph bits in * @cxc_count: number of @cxcs * @pwrsts: Possible powerdomain power states + * @en_rest_wait_val: transition delay value for receiving enr ack signal + * @en_few_wait_val: transition delay value for receiving enf ack signal + * @clk_dis_wait_val: transition delay value for halting clock * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller @@ -34,6 +37,9 @@ unsigned int clamp_io_ctrl; unsigned int *cxcs; unsigned int cxc_count; + unsigned int en_rest_wait_val; + unsigned int en_few_wait_val; + unsigned int clk_dis_wait_val; const u8 pwrsts; /* Powerdomain allowable state bitfields */ #define PWRSTS_OFF BIT(0) --- linux-oracle-5.4.0.orig/drivers/clk/qcom/gpucc-sdm845.c +++ linux-oracle-5.4.0/drivers/clk/qcom/gpucc-sdm845.c @@ -22,8 +22,6 @@ #define CX_GMU_CBCR_SLEEP_SHIFT 4 #define CX_GMU_CBCR_WAKE_MASK 0xf #define CX_GMU_CBCR_WAKE_SHIFT 8 -#define CLK_DIS_WAIT_SHIFT 12 -#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT) enum { P_BI_TCXO, @@ -124,6 +122,7 @@ static struct gdsc gpu_cx_gdsc = { .gdscr = 0x106c, .gds_hw_ctrl = 0x1540, + .clk_dis_wait_val = 0x8, .pd = { .name = "gpu_cx_gdsc", }, @@ -221,10 +220,6 @@ value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT; regmap_update_bits(regmap, 0x1098, mask, value); - /* Configure clk_dis_wait for gpu_cx_gdsc */ - regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK, - 8 << CLK_DIS_WAIT_SHIFT); - return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap); } --- linux-oracle-5.4.0.orig/drivers/clk/qcom/mmcc-apq8084.c +++ linux-oracle-5.4.0/drivers/clk/qcom/mmcc-apq8084.c @@ -333,6 +333,7 @@ F(333430000, P_MMPLL1, 3.5, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), F(466800000, P_MMPLL1, 2.5, 0, 0), + { } }; static struct clk_rcg2 mmss_axi_clk_src = { @@ -357,6 +358,7 @@ F(150000000, P_GPLL0, 4, 0, 0), F(228570000, P_MMPLL0, 3.5, 0, 0), F(320000000, P_MMPLL0, 2.5, 0, 0), + { } }; static struct clk_rcg2 ocmemnoc_clk_src = { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/mmcc-msm8974.c +++ linux-oracle-5.4.0/drivers/clk/qcom/mmcc-msm8974.c @@ -283,6 +283,7 @@ F(291750000, P_MMPLL1, 4, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), F(466800000, P_MMPLL1, 2.5, 0, 0), + { } }; static struct clk_rcg2 mmss_axi_clk_src = { @@ -307,6 +308,7 @@ F(150000000, P_GPLL0, 4, 0, 0), F(291750000, P_MMPLL1, 4, 0, 0), F(400000000, P_MMPLL0, 2, 0, 0), + { } }; static struct clk_rcg2 ocmemnoc_clk_src = { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/reset.c +++ linux-oracle-5.4.0/drivers/clk/qcom/reset.c @@ -13,14 +13,16 @@ static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) { + struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); + rcdev->ops->assert(rcdev, id); - udelay(1); + udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ rcdev->ops->deassert(rcdev, id); return 0; } -static int -qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +static int qcom_reset_set_assert(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) { struct qcom_reset_controller *rst; const struct qcom_reset_map *map; @@ -28,23 +30,24 @@ rst = to_qcom_reset_controller(rcdev); map = &rst->reset_map[id]; - mask = BIT(map->bit); + mask = map->bitmask ? map->bitmask : BIT(map->bit); + + regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0); + + /* Read back the register to ensure write completion, ignore the value */ + regmap_read(rst->regmap, map->reg, &mask); - return regmap_update_bits(rst->regmap, map->reg, mask, mask); + return 0; } -static int -qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { - struct qcom_reset_controller *rst; - const struct qcom_reset_map *map; - u32 mask; - - rst = to_qcom_reset_controller(rcdev); - map = &rst->reset_map[id]; - mask = BIT(map->bit); + return qcom_reset_set_assert(rcdev, id, true); +} - return regmap_update_bits(rst->regmap, map->reg, mask, 0); +static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + return qcom_reset_set_assert(rcdev, id, false); } const struct reset_control_ops qcom_reset_ops = { --- linux-oracle-5.4.0.orig/drivers/clk/qcom/reset.h +++ linux-oracle-5.4.0/drivers/clk/qcom/reset.h @@ -11,6 +11,8 @@ struct qcom_reset_map { unsigned int reg; u8 bit; + u8 udelay; + u32 bitmask; }; struct regmap; --- linux-oracle-5.4.0.orig/drivers/clk/renesas/r7s9210-cpg-mssr.c +++ linux-oracle-5.4.0/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -213,7 +213,7 @@ .cpg_clk_register = rza2_cpg_clk_register, /* RZ/A2 has Standby Control Registers */ - .stbyctrl = true, + .reg_layout = CLK_REG_LAYOUT_RZ_A, }; static void __init r7s9210_cpg_mssr_early_init(struct device_node *np) --- linux-oracle-5.4.0.orig/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ linux-oracle-5.4.0/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -75,6 +75,7 @@ DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), /* Core Clock Outputs */ + DEF_FIXED("za2", R8A77995_CLK_ZA2, CLK_PLL0D3, 2, 1), DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), --- linux-oracle-5.4.0.orig/drivers/clk/renesas/r9a06g032-clocks.c +++ linux-oracle-5.4.0/drivers/clk/renesas/r9a06g032-clocks.c @@ -55,7 +55,7 @@ u16 sel, g1, r1, g2, r2; } dual; }; -} __packed; +}; #define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) \ { .gate = _clk, .reset = _rst, \ @@ -286,8 +286,8 @@ .name = "uart_group_012", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_UART, - /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ - .dual.sel = ((0xec / 4) << 5) | 24, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ + .dual.sel = ((0x34 / 4) << 5) | 30, .dual.group = 0, }, { @@ -295,8 +295,8 @@ .name = "uart_group_34567", .type = K_BITSEL, .source = 1 + R9A06G032_DIV_P2_PG, - /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ - .dual.sel = ((0x34 / 4) << 5) | 30, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ + .dual.sel = ((0xec / 4) << 5) | 24, .dual.group = 1, }, D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5), @@ -386,7 +386,7 @@ int error; int index; - while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, &clkspec)) { if (clkspec.np != pd->dev.of_node) continue; @@ -399,7 +399,6 @@ if (error) return error; } - i++; } return 0; --- linux-oracle-5.4.0.orig/drivers/clk/renesas/rcar-gen3-cpg.c +++ linux-oracle-5.4.0/drivers/clk/renesas/rcar-gen3-cpg.c @@ -464,7 +464,8 @@ clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, &rpc->div.hw, &clk_divider_ops, - &rpc->gate.hw, &clk_gate_ops, 0); + &rpc->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) { kfree(rpc); return clk; @@ -500,7 +501,8 @@ clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL, &rpcd2->fixed.hw, &clk_fixed_factor_ops, - &rpcd2->gate.hw, &clk_gate_ops, 0); + &rpcd2->gate.hw, &clk_gate_ops, + CLK_SET_RATE_PARENT); if (IS_ERR(clk)) kfree(rpcd2); --- linux-oracle-5.4.0.orig/drivers/clk/renesas/renesas-cpg-mssr.c +++ linux-oracle-5.4.0/drivers/clk/renesas/renesas-cpg-mssr.c @@ -111,12 +111,12 @@ * @rcdev: Optional reset controller entity * @dev: CPG/MSSR device * @base: CPG/MSSR register block base address + * @reg_layout: CPG/MSSR register layout * @rmw_lock: protects RMW register accesses * @np: Device node in DT for this CPG/MSSR module * @num_core_clks: Number of Core Clocks in clks[] * @num_mod_clks: Number of Module Clocks in clks[] * @last_dt_core_clk: ID of the last Core Clock exported to DT - * @stbyctrl: This device has Standby Control Registers * @notifiers: Notifier chain to save/restore clock state for system resume * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control * @smstpcr_saved[].val: Saved values of SMSTPCR[] @@ -128,13 +128,13 @@ #endif struct device *dev; void __iomem *base; + enum clk_reg_layout reg_layout; spinlock_t rmw_lock; struct device_node *np; unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; - bool stbyctrl; struct raw_notifier_head notifiers; struct { @@ -177,7 +177,7 @@ enable ? "ON" : "OFF"); spin_lock_irqsave(&priv->rmw_lock, flags); - if (priv->stbyctrl) { + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { value = readb(priv->base + STBCR(reg)); if (enable) value &= ~bitmask; @@ -199,7 +199,7 @@ spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (!enable || priv->stbyctrl) + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) return 0; for (i = 1000; i > 0; --i) { @@ -233,7 +233,7 @@ struct cpg_mssr_priv *priv = clock->priv; u32 value; - if (priv->stbyctrl) + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) value = readb(priv->base + STBCR(clock->index / 32)); else value = readl(priv->base + MSTPSR(clock->index / 32)); @@ -272,7 +272,7 @@ case CPG_MOD: type = "module"; - if (priv->stbyctrl) { + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { idx = MOD_CLK_PACK_10(clkidx); range_check = 7 - (clkidx % 10); } else { @@ -801,6 +801,8 @@ for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { if (priv->smstpcr_saved[reg].mask) priv->smstpcr_saved[reg].val = + priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? + readb(priv->base + STBCR(reg)) : readl(priv->base + SMSTPCR(reg)); } @@ -829,7 +831,7 @@ if (!mask) continue; - if (priv->stbyctrl) + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) oldval = readb(priv->base + STBCR(reg)); else oldval = readl(priv->base + SMSTPCR(reg)); @@ -838,7 +840,7 @@ if (newval == oldval) continue; - if (priv->stbyctrl) { + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { writeb(newval, priv->base + STBCR(reg)); /* dummy read to ensure write has completed */ readb(priv->base + STBCR(reg)); @@ -860,8 +862,8 @@ } if (!i) - dev_warn(dev, "Failed to enable SMSTP %p[0x%x]\n", - priv->base + SMSTPCR(reg), oldval & mask); + dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, + oldval & mask); } return 0; @@ -905,12 +907,11 @@ goto out_err; } - cpg_mssr_priv = priv; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); - priv->stbyctrl = info->stbyctrl; + priv->reg_layout = info->reg_layout; for (i = 0; i < nclks; i++) priv->clks[i] = ERR_PTR(-ENOENT); @@ -919,6 +920,8 @@ if (error) goto out_err; + cpg_mssr_priv = priv; + return 0; out_err: @@ -988,7 +991,7 @@ return error; /* Reset Controller not supported for Standby Control SoCs */ - if (info->stbyctrl) + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) return 0; error = cpg_mssr_reset_controller_register(priv); --- linux-oracle-5.4.0.orig/drivers/clk/renesas/renesas-cpg-mssr.h +++ linux-oracle-5.4.0/drivers/clk/renesas/renesas-cpg-mssr.h @@ -85,6 +85,11 @@ struct device_node; +enum clk_reg_layout { + CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3 = 0, + CLK_REG_LAYOUT_RZ_A, +}; + /** * SoC-specific CPG/MSSR Description * @@ -105,6 +110,7 @@ * @crit_mod_clks: Array with Module Clock IDs of critical clocks that * should not be disabled without a knowledgeable driver * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + * @reg_layout: CPG/MSSR register layout from enum clk_reg_layout * * @core_pm_clks: Array with IDs of Core Clocks that are suitable for Power * Management, in addition to Module Clocks @@ -112,10 +118,6 @@ * * @init: Optional callback to perform SoC-specific initialization * @cpg_clk_register: Optional callback to handle special Core Clock types - * - * @stbyctrl: This device has Standby Control Registers which are 8-bits - * wide, no status registers (MSTPSR) and have different address - * offsets. */ struct cpg_mssr_info { @@ -130,7 +132,7 @@ unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; - bool stbyctrl; + enum clk_reg_layout reg_layout; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-half-divider.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-half-divider.c @@ -167,7 +167,7 @@ unsigned long flags, spinlock_t *lock) { - struct clk *clk; + struct clk *clk = ERR_PTR(-ENOMEM); struct clk_mux *mux = NULL; struct clk_gate *gate = NULL; struct clk_divider *div = NULL; --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-pll.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-pll.c @@ -963,6 +963,7 @@ return mux_clk; err_pll: + kfree(pll->rate_table); clk_unregister(mux_clk); mux_clk = pll_clk; err_mux: --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-rk3128.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-rk3128.c @@ -489,7 +489,7 @@ GATE(HCLK_I2S_2CH, "hclk_i2s_2ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), GATE(0, "hclk_usb_peri", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 13, GFLAGS), GATE(HCLK_HOST2, "hclk_host2", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), - GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 13, GFLAGS), + GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK2928_CLKGATE_CON(5), 13, GFLAGS), GATE(0, "hclk_peri_ahb", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 14, GFLAGS), GATE(HCLK_SPDIF, "hclk_spdif", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), GATE(HCLK_TSP, "hclk_tsp", "hclk_peri", 0, RK2928_CLKGATE_CON(10), 12, GFLAGS), --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-rk3188.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-rk3188.c @@ -751,6 +751,7 @@ "pclk_peri", "hclk_cpubus", "hclk_vio_bus", + "sclk_mac_lbtest", }; static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np) --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-rk3228.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-rk3228.c @@ -137,7 +137,7 @@ PNAME(mux_hdmiphy_p) = { "hdmiphy_phy", "xin24m" }; PNAME(mux_aclk_cpu_src_p) = { "cpll_aclk_cpu", "gpll_aclk_cpu", "hdmiphy_aclk_cpu" }; -PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "hdmiphy" "usb480m" }; +PNAME(mux_pll_src_4plls_p) = { "cpll", "gpll", "hdmiphy", "usb480m" }; PNAME(mux_pll_src_3plls_p) = { "cpll", "gpll", "hdmiphy" }; PNAME(mux_pll_src_2plls_p) = { "cpll", "gpll" }; PNAME(mux_sclk_hdmi_cec_p) = { "cpll", "gpll", "xin24m" }; @@ -156,8 +156,6 @@ PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" }; PNAME(mux_sclk_spdif_p) = { "sclk_spdif_src", "spdif_frac", "xin12m" }; -PNAME(mux_aclk_gpu_pre_p) = { "cpll_gpu", "gpll_gpu", "hdmiphy_gpu", "usb480m_gpu" }; - PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; @@ -410,7 +408,7 @@ RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), - MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, + MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), FACTOR(0, "xin12m", "xin24m", 0, 1, 2), @@ -468,16 +466,9 @@ RK2928_CLKSEL_CON(24), 6, 10, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), - GATE(0, "cpll_gpu", "cpll", 0, - RK2928_CLKGATE_CON(3), 13, GFLAGS), - GATE(0, "gpll_gpu", "gpll", 0, - RK2928_CLKGATE_CON(3), 13, GFLAGS), - GATE(0, "hdmiphy_gpu", "hdmiphy", 0, - RK2928_CLKGATE_CON(3), 13, GFLAGS), - GATE(0, "usb480m_gpu", "usb480m", 0, + COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_4plls_p, 0, + RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 13, GFLAGS), - COMPOSITE_NOGATE(0, "aclk_gpu_pre", mux_aclk_gpu_pre_p, 0, - RK2928_CLKSEL_CON(34), 5, 2, MFLAGS, 0, 5, DFLAGS), COMPOSITE(SCLK_SPI0, "sclk_spi0", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(25), 8, 1, MFLAGS, 0, 7, DFLAGS, @@ -582,8 +573,8 @@ GATE(0, "pclk_peri_noc", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(12), 2, GFLAGS), /* PD_GPU */ - GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 14, GFLAGS), - GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(13), 15, GFLAGS), + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 14, GFLAGS), + GATE(0, "aclk_gpu_noc", "aclk_gpu_pre", 0, RK2928_CLKGATE_CON(7), 15, GFLAGS), /* PD_BUS */ GATE(0, "sclk_initmem_mbist", "aclk_cpu", 0, RK2928_CLKGATE_CON(8), 1, GFLAGS), --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk-rk3399.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk-rk3399.c @@ -1259,7 +1259,7 @@ RK3399_CLKSEL_CON(56), 6, 2, MFLAGS, RK3399_CLKGATE_CON(10), 7, GFLAGS), - COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0, + COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS), /* gic */ --- linux-oracle-5.4.0.orig/drivers/clk/rockchip/clk.c +++ linux-oracle-5.4.0/drivers/clk/rockchip/clk.c @@ -439,12 +439,13 @@ struct rockchip_clk_branch *list, unsigned int nr_clk) { - struct clk *clk = NULL; + struct clk *clk; unsigned int idx; unsigned long flags; for (idx = 0; idx < nr_clk; idx++, list++) { flags = list->flags; + clk = NULL; /* catch simple muxes */ switch (list->branch_type) { --- linux-oracle-5.4.0.orig/drivers/clk/samsung/clk-exynos4.c +++ linux-oracle-5.4.0/drivers/clk/samsung/clk-exynos4.c @@ -927,7 +927,7 @@ GATE(CLK_PCIE, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0), GATE(CLK_SMMU_PCIE, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), GATE(CLK_MODEMIF, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), - GATE(CLK_CHIPID, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), + GATE(CLK_CHIPID, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, CLK_IGNORE_UNUSED, 0), GATE(CLK_SYSREG, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, CLK_IGNORE_UNUSED, 0), GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, @@ -969,7 +969,7 @@ 0), GATE(CLK_TSADC, "tsadc", "aclk133", E4X12_GATE_BUS_FSYS1, 16, 0, 0), GATE(CLK_MIPI_HSI, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), - GATE(CLK_CHIPID, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), + GATE(CLK_CHIPID, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, CLK_IGNORE_UNUSED, 0), GATE(CLK_SYSREG, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, CLK_IGNORE_UNUSED, 0), GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, --- linux-oracle-5.4.0.orig/drivers/clk/samsung/clk-exynos5420.c +++ linux-oracle-5.4.0/drivers/clk/samsung/clk-exynos5420.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "clk.h" #include "clk-cpu.h" @@ -165,6 +166,8 @@ GATE_BUS_CPU, GATE_SCLK_CPU, CLKOUT_CMU_CPU, + APLL_CON0, + KPLL_CON0, CPLL_CON0, DPLL_CON0, EPLL_CON0, @@ -537,7 +540,7 @@ static const struct samsung_gate_clock exynos5800_gate_clks[] __initconst = { GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam", - GATE_BUS_TOP, 24, 0, 0), + GATE_BUS_TOP, 24, CLK_IS_CRITICAL, 0), GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), }; @@ -937,25 +940,25 @@ GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg", GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk333_432_isp0", "mout_user_aclk333_432_isp0", - GATE_BUS_TOP, 5, 0, 0), + GATE_BUS_TOP, 5, CLK_IS_CRITICAL, 0), GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl", GATE_BUS_TOP, 6, CLK_IS_CRITICAL, 0), GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl", GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp", - GATE_BUS_TOP, 8, 0, 0), + GATE_BUS_TOP, 8, CLK_IS_CRITICAL, 0), GATE(CLK_PCLK66_GPIO, "pclk66_gpio", "mout_user_pclk66_gpio", GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen", GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk266_isp", "mout_user_aclk266_isp", - GATE_BUS_TOP, 13, 0, 0), + GATE_BUS_TOP, 13, CLK_IS_CRITICAL, 0), GATE(0, "aclk166", "mout_user_aclk166", GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0), GATE(CLK_ACLK333, "aclk333", "mout_user_aclk333", GATE_BUS_TOP, 15, CLK_IS_CRITICAL, 0), GATE(0, "aclk400_isp", "mout_user_aclk400_isp", - GATE_BUS_TOP, 16, 0, 0), + GATE_BUS_TOP, 16, CLK_IS_CRITICAL, 0), GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl", GATE_BUS_TOP, 17, CLK_IS_CRITICAL, 0), GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1", @@ -1155,8 +1158,10 @@ GATE_IP_GSCL1, 3, 0, 0), GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333", GATE_IP_GSCL1, 4, 0, 0), - GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0), - GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0), + GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, + CLK_IS_CRITICAL, 0), + GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, + CLK_IS_CRITICAL, 0), GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333", GATE_IP_GSCL1, 16, 0, 0), GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl", @@ -1628,6 +1633,13 @@ exynos5x_subcmus); } + /* + * Keep top part of G3D clock path enabled permanently to ensure + * that the internal busses get their clock regardless of the + * main G3D clock enablement status. + */ + clk_prepare_enable(__clk_lookup("mout_sw_aclk_g3d")); + samsung_clk_of_add_provider(np, ctx); } --- linux-oracle-5.4.0.orig/drivers/clk/samsung/clk-exynos5433.c +++ linux-oracle-5.4.0/drivers/clk/samsung/clk-exynos5433.c @@ -1706,7 +1706,8 @@ GATE(CLK_SCLK_PCM1, "sclk_pcm1", "sclk_pcm1_peric", ENABLE_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_I2S1, "sclk_i2s1", "sclk_i2s1_peric", - ENABLE_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0), + ENABLE_SCLK_PERIC, 6, + CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 0), GATE(CLK_SCLK_SPI2, "sclk_spi2", "sclk_spi2_peric", ENABLE_SCLK_PERIC, 5, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPI1, "sclk_spi1", "sclk_spi1_peric", ENABLE_SCLK_PERIC, --- linux-oracle-5.4.0.orig/drivers/clk/samsung/clk-exynos7.c +++ linux-oracle-5.4.0/drivers/clk/samsung/clk-exynos7.c @@ -537,8 +537,13 @@ GATE(CLK_ACLK_FSYS0_200, "aclk_fsys0_200", "dout_aclk_fsys0_200", ENABLE_ACLK_TOP13, 28, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 0), + /* + * This clock is required for the CMU_FSYS1 registers access, keep it + * enabled permanently until proper runtime PM support is added. + */ GATE(CLK_ACLK_FSYS1_200, "aclk_fsys1_200", "dout_aclk_fsys1_200", - ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT, 0), + ENABLE_ACLK_TOP13, 24, CLK_SET_RATE_PARENT | + CLK_IS_CRITICAL, 0), GATE(CLK_SCLK_PHY_FSYS1_26M, "sclk_phy_fsys1_26m", "dout_sclk_phy_fsys1_26m", ENABLE_SCLK_TOP1_FSYS11, --- linux-oracle-5.4.0.orig/drivers/clk/samsung/clk-pll.c +++ linux-oracle-5.4.0/drivers/clk/samsung/clk-pll.c @@ -1390,6 +1390,7 @@ if (ret) { pr_err("%s: failed to register pll clock %s : %d\n", __func__, pll_clk->name, ret); + kfree(pll->rate_table); kfree(pll); return; } --- linux-oracle-5.4.0.orig/drivers/clk/sifive/fu540-prci.c +++ linux-oracle-5.4.0/drivers/clk/sifive/fu540-prci.c @@ -586,7 +586,10 @@ struct __prci_data *pd; int r; - pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); + pd = devm_kzalloc(dev, + struct_size(pd, hw_clks.hws, + ARRAY_SIZE(__prci_init_clocks)), + GFP_KERNEL); if (!pd) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/clk/sirf/clk-atlas6.c +++ linux-oracle-5.4.0/drivers/clk/sirf/clk-atlas6.c @@ -135,7 +135,7 @@ for (i = pll1; i < maxclk; i++) { atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]); - BUG_ON(!atlas6_clks[i]); + BUG_ON(IS_ERR(atlas6_clks[i])); } clk_register_clkdev(atlas6_clks[cpu], NULL, "cpu"); clk_register_clkdev(atlas6_clks[io], NULL, "io"); --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-gate-a10.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-gate-a10.c @@ -146,6 +146,7 @@ if (IS_ERR(socfpga_clk->sys_mgr_base_addr)) { pr_err("%s: failed to find altr,sys-mgr regmap!\n", __func__); + kfree(socfpga_clk); return; } } --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-gate.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-gate.c @@ -99,7 +99,7 @@ val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; val &= GENMASK(socfpgaclk->width - 1, 0); /* Check for GPIO_DB_CLK by its offset */ - if ((int) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET) + if ((uintptr_t) socfpgaclk->div_reg & SOCFPGA_GPIO_DB_CLK_OFFSET) div = val + 1; else div = (1 << val); @@ -174,21 +174,24 @@ u32 div_reg[3]; u32 clk_phase[2]; u32 fixed_div; - struct clk *clk; + struct clk_hw *hw_clk; struct socfpga_gate_clk *socfpga_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; struct clk_ops *ops; int rc; + int err; socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (WARN_ON(!socfpga_clk)) return; ops = kmemdup(&gateclk_ops, sizeof(gateclk_ops), GFP_KERNEL); - if (WARN_ON(!ops)) + if (WARN_ON(!ops)) { + kfree(socfpga_clk); return; + } rc = of_property_read_u32_array(node, "clk-gate", clk_gate, 2); if (rc) @@ -238,12 +241,15 @@ init.parent_names = parent_name; socfpga_clk->hw.hw.init = &init; - clk = clk_register(NULL, &socfpga_clk->hw.hw); - if (WARN_ON(IS_ERR(clk))) { + hw_clk = &socfpga_clk->hw.hw; + + err = clk_hw_register(NULL, hw_clk); + if (err) { + kfree(ops); kfree(socfpga_clk); return; } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); + rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); if (WARN_ON(rc)) return; } --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-periph.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-periph.c @@ -51,7 +51,7 @@ const struct clk_ops *ops) { u32 reg; - struct clk *clk; + struct clk_hw *hw_clk; struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; @@ -94,13 +94,13 @@ init.parent_names = parent_name; periph_clk->hw.hw.init = &init; + hw_clk = &periph_clk->hw.hw; - clk = clk_register(NULL, &periph_clk->hw.hw); - if (WARN_ON(IS_ERR(clk))) { + if (clk_hw_register(NULL, hw_clk)) { kfree(periph_clk); return; } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); + rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); } void __init socfpga_periph_init(struct device_node *node) --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-pll-s10.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-pll-s10.c @@ -39,7 +39,9 @@ /* read VCO1 reg for numerator and denominator */ reg = readl(socfpgaclk->hw.reg); refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; - vco_freq = (unsigned long long)parent_rate / refdiv; + + vco_freq = parent_rate; + do_div(vco_freq, refdiv); /* Read mdiv and fdiv from the fdbck register */ reg = readl(socfpgaclk->hw.reg + 0x4); --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-pll.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-pll.c @@ -70,17 +70,18 @@ .get_parent = clk_pll_get_parent, }; -static __init struct clk *__socfpga_pll_init(struct device_node *node, +static __init struct clk_hw *__socfpga_pll_init(struct device_node *node, const struct clk_ops *ops) { u32 reg; - struct clk *clk; + struct clk_hw *hw_clk; struct socfpga_pll *pll_clk; const char *clk_name = node->name; const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; struct device_node *clkmgr_np; int rc; + int err; of_property_read_u32(node, "reg", ®); @@ -108,13 +109,15 @@ clk_pll_ops.enable = clk_gate_ops.enable; clk_pll_ops.disable = clk_gate_ops.disable; - clk = clk_register(NULL, &pll_clk->hw.hw); - if (WARN_ON(IS_ERR(clk))) { + hw_clk = &pll_clk->hw.hw; + + err = clk_hw_register(NULL, hw_clk); + if (err) { kfree(pll_clk); - return NULL; + return ERR_PTR(err); } - rc = of_clk_add_provider(node, of_clk_src_simple_get, clk); - return clk; + rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); + return hw_clk; } void __init socfpga_pll_init(struct device_node *node) --- linux-oracle-5.4.0.orig/drivers/clk/socfpga/clk-s10.c +++ linux-oracle-5.4.0/drivers/clk/socfpga/clk-s10.c @@ -107,7 +107,7 @@ { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), 0, 0, 2, 0xB0, 1}, { STRATIX10_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL, emac_ptp_free_mux, - ARRAY_SIZE(emac_ptp_free_mux), 0, 0, 4, 0xB0, 2}, + ARRAY_SIZE(emac_ptp_free_mux), 0, 0, 2, 0xB0, 2}, { STRATIX10_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, ARRAY_SIZE(gpio_db_free_mux), 0, 0, 0, 0xB0, 3}, { STRATIX10_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, --- linux-oracle-5.4.0.orig/drivers/clk/sprd/common.c +++ linux-oracle-5.4.0/drivers/clk/sprd/common.c @@ -46,7 +46,7 @@ if (of_find_property(node, "sprd,syscon", NULL)) { regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon"); - if (IS_ERR_OR_NULL(regmap)) { + if (IS_ERR(regmap)) { pr_err("%s: failed to get syscon regmap\n", __func__); return PTR_ERR(regmap); } --- linux-oracle-5.4.0.orig/drivers/clk/sprd/pll.c +++ linux-oracle-5.4.0/drivers/clk/sprd/pll.c @@ -105,7 +105,7 @@ cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL); if (!cfg) - return -ENOMEM; + return parent_rate; for (i = 0; i < regs_num; i++) cfg[i] = sprd_pll_read(pll, i); --- linux-oracle-5.4.0.orig/drivers/clk/st/clk-flexgen.c +++ linux-oracle-5.4.0/drivers/clk/st/clk-flexgen.c @@ -375,6 +375,7 @@ break; } + flex_flags &= ~CLK_IS_CRITICAL; of_clk_detect_critical(np, i, &flex_flags); /* --- linux-oracle-5.4.0.orig/drivers/clk/st/clkgen-fsyn.c +++ linux-oracle-5.4.0/drivers/clk/st/clkgen-fsyn.c @@ -943,9 +943,10 @@ clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, data, reg, lock); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + kfree(lock); goto err_exit; - else + } else pr_debug("%s: parent %s rate %u\n", __clk_get_name(clk), __clk_get_name(clk_get_parent(clk)), --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -389,6 +389,7 @@ { .val = 1, .div = 2 }, { .val = 2, .div = 4 }, { .val = 3, .div = 6 }, + { /* Sentinel */ }, }; static const char * const ths_parents[] = { "osc24M" }; static struct ccu_div ths_clk = { @@ -921,11 +922,26 @@ .num_resets = ARRAY_SIZE(sun50i_a64_ccu_resets), }; +static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = { + .common = &pll_cpux_clk.common, + /* copy from pll_cpux_clk */ + .enable = BIT(31), + .lock = BIT(28), +}; + +static struct ccu_mux_nb sun50i_a64_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, /* > 8 clock cycles at 24 MHz */ + .bypass_index = 1, /* index of 24 MHz oscillator */ +}; + static int sun50i_a64_ccu_probe(struct platform_device *pdev) { struct resource *res; void __iomem *reg; u32 val; + int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); @@ -939,7 +955,18 @@ writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG); - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc); + if (ret) + return ret; + + /* Gate then ungate PLL CPU after any rate changes */ + ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb); + + /* Reparent CPU during PLL CPU rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_a64_cpu_nb); + + return 0; } static const struct of_device_id sun50i_a64_ccu_ids[] = { --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c @@ -23,9 +23,9 @@ */ static const char * const ar100_r_apb2_parents[] = { "osc24M", "osc32k", - "pll-periph0", "iosc" }; + "iosc", "pll-periph0" }; static const struct ccu_mux_var_prediv ar100_r_apb2_predivs[] = { - { .index = 2, .shift = 0, .width = 5 }, + { .index = 3, .shift = 0, .width = 5 }, }; static struct ccu_div ar100_clk = { --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-h6.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun50i-h6.c @@ -228,7 +228,7 @@ static SUNXI_CCU_MP_WITH_MUX(psi_ahb1_ahb2_clk, "psi-ahb1-ahb2", psi_ahb1_ahb2_parents, 0x510, - 0, 5, /* M */ + 0, 2, /* M */ 8, 2, /* P */ 24, 2, /* mux */ 0); @@ -237,19 +237,19 @@ "psi-ahb1-ahb2", "pll-periph0" }; static SUNXI_CCU_MP_WITH_MUX(ahb3_clk, "ahb3", ahb3_apb1_apb2_parents, 0x51c, - 0, 5, /* M */ + 0, 2, /* M */ 8, 2, /* P */ 24, 2, /* mux */ 0); static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", ahb3_apb1_apb2_parents, 0x520, - 0, 5, /* M */ + 0, 2, /* M */ 8, 2, /* P */ 24, 2, /* mux */ 0); static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", ahb3_apb1_apb2_parents, 0x524, - 0, 5, /* M */ + 0, 2, /* M */ 8, 2, /* P */ 24, 2, /* mux */ 0); @@ -673,7 +673,7 @@ .common = { .reg = 0xb10, - .features = CCU_FEATURE_VARIABLE_PREDIV, + .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("hdmi-cec", hdmi_cec_parents, &ccu_mux_ops, @@ -1172,12 +1172,19 @@ SUN50I_H6_USB3_CLK_REG, }; +static struct ccu_mux_nb sun50i_h6_cpu_nb = { + .common = &cpux_clk.common, + .cm = &cpux_clk.mux, + .delay_us = 1, + .bypass_index = 0, /* index of 24 MHz oscillator */ +}; + static int sun50i_h6_ccu_probe(struct platform_device *pdev) { struct resource *res; void __iomem *reg; + int i, ret; u32 val; - int i; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(&pdev->dev, res); @@ -1231,7 +1238,15 @@ val |= BIT(24); writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG); - return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc); + if (ret) + return ret; + + /* Reparent CPU during PLL CPUX rate changes */ + ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, + &sun50i_h6_cpu_nb); + + return 0; } static const struct of_device_id sun50i_h6_ccu_ids[] = { --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun8i-h3.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun8i-h3.c @@ -322,6 +322,7 @@ { .val = 1, .div = 2 }, { .val = 2, .div = 4 }, { .val = 3, .div = 6 }, + { /* Sentinel */ }, }; static SUNXI_CCU_DIV_TABLE_WITH_GATE(ths_clk, "ths", "osc24M", 0x074, 0, 2, ths_div_table, BIT(31), 0); --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun8i-r.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun8i-r.c @@ -51,19 +51,7 @@ static CLK_FIXED_FACTOR_HW(ahb0_clk, "ahb0", &ar100_clk.common.hw, 1, 1, 0); -static struct ccu_div apb0_clk = { - .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), - - .common = { - .reg = 0x0c, - .hw.init = CLK_HW_INIT_HW("apb0", - &ahb0_clk.hw, - &ccu_div_ops, - 0), - }, -}; - -static SUNXI_CCU_M(a83t_apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); +static SUNXI_CCU_M(apb0_clk, "apb0", "ahb0", 0x0c, 0, 2, 0); /* * Define the parent as an array that can be reused to save space @@ -127,7 +115,7 @@ static struct ccu_common *sun8i_a83t_r_ccu_clks[] = { &ar100_clk.common, - &a83t_apb0_clk.common, + &apb0_clk.common, &apb0_pio_clk.common, &apb0_ir_clk.common, &apb0_timer_clk.common, @@ -167,7 +155,7 @@ .hws = { [CLK_AR100] = &ar100_clk.common.hw, [CLK_AHB0] = &ahb0_clk.hw, - [CLK_APB0] = &a83t_apb0_clk.common.hw, + [CLK_APB0] = &apb0_clk.common.hw, [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, [CLK_APB0_IR] = &apb0_ir_clk.common.hw, [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, @@ -282,9 +270,6 @@ static void __init sun8i_a83t_r_ccu_setup(struct device_node *node) { - /* Fix apb0 bus gate parents here */ - apb0_gate_parent[0] = &a83t_apb0_clk.common.hw; - sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc); } CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu", --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun8i-r40.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun8i-r40.c @@ -761,7 +761,8 @@ .reg = 0x1f0, .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("outa", out_parents, - &ccu_mp_ops, 0), + &ccu_mp_ops, + CLK_SET_RATE_PARENT), } }; @@ -779,7 +780,8 @@ .reg = 0x1f4, .features = CCU_FEATURE_FIXED_PREDIV, .hw.init = CLK_HW_INIT_PARENTS("outb", out_parents, - &ccu_mp_ops, 0), + &ccu_mp_ops, + CLK_SET_RATE_PARENT), } }; --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -618,7 +618,7 @@ [CLK_MBUS] = &mbus_clk.common.hw, [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw, }, - .num = CLK_NUMBER, + .num = CLK_PLL_DDR1 + 1, }; static struct clk_hw_onecell_data sun8i_v3_hw_clks = { @@ -700,7 +700,7 @@ [CLK_MBUS] = &mbus_clk.common.hw, [CLK_MIPI_CSI] = &mipi_csi_clk.common.hw, }, - .num = CLK_NUMBER, + .num = CLK_I2S0 + 1, }; static struct ccu_reset_map sun8i_v3s_ccu_resets[] = { --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu-sun8i-v3s.h @@ -51,6 +51,4 @@ #define CLK_PLL_DDR1 74 -#define CLK_NUMBER (CLK_I2S0 + 1) - #endif /* _CCU_SUN8I_H3_H_ */ --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu_mmc_timing.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu_mmc_timing.c @@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); /** - * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode + * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode * @clk: clock to query * * Returns 0 if the clock is in old timing mode, > 0 if it is in --- linux-oracle-5.4.0.orig/drivers/clk/sunxi-ng/ccu_mp.c +++ linux-oracle-5.4.0/drivers/clk/sunxi-ng/ccu_mp.c @@ -108,7 +108,7 @@ max_m = cmp->m.max ?: 1 << cmp->m.width; max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1); - if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { + if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p); rate = *parent_rate / p / m; } else { --- linux-oracle-5.4.0.orig/drivers/clk/sunxi/clk-sun9i-mmc.c +++ linux-oracle-5.4.0/drivers/clk/sunxi/clk-sun9i-mmc.c @@ -109,6 +109,8 @@ spin_lock_init(&data->lock); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) + return -EINVAL; /* one clock/reset pair per word */ count = DIV_ROUND_UP((resource_size(r)), SUN9I_MMC_WIDTH); data->membase = devm_ioremap_resource(&pdev->dev, r); --- linux-oracle-5.4.0.orig/drivers/clk/sunxi/clk-sunxi.c +++ linux-oracle-5.4.0/drivers/clk/sunxi/clk-sunxi.c @@ -90,7 +90,7 @@ * Round down the frequency to the closest multiple of either * 6 or 16 */ - u32 round_freq_6 = round_down(freq_mhz, 6); + u32 round_freq_6 = rounddown(freq_mhz, 6); u32 round_freq_16 = round_down(freq_mhz, 16); if (round_freq_6 > round_freq_16) --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-bpmp.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-bpmp.c @@ -159,7 +159,7 @@ err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); if (err < 0) - return err; + return 0; return response.rate; } --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-dfll.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-dfll.c @@ -1801,13 +1801,13 @@ &td->reg_init_uV); if (!ret) { dev_err(td->dev, "couldn't get initialized voltage\n"); - return ret; + return -EINVAL; } ret = read_dt_param(td, "nvidia,pwm-period-nanoseconds", &pwm_period); if (!ret) { dev_err(td->dev, "couldn't get PWM period\n"); - return ret; + return -EINVAL; } td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES - 1); --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-emc.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-emc.c @@ -191,6 +191,7 @@ tegra->emc = platform_get_drvdata(pdev); if (!tegra->emc) { + put_device(&pdev->dev); pr_err("%s: cannot find EMC driver\n", __func__); return NULL; } @@ -458,6 +459,7 @@ err = load_one_timing_from_dt(tegra, timing, child); if (err) { of_node_put(child); + kfree(tegra->timings); return err; } @@ -509,6 +511,7 @@ err = load_timings_from_dt(tegra, node, node_ram_code); if (err) { of_node_put(node); + kfree(tegra); return ERR_PTR(err); } } --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-id.h +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-id.h @@ -233,6 +233,7 @@ tegra_clk_sdmmc4, tegra_clk_sdmmc4_8, tegra_clk_se, + tegra_clk_se_10, tegra_clk_soc_therm, tegra_clk_soc_therm_8, tegra_clk_sor0, --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-pll.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-pll.c @@ -1089,7 +1089,8 @@ if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) @@ -1569,9 +1570,6 @@ unsigned long flags = 0; unsigned long input_rate; - if (clk_pll_is_enabled(hw)) - return 0; - input_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); if (_get_table_rate(hw, &sel, pll->params->fixed_rate, input_rate)) @@ -1709,15 +1707,13 @@ return -EINVAL; } - if (clk_pll_is_enabled(hw)) - return 0; - input_rate = clk_hw_get_rate(__clk_get_hw(osc)); if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra-periph.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra-periph.c @@ -636,7 +636,7 @@ INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), INT8("host1x", mux_pllc4_out1_pllc_pllc4_out2_pllp_clkm_plla_pllc4_out0, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_9), INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), - INT8("se", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), + INT8("se", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se_10), INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03), @@ -785,7 +785,11 @@ GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0), GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0), GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), - GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), + /* + * Critical for RAM re-repair operation, which must occur on resume + * from LP1 system suspend and as part of CCPLEX cluster switching. + */ + GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL), GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0), --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra-pmc.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra-pmc.c @@ -49,16 +49,16 @@ static DEFINE_SPINLOCK(clk_out_lock); -static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern1", +static const char *clk_out1_parents[] = { "osc", "osc_div2", + "osc_div4", "extern1", }; -static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern2", +static const char *clk_out2_parents[] = { "osc", "osc_div2", + "osc_div4", "extern2", }; -static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2", - "clk_m_div4", "extern3", +static const char *clk_out3_parents[] = { "osc", "osc_div2", + "osc_div4", "extern3", }; static struct pmc_clk_init_data pmc_clks[] = { --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra114.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra114.c @@ -1337,6 +1337,7 @@ } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); WARN_ON(1); --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra20.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra20.c @@ -18,24 +18,24 @@ #define MISC_CLK_ENB 0x48 #define OSC_CTRL 0x50 -#define OSC_CTRL_OSC_FREQ_MASK (3<<30) -#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30) -#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30) -#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30) -#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30) -#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK) - -#define OSC_CTRL_PLL_REF_DIV_MASK (3<<28) -#define OSC_CTRL_PLL_REF_DIV_1 (0<<28) -#define OSC_CTRL_PLL_REF_DIV_2 (1<<28) -#define OSC_CTRL_PLL_REF_DIV_4 (2<<28) +#define OSC_CTRL_OSC_FREQ_MASK (3u<<30) +#define OSC_CTRL_OSC_FREQ_13MHZ (0u<<30) +#define OSC_CTRL_OSC_FREQ_19_2MHZ (1u<<30) +#define OSC_CTRL_OSC_FREQ_12MHZ (2u<<30) +#define OSC_CTRL_OSC_FREQ_26MHZ (3u<<30) +#define OSC_CTRL_MASK (0x3f2u | OSC_CTRL_OSC_FREQ_MASK) + +#define OSC_CTRL_PLL_REF_DIV_MASK (3u<<28) +#define OSC_CTRL_PLL_REF_DIV_1 (0u<<28) +#define OSC_CTRL_PLL_REF_DIV_2 (1u<<28) +#define OSC_CTRL_PLL_REF_DIV_4 (2u<<28) #define OSC_FREQ_DET 0x58 -#define OSC_FREQ_DET_TRIG (1<<31) +#define OSC_FREQ_DET_TRIG (1u<<31) #define OSC_FREQ_DET_STATUS 0x5c -#define OSC_FREQ_DET_BUSY (1<<31) -#define OSC_FREQ_DET_CNT_MASK 0xFFFF +#define OSC_FREQ_DET_BUSYu (1<<31) +#define OSC_FREQ_DET_CNT_MASK 0xFFFFu #define TEGRA20_CLK_PERIPH_BANKS 3 @@ -1151,6 +1151,7 @@ } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); BUG(); --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra210.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra210.c @@ -3523,6 +3523,7 @@ } pmc_base = of_iomap(node, 0); + of_node_put(node); if (!pmc_base) { pr_err("Can't map pmc registers\n"); WARN_ON(1); --- linux-oracle-5.4.0.orig/drivers/clk/tegra/clk-tegra30.c +++ linux-oracle-5.4.0/drivers/clk/tegra/clk-tegra30.c @@ -1263,6 +1263,8 @@ { TEGRA30_CLK_I2S3_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_I2S4_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_VIMCLK_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, + { TEGRA30_CLK_HDA, TEGRA30_CLK_PLL_P, 102000000, 0 }, + { TEGRA30_CLK_HDA2CODEC_2X, TEGRA30_CLK_PLL_P, 48000000, 0 }, /* must be the last entry */ { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, }; --- linux-oracle-5.4.0.orig/drivers/clk/ti/adpll.c +++ linux-oracle-5.4.0/drivers/clk/ti/adpll.c @@ -194,15 +194,8 @@ if (err) return NULL; } else { - const char *base_name = "adpll"; - char *buf; - - buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + - strlen(postfix), GFP_KERNEL); - if (!buf) - return NULL; - sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); - name = buf; + name = devm_kasprintf(d->dev, GFP_KERNEL, "%08lx.adpll.%s", + d->pa, postfix); } return name; --- linux-oracle-5.4.0.orig/drivers/clk/ti/clk-33xx.c +++ linux-oracle-5.4.0/drivers/clk/ti/clk-33xx.c @@ -212,7 +212,7 @@ }; static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst = { - { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { AM3_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk-24mhz-clkctrl:0000:0" }, { 0 }, }; --- linux-oracle-5.4.0.orig/drivers/clk/ti/clk-43xx.c +++ linux-oracle-5.4.0/drivers/clk/ti/clk-43xx.c @@ -78,7 +78,7 @@ }; static const struct omap_clkctrl_reg_data am4_l4_rtc_clkctrl_regs[] __initconst = { - { AM4_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clk_32768_ck" }, + { AM4_L4_RTC_RTC_CLKCTRL, NULL, CLKF_SW_SUP, "clkdiv32k_ick" }, { 0 }, }; --- linux-oracle-5.4.0.orig/drivers/clk/ti/clk-7xx.c +++ linux-oracle-5.4.0/drivers/clk/ti/clk-7xx.c @@ -405,7 +405,7 @@ }; static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = { - { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" }, + { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "gmac_main_clk" }, { 0 }, }; @@ -793,6 +793,7 @@ DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), DT_CLK(NULL, "sys_clkin", "sys_clkin1"), + DT_CLK(NULL, "timer_sys_ck", "timer_sys_clk_div"), DT_CLK(NULL, "atl_dpll_clk_mux", "atl-clkctrl:0000:24"), DT_CLK(NULL, "atl_gfclk_mux", "atl-clkctrl:0000:26"), DT_CLK(NULL, "dcan1_sys_clk_mux", "wkupaon-clkctrl:0068:24"), --- linux-oracle-5.4.0.orig/drivers/clk/ti/clk-dra7-atl.c +++ linux-oracle-5.4.0/drivers/clk/ti/clk-dra7-atl.c @@ -252,14 +252,17 @@ if (rc) { pr_err("%s: failed to lookup atl clock %d\n", __func__, i); - return -EINVAL; + ret = -EINVAL; + goto pm_put; } clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); if (IS_ERR(clk)) { pr_err("%s: failed to get atl clock %d from provider\n", __func__, i); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto pm_put; } cdesc = to_atl_desc(__clk_get_hw(clk)); @@ -292,8 +295,9 @@ if (cdesc->enabled) atl_clk_enable(__clk_get_hw(clk)); } - pm_runtime_put_sync(cinfo->dev); +pm_put: + pm_runtime_put_sync(cinfo->dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/clk/ti/clockdomain.c +++ linux-oracle-5.4.0/drivers/clk/ti/clockdomain.c @@ -146,10 +146,12 @@ if (!omap2_clk_is_hw_omap(clk_hw)) { pr_warn("can't setup clkdm for basic clk %s\n", __clk_get_name(clk)); + clk_put(clk); continue; } to_clk_hw_omap(clk_hw)->clkdm_name = clkdm_name; omap2_init_clk_clkdm(clk_hw); + clk_put(clk); } } --- linux-oracle-5.4.0.orig/drivers/clk/ti/composite.c +++ linux-oracle-5.4.0/drivers/clk/ti/composite.c @@ -196,6 +196,7 @@ if (!cclk->comp_clks[i]) continue; list_del(&cclk->comp_clks[i]->link); + kfree(cclk->comp_clks[i]->parent_names); kfree(cclk->comp_clks[i]); } --- linux-oracle-5.4.0.orig/drivers/clk/ti/fapll.c +++ linux-oracle-5.4.0/drivers/clk/ti/fapll.c @@ -498,6 +498,7 @@ { struct clk_init_data *init; struct fapll_synth *synth; + struct clk *clk = ERR_PTR(-ENOMEM); init = kzalloc(sizeof(*init), GFP_KERNEL); if (!init) @@ -520,13 +521,19 @@ synth->hw.init = init; synth->clk_pll = pll_clk; - return clk_register(NULL, &synth->hw); + clk = clk_register(NULL, &synth->hw); + if (IS_ERR(clk)) { + pr_err("failed to register clock\n"); + goto free; + } + + return clk; free: kfree(synth); kfree(init); - return ERR_PTR(-ENOMEM); + return clk; } static void __init ti_fapll_setup(struct device_node *node) --- linux-oracle-5.4.0.orig/drivers/clk/uniphier/clk-uniphier-fixed-rate.c +++ linux-oracle-5.4.0/drivers/clk/uniphier/clk-uniphier-fixed-rate.c @@ -24,6 +24,7 @@ init.name = name; init.ops = &clk_fixed_rate_ops; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; --- linux-oracle-5.4.0.orig/drivers/clk/uniphier/clk-uniphier-mux.c +++ linux-oracle-5.4.0/drivers/clk/uniphier/clk-uniphier-mux.c @@ -31,10 +31,10 @@ static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw) { struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw); - int num_parents = clk_hw_get_num_parents(hw); + unsigned int num_parents = clk_hw_get_num_parents(hw); int ret; unsigned int val; - u8 i; + unsigned int i; ret = regmap_read(mux->regmap, mux->reg, &val); if (ret) --- linux-oracle-5.4.0.orig/drivers/clk/uniphier/clk-uniphier-peri.c +++ linux-oracle-5.4.0/drivers/clk/uniphier/clk-uniphier-peri.c @@ -18,8 +18,8 @@ #define UNIPHIER_PERI_CLK_FI2C(idx, ch) \ UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch)) -#define UNIPHIER_PERI_CLK_SCSSI(idx) \ - UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17) +#define UNIPHIER_PERI_CLK_SCSSI(idx, ch) \ + UNIPHIER_CLK_GATE("scssi" #ch, (idx), "spi", 0x20, 17 + (ch)) #define UNIPHIER_PERI_CLK_MCSSI(idx) \ UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14) @@ -35,7 +35,7 @@ UNIPHIER_PERI_CLK_I2C(6, 2), UNIPHIER_PERI_CLK_I2C(7, 3), UNIPHIER_PERI_CLK_I2C(8, 4), - UNIPHIER_PERI_CLK_SCSSI(11), + UNIPHIER_PERI_CLK_SCSSI(11, 0), { /* sentinel */ } }; @@ -51,7 +51,10 @@ UNIPHIER_PERI_CLK_FI2C(8, 4), UNIPHIER_PERI_CLK_FI2C(9, 5), UNIPHIER_PERI_CLK_FI2C(10, 6), - UNIPHIER_PERI_CLK_SCSSI(11), - UNIPHIER_PERI_CLK_MCSSI(12), + UNIPHIER_PERI_CLK_SCSSI(11, 0), + UNIPHIER_PERI_CLK_SCSSI(12, 1), + UNIPHIER_PERI_CLK_SCSSI(13, 2), + UNIPHIER_PERI_CLK_SCSSI(14, 3), + UNIPHIER_PERI_CLK_MCSSI(15), { /* sentinel */ } }; --- linux-oracle-5.4.0.orig/drivers/clk/zynqmp/clk-mux-zynqmp.c +++ linux-oracle-5.4.0/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -85,7 +85,7 @@ static const struct clk_ops zynqmp_clk_mux_ops = { .get_parent = zynqmp_clk_mux_get_parent, .set_parent = zynqmp_clk_mux_set_parent, - .determine_rate = __clk_mux_determine_rate, + .determine_rate = __clk_mux_determine_rate_closest, }; static const struct clk_ops zynqmp_clk_mux_ro_ops = { --- linux-oracle-5.4.0.orig/drivers/clk/zynqmp/clkc.c +++ linux-oracle-5.4.0/drivers/clk/zynqmp/clkc.c @@ -558,7 +558,7 @@ { int j; u32 num_nodes, clk_dev_id; - char *clk_out = NULL; + char *clk_out[MAX_NODES]; struct clock_topology *nodes; struct clk_hw *hw = NULL; @@ -572,16 +572,16 @@ * Intermediate clock names are postfixed with type of clock. */ if (j != (num_nodes - 1)) { - clk_out = kasprintf(GFP_KERNEL, "%s%s", clk_name, + clk_out[j] = kasprintf(GFP_KERNEL, "%s%s", clk_name, clk_type_postfix[nodes[j].type]); } else { - clk_out = kasprintf(GFP_KERNEL, "%s", clk_name); + clk_out[j] = kasprintf(GFP_KERNEL, "%s", clk_name); } if (!clk_topology[nodes[j].type]) continue; - hw = (*clk_topology[nodes[j].type])(clk_out, clk_dev_id, + hw = (*clk_topology[nodes[j].type])(clk_out[j], clk_dev_id, parent_names, num_parents, &nodes[j]); @@ -590,9 +590,12 @@ __func__, clk_dev_id, clk_name, PTR_ERR(hw)); - parent_names[0] = clk_out; + parent_names[0] = clk_out[j]; } - kfree(clk_out); + + for (j = 0; j < num_nodes; j++) + kfree(clk_out[j]); + return hw; } @@ -676,6 +679,13 @@ FIELD_PREP(CLK_ATTR_NODE_INDEX, i); zynqmp_pm_clock_get_name(clock[i].clk_id, &name); + + /* + * Terminate with NULL character in case name provided by firmware + * is longer and truncated due to size limit. + */ + name.name[sizeof(name.name) - 1] = '\0'; + if (!strcmp(name.name, RESERVED_CLK_NAME)) continue; strncpy(clock[i].clk_name, name.name, MAX_NAME_LEN); --- linux-oracle-5.4.0.orig/drivers/clk/zynqmp/pll.c +++ linux-oracle-5.4.0/drivers/clk/zynqmp/pll.c @@ -98,28 +98,25 @@ unsigned long *prate) { u32 fbdiv; - long rate_div, f; + u32 mult, div; - /* Enable the fractional mode if needed */ - rate_div = (rate * FRAC_DIV) / *prate; - f = rate_div % FRAC_DIV; - zynqmp_pll_set_mode(hw, !!f); - - if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { - if (rate > PS_PLL_VCO_MAX) { - fbdiv = rate / PS_PLL_VCO_MAX; - rate = rate / (fbdiv + 1); - } - if (rate < PS_PLL_VCO_MIN) { - fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); - rate = rate * fbdiv; - } - return rate; + /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */ + if (rate > PS_PLL_VCO_MAX) { + div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX); + rate = rate / div; + } + if (rate < PS_PLL_VCO_MIN) { + mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate); + rate = rate * mult; } fbdiv = DIV_ROUND_CLOSEST(rate, *prate); - fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); - return *prate * fbdiv; + if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) { + fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX); + rate = *prate * fbdiv; + } + + return rate; } /** @@ -179,10 +176,12 @@ int ret; const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops(); - if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { - rate_div = (rate * FRAC_DIV) / parent_rate; + rate_div = (rate * FRAC_DIV) / parent_rate; + f = rate_div % FRAC_DIV; + zynqmp_pll_set_mode(hw, !!f); + + if (f) { m = rate_div / FRAC_DIV; - f = rate_div % FRAC_DIV; m = clamp_t(u32, m, (PLL_FBDIV_MIN), (PLL_FBDIV_MAX)); rate = parent_rate * m; frac = (parent_rate * f) / FRAC_DIV; --- linux-oracle-5.4.0.orig/drivers/clocksource/Kconfig +++ linux-oracle-5.4.0/drivers/clocksource/Kconfig @@ -24,6 +24,7 @@ config OMAP_DM_TIMER bool + select TIMER_OF config CLKBLD_I8253 def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK @@ -79,6 +80,7 @@ bool "Intel XScale IXP4xx timer driver" if COMPILE_TEST depends on HAS_IOMEM select CLKSRC_MMIO + select TIMER_OF if OF help Enables support for the Intel XScale IXP4xx SoC timer. --- linux-oracle-5.4.0.orig/drivers/clocksource/acpi_pm.c +++ linux-oracle-5.4.0/drivers/clocksource/acpi_pm.c @@ -229,8 +229,10 @@ int ret; ret = kstrtouint(arg, 16, &base); - if (ret) - return ret; + if (ret) { + pr_warn("PMTMR: invalid 'pmtmr=' value: '%s'\n", arg); + return 1; + } pr_info("PMTMR IOPort override: 0x%04x -> 0x%04x\n", pmtmr_ioport, base); --- linux-oracle-5.4.0.orig/drivers/clocksource/arm_arch_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/arm_arch_timer.c @@ -69,7 +69,7 @@ static bool arch_timer_c3stop; static bool arch_timer_mem_use_virtual; static bool arch_counter_suspend_stop; -static bool vdso_default = true; +static enum vdso_arch_clockmode vdso_default = VDSO_CLOCKMODE_ARCHTIMER; static cpumask_t evtstrm_available = CPU_MASK_NONE; static bool evtstrm_enable = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM); @@ -348,7 +348,7 @@ do { \ _val = read_sysreg(reg); \ _retries--; \ - } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \ + } while (((_val + 1) & GENMASK(8, 0)) <= 1 && _retries); \ \ WARN_ON_ONCE(!_retries); \ _val; \ @@ -392,10 +392,10 @@ ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; if (access == ARCH_TIMER_PHYS_ACCESS) { - cval = evt + arch_counter_get_cntpct(); + cval = evt + arch_counter_get_cntpct_stable(); write_sysreg(cval, cntp_cval_el0); } else { - cval = evt + arch_counter_get_cntvct(); + cval = evt + arch_counter_get_cntvct_stable(); write_sysreg(cval, cntv_cval_el0); } @@ -476,6 +476,14 @@ .set_next_event_virt = erratum_set_next_event_tval_virt, }, #endif +#ifdef CONFIG_ARM64_ERRATUM_1418040 + { + .match_type = ate_match_local_cap_id, + .id = (void *)ARM64_WORKAROUND_1418040, + .desc = "ARM erratum 1418040", + .disable_compat_vdso = true, + }, +#endif }; typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *, @@ -560,8 +568,11 @@ * change both the default value and the vdso itself. */ if (wa->read_cntvct_el0) { - clocksource_counter.archdata.vdso_direct = false; - vdso_default = false; + clocksource_counter.archdata.clock_mode = VDSO_CLOCKMODE_NONE; + vdso_default = VDSO_CLOCKMODE_NONE; + } else if (wa->disable_compat_vdso && vdso_default != VDSO_CLOCKMODE_NONE) { + vdso_default = VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT; + clocksource_counter.archdata.clock_mode = vdso_default; } } @@ -664,8 +675,8 @@ return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt); } -static __always_inline int timer_shutdown(const int access, - struct clock_event_device *clk) +static __always_inline int arch_timer_shutdown(const int access, + struct clock_event_device *clk) { unsigned long ctrl; @@ -678,22 +689,22 @@ static int arch_timer_shutdown_virt(struct clock_event_device *clk) { - return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk); + return arch_timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk); } static int arch_timer_shutdown_phys(struct clock_event_device *clk) { - return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk); + return arch_timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk); } static int arch_timer_shutdown_virt_mem(struct clock_event_device *clk) { - return timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk); + return arch_timer_shutdown(ARCH_TIMER_MEM_VIRT_ACCESS, clk); } static int arch_timer_shutdown_phys_mem(struct clock_event_device *clk) { - return timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk); + return arch_timer_shutdown(ARCH_TIMER_MEM_PHYS_ACCESS, clk); } static __always_inline void set_next_event(const int access, unsigned long evt, @@ -807,15 +818,24 @@ static void arch_timer_configure_evtstream(void) { - int evt_stream_div, pos; + int evt_stream_div, lsb; + + /* + * As the event stream can at most be generated at half the frequency + * of the counter, use half the frequency when computing the divider. + */ + evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ / 2; + + /* + * Find the closest power of two to the divisor. If the adjacent bit + * of lsb (last set bit, starts from 0) is set, then we use (lsb + 1). + */ + lsb = fls(evt_stream_div) - 1; + if (lsb > 0 && (evt_stream_div & BIT(lsb - 1))) + lsb++; - /* Find the closest power of two to the divisor */ - evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ; - pos = fls(evt_stream_div); - if (pos > 1 && !(evt_stream_div & (1 << (pos - 2)))) - pos--; /* enable event stream */ - arch_timer_evtstrm_enable(min(pos, 15)); + arch_timer_evtstrm_enable(max(0, min(lsb, 15))); } static void arch_counter_set_user_access(void) @@ -979,7 +999,7 @@ } arch_timer_read_counter = rd; - clocksource_counter.archdata.vdso_direct = vdso_default; + clocksource_counter.archdata.clock_mode = vdso_default; } else { arch_timer_read_counter = arch_counter_get_cntvct_mem; } --- linux-oracle-5.4.0.orig/drivers/clocksource/asm9260_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/asm9260_timer.c @@ -194,6 +194,10 @@ } clk = of_clk_get(np, 0); + if (IS_ERR(clk)) { + pr_err("Failed to get clk!\n"); + return PTR_ERR(clk); + } ret = clk_prepare_enable(clk); if (ret) { --- linux-oracle-5.4.0.orig/drivers/clocksource/bcm2835_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/bcm2835_timer.c @@ -121,7 +121,7 @@ ret = setup_irq(irq, &timer->act); if (ret) { pr_err("Can't set up timer IRQ\n"); - goto err_iounmap; + goto err_timer_free; } clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); @@ -130,6 +130,9 @@ return 0; +err_timer_free: + kfree(timer); + err_iounmap: iounmap(base); return ret; --- linux-oracle-5.4.0.orig/drivers/clocksource/dw_apb_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/dw_apb_timer.c @@ -222,7 +222,8 @@ /** * dw_apb_clockevent_init() - use an APB timer as a clock_event_device * - * @cpu: The CPU the events will be targeted at. + * @cpu: The CPU the events will be targeted at or -1 if CPU affiliation + * isn't required. * @name: The name used for the timer and the IRQ for it. * @rating: The rating to give the timer. * @base: I/O base for the timer registers. @@ -257,7 +258,7 @@ dw_ced->ced.max_delta_ticks = 0x7fffffff; dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); dw_ced->ced.min_delta_ticks = 5000; - dw_ced->ced.cpumask = cpumask_of(cpu); + dw_ced->ced.cpumask = cpu < 0 ? cpu_possible_mask : cpumask_of(cpu); dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; dw_ced->ced.set_state_shutdown = apbt_shutdown; --- linux-oracle-5.4.0.orig/drivers/clocksource/dw_apb_timer_of.c +++ linux-oracle-5.4.0/drivers/clocksource/dw_apb_timer_of.c @@ -147,10 +147,6 @@ static int __init dw_apb_timer_init(struct device_node *timer) { switch (num_called) { - case 0: - pr_debug("%s: found clockevent timer\n", __func__); - add_clockevent(timer); - break; case 1: pr_debug("%s: found clocksource timer\n", __func__); add_clocksource(timer); @@ -161,6 +157,8 @@ #endif break; default: + pr_debug("%s: found clockevent timer\n", __func__); + add_clockevent(timer); break; } --- linux-oracle-5.4.0.orig/drivers/clocksource/h8300_timer8.c +++ linux-oracle-5.4.0/drivers/clocksource/h8300_timer8.c @@ -169,7 +169,7 @@ return PTR_ERR(clk); } - ret = ENXIO; + ret = -ENXIO; base = of_iomap(node, 0); if (!base) { pr_err("failed to map registers for clockevent\n"); --- linux-oracle-5.4.0.orig/drivers/clocksource/hyperv_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/hyperv_timer.c @@ -233,7 +233,8 @@ static u64 read_hv_sched_clock_tsc(void) { - return read_hv_clock_tsc(NULL) - hv_sched_clock_offset; + return (read_hv_clock_tsc(NULL) - hv_sched_clock_offset) * + (NSEC_PER_SEC / HV_CLOCK_HZ); } static struct clocksource hyperv_cs_tsc = { @@ -258,7 +259,8 @@ static u64 read_hv_sched_clock_msr(void) { - return read_hv_clock_msr(NULL) - hv_sched_clock_offset; + return (read_hv_clock_msr(NULL) - hv_sched_clock_offset) * + (NSEC_PER_SEC / HV_CLOCK_HZ); } static struct clocksource hyperv_cs_msr = { @@ -323,4 +325,3 @@ hv_sched_clock_offset = hyperv_cs->read(hyperv_cs); hv_setup_sched_clock(read_hv_sched_clock_msr); } -EXPORT_SYMBOL_GPL(hv_init_clocksource); --- linux-oracle-5.4.0.orig/drivers/clocksource/i8253.c +++ linux-oracle-5.4.0/drivers/clocksource/i8253.c @@ -108,11 +108,8 @@ #endif #ifdef CONFIG_CLKEVT_I8253 -static int pit_shutdown(struct clock_event_device *evt) +void clockevent_i8253_disable(void) { - if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) - return 0; - raw_spin_lock(&i8253_lock); outb_p(0x30, PIT_MODE); @@ -123,6 +120,14 @@ } raw_spin_unlock(&i8253_lock); +} + +static int pit_shutdown(struct clock_event_device *evt) +{ + if (!clockevent_state_oneshot(evt) && !clockevent_state_periodic(evt)) + return 0; + + clockevent_i8253_disable(); return 0; } --- linux-oracle-5.4.0.orig/drivers/clocksource/mxs_timer.c +++ linux-oracle-5.4.0/drivers/clocksource/mxs_timer.c @@ -138,10 +138,7 @@ /* Clear pending interrupt */ timrot_irq_acknowledge(); - -#ifdef DEBUG - pr_info("%s: changing mode to %s\n", __func__, state) -#endif /* DEBUG */ + pr_debug("%s: changing mode to %s\n", __func__, state); } static int mxs_shutdown(struct clock_event_device *evt) --- linux-oracle-5.4.0.orig/drivers/clocksource/sh_cmt.c +++ linux-oracle-5.4.0/drivers/clocksource/sh_cmt.c @@ -231,6 +231,8 @@ #define CMCNT 1 /* channel register */ #define CMCOR 2 /* channel register */ +#define CMCLKE 0x1000 /* CLK Enable Register (R-Car Gen2) */ + static inline u32 sh_cmt_read_cmstr(struct sh_cmt_channel *ch) { if (ch->iostart) @@ -508,6 +510,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) { struct sh_cmt_channel *ch = dev_id; + unsigned long flags; /* clear flags */ sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) & @@ -538,6 +541,8 @@ ch->flags &= ~FLAG_SKIPEVENT; + raw_spin_lock_irqsave(&ch->lock, flags); + if (ch->flags & FLAG_REPROGRAM) { ch->flags &= ~FLAG_REPROGRAM; sh_cmt_clock_event_program_verify(ch, 1); @@ -550,6 +555,8 @@ ch->flags &= ~FLAG_IRQCONTEXT; + raw_spin_unlock_irqrestore(&ch->lock, flags); + return IRQ_HANDLED; } @@ -568,7 +575,8 @@ ch->flags |= flag; /* setup timeout if no clockevent */ - if ((flag == FLAG_CLOCKSOURCE) && (!(ch->flags & FLAG_CLOCKEVENT))) + if (ch->cmt->num_channels == 1 && + flag == FLAG_CLOCKSOURCE && (!(ch->flags & FLAG_CLOCKEVENT))) __sh_cmt_set_next(ch, ch->max_match_value); out: raw_spin_unlock_irqrestore(&ch->lock, flags); @@ -604,20 +612,25 @@ static u64 sh_cmt_clocksource_read(struct clocksource *cs) { struct sh_cmt_channel *ch = cs_to_sh_cmt(cs); - unsigned long flags; u32 has_wrapped; - u64 value; - u32 raw; - raw_spin_lock_irqsave(&ch->lock, flags); - value = ch->total_cycles; - raw = sh_cmt_get_counter(ch, &has_wrapped); + if (ch->cmt->num_channels == 1) { + unsigned long flags; + u64 value; + u32 raw; - if (unlikely(has_wrapped)) - raw += ch->match_value + 1; - raw_spin_unlock_irqrestore(&ch->lock, flags); + raw_spin_lock_irqsave(&ch->lock, flags); + value = ch->total_cycles; + raw = sh_cmt_get_counter(ch, &has_wrapped); + + if (unlikely(has_wrapped)) + raw += ch->match_value + 1; + raw_spin_unlock_irqrestore(&ch->lock, flags); - return value + raw; + return value + raw; + } + + return sh_cmt_get_counter(ch, &has_wrapped); } static int sh_cmt_clocksource_enable(struct clocksource *cs) @@ -680,7 +693,7 @@ cs->disable = sh_cmt_clocksource_disable; cs->suspend = sh_cmt_clocksource_suspend; cs->resume = sh_cmt_clocksource_resume; - cs->mask = CLOCKSOURCE_MASK(sizeof(u64) * 8); + cs->mask = CLOCKSOURCE_MASK(ch->cmt->info->width); cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n", @@ -742,12 +755,18 @@ struct clock_event_device *ced) { struct sh_cmt_channel *ch = ced_to_sh_cmt(ced); + unsigned long flags; BUG_ON(!clockevent_state_oneshot(ced)); + + raw_spin_lock_irqsave(&ch->lock, flags); + if (likely(ch->flags & FLAG_IRQCONTEXT)) ch->next_match_value = delta - 1; else - sh_cmt_set_next(ch, delta - 1); + __sh_cmt_set_next(ch, delta - 1); + + raw_spin_unlock_irqrestore(&ch->lock, flags); return 0; } @@ -839,6 +858,7 @@ unsigned int hwidx, bool clockevent, bool clocksource, struct sh_cmt_device *cmt) { + u32 value; int ret; /* Skip unused channels. */ @@ -868,6 +888,11 @@ ch->iostart = cmt->mapbase + ch->hwidx * 0x100; ch->ioctrl = ch->iostart + 0x10; ch->timer_bit = 0; + + /* Enable the clock supply to the channel */ + value = ioread32(cmt->mapbase + CMCLKE); + value |= BIT(hwidx); + iowrite32(value, cmt->mapbase + CMCLKE); break; } @@ -1000,12 +1025,10 @@ else cmt->rate = clk_get_rate(cmt->clk) / 8; - clk_disable(cmt->clk); - /* Map the memory resource(s). */ ret = sh_cmt_map_memory(cmt); if (ret < 0) - goto err_clk_unprepare; + goto err_clk_disable; /* Allocate and setup the channels. */ cmt->num_channels = hweight8(cmt->hw_channels); @@ -1033,6 +1056,8 @@ mask &= ~(1 << hwidx); } + clk_disable(cmt->clk); + platform_set_drvdata(pdev, cmt); return 0; @@ -1040,6 +1065,8 @@ err_unmap: kfree(cmt->channels); iounmap(cmt->mapbase); +err_clk_disable: + clk_disable(cmt->clk); err_clk_unprepare: clk_unprepare(cmt->clk); err_clk_put: --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-atmel-tcb.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-atmel-tcb.c @@ -310,6 +310,7 @@ writel(mck_divisor_idx /* likely divide-by-8 */ | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP /* free-run */ + | ATMEL_TC_ASWTRG_SET /* TIOA0 rises at software trigger */ | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ tcaddr + ATMEL_TC_REG(0, CMR)); --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-cadence-ttc.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-cadence-ttc.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include /* * This driver configures the 2 16/32-bit count-up timers as follows: @@ -411,10 +413,8 @@ ttcce->ttc.clk = clk; err = clk_prepare_enable(ttcce->ttc.clk); - if (err) { - kfree(ttcce); - return err; - } + if (err) + goto out_kfree; ttcce->ttc.clk_rate_change_nb.notifier_call = ttc_rate_change_clockevent_cb; @@ -424,7 +424,7 @@ &ttcce->ttc.clk_rate_change_nb); if (err) { pr_warn("Unable to register clock notifier.\n"); - return err; + goto out_kfree; } ttcce->ttc.freq = clk_get_rate(ttcce->ttc.clk); @@ -453,24 +453,20 @@ err = request_irq(irq, ttc_clock_event_interrupt, IRQF_TIMER, ttcce->ce.name, ttcce); - if (err) { - kfree(ttcce); - return err; - } + if (err) + goto out_kfree; clockevents_config_and_register(&ttcce->ce, ttcce->ttc.freq / PRESCALE, 1, 0xfffe); return 0; + +out_kfree: + kfree(ttcce); + return err; } -/** - * ttc_timer_init - Initialize the timer - * - * Initializes the timer hardware and register the clock source and clock event - * timers with Linux kernal timer framework - */ -static int __init ttc_timer_init(struct device_node *timer) +static int __init ttc_timer_probe(struct platform_device *pdev) { unsigned int irq; void __iomem *timer_baseaddr; @@ -478,6 +474,7 @@ static int initialized; int clksel, ret; u32 timer_width = 16; + struct device_node *timer = pdev->dev.of_node; if (initialized) return 0; @@ -489,10 +486,10 @@ * and use it. Note that the event timer uses the interrupt and it's the * 2nd TTC hence the irq_of_parse_and_map(,1) */ - timer_baseaddr = of_iomap(timer, 0); - if (!timer_baseaddr) { + timer_baseaddr = devm_of_iomap(&pdev->dev, timer, 0, NULL); + if (IS_ERR(timer_baseaddr)) { pr_err("ERROR: invalid timer base address\n"); - return -ENXIO; + return PTR_ERR(timer_baseaddr); } irq = irq_of_parse_and_map(timer, 1); @@ -516,20 +513,40 @@ clk_ce = of_clk_get(timer, clksel); if (IS_ERR(clk_ce)) { pr_err("ERROR: timer input clock not found\n"); - return PTR_ERR(clk_ce); + ret = PTR_ERR(clk_ce); + goto put_clk_cs; } ret = ttc_setup_clocksource(clk_cs, timer_baseaddr, timer_width); if (ret) - return ret; + goto put_clk_ce; ret = ttc_setup_clockevent(clk_ce, timer_baseaddr + 4, irq); if (ret) - return ret; + goto put_clk_ce; pr_info("%pOFn #0 at %p, irq=%d\n", timer, timer_baseaddr, irq); return 0; + +put_clk_ce: + clk_put(clk_ce); +put_clk_cs: + clk_put(clk_cs); + return ret; } -TIMER_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init); +static const struct of_device_id ttc_timer_of_match[] = { + {.compatible = "cdns,ttc"}, + {}, +}; + +MODULE_DEVICE_TABLE(of, ttc_timer_of_match); + +static struct platform_driver ttc_timer_driver = { + .driver = { + .name = "cdns_ttc_timer", + .of_match_table = ttc_timer_of_match, + }, +}; +builtin_platform_driver_probe(ttc_timer_driver, ttc_timer_probe); --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-davinci.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-davinci.c @@ -18,7 +18,7 @@ #include #undef pr_fmt -#define pr_fmt(fmt) "%s: " fmt "\n", __func__ +#define pr_fmt(fmt) "%s: " fmt, __func__ #define DAVINCI_TIMER_REG_TIM12 0x10 #define DAVINCI_TIMER_REG_TIM34 0x14 @@ -250,30 +250,32 @@ rv = clk_prepare_enable(clk); if (rv) { - pr_err("Unable to prepare and enable the timer clock"); + pr_err("Unable to prepare and enable the timer clock\n"); return rv; } if (!request_mem_region(timer_cfg->reg.start, resource_size(&timer_cfg->reg), "davinci-timer")) { - pr_err("Unable to request memory region"); - return -EBUSY; + pr_err("Unable to request memory region\n"); + rv = -EBUSY; + goto exit_clk_disable; } base = ioremap(timer_cfg->reg.start, resource_size(&timer_cfg->reg)); if (!base) { - pr_err("Unable to map the register range"); - return -ENOMEM; + pr_err("Unable to map the register range\n"); + rv = -ENOMEM; + goto exit_mem_region; } davinci_timer_init(base); tick_rate = clk_get_rate(clk); - clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL | __GFP_NOFAIL); + clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); if (!clockevent) { - pr_err("Error allocating memory for clockevent data"); - return -ENOMEM; + rv = -ENOMEM; + goto exit_iounmap_base; } clockevent->dev.name = "tim12"; @@ -298,14 +300,10 @@ davinci_timer_irq_timer, IRQF_TIMER, "clockevent/tim12", clockevent); if (rv) { - pr_err("Unable to request the clockevent interrupt"); - return rv; + pr_err("Unable to request the clockevent interrupt\n"); + goto exit_free_clockevent; } - clockevents_config_and_register(&clockevent->dev, tick_rate, - DAVINCI_TIMER_MIN_DELTA, - DAVINCI_TIMER_MAX_DELTA); - davinci_clocksource.dev.rating = 300; davinci_clocksource.dev.read = davinci_clocksource_read; davinci_clocksource.dev.mask = @@ -323,16 +321,34 @@ davinci_clocksource_init_tim34(base); } + clockevents_config_and_register(&clockevent->dev, tick_rate, + DAVINCI_TIMER_MIN_DELTA, + DAVINCI_TIMER_MAX_DELTA); + rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate); if (rv) { - pr_err("Unable to register clocksource"); - return rv; + pr_err("Unable to register clocksource\n"); + goto exit_free_irq; } sched_clock_register(davinci_timer_read_sched_clock, DAVINCI_TIMER_CLKSRC_BITS, tick_rate); return 0; + +exit_free_irq: + free_irq(timer_cfg->irq[DAVINCI_TIMER_CLOCKEVENT_IRQ].start, + clockevent); +exit_free_clockevent: + kfree(clockevent); +exit_iounmap_base: + iounmap(base); +exit_mem_region: + release_mem_region(timer_cfg->reg.start, + resource_size(&timer_cfg->reg)); +exit_clk_disable: + clk_disable_unprepare(clk); + return rv; } static int __init of_davinci_timer_register(struct device_node *np) @@ -343,20 +359,20 @@ rv = of_address_to_resource(np, 0, &timer_cfg.reg); if (rv) { - pr_err("Unable to get the register range for timer"); + pr_err("Unable to get the register range for timer\n"); return rv; } rv = of_irq_to_resource_table(np, timer_cfg.irq, DAVINCI_TIMER_NUM_IRQS); if (rv != DAVINCI_TIMER_NUM_IRQS) { - pr_err("Unable to get the interrupts for timer"); + pr_err("Unable to get the interrupts for timer\n"); return rv; } clk = of_clk_get(np, 0); if (IS_ERR(clk)) { - pr_err("Unable to get the timer clock"); + pr_err("Unable to get the timer clock\n"); return PTR_ERR(clk); } --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-gx6605s.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-gx6605s.c @@ -28,6 +28,7 @@ void __iomem *base = timer_of_base(to_timer_of(ce)); writel_relaxed(GX6605S_STATUS_CLR, base + TIMER_STATUS); + writel_relaxed(0, base + TIMER_INI); ce->event_handler(ce); --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-imx-gpt.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-imx-gpt.c @@ -460,12 +460,16 @@ return -ENOMEM; imxtm->base = of_iomap(np, 0); - if (!imxtm->base) - return -ENXIO; + if (!imxtm->base) { + ret = -ENXIO; + goto err_kfree; + } imxtm->irq = irq_of_parse_and_map(np, 0); - if (imxtm->irq <= 0) - return -EINVAL; + if (imxtm->irq <= 0) { + ret = -EINVAL; + goto err_kfree; + } imxtm->clk_ipg = of_clk_get_by_name(np, "ipg"); @@ -478,11 +482,15 @@ ret = _mxc_timer_init(imxtm); if (ret) - return ret; + goto err_kfree; initialized = 1; return 0; + +err_kfree: + kfree(imxtm); + return ret; } static int __init imx1_timer_init_dt(struct device_node *np) --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-imx-tpm.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-imx-tpm.c @@ -83,20 +83,28 @@ static int tpm_set_next_event(unsigned long delta, struct clock_event_device *evt) { - unsigned long next, now; + unsigned long next, prev, now; - next = tpm_read_counter(); - next += delta; + prev = tpm_read_counter(); + next = prev + delta; writel(next, timer_base + TPM_C0V); now = tpm_read_counter(); /* + * Need to wait CNT increase at least 1 cycle to make sure + * the C0V has been updated into HW. + */ + if ((next & 0xffffffff) != readl(timer_base + TPM_C0V)) + while (now == tpm_read_counter()) + ; + + /* * NOTE: We observed in a very small probability, the bus fabric * contention between GPU and A7 may results a few cycles delay * of writing CNT registers which may cause the min_delta event got * missed, so we need add a ETIME check here in case it happened. */ - return (int)(next - now) <= 0 ? -ETIME : 0; + return (now - prev) >= delta ? -ETIME : 0; } static int tpm_set_state_oneshot(struct clock_event_device *evt) --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-ixp4xx.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-ixp4xx.c @@ -258,7 +258,6 @@ } ixp4xx_timer_register(base, timer_irq, timer_freq); } -EXPORT_SYMBOL_GPL(ixp4xx_timer_setup); #ifdef CONFIG_OF static __init int ixp4xx_of_timer_init(struct device_node *np) --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-of.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-of.c @@ -25,10 +25,7 @@ struct clock_event_device *clkevt = &to->clkevt; - if (of_irq->percpu) - free_percpu_irq(of_irq->irq, clkevt); - else - free_irq(of_irq->irq, clkevt); + free_irq(of_irq->irq, clkevt); } /** @@ -42,9 +39,6 @@ * - Get interrupt number by name * - Get interrupt number by index * - * When the interrupt is per CPU, 'request_percpu_irq()' is called, - * otherwise 'request_irq()' is used. - * * Returns 0 on success, < 0 otherwise */ static __init int timer_of_irq_init(struct device_node *np, @@ -69,12 +63,9 @@ return -EINVAL; } - ret = of_irq->percpu ? - request_percpu_irq(of_irq->irq, of_irq->handler, - np->full_name, clkevt) : - request_irq(of_irq->irq, of_irq->handler, - of_irq->flags ? of_irq->flags : IRQF_TIMER, - np->full_name, clkevt); + ret = request_irq(of_irq->irq, of_irq->handler, + of_irq->flags ? of_irq->flags : IRQF_TIMER, + np->full_name, clkevt); if (ret) { pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np); return ret; @@ -157,9 +148,9 @@ of_base->base = of_base->name ? of_io_request_and_map(np, of_base->index, of_base->name) : of_iomap(np, of_base->index); - if (IS_ERR(of_base->base)) { - pr_err("Failed to iomap (%s)\n", of_base->name); - return PTR_ERR(of_base->base); + if (IS_ERR_OR_NULL(of_base->base)) { + pr_err("Failed to iomap (%s:%s)\n", np->name, of_base->name); + return of_base->base ? PTR_ERR(of_base->base) : -ENOMEM; } return 0; @@ -192,7 +183,7 @@ } if (!to->clkevt.name) - to->clkevt.name = np->name; + to->clkevt.name = np->full_name; to->np = np; --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-of.h +++ linux-oracle-5.4.0/drivers/clocksource/timer-of.h @@ -11,7 +11,6 @@ struct of_timer_irq { int irq; int index; - int percpu; const char *name; unsigned long flags; irq_handler_t handler; --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-orion.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-orion.c @@ -149,7 +149,8 @@ irq = irq_of_parse_and_map(np, 1); if (irq <= 0) { pr_err("%pOFn: unable to parse timer1 irq\n", np); - return -EINVAL; + ret = -EINVAL; + goto out_unprep_clk; } rate = clk_get_rate(clk); @@ -166,7 +167,7 @@ clocksource_mmio_readl_down); if (ret) { pr_err("Failed to initialize mmio timer\n"); - return ret; + goto out_unprep_clk; } sched_clock_register(orion_read_sched_clock, 32, rate); @@ -175,7 +176,7 @@ ret = setup_irq(irq, &orion_clkevt_irq); if (ret) { pr_err("%pOFn: unable to setup irq\n", np); - return ret; + goto out_unprep_clk; } ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; @@ -188,5 +189,9 @@ orion_delay_timer_init(rate); return 0; + +out_unprep_clk: + clk_disable_unprepare(clk); + return ret; } TIMER_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-oxnas-rps.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-oxnas-rps.c @@ -236,7 +236,7 @@ } rps->irq = irq_of_parse_and_map(np, 0); - if (rps->irq < 0) { + if (!rps->irq) { ret = -EINVAL; goto err_iomap; } --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-qcom.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-qcom.c @@ -233,6 +233,7 @@ } if (of_property_read_u32(np, "clock-frequency", &freq)) { + iounmap(cpu0_base); pr_err("Unknown frequency\n"); return -EINVAL; } @@ -243,7 +244,11 @@ freq /= 4; writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL); - return msm_timer_init(freq, 32, irq, !!percpu_offset); + ret = msm_timer_init(freq, 32, irq, !!percpu_offset); + if (ret) + iounmap(cpu0_base); + + return ret; } TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init); TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init); --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-riscv.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-riscv.c @@ -41,7 +41,7 @@ return get_cycles64(); } -static u64 riscv_sched_clock(void) +static u64 notrace riscv_sched_clock(void) { return get_cycles64(); } --- linux-oracle-5.4.0.orig/drivers/clocksource/timer-sp804.c +++ linux-oracle-5.4.0/drivers/clocksource/timer-sp804.c @@ -122,14 +122,14 @@ return IRQ_HANDLED; } -static inline void timer_shutdown(struct clock_event_device *evt) +static inline void evt_timer_shutdown(struct clock_event_device *evt) { writel(0, clkevt_base + TIMER_CTRL); } static int sp804_shutdown(struct clock_event_device *evt) { - timer_shutdown(evt); + evt_timer_shutdown(evt); return 0; } @@ -138,7 +138,7 @@ unsigned long ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE; - timer_shutdown(evt); + evt_timer_shutdown(evt); writel(clkevt_reload, clkevt_base + TIMER_LOAD); writel(ctrl, clkevt_base + TIMER_CTRL); return 0; @@ -215,6 +215,11 @@ struct clk *clk1, *clk2; const char *name = of_get_property(np, "compatible", NULL); + if (initialized) { + pr_debug("%pOF: skipping further SP804 timer device\n", np); + return 0; + } + base = of_iomap(np, 0); if (!base) return -ENXIO; @@ -223,11 +228,6 @@ writel(0, base + TIMER_CTRL); writel(0, base + TIMER_2_BASE + TIMER_CTRL); - if (initialized || !of_device_is_available(np)) { - ret = -EINVAL; - goto err; - } - clk1 = of_clk_get(np, 0); if (IS_ERR(clk1)) clk1 = NULL; --- linux-oracle-5.4.0.orig/drivers/counter/104-quad-8.c +++ linux-oracle-5.4.0/drivers/counter/104-quad-8.c @@ -42,6 +42,7 @@ * @base: base port address of the IIO device */ struct quad8_iio { + struct mutex lock; struct counter_device counter; unsigned int preset[QUAD8_NUM_COUNTERS]; unsigned int count_mode[QUAD8_NUM_COUNTERS]; @@ -56,10 +57,6 @@ #define QUAD8_REG_CHAN_OP 0x11 #define QUAD8_REG_INDEX_INPUT_LEVELS 0x16 -/* Borrow Toggle flip-flop */ -#define QUAD8_FLAG_BT BIT(0) -/* Carry Toggle flip-flop */ -#define QUAD8_FLAG_CT BIT(1) /* Error flag */ #define QUAD8_FLAG_E BIT(4) /* Up/Down flag */ @@ -96,9 +93,6 @@ { struct quad8_iio *const priv = iio_priv(indio_dev); const int base_offset = priv->base + 2 * chan->channel; - unsigned int flags; - unsigned int borrow; - unsigned int carry; int i; switch (mask) { @@ -109,12 +103,9 @@ return IIO_VAL_INT; } - flags = inb(base_offset + 1); - borrow = flags & QUAD8_FLAG_BT; - carry = !!(flags & QUAD8_FLAG_CT); + *val = 0; - /* Borrow XOR Carry effectively doubles count range */ - *val = (borrow ^ carry) << 24; + mutex_lock(&priv->lock); /* Reset Byte Pointer; transfer Counter to Output Latch */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT, @@ -123,6 +114,8 @@ for (i = 0; i < 3; i++) *val |= (unsigned int)inb(base_offset) << (8 * i); + mutex_unlock(&priv->lock); + return IIO_VAL_INT; case IIO_CHAN_INFO_ENABLE: *val = priv->ab_enable[chan->channel]; @@ -153,6 +146,8 @@ if ((unsigned int)val > 0xFFFFFF) return -EINVAL; + mutex_lock(&priv->lock); + /* Reset Byte Pointer */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); @@ -176,12 +171,16 @@ /* Reset Error flag */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1); + mutex_unlock(&priv->lock); + return 0; case IIO_CHAN_INFO_ENABLE: /* only boolean values accepted */ if (val < 0 || val > 1) return -EINVAL; + mutex_lock(&priv->lock); + priv->ab_enable[chan->channel] = val; ior_cfg = val | priv->preset_enable[chan->channel] << 1; @@ -189,11 +188,18 @@ /* Load I/O control configuration */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1); + mutex_unlock(&priv->lock); + return 0; case IIO_CHAN_INFO_SCALE: + mutex_lock(&priv->lock); + /* Quadrature scaling only available in quadrature mode */ - if (!priv->quadrature_mode[chan->channel] && (val2 || val != 1)) + if (!priv->quadrature_mode[chan->channel] && + (val2 || val != 1)) { + mutex_unlock(&priv->lock); return -EINVAL; + } /* Only three gain states (1, 0.5, 0.25) */ if (val == 1 && !val2) @@ -207,11 +213,15 @@ priv->quadrature_scale[chan->channel] = 2; break; default: + mutex_unlock(&priv->lock); return -EINVAL; } - else + else { + mutex_unlock(&priv->lock); return -EINVAL; + } + mutex_unlock(&priv->lock); return 0; } @@ -248,6 +258,8 @@ if (preset > 0xFFFFFF) return -EINVAL; + mutex_lock(&priv->lock); + priv->preset[chan->channel] = preset; /* Reset Byte Pointer */ @@ -257,6 +269,8 @@ for (i = 0; i < 3; i++) outb(preset >> (8 * i), base_offset); + mutex_unlock(&priv->lock); + return len; } @@ -286,6 +300,8 @@ /* Preset enable is active low in Input/Output Control register */ preset_enable = !preset_enable; + mutex_lock(&priv->lock); + priv->preset_enable[chan->channel] = preset_enable; ior_cfg = priv->ab_enable[chan->channel] | @@ -294,6 +310,8 @@ /* Load I/O control configuration to Input / Output Control Register */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset); + mutex_unlock(&priv->lock); + return len; } @@ -351,6 +369,8 @@ unsigned int mode_cfg = cnt_mode << 1; const int base_offset = priv->base + 2 * chan->channel + 1; + mutex_lock(&priv->lock); + priv->count_mode[chan->channel] = cnt_mode; /* Add quadrature mode configuration */ @@ -360,6 +380,8 @@ /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -387,19 +409,26 @@ const struct iio_chan_spec *chan, unsigned int synchronous_mode) { struct quad8_iio *const priv = iio_priv(indio_dev); - const unsigned int idr_cfg = synchronous_mode | - priv->index_polarity[chan->channel] << 1; const int base_offset = priv->base + 2 * chan->channel + 1; + unsigned int idr_cfg = synchronous_mode; + + mutex_lock(&priv->lock); + + idr_cfg |= priv->index_polarity[chan->channel] << 1; /* Index function must be non-synchronous in non-quadrature mode */ - if (synchronous_mode && !priv->quadrature_mode[chan->channel]) + if (synchronous_mode && !priv->quadrature_mode[chan->channel]) { + mutex_unlock(&priv->lock); return -EINVAL; + } priv->synchronous_mode[chan->channel] = synchronous_mode; /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -427,8 +456,12 @@ const struct iio_chan_spec *chan, unsigned int quadrature_mode) { struct quad8_iio *const priv = iio_priv(indio_dev); - unsigned int mode_cfg = priv->count_mode[chan->channel] << 1; const int base_offset = priv->base + 2 * chan->channel + 1; + unsigned int mode_cfg; + + mutex_lock(&priv->lock); + + mode_cfg = priv->count_mode[chan->channel] << 1; if (quadrature_mode) mode_cfg |= (priv->quadrature_scale[chan->channel] + 1) << 3; @@ -446,6 +479,8 @@ /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -473,15 +508,20 @@ const struct iio_chan_spec *chan, unsigned int index_polarity) { struct quad8_iio *const priv = iio_priv(indio_dev); - const unsigned int idr_cfg = priv->synchronous_mode[chan->channel] | - index_polarity << 1; const int base_offset = priv->base + 2 * chan->channel + 1; + unsigned int idr_cfg = index_polarity << 1; + + mutex_lock(&priv->lock); + + idr_cfg |= priv->synchronous_mode[chan->channel]; priv->index_polarity[chan->channel] = index_polarity; /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -585,20 +625,12 @@ static int quad8_count_read(struct counter_device *counter, struct counter_count *count, struct counter_count_read_value *val) { - const struct quad8_iio *const priv = counter->priv; + struct quad8_iio *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; - unsigned int flags; - unsigned int borrow; - unsigned int carry; - unsigned long position; + unsigned long position = 0; int i; - flags = inb(base_offset + 1); - borrow = flags & QUAD8_FLAG_BT; - carry = !!(flags & QUAD8_FLAG_CT); - - /* Borrow XOR Carry effectively doubles count range */ - position = (unsigned long)(borrow ^ carry) << 24; + mutex_lock(&priv->lock); /* Reset Byte Pointer; transfer Counter to Output Latch */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP | QUAD8_RLD_CNTR_OUT, @@ -609,13 +641,15 @@ counter_count_read_value_set(val, COUNTER_COUNT_POSITION, &position); + mutex_unlock(&priv->lock); + return 0; } static int quad8_count_write(struct counter_device *counter, struct counter_count *count, struct counter_count_write_value *val) { - const struct quad8_iio *const priv = counter->priv; + struct quad8_iio *const priv = counter->priv; const int base_offset = priv->base + 2 * count->id; int err; unsigned long position; @@ -630,6 +664,8 @@ if (position > 0xFFFFFF) return -EINVAL; + mutex_lock(&priv->lock); + /* Reset Byte Pointer */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); @@ -653,6 +689,8 @@ /* Reset Error flag */ outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_E, base_offset + 1); + mutex_unlock(&priv->lock); + return 0; } @@ -673,13 +711,13 @@ static int quad8_function_get(struct counter_device *counter, struct counter_count *count, size_t *function) { - const struct quad8_iio *const priv = counter->priv; + struct quad8_iio *const priv = counter->priv; const int id = count->id; - const unsigned int quadrature_mode = priv->quadrature_mode[id]; - const unsigned int scale = priv->quadrature_scale[id]; - if (quadrature_mode) - switch (scale) { + mutex_lock(&priv->lock); + + if (priv->quadrature_mode[id]) + switch (priv->quadrature_scale[id]) { case 0: *function = QUAD8_COUNT_FUNCTION_QUADRATURE_X1; break; @@ -693,6 +731,8 @@ else *function = QUAD8_COUNT_FUNCTION_PULSE_DIRECTION; + mutex_unlock(&priv->lock); + return 0; } @@ -703,10 +743,15 @@ const int id = count->id; unsigned int *const quadrature_mode = priv->quadrature_mode + id; unsigned int *const scale = priv->quadrature_scale + id; - unsigned int mode_cfg = priv->count_mode[id] << 1; unsigned int *const synchronous_mode = priv->synchronous_mode + id; - const unsigned int idr_cfg = priv->index_polarity[id] << 1; const int base_offset = priv->base + 2 * id + 1; + unsigned int mode_cfg; + unsigned int idr_cfg; + + mutex_lock(&priv->lock); + + mode_cfg = priv->count_mode[id] << 1; + idr_cfg = priv->index_polarity[id] << 1; if (function == QUAD8_COUNT_FUNCTION_PULSE_DIRECTION) { *quadrature_mode = 0; @@ -742,6 +787,8 @@ /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -858,15 +905,20 @@ { struct quad8_iio *const priv = counter->priv; const size_t channel_id = signal->id - 16; - const unsigned int idr_cfg = priv->synchronous_mode[channel_id] | - index_polarity << 1; const int base_offset = priv->base + 2 * channel_id + 1; + unsigned int idr_cfg = index_polarity << 1; + + mutex_lock(&priv->lock); + + idr_cfg |= priv->synchronous_mode[channel_id]; priv->index_polarity[channel_id] = index_polarity; /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -893,19 +945,26 @@ { struct quad8_iio *const priv = counter->priv; const size_t channel_id = signal->id - 16; - const unsigned int idr_cfg = synchronous_mode | - priv->index_polarity[channel_id] << 1; const int base_offset = priv->base + 2 * channel_id + 1; + unsigned int idr_cfg = synchronous_mode; + + mutex_lock(&priv->lock); + + idr_cfg |= priv->index_polarity[channel_id] << 1; /* Index function must be non-synchronous in non-quadrature mode */ - if (synchronous_mode && !priv->quadrature_mode[channel_id]) + if (synchronous_mode && !priv->quadrature_mode[channel_id]) { + mutex_unlock(&priv->lock); return -EINVAL; + } priv->synchronous_mode[channel_id] = synchronous_mode; /* Load Index Control configuration to Index Control Register */ outb(QUAD8_CTR_IDR | idr_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -970,6 +1029,8 @@ break; } + mutex_lock(&priv->lock); + priv->count_mode[count->id] = cnt_mode; /* Set count mode configuration value */ @@ -982,6 +1043,8 @@ /* Load mode configuration to Counter Mode Register */ outb(QUAD8_CTR_CMR | mode_cfg, base_offset); + mutex_unlock(&priv->lock); + return 0; } @@ -1023,6 +1086,8 @@ if (err) return err; + mutex_lock(&priv->lock); + priv->ab_enable[count->id] = ab_enable; ior_cfg = ab_enable | priv->preset_enable[count->id] << 1; @@ -1030,6 +1095,8 @@ /* Load I/O control configuration */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset + 1); + mutex_unlock(&priv->lock); + return len; } @@ -1058,14 +1125,28 @@ return sprintf(buf, "%u\n", priv->preset[count->id]); } +static void quad8_preset_register_set(struct quad8_iio *quad8iio, int id, + unsigned int preset) +{ + const unsigned int base_offset = quad8iio->base + 2 * id; + int i; + + quad8iio->preset[id] = preset; + + /* Reset Byte Pointer */ + outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); + + /* Set Preset Register */ + for (i = 0; i < 3; i++) + outb(preset >> (8 * i), base_offset); +} + static ssize_t quad8_count_preset_write(struct counter_device *counter, struct counter_count *count, void *private, const char *buf, size_t len) { struct quad8_iio *const priv = counter->priv; - const int base_offset = priv->base + 2 * count->id; unsigned int preset; int ret; - int i; ret = kstrtouint(buf, 0, &preset); if (ret) @@ -1075,14 +1156,11 @@ if (preset > 0xFFFFFF) return -EINVAL; - priv->preset[count->id] = preset; + mutex_lock(&priv->lock); - /* Reset Byte Pointer */ - outb(QUAD8_CTR_RLD | QUAD8_RLD_RESET_BP, base_offset + 1); + quad8_preset_register_set(priv, count->id, preset); - /* Set Preset Register */ - for (i = 0; i < 3; i++) - outb(preset >> (8 * i), base_offset); + mutex_unlock(&priv->lock); return len; } @@ -1090,33 +1168,53 @@ static ssize_t quad8_count_ceiling_read(struct counter_device *counter, struct counter_count *count, void *private, char *buf) { - const struct quad8_iio *const priv = counter->priv; + struct quad8_iio *const priv = counter->priv; + + mutex_lock(&priv->lock); /* Range Limit and Modulo-N count modes use preset value as ceiling */ switch (priv->count_mode[count->id]) { case 1: case 3: - return quad8_count_preset_read(counter, count, private, buf); + mutex_unlock(&priv->lock); + return sprintf(buf, "%u\n", priv->preset[count->id]); } - /* By default 0x1FFFFFF (25 bits unsigned) is maximum count */ - return sprintf(buf, "33554431\n"); + mutex_unlock(&priv->lock); + + /* By default 0xFFFFFF (24 bits unsigned) is maximum count */ + return sprintf(buf, "16777215\n"); } static ssize_t quad8_count_ceiling_write(struct counter_device *counter, struct counter_count *count, void *private, const char *buf, size_t len) { struct quad8_iio *const priv = counter->priv; + unsigned int ceiling; + int ret; + + ret = kstrtouint(buf, 0, &ceiling); + if (ret) + return ret; + + /* Only 24-bit values are supported */ + if (ceiling > 0xFFFFFF) + return -EINVAL; + + mutex_lock(&priv->lock); /* Range Limit and Modulo-N count modes use preset value as ceiling */ switch (priv->count_mode[count->id]) { case 1: case 3: - return quad8_count_preset_write(counter, count, private, buf, - len); + quad8_preset_register_set(priv, count->id, ceiling); + mutex_unlock(&priv->lock); + return len; } - return len; + mutex_unlock(&priv->lock); + + return -EINVAL; } static ssize_t quad8_count_preset_enable_read(struct counter_device *counter, @@ -1143,6 +1241,8 @@ /* Preset enable is active low in Input/Output Control register */ preset_enable = !preset_enable; + mutex_lock(&priv->lock); + priv->preset_enable[count->id] = preset_enable; ior_cfg = priv->ab_enable[count->id] | (unsigned int)preset_enable << 1; @@ -1150,6 +1250,8 @@ /* Load I/O control configuration to Input / Output Control Register */ outb(QUAD8_CTR_IOR | ior_cfg, base_offset); + mutex_unlock(&priv->lock); + return len; } @@ -1320,6 +1422,9 @@ quad8iio->counter.priv = quad8iio; quad8iio->base = base[id]; + /* Initialize mutex */ + mutex_init(&quad8iio->lock); + /* Reset all counters and disable interrupt function */ outb(QUAD8_CHAN_OP_RESET_COUNTERS, base[id] + QUAD8_REG_CHAN_OP); /* Set initial configuration for all counters */ --- linux-oracle-5.4.0.orig/drivers/counter/stm32-lptimer-cnt.c +++ linux-oracle-5.4.0/drivers/counter/stm32-lptimer-cnt.c @@ -69,7 +69,7 @@ /* ensure CMP & ARR registers are properly written */ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, - (val & STM32_LPTIM_CMPOK_ARROK), + (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 100, 1000); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/counter/stm32-timer-cnt.c +++ linux-oracle-5.4.0/drivers/counter/stm32-timer-cnt.c @@ -24,7 +24,7 @@ struct counter_device counter; struct regmap *regmap; struct clk *clk; - u32 ceiling; + u32 max_arr; }; /** @@ -35,13 +35,14 @@ * @STM32_COUNT_ENCODER_MODE_3: counts on both TI1FP1 and TI2FP2 edges */ enum stm32_count_function { - STM32_COUNT_SLAVE_MODE_DISABLED = -1, + STM32_COUNT_SLAVE_MODE_DISABLED, STM32_COUNT_ENCODER_MODE_1, STM32_COUNT_ENCODER_MODE_2, STM32_COUNT_ENCODER_MODE_3, }; static enum counter_count_function stm32_count_functions[] = { + [STM32_COUNT_SLAVE_MODE_DISABLED] = COUNTER_COUNT_FUNCTION_INCREASE, [STM32_COUNT_ENCODER_MODE_1] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_A, [STM32_COUNT_ENCODER_MODE_2] = COUNTER_COUNT_FUNCTION_QUADRATURE_X2_B, [STM32_COUNT_ENCODER_MODE_3] = COUNTER_COUNT_FUNCTION_QUADRATURE_X4, @@ -65,14 +66,15 @@ struct counter_count_write_value *val) { struct stm32_timer_cnt *const priv = counter->priv; - u32 cnt; + u32 cnt, ceiling; int err; err = counter_count_write_value_get(&cnt, COUNTER_COUNT_POSITION, val); if (err) return err; - if (cnt > priv->ceiling) + regmap_read(priv->regmap, TIM_ARR, &ceiling); + if (cnt > ceiling) return -EINVAL; return regmap_write(priv->regmap, TIM_CNT, cnt); @@ -88,6 +90,9 @@ regmap_read(priv->regmap, TIM_SMCR, &smcr); switch (smcr & TIM_SMCR_SMS) { + case 0: + *function = STM32_COUNT_SLAVE_MODE_DISABLED; + return 0; case 1: *function = STM32_COUNT_ENCODER_MODE_1; return 0; @@ -97,9 +102,9 @@ case 3: *function = STM32_COUNT_ENCODER_MODE_3; return 0; + default: + return -EINVAL; } - - return -EINVAL; } static int stm32_count_function_set(struct counter_device *counter, @@ -110,6 +115,9 @@ u32 cr1, sms; switch (function) { + case STM32_COUNT_SLAVE_MODE_DISABLED: + sms = 0; + break; case STM32_COUNT_ENCODER_MODE_1: sms = 1; break; @@ -120,8 +128,7 @@ sms = 3; break; default: - sms = 0; - break; + return -EINVAL; } /* Store enable status */ @@ -129,10 +136,6 @@ regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); - /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ - regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); - regmap_write(priv->regmap, TIM_ARR, priv->ceiling); - regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); /* Make sure that registers are updated */ @@ -183,11 +186,13 @@ if (ret) return ret; + if (ceiling > priv->max_arr) + return -ERANGE; + /* TIMx_ARR register shouldn't be buffered (ARPE=0) */ regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, 0); regmap_write(priv->regmap, TIM_ARR, ceiling); - priv->ceiling = ceiling; return len; } @@ -269,31 +274,36 @@ size_t function; int err; - /* Default action mode (e.g. STM32_COUNT_SLAVE_MODE_DISABLED) */ - *action = STM32_SYNAPSE_ACTION_NONE; - err = stm32_count_function_get(counter, count, &function); if (err) - return 0; + return err; switch (function) { + case STM32_COUNT_SLAVE_MODE_DISABLED: + /* counts on internal clock when CEN=1 */ + *action = STM32_SYNAPSE_ACTION_NONE; + return 0; case STM32_COUNT_ENCODER_MODE_1: /* counts up/down on TI1FP1 edge depending on TI2FP2 level */ if (synapse->signal->id == count->synapses[0].signal->id) *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; - break; + else + *action = STM32_SYNAPSE_ACTION_NONE; + return 0; case STM32_COUNT_ENCODER_MODE_2: /* counts up/down on TI2FP2 edge depending on TI1FP1 level */ if (synapse->signal->id == count->synapses[1].signal->id) *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; - break; + else + *action = STM32_SYNAPSE_ACTION_NONE; + return 0; case STM32_COUNT_ENCODER_MODE_3: /* counts up/down on both TI1FP1 and TI2FP2 edges */ *action = STM32_SYNAPSE_ACTION_BOTH_EDGES; - break; + return 0; + default: + return -EINVAL; } - - return 0; } static const struct counter_ops stm32_timer_cnt_ops = { @@ -354,7 +364,7 @@ priv->regmap = ddata->regmap; priv->clk = ddata->clk; - priv->ceiling = ddata->max_arr; + priv->max_arr = ddata->max_arr; priv->counter.name = dev_name(dev); priv->counter.parent = dev; --- linux-oracle-5.4.0.orig/drivers/cpufreq/Kconfig.arm +++ linux-oracle-5.4.0/drivers/cpufreq/Kconfig.arm @@ -41,6 +41,7 @@ config ARM_ARMADA_8K_CPUFREQ tristate "Armada 8K CPUFreq driver" depends on ARCH_MVEBU && CPUFREQ_DT + select ARMADA_AP_CPU_CLK help This enables the CPUFreq driver support for Marvell Armada8k SOCs. --- linux-oracle-5.4.0.orig/drivers/cpufreq/acpi-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/acpi-cpufreq.c @@ -30,6 +30,7 @@ #include #include #include +#include MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski"); MODULE_DESCRIPTION("ACPI Processor P-States Driver"); @@ -688,7 +689,8 @@ cpumask_copy(policy->cpus, topology_core_cpumask(cpu)); } - if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) { + if (check_amd_hwpstate_cpu(cpu) && boot_cpu_data.x86 < 0x19 && + !acpi_pstate_strict) { cpumask_clear(policy->cpus); cpumask_set_cpu(cpu, policy->cpus); cpumask_copy(data->freqdomain_cpus, --- linux-oracle-5.4.0.orig/drivers/cpufreq/amd_freq_sensitivity.c +++ linux-oracle-5.4.0/drivers/cpufreq/amd_freq_sensitivity.c @@ -18,6 +18,7 @@ #include #include +#include #include "cpufreq_ondemand.h" @@ -123,6 +124,8 @@ if (!pcidev) { if (!boot_cpu_has(X86_FEATURE_PROC_FEEDBACK)) return -ENODEV; + } else { + pci_dev_put(pcidev); } if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val)) --- linux-oracle-5.4.0.orig/drivers/cpufreq/armada-37xx-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/armada-37xx-cpufreq.c @@ -25,6 +25,10 @@ #include "cpufreq-dt.h" +/* Clk register set */ +#define ARMADA_37XX_CLK_TBG_SEL 0 +#define ARMADA_37XX_CLK_TBG_SEL_CPU_OFF 22 + /* Power management in North Bridge register set */ #define ARMADA_37XX_NB_L0L1 0x18 #define ARMADA_37XX_NB_L2L3 0x1C @@ -69,6 +73,8 @@ #define LOAD_LEVEL_NR 4 #define MIN_VOLT_MV 1000 +#define MIN_VOLT_MV_FOR_L1_1000MHZ 1108 +#define MIN_VOLT_MV_FOR_L1_1200MHZ 1155 /* AVS value for the corresponding voltage (in mV) */ static int avs_map[] = { @@ -96,7 +102,11 @@ }; static struct armada_37xx_dvfs armada_37xx_dvfs[] = { - {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, + /* + * The cpufreq scaling for 1.2 GHz variant of the SOC is currently + * unstable because we do not know how to configure it properly. + */ + /* {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, */ {.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} }, {.cpu_freq_max = 800*1000*1000, .divider = {1, 2, 3, 4} }, {.cpu_freq_max = 600*1000*1000, .divider = {2, 4, 5, 6} }, @@ -120,10 +130,15 @@ * will be configured then the DVFS will be enabled. */ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base, - struct clk *clk, u8 *divider) + struct regmap *clk_base, u8 *divider) { + u32 cpu_tbg_sel; int load_lvl; - struct clk *parent; + + /* Determine to which TBG clock is CPU connected */ + regmap_read(clk_base, ARMADA_37XX_CLK_TBG_SEL, &cpu_tbg_sel); + cpu_tbg_sel >>= ARMADA_37XX_CLK_TBG_SEL_CPU_OFF; + cpu_tbg_sel &= ARMADA_37XX_NB_TBG_SEL_MASK; for (load_lvl = 0; load_lvl < LOAD_LEVEL_NR; load_lvl++) { unsigned int reg, mask, val, offset = 0; @@ -142,6 +157,11 @@ mask = (ARMADA_37XX_NB_CLK_SEL_MASK << ARMADA_37XX_NB_CLK_SEL_OFF); + /* Set TBG index, for all levels we use the same TBG */ + val = cpu_tbg_sel << ARMADA_37XX_NB_TBG_SEL_OFF; + mask = (ARMADA_37XX_NB_TBG_SEL_MASK + << ARMADA_37XX_NB_TBG_SEL_OFF); + /* * Set cpu divider based on the pre-computed array in * order to have balanced step. @@ -160,14 +180,6 @@ regmap_update_bits(base, reg, mask, val); } - - /* - * Set cpu clock source, for all the level we keep the same - * clock source that the one already configured. For this one - * we need to use the clock framework - */ - parent = clk_get_parent(clk); - clk_set_parent(clk, parent); } /* @@ -202,6 +214,8 @@ * - L2 & L3 voltage should be about 150mv smaller than L0 voltage. * This function calculates L1 & L2 & L3 AVS values dynamically based * on L0 voltage and fill all AVS values to the AVS value table. + * When base CPU frequency is 1000 or 1200 MHz then there is additional + * minimal avs value for load L1. */ static void __init armada37xx_cpufreq_avs_configure(struct regmap *base, struct armada_37xx_dvfs *dvfs) @@ -233,6 +247,19 @@ for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++) dvfs->avs[load_level] = avs_min; + /* + * Set the avs values for load L0 and L1 when base CPU frequency + * is 1000/1200 MHz to its typical initial values according to + * the Armada 3700 Hardware Specifications. + */ + if (dvfs->cpu_freq_max >= 1000*1000*1000) { + if (dvfs->cpu_freq_max >= 1200*1000*1000) + avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1200MHZ); + else + avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1000MHZ); + dvfs->avs[0] = dvfs->avs[1] = avs_min; + } + return; } @@ -252,6 +279,26 @@ target_vm = avs_map[l0_vdd_min] - 150; target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV; dvfs->avs[2] = dvfs->avs[3] = armada_37xx_avs_val_match(target_vm); + + /* + * Fix the avs value for load L1 when base CPU frequency is 1000/1200 MHz, + * otherwise the CPU gets stuck when switching from load L1 to load L0. + * Also ensure that avs value for load L1 is not higher than for L0. + */ + if (dvfs->cpu_freq_max >= 1000*1000*1000) { + u32 avs_min_l1; + + if (dvfs->cpu_freq_max >= 1200*1000*1000) + avs_min_l1 = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1200MHZ); + else + avs_min_l1 = armada_37xx_avs_val_match(MIN_VOLT_MV_FOR_L1_1000MHZ); + + if (avs_min_l1 > dvfs->avs[0]) + avs_min_l1 = dvfs->avs[0]; + + if (dvfs->avs[1] < avs_min_l1) + dvfs->avs[1] = avs_min_l1; + } } static void __init armada37xx_cpufreq_avs_setup(struct regmap *base, @@ -358,11 +405,16 @@ struct platform_device *pdev; unsigned long freq; unsigned int cur_frequency, base_frequency; - struct regmap *nb_pm_base, *avs_base; + struct regmap *nb_clk_base, *nb_pm_base, *avs_base; struct device *cpu_dev; int load_lvl, ret; struct clk *clk, *parent; + nb_clk_base = + syscon_regmap_lookup_by_compatible("marvell,armada-3700-periph-clock-nb"); + if (IS_ERR(nb_clk_base)) + return -ENODEV; + nb_pm_base = syscon_regmap_lookup_by_compatible("marvell,armada-3700-nb-pm"); @@ -391,7 +443,7 @@ return -ENODEV; } - clk = clk_get(cpu_dev, 0); + clk = clk_get(cpu_dev, NULL); if (IS_ERR(clk)) { dev_err(cpu_dev, "Cannot get clock for CPU0\n"); return PTR_ERR(clk); @@ -421,7 +473,7 @@ return -EINVAL; } - dvfs = armada_37xx_cpu_freq_info_get(cur_frequency); + dvfs = armada_37xx_cpu_freq_info_get(base_frequency); if (!dvfs) { clk_put(clk); return -EINVAL; @@ -439,7 +491,7 @@ armada37xx_cpufreq_avs_configure(avs_base, dvfs); armada37xx_cpufreq_avs_setup(avs_base, dvfs); - armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider); + armada37xx_cpufreq_dvfs_setup(nb_pm_base, nb_clk_base, dvfs->divider); clk_put(clk); for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR; @@ -456,6 +508,7 @@ /* Now that everything is setup, enable the DVFS at hardware level */ armada37xx_cpufreq_enable_dvfs(nb_pm_base); + memset(&pdata, 0, sizeof(pdata)); pdata.suspend = armada37xx_cpufreq_suspend; pdata.resume = armada37xx_cpufreq_resume; @@ -472,7 +525,7 @@ remove_opp: /* clean-up the already added opp before leaving */ while (load_lvl-- > ARMADA_37XX_DVFS_LOAD_0) { - freq = cur_frequency / dvfs->divider[load_lvl]; + freq = base_frequency / dvfs->divider[load_lvl]; dev_pm_opp_remove(cpu_dev, freq); } @@ -483,6 +536,12 @@ /* late_initcall, to guarantee the driver is loaded after A37xx clock driver */ late_initcall(armada37xx_cpufreq_driver_init); +static const struct of_device_id __maybe_unused armada37xx_cpufreq_of_match[] = { + { .compatible = "marvell,armada-3700-nb-pm" }, + { }, +}; +MODULE_DEVICE_TABLE(of, armada37xx_cpufreq_of_match); + MODULE_AUTHOR("Gregory CLEMENT "); MODULE_DESCRIPTION("Armada 37xx cpufreq driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/cpufreq/armada-8k-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/armada-8k-cpufreq.c @@ -204,6 +204,12 @@ } module_exit(armada_8k_cpufreq_exit); +static const struct of_device_id __maybe_unused armada_8k_cpufreq_of_match[] = { + { .compatible = "marvell,ap806-cpu-clock" }, + { }, +}; +MODULE_DEVICE_TABLE(of, armada_8k_cpufreq_of_match); + MODULE_AUTHOR("Gregory Clement "); MODULE_DESCRIPTION("Armada 8K cpufreq driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -410,7 +410,11 @@ if (ret) return ERR_PTR(ret); - table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table), + /* + * We allocate space for the 5 different P-STATES AVS, + * plus extra space for a terminating element. + */ + table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1 + 1, sizeof(*table), GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM); @@ -453,7 +457,12 @@ static unsigned int brcm_avs_cpufreq_get(unsigned int cpu) { struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - struct private_data *priv = policy->driver_data; + struct private_data *priv; + + if (!policy) + return 0; + + priv = policy->driver_data; return brcm_avs_get_frequency(priv->base); } @@ -566,6 +575,16 @@ return ret; } +static void brcm_avs_prepare_uninit(struct platform_device *pdev) +{ + struct private_data *priv; + + priv = platform_get_drvdata(pdev); + + iounmap(priv->avs_intr_base); + iounmap(priv->base); +} + static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy) { struct cpufreq_frequency_table *freq_table; @@ -701,21 +720,21 @@ brcm_avs_driver.driver_data = pdev; - return cpufreq_register_driver(&brcm_avs_driver); + ret = cpufreq_register_driver(&brcm_avs_driver); + if (ret) + brcm_avs_prepare_uninit(pdev); + + return ret; } static int brcm_avs_cpufreq_remove(struct platform_device *pdev) { - struct private_data *priv; int ret; ret = cpufreq_unregister_driver(&brcm_avs_driver); - if (ret) - return ret; + WARN_ON(ret); - priv = platform_get_drvdata(pdev); - iounmap(priv->base); - iounmap(priv->avs_intr_base); + brcm_avs_prepare_uninit(pdev); return 0; } --- linux-oracle-5.4.0.orig/drivers/cpufreq/cppc_cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/cppc_cpufreq.c @@ -217,7 +217,7 @@ return ret; } -static int cppc_verify_policy(struct cpufreq_policy *policy) +static int cppc_verify_policy(struct cpufreq_policy_data *policy) { cpufreq_verify_within_cpu_limits(policy); return 0; --- linux-oracle-5.4.0.orig/drivers/cpufreq/cpufreq-dt-platdev.c +++ linux-oracle-5.4.0/drivers/cpufreq/cpufreq-dt-platdev.c @@ -103,6 +103,8 @@ static const struct of_device_id blacklist[] __initconst = { { .compatible = "allwinner,sun50i-h6", }, + { .compatible = "arm,vexpress", }, + { .compatible = "calxeda,highbank", }, { .compatible = "calxeda,ecx-2000", }, @@ -124,6 +126,7 @@ { .compatible = "nvidia,tegra124", }, { .compatible = "nvidia,tegra210", }, + { .compatible = "nvidia,tegra234", }, { .compatible = "qcom,apq8096", }, { .compatible = "qcom,msm8996", }, --- linux-oracle-5.4.0.orig/drivers/cpufreq/cpufreq-nforce2.c +++ linux-oracle-5.4.0/drivers/cpufreq/cpufreq-nforce2.c @@ -291,7 +291,7 @@ * nforce2_verify - verifies a new CPUFreq policy * @policy: new policy */ -static int nforce2_verify(struct cpufreq_policy *policy) +static int nforce2_verify(struct cpufreq_policy_data *policy) { unsigned int fsb_pol_max; --- linux-oracle-5.4.0.orig/drivers/cpufreq/cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/cpufreq.c @@ -74,6 +74,9 @@ static int cpufreq_start_governor(struct cpufreq_policy *policy); static void cpufreq_stop_governor(struct cpufreq_policy *policy); static void cpufreq_governor_limits(struct cpufreq_policy *policy); +static int cpufreq_set_policy(struct cpufreq_policy *policy, + struct cpufreq_governor *new_gov, + unsigned int new_pol); /** * Two notifier lists: the "policy" list is involved in the @@ -438,8 +441,10 @@ cpufreq_notify_post_transition(policy, freqs, transition_failed); + spin_lock(&policy->transition_lock); policy->transition_ongoing = false; policy->transition_task = NULL; + spin_unlock(&policy->transition_lock); wake_up(&policy->transition_wait); } @@ -613,55 +618,51 @@ return NULL; } -static int cpufreq_parse_policy(char *str_governor, - struct cpufreq_policy *policy) -{ - if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { - policy->policy = CPUFREQ_POLICY_PERFORMANCE; - return 0; - } - if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { - policy->policy = CPUFREQ_POLICY_POWERSAVE; - return 0; - } - return -EINVAL; -} - -/** - * cpufreq_parse_governor - parse a governor string only for has_target() - */ -static int cpufreq_parse_governor(char *str_governor, - struct cpufreq_policy *policy) +static struct cpufreq_governor *get_governor(const char *str_governor) { struct cpufreq_governor *t; mutex_lock(&cpufreq_governor_mutex); - t = find_governor(str_governor); - if (!t) { - int ret; + if (!t) + goto unlock; - mutex_unlock(&cpufreq_governor_mutex); + if (!try_module_get(t->owner)) + t = NULL; - ret = request_module("cpufreq_%s", str_governor); - if (ret) - return -EINVAL; +unlock: + mutex_unlock(&cpufreq_governor_mutex); - mutex_lock(&cpufreq_governor_mutex); + return t; +} - t = find_governor(str_governor); - } - if (t && !try_module_get(t->owner)) - t = NULL; +static unsigned int cpufreq_parse_policy(char *str_governor) +{ + if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) + return CPUFREQ_POLICY_PERFORMANCE; - mutex_unlock(&cpufreq_governor_mutex); + if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) + return CPUFREQ_POLICY_POWERSAVE; - if (t) { - policy->governor = t; - return 0; - } + return CPUFREQ_POLICY_UNKNOWN; +} - return -EINVAL; +/** + * cpufreq_parse_governor - parse a governor string only for has_target() + * @str_governor: Governor name. + */ +static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor) +{ + struct cpufreq_governor *t; + + t = get_governor(str_governor); + if (t) + return t; + + if (request_module("cpufreq_%s", str_governor)) + return NULL; + + return get_governor(str_governor); } /** @@ -762,28 +763,33 @@ static ssize_t store_scaling_governor(struct cpufreq_policy *policy, const char *buf, size_t count) { + char str_governor[16]; int ret; - char str_governor[16]; - struct cpufreq_policy new_policy; - - memcpy(&new_policy, policy, sizeof(*policy)); ret = sscanf(buf, "%15s", str_governor); if (ret != 1) return -EINVAL; if (cpufreq_driver->setpolicy) { - if (cpufreq_parse_policy(str_governor, &new_policy)) + unsigned int new_pol; + + new_pol = cpufreq_parse_policy(str_governor); + if (!new_pol) return -EINVAL; + + ret = cpufreq_set_policy(policy, NULL, new_pol); } else { - if (cpufreq_parse_governor(str_governor, &new_policy)) + struct cpufreq_governor *new_gov; + + new_gov = cpufreq_parse_governor(str_governor); + if (!new_gov) return -EINVAL; - } - ret = cpufreq_set_policy(policy, &new_policy); + ret = cpufreq_set_policy(policy, new_gov, + CPUFREQ_POLICY_UNKNOWN); - if (new_policy.governor) - module_put(new_policy.governor->owner); + module_put(new_gov->owner); + } return ret ? ret : count; } @@ -810,12 +816,14 @@ goto out; } + mutex_lock(&cpufreq_governor_mutex); for_each_governor(t) { if (i >= (ssize_t) ((PAGE_SIZE / sizeof(char)) - (CPUFREQ_NAME_LEN + 2))) - goto out; + break; i += scnprintf(&buf[i], CPUFREQ_NAME_PLEN, "%s ", t->name); } + mutex_unlock(&cpufreq_governor_mutex); out: i += sprintf(&buf[i], "\n"); return i; @@ -933,6 +941,9 @@ struct freq_attr *fattr = to_attr(attr); ssize_t ret; + if (!fattr->show) + return -EIO; + down_read(&policy->rwsem); ret = fattr->show(policy, buf); up_read(&policy->rwsem); @@ -947,6 +958,9 @@ struct freq_attr *fattr = to_attr(attr); ssize_t ret = -EINVAL; + if (!fattr->store) + return -EIO; + /* * cpus_read_trylock() is used here to work around a circular lock * dependency problem with respect to the cpufreq_register_driver(). @@ -983,10 +997,9 @@ .release = cpufreq_sysfs_release, }; -static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) +static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu, + struct device *dev) { - struct device *dev = get_cpu_device(cpu); - if (unlikely(!dev)) return; @@ -1044,40 +1057,47 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) { - struct cpufreq_governor *gov = NULL, *def_gov = NULL; - struct cpufreq_policy new_policy; - - memcpy(&new_policy, policy, sizeof(*policy)); - - def_gov = cpufreq_default_governor(); + struct cpufreq_governor *def_gov = cpufreq_default_governor(); + struct cpufreq_governor *gov = NULL; + unsigned int pol = CPUFREQ_POLICY_UNKNOWN; + int ret; if (has_target()) { - /* - * Update governor of new_policy to the governor used before - * hotplug - */ - gov = find_governor(policy->last_governor); + /* Update policy governor to the one used before hotplug. */ + gov = get_governor(policy->last_governor); if (gov) { pr_debug("Restoring governor %s for cpu %d\n", - policy->governor->name, policy->cpu); - } else { - if (!def_gov) - return -ENODATA; + policy->governor->name, policy->cpu); + } else if (def_gov) { gov = def_gov; + __module_get(gov->owner); + } else { + return -ENODATA; } - new_policy.governor = gov; } else { /* Use the default policy if there is no last_policy. */ if (policy->last_policy) { - new_policy.policy = policy->last_policy; - } else { - if (!def_gov) - return -ENODATA; - cpufreq_parse_policy(def_gov->name, &new_policy); + pol = policy->last_policy; + } else if (def_gov) { + pol = cpufreq_parse_policy(def_gov->name); + /* + * In case the default governor is neiter "performance" + * nor "powersave", fall back to the initial policy + * value set by the driver. + */ + if (pol == CPUFREQ_POLICY_UNKNOWN) + pol = policy->policy; } + if (pol != CPUFREQ_POLICY_PERFORMANCE && + pol != CPUFREQ_POLICY_POWERSAVE) + return -ENODATA; } - return cpufreq_set_policy(policy, &new_policy); + ret = cpufreq_set_policy(policy, gov, pol); + if (gov) + module_put(gov->owner); + + return ret; } static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) @@ -1105,13 +1125,10 @@ void refresh_frequency_limits(struct cpufreq_policy *policy) { - struct cpufreq_policy new_policy; - if (!policy_is_inactive(policy)) { - new_policy = *policy; pr_debug("updating policy for CPU %u\n", policy->cpu); - cpufreq_set_policy(policy, &new_policy); + cpufreq_set_policy(policy, policy->governor, policy->policy); } } EXPORT_SYMBOL(refresh_frequency_limits); @@ -1189,6 +1206,7 @@ if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL)) goto err_free_rcpumask; + init_completion(&policy->kobj_unregister); ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, cpufreq_global_kobject, "policy%u", cpu); if (ret) { @@ -1227,7 +1245,6 @@ init_rwsem(&policy->rwsem); spin_lock_init(&policy->transition_lock); init_waitqueue_head(&policy->transition_wait); - init_completion(&policy->kobj_unregister); INIT_WORK(&policy->update, handle_update); policy->cpu = cpu; @@ -1345,9 +1362,14 @@ goto out_free_policy; } + /* + * The initialization has succeeded and the policy is online. + * If there is a problem with its frequency table, take it + * offline and drop it. + */ ret = cpufreq_table_validate_and_sort(policy); if (ret) - goto out_exit_policy; + goto out_offline_policy; /* related_cpus should at least include policy->cpus. */ cpumask_copy(policy->related_cpus, policy->cpus); @@ -1363,7 +1385,7 @@ if (new_policy) { for_each_cpu(j, policy->related_cpus) { per_cpu(cpufreq_cpu_data, j) = policy; - add_cpu_dev_symlink(policy, j); + add_cpu_dev_symlink(policy, j, get_cpu_device(j)); } policy->min_freq_req = kzalloc(2 * sizeof(*policy->min_freq_req), @@ -1373,7 +1395,7 @@ ret = freq_qos_add_request(&policy->constraints, policy->min_freq_req, FREQ_QOS_MIN, - policy->min); + FREQ_QOS_MIN_DEFAULT_VALUE); if (ret < 0) { /* * So we don't call freq_qos_remove_request() for an @@ -1393,7 +1415,7 @@ ret = freq_qos_add_request(&policy->constraints, policy->max_freq_req, FREQ_QOS_MAX, - policy->max); + FREQ_QOS_MAX_DEFAULT_VALUE); if (ret < 0) { policy->max_freq_req = NULL; goto out_destroy_policy; @@ -1491,6 +1513,10 @@ up_write(&policy->rwsem); +out_offline_policy: + if (cpufreq_driver->offline) + cpufreq_driver->offline(policy); + out_exit_policy: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); @@ -1522,52 +1548,41 @@ /* Create sysfs link on CPU registration */ policy = per_cpu(cpufreq_cpu_data, cpu); if (policy) - add_cpu_dev_symlink(policy, cpu); + add_cpu_dev_symlink(policy, cpu, dev); return 0; } -static int cpufreq_offline(unsigned int cpu) +static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy) { - struct cpufreq_policy *policy; int ret; - pr_debug("%s: unregistering CPU %u\n", __func__, cpu); - - policy = cpufreq_cpu_get_raw(cpu); - if (!policy) { - pr_debug("%s: No cpu_data found\n", __func__); - return 0; - } - - down_write(&policy->rwsem); if (has_target()) cpufreq_stop_governor(policy); cpumask_clear_cpu(cpu, policy->cpus); - if (policy_is_inactive(policy)) { - if (has_target()) - strncpy(policy->last_governor, policy->governor->name, - CPUFREQ_NAME_LEN); - else - policy->last_policy = policy->policy; - } else if (cpu == policy->cpu) { - /* Nominate new CPU */ - policy->cpu = cpumask_any(policy->cpus); - } - - /* Start governor again for active policy */ if (!policy_is_inactive(policy)) { + /* Nominate a new CPU if necessary. */ + if (cpu == policy->cpu) + policy->cpu = cpumask_any(policy->cpus); + + /* Start the governor again for the active policy. */ if (has_target()) { ret = cpufreq_start_governor(policy); if (ret) pr_err("%s: Failed to start governor\n", __func__); } - goto unlock; + return; } + if (has_target()) + strncpy(policy->last_governor, policy->governor->name, + CPUFREQ_NAME_LEN); + else + policy->last_policy = policy->policy; + if (cpufreq_thermal_control_enabled(cpufreq_driver)) { cpufreq_cooling_unregister(policy->cdev); policy->cdev = NULL; @@ -1585,12 +1600,31 @@ */ if (cpufreq_driver->offline) { cpufreq_driver->offline(policy); - } else if (cpufreq_driver->exit) { + return; + } + + if (cpufreq_driver->exit) cpufreq_driver->exit(policy); - policy->freq_table = NULL; + + policy->freq_table = NULL; +} + +static int cpufreq_offline(unsigned int cpu) +{ + struct cpufreq_policy *policy; + + pr_debug("%s: unregistering CPU %u\n", __func__, cpu); + + policy = cpufreq_cpu_get_raw(cpu); + if (!policy) { + pr_debug("%s: No cpu_data found\n", __func__); + return 0; } -unlock: + down_write(&policy->rwsem); + + __cpufreq_offline(cpu, policy); + up_write(&policy->rwsem); return 0; } @@ -1608,19 +1642,26 @@ if (!policy) return; + down_write(&policy->rwsem); + if (cpu_online(cpu)) - cpufreq_offline(cpu); + __cpufreq_offline(cpu, policy); cpumask_clear_cpu(cpu, policy->real_cpus); remove_cpu_dev_symlink(policy, dev); - if (cpumask_empty(policy->real_cpus)) { - /* We did light-weight exit earlier, do full tear down now */ - if (cpufreq_driver->offline) - cpufreq_driver->exit(policy); - - cpufreq_policy_free(policy); + if (!cpumask_empty(policy->real_cpus)) { + up_write(&policy->rwsem); + return; } + + /* We did light-weight exit earlier, do full tear down now */ + if (cpufreq_driver->offline && cpufreq_driver->exit) + cpufreq_driver->exit(policy); + + up_write(&policy->rwsem); + + cpufreq_policy_free(policy); } /** @@ -2355,43 +2396,46 @@ /** * cpufreq_set_policy - Modify cpufreq policy parameters. * @policy: Policy object to modify. - * @new_policy: New policy data. + * @new_gov: Policy governor pointer. + * @new_pol: Policy value (for drivers with built-in governors). * - * Pass @new_policy to the cpufreq driver's ->verify() callback. Next, copy the - * min and max parameters of @new_policy to @policy and either invoke the - * driver's ->setpolicy() callback (if present) or carry out a governor update - * for @policy. That is, run the current governor's ->limits() callback (if the - * governor field in @new_policy points to the same object as the one in - * @policy) or replace the governor for @policy with the new one stored in - * @new_policy. + * Invoke the cpufreq driver's ->verify() callback to sanity-check the frequency + * limits to be set for the policy, update @policy with the verified limits + * values and either invoke the driver's ->setpolicy() callback (if present) or + * carry out a governor update for @policy. That is, run the current governor's + * ->limits() callback (if @new_gov points to the same object as the one in + * @policy) or replace the governor for @policy with @new_gov. * * The cpuinfo part of @policy is not updated by this function. */ -int cpufreq_set_policy(struct cpufreq_policy *policy, - struct cpufreq_policy *new_policy) +static int cpufreq_set_policy(struct cpufreq_policy *policy, + struct cpufreq_governor *new_gov, + unsigned int new_pol) { + struct cpufreq_policy_data new_data; struct cpufreq_governor *old_gov; int ret; - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", - new_policy->cpu, new_policy->min, new_policy->max); - - memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); - + memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); + new_data.freq_table = policy->freq_table; + new_data.cpu = policy->cpu; /* * PM QoS framework collects all the requests from users and provide us * the final aggregated value here. */ - new_policy->min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); - new_policy->max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); + new_data.min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); + new_data.max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); + + pr_debug("setting new policy for CPU %u: %u - %u kHz\n", + new_data.cpu, new_data.min, new_data.max); /* verify the cpu speed can be set within this limit */ - ret = cpufreq_driver->verify(new_policy); + ret = cpufreq_driver->verify(&new_data); if (ret) return ret; - policy->min = new_policy->min; - policy->max = new_policy->max; + policy->min = new_data.min; + policy->max = new_data.max; trace_cpu_frequency_limits(policy); policy->cached_target_freq = UINT_MAX; @@ -2400,12 +2444,12 @@ policy->min, policy->max); if (cpufreq_driver->setpolicy) { - policy->policy = new_policy->policy; + policy->policy = new_pol; pr_debug("setting range\n"); return cpufreq_driver->setpolicy(policy); } - if (new_policy->governor == policy->governor) { + if (new_gov == policy->governor) { pr_debug("governor limits update\n"); cpufreq_governor_limits(policy); return 0; @@ -2422,7 +2466,7 @@ } /* start new governor */ - policy->governor = new_policy->governor; + policy->governor = new_gov; ret = cpufreq_init_governor(policy); if (!ret) { ret = cpufreq_start_governor(policy); @@ -2500,26 +2544,27 @@ static int cpufreq_boost_set_sw(int state) { struct cpufreq_policy *policy; - int ret = -EINVAL; for_each_active_policy(policy) { + int ret; + if (!policy->freq_table) - continue; + return -ENXIO; ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table); if (ret) { pr_err("%s: Policy frequency update failed\n", __func__); - break; + return ret; } ret = freq_qos_update_request(policy->max_freq_req, policy->max); if (ret < 0) - break; + return ret; } - return ret; + return 0; } int cpufreq_boost_trigger_state(int state) @@ -2610,6 +2655,20 @@ return 0; } +static char cpufreq_driver_name[CPUFREQ_NAME_LEN]; + +static int __init cpufreq_driver_setup(char *str) +{ + strlcpy(cpufreq_driver_name, str, CPUFREQ_NAME_LEN); + return 1; +} + +/* + * Set this name to only allow one specific cpu freq driver, e.g., + * cpufreq_driver=powernow-k8 + */ +__setup("cpufreq_driver=", cpufreq_driver_setup); + /** * cpufreq_register_driver - register a CPU Frequency driver * @driver_data: A struct cpufreq_driver containing the values# @@ -2628,6 +2687,13 @@ if (cpufreq_disabled()) return -ENODEV; + /* + * The cpufreq core depends heavily on the availability of device + * structure, make sure they are available before proceeding further. + */ + if (!get_cpu_device(0)) + return -EPROBE_DEFER; + if (!driver_data || !driver_data->verify || !driver_data->init || !(driver_data->setpolicy || driver_data->target_index || driver_data->target) || @@ -2637,7 +2703,13 @@ (!driver_data->online != !driver_data->offline)) return -EINVAL; - pr_debug("trying to register driver %s\n", driver_data->name); + pr_debug("trying to register driver %s, cpufreq_driver=%s\n", + driver_data->name, cpufreq_driver_name); + + if (cpufreq_driver_name[0]) + if (!driver_data->name || + strcmp(cpufreq_driver_name, driver_data->name)) + return -EINVAL; /* Protect against concurrent CPU online/offline. */ cpus_read_lock(); --- linux-oracle-5.4.0.orig/drivers/cpufreq/cpufreq_governor_attr_set.c +++ linux-oracle-5.4.0/drivers/cpufreq/cpufreq_governor_attr_set.c @@ -74,8 +74,8 @@ if (count) return count; - kobject_put(&attr_set->kobj); mutex_destroy(&attr_set->update_lock); + kobject_put(&attr_set->kobj); return 0; } EXPORT_SYMBOL_GPL(gov_attr_set_put); --- linux-oracle-5.4.0.orig/drivers/cpufreq/freq_table.c +++ linux-oracle-5.4.0/drivers/cpufreq/freq_table.c @@ -60,7 +60,7 @@ return 0; } -int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, +int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy, struct cpufreq_frequency_table *table) { struct cpufreq_frequency_table *pos; @@ -100,7 +100,7 @@ * Generic routine to verify policy & frequency table, requires driver to set * policy->freq_table prior to it. */ -int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) +int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy) { if (!policy->freq_table) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/cpufreq/gx-suspmod.c +++ linux-oracle-5.4.0/drivers/cpufreq/gx-suspmod.c @@ -328,7 +328,7 @@ * for the hardware supported by the driver. */ -static int cpufreq_gx_verify(struct cpufreq_policy *policy) +static int cpufreq_gx_verify(struct cpufreq_policy_data *policy) { unsigned int tmp_freq = 0; u8 tmp1, tmp2; --- linux-oracle-5.4.0.orig/drivers/cpufreq/highbank-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/highbank-cpufreq.c @@ -101,6 +101,13 @@ } module_init(hb_cpufreq_driver_init); +static const struct of_device_id __maybe_unused hb_cpufreq_of_match[] = { + { .compatible = "calxeda,highbank" }, + { .compatible = "calxeda,ecx-2000" }, + { }, +}; +MODULE_DEVICE_TABLE(of, hb_cpufreq_of_match); + MODULE_AUTHOR("Mark Langsdorf "); MODULE_DESCRIPTION("Calxeda Highbank cpufreq driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/cpufreq/imx-cpufreq-dt.c +++ linux-oracle-5.4.0/drivers/cpufreq/imx-cpufreq-dt.c @@ -44,19 +44,19 @@ mkt_segment = (cell_value & OCOTP_CFG3_MKT_SEGMENT_MASK) >> OCOTP_CFG3_MKT_SEGMENT_SHIFT; /* - * Early samples without fuses written report "0 0" which means - * consumer segment and minimum speed grading. - * - * According to datasheet minimum speed grading is not supported for - * consumer parts so clamp to 1 to avoid warning for "no OPPs" + * Early samples without fuses written report "0 0" which may NOT + * match any OPP defined in DT. So clamp to minimum OPP defined in + * DT to avoid warning for "no OPPs". * * Applies to i.MX8M series SoCs. */ - if (mkt_segment == 0 && speed_grade == 0 && ( - of_machine_is_compatible("fsl,imx8mm") || - of_machine_is_compatible("fsl,imx8mn") || - of_machine_is_compatible("fsl,imx8mq"))) - speed_grade = 1; + if (mkt_segment == 0 && speed_grade == 0) { + if (of_machine_is_compatible("fsl,imx8mm") || + of_machine_is_compatible("fsl,imx8mq")) + speed_grade = 1; + if (of_machine_is_compatible("fsl,imx8mn")) + speed_grade = 0xb; + } supported_hw[0] = BIT(speed_grade); supported_hw[1] = BIT(mkt_segment); --- linux-oracle-5.4.0.orig/drivers/cpufreq/imx6q-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/imx6q-cpufreq.c @@ -210,6 +210,14 @@ .suspend = cpufreq_generic_suspend, }; +static void imx6x_disable_freq_in_opp(struct device *dev, unsigned long freq) +{ + int ret = dev_pm_opp_disable(dev, freq); + + if (ret < 0 && ret != -ENODEV) + dev_warn(dev, "failed to disable %ldMHz OPP\n", freq / 1000000); +} + #define OCOTP_CFG3 0x440 #define OCOTP_CFG3_SPEED_SHIFT 16 #define OCOTP_CFG3_SPEED_1P2GHZ 0x3 @@ -245,17 +253,15 @@ val &= 0x3; if (val < OCOTP_CFG3_SPEED_996MHZ) - if (dev_pm_opp_disable(dev, 996000000)) - dev_warn(dev, "failed to disable 996MHz OPP\n"); + imx6x_disable_freq_in_opp(dev, 996000000); if (of_machine_is_compatible("fsl,imx6q") || of_machine_is_compatible("fsl,imx6qp")) { if (val != OCOTP_CFG3_SPEED_852MHZ) - if (dev_pm_opp_disable(dev, 852000000)) - dev_warn(dev, "failed to disable 852MHz OPP\n"); + imx6x_disable_freq_in_opp(dev, 852000000); + if (val != OCOTP_CFG3_SPEED_1P2GHZ) - if (dev_pm_opp_disable(dev, 1200000000)) - dev_warn(dev, "failed to disable 1.2GHz OPP\n"); + imx6x_disable_freq_in_opp(dev, 1200000000); } iounmap(base); put_node: @@ -281,6 +287,9 @@ np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-ocotp"); if (!np) + np = of_find_compatible_node(NULL, NULL, + "fsl,imx6ull-ocotp"); + if (!np) return -ENOENT; base = of_iomap(np, 0); @@ -305,20 +314,16 @@ val >>= OCOTP_CFG3_SPEED_SHIFT; val &= 0x3; - if (of_machine_is_compatible("fsl,imx6ul")) { + if (of_machine_is_compatible("fsl,imx6ul")) if (val != OCOTP_CFG3_6UL_SPEED_696MHZ) - if (dev_pm_opp_disable(dev, 696000000)) - dev_warn(dev, "failed to disable 696MHz OPP\n"); - } + imx6x_disable_freq_in_opp(dev, 696000000); if (of_machine_is_compatible("fsl,imx6ull")) { - if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ) - if (dev_pm_opp_disable(dev, 792000000)) - dev_warn(dev, "failed to disable 792MHz OPP\n"); + if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ) + imx6x_disable_freq_in_opp(dev, 792000000); if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ) - if (dev_pm_opp_disable(dev, 900000000)) - dev_warn(dev, "failed to disable 900MHz OPP\n"); + imx6x_disable_freq_in_opp(dev, 900000000); } return ret; @@ -378,23 +383,24 @@ goto put_reg; } + /* Because we have added the OPPs here, we must free them */ + free_opp = true; + if (of_machine_is_compatible("fsl,imx6ul") || of_machine_is_compatible("fsl,imx6ull")) { ret = imx6ul_opp_check_speed_grading(cpu_dev); if (ret) { if (ret == -EPROBE_DEFER) - goto put_node; + goto out_free_opp; dev_err(cpu_dev, "failed to read ocotp: %d\n", ret); - goto put_node; + goto out_free_opp; } } else { imx6q_opp_check_speed_grading(cpu_dev); } - /* Because we have added the OPPs here, we must free them */ - free_opp = true; num = dev_pm_opp_get_opp_count(cpu_dev); if (num < 0) { ret = num; --- linux-oracle-5.4.0.orig/drivers/cpufreq/intel_pstate.c +++ linux-oracle-5.4.0/drivers/cpufreq/intel_pstate.c @@ -442,20 +442,6 @@ (u32) cpu->acpi_perf_data.states[i].control); } - /* - * The _PSS table doesn't contain whole turbo frequency range. - * This just contains +1 MHZ above the max non turbo frequency, - * with control value corresponding to max turbo ratio. But - * when cpufreq set policy is called, it will call with this - * max frequency, which will cause a reduced performance as - * this driver uses real max turbo frequency as the max - * frequency. So correct this frequency in _PSS table to - * correct max turbo frequency based on the turbo state. - * Also need to convert to MHz as _PSS freq is in MHz. - */ - if (!global.turbo_disabled) - cpu->acpi_perf_data.states[0].core_frequency = - policy->cpuinfo.max_freq / 1000; cpu->valid_pss_table = true; pr_debug("_PPC limits will be enforced\n"); @@ -649,11 +635,12 @@ mutex_lock(&intel_pstate_limits_lock); if (boot_cpu_has(X86_FEATURE_HWP_EPP)) { - u64 value; - - ret = rdmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, &value); - if (ret) - goto return_pref; + /* + * Use the cached HWP Request MSR value, because the register + * itself may be updated by intel_pstate_hwp_boost_up() or + * intel_pstate_hwp_boost_down() at any time. + */ + u64 value = READ_ONCE(cpu_data->hwp_req_cached); value &= ~GENMASK_ULL(31, 24); @@ -661,13 +648,18 @@ epp = epp_values[pref_index - 1]; value |= (u64)epp << 24; + /* + * The only other updater of hwp_req_cached in the active mode, + * intel_pstate_hwp_set(), is called under the same lock as this + * function, so it cannot run in parallel with the update below. + */ + WRITE_ONCE(cpu_data->hwp_req_cached, value); ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value); } else { if (epp == -EINVAL) epp = (pref_index - 1) << 2; ret = intel_pstate_set_epb(cpu_data->cpu, epp); } -return_pref: mutex_unlock(&intel_pstate_limits_lock); return ret; @@ -756,7 +748,7 @@ rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap); WRITE_ONCE(all_cpu_data[cpu]->hwp_cap_cached, cap); - if (global.no_turbo) + if (global.no_turbo || global.turbo_disabled) *current_max = HWP_GUARANTEED_PERF(cap); else *current_max = HWP_HIGHEST_PERF(cap); @@ -1058,7 +1050,7 @@ update_turbo_state(); if (global.turbo_disabled) { - pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); + pr_notice_once("Turbo disabled by BIOS or unavailable on processor\n"); mutex_unlock(&intel_pstate_limits_lock); mutex_unlock(&intel_pstate_driver_lock); return -EPERM; @@ -1560,20 +1552,22 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) { cpu->pstate.min_pstate = pstate_funcs.get_min(); - cpu->pstate.max_pstate = pstate_funcs.get_max(); cpu->pstate.max_pstate_physical = pstate_funcs.get_max_physical(); cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); cpu->pstate.scaling = pstate_funcs.get_scaling(); - cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling; if (hwp_active && !hwp_mode_bdw) { unsigned int phy_max, current_max; intel_pstate_get_hwp_max(cpu->cpu, &phy_max, ¤t_max); cpu->pstate.turbo_freq = phy_max * cpu->pstate.scaling; + cpu->pstate.turbo_pstate = phy_max; + cpu->pstate.max_pstate = HWP_GUARANTEED_PERF(READ_ONCE(cpu->hwp_cap_cached)); } else { cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling; + cpu->pstate.max_pstate = pstate_funcs.get_max(); } + cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling; if (pstate_funcs.get_aperf_mperf_shift) cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift(); @@ -2036,8 +2030,9 @@ cpu->pstate.max_freq : cpu->pstate.turbo_freq; } -static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, - struct cpudata *cpu) +static void intel_pstate_update_perf_limits(struct cpudata *cpu, + unsigned int policy_min, + unsigned int policy_max) { int max_freq = intel_pstate_get_max_freq(cpu); int32_t max_policy_perf, min_policy_perf; @@ -2056,18 +2051,17 @@ turbo_max = cpu->pstate.turbo_pstate; } - max_policy_perf = max_state * policy->max / max_freq; - if (policy->max == policy->min) { + max_policy_perf = max_state * policy_max / max_freq; + if (policy_max == policy_min) { min_policy_perf = max_policy_perf; } else { - min_policy_perf = max_state * policy->min / max_freq; + min_policy_perf = max_state * policy_min / max_freq; min_policy_perf = clamp_t(int32_t, min_policy_perf, 0, max_policy_perf); } pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n", - policy->cpu, max_state, - min_policy_perf, max_policy_perf); + cpu->cpu, max_state, min_policy_perf, max_policy_perf); /* Normalize user input to [min_perf, max_perf] */ if (per_cpu_limits) { @@ -2081,7 +2075,7 @@ global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100); global_min = clamp_t(int32_t, global_min, 0, global_max); - pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu, + pr_debug("cpu:%d global_min:%d global_max:%d\n", cpu->cpu, global_min, global_max); cpu->min_perf_ratio = max(min_policy_perf, global_min); @@ -2094,7 +2088,7 @@ cpu->max_perf_ratio); } - pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu, + pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", cpu->cpu, cpu->max_perf_ratio, cpu->min_perf_ratio); } @@ -2114,7 +2108,7 @@ mutex_lock(&intel_pstate_limits_lock); - intel_pstate_update_perf_limits(policy, cpu); + intel_pstate_update_perf_limits(cpu, policy->min, policy->max); if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) { /* @@ -2143,8 +2137,8 @@ return 0; } -static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy, - struct cpudata *cpu) +static void intel_pstate_adjust_policy_max(struct cpudata *cpu, + struct cpufreq_policy_data *policy) { if (!hwp_active && cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate && @@ -2155,7 +2149,7 @@ } } -static int intel_pstate_verify_policy(struct cpufreq_policy *policy) +static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy) { struct cpudata *cpu = all_cpu_data[policy->cpu]; @@ -2163,11 +2157,7 @@ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, intel_pstate_get_max_freq(cpu)); - if (policy->policy != CPUFREQ_POLICY_POWERSAVE && - policy->policy != CPUFREQ_POLICY_PERFORMANCE) - return -EINVAL; - - intel_pstate_adjust_policy_max(policy, cpu); + intel_pstate_adjust_policy_max(cpu, policy); return 0; } @@ -2268,7 +2258,7 @@ .name = "intel_pstate", }; -static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy) +static int intel_cpufreq_verify_policy(struct cpufreq_policy_data *policy) { struct cpudata *cpu = all_cpu_data[policy->cpu]; @@ -2276,9 +2266,9 @@ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, intel_pstate_get_max_freq(cpu)); - intel_pstate_adjust_policy_max(policy, cpu); + intel_pstate_adjust_policy_max(cpu, policy); - intel_pstate_update_perf_limits(policy, cpu); + intel_pstate_update_perf_limits(cpu, policy->min, policy->max); return 0; } @@ -2530,9 +2520,15 @@ { int ret; - if (size == 3 && !strncmp(buf, "off", size)) - return intel_pstate_driver ? - intel_pstate_unregister_driver() : -EINVAL; + if (size == 3 && !strncmp(buf, "off", size)) { + if (!intel_pstate_driver) + return -EINVAL; + + if (hwp_active) + return -EBUSY; + + return intel_pstate_unregister_driver(); + } if (size == 6 && !strncmp(buf, "active", size)) { if (intel_pstate_driver) { --- linux-oracle-5.4.0.orig/drivers/cpufreq/longrun.c +++ linux-oracle-5.4.0/drivers/cpufreq/longrun.c @@ -122,7 +122,7 @@ * Validates a new CPUFreq policy. This function has to be called with * cpufreq_driver locked. */ -static int longrun_verify_policy(struct cpufreq_policy *policy) +static int longrun_verify_policy(struct cpufreq_policy_data *policy) { if (!policy) return -EINVAL; @@ -130,10 +130,6 @@ policy->cpu = 0; cpufreq_verify_within_cpu_limits(policy); - if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && - (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) - return -EINVAL; - return 0; } --- linux-oracle-5.4.0.orig/drivers/cpufreq/loongson1-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/loongson1-cpufreq.c @@ -216,6 +216,7 @@ module_platform_driver(ls1x_cpufreq_platdrv); +MODULE_ALIAS("platform:ls1x-cpufreq"); MODULE_AUTHOR("Kelvin Cheung "); MODULE_DESCRIPTION("Loongson1 CPUFreq driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/cpufreq/loongson2_cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/loongson2_cpufreq.c @@ -167,7 +167,9 @@ ret = cpufreq_register_driver(&loongson2_cpufreq_driver); - if (!ret && !nowait) { + if (ret) { + platform_driver_unregister(&platform_driver); + } else if (!nowait) { saved_cpu_wait = cpu_wait; cpu_wait = loongson2_cpu_wait; } --- linux-oracle-5.4.0.orig/drivers/cpufreq/mediatek-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/mediatek-cpufreq.c @@ -540,6 +540,7 @@ { } }; +MODULE_DEVICE_TABLE(of, mtk_cpufreq_machines); static int __init mtk_cpufreq_driver_init(void) { --- linux-oracle-5.4.0.orig/drivers/cpufreq/pcc-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/pcc-cpufreq.c @@ -109,7 +109,7 @@ static struct pcc_cpu __percpu *pcc_cpu_info; -static int pcc_cpufreq_verify(struct cpufreq_policy *policy) +static int pcc_cpufreq_verify(struct cpufreq_policy_data *policy) { cpufreq_verify_within_cpu_limits(policy); return 0; --- linux-oracle-5.4.0.orig/drivers/cpufreq/pmac32-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/pmac32-cpufreq.c @@ -471,6 +471,10 @@ if (slew_done_gpio_np) slew_done_gpio = read_gpio(slew_done_gpio_np); + of_node_put(volt_gpio_np); + of_node_put(freq_gpio_np); + of_node_put(slew_done_gpio_np); + /* If we use the frequency GPIOs, calculate the min/max speeds based * on the bus frequencies */ --- linux-oracle-5.4.0.orig/drivers/cpufreq/powernow-k8.c +++ linux-oracle-5.4.0/drivers/cpufreq/powernow-k8.c @@ -878,9 +878,9 @@ /* Take a frequency, and issue the fid/vid transition command */ static int transition_frequency_fidvid(struct powernow_k8_data *data, - unsigned int index) + unsigned int index, + struct cpufreq_policy *policy) { - struct cpufreq_policy *policy; u32 fid = 0; u32 vid = 0; int res; @@ -912,9 +912,6 @@ freqs.old = find_khz_freq_from_fid(data->currfid); freqs.new = find_khz_freq_from_fid(fid); - policy = cpufreq_cpu_get(smp_processor_id()); - cpufreq_cpu_put(policy); - cpufreq_freq_transition_begin(policy, &freqs); res = transition_fid_vid(data, fid, vid); cpufreq_freq_transition_end(policy, &freqs, res); @@ -969,7 +966,7 @@ powernow_k8_acpi_pst_values(data, newstate); - ret = transition_frequency_fidvid(data, newstate); + ret = transition_frequency_fidvid(data, newstate, pol); if (ret) { pr_err("transition frequency failed\n"); @@ -1104,7 +1101,8 @@ kfree(data->powernow_table); kfree(data); - for_each_cpu(cpu, pol->cpus) + /* pol->cpus will be empty here, use related_cpus instead. */ + for_each_cpu(cpu, pol->related_cpus) per_cpu(powernow_data, cpu) = NULL; return 0; --- linux-oracle-5.4.0.orig/drivers/cpufreq/powernv-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/powernv-cpufreq.c @@ -36,6 +36,7 @@ #define MAX_PSTATE_SHIFT 32 #define LPSTATE_SHIFT 48 #define GPSTATE_SHIFT 56 +#define MAX_NR_CHIPS 32 #define MAX_RAMP_DOWN_TIME 5120 /* @@ -884,12 +885,15 @@ unsigned long action, void *unused) { int cpu; - struct cpufreq_policy cpu_policy; + struct cpufreq_policy *cpu_policy; rebooting = true; for_each_online_cpu(cpu) { - cpufreq_get_policy(&cpu_policy, cpu); - powernv_cpufreq_target_index(&cpu_policy, get_nominal_index()); + cpu_policy = cpufreq_cpu_get(cpu); + if (!cpu_policy) + continue; + powernv_cpufreq_target_index(cpu_policy, get_nominal_index()); + cpufreq_cpu_put(cpu_policy); } return NOTIFY_DONE; @@ -902,6 +906,7 @@ void powernv_cpufreq_work_fn(struct work_struct *work) { struct chip *chip = container_of(work, struct chip, throttle); + struct cpufreq_policy *policy; unsigned int cpu; cpumask_t mask; @@ -916,12 +921,14 @@ chip->restore = false; for_each_cpu(cpu, &mask) { int index; - struct cpufreq_policy policy; - cpufreq_get_policy(&policy, cpu); - index = cpufreq_table_find_index_c(&policy, policy.cur); - powernv_cpufreq_target_index(&policy, index); - cpumask_andnot(&mask, &mask, policy.cpus); + policy = cpufreq_cpu_get(cpu); + if (!policy) + continue; + index = cpufreq_table_find_index_c(policy, policy->cur); + powernv_cpufreq_target_index(policy, index); + cpumask_andnot(&mask, &mask, policy->cpus); + cpufreq_cpu_put(policy); } out: put_online_cpus(); @@ -1041,9 +1048,22 @@ static int init_chip_info(void) { - unsigned int chip[256]; + unsigned int *chip; unsigned int cpu, i; unsigned int prev_chip_id = UINT_MAX; + cpumask_t *chip_cpu_mask; + int ret = 0; + + chip = kcalloc(num_possible_cpus(), sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + /* Allocate a chip cpu mask large enough to fit mask for all chips */ + chip_cpu_mask = kcalloc(MAX_NR_CHIPS, sizeof(cpumask_t), GFP_KERNEL); + if (!chip_cpu_mask) { + ret = -ENOMEM; + goto free_and_return; + } for_each_possible_cpu(cpu) { unsigned int id = cpu_to_chip_id(cpu); @@ -1052,25 +1072,38 @@ prev_chip_id = id; chip[nr_chips++] = id; } + cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]); } chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); - if (!chips) - return -ENOMEM; + if (!chips) { + ret = -ENOMEM; + goto out_free_chip_cpu_mask; + } for (i = 0; i < nr_chips; i++) { chips[i].id = chip[i]; - cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); + cpumask_copy(&chips[i].mask, &chip_cpu_mask[i]); INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); for_each_cpu(cpu, &chips[i].mask) per_cpu(chip_info, cpu) = &chips[i]; } - return 0; +out_free_chip_cpu_mask: + kfree(chip_cpu_mask); +free_and_return: + kfree(chip); + return ret; } static inline void clean_chip_info(void) { + int i; + + /* flush any pending work items */ + if (chips) + for (i = 0; i < nr_chips; i++) + cancel_work_sync(&chips[i].throttle); kfree(chips); } --- linux-oracle-5.4.0.orig/drivers/cpufreq/qcom-cpufreq-nvmem.c +++ linux-oracle-5.4.0/drivers/cpufreq/qcom-cpufreq-nvmem.c @@ -305,6 +305,7 @@ { .compatible = "qcom,qcs404", .data = &match_data_qcs404 }, {}, }; +MODULE_DEVICE_TABLE(of, qcom_cpufreq_match_list); /* * Since the driver depends on smem and nvmem drivers, which may --- linux-oracle-5.4.0.orig/drivers/cpufreq/s3c64xx-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/s3c64xx-cpufreq.c @@ -25,6 +25,7 @@ unsigned int vddarm_max; }; +#ifdef CONFIG_REGULATOR static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = { [0] = { 1000000, 1150000 }, [1] = { 1050000, 1150000 }, @@ -32,6 +33,7 @@ [3] = { 1200000, 1350000 }, [4] = { 1300000, 1350000 }, }; +#endif static struct cpufreq_frequency_table s3c64xx_freq_table[] = { { 0, 0, 66000 }, @@ -53,15 +55,16 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) { - struct s3c64xx_dvfs *dvfs; - unsigned int old_freq, new_freq; + unsigned int new_freq = s3c64xx_freq_table[index].frequency; int ret; +#ifdef CONFIG_REGULATOR + struct s3c64xx_dvfs *dvfs; + unsigned int old_freq; + old_freq = clk_get_rate(policy->clk) / 1000; - new_freq = s3c64xx_freq_table[index].frequency; dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; -#ifdef CONFIG_REGULATOR if (vddarm && new_freq > old_freq) { ret = regulator_set_voltage(vddarm, dvfs->vddarm_min, --- linux-oracle-5.4.0.orig/drivers/cpufreq/scpi-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/scpi-cpufreq.c @@ -239,6 +239,7 @@ }; module_platform_driver(scpi_cpufreq_platdrv); +MODULE_ALIAS("platform:scpi-cpufreq"); MODULE_AUTHOR("Sudeep Holla "); MODULE_DESCRIPTION("ARM SCPI CPUFreq interface driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/cpufreq/sh-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/sh-cpufreq.c @@ -87,7 +87,7 @@ return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); } -static int sh_cpufreq_verify(struct cpufreq_policy *policy) +static int sh_cpufreq_verify(struct cpufreq_policy_data *policy) { struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); struct cpufreq_frequency_table *freq_table; --- linux-oracle-5.4.0.orig/drivers/cpufreq/sti-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/sti-cpufreq.c @@ -141,7 +141,8 @@ static const struct reg_field *sti_cpufreq_match(void) { if (of_machine_is_compatible("st,stih407") || - of_machine_is_compatible("st,stih410")) + of_machine_is_compatible("st,stih410") || + of_machine_is_compatible("st,stih418")) return sti_stih407_dvfs_regfields; return NULL; @@ -258,7 +259,8 @@ int ret; if ((!of_machine_is_compatible("st,stih407")) && - (!of_machine_is_compatible("st,stih410"))) + (!of_machine_is_compatible("st,stih410")) && + (!of_machine_is_compatible("st,stih418"))) return -ENODEV; ddata.cpu = get_cpu_device(0); @@ -290,6 +292,13 @@ } module_init(sti_cpufreq_init); +static const struct of_device_id __maybe_unused sti_cpufreq_of_match[] = { + { .compatible = "st,stih407" }, + { .compatible = "st,stih410" }, + { }, +}; +MODULE_DEVICE_TABLE(of, sti_cpufreq_of_match); + MODULE_DESCRIPTION("STMicroelectronics CPUFreq/OPP driver"); MODULE_AUTHOR("Ajitpal Singh "); MODULE_AUTHOR("Lee Jones "); --- linux-oracle-5.4.0.orig/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ linux-oracle-5.4.0/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -25,7 +25,7 @@ static struct platform_device *cpufreq_dt_pdev, *sun50i_cpufreq_pdev; /** - * sun50i_cpufreq_get_efuse() - Parse and return efuse value present on SoC + * sun50i_cpufreq_get_efuse() - Determine speed grade from efuse value * @versions: Set to the value parsed from efuse * * Returns 0 if success. @@ -69,21 +69,16 @@ return PTR_ERR(speedbin); efuse_value = (*speedbin >> NVMEM_SHIFT) & NVMEM_MASK; - switch (efuse_value) { - case 0b0001: - *versions = 1; - break; - case 0b0011: - *versions = 2; - break; - default: - /* - * For other situations, we treat it as bin0. - * This vf table can be run for any good cpu. - */ + + /* + * We treat unexpected efuse values as if the SoC was from + * the slowest bin. Expected efuse values are 1-3, slowest + * to fastest. + */ + if (efuse_value >= 1 && efuse_value <= 3) + *versions = efuse_value - 1; + else *versions = 0; - break; - } kfree(speedbin); return 0; @@ -103,8 +98,10 @@ return -ENOMEM; ret = sun50i_cpufreq_get_efuse(&speed); - if (ret) + if (ret) { + kfree(opp_tables); return ret; + } snprintf(name, MAX_NAME_LEN, "speed%d", speed); @@ -172,6 +169,7 @@ { .compatible = "allwinner,sun50i-h6" }, {} }; +MODULE_DEVICE_TABLE(of, sun50i_cpufreq_match_list); static const struct of_device_id *sun50i_cpufreq_match_node(void) { --- linux-oracle-5.4.0.orig/drivers/cpufreq/unicore2-cpufreq.c +++ linux-oracle-5.4.0/drivers/cpufreq/unicore2-cpufreq.c @@ -22,7 +22,7 @@ /* make sure that only the "userspace" governor is run * -- anything else wouldn't make sense on this platform, anyway. */ -static int ucv2_verify_speed(struct cpufreq_policy *policy) +static int ucv2_verify_speed(struct cpufreq_policy_data *policy) { if (policy->cpu) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/cpuidle/cpuidle.c +++ linux-oracle-5.4.0/drivers/cpuidle/cpuidle.c @@ -148,7 +148,8 @@ */ stop_critical_timings(); drv->states[index].enter_s2idle(dev, drv, index); - WARN_ON(!irqs_disabled()); + if (WARN_ON_ONCE(!irqs_disabled())) + local_irq_disable(); /* * timekeeping_resume() that will be called by tick_unfreeze() for the * first CPU executing it calls functions containing RCU read-side @@ -384,6 +385,7 @@ continue; limit_ns = (u64)drv->states[i].target_residency * NSEC_PER_USEC; + break; } dev->poll_limit_ns = limit_ns; --- linux-oracle-5.4.0.orig/drivers/cpuidle/driver.c +++ linux-oracle-5.4.0/drivers/cpuidle/driver.c @@ -62,24 +62,23 @@ * __cpuidle_set_driver - set per CPU driver variables for the given driver. * @drv: a valid pointer to a struct cpuidle_driver * - * For each CPU in the driver's cpumask, unset the registered driver per CPU - * to @drv. - * - * Returns 0 on success, -EBUSY if the CPUs have driver(s) already. + * Returns 0 on success, -EBUSY if any CPU in the cpumask have a driver + * different from drv already. */ static inline int __cpuidle_set_driver(struct cpuidle_driver *drv) { int cpu; for_each_cpu(cpu, drv->cpumask) { + struct cpuidle_driver *old_drv; - if (__cpuidle_get_cpu_driver(cpu)) { - __cpuidle_unset_driver(drv); + old_drv = __cpuidle_get_cpu_driver(cpu); + if (old_drv && old_drv != drv) return -EBUSY; - } + } + for_each_cpu(cpu, drv->cpumask) per_cpu(cpuidle_drivers, cpu) = drv; - } return 0; } --- linux-oracle-5.4.0.orig/drivers/cpuidle/dt_idle_states.c +++ linux-oracle-5.4.0/drivers/cpuidle/dt_idle_states.c @@ -224,6 +224,6 @@ * also be 0 on platforms with missing DT idle states or legacy DT * configuration predating the DT idle states bindings. */ - return i; + return state_idx - start_idx; } EXPORT_SYMBOL_GPL(dt_init_idle_driver); --- linux-oracle-5.4.0.orig/drivers/cpuidle/governors/teo.c +++ linux-oracle-5.4.0/drivers/cpuidle/governors/teo.c @@ -194,7 +194,7 @@ * pattern detection. */ cpu_data->intervals[cpu_data->interval_idx++] = measured_us; - if (cpu_data->interval_idx > INTERVALS) + if (cpu_data->interval_idx >= INTERVALS) cpu_data->interval_idx = 0; } @@ -233,8 +233,8 @@ { struct teo_cpu *cpu_data = per_cpu_ptr(&teo_cpus, dev->cpu); int latency_req = cpuidle_governor_latency_req(dev->cpu); - unsigned int duration_us, count; - int max_early_idx, constraint_idx, idx, i; + unsigned int duration_us, hits, misses, early_hits; + int max_early_idx, prev_max_early_idx, constraint_idx, idx, i; ktime_t delta_tick; if (dev->last_state_idx >= 0) { @@ -247,8 +247,11 @@ cpu_data->sleep_length_ns = tick_nohz_get_sleep_length(&delta_tick); duration_us = ktime_to_us(cpu_data->sleep_length_ns); - count = 0; + hits = 0; + misses = 0; + early_hits = 0; max_early_idx = -1; + prev_max_early_idx = -1; constraint_idx = drv->state_count; idx = -1; @@ -258,23 +261,62 @@ if (s->disabled || su->disable) { /* - * If the "early hits" metric of a disabled state is - * greater than the current maximum, it should be taken - * into account, because it would be a mistake to select - * a deeper state with lower "early hits" metric. The - * index cannot be changed to point to it, however, so - * just increase the max count alone and let the index - * still point to a shallower idle state. + * Ignore disabled states with target residencies beyond + * the anticipated idle duration. */ - if (max_early_idx >= 0 && - count < cpu_data->states[i].early_hits) - count = cpu_data->states[i].early_hits; + if (s->target_residency > duration_us) + continue; + + /* + * This state is disabled, so the range of idle duration + * values corresponding to it is covered by the current + * candidate state, but still the "hits" and "misses" + * metrics of the disabled state need to be used to + * decide whether or not the state covering the range in + * question is good enough. + */ + hits = cpu_data->states[i].hits; + misses = cpu_data->states[i].misses; + + if (early_hits >= cpu_data->states[i].early_hits || + idx < 0) + continue; + + /* + * If the current candidate state has been the one with + * the maximum "early hits" metric so far, the "early + * hits" metric of the disabled state replaces the + * current "early hits" count to avoid selecting a + * deeper state with lower "early hits" metric. + */ + if (max_early_idx == idx) { + early_hits = cpu_data->states[i].early_hits; + continue; + } + + /* + * The current candidate state is closer to the disabled + * one than the current maximum "early hits" state, so + * replace the latter with it, but in case the maximum + * "early hits" state index has not been set so far, + * check if the current candidate state is not too + * shallow for that role. + */ + if (!(tick_nohz_tick_stopped() && + drv->states[idx].target_residency < TICK_USEC)) { + prev_max_early_idx = max_early_idx; + early_hits = cpu_data->states[i].early_hits; + max_early_idx = idx; + } continue; } - if (idx < 0) + if (idx < 0) { idx = i; /* first enabled state */ + hits = cpu_data->states[i].hits; + misses = cpu_data->states[i].misses; + } if (s->target_residency > duration_us) break; @@ -283,11 +325,14 @@ constraint_idx = i; idx = i; + hits = cpu_data->states[i].hits; + misses = cpu_data->states[i].misses; - if (count < cpu_data->states[i].early_hits && + if (early_hits < cpu_data->states[i].early_hits && !(tick_nohz_tick_stopped() && drv->states[i].target_residency < TICK_USEC)) { - count = cpu_data->states[i].early_hits; + prev_max_early_idx = max_early_idx; + early_hits = cpu_data->states[i].early_hits; max_early_idx = i; } } @@ -300,10 +345,19 @@ * "early hits" metric, but if that cannot be determined, just use the * state selected so far. */ - if (cpu_data->states[idx].hits <= cpu_data->states[idx].misses && - max_early_idx >= 0) { - idx = max_early_idx; - duration_us = drv->states[idx].target_residency; + if (hits <= misses) { + /* + * The current candidate state is not suitable, so take the one + * whose "early hits" metric is the maximum for the range of + * shallower states. + */ + if (idx == max_early_idx) + max_early_idx = prev_max_early_idx; + + if (max_early_idx >= 0) { + idx = max_early_idx; + duration_us = drv->states[idx].target_residency; + } } /* @@ -316,10 +370,9 @@ if (idx < 0) { idx = 0; /* No states enabled. Must use 0. */ } else if (idx > 0) { + unsigned int count = 0; u64 sum = 0; - count = 0; - /* * Count and sum the most recent idle duration values less than * the current expected idle duration value. --- linux-oracle-5.4.0.orig/drivers/cpuidle/sysfs.c +++ linux-oracle-5.4.0/drivers/cpuidle/sysfs.c @@ -480,6 +480,7 @@ ret = kobject_init_and_add(&kobj->kobj, &ktype_state_cpuidle, &kdev->kobj, "state%d", i); if (ret) { + kobject_put(&kobj->kobj); kfree(kobj); goto error_state; } @@ -611,6 +612,7 @@ ret = kobject_init_and_add(&kdrv->kobj, &ktype_driver_cpuidle, &kdev->kobj, "driver"); if (ret) { + kobject_put(&kdrv->kobj); kfree(kdrv); return ret; } @@ -698,17 +700,18 @@ if (!kdev) return -ENOMEM; kdev->dev = dev; - dev->kobj_dev = kdev; init_completion(&kdev->kobj_unregister); error = kobject_init_and_add(&kdev->kobj, &ktype_cpuidle, &cpu_dev->kobj, "cpuidle"); if (error) { + kobject_put(&kdev->kobj); kfree(kdev); return error; } + dev->kobj_dev = kdev; kobject_uevent(&kdev->kobj, KOBJ_ADD); return 0; --- linux-oracle-5.4.0.orig/drivers/crypto/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/Kconfig @@ -287,6 +287,7 @@ select CRYPTO_AUTHENC select CRYPTO_BLKCIPHER select CRYPTO_HASH + select CRYPTO_LIB_DES select HW_RANDOM depends on FSL_SOC help @@ -332,6 +333,7 @@ depends on PPC && 4xx select CRYPTO_HASH select CRYPTO_AEAD + select CRYPTO_AES select CRYPTO_LIB_AES select CRYPTO_CCM select CRYPTO_CTR @@ -489,11 +491,9 @@ endif # if CRYPTO_DEV_UX500 config CRYPTO_DEV_ATMEL_AUTHENC - tristate "Support for Atmel IPSEC/SSL hw accelerator" + bool "Support for Atmel IPSEC/SSL hw accelerator" depends on ARCH_AT91 || COMPILE_TEST - select CRYPTO_AUTHENC - select CRYPTO_DEV_ATMEL_AES - select CRYPTO_DEV_ATMEL_SHA + depends on CRYPTO_DEV_ATMEL_AES help Some Atmel processors can combine the AES and SHA hw accelerators to enhance support of IPSEC/SSL. @@ -506,6 +506,8 @@ select CRYPTO_AES select CRYPTO_AEAD select CRYPTO_BLKCIPHER + select CRYPTO_AUTHENC if CRYPTO_DEV_ATMEL_AUTHENC + select CRYPTO_DEV_ATMEL_SHA if CRYPTO_DEV_ATMEL_AUTHENC help Some Atmel processors have AES hw accelerator. Select this if you want to use the Atmel module for @@ -542,6 +544,7 @@ config CRYPTO_DEV_ATMEL_I2C tristate + select BITREVERSE config CRYPTO_DEV_ATMEL_ECC tristate "Support for Microchip / Atmel ECC hw accelerator" @@ -737,7 +740,7 @@ config CRYPTO_DEV_SAFEXCEL tristate "Inside Secure's SafeXcel cryptographic engine driver" - depends on OF || PCI || COMPILE_TEST + depends on (OF || PCI || COMPILE_TEST) && HAS_IOMEM select CRYPTO_LIB_AES select CRYPTO_AUTHENC select CRYPTO_BLKCIPHER --- linux-oracle-5.4.0.orig/drivers/crypto/amcc/crypto4xx_core.c +++ linux-oracle-5.4.0/drivers/crypto/amcc/crypto4xx_core.c @@ -365,12 +365,8 @@ dma_alloc_coherent(dev->core_dev->device, PPC4XX_SD_BUFFER_SIZE * PPC4XX_NUM_SD, &dev->scatter_buffer_pa, GFP_ATOMIC); - if (!dev->scatter_buffer_va) { - dma_free_coherent(dev->core_dev->device, - sizeof(struct ce_sd) * PPC4XX_NUM_SD, - dev->sdr, dev->sdr_pa); + if (!dev->scatter_buffer_va) return -ENOMEM; - } for (i = 0; i < PPC4XX_NUM_SD; i++) { dev->sdr[i].ptr = dev->scatter_buffer_pa + @@ -525,7 +521,6 @@ { struct skcipher_request *req; struct scatterlist *dst; - dma_addr_t addr; req = skcipher_request_cast(pd_uinfo->async_req); @@ -534,8 +529,8 @@ req->cryptlen, req->dst); } else { dst = pd_uinfo->dest_va; - addr = dma_map_page(dev->core_dev->device, sg_page(dst), - dst->offset, dst->length, DMA_FROM_DEVICE); + dma_unmap_page(dev->core_dev->device, pd->dest, dst->length, + DMA_FROM_DEVICE); } if (pd_uinfo->sa_va->sa_command_0.bf.save_iv == SA_SAVE_IV) { @@ -560,10 +555,9 @@ struct ahash_request *ahash_req; ahash_req = ahash_request_cast(pd_uinfo->async_req); - ctx = crypto_tfm_ctx(ahash_req->base.tfm); + ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(ahash_req)); - crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, - crypto_tfm_ctx(ahash_req->base.tfm)); + crypto4xx_copy_digest_to_dst(ahash_req->result, pd_uinfo, ctx); crypto4xx_ret_sg_desc(dev, pd_uinfo); if (pd_uinfo->state & PD_ENTRY_BUSY) @@ -920,7 +914,7 @@ } pd->pd_ctl.w = PD_CTL_HOST_READY | - ((crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AHASH) | + ((crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AHASH) || (crypto_tfm_alg_type(req->tfm) == CRYPTO_ALG_TYPE_AEAD) ? PD_CTL_HASH_FINAL : 0); pd->pd_ctl_len.w = 0x00400000 | (assoclen + datalen); --- linux-oracle-5.4.0.orig/drivers/crypto/atmel-aes.c +++ linux-oracle-5.4.0/drivers/crypto/atmel-aes.c @@ -88,7 +88,6 @@ struct atmel_aes_caps { bool has_dualbuff; bool has_cfb64; - bool has_ctr32; bool has_gcm; bool has_xts; bool has_authenc; @@ -145,7 +144,7 @@ u32 key2[AES_KEYSIZE_256 / sizeof(u32)]; }; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) struct atmel_aes_authenc_ctx { struct atmel_aes_base_ctx base; struct atmel_sha_authenc_ctx *auth; @@ -157,7 +156,7 @@ u32 lastc[AES_BLOCK_SIZE / sizeof(u32)]; }; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) struct atmel_aes_authenc_reqctx { struct atmel_aes_reqctx base; @@ -486,13 +485,36 @@ return (dd->flags & AES_FLAGS_ENCRYPT); } -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) static void atmel_aes_authenc_complete(struct atmel_aes_dev *dd, int err); #endif +static void atmel_aes_set_iv_as_last_ciphertext_block(struct atmel_aes_dev *dd) +{ + struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq); + struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req); + struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); + unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + + if (req->nbytes < ivsize) + return; + + if (rctx->mode & AES_FLAGS_ENCRYPT) { + scatterwalk_map_and_copy(req->info, req->dst, + req->nbytes - ivsize, ivsize, 0); + } else { + if (req->src == req->dst) + memcpy(req->info, rctx->lastc, ivsize); + else + scatterwalk_map_and_copy(req->info, req->src, + req->nbytes - ivsize, + ivsize, 0); + } +} + static inline int atmel_aes_complete(struct atmel_aes_dev *dd, int err) { -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) if (dd->ctx->is_aead) atmel_aes_authenc_complete(dd, err); #endif @@ -500,26 +522,8 @@ clk_disable(dd->iclk); dd->flags &= ~AES_FLAGS_BUSY; - if (!dd->ctx->is_aead) { - struct ablkcipher_request *req = - ablkcipher_request_cast(dd->areq); - struct atmel_aes_reqctx *rctx = ablkcipher_request_ctx(req); - struct crypto_ablkcipher *ablkcipher = - crypto_ablkcipher_reqtfm(req); - int ivsize = crypto_ablkcipher_ivsize(ablkcipher); - - if (rctx->mode & AES_FLAGS_ENCRYPT) { - scatterwalk_map_and_copy(req->info, req->dst, - req->nbytes - ivsize, ivsize, 0); - } else { - if (req->src == req->dst) { - memcpy(req->info, rctx->lastc, ivsize); - } else { - scatterwalk_map_and_copy(req->info, req->src, - req->nbytes - ivsize, ivsize, 0); - } - } - } + if (!dd->ctx->is_aead) + atmel_aes_set_iv_as_last_ciphertext_block(dd); if (dd->is_async) dd->areq->complete(dd->areq, err); @@ -1008,8 +1012,9 @@ struct atmel_aes_ctr_ctx *ctx = atmel_aes_ctr_ctx_cast(dd->ctx); struct ablkcipher_request *req = ablkcipher_request_cast(dd->areq); struct scatterlist *src, *dst; - u32 ctr, blocks; size_t datalen; + u32 ctr; + u16 blocks, start, end; bool use_dma, fragmented = false; /* Check for transfer completion. */ @@ -1021,27 +1026,17 @@ datalen = req->nbytes - ctx->offset; blocks = DIV_ROUND_UP(datalen, AES_BLOCK_SIZE); ctr = be32_to_cpu(ctx->iv[3]); - if (dd->caps.has_ctr32) { - /* Check 32bit counter overflow. */ - u32 start = ctr; - u32 end = start + blocks - 1; - - if (end < start) { - ctr |= 0xffffffff; - datalen = AES_BLOCK_SIZE * -start; - fragmented = true; - } - } else { - /* Check 16bit counter overflow. */ - u16 start = ctr & 0xffff; - u16 end = start + (u16)blocks - 1; - - if (blocks >> 16 || end < start) { - ctr |= 0xffff; - datalen = AES_BLOCK_SIZE * (0x10000-start); - fragmented = true; - } + + /* Check 16bit counter overflow. */ + start = ctr & 0xffff; + end = start + blocks - 1; + + if (blocks >> 16 || end < start) { + ctr |= 0xffff; + datalen = AES_BLOCK_SIZE * (0x10000 - start); + fragmented = true; } + use_dma = (datalen >= ATMEL_AES_DMA_THRESHOLD); /* Jump to offset. */ @@ -1125,10 +1120,12 @@ rctx->mode = mode; if (!(mode & AES_FLAGS_ENCRYPT) && (req->src == req->dst)) { - int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher); - scatterwalk_map_and_copy(rctx->lastc, req->src, - (req->nbytes - ivsize), ivsize, 0); + if (req->nbytes >= ivsize) + scatterwalk_map_and_copy(rctx->lastc, req->src, + req->nbytes - ivsize, + ivsize, 0); } return atmel_aes_handle_queue(dd, &req->base); @@ -1973,7 +1970,7 @@ } }; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) /* authenc aead functions */ static int atmel_aes_authenc_start(struct atmel_aes_dev *dd); @@ -2460,7 +2457,7 @@ { int i; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) if (dd->caps.has_authenc) for (i = 0; i < ARRAY_SIZE(aes_authenc_algs); i++) crypto_unregister_aead(&aes_authenc_algs[i]); @@ -2507,7 +2504,7 @@ goto err_aes_xts_alg; } -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) if (dd->caps.has_authenc) { for (i = 0; i < ARRAY_SIZE(aes_authenc_algs); i++) { err = crypto_register_aead(&aes_authenc_algs[i]); @@ -2519,7 +2516,7 @@ return 0; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) /* i = ARRAY_SIZE(aes_authenc_algs); */ err_aes_authenc_alg: for (j = 0; j < i; j++) @@ -2543,7 +2540,6 @@ { dd->caps.has_dualbuff = 0; dd->caps.has_cfb64 = 0; - dd->caps.has_ctr32 = 0; dd->caps.has_gcm = 0; dd->caps.has_xts = 0; dd->caps.has_authenc = 0; @@ -2554,7 +2550,6 @@ case 0x500: dd->caps.has_dualbuff = 1; dd->caps.has_cfb64 = 1; - dd->caps.has_ctr32 = 1; dd->caps.has_gcm = 1; dd->caps.has_xts = 1; dd->caps.has_authenc = 1; @@ -2563,7 +2558,6 @@ case 0x200: dd->caps.has_dualbuff = 1; dd->caps.has_cfb64 = 1; - dd->caps.has_ctr32 = 1; dd->caps.has_gcm = 1; dd->caps.max_burst_size = 4; break; @@ -2709,7 +2703,7 @@ atmel_aes_get_cap(aes_dd); -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) if (aes_dd->caps.has_authenc && !atmel_sha_authenc_is_ready()) { err = -EPROBE_DEFER; goto iclk_unprepare; --- linux-oracle-5.4.0.orig/drivers/crypto/atmel-authenc.h +++ linux-oracle-5.4.0/drivers/crypto/atmel-authenc.h @@ -12,7 +12,7 @@ #ifndef __ATMEL_AUTHENC_H__ #define __ATMEL_AUTHENC_H__ -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) #include #include --- linux-oracle-5.4.0.orig/drivers/crypto/atmel-sha.c +++ linux-oracle-5.4.0/drivers/crypto/atmel-sha.c @@ -1918,12 +1918,7 @@ { struct atmel_sha_hmac_ctx *hmac = crypto_ahash_ctx(tfm); - if (atmel_sha_hmac_key_set(&hmac->hkey, key, keylen)) { - crypto_ahash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } - - return 0; + return atmel_sha_hmac_key_set(&hmac->hkey, key, keylen); } static int atmel_sha_hmac_init(struct ahash_request *req) @@ -2212,7 +2207,7 @@ }, }; -#ifdef CONFIG_CRYPTO_DEV_ATMEL_AUTHENC +#if IS_ENABLED(CONFIG_CRYPTO_DEV_ATMEL_AUTHENC) /* authenc functions */ static int atmel_sha_authenc_init2(struct atmel_sha_dev *dd); --- linux-oracle-5.4.0.orig/drivers/crypto/axis/artpec6_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/axis/artpec6_crypto.c @@ -1251,7 +1251,7 @@ if (len != 16 && len != 24 && len != 32) { crypto_aead_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -1; + return -EINVAL; } ctx->key_length = len; --- linux-oracle-5.4.0.orig/drivers/crypto/bcm/cipher.c +++ linux-oracle-5.4.0/drivers/crypto/bcm/cipher.c @@ -41,7 +41,7 @@ /* ================= Device Structure ================== */ -struct device_private iproc_priv; +struct bcm_device_private iproc_priv; /* ==================== Parameters ===================== */ @@ -2478,6 +2478,7 @@ static int ahash_hmac_init(struct ahash_request *req) { + int ret; struct iproc_reqctx_s *rctx = ahash_request_ctx(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct iproc_ctx_s *ctx = crypto_ahash_ctx(tfm); @@ -2487,7 +2488,9 @@ flow_log("ahash_hmac_init()\n"); /* init the context as a hash */ - ahash_init(req); + ret = ahash_init(req); + if (ret) + return ret; if (!spu_no_incr_hash(ctx)) { /* SPU-M can do incr hashing but needs sw for outer HMAC */ @@ -2937,7 +2940,6 @@ ctx->enckeylen = keylen; ctx->authkeylen = 0; - memcpy(ctx->enckey, key, ctx->enckeylen); switch (ctx->enckeylen) { case AES_KEYSIZE_128: @@ -2953,6 +2955,8 @@ goto badkey; } + memcpy(ctx->enckey, key, ctx->enckeylen); + flow_log(" enckeylen:%u authkeylen:%u\n", ctx->enckeylen, ctx->authkeylen); flow_dump(" enc: ", ctx->enckey, ctx->enckeylen); @@ -3013,6 +3017,10 @@ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); flow_log("%s\n", __func__); + + if (keylen < GCM_ESP_SALT_SIZE) + return -EINVAL; + ctx->salt_len = GCM_ESP_SALT_SIZE; ctx->salt_offset = GCM_ESP_SALT_OFFSET; memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE); @@ -3041,6 +3049,10 @@ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); flow_log("%s\n", __func__); + + if (keylen < GCM_ESP_SALT_SIZE) + return -EINVAL; + ctx->salt_len = GCM_ESP_SALT_SIZE; ctx->salt_offset = GCM_ESP_SALT_OFFSET; memcpy(ctx->salt, key + keylen - GCM_ESP_SALT_SIZE, GCM_ESP_SALT_SIZE); @@ -3070,6 +3082,10 @@ struct iproc_ctx_s *ctx = crypto_aead_ctx(cipher); flow_log("%s\n", __func__); + + if (keylen < CCM_ESP_SALT_SIZE) + return -EINVAL; + ctx->salt_len = CCM_ESP_SALT_SIZE; ctx->salt_offset = CCM_ESP_SALT_OFFSET; memcpy(ctx->salt, key + keylen - CCM_ESP_SALT_SIZE, CCM_ESP_SALT_SIZE); --- linux-oracle-5.4.0.orig/drivers/crypto/bcm/cipher.h +++ linux-oracle-5.4.0/drivers/crypto/bcm/cipher.h @@ -418,7 +418,7 @@ u32 num_chan; }; -struct device_private { +struct bcm_device_private { struct platform_device *pdev; struct spu_hw spu; @@ -465,6 +465,6 @@ struct mbox_chan **mbox; }; -extern struct device_private iproc_priv; +extern struct bcm_device_private iproc_priv; #endif --- linux-oracle-5.4.0.orig/drivers/crypto/bcm/spu2.c +++ linux-oracle-5.4.0/drivers/crypto/bcm/spu2.c @@ -495,7 +495,7 @@ if (hash_iv_len) { packet_log(" Hash IV Length %u bytes\n", hash_iv_len); packet_dump(" hash IV: ", ptr, hash_iv_len); - ptr += ciph_key_len; + ptr += hash_iv_len; } if (ciph_iv_len) { --- linux-oracle-5.4.0.orig/drivers/crypto/bcm/util.c +++ linux-oracle-5.4.0/drivers/crypto/bcm/util.c @@ -348,7 +348,7 @@ static ssize_t spu_debugfs_read(struct file *filp, char __user *ubuf, size_t count, loff_t *offp) { - struct device_private *ipriv; + struct bcm_device_private *ipriv; char *buf; ssize_t ret, out_offset, out_count; int i; --- linux-oracle-5.4.0.orig/drivers/crypto/caam/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/caam/Kconfig @@ -112,6 +112,7 @@ select CRYPTO_AUTHENC select CRYPTO_BLKCIPHER select CRYPTO_DES + select CRYPTO_XTS help Selecting this will use CAAM Queue Interface (QI) for sending & receiving crypto jobs to/from CAAM. This gives better performance --- linux-oracle-5.4.0.orig/drivers/crypto/caam/caamalg.c +++ linux-oracle-5.4.0/drivers/crypto/caam/caamalg.c @@ -553,7 +553,8 @@ return -EINVAL; } - ctx->cdata.key_virt = key; + memcpy(ctx->key, key, keylen); + ctx->cdata.key_virt = ctx->key; ctx->cdata.keylen = keylen - saltlen; return chachapoly_set_sh_desc(aead); @@ -818,12 +819,6 @@ return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off); } -static int arc4_skcipher_setkey(struct crypto_skcipher *skcipher, - const u8 *key, unsigned int keylen) -{ - return skcipher_setkey(skcipher, key, keylen, 0); -} - static int des_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, unsigned int keylen) { @@ -1810,7 +1805,7 @@ if (ivsize || mapped_dst_nents > 1) sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx + - mapped_dst_nents); + mapped_dst_nents - 1 + !!ivsize); if (sec4_sg_bytes) { edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, @@ -2058,21 +2053,6 @@ }, .caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_ECB, }, - { - .skcipher = { - .base = { - .cra_name = "ecb(arc4)", - .cra_driver_name = "ecb-arc4-caam", - .cra_blocksize = ARC4_BLOCK_SIZE, - }, - .setkey = arc4_skcipher_setkey, - .encrypt = skcipher_encrypt, - .decrypt = skcipher_decrypt, - .min_keysize = ARC4_MIN_KEY_SIZE, - .max_keysize = ARC4_MAX_KEY_SIZE, - }, - .caam.class1_alg_type = OP_ALG_ALGSEL_ARC4 | OP_ALG_AAI_ECB, - }, }; static struct caam_aead_alg driver_aeads[] = { @@ -3533,7 +3513,6 @@ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); int i = 0, err = 0; u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst; - u32 arc4_inst; unsigned int md_limit = SHA512_DIGEST_SIZE; bool registered = false, gcm_support; @@ -3553,8 +3532,6 @@ CHA_ID_LS_DES_SHIFT; aes_inst = cha_inst & CHA_ID_LS_AES_MASK; md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; - arc4_inst = (cha_inst & CHA_ID_LS_ARC4_MASK) >> - CHA_ID_LS_ARC4_SHIFT; ccha_inst = 0; ptha_inst = 0; @@ -3575,7 +3552,6 @@ md_inst = mdha & CHA_VER_NUM_MASK; ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK; ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK; - arc4_inst = rd_reg32(&priv->ctrl->vreg.afha) & CHA_VER_NUM_MASK; gcm_support = aesa & CHA_VER_MISC_AES_GCM; } @@ -3598,10 +3574,6 @@ if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES)) continue; - /* Skip ARC4 algorithms if not supported by device */ - if (!arc4_inst && alg_sel == OP_ALG_ALGSEL_ARC4) - continue; - /* * Check support for AES modes not available * on LP devices. --- linux-oracle-5.4.0.orig/drivers/crypto/caam/caamalg_desc.c +++ linux-oracle-5.4.0/drivers/crypto/caam/caamalg_desc.c @@ -1379,6 +1379,9 @@ const u32 ctx1_iv_off) { u32 *key_jump_cmd; + u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT; + bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_CHACHA20); init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); /* Skip if already shared */ @@ -1417,14 +1420,15 @@ LDST_OFFSET_SHIFT)); /* Load operation */ - append_operation(desc, cdata->algtype | OP_ALG_AS_INIT | - OP_ALG_ENCRYPT); + if (is_chacha20) + options |= OP_ALG_AS_FINALIZE; + append_operation(desc, options); /* Perform operation */ skcipher_append_src_dst(desc); /* Store IV */ - if (ivsize) + if (!is_chacha20 && ivsize) append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT)); @@ -1451,6 +1455,8 @@ const u32 ctx1_iv_off) { u32 *key_jump_cmd; + bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) == + OP_ALG_ALGSEL_CHACHA20); init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); /* Skip if already shared */ @@ -1499,7 +1505,7 @@ skcipher_append_src_dst(desc); /* Store IV */ - if (ivsize) + if (!is_chacha20 && ivsize) append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT)); @@ -1518,7 +1524,13 @@ */ void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata) { - __be64 sector_size = cpu_to_be64(512); + /* + * Set sector size to a big value, practically disabling + * sector size segmentation in xts implementation. We cannot + * take full advantage of this HW feature with existing + * crypto API / dm-crypt SW architecture. + */ + __be64 sector_size = cpu_to_be64(BIT(15)); u32 *key_jump_cmd; init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); @@ -1571,7 +1583,13 @@ */ void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata) { - __be64 sector_size = cpu_to_be64(512); + /* + * Set sector size to a big value, practically disabling + * sector size segmentation in xts implementation. We cannot + * take full advantage of this HW feature with existing + * crypto API / dm-crypt SW architecture. + */ + __be64 sector_size = cpu_to_be64(BIT(15)); u32 *key_jump_cmd; init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); --- linux-oracle-5.4.0.orig/drivers/crypto/caam/caamalg_qi.c +++ linux-oracle-5.4.0/drivers/crypto/caam/caamalg_qi.c @@ -18,6 +18,7 @@ #include "qi.h" #include "jr.h" #include "caamalg_desc.h" +#include /* * crypto alg @@ -67,6 +68,11 @@ struct device *qidev; spinlock_t lock; /* Protects multiple init of driver context */ struct caam_drv_ctx *drv_ctx[NUM_OP]; + struct crypto_skcipher *fallback; +}; + +struct caam_skcipher_req_ctx { + struct skcipher_request fallback_req; }; static int aead_set_sh_desc(struct crypto_aead *aead) @@ -745,12 +751,17 @@ struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher); struct device *jrdev = ctx->jrdev; int ret = 0; + int err; if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) { dev_err(jrdev, "key size mismatch\n"); goto badkey; } + err = crypto_skcipher_setkey(ctx->fallback, key, keylen); + if (err) + return err; + ctx->cdata.keylen = keylen; ctx->cdata.key_virt = key; ctx->cdata.key_inline = true; @@ -1395,6 +1406,14 @@ return edesc; } +static inline bool xts_skcipher_ivsize(struct skcipher_request *req) +{ + struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); + unsigned int ivsize = crypto_skcipher_ivsize(skcipher); + + return !!get_unaligned((u64 *)(req->iv + (ivsize / 2))); +} + static inline int skcipher_crypt(struct skcipher_request *req, bool encrypt) { struct skcipher_edesc *edesc; @@ -1405,6 +1424,21 @@ if (!req->cryptlen) return 0; + if (ctx->fallback && xts_skcipher_ivsize(req)) { + struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req); + + skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); + skcipher_request_set_callback(&rctx->fallback_req, + req->base.flags, + req->base.complete, + req->base.data); + skcipher_request_set_crypt(&rctx->fallback_req, req->src, + req->dst, req->cryptlen, req->iv); + + return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) : + crypto_skcipher_decrypt(&rctx->fallback_req); + } + if (unlikely(caam_congested)) return -EAGAIN; @@ -1529,6 +1563,7 @@ .base = { .cra_name = "xts(aes)", .cra_driver_name = "xts-aes-caam-qi", + .cra_flags = CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, }, .setkey = xts_skcipher_setkey, @@ -2462,9 +2497,32 @@ struct skcipher_alg *alg = crypto_skcipher_alg(tfm); struct caam_skcipher_alg *caam_alg = container_of(alg, typeof(*caam_alg), skcipher); + struct caam_ctx *ctx = crypto_skcipher_ctx(tfm); + u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK; + int ret = 0; + + if (alg_aai == OP_ALG_AAI_XTS) { + const char *tfm_name = crypto_tfm_alg_name(&tfm->base); + struct crypto_skcipher *fallback; + + fallback = crypto_alloc_skcipher(tfm_name, 0, + CRYPTO_ALG_NEED_FALLBACK); + if (IS_ERR(fallback)) { + dev_err(ctx->jrdev, "Failed to allocate %s fallback: %ld\n", + tfm_name, PTR_ERR(fallback)); + return PTR_ERR(fallback); + } + + ctx->fallback = fallback; + crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx) + + crypto_skcipher_reqsize(fallback)); + } + + ret = caam_init_common(ctx, &caam_alg->caam, false); + if (ret && ctx->fallback) + crypto_free_skcipher(ctx->fallback); - return caam_init_common(crypto_skcipher_ctx(tfm), &caam_alg->caam, - false); + return ret; } static int caam_aead_init(struct crypto_aead *tfm) @@ -2490,7 +2548,11 @@ static void caam_cra_exit(struct crypto_skcipher *tfm) { - caam_exit_common(crypto_skcipher_ctx(tfm)); + struct caam_ctx *ctx = crypto_skcipher_ctx(tfm); + + if (ctx->fallback) + crypto_free_skcipher(ctx->fallback); + caam_exit_common(ctx); } static void caam_aead_exit(struct crypto_aead *tfm) @@ -2524,7 +2586,7 @@ alg->base.cra_module = THIS_MODULE; alg->base.cra_priority = CAAM_CRA_PRIORITY; alg->base.cra_ctxsize = sizeof(struct caam_ctx); - alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; + alg->base.cra_flags |= CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY; alg->init = caam_cra_init; alg->exit = caam_cra_exit; --- linux-oracle-5.4.0.orig/drivers/crypto/caam/caamalg_qi2.c +++ linux-oracle-5.4.0/drivers/crypto/caam/caamalg_qi2.c @@ -639,7 +639,8 @@ return -EINVAL; } - ctx->cdata.key_virt = key; + memcpy(ctx->key, key, keylen); + ctx->cdata.key_virt = ctx->key; ctx->cdata.keylen = keylen - saltlen; return chachapoly_set_sh_desc(aead); @@ -2481,7 +2482,7 @@ .cra_name = "echainiv(authenc(hmac(sha256)," "cbc(des)))", .cra_driver_name = "echainiv-authenc-" - "hmac-sha256-cbc-desi-" + "hmac-sha256-cbc-des-" "caam-qi2", .cra_blocksize = DES_BLOCK_SIZE, }, @@ -5421,7 +5422,7 @@ dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1])); dpaa2_fd_set_flc(&fd, req->flc_dma); - ppriv = this_cpu_ptr(priv->ppriv); + ppriv = raw_cpu_ptr(priv->ppriv); for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) { err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid, &fd); --- linux-oracle-5.4.0.orig/drivers/crypto/caam/caampkc.c +++ linux-oracle-5.4.0/drivers/crypto/caam/caampkc.c @@ -225,7 +225,9 @@ if (len && *buff) break; - sg_miter_next(&miter); + if (!sg_miter_next(&miter)) + break; + buff = miter.addr; len = miter.length; @@ -1087,16 +1089,27 @@ int caam_pkc_init(struct device *ctrldev) { struct caam_drv_private *priv = dev_get_drvdata(ctrldev); - u32 pk_inst; + u32 pk_inst, pkha; int err; init_done = false; /* Determine public key hardware accelerator presence. */ - if (priv->era < 10) + if (priv->era < 10) { pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; - else - pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK; + } else { + pkha = rd_reg32(&priv->ctrl->vreg.pkha); + pk_inst = pkha & CHA_VER_NUM_MASK; + + /* + * Newer CAAMs support partially disabled functionality. If this is the + * case, the number is non-zero, but this bit is set to indicate that + * no encryption or decryption is supported. Only signing and verifying + * is supported. + */ + if (pkha & CHA_VER_MISC_PKHA_NO_CRYPT) + pk_inst = 0; + } /* Do not register algorithms if PKHA is not present. */ if (!pk_inst) --- linux-oracle-5.4.0.orig/drivers/crypto/caam/compat.h +++ linux-oracle-5.4.0/drivers/crypto/caam/compat.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include --- linux-oracle-5.4.0.orig/drivers/crypto/caam/ctrl.c +++ linux-oracle-5.4.0/drivers/crypto/caam/ctrl.c @@ -685,11 +685,9 @@ of_node_put(np); if (!ctrlpriv->mc_en) - clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, + clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | - MCFGR_WDENABLE | MCFGR_LARGE_BURST | - (sizeof(dma_addr_t) == sizeof(u64) ? - MCFGR_LONG_PTR : 0)); + MCFGR_WDENABLE | MCFGR_LARGE_BURST); handle_imx6_err005766(&ctrl->mcr); --- linux-oracle-5.4.0.orig/drivers/crypto/caam/regs.h +++ linux-oracle-5.4.0/drivers/crypto/caam/regs.h @@ -317,6 +317,9 @@ /* CHA Miscellaneous Information - AESA_MISC specific */ #define CHA_VER_MISC_AES_GCM BIT(1 + CHA_VER_MISC_SHIFT) +/* CHA Miscellaneous Information - PKHA_MISC specific */ +#define CHA_VER_MISC_PKHA_NO_CRYPT BIT(7 + CHA_VER_MISC_SHIFT) + /* * caam_perfmon - Performance Monitor/Secure Memory Status/ * CAAM Global Status/Component Version IDs --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/cpt/cptpf_main.c +++ linux-oracle-5.4.0/drivers/crypto/cavium/cpt/cptpf_main.c @@ -45,7 +45,7 @@ dev_err(dev, "Cores still busy %llx", coremask); grp = cpt_read_csr64(cpt->reg_base, CPTX_PF_EXEC_BUSY(0)); - if (timeout--) + if (!timeout--) break; udelay(CSR_DELAY); @@ -254,6 +254,7 @@ const struct firmware *fw_entry; struct device *dev = &cpt->pdev->dev; struct ucode_header *ucode; + unsigned int code_length; struct microcode *mcode; int j, ret = 0; @@ -264,11 +265,12 @@ ucode = (struct ucode_header *)fw_entry->data; mcode = &cpt->mcode[cpt->next_mc_idx]; memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ); - mcode->code_size = ntohl(ucode->code_length) * 2; - if (!mcode->code_size) { + code_length = ntohl(ucode->code_length); + if (code_length == 0 || code_length >= INT_MAX / 2) { ret = -EINVAL; goto fw_release; } + mcode->code_size = code_length * 2; mcode->is_ae = is_ae; mcode->core_mask = 0ULL; @@ -301,6 +303,8 @@ ret = do_cpt_init(cpt, mcode); if (ret) { + dma_free_coherent(&cpt->pdev->dev, mcode->code_size, + mcode->code, mcode->phys_base); dev_err(dev, "do_cpt_init failed with ret: %d\n", ret); goto fw_release; } @@ -393,7 +397,7 @@ dev_err(dev, "Cores still busy"); grp = cpt_read_csr64(cpt->reg_base, CPTX_PF_EXEC_BUSY(0)); - if (timeout--) + if (!timeout--) break; udelay(CSR_DELAY); --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/cpt/cptvf_algs.c +++ linux-oracle-5.4.0/drivers/crypto/cavium/cpt/cptvf_algs.c @@ -200,6 +200,7 @@ int status; memset(req_info, 0, sizeof(struct cpt_request_info)); + req_info->may_sleep = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) != 0; memset(fctx, 0, sizeof(struct fc_context)); create_input_list(req, enc, enc_iv_len); create_output_list(req, enc_iv_len); --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/cpt/cptvf_reqmanager.c +++ linux-oracle-5.4.0/drivers/crypto/cavium/cpt/cptvf_reqmanager.c @@ -133,7 +133,7 @@ /* Setup gather (input) components */ g_sz_bytes = ((req->incnt + 3) / 4) * sizeof(struct sglist_component); - info->gather_components = kzalloc(g_sz_bytes, GFP_KERNEL); + info->gather_components = kzalloc(g_sz_bytes, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (!info->gather_components) { ret = -ENOMEM; goto scatter_gather_clean; @@ -150,7 +150,7 @@ /* Setup scatter (output) components */ s_sz_bytes = ((req->outcnt + 3) / 4) * sizeof(struct sglist_component); - info->scatter_components = kzalloc(s_sz_bytes, GFP_KERNEL); + info->scatter_components = kzalloc(s_sz_bytes, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (!info->scatter_components) { ret = -ENOMEM; goto scatter_gather_clean; @@ -167,7 +167,7 @@ /* Create and initialize DPTR */ info->dlen = g_sz_bytes + s_sz_bytes + SG_LIST_HDR_SIZE; - info->in_buffer = kzalloc(info->dlen, GFP_KERNEL); + info->in_buffer = kzalloc(info->dlen, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (!info->in_buffer) { ret = -ENOMEM; goto scatter_gather_clean; @@ -195,7 +195,7 @@ } /* Create and initialize RPTR */ - info->out_buffer = kzalloc(COMPLETION_CODE_SIZE, GFP_KERNEL); + info->out_buffer = kzalloc(COMPLETION_CODE_SIZE, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (!info->out_buffer) { ret = -ENOMEM; goto scatter_gather_clean; @@ -421,7 +421,7 @@ struct cpt_vq_command vq_cmd; union cpt_inst_s cptinst; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc(sizeof(*info), req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (unlikely(!info)) { dev_err(&pdev->dev, "Unable to allocate memory for info_buffer\n"); return -ENOMEM; @@ -443,7 +443,7 @@ * Get buffer for union cpt_res_s response * structure and its physical address */ - info->completion_addr = kzalloc(sizeof(union cpt_res_s), GFP_KERNEL); + info->completion_addr = kzalloc(sizeof(union cpt_res_s), req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (unlikely(!info->completion_addr)) { dev_err(&pdev->dev, "Unable to allocate memory for completion_addr\n"); ret = -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/cpt/request_manager.h +++ linux-oracle-5.4.0/drivers/crypto/cavium/cpt/request_manager.h @@ -62,6 +62,8 @@ union ctrl_info ctrl; /* User control information */ struct cptvf_request req; /* Request Information (Core specific) */ + bool may_sleep; + struct buf_ptr in[MAX_BUF_CNT]; struct buf_ptr out[MAX_BUF_CNT]; --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/nitrox/nitrox_isr.c +++ linux-oracle-5.4.0/drivers/crypto/cavium/nitrox/nitrox_isr.c @@ -306,6 +306,10 @@ * Entry 192: NPS_CORE_INT_ACTIVE */ nr_vecs = pci_msix_vec_count(pdev); + if (nr_vecs < 0) { + dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs); + return nr_vecs; + } /* Enable MSI-X */ ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX); --- linux-oracle-5.4.0.orig/drivers/crypto/cavium/nitrox/nitrox_main.c +++ linux-oracle-5.4.0/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -103,8 +103,7 @@ offset = UCD_UCODE_LOAD_BLOCK_NUM; nitrox_write_csr(ndev, offset, block_num); - code_size = ucode_size; - code_size = roundup(code_size, 8); + code_size = roundup(ucode_size, 16); while (code_size) { data = ucode_data[i]; /* write 8 bytes at a time */ @@ -220,11 +219,11 @@ /* write block number and firmware length * bit:<2:0> block number - * bit:3 is set SE uses 32KB microcode - * bit:3 is clear SE uses 64KB microcode + * bit:3 is set AE uses 32KB microcode + * bit:3 is clear AE uses 64KB microcode */ core_2_eid_val.value = 0ULL; - core_2_eid_val.ucode_blk = 0; + core_2_eid_val.ucode_blk = 2; if (ucode_size <= CNN55XX_UCD_BLOCK_SIZE) core_2_eid_val.ucode_len = 1; else @@ -279,7 +278,7 @@ struct nitrox_device *nitrox_get_first_device(void) { - struct nitrox_device *ndev = NULL; + struct nitrox_device *ndev; mutex_lock(&devlist_lock); list_for_each_entry(ndev, &ndevlist, list) { @@ -287,7 +286,7 @@ break; } mutex_unlock(&devlist_lock); - if (!ndev) + if (&ndev->list == &ndevlist) return NULL; refcount_inc(&ndev->refcnt); --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/ccp/Kconfig @@ -10,10 +10,9 @@ config CRYPTO_DEV_SP_CCP bool "Cryptographic Coprocessor device" default y - depends on CRYPTO_DEV_CCP_DD + depends on CRYPTO_DEV_CCP_DD && DMADEVICES select HW_RANDOM select DMA_ENGINE - select DMADEVICES select CRYPTO_SHA1 select CRYPTO_SHA256 help --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/ccp-dev-v3.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/ccp-dev-v3.c @@ -586,6 +586,7 @@ .setup = NULL, .perform = &ccp3_actions, .offset = 0, + .rsamax = CCP_RSA_MAX_WIDTH, }; const struct ccp_vdata ccpv3 = { --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/ccp-dev.h +++ linux-oracle-5.4.0/drivers/crypto/ccp/ccp-dev.h @@ -469,6 +469,7 @@ unsigned int sg_used; struct scatterlist *dma_sg; + struct scatterlist *dma_sg_head; struct device *dma_dev; unsigned int dma_count; enum dma_data_direction dma_dir; --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/ccp-dmaengine.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/ccp-dmaengine.c @@ -342,6 +342,7 @@ desc->tx_desc.flags = flags; desc->tx_desc.tx_submit = ccp_tx_submit; desc->ccp = chan->ccp; + INIT_LIST_HEAD(&desc->entry); INIT_LIST_HEAD(&desc->pending); INIT_LIST_HEAD(&desc->active); desc->status = DMA_IN_PROGRESS; @@ -632,6 +633,36 @@ return 0; } +static void ccp_dma_release(struct ccp_device *ccp) +{ + struct ccp_dma_chan *chan; + struct dma_chan *dma_chan; + unsigned int i; + + for (i = 0; i < ccp->cmd_q_count; i++) { + chan = ccp->ccp_dma_chan + i; + dma_chan = &chan->dma_chan; + + tasklet_kill(&chan->cleanup_tasklet); + list_del_rcu(&dma_chan->device_node); + } +} + +static void ccp_dma_release_channels(struct ccp_device *ccp) +{ + struct ccp_dma_chan *chan; + struct dma_chan *dma_chan; + unsigned int i; + + for (i = 0; i < ccp->cmd_q_count; i++) { + chan = ccp->ccp_dma_chan + i; + dma_chan = &chan->dma_chan; + + if (dma_chan->client_count) + dma_release_channel(dma_chan); + } +} + int ccp_dmaengine_register(struct ccp_device *ccp) { struct ccp_dma_chan *chan; @@ -736,6 +767,7 @@ return 0; err_reg: + ccp_dma_release(ccp); kmem_cache_destroy(ccp->dma_desc_cache); err_cache: @@ -751,7 +783,9 @@ if (!dmaengine) return; + ccp_dma_release_channels(ccp); dma_async_device_unregister(dma_dev); + ccp_dma_release(ccp); kmem_cache_destroy(ccp->dma_desc_cache); kmem_cache_destroy(ccp->dma_cmd_cache); --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/ccp-ops.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/ccp-ops.c @@ -63,7 +63,7 @@ static void ccp_sg_free(struct ccp_sg_workarea *wa) { if (wa->dma_count) - dma_unmap_sg(wa->dma_dev, wa->dma_sg, wa->nents, wa->dma_dir); + dma_unmap_sg(wa->dma_dev, wa->dma_sg_head, wa->nents, wa->dma_dir); wa->dma_count = 0; } @@ -92,6 +92,7 @@ return 0; wa->dma_sg = sg; + wa->dma_sg_head = sg; wa->dma_dev = dev; wa->dma_dir = dma_dir; wa->dma_count = dma_map_sg(dev, sg, wa->nents, dma_dir); @@ -104,14 +105,28 @@ static void ccp_update_sg_workarea(struct ccp_sg_workarea *wa, unsigned int len) { unsigned int nbytes = min_t(u64, len, wa->bytes_left); + unsigned int sg_combined_len = 0; if (!wa->sg) return; wa->sg_used += nbytes; wa->bytes_left -= nbytes; - if (wa->sg_used == wa->sg->length) { - wa->sg = sg_next(wa->sg); + if (wa->sg_used == sg_dma_len(wa->dma_sg)) { + /* Advance to the next DMA scatterlist entry */ + wa->dma_sg = sg_next(wa->dma_sg); + + /* In the case that the DMA mapped scatterlist has entries + * that have been merged, the non-DMA mapped scatterlist + * must be advanced multiple times for each merged entry. + * This ensures that the current non-DMA mapped entry + * corresponds to the current DMA mapped entry. + */ + do { + sg_combined_len += wa->sg->length; + wa->sg = sg_next(wa->sg); + } while (wa->sg_used > sg_combined_len); + wa->sg_used = 0; } } @@ -163,8 +178,11 @@ wa->dma.address = dma_map_single(wa->dev, wa->address, len, dir); - if (dma_mapping_error(wa->dev, wa->dma.address)) + if (dma_mapping_error(wa->dev, wa->dma.address)) { + kfree(wa->address); + wa->address = NULL; return -ENOMEM; + } wa->dma.length = len; } @@ -299,7 +317,7 @@ /* Update the structures and generate the count */ buf_count = 0; while (sg_wa->bytes_left && (buf_count < dm_wa->length)) { - nbytes = min(sg_wa->sg->length - sg_wa->sg_used, + nbytes = min(sg_dma_len(sg_wa->dma_sg) - sg_wa->sg_used, dm_wa->length - buf_count); nbytes = min_t(u64, sg_wa->bytes_left, nbytes); @@ -331,11 +349,11 @@ * and destination. The resulting len values will always be <= UINT_MAX * because the dma length is an unsigned int. */ - sg_src_len = sg_dma_len(src->sg_wa.sg) - src->sg_wa.sg_used; + sg_src_len = sg_dma_len(src->sg_wa.dma_sg) - src->sg_wa.sg_used; sg_src_len = min_t(u64, src->sg_wa.bytes_left, sg_src_len); if (dst) { - sg_dst_len = sg_dma_len(dst->sg_wa.sg) - dst->sg_wa.sg_used; + sg_dst_len = sg_dma_len(dst->sg_wa.dma_sg) - dst->sg_wa.sg_used; sg_dst_len = min_t(u64, src->sg_wa.bytes_left, sg_dst_len); op_len = min(sg_src_len, sg_dst_len); } else { @@ -365,7 +383,7 @@ /* Enough data in the sg element, but we need to * adjust for any previously copied data */ - op->src.u.dma.address = sg_dma_address(src->sg_wa.sg); + op->src.u.dma.address = sg_dma_address(src->sg_wa.dma_sg); op->src.u.dma.offset = src->sg_wa.sg_used; op->src.u.dma.length = op_len & ~(block_size - 1); @@ -386,7 +404,7 @@ /* Enough room in the sg element, but we need to * adjust for any previously used area */ - op->dst.u.dma.address = sg_dma_address(dst->sg_wa.sg); + op->dst.u.dma.address = sg_dma_address(dst->sg_wa.dma_sg); op->dst.u.dma.offset = dst->sg_wa.sg_used; op->dst.u.dma.length = op->src.u.dma.length; } @@ -763,7 +781,7 @@ in_place ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE); if (ret) - goto e_ctx; + goto e_aad; if (in_place) { dst = src; @@ -848,7 +866,7 @@ op.u.aes.size = 0; ret = cmd_q->ccp->vdata->perform->aes(&op); if (ret) - goto e_dst; + goto e_final_wa; if (aes->action == CCP_AES_ACTION_ENCRYPT) { /* Put the ciphered tag after the ciphertext. */ @@ -858,17 +876,19 @@ ret = ccp_init_dm_workarea(&tag, cmd_q, authsize, DMA_BIDIRECTIONAL); if (ret) - goto e_tag; + goto e_final_wa; ret = ccp_set_dm_area(&tag, 0, p_tag, 0, authsize); - if (ret) - goto e_tag; + if (ret) { + ccp_dm_free(&tag); + goto e_final_wa; + } ret = crypto_memneq(tag.address, final_wa.address, authsize) ? -EBADMSG : 0; ccp_dm_free(&tag); } -e_tag: +e_final_wa: ccp_dm_free(&final_wa); e_dst: @@ -1731,7 +1751,7 @@ break; default: ret = -EINVAL; - goto e_ctx; + goto e_data; } } else { /* Stash the context */ @@ -1777,8 +1797,9 @@ LSB_ITEM_SIZE); break; default: + kfree(hmac_buf); ret = -EINVAL; - goto e_ctx; + goto e_data; } memset(&hmac_cmd, 0, sizeof(hmac_cmd)); @@ -2027,7 +2048,7 @@ dst.sg_wa.sg_used = 0; for (i = 1; i <= src.sg_wa.dma_count; i++) { if (!dst.sg_wa.sg || - (dst.sg_wa.sg->length < src.sg_wa.sg->length)) { + (sg_dma_len(dst.sg_wa.sg) < sg_dma_len(src.sg_wa.sg))) { ret = -EINVAL; goto e_dst; } @@ -2053,8 +2074,8 @@ goto e_dst; } - dst.sg_wa.sg_used += src.sg_wa.sg->length; - if (dst.sg_wa.sg_used == dst.sg_wa.sg->length) { + dst.sg_wa.sg_used += sg_dma_len(src.sg_wa.sg); + if (dst.sg_wa.sg_used == sg_dma_len(dst.sg_wa.sg)) { dst.sg_wa.sg = sg_next(dst.sg_wa.sg); dst.sg_wa.sg_used = 0; } --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/psp-dev.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/psp-dev.c @@ -40,6 +40,10 @@ module_param(psp_probe_timeout, int, 0644); MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe"); +MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ +MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ +MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ + static bool psp_dead; static int psp_timeout; --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/sp-pci.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/sp-pci.c @@ -213,7 +213,7 @@ if (ret) { dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); - goto e_err; + goto free_irqs; } } @@ -221,10 +221,12 @@ ret = sp_init(sp); if (ret) - goto e_err; + goto free_irqs; return 0; +free_irqs: + sp_free_irqs(sp); e_err: dev_notice(dev, "initialization failed\n"); return ret; --- linux-oracle-5.4.0.orig/drivers/crypto/ccp/sp-platform.c +++ linux-oracle-5.4.0/drivers/crypto/ccp/sp-platform.c @@ -39,44 +39,38 @@ }, }; -#ifdef CONFIG_ACPI static const struct acpi_device_id sp_acpi_match[] = { { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(acpi, sp_acpi_match); -#endif -#ifdef CONFIG_OF static const struct of_device_id sp_of_match[] = { { .compatible = "amd,ccp-seattle-v1a", .data = (const void *)&dev_vdata[0] }, { }, }; MODULE_DEVICE_TABLE(of, sp_of_match); -#endif static struct sp_dev_vdata *sp_get_of_version(struct platform_device *pdev) { -#ifdef CONFIG_OF const struct of_device_id *match; match = of_match_node(sp_of_match, pdev->dev.of_node); if (match && match->data) return (struct sp_dev_vdata *)match->data; -#endif + return NULL; } static struct sp_dev_vdata *sp_get_acpi_version(struct platform_device *pdev) { -#ifdef CONFIG_ACPI const struct acpi_device_id *match; match = acpi_match_device(sp_acpi_match, &pdev->dev); if (match && match->driver_data) return (struct sp_dev_vdata *)match->driver_data; -#endif + return NULL; } @@ -222,12 +216,8 @@ static struct platform_driver sp_platform_driver = { .driver = { .name = "ccp", -#ifdef CONFIG_ACPI .acpi_match_table = sp_acpi_match, -#endif -#ifdef CONFIG_OF .of_match_table = sp_of_match, -#endif }, .probe = sp_platform_probe, .remove = sp_platform_remove, --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_aead.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_aead.c @@ -237,7 +237,7 @@ * revealed the decrypted message --> zero its memory. */ sg_zero_buffer(areq->dst, sg_nents(areq->dst), - areq->cryptlen, 0); + areq->cryptlen, areq->assoclen); err = -EBADMSG; } /*ENCRYPT*/ --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_buffer_mgr.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_buffer_mgr.c @@ -87,6 +87,8 @@ { unsigned int nents = 0; + *lbytes = 0; + while (nbytes && sg_list) { nents++; /* get the number of bytes in the last entry */ @@ -95,6 +97,7 @@ nbytes : sg_list->length; sg_list = sg_next(sg_list); } + dev_dbg(dev, "nents %d last bytes %d\n", nents, *lbytes); return nents; } @@ -290,37 +293,32 @@ unsigned int nbytes, int direction, u32 *nents, u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents) { - if (sg_is_last(sg)) { - /* One entry only case -set to DLLI */ - if (dma_map_sg(dev, sg, 1, direction) != 1) { - dev_err(dev, "dma_map_sg() single buffer failed\n"); - return -ENOMEM; - } - dev_dbg(dev, "Mapped sg: dma_address=%pad page=%p addr=%pK offset=%u length=%u\n", - &sg_dma_address(sg), sg_page(sg), sg_virt(sg), - sg->offset, sg->length); - *lbytes = nbytes; - *nents = 1; - *mapped_nents = 1; - } else { /*sg_is_last*/ - *nents = cc_get_sgl_nents(dev, sg, nbytes, lbytes); - if (*nents > max_sg_nents) { - *nents = 0; - dev_err(dev, "Too many fragments. current %d max %d\n", - *nents, max_sg_nents); - return -ENOMEM; - } - /* In case of mmu the number of mapped nents might - * be changed from the original sgl nents - */ - *mapped_nents = dma_map_sg(dev, sg, *nents, direction); - if (*mapped_nents == 0) { - *nents = 0; - dev_err(dev, "dma_map_sg() sg buffer failed\n"); - return -ENOMEM; - } + int ret = 0; + + if (!nbytes) { + *mapped_nents = 0; + *lbytes = 0; + *nents = 0; + return 0; } + *nents = cc_get_sgl_nents(dev, sg, nbytes, lbytes); + if (*nents > max_sg_nents) { + *nents = 0; + dev_err(dev, "Too many fragments. current %d max %d\n", + *nents, max_sg_nents); + return -ENOMEM; + } + + ret = dma_map_sg(dev, sg, *nents, direction); + if (dma_mapping_error(dev, ret)) { + *nents = 0; + dev_err(dev, "dma_map_sg() sg buffer failed %d\n", ret); + return -ENOMEM; + } + + *mapped_nents = ret; + return 0; } @@ -555,11 +553,12 @@ sg_virt(req->src), areq_ctx->src.nents, areq_ctx->assoc.nents, areq_ctx->assoclen, req->cryptlen); - dma_unmap_sg(dev, req->src, sg_nents(req->src), DMA_BIDIRECTIONAL); + dma_unmap_sg(dev, req->src, areq_ctx->src.mapped_nents, + DMA_BIDIRECTIONAL); if (req->src != req->dst) { dev_dbg(dev, "Unmapping dst sgl: req->dst=%pK\n", sg_virt(req->dst)); - dma_unmap_sg(dev, req->dst, sg_nents(req->dst), + dma_unmap_sg(dev, req->dst, areq_ctx->dst.mapped_nents, DMA_BIDIRECTIONAL); } if (drvdata->coherent && @@ -881,7 +880,7 @@ &src_last_bytes); sg_index = areq_ctx->src_sgl->length; //check where the data starts - while (sg_index <= size_to_skip) { + while (src_mapped_nents && (sg_index <= size_to_skip)) { src_mapped_nents--; offset -= areq_ctx->src_sgl->length; sgl = sg_next(areq_ctx->src_sgl); @@ -902,13 +901,17 @@ if (req->src != req->dst) { size_for_map = areq_ctx->assoclen + req->cryptlen; - size_for_map += (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) ? - authsize : 0; + + if (direct == DRV_CRYPTO_DIRECTION_ENCRYPT) + size_for_map += authsize; + else + size_for_map -= authsize; + if (is_gcm4543) size_for_map += crypto_aead_ivsize(tfm); rc = cc_map_sg(dev, req->dst, size_for_map, DMA_BIDIRECTIONAL, - &areq_ctx->dst.nents, + &areq_ctx->dst.mapped_nents, LLI_MAX_NUM_OF_DATA_ENTRIES, &dst_last_bytes, &dst_mapped_nents); if (rc) @@ -921,7 +924,7 @@ offset = size_to_skip; //check where the data starts - while (sg_index <= size_to_skip) { + while (dst_mapped_nents && sg_index <= size_to_skip) { dst_mapped_nents--; offset -= areq_ctx->dst_sgl->length; sgl = sg_next(areq_ctx->dst_sgl); @@ -1117,13 +1120,15 @@ } size_to_map = req->cryptlen + areq_ctx->assoclen; - if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_ENCRYPT) + /* If we do in-place encryption, we also need the auth tag */ + if ((areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_ENCRYPT) && + (req->src == req->dst)) { size_to_map += authsize; - + } if (is_gcm4543) size_to_map += crypto_aead_ivsize(tfm); rc = cc_map_sg(dev, req->src, size_to_map, DMA_BIDIRECTIONAL, - &areq_ctx->src.nents, + &areq_ctx->src.mapped_nents, (LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES + LLI_MAX_NUM_OF_DATA_ENTRIES), &dummy, &mapped_nents); --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_buffer_mgr.h +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_buffer_mgr.h @@ -25,6 +25,7 @@ struct cc_mlli { cc_sram_addr_t sram_addr; + unsigned int mapped_nents; unsigned int nents; //sg nents unsigned int mlli_nents; //mlli nents might be different than the above }; --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_cipher.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_cipher.c @@ -163,7 +163,6 @@ skcipher_alg.base); struct device *dev = drvdata_to_dev(cc_alg->drvdata); unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize; - int rc = 0; dev_dbg(dev, "Initializing context @%p for %s\n", ctx_p, crypto_tfm_alg_name(tfm)); @@ -175,10 +174,19 @@ ctx_p->flow_mode = cc_alg->flow_mode; ctx_p->drvdata = cc_alg->drvdata; + if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { + /* Alloc hash tfm for essiv */ + ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0); + if (IS_ERR(ctx_p->shash_tfm)) { + dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); + return PTR_ERR(ctx_p->shash_tfm); + } + } + /* Allocate key buffer, cache line aligned */ ctx_p->user.key = kmalloc(max_key_buf_size, GFP_KERNEL); if (!ctx_p->user.key) - return -ENOMEM; + goto free_shash; dev_dbg(dev, "Allocated key buffer in context. key=@%p\n", ctx_p->user.key); @@ -190,21 +198,19 @@ if (dma_mapping_error(dev, ctx_p->user.key_dma_addr)) { dev_err(dev, "Mapping Key %u B at va=%pK for DMA failed\n", max_key_buf_size, ctx_p->user.key); - return -ENOMEM; + goto free_key; } dev_dbg(dev, "Mapped key %u B at va=%pK to dma=%pad\n", max_key_buf_size, ctx_p->user.key, &ctx_p->user.key_dma_addr); - if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) { - /* Alloc hash tfm for essiv */ - ctx_p->shash_tfm = crypto_alloc_shash("sha256-generic", 0, 0); - if (IS_ERR(ctx_p->shash_tfm)) { - dev_err(dev, "Error allocating hash tfm for ESSIV.\n"); - return PTR_ERR(ctx_p->shash_tfm); - } - } + return 0; - return rc; +free_key: + kfree(ctx_p->user.key); +free_shash: + crypto_free_shash(ctx_p->shash_tfm); + + return -ENOMEM; } static void cc_cipher_exit(struct crypto_tfm *tfm) @@ -523,6 +529,7 @@ } } + static void cc_setup_state_desc(struct crypto_tfm *tfm, struct cipher_req_ctx *req_ctx, unsigned int ivsize, unsigned int nbytes, @@ -534,8 +541,6 @@ int cipher_mode = ctx_p->cipher_mode; int flow_mode = ctx_p->flow_mode; int direction = req_ctx->gen_ctx.op_type; - dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr; - unsigned int key_len = ctx_p->keylen; dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; unsigned int du_size = nbytes; @@ -571,6 +576,47 @@ case DRV_CIPHER_XTS: case DRV_CIPHER_ESSIV: case DRV_CIPHER_BITLOCKER: + break; + default: + dev_err(dev, "Unsupported cipher mode (%d)\n", cipher_mode); + } +} + + +static void cc_setup_xex_state_desc(struct crypto_tfm *tfm, + struct cipher_req_ctx *req_ctx, + unsigned int ivsize, unsigned int nbytes, + struct cc_hw_desc desc[], + unsigned int *seq_size) +{ + struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm); + struct device *dev = drvdata_to_dev(ctx_p->drvdata); + int cipher_mode = ctx_p->cipher_mode; + int flow_mode = ctx_p->flow_mode; + int direction = req_ctx->gen_ctx.op_type; + dma_addr_t key_dma_addr = ctx_p->user.key_dma_addr; + unsigned int key_len = ctx_p->keylen; + dma_addr_t iv_dma_addr = req_ctx->gen_ctx.iv_dma_addr; + unsigned int du_size = nbytes; + + struct cc_crypto_alg *cc_alg = + container_of(tfm->__crt_alg, struct cc_crypto_alg, + skcipher_alg.base); + + if (cc_alg->data_unit) + du_size = cc_alg->data_unit; + + switch (cipher_mode) { + case DRV_CIPHER_ECB: + break; + case DRV_CIPHER_CBC: + case DRV_CIPHER_CBC_CTS: + case DRV_CIPHER_CTR: + case DRV_CIPHER_OFB: + break; + case DRV_CIPHER_XTS: + case DRV_CIPHER_ESSIV: + case DRV_CIPHER_BITLOCKER: /* load XEX key */ hw_desc_init(&desc[*seq_size]); set_cipher_mode(&desc[*seq_size], cipher_mode); @@ -881,12 +927,14 @@ /* STAT_PHASE_2: Create sequence */ - /* Setup IV and XEX key used */ + /* Setup state (IV) */ cc_setup_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); /* Setup MLLI line, if needed */ cc_setup_mlli_desc(tfm, req_ctx, dst, src, nbytes, req, desc, &seq_len); /* Setup key */ cc_setup_key_desc(tfm, req_ctx, nbytes, desc, &seq_len); + /* Setup state (IV and XEX key) */ + cc_setup_xex_state_desc(tfm, req_ctx, ivsize, nbytes, desc, &seq_len); /* Data processing */ cc_setup_flow_desc(tfm, req_ctx, dst, src, nbytes, desc, &seq_len); /* Read next IV */ --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_debugfs.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_debugfs.c @@ -59,7 +59,7 @@ cc_debugfs_dir = debugfs_create_dir("ccree", NULL); } -void __exit cc_debugfs_global_fini(void) +void cc_debugfs_global_fini(void) { debugfs_remove(cc_debugfs_dir); } --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_driver.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_driver.c @@ -653,10 +653,17 @@ static int __init ccree_init(void) { - cc_hash_global_init(); + int rc; + cc_debugfs_global_init(); - return platform_driver_register(&ccree_driver); + rc = platform_driver_register(&ccree_driver); + if (rc) { + cc_debugfs_global_fini(); + return rc; + } + + return 0; } module_init(ccree_init); --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_driver.h +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_driver.h @@ -161,6 +161,7 @@ int std_bodies; bool sec_disabled; u32 comp_mask; + bool pm_on; }; struct cc_crypto_alg { --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_hash.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_hash.c @@ -39,12 +39,19 @@ SHA256_H3, SHA256_H2, SHA256_H1, SHA256_H0 }; static const u32 cc_digest_len_sha512_init[] = { 0x00000080, 0x00000000, 0x00000000, 0x00000000 }; -static u64 cc_sha384_init[] = { - SHA384_H7, SHA384_H6, SHA384_H5, SHA384_H4, - SHA384_H3, SHA384_H2, SHA384_H1, SHA384_H0 }; -static u64 cc_sha512_init[] = { - SHA512_H7, SHA512_H6, SHA512_H5, SHA512_H4, - SHA512_H3, SHA512_H2, SHA512_H1, SHA512_H0 }; + +/* + * Due to the way the HW works, every double word in the SHA384 and SHA512 + * larval hashes must be stored in hi/lo order + */ +#define hilo(x) upper_32_bits(x), lower_32_bits(x) +static const u32 cc_sha384_init[] = { + hilo(SHA384_H7), hilo(SHA384_H6), hilo(SHA384_H5), hilo(SHA384_H4), + hilo(SHA384_H3), hilo(SHA384_H2), hilo(SHA384_H1), hilo(SHA384_H0) }; +static const u32 cc_sha512_init[] = { + hilo(SHA512_H7), hilo(SHA512_H6), hilo(SHA512_H5), hilo(SHA512_H4), + hilo(SHA512_H3), hilo(SHA512_H2), hilo(SHA512_H1), hilo(SHA512_H0) }; + static const u32 cc_sm3_init[] = { SM3_IVH, SM3_IVG, SM3_IVF, SM3_IVE, SM3_IVD, SM3_IVC, SM3_IVB, SM3_IVA }; @@ -1948,8 +1955,8 @@ } if (large_sha_supported) { - cc_set_sram_desc((u32 *)cc_sha384_init, sram_buff_ofs, - (ARRAY_SIZE(cc_sha384_init) * 2), larval_seq, + cc_set_sram_desc(cc_sha384_init, sram_buff_ofs, + ARRAY_SIZE(cc_sha384_init), larval_seq, &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); if (rc) @@ -1957,8 +1964,8 @@ sram_buff_ofs += sizeof(cc_sha384_init); larval_seq_len = 0; - cc_set_sram_desc((u32 *)cc_sha512_init, sram_buff_ofs, - (ARRAY_SIZE(cc_sha512_init) * 2), larval_seq, + cc_set_sram_desc(cc_sha512_init, sram_buff_ofs, + ARRAY_SIZE(cc_sha512_init), larval_seq, &larval_seq_len); rc = send_request_init(drvdata, larval_seq, larval_seq_len); if (rc) @@ -1969,28 +1976,6 @@ return rc; } -static void __init cc_swap_dwords(u32 *buf, unsigned long size) -{ - int i; - u32 tmp; - - for (i = 0; i < size; i += 2) { - tmp = buf[i]; - buf[i] = buf[i + 1]; - buf[i + 1] = tmp; - } -} - -/* - * Due to the way the HW works we need to swap every - * double word in the SHA384 and SHA512 larval hashes - */ -void __init cc_hash_global_init(void) -{ - cc_swap_dwords((u32 *)&cc_sha384_init, (ARRAY_SIZE(cc_sha384_init) * 2)); - cc_swap_dwords((u32 *)&cc_sha512_init, (ARRAY_SIZE(cc_sha512_init) * 2)); -} - int cc_hash_alloc(struct cc_drvdata *drvdata) { struct cc_hash_handle *hash_handle; --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_hash.h +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_hash.h @@ -104,6 +104,4 @@ */ cc_sram_addr_t cc_larval_digest_addr(void *drvdata, u32 mode); -void cc_hash_global_init(void); - #endif /*__CC_HASH_H__*/ --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_pm.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_pm.c @@ -22,14 +22,8 @@ int cc_pm_suspend(struct device *dev) { struct cc_drvdata *drvdata = dev_get_drvdata(dev); - int rc; dev_dbg(dev, "set HOST_POWER_DOWN_EN\n"); - rc = cc_suspend_req_queue(drvdata); - if (rc) { - dev_err(dev, "cc_suspend_req_queue (%x)\n", rc); - return rc; - } fini_cc_regs(drvdata); cc_iowrite(drvdata, CC_REG(HOST_POWER_DOWN_EN), POWER_DOWN_ENABLE); cc_clk_off(drvdata); @@ -63,13 +57,6 @@ /* check if tee fips error occurred during power down */ cc_tee_handle_fips_error(drvdata); - rc = cc_resume_req_queue(drvdata); - if (rc) { - dev_err(dev, "cc_resume_req_queue (%x)\n", rc); - return rc; - } - - /* must be after the queue resuming as it uses the HW queue*/ cc_init_hash_sram(drvdata); return 0; @@ -80,12 +67,10 @@ int rc = 0; struct cc_drvdata *drvdata = dev_get_drvdata(dev); - if (cc_req_queue_suspended(drvdata)) + if (drvdata->pm_on) rc = pm_runtime_get_sync(dev); - else - pm_runtime_get_noresume(dev); - return rc; + return (rc == 1 ? 0 : rc); } int cc_pm_put_suspend(struct device *dev) @@ -93,14 +78,11 @@ int rc = 0; struct cc_drvdata *drvdata = dev_get_drvdata(dev); - if (!cc_req_queue_suspended(drvdata)) { + if (drvdata->pm_on) { pm_runtime_mark_last_busy(dev); rc = pm_runtime_put_autosuspend(dev); - } else { - /* Something wrong happens*/ - dev_err(dev, "request to suspend already suspended queue"); - rc = -EBUSY; } + return rc; } @@ -117,7 +99,7 @@ /* must be before the enabling to avoid resdundent suspending */ pm_runtime_set_autosuspend_delay(dev, CC_SUSPEND_TIMEOUT); pm_runtime_use_autosuspend(dev); - /* activate the PM module */ + /* set us as active - note we won't do PM ops until cc_pm_go()! */ return pm_runtime_set_active(dev); } @@ -125,9 +107,11 @@ void cc_pm_go(struct cc_drvdata *drvdata) { pm_runtime_enable(drvdata_to_dev(drvdata)); + drvdata->pm_on = true; } void cc_pm_fini(struct cc_drvdata *drvdata) { pm_runtime_disable(drvdata_to_dev(drvdata)); + drvdata->pm_on = false; } --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_request_mgr.c +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_request_mgr.c @@ -41,7 +41,6 @@ #else struct tasklet_struct comptask; #endif - bool is_runtime_suspended; }; struct cc_bl_item { @@ -404,6 +403,7 @@ spin_lock(&mgr->bl_lock); list_del(&bli->list); --mgr->bl_len; + kfree(bli); } spin_unlock(&mgr->bl_lock); @@ -677,52 +677,3 @@ cc_proc_backlog(drvdata); dev_dbg(dev, "Comp. handler done.\n"); } - -/* - * resume the queue configuration - no need to take the lock as this happens - * inside the spin lock protection - */ -#if defined(CONFIG_PM) -int cc_resume_req_queue(struct cc_drvdata *drvdata) -{ - struct cc_req_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - spin_lock_bh(&request_mgr_handle->hw_lock); - request_mgr_handle->is_runtime_suspended = false; - spin_unlock_bh(&request_mgr_handle->hw_lock); - - return 0; -} - -/* - * suspend the queue configuration. Since it is used for the runtime suspend - * only verify that the queue can be suspended. - */ -int cc_suspend_req_queue(struct cc_drvdata *drvdata) -{ - struct cc_req_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - /* lock the send_request */ - spin_lock_bh(&request_mgr_handle->hw_lock); - if (request_mgr_handle->req_queue_head != - request_mgr_handle->req_queue_tail) { - spin_unlock_bh(&request_mgr_handle->hw_lock); - return -EBUSY; - } - request_mgr_handle->is_runtime_suspended = true; - spin_unlock_bh(&request_mgr_handle->hw_lock); - - return 0; -} - -bool cc_req_queue_suspended(struct cc_drvdata *drvdata) -{ - struct cc_req_mgr_handle *request_mgr_handle = - drvdata->request_mgr_handle; - - return request_mgr_handle->is_runtime_suspended; -} - -#endif --- linux-oracle-5.4.0.orig/drivers/crypto/ccree/cc_request_mgr.h +++ linux-oracle-5.4.0/drivers/crypto/ccree/cc_request_mgr.h @@ -40,12 +40,4 @@ void cc_req_mgr_fini(struct cc_drvdata *drvdata); -#if defined(CONFIG_PM) -int cc_resume_req_queue(struct cc_drvdata *drvdata); - -int cc_suspend_req_queue(struct cc_drvdata *drvdata); - -bool cc_req_queue_suspended(struct cc_drvdata *drvdata); -#endif - #endif /*__REQUEST_MGR_H__*/ --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chcr_algo.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chcr_algo.c @@ -2480,8 +2480,9 @@ else reqctx->b0_dma = 0; if (req->src == req->dst) { - error = dma_map_sg(dev, req->src, sg_nents(req->src), - DMA_BIDIRECTIONAL); + error = dma_map_sg(dev, req->src, + sg_nents_for_len(req->src, dst_size), + DMA_BIDIRECTIONAL); if (!error) goto err; } else { @@ -2818,7 +2819,7 @@ unsigned int mac_mode = CHCR_SCMD_AUTH_MODE_CBCMAC; unsigned int c_id = a_ctx(tfm)->tx_chan_id; unsigned int ccm_xtra; - unsigned char tag_offset = 0, auth_offset = 0; + unsigned int tag_offset = 0, auth_offset = 0; unsigned int assoclen; if (get_aead_subtype(tfm) == CRYPTO_ALG_SUB_TYPE_AEAD_RFC4309) @@ -3194,9 +3195,6 @@ aeadctx->mayverify = VERIFY_SW; break; default: - - crypto_tfm_set_flags((struct crypto_tfm *) tfm, - CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); @@ -3221,8 +3219,6 @@ aeadctx->mayverify = VERIFY_HW; break; default: - crypto_tfm_set_flags((struct crypto_tfm *)tfm, - CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); @@ -3263,8 +3259,6 @@ aeadctx->mayverify = VERIFY_HW; break; default: - crypto_tfm_set_flags((struct crypto_tfm *)tfm, - CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize); @@ -3289,8 +3283,7 @@ ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256; mk_size = CHCR_KEYCTX_MAC_KEY_SIZE_256; } else { - crypto_tfm_set_flags((struct crypto_tfm *)aead, - CRYPTO_TFM_RES_BAD_KEY_LEN); + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); aeadctx->enckey_len = 0; return -EINVAL; } @@ -3328,8 +3321,7 @@ int error; if (keylen < 3) { - crypto_tfm_set_flags((struct crypto_tfm *)aead, - CRYPTO_TFM_RES_BAD_KEY_LEN); + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); aeadctx->enckey_len = 0; return -EINVAL; } @@ -3379,8 +3371,7 @@ } else if (keylen == AES_KEYSIZE_256) { ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256; } else { - crypto_tfm_set_flags((struct crypto_tfm *)aead, - CRYPTO_TFM_RES_BAD_KEY_LEN); + crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); pr_err("GCM: Invalid key length %d\n", keylen); ret = -EINVAL; goto out; --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chcr_core.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chcr_core.c @@ -125,8 +125,6 @@ atomic_set(&dev->inflight, 0); mutex_lock(&drv_data.drv_mutex); list_add_tail(&u_ctx->entry, &drv_data.inact_dev); - if (!drv_data.last_dev) - drv_data.last_dev = u_ctx; mutex_unlock(&drv_data.drv_mutex); } --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chtls/chtls_cm.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chtls/chtls_cm.c @@ -174,7 +174,7 @@ { if (likely(skb && !skb_shared(skb) && !skb_cloned(skb))) { __skb_trim(skb, 0); - refcount_add(2, &skb->users); + refcount_inc(&skb->users); } else { skb = alloc_skb(len, GFP_KERNEL | __GFP_NOFAIL); } @@ -577,7 +577,7 @@ while (!skb_queue_empty(&listen_ctx->synq)) { struct chtls_sock *csk = - container_of((struct synq *)__skb_dequeue + container_of((struct synq *)skb_peek (&listen_ctx->synq), struct chtls_sock, synq); struct sock *child = csk->sk; @@ -692,14 +692,13 @@ if (rpl->status != CPL_ERR_NONE) { pr_info("Unexpected PASS_OPEN_RPL status %u for STID %u\n", rpl->status, stid); - return CPL_RET_BUF_DONE; + } else { + cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family); + sock_put(listen_ctx->lsk); + kfree(listen_ctx); + module_put(THIS_MODULE); } - cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family); - sock_put(listen_ctx->lsk); - kfree(listen_ctx); - module_put(THIS_MODULE); - - return 0; + return CPL_RET_BUF_DONE; } static int chtls_close_listsrv_rpl(struct chtls_dev *cdev, struct sk_buff *skb) @@ -716,15 +715,21 @@ if (rpl->status != CPL_ERR_NONE) { pr_info("Unexpected CLOSE_LISTSRV_RPL status %u for STID %u\n", rpl->status, stid); - return CPL_RET_BUF_DONE; + } else { + cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family); + sock_put(listen_ctx->lsk); + kfree(listen_ctx); + module_put(THIS_MODULE); } + return CPL_RET_BUF_DONE; +} - cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family); - sock_put(listen_ctx->lsk); - kfree(listen_ctx); - module_put(THIS_MODULE); +static void chtls_purge_wr_queue(struct sock *sk) +{ + struct sk_buff *skb; - return 0; + while ((skb = dequeue_wr(sk)) != NULL) + kfree_skb(skb); } static void chtls_release_resources(struct sock *sk) @@ -741,6 +746,11 @@ kfree_skb(csk->txdata_skb_cache); csk->txdata_skb_cache = NULL; + if (csk->wr_credits != csk->wr_max_credits) { + chtls_purge_wr_queue(sk); + chtls_reset_wr_list(csk); + } + if (csk->l2t_entry) { cxgb4_l2t_release(csk->l2t_entry); csk->l2t_entry = NULL; @@ -1011,6 +1021,7 @@ const struct cpl_pass_accept_req *req, struct chtls_dev *cdev) { + struct adapter *adap = pci_get_drvdata(cdev->pdev); struct inet_sock *newinet; const struct iphdr *iph; struct tls_context *ctx; @@ -1020,9 +1031,10 @@ struct neighbour *n; struct tcp_sock *tp; struct sock *newsk; + bool found = false; u16 port_id; int rxq_idx; - int step; + int step, i; iph = (const struct iphdr *)network_hdr; newsk = tcp_create_openreq_child(lsk, oreq, cdev->askb); @@ -1034,12 +1046,20 @@ goto free_sk; n = dst_neigh_lookup(dst, &iph->saddr); - if (!n) - goto free_sk; + if (!n || !n->dev) + goto free_dst; ndev = n->dev; - if (!ndev) + if (is_vlan_dev(ndev)) + ndev = vlan_dev_real_dev(ndev); + + for_each_port(adap, i) + if (cdev->ports[i] == ndev) + found = true; + + if (!found) goto free_dst; + port_id = cxgb4_port_idx(ndev); csk = chtls_sock_create(cdev); @@ -1064,6 +1084,7 @@ sk_setup_caps(newsk, dst); ctx = tls_get_ctx(lsk); newsk->sk_destruct = ctx->sk_destruct; + newsk->sk_prot_creator = lsk->sk_prot_creator; csk->sk = newsk; csk->passive_reap_next = oreq; csk->tx_chan = cxgb4_port_chan(ndev); @@ -1082,8 +1103,8 @@ csk->sndbuf = newsk->sk_sndbuf; csk->smac_idx = ((struct port_info *)netdev_priv(ndev))->smt_idx; RCV_WSCALE(tp) = select_rcv_wscale(tcp_full_space(newsk), - sock_net(newsk)-> - ipv4.sysctl_tcp_window_scaling, + READ_ONCE(sock_net(newsk)-> + ipv4.sysctl_tcp_window_scaling), tp->window_clamp); neigh_release(n); inet_inherit_port(&tcp_hashinfo, lsk, newsk); @@ -1094,6 +1115,8 @@ free_csk: chtls_sock_release(&csk->kref); free_dst: + if (n) + neigh_release(n); dst_release(dst); free_sk: inet_csk_prepare_forced_close(newsk); @@ -1212,7 +1235,7 @@ chtls_set_req_addr(oreq, iph->daddr, iph->saddr); ip_dsfield = ipv4_get_dsfield(iph); if (req->tcpopt.wsf <= 14 && - sock_net(sk)->ipv4.sysctl_tcp_window_scaling) { + READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_window_scaling)) { inet_rsk(oreq)->wscale_ok = 1; inet_rsk(oreq)->snd_wscale = req->tcpopt.wsf; } @@ -1353,7 +1376,6 @@ struct chtls_sock *csk = sk->sk_user_data; local_bh_disable(); - bh_lock_sock(sk); release_tcp_port(sk); /* release the port immediately */ spin_lock(&reap_list_lock); @@ -1362,7 +1384,6 @@ if (!csk->passive_reap_next) schedule_work(&reap_task); spin_unlock(&reap_list_lock); - bh_unlock_sock(sk); local_bh_enable(); } @@ -1431,6 +1452,11 @@ sk_wake_async(sk, 0, POLL_OUT); data = lookup_stid(cdev->tids, stid); + if (!data) { + /* listening server close */ + kfree_skb(skb); + goto unlock; + } lsk = ((struct listen_ctx *)data)->lsk; bh_lock_sock(lsk); @@ -1735,6 +1761,7 @@ else sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); } + kfree_skb(skb); } static void chtls_close_con_rpl(struct sock *sk, struct sk_buff *skb) @@ -1815,39 +1842,6 @@ kfree_skb(skb); } -static void send_abort_rpl(struct sock *sk, struct sk_buff *skb, - struct chtls_dev *cdev, int status, int queue) -{ - struct cpl_abort_req_rss *req = cplhdr(skb); - struct sk_buff *reply_skb; - struct chtls_sock *csk; - - csk = rcu_dereference_sk_user_data(sk); - - reply_skb = alloc_skb(sizeof(struct cpl_abort_rpl), - GFP_KERNEL); - - if (!reply_skb) { - req->status = (queue << 1); - send_defer_abort_rpl(cdev, skb); - return; - } - - set_abort_rpl_wr(reply_skb, GET_TID(req), status); - kfree_skb(skb); - - set_wr_txq(reply_skb, CPL_PRIORITY_DATA, queue); - if (csk_conn_inline(csk)) { - struct l2t_entry *e = csk->l2t_entry; - - if (e && sk->sk_state != TCP_SYN_RECV) { - cxgb4_l2t_send(csk->egress_dev, reply_skb, e); - return; - } - } - cxgb4_ofld_send(cdev->lldi->ports[0], reply_skb); -} - /* * Add an skb to the deferred skb queue for processing from process context. */ @@ -1910,9 +1904,9 @@ queue = csk->txq_idx; skb->sk = NULL; + chtls_send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, + CPL_ABORT_NO_RST, queue); do_abort_syn_rcv(child, lsk); - send_abort_rpl(child, skb, BLOG_SKB_CB(skb)->cdev, - CPL_ABORT_NO_RST, queue); } static int abort_syn_rcv(struct sock *sk, struct sk_buff *skb) @@ -1942,8 +1936,8 @@ if (!sock_owned_by_user(psk)) { int queue = csk->txq_idx; + chtls_send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); do_abort_syn_rcv(sk, psk); - send_abort_rpl(sk, skb, cdev, CPL_ABORT_NO_RST, queue); } else { skb->sk = sk; BLOG_SKB_CB(skb)->backlog_rcv = bl_abort_syn_rcv; @@ -1961,9 +1955,6 @@ int queue = csk->txq_idx; if (is_neg_adv(req->status)) { - if (sk->sk_state == TCP_SYN_RECV) - chtls_set_tcb_tflag(sk, 0, 0); - kfree_skb(skb); return; } @@ -1989,12 +1980,11 @@ if (sk->sk_state == TCP_SYN_RECV && !abort_syn_rcv(sk, skb)) return; - - chtls_release_resources(sk); - chtls_conn_done(sk); } chtls_send_abort_rpl(sk, skb, csk->cdev, rst_status, queue); + chtls_release_resources(sk); + chtls_conn_done(sk); } static void chtls_abort_rpl_rss(struct sock *sk, struct sk_buff *skb) @@ -2062,19 +2052,6 @@ return 0; } -static struct sk_buff *dequeue_wr(struct sock *sk) -{ - struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); - struct sk_buff *skb = csk->wr_skb_head; - - if (likely(skb)) { - /* Don't bother clearing the tail */ - csk->wr_skb_head = WR_SKB_CB(skb)->next_wr; - WR_SKB_CB(skb)->next_wr = NULL; - } - return skb; -} - static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb) { struct cpl_fw4_ack *hdr = cplhdr(skb) + RSS_HDR; @@ -2115,7 +2092,7 @@ if (tp->snd_una != snd_una) { tp->snd_una = snd_una; - tp->rcv_tstamp = tcp_time_stamp(tp); + tp->rcv_tstamp = tcp_jiffies32; if (tp->snd_una == tp->snd_nxt && !csk_flag_nochk(csk, CSK_TX_FAILOVER)) csk_reset_flag(csk, CSK_TX_WAIT_IDLE); --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chtls/chtls_cm.h +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chtls/chtls_cm.h @@ -50,9 +50,6 @@ #define MIN_RCV_WND (24 * 1024U) #define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000)) -/* ulp_mem_io + ulptx_idata + payload + padding */ -#define MAX_IMM_ULPTX_WR_LEN (32 + 8 + 256 + 8) - /* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */ #define TX_HEADER_LEN \ (sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr)) @@ -185,6 +182,12 @@ kfree_skb(skb); } +static inline void chtls_reset_wr_list(struct chtls_sock *csk) +{ + csk->wr_skb_head = NULL; + csk->wr_skb_tail = NULL; +} + static inline void enqueue_wr(struct chtls_sock *csk, struct sk_buff *skb) { WR_SKB_CB(skb)->next_wr = NULL; @@ -197,4 +200,19 @@ WR_SKB_CB(csk->wr_skb_tail)->next_wr = skb; csk->wr_skb_tail = skb; } + +static inline struct sk_buff *dequeue_wr(struct sock *sk) +{ + struct chtls_sock *csk = rcu_dereference_sk_user_data(sk); + struct sk_buff *skb = NULL; + + skb = csk->wr_skb_head; + + if (likely(skb)) { + /* Don't bother clearing the tail */ + csk->wr_skb_head = WR_SKB_CB(skb)->next_wr; + WR_SKB_CB(skb)->next_wr = NULL; + } + return skb; +} #endif --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chtls/chtls_hw.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chtls/chtls_hw.c @@ -350,17 +350,22 @@ kwr->sc_imm.cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM)); kwr->sc_imm.len = cpu_to_be32(klen); + lock_sock(sk); /* key info */ kctx = (struct _key_ctx *)(kwr + 1); ret = chtls_key_info(csk, kctx, keylen, optname); if (ret) goto out_notcb; + if (unlikely(csk_flag(sk, CSK_ABORT_SHUTDOWN))) + goto out_notcb; + set_wr_txq(skb, CPL_PRIORITY_DATA, csk->tlshws.txqid); csk->wr_credits -= DIV_ROUND_UP(len, 16); csk->wr_unacked += DIV_ROUND_UP(len, 16); enqueue_wr(csk, skb); cxgb4_ofld_send(csk->egress_dev, skb); + skb = NULL; chtls_set_scmd(csk); /* Clear quiesce for Rx key */ @@ -388,8 +393,10 @@ csk->tlshws.txkey = keyid; } + release_sock(sk); return ret; out_notcb: + release_sock(sk); free_tls_keyid(sk); out_nokey: kfree_skb(skb); --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chtls/chtls_io.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chtls/chtls_io.c @@ -682,7 +682,7 @@ make_tx_data_wr(sk, skb, immdlen, len, credits_needed, completion); tp->snd_nxt += len; - tp->lsndtime = tcp_time_stamp(tp); + tp->lsndtime = tcp_jiffies32; if (completion) ULP_SKB_CB(skb)->flags &= ~ULPCB_FLAG_NEED_HDR; } else { @@ -910,9 +910,9 @@ return (__force int)cpu_to_be16(thdr->length); } -static int csk_mem_free(struct chtls_dev *cdev, struct sock *sk) +static bool csk_mem_free(struct chtls_dev *cdev, struct sock *sk) { - return (cdev->max_host_sndbuf - sk->sk_wmem_queued); + return (cdev->max_host_sndbuf - sk->sk_wmem_queued > 0); } static int csk_wait_memory(struct chtls_dev *cdev, @@ -1210,6 +1210,7 @@ copied = 0; csk = rcu_dereference_sk_user_data(sk); cdev = csk->cdev; + lock_sock(sk); timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); err = sk_stream_wait_connect(sk, &timeo); @@ -1437,7 +1438,7 @@ csk->wr_max_credits)) sk->sk_write_space(sk); - if (copied >= target && !sk->sk_backlog.tail) + if (copied >= target && !READ_ONCE(sk->sk_backlog.tail)) break; if (copied) { @@ -1470,7 +1471,7 @@ break; } } - if (sk->sk_backlog.tail) { + if (READ_ONCE(sk->sk_backlog.tail)) { release_sock(sk); lock_sock(sk); chtls_cleanup_rbuf(sk, copied); @@ -1536,6 +1537,7 @@ tp->urg_data = 0; if ((avail + offset) >= skb->len) { + struct sk_buff *next_skb; if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_TLS_HDR) { tp->copied_seq += skb->len; hws->rcvpld = skb->hdr_len; @@ -1545,8 +1547,10 @@ chtls_free_skb(sk, skb); buffers_freed++; hws->copied_seq = 0; - if (copied >= target && - !skb_peek(&sk->sk_receive_queue)) + next_skb = skb_peek(&sk->sk_receive_queue); + if (copied >= target && !next_skb) + break; + if (ULP_SKB_CB(next_skb)->flags & ULPCB_FLAG_TLS_HDR) break; } } while (len > 0); @@ -1615,7 +1619,7 @@ break; } - if (sk->sk_backlog.tail) { + if (READ_ONCE(sk->sk_backlog.tail)) { /* Do not sleep, just process backlog. */ release_sock(sk); lock_sock(sk); @@ -1743,7 +1747,7 @@ csk->wr_max_credits)) sk->sk_write_space(sk); - if (copied >= target && !sk->sk_backlog.tail) + if (copied >= target && !READ_ONCE(sk->sk_backlog.tail)) break; if (copied) { @@ -1774,7 +1778,7 @@ } } - if (sk->sk_backlog.tail) { + if (READ_ONCE(sk->sk_backlog.tail)) { release_sock(sk); lock_sock(sk); chtls_cleanup_rbuf(sk, copied); --- linux-oracle-5.4.0.orig/drivers/crypto/chelsio/chtls/chtls_main.c +++ linux-oracle-5.4.0/drivers/crypto/chelsio/chtls/chtls_main.c @@ -339,8 +339,9 @@ * driver. Once driver synthesizes cpl_pass_accpet_req the skb will go * through the regular cpl_pass_accept_req processing in TOM. */ - skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) - - pktshift, GFP_ATOMIC); + skb = alloc_skb(size_add(gl->tot_len, + sizeof(struct cpl_pass_accept_req)) - + pktshift, GFP_ATOMIC); if (unlikely(!skb)) return NULL; __skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req) --- linux-oracle-5.4.0.orig/drivers/crypto/geode-aes.c +++ linux-oracle-5.4.0/drivers/crypto/geode-aes.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -23,12 +24,12 @@ /* Write a 128 bit field (either a writable key or IV) */ static inline void -_writefield(u32 offset, void *value) +_writefield(u32 offset, const void *value) { int i; for (i = 0; i < 4; i++) - iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4)); + iowrite32(((const u32 *) value)[i], _iobase + offset + (i * 4)); } /* Read a 128 bit field (either a writable key or IV) */ @@ -42,12 +43,12 @@ } static int -do_crypt(void *src, void *dst, int len, u32 flags) +do_crypt(const void *src, void *dst, u32 len, u32 flags) { u32 status; u32 counter = AES_OP_TIMEOUT; - iowrite32(virt_to_phys(src), _iobase + AES_SOURCEA_REG); + iowrite32(virt_to_phys((void *)src), _iobase + AES_SOURCEA_REG); iowrite32(virt_to_phys(dst), _iobase + AES_DSTA_REG); iowrite32(len, _iobase + AES_LENA_REG); @@ -64,16 +65,14 @@ return counter ? 0 : 1; } -static unsigned int -geode_aes_crypt(struct geode_aes_op *op) +static void +geode_aes_crypt(const struct geode_aes_tfm_ctx *tctx, const void *src, + void *dst, u32 len, u8 *iv, int mode, int dir) { u32 flags = 0; unsigned long iflags; int ret; - if (op->len == 0) - return 0; - /* If the source and destination is the same, then * we need to turn on the coherent flags, otherwise * we don't need to worry @@ -81,32 +80,28 @@ flags |= (AES_CTRL_DCA | AES_CTRL_SCA); - if (op->dir == AES_DIR_ENCRYPT) + if (dir == AES_DIR_ENCRYPT) flags |= AES_CTRL_ENCRYPT; /* Start the critical section */ spin_lock_irqsave(&lock, iflags); - if (op->mode == AES_MODE_CBC) { + if (mode == AES_MODE_CBC) { flags |= AES_CTRL_CBC; - _writefield(AES_WRITEIV0_REG, op->iv); + _writefield(AES_WRITEIV0_REG, iv); } - if (!(op->flags & AES_FLAGS_HIDDENKEY)) { - flags |= AES_CTRL_WRKEY; - _writefield(AES_WRITEKEY0_REG, op->key); - } + flags |= AES_CTRL_WRKEY; + _writefield(AES_WRITEKEY0_REG, tctx->key); - ret = do_crypt(op->src, op->dst, op->len, flags); + ret = do_crypt(src, dst, len, flags); BUG_ON(ret); - if (op->mode == AES_MODE_CBC) - _readfield(AES_WRITEIV0_REG, op->iv); + if (mode == AES_MODE_CBC) + _readfield(AES_WRITEIV0_REG, iv); spin_unlock_irqrestore(&lock, iflags); - - return op->len; } /* CRYPTO-API Functions */ @@ -114,13 +109,13 @@ static int geode_setkey_cip(struct crypto_tfm *tfm, const u8 *key, unsigned int len) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); unsigned int ret; - op->keylen = len; + tctx->keylen = len; if (len == AES_KEYSIZE_128) { - memcpy(op->key, key, len); + memcpy(tctx->key, key, len); return 0; } @@ -133,135 +128,93 @@ /* * The requested key size is not supported by HW, do a fallback */ - op->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; - op->fallback.cip->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); + tctx->fallback.cip->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; + tctx->fallback.cip->base.crt_flags |= + (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); - ret = crypto_cipher_setkey(op->fallback.cip, key, len); + ret = crypto_cipher_setkey(tctx->fallback.cip, key, len); if (ret) { tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; - tfm->crt_flags |= (op->fallback.cip->base.crt_flags & CRYPTO_TFM_RES_MASK); + tfm->crt_flags |= (tctx->fallback.cip->base.crt_flags & + CRYPTO_TFM_RES_MASK); } return ret; } -static int geode_setkey_blk(struct crypto_tfm *tfm, const u8 *key, - unsigned int len) +static int geode_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, + unsigned int len) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); unsigned int ret; - op->keylen = len; + tctx->keylen = len; if (len == AES_KEYSIZE_128) { - memcpy(op->key, key, len); + memcpy(tctx->key, key, len); return 0; } if (len != AES_KEYSIZE_192 && len != AES_KEYSIZE_256) { /* not supported at all */ - tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); return -EINVAL; } /* * The requested key size is not supported by HW, do a fallback */ - op->fallback.blk->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; - op->fallback.blk->base.crt_flags |= (tfm->crt_flags & CRYPTO_TFM_REQ_MASK); - - ret = crypto_blkcipher_setkey(op->fallback.blk, key, len); - if (ret) { - tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; - tfm->crt_flags |= (op->fallback.blk->base.crt_flags & CRYPTO_TFM_RES_MASK); - } - return ret; -} - -static int fallback_blk_dec(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - unsigned int ret; - struct crypto_blkcipher *tfm; - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - - tfm = desc->tfm; - desc->tfm = op->fallback.blk; - - ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes); - - desc->tfm = tfm; - return ret; -} -static int fallback_blk_enc(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - unsigned int ret; - struct crypto_blkcipher *tfm; - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - - tfm = desc->tfm; - desc->tfm = op->fallback.blk; - - ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes); - - desc->tfm = tfm; + crypto_skcipher_clear_flags(tctx->fallback.skcipher, + CRYPTO_TFM_REQ_MASK); + crypto_skcipher_set_flags(tctx->fallback.skcipher, + crypto_skcipher_get_flags(tfm) & + CRYPTO_TFM_REQ_MASK); + ret = crypto_skcipher_setkey(tctx->fallback.skcipher, key, len); + crypto_skcipher_set_flags(tfm, + crypto_skcipher_get_flags(tctx->fallback.skcipher) & + CRYPTO_TFM_RES_MASK); return ret; } static void geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); - if (unlikely(op->keylen != AES_KEYSIZE_128)) { - crypto_cipher_encrypt_one(op->fallback.cip, out, in); + if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { + crypto_cipher_encrypt_one(tctx->fallback.cip, out, in); return; } - op->src = (void *) in; - op->dst = (void *) out; - op->mode = AES_MODE_ECB; - op->flags = 0; - op->len = AES_BLOCK_SIZE; - op->dir = AES_DIR_ENCRYPT; - - geode_aes_crypt(op); + geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, + AES_MODE_ECB, AES_DIR_ENCRYPT); } static void geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + const struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); - if (unlikely(op->keylen != AES_KEYSIZE_128)) { - crypto_cipher_decrypt_one(op->fallback.cip, out, in); + if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { + crypto_cipher_decrypt_one(tctx->fallback.cip, out, in); return; } - op->src = (void *) in; - op->dst = (void *) out; - op->mode = AES_MODE_ECB; - op->flags = 0; - op->len = AES_BLOCK_SIZE; - op->dir = AES_DIR_DECRYPT; - - geode_aes_crypt(op); + geode_aes_crypt(tctx, in, out, AES_BLOCK_SIZE, NULL, + AES_MODE_ECB, AES_DIR_DECRYPT); } static int fallback_init_cip(struct crypto_tfm *tfm) { const char *name = crypto_tfm_alg_name(tfm); - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); - op->fallback.cip = crypto_alloc_cipher(name, 0, - CRYPTO_ALG_NEED_FALLBACK); + tctx->fallback.cip = crypto_alloc_cipher(name, 0, + CRYPTO_ALG_NEED_FALLBACK); - if (IS_ERR(op->fallback.cip)) { + if (IS_ERR(tctx->fallback.cip)) { printk(KERN_ERR "Error allocating fallback algo %s\n", name); - return PTR_ERR(op->fallback.cip); + return PTR_ERR(tctx->fallback.cip); } return 0; @@ -269,10 +222,9 @@ static void fallback_exit_cip(struct crypto_tfm *tfm) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + struct geode_aes_tfm_ctx *tctx = crypto_tfm_ctx(tfm); - crypto_free_cipher(op->fallback.cip); - op->fallback.cip = NULL; + crypto_free_cipher(tctx->fallback.cip); } static struct crypto_alg geode_alg = { @@ -285,7 +237,7 @@ .cra_init = fallback_init_cip, .cra_exit = fallback_exit_cip, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct geode_aes_op), + .cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), .cra_module = THIS_MODULE, .cra_u = { .cipher = { @@ -298,209 +250,126 @@ } }; -static int -geode_cbc_decrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - struct blkcipher_walk walk; - int err, ret; - - if (unlikely(op->keylen != AES_KEYSIZE_128)) - return fallback_blk_dec(desc, dst, src, nbytes); - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - op->iv = walk.iv; - - while ((nbytes = walk.nbytes)) { - op->src = walk.src.virt.addr, - op->dst = walk.dst.virt.addr; - op->mode = AES_MODE_CBC; - op->len = nbytes - (nbytes % AES_BLOCK_SIZE); - op->dir = AES_DIR_DECRYPT; - - ret = geode_aes_crypt(op); - - nbytes -= ret; - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static int -geode_cbc_encrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - struct blkcipher_walk walk; - int err, ret; - - if (unlikely(op->keylen != AES_KEYSIZE_128)) - return fallback_blk_enc(desc, dst, src, nbytes); - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - op->iv = walk.iv; - - while ((nbytes = walk.nbytes)) { - op->src = walk.src.virt.addr, - op->dst = walk.dst.virt.addr; - op->mode = AES_MODE_CBC; - op->len = nbytes - (nbytes % AES_BLOCK_SIZE); - op->dir = AES_DIR_ENCRYPT; - - ret = geode_aes_crypt(op); - nbytes -= ret; - err = blkcipher_walk_done(desc, &walk, nbytes); - } - - return err; -} - -static int fallback_init_blk(struct crypto_tfm *tfm) +static int geode_init_skcipher(struct crypto_skcipher *tfm) { - const char *name = crypto_tfm_alg_name(tfm); - struct geode_aes_op *op = crypto_tfm_ctx(tfm); - - op->fallback.blk = crypto_alloc_blkcipher(name, 0, - CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK); + const char *name = crypto_tfm_alg_name(&tfm->base); + struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); - if (IS_ERR(op->fallback.blk)) { + tctx->fallback.skcipher = + crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK | + CRYPTO_ALG_ASYNC); + if (IS_ERR(tctx->fallback.skcipher)) { printk(KERN_ERR "Error allocating fallback algo %s\n", name); - return PTR_ERR(op->fallback.blk); + return PTR_ERR(tctx->fallback.skcipher); } + crypto_skcipher_set_reqsize(tfm, sizeof(struct skcipher_request) + + crypto_skcipher_reqsize(tctx->fallback.skcipher)); return 0; } -static void fallback_exit_blk(struct crypto_tfm *tfm) +static void geode_exit_skcipher(struct crypto_skcipher *tfm) { - struct geode_aes_op *op = crypto_tfm_ctx(tfm); + struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); - crypto_free_blkcipher(op->fallback.blk); - op->fallback.blk = NULL; + crypto_free_skcipher(tctx->fallback.skcipher); } -static struct crypto_alg geode_cbc_alg = { - .cra_name = "cbc(aes)", - .cra_driver_name = "cbc-aes-geode", - .cra_priority = 400, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_KERN_DRIVER_ONLY | - CRYPTO_ALG_NEED_FALLBACK, - .cra_init = fallback_init_blk, - .cra_exit = fallback_exit_blk, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct geode_aes_op), - .cra_alignmask = 15, - .cra_type = &crypto_blkcipher_type, - .cra_module = THIS_MODULE, - .cra_u = { - .blkcipher = { - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .setkey = geode_setkey_blk, - .encrypt = geode_cbc_encrypt, - .decrypt = geode_cbc_decrypt, - .ivsize = AES_BLOCK_SIZE, - } +static int geode_skcipher_crypt(struct skcipher_request *req, int mode, int dir) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + const struct geode_aes_tfm_ctx *tctx = crypto_skcipher_ctx(tfm); + struct skcipher_walk walk; + unsigned int nbytes; + int err; + + if (unlikely(tctx->keylen != AES_KEYSIZE_128)) { + struct skcipher_request *subreq = skcipher_request_ctx(req); + + *subreq = *req; + skcipher_request_set_tfm(subreq, tctx->fallback.skcipher); + if (dir == AES_DIR_DECRYPT) + return crypto_skcipher_decrypt(subreq); + else + return crypto_skcipher_encrypt(subreq); } -}; -static int -geode_ecb_decrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - struct blkcipher_walk walk; - int err, ret; - - if (unlikely(op->keylen != AES_KEYSIZE_128)) - return fallback_blk_dec(desc, dst, src, nbytes); - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - op->src = walk.src.virt.addr, - op->dst = walk.dst.virt.addr; - op->mode = AES_MODE_ECB; - op->len = nbytes - (nbytes % AES_BLOCK_SIZE); - op->dir = AES_DIR_DECRYPT; - - ret = geode_aes_crypt(op); - nbytes -= ret; - err = blkcipher_walk_done(desc, &walk, nbytes); + err = skcipher_walk_virt(&walk, req, false); + + while ((nbytes = walk.nbytes) != 0) { + geode_aes_crypt(tctx, walk.src.virt.addr, walk.dst.virt.addr, + round_down(nbytes, AES_BLOCK_SIZE), + walk.iv, mode, dir); + err = skcipher_walk_done(&walk, nbytes % AES_BLOCK_SIZE); } return err; } -static int -geode_ecb_encrypt(struct blkcipher_desc *desc, - struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes) -{ - struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); - struct blkcipher_walk walk; - int err, ret; - - if (unlikely(op->keylen != AES_KEYSIZE_128)) - return fallback_blk_enc(desc, dst, src, nbytes); - - blkcipher_walk_init(&walk, dst, src, nbytes); - err = blkcipher_walk_virt(desc, &walk); - - while ((nbytes = walk.nbytes)) { - op->src = walk.src.virt.addr, - op->dst = walk.dst.virt.addr; - op->mode = AES_MODE_ECB; - op->len = nbytes - (nbytes % AES_BLOCK_SIZE); - op->dir = AES_DIR_ENCRYPT; - - ret = geode_aes_crypt(op); - nbytes -= ret; - ret = blkcipher_walk_done(desc, &walk, nbytes); - } +static int geode_cbc_encrypt(struct skcipher_request *req) +{ + return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_ENCRYPT); +} - return err; +static int geode_cbc_decrypt(struct skcipher_request *req) +{ + return geode_skcipher_crypt(req, AES_MODE_CBC, AES_DIR_DECRYPT); } -static struct crypto_alg geode_ecb_alg = { - .cra_name = "ecb(aes)", - .cra_driver_name = "ecb-aes-geode", - .cra_priority = 400, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_KERN_DRIVER_ONLY | - CRYPTO_ALG_NEED_FALLBACK, - .cra_init = fallback_init_blk, - .cra_exit = fallback_exit_blk, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct geode_aes_op), - .cra_alignmask = 15, - .cra_type = &crypto_blkcipher_type, - .cra_module = THIS_MODULE, - .cra_u = { - .blkcipher = { - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .setkey = geode_setkey_blk, - .encrypt = geode_ecb_encrypt, - .decrypt = geode_ecb_decrypt, - } - } +static int geode_ecb_encrypt(struct skcipher_request *req) +{ + return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_ENCRYPT); +} + +static int geode_ecb_decrypt(struct skcipher_request *req) +{ + return geode_skcipher_crypt(req, AES_MODE_ECB, AES_DIR_DECRYPT); +} + +static struct skcipher_alg geode_skcipher_algs[] = { + { + .base.cra_name = "cbc(aes)", + .base.cra_driver_name = "cbc-aes-geode", + .base.cra_priority = 400, + .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), + .base.cra_alignmask = 15, + .base.cra_module = THIS_MODULE, + .init = geode_init_skcipher, + .exit = geode_exit_skcipher, + .setkey = geode_setkey_skcipher, + .encrypt = geode_cbc_encrypt, + .decrypt = geode_cbc_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_BLOCK_SIZE, + }, { + .base.cra_name = "ecb(aes)", + .base.cra_driver_name = "ecb-aes-geode", + .base.cra_priority = 400, + .base.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, + .base.cra_blocksize = AES_BLOCK_SIZE, + .base.cra_ctxsize = sizeof(struct geode_aes_tfm_ctx), + .base.cra_alignmask = 15, + .base.cra_module = THIS_MODULE, + .init = geode_init_skcipher, + .exit = geode_exit_skcipher, + .setkey = geode_setkey_skcipher, + .encrypt = geode_ecb_encrypt, + .decrypt = geode_ecb_decrypt, + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + }, }; static void geode_aes_remove(struct pci_dev *dev) { crypto_unregister_alg(&geode_alg); - crypto_unregister_alg(&geode_ecb_alg); - crypto_unregister_alg(&geode_cbc_alg); + crypto_unregister_skciphers(geode_skcipher_algs, + ARRAY_SIZE(geode_skcipher_algs)); pci_iounmap(dev, _iobase); _iobase = NULL; @@ -538,20 +407,14 @@ if (ret) goto eiomap; - ret = crypto_register_alg(&geode_ecb_alg); + ret = crypto_register_skciphers(geode_skcipher_algs, + ARRAY_SIZE(geode_skcipher_algs)); if (ret) goto ealg; - ret = crypto_register_alg(&geode_cbc_alg); - if (ret) - goto eecb; - dev_notice(&dev->dev, "GEODE AES engine enabled.\n"); return 0; - eecb: - crypto_unregister_alg(&geode_ecb_alg); - ealg: crypto_unregister_alg(&geode_alg); --- linux-oracle-5.4.0.orig/drivers/crypto/geode-aes.h +++ linux-oracle-5.4.0/drivers/crypto/geode-aes.h @@ -46,21 +46,10 @@ #define AES_OP_TIMEOUT 0x50000 -struct geode_aes_op { - - void *src; - void *dst; - - u32 mode; - u32 dir; - u32 flags; - int len; - +struct geode_aes_tfm_ctx { u8 key[AES_KEYSIZE_128]; - u8 *iv; - union { - struct crypto_blkcipher *blk; + struct crypto_skcipher *skcipher; struct crypto_cipher *cip; } fallback; u32 keylen; --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/Kconfig @@ -14,26 +14,53 @@ To compile this as a module, choose M here: the module will be called hisi_sec. +config CRYPTO_DEV_HISI_SEC2 + tristate "Support for HiSilicon SEC2 crypto block cipher accelerator" + select CRYPTO_BLKCIPHER + select CRYPTO_ALGAPI + select CRYPTO_LIB_DES + select CRYPTO_DEV_HISI_QM + select CRYPTO_AEAD + select CRYPTO_AUTHENC + select CRYPTO_HMAC + select CRYPTO_SHA1 + select CRYPTO_SHA256 + select CRYPTO_SHA512 + depends on PCI && PCI_MSI + depends on ARM64 || (COMPILE_TEST && 64BIT) + help + Support for HiSilicon SEC Engine of version 2 in crypto subsystem. + It provides AES, SM4, and 3DES algorithms with ECB + CBC, and XTS cipher mode, and AEAD algorithms. + + To compile this as a module, choose M here: the module + will be called hisi_sec2. + config CRYPTO_DEV_HISI_QM tristate - depends on ARM64 && PCI && PCI_MSI + depends on ARM64 || COMPILE_TEST + depends on PCI && PCI_MSI + select NEED_SG_DMA_LENGTH help HiSilicon accelerator engines use a common queue management interface. Specific engine driver may use this module. -config CRYPTO_HISI_SGL - tristate - depends on ARM64 - help - HiSilicon accelerator engines use a common hardware scatterlist - interface for data format. Specific engine driver may use this - module. - config CRYPTO_DEV_HISI_ZIP tristate "Support for HiSilicon ZIP accelerator" - depends on ARM64 && PCI && PCI_MSI + depends on PCI && PCI_MSI + depends on ARM64 || (COMPILE_TEST && 64BIT) + depends on !CPU_BIG_ENDIAN || COMPILE_TEST select CRYPTO_DEV_HISI_QM - select CRYPTO_HISI_SGL - select SG_SPLIT help Support for HiSilicon ZIP Driver + +config CRYPTO_DEV_HISI_HPRE + tristate "Support for HISI HPRE accelerator" + depends on PCI && PCI_MSI + depends on ARM64 || (COMPILE_TEST && 64BIT) + select CRYPTO_DEV_HISI_QM + select CRYPTO_DH + select CRYPTO_RSA + help + Support for HiSilicon HPRE(High Performance RSA Engine) + accelerator, which can accelerate RSA and DH algorithms. --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/Makefile +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hpre/ obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/ -obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += qm.o -obj-$(CONFIG_CRYPTO_HISI_SGL) += sgl.o +obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/ +obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o +hisi_qm-objs = qm.o sgl.o obj-$(CONFIG_CRYPTO_DEV_HISI_ZIP) += zip/ --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/hpre/Makefile +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/hpre/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hisi_hpre.o +hisi_hpre-objs = hpre_main.o hpre_crypto.o --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/hpre/hpre.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/hpre/hpre.h @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019 HiSilicon Limited. */ +#ifndef __HISI_HPRE_H +#define __HISI_HPRE_H + +#include +#include "../qm.h" + +#define HPRE_SQE_SIZE sizeof(struct hpre_sqe) +#define HPRE_PF_DEF_Q_NUM 64 +#define HPRE_PF_DEF_Q_BASE 0 + +enum { + HPRE_CLUSTER0, + HPRE_CLUSTER1, + HPRE_CLUSTER2, + HPRE_CLUSTER3, + HPRE_CLUSTERS_NUM, +}; + +enum hpre_ctrl_dbgfs_file { + HPRE_CURRENT_QM, + HPRE_CLEAR_ENABLE, + HPRE_CLUSTER_CTRL, + HPRE_DEBUG_FILE_NUM, +}; + +#define HPRE_DEBUGFS_FILE_NUM (HPRE_DEBUG_FILE_NUM + HPRE_CLUSTERS_NUM - 1) + +struct hpre_debugfs_file { + int index; + enum hpre_ctrl_dbgfs_file type; + spinlock_t lock; + struct hpre_debug *debug; +}; + +/* + * One HPRE controller has one PF and multiple VFs, some global configurations + * which PF has need this structure. + * Just relevant for PF. + */ +struct hpre_debug { + struct dentry *debug_root; + struct hpre_debugfs_file files[HPRE_DEBUGFS_FILE_NUM]; +}; + +struct hpre { + struct hisi_qm qm; + struct list_head list; + struct hpre_debug debug; + u32 num_vfs; + unsigned long status; +}; + +enum hpre_alg_type { + HPRE_ALG_NC_NCRT = 0x0, + HPRE_ALG_NC_CRT = 0x1, + HPRE_ALG_KG_STD = 0x2, + HPRE_ALG_KG_CRT = 0x3, + HPRE_ALG_DH_G2 = 0x4, + HPRE_ALG_DH = 0x5, +}; + +struct hpre_sqe { + __le32 dw0; + __u8 task_len1; + __u8 task_len2; + __u8 mrttest_num; + __u8 resv1; + __le64 key; + __le64 in; + __le64 out; + __le16 tag; + __le16 resv2; +#define _HPRE_SQE_ALIGN_EXT 7 + __le32 rsvd1[_HPRE_SQE_ALIGN_EXT]; +}; + +struct hpre *hpre_find_device(int node); +int hpre_algs_register(void); +void hpre_algs_unregister(void); + +#endif --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/hpre/hpre_crypto.c @@ -0,0 +1,1134 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 HiSilicon Limited. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hpre.h" + +struct hpre_ctx; + +#define HPRE_CRYPTO_ALG_PRI 1000 +#define HPRE_ALIGN_SZ 64 +#define HPRE_BITS_2_BYTES_SHIFT 3 +#define HPRE_RSA_512BITS_KSZ 64 +#define HPRE_RSA_1536BITS_KSZ 192 +#define HPRE_CRT_PRMS 5 +#define HPRE_CRT_Q 2 +#define HPRE_CRT_P 3 +#define HPRE_CRT_INV 4 +#define HPRE_DH_G_FLAG 0x02 +#define HPRE_TRY_SEND_TIMES 100 +#define HPRE_INVLD_REQ_ID (-1) +#define HPRE_DEV(ctx) (&((ctx)->qp->qm->pdev->dev)) + +#define HPRE_SQE_ALG_BITS 5 +#define HPRE_SQE_DONE_SHIFT 30 +#define HPRE_DH_MAX_P_SZ 512 + +typedef void (*hpre_cb)(struct hpre_ctx *ctx, void *sqe); + +struct hpre_rsa_ctx { + /* low address: e--->n */ + char *pubkey; + dma_addr_t dma_pubkey; + + /* low address: d--->n */ + char *prikey; + dma_addr_t dma_prikey; + + /* low address: dq->dp->q->p->qinv */ + char *crt_prikey; + dma_addr_t dma_crt_prikey; + + struct crypto_akcipher *soft_tfm; +}; + +struct hpre_dh_ctx { + /* + * If base is g we compute the public key + * ya = g^xa mod p; [RFC2631 sec 2.1.1] + * else if base if the counterpart public key we + * compute the shared secret + * ZZ = yb^xa mod p; [RFC2631 sec 2.1.1] + */ + char *xa_p; /* low address: d--->n, please refer to Hisilicon HPRE UM */ + dma_addr_t dma_xa_p; + + char *g; /* m */ + dma_addr_t dma_g; +}; + +struct hpre_ctx { + struct hisi_qp *qp; + struct hpre_asym_request **req_list; + spinlock_t req_lock; + unsigned int key_sz; + bool crt_g2_mode; + struct idr req_idr; + union { + struct hpre_rsa_ctx rsa; + struct hpre_dh_ctx dh; + }; +}; + +struct hpre_asym_request { + char *src; + char *dst; + struct hpre_sqe req; + struct hpre_ctx *ctx; + union { + struct akcipher_request *rsa; + struct kpp_request *dh; + } areq; + int err; + int req_id; + hpre_cb cb; +}; + +static DEFINE_MUTEX(hpre_alg_lock); +static unsigned int hpre_active_devs; + +static int hpre_alloc_req_id(struct hpre_ctx *ctx) +{ + unsigned long flags; + int id; + + spin_lock_irqsave(&ctx->req_lock, flags); + id = idr_alloc(&ctx->req_idr, NULL, 0, QM_Q_DEPTH, GFP_ATOMIC); + spin_unlock_irqrestore(&ctx->req_lock, flags); + + return id; +} + +static void hpre_free_req_id(struct hpre_ctx *ctx, int req_id) +{ + unsigned long flags; + + spin_lock_irqsave(&ctx->req_lock, flags); + idr_remove(&ctx->req_idr, req_id); + spin_unlock_irqrestore(&ctx->req_lock, flags); +} + +static int hpre_add_req_to_ctx(struct hpre_asym_request *hpre_req) +{ + struct hpre_ctx *ctx; + int id; + + ctx = hpre_req->ctx; + id = hpre_alloc_req_id(ctx); + if (unlikely(id < 0)) + return -EINVAL; + + ctx->req_list[id] = hpre_req; + hpre_req->req_id = id; + + return id; +} + +static void hpre_rm_req_from_ctx(struct hpre_asym_request *hpre_req) +{ + struct hpre_ctx *ctx = hpre_req->ctx; + int id = hpre_req->req_id; + + if (hpre_req->req_id >= 0) { + hpre_req->req_id = HPRE_INVLD_REQ_ID; + ctx->req_list[id] = NULL; + hpre_free_req_id(ctx, id); + } +} + +static struct hisi_qp *hpre_get_qp_and_start(void) +{ + struct hisi_qp *qp; + struct hpre *hpre; + int ret; + + /* find the proper hpre device, which is near the current CPU core */ + hpre = hpre_find_device(cpu_to_node(smp_processor_id())); + if (!hpre) { + pr_err("Can not find proper hpre device!\n"); + return ERR_PTR(-ENODEV); + } + + qp = hisi_qm_create_qp(&hpre->qm, 0); + if (IS_ERR(qp)) { + pci_err(hpre->qm.pdev, "Can not create qp!\n"); + return ERR_PTR(-ENODEV); + } + + ret = hisi_qm_start_qp(qp, 0); + if (ret < 0) { + hisi_qm_release_qp(qp); + pci_err(hpre->qm.pdev, "Can not start qp!\n"); + return ERR_PTR(-EINVAL); + } + + return qp; +} + +static int hpre_get_data_dma_addr(struct hpre_asym_request *hpre_req, + struct scatterlist *data, unsigned int len, + int is_src, dma_addr_t *tmp) +{ + struct hpre_ctx *ctx = hpre_req->ctx; + struct device *dev = HPRE_DEV(ctx); + enum dma_data_direction dma_dir; + + if (is_src) { + hpre_req->src = NULL; + dma_dir = DMA_TO_DEVICE; + } else { + hpre_req->dst = NULL; + dma_dir = DMA_FROM_DEVICE; + } + *tmp = dma_map_single(dev, sg_virt(data), + len, dma_dir); + if (unlikely(dma_mapping_error(dev, *tmp))) { + dev_err(dev, "dma map data err!\n"); + return -ENOMEM; + } + + return 0; +} + +static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, + struct scatterlist *data, unsigned int len, + int is_src, dma_addr_t *tmp) +{ + struct hpre_ctx *ctx = hpre_req->ctx; + struct device *dev = HPRE_DEV(ctx); + void *ptr; + int shift; + + shift = ctx->key_sz - len; + if (unlikely(shift < 0)) + return -EINVAL; + + ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_KERNEL); + if (unlikely(!ptr)) + return -ENOMEM; + + if (is_src) { + scatterwalk_map_and_copy(ptr + shift, data, 0, len, 0); + hpre_req->src = ptr; + } else { + hpre_req->dst = ptr; + } + + return 0; +} + +static int hpre_hw_data_init(struct hpre_asym_request *hpre_req, + struct scatterlist *data, unsigned int len, + int is_src, int is_dh) +{ + struct hpre_sqe *msg = &hpre_req->req; + struct hpre_ctx *ctx = hpre_req->ctx; + dma_addr_t tmp = 0; + int ret; + + /* when the data is dh's source, we should format it */ + if ((sg_is_last(data) && len == ctx->key_sz) && + ((is_dh && !is_src) || !is_dh)) + ret = hpre_get_data_dma_addr(hpre_req, data, len, is_src, &tmp); + else + ret = hpre_prepare_dma_buf(hpre_req, data, len, + is_src, &tmp); + if (unlikely(ret)) + return ret; + + if (is_src) + msg->in = cpu_to_le64(tmp); + else + msg->out = cpu_to_le64(tmp); + + return 0; +} + +static void hpre_hw_data_clr_all(struct hpre_ctx *ctx, + struct hpre_asym_request *req, + struct scatterlist *dst, + struct scatterlist *src) +{ + struct device *dev = HPRE_DEV(ctx); + struct hpre_sqe *sqe = &req->req; + dma_addr_t tmp; + + tmp = le64_to_cpu(sqe->in); + if (unlikely(!tmp)) + return; + + if (src) { + if (req->src) + dma_free_coherent(dev, ctx->key_sz, + req->src, tmp); + else + dma_unmap_single(dev, tmp, + ctx->key_sz, DMA_TO_DEVICE); + } + + tmp = le64_to_cpu(sqe->out); + if (unlikely(!tmp)) + return; + + if (req->dst) { + if (dst) + scatterwalk_map_and_copy(req->dst, dst, 0, + ctx->key_sz, 1); + dma_free_coherent(dev, ctx->key_sz, req->dst, tmp); + } else { + dma_unmap_single(dev, tmp, ctx->key_sz, DMA_FROM_DEVICE); + } +} + +static int hpre_alg_res_post_hf(struct hpre_ctx *ctx, struct hpre_sqe *sqe, + void **kreq) +{ + struct hpre_asym_request *req; + int err, id, done; + +#define HPRE_NO_HW_ERR 0 +#define HPRE_HW_TASK_DONE 3 +#define HREE_HW_ERR_MASK 0x7ff +#define HREE_SQE_DONE_MASK 0x3 + id = (int)le16_to_cpu(sqe->tag); + req = ctx->req_list[id]; + hpre_rm_req_from_ctx(req); + *kreq = req; + + err = (le32_to_cpu(sqe->dw0) >> HPRE_SQE_ALG_BITS) & + HREE_HW_ERR_MASK; + + done = (le32_to_cpu(sqe->dw0) >> HPRE_SQE_DONE_SHIFT) & + HREE_SQE_DONE_MASK; + + if (likely(err == HPRE_NO_HW_ERR && done == HPRE_HW_TASK_DONE)) + return 0; + + return -EINVAL; +} + +static int hpre_ctx_set(struct hpre_ctx *ctx, struct hisi_qp *qp, int qlen) +{ + if (!ctx || !qp || qlen < 0) + return -EINVAL; + + spin_lock_init(&ctx->req_lock); + ctx->qp = qp; + + ctx->req_list = kcalloc(qlen, sizeof(void *), GFP_KERNEL); + if (!ctx->req_list) + return -ENOMEM; + ctx->key_sz = 0; + ctx->crt_g2_mode = false; + idr_init(&ctx->req_idr); + + return 0; +} + +static void hpre_ctx_clear(struct hpre_ctx *ctx, bool is_clear_all) +{ + if (is_clear_all) { + idr_destroy(&ctx->req_idr); + kfree(ctx->req_list); + hisi_qm_release_qp(ctx->qp); + } + + ctx->crt_g2_mode = false; + ctx->key_sz = 0; +} + +static void hpre_dh_cb(struct hpre_ctx *ctx, void *resp) +{ + struct hpre_asym_request *req; + struct kpp_request *areq; + int ret; + + ret = hpre_alg_res_post_hf(ctx, resp, (void **)&req); + areq = req->areq.dh; + areq->dst_len = ctx->key_sz; + hpre_hw_data_clr_all(ctx, req, areq->dst, areq->src); + kpp_request_complete(areq, ret); +} + +static void hpre_rsa_cb(struct hpre_ctx *ctx, void *resp) +{ + struct hpre_asym_request *req; + struct akcipher_request *areq; + int ret; + + ret = hpre_alg_res_post_hf(ctx, resp, (void **)&req); + areq = req->areq.rsa; + areq->dst_len = ctx->key_sz; + hpre_hw_data_clr_all(ctx, req, areq->dst, areq->src); + akcipher_request_complete(areq, ret); +} + +static void hpre_alg_cb(struct hisi_qp *qp, void *resp) +{ + struct hpre_ctx *ctx = qp->qp_ctx; + struct hpre_sqe *sqe = resp; + + ctx->req_list[le16_to_cpu(sqe->tag)]->cb(ctx, resp); +} + +static int hpre_ctx_init(struct hpre_ctx *ctx) +{ + struct hisi_qp *qp; + + qp = hpre_get_qp_and_start(); + if (IS_ERR(qp)) + return PTR_ERR(qp); + + qp->qp_ctx = ctx; + qp->req_cb = hpre_alg_cb; + + return hpre_ctx_set(ctx, qp, QM_Q_DEPTH); +} + +static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) +{ + struct hpre_asym_request *h_req; + struct hpre_sqe *msg; + int req_id; + void *tmp; + + if (is_rsa) { + struct akcipher_request *akreq = req; + + if (akreq->dst_len < ctx->key_sz) { + akreq->dst_len = ctx->key_sz; + return -EOVERFLOW; + } + + tmp = akcipher_request_ctx(akreq); + h_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ); + h_req->cb = hpre_rsa_cb; + h_req->areq.rsa = akreq; + msg = &h_req->req; + memset(msg, 0, sizeof(*msg)); + } else { + struct kpp_request *kreq = req; + + if (kreq->dst_len < ctx->key_sz) { + kreq->dst_len = ctx->key_sz; + return -EOVERFLOW; + } + + tmp = kpp_request_ctx(kreq); + h_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ); + h_req->cb = hpre_dh_cb; + h_req->areq.dh = kreq; + msg = &h_req->req; + memset(msg, 0, sizeof(*msg)); + msg->key = cpu_to_le64((u64)ctx->dh.dma_xa_p); + } + + msg->dw0 |= cpu_to_le32(0x1 << HPRE_SQE_DONE_SHIFT); + msg->task_len1 = (ctx->key_sz >> HPRE_BITS_2_BYTES_SHIFT) - 1; + h_req->ctx = ctx; + + req_id = hpre_add_req_to_ctx(h_req); + if (req_id < 0) + return -EBUSY; + + msg->tag = cpu_to_le16((u16)req_id); + + return 0; +} + +#ifdef CONFIG_CRYPTO_DH +static int hpre_dh_compute_value(struct kpp_request *req) +{ + struct crypto_kpp *tfm = crypto_kpp_reqtfm(req); + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); + void *tmp = kpp_request_ctx(req); + struct hpre_asym_request *hpre_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ); + struct hpre_sqe *msg = &hpre_req->req; + int ctr = 0; + int ret; + + ret = hpre_msg_request_set(ctx, req, false); + if (unlikely(ret)) + return ret; + + if (req->src) { + ret = hpre_hw_data_init(hpre_req, req->src, req->src_len, 1, 1); + if (unlikely(ret)) + goto clear_all; + } + + ret = hpre_hw_data_init(hpre_req, req->dst, req->dst_len, 0, 1); + if (unlikely(ret)) + goto clear_all; + + if (ctx->crt_g2_mode && !req->src) + msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_DH_G2); + else + msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | HPRE_ALG_DH); + do { + ret = hisi_qp_send(ctx->qp, msg); + } while (ret == -EBUSY && ctr++ < HPRE_TRY_SEND_TIMES); + + /* success */ + if (likely(!ret)) + return -EINPROGRESS; + +clear_all: + hpre_rm_req_from_ctx(hpre_req); + hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); + + return ret; +} + +static int hpre_is_dh_params_length_valid(unsigned int key_sz) +{ +#define _HPRE_DH_GRP1 768 +#define _HPRE_DH_GRP2 1024 +#define _HPRE_DH_GRP5 1536 +#define _HPRE_DH_GRP14 2048 +#define _HPRE_DH_GRP15 3072 +#define _HPRE_DH_GRP16 4096 + switch (key_sz) { + case _HPRE_DH_GRP1: + case _HPRE_DH_GRP2: + case _HPRE_DH_GRP5: + case _HPRE_DH_GRP14: + case _HPRE_DH_GRP15: + case _HPRE_DH_GRP16: + return 0; + } + + return -EINVAL; +} + +static int hpre_dh_set_params(struct hpre_ctx *ctx, struct dh *params) +{ + struct device *dev = HPRE_DEV(ctx); + unsigned int sz; + + if (params->p_size > HPRE_DH_MAX_P_SZ) + return -EINVAL; + + if (hpre_is_dh_params_length_valid(params->p_size << + HPRE_BITS_2_BYTES_SHIFT)) + return -EINVAL; + + sz = ctx->key_sz = params->p_size; + ctx->dh.xa_p = dma_alloc_coherent(dev, sz << 1, + &ctx->dh.dma_xa_p, GFP_KERNEL); + if (!ctx->dh.xa_p) + return -ENOMEM; + + memcpy(ctx->dh.xa_p + sz, params->p, sz); + + /* If g equals 2 don't copy it */ + if (params->g_size == 1 && *(char *)params->g == HPRE_DH_G_FLAG) { + ctx->crt_g2_mode = true; + return 0; + } + + ctx->dh.g = dma_alloc_coherent(dev, sz, &ctx->dh.dma_g, GFP_KERNEL); + if (!ctx->dh.g) { + dma_free_coherent(dev, sz << 1, ctx->dh.xa_p, + ctx->dh.dma_xa_p); + ctx->dh.xa_p = NULL; + return -ENOMEM; + } + + memcpy(ctx->dh.g + (sz - params->g_size), params->g, params->g_size); + + return 0; +} + +static void hpre_dh_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all) +{ + struct device *dev = HPRE_DEV(ctx); + unsigned int sz = ctx->key_sz; + + if (is_clear_all) + hisi_qm_stop_qp(ctx->qp); + + if (ctx->dh.g) { + dma_free_coherent(dev, sz, ctx->dh.g, ctx->dh.dma_g); + ctx->dh.g = NULL; + } + + if (ctx->dh.xa_p) { + memzero_explicit(ctx->dh.xa_p, sz); + dma_free_coherent(dev, sz << 1, ctx->dh.xa_p, + ctx->dh.dma_xa_p); + ctx->dh.xa_p = NULL; + } + + hpre_ctx_clear(ctx, is_clear_all); +} + +static int hpre_dh_set_secret(struct crypto_kpp *tfm, const void *buf, + unsigned int len) +{ + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); + struct dh params; + int ret; + + if (crypto_dh_decode_key(buf, len, ¶ms) < 0) + return -EINVAL; + + /* Free old secret if any */ + hpre_dh_clear_ctx(ctx, false); + + ret = hpre_dh_set_params(ctx, ¶ms); + if (ret < 0) + goto err_clear_ctx; + + memcpy(ctx->dh.xa_p + (ctx->key_sz - params.key_size), params.key, + params.key_size); + + return 0; + +err_clear_ctx: + hpre_dh_clear_ctx(ctx, false); + return ret; +} + +static unsigned int hpre_dh_max_size(struct crypto_kpp *tfm) +{ + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); + + return ctx->key_sz; +} + +static int hpre_dh_init_tfm(struct crypto_kpp *tfm) +{ + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); + + return hpre_ctx_init(ctx); +} + +static void hpre_dh_exit_tfm(struct crypto_kpp *tfm) +{ + struct hpre_ctx *ctx = kpp_tfm_ctx(tfm); + + hpre_dh_clear_ctx(ctx, true); +} +#endif + +static void hpre_rsa_drop_leading_zeros(const char **ptr, size_t *len) +{ + while (!**ptr && *len) { + (*ptr)++; + (*len)--; + } +} + +static bool hpre_rsa_key_size_is_support(unsigned int len) +{ + unsigned int bits = len << HPRE_BITS_2_BYTES_SHIFT; + +#define _RSA_1024BITS_KEY_WDTH 1024 +#define _RSA_2048BITS_KEY_WDTH 2048 +#define _RSA_3072BITS_KEY_WDTH 3072 +#define _RSA_4096BITS_KEY_WDTH 4096 + + switch (bits) { + case _RSA_1024BITS_KEY_WDTH: + case _RSA_2048BITS_KEY_WDTH: + case _RSA_3072BITS_KEY_WDTH: + case _RSA_4096BITS_KEY_WDTH: + return true; + default: + return false; + } +} + +static int hpre_rsa_enc(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + void *tmp = akcipher_request_ctx(req); + struct hpre_asym_request *hpre_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ); + struct hpre_sqe *msg = &hpre_req->req; + int ctr = 0; + int ret; + + /* For 512 and 1536 bits key size, use soft tfm instead */ + if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || + ctx->key_sz == HPRE_RSA_1536BITS_KSZ) { + akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); + ret = crypto_akcipher_encrypt(req); + akcipher_request_set_tfm(req, tfm); + return ret; + } + + if (unlikely(!ctx->rsa.pubkey)) + return -EINVAL; + + ret = hpre_msg_request_set(ctx, req, true); + if (unlikely(ret)) + return ret; + + msg->dw0 |= cpu_to_le32(HPRE_ALG_NC_NCRT); + msg->key = cpu_to_le64((u64)ctx->rsa.dma_pubkey); + + ret = hpre_hw_data_init(hpre_req, req->src, req->src_len, 1, 0); + if (unlikely(ret)) + goto clear_all; + + ret = hpre_hw_data_init(hpre_req, req->dst, req->dst_len, 0, 0); + if (unlikely(ret)) + goto clear_all; + + do { + ret = hisi_qp_send(ctx->qp, msg); + } while (ret == -EBUSY && ctr++ < HPRE_TRY_SEND_TIMES); + + /* success */ + if (likely(!ret)) + return -EINPROGRESS; + +clear_all: + hpre_rm_req_from_ctx(hpre_req); + hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); + + return ret; +} + +static int hpre_rsa_dec(struct akcipher_request *req) +{ + struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + void *tmp = akcipher_request_ctx(req); + struct hpre_asym_request *hpre_req = PTR_ALIGN(tmp, HPRE_ALIGN_SZ); + struct hpre_sqe *msg = &hpre_req->req; + int ctr = 0; + int ret; + + /* For 512 and 1536 bits key size, use soft tfm instead */ + if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || + ctx->key_sz == HPRE_RSA_1536BITS_KSZ) { + akcipher_request_set_tfm(req, ctx->rsa.soft_tfm); + ret = crypto_akcipher_decrypt(req); + akcipher_request_set_tfm(req, tfm); + return ret; + } + + if (unlikely(!ctx->rsa.prikey)) + return -EINVAL; + + ret = hpre_msg_request_set(ctx, req, true); + if (unlikely(ret)) + return ret; + + if (ctx->crt_g2_mode) { + msg->key = cpu_to_le64((u64)ctx->rsa.dma_crt_prikey); + msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | + HPRE_ALG_NC_CRT); + } else { + msg->key = cpu_to_le64((u64)ctx->rsa.dma_prikey); + msg->dw0 = cpu_to_le32(le32_to_cpu(msg->dw0) | + HPRE_ALG_NC_NCRT); + } + + ret = hpre_hw_data_init(hpre_req, req->src, req->src_len, 1, 0); + if (unlikely(ret)) + goto clear_all; + + ret = hpre_hw_data_init(hpre_req, req->dst, req->dst_len, 0, 0); + if (unlikely(ret)) + goto clear_all; + + do { + ret = hisi_qp_send(ctx->qp, msg); + } while (ret == -EBUSY && ctr++ < HPRE_TRY_SEND_TIMES); + + /* success */ + if (likely(!ret)) + return -EINPROGRESS; + +clear_all: + hpre_rm_req_from_ctx(hpre_req); + hpre_hw_data_clr_all(ctx, hpre_req, req->dst, req->src); + + return ret; +} + +static int hpre_rsa_set_n(struct hpre_ctx *ctx, const char *value, + size_t vlen, bool private) +{ + const char *ptr = value; + + hpre_rsa_drop_leading_zeros(&ptr, &vlen); + + ctx->key_sz = vlen; + + /* if invalid key size provided, we use software tfm */ + if (!hpre_rsa_key_size_is_support(ctx->key_sz)) + return 0; + + ctx->rsa.pubkey = dma_alloc_coherent(HPRE_DEV(ctx), vlen << 1, + &ctx->rsa.dma_pubkey, + GFP_KERNEL); + if (!ctx->rsa.pubkey) + return -ENOMEM; + + if (private) { + ctx->rsa.prikey = dma_alloc_coherent(HPRE_DEV(ctx), vlen << 1, + &ctx->rsa.dma_prikey, + GFP_KERNEL); + if (!ctx->rsa.prikey) { + dma_free_coherent(HPRE_DEV(ctx), vlen << 1, + ctx->rsa.pubkey, + ctx->rsa.dma_pubkey); + ctx->rsa.pubkey = NULL; + return -ENOMEM; + } + memcpy(ctx->rsa.prikey + vlen, ptr, vlen); + } + memcpy(ctx->rsa.pubkey + vlen, ptr, vlen); + + /* Using hardware HPRE to do RSA */ + return 1; +} + +static int hpre_rsa_set_e(struct hpre_ctx *ctx, const char *value, + size_t vlen) +{ + const char *ptr = value; + + hpre_rsa_drop_leading_zeros(&ptr, &vlen); + + if (!ctx->key_sz || !vlen || vlen > ctx->key_sz) + return -EINVAL; + + memcpy(ctx->rsa.pubkey + ctx->key_sz - vlen, ptr, vlen); + + return 0; +} + +static int hpre_rsa_set_d(struct hpre_ctx *ctx, const char *value, + size_t vlen) +{ + const char *ptr = value; + + hpre_rsa_drop_leading_zeros(&ptr, &vlen); + + if (!ctx->key_sz || !vlen || vlen > ctx->key_sz) + return -EINVAL; + + memcpy(ctx->rsa.prikey + ctx->key_sz - vlen, ptr, vlen); + + return 0; +} + +static int hpre_crt_para_get(char *para, size_t para_sz, + const char *raw, size_t raw_sz) +{ + const char *ptr = raw; + size_t len = raw_sz; + + hpre_rsa_drop_leading_zeros(&ptr, &len); + if (!len || len > para_sz) + return -EINVAL; + + memcpy(para + para_sz - len, ptr, len); + + return 0; +} + +static int hpre_rsa_setkey_crt(struct hpre_ctx *ctx, struct rsa_key *rsa_key) +{ + unsigned int hlf_ksz = ctx->key_sz >> 1; + struct device *dev = HPRE_DEV(ctx); + u64 offset; + int ret; + + ctx->rsa.crt_prikey = dma_alloc_coherent(dev, hlf_ksz * HPRE_CRT_PRMS, + &ctx->rsa.dma_crt_prikey, + GFP_KERNEL); + if (!ctx->rsa.crt_prikey) + return -ENOMEM; + + ret = hpre_crt_para_get(ctx->rsa.crt_prikey, hlf_ksz, + rsa_key->dq, rsa_key->dq_sz); + if (ret) + goto free_key; + + offset = hlf_ksz; + ret = hpre_crt_para_get(ctx->rsa.crt_prikey + offset, hlf_ksz, + rsa_key->dp, rsa_key->dp_sz); + if (ret) + goto free_key; + + offset = hlf_ksz * HPRE_CRT_Q; + ret = hpre_crt_para_get(ctx->rsa.crt_prikey + offset, hlf_ksz, + rsa_key->q, rsa_key->q_sz); + if (ret) + goto free_key; + + offset = hlf_ksz * HPRE_CRT_P; + ret = hpre_crt_para_get(ctx->rsa.crt_prikey + offset, hlf_ksz, + rsa_key->p, rsa_key->p_sz); + if (ret) + goto free_key; + + offset = hlf_ksz * HPRE_CRT_INV; + ret = hpre_crt_para_get(ctx->rsa.crt_prikey + offset, hlf_ksz, + rsa_key->qinv, rsa_key->qinv_sz); + if (ret) + goto free_key; + + ctx->crt_g2_mode = true; + + return 0; + +free_key: + offset = hlf_ksz * HPRE_CRT_PRMS; + memzero_explicit(ctx->rsa.crt_prikey, offset); + dma_free_coherent(dev, hlf_ksz * HPRE_CRT_PRMS, ctx->rsa.crt_prikey, + ctx->rsa.dma_crt_prikey); + ctx->rsa.crt_prikey = NULL; + ctx->crt_g2_mode = false; + + return ret; +} + +/* If it is clear all, all the resources of the QP will be cleaned. */ +static void hpre_rsa_clear_ctx(struct hpre_ctx *ctx, bool is_clear_all) +{ + unsigned int half_key_sz = ctx->key_sz >> 1; + struct device *dev = HPRE_DEV(ctx); + + if (is_clear_all) + hisi_qm_stop_qp(ctx->qp); + + if (ctx->rsa.pubkey) { + dma_free_coherent(dev, ctx->key_sz << 1, + ctx->rsa.pubkey, ctx->rsa.dma_pubkey); + ctx->rsa.pubkey = NULL; + } + + if (ctx->rsa.crt_prikey) { + memzero_explicit(ctx->rsa.crt_prikey, + half_key_sz * HPRE_CRT_PRMS); + dma_free_coherent(dev, half_key_sz * HPRE_CRT_PRMS, + ctx->rsa.crt_prikey, ctx->rsa.dma_crt_prikey); + ctx->rsa.crt_prikey = NULL; + } + + if (ctx->rsa.prikey) { + memzero_explicit(ctx->rsa.prikey, ctx->key_sz); + dma_free_coherent(dev, ctx->key_sz << 1, ctx->rsa.prikey, + ctx->rsa.dma_prikey); + ctx->rsa.prikey = NULL; + } + + hpre_ctx_clear(ctx, is_clear_all); +} + +/* + * we should judge if it is CRT or not, + * CRT: return true, N-CRT: return false . + */ +static bool hpre_is_crt_key(struct rsa_key *key) +{ + u16 len = key->p_sz + key->q_sz + key->dp_sz + key->dq_sz + + key->qinv_sz; + +#define LEN_OF_NCRT_PARA 5 + + /* N-CRT less than 5 parameters */ + return len > LEN_OF_NCRT_PARA; +} + +static int hpre_rsa_setkey(struct hpre_ctx *ctx, const void *key, + unsigned int keylen, bool private) +{ + struct rsa_key rsa_key; + int ret; + + hpre_rsa_clear_ctx(ctx, false); + + if (private) + ret = rsa_parse_priv_key(&rsa_key, key, keylen); + else + ret = rsa_parse_pub_key(&rsa_key, key, keylen); + if (ret < 0) + return ret; + + ret = hpre_rsa_set_n(ctx, rsa_key.n, rsa_key.n_sz, private); + if (ret <= 0) + return ret; + + if (private) { + ret = hpre_rsa_set_d(ctx, rsa_key.d, rsa_key.d_sz); + if (ret < 0) + goto free; + + if (hpre_is_crt_key(&rsa_key)) { + ret = hpre_rsa_setkey_crt(ctx, &rsa_key); + if (ret < 0) + goto free; + } + } + + ret = hpre_rsa_set_e(ctx, rsa_key.e, rsa_key.e_sz); + if (ret < 0) + goto free; + + if ((private && !ctx->rsa.prikey) || !ctx->rsa.pubkey) { + ret = -EINVAL; + goto free; + } + + return 0; + +free: + hpre_rsa_clear_ctx(ctx, false); + return ret; +} + +static int hpre_rsa_setpubkey(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + int ret; + + ret = crypto_akcipher_set_pub_key(ctx->rsa.soft_tfm, key, keylen); + if (ret) + return ret; + + return hpre_rsa_setkey(ctx, key, keylen, false); +} + +static int hpre_rsa_setprivkey(struct crypto_akcipher *tfm, const void *key, + unsigned int keylen) +{ + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + int ret; + + ret = crypto_akcipher_set_priv_key(ctx->rsa.soft_tfm, key, keylen); + if (ret) + return ret; + + return hpre_rsa_setkey(ctx, key, keylen, true); +} + +static unsigned int hpre_rsa_max_size(struct crypto_akcipher *tfm) +{ + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + + /* For 512 and 1536 bits key size, use soft tfm instead */ + if (ctx->key_sz == HPRE_RSA_512BITS_KSZ || + ctx->key_sz == HPRE_RSA_1536BITS_KSZ) + return crypto_akcipher_maxsize(ctx->rsa.soft_tfm); + + return ctx->key_sz; +} + +static int hpre_rsa_init_tfm(struct crypto_akcipher *tfm) +{ + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + int ret; + + ctx->rsa.soft_tfm = crypto_alloc_akcipher("rsa-generic", 0, 0); + if (IS_ERR(ctx->rsa.soft_tfm)) { + pr_err("Can not alloc_akcipher!\n"); + return PTR_ERR(ctx->rsa.soft_tfm); + } + + ret = hpre_ctx_init(ctx); + if (ret) + crypto_free_akcipher(ctx->rsa.soft_tfm); + + return ret; +} + +static void hpre_rsa_exit_tfm(struct crypto_akcipher *tfm) +{ + struct hpre_ctx *ctx = akcipher_tfm_ctx(tfm); + + hpre_rsa_clear_ctx(ctx, true); + crypto_free_akcipher(ctx->rsa.soft_tfm); +} + +static struct akcipher_alg rsa = { + .sign = hpre_rsa_dec, + .verify = hpre_rsa_enc, + .encrypt = hpre_rsa_enc, + .decrypt = hpre_rsa_dec, + .set_pub_key = hpre_rsa_setpubkey, + .set_priv_key = hpre_rsa_setprivkey, + .max_size = hpre_rsa_max_size, + .init = hpre_rsa_init_tfm, + .exit = hpre_rsa_exit_tfm, + .reqsize = sizeof(struct hpre_asym_request) + HPRE_ALIGN_SZ, + .base = { + .cra_ctxsize = sizeof(struct hpre_ctx), + .cra_priority = HPRE_CRYPTO_ALG_PRI, + .cra_name = "rsa", + .cra_driver_name = "hpre-rsa", + .cra_module = THIS_MODULE, + }, +}; + +#ifdef CONFIG_CRYPTO_DH +static struct kpp_alg dh = { + .set_secret = hpre_dh_set_secret, + .generate_public_key = hpre_dh_compute_value, + .compute_shared_secret = hpre_dh_compute_value, + .max_size = hpre_dh_max_size, + .init = hpre_dh_init_tfm, + .exit = hpre_dh_exit_tfm, + .reqsize = sizeof(struct hpre_asym_request) + HPRE_ALIGN_SZ, + .base = { + .cra_ctxsize = sizeof(struct hpre_ctx), + .cra_priority = HPRE_CRYPTO_ALG_PRI, + .cra_name = "dh", + .cra_driver_name = "hpre-dh", + .cra_module = THIS_MODULE, + }, +}; +#endif + +int hpre_algs_register(void) +{ + int ret = 0; + + mutex_lock(&hpre_alg_lock); + if (++hpre_active_devs == 1) { + rsa.base.cra_flags = 0; + ret = crypto_register_akcipher(&rsa); + if (ret) + goto unlock; +#ifdef CONFIG_CRYPTO_DH + ret = crypto_register_kpp(&dh); + if (ret) { + crypto_unregister_akcipher(&rsa); + goto unlock; + } +#endif + } + +unlock: + mutex_unlock(&hpre_alg_lock); + return ret; +} + +void hpre_algs_unregister(void) +{ + mutex_lock(&hpre_alg_lock); + if (--hpre_active_devs == 0) { + crypto_unregister_akcipher(&rsa); +#ifdef CONFIG_CRYPTO_DH + crypto_unregister_kpp(&dh); +#endif + } + mutex_unlock(&hpre_alg_lock); +} --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/hpre/hpre_main.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -0,0 +1,1037 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2018-2019 HiSilicon Limited. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hpre.h" + +#define HPRE_VF_NUM 63 +#define HPRE_QUEUE_NUM_V2 1024 +#define HPRE_QM_ABNML_INT_MASK 0x100004 +#define HPRE_CTRL_CNT_CLR_CE_BIT BIT(0) +#define HPRE_COMM_CNT_CLR_CE 0x0 +#define HPRE_CTRL_CNT_CLR_CE 0x301000 +#define HPRE_FSM_MAX_CNT 0x301008 +#define HPRE_VFG_AXQOS 0x30100c +#define HPRE_VFG_AXCACHE 0x301010 +#define HPRE_RDCHN_INI_CFG 0x301014 +#define HPRE_AWUSR_FP_CFG 0x301018 +#define HPRE_BD_ENDIAN 0x301020 +#define HPRE_ECC_BYPASS 0x301024 +#define HPRE_RAS_WIDTH_CFG 0x301028 +#define HPRE_POISON_BYPASS 0x30102c +#define HPRE_BD_ARUSR_CFG 0x301030 +#define HPRE_BD_AWUSR_CFG 0x301034 +#define HPRE_TYPES_ENB 0x301038 +#define HPRE_DATA_RUSER_CFG 0x30103c +#define HPRE_DATA_WUSER_CFG 0x301040 +#define HPRE_INT_MASK 0x301400 +#define HPRE_INT_STATUS 0x301800 +#define HPRE_CORE_INT_ENABLE 0 +#define HPRE_CORE_INT_DISABLE 0x003fffff +#define HPRE_RAS_ECC_1BIT_TH 0x30140c +#define HPRE_RDCHN_INI_ST 0x301a00 +#define HPRE_CLSTR_BASE 0x302000 +#define HPRE_CORE_EN_OFFSET 0x04 +#define HPRE_CORE_INI_CFG_OFFSET 0x20 +#define HPRE_CORE_INI_STATUS_OFFSET 0x80 +#define HPRE_CORE_HTBT_WARN_OFFSET 0x8c +#define HPRE_CORE_IS_SCHD_OFFSET 0x90 + +#define HPRE_RAS_CE_ENB 0x301410 +#define HPRE_HAC_RAS_CE_ENABLE 0x3f +#define HPRE_RAS_NFE_ENB 0x301414 +#define HPRE_HAC_RAS_NFE_ENABLE 0x3fffc0 +#define HPRE_RAS_FE_ENB 0x301418 +#define HPRE_HAC_RAS_FE_ENABLE 0 + +#define HPRE_CORE_ENB (HPRE_CLSTR_BASE + HPRE_CORE_EN_OFFSET) +#define HPRE_CORE_INI_CFG (HPRE_CLSTR_BASE + HPRE_CORE_INI_CFG_OFFSET) +#define HPRE_CORE_INI_STATUS (HPRE_CLSTR_BASE + HPRE_CORE_INI_STATUS_OFFSET) +#define HPRE_HAC_ECC1_CNT 0x301a04 +#define HPRE_HAC_ECC2_CNT 0x301a08 +#define HPRE_HAC_INT_STATUS 0x301800 +#define HPRE_HAC_SOURCE_INT 0x301600 +#define MASTER_GLOBAL_CTRL_SHUTDOWN 1 +#define MASTER_TRANS_RETURN_RW 3 +#define HPRE_MASTER_TRANS_RETURN 0x300150 +#define HPRE_MASTER_GLOBAL_CTRL 0x300000 +#define HPRE_CLSTR_ADDR_INTRVL 0x1000 +#define HPRE_CLUSTER_INQURY 0x100 +#define HPRE_CLSTR_ADDR_INQRY_RSLT 0x104 +#define HPRE_TIMEOUT_ABNML_BIT 6 +#define HPRE_PASID_EN_BIT 9 +#define HPRE_REG_RD_INTVRL_US 10 +#define HPRE_REG_RD_TMOUT_US 1000 +#define HPRE_DBGFS_VAL_MAX_LEN 20 +#define HPRE_PCI_DEVICE_ID 0xa258 +#define HPRE_PCI_VF_DEVICE_ID 0xa259 +#define HPRE_ADDR(qm, offset) ((qm)->io_base + (offset)) +#define HPRE_QM_USR_CFG_MASK 0xfffffffe +#define HPRE_QM_AXI_CFG_MASK 0xffff +#define HPRE_QM_VFG_AX_MASK 0xff +#define HPRE_BD_USR_MASK 0x3 +#define HPRE_CLUSTER_CORE_MASK 0xf + +#define HPRE_VIA_MSI_DSM 1 + +static LIST_HEAD(hpre_list); +static DEFINE_MUTEX(hpre_list_lock); +static const char hpre_name[] = "hisi_hpre"; +static struct dentry *hpre_debugfs_root; +static const struct pci_device_id hpre_dev_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_DEVICE_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_VF_DEVICE_ID) }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, hpre_dev_ids); + +struct hpre_hw_error { + u32 int_msk; + const char *msg; +}; + +static const char * const hpre_debug_file_name[] = { + [HPRE_CURRENT_QM] = "current_qm", + [HPRE_CLEAR_ENABLE] = "rdclr_en", + [HPRE_CLUSTER_CTRL] = "cluster_ctrl", +}; + +static const struct hpre_hw_error hpre_hw_errors[] = { + { .int_msk = BIT(0), .msg = "core_ecc_1bit_err_int_set" }, + { .int_msk = BIT(1), .msg = "core_ecc_2bit_err_int_set" }, + { .int_msk = BIT(2), .msg = "dat_wb_poison_int_set" }, + { .int_msk = BIT(3), .msg = "dat_rd_poison_int_set" }, + { .int_msk = BIT(4), .msg = "bd_rd_poison_int_set" }, + { .int_msk = BIT(5), .msg = "ooo_ecc_2bit_err_int_set" }, + { .int_msk = BIT(6), .msg = "cluster1_shb_timeout_int_set" }, + { .int_msk = BIT(7), .msg = "cluster2_shb_timeout_int_set" }, + { .int_msk = BIT(8), .msg = "cluster3_shb_timeout_int_set" }, + { .int_msk = BIT(9), .msg = "cluster4_shb_timeout_int_set" }, + { .int_msk = GENMASK(15, 10), .msg = "ooo_rdrsp_err_int_set" }, + { .int_msk = GENMASK(21, 16), .msg = "ooo_wrrsp_err_int_set" }, + { /* sentinel */ } +}; + +static const u64 hpre_cluster_offsets[] = { + [HPRE_CLUSTER0] = + HPRE_CLSTR_BASE + HPRE_CLUSTER0 * HPRE_CLSTR_ADDR_INTRVL, + [HPRE_CLUSTER1] = + HPRE_CLSTR_BASE + HPRE_CLUSTER1 * HPRE_CLSTR_ADDR_INTRVL, + [HPRE_CLUSTER2] = + HPRE_CLSTR_BASE + HPRE_CLUSTER2 * HPRE_CLSTR_ADDR_INTRVL, + [HPRE_CLUSTER3] = + HPRE_CLSTR_BASE + HPRE_CLUSTER3 * HPRE_CLSTR_ADDR_INTRVL, +}; + +static struct debugfs_reg32 hpre_cluster_dfx_regs[] = { + {"CORES_EN_STATUS ", HPRE_CORE_EN_OFFSET}, + {"CORES_INI_CFG ", HPRE_CORE_INI_CFG_OFFSET}, + {"CORES_INI_STATUS ", HPRE_CORE_INI_STATUS_OFFSET}, + {"CORES_HTBT_WARN ", HPRE_CORE_HTBT_WARN_OFFSET}, + {"CORES_IS_SCHD ", HPRE_CORE_IS_SCHD_OFFSET}, +}; + +static struct debugfs_reg32 hpre_com_dfx_regs[] = { + {"READ_CLR_EN ", HPRE_CTRL_CNT_CLR_CE}, + {"AXQOS ", HPRE_VFG_AXQOS}, + {"AWUSR_CFG ", HPRE_AWUSR_FP_CFG}, + {"QM_ARUSR_MCFG1 ", QM_ARUSER_M_CFG_1}, + {"QM_AWUSR_MCFG1 ", QM_AWUSER_M_CFG_1}, + {"BD_ENDIAN ", HPRE_BD_ENDIAN}, + {"ECC_CHECK_CTRL ", HPRE_ECC_BYPASS}, + {"RAS_INT_WIDTH ", HPRE_RAS_WIDTH_CFG}, + {"POISON_BYPASS ", HPRE_POISON_BYPASS}, + {"BD_ARUSER ", HPRE_BD_ARUSR_CFG}, + {"BD_AWUSER ", HPRE_BD_AWUSR_CFG}, + {"DATA_ARUSER ", HPRE_DATA_RUSER_CFG}, + {"DATA_AWUSER ", HPRE_DATA_WUSER_CFG}, + {"INT_STATUS ", HPRE_INT_STATUS}, +}; + +static int hpre_pf_q_num_set(const char *val, const struct kernel_param *kp) +{ + struct pci_dev *pdev; + u32 n, q_num; + u8 rev_id; + int ret; + + if (!val) + return -EINVAL; + + pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, HPRE_PCI_DEVICE_ID, NULL); + if (!pdev) { + q_num = HPRE_QUEUE_NUM_V2; + pr_info("No device found currently, suppose queue number is %d\n", + q_num); + } else { + rev_id = pdev->revision; + if (rev_id != QM_HW_V2) + return -EINVAL; + + q_num = HPRE_QUEUE_NUM_V2; + } + + ret = kstrtou32(val, 10, &n); + if (ret != 0 || n == 0 || n > q_num) + return -EINVAL; + + return param_set_int(val, kp); +} + +static const struct kernel_param_ops hpre_pf_q_num_ops = { + .set = hpre_pf_q_num_set, + .get = param_get_int, +}; + +static u32 hpre_pf_q_num = HPRE_PF_DEF_Q_NUM; +module_param_cb(hpre_pf_q_num, &hpre_pf_q_num_ops, &hpre_pf_q_num, 0444); +MODULE_PARM_DESC(hpre_pf_q_num, "Number of queues in PF of CS(1-1024)"); + +static inline void hpre_add_to_list(struct hpre *hpre) +{ + mutex_lock(&hpre_list_lock); + list_add_tail(&hpre->list, &hpre_list); + mutex_unlock(&hpre_list_lock); +} + +static inline void hpre_remove_from_list(struct hpre *hpre) +{ + mutex_lock(&hpre_list_lock); + list_del(&hpre->list); + mutex_unlock(&hpre_list_lock); +} + +struct hpre *hpre_find_device(int node) +{ + struct hpre *hpre, *ret = NULL; + int min_distance = INT_MAX; + struct device *dev; + int dev_node = 0; + + mutex_lock(&hpre_list_lock); + list_for_each_entry(hpre, &hpre_list, list) { + dev = &hpre->qm.pdev->dev; +#ifdef CONFIG_NUMA + dev_node = dev->numa_node; + if (dev_node < 0) + dev_node = 0; +#endif + if (node_distance(dev_node, node) < min_distance) { + ret = hpre; + min_distance = node_distance(dev_node, node); + } + } + mutex_unlock(&hpre_list_lock); + + return ret; +} + +static int hpre_cfg_by_dsm(struct hisi_qm *qm) +{ + struct device *dev = &qm->pdev->dev; + union acpi_object *obj; + guid_t guid; + + if (guid_parse("b06b81ab-0134-4a45-9b0c-483447b95fa7", &guid)) { + dev_err(dev, "Hpre GUID failed\n"); + return -EINVAL; + } + + /* Switch over to MSI handling due to non-standard PCI implementation */ + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, + 0, HPRE_VIA_MSI_DSM, NULL); + if (!obj) { + dev_err(dev, "ACPI handle failed!\n"); + return -EIO; + } + + ACPI_FREE(obj); + + return 0; +} + +static int hpre_set_user_domain_and_cache(struct hpre *hpre) +{ + struct hisi_qm *qm = &hpre->qm; + struct device *dev = &qm->pdev->dev; + unsigned long offset; + int ret, i; + u32 val; + + writel(HPRE_QM_USR_CFG_MASK, HPRE_ADDR(qm, QM_ARUSER_M_CFG_ENABLE)); + writel(HPRE_QM_USR_CFG_MASK, HPRE_ADDR(qm, QM_AWUSER_M_CFG_ENABLE)); + writel_relaxed(HPRE_QM_AXI_CFG_MASK, HPRE_ADDR(qm, QM_AXI_M_CFG)); + + /* disable FLR triggered by BME(bus master enable) */ + writel(PEH_AXUSER_CFG, HPRE_ADDR(qm, QM_PEH_AXUSER_CFG)); + writel(PEH_AXUSER_CFG_ENABLE, HPRE_ADDR(qm, QM_PEH_AXUSER_CFG_ENABLE)); + + /* HPRE need more time, we close this interrupt */ + val = readl_relaxed(HPRE_ADDR(qm, HPRE_QM_ABNML_INT_MASK)); + val |= BIT(HPRE_TIMEOUT_ABNML_BIT); + writel_relaxed(val, HPRE_ADDR(qm, HPRE_QM_ABNML_INT_MASK)); + + writel(0x1, HPRE_ADDR(qm, HPRE_TYPES_ENB)); + writel(HPRE_QM_VFG_AX_MASK, HPRE_ADDR(qm, HPRE_VFG_AXCACHE)); + writel(0x0, HPRE_ADDR(qm, HPRE_BD_ENDIAN)); + writel(0x0, HPRE_ADDR(qm, HPRE_INT_MASK)); + writel(0x0, HPRE_ADDR(qm, HPRE_RAS_ECC_1BIT_TH)); + writel(0x0, HPRE_ADDR(qm, HPRE_POISON_BYPASS)); + writel(0x0, HPRE_ADDR(qm, HPRE_COMM_CNT_CLR_CE)); + writel(0x0, HPRE_ADDR(qm, HPRE_ECC_BYPASS)); + + writel(HPRE_BD_USR_MASK, HPRE_ADDR(qm, HPRE_BD_ARUSR_CFG)); + writel(HPRE_BD_USR_MASK, HPRE_ADDR(qm, HPRE_BD_AWUSR_CFG)); + writel(0x1, HPRE_ADDR(qm, HPRE_RDCHN_INI_CFG)); + ret = readl_relaxed_poll_timeout(HPRE_ADDR(qm, HPRE_RDCHN_INI_ST), val, + val & BIT(0), + HPRE_REG_RD_INTVRL_US, + HPRE_REG_RD_TMOUT_US); + if (ret) { + dev_err(dev, "read rd channel timeout fail!\n"); + return -ETIMEDOUT; + } + + for (i = 0; i < HPRE_CLUSTERS_NUM; i++) { + offset = i * HPRE_CLSTR_ADDR_INTRVL; + + /* clusters initiating */ + writel(HPRE_CLUSTER_CORE_MASK, + HPRE_ADDR(qm, offset + HPRE_CORE_ENB)); + writel(0x1, HPRE_ADDR(qm, offset + HPRE_CORE_INI_CFG)); + ret = readl_relaxed_poll_timeout(HPRE_ADDR(qm, offset + + HPRE_CORE_INI_STATUS), val, + ((val & HPRE_CLUSTER_CORE_MASK) == + HPRE_CLUSTER_CORE_MASK), + HPRE_REG_RD_INTVRL_US, + HPRE_REG_RD_TMOUT_US); + if (ret) { + dev_err(dev, + "cluster %d int st status timeout!\n", i); + return -ETIMEDOUT; + } + } + + ret = hpre_cfg_by_dsm(qm); + if (ret) + dev_err(dev, "acpi_evaluate_dsm err.\n"); + + return ret; +} + +static void hpre_cnt_regs_clear(struct hisi_qm *qm) +{ + unsigned long offset; + int i; + + /* clear current_qm */ + writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF); + writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF); + + /* clear clusterX/cluster_ctrl */ + for (i = 0; i < HPRE_CLUSTERS_NUM; i++) { + offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; + writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); + } + + /* clear rdclr_en */ + writel(0x0, qm->io_base + HPRE_CTRL_CNT_CLR_CE); + + hisi_qm_debug_regs_clear(qm); +} + +static void hpre_hw_error_disable(struct hisi_qm *qm) +{ + /* disable hpre hw error interrupts */ + writel(HPRE_CORE_INT_DISABLE, qm->io_base + HPRE_INT_MASK); +} + +static void hpre_hw_error_enable(struct hisi_qm *qm) +{ + /* enable hpre hw error interrupts */ + writel(HPRE_CORE_INT_ENABLE, qm->io_base + HPRE_INT_MASK); + writel(HPRE_HAC_RAS_CE_ENABLE, qm->io_base + HPRE_RAS_CE_ENB); + writel(HPRE_HAC_RAS_NFE_ENABLE, qm->io_base + HPRE_RAS_NFE_ENB); + writel(HPRE_HAC_RAS_FE_ENABLE, qm->io_base + HPRE_RAS_FE_ENB); +} + +static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file) +{ + struct hpre *hpre = container_of(file->debug, struct hpre, debug); + + return &hpre->qm; +} + +static u32 hpre_current_qm_read(struct hpre_debugfs_file *file) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + + return readl(qm->io_base + QM_DFX_MB_CNT_VF); +} + +static int hpre_current_qm_write(struct hpre_debugfs_file *file, u32 val) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + struct hpre_debug *debug = file->debug; + struct hpre *hpre = container_of(debug, struct hpre, debug); + u32 num_vfs = hpre->num_vfs; + u32 vfq_num, tmp; + + + if (val > num_vfs) + return -EINVAL; + + /* According PF or VF Dev ID to calculation curr_qm_qp_num and store */ + if (val == 0) { + qm->debug.curr_qm_qp_num = qm->qp_num; + } else { + vfq_num = (qm->ctrl_qp_num - qm->qp_num) / num_vfs; + if (val == num_vfs) { + qm->debug.curr_qm_qp_num = + qm->ctrl_qp_num - qm->qp_num - (num_vfs - 1) * vfq_num; + } else { + qm->debug.curr_qm_qp_num = vfq_num; + } + } + + writel(val, qm->io_base + QM_DFX_MB_CNT_VF); + writel(val, qm->io_base + QM_DFX_DB_CNT_VF); + + tmp = val | + (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_Q_MASK); + writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); + + tmp = val | + (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_Q_MASK); + writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); + + return 0; +} + +static u32 hpre_clear_enable_read(struct hpre_debugfs_file *file) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + + return readl(qm->io_base + HPRE_CTRL_CNT_CLR_CE) & + HPRE_CTRL_CNT_CLR_CE_BIT; +} + +static int hpre_clear_enable_write(struct hpre_debugfs_file *file, u32 val) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + u32 tmp; + + if (val != 1 && val != 0) + return -EINVAL; + + tmp = (readl(qm->io_base + HPRE_CTRL_CNT_CLR_CE) & + ~HPRE_CTRL_CNT_CLR_CE_BIT) | val; + writel(tmp, qm->io_base + HPRE_CTRL_CNT_CLR_CE); + + return 0; +} + +static u32 hpre_cluster_inqry_read(struct hpre_debugfs_file *file) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + int cluster_index = file->index - HPRE_CLUSTER_CTRL; + unsigned long offset = HPRE_CLSTR_BASE + + cluster_index * HPRE_CLSTR_ADDR_INTRVL; + + return readl(qm->io_base + offset + HPRE_CLSTR_ADDR_INQRY_RSLT); +} + +static int hpre_cluster_inqry_write(struct hpre_debugfs_file *file, u32 val) +{ + struct hisi_qm *qm = hpre_file_to_qm(file); + int cluster_index = file->index - HPRE_CLUSTER_CTRL; + unsigned long offset = HPRE_CLSTR_BASE + cluster_index * + HPRE_CLSTR_ADDR_INTRVL; + + writel(val, qm->io_base + offset + HPRE_CLUSTER_INQURY); + + return 0; +} + +static ssize_t hpre_ctrl_debug_read(struct file *filp, char __user *buf, + size_t count, loff_t *pos) +{ + struct hpre_debugfs_file *file = filp->private_data; + char tbuf[HPRE_DBGFS_VAL_MAX_LEN]; + u32 val; + int ret; + + spin_lock_irq(&file->lock); + switch (file->type) { + case HPRE_CURRENT_QM: + val = hpre_current_qm_read(file); + break; + case HPRE_CLEAR_ENABLE: + val = hpre_clear_enable_read(file); + break; + case HPRE_CLUSTER_CTRL: + val = hpre_cluster_inqry_read(file); + break; + default: + spin_unlock_irq(&file->lock); + return -EINVAL; + } + spin_unlock_irq(&file->lock); + ret = snprintf(tbuf, HPRE_DBGFS_VAL_MAX_LEN, "%u\n", val); + return simple_read_from_buffer(buf, count, pos, tbuf, ret); +} + +static ssize_t hpre_ctrl_debug_write(struct file *filp, const char __user *buf, + size_t count, loff_t *pos) +{ + struct hpre_debugfs_file *file = filp->private_data; + char tbuf[HPRE_DBGFS_VAL_MAX_LEN]; + unsigned long val; + int len, ret; + + if (*pos != 0) + return 0; + + if (count >= HPRE_DBGFS_VAL_MAX_LEN) + return -ENOSPC; + + len = simple_write_to_buffer(tbuf, HPRE_DBGFS_VAL_MAX_LEN - 1, + pos, buf, count); + if (len < 0) + return len; + + tbuf[len] = '\0'; + if (kstrtoul(tbuf, 0, &val)) + return -EFAULT; + + spin_lock_irq(&file->lock); + switch (file->type) { + case HPRE_CURRENT_QM: + ret = hpre_current_qm_write(file, val); + if (ret) + goto err_input; + break; + case HPRE_CLEAR_ENABLE: + ret = hpre_clear_enable_write(file, val); + if (ret) + goto err_input; + break; + case HPRE_CLUSTER_CTRL: + ret = hpre_cluster_inqry_write(file, val); + if (ret) + goto err_input; + break; + default: + ret = -EINVAL; + goto err_input; + } + spin_unlock_irq(&file->lock); + + return count; + +err_input: + spin_unlock_irq(&file->lock); + return ret; +} + +static const struct file_operations hpre_ctrl_debug_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = hpre_ctrl_debug_read, + .write = hpre_ctrl_debug_write, +}; + +static int hpre_create_debugfs_file(struct hpre_debug *dbg, struct dentry *dir, + enum hpre_ctrl_dbgfs_file type, int indx) +{ + struct dentry *file_dir; + + if (dir) + file_dir = dir; + else + file_dir = dbg->debug_root; + + if (type >= HPRE_DEBUG_FILE_NUM) + return -EINVAL; + + spin_lock_init(&dbg->files[indx].lock); + dbg->files[indx].debug = dbg; + dbg->files[indx].type = type; + dbg->files[indx].index = indx; + debugfs_create_file(hpre_debug_file_name[type], 0600, file_dir, + dbg->files + indx, &hpre_ctrl_debug_fops); + + return 0; +} + +static int hpre_pf_comm_regs_debugfs_init(struct hpre_debug *debug) +{ + struct hpre *hpre = container_of(debug, struct hpre, debug); + struct hisi_qm *qm = &hpre->qm; + struct device *dev = &qm->pdev->dev; + struct debugfs_regset32 *regset; + + regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return -ENOMEM; + + regset->regs = hpre_com_dfx_regs; + regset->nregs = ARRAY_SIZE(hpre_com_dfx_regs); + regset->base = qm->io_base; + + debugfs_create_regset32("regs", 0444, debug->debug_root, regset); + return 0; +} + +static int hpre_cluster_debugfs_init(struct hpre_debug *debug) +{ + struct hpre *hpre = container_of(debug, struct hpre, debug); + struct hisi_qm *qm = &hpre->qm; + struct device *dev = &qm->pdev->dev; + char buf[HPRE_DBGFS_VAL_MAX_LEN]; + struct debugfs_regset32 *regset; + struct dentry *tmp_d; + int i, ret; + + for (i = 0; i < HPRE_CLUSTERS_NUM; i++) { + ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); + if (ret < 0) + return -EINVAL; + tmp_d = debugfs_create_dir(buf, debug->debug_root); + + regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return -ENOMEM; + + regset->regs = hpre_cluster_dfx_regs; + regset->nregs = ARRAY_SIZE(hpre_cluster_dfx_regs); + regset->base = qm->io_base + hpre_cluster_offsets[i]; + + debugfs_create_regset32("regs", 0444, tmp_d, regset); + ret = hpre_create_debugfs_file(debug, tmp_d, HPRE_CLUSTER_CTRL, + i + HPRE_CLUSTER_CTRL); + if (ret) + return ret; + } + + return 0; +} + +static int hpre_ctrl_debug_init(struct hpre_debug *debug) +{ + int ret; + + ret = hpre_create_debugfs_file(debug, NULL, HPRE_CURRENT_QM, + HPRE_CURRENT_QM); + if (ret) + return ret; + + ret = hpre_create_debugfs_file(debug, NULL, HPRE_CLEAR_ENABLE, + HPRE_CLEAR_ENABLE); + if (ret) + return ret; + + ret = hpre_pf_comm_regs_debugfs_init(debug); + if (ret) + return ret; + + return hpre_cluster_debugfs_init(debug); +} + +static int hpre_debugfs_init(struct hpre *hpre) +{ + struct hisi_qm *qm = &hpre->qm; + struct device *dev = &qm->pdev->dev; + struct dentry *dir; + int ret; + + dir = debugfs_create_dir(dev_name(dev), hpre_debugfs_root); + qm->debug.debug_root = dir; + + ret = hisi_qm_debug_init(qm); + if (ret) + goto failed_to_create; + + if (qm->pdev->device == HPRE_PCI_DEVICE_ID) { + hpre->debug.debug_root = dir; + ret = hpre_ctrl_debug_init(&hpre->debug); + if (ret) + goto failed_to_create; + } + return 0; + +failed_to_create: + debugfs_remove_recursive(qm->debug.debug_root); + return ret; +} + +static void hpre_debugfs_exit(struct hpre *hpre) +{ + struct hisi_qm *qm = &hpre->qm; + + debugfs_remove_recursive(qm->debug.debug_root); +} + +static int hpre_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev) +{ + enum qm_hw_ver rev_id; + + rev_id = hisi_qm_get_hw_version(pdev); + if (rev_id < 0) + return -ENODEV; + + if (rev_id == QM_HW_V1) { + pci_warn(pdev, "HPRE version 1 is not supported!\n"); + return -EINVAL; + } + + qm->pdev = pdev; + qm->ver = rev_id; + qm->sqe_size = HPRE_SQE_SIZE; + qm->dev_name = hpre_name; + qm->fun_type = (pdev->device == HPRE_PCI_DEVICE_ID) ? + QM_HW_PF : QM_HW_VF; + if (pdev->is_physfn) { + qm->qp_base = HPRE_PF_DEF_Q_BASE; + qm->qp_num = hpre_pf_q_num; + } + qm->use_dma_api = true; + + return 0; +} + +static const struct hisi_qm_err_ini hpre_err_ini = { + .hw_err_enable = hpre_hw_error_enable, + .hw_err_disable = hpre_hw_error_disable, + .err_info = { + .ce = QM_BASE_CE, + .nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT, + .fe = 0, + .msi = QM_DB_RANDOM_INVALID, + } +}; + +static int hpre_pf_probe_init(struct hpre *hpre) +{ + struct hisi_qm *qm = &hpre->qm; + int ret; + + qm->ctrl_qp_num = HPRE_QUEUE_NUM_V2; + + ret = hpre_set_user_domain_and_cache(hpre); + if (ret) + return ret; + + qm->err_ini = &hpre_err_ini; + hisi_qm_dev_err_init(qm); + + return 0; +} + +static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct hisi_qm *qm; + struct hpre *hpre; + int ret; + + hpre = devm_kzalloc(&pdev->dev, sizeof(*hpre), GFP_KERNEL); + if (!hpre) + return -ENOMEM; + + pci_set_drvdata(pdev, hpre); + + qm = &hpre->qm; + ret = hpre_qm_pre_init(qm, pdev); + if (ret) + return ret; + + ret = hisi_qm_init(qm); + if (ret) + return ret; + + if (pdev->is_physfn) { + ret = hpre_pf_probe_init(hpre); + if (ret) + goto err_with_qm_init; + } else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) { + /* v2 starts to support get vft by mailbox */ + ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num); + if (ret) + goto err_with_qm_init; + } + + ret = hisi_qm_start(qm); + if (ret) + goto err_with_err_init; + + ret = hpre_debugfs_init(hpre); + if (ret) + dev_warn(&pdev->dev, "init debugfs fail!\n"); + + hpre_add_to_list(hpre); + + ret = hpre_algs_register(); + if (ret < 0) { + hpre_remove_from_list(hpre); + pci_err(pdev, "fail to register algs to crypto!\n"); + goto err_with_qm_start; + } + return 0; + +err_with_qm_start: + hisi_qm_stop(qm); + +err_with_err_init: + hisi_qm_dev_err_uninit(qm); + +err_with_qm_init: + hisi_qm_uninit(qm); + + return ret; +} + +static int hpre_vf_q_assign(struct hpre *hpre, int num_vfs) +{ + struct hisi_qm *qm = &hpre->qm; + u32 qp_num = qm->qp_num; + int q_num, remain_q_num, i; + u32 q_base = qp_num; + int ret; + + if (!num_vfs) + return -EINVAL; + + remain_q_num = qm->ctrl_qp_num - qp_num; + + /* If remaining queues are not enough, return error. */ + if (remain_q_num < num_vfs) + return -EINVAL; + + q_num = remain_q_num / num_vfs; + for (i = 1; i <= num_vfs; i++) { + if (i == num_vfs) + q_num += remain_q_num % num_vfs; + ret = hisi_qm_set_vft(qm, i, q_base, (u32)q_num); + if (ret) + return ret; + q_base += q_num; + } + + return 0; +} + +static int hpre_clear_vft_config(struct hpre *hpre) +{ + struct hisi_qm *qm = &hpre->qm; + u32 num_vfs = hpre->num_vfs; + int ret; + u32 i; + + for (i = 1; i <= num_vfs; i++) { + ret = hisi_qm_set_vft(qm, i, 0, 0); + if (ret) + return ret; + } + hpre->num_vfs = 0; + + return 0; +} + +static int hpre_sriov_enable(struct pci_dev *pdev, int max_vfs) +{ + struct hpre *hpre = pci_get_drvdata(pdev); + int pre_existing_vfs, num_vfs, ret; + + pre_existing_vfs = pci_num_vf(pdev); + if (pre_existing_vfs) { + pci_err(pdev, + "Can't enable VF. Please disable pre-enabled VFs!\n"); + return 0; + } + + num_vfs = min_t(int, max_vfs, HPRE_VF_NUM); + ret = hpre_vf_q_assign(hpre, num_vfs); + if (ret) { + pci_err(pdev, "Can't assign queues for VF!\n"); + return ret; + } + + hpre->num_vfs = num_vfs; + + ret = pci_enable_sriov(pdev, num_vfs); + if (ret) { + pci_err(pdev, "Can't enable VF!\n"); + hpre_clear_vft_config(hpre); + return ret; + } + + return num_vfs; +} + +static int hpre_sriov_disable(struct pci_dev *pdev) +{ + struct hpre *hpre = pci_get_drvdata(pdev); + + if (pci_vfs_assigned(pdev)) { + pci_err(pdev, "Failed to disable VFs while VFs are assigned!\n"); + return -EPERM; + } + + /* remove in hpre_pci_driver will be called to free VF resources */ + pci_disable_sriov(pdev); + + return hpre_clear_vft_config(hpre); +} + +static int hpre_sriov_configure(struct pci_dev *pdev, int num_vfs) +{ + if (num_vfs) + return hpre_sriov_enable(pdev, num_vfs); + else + return hpre_sriov_disable(pdev); +} + +static void hpre_remove(struct pci_dev *pdev) +{ + struct hpre *hpre = pci_get_drvdata(pdev); + struct hisi_qm *qm = &hpre->qm; + int ret; + + hpre_algs_unregister(); + hpre_remove_from_list(hpre); + if (qm->fun_type == QM_HW_PF && hpre->num_vfs != 0) { + ret = hpre_sriov_disable(pdev); + if (ret) { + pci_err(pdev, "Disable SRIOV fail!\n"); + return; + } + } + if (qm->fun_type == QM_HW_PF) { + hpre_cnt_regs_clear(qm); + qm->debug.curr_qm_qp_num = 0; + } + + hpre_debugfs_exit(hpre); + hisi_qm_stop(qm); + hisi_qm_dev_err_uninit(qm); + hisi_qm_uninit(qm); +} + +static void hpre_log_hw_error(struct hpre *hpre, u32 err_sts) +{ + const struct hpre_hw_error *err = hpre_hw_errors; + struct device *dev = &hpre->qm.pdev->dev; + + while (err->msg) { + if (err->int_msk & err_sts) + dev_warn(dev, "%s [error status=0x%x] found\n", + err->msg, err->int_msk); + err++; + } +} + +static pci_ers_result_t hpre_hw_error_handle(struct hpre *hpre) +{ + u32 err_sts; + + /* read err sts */ + err_sts = readl(hpre->qm.io_base + HPRE_HAC_INT_STATUS); + if (err_sts) { + hpre_log_hw_error(hpre, err_sts); + + /* clear error interrupts */ + writel(err_sts, hpre->qm.io_base + HPRE_HAC_SOURCE_INT); + return PCI_ERS_RESULT_NEED_RESET; + } + + return PCI_ERS_RESULT_RECOVERED; +} + +static pci_ers_result_t hpre_process_hw_error(struct pci_dev *pdev) +{ + struct hpre *hpre = pci_get_drvdata(pdev); + pci_ers_result_t qm_ret, hpre_ret; + + /* log qm error */ + qm_ret = hisi_qm_hw_error_handle(&hpre->qm); + + /* log hpre error */ + hpre_ret = hpre_hw_error_handle(hpre); + + return (qm_ret == PCI_ERS_RESULT_NEED_RESET || + hpre_ret == PCI_ERS_RESULT_NEED_RESET) ? + PCI_ERS_RESULT_NEED_RESET : PCI_ERS_RESULT_RECOVERED; +} + +static pci_ers_result_t hpre_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + pci_info(pdev, "PCI error detected, state(=%d)!!\n", state); + if (state == pci_channel_io_perm_failure) + return PCI_ERS_RESULT_DISCONNECT; + + return hpre_process_hw_error(pdev); +} + +static const struct pci_error_handlers hpre_err_handler = { + .error_detected = hpre_error_detected, +}; + +static struct pci_driver hpre_pci_driver = { + .name = hpre_name, + .id_table = hpre_dev_ids, + .probe = hpre_probe, + .remove = hpre_remove, + .sriov_configure = hpre_sriov_configure, + .err_handler = &hpre_err_handler, +}; + +static void hpre_register_debugfs(void) +{ + if (!debugfs_initialized()) + return; + + hpre_debugfs_root = debugfs_create_dir(hpre_name, NULL); +} + +static void hpre_unregister_debugfs(void) +{ + debugfs_remove_recursive(hpre_debugfs_root); +} + +static int __init hpre_init(void) +{ + int ret; + + hpre_register_debugfs(); + + ret = pci_register_driver(&hpre_pci_driver); + if (ret) { + hpre_unregister_debugfs(); + pr_err("hpre: can't register hisi hpre driver.\n"); + } + + return ret; +} + +static void __exit hpre_exit(void) +{ + pci_unregister_driver(&hpre_pci_driver); + hpre_unregister_debugfs(); +} + +module_init(hpre_init); +module_exit(hpre_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Zaibo Xu "); +MODULE_DESCRIPTION("Driver for HiSilicon HPRE accelerator"); --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/qm.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/qm.c @@ -59,17 +59,17 @@ #define QM_CQ_PHASE_SHIFT 0 #define QM_CQ_FLAG_SHIFT 1 -#define QM_CQE_PHASE(cqe) ((cqe)->w7 & 0x1) +#define QM_CQE_PHASE(cqe) (le16_to_cpu((cqe)->w7) & 0x1) #define QM_QC_CQE_SIZE 4 /* eqc shift */ #define QM_EQE_AEQE_SIZE (2UL << 12) #define QM_EQC_PHASE_SHIFT 16 -#define QM_EQE_PHASE(eqe) (((eqe)->dw0 >> 16) & 0x1) +#define QM_EQE_PHASE(eqe) ((le32_to_cpu((eqe)->dw0) >> 16) & 0x1) #define QM_EQE_CQN_MASK GENMASK(15, 0) -#define QM_AEQE_PHASE(aeqe) (((aeqe)->dw0 >> 16) & 0x1) +#define QM_AEQE_PHASE(aeqe) ((le32_to_cpu((aeqe)->dw0) >> 16) & 0x1) #define QM_AEQE_TYPE_SHIFT 17 #define QM_DOORBELL_CMD_SQ 0 @@ -169,17 +169,17 @@ #define QM_MK_SQC_DW3_V2(sqe_sz) \ ((QM_Q_DEPTH - 1) | ((u32)ilog2(sqe_sz) << QM_SQ_SQE_SIZE_SHIFT)) -#define INIT_QC_COMMON(qc, base, pasid) do { \ - (qc)->head = 0; \ - (qc)->tail = 0; \ - (qc)->base_l = lower_32_bits(base); \ - (qc)->base_h = upper_32_bits(base); \ - (qc)->dw3 = 0; \ - (qc)->w8 = 0; \ - (qc)->rsvd0 = 0; \ - (qc)->pasid = pasid; \ - (qc)->w11 = 0; \ - (qc)->rsvd1 = 0; \ +#define INIT_QC_COMMON(qc, base, pasid) do { \ + (qc)->head = 0; \ + (qc)->tail = 0; \ + (qc)->base_l = cpu_to_le32(lower_32_bits(base)); \ + (qc)->base_h = cpu_to_le32(upper_32_bits(base)); \ + (qc)->dw3 = 0; \ + (qc)->w8 = 0; \ + (qc)->rsvd0 = 0; \ + (qc)->pasid = cpu_to_le16(pasid); \ + (qc)->w11 = 0; \ + (qc)->rsvd1 = 0; \ } while (0) enum vft_type { @@ -277,6 +277,7 @@ int (*debug_init)(struct hisi_qm *qm); void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe, u32 msi); + void (*hw_error_uninit)(struct hisi_qm *qm); pci_ers_result_t (*hw_error_handle)(struct hisi_qm *qm); }; @@ -331,12 +332,18 @@ void __iomem *fun_base = qm->io_base + QM_MB_CMD_SEND_BASE; unsigned long tmp0 = 0, tmp1 = 0; + if (!IS_ENABLED(CONFIG_ARM64)) { + memcpy_toio(fun_base, src, 16); + wmb(); + return; + } + asm volatile("ldp %0, %1, %3\n" "stp %0, %1, %2\n" "dsb sy\n" : "=&r" (tmp0), "=&r" (tmp1), - "+Q" (*((char *)fun_base)) + "+Q" (*((char __iomem *)fun_base)) : "Q" (*((char *)src)) : "memory"); } @@ -350,12 +357,12 @@ dev_dbg(&qm->pdev->dev, "QM mailbox request to q%u: %u-%llx\n", queue, cmd, (unsigned long long)dma_addr); - mailbox.w0 = cmd | + mailbox.w0 = cpu_to_le16(cmd | (op ? 0x1 << QM_MB_OP_SHIFT : 0) | - (0x1 << QM_MB_BUSY_SHIFT); - mailbox.queue_num = queue; - mailbox.base_l = lower_32_bits(dma_addr); - mailbox.base_h = upper_32_bits(dma_addr); + (0x1 << QM_MB_BUSY_SHIFT)); + mailbox.queue_num = cpu_to_le16(queue); + mailbox.base_l = cpu_to_le32(lower_32_bits(dma_addr)); + mailbox.base_h = cpu_to_le32(upper_32_bits(dma_addr)); mailbox.rsvd = 0; mutex_lock(&qm->mailbox_lock); @@ -442,7 +449,7 @@ static struct hisi_qp *qm_to_hisi_qp(struct hisi_qm *qm, struct qm_eqe *eqe) { - u16 cqn = eqe->dw0 & QM_EQE_CQN_MASK; + u16 cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK; return qm->qp_array[cqn]; } @@ -464,7 +471,8 @@ if (qp->req_cb) { while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { dma_rmb(); - qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); + qp->req_cb(qp, qp->sqe + qm->sqe_size * + le16_to_cpu(cqe->sq_head)); qm_cq_head_update(qp); cqe = qp->cqe + qp->qp_status.cq_head; qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, @@ -478,17 +486,9 @@ } } -static void qm_qp_work_func(struct work_struct *work) -{ - struct hisi_qp *qp; - - qp = container_of(work, struct hisi_qp, work); - qm_poll_qp(qp, qp->qm); -} - -static irqreturn_t qm_irq_handler(int irq, void *data) +static void qm_work_process(struct work_struct *work) { - struct hisi_qm *qm = data; + struct hisi_qm *qm = container_of(work, struct hisi_qm, work); struct qm_eqe *eqe = qm->eqe + qm->status.eq_head; struct hisi_qp *qp; int eqe_num = 0; @@ -497,7 +497,7 @@ eqe_num++; qp = qm_to_hisi_qp(qm, eqe); if (qp) - queue_work(qp->wq, &qp->work); + qm_poll_qp(qp, qm); if (qm->status.eq_head == QM_Q_DEPTH - 1) { qm->status.eqc_phase = !qm->status.eqc_phase; @@ -515,6 +515,17 @@ } qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); +} + +static irqreturn_t do_qm_irq(int irq, void *data) +{ + struct hisi_qm *qm = (struct hisi_qm *)data; + + /* the workqueue created by device driver of QM */ + if (qm->wq) + queue_work(qm->wq, &qm->work); + else + schedule_work(&qm->work); return IRQ_HANDLED; } @@ -524,7 +535,7 @@ struct hisi_qm *qm = data; if (readl(qm->io_base + QM_VF_EQ_INT_SOURCE)) - return qm_irq_handler(irq, data); + return do_qm_irq(irq, data); dev_err(&qm->pdev->dev, "invalid int source\n"); qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); @@ -542,7 +553,7 @@ return IRQ_NONE; while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) { - type = aeqe->dw0 >> QM_AEQE_TYPE_SHIFT; + type = le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT; if (type < ARRAY_SIZE(qm_fifo_overflow)) dev_err(&qm->pdev->dev, "%s overflow\n", qm_fifo_overflow[type]); @@ -646,7 +657,7 @@ qp_status->sq_tail = 0; qp_status->cq_head = 0; - qp_status->cqc_phase = 1; + qp_status->cqc_phase = true; qp_status->flags = 0; } @@ -963,13 +974,11 @@ static int qm_create_debugfs_file(struct hisi_qm *qm, enum qm_debug_file index) { - struct dentry *qm_d = qm->debug.qm_d, *tmp; + struct dentry *qm_d = qm->debug.qm_d; struct debugfs_file *file = qm->debug.files + index; - tmp = debugfs_create_file(qm_debug_file_name[index], 0600, qm_d, file, - &qm_debug_fops); - if (IS_ERR(tmp)) - return -ENOENT; + debugfs_create_file(qm_debug_file_name[index], 0600, qm_d, file, + &qm_debug_fops); file->index = index; mutex_init(&file->lock); @@ -981,9 +990,6 @@ static void qm_hw_error_init_v1(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe, u32 msi) { - dev_info(&qm->pdev->dev, - "QM v%d does not support hw error handle\n", qm->ver); - writel(QM_ABNORMAL_INT_MASK_VALUE, qm->io_base + QM_ABNORMAL_INT_MASK); } @@ -1009,6 +1015,11 @@ writel(irq_unmask, qm->io_base + QM_ABNORMAL_INT_MASK); } +static void qm_hw_error_uninit_v2(struct hisi_qm *qm) +{ + writel(QM_ABNORMAL_INT_MASK_VALUE, qm->io_base + QM_ABNORMAL_INT_MASK); +} + static void qm_log_hw_error(struct hisi_qm *qm, u32 error_status) { const struct hisi_qm_hw_error *err = qm_hw_error; @@ -1080,6 +1091,7 @@ .qm_db = qm_db_v2, .get_irq_num = qm_get_irq_num_v2, .hw_error_init = qm_hw_error_init_v2, + .hw_error_uninit = qm_hw_error_uninit_v2, .hw_error_handle = qm_hw_error_handle_v2, }; @@ -1123,6 +1135,7 @@ } set_bit(qp_id, qm->qp_bitmap); qm->qp_array[qp_id] = qp; + qm->qp_in_used++; write_unlock(&qm->qps_lock); @@ -1144,20 +1157,9 @@ qp->qp_id = qp_id; qp->alg_type = alg_type; - INIT_WORK(&qp->work, qm_qp_work_func); - qp->wq = alloc_workqueue("hisi_qm", WQ_UNBOUND | WQ_HIGHPRI | - WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 0); - if (!qp->wq) { - ret = -EFAULT; - goto err_free_qp_mem; - } return qp; -err_free_qp_mem: - if (qm->use_dma_api) - dma_free_coherent(dev, qp->qdma.size, qp->qdma.va, - qp->qdma.dma); err_clear_bit: write_lock(&qm->qps_lock); qm->qp_array[qp_id] = NULL; @@ -1187,6 +1189,7 @@ write_lock(&qm->qps_lock); qm->qp_array[qp->qp_id] = NULL; clear_bit(qp->qp_id, qm->qp_bitmap); + qm->qp_in_used--; write_unlock(&qm->qps_lock); kfree(qp); @@ -1218,14 +1221,14 @@ INIT_QC_COMMON(sqc, qp->sqe_dma, pasid); if (ver == QM_HW_V1) { - sqc->dw3 = QM_MK_SQC_DW3_V1(0, 0, 0, qm->sqe_size); - sqc->w8 = QM_Q_DEPTH - 1; + sqc->dw3 = cpu_to_le32(QM_MK_SQC_DW3_V1(0, 0, 0, qm->sqe_size)); + sqc->w8 = cpu_to_le16(QM_Q_DEPTH - 1); } else if (ver == QM_HW_V2) { - sqc->dw3 = QM_MK_SQC_DW3_V2(qm->sqe_size); + sqc->dw3 = cpu_to_le32(QM_MK_SQC_DW3_V2(qm->sqe_size)); sqc->w8 = 0; /* rand_qc */ } - sqc->cq_num = qp_id; - sqc->w13 = QM_MK_SQC_W13(0, 1, qp->alg_type); + sqc->cq_num = cpu_to_le16(qp_id); + sqc->w13 = cpu_to_le16(QM_MK_SQC_W13(0, 1, qp->alg_type)); ret = qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 0); dma_unmap_single(dev, sqc_dma, sizeof(struct qm_sqc), DMA_TO_DEVICE); @@ -1245,13 +1248,13 @@ INIT_QC_COMMON(cqc, qp->cqe_dma, pasid); if (ver == QM_HW_V1) { - cqc->dw3 = QM_MK_CQC_DW3_V1(0, 0, 0, 4); - cqc->w8 = QM_Q_DEPTH - 1; + cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0, 4)); + cqc->w8 = cpu_to_le16(QM_Q_DEPTH - 1); } else if (ver == QM_HW_V2) { - cqc->dw3 = QM_MK_CQC_DW3_V2(4); + cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(4)); cqc->w8 = 0; } - cqc->dw6 = 1 << QM_CQ_PHASE_SHIFT | 1 << QM_CQ_FLAG_SHIFT; + cqc->dw6 = cpu_to_le32(1 << QM_CQ_PHASE_SHIFT | 1 << QM_CQ_FLAG_SHIFT); ret = qm_mb(qm, QM_MB_CMD_CQC, cqc_dma, qp_id, 0); dma_unmap_single(dev, cqc_dma, sizeof(struct qm_cqc), DMA_TO_DEVICE); @@ -1392,6 +1395,24 @@ } /** + * hisi_qm_get_free_qp_num() - Get free number of qp in qm. + * @qm: The qm which want to get free qp. + * + * This function return free number of qp in qm. + */ +int hisi_qm_get_free_qp_num(struct hisi_qm *qm) +{ + int ret; + + read_lock(&qm->qps_lock); + ret = qm->qp_num - qm->qp_in_used; + read_unlock(&qm->qps_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(hisi_qm_get_free_qp_num); + +/** * hisi_qm_init() - Initialize configures about qm. * @qm: The qm needing init. * @@ -1454,8 +1475,10 @@ if (ret) goto err_free_irq_vectors; + qm->qp_in_used = 0; mutex_init(&qm->mailbox_lock); rwlock_init(&qm->qps_lock); + INIT_WORK(&qm->work, qm_work_process); dev_dbg(dev, "init qm %s with %s\n", pdev->is_physfn ? "pf" : "vf", qm->use_dma_api ? "dma api" : "iommu api"); @@ -1560,8 +1583,8 @@ status->eq_head = 0; status->aeq_head = 0; - status->eqc_phase = 1; - status->aeqc_phase = 1; + status->eqc_phase = true; + status->aeqc_phase = true; } static int qm_eq_ctx_cfg(struct hisi_qm *qm) @@ -1585,11 +1608,11 @@ return -ENOMEM; } - eqc->base_l = lower_32_bits(qm->eqe_dma); - eqc->base_h = upper_32_bits(qm->eqe_dma); + eqc->base_l = cpu_to_le32(lower_32_bits(qm->eqe_dma)); + eqc->base_h = cpu_to_le32(upper_32_bits(qm->eqe_dma)); if (qm->ver == QM_HW_V1) - eqc->dw3 = QM_EQE_AEQE_SIZE; - eqc->dw6 = (QM_Q_DEPTH - 1) | (1 << QM_EQC_PHASE_SHIFT); + eqc->dw3 = cpu_to_le32(QM_EQE_AEQE_SIZE); + eqc->dw6 = cpu_to_le32((QM_Q_DEPTH - 1) | (1 << QM_EQC_PHASE_SHIFT)); ret = qm_mb(qm, QM_MB_CMD_EQC, eqc_dma, 0, 0); dma_unmap_single(dev, eqc_dma, sizeof(struct qm_eqc), DMA_TO_DEVICE); kfree(eqc); @@ -1606,9 +1629,9 @@ return -ENOMEM; } - aeqc->base_l = lower_32_bits(qm->aeqe_dma); - aeqc->base_h = upper_32_bits(qm->aeqe_dma); - aeqc->dw6 = (QM_Q_DEPTH - 1) | (1 << QM_EQC_PHASE_SHIFT); + aeqc->base_l = cpu_to_le32(lower_32_bits(qm->aeqe_dma)); + aeqc->base_h = cpu_to_le32(upper_32_bits(qm->aeqe_dma)); + aeqc->dw6 = cpu_to_le32((QM_Q_DEPTH - 1) | (1 << QM_EQC_PHASE_SHIFT)); ret = qm_mb(qm, QM_MB_CMD_AEQC, aeqc_dma, 0, 0); dma_unmap_single(dev, aeqc_dma, sizeof(struct qm_aeqc), DMA_TO_DEVICE); @@ -1780,12 +1803,10 @@ */ int hisi_qm_debug_init(struct hisi_qm *qm) { - struct dentry *qm_d, *qm_regs; + struct dentry *qm_d; int i, ret; qm_d = debugfs_create_dir("qm", qm->debug.debug_root); - if (IS_ERR(qm_d)) - return -ENOENT; qm->debug.qm_d = qm_d; /* only show this in PF */ @@ -1796,12 +1817,7 @@ goto failed_to_create; } - qm_regs = debugfs_create_file("qm_regs", 0444, qm->debug.qm_d, qm, - &qm_regs_fops); - if (IS_ERR(qm_regs)) { - ret = -ENOENT; - goto failed_to_create; - } + debugfs_create_file("qm_regs", 0444, qm->debug.qm_d, qm, &qm_regs_fops); return 0; @@ -1840,36 +1856,28 @@ } EXPORT_SYMBOL_GPL(hisi_qm_debug_regs_clear); -/** - * hisi_qm_hw_error_init() - Configure qm hardware error report method. - * @qm: The qm which we want to configure. - * @ce: Bit mask of correctable error configure. - * @nfe: Bit mask of non-fatal error configure. - * @fe: Bit mask of fatal error configure. - * @msi: Bit mask of error reported by message signal interrupt. - * - * Hardware errors of qm can be reported either by RAS interrupts which will - * be handled by UEFI and then PCIe AER or by device MSI. User can configure - * each error to use either of above two methods. For RAS interrupts, we can - * configure an error as one of correctable error, non-fatal error or - * fatal error. - * - * Bits indicating errors can be configured to ce, nfe, fe and msi to enable - * related report methods. Error report will be masked if related error bit - * does not configure. - */ -void hisi_qm_hw_error_init(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe, - u32 msi) +static void qm_hw_error_init(struct hisi_qm *qm) { + const struct hisi_qm_err_info *err_info = &qm->err_ini->err_info; + if (!qm->ops->hw_error_init) { - dev_err(&qm->pdev->dev, "QM version %d doesn't support hw error handling!\n", - qm->ver); + dev_err(&qm->pdev->dev, "QM doesn't support hw error handling!\n"); + return; + } + + qm->ops->hw_error_init(qm, err_info->ce, err_info->nfe, + err_info->fe, err_info->msi); +} + +static void qm_hw_error_uninit(struct hisi_qm *qm) +{ + if (!qm->ops->hw_error_uninit) { + dev_err(&qm->pdev->dev, "Unexpected QM hw error uninit!\n"); return; } - qm->ops->hw_error_init(qm, ce, nfe, fe, msi); + qm->ops->hw_error_uninit(qm); } -EXPORT_SYMBOL_GPL(hisi_qm_hw_error_init); /** * hisi_qm_hw_error_handle() - Handle qm non-fatal hardware errors. @@ -1877,11 +1885,10 @@ * * Accelerators use this function to handle qm non-fatal hardware errors. */ -int hisi_qm_hw_error_handle(struct hisi_qm *qm) +pci_ers_result_t hisi_qm_hw_error_handle(struct hisi_qm *qm) { if (!qm->ops->hw_error_handle) { - dev_err(&qm->pdev->dev, "QM version %d doesn't support hw error report!\n", - qm->ver); + dev_err(&qm->pdev->dev, "QM doesn't support hw error report!\n"); return PCI_ERS_RESULT_NONE; } @@ -1908,6 +1915,48 @@ } EXPORT_SYMBOL_GPL(hisi_qm_get_hw_version); +/** + * hisi_qm_dev_err_init() - Initialize device error configuration. + * @qm: The qm for which we want to do error initialization. + * + * Initialize QM and device error related configuration. + */ +void hisi_qm_dev_err_init(struct hisi_qm *qm) +{ + if (qm->fun_type == QM_HW_VF) + return; + + qm_hw_error_init(qm); + + if (!qm->err_ini->hw_err_enable) { + dev_err(&qm->pdev->dev, "Device doesn't support hw error init!\n"); + return; + } + qm->err_ini->hw_err_enable(qm); +} +EXPORT_SYMBOL_GPL(hisi_qm_dev_err_init); + +/** + * hisi_qm_dev_err_uninit() - Uninitialize device error configuration. + * @qm: The qm for which we want to do error uninitialization. + * + * Uninitialize QM and device error related configuration. + */ +void hisi_qm_dev_err_uninit(struct hisi_qm *qm) +{ + if (qm->fun_type == QM_HW_VF) + return; + + qm_hw_error_uninit(qm); + + if (!qm->err_ini->hw_err_disable) { + dev_err(&qm->pdev->dev, "Unexpected device hw error uninit!\n"); + return; + } + qm->err_ini->hw_err_disable(qm); +} +EXPORT_SYMBOL_GPL(hisi_qm_dev_err_uninit); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Zhou Wang "); MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver"); --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/qm.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/qm.h @@ -40,6 +40,7 @@ #define QM_AXI_M_CFG 0x1000ac #define AXI_M_CFG 0xffff #define QM_AXI_M_CFG_ENABLE 0x1000b0 +#define AM_CFG_SINGLE_PORT_MAX_TRANS 0x300014 #define AXI_M_CFG_ENABLE 0xffffffff #define QM_PEH_AXUSER_CFG 0x1000cc #define QM_PEH_AXUSER_CFG_ENABLE 0x1000d0 @@ -75,6 +76,8 @@ #define QM_Q_DEPTH 1024 +#define HISI_ACC_SGL_SGE_NR_MAX 255 + enum qp_state { QP_STOP, }; @@ -123,6 +126,21 @@ unsigned long flags; }; +struct hisi_qm; + +struct hisi_qm_err_info { + u32 ce; + u32 nfe; + u32 fe; + u32 msi; +}; + +struct hisi_qm_err_ini { + void (*hw_err_enable)(struct hisi_qm *qm); + void (*hw_err_disable)(struct hisi_qm *qm); + struct hisi_qm_err_info err_info; +}; + struct hisi_qm { enum qm_hw_ver ver; enum qm_fun_type fun_type; @@ -132,6 +150,7 @@ u32 sqe_size; u32 qp_base; u32 qp_num; + u32 qp_in_used; u32 ctrl_qp_num; struct qm_dma qdma; @@ -145,6 +164,7 @@ dma_addr_t aeqe_dma; struct hisi_qm_status status; + const struct hisi_qm_err_ini *err_ini; rwlock_t qps_lock; unsigned long *qp_bitmap; @@ -159,6 +179,8 @@ u32 error_mask; u32 msi_mask; + struct workqueue_struct *wq; + struct work_struct work; bool use_dma_api; }; @@ -189,8 +211,6 @@ struct hisi_qp_ops *hw_ops; void *qp_ctx; void (*req_cb)(struct hisi_qp *qp, void *data); - struct work_struct work; - struct workqueue_struct *wq; struct hisi_qm *qm; }; @@ -204,12 +224,24 @@ int hisi_qm_stop_qp(struct hisi_qp *qp); void hisi_qm_release_qp(struct hisi_qp *qp); int hisi_qp_send(struct hisi_qp *qp, const void *msg); +int hisi_qm_get_free_qp_num(struct hisi_qm *qm); int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number); int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base, u32 number); int hisi_qm_debug_init(struct hisi_qm *qm); -void hisi_qm_hw_error_init(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe, - u32 msi); -int hisi_qm_hw_error_handle(struct hisi_qm *qm); +pci_ers_result_t hisi_qm_hw_error_handle(struct hisi_qm *qm); enum qm_hw_ver hisi_qm_get_hw_version(struct pci_dev *pdev); void hisi_qm_debug_regs_clear(struct hisi_qm *qm); +void hisi_qm_dev_err_init(struct hisi_qm *qm); +void hisi_qm_dev_err_uninit(struct hisi_qm *qm); + +struct hisi_acc_sgl_pool; +struct hisi_acc_hw_sgl *hisi_acc_sg_buf_map_to_hw_sgl(struct device *dev, + struct scatterlist *sgl, struct hisi_acc_sgl_pool *pool, + u32 index, dma_addr_t *hw_sgl_dma); +void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl, + struct hisi_acc_hw_sgl *hw_sgl); +struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, + u32 count, u32 sge_nr); +void hisi_acc_free_sgl_pool(struct device *dev, + struct hisi_acc_sgl_pool *pool); #endif --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec/sec_algs.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec/sec_algs.c @@ -175,7 +175,8 @@ dma_addr_t *psec_sgl, struct scatterlist *sgl, int count, - struct sec_dev_info *info) + struct sec_dev_info *info, + gfp_t gfp) { struct sec_hw_sgl *sgl_current = NULL; struct sec_hw_sgl *sgl_next; @@ -190,7 +191,7 @@ sge_index = i % SEC_MAX_SGE_NUM; if (sge_index == 0) { sgl_next = dma_pool_zalloc(info->hw_sgl_pool, - GFP_KERNEL, &sgl_next_dma); + gfp, &sgl_next_dma); if (!sgl_next) { ret = -ENOMEM; goto err_free_hw_sgls; @@ -448,7 +449,7 @@ */ } - mutex_lock(&ctx->queue->queuelock); + spin_lock_bh(&ctx->queue->queuelock); /* Put the IV in place for chained cases */ switch (ctx->cipher_alg) { case SEC_C_AES_CBC_128: @@ -508,7 +509,7 @@ list_del(&backlog_req->backlog_head); } } - mutex_unlock(&ctx->queue->queuelock); + spin_unlock_bh(&ctx->queue->queuelock); mutex_lock(&sec_req->lock); list_del(&sec_req_el->head); @@ -545,14 +546,14 @@ } static int sec_alg_alloc_and_calc_split_sizes(int length, size_t **split_sizes, - int *steps) + int *steps, gfp_t gfp) { size_t *sizes; int i; /* Split into suitable sized blocks */ *steps = roundup(length, SEC_REQ_LIMIT) / SEC_REQ_LIMIT; - sizes = kcalloc(*steps, sizeof(*sizes), GFP_KERNEL); + sizes = kcalloc(*steps, sizeof(*sizes), gfp); if (!sizes) return -ENOMEM; @@ -568,7 +569,7 @@ int steps, struct scatterlist ***splits, int **splits_nents, int sgl_len_in, - struct device *dev) + struct device *dev, gfp_t gfp) { int ret, count; @@ -576,12 +577,12 @@ if (!count) return -EINVAL; - *splits = kcalloc(steps, sizeof(struct scatterlist *), GFP_KERNEL); + *splits = kcalloc(steps, sizeof(struct scatterlist *), gfp); if (!*splits) { ret = -ENOMEM; goto err_unmap_sg; } - *splits_nents = kcalloc(steps, sizeof(int), GFP_KERNEL); + *splits_nents = kcalloc(steps, sizeof(int), gfp); if (!*splits_nents) { ret = -ENOMEM; goto err_free_splits; @@ -589,7 +590,7 @@ /* output the scatter list before and after this */ ret = sg_split(sgl, count, 0, steps, split_sizes, - *splits, *splits_nents, GFP_KERNEL); + *splits, *splits_nents, gfp); if (ret) { ret = -ENOMEM; goto err_free_splits_nents; @@ -630,13 +631,13 @@ int el_size, bool different_dest, struct scatterlist *sgl_in, int n_ents_in, struct scatterlist *sgl_out, int n_ents_out, - struct sec_dev_info *info) + struct sec_dev_info *info, gfp_t gfp) { struct sec_request_el *el; struct sec_bd_info *req; int ret; - el = kzalloc(sizeof(*el), GFP_KERNEL); + el = kzalloc(sizeof(*el), gfp); if (!el) return ERR_PTR(-ENOMEM); el->el_length = el_size; @@ -668,7 +669,7 @@ el->sgl_in = sgl_in; ret = sec_alloc_and_fill_hw_sgl(&el->in, &el->dma_in, el->sgl_in, - n_ents_in, info); + n_ents_in, info, gfp); if (ret) goto err_free_el; @@ -679,7 +680,7 @@ el->sgl_out = sgl_out; ret = sec_alloc_and_fill_hw_sgl(&el->out, &el->dma_out, el->sgl_out, - n_ents_out, info); + n_ents_out, info, gfp); if (ret) goto err_free_hw_sgl_in; @@ -720,6 +721,7 @@ int *splits_out_nents = NULL; struct sec_request_el *el, *temp; bool split = skreq->src != skreq->dst; + gfp_t gfp = skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; mutex_init(&sec_req->lock); sec_req->req_base = &skreq->base; @@ -728,13 +730,13 @@ sec_req->len_in = sg_nents(skreq->src); ret = sec_alg_alloc_and_calc_split_sizes(skreq->cryptlen, &split_sizes, - &steps); + &steps, gfp); if (ret) return ret; sec_req->num_elements = steps; ret = sec_map_and_split_sg(skreq->src, split_sizes, steps, &splits_in, &splits_in_nents, sec_req->len_in, - info->dev); + info->dev, gfp); if (ret) goto err_free_split_sizes; @@ -742,7 +744,7 @@ sec_req->len_out = sg_nents(skreq->dst); ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps, &splits_out, &splits_out_nents, - sec_req->len_out, info->dev); + sec_req->len_out, info->dev, gfp); if (ret) goto err_unmap_in_sg; } @@ -775,7 +777,7 @@ splits_in[i], splits_in_nents[i], split ? splits_out[i] : NULL, split ? splits_out_nents[i] : 0, - info); + info, gfp); if (IS_ERR(el)) { ret = PTR_ERR(el); goto err_free_elements; @@ -796,7 +798,7 @@ */ /* Grab a big lock for a long time to avoid concurrency issues */ - mutex_lock(&queue->queuelock); + spin_lock_bh(&queue->queuelock); /* * Can go on to queue if we have space in either: @@ -812,15 +814,15 @@ ret = -EBUSY; if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { list_add_tail(&sec_req->backlog_head, &ctx->backlog); - mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); goto out; } - mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); goto err_free_elements; } ret = sec_send_request(sec_req, queue); - mutex_unlock(&queue->queuelock); + spin_unlock_bh(&queue->queuelock); if (ret) goto err_free_elements; @@ -879,7 +881,7 @@ if (IS_ERR(ctx->queue)) return PTR_ERR(ctx->queue); - mutex_init(&ctx->queue->queuelock); + spin_lock_init(&ctx->queue->queuelock); ctx->queue->havesoftqueue = false; return 0; --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec/sec_drv.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec/sec_drv.h @@ -347,7 +347,7 @@ DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN); DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *)); bool havesoftqueue; - struct mutex queuelock; + spinlock_t queuelock; void *shadow[SEC_QUEUE_LEN]; }; --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec2/Makefile +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec2/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += hisi_sec2.o +hisi_sec2-objs = sec_main.o sec_crypto.o --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec2/sec.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec2/sec.h @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019 HiSilicon Limited. */ + +#ifndef __HISI_SEC_V2_H +#define __HISI_SEC_V2_H + +#include + +#include "../qm.h" +#include "sec_crypto.h" + +/* Algorithm resource per hardware SEC queue */ +struct sec_alg_res { + u8 *c_ivin; + dma_addr_t c_ivin_dma; + u8 *out_mac; + dma_addr_t out_mac_dma; +}; + +/* Cipher request of SEC private */ +struct sec_cipher_req { + struct hisi_acc_hw_sgl *c_in; + dma_addr_t c_in_dma; + struct hisi_acc_hw_sgl *c_out; + dma_addr_t c_out_dma; + struct skcipher_request *sk_req; + u32 c_len; + bool encrypt; +}; + +struct sec_aead_req { + u8 *out_mac; + dma_addr_t out_mac_dma; + struct aead_request *aead_req; +}; + +/* SEC request of Crypto */ +struct sec_req { + struct sec_sqe sec_sqe; + struct sec_ctx *ctx; + struct sec_qp_ctx *qp_ctx; + + struct sec_cipher_req c_req; + struct sec_aead_req aead_req; + + int err_type; + int req_id; + + /* Status of the SEC request */ + bool fake_busy; +}; + +/** + * struct sec_req_op - Operations for SEC request + * @buf_map: DMA map the SGL buffers of the request + * @buf_unmap: DMA unmap the SGL buffers of the request + * @bd_fill: Fill the SEC queue BD + * @bd_send: Send the SEC BD into the hardware queue + * @callback: Call back for the request + * @process: Main processing logic of Skcipher + */ +struct sec_req_op { + int (*buf_map)(struct sec_ctx *ctx, struct sec_req *req); + void (*buf_unmap)(struct sec_ctx *ctx, struct sec_req *req); + void (*do_transfer)(struct sec_ctx *ctx, struct sec_req *req); + int (*bd_fill)(struct sec_ctx *ctx, struct sec_req *req); + int (*bd_send)(struct sec_ctx *ctx, struct sec_req *req); + void (*callback)(struct sec_ctx *ctx, struct sec_req *req, int err); + int (*process)(struct sec_ctx *ctx, struct sec_req *req); +}; + +/* SEC auth context */ +struct sec_auth_ctx { + dma_addr_t a_key_dma; + u8 *a_key; + u8 a_key_len; + u8 mac_len; + u8 a_alg; + struct crypto_shash *hash_tfm; +}; + +/* SEC cipher context which cipher's relatives */ +struct sec_cipher_ctx { + u8 *c_key; + dma_addr_t c_key_dma; + sector_t iv_offset; + u32 c_gran_size; + u32 ivsize; + u8 c_mode; + u8 c_alg; + u8 c_key_len; +}; + +/* SEC queue context which defines queue's relatives */ +struct sec_qp_ctx { + struct hisi_qp *qp; + struct sec_req *req_list[QM_Q_DEPTH]; + struct idr req_idr; + struct sec_alg_res res[QM_Q_DEPTH]; + struct sec_ctx *ctx; + struct mutex req_lock; + struct hisi_acc_sgl_pool *c_in_pool; + struct hisi_acc_sgl_pool *c_out_pool; + atomic_t pending_reqs; +}; + +enum sec_alg_type { + SEC_SKCIPHER, + SEC_AEAD +}; + +/* SEC Crypto TFM context which defines queue and cipher .etc relatives */ +struct sec_ctx { + struct sec_qp_ctx *qp_ctx; + struct sec_dev *sec; + const struct sec_req_op *req_op; + + /* Half queues for encipher, and half for decipher */ + u32 hlf_q_num; + + /* Threshold for fake busy, trigger to return -EBUSY to user */ + u32 fake_req_limit; + + /* Currrent cyclic index to select a queue for encipher */ + atomic_t enc_qcyclic; + + /* Currrent cyclic index to select a queue for decipher */ + atomic_t dec_qcyclic; + + enum sec_alg_type alg_type; + struct sec_cipher_ctx c_ctx; + struct sec_auth_ctx a_ctx; +}; + +enum sec_endian { + SEC_LE = 0, + SEC_32BE, + SEC_64BE +}; + +enum sec_debug_file_index { + SEC_CURRENT_QM, + SEC_CLEAR_ENABLE, + SEC_DEBUG_FILE_NUM, +}; + +struct sec_debug_file { + enum sec_debug_file_index index; + spinlock_t lock; + struct hisi_qm *qm; +}; + +struct sec_dfx { + atomic64_t send_cnt; + atomic64_t recv_cnt; +}; + +struct sec_debug { + struct sec_dfx dfx; + struct sec_debug_file files[SEC_DEBUG_FILE_NUM]; +}; + +struct sec_dev { + struct hisi_qm qm; + struct list_head list; + struct sec_debug debug; + u32 ctx_q_num; + u32 num_vfs; + unsigned long status; +}; + +struct sec_dev *sec_find_device(int node); +int sec_register_to_crypto(void); +void sec_unregister_from_crypto(void); +#endif --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -0,0 +1,1446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 HiSilicon Limited. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sec.h" +#include "sec_crypto.h" + +#define SEC_PRIORITY 4001 +#define SEC_XTS_MIN_KEY_SIZE (2 * AES_MIN_KEY_SIZE) +#define SEC_XTS_MAX_KEY_SIZE (2 * AES_MAX_KEY_SIZE) +#define SEC_DES3_2KEY_SIZE (2 * DES_KEY_SIZE) +#define SEC_DES3_3KEY_SIZE (3 * DES_KEY_SIZE) + +/* SEC sqe(bd) bit operational relative MACRO */ +#define SEC_DE_OFFSET 1 +#define SEC_CIPHER_OFFSET 4 +#define SEC_SCENE_OFFSET 3 +#define SEC_DST_SGL_OFFSET 2 +#define SEC_SRC_SGL_OFFSET 7 +#define SEC_CKEY_OFFSET 9 +#define SEC_CMODE_OFFSET 12 +#define SEC_AKEY_OFFSET 5 +#define SEC_AEAD_ALG_OFFSET 11 +#define SEC_AUTH_OFFSET 6 + +#define SEC_FLAG_OFFSET 7 +#define SEC_FLAG_MASK 0x0780 +#define SEC_TYPE_MASK 0x0F +#define SEC_DONE_MASK 0x0001 + +#define SEC_TOTAL_IV_SZ (SEC_IV_SIZE * QM_Q_DEPTH) +#define SEC_SGL_SGE_NR 128 +#define SEC_CTX_DEV(ctx) (&(ctx)->sec->qm.pdev->dev) +#define SEC_CIPHER_AUTH 0xfe +#define SEC_AUTH_CIPHER 0x1 +#define SEC_MAX_MAC_LEN 64 +#define SEC_TOTAL_MAC_SZ (SEC_MAX_MAC_LEN * QM_Q_DEPTH) +#define SEC_SQE_LEN_RATE 4 +#define SEC_SQE_CFLAG 2 +#define SEC_SQE_AEAD_FLAG 3 +#define SEC_SQE_DONE 0x1 + +static atomic_t sec_active_devs; + +/* Get an en/de-cipher queue cyclically to balance load over queues of TFM */ +static inline int sec_alloc_queue_id(struct sec_ctx *ctx, struct sec_req *req) +{ + if (req->c_req.encrypt) + return (u32)atomic_inc_return(&ctx->enc_qcyclic) % + ctx->hlf_q_num; + + return (u32)atomic_inc_return(&ctx->dec_qcyclic) % ctx->hlf_q_num + + ctx->hlf_q_num; +} + +static inline void sec_free_queue_id(struct sec_ctx *ctx, struct sec_req *req) +{ + if (req->c_req.encrypt) + atomic_dec(&ctx->enc_qcyclic); + else + atomic_dec(&ctx->dec_qcyclic); +} + +static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx) +{ + int req_id; + + mutex_lock(&qp_ctx->req_lock); + + req_id = idr_alloc_cyclic(&qp_ctx->req_idr, NULL, + 0, QM_Q_DEPTH, GFP_ATOMIC); + mutex_unlock(&qp_ctx->req_lock); + if (unlikely(req_id < 0)) { + dev_err(SEC_CTX_DEV(req->ctx), "alloc req id fail!\n"); + return req_id; + } + + req->qp_ctx = qp_ctx; + qp_ctx->req_list[req_id] = req; + return req_id; +} + +static void sec_free_req_id(struct sec_req *req) +{ + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + int req_id = req->req_id; + + if (unlikely(req_id < 0 || req_id >= QM_Q_DEPTH)) { + dev_err(SEC_CTX_DEV(req->ctx), "free request id invalid!\n"); + return; + } + + qp_ctx->req_list[req_id] = NULL; + req->qp_ctx = NULL; + + mutex_lock(&qp_ctx->req_lock); + idr_remove(&qp_ctx->req_idr, req_id); + mutex_unlock(&qp_ctx->req_lock); +} + +static int sec_aead_verify(struct sec_req *req, struct sec_qp_ctx *qp_ctx) +{ + struct aead_request *aead_req = req->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req); + u8 *mac_out = qp_ctx->res[req->req_id].out_mac; + size_t authsize = crypto_aead_authsize(tfm); + u8 *mac = mac_out + SEC_MAX_MAC_LEN; + struct scatterlist *sgl = aead_req->src; + size_t sz; + + sz = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac, authsize, + aead_req->cryptlen + aead_req->assoclen - + authsize); + if (unlikely(sz != authsize || memcmp(mac_out, mac, sz))) { + dev_err(SEC_CTX_DEV(req->ctx), "aead verify failure!\n"); + return -EBADMSG; + } + + return 0; +} + +static void sec_req_cb(struct hisi_qp *qp, void *resp) +{ + struct sec_qp_ctx *qp_ctx = qp->qp_ctx; + struct sec_sqe *bd = resp; + struct sec_ctx *ctx; + struct sec_req *req; + u16 done, flag; + int err = 0; + u8 type; + + type = bd->type_cipher_auth & SEC_TYPE_MASK; + if (unlikely(type != SEC_BD_TYPE2)) { + pr_err("err bd type [%d]\n", type); + return; + } + + req = qp_ctx->req_list[le16_to_cpu(bd->type2.tag)]; + req->err_type = bd->type2.error_type; + ctx = req->ctx; + done = le16_to_cpu(bd->type2.done_flag) & SEC_DONE_MASK; + flag = (le16_to_cpu(bd->type2.done_flag) & + SEC_FLAG_MASK) >> SEC_FLAG_OFFSET; + if (unlikely(req->err_type || done != SEC_SQE_DONE || + (ctx->alg_type == SEC_SKCIPHER && flag != SEC_SQE_CFLAG) || + (ctx->alg_type == SEC_AEAD && flag != SEC_SQE_AEAD_FLAG))) { + dev_err(SEC_CTX_DEV(ctx), + "err_type[%d],done[%d],flag[%d]\n", + req->err_type, done, flag); + err = -EIO; + } + + if (ctx->alg_type == SEC_AEAD && !req->c_req.encrypt) + err = sec_aead_verify(req, qp_ctx); + + atomic64_inc(&ctx->sec->debug.dfx.recv_cnt); + + ctx->req_op->buf_unmap(ctx, req); + + ctx->req_op->callback(ctx, req, err); +} + +static int sec_bd_send(struct sec_ctx *ctx, struct sec_req *req) +{ + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + int ret; + + mutex_lock(&qp_ctx->req_lock); + ret = hisi_qp_send(qp_ctx->qp, &req->sec_sqe); + mutex_unlock(&qp_ctx->req_lock); + atomic64_inc(&ctx->sec->debug.dfx.send_cnt); + + if (unlikely(ret == -EBUSY)) + return -ENOBUFS; + + if (!ret) { + if (req->fake_busy) + ret = -EBUSY; + else + ret = -EINPROGRESS; + } + + return ret; +} + +/* Get DMA memory resources */ +static int sec_alloc_civ_resource(struct device *dev, struct sec_alg_res *res) +{ + int i; + + res->c_ivin = dma_alloc_coherent(dev, SEC_TOTAL_IV_SZ, + &res->c_ivin_dma, GFP_KERNEL); + if (!res->c_ivin) + return -ENOMEM; + + for (i = 1; i < QM_Q_DEPTH; i++) { + res[i].c_ivin_dma = res->c_ivin_dma + i * SEC_IV_SIZE; + res[i].c_ivin = res->c_ivin + i * SEC_IV_SIZE; + } + + return 0; +} + +static void sec_free_civ_resource(struct device *dev, struct sec_alg_res *res) +{ + if (res->c_ivin) + dma_free_coherent(dev, SEC_TOTAL_IV_SZ, + res->c_ivin, res->c_ivin_dma); +} + +static int sec_alloc_mac_resource(struct device *dev, struct sec_alg_res *res) +{ + int i; + + res->out_mac = dma_alloc_coherent(dev, SEC_TOTAL_MAC_SZ << 1, + &res->out_mac_dma, GFP_KERNEL); + if (!res->out_mac) + return -ENOMEM; + + for (i = 1; i < QM_Q_DEPTH; i++) { + res[i].out_mac_dma = res->out_mac_dma + + i * (SEC_MAX_MAC_LEN << 1); + res[i].out_mac = res->out_mac + i * (SEC_MAX_MAC_LEN << 1); + } + + return 0; +} + +static void sec_free_mac_resource(struct device *dev, struct sec_alg_res *res) +{ + if (res->out_mac) + dma_free_coherent(dev, SEC_TOTAL_MAC_SZ << 1, + res->out_mac, res->out_mac_dma); +} + +static int sec_alg_resource_alloc(struct sec_ctx *ctx, + struct sec_qp_ctx *qp_ctx) +{ + struct device *dev = SEC_CTX_DEV(ctx); + struct sec_alg_res *res = qp_ctx->res; + int ret; + + ret = sec_alloc_civ_resource(dev, res); + if (ret) + return ret; + + if (ctx->alg_type == SEC_AEAD) { + ret = sec_alloc_mac_resource(dev, res); + if (ret) + goto get_fail; + } + + return 0; +get_fail: + sec_free_civ_resource(dev, res); + + return ret; +} + +static void sec_alg_resource_free(struct sec_ctx *ctx, + struct sec_qp_ctx *qp_ctx) +{ + struct device *dev = SEC_CTX_DEV(ctx); + + sec_free_civ_resource(dev, qp_ctx->res); + + if (ctx->alg_type == SEC_AEAD) + sec_free_mac_resource(dev, qp_ctx->res); +} + +static int sec_create_qp_ctx(struct hisi_qm *qm, struct sec_ctx *ctx, + int qp_ctx_id, int alg_type) +{ + struct device *dev = SEC_CTX_DEV(ctx); + struct sec_qp_ctx *qp_ctx; + struct hisi_qp *qp; + int ret = -ENOMEM; + + qp = hisi_qm_create_qp(qm, alg_type); + if (IS_ERR(qp)) + return PTR_ERR(qp); + + qp_ctx = &ctx->qp_ctx[qp_ctx_id]; + qp->req_type = 0; + qp->qp_ctx = qp_ctx; + qp->req_cb = sec_req_cb; + qp_ctx->qp = qp; + qp_ctx->ctx = ctx; + + mutex_init(&qp_ctx->req_lock); + atomic_set(&qp_ctx->pending_reqs, 0); + idr_init(&qp_ctx->req_idr); + + qp_ctx->c_in_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH, + SEC_SGL_SGE_NR); + if (IS_ERR(qp_ctx->c_in_pool)) { + dev_err(dev, "fail to create sgl pool for input!\n"); + goto err_destroy_idr; + } + + qp_ctx->c_out_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH, + SEC_SGL_SGE_NR); + if (IS_ERR(qp_ctx->c_out_pool)) { + dev_err(dev, "fail to create sgl pool for output!\n"); + goto err_free_c_in_pool; + } + + ret = sec_alg_resource_alloc(ctx, qp_ctx); + if (ret) + goto err_free_c_out_pool; + + ret = hisi_qm_start_qp(qp, 0); + if (ret < 0) + goto err_queue_free; + + return 0; + +err_queue_free: + sec_alg_resource_free(ctx, qp_ctx); +err_free_c_out_pool: + hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool); +err_free_c_in_pool: + hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool); +err_destroy_idr: + idr_destroy(&qp_ctx->req_idr); + hisi_qm_release_qp(qp); + + return ret; +} + +static void sec_release_qp_ctx(struct sec_ctx *ctx, + struct sec_qp_ctx *qp_ctx) +{ + struct device *dev = SEC_CTX_DEV(ctx); + + hisi_qm_stop_qp(qp_ctx->qp); + sec_alg_resource_free(ctx, qp_ctx); + + hisi_acc_free_sgl_pool(dev, qp_ctx->c_out_pool); + hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool); + + idr_destroy(&qp_ctx->req_idr); + hisi_qm_release_qp(qp_ctx->qp); +} + +static int sec_ctx_base_init(struct sec_ctx *ctx) +{ + struct sec_dev *sec; + int i, ret; + + sec = sec_find_device(cpu_to_node(smp_processor_id())); + if (!sec) { + pr_err("Can not find proper Hisilicon SEC device!\n"); + return -ENODEV; + } + ctx->sec = sec; + ctx->hlf_q_num = sec->ctx_q_num >> 1; + + /* Half of queue depth is taken as fake requests limit in the queue. */ + ctx->fake_req_limit = QM_Q_DEPTH >> 1; + ctx->qp_ctx = kcalloc(sec->ctx_q_num, sizeof(struct sec_qp_ctx), + GFP_KERNEL); + if (!ctx->qp_ctx) + return -ENOMEM; + + for (i = 0; i < sec->ctx_q_num; i++) { + ret = sec_create_qp_ctx(&sec->qm, ctx, i, 0); + if (ret) + goto err_sec_release_qp_ctx; + } + + return 0; +err_sec_release_qp_ctx: + for (i = i - 1; i >= 0; i--) + sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]); + + kfree(ctx->qp_ctx); + return ret; +} + +static void sec_ctx_base_uninit(struct sec_ctx *ctx) +{ + int i; + + for (i = 0; i < ctx->sec->ctx_q_num; i++) + sec_release_qp_ctx(ctx, &ctx->qp_ctx[i]); + + kfree(ctx->qp_ctx); +} + +static int sec_cipher_init(struct sec_ctx *ctx) +{ + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + + c_ctx->c_key = dma_alloc_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE, + &c_ctx->c_key_dma, GFP_KERNEL); + if (!c_ctx->c_key) + return -ENOMEM; + + return 0; +} + +static void sec_cipher_uninit(struct sec_ctx *ctx) +{ + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + + memzero_explicit(c_ctx->c_key, SEC_MAX_KEY_SIZE); + dma_free_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE, + c_ctx->c_key, c_ctx->c_key_dma); +} + +static int sec_auth_init(struct sec_ctx *ctx) +{ + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; + + a_ctx->a_key = dma_alloc_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE, + &a_ctx->a_key_dma, GFP_KERNEL); + if (!a_ctx->a_key) + return -ENOMEM; + + return 0; +} + +static void sec_auth_uninit(struct sec_ctx *ctx) +{ + struct sec_auth_ctx *a_ctx = &ctx->a_ctx; + + memzero_explicit(a_ctx->a_key, SEC_MAX_KEY_SIZE); + dma_free_coherent(SEC_CTX_DEV(ctx), SEC_MAX_KEY_SIZE, + a_ctx->a_key, a_ctx->a_key_dma); +} + +static int sec_skcipher_init(struct crypto_skcipher *tfm) +{ + struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); + int ret; + + ctx = crypto_skcipher_ctx(tfm); + ctx->alg_type = SEC_SKCIPHER; + crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_req)); + ctx->c_ctx.ivsize = crypto_skcipher_ivsize(tfm); + if (ctx->c_ctx.ivsize > SEC_IV_SIZE) { + dev_err(SEC_CTX_DEV(ctx), "get error skcipher iv size!\n"); + return -EINVAL; + } + + ret = sec_ctx_base_init(ctx); + if (ret) + return ret; + + ret = sec_cipher_init(ctx); + if (ret) + goto err_cipher_init; + + return 0; +err_cipher_init: + sec_ctx_base_uninit(ctx); + + return ret; +} + +static void sec_skcipher_uninit(struct crypto_skcipher *tfm) +{ + struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); + + sec_cipher_uninit(ctx); + sec_ctx_base_uninit(ctx); +} + +static int sec_skcipher_3des_setkey(struct sec_cipher_ctx *c_ctx, + const u32 keylen, + const enum sec_cmode c_mode) +{ + switch (keylen) { + case SEC_DES3_2KEY_SIZE: + c_ctx->c_key_len = SEC_CKEY_3DES_2KEY; + break; + case SEC_DES3_3KEY_SIZE: + c_ctx->c_key_len = SEC_CKEY_3DES_3KEY; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int sec_skcipher_aes_sm4_setkey(struct sec_cipher_ctx *c_ctx, + const u32 keylen, + const enum sec_cmode c_mode) +{ + if (c_mode == SEC_CMODE_XTS) { + switch (keylen) { + case SEC_XTS_MIN_KEY_SIZE: + c_ctx->c_key_len = SEC_CKEY_128BIT; + break; + case SEC_XTS_MAX_KEY_SIZE: + c_ctx->c_key_len = SEC_CKEY_256BIT; + break; + default: + pr_err("hisi_sec2: xts mode key error!\n"); + return -EINVAL; + } + } else { + switch (keylen) { + case AES_KEYSIZE_128: + c_ctx->c_key_len = SEC_CKEY_128BIT; + break; + case AES_KEYSIZE_192: + c_ctx->c_key_len = SEC_CKEY_192BIT; + break; + case AES_KEYSIZE_256: + c_ctx->c_key_len = SEC_CKEY_256BIT; + break; + default: + pr_err("hisi_sec2: aes key error!\n"); + return -EINVAL; + } + } + + return 0; +} + +static int sec_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, + const u32 keylen, const enum sec_calg c_alg, + const enum sec_cmode c_mode) +{ + struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + int ret; + + if (c_mode == SEC_CMODE_XTS) { + ret = xts_verify_key(tfm, key, keylen); + if (ret) { + dev_err(SEC_CTX_DEV(ctx), "xts mode key err!\n"); + return ret; + } + } + + c_ctx->c_alg = c_alg; + c_ctx->c_mode = c_mode; + + switch (c_alg) { + case SEC_CALG_3DES: + ret = sec_skcipher_3des_setkey(c_ctx, keylen, c_mode); + break; + case SEC_CALG_AES: + case SEC_CALG_SM4: + ret = sec_skcipher_aes_sm4_setkey(c_ctx, keylen, c_mode); + break; + default: + return -EINVAL; + } + + if (ret) { + dev_err(SEC_CTX_DEV(ctx), "set sec key err!\n"); + return ret; + } + + memcpy(c_ctx->c_key, key, keylen); + + return 0; +} + +#define GEN_SEC_SETKEY_FUNC(name, c_alg, c_mode) \ +static int sec_setkey_##name(struct crypto_skcipher *tfm, const u8 *key,\ + u32 keylen) \ +{ \ + return sec_skcipher_setkey(tfm, key, keylen, c_alg, c_mode); \ +} + +GEN_SEC_SETKEY_FUNC(aes_ecb, SEC_CALG_AES, SEC_CMODE_ECB) +GEN_SEC_SETKEY_FUNC(aes_cbc, SEC_CALG_AES, SEC_CMODE_CBC) +GEN_SEC_SETKEY_FUNC(aes_xts, SEC_CALG_AES, SEC_CMODE_XTS) + +GEN_SEC_SETKEY_FUNC(3des_ecb, SEC_CALG_3DES, SEC_CMODE_ECB) +GEN_SEC_SETKEY_FUNC(3des_cbc, SEC_CALG_3DES, SEC_CMODE_CBC) + +GEN_SEC_SETKEY_FUNC(sm4_xts, SEC_CALG_SM4, SEC_CMODE_XTS) +GEN_SEC_SETKEY_FUNC(sm4_cbc, SEC_CALG_SM4, SEC_CMODE_CBC) + +static int sec_cipher_map(struct device *dev, struct sec_req *req, + struct scatterlist *src, struct scatterlist *dst) +{ + struct sec_cipher_req *c_req = &req->c_req; + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + + c_req->c_in = hisi_acc_sg_buf_map_to_hw_sgl(dev, src, + qp_ctx->c_in_pool, + req->req_id, + &c_req->c_in_dma); + + if (IS_ERR(c_req->c_in)) { + dev_err(dev, "fail to dma map input sgl buffers!\n"); + return PTR_ERR(c_req->c_in); + } + + if (dst == src) { + c_req->c_out = c_req->c_in; + c_req->c_out_dma = c_req->c_in_dma; + } else { + c_req->c_out = hisi_acc_sg_buf_map_to_hw_sgl(dev, dst, + qp_ctx->c_out_pool, + req->req_id, + &c_req->c_out_dma); + + if (IS_ERR(c_req->c_out)) { + dev_err(dev, "fail to dma map output sgl buffers!\n"); + hisi_acc_sg_buf_unmap(dev, src, c_req->c_in); + return PTR_ERR(c_req->c_out); + } + } + + return 0; +} + +static void sec_cipher_unmap(struct device *dev, struct sec_cipher_req *req, + struct scatterlist *src, struct scatterlist *dst) +{ + if (dst != src) + hisi_acc_sg_buf_unmap(dev, src, req->c_in); + + hisi_acc_sg_buf_unmap(dev, dst, req->c_out); +} + +static int sec_skcipher_sgl_map(struct sec_ctx *ctx, struct sec_req *req) +{ + struct skcipher_request *sq = req->c_req.sk_req; + + return sec_cipher_map(SEC_CTX_DEV(ctx), req, sq->src, sq->dst); +} + +static void sec_skcipher_sgl_unmap(struct sec_ctx *ctx, struct sec_req *req) +{ + struct device *dev = SEC_CTX_DEV(ctx); + struct sec_cipher_req *c_req = &req->c_req; + struct skcipher_request *sk_req = c_req->sk_req; + + sec_cipher_unmap(dev, c_req, sk_req->src, sk_req->dst); +} + +static int sec_aead_aes_set_key(struct sec_cipher_ctx *c_ctx, + struct crypto_authenc_keys *keys) +{ + switch (keys->enckeylen) { + case AES_KEYSIZE_128: + c_ctx->c_key_len = SEC_CKEY_128BIT; + break; + case AES_KEYSIZE_192: + c_ctx->c_key_len = SEC_CKEY_192BIT; + break; + case AES_KEYSIZE_256: + c_ctx->c_key_len = SEC_CKEY_256BIT; + break; + default: + pr_err("hisi_sec2: aead aes key error!\n"); + return -EINVAL; + } + memcpy(c_ctx->c_key, keys->enckey, keys->enckeylen); + + return 0; +} + +static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx, + struct crypto_authenc_keys *keys) +{ + struct crypto_shash *hash_tfm = ctx->hash_tfm; + SHASH_DESC_ON_STACK(shash, hash_tfm); + int blocksize, ret; + + if (!keys->authkeylen) { + pr_err("hisi_sec2: aead auth key error!\n"); + return -EINVAL; + } + + blocksize = crypto_shash_blocksize(hash_tfm); + if (keys->authkeylen > blocksize) { + ret = crypto_shash_digest(shash, keys->authkey, + keys->authkeylen, ctx->a_key); + if (ret) { + pr_err("hisi_sec2: aead auth digest error!\n"); + return -EINVAL; + } + ctx->a_key_len = blocksize; + } else { + memcpy(ctx->a_key, keys->authkey, keys->authkeylen); + ctx->a_key_len = keys->authkeylen; + } + + return 0; +} + +static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key, + const u32 keylen, const enum sec_hash_alg a_alg, + const enum sec_calg c_alg, + const enum sec_mac_len mac_len, + const enum sec_cmode c_mode) +{ + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + struct crypto_authenc_keys keys; + int ret; + + ctx->a_ctx.a_alg = a_alg; + ctx->c_ctx.c_alg = c_alg; + ctx->a_ctx.mac_len = mac_len; + c_ctx->c_mode = c_mode; + + if (crypto_authenc_extractkeys(&keys, key, keylen)) + goto bad_key; + + ret = sec_aead_aes_set_key(c_ctx, &keys); + if (ret) { + dev_err(SEC_CTX_DEV(ctx), "set sec cipher key err!\n"); + goto bad_key; + } + + ret = sec_aead_auth_set_key(&ctx->a_ctx, &keys); + if (ret) { + dev_err(SEC_CTX_DEV(ctx), "set sec auth key err!\n"); + goto bad_key; + } + + return 0; +bad_key: + memzero_explicit(&keys, sizeof(struct crypto_authenc_keys)); + + return -EINVAL; +} + + +#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, maclen, cmode) \ +static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, \ + u32 keylen) \ +{ \ + return sec_aead_setkey(tfm, key, keylen, aalg, calg, maclen, cmode);\ +} + +GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, + SEC_CALG_AES, SEC_HMAC_SHA1_MAC, SEC_CMODE_CBC) +GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, + SEC_CALG_AES, SEC_HMAC_SHA256_MAC, SEC_CMODE_CBC) +GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, + SEC_CALG_AES, SEC_HMAC_SHA512_MAC, SEC_CMODE_CBC) + +static int sec_aead_sgl_map(struct sec_ctx *ctx, struct sec_req *req) +{ + struct aead_request *aq = req->aead_req.aead_req; + + return sec_cipher_map(SEC_CTX_DEV(ctx), req, aq->src, aq->dst); +} + +static void sec_aead_sgl_unmap(struct sec_ctx *ctx, struct sec_req *req) +{ + struct device *dev = SEC_CTX_DEV(ctx); + struct sec_cipher_req *cq = &req->c_req; + struct aead_request *aq = req->aead_req.aead_req; + + sec_cipher_unmap(dev, cq, aq->src, aq->dst); +} + +static int sec_request_transfer(struct sec_ctx *ctx, struct sec_req *req) +{ + int ret; + + ret = ctx->req_op->buf_map(ctx, req); + if (unlikely(ret)) + return ret; + + ctx->req_op->do_transfer(ctx, req); + + ret = ctx->req_op->bd_fill(ctx, req); + if (unlikely(ret)) + goto unmap_req_buf; + + return ret; + +unmap_req_buf: + ctx->req_op->buf_unmap(ctx, req); + + return ret; +} + +static void sec_request_untransfer(struct sec_ctx *ctx, struct sec_req *req) +{ + ctx->req_op->buf_unmap(ctx, req); +} + +static void sec_skcipher_copy_iv(struct sec_ctx *ctx, struct sec_req *req) +{ + struct skcipher_request *sk_req = req->c_req.sk_req; + u8 *c_ivin = req->qp_ctx->res[req->req_id].c_ivin; + + memcpy(c_ivin, sk_req->iv, ctx->c_ctx.ivsize); +} + +static int sec_skcipher_bd_fill(struct sec_ctx *ctx, struct sec_req *req) +{ + struct sec_cipher_ctx *c_ctx = &ctx->c_ctx; + struct sec_cipher_req *c_req = &req->c_req; + struct sec_sqe *sec_sqe = &req->sec_sqe; + u8 scene, sa_type, da_type; + u8 bd_type, cipher; + u8 de = 0; + + memset(sec_sqe, 0, sizeof(struct sec_sqe)); + + sec_sqe->type2.c_key_addr = cpu_to_le64(c_ctx->c_key_dma); + sec_sqe->type2.c_ivin_addr = + cpu_to_le64(req->qp_ctx->res[req->req_id].c_ivin_dma); + sec_sqe->type2.data_src_addr = cpu_to_le64(c_req->c_in_dma); + sec_sqe->type2.data_dst_addr = cpu_to_le64(c_req->c_out_dma); + + sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_mode) << + SEC_CMODE_OFFSET); + sec_sqe->type2.c_alg = c_ctx->c_alg; + sec_sqe->type2.icvw_kmode |= cpu_to_le16(((u16)c_ctx->c_key_len) << + SEC_CKEY_OFFSET); + + bd_type = SEC_BD_TYPE2; + if (c_req->encrypt) + cipher = SEC_CIPHER_ENC << SEC_CIPHER_OFFSET; + else + cipher = SEC_CIPHER_DEC << SEC_CIPHER_OFFSET; + sec_sqe->type_cipher_auth = bd_type | cipher; + + sa_type = SEC_SGL << SEC_SRC_SGL_OFFSET; + scene = SEC_COMM_SCENE << SEC_SCENE_OFFSET; + if (c_req->c_in_dma != c_req->c_out_dma) + de = 0x1 << SEC_DE_OFFSET; + + sec_sqe->sds_sa_type = (de | scene | sa_type); + + /* Just set DST address type */ + da_type = SEC_SGL << SEC_DST_SGL_OFFSET; + sec_sqe->sdm_addr_type |= da_type; + + sec_sqe->type2.clen_ivhlen |= cpu_to_le32(c_req->c_len); + sec_sqe->type2.tag = cpu_to_le16((u16)req->req_id); + + return 0; +} + +static void sec_update_iv(struct sec_req *req, enum sec_alg_type alg_type) +{ + struct aead_request *aead_req = req->aead_req.aead_req; + struct skcipher_request *sk_req = req->c_req.sk_req; + u32 iv_size = req->ctx->c_ctx.ivsize; + struct scatterlist *sgl; + unsigned int cryptlen; + size_t sz; + u8 *iv; + + if (req->c_req.encrypt) + sgl = alg_type == SEC_SKCIPHER ? sk_req->dst : aead_req->dst; + else + sgl = alg_type == SEC_SKCIPHER ? sk_req->src : aead_req->src; + + if (alg_type == SEC_SKCIPHER) { + iv = sk_req->iv; + cryptlen = sk_req->cryptlen; + } else { + iv = aead_req->iv; + cryptlen = aead_req->cryptlen; + } + + sz = sg_pcopy_to_buffer(sgl, sg_nents(sgl), iv, iv_size, + cryptlen - iv_size); + if (unlikely(sz != iv_size)) + dev_err(SEC_CTX_DEV(req->ctx), "copy output iv error!\n"); +} + +static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req, + int err) +{ + struct skcipher_request *sk_req = req->c_req.sk_req; + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + + atomic_dec(&qp_ctx->pending_reqs); + sec_free_req_id(req); + + /* IV output at encrypto of CBC mode */ + if (!err && ctx->c_ctx.c_mode == SEC_CMODE_CBC && req->c_req.encrypt) + sec_update_iv(req, SEC_SKCIPHER); + + if (req->fake_busy) + sk_req->base.complete(&sk_req->base, -EINPROGRESS); + + sk_req->base.complete(&sk_req->base, err); +} + +static void sec_aead_copy_iv(struct sec_ctx *ctx, struct sec_req *req) +{ + struct aead_request *aead_req = req->aead_req.aead_req; + u8 *c_ivin = req->qp_ctx->res[req->req_id].c_ivin; + + memcpy(c_ivin, aead_req->iv, ctx->c_ctx.ivsize); +} + +static void sec_auth_bd_fill_ex(struct sec_auth_ctx *ctx, int dir, + struct sec_req *req, struct sec_sqe *sec_sqe) +{ + struct sec_aead_req *a_req = &req->aead_req; + struct sec_cipher_req *c_req = &req->c_req; + struct aead_request *aq = a_req->aead_req; + + sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma); + + sec_sqe->type2.mac_key_alg = + cpu_to_le32(ctx->mac_len / SEC_SQE_LEN_RATE); + + sec_sqe->type2.mac_key_alg |= + cpu_to_le32((u32)((ctx->a_key_len) / + SEC_SQE_LEN_RATE) << SEC_AKEY_OFFSET); + + sec_sqe->type2.mac_key_alg |= + cpu_to_le32((u32)(ctx->a_alg) << SEC_AEAD_ALG_OFFSET); + + sec_sqe->type_cipher_auth |= SEC_AUTH_TYPE1 << SEC_AUTH_OFFSET; + + if (dir) + sec_sqe->sds_sa_type &= SEC_CIPHER_AUTH; + else + sec_sqe->sds_sa_type |= SEC_AUTH_CIPHER; + + sec_sqe->type2.alen_ivllen = cpu_to_le32(c_req->c_len + aq->assoclen); + + sec_sqe->type2.cipher_src_offset = cpu_to_le16((u16)aq->assoclen); + + sec_sqe->type2.mac_addr = + cpu_to_le64(req->qp_ctx->res[req->req_id].out_mac_dma); +} + +static int sec_aead_bd_fill(struct sec_ctx *ctx, struct sec_req *req) +{ + struct sec_auth_ctx *auth_ctx = &ctx->a_ctx; + struct sec_sqe *sec_sqe = &req->sec_sqe; + int ret; + + ret = sec_skcipher_bd_fill(ctx, req); + if (unlikely(ret)) { + dev_err(SEC_CTX_DEV(ctx), "skcipher bd fill is error!\n"); + return ret; + } + + sec_auth_bd_fill_ex(auth_ctx, req->c_req.encrypt, req, sec_sqe); + + return 0; +} + +static void sec_aead_callback(struct sec_ctx *c, struct sec_req *req, int err) +{ + struct aead_request *a_req = req->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(a_req); + struct sec_cipher_req *c_req = &req->c_req; + size_t authsize = crypto_aead_authsize(tfm); + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + size_t sz; + + atomic_dec(&qp_ctx->pending_reqs); + + if (!err && c->c_ctx.c_mode == SEC_CMODE_CBC && c_req->encrypt) + sec_update_iv(req, SEC_AEAD); + + /* Copy output mac */ + if (!err && c_req->encrypt) { + struct scatterlist *sgl = a_req->dst; + + sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), + qp_ctx->res[req->req_id].out_mac, + authsize, a_req->cryptlen + + a_req->assoclen); + + if (unlikely(sz != authsize)) { + dev_err(SEC_CTX_DEV(req->ctx), "copy out mac err!\n"); + err = -EINVAL; + } + } + + sec_free_req_id(req); + + if (req->fake_busy) + a_req->base.complete(&a_req->base, -EINPROGRESS); + + a_req->base.complete(&a_req->base, err); +} + +static void sec_request_uninit(struct sec_ctx *ctx, struct sec_req *req) +{ + struct sec_qp_ctx *qp_ctx = req->qp_ctx; + + atomic_dec(&qp_ctx->pending_reqs); + sec_free_req_id(req); + sec_free_queue_id(ctx, req); +} + +static int sec_request_init(struct sec_ctx *ctx, struct sec_req *req) +{ + struct sec_qp_ctx *qp_ctx; + int queue_id; + + /* To load balance */ + queue_id = sec_alloc_queue_id(ctx, req); + qp_ctx = &ctx->qp_ctx[queue_id]; + + req->req_id = sec_alloc_req_id(req, qp_ctx); + if (unlikely(req->req_id < 0)) { + sec_free_queue_id(ctx, req); + return req->req_id; + } + + if (ctx->fake_req_limit <= atomic_inc_return(&qp_ctx->pending_reqs)) + req->fake_busy = true; + else + req->fake_busy = false; + + return 0; +} + +static int sec_process(struct sec_ctx *ctx, struct sec_req *req) +{ + int ret; + + ret = sec_request_init(ctx, req); + if (unlikely(ret)) + return ret; + + ret = sec_request_transfer(ctx, req); + if (unlikely(ret)) + goto err_uninit_req; + + /* Output IV as decrypto */ + if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt) + sec_update_iv(req, ctx->alg_type); + + ret = ctx->req_op->bd_send(ctx, req); + if (unlikely(ret != -EBUSY && ret != -EINPROGRESS)) { + dev_err_ratelimited(SEC_CTX_DEV(ctx), "send sec request failed!\n"); + goto err_send_req; + } + + return ret; + +err_send_req: + /* As failing, restore the IV from user */ + if (ctx->c_ctx.c_mode == SEC_CMODE_CBC && !req->c_req.encrypt) { + if (ctx->alg_type == SEC_SKCIPHER) + memcpy(req->c_req.sk_req->iv, + req->qp_ctx->res[req->req_id].c_ivin, + ctx->c_ctx.ivsize); + else + memcpy(req->aead_req.aead_req->iv, + req->qp_ctx->res[req->req_id].c_ivin, + ctx->c_ctx.ivsize); + } + + sec_request_untransfer(ctx, req); +err_uninit_req: + sec_request_uninit(ctx, req); + + return ret; +} + +static const struct sec_req_op sec_skcipher_req_ops = { + .buf_map = sec_skcipher_sgl_map, + .buf_unmap = sec_skcipher_sgl_unmap, + .do_transfer = sec_skcipher_copy_iv, + .bd_fill = sec_skcipher_bd_fill, + .bd_send = sec_bd_send, + .callback = sec_skcipher_callback, + .process = sec_process, +}; + +static const struct sec_req_op sec_aead_req_ops = { + .buf_map = sec_aead_sgl_map, + .buf_unmap = sec_aead_sgl_unmap, + .do_transfer = sec_aead_copy_iv, + .bd_fill = sec_aead_bd_fill, + .bd_send = sec_bd_send, + .callback = sec_aead_callback, + .process = sec_process, +}; + +static int sec_skcipher_ctx_init(struct crypto_skcipher *tfm) +{ + struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); + + ctx->req_op = &sec_skcipher_req_ops; + + return sec_skcipher_init(tfm); +} + +static void sec_skcipher_ctx_exit(struct crypto_skcipher *tfm) +{ + sec_skcipher_uninit(tfm); +} + +static int sec_aead_init(struct crypto_aead *tfm) +{ + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + int ret; + + crypto_aead_set_reqsize(tfm, sizeof(struct sec_req)); + ctx->alg_type = SEC_AEAD; + ctx->c_ctx.ivsize = crypto_aead_ivsize(tfm); + if (ctx->c_ctx.ivsize > SEC_IV_SIZE) { + dev_err(SEC_CTX_DEV(ctx), "get error aead iv size!\n"); + return -EINVAL; + } + + ctx->req_op = &sec_aead_req_ops; + ret = sec_ctx_base_init(ctx); + if (ret) + return ret; + + ret = sec_auth_init(ctx); + if (ret) + goto err_auth_init; + + ret = sec_cipher_init(ctx); + if (ret) + goto err_cipher_init; + + return ret; + +err_cipher_init: + sec_auth_uninit(ctx); +err_auth_init: + sec_ctx_base_uninit(ctx); + + return ret; +} + +static void sec_aead_exit(struct crypto_aead *tfm) +{ + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + + sec_cipher_uninit(ctx); + sec_auth_uninit(ctx); + sec_ctx_base_uninit(ctx); +} + +static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name) +{ + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + struct sec_auth_ctx *auth_ctx = &ctx->a_ctx; + int ret; + + ret = sec_aead_init(tfm); + if (ret) { + pr_err("hisi_sec2: aead init error!\n"); + return ret; + } + + auth_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0); + if (IS_ERR(auth_ctx->hash_tfm)) { + dev_err(SEC_CTX_DEV(ctx), "aead alloc shash error!\n"); + sec_aead_exit(tfm); + return PTR_ERR(auth_ctx->hash_tfm); + } + + return 0; +} + +static void sec_aead_ctx_exit(struct crypto_aead *tfm) +{ + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + + crypto_free_shash(ctx->a_ctx.hash_tfm); + sec_aead_exit(tfm); +} + +static int sec_aead_sha1_ctx_init(struct crypto_aead *tfm) +{ + return sec_aead_ctx_init(tfm, "sha1"); +} + +static int sec_aead_sha256_ctx_init(struct crypto_aead *tfm) +{ + return sec_aead_ctx_init(tfm, "sha256"); +} + +static int sec_aead_sha512_ctx_init(struct crypto_aead *tfm) +{ + return sec_aead_ctx_init(tfm, "sha512"); +} + +static int sec_skcipher_param_check(struct sec_ctx *ctx, struct sec_req *sreq) +{ + struct skcipher_request *sk_req = sreq->c_req.sk_req; + struct device *dev = SEC_CTX_DEV(ctx); + u8 c_alg = ctx->c_ctx.c_alg; + + if (unlikely(!sk_req->src || !sk_req->dst)) { + dev_err(dev, "skcipher input param error!\n"); + return -EINVAL; + } + sreq->c_req.c_len = sk_req->cryptlen; + if (c_alg == SEC_CALG_3DES) { + if (unlikely(sk_req->cryptlen & (DES3_EDE_BLOCK_SIZE - 1))) { + dev_err(dev, "skcipher 3des input length error!\n"); + return -EINVAL; + } + return 0; + } else if (c_alg == SEC_CALG_AES || c_alg == SEC_CALG_SM4) { + if (unlikely(sk_req->cryptlen & (AES_BLOCK_SIZE - 1))) { + dev_err(dev, "skcipher aes input length error!\n"); + return -EINVAL; + } + return 0; + } + + dev_err(dev, "skcipher algorithm error!\n"); + return -EINVAL; +} + +static int sec_skcipher_crypto(struct skcipher_request *sk_req, bool encrypt) +{ + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(sk_req); + struct sec_req *req = skcipher_request_ctx(sk_req); + struct sec_ctx *ctx = crypto_skcipher_ctx(tfm); + int ret; + + if (!sk_req->cryptlen) + return 0; + + req->c_req.sk_req = sk_req; + req->c_req.encrypt = encrypt; + req->ctx = ctx; + + ret = sec_skcipher_param_check(ctx, req); + if (unlikely(ret)) + return -EINVAL; + + return ctx->req_op->process(ctx, req); +} + +static int sec_skcipher_encrypt(struct skcipher_request *sk_req) +{ + return sec_skcipher_crypto(sk_req, true); +} + +static int sec_skcipher_decrypt(struct skcipher_request *sk_req) +{ + return sec_skcipher_crypto(sk_req, false); +} + +#define SEC_SKCIPHER_GEN_ALG(sec_cra_name, sec_set_key, sec_min_key_size, \ + sec_max_key_size, ctx_init, ctx_exit, blk_size, iv_size)\ +{\ + .base = {\ + .cra_name = sec_cra_name,\ + .cra_driver_name = "hisi_sec_"sec_cra_name,\ + .cra_priority = SEC_PRIORITY,\ + .cra_flags = CRYPTO_ALG_ASYNC,\ + .cra_blocksize = blk_size,\ + .cra_ctxsize = sizeof(struct sec_ctx),\ + .cra_module = THIS_MODULE,\ + },\ + .init = ctx_init,\ + .exit = ctx_exit,\ + .setkey = sec_set_key,\ + .decrypt = sec_skcipher_decrypt,\ + .encrypt = sec_skcipher_encrypt,\ + .min_keysize = sec_min_key_size,\ + .max_keysize = sec_max_key_size,\ + .ivsize = iv_size,\ +}, + +#define SEC_SKCIPHER_ALG(name, key_func, min_key_size, \ + max_key_size, blk_size, iv_size) \ + SEC_SKCIPHER_GEN_ALG(name, key_func, min_key_size, max_key_size, \ + sec_skcipher_ctx_init, sec_skcipher_ctx_exit, blk_size, iv_size) + +static struct skcipher_alg sec_skciphers[] = { + SEC_SKCIPHER_ALG("ecb(aes)", sec_setkey_aes_ecb, + AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE, + AES_BLOCK_SIZE, 0) + + SEC_SKCIPHER_ALG("cbc(aes)", sec_setkey_aes_cbc, + AES_MIN_KEY_SIZE, AES_MAX_KEY_SIZE, + AES_BLOCK_SIZE, AES_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("xts(aes)", sec_setkey_aes_xts, + SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MAX_KEY_SIZE, + AES_BLOCK_SIZE, AES_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb, + SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, + DES3_EDE_BLOCK_SIZE, 0) + + SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc, + SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, + DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts, + SEC_XTS_MIN_KEY_SIZE, SEC_XTS_MIN_KEY_SIZE, + AES_BLOCK_SIZE, AES_BLOCK_SIZE) + + SEC_SKCIPHER_ALG("cbc(sm4)", sec_setkey_sm4_cbc, + AES_MIN_KEY_SIZE, AES_MIN_KEY_SIZE, + AES_BLOCK_SIZE, AES_BLOCK_SIZE) +}; + +static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq) +{ + u8 c_alg = ctx->c_ctx.c_alg; + struct aead_request *req = sreq->aead_req.aead_req; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + size_t authsize = crypto_aead_authsize(tfm); + + if (unlikely(!req->src || !req->dst || !req->cryptlen)) { + dev_err(SEC_CTX_DEV(ctx), "aead input param error!\n"); + return -EINVAL; + } + + /* Support AES only */ + if (unlikely(c_alg != SEC_CALG_AES)) { + dev_err(SEC_CTX_DEV(ctx), "aead crypto alg error!\n"); + return -EINVAL; + + } + if (sreq->c_req.encrypt) + sreq->c_req.c_len = req->cryptlen; + else + sreq->c_req.c_len = req->cryptlen - authsize; + + if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) { + dev_err(SEC_CTX_DEV(ctx), "aead crypto length error!\n"); + return -EINVAL; + } + + return 0; +} + +static int sec_aead_crypto(struct aead_request *a_req, bool encrypt) +{ + struct crypto_aead *tfm = crypto_aead_reqtfm(a_req); + struct sec_req *req = aead_request_ctx(a_req); + struct sec_ctx *ctx = crypto_aead_ctx(tfm); + int ret; + + req->aead_req.aead_req = a_req; + req->c_req.encrypt = encrypt; + req->ctx = ctx; + + ret = sec_aead_param_check(ctx, req); + if (unlikely(ret)) + return -EINVAL; + + return ctx->req_op->process(ctx, req); +} + +static int sec_aead_encrypt(struct aead_request *a_req) +{ + return sec_aead_crypto(a_req, true); +} + +static int sec_aead_decrypt(struct aead_request *a_req) +{ + return sec_aead_crypto(a_req, false); +} + +#define SEC_AEAD_GEN_ALG(sec_cra_name, sec_set_key, ctx_init,\ + ctx_exit, blk_size, iv_size, max_authsize)\ +{\ + .base = {\ + .cra_name = sec_cra_name,\ + .cra_driver_name = "hisi_sec_"sec_cra_name,\ + .cra_priority = SEC_PRIORITY,\ + .cra_flags = CRYPTO_ALG_ASYNC,\ + .cra_blocksize = blk_size,\ + .cra_ctxsize = sizeof(struct sec_ctx),\ + .cra_module = THIS_MODULE,\ + },\ + .init = ctx_init,\ + .exit = ctx_exit,\ + .setkey = sec_set_key,\ + .decrypt = sec_aead_decrypt,\ + .encrypt = sec_aead_encrypt,\ + .ivsize = iv_size,\ + .maxauthsize = max_authsize,\ +} + +#define SEC_AEAD_ALG(algname, keyfunc, aead_init, blksize, ivsize, authsize)\ + SEC_AEAD_GEN_ALG(algname, keyfunc, aead_init,\ + sec_aead_ctx_exit, blksize, ivsize, authsize) + +static struct aead_alg sec_aeads[] = { + SEC_AEAD_ALG("authenc(hmac(sha1),cbc(aes))", + sec_setkey_aes_cbc_sha1, sec_aead_sha1_ctx_init, + AES_BLOCK_SIZE, AES_BLOCK_SIZE, SHA1_DIGEST_SIZE), + + SEC_AEAD_ALG("authenc(hmac(sha256),cbc(aes))", + sec_setkey_aes_cbc_sha256, sec_aead_sha256_ctx_init, + AES_BLOCK_SIZE, AES_BLOCK_SIZE, SHA256_DIGEST_SIZE), + + SEC_AEAD_ALG("authenc(hmac(sha512),cbc(aes))", + sec_setkey_aes_cbc_sha512, sec_aead_sha512_ctx_init, + AES_BLOCK_SIZE, AES_BLOCK_SIZE, SHA512_DIGEST_SIZE), +}; + +int sec_register_to_crypto(void) +{ + int ret = 0; + + /* To avoid repeat register */ + if (atomic_add_return(1, &sec_active_devs) == 1) { + ret = crypto_register_skciphers(sec_skciphers, + ARRAY_SIZE(sec_skciphers)); + if (ret) + return ret; + + ret = crypto_register_aeads(sec_aeads, ARRAY_SIZE(sec_aeads)); + if (ret) + goto reg_aead_fail; + } + + return ret; + +reg_aead_fail: + crypto_unregister_skciphers(sec_skciphers, ARRAY_SIZE(sec_skciphers)); + + return ret; +} + +void sec_unregister_from_crypto(void) +{ + if (atomic_sub_return(1, &sec_active_devs) == 0) { + crypto_unregister_skciphers(sec_skciphers, + ARRAY_SIZE(sec_skciphers)); + crypto_unregister_aeads(sec_aeads, ARRAY_SIZE(sec_aeads)); + } +} --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec2/sec_crypto.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019 HiSilicon Limited. */ + +#ifndef __HISI_SEC_V2_CRYPTO_H +#define __HISI_SEC_V2_CRYPTO_H + +#define SEC_IV_SIZE 24 +#define SEC_MAX_KEY_SIZE 64 +#define SEC_COMM_SCENE 0 + +enum sec_calg { + SEC_CALG_3DES = 0x1, + SEC_CALG_AES = 0x2, + SEC_CALG_SM4 = 0x3, +}; + +enum sec_hash_alg { + SEC_A_HMAC_SHA1 = 0x10, + SEC_A_HMAC_SHA256 = 0x11, + SEC_A_HMAC_SHA512 = 0x15, +}; + +enum sec_mac_len { + SEC_HMAC_SHA1_MAC = 20, + SEC_HMAC_SHA256_MAC = 32, + SEC_HMAC_SHA512_MAC = 64, +}; + +enum sec_cmode { + SEC_CMODE_ECB = 0x0, + SEC_CMODE_CBC = 0x1, + SEC_CMODE_CTR = 0x4, + SEC_CMODE_XTS = 0x7, +}; + +enum sec_ckey_type { + SEC_CKEY_128BIT = 0x0, + SEC_CKEY_192BIT = 0x1, + SEC_CKEY_256BIT = 0x2, + SEC_CKEY_3DES_3KEY = 0x1, + SEC_CKEY_3DES_2KEY = 0x3, +}; + +enum sec_bd_type { + SEC_BD_TYPE1 = 0x1, + SEC_BD_TYPE2 = 0x2, +}; + +enum sec_auth { + SEC_NO_AUTH = 0x0, + SEC_AUTH_TYPE1 = 0x1, + SEC_AUTH_TYPE2 = 0x2, +}; + +enum sec_cipher_dir { + SEC_CIPHER_ENC = 0x1, + SEC_CIPHER_DEC = 0x2, +}; + +enum sec_addr_type { + SEC_PBUF = 0x0, + SEC_SGL = 0x1, + SEC_PRP = 0x2, +}; + +struct sec_sqe_type2 { + + /* + * mac_len: 0~4 bits + * a_key_len: 5~10 bits + * a_alg: 11~16 bits + */ + __le32 mac_key_alg; + + /* + * c_icv_len: 0~5 bits + * c_width: 6~8 bits + * c_key_len: 9~11 bits + * c_mode: 12~15 bits + */ + __le16 icvw_kmode; + + /* c_alg: 0~3 bits */ + __u8 c_alg; + __u8 rsvd4; + + /* + * a_len: 0~23 bits + * iv_offset_l: 24~31 bits + */ + __le32 alen_ivllen; + + /* + * c_len: 0~23 bits + * iv_offset_h: 24~31 bits + */ + __le32 clen_ivhlen; + + __le16 auth_src_offset; + __le16 cipher_src_offset; + __le16 cs_ip_header_offset; + __le16 cs_udp_header_offset; + __le16 pass_word_len; + __le16 dk_len; + __u8 salt3; + __u8 salt2; + __u8 salt1; + __u8 salt0; + + __le16 tag; + __le16 rsvd5; + + /* + * c_pad_type: 0~3 bits + * c_pad_len: 4~11 bits + * c_pad_data_type: 12~15 bits + */ + __le16 cph_pad; + + /* c_pad_len_field: 0~1 bits */ + __le16 c_pad_len_field; + + + __le64 long_a_data_len; + __le64 a_ivin_addr; + __le64 a_key_addr; + __le64 mac_addr; + __le64 c_ivin_addr; + __le64 c_key_addr; + + __le64 data_src_addr; + __le64 data_dst_addr; + + /* + * done: 0 bit + * icv: 1~3 bits + * csc: 4~6 bits + * flag: 7-10 bits + * dif_check: 11~13 bits + */ + __le16 done_flag; + + __u8 error_type; + __u8 warning_type; + __u8 mac_i3; + __u8 mac_i2; + __u8 mac_i1; + __u8 mac_i0; + __le16 check_sum_i; + __u8 tls_pad_len_i; + __u8 rsvd12; + __le32 counter; +}; + +struct sec_sqe { + /* + * type: 0~3 bits + * cipher: 4~5 bits + * auth: 6~7 bit s + */ + __u8 type_cipher_auth; + + /* + * seq: 0 bit + * de: 1~2 bits + * scene: 3~6 bits + * src_addr_type: ~7 bit, with sdm_addr_type 0-1 bits + */ + __u8 sds_sa_type; + + /* + * src_addr_type: 0~1 bits, not used now, + * if support PRP, set this field, or set zero. + * dst_addr_type: 2~4 bits + * mac_addr_type: 5~7 bits + */ + __u8 sdm_addr_type; + __u8 rsvd0; + + /* + * nonce_len(type2): 0~3 bits + * huk(type2): 4 bit + * key_s(type2): 5 bit + * ci_gen: 6~7 bits + */ + __u8 huk_key_ci; + + /* + * ai_gen: 0~1 bits + * a_pad(type2): 2~3 bits + * c_s(type2): 4~5 bits + */ + __u8 ai_apd_cs; + + /* + * rhf(type2): 0 bit + * c_key_type: 1~2 bits + * a_key_type: 3~4 bits + * write_frame_len(type2): 5~7 bits + */ + __u8 rca_key_frm; + + /* + * cal_iv_addr_en(type2): 0 bit + * tls_up(type2): 1 bit + * inveld: 7 bit + */ + __u8 iv_tls_ld; + + /* Just using type2 BD now */ + struct sec_sqe_type2 type2; +}; + +int sec_register_to_crypto(void); +void sec_unregister_from_crypto(void); +#endif --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sec2/sec_main.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sec2/sec_main.c @@ -0,0 +1,1124 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 HiSilicon Limited. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sec.h" + +#define SEC_VF_NUM 63 +#define SEC_QUEUE_NUM_V1 4096 +#define SEC_QUEUE_NUM_V2 1024 +#define SEC_PF_PCI_DEVICE_ID 0xa255 +#define SEC_VF_PCI_DEVICE_ID 0xa256 + +#define SEC_BD_ERR_CHK_EN0 0xEFFFFFFF +#define SEC_BD_ERR_CHK_EN1 0x7ffff7fd +#define SEC_BD_ERR_CHK_EN3 0xffffbfff + +#define SEC_SQE_SIZE 128 +#define SEC_SQ_SIZE (SEC_SQE_SIZE * QM_Q_DEPTH) +#define SEC_PF_DEF_Q_NUM 256 +#define SEC_PF_DEF_Q_BASE 0 +#define SEC_CTX_Q_NUM_DEF 2 +#define SEC_CTX_Q_NUM_MAX 32 + +#define SEC_CTRL_CNT_CLR_CE 0x301120 +#define SEC_CTRL_CNT_CLR_CE_BIT BIT(0) +#define SEC_ENGINE_PF_CFG_OFF 0x300000 +#define SEC_ACC_COMMON_REG_OFF 0x1000 +#define SEC_CORE_INT_SOURCE 0x301010 +#define SEC_CORE_INT_MASK 0x301000 +#define SEC_CORE_INT_STATUS 0x301008 +#define SEC_CORE_SRAM_ECC_ERR_INFO 0x301C14 +#define SEC_ECC_NUM(err) (((err) >> 16) & 0xFF) +#define SEC_ECC_ADDR(err) ((err) >> 0) +#define SEC_CORE_INT_DISABLE 0x0 +#define SEC_CORE_INT_ENABLE 0x1ff +#define SEC_CORE_INT_CLEAR 0x1ff +#define SEC_SAA_ENABLE 0x17f + +#define SEC_RAS_CE_REG 0x301050 +#define SEC_RAS_FE_REG 0x301054 +#define SEC_RAS_NFE_REG 0x301058 +#define SEC_RAS_CE_ENB_MSK 0x88 +#define SEC_RAS_FE_ENB_MSK 0x0 +#define SEC_RAS_NFE_ENB_MSK 0x177 +#define SEC_RAS_DISABLE 0x0 +#define SEC_MEM_START_INIT_REG 0x0100 +#define SEC_MEM_INIT_DONE_REG 0x0104 + +#define SEC_CONTROL_REG 0x0200 +#define SEC_TRNG_EN_SHIFT 8 +#define SEC_CLK_GATE_ENABLE BIT(3) +#define SEC_CLK_GATE_DISABLE (~BIT(3)) +#define SEC_AXI_SHUTDOWN_ENABLE BIT(12) +#define SEC_AXI_SHUTDOWN_DISABLE 0xFFFFEFFF + +#define SEC_INTERFACE_USER_CTRL0_REG 0x0220 +#define SEC_INTERFACE_USER_CTRL1_REG 0x0224 +#define SEC_SAA_EN_REG 0x0270 +#define SEC_BD_ERR_CHK_EN_REG0 0x0380 +#define SEC_BD_ERR_CHK_EN_REG1 0x0384 +#define SEC_BD_ERR_CHK_EN_REG3 0x038c + +#define SEC_USER0_SMMU_NORMAL (BIT(23) | BIT(15)) +#define SEC_USER1_SMMU_NORMAL (BIT(31) | BIT(23) | BIT(15) | BIT(7)) +#define SEC_CORE_INT_STATUS_M_ECC BIT(2) + +#define SEC_DELAY_10_US 10 +#define SEC_POLL_TIMEOUT_US 1000 +#define SEC_DBGFS_VAL_MAX_LEN 20 +#define SEC_SINGLE_PORT_MAX_TRANS 0x2060 + +#define SEC_ADDR(qm, offset) ((qm)->io_base + (offset) + \ + SEC_ENGINE_PF_CFG_OFF + SEC_ACC_COMMON_REG_OFF) + +struct sec_hw_error { + u32 int_msk; + const char *msg; +}; + +static const char sec_name[] = "hisi_sec2"; +static struct dentry *sec_debugfs_root; +static LIST_HEAD(sec_list); +static DEFINE_MUTEX(sec_list_lock); + +static const struct sec_hw_error sec_hw_errors[] = { + {.int_msk = BIT(0), .msg = "sec_axi_rresp_err_rint"}, + {.int_msk = BIT(1), .msg = "sec_axi_bresp_err_rint"}, + {.int_msk = BIT(2), .msg = "sec_ecc_2bit_err_rint"}, + {.int_msk = BIT(3), .msg = "sec_ecc_1bit_err_rint"}, + {.int_msk = BIT(4), .msg = "sec_req_trng_timeout_rint"}, + {.int_msk = BIT(5), .msg = "sec_fsm_hbeat_rint"}, + {.int_msk = BIT(6), .msg = "sec_channel_req_rng_timeout_rint"}, + {.int_msk = BIT(7), .msg = "sec_bd_err_rint"}, + {.int_msk = BIT(8), .msg = "sec_chain_buff_err_rint"}, + { /* sentinel */ } +}; + +struct sec_dev *sec_find_device(int node) +{ +#define SEC_NUMA_MAX_DISTANCE 100 + int min_distance = SEC_NUMA_MAX_DISTANCE; + int dev_node = 0, free_qp_num = 0; + struct sec_dev *sec, *ret = NULL; + struct hisi_qm *qm; + struct device *dev; + + mutex_lock(&sec_list_lock); + list_for_each_entry(sec, &sec_list, list) { + qm = &sec->qm; + dev = &qm->pdev->dev; +#ifdef CONFIG_NUMA + dev_node = dev->numa_node; + if (dev_node < 0) + dev_node = 0; +#endif + if (node_distance(dev_node, node) < min_distance) { + free_qp_num = hisi_qm_get_free_qp_num(qm); + if (free_qp_num >= sec->ctx_q_num) { + ret = sec; + min_distance = node_distance(dev_node, node); + } + } + } + mutex_unlock(&sec_list_lock); + + return ret; +} + +static const char * const sec_dbg_file_name[] = { + [SEC_CURRENT_QM] = "current_qm", + [SEC_CLEAR_ENABLE] = "clear_enable", +}; + +static struct debugfs_reg32 sec_dfx_regs[] = { + {"SEC_PF_ABNORMAL_INT_SOURCE ", 0x301010}, + {"SEC_SAA_EN ", 0x301270}, + {"SEC_BD_LATENCY_MIN ", 0x301600}, + {"SEC_BD_LATENCY_MAX ", 0x301608}, + {"SEC_BD_LATENCY_AVG ", 0x30160C}, + {"SEC_BD_NUM_IN_SAA0 ", 0x301670}, + {"SEC_BD_NUM_IN_SAA1 ", 0x301674}, + {"SEC_BD_NUM_IN_SEC ", 0x301680}, + {"SEC_ECC_1BIT_CNT ", 0x301C00}, + {"SEC_ECC_1BIT_INFO ", 0x301C04}, + {"SEC_ECC_2BIT_CNT ", 0x301C10}, + {"SEC_ECC_2BIT_INFO ", 0x301C14}, + {"SEC_BD_SAA0 ", 0x301C20}, + {"SEC_BD_SAA1 ", 0x301C24}, + {"SEC_BD_SAA2 ", 0x301C28}, + {"SEC_BD_SAA3 ", 0x301C2C}, + {"SEC_BD_SAA4 ", 0x301C30}, + {"SEC_BD_SAA5 ", 0x301C34}, + {"SEC_BD_SAA6 ", 0x301C38}, + {"SEC_BD_SAA7 ", 0x301C3C}, + {"SEC_BD_SAA8 ", 0x301C40}, +}; + +static int sec_pf_q_num_set(const char *val, const struct kernel_param *kp) +{ + struct pci_dev *pdev; + u32 n, q_num; + u8 rev_id; + int ret; + + if (!val) + return -EINVAL; + + pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, + SEC_PF_PCI_DEVICE_ID, NULL); + if (!pdev) { + q_num = min_t(u32, SEC_QUEUE_NUM_V1, SEC_QUEUE_NUM_V2); + pr_info("No device, suppose queue number is %d!\n", q_num); + } else { + rev_id = pdev->revision; + + switch (rev_id) { + case QM_HW_V1: + q_num = SEC_QUEUE_NUM_V1; + break; + case QM_HW_V2: + q_num = SEC_QUEUE_NUM_V2; + break; + default: + return -EINVAL; + } + } + + ret = kstrtou32(val, 10, &n); + if (ret || !n || n > q_num) + return -EINVAL; + + return param_set_int(val, kp); +} + +static const struct kernel_param_ops sec_pf_q_num_ops = { + .set = sec_pf_q_num_set, + .get = param_get_int, +}; +static u32 pf_q_num = SEC_PF_DEF_Q_NUM; +module_param_cb(pf_q_num, &sec_pf_q_num_ops, &pf_q_num, 0444); +MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 0-4096, v2 0-1024)"); + +static int sec_ctx_q_num_set(const char *val, const struct kernel_param *kp) +{ + u32 ctx_q_num; + int ret; + + if (!val) + return -EINVAL; + + ret = kstrtou32(val, 10, &ctx_q_num); + if (ret) + return -EINVAL; + + if (!ctx_q_num || ctx_q_num > SEC_CTX_Q_NUM_MAX || ctx_q_num & 0x1) { + pr_err("ctx queue num[%u] is invalid!\n", ctx_q_num); + return -EINVAL; + } + + return param_set_int(val, kp); +} + +static const struct kernel_param_ops sec_ctx_q_num_ops = { + .set = sec_ctx_q_num_set, + .get = param_get_int, +}; +static u32 ctx_q_num = SEC_CTX_Q_NUM_DEF; +module_param_cb(ctx_q_num, &sec_ctx_q_num_ops, &ctx_q_num, 0444); +MODULE_PARM_DESC(ctx_q_num, "Queue num in ctx (2 default, 2, 4, ..., 32)"); + +static const struct pci_device_id sec_dev_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, SEC_PF_PCI_DEVICE_ID) }, + { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, SEC_VF_PCI_DEVICE_ID) }, + { 0, } +}; +MODULE_DEVICE_TABLE(pci, sec_dev_ids); + +static inline void sec_add_to_list(struct sec_dev *sec) +{ + mutex_lock(&sec_list_lock); + list_add_tail(&sec->list, &sec_list); + mutex_unlock(&sec_list_lock); +} + +static inline void sec_remove_from_list(struct sec_dev *sec) +{ + mutex_lock(&sec_list_lock); + list_del(&sec->list); + mutex_unlock(&sec_list_lock); +} + +static u8 sec_get_endian(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + u32 reg; + + /* + * As for VF, it is a wrong way to get endian setting by + * reading a register of the engine + */ + if (qm->pdev->is_virtfn) { + dev_err_ratelimited(&qm->pdev->dev, + "cannot access a register in VF!\n"); + return SEC_LE; + } + reg = readl_relaxed(qm->io_base + SEC_ENGINE_PF_CFG_OFF + + SEC_ACC_COMMON_REG_OFF + SEC_CONTROL_REG); + + /* BD little endian mode */ + if (!(reg & BIT(0))) + return SEC_LE; + + /* BD 32-bits big endian mode */ + else if (!(reg & BIT(1))) + return SEC_32BE; + + /* BD 64-bits big endian mode */ + else + return SEC_64BE; +} + +static int sec_engine_init(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + int ret; + u32 reg; + + /* disable clock gate control */ + reg = readl_relaxed(SEC_ADDR(qm, SEC_CONTROL_REG)); + reg &= SEC_CLK_GATE_DISABLE; + writel_relaxed(reg, SEC_ADDR(qm, SEC_CONTROL_REG)); + + writel_relaxed(0x1, SEC_ADDR(qm, SEC_MEM_START_INIT_REG)); + + ret = readl_relaxed_poll_timeout(SEC_ADDR(qm, SEC_MEM_INIT_DONE_REG), + reg, reg & 0x1, SEC_DELAY_10_US, + SEC_POLL_TIMEOUT_US); + if (ret) { + dev_err(&qm->pdev->dev, "fail to init sec mem\n"); + return ret; + } + + reg = readl_relaxed(SEC_ADDR(qm, SEC_CONTROL_REG)); + reg |= (0x1 << SEC_TRNG_EN_SHIFT); + writel_relaxed(reg, SEC_ADDR(qm, SEC_CONTROL_REG)); + + reg = readl_relaxed(SEC_ADDR(qm, SEC_INTERFACE_USER_CTRL0_REG)); + reg |= SEC_USER0_SMMU_NORMAL; + writel_relaxed(reg, SEC_ADDR(qm, SEC_INTERFACE_USER_CTRL0_REG)); + + reg = readl_relaxed(SEC_ADDR(qm, SEC_INTERFACE_USER_CTRL1_REG)); + reg |= SEC_USER1_SMMU_NORMAL; + writel_relaxed(reg, SEC_ADDR(qm, SEC_INTERFACE_USER_CTRL1_REG)); + + writel(SEC_SINGLE_PORT_MAX_TRANS, + qm->io_base + AM_CFG_SINGLE_PORT_MAX_TRANS); + + writel(SEC_SAA_ENABLE, SEC_ADDR(qm, SEC_SAA_EN_REG)); + + /* Enable sm4 extra mode, as ctr/ecb */ + writel_relaxed(SEC_BD_ERR_CHK_EN0, + SEC_ADDR(qm, SEC_BD_ERR_CHK_EN_REG0)); + /* Enable sm4 xts mode multiple iv */ + writel_relaxed(SEC_BD_ERR_CHK_EN1, + SEC_ADDR(qm, SEC_BD_ERR_CHK_EN_REG1)); + writel_relaxed(SEC_BD_ERR_CHK_EN3, + SEC_ADDR(qm, SEC_BD_ERR_CHK_EN_REG3)); + + /* config endian */ + reg = readl_relaxed(SEC_ADDR(qm, SEC_CONTROL_REG)); + reg |= sec_get_endian(sec); + writel_relaxed(reg, SEC_ADDR(qm, SEC_CONTROL_REG)); + + return 0; +} + +static int sec_set_user_domain_and_cache(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + + /* qm user domain */ + writel(AXUSER_BASE, qm->io_base + QM_ARUSER_M_CFG_1); + writel(ARUSER_M_CFG_ENABLE, qm->io_base + QM_ARUSER_M_CFG_ENABLE); + writel(AXUSER_BASE, qm->io_base + QM_AWUSER_M_CFG_1); + writel(AWUSER_M_CFG_ENABLE, qm->io_base + QM_AWUSER_M_CFG_ENABLE); + writel(WUSER_M_CFG_ENABLE, qm->io_base + QM_WUSER_M_CFG_ENABLE); + + /* qm cache */ + writel(AXI_M_CFG, qm->io_base + QM_AXI_M_CFG); + writel(AXI_M_CFG_ENABLE, qm->io_base + QM_AXI_M_CFG_ENABLE); + + /* disable FLR triggered by BME(bus master enable) */ + writel(PEH_AXUSER_CFG, qm->io_base + QM_PEH_AXUSER_CFG); + writel(PEH_AXUSER_CFG_ENABLE, qm->io_base + QM_PEH_AXUSER_CFG_ENABLE); + + /* enable sqc,cqc writeback */ + writel(SQC_CACHE_ENABLE | CQC_CACHE_ENABLE | SQC_CACHE_WB_ENABLE | + CQC_CACHE_WB_ENABLE | FIELD_PREP(SQC_CACHE_WB_THRD, 1) | + FIELD_PREP(CQC_CACHE_WB_THRD, 1), qm->io_base + QM_CACHE_CTL); + + return sec_engine_init(sec); +} + +/* sec_debug_regs_clear() - clear the sec debug regs */ +static void sec_debug_regs_clear(struct hisi_qm *qm) +{ + /* clear current_qm */ + writel(0x0, qm->io_base + QM_DFX_MB_CNT_VF); + writel(0x0, qm->io_base + QM_DFX_DB_CNT_VF); + + /* clear rdclr_en */ + writel(0x0, qm->io_base + SEC_CTRL_CNT_CLR_CE); + + hisi_qm_debug_regs_clear(qm); +} + +static void sec_hw_error_enable(struct hisi_qm *qm) +{ + u32 val; + + if (qm->ver == QM_HW_V1) { + writel(SEC_CORE_INT_DISABLE, qm->io_base + SEC_CORE_INT_MASK); + dev_info(&qm->pdev->dev, "V1 not support hw error handle\n"); + return; + } + + val = readl(SEC_ADDR(qm, SEC_CONTROL_REG)); + + /* clear SEC hw error source if having */ + writel(SEC_CORE_INT_CLEAR, qm->io_base + SEC_CORE_INT_SOURCE); + + /* enable SEC hw error interrupts */ + writel(SEC_CORE_INT_ENABLE, qm->io_base + SEC_CORE_INT_MASK); + + /* enable RAS int */ + writel(SEC_RAS_CE_ENB_MSK, qm->io_base + SEC_RAS_CE_REG); + writel(SEC_RAS_FE_ENB_MSK, qm->io_base + SEC_RAS_FE_REG); + writel(SEC_RAS_NFE_ENB_MSK, qm->io_base + SEC_RAS_NFE_REG); + + /* enable SEC block master OOO when m-bit error occur */ + val = val | SEC_AXI_SHUTDOWN_ENABLE; + + writel(val, SEC_ADDR(qm, SEC_CONTROL_REG)); +} + +static void sec_hw_error_disable(struct hisi_qm *qm) +{ + u32 val; + + val = readl(SEC_ADDR(qm, SEC_CONTROL_REG)); + + /* disable RAS int */ + writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_CE_REG); + writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_FE_REG); + writel(SEC_RAS_DISABLE, qm->io_base + SEC_RAS_NFE_REG); + + /* disable SEC hw error interrupts */ + writel(SEC_CORE_INT_DISABLE, qm->io_base + SEC_CORE_INT_MASK); + + /* disable SEC block master OOO when m-bit error occur */ + val = val & SEC_AXI_SHUTDOWN_DISABLE; + + writel(val, SEC_ADDR(qm, SEC_CONTROL_REG)); +} + +static u32 sec_current_qm_read(struct sec_debug_file *file) +{ + struct hisi_qm *qm = file->qm; + + return readl(qm->io_base + QM_DFX_MB_CNT_VF); +} + +static int sec_current_qm_write(struct sec_debug_file *file, u32 val) +{ + struct hisi_qm *qm = file->qm; + struct sec_dev *sec = container_of(qm, struct sec_dev, qm); + u32 vfq_num; + u32 tmp; + + if (val > sec->num_vfs) + return -EINVAL; + + /* According PF or VF Dev ID to calculation curr_qm_qp_num and store */ + if (!val) { + qm->debug.curr_qm_qp_num = qm->qp_num; + } else { + vfq_num = (qm->ctrl_qp_num - qm->qp_num) / sec->num_vfs; + + if (val == sec->num_vfs) + qm->debug.curr_qm_qp_num = + qm->ctrl_qp_num - qm->qp_num - + (sec->num_vfs - 1) * vfq_num; + else + qm->debug.curr_qm_qp_num = vfq_num; + } + + writel(val, qm->io_base + QM_DFX_MB_CNT_VF); + writel(val, qm->io_base + QM_DFX_DB_CNT_VF); + + tmp = val | + (readl(qm->io_base + QM_DFX_SQE_CNT_VF_SQN) & CURRENT_Q_MASK); + writel(tmp, qm->io_base + QM_DFX_SQE_CNT_VF_SQN); + + tmp = val | + (readl(qm->io_base + QM_DFX_CQE_CNT_VF_CQN) & CURRENT_Q_MASK); + writel(tmp, qm->io_base + QM_DFX_CQE_CNT_VF_CQN); + + return 0; +} + +static u32 sec_clear_enable_read(struct sec_debug_file *file) +{ + struct hisi_qm *qm = file->qm; + + return readl(qm->io_base + SEC_CTRL_CNT_CLR_CE) & + SEC_CTRL_CNT_CLR_CE_BIT; +} + +static int sec_clear_enable_write(struct sec_debug_file *file, u32 val) +{ + struct hisi_qm *qm = file->qm; + u32 tmp; + + if (val != 1 && val) + return -EINVAL; + + tmp = (readl(qm->io_base + SEC_CTRL_CNT_CLR_CE) & + ~SEC_CTRL_CNT_CLR_CE_BIT) | val; + writel(tmp, qm->io_base + SEC_CTRL_CNT_CLR_CE); + + return 0; +} + +static ssize_t sec_debug_read(struct file *filp, char __user *buf, + size_t count, loff_t *pos) +{ + struct sec_debug_file *file = filp->private_data; + char tbuf[SEC_DBGFS_VAL_MAX_LEN]; + u32 val; + int ret; + + spin_lock_irq(&file->lock); + + switch (file->index) { + case SEC_CURRENT_QM: + val = sec_current_qm_read(file); + break; + case SEC_CLEAR_ENABLE: + val = sec_clear_enable_read(file); + break; + default: + spin_unlock_irq(&file->lock); + return -EINVAL; + } + + spin_unlock_irq(&file->lock); + ret = snprintf(tbuf, SEC_DBGFS_VAL_MAX_LEN, "%u\n", val); + + return simple_read_from_buffer(buf, count, pos, tbuf, ret); +} + +static ssize_t sec_debug_write(struct file *filp, const char __user *buf, + size_t count, loff_t *pos) +{ + struct sec_debug_file *file = filp->private_data; + char tbuf[SEC_DBGFS_VAL_MAX_LEN]; + unsigned long val; + int len, ret; + + if (*pos != 0) + return 0; + + if (count >= SEC_DBGFS_VAL_MAX_LEN) + return -ENOSPC; + + len = simple_write_to_buffer(tbuf, SEC_DBGFS_VAL_MAX_LEN - 1, + pos, buf, count); + if (len < 0) + return len; + + tbuf[len] = '\0'; + if (kstrtoul(tbuf, 0, &val)) + return -EFAULT; + + spin_lock_irq(&file->lock); + + switch (file->index) { + case SEC_CURRENT_QM: + ret = sec_current_qm_write(file, val); + if (ret) + goto err_input; + break; + case SEC_CLEAR_ENABLE: + ret = sec_clear_enable_write(file, val); + if (ret) + goto err_input; + break; + default: + ret = -EINVAL; + goto err_input; + } + + spin_unlock_irq(&file->lock); + + return count; + + err_input: + spin_unlock_irq(&file->lock); + return ret; +} + +static const struct file_operations sec_dbg_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = sec_debug_read, + .write = sec_debug_write, +}; + +static int sec_debugfs_atomic64_get(void *data, u64 *val) +{ + *val = atomic64_read((atomic64_t *)data); + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(sec_atomic64_ops, sec_debugfs_atomic64_get, + NULL, "%lld\n"); + +static int sec_core_debug_init(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + struct device *dev = &qm->pdev->dev; + struct sec_dfx *dfx = &sec->debug.dfx; + struct debugfs_regset32 *regset; + struct dentry *tmp_d; + + tmp_d = debugfs_create_dir("sec_dfx", sec->qm.debug.debug_root); + + regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); + if (!regset) + return -ENOENT; + + regset->regs = sec_dfx_regs; + regset->nregs = ARRAY_SIZE(sec_dfx_regs); + regset->base = qm->io_base; + + debugfs_create_regset32("regs", 0444, tmp_d, regset); + + debugfs_create_file("send_cnt", 0444, tmp_d, + &dfx->send_cnt, &sec_atomic64_ops); + + debugfs_create_file("recv_cnt", 0444, tmp_d, + &dfx->recv_cnt, &sec_atomic64_ops); + + return 0; +} + +static int sec_debug_init(struct sec_dev *sec) +{ + int i; + + for (i = SEC_CURRENT_QM; i < SEC_DEBUG_FILE_NUM; i++) { + spin_lock_init(&sec->debug.files[i].lock); + sec->debug.files[i].index = i; + sec->debug.files[i].qm = &sec->qm; + + debugfs_create_file(sec_dbg_file_name[i], 0600, + sec->qm.debug.debug_root, + sec->debug.files + i, + &sec_dbg_fops); + } + + return sec_core_debug_init(sec); +} + +static int sec_debugfs_init(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + struct device *dev = &qm->pdev->dev; + int ret; + + qm->debug.debug_root = debugfs_create_dir(dev_name(dev), + sec_debugfs_root); + ret = hisi_qm_debug_init(qm); + if (ret) + goto failed_to_create; + + if (qm->pdev->device == SEC_PF_PCI_DEVICE_ID) { + ret = sec_debug_init(sec); + if (ret) + goto failed_to_create; + } + + return 0; + +failed_to_create: + debugfs_remove_recursive(sec_debugfs_root); + + return ret; +} + +static void sec_debugfs_exit(struct sec_dev *sec) +{ + debugfs_remove_recursive(sec->qm.debug.debug_root); +} + +static const struct hisi_qm_err_ini sec_err_ini = { + .hw_err_enable = sec_hw_error_enable, + .hw_err_disable = sec_hw_error_disable, + .err_info = { + .ce = QM_BASE_CE, + .nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT | + QM_ACC_WB_NOT_READY_TIMEOUT, + .fe = 0, + .msi = QM_DB_RANDOM_INVALID, + } +}; + +static int sec_pf_probe_init(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + int ret; + + switch (qm->ver) { + case QM_HW_V1: + qm->ctrl_qp_num = SEC_QUEUE_NUM_V1; + break; + + case QM_HW_V2: + qm->ctrl_qp_num = SEC_QUEUE_NUM_V2; + break; + + default: + return -EINVAL; + } + + qm->err_ini = &sec_err_ini; + + ret = sec_set_user_domain_and_cache(sec); + if (ret) + return ret; + + hisi_qm_dev_err_init(qm); + sec_debug_regs_clear(qm); + + return 0; +} + +static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) +{ + enum qm_hw_ver rev_id; + + rev_id = hisi_qm_get_hw_version(pdev); + if (rev_id == QM_HW_UNKNOWN) + return -ENODEV; + + qm->pdev = pdev; + qm->ver = rev_id; + + qm->sqe_size = SEC_SQE_SIZE; + qm->dev_name = sec_name; + qm->fun_type = (pdev->device == SEC_PF_PCI_DEVICE_ID) ? + QM_HW_PF : QM_HW_VF; + qm->use_dma_api = true; + + return hisi_qm_init(qm); +} + +static void sec_qm_uninit(struct hisi_qm *qm) +{ + hisi_qm_uninit(qm); +} + +static int sec_probe_init(struct hisi_qm *qm, struct sec_dev *sec) +{ + int ret; + + /* + * WQ_HIGHPRI: SEC request must be low delayed, + * so need a high priority workqueue. + * WQ_UNBOUND: SEC task is likely with long + * running CPU intensive workloads. + */ + qm->wq = alloc_workqueue("%s", WQ_HIGHPRI | + WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus(), + pci_name(qm->pdev)); + if (!qm->wq) { + pci_err(qm->pdev, "fail to alloc workqueue\n"); + return -ENOMEM; + } + + if (qm->fun_type == QM_HW_PF) { + qm->qp_base = SEC_PF_DEF_Q_BASE; + qm->qp_num = pf_q_num; + qm->debug.curr_qm_qp_num = pf_q_num; + + ret = sec_pf_probe_init(sec); + if (ret) + goto err_probe_uninit; + } else if (qm->fun_type == QM_HW_VF) { + /* + * have no way to get qm configure in VM in v1 hardware, + * so currently force PF to uses SEC_PF_DEF_Q_NUM, and force + * to trigger only one VF in v1 hardware. + * v2 hardware has no such problem. + */ + if (qm->ver == QM_HW_V1) { + qm->qp_base = SEC_PF_DEF_Q_NUM; + qm->qp_num = SEC_QUEUE_NUM_V1 - SEC_PF_DEF_Q_NUM; + } else if (qm->ver == QM_HW_V2) { + /* v2 starts to support get vft by mailbox */ + ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num); + if (ret) + goto err_probe_uninit; + } + } else { + ret = -ENODEV; + goto err_probe_uninit; + } + + return 0; +err_probe_uninit: + destroy_workqueue(qm->wq); + return ret; +} + +static void sec_probe_uninit(struct hisi_qm *qm) +{ + hisi_qm_dev_err_uninit(qm); + + destroy_workqueue(qm->wq); +} + +static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct sec_dev *sec; + struct hisi_qm *qm; + int ret; + + sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL); + if (!sec) + return -ENOMEM; + + pci_set_drvdata(pdev, sec); + + sec->ctx_q_num = ctx_q_num; + + qm = &sec->qm; + + ret = sec_qm_init(qm, pdev); + if (ret) { + pci_err(pdev, "Failed to pre init qm!\n"); + return ret; + } + + ret = sec_probe_init(qm, sec); + if (ret) { + pci_err(pdev, "Failed to probe!\n"); + goto err_qm_uninit; + } + + ret = hisi_qm_start(qm); + if (ret) { + pci_err(pdev, "Failed to start sec qm!\n"); + goto err_probe_uninit; + } + + ret = sec_debugfs_init(sec); + if (ret) + pci_warn(pdev, "Failed to init debugfs!\n"); + + sec_add_to_list(sec); + + ret = sec_register_to_crypto(); + if (ret < 0) { + pr_err("Failed to register driver to crypto.\n"); + goto err_remove_from_list; + } + + return 0; + +err_remove_from_list: + sec_remove_from_list(sec); + sec_debugfs_exit(sec); + hisi_qm_stop(qm); + +err_probe_uninit: + sec_probe_uninit(qm); + +err_qm_uninit: + sec_qm_uninit(qm); + + return ret; +} + +/* now we only support equal assignment */ +static int sec_vf_q_assign(struct sec_dev *sec, u32 num_vfs) +{ + struct hisi_qm *qm = &sec->qm; + u32 qp_num = qm->qp_num; + u32 q_base = qp_num; + u32 q_num, remain_q_num; + int i, j, ret; + + if (!num_vfs) + return -EINVAL; + + remain_q_num = qm->ctrl_qp_num - qp_num; + q_num = remain_q_num / num_vfs; + + for (i = 1; i <= num_vfs; i++) { + if (i == num_vfs) + q_num += remain_q_num % num_vfs; + ret = hisi_qm_set_vft(qm, i, q_base, q_num); + if (ret) { + for (j = i; j > 0; j--) + hisi_qm_set_vft(qm, j, 0, 0); + return ret; + } + q_base += q_num; + } + + return 0; +} + +static int sec_clear_vft_config(struct sec_dev *sec) +{ + struct hisi_qm *qm = &sec->qm; + u32 num_vfs = sec->num_vfs; + int ret; + u32 i; + + for (i = 1; i <= num_vfs; i++) { + ret = hisi_qm_set_vft(qm, i, 0, 0); + if (ret) + return ret; + } + + sec->num_vfs = 0; + + return 0; +} + +static int sec_sriov_enable(struct pci_dev *pdev, int max_vfs) +{ + struct sec_dev *sec = pci_get_drvdata(pdev); + int pre_existing_vfs, ret; + u32 num_vfs; + + pre_existing_vfs = pci_num_vf(pdev); + + if (pre_existing_vfs) { + pci_err(pdev, "Can't enable VF. Please disable at first!\n"); + return 0; + } + + num_vfs = min_t(u32, max_vfs, SEC_VF_NUM); + + ret = sec_vf_q_assign(sec, num_vfs); + if (ret) { + pci_err(pdev, "Can't assign queues for VF!\n"); + return ret; + } + + sec->num_vfs = num_vfs; + + ret = pci_enable_sriov(pdev, num_vfs); + if (ret) { + pci_err(pdev, "Can't enable VF!\n"); + sec_clear_vft_config(sec); + return ret; + } + + return num_vfs; +} + +static int sec_sriov_disable(struct pci_dev *pdev) +{ + struct sec_dev *sec = pci_get_drvdata(pdev); + + if (pci_vfs_assigned(pdev)) { + pci_err(pdev, "Can't disable VFs while VFs are assigned!\n"); + return -EPERM; + } + + /* remove in sec_pci_driver will be called to free VF resources */ + pci_disable_sriov(pdev); + + return sec_clear_vft_config(sec); +} + +static int sec_sriov_configure(struct pci_dev *pdev, int num_vfs) +{ + if (num_vfs) + return sec_sriov_enable(pdev, num_vfs); + else + return sec_sriov_disable(pdev); +} + +static void sec_remove(struct pci_dev *pdev) +{ + struct sec_dev *sec = pci_get_drvdata(pdev); + struct hisi_qm *qm = &sec->qm; + + sec_unregister_from_crypto(); + + sec_remove_from_list(sec); + + if (qm->fun_type == QM_HW_PF && sec->num_vfs) + (void)sec_sriov_disable(pdev); + + sec_debugfs_exit(sec); + + (void)hisi_qm_stop(qm); + + if (qm->fun_type == QM_HW_PF) + sec_debug_regs_clear(qm); + + sec_probe_uninit(qm); + + sec_qm_uninit(qm); +} + +static void sec_log_hw_error(struct sec_dev *sec, u32 err_sts) +{ + const struct sec_hw_error *errs = sec_hw_errors; + struct device *dev = &sec->qm.pdev->dev; + u32 err_val; + + while (errs->msg) { + if (errs->int_msk & err_sts) { + dev_err(dev, "%s [error status=0x%x] found\n", + errs->msg, errs->int_msk); + + if (SEC_CORE_INT_STATUS_M_ECC & err_sts) { + err_val = readl(sec->qm.io_base + + SEC_CORE_SRAM_ECC_ERR_INFO); + dev_err(dev, "multi ecc sram num=0x%x\n", + SEC_ECC_NUM(err_val)); + dev_err(dev, "multi ecc sram addr=0x%x\n", + SEC_ECC_ADDR(err_val)); + } + } + errs++; + } +} + +static pci_ers_result_t sec_hw_error_handle(struct sec_dev *sec) +{ + u32 err_sts; + + /* read err sts */ + err_sts = readl(sec->qm.io_base + SEC_CORE_INT_STATUS); + if (err_sts) { + sec_log_hw_error(sec, err_sts); + + /* clear error interrupts */ + writel(err_sts, sec->qm.io_base + SEC_CORE_INT_SOURCE); + + return PCI_ERS_RESULT_NEED_RESET; + } + + return PCI_ERS_RESULT_RECOVERED; +} + +static pci_ers_result_t sec_process_hw_error(struct pci_dev *pdev) +{ + struct sec_dev *sec = pci_get_drvdata(pdev); + pci_ers_result_t qm_ret, sec_ret; + + if (!sec) { + pci_err(pdev, "Can't recover error during device init\n"); + return PCI_ERS_RESULT_NONE; + } + + /* log qm error */ + qm_ret = hisi_qm_hw_error_handle(&sec->qm); + + /* log sec error */ + sec_ret = sec_hw_error_handle(sec); + + return (qm_ret == PCI_ERS_RESULT_NEED_RESET || + sec_ret == PCI_ERS_RESULT_NEED_RESET) ? + PCI_ERS_RESULT_NEED_RESET : PCI_ERS_RESULT_RECOVERED; +} + +static pci_ers_result_t sec_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + if (pdev->is_virtfn) + return PCI_ERS_RESULT_NONE; + + pci_info(pdev, "PCI error detected, state(=%d)!!\n", state); + if (state == pci_channel_io_perm_failure) + return PCI_ERS_RESULT_DISCONNECT; + + return sec_process_hw_error(pdev); +} + +static const struct pci_error_handlers sec_err_handler = { + .error_detected = sec_error_detected, +}; + +static struct pci_driver sec_pci_driver = { + .name = "hisi_sec2", + .id_table = sec_dev_ids, + .probe = sec_probe, + .remove = sec_remove, + .err_handler = &sec_err_handler, + .sriov_configure = sec_sriov_configure, +}; + +static void sec_register_debugfs(void) +{ + if (!debugfs_initialized()) + return; + + sec_debugfs_root = debugfs_create_dir("hisi_sec2", NULL); +} + +static void sec_unregister_debugfs(void) +{ + debugfs_remove_recursive(sec_debugfs_root); +} + +static int __init sec_init(void) +{ + int ret; + + sec_register_debugfs(); + + ret = pci_register_driver(&sec_pci_driver); + if (ret < 0) { + sec_unregister_debugfs(); + pr_err("Failed to register pci driver.\n"); + return ret; + } + + return 0; +} + +static void __exit sec_exit(void) +{ + pci_unregister_driver(&sec_pci_driver); + sec_unregister_debugfs(); +} + +module_init(sec_init); +module_exit(sec_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Zaibo Xu "); +MODULE_AUTHOR("Longfang Liu "); +MODULE_AUTHOR("Wei Zhang "); +MODULE_DESCRIPTION("Driver for HiSilicon SEC accelerator"); --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/sgl.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/sgl.c @@ -2,37 +2,13 @@ /* Copyright (c) 2019 HiSilicon Limited. */ #include #include -#include "./sgl.h" +#include +#include "qm.h" #define HISI_ACC_SGL_SGE_NR_MIN 1 -#define HISI_ACC_SGL_SGE_NR_MAX 255 -#define HISI_ACC_SGL_SGE_NR_DEF 10 #define HISI_ACC_SGL_NR_MAX 256 #define HISI_ACC_SGL_ALIGN_SIZE 64 - -static int acc_sgl_sge_set(const char *val, const struct kernel_param *kp) -{ - int ret; - u32 n; - - if (!val) - return -EINVAL; - - ret = kstrtou32(val, 10, &n); - if (ret != 0 || n > HISI_ACC_SGL_SGE_NR_MAX || n == 0) - return -EINVAL; - - return param_set_int(val, kp); -} - -static const struct kernel_param_ops acc_sgl_sge_ops = { - .set = acc_sgl_sge_set, - .get = param_get_int, -}; - -static u32 acc_sgl_sge_nr = HISI_ACC_SGL_SGE_NR_DEF; -module_param_cb(acc_sgl_sge_nr, &acc_sgl_sge_ops, &acc_sgl_sge_nr, 0444); -MODULE_PARM_DESC(acc_sgl_sge_nr, "Number of sge in sgl(1-255)"); +#define HISI_ACC_MEM_BLOCK_NR 5 struct acc_hw_sge { dma_addr_t buf; @@ -55,37 +31,91 @@ struct acc_hw_sge sge_entries[]; } __aligned(1); +struct hisi_acc_sgl_pool { + struct mem_block { + struct hisi_acc_hw_sgl *sgl; + dma_addr_t sgl_dma; + size_t size; + } mem_block[HISI_ACC_MEM_BLOCK_NR]; + u32 sgl_num_per_block; + u32 block_num; + u32 count; + u32 sge_nr; + size_t sgl_size; +}; + /** * hisi_acc_create_sgl_pool() - Create a hw sgl pool. * @dev: The device which hw sgl pool belongs to. - * @pool: Pointer of pool. * @count: Count of hisi_acc_hw_sgl in pool. + * @sge_nr: The count of sge in hw_sgl * * This function creates a hw sgl pool, after this user can get hw sgl memory * from it. */ -int hisi_acc_create_sgl_pool(struct device *dev, - struct hisi_acc_sgl_pool *pool, u32 count) +struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, + u32 count, u32 sge_nr) { - u32 sgl_size; - u32 size; + u32 sgl_size, block_size, sgl_num_per_block, block_num, remain_sgl = 0; + struct hisi_acc_sgl_pool *pool; + struct mem_block *block; + u32 i, j; - if (!dev || !pool || !count) - return -EINVAL; + if (!dev || !count || !sge_nr || sge_nr > HISI_ACC_SGL_SGE_NR_MAX) + return ERR_PTR(-EINVAL); - sgl_size = sizeof(struct acc_hw_sge) * acc_sgl_sge_nr + + sgl_size = sizeof(struct acc_hw_sge) * sge_nr + sizeof(struct hisi_acc_hw_sgl); - size = sgl_size * count; + block_size = PAGE_SIZE * (1 << (MAX_ORDER - 1)); + sgl_num_per_block = block_size / sgl_size; + block_num = count / sgl_num_per_block; + remain_sgl = count % sgl_num_per_block; + + if ((!remain_sgl && block_num > HISI_ACC_MEM_BLOCK_NR) || + (remain_sgl > 0 && block_num > HISI_ACC_MEM_BLOCK_NR - 1)) + return ERR_PTR(-EINVAL); + + pool = kzalloc(sizeof(*pool), GFP_KERNEL); + if (!pool) + return ERR_PTR(-ENOMEM); + block = pool->mem_block; + + for (i = 0; i < block_num; i++) { + block[i].sgl = dma_alloc_coherent(dev, block_size, + &block[i].sgl_dma, + GFP_KERNEL); + if (!block[i].sgl) + goto err_free_mem; + + block[i].size = block_size; + } - pool->sgl = dma_alloc_coherent(dev, size, &pool->sgl_dma, GFP_KERNEL); - if (!pool->sgl) - return -ENOMEM; + if (remain_sgl > 0) { + block[i].sgl = dma_alloc_coherent(dev, remain_sgl * sgl_size, + &block[i].sgl_dma, + GFP_KERNEL); + if (!block[i].sgl) + goto err_free_mem; - pool->size = size; + block[i].size = remain_sgl * sgl_size; + } + + pool->sgl_num_per_block = sgl_num_per_block; + pool->block_num = remain_sgl ? block_num + 1 : block_num; pool->count = count; pool->sgl_size = sgl_size; + pool->sge_nr = sge_nr; + + return pool; - return 0; +err_free_mem: + for (j = 0; j < i; j++) { + dma_free_coherent(dev, block_size, block[j].sgl, + block[j].sgl_dma); + memset(block + j, 0, sizeof(*block)); + } + kfree(pool); + return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL_GPL(hisi_acc_create_sgl_pool); @@ -98,38 +128,57 @@ */ void hisi_acc_free_sgl_pool(struct device *dev, struct hisi_acc_sgl_pool *pool) { - dma_free_coherent(dev, pool->size, pool->sgl, pool->sgl_dma); - memset(pool, 0, sizeof(struct hisi_acc_sgl_pool)); + struct mem_block *block; + int i; + + if (!dev || !pool) + return; + + block = pool->mem_block; + + for (i = 0; i < pool->block_num; i++) + dma_free_coherent(dev, block[i].size, block[i].sgl, + block[i].sgl_dma); + + kfree(pool); } EXPORT_SYMBOL_GPL(hisi_acc_free_sgl_pool); -struct hisi_acc_hw_sgl *acc_get_sgl(struct hisi_acc_sgl_pool *pool, u32 index, - dma_addr_t *hw_sgl_dma) +static struct hisi_acc_hw_sgl *acc_get_sgl(struct hisi_acc_sgl_pool *pool, + u32 index, dma_addr_t *hw_sgl_dma) { - if (!pool || !hw_sgl_dma || index >= pool->count || !pool->sgl) + struct mem_block *block; + u32 block_index, offset; + + if (!pool || !hw_sgl_dma || index >= pool->count) return ERR_PTR(-EINVAL); - *hw_sgl_dma = pool->sgl_dma + pool->sgl_size * index; - return (void *)pool->sgl + pool->sgl_size * index; -} + block = pool->mem_block; + block_index = index / pool->sgl_num_per_block; + offset = index % pool->sgl_num_per_block; -void acc_put_sgl(struct hisi_acc_sgl_pool *pool, u32 index) {} + *hw_sgl_dma = block[block_index].sgl_dma + pool->sgl_size * offset; + return (void *)block[block_index].sgl + pool->sgl_size * offset; +} static void sg_map_to_hw_sg(struct scatterlist *sgl, struct acc_hw_sge *hw_sge) { - hw_sge->buf = sgl->dma_address; - hw_sge->len = sgl->dma_length; + hw_sge->buf = sg_dma_address(sgl); + hw_sge->len = cpu_to_le32(sg_dma_len(sgl)); } static void inc_hw_sgl_sge(struct hisi_acc_hw_sgl *hw_sgl) { - hw_sgl->entry_sum_in_sgl++; + u16 var = le16_to_cpu(hw_sgl->entry_sum_in_sgl); + + var++; + hw_sgl->entry_sum_in_sgl = cpu_to_le16(var); } static void update_hw_sgl_sum_sge(struct hisi_acc_hw_sgl *hw_sgl, u16 sum) { - hw_sgl->entry_sum_in_chain = sum; + hw_sgl->entry_sum_in_chain = cpu_to_le16(sum); } /** @@ -153,10 +202,13 @@ dma_addr_t curr_sgl_dma = 0; struct acc_hw_sge *curr_hw_sge; struct scatterlist *sg; - int sg_n = sg_nents(sgl); - int i, ret; + int i, ret, sg_n; + + if (!dev || !sgl || !pool || !hw_sgl_dma) + return ERR_PTR(-EINVAL); - if (!dev || !sgl || !pool || !hw_sgl_dma || sg_n > acc_sgl_sge_nr) + sg_n = sg_nents(sgl); + if (sg_n > pool->sge_nr) return ERR_PTR(-EINVAL); ret = dma_map_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); @@ -164,11 +216,12 @@ return ERR_PTR(-EINVAL); curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma); - if (!curr_hw_sgl) { - ret = -ENOMEM; - goto err_unmap_sg; + if (IS_ERR(curr_hw_sgl)) { + dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); + return ERR_PTR(-ENOMEM); + } - curr_hw_sgl->entry_length_in_sgl = acc_sgl_sge_nr; + curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr); curr_hw_sge = curr_hw_sgl->sge_entries; for_each_sg(sgl, sg, sg_n, i) { @@ -177,14 +230,10 @@ curr_hw_sge++; } - update_hw_sgl_sum_sge(curr_hw_sgl, acc_sgl_sge_nr); + update_hw_sgl_sum_sge(curr_hw_sgl, pool->sge_nr); *hw_sgl_dma = curr_sgl_dma; return curr_hw_sgl; - -err_unmap_sg: - dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL); - return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl); @@ -201,6 +250,9 @@ void hisi_acc_sg_buf_unmap(struct device *dev, struct scatterlist *sgl, struct hisi_acc_hw_sgl *hw_sgl) { + if (!dev || !sgl || !hw_sgl) + return; + dma_unmap_sg(dev, sgl, sg_nents(sgl), DMA_BIDIRECTIONAL); hw_sgl->entry_sum_in_chain = 0; --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/zip/zip.h +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/zip/zip.h @@ -8,10 +8,13 @@ #include #include "../qm.h" -#include "../sgl.h" /* hisi_zip_sqe dw3 */ #define HZIP_BD_STATUS_M GENMASK(7, 0) +/* hisi_zip_sqe dw7 */ +#define HZIP_IN_SGE_DATA_OFFSET_M GENMASK(23, 0) +/* hisi_zip_sqe dw8 */ +#define HZIP_OUT_SGE_DATA_OFFSET_M GENMASK(23, 0) /* hisi_zip_sqe dw9 */ #define HZIP_REQ_TYPE_M GENMASK(7, 0) #define HZIP_ALG_TYPE_ZLIB 0x02 --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/zip/zip_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -22,6 +22,7 @@ #define HZIP_CTX_Q_NUM 2 #define HZIP_GZIP_HEAD_BUF 256 #define HZIP_ALG_PRIORITY 300 +#define HZIP_SGL_SGE_NR 10 static const u8 zlib_head[HZIP_ZLIB_HEAD_SIZE] = {0x78, 0x9c}; static const u8 gzip_head[HZIP_GZIP_HEAD_SIZE] = {0x1f, 0x8b, 0x08, 0x0, 0x0, @@ -41,14 +42,12 @@ #define TO_HEAD(req_type) \ (((req_type) == HZIP_ALG_TYPE_ZLIB) ? zlib_head : \ - ((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : 0) \ + ((req_type) == HZIP_ALG_TYPE_GZIP) ? gzip_head : NULL) \ struct hisi_zip_req { struct acomp_req *req; - struct scatterlist *src; - struct scatterlist *dst; - size_t slen; - size_t dlen; + int sskip; + int dskip; struct hisi_acc_hw_sgl *hw_src; struct hisi_acc_hw_sgl *hw_dst; dma_addr_t dma_src; @@ -67,7 +66,7 @@ struct hisi_qp *qp; struct hisi_zip_sqe zip_sqe; struct hisi_zip_req_q req_q; - struct hisi_acc_sgl_pool sgl_pool; + struct hisi_acc_sgl_pool *sgl_pool; struct hisi_zip *zip_dev; struct hisi_zip_ctx *ctx; }; @@ -78,6 +77,30 @@ struct hisi_zip_qp_ctx qp_ctx[HZIP_CTX_Q_NUM]; }; +static int sgl_sge_nr_set(const char *val, const struct kernel_param *kp) +{ + int ret; + u16 n; + + if (!val) + return -EINVAL; + + ret = kstrtou16(val, 10, &n); + if (ret || n == 0 || n > HISI_ACC_SGL_SGE_NR_MAX) + return -EINVAL; + + return param_set_int(val, kp); +} + +static const struct kernel_param_ops sgl_sge_nr_ops = { + .set = sgl_sge_nr_set, + .get = param_get_int, +}; + +static u16 sgl_sge_nr = HZIP_SGL_SGE_NR; +module_param_cb(sgl_sge_nr, &sgl_sge_nr_ops, &sgl_sge_nr, 0444); +MODULE_PARM_DESC(sgl_sge_nr, "Number of sge in sgl(1-255)"); + static void hisi_zip_config_buf_type(struct hisi_zip_sqe *sqe, u8 buf_type) { u32 val; @@ -94,13 +117,15 @@ static void hisi_zip_fill_sqe(struct hisi_zip_sqe *sqe, u8 req_type, dma_addr_t s_addr, dma_addr_t d_addr, u32 slen, - u32 dlen) + u32 dlen, int sskip, int dskip) { memset(sqe, 0, sizeof(struct hisi_zip_sqe)); - sqe->input_data_length = slen; + sqe->input_data_length = slen - sskip; + sqe->dw7 = FIELD_PREP(HZIP_IN_SGE_DATA_OFFSET_M, sskip); + sqe->dw8 = FIELD_PREP(HZIP_OUT_SGE_DATA_OFFSET_M, dskip); sqe->dw9 = FIELD_PREP(HZIP_REQ_TYPE_M, req_type); - sqe->dest_avail_out = dlen; + sqe->dest_avail_out = dlen - dskip; sqe->source_addr_l = lower_32_bits(s_addr); sqe->source_addr_h = upper_32_bits(s_addr); sqe->dest_addr_l = lower_32_bits(d_addr); @@ -265,14 +290,15 @@ static int hisi_zip_create_sgl_pool(struct hisi_zip_ctx *ctx) { struct hisi_zip_qp_ctx *tmp; - int i, ret; + struct device *dev; + int i; for (i = 0; i < HZIP_CTX_Q_NUM; i++) { tmp = &ctx->qp_ctx[i]; - ret = hisi_acc_create_sgl_pool(&tmp->qp->qm->pdev->dev, - &tmp->sgl_pool, - QM_Q_DEPTH << 1); - if (ret < 0) { + dev = &tmp->qp->qm->pdev->dev; + tmp->sgl_pool = hisi_acc_create_sgl_pool(dev, QM_Q_DEPTH << 1, + sgl_sge_nr); + if (IS_ERR(tmp->sgl_pool)) { if (i == 1) goto err_free_sgl_pool0; return -ENOMEM; @@ -283,7 +309,7 @@ err_free_sgl_pool0: hisi_acc_free_sgl_pool(&ctx->qp_ctx[QPC_COMP].qp->qm->pdev->dev, - &ctx->qp_ctx[QPC_COMP].sgl_pool); + ctx->qp_ctx[QPC_COMP].sgl_pool); return -ENOMEM; } @@ -293,7 +319,7 @@ for (i = 0; i < HZIP_CTX_Q_NUM; i++) hisi_acc_free_sgl_pool(&ctx->qp_ctx[i].qp->qm->pdev->dev, - &ctx->qp_ctx[i].sgl_pool); + ctx->qp_ctx[i].sgl_pool); } static void hisi_zip_remove_req(struct hisi_zip_qp_ctx *qp_ctx, @@ -301,11 +327,6 @@ { struct hisi_zip_req_q *req_q = &qp_ctx->req_q; - if (qp_ctx->qp->alg_type == HZIP_ALG_TYPE_COMP) - kfree(req->dst); - else - kfree(req->src); - write_lock(&req_q->req_lock); clear_bit(req->req_id, req_q->req_bitmap); memset(req, 0, sizeof(struct hisi_zip_req)); @@ -333,8 +354,8 @@ } dlen = sqe->produced; - hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src); - hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst); + hisi_acc_sg_buf_unmap(dev, acomp_req->src, req->hw_src); + hisi_acc_sg_buf_unmap(dev, acomp_req->dst, req->hw_dst); head_size = (qp->alg_type == 0) ? TO_HEAD_SIZE(qp->req_type) : 0; acomp_req->dlen = dlen + head_size; @@ -428,20 +449,6 @@ } } -static int get_sg_skip_bytes(struct scatterlist *sgl, size_t bytes, - size_t remains, struct scatterlist **out) -{ -#define SPLIT_NUM 2 - size_t split_sizes[SPLIT_NUM]; - int out_mapped_nents[SPLIT_NUM]; - - split_sizes[0] = bytes; - split_sizes[1] = remains; - - return sg_split(sgl, 0, 0, SPLIT_NUM, split_sizes, out, - out_mapped_nents, GFP_KERNEL); -} - static struct hisi_zip_req *hisi_zip_create_req(struct acomp_req *req, struct hisi_zip_qp_ctx *qp_ctx, size_t head_size, bool is_comp) @@ -449,31 +456,7 @@ struct hisi_zip_req_q *req_q = &qp_ctx->req_q; struct hisi_zip_req *q = req_q->q; struct hisi_zip_req *req_cache; - struct scatterlist *out[2]; - struct scatterlist *sgl; - size_t len; - int ret, req_id; - - /* - * remove/add zlib/gzip head, as hardware operations do not include - * comp head. so split req->src to get sgl without heads in acomp, or - * add comp head to req->dst ahead of that hardware output compressed - * data in sgl splited from req->dst without comp head. - */ - if (is_comp) { - sgl = req->dst; - len = req->dlen - head_size; - } else { - sgl = req->src; - len = req->slen - head_size; - } - - ret = get_sg_skip_bytes(sgl, head_size, len, out); - if (ret) - return ERR_PTR(ret); - - /* sgl for comp head is useless, so free it now */ - kfree(out[0]); + int req_id; write_lock(&req_q->req_lock); @@ -481,7 +464,6 @@ if (req_id >= req_q->size) { write_unlock(&req_q->req_lock); dev_dbg(&qp_ctx->qp->qm->pdev->dev, "req cache is full!\n"); - kfree(out[1]); return ERR_PTR(-EBUSY); } set_bit(req_id, req_q->req_bitmap); @@ -489,16 +471,13 @@ req_cache = q + req_id; req_cache->req_id = req_id; req_cache->req = req; + if (is_comp) { - req_cache->src = req->src; - req_cache->dst = out[1]; - req_cache->slen = req->slen; - req_cache->dlen = req->dlen - head_size; + req_cache->sskip = 0; + req_cache->dskip = head_size; } else { - req_cache->src = out[1]; - req_cache->dst = req->dst; - req_cache->slen = req->slen - head_size; - req_cache->dlen = req->dlen; + req_cache->sskip = head_size; + req_cache->dskip = 0; } write_unlock(&req_q->req_lock); @@ -510,23 +489,24 @@ struct hisi_zip_qp_ctx *qp_ctx) { struct hisi_zip_sqe *zip_sqe = &qp_ctx->zip_sqe; + struct acomp_req *a_req = req->req; struct hisi_qp *qp = qp_ctx->qp; struct device *dev = &qp->qm->pdev->dev; - struct hisi_acc_sgl_pool *pool = &qp_ctx->sgl_pool; + struct hisi_acc_sgl_pool *pool = qp_ctx->sgl_pool; dma_addr_t input; dma_addr_t output; int ret; - if (!req->src || !req->slen || !req->dst || !req->dlen) + if (!a_req->src || !a_req->slen || !a_req->dst || !a_req->dlen) return -EINVAL; - req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->src, pool, + req->hw_src = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->src, pool, req->req_id << 1, &input); if (IS_ERR(req->hw_src)) return PTR_ERR(req->hw_src); req->dma_src = input; - req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, req->dst, pool, + req->hw_dst = hisi_acc_sg_buf_map_to_hw_sgl(dev, a_req->dst, pool, (req->req_id << 1) + 1, &output); if (IS_ERR(req->hw_dst)) { @@ -535,8 +515,8 @@ } req->dma_dst = output; - hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, req->slen, - req->dlen); + hisi_zip_fill_sqe(zip_sqe, qp->req_type, input, output, a_req->slen, + a_req->dlen, req->sskip, req->dskip); hisi_zip_config_buf_type(zip_sqe, HZIP_SGL); hisi_zip_config_tag(zip_sqe, req->req_id); @@ -548,9 +528,9 @@ return -EINPROGRESS; err_unmap_output: - hisi_acc_sg_buf_unmap(dev, req->dst, req->hw_dst); + hisi_acc_sg_buf_unmap(dev, a_req->dst, req->hw_dst); err_unmap_input: - hisi_acc_sg_buf_unmap(dev, req->src, req->hw_src); + hisi_acc_sg_buf_unmap(dev, a_req->src, req->hw_src); return ret; } --- linux-oracle-5.4.0.orig/drivers/crypto/hisilicon/zip/zip_main.c +++ linux-oracle-5.4.0/drivers/crypto/hisilicon/zip/zip_main.c @@ -60,13 +60,13 @@ #define HZIP_CORE_DEBUG_DECOMP_5 0x309000 #define HZIP_CORE_INT_SOURCE 0x3010A0 -#define HZIP_CORE_INT_MASK 0x3010A4 +#define HZIP_CORE_INT_MASK_REG 0x3010A4 #define HZIP_CORE_INT_STATUS 0x3010AC #define HZIP_CORE_INT_STATUS_M_ECC BIT(1) #define HZIP_CORE_SRAM_ECC_ERR_INFO 0x301148 #define SRAM_ECC_ERR_NUM_SHIFT 16 #define SRAM_ECC_ERR_ADDR_SHIFT 24 -#define HZIP_CORE_INT_DISABLE 0x000007FF +#define HZIP_CORE_INT_MASK_ALL GENMASK(10, 0) #define HZIP_COMP_CORE_NUM 2 #define HZIP_DECOMP_CORE_NUM 6 #define HZIP_CORE_NUM (HZIP_COMP_CORE_NUM + \ @@ -79,47 +79,80 @@ #define HZIP_SOFT_CTRL_CNT_CLR_CE 0x301000 #define SOFT_CTRL_CNT_CLR_CE_BIT BIT(0) -#define HZIP_NUMA_DISTANCE 100 #define HZIP_BUF_SIZE 22 static const char hisi_zip_name[] = "hisi_zip"; static struct dentry *hzip_debugfs_root; -LIST_HEAD(hisi_zip_list); -DEFINE_MUTEX(hisi_zip_list_lock); +static LIST_HEAD(hisi_zip_list); +static DEFINE_MUTEX(hisi_zip_list_lock); -#ifdef CONFIG_NUMA -static struct hisi_zip *find_zip_device_numa(int node) +struct hisi_zip_resource { + struct hisi_zip *hzip; + int distance; + struct list_head list; +}; + +static void free_list(struct list_head *head) { - struct hisi_zip *zip = NULL; - struct hisi_zip *hisi_zip; - int min_distance = HZIP_NUMA_DISTANCE; - struct device *dev; + struct hisi_zip_resource *res, *tmp; - list_for_each_entry(hisi_zip, &hisi_zip_list, list) { - dev = &hisi_zip->qm.pdev->dev; - if (node_distance(dev->numa_node, node) < min_distance) { - zip = hisi_zip; - min_distance = node_distance(dev->numa_node, node); - } + list_for_each_entry_safe(res, tmp, head, list) { + list_del(&res->list); + kfree(res); } - - return zip; } -#endif struct hisi_zip *find_zip_device(int node) { - struct hisi_zip *zip = NULL; + struct hisi_zip_resource *res, *tmp; + struct hisi_zip *ret = NULL; + struct hisi_zip *hisi_zip; + struct list_head *n; + struct device *dev; + LIST_HEAD(head); mutex_lock(&hisi_zip_list_lock); -#ifdef CONFIG_NUMA - zip = find_zip_device_numa(node); -#else - zip = list_first_entry(&hisi_zip_list, struct hisi_zip, list); -#endif + + if (IS_ENABLED(CONFIG_NUMA)) { + list_for_each_entry(hisi_zip, &hisi_zip_list, list) { + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) + goto err; + + dev = &hisi_zip->qm.pdev->dev; + res->hzip = hisi_zip; + res->distance = node_distance(dev_to_node(dev), node); + + n = &head; + list_for_each_entry(tmp, &head, list) { + if (res->distance < tmp->distance) { + n = &tmp->list; + break; + } + } + list_add_tail(&res->list, n); + } + + list_for_each_entry(tmp, &head, list) { + if (hisi_qm_get_free_qp_num(&tmp->hzip->qm)) { + ret = tmp->hzip; + break; + } + } + + free_list(&head); + } else { + ret = list_first_entry(&hisi_zip_list, struct hisi_zip, list); + } + mutex_unlock(&hisi_zip_list_lock); - return zip; + return ret; + +err: + free_list(&head); + mutex_unlock(&hisi_zip_list_lock); + return NULL; } struct hisi_zip_hw_error { @@ -267,6 +300,10 @@ static int uacce_mode; module_param(uacce_mode, int, 0); +static u32 vfs_num; +module_param(vfs_num, uint, 0444); +MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63)"); + static const struct pci_device_id hisi_zip_dev_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ZIP_PF) }, { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_ZIP_VF) }, @@ -329,28 +366,26 @@ FIELD_PREP(CQC_CACHE_WB_THRD, 1), base + QM_CACHE_CTL); } -static void hisi_zip_hw_error_set_state(struct hisi_zip *hisi_zip, bool state) +static void hisi_zip_hw_error_enable(struct hisi_qm *qm) { - struct hisi_qm *qm = &hisi_zip->qm; - if (qm->ver == QM_HW_V1) { - writel(HZIP_CORE_INT_DISABLE, qm->io_base + HZIP_CORE_INT_MASK); - dev_info(&qm->pdev->dev, "ZIP v%d does not support hw error handle\n", - qm->ver); + writel(HZIP_CORE_INT_MASK_ALL, + qm->io_base + HZIP_CORE_INT_MASK_REG); + dev_info(&qm->pdev->dev, "Does not support hw error handle\n"); return; } - if (state) { - /* clear ZIP hw error source if having */ - writel(HZIP_CORE_INT_DISABLE, hisi_zip->qm.io_base + - HZIP_CORE_INT_SOURCE); - /* enable ZIP hw error interrupts */ - writel(0, hisi_zip->qm.io_base + HZIP_CORE_INT_MASK); - } else { - /* disable ZIP hw error interrupts */ - writel(HZIP_CORE_INT_DISABLE, - hisi_zip->qm.io_base + HZIP_CORE_INT_MASK); - } + /* clear ZIP hw error source if having */ + writel(HZIP_CORE_INT_MASK_ALL, qm->io_base + HZIP_CORE_INT_SOURCE); + + /* enable ZIP hw error interrupts */ + writel(0, qm->io_base + HZIP_CORE_INT_MASK_REG); +} + +static void hisi_zip_hw_error_disable(struct hisi_qm *qm) +{ + /* disable ZIP hw error interrupts */ + writel(HZIP_CORE_INT_MASK_ALL, qm->io_base + HZIP_CORE_INT_MASK_REG); } static inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file) @@ -511,7 +546,7 @@ struct hisi_qm *qm = &hisi_zip->qm; struct device *dev = &qm->pdev->dev; struct debugfs_regset32 *regset; - struct dentry *tmp_d, *tmp; + struct dentry *tmp_d; char buf[HZIP_BUF_SIZE]; int i; @@ -521,10 +556,6 @@ else sprintf(buf, "decomp_core%d", i - HZIP_COMP_CORE_NUM); - tmp_d = debugfs_create_dir(buf, ctrl->debug_root); - if (!tmp_d) - return -ENOENT; - regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL); if (!regset) return -ENOENT; @@ -533,9 +564,8 @@ regset->nregs = ARRAY_SIZE(hzip_dfx_regs); regset->base = qm->io_base + core_offsets[i]; - tmp = debugfs_create_regset32("regs", 0444, tmp_d, regset); - if (!tmp) - return -ENOENT; + tmp_d = debugfs_create_dir(buf, ctrl->debug_root); + debugfs_create_regset32("regs", 0444, tmp_d, regset); } return 0; @@ -543,7 +573,6 @@ static int hisi_zip_ctrl_debug_init(struct hisi_zip_ctrl *ctrl) { - struct dentry *tmp; int i; for (i = HZIP_CURRENT_QM; i < HZIP_DEBUG_FILE_NUM; i++) { @@ -551,11 +580,9 @@ ctrl->files[i].ctrl = ctrl; ctrl->files[i].index = i; - tmp = debugfs_create_file(ctrl_debug_file_name[i], 0600, - ctrl->debug_root, ctrl->files + i, - &ctrl_debug_fops); - if (!tmp) - return -ENOENT; + debugfs_create_file(ctrl_debug_file_name[i], 0600, + ctrl->debug_root, ctrl->files + i, + &ctrl_debug_fops); } return hisi_zip_core_debug_init(ctrl); @@ -569,8 +596,6 @@ int ret; dev_d = debugfs_create_dir(dev_name(dev), hzip_debugfs_root); - if (!dev_d) - return -ENOENT; qm->debug.debug_root = dev_d; ret = hisi_qm_debug_init(qm); @@ -612,13 +637,16 @@ hisi_zip_debug_regs_clear(hisi_zip); } -static void hisi_zip_hw_error_init(struct hisi_zip *hisi_zip) -{ - hisi_qm_hw_error_init(&hisi_zip->qm, QM_BASE_CE, - QM_BASE_NFE | QM_ACC_WB_NOT_READY_TIMEOUT, 0, - QM_DB_RANDOM_INVALID); - hisi_zip_hw_error_set_state(hisi_zip, true); -} +static const struct hisi_qm_err_ini hisi_zip_err_ini = { + .hw_err_enable = hisi_zip_hw_error_enable, + .hw_err_disable = hisi_zip_hw_error_disable, + .err_info = { + .ce = QM_BASE_CE, + .nfe = QM_BASE_NFE | QM_ACC_WB_NOT_READY_TIMEOUT, + .fe = 0, + .msi = QM_DB_RANDOM_INVALID, + } +}; static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip) { @@ -645,97 +673,15 @@ return -EINVAL; } + qm->err_ini = &hisi_zip_err_ini; + hisi_zip_set_user_domain_and_cache(hisi_zip); - hisi_zip_hw_error_init(hisi_zip); + hisi_qm_dev_err_init(qm); hisi_zip_debug_regs_clear(hisi_zip); return 0; } -static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - struct hisi_zip *hisi_zip; - enum qm_hw_ver rev_id; - struct hisi_qm *qm; - int ret; - - rev_id = hisi_qm_get_hw_version(pdev); - if (rev_id == QM_HW_UNKNOWN) - return -EINVAL; - - hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL); - if (!hisi_zip) - return -ENOMEM; - pci_set_drvdata(pdev, hisi_zip); - - qm = &hisi_zip->qm; - qm->pdev = pdev; - qm->ver = rev_id; - - qm->sqe_size = HZIP_SQE_SIZE; - qm->dev_name = hisi_zip_name; - qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ? QM_HW_PF : - QM_HW_VF; - switch (uacce_mode) { - case 0: - qm->use_dma_api = true; - break; - case 1: - qm->use_dma_api = false; - break; - case 2: - qm->use_dma_api = true; - break; - default: - return -EINVAL; - } - - ret = hisi_qm_init(qm); - if (ret) { - dev_err(&pdev->dev, "Failed to init qm!\n"); - return ret; - } - - if (qm->fun_type == QM_HW_PF) { - ret = hisi_zip_pf_probe_init(hisi_zip); - if (ret) - return ret; - - qm->qp_base = HZIP_PF_DEF_Q_BASE; - qm->qp_num = pf_q_num; - } else if (qm->fun_type == QM_HW_VF) { - /* - * have no way to get qm configure in VM in v1 hardware, - * so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force - * to trigger only one VF in v1 hardware. - * - * v2 hardware has no such problem. - */ - if (qm->ver == QM_HW_V1) { - qm->qp_base = HZIP_PF_DEF_Q_NUM; - qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM; - } else if (qm->ver == QM_HW_V2) - /* v2 starts to support get vft by mailbox */ - hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num); - } - - ret = hisi_qm_start(qm); - if (ret) - goto err_qm_uninit; - - ret = hisi_zip_debugfs_init(hisi_zip); - if (ret) - dev_err(&pdev->dev, "Failed to init debugfs (%d)!\n", ret); - - hisi_zip_add_to_list(hisi_zip); - - return 0; - -err_qm_uninit: - hisi_qm_uninit(qm); - return ret; -} - /* Currently we only support equal assignment */ static int hisi_zip_vf_q_assign(struct hisi_zip *hisi_zip, int num_vfs) { @@ -832,6 +778,100 @@ return hisi_zip_clear_vft_config(hisi_zip); } +static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct hisi_zip *hisi_zip; + enum qm_hw_ver rev_id; + struct hisi_qm *qm; + int ret; + + rev_id = hisi_qm_get_hw_version(pdev); + if (rev_id == QM_HW_UNKNOWN) + return -EINVAL; + + hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL); + if (!hisi_zip) + return -ENOMEM; + pci_set_drvdata(pdev, hisi_zip); + + qm = &hisi_zip->qm; + qm->pdev = pdev; + qm->ver = rev_id; + + qm->sqe_size = HZIP_SQE_SIZE; + qm->dev_name = hisi_zip_name; + qm->fun_type = (pdev->device == PCI_DEVICE_ID_ZIP_PF) ? QM_HW_PF : + QM_HW_VF; + switch (uacce_mode) { + case 0: + qm->use_dma_api = true; + break; + case 1: + qm->use_dma_api = false; + break; + case 2: + qm->use_dma_api = true; + break; + default: + return -EINVAL; + } + + ret = hisi_qm_init(qm); + if (ret) { + dev_err(&pdev->dev, "Failed to init qm!\n"); + return ret; + } + + if (qm->fun_type == QM_HW_PF) { + ret = hisi_zip_pf_probe_init(hisi_zip); + if (ret) + return ret; + + qm->qp_base = HZIP_PF_DEF_Q_BASE; + qm->qp_num = pf_q_num; + } else if (qm->fun_type == QM_HW_VF) { + /* + * have no way to get qm configure in VM in v1 hardware, + * so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force + * to trigger only one VF in v1 hardware. + * + * v2 hardware has no such problem. + */ + if (qm->ver == QM_HW_V1) { + qm->qp_base = HZIP_PF_DEF_Q_NUM; + qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM; + } else if (qm->ver == QM_HW_V2) + /* v2 starts to support get vft by mailbox */ + hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num); + } + + ret = hisi_qm_start(qm); + if (ret) + goto err_qm_uninit; + + ret = hisi_zip_debugfs_init(hisi_zip); + if (ret) + dev_err(&pdev->dev, "Failed to init debugfs (%d)!\n", ret); + + hisi_zip_add_to_list(hisi_zip); + + if (qm->fun_type == QM_HW_PF && vfs_num > 0) { + ret = hisi_zip_sriov_enable(pdev, vfs_num); + if (ret < 0) + goto err_remove_from_list; + } + + return 0; + +err_remove_from_list: + hisi_zip_remove_from_list(hisi_zip); + hisi_zip_debugfs_exit(hisi_zip); + hisi_qm_stop(qm); +err_qm_uninit: + hisi_qm_uninit(qm); + return ret; +} + static int hisi_zip_sriov_configure(struct pci_dev *pdev, int num_vfs) { if (num_vfs == 0) @@ -851,9 +891,7 @@ hisi_zip_debugfs_exit(hisi_zip); hisi_qm_stop(qm); - if (qm->fun_type == QM_HW_PF) - hisi_zip_hw_error_set_state(hisi_zip, false); - + hisi_qm_dev_err_uninit(qm); hisi_qm_uninit(qm); hisi_zip_remove_from_list(hisi_zip); } @@ -945,7 +983,7 @@ .probe = hisi_zip_probe, .remove = hisi_zip_remove, .sriov_configure = IS_ENABLED(CONFIG_PCI_IOV) ? - hisi_zip_sriov_configure : 0, + hisi_zip_sriov_configure : NULL, .err_handler = &hisi_zip_err_handler, }; @@ -955,8 +993,6 @@ return; hzip_debugfs_root = debugfs_create_dir("hisi_zip", NULL); - if (IS_ERR_OR_NULL(hzip_debugfs_root)) - hzip_debugfs_root = NULL; } static void hisi_zip_unregister_debugfs(void) --- linux-oracle-5.4.0.orig/drivers/crypto/img-hash.c +++ linux-oracle-5.4.0/drivers/crypto/img-hash.c @@ -356,12 +356,16 @@ static void img_hash_dma_task(unsigned long d) { struct img_hash_dev *hdev = (struct img_hash_dev *)d; - struct img_hash_request_ctx *ctx = ahash_request_ctx(hdev->req); + struct img_hash_request_ctx *ctx; u8 *addr; size_t nbytes, bleft, wsend, len, tbc; struct scatterlist tsg; - if (!hdev->req || !ctx->sg) + if (!hdev->req) + return; + + ctx = ahash_request_ctx(hdev->req); + if (!ctx->sg) return; addr = sg_virt(ctx->sg); --- linux-oracle-5.4.0.orig/drivers/crypto/inside-secure/safexcel.c +++ linux-oracle-5.4.0/drivers/crypto/inside-secure/safexcel.c @@ -221,9 +221,9 @@ /* Step #3: Determine log2 of hash table size */ cs_ht_sz = __fls(asize - cs_rc_max) - 2; /* Step #4: determine current size of hash table in dwords */ - cs_ht_wc = 16<> 4)); + cs_rc_max = min_t(uint, cs_rc_abs_max, asize - (cs_ht_wc >> 2)); /* Clear the cache RAMs */ eip197_trc_cache_clear(priv, cs_rc_max, cs_ht_wc); @@ -1090,11 +1090,12 @@ static int safexcel_request_ring_irq(void *pdev, int irqid, int is_pci_dev, + int ring_id, irq_handler_t handler, irq_handler_t threaded_handler, struct safexcel_ring_irq_data *ring_irq_priv) { - int ret, irq; + int ret, irq, cpu; struct device *dev; if (IS_ENABLED(CONFIG_PCI) && is_pci_dev) { @@ -1120,6 +1121,8 @@ irq_name, irq); return irq; } + } else { + return -ENXIO; } ret = devm_request_threaded_irq(dev, irq, handler, @@ -1130,6 +1133,10 @@ return ret; } + /* Set affinity */ + cpu = cpumask_local_spread(ring_id, NUMA_NO_NODE); + irq_set_affinity_hint(irq, get_cpu_mask(cpu)); + return irq; } @@ -1460,19 +1467,23 @@ &priv->ring[i].rdr); if (ret) { dev_err(dev, "Failed to initialize rings\n"); - return ret; + goto err_cleanup_rings; } priv->ring[i].rdr_req = devm_kcalloc(dev, EIP197_DEFAULT_RING_SIZE, - sizeof(priv->ring[i].rdr_req), + sizeof(*priv->ring[i].rdr_req), GFP_KERNEL); - if (!priv->ring[i].rdr_req) - return -ENOMEM; + if (!priv->ring[i].rdr_req) { + ret = -ENOMEM; + goto err_cleanup_rings; + } ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL); - if (!ring_irq) - return -ENOMEM; + if (!ring_irq) { + ret = -ENOMEM; + goto err_cleanup_rings; + } ring_irq->priv = priv; ring_irq->ring = i; @@ -1480,14 +1491,17 @@ irq = safexcel_request_ring_irq(pdev, EIP197_IRQ_NUMBER(i, is_pci_dev), is_pci_dev, + i, safexcel_irq_ring, safexcel_irq_ring_thread, ring_irq); if (irq < 0) { dev_err(dev, "Failed to get IRQ ID for ring %d\n", i); - return irq; + ret = irq; + goto err_cleanup_rings; } + priv->ring[i].irq = irq; priv->ring[i].work_data.priv = priv; priv->ring[i].work_data.ring = i; INIT_WORK(&priv->ring[i].work_data.work, @@ -1496,8 +1510,10 @@ snprintf(wq_name, 9, "wq_ring%d", i); priv->ring[i].workqueue = create_singlethread_workqueue(wq_name); - if (!priv->ring[i].workqueue) - return -ENOMEM; + if (!priv->ring[i].workqueue) { + ret = -ENOMEM; + goto err_cleanup_rings; + } priv->ring[i].requests = 0; priv->ring[i].busy = false; @@ -1514,16 +1530,26 @@ ret = safexcel_hw_init(priv); if (ret) { dev_err(dev, "HW init failed (%d)\n", ret); - return ret; + goto err_cleanup_rings; } ret = safexcel_register_algorithms(priv); if (ret) { dev_err(dev, "Failed to register algorithms (%d)\n", ret); - return ret; + goto err_cleanup_rings; } return 0; + +err_cleanup_rings: + for (i = 0; i < priv->config.rings; i++) { + if (priv->ring[i].irq) + irq_set_affinity_hint(priv->ring[i].irq, NULL); + if (priv->ring[i].workqueue) + destroy_workqueue(priv->ring[i].workqueue); + } + + return ret; } static void safexcel_hw_reset_rings(struct safexcel_crypto_priv *priv) @@ -1625,8 +1651,10 @@ clk_disable_unprepare(priv->clk); - for (i = 0; i < priv->config.rings; i++) + for (i = 0; i < priv->config.rings; i++) { + irq_set_affinity_hint(priv->ring[i].irq, NULL); destroy_workqueue(priv->ring[i].workqueue); + } return 0; } @@ -1656,6 +1684,8 @@ {}, }; +MODULE_DEVICE_TABLE(of, safexcel_of_match_table); + static struct platform_driver crypto_safexcel = { .probe = safexcel_probe, .remove = safexcel_remove, --- linux-oracle-5.4.0.orig/drivers/crypto/inside-secure/safexcel.h +++ linux-oracle-5.4.0/drivers/crypto/inside-secure/safexcel.h @@ -640,6 +640,9 @@ */ struct crypto_async_request *req; struct crypto_async_request *backlog; + + /* irq of this ring */ + int irq; }; /* EIP integration context flags */ --- linux-oracle-5.4.0.orig/drivers/crypto/ixp4xx_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/ixp4xx_crypto.c @@ -329,7 +329,7 @@ buf1 = buf->next; phys1 = buf->phys_next; - dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir); + dma_unmap_single(dev, buf->phys_addr, buf->buf_len, buf->dir); dma_pool_free(buffer_pool, buf, phys); buf = buf1; phys = phys1; @@ -527,7 +527,7 @@ if (crypt_virt) { dma_free_coherent(dev, - NPE_QLEN_TOTAL * sizeof( struct crypt_ctl), + NPE_QLEN * sizeof(struct crypt_ctl), crypt_virt, crypt_phys); } } --- linux-oracle-5.4.0.orig/drivers/crypto/marvell/cipher.c +++ linux-oracle-5.4.0/drivers/crypto/marvell/cipher.c @@ -287,7 +287,7 @@ static int mv_cesa_des3_ede_setkey(struct crypto_skcipher *cipher, const u8 *key, unsigned int len) { - struct mv_cesa_des_ctx *ctx = crypto_skcipher_ctx(cipher); + struct mv_cesa_des3_ctx *ctx = crypto_skcipher_ctx(cipher); int err; err = verify_skcipher_des3_key(cipher, key); @@ -610,7 +610,6 @@ .decrypt = mv_cesa_ecb_des3_ede_decrypt, .min_keysize = DES3_EDE_KEY_SIZE, .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = DES3_EDE_BLOCK_SIZE, .base = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "mv-ecb-des3-ede", --- linux-oracle-5.4.0.orig/drivers/crypto/mediatek/mtk-platform.c +++ linux-oracle-5.4.0/drivers/crypto/mediatek/mtk-platform.c @@ -442,7 +442,7 @@ static int mtk_desc_ring_alloc(struct mtk_cryp *cryp) { struct mtk_ring **ring = cryp->ring; - int i, err = ENOMEM; + int i; for (i = 0; i < MTK_RING_MAX; i++) { ring[i] = kzalloc(sizeof(**ring), GFP_KERNEL); @@ -469,14 +469,14 @@ return 0; err_cleanup: - for (; i--; ) { + do { dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, ring[i]->res_base, ring[i]->res_dma); dma_free_coherent(cryp->dev, MTK_DESC_RING_SZ, ring[i]->cmd_base, ring[i]->cmd_dma); kfree(ring[i]); - } - return err; + } while (i--); + return -ENOMEM; } static int mtk_crypto_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/crypto/mxs-dcp.c +++ linux-oracle-5.4.0/drivers/crypto/mxs-dcp.c @@ -20,6 +20,7 @@ #include #include #include +#include #define DCP_MAX_CHANS 4 #define DCP_BUF_SZ PAGE_SIZE @@ -167,15 +168,19 @@ static int mxs_dcp_start_dma(struct dcp_async_ctx *actx) { + int dma_err; struct dcp *sdcp = global_sdcp; const int chan = actx->chan; uint32_t stat; unsigned long ret; struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan]; - dma_addr_t desc_phys = dma_map_single(sdcp->dev, desc, sizeof(*desc), DMA_TO_DEVICE); + dma_err = dma_mapping_error(sdcp->dev, desc_phys); + if (dma_err) + return dma_err; + reinit_completion(&sdcp->completion[chan]); /* Clear status register. */ @@ -213,18 +218,29 @@ static int mxs_dcp_run_aes(struct dcp_async_ctx *actx, struct ablkcipher_request *req, int init) { + dma_addr_t key_phys, src_phys, dst_phys; struct dcp *sdcp = global_sdcp; struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan]; struct dcp_aes_req_ctx *rctx = ablkcipher_request_ctx(req); int ret; - dma_addr_t key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key, - 2 * AES_KEYSIZE_128, - DMA_TO_DEVICE); - dma_addr_t src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf, - DCP_BUF_SZ, DMA_TO_DEVICE); - dma_addr_t dst_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_out_buf, - DCP_BUF_SZ, DMA_FROM_DEVICE); + key_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_key, + 2 * AES_KEYSIZE_128, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, key_phys); + if (ret) + return ret; + + src_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_in_buf, + DCP_BUF_SZ, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, src_phys); + if (ret) + goto err_src; + + dst_phys = dma_map_single(sdcp->dev, sdcp->coh->aes_out_buf, + DCP_BUF_SZ, DMA_FROM_DEVICE); + ret = dma_mapping_error(sdcp->dev, dst_phys); + if (ret) + goto err_dst; if (actx->fill % AES_BLOCK_SIZE) { dev_err(sdcp->dev, "Invalid block size!\n"); @@ -262,10 +278,12 @@ ret = mxs_dcp_start_dma(actx); aes_done_run: + dma_unmap_single(sdcp->dev, dst_phys, DCP_BUF_SZ, DMA_FROM_DEVICE); +err_dst: + dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE); +err_src: dma_unmap_single(sdcp->dev, key_phys, 2 * AES_KEYSIZE_128, DMA_TO_DEVICE); - dma_unmap_single(sdcp->dev, src_phys, DCP_BUF_SZ, DMA_TO_DEVICE); - dma_unmap_single(sdcp->dev, dst_phys, DCP_BUF_SZ, DMA_FROM_DEVICE); return ret; } @@ -280,21 +298,20 @@ struct scatterlist *dst = req->dst; struct scatterlist *src = req->src; - const int nents = sg_nents(req->src); + int dst_nents = sg_nents(dst); const int out_off = DCP_BUF_SZ; uint8_t *in_buf = sdcp->coh->aes_in_buf; uint8_t *out_buf = sdcp->coh->aes_out_buf; - uint8_t *out_tmp, *src_buf, *dst_buf = NULL; uint32_t dst_off = 0; + uint8_t *src_buf = NULL; uint32_t last_out_len = 0; uint8_t *key = sdcp->coh->aes_key; int ret = 0; - int split = 0; - unsigned int i, len, clen, rem = 0, tlen = 0; + unsigned int i, len, clen, tlen = 0; int init = 0; bool limit_hit = false; @@ -312,7 +329,7 @@ memset(key + AES_KEYSIZE_128, 0, AES_KEYSIZE_128); } - for_each_sg(req->src, src, nents, i) { + for_each_sg(req->src, src, sg_nents(req->src), i) { src_buf = sg_virt(src); len = sg_dma_len(src); tlen += len; @@ -337,34 +354,17 @@ * submit the buffer. */ if (actx->fill == out_off || sg_is_last(src) || - limit_hit) { + limit_hit) { ret = mxs_dcp_run_aes(actx, req, init); if (ret) return ret; init = 0; - out_tmp = out_buf; + sg_pcopy_from_buffer(dst, dst_nents, out_buf, + actx->fill, dst_off); + dst_off += actx->fill; last_out_len = actx->fill; - while (dst && actx->fill) { - if (!split) { - dst_buf = sg_virt(dst); - dst_off = 0; - } - rem = min(sg_dma_len(dst) - dst_off, - actx->fill); - - memcpy(dst_buf + dst_off, out_tmp, rem); - out_tmp += rem; - dst_off += rem; - actx->fill -= rem; - - if (dst_off == sg_dma_len(dst)) { - dst = sg_next(dst); - split = 0; - } else { - split = 1; - } - } + actx->fill = 0; } } while (len); @@ -564,6 +564,10 @@ dma_addr_t buf_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_in_buf, DCP_BUF_SZ, DMA_TO_DEVICE); + ret = dma_mapping_error(sdcp->dev, buf_phys); + if (ret) + return ret; + /* Fill in the DMA descriptor. */ desc->control0 = MXS_DCP_CONTROL0_DECR_SEMAPHORE | MXS_DCP_CONTROL0_INTERRUPT | @@ -596,6 +600,10 @@ if (rctx->fini) { digest_phys = dma_map_single(sdcp->dev, sdcp->coh->sha_out_buf, DCP_SHA_PAY_SZ, DMA_FROM_DEVICE); + ret = dma_mapping_error(sdcp->dev, digest_phys); + if (ret) + goto done_run; + desc->control0 |= MXS_DCP_CONTROL0_HASH_TERM; desc->payload = digest_phys; } @@ -621,49 +629,46 @@ struct dcp_async_ctx *actx = crypto_ahash_ctx(tfm); struct dcp_sha_req_ctx *rctx = ahash_request_ctx(req); struct hash_alg_common *halg = crypto_hash_alg_common(tfm); - const int nents = sg_nents(req->src); uint8_t *in_buf = sdcp->coh->sha_in_buf; uint8_t *out_buf = sdcp->coh->sha_out_buf; - uint8_t *src_buf; - struct scatterlist *src; - unsigned int i, len, clen; + unsigned int i, len, clen, oft = 0; int ret; int fin = rctx->fini; if (fin) rctx->fini = 0; - for_each_sg(req->src, src, nents, i) { - src_buf = sg_virt(src); - len = sg_dma_len(src); + src = req->src; + len = req->nbytes; - do { - if (actx->fill + len > DCP_BUF_SZ) - clen = DCP_BUF_SZ - actx->fill; - else - clen = len; + while (len) { + if (actx->fill + len > DCP_BUF_SZ) + clen = DCP_BUF_SZ - actx->fill; + else + clen = len; - memcpy(in_buf + actx->fill, src_buf, clen); - len -= clen; - src_buf += clen; - actx->fill += clen; + scatterwalk_map_and_copy(in_buf + actx->fill, src, oft, clen, + 0); - /* - * If we filled the buffer and still have some - * more data, submit the buffer. - */ - if (len && actx->fill == DCP_BUF_SZ) { - ret = mxs_dcp_run_sha(req); - if (ret) - return ret; - actx->fill = 0; - rctx->init = 0; - } - } while (len); + len -= clen; + oft += clen; + actx->fill += clen; + + /* + * If we filled the buffer and still have some + * more data, submit the buffer. + */ + if (len && actx->fill == DCP_BUF_SZ) { + ret = mxs_dcp_run_sha(req); + if (ret) + return ret; + actx->fill = 0; + rctx->init = 0; + } } if (fin) { --- linux-oracle-5.4.0.orig/drivers/crypto/n2_core.c +++ linux-oracle-5.4.0/drivers/crypto/n2_core.c @@ -1278,6 +1278,7 @@ const u32 *hash_init; u8 hw_op_hashsz; u8 digest_size; + u8 statesize; u8 block_size; u8 auth_type; u8 hmac_type; @@ -1309,6 +1310,7 @@ .hmac_type = AUTH_TYPE_HMAC_MD5, .hw_op_hashsz = MD5_DIGEST_SIZE, .digest_size = MD5_DIGEST_SIZE, + .statesize = sizeof(struct md5_state), .block_size = MD5_HMAC_BLOCK_SIZE }, { .name = "sha1", .hash_zero = sha1_zero_message_hash, @@ -1317,6 +1319,7 @@ .hmac_type = AUTH_TYPE_HMAC_SHA1, .hw_op_hashsz = SHA1_DIGEST_SIZE, .digest_size = SHA1_DIGEST_SIZE, + .statesize = sizeof(struct sha1_state), .block_size = SHA1_BLOCK_SIZE }, { .name = "sha256", .hash_zero = sha256_zero_message_hash, @@ -1325,6 +1328,7 @@ .hmac_type = AUTH_TYPE_HMAC_SHA256, .hw_op_hashsz = SHA256_DIGEST_SIZE, .digest_size = SHA256_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), .block_size = SHA256_BLOCK_SIZE }, { .name = "sha224", .hash_zero = sha224_zero_message_hash, @@ -1333,6 +1337,7 @@ .hmac_type = AUTH_TYPE_RESERVED, .hw_op_hashsz = SHA256_DIGEST_SIZE, .digest_size = SHA224_DIGEST_SIZE, + .statesize = sizeof(struct sha256_state), .block_size = SHA224_BLOCK_SIZE }, }; #define NUM_HASH_TMPLS ARRAY_SIZE(hash_tmpls) @@ -1474,6 +1479,7 @@ halg = &ahash->halg; halg->digestsize = tmpl->digest_size; + halg->statesize = tmpl->statesize; base = &halg->base; snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); --- linux-oracle-5.4.0.orig/drivers/crypto/nx/Makefile +++ linux-oracle-5.4.0/drivers/crypto/nx/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_NX_ENCRYPT) += nx-crypto.o nx-crypto-objs := nx.o \ - nx_debugfs.o \ nx-aes-cbc.o \ nx-aes-ecb.o \ nx-aes-gcm.o \ @@ -11,6 +10,7 @@ nx-sha256.o \ nx-sha512.o +nx-crypto-$(CONFIG_DEBUG_FS) += nx_debugfs.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o nx-compress.o obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o nx-compress.o nx-compress-objs := nx-842.o --- linux-oracle-5.4.0.orig/drivers/crypto/nx/nx-842-pseries.c +++ linux-oracle-5.4.0/drivers/crypto/nx/nx-842-pseries.c @@ -538,13 +538,15 @@ * The status field indicates if the device is enabled when the status * is 'okay'. Otherwise the device driver will be disabled. * - * @prop - struct property point containing the maxsyncop for the update + * @devdata: struct nx842_devdata to use for dev_info + * @prop: struct property point containing the maxsyncop for the update * * Returns: * 0 - Device is available * -ENODEV - Device is not available */ -static int nx842_OF_upd_status(struct property *prop) +static int nx842_OF_upd_status(struct nx842_devdata *devdata, + struct property *prop) { const char *status = (const char *)prop->value; @@ -758,7 +760,7 @@ goto out; /* Perform property updates */ - ret = nx842_OF_upd_status(status); + ret = nx842_OF_upd_status(new_devdata, status); if (ret) goto error_out; @@ -1071,6 +1073,7 @@ {"ibm,compression-v1", "ibm,compression"}, {"", ""}, }; +MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids); static struct vio_driver nx842_vio_driver = { .name = KBUILD_MODNAME, --- linux-oracle-5.4.0.orig/drivers/crypto/nx/nx.h +++ linux-oracle-5.4.0/drivers/crypto/nx/nx.h @@ -169,8 +169,8 @@ void nx_debugfs_init(struct nx_crypto_driver *); void nx_debugfs_fini(struct nx_crypto_driver *); #else -#define NX_DEBUGFS_INIT(drv) (0) -#define NX_DEBUGFS_FINI(drv) (0) +#define NX_DEBUGFS_INIT(drv) do {} while (0) +#define NX_DEBUGFS_FINI(drv) do {} while (0) #endif #define NX_PAGE_NUM(x) ((u64)(x) & 0xfffffffffffff000ULL) --- linux-oracle-5.4.0.orig/drivers/crypto/omap-aes.c +++ linux-oracle-5.4.0/drivers/crypto/omap-aes.c @@ -103,7 +103,7 @@ dd->err = 0; } - err = pm_runtime_get_sync(dd->dev); + err = pm_runtime_resume_and_get(dd->dev); if (err < 0) { dev_err(dd->dev, "failed to get sync: %d\n", err); return err; @@ -1153,11 +1153,11 @@ pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY); pm_runtime_enable(dev); - err = pm_runtime_get_sync(dev); + err = pm_runtime_resume_and_get(dev); if (err < 0) { dev_err(dev, "%s: failed to get_sync(%d)\n", __func__, err); - goto err_res; + goto err_pm_disable; } omap_aes_dma_stop(dd); @@ -1267,6 +1267,7 @@ omap_aes_dma_cleanup(dd); err_irq: tasklet_kill(&dd->done_task); +err_pm_disable: pm_runtime_disable(dev); err_res: dd = NULL; --- linux-oracle-5.4.0.orig/drivers/crypto/omap-sham.c +++ linux-oracle-5.4.0/drivers/crypto/omap-sham.c @@ -165,8 +165,6 @@ }; struct omap_sham_ctx { - struct omap_sham_dev *dd; - unsigned long flags; /* fallback stuff */ @@ -366,7 +364,7 @@ { int err; - err = pm_runtime_get_sync(dd->dev); + err = pm_runtime_resume_and_get(dd->dev); if (err < 0) { dev_err(dd->dev, "failed to get sync: %d\n", err); return err; @@ -455,6 +453,9 @@ struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); u32 val, mask; + if (likely(ctx->digcnt)) + omap_sham_write(dd, SHA_REG_DIGCNT(dd), ctx->digcnt); + /* * Setting ALGO_CONST only for the first iteration and * CLOSE_HASH only for the last one. Note that flags mode bits @@ -918,27 +919,35 @@ return 0; } +struct omap_sham_dev *omap_sham_find_dev(struct omap_sham_reqctx *ctx) +{ + struct omap_sham_dev *dd; + + if (ctx->dd) + return ctx->dd; + + spin_lock_bh(&sham.lock); + dd = list_first_entry(&sham.dev_list, struct omap_sham_dev, list); + list_move_tail(&dd->list, &sham.dev_list); + ctx->dd = dd; + spin_unlock_bh(&sham.lock); + + return dd; +} + static int omap_sham_init(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct omap_sham_ctx *tctx = crypto_ahash_ctx(tfm); struct omap_sham_reqctx *ctx = ahash_request_ctx(req); - struct omap_sham_dev *dd = NULL, *tmp; + struct omap_sham_dev *dd; int bs = 0; - spin_lock_bh(&sham.lock); - if (!tctx->dd) { - list_for_each_entry(tmp, &sham.dev_list, list) { - dd = tmp; - break; - } - tctx->dd = dd; - } else { - dd = tctx->dd; - } - spin_unlock_bh(&sham.lock); + ctx->dd = NULL; - ctx->dd = dd; + dd = omap_sham_find_dev(ctx); + if (!dd) + return -ENODEV; ctx->flags = 0; @@ -1187,8 +1196,7 @@ static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) { struct omap_sham_reqctx *ctx = ahash_request_ctx(req); - struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); - struct omap_sham_dev *dd = tctx->dd; + struct omap_sham_dev *dd = ctx->dd; ctx->op = op; @@ -1198,7 +1206,7 @@ static int omap_sham_update(struct ahash_request *req) { struct omap_sham_reqctx *ctx = ahash_request_ctx(req); - struct omap_sham_dev *dd = ctx->dd; + struct omap_sham_dev *dd = omap_sham_find_dev(ctx); if (!req->nbytes) return 0; @@ -1302,21 +1310,8 @@ struct omap_sham_hmac_ctx *bctx = tctx->base; int bs = crypto_shash_blocksize(bctx->shash); int ds = crypto_shash_digestsize(bctx->shash); - struct omap_sham_dev *dd = NULL, *tmp; int err, i; - spin_lock_bh(&sham.lock); - if (!tctx->dd) { - list_for_each_entry(tmp, &sham.dev_list, list) { - dd = tmp; - break; - } - tctx->dd = dd; - } else { - dd = tctx->dd; - } - spin_unlock_bh(&sham.lock); - err = crypto_shash_setkey(tctx->fallback, key, keylen); if (err) return err; @@ -1334,7 +1329,7 @@ memset(bctx->ipad + keylen, 0, bs - keylen); - if (!test_bit(FLAGS_AUTO_XOR, &dd->flags)) { + if (!test_bit(FLAGS_AUTO_XOR, &sham.flags)) { memcpy(bctx->opad, bctx->ipad, bs); for (i = 0; i < bs; i++) { @@ -1739,7 +1734,7 @@ if (test_and_clear_bit(FLAGS_OUTPUT_READY, &dd->flags)) goto finish; } else if (test_bit(FLAGS_DMA_READY, &dd->flags)) { - if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { + if (test_bit(FLAGS_DMA_ACTIVE, &dd->flags)) { omap_sham_update_dma_stop(dd); if (dd->err) { err = dd->err; @@ -2136,6 +2131,7 @@ } dd->flags |= dd->pdata->flags; + sham.flags |= dd->pdata->flags; pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, DEFAULT_AUTOSUSPEND_DELAY); @@ -2145,7 +2141,7 @@ pm_runtime_enable(dev); pm_runtime_irq_safe(dev); - err = pm_runtime_get_sync(dev); + err = pm_runtime_resume_and_get(dev); if (err < 0) { dev_err(dev, "failed to get sync: %d\n", err); goto err_pm; @@ -2163,6 +2159,9 @@ spin_unlock(&sham.lock); for (i = 0; i < dd->pdata->algs_info_size; i++) { + if (dd->pdata->algs_info[i].registered) + break; + for (j = 0; j < dd->pdata->algs_info[i].size; j++) { struct ahash_alg *alg; @@ -2214,9 +2213,11 @@ list_del(&dd->list); spin_unlock(&sham.lock); for (i = dd->pdata->algs_info_size - 1; i >= 0; i--) - for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) + for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) { crypto_unregister_ahash( &dd->pdata->algs_info[i].algs_list[j]); + dd->pdata->algs_info[i].registered--; + } tasklet_kill(&dd->done_task); pm_runtime_disable(&pdev->dev); @@ -2235,7 +2236,7 @@ static int omap_sham_resume(struct device *dev) { - int err = pm_runtime_get_sync(dev); + int err = pm_runtime_resume_and_get(dev); if (err < 0) { dev_err(dev, "failed to get sync: %d\n", err); return err; --- linux-oracle-5.4.0.orig/drivers/crypto/picoxcell_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/picoxcell_crypto.c @@ -1613,6 +1613,11 @@ MODULE_DEVICE_TABLE(of, spacc_of_id_table); #endif /* CONFIG_OF */ +static void spacc_tasklet_kill(void *data) +{ + tasklet_kill(data); +} + static int spacc_probe(struct platform_device *pdev) { int i, err, ret; @@ -1655,6 +1660,14 @@ return -ENXIO; } + tasklet_init(&engine->complete, spacc_spacc_complete, + (unsigned long)engine); + + ret = devm_add_action(&pdev->dev, spacc_tasklet_kill, + &engine->complete); + if (ret) + return ret; + if (devm_request_irq(&pdev->dev, irq->start, spacc_spacc_irq, 0, engine->name, engine)) { dev_err(engine->dev, "failed to request IRQ\n"); @@ -1684,11 +1697,6 @@ goto err_clk_put; } - ret = device_create_file(&pdev->dev, &dev_attr_stat_irq_thresh); - if (ret) - goto err_clk_disable; - - /* * Use an IRQ threshold of 50% as a default. This seems to be a * reasonable trade off of latency against throughput but can be @@ -1696,6 +1704,10 @@ */ engine->stat_irq_thresh = (engine->fifo_sz / 2); + ret = device_create_file(&pdev->dev, &dev_attr_stat_irq_thresh); + if (ret) + goto err_clk_disable; + /* * Configure the interrupts. We only use the STAT_CNT interrupt as we * only submit a new packet for processing when we complete another in @@ -1712,8 +1724,6 @@ INIT_LIST_HEAD(&engine->completed); INIT_LIST_HEAD(&engine->in_progress); engine->in_flight = 0; - tasklet_init(&engine->complete, spacc_spacc_complete, - (unsigned long)engine); platform_set_drvdata(pdev, engine); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c @@ -123,10 +123,10 @@ hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c @@ -233,12 +233,12 @@ if (ret) goto out_err_free_reg; - set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - ret = adf_dev_init(accel_dev); if (ret) goto out_err_dev_shutdown; + set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + ret = adf_dev_start(accel_dev); if (ret) goto out_err_dev_stop; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c @@ -123,10 +123,10 @@ hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_c62xvf/adf_drv.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_c62xvf/adf_drv.c @@ -233,12 +233,12 @@ if (ret) goto out_err_free_reg; - set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - ret = adf_dev_init(accel_dev); if (ret) goto out_err_dev_shutdown; + set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + ret = adf_dev_start(accel_dev); if (ret) goto out_err_dev_stop; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_aer.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_aer.c @@ -139,7 +139,8 @@ if (adf_dev_init(accel_dev) || adf_dev_start(accel_dev)) { /* The device hanged and we can't restart it so stop here */ dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); - kfree(reset_data); + if (reset_data->mode == ADF_DEV_RESET_ASYNC) + kfree(reset_data); WARN(1, "QAT: device restart failed. Device is unusable\n"); return; } @@ -147,10 +148,10 @@ clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); /* The dev is back alive. Notify the caller if in sync mode */ - if (reset_data->mode == ADF_DEV_RESET_SYNC) - complete(&reset_data->compl); - else + if (reset_data->mode == ADF_DEV_RESET_ASYNC) kfree(reset_data); + else + complete(&reset_data->compl); } static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, @@ -182,6 +183,7 @@ if (!timeout) { dev_err(&GET_DEV(accel_dev), "Reset device timeout expired\n"); + cancel_work_sync(&reset_data->reset_work); ret = -EFAULT; } kfree(reset_data); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_common_drv.h +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_common_drv.h @@ -239,8 +239,8 @@ void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); -int adf_vf2pf_init(struct adf_accel_dev *accel_dev); -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev); +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev); +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev); int adf_init_pf_wq(void); void adf_exit_pf_wq(void); int adf_init_vf_wq(void); @@ -263,12 +263,12 @@ { } -static inline int adf_vf2pf_init(struct adf_accel_dev *accel_dev) +static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) { return 0; } -static inline void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) +static inline void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) { } --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_init.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_init.c @@ -105,6 +105,7 @@ struct service_hndl *service; struct list_head *list_itr; struct adf_hw_device_data *hw_data = accel_dev->hw_device; + int ret; if (!hw_data) { dev_err(&GET_DEV(accel_dev), @@ -171,9 +172,9 @@ } hw_data->enable_error_correction(accel_dev); - hw_data->enable_vf2pf_comms(accel_dev); + ret = hw_data->enable_vf2pf_comms(accel_dev); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_dev_init); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_isr.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_isr.c @@ -59,6 +59,8 @@ #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" +#define ADF_MAX_NUM_VFS 32 + static int adf_enable_msix(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; @@ -111,7 +113,7 @@ struct adf_bar *pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; void __iomem *pmisc_bar_addr = pmisc->virt_addr; - u32 vf_mask; + unsigned long vf_mask; /* Get the interrupt sources triggered by VFs */ vf_mask = ((ADF_CSR_RD(pmisc_bar_addr, ADF_ERRSOU5) & @@ -132,8 +134,7 @@ * unless the VF is malicious and is attempting to * flood the host OS with VF2PF interrupts. */ - for_each_set_bit(i, (const unsigned long *)&vf_mask, - (sizeof(vf_mask) * BITS_PER_BYTE)) { + for_each_set_bit(i, &vf_mask, ADF_MAX_NUM_VFS) { vf_info = accel_dev->pf.vf_info + i; if (!__ratelimit(&vf_info->vf2pf_ratelimit)) { @@ -330,19 +331,32 @@ ret = adf_isr_alloc_msix_entry_table(accel_dev); if (ret) - return ret; - if (adf_enable_msix(accel_dev)) goto err_out; - if (adf_setup_bh(accel_dev)) - goto err_out; + ret = adf_enable_msix(accel_dev); + if (ret) + goto err_free_msix_table; - if (adf_request_irqs(accel_dev)) - goto err_out; + ret = adf_setup_bh(accel_dev); + if (ret) + goto err_disable_msix; + + ret = adf_request_irqs(accel_dev); + if (ret) + goto err_cleanup_bh; return 0; + +err_cleanup_bh: + adf_cleanup_bh(accel_dev); + +err_disable_msix: + adf_disable_msix(&accel_dev->accel_pci_dev); + +err_free_msix_table: + adf_isr_free_msix_entry_table(accel_dev); + err_out: - adf_isr_resource_free(accel_dev); - return -EFAULT; + return ret; } EXPORT_SYMBOL_GPL(adf_isr_resource_alloc); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c @@ -195,6 +195,13 @@ val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); } while ((val & int_bit) && (count++ < ADF_IOV_MSG_ACK_MAX_RETRY)); + if (val != msg) { + dev_dbg(&GET_DEV(accel_dev), + "Collision - PFVF CSR overwritten by remote function\n"); + ret = -EIO; + goto out; + } + if (val & int_bit) { dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n"); val &= ~int_bit; @@ -231,7 +238,6 @@ return ret; } -EXPORT_SYMBOL_GPL(adf_iov_putmsg); void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) { @@ -244,6 +250,11 @@ /* Read message from the VF */ msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); + if (!(msg & ADF_VF2PF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious VF2PF interrupt, msg %X. Ignored\n", msg); + goto out; + } /* To ACK, clear the VF2PFINT bit */ msg &= ~ADF_VF2PF_INT; @@ -327,6 +338,7 @@ if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) dev_err(&GET_DEV(accel_dev), "Failed to send response to VF\n"); +out: /* re-enable interrupt on PF from this VF */ adf_enable_vf2pf_interrupts(accel_dev, (1 << vf_nr)); return; @@ -361,6 +373,8 @@ msg |= ADF_PFVF_COMPATIBILITY_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT; BUILD_BUG_ON(ADF_PFVF_COMPATIBILITY_VERSION > 255); + reinit_completion(&accel_dev->vf.iov_msg_completion); + /* Send request from VF to PF */ ret = adf_iov_putmsg(accel_dev, msg, 0); if (ret) { --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_transport.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_transport.c @@ -197,6 +197,7 @@ dev_err(&GET_DEV(accel_dev), "Ring address not aligned\n"); dma_free_coherent(&GET_DEV(accel_dev), ring_size_bytes, ring->base_addr, ring->dma_addr); + ring->base_addr = NULL; return -EFAULT; } --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_vf2pf_msg.c @@ -49,14 +49,14 @@ #include "adf_pf2vf_msg.h" /** - * adf_vf2pf_init() - send init msg to PF + * adf_vf2pf_notify_init() - send init msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends an init messge from the VF to a PF * * Return: 0 on success, error code otherwise. */ -int adf_vf2pf_init(struct adf_accel_dev *accel_dev) +int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) { u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT)); @@ -69,17 +69,17 @@ set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); return 0; } -EXPORT_SYMBOL_GPL(adf_vf2pf_init); +EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init); /** - * adf_vf2pf_shutdown() - send shutdown msg to PF + * adf_vf2pf_notify_shutdown() - send shutdown msg to PF * @accel_dev: Pointer to acceleration VF device. * * Function sends a shutdown messge from the VF to a PF * * Return: void */ -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) +void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) { u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT)); @@ -89,4 +89,4 @@ dev_err(&GET_DEV(accel_dev), "Failed to send Shutdown event to PF\n"); } -EXPORT_SYMBOL_GPL(adf_vf2pf_shutdown); +EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/adf_vf_isr.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/adf_vf_isr.c @@ -123,6 +123,11 @@ /* Read the message from PF */ msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); + if (!(msg & ADF_PF2VF_INT)) { + dev_info(&GET_DEV(accel_dev), + "Spurious PF2VF interrupt, msg %X. Ignored\n", msg); + goto out; + } if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) /* Ignore legacy non-system (non-kernel) PF2VF messages */ @@ -171,6 +176,7 @@ msg &= ~ADF_PF2VF_INT; ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); +out: /* Re-enable PF2VF interrupts */ adf_enable_pf2vf_interrupts(accel_dev); return; @@ -203,6 +209,7 @@ struct adf_bar *pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; void __iomem *pmisc_bar_addr = pmisc->virt_addr; + bool handled = false; u32 v_int; /* Read VF INT source CSR to determine the source of VF interrupt */ @@ -215,7 +222,7 @@ /* Schedule tasklet to handle interrupt BH */ tasklet_hi_schedule(&accel_dev->vf.pf2vf_bh_tasklet); - return IRQ_HANDLED; + handled = true; } /* Check bundle interrupt */ @@ -227,10 +234,10 @@ WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, bank->bank_number, 0); tasklet_hi_schedule(&bank->resp_handler); - return IRQ_HANDLED; + handled = true; } - return IRQ_NONE; + return handled ? IRQ_HANDLED : IRQ_NONE; } static int adf_request_msi_irq(struct adf_accel_dev *accel_dev) @@ -304,17 +311,26 @@ goto err_out; if (adf_setup_pf2vf_bh(accel_dev)) - goto err_out; + goto err_disable_msi; if (adf_setup_bh(accel_dev)) - goto err_out; + goto err_cleanup_pf2vf_bh; if (adf_request_msi_irq(accel_dev)) - goto err_out; + goto err_cleanup_bh; return 0; + +err_cleanup_bh: + adf_cleanup_bh(accel_dev); + +err_cleanup_pf2vf_bh: + adf_cleanup_pf2vf_bh(accel_dev); + +err_disable_msi: + adf_disable_msi(accel_dev); + err_out: - adf_vf_isr_resource_free(accel_dev); return -EFAULT; } EXPORT_SYMBOL_GPL(adf_vf_isr_resource_alloc); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/qat_algs.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/qat_algs.c @@ -715,7 +715,7 @@ struct qat_alg_buf_list *bufl; struct qat_alg_buf_list *buflout = NULL; dma_addr_t blp; - dma_addr_t bloutp = 0; + dma_addr_t bloutp; struct scatterlist *sg; size_t sz_out, sz = struct_size(bufl, bufers, n + 1); @@ -727,6 +727,9 @@ if (unlikely(!bufl)) return -ENOMEM; + for_each_sg(sgl, sg, n, i) + bufl->bufers[i].addr = DMA_MAPPING_ERROR; + blp = dma_map_single(dev, bufl, sz, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, blp))) goto err_in; @@ -760,10 +763,14 @@ dev_to_node(&GET_DEV(inst->accel_dev))); if (unlikely(!buflout)) goto err_in; + + bufers = buflout->bufers; + for_each_sg(sglout, sg, n, i) + bufers[i].addr = DMA_MAPPING_ERROR; + bloutp = dma_map_single(dev, buflout, sz_out, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev, bloutp))) goto err_out; - bufers = buflout->bufers; for_each_sg(sglout, sg, n, i) { int y = sg_nctr; @@ -873,6 +880,11 @@ struct icp_qat_fw_la_bulk_req *msg; int digst_size = crypto_aead_authsize(aead_tfm); int ret, ctr = 0; + u32 cipher_len; + + cipher_len = areq->cryptlen - digst_size; + if (cipher_len % AES_BLOCK_SIZE != 0) + return -EINVAL; ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req); if (unlikely(ret)) @@ -887,7 +899,7 @@ qat_req->req.comn_mid.src_data_addr = qat_req->buf.blp; qat_req->req.comn_mid.dest_data_addr = qat_req->buf.bloutp; cipher_param = (void *)&qat_req->req.serv_specif_rqpars; - cipher_param->cipher_length = areq->cryptlen - digst_size; + cipher_param->cipher_length = cipher_len; cipher_param->cipher_offset = areq->assoclen; memcpy(cipher_param->u.cipher_IV_array, areq->iv, AES_BLOCK_SIZE); auth_param = (void *)((uint8_t *)cipher_param + sizeof(*cipher_param)); @@ -916,6 +928,9 @@ uint8_t *iv = areq->iv; int ret, ctr = 0; + if (areq->cryptlen % AES_BLOCK_SIZE != 0) + return -EINVAL; + ret = qat_alg_sgl_to_bufl(ctx->inst, areq->src, areq->dst, qat_req); if (unlikely(ret)) return ret; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/qat_crypto.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/qat_crypto.c @@ -170,6 +170,14 @@ goto err; if (adf_cfg_section_add(accel_dev, "Accelerator0")) goto err; + + /* Temporarily set the number of crypto instances to zero to avoid + * registering the crypto algorithms. + * This will be removed when the algorithms will support the + * CRYPTO_TFM_REQ_MAY_BACKLOG flag + */ + instances = 0; + for (i = 0; i < instances; i++) { val = i; snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, i); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/qat_hal.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/qat_hal.c @@ -1189,7 +1189,7 @@ unsigned short mask; unsigned short dr_offset = 0x10; - status = ctx_enables = qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES); + ctx_enables = qat_hal_rd_ae_csr(handle, ae, CTX_ENABLES); if (CE_INUSE_CONTEXTS & ctx_enables) { if (ctx & 0x1) { pr_err("QAT: bad 4-ctx mode,ctx=0x%x\n", ctx); @@ -1256,7 +1256,11 @@ pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr); return -EINVAL; } - qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + status = qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + if (status) { + pr_err("QAT: failed to read register"); + return status; + } gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum); data16low = 0xffff & data; data16hi = 0xffff & (data >> 0x10); --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_common/qat_uclo.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_common/qat_uclo.c @@ -332,13 +332,18 @@ } return 0; out_err: + /* Do not free the list head unless we allocated it. */ + tail_old = tail_old->next; + if (flag) { + kfree(*init_tab_base); + *init_tab_base = NULL; + } + while (tail_old) { mem_init = tail_old->next; kfree(tail_old); tail_old = mem_init; } - if (flag) - kfree(*init_tab_base); return -ENOMEM; } @@ -380,7 +385,6 @@ return 0; } -#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000 static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle, struct icp_qat_uof_initmem *init_mem) { --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c @@ -123,10 +123,10 @@ hw_data->enable_error_correction = adf_vf_void_noop; hw_data->init_admin_comms = adf_vf_int_noop; hw_data->exit_admin_comms = adf_vf_void_noop; - hw_data->send_admin_init = adf_vf2pf_init; + hw_data->send_admin_init = adf_vf2pf_notify_init; hw_data->init_arb = adf_vf_int_noop; hw_data->exit_arb = adf_vf_void_noop; - hw_data->disable_iov = adf_vf2pf_shutdown; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_num_accels = get_num_accels; --- linux-oracle-5.4.0.orig/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c +++ linux-oracle-5.4.0/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c @@ -233,12 +233,12 @@ if (ret) goto out_err_free_reg; - set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - ret = adf_dev_init(accel_dev); if (ret) goto out_err_dev_shutdown; + set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + ret = adf_dev_start(accel_dev); if (ret) goto out_err_dev_stop; --- linux-oracle-5.4.0.orig/drivers/crypto/qce/core.c +++ linux-oracle-5.4.0/drivers/crypto/qce/core.c @@ -40,16 +40,19 @@ static int qce_register_algs(struct qce_device *qce) { const struct qce_algo_ops *ops; - int i, ret = -ENODEV; + int i, j, ret = -ENODEV; for (i = 0; i < ARRAY_SIZE(qce_ops); i++) { ops = qce_ops[i]; ret = ops->register_algs(qce); - if (ret) - break; + if (ret) { + for (j = i - 1; j >= 0; j--) + ops->unregister_algs(qce); + return ret; + } } - return ret; + return 0; } static int qce_handle_request(struct crypto_async_request *async_req) @@ -214,7 +217,7 @@ ret = qce_check_version(qce); if (ret) - goto err_clks; + goto err_dma; spin_lock_init(&qce->lock); tasklet_init(&qce->done_tasklet, qce_tasklet_req_done, --- linux-oracle-5.4.0.orig/drivers/crypto/qce/sha.c +++ linux-oracle-5.4.0/drivers/crypto/qce/sha.c @@ -512,8 +512,8 @@ ret = crypto_register_ahash(alg); if (ret) { - kfree(tmpl); dev_err(qce->dev, "%s registration failed\n", base->cra_name); + kfree(tmpl); return ret; } --- linux-oracle-5.4.0.orig/drivers/crypto/qcom-rng.c +++ linux-oracle-5.4.0/drivers/crypto/qcom-rng.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -42,16 +43,19 @@ { unsigned int currsize = 0; u32 val; + int ret; /* read random data from hardware */ do { - val = readl_relaxed(rng->base + PRNG_STATUS); - if (!(val & PRNG_STATUS_DATA_AVAIL)) - break; + ret = readl_poll_timeout(rng->base + PRNG_STATUS, val, + val & PRNG_STATUS_DATA_AVAIL, + 200, 10000); + if (ret) + return ret; val = readl_relaxed(rng->base + PRNG_DATA_OUT); if (!val) - break; + return -EINVAL; if ((max - currsize) >= WORD_SZ) { memcpy(data, &val, WORD_SZ); @@ -64,7 +68,7 @@ } } while (currsize < max); - return currsize; + return 0; } static int qcom_rng_generate(struct crypto_rng *tfm, @@ -86,7 +90,7 @@ mutex_unlock(&rng->lock); clk_disable_unprepare(rng->clk); - return 0; + return ret; } static int qcom_rng_seed(struct crypto_rng *tfm, const u8 *seed, --- linux-oracle-5.4.0.orig/drivers/crypto/s5p-sss.c +++ linux-oracle-5.4.0/drivers/crypto/s5p-sss.c @@ -2208,6 +2208,8 @@ variant = find_s5p_sss_version(pdev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; /* * Note: HASH and PRNG uses the same registers in secss, avoid --- linux-oracle-5.4.0.orig/drivers/crypto/sahara.c +++ linux-oracle-5.4.0/drivers/crypto/sahara.c @@ -43,7 +43,6 @@ #define FLAGS_MODE_MASK 0x000f #define FLAGS_ENCRYPT BIT(0) #define FLAGS_CBC BIT(1) -#define FLAGS_NEW_KEY BIT(3) #define SAHARA_HDR_BASE 0x00800000 #define SAHARA_HDR_SKHA_ALG_AES 0 @@ -141,8 +140,6 @@ }; struct sahara_ctx { - unsigned long flags; - /* AES-specific context */ int keylen; u8 key[AES_KEYSIZE_128]; @@ -445,27 +442,24 @@ int ret; int i, j; int idx = 0; + u32 len; - /* Copy new key if necessary */ - if (ctx->flags & FLAGS_NEW_KEY) { - memcpy(dev->key_base, ctx->key, ctx->keylen); - ctx->flags &= ~FLAGS_NEW_KEY; - - if (dev->flags & FLAGS_CBC) { - dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; - dev->hw_desc[idx]->p1 = dev->iv_phys_base; - } else { - dev->hw_desc[idx]->len1 = 0; - dev->hw_desc[idx]->p1 = 0; - } - dev->hw_desc[idx]->len2 = ctx->keylen; - dev->hw_desc[idx]->p2 = dev->key_phys_base; - dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; - - dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + memcpy(dev->key_base, ctx->key, ctx->keylen); - idx++; + if (dev->flags & FLAGS_CBC) { + dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; + dev->hw_desc[idx]->p1 = dev->iv_phys_base; + } else { + dev->hw_desc[idx]->len1 = 0; + dev->hw_desc[idx]->p1 = 0; } + dev->hw_desc[idx]->len2 = ctx->keylen; + dev->hw_desc[idx]->p2 = dev->key_phys_base; + dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; + dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + + idx++; + dev->nb_in_sg = sg_nents_for_len(dev->in_sg, dev->total); if (dev->nb_in_sg < 0) { @@ -487,24 +481,27 @@ DMA_TO_DEVICE); if (ret != dev->nb_in_sg) { dev_err(dev->device, "couldn't map in sg\n"); - goto unmap_in; + return -EINVAL; } + ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, DMA_FROM_DEVICE); if (ret != dev->nb_out_sg) { dev_err(dev->device, "couldn't map out sg\n"); - goto unmap_out; + goto unmap_in; } /* Create input links */ dev->hw_desc[idx]->p1 = dev->hw_phys_link[0]; sg = dev->in_sg; + len = dev->total; for (i = 0; i < dev->nb_in_sg; i++) { - dev->hw_link[i]->len = sg->length; + dev->hw_link[i]->len = min(len, sg->length); dev->hw_link[i]->p = sg->dma_address; if (i == (dev->nb_in_sg - 1)) { dev->hw_link[i]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; sg = sg_next(sg); } @@ -513,12 +510,14 @@ /* Create output links */ dev->hw_desc[idx]->p2 = dev->hw_phys_link[i]; sg = dev->out_sg; + len = dev->total; for (j = i; j < dev->nb_out_sg + i; j++) { - dev->hw_link[j]->len = sg->length; + dev->hw_link[j]->len = min(len, sg->length); dev->hw_link[j]->p = sg->dma_address; if (j == (dev->nb_out_sg + i - 1)) { dev->hw_link[j]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; sg = sg_next(sg); } @@ -537,9 +536,6 @@ return 0; -unmap_out: - dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, - DMA_FROM_DEVICE); unmap_in: dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); @@ -584,16 +580,17 @@ timeout = wait_for_completion_timeout(&dev->dma_completion, msecs_to_jiffies(SAHARA_TIMEOUT_MS)); - if (!timeout) { - dev_err(dev->device, "AES timeout\n"); - return -ETIMEDOUT; - } dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, DMA_FROM_DEVICE); dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); + if (!timeout) { + dev_err(dev->device, "AES timeout\n"); + return -ETIMEDOUT; + } + return 0; } @@ -608,7 +605,6 @@ /* SAHARA only supports 128bit keys */ if (keylen == AES_KEYSIZE_128) { memcpy(ctx->key, key, keylen); - ctx->flags |= FLAGS_NEW_KEY; return 0; } @@ -796,6 +792,7 @@ int start) { struct scatterlist *sg; + unsigned int len; unsigned int i; int ret; @@ -817,12 +814,14 @@ if (!ret) return -EFAULT; + len = rctx->total; for (i = start; i < dev->nb_in_sg + start; i++) { - dev->hw_link[i]->len = sg->length; + dev->hw_link[i]->len = min(len, sg->length); dev->hw_link[i]->p = sg->dma_address; if (i == (dev->nb_in_sg + start - 1)) { dev->hw_link[i]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; sg = sg_next(sg); } @@ -903,24 +902,6 @@ return 0; } -static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes) -{ - if (!sg || !sg->length) - return nbytes; - - while (nbytes && sg) { - if (nbytes <= sg->length) { - sg->length = nbytes; - sg_mark_end(sg); - break; - } - nbytes -= sg->length; - sg = sg_next(sg); - } - - return nbytes; -} - static int sahara_sha_prepare_request(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); @@ -957,36 +938,20 @@ hash_later, 0); } - /* nbytes should now be multiple of blocksize */ - req->nbytes = req->nbytes - hash_later; - - sahara_walk_and_recalc(req->src, req->nbytes); - + rctx->total = len - hash_later; /* have data from previous operation and current */ if (rctx->buf_cnt && req->nbytes) { sg_init_table(rctx->in_sg_chain, 2); sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt); - sg_chain(rctx->in_sg_chain, 2, req->src); - - rctx->total = req->nbytes + rctx->buf_cnt; rctx->in_sg = rctx->in_sg_chain; - - req->src = rctx->in_sg_chain; /* only data from previous operation */ } else if (rctx->buf_cnt) { - if (req->src) - rctx->in_sg = req->src; - else - rctx->in_sg = rctx->in_sg_chain; - /* buf was copied into rembuf above */ + rctx->in_sg = rctx->in_sg_chain; sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt); - rctx->total = rctx->buf_cnt; /* no data from previous operation */ } else { rctx->in_sg = req->src; - rctx->total = req->nbytes; - req->src = rctx->in_sg; } /* on next call, we only have the remaining data in the buffer */ @@ -1007,7 +972,10 @@ return ret; if (rctx->first) { - sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); + ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); + if (ret) + return ret; + dev->hw_desc[0]->next = 0; rctx->first = 0; } else { @@ -1015,7 +983,10 @@ sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0); dev->hw_desc[0]->next = dev->hw_phys_desc[1]; - sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); + ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); + if (ret) + return ret; + dev->hw_desc[1]->next = 0; } @@ -1028,18 +999,19 @@ timeout = wait_for_completion_timeout(&dev->dma_completion, msecs_to_jiffies(SAHARA_TIMEOUT_MS)); - if (!timeout) { - dev_err(dev->device, "SHA timeout\n"); - return -ETIMEDOUT; - } if (rctx->sg_in_idx) dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); + if (!timeout) { + dev_err(dev->device, "SHA timeout\n"); + return -ETIMEDOUT; + } + memcpy(rctx->context, dev->context_base, rctx->context_size); - if (req->result) + if (req->result && rctx->last) memcpy(req->result, rctx->context, rctx->digest_size); return 0; @@ -1183,8 +1155,7 @@ static int sahara_sha_cra_init(struct crypto_tfm *tfm) { crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), - sizeof(struct sahara_sha_reqctx) + - SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); + sizeof(struct sahara_sha_reqctx)); return 0; } --- linux-oracle-5.4.0.orig/drivers/crypto/stm32/stm32-crc32.c +++ linux-oracle-5.4.0/drivers/crypto/stm32/stm32-crc32.c @@ -28,8 +28,10 @@ /* Registers values */ #define CRC_CR_RESET BIT(0) -#define CRC_CR_REVERSE (BIT(7) | BIT(6) | BIT(5)) -#define CRC_INIT_DEFAULT 0xFFFFFFFF +#define CRC_CR_REV_IN_WORD (BIT(6) | BIT(5)) +#define CRC_CR_REV_IN_BYTE BIT(5) +#define CRC_CR_REV_OUT BIT(7) +#define CRC32C_INIT_DEFAULT 0xFFFFFFFF #define CRC_AUTOSUSPEND_DELAY 50 @@ -38,8 +40,6 @@ struct device *dev; void __iomem *regs; struct clk *clk; - u8 pending_data[sizeof(u32)]; - size_t nb_pending_bytes; }; struct stm32_crc_list { @@ -59,14 +59,13 @@ struct stm32_crc_desc_ctx { u32 partial; /* crc32c: partial in first 4 bytes of that struct */ - struct stm32_crc *crc; }; static int stm32_crc32_cra_init(struct crypto_tfm *tfm) { struct stm32_crc_ctx *mctx = crypto_tfm_ctx(tfm); - mctx->key = CRC_INIT_DEFAULT; + mctx->key = 0; mctx->poly = CRC32_POLY_LE; return 0; } @@ -75,7 +74,7 @@ { struct stm32_crc_ctx *mctx = crypto_tfm_ctx(tfm); - mctx->key = CRC_INIT_DEFAULT; + mctx->key = CRC32C_INIT_DEFAULT; mctx->poly = CRC32C_POLY_LE; return 0; } @@ -94,32 +93,42 @@ return 0; } +static struct stm32_crc *stm32_crc_get_next_crc(void) +{ + struct stm32_crc *crc; + + spin_lock_bh(&crc_list.lock); + crc = list_first_entry_or_null(&crc_list.dev_list, struct stm32_crc, list); + if (crc) + list_move_tail(&crc->list, &crc_list.dev_list); + spin_unlock_bh(&crc_list.lock); + + return crc; +} + static int stm32_crc_init(struct shash_desc *desc) { struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc); struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm); struct stm32_crc *crc; - spin_lock_bh(&crc_list.lock); - list_for_each_entry(crc, &crc_list.dev_list, list) { - ctx->crc = crc; - break; - } - spin_unlock_bh(&crc_list.lock); + crc = stm32_crc_get_next_crc(); + if (!crc) + return -ENODEV; - pm_runtime_get_sync(ctx->crc->dev); + pm_runtime_get_sync(crc->dev); /* Reset, set key, poly and configure in bit reverse mode */ - writel_relaxed(bitrev32(mctx->key), ctx->crc->regs + CRC_INIT); - writel_relaxed(bitrev32(mctx->poly), ctx->crc->regs + CRC_POL); - writel_relaxed(CRC_CR_RESET | CRC_CR_REVERSE, ctx->crc->regs + CRC_CR); + writel_relaxed(bitrev32(mctx->key), crc->regs + CRC_INIT); + writel_relaxed(bitrev32(mctx->poly), crc->regs + CRC_POL); + writel_relaxed(CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); /* Store partial result */ - ctx->partial = readl_relaxed(ctx->crc->regs + CRC_DR); - ctx->crc->nb_pending_bytes = 0; + ctx->partial = readl_relaxed(crc->regs + CRC_DR); - pm_runtime_mark_last_busy(ctx->crc->dev); - pm_runtime_put_autosuspend(ctx->crc->dev); + pm_runtime_mark_last_busy(crc->dev); + pm_runtime_put_autosuspend(crc->dev); return 0; } @@ -128,31 +137,49 @@ unsigned int length) { struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc); - struct stm32_crc *crc = ctx->crc; - u32 *d32; - unsigned int i; + struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm); + struct stm32_crc *crc; + + crc = stm32_crc_get_next_crc(); + if (!crc) + return -ENODEV; pm_runtime_get_sync(crc->dev); - if (unlikely(crc->nb_pending_bytes)) { - while (crc->nb_pending_bytes != sizeof(u32) && length) { - /* Fill in pending data */ - crc->pending_data[crc->nb_pending_bytes++] = *(d8++); + /* + * Restore previously calculated CRC for this context as init value + * Restore polynomial configuration + * Configure in register for word input data, + * Configure out register in reversed bit mode data. + */ + writel_relaxed(bitrev32(ctx->partial), crc->regs + CRC_INIT); + writel_relaxed(bitrev32(mctx->poly), crc->regs + CRC_POL); + writel_relaxed(CRC_CR_RESET | CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + + if (d8 != PTR_ALIGN(d8, sizeof(u32))) { + /* Configure for byte data */ + writel_relaxed(CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + while (d8 != PTR_ALIGN(d8, sizeof(u32)) && length) { + writeb_relaxed(*d8++, crc->regs + CRC_DR); length--; } - - if (crc->nb_pending_bytes == sizeof(u32)) { - /* Process completed pending data */ - writel_relaxed(*(u32 *)crc->pending_data, - crc->regs + CRC_DR); - crc->nb_pending_bytes = 0; - } + /* Configure for word data */ + writel_relaxed(CRC_CR_REV_IN_WORD | CRC_CR_REV_OUT, + crc->regs + CRC_CR); } - d32 = (u32 *)d8; - for (i = 0; i < length >> 2; i++) - /* Process 32 bits data */ - writel_relaxed(*(d32++), crc->regs + CRC_DR); + for (; length >= sizeof(u32); d8 += sizeof(u32), length -= sizeof(u32)) + writel_relaxed(*((u32 *)d8), crc->regs + CRC_DR); + + if (length) { + /* Configure for byte data */ + writel_relaxed(CRC_CR_REV_IN_BYTE | CRC_CR_REV_OUT, + crc->regs + CRC_CR); + while (length--) + writeb_relaxed(*d8++, crc->regs + CRC_DR); + } /* Store partial result */ ctx->partial = readl_relaxed(crc->regs + CRC_DR); @@ -160,22 +187,6 @@ pm_runtime_mark_last_busy(crc->dev); pm_runtime_put_autosuspend(crc->dev); - /* Check for pending data (non 32 bits) */ - length &= 3; - if (likely(!length)) - return 0; - - if ((crc->nb_pending_bytes + length) >= sizeof(u32)) { - /* Shall not happen */ - dev_err(crc->dev, "Pending data overflow\n"); - return -EINVAL; - } - - d8 = (const u8 *)d32; - for (i = 0; i < length; i++) - /* Store pending data */ - crc->pending_data[crc->nb_pending_bytes++] = *(d8++); - return 0; } @@ -204,6 +215,8 @@ return stm32_crc_init(desc) ?: stm32_crc_finup(desc, data, length, out); } +static unsigned int refcnt; +static DEFINE_MUTEX(refcnt_lock); static struct shash_alg algs[] = { /* CRC-32 */ { @@ -217,7 +230,7 @@ .digestsize = CHKSUM_DIGEST_SIZE, .base = { .cra_name = "crc32", - .cra_driver_name = DRIVER_NAME, + .cra_driver_name = "stm32-crc32-crc32", .cra_priority = 200, .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, .cra_blocksize = CHKSUM_BLOCK_SIZE, @@ -239,7 +252,7 @@ .digestsize = CHKSUM_DIGEST_SIZE, .base = { .cra_name = "crc32c", - .cra_driver_name = DRIVER_NAME, + .cra_driver_name = "stm32-crc32-crc32c", .cra_priority = 200, .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, .cra_blocksize = CHKSUM_BLOCK_SIZE, @@ -294,12 +307,18 @@ list_add(&crc->list, &crc_list.dev_list); spin_unlock(&crc_list.lock); - ret = crypto_register_shashes(algs, ARRAY_SIZE(algs)); - if (ret) { - dev_err(dev, "Failed to register\n"); - clk_disable_unprepare(crc->clk); - return ret; + mutex_lock(&refcnt_lock); + if (!refcnt) { + ret = crypto_register_shashes(algs, ARRAY_SIZE(algs)); + if (ret) { + mutex_unlock(&refcnt_lock); + dev_err(dev, "Failed to register\n"); + clk_disable_unprepare(crc->clk); + return ret; + } } + refcnt++; + mutex_unlock(&refcnt_lock); dev_info(dev, "Initialized\n"); @@ -313,14 +332,19 @@ struct stm32_crc *crc = platform_get_drvdata(pdev); int ret = pm_runtime_get_sync(crc->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(crc->dev); return ret; + } spin_lock(&crc_list.lock); list_del(&crc->list); spin_unlock(&crc_list.lock); - crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); + mutex_lock(&refcnt_lock); + if (!--refcnt) + crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); + mutex_unlock(&refcnt_lock); pm_runtime_disable(crc->dev); pm_runtime_put_noidle(crc->dev); --- linux-oracle-5.4.0.orig/drivers/crypto/stm32/stm32-cryp.c +++ linux-oracle-5.4.0/drivers/crypto/stm32/stm32-cryp.c @@ -537,7 +537,7 @@ int ret; u32 cfg, hw_mode; - pm_runtime_get_sync(cryp->dev); + pm_runtime_resume_and_get(cryp->dev); /* Disable interrupt */ stm32_cryp_write(cryp, CRYP_IMSCR, 0); @@ -639,7 +639,7 @@ /* Phase 4 : output tag */ err = stm32_cryp_read_auth_tag(cryp); - if (!err && (!(is_gcm(cryp) || is_ccm(cryp)))) + if (!err && (!(is_gcm(cryp) || is_ccm(cryp) || is_ecb(cryp)))) stm32_cryp_get_iv(cryp); if (cryp->sgs_copied) { @@ -669,8 +669,6 @@ else crypto_finalize_ablkcipher_request(cryp->engine, cryp->req, err); - - memset(cryp->ctx->key, 0, cryp->ctx->keylen); } static int stm32_cryp_cpu_start(struct stm32_cryp *cryp) @@ -2038,8 +2036,6 @@ pm_runtime_disable(dev); pm_runtime_put_noidle(dev); - pm_runtime_disable(dev); - pm_runtime_put_noidle(dev); clk_disable_unprepare(cryp->clk); @@ -2054,7 +2050,7 @@ if (!cryp) return -ENODEV; - ret = pm_runtime_get_sync(cryp->dev); + ret = pm_runtime_resume_and_get(cryp->dev); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/crypto/stm32/stm32-hash.c +++ linux-oracle-5.4.0/drivers/crypto/stm32/stm32-hash.c @@ -562,9 +562,9 @@ } for_each_sg(rctx->sg, tsg, rctx->nents, i) { + sg[0] = *tsg; len = sg->length; - sg[0] = *tsg; if (sg_is_last(sg)) { if (hdev->dma_mode == 1) { len = (ALIGN(sg->length, 16) - 16); @@ -810,7 +810,7 @@ static int stm32_hash_hw_init(struct stm32_hash_dev *hdev, struct stm32_hash_request_ctx *rctx) { - pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev); if (!(HASH_FLAGS_INIT & hdev->flags)) { stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT); @@ -959,7 +959,7 @@ u32 *preg; unsigned int i; - pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev); while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) cpu_relax(); @@ -997,7 +997,7 @@ preg = rctx->hw_context; - pm_runtime_get_sync(hdev->dev); + pm_runtime_resume_and_get(hdev->dev); stm32_hash_write(hdev, HASH_IMR, *preg++); stm32_hash_write(hdev, HASH_STR, *preg++); @@ -1554,8 +1554,6 @@ return -ENODEV; ret = pm_runtime_get_sync(hdev->dev); - if (ret < 0) - return ret; stm32_hash_unregister_algs(hdev); @@ -1571,7 +1569,8 @@ pm_runtime_disable(hdev->dev); pm_runtime_put_noidle(hdev->dev); - clk_disable_unprepare(hdev->clk); + if (ret >= 0) + clk_disable_unprepare(hdev->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +++ linux-oracle-5.4.0/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c @@ -30,6 +30,8 @@ unsigned int ileft = areq->cryptlen; unsigned int oleft = areq->cryptlen; unsigned int todo; + unsigned long pi = 0, po = 0; /* progress for in and out */ + bool miter_err; struct sg_mapping_iter mi, mo; unsigned int oi, oo; /* offset for in and out */ unsigned long flags; @@ -44,59 +46,74 @@ spin_lock_irqsave(&ss->slock, flags); - for (i = 0; i < op->keylen; i += 4) - writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); + for (i = 0; i < op->keylen / 4; i++) + writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1); if (areq->iv) { for (i = 0; i < 4 && i < ivsize / 4; i++) { v = *(u32 *)(areq->iv + i * 4); - writel(v, ss->base + SS_IV0 + i * 4); + writesl(ss->base + SS_IV0 + i * 4, &v, 1); } } writel(mode, ss->base + SS_CTL); - sg_miter_start(&mi, areq->src, sg_nents(areq->src), - SG_MITER_FROM_SG | SG_MITER_ATOMIC); - sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), - SG_MITER_TO_SG | SG_MITER_ATOMIC); - sg_miter_next(&mi); - sg_miter_next(&mo); - if (!mi.addr || !mo.addr) { - dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); - err = -EINVAL; - goto release_ss; - } ileft = areq->cryptlen / 4; oleft = areq->cryptlen / 4; oi = 0; oo = 0; do { - todo = min3(rx_cnt, ileft, (mi.length - oi) / 4); - if (todo) { - ileft -= todo; - writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); - oi += todo * 4; - } - if (oi == mi.length) { - sg_miter_next(&mi); - oi = 0; + if (ileft) { + sg_miter_start(&mi, areq->src, sg_nents(areq->src), + SG_MITER_FROM_SG | SG_MITER_ATOMIC); + if (pi) + sg_miter_skip(&mi, pi); + miter_err = sg_miter_next(&mi); + if (!miter_err || !mi.addr) { + dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); + err = -EINVAL; + goto release_ss; + } + todo = min(rx_cnt, ileft); + todo = min_t(size_t, todo, (mi.length - oi) / 4); + if (todo) { + ileft -= todo; + writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); + oi += todo * 4; + } + if (oi == mi.length) { + pi += mi.length; + oi = 0; + } + sg_miter_stop(&mi); } spaces = readl(ss->base + SS_FCSR); rx_cnt = SS_RXFIFO_SPACES(spaces); tx_cnt = SS_TXFIFO_SPACES(spaces); - todo = min3(tx_cnt, oleft, (mo.length - oo) / 4); + sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), + SG_MITER_TO_SG | SG_MITER_ATOMIC); + if (po) + sg_miter_skip(&mo, po); + miter_err = sg_miter_next(&mo); + if (!miter_err || !mo.addr) { + dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); + err = -EINVAL; + goto release_ss; + } + todo = min(tx_cnt, oleft); + todo = min_t(size_t, todo, (mo.length - oo) / 4); if (todo) { oleft -= todo; readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); oo += todo * 4; } if (oo == mo.length) { - sg_miter_next(&mo); oo = 0; + po += mo.length; } + sg_miter_stop(&mo); } while (oleft); if (areq->iv) { @@ -107,8 +124,6 @@ } release_ss: - sg_miter_stop(&mi); - sg_miter_stop(&mo); writel(0, ss->base + SS_CTL); spin_unlock_irqrestore(&ss->slock, flags); return err; @@ -162,12 +177,14 @@ unsigned int oleft = areq->cryptlen; unsigned int todo; struct sg_mapping_iter mi, mo; + unsigned long pi = 0, po = 0; /* progress for in and out */ + bool miter_err; unsigned int oi, oo; /* offset for in and out */ unsigned int ob = 0; /* offset in buf */ unsigned int obo = 0; /* offset in bufo*/ unsigned int obl = 0; /* length of data in bufo */ unsigned long flags; - bool need_fallback; + bool need_fallback = false; if (!areq->cryptlen) return 0; @@ -186,12 +203,12 @@ * we can use the SS optimized function */ while (in_sg && no_chunk == 1) { - if (in_sg->length % 4) + if ((in_sg->length | in_sg->offset) & 3u) no_chunk = 0; in_sg = sg_next(in_sg); } while (out_sg && no_chunk == 1) { - if (out_sg->length % 4) + if ((out_sg->length | out_sg->offset) & 3u) no_chunk = 0; out_sg = sg_next(out_sg); } @@ -204,28 +221,17 @@ spin_lock_irqsave(&ss->slock, flags); - for (i = 0; i < op->keylen; i += 4) - writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); + for (i = 0; i < op->keylen / 4; i++) + writesl(ss->base + SS_KEY0 + i * 4, &op->key[i], 1); if (areq->iv) { for (i = 0; i < 4 && i < ivsize / 4; i++) { v = *(u32 *)(areq->iv + i * 4); - writel(v, ss->base + SS_IV0 + i * 4); + writesl(ss->base + SS_IV0 + i * 4, &v, 1); } } writel(mode, ss->base + SS_CTL); - sg_miter_start(&mi, areq->src, sg_nents(areq->src), - SG_MITER_FROM_SG | SG_MITER_ATOMIC); - sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), - SG_MITER_TO_SG | SG_MITER_ATOMIC); - sg_miter_next(&mi); - sg_miter_next(&mo); - if (!mi.addr || !mo.addr) { - dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); - err = -EINVAL; - goto release_ss; - } ileft = areq->cryptlen; oleft = areq->cryptlen; oi = 0; @@ -233,13 +239,22 @@ while (oleft) { if (ileft) { - char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */ - + sg_miter_start(&mi, areq->src, sg_nents(areq->src), + SG_MITER_FROM_SG | SG_MITER_ATOMIC); + if (pi) + sg_miter_skip(&mi, pi); + miter_err = sg_miter_next(&mi); + if (!miter_err || !mi.addr) { + dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); + err = -EINVAL; + goto release_ss; + } /* * todo is the number of consecutive 4byte word that we * can read from current SG */ - todo = min3(rx_cnt, ileft / 4, (mi.length - oi) / 4); + todo = min(rx_cnt, ileft / 4); + todo = min_t(size_t, todo, (mi.length - oi) / 4); if (todo && !ob) { writesl(ss->base + SS_RXFIFO, mi.addr + oi, todo); @@ -253,52 +268,59 @@ * we need to be able to write all buf in one * pass, so it is why we min() with rx_cnt */ - todo = min3(rx_cnt * 4 - ob, ileft, - mi.length - oi); - memcpy(buf + ob, mi.addr + oi, todo); + todo = min(rx_cnt * 4 - ob, ileft); + todo = min_t(size_t, todo, mi.length - oi); + memcpy(ss->buf + ob, mi.addr + oi, todo); ileft -= todo; oi += todo; ob += todo; if (!(ob % 4)) { - writesl(ss->base + SS_RXFIFO, buf, + writesl(ss->base + SS_RXFIFO, ss->buf, ob / 4); ob = 0; } } if (oi == mi.length) { - sg_miter_next(&mi); + pi += mi.length; oi = 0; } + sg_miter_stop(&mi); } spaces = readl(ss->base + SS_FCSR); rx_cnt = SS_RXFIFO_SPACES(spaces); tx_cnt = SS_TXFIFO_SPACES(spaces); - dev_dbg(ss->dev, "%x %u/%u %u/%u cnt=%u %u/%u %u/%u cnt=%u %u\n", - mode, - oi, mi.length, ileft, areq->cryptlen, rx_cnt, - oo, mo.length, oleft, areq->cryptlen, tx_cnt, ob); if (!tx_cnt) continue; + sg_miter_start(&mo, areq->dst, sg_nents(areq->dst), + SG_MITER_TO_SG | SG_MITER_ATOMIC); + if (po) + sg_miter_skip(&mo, po); + miter_err = sg_miter_next(&mo); + if (!miter_err || !mo.addr) { + dev_err_ratelimited(ss->dev, "ERROR: sg_miter return null\n"); + err = -EINVAL; + goto release_ss; + } /* todo in 4bytes word */ - todo = min3(tx_cnt, oleft / 4, (mo.length - oo) / 4); + todo = min(tx_cnt, oleft / 4); + todo = min_t(size_t, todo, (mo.length - oo) / 4); + if (todo) { readsl(ss->base + SS_TXFIFO, mo.addr + oo, todo); oleft -= todo * 4; oo += todo * 4; if (oo == mo.length) { - sg_miter_next(&mo); + po += mo.length; oo = 0; } } else { - char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */ - /* * read obl bytes in bufo, we read at maximum for * emptying the device */ - readsl(ss->base + SS_TXFIFO, bufo, tx_cnt); + readsl(ss->base + SS_TXFIFO, ss->bufo, tx_cnt); obl = tx_cnt * 4; obo = 0; do { @@ -308,18 +330,21 @@ * no more than remaining buffer * no need to test against oleft */ - todo = min(mo.length - oo, obl - obo); - memcpy(mo.addr + oo, bufo + obo, todo); + todo = min_t(size_t, + mo.length - oo, obl - obo); + memcpy(mo.addr + oo, ss->bufo + obo, todo); oleft -= todo; obo += todo; oo += todo; if (oo == mo.length) { + po += mo.length; sg_miter_next(&mo); oo = 0; } } while (obo < obl); /* bufo must be fully used here */ } + sg_miter_stop(&mo); } if (areq->iv) { for (i = 0; i < 4 && i < ivsize / 4; i++) { @@ -329,8 +354,6 @@ } release_ss: - sg_miter_stop(&mi); - sg_miter_stop(&mo); writel(0, ss->base + SS_CTL); spin_unlock_irqrestore(&ss->slock, flags); --- linux-oracle-5.4.0.orig/drivers/crypto/sunxi-ss/sun4i-ss-hash.c +++ linux-oracle-5.4.0/drivers/crypto/sunxi-ss/sun4i-ss-hash.c @@ -175,7 +175,7 @@ */ unsigned int i = 0, end, fill, min_fill, nwait, nbw = 0, j = 0, todo; unsigned int in_i = 0; - u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32] = {0}, wb = 0, v, ivmode = 0; + u32 spaces, rx_cnt = SS_RX_DEFAULT, bf[32] = {0}, v, ivmode = 0; struct sun4i_req_ctx *op = ahash_request_ctx(areq); struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); struct sun4i_tfm_ctx *tfmctx = crypto_ahash_ctx(tfm); @@ -184,6 +184,7 @@ struct sg_mapping_iter mi; int in_r, err = 0; size_t copied = 0; + __le32 wb = 0; dev_dbg(ss->dev, "%s %s bc=%llu len=%u mode=%x wl=%u h0=%0x", __func__, crypto_tfm_alg_name(areq->base.tfm), @@ -272,8 +273,8 @@ */ while (op->len < 64 && i < end) { /* how many bytes we can read from current SG */ - in_r = min3(mi.length - in_i, end - i, - 64 - op->len); + in_r = min(end - i, 64 - op->len); + in_r = min_t(size_t, mi.length - in_i, in_r); memcpy(op->buf + op->len, mi.addr + in_i, in_r); op->len += in_r; i += in_r; @@ -293,8 +294,8 @@ } if (mi.length - in_i > 3 && i < end) { /* how many bytes we can read from current SG */ - in_r = min3(mi.length - in_i, areq->nbytes - i, - ((mi.length - in_i) / 4) * 4); + in_r = min_t(size_t, mi.length - in_i, areq->nbytes - i); + in_r = min_t(size_t, ((mi.length - in_i) / 4) * 4, in_r); /* how many bytes we can write in the device*/ todo = min3((u32)(end - i) / 4, rx_cnt, (u32)in_r / 4); writesl(ss->base + SS_RXFIFO, mi.addr + in_i, todo); @@ -320,8 +321,8 @@ if ((areq->nbytes - i) < 64) { while (i < areq->nbytes && in_i < mi.length && op->len < 64) { /* how many bytes we can read from current SG */ - in_r = min3(mi.length - in_i, areq->nbytes - i, - 64 - op->len); + in_r = min(areq->nbytes - i, 64 - op->len); + in_r = min_t(size_t, mi.length - in_i, in_r); memcpy(op->buf + op->len, mi.addr + in_i, in_r); op->len += in_r; i += in_r; @@ -395,7 +396,7 @@ nbw = op->len - 4 * nwait; if (nbw) { - wb = *(u32 *)(op->buf + nwait * 4); + wb = cpu_to_le32(*(u32 *)(op->buf + nwait * 4)); wb &= GENMASK((nbw * 8) - 1, 0); op->byte_count += nbw; @@ -404,7 +405,7 @@ /* write the remaining bytes of the nbw buffer */ wb |= ((1 << 7) << (nbw * 8)); - bf[j++] = wb; + bf[j++] = le32_to_cpu(wb); /* * number of space to pad to obtain 64o minus 8(size) minus 4 (final 1) @@ -423,13 +424,13 @@ /* write the length of data */ if (op->mode == SS_OP_SHA1) { - __be64 bits = cpu_to_be64(op->byte_count << 3); - bf[j++] = lower_32_bits(bits); - bf[j++] = upper_32_bits(bits); + __be64 *bits = (__be64 *)&bf[j]; + *bits = cpu_to_be64(op->byte_count << 3); + j += 2; } else { - __le64 bits = op->byte_count << 3; - bf[j++] = lower_32_bits(bits); - bf[j++] = upper_32_bits(bits); + __le64 *bits = (__le64 *)&bf[j]; + *bits = cpu_to_le64(op->byte_count << 3); + j += 2; } writesl(ss->base + SS_RXFIFO, bf, j); @@ -471,7 +472,7 @@ } } else { for (i = 0; i < 4; i++) { - v = readl(ss->base + SS_MD0 + i * 4); + v = cpu_to_le32(readl(ss->base + SS_MD0 + i * 4)); memcpy(areq->result + i * 4, &v, 4); } } --- linux-oracle-5.4.0.orig/drivers/crypto/sunxi-ss/sun4i-ss.h +++ linux-oracle-5.4.0/drivers/crypto/sunxi-ss/sun4i-ss.h @@ -138,6 +138,8 @@ struct reset_control *reset; struct device *dev; struct resource *res; + char buf[4 * SS_RX_MAX];/* buffer for linearize SG src */ + char bufo[4 * SS_TX_MAX]; /* buffer for linearize SG dst */ spinlock_t slock; /* control the use of the device */ #ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG u32 seed[SS_SEED_LEN / BITS_PER_LONG]; --- linux-oracle-5.4.0.orig/drivers/crypto/talitos.c +++ linux-oracle-5.4.0/drivers/crypto/talitos.c @@ -460,7 +460,7 @@ /* * locate current (offending) descriptor */ -static u32 current_desc_hdr(struct device *dev, int ch) +static __be32 current_desc_hdr(struct device *dev, int ch) { struct talitos_private *priv = dev_get_drvdata(dev); int tail, iter; @@ -478,7 +478,7 @@ iter = tail; while (priv->chan[ch].fifo[iter].dma_desc != cur_desc && - priv->chan[ch].fifo[iter].desc->next_desc != cur_desc) { + priv->chan[ch].fifo[iter].desc->next_desc != cpu_to_be32(cur_desc)) { iter = (iter + 1) & (priv->fifo_len - 1); if (iter == tail) { dev_err(dev, "couldn't locate current descriptor\n"); @@ -486,7 +486,7 @@ } } - if (priv->chan[ch].fifo[iter].desc->next_desc == cur_desc) { + if (priv->chan[ch].fifo[iter].desc->next_desc == cpu_to_be32(cur_desc)) { struct talitos_edesc *edesc; edesc = container_of(priv->chan[ch].fifo[iter].desc, @@ -501,13 +501,13 @@ /* * user diagnostics; report root cause of error based on execution unit status */ -static void report_eu_error(struct device *dev, int ch, u32 desc_hdr) +static void report_eu_error(struct device *dev, int ch, __be32 desc_hdr) { struct talitos_private *priv = dev_get_drvdata(dev); int i; if (!desc_hdr) - desc_hdr = in_be32(priv->chan[ch].reg + TALITOS_DESCBUF); + desc_hdr = cpu_to_be32(in_be32(priv->chan[ch].reg + TALITOS_DESCBUF)); switch (desc_hdr & DESC_HDR_SEL0_MASK) { case DESC_HDR_SEL0_AFEU: @@ -1097,11 +1097,12 @@ */ static int sg_to_link_tbl_offset(struct scatterlist *sg, int sg_count, unsigned int offset, int datalen, int elen, - struct talitos_ptr *link_tbl_ptr) + struct talitos_ptr *link_tbl_ptr, int align) { int n_sg = elen ? sg_count + 1 : sg_count; int count = 0; int cryptlen = datalen + elen; + int padding = ALIGN(cryptlen, align) - cryptlen; while (cryptlen && sg && n_sg--) { unsigned int len = sg_dma_len(sg); @@ -1125,7 +1126,7 @@ offset += datalen; } to_talitos_ptr(link_tbl_ptr + count, - sg_dma_address(sg) + offset, len, 0); + sg_dma_address(sg) + offset, sg_next(sg) ? len : len + padding, 0); to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0); count++; cryptlen -= len; @@ -1148,10 +1149,11 @@ unsigned int len, struct talitos_edesc *edesc, struct talitos_ptr *ptr, int sg_count, unsigned int offset, int tbl_off, int elen, - bool force) + bool force, int align) { struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); + int aligned_len = ALIGN(len, align); if (!src) { to_talitos_ptr(ptr, 0, 0, is_sec1); @@ -1159,22 +1161,22 @@ } to_talitos_ptr_ext_set(ptr, elen, is_sec1); if (sg_count == 1 && !force) { - to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1); + to_talitos_ptr(ptr, sg_dma_address(src) + offset, aligned_len, is_sec1); return sg_count; } if (is_sec1) { - to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1); + to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, aligned_len, is_sec1); return sg_count; } sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len, elen, - &edesc->link_tbl[tbl_off]); + &edesc->link_tbl[tbl_off], align); if (sg_count == 1 && !force) { /* Only one segment now, so no link tbl needed*/ copy_talitos_ptr(ptr, &edesc->link_tbl[tbl_off], is_sec1); return sg_count; } to_talitos_ptr(ptr, edesc->dma_link_tbl + - tbl_off * sizeof(struct talitos_ptr), len, is_sec1); + tbl_off * sizeof(struct talitos_ptr), aligned_len, is_sec1); to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1); return sg_count; @@ -1186,7 +1188,7 @@ unsigned int offset, int tbl_off) { return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset, - tbl_off, 0, false); + tbl_off, 0, false, 1); } /* @@ -1255,7 +1257,7 @@ ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[4], sg_count, areq->assoclen, tbl_off, elen, - false); + false, 1); if (ret > 1) { tbl_off += ret; @@ -1275,7 +1277,7 @@ elen = 0; ret = talitos_sg_map_ext(dev, areq->dst, cryptlen, edesc, &desc->ptr[5], sg_count, areq->assoclen, tbl_off, elen, - is_ipsec_esp && !encrypt); + is_ipsec_esp && !encrypt, 1); tbl_off += ret; if (!encrypt && is_ipsec_esp) { @@ -1583,6 +1585,8 @@ bool sync_needed = false; struct talitos_private *priv = dev_get_drvdata(dev); bool is_sec1 = has_ftr_sec1(priv); + bool is_ctr = (desc->hdr & DESC_HDR_SEL0_MASK) == DESC_HDR_SEL0_AESU && + (desc->hdr & DESC_HDR_MODE0_AESU_MASK) == DESC_HDR_MODE0_AESU_CTR; /* first DWORD empty */ @@ -1603,8 +1607,8 @@ /* * cipher in */ - sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc, - &desc->ptr[3], sg_count, 0, 0); + sg_count = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, &desc->ptr[3], + sg_count, 0, 0, 0, false, is_ctr ? 16 : 1); if (sg_count > 1) sync_needed = true; --- linux-oracle-5.4.0.orig/drivers/crypto/talitos.h +++ linux-oracle-5.4.0/drivers/crypto/talitos.h @@ -344,6 +344,7 @@ /* primary execution unit mode (MODE0) and derivatives */ #define DESC_HDR_MODE0_ENCRYPT cpu_to_be32(0x00100000) +#define DESC_HDR_MODE0_AESU_MASK cpu_to_be32(0x00600000) #define DESC_HDR_MODE0_AESU_CBC cpu_to_be32(0x00200000) #define DESC_HDR_MODE0_AESU_CTR cpu_to_be32(0x00600000) #define DESC_HDR_MODE0_DEU_CBC cpu_to_be32(0x00400000) --- linux-oracle-5.4.0.orig/drivers/crypto/ux500/hash/hash_core.c +++ linux-oracle-5.4.0/drivers/crypto/ux500/hash/hash_core.c @@ -1009,6 +1009,7 @@ goto out; } } else if (req->nbytes == 0 && ctx->keylen > 0) { + ret = -EPERM; dev_err(device_data->dev, "%s: Empty message with keylength > 0, NOT supported\n", __func__); goto out; --- linux-oracle-5.4.0.orig/drivers/crypto/virtio/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/virtio/Kconfig @@ -5,7 +5,6 @@ select CRYPTO_AEAD select CRYPTO_BLKCIPHER select CRYPTO_ENGINE - default m help This driver provides support for virtio crypto device. If you choose 'M' here, this module will be called virtio_crypto. --- linux-oracle-5.4.0.orig/drivers/crypto/virtio/virtio_crypto_algs.c +++ linux-oracle-5.4.0/drivers/crypto/virtio/virtio_crypto_algs.c @@ -105,8 +105,6 @@ *alg = VIRTIO_CRYPTO_CIPHER_AES_CBC; break; default: - pr_err("virtio_crypto: Unsupported key length: %d\n", - key_len); return -EINVAL; } return 0; @@ -355,13 +353,18 @@ int err; unsigned long flags; struct scatterlist outhdr, iv_sg, status_sg, **sgs; - int i; u64 dst_len; unsigned int num_out = 0, num_in = 0; int sg_total; uint8_t *iv; + struct scatterlist *sg; src_nents = sg_nents_for_len(req->src, req->nbytes); + if (src_nents < 0) { + pr_err("Invalid number of src SG.\n"); + return src_nents; + } + dst_nents = sg_nents(req->dst); pr_debug("virtio_crypto: Number of sgs (src_nents: %d, dst_nents: %d)\n", @@ -407,6 +410,7 @@ goto free; } + dst_len = min_t(unsigned int, req->nbytes, dst_len); pr_debug("virtio_crypto: src_len: %u, dst_len: %llu\n", req->nbytes, dst_len); @@ -437,17 +441,22 @@ goto free; } memcpy(iv, req->info, ivsize); + if (!vc_sym_req->encrypt) + scatterwalk_map_and_copy(req->info, req->src, + req->nbytes - AES_BLOCK_SIZE, + AES_BLOCK_SIZE, 0); + sg_init_one(&iv_sg, iv, ivsize); sgs[num_out++] = &iv_sg; vc_sym_req->iv = iv; /* Source data */ - for (i = 0; i < src_nents; i++) - sgs[num_out++] = &req->src[i]; + for (sg = req->src; src_nents; sg = sg_next(sg), src_nents--) + sgs[num_out++] = sg; /* Destination data */ - for (i = 0; i < dst_nents; i++) - sgs[num_out + num_in++] = &req->dst[i]; + for (sg = req->dst; sg; sg = sg_next(sg)) + sgs[num_out + num_in++] = sg; /* Status */ sg_init_one(&status_sg, &vc_req->status, sizeof(vc_req->status)); @@ -484,6 +493,11 @@ /* Use the first data virtqueue as default */ struct data_queue *data_vq = &vcrypto->data_vq[0]; + if (!req->nbytes) + return 0; + if (req->nbytes % AES_BLOCK_SIZE) + return -EINVAL; + vc_req->dataq = data_vq; vc_req->alg_cb = virtio_crypto_dataq_sym_callback; vc_sym_req->ablkcipher_ctx = ctx; @@ -504,6 +518,11 @@ /* Use the first data virtqueue as default */ struct data_queue *data_vq = &vcrypto->data_vq[0]; + if (!req->nbytes) + return 0; + if (req->nbytes % AES_BLOCK_SIZE) + return -EINVAL; + vc_req->dataq = data_vq; vc_req->alg_cb = virtio_crypto_dataq_sym_callback; vc_sym_req->ablkcipher_ctx = ctx; @@ -563,10 +582,15 @@ struct ablkcipher_request *req, int err) { - crypto_finalize_ablkcipher_request(vc_sym_req->base.dataq->engine, - req, err); + if (vc_sym_req->encrypt) + scatterwalk_map_and_copy(req->info, req->dst, + req->nbytes - AES_BLOCK_SIZE, + AES_BLOCK_SIZE, 0); kzfree(vc_sym_req->iv); virtcrypto_clear_request(&vc_sym_req->base); + + crypto_finalize_ablkcipher_request(vc_sym_req->base.dataq->engine, + req, err); } static struct virtio_crypto_algo virtio_crypto_algs[] = { { --- linux-oracle-5.4.0.orig/drivers/crypto/virtio/virtio_crypto_common.h +++ linux-oracle-5.4.0/drivers/crypto/virtio/virtio_crypto_common.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ char name[32]; struct crypto_engine *engine; + struct tasklet_struct done_task; }; struct virtio_crypto { --- linux-oracle-5.4.0.orig/drivers/crypto/virtio/virtio_crypto_core.c +++ linux-oracle-5.4.0/drivers/crypto/virtio/virtio_crypto_core.c @@ -22,27 +22,28 @@ } } -static void virtcrypto_dataq_callback(struct virtqueue *vq) +static void virtcrypto_done_task(unsigned long data) { - struct virtio_crypto *vcrypto = vq->vdev->priv; + struct data_queue *data_vq = (struct data_queue *)data; + struct virtqueue *vq = data_vq->vq; struct virtio_crypto_request *vc_req; - unsigned long flags; unsigned int len; - unsigned int qid = vq->index; - spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags); do { virtqueue_disable_cb(vq); while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { - spin_unlock_irqrestore( - &vcrypto->data_vq[qid].lock, flags); if (vc_req->alg_cb) vc_req->alg_cb(vc_req, len); - spin_lock_irqsave( - &vcrypto->data_vq[qid].lock, flags); } } while (!virtqueue_enable_cb(vq)); - spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags); +} + +static void virtcrypto_dataq_callback(struct virtqueue *vq) +{ + struct virtio_crypto *vcrypto = vq->vdev->priv; + struct data_queue *dq = &vcrypto->data_vq[vq->index]; + + tasklet_schedule(&dq->done_task); } static int virtcrypto_find_vqs(struct virtio_crypto *vi) @@ -99,6 +100,8 @@ ret = -ENOMEM; goto err_engine; } + tasklet_init(&vi->data_vq[i].done_task, virtcrypto_done_task, + (unsigned long)&vi->data_vq[i]); } kfree(names); @@ -431,11 +434,14 @@ static void virtcrypto_remove(struct virtio_device *vdev) { struct virtio_crypto *vcrypto = vdev->priv; + int i; dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); if (virtcrypto_dev_started(vcrypto)) virtcrypto_dev_stop(vcrypto); + for (i = 0; i < vcrypto->max_data_queues; i++) + tasklet_kill(&vcrypto->data_vq[i].done_task); vdev->config->reset(vdev); virtcrypto_free_unused_reqs(vcrypto); virtcrypto_clear_crypto_engines(vcrypto); --- linux-oracle-5.4.0.orig/drivers/crypto/vmx/Kconfig +++ linux-oracle-5.4.0/drivers/crypto/vmx/Kconfig @@ -2,7 +2,11 @@ config CRYPTO_DEV_VMX_ENCRYPT tristate "Encryption acceleration support on P8 CPU" depends on CRYPTO_DEV_VMX + select CRYPTO_AES + select CRYPTO_CBC + select CRYPTO_CTR select CRYPTO_GHASH + select CRYPTO_XTS default m help Support for VMX cryptographic acceleration instructions on Power8 CPU. --- linux-oracle-5.4.0.orig/drivers/crypto/vmx/Makefile +++ linux-oracle-5.4.0/drivers/crypto/vmx/Makefile @@ -3,13 +3,13 @@ vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) -TARGET := linux-ppc64le +override flavour := linux-ppc64le else -TARGET := linux-ppc64 +override flavour := linux-ppc64 endif quiet_cmd_perl = PERL $@ - cmd_perl = $(PERL) $(<) $(TARGET) > $(@) + cmd_perl = $(PERL) $(<) $(flavour) > $(@) targets += aesp8-ppc.S ghashp8-ppc.S --- linux-oracle-5.4.0.orig/drivers/crypto/vmx/aes_xts.c +++ linux-oracle-5.4.0/drivers/crypto/vmx/aes_xts.c @@ -84,6 +84,9 @@ u8 tweak[AES_BLOCK_SIZE]; int ret; + if (req->cryptlen < AES_BLOCK_SIZE) + return -EINVAL; + if (!crypto_simd_usable() || (req->cryptlen % XTS_BLOCK_SIZE) != 0) { struct skcipher_request *subreq = skcipher_request_ctx(req); --- linux-oracle-5.4.0.orig/drivers/dax/bus.c +++ linux-oracle-5.4.0/drivers/dax/bus.c @@ -227,7 +227,7 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id, struct resource *res, int target_node, unsigned int align, - unsigned long pfn_flags) + unsigned long long pfn_flags) { struct dax_region *dax_region; --- linux-oracle-5.4.0.orig/drivers/dax/bus.h +++ linux-oracle-5.4.0/drivers/dax/bus.h @@ -11,7 +11,7 @@ void dax_region_put(struct dax_region *dax_region); struct dax_region *alloc_dax_region(struct device *parent, int region_id, struct resource *res, int target_node, unsigned int align, - unsigned long flags); + unsigned long long flags); enum dev_dax_subsys { DEV_DAX_BUS, --- linux-oracle-5.4.0.orig/drivers/dax/dax-private.h +++ linux-oracle-5.4.0/drivers/dax/dax-private.h @@ -32,7 +32,7 @@ struct device *dev; unsigned int align; struct resource res; - unsigned long pfn_flags; + unsigned long long pfn_flags; }; /** --- linux-oracle-5.4.0.orig/drivers/dax/kmem.c +++ linux-oracle-5.4.0/drivers/dax/kmem.c @@ -22,6 +22,7 @@ resource_size_t kmem_size; resource_size_t kmem_end; struct resource *new_res; + const char *new_res_name; int numa_node; int rc; @@ -48,11 +49,16 @@ kmem_size &= ~(memory_block_size_bytes() - 1); kmem_end = kmem_start + kmem_size; - /* Region is permanently reserved. Hot-remove not yet implemented. */ - new_res = request_mem_region(kmem_start, kmem_size, dev_name(dev)); + new_res_name = kstrdup(dev_name(dev), GFP_KERNEL); + if (!new_res_name) + return -ENOMEM; + + /* Region is permanently reserved if hotremove fails. */ + new_res = request_mem_region(kmem_start, kmem_size, new_res_name); if (!new_res) { dev_warn(dev, "could not reserve region [%pa-%pa]\n", &kmem_start, &kmem_end); + kfree(new_res_name); return -EBUSY; } @@ -63,12 +69,12 @@ * unknown to us that will break add_memory() below. */ new_res->flags = IORESOURCE_SYSTEM_RAM; - new_res->name = dev_name(dev); rc = add_memory(numa_node, new_res->start, resource_size(new_res)); if (rc) { release_resource(new_res); kfree(new_res); + kfree(new_res_name); return rc; } dev_dax->dax_kmem_res = new_res; @@ -83,6 +89,7 @@ struct resource *res = dev_dax->dax_kmem_res; resource_size_t kmem_start = res->start; resource_size_t kmem_size = resource_size(res); + const char *res_name = res->name; int rc; /* @@ -102,6 +109,7 @@ /* Release and free dax resources */ release_resource(res); kfree(res); + kfree(res_name); dev_dax->dax_kmem_res = NULL; return 0; --- linux-oracle-5.4.0.orig/drivers/dax/super.c +++ linux-oracle-5.4.0/drivers/dax/super.c @@ -318,11 +318,15 @@ bool dax_supported(struct dax_device *dax_dev, struct block_device *bdev, int blocksize, sector_t start, sector_t len) { + if (!dax_dev) + return false; + if (!dax_alive(dax_dev)) return false; return dax_dev->ops->dax_supported(dax_dev, bdev, blocksize, start, len); } +EXPORT_SYMBOL_GPL(dax_supported); size_t dax_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i) @@ -687,6 +691,7 @@ static void dax_fs_exit(void) { kern_unmount(dax_mnt); + rcu_barrier(); kmem_cache_destroy(dax_cache); } @@ -716,6 +721,7 @@ static void __exit dax_core_exit(void) { + dax_bus_exit(); unregister_chrdev_region(dax_devt, MINORMASK+1); ida_destroy(&dax_minor_ida); dax_fs_exit(); --- linux-oracle-5.4.0.orig/drivers/devfreq/Kconfig +++ linux-oracle-5.4.0/drivers/devfreq/Kconfig @@ -99,6 +99,7 @@ ARCH_TEGRA_210_SOC || \ COMPILE_TEST select PM_OPP + depends on COMMON_CLK help This adds the DEVFREQ driver for the Tegra family of SoCs. It reads ACTMON counters of memory controllers and adjusts the @@ -117,7 +118,8 @@ config ARM_RK3399_DMC_DEVFREQ tristate "ARM RK3399 DMC DEVFREQ Driver" - depends on ARCH_ROCKCHIP + depends on (ARCH_ROCKCHIP && HAVE_ARM_SMCCC) || \ + (COMPILE_TEST && HAVE_ARM_SMCCC) select DEVFREQ_EVENT_ROCKCHIP_DFI select DEVFREQ_GOV_SIMPLE_ONDEMAND select PM_DEVFREQ_EVENT --- linux-oracle-5.4.0.orig/drivers/devfreq/devfreq.c +++ linux-oracle-5.4.0/drivers/devfreq/devfreq.c @@ -160,6 +160,7 @@ int lev, prev_lev, ret = 0; unsigned long cur_time; + lockdep_assert_held(&devfreq->lock); cur_time = jiffies; /* Immediately exit if previous_freq is not initialized yet. */ @@ -318,7 +319,7 @@ devfreq->previous_freq = new_freq; if (devfreq->suspend_freq) - devfreq->resume_freq = cur_freq; + devfreq->resume_freq = new_freq; return err; } @@ -550,26 +551,30 @@ void *devp) { struct devfreq *devfreq = container_of(nb, struct devfreq, nb); - int ret; + int err = -EINVAL; mutex_lock(&devfreq->lock); devfreq->scaling_min_freq = find_available_min_freq(devfreq); - if (!devfreq->scaling_min_freq) { - mutex_unlock(&devfreq->lock); - return -EINVAL; - } + if (!devfreq->scaling_min_freq) + goto out; devfreq->scaling_max_freq = find_available_max_freq(devfreq); if (!devfreq->scaling_max_freq) { - mutex_unlock(&devfreq->lock); - return -EINVAL; + devfreq->scaling_max_freq = ULONG_MAX; + goto out; } - ret = update_devfreq(devfreq); + err = update_devfreq(devfreq); + +out: mutex_unlock(&devfreq->lock); + if (err) + dev_err(devfreq->dev.parent, + "failed to update frequency from OPP notifier (%d)\n", + err); - return ret; + return NOTIFY_OK; } /** @@ -583,11 +588,6 @@ struct devfreq *devfreq = to_devfreq(dev); mutex_lock(&devfreq_list_lock); - if (IS_ERR(find_device_devfreq(devfreq->dev.parent))) { - mutex_unlock(&devfreq_list_lock); - dev_warn(&devfreq->dev, "releasing devfreq which doesn't exist\n"); - return; - } list_del(&devfreq->node); mutex_unlock(&devfreq_list_lock); @@ -595,6 +595,7 @@ devfreq->profile->exit(devfreq->dev.parent); mutex_destroy(&devfreq->lock); + srcu_cleanup_notifier_head(&devfreq->transition_notifier_list); kfree(devfreq); } @@ -603,8 +604,7 @@ * @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. * @governor_name: name of the policy to choose frequency. - * @data: private data for the governor. The devfreq framework does not - * touch this value. + * @data: devfreq driver pass to governors, governor should not change it. */ struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, @@ -613,7 +613,6 @@ { struct devfreq *devfreq; struct devfreq_governor *governor; - static atomic_t devfreq_no = ATOMIC_INIT(-1); int err = 0; if (!dev || !profile || !governor_name) { @@ -642,6 +641,7 @@ devfreq->dev.parent = dev; devfreq->dev.class = devfreq_class; devfreq->dev.release = devfreq_dev_release; + INIT_LIST_HEAD(&devfreq->node); devfreq->profile = profile; strncpy(devfreq->governor_name, governor_name, DEVFREQ_NAME_LEN); devfreq->previous_freq = profile->initial_freq; @@ -676,8 +676,7 @@ devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev); atomic_set(&devfreq->suspend_count, 0); - dev_set_name(&devfreq->dev, "devfreq%d", - atomic_inc_return(&devfreq_no)); + dev_set_name(&devfreq->dev, "%s", dev_name(dev)); err = device_register(&devfreq->dev); if (err) { mutex_unlock(&devfreq->lock); @@ -789,8 +788,7 @@ * @dev: the device to add devfreq feature. * @profile: device-specific profile to run devfreq. * @governor_name: name of the policy to choose frequency. - * @data: private data for the governor. The devfreq framework does not - * touch this value. + * @data: devfreq driver pass to governors, governor should not change it. * * This function manages automatically the memory of devfreq device using device * resource management and simplify the free operation for memory of devfreq @@ -903,7 +901,9 @@ } if (devfreq->suspend_freq) { + mutex_lock(&devfreq->lock); ret = devfreq_set_target(devfreq, devfreq->suspend_freq, 0); + mutex_unlock(&devfreq->lock); if (ret) return ret; } @@ -931,7 +931,9 @@ return 0; if (devfreq->resume_freq) { + mutex_lock(&devfreq->lock); ret = devfreq_set_target(devfreq, devfreq->resume_freq, 0); + mutex_unlock(&devfreq->lock); if (ret) return ret; } @@ -1111,6 +1113,14 @@ } EXPORT_SYMBOL(devfreq_remove_governor); +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct devfreq *devfreq = to_devfreq(dev); + return sprintf(buf, "%s\n", dev_name(devfreq->dev.parent)); +} +static DEVICE_ATTR_RO(name); + static ssize_t governor_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1195,7 +1205,7 @@ * The devfreq with immutable governor (e.g., passive) shows * only own governor. */ - if (df->governor->immutable) { + if (df->governor && df->governor->immutable) { count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, "%s ", df->governor_name); /* @@ -1393,47 +1403,75 @@ struct device_attribute *attr, char *buf) { struct devfreq *devfreq = to_devfreq(dev); - ssize_t len; + ssize_t len = 0; int i, j; unsigned int max_state = devfreq->profile->max_state; + if (max_state == 0) + return scnprintf(buf, PAGE_SIZE, "Not Supported.\n"); + + mutex_lock(&devfreq->lock); if (!devfreq->stop_polling && - devfreq_update_status(devfreq, devfreq->previous_freq)) + devfreq_update_status(devfreq, devfreq->previous_freq)) { + mutex_unlock(&devfreq->lock); return 0; - if (max_state == 0) - return sprintf(buf, "Not Supported.\n"); + } + mutex_unlock(&devfreq->lock); - len = sprintf(buf, " From : To\n"); - len += sprintf(buf + len, " :"); - for (i = 0; i < max_state; i++) - len += sprintf(buf + len, "%10lu", - devfreq->profile->freq_table[i]); + len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " :"); + for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu", + devfreq->profile->freq_table[i]); + } + if (len >= PAGE_SIZE - 1) + return PAGE_SIZE - 1; - len += sprintf(buf + len, " time(ms)\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " time(ms)\n"); for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; if (devfreq->profile->freq_table[i] == devfreq->previous_freq) { - len += sprintf(buf + len, "*"); + len += scnprintf(buf + len, PAGE_SIZE - len, "*"); } else { - len += sprintf(buf + len, " "); + len += scnprintf(buf + len, PAGE_SIZE - len, " "); } - len += sprintf(buf + len, "%10lu:", - devfreq->profile->freq_table[i]); - for (j = 0; j < max_state; j++) - len += sprintf(buf + len, "%10u", - devfreq->trans_table[(i * max_state) + j]); - len += sprintf(buf + len, "%10u\n", - jiffies_to_msecs(devfreq->time_in_state[i])); + if (len >= PAGE_SIZE - 1) + break; + + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu:", + devfreq->profile->freq_table[i]); + for (j = 0; j < max_state; j++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10u", + devfreq->trans_table[(i * max_state) + j]); + } + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10u\n", + jiffies_to_msecs(devfreq->time_in_state[i])); + } + + if (len < PAGE_SIZE - 1) + len += scnprintf(buf + len, PAGE_SIZE - len, "Total transition : %u\n", + devfreq->total_trans); + + if (len >= PAGE_SIZE - 1) { + pr_warn_once("devfreq transition table exceeds PAGE_SIZE. Disabling\n"); + return -EFBIG; } - len += sprintf(buf + len, "Total transition : %u\n", - devfreq->total_trans); return len; } static DEVICE_ATTR_RO(trans_stat); static struct attribute *devfreq_attrs[] = { + &dev_attr_name.attr, &dev_attr_governor.attr, &dev_attr_available_governors.attr, &dev_attr_cur_freq.attr, --- linux-oracle-5.4.0.orig/drivers/devfreq/event/Kconfig +++ linux-oracle-5.4.0/drivers/devfreq/event/Kconfig @@ -34,7 +34,7 @@ config DEVFREQ_EVENT_ROCKCHIP_DFI tristate "ROCKCHIP DFI DEVFREQ event Driver" - depends on ARCH_ROCKCHIP + depends on ARCH_ROCKCHIP || COMPILE_TEST help This add the devfreq-event driver for Rockchip SoC. It provides DFI (DDR Monitor Module) driver to count ddr load. --- linux-oracle-5.4.0.orig/drivers/devfreq/event/exynos-ppmu.c +++ linux-oracle-5.4.0/drivers/devfreq/event/exynos-ppmu.c @@ -101,17 +101,22 @@ PPMU_EVENT(dmc1_1), }; -static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev) +static int __exynos_ppmu_find_ppmu_id(const char *edev_name) { int i; for (i = 0; i < ARRAY_SIZE(ppmu_events); i++) - if (!strcmp(edev->desc->name, ppmu_events[i].name)) + if (!strcmp(edev_name, ppmu_events[i].name)) return ppmu_events[i].id; return -EINVAL; } +static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev *edev) +{ + return __exynos_ppmu_find_ppmu_id(edev->desc->name); +} + /* * The devfreq-event ops structure for PPMU v1.1 */ @@ -509,15 +514,19 @@ count = of_get_child_count(events_np); desc = devm_kcalloc(dev, count, sizeof(*desc), GFP_KERNEL); - if (!desc) + if (!desc) { + of_node_put(events_np); return -ENOMEM; + } info->num_events = count; of_id = of_match_device(exynos_ppmu_id_match, dev); if (of_id) info->ppmu_type = (enum exynos_ppmu_type)of_id->data; - else + else { + of_node_put(events_np); return -EINVAL; + } j = 0; for_each_child_of_node(events_np, node) { @@ -556,13 +565,11 @@ * use default if not. */ if (info->ppmu_type == EXYNOS_TYPE_PPMU_V2) { - struct devfreq_event_dev edev; int id; /* Not all registers take the same value for * read+write data count. */ - edev.desc = &desc[j]; - id = exynos_ppmu_find_ppmu_id(&edev); + id = __exynos_ppmu_find_ppmu_id(desc[j].name); switch (id) { case PPMU_PMNCNT0: --- linux-oracle-5.4.0.orig/drivers/devfreq/governor_userspace.c +++ linux-oracle-5.4.0/drivers/devfreq/governor_userspace.c @@ -21,7 +21,7 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) { - struct userspace_data *data = df->data; + struct userspace_data *data = df->governor_data; if (data->valid) *freq = data->user_frequency; @@ -40,7 +40,7 @@ int err = 0; mutex_lock(&devfreq->lock); - data = devfreq->data; + data = devfreq->governor_data; sscanf(buf, "%lu", &wanted); data->user_frequency = wanted; @@ -60,7 +60,7 @@ int err = 0; mutex_lock(&devfreq->lock); - data = devfreq->data; + data = devfreq->governor_data; if (data->valid) err = sprintf(buf, "%lu\n", data->user_frequency); @@ -91,7 +91,7 @@ goto out; } data->valid = false; - devfreq->data = data; + devfreq->governor_data = data; err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group); out: @@ -107,8 +107,8 @@ if (devfreq->dev.kobj.sd) sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); - kfree(devfreq->data); - devfreq->data = NULL; + kfree(devfreq->governor_data); + devfreq->governor_data = NULL; } static int devfreq_userspace_handler(struct devfreq *devfreq, --- linux-oracle-5.4.0.orig/drivers/devfreq/rk3399_dmc.c +++ linux-oracle-5.4.0/drivers/devfreq/rk3399_dmc.c @@ -95,18 +95,20 @@ mutex_lock(&dmcfreq->lock); - if (target_rate >= dmcfreq->odt_dis_freq) - odt_enable = true; - - /* - * This makes a SMC call to the TF-A to set the DDR PD (power-down) - * timings and to enable or disable the ODT (on-die termination) - * resistors. - */ - arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0, - dmcfreq->odt_pd_arg1, - ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, - odt_enable, 0, 0, 0, &res); + if (dmcfreq->regmap_pmu) { + if (target_rate >= dmcfreq->odt_dis_freq) + odt_enable = true; + + /* + * This makes a SMC call to the TF-A to set the DDR PD + * (power-down) timings and to enable or disable the + * ODT (on-die termination) resistors. + */ + arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0, + dmcfreq->odt_pd_arg1, + ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, + odt_enable, 0, 0, 0, &res); + } /* * If frequency scaling from low to high, adjust voltage first. @@ -364,16 +366,21 @@ if (res.a0) { dev_err(dev, "Failed to set dram param: %ld\n", res.a0); - return -EINVAL; + ret = -EINVAL; + goto err_edev; } } } node = of_parse_phandle(np, "rockchip,pmu", 0); - if (node) { - data->regmap_pmu = syscon_node_to_regmap(node); - if (IS_ERR(data->regmap_pmu)) - return PTR_ERR(data->regmap_pmu); + if (!node) + goto no_pmu; + + data->regmap_pmu = syscon_node_to_regmap(node); + of_node_put(node); + if (IS_ERR(data->regmap_pmu)) { + ret = PTR_ERR(data->regmap_pmu); + goto err_edev; } regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); @@ -391,9 +398,11 @@ data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq; break; default: - return -EINVAL; + ret = -EINVAL; + goto err_edev; }; +no_pmu: arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, ROCKCHIP_SIP_CONFIG_DRAM_INIT, 0, 0, 0, 0, &res); @@ -425,7 +434,8 @@ */ if (dev_pm_opp_of_add_table(dev)) { dev_err(dev, "Invalid operating-points in device tree.\n"); - return -EINVAL; + ret = -EINVAL; + goto err_edev; } of_property_read_u32(np, "upthreshold", @@ -465,6 +475,9 @@ err_free_opp: dev_pm_opp_of_remove_table(&pdev->dev); +err_edev: + devfreq_event_disable_edev(data->edev); + return ret; } @@ -472,6 +485,8 @@ { struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev); + devfreq_event_disable_edev(dmcfreq->edev); + /* * Before remove the opp table we need to unregister the opp notifier. */ --- linux-oracle-5.4.0.orig/drivers/devfreq/tegra30-devfreq.c +++ linux-oracle-5.4.0/drivers/devfreq/tegra30-devfreq.c @@ -68,6 +68,8 @@ #define KHZ 1000 +#define KHZ_MAX (ULONG_MAX / KHZ) + /* Assume that the bus is saturated if the utilization is 25% */ #define BUS_SATURATION_RATIO 25 @@ -169,7 +171,7 @@ }; static struct tegra_actmon_emc_ratio actmon_emc_ratios[] = { - { 1400000, ULONG_MAX }, + { 1400000, KHZ_MAX }, { 1200000, 750000 }, { 1100000, 600000 }, { 1000000, 500000 }, --- linux-oracle-5.4.0.orig/drivers/dio/dio.c +++ linux-oracle-5.4.0/drivers/dio/dio.c @@ -110,6 +110,12 @@ #endif /* CONFIG_DIO_CONSTANTS */ +static void dio_dev_release(struct device *dev) +{ + struct dio_dev *ddev = container_of(dev, typeof(struct dio_dev), dev); + kfree(ddev); +} + int __init dio_find(int deviceid) { /* Called to find a DIO device before the full bus scan has run. @@ -222,6 +228,7 @@ dev->bus = &dio_bus; dev->dev.parent = &dio_bus.dev; dev->dev.bus = &dio_bus_type; + dev->dev.release = dio_dev_release; dev->scode = scode; dev->resource.start = pa; dev->resource.end = pa + DIO_SIZE(scode, va); @@ -249,6 +256,7 @@ if (error) { pr_err("DIO: Error registering device %s\n", dev->name); + put_device(&dev->dev); continue; } error = dio_create_sysfs_dev_files(dev); --- linux-oracle-5.4.0.orig/drivers/dma-buf/dma-buf.c +++ linux-oracle-5.4.0/drivers/dma-buf/dma-buf.c @@ -45,46 +45,22 @@ size_t ret = 0; dmabuf = dentry->d_fsdata; - mutex_lock(&dmabuf->lock); + spin_lock(&dmabuf->name_lock); if (dmabuf->name) ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN); - mutex_unlock(&dmabuf->lock); + spin_unlock(&dmabuf->name_lock); return dynamic_dname(dentry, buffer, buflen, "/%s:%s", dentry->d_name.name, ret > 0 ? name : ""); } -static const struct dentry_operations dma_buf_dentry_ops = { - .d_dname = dmabuffs_dname, -}; - -static struct vfsmount *dma_buf_mnt; - -static int dma_buf_fs_init_context(struct fs_context *fc) -{ - struct pseudo_fs_context *ctx; - - ctx = init_pseudo(fc, DMA_BUF_MAGIC); - if (!ctx) - return -ENOMEM; - ctx->dops = &dma_buf_dentry_ops; - return 0; -} - -static struct file_system_type dma_buf_fs_type = { - .name = "dmabuf", - .init_fs_context = dma_buf_fs_init_context, - .kill_sb = kill_anon_super, -}; - -static int dma_buf_release(struct inode *inode, struct file *file) +static void dma_buf_release(struct dentry *dentry) { struct dma_buf *dmabuf; - if (!is_dma_buf_file(file)) - return -EINVAL; - - dmabuf = file->private_data; + dmabuf = dentry->d_fsdata; + if (unlikely(!dmabuf)) + return; BUG_ON(dmabuf->vmapping_counter); @@ -100,18 +76,55 @@ dmabuf->ops->release(dmabuf); - mutex_lock(&db_list.lock); - list_del(&dmabuf->list_node); - mutex_unlock(&db_list.lock); - if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) dma_resv_fini(dmabuf->resv); + WARN_ON(!list_empty(&dmabuf->attachments)); module_put(dmabuf->owner); + kfree(dmabuf->name); kfree(dmabuf); +} + +static int dma_buf_file_release(struct inode *inode, struct file *file) +{ + struct dma_buf *dmabuf; + + if (!is_dma_buf_file(file)) + return -EINVAL; + + dmabuf = file->private_data; + + mutex_lock(&db_list.lock); + list_del(&dmabuf->list_node); + mutex_unlock(&db_list.lock); + return 0; } +static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +}; + +static struct vfsmount *dma_buf_mnt; + +static int dma_buf_fs_init_context(struct fs_context *fc) +{ + struct pseudo_fs_context *ctx; + + ctx = init_pseudo(fc, DMA_BUF_MAGIC); + if (!ctx) + return -ENOMEM; + ctx->dops = &dma_buf_dentry_ops; + return 0; +} + +static struct file_system_type dma_buf_fs_type = { + .name = "dmabuf", + .init_fs_context = dma_buf_fs_init_context, + .kill_sb = kill_anon_super, +}; + static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; @@ -340,8 +353,10 @@ kfree(name); goto out_unlock; } + spin_lock(&dmabuf->name_lock); kfree(dmabuf->name); dmabuf->name = name; + spin_unlock(&dmabuf->name_lock); out_unlock: mutex_unlock(&dmabuf->lock); @@ -387,7 +402,8 @@ return ret; - case DMA_BUF_SET_NAME: + case DMA_BUF_SET_NAME_A: + case DMA_BUF_SET_NAME_B: return dma_buf_set_name(dmabuf, (const char __user *)arg); default: @@ -403,14 +419,14 @@ /* Don't count the temporary reference taken inside procfs seq_show */ seq_printf(m, "count:\t%ld\n", file_count(dmabuf->file) - 1); seq_printf(m, "exp_name:\t%s\n", dmabuf->exp_name); - mutex_lock(&dmabuf->lock); + spin_lock(&dmabuf->name_lock); if (dmabuf->name) seq_printf(m, "name:\t%s\n", dmabuf->name); - mutex_unlock(&dmabuf->lock); + spin_unlock(&dmabuf->name_lock); } static const struct file_operations dma_buf_fops = { - .release = dma_buf_release, + .release = dma_buf_file_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll, @@ -539,6 +555,7 @@ dmabuf->size = exp_info->size; dmabuf->exp_name = exp_info->exp_name; dmabuf->owner = exp_info->owner; + spin_lock_init(&dmabuf->name_lock); init_waitqueue_head(&dmabuf->poll); dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll; dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0; --- linux-oracle-5.4.0.orig/drivers/dma-buf/dma-fence-array.c +++ linux-oracle-5.4.0/drivers/dma-buf/dma-fence-array.c @@ -103,8 +103,38 @@ static bool dma_fence_array_signaled(struct dma_fence *fence) { struct dma_fence_array *array = to_dma_fence_array(fence); + int num_pending; + unsigned int i; - return atomic_read(&array->num_pending) <= 0; + /* + * We need to read num_pending before checking the enable_signal bit + * to avoid racing with the enable_signaling() implementation, which + * might decrement the counter, and cause a partial check. + * atomic_read_acquire() pairs with atomic_dec_and_test() in + * dma_fence_array_enable_signaling() + * + * The !--num_pending check is here to account for the any_signaled case + * if we race with enable_signaling(), that means the !num_pending check + * in the is_signalling_enabled branch might be outdated (num_pending + * might have been decremented), but that's fine. The user will get the + * right value when testing again later. + */ + num_pending = atomic_read_acquire(&array->num_pending); + if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &array->base.flags)) { + if (num_pending <= 0) + goto signal; + return false; + } + + for (i = 0; i < array->num_fences; ++i) { + if (dma_fence_is_signaled(array->fences[i]) && !--num_pending) + goto signal; + } + return false; + +signal: + dma_fence_array_clear_pending_error(array); + return true; } static void dma_fence_array_release(struct dma_fence *fence) --- linux-oracle-5.4.0.orig/drivers/dma-buf/dma-fence.c +++ linux-oracle-5.4.0/drivers/dma-buf/dma-fence.c @@ -273,6 +273,30 @@ } EXPORT_SYMBOL(dma_fence_free); +static bool __dma_fence_enable_signaling(struct dma_fence *fence) +{ + bool was_set; + + lockdep_assert_held(fence->lock); + + was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, + &fence->flags); + + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) + return false; + + if (!was_set && fence->ops->enable_signaling) { + trace_dma_fence_enable_signal(fence); + + if (!fence->ops->enable_signaling(fence)) { + dma_fence_signal_locked(fence); + return false; + } + } + + return true; +} + /** * dma_fence_enable_sw_signaling - enable signaling on fence * @fence: the fence to enable @@ -285,19 +309,12 @@ { unsigned long flags; - if (!test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &fence->flags) && - !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && - fence->ops->enable_signaling) { - trace_dma_fence_enable_signal(fence); - - spin_lock_irqsave(fence->lock, flags); - - if (!fence->ops->enable_signaling(fence)) - dma_fence_signal_locked(fence); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) + return; - spin_unlock_irqrestore(fence->lock, flags); - } + spin_lock_irqsave(fence->lock, flags); + __dma_fence_enable_signaling(fence); + spin_unlock_irqrestore(fence->lock, flags); } EXPORT_SYMBOL(dma_fence_enable_sw_signaling); @@ -331,7 +348,6 @@ { unsigned long flags; int ret = 0; - bool was_set; if (WARN_ON(!fence || !func)) return -EINVAL; @@ -343,25 +359,14 @@ spin_lock_irqsave(fence->lock, flags); - was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &fence->flags); - - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) - ret = -ENOENT; - else if (!was_set && fence->ops->enable_signaling) { - trace_dma_fence_enable_signal(fence); - - if (!fence->ops->enable_signaling(fence)) { - dma_fence_signal_locked(fence); - ret = -ENOENT; - } - } - - if (!ret) { + if (__dma_fence_enable_signaling(fence)) { cb->func = func; list_add_tail(&cb->node, &fence->cb_list); - } else + } else { INIT_LIST_HEAD(&cb->node); + ret = -ENOENT; + } + spin_unlock_irqrestore(fence->lock, flags); return ret; @@ -461,7 +466,6 @@ struct default_wait_cb cb; unsigned long flags; signed long ret = timeout ? timeout : 1; - bool was_set; if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) return ret; @@ -473,21 +477,9 @@ goto out; } - was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, - &fence->flags); - - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) + if (!__dma_fence_enable_signaling(fence)) goto out; - if (!was_set && fence->ops->enable_signaling) { - trace_dma_fence_enable_signal(fence); - - if (!fence->ops->enable_signaling(fence)) { - dma_fence_signal_locked(fence); - goto out; - } - } - if (!timeout) { ret = 0; goto out; --- linux-oracle-5.4.0.orig/drivers/dma-buf/dma-resv.c +++ linux-oracle-5.4.0/drivers/dma-buf/dma-resv.c @@ -161,7 +161,7 @@ max = max(old->shared_count + num_fences, old->shared_max * 2); } else { - max = 4; + max = max(4ul, roundup_pow_of_two(num_fences)); } new = dma_resv_list_alloc(max); --- linux-oracle-5.4.0.orig/drivers/dma-buf/sw_sync.c +++ linux-oracle-5.4.0/drivers/dma-buf/sw_sync.c @@ -191,6 +191,7 @@ */ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) { + LIST_HEAD(signalled); struct sync_pt *pt, *next; trace_sync_timeline(obj); @@ -203,21 +204,20 @@ if (!timeline_fence_signaled(&pt->base)) break; - list_del_init(&pt->link); + dma_fence_get(&pt->base); + + list_move_tail(&pt->link, &signalled); rb_erase(&pt->node, &obj->pt_tree); - /* - * A signal callback may release the last reference to this - * fence, causing it to be freed. That operation has to be - * last to avoid a use after free inside this loop, and must - * be after we remove the fence from the timeline in order to - * prevent deadlocking on timeline->lock inside - * timeline_fence_release(). - */ dma_fence_signal_locked(&pt->base); } spin_unlock_irq(&obj->lock); + + list_for_each_entry_safe(pt, next, &signalled, link) { + list_del_init(&pt->link); + dma_fence_put(&pt->base); + } } /** --- linux-oracle-5.4.0.orig/drivers/dma-buf/sync_debug.c +++ linux-oracle-5.4.0/drivers/dma-buf/sync_debug.c @@ -110,12 +110,12 @@ seq_printf(s, "%s: %d\n", obj->name, obj->value); - spin_lock_irq(&obj->lock); + spin_lock(&obj->lock); /* Caller already disabled IRQ. */ list_for_each(pos, &obj->pt_list) { struct sync_pt *pt = container_of(pos, struct sync_pt, link); sync_print_fence(s, &pt->base, false); } - spin_unlock_irq(&obj->lock); + spin_unlock(&obj->lock); } static void sync_print_sync_file(struct seq_file *s, --- linux-oracle-5.4.0.orig/drivers/dma-buf/sync_file.c +++ linux-oracle-5.4.0/drivers/dma-buf/sync_file.c @@ -211,8 +211,8 @@ struct sync_file *b) { struct sync_file *sync_file; - struct dma_fence **fences, **nfences, **a_fences, **b_fences; - int i, i_a, i_b, num_fences, a_num_fences, b_num_fences; + struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences; + int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences; sync_file = sync_file_alloc(); if (!sync_file) @@ -221,7 +221,7 @@ a_fences = get_fences(a, &a_num_fences); b_fences = get_fences(b, &b_num_fences); if (a_num_fences > INT_MAX - b_num_fences) - return NULL; + goto err; num_fences = a_num_fences + b_num_fences; @@ -236,7 +236,7 @@ * If a sync_file can only be created with sync_file_merge * and sync_file_create, this is a reasonable assumption. */ - for (i = i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { + for (i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { struct dma_fence *pt_a = a_fences[i_a]; struct dma_fence *pt_b = b_fences[i_b]; @@ -278,15 +278,16 @@ fences = nfences; } - if (sync_file_set_fence(sync_file, fences, i) < 0) { - kfree(fences); + if (sync_file_set_fence(sync_file, fences, i) < 0) goto err; - } strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); return sync_file; err: + while (i) + dma_fence_put(fences[--i]); + kfree(fences); fput(sync_file->file); return NULL; --- linux-oracle-5.4.0.orig/drivers/dma-buf/udmabuf.c +++ linux-oracle-5.4.0/drivers/dma-buf/udmabuf.c @@ -24,8 +24,11 @@ { struct vm_area_struct *vma = vmf->vma; struct udmabuf *ubuf = vma->vm_private_data; + pgoff_t pgoff = vmf->pgoff; - vmf->page = ubuf->pages[vmf->pgoff]; + if (pgoff >= ubuf->pagecount) + return VM_FAULT_SIGBUS; + vmf->page = ubuf->pages[pgoff]; get_page(vmf->page); return 0; } @@ -117,7 +120,7 @@ }; #define SEALS_WANTED (F_SEAL_SHRINK) -#define SEALS_DENIED (F_SEAL_WRITE) +#define SEALS_DENIED (F_SEAL_WRITE|F_SEAL_FUTURE_WRITE) static long udmabuf_create(const struct udmabuf_create_list *head, const struct udmabuf_create_item *list) @@ -145,6 +148,10 @@ if (ubuf->pagecount > pglimit) goto err; } + + if (!ubuf->pagecount) + goto err; + ubuf->pages = kmalloc_array(ubuf->pagecount, sizeof(*ubuf->pages), GFP_KERNEL); if (!ubuf->pages) { @@ -280,7 +287,23 @@ static int __init udmabuf_dev_init(void) { - return misc_register(&udmabuf_misc); + int ret; + + ret = misc_register(&udmabuf_misc); + if (ret < 0) { + pr_err("Could not initialize udmabuf device\n"); + return ret; + } + + ret = dma_coerce_mask_and_coherent(udmabuf_misc.this_device, + DMA_BIT_MASK(64)); + if (ret < 0) { + pr_err("Could not setup DMA mask for udmabuf device\n"); + misc_deregister(&udmabuf_misc); + return ret; + } + + return 0; } static void __exit udmabuf_dev_exit(void) --- linux-oracle-5.4.0.orig/drivers/dma/Kconfig +++ linux-oracle-5.4.0/drivers/dma/Kconfig @@ -59,6 +59,7 @@ #devices config ALTERA_MSGDMA tristate "Altera / Intel mSGDMA Engine" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for Altera / Intel mSGDMA controller. @@ -207,6 +208,7 @@ config FSL_EDMA tristate "Freescale eDMA engine support" depends on OF + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help @@ -239,6 +241,14 @@ the capability to offload memcpy, xor and pq computation for raid5/6. +config HISI_DMA + tristate "HiSilicon DMA Engine support" + depends on ARM64 || (COMPILE_TEST && PCI_MSI) + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + help + Support HiSilicon Kunpeng DMA engine. + config IMG_MDC_DMA tristate "IMG MDC support" depends on MIPS || COMPILE_TEST @@ -267,6 +277,7 @@ config INTEL_IDMA64 tristate "Intel integrated DMA 64-bit support" + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help @@ -275,7 +286,7 @@ config INTEL_IOATDMA tristate "Intel I/OAT DMA support" - depends on PCI && X86_64 + depends on PCI && X86_64 && !UML select DMA_ENGINE select DMA_ENGINE_RAID select DCA @@ -579,16 +590,16 @@ config TEGRA210_ADMA tristate "NVIDIA Tegra210 ADMA support" - depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST) + depends on (ARCH_TEGRA || COMPILE_TEST) select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help - Support for the NVIDIA Tegra210 ADMA controller driver. The - DMA controller has multiple DMA channels and is used to service - various audio clients in the Tegra210 audio processing engine - (APE). This DMA controller transfers data from memory to - peripheral and vice versa. It does not support memory to - memory data transfer. + Support for the NVIDIA Tegra210/Tegra186/Tegra194/Tegra234 ADMA + controller driver. The DMA controller has multiple DMA channels + and is used to service various audio clients in the Tegra210 + audio processing engine (APE). This DMA controller transfers + data from memory to peripheral and vice versa. It does not + support memory to memory data transfer. config TIMB_DMA tristate "Timberdale FPGA DMA support" --- linux-oracle-5.4.0.orig/drivers/dma/Makefile +++ linux-oracle-5.4.0/drivers/dma/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_MCF_EDMA) += mcf-edma.o fsl-edma-common.o obj-$(CONFIG_FSL_QDMA) += fsl-qdma.o obj-$(CONFIG_FSL_RAID) += fsl_raid.o +obj-$(CONFIG_HISI_DMA) += hisi_dma.o obj-$(CONFIG_HSU_DMA) += hsu/ obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o obj-$(CONFIG_IMX_DMA) += imx-dma.o --- linux-oracle-5.4.0.orig/drivers/dma/acpi-dma.c +++ linux-oracle-5.4.0/drivers/dma/acpi-dma.c @@ -70,10 +70,14 @@ si = (const struct acpi_csrt_shared_info *)&grp[1]; - /* Match device by MMIO and IRQ */ + /* Match device by MMIO */ if (si->mmio_base_low != lower_32_bits(mem) || - si->mmio_base_high != upper_32_bits(mem) || - si->gsi_interrupt != irq) + si->mmio_base_high != upper_32_bits(mem)) + return 0; + + /* Match device by Linux vIRQ */ + ret = acpi_register_gsi(NULL, si->gsi_interrupt, si->interrupt_mode, si->interrupt_polarity); + if (ret != irq) return 0; dev_dbg(&adev->dev, "matches with %.4s%04X (rev %u)\n", @@ -135,11 +139,13 @@ if (ret < 0) { dev_warn(&adev->dev, "error in parsing resource group\n"); - return; + break; } grp = (struct acpi_csrt_group *)((void *)grp + grp->length); } + + acpi_put_table((struct acpi_table_header *)csrt); } /** --- linux-oracle-5.4.0.orig/drivers/dma/at_hdmac.c +++ linux-oracle-5.4.0/drivers/dma/at_hdmac.c @@ -246,6 +246,8 @@ ATC_SPIP_BOUNDARY(first->boundary)); channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) | ATC_DPIP_BOUNDARY(first->boundary)); + /* Don't allow CPU to reorder channel enable. */ + wmb(); dma_writel(atdma, CHER, atchan->mask); vdbg_dump_regs(atchan); @@ -306,7 +308,8 @@ struct at_desc *desc_first = atc_first_active(atchan); struct at_desc *desc; int ret; - u32 ctrla, dscr, trials; + u32 ctrla, dscr; + unsigned int i; /* * If the cookie doesn't match to the currently running transfer then @@ -376,7 +379,7 @@ dscr = channel_readl(atchan, DSCR); rmb(); /* ensure DSCR is read before CTRLA */ ctrla = channel_readl(atchan, CTRLA); - for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) { + for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) { u32 new_dscr; rmb(); /* ensure DSCR is read after CTRLA */ @@ -402,7 +405,7 @@ rmb(); /* ensure DSCR is read before CTRLA */ ctrla = channel_readl(atchan, CTRLA); } - if (unlikely(trials >= ATC_MAX_DSCR_TRIALS)) + if (unlikely(i == ATC_MAX_DSCR_TRIALS)) return -ETIMEDOUT; /* for the first descriptor we can be more accurate */ @@ -550,10 +553,6 @@ bad_desc = atc_first_active(atchan); list_del_init(&bad_desc->desc_node); - /* As we are stopped, take advantage to push queued descriptors - * in active_list */ - list_splice_init(&atchan->queue, atchan->active_list.prev); - /* Try to restart the controller */ if (!list_empty(&atchan->active_list)) atc_dostart(atchan, atc_first_active(atchan)); @@ -674,19 +673,11 @@ spin_lock_irqsave(&atchan->lock, flags); cookie = dma_cookie_assign(tx); - if (list_empty(&atchan->active_list)) { - dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n", - desc->txd.cookie); - atc_dostart(atchan, desc); - list_add_tail(&desc->desc_node, &atchan->active_list); - } else { - dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", - desc->txd.cookie); - list_add_tail(&desc->desc_node, &atchan->queue); - } - + list_add_tail(&desc->desc_node, &atchan->queue); spin_unlock_irqrestore(&atchan->lock, flags); + dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", + desc->txd.cookie); return cookie; } @@ -1667,13 +1658,17 @@ return NULL; dmac_pdev = of_find_device_by_node(dma_spec->np); + if (!dmac_pdev) + return NULL; dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - atslave = kzalloc(sizeof(*atslave), GFP_KERNEL); - if (!atslave) + atslave = kmalloc(sizeof(*atslave), GFP_KERNEL); + if (!atslave) { + put_device(&dmac_pdev->dev); return NULL; + } atslave->cfg = ATC_DST_H2SEL_HW | ATC_SRC_H2SEL_HW; /* @@ -1702,8 +1697,11 @@ atslave->dma_dev = &dmac_pdev->dev; chan = dma_request_channel(mask, at_dma_filter, atslave); - if (!chan) + if (!chan) { + put_device(&dmac_pdev->dev); + kfree(atslave); return NULL; + } atchan = to_at_dma_chan(chan); atchan->per_if = dma_spec->args[0] & 0xff; @@ -1950,7 +1948,11 @@ dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", plat_dat->nr_channels); - dma_async_device_register(&atdma->dma_common); + err = dma_async_device_register(&atdma->dma_common); + if (err) { + dev_err(&pdev->dev, "Unable to register: %d.\n", err); + goto err_dma_async_device_register; + } /* * Do not return an error if the dmac node is not present in order to @@ -1970,6 +1972,7 @@ err_of_dma_controller_register: dma_async_device_unregister(&atdma->dma_common); +err_dma_async_device_register: dma_pool_destroy(atdma->memset_pool); err_memset_pool_create: dma_pool_destroy(atdma->dma_desc_pool); --- linux-oracle-5.4.0.orig/drivers/dma/at_hdmac_regs.h +++ linux-oracle-5.4.0/drivers/dma/at_hdmac_regs.h @@ -164,13 +164,13 @@ /* LLI == Linked List Item; aka DMA buffer descriptor */ struct at_lli { /* values that are not changed by hardware */ - dma_addr_t saddr; - dma_addr_t daddr; + u32 saddr; + u32 daddr; /* value that may get written back: */ - u32 ctrla; + u32 ctrla; /* more values that are not changed by hardware */ - u32 ctrlb; - dma_addr_t dscr; /* chain to next lli */ + u32 ctrlb; + u32 dscr; /* chain to next lli */ }; /** --- linux-oracle-5.4.0.orig/drivers/dma/at_xdmac.c +++ linux-oracle-5.4.0/drivers/dma/at_xdmac.c @@ -89,6 +89,7 @@ #define AT_XDMAC_CNDC_NDE (0x1 << 0) /* Channel x Next Descriptor Enable */ #define AT_XDMAC_CNDC_NDSUP (0x1 << 1) /* Channel x Next Descriptor Source Update */ #define AT_XDMAC_CNDC_NDDUP (0x1 << 2) /* Channel x Next Descriptor Destination Update */ +#define AT_XDMAC_CNDC_NDVIEW_MASK GENMASK(28, 27) #define AT_XDMAC_CNDC_NDVIEW_NDV0 (0x0 << 3) /* Channel x Next Descriptor View 0 */ #define AT_XDMAC_CNDC_NDVIEW_NDV1 (0x1 << 3) /* Channel x Next Descriptor View 1 */ #define AT_XDMAC_CNDC_NDVIEW_NDV2 (0x2 << 3) /* Channel x Next Descriptor View 2 */ @@ -145,7 +146,7 @@ #define AT_XDMAC_CC_WRIP (0x1 << 23) /* Write in Progress (read only) */ #define AT_XDMAC_CC_WRIP_DONE (0x0 << 23) #define AT_XDMAC_CC_WRIP_IN_PROGRESS (0x1 << 23) -#define AT_XDMAC_CC_PERID(i) (0x7f & (i) << 24) /* Channel Peripheral Identifier */ +#define AT_XDMAC_CC_PERID(i) ((0x7f & (i)) << 24) /* Channel Peripheral Identifier */ #define AT_XDMAC_CDS_MSP 0x2C /* Channel Data Stride Memory Set Pattern */ #define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ #define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */ @@ -211,6 +212,7 @@ int irq; struct clk *clk; u32 save_gim; + u32 save_gs; struct dma_pool *at_xdmac_desc_pool; struct at_xdmac_chan chan[0]; }; @@ -220,15 +222,15 @@ /* Linked List Descriptor */ struct at_xdmac_lld { - dma_addr_t mbr_nda; /* Next Descriptor Member */ - u32 mbr_ubc; /* Microblock Control Member */ - dma_addr_t mbr_sa; /* Source Address Member */ - dma_addr_t mbr_da; /* Destination Address Member */ - u32 mbr_cfg; /* Configuration Register */ - u32 mbr_bc; /* Block Control Register */ - u32 mbr_ds; /* Data Stride Register */ - u32 mbr_sus; /* Source Microblock Stride Register */ - u32 mbr_dus; /* Destination Microblock Stride Register */ + u32 mbr_nda; /* Next Descriptor Member */ + u32 mbr_ubc; /* Microblock Control Member */ + u32 mbr_sa; /* Source Address Member */ + u32 mbr_da; /* Destination Address Member */ + u32 mbr_cfg; /* Configuration Register */ + u32 mbr_bc; /* Block Control Register */ + u32 mbr_ds; /* Data Stride Register */ + u32 mbr_sus; /* Source Microblock Stride Register */ + u32 mbr_dus; /* Destination Microblock Stride Register */ }; /* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */ @@ -338,9 +340,6 @@ dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); - if (at_xdmac_chan_is_enabled(atchan)) - return; - /* Set transfer as active to not try to start it again. */ first->active_xfer = true; @@ -356,7 +355,8 @@ */ if (at_xdmac_chan_is_cyclic(atchan)) reg = AT_XDMAC_CNDC_NDVIEW_NDV1; - else if (first->lld.mbr_ubc & AT_XDMAC_MBR_UBC_NDV3) + else if ((first->lld.mbr_ubc & + AT_XDMAC_CNDC_NDVIEW_MASK) == AT_XDMAC_MBR_UBC_NDV3) reg = AT_XDMAC_CNDC_NDVIEW_NDV3; else reg = AT_XDMAC_CNDC_NDVIEW_NDV2; @@ -427,13 +427,12 @@ spin_lock_irqsave(&atchan->lock, irqflags); cookie = dma_cookie_assign(tx); + list_add_tail(&desc->xfer_node, &atchan->xfers_list); + spin_unlock_irqrestore(&atchan->lock, irqflags); + dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", __func__, atchan, desc); - list_add_tail(&desc->xfer_node, &atchan->xfers_list); - if (list_is_singular(&atchan->xfers_list)) - at_xdmac_start_xfer(atchan, desc); - spin_unlock_irqrestore(&atchan->lock, irqflags); return cookie; } @@ -1215,6 +1214,8 @@ return NULL; desc = at_xdmac_memset_create_desc(chan, atchan, dest, len, value); + if (!desc) + return NULL; list_add_tail(&desc->desc_node, &desc->descs_list); desc->tx_dma_desc.cookie = -EBUSY; @@ -1392,7 +1393,7 @@ { struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); - struct at_xdmac_desc *desc, *_desc; + struct at_xdmac_desc *desc, *_desc, *iter; struct list_head *descs_list; enum dma_status ret; int residue, retry; @@ -1507,11 +1508,13 @@ * microblock. */ descs_list = &desc->descs_list; - list_for_each_entry_safe(desc, _desc, descs_list, desc_node) { - dwidth = at_xdmac_get_dwidth(desc->lld.mbr_cfg); - residue -= (desc->lld.mbr_ubc & 0xffffff) << dwidth; - if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda) + list_for_each_entry_safe(iter, _desc, descs_list, desc_node) { + dwidth = at_xdmac_get_dwidth(iter->lld.mbr_cfg); + residue -= (iter->lld.mbr_ubc & 0xffffff) << dwidth; + if ((iter->lld.mbr_nda & 0xfffffffc) == cur_nda) { + desc = iter; break; + } } residue += cur_ubc << dwidth; @@ -1568,14 +1571,17 @@ struct at_xdmac_desc *desc; struct dma_async_tx_descriptor *txd; - if (!list_empty(&atchan->xfers_list)) { - desc = list_first_entry(&atchan->xfers_list, - struct at_xdmac_desc, xfer_node); - txd = &desc->tx_dma_desc; - - if (txd->flags & DMA_PREP_INTERRUPT) - dmaengine_desc_get_callback_invoke(txd, NULL); + spin_lock_irq(&atchan->lock); + if (list_empty(&atchan->xfers_list)) { + spin_unlock_irq(&atchan->lock); + return; } + desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, + xfer_node); + spin_unlock_irq(&atchan->lock); + txd = &desc->tx_dma_desc; + if (txd->flags & DMA_PREP_INTERRUPT) + dmaengine_desc_get_callback_invoke(txd, NULL); } static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) @@ -1725,11 +1731,13 @@ static void at_xdmac_issue_pending(struct dma_chan *chan) { struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); + unsigned long flags; dev_dbg(chan2dev(&atchan->chan), "%s\n", __func__); - if (!at_xdmac_chan_is_cyclic(atchan)) - at_xdmac_advance_work(atchan); + spin_lock_irqsave(&atchan->lock, flags); + at_xdmac_advance_work(atchan); + spin_unlock_irqrestore(&atchan->lock, flags); return; } @@ -1843,6 +1851,11 @@ for (i = 0; i < init_nr_desc_per_channel; i++) { desc = at_xdmac_alloc_desc(chan, GFP_ATOMIC); if (!desc) { + if (i == 0) { + dev_warn(chan2dev(chan), + "can't allocate any descriptors\n"); + return -EIO; + } dev_warn(chan2dev(chan), "only %d descriptors have been allocated\n", i); break; @@ -1912,6 +1925,7 @@ } } atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); + atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS); at_xdmac_off(atxdmac); clk_disable_unprepare(atxdmac->clk); @@ -1948,7 +1962,8 @@ at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); wmb(); - at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); + if (atxdmac->save_gs & atchan->mask) + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); } } return 0; --- linux-oracle-5.4.0.orig/drivers/dma/coh901318.c +++ linux-oracle-5.4.0/drivers/dma/coh901318.c @@ -1947,8 +1947,6 @@ return; } - spin_lock(&cohc->lock); - /* * When we reach this point, at least one queue item * should have been moved over from cohc->queue to @@ -1969,8 +1967,6 @@ if (coh901318_queue_start(cohc) == NULL) cohc->busy = 0; - spin_unlock(&cohc->lock); - /* * This tasklet will remove items from cohc->active * and thus terminates them. --- linux-oracle-5.4.0.orig/drivers/dma/dma-axi-dmac.c +++ linux-oracle-5.4.0/drivers/dma/dma-axi-dmac.c @@ -830,6 +830,7 @@ struct dma_device *dma_dev; struct axi_dmac *dmac; struct resource *res; + struct regmap *regmap; int ret; dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL); @@ -921,10 +922,17 @@ platform_set_drvdata(pdev, dmac); - devm_regmap_init_mmio(&pdev->dev, dmac->base, &axi_dmac_regmap_config); + regmap = devm_regmap_init_mmio(&pdev->dev, dmac->base, + &axi_dmac_regmap_config); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_free_irq; + } return 0; +err_free_irq: + free_irq(dmac->irq, dmac); err_unregister_of: of_dma_controller_free(pdev->dev.of_node); err_unregister_device: @@ -939,8 +947,8 @@ { struct axi_dmac *dmac = platform_get_drvdata(pdev); - of_dma_controller_free(pdev->dev.of_node); free_irq(dmac->irq, dmac); + of_dma_controller_free(pdev->dev.of_node); tasklet_kill(&dmac->chan.vchan.task); dma_async_device_unregister(&dmac->dma_dev); clk_disable_unprepare(dmac->clk); --- linux-oracle-5.4.0.orig/drivers/dma/dma-jz4780.c +++ linux-oracle-5.4.0/drivers/dma/dma-jz4780.c @@ -639,11 +639,11 @@ unsigned long flags; unsigned long residue = 0; + spin_lock_irqsave(&jzchan->vchan.lock, flags); + status = dma_cookie_status(chan, cookie, txstate); if ((status == DMA_COMPLETE) || (txstate == NULL)) - return status; - - spin_lock_irqsave(&jzchan->vchan.lock, flags); + goto out_unlock_irqrestore; vdesc = vchan_find_desc(&jzchan->vchan, cookie); if (vdesc) { @@ -660,6 +660,7 @@ && jzchan->desc->status & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT)) status = DMA_ERROR; +out_unlock_irqrestore: spin_unlock_irqrestore(&jzchan->vchan.lock, flags); return status; } @@ -885,24 +886,11 @@ return -EINVAL; } - ret = platform_get_irq(pdev, 0); - if (ret < 0) - return ret; - - jzdma->irq = ret; - - ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev), - jzdma); - if (ret) { - dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq); - return ret; - } - jzdma->clk = devm_clk_get(dev, NULL); if (IS_ERR(jzdma->clk)) { dev_err(dev, "failed to get clock\n"); ret = PTR_ERR(jzdma->clk); - goto err_free_irq; + return ret; } clk_prepare_enable(jzdma->clk); @@ -955,10 +943,23 @@ jzchan->vchan.desc_free = jz4780_dma_desc_free; } + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto err_disable_clk; + + jzdma->irq = ret; + + ret = request_irq(jzdma->irq, jz4780_dma_irq_handler, 0, dev_name(dev), + jzdma); + if (ret) { + dev_err(dev, "failed to request IRQ %u!\n", jzdma->irq); + goto err_disable_clk; + } + ret = dmaenginem_async_device_register(dd); if (ret) { dev_err(dev, "failed to register device\n"); - goto err_disable_clk; + goto err_free_irq; } /* Register with OF DMA helpers. */ @@ -966,17 +967,17 @@ jzdma); if (ret) { dev_err(dev, "failed to register OF DMA controller\n"); - goto err_disable_clk; + goto err_free_irq; } dev_info(dev, "JZ4780 DMA controller initialised\n"); return 0; -err_disable_clk: - clk_disable_unprepare(jzdma->clk); - err_free_irq: free_irq(jzdma->irq, jzdma); + +err_disable_clk: + clk_disable_unprepare(jzdma->clk); return ret; } @@ -1004,7 +1005,8 @@ static const struct jz4780_dma_soc_data jz4725b_dma_soc_data = { .nb_channels = 6, .transfer_ord_max = 5, - .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC, + .flags = JZ_SOC_DATA_PER_CHAN_PM | JZ_SOC_DATA_NO_DCKES_DCKEC | + JZ_SOC_DATA_BREAK_LINKS, }; static const struct jz4780_dma_soc_data jz4770_dma_soc_data = { --- linux-oracle-5.4.0.orig/drivers/dma/dmaengine.c +++ linux-oracle-5.4.0/drivers/dma/dmaengine.c @@ -179,7 +179,7 @@ static struct module *dma_chan_to_owner(struct dma_chan *chan) { - return chan->device->dev->driver->owner; + return chan->device->owner; } /** @@ -212,7 +212,8 @@ /* The channel is already in use, update client count */ if (chan->client_count) { __module_get(owner); - goto out; + chan->client_count++; + return 0; } if (!try_module_get(owner)) @@ -225,11 +226,11 @@ goto err_out; } + chan->client_count++; + if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) balance_ref_count(chan); -out: - chan->client_count++; return 0; err_out: @@ -919,6 +920,8 @@ return -EIO; } + device->owner = device->dev->driver->owner; + if (dma_has_cap(DMA_MEMCPY, device->cap_mask) && !device->device_prep_dma_memcpy) { dev_err(device->dev, "Device claims capability %s, but op is not defined\n", --- linux-oracle-5.4.0.orig/drivers/dma/dmaengine.h +++ linux-oracle-5.4.0/drivers/dma/dmaengine.h @@ -168,7 +168,7 @@ static inline bool dmaengine_desc_callback_valid(struct dmaengine_desc_callback *cb) { - return (cb->callback) ? true : false; + return cb->callback || cb->callback_result; } #endif --- linux-oracle-5.4.0.orig/drivers/dma/dmatest.c +++ linux-oracle-5.4.0/drivers/dma/dmatest.c @@ -240,7 +240,7 @@ struct dmatest_thread *thread; list_for_each_entry(thread, &dtc->threads, node) { - if (!thread->done) + if (!thread->done && !thread->pending) return true; } } @@ -662,8 +662,8 @@ flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; ktime = ktime_get(); - while (!kthread_should_stop() - && !(params->iterations && total_tests >= params->iterations)) { + while (!(kthread_should_stop() || + (params->iterations && total_tests >= params->iterations))) { struct dma_async_tx_descriptor *tx = NULL; struct dmaengine_unmap_data *um; dma_addr_t *dsts; @@ -1166,10 +1166,13 @@ mutex_unlock(&info->lock); return ret; } else if (dmatest_run) { - if (is_threaded_test_pending(info)) - start_threaded_tests(info); - else - pr_info("Could not start test, no channels configured\n"); + if (!is_threaded_test_pending(info)) { + pr_info("No channels configured, continue with any\n"); + if (!is_threaded_test_run(info)) + stop_threaded_test(info); + add_threaded_test(info); + } + start_threaded_tests(info); } else { stop_threaded_test(info); } @@ -1215,15 +1218,14 @@ add_threaded_test(info); /* Check if channel was added successfully */ - dtc = list_last_entry(&info->channels, struct dmatest_chan, node); - - if (dtc->chan) { + if (!list_empty(&info->channels)) { /* * if new channel was not successfully added, revert the * "test_channel" string to the name of the last successfully * added channel. exception for when users issues empty string * to channel parameter. */ + dtc = list_last_entry(&info->channels, struct dmatest_chan, node); if ((strcmp(dma_chan_name(dtc->chan), strim(test_channel)) != 0) && (strcmp("", strim(test_channel)) != 0)) { ret = -EINVAL; --- linux-oracle-5.4.0.orig/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ linux-oracle-5.4.0/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -551,6 +551,11 @@ /* The bad descriptor currently is in the head of vc list */ vd = vchan_next_desc(&chan->vc); + if (!vd) { + dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", + axi_chan_name(chan)); + goto out; + } /* Remove the completed descriptor from issued list */ list_del(&vd->node); @@ -565,6 +570,7 @@ /* Try to restart the controller */ axi_chan_start_first_queued(chan); +out: spin_unlock_irqrestore(&chan->vc.lock, flags); } --- linux-oracle-5.4.0.orig/drivers/dma/dw-edma/dw-edma-core.c +++ linux-oracle-5.4.0/drivers/dma/dw-edma/dw-edma-core.c @@ -85,12 +85,12 @@ if (desc->chunk) { /* Create and add new element into the linked list */ - desc->chunks_alloc++; - list_add_tail(&chunk->list, &desc->chunk->list); if (!dw_edma_alloc_burst(chunk)) { kfree(chunk); return NULL; } + desc->chunks_alloc++; + list_add_tail(&chunk->list, &desc->chunk->list); } else { /* List head */ chunk->burst = NULL; @@ -165,7 +165,7 @@ dw_edma_free_desc(vd2dw_edma_desc(vdesc)); } -static void dw_edma_start_transfer(struct dw_edma_chan *chan) +static int dw_edma_start_transfer(struct dw_edma_chan *chan) { struct dw_edma_chunk *child; struct dw_edma_desc *desc; @@ -173,16 +173,16 @@ vd = vchan_next_desc(&chan->vc); if (!vd) - return; + return 0; desc = vd2dw_edma_desc(vd); if (!desc) - return; + return 0; child = list_first_entry_or_null(&desc->chunk->list, struct dw_edma_chunk, list); if (!child) - return; + return 0; dw_edma_v0_core_start(child, !desc->xfer_sz); desc->xfer_sz += child->ll_region.sz; @@ -190,6 +190,8 @@ list_del(&child->list); kfree(child); desc->chunks_alloc--; + + return 1; } static int dw_edma_device_config(struct dma_chan *dchan, @@ -273,9 +275,12 @@ struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan); unsigned long flags; + if (!chan->configured) + return; + spin_lock_irqsave(&chan->vc.lock, flags); - if (chan->configured && chan->request == EDMA_REQ_NONE && - chan->status == EDMA_ST_IDLE && vchan_issue_pending(&chan->vc)) { + if (vchan_issue_pending(&chan->vc) && chan->request == EDMA_REQ_NONE && + chan->status == EDMA_ST_IDLE) { chan->status = EDMA_ST_BUSY; dw_edma_start_transfer(chan); } @@ -391,7 +396,7 @@ if (xfer->cyclic) { burst->dar = xfer->xfer.cyclic.paddr; } else { - burst->dar = sg_dma_address(sg); + burst->dar = dst_addr; /* Unlike the typical assumption by other * drivers/IPs the peripheral memory isn't * a FIFO memory, in this case, it's a @@ -399,14 +404,13 @@ * and destination addresses are increased * by the same portion (data length) */ - src_addr += sg_dma_len(sg); } } else { burst->dar = dst_addr; if (xfer->cyclic) { burst->sar = xfer->xfer.cyclic.paddr; } else { - burst->sar = sg_dma_address(sg); + burst->sar = src_addr; /* Unlike the typical assumption by other * drivers/IPs the peripheral memory isn't * a FIFO memory, in this case, it's a @@ -414,12 +418,14 @@ * and destination addresses are increased * by the same portion (data length) */ - dst_addr += sg_dma_len(sg); } } - if (!xfer->cyclic) + if (!xfer->cyclic) { + src_addr += sg_dma_len(sg); + dst_addr += sg_dma_len(sg); sg = sg_next(sg); + } } return vchan_tx_prep(&chan->vc, &desc->vd, xfer->flags); @@ -482,14 +488,14 @@ switch (chan->request) { case EDMA_REQ_NONE: desc = vd2dw_edma_desc(vd); - if (desc->chunks_alloc) { - chan->status = EDMA_ST_BUSY; - dw_edma_start_transfer(chan); - } else { + if (!desc->chunks_alloc) { list_del(&vd->node); vchan_cookie_complete(vd); - chan->status = EDMA_ST_IDLE; } + + /* Continue transferring if there are remaining chunks or issued requests. + */ + chan->status = dw_edma_start_transfer(chan) ? EDMA_ST_BUSY : EDMA_ST_IDLE; break; case EDMA_REQ_STOP: @@ -909,22 +915,21 @@ /* Power management */ pm_runtime_disable(dev); + /* Deregister eDMA device */ + dma_async_device_unregister(&dw->wr_edma); list_for_each_entry_safe(chan, _chan, &dw->wr_edma.channels, vc.chan.device_node) { - list_del(&chan->vc.chan.device_node); tasklet_kill(&chan->vc.task); + list_del(&chan->vc.chan.device_node); } + dma_async_device_unregister(&dw->rd_edma); list_for_each_entry_safe(chan, _chan, &dw->rd_edma.channels, vc.chan.device_node) { - list_del(&chan->vc.chan.device_node); tasklet_kill(&chan->vc.task); + list_del(&chan->vc.chan.device_node); } - /* Deregister eDMA device */ - dma_async_device_unregister(&dw->wr_edma); - dma_async_device_unregister(&dw->rd_edma); - /* Turn debugfs off */ dw_edma_v0_core_debugfs_off(); --- linux-oracle-5.4.0.orig/drivers/dma/dw/Kconfig +++ linux-oracle-5.4.0/drivers/dma/dw/Kconfig @@ -10,6 +10,7 @@ config DW_DMAC tristate "Synopsys DesignWare AHB DMA platform driver" + depends on HAS_IOMEM select DW_DMAC_CORE help Support the Synopsys DesignWare AHB DMA controller. This @@ -18,6 +19,7 @@ config DW_DMAC_PCI tristate "Synopsys DesignWare AHB DMA PCI driver" depends on PCI + depends on HAS_IOMEM select DW_DMAC_CORE help Support the Synopsys DesignWare AHB DMA controller on the --- linux-oracle-5.4.0.orig/drivers/dma/dw/core.c +++ linux-oracle-5.4.0/drivers/dma/dw/core.c @@ -118,16 +118,11 @@ { struct dw_dma *dw = to_dw_dma(dwc->chan.device); - if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags)) - return; - dw->initialize_chan(dwc); /* Enable interrupts */ channel_set_bit(dw, MASK.XFER, dwc->mask); channel_set_bit(dw, MASK.ERROR, dwc->mask); - - set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); } /*----------------------------------------------------------------------*/ @@ -777,6 +772,10 @@ if (dws->dma_dev != chan->device->dev) return false; + /* permit channels in accordance with the channels mask */ + if (dws->channels && !(dws->channels & dwc->mask)) + return false; + /* We have to copy data since dws can be temporary storage */ memcpy(&dwc->dws, dws, sizeof(struct dw_dma_slave)); @@ -954,8 +953,6 @@ void do_dw_dma_off(struct dw_dma *dw) { - unsigned int i; - dma_writel(dw, CFG, 0); channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask); @@ -966,9 +963,6 @@ while (dma_readl(dw, CFG) & DW_CFG_DMA_EN) cpu_relax(); - - for (i = 0; i < dw->dma.chancnt; i++) - clear_bit(DW_DMA_IS_INITIALIZED, &dw->chan[i].flags); } void do_dw_dma_on(struct dw_dma *dw) @@ -1032,8 +1026,6 @@ /* Clear custom channel configuration */ memset(&dwc->dws, 0, sizeof(struct dw_dma_slave)); - clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags); - /* Disable interrupts */ channel_clear_bit(dw, MASK.XFER, dwc->mask); channel_clear_bit(dw, MASK.BLOCK, dwc->mask); --- linux-oracle-5.4.0.orig/drivers/dma/dw/dw.c +++ linux-oracle-5.4.0/drivers/dma/dw/dw.c @@ -14,7 +14,7 @@ static void dw_dma_initialize_chan(struct dw_dma_chan *dwc) { struct dw_dma *dw = to_dw_dma(dwc->chan.device); - u32 cfghi = DWC_CFGH_FIFO_MODE; + u32 cfghi = is_slave_direction(dwc->direction) ? 0 : DWC_CFGH_FIFO_MODE; u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority); bool hs_polarity = dwc->dws.hs_polarity; --- linux-oracle-5.4.0.orig/drivers/dma/dw/of.c +++ linux-oracle-5.4.0/drivers/dma/dw/of.c @@ -22,18 +22,21 @@ }; dma_cap_mask_t cap; - if (dma_spec->args_count != 3) + if (dma_spec->args_count < 3 || dma_spec->args_count > 4) return NULL; slave.src_id = dma_spec->args[0]; slave.dst_id = dma_spec->args[0]; slave.m_master = dma_spec->args[1]; slave.p_master = dma_spec->args[2]; + if (dma_spec->args_count >= 4) + slave.channels = dma_spec->args[3]; if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS || slave.dst_id >= DW_DMA_MAX_NR_REQUESTS || slave.m_master >= dw->pdata->nr_masters || - slave.p_master >= dw->pdata->nr_masters)) + slave.p_master >= dw->pdata->nr_masters || + slave.channels >= BIT(dw->pdata->nr_channels))) return NULL; dma_cap_zero(cap); --- linux-oracle-5.4.0.orig/drivers/dma/dw/platform.c +++ linux-oracle-5.4.0/drivers/dma/dw/platform.c @@ -66,7 +66,7 @@ data->chip = chip; - chip->clk = devm_clk_get(chip->dev, "hclk"); + chip->clk = devm_clk_get_optional(chip->dev, "hclk"); if (IS_ERR(chip->clk)) return PTR_ERR(chip->clk); err = clk_prepare_enable(chip->clk); --- linux-oracle-5.4.0.orig/drivers/dma/fsl-edma-common.c +++ linux-oracle-5.4.0/drivers/dma/fsl-edma-common.c @@ -347,26 +347,28 @@ /* * TCD parameters are stored in struct fsl_edma_hw_tcd in little * endian format. However, we need to load the TCD registers in - * big- or little-endian obeying the eDMA engine model endian. + * big- or little-endian obeying the eDMA engine model endian, + * and this is performed from specific edma_write functions */ edma_writew(edma, 0, ®s->tcd[ch].csr); - edma_writel(edma, le32_to_cpu(tcd->saddr), ®s->tcd[ch].saddr); - edma_writel(edma, le32_to_cpu(tcd->daddr), ®s->tcd[ch].daddr); - edma_writew(edma, le16_to_cpu(tcd->attr), ®s->tcd[ch].attr); - edma_writew(edma, le16_to_cpu(tcd->soff), ®s->tcd[ch].soff); + edma_writel(edma, (s32)tcd->saddr, ®s->tcd[ch].saddr); + edma_writel(edma, (s32)tcd->daddr, ®s->tcd[ch].daddr); - edma_writel(edma, le32_to_cpu(tcd->nbytes), ®s->tcd[ch].nbytes); - edma_writel(edma, le32_to_cpu(tcd->slast), ®s->tcd[ch].slast); + edma_writew(edma, (s16)tcd->attr, ®s->tcd[ch].attr); + edma_writew(edma, tcd->soff, ®s->tcd[ch].soff); - edma_writew(edma, le16_to_cpu(tcd->citer), ®s->tcd[ch].citer); - edma_writew(edma, le16_to_cpu(tcd->biter), ®s->tcd[ch].biter); - edma_writew(edma, le16_to_cpu(tcd->doff), ®s->tcd[ch].doff); + edma_writel(edma, (s32)tcd->nbytes, ®s->tcd[ch].nbytes); + edma_writel(edma, (s32)tcd->slast, ®s->tcd[ch].slast); - edma_writel(edma, le32_to_cpu(tcd->dlast_sga), + edma_writew(edma, (s16)tcd->citer, ®s->tcd[ch].citer); + edma_writew(edma, (s16)tcd->biter, ®s->tcd[ch].biter); + edma_writew(edma, (s16)tcd->doff, ®s->tcd[ch].doff); + + edma_writel(edma, (s32)tcd->dlast_sga, ®s->tcd[ch].dlast_sga); - edma_writew(edma, le16_to_cpu(tcd->csr), ®s->tcd[ch].csr); + edma_writew(edma, (s16)tcd->csr, ®s->tcd[ch].csr); } static inline --- linux-oracle-5.4.0.orig/drivers/dma/fsl-edma-common.h +++ linux-oracle-5.4.0/drivers/dma/fsl-edma-common.h @@ -33,7 +33,7 @@ #define EDMA_TCD_ATTR_DSIZE_16BIT BIT(0) #define EDMA_TCD_ATTR_DSIZE_32BIT BIT(1) #define EDMA_TCD_ATTR_DSIZE_64BIT (BIT(0) | BIT(1)) -#define EDMA_TCD_ATTR_DSIZE_32BYTE (BIT(3) | BIT(0)) +#define EDMA_TCD_ATTR_DSIZE_32BYTE (BIT(2) | BIT(0)) #define EDMA_TCD_ATTR_SSIZE_8BIT 0 #define EDMA_TCD_ATTR_SSIZE_16BIT (EDMA_TCD_ATTR_DSIZE_16BIT << 8) #define EDMA_TCD_ATTR_SSIZE_32BIT (EDMA_TCD_ATTR_DSIZE_32BIT << 8) --- linux-oracle-5.4.0.orig/drivers/dma/fsl-edma.c +++ linux-oracle-5.4.0/drivers/dma/fsl-edma.c @@ -45,6 +45,13 @@ fsl_chan = &fsl_edma->chans[ch]; spin_lock(&fsl_chan->vchan.lock); + + if (!fsl_chan->edesc) { + /* terminate_all called before */ + spin_unlock(&fsl_chan->vchan.lock); + continue; + } + if (!fsl_chan->edesc->iscyclic) { list_del(&fsl_chan->edesc->vdesc.node); vchan_cookie_complete(&fsl_chan->edesc->vdesc); --- linux-oracle-5.4.0.orig/drivers/dma/fsl-qdma.c +++ linux-oracle-5.4.0/drivers/dma/fsl-qdma.c @@ -109,6 +109,7 @@ #define FSL_QDMA_CMD_WTHROTL_OFFSET 20 #define FSL_QDMA_CMD_DSEN_OFFSET 19 #define FSL_QDMA_CMD_LWC_OFFSET 16 +#define FSL_QDMA_CMD_PF BIT(17) /* Field definition for Descriptor offset */ #define QDMA_CCDF_STATUS 20 @@ -304,7 +305,7 @@ vchan_dma_desc_free_list(&fsl_chan->vchan, &head); - if (!fsl_queue->comp_pool && !fsl_queue->comp_pool) + if (!fsl_queue->comp_pool && !fsl_queue->desc_pool) return; list_for_each_entry_safe(comp_temp, _comp_temp, @@ -372,7 +373,8 @@ qdma_csgf_set_f(csgf_dest, len); /* Descriptor Buffer */ cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE << - FSL_QDMA_CMD_RWTTYPE_OFFSET); + FSL_QDMA_CMD_RWTTYPE_OFFSET) | + FSL_QDMA_CMD_PF; sdf->data = QDMA_SDDF_CMD(cmd); cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE << @@ -502,11 +504,11 @@ queue_temp = queue_head + i + (j * queue_num); queue_temp->cq = - dma_alloc_coherent(&pdev->dev, - sizeof(struct fsl_qdma_format) * - queue_size[i], - &queue_temp->bus_addr, - GFP_KERNEL); + dmam_alloc_coherent(&pdev->dev, + sizeof(struct fsl_qdma_format) * + queue_size[i], + &queue_temp->bus_addr, + GFP_KERNEL); if (!queue_temp->cq) return NULL; queue_temp->block_base = fsl_qdma->block_base + @@ -551,11 +553,11 @@ /* * Buffer for queue command */ - status_head->cq = dma_alloc_coherent(&pdev->dev, - sizeof(struct fsl_qdma_format) * - status_size, - &status_head->bus_addr, - GFP_KERNEL); + status_head->cq = dmam_alloc_coherent(&pdev->dev, + sizeof(struct fsl_qdma_format) * + status_size, + &status_head->bus_addr, + GFP_KERNEL); if (!status_head->cq) { devm_kfree(&pdev->dev, status_head); return NULL; @@ -754,7 +756,7 @@ int i; int cpu; int ret; - char irq_name[20]; + char irq_name[32]; fsl_qdma->error_irq = platform_get_irq_byname(pdev, "qdma-error"); @@ -1150,11 +1152,10 @@ if (!fsl_qdma->queue) return -ENOMEM; - ret = fsl_qdma_irq_init(pdev, fsl_qdma); - if (ret) - return ret; - fsl_qdma->irq_base = platform_get_irq_byname(pdev, "qdma-queue0"); + if (fsl_qdma->irq_base < 0) + return fsl_qdma->irq_base; + fsl_qdma->feature = of_property_read_bool(np, "big-endian"); INIT_LIST_HEAD(&fsl_qdma->dma_dev.channels); @@ -1181,20 +1182,27 @@ fsl_qdma->dma_dev.device_synchronize = fsl_qdma_synchronize; fsl_qdma->dma_dev.device_terminate_all = fsl_qdma_terminate_all; - dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); + if (ret) { + dev_err(&pdev->dev, "dma_set_mask failure.\n"); + return ret; + } platform_set_drvdata(pdev, fsl_qdma); - ret = dma_async_device_register(&fsl_qdma->dma_dev); + ret = fsl_qdma_reg_init(fsl_qdma); if (ret) { - dev_err(&pdev->dev, - "Can't register NXP Layerscape qDMA engine.\n"); + dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n"); return ret; } - ret = fsl_qdma_reg_init(fsl_qdma); + ret = fsl_qdma_irq_init(pdev, fsl_qdma); + if (ret) + return ret; + + ret = dma_async_device_register(&fsl_qdma->dma_dev); if (ret) { - dev_err(&pdev->dev, "Can't Initialize the qDMA engine.\n"); + dev_err(&pdev->dev, "Can't register NXP Layerscape qDMA engine.\n"); return ret; } @@ -1214,8 +1222,6 @@ static int fsl_qdma_remove(struct platform_device *pdev) { - int i; - struct fsl_qdma_queue *status; struct device_node *np = pdev->dev.of_node; struct fsl_qdma_engine *fsl_qdma = platform_get_drvdata(pdev); @@ -1224,11 +1230,6 @@ of_dma_controller_free(np); dma_async_device_unregister(&fsl_qdma->dma_dev); - for (i = 0; i < fsl_qdma->block_number; i++) { - status = fsl_qdma->status[i]; - dma_free_coherent(&pdev->dev, sizeof(struct fsl_qdma_format) * - status->n_cq, status->cq, status->bus_addr); - } return 0; } --- linux-oracle-5.4.0.orig/drivers/dma/fsldma.c +++ linux-oracle-5.4.0/drivers/dma/fsldma.c @@ -1214,6 +1214,7 @@ { struct fsldma_device *fdev; struct device_node *child; + unsigned int i; int err; fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); @@ -1292,6 +1293,10 @@ return 0; out_free_fdev: + for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) { + if (fdev->chan[i]) + fsl_dma_chan_remove(fdev->chan[i]); + } irq_dispose_mapping(fdev->irq); iounmap(fdev->regs); out_free: @@ -1314,6 +1319,7 @@ if (fdev->chan[i]) fsl_dma_chan_remove(fdev->chan[i]); } + irq_dispose_mapping(fdev->irq); iounmap(fdev->regs); kfree(fdev); --- linux-oracle-5.4.0.orig/drivers/dma/fsldma.h +++ linux-oracle-5.4.0/drivers/dma/fsldma.h @@ -205,10 +205,10 @@ #else static u64 fsl_ioread64(const u64 __iomem *addr) { - u32 fsl_addr = lower_32_bits(addr); - u64 fsl_addr_hi = (u64)in_le32((u32 *)(fsl_addr + 1)) << 32; + u32 val_lo = in_le32((u32 __iomem *)addr); + u32 val_hi = in_le32((u32 __iomem *)addr + 1); - return fsl_addr_hi | in_le32((u32 *)fsl_addr); + return ((u64)val_hi << 32) + val_lo; } static void fsl_iowrite64(u64 val, u64 __iomem *addr) @@ -219,10 +219,10 @@ static u64 fsl_ioread64be(const u64 __iomem *addr) { - u32 fsl_addr = lower_32_bits(addr); - u64 fsl_addr_hi = (u64)in_be32((u32 *)fsl_addr) << 32; + u32 val_hi = in_be32((u32 __iomem *)addr); + u32 val_lo = in_be32((u32 __iomem *)addr + 1); - return fsl_addr_hi | in_be32((u32 *)(fsl_addr + 1)); + return ((u64)val_hi << 32) + val_lo; } static void fsl_iowrite64be(u64 val, u64 __iomem *addr) --- linux-oracle-5.4.0.orig/drivers/dma/hisi_dma.c +++ linux-oracle-5.4.0/drivers/dma/hisi_dma.c @@ -0,0 +1,611 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2019 HiSilicon Limited. */ +#include +#include +#include +#include +#include +#include +#include +#include "virt-dma.h" + +#define HISI_DMA_SQ_BASE_L 0x0 +#define HISI_DMA_SQ_BASE_H 0x4 +#define HISI_DMA_SQ_DEPTH 0x8 +#define HISI_DMA_SQ_TAIL_PTR 0xc +#define HISI_DMA_CQ_BASE_L 0x10 +#define HISI_DMA_CQ_BASE_H 0x14 +#define HISI_DMA_CQ_DEPTH 0x18 +#define HISI_DMA_CQ_HEAD_PTR 0x1c +#define HISI_DMA_CTRL0 0x20 +#define HISI_DMA_CTRL0_QUEUE_EN_S 0 +#define HISI_DMA_CTRL0_QUEUE_PAUSE_S 4 +#define HISI_DMA_CTRL1 0x24 +#define HISI_DMA_CTRL1_QUEUE_RESET_S 0 +#define HISI_DMA_Q_FSM_STS 0x30 +#define HISI_DMA_FSM_STS_MASK GENMASK(3, 0) +#define HISI_DMA_INT_STS 0x40 +#define HISI_DMA_INT_STS_MASK GENMASK(12, 0) +#define HISI_DMA_INT_MSK 0x44 +#define HISI_DMA_MODE 0x217c +#define HISI_DMA_OFFSET 0x100 + +#define HISI_DMA_MSI_NUM 30 +#define HISI_DMA_CHAN_NUM 30 +#define HISI_DMA_Q_DEPTH_VAL 1024 + +#define PCI_BAR_2 2 + +enum hisi_dma_mode { + EP = 0, + RC, +}; + +enum hisi_dma_chan_status { + DISABLE = -1, + IDLE = 0, + RUN, + CPL, + PAUSE, + HALT, + ABORT, + WAIT, + BUFFCLR, +}; + +struct hisi_dma_sqe { + __le32 dw0; +#define OPCODE_MASK GENMASK(3, 0) +#define OPCODE_SMALL_PACKAGE 0x1 +#define OPCODE_M2M 0x4 +#define LOCAL_IRQ_EN BIT(8) +#define ATTR_SRC_MASK GENMASK(14, 12) + __le32 dw1; + __le32 dw2; +#define ATTR_DST_MASK GENMASK(26, 24) + __le32 length; + __le64 src_addr; + __le64 dst_addr; +}; + +struct hisi_dma_cqe { + __le32 rsv0; + __le32 rsv1; + __le16 sq_head; + __le16 rsv2; + __le16 rsv3; + __le16 w0; +#define STATUS_MASK GENMASK(15, 1) +#define STATUS_SUCC 0x0 +#define VALID_BIT BIT(0) +}; + +struct hisi_dma_desc { + struct virt_dma_desc vd; + struct hisi_dma_sqe sqe; +}; + +struct hisi_dma_chan { + struct virt_dma_chan vc; + struct hisi_dma_dev *hdma_dev; + struct hisi_dma_sqe *sq; + struct hisi_dma_cqe *cq; + dma_addr_t sq_dma; + dma_addr_t cq_dma; + u32 sq_tail; + u32 cq_head; + u32 qp_num; + enum hisi_dma_chan_status status; + struct hisi_dma_desc *desc; +}; + +struct hisi_dma_dev { + struct pci_dev *pdev; + void __iomem *base; + struct dma_device dma_dev; + u32 chan_num; + u32 chan_depth; + struct hisi_dma_chan chan[]; +}; + +static inline struct hisi_dma_chan *to_hisi_dma_chan(struct dma_chan *c) +{ + return container_of(c, struct hisi_dma_chan, vc.chan); +} + +static inline struct hisi_dma_desc *to_hisi_dma_desc(struct virt_dma_desc *vd) +{ + return container_of(vd, struct hisi_dma_desc, vd); +} + +static inline void hisi_dma_chan_write(void __iomem *base, u32 reg, u32 index, + u32 val) +{ + writel_relaxed(val, base + reg + index * HISI_DMA_OFFSET); +} + +static inline void hisi_dma_update_bit(void __iomem *addr, u32 pos, bool val) +{ + u32 tmp; + + tmp = readl_relaxed(addr); + tmp = val ? tmp | BIT(pos) : tmp & ~BIT(pos); + writel_relaxed(tmp, addr); +} + +static void hisi_dma_free_irq_vectors(void *data) +{ + pci_free_irq_vectors(data); +} + +static void hisi_dma_pause_dma(struct hisi_dma_dev *hdma_dev, u32 index, + bool pause) +{ + void __iomem *addr = hdma_dev->base + HISI_DMA_CTRL0 + index * + HISI_DMA_OFFSET; + + hisi_dma_update_bit(addr, HISI_DMA_CTRL0_QUEUE_PAUSE_S, pause); +} + +static void hisi_dma_enable_dma(struct hisi_dma_dev *hdma_dev, u32 index, + bool enable) +{ + void __iomem *addr = hdma_dev->base + HISI_DMA_CTRL0 + index * + HISI_DMA_OFFSET; + + hisi_dma_update_bit(addr, HISI_DMA_CTRL0_QUEUE_EN_S, enable); +} + +static void hisi_dma_mask_irq(struct hisi_dma_dev *hdma_dev, u32 qp_index) +{ + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_INT_MSK, qp_index, + HISI_DMA_INT_STS_MASK); +} + +static void hisi_dma_unmask_irq(struct hisi_dma_dev *hdma_dev, u32 qp_index) +{ + void __iomem *base = hdma_dev->base; + + hisi_dma_chan_write(base, HISI_DMA_INT_STS, qp_index, + HISI_DMA_INT_STS_MASK); + hisi_dma_chan_write(base, HISI_DMA_INT_MSK, qp_index, 0); +} + +static void hisi_dma_do_reset(struct hisi_dma_dev *hdma_dev, u32 index) +{ + void __iomem *addr = hdma_dev->base + HISI_DMA_CTRL1 + index * + HISI_DMA_OFFSET; + + hisi_dma_update_bit(addr, HISI_DMA_CTRL1_QUEUE_RESET_S, 1); +} + +static void hisi_dma_reset_qp_point(struct hisi_dma_dev *hdma_dev, u32 index) +{ + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_SQ_TAIL_PTR, index, 0); + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_CQ_HEAD_PTR, index, 0); +} + +static void hisi_dma_reset_hw_chan(struct hisi_dma_chan *chan) +{ + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + u32 index = chan->qp_num, tmp; + int ret; + + hisi_dma_pause_dma(hdma_dev, index, true); + hisi_dma_enable_dma(hdma_dev, index, false); + hisi_dma_mask_irq(hdma_dev, index); + + ret = readl_relaxed_poll_timeout(hdma_dev->base + + HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp, + FIELD_GET(HISI_DMA_FSM_STS_MASK, tmp) != RUN, 10, 1000); + if (ret) { + dev_err(&hdma_dev->pdev->dev, "disable channel timeout!\n"); + WARN_ON(1); + } + + hisi_dma_do_reset(hdma_dev, index); + hisi_dma_reset_qp_point(hdma_dev, index); + hisi_dma_pause_dma(hdma_dev, index, false); + hisi_dma_enable_dma(hdma_dev, index, true); + hisi_dma_unmask_irq(hdma_dev, index); + + ret = readl_relaxed_poll_timeout(hdma_dev->base + + HISI_DMA_Q_FSM_STS + index * HISI_DMA_OFFSET, tmp, + FIELD_GET(HISI_DMA_FSM_STS_MASK, tmp) == IDLE, 10, 1000); + if (ret) { + dev_err(&hdma_dev->pdev->dev, "reset channel timeout!\n"); + WARN_ON(1); + } +} + +static void hisi_dma_free_chan_resources(struct dma_chan *c) +{ + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + + hisi_dma_reset_hw_chan(chan); + vchan_free_chan_resources(&chan->vc); + + memset(chan->sq, 0, sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth); + memset(chan->cq, 0, sizeof(struct hisi_dma_cqe) * hdma_dev->chan_depth); + chan->sq_tail = 0; + chan->cq_head = 0; + chan->status = DISABLE; +} + +static void hisi_dma_desc_free(struct virt_dma_desc *vd) +{ + kfree(to_hisi_dma_desc(vd)); +} + +static struct dma_async_tx_descriptor * +hisi_dma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dst, dma_addr_t src, + size_t len, unsigned long flags) +{ + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + struct hisi_dma_desc *desc; + + desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + if (!desc) + return NULL; + + desc->sqe.length = cpu_to_le32(len); + desc->sqe.src_addr = cpu_to_le64(src); + desc->sqe.dst_addr = cpu_to_le64(dst); + + return vchan_tx_prep(&chan->vc, &desc->vd, flags); +} + +static enum dma_status +hisi_dma_tx_status(struct dma_chan *c, dma_cookie_t cookie, + struct dma_tx_state *txstate) +{ + return dma_cookie_status(c, cookie, txstate); +} + +static void hisi_dma_start_transfer(struct hisi_dma_chan *chan) +{ + struct hisi_dma_sqe *sqe = chan->sq + chan->sq_tail; + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + struct hisi_dma_desc *desc; + struct virt_dma_desc *vd; + + vd = vchan_next_desc(&chan->vc); + if (!vd) { + dev_err(&hdma_dev->pdev->dev, "no issued task!\n"); + chan->desc = NULL; + return; + } + list_del(&vd->node); + desc = to_hisi_dma_desc(vd); + chan->desc = desc; + + memcpy(sqe, &desc->sqe, sizeof(struct hisi_dma_sqe)); + + /* update other field in sqe */ + sqe->dw0 = cpu_to_le32(FIELD_PREP(OPCODE_MASK, OPCODE_M2M)); + sqe->dw0 |= cpu_to_le32(LOCAL_IRQ_EN); + + /* make sure data has been updated in sqe */ + wmb(); + + /* update sq tail, point to new sqe position */ + chan->sq_tail = (chan->sq_tail + 1) % hdma_dev->chan_depth; + + /* update sq_tail to trigger a new task */ + hisi_dma_chan_write(hdma_dev->base, HISI_DMA_SQ_TAIL_PTR, chan->qp_num, + chan->sq_tail); +} + +static void hisi_dma_issue_pending(struct dma_chan *c) +{ + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + unsigned long flags; + + spin_lock_irqsave(&chan->vc.lock, flags); + + if (vchan_issue_pending(&chan->vc)) + hisi_dma_start_transfer(chan); + + spin_unlock_irqrestore(&chan->vc.lock, flags); +} + +static int hisi_dma_terminate_all(struct dma_chan *c) +{ + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + unsigned long flags; + LIST_HEAD(head); + + spin_lock_irqsave(&chan->vc.lock, flags); + + hisi_dma_pause_dma(chan->hdma_dev, chan->qp_num, true); + if (chan->desc) { + vchan_terminate_vdesc(&chan->desc->vd); + chan->desc = NULL; + } + + vchan_get_all_descriptors(&chan->vc, &head); + + spin_unlock_irqrestore(&chan->vc.lock, flags); + + vchan_dma_desc_free_list(&chan->vc, &head); + hisi_dma_pause_dma(chan->hdma_dev, chan->qp_num, false); + + return 0; +} + +static void hisi_dma_synchronize(struct dma_chan *c) +{ + struct hisi_dma_chan *chan = to_hisi_dma_chan(c); + + vchan_synchronize(&chan->vc); +} + +static int hisi_dma_alloc_qps_mem(struct hisi_dma_dev *hdma_dev) +{ + size_t sq_size = sizeof(struct hisi_dma_sqe) * hdma_dev->chan_depth; + size_t cq_size = sizeof(struct hisi_dma_cqe) * hdma_dev->chan_depth; + struct device *dev = &hdma_dev->pdev->dev; + struct hisi_dma_chan *chan; + int i; + + for (i = 0; i < hdma_dev->chan_num; i++) { + chan = &hdma_dev->chan[i]; + chan->sq = dmam_alloc_coherent(dev, sq_size, &chan->sq_dma, + GFP_KERNEL); + if (!chan->sq) + return -ENOMEM; + + chan->cq = dmam_alloc_coherent(dev, cq_size, &chan->cq_dma, + GFP_KERNEL); + if (!chan->cq) + return -ENOMEM; + } + + return 0; +} + +static void hisi_dma_init_hw_qp(struct hisi_dma_dev *hdma_dev, u32 index) +{ + struct hisi_dma_chan *chan = &hdma_dev->chan[index]; + u32 hw_depth = hdma_dev->chan_depth - 1; + void __iomem *base = hdma_dev->base; + + /* set sq, cq base */ + hisi_dma_chan_write(base, HISI_DMA_SQ_BASE_L, index, + lower_32_bits(chan->sq_dma)); + hisi_dma_chan_write(base, HISI_DMA_SQ_BASE_H, index, + upper_32_bits(chan->sq_dma)); + hisi_dma_chan_write(base, HISI_DMA_CQ_BASE_L, index, + lower_32_bits(chan->cq_dma)); + hisi_dma_chan_write(base, HISI_DMA_CQ_BASE_H, index, + upper_32_bits(chan->cq_dma)); + + /* set sq, cq depth */ + hisi_dma_chan_write(base, HISI_DMA_SQ_DEPTH, index, hw_depth); + hisi_dma_chan_write(base, HISI_DMA_CQ_DEPTH, index, hw_depth); + + /* init sq tail and cq head */ + hisi_dma_chan_write(base, HISI_DMA_SQ_TAIL_PTR, index, 0); + hisi_dma_chan_write(base, HISI_DMA_CQ_HEAD_PTR, index, 0); +} + +static void hisi_dma_enable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) +{ + hisi_dma_init_hw_qp(hdma_dev, qp_index); + hisi_dma_unmask_irq(hdma_dev, qp_index); + hisi_dma_enable_dma(hdma_dev, qp_index, true); +} + +static void hisi_dma_disable_qp(struct hisi_dma_dev *hdma_dev, u32 qp_index) +{ + hisi_dma_reset_hw_chan(&hdma_dev->chan[qp_index]); +} + +static void hisi_dma_enable_qps(struct hisi_dma_dev *hdma_dev) +{ + int i; + + for (i = 0; i < hdma_dev->chan_num; i++) { + hdma_dev->chan[i].qp_num = i; + hdma_dev->chan[i].hdma_dev = hdma_dev; + hdma_dev->chan[i].vc.desc_free = hisi_dma_desc_free; + vchan_init(&hdma_dev->chan[i].vc, &hdma_dev->dma_dev); + hisi_dma_enable_qp(hdma_dev, i); + } +} + +static void hisi_dma_disable_qps(struct hisi_dma_dev *hdma_dev) +{ + int i; + + for (i = 0; i < hdma_dev->chan_num; i++) { + hisi_dma_disable_qp(hdma_dev, i); + tasklet_kill(&hdma_dev->chan[i].vc.task); + } +} + +static irqreturn_t hisi_dma_irq(int irq, void *data) +{ + struct hisi_dma_chan *chan = data; + struct hisi_dma_dev *hdma_dev = chan->hdma_dev; + struct hisi_dma_desc *desc; + struct hisi_dma_cqe *cqe; + unsigned long flags; + + spin_lock_irqsave(&chan->vc.lock, flags); + + desc = chan->desc; + cqe = chan->cq + chan->cq_head; + if (desc) { + if (FIELD_GET(STATUS_MASK, cqe->w0) == STATUS_SUCC) { + chan->cq_head = (chan->cq_head + 1) % + hdma_dev->chan_depth; + hisi_dma_chan_write(hdma_dev->base, + HISI_DMA_CQ_HEAD_PTR, chan->qp_num, + chan->cq_head); + vchan_cookie_complete(&desc->vd); + } else { + dev_err(&hdma_dev->pdev->dev, "task error!\n"); + } + + chan->desc = NULL; + } + + spin_unlock_irqrestore(&chan->vc.lock, flags); + + return IRQ_HANDLED; +} + +static int hisi_dma_request_qps_irq(struct hisi_dma_dev *hdma_dev) +{ + struct pci_dev *pdev = hdma_dev->pdev; + int i, ret; + + for (i = 0; i < hdma_dev->chan_num; i++) { + ret = devm_request_irq(&pdev->dev, pci_irq_vector(pdev, i), + hisi_dma_irq, IRQF_SHARED, "hisi_dma", + &hdma_dev->chan[i]); + if (ret) + return ret; + } + + return 0; +} + +/* This function enables all hw channels in a device */ +static int hisi_dma_enable_hw_channels(struct hisi_dma_dev *hdma_dev) +{ + int ret; + + ret = hisi_dma_alloc_qps_mem(hdma_dev); + if (ret) { + dev_err(&hdma_dev->pdev->dev, "fail to allocate qp memory!\n"); + return ret; + } + + ret = hisi_dma_request_qps_irq(hdma_dev); + if (ret) { + dev_err(&hdma_dev->pdev->dev, "fail to request qp irq!\n"); + return ret; + } + + hisi_dma_enable_qps(hdma_dev); + + return 0; +} + +static void hisi_dma_disable_hw_channels(void *data) +{ + hisi_dma_disable_qps(data); +} + +static void hisi_dma_set_mode(struct hisi_dma_dev *hdma_dev, + enum hisi_dma_mode mode) +{ + writel_relaxed(mode == RC ? 1 : 0, hdma_dev->base + HISI_DMA_MODE); +} + +static int hisi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct device *dev = &pdev->dev; + struct hisi_dma_dev *hdma_dev; + struct dma_device *dma_dev; + size_t dev_size; + int ret; + + ret = pcim_enable_device(pdev); + if (ret) { + dev_err(dev, "failed to enable device mem!\n"); + return ret; + } + + ret = pcim_iomap_regions(pdev, 1 << PCI_BAR_2, pci_name(pdev)); + if (ret) { + dev_err(dev, "failed to remap I/O region!\n"); + return ret; + } + + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + return ret; + + ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); + if (ret) + return ret; + + dev_size = sizeof(struct hisi_dma_chan) * HISI_DMA_CHAN_NUM + + sizeof(*hdma_dev); + hdma_dev = devm_kzalloc(dev, dev_size, GFP_KERNEL); + if (!hdma_dev) + return -EINVAL; + + hdma_dev->base = pcim_iomap_table(pdev)[PCI_BAR_2]; + hdma_dev->pdev = pdev; + hdma_dev->chan_num = HISI_DMA_CHAN_NUM; + hdma_dev->chan_depth = HISI_DMA_Q_DEPTH_VAL; + + pci_set_drvdata(pdev, hdma_dev); + pci_set_master(pdev); + + ret = pci_alloc_irq_vectors(pdev, HISI_DMA_MSI_NUM, HISI_DMA_MSI_NUM, + PCI_IRQ_MSI); + if (ret < 0) { + dev_err(dev, "Failed to allocate MSI vectors!\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, hisi_dma_free_irq_vectors, pdev); + if (ret) + return ret; + + dma_dev = &hdma_dev->dma_dev; + dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); + dma_dev->device_free_chan_resources = hisi_dma_free_chan_resources; + dma_dev->device_prep_dma_memcpy = hisi_dma_prep_dma_memcpy; + dma_dev->device_tx_status = hisi_dma_tx_status; + dma_dev->device_issue_pending = hisi_dma_issue_pending; + dma_dev->device_terminate_all = hisi_dma_terminate_all; + dma_dev->device_synchronize = hisi_dma_synchronize; + dma_dev->directions = BIT(DMA_MEM_TO_MEM); + dma_dev->dev = dev; + INIT_LIST_HEAD(&dma_dev->channels); + + hisi_dma_set_mode(hdma_dev, RC); + + ret = hisi_dma_enable_hw_channels(hdma_dev); + if (ret < 0) { + dev_err(dev, "failed to enable hw channel!\n"); + return ret; + } + + ret = devm_add_action_or_reset(dev, hisi_dma_disable_hw_channels, + hdma_dev); + if (ret) + return ret; + + ret = dmaenginem_async_device_register(dma_dev); + if (ret < 0) + dev_err(dev, "failed to register device!\n"); + + return ret; +} + +static const struct pci_device_id hisi_dma_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa122) }, + { 0, } +}; + +static struct pci_driver hisi_dma_pci_driver = { + .name = "hisi_dma", + .id_table = hisi_dma_pci_tbl, + .probe = hisi_dma_probe, +}; + +module_pci_driver(hisi_dma_pci_driver); + +MODULE_AUTHOR("Zhou Wang "); +MODULE_AUTHOR("Zhenfa Qiu "); +MODULE_DESCRIPTION("HiSilicon Kunpeng DMA controller driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(pci, hisi_dma_pci_tbl); --- linux-oracle-5.4.0.orig/drivers/dma/hsu/pci.c +++ linux-oracle-5.4.0/drivers/dma/hsu/pci.c @@ -26,22 +26,12 @@ static irqreturn_t hsu_pci_irq(int irq, void *dev) { struct hsu_dma_chip *chip = dev; - struct pci_dev *pdev = to_pci_dev(chip->dev); u32 dmaisr; u32 status; unsigned short i; int ret = 0; int err; - /* - * On Intel Tangier B0 and Anniedale the interrupt line, disregarding - * to have different numbers, is shared between HSU DMA and UART IPs. - * Thus on such SoCs we are expecting that IRQ handler is called in - * UART driver only. - */ - if (pdev->device == PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA) - return IRQ_HANDLED; - dmaisr = readl(chip->regs + HSU_PCI_DMAISR); for (i = 0; i < chip->hsu->nr_channels; i++) { if (dmaisr & 0x1) { @@ -105,6 +95,17 @@ if (ret) goto err_register_irq; + /* + * On Intel Tangier B0 and Anniedale the interrupt line, disregarding + * to have different numbers, is shared between HSU DMA and UART IPs. + * Thus on such SoCs we are expecting that IRQ handler is called in + * UART driver only. Instead of handling the spurious interrupt + * from HSU DMA here and waste CPU time and delay HSU UART interrupt + * handling, disable the interrupt entirely. + */ + if (pdev->device == PCI_DEVICE_ID_INTEL_MRFLD_HSU_DMA) + disable_irq_nosync(chip->irq); + pci_set_drvdata(pdev, chip); return 0; --- linux-oracle-5.4.0.orig/drivers/dma/idma64.c +++ linux-oracle-5.4.0/drivers/dma/idma64.c @@ -167,6 +167,10 @@ u32 status_err; unsigned short i; + /* Since IRQ may be shared, check if DMA controller is powered on */ + if (status == GENMASK(31, 0)) + return IRQ_NONE; + dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status); /* Check if we have any interrupt from the DMA controller */ @@ -590,7 +594,9 @@ idma64->dma.dev = chip->sysdev; - dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + ret = dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK); + if (ret) + return ret; ret = dma_async_device_register(&idma64->dma); if (ret) --- linux-oracle-5.4.0.orig/drivers/dma/imx-dma.c +++ linux-oracle-5.4.0/drivers/dma/imx-dma.c @@ -832,6 +832,8 @@ dma_length += sg_dma_len(sg); } + imxdma_config_write(chan, &imxdmac->config, direction); + switch (imxdmac->word_size) { case DMA_SLAVE_BUSWIDTH_4_BYTES: if (sg_dma_len(sgl) & 3 || sgl->dma_address & 3) --- linux-oracle-5.4.0.orig/drivers/dma/imx-sdma.c +++ linux-oracle-5.4.0/drivers/dma/imx-sdma.c @@ -377,7 +377,6 @@ unsigned long watermark_level; u32 shp_addr, per_addr; enum dma_status status; - bool context_loaded; struct imx_dma_data data; struct work_struct terminate_worker; }; @@ -988,9 +987,6 @@ int ret; unsigned long flags; - if (sdmac->context_loaded) - return 0; - if (sdmac->direction == DMA_DEV_TO_MEM) load_address = sdmac->pc_from_device; else if (sdmac->direction == DMA_DEV_TO_DEV) @@ -1033,8 +1029,6 @@ spin_unlock_irqrestore(&sdma->channel_0_lock, flags); - sdmac->context_loaded = true; - return ret; } @@ -1074,7 +1068,6 @@ sdmac->desc = NULL; spin_unlock_irqrestore(&sdmac->vc.lock, flags); vchan_dma_desc_free_list(&sdmac->vc, &head); - sdmac->context_loaded = false; } static int sdma_disable_channel_async(struct dma_chan *chan) @@ -1141,7 +1134,6 @@ static int sdma_config_channel(struct dma_chan *chan) { struct sdma_channel *sdmac = to_sdma_chan(chan); - int ret; sdma_disable_channel(chan); @@ -1181,9 +1173,7 @@ sdmac->watermark_level = 0; /* FIXME: M3_BASE_ADDRESS */ } - ret = sdma_load_context(sdmac); - - return ret; + return 0; } static int sdma_set_channel_priority(struct sdma_channel *sdmac, @@ -1328,7 +1318,7 @@ sdma_channel_synchronize(chan); - if (sdmac->event_id0) + if (sdmac->event_id0 >= 0) sdma_event_disable(sdmac, sdmac->event_id0); if (sdmac->event_id1) sdma_event_disable(sdmac, sdmac->event_id1); @@ -1370,10 +1360,12 @@ sdma_config_ownership(sdmac, false, true, false); if (sdma_load_context(sdmac)) - goto err_desc_out; + goto err_bd_out; return desc; +err_bd_out: + sdma_free_bd(desc); err_desc_out: kfree(desc); err_out: @@ -1628,7 +1620,7 @@ memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg)); /* Set ENBLn earlier to make sure dma request triggered after that */ - if (sdmac->event_id0) { + if (sdmac->event_id0 >= 0) { if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events) return -EINVAL; sdma_event_enable(sdmac, sdmac->event_id0); @@ -1794,7 +1786,7 @@ u32 reg, val, shift, num_map, i; int ret = 0; - if (IS_ERR(np) || IS_ERR(gpr_np)) + if (IS_ERR(np) || !gpr_np) goto out; event_remap = of_find_property(np, propname, NULL); @@ -1842,7 +1834,7 @@ } out: - if (!IS_ERR(gpr_np)) + if (gpr_np) of_node_put(gpr_np); return ret; @@ -2218,7 +2210,7 @@ #if IS_ENABLED(CONFIG_SOC_IMX6Q) MODULE_FIRMWARE("imx/sdma/sdma-imx6q.bin"); #endif -#if IS_ENABLED(CONFIG_SOC_IMX7D) +#if IS_ENABLED(CONFIG_SOC_IMX7D) || IS_ENABLED(CONFIG_SOC_IMX8M) MODULE_FIRMWARE("imx/sdma/sdma-imx7d.bin"); #endif MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/dma/ioat/dma.c +++ linux-oracle-5.4.0/drivers/dma/ioat/dma.c @@ -26,6 +26,18 @@ #include "../dmaengine.h" +int completion_timeout = 200; +module_param(completion_timeout, int, 0644); +MODULE_PARM_DESC(completion_timeout, + "set ioat completion timeout [msec] (default 200 [msec])"); +int idle_timeout = 2000; +module_param(idle_timeout, int, 0644); +MODULE_PARM_DESC(idle_timeout, + "set ioat idel timeout [msec] (default 2000 [msec])"); + +#define IDLE_TIMEOUT msecs_to_jiffies(idle_timeout) +#define COMPLETION_TIMEOUT msecs_to_jiffies(completion_timeout) + static char *chanerr_str[] = { "DMA Transfer Source Address Error", "DMA Transfer Destination Address Error", @@ -377,10 +389,11 @@ descs->virt = dma_alloc_coherent(to_dev(ioat_chan), SZ_2M, &descs->hw, flags); - if (!descs->virt && (i > 0)) { + if (!descs->virt) { int idx; for (idx = 0; idx < i; idx++) { + descs = &ioat_chan->descs[idx]; dma_free_coherent(to_dev(ioat_chan), SZ_2M, descs->virt, descs->hw); descs->virt = NULL; @@ -640,7 +653,7 @@ if (active - i == 0) { dev_dbg(to_dev(ioat_chan), "%s: cancel completion timeout\n", __func__); - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); } /* microsecond delay by sysfs variable per pending descriptor */ @@ -666,7 +679,7 @@ if (chanerr & (IOAT_CHANERR_HANDLE_MASK | IOAT_CHANERR_RECOVER_MASK)) { - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); ioat_eh(ioat_chan); } } @@ -863,7 +876,7 @@ } if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &ioat_chan->state)) - mod_timer(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); + mod_timer_pending(&ioat_chan->timer, jiffies + IDLE_TIMEOUT); } void ioat_timer_event(struct timer_list *t) --- linux-oracle-5.4.0.orig/drivers/dma/ioat/dma.h +++ linux-oracle-5.4.0/drivers/dma/ioat/dma.h @@ -99,8 +99,6 @@ #define IOAT_RUN 5 #define IOAT_CHAN_ACTIVE 6 struct timer_list timer; - #define COMPLETION_TIMEOUT msecs_to_jiffies(100) - #define IDLE_TIMEOUT msecs_to_jiffies(2000) #define RESET_DELAY msecs_to_jiffies(100) struct ioatdma_device *ioat_dma; dma_addr_t completion_dma; --- linux-oracle-5.4.0.orig/drivers/dma/ioat/init.c +++ linux-oracle-5.4.0/drivers/dma/ioat/init.c @@ -1446,6 +1446,7 @@ static void __exit ioat_exit_module(void) { pci_unregister_driver(&ioat_pci_driver); + kmem_cache_destroy(ioat_sed_cache); kmem_cache_destroy(ioat_cache); } module_exit(ioat_exit_module); --- linux-oracle-5.4.0.orig/drivers/dma/k3dma.c +++ linux-oracle-5.4.0/drivers/dma/k3dma.c @@ -229,9 +229,11 @@ c = p->vchan; if (c && (tc1 & BIT(i))) { spin_lock_irqsave(&c->vc.lock, flags); - vchan_cookie_complete(&p->ds_run->vd); - p->ds_done = p->ds_run; - p->ds_run = NULL; + if (p->ds_run != NULL) { + vchan_cookie_complete(&p->ds_run->vd); + p->ds_done = p->ds_run; + p->ds_run = NULL; + } spin_unlock_irqrestore(&c->vc.lock, flags); } if (c && (tc2 & BIT(i))) { @@ -271,6 +273,10 @@ if (BIT(c->phy->idx) & k3_dma_get_chan_stat(d)) return -EAGAIN; + /* Avoid losing track of ds_run if a transaction is in flight */ + if (c->phy->ds_run) + return -EAGAIN; + if (vd) { struct k3_dma_desc_sw *ds = container_of(vd, struct k3_dma_desc_sw, vd); --- linux-oracle-5.4.0.orig/drivers/dma/mcf-edma.c +++ linux-oracle-5.4.0/drivers/dma/mcf-edma.c @@ -35,6 +35,13 @@ mcf_chan = &mcf_edma->chans[ch]; spin_lock(&mcf_chan->vchan.lock); + + if (!mcf_chan->edesc) { + /* terminate_all called before */ + spin_unlock(&mcf_chan->vchan.lock); + continue; + } + if (!mcf_chan->edesc->iscyclic) { list_del(&mcf_chan->edesc->vdesc.node); vchan_cookie_complete(&mcf_chan->edesc->vdesc); @@ -184,7 +191,13 @@ return -EINVAL; } - chans = pdata->dma_channels; + if (!pdata->dma_channels) { + dev_info(&pdev->dev, "setting default channel number to 64"); + chans = 64; + } else { + chans = pdata->dma_channels; + } + len = sizeof(*mcf_edma) + sizeof(*mcf_chan) * chans; mcf_edma = devm_kzalloc(&pdev->dev, len, GFP_KERNEL); if (!mcf_edma) @@ -196,11 +209,6 @@ mcf_edma->drvdata = &mcf_data; mcf_edma->big_endian = 1; - if (!mcf_edma->n_chans) { - dev_info(&pdev->dev, "setting default channel number to 64"); - mcf_edma->n_chans = 64; - } - mutex_init(&mcf_edma->fsl_edma_mutex); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); --- linux-oracle-5.4.0.orig/drivers/dma/mediatek/mtk-hsdma.c +++ linux-oracle-5.4.0/drivers/dma/mediatek/mtk-hsdma.c @@ -997,7 +997,7 @@ if (err) { dev_err(&pdev->dev, "request_irq failed with err %d\n", err); - goto err_unregister; + goto err_free; } platform_set_drvdata(pdev, hsdma); @@ -1006,6 +1006,9 @@ return 0; +err_free: + mtk_hsdma_hw_deinit(hsdma); + of_dma_controller_free(pdev->dev.of_node); err_unregister: dma_async_device_unregister(dd); --- linux-oracle-5.4.0.orig/drivers/dma/mediatek/mtk-uart-apdma.c +++ linux-oracle-5.4.0/drivers/dma/mediatek/mtk-uart-apdma.c @@ -131,10 +131,7 @@ static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd) { - struct dma_chan *chan = vd->tx.chan; - struct mtk_chan *c = to_mtk_uart_apdma_chan(chan); - - kfree(c->desc); + kfree(container_of(vd, struct mtk_uart_apdma_desc, vd)); } static void mtk_uart_apdma_start_tx(struct mtk_chan *c) @@ -207,14 +204,9 @@ static void mtk_uart_apdma_tx_handler(struct mtk_chan *c) { - struct mtk_uart_apdma_desc *d = c->desc; - mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_CLR_B); mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B); mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B); - - list_del(&d->vd.node); - vchan_cookie_complete(&d->vd); } static void mtk_uart_apdma_rx_handler(struct mtk_chan *c) @@ -245,9 +237,17 @@ c->rx_status = d->avail_len - cnt; mtk_uart_apdma_write(c, VFF_RPT, wg); +} + +static void mtk_uart_apdma_chan_complete_handler(struct mtk_chan *c) +{ + struct mtk_uart_apdma_desc *d = c->desc; - list_del(&d->vd.node); - vchan_cookie_complete(&d->vd); + if (d) { + list_del(&d->vd.node); + vchan_cookie_complete(&d->vd); + c->desc = NULL; + } } static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id) @@ -261,6 +261,7 @@ mtk_uart_apdma_rx_handler(c); else if (c->dir == DMA_MEM_TO_DEV) mtk_uart_apdma_tx_handler(c); + mtk_uart_apdma_chan_complete_handler(c); spin_unlock_irqrestore(&c->vc.lock, flags); return IRQ_HANDLED; @@ -273,7 +274,7 @@ unsigned int status; int ret; - ret = pm_runtime_get_sync(mtkd->ddev.dev); + ret = pm_runtime_resume_and_get(mtkd->ddev.dev); if (ret < 0) { pm_runtime_put_noidle(chan->device->dev); return ret; @@ -287,18 +288,21 @@ ret = readx_poll_timeout(readl, c->base + VFF_EN, status, !status, 10, 100); if (ret) - return ret; + goto err_pm; ret = request_irq(c->irq, mtk_uart_apdma_irq_handler, IRQF_TRIGGER_NONE, KBUILD_MODNAME, chan); if (ret < 0) { dev_err(chan->device->dev, "Can't request dma IRQ\n"); - return -EINVAL; + ret = -EINVAL; + goto err_pm; } if (mtkd->support_33bits) mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B); +err_pm: + pm_runtime_put_noidle(mtkd->ddev.dev); return ret; } @@ -348,7 +352,7 @@ return NULL; /* Now allocate and setup the descriptor */ - d = kzalloc(sizeof(*d), GFP_ATOMIC); + d = kzalloc(sizeof(*d), GFP_NOWAIT); if (!d) return NULL; @@ -366,7 +370,7 @@ unsigned long flags; spin_lock_irqsave(&c->vc.lock, flags); - if (vchan_issue_pending(&c->vc)) { + if (vchan_issue_pending(&c->vc) && !c->desc) { vd = vchan_next_desc(&c->vc); c->desc = to_mtk_uart_apdma_desc(&vd->tx); @@ -446,9 +450,8 @@ mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B); mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B); - synchronize_irq(c->irq); - spin_unlock_irqrestore(&c->vc.lock, flags); + synchronize_irq(c->irq); return 0; } --- linux-oracle-5.4.0.orig/drivers/dma/mmp_pdma.c +++ linux-oracle-5.4.0/drivers/dma/mmp_pdma.c @@ -728,12 +728,6 @@ chan->dir = direction; chan->dev_addr = addr; - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (cfg->slave_id) - chan->drcmr = cfg->slave_id; return 0; } --- linux-oracle-5.4.0.orig/drivers/dma/mmp_tdma.c +++ linux-oracle-5.4.0/drivers/dma/mmp_tdma.c @@ -363,6 +363,8 @@ gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, size); tdmac->desc_arr = NULL; + if (tdmac->status == DMA_ERROR) + tdmac->status = DMA_COMPLETE; return; } @@ -443,7 +445,8 @@ if (!desc) goto err_out; - mmp_tdma_config_write(chan, direction, &tdmac->slave_config); + if (mmp_tdma_config_write(chan, direction, &tdmac->slave_config)) + goto err_out; while (buf < buf_len) { desc = &tdmac->desc_arr[i]; --- linux-oracle-5.4.0.orig/drivers/dma/mv_xor.c +++ linux-oracle-5.4.0/drivers/dma/mv_xor.c @@ -1394,6 +1394,7 @@ irq = irq_of_parse_and_map(np, 0); if (!irq) { ret = -ENODEV; + of_node_put(np); goto err_channel_add; } @@ -1402,6 +1403,7 @@ if (IS_ERR(chan)) { ret = PTR_ERR(chan); irq_dispose_mapping(irq); + of_node_put(np); goto err_channel_add; } --- linux-oracle-5.4.0.orig/drivers/dma/mv_xor_v2.c +++ linux-oracle-5.4.0/drivers/dma/mv_xor_v2.c @@ -751,7 +751,7 @@ xor_dev->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { - ret = EPROBE_DEFER; + ret = -EPROBE_DEFER; goto disable_reg_clk; } if (!IS_ERR(xor_dev->clk)) { @@ -766,8 +766,10 @@ goto disable_clk; msi_desc = first_msi_entry(&pdev->dev); - if (!msi_desc) + if (!msi_desc) { + ret = -ENODEV; goto free_msi_irqs; + } xor_dev->msi_desc = msi_desc; ret = devm_request_irq(&pdev->dev, msi_desc->irq, @@ -893,6 +895,7 @@ tasklet_kill(&xor_dev->irq_tasklet); clk_disable_unprepare(xor_dev->clk); + clk_disable_unprepare(xor_dev->reg_clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/dma/of-dma.c +++ linux-oracle-5.4.0/drivers/dma/of-dma.c @@ -65,18 +65,23 @@ return NULL; ofdma_target = of_dma_find_controller(&dma_spec_target); - if (!ofdma_target) - return NULL; + if (!ofdma_target) { + ofdma->dma_router->route_free(ofdma->dma_router->dev, + route_data); + chan = ERR_PTR(-EPROBE_DEFER); + goto err; + } chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target); - if (chan) { - chan->router = ofdma->dma_router; - chan->route_data = route_data; - } else { + if (IS_ERR_OR_NULL(chan)) { ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data); + } else { + chan->router = ofdma->dma_router; + chan->route_data = route_data; } +err: /* * Need to put the node back since the ofdma->of_dma_route_allocate * has taken it for generating the new, translated dma_spec --- linux-oracle-5.4.0.orig/drivers/dma/owl-dma.c +++ linux-oracle-5.4.0/drivers/dma/owl-dma.c @@ -175,13 +175,11 @@ * @id: physical index to this channel * @base: virtual memory base for the dma channel * @vchan: the virtual channel currently being served by this physical channel - * @lock: a lock to use when altering an instance of this struct */ struct owl_dma_pchan { u32 id; void __iomem *base; struct owl_dma_vchan *vchan; - spinlock_t lock; }; /** @@ -240,7 +238,7 @@ else regval &= ~val; - writel(val, pchan->base + reg); + writel(regval, pchan->base + reg); } static void pchan_writel(struct owl_dma_pchan *pchan, u32 reg, u32 data) @@ -264,7 +262,7 @@ else regval &= ~val; - writel(val, od->base + reg); + writel(regval, od->base + reg); } static void dma_writel(struct owl_dma *od, u32 reg, u32 data) @@ -437,14 +435,14 @@ for (i = 0; i < od->nr_pchans; i++) { pchan = &od->pchans[i]; - spin_lock_irqsave(&pchan->lock, flags); + spin_lock_irqsave(&od->lock, flags); if (!pchan->vchan) { pchan->vchan = vchan; - spin_unlock_irqrestore(&pchan->lock, flags); + spin_unlock_irqrestore(&od->lock, flags); break; } - spin_unlock_irqrestore(&pchan->lock, flags); + spin_unlock_irqrestore(&od->lock, flags); } return pchan; @@ -1203,6 +1201,7 @@ owl_dma_free(od); clk_disable_unprepare(od->clk); + dma_pool_destroy(od->lli_pool); return 0; } --- linux-oracle-5.4.0.orig/drivers/dma/pch_dma.c +++ linux-oracle-5.4.0/drivers/dma/pch_dma.c @@ -865,6 +865,7 @@ } pci_set_master(pdev); + pd->dma.dev = &pdev->dev; err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); if (err) { @@ -880,7 +881,6 @@ goto err_free_irq; } - pd->dma.dev = &pdev->dev; INIT_LIST_HEAD(&pd->dma.channels); --- linux-oracle-5.4.0.orig/drivers/dma/pl330.c +++ linux-oracle-5.4.0/drivers/dma/pl330.c @@ -403,6 +403,12 @@ */ BUSY, /* + * Pause was called while descriptor was BUSY. Due to hardware + * limitations, only termination is possible for descriptors + * that have been paused. + */ + PAUSED, + /* * Sitting on the channel work_list but xfer done * by PL330 core */ @@ -1048,7 +1054,7 @@ return true; } -static bool _start(struct pl330_thread *thrd) +static bool pl330_start_thread(struct pl330_thread *thrd) { switch (_state(thrd)) { case PL330_STATE_FAULT_COMPLETING: @@ -1696,7 +1702,7 @@ thrd->req_running = -1; /* Get going again ASAP */ - _start(thrd); + pl330_start_thread(thrd); /* For now, just make a list of callbacks to be done */ list_add_tail(&descdone->rqd, &pl330->req_done); @@ -2035,7 +2041,7 @@ list_for_each_entry(desc, &pch->work_list, node) { /* If already submitted */ - if (desc->status == BUSY) + if (desc->status == BUSY || desc->status == PAUSED) continue; ret = pl330_submit_req(pch->thread, desc); @@ -2083,7 +2089,7 @@ } else { /* Make sure the PL330 Channel thread is active */ spin_lock(&pch->thread->dmac->lock); - _start(pch->thread); + pl330_start_thread(pch->thread); spin_unlock(&pch->thread->dmac->lock); } @@ -2101,7 +2107,7 @@ if (power_down) { pch->active = true; spin_lock(&pch->thread->dmac->lock); - _start(pch->thread); + pl330_start_thread(pch->thread); spin_unlock(&pch->thread->dmac->lock); power_down = false; } @@ -2322,6 +2328,7 @@ { struct dma_pl330_chan *pch = to_pchan(chan); struct pl330_dmac *pl330 = pch->dmac; + struct dma_pl330_desc *desc; unsigned long flags; pm_runtime_get_sync(pl330->ddma.dev); @@ -2331,6 +2338,10 @@ _stop(pch->thread); spin_unlock(&pl330->lock); + list_for_each_entry(desc, &pch->work_list, node) { + if (desc->status == BUSY) + desc->status = PAUSED; + } spin_unlock_irqrestore(&pch->lock, flags); pm_runtime_mark_last_busy(pl330->ddma.dev); pm_runtime_put_autosuspend(pl330->ddma.dev); @@ -2421,7 +2432,7 @@ else if (running && desc == running) transferred = pl330_get_current_xferred_count(pch, desc); - else if (desc->status == BUSY) + else if (desc->status == BUSY || desc->status == PAUSED) /* * Busy but not running means either just enqueued, * or finished and not yet marked done @@ -2438,6 +2449,9 @@ case DONE: ret = DMA_COMPLETE; break; + case PAUSED: + ret = DMA_PAUSED; + break; case PREP: case BUSY: ret = DMA_IN_PROGRESS; @@ -2585,7 +2599,7 @@ /* If the DMAC pool is empty, alloc new */ if (!desc) { - DEFINE_SPINLOCK(lock); + static DEFINE_SPINLOCK(lock); LIST_HEAD(pool); if (!add_desc(&pool, &lock, GFP_ATOMIC, 1)) @@ -2690,13 +2704,15 @@ for (i = 0; i < len / period_len; i++) { desc = pl330_get_desc(pch); if (!desc) { + unsigned long iflags; + dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", __func__, __LINE__); if (!first) return NULL; - spin_lock_irqsave(&pl330->pool_lock, flags); + spin_lock_irqsave(&pl330->pool_lock, iflags); while (!list_empty(&first->node)) { desc = list_entry(first->node.next, @@ -2706,7 +2722,7 @@ list_move_tail(&first->node, &pl330->desc_pool); - spin_unlock_irqrestore(&pl330->pool_lock, flags); + spin_unlock_irqrestore(&pl330->pool_lock, iflags); return NULL; } @@ -2788,14 +2804,14 @@ while (burst != (1 << desc->rqcfg.brst_size)) desc->rqcfg.brst_size++; + desc->rqcfg.brst_len = get_burst_len(desc, len); /* * If burst size is smaller than bus width then make sure we only * transfer one at a time to avoid a burst stradling an MFIFO entry. */ - if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width) + if (burst * 8 < pl330->pcfg.data_bus_width) desc->rqcfg.brst_len = 1; - desc->rqcfg.brst_len = get_burst_len(desc, len); desc->bytes_requested = len; desc->txd.flags = flags; --- linux-oracle-5.4.0.orig/drivers/dma/pxa_dma.c +++ linux-oracle-5.4.0/drivers/dma/pxa_dma.c @@ -723,7 +723,6 @@ dma_addr_t dma; struct pxad_desc_sw *sw_desc = to_pxad_sw_desc(vd); - BUG_ON(sw_desc->nb_desc == 0); for (i = sw_desc->nb_desc - 1; i >= 0; i--) { if (i > 0) dma = sw_desc->hw_desc[i - 1]->ddadr; @@ -911,13 +910,6 @@ *dcmd |= PXA_DCMD_BURST16; else if (maxburst == 32) *dcmd |= PXA_DCMD_BURST32; - - /* FIXME: drivers should be ported over to use the filter - * function. Once that's done, the following two lines can - * be removed. - */ - if (chan->cfg.slave_id) - chan->drcmr = chan->cfg.slave_id; } static struct dma_async_tx_descriptor * @@ -1256,14 +1248,14 @@ return -ENOMEM; for (i = 0; i < nb_phy_chans; i++) - if (platform_get_irq(op, i) > 0) + if (platform_get_irq_optional(op, i) > 0) nr_irq++; for (i = 0; i < nb_phy_chans; i++) { phy = &pdev->phys[i]; phy->base = pdev->base; phy->idx = i; - irq = platform_get_irq(op, i); + irq = platform_get_irq_optional(op, i); if ((nr_irq > 1) && (irq > 0)) ret = devm_request_irq(&op->dev, irq, pxad_chan_handler, --- linux-oracle-5.4.0.orig/drivers/dma/qcom/Kconfig +++ linux-oracle-5.4.0/drivers/dma/qcom/Kconfig @@ -10,6 +10,7 @@ config QCOM_HIDMA_MGMT tristate "Qualcomm Technologies HIDMA Management support" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for the Qualcomm Technologies HIDMA Management. --- linux-oracle-5.4.0.orig/drivers/dma/qcom/hidma_mgmt.c +++ linux-oracle-5.4.0/drivers/dma/qcom/hidma_mgmt.c @@ -418,8 +418,23 @@ hidma_mgmt_of_populate_channels(child); } #endif - return platform_driver_register(&hidma_mgmt_driver); + /* + * We do not check for return value here, as it is assumed that + * platform_driver_register must not fail. The reason for this is that + * the (potential) hidma_mgmt_of_populate_channels calls above are not + * cleaned up if it does fail, and to do this work is quite + * complicated. In particular, various calls of of_address_to_resource, + * of_irq_to_resource, platform_device_register_full, of_dma_configure, + * and of_msi_configure which then call other functions and so on, must + * be cleaned up - this is not a trivial exercise. + * + * Currently, this module is not intended to be unloaded, and there is + * no module_exit function defined which does the needed cleanup. For + * this reason, we have to assume success here. + */ + platform_driver_register(&hidma_mgmt_driver); + return 0; } module_init(hidma_mgmt_init); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/dma/sh/rcar-dmac.c +++ linux-oracle-5.4.0/drivers/dma/sh/rcar-dmac.c @@ -1824,8 +1824,13 @@ dmac->dev = &pdev->dev; platform_set_drvdata(pdev, dmac); dmac->dev->dma_parms = &dmac->parms; - dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); - dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); + ret = dma_set_max_seg_size(dmac->dev, RCAR_DMATCR_MASK); + if (ret) + return ret; + + ret = dma_set_mask_and_coherent(dmac->dev, DMA_BIT_MASK(40)); + if (ret) + return ret; ret = rcar_dmac_parse_of(&pdev->dev, dmac); if (ret < 0) @@ -1855,7 +1860,7 @@ /* Enable runtime PM and initialize the device. */ pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret); return ret; --- linux-oracle-5.4.0.orig/drivers/dma/sh/shdma.h +++ linux-oracle-5.4.0/drivers/dma/sh/shdma.h @@ -25,7 +25,7 @@ const struct sh_dmae_slave_config *config; /* Slave DMA configuration */ int xmit_shift; /* log_2(bytes_per_xfer) */ void __iomem *base; - char dev_id[16]; /* unique name per DMAC of channel */ + char dev_id[32]; /* unique name per DMAC of channel */ int pm_error; dma_addr_t slave_addr; }; --- linux-oracle-5.4.0.orig/drivers/dma/sh/usb-dmac.c +++ linux-oracle-5.4.0/drivers/dma/sh/usb-dmac.c @@ -586,6 +586,8 @@ desc->residue = usb_dmac_get_current_residue(chan, desc, desc->sg_index - 1); desc->done_cookie = desc->vd.tx.cookie; + desc->vd.tx_result.result = DMA_TRANS_NOERROR; + desc->vd.tx_result.residue = desc->residue; vchan_cookie_complete(&desc->vd); /* Restart the next transfer if this driver has a next desc */ @@ -853,8 +855,8 @@ error: of_dma_controller_free(pdev->dev.of_node); - pm_runtime_put(&pdev->dev); error_pm: + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/dma/sprd-dma.c +++ linux-oracle-5.4.0/drivers/dma/sprd-dma.c @@ -1201,11 +1201,8 @@ { struct sprd_dma_dev *sdev = platform_get_drvdata(pdev); struct sprd_dma_chn *c, *cn; - int ret; - ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) - return ret; + pm_runtime_get_sync(&pdev->dev); /* explicitly free the irq */ if (sdev->irq > 0) @@ -1230,6 +1227,7 @@ { .compatible = "sprd,sc9860-dma", }, {}, }; +MODULE_DEVICE_TABLE(of, sprd_dma_match); static int __maybe_unused sprd_dma_runtime_suspend(struct device *dev) { --- linux-oracle-5.4.0.orig/drivers/dma/st_fdma.c +++ linux-oracle-5.4.0/drivers/dma/st_fdma.c @@ -873,4 +873,4 @@ MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver"); MODULE_AUTHOR("Ludovic.barre "); MODULE_AUTHOR("Peter Griffin "); -MODULE_ALIAS("platform: " DRIVER_NAME); +MODULE_ALIAS("platform:" DRIVER_NAME); --- linux-oracle-5.4.0.orig/drivers/dma/ste_dma40.c +++ linux-oracle-5.4.0/drivers/dma/ste_dma40.c @@ -3599,6 +3599,10 @@ spin_lock_init(&base->lcla_pool.lock); base->irq = platform_get_irq(pdev, 0); + if (base->irq < 0) { + ret = base->irq; + goto destroy_cache; + } ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); if (ret) { @@ -3678,6 +3682,9 @@ kfree(base->lcla_pool.base_unaligned); + if (base->lcpa_base) + iounmap(base->lcpa_base); + if (base->phy_lcpa) release_mem_region(base->phy_lcpa, base->lcpa_size); @@ -3693,6 +3700,7 @@ regulator_disable(base->lcpa_regulator); regulator_put(base->lcpa_regulator); } + pm_runtime_disable(base->dev); kfree(base->lcla_pool.alloc_map); kfree(base->lookup_log_chans); --- linux-oracle-5.4.0.orig/drivers/dma/stm32-dma.c +++ linux-oracle-5.4.0/drivers/dma/stm32-dma.c @@ -488,8 +488,10 @@ spin_lock_irqsave(&chan->vchan.lock, flags); - if (chan->busy) { - stm32_dma_stop(chan); + if (chan->desc) { + vchan_terminate_vdesc(&chan->desc->vdesc); + if (chan->busy) + stm32_dma_stop(chan); chan->desc = NULL; } @@ -545,6 +547,8 @@ if (!vdesc) return; + list_del(&vdesc->node); + chan->desc = to_stm32_dma_desc(vdesc); chan->next_sg = 0; } @@ -622,7 +626,6 @@ } else { chan->busy = false; if (chan->next_sg == chan->desc->num_sgs) { - list_del(&chan->desc->vdesc.node); vchan_cookie_complete(&chan->desc->vdesc); chan->desc = NULL; } --- linux-oracle-5.4.0.orig/drivers/dma/stm32-mdma.c +++ linux-oracle-5.4.0/drivers/dma/stm32-mdma.c @@ -40,7 +40,6 @@ STM32_MDMA_SHIFT(mask)) #define STM32_MDMA_GISR0 0x0000 /* MDMA Int Status Reg 1 */ -#define STM32_MDMA_GISR1 0x0004 /* MDMA Int Status Reg 2 */ /* MDMA Channel x interrupt/status register */ #define STM32_MDMA_CISR(x) (0x40 + 0x40 * (x)) /* x = 0..62 */ @@ -184,7 +183,7 @@ #define STM32_MDMA_CTBR(x) (0x68 + 0x40 * (x)) #define STM32_MDMA_CTBR_DBUS BIT(17) #define STM32_MDMA_CTBR_SBUS BIT(16) -#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(7, 0) +#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(5, 0) #define STM32_MDMA_CTBR_TSEL(n) STM32_MDMA_SET(n, \ STM32_MDMA_CTBR_TSEL_MASK) @@ -196,7 +195,7 @@ #define STM32_MDMA_MAX_BUF_LEN 128 #define STM32_MDMA_MAX_BLOCK_LEN 65536 -#define STM32_MDMA_MAX_CHANNELS 63 +#define STM32_MDMA_MAX_CHANNELS 32 #define STM32_MDMA_MAX_REQUESTS 256 #define STM32_MDMA_MAX_BURST 128 #define STM32_MDMA_VERY_HIGH_PRIORITY 0x11 @@ -511,7 +510,7 @@ src_maxburst = chan->dma_config.src_maxburst; dst_maxburst = chan->dma_config.dst_maxburst; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); @@ -939,7 +938,7 @@ if (!desc) return NULL; - ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)); + ccr = stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & ~STM32_MDMA_CCR_EN; ctcr = stm32_mdma_read(dmadev, STM32_MDMA_CTCR(chan->id)); ctbr = stm32_mdma_read(dmadev, STM32_MDMA_CTBR(chan->id)); cbndtr = stm32_mdma_read(dmadev, STM32_MDMA_CBNDTR(chan->id)); @@ -1127,6 +1126,8 @@ return; } + list_del(&vdesc->node); + chan->desc = to_stm32_mdma_desc(vdesc); hwdesc = chan->desc->node[0].hwdesc; chan->curr_hwdesc = 0; @@ -1206,6 +1207,10 @@ unsigned long flags; u32 status, reg; + /* Transfer can be terminated */ + if (!chan->desc || (stm32_mdma_read(dmadev, STM32_MDMA_CCR(chan->id)) & STM32_MDMA_CCR_EN)) + return -EPERM; + hwdesc = chan->desc->node[chan->curr_hwdesc].hwdesc; spin_lock_irqsave(&chan->vchan.lock, flags); @@ -1242,8 +1247,10 @@ LIST_HEAD(head); spin_lock_irqsave(&chan->vchan.lock, flags); - if (chan->busy) { - stm32_mdma_stop(chan); + if (chan->desc) { + vchan_terminate_vdesc(&chan->desc->vdesc); + if (chan->busy) + stm32_mdma_stop(chan); chan->desc = NULL; } vchan_get_all_descriptors(&chan->vchan, &head); @@ -1331,7 +1338,6 @@ static void stm32_mdma_xfer_end(struct stm32_mdma_chan *chan) { - list_del(&chan->desc->vdesc.node); vchan_cookie_complete(&chan->desc->vdesc); chan->desc = NULL; chan->busy = false; @@ -1348,21 +1354,11 @@ /* Find out which channel generates the interrupt */ status = readl_relaxed(dmadev->base + STM32_MDMA_GISR0); - if (status) { - id = __ffs(status); - } else { - status = readl_relaxed(dmadev->base + STM32_MDMA_GISR1); - if (!status) { - dev_dbg(mdma2dev(dmadev), "spurious it\n"); - return IRQ_NONE; - } - id = __ffs(status); - /* - * As GISR0 provides status for channel id from 0 to 31, - * so GISR1 provides status for channel id from 32 to 62 - */ - id += 32; + if (!status) { + dev_dbg(mdma2dev(dmadev), "spurious it\n"); + return IRQ_NONE; } + id = __ffs(status); chan = &dmadev->chan[id]; if (!chan) { --- linux-oracle-5.4.0.orig/drivers/dma/tegra20-apb-dma.c +++ linux-oracle-5.4.0/drivers/dma/tegra20-apb-dma.c @@ -281,7 +281,7 @@ /* Do not allocate if desc are waiting for ack */ list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { - if (async_tx_test_ack(&dma_desc->txd)) { + if (async_tx_test_ack(&dma_desc->txd) && !dma_desc->cb_count) { list_del(&dma_desc->node); spin_unlock_irqrestore(&tdc->lock, flags); dma_desc->txd.flags = 0; @@ -756,10 +756,6 @@ bool was_busy; spin_lock_irqsave(&tdc->lock, flags); - if (list_empty(&tdc->pending_sg_req)) { - spin_unlock_irqrestore(&tdc->lock, flags); - return 0; - } if (!tdc->busy) goto skip_dma_stop; @@ -1291,8 +1287,7 @@ dev_dbg(tdc2dev(tdc), "Freeing channel %d\n", tdc->id); - if (tdc->busy) - tegra_dma_terminate_all(dc); + tegra_dma_terminate_all(dc); spin_lock_irqsave(&tdc->lock, flags); list_splice_init(&tdc->pending_sg_req, &sg_req_list); --- linux-oracle-5.4.0.orig/drivers/dma/tegra210-adma.c +++ linux-oracle-5.4.0/drivers/dma/tegra210-adma.c @@ -224,7 +224,7 @@ int ret; /* Clear any interrupts */ - tdma_write(tdma, tdma->cdata->global_int_clear, 0x1); + tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1); /* Assert soft reset */ tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1); @@ -658,6 +658,7 @@ ret = pm_runtime_get_sync(tdc2dev(tdc)); if (ret < 0) { + pm_runtime_put_noidle(tdc2dev(tdc)); free_irq(tdc->irq, tdc); return ret; } @@ -869,8 +870,10 @@ pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); goto rpm_disable; + } ret = tegra_adma_init(tdma); if (ret) @@ -900,7 +903,7 @@ ret = dma_async_device_register(&tdma->dma_dev); if (ret < 0) { dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret); - goto irq_dispose; + goto rpm_put; } ret = of_dma_controller_register(pdev->dev.of_node, --- linux-oracle-5.4.0.orig/drivers/dma/ti/dma-crossbar.c +++ linux-oracle-5.4.0/drivers/dma/ti/dma-crossbar.c @@ -247,6 +247,7 @@ if (dma_spec->args[0] >= xbar->xbar_requests) { dev_err(&pdev->dev, "Invalid XBAR request number: %d\n", dma_spec->args[0]); + put_device(&pdev->dev); return ERR_PTR(-EINVAL); } @@ -254,12 +255,14 @@ dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0); if (!dma_spec->np) { dev_err(&pdev->dev, "Can't get DMA master\n"); + put_device(&pdev->dev); return ERR_PTR(-EINVAL); } map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) { of_node_put(dma_spec->np); + put_device(&pdev->dev); return ERR_PTR(-ENOMEM); } @@ -270,6 +273,8 @@ mutex_unlock(&xbar->mutex); dev_err(&pdev->dev, "Run out of free DMA requests\n"); kfree(map); + of_node_put(dma_spec->np); + put_device(&pdev->dev); return ERR_PTR(-ENOMEM); } set_bit(map->xbar_out, xbar->dma_inuse); --- linux-oracle-5.4.0.orig/drivers/dma/ti/edma.c +++ linux-oracle-5.4.0/drivers/dma/ti/edma.c @@ -217,7 +217,6 @@ struct edma_cc; struct edma_tc { - struct device_node *node; u16 id; }; @@ -2361,7 +2360,7 @@ if (irq < 0 && node) irq = irq_of_parse_and_map(node, 0); - if (irq >= 0) { + if (irq > 0) { irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccint", dev_name(dev)); ret = devm_request_irq(dev, irq, dma_irq_handler, 0, irq_name, @@ -2377,7 +2376,7 @@ if (irq < 0 && node) irq = irq_of_parse_and_map(node, 2); - if (irq >= 0) { + if (irq > 0) { irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s_ccerrint", dev_name(dev)); ret = devm_request_irq(dev, irq, dma_ccerr_handler, 0, irq_name, @@ -2403,8 +2402,10 @@ ecc->tc_list = devm_kcalloc(dev, ecc->num_tc, sizeof(*ecc->tc_list), GFP_KERNEL); - if (!ecc->tc_list) - return -ENOMEM; + if (!ecc->tc_list) { + ret = -ENOMEM; + goto err_reg1; + } for (i = 0;; i++) { ret = of_parse_phandle_with_fixed_args(node, "ti,tptcs", @@ -2412,13 +2413,13 @@ if (ret || i == ecc->num_tc) break; - ecc->tc_list[i].node = tc_args.np; ecc->tc_list[i].id = i; queue_priority_mapping[i][1] = tc_args.args[0]; if (queue_priority_mapping[i][1] > lowest_priority) { lowest_priority = queue_priority_mapping[i][1]; info->default_queue = i; } + of_node_put(tc_args.np); } } --- linux-oracle-5.4.0.orig/drivers/dma/virt-dma.c +++ linux-oracle-5.4.0/drivers/dma/virt-dma.c @@ -104,9 +104,8 @@ dmaengine_desc_get_callback(&vd->tx, &cb); list_del(&vd->node); - vchan_vdesc_fini(vd); - dmaengine_desc_callback_invoke(&cb, &vd->tx_result); + vchan_vdesc_fini(vd); } } --- linux-oracle-5.4.0.orig/drivers/dma/xilinx/xilinx_dma.c +++ linux-oracle-5.4.0/drivers/dma/xilinx/xilinx_dma.c @@ -333,6 +333,7 @@ * @genlock: Support genlock mode * @err: Channel has errors * @idle: Check for channel idle + * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -370,6 +371,7 @@ bool genlock; bool err; bool idle; + bool terminating; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -454,8 +456,8 @@ #define to_dma_tx_descriptor(tx) \ container_of(tx, struct xilinx_dma_tx_descriptor, async_tx) #define xilinx_dma_poll_timeout(chan, reg, val, cond, delay_us, timeout_us) \ - readl_poll_timeout(chan->xdev->regs + chan->ctrl_offset + reg, val, \ - cond, delay_us, timeout_us) + readl_poll_timeout_atomic(chan->xdev->regs + chan->ctrl_offset + reg, \ + val, cond, delay_us, timeout_us) /* IO accessors */ static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg) @@ -844,6 +846,13 @@ /* Run any dependencies, then free the descriptor */ dma_run_dependencies(&desc->async_tx); xilinx_dma_free_tx_descriptor(chan, desc); + + /* + * While we ran a callback the user called a terminate function, + * which takes care of cleaning up any remaining descriptors + */ + if (chan->terminating) + break; } spin_unlock_irqrestore(&chan->lock, flags); @@ -1433,6 +1442,7 @@ chan->err = false; chan->idle = true; + chan->desc_pendingcount = 0; chan->desc_submitcount = 0; return err; @@ -1617,6 +1627,8 @@ if (desc->cyclic) chan->cyclic = true; + chan->terminating = false; + spin_unlock_irqrestore(&chan->lock, flags); return cookie; @@ -2073,6 +2085,7 @@ } /* Remove and free all of the descriptors in the lists */ + chan->terminating = true; xilinx_dma_free_descriptors(chan); chan->idle = true; @@ -2430,7 +2443,7 @@ has_dre = false; if (!has_dre) - xdev->common.copy_align = fls(width - 1); + xdev->common.copy_align = (enum dmaengine_alignment)fls(width - 1); if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || @@ -2542,7 +2555,8 @@ static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, struct device_node *node) { - int ret, i, nr_channels = 1; + int ret, i; + u32 nr_channels = 1; ret = of_property_read_u32(node, "dma-channels", &nr_channels); if ((ret < 0) && xdev->mcdma) @@ -2612,7 +2626,6 @@ struct device_node *node = pdev->dev.of_node; struct xilinx_dma_device *xdev; struct device_node *child, *np = pdev->dev.of_node; - struct resource *io; u32 num_frames, addr_width, len_width; int i, err; @@ -2638,11 +2651,11 @@ return err; /* Request and map I/O memory */ - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - xdev->regs = devm_ioremap_resource(&pdev->dev, io); - if (IS_ERR(xdev->regs)) - return PTR_ERR(xdev->regs); - + xdev->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(xdev->regs)) { + err = PTR_ERR(xdev->regs); + goto disable_clks; + } /* Retrieve the DMA engine properties from the device tree */ xdev->max_buffer_len = GENMASK(XILINX_DMA_MAX_TRANS_LEN_MAX - 1, 0); @@ -2669,7 +2682,7 @@ if (err < 0) { dev_err(xdev->dev, "missing xlnx,num-fstores property\n"); - return err; + goto disable_clks; } err = of_property_read_u32(node, "xlnx,flush-fsync", @@ -2689,7 +2702,11 @@ xdev->ext_addr = false; /* Set the dma mask bits */ - dma_set_mask(xdev->dev, DMA_BIT_MASK(addr_width)); + err = dma_set_mask_and_coherent(xdev->dev, DMA_BIT_MASK(addr_width)); + if (err < 0) { + dev_err(xdev->dev, "DMA mask error %d\n", err); + goto disable_clks; + } /* Initialize the DMA engine */ xdev->common.dev = &pdev->dev; @@ -2730,8 +2747,10 @@ /* Initialize the channels */ for_each_child_of_node(node, child) { err = xilinx_dma_child_probe(xdev, child); - if (err < 0) - goto disable_clks; + if (err < 0) { + of_node_put(child); + goto error; + } } if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { @@ -2741,7 +2760,11 @@ } /* Register the DMA engine with the core */ - dma_async_device_register(&xdev->common); + err = dma_async_device_register(&xdev->common); + if (err) { + dev_err(xdev->dev, "failed to register the dma device\n"); + goto error; + } err = of_dma_controller_register(node, of_dma_xilinx_xlate, xdev); @@ -2760,12 +2783,12 @@ return 0; -disable_clks: - xdma_disable_allclks(xdev); error: for (i = 0; i < xdev->nr_channels; i++) if (xdev->chan[i]) xilinx_dma_chan_remove(xdev->chan[i]); +disable_clks: + xdma_disable_allclks(xdev); return err; } --- linux-oracle-5.4.0.orig/drivers/dma/xilinx/zynqmp_dma.c +++ linux-oracle-5.4.0/drivers/dma/xilinx/zynqmp_dma.c @@ -123,10 +123,12 @@ /* Max transfer size per descriptor */ #define ZYNQMP_DMA_MAX_TRANS_LEN 0x40000000 +/* Max burst lengths */ +#define ZYNQMP_DMA_MAX_DST_BURST_LEN 32768U +#define ZYNQMP_DMA_MAX_SRC_BURST_LEN 32768U + /* Reset values for data attributes */ #define ZYNQMP_DMA_AXCACHE_VAL 0xF -#define ZYNQMP_DMA_ARLEN_RST_VAL 0xF -#define ZYNQMP_DMA_AWLEN_RST_VAL 0xF #define ZYNQMP_DMA_SRC_ISSUE_RST_VAL 0x1F @@ -230,7 +232,7 @@ bool is_dmacoherent; struct tasklet_struct tasklet; bool idle; - u32 desc_size; + size_t desc_size; bool err; u32 bus_width; u32 src_burst_len; @@ -465,7 +467,7 @@ struct zynqmp_dma_desc_sw *desc; int i, ret; - ret = pm_runtime_get_sync(chan->dev); + ret = pm_runtime_resume_and_get(chan->dev); if (ret < 0) return ret; @@ -487,7 +489,8 @@ } chan->desc_pool_v = dma_alloc_coherent(chan->dev, - (2 * chan->desc_size * ZYNQMP_DMA_NUM_DESCS), + (2 * ZYNQMP_DMA_DESC_SIZE(chan) * + ZYNQMP_DMA_NUM_DESCS), &chan->desc_pool_p, GFP_KERNEL); if (!chan->desc_pool_v) return -ENOMEM; @@ -534,17 +537,19 @@ static void zynqmp_dma_config(struct zynqmp_dma_chan *chan) { - u32 val; + u32 val, burst_val; val = readl(chan->regs + ZYNQMP_DMA_CTRL0); val |= ZYNQMP_DMA_POINT_TYPE_SG; writel(val, chan->regs + ZYNQMP_DMA_CTRL0); val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR); + burst_val = __ilog2_u32(chan->src_burst_len); val = (val & ~ZYNQMP_DMA_ARLEN) | - (chan->src_burst_len << ZYNQMP_DMA_ARLEN_OFST); + ((burst_val << ZYNQMP_DMA_ARLEN_OFST) & ZYNQMP_DMA_ARLEN); + burst_val = __ilog2_u32(chan->dst_burst_len); val = (val & ~ZYNQMP_DMA_AWLEN) | - (chan->dst_burst_len << ZYNQMP_DMA_AWLEN_OFST); + ((burst_val << ZYNQMP_DMA_AWLEN_OFST) & ZYNQMP_DMA_AWLEN); writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR); } @@ -560,8 +565,10 @@ { struct zynqmp_dma_chan *chan = to_chan(dchan); - chan->src_burst_len = config->src_maxburst; - chan->dst_burst_len = config->dst_maxburst; + chan->src_burst_len = clamp(config->src_maxburst, 1U, + ZYNQMP_DMA_MAX_SRC_BURST_LEN); + chan->dst_burst_len = clamp(config->dst_maxburst, 1U, + ZYNQMP_DMA_MAX_DST_BURST_LEN); return 0; } @@ -887,8 +894,8 @@ return PTR_ERR(chan->regs); chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64; - chan->dst_burst_len = ZYNQMP_DMA_AWLEN_RST_VAL; - chan->src_burst_len = ZYNQMP_DMA_ARLEN_RST_VAL; + chan->dst_burst_len = ZYNQMP_DMA_MAX_DST_BURST_LEN; + chan->src_burst_len = ZYNQMP_DMA_MAX_SRC_BURST_LEN; err = of_property_read_u32(node, "xlnx,bus-width", &chan->bus_width); if (err < 0) { dev_err(&pdev->dev, "missing xlnx,bus-width property\n"); --- linux-oracle-5.4.0.orig/drivers/edac/Makefile +++ linux-oracle-5.4.0/drivers/edac/Makefile @@ -57,11 +57,13 @@ layerscape_edac_mod-y := fsl_ddr_edac.o layerscape_edac.o obj-$(CONFIG_EDAC_LAYERSCAPE) += layerscape_edac_mod.o -skx_edac-y := skx_common.o skx_base.o -obj-$(CONFIG_EDAC_SKX) += skx_edac.o +skx_edac_common-y := skx_common.o -i10nm_edac-y := skx_common.o i10nm_base.o -obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o +skx_edac-y := skx_base.o +obj-$(CONFIG_EDAC_SKX) += skx_edac.o skx_edac_common.o + +i10nm_edac-y := i10nm_base.o +obj-$(CONFIG_EDAC_I10NM) += i10nm_edac.o skx_edac_common.o obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o obj-$(CONFIG_EDAC_CELL) += cell_edac.o --- linux-oracle-5.4.0.orig/drivers/edac/altera_edac.c +++ linux-oracle-5.4.0/drivers/edac/altera_edac.c @@ -349,7 +349,7 @@ if (irq < 0) { edac_printk(KERN_ERR, EDAC_MC, "No irq %d in DT\n", irq); - return -ENODEV; + return irq; } /* Arria10 has a 2nd IRQ */ @@ -560,6 +560,7 @@ .reg_write = s10_protected_reg_write, .use_single_read = true, .use_single_write = true, + .fast_io = true, }; /************** ***********/ --- linux-oracle-5.4.0.orig/drivers/edac/amd64_edac.c +++ linux-oracle-5.4.0/drivers/edac/amd64_edac.c @@ -22,6 +22,9 @@ /* Number of Unified Memory Controllers */ static u8 num_umcs; +/* Device for the PCI component */ +static struct device *pci_ctl_dev; + /* * Valid scrub rates for the K8 hardware memory scrubber. We map the scrubbing * bandwidth to a valid bit pattern. The 'set' operation finds the 'matching- @@ -215,7 +218,7 @@ scrubval = scrubrates[i].scrubval; - if (pvt->fam == 0x17 || pvt->fam == 0x18) { + if (pvt->umc) { __f17h_set_scrubval(pvt, scrubval); } else if (pvt->fam == 0x15 && pvt->model == 0x60) { f15h_select_dct(pvt, 0); @@ -257,18 +260,7 @@ int i, retval = -EINVAL; u32 scrubval = 0; - switch (pvt->fam) { - case 0x15: - /* Erratum #505 */ - if (pvt->model < 0x10) - f15h_select_dct(pvt, 0); - - if (pvt->model == 0x60) - amd64_read_pci_cfg(pvt->F2, F15H_M60H_SCRCTRL, &scrubval); - break; - - case 0x17: - case 0x18: + if (pvt->umc) { amd64_read_pci_cfg(pvt->F6, F17H_SCR_BASE_ADDR, &scrubval); if (scrubval & BIT(0)) { amd64_read_pci_cfg(pvt->F6, F17H_SCR_LIMIT_ADDR, &scrubval); @@ -277,11 +269,17 @@ } else { scrubval = 0; } - break; + } else if (pvt->fam == 0x15) { + /* Erratum #505 */ + if (pvt->model < 0x10) + f15h_select_dct(pvt, 0); - default: + if (pvt->model == 0x60) + amd64_read_pci_cfg(pvt->F2, F15H_M60H_SCRCTRL, &scrubval); + else + amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); + } else { amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); - break; } scrubval = scrubval & 0x001F; @@ -792,12 +790,14 @@ #define CS_ODD_PRIMARY BIT(1) #define CS_EVEN_SECONDARY BIT(2) #define CS_ODD_SECONDARY BIT(3) +#define CS_3R_INTERLEAVE BIT(4) #define CS_EVEN (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY) #define CS_ODD (CS_ODD_PRIMARY | CS_ODD_SECONDARY) static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt) { + u8 base, count = 0; int cs_mode = 0; if (csrow_enabled(2 * dimm, ctrl, pvt)) @@ -810,6 +810,20 @@ if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_SECONDARY; + /* + * 3 Rank inteleaving support. + * There should be only three bases enabled and their two masks should + * be equal. + */ + for_each_chip_select(base, ctrl, pvt) + count += csrow_enabled(base, ctrl, pvt); + + if (count == 3 && + pvt->csels[ctrl].csmasks[0] == pvt->csels[ctrl].csmasks[1]) { + edac_dbg(1, "3R interleaving in use.\n"); + cs_mode |= CS_3R_INTERLEAVE; + } + return cs_mode; } @@ -1056,6 +1070,16 @@ { u32 dram_ctrl, dcsm; + if (pvt->umc) { + if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5)) + pvt->dram_type = MEM_LRDDR4; + else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4)) + pvt->dram_type = MEM_RDDR4; + else + pvt->dram_type = MEM_DDR4; + return; + } + switch (pvt->fam) { case 0xf: if (pvt->ext_model >= K8_REV_F) @@ -1101,16 +1125,6 @@ case 0x16: goto ddr3; - case 0x17: - case 0x18: - if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5)) - pvt->dram_type = MEM_LRDDR4; - else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4)) - pvt->dram_type = MEM_RDDR4; - else - pvt->dram_type = MEM_DDR4; - return; - default: WARN(1, KERN_ERR "%s: Family??? 0x%x\n", __func__, pvt->fam); pvt->dram_type = MEM_EMPTY; @@ -1618,10 +1632,14 @@ * * The MSB is the number of bits in the full mask because BIT[0] is * always 0. + * + * In the special 3 Rank interleaving case, a single bit is flipped + * without swapping with the most significant bit. This can be handled + * by keeping the MSB where it is and ignoring the single zero bit. */ msb = fls(addr_mask_orig) - 1; weight = hweight_long(addr_mask_orig); - num_zero_bits = msb - weight; + num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE); /* Take the number of zero bits off from the top of the mask. */ addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1); @@ -2317,6 +2335,15 @@ .dbam_to_cs = f17_addr_mask_to_cs_size, } }, + [F17_M60H_CPUS] = { + .ctl_name = "F17h_M60h", + .f0_id = PCI_DEVICE_ID_AMD_17H_M60H_DF_F0, + .f6_id = PCI_DEVICE_ID_AMD_17H_M60H_DF_F6, + .ops = { + .early_channel_count = f17_early_channel_count, + .dbam_to_cs = f17_addr_mask_to_cs_size, + } + }, [F17_M70H_CPUS] = { .ctl_name = "F17h_M70h", .f0_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F0, @@ -2326,6 +2353,15 @@ .dbam_to_cs = f17_addr_mask_to_cs_size, } }, + [F19_CPUS] = { + .ctl_name = "F19h", + .f0_id = PCI_DEVICE_ID_AMD_19H_DF_F0, + .f6_id = PCI_DEVICE_ID_AMD_19H_DF_F6, + .ops = { + .early_channel_count = f17_early_channel_count, + .dbam_to_cs = f17_addr_mask_to_cs_size, + } + }, }; /* @@ -2661,6 +2697,9 @@ return -ENODEV; } + if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F0->dev; + edac_dbg(1, "F0: %s\n", pci_name(pvt->F0)); edac_dbg(1, "F3: %s\n", pci_name(pvt->F3)); edac_dbg(1, "F6: %s\n", pci_name(pvt->F6)); @@ -2685,6 +2724,9 @@ return -ENODEV; } + if (!pci_ctl_dev) + pci_ctl_dev = &pvt->F2->dev; + edac_dbg(1, "F1: %s\n", pci_name(pvt->F1)); edac_dbg(1, "F2: %s\n", pci_name(pvt->F2)); edac_dbg(1, "F3: %s\n", pci_name(pvt->F3)); @@ -2936,6 +2978,7 @@ dimm->mtype = pvt->dram_type; dimm->edac_mode = edac_mode; dimm->dtype = dev_type; + dimm->grain = 64; } } @@ -3012,6 +3055,7 @@ dimm = csrow->channels[j]->dimm; dimm->mtype = pvt->dram_type; dimm->edac_mode = edac_mode; + dimm->grain = 64; } } @@ -3364,6 +3408,10 @@ fam_type = &family_types[F17_M30H_CPUS]; pvt->ops = &family_types[F17_M30H_CPUS].ops; break; + } else if (pvt->model >= 0x60 && pvt->model <= 0x6f) { + fam_type = &family_types[F17_M60H_CPUS]; + pvt->ops = &family_types[F17_M60H_CPUS].ops; + break; } else if (pvt->model >= 0x70 && pvt->model <= 0x7f) { fam_type = &family_types[F17_M70H_CPUS]; pvt->ops = &family_types[F17_M70H_CPUS].ops; @@ -3378,6 +3426,12 @@ family_types[F17_CPUS].ctl_name = "F18h"; break; + case 0x19: + fam_type = &family_types[F19_CPUS]; + pvt->ops = &family_types[F19_CPUS].ops; + family_types[F19_CPUS].ctl_name = "F19h"; + break; + default: amd64_err("Unsupported family!\n"); return NULL; @@ -3609,21 +3663,10 @@ static void setup_pci_device(void) { - struct mem_ctl_info *mci; - struct amd64_pvt *pvt; - if (pci_ctl) return; - mci = edac_mc_find(0); - if (!mci) - return; - - pvt = mci->pvt_info; - if (pvt->umc) - pci_ctl = edac_pci_create_generic_ctl(&pvt->F0->dev, EDAC_MOD_STR); - else - pci_ctl = edac_pci_create_generic_ctl(&pvt->F2->dev, EDAC_MOD_STR); + pci_ctl = edac_pci_create_generic_ctl(pci_ctl_dev, EDAC_MOD_STR); if (!pci_ctl) { pr_warn("%s(): Unable to create PCI control\n", __func__); pr_warn("%s(): PCI error report via EDAC not set\n", __func__); @@ -3637,6 +3680,7 @@ { X86_VENDOR_AMD, 0x16, X86_MODEL_ANY, X86_FEATURE_ANY, 0 }, { X86_VENDOR_AMD, 0x17, X86_MODEL_ANY, X86_FEATURE_ANY, 0 }, { X86_VENDOR_HYGON, 0x18, X86_MODEL_ANY, X86_FEATURE_ANY, 0 }, + { X86_VENDOR_AMD, 0x19, X86_MODEL_ANY, X86_FEATURE_ANY, 0 }, { } }; MODULE_DEVICE_TABLE(x86cpu, amd64_cpuids); @@ -3706,6 +3750,8 @@ return 0; err_pci: + pci_ctl_dev = NULL; + msrs_free(msrs); msrs = NULL; @@ -3737,6 +3783,8 @@ kfree(ecc_stngs); ecc_stngs = NULL; + pci_ctl_dev = NULL; + msrs_free(msrs); msrs = NULL; } --- linux-oracle-5.4.0.orig/drivers/edac/amd64_edac.h +++ linux-oracle-5.4.0/drivers/edac/amd64_edac.h @@ -120,8 +120,12 @@ #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F6 0x15ee #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F0 0x1490 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F6 0x1496 +#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F0 0x1448 +#define PCI_DEVICE_ID_AMD_17H_M60H_DF_F6 0x144e #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F0 0x1440 #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F6 0x1446 +#define PCI_DEVICE_ID_AMD_19H_DF_F0 0x1650 +#define PCI_DEVICE_ID_AMD_19H_DF_F6 0x1656 /* * Function 1 - Address Map @@ -291,7 +295,9 @@ F17_CPUS, F17_M10H_CPUS, F17_M30H_CPUS, + F17_M60H_CPUS, F17_M70H_CPUS, + F19_CPUS, NUM_FAMILIES, }; --- linux-oracle-5.4.0.orig/drivers/edac/armada_xp_edac.c +++ linux-oracle-5.4.0/drivers/edac/armada_xp_edac.c @@ -178,7 +178,7 @@ "details unavailable (multiple errors)"); if (cnt_dbe) edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, - cnt_sbe, /* error count */ + cnt_dbe, /* error count */ 0, 0, 0, /* pfn, offset, syndrome */ -1, -1, -1, /* top, mid, low layer */ mci->ctl_name, --- linux-oracle-5.4.0.orig/drivers/edac/aspeed_edac.c +++ linux-oracle-5.4.0/drivers/edac/aspeed_edac.c @@ -209,8 +209,8 @@ /* register interrupt handler */ irq = platform_get_irq(pdev, 0); dev_dbg(&pdev->dev, "got irq %d\n", irq); - if (!irq) - return -ENODEV; + if (irq < 0) + return irq; rc = devm_request_irq(&pdev->dev, irq, mcr_isr, IRQF_TRIGGER_HIGH, DRV_NAME, ctx); --- linux-oracle-5.4.0.orig/drivers/edac/bluefield_edac.c +++ linux-oracle-5.4.0/drivers/edac/bluefield_edac.c @@ -180,7 +180,7 @@ static void bluefield_edac_init_dimms(struct mem_ctl_info *mci) { struct bluefield_edac_priv *priv = mci->pvt_info; - int mem_ctrl_idx = mci->mc_idx; + u64 mem_ctrl_idx = mci->mc_idx; struct dimm_info *dimm; u64 smc_info, smc_arg; int is_empty = 1, i; --- linux-oracle-5.4.0.orig/drivers/edac/edac_device.c +++ linux-oracle-5.4.0/drivers/edac/edac_device.c @@ -34,6 +34,9 @@ static DEFINE_MUTEX(device_ctls_mutex); static LIST_HEAD(edac_device_list); +/* Default workqueue processing interval on this instance, in msecs */ +#define DEFAULT_POLL_INTERVAL 1000 + #ifdef CONFIG_EDAC_DEBUG static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev) { @@ -366,7 +369,7 @@ * whole one second to save timers firing all over the period * between integral seconds */ - if (edac_dev->poll_msec == 1000) + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); else edac_queue_work(&edac_dev->work, edac_dev->delay); @@ -396,7 +399,7 @@ * timers firing on sub-second basis, while they are happy * to fire together on the 1 second exactly */ - if (edac_dev->poll_msec == 1000) + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) edac_queue_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); else edac_queue_work(&edac_dev->work, edac_dev->delay); @@ -424,17 +427,16 @@ * Then restart the workq on the new delay */ void edac_device_reset_delay_period(struct edac_device_ctl_info *edac_dev, - unsigned long value) + unsigned long msec) { - unsigned long jiffs = msecs_to_jiffies(value); - - if (value == 1000) - jiffs = round_jiffies_relative(value); - - edac_dev->poll_msec = value; - edac_dev->delay = jiffs; + edac_dev->poll_msec = msec; + edac_dev->delay = msecs_to_jiffies(msec); - edac_mod_work(&edac_dev->work, jiffs); + /* See comment in edac_device_workq_setup() above */ + if (edac_dev->poll_msec == DEFAULT_POLL_INTERVAL) + edac_mod_work(&edac_dev->work, round_jiffies_relative(edac_dev->delay)); + else + edac_mod_work(&edac_dev->work, edac_dev->delay); } int edac_device_alloc_index(void) @@ -473,11 +475,7 @@ /* This instance is NOW RUNNING */ edac_dev->op_state = OP_RUNNING_POLL; - /* - * enable workq processing on this instance, - * default = 1000 msec - */ - edac_device_workq_setup(edac_dev, 1000); + edac_device_workq_setup(edac_dev, edac_dev->poll_msec ?: DEFAULT_POLL_INTERVAL); } else { edac_dev->op_state = OP_RUNNING_INTERRUPT; } --- linux-oracle-5.4.0.orig/drivers/edac/edac_device_sysfs.c +++ linux-oracle-5.4.0/drivers/edac/edac_device_sysfs.c @@ -275,6 +275,7 @@ /* Error exit stack */ err_kobj_reg: + kobject_put(&edac_dev->kobj); module_put(edac_dev->owner); err_out: --- linux-oracle-5.4.0.orig/drivers/edac/edac_mc.c +++ linux-oracle-5.4.0/drivers/edac/edac_mc.c @@ -263,7 +263,7 @@ else return (char *)ptr; - r = (unsigned long)p % align; + r = (unsigned long)ptr % align; if (r == 0) return (char *)ptr; @@ -503,16 +503,10 @@ { edac_dbg(1, "\n"); - /* If we're not yet registered with sysfs free only what was allocated - * in edac_mc_alloc(). - */ - if (!device_is_registered(&mci->dev)) { - _edac_mc_free(mci); - return; - } + if (device_is_registered(&mci->dev)) + edac_unregister_sysfs(mci); - /* the mci instance is freed here, when the sysfs object is dropped */ - edac_unregister_sysfs(mci); + _edac_mc_free(mci); } EXPORT_SYMBOL_GPL(edac_mc_free); --- linux-oracle-5.4.0.orig/drivers/edac/edac_mc_sysfs.c +++ linux-oracle-5.4.0/drivers/edac/edac_mc_sysfs.c @@ -276,10 +276,7 @@ static void csrow_attr_release(struct device *dev) { - struct csrow_info *csrow = container_of(dev, struct csrow_info, dev); - - edac_dbg(1, "device %s released\n", dev_name(dev)); - kfree(csrow); + /* release device with _edac_mc_free() */ } static const struct device_type csrow_attr_type = { @@ -447,8 +444,7 @@ csrow = mci->csrows[i]; if (!nr_pages_per_csrow(csrow)) continue; - - device_del(&mci->csrows[i]->dev); + device_unregister(&mci->csrows[i]->dev); } return err; @@ -620,10 +616,7 @@ static void dimm_attr_release(struct device *dev) { - struct dimm_info *dimm = container_of(dev, struct dimm_info, dev); - - edac_dbg(1, "device %s released\n", dev_name(dev)); - kfree(dimm); + /* release device with _edac_mc_free() */ } static const struct device_type dimm_attr_type = { @@ -906,10 +899,7 @@ static void mci_attr_release(struct device *dev) { - struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev); - - edac_dbg(1, "device %s released\n", dev_name(dev)); - kfree(mci); + /* release device with _edac_mc_free() */ } static const struct device_type mci_attr_type = { --- linux-oracle-5.4.0.orig/drivers/edac/edac_module.h +++ linux-oracle-5.4.0/drivers/edac/edac_module.h @@ -57,7 +57,7 @@ bool edac_mod_work(struct delayed_work *work, unsigned long delay); extern void edac_device_reset_delay_period(struct edac_device_ctl_info - *edac_dev, unsigned long value); + *edac_dev, unsigned long msec); extern void edac_mc_reset_delay_period(unsigned long value); extern void *edac_align_ptr(void **p, unsigned size, int n_elems); --- linux-oracle-5.4.0.orig/drivers/edac/edac_pci_sysfs.c +++ linux-oracle-5.4.0/drivers/edac/edac_pci_sysfs.c @@ -386,7 +386,7 @@ /* Error unwind statck */ kobject_init_and_add_fail: - kfree(edac_pci_top_main_kobj); + kobject_put(edac_pci_top_main_kobj); kzalloc_fail: module_put(THIS_MODULE); --- linux-oracle-5.4.0.orig/drivers/edac/fsl_ddr_edac.c +++ linux-oracle-5.4.0/drivers/edac/fsl_ddr_edac.c @@ -331,21 +331,25 @@ * TODO: Add support for 32-bit wide buses */ if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) { + u64 cap = (u64)cap_high << 32 | cap_low; + u32 s = syndrome; + sbe_ecc_decode(cap_high, cap_low, syndrome, &bad_data_bit, &bad_ecc_bit); - if (bad_data_bit != -1) - fsl_mc_printk(mci, KERN_ERR, - "Faulty Data bit: %d\n", bad_data_bit); - if (bad_ecc_bit != -1) - fsl_mc_printk(mci, KERN_ERR, - "Faulty ECC bit: %d\n", bad_ecc_bit); + if (bad_data_bit >= 0) { + fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit); + cap ^= 1ULL << bad_data_bit; + } + + if (bad_ecc_bit >= 0) { + fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit); + s ^= 1 << bad_ecc_bit; + } fsl_mc_printk(mci, KERN_ERR, "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n", - cap_high ^ (1 << (bad_data_bit - 32)), - cap_low ^ (1 << bad_data_bit), - syndrome ^ (1 << bad_ecc_bit)); + upper_32_bits(cap), lower_32_bits(cap), s); } fsl_mc_printk(mci, KERN_ERR, --- linux-oracle-5.4.0.orig/drivers/edac/ghes_edac.c +++ linux-oracle-5.4.0/drivers/edac/ghes_edac.c @@ -26,9 +26,18 @@ char msg[80]; }; -static atomic_t ghes_init = ATOMIC_INIT(0); +static refcount_t ghes_refcount = REFCOUNT_INIT(0); + +/* + * Access to ghes_pvt must be protected by ghes_lock. The spinlock + * also provides the necessary (implicit) memory barrier for the SMP + * case to make the pointer visible on another CPU. + */ static struct ghes_edac_pvt *ghes_pvt; +/* GHES registration mutex */ +static DEFINE_MUTEX(ghes_reg_mutex); + /* * Sync with other, potentially concurrent callers of * ghes_edac_report_mem_error(). We don't know what the @@ -79,9 +88,8 @@ (*num_dimm)++; } -static int get_dimm_smbios_index(u16 handle) +static int get_dimm_smbios_index(struct mem_ctl_info *mci, u16 handle) { - struct mem_ctl_info *mci = ghes_pvt->mci; int i; for (i = 0; i < mci->tot_dimms; i++) { @@ -198,14 +206,11 @@ enum hw_event_mc_err_type type; struct edac_raw_error_desc *e; struct mem_ctl_info *mci; - struct ghes_edac_pvt *pvt = ghes_pvt; + struct ghes_edac_pvt *pvt; unsigned long flags; char *p; u8 grain_bits; - if (!pvt) - return; - /* * We can do the locking below because GHES defers error processing * from NMI to IRQ context. Whenever that changes, we'd at least @@ -216,12 +221,17 @@ spin_lock_irqsave(&ghes_lock, flags); + pvt = ghes_pvt; + if (!pvt) + goto unlock; + mci = pvt->mci; e = &mci->error_desc; /* Cleans the error report buffer */ memset(e, 0, sizeof (*e)); e->error_count = 1; + e->grain = 1; strcpy(e->label, "unknown label"); e->msg = pvt->msg; e->other_detail = pvt->other_detail; @@ -317,7 +327,7 @@ /* Error grain */ if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK) - e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK); + e->grain = ~mem_err->physical_addr_mask + 1; /* Memory error location, mapped on e->location */ p = e->location; @@ -348,7 +358,7 @@ p += sprintf(p, "DIMM DMI handle: 0x%.4x ", mem_err->mem_dev_handle); - index = get_dimm_smbios_index(mem_err->mem_dev_handle); + index = get_dimm_smbios_index(mci, mem_err->mem_dev_handle); if (index >= 0) { e->top_layer = index; e->enable_per_layer_report = true; @@ -433,8 +443,13 @@ if (p > pvt->other_detail) *(p - 1) = '\0'; + /* Sanity-check driver-supplied grain value. */ + if (WARN_ON_ONCE(!e->grain)) + e->grain = 1; + + grain_bits = fls_long(e->grain - 1); + /* Generate the trace event */ - grain_bits = fls_long(e->grain); snprintf(pvt->detail_location, sizeof(pvt->detail_location), "APEI location: %s %s", e->location, e->other_detail); trace_mc_event(type, e->msg, e->label, e->error_count, @@ -443,6 +458,8 @@ grain_bits, e->syndrome, pvt->detail_location); edac_raw_mc_handle_error(type, mci, e); + +unlock: spin_unlock_irqrestore(&ghes_lock, flags); } @@ -457,10 +474,12 @@ int ghes_edac_register(struct ghes *ghes, struct device *dev) { bool fake = false; - int rc, num_dimm = 0; + int rc = 0, num_dimm = 0; struct mem_ctl_info *mci; + struct ghes_edac_pvt *pvt; struct edac_mc_layer layers[1]; struct ghes_edac_dimm_fill dimm_fill; + unsigned long flags; int idx = -1; if (IS_ENABLED(CONFIG_X86)) { @@ -469,14 +488,18 @@ if (!force_load && idx < 0) return -ENODEV; } else { + force_load = true; idx = 0; } + /* finish another registration/unregistration instance first */ + mutex_lock(&ghes_reg_mutex); + /* * We have only one logical memory controller to which all DIMMs belong. */ - if (atomic_inc_return(&ghes_init) > 1) - return 0; + if (refcount_inc_not_zero(&ghes_refcount)) + goto unlock; /* Get the number of DIMMs */ dmi_walk(ghes_edac_count_dimms, &num_dimm); @@ -494,12 +517,13 @@ mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(struct ghes_edac_pvt)); if (!mci) { pr_info("Can't allocate memory for EDAC data\n"); - return -ENOMEM; + rc = -ENOMEM; + goto unlock; } - ghes_pvt = mci->pvt_info; - ghes_pvt->ghes = ghes; - ghes_pvt->mci = mci; + pvt = mci->pvt_info; + pvt->ghes = ghes; + pvt->mci = mci; mci->pdev = dev; mci->mtype_cap = MEM_FLAG_EMPTY; @@ -541,23 +565,51 @@ if (rc < 0) { pr_info("Can't register at EDAC core\n"); edac_mc_free(mci); - return -ENODEV; + rc = -ENODEV; + goto unlock; } - return 0; + + spin_lock_irqsave(&ghes_lock, flags); + ghes_pvt = pvt; + spin_unlock_irqrestore(&ghes_lock, flags); + + /* only set on success */ + refcount_set(&ghes_refcount, 1); + +unlock: + mutex_unlock(&ghes_reg_mutex); + + return rc; } void ghes_edac_unregister(struct ghes *ghes) { struct mem_ctl_info *mci; + unsigned long flags; - if (!ghes_pvt) + if (!force_load) return; - if (atomic_dec_return(&ghes_init)) - return; + mutex_lock(&ghes_reg_mutex); - mci = ghes_pvt->mci; + if (!refcount_dec_and_test(&ghes_refcount)) + goto unlock; + + /* + * Wait for the irq handler being finished. + */ + spin_lock_irqsave(&ghes_lock, flags); + mci = ghes_pvt ? ghes_pvt->mci : NULL; ghes_pvt = NULL; - edac_mc_del_mc(mci->pdev); - edac_mc_free(mci); + spin_unlock_irqrestore(&ghes_lock, flags); + + if (!mci) + goto unlock; + + mci = edac_mc_del_mc(mci->pdev); + if (mci) + edac_mc_free(mci); + +unlock: + mutex_unlock(&ghes_reg_mutex); } --- linux-oracle-5.4.0.orig/drivers/edac/highbank_mc_edac.c +++ linux-oracle-5.4.0/drivers/edac/highbank_mc_edac.c @@ -174,8 +174,10 @@ drvdata = mci->pvt_info; platform_set_drvdata(pdev, mci); - if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) - return -ENOMEM; + if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL)) { + res = -ENOMEM; + goto free; + } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { @@ -243,6 +245,7 @@ edac_mc_del_mc(&pdev->dev); err: devres_release_group(&pdev->dev, NULL); +free: edac_mc_free(mci); return res; } --- linux-oracle-5.4.0.orig/drivers/edac/i10nm_base.c +++ linux-oracle-5.4.0/drivers/edac/i10nm_base.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -19,14 +20,16 @@ #define i10nm_printk(level, fmt, arg...) \ edac_printk(level, "i10nm", fmt, ##arg) -#define I10NM_GET_SCK_BAR(d, reg) \ +#define I10NM_GET_SCK_BAR(d, reg) \ pci_read_config_dword((d)->uracu, 0xd0, &(reg)) #define I10NM_GET_IMC_BAR(d, i, reg) \ pci_read_config_dword((d)->uracu, 0xd8 + (i) * 4, &(reg)) #define I10NM_GET_DIMMMTR(m, i, j) \ - (*(u32 *)((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4)) -#define I10NM_GET_MCDDRTCFG(m, i, j) \ - (*(u32 *)((m)->mbase + 0x20970 + (i) * 0x4000 + (j) * 4)) + readl((m)->mbase + 0x2080c + (i) * 0x4000 + (j) * 4) +#define I10NM_GET_MCDDRTCFG(m, i) \ + readl((m)->mbase + 0x20970 + (i) * 0x4000) +#define I10NM_GET_MCMTR(m, i) \ + readl((m)->mbase + 0x20ef8 + (i) * 0x4000) #define I10NM_GET_SCK_MMIO_BASE(reg) (GET_BITFIELD(reg, 0, 28) << 23) #define I10NM_GET_IMC_MMIO_OFFSET(reg) (GET_BITFIELD(reg, 0, 10) << 12) @@ -50,11 +53,10 @@ if (unlikely(pci_enable_device(pdev) < 0)) { edac_dbg(2, "Failed to enable device %02x:%02x.%x\n", bus, dev, fun); + pci_dev_put(pdev); return NULL; } - pci_dev_get(pdev); - return pdev; } @@ -134,7 +136,7 @@ { u32 mcmtr; - mcmtr = *(u32 *)(imc->mbase + 0x20ef8 + chan * 0x4000); + mcmtr = I10NM_GET_MCMTR(imc, chan); edac_dbg(1, "ch%d mcmtr reg %x\n", chan, mcmtr); return !!GET_BITFIELD(mcmtr, 2, 2); @@ -153,16 +155,16 @@ continue; ndimms = 0; + mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i); for (j = 0; j < I10NM_NUM_DIMMS; j++) { dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, mci->n_layers, i, j, 0); mtr = I10NM_GET_DIMMMTR(imc, i, j); - mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i, j); edac_dbg(1, "dimmmtr 0x%x mcddrtcfg 0x%x (mc%d ch%d dimm%d)\n", mtr, mcddrtcfg, imc->mc, i, j); if (IS_DIMM_PRESENT(mtr)) - ndimms += skx_get_dimm_info(mtr, 0, dimm, + ndimms += skx_get_dimm_info(mtr, 0, 0, dimm, imc, i, j); else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) ndimms += skx_get_nvdimm_info(dimm, imc, i, j, @@ -246,6 +248,9 @@ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(i10nm_cpuids); if (!id) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/edac/i5100_edac.c +++ linux-oracle-5.4.0/drivers/edac/i5100_edac.c @@ -1074,16 +1074,15 @@ PCI_DEVICE_ID_INTEL_5100_19, 0); if (!einj) { ret = -ENODEV; - goto bail_einj; + goto bail_mc_free; } rc = pci_enable_device(einj); if (rc < 0) { ret = rc; - goto bail_disable_einj; + goto bail_einj; } - mci->pdev = &pdev->dev; priv = mci->pvt_info; @@ -1149,14 +1148,14 @@ bail_scrub: priv->scrub_enable = 0; cancel_delayed_work_sync(&(priv->i5100_scrubbing)); - edac_mc_free(mci); - -bail_disable_einj: pci_disable_device(einj); bail_einj: pci_dev_put(einj); +bail_mc_free: + edac_mc_free(mci); + bail_disable_ch1: pci_disable_device(ch1mm); --- linux-oracle-5.4.0.orig/drivers/edac/i7core_edac.c +++ linux-oracle-5.4.0/drivers/edac/i7core_edac.c @@ -1711,9 +1711,9 @@ if (uncorrected_error) { core_err_cnt = 1; if (ripv) - tp_event = HW_EVENT_ERR_FATAL; - else tp_event = HW_EVENT_ERR_UNCORRECTED; + else + tp_event = HW_EVENT_ERR_FATAL; } else { tp_event = HW_EVENT_ERR_CORRECTED; } --- linux-oracle-5.4.0.orig/drivers/edac/ie31200_edac.c +++ linux-oracle-5.4.0/drivers/edac/ie31200_edac.c @@ -170,6 +170,8 @@ (n << (28 + (2 * skl) - PAGE_SHIFT)) static int nr_channels; +static struct pci_dev *mci_pdev; +static int ie31200_registered = 1; struct ie31200_priv { void __iomem *window; @@ -541,12 +543,16 @@ static int ie31200_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - edac_dbg(0, "MC:\n"); + int rc; + edac_dbg(0, "MC:\n"); if (pci_enable_device(pdev) < 0) return -EIO; + rc = ie31200_probe1(pdev, ent->driver_data); + if (rc == 0 && !mci_pdev) + mci_pdev = pci_dev_get(pdev); - return ie31200_probe1(pdev, ent->driver_data); + return rc; } static void ie31200_remove_one(struct pci_dev *pdev) @@ -555,6 +561,8 @@ struct ie31200_priv *priv; edac_dbg(0, "\n"); + pci_dev_put(mci_pdev); + mci_pdev = NULL; mci = edac_mc_del_mc(&pdev->dev); if (!mci) return; @@ -596,17 +604,53 @@ static int __init ie31200_init(void) { + int pci_rc, i; + edac_dbg(3, "MC:\n"); /* Ensure that the OPSTATE is set correctly for POLL or NMI */ opstate_init(); - return pci_register_driver(&ie31200_driver); + pci_rc = pci_register_driver(&ie31200_driver); + if (pci_rc < 0) + goto fail0; + + if (!mci_pdev) { + ie31200_registered = 0; + for (i = 0; ie31200_pci_tbl[i].vendor != 0; i++) { + mci_pdev = pci_get_device(ie31200_pci_tbl[i].vendor, + ie31200_pci_tbl[i].device, + NULL); + if (mci_pdev) + break; + } + if (!mci_pdev) { + edac_dbg(0, "ie31200 pci_get_device fail\n"); + pci_rc = -ENODEV; + goto fail1; + } + pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]); + if (pci_rc < 0) { + edac_dbg(0, "ie31200 init fail\n"); + pci_rc = -ENODEV; + goto fail1; + } + } + return 0; + +fail1: + pci_unregister_driver(&ie31200_driver); +fail0: + pci_dev_put(mci_pdev); + + return pci_rc; } static void __exit ie31200_exit(void) { edac_dbg(3, "MC:\n"); pci_unregister_driver(&ie31200_driver); + if (!ie31200_registered) + ie31200_remove_one(mci_pdev); } module_init(ie31200_init); --- linux-oracle-5.4.0.orig/drivers/edac/mce_amd.c +++ linux-oracle-5.4.0/drivers/edac/mce_amd.c @@ -175,6 +175,33 @@ "L2 Fill Data error", }; +static const char * const smca_ls2_mce_desc[] = { + "An ECC error was detected on a data cache read by a probe or victimization", + "An ECC error or L2 poison was detected on a data cache read by a load", + "An ECC error was detected on a data cache read-modify-write by a store", + "An ECC error or poison bit mismatch was detected on a tag read by a probe or victimization", + "An ECC error or poison bit mismatch was detected on a tag read by a load", + "An ECC error or poison bit mismatch was detected on a tag read by a store", + "An ECC error was detected on an EMEM read by a load", + "An ECC error was detected on an EMEM read-modify-write by a store", + "A parity error was detected in an L1 TLB entry by any access", + "A parity error was detected in an L2 TLB entry by any access", + "A parity error was detected in a PWC entry by any access", + "A parity error was detected in an STQ entry by any access", + "A parity error was detected in an LDQ entry by any access", + "A parity error was detected in a MAB entry by any access", + "A parity error was detected in an SCB entry state field by any access", + "A parity error was detected in an SCB entry address field by any access", + "A parity error was detected in an SCB entry data field by any access", + "A parity error was detected in a WCB entry by any access", + "A poisoned line was detected in an SCB entry by any access", + "A SystemReadDataError error was reported on read data returned from L2 for a load", + "A SystemReadDataError error was reported on read data returned from L2 for an SCB store", + "A SystemReadDataError error was reported on read data returned from L2 for a WCB store", + "A hardware assertion error was reported", + "A parity error was detected in an STLF, SCB EMEM entry or SRB store data by any access", +}; + static const char * const smca_if_mce_desc[] = { "Op Cache Microtag Probe Port Parity Error", "IC Microtag or Full Tag Multi-hit Error", @@ -378,6 +405,7 @@ static struct smca_mce_desc smca_mce_descs[] = { [SMCA_LS] = { smca_ls_mce_desc, ARRAY_SIZE(smca_ls_mce_desc) }, + [SMCA_LS_V2] = { smca_ls2_mce_desc, ARRAY_SIZE(smca_ls2_mce_desc) }, [SMCA_IF] = { smca_if_mce_desc, ARRAY_SIZE(smca_if_mce_desc) }, [SMCA_L2_CACHE] = { smca_l2_mce_desc, ARRAY_SIZE(smca_l2_mce_desc) }, [SMCA_DE] = { smca_de_mce_desc, ARRAY_SIZE(smca_de_mce_desc) }, @@ -975,7 +1003,7 @@ } if (bank_type == SMCA_UMC && xec == 0 && decode_dram_ecc) - decode_dram_ecc(cpu_to_node(m->extcpu), m); + decode_dram_ecc(topology_die_id(m->extcpu), m); } static inline void amd_decode_err_code(u16 ec) @@ -1161,6 +1189,11 @@ if (!fam_ops) return -ENOMEM; + if (boot_cpu_has(X86_FEATURE_SMCA)) { + xec_mask = 0x3f; + goto out; + } + switch (c->x86) { case 0xf: fam_ops->mc0_mce = k8_mc0_mce; @@ -1209,11 +1242,8 @@ case 0x17: case 0x18: - xec_mask = 0x3f; - if (!boot_cpu_has(X86_FEATURE_SMCA)) { - printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n"); - goto err_out; - } + pr_warn("Decoding supported only on Scalable MCA processors.\n"); + goto err_out; break; default: @@ -1221,6 +1251,7 @@ goto err_out; } +out: pr_info("MCE: In-kernel MCE decoding enabled.\n"); mce_register_decode_chain(&amd_mce_dec_nb); --- linux-oracle-5.4.0.orig/drivers/edac/pnd2_edac.c +++ linux-oracle-5.4.0/drivers/edac/pnd2_edac.c @@ -1155,7 +1155,7 @@ u32 optypenum = GET_BITFIELD(m->status, 4, 6); int rc; - tp_event = uc_err ? (ripv ? HW_EVENT_ERR_FATAL : HW_EVENT_ERR_UNCORRECTED) : + tp_event = uc_err ? (ripv ? HW_EVENT_ERR_UNCORRECTED : HW_EVENT_ERR_FATAL) : HW_EVENT_ERR_CORRECTED; /* @@ -1555,6 +1555,9 @@ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(pnd2_cpuids); if (!id) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/edac/qcom_edac.c +++ linux-oracle-5.4.0/drivers/edac/qcom_edac.c @@ -252,7 +252,7 @@ static int dump_syn_reg(struct edac_device_ctl_info *edev_ctl, int err_type, u32 bank) { - struct llcc_drv_data *drv = edev_ctl->pvt_info; + struct llcc_drv_data *drv = edev_ctl->dev->platform_data; int ret; ret = dump_syn_reg_values(drv, bank, err_type); @@ -289,7 +289,7 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl) { struct edac_device_ctl_info *edac_dev_ctl = edev_ctl; - struct llcc_drv_data *drv = edac_dev_ctl->pvt_info; + struct llcc_drv_data *drv = edac_dev_ctl->dev->platform_data; irqreturn_t irq_rc = IRQ_NONE; u32 drp_error, trp_error, i; int ret; @@ -358,7 +358,6 @@ edev_ctl->dev_name = dev_name(dev); edev_ctl->ctl_name = "llcc"; edev_ctl->panic_on_ue = LLCC_ERP_PANIC_ON_UE; - edev_ctl->pvt_info = llcc_driv_data; rc = edac_device_add_device(edev_ctl); if (rc) --- linux-oracle-5.4.0.orig/drivers/edac/sb_edac.c +++ linux-oracle-5.4.0/drivers/edac/sb_edac.c @@ -254,18 +254,20 @@ * FIXME: Implement the error count reads directly */ -static const u32 correrrcnt[] = { - 0x104, 0x108, 0x10c, 0x110, -}; - #define RANK_ODD_OV(reg) GET_BITFIELD(reg, 31, 31) #define RANK_ODD_ERR_CNT(reg) GET_BITFIELD(reg, 16, 30) #define RANK_EVEN_OV(reg) GET_BITFIELD(reg, 15, 15) #define RANK_EVEN_ERR_CNT(reg) GET_BITFIELD(reg, 0, 14) +#if 0 /* Currently unused*/ +static const u32 correrrcnt[] = { + 0x104, 0x108, 0x10c, 0x110, +}; + static const u32 correrrthrsld[] = { 0x11c, 0x120, 0x124, 0x128, }; +#endif #define RANK_ODD_ERR_THRSLD(reg) GET_BITFIELD(reg, 16, 30) #define RANK_EVEN_ERR_THRSLD(reg) GET_BITFIELD(reg, 0, 14) @@ -1053,7 +1055,7 @@ pci_read_config_dword(pvt->info.pci_vtd, HASWELL_TOHM_1, ®); rc = ((reg << 6) | rc) << 26; - return rc | 0x1ffffff; + return rc | 0x3ffffff; } static u64 knl_get_tolm(struct sbridge_pvt *pvt) @@ -1340,7 +1342,7 @@ */ static int knl_get_dimm_capacity(struct sbridge_pvt *pvt, u64 *mc_sizes) { - u64 sad_base, sad_size, sad_limit = 0; + u64 sad_base, sad_limit = 0; u64 tad_base, tad_size, tad_limit, tad_deadspace, tad_livespace; int sad_rule = 0; int tad_rule = 0; @@ -1427,7 +1429,6 @@ edram_only = KNL_EDRAM_ONLY(dram_rule); sad_limit = pvt->info.sad_limit(dram_rule)+1; - sad_size = sad_limit - sad_base; pci_read_config_dword(pvt->pci_sad0, pvt->info.interleave_list[sad_rule], &interleave_reg); @@ -2952,7 +2953,7 @@ struct mem_ctl_info *new_mci; struct sbridge_pvt *pvt = mci->pvt_info; enum hw_event_mc_err_type tp_event; - char *type, *optype, msg[256]; + char *optype, msg[256]; bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0); bool overflow = GET_BITFIELD(m->status, 62, 62); bool uncorrected_error = GET_BITFIELD(m->status, 61, 61); @@ -2981,14 +2982,11 @@ if (uncorrected_error) { core_err_cnt = 1; if (ripv) { - type = "FATAL"; - tp_event = HW_EVENT_ERR_FATAL; - } else { - type = "NON_FATAL"; tp_event = HW_EVENT_ERR_UNCORRECTED; + } else { + tp_event = HW_EVENT_ERR_FATAL; } } else { - type = "CORRECTED"; tp_event = HW_EVENT_ERR_CORRECTED; } @@ -3200,7 +3198,6 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) { struct mem_ctl_info *mci = sbridge_dev->mci; - struct sbridge_pvt *pvt; if (unlikely(!mci || !mci->pvt_info)) { edac_dbg(0, "MC: dev = %p\n", &sbridge_dev->pdev[0]->dev); @@ -3209,8 +3206,6 @@ return; } - pvt = mci->pvt_info; - edac_dbg(0, "MC: mci = %p, dev = %p\n", mci, &sbridge_dev->pdev[0]->dev); @@ -3517,6 +3512,9 @@ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(sbridge_cpuids); if (!id) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/edac/sifive_edac.c +++ linux-oracle-5.4.0/drivers/edac/sifive_edac.c @@ -54,8 +54,8 @@ p->dci = edac_device_alloc_ctl_info(0, "sifive_ecc", 1, "sifive_ecc", 1, 1, NULL, 0, edac_device_alloc_index()); - if (IS_ERR(p->dci)) - return PTR_ERR(p->dci); + if (!p->dci) + return -ENOMEM; p->dci->dev = &pdev->dev; p->dci->mod_name = "Sifive ECC Manager"; --- linux-oracle-5.4.0.orig/drivers/edac/skx_base.c +++ linux-oracle-5.4.0/drivers/edac/skx_base.c @@ -46,7 +46,8 @@ } enum munittype { - CHAN0, CHAN1, CHAN2, SAD_ALL, UTIL_ALL, SAD + CHAN0, CHAN1, CHAN2, SAD_ALL, UTIL_ALL, SAD, + ERRCHAN0, ERRCHAN1, ERRCHAN2, }; struct munit { @@ -68,6 +69,9 @@ { 0x2040, { PCI_DEVFN(10, 0), PCI_DEVFN(12, 0) }, 2, 2, CHAN0 }, { 0x2044, { PCI_DEVFN(10, 4), PCI_DEVFN(12, 4) }, 2, 2, CHAN1 }, { 0x2048, { PCI_DEVFN(11, 0), PCI_DEVFN(13, 0) }, 2, 2, CHAN2 }, + { 0x2043, { PCI_DEVFN(10, 3), PCI_DEVFN(12, 3) }, 2, 2, ERRCHAN0 }, + { 0x2047, { PCI_DEVFN(10, 7), PCI_DEVFN(12, 7) }, 2, 2, ERRCHAN1 }, + { 0x204b, { PCI_DEVFN(11, 3), PCI_DEVFN(13, 3) }, 2, 2, ERRCHAN2 }, { 0x208e, { }, 1, 0, SAD }, { } }; @@ -104,10 +108,18 @@ } switch (m->mtype) { - case CHAN0: case CHAN1: case CHAN2: + case CHAN0: + case CHAN1: + case CHAN2: pci_dev_get(pdev); d->imc[i].chan[m->mtype].cdev = pdev; break; + case ERRCHAN0: + case ERRCHAN1: + case ERRCHAN2: + pci_dev_get(pdev); + d->imc[i].chan[m->mtype - ERRCHAN0].edev = pdev; + break; case SAD_ALL: pci_dev_get(pdev); d->sad_all = pdev; @@ -151,27 +163,23 @@ }; MODULE_DEVICE_TABLE(x86cpu, skx_cpuids); -#define SKX_GET_MTMTR(dev, reg) \ - pci_read_config_dword((dev), 0x87c, &(reg)) - -static bool skx_check_ecc(struct pci_dev *pdev) +static bool skx_check_ecc(u32 mcmtr) { - u32 mtmtr; - - SKX_GET_MTMTR(pdev, mtmtr); - - return !!GET_BITFIELD(mtmtr, 2, 2); + return !!GET_BITFIELD(mcmtr, 2, 2); } static int skx_get_dimm_config(struct mem_ctl_info *mci) { struct skx_pvt *pvt = mci->pvt_info; + u32 mtr, mcmtr, amap, mcddrtcfg; struct skx_imc *imc = pvt->imc; - u32 mtr, amap, mcddrtcfg; struct dimm_info *dimm; int i, j; int ndimms; + /* Only the mcmtr on the first channel is effective */ + pci_read_config_dword(imc->chan[0].cdev, 0x87c, &mcmtr); + for (i = 0; i < SKX_NUM_CHANNELS; i++) { ndimms = 0; pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap); @@ -182,14 +190,14 @@ pci_read_config_dword(imc->chan[i].cdev, 0x80 + 4 * j, &mtr); if (IS_DIMM_PRESENT(mtr)) { - ndimms += skx_get_dimm_info(mtr, amap, dimm, imc, i, j); + ndimms += skx_get_dimm_info(mtr, mcmtr, amap, dimm, imc, i, j); } else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) { ndimms += skx_get_nvdimm_info(dimm, imc, i, j, EDAC_MOD_STR); nvdimm_count++; } } - if (ndimms && !skx_check_ecc(imc->chan[0].cdev)) { + if (ndimms && !skx_check_ecc(mcmtr)) { skx_printk(KERN_ERR, "ECC is disabled on imc %d\n", imc->mc); return -ENODEV; } @@ -216,6 +224,39 @@ #define SKX_ILV_REMOTE(tgt) (((tgt) & 8) == 0) #define SKX_ILV_TARGET(tgt) ((tgt) & 7) +static void skx_show_retry_rd_err_log(struct decoded_addr *res, + char *msg, int len) +{ + u32 log0, log1, log2, log3, log4; + u32 corr0, corr1, corr2, corr3; + struct pci_dev *edev; + int n; + + edev = res->dev->imc[res->imc].chan[res->channel].edev; + + pci_read_config_dword(edev, 0x154, &log0); + pci_read_config_dword(edev, 0x148, &log1); + pci_read_config_dword(edev, 0x150, &log2); + pci_read_config_dword(edev, 0x15c, &log3); + pci_read_config_dword(edev, 0x114, &log4); + + n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x]", + log0, log1, log2, log3, log4); + + pci_read_config_dword(edev, 0x104, &corr0); + pci_read_config_dword(edev, 0x108, &corr1); + pci_read_config_dword(edev, 0x10c, &corr2); + pci_read_config_dword(edev, 0x110, &corr3); + + if (len - n > 0) + snprintf(msg + n, len - n, + " correrrcnt[%.4x %.4x %.4x %.4x %.4x %.4x %.4x %.4x]", + corr0 & 0xffff, corr0 >> 16, + corr1 & 0xffff, corr1 >> 16, + corr2 & 0xffff, corr2 >> 16, + corr3 & 0xffff, corr3 >> 16); +} + static bool skx_sad_decode(struct decoded_addr *res) { struct skx_dev *d = list_first_entry(skx_edac_list, typeof(*d), list); @@ -463,7 +504,7 @@ } static u8 skx_close_row[] = { - 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33 + 15, 16, 17, 18, 20, 21, 22, 28, 10, 11, 12, 13, 29, 30, 31, 32, 33, 34 }; static u8 skx_close_column[] = { @@ -471,7 +512,7 @@ }; static u8 skx_open_row[] = { - 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33 + 14, 15, 16, 20, 28, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34 }; static u8 skx_open_column[] = { @@ -609,6 +650,9 @@ if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(skx_cpuids); if (!id) return -ENODEV; @@ -659,7 +703,7 @@ } } - skx_set_decode(skx_decode); + skx_set_decode(skx_decode, skx_show_retry_rd_err_log); if (nvdimm_count && skx_adxl_get() == -ENODEV) skx_printk(KERN_NOTICE, "Only decoding DDR4 address!\n"); --- linux-oracle-5.4.0.orig/drivers/edac/skx_common.c +++ linux-oracle-5.4.0/drivers/edac/skx_common.c @@ -23,10 +23,13 @@ #include "skx_common.h" static const char * const component_names[] = { - [INDEX_SOCKET] = "ProcessorSocketId", - [INDEX_MEMCTRL] = "MemoryControllerId", - [INDEX_CHANNEL] = "ChannelId", - [INDEX_DIMM] = "DimmSlotId", + [INDEX_SOCKET] = "ProcessorSocketId", + [INDEX_MEMCTRL] = "MemoryControllerId", + [INDEX_CHANNEL] = "ChannelId", + [INDEX_DIMM] = "DimmSlotId", + [INDEX_NM_MEMCTRL] = "NmMemoryControllerId", + [INDEX_NM_CHANNEL] = "NmChannelId", + [INDEX_NM_DIMM] = "NmDimmSlotId", }; static int component_indices[ARRAY_SIZE(component_names)]; @@ -34,13 +37,16 @@ static const char * const *adxl_component_names; static u64 *adxl_values; static char *adxl_msg; +static unsigned long adxl_nm_bitmap; static char skx_msg[MSG_SIZE]; static skx_decode_f skx_decode; +static skx_show_retry_log_f skx_show_retry_rd_err_log; static u64 skx_tolm, skx_tohm; static LIST_HEAD(dev_edac_list); +static bool skx_mem_cfg_2lm; -int __init skx_adxl_get(void) +int skx_adxl_get(void) { const char * const *names; int i, j; @@ -55,14 +61,25 @@ for (j = 0; names[j]; j++) { if (!strcmp(component_names[i], names[j])) { component_indices[i] = j; + + if (i >= INDEX_NM_FIRST) + adxl_nm_bitmap |= 1 << i; + break; } } - if (!names[j]) + if (!names[j] && i < INDEX_NM_FIRST) goto err; } + if (skx_mem_cfg_2lm) { + if (!adxl_nm_bitmap) + skx_printk(KERN_NOTICE, "Not enough ADXL components for 2-level memory.\n"); + else + edac_dbg(2, "adxl_nm_bitmap: 0x%lx\n", adxl_nm_bitmap); + } + adxl_component_names = names; while (*names++) adxl_component_count++; @@ -91,15 +108,18 @@ return -ENODEV; } +EXPORT_SYMBOL_GPL(skx_adxl_get); -void __exit skx_adxl_put(void) +void skx_adxl_put(void) { kfree(adxl_values); kfree(adxl_msg); } +EXPORT_SYMBOL_GPL(skx_adxl_put); -static bool skx_adxl_decode(struct decoded_addr *res) +static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem) { + struct skx_dev *d; int i, len = 0; if (res->addr >= skx_tohm || (res->addr >= skx_tolm && @@ -114,9 +134,36 @@ } res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]]; - res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; - res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]]; - res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]]; + if (error_in_1st_level_mem) { + res->imc = (adxl_nm_bitmap & BIT_NM_MEMCTRL) ? + (int)adxl_values[component_indices[INDEX_NM_MEMCTRL]] : -1; + res->channel = (adxl_nm_bitmap & BIT_NM_CHANNEL) ? + (int)adxl_values[component_indices[INDEX_NM_CHANNEL]] : -1; + res->dimm = (adxl_nm_bitmap & BIT_NM_DIMM) ? + (int)adxl_values[component_indices[INDEX_NM_DIMM]] : -1; + } else { + res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; + res->channel = (int)adxl_values[component_indices[INDEX_CHANNEL]]; + res->dimm = (int)adxl_values[component_indices[INDEX_DIMM]]; + } + + if (res->imc > NUM_IMC - 1 || res->imc < 0) { + skx_printk(KERN_ERR, "Bad imc %d\n", res->imc); + return false; + } + + list_for_each_entry(d, &dev_edac_list, list) { + if (d->imc[0].src_id == res->socket) { + res->dev = d; + break; + } + } + + if (!res->dev) { + skx_printk(KERN_ERR, "No device for src_id %d imc %d\n", + res->socket, res->imc); + return false; + } for (i = 0; i < adxl_component_count; i++) { if (adxl_values[i] == ~0x0ull) @@ -131,10 +178,18 @@ return true; } -void skx_set_decode(skx_decode_f decode) +void skx_set_mem_cfg(bool mem_cfg_2lm) +{ + skx_mem_cfg_2lm = mem_cfg_2lm; +} +EXPORT_SYMBOL_GPL(skx_set_mem_cfg); + +void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) { skx_decode = decode; + skx_show_retry_rd_err_log = show_retry_log; } +EXPORT_SYMBOL_GPL(skx_set_decode); int skx_get_src_id(struct skx_dev *d, int off, u8 *id) { @@ -148,6 +203,7 @@ *id = GET_BITFIELD(reg, 12, 14); return 0; } +EXPORT_SYMBOL_GPL(skx_get_src_id); int skx_get_node_id(struct skx_dev *d, u8 *id) { @@ -161,6 +217,7 @@ *id = GET_BITFIELD(reg, 0, 2); return 0; } +EXPORT_SYMBOL_GPL(skx_get_node_id); static int get_width(u32 mtr) { @@ -227,6 +284,7 @@ *list = &dev_edac_list; return ndev; } +EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings); int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm) { @@ -235,7 +293,7 @@ pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, NULL); if (!pdev) { - skx_printk(KERN_ERR, "Can't get tolm/tohm\n"); + edac_dbg(2, "Can't get tolm/tohm\n"); return -ENODEV; } @@ -266,6 +324,7 @@ pci_dev_put(pdev); return -ENODEV; } +EXPORT_SYMBOL_GPL(skx_get_hi_lo); static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add, int minval, int maxval, const char *name) @@ -283,7 +342,7 @@ #define numrow(reg) skx_get_dimm_attr(reg, 2, 4, 12, 1, 6, "rows") #define numcol(reg) skx_get_dimm_attr(reg, 0, 1, 10, 0, 2, "cols") -int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, +int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, struct skx_imc *imc, int chan, int dimmno) { int banks = 16, ranks, rows, cols, npages; @@ -303,8 +362,8 @@ imc->mc, chan, dimmno, size, npages, banks, 1 << ranks, rows, cols); - imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mtr, 0, 0); - imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mtr, 9, 9); + imc->chan[chan].dimms[dimmno].close_pg = GET_BITFIELD(mcmtr, 0, 0); + imc->chan[chan].dimms[dimmno].bank_xor_enable = GET_BITFIELD(mcmtr, 9, 9); imc->chan[chan].dimms[dimmno].fine_grain_bank = GET_BITFIELD(amap, 0, 0); imc->chan[chan].dimms[dimmno].rowbits = rows; imc->chan[chan].dimms[dimmno].colbits = cols; @@ -319,6 +378,7 @@ return 1; } +EXPORT_SYMBOL_GPL(skx_get_dimm_info); int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, int chan, int dimmno, const char *mod_str) @@ -367,6 +427,7 @@ return (size == 0 || size == ~0ull) ? 0 : 1; } +EXPORT_SYMBOL_GPL(skx_get_nvdimm_info); int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, const char *ctl_name, const char *mod_str, @@ -434,6 +495,7 @@ imc->mci = NULL; return rc; } +EXPORT_SYMBOL_GPL(skx_register_mci); static void skx_unregister_mci(struct skx_imc *imc) { @@ -452,34 +514,17 @@ edac_mc_free(mci); } -static struct mem_ctl_info *get_mci(int src_id, int lmc) -{ - struct skx_dev *d; - - if (lmc > NUM_IMC - 1) { - skx_printk(KERN_ERR, "Bad lmc %d\n", lmc); - return NULL; - } - - list_for_each_entry(d, &dev_edac_list, list) { - if (d->imc[0].src_id == src_id) - return d->imc[lmc].mci; - } - - skx_printk(KERN_ERR, "No mci for src_id %d lmc %d\n", src_id, lmc); - return NULL; -} - static void skx_mce_output_error(struct mem_ctl_info *mci, const struct mce *m, struct decoded_addr *res) { enum hw_event_mc_err_type tp_event; - char *type, *optype; + char *optype; bool ripv = GET_BITFIELD(m->mcgstatus, 0, 0); bool overflow = GET_BITFIELD(m->status, 62, 62); bool uncorrected_error = GET_BITFIELD(m->status, 61, 61); bool recoverable; + int len; u32 core_err_cnt = GET_BITFIELD(m->status, 38, 52); u32 mscod = GET_BITFIELD(m->status, 16, 31); u32 errcode = GET_BITFIELD(m->status, 0, 15); @@ -490,14 +535,11 @@ if (uncorrected_error) { core_err_cnt = 1; if (ripv) { - type = "FATAL"; - tp_event = HW_EVENT_ERR_FATAL; - } else { - type = "NON_FATAL"; tp_event = HW_EVENT_ERR_UNCORRECTED; + } else { + tp_event = HW_EVENT_ERR_FATAL; } } else { - type = "CORRECTED"; tp_event = HW_EVENT_ERR_CORRECTED; } @@ -539,12 +581,12 @@ } } if (adxl_component_count) { - snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s", + len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s", overflow ? " OVERFLOW" : "", (uncorrected_error && recoverable) ? " recoverable" : "", mscod, errcode, adxl_msg); } else { - snprintf(skx_msg, MSG_SIZE, + len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:0x%x col:0x%x", overflow ? " OVERFLOW" : "", (uncorrected_error && recoverable) ? " recoverable" : "", @@ -553,6 +595,9 @@ res->bank_group, res->bank_address, res->row, res->column); } + if (skx_show_retry_rd_err_log) + skx_show_retry_rd_err_log(res, skx_msg + len, MSG_SIZE - len); + edac_dbg(0, "%s\n", skx_msg); /* Call the helper to output message */ @@ -562,6 +607,21 @@ optype, skx_msg); } +static bool skx_error_in_1st_level_mem(const struct mce *m) +{ + u32 errcode; + + if (!skx_mem_cfg_2lm) + return false; + + errcode = GET_BITFIELD(m->status, 0, 15); + + if ((errcode & 0xef80) != 0x280) + return false; + + return true; +} + int skx_mce_check_error(struct notifier_block *nb, unsigned long val, void *data) { @@ -581,17 +641,14 @@ res.addr = mce->addr; if (adxl_component_count) { - if (!skx_adxl_decode(&res)) + if (!skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce))) return NOTIFY_DONE; - - mci = get_mci(res.socket, res.imc); - } else { - if (!skx_decode || !skx_decode(&res)) - return NOTIFY_DONE; - - mci = res.dev->imc[res.imc].mci; + } else if (!skx_decode || !skx_decode(&res)) { + return NOTIFY_DONE; } + mci = res.dev->imc[res.imc].mci; + if (!mci) return NOTIFY_DONE; @@ -617,6 +674,7 @@ return NOTIFY_DONE; } +EXPORT_SYMBOL_GPL(skx_mce_check_error); void skx_remove(void) { @@ -652,3 +710,8 @@ kfree(d); } } +EXPORT_SYMBOL_GPL(skx_remove); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Tony Luck"); +MODULE_DESCRIPTION("MC Driver for Intel server processors"); --- linux-oracle-5.4.0.orig/drivers/edac/skx_common.h +++ linux-oracle-5.4.0/drivers/edac/skx_common.h @@ -9,6 +9,8 @@ #ifndef _SKX_COMM_EDAC_H #define _SKX_COMM_EDAC_H +#include + #define MSG_SIZE 1024 /* @@ -64,6 +66,7 @@ u8 src_id, node_id; struct skx_channel { struct pci_dev *cdev; + struct pci_dev *edev; struct skx_dimm { u8 close_pg; u8 bank_xor_enable; @@ -89,9 +92,17 @@ INDEX_MEMCTRL, INDEX_CHANNEL, INDEX_DIMM, + INDEX_NM_FIRST, + INDEX_NM_MEMCTRL = INDEX_NM_FIRST, + INDEX_NM_CHANNEL, + INDEX_NM_DIMM, INDEX_MAX }; +#define BIT_NM_MEMCTRL BIT_ULL(INDEX_NM_MEMCTRL) +#define BIT_NM_CHANNEL BIT_ULL(INDEX_NM_CHANNEL) +#define BIT_NM_DIMM BIT_ULL(INDEX_NM_DIMM) + struct decoded_addr { struct skx_dev *dev; u64 addr; @@ -113,10 +124,12 @@ typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); typedef bool (*skx_decode_f)(struct decoded_addr *res); +typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); -int __init skx_adxl_get(void); -void __exit skx_adxl_put(void); -void skx_set_decode(skx_decode_f decode); +int skx_adxl_get(void); +void skx_adxl_put(void); +void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); +void skx_set_mem_cfg(bool mem_cfg_2lm); int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id); @@ -126,7 +139,7 @@ int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); -int skx_get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, +int skx_get_dimm_info(u32 mtr, u32 mcmtr, u32 amap, struct dimm_info *dimm, struct skx_imc *imc, int chan, int dimmno); int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, --- linux-oracle-5.4.0.orig/drivers/edac/synopsys_edac.c +++ linux-oracle-5.4.0/drivers/edac/synopsys_edac.c @@ -163,6 +163,11 @@ #define ECC_STAT_CECNT_SHIFT 8 #define ECC_STAT_BITNUM_MASK 0x7F +/* ECC error count register definitions */ +#define ECC_ERRCNT_UECNT_MASK 0xFFFF0000 +#define ECC_ERRCNT_UECNT_SHIFT 16 +#define ECC_ERRCNT_CECNT_MASK 0xFFFF + /* DDR QOS Interrupt register definitions */ #define DDR_QOS_IRQ_STAT_OFST 0x20200 #define DDR_QOSUE_MASK 0x4 @@ -418,15 +423,16 @@ base = priv->baseaddr; p = &priv->stat; + regval = readl(base + ECC_ERRCNT_OFST); + p->ce_cnt = regval & ECC_ERRCNT_CECNT_MASK; + p->ue_cnt = (regval & ECC_ERRCNT_UECNT_MASK) >> ECC_ERRCNT_UECNT_SHIFT; + if (!p->ce_cnt) + goto ue_err; + regval = readl(base + ECC_STAT_OFST); if (!regval) return 1; - p->ce_cnt = (regval & ECC_STAT_CECNT_MASK) >> ECC_STAT_CECNT_SHIFT; - p->ue_cnt = (regval & ECC_STAT_UECNT_MASK) >> ECC_STAT_UECNT_SHIFT; - if (!p->ce_cnt) - goto ue_err; - p->ceinfo.bitpos = (regval & ECC_STAT_BITNUM_MASK); regval = readl(base + ECC_CEADDR0_OFST); @@ -479,20 +485,14 @@ pinf = &p->ceinfo; if (!priv->p_data->quirks) { snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "DDR ECC error type:%s Row %d Bank %d Col %d ", - "CE", pinf->row, pinf->bank, pinf->col); - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Bit Position: %d Data: 0x%08x\n", + "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x", + "CE", pinf->row, pinf->bank, pinf->col, pinf->bitpos, pinf->data); } else { snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "DDR ECC error type:%s Row %d Bank %d Col %d ", - "CE", pinf->row, pinf->bank, pinf->col); - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "BankGroup Number %d Block Number %d ", - pinf->bankgrpnr, pinf->blknr); - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "Bit Position: %d Data: 0x%08x\n", + "DDR ECC error type:%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d Bit Position: %d Data: 0x%08x", + "CE", pinf->row, pinf->bank, pinf->col, + pinf->bankgrpnr, pinf->blknr, pinf->bitpos, pinf->data); } @@ -509,10 +509,8 @@ "UE", pinf->row, pinf->bank, pinf->col); } else { snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "DDR ECC error type :%s Row %d Bank %d Col %d ", - "UE", pinf->row, pinf->bank, pinf->col); - snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, - "BankGroup Number %d Block Number %d", + "DDR ECC error type :%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d", + "UE", pinf->row, pinf->bank, pinf->col, pinf->bankgrpnr, pinf->blknr); } @@ -790,7 +788,7 @@ for (j = 0; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; - dimm->edac_mode = EDAC_FLAG_SECDED; + dimm->edac_mode = EDAC_SECDED; dimm->mtype = p_data->get_mtype(priv->baseaddr); dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; dimm->grain = SYNPS_EDAC_ERR_GRAIN; @@ -1359,8 +1357,7 @@ } } - if (of_device_is_compatible(pdev->dev.of_node, - "xlnx,zynqmp-ddrc-2.40a")) + if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) setup_address_map(priv); #endif --- linux-oracle-5.4.0.orig/drivers/edac/thunderx_edac.c +++ linux-oracle-5.4.0/drivers/edac/thunderx_edac.c @@ -1133,7 +1133,7 @@ decode_register(other, OCX_OTHER_SIZE, ocx_com_errors, ctx->reg_com_int); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); for (lane = 0; lane < OCX_RX_LANES; lane++) if (ctx->reg_com_int & BIT(lane)) { @@ -1142,12 +1142,12 @@ lane, ctx->reg_lane_int[lane], lane, ctx->reg_lane_stat11[lane]); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); decode_register(other, OCX_OTHER_SIZE, ocx_lane_errors, ctx->reg_lane_int[lane]); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); } if (ctx->reg_com_int & OCX_COM_INT_CE) @@ -1217,7 +1217,7 @@ decode_register(other, OCX_OTHER_SIZE, ocx_com_link_errors, ctx->reg_com_link_int); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); @@ -1896,7 +1896,7 @@ decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); - strncat(msg, other, L2C_MESSAGE_SIZE); + strlcat(msg, other, L2C_MESSAGE_SIZE); if (ctx->reg_int & mask_ue) edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); --- linux-oracle-5.4.0.orig/drivers/edac/ti_edac.c +++ linux-oracle-5.4.0/drivers/edac/ti_edac.c @@ -197,6 +197,7 @@ { .compatible = "ti,emif-dra7xx", .data = (void *)EMIF_TYPE_DRA7 }, {}, }; +MODULE_DEVICE_TABLE(of, ti_edac_of_match); static int _emif_get_id(struct device_node *node) { @@ -278,7 +279,8 @@ /* add EMIF ECC error handler */ error_irq = platform_get_irq(pdev, 0); - if (!error_irq) { + if (error_irq < 0) { + ret = error_irq; edac_printk(KERN_ERR, EDAC_MOD_NAME, "EMIF irq number not defined.\n"); goto err; --- linux-oracle-5.4.0.orig/drivers/edac/xgene_edac.c +++ linux-oracle-5.4.0/drivers/edac/xgene_edac.c @@ -1922,7 +1922,7 @@ irq = platform_get_irq(pdev, i); if (irq < 0) { dev_err(&pdev->dev, "No IRQ resource\n"); - rc = -EINVAL; + rc = irq; goto out_err; } rc = devm_request_irq(&pdev->dev, irq, --- linux-oracle-5.4.0.orig/drivers/extcon/Kconfig +++ linux-oracle-5.4.0/drivers/extcon/Kconfig @@ -121,7 +121,8 @@ config EXTCON_MAX8997 tristate "Maxim MAX8997 EXTCON Support" - depends on MFD_MAX8997 && IRQ_DOMAIN + depends on MFD_MAX8997 + select IRQ_DOMAIN help If you say yes here you get support for the MUIC device of Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-adc-jack.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-adc-jack.c @@ -124,7 +124,7 @@ for (i = 0; data->adc_conditions[i].id != EXTCON_NONE; i++); data->num_conditions = i; - data->chan = iio_channel_get(&pdev->dev, pdata->consumer_channel); + data->chan = devm_iio_channel_get(&pdev->dev, pdata->consumer_channel); if (IS_ERR(data->chan)) return PTR_ERR(data->chan); @@ -164,7 +164,6 @@ free_irq(data->irq, data); cancel_work_sync(&data->handler.work); - iio_channel_release(data->chan); return 0; } --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-arizona.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-arizona.c @@ -597,7 +597,7 @@ struct arizona *arizona = info->arizona; int id_gpio = arizona->pdata.hpdet_id_gpio; unsigned int report = EXTCON_JACK_HEADPHONE; - int ret, reading; + int ret, reading, state; bool mic = false; mutex_lock(&info->lock); @@ -610,12 +610,11 @@ } /* If the cable was removed while measuring ignore the result */ - ret = extcon_get_state(info->edev, EXTCON_MECHANICAL); - if (ret < 0) { - dev_err(arizona->dev, "Failed to check cable state: %d\n", - ret); + state = extcon_get_state(info->edev, EXTCON_MECHANICAL); + if (state < 0) { + dev_err(arizona->dev, "Failed to check cable state: %d\n", state); goto out; - } else if (!ret) { + } else if (!state) { dev_dbg(arizona->dev, "Ignoring HPDET for removed cable\n"); goto done; } @@ -668,7 +667,7 @@ ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); /* If we have a mic then reenable MICDET */ - if (mic || info->mic) + if (state && (mic || info->mic)) arizona_start_mic(info); if (info->hpdet_active) { @@ -676,7 +675,9 @@ info->hpdet_active = false; } - info->hpdet_done = true; + /* Do not set hp_det done when the cable has been unplugged */ + if (state) + info->hpdet_done = true; out: mutex_unlock(&info->lock); @@ -1724,25 +1725,6 @@ bool change; int ret; - ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, - ARIZONA_MICD_ENA, 0, - &change); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", - ret); - } else if (change) { - regulator_disable(info->micvdd); - pm_runtime_put(info->dev); - } - - gpiod_put(info->micd_pol_gpio); - - pm_runtime_disable(&pdev->dev); - - regmap_update_bits(arizona->regmap, - ARIZONA_MICD_CLAMP_CONTROL, - ARIZONA_MICD_CLAMP_MODE_MASK, 0); - if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; @@ -1758,10 +1740,31 @@ arizona_free_irq(arizona, jack_irq_rise, info); arizona_free_irq(arizona, jack_irq_fall, info); cancel_delayed_work_sync(&info->hpdet_work); + cancel_delayed_work_sync(&info->micd_detect_work); + cancel_delayed_work_sync(&info->micd_timeout_work); + + ret = regmap_update_bits_check(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0, + &change); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to disable micd on remove: %d\n", + ret); + } else if (change) { + regulator_disable(info->micvdd); + pm_runtime_put(info->dev); + } + + regmap_update_bits(arizona->regmap, + ARIZONA_MICD_CLAMP_CONTROL, + ARIZONA_MICD_CLAMP_MODE_MASK, 0); regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, ARIZONA_JD1_ENA, 0); arizona_clk32k_disable(arizona); + gpiod_put(info->micd_pol_gpio); + + pm_runtime_disable(&pdev->dev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-axp288.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-axp288.c @@ -423,9 +423,40 @@ /* Start charger cable type detection */ axp288_extcon_enable(info); + device_init_wakeup(dev, true); + platform_set_drvdata(pdev, info); + + return 0; +} + +static int __maybe_unused axp288_extcon_suspend(struct device *dev) +{ + struct axp288_extcon_info *info = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(info->irq[VBUS_RISING_IRQ]); + return 0; } +static int __maybe_unused axp288_extcon_resume(struct device *dev) +{ + struct axp288_extcon_info *info = dev_get_drvdata(dev); + + /* + * Wakeup when a charger is connected to do charger-type + * connection and generate an extcon event which makes the + * axp288 charger driver set the input current limit. + */ + if (device_may_wakeup(dev)) + disable_irq_wake(info->irq[VBUS_RISING_IRQ]); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(axp288_extcon_pm_ops, axp288_extcon_suspend, + axp288_extcon_resume); + static const struct platform_device_id axp288_extcon_table[] = { { .name = "axp288_extcon" }, {}, @@ -437,6 +468,7 @@ .id_table = axp288_extcon_table, .driver = { .name = "axp288_extcon", + .pm = &axp288_extcon_pm_ops, }, }; --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-intel-cht-wc.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-intel-cht-wc.c @@ -338,6 +338,7 @@ struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); struct cht_wc_extcon_data *ext; unsigned long mask = ~(CHT_WC_PWRSRC_VBUS | CHT_WC_PWRSRC_USBID_MASK); + int pwrsrc_sts, id; int irq, ret; irq = platform_get_irq(pdev, 0); @@ -387,8 +388,19 @@ goto disable_sw_control; } - /* Route D+ and D- to PMIC for initial charger detection */ - cht_wc_extcon_set_phymux(ext, MUX_SEL_PMIC); + ret = regmap_read(ext->regmap, CHT_WC_PWRSRC_STS, &pwrsrc_sts); + if (ret) { + dev_err(ext->dev, "Error reading pwrsrc status: %d\n", ret); + goto disable_sw_control; + } + + /* + * If no USB host or device connected, route D+ and D- to PMIC for + * initial charger detection + */ + id = cht_wc_extcon_get_id(ext, pwrsrc_sts); + if (id != INTEL_USB_ID_GND) + cht_wc_extcon_set_phymux(ext, MUX_SEL_PMIC); /* Get initial state */ cht_wc_extcon_pwrsrc_event(ext); --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-intel-mrfld.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-intel-mrfld.c @@ -197,6 +197,7 @@ struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent); struct regmap *regmap = pmic->regmap; struct mrfld_extcon_data *data; + unsigned int status; unsigned int id; int irq, ret; @@ -244,6 +245,14 @@ /* Get initial state */ mrfld_extcon_role_detect(data); + /* + * Cached status value is used for cable detection, see comments + * in mrfld_extcon_cable_detect(), we need to sync cached value + * with a real state of the hardware. + */ + regmap_read(regmap, BCOVE_SCHGRIRQ1, &status); + data->status = status; + mrfld_extcon_clear(data, BCOVE_MIRQLVL1, BCOVE_LVL1_CHGR); mrfld_extcon_clear(data, BCOVE_MCHGRIRQ1, BCOVE_CHGRIRQ_ALL); --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-max77693.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-max77693.c @@ -1277,4 +1277,4 @@ MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver"); MODULE_AUTHOR("Chanwoo Choi "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:extcon-max77693"); +MODULE_ALIAS("platform:max77693-muic"); --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-max8997.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-max8997.c @@ -729,7 +729,7 @@ 2, info->status); if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); - return ret; + goto err_irq; } cable_type = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC, &attached); @@ -784,3 +784,4 @@ MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver"); MODULE_AUTHOR("Donggeun Kim "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:max8997-muic"); --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-ptn5150.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-ptn5150.c @@ -127,7 +127,7 @@ case PTN5150_DFP_ATTACHED: extcon_set_state_sync(info->edev, EXTCON_USB_HOST, false); - gpiod_set_value(info->vbus_gpiod, 0); + gpiod_set_value_cansleep(info->vbus_gpiod, 0); extcon_set_state_sync(info->edev, EXTCON_USB, true); break; @@ -138,9 +138,9 @@ PTN5150_REG_CC_VBUS_DETECTION_MASK) >> PTN5150_REG_CC_VBUS_DETECTION_SHIFT); if (vbus) - gpiod_set_value(info->vbus_gpiod, 0); + gpiod_set_value_cansleep(info->vbus_gpiod, 0); else - gpiod_set_value(info->vbus_gpiod, 1); + gpiod_set_value_cansleep(info->vbus_gpiod, 1); extcon_set_state_sync(info->edev, EXTCON_USB_HOST, true); @@ -156,7 +156,7 @@ EXTCON_USB_HOST, false); extcon_set_state_sync(info->edev, EXTCON_USB, false); - gpiod_set_value(info->vbus_gpiod, 0); + gpiod_set_value_cansleep(info->vbus_gpiod, 0); } } --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-sm5502.c +++ linux-oracle-5.4.0/drivers/extcon/extcon-sm5502.c @@ -65,6 +65,10 @@ /* Default value of SM5502 register to bring up MUIC device. */ static struct reg_data sm5502_reg_data[] = { { + .reg = SM5502_REG_RESET, + .val = SM5502_REG_RESET_MASK, + .invert = true, + }, { .reg = SM5502_REG_CONTROL, .val = SM5502_REG_CONTROL_MASK_INT_MASK, .invert = false, @@ -84,7 +88,6 @@ | SM5502_REG_INTM2_MHL_MASK, .invert = true, }, - { } }; /* List of detectable cables */ --- linux-oracle-5.4.0.orig/drivers/extcon/extcon-sm5502.h +++ linux-oracle-5.4.0/drivers/extcon/extcon-sm5502.h @@ -237,6 +237,8 @@ #define DM_DP_SWITCH_UART ((DM_DP_CON_SWITCH_UART <dev.type = &edev->extcon_dev_type; } - ret = device_register(&edev->dev); - if (ret) { - put_device(&edev->dev); - goto err_dev; - } - spin_lock_init(&edev->lock); - edev->nh = devm_kcalloc(&edev->dev, edev->max_supported, - sizeof(*edev->nh), GFP_KERNEL); - if (!edev->nh) { - ret = -ENOMEM; - goto err_dev; + if (edev->max_supported) { + edev->nh = kcalloc(edev->max_supported, sizeof(*edev->nh), + GFP_KERNEL); + if (!edev->nh) { + ret = -ENOMEM; + goto err_alloc_nh; + } } for (index = 0; index < edev->max_supported; index++) @@ -1252,6 +1256,12 @@ dev_set_drvdata(&edev->dev, edev); edev->state = 0; + ret = device_register(&edev->dev); + if (ret) { + put_device(&edev->dev); + goto err_dev; + } + mutex_lock(&extcon_dev_list_lock); list_add(&edev->entry, &extcon_dev_list); mutex_unlock(&extcon_dev_list_lock); @@ -1260,6 +1270,9 @@ err_dev: if (edev->max_supported) + kfree(edev->nh); +err_alloc_nh: + if (edev->max_supported) kfree(edev->extcon_dev_type.groups); err_alloc_groups: if (edev->max_supported && edev->mutually_exclusive) { @@ -1319,6 +1332,7 @@ if (edev->max_supported) { kfree(edev->extcon_dev_type.groups); kfree(edev->cables); + kfree(edev->nh); } put_device(&edev->dev); --- linux-oracle-5.4.0.orig/drivers/firewire/core-card.c +++ linux-oracle-5.4.0/drivers/firewire/core-card.c @@ -429,7 +429,23 @@ */ card->bm_generation = generation; - if (root_device == NULL) { + if (card->gap_count == 0) { + /* + * If self IDs have inconsistent gap counts, do a + * bus reset ASAP. The config rom read might never + * complete, so don't wait for it. However, still + * send a PHY configuration packet prior to the + * bus reset. The PHY configuration packet might + * fail, but 1394-2008 8.4.5.2 explicitly permits + * it in this case, so it should be safe to try. + */ + new_root_id = local_id; + /* + * We must always send a bus reset if the gap count + * is inconsistent, so bypass the 5-reset limit. + */ + card->bm_retries = 0; + } else if (root_device == NULL) { /* * Either link_on is false, or we failed to read the * config rom. In either case, pick another root. @@ -484,7 +500,19 @@ fw_notice(card, "phy config: new root=%x, gap_count=%d\n", new_root_id, gap_count); fw_send_phy_config(card, new_root_id, generation, gap_count); - reset_bus(card, true); + /* + * Where possible, use a short bus reset to minimize + * disruption to isochronous transfers. But in the event + * of a gap count inconsistency, use a long bus reset. + * + * As noted in 1394a 8.4.6.2, nodes on a mixed 1394/1394a bus + * may set different gap counts after a bus reset. On a mixed + * 1394/1394a bus, a short bus reset can get doubled. Some + * nodes may treat the double reset as one bus reset and others + * may treat it as two, causing a gap count inconsistency + * again. Using a long bus reset prevents this. + */ + reset_bus(card, card->gap_count != 0); /* Will allocate broadcast channel after the reset. */ goto out; } @@ -668,6 +696,7 @@ void fw_core_remove_card(struct fw_card *card) { struct fw_card_driver dummy_driver = dummy_driver_template; + unsigned long flags; card->driver->update_phy_reg(card, 4, PHY_LINK_ACTIVE | PHY_CONTENDER, 0); @@ -682,7 +711,9 @@ dummy_driver.stop_iso = card->driver->stop_iso; card->driver = &dummy_driver; + spin_lock_irqsave(&card->lock, flags); fw_destroy_nodes(card); + spin_unlock_irqrestore(&card->lock, flags); /* Wait for all users, especially device workqueue jobs, to finish. */ fw_card_put(card); --- linux-oracle-5.4.0.orig/drivers/firewire/core-cdev.c +++ linux-oracle-5.4.0/drivers/firewire/core-cdev.c @@ -818,8 +818,10 @@ r = container_of(resource, struct inbound_transaction_resource, resource); - if (is_fcp_request(r->request)) + if (is_fcp_request(r->request)) { + kfree(r->data); goto out; + } if (a->length != fw_get_response_length(r->request)) { ret = -EINVAL; @@ -1482,6 +1484,7 @@ { struct outbound_phy_packet_event *e = container_of(packet, struct outbound_phy_packet_event, p); + struct client *e_client; switch (status) { /* expected: */ @@ -1498,9 +1501,10 @@ } e->phy_packet.data[0] = packet->timestamp; + e_client = e->client; queue_event(e->client, &e->event, &e->phy_packet, sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); - client_put(e->client); + client_put(e_client); } static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) --- linux-oracle-5.4.0.orig/drivers/firewire/core-device.c +++ linux-oracle-5.4.0/drivers/firewire/core-device.c @@ -100,10 +100,9 @@ * @buf: where to put the string * @size: size of @buf, in bytes * - * The string is taken from a minimal ASCII text descriptor leaf after - * the immediate entry with @key. The string is zero-terminated. - * An overlong string is silently truncated such that it and the - * zero byte fit into @size. + * The string is taken from a minimal ASCII text descriptor leaf just after the entry with the + * @key. The string is zero-terminated. An overlong string is silently truncated such that it + * and the zero byte fit into @size. * * Returns strlen(buf) or a negative error code. */ @@ -719,14 +718,11 @@ fw_unit_attributes, &unit->attribute_group); - if (device_register(&unit->device) < 0) - goto skip_unit; - fw_device_get(device); - continue; - - skip_unit: - kfree(unit); + if (device_register(&unit->device) < 0) { + put_device(&unit->device); + continue; + } } } --- linux-oracle-5.4.0.orig/drivers/firewire/core-topology.c +++ linux-oracle-5.4.0/drivers/firewire/core-topology.c @@ -374,16 +374,13 @@ card->bm_retries = 0; } +/* Must be called with card->lock held */ void fw_destroy_nodes(struct fw_card *card) { - unsigned long flags; - - spin_lock_irqsave(&card->lock, flags); card->color++; if (card->local_node != NULL) for_each_fw_node(card, card->local_node, report_lost_node); card->local_node = NULL; - spin_unlock_irqrestore(&card->lock, flags); } static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) @@ -509,6 +506,8 @@ struct fw_node *local_node; unsigned long flags; + spin_lock_irqsave(&card->lock, flags); + /* * If the selfID buffer is not the immediate successor of the * previously processed one, we cannot reliably compare the @@ -520,8 +519,6 @@ card->bm_retries = 0; } - spin_lock_irqsave(&card->lock, flags); - card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; card->node_id = node_id; /* --- linux-oracle-5.4.0.orig/drivers/firewire/core-transaction.c +++ linux-oracle-5.4.0/drivers/firewire/core-transaction.c @@ -73,24 +73,25 @@ static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode) { - struct fw_transaction *t; + struct fw_transaction *t = NULL, *iter; unsigned long flags; spin_lock_irqsave(&card->lock, flags); - list_for_each_entry(t, &card->transaction_list, link) { - if (t == transaction) { - if (!try_cancel_split_timeout(t)) { + list_for_each_entry(iter, &card->transaction_list, link) { + if (iter == transaction) { + if (!try_cancel_split_timeout(iter)) { spin_unlock_irqrestore(&card->lock, flags); goto timed_out; } - list_del_init(&t->link); - card->tlabel_mask &= ~(1ULL << t->tlabel); + list_del_init(&iter->link); + card->tlabel_mask &= ~(1ULL << iter->tlabel); + t = iter; break; } } spin_unlock_irqrestore(&card->lock, flags); - if (&t->link != &card->transaction_list) { + if (t) { t->callback(card, rcode, NULL, 0, t->callback_data); return 0; } @@ -935,7 +936,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) { - struct fw_transaction *t; + struct fw_transaction *t = NULL, *iter; unsigned long flags; u32 *data; size_t data_length; @@ -947,20 +948,21 @@ rcode = HEADER_GET_RCODE(p->header[1]); spin_lock_irqsave(&card->lock, flags); - list_for_each_entry(t, &card->transaction_list, link) { - if (t->node_id == source && t->tlabel == tlabel) { - if (!try_cancel_split_timeout(t)) { + list_for_each_entry(iter, &card->transaction_list, link) { + if (iter->node_id == source && iter->tlabel == tlabel) { + if (!try_cancel_split_timeout(iter)) { spin_unlock_irqrestore(&card->lock, flags); goto timed_out; } - list_del_init(&t->link); - card->tlabel_mask &= ~(1ULL << t->tlabel); + list_del_init(&iter->link); + card->tlabel_mask &= ~(1ULL << iter->tlabel); + t = iter; break; } } spin_unlock_irqrestore(&card->lock, flags); - if (&t->link == &card->transaction_list) { + if (!t) { timed_out: fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", source, tlabel); --- linux-oracle-5.4.0.orig/drivers/firewire/net.c +++ linux-oracle-5.4.0/drivers/firewire/net.c @@ -250,7 +250,11 @@ h = (struct fwnet_header *)((u8 *)hh->hh_data + HH_DATA_OFF(sizeof(*h))); h->h_proto = type; memcpy(h->h_dest, neigh->ha, net->addr_len); - hh->hh_len = FWNET_HLEN; + + /* Pairs with the READ_ONCE() in neigh_resolve_output(), + * neigh_hh_output() and neigh_update_hhs(). + */ + smp_store_release(&hh->hh_len, FWNET_HLEN); return 0; } --- linux-oracle-5.4.0.orig/drivers/firewire/nosy.c +++ linux-oracle-5.4.0/drivers/firewire/nosy.c @@ -148,10 +148,12 @@ if (atomic_read(&buffer->size) == 0) return -ENODEV; - /* FIXME: Check length <= user_length. */ + length = buffer->head->length; + + if (length > user_length) + return 0; end = buffer->data + buffer->capacity; - length = buffer->head->length; if (&buffer->head->data[length] < end) { if (copy_to_user(data, buffer->head->data, length)) @@ -346,6 +348,7 @@ struct client *client = file->private_data; spinlock_t *client_list_lock = &client->lynx->client_list_lock; struct nosy_stats stats; + int ret; switch (cmd) { case NOSY_IOC_GET_STATS: @@ -360,11 +363,15 @@ return 0; case NOSY_IOC_START: + ret = -EBUSY; spin_lock_irq(client_list_lock); - list_add_tail(&client->link, &client->lynx->client_list); + if (list_empty(&client->link)) { + list_add_tail(&client->link, &client->lynx->client_list); + ret = 0; + } spin_unlock_irq(client_list_lock); - return 0; + return ret; case NOSY_IOC_STOP: spin_lock_irq(client_list_lock); --- linux-oracle-5.4.0.orig/drivers/firewire/ohci.c +++ linux-oracle-5.4.0/drivers/firewire/ohci.c @@ -279,6 +279,51 @@ #define QUIRK_TI_SLLZ059 0x20 #define QUIRK_IR_WAKE 0x40 +// On PCI Express Root Complex in any type of AMD Ryzen machine, VIA VT6306/6307/6308 with Asmedia +// ASM1083/1085 brings an inconvenience that the read accesses to 'Isochronous Cycle Timer' register +// (at offset 0xf0 in PCI I/O space) often causes unexpected system reboot. The mechanism is not +// clear, since the read access to the other registers is enough safe; e.g. 'Node ID' register, +// while it is probable due to detection of any type of PCIe error. +#define QUIRK_REBOOT_BY_CYCLE_TIMER_READ 0x80000000 + +#if IS_ENABLED(CONFIG_X86) + +static bool has_reboot_by_cycle_timer_read_quirk(const struct fw_ohci *ohci) +{ + return !!(ohci->quirks & QUIRK_REBOOT_BY_CYCLE_TIMER_READ); +} + +#define PCI_DEVICE_ID_ASMEDIA_ASM108X 0x1080 + +static bool detect_vt630x_with_asm1083_on_amd_ryzen_machine(const struct pci_dev *pdev) +{ + const struct pci_dev *pcie_to_pci_bridge; + + // Detect any type of AMD Ryzen machine. + if (!static_cpu_has(X86_FEATURE_ZEN)) + return false; + + // Detect VIA VT6306/6307/6308. + if (pdev->vendor != PCI_VENDOR_ID_VIA) + return false; + if (pdev->device != PCI_DEVICE_ID_VIA_VT630X) + return false; + + // Detect Asmedia ASM1083/1085. + pcie_to_pci_bridge = pdev->bus->self; + if (pcie_to_pci_bridge->vendor != PCI_VENDOR_ID_ASMEDIA) + return false; + if (pcie_to_pci_bridge->device != PCI_DEVICE_ID_ASMEDIA_ASM108X) + return false; + + return true; +} + +#else +#define has_reboot_by_cycle_timer_read_quirk(ohci) false +#define detect_vt630x_with_asm1083_on_amd_ryzen_machine(pdev) false +#endif + /* In case of multiple matches in ohci_quirks[], only the first one is used. */ static const struct { unsigned short vendor, device, revision, flags; @@ -1099,7 +1144,7 @@ static int context_add_buffer(struct context *ctx) { struct descriptor_buffer *desc; - dma_addr_t uninitialized_var(bus_addr); + dma_addr_t bus_addr; int offset; /* @@ -1289,7 +1334,7 @@ struct fw_packet *packet) { struct fw_ohci *ohci = ctx->ohci; - dma_addr_t d_bus, uninitialized_var(payload_bus); + dma_addr_t d_bus, payload_bus; struct driver_data *driver_data; struct descriptor *d, *last; __le32 *header; @@ -1717,6 +1762,9 @@ s32 diff01, diff12; int i; + if (has_reboot_by_cycle_timer_read_quirk(ohci)) + return 0; + c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); if (ohci->quirks & QUIRK_CYCLE_TIMER) { @@ -2005,6 +2053,8 @@ ohci->generation = generation; reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); + if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) + reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); if (ohci->quirks & QUIRK_RESET_PACKET) ohci->request_generation = generation; @@ -2071,12 +2121,14 @@ return IRQ_NONE; /* - * busReset and postedWriteErr must not be cleared yet + * busReset and postedWriteErr events must not be cleared yet * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); log_irqs(ohci, event); + if (event & OHCI1394_busReset) + reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset); if (event & OHCI1394_selfIDComplete) queue_work(selfid_workqueue, &ohci->bus_reset_work); @@ -2445,7 +2497,7 @@ { struct fw_ohci *ohci; __be32 *next_config_rom; - dma_addr_t uninitialized_var(next_config_rom_bus); + dma_addr_t next_config_rom_bus; ohci = fw_ohci(card); @@ -2933,10 +2985,10 @@ int type, int channel, size_t header_size) { struct fw_ohci *ohci = fw_ohci(card); - struct iso_context *uninitialized_var(ctx); - descriptor_callback_t uninitialized_var(callback); - u64 *uninitialized_var(channels); - u32 *uninitialized_var(mask), uninitialized_var(regs); + struct iso_context *ctx; + descriptor_callback_t callback; + u64 *channels; + u32 *mask, regs; int index, ret = -EBUSY; spin_lock_irq(&ohci->lock); @@ -3619,6 +3671,9 @@ if (param_quirks) ohci->quirks = param_quirks; + if (detect_vt630x_with_asm1083_on_amd_ryzen_machine(dev)) + ohci->quirks |= QUIRK_REBOOT_BY_CYCLE_TIMER_READ; + /* * Because dma_alloc_coherent() allocates at least one page, * we save space by using a common buffer for the AR request/ --- linux-oracle-5.4.0.orig/drivers/firewire/sbp2.c +++ linux-oracle-5.4.0/drivers/firewire/sbp2.c @@ -408,7 +408,7 @@ void *payload, size_t length, void *callback_data) { struct sbp2_logical_unit *lu = callback_data; - struct sbp2_orb *orb; + struct sbp2_orb *orb = NULL, *iter; struct sbp2_status status; unsigned long flags; @@ -433,17 +433,18 @@ /* Lookup the orb corresponding to this status write. */ spin_lock_irqsave(&lu->tgt->lock, flags); - list_for_each_entry(orb, &lu->orb_list, link) { + list_for_each_entry(iter, &lu->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && - STATUS_GET_ORB_LOW(status) == orb->request_bus) { - orb->rcode = RCODE_COMPLETE; - list_del(&orb->link); + STATUS_GET_ORB_LOW(status) == iter->request_bus) { + iter->rcode = RCODE_COMPLETE; + list_del(&iter->link); + orb = iter; break; } } spin_unlock_irqrestore(&lu->tgt->lock, flags); - if (&orb->link != &lu->orb_list) { + if (orb) { orb->callback(orb, &status); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { --- linux-oracle-5.4.0.orig/drivers/firmware/Kconfig +++ linux-oracle-5.4.0/drivers/firmware/Kconfig @@ -170,7 +170,7 @@ select ISCSI_BOOT_SYSFS select ISCSI_IBFT_FIND if X86 depends on ACPI && SCSI && SCSI_LOWLEVEL - default n + default n help This option enables support for detection and exposing of iSCSI Boot Firmware Table (iBFT) via sysfs to userspace. If you wish to @@ -237,6 +237,7 @@ config QCOM_SCM bool depends on ARM || ARM64 + depends on HAVE_ARM_SMCCC select RESET_CONTROLLER config QCOM_SCM_32 --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/base.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/base.c @@ -164,7 +164,7 @@ break; loop_num_ret = le32_to_cpu(*num_ret); - if (tot_num_ret + loop_num_ret > MAX_PROTOCOLS_IMP) { + if (loop_num_ret > MAX_PROTOCOLS_IMP - tot_num_ret) { dev_err(dev, "No. of Protocol > MAX_PROTOCOLS_IMP"); break; } @@ -173,6 +173,8 @@ protocols_imp[tot_num_ret + loop] = *(list + loop); tot_num_ret += loop_num_ret; + + scmi_reset_rx_to_maxsz(handle, t); } while (loop_num_ret); scmi_xfer_put(handle, t); --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/bus.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/bus.c @@ -100,6 +100,9 @@ { int retval; + if (!driver->probe) + return -EINVAL; + driver->driver.bus = &scmi_bus_type; driver->driver.name = driver->name; driver->driver.owner = owner; @@ -135,8 +138,10 @@ return NULL; id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL); - if (id < 0) - goto free_mem; + if (id < 0) { + kfree(scmi_dev); + return NULL; + } scmi_dev->id = id; scmi_dev->protocol_id = protocol; @@ -154,8 +159,6 @@ put_dev: put_device(&scmi_dev->dev); ida_simple_remove(&scmi_bus_id, id); -free_mem: - kfree(scmi_dev); return NULL; } --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/clock.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/clock.c @@ -177,6 +177,8 @@ } tot_rate_cnt += num_returned; + + scmi_reset_rx_to_maxsz(handle, t); /* * check for both returned and remaining to avoid infinite * loop due to buggy firmware --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/common.h +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/common.h @@ -103,6 +103,8 @@ struct scmi_xfer *xfer); int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id, size_t tx_size, size_t rx_size, struct scmi_xfer **p); +void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle, + struct scmi_xfer *xfer); int scmi_handle_put(const struct scmi_handle *handle); struct scmi_handle *scmi_handle_get(struct device *dev); void scmi_set_handle(struct scmi_device *scmi_dev); --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/driver.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/driver.c @@ -54,7 +54,6 @@ SCMI_ERR_GENERIC = -8, /* Generic Error */ SCMI_ERR_HARDWARE = -9, /* Hardware Error */ SCMI_ERR_PROTOCOL = -10,/* Protocol Error */ - SCMI_ERR_MAX }; /* List of all SCMI devices active in system */ @@ -176,8 +175,10 @@ static inline int scmi_to_linux_errno(int errno) { - if (errno < SCMI_SUCCESS && errno > SCMI_ERR_MAX) - return scmi_linux_errmap[-errno]; + int err_idx = -errno; + + if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap)) + return scmi_linux_errmap[err_idx]; return -EIO; } @@ -370,6 +371,10 @@ xfer = &minfo->xfer_block[xfer_id]; + /* rx.len could be shrunk in the sync do_xfer, so reset to maxsz */ + if (msg_type == MSG_TYPE_DELAYED_RESP) + xfer->rx.len = info->desc->max_msg_size; + scmi_dump_header_dbg(dev, &xfer->hdr); scmi_fetch_response(xfer, mem); @@ -481,6 +486,14 @@ return ret; } +void scmi_reset_rx_to_maxsz(const struct scmi_handle *handle, + struct scmi_xfer *xfer) +{ + struct scmi_info *info = handle_to_scmi_info(handle); + + xfer->rx.len = info->desc->max_msg_size; +} + #define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC) /** @@ -502,8 +515,12 @@ xfer->async_done = &async_response; ret = scmi_do_xfer(handle, xfer); - if (!ret && !wait_for_completion_timeout(xfer->async_done, timeout)) - ret = -ETIMEDOUT; + if (!ret) { + if (!wait_for_completion_timeout(xfer->async_done, timeout)) + ret = -ETIMEDOUT; + else if (xfer->hdr.status) + ret = scmi_to_linux_errno(xfer->hdr.status); + } xfer->async_done = NULL; return ret; @@ -681,8 +698,9 @@ struct scmi_xfers_info *info = &sinfo->tx_minfo; /* Pre-allocated messages, no more than what hdr.seq can support */ - if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) { - dev_err(dev, "Maximum message of %d exceeds supported %ld\n", + if (WARN_ON(!desc->max_msg || desc->max_msg > MSG_TOKEN_MAX)) { + dev_err(dev, + "Invalid maximum messages %d, not in range [1 - %lu]\n", desc->max_msg, MSG_TOKEN_MAX); return -EINVAL; } @@ -719,6 +737,39 @@ idx, NULL); } +static int scmi_mailbox_chan_validate(struct device *cdev) +{ + int num_mb, num_sh, ret = 0; + struct device_node *np = cdev->of_node; + + num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); + num_sh = of_count_phandle_with_args(np, "shmem", NULL); + /* Bail out if mboxes and shmem descriptors are inconsistent */ + if (num_mb <= 0 || num_sh > 2 || num_mb != num_sh) { + dev_warn(cdev, "Invalid channel descriptor for '%s'\n", + of_node_full_name(np)); + return -EINVAL; + } + + if (num_sh > 1) { + struct device_node *np_tx, *np_rx; + + np_tx = of_parse_phandle(np, "shmem", 0); + np_rx = of_parse_phandle(np, "shmem", 1); + /* SCMI Tx and Rx shared mem areas have to be distinct */ + if (!np_tx || !np_rx || np_tx == np_rx) { + dev_warn(cdev, "Invalid shmem descriptor for '%s'\n", + of_node_full_name(np)); + ret = -EINVAL; + } + + of_node_put(np_tx); + of_node_put(np_rx); + } + + return ret; +} + static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id, bool tx) { @@ -742,6 +793,10 @@ goto idr_alloc; } + ret = scmi_mailbox_chan_validate(dev); + if (ret) + return ret; + cinfo = devm_kzalloc(info->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) return -ENOMEM; @@ -965,7 +1020,7 @@ module_platform_driver(scmi_driver); -MODULE_ALIAS("platform: arm-scmi"); +MODULE_ALIAS("platform:arm-scmi"); MODULE_AUTHOR("Sudeep Holla "); MODULE_DESCRIPTION("ARM SCMI protocol driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/perf.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/perf.c @@ -281,6 +281,8 @@ } tot_opp_cnt += num_returned; + + scmi_reset_rx_to_maxsz(handle, t); /* * check for both returned and remaining to avoid infinite * loop due to buggy firmware @@ -323,7 +325,7 @@ if (db->mask) val = ioread64_hi_lo(db->addr) & db->mask; - iowrite64_hi_lo(db->set, db->addr); + iowrite64_hi_lo(db->set | val, db->addr); } #endif } --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/reset.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/reset.c @@ -35,9 +35,7 @@ #define EXPLICIT_RESET_ASSERT BIT(1) #define ASYNCHRONOUS_RESET BIT(2) __le32 reset_state; -#define ARCH_RESET_TYPE BIT(31) -#define COLD_RESET_STATE BIT(0) -#define ARCH_COLD_RESET (ARCH_RESET_TYPE | COLD_RESET_STATE) +#define ARCH_COLD_RESET 0 }; struct reset_dom_info { @@ -137,8 +135,12 @@ struct scmi_xfer *t; struct scmi_msg_reset_domain_reset *dom; struct scmi_reset_info *pi = handle->reset_priv; - struct reset_dom_info *rdom = pi->dom_info + domain; + struct reset_dom_info *rdom; + if (domain >= pi->num_domains) + return -EINVAL; + + rdom = pi->dom_info + domain; if (rdom->async_reset) flags |= ASYNCHRONOUS_RESET; --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/scmi_pm_domain.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/scmi_pm_domain.c @@ -85,7 +85,10 @@ for (i = 0; i < num_domains; i++, scmi_pd++) { u32 state; - domains[i] = &scmi_pd->genpd; + if (handle->power_ops->state_get(handle, i, &state)) { + dev_warn(dev, "failed to get state for domain %d\n", i); + continue; + } scmi_pd->domain = i; scmi_pd->handle = handle; @@ -94,21 +97,35 @@ scmi_pd->genpd.power_off = scmi_pd_power_off; scmi_pd->genpd.power_on = scmi_pd_power_on; - if (handle->power_ops->state_get(handle, i, &state)) { - dev_warn(dev, "failed to get state for domain %d\n", i); - continue; - } - pm_genpd_init(&scmi_pd->genpd, NULL, state == SCMI_POWER_STATE_GENERIC_OFF); + + domains[i] = &scmi_pd->genpd; } scmi_pd_data->domains = domains; scmi_pd_data->num_domains = num_domains; - of_genpd_add_provider_onecell(np, scmi_pd_data); + dev_set_drvdata(dev, scmi_pd_data); - return 0; + return of_genpd_add_provider_onecell(np, scmi_pd_data); +} + +static void scmi_pm_domain_remove(struct scmi_device *sdev) +{ + int i; + struct genpd_onecell_data *scmi_pd_data; + struct device *dev = &sdev->dev; + struct device_node *np = dev->of_node; + + of_genpd_del_provider(np); + + scmi_pd_data = dev_get_drvdata(dev); + for (i = 0; i < scmi_pd_data->num_domains; i++) { + if (!scmi_pd_data->domains[i]) + continue; + pm_genpd_remove(scmi_pd_data->domains[i]); + } } static const struct scmi_device_id scmi_id_table[] = { @@ -120,6 +137,7 @@ static struct scmi_driver scmi_power_domain_driver = { .name = "scmi-power-domain", .probe = scmi_pm_domain_probe, + .remove = scmi_pm_domain_remove, .id_table = scmi_id_table, }; module_scmi_driver(scmi_power_domain_driver); --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scmi/sensors.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scmi/sensors.c @@ -154,6 +154,8 @@ } desc_index += num_returned; + + scmi_reset_rx_to_maxsz(handle, t); /* * check for both returned and remaining to avoid infinite * loop due to buggy firmware --- linux-oracle-5.4.0.orig/drivers/firmware/arm_scpi.c +++ linux-oracle-5.4.0/drivers/firmware/arm_scpi.c @@ -552,8 +552,10 @@ ret = scpi_send_message(CMD_GET_CLOCK_VALUE, &le_clk_id, sizeof(le_clk_id), &rate, sizeof(rate)); + if (ret) + return 0; - return ret ? ret : le32_to_cpu(rate); + return le32_to_cpu(rate); } static int scpi_clk_set_val(u16 clk_id, unsigned long rate) @@ -625,6 +627,9 @@ if (ret) return ERR_PTR(ret); + if (!buf.opp_count) + return ERR_PTR(-ENOENT); + info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return ERR_PTR(-ENOMEM); @@ -813,7 +818,7 @@ info->firmware_version = le32_to_cpu(caps.platform_version); } /* Ignore error if not implemented */ - if (scpi_info->is_legacy && ret == -EOPNOTSUPP) + if (info->is_legacy && ret == -EOPNOTSUPP) return 0; return ret; @@ -903,13 +908,14 @@ struct resource res; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + struct scpi_drvinfo *scpi_drvinfo; - scpi_info = devm_kzalloc(dev, sizeof(*scpi_info), GFP_KERNEL); - if (!scpi_info) + scpi_drvinfo = devm_kzalloc(dev, sizeof(*scpi_drvinfo), GFP_KERNEL); + if (!scpi_drvinfo) return -ENOMEM; if (of_match_device(legacy_scpi_of_match, &pdev->dev)) - scpi_info->is_legacy = true; + scpi_drvinfo->is_legacy = true; count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); if (count < 0) { @@ -917,19 +923,19 @@ return -ENODEV; } - scpi_info->channels = devm_kcalloc(dev, count, sizeof(struct scpi_chan), - GFP_KERNEL); - if (!scpi_info->channels) + scpi_drvinfo->channels = + devm_kcalloc(dev, count, sizeof(struct scpi_chan), GFP_KERNEL); + if (!scpi_drvinfo->channels) return -ENOMEM; - ret = devm_add_action(dev, scpi_free_channels, scpi_info); + ret = devm_add_action(dev, scpi_free_channels, scpi_drvinfo); if (ret) return ret; - for (; scpi_info->num_chans < count; scpi_info->num_chans++) { + for (; scpi_drvinfo->num_chans < count; scpi_drvinfo->num_chans++) { resource_size_t size; - int idx = scpi_info->num_chans; - struct scpi_chan *pchan = scpi_info->channels + idx; + int idx = scpi_drvinfo->num_chans; + struct scpi_chan *pchan = scpi_drvinfo->channels + idx; struct mbox_client *cl = &pchan->cl; struct device_node *shmem = of_parse_phandle(np, "shmem", idx); @@ -973,45 +979,53 @@ return ret; } - scpi_info->commands = scpi_std_commands; + scpi_drvinfo->commands = scpi_std_commands; - platform_set_drvdata(pdev, scpi_info); + platform_set_drvdata(pdev, scpi_drvinfo); - if (scpi_info->is_legacy) { + if (scpi_drvinfo->is_legacy) { /* Replace with legacy variants */ scpi_ops.clk_set_val = legacy_scpi_clk_set_val; - scpi_info->commands = scpi_legacy_commands; + scpi_drvinfo->commands = scpi_legacy_commands; /* Fill priority bitmap */ for (idx = 0; idx < ARRAY_SIZE(legacy_hpriority_cmds); idx++) set_bit(legacy_hpriority_cmds[idx], - scpi_info->cmd_priority); + scpi_drvinfo->cmd_priority); } - ret = scpi_init_versions(scpi_info); + scpi_info = scpi_drvinfo; + + ret = scpi_init_versions(scpi_drvinfo); if (ret) { dev_err(dev, "incorrect or no SCP firmware found\n"); + scpi_info = NULL; return ret; } - if (scpi_info->is_legacy && !scpi_info->protocol_version && - !scpi_info->firmware_version) + if (scpi_drvinfo->is_legacy && !scpi_drvinfo->protocol_version && + !scpi_drvinfo->firmware_version) dev_info(dev, "SCP Protocol legacy pre-1.0 firmware\n"); else dev_info(dev, "SCP Protocol %lu.%lu Firmware %lu.%lu.%lu version\n", FIELD_GET(PROTO_REV_MAJOR_MASK, - scpi_info->protocol_version), + scpi_drvinfo->protocol_version), FIELD_GET(PROTO_REV_MINOR_MASK, - scpi_info->protocol_version), + scpi_drvinfo->protocol_version), FIELD_GET(FW_REV_MAJOR_MASK, - scpi_info->firmware_version), + scpi_drvinfo->firmware_version), FIELD_GET(FW_REV_MINOR_MASK, - scpi_info->firmware_version), + scpi_drvinfo->firmware_version), FIELD_GET(FW_REV_PATCH_MASK, - scpi_info->firmware_version)); - scpi_info->scpi_ops = &scpi_ops; + scpi_drvinfo->firmware_version)); - return devm_of_platform_populate(dev); + scpi_drvinfo->scpi_ops = &scpi_ops; + + ret = devm_of_platform_populate(dev); + if (ret) + scpi_info = NULL; + + return ret; } static const struct of_device_id scpi_of_match[] = { --- linux-oracle-5.4.0.orig/drivers/firmware/arm_sdei.c +++ linux-oracle-5.4.0/drivers/firmware/arm_sdei.c @@ -44,6 +44,8 @@ /* entry point from firmware to arch asm code */ static unsigned long sdei_entry_point; +static int sdei_hp_state; + struct sdei_event { /* These three are protected by the sdei_list_lock */ struct list_head list; @@ -305,8 +307,6 @@ { int err; - WARN_ON_ONCE(preemptible()); - err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL); if (err && err != -EIO) { pr_warn_once("failed to mask CPU[%u]: %d\n", @@ -319,6 +319,7 @@ static void _ipi_mask_cpu(void *ignored) { + WARN_ON_ONCE(preemptible()); sdei_mask_local_cpu(); } @@ -326,8 +327,6 @@ { int err; - WARN_ON_ONCE(preemptible()); - err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL); if (err && err != -EIO) { pr_warn_once("failed to unmask CPU[%u]: %d\n", @@ -340,6 +339,7 @@ static void _ipi_unmask_cpu(void *ignored) { + WARN_ON_ONCE(preemptible()); sdei_unmask_local_cpu(); } @@ -347,6 +347,8 @@ { int err; + WARN_ON_ONCE(preemptible()); + err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0, NULL); if (err && err != -EIO) @@ -393,8 +395,6 @@ int err; struct sdei_crosscall_args *arg = data; - WARN_ON_ONCE(preemptible()); - err = sdei_api_event_enable(arg->event->event_num); sdei_cross_call_return(arg, err); @@ -412,14 +412,19 @@ return -ENOENT; } - spin_lock(&sdei_list_lock); - event->reenable = true; - spin_unlock(&sdei_list_lock); + cpus_read_lock(); if (event->type == SDEI_EVENT_TYPE_SHARED) err = sdei_api_event_enable(event->event_num); else err = sdei_do_cross_call(_local_event_enable, event); + + if (!err) { + spin_lock(&sdei_list_lock); + event->reenable = true; + spin_unlock(&sdei_list_lock); + } + cpus_read_unlock(); mutex_unlock(&sdei_events_lock); return err; @@ -480,8 +485,6 @@ int err; struct sdei_crosscall_args *arg = data; - WARN_ON_ONCE(preemptible()); - err = sdei_api_event_unregister(arg->event->event_num); sdei_cross_call_return(arg, err); @@ -491,11 +494,6 @@ { lockdep_assert_held(&sdei_events_lock); - spin_lock(&sdei_list_lock); - event->reregister = false; - event->reenable = false; - spin_unlock(&sdei_list_lock); - if (event->type == SDEI_EVENT_TYPE_SHARED) return sdei_api_event_unregister(event->event_num); @@ -518,6 +516,11 @@ break; } + spin_lock(&sdei_list_lock); + event->reregister = false; + event->reenable = false; + spin_unlock(&sdei_list_lock); + err = _sdei_event_unregister(event); if (err) break; @@ -570,8 +573,6 @@ struct sdei_registered_event *reg; struct sdei_crosscall_args *arg = data; - WARN_ON(preemptible()); - reg = per_cpu_ptr(arg->event->private_registered, smp_processor_id()); err = sdei_api_event_register(arg->event->event_num, sdei_entry_point, reg, 0, 0); @@ -585,26 +586,15 @@ lockdep_assert_held(&sdei_events_lock); - spin_lock(&sdei_list_lock); - event->reregister = true; - spin_unlock(&sdei_list_lock); - if (event->type == SDEI_EVENT_TYPE_SHARED) return sdei_api_event_register(event->event_num, sdei_entry_point, event->registered, SDEI_EVENT_REGISTER_RM_ANY, 0); - err = sdei_do_cross_call(_local_event_register, event); - if (err) { - spin_lock(&sdei_list_lock); - event->reregister = false; - event->reenable = false; - spin_unlock(&sdei_list_lock); - + if (err) sdei_do_cross_call(_local_event_unregister, event); - } return err; } @@ -632,12 +622,18 @@ break; } + cpus_read_lock(); err = _sdei_event_register(event); if (err) { sdei_event_destroy(event); pr_warn("Failed to register event %u: %d\n", event_num, err); + } else { + spin_lock(&sdei_list_lock); + event->reregister = true; + spin_unlock(&sdei_list_lock); } + cpus_read_unlock(); } while (0); mutex_unlock(&sdei_events_lock); @@ -756,6 +752,8 @@ { int rv; + WARN_ON_ONCE(preemptible()); + switch (action) { case CPU_PM_ENTER: rv = sdei_mask_local_cpu(); @@ -804,7 +802,7 @@ int err; /* unregister private events */ - cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING); + cpuhp_remove_state(sdei_hp_state); err = sdei_unregister_shared(); if (err) @@ -825,12 +823,15 @@ return err; } - err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI", + err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI", &sdei_cpuhp_up, &sdei_cpuhp_down); - if (err) + if (err < 0) { pr_warn("Failed to re-register CPU hotplug notifier...\n"); + return err; + } - return err; + sdei_hp_state = err; + return 0; } static int sdei_device_restore(struct device *dev) @@ -862,7 +863,7 @@ * We are going to reset the interface, after this there is no point * doing work when we take CPUs offline. */ - cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING); + cpuhp_remove_state(sdei_hp_state); sdei_platform_reset(); @@ -1044,13 +1045,15 @@ goto remove_cpupm; } - err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI", + err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "SDEI", &sdei_cpuhp_up, &sdei_cpuhp_down); - if (err) { + if (err < 0) { pr_warn("Failed to register CPU hotplug notifier...\n"); goto remove_reboot; } + sdei_hp_state = err; + return 0; remove_reboot: --- linux-oracle-5.4.0.orig/drivers/firmware/dmi-id.c +++ linux-oracle-5.4.0/drivers/firmware/dmi-id.c @@ -160,9 +160,14 @@ return 0; } +static void dmi_dev_release(struct device *dev) +{ + kfree(dev); +} + static struct class dmi_class = { .name = "dmi", - .dev_release = (void(*)(struct device *)) kfree, + .dev_release = dmi_dev_release, .dev_uevent = dmi_dev_uevent, }; --- linux-oracle-5.4.0.orig/drivers/firmware/dmi-sysfs.c +++ linux-oracle-5.4.0/drivers/firmware/dmi-sysfs.c @@ -603,7 +603,7 @@ "%d-%d", dh->type, entry->instance); if (*ret) { - kfree(entry); + kobject_put(&entry->kobj); return; } --- linux-oracle-5.4.0.orig/drivers/firmware/dmi_scan.c +++ linux-oracle-5.4.0/drivers/firmware/dmi_scan.c @@ -97,6 +97,17 @@ const struct dmi_header *dm = (const struct dmi_header *)data; /* + * If a short entry is found (less than 4 bytes), not only it + * is invalid, but we cannot reliably locate the next entry. + */ + if (dm->length < sizeof(struct dmi_header)) { + pr_warn(FW_BUG + "Corrupted DMI table, offset %zd (only %d entries processed)\n", + data - buf, i); + break; + } + + /* * We want to know the total length (formatted area and * strings) before decoding to make sure we won't run off the * table in dmi_decode or dmi_string --- linux-oracle-5.4.0.orig/drivers/firmware/efi/Kconfig +++ linux-oracle-5.4.0/drivers/firmware/efi/Kconfig @@ -216,6 +216,17 @@ config EFI_EARLYCON def_bool y - depends on SERIAL_EARLYCON && !ARM && !IA64 + depends on EFI && SERIAL_EARLYCON && !ARM && !IA64 select FONT_SUPPORT select ARCH_USE_MEMREMAP_PROT + +config EFI_CUSTOM_SSDT_OVERLAYS + bool "Load custom ACPI SSDT overlay from an EFI variable" + depends on EFI_VARS && ACPI + default ACPI_TABLE_UPGRADE + help + Allow loading of an ACPI SSDT overlay from an EFI variable specified + by a kernel command line option. + + See Documentation/admin-guide/acpi/ssdt-overlays.rst for more + information. --- linux-oracle-5.4.0.orig/drivers/firmware/efi/Makefile +++ linux-oracle-5.4.0/drivers/firmware/efi/Makefile @@ -24,8 +24,10 @@ obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o obj-$(CONFIG_EFI_TEST) += test/ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o +obj-$(CONFIG_EFI) += secureboot.o obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o +obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y) --- linux-oracle-5.4.0.orig/drivers/firmware/efi/apple-properties.c +++ linux-oracle-5.4.0/drivers/firmware/efi/apple-properties.c @@ -23,7 +23,7 @@ static int __init dump_properties_enable(char *arg) { dump_properties = true; - return 0; + return 1; } __setup("dump_apple_properties", dump_properties_enable); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/arm-init.c +++ linux-oracle-5.4.0/drivers/firmware/efi/arm-init.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -253,8 +254,16 @@ return; } + efi_set_secure_boot(params.secure_boot); + +#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT + if (efi_enabled(EFI_SECURE_BOOT)) + security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX); +#endif + reserve_regions(); efi_esrt_init(); + efi_mokvar_table_init(); memblock_reserve(params.mmap & PAGE_MASK, PAGE_ALIGN(params.mmap_size + --- linux-oracle-5.4.0.orig/drivers/firmware/efi/capsule-loader.c +++ linux-oracle-5.4.0/drivers/firmware/efi/capsule-loader.c @@ -242,29 +242,6 @@ } /** - * efi_capsule_flush - called by file close or file flush - * @file: file pointer - * @id: not used - * - * If a capsule is being partially uploaded then calling this function - * will be treated as upload termination and will free those completed - * buffer pages and -ECANCELED will be returned. - **/ -static int efi_capsule_flush(struct file *file, fl_owner_t id) -{ - int ret = 0; - struct capsule_info *cap_info = file->private_data; - - if (cap_info->index > 0) { - pr_err("capsule upload not complete\n"); - efi_free_all_buff_pages(cap_info); - ret = -ECANCELED; - } - - return ret; -} - -/** * efi_capsule_release - called by file close * @inode: not used * @file: file pointer @@ -276,6 +253,13 @@ { struct capsule_info *cap_info = file->private_data; + if (cap_info->index > 0 && + (cap_info->header.headersize == 0 || + cap_info->count < cap_info->total_size)) { + pr_err("capsule upload not complete\n"); + efi_free_all_buff_pages(cap_info); + } + kfree(cap_info->pages); kfree(cap_info->phys); kfree(file->private_data); @@ -307,7 +291,7 @@ return -ENOMEM; } - cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL); + cap_info->phys = kzalloc(sizeof(phys_addr_t), GFP_KERNEL); if (!cap_info->phys) { kfree(cap_info->pages); kfree(cap_info); @@ -323,7 +307,6 @@ .owner = THIS_MODULE, .open = efi_capsule_open, .write = efi_capsule_write, - .flush = efi_capsule_flush, .release = efi_capsule_release, .llseek = no_llseek, }; --- linux-oracle-5.4.0.orig/drivers/firmware/efi/cper.c +++ linux-oracle-5.4.0/drivers/firmware/efi/cper.c @@ -25,8 +25,6 @@ #include #include -static char rcd_decode_str[CPER_REC_LEN]; - /* * CPER record ID need to be unique even after reboot, because record * ID is used as index for ERST storage, while CPER records from @@ -263,8 +261,7 @@ if (!msg || !(mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE)) return 0; - n = 0; - len = CPER_REC_LEN - 1; + len = CPER_REC_LEN; dmi_memdev_name(mem->mem_dev_handle, &bank, &device); if (bank && device) n = snprintf(msg, len, "DIMM location: %s %s ", bank, device); @@ -273,7 +270,6 @@ "DIMM location: not present. DMI handle: 0x%.4x ", mem->mem_dev_handle); - msg[n] = '\0'; return n; } @@ -301,6 +297,7 @@ struct cper_mem_err_compact *cmem) { const char *ret = trace_seq_buffer_ptr(p); + char rcd_decode_str[CPER_REC_LEN]; if (cper_mem_err_location(cmem, rcd_decode_str)) trace_seq_printf(p, "%s", rcd_decode_str); @@ -315,6 +312,7 @@ int len) { struct cper_mem_err_compact cmem; + char rcd_decode_str[CPER_REC_LEN]; /* Don't trust UEFI 2.1/2.2 structure with bad validation bits */ if (len == sizeof(struct cper_sec_mem_err_old) && --- linux-oracle-5.4.0.orig/drivers/firmware/efi/earlycon.c +++ linux-oracle-5.4.0/drivers/firmware/efi/earlycon.c @@ -13,18 +13,58 @@ #include +static const struct console *earlycon_console __initdata; static const struct font_desc *font; static u32 efi_x, efi_y; static u64 fb_base; -static pgprot_t fb_prot; +static bool fb_wb; +static void *efi_fb; + +/* + * EFI earlycon needs to use early_memremap() to map the framebuffer. + * But early_memremap() is not usable for 'earlycon=efifb keep_bootcon', + * memremap() should be used instead. memremap() will be available after + * paging_init() which is earlier than initcall callbacks. Thus adding this + * early initcall function early_efi_map_fb() to map the whole EFI framebuffer. + */ +static int __init efi_earlycon_remap_fb(void) +{ + /* bail if there is no bootconsole or it has been disabled already */ + if (!earlycon_console || !(earlycon_console->flags & CON_ENABLED)) + return 0; + + efi_fb = memremap(fb_base, screen_info.lfb_size, + fb_wb ? MEMREMAP_WB : MEMREMAP_WC); + + return efi_fb ? 0 : -ENOMEM; +} +early_initcall(efi_earlycon_remap_fb); + +static int __init efi_earlycon_unmap_fb(void) +{ + /* unmap the bootconsole fb unless keep_bootcon has left it enabled */ + if (efi_fb && !(earlycon_console->flags & CON_ENABLED)) + memunmap(efi_fb); + return 0; +} +late_initcall(efi_earlycon_unmap_fb); static __ref void *efi_earlycon_map(unsigned long start, unsigned long len) { + pgprot_t fb_prot; + + if (efi_fb) + return efi_fb + start; + + fb_prot = fb_wb ? PAGE_KERNEL : pgprot_writecombine(PAGE_KERNEL); return early_memremap_prot(fb_base + start, len, pgprot_val(fb_prot)); } static __ref void efi_earlycon_unmap(void *addr, unsigned long len) { + if (efi_fb) + return; + early_memunmap(addr, len); } @@ -176,10 +216,7 @@ if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) fb_base |= (u64)screen_info.ext_lfb_base << 32; - if (opt && !strcmp(opt, "ram")) - fb_prot = PAGE_KERNEL; - else - fb_prot = pgprot_writecombine(PAGE_KERNEL); + fb_wb = opt && !strcmp(opt, "ram"); si = &screen_info; xres = si->lfb_width; @@ -201,6 +238,7 @@ efi_earlycon_scroll_up(); device->con->write = efi_earlycon_write; + earlycon_console = device->con; return 0; } EARLYCON_DECLARE(efifb, efi_earlycon_setup); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/efi.c +++ linux-oracle-5.4.0/drivers/firmware/efi/efi.c @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -52,6 +53,9 @@ .rng_seed = EFI_INVALID_TABLE_ADDR, .tpm_log = EFI_INVALID_TABLE_ADDR, .tpm_final_log = EFI_INVALID_TABLE_ADDR, +#ifdef CONFIG_LOAD_UEFI_KEYS + .mokvar_table = EFI_INVALID_TABLE_ADDR, +#endif .mem_reserve = EFI_INVALID_TABLE_ADDR, }; EXPORT_SYMBOL(efi); @@ -217,7 +221,7 @@ efivars_unregister(&generic_efivars); } -#if IS_ENABLED(CONFIG_ACPI) +#ifdef CONFIG_EFI_CUSTOM_SSDT_OVERLAYS #define EFIVAR_SSDT_NAME_MAX 16 static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata; static int __init efivar_ssdt_setup(char *str) @@ -231,7 +235,7 @@ memcpy(efivar_ssdt, str, strlen(str)); else pr_warn("efivar_ssdt: name too long: %s\n", str); - return 0; + return 1; } __setup("efivar_ssdt=", efivar_ssdt_setup); @@ -345,7 +349,8 @@ efi_kobj = kobject_create_and_add("efi", firmware_kobj); if (!efi_kobj) { pr_err("efi: Firmware registration failed.\n"); - return -ENOMEM; + error = -ENOMEM; + goto err_destroy_wq; } error = generic_ops_register(); @@ -381,6 +386,10 @@ generic_ops_unregister(); err_put: kobject_put(efi_kobj); +err_destroy_wq: + if (efi_rts_wq) + destroy_workqueue(efi_rts_wq); + return error; } @@ -477,6 +486,9 @@ #ifdef CONFIG_EFI_RCI2_TABLE {DELLEMC_EFI_RCI2_TABLE_GUID, NULL, &rci2_table_phys}, #endif +#ifdef CONFIG_LOAD_UEFI_KEYS + {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, "MOKvar", &efi.mokvar_table}, +#endif {NULL_GUID, NULL, NULL}, }; @@ -544,7 +556,7 @@ seed = early_memremap(efi.rng_seed, sizeof(*seed)); if (seed != NULL) { - size = seed->size; + size = min(seed->size, EFI_RANDOM_SEED_SIZE); early_memunmap(seed, sizeof(*seed)); } else { pr_err("Could not map UEFI random seed!\n"); @@ -554,7 +566,7 @@ sizeof(*seed) + size); if (seed != NULL) { pr_notice("seeding entropy pool\n"); - add_bootloader_randomness(seed->bits, seed->size); + add_bootloader_randomness(seed->bits, size); early_memunmap(seed, sizeof(*seed) + size); } else { pr_err("Could not map UEFI random seed!\n"); @@ -562,7 +574,7 @@ } } - if (efi_enabled(EFI_MEMMAP)) + if (!IS_ENABLED(CONFIG_X86_32) && efi_enabled(EFI_MEMMAP)) efi_memattr_init(); efi_tpm_eventlog_init(); @@ -688,7 +700,8 @@ UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), - UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) + UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver), + UEFI_PARAM("Secure Boot Enabled", "linux,uefi-secure-boot", secure_boot) }; static __initdata struct params xen_fdt_params[] = { @@ -918,40 +931,101 @@ } #endif +struct efi_error_code { + efi_status_t status; + int errno; + const char *description; +}; + +static const struct efi_error_code efi_error_codes[] = { + { EFI_SUCCESS, 0, "Success"}, +#if 0 + { EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"}, +#endif + { EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"}, + { EFI_UNSUPPORTED, -ENOSYS, "Unsupported"}, + { EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"}, + { EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"}, + { EFI_NOT_READY, -EAGAIN, "Not Ready"}, + { EFI_DEVICE_ERROR, -EIO, "Device Error"}, + { EFI_WRITE_PROTECTED, -EROFS, "Write Protected"}, + { EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"}, +#if 0 + { EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"}, + { EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"}, + { EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"}, + { EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"}, +#endif + { EFI_NOT_FOUND, -ENOENT, "Not Found"}, +#if 0 + { EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"}, + { EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"}, + { EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"}, + { EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"}, + { EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"}, + { EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"}, +#endif + { EFI_ABORTED, -EINTR, "Aborted"}, +#if 0 + { EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"}, + { EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"}, + { EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"}, + { EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"}, +#endif + { EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"}, +#if 0 + { EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"}, + { EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"}, + { EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"}, + { EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"}, + { EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"}, + + // warnings + { EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"}, + { EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"}, + { EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"}, + { EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"}, +#endif +}; + +static int +efi_status_cmp_bsearch(const void *key, const void *item) +{ + u64 status = (u64)(uintptr_t)key; + struct efi_error_code *code = (struct efi_error_code *)item; + + if (status < code->status) + return -1; + if (status > code->status) + return 1; + return 0; +} + int efi_status_to_err(efi_status_t status) { - int err; + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - switch (status) { - case EFI_SUCCESS: - err = 0; - break; - case EFI_INVALID_PARAMETER: - err = -EINVAL; - break; - case EFI_OUT_OF_RESOURCES: - err = -ENOSPC; - break; - case EFI_DEVICE_ERROR: - err = -EIO; - break; - case EFI_WRITE_PROTECTED: - err = -EROFS; - break; - case EFI_SECURITY_VIOLATION: - err = -EACCES; - break; - case EFI_NOT_FOUND: - err = -ENOENT; - break; - case EFI_ABORTED: - err = -EINTR; - break; - default: - err = -EINVAL; - } + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return -EINVAL; + return found->errno; +} + +const char * +efi_status_to_str(efi_status_t status) +{ + struct efi_error_code *found; + size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); - return err; + found = bsearch((void *)(uintptr_t)status, efi_error_codes, + sizeof(struct efi_error_code), num, + efi_status_cmp_bsearch); + if (!found) + return "Unknown error code"; + return found->description; } static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock); @@ -970,6 +1044,35 @@ return 0; } +static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) +{ + struct resource *res, *parent; + int ret; + + res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + if (!res) + return -ENOMEM; + + res->name = "reserved"; + res->flags = IORESOURCE_MEM; + res->start = addr; + res->end = addr + size - 1; + + /* we expect a conflict with a 'System RAM' region */ + parent = request_resource_conflict(&iomem_resource, res); + ret = parent ? request_resource(parent, res) : 0; + + /* + * Given that efi_mem_reserve_iomem() can be called at any + * time, only call memblock_reserve() if the architecture + * keeps the infrastructure around. + */ + if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !ret) + memblock_reserve(addr, size); + + return ret; +} + int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) { struct linux_efi_memreserve *rsv; @@ -986,16 +1089,19 @@ } /* first try to find a slot in an existing linked list entry */ - for (prsv = efi_memreserve_root->next; prsv; prsv = rsv->next) { + for (prsv = efi_memreserve_root->next; prsv; ) { rsv = memremap(prsv, sizeof(*rsv), MEMREMAP_WB); + if (!rsv) + return -ENOMEM; index = atomic_fetch_add_unless(&rsv->count, 1, rsv->size); if (index < rsv->size) { rsv->entry[index].base = addr; rsv->entry[index].size = size; memunmap(rsv); - return 0; + return efi_mem_reserve_iomem(addr, size); } + prsv = rsv->next; memunmap(rsv); } @@ -1004,6 +1110,12 @@ if (!rsv) return -ENOMEM; + rc = efi_mem_reserve_iomem(__pa(rsv), SZ_4K); + if (rc) { + free_page((unsigned long)rsv); + return rc; + } + /* * The memremap() call above assumes that a linux_efi_memreserve entry * never crosses a page boundary, so let's ensure that this remains true @@ -1020,7 +1132,7 @@ efi_memreserve_root->next = __pa(rsv); spin_unlock(&efi_mem_reserve_persistent_lock); - return 0; + return efi_mem_reserve_iomem(addr, size); } static int __init efi_memreserve_root_init(void) --- linux-oracle-5.4.0.orig/drivers/firmware/efi/efivars.c +++ linux-oracle-5.4.0/drivers/firmware/efi/efivars.c @@ -83,13 +83,16 @@ efivar_attr_read(struct efivar_entry *entry, char *buf) { struct efi_variable *var = &entry->var; + unsigned long size = sizeof(var->Data); char *str = buf; + int ret; if (!entry || !buf) return -EINVAL; - var->DataSize = 1024; - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); + var->DataSize = size; + if (ret) return -EIO; if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) @@ -116,13 +119,16 @@ efivar_size_read(struct efivar_entry *entry, char *buf) { struct efi_variable *var = &entry->var; + unsigned long size = sizeof(var->Data); char *str = buf; + int ret; if (!entry || !buf) return -EINVAL; - var->DataSize = 1024; - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); + var->DataSize = size; + if (ret) return -EIO; str += sprintf(str, "0x%lx\n", var->DataSize); @@ -133,12 +139,15 @@ efivar_data_read(struct efivar_entry *entry, char *buf) { struct efi_variable *var = &entry->var; + unsigned long size = sizeof(var->Data); + int ret; if (!entry || !buf) return -EINVAL; - var->DataSize = 1024; - if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); + var->DataSize = size; + if (ret) return -EIO; memcpy(buf, var->Data, var->DataSize); @@ -199,6 +208,9 @@ u8 *data; int err; + if (!entry || !buf) + return -EINVAL; + if (in_compat_syscall()) { struct compat_efi_variable *compat; @@ -250,14 +262,16 @@ { struct efi_variable *var = &entry->var; struct compat_efi_variable *compat; + unsigned long datasize = sizeof(var->Data); size_t size; + int ret; if (!entry || !buf) return 0; - var->DataSize = 1024; - if (efivar_entry_get(entry, &entry->var.Attributes, - &entry->var.DataSize, entry->var.Data)) + ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); + var->DataSize = datasize; + if (ret) return -EIO; if (in_compat_syscall()) { @@ -508,8 +522,10 @@ ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype, NULL, "%s", short_name); kfree(short_name); - if (ret) + if (ret) { + kobject_put(&new_var->kobj); return ret; + } kobject_uevent(&new_var->kobj, KOBJ_ADD); if (efivar_entry_add(new_var, &efivar_sysfs_list)) { --- linux-oracle-5.4.0.orig/drivers/firmware/efi/esrt.c +++ linux-oracle-5.4.0/drivers/firmware/efi/esrt.c @@ -181,7 +181,7 @@ rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL, "entry%d", entry_num); if (rc) { - kfree(entry); + kobject_put(&entry->kobj); return rc; } } --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/Makefile +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/Makefile @@ -28,6 +28,7 @@ -D__NO_FORTIFY \ $(call cc-option,-ffreestanding) \ $(call cc-option,-fno-stack-protector) \ + $(call cc-option,-fno-addrsig) \ -D__DISABLE_EXPORTS GCOV_PROFILE := n --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/arm-stub.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/arm-stub.c @@ -189,6 +189,8 @@ goto fail_free_cmdline; } + efi_retrieve_tpm2_eventlog(sys_table); + /* Ask the firmware to clear memory on unclean shutdown */ efi_enable_reset_attack_mitigation(sys_table); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/efi-stub-helper.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -46,7 +46,7 @@ return __novamap; } -#define EFI_MMAP_NR_SLACK_SLOTS 8 +#define EFI_MMAP_NR_SLACK_SLOTS 16 struct file_info { efi_file_handle_t *handle; --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/fdt.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/fdt.c @@ -151,6 +151,12 @@ } } + fdt_val32 = cpu_to_fdt32(efi_get_secureboot(sys_table)); + status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", + &fdt_val32, sizeof(fdt_val32)); + if (status) + goto fdt_set_fail; + /* Shrink the FDT back to its minimum size: */ fdt_pack(fdt); @@ -291,14 +297,6 @@ goto fail; } - /* - * Now that we have done our final memory allocation (and free) - * we can get the memory map key needed for exit_boot_services(). - */ - status = efi_get_memory_map(sys_table, &map); - if (status != EFI_SUCCESS) - goto fail_free_new_fdt; - status = update_fdt(sys_table, (void *)fdt_addr, fdt_size, (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, initrd_addr, initrd_size); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/gop.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/gop.c @@ -84,30 +84,6 @@ } static efi_status_t -__gop_query32(efi_system_table_t *sys_table_arg, - struct efi_graphics_output_protocol_32 *gop32, - struct efi_graphics_output_mode_info **info, - unsigned long *size, u64 *fb_base) -{ - struct efi_graphics_output_protocol_mode_32 *mode; - efi_graphics_output_protocol_query_mode query_mode; - efi_status_t status; - unsigned long m; - - m = gop32->mode; - mode = (struct efi_graphics_output_protocol_mode_32 *)m; - query_mode = (void *)(unsigned long)gop32->query_mode; - - status = __efi_call_early(query_mode, (void *)gop32, mode->mode, size, - info); - if (status != EFI_SUCCESS) - return status; - - *fb_base = mode->frame_buffer_base; - return status; -} - -static efi_status_t setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si, efi_guid_t *proto, unsigned long size, void **gop_handle) { @@ -119,7 +95,7 @@ u64 fb_base; struct efi_pixel_bitmask pixel_info; int pixel_format; - efi_status_t status = EFI_NOT_FOUND; + efi_status_t status; u32 *handles = (u32 *)(unsigned long)gop_handle; int i; @@ -128,6 +104,7 @@ nr_gops = size / sizeof(u32); for (i = 0; i < nr_gops; i++) { + struct efi_graphics_output_protocol_mode_32 *mode; struct efi_graphics_output_mode_info *info = NULL; efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; bool conout_found = false; @@ -145,9 +122,11 @@ if (status == EFI_SUCCESS) conout_found = true; - status = __gop_query32(sys_table_arg, gop32, &info, &size, - ¤t_fb_base); - if (status == EFI_SUCCESS && (!first_gop || conout_found) && + mode = (void *)(unsigned long)gop32->mode; + info = (void *)(unsigned long)mode->info; + current_fb_base = mode->frame_buffer_base; + + if ((!first_gop || conout_found) && info->pixel_format != PIXEL_BLT_ONLY) { /* * Systems that use the UEFI Console Splitter may @@ -175,7 +154,7 @@ /* Did we find any GOPs? */ if (!first_gop) - goto out; + return EFI_NOT_FOUND; /* EFI framebuffer */ si->orig_video_isVGA = VIDEO_TYPE_EFI; @@ -197,32 +176,8 @@ si->lfb_size = si->lfb_linelength * si->lfb_height; si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; -out: - return status; -} - -static efi_status_t -__gop_query64(efi_system_table_t *sys_table_arg, - struct efi_graphics_output_protocol_64 *gop64, - struct efi_graphics_output_mode_info **info, - unsigned long *size, u64 *fb_base) -{ - struct efi_graphics_output_protocol_mode_64 *mode; - efi_graphics_output_protocol_query_mode query_mode; - efi_status_t status; - unsigned long m; - m = gop64->mode; - mode = (struct efi_graphics_output_protocol_mode_64 *)m; - query_mode = (void *)(unsigned long)gop64->query_mode; - - status = __efi_call_early(query_mode, (void *)gop64, mode->mode, size, - info); - if (status != EFI_SUCCESS) - return status; - - *fb_base = mode->frame_buffer_base; - return status; + return EFI_SUCCESS; } static efi_status_t @@ -237,7 +192,7 @@ u64 fb_base; struct efi_pixel_bitmask pixel_info; int pixel_format; - efi_status_t status = EFI_NOT_FOUND; + efi_status_t status; u64 *handles = (u64 *)(unsigned long)gop_handle; int i; @@ -246,6 +201,7 @@ nr_gops = size / sizeof(u64); for (i = 0; i < nr_gops; i++) { + struct efi_graphics_output_protocol_mode_64 *mode; struct efi_graphics_output_mode_info *info = NULL; efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; bool conout_found = false; @@ -263,9 +219,11 @@ if (status == EFI_SUCCESS) conout_found = true; - status = __gop_query64(sys_table_arg, gop64, &info, &size, - ¤t_fb_base); - if (status == EFI_SUCCESS && (!first_gop || conout_found) && + mode = (void *)(unsigned long)gop64->mode; + info = (void *)(unsigned long)mode->info; + current_fb_base = mode->frame_buffer_base; + + if ((!first_gop || conout_found) && info->pixel_format != PIXEL_BLT_ONLY) { /* * Systems that use the UEFI Console Splitter may @@ -293,7 +251,7 @@ /* Did we find any GOPs? */ if (!first_gop) - goto out; + return EFI_NOT_FOUND; /* EFI framebuffer */ si->orig_video_isVGA = VIDEO_TYPE_EFI; @@ -315,8 +273,8 @@ si->lfb_size = si->lfb_linelength * si->lfb_height; si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; -out: - return status; + + return EFI_SUCCESS; } /* --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/secureboot.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/secureboot.c @@ -19,7 +19,7 @@ /* SHIM variables */ static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; -static const efi_char16_t shim_MokSBState_name[] = L"MokSBState"; +static const efi_char16_t shim_MokSBState_name[] = L"MokSBStateRT"; #define get_efi_var(name, vendor, ...) \ efi_call_runtime(get_variable, \ @@ -58,8 +58,8 @@ /* * See if a user has put the shim into insecure mode. If so, and if the - * variable doesn't have the runtime attribute set, we might as well - * honor that. + * variable doesn't have the non-volatile attribute set, we might as + * well honor that. */ size = sizeof(moksbstate); status = get_efi_var(shim_MokSBState_name, &shim_guid, @@ -68,7 +68,7 @@ /* If it fails, we don't care why. Default to secure */ if (status != EFI_SUCCESS) goto secure_boot_enabled; - if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS) && moksbstate == 1) + if (!(attr & EFI_VARIABLE_NON_VOLATILE) && moksbstate == 1) return efi_secureboot_mode_disabled; secure_boot_enabled: --- linux-oracle-5.4.0.orig/drivers/firmware/efi/libstub/tpm.c +++ linux-oracle-5.4.0/drivers/firmware/efi/libstub/tpm.c @@ -64,7 +64,7 @@ efi_status_t status; efi_physical_addr_t log_location = 0, log_last_entry = 0; struct linux_efi_tpm_eventlog *log_tbl = NULL; - struct efi_tcg2_final_events_table *final_events_table; + struct efi_tcg2_final_events_table *final_events_table = NULL; unsigned long first_entry_addr, last_entry_addr; size_t log_size, last_entry_size; efi_bool_t truncated; @@ -140,7 +140,8 @@ * Figure out whether any events have already been logged to the * final events structure, and if so how much space they take up */ - final_events_table = get_efi_config_table(sys_table_arg, + if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + final_events_table = get_efi_config_table(sys_table_arg, LINUX_EFI_TPM_FINAL_LOG_GUID); if (final_events_table && final_events_table->nr_events) { struct tcg_pcr_event2_head *header; --- linux-oracle-5.4.0.orig/drivers/firmware/efi/memattr.c +++ linux-oracle-5.4.0/drivers/firmware/efi/memattr.c @@ -32,7 +32,7 @@ return -ENOMEM; } - if (tbl->version > 1) { + if (tbl->version > 2) { pr_warn("Unexpected EFI Memory Attributes table version %d\n", tbl->version); goto unmap; @@ -66,11 +66,6 @@ return false; } - if (!(in->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))) { - pr_warn("Entry attributes invalid: RO and XP bits both cleared\n"); - return false; - } - if (PAGE_SIZE > EFI_PAGE_SIZE && (!PAGE_ALIGNED(in->phys_addr) || !PAGE_ALIGNED(in->num_pages << EFI_PAGE_SHIFT))) { --- linux-oracle-5.4.0.orig/drivers/firmware/efi/mokvar-table.c +++ linux-oracle-5.4.0/drivers/firmware/efi/mokvar-table.c @@ -0,0 +1,362 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mokvar-table.c + * + * Copyright (c) 2020 Red Hat + * Author: Lenny Szubowicz + * + * This module contains the kernel support for the Linux EFI Machine + * Owner Key (MOK) variable configuration table, which is identified by + * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID. + * + * This EFI configuration table provides a more robust alternative to + * EFI volatile variables by which an EFI boot loader can pass the + * contents of the Machine Owner Key (MOK) certificate stores to the + * kernel during boot. If both the EFI MOK config table and corresponding + * EFI MOK variables are present, the table should be considered as + * more authoritative. + * + * This module includes code that validates and maps the EFI MOK table, + * if it's presence was detected very early in boot. + * + * Kernel interface routines are provided to walk through all the + * entries in the MOK config table or to search for a specific named + * entry. + * + * The contents of the individual named MOK config table entries are + * made available to user space via read-only sysfs binary files under: + * + * /sys/firmware/efi/mok-variables/ + * + */ +#define pr_fmt(fmt) "mokvar: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed + * sequence of struct efi_mokvar_table_entry, one for each named + * MOK variable. The sequence is terminated by an entry with a + * completely NULL name and 0 data size. + * + * efi_mokvar_table_size is set to the computed size of the + * MOK config table by efi_mokvar_table_init(). This will be + * non-zero if and only if the table if present and has been + * validated by efi_mokvar_table_init(). + */ +static size_t efi_mokvar_table_size; + +/* + * efi_mokvar_table_va is the kernel virtual address at which the + * EFI MOK config table has been mapped by efi_mokvar_sysfs_init(). + */ +static struct efi_mokvar_table_entry *efi_mokvar_table_va; + +/* + * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by + * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list. + * bin_attr.private points to the associated EFI MOK config table entry. + * + * This list is created during boot and then remains unchanged. + * So no synchronization is currently required to walk the list. + */ +struct efi_mokvar_sysfs_attr { + struct bin_attribute bin_attr; + struct list_head node; +}; + +static LIST_HEAD(efi_mokvar_sysfs_list); +static struct kobject *mokvar_kobj; + +/* + * efi_mokvar_table_init() - Early boot validation of EFI MOK config table + * + * If present, validate and compute the size of the EFI MOK variable + * configuration table. This table may be provided by an EFI boot loader + * as an alternative to ordinary EFI variables, due to platform-dependent + * limitations. The memory occupied by this table is marked as reserved. + * + * This routine must be called before efi_free_boot_services() in order + * to guarantee that it can mark the table as reserved. + * + * Implicit inputs: + * efi.mokvar_table: Physical address of EFI MOK variable config table + * or special value that indicates no such table. + * + * Implicit outputs: + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. + * The table is considered present and valid if this + * is non-zero. + */ +void __init efi_mokvar_table_init(void) +{ + efi_memory_desc_t md; + void *va = NULL; + unsigned long cur_offset = 0; + unsigned long offset_limit; + unsigned long map_size = 0; + unsigned long map_size_needed = 0; + unsigned long size; + struct efi_mokvar_table_entry *mokvar_entry; + int err; + + if (!efi_enabled(EFI_MEMMAP)) + return; + + if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR) + return; + /* + * The EFI MOK config table must fit within a single EFI memory + * descriptor range. + */ + err = efi_mem_desc_lookup(efi.mokvar_table, &md); + if (err) { + pr_warn("EFI MOKvar config table is not within the EFI memory map\n"); + return; + } + + offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table; + + /* + * Validate the MOK config table. Since there is no table header + * from which we could get the total size of the MOK config table, + * we compute the total size as we validate each variably sized + * entry, remapping as necessary. + */ + err = -EINVAL; + while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) { + mokvar_entry = va + cur_offset; + map_size_needed = cur_offset + sizeof(*mokvar_entry); + if (map_size_needed > map_size) { + if (va) + early_memunmap(va, map_size); + /* + * Map a little more than the fixed size entry + * header, anticipating some data. It's safe to + * do so as long as we stay within current memory + * descriptor. + */ + map_size = min(map_size_needed + 2*EFI_PAGE_SIZE, + offset_limit); + va = early_memremap(efi.mokvar_table, map_size); + if (!va) { + pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n", + efi.mokvar_table, map_size); + return; + } + mokvar_entry = va + cur_offset; + } + + /* Check for last sentinel entry */ + if (mokvar_entry->name[0] == '\0') { + if (mokvar_entry->data_size != 0) + break; + err = 0; + break; + } + + /* Sanity check that the name is null terminated */ + size = strnlen(mokvar_entry->name, + sizeof(mokvar_entry->name)); + if (size >= sizeof(mokvar_entry->name)) + break; + + /* Advance to the next entry */ + cur_offset = map_size_needed + mokvar_entry->data_size; + } + + if (va) + early_memunmap(va, map_size); + if (err) { + pr_err("EFI MOKvar config table is not valid\n"); + return; + } + + if (md.type == EFI_BOOT_SERVICES_DATA) + efi_mem_reserve(efi.mokvar_table, map_size_needed); + + efi_mokvar_table_size = map_size_needed; +} + +/* + * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table + * + * mokvar_entry: Pointer to current EFI MOK config table entry + * or null. Null indicates get first entry. + * Passed by reference. This is updated to the + * same value as the return value. + * + * Returns: Pointer to next EFI MOK config table entry + * or null, if there are no more entries. + * Same value is returned in the mokvar_entry + * parameter. + * + * This routine depends on the EFI MOK config table being entirely + * mapped with it's starting virtual address in efi_mokvar_table_va. + */ +struct efi_mokvar_table_entry *efi_mokvar_entry_next( + struct efi_mokvar_table_entry **mokvar_entry) +{ + struct efi_mokvar_table_entry *mokvar_cur; + struct efi_mokvar_table_entry *mokvar_next; + size_t size_cur; + + mokvar_cur = *mokvar_entry; + *mokvar_entry = NULL; + + if (efi_mokvar_table_va == NULL) + return NULL; + + if (mokvar_cur == NULL) { + mokvar_next = efi_mokvar_table_va; + } else { + if (mokvar_cur->name[0] == '\0') + return NULL; + size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size; + mokvar_next = (void *)mokvar_cur + size_cur; + } + + if (mokvar_next->name[0] == '\0') + return NULL; + + *mokvar_entry = mokvar_next; + return mokvar_next; +} + +/* + * efi_mokvar_entry_find() - Find EFI MOK config entry by name + * + * name: Name of the entry to look for. + * + * Returns: Pointer to EFI MOK config table entry if found; + * null otherwise. + * + * This routine depends on the EFI MOK config table being entirely + * mapped with it's starting virtual address in efi_mokvar_table_va. + */ +struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name) +{ + struct efi_mokvar_table_entry *mokvar_entry = NULL; + + while (efi_mokvar_entry_next(&mokvar_entry)) { + if (!strncmp(name, mokvar_entry->name, + sizeof(mokvar_entry->name))) + return mokvar_entry; + } + return NULL; +} + +/* + * efi_mokvar_sysfs_read() - sysfs binary file read routine + * + * Returns: Count of bytes read. + * + * Copy EFI MOK config table entry data for this mokvar sysfs binary file + * to the supplied buffer, starting at the specified offset into mokvar table + * entry data, for the specified count bytes. The copy is limited by the + * amount of data in this mokvar config table entry. + */ +static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, char *buf, + loff_t off, size_t count) +{ + struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private; + + if (!capable(CAP_SYS_ADMIN)) + return 0; + + if (off >= mokvar_entry->data_size) + return 0; + if (count > mokvar_entry->data_size - off) + count = mokvar_entry->data_size - off; + + memcpy(buf, mokvar_entry->data + off, count); + return count; +} + +/* + * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs + * + * Map the EFI MOK variable config table for run-time use by the kernel + * and create the sysfs entries in /sys/firmware/efi/mok-variables/ + * + * This routine just returns if a valid EFI MOK variable config table + * was not found earlier during boot. + * + * This routine must be called during a "middle" initcall phase, i.e. + * after efi_mokvar_table_init() but before UEFI certs are loaded + * during late init. + * + * Implicit inputs: + * efi.mokvar_table: Physical address of EFI MOK variable config table + * or special value that indicates no such table. + * + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. + * The table is considered present and valid if this + * is non-zero. + * + * Implicit outputs: + * efi_mokvar_table_va: Start virtual address of the EFI MOK config table. + */ +static int __init efi_mokvar_sysfs_init(void) +{ + void *config_va; + struct efi_mokvar_table_entry *mokvar_entry = NULL; + struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL; + int err = 0; + + if (efi_mokvar_table_size == 0) + return -ENOENT; + + config_va = memremap(efi.mokvar_table, efi_mokvar_table_size, + MEMREMAP_WB); + if (!config_va) { + pr_err("Failed to map EFI MOKvar config table\n"); + return -ENOMEM; + } + efi_mokvar_table_va = config_va; + + mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj); + if (!mokvar_kobj) { + pr_err("Failed to create EFI mok-variables sysfs entry\n"); + return -ENOMEM; + } + + while (efi_mokvar_entry_next(&mokvar_entry)) { + mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL); + if (!mokvar_sysfs) { + err = -ENOMEM; + break; + } + + sysfs_bin_attr_init(&mokvar_sysfs->bin_attr); + mokvar_sysfs->bin_attr.private = mokvar_entry; + mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name; + mokvar_sysfs->bin_attr.attr.mode = 0400; + mokvar_sysfs->bin_attr.size = mokvar_entry->data_size; + mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read; + + err = sysfs_create_bin_file(mokvar_kobj, + &mokvar_sysfs->bin_attr); + if (err) + break; + + list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list); + } + + if (err) { + pr_err("Failed to create some EFI mok-variables sysfs entries\n"); + kfree(mokvar_sysfs); + } + return err; +} +device_initcall(efi_mokvar_sysfs_init); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/rci2-table.c +++ linux-oracle-5.4.0/drivers/firmware/efi/rci2-table.c @@ -81,6 +81,9 @@ struct kobject *tables_kobj; int ret = -ENOMEM; + if (rci2_table_phys == EFI_INVALID_TABLE_ADDR) + return 0; + rci2_base = memremap(rci2_table_phys, sizeof(struct rci2_table_global_hdr), MEMREMAP_WB); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/runtime-wrappers.c +++ linux-oracle-5.4.0/drivers/firmware/efi/runtime-wrappers.c @@ -62,6 +62,7 @@ \ if (!efi_enabled(EFI_RUNTIME_SERVICES)) { \ pr_warn_once("EFI Runtime Services are disabled!\n"); \ + efi_rts_work.status = EFI_DEVICE_ERROR; \ goto exit; \ } \ \ @@ -414,7 +415,7 @@ unsigned long data_size, efi_char16_t *data) { - if (down_interruptible(&efi_runtime_lock)) { + if (down_trylock(&efi_runtime_lock)) { pr_warn("failed to invoke the reset_system() runtime service:\n" "could not get exclusive access to the firmware\n"); return; --- linux-oracle-5.4.0.orig/drivers/firmware/efi/secureboot.c +++ linux-oracle-5.4.0/drivers/firmware/efi/secureboot.c @@ -0,0 +1,38 @@ +/* Core kernel secure boot support. + * + * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public Licence + * as published by the Free Software Foundation; either version + * 2 of the Licence, or (at your option) any later version. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include + +/* + * Decide what to do when UEFI secure boot mode is enabled. + */ +void __init efi_set_secure_boot(enum efi_secureboot_mode mode) +{ + if (efi_enabled(EFI_BOOT)) { + switch (mode) { + case efi_secureboot_mode_disabled: + pr_info("Secure boot disabled\n"); + break; + case efi_secureboot_mode_enabled: + set_bit(EFI_SECURE_BOOT, &efi.flags); + pr_info("Secure boot enabled\n"); + break; + default: + pr_warning("Secure boot could not be determined (mode %u)\n", + mode); + break; + } + } +} --- linux-oracle-5.4.0.orig/drivers/firmware/efi/tpm.c +++ linux-oracle-5.4.0/drivers/firmware/efi/tpm.c @@ -16,7 +16,7 @@ int efi_tpm_final_log_size; EXPORT_SYMBOL(efi_tpm_final_log_size); -static int tpm2_calc_event_log_size(void *data, int count, void *size_info) +static int __init tpm2_calc_event_log_size(void *data, int count, void *size_info) { struct tcg_pcr_event2_head *header; int event_size, size = 0; @@ -40,7 +40,8 @@ { struct linux_efi_tpm_eventlog *log_tbl; struct efi_tcg2_final_events_table *final_tbl; - int tbl_size; + unsigned int tbl_size; + int final_tbl_size; int ret = 0; if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { @@ -62,8 +63,13 @@ tbl_size = sizeof(*log_tbl) + log_tbl->size; memblock_reserve(efi.tpm_log, tbl_size); - if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) { + pr_info("TPM Final Events table not present\n"); goto out; + } else if (log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + pr_warn(FW_BUG "TPM Final Events table invalid\n"); + goto out; + } final_tbl = early_memremap(efi.tpm_final_log, sizeof(*final_tbl)); @@ -75,26 +81,26 @@ goto out; } - tbl_size = 0; + final_tbl_size = 0; if (final_tbl->nr_events != 0) { void *events = (void *)efi.tpm_final_log + sizeof(final_tbl->version) + sizeof(final_tbl->nr_events); - tbl_size = tpm2_calc_event_log_size(events, - final_tbl->nr_events, - log_tbl->log); + final_tbl_size = tpm2_calc_event_log_size(events, + final_tbl->nr_events, + log_tbl->log); } - if (tbl_size < 0) { + if (final_tbl_size < 0) { pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); ret = -EINVAL; goto out_calc; } - memblock_reserve((unsigned long)final_tbl, - tbl_size + sizeof(*final_tbl)); - efi_tpm_final_log_size = tbl_size; + memblock_reserve(efi.tpm_final_log, + final_tbl_size + sizeof(*final_tbl)); + efi_tpm_final_log_size = final_tbl_size; out_calc: early_memunmap(final_tbl, sizeof(*final_tbl)); --- linux-oracle-5.4.0.orig/drivers/firmware/efi/vars.c +++ linux-oracle-5.4.0/drivers/firmware/efi/vars.c @@ -427,7 +427,7 @@ void *data, bool duplicates, struct list_head *head) { const struct efivar_operations *ops; - unsigned long variable_name_size = 1024; + unsigned long variable_name_size = 512; efi_char16_t *variable_name; efi_status_t status; efi_guid_t vendor_guid; @@ -450,12 +450,13 @@ } /* - * Per EFI spec, the maximum storage allocated for both - * the variable name and variable data is 1024 bytes. + * A small set of old UEFI implementations reject sizes + * above a certain threshold, the lowest seen in the wild + * is 512. */ do { - variable_name_size = 1024; + variable_name_size = 512; status = ops->get_next_variable(&variable_name_size, variable_name, @@ -499,9 +500,13 @@ break; case EFI_NOT_FOUND: break; + case EFI_BUFFER_TOO_SMALL: + pr_warn("efivars: Variable name size exceeds maximum (%lu > 512)\n", + variable_name_size); + status = EFI_NOT_FOUND; + break; default: - printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n", - status); + pr_warn("efivars: get_next_variable: status=%lx\n", status); status = EFI_NOT_FOUND; break; } @@ -750,6 +755,7 @@ { const struct efivar_operations *ops; efi_status_t status; + unsigned long varsize; if (!__efivars) return -EINVAL; @@ -772,15 +778,17 @@ return efivar_entry_set_nonblocking(name, vendor, attributes, size, data); + varsize = size + ucs2_strsize(name, 1024); if (!block) { if (down_trylock(&efivars_lock)) return -EBUSY; + status = check_var_size_nonblocking(attributes, varsize); } else { if (down_interruptible(&efivars_lock)) return -EINTR; + status = check_var_size(attributes, varsize); } - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { up(&efivars_lock); return -ENOSPC; --- linux-oracle-5.4.0.orig/drivers/firmware/google/Kconfig +++ linux-oracle-5.4.0/drivers/firmware/google/Kconfig @@ -3,9 +3,9 @@ bool "Google Firmware Drivers" default n help - These firmware drivers are used by Google's servers. They are - only useful if you are working directly on one of their - proprietary servers. If in doubt, say "N". + These firmware drivers are used by Google servers, + Chromebooks and other devices using coreboot firmware. + If in doubt, say "N". if GOOGLE_FIRMWARE @@ -21,7 +21,7 @@ config GOOGLE_COREBOOT_TABLE tristate "Coreboot Table Access" - depends on ACPI || OF + depends on HAS_IOMEM && (ACPI || OF) help This option enables the coreboot_table module, which provides other firmware modules access to the coreboot table. The coreboot table --- linux-oracle-5.4.0.orig/drivers/firmware/google/coreboot_table.c +++ linux-oracle-5.4.0/drivers/firmware/google/coreboot_table.c @@ -152,20 +152,22 @@ if (!ptr) return -ENOMEM; - ret = bus_register(&coreboot_bus_type); - if (!ret) { - ret = coreboot_table_populate(dev, ptr); - if (ret) - bus_unregister(&coreboot_bus_type); - } + ret = coreboot_table_populate(dev, ptr); + memunmap(ptr); return ret; } +static int __cb_dev_unregister(struct device *dev, void *dummy) +{ + device_unregister(dev); + return 0; +} + static int coreboot_table_remove(struct platform_device *pdev) { - bus_unregister(&coreboot_bus_type); + bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); return 0; } @@ -195,6 +197,32 @@ .of_match_table = of_match_ptr(coreboot_of_match), }, }; -module_platform_driver(coreboot_table_driver); + +static int __init coreboot_table_driver_init(void) +{ + int ret; + + ret = bus_register(&coreboot_bus_type); + if (ret) + return ret; + + ret = platform_driver_register(&coreboot_table_driver); + if (ret) { + bus_unregister(&coreboot_bus_type); + return ret; + } + + return 0; +} + +static void __exit coreboot_table_driver_exit(void) +{ + platform_driver_unregister(&coreboot_table_driver); + bus_unregister(&coreboot_bus_type); +} + +module_init(coreboot_table_driver_init); +module_exit(coreboot_table_driver_exit); + MODULE_AUTHOR("Google, Inc."); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/firmware/google/framebuffer-coreboot.c +++ linux-oracle-5.4.0/drivers/firmware/google/framebuffer-coreboot.c @@ -43,9 +43,7 @@ fb->green_mask_pos == formats[i].green.offset && fb->green_mask_size == formats[i].green.length && fb->blue_mask_pos == formats[i].blue.offset && - fb->blue_mask_size == formats[i].blue.length && - fb->reserved_mask_pos == formats[i].transp.offset && - fb->reserved_mask_size == formats[i].transp.length) + fb->blue_mask_size == formats[i].blue.length) pdata.format = formats[i].name; } if (!pdata.format) --- linux-oracle-5.4.0.orig/drivers/firmware/google/gsmi.c +++ linux-oracle-5.4.0/drivers/firmware/google/gsmi.c @@ -359,9 +359,10 @@ memcpy(data, gsmi_dev.data_buf->start, *data_size); /* All variables are have the following attributes */ - *attr = EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS; + if (attr) + *attr = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; } spin_unlock_irqrestore(&gsmi_dev.lock, flags); @@ -679,6 +680,15 @@ static int gsmi_panic_callback(struct notifier_block *nb, unsigned long reason, void *arg) { + + /* + * Panic callbacks are executed with all other CPUs stopped, + * so we must not attempt to spin waiting for gsmi_dev.lock + * to be released. + */ + if (spin_is_locked(&gsmi_dev.lock)) + return NOTIFY_DONE; + gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC); return NOTIFY_DONE; } @@ -888,7 +898,8 @@ gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info); if (IS_ERR(gsmi_dev.pdev)) { printk(KERN_ERR "gsmi: unable to register platform device\n"); - return PTR_ERR(gsmi_dev.pdev); + ret = PTR_ERR(gsmi_dev.pdev); + goto out_unregister; } /* SMI access needs to be serialized */ @@ -1015,6 +1026,10 @@ gsmi_buf_free(gsmi_dev.name_buf); dma_pool_destroy(gsmi_dev.dma_pool); platform_device_unregister(gsmi_dev.pdev); +out_unregister: +#ifdef CONFIG_PM + platform_driver_unregister(&gsmi_driver_info); +#endif pr_info("gsmi: failed to load: %d\n", ret); return ret; } @@ -1037,6 +1052,9 @@ gsmi_buf_free(gsmi_dev.name_buf); dma_pool_destroy(gsmi_dev.dma_pool); platform_device_unregister(gsmi_dev.pdev); +#ifdef CONFIG_PM + platform_driver_unregister(&gsmi_driver_info); +#endif } module_init(gsmi_init); --- linux-oracle-5.4.0.orig/drivers/firmware/imx/Kconfig +++ linux-oracle-5.4.0/drivers/firmware/imx/Kconfig @@ -13,6 +13,7 @@ config IMX_SCU bool "IMX SCU Protocol driver" depends on IMX_MBOX + select SOC_BUS help The System Controller Firmware (SCFW) is a low-level system function which runs on a dedicated Cortex-M core to provide power, clock, and --- linux-oracle-5.4.0.orig/drivers/firmware/imx/imx-dsp.c +++ linux-oracle-5.4.0/drivers/firmware/imx/imx-dsp.c @@ -114,7 +114,7 @@ dev_info(dev, "NXP i.MX DSP IPC initialized\n"); - return devm_of_platform_populate(dev); + return 0; out: kfree(chan_name); for (j = 0; j < i; j++) { --- linux-oracle-5.4.0.orig/drivers/firmware/imx/imx-scu.c +++ linux-oracle-5.4.0/drivers/firmware/imx/imx-scu.c @@ -29,6 +29,7 @@ struct mbox_client cl; struct mbox_chan *ch; int idx; + struct completion tx_done; }; struct imx_sc_ipc { @@ -37,6 +38,7 @@ struct device *dev; struct mutex lock; struct completion done; + bool fast_ipc; /* temporarily store the SCU msg */ u32 *msg; @@ -100,12 +102,40 @@ } EXPORT_SYMBOL(imx_scu_get_handle); +/* Callback called when the word of a message is ack-ed, eg read by SCU */ +static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r) +{ + struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl); + + complete(&sc_chan->tx_done); +} + static void imx_scu_rx_callback(struct mbox_client *c, void *msg) { struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl); struct imx_sc_ipc *sc_ipc = sc_chan->sc_ipc; struct imx_sc_rpc_msg *hdr; u32 *data = msg; + int i; + + if (!sc_ipc->msg) { + dev_warn(sc_ipc->dev, "unexpected rx idx %d 0x%08x, ignore!\n", + sc_chan->idx, *data); + return; + } + + if (sc_ipc->fast_ipc) { + hdr = msg; + sc_ipc->rx_size = hdr->size; + sc_ipc->msg[0] = *data++; + + for (i = 1; i < sc_ipc->rx_size; i++) + sc_ipc->msg[i] = *data++; + + complete(&sc_ipc->done); + + return; + } if (sc_chan->idx == 0) { hdr = msg; @@ -128,21 +158,38 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) { - struct imx_sc_rpc_msg *hdr = msg; + struct imx_sc_rpc_msg hdr = *(struct imx_sc_rpc_msg *)msg; struct imx_sc_chan *sc_chan; u32 *data = msg; int ret; + int size; int i; /* Check size */ - if (hdr->size > IMX_SC_RPC_MAX_MSG) + if (hdr.size > IMX_SC_RPC_MAX_MSG) return -EINVAL; - dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr->svc, - hdr->func, hdr->size); + dev_dbg(sc_ipc->dev, "RPC SVC %u FUNC %u SIZE %u\n", hdr.svc, + hdr.func, hdr.size); - for (i = 0; i < hdr->size; i++) { + size = sc_ipc->fast_ipc ? 1 : hdr.size; + for (i = 0; i < size; i++) { sc_chan = &sc_ipc->chans[i % 4]; + + /* + * SCU requires that all messages words are written + * sequentially but linux MU driver implements multiple + * independent channels for each register so ordering between + * different channels must be ensured by SCU API interface. + * + * Wait for tx_done before every send to ensure that no + * queueing happens at the mailbox channel level. + */ + if (!sc_ipc->fast_ipc) { + wait_for_completion(&sc_chan->tx_done); + reinit_completion(&sc_chan->tx_done); + } + ret = mbox_send_message(sc_chan->ch, &data[i]); if (ret < 0) return ret; @@ -165,7 +212,8 @@ mutex_lock(&sc_ipc->lock); reinit_completion(&sc_ipc->done); - sc_ipc->msg = msg; + if (have_resp) + sc_ipc->msg = msg; sc_ipc->count = 0; ret = imx_scu_ipc_write(sc_ipc, msg); if (ret < 0) { @@ -187,6 +235,7 @@ } out: + sc_ipc->msg = NULL; mutex_unlock(&sc_ipc->lock); dev_dbg(sc_ipc->dev, "RPC SVC done\n"); @@ -202,6 +251,8 @@ struct imx_sc_chan *sc_chan; struct mbox_client *cl; char *chan_name; + struct of_phandle_args args; + int num_channel; int ret; int i; @@ -209,11 +260,20 @@ if (!sc_ipc) return -ENOMEM; - for (i = 0; i < SCU_MU_CHAN_NUM; i++) { - if (i < 4) + ret = of_parse_phandle_with_args(pdev->dev.of_node, "mboxes", + "#mbox-cells", 0, &args); + if (ret) + return ret; + + sc_ipc->fast_ipc = of_device_is_compatible(args.np, "fsl,imx8-mu-scu"); + + num_channel = sc_ipc->fast_ipc ? 2 : SCU_MU_CHAN_NUM; + for (i = 0; i < num_channel; i++) { + if (i < num_channel / 2) chan_name = kasprintf(GFP_KERNEL, "tx%d", i); else - chan_name = kasprintf(GFP_KERNEL, "rx%d", i - 4); + chan_name = kasprintf(GFP_KERNEL, "rx%d", + i - num_channel / 2); if (!chan_name) return -ENOMEM; @@ -225,14 +285,22 @@ cl->knows_txdone = true; cl->rx_callback = imx_scu_rx_callback; + if (!sc_ipc->fast_ipc) { + /* Initial tx_done completion as "done" */ + cl->tx_done = imx_scu_tx_done; + init_completion(&sc_chan->tx_done); + complete(&sc_chan->tx_done); + } + sc_chan->sc_ipc = sc_ipc; - sc_chan->idx = i % 4; + sc_chan->idx = i % (num_channel / 2); sc_chan->ch = mbox_request_channel_byname(cl, chan_name); if (IS_ERR(sc_chan->ch)) { ret = PTR_ERR(sc_chan->ch); if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to request mbox chan %s ret %d\n", chan_name, ret); + kfree(chan_name); return ret; } --- linux-oracle-5.4.0.orig/drivers/firmware/imx/misc.c +++ linux-oracle-5.4.0/drivers/firmware/imx/misc.c @@ -16,7 +16,7 @@ u32 ctrl; u32 val; u16 resource; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_req_cpu_start { struct imx_sc_rpc_msg hdr; @@ -24,18 +24,18 @@ u32 address_lo; u16 resource; u8 enable; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_req_misc_get_ctrl { struct imx_sc_rpc_msg hdr; u32 ctrl; u16 resource; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_resp_misc_get_ctrl { struct imx_sc_rpc_msg hdr; u32 val; -} __packed; +} __packed __aligned(4); /* * This function sets a miscellaneous control value. --- linux-oracle-5.4.0.orig/drivers/firmware/imx/scu-pd.c +++ linux-oracle-5.4.0/drivers/firmware/imx/scu-pd.c @@ -61,7 +61,7 @@ struct imx_sc_rpc_msg hdr; u16 resource; u8 mode; -} __packed; +} __packed __aligned(4); #define IMX_SCU_PD_NAME_SIZE 20 struct imx_sc_pm_domain { --- linux-oracle-5.4.0.orig/drivers/firmware/meson/meson_sm.c +++ linux-oracle-5.4.0/drivers/firmware/meson/meson_sm.c @@ -54,8 +54,6 @@ void __iomem *sm_shmem_out_base; }; -static struct meson_sm_firmware fw; - static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip, unsigned int cmd_index) { @@ -90,6 +88,7 @@ /** * meson_sm_call - generic SMC32 call to the secure-monitor * + * @fw: Pointer to secure-monitor firmware * @cmd_index: Index of the SMC32 function ID * @ret: Returned value * @arg0: SMC32 Argument 0 @@ -100,15 +99,15 @@ * * Return: 0 on success, a negative value on error */ -int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, - u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index, + u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 cmd, lret; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - cmd = meson_sm_get_cmd(fw.chip, cmd_index); + cmd = meson_sm_get_cmd(fw->chip, cmd_index); if (!cmd) return -EINVAL; @@ -124,6 +123,7 @@ /** * meson_sm_call_read - retrieve data from secure-monitor * + * @fw: Pointer to secure-monitor firmware * @buffer: Buffer to store the retrieved data * @bsize: Size of the buffer * @cmd_index: Index of the SMC32 function ID @@ -137,22 +137,23 @@ * When 0 is returned there is no guarantee about the amount of * data read and bsize bytes are copied in buffer. */ -int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer, + unsigned int bsize, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 size; int ret; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - if (!fw.chip->cmd_shmem_out_base) + if (!fw->chip->cmd_shmem_out_base) return -EINVAL; - if (bsize > fw.chip->shmem_size) + if (bsize > fw->chip->shmem_size) return -EINVAL; - if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) + if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) return -EINVAL; if (size > bsize) @@ -164,7 +165,7 @@ size = bsize; if (buffer) - memcpy(buffer, fw.sm_shmem_out_base, size); + memcpy(buffer, fw->sm_shmem_out_base, size); return ret; } @@ -173,6 +174,7 @@ /** * meson_sm_call_write - send data to secure-monitor * + * @fw: Pointer to secure-monitor firmware * @buffer: Buffer containing data to send * @size: Size of the data to send * @cmd_index: Index of the SMC32 function ID @@ -184,23 +186,24 @@ * * Return: size of sent data on success, a negative value on error */ -int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer, + unsigned int size, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 written; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - if (size > fw.chip->shmem_size) + if (size > fw->chip->shmem_size) return -EINVAL; - if (!fw.chip->cmd_shmem_in_base) + if (!fw->chip->cmd_shmem_in_base) return -EINVAL; - memcpy(fw.sm_shmem_in_base, buffer, size); + memcpy(fw->sm_shmem_in_base, buffer, size); - if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) + if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) return -EINVAL; if (!written) @@ -210,6 +213,24 @@ } EXPORT_SYMBOL(meson_sm_call_write); +/** + * meson_sm_get - get pointer to meson_sm_firmware structure. + * + * @sm_node: Pointer to the secure-monitor Device Tree node. + * + * Return: NULL is the secure-monitor device is not ready. + */ +struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node) +{ + struct platform_device *pdev = of_find_device_by_node(sm_node); + + if (!pdev) + return NULL; + + return platform_get_drvdata(pdev); +} +EXPORT_SYMBOL_GPL(meson_sm_get); + #define SM_CHIP_ID_LENGTH 119 #define SM_CHIP_ID_OFFSET 4 #define SM_CHIP_ID_SIZE 12 @@ -217,14 +238,18 @@ static ssize_t serial_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct platform_device *pdev = to_platform_device(dev); + struct meson_sm_firmware *fw; uint8_t *id_buf; int ret; + fw = platform_get_drvdata(pdev); + id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL); if (!id_buf) return -ENOMEM; - ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, + ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, 0, 0, 0, 0, 0); if (ret < 0) { kfree(id_buf); @@ -268,25 +293,36 @@ static int __init meson_sm_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; const struct meson_sm_chip *chip; + struct meson_sm_firmware *fw; - chip = of_match_device(meson_sm_ids, &pdev->dev)->data; + fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); + if (!fw) + return -ENOMEM; + + chip = of_match_device(meson_sm_ids, dev)->data; + if (!chip) + return -EINVAL; if (chip->cmd_shmem_in_base) { - fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, - chip->shmem_size); - if (WARN_ON(!fw.sm_shmem_in_base)) + fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, + chip->shmem_size); + if (WARN_ON(!fw->sm_shmem_in_base)) goto out; } if (chip->cmd_shmem_out_base) { - fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, - chip->shmem_size); - if (WARN_ON(!fw.sm_shmem_out_base)) + fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, + chip->shmem_size); + if (WARN_ON(!fw->sm_shmem_out_base)) goto out_in_base; } - fw.chip = chip; + fw->chip = chip; + + platform_set_drvdata(pdev, fw); + pr_info("secure-monitor enabled\n"); if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group)) @@ -295,7 +331,7 @@ return 0; out_in_base: - iounmap(fw.sm_shmem_in_base); + iounmap(fw->sm_shmem_in_base); out: return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/firmware/psci/psci.c +++ linux-oracle-5.4.0/drivers/firmware/psci/psci.c @@ -57,6 +57,21 @@ .smccc_version = SMCCC_VERSION_1_0, }; +enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) +{ + if (psci_ops.smccc_version < SMCCC_VERSION_1_1) + return SMCCC_CONDUIT_NONE; + + switch (psci_ops.conduit) { + case PSCI_CONDUIT_SMC: + return SMCCC_CONDUIT_SMC; + case PSCI_CONDUIT_HVC: + return SMCCC_CONDUIT_HVC; + default: + return SMCCC_CONDUIT_NONE; + } +} + typedef unsigned long (psci_fn)(unsigned long, unsigned long, unsigned long, unsigned long); static psci_fn *invoke_psci_fn; --- linux-oracle-5.4.0.orig/drivers/firmware/psci/psci_checker.c +++ linux-oracle-5.4.0/drivers/firmware/psci/psci_checker.c @@ -155,10 +155,12 @@ if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return -ENOMEM; - cpu_groups = kcalloc(nb_available_cpus, sizeof(cpu_groups), + cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups), GFP_KERNEL); - if (!cpu_groups) + if (!cpu_groups) { + free_cpumask_var(tmp); return -ENOMEM; + } cpumask_copy(tmp, cpu_online_mask); @@ -167,6 +169,7 @@ topology_core_cpumask(cpumask_any(tmp)); if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) { + free_cpumask_var(tmp); free_cpu_groups(num_groups, &cpu_groups); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/firmware/qcom_scm-64.c +++ linux-oracle-5.4.0/drivers/firmware/qcom_scm-64.c @@ -150,7 +150,7 @@ kfree(args_virt); } - if (res->a0 < 0) + if ((long)res->a0 < 0) return qcom_scm_remap_error(res->a0); return 0; --- linux-oracle-5.4.0.orig/drivers/firmware/qcom_scm.c +++ linux-oracle-5.4.0/drivers/firmware/qcom_scm.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -441,8 +440,7 @@ struct qcom_scm_mem_map_info *mem_to_map; phys_addr_t mem_to_map_phys; phys_addr_t dest_phys; - phys_addr_t ptr_phys; - dma_addr_t ptr_dma; + dma_addr_t ptr_phys; size_t mem_to_map_sz; size_t dest_sz; size_t src_sz; @@ -459,10 +457,9 @@ ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(dest_sz, SZ_64); - ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_dma, GFP_KERNEL); + ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL); if (!ptr) return -ENOMEM; - ptr_phys = dma_to_phys(__scm->dev, ptr_dma); /* Fill source vmid detail */ src = ptr; @@ -490,7 +487,7 @@ ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz, ptr_phys, src_sz, dest_phys, dest_sz); - dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_dma); + dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys); if (ret) { dev_err(__scm->dev, "Assign memory protection call failed %d\n", ret); @@ -588,8 +585,7 @@ static void qcom_scm_shutdown(struct platform_device *pdev) { /* Clean shutdown, disable download mode to allow normal restart */ - if (download_mode) - qcom_scm_set_download_mode(false); + qcom_scm_set_download_mode(false); } static const struct of_device_id qcom_scm_dt_match[] = { --- linux-oracle-5.4.0.orig/drivers/firmware/qemu_fw_cfg.c +++ linux-oracle-5.4.0/drivers/firmware/qemu_fw_cfg.c @@ -296,15 +296,13 @@ return 0; } -static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) +static ssize_t fw_cfg_showrev(struct kobject *k, struct kobj_attribute *a, + char *buf) { return sprintf(buf, "%u\n", fw_cfg_rev); } -static const struct { - struct attribute attr; - ssize_t (*show)(struct kobject *k, struct attribute *a, char *buf); -} fw_cfg_rev_attr = { +static const struct kobj_attribute fw_cfg_rev_attr = { .attr = { .name = "rev", .mode = S_IRUSR }, .show = fw_cfg_showrev, }; @@ -387,9 +385,7 @@ struct fw_cfg_sysfs_entry *entry, *next; list_for_each_entry_safe(entry, next, &fw_cfg_entry_cache, list) { - /* will end up invoking fw_cfg_sysfs_cache_delist() - * via each object's release() method (i.e. destructor) - */ + fw_cfg_sysfs_cache_delist(entry); kobject_put(&entry->kobj); } } @@ -447,7 +443,6 @@ { struct fw_cfg_sysfs_entry *entry = to_entry(kobj); - fw_cfg_sysfs_cache_delist(entry); kfree(entry); } @@ -600,18 +595,18 @@ /* set file entry information */ entry->size = be32_to_cpu(f->size); entry->select = be16_to_cpu(f->select); - memcpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); + strscpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); /* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype, fw_cfg_sel_ko, "%d", entry->select); if (err) - goto err_register; + goto err_put_entry; /* add raw binary content access */ err = sysfs_create_bin_file(&entry->kobj, &fw_cfg_sysfs_attr_raw); if (err) - goto err_add_raw; + goto err_del_entry; /* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->name); @@ -620,10 +615,10 @@ fw_cfg_sysfs_cache_enlist(entry); return 0; -err_add_raw: +err_del_entry: kobject_del(&entry->kobj); -err_register: - kfree(entry); +err_put_entry: + kobject_put(&entry->kobj); return err; } --- linux-oracle-5.4.0.orig/drivers/firmware/raspberrypi.c +++ linux-oracle-5.4.0/drivers/firmware/raspberrypi.c @@ -7,7 +7,9 @@ */ #include +#include #include +#include #include #include #include @@ -27,6 +29,8 @@ struct mbox_chan *chan; /* The property channel. */ struct completion c; u32 enabled; + + struct kref consumers; }; static DEFINE_MUTEX(transaction_lock); @@ -93,8 +97,8 @@ if (size & 3) return -EINVAL; - buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr, - GFP_ATOMIC); + buf = dma_alloc_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), + &bus_addr, GFP_ATOMIC); if (!buf) return -ENOMEM; @@ -122,7 +126,7 @@ ret = -EINVAL; } - dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr); + dma_free_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), buf, bus_addr); return ret; } @@ -214,12 +218,38 @@ -1, NULL, 0); } +static void rpi_firmware_delete(struct kref *kref) +{ + struct rpi_firmware *fw = container_of(kref, struct rpi_firmware, + consumers); + + mbox_free_channel(fw->chan); + kfree(fw); +} + +void rpi_firmware_put(struct rpi_firmware *fw) +{ + kref_put(&fw->consumers, rpi_firmware_delete); +} +EXPORT_SYMBOL_GPL(rpi_firmware_put); + +static void devm_rpi_firmware_put(void *data) +{ + struct rpi_firmware *fw = data; + + rpi_firmware_put(fw); +} + static int rpi_firmware_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rpi_firmware *fw; - fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); + /* + * Memory will be freed by rpi_firmware_delete() once all users have + * released their firmware handles. Don't use devm_kzalloc() here. + */ + fw = kzalloc(sizeof(*fw), GFP_KERNEL); if (!fw) return -ENOMEM; @@ -232,10 +262,12 @@ int ret = PTR_ERR(fw->chan); if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to get mbox channel: %d\n", ret); + kfree(fw); return ret; } init_completion(&fw->c); + kref_init(&fw->consumers); platform_set_drvdata(pdev, fw); @@ -264,7 +296,8 @@ rpi_hwmon = NULL; platform_device_unregister(rpi_clk); rpi_clk = NULL; - mbox_free_channel(fw->chan); + + rpi_firmware_put(fw); return 0; } @@ -273,19 +306,51 @@ * rpi_firmware_get - Get pointer to rpi_firmware structure. * @firmware_node: Pointer to the firmware Device Tree node. * + * The reference to rpi_firmware has to be released with rpi_firmware_put(). + * * Returns NULL is the firmware device is not ready. */ struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node) { struct platform_device *pdev = of_find_device_by_node(firmware_node); + struct rpi_firmware *fw; if (!pdev) return NULL; - return platform_get_drvdata(pdev); + fw = platform_get_drvdata(pdev); + if (!fw) + return NULL; + + if (!kref_get_unless_zero(&fw->consumers)) + return NULL; + + return fw; } EXPORT_SYMBOL_GPL(rpi_firmware_get); +/** + * devm_rpi_firmware_get - Get pointer to rpi_firmware structure. + * @firmware_node: Pointer to the firmware Device Tree node. + * + * Returns NULL is the firmware device is not ready. + */ +struct rpi_firmware *devm_rpi_firmware_get(struct device *dev, + struct device_node *firmware_node) +{ + struct rpi_firmware *fw; + + fw = rpi_firmware_get(firmware_node); + if (!fw) + return NULL; + + if (devm_add_action_or_reset(dev, devm_rpi_firmware_put, fw)) + return NULL; + + return fw; +} +EXPORT_SYMBOL_GPL(devm_rpi_firmware_get); + static const struct of_device_id rpi_firmware_of_match[] = { { .compatible = "raspberrypi,bcm2835-firmware", }, {}, --- linux-oracle-5.4.0.orig/drivers/firmware/scpi_pm_domain.c +++ linux-oracle-5.4.0/drivers/firmware/scpi_pm_domain.c @@ -16,7 +16,6 @@ struct generic_pm_domain genpd; struct scpi_ops *ops; u32 domain; - char name[30]; }; /* @@ -110,8 +109,13 @@ scpi_pd->domain = i; scpi_pd->ops = scpi_ops; - sprintf(scpi_pd->name, "%pOFn.%d", np, i); - scpi_pd->genpd.name = scpi_pd->name; + scpi_pd->genpd.name = devm_kasprintf(dev, GFP_KERNEL, + "%pOFn.%d", np, i); + if (!scpi_pd->genpd.name) { + dev_err(dev, "Failed to allocate genpd name:%pOFn.%d\n", + np, i); + continue; + } scpi_pd->genpd.power_off = scpi_pd_power_off; scpi_pd->genpd.power_on = scpi_pd_power_on; --- linux-oracle-5.4.0.orig/drivers/firmware/stratix10-svc.c +++ linux-oracle-5.4.0/drivers/firmware/stratix10-svc.c @@ -615,8 +615,8 @@ end = rounddown(sh_memory->addr + sh_memory->size, PAGE_SIZE); paddr = begin; size = end - begin; - va = memremap(paddr, size, MEMREMAP_WC); - if (!va) { + va = devm_memremap(dev, paddr, size, MEMREMAP_WC); + if (IS_ERR(va)) { dev_err(dev, "fail to remap shared memory\n"); return ERR_PTR(-EINVAL); } @@ -934,17 +934,17 @@ void stratix10_svc_free_memory(struct stratix10_svc_chan *chan, void *kaddr) { struct stratix10_svc_data_mem *pmem; - size_t size = 0; list_for_each_entry(pmem, &svc_data_mem, node) if (pmem->vaddr == kaddr) { - size = pmem->size; - break; + gen_pool_free(chan->ctrl->genpool, + (unsigned long)kaddr, pmem->size); + pmem->vaddr = NULL; + list_del(&pmem->node); + return; } - gen_pool_free(chan->ctrl->genpool, (unsigned long)kaddr, size); - pmem->vaddr = NULL; - list_del(&pmem->node); + list_del(&svc_data_mem); } EXPORT_SYMBOL_GPL(stratix10_svc_free_memory); @@ -981,8 +981,8 @@ return ret; genpool = svc_create_memory_pool(pdev, sh_memory); - if (!genpool) - return -ENOMEM; + if (IS_ERR(genpool)) + return PTR_ERR(genpool); /* allocate service controller and supporting channel */ controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL); @@ -1026,24 +1026,32 @@ /* add svc client device(s) */ svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL); - if (!svc) - return -ENOMEM; + if (!svc) { + ret = -ENOMEM; + goto err_free_kfifo; + } svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0); if (!svc->stratix10_svc_rsu) { dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_kfifo; } ret = platform_device_add(svc->stratix10_svc_rsu); - if (ret) { - platform_device_put(svc->stratix10_svc_rsu); - return ret; - } + if (ret) + goto err_put_device; + dev_set_drvdata(dev, svc); pr_info("Intel Service Layer Driver Initialized\n"); + return 0; + +err_put_device: + platform_device_put(svc->stratix10_svc_rsu); +err_free_kfifo: + kfifo_free(&controller->svc_fifo); return ret; } --- linux-oracle-5.4.0.orig/drivers/firmware/tegra/Makefile +++ linux-oracle-5.4.0/drivers/firmware/tegra/Makefile @@ -3,6 +3,7 @@ tegra-bpmp-$(CONFIG_ARCH_TEGRA_210_SOC) += bpmp-tegra210.o tegra-bpmp-$(CONFIG_ARCH_TEGRA_186_SOC) += bpmp-tegra186.o tegra-bpmp-$(CONFIG_ARCH_TEGRA_194_SOC) += bpmp-tegra186.o +tegra-bpmp-$(CONFIG_ARCH_TEGRA_234_SOC) += bpmp-tegra186.o tegra-bpmp-$(CONFIG_DEBUG_FS) += bpmp-debugfs.o obj-$(CONFIG_TEGRA_BPMP) += tegra-bpmp.o obj-$(CONFIG_TEGRA_IVC) += ivc.o --- linux-oracle-5.4.0.orig/drivers/firmware/tegra/bpmp-private.h +++ linux-oracle-5.4.0/drivers/firmware/tegra/bpmp-private.h @@ -24,7 +24,8 @@ }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) extern const struct tegra_bpmp_ops tegra186_bpmp_ops; #endif #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) --- linux-oracle-5.4.0.orig/drivers/firmware/tegra/bpmp-tegra210.c +++ linux-oracle-5.4.0/drivers/firmware/tegra/bpmp-tegra210.c @@ -210,7 +210,7 @@ priv->tx_irq_data = irq_get_irq_data(err); if (!priv->tx_irq_data) { dev_err(&pdev->dev, "failed to get IRQ data for TX IRQ\n"); - return err; + return -ENOENT; } err = platform_get_irq_byname(pdev, "rx"); --- linux-oracle-5.4.0.orig/drivers/firmware/tegra/bpmp.c +++ linux-oracle-5.4.0/drivers/firmware/tegra/bpmp.c @@ -24,12 +24,6 @@ #define MSG_RING BIT(1) #define TAG_SZ 32 -static inline struct tegra_bpmp * -mbox_client_to_bpmp(struct mbox_client *client) -{ - return container_of(client, struct tegra_bpmp, mbox.client); -} - static inline const struct tegra_bpmp_ops * channel_to_ops(struct tegra_bpmp_channel *channel) { @@ -808,7 +802,8 @@ }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) static const struct tegra_bpmp_soc tegra186_soc = { .channels = { .cpu_tx = { --- linux-oracle-5.4.0.orig/drivers/firmware/ti_sci.c +++ linux-oracle-5.4.0/drivers/firmware/ti_sci.c @@ -2,7 +2,7 @@ /* * Texas Instruments System Control Interface Protocol Driver * - * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/ * Nishanth Menon */ @@ -179,7 +179,7 @@ { struct device *dev = &pdev->dev; struct resource *res; - char debug_name[50] = "ti_sci_debug@"; + char debug_name[50]; /* Debug region is optional */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -196,10 +196,10 @@ /* Setup NULL termination */ info->debug_buffer[info->debug_region_size] = 0; - info->d = debugfs_create_file(strncat(debug_name, dev_name(dev), - sizeof(debug_name) - - sizeof("ti_sci_debug@")), - 0444, NULL, info, &ti_sci_debug_fops); + snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", + dev_name(dev)); + info->d = debugfs_create_file(debug_name, 0444, NULL, info, + &ti_sci_debug_fops); if (IS_ERR(info->d)) return PTR_ERR(info->d); @@ -208,19 +208,6 @@ return 0; } -/** - * ti_sci_debugfs_destroy() - clean up log debug file - * @pdev: platform device pointer - * @info: Pointer to SCI entity information - */ -static void ti_sci_debugfs_destroy(struct platform_device *pdev, - struct ti_sci_info *info) -{ - if (IS_ERR(info->debug_region)) - return; - - debugfs_remove(info->d); -} #else /* CONFIG_DEBUG_FS */ static inline int ti_sci_debugfs_create(struct platform_device *dev, struct ti_sci_info *info) @@ -3527,43 +3514,12 @@ return ret; } -static int ti_sci_remove(struct platform_device *pdev) -{ - struct ti_sci_info *info; - struct device *dev = &pdev->dev; - int ret = 0; - - of_platform_depopulate(dev); - - info = platform_get_drvdata(pdev); - - if (info->nb.notifier_call) - unregister_restart_handler(&info->nb); - - mutex_lock(&ti_sci_list_mutex); - if (info->users) - ret = -EBUSY; - else - list_del(&info->node); - mutex_unlock(&ti_sci_list_mutex); - - if (!ret) { - ti_sci_debugfs_destroy(pdev, info); - - /* Safe to free channels since no more users */ - mbox_free_channel(info->chan_tx); - mbox_free_channel(info->chan_rx); - } - - return ret; -} - static struct platform_driver ti_sci_driver = { .probe = ti_sci_probe, - .remove = ti_sci_remove, .driver = { .name = "ti-sci", .of_match_table = of_match_ptr(ti_sci_of_match), + .suppress_bind_attrs = true, }, }; module_platform_driver(ti_sci_driver); --- linux-oracle-5.4.0.orig/drivers/firmware/ti_sci.h +++ linux-oracle-5.4.0/drivers/firmware/ti_sci.h @@ -6,7 +6,7 @@ * The system works in a message response protocol * See: http://processors.wiki.ti.com/index.php/TISCI for details * - * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2016 Texas Instruments Incorporated - https://www.ti.com/ */ #ifndef __TI_SCI_H --- linux-oracle-5.4.0.orig/drivers/firmware/turris-mox-rwtm.c +++ linux-oracle-5.4.0/drivers/firmware/turris-mox-rwtm.c @@ -134,11 +134,14 @@ static int mox_get_status(enum mbox_cmd cmd, u32 retval) { - if (MBOX_STS_CMD(retval) != cmd || - MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS) + if (MBOX_STS_CMD(retval) != cmd) return -EIO; else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL) return -(int)MBOX_STS_VALUE(retval); + else if (MBOX_STS_ERROR(retval) == MBOX_STS_BADCMD) + return -ENOSYS; + else if (MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS) + return -EIO; else return MBOX_STS_VALUE(retval); } @@ -183,16 +186,18 @@ if (ret < 0) return ret; - ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); - if (ret < 0) - return ret; + if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) + return -ETIMEDOUT; ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval); - if (ret < 0 && ret != -ENODATA) { - return ret; - } else if (ret == -ENODATA) { + if (ret == -ENODATA) { dev_warn(rwtm->dev, "Board does not have manufacturing information burned!\n"); + } else if (ret == -ENOSYS) { + dev_notice(rwtm->dev, + "Firmware does not support the BOARD_INFO command\n"); + } else if (ret < 0) { + return ret; } else { rwtm->serial_number = reply->status[1]; rwtm->serial_number <<= 32; @@ -216,15 +221,17 @@ if (ret < 0) return ret; - ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); - if (ret < 0) - return ret; + if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) + return -ETIMEDOUT; ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval); - if (ret < 0 && ret != -ENODATA) { - return ret; - } else if (ret == -ENODATA) { + if (ret == -ENODATA) { dev_warn(rwtm->dev, "Board has no public key burned!\n"); + } else if (ret == -ENOSYS) { + dev_notice(rwtm->dev, + "Firmware does not support the ECDSA_PUB_KEY command\n"); + } else if (ret < 0) { + return ret; } else { u32 *s = reply->status; @@ -238,6 +245,26 @@ return 0; } +static int check_get_random_support(struct mox_rwtm *rwtm) +{ + struct armada_37xx_rwtm_tx_msg msg; + int ret; + + msg.command = MBOX_CMD_GET_RANDOM; + msg.args[0] = 1; + msg.args[1] = rwtm->buf_phys; + msg.args[2] = 4; + + ret = mbox_send_message(rwtm->mbox, &msg); + if (ret < 0) + return ret; + + if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2)) + return -ETIMEDOUT; + + return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval); +} + static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct mox_rwtm *rwtm = (struct mox_rwtm *) rng->priv; @@ -310,6 +337,7 @@ platform_set_drvdata(pdev, rwtm); mutex_init(&rwtm->busy); + init_completion(&rwtm->cmd_done); rwtm->mbox_client.dev = dev; rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback; @@ -323,12 +351,17 @@ goto remove_files; } - init_completion(&rwtm->cmd_done); - ret = mox_get_board_info(rwtm); if (ret < 0) dev_warn(dev, "Cannot read board information: %i\n", ret); + ret = check_get_random_support(rwtm); + if (ret < 0) { + dev_notice(dev, + "Firmware does not support the GET_RANDOM command\n"); + goto free_channel; + } + rwtm->hwrng.name = DRIVER_NAME "_hwrng"; rwtm->hwrng.read = mox_hwrng_read; rwtm->hwrng.priv = (unsigned long) rwtm; @@ -364,6 +397,7 @@ static const struct of_device_id turris_mox_rwtm_match[] = { { .compatible = "cznic,turris-mox-rwtm", }, + { .compatible = "marvell,armada-3700-rwtm-firmware", }, { }, }; --- linux-oracle-5.4.0.orig/drivers/fpga/altera-pr-ip-core.c +++ linux-oracle-5.4.0/drivers/fpga/altera-pr-ip-core.c @@ -108,7 +108,7 @@ u32 *buffer_32 = (u32 *)buf; size_t i = 0; - if (count <= 0) + if (!count) return -EINVAL; /* Write out the complete 32-bit chunks */ --- linux-oracle-5.4.0.orig/drivers/fpga/dfl-afu-dma-region.c +++ linux-oracle-5.4.0/drivers/fpga/dfl-afu-dma-region.c @@ -61,10 +61,10 @@ region->pages); if (pinned < 0) { ret = pinned; - goto put_pages; + goto free_pages; } else if (pinned != npages) { ret = -EFAULT; - goto free_pages; + goto put_pages; } dev_dbg(dev, "%d pages pinned\n", pinned); --- linux-oracle-5.4.0.orig/drivers/fpga/dfl-afu-main.c +++ linux-oracle-5.4.0/drivers/fpga/dfl-afu-main.c @@ -83,7 +83,8 @@ * on this port and minimum soft reset pulse width has elapsed. * Driver polls port_soft_reset_ack to determine if reset done by HW. */ - if (readq_poll_timeout(base + PORT_HDR_CTRL, v, v & PORT_CTRL_SFTRST, + if (readq_poll_timeout(base + PORT_HDR_CTRL, v, + v & PORT_CTRL_SFTRST_ACK, RST_POLL_INVL, RST_POLL_TIMEOUT)) { dev_err(&pdev->dev, "timeout, fail to reset device\n"); return -ETIMEDOUT; --- linux-oracle-5.4.0.orig/drivers/fpga/dfl-pci.c +++ linux-oracle-5.4.0/drivers/fpga/dfl-pci.c @@ -227,7 +227,6 @@ { struct cci_drvdata *drvdata = pci_get_drvdata(pcidev); struct dfl_fpga_cdev *cdev = drvdata->cdev; - int ret = 0; if (!num_vfs) { /* @@ -239,6 +238,8 @@ dfl_fpga_cdev_config_ports_pf(cdev); } else { + int ret; + /* * before enable SRIOV, put released ports into VF access mode * first of all. @@ -248,11 +249,13 @@ return ret; ret = pci_enable_sriov(pcidev, num_vfs); - if (ret) + if (ret) { dfl_fpga_cdev_config_ports_pf(cdev); + return ret; + } } - return ret; + return num_vfs; } static void cci_pci_remove(struct pci_dev *pcidev) --- linux-oracle-5.4.0.orig/drivers/fpga/fpga-bridge.c +++ linux-oracle-5.4.0/drivers/fpga/fpga-bridge.c @@ -115,7 +115,7 @@ /** * fpga_bridge_get - get an exclusive reference to a fpga bridge * @dev: parent device that fpga bridge was registered with - * @info: fpga manager info + * @info: fpga image specific information * * Given a device, get an exclusive reference to a fpga bridge. * --- linux-oracle-5.4.0.orig/drivers/fpga/machxo2-spi.c +++ linux-oracle-5.4.0/drivers/fpga/machxo2-spi.c @@ -223,8 +223,10 @@ goto fail; get_status(spi, &status); - if (test_bit(FAIL, &status)) + if (test_bit(FAIL, &status)) { + ret = -EINVAL; goto fail; + } dump_status_reg(&status); spi_message_init(&msg); @@ -310,6 +312,7 @@ dump_status_reg(&status); if (!test_bit(DONE, &status)) { machxo2_cleanup(mgr); + ret = -EINVAL; goto fail; } @@ -331,6 +334,7 @@ break; if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) { machxo2_cleanup(mgr); + ret = -EINVAL; goto fail; } } while (1); --- linux-oracle-5.4.0.orig/drivers/fpga/stratix10-soc.c +++ linux-oracle-5.4.0/drivers/fpga/stratix10-soc.c @@ -218,9 +218,9 @@ /* Allocate buffers from the service layer's pool. */ for (i = 0; i < NUM_SVC_BUFS; i++) { kbuf = stratix10_svc_allocate_memory(priv->chan, SVC_BUF_SIZE); - if (!kbuf) { + if (IS_ERR(kbuf)) { s10_free_buffers(mgr); - ret = -ENOMEM; + ret = PTR_ERR(kbuf); goto init_done; } @@ -476,6 +476,7 @@ struct s10_priv *priv = mgr->priv; fpga_mgr_unregister(mgr); + fpga_mgr_free(mgr); stratix10_svc_free_channel(priv->chan); return 0; --- linux-oracle-5.4.0.orig/drivers/fsi/fsi-core.c +++ linux-oracle-5.4.0/drivers/fsi/fsi-core.c @@ -544,6 +544,31 @@ return 0; } +static unsigned long aligned_access_size(size_t offset, size_t count) +{ + unsigned long offset_unit, count_unit; + + /* Criteria: + * + * 1. Access size must be less than or equal to the maximum access + * width or the highest power-of-two factor of offset + * 2. Access size must be less than or equal to the amount specified by + * count + * + * The access width is optimal if we can calculate 1 to be strictly + * equal while still satisfying 2. + */ + + /* Find 1 by the bottom bit of offset (with a 4 byte access cap) */ + offset_unit = BIT(__builtin_ctzl(offset | 4)); + + /* Find 2 by the top bit of count */ + count_unit = BIT(8 * sizeof(unsigned long) - 1 - __builtin_clzl(count)); + + /* Constrain the maximum access width to the minimum of both criteria */ + return BIT(__builtin_ctzl(offset_unit | count_unit)); +} + static ssize_t fsi_slave_sysfs_raw_read(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -559,8 +584,7 @@ return -EINVAL; for (total_len = 0; total_len < count; total_len += read_len) { - read_len = min_t(size_t, count, 4); - read_len -= off & 0x3; + read_len = aligned_access_size(off, count - total_len); rc = fsi_slave_read(slave, off, buf + total_len, read_len); if (rc) @@ -587,8 +611,7 @@ return -EINVAL; for (total_len = 0; total_len < count; total_len += write_len) { - write_len = min_t(size_t, count, 4); - write_len -= off & 0x3; + write_len = aligned_access_size(off, count - total_len); rc = fsi_slave_write(slave, off, buf + total_len, write_len); if (rc) @@ -695,7 +718,7 @@ rc = count; fail: *offset = off; - return count; + return rc; } static ssize_t cfam_write(struct file *filep, const char __user *buf, @@ -732,7 +755,7 @@ rc = count; fail: *offset = off; - return count; + return rc; } static loff_t cfam_llseek(struct file *file, loff_t offset, int whence) @@ -1248,6 +1271,9 @@ mutex_init(&master->scan_lock); master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL); + if (master->idx < 0) + return master->idx; + dev_set_name(&master->dev, "fsi%d", master->idx); rc = device_register(&master->dev); --- linux-oracle-5.4.0.orig/drivers/fsi/fsi-master-ast-cf.c +++ linux-oracle-5.4.0/drivers/fsi/fsi-master-ast-cf.c @@ -1438,3 +1438,4 @@ module_platform_driver(fsi_master_acf); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE(FW_FILE_NAME); --- linux-oracle-5.4.0.orig/drivers/fsi/fsi-occ.c +++ linux-oracle-5.4.0/drivers/fsi/fsi-occ.c @@ -445,6 +445,7 @@ goto done; if (resp->return_status == OCC_RESP_CMD_IN_PRG || + resp->return_status == OCC_RESP_CRIT_INIT || resp->seq_no != seq_no) { rc = -ETIMEDOUT; --- linux-oracle-5.4.0.orig/drivers/fsi/fsi-sbefifo.c +++ linux-oracle-5.4.0/drivers/fsi/fsi-sbefifo.c @@ -325,7 +325,8 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo) { struct device *dev = &sbefifo->fsi_dev->dev; - u32 status, timeout; + unsigned long end_time; + u32 status; int rc; dev_dbg(dev, "Requesting FIFO reset\n"); @@ -341,7 +342,8 @@ } /* Wait for it to complete */ - for (timeout = 0; timeout < SBEFIFO_RESET_TIMEOUT; timeout++) { + end_time = jiffies + msecs_to_jiffies(SBEFIFO_RESET_TIMEOUT); + while (!time_after(jiffies, end_time)) { rc = sbefifo_regr(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &status); if (rc) { dev_err(dev, "Failed to read UP fifo status during reset" @@ -355,7 +357,7 @@ return 0; } - msleep(1); + cond_resched(); } dev_err(dev, "FIFO reset timed out\n"); @@ -400,7 +402,7 @@ /* The FIFO already contains a reset request from the SBE ? */ if (down_status & SBEFIFO_STS_RESET_REQ) { dev_info(dev, "Cleanup: FIFO reset request set, resetting\n"); - rc = sbefifo_regw(sbefifo, SBEFIFO_UP, SBEFIFO_PERFORM_RESET); + rc = sbefifo_regw(sbefifo, SBEFIFO_DOWN, SBEFIFO_PERFORM_RESET); if (rc) { sbefifo->broken = true; dev_err(dev, "Cleanup: Reset reg write failed, rc=%d\n", rc); @@ -638,7 +640,7 @@ } ffdc_iov.iov_base = ffdc; ffdc_iov.iov_len = SBEFIFO_MAX_FFDC_SIZE; - iov_iter_kvec(&ffdc_iter, WRITE, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); + iov_iter_kvec(&ffdc_iter, READ, &ffdc_iov, 1, SBEFIFO_MAX_FFDC_SIZE); cmd[0] = cpu_to_be32(2); cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC); rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter); @@ -735,7 +737,7 @@ rbytes = (*resp_len) * sizeof(__be32); resp_iov.iov_base = response; resp_iov.iov_len = rbytes; - iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes); + iov_iter_kvec(&resp_iter, READ, &resp_iov, 1, rbytes); /* Perform the command */ mutex_lock(&sbefifo->lock); @@ -815,7 +817,7 @@ /* Prepare iov iterator */ resp_iov.iov_base = buf; resp_iov.iov_len = len; - iov_iter_init(&resp_iter, WRITE, &resp_iov, 1, len); + iov_iter_init(&resp_iter, READ, &resp_iov, 1, len); /* Perform the command */ mutex_lock(&sbefifo->lock); --- linux-oracle-5.4.0.orig/drivers/fsi/fsi-scom.c +++ linux-oracle-5.4.0/drivers/fsi/fsi-scom.c @@ -38,9 +38,10 @@ #define SCOM_STATUS_PIB_RESP_MASK 0x00007000 #define SCOM_STATUS_PIB_RESP_SHIFT 12 -#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_PROTECTION | \ - SCOM_STATUS_PARITY | \ - SCOM_STATUS_PIB_ABORT | \ +#define SCOM_STATUS_FSI2PIB_ERROR (SCOM_STATUS_PROTECTION | \ + SCOM_STATUS_PARITY | \ + SCOM_STATUS_PIB_ABORT) +#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_FSI2PIB_ERROR | \ SCOM_STATUS_PIB_RESP_MASK) /* SCOM address encodings */ #define XSCOM_ADDR_IND_FLAG BIT_ULL(63) @@ -240,13 +241,14 @@ { uint32_t dummy = -1; - if (status & SCOM_STATUS_PROTECTION) - return -EPERM; - if (status & SCOM_STATUS_PARITY) { + if (status & SCOM_STATUS_FSI2PIB_ERROR) fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, sizeof(uint32_t)); + + if (status & SCOM_STATUS_PROTECTION) + return -EPERM; + if (status & SCOM_STATUS_PARITY) return -EIO; - } /* Return -EBUSY on PIB abort to force a retry */ if (status & SCOM_STATUS_PIB_ABORT) return -EBUSY; --- linux-oracle-5.4.0.orig/drivers/gnss/sirf.c +++ linux-oracle-5.4.0/drivers/gnss/sirf.c @@ -439,14 +439,18 @@ data->on_off = devm_gpiod_get_optional(dev, "sirf,onoff", GPIOD_OUT_LOW); - if (IS_ERR(data->on_off)) + if (IS_ERR(data->on_off)) { + ret = PTR_ERR(data->on_off); goto err_put_device; + } if (data->on_off) { data->wakeup = devm_gpiod_get_optional(dev, "sirf,wakeup", GPIOD_IN); - if (IS_ERR(data->wakeup)) + if (IS_ERR(data->wakeup)) { + ret = PTR_ERR(data->wakeup); goto err_put_device; + } ret = regulator_enable(data->vcc); if (ret) --- linux-oracle-5.4.0.orig/drivers/gpio/Kconfig +++ linux-oracle-5.4.0/drivers/gpio/Kconfig @@ -546,7 +546,6 @@ tristate "Cavium ThunderX/OCTEON-TX GPIO" depends on ARCH_THUNDER || (64BIT && COMPILE_TEST) depends on PCI_MSI - select GPIOLIB_IRQCHIP select IRQ_DOMAIN_HIERARCHY select IRQ_FASTEOI_HIERARCHY_HANDLERS help @@ -1121,6 +1120,7 @@ config GPIO_MAX77620 tristate "GPIO support for PMIC MAX77620 and MAX20024" depends on MFD_MAX77620 + select GPIOLIB_IRQCHIP help GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. MAX77620 PMIC has 8 pins that can be configured as GPIOs. The @@ -1230,8 +1230,9 @@ drivers are loaded. config GPIO_TQMX86 - tristate "TQ-Systems QTMX86 GPIO" + tristate "TQ-Systems TQMx86 GPIO" depends on MFD_TQMX86 || COMPILE_TEST + depends on HAS_IOPORT_MAP select GPIOLIB_IRQCHIP help This driver supports GPIO on the TQMX86 IO controller. @@ -1299,6 +1300,7 @@ config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" depends on X86 || COMPILE_TEST + depends on HAS_IOPORT_MAP help The AMD 8111 south bridge contains 32 GPIO pins which can be used. --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-74x164.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-74x164.c @@ -128,8 +128,6 @@ if (IS_ERR(chip->gpiod_oe)) return PTR_ERR(chip->gpiod_oe); - gpiod_set_value_cansleep(chip->gpiod_oe, 1); - spi_set_drvdata(spi, chip); chip->gpio_chip.label = spi->modalias; @@ -154,6 +152,8 @@ goto exit_destroy; } + gpiod_set_value_cansleep(chip->gpiod_oe, 1); + ret = gpiochip_add_data(&chip->gpio_chip, chip); if (!ret) return 0; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-amd8111.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-amd8111.c @@ -231,7 +231,10 @@ ioport_unmap(gp.pm); goto out; } + return 0; + out: + pci_dev_put(pdev); return err; } @@ -239,6 +242,7 @@ { gpiochip_remove(&gp.chip); ioport_unmap(gp.pm); + pci_dev_put(gp.pdev); } module_init(amd_gpio_init); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-arizona.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-arizona.c @@ -64,6 +64,7 @@ ret = pm_runtime_get_sync(chip->parent); if (ret < 0) { dev_err(chip->parent, "Failed to resume: %d\n", ret); + pm_runtime_put_autosuspend(chip->parent); return ret; } @@ -72,12 +73,15 @@ if (ret < 0) { dev_err(chip->parent, "Failed to drop cache: %d\n", ret); + pm_runtime_put_autosuspend(chip->parent); return ret; } ret = regmap_read(arizona->regmap, reg, &val); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(chip->parent); return ret; + } pm_runtime_mark_last_busy(chip->parent); pm_runtime_put_autosuspend(chip->parent); @@ -106,6 +110,7 @@ ret = pm_runtime_get_sync(chip->parent); if (ret < 0) { dev_err(chip->parent, "Failed to resume: %d\n", ret); + pm_runtime_put(chip->parent); return ret; } } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-aspeed.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-aspeed.c @@ -53,7 +53,7 @@ struct aspeed_gpio { struct gpio_chip chip; struct irq_chip irqc; - spinlock_t lock; + raw_spinlock_t lock; void __iomem *base; int irq; const struct aspeed_gpio_config *config; @@ -404,6 +404,8 @@ gpio->dcache[GPIO_BANK(offset)] = reg; iowrite32(reg, addr); + /* Flush write */ + ioread32(addr); } static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, @@ -413,14 +415,14 @@ unsigned long flags; bool copro; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); copro = aspeed_gpio_copro_request(gpio, offset); __aspeed_gpio_set(gc, offset, val); if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); } static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) @@ -435,7 +437,7 @@ if (!have_input(gpio, offset)) return -ENOTSUPP; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); reg = ioread32(addr); reg &= ~GPIO_BIT(offset); @@ -445,7 +447,7 @@ if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return 0; } @@ -463,7 +465,7 @@ if (!have_output(gpio, offset)) return -ENOTSUPP; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); reg = ioread32(addr); reg |= GPIO_BIT(offset); @@ -474,7 +476,7 @@ if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return 0; } @@ -492,11 +494,11 @@ if (!have_output(gpio, offset)) return 1; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return !val; @@ -540,14 +542,14 @@ status_addr = bank_reg(gpio, bank, reg_irq_status); - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); copro = aspeed_gpio_copro_request(gpio, offset); iowrite32(bit, status_addr); if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); } static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) @@ -566,7 +568,7 @@ addr = bank_reg(gpio, bank, reg_irq_enable); - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); copro = aspeed_gpio_copro_request(gpio, offset); reg = ioread32(addr); @@ -578,7 +580,7 @@ if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); } static void aspeed_gpio_irq_mask(struct irq_data *d) @@ -630,7 +632,7 @@ return -EINVAL; } - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); copro = aspeed_gpio_copro_request(gpio, offset); addr = bank_reg(gpio, bank, reg_irq_type0); @@ -650,7 +652,7 @@ if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); irq_set_handler_locked(d, handler); @@ -720,7 +722,7 @@ treg = bank_reg(gpio, to_bank(offset), reg_tolerance); - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); copro = aspeed_gpio_copro_request(gpio, offset); val = readl(treg); @@ -734,7 +736,7 @@ if (copro) aspeed_gpio_copro_release(gpio, offset); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return 0; } @@ -860,7 +862,7 @@ return rc; } - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); if (timer_allocation_registered(gpio, offset)) { rc = unregister_allocated_timer(gpio, offset); @@ -920,7 +922,7 @@ configure_timer(gpio, offset, i); out: - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return rc; } @@ -931,13 +933,13 @@ unsigned long flags; int rc; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); rc = unregister_allocated_timer(gpio, offset); if (!rc) configure_timer(gpio, offset, 0); - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return rc; } @@ -967,7 +969,7 @@ else if (param == PIN_CONFIG_BIAS_DISABLE || param == PIN_CONFIG_BIAS_PULL_DOWN || param == PIN_CONFIG_DRIVE_STRENGTH) - return pinctrl_gpio_set_config(offset, config); + return pinctrl_gpio_set_config(chip->base + offset, config); else if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN || param == PIN_CONFIG_DRIVE_OPEN_SOURCE) /* Return -ENOTSUPP to trigger emulation, as per datasheet */ @@ -1019,7 +1021,7 @@ return -EINVAL; bindex = offset >> 3; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); /* Sanity check, this shouldn't happen */ if (gpio->cf_copro_bankmap[bindex] == 0xff) { @@ -1040,7 +1042,7 @@ if (bit) *bit = GPIO_OFFSET(offset); bail: - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return rc; } EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio); @@ -1064,7 +1066,7 @@ return -EINVAL; bindex = offset >> 3; - spin_lock_irqsave(&gpio->lock, flags); + raw_spin_lock_irqsave(&gpio->lock, flags); /* Sanity check, this shouldn't happen */ if (gpio->cf_copro_bankmap[bindex] == 0) { @@ -1078,7 +1080,7 @@ aspeed_gpio_change_cmd_source(gpio, bank, bindex, GPIO_CMDSRC_ARM); bail: - spin_unlock_irqrestore(&gpio->lock, flags); + raw_spin_unlock_irqrestore(&gpio->lock, flags); return rc; } EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio); @@ -1115,8 +1117,8 @@ static const struct aspeed_bank_props ast2600_bank_props[] = { /* input output */ - {5, 0xffffffff, 0x0000ffff}, /* U/V/W/X */ - {6, 0xffff0000, 0x0fff0000}, /* Y/Z */ + {5, 0xffffffff, 0xffffff00}, /* U/V/W/X */ + {6, 0x0000ffff, 0x0000ffff}, /* Y/Z */ { }, }; @@ -1151,13 +1153,13 @@ if (IS_ERR(gpio->base)) return PTR_ERR(gpio->base); - spin_lock_init(&gpio->lock); + raw_spin_lock_init(&gpio->lock); gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node); if (!gpio_id) return -EINVAL; - gpio->clk = of_clk_get(pdev->dev.of_node, 0); + gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(gpio->clk)) { dev_warn(&pdev->dev, "Failed to get clock from devicetree, debouncing disabled\n"); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-bcm-kona.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-bcm-kona.c @@ -77,6 +77,22 @@ struct bcm_kona_gpio_bank { int id; int irq; + /* + * Used to keep track of lock/unlock operations for each GPIO in the + * bank. + * + * All GPIOs are locked by default (see bcm_kona_gpio_reset), and the + * unlock count for all GPIOs is 0 by default. Each unlock increments + * the counter, and each lock decrements the counter. + * + * The lock function only locks the GPIO once its unlock counter is + * down to 0. This is necessary because the GPIO is unlocked in two + * places in this driver: once for requested GPIOs, and once for + * requested IRQs. Since it is possible for a GPIO to be requested + * as both a GPIO and an IRQ, we need to ensure that we don't lock it + * too early. + */ + u8 gpio_unlock_count[GPIO_PER_BANK]; /* Used in the interrupt handler */ struct bcm_kona_gpio *kona_gpio; }; @@ -94,14 +110,24 @@ u32 val; unsigned long flags; int bank_id = GPIO_BANK(gpio); + int bit = GPIO_BIT(gpio); + struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; - raw_spin_lock_irqsave(&kona_gpio->lock, flags); + if (bank->gpio_unlock_count[bit] == 0) { + dev_err(kona_gpio->gpio_chip.parent, + "Unbalanced locks for GPIO %u\n", gpio); + return; + } - val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); - val |= BIT(gpio); - bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); + if (--bank->gpio_unlock_count[bit] == 0) { + raw_spin_lock_irqsave(&kona_gpio->lock, flags); - raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); + val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); + val |= BIT(bit); + bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); + + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); + } } static void bcm_kona_gpio_unlock_gpio(struct bcm_kona_gpio *kona_gpio, @@ -110,14 +136,20 @@ u32 val; unsigned long flags; int bank_id = GPIO_BANK(gpio); + int bit = GPIO_BIT(gpio); + struct bcm_kona_gpio_bank *bank = &kona_gpio->banks[bank_id]; - raw_spin_lock_irqsave(&kona_gpio->lock, flags); + if (bank->gpio_unlock_count[bit] == 0) { + raw_spin_lock_irqsave(&kona_gpio->lock, flags); - val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); - val &= ~BIT(gpio); - bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); + val = readl(kona_gpio->reg_base + GPIO_PWD_STATUS(bank_id)); + val &= ~BIT(bit); + bcm_kona_gpio_write_lock_regs(kona_gpio->reg_base, bank_id, val); - raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); + raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); + } + + ++bank->gpio_unlock_count[bit]; } static int bcm_kona_gpio_get_dir(struct gpio_chip *chip, unsigned gpio) @@ -368,6 +400,7 @@ kona_gpio = irq_data_get_irq_chip_data(d); reg_base = kona_gpio->reg_base; + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_INT_MASK(bank_id)); @@ -390,6 +423,7 @@ kona_gpio = irq_data_get_irq_chip_data(d); reg_base = kona_gpio->reg_base; + raw_spin_lock_irqsave(&kona_gpio->lock, flags); val = readl(reg_base + GPIO_INT_MSKCLR(bank_id)); @@ -487,15 +521,26 @@ static int bcm_kona_gpio_irq_reqres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); + unsigned int gpio = d->hwirq; - return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); + /* + * We need to unlock the GPIO before any other operations are performed + * on the relevant GPIO configuration registers + */ + bcm_kona_gpio_unlock_gpio(kona_gpio, gpio); + + return gpiochip_reqres_irq(&kona_gpio->gpio_chip, gpio); } static void bcm_kona_gpio_irq_relres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); + unsigned int gpio = d->hwirq; + + /* Once we no longer use it, lock the GPIO again */ + bcm_kona_gpio_lock_gpio(kona_gpio, gpio); - gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); + gpiochip_relres_irq(&kona_gpio->gpio_chip, gpio); } static struct irq_chip bcm_gpio_irq_chip = { @@ -619,7 +664,7 @@ kona_gpio->reg_base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(kona_gpio->reg_base)) { - ret = -ENXIO; + ret = PTR_ERR(kona_gpio->reg_base); goto err_irq_domain; } @@ -629,7 +674,7 @@ bank->irq = platform_get_irq(pdev, i); bank->kona_gpio = kona_gpio; if (bank->irq < 0) { - dev_err(dev, "Couldn't get IRQ for bank %d", i); + dev_err(dev, "Couldn't get IRQ for bank %d\n", i); ret = -ENOENT; goto err_irq_domain; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-cadence.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-cadence.c @@ -278,6 +278,7 @@ { .compatible = "cdns,gpio-r1p02" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, cdns_of_ids); static struct platform_driver cdns_gpio_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-crystalcove.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-crystalcove.c @@ -91,7 +91,7 @@ case 0x5e: return GPIOPANELCTL; default: - return -EOPNOTSUPP; + return -ENOTSUPP; } } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-davinci.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-davinci.c @@ -227,6 +227,11 @@ else nirq = DIV_ROUND_UP(ngpio, 16); + if (nirq > MAX_INT_PER_BANK) { + dev_err(dev, "Too many IRQs!\n"); + return -EINVAL; + } + chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL); if (!chips) return -ENOMEM; @@ -295,7 +300,7 @@ * serve as EDMA event triggers. */ -static void gpio_irq_disable(struct irq_data *d) +static void gpio_irq_mask(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); @@ -304,7 +309,7 @@ writel_relaxed(mask, &g->clr_rising); } -static void gpio_irq_enable(struct irq_data *d) +static void gpio_irq_unmask(struct irq_data *d) { struct davinci_gpio_regs __iomem *g = irq2regs(d); uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d); @@ -330,10 +335,10 @@ static struct irq_chip gpio_irqchip = { .name = "GPIO", - .irq_enable = gpio_irq_enable, - .irq_disable = gpio_irq_disable, + .irq_unmask = gpio_irq_unmask, + .irq_mask = gpio_irq_mask, .irq_set_type = gpio_irq_type, - .flags = IRQCHIP_SET_TYPE_MASKED, + .flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE, }; static void gpio_irq_handler(struct irq_desc *desc) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-dwapb.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-dwapb.c @@ -49,7 +49,9 @@ #define GPIO_EXT_PORTC 0x58 #define GPIO_EXT_PORTD 0x5c +#define DWAPB_DRIVER_NAME "gpio-dwapb" #define DWAPB_MAX_PORTS 4 + #define GPIO_EXT_PORT_STRIDE 0x04 /* register stride 32 bits */ #define GPIO_SWPORT_DR_STRIDE 0x0c /* register stride 3*32 bits */ #define GPIO_SWPORT_DDR_STRIDE 0x0c /* register stride 3*32 bits */ @@ -398,7 +400,7 @@ return; err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2, - "gpio-dwapb", handle_level_irq, + DWAPB_DRIVER_NAME, handle_level_irq, IRQ_NOREQUEST, 0, IRQ_GC_INIT_NESTED_LOCK); if (err) { @@ -455,7 +457,7 @@ */ err = devm_request_irq(gpio->dev, pp->irq[0], dwapb_irq_handler_mfd, - IRQF_SHARED, "gpio-dwapb-mfd", gpio); + IRQF_SHARED, DWAPB_DRIVER_NAME, gpio); if (err) { dev_err(gpio->dev, "error requesting IRQ\n"); irq_domain_remove(gpio->domain); @@ -533,26 +535,33 @@ dwapb_configure_irqs(gpio, port, pp); err = gpiochip_add_data(&port->gc, port); - if (err) + if (err) { dev_err(gpio->dev, "failed to register gpiochip for port%d\n", port->idx); - else - port->is_registered = true; + return err; + } /* Add GPIO-signaled ACPI event support */ - if (pp->has_irq) - acpi_gpiochip_request_interrupts(&port->gc); + acpi_gpiochip_request_interrupts(&port->gc); - return err; + port->is_registered = true; + + return 0; } static void dwapb_gpio_unregister(struct dwapb_gpio *gpio) { unsigned int m; - for (m = 0; m < gpio->nr_ports; ++m) - if (gpio->ports[m].is_registered) - gpiochip_remove(&gpio->ports[m].gc); + for (m = 0; m < gpio->nr_ports; ++m) { + struct dwapb_gpio_port *port = &gpio->ports[m]; + + if (!port->is_registered) + continue; + + acpi_gpiochip_free_interrupts(&port->gc); + gpiochip_remove(&port->gc); + } } static struct dwapb_platform_data * @@ -836,7 +845,7 @@ static struct platform_driver dwapb_gpio_driver = { .driver = { - .name = "gpio-dwapb", + .name = DWAPB_DRIVER_NAME, .pm = &dwapb_gpio_pm_ops, .of_match_table = of_match_ptr(dwapb_of_match), .acpi_match_table = ACPI_PTR(dwapb_acpi_match), @@ -850,3 +859,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jamie Iles"); MODULE_DESCRIPTION("Synopsys DesignWare APB GPIO driver"); +MODULE_ALIAS("platform:" DWAPB_DRIVER_NAME); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-eic-sprd.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-eic-sprd.c @@ -318,20 +318,27 @@ switch (flow_type) { case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); + sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); + sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); break; case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: state = sprd_eic_get(chip, offset); - if (state) + if (state) { sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); - else + sprd_eic_update(chip, offset, + SPRD_EIC_DBNC_IC, 1); + } else { sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); + sprd_eic_update(chip, offset, + SPRD_EIC_DBNC_IC, 1); + } break; default: return -ENOTSUPP; @@ -343,20 +350,27 @@ switch (flow_type) { case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); break; case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: state = sprd_eic_get(chip, offset); - if (state) + if (state) { sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); - else + sprd_eic_update(chip, offset, + SPRD_EIC_LATCH_INTCLR, 1); + } else { sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); + sprd_eic_update(chip, offset, + SPRD_EIC_LATCH_INTCLR, 1); + } break; default: return -ENOTSUPP; @@ -370,29 +384,34 @@ sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_BOTH: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; default: @@ -405,29 +424,34 @@ sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_BOTH: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; default: @@ -569,6 +593,7 @@ const struct sprd_eic_variant_data *pdata; struct gpio_irq_chip *irq; struct sprd_eic *sprd_eic; + struct resource *res; int ret, i; pdata = of_device_get_match_data(&pdev->dev); @@ -595,9 +620,13 @@ * have one bank EIC, thus base[1] and base[2] can be * optional. */ - sprd_eic->base[i] = devm_platform_ioremap_resource(pdev, i); + res = platform_get_resource(pdev, IORESOURCE_MEM, i); + if (!res) + break; + + sprd_eic->base[i] = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(sprd_eic->base[i])) - continue; + return PTR_ERR(sprd_eic->base[i]); } sprd_eic->chip.label = sprd_eic_label_name[sprd_eic->type]; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-ep93xx.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-ep93xx.c @@ -25,6 +25,9 @@ /* Maximum value for gpio line identifiers */ #define EP93XX_GPIO_LINE_MAX 63 +/* Number of GPIO chips in EP93XX */ +#define EP93XX_GPIO_CHIP_NUM 8 + /* Maximum value for irq capable line identifiers */ #define EP93XX_GPIO_LINE_MAX_IRQ 23 @@ -34,74 +37,75 @@ */ #define EP93XX_GPIO_F_IRQ_BASE 80 +struct ep93xx_gpio_irq_chip { + struct irq_chip ic; + u8 irq_offset; + u8 int_unmasked; + u8 int_enabled; + u8 int_type1; + u8 int_type2; + u8 int_debounce; +}; + +struct ep93xx_gpio_chip { + struct gpio_chip gc; + struct ep93xx_gpio_irq_chip *eic; +}; + struct ep93xx_gpio { void __iomem *base; - struct gpio_chip gc[8]; + struct ep93xx_gpio_chip gc[EP93XX_GPIO_CHIP_NUM]; }; -/************************************************************************* - * Interrupt handling for EP93xx on-chip GPIOs - *************************************************************************/ -static unsigned char gpio_int_unmasked[3]; -static unsigned char gpio_int_enabled[3]; -static unsigned char gpio_int_type1[3]; -static unsigned char gpio_int_type2[3]; -static unsigned char gpio_int_debounce[3]; - -/* Port ordering is: A B F */ -static const u8 int_type1_register_offset[3] = { 0x90, 0xac, 0x4c }; -static const u8 int_type2_register_offset[3] = { 0x94, 0xb0, 0x50 }; -static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 }; -static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 }; -static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 }; +#define to_ep93xx_gpio_chip(x) container_of(x, struct ep93xx_gpio_chip, gc) -static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, unsigned port) +static struct ep93xx_gpio_irq_chip *to_ep93xx_gpio_irq_chip(struct gpio_chip *gc) { - BUG_ON(port > 2); - - writeb_relaxed(0, epg->base + int_en_register_offset[port]); + struct ep93xx_gpio_chip *egc = to_ep93xx_gpio_chip(gc); - writeb_relaxed(gpio_int_type2[port], - epg->base + int_type2_register_offset[port]); - - writeb_relaxed(gpio_int_type1[port], - epg->base + int_type1_register_offset[port]); - - writeb(gpio_int_unmasked[port] & gpio_int_enabled[port], - epg->base + int_en_register_offset[port]); + return egc->eic; } -static int ep93xx_gpio_port(struct gpio_chip *gc) -{ - struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = 0; +/************************************************************************* + * Interrupt handling for EP93xx on-chip GPIOs + *************************************************************************/ +#define EP93XX_INT_TYPE1_OFFSET 0x00 +#define EP93XX_INT_TYPE2_OFFSET 0x04 +#define EP93XX_INT_EOI_OFFSET 0x08 +#define EP93XX_INT_EN_OFFSET 0x0c +#define EP93XX_INT_STATUS_OFFSET 0x10 +#define EP93XX_INT_RAW_STATUS_OFFSET 0x14 +#define EP93XX_INT_DEBOUNCE_OFFSET 0x18 + +static void ep93xx_gpio_update_int_params(struct ep93xx_gpio *epg, + struct ep93xx_gpio_irq_chip *eic) +{ + writeb_relaxed(0, epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET); - while (port < ARRAY_SIZE(epg->gc) && gc != &epg->gc[port]) - port++; + writeb_relaxed(eic->int_type2, + epg->base + eic->irq_offset + EP93XX_INT_TYPE2_OFFSET); - /* This should not happen but is there as a last safeguard */ - if (port == ARRAY_SIZE(epg->gc)) { - pr_crit("can't find the GPIO port\n"); - return 0; - } + writeb_relaxed(eic->int_type1, + epg->base + eic->irq_offset + EP93XX_INT_TYPE1_OFFSET); - return port; + writeb_relaxed(eic->int_unmasked & eic->int_enabled, + epg->base + eic->irq_offset + EP93XX_INT_EN_OFFSET); } static void ep93xx_gpio_int_debounce(struct gpio_chip *gc, unsigned int offset, bool enable) { struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); int port_mask = BIT(offset); if (enable) - gpio_int_debounce[port] |= port_mask; + eic->int_debounce |= port_mask; else - gpio_int_debounce[port] &= ~port_mask; + eic->int_debounce &= ~port_mask; - writeb(gpio_int_debounce[port], - epg->base + int_debounce_register_offset[port]); + writeb(eic->int_debounce, + epg->base + eic->irq_offset + EP93XX_INT_DEBOUNCE_OFFSET); } static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc) @@ -122,12 +126,12 @@ */ stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS); for_each_set_bit(offset, &stat, 8) - generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain, + generic_handle_irq(irq_find_mapping(epg->gc[0].gc.irq.domain, offset)); stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS); for_each_set_bit(offset, &stat, 8) - generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain, + generic_handle_irq(irq_find_mapping(epg->gc[1].gc.irq.domain, offset)); chained_irq_exit(irqchip, desc); @@ -153,52 +157,52 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); int port_mask = BIT(d->irq & 7); if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) { - gpio_int_type2[port] ^= port_mask; /* switch edge direction */ - ep93xx_gpio_update_int_params(epg, port); + eic->int_type2 ^= port_mask; /* switch edge direction */ + ep93xx_gpio_update_int_params(epg, eic); } - writeb(port_mask, epg->base + eoi_register_offset[port]); + writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET); } static void ep93xx_gpio_irq_mask_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); int port_mask = BIT(d->irq & 7); if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) - gpio_int_type2[port] ^= port_mask; /* switch edge direction */ + eic->int_type2 ^= port_mask; /* switch edge direction */ - gpio_int_unmasked[port] &= ~port_mask; - ep93xx_gpio_update_int_params(epg, port); + eic->int_unmasked &= ~port_mask; + ep93xx_gpio_update_int_params(epg, eic); - writeb(port_mask, epg->base + eoi_register_offset[port]); + writeb(port_mask, epg->base + eic->irq_offset + EP93XX_INT_EOI_OFFSET); } static void ep93xx_gpio_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); - gpio_int_unmasked[port] &= ~BIT(d->irq & 7); - ep93xx_gpio_update_int_params(epg, port); + eic->int_unmasked &= ~BIT(d->irq & 7); + ep93xx_gpio_update_int_params(epg, eic); } static void ep93xx_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); - gpio_int_unmasked[port] |= BIT(d->irq & 7); - ep93xx_gpio_update_int_params(epg, port); + eic->int_unmasked |= BIT(d->irq & 7); + ep93xx_gpio_update_int_params(epg, eic); } /* @@ -209,8 +213,8 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct ep93xx_gpio_irq_chip *eic = to_ep93xx_gpio_irq_chip(gc); struct ep93xx_gpio *epg = gpiochip_get_data(gc); - int port = ep93xx_gpio_port(gc); int offset = d->irq & 7; int port_mask = BIT(offset); irq_flow_handler_t handler; @@ -219,32 +223,32 @@ switch (type) { case IRQ_TYPE_EDGE_RISING: - gpio_int_type1[port] |= port_mask; - gpio_int_type2[port] |= port_mask; + eic->int_type1 |= port_mask; + eic->int_type2 |= port_mask; handler = handle_edge_irq; break; case IRQ_TYPE_EDGE_FALLING: - gpio_int_type1[port] |= port_mask; - gpio_int_type2[port] &= ~port_mask; + eic->int_type1 |= port_mask; + eic->int_type2 &= ~port_mask; handler = handle_edge_irq; break; case IRQ_TYPE_LEVEL_HIGH: - gpio_int_type1[port] &= ~port_mask; - gpio_int_type2[port] |= port_mask; + eic->int_type1 &= ~port_mask; + eic->int_type2 |= port_mask; handler = handle_level_irq; break; case IRQ_TYPE_LEVEL_LOW: - gpio_int_type1[port] &= ~port_mask; - gpio_int_type2[port] &= ~port_mask; + eic->int_type1 &= ~port_mask; + eic->int_type2 &= ~port_mask; handler = handle_level_irq; break; case IRQ_TYPE_EDGE_BOTH: - gpio_int_type1[port] |= port_mask; + eic->int_type1 |= port_mask; /* set initial polarity based on current input level */ if (gc->get(gc, offset)) - gpio_int_type2[port] &= ~port_mask; /* falling */ + eic->int_type2 &= ~port_mask; /* falling */ else - gpio_int_type2[port] |= port_mask; /* rising */ + eic->int_type2 |= port_mask; /* rising */ handler = handle_edge_irq; break; default: @@ -253,22 +257,13 @@ irq_set_handler_locked(d, handler); - gpio_int_enabled[port] |= port_mask; + eic->int_enabled |= port_mask; - ep93xx_gpio_update_int_params(epg, port); + ep93xx_gpio_update_int_params(epg, eic); return 0; } -static struct irq_chip ep93xx_gpio_irq_chip = { - .name = "GPIO", - .irq_ack = ep93xx_gpio_irq_ack, - .irq_mask_ack = ep93xx_gpio_irq_mask_ack, - .irq_mask = ep93xx_gpio_irq_mask, - .irq_unmask = ep93xx_gpio_irq_unmask, - .irq_set_type = ep93xx_gpio_irq_type, -}; - /************************************************************************* * gpiolib interface for EP93xx on-chip GPIOs *************************************************************************/ @@ -276,17 +271,19 @@ const char *label; int data; int dir; + int irq; int base; bool has_irq; bool has_hierarchical_irq; unsigned int irq_base; }; -#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq, _has_hier, _irq_base) \ +#define EP93XX_GPIO_BANK(_label, _data, _dir, _irq, _base, _has_irq, _has_hier, _irq_base) \ { \ .label = _label, \ .data = _data, \ .dir = _dir, \ + .irq = _irq, \ .base = _base, \ .has_irq = _has_irq, \ .has_hierarchical_irq = _has_hier, \ @@ -295,16 +292,16 @@ static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = { /* Bank A has 8 IRQs */ - EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true, false, 64), + EP93XX_GPIO_BANK("A", 0x00, 0x10, 0x90, 0, true, false, 64), /* Bank B has 8 IRQs */ - EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true, false, 72), - EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false, false, 0), - EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false, false, 0), - EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false, false, 0), + EP93XX_GPIO_BANK("B", 0x04, 0x14, 0xac, 8, true, false, 72), + EP93XX_GPIO_BANK("C", 0x08, 0x18, 0x00, 40, false, false, 0), + EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 0x00, 24, false, false, 0), + EP93XX_GPIO_BANK("E", 0x20, 0x24, 0x00, 32, false, false, 0), /* Bank F has 8 IRQs */ - EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, false, true, 0), - EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false, false, 0), - EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false, false, 0), + EP93XX_GPIO_BANK("F", 0x30, 0x34, 0x4c, 16, false, true, 0), + EP93XX_GPIO_BANK("G", 0x38, 0x3c, 0x00, 48, false, false, 0), + EP93XX_GPIO_BANK("H", 0x40, 0x44, 0x00, 56, false, false, 0), }; static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset, @@ -326,13 +323,23 @@ return EP93XX_GPIO_F_IRQ_BASE + offset; } -static int ep93xx_gpio_add_bank(struct gpio_chip *gc, +static void ep93xx_init_irq_chip(struct device *dev, struct irq_chip *ic) +{ + ic->irq_ack = ep93xx_gpio_irq_ack; + ic->irq_mask_ack = ep93xx_gpio_irq_mask_ack; + ic->irq_mask = ep93xx_gpio_irq_mask; + ic->irq_unmask = ep93xx_gpio_irq_unmask; + ic->irq_set_type = ep93xx_gpio_irq_type; +} + +static int ep93xx_gpio_add_bank(struct ep93xx_gpio_chip *egc, struct platform_device *pdev, struct ep93xx_gpio *epg, struct ep93xx_gpio_bank *bank) { void __iomem *data = epg->base + bank->data; void __iomem *dir = epg->base + bank->dir; + struct gpio_chip *gc = &egc->gc; struct device *dev = &pdev->dev; struct gpio_irq_chip *girq; int err; @@ -346,8 +353,21 @@ girq = &gc->irq; if (bank->has_irq || bank->has_hierarchical_irq) { + struct irq_chip *ic; + gc->set_config = ep93xx_gpio_set_config; - girq->chip = &ep93xx_gpio_irq_chip; + egc->eic = devm_kcalloc(dev, 1, + sizeof(*egc->eic), + GFP_KERNEL); + if (!egc->eic) + return -ENOMEM; + egc->eic->irq_offset = bank->irq; + ic = &egc->eic->ic; + ic->name = devm_kasprintf(dev, GFP_KERNEL, "gpio-irq-%s", bank->label); + if (!ic->name) + return -ENOMEM; + ep93xx_init_irq_chip(dev, ic); + girq->chip = ic; } if (bank->has_irq) { @@ -389,7 +409,7 @@ gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i; irq_set_chip_data(gpio_irq, &epg->gc[5]); irq_set_chip_and_handler(gpio_irq, - &ep93xx_gpio_irq_chip, + girq->chip, handle_level_irq); irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); } @@ -415,7 +435,7 @@ return PTR_ERR(epg->base); for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { - struct gpio_chip *gc = &epg->gc[i]; + struct ep93xx_gpio_chip *gc = &epg->gc[i]; struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i]; if (ep93xx_gpio_add_bank(gc, pdev, epg, bank)) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-exar.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-exar.c @@ -145,8 +145,10 @@ mutex_init(&exar_gpio->lock); index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL); - if (index < 0) - goto err_destroy; + if (index < 0) { + ret = index; + goto err_mutex_destroy; + } sprintf(exar_gpio->name, "exar_gpio%d", index); exar_gpio->gpio_chip.label = exar_gpio->name; @@ -173,6 +175,7 @@ err_destroy: ida_simple_remove(&ida_index, index); +err_mutex_destroy: mutex_destroy(&exar_gpio->lock); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-grgpio.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-grgpio.c @@ -253,17 +253,16 @@ lirq->irq = irq; uirq = &priv->uirqs[lirq->index]; if (uirq->refcnt == 0) { + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); ret = request_irq(uirq->uirq, grgpio_irq_handler, 0, dev_name(priv->dev), priv); if (ret) { dev_err(priv->dev, "Could not request underlying irq %d\n", uirq->uirq); - - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); - return ret; } + spin_lock_irqsave(&priv->gc.bgpio_lock, flags); } uirq->refcnt++; @@ -309,8 +308,11 @@ if (index >= 0) { uirq = &priv->uirqs[lirq->index]; uirq->refcnt--; - if (uirq->refcnt == 0) + if (uirq->refcnt == 0) { + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); free_irq(uirq->uirq, priv); + return; + } } spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); @@ -326,6 +328,7 @@ static int grgpio_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; + struct device *dev = &ofdev->dev; void __iomem *regs; struct gpio_chip *gc; struct grgpio_priv *priv; @@ -335,7 +338,7 @@ int size; int i; - priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -344,29 +347,32 @@ return PTR_ERR(regs); gc = &priv->gc; - err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA, + err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA, regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL, BGPIOF_BIG_ENDIAN_BYTE_ORDER); if (err) { - dev_err(&ofdev->dev, "bgpio_init() failed\n"); + dev_err(dev, "bgpio_init() failed\n"); return err; } priv->regs = regs; priv->imask = gc->read_reg(regs + GRGPIO_IMASK); - priv->dev = &ofdev->dev; + priv->dev = dev; gc->of_node = np; gc->owner = THIS_MODULE; gc->to_irq = grgpio_to_irq; - gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np); + gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np); + if (!gc->label) + return -ENOMEM; + gc->base = -1; err = of_property_read_u32(np, "nbits", &prop); if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) { gc->ngpio = GRGPIO_MAX_NGPIO; - dev_dbg(&ofdev->dev, - "No or invalid nbits property: assume %d\n", gc->ngpio); + dev_dbg(dev, "No or invalid nbits property: assume %d\n", + gc->ngpio); } else { gc->ngpio = prop; } @@ -378,7 +384,7 @@ irqmap = (s32 *)of_get_property(np, "irqmap", &size); if (irqmap) { if (size < gc->ngpio) { - dev_err(&ofdev->dev, + dev_err(dev, "irqmap shorter than ngpio (%d < %d)\n", size, gc->ngpio); return -EINVAL; @@ -388,7 +394,7 @@ &grgpio_irq_domain_ops, priv); if (!priv->domain) { - dev_err(&ofdev->dev, "Could not add irq domain\n"); + dev_err(dev, "Could not add irq domain\n"); return -EINVAL; } @@ -418,13 +424,13 @@ err = gpiochip_add_data(gc, priv); if (err) { - dev_err(&ofdev->dev, "Could not add gpiochip\n"); + dev_err(dev, "Could not add gpiochip\n"); if (priv->domain) irq_domain_remove(priv->domain); return err; } - dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", + dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n", priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off"); return 0; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-lynxpoint.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-lynxpoint.c @@ -164,6 +164,12 @@ value |= TRIG_SEL_BIT | INT_INV_BIT; outl(value, reg); + + if (type & IRQ_TYPE_EDGE_BOTH) + irq_set_handler_locked(d, handle_edge_irq); + else if (type & IRQ_TYPE_LEVEL_MASK) + irq_set_handler_locked(d, handle_level_irq); + spin_unlock_irqrestore(&lg->lock, flags); return 0; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-mockup.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-mockup.c @@ -339,7 +339,7 @@ priv->offset = i; priv->desc = &gc->gpiodev->descs[i]; - debugfs_create_file(name, 0200, chip->dbg_dir, priv, + debugfs_create_file(name, 0600, chip->dbg_dir, priv, &gpio_mockup_debugfs_ops); } @@ -497,6 +497,7 @@ err = platform_driver_register(&gpio_mockup_driver); if (err) { gpio_mockup_err("error registering platform driver\n"); + debugfs_remove_recursive(gpio_mockup_dbg_dir); return err; } @@ -527,6 +528,7 @@ gpio_mockup_err("error registering device"); platform_driver_unregister(&gpio_mockup_driver); gpio_mockup_unregister_pdevs(); + debugfs_remove_recursive(gpio_mockup_dbg_dir); return PTR_ERR(pdev); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-mpc8xxx.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-mpc8xxx.c @@ -190,6 +190,7 @@ switch (flow_type) { case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_LEVEL_LOW: raw_spin_lock_irqsave(&mpc8xxx_gc->lock, flags); gc->write_reg(mpc8xxx_gc->regs + GPIO_ICR, gc->read_reg(mpc8xxx_gc->regs + GPIO_ICR) @@ -346,6 +347,7 @@ return -ENOMEM; gc = &mpc8xxx_gc->gc; + gc->parent = &pdev->dev; if (of_property_read_bool(np, "little-endian")) { ret = bgpio_init(gc, &pdev->dev, 4, @@ -377,7 +379,8 @@ * It's assumed that only a single type of gpio controller is available * on the current machine, so overwriting global data is fine. */ - mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type; + if (devtype->irq_set_type) + mpc8xxx_irq_chip.irq_set_type = devtype->irq_set_type; if (devtype->gpio_dir_out) gc->direction_output = devtype->gpio_dir_out; @@ -386,6 +389,9 @@ gc->to_irq = mpc8xxx_gpio_to_irq; + if (of_device_is_compatible(np, "fsl,qoriq-gpio")) + gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff); + ret = gpiochip_add_data(gc, mpc8xxx_gc); if (ret) { pr_err("%pOF: GPIO chip registration failed with status %d\n", --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-mvebu.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-mvebu.c @@ -657,9 +657,8 @@ spin_lock_irqsave(&mvpwm->lock, flags); - val = (unsigned long long) - readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); - val *= NSEC_PER_SEC; + u = readl_relaxed(mvebu_pwmreg_blink_on_duration(mvpwm)); + val = (unsigned long long) u * NSEC_PER_SEC; do_div(val, mvpwm->clk_rate); if (val > UINT_MAX) state->duty_cycle = UINT_MAX; @@ -668,21 +667,17 @@ else state->duty_cycle = 1; - val = (unsigned long long) - readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); + val = (unsigned long long) u; /* on duration */ + /* period = on + off duration */ + val += readl_relaxed(mvebu_pwmreg_blink_off_duration(mvpwm)); val *= NSEC_PER_SEC; do_div(val, mvpwm->clk_rate); - if (val < state->duty_cycle) { + if (val > UINT_MAX) + state->period = UINT_MAX; + else if (val) + state->period = val; + else state->period = 1; - } else { - val -= state->duty_cycle; - if (val > UINT_MAX) - state->period = UINT_MAX; - else if (val) - state->period = val; - else - state->period = 1; - } regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u); if (u) @@ -702,6 +697,9 @@ unsigned long flags; unsigned int on, off; + if (state->polarity != PWM_POLARITY_NORMAL) + return -EINVAL; + val = (unsigned long long) mvpwm->clk_rate * state->duty_cycle; do_div(val, NSEC_PER_SEC); if (val > UINT_MAX) @@ -1196,6 +1194,13 @@ devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip); + /* Some MVEBU SoCs have simple PWM support for GPIO lines */ + if (IS_ENABLED(CONFIG_PWM)) { + err = mvebu_pwm_probe(pdev, mvchip, id); + if (err) + return err; + } + /* Some gpio controllers do not provide irq support */ if (!have_irqs) return 0; @@ -1205,7 +1210,8 @@ if (!mvchip->domain) { dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n", mvchip->chip.label); - return -ENODEV; + err = -ENODEV; + goto err_pwm; } err = irq_alloc_domain_generic_chips( @@ -1253,14 +1259,12 @@ mvchip); } - /* Some MVEBU SoCs have simple PWM support for GPIO lines */ - if (IS_ENABLED(CONFIG_PWM)) - return mvebu_pwm_probe(pdev, mvchip, id); - return 0; err_domain: irq_domain_remove(mvchip->domain); +err_pwm: + pwmchip_remove(&mvchip->mvpwm->chip); return err; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-mxc.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-mxc.c @@ -229,7 +229,7 @@ writel(1 << gpio_idx, port->base + GPIO_ISR); - return 0; + return port->gc.direction_input(&port->gc, gpio_idx); } static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) @@ -411,6 +411,7 @@ { struct device_node *np = pdev->dev.of_node; struct mxc_gpio_port *port; + int irq_count; int irq_base; int err; @@ -426,9 +427,15 @@ if (IS_ERR(port->base)) return PTR_ERR(port->base); - port->irq_high = platform_get_irq(pdev, 1); - if (port->irq_high < 0) - port->irq_high = 0; + irq_count = platform_irq_count(pdev); + if (irq_count < 0) + return irq_count; + + if (irq_count > 1) { + port->irq_high = platform_get_irq(pdev, 1); + if (port->irq_high < 0) + port->irq_high = 0; + } port->irq = platform_get_irq(pdev, 0); if (port->irq < 0) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-omap.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-omap.c @@ -29,6 +29,7 @@ #define OMAP4_GPIO_DEBOUNCINGTIME_MASK 0xFF struct gpio_regs { + u32 sysconfig; u32 irqenable1; u32 irqenable2; u32 wake_en; @@ -1058,6 +1059,7 @@ const struct omap_gpio_reg_offs *regs = p->regs; void __iomem *base = p->base; + p->context.sysconfig = readl_relaxed(base + regs->sysconfig); p->context.ctrl = readl_relaxed(base + regs->ctrl); p->context.oe = readl_relaxed(base + regs->direction); p->context.wake_en = readl_relaxed(base + regs->wkup_en); @@ -1077,6 +1079,7 @@ const struct omap_gpio_reg_offs *regs = bank->regs; void __iomem *base = bank->base; + writel_relaxed(bank->context.sysconfig, base + regs->sysconfig); writel_relaxed(bank->context.wake_en, base + regs->wkup_en); writel_relaxed(bank->context.ctrl, base + regs->ctrl); writel_relaxed(bank->context.leveldetect0, base + regs->leveldetect0); @@ -1104,6 +1107,10 @@ bank->saved_datain = readl_relaxed(base + bank->regs->datain); + /* Save syconfig, it's runtime value can be different from init value */ + if (bank->loses_context) + bank->context.sysconfig = readl_relaxed(base + bank->regs->sysconfig); + if (!bank->enabled_non_wakeup_gpios) goto update_gpio_context_count; @@ -1259,6 +1266,7 @@ static const struct omap_gpio_reg_offs omap2_gpio_regs = { .revision = OMAP24XX_GPIO_REVISION, + .sysconfig = OMAP24XX_GPIO_SYSCONFIG, .direction = OMAP24XX_GPIO_OE, .datain = OMAP24XX_GPIO_DATAIN, .dataout = OMAP24XX_GPIO_DATAOUT, @@ -1282,6 +1290,7 @@ static const struct omap_gpio_reg_offs omap4_gpio_regs = { .revision = OMAP4_GPIO_REVISION, + .sysconfig = OMAP4_GPIO_SYSCONFIG, .direction = OMAP4_GPIO_OE, .datain = OMAP4_GPIO_DATAIN, .dataout = OMAP4_GPIO_DATAOUT, --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-pca953x.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-pca953x.c @@ -107,6 +107,84 @@ }; MODULE_DEVICE_TABLE(i2c, pca953x_id); +#ifdef CONFIG_GPIO_PCA953X_IRQ + +#include +#include +#include + +static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { + { + /* + * On Intel Galileo Gen 2 board the IRQ pin of one of + * the I²C GPIO expanders, which has GpioInt() resource, + * is provided as an absolute number instead of being + * relative. Since first controller (gpio-sch.c) and + * second (gpio-dwapb.c) are at the fixed bases, we may + * safely refer to the number in the global space to get + * an IRQ out of it. + */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"), + }, + }, + {} +}; + +#ifdef CONFIG_ACPI +static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data) +{ + struct acpi_resource_gpio *agpio; + int *pin = data; + + if (acpi_gpio_get_irq_resource(ares, &agpio)) + *pin = agpio->pin_table[0]; + return 1; +} + +static int pca953x_acpi_find_pin(struct device *dev) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + int pin = -ENOENT, ret; + LIST_HEAD(r); + + ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin); + acpi_dev_free_resource_list(&r); + if (ret < 0) + return ret; + + return pin; +} +#else +static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; } +#endif + +static int pca953x_acpi_get_irq(struct device *dev) +{ + int pin, ret; + + pin = pca953x_acpi_find_pin(dev); + if (pin < 0) + return pin; + + dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin); + + if (!gpio_is_valid(pin)) + return -EINVAL; + + ret = gpio_request(pin, "pca953x interrupt"); + if (ret) + return ret; + + ret = gpio_to_irq(pin); + + /* When pin is used as an IRQ, no need to keep it requested */ + gpio_free(pin); + + return ret; +} +#endif + static const struct acpi_device_id pca953x_acpi_ids[] = { { "INT3491", 16 | PCA953X_TYPE | PCA_LATCH_INT, }, { } @@ -301,13 +379,31 @@ .reg_bits = 8, .val_bits = 8, + .use_single_read = true, + .use_single_write = true, + .readable_reg = pca953x_readable_register, .writeable_reg = pca953x_writeable_register, .volatile_reg = pca953x_volatile_register, .cache_type = REGCACHE_RBTREE, - /* REVISIT: should be 0x7f but some 24 bit chips use REG_ADDR_AI */ - .max_register = 0xff, + .max_register = 0x7f, +}; + +static const struct regmap_config pca953x_ai_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .read_flag_mask = REG_ADDR_AI, + .write_flag_mask = REG_ADDR_AI, + + .readable_reg = pca953x_readable_register, + .writeable_reg = pca953x_writeable_register, + .volatile_reg = pca953x_volatile_register, + + .disable_locking = true, + .cache_type = REGCACHE_RBTREE, + .max_register = 0x7f, }; static u8 pca953x_recalc_addr(struct pca953x_chip *chip, int reg, int off, @@ -318,18 +414,6 @@ int pinctrl = (reg & PCAL_PINCTRL_MASK) << 1; u8 regaddr = pinctrl | addr | (off / BANK_SZ); - /* Single byte read doesn't need AI bit set. */ - if (!addrinc) - return regaddr; - - /* Chips with 24 and more GPIOs always support Auto Increment */ - if (write && NBANK(chip) > 2) - regaddr |= REG_ADDR_AI; - - /* PCA9575 needs address-increment on multi-byte writes */ - if (PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) - regaddr |= REG_ADDR_AI; - return regaddr; } @@ -502,21 +586,21 @@ mutex_lock(&chip->i2c_lock); - /* Disable pull-up/pull-down */ - ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); - if (ret) - goto exit; - /* Configure pull-up/pull-down */ if (config == PIN_CONFIG_BIAS_PULL_UP) ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, bit); else if (config == PIN_CONFIG_BIAS_PULL_DOWN) ret = regmap_write_bits(chip->regmap, pull_sel_reg, bit, 0); + else + ret = 0; if (ret) goto exit; - /* Enable pull-up/pull-down */ - ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); + /* Disable/Enable pull-up/pull-down */ + if (config == PIN_CONFIG_BIAS_DISABLE) + ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, 0); + else + ret = regmap_write_bits(chip->regmap, pull_en_reg, bit, bit); exit: mutex_unlock(&chip->i2c_lock); @@ -528,9 +612,11 @@ { struct pca953x_chip *chip = gpiochip_get_data(gc); - switch (config) { + switch (pinconf_to_config_param(config)) { case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_DISABLE: return pca953x_gpio_set_pull_up_down(chip, offset, config); default: return -ENOTSUPP; @@ -770,6 +856,12 @@ u8 reg_direction[MAX_BANK]; int ret, i; + if (dmi_first_match(pca953x_dmi_acpi_irq_info)) { + ret = pca953x_acpi_get_irq(&client->dev); + if (ret > 0) + client->irq = ret; + } + if (!client->irq) return 0; @@ -897,6 +989,7 @@ int ret; u32 invert = 0; struct regulator *reg; + const struct regmap_config *regmap_config; chip = devm_kzalloc(&client->dev, sizeof(struct pca953x_chip), GFP_KERNEL); @@ -960,7 +1053,17 @@ i2c_set_clientdata(client, chip); - chip->regmap = devm_regmap_init_i2c(client, &pca953x_i2c_regmap); + pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK); + + if (NBANK(chip) > 2 || PCA_CHIP_TYPE(chip->driver_data) == PCA957X_TYPE) { + dev_info(&client->dev, "using AI\n"); + regmap_config = &pca953x_ai_i2c_regmap; + } else { + dev_info(&client->dev, "using no AI\n"); + regmap_config = &pca953x_i2c_regmap; + } + + chip->regmap = devm_regmap_init_i2c(client, regmap_config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); goto err_exit; @@ -991,7 +1094,6 @@ /* initialize cached registers from their original values. * we can't share this chip with another i2c master. */ - pca953x_setup_gpio(chip, chip->driver_data & PCA_GPIO_MASK); if (PCA_CHIP_TYPE(chip->driver_data) == PCA953X_TYPE) { chip->regs = &pca953x_regs; @@ -1096,7 +1198,9 @@ { struct pca953x_chip *chip = dev_get_drvdata(dev); + mutex_lock(&chip->i2c_lock); regcache_cache_only(chip->regmap, true); + mutex_unlock(&chip->i2c_lock); if (atomic_read(&chip->wakeup_path)) device_set_wakeup_path(dev); @@ -1119,13 +1223,17 @@ } } + mutex_lock(&chip->i2c_lock); regcache_cache_only(chip->regmap, false); regcache_mark_dirty(chip->regmap); ret = pca953x_regcache_sync(dev); - if (ret) + if (ret) { + mutex_unlock(&chip->i2c_lock); return ret; + } ret = regcache_sync(chip->regmap); + mutex_unlock(&chip->i2c_lock); if (ret) { dev_err(dev, "Failed to restore register map: %d\n", ret); return ret; @@ -1175,6 +1283,7 @@ { .compatible = "onnn,cat9554", .data = OF_953X( 8, PCA_INT), }, { .compatible = "onnn,pca9654", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "onnn,pca9655", .data = OF_953X(16, PCA_INT), }, { .compatible = "exar,xra1202", .data = OF_953X( 8, 0), }, { } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-pcf857x.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-pcf857x.c @@ -332,7 +332,7 @@ * reset state. Otherwise it flags pins to be driven low. */ gpio->out = ~n_latch; - gpio->status = gpio->out; + gpio->status = gpio->read(gpio->client); status = devm_gpiochip_add_data(&client->dev, &gpio->chip, gpio); if (status < 0) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-pcie-idio-24.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-pcie-idio-24.c @@ -28,6 +28,47 @@ #include #include +/* + * PLX PEX8311 PCI LCS_INTCSR Interrupt Control/Status + * + * Bit: Description + * 0: Enable Interrupt Sources (Bit 0) + * 1: Enable Interrupt Sources (Bit 1) + * 2: Generate Internal PCI Bus Internal SERR# Interrupt + * 3: Mailbox Interrupt Enable + * 4: Power Management Interrupt Enable + * 5: Power Management Interrupt + * 6: Slave Read Local Data Parity Check Error Enable + * 7: Slave Read Local Data Parity Check Error Status + * 8: Internal PCI Wire Interrupt Enable + * 9: PCI Express Doorbell Interrupt Enable + * 10: PCI Abort Interrupt Enable + * 11: Local Interrupt Input Enable + * 12: Retry Abort Enable + * 13: PCI Express Doorbell Interrupt Active + * 14: PCI Abort Interrupt Active + * 15: Local Interrupt Input Active + * 16: Local Interrupt Output Enable + * 17: Local Doorbell Interrupt Enable + * 18: DMA Channel 0 Interrupt Enable + * 19: DMA Channel 1 Interrupt Enable + * 20: Local Doorbell Interrupt Active + * 21: DMA Channel 0 Interrupt Active + * 22: DMA Channel 1 Interrupt Active + * 23: Built-In Self-Test (BIST) Interrupt Active + * 24: Direct Master was the Bus Master during a Master or Target Abort + * 25: DMA Channel 0 was the Bus Master during a Master or Target Abort + * 26: DMA Channel 1 was the Bus Master during a Master or Target Abort + * 27: Target Abort after internal 256 consecutive Master Retrys + * 28: PCI Bus wrote data to LCS_MBOX0 + * 29: PCI Bus wrote data to LCS_MBOX1 + * 30: PCI Bus wrote data to LCS_MBOX2 + * 31: PCI Bus wrote data to LCS_MBOX3 + */ +#define PLX_PEX8311_PCI_LCS_INTCSR 0x68 +#define INTCSR_INTERNAL_PCI_WIRE BIT(8) +#define INTCSR_LOCAL_INPUT BIT(11) + /** * struct idio_24_gpio_reg - GPIO device registers structure * @out0_7: Read: FET Outputs 0-7 @@ -92,6 +133,7 @@ struct idio_24_gpio { struct gpio_chip chip; raw_spinlock_t lock; + __u8 __iomem *plx; struct idio_24_gpio_reg __iomem *reg; unsigned long irq_mask; }; @@ -360,13 +402,13 @@ unsigned long flags; const unsigned long bit_offset = irqd_to_hwirq(data) - 24; unsigned char new_irq_mask; - const unsigned long bank_offset = bit_offset/8 * 8; + const unsigned long bank_offset = bit_offset / 8; unsigned char cos_enable_state; raw_spin_lock_irqsave(&idio24gpio->lock, flags); - idio24gpio->irq_mask &= BIT(bit_offset); - new_irq_mask = idio24gpio->irq_mask >> bank_offset; + idio24gpio->irq_mask &= ~BIT(bit_offset); + new_irq_mask = idio24gpio->irq_mask >> bank_offset * 8; if (!new_irq_mask) { cos_enable_state = ioread8(&idio24gpio->reg->cos_enable); @@ -389,12 +431,12 @@ unsigned long flags; unsigned char prev_irq_mask; const unsigned long bit_offset = irqd_to_hwirq(data) - 24; - const unsigned long bank_offset = bit_offset/8 * 8; + const unsigned long bank_offset = bit_offset / 8; unsigned char cos_enable_state; raw_spin_lock_irqsave(&idio24gpio->lock, flags); - prev_irq_mask = idio24gpio->irq_mask >> bank_offset; + prev_irq_mask = idio24gpio->irq_mask >> bank_offset * 8; idio24gpio->irq_mask |= BIT(bit_offset); if (!prev_irq_mask) { @@ -481,6 +523,7 @@ struct device *const dev = &pdev->dev; struct idio_24_gpio *idio24gpio; int err; + const size_t pci_plx_bar_index = 1; const size_t pci_bar_index = 2; const char *const name = pci_name(pdev); @@ -494,12 +537,13 @@ return err; } - err = pcim_iomap_regions(pdev, BIT(pci_bar_index), name); + err = pcim_iomap_regions(pdev, BIT(pci_plx_bar_index) | BIT(pci_bar_index), name); if (err) { dev_err(dev, "Unable to map PCI I/O addresses (%d)\n", err); return err; } + idio24gpio->plx = pcim_iomap_table(pdev)[pci_plx_bar_index]; idio24gpio->reg = pcim_iomap_table(pdev)[pci_bar_index]; idio24gpio->chip.label = name; @@ -520,6 +564,12 @@ /* Software board reset */ iowrite8(0, &idio24gpio->reg->soft_reset); + /* + * enable PLX PEX8311 internal PCI wire interrupt and local interrupt + * input + */ + iowrite8((INTCSR_INTERNAL_PCI_WIRE | INTCSR_LOCAL_INPUT) >> 8, + idio24gpio->plx + PLX_PEX8311_PCI_LCS_INTCSR + 1); err = devm_gpiochip_add_data(dev, &idio24gpio->chip, idio24gpio); if (err) { --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-pmic-eic-sprd.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-pmic-eic-sprd.c @@ -338,6 +338,7 @@ pmic_eic->chip.set_config = sprd_pmic_eic_set_config; pmic_eic->chip.set = sprd_pmic_eic_set; pmic_eic->chip.get = sprd_pmic_eic_get; + pmic_eic->chip.can_sleep = true; pmic_eic->intc.name = dev_name(&pdev->dev); pmic_eic->intc.irq_mask = sprd_pmic_eic_irq_mask; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-pxa.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-pxa.c @@ -243,6 +243,7 @@ switch (gpio_type) { case PXA3XX_GPIO: case MMP2_GPIO: + case MMP_GPIO: return false; default: @@ -663,8 +664,8 @@ pchip->irq1 = irq1; gpio_reg_base = devm_platform_ioremap_resource(pdev, 0); - if (!gpio_reg_base) - return -EINVAL; + if (IS_ERR(gpio_reg_base)) + return PTR_ERR(gpio_reg_base); clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-rcar.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-rcar.c @@ -250,8 +250,10 @@ int error; error = pm_runtime_get_sync(p->dev); - if (error < 0) + if (error < 0) { + pm_runtime_put(p->dev); return error; + } error = pinctrl_gpio_request(chip->base + offset); if (error) @@ -416,7 +418,12 @@ p->has_both_edge_trigger = info->has_both_edge_trigger; ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args); - *npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK; + if (ret) { + *npins = RCAR_MAX_GPIO_PER_BANK; + } else { + *npins = args.args[2]; + of_node_put(args.np); + } if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) { dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n", --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-siox.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-siox.c @@ -245,6 +245,7 @@ girq->chip = &ddata->ichip; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; + girq->threaded = true; ret = devm_gpiochip_add_data(dev, &ddata->gchip, NULL); if (ret) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-sprd.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-sprd.c @@ -149,17 +149,20 @@ sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0); sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0); sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 1); + sprd_gpio_update(chip, offset, SPRD_GPIO_IC, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0); sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 0); sprd_gpio_update(chip, offset, SPRD_GPIO_IEV, 0); + sprd_gpio_update(chip, offset, SPRD_GPIO_IC, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_BOTH: sprd_gpio_update(chip, offset, SPRD_GPIO_IS, 0); sprd_gpio_update(chip, offset, SPRD_GPIO_IBE, 1); + sprd_gpio_update(chip, offset, SPRD_GPIO_IC, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_LEVEL_HIGH: --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-stmpe.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-stmpe.c @@ -188,7 +188,7 @@ [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, }; - int i, j; + int ret, i, j; /* * STMPE1600: to be able to get IRQ from pins, @@ -196,8 +196,16 @@ * GPSR or GPCR registers */ if (stmpe->partnum == STMPE1600) { - stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); - stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); + ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); + if (ret < 0) { + dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret); + goto err; + } + ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); + if (ret < 0) { + dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret); + goto err; + } } for (i = 0; i < CACHE_NR_REGS; i++) { @@ -219,6 +227,7 @@ } } +err: mutex_unlock(&stmpe_gpio->irq_lock); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tb10x.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tb10x.c @@ -195,7 +195,7 @@ handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, IRQ_GC_INIT_MASK_CACHE); if (ret) - return ret; + goto err_remove_domain; gc = tb10x_gpio->domain->gc->gc[0]; gc->reg_base = tb10x_gpio->base; @@ -209,6 +209,10 @@ } return 0; + +err_remove_domain: + irq_domain_remove(tb10x_gpio->domain); + return ret; } static int tb10x_gpio_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tc3589x.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tc3589x.c @@ -209,7 +209,7 @@ continue; tc3589x_gpio->oldregs[i][j] = new; - tc3589x_reg_write(tc3589x, regmap[i] + j * 8, new); + tc3589x_reg_write(tc3589x, regmap[i] + j, new); } } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tegra.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tegra.c @@ -365,6 +365,7 @@ struct tegra_gpio_info *tgi = bank->tgi; unsigned int gpio = d->hwirq; + tegra_gpio_irq_mask(d); gpiochip_unlock_as_irq(&tgi->gc, gpio); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tegra186.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tegra186.c @@ -234,9 +234,12 @@ return offset + pin; } +#define to_tegra_gpio(x) container_of((x), struct tegra_gpio, gpio) + static void tegra186_irq_ack(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; base = tegra186_gpio_get_base(gpio, data->hwirq); @@ -248,7 +251,8 @@ static void tegra186_irq_mask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; @@ -263,7 +267,8 @@ static void tegra186_irq_unmask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; @@ -278,7 +283,8 @@ static int tegra186_irq_set_type(struct irq_data *data, unsigned int type) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *gc = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = to_tegra_gpio(gc); void __iomem *base; u32 value; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-thunderx.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-thunderx.c @@ -53,6 +53,7 @@ struct thunderx_gpio { struct gpio_chip chip; u8 __iomem *register_base; + struct irq_domain *irqd; struct msix_entry *msix_entries; /* per line MSI-X */ struct thunderx_line *line_entries; /* per line irq info */ raw_spinlock_t lock; @@ -282,60 +283,54 @@ } } -static void thunderx_gpio_irq_ack(struct irq_data *d) +static void thunderx_gpio_irq_ack(struct irq_data *data) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); writeq(GPIO_INTR_INTR, - txgpio->register_base + intr_reg(irqd_to_hwirq(d))); + txline->txgpio->register_base + intr_reg(txline->line)); } -static void thunderx_gpio_irq_mask(struct irq_data *d) +static void thunderx_gpio_irq_mask(struct irq_data *data) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); writeq(GPIO_INTR_ENA_W1C, - txgpio->register_base + intr_reg(irqd_to_hwirq(d))); + txline->txgpio->register_base + intr_reg(txline->line)); } -static void thunderx_gpio_irq_mask_ack(struct irq_data *d) +static void thunderx_gpio_irq_mask_ack(struct irq_data *data) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); writeq(GPIO_INTR_ENA_W1C | GPIO_INTR_INTR, - txgpio->register_base + intr_reg(irqd_to_hwirq(d))); + txline->txgpio->register_base + intr_reg(txline->line)); } -static void thunderx_gpio_irq_unmask(struct irq_data *d) +static void thunderx_gpio_irq_unmask(struct irq_data *data) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); writeq(GPIO_INTR_ENA_W1S, - txgpio->register_base + intr_reg(irqd_to_hwirq(d))); + txline->txgpio->register_base + intr_reg(txline->line)); } -static int thunderx_gpio_irq_set_type(struct irq_data *d, +static int thunderx_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) { - struct gpio_chip *gc = irq_data_get_irq_chip_data(d); - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); - struct thunderx_line *txline = - &txgpio->line_entries[irqd_to_hwirq(d)]; + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); + struct thunderx_gpio *txgpio = txline->txgpio; u64 bit_cfg; - irqd_set_trigger_type(d, flow_type); + irqd_set_trigger_type(data, flow_type); bit_cfg = txline->fil_bits | GPIO_BIT_CFG_INT_EN; if (flow_type & IRQ_TYPE_EDGE_BOTH) { - irq_set_handler_locked(d, handle_fasteoi_ack_irq); + irq_set_handler_locked(data, handle_fasteoi_ack_irq); bit_cfg |= GPIO_BIT_CFG_INT_TYPE; } else { - irq_set_handler_locked(d, handle_fasteoi_mask_irq); + irq_set_handler_locked(data, handle_fasteoi_mask_irq); } raw_spin_lock(&txgpio->lock); @@ -364,6 +359,33 @@ irq_chip_disable_parent(data); } +static int thunderx_gpio_irq_request_resources(struct irq_data *data) +{ + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); + struct thunderx_gpio *txgpio = txline->txgpio; + int r; + + r = gpiochip_lock_as_irq(&txgpio->chip, txline->line); + if (r) + return r; + + r = irq_chip_request_resources_parent(data); + if (r) + gpiochip_unlock_as_irq(&txgpio->chip, txline->line); + + return r; +} + +static void thunderx_gpio_irq_release_resources(struct irq_data *data) +{ + struct thunderx_line *txline = irq_data_get_irq_chip_data(data); + struct thunderx_gpio *txgpio = txline->txgpio; + + irq_chip_release_resources_parent(data); + + gpiochip_unlock_as_irq(&txgpio->chip, txline->line); +} + /* * Interrupts are chained from underlying MSI-X vectors. We have * these irq_chip functions to be able to handle level triggering @@ -380,22 +402,48 @@ .irq_unmask = thunderx_gpio_irq_unmask, .irq_eoi = irq_chip_eoi_parent, .irq_set_affinity = irq_chip_set_affinity_parent, + .irq_request_resources = thunderx_gpio_irq_request_resources, + .irq_release_resources = thunderx_gpio_irq_release_resources, .irq_set_type = thunderx_gpio_irq_set_type, .flags = IRQCHIP_SET_TYPE_MASKED }; -static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc, - unsigned int child, - unsigned int child_type, - unsigned int *parent, - unsigned int *parent_type) +static int thunderx_gpio_irq_translate(struct irq_domain *d, + struct irq_fwspec *fwspec, + irq_hw_number_t *hwirq, + unsigned int *type) +{ + struct thunderx_gpio *txgpio = d->host_data; + + if (WARN_ON(fwspec->param_count < 2)) + return -EINVAL; + if (fwspec->param[0] >= txgpio->chip.ngpio) + return -EINVAL; + *hwirq = fwspec->param[0]; + *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; + return 0; +} + +static int thunderx_gpio_irq_alloc(struct irq_domain *d, unsigned int virq, + unsigned int nr_irqs, void *arg) { - struct thunderx_gpio *txgpio = gpiochip_get_data(gc); + struct thunderx_line *txline = arg; - *parent = txgpio->base_msi + (2 * child); - *parent_type = IRQ_TYPE_LEVEL_HIGH; - return 0; + return irq_domain_set_hwirq_and_chip(d, virq, txline->line, + &thunderx_gpio_irq_chip, txline); +} + +static const struct irq_domain_ops thunderx_gpio_irqd_ops = { + .alloc = thunderx_gpio_irq_alloc, + .translate = thunderx_gpio_irq_translate +}; + +static int thunderx_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct thunderx_gpio *txgpio = gpiochip_get_data(chip); + + return irq_find_mapping(txgpio->irqd, offset); } static int thunderx_gpio_probe(struct pci_dev *pdev, @@ -405,7 +453,6 @@ struct device *dev = &pdev->dev; struct thunderx_gpio *txgpio; struct gpio_chip *chip; - struct gpio_irq_chip *girq; int ngpio, i; int err = 0; @@ -450,8 +497,8 @@ } txgpio->msix_entries = devm_kcalloc(dev, - ngpio, sizeof(struct msix_entry), - GFP_KERNEL); + ngpio, sizeof(struct msix_entry), + GFP_KERNEL); if (!txgpio->msix_entries) { err = -ENOMEM; goto out; @@ -492,6 +539,27 @@ if (err < 0) goto out; + /* + * Push GPIO specific irqdomain on hierarchy created as a side + * effect of the pci_enable_msix() + */ + txgpio->irqd = irq_domain_create_hierarchy(irq_get_irq_data(txgpio->msix_entries[0].vector)->domain, + 0, 0, of_node_to_fwnode(dev->of_node), + &thunderx_gpio_irqd_ops, txgpio); + if (!txgpio->irqd) { + err = -ENOMEM; + goto out; + } + + /* Push on irq_data and the domain for each line. */ + for (i = 0; i < ngpio; i++) { + err = irq_domain_push_irq(txgpio->irqd, + txgpio->msix_entries[i].vector, + &txgpio->line_entries[i]); + if (err < 0) + dev_err(dev, "irq_domain_push_irq: %d\n", err); + } + chip->label = KBUILD_MODNAME; chip->parent = dev; chip->owner = THIS_MODULE; @@ -506,28 +574,11 @@ chip->set = thunderx_gpio_set; chip->set_multiple = thunderx_gpio_set_multiple; chip->set_config = thunderx_gpio_set_config; - girq = &chip->irq; - girq->chip = &thunderx_gpio_irq_chip; - girq->fwnode = of_node_to_fwnode(dev->of_node); - girq->parent_domain = - irq_get_irq_data(txgpio->msix_entries[0].vector)->domain; - girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq; - girq->handler = handle_bad_irq; - girq->default_type = IRQ_TYPE_NONE; - + chip->to_irq = thunderx_gpio_to_irq; err = devm_gpiochip_add_data(dev, chip, txgpio); if (err) goto out; - /* Push on irq_data and the domain for each line. */ - for (i = 0; i < ngpio; i++) { - err = irq_domain_push_irq(chip->irq.domain, - txgpio->msix_entries[i].vector, - chip); - if (err < 0) - dev_err(dev, "irq_domain_push_irq: %d\n", err); - } - dev_info(dev, "ThunderX GPIO: %d lines with base %d.\n", ngpio, chip->base); return 0; @@ -542,10 +593,10 @@ struct thunderx_gpio *txgpio = pci_get_drvdata(pdev); for (i = 0; i < txgpio->chip.ngpio; i++) - irq_domain_pop_irq(txgpio->chip.irq.domain, + irq_domain_pop_irq(txgpio->irqd, txgpio->msix_entries[i].vector); - irq_domain_remove(txgpio->chip.irq.domain); + irq_domain_remove(txgpio->irqd); pci_set_drvdata(pdev, NULL); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-timberdale.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-timberdale.c @@ -43,9 +43,10 @@ unsigned offset, bool enabled) { struct timbgpio *tgpio = gpiochip_get_data(gpio); + unsigned long flags; u32 reg; - spin_lock(&tgpio->lock); + spin_lock_irqsave(&tgpio->lock, flags); reg = ioread32(tgpio->membase + offset); if (enabled) @@ -54,7 +55,7 @@ reg &= ~(1 << index); iowrite32(reg, tgpio->membase + offset); - spin_unlock(&tgpio->lock); + spin_unlock_irqrestore(&tgpio->lock, flags); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tps68470.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tps68470.c @@ -91,13 +91,13 @@ struct tps68470_gpio_data *tps68470_gpio = gpiochip_get_data(gc); struct regmap *regmap = tps68470_gpio->tps68470_regmap; + /* Set the initial value */ + tps68470_gpio_set(gc, offset, value); + /* rest are always outputs */ if (offset >= TPS68470_N_REGULAR_GPIO) return 0; - /* Set the initial value */ - tps68470_gpio_set(gc, offset, value); - return regmap_update_bits(regmap, TPS68470_GPIO_CTL_REG_A(offset), TPS68470_GPIO_MODE_MASK, TPS68470_GPIO_MODE_OUT_CMOS); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-tqmx86.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-tqmx86.c @@ -235,8 +235,8 @@ struct resource *res; int ret, irq; - irq = platform_get_irq(pdev, 0); - if (irq < 0) + irq = platform_get_irq_optional(pdev, 0); + if (irq < 0 && irq != -ENXIO) return irq; res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -275,7 +275,7 @@ pm_runtime_enable(&pdev->dev); - if (irq) { + if (irq > 0) { struct irq_chip *irq_chip = &gpio->irq_chip; u8 irq_status; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-ts4900.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-ts4900.c @@ -1,7 +1,7 @@ /* * Digital I/O driver for Technologic Systems I2C FPGA Core * - * Copyright (C) 2015 Technologic Systems + * Copyright (C) 2015, 2018 Technologic Systems * Copyright (C) 2016 Savoir-Faire Linux * * This program is free software; you can redistribute it and/or @@ -52,19 +52,33 @@ { struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); - /* - * This will clear the output enable bit, the other bits are - * dontcare when this is cleared + /* Only clear the OE bit here, requires a RMW. Prevents potential issue + * with OE and data getting to the physical pin at different times. */ - return regmap_write(priv->regmap, offset, 0); + return regmap_update_bits(priv->regmap, offset, TS4900_GPIO_OE, 0); } static int ts4900_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { struct ts4900_gpio_priv *priv = gpiochip_get_data(chip); + unsigned int reg; int ret; + /* If changing from an input to an output, we need to first set the + * proper data bit to what is requested and then set OE bit. This + * prevents a glitch that can occur on the IO line + */ + regmap_read(priv->regmap, offset, ®); + if (!(reg & TS4900_GPIO_OE)) { + if (value) + reg = TS4900_GPIO_OUT; + else + reg &= ~TS4900_GPIO_OUT; + + regmap_write(priv->regmap, offset, reg); + } + if (value) ret = regmap_write(priv->regmap, offset, TS4900_GPIO_OE | TS4900_GPIO_OUT); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-uniphier.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-uniphier.c @@ -188,7 +188,7 @@ uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, 0); - return irq_chip_mask_parent(data); + irq_chip_mask_parent(data); } static void uniphier_gpio_irq_unmask(struct irq_data *data) @@ -198,7 +198,7 @@ uniphier_gpio_reg_update(priv, UNIPHIER_GPIO_IRQ_EN, mask, mask); - return irq_chip_unmask_parent(data); + irq_chip_unmask_parent(data); } static int uniphier_gpio_irq_set_type(struct irq_data *data, unsigned int type) --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-vf610.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-vf610.c @@ -125,12 +125,16 @@ { struct vf610_gpio_port *port = gpiochip_get_data(chip); unsigned long mask = BIT(gpio); - - if (port->sdata && port->sdata->have_paddr) - vf610_gpio_writel(mask, port->gpio_base + GPIO_PDDR); + u32 val; vf610_gpio_set(chip, gpio, value); + if (port->sdata && port->sdata->have_paddr) { + val = vf610_gpio_readl(port->gpio_base + GPIO_PDDR); + val |= mask; + vf610_gpio_writel(val, port->gpio_base + GPIO_PDDR); + } + return pinctrl_gpio_direction_output(chip->base + gpio); } @@ -300,7 +304,7 @@ gc = &port->gc; gc->of_node = np; gc->parent = dev; - gc->label = "vf610-gpio"; + gc->label = dev_name(dev); gc->ngpio = VF610_GPIO_PER_PORT; gc->base = of_alias_get_id(np, "gpio") * VF610_GPIO_PER_PORT; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-vr41xx.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-vr41xx.c @@ -217,8 +217,6 @@ printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", maskl, pendl, maskh, pendh); - atomic_inc(&irq_err_count); - return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-wcove.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-wcove.c @@ -102,7 +102,7 @@ unsigned int reg; if (gpio >= WCOVE_GPIO_NUM) - return -EOPNOTSUPP; + return -ENOTSUPP; if (reg_type == CTRL_IN) reg = GPIO_IN_CTRL_BASE + gpio; --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-winbond.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-winbond.c @@ -385,12 +385,13 @@ unsigned long *base = gpiochip_get_data(gc); const struct winbond_gpio_info *info; bool val; + int ret; winbond_gpio_get_info(&offset, &info); - val = winbond_sio_enter(*base); - if (val) - return val; + ret = winbond_sio_enter(*base); + if (ret) + return ret; winbond_sio_select_logical(*base, info->dev); --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-xilinx.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-xilinx.c @@ -147,9 +147,10 @@ for (i = 0; i < gc->ngpio; i++) { if (*mask == 0) break; + /* Once finished with an index write it out to the register */ if (index != xgpio_index(chip, i)) { xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + - xgpio_regoffset(chip, i), + index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]); spin_unlock_irqrestore(&chip->gpio_lock[index], flags); index = xgpio_index(chip, i); @@ -165,7 +166,7 @@ } xgpio_writereg(chip->regs + XGPIO_DATA_OFFSET + - xgpio_regoffset(chip, i), chip->gpio_state[index]); + index * XGPIO_CHANNEL_OFFSET, chip->gpio_state[index]); spin_unlock_irqrestore(&chip->gpio_lock[index], flags); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-xtensa.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-xtensa.c @@ -44,15 +44,14 @@ unsigned long flags; local_irq_save(flags); - RSR_CPENABLE(*cpenable); - WSR_CPENABLE(*cpenable | BIT(XCHAL_CP_ID_XTIOP)); - + *cpenable = xtensa_get_sr(cpenable); + xtensa_set_sr(*cpenable | BIT(XCHAL_CP_ID_XTIOP), cpenable); return flags; } static inline void disable_cp(unsigned long flags, unsigned long cpenable) { - WSR_CPENABLE(cpenable); + xtensa_set_sr(cpenable, cpenable); local_irq_restore(flags); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpio-zynq.c +++ linux-oracle-5.4.0/drivers/gpio/gpio-zynq.c @@ -556,7 +556,7 @@ struct gpio_chip *chip = irq_data_get_irq_chip_data(d); int ret; - ret = pm_runtime_get_sync(chip->parent); + ret = pm_runtime_resume_and_get(chip->parent); if (ret < 0) return ret; @@ -681,6 +681,8 @@ unsigned int bank_num; for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { + writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); writel_relaxed(gpio->context.datalsw[bank_num], gpio->base_addr + ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); @@ -690,9 +692,6 @@ writel_relaxed(gpio->context.dirm[bank_num], gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); - writel_relaxed(gpio->context.int_en[bank_num], - gpio->base_addr + - ZYNQ_GPIO_INTEN_OFFSET(bank_num)); writel_relaxed(gpio->context.int_type[bank_num], gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); @@ -702,6 +701,9 @@ writel_relaxed(gpio->context.int_any[bank_num], gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); + writel_relaxed(~(gpio->context.int_en[bank_num]), + gpio->base_addr + + ZYNQ_GPIO_INTEN_OFFSET(bank_num)); } } @@ -882,7 +884,7 @@ pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) goto err_pm_dis; @@ -936,8 +938,11 @@ static int zynq_gpio_remove(struct platform_device *pdev) { struct zynq_gpio *gpio = platform_get_drvdata(pdev); + int ret; - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); gpiochip_remove(&gpio->chip); clk_disable_unprepare(gpio->clk); device_set_wakeup_capable(&pdev->dev, 0); --- linux-oracle-5.4.0.orig/drivers/gpio/gpiolib-acpi.c +++ linux-oracle-5.4.0/drivers/gpio/gpiolib-acpi.c @@ -26,6 +26,17 @@ MODULE_PARM_DESC(run_edge_events_on_boot, "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); +static char *ignore_wake; +module_param(ignore_wake, charp, 0444); +MODULE_PARM_DESC(ignore_wake, + "controller@pin combos on which to ignore the ACPI wake flag " + "ignore_wake=controller@pin[,controller@pin[,...]]"); + +struct acpi_gpiolib_dmi_quirk { + bool no_edge_events_on_boot; + char *ignore_wake; +}; + /** * struct acpi_gpio_event - ACPI GPIO event handler data * @@ -163,7 +174,7 @@ int ret, value; ret = request_threaded_irq(event->irq, NULL, event->handler, - event->irqflags, "ACPI:Event", event); + event->irqflags | IRQF_ONESHOT, "ACPI:Event", event); if (ret) { dev_err(acpi_gpio->chip->parent, "Failed to setup interrupt handler for %d\n", @@ -194,6 +205,57 @@ acpi_gpiochip_request_irq(acpi_gpio, event); } +static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) +{ + const char *controller, *pin_str; + int len, pin; + char *endp; + + controller = ignore_wake; + while (controller) { + pin_str = strchr(controller, '@'); + if (!pin_str) + goto err; + + len = pin_str - controller; + if (len == strlen(controller_in) && + strncmp(controller, controller_in, len) == 0) { + pin = simple_strtoul(pin_str + 1, &endp, 10); + if (*endp != 0 && *endp != ',') + goto err; + + if (pin == pin_in) + return true; + } + + controller = strchr(controller, ','); + if (controller) + controller++; + } + + return false; +err: + pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n", + ignore_wake); + return false; +} + +static bool acpi_gpio_irq_is_wake(struct device *parent, + struct acpi_resource_gpio *agpio) +{ + int pin = agpio->pin_table[0]; + + if (agpio->wake_capable != ACPI_WAKE_CAPABLE) + return false; + + if (acpi_gpio_in_ignore_list(dev_name(parent), pin)) { + dev_info(parent, "Ignoring wakeup on pin %d\n", pin); + return false; + } + + return true; +} + static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, void *context) { @@ -213,8 +275,8 @@ pin = agpio->pin_table[0]; if (pin <= 255) { - char ev_name[5]; - sprintf(ev_name, "_%c%02hhX", + char ev_name[8]; + sprintf(ev_name, "_%c%02X", agpio->triggering == ACPI_EDGE_SENSITIVE ? 'E' : 'L', pin); if (ACPI_SUCCESS(acpi_get_handle(handle, ev_name, &evt_handle))) @@ -274,7 +336,7 @@ event->handle = evt_handle; event->handler = handler; event->irq = irq; - event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE; + event->irq_is_wake = acpi_gpio_irq_is_wake(chip->parent, agpio); event->pin = pin; event->desc = desc; @@ -891,10 +953,17 @@ irq_flags = acpi_dev_get_irq_type(info.triggering, info.polarity); - /* Set type if specified and different than the current one */ - if (irq_flags != IRQ_TYPE_NONE && - irq_flags != irq_get_trigger_type(irq)) - irq_set_irq_type(irq, irq_flags); + /* + * If the IRQ is not already in use then set type + * if specified and different than the current one. + */ + if (can_request_irq(irq, irq_flags)) { + if (irq_flags != IRQ_TYPE_NONE && + irq_flags != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_flags); + } else { + dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); + } return irq; } @@ -1302,7 +1371,7 @@ /* We must use _sync so that this runs after the first deferred_probe run */ late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); -static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { +static const struct dmi_system_id gpiolib_acpi_quirks[] = { { /* * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for @@ -1312,7 +1381,10 @@ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), - } + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .no_edge_events_on_boot = true, + }, }, { /* @@ -1324,20 +1396,112 @@ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), - } + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .no_edge_events_on_boot = true, + }, + }, + { + /* + * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an + * external embedded-controller connected via I2C + an ACPI GPIO + * event handler on INT33FFC:02 pin 12, causing spurious wakeups. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "INT33FC:02@12", + }, + }, + { + /* + * HP X2 10 models with Cherry Trail SoC + TI PMIC use an + * external embedded-controller connected via I2C + an ACPI GPIO + * event handler on INT33FF:01 pin 0, causing spurious wakeups. + * When suspending by closing the LID, the power to the USB + * keyboard is turned off, causing INT0002 ACPI events to + * trigger once the XHCI controller notices the keyboard is + * gone. So INT0002 events cause spurious wakeups too. Ignoring + * EC wakes breaks wakeup when opening the lid, the user needs + * to press the power-button to wakeup the system. The + * alternative is suspend simply not working, which is worse. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "INT33FF:01@0,INT0002:00@2", + }, + }, + { + /* + * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an + * external embedded-controller connected via I2C + an ACPI GPIO + * event handler on INT33FC:02 pin 28, causing spurious wakeups. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), + DMI_MATCH(DMI_BOARD_NAME, "815D"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "INT33FC:02@28", + }, + }, + { + /* + * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an + * external embedded-controller connected via I2C + an ACPI GPIO + * event handler on INT33FF:01 pin 0, causing spurious wakeups. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), + DMI_MATCH(DMI_BOARD_NAME, "813E"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "INT33FF:01@0", + }, + }, + { + /* + * Spurious wakeups from TP_ATTN# pin + * Found in BIOS 0.35 + * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "PNP0C50:00@8", + }, }, {} /* Terminating entry */ }; static int acpi_gpio_setup_params(void) { + const struct acpi_gpiolib_dmi_quirk *quirk = NULL; + const struct dmi_system_id *id; + + id = dmi_first_match(gpiolib_acpi_quirks); + if (id) + quirk = id->driver_data; + if (run_edge_events_on_boot < 0) { - if (dmi_check_system(run_edge_events_on_boot_blacklist)) + if (quirk && quirk->no_edge_events_on_boot) run_edge_events_on_boot = 0; else run_edge_events_on_boot = 1; } + if (ignore_wake == NULL && quirk && quirk->ignore_wake) + ignore_wake = quirk->ignore_wake; + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpio/gpiolib-of.c +++ linux-oracle-5.4.0/drivers/gpio/gpiolib-of.c @@ -23,6 +23,29 @@ #include "gpiolib.h" #include "gpiolib-of.h" +/** + * of_gpio_spi_cs_get_count() - special GPIO counting for SPI + * Some elder GPIO controllers need special quirks. Currently we handle + * the Freescale GPIO controller with bindings that doesn't use the + * established "cs-gpios" for chip selects but instead rely on + * "gpios" for the chip select lines. If we detect this, we redirect + * the counting of "cs-gpios" to count "gpios" transparent to the + * driver. + */ +int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) +{ + struct device_node *np = dev->of_node; + + if (!IS_ENABLED(CONFIG_SPI_MASTER)) + return 0; + if (!con_id || strcmp(con_id, "cs")) + return 0; + if (!of_device_is_compatible(np, "fsl,spi") && + !of_device_is_compatible(np, "aeroflexgaisler,spictrl")) + return 0; + return of_gpio_named_count(np, "gpios"); +} + /* * This is used by external users of of_gpio_count() from * @@ -35,6 +58,10 @@ char propname[32]; unsigned int i; + ret = of_gpio_spi_cs_get_count(dev, con_id); + if (ret > 0) + return ret; + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(propname, sizeof(propname), "%s-%s", @@ -119,10 +146,6 @@ if (of_property_read_bool(np, "cd-inverted")) *flags ^= OF_GPIO_ACTIVE_LOW; } - if (!strcmp(propname, "wp-gpios")) { - if (of_property_read_bool(np, "wp-inverted")) - *flags ^= OF_GPIO_ACTIVE_LOW; - } } /* * Some GPIO fixed regulator quirks. @@ -711,7 +734,8 @@ if (mm_gc->save_regs) mm_gc->save_regs(mm_gc); - mm_gc->gc.of_node = np; + of_node_put(mm_gc->gc.of_node); + mm_gc->gc.of_node = of_node_get(np); ret = gpiochip_add_data(gc, data); if (ret) @@ -719,6 +743,7 @@ return 0; err2: + of_node_put(np); iounmap(mm_gc->regs); err1: kfree(gc->label); @@ -760,7 +785,7 @@ i, &start); of_property_read_u32_index(np, "gpio-reserved-ranges", i + 1, &count); - if (start >= chip->ngpio || start + count >= chip->ngpio) + if (start >= chip->ngpio || start + count > chip->ngpio) continue; bitmap_clear(chip->valid_mask, start, count); @@ -882,16 +907,13 @@ of_node_get(chip->of_node); ret = of_gpiochip_scan_gpios(chip); - if (ret) { + if (ret) of_node_put(chip->of_node); - gpiochip_remove_pin_ranges(chip); - } return ret; } void of_gpiochip_remove(struct gpio_chip *chip) { - gpiochip_remove_pin_ranges(chip); of_node_put(chip->of_node); } --- linux-oracle-5.4.0.orig/drivers/gpio/gpiolib-sysfs.c +++ linux-oracle-5.4.0/drivers/gpio/gpiolib-sysfs.c @@ -457,6 +457,8 @@ long gpio; struct gpio_desc *desc; int status; + struct gpio_chip *gc; + int offset; status = kstrtol(buf, 0, &gpio); if (status < 0) @@ -468,6 +470,12 @@ pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); return -EINVAL; } + gc = desc->gdev->chip; + offset = gpio_chip_hwgpio(desc); + if (!gpiochip_line_is_valid(gc, offset)) { + pr_warn("%s: GPIO %ld masked\n", __func__, gpio); + return -EINVAL; + } /* No extra locking here; FLAG_SYSFS just signifies that the * request and export were done by on behalf of userspace, so @@ -482,14 +490,17 @@ } status = gpiod_set_transitory(desc, false); - if (!status) { - status = gpiod_export(desc, true); - if (status < 0) - gpiod_free(desc); - else - set_bit(FLAG_SYSFS, &desc->flags); + if (status) { + gpiod_free(desc); + goto done; } + status = gpiod_export(desc, true); + if (status < 0) + gpiod_free(desc); + else + set_bit(FLAG_SYSFS, &desc->flags); + done: if (status) pr_debug("%s: status %d\n", __func__, status); --- linux-oracle-5.4.0.orig/drivers/gpio/gpiolib.c +++ linux-oracle-5.4.0/drivers/gpio/gpiolib.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -147,7 +148,7 @@ if (hwnum >= gdev->ngpio) return ERR_PTR(-EINVAL); - return &gdev->descs[hwnum]; + return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)]; } /** @@ -220,6 +221,14 @@ chip = gpiod_to_chip(desc); offset = gpio_chip_hwgpio(desc); + /* + * Open drain emulation using input mode may incorrectly report + * input here, fix that up. + */ + if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) && + test_bit(FLAG_IS_OUT, &desc->flags)) + return 0; + if (!chip->get_direction) return -ENOTSUPP; @@ -1444,6 +1453,7 @@ gpiochip_free_hogs(chip); of_gpiochip_remove(chip); err_free_gpiochip_mask: + gpiochip_remove_pin_ranges(chip); gpiochip_free_valid_mask(chip); err_remove_from_list: spin_lock_irqsave(&gpio_lock, flags); @@ -1499,8 +1509,8 @@ gdev->chip = NULL; gpiochip_irqchip_remove(chip); acpi_gpiochip_remove(chip); - gpiochip_remove_pin_ranges(chip); of_gpiochip_remove(chip); + gpiochip_remove_pin_ranges(chip); gpiochip_free_valid_mask(chip); /* * We accept no more calls into the driver from this point, so @@ -1915,6 +1925,7 @@ parent_type); chip_info(gc, "alloc_irqs_parent for %d parent hwirq %d\n", irq, parent_hwirq); + irq_set_lockdep_class(irq, gc->irq.lock_key, gc->irq.request_key); ret = irq_domain_alloc_irqs_parent(d, irq, 1, &parent_fwspec); if (ret) chip_err(gc, @@ -2184,9 +2195,16 @@ { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + /* + * Since we override .irq_disable() we need to mimic the + * behaviour of __irq_disable() in irq/chip.c. + * First call .irq_disable() if it exists, else mimic the + * behaviour of mask_irq() which calls .irq_mask() if + * it exists. + */ if (chip->irq.irq_disable) chip->irq.irq_disable(d); - else + else if (chip->irq.chip->irq_mask) chip->irq.chip->irq_mask(d); gpiochip_disable_irq(chip, d->hwirq); } @@ -3211,6 +3229,17 @@ } EXPORT_SYMBOL_GPL(gpiod_is_active_low); +/** + * gpiod_toggle_active_low - toggle whether a GPIO is active-low or not + * @desc: the gpio descriptor to change + */ +void gpiod_toggle_active_low(struct gpio_desc *desc) +{ + VALIDATE_DESC_VOID(desc); + change_bit(FLAG_ACTIVE_LOW, &desc->flags); +} +EXPORT_SYMBOL_GPL(gpiod_toggle_active_low); + /* I/O calls are only valid after configuration completed; the relevant * "is this a valid GPIO" error checks should already have been done. * @@ -3866,7 +3895,9 @@ } } - if (test_bit(FLAG_IS_OUT, &desc->flags)) { + /* To be valid for IRQ the line needs to be input or open drain */ + if (test_bit(FLAG_IS_OUT, &desc->flags) && + !test_bit(FLAG_OPEN_DRAIN, &desc->flags)) { chip_err(chip, "%s: tried to flag a GPIO set as output for IRQ\n", __func__); @@ -3929,7 +3960,12 @@ if (!IS_ERR(desc) && !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) { - WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags)); + /* + * We must not be output when using IRQ UNLESS we are + * open drain. + */ + WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags) && + !test_bit(FLAG_OPEN_DRAIN, &desc->flags)); set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); } } @@ -4320,8 +4356,9 @@ if (chip->ngpio <= p->chip_hwnum) { dev_err(dev, - "requested GPIO %d is out of range [0..%d] for chip %s\n", - idx, chip->ngpio, chip->label); + "requested GPIO %u (%u) is out of range [0..%u] for chip %s\n", + idx, p->chip_hwnum, chip->ngpio - 1, + chip->label); return ERR_PTR(-EINVAL); } --- linux-oracle-5.4.0.orig/drivers/gpio/sgpio-aspeed.c +++ linux-oracle-5.4.0/drivers/gpio/sgpio-aspeed.c @@ -17,7 +17,17 @@ #include #include -#define MAX_NR_SGPIO 80 +/* + * MAX_NR_HW_GPIO represents the number of actual hardware-supported GPIOs (ie, + * slots within the clocked serial GPIO data). Since each HW GPIO is both an + * input and an output, we provide MAX_NR_HW_GPIO * 2 lines on our gpiochip + * device. + * + * We use SGPIO_OUTPUT_OFFSET to define the split between the inputs and + * outputs; the inputs start at line 0, the outputs start at OUTPUT_OFFSET. + */ +#define MAX_NR_HW_SGPIO 80 +#define SGPIO_OUTPUT_OFFSET MAX_NR_HW_SGPIO #define ASPEED_SGPIO_CTRL 0x54 @@ -30,8 +40,8 @@ struct clk *pclk; spinlock_t lock; void __iomem *base; - uint32_t dir_in[3]; int irq; + int n_sgpio; }; struct aspeed_sgpio_bank { @@ -107,35 +117,73 @@ return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; default: /* acturally if code runs to here, it's an error case */ - BUG_ON(1); + BUG(); } } -#define GPIO_BANK(x) ((x) >> 5) -#define GPIO_OFFSET(x) ((x) & 0x1f) +#define GPIO_BANK(x) ((x % SGPIO_OUTPUT_OFFSET) >> 5) +#define GPIO_OFFSET(x) ((x % SGPIO_OUTPUT_OFFSET) & 0x1f) #define GPIO_BIT(x) BIT(GPIO_OFFSET(x)) static const struct aspeed_sgpio_bank *to_bank(unsigned int offset) { - unsigned int bank = GPIO_BANK(offset); + unsigned int bank; + + bank = GPIO_BANK(offset); WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks)); return &aspeed_sgpio_banks[bank]; } +static int aspeed_sgpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, unsigned int ngpios) +{ + struct aspeed_sgpio *sgpio = gpiochip_get_data(gc); + int n = sgpio->n_sgpio; + int c = SGPIO_OUTPUT_OFFSET - n; + + WARN_ON(ngpios < MAX_NR_HW_SGPIO * 2); + + /* input GPIOs in the lower range */ + bitmap_set(valid_mask, 0, n); + bitmap_clear(valid_mask, n, c); + + /* output GPIOS above SGPIO_OUTPUT_OFFSET */ + bitmap_set(valid_mask, SGPIO_OUTPUT_OFFSET, n); + bitmap_clear(valid_mask, SGPIO_OUTPUT_OFFSET + n, c); + + return 0; +} + +static void aspeed_sgpio_irq_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, unsigned int ngpios) +{ + struct aspeed_sgpio *sgpio = gpiochip_get_data(gc); + int n = sgpio->n_sgpio; + + WARN_ON(ngpios < MAX_NR_HW_SGPIO * 2); + + /* input GPIOs in the lower range */ + bitmap_set(valid_mask, 0, n); + bitmap_clear(valid_mask, n, ngpios - n); +} + +static bool aspeed_sgpio_is_input(unsigned int offset) +{ + return offset < SGPIO_OUTPUT_OFFSET; +} + static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset) { struct aspeed_sgpio *gpio = gpiochip_get_data(gc); const struct aspeed_sgpio_bank *bank = to_bank(offset); unsigned long flags; enum aspeed_sgpio_reg reg; - bool is_input; int rc = 0; spin_lock_irqsave(&gpio->lock, flags); - is_input = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset); - reg = is_input ? reg_val : reg_rdata; + reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata; rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset)); spin_unlock_irqrestore(&gpio->lock, flags); @@ -143,22 +191,31 @@ return rc; } -static void sgpio_set_value(struct gpio_chip *gc, unsigned int offset, int val) +static int sgpio_set_value(struct gpio_chip *gc, unsigned int offset, int val) { struct aspeed_sgpio *gpio = gpiochip_get_data(gc); const struct aspeed_sgpio_bank *bank = to_bank(offset); - void __iomem *addr; + void __iomem *addr_r, *addr_w; u32 reg = 0; - addr = bank_reg(gpio, bank, reg_val); - reg = ioread32(addr); + if (aspeed_sgpio_is_input(offset)) + return -EINVAL; + + /* Since this is an output, read the cached value from rdata, then + * update val. */ + addr_r = bank_reg(gpio, bank, reg_rdata); + addr_w = bank_reg(gpio, bank, reg_val); + + reg = ioread32(addr_r); if (val) reg |= GPIO_BIT(offset); else reg &= ~GPIO_BIT(offset); - iowrite32(reg, addr); + iowrite32(reg, addr_w); + + return 0; } static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) @@ -175,43 +232,28 @@ static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) { - struct aspeed_sgpio *gpio = gpiochip_get_data(gc); - unsigned long flags; - - spin_lock_irqsave(&gpio->lock, flags); - gpio->dir_in[GPIO_BANK(offset)] |= GPIO_BIT(offset); - spin_unlock_irqrestore(&gpio->lock, flags); - - return 0; + return aspeed_sgpio_is_input(offset) ? 0 : -EINVAL; } static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val) { struct aspeed_sgpio *gpio = gpiochip_get_data(gc); unsigned long flags; + int rc; - spin_lock_irqsave(&gpio->lock, flags); - - gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset); - sgpio_set_value(gc, offset, val); + /* No special action is required for setting the direction; we'll + * error-out in sgpio_set_value if this isn't an output GPIO */ + spin_lock_irqsave(&gpio->lock, flags); + rc = sgpio_set_value(gc, offset, val); spin_unlock_irqrestore(&gpio->lock, flags); - return 0; + return rc; } static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset) { - int dir_status; - struct aspeed_sgpio *gpio = gpiochip_get_data(gc); - unsigned long flags; - - spin_lock_irqsave(&gpio->lock, flags); - dir_status = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset); - spin_unlock_irqrestore(&gpio->lock, flags); - - return dir_status; - + return !!aspeed_sgpio_is_input(offset); } static void irqd_to_aspeed_sgpio_data(struct irq_data *d, @@ -402,6 +444,7 @@ irq = &gpio->chip.irq; irq->chip = &aspeed_sgpio_irqchip; + irq->init_valid_mask = aspeed_sgpio_irq_init_valid_mask; irq->handler = handle_bad_irq; irq->default_type = IRQ_TYPE_NONE; irq->parent_handler = aspeed_sgpio_irq_handler; @@ -409,17 +452,15 @@ irq->parents = &gpio->irq; irq->num_parents = 1; - /* set IRQ settings and Enable Interrupt */ + /* Apply default IRQ settings */ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) { bank = &aspeed_sgpio_banks[i]; /* set falling or level-low irq */ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0)); /* trigger type is edge */ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1)); - /* dual edge trigger mode. */ - iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2)); - /* enable irq */ - iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable)); + /* single edge trigger */ + iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type2)); } return 0; @@ -452,11 +493,12 @@ if (rc < 0) { dev_err(&pdev->dev, "Could not read ngpios property\n"); return -EINVAL; - } else if (nr_gpios > MAX_NR_SGPIO) { + } else if (nr_gpios > MAX_NR_HW_SGPIO) { dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: %d\n", - MAX_NR_SGPIO, nr_gpios); + MAX_NR_HW_SGPIO, nr_gpios); return -EINVAL; } + gpio->n_sgpio = nr_gpios; rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq); if (rc < 0) { @@ -497,7 +539,8 @@ spin_lock_init(&gpio->lock); gpio->chip.parent = &pdev->dev; - gpio->chip.ngpio = nr_gpios; + gpio->chip.ngpio = MAX_NR_HW_SGPIO * 2; + gpio->chip.init_valid_mask = aspeed_sgpio_init_valid_mask; gpio->chip.direction_input = aspeed_sgpio_dir_in; gpio->chip.direction_output = aspeed_sgpio_dir_out; gpio->chip.get_direction = aspeed_sgpio_get_direction; @@ -509,9 +552,6 @@ gpio->chip.label = dev_name(&pdev->dev); gpio->chip.base = -1; - /* set all SGPIO pins as input (1). */ - memset(gpio->dir_in, 0xff, sizeof(gpio->dir_in)); - aspeed_sgpio_setup_irqs(gpio, pdev); rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/Kconfig @@ -27,6 +27,7 @@ config DRM_MIPI_DBI tristate depends on DRM + select DRM_KMS_HELPER config DRM_MIPI_DSI bool @@ -206,6 +207,7 @@ config DRM_RADEON tristate "ATI Radeon" depends on DRM && PCI && MMU + depends on AGP || !AGP select FW_LOADER select DRM_KMS_HELPER select DRM_TTM --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/ObjectID.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/ObjectID.h @@ -119,6 +119,7 @@ #define CONNECTOR_OBJECT_ID_eDP 0x14 #define CONNECTOR_OBJECT_ID_MXM 0x15 #define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16 +#define CONNECTOR_OBJECT_ID_USBC 0x17 /* deleted */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -762,7 +762,7 @@ MAX_HWIP }; -#define HWIP_MAX_INSTANCE 8 +#define HWIP_MAX_INSTANCE 10 struct amd_powerplay { void *pp_handle; @@ -813,6 +813,7 @@ uint8_t *bios; uint32_t bios_size; struct amdgpu_bo *stolen_vga_memory; + struct amdgpu_bo *discovery_memory; uint32_t bios_scratch_reg_offset; uint32_t bios_scratch[AMDGPU_BIOS_NUM_SCRATCH]; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -163,17 +163,28 @@ return 0; } -static struct device *get_mfd_cell_dev(const char *device_name, int r) +static int acp_genpd_add_device(struct device *dev, void *data) { - char auto_dev_name[25]; - struct device *dev; + struct generic_pm_domain *gpd = data; + int ret; - snprintf(auto_dev_name, sizeof(auto_dev_name), - "%s.%d.auto", device_name, r); - dev = bus_find_device_by_name(&platform_bus_type, NULL, auto_dev_name); - dev_info(dev, "device %s added to pm domain\n", auto_dev_name); + ret = pm_genpd_add_device(gpd, dev); + if (ret) + dev_err(dev, "Failed to add dev to genpd %d\n", ret); - return dev; + return ret; +} + +static int acp_genpd_remove_device(struct device *dev, void *data) +{ + int ret; + + ret = pm_genpd_remove_device(dev); + if (ret) + dev_err(dev, "Failed to remove dev from genpd %d\n", ret); + + /* Continue to remove */ + return 0; } /** @@ -184,11 +195,10 @@ */ static int acp_hw_init(void *handle) { - int r, i; + int r; uint64_t acp_base; u32 val = 0; u32 count = 0; - struct device *dev; struct i2s_platform_data *i2s_pdata = NULL; struct amdgpu_device *adev = (struct amdgpu_device *)handle; @@ -344,15 +354,10 @@ if (r) goto failure; - for (i = 0; i < ACP_DEVS ; i++) { - dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); - r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); - if (r) { - dev_err(dev, "Failed to add dev to genpd\n"); - goto failure; - } - } - + r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd, + acp_genpd_add_device); + if (r) + goto failure; /* Assert Soft reset of ACP */ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); @@ -413,10 +418,8 @@ */ static int acp_hw_fini(void *handle) { - int i, ret; u32 val = 0; u32 count = 0; - struct device *dev; struct amdgpu_device *adev = (struct amdgpu_device *)handle; /* return early if no ACP */ @@ -461,13 +464,8 @@ udelay(100); } - for (i = 0; i < ACP_DEVS ; i++) { - dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); - ret = pm_genpd_remove_device(dev); - /* If removal fails, dont giveup and try rest */ - if (ret) - dev_err(dev, "remove dev from genpd failed\n"); - } + device_for_each_child(adev->acp.parent, NULL, + acp_genpd_remove_device); mfd_remove_devices(adev->acp.parent); kfree(adev->acp.acp_res); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -85,6 +85,7 @@ struct acpi_buffer *params) { acpi_status status; + union acpi_object *obj; union acpi_object atif_arg_elements[2]; struct acpi_object_list atif_arg; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -107,16 +108,24 @@ status = acpi_evaluate_object(atif->handle, NULL, &atif_arg, &buffer); + obj = (union acpi_object *)buffer.pointer; - /* Fail only if calling the method fails and ATIF is supported */ - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + /* Fail if calling the method fails */ + if (ACPI_FAILURE(status)) { DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", acpi_format_exception(status)); - kfree(buffer.pointer); + kfree(obj); return NULL; } - return buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER) { + DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n", + obj->type); + kfree(obj); + return NULL; + } + + return obj; } /** --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c @@ -100,6 +100,7 @@ amdgpu_afmt_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); amdgpu_afmt_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); amdgpu_afmt_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); + res.clock = clock; return res; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -88,7 +88,7 @@ return NULL; fence = container_of(f, struct amdgpu_amdkfd_fence, base); - if (fence && f->ops == &amdkfd_fence_ops) + if (f->ops == &amdkfd_fence_ops) return fence; return NULL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -165,7 +165,7 @@ .get_tile_config = amdgpu_amdkfd_get_tile_config, }; -struct kfd2kgd_calls *amdgpu_amdkfd_gfx_10_0_get_functions() +struct kfd2kgd_calls *amdgpu_amdkfd_gfx_10_0_get_functions(void) { return (struct kfd2kgd_calls *)&kfd2kgd; } @@ -644,6 +644,9 @@ uint32_t temp; struct v10_compute_mqd *m = get_mqd(mqd); + if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) + return 0; + #if 0 unsigned long flags; int retry; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -540,6 +540,9 @@ uint32_t temp; struct v9_mqd *m = get_mqd(mqd); + if (amdgpu_sriov_vf(adev) && adev->in_gpu_reset) + return 0; + if (adev->in_gpu_reset) return -EIO; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -55,12 +55,6 @@ spinlock_t mem_limit_lock; } kfd_mem_limit; -/* Struct used for amdgpu_amdkfd_bo_validate */ -struct amdgpu_vm_parser { - uint32_t domain; - bool wait; -}; - static const char * const domain_bit_to_string[] = { "CPU", "GTT", @@ -293,11 +287,9 @@ return ret; } -static int amdgpu_amdkfd_validate(void *param, struct amdgpu_bo *bo) +static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) { - struct amdgpu_vm_parser *p = param; - - return amdgpu_amdkfd_bo_validate(bo, p->domain, p->wait); + return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false); } /* vm_validate_pt_pd_bos - Validate page table and directory BOs @@ -311,20 +303,15 @@ { struct amdgpu_bo *pd = vm->root.base.bo; struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev); - struct amdgpu_vm_parser param; int ret; - param.domain = AMDGPU_GEM_DOMAIN_VRAM; - param.wait = false; - - ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate, - ¶m); + ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate_vm_bo, NULL); if (ret) { pr_err("amdgpu: failed to validate PT BOs\n"); return ret; } - ret = amdgpu_amdkfd_validate(¶m, pd); + ret = amdgpu_amdkfd_validate_vm_bo(NULL, pd); if (ret) { pr_err("amdgpu: failed to validate PD\n"); return ret; @@ -964,11 +951,15 @@ struct dma_fence **ef) { struct amdgpu_device *adev = get_amdgpu_device(kgd); - struct drm_file *drm_priv = filp->private_data; - struct amdgpu_fpriv *drv_priv = drm_priv->driver_priv; - struct amdgpu_vm *avm = &drv_priv->vm; + struct amdgpu_fpriv *drv_priv; + struct amdgpu_vm *avm; int ret; + ret = amdgpu_file_to_fpriv(filp, &drv_priv); + if (ret) + return ret; + avm = &drv_priv->vm; + /* Already a compute VM? */ if (avm->process_info) return -EINVAL; @@ -1213,6 +1204,7 @@ err_bo_create: unreserve_mem_limit(adev, size, alloc_domain, !!sg); err_reserve_limit: + amdgpu_sync_free(&(*mem)->sync); mutex_destroy(&(*mem)->lock); kfree(*mem); err: @@ -1247,15 +1239,15 @@ * be freed anyway */ - /* No more MMU notifiers */ - amdgpu_mn_unregister(mem->bo); - /* Make sure restore workers don't access the BO any more */ bo_list_entry = &mem->validate_list; mutex_lock(&process_info->lock); list_del(&bo_list_entry->head); mutex_unlock(&process_info->lock); + /* No more MMU notifiers */ + amdgpu_mn_unregister(mem->bo); + ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, &ctx); if (unlikely(ret)) return ret; @@ -1288,7 +1280,7 @@ } /* Free the BO*/ - amdgpu_bo_unref(&mem->bo); + drm_gem_object_put_unlocked(&mem->bo->tbo.base); mutex_destroy(&mem->lock); kfree(mem); @@ -1630,7 +1622,8 @@ AMDGPU_VM_PAGE_READABLE | AMDGPU_VM_PAGE_WRITEABLE | AMDGPU_VM_PAGE_EXECUTABLE | AMDGPU_VM_MTYPE_NC; - (*mem)->bo = amdgpu_bo_ref(bo); + drm_gem_object_get(&bo->tbo.base); + (*mem)->bo = bo; (*mem)->va = va; (*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) ? AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -338,17 +338,9 @@ path_size += le16_to_cpu(path->usSize); if (device_support & le16_to_cpu(path->usDeviceTag)) { - uint8_t con_obj_id, con_obj_num, con_obj_type; - - con_obj_id = + uint8_t con_obj_id = (le16_to_cpu(path->usConnObjectId) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - con_obj_num = - (le16_to_cpu(path->usConnObjectId) & ENUM_ID_MASK) - >> ENUM_ID_SHIFT; - con_obj_type = - (le16_to_cpu(path->usConnObjectId) & - OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; /* Skip TV/CV support */ if ((le16_to_cpu(path->usDeviceTag) == @@ -373,15 +365,7 @@ router.ddc_valid = false; router.cd_valid = false; for (j = 0; j < ((le16_to_cpu(path->usSize) - 8) / 2); j++) { - uint8_t grph_obj_id, grph_obj_num, grph_obj_type; - - grph_obj_id = - (le16_to_cpu(path->usGraphicObjIds[j]) & - OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; - grph_obj_num = - (le16_to_cpu(path->usGraphicObjIds[j]) & - ENUM_ID_MASK) >> ENUM_ID_SHIFT; - grph_obj_type = + uint8_t grph_obj_type = (le16_to_cpu(path->usGraphicObjIds[j]) & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; @@ -1642,6 +1626,8 @@ (u32)le32_to_cpu(*((u32 *)reg_data + j)); j++; } else if ((reg_table->mc_reg_address[i].pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { + if (i == 0) + continue; reg_table->mc_reg_table_entry[num_ranges].mc_data[i] = reg_table->mc_reg_table_entry[num_ranges].mc_data[i - 1]; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c @@ -150,6 +150,7 @@ (mode_info->atom_context->bios + data_offset); switch (crev) { case 11: + case 12: mem_channel_number = igp_info->v11.umachannelnumber; /* channel width is 64 */ return mem_channel_number * 64; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c @@ -192,30 +192,35 @@ static bool amdgpu_read_platform_bios(struct amdgpu_device *adev) { - uint8_t __iomem *bios; - size_t size; + phys_addr_t rom = adev->pdev->rom; + size_t romlen = adev->pdev->romlen; + void __iomem *bios; adev->bios = NULL; - bios = pci_platform_rom(adev->pdev, &size); - if (!bios) { + if (!rom || romlen == 0) return false; - } - adev->bios = kzalloc(size, GFP_KERNEL); - if (adev->bios == NULL) + adev->bios = kzalloc(romlen, GFP_KERNEL); + if (!adev->bios) return false; - memcpy_fromio(adev->bios, bios, size); + bios = ioremap(rom, romlen); + if (!bios) + goto free_bios; - if (!check_atom_bios(adev->bios, size)) { - kfree(adev->bios); - return false; - } + memcpy_fromio(adev->bios, bios, romlen); + iounmap(bios); + + if (!check_atom_bios(adev->bios, romlen)) + goto free_bios; - adev->bios_size = size; + adev->bios_size = romlen; return true; +free_bios: + kfree(adev->bios); + return false; } #ifdef CONFIG_ACPI @@ -308,6 +313,7 @@ if (!found) return false; + pci_dev_put(pdev); adev->bios = kmalloc(size, GFP_KERNEL); if (!adev->bios) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -61,7 +61,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, - unsigned num_entries, struct amdgpu_bo_list **result) + size_t num_entries, struct amdgpu_bo_list **result) { unsigned last_entry = 0, first_userptr = num_entries; struct amdgpu_bo_list_entry *array; @@ -178,6 +178,7 @@ } rcu_read_unlock(); + *result = NULL; return -ENOENT; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h @@ -60,7 +60,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, struct drm_amdgpu_bo_list_entry *info, - unsigned num_entries, + size_t num_entries, struct amdgpu_bo_list **list); static inline struct amdgpu_bo_list_entry * --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -213,6 +213,9 @@ struct amdgpu_firmware_info *ucode; id = fw_type_convert(cgs_device, type); + if (id >= AMDGPU_UCODE_ID_MAXIMUM) + return -EINVAL; + ucode = &adev->firmware.ucode[id]; if (ucode->fw == NULL) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -316,8 +316,10 @@ if (!amdgpu_connector->edid) { /* some laptops provide a hardcoded edid in rom for LCDs */ if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) || - (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) + (connector->connector_type == DRM_MODE_CONNECTOR_eDP))) { amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev); + drm_connector_update_edid_property(connector, amdgpu_connector->edid); + } } } @@ -389,6 +391,9 @@ native_mode->vdisplay != 0 && native_mode->clock != 0) { mode = drm_mode_duplicate(dev, native_mode); + if (!mode) + return NULL; + mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; drm_mode_set_name(mode); @@ -403,6 +408,9 @@ * simpler. */ mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); + if (!mode) + return NULL; + mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); } @@ -719,8 +727,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (encoder) { @@ -827,6 +837,7 @@ amdgpu_connector_get_edid(connector); ret = amdgpu_connector_ddc_get_modes(connector); + amdgpu_get_native_mode(connector); return ret; } @@ -857,8 +868,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } encoder = amdgpu_connector_best_single_encoder(connector); @@ -980,8 +993,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { @@ -1330,8 +1345,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) { @@ -1631,10 +1648,12 @@ adev->mode_info.dither_property, AMDGPU_FMT_DITHER_DISABLE); - if (amdgpu_audio != 0) + if (amdgpu_audio != 0) { drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; + } subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = true; @@ -1756,6 +1775,7 @@ drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, @@ -1809,6 +1829,7 @@ drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, @@ -1859,6 +1880,7 @@ drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.audio_property, AMDGPU_AUDIO_AUTO); + amdgpu_connector->audio = AMDGPU_AUDIO_AUTO; } drm_object_attach_property(&amdgpu_connector->base.base, adev->mode_info.dither_property, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -43,7 +43,6 @@ struct drm_gem_object *gobj; struct amdgpu_bo *bo; unsigned long size; - int r; gobj = drm_gem_object_lookup(p->filp, data->handle); if (gobj == NULL) @@ -58,23 +57,14 @@ drm_gem_object_put_unlocked(gobj); size = amdgpu_bo_size(bo); - if (size != PAGE_SIZE || (data->offset + 8) > size) { - r = -EINVAL; - goto error_unref; - } + if (size != PAGE_SIZE || data->offset > (size - 8)) + return -EINVAL; - if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) { - r = -EINVAL; - goto error_unref; - } + if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) + return -EINVAL; *offset = data->offset; - return 0; - -error_unref: - amdgpu_bo_unref(&bo); - return r; } static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p, @@ -114,7 +104,7 @@ int ret; if (cs->in.num_chunks == 0) - return 0; + return -EINVAL; chunk_array = kmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL); if (!chunk_array) @@ -151,7 +141,7 @@ } for (i = 0; i < p->nchunks; i++) { - struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL; + struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL; struct drm_amdgpu_cs_chunk user_chunk; uint32_t __user *cdata; @@ -1542,6 +1532,7 @@ return 0; default: + dma_fence_put(fence); return -EINVAL; } } @@ -1574,15 +1565,15 @@ continue; r = dma_fence_wait_timeout(fence, true, timeout); + if (r > 0 && fence->error) + r = fence->error; + dma_fence_put(fence); if (r < 0) return r; if (r == 0) break; - - if (fence->error) - return fence->error; } memset(wait, 0, sizeof(*wait)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -351,7 +351,6 @@ { struct amdgpu_ctx *ctx; struct amdgpu_ctx_mgr *mgr; - unsigned long ras_counter; if (!fpriv) return -EINVAL; @@ -376,21 +375,6 @@ if (atomic_read(&ctx->guilty)) out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_GUILTY; - /*query ue count*/ - ras_counter = amdgpu_ras_query_error_count(adev, false); - /*ras counter is monotonic increasing*/ - if (ras_counter != ctx->ras_counter_ue) { - out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_UE; - ctx->ras_counter_ue = ras_counter; - } - - /*query ce count*/ - ras_counter = amdgpu_ras_query_error_count(adev, true); - if (ras_counter != ctx->ras_counter_ce) { - out->state.flags |= AMDGPU_CTX_QUERY2_FLAGS_RAS_CE; - ctx->ras_counter_ce = ras_counter; - } - mutex_unlock(&mgr->lock); return 0; } @@ -417,16 +401,24 @@ switch (args->in.op) { case AMDGPU_CTX_OP_ALLOC_CTX: + if (args->in.flags) + return -EINVAL; r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id); args->out.alloc.ctx_id = id; break; case AMDGPU_CTX_OP_FREE_CTX: + if (args->in.flags) + return -EINVAL; r = amdgpu_ctx_free(fpriv, id); break; case AMDGPU_CTX_OP_QUERY_STATE: + if (args->in.flags) + return -EINVAL; r = amdgpu_ctx_query(adev, fpriv, id, &args->out); break; case AMDGPU_CTX_OP_QUERY_STATE2: + if (args->in.flags) + return -EINVAL; r = amdgpu_ctx_query2(adev, fpriv, id, &args->out); break; default: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -240,7 +240,7 @@ while (size) { uint32_t value; - value = RREG32_PCIE(*pos >> 2); + value = RREG32_PCIE(*pos); r = put_user(value, (uint32_t *)buf); if (r) return r; @@ -283,7 +283,7 @@ if (r) return r; - WREG32_PCIE(*pos >> 2, value); + WREG32_PCIE(*pos, value); result += 4; buf += 4; @@ -392,6 +392,9 @@ ssize_t result = 0; int r; + if (!adev->smc_rreg) + return -EOPNOTSUPP; + if (size & 0x3 || *pos & 0x3) return -EINVAL; @@ -431,6 +434,9 @@ ssize_t result = 0; int r; + if (!adev->smc_wreg) + return -EOPNOTSUPP; + if (size & 0x3 || *pos & 0x3) return -EINVAL; @@ -694,11 +700,11 @@ ssize_t result = 0; uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; - if (size & 3 || *pos & 3) + if (size > 4096 || size & 3 || *pos & 3) return -EINVAL; /* decode offset */ - offset = *pos & GENMASK_ULL(11, 0); + offset = (*pos & GENMASK_ULL(11, 0)) >> 2; se = (*pos & GENMASK_ULL(19, 12)) >> 12; sh = (*pos & GENMASK_ULL(27, 20)) >> 20; cu = (*pos & GENMASK_ULL(35, 28)) >> 28; @@ -729,7 +735,7 @@ while (size) { uint32_t value; - value = data[offset++]; + value = data[result >> 2]; r = put_user(value, (uint32_t *)buf); if (r) { result = r; @@ -859,6 +865,9 @@ struct amdgpu_device *adev = dev->dev_private; int r = 0, i; + /* Avoid accidently unparking the sched thread during GPU reset */ + mutex_lock(&adev->lock_reset); + /* hold on the scheduler */ for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; @@ -884,6 +893,8 @@ kthread_unpark(ring->sched.thread); } + mutex_unlock(&adev->lock_reset); + return 0; } @@ -985,27 +996,37 @@ static void amdgpu_ib_preempt_mark_partial_job(struct amdgpu_ring *ring) { struct amdgpu_job *job; - struct drm_sched_job *s_job; + struct drm_sched_job *s_job, *tmp; uint32_t preempt_seq; struct dma_fence *fence, **ptr; struct amdgpu_fence_driver *drv = &ring->fence_drv; struct drm_gpu_scheduler *sched = &ring->sched; + bool preempted = true; if (ring->funcs->type != AMDGPU_RING_TYPE_GFX) return; preempt_seq = le32_to_cpu(*(drv->cpu_addr + 2)); - if (preempt_seq <= atomic_read(&drv->last_seq)) - return; + if (preempt_seq <= atomic_read(&drv->last_seq)) { + preempted = false; + goto no_preempt; + } preempt_seq &= drv->num_fences_mask; ptr = &drv->fences[preempt_seq]; fence = rcu_dereference_protected(*ptr, 1); +no_preempt: spin_lock(&sched->job_list_lock); - list_for_each_entry(s_job, &sched->ring_mirror_list, node) { + list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) { + if (dma_fence_is_signaled(&s_job->s_fence->finished)) { + /* remove job from ring_mirror_list */ + list_del_init(&s_job->node); + sched->ops->free_job(s_job); + continue; + } job = to_amdgpu_job(s_job); - if (job->fence == fence) + if (preempted && job->fence == fence) /* mark the job as preempted */ job->preemption_status |= AMDGPU_IB_PREEMPTED; } @@ -1036,6 +1057,9 @@ if (!fences) return -ENOMEM; + /* Avoid accidently unparking the sched thread during GPU reset */ + mutex_lock(&adev->lock_reset); + /* stop the scheduler */ kthread_park(ring->sched.thread); @@ -1075,6 +1099,8 @@ /* restart the scheduler */ kthread_unpark(ring->sched.thread); + mutex_unlock(&adev->lock_reset); + ttm_bo_unlock_delayed_workqueue(&adev->mman.bdev, resched); if (fences) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -70,11 +70,9 @@ MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/picasso_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/raven2_gpu_info.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/renoir_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin"); MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin"); -MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin"); #define AMDGPU_RESUME_MS 2000 @@ -759,10 +757,29 @@ u16 cmd; int r; + if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) + return 0; + /* Bypass for VF */ if (amdgpu_sriov_vf(adev)) return 0; + /* resizing on Dell G5 SE platforms causes problems with runtime pm */ + if ((amdgpu_runtime_pm != 0) && + adev->pdev->vendor == PCI_VENDOR_ID_ATI && + adev->pdev->device == 0x731f && + adev->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) + return 0; + + /* PCI_EXT_CAP_ID_VNDR extended capability is located at 0x100 */ + if (!pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_VNDR)) + DRM_WARN("System can't access extended configuration space,please check!!\n"); + + /* skip if the bios has already enabled large BAR */ + if (adev->gmc.real_vram_size && + (pci_resource_len(adev->pdev, 0) >= adev->gmc.real_vram_size)) + return 0; + /* Check if the root BUS has 64bit memory resources */ root = adev->pdev->bus; while (root->parent) @@ -844,6 +861,7 @@ return true; fw_ver = *((uint32_t *)adev->pm.fw->data + 69); + release_firmware(adev->pm.fw); if (fw_ver < 0x00160e00) return true; } @@ -2057,11 +2075,11 @@ if (adev->gmc.xgmi.num_physical_nodes > 1) amdgpu_xgmi_remove_device(adev); - amdgpu_amdkfd_device_fini(adev); - amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); + amdgpu_amdkfd_device_fini(adev); + /* need to disable SMC first */ for (i = 0; i < adev->num_ip_blocks; i++) { if (!adev->ip_blocks[i].status.hw) @@ -2291,7 +2309,7 @@ AMD_IP_BLOCK_TYPE_IH, }; - for (i = 0; i < ARRAY_SIZE(ip_order); i++) { + for (i = 0; i < adev->num_ip_blocks; i++) { int j; struct amdgpu_ip_block *block; @@ -3070,12 +3088,12 @@ } } - amdgpu_amdkfd_suspend(adev); - amdgpu_ras_suspend(adev); r = amdgpu_device_ip_suspend_phase1(adev); + amdgpu_amdkfd_suspend(adev); + /* evict vram memory */ amdgpu_bo_evict_vram(adev); @@ -3704,7 +3722,6 @@ r = amdgpu_ib_ring_tests(tmp_adev); if (r) { dev_err(tmp_adev->dev, "ib ring test failed (%d).\n", r); - r = amdgpu_device_ip_suspend(tmp_adev); need_full_reset = true; r = -EAGAIN; goto end; @@ -3890,7 +3907,7 @@ amdgpu_device_lock_adev(tmp_adev, false); r = amdgpu_device_pre_asic_reset(tmp_adev, - NULL, + (tmp_adev == adev) ? job : NULL, &need_full_reset); /*TODO Should we stop ?*/ if (r) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -136,7 +136,7 @@ { uint32_t *p = (uint32_t *)binary; uint64_t vram_size = (uint64_t)RREG32(mmRCC_CONFIG_MEMSIZE) << 20; - uint64_t pos = vram_size - BINARY_MAX_SIZE; + uint64_t pos = vram_size - DISCOVERY_TMR_SIZE; unsigned long flags; while (pos < vram_size) { @@ -179,7 +179,7 @@ uint16_t checksum; int r; - adev->discovery = kzalloc(BINARY_MAX_SIZE, GFP_KERNEL); + adev->discovery = kzalloc(DISCOVERY_TMR_SIZE, GFP_KERNEL); if (!adev->discovery) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.h @@ -24,6 +24,8 @@ #ifndef __AMDGPU_DISCOVERY__ #define __AMDGPU_DISCOVERY__ +#define DISCOVERY_TMR_SIZE (64 << 10) + int amdgpu_discovery_init(struct amdgpu_device *adev); void amdgpu_discovery_fini(struct amdgpu_device *adev); int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -282,7 +282,7 @@ ret = pm_runtime_get_sync(dev->dev); if (ret < 0) - return ret; + goto out; ret = drm_crtc_helper_set_config(set, ctx); @@ -306,6 +306,7 @@ adev->have_disp_power_ref = false; } +out: /* drop the power reference we got coming in here */ pm_runtime_put_autosuspend(dev->dev); return ret; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -145,7 +145,7 @@ int amdgpu_mcbp = 0; int amdgpu_discovery = -1; int amdgpu_mes = 0; -int amdgpu_noretry = 1; +int amdgpu_noretry; struct amdgpu_mgpu_info mgpu_info = { .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex), @@ -613,7 +613,7 @@ module_param_named(mes, amdgpu_mes, int, 0444); MODULE_PARM_DESC(noretry, - "Disable retry faults (0 = retry enabled, 1 = retry disabled (default))"); + "Disable retry faults (0 = retry enabled (default), 1 = retry disabled)"); module_param_named(noretry, amdgpu_noretry, int, 0644); #ifdef CONFIG_HSA_AMD @@ -633,7 +633,7 @@ * Maximum number of processes that HWS can schedule concurrently. The maximum is the * number of VMIDs assigned to the HWS, which is also the default. */ -int hws_max_conc_proc = 8; +int hws_max_conc_proc = -1; module_param(hws_max_conc_proc, int, 0444); MODULE_PARM_DESC(hws_max_conc_proc, "Max # processes HWS can execute concurrently when sched_policy=0 (0 = no concurrency, #VMIDs for KFD = Maximum(default))"); @@ -1011,6 +1011,7 @@ {0x1002, 0x7319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, {0x1002, 0x731A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, {0x1002, 0x731B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, + {0x1002, 0x731E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, {0x1002, 0x731F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI10}, /* Navi14 */ {0x1002, 0x7340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI14}, @@ -1023,6 +1024,7 @@ /* Navi12 */ {0x1002, 0x7360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT}, + {0x1002, 0x7362, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_NAVI12|AMD_EXP_HW_SUPPORT}, {0, 0, 0} }; @@ -1285,11 +1287,12 @@ dev = file_priv->minor->dev; ret = pm_runtime_get_sync(dev->dev); if (ret < 0) - return ret; + goto out; ret = drm_ioctl(filp, cmd, arg); pm_runtime_mark_last_busy(dev->dev); +out: pm_runtime_put_autosuspend(dev->dev); return ret; } @@ -1420,7 +1423,7 @@ static struct drm_driver kms_driver = { .driver_features = - DRIVER_USE_AGP | DRIVER_ATOMIC | + DRIVER_ATOMIC | DRIVER_GEM | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ, .load = amdgpu_driver_load_kms, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c @@ -133,8 +133,7 @@ u32 cpp; u64 flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | - AMDGPU_GEM_CREATE_VRAM_CLEARED | - AMDGPU_GEM_CREATE_CPU_GTT_USWC; + AMDGPU_GEM_CREATE_VRAM_CLEARED; info = drm_get_format_info(adev->ddev, mode_cmd); cpp = info->cpp[0]; @@ -147,7 +146,7 @@ size = mode_cmd->pitches[0] * height; aligned_size = ALIGN(size, PAGE_SIZE); ret = amdgpu_gem_object_create(adev, aligned_size, 0, domain, flags, - ttm_bo_type_kernel, NULL, &gobj); + ttm_bo_type_device, NULL, &gobj); if (ret) { pr_err("failed to allocate framebuffer (%d)\n", aligned_size); return -ENOMEM; @@ -290,10 +289,13 @@ static int amdgpu_fbdev_destroy(struct drm_device *dev, struct amdgpu_fbdev *rfbdev) { struct amdgpu_framebuffer *rfb = &rfbdev->rfb; + int i; drm_fb_helper_unregister_fbi(&rfbdev->helper); if (rfb->base.obj[0]) { + for (i = 0; i < rfb->base.format->num_planes; i++) + drm_gem_object_put(rfb->base.obj[0]); amdgpufb_destroy_pinned_object(rfb->base.obj[0]); rfb->base.obj[0] = NULL; drm_framebuffer_unregister_private(&rfb->base); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -404,7 +404,9 @@ ring->fence_drv.gpu_addr = adev->uvd.inst[ring->me].gpu_addr + index; } amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq)); - amdgpu_irq_get(adev, irq_src, irq_type); + + if (irq_src) + amdgpu_irq_get(adev, irq_src, irq_type); ring->fence_drv.irq_src = irq_src; ring->fence_drv.irq_type = irq_type; @@ -539,8 +541,9 @@ /* no need to trigger GPU reset as we are unloading */ amdgpu_fence_driver_force_completion(ring); } - amdgpu_irq_put(adev, ring->fence_drv.irq_src, - ring->fence_drv.irq_type); + if (ring->fence_drv.irq_src) + amdgpu_irq_put(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); drm_sched_fini(&ring->sched); del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) @@ -576,8 +579,9 @@ } /* disable the interrupt */ - amdgpu_irq_put(adev, ring->fence_drv.irq_src, - ring->fence_drv.irq_type); + if (ring->fence_drv.irq_src) + amdgpu_irq_put(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); } } @@ -603,8 +607,9 @@ continue; /* enable the interrupt */ - amdgpu_irq_get(adev, ring->fence_drv.irq_src, - ring->fence_drv.irq_type); + if (ring->fence_drv.irq_src) + amdgpu_irq_get(adev, ring->fence_drv.irq_src, + ring->fence_drv.irq_type); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -161,16 +161,17 @@ struct amdgpu_bo_list_entry vm_pd; struct list_head list, duplicates; + struct dma_fence *fence = NULL; struct ttm_validate_buffer tv; struct ww_acquire_ctx ticket; struct amdgpu_bo_va *bo_va; - int r; + long r; INIT_LIST_HEAD(&list); INIT_LIST_HEAD(&duplicates); tv.bo = &bo->tbo; - tv.num_shared = 1; + tv.num_shared = 2; list_add(&tv.head, &list); amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); @@ -178,28 +179,34 @@ r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates, false); if (r) { dev_err(adev->dev, "leaking bo va because " - "we fail to reserve bo (%d)\n", r); + "we fail to reserve bo (%ld)\n", r); return; } bo_va = amdgpu_vm_bo_find(vm, bo); - if (bo_va && --bo_va->ref_count == 0) { - amdgpu_vm_bo_rmv(adev, bo_va); + if (!bo_va || --bo_va->ref_count) + goto out_unlock; - if (amdgpu_vm_ready(vm)) { - struct dma_fence *fence = NULL; + amdgpu_vm_bo_rmv(adev, bo_va); + if (!amdgpu_vm_ready(vm)) + goto out_unlock; - r = amdgpu_vm_clear_freed(adev, vm, &fence); - if (unlikely(r)) { - dev_err(adev->dev, "failed to clear page " - "tables on GEM object close (%d)\n", r); - } - - if (fence) { - amdgpu_bo_fence(bo, fence, true); - dma_fence_put(fence); - } - } + fence = dma_resv_get_excl(bo->tbo.base.resv); + if (fence) { + amdgpu_bo_fence(bo, fence, true); + fence = NULL; } + + r = amdgpu_vm_clear_freed(adev, vm, &fence); + if (r || !fence) + goto out_unlock; + + amdgpu_bo_fence(bo, fence, true); + dma_fence_put(fence); + +out_unlock: + if (unlikely(r < 0)) + dev_err(adev->dev, "failed to clear page " + "tables on GEM object close (%ld)\n", r); ttm_eu_backoff_reservation(&ticket, &list); } @@ -322,11 +329,9 @@ if (r) goto release_object; - if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { - r = amdgpu_mn_register(bo, args->addr); - if (r) - goto release_object; - } + r = amdgpu_mn_register(bo, args->addr); + if (r) + goto release_object; if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); @@ -554,6 +559,7 @@ struct ww_acquire_ctx ticket; struct list_head list, duplicates; uint64_t va_flags; + uint64_t vm_size; int r = 0; if (args->va_address < AMDGPU_VA_RESERVED_SIZE) { @@ -574,6 +580,15 @@ args->va_address &= AMDGPU_GMC_HOLE_MASK; + vm_size = adev->vm_manager.max_pfn * AMDGPU_GPU_PAGE_SIZE; + vm_size -= AMDGPU_VA_RESERVED_SIZE; + if (args->va_address + args->map_size > vm_size) { + dev_dbg(&dev->pdev->dev, + "va_address 0x%llx is in top reserved area 0x%llx\n", + args->va_address + args->map_size, vm_size); + return -EINVAL; + } + if ((args->flags & ~valid_flags) && (args->flags & ~prt_flags)) { dev_dbg(&dev->pdev->dev, "invalid flags combination 0x%08X\n", args->flags); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -263,7 +263,7 @@ * adev->gfx.mec.num_pipe_per_mec * adev->gfx.mec.num_queue_per_pipe; - while (queue_bit-- >= 0) { + while (--queue_bit >= 0) { if (test_bit(queue_bit, adev->gfx.mec.queue_bitmap)) continue; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -77,6 +77,7 @@ struct amdgpu_vmhub { uint32_t ctx0_ptb_addr_lo32; uint32_t ctx0_ptb_addr_hi32; + uint32_t vm_inv_eng0_sem; uint32_t vm_inv_eng0_req; uint32_t vm_inv_eng0_ack; uint32_t vm_context0_cntl; @@ -156,6 +157,7 @@ uint32_t srbm_soft_reset; bool prt_warning; uint64_t stolen_size; + uint32_t sdpif_register; /* apertures */ u64 shared_aperture_start; u64 shared_aperture_end; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c @@ -339,7 +339,7 @@ void amdgpu_i2c_router_select_ddc_port(const struct amdgpu_connector *amdgpu_connector) { - u8 val; + u8 val = 0; if (!amdgpu_connector->router.ddc_valid) return; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -384,6 +384,14 @@ int r; entry.iv_entry = (const uint32_t *)&ih->ring[ring_index]; + + /* + * timestamp is not supported on some legacy SOCs (cik, cz, iceland, + * si and tonga), so initialize timestamp and timestamp_src to 0 + */ + entry.timestamp = 0; + entry.timestamp_src = 0; + amdgpu_ih_decode_iv(adev, &entry); trace_amdgpu_iv(ih - &adev->irq.ih, &entry); @@ -469,7 +477,7 @@ for (j = 0; j < AMDGPU_MAX_IRQ_SRC_ID; ++j) { struct amdgpu_irq_src *src = adev->irq.client[i].sources[j]; - if (!src) + if (!src || !src->funcs || !src->funcs->set) continue; for (k = 0; k < src->num_types; k++) amdgpu_irq_update(adev, src, k); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -36,7 +36,8 @@ memset(&ti, 0, sizeof(struct amdgpu_task_info)); - if (amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { + if (amdgpu_gpu_recovery && + amdgpu_ring_soft_recovery(ring, job->vmid, s_job->s_fence->parent)) { DRM_ERROR("ring %s timeout, but soft recovered\n", s_job->sched->name); return; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -471,6 +471,7 @@ crtc = (struct drm_crtc *)minfo->crtcs[i]; if (crtc && crtc->base.id == info->mode_crtc.id) { struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); + ui32 = amdgpu_crtc->crtc_id; found = 1; break; @@ -489,7 +490,7 @@ if (ret) return ret; - ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip))); + ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip))); return ret ? -EFAULT : 0; } case AMDGPU_INFO_HW_IP_COUNT: { @@ -625,21 +626,29 @@ ? -EFAULT : 0; } case AMDGPU_INFO_READ_MMR_REG: { - unsigned n, alloc_size; + unsigned int n, alloc_size; uint32_t *regs; - unsigned se_num = (info->read_mmr_reg.instance >> + unsigned int se_num = (info->read_mmr_reg.instance >> AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & AMDGPU_INFO_MMR_SE_INDEX_MASK; - unsigned sh_num = (info->read_mmr_reg.instance >> + unsigned int sh_num = (info->read_mmr_reg.instance >> AMDGPU_INFO_MMR_SH_INDEX_SHIFT) & AMDGPU_INFO_MMR_SH_INDEX_MASK; /* set full masks if the userspace set all bits - * in the bitfields */ + * in the bitfields + */ if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) se_num = 0xffffffff; + else if (se_num >= AMDGPU_GFX_MAX_SE) + return -EINVAL; if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) sh_num = 0xffffffff; + else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) + return -EINVAL; + + if (info->read_mmr_reg.count > 128) + return -EINVAL; if (info->read_mmr_reg.count > 128) return -EINVAL; @@ -667,9 +676,10 @@ return n ? -EFAULT : 0; } case AMDGPU_INFO_DEV_INFO: { - struct drm_amdgpu_info_device dev_info = {}; + struct drm_amdgpu_info_device dev_info; uint64_t vm_size; + memset(&dev_info, 0, sizeof(dev_info)); dev_info.device_id = dev->pdev->device; dev_info.chip_rev = adev->rev_id; dev_info.external_rev = adev->external_rev_id; @@ -761,7 +771,7 @@ min((size_t)size, sizeof(dev_info))) ? -EFAULT : 0; } case AMDGPU_INFO_VCE_CLOCK_TABLE: { - unsigned i; + unsigned int i; struct drm_amdgpu_info_vce_clock_table vce_clk_table = {}; struct amd_vce_state *vce_state; @@ -975,7 +985,7 @@ r = pm_runtime_get_sync(dev->dev); if (r < 0) - return r; + goto pm_put; fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); if (unlikely(!fpriv)) { @@ -1026,6 +1036,7 @@ out_suspend: pm_runtime_mark_last_busy(dev->dev); +pm_put: pm_runtime_put_autosuspend(dev->dev); return r; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -200,7 +200,7 @@ c++; } - BUG_ON(c >= AMDGPU_BO_MAX_PLACEMENTS); + BUG_ON(c > AMDGPU_BO_MAX_PLACEMENTS); placement->num_placement = c; placement->placement = places; @@ -343,6 +343,67 @@ } /** + * amdgpu_bo_create_kernel_at - create BO for kernel use at specific location + * + * @adev: amdgpu device object + * @offset: offset of the BO + * @size: size of the BO + * @domain: where to place it + * @bo_ptr: used to initialize BOs in structures + * @cpu_addr: optional CPU address mapping + * + * Creates a kernel BO at a specific offset in the address space of the domain. + * + * Returns: + * 0 on success, negative error code otherwise. + */ +int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, + uint64_t offset, uint64_t size, uint32_t domain, + struct amdgpu_bo **bo_ptr, void **cpu_addr) +{ + struct ttm_operation_ctx ctx = { false, false }; + unsigned int i; + int r; + + offset &= PAGE_MASK; + size = ALIGN(size, PAGE_SIZE); + + r = amdgpu_bo_create_reserved(adev, size, PAGE_SIZE, domain, bo_ptr, + NULL, NULL); + if (r) + return r; + + /* + * Remove the original mem node and create a new one at the request + * position. + */ + for (i = 0; i < (*bo_ptr)->placement.num_placement; ++i) { + (*bo_ptr)->placements[i].fpfn = offset >> PAGE_SHIFT; + (*bo_ptr)->placements[i].lpfn = (offset + size) >> PAGE_SHIFT; + } + + ttm_bo_mem_put(&(*bo_ptr)->tbo, &(*bo_ptr)->tbo.mem); + r = ttm_bo_mem_space(&(*bo_ptr)->tbo, &(*bo_ptr)->placement, + &(*bo_ptr)->tbo.mem, &ctx); + if (r) + goto error; + + if (cpu_addr) { + r = amdgpu_bo_kmap(*bo_ptr, cpu_addr); + if (r) + goto error; + } + + amdgpu_bo_unreserve(*bo_ptr); + return 0; + +error: + amdgpu_bo_unreserve(*bo_ptr); + amdgpu_bo_unref(bo_ptr); + return r; +} + +/** * amdgpu_bo_free_kernel - free BO for kernel use * * @bo: amdgpu BO to free @@ -831,6 +892,10 @@ if (WARN_ON_ONCE(min_offset > max_offset)) return -EINVAL; + /* Check domain to be pinned to against preferred domains */ + if (bo->preferred_domains & domain) + domain = bo->preferred_domains & domain; + /* A shared bo cannot be migrated to VRAM */ if (bo->prime_shared_count) { if (domain & AMDGPU_GEM_DOMAIN_GTT) @@ -1244,7 +1309,8 @@ !(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) return; - dma_resv_lock(bo->base.resv, NULL); + if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv))) + return; r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence); if (!WARN_ON(r)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -237,6 +237,9 @@ unsigned long size, int align, u32 domain, struct amdgpu_bo **bo_ptr, u64 *gpu_addr, void **cpu_addr); +int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, + uint64_t offset, uint64_t size, uint32_t domain, + struct amdgpu_bo **bo_ptr, void **cpu_addr); void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, void **cpu_addr); int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -90,7 +90,8 @@ adev->pm.ac_power = true; else adev->pm.ac_power = false; - if (adev->powerplay.pp_funcs->enable_bapm) + if (adev->powerplay.pp_funcs && + adev->powerplay.pp_funcs->enable_bapm) amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power); mutex_unlock(&adev->pm.mutex); } @@ -369,6 +370,15 @@ if (current_level == level) return count; + if (adev->asic_type == CHIP_RAVEN) { + if (adev->rev_id < 8) { + if (current_level != AMD_DPM_FORCED_LEVEL_MANUAL && level == AMD_DPM_FORCED_LEVEL_MANUAL) + amdgpu_gfx_off_ctrl(adev, false); + else if (current_level == AMD_DPM_FORCED_LEVEL_MANUAL && level != AMD_DPM_FORCED_LEVEL_MANUAL) + amdgpu_gfx_off_ctrl(adev, true); + } + } + /* profile_exit setting is valid only when current mode is in profile mode */ if (!(current_level & (AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD | AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK | @@ -415,8 +425,11 @@ ret = smu_get_power_num_states(&adev->smu, &data); if (ret) return ret; - } else if (adev->powerplay.pp_funcs->get_pp_num_states) + } else if (adev->powerplay.pp_funcs->get_pp_num_states) { amdgpu_dpm_get_pp_num_states(adev, &data); + } else { + memset(&data, 0, sizeof(data)); + } buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); for (i = 0; i < data.nums; i++) @@ -857,7 +870,7 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask) { int ret; - long level; + unsigned long level; char *sub_str = NULL; char *tmp; char buf_cpy[AMDGPU_MASK_BUF_MAX + 1]; @@ -873,8 +886,8 @@ while (tmp[0]) { sub_str = strsep(&tmp, delimiter); if (strlen(sub_str)) { - ret = kstrtol(sub_str, 0, &level); - if (ret) + ret = kstrtoul(sub_str, 0, &level); + if (ret || level > 31) return -EINVAL; *mask |= 1 << level; } else @@ -2088,7 +2101,7 @@ if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", sclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", sclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_sclk_label(struct device *dev, @@ -2118,7 +2131,7 @@ if (r) return r; - return snprintf(buf, PAGE_SIZE, "%d\n", mclk * 10 * 1000); + return snprintf(buf, PAGE_SIZE, "%u\n", mclk * 10 * 1000); } static ssize_t amdgpu_hwmon_show_mclk_label(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -65,12 +65,6 @@ /* inject address is 52 bits */ #define RAS_UMC_INJECT_ADDR_LIMIT (0x1ULL << 52) -static int amdgpu_ras_reserve_vram(struct amdgpu_device *adev, - uint64_t offset, uint64_t size, - struct amdgpu_bo **bo_ptr); -static int amdgpu_ras_release_vram(struct amdgpu_device *adev, - struct amdgpu_bo **bo_ptr); - static ssize_t amdgpu_ras_debugfs_read(struct file *f, char __user *buf, size_t size, loff_t *pos) { @@ -600,6 +594,9 @@ if (!obj) return -EINVAL; + if (!info || info->head.block == AMDGPU_RAS_BLOCK_COUNT) + return -EINVAL; + switch (info->head.block) { case AMDGPU_RAS_BLOCK__UMC: if (adev->umc.funcs->query_ras_error_count) @@ -1056,12 +1053,15 @@ int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev, struct ras_dispatch_if *info) { - struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head); - struct ras_ih_data *data = &obj->ih_data; + struct ras_manager *obj; + struct ras_ih_data *data; + obj = amdgpu_ras_find_obj(adev, &info->head); if (!obj) return -EINVAL; + data = &obj->ih_data; + if (data->inuse == 0) return 0; @@ -1214,75 +1214,6 @@ atomic_set(&ras->in_recovery, 0); } -static int amdgpu_ras_release_vram(struct amdgpu_device *adev, - struct amdgpu_bo **bo_ptr) -{ - /* no need to free it actually. */ - amdgpu_bo_free_kernel(bo_ptr, NULL, NULL); - return 0; -} - -/* reserve vram with size@offset */ -static int amdgpu_ras_reserve_vram(struct amdgpu_device *adev, - uint64_t offset, uint64_t size, - struct amdgpu_bo **bo_ptr) -{ - struct ttm_operation_ctx ctx = { false, false }; - struct amdgpu_bo_param bp; - int r = 0; - int i; - struct amdgpu_bo *bo; - - if (bo_ptr) - *bo_ptr = NULL; - memset(&bp, 0, sizeof(bp)); - bp.size = size; - bp.byte_align = PAGE_SIZE; - bp.domain = AMDGPU_GEM_DOMAIN_VRAM; - bp.flags = AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS | - AMDGPU_GEM_CREATE_NO_CPU_ACCESS; - bp.type = ttm_bo_type_kernel; - bp.resv = NULL; - - r = amdgpu_bo_create(adev, &bp, &bo); - if (r) - return -EINVAL; - - r = amdgpu_bo_reserve(bo, false); - if (r) - goto error_reserve; - - offset = ALIGN(offset, PAGE_SIZE); - for (i = 0; i < bo->placement.num_placement; ++i) { - bo->placements[i].fpfn = offset >> PAGE_SHIFT; - bo->placements[i].lpfn = (offset + size) >> PAGE_SHIFT; - } - - ttm_bo_mem_put(&bo->tbo, &bo->tbo.mem); - r = ttm_bo_mem_space(&bo->tbo, &bo->placement, &bo->tbo.mem, &ctx); - if (r) - goto error_pin; - - r = amdgpu_bo_pin_restricted(bo, - AMDGPU_GEM_DOMAIN_VRAM, - offset, - offset + size); - if (r) - goto error_pin; - - if (bo_ptr) - *bo_ptr = bo; - - amdgpu_bo_unreserve(bo); - return r; - -error_pin: - amdgpu_bo_unreserve(bo); -error_reserve: - amdgpu_bo_unref(&bo); - return r; -} - /* alloc/realloc bps array */ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev, struct ras_err_handler_data *data, int pages) @@ -1345,7 +1276,7 @@ struct amdgpu_ras *con = amdgpu_ras_get_context(adev); struct ras_err_handler_data *data; uint64_t bp; - struct amdgpu_bo *bo; + struct amdgpu_bo *bo = NULL; int i; if (!con || !con->eh_data) @@ -1359,12 +1290,14 @@ for (i = data->last_reserved; i < data->count; i++) { bp = data->bps[i].bp; - if (amdgpu_ras_reserve_vram(adev, bp << PAGE_SHIFT, - PAGE_SIZE, &bo)) + if (amdgpu_bo_create_kernel_at(adev, bp << PAGE_SHIFT, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &bo, NULL)) DRM_ERROR("RAS ERROR: reserve vram %llx fail\n", bp); data->bps[i].bo = bo; data->last_reserved = i + 1; + bo = NULL; } out: mutex_unlock(&con->recovery_lock); @@ -1390,7 +1323,7 @@ for (i = data->last_reserved - 1; i >= 0; i--) { bo = data->bps[i].bo; - amdgpu_ras_release_vram(adev, &bo); + amdgpu_bo_free_kernel(&bo, NULL, NULL); data->bps[i].bo = bo; data->last_reserved = i; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -138,7 +138,7 @@ return ret; } - __decode_table_header_from_buff(hdr, &buff[2]); + __decode_table_header_from_buff(hdr, buff); if (hdr->header == EEPROM_TABLE_HDR_VAL) { control->num_recs = (hdr->tbl_size - EEPROM_TABLE_HEADER_SIZE) / --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -437,8 +437,9 @@ size_t size, loff_t *pos) { struct amdgpu_ring *ring = file_inode(f)->i_private; - int r, i; uint32_t value, result, early[3]; + loff_t i; + int r; if (*pos & 3 || size & 3) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.c @@ -124,13 +124,12 @@ */ int amdgpu_gfx_rlc_init_csb(struct amdgpu_device *adev) { - volatile u32 *dst_ptr; u32 dws; int r; /* allocate clear state block */ adev->gfx.rlc.clear_state_size = dws = adev->gfx.rlc.funcs->get_csb_size(adev); - r = amdgpu_bo_create_reserved(adev, dws * 4, PAGE_SIZE, + r = amdgpu_bo_create_kernel(adev, dws * 4, PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &adev->gfx.rlc.clear_state_obj, &adev->gfx.rlc.clear_state_gpu_addr, @@ -141,13 +140,6 @@ return r; } - /* set up the cs buffer */ - dst_ptr = adev->gfx.rlc.cs_ptr; - adev->gfx.rlc.funcs->get_csb_buffer(adev, dst_ptr); - amdgpu_bo_kunmap(adev->gfx.rlc.clear_state_obj); - amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c @@ -58,6 +58,7 @@ { struct fd f = fdget(fd); struct amdgpu_fpriv *fpriv; + struct amdgpu_ctx_mgr *mgr; struct amdgpu_ctx *ctx; uint32_t id; int r; @@ -71,8 +72,11 @@ return r; } - idr_for_each_entry(&fpriv->ctx_mgr.ctx_handles, ctx, id) + mgr = &fpriv->ctx_mgr; + mutex_lock(&mgr->lock); + idr_for_each_entry(&mgr->ctx_handles, ctx, id) amdgpu_ctx_priority_override(ctx, priority); + mutex_unlock(&mgr->lock); fdput(f); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -218,7 +218,8 @@ */ fence_owner = amdgpu_sync_get_owner(f); if (fence_owner == AMDGPU_FENCE_OWNER_KFD && - owner != AMDGPU_FENCE_OWNER_UNDEFINED) + owner != AMDGPU_FENCE_OWNER_UNDEFINED && + owner != AMDGPU_FENCE_OWNER_KFD) continue; if (amdgpu_sync_same_dev(adev, f)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -138,6 +138,7 @@ } dma_fence_put(fence); + fence = NULL; r = amdgpu_bo_kmap(vram_obj, &vram_map); if (r) { @@ -183,6 +184,7 @@ } dma_fence_put(fence); + fence = NULL; r = amdgpu_bo_kmap(gtt_obj[i], >t_map); if (r) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -21,7 +21,7 @@ * */ -#if !defined(_AMDGPU_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#if !defined(_AMDGPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define _AMDGPU_TRACE_H_ #include @@ -170,7 +170,7 @@ __field(unsigned int, context) __field(unsigned int, seqno) __field(struct dma_fence *, fence) - __field(char *, ring_name) + __string(ring, to_amdgpu_ring(job->base.sched)->name) __field(u32, num_ibs) ), @@ -179,12 +179,12 @@ __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) __entry->context = job->base.s_fence->finished.context; __entry->seqno = job->base.s_fence->finished.seqno; - __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; + __assign_str(ring, to_amdgpu_ring(job->base.sched)->name) __entry->num_ibs = job->num_ibs; ), TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", __entry->sched_job_id, __get_str(timeline), __entry->context, - __entry->seqno, __entry->ring_name, __entry->num_ibs) + __entry->seqno, __get_str(ring), __entry->num_ibs) ); TRACE_EVENT(amdgpu_sched_run_job, @@ -195,7 +195,7 @@ __string(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) __field(unsigned int, context) __field(unsigned int, seqno) - __field(char *, ring_name) + __string(ring, to_amdgpu_ring(job->base.sched)->name) __field(u32, num_ibs) ), @@ -204,12 +204,12 @@ __assign_str(timeline, AMDGPU_JOB_GET_TIMELINE_NAME(job)) __entry->context = job->base.s_fence->finished.context; __entry->seqno = job->base.s_fence->finished.seqno; - __entry->ring_name = to_amdgpu_ring(job->base.sched)->name; + __assign_str(ring, to_amdgpu_ring(job->base.sched)->name) __entry->num_ibs = job->num_ibs; ), TP_printk("sched_job=%llu, timeline=%s, context=%u, seqno=%u, ring_name=%s, num_ibs=%u", __entry->sched_job_id, __get_str(timeline), __entry->context, - __entry->seqno, __entry->ring_name, __entry->num_ibs) + __entry->seqno, __get_str(ring), __entry->num_ibs) ); @@ -468,7 +468,7 @@ TP_PROTO(struct amdgpu_job *sched_job, struct dma_fence *fence), TP_ARGS(sched_job, fence), TP_STRUCT__entry( - __field(const char *,name) + __string(ring, sched_job->base.sched->name); __field(uint64_t, id) __field(struct dma_fence *, fence) __field(uint64_t, ctx) @@ -476,14 +476,14 @@ ), TP_fast_assign( - __entry->name = sched_job->base.sched->name; + __assign_str(ring, sched_job->base.sched->name) __entry->id = sched_job->base.id; __entry->fence = fence; __entry->ctx = fence->context; __entry->seqno = fence->seqno; ), TP_printk("job ring=%s, id=%llu, need pipe sync to fence=%p, context=%llu, seq=%u", - __entry->name, __entry->id, + __get_str(ring), __entry->id, __entry->fence, __entry->ctx, __entry->seqno) ); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -788,7 +789,7 @@ struct hmm_mirror *mirror = bo->mn ? &bo->mn->mirror : NULL; struct ttm_tt *ttm = bo->tbo.ttm; struct amdgpu_ttm_tt *gtt = (void *)ttm; - struct mm_struct *mm = gtt->usertask->mm; + struct mm_struct *mm; unsigned long start = gtt->userptr; struct vm_area_struct *vma; struct hmm_range *range; @@ -796,25 +797,14 @@ uint64_t *pfns; int r = 0; - if (!mm) /* Happens during process shutdown */ - return -ESRCH; - if (unlikely(!mirror)) { DRM_DEBUG_DRIVER("Failed to get hmm_mirror\n"); - r = -EFAULT; - goto out; + return -EFAULT; } - vma = find_vma(mm, start); - if (unlikely(!vma || start < vma->vm_start)) { - r = -EFAULT; - goto out; - } - if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) && - vma->vm_file)) { - r = -EPERM; - goto out; - } + mm = mirror->hmm->mmu_notifier.mm; + if (!mmget_not_zero(mm)) /* Happens during process shutdown */ + return -ESRCH; range = kzalloc(sizeof(*range), GFP_KERNEL); if (unlikely(!range)) { @@ -847,6 +837,17 @@ hmm_range_wait_until_valid(range, HMM_RANGE_DEFAULT_TIMEOUT); down_read(&mm->mmap_sem); + vma = find_vma(mm, start); + if (unlikely(!vma || start < vma->vm_start)) { + r = -EFAULT; + goto out_unlock; + } + if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) && + vma->vm_file)) { + r = -EPERM; + goto out_unlock; + } + r = hmm_range_fault(range, 0); up_read(&mm->mmap_sem); @@ -865,15 +866,19 @@ } gtt->range = range; + mmput(mm); return 0; +out_unlock: + up_read(&mm->mmap_sem); out_free_pfns: hmm_range_unregister(range); kvfree(pfns); out_free_ranges: kfree(range); out: + mmput(mm); return r; } @@ -962,6 +967,7 @@ release_sg: kfree(ttm->sg); + ttm->sg = NULL; return r; } @@ -978,7 +984,7 @@ DMA_BIDIRECTIONAL : DMA_TO_DEVICE; /* double check that we don't free the table twice */ - if (!ttm->sg->sgl) + if (!ttm->sg || !ttm->sg->sgl) return; /* unmap the pages mapped to the device */ @@ -1294,6 +1300,7 @@ if (gtt && gtt->userptr) { amdgpu_ttm_tt_set_user_pages(ttm, NULL); kfree(ttm->sg); + ttm->sg = NULL; ttm->page_flags &= ~TTM_PAGE_FLAG_SG; return; } @@ -1634,81 +1641,25 @@ */ static int amdgpu_ttm_fw_reserve_vram_init(struct amdgpu_device *adev) { - struct ttm_operation_ctx ctx = { false, false }; - struct amdgpu_bo_param bp; - int r = 0; - int i; - u64 vram_size = adev->gmc.visible_vram_size; - u64 offset = adev->fw_vram_usage.start_offset; - u64 size = adev->fw_vram_usage.size; - struct amdgpu_bo *bo; - - memset(&bp, 0, sizeof(bp)); - bp.size = adev->fw_vram_usage.size; - bp.byte_align = PAGE_SIZE; - bp.domain = AMDGPU_GEM_DOMAIN_VRAM; - bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | - AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; - bp.type = ttm_bo_type_kernel; - bp.resv = NULL; + uint64_t vram_size = adev->gmc.visible_vram_size; + int r; + adev->fw_vram_usage.va = NULL; adev->fw_vram_usage.reserved_bo = NULL; - if (adev->fw_vram_usage.size > 0 && - adev->fw_vram_usage.size <= vram_size) { - - r = amdgpu_bo_create(adev, &bp, - &adev->fw_vram_usage.reserved_bo); - if (r) - goto error_create; - - r = amdgpu_bo_reserve(adev->fw_vram_usage.reserved_bo, false); - if (r) - goto error_reserve; - - /* remove the original mem node and create a new one at the - * request position - */ - bo = adev->fw_vram_usage.reserved_bo; - offset = ALIGN(offset, PAGE_SIZE); - for (i = 0; i < bo->placement.num_placement; ++i) { - bo->placements[i].fpfn = offset >> PAGE_SHIFT; - bo->placements[i].lpfn = (offset + size) >> PAGE_SHIFT; - } - - ttm_bo_mem_put(&bo->tbo, &bo->tbo.mem); - r = ttm_bo_mem_space(&bo->tbo, &bo->placement, - &bo->tbo.mem, &ctx); - if (r) - goto error_pin; - - r = amdgpu_bo_pin_restricted(adev->fw_vram_usage.reserved_bo, - AMDGPU_GEM_DOMAIN_VRAM, - adev->fw_vram_usage.start_offset, - (adev->fw_vram_usage.start_offset + - adev->fw_vram_usage.size)); - if (r) - goto error_pin; - r = amdgpu_bo_kmap(adev->fw_vram_usage.reserved_bo, - &adev->fw_vram_usage.va); - if (r) - goto error_kmap; - - amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); - } - return r; + if (adev->fw_vram_usage.size == 0 || + adev->fw_vram_usage.size > vram_size) + return 0; -error_kmap: - amdgpu_bo_unpin(adev->fw_vram_usage.reserved_bo); -error_pin: - amdgpu_bo_unreserve(adev->fw_vram_usage.reserved_bo); -error_reserve: - amdgpu_bo_unref(&adev->fw_vram_usage.reserved_bo); -error_create: - adev->fw_vram_usage.va = NULL; - adev->fw_vram_usage.reserved_bo = NULL; + return amdgpu_bo_create_kernel_at(adev, + adev->fw_vram_usage.start_offset, + adev->fw_vram_usage.size, + AMDGPU_GEM_DOMAIN_VRAM, + &adev->fw_vram_usage.reserved_bo, + &adev->fw_vram_usage.va); return r; } + /** * amdgpu_ttm_init - Init the memory management (ttm) as well as various * gtt/vram related fields. @@ -1727,6 +1678,7 @@ mutex_init(&adev->mman.gtt_window_lock); + dma_set_max_seg_size(adev->dev, UINT_MAX); /* No others user of address space so set it to 0 */ r = ttm_bo_device_init(&adev->mman.bdev, &amdgpu_bo_driver, @@ -1781,6 +1733,20 @@ NULL, &stolen_vga_buf); if (r) return r; + + /* + * reserve one TMR (64K) memory at the top of VRAM which holds + * IP Discovery data and is protected by PSP. + */ + r = amdgpu_bo_create_kernel_at(adev, + adev->gmc.real_vram_size - DISCOVERY_TMR_SIZE, + DISCOVERY_TMR_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, + &adev->discovery_memory, + NULL); + if (r) + return r; + DRM_INFO("amdgpu: %uM of VRAM memory ready\n", (unsigned) (adev->gmc.real_vram_size / (1024 * 1024))); @@ -1845,6 +1811,9 @@ void *stolen_vga_buf; /* return the VGA stolen memory (if any) back to VRAM */ amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf); + + /* return the IP Discovery TMR memory back to VRAM */ + amdgpu_bo_free_kernel(&adev->discovery_memory, NULL, NULL); } /** @@ -2008,7 +1977,7 @@ unsigned i; int r; - if (direct_submit && !ring->sched.ready) { + if (!direct_submit && !ring->sched.ready) { DRM_ERROR("Trying to move memory with ring turned off.\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -568,8 +568,7 @@ void amdgpu_ucode_free_bo(struct amdgpu_device *adev) { - if (adev->firmware.load_type != AMDGPU_FW_LOAD_DIRECT) - amdgpu_bo_free_kernel(&adev->firmware.fw_buf, + amdgpu_bo_free_kernel(&adev->firmware.fw_buf, &adev->firmware.fw_buf_mc, &adev->firmware.fw_buf_ptr); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -231,7 +231,7 @@ if ((adev->asic_type == CHIP_POLARIS10 || adev->asic_type == CHIP_POLARIS11) && (adev->uvd.fw_version < FW_1_66_16)) - DRM_ERROR("POLARIS10/11 UVD firmware version %hu.%hu is too old.\n", + DRM_ERROR("POLARIS10/11 UVD firmware version %u.%u is too old.\n", version_major, version_minor); } else { unsigned int enc_major, enc_minor, dec_minor; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -715,7 +715,8 @@ uint32_t created = 0; uint32_t allocated = 0; uint32_t tmp, handle = 0; - uint32_t *size = &tmp; + uint32_t dummy = 0xffffffff; + uint32_t *size = &dummy; unsigned idx; int i, r = 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -55,11 +55,9 @@ MODULE_FIRMWARE(FIRMWARE_RAVEN); MODULE_FIRMWARE(FIRMWARE_PICASSO); MODULE_FIRMWARE(FIRMWARE_RAVEN2); -MODULE_FIRMWARE(FIRMWARE_ARCTURUS); MODULE_FIRMWARE(FIRMWARE_RENOIR); MODULE_FIRMWARE(FIRMWARE_NAVI10); MODULE_FIRMWARE(FIRMWARE_NAVI14); -MODULE_FIRMWARE(FIRMWARE_NAVI12); static void amdgpu_vcn_idle_work_handler(struct work_struct *work); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h @@ -48,6 +48,8 @@ uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; }; +enum idh_request; + /** * struct amdgpu_virt_ops - amdgpu device virt operations */ @@ -56,7 +58,8 @@ int (*rel_full_gpu)(struct amdgpu_device *adev, bool init); int (*reset_gpu)(struct amdgpu_device *adev); int (*wait_reset)(struct amdgpu_device *adev); - void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); + void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req, + u32 data1, u32 data2, u32 data3); int (*get_pp_clk)(struct amdgpu_device *adev, u32 type, char *buf); int (*force_dpm_level)(struct amdgpu_device *adev, u32 level); }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1034,10 +1034,8 @@ id->oa_base != job->oa_base || id->oa_size != job->oa_size); bool vm_flush_needed = job->vm_needs_flush; - bool pasid_mapping_needed = id->pasid != job->pasid || - !id->pasid_mapping || - !dma_fence_is_signaled(id->pasid_mapping); struct dma_fence *fence = NULL; + bool pasid_mapping_needed = false; unsigned patch_offset = 0; int r; @@ -1047,6 +1045,12 @@ pasid_mapping_needed = true; } + mutex_lock(&id_mgr->lock); + if (id->pasid != job->pasid || !id->pasid_mapping || + !dma_fence_is_signaled(id->pasid_mapping)) + pasid_mapping_needed = true; + mutex_unlock(&id_mgr->lock); + gds_switch_needed &= !!ring->funcs->emit_gds_switch; vm_flush_needed &= !!ring->funcs->emit_vm_flush && job->vm_pd_addr != AMDGPU_BO_INVALID_OFFSET; @@ -1086,9 +1090,11 @@ } if (pasid_mapping_needed) { + mutex_lock(&id_mgr->lock); id->pasid = job->pasid; dma_fence_put(id->pasid_mapping); id->pasid_mapping = dma_fence_get(fence); + mutex_unlock(&id_mgr->lock); } dma_fence_put(fence); @@ -2089,6 +2095,37 @@ trace_amdgpu_vm_bo_map(bo_va, mapping); } +/* Validate operation parameters to prevent potential abuse */ +static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev, + struct amdgpu_bo *bo, + uint64_t saddr, + uint64_t offset, + uint64_t size) +{ + uint64_t tmp, lpfn; + + if (saddr & AMDGPU_GPU_PAGE_MASK + || offset & AMDGPU_GPU_PAGE_MASK + || size & AMDGPU_GPU_PAGE_MASK) + return -EINVAL; + + if (check_add_overflow(saddr, size, &tmp) + || check_add_overflow(offset, size, &tmp) + || size == 0 /* which also leads to end < begin */) + return -EINVAL; + + /* make sure object fit at this offset */ + if (bo && offset + size > amdgpu_bo_size(bo)) + return -EINVAL; + + /* Ensure last pfn not exceed max_pfn */ + lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT; + if (lpfn >= adev->vm_manager.max_pfn) + return -EINVAL; + + return 0; +} + /** * amdgpu_vm_bo_map - map bo inside a vm * @@ -2115,20 +2152,14 @@ struct amdgpu_bo *bo = bo_va->base.bo; struct amdgpu_vm *vm = bo_va->base.vm; uint64_t eaddr; + int r; - /* validate the parameters */ - if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || - size == 0 || size & AMDGPU_GPU_PAGE_MASK) - return -EINVAL; - - /* make sure object fit at this offset */ - eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo))) - return -EINVAL; + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); + if (r) + return r; saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr); if (tmp) { @@ -2181,16 +2212,9 @@ uint64_t eaddr; int r; - /* validate the parameters */ - if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK || - size == 0 || size & AMDGPU_GPU_PAGE_MASK) - return -EINVAL; - - /* make sure object fit at this offset */ - eaddr = saddr + size - 1; - if (saddr >= eaddr || - (bo && offset + size > amdgpu_bo_size(bo))) - return -EINVAL; + r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); + if (r) + return r; /* Allocate all the needed memory */ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); @@ -2204,7 +2228,7 @@ } saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; mapping->start = saddr; mapping->last = eaddr; @@ -2291,10 +2315,14 @@ struct amdgpu_bo_va_mapping *before, *after, *tmp, *next; LIST_HEAD(removed); uint64_t eaddr; + int r; + + r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size); + if (r) + return r; - eaddr = saddr + size - 1; saddr /= AMDGPU_GPU_PAGE_SIZE; - eaddr /= AMDGPU_GPU_PAGE_SIZE; + eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; /* Allocate all the needed memory */ before = kzalloc(sizeof(*before), GFP_KERNEL); @@ -2327,7 +2355,7 @@ after->start = eaddr + 1; after->last = tmp->last; after->offset = tmp->offset; - after->offset += after->start - tmp->start; + after->offset += (after->start - tmp->start) << PAGE_SHIFT; after->flags = tmp->flags; after->bo_va = tmp->bo_va; list_add(&after->list, &tmp->bo_va->invalids); @@ -2861,10 +2889,17 @@ WARN_ONCE((vm->use_cpu_for_update && !amdgpu_gmc_vram_full_visible(&adev->gmc)), "CPU update of VM recommended only for large BAR system\n"); - if (vm->use_cpu_for_update) + if (vm->use_cpu_for_update) { + /* Sync with last SDMA update/clear before switching to CPU */ + r = amdgpu_bo_sync_wait(vm->root.base.bo, + AMDGPU_FENCE_OWNER_UNDEFINED, true); + if (r) + goto free_idr; + vm->update_funcs = &amdgpu_vm_cpu_funcs; - else + } else { vm->update_funcs = &amdgpu_vm_sdma_funcs; + } dma_fence_put(vm->last_update); vm->last_update = NULL; @@ -3063,6 +3098,10 @@ struct amdgpu_fpriv *fpriv = filp->driver_priv; int r; + /* No valid flags defined yet */ + if (args->in.flags) + return -EINVAL; + switch (args->in.op) { case AMDGPU_VM_OP_RESERVE_VMID: /* current, we only have requirement to reserve vmid from gfxhub */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -105,8 +105,8 @@ #define AMDGPU_MMHUB_0 1 #define AMDGPU_MMHUB_1 2 -/* hardcode that limit for now */ -#define AMDGPU_VA_RESERVED_SIZE (1ULL << 20) +/* Reserve 2MB at top/bottom of address space for kernel use */ +#define AMDGPU_VA_RESERVED_SIZE (2ULL << 20) /* max vmids dedicated for process */ #define AMDGPU_VM_MAX_RESERVED_VMID 1 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -311,15 +311,22 @@ } +/* + * NOTE psp_xgmi_node_info.num_hops layout is as follows: + * num_hops[7:6] = link type (0 = xGMI2, 1 = xGMI3, 2/3 = reserved) + * num_hops[5:3] = reserved + * num_hops[2:0] = number of hops + */ int amdgpu_xgmi_get_hops_count(struct amdgpu_device *adev, struct amdgpu_device *peer_adev) { struct psp_xgmi_topology_info *top = &adev->psp.xgmi_context.top_info; + uint8_t num_hops_mask = 0x7; int i; for (i = 0 ; i < top->num_nodes; ++i) if (top->nodes[i].node_id == peer_adev->gmc.xgmi.node_id) - return top->nodes[i].num_hops; + return top->nodes[i].num_hops & num_hops_mask; return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/atom.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/atom.c @@ -308,7 +308,7 @@ DEBUG("IMM 0x%02X\n", val); return val; } - return 0; + break; case ATOM_ARG_PLL: idx = U8(*ptr); (*ptr)++; @@ -744,8 +744,8 @@ cjiffies = jiffies; if (time_after(cjiffies, ctx->last_jump_jiffies)) { cjiffies -= ctx->last_jump_jiffies; - if ((jiffies_to_msecs(cjiffies) > 5000)) { - DRM_ERROR("atombios stuck in loop for more than 5secs aborting\n"); + if ((jiffies_to_msecs(cjiffies) > 10000)) { + DRM_ERROR("atombios stuck in loop for more than 10secs aborting\n"); ctx->abort = true; } } else { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -2098,23 +2098,29 @@ fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; if (fake_edid_record->ucFakeEDIDLength) { struct edid *edid; - int edid_size = - max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength); - edid = kmalloc(edid_size, GFP_KERNEL); - if (edid) { - memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], - fake_edid_record->ucFakeEDIDLength); + int edid_size; + if (fake_edid_record->ucFakeEDIDLength == 128) + edid_size = fake_edid_record->ucFakeEDIDLength; + else + edid_size = fake_edid_record->ucFakeEDIDLength * 128; + edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0], + edid_size, GFP_KERNEL); + if (edid) { if (drm_edid_is_valid(edid)) { adev->mode_info.bios_hardcoded_edid = edid; adev->mode_info.bios_hardcoded_edid_size = edid_size; - } else + } else { kfree(edid); + } } + record += struct_size(fake_edid_record, + ucFakeEDIDString, + edid_size); + } else { + /* empty fake edid record must be 3 bytes long */ + record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1; } - record += fake_edid_record->ucFakeEDIDLength ? - fake_edid_record->ucFakeEDIDLength + 2 : - sizeof(ATOM_FAKE_EDID_PATCH_RECORD); break; case LCD_PANEL_RESOLUTION_RECORD_TYPE: panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/cik.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1384,7 +1384,6 @@ static void cik_pcie_gen3_enable(struct amdgpu_device *adev) { struct pci_dev *root = adev->pdev->bus->self; - int bridge_pos, gpu_pos; u32 speed_cntl, current_data_rate; int i; u16 tmp16; @@ -1419,12 +1418,7 @@ DRM_INFO("enabling PCIE gen 2 link speeds, disable with amdgpu.pcie_gen2=0\n"); } - bridge_pos = pci_pcie_cap(root); - if (!bridge_pos) - return; - - gpu_pos = pci_pcie_cap(adev->pdev); - if (!gpu_pos) + if (!pci_is_pcie(root) || !pci_is_pcie(adev->pdev)) return; if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { @@ -1434,14 +1428,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(ixPCIE_LC_STATUS1); max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >> @@ -1465,15 +1453,23 @@ for (i = 0; i < 10; i++) { /* check status */ - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16); + pcie_capability_read_word(adev->pdev, + PCI_EXP_DEVSTA, + &tmp16); if (tmp16 & PCI_EXP_DEVSTA_TRPND) break; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2); + pcie_capability_read_word(root, PCI_EXP_LNKCTL, + &bridge_cfg); + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL, + &gpu_cfg); + + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &bridge_cfg2); + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL2, + &gpu_cfg2); tmp = RREG32_PCIE(ixPCIE_LC_CNTL4); tmp |= PCIE_LC_CNTL4__LC_SET_QUIESCE_MASK; @@ -1486,26 +1482,38 @@ msleep(100); /* linkctl */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16); - - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(root, + PCI_EXP_LNKCTL2, + tmp16); + + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(adev->pdev, + PCI_EXP_LNKCTL2, + tmp16); tmp = RREG32_PCIE(ixPCIE_LC_CNTL4); tmp &= ~PCIE_LC_CNTL4__LC_SET_QUIESCE_MASK; @@ -1520,15 +1528,16 @@ speed_cntl &= ~PCIE_LC_SPEED_CNTL__LC_FORCE_DIS_SW_SPEED_CHANGE_MASK; WREG32_PCIE(ixPCIE_LC_SPEED_CNTL, speed_cntl); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~0xf; + pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16); + tmp16 &= ~PCI_EXP_LNKCTL2_TLS; + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) - tmp16 |= 3; /* gen3 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) - tmp16 |= 2; /* gen2 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else - tmp16 |= 1; /* gen1 */ - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ + pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16); speed_cntl = RREG32_PCIE(ixPCIE_LC_SPEED_CNTL); speed_cntl |= PCIE_LC_SPEED_CNTL__LC_INITIATE_LINK_SPEED_CHANGE_MASK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -203,6 +203,12 @@ tmp = RREG32(mmIH_RB_CNTL); tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; WREG32(mmIH_RB_CNTL, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; + WREG32(mmIH_RB_CNTL, tmp); } return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -228,7 +228,7 @@ u32 extra_bits = vmid & 0xf; /* IB packet must end on a 8 DW boundary */ - cik_sdma_ring_insert_nop(ring, (12 - (lower_32_bits(ring->wptr) & 7)) % 8); + cik_sdma_ring_insert_nop(ring, (4 - lower_32_bits(ring->wptr)) & 7); amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_INDIRECT_BUFFER, 0, extra_bits)); amdgpu_ring_write(ring, ib->gpu_addr & 0xffffffe0); /* base must be 32 byte aligned */ @@ -811,7 +811,7 @@ u32 pad_count; int i; - pad_count = (8 - (ib->length_dw & 0x7)) % 8; + pad_count = (-ib->length_dw) & 7; for (i = 0; i < pad_count; i++) if (sdma && sdma->burst_nop && (i == 0)) ib->ptr[ib->length_dw++] = @@ -1071,22 +1071,19 @@ { u32 srbm_soft_reset = 0; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - u32 tmp = RREG32(mmSRBM_STATUS2); + u32 tmp; - if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) { - /* sdma0 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; - } - if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) { - /* sdma1 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; - } + /* sdma0 */ + tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); + tmp |= SDMA0_F32_CNTL__HALT_MASK; + WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); + srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; + + /* sdma1 */ + tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); + tmp |= SDMA0_F32_CNTL__HALT_MASK; + WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); + srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; if (srbm_soft_reset) { tmp = RREG32(mmSRBM_SOFT_RESET); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -193,19 +193,35 @@ wptr = le32_to_cpu(*ih->wptr_cpu); - if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { - wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", - wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); - ih->rptr = (wptr + 16) & ih->ptr_mask; - tmp = RREG32(mmIH_RB_CNTL); - tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); - WREG32(mmIH_RB_CNTL, tmp); - } + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + /* Double check that the overflow wasn't already cleared. */ + wptr = RREG32(mmIH_RB_WPTR); + + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); + + /* When a ring buffer overflow happen start parsing interrupt + * from the last not overwritten vector (wptr + 16). Hopefully + * this should allow us to catchup. + */ + dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); + ih->rptr = (wptr + 16) & ih->ptr_mask; + tmp = RREG32(mmIH_RB_CNTL); + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); + WREG32(mmIH_RB_CNTL, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); + WREG32(mmIH_RB_CNTL, tmp); + +out: return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/df_v1_7.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/df_v1_7.c @@ -63,6 +63,8 @@ int fb_channel_number; fb_channel_number = adev->df_funcs->get_fb_channel_number(adev); + if (fb_channel_number >= ARRAY_SIZE(df_v1_7_channel_number)) + fb_channel_number = 0; return df_v1_7_channel_number[fb_channel_number]; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/df_v3_6.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/df_v3_6.c @@ -261,23 +261,29 @@ { u32 tmp; - /* Put DF on broadcast mode */ - adev->df_funcs->enable_broadcast_mode(adev, true); + if (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG) { + /* Put DF on broadcast mode */ + adev->df_funcs->enable_broadcast_mode(adev, true); - if (enable && (adev->cg_flags & AMD_CG_SUPPORT_DF_MGCG)) { - tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater); - tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; - tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY; - WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp); - } else { - tmp = RREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater); - tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; - tmp |= DF_V3_6_MGCG_DISABLE; - WREG32_SOC15(DF, 0, mmDF_PIE_AON0_DfGlobalClkGater, tmp); - } + if (enable) { + tmp = RREG32_SOC15(DF, 0, + mmDF_PIE_AON0_DfGlobalClkGater); + tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; + tmp |= DF_V3_6_MGCG_ENABLE_15_CYCLE_DELAY; + WREG32_SOC15(DF, 0, + mmDF_PIE_AON0_DfGlobalClkGater, tmp); + } else { + tmp = RREG32_SOC15(DF, 0, + mmDF_PIE_AON0_DfGlobalClkGater); + tmp &= ~DF_PIE_AON0_DfGlobalClkGater__MGCGMode_MASK; + tmp |= DF_V3_6_MGCG_DISABLE; + WREG32_SOC15(DF, 0, + mmDF_PIE_AON0_DfGlobalClkGater, tmp); + } - /* Exit broadcast mode */ - adev->df_funcs->enable_broadcast_mode(adev, false); + /* Exit broadcast mode */ + adev->df_funcs->enable_broadcast_mode(adev, false); + } } static void df_v3_6_get_clockgating_state(struct amdgpu_device *adev, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -82,13 +82,6 @@ MODULE_FIRMWARE("amdgpu/navi14_mec2.bin"); MODULE_FIRMWARE("amdgpu/navi14_rlc.bin"); -MODULE_FIRMWARE("amdgpu/navi12_ce.bin"); -MODULE_FIRMWARE("amdgpu/navi12_pfp.bin"); -MODULE_FIRMWARE("amdgpu/navi12_me.bin"); -MODULE_FIRMWARE("amdgpu/navi12_mec.bin"); -MODULE_FIRMWARE("amdgpu/navi12_mec2.bin"); -MODULE_FIRMWARE("amdgpu/navi12_rlc.bin"); - static const struct soc15_reg_golden golden_settings_gc_10_1[] = { SOC15_REG_GOLDEN_VALUE(GC, 0, mmCB_HW_CONTROL_4, 0xffffffff, 0x00400014), @@ -190,9 +183,10 @@ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG, 0xffffffff, 0x20000000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xffffffff, 0x00000420), SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000200), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x04800000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x04900000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DFSM_TILES_IN_FLIGHT, 0x0000ffff, 0x0000003f), SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_LAST_OF_BURST_CONFIG, 0xffffffff, 0x03860204), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1800ff, 0x00000044), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff0ffff, 0x00000500), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PRIV_CONTROL, 0x00007fff, 0x000001fe), SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0xffffffff, 0xe4e4e4e4), @@ -210,12 +204,13 @@ SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000820, 0x00000820), SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x001f0000, 0x00070104), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000133, 0x00000130), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff), SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CNTL, 0xffdf80ff, 0x479c0010), - SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00800000) + SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00c00000) }; static const struct soc15_reg_golden golden_settings_gc_10_1_nv14[] = @@ -993,39 +988,6 @@ return 0; } -static int gfx_v10_0_csb_vram_pin(struct amdgpu_device *adev) -{ - int r; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); - if (unlikely(r != 0)) - return r; - - r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, - AMDGPU_GEM_DOMAIN_VRAM); - if (!r) - adev->gfx.rlc.clear_state_gpu_addr = - amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj); - - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - - return r; -} - -static void gfx_v10_0_csb_vram_unpin(struct amdgpu_device *adev) -{ - int r; - - if (!adev->gfx.rlc.clear_state_obj) - return; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true); - if (likely(r == 0)) { - amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - } -} - static void gfx_v10_0_mec_fini(struct amdgpu_device *adev) { amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL); @@ -1785,27 +1747,34 @@ WREG32_SOC15(GC, 0, mmCP_INT_CNTL_RING0, tmp); } -static void gfx_v10_0_init_csb(struct amdgpu_device *adev) +static int gfx_v10_0_init_csb(struct amdgpu_device *adev) { + adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr); + /* csib */ WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_HI, adev->gfx.rlc.clear_state_gpu_addr >> 32); WREG32_SOC15(GC, 0, mmRLC_CSIB_ADDR_LO, adev->gfx.rlc.clear_state_gpu_addr & 0xfffffffc); WREG32_SOC15(GC, 0, mmRLC_CSIB_LENGTH, adev->gfx.rlc.clear_state_size); + + return 0; } -static void gfx_v10_0_init_pg(struct amdgpu_device *adev) +static int gfx_v10_0_init_pg(struct amdgpu_device *adev) { int i; + int r; - gfx_v10_0_init_csb(adev); + r = gfx_v10_0_init_csb(adev); + if (r) + return r; for (i = 0; i < adev->num_vmhubs; i++) amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0); /* TODO: init power gating */ - return; + return 0; } void gfx_v10_0_rlc_stop(struct amdgpu_device *adev) @@ -1907,7 +1876,10 @@ r = gfx_v10_0_wait_for_rlc_autoload_complete(adev); if (r) return r; - gfx_v10_0_init_pg(adev); + + r = gfx_v10_0_init_pg(adev); + if (r) + return r; /* enable RLC SRM */ gfx_v10_0_rlc_enable_srm(adev); @@ -1933,7 +1905,10 @@ return r; } - gfx_v10_0_init_pg(adev); + r = gfx_v10_0_init_pg(adev); + if (r) + return r; + adev->gfx.rlc.funcs->start(adev); if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) { @@ -2400,7 +2375,7 @@ return 0; } -static void gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) +static int gfx_v10_0_cp_gfx_enable(struct amdgpu_device *adev, bool enable) { int i; u32 tmp = RREG32_SOC15(GC, 0, mmCP_ME_CNTL); @@ -2413,7 +2388,17 @@ adev->gfx.gfx_ring[i].sched.ready = false; } WREG32_SOC15(GC, 0, mmCP_ME_CNTL, tmp); - udelay(50); + + for (i = 0; i < adev->usec_timeout; i++) { + if (RREG32_SOC15(GC, 0, mmCP_STAT) == 0) + break; + udelay(1); + } + + if (i >= adev->usec_timeout) + DRM_ERROR("failed to %s cp gfx\n", enable ? "unhalt" : "halt"); + + return 0; } static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev) @@ -3514,6 +3499,7 @@ /* reset ring buffer */ ring->wptr = 0; + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], 0); amdgpu_ring_clear_ring(ring); } else { amdgpu_ring_clear_ring(ring); @@ -3534,8 +3520,10 @@ return r; r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); - if (unlikely(r != 0)) + if (unlikely(r != 0)) { + amdgpu_bo_unreserve(ring->mqd_obj); return r; + } gfx_v10_0_kiq_init_queue(ring); amdgpu_bo_kunmap(ring->mqd_obj); @@ -3732,10 +3720,6 @@ int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = gfx_v10_0_csb_vram_pin(adev); - if (r) - return r; - if (!amdgpu_emu_mode) gfx_v10_0_init_golden_registers(adev); @@ -3823,7 +3807,6 @@ } gfx_v10_0_cp_enable(adev, false); gfx_v10_0_enable_gui_idle_interrupt(adev, false); - gfx_v10_0_csb_vram_unpin(adev); return 0; } @@ -3936,11 +3919,13 @@ { uint64_t clock; + amdgpu_gfx_off_ctrl(adev, false); mutex_lock(&adev->gfx.gpu_clock_mutex); WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); mutex_unlock(&adev->gfx.gpu_clock_mutex); + amdgpu_gfx_off_ctrl(adev, true); return clock; } @@ -4050,10 +4035,8 @@ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); data &= ~(RLC_CGTT_MGCG_OVERRIDE__GRBM_CGTT_SCLK_OVERRIDE_MASK | RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK | - RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK); - - /* only for Vega10 & Raven1 */ - data |= RLC_CGTT_MGCG_OVERRIDE__RLC_CGTT_SCLK_OVERRIDE_MASK; + RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGLS_OVERRIDE_MASK | + RLC_CGTT_MGCG_OVERRIDE__ENABLE_CGTS_LEGACY_MASK); if (def != data) WREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE, data); @@ -4246,11 +4229,7 @@ switch (adev->asic_type) { case CHIP_NAVI10: case CHIP_NAVI14: - if (!enable) { - amdgpu_gfx_off_ctrl(adev, false); - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); - } else - amdgpu_gfx_off_ctrl(adev, true); + amdgpu_gfx_off_ctrl(adev, enable); break; default: break; @@ -4643,12 +4622,17 @@ struct amdgpu_device *adev = ring->adev; struct amdgpu_kiq *kiq = &adev->gfx.kiq; struct amdgpu_ring *kiq_ring = &kiq->ring; + unsigned long flags; if (!kiq->pmf || !kiq->pmf->kiq_unmap_queues) return -EINVAL; - if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) + spin_lock_irqsave(&kiq->ring_lock, flags); + + if (amdgpu_ring_alloc(kiq_ring, kiq->pmf->unmap_queues_size)) { + spin_unlock_irqrestore(&kiq->ring_lock, flags); return -ENOMEM; + } /* assert preemption condition */ amdgpu_ring_set_preempt_cond_exec(ring, false); @@ -4659,6 +4643,8 @@ ++ring->trail_seq); amdgpu_ring_commit(kiq_ring); + spin_unlock_irqrestore(&kiq->ring_lock, flags); + /* poll the trailing fence */ for (i = 0; i < adev->usec_timeout; i++) { if (ring->trail_seq == --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -4554,6 +4554,8 @@ gfx_v7_0_constants_init(adev); + /* init CSB */ + adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr); /* init rlc */ r = adev->gfx.rlc.funcs->resume(adev); if (r) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -1321,39 +1321,6 @@ return 0; } -static int gfx_v8_0_csb_vram_pin(struct amdgpu_device *adev) -{ - int r; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); - if (unlikely(r != 0)) - return r; - - r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, - AMDGPU_GEM_DOMAIN_VRAM); - if (!r) - adev->gfx.rlc.clear_state_gpu_addr = - amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj); - - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - - return r; -} - -static void gfx_v8_0_csb_vram_unpin(struct amdgpu_device *adev) -{ - int r; - - if (!adev->gfx.rlc.clear_state_obj) - return; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true); - if (likely(r == 0)) { - amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - } -} - static void gfx_v8_0_mec_fini(struct amdgpu_device *adev) { amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL); @@ -3917,6 +3884,7 @@ static void gfx_v8_0_init_csb(struct amdgpu_device *adev) { + adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr); /* csib */ WREG32(mmRLC_CSIB_ADDR_HI, adev->gfx.rlc.clear_state_gpu_addr >> 32); @@ -4837,10 +4805,6 @@ gfx_v8_0_init_golden_registers(adev); gfx_v8_0_constants_init(adev); - r = gfx_v8_0_csb_vram_pin(adev); - if (r) - return r; - r = adev->gfx.rlc.funcs->resume(adev); if (r) return r; @@ -4958,8 +4922,6 @@ pr_err("rlc is busy, skip halt rlc\n"); amdgpu_gfx_rlc_exit_safe_mode(adev); - gfx_v8_0_csb_vram_unpin(adev); - return 0; } @@ -6184,7 +6146,23 @@ bool write64bit = flags & AMDGPU_FENCE_FLAG_64BIT; bool int_sel = flags & AMDGPU_FENCE_FLAG_INT; - /* EVENT_WRITE_EOP - flush caches, send int */ + /* Workaround for cache flush problems. First send a dummy EOP + * event down the pipe with seq one below. + */ + amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); + amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | + EOP_TC_ACTION_EN | + EOP_TC_WB_ACTION_EN | + EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | + EVENT_INDEX(5))); + amdgpu_ring_write(ring, addr & 0xfffffffc); + amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | + DATA_SEL(1) | INT_SEL(0)); + amdgpu_ring_write(ring, lower_32_bits(seq - 1)); + amdgpu_ring_write(ring, upper_32_bits(seq - 1)); + + /* Then send the real EOP event down the pipe: + * EVENT_WRITE_EOP - flush caches, send int */ amdgpu_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); amdgpu_ring_write(ring, (EOP_TCL1_ACTION_EN | EOP_TC_ACTION_EN | @@ -6926,7 +6904,7 @@ 5 + /* COND_EXEC */ 7 + /* PIPELINE_SYNC */ VI_FLUSH_GPU_TLB_NUM_WREG * 5 + 9 + /* VM_FLUSH */ - 8 + /* FENCE for VM_FLUSH */ + 12 + /* FENCE for VM_FLUSH */ 20 + /* GDS switch */ 4 + /* double SWITCH_BUFFER, the first COND_EXEC jump to the place just @@ -6938,7 +6916,7 @@ 31 + /* DE_META */ 3 + /* CNTX_CTRL */ 5 + /* HDP_INVL */ - 8 + 8 + /* FENCE x2 */ + 12 + 12 + /* FENCE x2 */ 2, /* SWITCH_BUFFER */ .emit_ib_size = 4, /* gfx_v8_0_ring_emit_ib_gfx */ .emit_ib = gfx_v8_0_ring_emit_ib_gfx, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -107,10 +107,6 @@ MODULE_FIRMWARE("amdgpu/raven2_rlc.bin"); MODULE_FIRMWARE("amdgpu/raven_kicker_rlc.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_mec.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_mec2.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_rlc.bin"); - MODULE_FIRMWARE("amdgpu/renoir_ce.bin"); MODULE_FIRMWARE("amdgpu/renoir_pfp.bin"); MODULE_FIRMWARE("amdgpu/renoir_me.bin"); @@ -1026,6 +1022,8 @@ adev->gfx.mec_fw_write_wait = true; break; default: + adev->gfx.me_fw_write_wait = true; + adev->gfx.mec_fw_write_wait = true; break; } } @@ -1038,17 +1036,10 @@ case CHIP_VEGA20: break; case CHIP_RAVEN: - /* Disable GFXOFF on original raven. There are combinations - * of sbios and platforms that are not stable. - */ - if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)) - adev->pm.pp_feature &= ~PP_GFXOFF_MASK; - else if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) - &&((adev->gfx.rlc_fw_version != 106 && - adev->gfx.rlc_fw_version < 531) || - (adev->gfx.rlc_fw_version == 53815) || - (adev->gfx.rlc_feature_version < 1) || - !adev->gfx.rlc.is_rlc_v2_1)) + if (!(adev->rev_id >= 0x8 || + adev->pdev->device == 0x15d8) && + (adev->pm.fw_version < 0x41e2b || /* not raven1 fresh */ + !adev->gfx.rlc.is_rlc_v2_1)) /* without rlc save restore ucodes */ adev->pm.pp_feature &= ~PP_GFXOFF_MASK; if (adev->pm.pp_feature & PP_GFXOFF_MASK) @@ -1680,39 +1671,6 @@ return 0; } -static int gfx_v9_0_csb_vram_pin(struct amdgpu_device *adev) -{ - int r; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, false); - if (unlikely(r != 0)) - return r; - - r = amdgpu_bo_pin(adev->gfx.rlc.clear_state_obj, - AMDGPU_GEM_DOMAIN_VRAM); - if (!r) - adev->gfx.rlc.clear_state_gpu_addr = - amdgpu_bo_gpu_offset(adev->gfx.rlc.clear_state_obj); - - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - - return r; -} - -static void gfx_v9_0_csb_vram_unpin(struct amdgpu_device *adev) -{ - int r; - - if (!adev->gfx.rlc.clear_state_obj) - return; - - r = amdgpu_bo_reserve(adev->gfx.rlc.clear_state_obj, true); - if (likely(r == 0)) { - amdgpu_bo_unpin(adev->gfx.rlc.clear_state_obj); - amdgpu_bo_unreserve(adev->gfx.rlc.clear_state_obj); - } -} - static void gfx_v9_0_mec_fini(struct amdgpu_device *adev) { amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL); @@ -2510,7 +2468,8 @@ gfx_v9_0_tiling_mode_table_init(adev); - gfx_v9_0_setup_rb(adev); + if (adev->gfx.num_gfx_rings) + gfx_v9_0_setup_rb(adev); gfx_v9_0_get_cu_info(adev, &adev->gfx.cu_info); adev->gfx.config.db_debug2 = RREG32_SOC15(GC, 0, mmDB_DEBUG2); @@ -2601,6 +2560,7 @@ static void gfx_v9_0_init_csb(struct amdgpu_device *adev) { + adev->gfx.rlc.funcs->get_csb_buffer(adev, adev->gfx.rlc.cs_ptr); /* csib */ WREG32_RLC(SOC15_REG_OFFSET(GC, 0, mmRLC_CSIB_ADDR_HI), adev->gfx.rlc.clear_state_gpu_addr >> 32); @@ -2930,7 +2890,10 @@ * And it's needed by gfxoff feature. */ if (adev->gfx.rlc.is_rlc_v2_1) { - gfx_v9_1_init_rlc_save_restore_list(adev); + if (adev->asic_type == CHIP_VEGA12 || + (adev->asic_type == CHIP_RAVEN && + adev->rev_id >= 8)) + gfx_v9_1_init_rlc_save_restore_list(adev); gfx_v9_0_enable_save_restore_machine(adev); } @@ -2940,8 +2903,8 @@ AMD_PG_SUPPORT_CP | AMD_PG_SUPPORT_GDS | AMD_PG_SUPPORT_RLC_SMU_HS)) { - WREG32(mmRLC_JUMP_TABLE_RESTORE, - adev->gfx.rlc.cp_table_gpu_addr >> 8); + WREG32_SOC15(GC, 0, mmRLC_JUMP_TABLE_RESTORE, + adev->gfx.rlc.cp_table_gpu_addr >> 8); gfx_v9_0_init_gfx_power_gating(adev); } } @@ -3760,6 +3723,7 @@ /* reset ring buffer */ ring->wptr = 0; + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], 0); amdgpu_ring_clear_ring(ring); } else { amdgpu_ring_clear_ring(ring); @@ -3780,8 +3744,10 @@ return r; r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); - if (unlikely(r != 0)) + if (unlikely(r != 0)) { + amdgpu_bo_unreserve(ring->mqd_obj); return r; + } gfx_v9_0_kiq_init_queue(ring); amdgpu_bo_kunmap(ring->mqd_obj); @@ -3889,10 +3855,6 @@ gfx_v9_0_constants_init(adev); - r = gfx_v9_0_csb_vram_pin(adev); - if (r) - return r; - r = adev->gfx.rlc.funcs->resume(adev); if (r) return r; @@ -3944,7 +3906,8 @@ { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0); + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX)) + amdgpu_irq_put(adev, &adev->gfx.cp_ecc_error_irq, 0); amdgpu_irq_put(adev, &adev->gfx.priv_reg_irq, 0); amdgpu_irq_put(adev, &adev->gfx.priv_inst_irq, 0); @@ -3978,8 +3941,6 @@ gfx_v9_0_cp_enable(adev, false); adev->gfx.rlc.funcs->stop(adev); - gfx_v9_0_csb_vram_unpin(adev); - return 0; } @@ -4084,11 +4045,13 @@ { uint64_t clock; + amdgpu_gfx_off_ctrl(adev, false); mutex_lock(&adev->gfx.gpu_clock_mutex); WREG32_SOC15(GC, 0, mmRLC_CAPTURE_GPU_CLOCK_COUNT, 1); clock = (uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_LSB) | ((uint64_t)RREG32_SOC15(GC, 0, mmRLC_GPU_CLOCK_COUNT_MSB) << 32ULL); mutex_unlock(&adev->gfx.gpu_clock_mutex); + amdgpu_gfx_off_ctrl(adev, true); return clock; } @@ -4698,7 +4661,7 @@ amdgpu_gfx_rlc_enter_safe_mode(adev); /* Enable 3D CGCG/CGLS */ - if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG)) { + if (enable) { /* write cmd to clear cgcg/cgls ov */ def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); /* unset CGCG override */ @@ -4710,8 +4673,12 @@ /* enable 3Dcgcg FSM(0x0000363f) */ def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D); - data = (0x36 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | - RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK; + if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG) + data = (0x36 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | + RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK; + else + data = 0x0 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT; + if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGLS) data |= (0x000F << RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY__SHIFT) | RLC_CGCG_CGLS_CTRL_3D__CGLS_EN_MASK; @@ -4838,10 +4805,9 @@ switch (adev->asic_type) { case CHIP_RAVEN: case CHIP_RENOIR: - if (!enable) { + if (!enable) amdgpu_gfx_off_ctrl(adev, false); - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); - } + if (adev->pg_flags & AMD_PG_SUPPORT_RLC_SMU_HS) { gfx_v9_0_enable_sck_slow_down_on_power_up(adev, true); gfx_v9_0_enable_sck_slow_down_on_power_down(adev, true); @@ -4867,12 +4833,7 @@ amdgpu_gfx_off_ctrl(adev, true); break; case CHIP_VEGA12: - if (!enable) { - amdgpu_gfx_off_ctrl(adev, false); - cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); - } else { - amdgpu_gfx_off_ctrl(adev, true); - } + amdgpu_gfx_off_ctrl(adev, enable); break; default: break; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -365,6 +365,8 @@ hub->ctx0_ptb_addr_hi32 = SOC15_REG_OFFSET(GC, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); + hub->vm_inv_eng0_sem = + SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_SEM); hub->vm_inv_eng0_req = SOC15_REG_OFFSET(GC, 0, mmVM_INVALIDATE_ENG0_REQ); hub->vm_inv_eng0_ack = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c @@ -350,6 +350,8 @@ hub->ctx0_ptb_addr_hi32 = SOC15_REG_OFFSET(GC, 0, mmGCVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); + hub->vm_inv_eng0_sem = + SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_SEM); hub->vm_inv_eng0_req = SOC15_REG_OFFSET(GC, 0, mmGCVM_INVALIDATE_ENG0_REQ); hub->vm_inv_eng0_ack = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -230,12 +230,36 @@ unsigned int vmhub, uint32_t flush_type) { struct amdgpu_vmhub *hub = &adev->vmhub[vmhub]; - u32 tmp = gmc_v10_0_get_invalidate_req(vmid, flush_type); + u32 inv_req = gmc_v10_0_get_invalidate_req(vmid, flush_type); + u32 tmp; /* Use register 17 for GART */ const unsigned eng = 17; unsigned int i; - WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); + spin_lock(&adev->gmc.invalidate_lock); + /* + * It may lose gpuvm invalidate acknowldege state across power-gating + * off cycle, add semaphore acquire before invalidation and semaphore + * release after invalidation to avoid entering power gated state + * to WA the Issue + */ + + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (vmhub == AMDGPU_MMHUB_0 || + vmhub == AMDGPU_MMHUB_1) { + for (i = 0; i < adev->usec_timeout; i++) { + /* a read return value of 1 means semaphore acuqire */ + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); + if (tmp & 0x1) + break; + udelay(1); + } + + if (i >= adev->usec_timeout) + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + + WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); /* * Issue a dummy read to wait for the ACK register to be cleared @@ -254,6 +278,17 @@ udelay(1); } + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (vmhub == AMDGPU_MMHUB_0 || + vmhub == AMDGPU_MMHUB_1) + /* + * add semaphore release after invalidation, + * write with 0 means semaphore release + */ + WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); + + spin_unlock(&adev->gmc.invalidate_lock); + if (i < adev->usec_timeout) return; @@ -338,6 +373,20 @@ uint32_t req = gmc_v10_0_get_invalidate_req(vmid, 0); unsigned eng = ring->vm_inv_eng; + /* + * It may lose gpuvm invalidate acknowldege state across power-gating + * off cycle, add semaphore acquire before invalidation and semaphore + * release after invalidation to avoid entering power gated state + * to WA the Issue + */ + + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || + ring->funcs->vmhub == AMDGPU_MMHUB_1) + /* a read return value of 1 means semaphore acuqire */ + amdgpu_ring_emit_reg_wait(ring, + hub->vm_inv_eng0_sem + eng, 0x1, 0x1); + amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), lower_32_bits(pd_addr)); @@ -348,6 +397,15 @@ hub->vm_inv_eng0_ack + eng, req, 1 << vmid); + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (ring->funcs->vmhub == AMDGPU_MMHUB_0 || + ring->funcs->vmhub == AMDGPU_MMHUB_1) + /* + * add semaphore release after invalidation, + * write with 0 means semaphore release + */ + amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); + return pd_addr; } @@ -845,6 +903,8 @@ { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + gmc_v10_0_gart_disable(adev); + if (amdgpu_sriov_vf(adev)) { /* full access mode, so don't touch any GMC register */ DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); @@ -852,7 +912,6 @@ } amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); - gmc_v10_0_gart_disable(adev); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -863,12 +863,12 @@ adev->gmc.mc_mask = 0xffffffffffULL; - r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); if (r) { dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n"); return r; } - adev->need_swiotlb = drm_need_swiotlb(44); + adev->need_swiotlb = drm_need_swiotlb(40); r = gmc_v6_0_init_microcode(adev); if (r) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -524,10 +524,10 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) { int r; + u32 tmp; adev->gmc.vram_width = amdgpu_atombios_get_vram_width(adev); if (!adev->gmc.vram_width) { - u32 tmp; int chansize, numchan; /* Get VRAM informations */ @@ -571,8 +571,15 @@ adev->gmc.vram_width = numchan * chansize; } /* size in MB on si */ - adev->gmc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; - adev->gmc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; + tmp = RREG32(mmCONFIG_MEMSIZE); + /* some boards may have garbage in the upper 16 bits */ + if (tmp & 0xffff0000) { + DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); + if (tmp & 0xffff) + tmp &= 0xffff; + } + adev->gmc.mc_vram_size = tmp * 1024ULL * 1024ULL; + adev->gmc.real_vram_size = adev->gmc.mc_vram_size; if (!(adev->flags & AMD_IS_APU)) { r = amdgpu_device_resize_fb_bar(adev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -448,6 +448,24 @@ return req; } +/** + * gmc_v9_0_use_invalidate_semaphore - judge whether to use semaphore + * + * @adev: amdgpu_device pointer + * @vmhub: vmhub type + * + */ +static bool gmc_v9_0_use_invalidate_semaphore(struct amdgpu_device *adev, + uint32_t vmhub) +{ + return ((vmhub == AMDGPU_MMHUB_0 || + vmhub == AMDGPU_MMHUB_1) && + (!amdgpu_sriov_vf(adev)) && + (!(adev->asic_type == CHIP_RAVEN && + adev->rev_id < 0x8 && + adev->pdev->device == 0x15d8))); +} + /* * GART * VMID 0 is the physical GPU addresses as used by the kernel. @@ -467,14 +485,15 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, uint32_t vmhub, uint32_t flush_type) { + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub); const unsigned eng = 17; - u32 j, tmp; + u32 j, inv_req, tmp; struct amdgpu_vmhub *hub; BUG_ON(vmhub >= adev->num_vmhubs); hub = &adev->vmhub[vmhub]; - tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type); + inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type); /* This is necessary for a HW workaround under SRIOV as well * as GFXOFF under bare metal @@ -485,13 +504,35 @@ uint32_t req = hub->vm_inv_eng0_req + eng; uint32_t ack = hub->vm_inv_eng0_ack + eng; - amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp, + amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req, 1 << vmid); return; } spin_lock(&adev->gmc.invalidate_lock); - WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp); + + /* + * It may lose gpuvm invalidate acknowldege state across power-gating + * off cycle, add semaphore acquire before invalidation and semaphore + * release after invalidation to avoid entering power gated state + * to WA the Issue + */ + + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (use_semaphore) { + for (j = 0; j < adev->usec_timeout; j++) { + /* a read return value of 1 means semaphore acuqire */ + tmp = RREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng); + if (tmp & 0x1) + break; + udelay(1); + } + + if (j >= adev->usec_timeout) + DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n"); + } + + WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req); /* * Issue a dummy read to wait for the ACK register to be cleared @@ -506,7 +547,17 @@ break; udelay(1); } + + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (use_semaphore) + /* + * add semaphore release after invalidation, + * write with 0 means semaphore release + */ + WREG32_NO_KIQ(hub->vm_inv_eng0_sem + eng, 0); + spin_unlock(&adev->gmc.invalidate_lock); + if (j < adev->usec_timeout) return; @@ -516,11 +567,25 @@ static uint64_t gmc_v9_0_emit_flush_gpu_tlb(struct amdgpu_ring *ring, unsigned vmid, uint64_t pd_addr) { + bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(ring->adev, ring->funcs->vmhub); struct amdgpu_device *adev = ring->adev; struct amdgpu_vmhub *hub = &adev->vmhub[ring->funcs->vmhub]; uint32_t req = gmc_v9_0_get_invalidate_req(vmid, 0); unsigned eng = ring->vm_inv_eng; + /* + * It may lose gpuvm invalidate acknowldege state across power-gating + * off cycle, add semaphore acquire before invalidation and semaphore + * release after invalidation to avoid entering power gated state + * to WA the Issue + */ + + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (use_semaphore) + /* a read return value of 1 means semaphore acuqire */ + amdgpu_ring_emit_reg_wait(ring, + hub->vm_inv_eng0_sem + eng, 0x1, 0x1); + amdgpu_ring_emit_wreg(ring, hub->ctx0_ptb_addr_lo32 + (2 * vmid), lower_32_bits(pd_addr)); @@ -531,6 +596,14 @@ hub->vm_inv_eng0_ack + eng, req, 1 << vmid); + /* TODO: It needs to continue working on debugging with semaphore for GFXHUB as well. */ + if (use_semaphore) + /* + * add semaphore release after invalidation, + * write with 0 means semaphore release + */ + amdgpu_ring_emit_wreg(ring, hub->vm_inv_eng0_sem + eng, 0); + return pd_addr; } @@ -1310,6 +1383,19 @@ } /** + * gmc_v9_0_restore_registers - restores regs + * + * @adev: amdgpu_device pointer + * + * This restores register values, saved at suspend. + */ +static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) +{ + if (adev->asic_type == CHIP_RAVEN) + WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); +} + +/** * gmc_v9_0_gart_enable - gart enable * * @adev: amdgpu_device pointer @@ -1406,6 +1492,20 @@ } /** + * gmc_v9_0_save_registers - saves regs + * + * @adev: amdgpu_device pointer + * + * This saves potential register values that should be + * restored upon resume + */ +static void gmc_v9_0_save_registers(struct amdgpu_device *adev) +{ + if (adev->asic_type == CHIP_RAVEN) + adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); +} + +/** * gmc_v9_0_gart_disable - gart disable * * @adev: amdgpu_device pointer @@ -1426,24 +1526,31 @@ { struct amdgpu_device *adev = (struct amdgpu_device *)handle; + gmc_v9_0_gart_disable(adev); + if (amdgpu_sriov_vf(adev)) { /* full access mode, so don't touch any GMC register */ DRM_DEBUG("For SRIOV client, shouldn't do anything.\n"); return 0; } - amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); - gmc_v9_0_gart_disable(adev); return 0; } static int gmc_v9_0_suspend(void *handle) { + int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - return gmc_v9_0_hw_fini(adev); + r = gmc_v9_0_hw_fini(adev); + if (r) + return r; + + gmc_v9_0_save_registers(adev); + + return 0; } static int gmc_v9_0_resume(void *handle) @@ -1451,6 +1558,7 @@ int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + gmc_v9_0_restore_registers(adev); r = gmc_v9_0_hw_init(adev); if (r) return r; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -193,19 +193,34 @@ wptr = le32_to_cpu(*ih->wptr_cpu); - if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { - wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", - wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); - ih->rptr = (wptr + 16) & ih->ptr_mask; - tmp = RREG32(mmIH_RB_CNTL); - tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); - WREG32(mmIH_RB_CNTL, tmp); - } + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + /* Double check that the overflow wasn't already cleared. */ + wptr = RREG32(mmIH_RB_WPTR); + + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); + /* When a ring buffer overflow happen start parsing interrupt + * from the last not overwritten vector (wptr + 16). Hopefully + * this should allow us to catchup. + */ + dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); + ih->rptr = (wptr + 16) & ih->ptr_mask; + tmp = RREG32(mmIH_RB_CNTL); + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); + WREG32(mmIH_RB_CNTL, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); + WREG32(mmIH_RB_CNTL, tmp); + +out: return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/kv_dpm.c @@ -163,6 +163,8 @@ for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { if (table[i].ulSupportedSCLK != 0) { + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) + continue; vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = table[i].usVoltageID; vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = @@ -1609,19 +1611,7 @@ static u8 kv_get_acp_boot_level(struct amdgpu_device *adev) { - u8 i; - struct amdgpu_clock_voltage_dependency_table *table = - &adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table; - - for (i = 0; i < table->count; i++) { - if (table->entries[i].clk >= 0) /* XXX */ - break; - } - - if (i >= table->count) - i = table->count - 1; - - return i; + return 0; } static void kv_update_acp_boot_level(struct amdgpu_device *adev) @@ -2745,10 +2735,8 @@ non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(adev->pm.dpm.ps); + if (ps == NULL) return -ENOMEM; - } adev->pm.dpm.ps[i].ps_priv = ps; k = 0; idx = (u8 *)&power_state->v2.clockInfoIndex[0]; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/mes_v10_1.c @@ -29,8 +29,6 @@ #include "gc/gc_10_1_0_offset.h" #include "gc/gc_10_1_0_sh_mask.h" -MODULE_FIRMWARE("amdgpu/navi10_mes.bin"); - static int mes_v10_1_add_hw_queue(struct amdgpu_mes *mes, struct mes_add_queue_input *input) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -182,6 +182,7 @@ tmp = REG_SET_FIELD(tmp, VM_L2_CNTL2, INVALIDATE_L2_CACHE, 1); WREG32_SOC15(MMHUB, 0, mmVM_L2_CNTL2, tmp); + tmp = mmVM_L2_CNTL3_DEFAULT; if (adev->gmc.translate_further) { tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, BANK_SELECT, 12); tmp = REG_SET_FIELD(tmp, VM_L2_CNTL3, @@ -418,6 +419,8 @@ hub->ctx0_ptb_addr_hi32 = SOC15_REG_OFFSET(MMHUB, 0, mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); + hub->vm_inv_eng0_sem = + SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_SEM); hub->vm_inv_eng0_req = SOC15_REG_OFFSET(MMHUB, 0, mmVM_INVALIDATE_ENG0_REQ); hub->vm_inv_eng0_ack = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c @@ -341,6 +341,8 @@ hub->ctx0_ptb_addr_hi32 = SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32); + hub->vm_inv_eng0_sem = + SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_SEM); hub->vm_inv_eng0_req = SOC15_REG_OFFSET(MMHUB, 0, mmMMVM_INVALIDATE_ENG0_REQ); hub->vm_inv_eng0_ack = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c @@ -502,6 +502,10 @@ SOC15_REG_OFFSET(MMHUB, 0, mmVML2VC0_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR_HI32) + i * MMHUB_INSTANCE_REGISTER_OFFSET; + hub[i]->vm_inv_eng0_sem = + SOC15_REG_OFFSET(MMHUB, 0, + mmVML2VC0_VM_INVALIDATE_ENG0_SEM) + + i * MMHUB_INSTANCE_REGISTER_OFFSET; hub[i]->vm_inv_eng0_req = SOC15_REG_OFFSET(MMHUB, 0, mmVML2VC0_VM_INVALIDATE_ENG0_REQ) + --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/navi10_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/navi10_ih.c @@ -237,6 +237,12 @@ tmp = RREG32_NO_KIQ(reg); tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); WREG32_NO_KIQ(reg, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); + WREG32_NO_KIQ(reg, tmp); out: return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/navi10_sdma_pkt_open.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/navi10_sdma_pkt_open.h @@ -73,6 +73,22 @@ #define SDMA_OP_AQL_COPY 0 #define SDMA_OP_AQL_BARRIER_OR 0 +#define SDMA_GCR_RANGE_IS_PA (1 << 18) +#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16) +#define SDMA_GCR_GL2_WB (1 << 15) +#define SDMA_GCR_GL2_INV (1 << 14) +#define SDMA_GCR_GL2_DISCARD (1 << 13) +#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11) +#define SDMA_GCR_GL2_US (1 << 10) +#define SDMA_GCR_GL1_INV (1 << 9) +#define SDMA_GCR_GLV_INV (1 << 8) +#define SDMA_GCR_GLK_INV (1 << 7) +#define SDMA_GCR_GLK_WB (1 << 6) +#define SDMA_GCR_GLM_INV (1 << 5) +#define SDMA_GCR_GLM_WB (1 << 4) +#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2) +#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0) + /*define for op field*/ #define SDMA_PKT_HEADER_op_offset 0 #define SDMA_PKT_HEADER_op_mask 0x000000FF --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/nv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/nv.c @@ -660,6 +660,12 @@ adev->pg_flags = AMD_PG_SUPPORT_VCN | AMD_PG_SUPPORT_VCN_DPG | AMD_PG_SUPPORT_ATHUB; + /* guest vm gets 0xffffffff when reading RCC_DEV0_EPF0_STRAP0, + * as a consequence, the rev_id and external_rev_id are wrong. + * workaround it by hardcoding rev_id to 0 (default value). + */ + if (amdgpu_sriov_vf(adev)) + adev->rev_id = 0; adev->external_rev_id = adev->rev_id + 0xa; break; default: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -44,7 +44,7 @@ GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */ GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */ GFX_CTRL_CMD_ID_GBR_IH_SET = 0x00080000, /* set Gbr IH_RB_CNTL registers */ - GFX_CTRL_CMD_ID_CONSUME_CMD = 0x000A0000, /* send interrupt to psp for updating write pointer of vf */ + GFX_CTRL_CMD_ID_CONSUME_CMD = 0x00090000, /* send interrupt to psp for updating write pointer of vf */ GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */ GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -40,15 +40,10 @@ MODULE_FIRMWARE("amdgpu/vega20_sos.bin"); MODULE_FIRMWARE("amdgpu/vega20_asd.bin"); -MODULE_FIRMWARE("amdgpu/vega20_ta.bin"); MODULE_FIRMWARE("amdgpu/navi10_sos.bin"); MODULE_FIRMWARE("amdgpu/navi10_asd.bin"); MODULE_FIRMWARE("amdgpu/navi14_sos.bin"); MODULE_FIRMWARE("amdgpu/navi14_asd.bin"); -MODULE_FIRMWARE("amdgpu/navi12_sos.bin"); -MODULE_FIRMWARE("amdgpu/navi12_asd.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_sos.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_asd.bin"); /* address block */ #define smnMP1_FIRMWARE_FLAGS 0x3010024 @@ -398,6 +393,34 @@ return false; } +static int psp_v11_0_ring_stop(struct psp_context *psp, + enum psp_ring_type ring_type) +{ + int ret = 0; + struct amdgpu_device *adev = psp->adev; + + /* Write the ring destroy command*/ + if (psp_v11_0_support_vmr_ring(psp)) + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, + GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); + else + WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, + GFX_CTRL_CMD_ID_DESTROY_RINGS); + + /* there might be handshake issue with hardware which needs delay */ + mdelay(20); + + /* Wait for response flag (bit 31) */ + if (psp_v11_0_support_vmr_ring(psp)) + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), + 0x80000000, 0x80000000, false); + else + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), + 0x80000000, 0x80000000, false); + + return ret; +} + static int psp_v11_0_ring_create(struct psp_context *psp, enum psp_ring_type ring_type) { @@ -407,6 +430,12 @@ struct amdgpu_device *adev = psp->adev; if (psp_v11_0_support_vmr_ring(psp)) { + ret = psp_v11_0_ring_stop(psp, ring_type); + if (ret) { + DRM_ERROR("psp_v11_0_ring_stop_sriov failed!\n"); + return ret; + } + /* Write low address of the ring to C2PMSG_102 */ psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, psp_ring_reg); @@ -451,33 +480,6 @@ return ret; } -static int psp_v11_0_ring_stop(struct psp_context *psp, - enum psp_ring_type ring_type) -{ - int ret = 0; - struct amdgpu_device *adev = psp->adev; - - /* Write the ring destroy command*/ - if (psp_v11_0_support_vmr_ring(psp)) - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, - GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING); - else - WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_64, - GFX_CTRL_CMD_ID_DESTROY_RINGS); - - /* there might be handshake issue with hardware which needs delay */ - mdelay(20); - - /* Wait for response flag (bit 31) */ - if (psp_v11_0_support_vmr_ring(psp)) - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_101), - 0x80000000, 0x80000000, false); - else - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, mmMP0_SMN_C2PMSG_64), - 0x80000000, 0x80000000, false); - - return ret; -} static int psp_v11_0_ring_destroy(struct psp_context *psp, enum psp_ring_type ring_type) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -255,7 +255,7 @@ unsigned vmid = AMDGPU_JOB_GET_VMID(job); /* IB packet must end on a 8 DW boundary */ - sdma_v2_4_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); + sdma_v2_4_ring_insert_nop(ring, (2 - lower_32_bits(ring->wptr)) & 7); amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) | SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf)); @@ -750,7 +750,7 @@ u32 pad_count; int i; - pad_count = (8 - (ib->length_dw & 0x7)) % 8; + pad_count = (-ib->length_dw) & 7; for (i = 0; i < pad_count; i++) if (sdma && sdma->burst_nop && (i == 0)) ib->ptr[ib->length_dw++] = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -429,7 +429,7 @@ unsigned vmid = AMDGPU_JOB_GET_VMID(job); /* IB packet must end on a 8 DW boundary */ - sdma_v3_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); + sdma_v3_0_ring_insert_nop(ring, (2 - lower_32_bits(ring->wptr)) & 7); amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) | SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf)); @@ -1021,7 +1021,7 @@ u32 pad_count; int i; - pad_count = (8 - (ib->length_dw & 0x7)) % 8; + pad_count = (-ib->length_dw) & 7; for (i = 0; i < pad_count; i++) if (sdma && sdma->burst_nop && (i == 0)) ib->ptr[ib->length_dw++] = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -67,7 +67,6 @@ MODULE_FIRMWARE("amdgpu/raven_sdma.bin"); MODULE_FIRMWARE("amdgpu/picasso_sdma.bin"); MODULE_FIRMWARE("amdgpu/raven2_sdma.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_sdma.bin"); MODULE_FIRMWARE("amdgpu/renoir_sdma.bin"); #define SDMA0_POWER_CNTL__ON_OFF_CONDITION_HOLD_TIME_MASK 0x000000F8L @@ -698,7 +697,7 @@ unsigned vmid = AMDGPU_JOB_GET_VMID(job); /* IB packet must end on a 8 DW boundary */ - sdma_v4_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); + sdma_v4_0_ring_insert_nop(ring, (2 - lower_32_bits(ring->wptr)) & 7); amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) | SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf)); @@ -1579,7 +1578,7 @@ u32 pad_count; int i; - pad_count = (8 - (ib->length_dw & 0x7)) % 8; + pad_count = (-ib->length_dw) & 7; for (i = 0; i < pad_count; i++) if (sdma && sdma->burst_nop && (i == 0)) ib->ptr[ib->length_dw++] = @@ -1911,9 +1910,11 @@ if (amdgpu_sriov_vf(adev)) return 0; - for (i = 0; i < adev->sdma.num_instances; i++) { - amdgpu_irq_put(adev, &adev->sdma.ecc_irq, - AMDGPU_SDMA_IRQ_INSTANCE0 + i); + if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) { + for (i = 0; i < adev->sdma.num_instances; i++) { + amdgpu_irq_put(adev, &adev->sdma.ecc_irq, + AMDGPU_SDMA_IRQ_INSTANCE0 + i); + } } sdma_v4_0_ctx_switch_enable(adev, false); @@ -2001,10 +2002,13 @@ struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { - uint32_t instance; + int instance; DRM_DEBUG("IH: SDMA trap\n"); instance = sdma_v4_0_irq_id_to_seq(entry->client_id); + if (instance < 0) + return instance; + switch (entry->ring_id) { case 0: amdgpu_fence_process(&adev->sdma.instance[instance].ring); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -48,9 +48,6 @@ MODULE_FIRMWARE("amdgpu/navi14_sdma.bin"); MODULE_FIRMWARE("amdgpu/navi14_sdma1.bin"); -MODULE_FIRMWARE("amdgpu/navi12_sdma.bin"); -MODULE_FIRMWARE("amdgpu/navi12_sdma1.bin"); - #define SDMA1_REG_OFFSET 0x600 #define SDMA0_HYP_DEC_REG_START 0x5880 #define SDMA0_HYP_DEC_REG_END 0x5893 @@ -100,6 +97,10 @@ static const struct soc15_reg_golden golden_settings_sdma_nv12[] = { SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GB_ADDR_CONFIG, 0x001877ff, 0x00000044), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x001877ff, 0x00000044), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GB_ADDR_CONFIG, 0x001877ff, 0x00000044), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x001877ff, 0x00000044), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), }; @@ -286,30 +287,20 @@ static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - u64 *wptr = NULL; - uint64_t local_wptr = 0; + u64 wptr; if (ring->use_doorbell) { /* XXX check if swapping is necessary on BE */ - wptr = ((u64 *)&adev->wb.wb[ring->wptr_offs]); - DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", *wptr); - *wptr = (*wptr) >> 2; - DRM_DEBUG("wptr/doorbell after shift == 0x%016llx\n", *wptr); + wptr = READ_ONCE(*((u64 *)&adev->wb.wb[ring->wptr_offs])); + DRM_DEBUG("wptr/doorbell before shift == 0x%016llx\n", wptr); } else { - u32 lowbit, highbit; - - wptr = &local_wptr; - lowbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)) >> 2; - highbit = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)) >> 2; - - DRM_DEBUG("wptr [%i]high== 0x%08x low==0x%08x\n", - ring->me, highbit, lowbit); - *wptr = highbit; - *wptr = (*wptr) << 32; - *wptr |= lowbit; + wptr = RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI)); + wptr = wptr << 32; + wptr |= RREG32(sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR)); + DRM_DEBUG("wptr before shift [%i] wptr == 0x%016llx\n", ring->me, wptr); } - return *wptr; + return wptr >> 2; } /** @@ -382,8 +373,27 @@ unsigned vmid = AMDGPU_JOB_GET_VMID(job); uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); - /* IB packet must end on a 8 DW boundary */ - sdma_v5_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8); + /* Invalidate L2, because if we don't do it, we might get stale cache + * lines from previous IBs. + */ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ)); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV | + SDMA_GCR_GL2_WB | + SDMA_GCR_GLM_INV | + SDMA_GCR_GLM_WB) << 16); + amdgpu_ring_write(ring, 0xffffff80); + amdgpu_ring_write(ring, 0xffff); + + /* An IB packet must end on a 8 DW boundary--the next dword + * must be on a 8-dword boundary. Our IB packet below is 6 + * dwords long, thus add x number of NOPs, such that, in + * modular arithmetic, + * wptr + 6 + x = 8k, k >= 0, which in C is, + * (wptr + 6 + x) % 8 = 0. + * The expression below, is a solution of x. + */ + sdma_v5_0_ring_insert_nop(ring, (2 - lower_32_bits(ring->wptr)) & 7); amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) | SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf)); @@ -1086,10 +1096,10 @@ } /** - * sdma_v5_0_ring_pad_ib - pad the IB to the required number of dw - * + * sdma_v5_0_ring_pad_ib - pad the IB * @ib: indirect buffer to fill with padding * + * Pad the IB with NOPs to a boundary multiple of 8. */ static void sdma_v5_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { @@ -1097,7 +1107,7 @@ u32 pad_count; int i; - pad_count = (8 - (ib->length_dw & 0x7)) % 8; + pad_count = (-ib->length_dw) & 0x7; for (i = 0; i < pad_count; i++) if (sdma && sdma->burst_nop && (i == 0)) ib->ptr[ib->length_dw++] = @@ -1254,8 +1264,12 @@ struct amdgpu_device *adev = (struct amdgpu_device *)handle; int i; - for (i = 0; i < adev->sdma.num_instances; i++) + for (i = 0; i < adev->sdma.num_instances; i++) { + if (adev->sdma.instance[i].fw != NULL) + release_firmware(adev->sdma.instance[i].fw); + amdgpu_ring_fini(&adev->sdma.instance[i].ring); + } return 0; } @@ -1600,7 +1614,7 @@ SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + 10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ - .emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */ + .emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */ .emit_ib = sdma_v5_0_ring_emit_ib, .emit_fence = sdma_v5_0_ring_emit_fence, .emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/si.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/si.c @@ -1633,7 +1633,6 @@ static void si_pcie_gen3_enable(struct amdgpu_device *adev) { struct pci_dev *root = adev->pdev->bus->self; - int bridge_pos, gpu_pos; u32 speed_cntl, current_data_rate; int i; u16 tmp16; @@ -1668,12 +1667,7 @@ DRM_INFO("enabling PCIE gen 2 link speeds, disable with amdgpu.pcie_gen2=0\n"); } - bridge_pos = pci_pcie_cap(root); - if (!bridge_pos) - return; - - gpu_pos = pci_pcie_cap(adev->pdev); - if (!gpu_pos) + if (!pci_is_pcie(root) || !pci_is_pcie(adev->pdev)) return; if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) { @@ -1682,14 +1676,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -1706,15 +1694,23 @@ } for (i = 0; i < 10; i++) { - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16); + pcie_capability_read_word(adev->pdev, + PCI_EXP_DEVSTA, + &tmp16); if (tmp16 & PCI_EXP_DEVSTA_TRPND) break; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2); + pcie_capability_read_word(root, PCI_EXP_LNKCTL, + &bridge_cfg); + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL, + &gpu_cfg); + + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &bridge_cfg2); + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL2, + &gpu_cfg2); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp |= LC_SET_QUIESCE; @@ -1726,25 +1722,37 @@ mdelay(100); - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); - - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16); - - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); + + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(root, + PCI_EXP_LNKCTL2, + tmp16); + + pcie_capability_read_word(adev->pdev, + PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(adev->pdev, + PCI_EXP_LNKCTL2, + tmp16); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -1757,15 +1765,16 @@ speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pci_read_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~0xf; + pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL2, &tmp16); + tmp16 &= ~PCI_EXP_LNKCTL2_TLS; + if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) - tmp16 |= 3; + tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) - tmp16 |= 2; + tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else - tmp16 |= 1; - pci_write_config_word(adev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ + pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL2, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/si_dpm.c @@ -7250,17 +7250,15 @@ if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; - for (i = 0; i < state_array->ucNumEntries; i++) { + for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) { u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(adev->pm.dpm.ps); + if (ps == NULL) return -ENOMEM; - } adev->pm.dpm.ps[i].ps_priv = ps; si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i], non_clock_info, @@ -7282,8 +7280,8 @@ k++; } power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + adev->pm.dpm.num_ps++; } - adev->pm.dpm.num_ps = state_array->ucNumEntries; /* fill in the vce power states */ for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) { @@ -7351,10 +7349,9 @@ kcalloc(4, sizeof(struct amdgpu_clock_voltage_dependency_entry), GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) return -ENOMEM; - } + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/si_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/si_ih.c @@ -64,7 +64,8 @@ u32 interrupt_cntl, ih_cntl, ih_rb_cntl; si_ih_disable_interrupts(adev); - WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8); + /* set dummy read address to dummy page address */ + WREG32(INTERRUPT_CNTL2, adev->dummy_page_addr >> 8); interrupt_cntl = RREG32(INTERRUPT_CNTL); interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; @@ -116,6 +117,12 @@ tmp = RREG32(IH_RB_CNTL); tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; WREG32(IH_RB_CNTL, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp &= ~IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; + WREG32(IH_RB_CNTL, tmp); } return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/soc15.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -84,6 +84,13 @@ #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L #define mmHDP_MEM_POWER_CTRL_BASE_IDX 0 + +/* for Vega20/arcturus regiter offset change */ +#define mmROM_INDEX_VG20 0x00e4 +#define mmROM_INDEX_VG20_BASE_IDX 0 +#define mmROM_DATA_VG20 0x00e5 +#define mmROM_DATA_VG20_BASE_IDX 0 + /* * Indirect registers accessor */ @@ -267,7 +274,14 @@ static u32 soc15_get_xclk(struct amdgpu_device *adev) { - return adev->clock.spll.reference_freq; + u32 reference_clock = adev->clock.spll.reference_freq; + + if (adev->asic_type == CHIP_RENOIR) + return 10000; + if (adev->asic_type == CHIP_RAVEN) + return reference_clock / 4; + + return reference_clock; } @@ -299,6 +313,8 @@ { u32 *dw_ptr; u32 i, length_dw; + uint32_t rom_index_offset; + uint32_t rom_data_offset; if (bios == NULL) return false; @@ -311,11 +327,23 @@ dw_ptr = (u32 *)bios; length_dw = ALIGN(length_bytes, 4) / 4; + switch (adev->asic_type) { + case CHIP_VEGA20: + case CHIP_ARCTURUS: + rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX_VG20); + rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA_VG20); + break; + default: + rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX); + rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA); + break; + } + /* set rom index to 0 */ - WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX), 0); + WREG32(rom_index_offset, 0); /* read out the rom data */ for (i = 0; i < length_dw; i++) - dw_ptr[i] = RREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA)); + dw_ptr[i] = RREG32(rom_data_offset); return true; } @@ -1104,7 +1132,6 @@ adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_CP_LS | - AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | @@ -1116,16 +1143,17 @@ AMD_CG_SUPPORT_SDMA_MGCG | AMD_CG_SUPPORT_SDMA_LS; + /* + * MMHUB PG needs to be disabled for Picasso for + * stability reasons. + */ adev->pg_flags = AMD_PG_SUPPORT_SDMA | - AMD_PG_SUPPORT_MMHUB | - AMD_PG_SUPPORT_VCN | - AMD_PG_SUPPORT_VCN_DPG; + AMD_PG_SUPPORT_VCN; } else { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | AMD_CG_SUPPORT_GFX_RLC_LS | AMD_CG_SUPPORT_GFX_CP_LS | - AMD_CG_SUPPORT_GFX_3D_CGCG | AMD_CG_SUPPORT_GFX_3D_CGLS | AMD_CG_SUPPORT_GFX_CGCG | AMD_CG_SUPPORT_GFX_CGLS | --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/soc15.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/soc15.h @@ -28,8 +28,8 @@ #include "nbio_v7_0.h" #include "nbio_v7_4.h" -#define SOC15_FLUSH_GPU_TLB_NUM_WREG 4 -#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 1 +#define SOC15_FLUSH_GPU_TLB_NUM_WREG 6 +#define SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT 3 extern const struct amd_ip_funcs soc15_common_ip_funcs; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -52,6 +52,7 @@ uint32_t old_ = 0; \ uint32_t tmp_ = RREG32(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg); \ uint32_t loop = adev->usec_timeout; \ + ret = 0; \ while ((tmp_ & (mask)) != (expected_value)) { \ if (old_ != tmp_) { \ loop = adev->usec_timeout; \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/tonga_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/tonga_ih.c @@ -195,19 +195,36 @@ wptr = le32_to_cpu(*ih->wptr_cpu); - if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) { - wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); - /* When a ring buffer overflow happen start parsing interrupt - * from the last not overwritten vector (wptr + 16). Hopefully - * this should allow us to catchup. - */ - dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", - wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); - ih->rptr = (wptr + 16) & ih->ptr_mask; - tmp = RREG32(mmIH_RB_CNTL); - tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); - WREG32(mmIH_RB_CNTL, tmp); - } + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + /* Double check that the overflow wasn't already cleared. */ + wptr = RREG32(mmIH_RB_WPTR); + + if (!REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) + goto out; + + wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0); + + /* When a ring buffer overflow happen start parsing interrupt + * from the last not overwritten vector (wptr + 16). Hopefully + * this should allow us to catchup. + */ + + dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); + ih->rptr = (wptr + 16) & ih->ptr_mask; + tmp = RREG32(mmIH_RB_CNTL); + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); + WREG32(mmIH_RB_CNTL, tmp); + + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); + WREG32(mmIH_RB_CNTL, tmp); + +out: return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -354,6 +354,7 @@ error: dma_fence_put(fence); + amdgpu_bo_unpin(bo); amdgpu_bo_unreserve(bo); amdgpu_bo_unref(&bo); return r; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -233,9 +233,13 @@ struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; + cancel_delayed_work_sync(&adev->vcn.idle_work); + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || - RREG32_SOC15(VCN, 0, mmUVD_STATUS)) + (adev->vcn.cur_state != AMD_PG_STATE_GATE && + RREG32_SOC15(VCN, 0, mmUVD_STATUS))) { vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE); + } ring->sched.ready = false; @@ -1375,7 +1379,7 @@ if (enable) { /* wait for STATUS to clear */ - if (vcn_v1_0_is_idle(handle)) + if (!vcn_v1_0_is_idle(handle)) return -EBUSY; vcn_v1_0_enable_clock_gating(adev); } else { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c @@ -293,6 +293,8 @@ struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec; int i; + cancel_delayed_work_sync(&adev->vcn.idle_work); + if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) || (adev->vcn.cur_state != AMD_PG_STATE_GATE && RREG32_SOC15(VCN, 0, mmUVD_STATUS))) @@ -1026,6 +1028,10 @@ tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1); WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp); + /* Stall DPG before WPTR/RPTR reset */ + WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), + UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK, + ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); /* set the write pointer delay */ WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0); @@ -1048,6 +1054,9 @@ WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr)); + /* Unstall DPG */ + WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), + 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); return 0; } @@ -1357,8 +1366,13 @@ UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code); + /* Stall DPG before WPTR/RPTR reset */ + WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), + UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK, + ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); /* Restore */ ring = &adev->vcn.inst->ring_enc[0]; + ring->wptr = 0; WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); @@ -1366,6 +1380,7 @@ WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); ring = &adev->vcn.inst->ring_enc[1]; + ring->wptr = 0; WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); @@ -1374,6 +1389,9 @@ WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF); + /* Unstall DPG */ + WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), + 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK); SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -302,6 +302,8 @@ struct amdgpu_ring *ring; int i; + cancel_delayed_work_sync(&adev->vcn.idle_work); + for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { if (adev->vcn.harvest_config & (1 << i)) continue; @@ -423,7 +425,6 @@ * vcn_v2_5_disable_clock_gating - disable VCN clock gating * * @adev: amdgpu_device pointer - * @sw: enable SW clock gating * * Disable clock gating for VCN block */ @@ -542,7 +543,6 @@ * vcn_v2_5_enable_clock_gating - enable VCN clock gating * * @adev: amdgpu_device pointer - * @sw: enable SW clock gating * * Enable clock gating for VCN block */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -420,6 +420,12 @@ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); WREG32_NO_KIQ(reg, tmp); + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows + * can be detected. + */ + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); + WREG32_NO_KIQ(reg, tmp); + out: return (wptr & ih->ptr_mask); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdgpu/vi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdgpu/vi.c @@ -329,8 +329,15 @@ u32 reference_clock = adev->clock.spll.reference_freq; u32 tmp; - if (adev->flags & AMD_IS_APU) - return reference_clock; + if (adev->flags & AMD_IS_APU) { + switch (adev->asic_type) { + case CHIP_STONEY: + /* vbios says 48Mhz, but the actual freq is 100Mhz */ + return 10000; + default: + return reference_clock; + } + } tmp = RREG32_SMC(ixCG_CLKPIN_CNTL_2); if (REG_GET_FIELD(tmp, CG_CLKPIN_CNTL_2, MUX_TCLK_TO_XCLK)) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler.h @@ -905,7 +905,7 @@ 0x7a5d0000, 0x807c817c, 0x807aff7a, 0x00000080, 0xbf0a717c, 0xbf85fff8, - 0xbf820141, 0xbef4037e, + 0xbf820142, 0xbef4037e, 0x8775ff7f, 0x0000ffff, 0x8875ff75, 0x00040000, 0xbef60380, 0xbef703ff, @@ -967,7 +967,7 @@ 0x725d0000, 0xe0304080, 0x725d0100, 0xe0304100, 0x725d0200, 0xe0304180, - 0x725d0300, 0xbf820031, + 0x725d0300, 0xbf820032, 0xbef603ff, 0x01000000, 0xbef20378, 0x8078ff78, 0x00000400, 0xbefc0384, @@ -992,83 +992,84 @@ 0x725d0000, 0xe0304100, 0x725d0100, 0xe0304200, 0x725d0200, 0xe0304300, - 0x725d0300, 0xb9782a05, - 0x80788178, 0x907c9973, - 0x877c817c, 0xbf06817c, - 0xbf850002, 0x8f788978, - 0xbf820001, 0x8f788a78, - 0xb9721e06, 0x8f728a72, - 0x80787278, 0x8078ff78, - 0x00000200, 0x80f8ff78, - 0x00000050, 0xbef603ff, - 0x01000000, 0xbefc03ff, - 0x0000006c, 0x80f89078, - 0xf429003a, 0xf0000000, - 0xbf8cc07f, 0x80fc847c, - 0xbf800000, 0xbe803100, - 0xbe823102, 0x80f8a078, - 0xf42d003a, 0xf0000000, - 0xbf8cc07f, 0x80fc887c, - 0xbf800000, 0xbe803100, - 0xbe823102, 0xbe843104, - 0xbe863106, 0x80f8c078, - 0xf431003a, 0xf0000000, - 0xbf8cc07f, 0x80fc907c, - 0xbf800000, 0xbe803100, - 0xbe823102, 0xbe843104, - 0xbe863106, 0xbe883108, - 0xbe8a310a, 0xbe8c310c, - 0xbe8e310e, 0xbf06807c, - 0xbf84fff0, 0xb9782a05, - 0x80788178, 0x907c9973, - 0x877c817c, 0xbf06817c, - 0xbf850002, 0x8f788978, - 0xbf820001, 0x8f788a78, - 0xb9721e06, 0x8f728a72, - 0x80787278, 0x8078ff78, - 0x00000200, 0xbef603ff, - 0x01000000, 0xf4211bfa, + 0x725d0300, 0xbf8c3f70, + 0xb9782a05, 0x80788178, + 0x907c9973, 0x877c817c, + 0xbf06817c, 0xbf850002, + 0x8f788978, 0xbf820001, + 0x8f788a78, 0xb9721e06, + 0x8f728a72, 0x80787278, + 0x8078ff78, 0x00000200, + 0x80f8ff78, 0x00000050, + 0xbef603ff, 0x01000000, + 0xbefc03ff, 0x0000006c, + 0x80f89078, 0xf429003a, + 0xf0000000, 0xbf8cc07f, + 0x80fc847c, 0xbf800000, + 0xbe803100, 0xbe823102, + 0x80f8a078, 0xf42d003a, + 0xf0000000, 0xbf8cc07f, + 0x80fc887c, 0xbf800000, + 0xbe803100, 0xbe823102, + 0xbe843104, 0xbe863106, + 0x80f8c078, 0xf431003a, + 0xf0000000, 0xbf8cc07f, + 0x80fc907c, 0xbf800000, + 0xbe803100, 0xbe823102, + 0xbe843104, 0xbe863106, + 0xbe883108, 0xbe8a310a, + 0xbe8c310c, 0xbe8e310e, + 0xbf06807c, 0xbf84fff0, + 0xb9782a05, 0x80788178, + 0x907c9973, 0x877c817c, + 0xbf06817c, 0xbf850002, + 0x8f788978, 0xbf820001, + 0x8f788a78, 0xb9721e06, + 0x8f728a72, 0x80787278, + 0x8078ff78, 0x00000200, + 0xbef603ff, 0x01000000, + 0xf4211bfa, 0xf0000000, + 0x80788478, 0xf4211b3a, 0xf0000000, 0x80788478, - 0xf4211b3a, 0xf0000000, - 0x80788478, 0xf4211b7a, + 0xf4211b7a, 0xf0000000, + 0x80788478, 0xf4211eba, 0xf0000000, 0x80788478, - 0xf4211eba, 0xf0000000, - 0x80788478, 0xf4211efa, + 0xf4211efa, 0xf0000000, + 0x80788478, 0xf4211c3a, 0xf0000000, 0x80788478, - 0xf4211c3a, 0xf0000000, - 0x80788478, 0xf4211c7a, + 0xf4211c7a, 0xf0000000, + 0x80788478, 0xf4211e7a, 0xf0000000, 0x80788478, - 0xf4211e7a, 0xf0000000, - 0x80788478, 0xf4211cfa, + 0xf4211cfa, 0xf0000000, + 0x80788478, 0xf4211bba, 0xf0000000, 0x80788478, + 0xbf8cc07f, 0xb9eef814, 0xf4211bba, 0xf0000000, 0x80788478, 0xbf8cc07f, - 0xb9eef814, 0xf4211bba, - 0xf0000000, 0x80788478, - 0xbf8cc07f, 0xb9eef815, - 0xbef2036d, 0x876dff72, - 0x0000ffff, 0xbefc036f, - 0xbefe037a, 0xbeff037b, - 0x876f71ff, 0x000003ff, - 0xb9ef4803, 0xb9f9f816, - 0x876f71ff, 0xfffff800, - 0x906f8b6f, 0xb9efa2c3, - 0xb9f3f801, 0x876fff72, - 0xfc000000, 0x906f9a6f, - 0x8f6f906f, 0xbef30380, + 0xb9eef815, 0xbef2036d, + 0x876dff72, 0x0000ffff, + 0xbefc036f, 0xbefe037a, + 0xbeff037b, 0x876f71ff, + 0x000003ff, 0xb9ef4803, + 0xb9f9f816, 0x876f71ff, + 0xfffff800, 0x906f8b6f, + 0xb9efa2c3, 0xb9f3f801, + 0x876fff72, 0xfc000000, + 0x906f9a6f, 0x8f6f906f, + 0xbef30380, 0x88736f73, + 0x876fff72, 0x02000000, + 0x906f996f, 0x8f6f8f6f, 0x88736f73, 0x876fff72, - 0x02000000, 0x906f996f, - 0x8f6f8f6f, 0x88736f73, - 0x876fff72, 0x01000000, - 0x906f986f, 0x8f6f996f, - 0x88736f73, 0x876fff70, - 0x00800000, 0x906f976f, - 0xb9f3f807, 0x87fe7e7e, - 0x87ea6a6a, 0xb9f0f802, - 0xbf8a0000, 0xbe80226c, - 0xbf810000, 0xbf9f0000, + 0x01000000, 0x906f986f, + 0x8f6f996f, 0x88736f73, + 0x876fff70, 0x00800000, + 0x906f976f, 0xb9f3f807, + 0x87fe7e7e, 0x87ea6a6a, + 0xb9f0f802, 0xbf8a0000, + 0xbe80226c, 0xbf810000, 0xbf9f0000, 0xbf9f0000, 0xbf9f0000, 0xbf9f0000, + 0xbf9f0000, 0x00000000, }; static const uint32_t cwsr_trap_arcturus_hex[] = { 0xbf820001, 0xbf8202c4, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/cwsr_trap_handler_gfx10.asm @@ -758,6 +758,7 @@ buffer_load_dword v1, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256 buffer_load_dword v2, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*2 buffer_load_dword v3, v0, s_restore_buf_rsrc0, s_restore_mem_offset_save slc:1 glc:1 offset:256*3 + s_waitcnt vmcnt(0) /* restore SGPRs */ //will be 2+8+16*6 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -938,8 +938,8 @@ * nodes, but not more than args->num_of_nodes as that is * the amount of memory allocated by user */ - pa = kzalloc((sizeof(struct kfd_process_device_apertures) * - args->num_of_nodes), GFP_KERNEL); + pa = kcalloc(args->num_of_nodes, sizeof(struct kfd_process_device_apertures), + GFP_KERNEL); if (!pa) return -ENOMEM; @@ -1278,7 +1278,7 @@ if (args->size != PAGE_SIZE) return -EINVAL; offset = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); - if (!offset) + if (!offset || (PAGE_SIZE > 4096)) return -ENOMEM; } @@ -1664,6 +1664,7 @@ } mutex_unlock(&p->mutex); + dma_buf_put(dmabuf); args->handle = MAKE_HANDLE(args->gpu_id, idr_handle); @@ -1673,6 +1674,7 @@ amdgpu_amdkfd_gpuvm_free_memory_of_gpu(dev->kgd, (struct kgd_mem *)mem); err_unlock: mutex_unlock(&p->mutex); + dma_buf_put(dmabuf); return r; } @@ -1870,6 +1872,9 @@ if (vma->vm_end - vma->vm_start != PAGE_SIZE) return -EINVAL; + if (PAGE_SIZE > 4096) + return -EINVAL; + address = amdgpu_amdkfd_get_mmio_remap_phys_addr(dev->kgd); vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -407,6 +407,9 @@ return -ENODEV; /* same everything but the other direction */ props2 = kmemdup(props, sizeof(*props2), GFP_KERNEL); + if (!props2) + return -ENOMEM; + props2->node_from = id_to; props2->node_to = id_from; props2->kobj = NULL; @@ -758,7 +761,7 @@ /* Fetch the CRAT table from ACPI */ status = acpi_get_table(CRAT_SIGNATURE, 0, &crat_table); if (status == AE_NOT_FOUND) { - pr_warn("CRAT table not found\n"); + pr_info("CRAT table not found\n"); return -ENODATA; } else if (ACPI_FAILURE(status)) { const char *err = acpi_format_exception(status); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_crat.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_crat.h @@ -42,8 +42,6 @@ #define CRAT_OEMTABLEID_LENGTH 8 #define CRAT_RESERVED_LENGTH 6 -#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1) - /* Compute Unit flags */ #define COMPUTE_UNIT_CPU (1 << 0) /* Create Virtual CRAT for CPU */ #define COMPUTE_UNIT_GPU (1 << 1) /* Create Virtual CRAT for GPU */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c @@ -33,6 +33,11 @@ return single_open(file, show, NULL); } +static int kfd_debugfs_hang_hws_read(struct seq_file *m, void *data) +{ + seq_printf(m, "echo gpu_id > hang_hws\n"); + return 0; +} static ssize_t kfd_debugfs_hang_hws_write(struct file *file, const char __user *user_buf, size_t size, loff_t *ppos) @@ -93,8 +98,8 @@ kfd_debugfs_hqds_by_device, &kfd_debugfs_fops); debugfs_create_file("rls", S_IFREG | 0444, debugfs_root, kfd_debugfs_rls_by_device, &kfd_debugfs_fops); - debugfs_create_file("hang_hws", S_IFREG | 0644, debugfs_root, - NULL, &kfd_debugfs_hang_hws_fops); + debugfs_create_file("hang_hws", S_IFREG | 0200, debugfs_root, + kfd_debugfs_hang_hws_read, &kfd_debugfs_hang_hws_fops); } void kfd_debugfs_fini(void) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -609,15 +609,10 @@ - kfd->vm_info.first_vmid_kfd + 1; /* Verify module parameters regarding mapped process number*/ - if ((hws_max_conc_proc < 0) - || (hws_max_conc_proc > kfd->vm_info.vmid_num_kfd)) { - dev_err(kfd_device, - "hws_max_conc_proc %d must be between 0 and %d, use %d instead\n", - hws_max_conc_proc, kfd->vm_info.vmid_num_kfd, - kfd->vm_info.vmid_num_kfd); + if (hws_max_conc_proc >= 0) + kfd->max_proc_per_quantum = min((u32)hws_max_conc_proc, kfd->vm_info.vmid_num_kfd); + else kfd->max_proc_per_quantum = kfd->vm_info.vmid_num_kfd; - } else - kfd->max_proc_per_quantum = hws_max_conc_proc; /* Allocate global GWS that is shared by all KFD processes */ if (hws_gws_support && amdgpu_amdkfd_alloc_gws(kfd->kgd, @@ -1112,9 +1107,9 @@ return 0; kfd_gtt_no_free_chunk: - pr_debug("Allocation failed with mem_obj = %p\n", mem_obj); + pr_debug("Allocation failed with mem_obj = %p\n", *mem_obj); mutex_unlock(&kfd->gtt_sa_lock); - kfree(mem_obj); + kfree(*mem_obj); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1011,6 +1011,9 @@ static int initialize_cpsch(struct device_queue_manager *dqm) { + uint64_t num_sdma_queues; + uint64_t num_xgmi_sdma_queues; + pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm)); mutex_init(&dqm->lock_hidden); @@ -1019,8 +1022,18 @@ dqm->sdma_queue_count = 0; dqm->xgmi_sdma_queue_count = 0; dqm->active_runlist = false; - dqm->sdma_bitmap = ~0ULL >> (64 - get_num_sdma_queues(dqm)); - dqm->xgmi_sdma_bitmap = ~0ULL >> (64 - get_num_xgmi_sdma_queues(dqm)); + + num_sdma_queues = get_num_sdma_queues(dqm); + if (num_sdma_queues >= BITS_PER_TYPE(dqm->sdma_bitmap)) + dqm->sdma_bitmap = ULLONG_MAX; + else + dqm->sdma_bitmap = (BIT_ULL(num_sdma_queues) - 1); + + num_xgmi_sdma_queues = get_num_xgmi_sdma_queues(dqm); + if (num_xgmi_sdma_queues >= BITS_PER_TYPE(dqm->xgmi_sdma_bitmap)) + dqm->xgmi_sdma_bitmap = ULLONG_MAX; + else + dqm->xgmi_sdma_bitmap = (BIT_ULL(num_xgmi_sdma_queues) - 1); INIT_WORK(&dqm->hw_exception_work, kfd_process_hw_exception); @@ -1075,6 +1088,8 @@ unmap_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); dqm_unlock(dqm); + pm_release_ib(&dqm->packets); + kfd_gtt_sa_free(dqm->dev, dqm->fence_mem); pm_uninit(&dqm->packets); @@ -1181,16 +1196,18 @@ list_add(&q->list, &qpd->queues_list); qpd->queue_count++; + + if (q->properties.type == KFD_QUEUE_TYPE_SDMA) + dqm->sdma_queue_count++; + else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) + dqm->xgmi_sdma_queue_count++; + if (q->properties.is_active) { dqm->queue_count++; retval = execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); } - if (q->properties.type == KFD_QUEUE_TYPE_SDMA) - dqm->sdma_queue_count++; - else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) - dqm->xgmi_sdma_queue_count++; /* * Unconditionally increment this counter, regardless of the queue's * type or whether the queue is active. @@ -1567,7 +1584,7 @@ struct qcm_process_device *qpd) { int retval; - struct queue *q, *next; + struct queue *q; struct kernel_queue *kq, *kq_next; struct mqd_manager *mqd_mgr; struct device_process_node *cur, *next_dpn; @@ -1622,24 +1639,26 @@ qpd->reset_wavefronts = false; } - dqm_unlock(dqm); - - /* Outside the DQM lock because under the DQM lock we can't do - * reclaim or take other locks that others hold while reclaiming. - */ - if (found) - kfd_dec_compute_active(dqm->dev); - /* Lastly, free mqd resources. * Do free_mqd() after dqm_unlock to avoid circular locking. */ - list_for_each_entry_safe(q, next, &qpd->queues_list, list) { + while (!list_empty(&qpd->queues_list)) { + q = list_first_entry(&qpd->queues_list, struct queue, list); mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( q->properties.type)]; list_del(&q->list); qpd->queue_count--; + dqm_unlock(dqm); mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj); + dqm_lock(dqm); } + dqm_unlock(dqm); + + /* Outside the DQM lock because under the DQM lock we can't do + * reclaim or take other locks that others hold while reclaiming. + */ + if (found) + kfd_dec_compute_active(dqm->dev); return retval; } @@ -1676,7 +1695,8 @@ struct kfd_dev *dev = dqm->dev; struct kfd_mem_obj *mem_obj = &dqm->hiq_sdma_mqd; uint32_t size = dqm->mqd_mgrs[KFD_MQD_TYPE_SDMA]->mqd_size * - dev->device_info->num_sdma_engines * + (dev->device_info->num_sdma_engines + + dev->device_info->num_xgmi_sdma_engines) * dev->device_info->num_sdma_queues_per_engine + dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ]->mqd_size; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_v10.c @@ -58,8 +58,9 @@ /* check if sh_mem_config register already configured */ if (qpd->sh_mem_config == 0) { qpd->sh_mem_config = - SH_MEM_ALIGNMENT_MODE_UNALIGNED << - SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT; + (SH_MEM_ALIGNMENT_MODE_UNALIGNED << + SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | + (3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT); #if 0 /* TODO: * This shouldn't be an issue with Navi10. Verify. --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -529,14 +529,13 @@ struct kfd_event_waiter *event_waiters; uint32_t i; - event_waiters = kmalloc_array(num_events, - sizeof(struct kfd_event_waiter), - GFP_KERNEL); + event_waiters = kcalloc(num_events, sizeof(struct kfd_event_waiter), + GFP_KERNEL); + if (!event_waiters) + return NULL; - for (i = 0; (event_waiters) && (i < num_events) ; i++) { + for (i = 0; i < num_events; i++) init_wait(&event_waiters[i].wait); - event_waiters[i].activated = false; - } return event_waiters; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c @@ -62,6 +62,11 @@ } kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1); + if (unlikely(!kfd->ih_wq)) { + kfifo_free(&kfd->ih_fifo); + dev_err(kfd_chardev(), "Failed to allocate KFD IH workqueue\n"); + return -ENOMEM; + } spin_lock_init(&kfd->interrupt_lock); INIT_WORK(&kfd->interrupt_work, interrupt_wq); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_iommu.c @@ -20,6 +20,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +#include + +#if IS_REACHABLE(CONFIG_AMD_IOMMU_V2) + #include #include #include @@ -358,3 +362,5 @@ return 0; } + +#endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_iommu.h @@ -23,7 +23,9 @@ #ifndef __KFD_IOMMU_H__ #define __KFD_IOMMU_H__ -#if defined(CONFIG_AMD_IOMMU_V2_MODULE) || defined(CONFIG_AMD_IOMMU_V2) +#include + +#if IS_REACHABLE(CONFIG_AMD_IOMMU_V2) #define KFD_SUPPORT_IOMMU_V2 @@ -46,6 +48,9 @@ } static inline int kfd_iommu_device_init(struct kfd_dev *kfd) { +#if IS_MODULE(CONFIG_AMD_IOMMU_V2) + WARN_ONCE(1, "iommu_v2 module is not usable by built-in KFD"); +#endif return 0; } @@ -73,6 +78,6 @@ return 0; } -#endif /* defined(CONFIG_AMD_IOMMU_V2) */ +#endif /* IS_REACHABLE(CONFIG_AMD_IOMMU_V2) */ #endif /* __KFD_IOMMU_H__ */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -82,7 +82,7 @@ kfd_chardev_exit(); } -int kgd2kfd_init() +int kgd2kfd_init(void) { return kfd_init(); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -98,36 +98,78 @@ uint32_t *se_mask) { struct kfd_cu_info cu_info; - uint32_t cu_per_se[KFD_MAX_NUM_SE] = {0}; - int i, se, sh, cu = 0; - + uint32_t cu_per_sh[KFD_MAX_NUM_SE][KFD_MAX_NUM_SH_PER_SE] = {0}; + int i, se, sh, cu; amdgpu_amdkfd_get_cu_info(mm->dev->kgd, &cu_info); if (cu_mask_count > cu_info.cu_active_number) cu_mask_count = cu_info.cu_active_number; + /* Exceeding these bounds corrupts the stack and indicates a coding error. + * Returning with no CU's enabled will hang the queue, which should be + * attention grabbing. + */ + if (cu_info.num_shader_engines > KFD_MAX_NUM_SE) { + pr_err("Exceeded KFD_MAX_NUM_SE, chip reports %d\n", cu_info.num_shader_engines); + return; + } + if (cu_info.num_shader_arrays_per_engine > KFD_MAX_NUM_SH_PER_SE) { + pr_err("Exceeded KFD_MAX_NUM_SH, chip reports %d\n", + cu_info.num_shader_arrays_per_engine * cu_info.num_shader_engines); + return; + } + /* Count active CUs per SH. + * + * Some CUs in an SH may be disabled. HW expects disabled CUs to be + * represented in the high bits of each SH's enable mask (the upper and lower + * 16 bits of se_mask) and will take care of the actual distribution of + * disabled CUs within each SH automatically. + * Each half of se_mask must be filled only on bits 0-cu_per_sh[se][sh]-1. + * + * See note on Arcturus cu_bitmap layout in gfx_v9_0_get_cu_info. + */ for (se = 0; se < cu_info.num_shader_engines; se++) for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) - cu_per_se[se] += hweight32(cu_info.cu_bitmap[se % 4][sh + (se / 4)]); + cu_per_sh[se][sh] = hweight32(cu_info.cu_bitmap[se % 4][sh + (se / 4)]); - /* Symmetrically map cu_mask to all SEs: - * cu_mask[0] bit0 -> se_mask[0] bit0; - * cu_mask[0] bit1 -> se_mask[1] bit0; - * ... (if # SE is 4) - * cu_mask[0] bit4 -> se_mask[0] bit1; + /* Symmetrically map cu_mask to all SEs & SHs: + * se_mask programs up to 2 SH in the upper and lower 16 bits. + * + * Examples + * Assuming 1 SH/SE, 4 SEs: + * cu_mask[0] bit0 -> se_mask[0] bit0 + * cu_mask[0] bit1 -> se_mask[1] bit0 + * ... + * cu_mask[0] bit4 -> se_mask[0] bit1 + * ... + * + * Assuming 2 SH/SE, 4 SEs + * cu_mask[0] bit0 -> se_mask[0] bit0 (SE0,SH0,CU0) + * cu_mask[0] bit1 -> se_mask[1] bit0 (SE1,SH0,CU0) + * ... + * cu_mask[0] bit4 -> se_mask[0] bit16 (SE0,SH1,CU0) + * cu_mask[0] bit5 -> se_mask[1] bit16 (SE1,SH1,CU0) + * ... + * cu_mask[0] bit8 -> se_mask[0] bit1 (SE0,SH0,CU1) * ... + * + * First ensure all CUs are disabled, then enable user specified CUs. */ - se = 0; - for (i = 0; i < cu_mask_count; i++) { - if (cu_mask[i / 32] & (1 << (i % 32))) - se_mask[se] |= 1 << cu; + for (i = 0; i < cu_info.num_shader_engines; i++) + se_mask[i] = 0; - do { - se++; - if (se == cu_info.num_shader_engines) { - se = 0; - cu++; + i = 0; + for (cu = 0; cu < 16; cu++) { + for (sh = 0; sh < cu_info.num_shader_arrays_per_engine; sh++) { + for (se = 0; se < cu_info.num_shader_engines; se++) { + if (cu_per_sh[se][sh] > cu) { + if (cu_mask[i / 32] & (1 << (i % 32))) + se_mask[se] |= 1 << (cu + sh * 16); + i++; + if (i == cu_mask_count) + return; + } } - } while (cu >= cu_per_se[se] && cu < 32); + } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h @@ -27,6 +27,7 @@ #include "kfd_priv.h" #define KFD_MAX_NUM_SE 8 +#define KFD_MAX_NUM_SH_PER_SE 2 /** * struct mqd_manager --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -101,18 +101,19 @@ &(mqd_mem_obj->gtt_mem), &(mqd_mem_obj->gpu_addr), (void *)&(mqd_mem_obj->cpu_ptr), true); + + if (retval) { + kfree(mqd_mem_obj); + return NULL; + } } else { retval = kfd_gtt_sa_allocate(kfd, sizeof(struct v9_mqd), &mqd_mem_obj); - } - - if (retval) { - kfree(mqd_mem_obj); - return NULL; + if (retval) + return NULL; } return mqd_mem_obj; - } static void init_mqd(struct mqd_manager *mm, void **mqd, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -289,6 +289,14 @@ if (process) { pr_debug("Process already found\n"); } else { + /* If the process just called exec(3), it is possible that the + * cleanup of the kfd_process (following the release of the mm + * of the old process image) is still in the cleanup work queue. + * Make sure to drain any job before trying to recreate any + * resource for this process. + */ + flush_workqueue(kfd_process_wq); + process = create_process(thread); if (IS_ERR(process)) goto out; @@ -312,6 +320,7 @@ (int)process->lead_thread->pid); if (ret) { pr_warn("Creating procfs pid directory failed"); + kobject_put(process->kobj); goto out; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -612,8 +612,10 @@ ret = kobject_init_and_add(dev->kobj_node, &node_type, sys_props.kobj_nodes, "%d", id); - if (ret < 0) + if (ret < 0) { + kobject_put(dev->kobj_node); return ret; + } dev->kobj_mem = kobject_create_and_add("mem_banks", dev->kobj_node); if (!dev->kobj_mem) @@ -660,8 +662,10 @@ return -ENOMEM; ret = kobject_init_and_add(mem->kobj, &mem_type, dev->kobj_mem, "%d", i); - if (ret < 0) + if (ret < 0) { + kobject_put(mem->kobj); return ret; + } mem->attr.name = "properties"; mem->attr.mode = KFD_SYSFS_FILE_MODE; @@ -679,8 +683,10 @@ return -ENOMEM; ret = kobject_init_and_add(cache->kobj, &cache_type, dev->kobj_cache, "%d", i); - if (ret < 0) + if (ret < 0) { + kobject_put(cache->kobj); return ret; + } cache->attr.name = "properties"; cache->attr.mode = KFD_SYSFS_FILE_MODE; @@ -698,8 +704,10 @@ return -ENOMEM; ret = kobject_init_and_add(iolink->kobj, &iolink_type, dev->kobj_iolink, "%d", i); - if (ret < 0) + if (ret < 0) { + kobject_put(iolink->kobj); return ret; + } iolink->attr.name = "properties"; iolink->attr.mode = KFD_SYSFS_FILE_MODE; @@ -779,8 +787,10 @@ ret = kobject_init_and_add(sys_props.kobj_topology, &sysprops_type, &kfd_device->kobj, "topology"); - if (ret < 0) + if (ret < 0) { + kobject_put(sys_props.kobj_topology); return ret; + } sys_props.kobj_nodes = kobject_create_and_add("nodes", sys_props.kobj_topology); @@ -873,8 +883,7 @@ dev = list_last_entry(&topology_device_list, struct kfd_topology_device, list); if (dev) { - sys_props.platform_id = - (*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK; + sys_props.platform_id = dev->oem_id64; sys_props.platform_oem = *((uint64_t *)dev->oem_table_id); sys_props.platform_rev = dev->oem_revision; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_topology.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.h @@ -172,7 +172,10 @@ struct attribute attr_gpuid; struct attribute attr_name; struct attribute attr_props; - uint8_t oem_id[CRAT_OEMID_LENGTH]; + union { + uint8_t oem_id[CRAT_OEMID_LENGTH]; + uint64_t oem_id64; + }; uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH]; uint32_t oem_revision; }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -664,6 +664,7 @@ init_data.asic_id.pci_revision_id = adev->rev_id; init_data.asic_id.hw_internal_rev = adev->external_rev_id; + init_data.asic_id.chip_id = adev->pdev->device; init_data.asic_id.vram_width = adev->gmc.vram_width; /* TODO: initialize init_data.asic_id.vram_type here!!!! */ @@ -928,8 +929,13 @@ struct dmcu_iram_parameters params; unsigned int linear_lut[16]; int i; - struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu; - bool ret = false; + struct dmcu *dmcu = NULL; + bool ret; + + if (!adev->dm.fw_dmcu) + return detect_mst_link_for_all_connectors(adev->ddev); + + dmcu = adev->dm.dc->res_pool->dmcu; for (i = 0; i < 16; i++) linear_lut[i] = 0xFFFF * i / 15; @@ -940,13 +946,15 @@ params.backlight_lut_array_size = 16; params.backlight_lut_array = linear_lut; - /* todo will enable for navi10 */ - if (adev->asic_type <= CHIP_RAVEN) { - ret = dmcu_load_iram(dmcu, params); + /* Min backlight level after ABM reduction, Don't allow below 1% + * 0xFFFF x 0.01 = 0x28F + */ + params.min_abm_backlight = 0x28F; - if (!ret) - return -EINVAL; - } + ret = dmcu_load_iram(dmcu, params); + + if (!ret) + return -EINVAL; return detect_mst_link_for_all_connectors(adev->ddev); } @@ -1086,8 +1094,8 @@ link->type = dc_connection_none; prev_sink = link->local_sink; - if (prev_sink != NULL) - dc_sink_retain(prev_sink); + if (prev_sink) + dc_sink_release(prev_sink); switch (link->connector_signal) { case SIGNAL_TYPE_HDMI_TYPE_A: { @@ -1198,11 +1206,14 @@ list_for_each_entry(connector, &ddev->mode_config.connector_list, head) { aconnector = to_amdgpu_dm_connector(connector); + if (!aconnector->dc_link) + continue; + /* * this is the case when traversing through already created * MST connectors, should be skipped */ - if (aconnector->mst_port) + if (aconnector->dc_link->type == dc_connection_mst_branch) continue; mutex_lock(&aconnector->hpd_lock); @@ -1240,6 +1251,7 @@ dc_stream_release(dm_new_crtc_state->stream); dm_new_crtc_state->stream = NULL; } + dm_new_crtc_state->base.color_mgmt_changed = true; } for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) { @@ -1410,24 +1422,29 @@ * TODO: check if we still need the S3 mode update workaround. * If yes, put it here. */ - if (aconnector->dc_sink) + if (aconnector->dc_sink) { amdgpu_dm_update_freesync_caps(connector, NULL); + dc_sink_release(aconnector->dc_sink); + } aconnector->dc_sink = sink; dc_sink_retain(aconnector->dc_sink); if (sink->dc_edid.length == 0) { aconnector->edid = NULL; - drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux); + if (aconnector->dc_link->aux_mode) { + drm_dp_cec_unset_edid( + &aconnector->dm_dp_aux.aux); + } } else { aconnector->edid = - (struct edid *) sink->dc_edid.raw_edid; - + (struct edid *)sink->dc_edid.raw_edid; - drm_connector_update_edid_property(connector, - aconnector->edid); - drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, - aconnector->edid); + if (aconnector->dc_link->aux_mode) + drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux, + aconnector->edid); } + + drm_connector_update_edid_property(connector, aconnector->edid); amdgpu_dm_update_freesync_caps(connector, aconnector->edid); } else { @@ -2030,12 +2047,18 @@ &dm_atomic_state_funcs); r = amdgpu_display_modeset_create_props(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + } r = amdgpu_dm_audio_init(adev); - if (r) + if (r) { + dc_release_state(state->context); + kfree(state); return r; + } return 0; } @@ -2051,6 +2074,8 @@ #if defined(CONFIG_ACPI) struct amdgpu_dm_backlight_caps caps; + memset(&caps, 0, sizeof(caps)); + if (dm->backlight_caps.caps_valid) return; @@ -2238,7 +2263,10 @@ /* There is one primary plane per CRTC */ primary_planes = dm->dc->caps.max_streams; - ASSERT(primary_planes <= AMDGPU_MAX_PLANES); + if (primary_planes > AMDGPU_MAX_PLANES) { + DRM_ERROR("DM: Plane nums out of 6 planes\n"); + return -EINVAL; + } /* * Initialize primary planes, implicit planes for legacy IOCTLS. @@ -2611,6 +2639,23 @@ scaling_info->src_rect.x = state->src_x >> 16; scaling_info->src_rect.y = state->src_y >> 16; + /* + * For reasons we don't (yet) fully understand a non-zero + * src_y coordinate into an NV12 buffer can cause a + * system hang. To avoid hangs (and maybe be overly cautious) + * let's reject both non-zero src_x and src_y. + * + * We currently know of only one use-case to reproduce a + * scenario with non-zero src_x and src_y for NV12, which + * is to gesture the YouTube Android app into full screen + * on ChromeOS. + */ + if (state->fb && + state->fb->format->format == DRM_FORMAT_NV12 && + (scaling_info->src_rect.x != 0 || + scaling_info->src_rect.y != 0)) + return -EINVAL; + scaling_info->src_rect.width = state->src_w >> 16; if (scaling_info->src_rect.width == 0) return -EINVAL; @@ -2693,7 +2738,8 @@ const union dc_tiling_info *tiling_info, const uint64_t info, struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address) + struct dc_plane_address *address, + bool force_disable_dcc) { struct dc *dc = adev->dm.dc; struct dc_dcc_surface_param input; @@ -2705,6 +2751,9 @@ memset(&input, 0, sizeof(input)); memset(&output, 0, sizeof(output)); + if (force_disable_dcc) + return 0; + if (!offset) return 0; @@ -2754,7 +2803,8 @@ union dc_tiling_info *tiling_info, struct plane_size *plane_size, struct dc_plane_dcc_param *dcc, - struct dc_plane_address *address) + struct dc_plane_address *address, + bool force_disable_dcc) { const struct drm_framebuffer *fb = &afb->base; int ret; @@ -2864,7 +2914,8 @@ ret = fill_plane_dcc_attributes(adev, afb, format, rotation, plane_size, tiling_info, - tiling_flags, dcc, address); + tiling_flags, dcc, address, + force_disable_dcc); if (ret) return ret; } @@ -2956,7 +3007,8 @@ const struct drm_plane_state *plane_state, const uint64_t tiling_flags, struct dc_plane_info *plane_info, - struct dc_plane_address *address) + struct dc_plane_address *address, + bool force_disable_dcc) { const struct drm_framebuffer *fb = plane_state->fb; const struct amdgpu_framebuffer *afb = @@ -3035,7 +3087,8 @@ plane_info->rotation, tiling_flags, &plane_info->tiling_info, &plane_info->plane_size, - &plane_info->dcc, address); + &plane_info->dcc, address, + force_disable_dcc); if (ret) return ret; @@ -3058,6 +3111,7 @@ struct dc_plane_info plane_info; uint64_t tiling_flags; int ret; + bool force_disable_dcc = false; ret = fill_dc_scaling_info(plane_state, &scaling_info); if (ret) @@ -3072,9 +3126,11 @@ if (ret) return ret; + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, &plane_info, - &dc_plane_state->address); + &dc_plane_state->address, + force_disable_dcc); if (ret) return ret; @@ -3261,27 +3317,21 @@ return color_space; } -static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out) -{ - if (timing_out->display_color_depth <= COLOR_DEPTH_888) - return; - - timing_out->display_color_depth--; -} - -static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out, - const struct drm_display_info *info) +static bool adjust_colour_depth_from_display_info( + struct dc_crtc_timing *timing_out, + const struct drm_display_info *info) { + enum dc_color_depth depth = timing_out->display_color_depth; int normalized_clk; - if (timing_out->display_color_depth <= COLOR_DEPTH_888) - return; do { normalized_clk = timing_out->pix_clk_100hz / 10; /* YCbCr 4:2:0 requires additional adjustment of 1/2 */ if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420) normalized_clk /= 2; /* Adjusting pix clock following on HDMI spec based on colour depth */ - switch (timing_out->display_color_depth) { + switch (depth) { + case COLOR_DEPTH_888: + break; case COLOR_DEPTH_101010: normalized_clk = (normalized_clk * 30) / 24; break; @@ -3292,14 +3342,15 @@ normalized_clk = (normalized_clk * 48) / 24; break; default: - return; + /* The above depths are the only ones valid for HDMI. */ + return false; } - if (normalized_clk <= info->max_tmds_clock) - return; - reduce_mode_colour_depth(timing_out); - - } while (timing_out->display_color_depth > COLOR_DEPTH_888); - + if (normalized_clk <= info->max_tmds_clock) { + timing_out->display_color_depth = depth; + return true; + } + } while (--depth > COLOR_DEPTH_666); + return false; } static void fill_stream_properties_from_drm_display_mode( @@ -3365,8 +3416,14 @@ stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; - if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) - adjust_colour_depth_from_display_info(timing_out, info); + if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { + if (!adjust_colour_depth_from_display_info(timing_out, info) && + drm_mode_is_420_also(info, mode_in) && + timing_out->pixel_encoding != PIXEL_ENCODING_YCBCR420) { + timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420; + adjust_colour_depth_from_display_info(timing_out, info); + } + } } static void fill_audio_info(struct audio_info *audio_info, @@ -3923,6 +3980,13 @@ struct amdgpu_device *adev = connector->dev->dev_private; struct amdgpu_display_manager *dm = &adev->dm; + /* + * Call only if mst_mgr was iniitalized before since it's not done + * for all connector types. + */ + if (aconnector->mst_mgr.dev) + drm_dp_mst_topology_mgr_destroy(&aconnector->mst_mgr); + #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) ||\ defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) @@ -4266,19 +4330,6 @@ { } -static bool does_crtc_have_active_cursor(struct drm_crtc_state *new_crtc_state) -{ - struct drm_device *dev = new_crtc_state->crtc->dev; - struct drm_plane *plane; - - drm_for_each_plane_mask(plane, dev, new_crtc_state->plane_mask) { - if (plane->type == DRM_PLANE_TYPE_CURSOR) - return true; - } - - return false; -} - static int count_crtc_active_planes(struct drm_crtc_state *new_crtc_state) { struct drm_atomic_state *state = new_crtc_state->state; @@ -4358,19 +4409,20 @@ return ret; } - /* In some use cases, like reset, no stream is attached */ - if (!dm_crtc_state->stream) - return 0; - /* - * We want at least one hardware plane enabled to use - * the stream with a cursor enabled. + * We require the primary plane to be enabled whenever the CRTC is, otherwise + * drm_mode_cursor_universal may end up trying to enable the cursor plane while all other + * planes are disabled, which is not supported by the hardware. And there is legacy + * userspace which stops using the HW cursor altogether in response to the resulting EINVAL. */ - if (state->enable && state->active && - does_crtc_have_active_cursor(state) && - dm_crtc_state->active_planes == 0) + if (state->enable && + !(state->plane_mask & drm_plane_mask(crtc->primary))) return -EINVAL; + /* In some use cases, like reset, no stream is attached */ + if (!dm_crtc_state->stream) + return 0; + if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK) return 0; @@ -4475,6 +4527,7 @@ uint64_t tiling_flags; uint32_t domain; int r; + bool force_disable_dcc = false; dm_plane_state_old = to_dm_plane_state(plane->state); dm_plane_state_new = to_dm_plane_state(new_state); @@ -4533,11 +4586,13 @@ dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; + force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; fill_plane_buffer_attributes( adev, afb, plane_state->format, plane_state->rotation, tiling_flags, &plane_state->tiling_info, &plane_state->plane_size, &plane_state->dcc, - &plane_state->address); + &plane_state->address, + force_disable_dcc); } return 0; @@ -4947,6 +5002,9 @@ mode = amdgpu_dm_create_common_mode(encoder, common_modes[i].name, common_modes[i].w, common_modes[i].h); + if (!mode) + continue; + drm_mode_probed_add(connector, mode); amdgpu_dm_connector->num_modes++; } @@ -5341,10 +5399,6 @@ int x, y; int xorigin = 0, yorigin = 0; - position->enable = false; - position->x = 0; - position->y = 0; - if (!crtc || !plane->state->fb) return 0; @@ -5396,7 +5450,7 @@ struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); uint64_t address = afb ? afb->address : 0; - struct dc_cursor_position position; + struct dc_cursor_position position = {0}; struct dc_cursor_attributes attributes; int ret; @@ -5709,6 +5763,8 @@ continue; dc_plane = dm_new_plane_state->dc_state; + if (!dc_plane) + continue; bundle->surface_updates[planes_count].surface = dc_plane; if (new_pcrtc_state->color_mgmt_changed) { @@ -5761,7 +5817,12 @@ fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, &bundle->plane_infos[planes_count], - &bundle->flip_addrs[planes_count].address); + &bundle->flip_addrs[planes_count].address, + false); + + DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", + new_plane_state->plane->index, + bundle->plane_infos[planes_count].dcc.enable); bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count]; @@ -6429,14 +6490,14 @@ ret = PTR_ERR_OR_ZERO(conn_state); if (ret) - goto err; + goto out; /* Attach crtc to drm_atomic_state*/ crtc_state = drm_atomic_get_crtc_state(state, &disconnected_acrtc->base); ret = PTR_ERR_OR_ZERO(crtc_state); if (ret) - goto err; + goto out; /* force a restore */ crtc_state->mode_changed = true; @@ -6446,17 +6507,15 @@ ret = PTR_ERR_OR_ZERO(plane_state); if (ret) - goto err; - + goto out; /* Call commit internally with the state we just constructed */ ret = drm_atomic_commit(state); - if (!ret) - return 0; -err: - DRM_ERROR("Restoring old state failed with %i\n", ret); +out: drm_atomic_state_put(state); + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); return ret; } @@ -6785,7 +6844,8 @@ BUG_ON(dm_new_crtc_state->stream == NULL); /* Scaling or underscan settings */ - if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state)) + if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state) || + drm_atomic_crtc_needs_modeset(new_crtc_state)) update_stream_scaling_settings( &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream); @@ -6896,6 +6956,7 @@ struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct dm_crtc_state *dm_new_crtc_state, *dm_old_crtc_state; struct dm_plane_state *dm_new_plane_state, *dm_old_plane_state; + struct amdgpu_crtc *new_acrtc; bool needs_reset; int ret = 0; @@ -6905,9 +6966,23 @@ dm_new_plane_state = to_dm_plane_state(new_plane_state); dm_old_plane_state = to_dm_plane_state(old_plane_state); - /*TODO Implement atomic check for cursor plane */ - if (plane->type == DRM_PLANE_TYPE_CURSOR) + /*TODO Implement better atomic check for cursor plane */ + if (plane->type == DRM_PLANE_TYPE_CURSOR) { + if (!enable || !new_plane_crtc || + drm_atomic_plane_disabling(plane->state, new_plane_state)) + return 0; + + new_acrtc = to_amdgpu_crtc(new_plane_crtc); + + if ((new_plane_state->crtc_w > new_acrtc->max_cursor_width) || + (new_plane_state->crtc_h > new_acrtc->max_cursor_height)) { + DRM_DEBUG_ATOMIC("Bad cursor size %d x %d\n", + new_plane_state->crtc_w, new_plane_state->crtc_h); + return -EINVAL; + } + return 0; + } needs_reset = should_reset_plane(state, plane, old_plane_state, new_plane_state); @@ -6940,12 +7015,12 @@ dm_old_plane_state->dc_state, dm_state->context)) { - ret = EINVAL; - return ret; + return -EINVAL; } + if (dm_old_plane_state->dc_state) + dc_plane_state_release(dm_old_plane_state->dc_state); - dc_plane_state_release(dm_old_plane_state->dc_state); dm_new_plane_state->dc_state = NULL; *lock_and_validation_needed = true; @@ -7132,7 +7207,8 @@ ret = fill_dc_plane_info_and_addr( dm->adev, new_plane_state, tiling_flags, &plane_info, - &flip_addr.address); + &flip_addr.address, + false); if (ret) goto cleanup; @@ -7180,6 +7256,80 @@ *out_type = update_type; return ret; } +#if defined(CONFIG_DRM_AMD_DC_DCN) +static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm_crtc *crtc) +{ + struct drm_connector *connector; + struct drm_connector_state *conn_state, *old_conn_state; + struct amdgpu_dm_connector *aconnector = NULL; + int i; + for_each_oldnew_connector_in_state(state, connector, old_conn_state, conn_state, i) { + if (!conn_state->crtc) + conn_state = old_conn_state; + + if (conn_state->crtc != crtc) + continue; + + aconnector = to_amdgpu_dm_connector(connector); + if (!aconnector->port || !aconnector->mst_port) + aconnector = NULL; + else + break; + } + + if (!aconnector) + return 0; + + return drm_dp_mst_add_affected_dsc_crtcs(state, &aconnector->mst_port->mst_mgr); +} +#endif + +static int validate_overlay(struct drm_atomic_state *state) +{ + int i; + struct drm_plane *plane; + struct drm_plane_state *old_plane_state, *new_plane_state; + struct drm_plane_state *primary_state, *overlay_state = NULL; + + /* Check if primary plane is contained inside overlay */ + for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { + if (plane->type == DRM_PLANE_TYPE_OVERLAY) { + if (drm_atomic_plane_disabling(plane->state, new_plane_state)) + return 0; + + overlay_state = new_plane_state; + continue; + } + } + + /* check if we're making changes to the overlay plane */ + if (!overlay_state) + return 0; + + /* check if overlay plane is enabled */ + if (!overlay_state->crtc) + return 0; + + /* find the primary plane for the CRTC that the overlay is enabled on */ + primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary); + if (IS_ERR(primary_state)) + return PTR_ERR(primary_state); + + /* check if primary plane is enabled */ + if (!primary_state->crtc) + return 0; + + /* Perform the bounds check to ensure the overlay plane covers the primary */ + if (primary_state->crtc_x < overlay_state->crtc_x || + primary_state->crtc_y < overlay_state->crtc_y || + primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w || + primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) { + DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n"); + return -EINVAL; + } + + return 0; +} /** * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM. @@ -7233,12 +7383,50 @@ if (ret) goto fail; + /* Check connector changes */ + for_each_oldnew_connector_in_state(state, connector, old_con_state, new_con_state, i) { + struct dm_connector_state *dm_old_con_state = to_dm_connector_state(old_con_state); + struct dm_connector_state *dm_new_con_state = to_dm_connector_state(new_con_state); + + /* Skip connectors that are disabled or part of modeset already. */ + if (!old_con_state->crtc && !new_con_state->crtc) + continue; + + if (!new_con_state->crtc) + continue; + + new_crtc_state = drm_atomic_get_crtc_state(state, new_con_state->crtc); + if (IS_ERR(new_crtc_state)) { + ret = PTR_ERR(new_crtc_state); + goto fail; + } + + if (dm_old_con_state->abm_level != dm_new_con_state->abm_level || + dm_old_con_state->scaling != dm_new_con_state->scaling) + new_crtc_state->connectors_changed = true; + } + +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dc_resource_is_dsc_encoding_supported(dc)) { + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + if (drm_atomic_crtc_needs_modeset(new_crtc_state)) { + ret = add_affected_mst_dsc_crtcs(state, crtc); + if (ret) + goto fail; + } + } + } +#endif for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { if (!drm_atomic_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->color_mgmt_changed && old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled) continue; + ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); + if (ret) + goto fail; + if (!new_crtc_state->enable) continue; @@ -7320,6 +7508,10 @@ goto fail; } + ret = validate_overlay(state); + if (ret) + goto fail; + /* Add new/modified planes */ for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { ret = dm_update_plane_state(dc, state, plane, @@ -7416,20 +7608,38 @@ * the same resource. If we have a new DC context as part of * the DM atomic state from validation we need to free it and * retain the existing one instead. + * + * Furthermore, since the DM atomic state only contains the DC + * context and can safely be annulled, we can free the state + * and clear the associated private object now to free + * some memory and avoid a possible use-after-free later. */ - struct dm_atomic_state *new_dm_state, *old_dm_state; - new_dm_state = dm_atomic_get_new_state(state); - old_dm_state = dm_atomic_get_old_state(state); + for (i = 0; i < state->num_private_objs; i++) { + struct drm_private_obj *obj = state->private_objs[i].ptr; - if (new_dm_state && old_dm_state) { - if (new_dm_state->context) - dc_release_state(new_dm_state->context); + if (obj->funcs == adev->dm.atomic_obj.funcs) { + int j = state->num_private_objs-1; - new_dm_state->context = old_dm_state->context; + dm_atomic_destroy_state(obj, + state->private_objs[i].state); - if (old_dm_state->context) - dc_retain_state(old_dm_state->context); + /* If i is not at the end of the array then the + * last element needs to be moved to where i was + * before the array can safely be truncated. + */ + if (i != j) + state->private_objs[i] = + state->private_objs[j]; + + state->private_objs[j].ptr = NULL; + state->private_objs[j].state = NULL; + state->private_objs[j].old_state = NULL; + state->private_objs[j].new_state = NULL; + + state->num_private_objs = j; + break; + } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -387,6 +387,7 @@ #define MAX_COLOR_LEGACY_LUT_ENTRIES 256 void amdgpu_dm_init_color_mod(void); +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state); int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc); int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct dc_plane_state *dc_plane_state); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -210,6 +210,8 @@ res = mod_color_calculate_regamma_params(func, gamma, true, has_rom, NULL); + dc_gamma_release(&gamma); + return res ? 0 : -ENOMEM; } @@ -276,6 +278,37 @@ } /** + * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of + * the expected size. + * Returns 0 on success. + */ +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) +{ + const struct drm_color_lut *lut = NULL; + uint32_t size = 0; + + lut = __extract_blob_lut(crtc_state->degamma_lut, &size); + if (lut && size != MAX_COLOR_LUT_ENTRIES) { + DRM_DEBUG_DRIVER( + "Invalid Degamma LUT size. Should be %u but got %u.\n", + MAX_COLOR_LUT_ENTRIES, size); + return -EINVAL; + } + + lut = __extract_blob_lut(crtc_state->gamma_lut, &size); + if (lut && size != MAX_COLOR_LUT_ENTRIES && + size != MAX_COLOR_LEGACY_LUT_ENTRIES) { + DRM_DEBUG_DRIVER( + "Invalid Gamma LUT size. Should be %u (or %u for legacy) but got %u.\n", + MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES, + size); + return -EINVAL; + } + + return 0; +} + +/** * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream. * @crtc: amdgpu_dm crtc state * @@ -309,14 +342,12 @@ bool is_legacy; int r; - degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size); - if (degamma_lut && degamma_size != MAX_COLOR_LUT_ENTRIES) - return -EINVAL; + r = amdgpu_dm_verify_lut_sizes(&crtc->base); + if (r) + return r; + degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size); regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, ®amma_size); - if (regamma_lut && regamma_size != MAX_COLOR_LUT_ENTRIES && - regamma_size != MAX_COLOR_LEGACY_LUT_ENTRIES) - return -EINVAL; has_degamma = degamma_lut && !__is_lut_linear(degamma_lut, degamma_size); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -113,7 +113,7 @@ mutex_lock(&adev->dm.dc_lock); /* Enable CRTC CRC generation if necessary. */ - if (dm_is_crc_source_crtc(source)) { + if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state, enable, enable)) { ret = -EINVAL; @@ -221,6 +221,14 @@ ret = -EINVAL; goto cleanup; } + + if ((aconn->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) && + (aconn->base.connector_type != DRM_MODE_CONNECTOR_eDP)) { + DRM_DEBUG_DRIVER("No DP connector available for CRC source\n"); + ret = -EINVAL; + goto cleanup; + } + } if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -95,29 +95,29 @@ rd_buf_ptr = rd_buf; - str_len = strlen("Current: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Current: %d %d %d ", + str_len = strlen("Current: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ", link->cur_link_settings.lane_count, link->cur_link_settings.link_rate, link->cur_link_settings.link_spread); rd_buf_ptr += str_len; - str_len = strlen("Verified: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Verified: %d %d %d ", + str_len = strlen("Verified: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ", link->verified_link_cap.lane_count, link->verified_link_cap.link_rate, link->verified_link_cap.link_spread); rd_buf_ptr += str_len; - str_len = strlen("Reported: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Reported: %d %d %d ", + str_len = strlen("Reported: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ", link->reported_link_cap.lane_count, link->reported_link_cap.link_rate, link->reported_link_cap.link_spread); rd_buf_ptr += str_len; - str_len = strlen("Preferred: %d %d %d "); - snprintf(rd_buf_ptr, str_len, "Preferred: %d %d %d\n", + str_len = strlen("Preferred: %d 0x%x %d "); + snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n", link->preferred_link_setting.lane_count, link->preferred_link_setting.link_rate, link->preferred_link_setting.link_spread); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -247,7 +247,8 @@ drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port); } - ret = drm_dp_update_payload_part1(mst_mgr); + /* It's OK for this to fail */ + drm_dp_update_payload_part1(mst_mgr); /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or * AUX message. The sequence is slot 1-63 allocated sequence for each @@ -256,9 +257,6 @@ get_payload_table(aconnector, proposed_table); - if (ret) - return false; - return true; } @@ -316,7 +314,6 @@ struct amdgpu_dm_connector *aconnector; struct drm_dp_mst_topology_mgr *mst_mgr; struct drm_dp_mst_port *mst_port; - int ret; aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; @@ -330,10 +327,8 @@ if (!mst_mgr->mst_state) return false; - ret = drm_dp_update_payload_part2(mst_mgr); - - if (ret) - return false; + /* It's OK for this to fail */ + drm_dp_update_payload_part2(mst_mgr); if (!enable) drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -101,7 +101,7 @@ result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, &operation_result); - if (payload.write) + if (payload.write && result >= 0) result = msg->size; if (result < 0) @@ -379,6 +379,7 @@ aconnector->dc_sink); dc_sink_release(aconnector->dc_sink); aconnector->dc_sink = NULL; + aconnector->dc_link->cur_link_settings.lane_count = 0; } drm_connector_unregister(connector); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c @@ -342,7 +342,8 @@ if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->get_clock_by_type) { if (adev->powerplay.pp_funcs->get_clock_by_type(pp_handle, dc_to_pp_clock_type(clk_type), &pp_clks)) { - /* Error in pplib. Provide default values. */ + /* Error in pplib. Provide default values. */ + get_default_clock_levels(clk_type, dc_clks); return true; } } else if (adev->smu.funcs && adev->smu.funcs->get_clock_by_type) { @@ -529,6 +530,8 @@ &pp_clk_info); else if (adev->smu.funcs) ret = smu_get_current_clocks(&adev->smu, &pp_clk_info); + else + return false; if (ret) return false; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -2543,7 +2543,6 @@ /* Sort voltage table from low to high*/ if (result == BP_RESULT_OK) { - struct clock_voltage_caps temp = {0, 0}; uint32_t i; uint32_t j; @@ -2553,10 +2552,8 @@ info->disp_clk_voltage[j].max_supported_clk < info->disp_clk_voltage[j-1].max_supported_clk) { /* swap j and j - 1*/ - temp = info->disp_clk_voltage[j-1]; - info->disp_clk_voltage[j-1] = - info->disp_clk_voltage[j]; - info->disp_clk_voltage[j] = temp; + swap(info->disp_clk_voltage[j - 1], + info->disp_clk_voltage[j]); } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -1613,8 +1613,6 @@ struct atom_common_table_header *header; struct atom_data_revision revision; - - struct clock_voltage_caps temp = {0, 0}; uint32_t i; uint32_t j; @@ -1644,10 +1642,8 @@ info->disp_clk_voltage[j-1].max_supported_clk ) { /* swap j and j - 1*/ - temp = info->disp_clk_voltage[j-1]; - info->disp_clk_voltage[j-1] = - info->disp_clk_voltage[j]; - info->disp_clk_voltage[j] = temp; + swap(info->disp_clk_voltage[j - 1], + info->disp_clk_voltage[j]); } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -245,6 +245,23 @@ cntl->enable_dp_audio); params.ucLaneNum = (uint8_t)(cntl->lanes_number); + switch (cntl->color_depth) { + case COLOR_DEPTH_888: + params.ucBitPerColor = PANEL_8BIT_PER_COLOR; + break; + case COLOR_DEPTH_101010: + params.ucBitPerColor = PANEL_10BIT_PER_COLOR; + break; + case COLOR_DEPTH_121212: + params.ucBitPerColor = PANEL_12BIT_PER_COLOR; + break; + case COLOR_DEPTH_161616: + params.ucBitPerColor = PANEL_16BIT_PER_COLOR; + break; + default: + break; + } + if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) result = BP_RESULT_OK; @@ -274,6 +291,23 @@ cntl->enable_dp_audio)); params.ucLaneNum = (uint8_t)(cntl->lanes_number); + switch (cntl->color_depth) { + case COLOR_DEPTH_888: + params.ucBitPerColor = PANEL_8BIT_PER_COLOR; + break; + case COLOR_DEPTH_101010: + params.ucBitPerColor = PANEL_10BIT_PER_COLOR; + break; + case COLOR_DEPTH_121212: + params.ucBitPerColor = PANEL_12BIT_PER_COLOR; + break; + case COLOR_DEPTH_161616: + params.ucBitPerColor = PANEL_16BIT_PER_COLOR; + break; + default: + break; + } + if (EXEC_BIOS_CMD_TABLE(DIGxEncoderControl, params)) result = BP_RESULT_OK; @@ -1057,6 +1091,19 @@ * driver choose program it itself, i.e. here we program it * to 888 by default. */ + if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) + switch (bp_params->color_depth) { + case TRANSMITTER_COLOR_DEPTH_30: + /* yes this is correct, the atom define is wrong */ + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP; + break; + case TRANSMITTER_COLOR_DEPTH_36: + /* yes this is correct, the atom define is wrong */ + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; + break; + default: + break; + } if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) result = BP_RESULT_OK; @@ -1135,6 +1182,20 @@ * driver choose program it itself, i.e. here we pass required * target rate that includes deep color. */ + if (bp_params->signal_type == SIGNAL_TYPE_HDMI_TYPE_A) + switch (bp_params->color_depth) { + case TRANSMITTER_COLOR_DEPTH_30: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6; + break; + case TRANSMITTER_COLOR_DEPTH_36: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6; + break; + case TRANSMITTER_COLOR_DEPTH_48: + clk.sPCLKInput.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; + break; + default: + break; + } if (EXEC_BIOS_CMD_TABLE(SetPixelClock, clk)) result = BP_RESULT_OK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/calcs/bw_fixed.c @@ -26,12 +26,12 @@ #include "bw_fixed.h" -#define MIN_I64 \ - (int64_t)(-(1LL << 63)) - #define MAX_I64 \ (int64_t)((1ULL << 63) - 1) +#define MIN_I64 \ + (-MAX_I64 - 1) + #define FRACTIONAL_PART_MASK \ ((1ULL << BW_FIXED_BITS_PER_FRACTIONAL_PART) - 1) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -1438,6 +1438,7 @@ struct dc_context *ctx = dc->ctx; struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0}; bool res; + unsigned vmin0p65_idx, vmid0p72_idx, vnom0p8_idx, vmax0p9_idx; /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */ res = dm_pp_get_clock_levels_by_type_with_voltage( @@ -1449,17 +1450,28 @@ res = verify_clock_values(&fclks); if (res) { - ASSERT(fclks.num_levels >= 3); - dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 32 * (fclks.data[0].clocks_in_khz / 1000.0) / 1000.0; - dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels * - (fclks.data[fclks.num_levels - (fclks.num_levels > 2 ? 3 : 2)].clocks_in_khz / 1000.0) - * ddr4_dram_factor_single_Channel / 1000.0; - dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc->number_of_channels * - (fclks.data[fclks.num_levels - 2].clocks_in_khz / 1000.0) - * ddr4_dram_factor_single_Channel / 1000.0; - dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc->number_of_channels * - (fclks.data[fclks.num_levels - 1].clocks_in_khz / 1000.0) - * ddr4_dram_factor_single_Channel / 1000.0; + ASSERT(fclks.num_levels); + + vmin0p65_idx = 0; + vmid0p72_idx = fclks.num_levels - + (fclks.num_levels > 2 ? 3 : (fclks.num_levels > 1 ? 2 : 1)); + vnom0p8_idx = fclks.num_levels - (fclks.num_levels > 1 ? 2 : 1); + vmax0p9_idx = fclks.num_levels - 1; + + dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = + 32 * (fclks.data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0; + dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = + dc->dcn_soc->number_of_channels * + (fclks.data[vmid0p72_idx].clocks_in_khz / 1000.0) + * ddr4_dram_factor_single_Channel / 1000.0; + dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = + dc->dcn_soc->number_of_channels * + (fclks.data[vnom0p8_idx].clocks_in_khz / 1000.0) + * ddr4_dram_factor_single_Channel / 1000.0; + dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = + dc->dcn_soc->number_of_channels * + (fclks.data[vmax0p9_idx].clocks_in_khz / 1000.0) + * ddr4_dram_factor_single_Channel / 1000.0; } else BREAK_TO_DEBUGGER(); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile @@ -91,6 +91,12 @@ ############################################################################### CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o +# prevent build errors regarding soft-float vs hard-float FP ABI tags +# this code is currently unused on ppc64, as it applies to Renoir APUs only +ifdef CONFIG_PPC64 +CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call cc-option,-mno-gnu-attribute) +endif + AMD_DAL_CLK_MGR_DCN21 = $(addprefix $(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21)) AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn10/rv1_clk_mgr.c @@ -85,12 +85,77 @@ return disp_clk_threshold; } -static void ramp_up_dispclk_with_dpp(struct clk_mgr_internal *clk_mgr, struct dc *dc, struct dc_clocks *new_clocks) +static void ramp_up_dispclk_with_dpp( + struct clk_mgr_internal *clk_mgr, + struct dc *dc, + struct dc_clocks *new_clocks, + bool safe_to_lower) { int i; int dispclk_to_dpp_threshold = rv1_determine_dppclk_threshold(clk_mgr, new_clocks); bool request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz; + /* this function is to change dispclk, dppclk and dprefclk according to + * bandwidth requirement. Its call stack is rv1_update_clocks --> + * update_clocks --> dcn10_prepare_bandwidth / dcn10_optimize_bandwidth + * --> prepare_bandwidth / optimize_bandwidth. before change dcn hw, + * prepare_bandwidth will be called first to allow enough clock, + * watermark for change, after end of dcn hw change, optimize_bandwidth + * is executed to lower clock to save power for new dcn hw settings. + * + * below is sequence of commit_planes_for_stream: + * + * step 1: prepare_bandwidth - raise clock to have enough bandwidth + * step 2: lock_doublebuffer_enable + * step 3: pipe_control_lock(true) - make dchubp register change will + * not take effect right way + * step 4: apply_ctx_for_surface - program dchubp + * step 5: pipe_control_lock(false) - dchubp register change take effect + * step 6: optimize_bandwidth --> dc_post_update_surfaces_to_stream + * for full_date, optimize clock to save power + * + * at end of step 1, dcn clocks (dprefclk, dispclk, dppclk) may be + * changed for new dchubp configuration. but real dcn hub dchubps are + * still running with old configuration until end of step 5. this need + * clocks settings at step 1 should not less than that before step 1. + * this is checked by two conditions: 1. if (should_set_clock(safe_to_lower + * , new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) || + * new_clocks->dispclk_khz == clk_mgr_base->clks.dispclk_khz) + * 2. request_dpp_div = new_clocks->dispclk_khz > new_clocks->dppclk_khz + * + * the second condition is based on new dchubp configuration. dppclk + * for new dchubp may be different from dppclk before step 1. + * for example, before step 1, dchubps are as below: + * pipe 0: recout=(0,40,1920,980) viewport=(0,0,1920,979) + * pipe 1: recout=(0,0,1920,1080) viewport=(0,0,1920,1080) + * for dppclk for pipe0 need dppclk = dispclk + * + * new dchubp pipe split configuration: + * pipe 0: recout=(0,0,960,1080) viewport=(0,0,960,1080) + * pipe 1: recout=(960,0,960,1080) viewport=(960,0,960,1080) + * dppclk only needs dppclk = dispclk /2. + * + * dispclk, dppclk are not lock by otg master lock. they take effect + * after step 1. during this transition, dispclk are the same, but + * dppclk is changed to half of previous clock for old dchubp + * configuration between step 1 and step 6. This may cause p-state + * warning intermittently. + * + * for new_clocks->dispclk_khz == clk_mgr_base->clks.dispclk_khz, we + * need make sure dppclk are not changed to less between step 1 and 6. + * for new_clocks->dispclk_khz > clk_mgr_base->clks.dispclk_khz, + * new display clock is raised, but we do not know ratio of + * new_clocks->dispclk_khz and clk_mgr_base->clks.dispclk_khz, + * new_clocks->dispclk_khz /2 does not guarantee equal or higher than + * old dppclk. we could ignore power saving different between + * dppclk = displck and dppclk = dispclk / 2 between step 1 and step 6. + * as long as safe_to_lower = false, set dpclk = dispclk to simplify + * condition check. + * todo: review this change for other asic. + **/ + if (!safe_to_lower) + request_dpp_div = false; + /* set disp clk to dpp clk threshold */ clk_mgr->funcs->set_dispclk(clk_mgr, dispclk_to_dpp_threshold); @@ -206,7 +271,7 @@ /* program dispclk on = as a w/a for sleep resume clock ramping issues */ if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz) || new_clocks->dispclk_khz == clk_mgr_base->clks.dispclk_khz) { - ramp_up_dispclk_with_dpp(clk_mgr, dc, new_clocks); + ramp_up_dispclk_with_dpp(clk_mgr, dc, new_clocks, safe_to_lower); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; send_request_to_lower = true; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -320,6 +320,8 @@ struct dc_state *context, bool safe_to_lower) { + struct clk_mgr_internal *clk_mgr_int = TO_CLK_MGR_INTERNAL(clk_mgr); + struct dc_clocks *new_clocks = &context->bw_ctx.bw.dcn.clk; /* Min fclk = 1.2GHz since all the extra scemi logic seems to run off of it */ int fclk_adj = new_clocks->fclk_khz > 1200000 ? new_clocks->fclk_khz : 1200000; @@ -357,14 +359,18 @@ clk_mgr->clks.dispclk_khz = new_clocks->dispclk_khz; } - /* Both fclk and dppclk ref are run on the same scemi clock so we - * need to keep the same value for both + /* Both fclk and ref_dppclk run on the same scemi clock. + * So take the higher value since the DPP DTO is typically programmed + * such that max dppclk is 1:1 with ref_dppclk. */ if (clk_mgr->clks.fclk_khz > clk_mgr->clks.dppclk_khz) clk_mgr->clks.dppclk_khz = clk_mgr->clks.fclk_khz; if (clk_mgr->clks.dppclk_khz > clk_mgr->clks.fclk_khz) clk_mgr->clks.fclk_khz = clk_mgr->clks.dppclk_khz; + // Both fclk and ref_dppclk run on the same scemi clock. + clk_mgr_int->dccg->ref_dppclk = clk_mgr->clks.fclk_khz; + dm_set_dcn_clocks(clk_mgr->ctx, &clk_mgr->clks); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -91,8 +91,23 @@ rn_vbios_smu_set_min_deep_sleep_dcfclk(clk_mgr, clk_mgr_base->clks.dcfclk_deep_sleep_khz); } - if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr->base.clks.dppclk_khz)) { - if (clk_mgr->base.clks.dppclk_khz > new_clocks->dppclk_khz) + // workaround: Limit dppclk to 100Mhz to avoid lower eDP panel switch to plus 4K monitor underflow. + if (!IS_DIAG_DC(dc->ctx->dce_environment)) { + if (new_clocks->dppclk_khz < 100000) + new_clocks->dppclk_khz = 100000; + } + + /* + * Temporally ignore thew 0 cases for disp and dpp clks. + * We may have a new feature that requires 0 clks in the future. + */ + if (new_clocks->dppclk_khz == 0 || new_clocks->dispclk_khz == 0) { + new_clocks->dppclk_khz = clk_mgr_base->clks.dppclk_khz; + new_clocks->dispclk_khz = clk_mgr_base->clks.dispclk_khz; + } + + if (should_set_clock(safe_to_lower, new_clocks->dppclk_khz, clk_mgr_base->clks.dppclk_khz)) { + if (clk_mgr_base->clks.dppclk_khz > new_clocks->dppclk_khz) dpp_clock_lowered = true; clk_mgr_base->clks.dppclk_khz = new_clocks->dppclk_khz; update_dppclk = true; @@ -438,7 +453,8 @@ ranges->reader_wm_sets[num_valid_sets].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; /* Modify previous watermark range to cover up to max */ - ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; + if (num_valid_sets > 0) + ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX; } num_valid_sets++; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr_vbios_smu.c @@ -33,7 +33,7 @@ #include "mp/mp_12_0_0_sh_mask.h" #define REG(reg_name) \ - (MP1_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) + (MP0_BASE.instance[0].segment[mm ## reg_name ## _BASE_IDX] + mm ## reg_name) #define FN(reg_name, field) \ FD(reg_name##__##field) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -283,6 +283,8 @@ int i = 0; bool ret = false; + stream->adjust = *adjust; + for (i = 0; i < MAX_PIPES; i++) { struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; @@ -905,15 +907,11 @@ /* set first pipe with plane as master */ for (j = 0; j < group_size; j++) { - struct pipe_ctx *temp; - if (pipe_set[j]->plane_state) { if (j == 0) break; - temp = pipe_set[0]; - pipe_set[0] = pipe_set[j]; - pipe_set[j] = temp; + swap(pipe_set[0], pipe_set[j]); break; } } @@ -1180,6 +1178,26 @@ return (result == DC_OK); } +static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) +{ + int i; + struct pipe_ctx *pipe; + + for (i = 0; i < MAX_PIPES; i++) { + pipe = &context->res_ctx.pipe_ctx[i]; + + if (!pipe->plane_state) + continue; + + /* Must set to false to start with, due to OR in update function */ + pipe->plane_state->status.is_flip_pending = false; + dc->hwss.update_pending_status(pipe); + if (pipe->plane_state->status.is_flip_pending) + return true; + } + return false; +} + bool dc_post_update_surfaces_to_stream(struct dc *dc) { int i; @@ -1190,6 +1208,9 @@ post_surface_trace(dc); + if (is_flip_pending_in_pipes(dc, context)) + return true; + for (i = 0; i < dc->res_pool->pipe_count; i++) if (context->res_ctx.pipe_ctx[i].stream == NULL || context->res_ctx.pipe_ctx[i].plane_state == NULL) { @@ -1940,7 +1961,8 @@ if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); - dc->hwss.optimize_bandwidth(dc, dc->current_state); + dc->optimized_required = true; + } else { if (!dc->optimize_seamless_boot) dc->hwss.prepare_bandwidth(dc, dc->current_state); @@ -2028,6 +2050,10 @@ plane_state->triplebuffer_flips = true; } } + if (update_type == UPDATE_TYPE_FULL) { + /* force vsync flip when reconfiguring pipes to prevent underflow */ + plane_state->flip_immediate = false; + } } } #endif @@ -2152,7 +2178,7 @@ enum surface_update_type update_type; struct dc_state *context; struct dc_context *dc_ctx = dc->ctx; - int i; + int i, j; stream_status = dc_stream_get_status(stream); context = dc->current_state; @@ -2190,10 +2216,29 @@ copy_surface_update_to_plane(surface, &srf_updates[i]); + if (update_type >= UPDATE_TYPE_MED) { + for (j = 0; j < dc->res_pool->pipe_count; j++) { + struct pipe_ctx *pipe_ctx = + &context->res_ctx.pipe_ctx[j]; + + if (pipe_ctx->plane_state != surface) + continue; + + resource_build_scaling_params(pipe_ctx); + } + } } copy_stream_update_to_stream(dc, context, stream, stream_update); + if (update_type > UPDATE_TYPE_FAST) { + if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { + DC_ERROR("Mode validation failed for stream update!\n"); + dc_release_state(context); + return; + } + } + commit_planes_for_stream( dc, srf_updates, @@ -2267,12 +2312,7 @@ enum dc_acpi_cm_power_state power_state) { struct kref refcount; - struct display_mode_lib *dml = kzalloc(sizeof(struct display_mode_lib), - GFP_KERNEL); - - ASSERT(dml); - if (!dml) - return; + struct display_mode_lib *dml; switch (power_state) { case DC_ACPI_CM_POWER_STATE_D0: @@ -2294,6 +2334,12 @@ * clean state, and dc hw programming optimizations will not * cause any trouble. */ + dml = kzalloc(sizeof(struct display_mode_lib), + GFP_KERNEL); + + ASSERT(dml); + if (!dml) + return; /* Preserve refcount */ refcount = dc->current_state->refcount; @@ -2307,10 +2353,10 @@ dc->current_state->refcount = refcount; dc->current_state->bw_ctx.dml = *dml; + kfree(dml); + break; } - - kfree(dml); } void dc_resume(struct dc *dc) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -92,8 +92,8 @@ { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, { COLOR_SPACE_YCBCR2020_TYPE, - { 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2, - 0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} }, + { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2, + 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }, { COLOR_SPACE_YCBCR709_BLACK_TYPE, { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} }, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -373,7 +373,7 @@ if (GPIO_RESULT_OK != dal_ddc_open( ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C)) { - dal_gpio_destroy_ddc(&ddc); + dal_ddc_close(ddc); return present; } @@ -809,8 +809,8 @@ } case SIGNAL_TYPE_EDP: { - read_edp_current_link_settings_on_detect(link); detect_edp_sink_caps(link); + read_edp_current_link_settings_on_detect(link); sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C_OVER_AUX; sink_caps.signal = SIGNAL_TYPE_EDP; @@ -936,6 +936,24 @@ dc_is_dvi_signal(link->connector_signal)) { if (prev_sink != NULL) dc_sink_release(prev_sink); + link_disconnect_sink(link); + + return false; + } + /* + * Abort detection for DP connectors if we have + * no EDID and connector is active converter + * as there are no display downstream + * + */ + if (dc_is_dp_sst_signal(link->connector_signal) && + (link->dpcd_caps.dongle_type == + DISPLAY_DONGLE_DP_VGA_CONVERTER || + link->dpcd_caps.dongle_type == + DISPLAY_DONGLE_DP_DVI_CONVERTER)) { + if (prev_sink) + dc_sink_release(prev_sink); + link_disconnect_sink(link); return false; } @@ -948,8 +966,7 @@ same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid); if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT && - sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX && - reason != DETECT_REASON_HPDRX) { + sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) { /* * TODO debug why Dell 2413 doesn't like * two link trainings @@ -1304,6 +1321,11 @@ goto ddc_create_fail; } + if (!link->ddc->ddc_pin) { + DC_ERROR("Failed to get I2C info for connector!\n"); + goto ddc_create_fail; + } + link->ddc_hw_inst = dal_ddc_get_line( dal_ddc_service_get_ddc_pin(link->ddc)); @@ -1734,8 +1756,7 @@ slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A * needs to be set to 1 on every 0xA-0xC write. @@ -1753,8 +1774,7 @@ pipe_ctx->stream->link->ddc, slave_address, &offset, 1, &value, 1); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } buffer[0] = offset; @@ -1766,8 +1786,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } } } @@ -1787,8 +1806,7 @@ slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Based on DP159 specs, APPLY_RX_TX_CHANGE bit in 0x0A * needs to be set to 1 on every 0xA-0xC write. @@ -1806,8 +1824,7 @@ pipe_ctx->stream->link->ddc, slave_address, &offset, 1, &value, 1); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } buffer[0] = offset; @@ -1819,8 +1836,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } } } @@ -1838,8 +1854,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x00 to 0x23 */ buffer[0] = 0x00; @@ -1850,8 +1865,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0xff to 0x00 */ buffer[0] = 0xff; @@ -1862,10 +1876,14 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } + + return; + +i2c_write_fail: + DC_LOG_DEBUG("Set retimer failed"); } static void write_i2c_default_retimer_setting( @@ -1890,8 +1908,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1902,8 +1919,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x0B to 0xDA or 0xD8 */ buffer[0] = 0x0B; @@ -1914,8 +1930,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1926,8 +1941,7 @@ offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x0C to 0x1D or 0x91 */ buffer[0] = 0x0C; @@ -1938,8 +1952,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x0A to 0x17 */ buffer[0] = 0x0A; @@ -1950,8 +1963,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; if (is_vga_mode) { @@ -1966,8 +1978,7 @@ offset = 0x%x, reg_val = 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0x00 to 0x23 */ buffer[0] = 0x00; @@ -1978,8 +1989,7 @@ offset = 0x%x, reg_val= 0x%x, i2c_success = %d\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; /* Write offset 0xff to 0x00 */ buffer[0] = 0xff; @@ -1990,9 +2000,13 @@ offset = 0x%x, reg_val= 0x%x, i2c_success = %d end here\n", slave_address, buffer[0], buffer[1], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + goto i2c_write_fail; } + + return; + +i2c_write_fail: + DC_LOG_DEBUG("Set default retimer failed"); } static void write_i2c_redriver_setting( @@ -2021,8 +2035,7 @@ slave_address, buffer[3], buffer[4], buffer[5], buffer[6], i2c_success?1:0); if (!i2c_success) - /* Write failure */ - ASSERT(i2c_success); + DC_LOG_DEBUG("Set redriver failed"); } static void enable_link_hdmi(struct pipe_ctx *pipe_ctx) @@ -2169,8 +2182,10 @@ dp_set_fec_ready(link, false); } #endif - } else - link->link_enc->funcs->disable_output(link->link_enc, signal); + } else { + if (signal != SIGNAL_TYPE_VIRTUAL) + link->link_enc->funcs->disable_output(link->link_enc, signal); + } if (signal == SIGNAL_TYPE_DISPLAY_PORT_MST) { /* MST disable link only when no stream use the link */ @@ -2217,7 +2232,7 @@ break; } - if (dongle_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || + if (dpcd_caps->dongle_type != DISPLAY_DONGLE_DP_HDMI_CONVERTER || dongle_caps->extendedCapValid == false) return true; @@ -2276,7 +2291,7 @@ /* A hack to avoid failing any modes for EDID override feature on * topology change such as lower quality cable for DP or different dongle */ - if (link->remote_sinks[0]) + if (link->remote_sinks[0] && link->remote_sinks[0]->sink_signal == SIGNAL_TYPE_VIRTUAL) return DC_OK; /* Passive Dongle */ @@ -2917,8 +2932,12 @@ #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT if (timing->flags.DSC) { - kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel); - kbps = kbps / 160 + ((kbps % 160) ? 1 : 0); + struct fixed31_32 link_bw_kbps; + + link_bw_kbps = dc_fixpt_from_int(timing->pix_clk_100hz); + link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160); + link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, timing->dsc_cfg.bits_per_pixel); + kbps = dc_fixpt_ceil(link_bw_kbps); return kbps; } #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c @@ -126,22 +126,16 @@ struct vector payloads; }; -static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count) +static bool dal_ddc_i2c_payloads_create( + struct dc_context *ctx, + struct i2c_payloads *payloads, + uint32_t count) { - struct i2c_payloads *payloads; - - payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL); - - if (!payloads) - return NULL; - if (dal_vector_construct( &payloads->payloads, ctx, count, sizeof(struct i2c_payload))) - return payloads; - - kfree(payloads); - return NULL; + return true; + return false; } static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p) @@ -154,14 +148,12 @@ return p->payloads.count; } -static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p) +static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads *p) { - if (!p || !*p) + if (!p) return; - dal_vector_destruct(&(*p)->payloads); - kfree(*p); - *p = NULL; + dal_vector_destruct(&p->payloads); } #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -521,9 +513,13 @@ uint32_t payloads_num = write_payloads + read_payloads; + if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE) return false; + if (!payloads_num) + return false; + /*TODO: len of payload data for i2c and aux is uint8!!!!, * but we want to read 256 over i2c!!!!*/ if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) { @@ -556,23 +552,25 @@ ret = dc_link_aux_transfer_with_retries(ddc, &read_payload); } else { - struct i2c_payloads *payloads = - dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num); + struct i2c_command command = {0}; + struct i2c_payloads payloads; + + if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num)) + return false; - struct i2c_command command = { - .payloads = dal_ddc_i2c_payloads_get(payloads), - .number_of_payloads = 0, - .engine = DDC_I2C_COMMAND_ENGINE, - .speed = ddc->ctx->dc->caps.i2c_speed_in_khz }; + command.payloads = dal_ddc_i2c_payloads_get(&payloads); + command.number_of_payloads = 0; + command.engine = DDC_I2C_COMMAND_ENGINE; + command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz; dal_ddc_i2c_payloads_add( - payloads, address, write_size, write_buf, true); + &payloads, address, write_size, write_buf, true); dal_ddc_i2c_payloads_add( - payloads, address, read_size, read_buf, false); + &payloads, address, read_size, read_buf, false); command.number_of_payloads = - dal_ddc_i2c_payloads_get_count(payloads); + dal_ddc_i2c_payloads_get_count(&payloads); ret = dm_helpers_submit_i2c( ddc->ctx, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1284,6 +1284,8 @@ link->type = dc_connection_single; link->local_sink = link->remote_sinks[0]; link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT; + dc_sink_retain(link->local_sink); + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); } else if (mst_enable == true && link->type == dc_connection_single && link->remote_sinks[0] != NULL) { @@ -1914,6 +1916,9 @@ initial_link_setting; uint32_t link_bw; + if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap)) + return false; + /* search for the minimum link setting that: * 1. is supported according to the link training result * 2. could support the b/w requested by the timing @@ -2545,6 +2550,7 @@ uint8_t data, struct dc_link *link) { union dp_downstream_port_present ds_port = { .byte = data }; + memset(&link->dpcd_caps.dongle_caps, 0, sizeof(link->dpcd_caps.dongle_caps)); /* decode converter info*/ if (!ds_port.fields.PORT_PRESENT) { @@ -2691,6 +2697,7 @@ * keep receiver powered all the time.*/ case DP_BRANCH_DEVICE_ID_0010FA: case DP_BRANCH_DEVICE_ID_0080E1: + case DP_BRANCH_DEVICE_ID_00E04C: link->wa_flags.dp_keep_receiver_powered = true; break; @@ -2877,6 +2884,17 @@ sink_id.ieee_device_id, sizeof(sink_id.ieee_device_id)); + /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */ + { + uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 }; + + if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && + !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017, + sizeof(str_mbp_2017))) { + link->reported_link_cap.link_rate = 0x0c; + } + } + core_link_read_dpcd( link, DP_SINK_HW_REVISION_START, @@ -3365,7 +3383,7 @@ if (edp_config_set.bits.PANEL_MODE_EDP != panel_mode_edp) { - enum ddc_result result = DDC_RESULT_UNKNOWN; + enum dc_status result = DC_ERROR_UNEXPECTED; edp_config_set.bits.PANEL_MODE_EDP = panel_mode_edp; @@ -3375,7 +3393,7 @@ &edp_config_set.raw, sizeof(edp_config_set.raw)); - ASSERT(result == DDC_RESULT_SUCESSFULL); + ASSERT(result == DC_OK); } } DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " @@ -3490,7 +3508,14 @@ if (link_enc->funcs->fec_set_enable && link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) { if (link->fec_state == dc_link_fec_ready && enable) { - msleep(1); + /* Accord to DP spec, FEC enable sequence can first + * be transmitted anytime after 1000 LL codes have + * been transmitted on the link after link training + * completion. Using 1 lane RBR should have the maximum + * time for transmitting 1000 LL codes which is 6.173 us. + * So use 7 microseconds delay instead. + */ + udelay(7); link_enc->funcs->fec_set_enable(link_enc, true); link->fec_state = dc_link_fec_enabled; } else if (link->fec_state == dc_link_fec_enabled && !enable) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_link_hwss.c @@ -277,7 +277,8 @@ if (pipes[i].stream != NULL && !pipes[i].top_pipe && !pipes[i].prev_odm_pipe && pipes[i].stream->link != NULL && - pipes[i].stream_res.stream_enc != NULL) { + pipes[i].stream_res.stream_enc != NULL && + pipes[i].stream->link == link) { udelay(100); pipes[i].stream_res.stream_enc->funcs->dp_blank( @@ -399,6 +400,7 @@ dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom; dsc_cfg.pixel_encoding = stream->timing.pixel_encoding; dsc_cfg.color_depth = stream->timing.display_color_depth; + dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false; dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg; ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0); dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt; @@ -495,11 +497,15 @@ struct dsc_config dsc_cfg; uint8_t dsc_packed_pps[128]; + memset(&dsc_cfg, 0, sizeof(dsc_cfg)); + memset(dsc_packed_pps, 0, 128); + /* Enable DSC hw block */ dsc_cfg.pic_width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right; dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom; dsc_cfg.pixel_encoding = stream->timing.pixel_encoding; dsc_cfg.color_depth = stream->timing.display_color_depth; + dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false; dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg; DC_LOG_DSC(" "); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1315,6 +1315,9 @@ struct dc_stream_status *stream_status = NULL; struct resource_pool *pool = dc->res_pool; + if (!plane_state) + return true; + for (i = 0; i < context->stream_count; i++) if (context->streams[i] == stream) { stream_status = &context->stream_status[i]; @@ -1539,6 +1542,8 @@ bool dc_is_stream_unchanged( struct dc_stream_state *old_stream, struct dc_stream_state *stream) { + if (!old_stream || !stream) + return false; if (!are_stream_backends_same(old_stream, stream)) return false; @@ -1546,6 +1551,10 @@ if (old_stream->ignore_msa_timing_param != stream->ignore_msa_timing_param) return false; + /*compare audio info*/ + if (memcmp(&old_stream->audio_info, &stream->audio_info, sizeof(stream->audio_info)) != 0) + return false; + return true; } @@ -1639,6 +1648,9 @@ { int i, available_audio_count; + if (id == ENGINE_ID_UNKNOWN) + return NULL; + available_audio_count = pool->audio_count; for (i = 0; i < available_audio_count; i++) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -423,10 +423,10 @@ if (dwb->funcs->is_enabled(dwb)) { /* writeback pipe already enabled, only need to update */ - dc->hwss.update_writeback(dc, stream_status, wb_info); + dc->hwss.update_writeback(dc, stream_status, wb_info, dc->current_state); } else { /* Enable writeback pipe from scratch*/ - dc->hwss.enable_writeback(dc, stream_status, wb_info); + dc->hwss.enable_writeback(dc, stream_status, wb_info, dc->current_state); } } @@ -492,7 +492,7 @@ for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; - if (res_ctx->pipe_ctx[i].stream != stream) + if (res_ctx->pipe_ctx[i].stream != stream || !tg) continue; return tg->funcs->get_frame_count(tg); @@ -551,7 +551,7 @@ for (i = 0; i < MAX_PIPES; i++) { struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg; - if (res_ctx->pipe_ctx[i].stream != stream) + if (res_ctx->pipe_ctx[i].stream != stream || !tg) continue; tg->funcs->get_scanoutpos(tg, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -165,7 +165,8 @@ if (pipe_ctx->plane_state != plane_state) continue; - pipe_ctx->plane_state->status.is_flip_pending = false; + if (pipe_ctx->plane_state) + pipe_ctx->plane_state->status.is_flip_pending = false; break; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dc.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dc.h @@ -41,7 +41,7 @@ #define DC_VER "3.2.48" -#define MAX_SURFACES 3 +#define MAX_SURFACES 4 #define MAX_PLANES 6 #define MAX_STREAMS 6 #define MAX_SINKS_PER_LINK 4 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -77,6 +77,9 @@ /* notifyDMCUMsg */ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1); + REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, + 1, 80000); + return true; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c @@ -386,7 +386,7 @@ { enum gpio_result result; - if (!is_engine_available(engine)) + if ((engine == NULL) || !is_engine_available(engine)) return false; result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -546,9 +546,11 @@ switch (pix_clk_params->color_depth) { case COLOR_DEPTH_101010: actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 5) >> 2; + actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10; break; case COLOR_DEPTH_121212: actual_pixel_clock_100hz = (actual_pixel_clock_100hz * 6) >> 2; + actual_pixel_clock_100hz -= actual_pixel_clock_100hz % 10; break; case COLOR_DEPTH_161616: actual_pixel_clock_100hz = actual_pixel_clock_100hz * 2; @@ -871,6 +873,20 @@ bp_pc_params.flags.SET_EXTERNAL_REF_DIV_SRC = pll_settings->use_external_clk; + switch (pix_clk_params->color_depth) { + case COLOR_DEPTH_101010: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_30; + break; + case COLOR_DEPTH_121212: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_36; + break; + case COLOR_DEPTH_161616: + bp_pc_params.color_depth = TRANSMITTER_COLOR_DEPTH_48; + break; + default: + break; + } + if (clk_src->bios->funcs->set_pixel_clock( clk_src->bios, &bp_pc_params) != BP_RESULT_OK) return false; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -563,6 +563,7 @@ cntl.enable_dp_audio = enable_audio; cntl.pixel_clock = actual_pix_clk_khz; cntl.lanes_number = LANE_COUNT_FOUR; + cntl.color_depth = crtc_timing->display_color_depth; if (enc110->base.bp->funcs->encoder_control( enc110->base.bp, &cntl) != BP_RESULT_OK) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce/dce_transform.c @@ -429,12 +429,12 @@ clamp_max = 0x3FC0; break; case COLOR_DEPTH_101010: - /* 10bit MSB aligned on 14 bit bus '11 1111 1111 1100' */ - clamp_max = 0x3FFC; + /* 10bit MSB aligned on 14 bit bus '11 1111 1111 0000' */ + clamp_max = 0x3FF0; break; case COLOR_DEPTH_121212: - /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1111' */ - clamp_max = 0x3FFF; + /* 12bit MSB aligned on 14 bit bus '11 1111 1111 1100' */ + clamp_max = 0x3FFC; break; default: clamp_max = 0x3FC0; @@ -778,7 +778,7 @@ color_depth = COLOR_DEPTH_101010; pixel_depth = 0; expan_mode = 1; - BREAK_TO_DEBUGGER(); + DC_LOG_DC("The pixel depth %d is not valid, set COLOR_DEPTH_101010 instead.", depth); break; } @@ -792,8 +792,7 @@ if (!(xfm_dce->lb_pixel_depth_supported & depth)) { /*we should use unsupported capabilities * unless it is required by w/a*/ - DC_LOG_WARNING("%s: Capability not supported", - __func__); + DC_LOG_DC("%s: Capability not supported", __func__); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -340,7 +340,8 @@ audio_regs(2), audio_regs(3), audio_regs(4), - audio_regs(5) + audio_regs(5), + audio_regs(6), }; #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c @@ -380,6 +380,11 @@ i += increment) { if (j == hw_points - 1) break; + if (i >= TRANSFER_FUNC_POINTS) { + DC_LOG_ERROR("Index out of bounds: i=%d, TRANSFER_FUNC_POINTS=%d\n", + i, TRANSFER_FUNC_POINTS); + return false; + } rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; @@ -546,6 +551,8 @@ i += increment) { if (j == hw_points - 1) break; + if (i >= TRANSFER_FUNC_POINTS) + return false; rgb_resulted[j].red = output_tf->tf_pts.red[i]; rgb_resulted[j].green = output_tf->tf_pts.green[i]; rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -484,10 +484,13 @@ int vtaps_c = scl_data->taps.v_taps_c; int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert); int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c); - enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; - if (dpp->base.ctx->dc->debug.use_max_lb) - return mem_cfg; + if (dpp->base.ctx->dc->debug.use_max_lb) { + if (scl_data->format == PIXEL_FORMAT_420BPP8 + || scl_data->format == PIXEL_FORMAT_420BPP10) + return LB_MEMORY_CONFIG_3; + return LB_MEMORY_CONFIG_0; + } dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -840,8 +840,8 @@ hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe); - swath_bytes_horz_wc = height * blk256_height * bpe; - swath_bytes_vert_wc = width * blk256_width * bpe; + swath_bytes_horz_wc = width * blk256_height * bpe; + swath_bytes_vert_wc = height * blk256_width * bpe; *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? false : /* full 256B request */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1470,6 +1470,9 @@ { struct dpp *dpp = pipe_ctx->plane_res.dpp; + if (!stream) + return false; + if (dpp == NULL) return false; @@ -1492,8 +1495,8 @@ } else dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS); - if (stream != NULL && stream->ctx != NULL && - stream->out_transfer_func != NULL) { + if (stream->ctx && + stream->out_transfer_func) { log_tf(stream->ctx, stream->out_transfer_func, dpp->regamma_params.hw_points_num); @@ -2202,14 +2205,18 @@ &blnd_cfg.black_color); } - if (per_pixel_alpha) - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; - else - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; - blnd_cfg.overlap_only = false; blnd_cfg.global_gain = 0xff; + if (per_pixel_alpha && pipe_ctx->plane_state->global_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; + blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; + } else if (per_pixel_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + } else { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; + } + if (pipe_ctx->plane_state->global_alpha) blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value; else @@ -2898,7 +2905,9 @@ if (pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst]) { struct hubp *hubp = get_hubp_by_inst(res_pool, mpcc_inst); - res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst); + if (pipe_ctx->stream_res.tg && + pipe_ctx->stream_res.tg->funcs->is_tg_enabled(pipe_ctx->stream_res.tg)) + res_pool->mpc->funcs->wait_for_idle(res_pool->mpc, mpcc_inst); pipe_ctx->stream_res.opp->mpcc_disconnect_pending[mpcc_inst] = false; hubp->funcs->set_blank(hubp, true); } @@ -3264,13 +3273,12 @@ struct dc_clock_config clock_cfg = {0}; struct dc_clocks *current_clocks = &context->bw_ctx.bw.dcn.clk; - if (dc->clk_mgr && dc->clk_mgr->funcs->get_clock) - dc->clk_mgr->funcs->get_clock(dc->clk_mgr, - context, clock_type, &clock_cfg); - - if (!dc->clk_mgr->funcs->get_clock) + if (!dc->clk_mgr || !dc->clk_mgr->funcs->get_clock) return DC_FAIL_UNSUPPORTED_1; + dc->clk_mgr->funcs->get_clock(dc->clk_mgr, + context, clock_type, &clock_cfg); + if (clk_khz > clock_cfg.max_clock_khz) return DC_FAIL_CLK_EXCEED_MAX; @@ -3288,7 +3296,7 @@ else return DC_ERROR_UNEXPECTED; - if (dc->clk_mgr && dc->clk_mgr->funcs->update_clocks) + if (dc->clk_mgr->funcs->update_clocks) dc->clk_mgr->funcs->update_clocks(dc->clk_mgr, context, true); return DC_OK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -118,6 +118,12 @@ while (tmp_mpcc != NULL) { if (tmp_mpcc->dpp_id == dpp_id) return tmp_mpcc; + + /* avoid circular linked list */ + ASSERT(tmp_mpcc != tmp_mpcc->mpcc_bot); + if (tmp_mpcc == tmp_mpcc->mpcc_bot) + break; + tmp_mpcc = tmp_mpcc->mpcc_bot; } return NULL; @@ -193,8 +199,9 @@ /* check insert_above_mpcc exist in tree->opp_list */ struct mpcc *temp_mpcc = tree->opp_list; - while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) - temp_mpcc = temp_mpcc->mpcc_bot; + if (temp_mpcc != insert_above_mpcc) + while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) + temp_mpcc = temp_mpcc->mpcc_bot; if (temp_mpcc == NULL) return NULL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -425,6 +425,11 @@ OTG_CLOCK_ON, 1, 1, 1000); } else { + + //last chance to clear underflow, otherwise, it will always there due to clock is off. + if (optc->funcs->is_optc_underflow_occurred(optc) == true) + optc->funcs->clear_optc_underflow(optc); + REG_UPDATE_2(OTG_CLOCK_CONTROL, OTG_CLOCK_GATE_DIS, 0, OTG_CLOCK_EN, 0); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c @@ -1151,6 +1151,7 @@ bool video_large = false; bool desktop_large = false; bool dcc_disabled = false; + bool mpo_enabled = false; for (i = 0; i < context->stream_count; i++) { if (context->stream_status[i].plane_count == 0) @@ -1159,6 +1160,9 @@ if (context->stream_status[i].plane_count > 2) return DC_FAIL_UNSUPPORTED_1; + if (context->stream_status[i].plane_count > 1) + mpo_enabled = true; + for (j = 0; j < context->stream_status[i].plane_count; j++) { struct dc_plane_state *plane = context->stream_status[i].plane_states[j]; @@ -1182,6 +1186,10 @@ } } + /* Disable MPO in multi-display configurations. */ + if (context->stream_count > 1 && mpo_enabled) + return DC_FAIL_UNSUPPORTED_1; + /* * Workaround: On DCN10 there is UMC issue that causes underflow when * playing 4k video on 4k desktop with video downscaled and single channel --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c @@ -121,35 +121,35 @@ switch (packet_index) { case 0: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC0_FRAME_UPDATE, 1); + AFMT_GENERIC0_IMMEDIATE_UPDATE, 1); break; case 1: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC1_FRAME_UPDATE, 1); + AFMT_GENERIC1_IMMEDIATE_UPDATE, 1); break; case 2: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC2_FRAME_UPDATE, 1); + AFMT_GENERIC2_IMMEDIATE_UPDATE, 1); break; case 3: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC3_FRAME_UPDATE, 1); + AFMT_GENERIC3_IMMEDIATE_UPDATE, 1); break; case 4: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC4_FRAME_UPDATE, 1); + AFMT_GENERIC4_IMMEDIATE_UPDATE, 1); break; case 5: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC5_FRAME_UPDATE, 1); + AFMT_GENERIC5_IMMEDIATE_UPDATE, 1); break; case 6: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC6_FRAME_UPDATE, 1); + AFMT_GENERIC6_IMMEDIATE_UPDATE, 1); break; case 7: REG_UPDATE(AFMT_VBI_PACKET_CONTROL1, - AFMT_GENERIC7_FRAME_UPDATE, 1); + AFMT_GENERIC7_IMMEDIATE_UPDATE, 1); break; default: break; @@ -635,6 +635,12 @@ x), 26)); + // If y rounds up to integer, carry it over to x. + if (y >> 26) { + x += 1; + y = 0; + } + REG_SET_2(DP_MSE_RATE_CNTL, 0, DP_MSE_RATE_X, x, DP_MSE_RATE_Y, y); @@ -898,10 +904,10 @@ */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, 2); /* Larger delay to wait until VBLANK - use max retry of - * 10us*5000=50ms. This covers 41.7ms of minimum 24 Hz mode + + * 10us*10200=102ms. This covers 100.0ms of minimum 10 Hz mode + * a little more because we may not trust delay accuracy. */ - max_retries = DP_BLANK_MAX_RETRY * 250; + max_retries = DP_BLANK_MAX_RETRY * 501; /* disable DP stream */ REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h @@ -275,7 +275,14 @@ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_IMMEDIATE_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_IMMEDIATE_UPDATE, mask_sh),\ + SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_IMMEDIATE_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE, mask_sh),\ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, mask_sh),\ @@ -339,7 +346,14 @@ type AFMT_GENERIC2_FRAME_UPDATE;\ type AFMT_GENERIC3_FRAME_UPDATE;\ type AFMT_GENERIC4_FRAME_UPDATE;\ + type AFMT_GENERIC0_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC1_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC2_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC3_IMMEDIATE_UPDATE;\ type AFMT_GENERIC4_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC5_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC6_IMMEDIATE_UPDATE;\ + type AFMT_GENERIC7_IMMEDIATE_UPDATE;\ type AFMT_GENERIC5_FRAME_UPDATE;\ type AFMT_GENERIC6_FRAME_UPDATE;\ type AFMT_GENERIC7_FRAME_UPDATE;\ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dccg.c @@ -119,32 +119,6 @@ void dccg2_init(struct dccg *dccg) { - struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); - - // Fallthrough intentional to program all available dpp_dto's - switch (dccg_dcn->base.ctx->dc->res_pool->pipe_count) { - case 6: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[5], 1); - /* Fall through */ - case 5: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[4], 1); - /* Fall through */ - case 4: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[3], 1); - /* Fall through */ - case 3: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[2], 1); - /* Fall through */ - case 2: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[1], 1); - /* Fall through */ - case 1: - REG_UPDATE(DPPCLK_DTO_CTRL, DPPCLK_DTO_DB_EN[0], 1); - break; - default: - ASSERT(false); - break; - } } static const struct dccg_funcs dccg2_funcs = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dsc.c @@ -207,6 +207,9 @@ struct dsc_reg_values dsc_reg_vals; struct dsc_optc_config dsc_optc_cfg; + memset(&dsc_reg_vals, 0, sizeof(dsc_reg_vals)); + memset(&dsc_optc_cfg, 0, sizeof(dsc_optc_cfg)); + DC_LOG_DSC("Getting packed DSC PPS for DSC Config:"); dsc_config_log(dsc, dsc_cfg); DC_LOG_DSC("DSC Picture Parameter Set (PPS):"); @@ -348,6 +351,7 @@ dsc_reg_vals->pps.block_pred_enable = dsc_cfg->dc_dsc_cfg.block_pred_enable; dsc_reg_vals->pps.line_buf_depth = dsc_cfg->dc_dsc_cfg.linebuf_depth; dsc_reg_vals->alternate_ich_encoding_en = dsc_reg_vals->pps.dsc_version_minor == 1 ? 0 : 1; + dsc_reg_vals->ich_reset_at_eol = (dsc_cfg->is_odm || dsc_reg_vals->num_slices_h > 1) ? 0xF : 0; // TODO: in addition to validating slice height (pic height must be divisible by slice height), // see what happens when the same condition doesn't apply for slice_width/pic_width. @@ -510,7 +514,6 @@ reg_vals->pps.rc_buf_thresh[i] = reg_vals->pps.rc_buf_thresh[i] >> 6; reg_vals->rc_buffer_model_size = dsc_params->rc_buffer_model_size; - reg_vals->ich_reset_at_eol = reg_vals->num_slices_h == 1 ? 0 : 0xf; } static void dsc_write_to_registers(struct display_stream_compressor *dsc, const struct dsc_reg_values *reg_vals) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c @@ -690,6 +690,9 @@ int pair; uint16_t odd_coef, even_coef; + if (!filter) + return; + for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) { for (pair = 0; pair < tap_pairs; pair++) { even_coef = filter[phase * taps + 2 * pair]; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-17 Advanced Micro Devices, Inc. + * Copyright 2012-2021 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -179,11 +179,14 @@ else Set HUBP_VREADY_AT_OR_AFTER_VSYNC = 0 */ - if ((pipe_dest->vstartup_start - (pipe_dest->vready_offset+pipe_dest->vupdate_width - + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) { - value = 1; - } else - value = 0; + if (pipe_dest->htotal != 0) { + if ((pipe_dest->vstartup_start - (pipe_dest->vready_offset+pipe_dest->vupdate_width + + pipe_dest->vupdate_offset) / pipe_dest->htotal) <= pipe_dest->vblank_end) { + value = 1; + } else + value = 0; + } + REG_UPDATE(DCHUBP_CNTL, HUBP_VREADY_AT_OR_AFTER_VSYNC, value); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -126,7 +126,7 @@ REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0); /* This value is dependent on the hardware pipeline delay so set once per SOC */ - REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x801003c); + REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c); } void dcn20_display_init(struct dc *dc) { @@ -493,7 +493,6 @@ dpp->funcs->dpp_dppclk_control(dpp, false, false); hubp->power_gated = true; - dc->optimized_required = false; /* We're powering off, no need to optimize */ dc->hwss.plane_atomic_power_down(dc, pipe_ctx->plane_res.dpp, @@ -1103,6 +1102,25 @@ if (pipe->plane_state != NULL) flip_immediate = pipe->plane_state->flip_immediate; + if (flip_immediate && lock) { + const int TIMEOUT_FOR_FLIP_PENDING = 100000; + int i; + + for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { + if (!pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->plane_res.hubp)) + break; + udelay(1); + } + + if (pipe->bottom_pipe != NULL) { + for (i = 0; i < TIMEOUT_FOR_FLIP_PENDING; ++i) { + if (!pipe->bottom_pipe->plane_res.hubp->funcs->hubp_is_flip_pending(pipe->bottom_pipe->plane_res.hubp)) + break; + udelay(1); + } + } + } + /* In flip immediate and pipe splitting case, we need to use GSL * for synchronization. Only do setup on locking and on flip type change. */ @@ -1337,7 +1355,8 @@ static void dcn20_enable_writeback( struct dc *dc, const struct dc_stream_status *stream_status, - struct dc_writeback_info *wb_info) + struct dc_writeback_info *wb_info, + struct dc_state *context) { struct dwbc *dwb; struct mcif_wb *mcif_wb; @@ -1354,7 +1373,7 @@ optc->funcs->set_dwb_source(optc, wb_info->dwb_pipe_inst); /* set MCIF_WB buffer and arbitration configuration */ mcif_wb->funcs->config_mcif_buf(mcif_wb, &wb_info->mcif_buf_params, wb_info->dwb_params.dest_height); - mcif_wb->funcs->config_mcif_arb(mcif_wb, &dc->current_state->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]); + mcif_wb->funcs->config_mcif_arb(mcif_wb, &context->bw_ctx.bw.dcn.bw_writeback.mcif_wb_arb[wb_info->dwb_pipe_inst]); /* Enable MCIF_WB */ mcif_wb->funcs->enable_mcif(mcif_wb); /* Enable DWB */ @@ -1721,14 +1740,18 @@ pipe_ctx, &blnd_cfg.black_color); } - if (per_pixel_alpha) - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; - else - blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; - blnd_cfg.overlap_only = false; blnd_cfg.global_gain = 0xff; + if (per_pixel_alpha && pipe_ctx->plane_state->global_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN; + blnd_cfg.global_gain = pipe_ctx->plane_state->global_alpha_value; + } else if (per_pixel_alpha) { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA; + } else { + blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA; + } + if (pipe_ctx->plane_state->global_alpha) blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value; else @@ -1996,7 +2019,8 @@ REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); - REG_WRITE(REFCLK_CNTL, 0); + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); // --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c @@ -488,6 +488,12 @@ while (tmp_mpcc != NULL) { if (tmp_mpcc->dpp_id == 0xf || tmp_mpcc->dpp_id == dpp_id) return tmp_mpcc; + + /* avoid circular linked list */ + ASSERT(tmp_mpcc != tmp_mpcc->mpcc_bot); + if (tmp_mpcc == tmp_mpcc->mpcc_bot) + break; + tmp_mpcc = tmp_mpcc->mpcc_bot; } return NULL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c @@ -233,12 +233,13 @@ struct dc_crtc_timing *timing) { struct optc *optc1 = DCN10TG_FROM_TG(optc); - /* 2 pieces of memory required for up to 5120 displays, 4 for up to 8192 */ int mpcc_hactive = (timing->h_addressable + timing->h_border_left + timing->h_border_right) / opp_cnt; - int memory_mask = mpcc_hactive <= 2560 ? 0x3 : 0xf; + uint32_t memory_mask; uint32_t data_fmt = 0; + ASSERT(opp_cnt == 2); + /* TODO: In pseudocode but does not affect maximus, delete comment if we dont need on asic * REG_SET(OTG_GLOBAL_CONTROL2, 0, GLOBAL_UPDATE_LOCK_EN, 1); * Program OTG register MASTER_UPDATE_LOCK_DB_X/Y to the position before DP frame start @@ -246,9 +247,17 @@ * MASTER_UPDATE_LOCK_DB_X, 160, * MASTER_UPDATE_LOCK_DB_Y, 240); */ + + /* 2 pieces of memory required for up to 5120 displays, 4 for up to 8192, + * however, for ODM combine we can simplify by always using 4. + * To make sure there's no overlap, each instance "reserves" 2 memories and + * they are uniquely combined here. + */ + memory_mask = 0x3 << (opp_id[0] * 2) | 0x3 << (opp_id[1] * 2); + if (REG(OPTC_MEMORY_CONFIG)) REG_SET(OPTC_MEMORY_CONFIG, 0, - OPTC_MEM_SEL, memory_mask << (optc->inst * 4)); + OPTC_MEM_SEL, memory_mask); if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) data_fmt = 1; @@ -257,7 +266,6 @@ REG_UPDATE(OPTC_DATA_FORMAT_CONTROL, OPTC_DATA_FORMAT, data_fmt); - ASSERT(opp_cnt == 2); REG_SET_3(OPTC_DATA_SOURCE_SELECT, 0, OPTC_NUM_OF_INPUT_SEGMENT, 1, OPTC_SEG0_SRC_SEL, opp_id[0], @@ -287,6 +295,10 @@ *num_of_src_opp = 2; else *num_of_src_opp = 1; + + /* Work around VBIOS not updating OPTC_NUM_OF_INPUT_SEGMENT */ + if (*src_opp_id_1 == 0xf) + *num_of_src_opp = 1; } void optc2_set_dwb_source(struct timing_generator *optc, @@ -350,7 +362,7 @@ REG_UPDATE_2(OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_X, - h_blank_start - 200 - 1, + (h_blank_start - 200 - 1) / optc1->opp_count, MASTER_UPDATE_LOCK_DB_Y, v_blank_start - 1); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -269,6 +269,117 @@ .use_urgent_burst_bw = 0 }; +struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = { + .clock_limits = { + { + .state = 0, + .dcfclk_mhz = 560.0, + .fabricclk_mhz = 560.0, + .dispclk_mhz = 513.0, + .dppclk_mhz = 513.0, + .phyclk_mhz = 540.0, + .socclk_mhz = 560.0, + .dscclk_mhz = 171.0, + .dram_speed_mts = 8960.0, + }, + { + .state = 1, + .dcfclk_mhz = 694.0, + .fabricclk_mhz = 694.0, + .dispclk_mhz = 642.0, + .dppclk_mhz = 642.0, + .phyclk_mhz = 600.0, + .socclk_mhz = 694.0, + .dscclk_mhz = 214.0, + .dram_speed_mts = 11104.0, + }, + { + .state = 2, + .dcfclk_mhz = 875.0, + .fabricclk_mhz = 875.0, + .dispclk_mhz = 734.0, + .dppclk_mhz = 734.0, + .phyclk_mhz = 810.0, + .socclk_mhz = 875.0, + .dscclk_mhz = 245.0, + .dram_speed_mts = 14000.0, + }, + { + .state = 3, + .dcfclk_mhz = 1000.0, + .fabricclk_mhz = 1000.0, + .dispclk_mhz = 1100.0, + .dppclk_mhz = 1100.0, + .phyclk_mhz = 810.0, + .socclk_mhz = 1000.0, + .dscclk_mhz = 367.0, + .dram_speed_mts = 16000.0, + }, + { + .state = 4, + .dcfclk_mhz = 1200.0, + .fabricclk_mhz = 1200.0, + .dispclk_mhz = 1284.0, + .dppclk_mhz = 1284.0, + .phyclk_mhz = 810.0, + .socclk_mhz = 1200.0, + .dscclk_mhz = 428.0, + .dram_speed_mts = 16000.0, + }, + /*Extra state, no dispclk ramping*/ + { + .state = 5, + .dcfclk_mhz = 1200.0, + .fabricclk_mhz = 1200.0, + .dispclk_mhz = 1284.0, + .dppclk_mhz = 1284.0, + .phyclk_mhz = 810.0, + .socclk_mhz = 1200.0, + .dscclk_mhz = 428.0, + .dram_speed_mts = 16000.0, + }, + }, + .num_states = 5, + .sr_exit_time_us = 11.6, + .sr_enter_plus_exit_time_us = 13.9, + .urgent_latency_us = 4.0, + .urgent_latency_pixel_data_only_us = 4.0, + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, + .urgent_latency_vm_data_only_us = 4.0, + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0, + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0, + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, + .max_avg_sdp_bw_use_normal_percent = 40.0, + .max_avg_dram_bw_use_normal_percent = 40.0, + .writeback_latency_us = 12.0, + .ideal_dram_bw_after_urgent_percent = 40.0, + .max_request_size_bytes = 256, + .dram_channel_width_bytes = 2, + .fabric_datapath_to_dcn_data_return_bytes = 64, + .dcn_downspread_percent = 0.5, + .downspread_percent = 0.38, + .dram_page_open_time_ns = 50.0, + .dram_rw_turnaround_time_ns = 17.5, + .dram_return_buffer_per_channel_bytes = 8192, + .round_trip_ping_latency_dcfclk_cycles = 131, + .urgent_out_of_order_return_per_channel_bytes = 256, + .channel_interleave_bytes = 256, + .num_banks = 8, + .num_chans = 8, + .vmm_page_size_bytes = 4096, + .dram_clock_change_latency_us = 404.0, + .dummy_pstate_latency_us = 5.0, + .writeback_dram_clock_change_latency_us = 23.0, + .return_bus_width_bytes = 64, + .dispclk_dppclk_vco_speed_mhz = 3850, + .xfc_bus_transport_time_us = 20, + .xfc_xbuf_latency_tolerance_us = 4, + .use_urgent_burst_bw = 0 +}; + struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 }; #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL @@ -1419,13 +1530,20 @@ static void acquire_dsc(struct resource_context *res_ctx, const struct resource_pool *pool, - struct display_stream_compressor **dsc) + struct display_stream_compressor **dsc, + int pipe_idx) { int i; ASSERT(*dsc == NULL); *dsc = NULL; + if (pool->res_cap->num_dsc == pool->res_cap->num_opp) { + *dsc = pool->dscs[pipe_idx]; + res_ctx->is_dsc_acquired[pipe_idx] = true; + return; + } + /* Find first free DSC */ for (i = 0; i < pool->res_cap->num_dsc; i++) if (!res_ctx->is_dsc_acquired[i]) { @@ -1468,7 +1586,7 @@ if (pipe_ctx->stream != dc_stream) continue; - acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc); + acquire_dsc(&dc_ctx->res_ctx, pool, &pipe_ctx->stream_res.dsc, i); /* The number of DSCs can be less than the number of pipes */ if (!pipe_ctx->stream_res.dsc) { @@ -1669,7 +1787,7 @@ next_odm_pipe->stream_res.opp = pool->opps[next_odm_pipe->pipe_idx]; #ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT if (next_odm_pipe->stream->timing.flags.DSC == 1) { - acquire_dsc(res_ctx, pool, &next_odm_pipe->stream_res.dsc); + acquire_dsc(res_ctx, pool, &next_odm_pipe->stream_res.dsc, next_odm_pipe->pipe_idx); ASSERT(next_odm_pipe->stream_res.dsc); if (next_odm_pipe->stream_res.dsc == NULL) return false; @@ -1765,7 +1883,7 @@ pipe_cnt = i; continue; } - if (!resource_are_streams_timing_synchronizable( + if (dc->debug.disable_timing_sync || !resource_are_streams_timing_synchronizable( res_ctx->pipe_ctx[pipe_cnt].stream, res_ctx->pipe_ctx[i].stream)) { synchronized_vblank = false; @@ -2114,7 +2232,7 @@ wb_arb_params->cli_watermark[k] = get_wm_writeback_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; wb_arb_params->pstate_watermark[k] = get_wm_writeback_dram_clock_change(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; } - wb_arb_params->time_per_pixel = 16.0 / context->res_ctx.pipe_ctx[i].stream->phy_pix_clk; /* 4 bit fraction, ms */ + wb_arb_params->time_per_pixel = 16.0 * 1000 / (context->res_ctx.pipe_ctx[i].stream->phy_pix_clk / 1000); /* 4 bit fraction, ms */ wb_arb_params->slice_lines = 32; wb_arb_params->arbitration_slice = 2; wb_arb_params->max_scaled_time = dcn20_calc_max_scaled_time(wb_arb_params->time_per_pixel, @@ -2157,6 +2275,7 @@ + stream->timing.v_border_bottom; dsc_cfg.pixel_encoding = stream->timing.pixel_encoding; dsc_cfg.color_depth = stream->timing.display_color_depth; + dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false; dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg; dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt; @@ -2474,6 +2593,7 @@ &context->res_ctx, dc->res_pool, pipe, hsplit_pipe)) goto validate_fail; + dcn20_build_mapped_resource(dc, context, pipe->stream); } else dcn20_split_stream_for_mpc( &context->res_ctx, dc->res_pool, @@ -2726,7 +2846,7 @@ int vlevel = 0; int pipe_split_from[MAX_PIPES]; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc(dc->res_pool->pipe_count * sizeof(display_e2e_pipe_params_st), GFP_ATOMIC); DC_LOGGER_INIT(dc->ctx->logger); BW_VAL_TRACE_COUNT(); @@ -2797,7 +2917,7 @@ voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; - if (voltage_supported && dummy_pstate_supported) { + if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) { context->bw_ctx.bw.dcn.clk.p_state_change_support = false; goto restore_dml_state; } @@ -3040,7 +3160,7 @@ static void update_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st *bb, struct pp_smu_nv_clock_table *max_clocks, unsigned int *uclk_states, unsigned int num_states) { - struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES] = {0}; + struct _vcs_dpi_voltage_scaling_st calculated_states[MAX_CLOCK_LIMIT_STATES]; int i; int num_calculated_states = 0; int min_dcfclk = 0; @@ -3048,6 +3168,8 @@ if (num_states == 0) return; + memset(calculated_states, 0, sizeof(calculated_states)); + if (dc->bb_overrides.min_dcfclk_mhz > 0) min_dcfclk = dc->bb_overrides.min_dcfclk_mhz; else @@ -3125,6 +3247,9 @@ static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb( uint32_t hw_internal_rev) { + if (ASICREV_IS_NAVI14_M(hw_internal_rev)) + return &dcn2_0_nv14_soc; + if (ASICREV_IS_NAVI12_P(hw_internal_rev)) return &dcn2_0_nv12_soc; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_stream_encoder.c @@ -492,15 +492,23 @@ DP_VID_N_MUL, n_multiply); } - /* set DIG_START to 0x1 to reset FIFO */ + /* make sure stream is disabled before resetting steer fifo */ + REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, false); + REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS, 0, 10, 5000); + /* set DIG_START to 0x1 to reset FIFO */ REG_UPDATE(DIG_FE_CNTL, DIG_START, 1); + udelay(1); /* write 0 to take the FIFO out of reset */ REG_UPDATE(DIG_FE_CNTL, DIG_START, 0); - /* switch DP encoder to CRTC data */ + /* switch DP encoder to CRTC data, but reset it the fifo first. It may happen + * that it overflows during mode transition, and sometimes doesn't recover. + */ + REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 1); + udelay(10); REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubbub.c @@ -22,6 +22,7 @@ * Authors: AMD * */ +#include #include "dm_services.h" #include "dcn20/dcn20_hubbub.h" #include "dcn21_hubbub.h" @@ -71,30 +72,39 @@ void dcn21_dchvm_init(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub1 = TO_DCN20_HUBBUB(hubbub); + uint32_t riommu_active; + int i; //Init DCHVM block REG_UPDATE(DCHVM_CTRL0, HOSTVM_INIT_REQ, 1); //Poll until RIOMMU_ACTIVE = 1 - //TODO: Figure out interval us and retry count - REG_WAIT(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, 1, 5, 100); + for (i = 0; i < 100; i++) { + REG_GET(DCHVM_RIOMMU_STAT0, RIOMMU_ACTIVE, &riommu_active); - //Reflect the power status of DCHUBBUB - REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); - - //Start rIOMMU prefetching - REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); - - // Enable dynamic clock gating - REG_UPDATE_4(DCHVM_CLK_CTRL, - HVM_DISPCLK_R_GATE_DIS, 0, - HVM_DISPCLK_G_GATE_DIS, 0, - HVM_DCFCLK_R_GATE_DIS, 0, - HVM_DCFCLK_G_GATE_DIS, 0); - - //Poll until HOSTVM_PREFETCH_DONE = 1 - //TODO: Figure out interval us and retry count - REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); + if (riommu_active) + break; + else + udelay(5); + } + + if (riommu_active) { + //Reflect the power status of DCHUBBUB + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_POWERSTATUS, 1); + + //Start rIOMMU prefetching + REG_UPDATE(DCHVM_RIOMMU_CTRL0, HOSTVM_PREFETCH_REQ, 1); + + // Enable dynamic clock gating + REG_UPDATE_4(DCHVM_CLK_CTRL, + HVM_DISPCLK_R_GATE_DIS, 0, + HVM_DISPCLK_G_GATE_DIS, 0, + HVM_DCFCLK_R_GATE_DIS, 0, + HVM_DCFCLK_G_GATE_DIS, 0); + + //Poll until HOSTVM_PREFETCH_DONE = 1 + REG_WAIT(DCHVM_RIOMMU_STAT0, HOSTVM_PREFETCH_DONE, 1, 5, 100); + } } static int hubbub21_init_dchub(struct hubbub *hubbub, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c @@ -73,32 +73,47 @@ struct _vcs_dpi_display_dlg_regs_st *dlg_attr) { struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp); - uint32_t cur_value; + uint32_t refcyc_per_vm_group_vblank; + uint32_t refcyc_per_vm_req_vblank; + uint32_t refcyc_per_vm_group_flip; + uint32_t refcyc_per_vm_req_flip; + const uint32_t uninitialized_hw_default = 0; - REG_GET(VBLANK_PARAMETERS_5, REFCYC_PER_VM_GROUP_VBLANK, &cur_value); - if (cur_value > dlg_attr->refcyc_per_vm_group_vblank) + REG_GET(VBLANK_PARAMETERS_5, + REFCYC_PER_VM_GROUP_VBLANK, &refcyc_per_vm_group_vblank); + + if (refcyc_per_vm_group_vblank == uninitialized_hw_default || + refcyc_per_vm_group_vblank > dlg_attr->refcyc_per_vm_group_vblank) REG_SET(VBLANK_PARAMETERS_5, 0, REFCYC_PER_VM_GROUP_VBLANK, dlg_attr->refcyc_per_vm_group_vblank); REG_GET(VBLANK_PARAMETERS_6, - REFCYC_PER_VM_REQ_VBLANK, - &cur_value); - if (cur_value > dlg_attr->refcyc_per_vm_req_vblank) + REFCYC_PER_VM_REQ_VBLANK, &refcyc_per_vm_req_vblank); + + if (refcyc_per_vm_req_vblank == uninitialized_hw_default || + refcyc_per_vm_req_vblank > dlg_attr->refcyc_per_vm_req_vblank) REG_SET(VBLANK_PARAMETERS_6, 0, REFCYC_PER_VM_REQ_VBLANK, dlg_attr->refcyc_per_vm_req_vblank); - REG_GET(FLIP_PARAMETERS_3, REFCYC_PER_VM_GROUP_FLIP, &cur_value); - if (cur_value > dlg_attr->refcyc_per_vm_group_flip) + REG_GET(FLIP_PARAMETERS_3, + REFCYC_PER_VM_GROUP_FLIP, &refcyc_per_vm_group_flip); + + if (refcyc_per_vm_group_flip == uninitialized_hw_default || + refcyc_per_vm_group_flip > dlg_attr->refcyc_per_vm_group_flip) REG_SET(FLIP_PARAMETERS_3, 0, REFCYC_PER_VM_GROUP_FLIP, dlg_attr->refcyc_per_vm_group_flip); - REG_GET(FLIP_PARAMETERS_4, REFCYC_PER_VM_REQ_FLIP, &cur_value); - if (cur_value > dlg_attr->refcyc_per_vm_req_flip) + REG_GET(FLIP_PARAMETERS_4, + REFCYC_PER_VM_REQ_FLIP, &refcyc_per_vm_req_flip); + + if (refcyc_per_vm_req_flip == uninitialized_hw_default || + refcyc_per_vm_req_flip > dlg_attr->refcyc_per_vm_req_flip) REG_SET(FLIP_PARAMETERS_4, 0, REFCYC_PER_VM_REQ_FLIP, dlg_attr->refcyc_per_vm_req_flip); REG_SET(FLIP_PARAMETERS_5, 0, REFCYC_PER_PTE_GROUP_FLIP_C, dlg_attr->refcyc_per_pte_group_flip_c); + REG_SET(FLIP_PARAMETERS_6, 0, REFCYC_PER_META_CHUNK_FLIP_C, dlg_attr->refcyc_per_meta_chunk_flip_c); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c @@ -57,6 +57,7 @@ #include "dcn20/dcn20_dccg.h" #include "dcn21_hubbub.h" #include "dcn10/dcn10_resource.h" +#include "dce110/dce110_resource.h" #include "dcn20/dcn20_dwb.h" #include "dcn20/dcn20_mmhubbub.h" @@ -246,7 +247,7 @@ .dram_channel_width_bytes = 4, .fabric_datapath_to_dcn_data_return_bytes = 32, .dcn_downspread_percent = 0.5, - .downspread_percent = 0.5, + .downspread_percent = 0.38, .dram_page_open_time_ns = 50.0, .dram_rw_turnaround_time_ns = 17.5, .dram_return_buffer_per_channel_bytes = 8192, @@ -258,7 +259,7 @@ .vmm_page_size_bytes = 4096, .dram_clock_change_latency_us = 23.84, .return_bus_width_bytes = 64, - .dispclk_dppclk_vco_speed_mhz = 3550, + .dispclk_dppclk_vco_speed_mhz = 3600, .xfc_bus_transport_time_us = 4, .xfc_xbuf_latency_tolerance_us = 4, .use_urgent_burst_bw = 1, @@ -824,6 +825,9 @@ enum dcn20_clk_src_array_id { DCN20_CLK_SRC_PLL0, DCN20_CLK_SRC_PLL1, + DCN20_CLK_SRC_PLL2, + DCN20_CLK_SRC_PLL3, + DCN20_CLK_SRC_PLL4, DCN20_CLK_SRC_TOTAL_DCN21 }; @@ -1136,6 +1140,7 @@ return &clk_src->base; } + kfree(clk_src); BREAK_TO_DEBUGGER(); return NULL; } @@ -1492,6 +1497,18 @@ dcn21_clock_source_create(ctx, ctx->dc_bios, CLOCK_SOURCE_COMBO_PHY_PLL1, &clk_src_regs[1], false); + pool->base.clock_sources[DCN20_CLK_SRC_PLL2] = + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL2, + &clk_src_regs[2], false); + pool->base.clock_sources[DCN20_CLK_SRC_PLL3] = + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL3, + &clk_src_regs[3], false); + pool->base.clock_sources[DCN20_CLK_SRC_PLL4] = + dcn21_clock_source_create(ctx, ctx->dc_bios, + CLOCK_SOURCE_COMBO_PHY_PLL4, + &clk_src_regs[4], false); pool->base.clk_src_count = DCN20_CLK_SRC_TOTAL_DCN21; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c @@ -3435,6 +3435,7 @@ mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c @@ -3467,6 +3467,7 @@ mode_lib->vba.DCCEnabledInAnyPlane = true; } } + mode_lib->vba.UrgentLatency = mode_lib->vba.UrgentLatencyPixelDataOnly; for (i = 0; i <= mode_lib->vba.soc.num_states; i++) { locals->FabricAndDRAMBandwidthPerState[i] = dml_min( mode_lib->vba.DRAMSpeedPerState[i] * mode_lib->vba.NumberOfChannels --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c @@ -78,7 +78,7 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { - unsigned int ret_val = 0; + unsigned int ret_val = 1; if (source_format == dm_444_16) { if (!is_chroma) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c @@ -54,7 +54,7 @@ static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma) { - unsigned int ret_val = 0; + unsigned int ret_val = 1; if (source_format == dm_444_16) { if (!is_chroma) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dml_common_defs.c @@ -24,7 +24,7 @@ */ #include "dml_common_defs.h" -#include "../calcs/dcn_calc_math.h" +#include "dcn_calc_math.h" #include "dml_inline_defs.h" --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h @@ -27,7 +27,7 @@ #define __DML_INLINE_DEFS_H__ #include "dml_common_defs.h" -#include "../calcs/dcn_calc_math.h" +#include "dcn_calc_math.h" #include "dml_logger.h" static inline double dml_min(double a, double b) @@ -67,11 +67,15 @@ static inline double dml_ceil(double a, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_ceil2(a, granularity); } static inline double dml_floor(double a, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_floor2(a, granularity); } @@ -97,11 +101,15 @@ static inline double dml_ceil_ex(double x, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_ceil2(x, granularity); } static inline double dml_floor_ex(double x, double granularity) { + if (granularity == 0) + return 0; return (double) dcn_bw_floor2(x, granularity); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c @@ -63,13 +63,13 @@ enum gpio_mode mode) { if (gpio->pin) { - ASSERT_CRITICAL(false); + BREAK_TO_DEBUGGER(); return GPIO_RESULT_ALREADY_OPENED; } // No action if allocation failed during gpio construct if (!gpio->hw_container.ddc) { - ASSERT_CRITICAL(false); + BREAK_TO_DEBUGGER(); return GPIO_RESULT_NON_SPECIFIC_ERROR; } gpio->mode = mode; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -53,12 +53,12 @@ */ struct gpio_service *dal_gpio_service_create( - enum dce_version dce_version_major, - enum dce_version dce_version_minor, + enum dce_version dce_version, + enum dce_environment dce_environment, struct dc_context *ctx) { struct gpio_service *service; - uint32_t index_of_id; + int32_t index_of_id; service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); @@ -67,14 +67,14 @@ return NULL; } - if (!dal_hw_translate_init(&service->translate, dce_version_major, - dce_version_minor)) { + if (!dal_hw_translate_init(&service->translate, dce_version, + dce_environment)) { BREAK_TO_DEBUGGER(); goto failure_1; } - if (!dal_hw_factory_init(&service->factory, dce_version_major, - dce_version_minor)) { + if (!dal_hw_factory_init(&service->factory, dce_version, + dce_environment)) { BREAK_TO_DEBUGGER(); goto failure_1; } @@ -114,7 +114,7 @@ return service; failure_2: - while (index_of_id) { + while (index_of_id > 0) { --index_of_id; kfree(service->busyness[index_of_id]); } @@ -242,6 +242,9 @@ enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return false; + return service->busyness[id][en]; } @@ -250,6 +253,9 @@ enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = true; } @@ -258,6 +264,9 @@ enum gpio_id id, uint32_t en) { + if (id == GPIO_ID_UNKNOWN) + return; + service->busyness[id][en] = false; } @@ -266,7 +275,7 @@ enum gpio_id id, uint32_t en) { - if (!service->busyness[id]) { + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { ASSERT_CRITICAL(false); return GPIO_RESULT_OPEN_FAILED; } @@ -280,7 +289,7 @@ enum gpio_id id, uint32_t en) { - if (!service->busyness[id]) { + if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) { ASSERT_CRITICAL(false); return GPIO_RESULT_OPEN_FAILED; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/inc/dcn_calc_math.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef _DCN_CALC_MATH_H_ +#define _DCN_CALC_MATH_H_ + +float dcn_bw_mod(const float arg1, const float arg2); +float dcn_bw_min2(const float arg1, const float arg2); +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2); +float dcn_bw_max2(const float arg1, const float arg2); +float dcn_bw_floor2(const float arg, const float significance); +float dcn_bw_floor(const float arg); +float dcn_bw_ceil2(const float arg, const float significance); +float dcn_bw_ceil(const float arg); +float dcn_bw_max3(float v1, float v2, float v3); +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5); +float dcn_bw_pow(float a, float exp); +float dcn_bw_log(float a, float b); +double dcn_bw_fabs(double a); + +#endif /* _DCN_CALC_MATH_H_ */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/inc/hw/dsc.h @@ -36,6 +36,7 @@ uint32_t pic_height; enum dc_pixel_encoding pixel_encoding; enum dc_color_depth color_depth; /* Bits per component */ + bool is_odm; struct dc_dsc_config dc_dsc_cfg; }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -321,10 +321,12 @@ struct dc_state *context); void (*update_writeback)(struct dc *dc, const struct dc_stream_status *stream_status, - struct dc_writeback_info *wb_info); + struct dc_writeback_info *wb_info, + struct dc_state *context); void (*enable_writeback)(struct dc *dc, const struct dc_stream_status *stream_status, - struct dc_writeback_info *wb_info); + struct dc_writeback_info *wb_info, + struct dc_state *context); void (*disable_writeback)(struct dc *dc, unsigned int dwb_pipe_inst); #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c @@ -299,8 +299,8 @@ pflip_int_entry(1), pflip_int_entry(2), pflip_int_entry(3), - [DC_IRQ_SOURCE_PFLIP5] = dummy_irq_entry(), - [DC_IRQ_SOURCE_PFLIP6] = dummy_irq_entry(), + pflip_int_entry(4), + pflip_int_entry(5), [DC_IRQ_SOURCE_PFLIP_UNDERLAY0] = dummy_irq_entry(), gpio_pad_int_entry(0), gpio_pad_int_entry(1), --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -168,6 +168,11 @@ .ack = NULL }; +static const struct irq_source_info_funcs vupdate_no_lock_irq_info_funcs = { + .set = NULL, + .ack = NULL +}; + #undef BASE_INNER #define BASE_INNER(seg) DMU_BASE__INST0_SEG ## seg @@ -222,12 +227,15 @@ .funcs = &pflip_irq_info_funcs\ } -#define vupdate_int_entry(reg_num)\ +/* vupdate_no_lock_int_entry maps to DC_IRQ_SOURCE_VUPDATEx, to match semantic + * of DCE's DC_IRQ_SOURCE_VUPDATEx. + */ +#define vupdate_no_lock_int_entry(reg_num)\ [DC_IRQ_SOURCE_VUPDATE1 + reg_num] = {\ IRQ_REG_ENTRY(OTG, reg_num,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_INT_EN,\ - OTG_GLOBAL_SYNC_STATUS, VUPDATE_EVENT_CLEAR),\ - .funcs = &vblank_irq_info_funcs\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_INT_EN,\ + OTG_GLOBAL_SYNC_STATUS, VUPDATE_NO_LOCK_EVENT_CLEAR),\ + .funcs = &vupdate_no_lock_irq_info_funcs\ } #define vblank_int_entry(reg_num)\ @@ -332,12 +340,12 @@ dc_underflow_int_entry(6), [DC_IRQ_SOURCE_DMCU_SCP] = dummy_irq_entry(), [DC_IRQ_SOURCE_VBIOS_SW] = dummy_irq_entry(), - vupdate_int_entry(0), - vupdate_int_entry(1), - vupdate_int_entry(2), - vupdate_int_entry(3), - vupdate_int_entry(4), - vupdate_int_entry(5), + vupdate_no_lock_int_entry(0), + vupdate_no_lock_int_entry(1), + vupdate_no_lock_int_entry(2), + vupdate_no_lock_int_entry(3), + vupdate_no_lock_int_entry(4), + vupdate_no_lock_int_entry(5), vblank_int_entry(0), vblank_int_entry(1), vblank_int_entry(2), --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/irq_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/irq_types.h @@ -163,7 +163,7 @@ }; #define DAL_VALID_IRQ_SRC_NUM(src) \ - ((src) <= DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID) + ((src) < DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID) /* Number of Page Flip IRQ Sources. */ #define DAL_PFLIP_IRQ_SRC_NUM \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/dc/os_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/dc/os_types.h @@ -57,7 +57,7 @@ * general debug capabilities * */ -#if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB) +#if defined(CONFIG_DEBUG_KERNEL_DC) && (defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)) #define ASSERT_CRITICAL(expr) do { \ if (WARN_ON(!(expr))) { \ kgdb_breakpoint(); \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/include/ddc_service_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/include/ddc_service_types.h @@ -31,6 +31,8 @@ #define DP_BRANCH_DEVICE_ID_0022B9 0x0022B9 #define DP_BRANCH_DEVICE_ID_00001A 0x00001A #define DP_BRANCH_DEVICE_ID_0080E1 0x0080e1 +#define DP_BRANCH_DEVICE_ID_90CC24 0x90CC24 +#define DP_BRANCH_DEVICE_ID_00E04C 0x00E04C enum ddc_result { DDC_RESULT_UNKNOWN = 0, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/include/fixed31_32.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/include/fixed31_32.h @@ -431,6 +431,9 @@ */ static inline struct fixed31_32 dc_fixpt_pow(struct fixed31_32 arg1, struct fixed31_32 arg2) { + if (arg1.value == 0) + return arg2.value == 0 ? dc_fixpt_one : dc_fixpt_zero; + return dc_fixpt_exp( dc_fixpt_mul( dc_fixpt_log(arg1), --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/include/gpio_service_interface.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/include/gpio_service_interface.h @@ -42,8 +42,8 @@ struct gpio **ptr); struct gpio_service *dal_gpio_service_create( - enum dce_version dce_version_major, - enum dce_version dce_version_minor, + enum dce_version dce_version, + enum dce_environment dce_environment, struct dc_context *ctx); struct gpio *dal_gpio_service_create_irq( --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -799,7 +799,7 @@ pow_buffer_ptr = -1; // reset back to no optimize ret = true; release: - kfree(coeff); + kvfree(coeff); return ret; } @@ -1486,6 +1486,7 @@ struct fixed31_32 lut2; struct fixed31_32 delta_lut; struct fixed31_32 delta_index; + const struct fixed31_32 one = dc_fixpt_from_int(1); i = 0; /* fixed_pt library has problems handling too small values */ @@ -1514,6 +1515,9 @@ } else hw_x = coordinates_x[i].x; + if (dc_fixpt_le(one, hw_x)) + hw_x = one; + norm_x = dc_fixpt_mul(norm_factor, hw_x); index = dc_fixpt_floor(norm_x); if (index < 0 || index > 255) @@ -1576,7 +1580,7 @@ struct pwl_float_data_ex *rgb = rgb_regamma; const struct hw_x_point *coord_x = coordinates_x; - build_coefficients(&coeff, true); + build_coefficients(&coeff, TRANSFER_FUNCTION_SRGB); i = 0; while (i != hw_points_num + 1) { @@ -1862,7 +1866,7 @@ kfree(rgb_regamma); rgb_regamma_alloc_fail: - kvfree(rgb_user); + kfree(rgb_user); rgb_user_alloc_fail: return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -37,8 +37,8 @@ #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65) /* Number of elements in the render times cache array */ #define RENDER_TIMES_MAX_COUNT 10 -/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ -#define BTR_EXIT_MARGIN 2000 +/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */ +#define BTR_MAX_MARGIN 2500 /* Threshold to change BTR multiplier (to avoid frequent changes) */ #define BTR_DRIFT_MARGIN 2000 /*Threshold to exit fixed refresh rate*/ @@ -131,7 +131,7 @@ v_total = div64_u64(div64_u64(((unsigned long long)( frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)), - stream->timing.h_total), 1000000); + stream->timing.h_total) + 500000, 1000000); /* v_total cannot be less than nominal */ if (v_total < stream->timing.v_total) { @@ -250,24 +250,22 @@ unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF; unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF; unsigned int frames_to_insert = 0; - unsigned int min_frame_duration_in_ns = 0; - unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us; unsigned int delta_from_mid_point_delta_in_us; - - min_frame_duration_in_ns = ((unsigned int) (div64_u64( - (1000000000ULL * 1000000), - in_out_vrr->max_refresh_in_uhz))); + unsigned int max_render_time_in_us = + in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us; /* Program BTR */ - if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) { + if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) { /* Exit Below the Range */ if (in_out_vrr->btr.btr_active) { in_out_vrr->btr.frame_counter = 0; in_out_vrr->btr.btr_active = false; } - } else if (last_render_time_in_us > max_render_time_in_us) { + } else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) { /* Enter Below the Range */ - in_out_vrr->btr.btr_active = true; + if (!in_out_vrr->btr.btr_active) { + in_out_vrr->btr.btr_active = true; + } } /* BTR set to "not active" so disengage */ @@ -322,24 +320,50 @@ /* Choose number of frames to insert based on how close it * can get to the mid point of the variable range. + * - Delta for CEIL: delta_from_mid_point_in_us_1 + * - Delta for FLOOR: delta_from_mid_point_in_us_2 */ - if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { + if (mid_point_frames_ceil && + (last_render_time_in_us / mid_point_frames_ceil) < + in_out_vrr->min_duration_in_us) { + /* Check for out of range. + * If using CEIL produces a value that is out of range, + * then we are forced to use FLOOR. + */ + frames_to_insert = mid_point_frames_floor; + } else if (mid_point_frames_floor < 2) { + /* Check if FLOOR would result in non-LFC. In this case + * choose to use CEIL + */ + frames_to_insert = mid_point_frames_ceil; + } else if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { + /* If choosing CEIL results in a frame duration that is + * closer to the mid point of the range. + * Choose CEIL + */ frames_to_insert = mid_point_frames_ceil; - delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 - - delta_from_mid_point_in_us_1; } else { + /* If choosing FLOOR results in a frame duration that is + * closer to the mid point of the range. + * Choose FLOOR + */ frames_to_insert = mid_point_frames_floor; - delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 - - delta_from_mid_point_in_us_2; } /* Prefer current frame multiplier when BTR is enabled unless it drifts * too far from the midpoint */ + if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { + delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 - + delta_from_mid_point_in_us_1; + } else { + delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 - + delta_from_mid_point_in_us_2; + } if (in_out_vrr->btr.frames_to_insert != 0 && delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) { if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) < - in_out_vrr->max_duration_in_us) && + max_render_time_in_us) && ((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) > in_out_vrr->min_duration_in_us)) frames_to_insert = in_out_vrr->btr.frames_to_insert; @@ -348,8 +372,9 @@ /* Either we've calculated the number of frames to insert, * or we need to insert min duration frames */ - if (last_render_time_in_us / frames_to_insert < - in_out_vrr->min_duration_in_us){ + if (frames_to_insert && + (last_render_time_in_us / frames_to_insert) < + in_out_vrr->min_duration_in_us){ frames_to_insert -= (frames_to_insert > 1) ? 1 : 0; } @@ -743,6 +768,10 @@ nominal_field_rate_in_uhz = mod_freesync_calc_nominal_field_rate(stream); + /* Rounded to the nearest Hz */ + nominal_field_rate_in_uhz = 1000000ULL * + div_u64(nominal_field_rate_in_uhz + 500000, 1000000); + min_refresh_in_uhz = in_config->min_refresh_in_uhz; max_refresh_in_uhz = in_config->max_refresh_in_uhz; @@ -788,6 +817,11 @@ refresh_range = in_out_vrr->max_refresh_in_uhz - in_out_vrr->min_refresh_in_uhz; + in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us - + 2 * in_out_vrr->min_duration_in_us; + if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN) + in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN; + in_out_vrr->supported = true; } @@ -799,10 +833,12 @@ 2 * in_out_vrr->min_refresh_in_uhz) in_out_vrr->btr.btr_enabled = false; + in_out_vrr->fixed.fixed_active = false; in_out_vrr->btr.btr_active = false; in_out_vrr->btr.inserted_duration_in_us = 0; in_out_vrr->btr.frames_to_insert = 0; in_out_vrr->btr.frame_counter = 0; + in_out_vrr->btr.mid_point_in_us = (in_out_vrr->min_duration_in_us + in_out_vrr->max_duration_in_us) / 2; @@ -818,6 +854,7 @@ in_out_vrr->adjust.v_total_max = stream->timing.v_total; } else if (in_out_vrr->state == VRR_STATE_ACTIVE_VARIABLE && refresh_range >= MIN_REFRESH_RANGE_IN_US) { + in_out_vrr->adjust.v_total_min = calc_v_total_from_refresh(stream, in_out_vrr->max_refresh_in_uhz); @@ -996,14 +1033,13 @@ const struct dc_stream_state *stream) { unsigned long long nominal_field_rate_in_uhz = 0; + unsigned int total = stream->timing.h_total * stream->timing.v_total; - /* Calculate nominal field rate for stream */ + /* Calculate nominal field rate for stream, rounded up to nearest integer */ nominal_field_rate_in_uhz = stream->timing.pix_clk_100hz / 10; nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL; - nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, - stream->timing.h_total); - nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, - stream->timing.v_total); + + nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, total); return nominal_field_rate_in_uhz; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h @@ -92,6 +92,7 @@ uint32_t inserted_duration_in_us; uint32_t frames_to_insert; uint32_t frame_counter; + uint32_t margin_in_us; }; struct mod_vrr_params_fixed_refresh { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h @@ -51,10 +51,10 @@ unsigned int length); void mod_stats_update_flip(struct mod_stats *mod_stats, - unsigned long timestamp_in_ns); + unsigned long long timestamp_in_ns); void mod_stats_update_vupdate(struct mod_stats *mod_stats, - unsigned long timestamp_in_ns); + unsigned long long timestamp_in_ns); void mod_stats_update_freesync(struct mod_stats *mod_stats, unsigned int v_total_min, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -85,7 +85,8 @@ //PB7 = MD0 #define MASK_VTEM_MD0__VRR_EN 0x01 #define MASK_VTEM_MD0__M_CONST 0x02 -#define MASK_VTEM_MD0__RESERVED2 0x0C +#define MASK_VTEM_MD0__QMS_EN 0x04 +#define MASK_VTEM_MD0__RESERVED2 0x08 #define MASK_VTEM_MD0__FVA_FACTOR_M1 0xF0 //MD1 @@ -94,7 +95,7 @@ //MD2 #define MASK_VTEM_MD2__BASE_REFRESH_RATE_98 0x03 #define MASK_VTEM_MD2__RB 0x04 -#define MASK_VTEM_MD2__RESERVED3 0xF8 +#define MASK_VTEM_MD2__NEXT_TFR 0xF8 //MD3 #define MASK_VTEM_MD3__BASE_REFRESH_RATE_07 0xFF --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -115,7 +115,7 @@ /* NOTE: iRAM is 256B in size */ struct iram_table_v_2 { /* flags */ - uint16_t flags; /* 0x00 U16 */ + uint16_t min_abm_backlight; /* 0x00 U16 */ /* parameters for ABM2.0 algorithm */ uint8_t min_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x02 U0.8 */ @@ -140,10 +140,10 @@ /* For reading PSR State directly from IRAM */ uint8_t psr_state; /* 0xf0 */ - uint8_t dmcu_mcp_interface_version; /* 0xf1 */ - uint8_t dmcu_abm_feature_version; /* 0xf2 */ - uint8_t dmcu_psr_feature_version; /* 0xf3 */ - uint16_t dmcu_version; /* 0xf4 */ + uint8_t dmcu_mcp_interface_version; /* 0xf1 */ + uint8_t dmcu_abm_feature_version; /* 0xf2 */ + uint8_t dmcu_psr_feature_version; /* 0xf3 */ + uint16_t dmcu_version; /* 0xf4 */ uint8_t dmcu_state; /* 0xf6 */ uint16_t blRampReduction; /* 0xf7 */ @@ -164,42 +164,43 @@ uint8_t max_reduction[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x16 U0.8 */ uint8_t bright_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x2a U2.6 */ uint8_t dark_pos_gain[NUM_AMBI_LEVEL][NUM_AGGR_LEVEL]; /* 0x3e U2.6 */ - uint8_t hybrid_factor[NUM_AGGR_LEVEL]; /* 0x52 U0.8 */ - uint8_t contrast_factor[NUM_AGGR_LEVEL]; /* 0x56 U0.8 */ - uint8_t deviation_gain[NUM_AGGR_LEVEL]; /* 0x5a U0.8 */ - uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x5e U0.8 */ - uint8_t min_knee[NUM_AGGR_LEVEL]; /* 0x63 U0.8 */ - uint8_t max_knee[NUM_AGGR_LEVEL]; /* 0x67 U0.8 */ - uint8_t pad[21]; /* 0x6b U0.8 */ + uint8_t hybrid_factor[NUM_AGGR_LEVEL]; /* 0x52 U0.8 */ + uint8_t contrast_factor[NUM_AGGR_LEVEL]; /* 0x56 U0.8 */ + uint8_t deviation_gain[NUM_AGGR_LEVEL]; /* 0x5a U0.8 */ + uint8_t iir_curve[NUM_AMBI_LEVEL]; /* 0x5e U0.8 */ + uint8_t min_knee[NUM_AGGR_LEVEL]; /* 0x63 U0.8 */ + uint8_t max_knee[NUM_AGGR_LEVEL]; /* 0x67 U0.8 */ + uint16_t min_abm_backlight; /* 0x6b U16 */ + uint8_t pad[19]; /* 0x6d U0.8 */ /* parameters for crgb conversion */ - uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */ - uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */ - uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */ + uint16_t crgb_thresh[NUM_POWER_FN_SEGS]; /* 0x80 U3.13 */ + uint16_t crgb_offset[NUM_POWER_FN_SEGS]; /* 0x90 U1.15 */ + uint16_t crgb_slope[NUM_POWER_FN_SEGS]; /* 0xa0 U4.12 */ /* parameters for custom curve */ /* thresholds for brightness --> backlight */ - uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */ + uint16_t backlight_thresholds[NUM_BL_CURVE_SEGS]; /* 0xb0 U16.0 */ /* offsets for brightness --> backlight */ - uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */ + uint16_t backlight_offsets[NUM_BL_CURVE_SEGS]; /* 0xd0 U16.0 */ /* For reading PSR State directly from IRAM */ - uint8_t psr_state; /* 0xf0 */ - uint8_t dmcu_mcp_interface_version; /* 0xf1 */ - uint8_t dmcu_abm_feature_version; /* 0xf2 */ - uint8_t dmcu_psr_feature_version; /* 0xf3 */ - uint16_t dmcu_version; /* 0xf4 */ - uint8_t dmcu_state; /* 0xf6 */ - - uint8_t dummy1; /* 0xf7 */ - uint8_t dummy2; /* 0xf8 */ - uint8_t dummy3; /* 0xf9 */ - uint8_t dummy4; /* 0xfa */ - uint8_t dummy5; /* 0xfb */ - uint8_t dummy6; /* 0xfc */ - uint8_t dummy7; /* 0xfd */ - uint8_t dummy8; /* 0xfe */ - uint8_t dummy9; /* 0xff */ + uint8_t psr_state; /* 0xf0 */ + uint8_t dmcu_mcp_interface_version; /* 0xf1 */ + uint8_t dmcu_abm_feature_version; /* 0xf2 */ + uint8_t dmcu_psr_feature_version; /* 0xf3 */ + uint16_t dmcu_version; /* 0xf4 */ + uint8_t dmcu_state; /* 0xf6 */ + + uint8_t dummy1; /* 0xf7 */ + uint8_t dummy2; /* 0xf8 */ + uint8_t dummy3; /* 0xf9 */ + uint8_t dummy4; /* 0xfa */ + uint8_t dummy5; /* 0xfb */ + uint8_t dummy6; /* 0xfc */ + uint8_t dummy7; /* 0xfd */ + uint8_t dummy8; /* 0xfe */ + uint8_t dummy9; /* 0xff */ }; #pragma pack(pop) @@ -271,7 +272,8 @@ { unsigned int set = params.set; - ram_table->flags = 0x0; + ram_table->min_abm_backlight = + cpu_to_be16(params.min_abm_backlight); ram_table->deviation_gain = 0xb3; ram_table->blRampReduction = @@ -445,6 +447,9 @@ ram_table->flags = 0x0; + ram_table->min_abm_backlight = + cpu_to_be16(params.min_abm_backlight); + ram_table->deviation_gain[0] = 0xb3; ram_table->deviation_gain[1] = 0xa8; ram_table->deviation_gain[2] = 0x98; @@ -588,6 +593,10 @@ unsigned int set = params.set; ram_table->flags = 0x0; + + ram_table->min_abm_backlight = + cpu_to_be16(params.min_abm_backlight); + for (i = 0; i < NUM_AGGR_LEVEL; i++) { ram_table->hybrid_factor[i] = abm_settings[set][i].brightness_gain; ram_table->contrast_factor[i] = abm_settings[set][i].contrast_factor; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.h @@ -38,6 +38,7 @@ unsigned int backlight_lut_array_size; unsigned int backlight_ramping_reduction; unsigned int backlight_ramping_start; + unsigned int min_abm_backlight; unsigned int set; }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/asic_reg/dce/dce_12_0_offset.h @@ -7376,6 +7376,8 @@ #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 // addressBlock: dce_dc_fmt4_dispdec // base address: 0x2000 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/atombios.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/atombios.h @@ -4107,7 +4107,7 @@ { UCHAR ucRecordType; UCHAR ucFakeEDIDLength; // = 128 means EDID length is 128 bytes, otherwise the EDID length = ucFakeEDIDLength*128 - UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. + UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements. } ATOM_FAKE_EDID_PATCH_RECORD; typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/atomfirmware.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/atomfirmware.h @@ -653,7 +653,7 @@ { struct atom_common_table_header table_header; /*the real number of this included in the structure is calcualted by using the (whole structure size - the header size)/size of atom_gpio_pin_lut */ - struct atom_gpio_pin_assignment gpio_pin[8]; + struct atom_gpio_pin_assignment gpio_pin[]; }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/discovery.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/discovery.h @@ -25,7 +25,6 @@ #define _DISCOVERY_H_ #define PSP_HEADER_SIZE 256 -#define BINARY_MAX_SIZE (64 << 10) #define BINARY_SIGNATURE 0x28211407 #define DISCOVERY_TABLE_SIGNATURE 0x53445049 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/navi10_enum.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/navi10_enum.h @@ -430,7 +430,7 @@ */ typedef enum ENUM_NUM_SIMD_PER_CU { -NUM_SIMD_PER_CU = 0x00000004, +NUM_SIMD_PER_CU = 0x00000002, } ENUM_NUM_SIMD_PER_CU; /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/include/pptable.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/include/pptable.h @@ -78,7 +78,7 @@ typedef struct _ATOM_PPLIB_STATE { UCHAR ucNonClockStateIndex; - UCHAR ucClockStateIndices[1]; // variable-sized + UCHAR ucClockStateIndices[]; // variable-sized } ATOM_PPLIB_STATE; @@ -473,7 +473,7 @@ /** * Driver will read the first ucNumDPMLevels in this array */ - UCHAR clockInfoIndex[1]; + UCHAR clockInfoIndex[]; } ATOM_PPLIB_STATE_V2; typedef struct _StateArray{ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -320,12 +320,12 @@ if (*level & profile_mode_mask) { hwmgr->saved_dpm_level = hwmgr->dpm_level; hwmgr->en_umd_pstate = true; - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, - AMD_IP_BLOCK_TYPE_GFX, - AMD_CG_STATE_UNGATE); amdgpu_device_ip_set_powergating_state(hwmgr->adev, AMD_IP_BLOCK_TYPE_GFX, AMD_PG_STATE_UNGATE); + amdgpu_device_ip_set_clockgating_state(hwmgr->adev, + AMD_IP_BLOCK_TYPE_GFX, + AMD_CG_STATE_UNGATE); } } else { /* exit umd pstate, restore level, enable gfx cg*/ @@ -1421,10 +1421,12 @@ { struct pp_hwmgr *hwmgr = handle; + *cap = false; if (!hwmgr) return -EINVAL; - if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability) + if (!(hwmgr->not_vf && amdgpu_dpm) || + !hwmgr->hwmgr_func->get_asic_baco_capability) return 0; mutex_lock(&hwmgr->smu_lock); @@ -1458,7 +1460,8 @@ if (!hwmgr) return -EINVAL; - if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state) + if (!(hwmgr->not_vf && amdgpu_dpm) || + !hwmgr->hwmgr_func->set_asic_baco_state) return 0; mutex_lock(&hwmgr->smu_lock); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c @@ -844,6 +844,7 @@ smu->smu_baco.platform_support = false; mutex_init(&smu->sensor_lock); + mutex_init(&smu->metrics_lock); smu->watermarks_bitmap = 0; smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT; @@ -1344,7 +1345,10 @@ int ret; struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct smu_context *smu = &adev->smu; - bool baco_feature_is_enabled = smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT); + bool baco_feature_is_enabled = false; + + if(!(adev->flags & AMD_IS_APU)) + baco_feature_is_enabled = smu_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT); ret = smu_system_features_control(smu, false); if (ret) @@ -1537,12 +1541,12 @@ if (*level & profile_mode_mask) { smu_dpm_ctx->saved_dpm_level = smu_dpm_ctx->dpm_level; smu_dpm_ctx->enable_umd_pstate = true; - amdgpu_device_ip_set_clockgating_state(smu->adev, - AMD_IP_BLOCK_TYPE_GFX, - AMD_CG_STATE_UNGATE); amdgpu_device_ip_set_powergating_state(smu->adev, AMD_IP_BLOCK_TYPE_GFX, AMD_PG_STATE_UNGATE); + amdgpu_device_ip_set_clockgating_state(smu->adev, + AMD_IP_BLOCK_TYPE_GFX, + AMD_CG_STATE_UNGATE); } } else { /* exit umd pstate, restore level, enable gfx cg*/ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/arcturus_ppt.c @@ -910,18 +910,21 @@ struct smu_table_context *smu_table= &smu->smu_table; int ret = 0; + mutex_lock(&smu->metrics_lock); if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)smu_table->metrics_table, false); if (ret) { pr_info("Failed to export SMU metrics table!\n"); + mutex_unlock(&smu->metrics_lock); return ret; } smu_table->metrics_time = jiffies; } memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); + mutex_unlock(&smu->metrics_lock); return ret; } @@ -1388,12 +1391,17 @@ "VR", "COMPUTE", "CUSTOM"}; + static const char *title[] = { + "PROFILE_INDEX(NAME)"}; uint32_t i, size = 0; int16_t workload_type = 0; if (!smu->pm_enabled || !buf) return -EINVAL; + size += sprintf(buf + size, "%16s\n", + title[0]); + for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { /* * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/ppatomctrl.c @@ -73,8 +73,9 @@ j++; } else if ((table->mc_reg_address[i].uc_pre_reg_data & LOW_NIBBLE_MASK) == DATA_EQU_PREV) { - table->mc_reg_table_entry[num_ranges].mc_data[i] = - table->mc_reg_table_entry[num_ranges].mc_data[i-1]; + if (i) + table->mc_reg_table_entry[num_ranges].mc_data[i] = + table->mc_reg_table_entry[num_ranges].mc_data[i-1]; } } num_ranges++; @@ -1369,6 +1370,8 @@ GetIndexIntoMasterTable(DATA, SMU_Info), &size, &frev, &crev); + if (!psmu_info) + return -EINVAL; for (i = 0; i < psmu_info->ucSclkEntryNum; i++) { table->entry[i].ucVco_setting = psmu_info->asSclkFcwRangeEntry[i].ucVco_setting; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/pptable_v1_0.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/pptable_v1_0.h @@ -164,7 +164,7 @@ typedef struct _ATOM_Tonga_State_Array { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_State entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_State entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_State_Array; typedef struct _ATOM_Tonga_MCLK_Dependency_Record { @@ -179,7 +179,7 @@ typedef struct _ATOM_Tonga_MCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_MCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_MCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_MCLK_Dependency_Table; typedef struct _ATOM_Tonga_SCLK_Dependency_Record { @@ -194,7 +194,7 @@ typedef struct _ATOM_Tonga_SCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_SCLK_Dependency_Table; typedef struct _ATOM_Polaris_SCLK_Dependency_Record { @@ -210,7 +210,7 @@ typedef struct _ATOM_Polaris_SCLK_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Polaris_SCLK_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Polaris_SCLK_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Polaris_SCLK_Dependency_Table; typedef struct _ATOM_Tonga_PCIE_Record { @@ -222,7 +222,7 @@ typedef struct _ATOM_Tonga_PCIE_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_PCIE_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_PCIE_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_PCIE_Table; typedef struct _ATOM_Polaris10_PCIE_Record { @@ -235,7 +235,7 @@ typedef struct _ATOM_Polaris10_PCIE_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Polaris10_PCIE_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Polaris10_PCIE_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Polaris10_PCIE_Table; @@ -252,7 +252,7 @@ typedef struct _ATOM_Tonga_MM_Dependency_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_MM_Dependency_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_MM_Dependency_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_MM_Dependency_Table; typedef struct _ATOM_Tonga_Voltage_Lookup_Record { @@ -265,7 +265,7 @@ typedef struct _ATOM_Tonga_Voltage_Lookup_Table { UCHAR ucRevId; UCHAR ucNumEntries; /* Number of entries. */ - ATOM_Tonga_Voltage_Lookup_Record entries[1]; /* Dynamically allocate entries. */ + ATOM_Tonga_Voltage_Lookup_Record entries[]; /* Dynamically allocate entries. */ } ATOM_Tonga_Voltage_Lookup_Table; typedef struct _ATOM_Tonga_Fan_Table { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/processpptables.c @@ -984,6 +984,32 @@ struct pp_hwmgr *hwmgr, const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table) { + hwmgr->thermal_controller.ucType = + powerplay_table->sThermalController.ucType; + hwmgr->thermal_controller.ucI2cLine = + powerplay_table->sThermalController.ucI2cLine; + hwmgr->thermal_controller.ucI2cAddress = + powerplay_table->sThermalController.ucI2cAddress; + + hwmgr->thermal_controller.fanInfo.bNoFan = + (0 != (powerplay_table->sThermalController.ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN)); + + hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution = + powerplay_table->sThermalController.ucFanParameters & + ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK; + + hwmgr->thermal_controller.fanInfo.ulMinRPM + = powerplay_table->sThermalController.ucFanMinRPM * 100UL; + hwmgr->thermal_controller.fanInfo.ulMaxRPM + = powerplay_table->sThermalController.ucFanMaxRPM * 100UL; + + set_hw_cap(hwmgr, + ATOM_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType, + PHM_PlatformCaps_ThermalController); + + hwmgr->thermal_controller.use_hw_fan_control = 1; + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -209,8 +209,7 @@ { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->need_min_deep_sleep_dcefclk && - smu10_data->deep_sleep_dcefclk != clock) { + if (clock && smu10_data->deep_sleep_dcefclk != clock) { smu10_data->deep_sleep_dcefclk = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk, @@ -223,8 +222,7 @@ { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->dcf_actual_hard_min_freq && - smu10_data->dcf_actual_hard_min_freq != clock) { + if (clock && smu10_data->dcf_actual_hard_min_freq != clock) { smu10_data->dcf_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinDcefclkByFreq, @@ -237,8 +235,7 @@ { struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend); - if (smu10_data->f_actual_hard_min_freq && - smu10_data->f_actual_hard_min_freq != clock) { + if (clock && smu10_data->f_actual_hard_min_freq != clock) { smu10_data->f_actual_hard_min_freq = clock; smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinFclkByFreq, @@ -1026,12 +1023,15 @@ clocks->num_levels = 0; for (i = 0; i < pclk_vol_table->count; i++) { - clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10; - clocks->data[i].latency_in_us = latency_required ? - smu10_get_mem_latency(hwmgr, - pclk_vol_table->entries[i].clk) : - 0; - clocks->num_levels++; + if (pclk_vol_table->entries[i].clk) { + clocks->data[clocks->num_levels].clocks_in_khz = + pclk_vol_table->entries[i].clk * 10; + clocks->data[clocks->num_levels].latency_in_us = latency_required ? + smu10_get_mem_latency(hwmgr, + pclk_vol_table->entries[i].clk) : + 0; + clocks->num_levels++; + } } return 0; @@ -1077,9 +1077,11 @@ clocks->num_levels = 0; for (i = 0; i < pclk_vol_table->count; i++) { - clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10; - clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol; - clocks->num_levels++; + if (pclk_vol_table->entries[i].clk) { + clocks->data[clocks->num_levels].clocks_in_khz = pclk_vol_table->entries[i].clk * 10; + clocks->data[clocks->num_levels].voltage_in_mv = pclk_vol_table->entries[i].vol; + clocks->num_levels++; + } } return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c @@ -1533,6 +1533,10 @@ PP_ASSERT_WITH_CODE((tmp_result == 0), "Failed to reset to default!", result = tmp_result); + tmp_result = smum_stop_smc(hwmgr); + PP_ASSERT_WITH_CODE((tmp_result == 0), + "Failed to stop smc!", result = tmp_result); + tmp_result = smu7_force_switch_to_arbf0(hwmgr); PP_ASSERT_WITH_CODE((tmp_result == 0), "Failed to force to switch arbf0!", result = tmp_result); @@ -2864,7 +2868,7 @@ if (hwmgr->is_kicker) switch_limit_us = data->is_memory_gddr5 ? 450 : 150; else - switch_limit_us = data->is_memory_gddr5 ? 190 : 150; + switch_limit_us = data->is_memory_gddr5 ? 200 : 150; break; case CHIP_VEGAM: switch_limit_us = 30; @@ -3575,7 +3579,8 @@ case AMDGPU_PP_SENSOR_GPU_POWER: return smu7_get_gpu_power(hwmgr, (uint32_t *)value); case AMDGPU_PP_SENSOR_VDDGFX: - if ((data->vr_config & 0xff) == 0x2) + if ((data->vr_config & VRCONF_VDDGFX_MASK) == + (VR_SVI2_PLANE_2 << VRCONF_VDDGFX_SHIFT)) val_vid = PHM_READ_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, PWR_SVI2_STATUS, PLANE2_VID); else @@ -3805,9 +3810,12 @@ { uint32_t i; + /* force the trim if mclk_switching is disabled to prevent flicker */ + bool force_trim = (low_limit == high_limit); for (i = 0; i < dpm_table->count; i++) { /*skip the trim if od is enabled*/ - if (!hwmgr->od_enabled && (dpm_table->dpm_levels[i].value < low_limit + if ((!hwmgr->od_enabled || force_trim) + && (dpm_table->dpm_levels[i].value < low_limit || dpm_table->dpm_levels[i].value > high_limit)) dpm_table->dpm_levels[i].enabled = false; else @@ -3983,6 +3991,13 @@ "Failed to populate and upload SCLK MCLK DPM levels!", result = tmp_result); + /* + * If a custom pp table is loaded, set DPMTABLE_OD_UPDATE_VDDC flag. + * That effectively disables AVFS feature. + */ + if (hwmgr->hardcode_pp_table != NULL) + data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; + tmp_result = smu7_update_avfs(hwmgr); PP_ASSERT_WITH_CODE((0 == tmp_result), "Failed to update avfs voltages!", --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_hwmgr.c @@ -3691,6 +3691,13 @@ PP_ASSERT_WITH_CODE(!result, "Failed to upload PPtable!", return result); + /* + * If a custom pp table is loaded, set DPMTABLE_OD_UPDATE_VDDC flag. + * That effectively disables AVFS feature. + */ + if(hwmgr->hardcode_pp_table != NULL) + data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC; + vega10_update_avfs(hwmgr); /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega10_thermal.c @@ -364,17 +364,29 @@ static int vega10_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v2_information *pp_table_info = + (struct phm_ppt_v2_information *)(hwmgr->pptable); + struct phm_tdp_table *tdp_table = pp_table_info->tdp_table; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA10_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA10_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; - if (high > range->max) - high = range->max; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + + /* + * As a common sense, usSoftwareShutdownTemp should be bigger + * than ThotspotLimit. For any invalid usSoftwareShutdownTemp, + * we will just use the max possible setting VEGA10_THERMAL_MAXIMUM_ALERT_TEMP + * to avoid false alarms. + */ + if ((tdp_table->usSoftwareShutdownTemp > + range->hotspot_crit_max / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)) { + if (high > tdp_table->usSoftwareShutdownTemp) + high = tdp_table->usSoftwareShutdownTemp; + } if (low > high) return -EINVAL; @@ -383,8 +395,8 @@ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val &= (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK) & (~THM_THERMAL_INT_CTRL__THERM_INTH_MASK_MASK) & (~THM_THERMAL_INT_CTRL__THERM_INTL_MASK_MASK); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_thermal.c @@ -170,17 +170,18 @@ static int vega12_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v3_information *pptable_information = + (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA12_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA12_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; - if (high > range->max) - high = range->max; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + if (high > pptable_information->us_software_shutdown_temp) + high = pptable_information->us_software_shutdown_temp; if (low > high) return -EINVAL; @@ -189,8 +190,8 @@ val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_baco.c @@ -29,7 +29,7 @@ #include "vega20_baco.h" #include "vega20_smumgr.h" - +#include "amdgpu_ras.h" static const struct soc15_baco_cmd_entry clean_baco_tbl[] = { @@ -74,6 +74,7 @@ int vega20_baco_set_state(struct pp_hwmgr *hwmgr, enum BACO_STATE state) { struct amdgpu_device *adev = (struct amdgpu_device *)(hwmgr->adev); + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); enum BACO_STATE cur_state; uint32_t data; @@ -84,10 +85,11 @@ return 0; if (state == BACO_STATE_IN) { - data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); - data |= 0x80000000; - WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); - + if (!ras || !ras->supported) { + data = RREG32_SOC15(THM, 0, mmTHM_BACO_CNTL); + data |= 0x80000000; + WREG32_SOC15(THM, 0, mmTHM_BACO_CNTL, data); + } if(smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_EnterBaco, 0)) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -981,27 +981,15 @@ { struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); - uint64_t features_enabled; - int i; - bool enabled; - int ret = 0; + int i, ret = 0; PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableAllSmuFeatures)) == 0, "[DisableAllSMUFeatures] Failed to disable all smu features!", return ret); - ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled); - PP_ASSERT_WITH_CODE(!ret, - "[DisableAllSMUFeatures] Failed to get enabled smc features!", - return ret); - - for (i = 0; i < GNLD_FEATURES_MAX; i++) { - enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? - true : false; - data->smu_features[i].enabled = enabled; - data->smu_features[i].supported = enabled; - } + for (i = 0; i < GNLD_FEATURES_MAX; i++) + data->smu_features[i].enabled = 0; return 0; } @@ -1652,12 +1640,6 @@ data->uvd_power_gated = true; data->vce_power_gated = true; - - if (data->smu_features[GNLD_DPM_UVD].enabled) - data->uvd_power_gated = false; - - if (data->smu_features[GNLD_DPM_VCE].enabled) - data->vce_power_gated = false; } static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr) @@ -2912,7 +2894,8 @@ data->od8_settings.od8_settings_array; OverDriveTable_t *od_table = &(data->smc_state_table.overdrive_table); - int32_t input_index, input_clk, input_vol, i; + int32_t input_clk, input_vol, i; + uint32_t input_index; int od8_id; int ret; @@ -3211,10 +3194,11 @@ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfeature_masks) { - uint64_t features_enabled; - uint64_t features_to_enable; - uint64_t features_to_disable; - int ret = 0; + struct vega20_hwmgr *data = + (struct vega20_hwmgr *)(hwmgr->backend); + uint64_t features_enabled, features_to_enable, features_to_disable; + int i, ret = 0; + bool enabled; if (new_ppfeature_masks >= (1ULL << GNLD_FEATURES_MAX)) return -EINVAL; @@ -3243,6 +3227,17 @@ return ret; } + /* Update the cached feature enablement state */ + ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled); + if (ret) + return ret; + + for (i = 0; i < GNLD_FEATURES_MAX; i++) { + enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? + true : false; + data->smu_features[i].enabled = enabled; + } + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_thermal.c @@ -240,17 +240,18 @@ static int vega20_thermal_set_temperature_range(struct pp_hwmgr *hwmgr, struct PP_TemperatureRange *range) { + struct phm_ppt_v3_information *pptable_information = + (struct phm_ppt_v3_information *)hwmgr->pptable; struct amdgpu_device *adev = hwmgr->adev; - int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; - int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP * - PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + int low = VEGA20_THERMAL_MINIMUM_ALERT_TEMP; + int high = VEGA20_THERMAL_MAXIMUM_ALERT_TEMP; uint32_t val; - if (low < range->min) - low = range->min; - if (high > range->max) - high = range->max; + /* compare them in unit celsius degree */ + if (low < range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES) + low = range->min / PP_TEMPERATURE_UNITS_PER_CENTIGRADES; + if (high > pptable_information->us_software_shutdown_temp) + high = pptable_information->us_software_shutdown_temp; if (low > high) return -EINVAL; @@ -259,8 +260,8 @@ val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5); val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1); - val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); - val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low / PP_TEMPERATURE_UNITS_PER_CENTIGRADES)); + val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, high); + val = CGS_REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, low); val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK); WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -345,6 +345,7 @@ const struct pptable_funcs *ppt_funcs; struct mutex mutex; struct mutex sensor_lock; + struct mutex metrics_lock; uint64_t pool_size; struct smu_table_context smu_table; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -229,6 +229,7 @@ bool (*is_hw_avfs_present)(struct pp_hwmgr *hwmgr); int (*update_dpm_settings)(struct pp_hwmgr *hwmgr, void *profile_setting); int (*smc_table_manager)(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw); /*rw: true for read, false for write */ + int (*stop_smc)(struct pp_hwmgr *hwmgr); }; struct pp_hwmgr_func { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -114,4 +114,6 @@ extern int smum_smc_table_manager(struct pp_hwmgr *hwmgr, uint8_t *table, uint16_t table_id, bool rw); +extern int smum_stop_smc(struct pp_hwmgr *hwmgr); + #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -547,17 +547,20 @@ struct smu_table_context *smu_table= &smu->smu_table; int ret = 0; + mutex_lock(&smu->metrics_lock); if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(100))) { ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)smu_table->metrics_table, false); if (ret) { pr_info("Failed to export SMU metrics table!\n"); + mutex_unlock(&smu->metrics_lock); return ret; } smu_table->metrics_time = jiffies; } memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); + mutex_unlock(&smu->metrics_lock); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/renoir_ppt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/renoir_ppt.c @@ -183,11 +183,14 @@ int i, size = 0, ret = 0; uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0; DpmClocks_t *clk_table = smu->smu_table.clocks_table; - SmuMetrics_t metrics = {0}; + SmuMetrics_t metrics; + bool cur_value_match_level = false; if (!clk_table || clk_type >= SMU_CLK_COUNT) return -EINVAL; + memset(&metrics, 0, sizeof(metrics)); + ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)&metrics, false); if (ret) @@ -241,8 +244,13 @@ GET_DPM_CUR_FREQ(clk_table, clk_type, i, value); size += sprintf(buf + size, "%d: %uMhz %s\n", i, value, cur_value == value ? "*" : ""); + if (cur_value == value) + cur_value_match_level = true; } + if (!cur_value_match_level) + size += sprintf(buf + size, " %uMhz *\n", cur_value); + return size; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/renoir_ppt.h +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/renoir_ppt.h @@ -37,7 +37,7 @@ freq = table->SocClocks[dpm_level].Freq; \ break; \ case SMU_MCLK: \ - freq = table->MemClocks[dpm_level].Freq; \ + freq = table->FClocks[dpm_level].Freq; \ break; \ case SMU_DCEFCLK: \ freq = table->DcfClocks[dpm_level].Freq; \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/smu_v11_0.c @@ -46,10 +46,8 @@ #include "asic_reg/smuio/smuio_11_0_0_sh_mask.h" MODULE_FIRMWARE("amdgpu/vega20_smc.bin"); -MODULE_FIRMWARE("amdgpu/arcturus_smc.bin"); MODULE_FIRMWARE("amdgpu/navi10_smc.bin"); MODULE_FIRMWARE("amdgpu/navi14_smc.bin"); -MODULE_FIRMWARE("amdgpu/navi12_smc.bin"); #define SMU11_VOLTAGE_SCALE 4 @@ -171,7 +169,8 @@ chip_name = "navi12"; break; default: - BUG(); + dev_err(adev->dev, "Unsupported ASIC type %d\n", adev->asic_type); + return -EINVAL; } snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name); @@ -988,8 +987,12 @@ struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks; int ret = 0; - max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), + if (!smu->smu_table.max_sustainable_clocks) + max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), GFP_KERNEL); + else + max_sustainable_clocks = smu->smu_table.max_sustainable_clocks; + smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks; max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/smumgr/ci_smumgr.c @@ -239,7 +239,7 @@ switch (dev_id) { case 0x67BA: - case 0x66B1: + case 0x67B1: smu_data->power_tune_defaults = &defaults_hawaii_pro; break; case 0x67B8: @@ -2933,6 +2933,29 @@ return 0; } +static void ci_reset_smc(struct pp_hwmgr *hwmgr) +{ + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, + SMC_SYSCON_RESET_CNTL, + rst_reg, 1); +} + + +static void ci_stop_smc_clock(struct pp_hwmgr *hwmgr) +{ + PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, + SMC_SYSCON_CLOCK_CNTL_0, + ck_disable, 1); +} + +static int ci_stop_smc(struct pp_hwmgr *hwmgr) +{ + ci_reset_smc(hwmgr); + ci_stop_smc_clock(hwmgr); + + return 0; +} + const struct pp_smumgr_func ci_smu_funcs = { .name = "ci_smu", .smu_init = ci_smu_init, @@ -2957,4 +2980,5 @@ .is_dpm_running = ci_is_dpm_running, .update_dpm_settings = ci_update_dpm_settings, .update_smc_table = ci_update_smc_table, + .stop_smc = ci_stop_smc, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/smumgr/smumgr.c @@ -217,3 +217,11 @@ return -EINVAL; } + +int smum_stop_smc(struct pp_hwmgr *hwmgr) +{ + if (hwmgr->smumgr_funcs->stop_smc) + return hwmgr->smumgr_funcs->stop_smc(hwmgr); + + return 0; +} --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c @@ -642,9 +642,6 @@ /* sclk is bigger than max sclk in the dependence table */ *voltage |= (dep_table->entries[i - 1].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; - vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), - (dep_table->entries[i - 1].vddc - - (uint16_t)VDDC_VDDCI_DELTA)); if (SMU7_VOLTAGE_CONTROL_NONE == data->vddci_control) *voltage |= (data->vbios_boot_state.vddci_bootup_value * @@ -652,8 +649,13 @@ else if (dep_table->entries[i - 1].vddci) *voltage |= (dep_table->entries[i - 1].vddci * VOLTAGE_SCALE) << VDDC_SHIFT; - else + else { + vddci = phm_find_closest_vddci(&(data->vddci_voltage_table), + (dep_table->entries[i - 1].vddc - + (uint16_t)VDDC_VDDCI_DELTA)); + *voltage |= (vddci * VOLTAGE_SCALE) << VDDCI_SHIFT; + } if (SMU7_VOLTAGE_CONTROL_NONE == data->mvdd_control) *mvdd = data->vbios_boot_state.mvdd_bootup_value * VOLTAGE_SCALE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/amd/powerplay/vega20_ppt.c @@ -1691,17 +1691,20 @@ struct smu_table_context *smu_table= &smu->smu_table; int ret = 0; + mutex_lock(&smu->metrics_lock); if (!smu_table->metrics_time || time_after(jiffies, smu_table->metrics_time + HZ / 1000)) { ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0, (void *)smu_table->metrics_table, false); if (ret) { pr_info("Failed to export SMU metrics table!\n"); + mutex_unlock(&smu->metrics_lock); return ret; } smu_table->metrics_time = jiffies; } memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t)); + mutex_unlock(&smu->metrics_lock); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -250,6 +250,7 @@ { komeda_crtc_prepare(to_kcrtc(crtc)); drm_crtc_vblank_on(crtc); + WARN_ON(drm_crtc_vblank_get(crtc)); komeda_crtc_do_flush(crtc, old); } @@ -319,6 +320,7 @@ } } + drm_crtc_vblank_put(crtc); drm_crtc_vblank_off(crtc); komeda_crtc_unprepare(kcrtc); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -148,6 +148,7 @@ struct drm_plane *plane; struct list_head zorder_list; int order = 0, err; + u32 slave_zpos = 0; DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n", crtc->base.id, crtc->name); @@ -187,10 +188,13 @@ plane_st->zpos, plane_st->normalized_zpos); /* calculate max slave zorder */ - if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) + if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) { + slave_zpos = plane_st->normalized_zpos; + if (to_kplane_st(plane_st)->layer_split) + slave_zpos++; kcrtc_st->max_slave_zorder = - max(plane_st->normalized_zpos, - kcrtc_st->max_slave_zorder); + max(slave_zpos, kcrtc_st->max_slave_zorder); + } } crtc_st->zpos_changed = true; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -259,7 +259,7 @@ u32 avail_scalers; pipe_st = komeda_pipeline_get_state(c->pipeline, state); - if (!pipe_st) + if (IS_ERR_OR_NULL(pipe_st)) return NULL; avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^ @@ -1171,7 +1171,7 @@ return 0; } -static void +static int komeda_pipeline_unbound_components(struct komeda_pipeline *pipe, struct komeda_pipeline_state *new) { @@ -1190,8 +1190,12 @@ c = komeda_pipeline_get_component(pipe, id); c_st = komeda_component_get_state_and_set_user(c, drm_st, NULL, new->crtc); + if (PTR_ERR(c_st) == -EDEADLK) + return -EDEADLK; WARN_ON(IS_ERR(c_st)); } + + return 0; } /* release unclaimed pipeline resource */ @@ -1213,9 +1217,8 @@ if (WARN_ON(IS_ERR_OR_NULL(st))) return -EINVAL; - komeda_pipeline_unbound_components(pipe, st); + return komeda_pipeline_unbound_components(pipe, st); - return 0; } void komeda_pipeline_disable(struct komeda_pipeline *pipe, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -264,6 +264,10 @@ formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, layer->layer_type, &n_formats); + if (!formats) { + kfree(kplane); + return -ENOMEM; + } err = drm_universal_plane_init(&kms->base, plane, get_possible_crtcs(kms, c->pipeline), @@ -274,8 +278,10 @@ komeda_put_fourcc_list(formats); - if (err) - goto cleanup; + if (err) { + kfree(kplane); + return err; + } drm_plane_helper_add(plane, &komeda_plane_helper_funcs); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -159,6 +159,10 @@ formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, kwb_conn->wb_layer->layer_type, &n_formats); + if (!formats) { + kfree(kwb_conn); + return -ENOMEM; + } err = drm_writeback_connector_init(&kms->base, wb_conn, &komeda_wb_connector_funcs, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/malidp_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/malidp_crtc.c @@ -483,7 +483,10 @@ if (crtc->state) malidp_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &state->base); + if (state) + __drm_atomic_helper_crtc_reset(crtc, &state->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } static int malidp_crtc_enable_vblank(struct drm_crtc *crtc) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/malidp_mw.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/malidp_mw.c @@ -56,7 +56,7 @@ return MODE_OK; } -const struct drm_connector_helper_funcs malidp_mw_connector_helper_funcs = { +static const struct drm_connector_helper_funcs malidp_mw_connector_helper_funcs = { .get_modes = malidp_mw_connector_get_modes, .mode_valid = malidp_mw_connector_mode_valid, }; @@ -70,7 +70,10 @@ __drm_atomic_helper_connector_destroy_state(connector->state); kfree(connector->state); - __drm_atomic_helper_connector_reset(connector, &mw_state->base); + connector->state = NULL; + + if (mw_state) + __drm_atomic_helper_connector_reset(connector, &mw_state->base); } static enum drm_connector_status --- linux-oracle-5.4.0.orig/drivers/gpu/drm/arm/malidp_planes.c +++ linux-oracle-5.4.0/drivers/gpu/drm/arm/malidp_planes.c @@ -348,7 +348,7 @@ else sgt = obj->dev->driver->gem_prime_get_sg_table(obj); - if (!sgt) + if (IS_ERR(sgt)) return false; sgl = sgt->sgl; @@ -922,13 +922,18 @@ .atomic_disable = malidp_de_plane_disable, }; +static const uint64_t linear_only_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + int malidp_de_planes_init(struct drm_device *drm) { struct malidp_drm *malidp = drm->dev_private; const struct malidp_hw_regmap *map = &malidp->dev->hw->map; struct malidp_plane *plane = NULL; enum drm_plane_type plane_type; - unsigned long crtcs = 1 << drm->mode_config.num_crtc; + unsigned long crtcs = BIT(drm->mode_config.num_crtc); unsigned long flags = DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y; unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | @@ -985,8 +990,8 @@ */ ret = drm_universal_plane_init(drm, &plane->base, crtcs, &malidp_de_plane_funcs, formats, n, - (id == DE_SMART) ? NULL : modifiers, plane_type, - NULL); + (id == DE_SMART) ? linear_only_modifiers : modifiers, + plane_type, NULL); if (ret < 0) goto cleanup; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/armada/armada_overlay.c +++ linux-oracle-5.4.0/drivers/gpu/drm/armada/armada_overlay.c @@ -4,6 +4,8 @@ * Rewritten from the dovefb driver, and Armada510 manuals. */ +#include + #include #include #include @@ -446,8 +448,8 @@ drm_to_overlay_state(state)->colorkey_ug, drm_to_overlay_state(state)->colorkey_vb, 0); } else if (property == priv->colorkey_mode_prop) { - *val = (drm_to_overlay_state(state)->colorkey_mode & - CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK); + *val = FIELD_GET(CFG_CKMODE_MASK, + drm_to_overlay_state(state)->colorkey_mode); } else if (property == priv->brightness_prop) { *val = drm_to_overlay_state(state)->brightness + 256; } else if (property == priv->contrast_prop) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/aspeed/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/aspeed/Kconfig @@ -3,6 +3,7 @@ tristate "ASPEED BMC Display Controller" depends on DRM && OF depends on (COMPILE_TEST || ARCH_ASPEED) + depends on MMU select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DMA_CMA if HAVE_DMA_CONTIGUOUS --- linux-oracle-5.4.0.orig/drivers/gpu/drm/ast/ast_post.c +++ linux-oracle-5.4.0/drivers/gpu/drm/ast/ast_post.c @@ -294,7 +294,7 @@ ; } while (ast_read32(ast, 0x10100) != 0xa8); } else {/* AST2100/1100 */ - if (ast->chip == AST2100 || ast->chip == 2200) + if (ast->chip == AST2100 || ast->chip == AST2200) dram_reg_info = ast2100_dram_table_data; else dram_reg_info = ast1100_dram_table_data; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -73,7 +73,11 @@ unsigned long prate; unsigned int mask = ATMEL_HLCDC_CLKDIV_MASK | ATMEL_HLCDC_CLKPOL; unsigned int cfg = 0; - int div; + int div, ret; + + ret = clk_prepare_enable(crtc->dc->hlcdc->sys_clk); + if (ret) + return; vm.vfront_porch = adj->crtc_vsync_start - adj->crtc_vdisplay; vm.vback_porch = adj->crtc_vtotal - adj->crtc_vsync_end; @@ -95,14 +99,14 @@ (adj->crtc_hdisplay - 1) | ((adj->crtc_vdisplay - 1) << 16)); + prate = clk_get_rate(crtc->dc->hlcdc->sys_clk); + mode_rate = adj->crtc_clock * 1000; if (!crtc->dc->desc->fixed_clksrc) { + prate *= 2; cfg |= ATMEL_HLCDC_CLKSEL; mask |= ATMEL_HLCDC_CLKSEL; } - prate = 2 * clk_get_rate(crtc->dc->hlcdc->sys_clk); - mode_rate = adj->crtc_clock * 1000; - div = DIV_ROUND_UP(prate, mode_rate); if (div < 2) { div = 2; @@ -117,8 +121,8 @@ int div_low = prate / mode_rate; if (div_low >= 2 && - ((prate / div_low - mode_rate) < - 10 * (mode_rate - prate / div))) + (10 * (prate / div_low - mode_rate) < + (mode_rate - prate / div))) /* * At least 10 times better when using a higher * frequency than requested, instead of a lower. @@ -147,6 +151,8 @@ ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO | ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK, cfg); + + clk_disable_unprepare(crtc->dc->hlcdc->sys_clk); } static enum drm_mode_status --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bochs/bochs_hw.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bochs/bochs_hw.c @@ -156,10 +156,8 @@ size = min(size, mem); } - if (pci_request_region(pdev, 0, "bochs-drm") != 0) { - DRM_ERROR("Cannot request framebuffer\n"); - return -EBUSY; - } + if (pci_request_region(pdev, 0, "bochs-drm") != 0) + DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); bochs->fb_map = ioremap(addr, size); if (bochs->fb_map == NULL) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bochs/bochs_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bochs/bochs_kms.c @@ -194,6 +194,7 @@ bochs->dev->mode_config.preferred_depth = 24; bochs->dev->mode_config.prefer_shadow = 0; bochs->dev->mode_config.prefer_shadow_fbdev = 1; + bochs->dev->mode_config.fbdev_use_iomem = true; bochs->dev->mode_config.quirk_addfb_prefer_host_byte_order = true; bochs->dev->mode_config.funcs = &bochs_mode_funcs; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/Makefile +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -adv7511-y := adv7511_drv.o -adv7511-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o -adv7511-$(CONFIG_DRM_I2C_ADV7511_CEC) += adv7511_cec.o -adv7511-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o -obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511.o +adv7511_drm-y := adv7511_drv.o +adv7511_drm-$(CONFIG_DRM_I2C_ADV7511_AUDIO) += adv7511_audio.o +adv7511_drm-$(CONFIG_DRM_I2C_ADV7511_CEC) += adv7511_cec.o +adv7511_drm-$(CONFIG_DRM_I2C_ADV7533) += adv7533.o +obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511_drm.o --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -384,10 +384,7 @@ #else static inline int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->type == ADV7533 ? - ADV7533_REG_CEC_OFFSET : 0; - - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, ADV7511_CEC_CTRL_POWER_DOWN); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c @@ -19,13 +19,15 @@ { switch (fs) { case 32000: - *n = 4096; + case 48000: + case 96000: + case 192000: + *n = fs * 128 / 1000; break; case 44100: - *n = 6272; - break; - case 48000: - *n = 6144; + case 88200: + case 176400: + *n = fs * 128 / 900; break; } @@ -119,6 +121,9 @@ audio_source = ADV7511_AUDIO_SOURCE_I2S; i2s_format = ADV7511_I2S_FORMAT_LEFT_J; break; + case HDMI_SPDIF: + audio_source = ADV7511_AUDIO_SOURCE_SPDIF; + break; default: return -EINVAL; } @@ -142,7 +147,16 @@ ADV7511_AUDIO_CFG3_LEN_MASK, len); regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); - regmap_write(adv7511->regmap, 0x73, 0x1); + + /* send current Audio infoframe values while updating */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), BIT(5)); + + regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1); + + /* use Audio infoframe updated info */ + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, + BIT(5), 0); return 0; } @@ -173,13 +187,24 @@ regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0), BIT(7) | BIT(6), BIT(7)); /* use Audio infoframe updated info */ - regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1), + regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, BIT(5), 0); + + /* enable SPDIF receiver */ + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, + BIT(7), BIT(7)); + return 0; } static void audio_shutdown(struct device *dev, void *data) { + struct adv7511 *adv7511 = dev_get_drvdata(dev); + + if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) + regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, + BIT(7), 0); } static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, @@ -213,6 +238,7 @@ .ops = &adv7511_codec_ops, .max_i2s_channels = 2, .i2s = 1, + .spdif = 1, }; int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -316,7 +316,7 @@ goto err_cec_alloc; } - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0); + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, 0); /* cec soft reset */ regmap_write(adv7511->regmap_cec, ADV7511_REG_CEC_SOFT_RESET + offset, 0x01); @@ -343,7 +343,7 @@ dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n", ret); err_cec_parse_dt: - regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, + regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL, ADV7511_CEC_CTRL_POWER_DOWN); return ret == -EPROBE_DEFER ? ret : 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -756,8 +756,13 @@ else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - regmap_update_bits(adv7511->regmap, 0xfb, - 0x6, low_refresh_rate << 1); + if (adv7511->type == ADV7511) + regmap_update_bits(adv7511->regmap, 0xfb, + 0x6, low_refresh_rate << 1); + else + regmap_update_bits(adv7511->regmap, 0x4a, + 0xc, low_refresh_rate << 2); + regmap_update_bits(adv7511->regmap, 0x17, 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); @@ -985,6 +990,10 @@ ADV7511_CEC_I2C_ADDR_DEFAULT); if (IS_ERR(adv->i2c_cec)) return PTR_ERR(adv->i2c_cec); + + regmap_write(adv->regmap, ADV7511_REG_CEC_I2C_ADDR, + adv->i2c_cec->addr << 1); + i2c_set_clientdata(adv->i2c_cec, adv); adv->regmap_cec = devm_regmap_init_i2c(adv->i2c_cec, @@ -1189,9 +1198,6 @@ if (ret) goto err_i2c_unregister_packet; - regmap_write(adv7511->regmap, ADV7511_REG_CEC_I2C_ADDR, - adv7511->i2c_cec->addr << 1); - INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work); if (i2c->irq) { @@ -1225,6 +1231,7 @@ return 0; err_unregister_cec: + cec_unregister_adapter(adv7511->cec_adap); i2c_unregister_device(adv7511->i2c_cec); if (adv7511->cec_clk) clk_disable_unprepare(adv7511->cec_clk); @@ -1300,10 +1307,21 @@ static int __init adv7511_init(void) { - if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) - mipi_dsi_driver_register(&adv7533_dsi_driver); + int ret; - return i2c_add_driver(&adv7511_driver); + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) { + ret = mipi_dsi_driver_register(&adv7533_dsi_driver); + if (ret) + return ret; + } + + ret = i2c_add_driver(&adv7511_driver); + if (ret) { + if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) + mipi_dsi_driver_unregister(&adv7533_dsi_driver); + } + + return ret; } module_init(adv7511_init); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -193,7 +193,7 @@ of_property_read_u32(np, "adi,dsi-lanes", &num_lanes); - if (num_lanes < 1 || num_lanes > 4) + if (num_lanes < 2 || num_lanes > 4) return -EINVAL; adv->num_dsi_lanes = num_lanes; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/analogix-anx78xx.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/analogix-anx78xx.c @@ -715,7 +715,9 @@ /* 1.0V digital core power regulator */ pdata->dvdd10 = devm_regulator_get(dev, "dvdd10"); if (IS_ERR(pdata->dvdd10)) { - DRM_ERROR("DVDD10 regulator not found\n"); + if (PTR_ERR(pdata->dvdd10) != -EPROBE_DEFER) + DRM_ERROR("DVDD10 regulator not found\n"); + return PTR_ERR(pdata->dvdd10); } @@ -1332,7 +1334,9 @@ err = anx78xx_init_pdata(anx78xx); if (err) { - DRM_ERROR("Failed to initialize pdata: %d\n", err); + if (err != -EPROBE_DEFER) + DRM_ERROR("Failed to initialize pdata: %d\n", err); + return err; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1630,13 +1630,23 @@ struct drm_dp_aux_msg *msg) { struct analogix_dp_device *dp = to_dp(aux); + int ret; + + pm_runtime_get_sync(dp->dev); + + ret = analogix_dp_detect_hpd(dp); + if (ret) + goto out; + + ret = analogix_dp_transfer(dp, msg); +out: + pm_runtime_put(dp->dev); - return analogix_dp_transfer(dp, msg); + return ret; } struct analogix_dp_device * -analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, - struct analogix_dp_plat_data *plat_data) +analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) { struct platform_device *pdev = to_platform_device(dev); struct analogix_dp_device *dp; @@ -1697,8 +1707,10 @@ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(dp->reg_base)) - return ERR_CAST(dp->reg_base); + if (IS_ERR(dp->reg_base)) { + ret = PTR_ERR(dp->reg_base); + goto err_disable_clk; + } dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); @@ -1710,7 +1722,8 @@ if (IS_ERR(dp->hpd_gpiod)) { dev_err(dev, "error getting HDP GPIO: %ld\n", PTR_ERR(dp->hpd_gpiod)); - return ERR_CAST(dp->hpd_gpiod); + ret = PTR_ERR(dp->hpd_gpiod); + goto err_disable_clk; } if (dp->hpd_gpiod) { @@ -1730,7 +1743,8 @@ if (dp->irq == -ENXIO) { dev_err(&pdev->dev, "failed to get irq\n"); - return ERR_PTR(-ENODEV); + ret = -ENODEV; + goto err_disable_clk; } ret = devm_request_threaded_irq(&pdev->dev, dp->irq, @@ -1739,22 +1753,34 @@ irq_flags, "analogix-dp", dp); if (ret) { dev_err(&pdev->dev, "failed to request irq\n"); - goto err_disable_pm_runtime; + goto err_disable_clk; } disable_irq(dp->irq); + return dp; + +err_disable_clk: + clk_disable_unprepare(dp->clock); + return ERR_PTR(ret); +} +EXPORT_SYMBOL_GPL(analogix_dp_probe); + +int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev) +{ + int ret; + dp->drm_dev = drm_dev; dp->encoder = dp->plat_data->encoder; dp->aux.name = "DP-AUX"; dp->aux.transfer = analogix_dpaux_transfer; - dp->aux.dev = &pdev->dev; + dp->aux.dev = dp->dev; ret = drm_dp_aux_register(&dp->aux); if (ret) - return ERR_PTR(ret); + return ret; - pm_runtime_enable(dev); + pm_runtime_enable(dp->dev); ret = analogix_dp_create_bridge(drm_dev, dp); if (ret) { @@ -1762,13 +1788,12 @@ goto err_disable_pm_runtime; } - return dp; + return 0; err_disable_pm_runtime: + pm_runtime_disable(dp->dev); - pm_runtime_disable(dev); - - return ERR_PTR(ret); + return ret; } EXPORT_SYMBOL_GPL(analogix_dp_bind); @@ -1785,20 +1810,19 @@ drm_dp_aux_unregister(&dp->aux); pm_runtime_disable(dp->dev); - clk_disable_unprepare(dp->clock); } EXPORT_SYMBOL_GPL(analogix_dp_unbind); +void analogix_dp_remove(struct analogix_dp_device *dp) +{ + clk_disable_unprepare(dp->clock); +} +EXPORT_SYMBOL_GPL(analogix_dp_remove); + #ifdef CONFIG_PM int analogix_dp_suspend(struct analogix_dp_device *dp) { clk_disable_unprepare(dp->clock); - - if (dp->plat_data->panel) { - if (drm_panel_unprepare(dp->plat_data->panel)) - DRM_ERROR("failed to turnoff the panel\n"); - } - return 0; } EXPORT_SYMBOL_GPL(analogix_dp_suspend); @@ -1813,13 +1837,6 @@ return ret; } - if (dp->plat_data->panel) { - if (drm_panel_prepare(dp->plat_data->panel)) { - DRM_ERROR("failed to setup the panel\n"); - return -EBUSY; - } - } - return 0; } EXPORT_SYMBOL_GPL(analogix_dp_resume); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1086,11 +1086,21 @@ if (!blocking) return 0; + /* + * db[1]!=0: entering PSR, wait for fully active remote frame buffer. + * db[1]==0: exiting PSR, wait for either + * (a) ACTIVE_RESYNC - the sink "must display the + * incoming active frames from the Source device with no visible + * glitches and/or artifacts", even though timings may still be + * re-synchronizing; or + * (b) INACTIVE - the transition is fully complete. + */ ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status, psr_status >= 0 && ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) || - (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500, - DP_TIMEOUT_PSR_LOOP_MS * 1000); + (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC || + psr_status == DP_PSR_SINK_INACTIVE))), + 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000); if (ret) { dev_warn(dp->dev, "Failed to apply PSR %d\n", ret); return ret; @@ -1105,7 +1115,6 @@ u32 status_reg; u8 *buffer = msg->buffer; unsigned int i; - int num_transferred = 0; int ret; /* Buffer size of AUX CH is 16 bytes */ @@ -1157,7 +1166,6 @@ reg = buffer[i]; writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 4 * i); - num_transferred++; } } @@ -1205,7 +1213,6 @@ reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 4 * i); buffer[i] = (unsigned char)reg; - num_transferred++; } } @@ -1222,7 +1229,7 @@ (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return msg->size; aux_error: /* if aux err happen, reset aux */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/cdns-dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/cdns-dsi.c @@ -1026,7 +1026,7 @@ struct mipi_dsi_packet packet; int ret, i, tx_len, rx_len; - ret = pm_runtime_get_sync(host->dev); + ret = pm_runtime_resume_and_get(host->dev); if (ret < 0) return ret; @@ -1284,6 +1284,7 @@ { .compatible = "cdns,dsi" }, { }, }; +MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); static struct platform_driver cdns_dsi_platform_driver = { .probe = cdns_dsi_drm_probe, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -279,7 +279,9 @@ * This check is to avoid both the drivers * removing the bridge in their remove() function */ - if (!ge_b850v3_lvds_ptr) + if (!ge_b850v3_lvds_ptr || + !ge_b850v3_lvds_ptr->stdp2690_i2c || + !ge_b850v3_lvds_ptr->stdp4028_i2c) goto out; drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge); @@ -291,16 +293,11 @@ mutex_unlock(&ge_b850v3_lvds_dev_mutex); } -static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, - const struct i2c_device_id *id) +static int ge_b850v3_register(void) { + struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c; struct device *dev = &stdp4028_i2c->dev; - ge_b850v3_lvds_init(dev); - - ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; - i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); - /* drm bridge initialization */ ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs; ge_b850v3_lvds_ptr->bridge.of_node = dev->of_node; @@ -321,6 +318,27 @@ "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr); } +static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, + const struct i2c_device_id *id) +{ + struct device *dev = &stdp4028_i2c->dev; + int ret; + + ret = ge_b850v3_lvds_init(dev); + + if (ret) + return ret; + + ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; + i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); + + /* Only register after both bridges are probed */ + if (!ge_b850v3_lvds_ptr->stdp2690_i2c) + return 0; + + return ge_b850v3_register(); +} + static int stdp4028_ge_b850v3_fw_remove(struct i2c_client *stdp4028_i2c) { ge_b850v3_lvds_remove(); @@ -354,13 +372,21 @@ const struct i2c_device_id *id) { struct device *dev = &stdp2690_i2c->dev; + int ret; - ge_b850v3_lvds_init(dev); + ret = ge_b850v3_lvds_init(dev); + + if (ret) + return ret; ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c; i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr); - return 0; + /* Only register after both bridges are probed */ + if (!ge_b850v3_lvds_ptr->stdp4028_i2c) + return 0; + + return ge_b850v3_register(); } static int stdp2690_ge_b850v3_fw_remove(struct i2c_client *stdp2690_i2c) @@ -400,7 +426,11 @@ if (ret) return ret; - return i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); + ret = i2c_add_driver(&stdp2690_ge_b850v3_fw_driver); + if (ret) + i2c_del_driver(&stdp4028_ge_b850v3_fw_driver); + + return ret; } module_init(stdpxxxx_ge_b850v3_init); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/nxp-ptn3460.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/nxp-ptn3460.c @@ -54,13 +54,13 @@ int ret; ret = i2c_master_send(ptn_bridge->client, &addr, 1); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to send i2c command, ret=%d\n", ret); return ret; } ret = i2c_master_recv(ptn_bridge->client, buf, len); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret); return ret; } @@ -78,7 +78,7 @@ buf[1] = val; ret = i2c_master_send(ptn_bridge->client, buf, ARRAY_SIZE(buf)); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to send i2c command, ret=%d\n", ret); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/panel.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/panel.c @@ -87,8 +87,17 @@ static void panel_bridge_detach(struct drm_bridge *bridge) { struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); + struct drm_connector *connector = &panel_bridge->connector; - drm_panel_detach(panel_bridge->panel); + /* + * Cleanup the connector if we know it was initialized. + * + * FIXME: This wouldn't be needed if the panel_bridge structure was + * allocated with drmm_kzalloc(). This might be tricky since the + * drm_device pointer can only be retrieved when the bridge is attached. + */ + if (connector->dev) + drm_connector_cleanup(connector); } static void panel_bridge_pre_enable(struct drm_bridge *bridge) @@ -203,9 +212,12 @@ static void devm_drm_panel_bridge_release(struct device *dev, void *res) { - struct drm_bridge **bridge = res; + struct drm_bridge *bridge = *(struct drm_bridge **)res; - drm_panel_bridge_remove(*bridge); + if (!bridge) + return; + + drm_bridge_remove(bridge); } /** --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/sii902x.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/sii902x.c @@ -1016,11 +1016,6 @@ return ret; } - sii902x->bridge.funcs = &sii902x_bridge_funcs; - sii902x->bridge.of_node = dev->of_node; - sii902x->bridge.timings = &default_sii902x_timings; - drm_bridge_add(&sii902x->bridge); - sii902x_audio_codec_init(sii902x, dev); i2c_set_clientdata(client, sii902x); @@ -1033,16 +1028,24 @@ return -ENOMEM; sii902x->i2cmux->priv = sii902x; - return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); + ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); + if (ret) + return ret; + + sii902x->bridge.funcs = &sii902x_bridge_funcs; + sii902x->bridge.of_node = dev->of_node; + sii902x->bridge.timings = &default_sii902x_timings; + drm_bridge_add(&sii902x->bridge); + + return 0; } static int sii902x_remove(struct i2c_client *client) - { struct sii902x *sii902x = i2c_get_clientdata(client); - i2c_mux_del_adapters(sii902x->i2cmux); drm_bridge_remove(&sii902x->bridge); + i2c_mux_del_adapters(sii902x->i2cmux); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/sil-sii8620.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/sil-sii8620.c @@ -177,7 +177,7 @@ static u8 sii8620_readb(struct sii8620 *ctx, u16 addr) { - u8 ret; + u8 ret = 0; sii8620_read_buf(ctx, addr, &ret, 1); return ret; @@ -604,7 +604,7 @@ u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count]; int size = len + 2; - if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) { dev_err(ctx->dev, "TX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL; @@ -621,7 +621,7 @@ u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count]; int size = len + 1; - if (ctx->burst.tx_count + size > ARRAY_SIZE(ctx->burst.tx_buf)) { + if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) { dev_err(ctx->dev, "RX-BLK buffer exhausted\n"); ctx->error = -EINVAL; return NULL; @@ -985,7 +985,7 @@ static void sii8620_stop_video(struct sii8620 *ctx) { - u8 uninitialized_var(val); + u8 val; sii8620_write_seq_static(ctx, REG_TPI_INTR_EN, 0, @@ -2118,7 +2118,7 @@ if (ret) { dev_err(ctx->dev, "Failed to register RC device\n"); ctx->error = ret; - rc_free_device(ctx->rc_dev); + rc_free_device(rc_dev); return; } ctx->rc_dev = rc_dev; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -36,6 +36,7 @@ #include "dw-hdmi-cec.h" #include "dw-hdmi.h" +#define DDC_CI_ADDR 0x37 #define DDC_SEGMENT_ADDR 0x30 #define HDMI_EDID_LEN 512 @@ -398,6 +399,15 @@ u8 addr = msgs[0].addr; int i, ret = 0; + if (addr == DDC_CI_ADDR) + /* + * The internal I2C controller does not support the multi-byte + * read and write operations needed for DDC/CI. + * TOFIX: Blacklist the DDC/CI address until we filter out + * unsupported I2C operations. + */ + return -EOPNOTSUPP; + dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr); for (i = 0; i < num; i++) { @@ -1566,28 +1576,34 @@ frame.colorspace = HDMI_COLORSPACE_RGB; /* Set up colorimetry */ - switch (hdmi->hdmi_data.enc_out_encoding) { - case V4L2_YCBCR_ENC_601: - if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) - frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; - else + if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { + switch (hdmi->hdmi_data.enc_out_encoding) { + case V4L2_YCBCR_ENC_601: + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) + frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; + else + frame.colorimetry = HDMI_COLORIMETRY_ITU_601; + frame.extended_colorimetry = + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + break; + case V4L2_YCBCR_ENC_709: + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) + frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; + else + frame.colorimetry = HDMI_COLORIMETRY_ITU_709; + frame.extended_colorimetry = + HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; + break; + default: /* Carries no data */ frame.colorimetry = HDMI_COLORIMETRY_ITU_601; + frame.extended_colorimetry = + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + break; + } + } else { + frame.colorimetry = HDMI_COLORIMETRY_NONE; frame.extended_colorimetry = - HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; - break; - case V4L2_YCBCR_ENC_709: - if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) - frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; - else - frame.colorimetry = HDMI_COLORIMETRY_ITU_709; - frame.extended_colorimetry = - HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; - break; - default: /* Carries no data */ - frame.colorimetry = HDMI_COLORIMETRY_ITU_601; - frame.extended_colorimetry = - HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; - break; + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; } frame.scan_mode = HDMI_SCAN_MODE_NONE; @@ -2023,7 +2039,7 @@ /* HDMI Initialization Step E - Configure audio */ hdmi_clk_regenerator_update_pixel_clock(hdmi); - hdmi_enable_audio_clk(hdmi, true); + hdmi_enable_audio_clk(hdmi, hdmi->audio_enable); } /* not for DVI mode */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -365,7 +365,6 @@ if (lpm) val |= CMD_MODE_ALL_LP; - dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS); dsi_write(dsi, DSI_CMD_MODE_CFG, val); } @@ -541,16 +540,22 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi, unsigned long mode_flags) { + u32 val; + dsi_write(dsi, DSI_PWR_UP, RESET); if (mode_flags & MIPI_DSI_MODE_VIDEO) { dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE); dw_mipi_dsi_video_mode_config(dsi); - dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS); } else { dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); } + val = PHY_TXREQUESTCLKHS; + if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) + val |= AUTO_CLKLANE_CTRL; + dsi_write(dsi, DSI_LPCLK_CTRL, val); + dsi_write(dsi, DSI_PWR_UP, POWERUP); } @@ -1052,6 +1057,7 @@ ret = mipi_dsi_host_register(&dsi->dsi_host); if (ret) { dev_err(dev, "Failed to register MIPI host: %d\n", ret); + pm_runtime_disable(dev); dw_mipi_dsi_debugfs_remove(dsi); return ERR_PTR(ret); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/tc358764.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/tc358764.c @@ -180,7 +180,7 @@ if (ret >= 0) le32_to_cpus(val); - dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val); + dev_dbg(ctx->dev, "read: addr=0x%04x data=0x%08x\n", addr, *val); } static void tc358764_write(struct tc358764 *ctx, u16 addr, u32 val) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/tc358767.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/tc358767.c @@ -294,7 +294,7 @@ static int tc_aux_wait_busy(struct tc_data *tc) { - return tc_poll_timeout(tc, DP0_AUXSTATUS, AUX_BUSY, 0, 1000, 100000); + return tc_poll_timeout(tc, DP0_AUXSTATUS, AUX_BUSY, 0, 100, 100000); } static int tc_aux_write_data(struct tc_data *tc, const void *data, @@ -637,7 +637,7 @@ if (ret) goto err; - ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 1, 1000); + ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 100, 100000); if (ret == -ETIMEDOUT) { dev_err(tc->dev, "Timeout waiting for PHY to become ready"); return ret; @@ -861,7 +861,7 @@ int ret; ret = tc_poll_timeout(tc, DP0_LTSTAT, LT_LOOPDONE, - LT_LOOPDONE, 1, 1000); + LT_LOOPDONE, 500, 100000); if (ret) { dev_err(tc->dev, "Link training timeout waiting for LT_LOOPDONE!\n"); return ret; @@ -934,7 +934,7 @@ dp_phy_ctrl &= ~(DP_PHY_RST | PHY_M1_RST | PHY_M0_RST); ret = regmap_write(tc->regmap, DP_PHY_CTRL, dp_phy_ctrl); - ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 1, 1000); + ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 500, 100000); if (ret) { dev_err(dev, "timeout waiting for phy become ready"); return ret; @@ -1574,7 +1574,7 @@ } else { if (tc->hpd_pin < 0 || tc->hpd_pin > 1) { dev_err(dev, "failed to parse HPD number\n"); - return ret; + return -EINVAL; } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ linux-oracle-5.4.0/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -115,6 +115,7 @@ .val_bits = 8, .volatile_table = &ti_sn_bridge_volatile_table, .cache_type = REGCACHE_NONE, + .max_register = 0xFF, }; static void ti_sn_bridge_write_u16(struct ti_sn_bridge *pdata, @@ -459,9 +460,9 @@ &pdata->bridge.encoder->crtc->state->adjusted_mode; u8 hsync_polarity = 0, vsync_polarity = 0; - if (mode->flags & DRM_MODE_FLAG_PHSYNC) + if (mode->flags & DRM_MODE_FLAG_NHSYNC) hsync_polarity = CHA_HSYNC_POLARITY; - if (mode->flags & DRM_MODE_FLAG_PVSYNC) + if (mode->flags & DRM_MODE_FLAG_NVSYNC) vsync_polarity = CHA_VSYNC_POLARITY; ti_sn_bridge_write_u16(pdata, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG, @@ -647,6 +648,12 @@ buf[i]); } + /* Clear old status bits before start so we don't get confused */ + regmap_write(pdata->regmap, SN_AUX_CMD_STATUS_REG, + AUX_IRQ_STATUS_NAT_I2C_FAIL | + AUX_IRQ_STATUS_AUX_RPLY_TOUT | + AUX_IRQ_STATUS_AUX_SHORT); + regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val | AUX_CMD_SEND); ret = regmap_read_poll_timeout(pdata->regmap, SN_AUX_CMD_REG, val, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_atomic.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_atomic.c @@ -97,6 +97,12 @@ if (!state->planes) goto fail; + /* + * Because drm_atomic_state can be committed asynchronously we need our + * own reference and cannot rely on the on implied by drm_file in the + * ioctl call. + */ + drm_dev_get(dev); state->dev = dev; DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state); @@ -256,7 +262,8 @@ void __drm_atomic_state_free(struct kref *ref) { struct drm_atomic_state *state = container_of(ref, typeof(*state), ref); - struct drm_mode_config *config = &state->dev->mode_config; + struct drm_device *dev = state->dev; + struct drm_mode_config *config = &dev->mode_config; drm_atomic_state_clear(state); @@ -268,6 +275,8 @@ drm_atomic_state_default_release(state); kfree(state); } + + drm_dev_put(dev); } EXPORT_SYMBOL(__drm_atomic_state_free); @@ -1006,6 +1015,7 @@ drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name); drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)"); drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware); + drm_printf(p, "\tmax_requested_bpc=%d\n", state->max_requested_bpc); if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) if (state->writeback_job && state->writeback_job->fb) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_atomic_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_atomic_helper.c @@ -445,8 +445,9 @@ encoder = new_conn_state->best_encoder; funcs = encoder->helper_private; - ret = drm_bridge_mode_fixup(encoder->bridge, &new_crtc_state->mode, - &new_crtc_state->adjusted_mode); + ret = drm_bridge_chain_mode_fixup(encoder->bridge, + &new_crtc_state->mode, + &new_crtc_state->adjusted_mode); if (!ret) { DRM_DEBUG_ATOMIC("Bridge fixup failed\n"); return -EINVAL; @@ -511,7 +512,7 @@ return ret; } - ret = drm_bridge_mode_valid(encoder->bridge, mode); + ret = drm_bridge_chain_mode_valid(encoder->bridge, mode); if (ret != MODE_OK) { DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n"); return ret; @@ -588,6 +589,7 @@ * &drm_crtc_state.connectors_changed is set when a connector is added or * removed from the crtc. &drm_crtc_state.active_changed is set when * &drm_crtc_state.active changes, which is used for DPMS. + * &drm_crtc_state.no_vblank is set from the result of drm_dev_has_vblank(). * See also: drm_atomic_crtc_needs_modeset() * * IMPORTANT: @@ -654,6 +656,11 @@ return -EINVAL; } + + if (drm_dev_has_vblank(dev)) + new_crtc_state->no_vblank = false; + else + new_crtc_state->no_vblank = true; } ret = handle_conflicting_encoders(state, false); @@ -1030,7 +1037,7 @@ * Each encoder has at most one connector (since we always steal * it away), so we won't call disable hooks twice. */ - drm_atomic_bridge_disable(encoder->bridge, old_state); + drm_atomic_bridge_chain_disable(encoder->bridge, old_state); /* Right function depends upon target state. */ if (funcs) { @@ -1044,7 +1051,8 @@ funcs->dpms(encoder, DRM_MODE_DPMS_OFF); } - drm_atomic_bridge_post_disable(encoder->bridge, old_state); + drm_atomic_bridge_chain_post_disable(encoder->bridge, + old_state); } for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) { @@ -1078,7 +1086,16 @@ continue; ret = drm_crtc_vblank_get(crtc); - WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n"); + /* + * Self-refresh is not a true "disable"; ensure vblank remains + * enabled. + */ + if (new_crtc_state->self_refresh_active) + WARN_ONCE(ret != 0, + "driver disabled vblank in self-refresh\n"); + else + WARN_ONCE(ret != -EINVAL, + "driver forgot to call drm_crtc_vblank_off()\n"); if (ret == 0) drm_crtc_vblank_put(crtc); } @@ -1225,7 +1242,8 @@ funcs->mode_set(encoder, mode, adjusted_mode); } - drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode); + drm_bridge_chain_mode_set(encoder->bridge, mode, + adjusted_mode); } } @@ -1342,7 +1360,7 @@ * Each encoder has at most one connector (since we always steal * it away), so we won't call enable hooks twice. */ - drm_atomic_bridge_pre_enable(encoder->bridge, old_state); + drm_atomic_bridge_chain_pre_enable(encoder->bridge, old_state); if (funcs) { if (funcs->atomic_enable) @@ -1353,7 +1371,7 @@ funcs->commit(encoder); } - drm_atomic_bridge_enable(encoder->bridge, old_state); + drm_atomic_bridge_chain_enable(encoder->bridge, old_state); } drm_atomic_helper_commit_writebacks(dev, old_state); @@ -2202,7 +2220,9 @@ * when a job is queued, and any change to the pipeline that does not touch the * connector is leading to timeouts when calling * drm_atomic_helper_wait_for_vblanks() or - * drm_atomic_helper_wait_for_flip_done(). + * drm_atomic_helper_wait_for_flip_done(). In addition to writeback + * connectors, this function can also fake VBLANK events for CRTCs without + * VBLANK interrupt. * * This is part of the atomic helper support for nonblocking commits, see * drm_atomic_helper_setup_commit() for an overview. @@ -2948,7 +2968,7 @@ ret = handle_conflicting_encoders(state, true); if (ret) - return ret; + goto fail; ret = drm_atomic_commit(state); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_atomic_uapi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_atomic_uapi.c @@ -75,15 +75,17 @@ state->mode_blob = NULL; if (mode) { + struct drm_property_blob *blob; + drm_mode_convert_to_umode(&umode, mode); - state->mode_blob = - drm_property_create_blob(state->crtc->dev, - sizeof(umode), - &umode); - if (IS_ERR(state->mode_blob)) - return PTR_ERR(state->mode_blob); + blob = drm_property_create_blob(crtc->dev, + sizeof(umode), &umode); + if (IS_ERR(blob)) + return PTR_ERR(blob); drm_mode_copy(&state->mode, mode); + + state->mode_blob = blob; state->enable = true; DRM_DEBUG_ATOMIC("Set [MODE:%s] for [CRTC:%d:%s] state %p\n", mode->name, crtc->base.id, crtc->name, state); @@ -580,7 +582,7 @@ &state->fb_damage_clips, val, -1, - sizeof(struct drm_rect), + sizeof(struct drm_mode_rect), &replaced); return ret; } else if (plane->funcs->atomic_set_property) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_auth.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_auth.c @@ -268,9 +268,10 @@ void drm_master_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; - struct drm_master *master = file_priv->master; + struct drm_master *master; mutex_lock(&dev->master_mutex); + master = file_priv->master; if (file_priv->magic) idr_remove(&file_priv->master->magic_map, file_priv->magic); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_bridge.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_bridge.c @@ -172,8 +172,8 @@ */ /** - * drm_bridge_mode_fixup - fixup proposed mode for all bridges in the - * encoder chain + * drm_bridge_chain_mode_fixup - fixup proposed mode for all bridges in the + * encoder chain * @bridge: bridge control structure * @mode: desired mode to be set for the bridge * @adjusted_mode: updated mode that works for this bridge @@ -186,9 +186,9 @@ * RETURNS: * true on success, false on failure */ -bool drm_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) +bool drm_bridge_chain_mode_fixup(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { bool ret = true; @@ -198,15 +198,16 @@ if (bridge->funcs->mode_fixup) ret = bridge->funcs->mode_fixup(bridge, mode, adjusted_mode); - ret = ret && drm_bridge_mode_fixup(bridge->next, mode, adjusted_mode); + ret = ret && drm_bridge_chain_mode_fixup(bridge->next, mode, + adjusted_mode); return ret; } -EXPORT_SYMBOL(drm_bridge_mode_fixup); +EXPORT_SYMBOL(drm_bridge_chain_mode_fixup); /** - * drm_bridge_mode_valid - validate the mode against all bridges in the - * encoder chain. + * drm_bridge_chain_mode_valid - validate the mode against all bridges in the + * encoder chain. * @bridge: bridge control structure * @mode: desired mode to be validated * @@ -219,8 +220,9 @@ * RETURNS: * MODE_OK on success, drm_mode_status Enum error code on failure */ -enum drm_mode_status drm_bridge_mode_valid(struct drm_bridge *bridge, - const struct drm_display_mode *mode) +enum drm_mode_status +drm_bridge_chain_mode_valid(struct drm_bridge *bridge, + const struct drm_display_mode *mode) { enum drm_mode_status ret = MODE_OK; @@ -233,12 +235,12 @@ if (ret != MODE_OK) return ret; - return drm_bridge_mode_valid(bridge->next, mode); + return drm_bridge_chain_mode_valid(bridge->next, mode); } -EXPORT_SYMBOL(drm_bridge_mode_valid); +EXPORT_SYMBOL(drm_bridge_chain_mode_valid); /** - * drm_bridge_disable - disables all bridges in the encoder chain + * drm_bridge_chain_disable - disables all bridges in the encoder chain * @bridge: bridge control structure * * Calls &drm_bridge_funcs.disable op for all the bridges in the encoder @@ -247,20 +249,21 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_bridge_disable(struct drm_bridge *bridge) +void drm_bridge_chain_disable(struct drm_bridge *bridge) { if (!bridge) return; - drm_bridge_disable(bridge->next); + drm_bridge_chain_disable(bridge->next); if (bridge->funcs->disable) bridge->funcs->disable(bridge); } -EXPORT_SYMBOL(drm_bridge_disable); +EXPORT_SYMBOL(drm_bridge_chain_disable); /** - * drm_bridge_post_disable - cleans up after disabling all bridges in the encoder chain + * drm_bridge_chain_post_disable - cleans up after disabling all bridges in the + * encoder chain * @bridge: bridge control structure * * Calls &drm_bridge_funcs.post_disable op for all the bridges in the @@ -269,7 +272,7 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_bridge_post_disable(struct drm_bridge *bridge) +void drm_bridge_chain_post_disable(struct drm_bridge *bridge) { if (!bridge) return; @@ -277,25 +280,25 @@ if (bridge->funcs->post_disable) bridge->funcs->post_disable(bridge); - drm_bridge_post_disable(bridge->next); + drm_bridge_chain_post_disable(bridge->next); } -EXPORT_SYMBOL(drm_bridge_post_disable); +EXPORT_SYMBOL(drm_bridge_chain_post_disable); /** - * drm_bridge_mode_set - set proposed mode for all bridges in the - * encoder chain + * drm_bridge_chain_mode_set - set proposed mode for all bridges in the + * encoder chain * @bridge: bridge control structure - * @mode: desired mode to be set for the bridge - * @adjusted_mode: updated mode that works for this bridge + * @mode: desired mode to be set for the encoder chain + * @adjusted_mode: updated mode that works for this encoder chain * * Calls &drm_bridge_funcs.mode_set op for all the bridges in the * encoder chain, starting from the first bridge to the last. * * Note: the bridge passed should be the one closest to the encoder */ -void drm_bridge_mode_set(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - const struct drm_display_mode *adjusted_mode) +void drm_bridge_chain_mode_set(struct drm_bridge *bridge, + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { if (!bridge) return; @@ -303,13 +306,13 @@ if (bridge->funcs->mode_set) bridge->funcs->mode_set(bridge, mode, adjusted_mode); - drm_bridge_mode_set(bridge->next, mode, adjusted_mode); + drm_bridge_chain_mode_set(bridge->next, mode, adjusted_mode); } -EXPORT_SYMBOL(drm_bridge_mode_set); +EXPORT_SYMBOL(drm_bridge_chain_mode_set); /** - * drm_bridge_pre_enable - prepares for enabling all - * bridges in the encoder chain + * drm_bridge_chain_pre_enable - prepares for enabling all bridges in the + * encoder chain * @bridge: bridge control structure * * Calls &drm_bridge_funcs.pre_enable op for all the bridges in the encoder @@ -318,20 +321,20 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_bridge_pre_enable(struct drm_bridge *bridge) +void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) { if (!bridge) return; - drm_bridge_pre_enable(bridge->next); + drm_bridge_chain_pre_enable(bridge->next); if (bridge->funcs->pre_enable) bridge->funcs->pre_enable(bridge); } -EXPORT_SYMBOL(drm_bridge_pre_enable); +EXPORT_SYMBOL(drm_bridge_chain_pre_enable); /** - * drm_bridge_enable - enables all bridges in the encoder chain + * drm_bridge_chain_enable - enables all bridges in the encoder chain * @bridge: bridge control structure * * Calls &drm_bridge_funcs.enable op for all the bridges in the encoder @@ -340,7 +343,7 @@ * * Note that the bridge passed should be the one closest to the encoder */ -void drm_bridge_enable(struct drm_bridge *bridge) +void drm_bridge_chain_enable(struct drm_bridge *bridge) { if (!bridge) return; @@ -348,12 +351,12 @@ if (bridge->funcs->enable) bridge->funcs->enable(bridge); - drm_bridge_enable(bridge->next); + drm_bridge_chain_enable(bridge->next); } -EXPORT_SYMBOL(drm_bridge_enable); +EXPORT_SYMBOL(drm_bridge_chain_enable); /** - * drm_atomic_bridge_disable - disables all bridges in the encoder chain + * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain * @bridge: bridge control structure * @state: atomic state being committed * @@ -364,24 +367,24 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_atomic_bridge_disable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { if (!bridge) return; - drm_atomic_bridge_disable(bridge->next, state); + drm_atomic_bridge_chain_disable(bridge->next, state); if (bridge->funcs->atomic_disable) bridge->funcs->atomic_disable(bridge, state); else if (bridge->funcs->disable) bridge->funcs->disable(bridge); } -EXPORT_SYMBOL(drm_atomic_bridge_disable); +EXPORT_SYMBOL(drm_atomic_bridge_chain_disable); /** - * drm_atomic_bridge_post_disable - cleans up after disabling all bridges in the - * encoder chain + * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges + * in the encoder chain * @bridge: bridge control structure * @state: atomic state being committed * @@ -392,8 +395,8 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_atomic_bridge_post_disable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { if (!bridge) return; @@ -403,13 +406,13 @@ else if (bridge->funcs->post_disable) bridge->funcs->post_disable(bridge); - drm_atomic_bridge_post_disable(bridge->next, state); + drm_atomic_bridge_chain_post_disable(bridge->next, state); } -EXPORT_SYMBOL(drm_atomic_bridge_post_disable); +EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable); /** - * drm_atomic_bridge_pre_enable - prepares for enabling all bridges in the - * encoder chain + * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in + * the encoder chain * @bridge: bridge control structure * @state: atomic state being committed * @@ -420,23 +423,23 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_atomic_bridge_pre_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { if (!bridge) return; - drm_atomic_bridge_pre_enable(bridge->next, state); + drm_atomic_bridge_chain_pre_enable(bridge->next, state); if (bridge->funcs->atomic_pre_enable) bridge->funcs->atomic_pre_enable(bridge, state); else if (bridge->funcs->pre_enable) bridge->funcs->pre_enable(bridge); } -EXPORT_SYMBOL(drm_atomic_bridge_pre_enable); +EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable); /** - * drm_atomic_bridge_enable - enables all bridges in the encoder chain + * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain * @bridge: bridge control structure * @state: atomic state being committed * @@ -447,8 +450,8 @@ * * Note: the bridge passed should be the one closest to the encoder */ -void drm_atomic_bridge_enable(struct drm_bridge *bridge, - struct drm_atomic_state *state) +void drm_atomic_bridge_chain_enable(struct drm_bridge *bridge, + struct drm_atomic_state *state) { if (!bridge) return; @@ -458,9 +461,9 @@ else if (bridge->funcs->enable) bridge->funcs->enable(bridge); - drm_atomic_bridge_enable(bridge->next, state); + drm_atomic_bridge_chain_enable(bridge->next, state); } -EXPORT_SYMBOL(drm_atomic_bridge_enable); +EXPORT_SYMBOL(drm_atomic_bridge_chain_enable); #ifdef CONFIG_OF /** --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_client_modeset.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_client_modeset.c @@ -281,6 +281,9 @@ can_clone = true; dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false); + if (!dmt_mode) + goto fail; + for (i = 0; i < connector_count; i++) { if (!enabled[i]) continue; @@ -296,11 +299,13 @@ if (!modes[i]) can_clone = false; } + kfree(dmt_mode); if (can_clone) { DRM_DEBUG_KMS("can clone using 1024x768\n"); return true; } +fail: DRM_INFO("kms: can't enable cloning when we probably wanted to.\n"); return false; } @@ -695,6 +700,7 @@ unsigned int total_modes_count = 0; struct drm_client_offset *offsets; unsigned int connector_count = 0; + /* points to modes protected by mode_config.mutex */ struct drm_display_mode **modes; struct drm_crtc **crtcs; int i, ret = 0; @@ -763,7 +769,6 @@ drm_client_pick_crtcs(client, connectors, connector_count, crtcs, modes, 0, width, height); } - mutex_unlock(&dev->mode_config.mutex); drm_client_modeset_release(client); @@ -785,13 +790,20 @@ break; } + kfree(modeset->mode); modeset->mode = drm_mode_duplicate(dev, mode); + if (!modeset->mode) { + ret = -ENOMEM; + break; + } + drm_connector_get(connector); modeset->connectors[modeset->num_connectors++] = connector; modeset->x = offset->x; modeset->y = offset->y; } } + mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&client->modeset_mutex); out: @@ -880,7 +892,8 @@ * depending on the hardware this may require the framebuffer * to be in a specific tiling format. */ - if ((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180 || + if (((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_0 && + (*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180) || !plane->rotation_property) return false; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_connector.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_connector.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -473,6 +474,9 @@ mutex_destroy(&connector->mutex); memset(connector, 0, sizeof(*connector)); + + if (dev->registered) + drm_sysfs_hotplug_event(dev); } EXPORT_SYMBOL(drm_connector_cleanup); @@ -511,6 +515,10 @@ drm_mode_object_register(connector->dev, &connector->base); connector->registration_state = DRM_CONNECTOR_REGISTERED; + + /* Let userspace know we have a new connector */ + drm_sysfs_hotplug_event(connector->dev); + goto unlock; err_debugfs: @@ -1979,6 +1987,9 @@ void drm_connector_set_vrr_capable_property( struct drm_connector *connector, bool capable) { + if (!connector->vrr_capable_property) + return; + drm_object_property_set_value(&connector->base, connector->vrr_capable_property, capable); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_crtc.c @@ -535,8 +535,7 @@ struct drm_mode_set set; uint32_t __user *set_connectors_ptr; struct drm_modeset_acquire_ctx ctx; - int ret; - int i; + int ret, i, num_connectors = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP; @@ -694,6 +693,7 @@ connector->name); connector_set[i] = connector; + num_connectors++; } } @@ -702,7 +702,7 @@ set.y = crtc_req->y; set.mode = mode; set.connectors = connector_set; - set.num_connectors = crtc_req->count_connectors; + set.num_connectors = num_connectors; set.fb = fb; if (drm_drv_uses_atomic_modeset(dev)) @@ -715,7 +715,7 @@ drm_framebuffer_put(fb); if (connector_set) { - for (i = 0; i < crtc_req->count_connectors; i++) { + for (i = 0; i < num_connectors; i++) { if (connector_set[i]) drm_connector_put(connector_set[i]); } @@ -727,6 +727,7 @@ connector_set = NULL; fb = NULL; mode = NULL; + num_connectors = 0; DRM_MODESET_LOCK_ALL_END(ctx, ret); mutex_unlock(&crtc->dev->mode_config.mutex); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_crtc_helper_internal.h +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_crtc_helper_internal.h @@ -32,16 +32,6 @@ #include #include -/* drm_fb_helper.c */ -#ifdef CONFIG_DRM_FBDEV_EMULATION -int drm_fb_helper_modinit(void); -#else -static inline int drm_fb_helper_modinit(void) -{ - return 0; -} -#endif - /* drm_dp_aux_dev.c */ #ifdef CONFIG_DRM_DP_AUX_CHARDEV int drm_dp_aux_dev_init(void); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_crtc_internal.h +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_crtc_internal.h @@ -216,6 +216,8 @@ void *data, struct drm_file *file_priv); int drm_mode_getfb(struct drm_device *dev, void *data, struct drm_file *file_priv); +int drm_mode_getfb2_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); int drm_mode_dirtyfb_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_damage_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_damage_helper.c @@ -212,8 +212,14 @@ drm_for_each_plane(plane, fb->dev) { struct drm_plane_state *plane_state; - if (plane->state->fb != fb) + ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx); + if (ret) + goto out; + + if (plane->state->fb != fb) { + drm_modeset_unlock(&plane->mutex); continue; + } plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_debugfs.c @@ -91,6 +91,7 @@ mutex_lock(&dev->filelist_mutex); list_for_each_entry_reverse(priv, &dev->filelist, lhead) { struct task_struct *task; + bool is_current_master = drm_is_current_master(priv); rcu_read_lock(); /* locks pid_task()->comm */ task = pid_task(priv->pid, PIDTYPE_PID); @@ -99,7 +100,7 @@ task ? task->comm : "", pid_vnr(priv->pid), priv->minor->index, - drm_is_current_master(priv) ? 'y' : 'n', + is_current_master ? 'y' : 'n', priv->authenticated ? 'y' : 'n', from_kuid_munged(seq_user_ns(m), uid), priv->magic); @@ -337,13 +338,13 @@ buf[len] = '\0'; - if (!strcmp(buf, "on")) + if (sysfs_streq(buf, "on")) connector->force = DRM_FORCE_ON; - else if (!strcmp(buf, "digital")) + else if (sysfs_streq(buf, "digital")) connector->force = DRM_FORCE_ON_DIGITAL; - else if (!strcmp(buf, "off")) + else if (sysfs_streq(buf, "off")) connector->force = DRM_FORCE_OFF; - else if (!strcmp(buf, "unspecified")) + else if (sysfs_streq(buf, "unspecified")) connector->force = DRM_FORCE_UNSPECIFIED; else return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_debugfs_crc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_debugfs_crc.c @@ -140,12 +140,14 @@ if (IS_ERR(source)) return PTR_ERR(source); - if (source[len] == '\n') - source[len] = '\0'; + if (source[len - 1] == '\n') + source[len - 1] = '\0'; ret = crtc->funcs->verify_crc_source(crtc, source, &values_cnt); - if (ret) + if (ret) { + kfree(source); return ret; + } spin_lock_irq(&crc->lock); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_dp_aux_dev.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_dp_aux_dev.c @@ -63,7 +63,7 @@ mutex_lock(&aux_idr_mutex); aux_dev = idr_find(&aux_idr, index); - if (!kref_get_unless_zero(&aux_dev->refcount)) + if (aux_dev && !kref_get_unless_zero(&aux_dev->refcount)) aux_dev = NULL; mutex_unlock(&aux_idr_mutex); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_dp_cec.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_dp_cec.c @@ -303,16 +303,6 @@ if (!aux->transfer) return; -#ifndef CONFIG_MEDIA_CEC_RC - /* - * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by - * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined. - * - * Do this here as well to ensure the tests against cec_caps are - * correct. - */ - cec_caps &= ~CEC_CAP_RC; -#endif cancel_delayed_work_sync(&aux->cec.unregister_work); mutex_lock(&aux->cec.lock); @@ -329,7 +319,9 @@ num_las = CEC_MAX_LOG_ADDRS; if (aux->cec.adap) { - if (aux->cec.adap->capabilities == cec_caps && + /* Check if the adapter properties have changed */ + if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) == + (cec_caps & CEC_CAP_MONITOR_ALL) && aux->cec.adap->available_log_addrs == num_las) { /* Unchanged, so just set the phys addr */ cec_s_phys_addr_from_edid(aux->cec.adap, edid); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_dp_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_dp_helper.c @@ -1302,6 +1302,99 @@ #undef DEVICE_ID_ANY #undef DEVICE_ID +struct edid_quirk { + u8 mfg_id[2]; + u8 prod_id[2]; + u32 quirks; +}; + +#define MFG(first, second) { (first), (second) } +#define PROD_ID(first, second) { (first), (second) } + +/* + * Some devices have unreliable OUIDs where they don't set the device ID + * correctly, and as a result we need to use the EDID for finding additional + * DP quirks in such cases. + */ +static const struct edid_quirk edid_quirk_list[] = { + /* Optional 4K AMOLED panel in the ThinkPad X1 Extreme 2nd Generation + * only supports DPCD backlight controls + */ + { MFG(0x4c, 0x83), PROD_ID(0x41, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + /* HP Spectre x360 Convertible 13t-aw100 */ + { MFG(0x4c, 0x83), PROD_ID(0x42, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + /* HP CML 2020 system */ + { MFG(0x4c, 0x83), PROD_ID(0x45, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + /* + * Some Dell CML 2020 systems have panels support both AUX and PWM + * backlight control, and some only support AUX backlight control. All + * said panels start up in AUX mode by default, and we don't have any + * support for disabling HDR mode on these panels which would be + * required to switch to PWM backlight control mode (plus, I'm not + * even sure we want PWM backlight controls over DPCD backlight + * controls anyway...). Until we have a better way of detecting these, + * force DPCD backlight mode on all of them. + */ + { MFG(0x06, 0xaf), PROD_ID(0x8c, 0xcd), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x06, 0xaf), PROD_ID(0x9b, 0x32), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x06, 0xaf), PROD_ID(0xeb, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x30, 0xe4), PROD_ID(0x61, 0x06), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x4d, 0x10), PROD_ID(0xc7, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x4d, 0x10), PROD_ID(0xe6, 0x14), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x4c, 0x83), PROD_ID(0x47, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x4c, 0x83), PROD_ID(0x4f, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + { MFG(0x4c, 0x83), PROD_ID(0x4d, 0x41), BIT(DP_QUIRK_FORCE_DPCD_BACKLIGHT) }, + /* + * Some HP ZBook Studio G7 systems have panels support and relies on + * PSR being enabled. + */ + { MFG(0x0d, 0xae), PROD_ID(0x19, 0x15), BIT(DP_QUIRK_FORCE_PSR_CHIP_DEFAULT) }, +}; + +#undef MFG +#undef PROD_ID + +/** + * drm_dp_get_edid_quirks() - Check the EDID of a DP device to find additional + * DP-specific quirks + * @edid: The EDID to check + * + * While OUIDs are meant to be used to recognize a DisplayPort device, a lot + * of manufacturers don't seem to like following standards and neglect to fill + * the dev-ID in, making it impossible to only use OUIDs for determining + * quirks in some cases. This function can be used to check the EDID and look + * up any additional DP quirks. The bits returned by this function correspond + * to the quirk bits in &drm_dp_quirk. + * + * Returns: a bitmask of quirks, if any. The driver can check this using + * drm_dp_has_quirk(). + */ +u32 drm_dp_get_edid_quirks(const struct edid *edid) +{ + const struct edid_quirk *quirk; + u32 quirks = 0; + int i; + + if (!edid) + return 0; + + for (i = 0; i < ARRAY_SIZE(edid_quirk_list); i++) { + quirk = &edid_quirk_list[i]; + if (memcmp(quirk->mfg_id, edid->mfg_id, + sizeof(edid->mfg_id)) == 0 && + memcmp(quirk->prod_id, edid->prod_code, + sizeof(edid->prod_code)) == 0) + quirks |= quirk->quirks; + } + + DRM_DEBUG_KMS("DP sink: EDID mfg %*phD prod-ID %*phD quirks: 0x%04x\n", + (int)sizeof(edid->mfg_id), edid->mfg_id, + (int)sizeof(edid->prod_code), edid->prod_code, quirks); + + return quirks; +} +EXPORT_SYMBOL(drm_dp_get_edid_quirks); + /** * drm_dp_read_desc - read sink/branch descriptor from DPCD * @aux: DisplayPort AUX channel --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_dp_mst_topology.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_dp_mst_topology.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -339,7 +340,7 @@ memcpy(&buf[idx], req->u.i2c_read.transactions[i].bytes, req->u.i2c_read.transactions[i].num_bytes); idx += req->u.i2c_read.transactions[i].num_bytes; - buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 5; + buf[idx] = (req->u.i2c_read.transactions[i].no_stop_bit & 0x1) << 4; buf[idx] |= (req->u.i2c_read.transactions[i].i2c_transaction_delay & 0xf); idx++; } @@ -1805,14 +1806,14 @@ struct drm_dp_mst_branch *found_mstb; struct drm_dp_mst_port *port; + if (!mstb) + return NULL; + if (memcmp(mstb->guid, guid, 16) == 0) return mstb; list_for_each_entry(port, &mstb->ports, next) { - if (!port->mstb) - continue; - found_mstb = get_mst_branch_device_by_guid_helper(port->mstb, guid); if (found_mstb) @@ -2465,9 +2466,11 @@ drm_dp_mst_topology_put_port(port); } - for (i = 0; i < mgr->max_payloads; i++) { - if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) + for (i = 0; i < mgr->max_payloads; /* do nothing */) { + if (mgr->payloads[i].payload_state != DP_PAYLOAD_DELETE_LOCAL) { + i++; continue; + } DRM_DEBUG_KMS("removing payload %d\n", i); for (j = i; j < mgr->max_payloads - 1; j++) { @@ -2694,6 +2697,7 @@ int ret = 0; struct drm_dp_mst_branch *mstb = NULL; + mutex_lock(&mgr->payload_lock); mutex_lock(&mgr->lock); if (mst_state == mgr->mst_state) goto out_unlock; @@ -2752,7 +2756,10 @@ /* this can fail if the device is gone */ drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0); ret = 0; - memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload)); + memset(mgr->payloads, 0, + mgr->max_payloads * sizeof(mgr->payloads[0])); + memset(mgr->proposed_vcpis, 0, + mgr->max_payloads * sizeof(mgr->proposed_vcpis[0])); mgr->payload_mask = 0; set_bit(0, &mgr->payload_mask); mgr->vcpi_mask = 0; @@ -2760,6 +2767,7 @@ out_unlock: mutex_unlock(&mgr->lock); + mutex_unlock(&mgr->payload_lock); if (mstb) drm_dp_mst_topology_put_mstb(mstb); return ret; @@ -3361,11 +3369,11 @@ { int ret; - port = drm_dp_mst_topology_get_port_validated(mgr, port); - if (!port) + if (slots < 0) return false; - if (slots < 0) + port = drm_dp_mst_topology_get_port_validated(mgr, port); + if (!port) return false; if (port->vcpi.vcpi > 0) { @@ -3381,6 +3389,7 @@ if (ret) { DRM_DEBUG_KMS("failed to init vcpi slots=%d max=63 ret=%d\n", DIV_ROUND_UP(pbn, mgr->pbn_div), ret); + drm_dp_mst_topology_put_port(port); goto out; } DRM_DEBUG_KMS("initing vcpi for pbn=%d slots=%d\n", @@ -3491,6 +3500,17 @@ return ret; } +static int do_get_act_status(struct drm_dp_aux *aux) +{ + int ret; + u8 status; + + ret = drm_dp_dpcd_readb(aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status); + if (ret < 0) + return ret; + + return status; +} /** * drm_dp_check_act_status() - Check ACT handled status. @@ -3500,33 +3520,29 @@ */ int drm_dp_check_act_status(struct drm_dp_mst_topology_mgr *mgr) { - u8 status; - int ret; - int count = 0; - - do { - ret = drm_dp_dpcd_readb(mgr->aux, DP_PAYLOAD_TABLE_UPDATE_STATUS, &status); - - if (ret < 0) { - DRM_DEBUG_KMS("failed to read payload table status %d\n", ret); - goto fail; - } - - if (status & DP_PAYLOAD_ACT_HANDLED) - break; - count++; - udelay(100); - - } while (count < 30); + /* + * There doesn't seem to be any recommended retry count or timeout in + * the MST specification. Since some hubs have been observed to take + * over 1 second to update their payload allocations under certain + * conditions, we use a rather large timeout value. + */ + const int timeout_ms = 3000; + int ret, status; - if (!(status & DP_PAYLOAD_ACT_HANDLED)) { - DRM_DEBUG_KMS("failed to get ACT bit %d after %d retries\n", status, count); - ret = -EINVAL; - goto fail; + ret = readx_poll_timeout(do_get_act_status, mgr->aux, status, + status & DP_PAYLOAD_ACT_HANDLED || status < 0, + 200, timeout_ms * USEC_PER_MSEC); + if (ret < 0 && status >= 0) { + DRM_DEBUG_KMS("Failed to get ACT after %dms, last status: %02x\n", + timeout_ms, status); + return -EINVAL; + } else if (status < 0) { + DRM_DEBUG_KMS("Failed to read payload table status: %d\n", + status); + return status; } + return 0; -fail: - return ret; } EXPORT_SYMBOL(drm_dp_check_act_status); @@ -3641,6 +3657,7 @@ mst_edid = drm_dp_mst_get_edid(port->connector, mgr, port); drm_edid_get_monitor_name(mst_edid, name, namelen); + kfree(mst_edid); } /** --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_drv.c @@ -984,8 +984,11 @@ goto err_minors; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_modeset_register_all(dev); + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_modeset_register_all(dev); + if (ret) + goto err_unload; + } ret = 0; @@ -997,6 +1000,9 @@ goto out_unlock; +err_unload: + if (dev->driver->unload) + dev->driver->unload(dev); err_minors: remove_compat_control_link(dev); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_edid.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_edid.c @@ -191,10 +191,11 @@ { "HVR", 0xaa01, EDID_QUIRK_NON_DESKTOP }, { "HVR", 0xaa02, EDID_QUIRK_NON_DESKTOP }, - /* Oculus Rift DK1, DK2, and CV1 VR Headsets */ + /* Oculus Rift DK1, DK2, CV1 and Rift S VR Headsets */ { "OVR", 0x0001, EDID_QUIRK_NON_DESKTOP }, { "OVR", 0x0003, EDID_QUIRK_NON_DESKTOP }, { "OVR", 0x0004, EDID_QUIRK_NON_DESKTOP }, + { "OVR", 0x0012, EDID_QUIRK_NON_DESKTOP }, /* Windows Mixed Reality Headsets */ { "ACR", 0x7fce, EDID_QUIRK_NON_DESKTOP }, @@ -1701,9 +1702,6 @@ connector_bad_edid(connector, edid, edid[0x7e] + 1); - edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions; - edid[0x7e] = valid_extensions; - new = kmalloc_array(valid_extensions + 1, EDID_LENGTH, GFP_KERNEL); if (!new) @@ -1720,6 +1718,9 @@ base += EDID_LENGTH; } + new[EDID_LENGTH - 1] += new[0x7e] - valid_extensions; + new[0x7e] = valid_extensions; + kfree(edid); edid = new; } @@ -2770,7 +2771,7 @@ const u8 empty[3] = { 0, 0, 0 }; for (i = 0; i < 4; i++) { - int uninitialized_var(width), height; + int width, height; cvt = &(timing->data.other_data.data.cvt[i]); if (!memcmp(cvt->code, empty, 3)) @@ -2778,6 +2779,8 @@ height = (cvt->code[0] + ((cvt->code[1] & 0xf0) << 4) + 1) * 2; switch (cvt->code[1] & 0x0c) { + /* default - because compiler doesn't see that we've enumerated all cases */ + default: case 0x00: width = height * 4 / 3; break; @@ -3722,7 +3725,7 @@ if (*end < 4 || *end > 127) return -ERANGE; } else { - return -ENOTSUPP; + return -EOPNOTSUPP; } return 0; @@ -4191,7 +4194,7 @@ if (cea_revision(cea) < 3) { DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } if (cea_db_offsets(cea, &start, &end)) { @@ -4252,7 +4255,7 @@ if (cea_revision(cea) < 3) { DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } if (cea_db_offsets(cea, &start, &end)) { @@ -4379,7 +4382,8 @@ if (!edid_ext) goto end; - has_audio = ((edid_ext[3] & EDID_BASIC_AUDIO) != 0); + has_audio = (edid_ext[0] == CEA_EXT && + (edid_ext[3] & EDID_BASIC_AUDIO) != 0); if (has_audio) { DRM_DEBUG_KMS("Monitor has basic audio support\n"); @@ -4532,16 +4536,8 @@ connector->name, dc_bpc); info->bpc = dc_bpc; - /* - * Deep color support mandates RGB444 support for all video - * modes and forbids YCRCB422 support for all video modes per - * HDMI 1.3 spec. - */ - info->color_formats = DRM_COLOR_FORMAT_RGB444; - /* YCRCB444 is optional according to spec. */ if (hdmi[6] & DRM_EDID_HDMI_DC_Y444) { - info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; DRM_DEBUG("%s: HDMI sink does YCRCB444 in deep color.\n", connector->name); } @@ -4658,6 +4654,7 @@ if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) return quirks; + info->color_formats |= DRM_COLOR_FORMAT_RGB444; drm_parse_cea_ext(connector, edid); /* @@ -4706,7 +4703,6 @@ DRM_DEBUG("%s: Assigning EDID-1.4 digital sink color depth as %d bpc.\n", connector->name, info->bpc); - info->color_formats |= DRM_COLOR_FORMAT_RGB444; if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) @@ -4743,7 +4739,7 @@ struct drm_display_mode *mode; unsigned pixel_clock = (timings->pixel_clock[0] | (timings->pixel_clock[1] << 8) | - (timings->pixel_clock[2] << 16)); + (timings->pixel_clock[2] << 16)) + 1; unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_encoder.c @@ -170,7 +170,7 @@ struct drm_bridge *next; while (bridge) { - next = bridge->next; + next = drm_bridge_get_next_bridge(bridge); drm_bridge_detach(bridge); bridge = next; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_encoder_slave.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_encoder_slave.c @@ -84,7 +84,7 @@ err = encoder_drv->encoder_init(client, dev, encoder); if (err) - goto fail_unregister; + goto fail_module_put; if (info->platform_data) encoder->slave_funcs->set_config(&encoder->base, @@ -92,9 +92,10 @@ return 0; +fail_module_put: + module_put(module); fail_unregister: i2c_unregister_device(client); - module_put(module); fail: return err; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_fb_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_fb_helper.c @@ -390,7 +390,11 @@ unsigned int y; for (y = clip->y1; y < clip->y2; y++) { - memcpy(dst, src, len); + if (!fb_helper->dev->mode_config.fbdev_use_iomem) + memcpy(dst, src, len); + else + memcpy_toio((void __iomem *)dst, src, len); + src += fb->pitches[0]; dst += fb->pitches[0]; } @@ -961,11 +965,15 @@ drm_modeset_lock_all(fb_helper->dev); drm_client_for_each_modeset(modeset, &fb_helper->client) { crtc = modeset->crtc; - if (!crtc->funcs->gamma_set || !crtc->gamma_size) - return -EINVAL; + if (!crtc->funcs->gamma_set || !crtc->gamma_size) { + ret = -EINVAL; + goto out; + } - if (cmap->start + cmap->len > crtc->gamma_size) - return -EINVAL; + if (cmap->start + cmap->len > crtc->gamma_size) { + ret = -EINVAL; + goto out; + } r = crtc->gamma_store; g = r + crtc->gamma_size; @@ -978,8 +986,9 @@ ret = crtc->funcs->gamma_set(crtc, r, g, b, crtc->gamma_size, NULL); if (ret) - return ret; + goto out; } +out: drm_modeset_unlock_all(fb_helper->dev); return ret; @@ -1320,7 +1329,7 @@ * Changes struct fb_var_screeninfo are currently not pushed back * to KMS, hence fail if different settings are requested. */ - if (var->bits_per_pixel != fb->format->cpp[0] * 8 || + if (var->bits_per_pixel > fb->format->cpp[0] * 8 || var->xres > fb->width || var->yres > fb->height || var->xres_virtual > fb->width || var->yres_virtual > fb->height) { DRM_DEBUG("fb requested width/height/bpp can't fit in current fb " @@ -1331,6 +1340,9 @@ return -EINVAL; } + var->xres_virtual = fb->width; + var->yres_virtual = fb->height; + /* * Workaround for SDL 1.2, which is known to be setting all pixel format * fields values to zero in some cases. We treat this situation as a @@ -1346,6 +1358,11 @@ } /* + * Likewise, bits_per_pixel should be rounded up to a supported value. + */ + var->bits_per_pixel = fb->format->cpp[0] * 8; + + /* * drm fbdev emulation doesn't support changing the pixel format at all, * so reject all pixel format changing requests. */ @@ -2401,24 +2418,3 @@ return 0; } EXPORT_SYMBOL(drm_fbdev_generic_setup); - -/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) - * but the module doesn't depend on any fb console symbols. At least - * attempt to load fbcon to avoid leaving the system without a usable console. - */ -int __init drm_fb_helper_modinit(void) -{ -#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) - const char name[] = "fbcon"; - struct module *fbcon; - - mutex_lock(&module_mutex); - fbcon = find_module(name); - mutex_unlock(&module_mutex); - - if (!fbcon) - request_module_nowait(name); -#endif - return 0; -} -EXPORT_SYMBOL(drm_fb_helper_modinit); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_file.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_file.c @@ -369,7 +369,7 @@ { struct drm_device *dev; struct drm_minor *minor; - int retcode; + int retcode = 0; int need_setup = 0; minor = drm_minor_acquire(iminor(inode)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_fourcc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_fourcc.c @@ -178,6 +178,10 @@ { .format = DRM_FORMAT_BGRA5551, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true }, { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_BGR565, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, +#ifdef __BIG_ENDIAN + { .format = DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, .depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, + { .format = DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, .depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 }, +#endif { .format = DRM_FORMAT_RGB888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_BGR888, .depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 }, { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 }, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_framebuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_framebuffer.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -548,7 +549,128 @@ out: drm_framebuffer_put(fb); + return ret; +} + +/** + * drm_mode_getfb2 - get extended FB info + * @dev: drm device for the ioctl + * @data: data pointer for the ioctl + * @file_priv: drm file for the ioctl call + * + * Lookup the FB given its ID and return info about it. + * + * Called by the user via ioctl. + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_mode_getfb2_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv) +{ + struct drm_mode_fb_cmd2 *r = data; + struct drm_framebuffer *fb; + unsigned int i; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + + fb = drm_framebuffer_lookup(dev, file_priv, r->fb_id); + if (!fb) + return -ENOENT; + + /* For multi-plane framebuffers, we require the driver to place the + * GEM objects directly in the drm_framebuffer. For single-plane + * framebuffers, we can fall back to create_handle. + */ + if (!fb->obj[0] && + (fb->format->num_planes > 1 || !fb->funcs->create_handle)) { + ret = -ENODEV; + goto out; + } + + r->height = fb->height; + r->width = fb->width; + r->pixel_format = fb->format->format; + + r->flags = 0; + if (dev->mode_config.allow_fb_modifiers) + r->flags |= DRM_MODE_FB_MODIFIERS; + + for (i = 0; i < ARRAY_SIZE(r->handles); i++) { + r->handles[i] = 0; + r->pitches[i] = 0; + r->offsets[i] = 0; + r->modifier[i] = 0; + } + + for (i = 0; i < fb->format->num_planes; i++) { + r->pitches[i] = fb->pitches[i]; + r->offsets[i] = fb->offsets[i]; + if (dev->mode_config.allow_fb_modifiers) + r->modifier[i] = fb->modifier; + } + + /* GET_FB2() is an unprivileged ioctl so we must not return a + * buffer-handle to non master/root processes! To match GET_FB() + * just return invalid handles (0) for non masters/root + * rather than making GET_FB2() privileged. + */ + if (!drm_is_current_master(file_priv) && !capable(CAP_SYS_ADMIN)) { + ret = 0; + goto out; + } + + for (i = 0; i < fb->format->num_planes; i++) { + int j; + + /* If we reuse the same object for multiple planes, also + * return the same handle. + */ + for (j = 0; j < i; j++) { + if (fb->obj[i] == fb->obj[j]) { + r->handles[i] = r->handles[j]; + break; + } + } + if (r->handles[i]) + continue; + + if (fb->obj[i]) { + ret = drm_gem_handle_create(file_priv, fb->obj[i], + &r->handles[i]); + } else { + WARN_ON(i > 0); + ret = fb->funcs->create_handle(fb, file_priv, + &r->handles[i]); + } + + if (ret != 0) + goto out; + } + +out: + if (ret != 0) { + /* Delete any previously-created handles on failure. */ + for (i = 0; i < ARRAY_SIZE(r->handles); i++) { + int j; + + if (r->handles[i]) + drm_gem_handle_delete(file_priv, r->handles[i]); + + /* Zero out any handles identical to the one we just + * deleted. + */ + for (j = i + 1; j < ARRAY_SIZE(r->handles); j++) { + if (r->handles[j] == r->handles[i]) + r->handles[j] = 0; + } + } + } + + drm_framebuffer_put(fb); return ret; } @@ -580,7 +702,7 @@ struct drm_framebuffer *fb; unsigned flags; int num_clips; - int ret; + int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EOPNOTSUPP; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_gem.c @@ -167,21 +167,6 @@ } EXPORT_SYMBOL(drm_gem_private_object_init); -static void -drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) -{ - /* - * Note: obj->dma_buf can't disappear as long as we still hold a - * handle reference in obj->handle_count. - */ - mutex_lock(&filp->prime.lock); - if (obj->dma_buf) { - drm_prime_remove_buf_handle_locked(&filp->prime, - obj->dma_buf); - } - mutex_unlock(&filp->prime.lock); -} - /** * drm_gem_object_handle_free - release resources bound to userspace handles * @obj: GEM object to clean up. @@ -255,7 +240,7 @@ else if (dev->driver->gem_close_object) dev->driver->gem_close_object(obj, file_priv); - drm_gem_remove_prime_handles(obj, file_priv); + drm_prime_remove_buf_handle(&file_priv->prime, id); drm_vma_node_revoke(&obj->vma_node, file_priv); drm_gem_object_handle_put_unlocked(obj); @@ -710,6 +695,8 @@ if (!objs) return -ENOMEM; + *objs_out = objs; + handles = kvmalloc_array(count, sizeof(u32), GFP_KERNEL); if (!handles) { ret = -ENOMEM; @@ -723,8 +710,6 @@ } ret = objects_lookup(filp, handles, count, objs); - *objs_out = objs; - out: kvfree(handles); return ret; @@ -872,9 +857,6 @@ * @file_priv: drm file-private structure * * Open an object using the global name, returning a handle and the size. - * - * This handle (of course) holds a reference to the object, so the object - * will not go away until the handle is deleted. */ int drm_gem_open_ioctl(struct drm_device *dev, void *data, @@ -899,14 +881,15 @@ /* drm_gem_handle_create_tail unlocks dev->object_name_lock. */ ret = drm_gem_handle_create_tail(file_priv, obj, &handle); - drm_gem_object_put_unlocked(obj); if (ret) - return ret; + goto err; args->handle = handle; args->size = obj->size; - return 0; +err: + drm_gem_object_put_unlocked(obj); + return ret; } /** @@ -1294,7 +1277,7 @@ ret = dma_resv_lock_slow_interruptible(obj->resv, acquire_ctx); if (ret) { - ww_acquire_done(acquire_ctx); + ww_acquire_fini(acquire_ctx); return ret; } } @@ -1319,7 +1302,7 @@ goto retry; } - ww_acquire_done(acquire_ctx); + ww_acquire_fini(acquire_ctx); return ret; } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_gem_shmem_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -474,14 +474,28 @@ struct drm_gem_object *obj = vma->vm_private_data; struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); loff_t num_pages = obj->size >> PAGE_SHIFT; + vm_fault_t ret; struct page *page; + pgoff_t page_offset; - if (vmf->pgoff >= num_pages || WARN_ON_ONCE(!shmem->pages)) - return VM_FAULT_SIGBUS; + /* We don't use vmf->pgoff since that has the fake offset */ + page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT; - page = shmem->pages[vmf->pgoff]; + mutex_lock(&shmem->pages_lock); - return vmf_insert_page(vma, vmf->address, page); + if (page_offset >= num_pages || + WARN_ON_ONCE(!shmem->pages) || + shmem->madv < 0) { + ret = VM_FAULT_SIGBUS; + } else { + page = shmem->pages[page_offset]; + + ret = vmf_insert_page(vma, vmf->address, page); + } + + mutex_unlock(&shmem->pages_lock); + + return ret; } static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) @@ -540,18 +554,13 @@ shmem = to_drm_gem_shmem_obj(vma->vm_private_data); ret = drm_gem_shmem_get_pages(shmem); - if (ret) { - drm_gem_vm_close(vma); + if (ret) return ret; - } /* VM_PFNMAP was set by drm_gem_mmap() */ vma->vm_flags &= ~VM_PFNMAP; vma->vm_flags |= VM_MIXEDMAP; - /* Remove the fake offset */ - vma->vm_pgoff -= drm_vma_node_start(&shmem->base.vma_node); - return 0; } EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_gem_vram_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_gem_vram_helper.c @@ -73,6 +73,10 @@ } } +/* + * Note that on error, drm_gem_vram_init will free the buffer object. + */ + static int drm_gem_vram_init(struct drm_device *dev, struct ttm_bo_device *bdev, struct drm_gem_vram_object *gbo, @@ -86,8 +90,10 @@ gbo->bo.base.funcs = &drm_gem_vram_object_funcs; ret = drm_gem_object_init(dev, &gbo->bo.base, size); - if (ret) + if (ret) { + kfree(gbo); return ret; + } acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo)); @@ -98,13 +104,13 @@ &gbo->placement, pg_align, interruptible, acc_size, NULL, NULL, ttm_buffer_object_destroy); if (ret) - goto err_drm_gem_object_release; + /* + * A failing ttm_bo_init will call ttm_buffer_object_destroy + * to release gbo->bo.base and kfree gbo. + */ + return ret; return 0; - -err_drm_gem_object_release: - drm_gem_object_release(&gbo->bo.base); - return ret; } /** @@ -134,13 +140,9 @@ ret = drm_gem_vram_init(dev, bdev, gbo, size, pg_align, interruptible); if (ret < 0) - goto err_kfree; + return ERR_PTR(ret); return gbo; - -err_kfree: - kfree(gbo); - return ERR_PTR(ret); } EXPORT_SYMBOL(drm_gem_vram_create); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_internal.h +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_internal.h @@ -59,8 +59,8 @@ void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv); void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv); -void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf); +void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, + uint32_t handle); /* drm_drv.c */ struct drm_minor *drm_minor_acquire(unsigned int minor_id); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_ioc32.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_ioc32.c @@ -99,6 +99,8 @@ if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) return -EFAULT; + memset(&v, 0, sizeof(v)); + v = (struct drm_version) { .name_len = v32.name_len, .name = compat_ptr(v32.name), @@ -137,6 +139,9 @@ if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; + + memset(&uq, 0, sizeof(uq)); + uq = (struct drm_unique){ .unique_len = uq32.unique_len, .unique = compat_ptr(uq32.unique), @@ -265,6 +270,8 @@ if (copy_from_user(&c32, argp, sizeof(c32))) return -EFAULT; + memset(&client, 0, sizeof(client)); + client.idx = c32.idx; err = drm_ioctl_kernel(file, drm_getclient, &client, 0); @@ -850,12 +857,12 @@ if (copy_from_user(&req32, argp, sizeof(req32))) return -EFAULT; + memset(&req, 0, sizeof(req)); + req.request.type = req32.request.type; req.request.sequence = req32.request.sequence; req.request.signal = req32.request.signal; err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED); - if (err) - return err; req32.reply.type = req.reply.type; req32.reply.sequence = req.reply.sequence; @@ -864,7 +871,7 @@ if (copy_to_user(argp, &req32, sizeof(req32))) return -EFAULT; - return 0; + return err; } #if defined(CONFIG_X86) @@ -887,6 +894,8 @@ struct drm_mode_fb_cmd2 req64; int err; + memset(&req64, 0, sizeof(req64)); + if (copy_from_user(&req64, argp, offsetof(drm_mode_fb_cmd232_t, modifier))) return -EFAULT; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_ioctl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_ioctl.c @@ -118,17 +118,18 @@ struct drm_file *file_priv) { struct drm_unique *u = data; - struct drm_master *master = file_priv->master; + struct drm_master *master; - mutex_lock(&master->dev->master_mutex); + mutex_lock(&dev->master_mutex); + master = file_priv->master; if (u->unique_len >= master->unique_len) { if (copy_to_user(u->unique, master->unique, master->unique_len)) { - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return -EFAULT; } } u->unique_len = master->unique_len; - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return 0; } @@ -472,7 +473,13 @@ */ static int drm_copy_field(char __user *buf, size_t *buf_len, const char *value) { - int len; + size_t len; + + /* don't attempt to copy a NULL pointer */ + if (WARN_ONCE(!value, "BUG: the value to copy was not set!")) { + *buf_len = 0; + return 0; + } /* don't overflow userbuf */ len = strlen(value); @@ -671,6 +678,7 @@ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_connector_property_set_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, 0), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB2, drm_mode_getfb2_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2_ioctl, 0), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb_ioctl, 0), @@ -825,6 +833,9 @@ if (drm_dev_is_unplugged(dev)) return -ENODEV; + if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) + return -ENOTTY; + is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; if (is_driver_ioctl) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_kms_helper_common.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_kms_helper_common.c @@ -64,19 +64,18 @@ static int __init drm_kms_helper_init(void) { - int ret; + /* + * The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) + * but the module doesn't depend on any fb console symbols. At least + * attempt to load fbcon to avoid leaving the system without a usable + * console. + */ + if (IS_ENABLED(CONFIG_DRM_FBDEV_EMULATION) && + IS_MODULE(CONFIG_FRAMEBUFFER_CONSOLE) && + !IS_ENABLED(CONFIG_EXPERT)) + request_module_nowait("fbcon"); - /* Call init functions from specific kms helpers here */ - ret = drm_fb_helper_modinit(); - if (ret < 0) - goto out; - - ret = drm_dp_aux_dev_init(); - if (ret < 0) - goto out; - -out: - return ret; + return drm_dp_aux_dev_init(); } static void __exit drm_kms_helper_exit(void) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_lease.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_lease.c @@ -542,10 +542,12 @@ } DRM_DEBUG_LEASE("Creating lease\n"); + /* lessee will take the ownership of leases */ lessee = drm_lease_create(lessor, &leases); if (IS_ERR(lessee)) { ret = PTR_ERR(lessee); + idr_destroy(&leases); goto out_leases; } @@ -580,7 +582,6 @@ out_leases: put_unused_fd(fd); - idr_destroy(&leases); DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); return ret; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_mipi_dbi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_mipi_dbi.c @@ -367,9 +367,9 @@ memset(dbidev->tx_buf, 0, len); mipi_dbi_command(dbi, MIPI_DCS_SET_COLUMN_ADDRESS, 0, 0, - (width >> 8) & 0xFF, (width - 1) & 0xFF); + ((width - 1) >> 8) & 0xFF, (width - 1) & 0xFF); mipi_dbi_command(dbi, MIPI_DCS_SET_PAGE_ADDRESS, 0, 0, - (height >> 8) & 0xFF, (height - 1) & 0xFF); + ((height - 1) >> 8) & 0xFF, (height - 1) & 0xFF); mipi_dbi_command_buf(dbi, MIPI_DCS_WRITE_MEMORY_START, (u8 *)dbidev->tx_buf, len); @@ -937,7 +937,7 @@ } } - tr.len = chunk; + tr.len = chunk * 2; len -= chunk; ret = spi_sync(spi, &m); @@ -955,7 +955,7 @@ int ret; if (mipi_dbi_command_is_read(dbi, *cmd)) - return -ENOTSUPP; + return -EOPNOTSUPP; MIPI_DBI_DEBUG_COMMAND(*cmd, parameters, num); @@ -1156,6 +1156,13 @@ size_t chunk; int ret; + /* In __spi_validate, there's a validation that no partial transfers + * are accepted (xfer->len % w_size must be zero). + * Here we align max_chunk to multiple of 2 (16bits), + * to prevent transfers from being rejected. + */ + max_chunk = ALIGN_DOWN(max_chunk, 2); + spi_message_init_with_transfers(&m, &tr, 1); while (len) { @@ -1187,8 +1194,7 @@ struct mipi_dbi_dev *dbidev = m->private; u8 val, cmd = 0, parameters[64]; char *buf, *pos, *token; - unsigned int i; - int ret, idx; + int i, ret, idx; if (!drm_dev_enter(&dbidev->drm, &idx)) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_mipi_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_mipi_dsi.c @@ -300,6 +300,8 @@ { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); + if (dsi->attached) + mipi_dsi_detach(dsi); mipi_dsi_device_unregister(dsi); return 0; @@ -322,11 +324,18 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + int ret; if (!ops || !ops->attach) return -ENOSYS; - return ops->attach(dsi->host, dsi); + ret = ops->attach(dsi->host, dsi); + if (ret) + return ret; + + dsi->attached = true; + + return 0; } EXPORT_SYMBOL(mipi_dsi_attach); @@ -338,9 +347,14 @@ { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + if (WARN_ON(!dsi->attached)) + return -EINVAL; + if (!ops || !ops->detach) return -ENOSYS; + dsi->attached = false; + return ops->detach(dsi->host, dsi); } EXPORT_SYMBOL(mipi_dsi_detach); @@ -1029,11 +1043,11 @@ */ int mipi_dsi_dcs_set_tear_scanline(struct mipi_dsi_device *dsi, u16 scanline) { - u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, scanline >> 8, - scanline & 0xff }; + u8 payload[2] = { scanline >> 8, scanline & 0xff }; ssize_t err; - err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_SCANLINE, payload, + sizeof(payload)); if (err < 0) return err; @@ -1090,6 +1104,58 @@ } EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness); +/** + * mipi_dsi_dcs_set_display_brightness_large() - sets the 16-bit brightness value + * of the display + * @dsi: DSI peripheral device + * @brightness: brightness value + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_set_display_brightness_large(struct mipi_dsi_device *dsi, + u16 brightness) +{ + u8 payload[2] = { brightness >> 8, brightness & 0xff }; + ssize_t err; + + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, + payload, sizeof(payload)); + if (err < 0) + return err; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_set_display_brightness_large); + +/** + * mipi_dsi_dcs_get_display_brightness_large() - gets the current 16-bit + * brightness value of the display + * @dsi: DSI peripheral device + * @brightness: brightness value + * + * Return: 0 on success or a negative error code on failure. + */ +int mipi_dsi_dcs_get_display_brightness_large(struct mipi_dsi_device *dsi, + u16 *brightness) +{ + u8 brightness_be[2]; + ssize_t err; + + err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_DISPLAY_BRIGHTNESS, + brightness_be, sizeof(brightness_be)); + if (err <= 0) { + if (err == 0) + err = -ENODATA; + + return err; + } + + *brightness = (brightness_be[0] << 8) | brightness_be[1]; + + return 0; +} +EXPORT_SYMBOL(mipi_dsi_dcs_get_display_brightness_large); + static int mipi_dsi_drv_probe(struct device *dev) { struct mipi_dsi_driver *drv = to_mipi_dsi_driver(dev->driver); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_mm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_mm.c @@ -154,7 +154,7 @@ INTERVAL_TREE_DEFINE(struct drm_mm_node, rb, u64, __subtree_last, - START, LAST, static inline, drm_mm_interval_tree) + START, LAST, static inline __maybe_unused, drm_mm_interval_tree) struct drm_mm_node * __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_modes.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_modes.c @@ -1672,6 +1672,13 @@ } } + if (!(rotation & DRM_MODE_ROTATE_MASK)) + rotation |= DRM_MODE_ROTATE_0; + + /* Make sure there is exactly one rotation defined */ + if (!is_power_of_2(rotation & DRM_MODE_ROTATE_MASK)) + return -EINVAL; + mode->rotation_reflection = rotation; return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_panel.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_panel.c @@ -44,13 +44,21 @@ /** * drm_panel_init - initialize a panel * @panel: DRM panel + * @dev: parent device of the panel + * @funcs: panel operations + * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to + * the panel interface * - * Sets up internal fields of the panel so that it can subsequently be added - * to the registry. + * Initialize the panel structure for subsequent registration with + * drm_panel_add(). */ -void drm_panel_init(struct drm_panel *panel) +void drm_panel_init(struct drm_panel *panel, struct device *dev, + const struct drm_panel_funcs *funcs, int connector_type) { INIT_LIST_HEAD(&panel->list); + panel->dev = dev; + panel->funcs = funcs; + panel->connector_type = connector_type; } EXPORT_SYMBOL(drm_panel_init); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -30,12 +30,6 @@ int orientation; }; -static const struct drm_dmi_panel_orientation_data acer_s1003 = { - .width = 800, - .height = 1280, - .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, -}; - static const struct drm_dmi_panel_orientation_data asus_t100ha = { .width = 800, .height = 1280, @@ -50,6 +44,14 @@ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +static const struct drm_dmi_panel_orientation_data gpd_onemix2s = { + .width = 1200, + .height = 1920, + .bios_dates = (const char * const []){ "05/21/2018", "10/26/2018", + "03/04/2019", NULL }, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data gpd_pocket = { .width = 1200, .height = 1920, @@ -90,6 +92,13 @@ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +static const struct drm_dmi_panel_orientation_data onegx1_pro = { + .width = 1200, + .height = 1920, + .bios_dates = (const char * const []){ "12/17/2020", NULL }, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + static const struct drm_dmi_panel_orientation_data lcd720x1280_rightside_up = { .width = 720, .height = 1280, @@ -108,19 +117,67 @@ .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +static const struct drm_dmi_panel_orientation_data lcd1280x1920_rightside_up = { + .width = 1280, + .height = 1920, + .orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, +}; + +static const struct drm_dmi_panel_orientation_data lcd1600x2560_leftside_up = { + .width = 1600, + .height = 2560, + .orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP, +}; + static const struct dmi_system_id orientation_data[] = { { /* Acer One 10 (S1003) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), }, - .driver_data = (void *)&acer_s1003, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Acer Switch V 10 (SW5-017) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Anbernic Win600 */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Win600"), + }, + .driver_data = (void *)&lcd720x1280_rightside_up, }, { /* Asus T100HA */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"), }, .driver_data = (void *)&asus_t100ha, + }, { /* Asus T101HA */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T101HA"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Asus T103HAF */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* AYA NEO AYANEO 2 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* AYA NEO 2021 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYADEVICE"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYA NEO 2021"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* GPD MicroPC (generic strings, also match on bios date) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), @@ -135,6 +192,12 @@ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MicroPC"), }, .driver_data = (void *)&lcd720x1280_rightside_up, + }, { /* GPD Win Max */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1619-01"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* * GPD Pocket, note that the the DMI data is less generic then * it seems, devices with a board-vendor of "AMI Corporation" @@ -172,6 +235,12 @@ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), }, .driver_data = (void *)&gpd_win2, + }, { /* GPD Win 3 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03") + }, + .driver_data = (void *)&lcd720x1280_rightside_up, }, { /* I.T.Works TW891 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), @@ -180,6 +249,13 @@ DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"), }, .driver_data = (void *)&itworks_tw891, + }, { /* KD Kurio Smart C15200 2-in-1 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "KD Interactive"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Kurio Smart"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "KDM960BCP"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* * Lenovo Ideapad Miix 310 laptop, only some production batches * have a portrait screen, the resolution checks makes the quirk @@ -198,19 +274,89 @@ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), }, .driver_data = (void *)&lcd800x1280_rightside_up, - }, { /* Lenovo Ideapad D330 */ + }, { /* Lenovo Ideapad D330-10IGM (HD) */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "81H3"), DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Lenovo Ideapad D330-10IGM (FHD) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Lenovo Ideapad D330-10IGL (HD) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGL"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* Lenovo IdeaPad Duet 3 10IGL5 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Lenovo Yoga Book X90F / X90L */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Lenovo Yoga Book X91F / X91L */ + .matches = { + /* Non exact match to match F + L versions */ + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), + }, + .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* OneGX1 Pro */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SYSTEM_PRODUCT_NAME"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Default string"), + }, + .driver_data = (void *)&onegx1_pro, + }, { /* OneXPlayer */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ONE-NETBOOK TECHNOLOGY CO., LTD."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"), + }, + .driver_data = (void *)&lcd1600x2560_leftside_up, + }, { /* OrangePi Neo */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "OrangePi"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "NEO-01"), + }, .driver_data = (void *)&lcd1200x1920_rightside_up, + }, { /* Samsung GalaxyBook 10.6 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galaxy Book 10.6"), + }, + .driver_data = (void *)&lcd1280x1920_rightside_up, + }, { /* Valve Steam Deck */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jupiter"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"), + }, + .driver_data = (void *)&lcd800x1280_rightside_up, }, { /* VIOS LTH17 */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"), DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LTH17"), }, .driver_data = (void *)&lcd800x1280_rightside_up, + }, { /* One Mix 2S (generic strings, also match on bios date) */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), + }, + .driver_data = (void *)&gpd_onemix2s, }, {} }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_pci.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_pci.c @@ -51,8 +51,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align) { drm_dma_handle_t *dmah; - unsigned long addr; - size_t sz; /* pci_alloc_consistent only guarantees alignment to the smallest * PAGE_SIZE order which is greater than or equal to the requested size. @@ -68,20 +66,13 @@ dmah->size = size; dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, - GFP_KERNEL | __GFP_COMP); + GFP_KERNEL); if (dmah->vaddr == NULL) { kfree(dmah); return NULL; } - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Reserve */ - for (addr = (unsigned long)dmah->vaddr, sz = size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - SetPageReserved(virt_to_page((void *)addr)); - } - return dmah; } @@ -94,19 +85,9 @@ */ void __drm_legacy_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) { - unsigned long addr; - size_t sz; - - if (dmah->vaddr) { - /* XXX - Is virt_to_page() legal for consistent mem? */ - /* Unreserve */ - for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; - sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) { - ClearPageReserved(virt_to_page((void *)addr)); - } + if (dmah->vaddr) dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, dmah->busaddr); - } } /** --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_plane.c @@ -186,6 +186,13 @@ if (WARN_ON(config->num_total_plane >= 32)) return -EINVAL; + /* + * First driver to need more than 64 formats needs to fix this. Each + * format is encoded as a bit and the current code only supports a u64. + */ + if (WARN_ON(format_count > 64)) + return -EINVAL; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && (!funcs->atomic_destroy_state || !funcs->atomic_duplicate_state)); @@ -207,13 +214,6 @@ return -ENOMEM; } - /* - * First driver to need more than 64 formats needs to fix this. Each - * format is encoded as a bit and the current code only supports a u64. - */ - if (WARN_ON(format_count > 64)) - return -EINVAL; - if (format_modifiers) { const uint64_t *temp_modifiers = format_modifiers; while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) @@ -1203,6 +1203,7 @@ out: if (fb) drm_framebuffer_put(fb); + fb = NULL; if (plane->old_fb) drm_framebuffer_put(plane->old_fb); plane->old_fb = NULL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_plane_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_plane_helper.c @@ -123,7 +123,6 @@ .crtc_w = drm_rect_width(dst), .crtc_h = drm_rect_height(dst), .rotation = rotation, - .visible = *visible, }; struct drm_crtc_state crtc_state = { .crtc = crtc, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_prime.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_prime.c @@ -187,29 +187,33 @@ return -ENOENT; } -void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpriv, - struct dma_buf *dma_buf) +void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv, + uint32_t handle) { struct rb_node *rb; - rb = prime_fpriv->dmabufs.rb_node; + mutex_lock(&prime_fpriv->lock); + + rb = prime_fpriv->handles.rb_node; while (rb) { struct drm_prime_member *member; - member = rb_entry(rb, struct drm_prime_member, dmabuf_rb); - if (member->dma_buf == dma_buf) { + member = rb_entry(rb, struct drm_prime_member, handle_rb); + if (member->handle == handle) { rb_erase(&member->handle_rb, &prime_fpriv->handles); rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs); - dma_buf_put(dma_buf); + dma_buf_put(member->dma_buf); kfree(member); - return; - } else if (member->dma_buf < dma_buf) { + break; + } else if (member->handle < handle) { rb = rb->rb_right; } else { rb = rb->rb_left; } } + + mutex_unlock(&prime_fpriv->lock); } void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_print.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_print.c @@ -59,8 +59,9 @@ copy = iterator->remain; /* Copy out the bit of the string that we need */ - memcpy(iterator->data, - str + (iterator->start - iterator->offset), copy); + if (iterator->data) + memcpy(iterator->data, + str + (iterator->start - iterator->offset), copy); iterator->offset = iterator->start + copy; iterator->remain -= copy; @@ -69,7 +70,8 @@ len = min_t(ssize_t, strlen(str), iterator->remain); - memcpy(iterator->data + pos, str, len); + if (iterator->data) + memcpy(iterator->data + pos, str, len); iterator->offset += len; iterator->remain -= len; @@ -99,8 +101,9 @@ if ((iterator->offset >= iterator->start) && (len < iterator->remain)) { ssize_t pos = iterator->offset - iterator->start; - snprintf(((char *) iterator->data) + pos, - iterator->remain, "%pV", vaf); + if (iterator->data) + snprintf(((char *) iterator->data) + pos, + iterator->remain, "%pV", vaf); iterator->offset += len; iterator->remain -= len; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_probe_helper.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_probe_helper.c @@ -112,7 +112,7 @@ continue; } - ret = drm_bridge_mode_valid(encoder->bridge, mode); + ret = drm_bridge_chain_mode_valid(encoder->bridge, mode); if (ret != MODE_OK) { /* There is also no point in continuing for crtc check * here. */ @@ -460,8 +460,9 @@ */ dev->mode_config.delayed_event = true; if (dev->mode_config.poll_enabled) - schedule_delayed_work(&dev->mode_config.output_poll_work, - 0); + mod_delayed_work(system_wq, + &dev->mode_config.output_poll_work, + 0); } /* Re-enable polling in case the global poll config changed. */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_property.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_property.c @@ -561,7 +561,7 @@ struct drm_property_blob *blob; int ret; - if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob)) + if (!length || length > INT_MAX - sizeof(struct drm_property_blob)) return ERR_PTR(-EINVAL); blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_rect.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_rect.c @@ -54,7 +54,12 @@ static u32 clip_scaled(u32 src, u32 dst, u32 clip) { - u64 tmp = mul_u32_u32(src, dst - clip); + u64 tmp; + + if (dst == 0) + return 0; + + tmp = mul_u32_u32(src, dst - clip); /* * Round toward 1.0 when clipping so that we don't accidentally --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_syncobj.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_syncobj.c @@ -325,20 +325,37 @@ if (!syncobj) return -ENOENT; + /* Waiting for userspace with locks help is illegal cause that can + * trivial deadlock with page faults for example. Make lockdep complain + * about it early on. + */ + if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { + might_sleep(); + lockdep_assert_none_held_once(); + } + *fence = drm_syncobj_fence_get(syncobj); - drm_syncobj_put(syncobj); if (*fence) { ret = dma_fence_chain_find_seqno(fence, point); - if (!ret) - return 0; + if (!ret) { + /* If the requested seqno is already signaled + * drm_syncobj_find_fence may return a NULL + * fence. To make sure the recipient gets + * signalled, use a new fence instead. + */ + if (!*fence) + *fence = dma_fence_get_stub(); + + goto out; + } dma_fence_put(*fence); } else { ret = -EINVAL; } if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT)) - return ret; + goto out; memset(&wait, 0, sizeof(wait)); wait.task = current; @@ -370,6 +387,9 @@ if (wait.node.next) drm_syncobj_remove_wait(syncobj, &wait); +out: + drm_syncobj_put(syncobj); + return ret; } EXPORT_SYMBOL(drm_syncobj_find_fence); @@ -878,6 +898,10 @@ uint64_t *points; uint32_t signaled_count, i; + if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) + lockdep_assert_none_held_once(); + points = kmalloc_array(count, sizeof(*points), GFP_KERNEL); if (points == NULL) return -ENOMEM; @@ -910,7 +934,8 @@ fence = drm_syncobj_fence_get(syncobjs[i]); if (!fence || dma_fence_chain_find_seqno(&fence, points[i])) { dma_fence_put(fence); - if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { + if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { continue; } else { timeout = -EINVAL; @@ -943,7 +968,8 @@ * fallthough and try a 0 timeout wait! */ - if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { + if (flags & (DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT | + DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE)) { for (i = 0; i < count; ++i) drm_syncobj_fence_add_wait(syncobjs[i], &entries[i]); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_sysfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_sysfs.c @@ -293,9 +293,6 @@ return PTR_ERR(connector->kdev); } - /* Let userspace know we have a new connector */ - drm_sysfs_hotplug_event(dev); - if (connector->ddc) return sysfs_create_link(&connector->kdev->kobj, &connector->ddc->dev.kobj, "ddc"); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/drm_vblank.c +++ linux-oracle-5.4.0/drivers/gpu/drm/drm_vblank.c @@ -69,6 +69,12 @@ * &drm_driver.max_vblank_count. In that case the vblank core only disables the * vblanks after a timer has expired, which can be configured through the * ``vblankoffdelay`` module parameter. + * + * Drivers for hardware without support for vertical-blanking interrupts + * must not call drm_vblank_init(). For such drivers, atomic helpers will + * automatically generate fake vblank events as part of the display update. + * This functionality also can be controlled by the driver by enabling and + * disabling struct drm_crtc_state.no_vblank. */ /* Retry timestamp calculation up to 3 times to satisfy @@ -489,6 +495,28 @@ EXPORT_SYMBOL(drm_vblank_init); /** + * drm_dev_has_vblank - test if vblanking has been initialized for + * a device + * @dev: the device + * + * Drivers may call this function to test if vblank support is + * initialized for a device. For most hardware this means that vblanking + * can also be enabled. + * + * Atomic helpers use this function to initialize + * &drm_crtc_state.no_vblank. See also drm_atomic_helper_check_modeset(). + * + * Returns: + * True if vblanking has been initialized for the given device, false + * otherwise. + */ +bool drm_dev_has_vblank(const struct drm_device *dev) +{ + return dev->num_crtcs != 0; +} +EXPORT_SYMBOL(drm_dev_has_vblank); + +/** * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC * @crtc: which CRTC's vblank waitqueue to retrieve * @@ -1581,7 +1609,7 @@ unsigned int flags, pipe, high_pipe; if (!dev->irq_enabled) - return -EINVAL; + return -EOPNOTSUPP; if (vblwait->request.type & _DRM_VBLANK_SIGNAL) return -EINVAL; @@ -1838,7 +1866,7 @@ return -EOPNOTSUPP; if (!dev->irq_enabled) - return -EINVAL; + return -EOPNOTSUPP; crtc = drm_crtc_find(dev, file_priv, get_seq->crtc_id); if (!crtc) @@ -1896,7 +1924,7 @@ return -EOPNOTSUPP; if (!dev->irq_enabled) - return -EINVAL; + return -EOPNOTSUPP; crtc = drm_crtc_find(dev, file_priv, queue_seq->crtc_id); if (!crtc) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_buffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_buffer.c @@ -12,6 +12,7 @@ #include "common.xml.h" #include "state.xml.h" +#include "state_blt.xml.h" #include "state_hi.xml.h" #include "state_3d.xml.h" #include "cmdstream.xml.h" @@ -233,6 +234,8 @@ struct etnaviv_cmdbuf *buffer = &gpu->buffer; unsigned int waitlink_offset = buffer->user_size - 16; u32 link_target, flush = 0; + bool has_blt = !!(gpu->identity.minor_features5 & + chipMinorFeatures5_BLT_ENGINE); lockdep_assert_held(&gpu->lock); @@ -248,16 +251,38 @@ if (flush) { unsigned int dwords = 7; + if (has_blt) + dwords += 10; + link_target = etnaviv_buffer_reserve(gpu, buffer, dwords); CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + if (has_blt) { + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); + } CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush); - if (gpu->exec_state == ETNA_PIPE_3D) - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, - VIVS_TS_FLUSH_CACHE_FLUSH); + if (gpu->exec_state == ETNA_PIPE_3D) { + if (has_blt) { + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); + } else { + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, + VIVS_TS_FLUSH_CACHE_FLUSH); + } + } CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + if (has_blt) { + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); + } CMD_END(buffer); etnaviv_buffer_replace_wait(buffer, waitlink_offset, @@ -323,6 +348,8 @@ bool switch_mmu_context = gpu->mmu_context != mmu_context; unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq; + bool has_blt = !!(gpu->identity.minor_features5 & + chipMinorFeatures5_BLT_ENGINE); lockdep_assert_held(&gpu->lock); @@ -370,8 +397,7 @@ if (switch_mmu_context) { struct etnaviv_iommu_context *old_context = gpu->mmu_context; - etnaviv_iommu_context_get(mmu_context); - gpu->mmu_context = mmu_context; + gpu->mmu_context = etnaviv_iommu_context_get(mmu_context); etnaviv_iommu_context_put(old_context); } @@ -433,6 +459,15 @@ * 2 semaphore stall + 1 event + 1 wait + 1 link. */ return_dwords = 7; + + /* + * When the BLT engine is present we need 6 more dwords in the return + * target: 3 enable/flush/disable + 4 enable/semaphore stall/disable, + * but we don't need the normal TS flush state. + */ + if (has_blt) + return_dwords += 6; + return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); CMD_LINK(cmdbuf, return_dwords, return_target); @@ -446,12 +481,27 @@ } else { CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_DEPTH | - VIVS_GL_FLUSH_CACHE_COLOR); - CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, - VIVS_TS_FLUSH_CACHE_FLUSH); + VIVS_GL_FLUSH_CACHE_COLOR | + VIVS_GL_FLUSH_CACHE_SHADER_L1); + if (has_blt) { + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); + CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1); + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); + } else { + CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, + VIVS_TS_FLUSH_CACHE_FLUSH); + } } CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); + + if (has_blt) { + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1); + CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT); + CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0); + } + CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | VIVS_GL_EVENT_FROM_PE); CMD_WAIT(buffer); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -75,7 +75,7 @@ hdr->file_size = cpu_to_le32(data_end - iter->data); iter->hdr++; - iter->data += hdr->file_size; + iter->data += le32_to_cpu(hdr->file_size); } static void etnaviv_core_dump_registers(struct core_dump_iterator *iter, @@ -83,10 +83,15 @@ { struct etnaviv_dump_registers *reg = iter->data; unsigned int i; + u32 read_addr; for (i = 0; i < ARRAY_SIZE(etnaviv_dump_registers); i++, reg++) { - reg->reg = etnaviv_dump_registers[i]; - reg->value = gpu_read(gpu, etnaviv_dump_registers[i]); + read_addr = etnaviv_dump_registers[i]; + if (read_addr >= VIVS_PM_POWER_CONTROLS && + read_addr <= VIVS_PM_PULSE_EATER) + read_addr = gpu_fix_power_address(gpu, read_addr); + reg->reg = cpu_to_le32(etnaviv_dump_registers[i]); + reg->value = cpu_to_le32(gpu_read(gpu, read_addr)); } etnaviv_core_dump_header(iter, ETDUMP_BUF_REG, reg); @@ -125,9 +130,9 @@ return; etnaviv_dump_core = false; - mutex_lock(&gpu->mmu_context->lock); + mutex_lock(&submit->mmu_context->lock); - mmu_size = etnaviv_iommu_dump_size(gpu->mmu_context); + mmu_size = etnaviv_iommu_dump_size(submit->mmu_context); /* We always dump registers, mmu, ring, hanging cmdbuf and end marker */ n_obj = 5; @@ -157,7 +162,7 @@ iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, PAGE_KERNEL); if (!iter.start) { - mutex_unlock(&gpu->mmu_context->lock); + mutex_unlock(&submit->mmu_context->lock); dev_warn(gpu->dev, "failed to allocate devcoredump file\n"); return; } @@ -169,18 +174,18 @@ memset(iter.hdr, 0, iter.data - iter.start); etnaviv_core_dump_registers(&iter, gpu); - etnaviv_core_dump_mmu(&iter, gpu->mmu_context, mmu_size); + etnaviv_core_dump_mmu(&iter, submit->mmu_context, mmu_size); etnaviv_core_dump_mem(&iter, ETDUMP_BUF_RING, gpu->buffer.vaddr, gpu->buffer.size, etnaviv_cmdbuf_get_va(&gpu->buffer, - &gpu->mmu_context->cmdbuf_mapping)); + &submit->mmu_context->cmdbuf_mapping)); etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD, submit->cmdbuf.vaddr, submit->cmdbuf.size, etnaviv_cmdbuf_get_va(&submit->cmdbuf, - &gpu->mmu_context->cmdbuf_mapping)); + &submit->mmu_context->cmdbuf_mapping)); - mutex_unlock(&gpu->mmu_context->lock); + mutex_unlock(&submit->mmu_context->lock); /* Reserve space for the bomap */ if (n_bomap_pages) { @@ -207,7 +212,7 @@ if (!IS_ERR(pages)) { int j; - iter.hdr->data[0] = bomap - bomap_start; + iter.hdr->data[0] = cpu_to_le32((bomap - bomap_start)); for (j = 0; j < obj->base.size >> PAGE_SHIFT; j++) *bomap++ = cpu_to_le64(page_to_phys(*pages++)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -27,7 +27,7 @@ * because display controller, GPU, etc. are not coherent. */ if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK) - dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); + dma_map_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL, 0); } static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj) @@ -51,7 +51,7 @@ * discard those writes. */ if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK) - dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL); + dma_unmap_sgtable(dev->dev, sgt, DMA_BIDIRECTIONAL, 0); } /* called with etnaviv_obj->lock held */ @@ -304,8 +304,7 @@ list_del(&mapping->obj_node); } - etnaviv_iommu_context_get(mmu_context); - mapping->context = mmu_context; + mapping->context = etnaviv_iommu_context_get(mmu_context); mapping->use = 1; ret = etnaviv_iommu_map_gem(mmu_context, etnaviv_obj, @@ -351,6 +350,7 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) { struct page **pages; + pgprot_t prot; lockdep_assert_held(&obj->lock); @@ -358,15 +358,28 @@ if (IS_ERR(pages)) return NULL; - return vmap(pages, obj->base.size >> PAGE_SHIFT, - VM_MAP, pgprot_writecombine(PAGE_KERNEL)); + switch (obj->flags & ETNA_BO_CACHE_MASK) { + case ETNA_BO_CACHED: + prot = PAGE_KERNEL; + break; + case ETNA_BO_UNCACHED: + prot = pgprot_noncached(PAGE_KERNEL); + break; + case ETNA_BO_WC: + default: + prot = pgprot_writecombine(PAGE_KERNEL); + } + + return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot); } static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) { - if (op & ETNA_PREP_READ) + op &= ETNA_PREP_READ | ETNA_PREP_WRITE; + + if (op == ETNA_PREP_READ) return DMA_FROM_DEVICE; - else if (op & ETNA_PREP_WRITE) + else if (op == ETNA_PREP_WRITE) return DMA_TO_DEVICE; else return DMA_BIDIRECTIONAL; @@ -404,9 +417,8 @@ } if (etnaviv_obj->flags & ETNA_BO_CACHED) { - dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl, - etnaviv_obj->sgt->nents, - etnaviv_op_to_dma_dir(op)); + dma_sync_sgtable_for_cpu(dev->dev, etnaviv_obj->sgt, + etnaviv_op_to_dma_dir(op)); etnaviv_obj->last_cpu_prep_op = op; } @@ -421,8 +433,7 @@ if (etnaviv_obj->flags & ETNA_BO_CACHED) { /* fini without a prep is almost certainly a userspace error */ WARN_ON(etnaviv_obj->last_cpu_prep_op == 0); - dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl, - etnaviv_obj->sgt->nents, + dma_sync_sgtable_for_device(dev->dev, etnaviv_obj->sgt, etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op)); etnaviv_obj->last_cpu_prep_op = 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -93,7 +93,15 @@ static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj, struct vm_area_struct *vma) { - return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + int ret; + + ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + if (!ret) { + /* Drop the reference acquired by drm_gem_mmap_obj(). */ + drm_gem_object_put_unlocked(&etnaviv_obj->base); + } + + return ret; } static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -240,8 +240,10 @@ } if ((submit->flags & ETNA_SUBMIT_SOFTPIN) && - submit->bos[i].va != mapping->iova) + submit->bos[i].va != mapping->iova) { + etnaviv_gem_mapping_unreference(mapping); return -EINVAL; + } atomic_inc(&etnaviv_obj->gpu_active); @@ -469,6 +471,12 @@ return -EINVAL; } + if (args->stream_size > SZ_128K || args->nr_relocs > SZ_128K || + args->nr_bos > SZ_128K || args->nr_pmrs > 128) { + DRM_ERROR("submit arguments out of size limits\n"); + return -EINVAL; + } + /* * Copy the command submission and bo array to kernel space in * one go, and do this outside of any locks. @@ -532,8 +540,7 @@ goto err_submit_objects; submit->ctx = file->driver_priv; - etnaviv_iommu_context_get(submit->ctx->mmu); - submit->mmu_context = submit->ctx->mmu; + submit->mmu_context = etnaviv_iommu_context_get(submit->ctx->mmu); submit->exec_state = args->exec_state; submit->flags = args->flags; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -392,6 +392,12 @@ if (gpu->identity.model == chipModel_GC700) gpu->identity.features &= ~chipFeatures_FAST_CLEAR; + /* These models/revisions don't have the 2D pipe bit */ + if ((gpu->identity.model == chipModel_GC500 && + gpu->identity.revision <= 2) || + gpu->identity.model == chipModel_GC300) + gpu->identity.features |= chipFeatures_PIPE_2D; + if ((gpu->identity.model == chipModel_GC500 && gpu->identity.revision < 2) || (gpu->identity.model == chipModel_GC300 && @@ -425,8 +431,9 @@ gpu_read(gpu, VIVS_HI_CHIP_MINOR_FEATURE_5); } - /* GC600 idle register reports zero bits where modules aren't present */ - if (gpu->identity.model == chipModel_GC600) + /* GC600/300 idle register reports zero bits where modules aren't present */ + if (gpu->identity.model == chipModel_GC600 || + gpu->identity.model == chipModel_GC300) gpu->idle_mask = VIVS_HI_IDLE_STATE_TX | VIVS_HI_IDLE_STATE_RA | VIVS_HI_IDLE_STATE_SE | @@ -545,6 +552,12 @@ /* We rely on the GPU running, so program the clock */ etnaviv_gpu_update_clock(gpu); + gpu->fe_running = false; + gpu->exec_state = -1; + if (gpu->mmu_context) + etnaviv_iommu_context_put(gpu->mmu_context); + gpu->mmu_context = NULL; + return 0; } @@ -553,7 +566,7 @@ u32 pmc, ppc; /* enable clock gating */ - ppc = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); + ppc = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); ppc |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; /* Disable stall module clock gating for 4.3.0.1 and 4.3.0.2 revs */ @@ -561,9 +574,9 @@ gpu->identity.revision == 0x4302) ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING; - gpu_write(gpu, VIVS_PM_POWER_CONTROLS, ppc); + gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc); - pmc = gpu_read(gpu, VIVS_PM_MODULE_CONTROLS); + pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS); /* Disable PA clock gating for GC400+ without bugfix except for GC420 */ if (gpu->identity.model >= chipModel_GC400 && @@ -592,7 +605,7 @@ pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ; pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ; - gpu_write(gpu, VIVS_PM_MODULE_CONTROLS, pmc); + gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc); } void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch) @@ -607,19 +620,23 @@ VIVS_MMUv2_SEC_COMMAND_CONTROL_ENABLE | VIVS_MMUv2_SEC_COMMAND_CONTROL_PREFETCH(prefetch)); } + + gpu->fe_running = true; } -static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu) +static void etnaviv_gpu_start_fe_idleloop(struct etnaviv_gpu *gpu, + struct etnaviv_iommu_context *context) { - u32 address = etnaviv_cmdbuf_get_va(&gpu->buffer, - &gpu->mmu_context->cmdbuf_mapping); u16 prefetch; + u32 address; /* setup the MMU */ - etnaviv_iommu_restore(gpu, gpu->mmu_context); + etnaviv_iommu_restore(gpu, context); /* Start command processor */ prefetch = etnaviv_buffer_init(gpu); + address = etnaviv_cmdbuf_get_va(&gpu->buffer, + &gpu->mmu_context->cmdbuf_mapping); etnaviv_gpu_start_fe(gpu, address, prefetch); } @@ -648,11 +665,11 @@ (gpu->identity.features & chipFeatures_PIPE_3D)) { /* Performance fix: disable internal DFS */ - pulse_eater = gpu_read(gpu, VIVS_PM_PULSE_EATER); + pulse_eater = gpu_read_power(gpu, VIVS_PM_PULSE_EATER); pulse_eater |= BIT(18); } - gpu_write(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); } static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) @@ -713,7 +730,7 @@ ret = pm_runtime_get_sync(gpu->dev); if (ret < 0) { dev_err(gpu->dev, "Failed to enable GPU power domain\n"); - return ret; + goto pm_put; } etnaviv_hw_identify(gpu); @@ -790,7 +807,6 @@ /* Now program the hardware */ mutex_lock(&gpu->lock); etnaviv_gpu_hw_init(gpu); - gpu->exec_state = -1; mutex_unlock(&gpu->lock); pm_runtime_mark_last_busy(gpu->dev); @@ -802,6 +818,7 @@ fail: pm_runtime_mark_last_busy(gpu->dev); +pm_put: pm_runtime_put_autosuspend(gpu->dev); return ret; @@ -842,7 +859,7 @@ ret = pm_runtime_get_sync(gpu->dev); if (ret < 0) - return ret; + goto pm_put; dma_lo = gpu_read(gpu, VIVS_FE_DMA_LOW); dma_hi = gpu_read(gpu, VIVS_FE_DMA_HIGH); @@ -965,6 +982,7 @@ ret = 0; pm_runtime_mark_last_busy(gpu->dev); +pm_put: pm_runtime_put_autosuspend(gpu->dev); return ret; @@ -978,7 +996,7 @@ dev_err(gpu->dev, "recover hung GPU!\n"); if (pm_runtime_get_sync(gpu->dev) < 0) - return; + goto pm_put; mutex_lock(&gpu->lock); @@ -992,11 +1010,10 @@ spin_unlock(&gpu->event_spinlock); etnaviv_gpu_hw_init(gpu); - gpu->exec_state = -1; - gpu->mmu_context = NULL; mutex_unlock(&gpu->lock); pm_runtime_mark_last_busy(gpu->dev); +pm_put: pm_runtime_put_autosuspend(gpu->dev); } @@ -1219,10 +1236,12 @@ { u32 val; + mutex_lock(&gpu->lock); + /* disable clock gating */ - val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); + val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; - gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); + gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val); /* enable debug register */ val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); @@ -1230,6 +1249,8 @@ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE); + + mutex_unlock(&gpu->lock); } static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu, @@ -1239,13 +1260,9 @@ unsigned int i; u32 val; - sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); - - for (i = 0; i < submit->nr_pmrs; i++) { - const struct etnaviv_perfmon_request *pmr = submit->pmrs + i; + mutex_lock(&gpu->lock); - *pmr->bo_vma = pmr->sequence; - } + sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST); /* disable debug register */ val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL); @@ -1253,9 +1270,17 @@ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val); /* enable clock gating */ - val = gpu_read(gpu, VIVS_PM_POWER_CONTROLS); + val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS); val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING; - gpu_write(gpu, VIVS_PM_POWER_CONTROLS, val); + gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val); + + mutex_unlock(&gpu->lock); + + for (i = 0; i < submit->nr_pmrs; i++) { + const struct etnaviv_perfmon_request *pmr = submit->pmrs + i; + + *pmr->bo_vma = pmr->sequence; + } } @@ -1269,8 +1294,10 @@ if (!submit->runtime_resumed) { ret = pm_runtime_get_sync(gpu->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(gpu->dev); return NULL; + } submit->runtime_resumed = true; } @@ -1287,6 +1314,7 @@ ret = event_alloc(gpu, nr_events, event); if (ret) { DRM_ERROR("no free events\n"); + pm_runtime_put_noidle(gpu->dev); return NULL; } @@ -1300,14 +1328,12 @@ goto out_unlock; } - if (!gpu->mmu_context) { - etnaviv_iommu_context_get(submit->mmu_context); - gpu->mmu_context = submit->mmu_context; - etnaviv_gpu_start_fe_idleloop(gpu); - } else { - etnaviv_iommu_context_get(gpu->mmu_context); - submit->prev_mmu_context = gpu->mmu_context; - } + if (!gpu->fe_running) + etnaviv_gpu_start_fe_idleloop(gpu, submit->mmu_context); + + if (submit->prev_mmu_context) + etnaviv_iommu_context_put(submit->prev_mmu_context); + submit->prev_mmu_context = etnaviv_iommu_context_get(gpu->mmu_context); if (submit->nr_pmrs) { gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre; @@ -1457,7 +1483,7 @@ if (gpu->clk_bus) { ret = clk_prepare_enable(gpu->clk_bus); if (ret) - return ret; + goto disable_clk_reg; } if (gpu->clk_core) { @@ -1480,6 +1506,9 @@ disable_clk_bus: if (gpu->clk_bus) clk_disable_unprepare(gpu->clk_bus); +disable_clk_reg: + if (gpu->clk_reg) + clk_disable_unprepare(gpu->clk_reg); return ret; } @@ -1521,7 +1550,7 @@ static int etnaviv_gpu_hw_suspend(struct etnaviv_gpu *gpu) { - if (gpu->initialized && gpu->mmu_context) { + if (gpu->initialized && gpu->fe_running) { /* Replace the last WAIT with END */ mutex_lock(&gpu->lock); etnaviv_buffer_end(gpu); @@ -1534,8 +1563,7 @@ */ etnaviv_gpu_wait_idle(gpu, 100); - etnaviv_iommu_context_put(gpu->mmu_context); - gpu->mmu_context = NULL; + gpu->fe_running = false; } gpu->exec_state = -1; @@ -1683,6 +1711,9 @@ etnaviv_gpu_hw_suspend(gpu); #endif + if (gpu->mmu_context) + etnaviv_iommu_context_put(gpu->mmu_context); + if (gpu->initialized) { etnaviv_cmdbuf_free(&gpu->buffer); etnaviv_iommu_global_fini(gpu); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -10,6 +10,7 @@ #include "etnaviv_gem.h" #include "etnaviv_mmu.h" #include "etnaviv_drv.h" +#include "common.xml.h" struct etnaviv_gem_submit; struct etnaviv_vram_mapping; @@ -101,6 +102,7 @@ struct workqueue_struct *wq; struct drm_gpu_scheduler sched; bool initialized; + bool fe_running; /* 'ring'-buffer: */ struct etnaviv_cmdbuf buffer; @@ -157,6 +159,26 @@ return readl(gpu->mmio + reg); } +static inline u32 gpu_fix_power_address(struct etnaviv_gpu *gpu, u32 reg) +{ + /* Power registers in GC300 < 2.0 are offset by 0x100 */ + if (gpu->identity.model == chipModel_GC300 && + gpu->identity.revision < 0x2000) + reg += 0x100; + + return reg; +} + +static inline void gpu_write_power(struct etnaviv_gpu *gpu, u32 reg, u32 data) +{ + writel(data, gpu->mmio + gpu_fix_power_address(gpu, reg)); +} + +static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg) +{ + return readl(gpu->mmio + gpu_fix_power_address(gpu, reg)); +} + int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); int etnaviv_gpu_init(struct etnaviv_gpu *gpu); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -92,6 +92,10 @@ struct etnaviv_iommuv1_context *v1_context = to_v1_context(context); u32 pgtable; + if (gpu->mmu_context) + etnaviv_iommu_context_put(gpu->mmu_context); + gpu->mmu_context = etnaviv_iommu_context_get(context); + /* set base addresses */ gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_RA, context->global->memory_base); gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_FE, context->global->memory_base); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_iommu_v2.c @@ -172,6 +172,10 @@ if (gpu_read(gpu, VIVS_MMUv2_CONTROL) & VIVS_MMUv2_CONTROL_ENABLE) return; + if (gpu->mmu_context) + etnaviv_iommu_context_put(gpu->mmu_context); + gpu->mmu_context = etnaviv_iommu_context_get(context); + prefetch = etnaviv_buffer_config_mmuv2(gpu, (u32)v2_context->mtlb_dma, (u32)context->global->bad_page_dma); @@ -192,6 +196,10 @@ if (gpu_read(gpu, VIVS_MMUv2_SEC_CONTROL) & VIVS_MMUv2_SEC_CONTROL_ENABLE) return; + if (gpu->mmu_context) + etnaviv_iommu_context_put(gpu->mmu_context); + gpu->mmu_context = etnaviv_iommu_context_get(context); + gpu_write(gpu, VIVS_MMUv2_PTA_ADDRESS_LOW, lower_32_bits(context->global->v2.pta_dma)); gpu_write(gpu, VIVS_MMUv2_PTA_ADDRESS_HIGH, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -73,17 +73,17 @@ struct sg_table *sgt, unsigned len, int prot) { struct scatterlist *sg; unsigned int da = iova; - unsigned int i, j; + unsigned int i; int ret; if (!context || !sgt) return -EINVAL; - for_each_sg(sgt->sgl, sg, sgt->nents, i) { - u32 pa = sg_dma_address(sg) - sg->offset; + for_each_sgtable_dma_sg(sgt, sg, i) { + phys_addr_t pa = sg_dma_address(sg) - sg->offset; size_t bytes = sg_dma_len(sg) + sg->offset; - VERB("map[%d]: %08x %08x(%zx)", i, iova, pa, bytes); + VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes); ret = etnaviv_context_map(context, da, pa, bytes, prot); if (ret) @@ -95,14 +95,7 @@ return 0; fail: - da = iova; - - for_each_sg(sgt->sgl, sg, i, j) { - size_t bytes = sg_dma_len(sg) + sg->offset; - - etnaviv_context_unmap(context, da, bytes); - da += bytes; - } + etnaviv_context_unmap(context, iova, da - iova); return ret; } @@ -113,7 +106,7 @@ unsigned int da = iova; int i; - for_each_sg(sgt->sgl, sg, sgt->nents, i) { + for_each_sgtable_dma_sg(sgt, sg, i) { size_t bytes = sg_dma_len(sg) + sg->offset; etnaviv_context_unmap(context, da, bytes); @@ -204,6 +197,7 @@ */ list_for_each_entry_safe(m, n, &list, scan_node) { etnaviv_iommu_remove_mapping(context, m); + etnaviv_iommu_context_put(m->context); m->context = NULL; list_del_init(&m->mmu_node); list_del_init(&m->scan_node); @@ -288,6 +282,12 @@ mutex_lock(&context->lock); + /* Bail if the mapping has been reaped by another thread */ + if (!mapping->context) { + mutex_unlock(&context->lock); + return; + } + /* If the vram node is on the mm, unmap and remove the node */ if (mapping->vram_node.mm == &context->mm) etnaviv_iommu_remove_mapping(context, mapping); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_mmu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_mmu.h @@ -105,9 +105,11 @@ struct etnaviv_iommu_context * etnaviv_iommu_context_init(struct etnaviv_iommu_global *global, struct etnaviv_cmdbuf_suballoc *suballoc); -static inline void etnaviv_iommu_context_get(struct etnaviv_iommu_context *ctx) +static inline struct etnaviv_iommu_context * +etnaviv_iommu_context_get(struct etnaviv_iommu_context *ctx) { kref_get(&ctx->refcount); + return ctx; } void etnaviv_iommu_context_put(struct etnaviv_iommu_context *ctx); void etnaviv_iommu_restore(struct etnaviv_gpu *gpu, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c @@ -32,6 +32,7 @@ }; struct etnaviv_pm_domain_meta { + unsigned int feature; const struct etnaviv_pm_domain *domains; u32 nr_domains; }; @@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain_meta doms_meta[] = { { + .feature = chipFeatures_PIPE_3D, .nr_domains = ARRAY_SIZE(doms_3d), .domains = &doms_3d[0] }, { + .feature = chipFeatures_PIPE_2D, .nr_domains = ARRAY_SIZE(doms_2d), .domains = &doms_2d[0] }, { + .feature = chipFeatures_PIPE_VG, .nr_domains = ARRAY_SIZE(doms_vg), .domains = &doms_vg[0] } }; +static unsigned int num_pm_domains(const struct etnaviv_gpu *gpu) +{ + unsigned int num = 0, i; + + for (i = 0; i < ARRAY_SIZE(doms_meta); i++) { + const struct etnaviv_pm_domain_meta *meta = &doms_meta[i]; + + if (gpu->identity.features & meta->feature) + num += meta->nr_domains; + } + + return num; +} + +static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu, + unsigned int index) +{ + const struct etnaviv_pm_domain *domain = NULL; + unsigned int offset = 0, i; + + for (i = 0; i < ARRAY_SIZE(doms_meta); i++) { + const struct etnaviv_pm_domain_meta *meta = &doms_meta[i]; + + if (!(gpu->identity.features & meta->feature)) + continue; + + if (index - offset >= meta->nr_domains) { + offset += meta->nr_domains; + continue; + } + + domain = meta->domains + (index - offset); + } + + return domain; +} + int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, struct drm_etnaviv_pm_domain *domain) { - const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe]; + const unsigned int nr_domains = num_pm_domains(gpu); const struct etnaviv_pm_domain *dom; - if (domain->iter >= meta->nr_domains) + if (domain->iter >= nr_domains) return -EINVAL; - dom = meta->domains + domain->iter; + dom = pm_domain(gpu, domain->iter); + if (!dom) + return -EINVAL; domain->id = domain->iter; domain->nr_signals = dom->nr_signals; strncpy(domain->name, dom->name, sizeof(domain->name)); domain->iter++; - if (domain->iter == meta->nr_domains) + if (domain->iter == nr_domains) domain->iter = 0xff; return 0; @@ -448,14 +491,16 @@ int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, struct drm_etnaviv_pm_signal *signal) { - const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe]; + const unsigned int nr_domains = num_pm_domains(gpu); const struct etnaviv_pm_domain *dom; const struct etnaviv_pm_signal *sig; - if (signal->domain >= meta->nr_domains) + if (signal->domain >= nr_domains) return -EINVAL; - dom = meta->domains + signal->domain; + dom = pm_domain(gpu, signal->domain); + if (!dom) + return -EINVAL; if (signal->iter >= dom->nr_signals) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/etnaviv/state_blt.xml.h +++ linux-oracle-5.4.0/drivers/gpu/drm/etnaviv/state_blt.xml.h @@ -46,6 +46,8 @@ /* This is a cut-down version of the state_blt.xml.h file */ +#define VIVS_BLT_SET_COMMAND 0x000140ac + #define VIVS_BLT_ENABLE 0x000140b8 #define VIVS_BLT_ENABLE_ENABLE 0x00000001 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -55,6 +55,7 @@ struct decon_context { struct device *dev; struct drm_device *drm_dev; + void *dma_priv; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct exynos_drm_plane_config configs[WINDOWS_NR]; @@ -317,9 +318,9 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, struct drm_framebuffer *fb) { - struct exynos_drm_plane plane = ctx->planes[win]; + struct exynos_drm_plane *plane = &ctx->planes[win]; struct exynos_drm_plane_state *state = - to_exynos_plane_state(plane.base.state); + to_exynos_plane_state(plane->base.state); unsigned int alpha = state->base.alpha; unsigned int pixel_alpha; unsigned long val; @@ -644,7 +645,7 @@ decon_clear_channels(ctx->crtc); - return exynos_drm_register_dma(drm_dev, dev); + return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); } static void decon_unbind(struct device *dev, struct device *master, void *data) @@ -654,7 +655,7 @@ decon_disable(ctx->crtc); /* detach this sub driver from iommu mapping if supported. */ - exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); } static const struct component_ops decon_component_ops = { @@ -774,8 +775,8 @@ return irq; } } - irq_set_status_flags(irq, IRQ_NOAUTOEN); - ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx); + ret = devm_request_irq(ctx->dev, irq, handler, + flags | IRQF_NO_AUTOEN, "drm_decon", ctx); if (ret < 0) { dev_err(ctx->dev, "IRQ %s request failed\n", name); return ret; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos7_drm_decon.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos7_drm_decon.c @@ -40,6 +40,7 @@ struct decon_context { struct device *dev; struct drm_device *drm_dev; + void *dma_priv; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct exynos_drm_plane_config configs[WINDOWS_NR]; @@ -127,13 +128,13 @@ decon_clear_channels(ctx->crtc); - return exynos_drm_register_dma(drm_dev, ctx->dev); + return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv); } static void decon_ctx_remove(struct decon_context *ctx) { /* detach this sub driver from iommu mapping if supported. */ - exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); } static u32 decon_calc_clkdiv(struct decon_context *ctx, @@ -799,31 +800,40 @@ if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the pclk [%d]\n", ret); - return ret; + goto err_pclk_enable; } ret = clk_prepare_enable(ctx->aclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the aclk [%d]\n", ret); - return ret; + goto err_aclk_enable; } ret = clk_prepare_enable(ctx->eclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the eclk [%d]\n", ret); - return ret; + goto err_eclk_enable; } ret = clk_prepare_enable(ctx->vclk); if (ret < 0) { DRM_DEV_ERROR(dev, "Failed to prepare_enable the vclk [%d]\n", ret); - return ret; + goto err_vclk_enable; } return 0; + +err_vclk_enable: + clk_disable_unprepare(ctx->eclk); +err_eclk_enable: + clk_disable_unprepare(ctx->aclk); +err_aclk_enable: + clk_disable_unprepare(ctx->pclk); +err_pclk_enable: + return ret; } #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_dp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_dp.c @@ -109,7 +109,6 @@ if (ret) { DRM_DEV_ERROR(dp->dev, "Failed to attach bridge to drm\n"); - bridge->next = NULL; return ret; } } @@ -158,15 +157,8 @@ struct drm_device *drm_dev = data; int ret; - dp->dev = dev; dp->drm_dev = drm_dev; - dp->plat_data.dev_type = EXYNOS_DP; - dp->plat_data.power_on_start = exynos_dp_poweron; - dp->plat_data.power_off = exynos_dp_poweroff; - dp->plat_data.attach = exynos_dp_bridge_attach; - dp->plat_data.get_modes = exynos_dp_get_modes; - if (!dp->plat_data.panel && !dp->ptn_bridge) { ret = exynos_dp_dt_parse_panel(dp); if (ret) @@ -184,13 +176,11 @@ dp->plat_data.encoder = encoder; - dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); - if (IS_ERR(dp->adp)) { + ret = analogix_dp_bind(dp->adp, dp->drm_dev); + if (ret) dp->encoder.funcs->destroy(&dp->encoder); - return PTR_ERR(dp->adp); - } - return 0; + return ret; } static void exynos_dp_unbind(struct device *dev, struct device *master, @@ -221,6 +211,7 @@ if (!dp) return -ENOMEM; + dp->dev = dev; /* * We just use the drvdata until driver run into component * add function, and then we would set drvdata to null, so @@ -246,16 +237,29 @@ /* The remote port can be either a panel or a bridge */ dp->plat_data.panel = panel; + dp->plat_data.dev_type = EXYNOS_DP; + dp->plat_data.power_on_start = exynos_dp_poweron; + dp->plat_data.power_off = exynos_dp_poweroff; + dp->plat_data.attach = exynos_dp_bridge_attach; + dp->plat_data.get_modes = exynos_dp_get_modes; dp->plat_data.skip_connector = !!bridge; + dp->ptn_bridge = bridge; out: + dp->adp = analogix_dp_probe(dev, &dp->plat_data); + if (IS_ERR(dp->adp)) + return PTR_ERR(dp->adp); + return component_add(&pdev->dev, &exynos_dp_ops); } static int exynos_dp_remove(struct platform_device *pdev) { + struct exynos_dp_device *dp = platform_get_drvdata(pdev); + component_del(&pdev->dev, &exynos_dp_ops); + analogix_dp_remove(dp->adp); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -39,13 +39,12 @@ if (exynos_crtc->ops->disable) exynos_crtc->ops->disable(exynos_crtc); + spin_lock_irq(&crtc->dev->event_lock); if (crtc->state->event && !crtc->state->active) { - spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); - spin_unlock_irq(&crtc->dev->event_lock); - crtc->state->event = NULL; } + spin_unlock_irq(&crtc->dev->event_lock); } static int exynos_crtc_atomic_check(struct drm_crtc *crtc, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_dma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_dma.c @@ -58,10 +58,10 @@ * mapping. */ static int drm_iommu_attach_device(struct drm_device *drm_dev, - struct device *subdrv_dev) + struct device *subdrv_dev, void **dma_priv) { struct exynos_drm_private *priv = drm_dev->dev_private; - int ret; + int ret = 0; if (get_dma_ops(priv->dma_dev) != get_dma_ops(subdrv_dev)) { DRM_DEV_ERROR(subdrv_dev, "Device %s lacks support for IOMMU\n", @@ -74,7 +74,14 @@ return ret; if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { - if (to_dma_iommu_mapping(subdrv_dev)) + /* + * Keep the original DMA mapping of the sub-device and + * restore it on Exynos DRM detach, otherwise the DMA + * framework considers it as IOMMU-less during the next + * probe (in case of deferred probe or modular build) + */ + *dma_priv = to_dma_iommu_mapping(subdrv_dev); + if (*dma_priv) arm_iommu_detach_device(subdrv_dev); ret = arm_iommu_attach_device(subdrv_dev, priv->mapping); @@ -85,7 +92,7 @@ if (ret) clear_dma_max_seg_size(subdrv_dev); - return 0; + return ret; } /* @@ -98,19 +105,21 @@ * mapping */ static void drm_iommu_detach_device(struct drm_device *drm_dev, - struct device *subdrv_dev) + struct device *subdrv_dev, void **dma_priv) { struct exynos_drm_private *priv = drm_dev->dev_private; - if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { arm_iommu_detach_device(subdrv_dev); - else if (IS_ENABLED(CONFIG_IOMMU_DMA)) + arm_iommu_attach_device(subdrv_dev, *dma_priv); + } else if (IS_ENABLED(CONFIG_IOMMU_DMA)) iommu_detach_device(priv->mapping, subdrv_dev); clear_dma_max_seg_size(subdrv_dev); } -int exynos_drm_register_dma(struct drm_device *drm, struct device *dev) +int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, + void **dma_priv) { struct exynos_drm_private *priv = drm->dev_private; @@ -124,7 +133,7 @@ return 0; if (!priv->mapping) { - void *mapping; + void *mapping = NULL; if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) mapping = arm_iommu_create_mapping(&platform_bus_type, @@ -132,18 +141,19 @@ else if (IS_ENABLED(CONFIG_IOMMU_DMA)) mapping = iommu_get_domain_for_dev(priv->dma_dev); - if (IS_ERR(mapping)) - return PTR_ERR(mapping); + if (!mapping) + return -ENODEV; priv->mapping = mapping; } - return drm_iommu_attach_device(drm, dev); + return drm_iommu_attach_device(drm, dev, dma_priv); } -void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev) +void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev, + void **dma_priv) { if (IS_ENABLED(CONFIG_EXYNOS_IOMMU)) - drm_iommu_detach_device(drm, dev); + drm_iommu_detach_device(drm, dev, dma_priv); } void exynos_drm_cleanup_dma(struct drm_device *drm) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -346,6 +346,7 @@ drm_mode_config_cleanup(drm); exynos_drm_cleanup_dma(drm); kfree(private); + dev_set_drvdata(dev, NULL); err_free_drm: drm_dev_put(drm); @@ -360,6 +361,7 @@ exynos_drm_fbdev_fini(drm); drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); component_unbind_all(drm->dev, drm); drm_mode_config_cleanup(drm); @@ -397,9 +399,18 @@ return 0; } +static void exynos_drm_platform_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + if (drm) + drm_atomic_helper_shutdown(drm); +} + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, + .shutdown = exynos_drm_platform_shutdown, .driver = { .name = "exynos-drm", .pm = &exynos_drm_pm_ops, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -223,8 +223,10 @@ return priv->mapping ? true : false; } -int exynos_drm_register_dma(struct drm_device *drm, struct device *dev); -void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev); +int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, + void **dma_priv); +void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev, + void **dma_priv); void exynos_drm_cleanup_dma(struct drm_device *drm); #ifdef CONFIG_DRM_EXYNOS_DPI --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -544,9 +544,9 @@ unsigned long best_freq = 0; u32 min_delta = 0xffffffff; u8 p_min, p_max; - u8 _p, uninitialized_var(best_p); - u16 _m, uninitialized_var(best_m); - u8 _s, uninitialized_var(best_s); + u8 _p, best_p; + u16 _m, best_m; + u8 _s, best_s; p_min = DIV_ROUND_UP(fin, (12 * MHZ)); p_max = fin / (6 * MHZ); @@ -1350,10 +1350,9 @@ } te_gpio_irq = gpio_to_irq(dsi->te_gpio); - irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN); ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL, - IRQF_TRIGGER_RISING, "TE", dsi); + IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi); if (ret) { dev_err(dsi->dev, "request interrupt failed with %d\n", ret); gpio_free(dsi->te_gpio); @@ -1389,7 +1388,7 @@ if (ret < 0) goto err_put_sync; } else { - drm_bridge_pre_enable(dsi->out_bridge); + drm_bridge_chain_pre_enable(dsi->out_bridge); } exynos_dsi_set_display_mode(dsi); @@ -1400,7 +1399,7 @@ if (ret < 0) goto err_display_disable; } else { - drm_bridge_enable(dsi->out_bridge); + drm_bridge_chain_enable(dsi->out_bridge); } dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; @@ -1425,10 +1424,10 @@ dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; drm_panel_disable(dsi->panel); - drm_bridge_disable(dsi->out_bridge); + drm_bridge_chain_disable(dsi->out_bridge); exynos_dsi_set_display_enable(dsi, false); drm_panel_unprepare(dsi->panel); - drm_bridge_post_disable(dsi->out_bridge); + drm_bridge_chain_post_disable(dsi->out_bridge); dsi->state &= ~DSIM_STATE_ENABLED; pm_runtime_put_sync(dsi->dev); } @@ -1741,17 +1740,14 @@ dsi->dev = dev; dsi->driver_data = of_device_get_match_data(dev); - ret = exynos_dsi_parse_dt(dsi); - if (ret) - return ret; - dsi->supplies[0].supply = "vddcore"; dsi->supplies[1].supply = "vddio"; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies), dsi->supplies); if (ret) { - dev_info(dev, "failed to get regulators: %d\n", ret); - return -EPROBE_DEFER; + if (ret != -EPROBE_DEFER) + dev_info(dev, "failed to get regulators: %d\n", ret); + return ret; } dsi->clks = devm_kcalloc(dev, @@ -1764,9 +1760,10 @@ dsi->clks[i] = devm_clk_get(dev, clk_names[i]); if (IS_ERR(dsi->clks[i])) { if (strcmp(clk_names[i], "sclk_mipi") == 0) { - strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME); - i--; - continue; + dsi->clks[i] = devm_clk_get(dev, + OLD_SCLK_MIPI_CLK_NAME); + if (!IS_ERR(dsi->clks[i])) + continue; } dev_info(dev, "failed to get the clock: %s\n", @@ -1794,20 +1791,34 @@ return dsi->irq; } - irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN); ret = devm_request_threaded_irq(dev, dsi->irq, NULL, - exynos_dsi_irq, IRQF_ONESHOT, + exynos_dsi_irq, + IRQF_ONESHOT | IRQF_NO_AUTOEN, dev_name(dev), dsi); if (ret) { dev_err(dev, "failed to request dsi irq\n"); return ret; } + ret = exynos_dsi_parse_dt(dsi); + if (ret) + return ret; + platform_set_drvdata(pdev, &dsi->encoder); pm_runtime_enable(dev); - return component_add(dev, &exynos_dsi_component_ops); + ret = component_add(dev, &exynos_dsi_component_ops); + if (ret) + goto err_disable_runtime; + + return 0; + +err_disable_runtime: + pm_runtime_disable(dev); + of_node_put(dsi->in_bridge_node); + + return ret; } static int exynos_dsi_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_fimc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_fimc.c @@ -97,6 +97,7 @@ struct fimc_context { struct exynos_drm_ipp ipp; struct drm_device *drm_dev; + void *dma_priv; struct device *dev; struct exynos_drm_ipp_task *task; struct exynos_drm_ipp_formats *formats; @@ -1133,7 +1134,7 @@ ctx->drm_dev = drm_dev; ipp->drm_dev = drm_dev; - exynos_drm_register_dma(drm_dev, dev); + exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | @@ -1153,7 +1154,7 @@ struct exynos_drm_ipp *ipp = &ctx->ipp; exynos_drm_ipp_unregister(dev, ipp); - exynos_drm_unregister_dma(drm_dev, dev); + exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); } static const struct component_ops fimc_component_ops = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -167,6 +167,7 @@ struct fimd_context { struct device *dev; struct drm_device *drm_dev; + void *dma_priv; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[WINDOWS_NR]; struct exynos_drm_plane_config configs[WINDOWS_NR]; @@ -636,9 +637,9 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, struct drm_framebuffer *fb, int width) { - struct exynos_drm_plane plane = ctx->planes[win]; + struct exynos_drm_plane *plane = &ctx->planes[win]; struct exynos_drm_plane_state *state = - to_exynos_plane_state(plane.base.state); + to_exynos_plane_state(plane->base.state); uint32_t pixel_format = fb->format->format; unsigned int alpha = state->base.alpha; u32 val = WINCONx_ENWIN; @@ -1090,7 +1091,7 @@ if (is_drm_iommu_supported(drm_dev)) fimd_clear_channels(ctx->crtc); - return exynos_drm_register_dma(drm_dev, dev); + return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); } static void fimd_unbind(struct device *dev, struct device *master, @@ -1100,7 +1101,7 @@ fimd_disable(ctx->crtc); - exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); if (ctx->encoder) exynos_dpi_remove(ctx->encoder); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -232,6 +232,7 @@ struct g2d_data { struct device *dev; + void *dma_priv; struct clk *gate_clk; void __iomem *regs; int irq; @@ -1331,7 +1332,7 @@ /* Let the runqueue know that there is work to do. */ queue_work(g2d->g2d_workq, &g2d->runqueue_work); - if (runqueue_node->async) + if (req->async) goto out; wait_for_completion(&runqueue_node->complete); @@ -1409,7 +1410,7 @@ return ret; } - ret = exynos_drm_register_dma(drm_dev, dev); + ret = exynos_drm_register_dma(drm_dev, dev, &g2d->dma_priv); if (ret < 0) { dev_err(dev, "failed to enable iommu.\n"); g2d_fini_cmdlist(g2d); @@ -1434,7 +1435,7 @@ priv->g2d_dev = NULL; cancel_work_sync(&g2d->runqueue_work); - exynos_drm_unregister_dma(g2d->drm_dev, dev); + exynos_drm_unregister_dma(g2d->drm_dev, dev, &g2d->dma_priv); } static const struct component_ops g2d_component_ops = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_g2d.h +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_g2d.h @@ -34,11 +34,11 @@ return -ENODEV; } -int g2d_open(struct drm_device *drm_dev, struct drm_file *file) +static inline int g2d_open(struct drm_device *drm_dev, struct drm_file *file) { return 0; } -void g2d_close(struct drm_device *drm_dev, struct drm_file *file) +static inline void g2d_close(struct drm_device *drm_dev, struct drm_file *file) { } #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -97,6 +97,7 @@ struct gsc_context { struct exynos_drm_ipp ipp; struct drm_device *drm_dev; + void *dma_priv; struct device *dev; struct exynos_drm_ipp_task *task; struct exynos_drm_ipp_formats *formats; @@ -1168,8 +1169,8 @@ struct exynos_drm_ipp *ipp = &ctx->ipp; ctx->drm_dev = drm_dev; - ctx->drm_dev = drm_dev; - exynos_drm_register_dma(drm_dev, dev); + ipp->drm_dev = drm_dev; + exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | @@ -1189,7 +1190,7 @@ struct exynos_drm_ipp *ipp = &ctx->ipp; exynos_drm_ipp_unregister(dev, ipp); - exynos_drm_unregister_dma(drm_dev, dev); + exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); } static const struct component_ops gsc_component_ops = { @@ -1313,6 +1314,7 @@ { struct device *dev = &pdev->dev; + component_del(dev, &gsc_component_ops); pm_runtime_dont_use_autosuspend(dev); pm_runtime_disable(dev); @@ -1342,7 +1344,7 @@ for (i = 0; i < ctx->num_clocks; i++) { ret = clk_prepare_enable(ctx->clocks[i]); if (ret) { - while (--i > 0) + while (--i >= 0) clk_disable_unprepare(ctx->clocks[i]); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_mic.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_mic.c @@ -268,8 +268,10 @@ goto unlock; ret = pm_runtime_get_sync(mic->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(mic->dev); goto unlock; + } mic_set_path(mic, 1); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_rotator.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_rotator.c @@ -56,6 +56,7 @@ struct rot_context { struct exynos_drm_ipp ipp; struct drm_device *drm_dev; + void *dma_priv; struct device *dev; void __iomem *regs; struct clk *clock; @@ -243,7 +244,7 @@ rot->drm_dev = drm_dev; ipp->drm_dev = drm_dev; - exynos_drm_register_dma(drm_dev, dev); + exynos_drm_register_dma(drm_dev, dev, &rot->dma_priv); exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE, @@ -261,7 +262,7 @@ struct exynos_drm_ipp *ipp = &rot->ipp; exynos_drm_ipp_unregister(dev, ipp); - exynos_drm_unregister_dma(rot->drm_dev, rot->dev); + exynos_drm_unregister_dma(rot->drm_dev, rot->dev, &rot->dma_priv); } static const struct component_ops rotator_component_ops = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_scaler.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_scaler.c @@ -39,6 +39,7 @@ struct scaler_context { struct exynos_drm_ipp ipp; struct drm_device *drm_dev; + void *dma_priv; struct device *dev; void __iomem *regs; struct clk *clock[SCALER_MAX_CLK]; @@ -450,7 +451,7 @@ scaler->drm_dev = drm_dev; ipp->drm_dev = drm_dev; - exynos_drm_register_dma(drm_dev, dev); + exynos_drm_register_dma(drm_dev, dev, &scaler->dma_priv); exynos_drm_ipp_register(dev, ipp, &ipp_funcs, DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | @@ -470,7 +471,8 @@ struct exynos_drm_ipp *ipp = &scaler->ipp; exynos_drm_ipp_unregister(dev, ipp); - exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev); + exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev, + &scaler->dma_priv); } static const struct component_ops scaler_component_ops = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -301,6 +301,7 @@ struct vidi_context *ctx = ctx_from_connector(connector); struct edid *edid; int edid_len; + int count; /* * the edid data comes from user side and it would be set @@ -308,19 +309,23 @@ */ if (!ctx->raw_edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); - return -EFAULT; + return 0; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); - return -ENOMEM; + return 0; } drm_connector_update_edid_property(connector, edid); - return drm_add_edid_modes(connector, edid); + count = drm_add_edid_modes(connector, edid); + + kfree(edid); + + return count; } static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = { @@ -483,8 +488,6 @@ if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); ctx->raw_edid = NULL; - - return -EINVAL; } component_del(&pdev->dev, &vidi_component_ops); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_hdmi.c @@ -852,6 +852,10 @@ static void hdmi_connector_destroy(struct drm_connector *connector) { + struct hdmi_context *hdata = connector_to_hdmi(connector); + + cec_notifier_conn_unregister(hdata->notifier); + drm_connector_unregister(connector); drm_connector_cleanup(connector); } @@ -872,11 +876,11 @@ int ret; if (!hdata->ddc_adpt) - return -ENODEV; + goto no_edid; edid = drm_get_edid(connector, hdata->ddc_adpt); if (!edid) - return -ENODEV; + goto no_edid; hdata->dvi_mode = !drm_detect_hdmi_monitor(edid); DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n", @@ -891,6 +895,9 @@ kfree(edid); return ret; + +no_edid: + return drm_add_modes_noedid(connector, 640, 480); } static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock) @@ -935,6 +942,7 @@ { struct hdmi_context *hdata = encoder_to_hdmi(encoder); struct drm_connector *connector = &hdata->connector; + struct cec_connector_info conn_info; int ret; connector->interlace_allowed = true; @@ -957,6 +965,15 @@ DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n"); } + cec_fill_conn_info_from_drm(&conn_info, connector); + + hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL, + &conn_info); + if (!hdata->notifier) { + ret = -ENOMEM; + DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n"); + } + return ret; } @@ -1528,8 +1545,8 @@ */ mutex_unlock(&hdata->mutex); cancel_delayed_work(&hdata->hotplug_work); - cec_notifier_set_phys_addr(hdata->notifier, - CEC_PHYS_ADDR_INVALID); + if (hdata->notifier) + cec_notifier_phys_addr_invalidate(hdata->notifier); return; } @@ -1788,18 +1805,10 @@ hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en"); - if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) { + if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) if (IS_ERR(hdata->reg_hdmi_en)) return PTR_ERR(hdata->reg_hdmi_en); - ret = regulator_enable(hdata->reg_hdmi_en); - if (ret) { - DRM_DEV_ERROR(dev, - "failed to enable hdmi-en regulator\n"); - return ret; - } - } - return hdmi_bridge_init(hdata); } @@ -1844,6 +1853,8 @@ return ret; crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI); + if (IS_ERR(crtc)) + return PTR_ERR(crtc); crtc->pipe_clk = &hdata->phy_clk; ret = hdmi_create_connector(encoder); @@ -2006,10 +2017,13 @@ } } - hdata->notifier = cec_notifier_get(&pdev->dev); - if (hdata->notifier == NULL) { - ret = -ENOMEM; - goto err_hdmiphy; + if (!IS_ERR(hdata->reg_hdmi_en)) { + ret = regulator_enable(hdata->reg_hdmi_en); + if (ret) { + DRM_DEV_ERROR(dev, + "failed to enable hdmi-en regulator\n"); + goto err_hdmiphy; + } } pm_runtime_enable(dev); @@ -2023,7 +2037,7 @@ ret = hdmi_register_audio_device(hdata); if (ret) - goto err_notifier_put; + goto err_rpm_disable; ret = component_add(&pdev->dev, &hdmi_component_ops); if (ret) @@ -2034,10 +2048,10 @@ err_unregister_audio: platform_device_unregister(hdata->audio.pdev); -err_notifier_put: - cec_notifier_put(hdata->notifier); +err_rpm_disable: pm_runtime_disable(dev); - + if (!IS_ERR(hdata->reg_hdmi_en)) + regulator_disable(hdata->reg_hdmi_en); err_hdmiphy: if (hdata->hdmiphy_port) put_device(&hdata->hdmiphy_port->dev); @@ -2054,12 +2068,10 @@ struct hdmi_context *hdata = platform_get_drvdata(pdev); cancel_delayed_work_sync(&hdata->hotplug_work); - cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID); component_del(&pdev->dev, &hdmi_component_ops); platform_device_unregister(hdata->audio.pdev); - cec_notifier_put(hdata->notifier); pm_runtime_disable(&pdev->dev); if (!IS_ERR(hdata->reg_hdmi_en)) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/exynos/exynos_mixer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/exynos/exynos_mixer.c @@ -94,6 +94,7 @@ struct platform_device *pdev; struct device *dev; struct drm_device *drm_dev; + void *dma_priv; struct exynos_drm_crtc *crtc; struct exynos_drm_plane planes[MIXER_WIN_NR]; unsigned long flags; @@ -894,12 +895,14 @@ } } - return exynos_drm_register_dma(drm_dev, mixer_ctx->dev); + return exynos_drm_register_dma(drm_dev, mixer_ctx->dev, + &mixer_ctx->dma_priv); } static void mixer_ctx_remove(struct mixer_context *mixer_ctx) { - exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev); + exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev, + &mixer_ctx->dma_priv); } static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c @@ -70,8 +70,9 @@ return drm_panel_get_modes(fsl_connector->panel); } -static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { if (mode->hdisplay & 0xf) return MODE_ERROR; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/cdv_intel_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -405,6 +405,8 @@ struct gma_crtc *gma_crtc = to_gma_crtc(crtc); struct gma_clock_t clock; + memset(&clock, 0, sizeof(clock)); + switch (refclk) { case 27000: if (target < 200000) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -2120,12 +2120,12 @@ intel_dp->dpcd, sizeof(intel_dp->dpcd)); cdv_intel_edp_panel_vdd_off(gma_encoder); - if (ret == 0) { + if (ret <= 0) { /* if this fails, presume the device is a ghost */ DRM_INFO("failed to retrieve link info, disabling eDP\n"); cdv_intel_dp_encoder_destroy(encoder); cdv_intel_dp_destroy(connector); - goto err_priv; + goto err_connector; } else { DRM_DEBUG_KMS("DPCD: Rev=%x LN_Rate=%x LN_CNT=%x LN_DOWNSP=%x\n", intel_dp->dpcd[0], intel_dp->dpcd[1], --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -391,6 +391,9 @@ if (mode_dev->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); return 1; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/framebuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/framebuffer.c @@ -462,6 +462,7 @@ container_of(helper, struct psb_fbdev, psb_fb_helper); struct drm_device *dev = psb_fbdev->psb_fb_helper.dev; struct drm_psb_private *dev_priv = dev->dev_private; + unsigned int fb_size; int bytespp; bytespp = sizes->surface_bpp / 8; @@ -471,8 +472,11 @@ /* If the mode will not fit in 32bit then switch to 16bit to get a console on full resolution. The X mode setting server will allocate its own 32bit GEM framebuffer */ - if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height > - dev_priv->vram_stolen_size) { + fb_size = ALIGN(sizes->surface_width * bytespp, 64) * + sizes->surface_height; + fb_size = ALIGN(fb_size, PAGE_SIZE); + + if (fb_size > dev_priv->vram_stolen_size) { sizes->surface_bpp = 16; sizes->surface_depth = 16; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -129,6 +129,7 @@ s32 freq_error, min_error = 100000; memset(best_clock, 0, sizeof(*best_clock)); + memset(&clock, 0, sizeof(clock)); for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { for (clock.n = limit->n.min; clock.n <= limit->n.max; @@ -185,6 +186,7 @@ int err = target; memset(best_clock, 0, sizeof(*best_clock)); + memset(&clock, 0, sizeof(clock)); for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) { for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c @@ -279,11 +279,8 @@ hdmi_dev = pci_get_drvdata(dev); i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); - if (i2c_dev == NULL) { - DRM_ERROR("Can't allocate interface\n"); - ret = -ENOMEM; - goto exit; - } + if (!i2c_dev) + return -ENOMEM; i2c_dev->adap = &oaktrail_hdmi_i2c_adapter; i2c_dev->status = I2C_STAT_INIT; @@ -300,16 +297,23 @@ oaktrail_hdmi_i2c_adapter.name, hdmi_dev); if (ret) { DRM_ERROR("Failed to request IRQ for I2C controller\n"); - goto err; + goto free_dev; } /* Adapter registration */ ret = i2c_add_numbered_adapter(&oaktrail_hdmi_i2c_adapter); - return ret; + if (ret) { + DRM_ERROR("Failed to add I2C adapter\n"); + goto free_irq; + } + + return 0; -err: +free_irq: + free_irq(dev->irq, hdmi_dev); +free_dev: kfree(i2c_dev); -exit: + return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/psb_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/psb_drv.c @@ -313,6 +313,8 @@ if (ret) goto out_err; + ret = -ENOMEM; + dev_priv->mmu = psb_mmu_driver_init(dev, 1, 0, 0); if (!dev_priv->mmu) goto out_err; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/psb_intel_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/psb_intel_display.c @@ -532,14 +532,15 @@ struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) { - struct drm_crtc *crtc = NULL; + struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + if (gma_crtc->pipe == pipe) - break; + return crtc; } - return crtc; + return NULL; } int gma_connector_clones(struct drm_device *dev, int type_mask) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -506,6 +506,9 @@ if (mode_dev->panel_fixed_mode != NULL) { struct drm_display_mode *mode = drm_mode_duplicate(dev, mode_dev->panel_fixed_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); return 1; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/gma500/psb_irq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/gma500/psb_irq.c @@ -337,6 +337,7 @@ { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; + unsigned int i; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); @@ -349,20 +350,12 @@ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank[0].enabled) - psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank[1].enabled) - psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank[2].enabled) - psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); - else - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); + for (i = 0; i < dev->num_crtcs; ++i) { + if (dev->vblank[i].enabled) + psb_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + else + psb_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + } if (dev_priv->ops->hotplug_enable) dev_priv->ops->hotplug_enable(dev, true); @@ -375,6 +368,7 @@ { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long irqflags; + unsigned int i; spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); @@ -383,14 +377,10 @@ PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); - if (dev->vblank[0].enabled) - psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank[1].enabled) - psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE); - - if (dev->vblank[2].enabled) - psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); + for (i = 0; i < dev->num_crtcs; ++i) { + if (dev->vblank[i].enabled) + psb_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + } dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | _PSB_IRQ_MSVDX_FLAG | --- linux-oracle-5.4.0.orig/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -376,7 +376,6 @@ drm_dev_unregister(dev); hibmc_unload(dev); - drm_dev_put(dev); } static struct pci_device_id hibmc_pci_table[] = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h +++ linux-oracle-5.4.0/drivers/gpu/drm/hisilicon/kirin/kirin_ade_reg.h @@ -83,7 +83,6 @@ #define VSIZE_OFST 20 #define LDI_INT_EN 0x741C #define FRAME_END_INT_EN_OFST 1 -#define UNDERFLOW_INT_EN_OFST 2 #define LDI_CTRL 0x7420 #define BPP_OFST 3 #define DATA_GATE_EN BIT(2) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ linux-oracle-5.4.0/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -46,7 +46,6 @@ struct clk *media_noc_clk; struct clk *ade_pix_clk; struct reset_control *reset; - struct work_struct display_reset_wq; bool power_on; int irq; @@ -136,7 +135,6 @@ */ ade_update_bits(base + ADE_CTRL, FRM_END_START_OFST, FRM_END_START_MASK, REG_EFFECTIVE_IN_ADEEN_FRMEND); - ade_update_bits(base + LDI_INT_EN, UNDERFLOW_INT_EN_OFST, MASK(1), 1); } static bool ade_crtc_mode_fixup(struct drm_crtc *crtc, @@ -304,17 +302,6 @@ MASK(1), 0); } -static void drm_underflow_wq(struct work_struct *work) -{ - struct ade_hw_ctx *ctx = container_of(work, struct ade_hw_ctx, - display_reset_wq); - struct drm_device *drm_dev = ctx->crtc->dev; - struct drm_atomic_state *state; - - state = drm_atomic_helper_suspend(drm_dev); - drm_atomic_helper_resume(drm_dev, state); -} - static irqreturn_t ade_irq_handler(int irq, void *data) { struct ade_hw_ctx *ctx = data; @@ -331,12 +318,6 @@ MASK(1), 1); drm_crtc_handle_vblank(crtc); } - if (status & BIT(UNDERFLOW_INT_EN_OFST)) { - ade_update_bits(base + LDI_INT_CLR, UNDERFLOW_INT_EN_OFST, - MASK(1), 1); - DRM_ERROR("LDI underflow!"); - schedule_work(&ctx->display_reset_wq); - } return IRQ_HANDLED; } @@ -919,7 +900,6 @@ if (ret) return ERR_PTR(-EIO); - INIT_WORK(&ctx->display_reset_wq, drm_underflow_wq); ctx->crtc = crtc; return ctx; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i810/i810_dma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i810/i810_dma.c @@ -728,7 +728,7 @@ if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - if (used > 4 * 1024) + if (used < 0 || used > 4 * 1024) used = 0; if (sarea_priv->dirty) @@ -1048,7 +1048,7 @@ if (u != I810_BUF_CLIENT) DRM_DEBUG("MC found buffer that isn't mine!\n"); - if (used > 4 * 1024) + if (used < 0 || used > 4 * 1024) used = 0; sarea_priv->dirty = 0x7f; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/Kconfig @@ -75,9 +75,8 @@ help This option enables capturing the GPU state when a hang is detected. This information is vital for triaging hangs and assists in debugging. - Please report any hang to - https://bugs.freedesktop.org/enter_bug.cgi?product=DRI - for triaging. + Please report any hang for triaging according to: + https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs If in doubt, say "Y". --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/Kconfig.debug +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/Kconfig.debug @@ -7,7 +7,6 @@ # We use the dependency on !COMPILE_TEST to not be enabled in # allmodconfig or allyesconfig configurations depends on !COMPILE_TEST - select HEADER_TEST default n help Add -Werror to the build flags for (and only for) i915.ko. @@ -22,7 +21,6 @@ depends on DRM_I915 select DEBUG_FS select PREEMPT_COUNT - select REFCOUNT_FULL select I2C_CHARDEV select STACKDEPOT select DRM_DP_AUX_CHARDEV --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/Makefile +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/Makefile @@ -83,6 +83,7 @@ gt/intel_gt_irq.o \ gt/intel_gt_pm.o \ gt/intel_gt_pm_irq.o \ + gt/intel_gt_requests.o \ gt/intel_hangcheck.o \ gt/intel_lrc.o \ gt/intel_renderstate.o \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_acpi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_acpi.c @@ -83,13 +83,31 @@ return; } + if (!pkg->package.count) { + DRM_DEBUG_DRIVER("no connection in _DSM\n"); + return; + } + connector_count = &pkg->package.elements[0]; DRM_DEBUG_DRIVER("MUX info connectors: %lld\n", (unsigned long long)connector_count->integer.value); for (i = 1; i < pkg->package.count; i++) { union acpi_object *obj = &pkg->package.elements[i]; - union acpi_object *connector_id = &obj->package.elements[0]; - union acpi_object *info = &obj->package.elements[1]; + union acpi_object *connector_id; + union acpi_object *info; + + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count < 2) { + DRM_DEBUG_DRIVER("Invalid object for MUX #%d\n", i); + continue; + } + + connector_id = &obj->package.elements[0]; + info = &obj->package.elements[1]; + if (info->type != ACPI_TYPE_BUFFER || info->buffer.length < 4) { + DRM_DEBUG_DRIVER("Invalid info for MUX obj #%d\n", i); + continue; + } + DRM_DEBUG_DRIVER("Connector id: 0x%016llx\n", (unsigned long long)connector_id->integer.value); DRM_DEBUG_DRIVER(" port id: %s\n", --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_audio.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_audio.c @@ -851,10 +851,16 @@ ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO); /* Force CDCLK to 2*BCLK as long as we need audio to be powered. */ - if (dev_priv->audio_power_refcount++ == 0) - if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) + if (dev_priv->audio_power_refcount++ == 0) { + if (IS_GEMINILAKE(dev_priv)) glk_force_audio_cdclk(dev_priv, true); + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) + I915_WRITE(AUD_PIN_BUF_CTL, + (I915_READ(AUD_PIN_BUF_CTL) | + AUD_PIN_BUF_ENABLE)); + } + return ret; } @@ -865,7 +871,7 @@ /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */ if (--dev_priv->audio_power_refcount == 0) - if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) + if (IS_GEMINILAKE(dev_priv)) glk_force_audio_cdclk(dev_priv, false); intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_bios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_bios.c @@ -32,6 +32,7 @@ #include "display/intel_gmbus.h" #include "i915_drv.h" +#include #define _INTEL_BIOS_PRIVATE #include "intel_vbt_defs.h" @@ -1828,6 +1829,22 @@ return NULL; } +#define DRM_DMI_PRODUCT_VERSION 0x6 + +static void parse_product_info(struct drm_i915_private *dev_priv) +{ + const char *product_ver = dmi_get_system_info(DRM_DMI_PRODUCT_VERSION); + if (!product_ver) + return; + + if (!strncmp(product_ver, "ThinkPad X1", 11)) { + DRM_DEBUG_KMS("dmi: %s, Bypassing TMDS_OE write\n", product_ver); + dev_priv->bypass_tmds_oe = true; + } + + return; +} + /** * intel_bios_init - find VBT and initialize settings from the BIOS * @dev_priv: i915 device instance @@ -1886,6 +1903,8 @@ parse_sdvo_device_mapping(dev_priv, bdb->version); parse_ddi_ports(dev_priv, bdb->version); + parse_product_info(dev_priv); + out: if (!vbt) { DRM_INFO("Failed to find VBIOS tables (VBT)\n"); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_ddi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2124,7 +2124,11 @@ return; dig_port = enc_to_dig_port(&encoder->base); - intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain); + + if (!intel_phy_is_tc(dev_priv, phy) || + dig_port->tc_mode != TC_PORT_TBT_ALT) + intel_display_power_get(dev_priv, + dig_port->ddi_io_power_domain); /* * AUX power is only needed for (e)DP mode, and for HDMI mode on TC --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_display.c @@ -6753,20 +6753,30 @@ dig_port->tc_mode == TC_PORT_TBT_ALT) { switch (dig_port->aux_ch) { case AUX_CH_C: - return POWER_DOMAIN_AUX_TBT1; + return POWER_DOMAIN_AUX_C_TBT; case AUX_CH_D: - return POWER_DOMAIN_AUX_TBT2; + return POWER_DOMAIN_AUX_D_TBT; case AUX_CH_E: - return POWER_DOMAIN_AUX_TBT3; + return POWER_DOMAIN_AUX_E_TBT; case AUX_CH_F: - return POWER_DOMAIN_AUX_TBT4; + return POWER_DOMAIN_AUX_F_TBT; default: MISSING_CASE(dig_port->aux_ch); - return POWER_DOMAIN_AUX_TBT1; + return POWER_DOMAIN_AUX_C_TBT; } } - switch (dig_port->aux_ch) { + return intel_legacy_aux_to_power_domain(dig_port->aux_ch); +} + +/* + * Converts aux_ch to power_domain without caring about TBT ports for that use + * intel_aux_power_domain() + */ +enum intel_display_power_domain +intel_legacy_aux_to_power_domain(enum aux_ch aux_ch) +{ + switch (aux_ch) { case AUX_CH_A: return POWER_DOMAIN_AUX_A; case AUX_CH_B: @@ -6780,7 +6790,7 @@ case AUX_CH_F: return POWER_DOMAIN_AUX_F; default: - MISSING_CASE(dig_port->aux_ch); + MISSING_CASE(aux_ch); return POWER_DOMAIN_AUX_A; } } @@ -10510,7 +10520,7 @@ u32 base; if (INTEL_INFO(dev_priv)->display.cursor_needs_physical) - base = obj->phys_handle->busaddr; + base = sg_dma_address(obj->mm.pages->sgl); else base = intel_plane_ggtt_offset(plane_state); @@ -11893,10 +11903,11 @@ case 10 ... 11: bpp = 10 * 3; break; - case 12: + case 12 ... 16: bpp = 12 * 3; break; default: + MISSING_CASE(conn_state->max_bpc); return -EINVAL; } @@ -14429,7 +14440,7 @@ return ret; fb_obj_bump_render_priority(obj); - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_DIRTYFB); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_DIRTYFB); if (!new_state->fence) { /* implicit fencing */ struct dma_fence *fence; @@ -16860,8 +16871,11 @@ static void intel_early_display_was(struct drm_i915_private *dev_priv) { - /* Display WA #1185 WaDisableDARBFClkGating:cnl,glk */ - if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) + /* + * Display WA #1185 WaDisableDARBFClkGating:cnl,glk,icl,ehl,tgl + * Also known as Wa_14010480278. + */ + if (IS_GEN_RANGE(dev_priv, 10, 12) || IS_GEMINILAKE(dev_priv)) I915_WRITE(GEN9_CLKGATE_DIS_0, I915_READ(GEN9_CLKGATE_DIS_0) | DARBF_GATING_DIS); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_display.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_display.h @@ -513,6 +513,8 @@ enum intel_display_power_domain intel_port_to_power_domain(enum port port); enum intel_display_power_domain intel_aux_power_domain(struct intel_digital_port *dig_port); +enum intel_display_power_domain +intel_legacy_aux_to_power_domain(enum aux_ch aux_ch); void intel_mode_from_pipe_config(struct drm_display_mode *mode, struct intel_crtc_state *pipe_config); void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_display_power.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_display_power.c @@ -20,15 +20,14 @@ #include "intel_sideband.h" #include "intel_tc.h" +static const struct i915_power_well_ops icl_tc_phy_aux_power_well_ops; + bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv, enum i915_power_well_id power_well_id); const char * -intel_display_power_domain_str(struct drm_i915_private *i915, - enum intel_display_power_domain domain) +intel_display_power_domain_str(enum intel_display_power_domain domain) { - bool ddi_tc_ports = IS_GEN(i915, 12); - switch (domain) { case POWER_DOMAIN_DISPLAY_CORE: return "DISPLAY_CORE"; @@ -71,23 +70,17 @@ case POWER_DOMAIN_PORT_DDI_C_LANES: return "PORT_DDI_C_LANES"; case POWER_DOMAIN_PORT_DDI_D_LANES: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_LANES != - POWER_DOMAIN_PORT_DDI_TC1_LANES); - return ddi_tc_ports ? "PORT_DDI_TC1_LANES" : "PORT_DDI_D_LANES"; + return "PORT_DDI_D_LANES"; case POWER_DOMAIN_PORT_DDI_E_LANES: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_LANES != - POWER_DOMAIN_PORT_DDI_TC2_LANES); - return ddi_tc_ports ? "PORT_DDI_TC2_LANES" : "PORT_DDI_E_LANES"; + return "PORT_DDI_E_LANES"; case POWER_DOMAIN_PORT_DDI_F_LANES: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_F_LANES != - POWER_DOMAIN_PORT_DDI_TC3_LANES); - return ddi_tc_ports ? "PORT_DDI_TC3_LANES" : "PORT_DDI_F_LANES"; - case POWER_DOMAIN_PORT_DDI_TC4_LANES: - return "PORT_DDI_TC4_LANES"; - case POWER_DOMAIN_PORT_DDI_TC5_LANES: - return "PORT_DDI_TC5_LANES"; - case POWER_DOMAIN_PORT_DDI_TC6_LANES: - return "PORT_DDI_TC6_LANES"; + return "PORT_DDI_F_LANES"; + case POWER_DOMAIN_PORT_DDI_G_LANES: + return "PORT_DDI_G_LANES"; + case POWER_DOMAIN_PORT_DDI_H_LANES: + return "PORT_DDI_H_LANES"; + case POWER_DOMAIN_PORT_DDI_I_LANES: + return "PORT_DDI_I_LANES"; case POWER_DOMAIN_PORT_DDI_A_IO: return "PORT_DDI_A_IO"; case POWER_DOMAIN_PORT_DDI_B_IO: @@ -95,23 +88,17 @@ case POWER_DOMAIN_PORT_DDI_C_IO: return "PORT_DDI_C_IO"; case POWER_DOMAIN_PORT_DDI_D_IO: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_D_IO != - POWER_DOMAIN_PORT_DDI_TC1_IO); - return ddi_tc_ports ? "PORT_DDI_TC1_IO" : "PORT_DDI_D_IO"; + return "PORT_DDI_D_IO"; case POWER_DOMAIN_PORT_DDI_E_IO: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_E_IO != - POWER_DOMAIN_PORT_DDI_TC2_IO); - return ddi_tc_ports ? "PORT_DDI_TC2_IO" : "PORT_DDI_E_IO"; + return "PORT_DDI_E_IO"; case POWER_DOMAIN_PORT_DDI_F_IO: - BUILD_BUG_ON(POWER_DOMAIN_PORT_DDI_F_IO != - POWER_DOMAIN_PORT_DDI_TC3_IO); - return ddi_tc_ports ? "PORT_DDI_TC3_IO" : "PORT_DDI_F_IO"; - case POWER_DOMAIN_PORT_DDI_TC4_IO: - return "PORT_DDI_TC4_IO"; - case POWER_DOMAIN_PORT_DDI_TC5_IO: - return "PORT_DDI_TC5_IO"; - case POWER_DOMAIN_PORT_DDI_TC6_IO: - return "PORT_DDI_TC6_IO"; + return "PORT_DDI_F_IO"; + case POWER_DOMAIN_PORT_DDI_G_IO: + return "PORT_DDI_G_IO"; + case POWER_DOMAIN_PORT_DDI_H_IO: + return "PORT_DDI_H_IO"; + case POWER_DOMAIN_PORT_DDI_I_IO: + return "PORT_DDI_I_IO"; case POWER_DOMAIN_PORT_DSI: return "PORT_DSI"; case POWER_DOMAIN_PORT_CRT: @@ -129,34 +116,33 @@ case POWER_DOMAIN_AUX_C: return "AUX_C"; case POWER_DOMAIN_AUX_D: - BUILD_BUG_ON(POWER_DOMAIN_AUX_D != POWER_DOMAIN_AUX_TC1); - return ddi_tc_ports ? "AUX_TC1" : "AUX_D"; + return "AUX_D"; case POWER_DOMAIN_AUX_E: - BUILD_BUG_ON(POWER_DOMAIN_AUX_E != POWER_DOMAIN_AUX_TC2); - return ddi_tc_ports ? "AUX_TC2" : "AUX_E"; + return "AUX_E"; case POWER_DOMAIN_AUX_F: - BUILD_BUG_ON(POWER_DOMAIN_AUX_F != POWER_DOMAIN_AUX_TC3); - return ddi_tc_ports ? "AUX_TC3" : "AUX_F"; - case POWER_DOMAIN_AUX_TC4: - return "AUX_TC4"; - case POWER_DOMAIN_AUX_TC5: - return "AUX_TC5"; - case POWER_DOMAIN_AUX_TC6: - return "AUX_TC6"; + return "AUX_F"; + case POWER_DOMAIN_AUX_G: + return "AUX_G"; + case POWER_DOMAIN_AUX_H: + return "AUX_H"; + case POWER_DOMAIN_AUX_I: + return "AUX_I"; case POWER_DOMAIN_AUX_IO_A: return "AUX_IO_A"; - case POWER_DOMAIN_AUX_TBT1: - return "AUX_TBT1"; - case POWER_DOMAIN_AUX_TBT2: - return "AUX_TBT2"; - case POWER_DOMAIN_AUX_TBT3: - return "AUX_TBT3"; - case POWER_DOMAIN_AUX_TBT4: - return "AUX_TBT4"; - case POWER_DOMAIN_AUX_TBT5: - return "AUX_TBT5"; - case POWER_DOMAIN_AUX_TBT6: - return "AUX_TBT6"; + case POWER_DOMAIN_AUX_C_TBT: + return "AUX_C_TBT"; + case POWER_DOMAIN_AUX_D_TBT: + return "AUX_D_TBT"; + case POWER_DOMAIN_AUX_E_TBT: + return "AUX_E_TBT"; + case POWER_DOMAIN_AUX_F_TBT: + return "AUX_F_TBT"; + case POWER_DOMAIN_AUX_G_TBT: + return "AUX_G_TBT"; + case POWER_DOMAIN_AUX_H_TBT: + return "AUX_H_TBT"; + case POWER_DOMAIN_AUX_I_TBT: + return "AUX_I_TBT"; case POWER_DOMAIN_GMBUS: return "GMBUS"; case POWER_DOMAIN_INIT: @@ -167,6 +153,8 @@ return "GT_IRQ"; case POWER_DOMAIN_DPLL_DC_OFF: return "DPLL_DC_OFF"; + case POWER_DOMAIN_TC_COLD_OFF: + return "TC_COLD_OFF"; default: MISSING_CASE(domain); return "?"; @@ -312,6 +300,70 @@ gen8_irq_power_well_pre_disable(dev_priv, irq_pipe_mask); } +#define ICL_AUX_PW_TO_CH(pw_idx) \ + ((pw_idx) - ICL_PW_CTL_IDX_AUX_A + AUX_CH_A) + +#define ICL_TBT_AUX_PW_TO_CH(pw_idx) \ + ((pw_idx) - ICL_PW_CTL_IDX_AUX_TBT1 + AUX_CH_C) + +static enum aux_ch icl_tc_phy_aux_ch(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + int pw_idx = power_well->desc->hsw.idx; + + return power_well->desc->hsw.is_tc_tbt ? ICL_TBT_AUX_PW_TO_CH(pw_idx) : + ICL_AUX_PW_TO_CH(pw_idx); +} + +static struct intel_digital_port * +aux_ch_to_digital_port(struct drm_i915_private *dev_priv, + enum aux_ch aux_ch) +{ + struct intel_digital_port *dig_port = NULL; + struct intel_encoder *encoder; + + for_each_intel_encoder(&dev_priv->drm, encoder) { + /* We'll check the MST primary port */ + if (encoder->type == INTEL_OUTPUT_DP_MST) + continue; + + dig_port = enc_to_dig_port(&encoder->base); + if (!dig_port) + continue; + + if (dig_port->aux_ch != aux_ch) { + dig_port = NULL; + continue; + } + + break; + } + + return dig_port; +} + +static bool tc_phy_aux_timeout_expected(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + /* An AUX timeout is expected if the TBT DP tunnel is down. */ + if (power_well->desc->hsw.is_tc_tbt) + return true; + + /* + * An AUX timeout is expected because we enable TC legacy port aux + * to hold port out of TC cold + */ + if (INTEL_GEN(dev_priv) == 11 && + power_well->desc->ops == &icl_tc_phy_aux_power_well_ops) { + enum aux_ch aux_ch = icl_tc_phy_aux_ch(dev_priv, power_well); + struct intel_digital_port *dig_port = aux_ch_to_digital_port(dev_priv, aux_ch); + + return dig_port->tc_legacy_port; + } + + return false; +} + static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { @@ -324,8 +376,8 @@ DRM_DEBUG_KMS("%s power well enable timeout\n", power_well->desc->name); - /* An AUX timeout is expected if the TBT DP tunnel is down. */ - WARN_ON(!power_well->desc->hsw.is_tc_tbt); + WARN_ON(!tc_phy_aux_timeout_expected(dev_priv, power_well)); + } } @@ -381,16 +433,16 @@ SKL_FUSE_PG_DIST_STATUS(pg), 1)); } -static void hsw_power_well_enable(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) +static void hsw_power_well_enable_prepare(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) { const struct i915_power_well_regs *regs = power_well->desc->hsw.regs; int pw_idx = power_well->desc->hsw.idx; - bool wait_fuses = power_well->desc->hsw.has_fuses; - enum skl_power_gate uninitialized_var(pg); u32 val; - if (wait_fuses) { + if (power_well->desc->hsw.has_fuses) { + enum skl_power_gate pg; + pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) : SKL_PW_CTL_IDX_TO_PG(pw_idx); /* @@ -406,25 +458,46 @@ val = I915_READ(regs->driver); I915_WRITE(regs->driver, val | HSW_PWR_WELL_CTL_REQ(pw_idx)); +} + +static void hsw_power_well_enable_complete(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + int pw_idx = power_well->desc->hsw.idx; + hsw_wait_for_power_well_enable(dev_priv, power_well); /* Display WA #1178: cnl */ if (IS_CANNONLAKE(dev_priv) && pw_idx >= GLK_PW_CTL_IDX_AUX_B && pw_idx <= CNL_PW_CTL_IDX_AUX_F) { + u32 val; + val = I915_READ(CNL_AUX_ANAOVRD1(pw_idx)); val |= CNL_AUX_ANAOVRD1_ENABLE | CNL_AUX_ANAOVRD1_LDO_BYPASS; I915_WRITE(CNL_AUX_ANAOVRD1(pw_idx), val); } - if (wait_fuses) + if (power_well->desc->hsw.has_fuses) { + enum skl_power_gate pg; + + pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) : + SKL_PW_CTL_IDX_TO_PG(pw_idx); gen9_wait_for_power_well_fuses(dev_priv, pg); + } hsw_power_well_post_enable(dev_priv, power_well->desc->hsw.irq_pipe_mask, power_well->desc->hsw.has_vga); } +static void hsw_power_well_enable(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + hsw_power_well_enable_prepare(dev_priv, power_well); + hsw_power_well_enable_complete(dev_priv, power_well); +} + static void hsw_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { @@ -497,21 +570,6 @@ hsw_wait_for_power_well_disable(dev_priv, power_well); } -#define ICL_AUX_PW_TO_CH(pw_idx) \ - ((pw_idx) - ICL_PW_CTL_IDX_AUX_A + AUX_CH_A) - -#define ICL_TBT_AUX_PW_TO_CH(pw_idx) \ - ((pw_idx) - ICL_PW_CTL_IDX_AUX_TBT1 + AUX_CH_C) - -static enum aux_ch icl_tc_phy_aux_ch(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) -{ - int pw_idx = power_well->desc->hsw.idx; - - return power_well->desc->hsw.is_tc_tbt ? ICL_TBT_AUX_PW_TO_CH(pw_idx) : - ICL_AUX_PW_TO_CH(pw_idx); -} - #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) static u64 async_put_domains_mask(struct i915_power_domains *power_domains); @@ -528,64 +586,63 @@ } static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) + struct i915_power_well *power_well, + struct intel_digital_port *dig_port) { - enum aux_ch aux_ch = icl_tc_phy_aux_ch(dev_priv, power_well); - struct intel_digital_port *dig_port = NULL; - struct intel_encoder *encoder; - /* Bypass the check if all references are released asynchronously */ if (power_well_async_ref_count(dev_priv, power_well) == power_well->count) return; - aux_ch = icl_tc_phy_aux_ch(dev_priv, power_well); - - for_each_intel_encoder(&dev_priv->drm, encoder) { - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - - if (!intel_phy_is_tc(dev_priv, phy)) - continue; - - /* We'll check the MST primary port */ - if (encoder->type == INTEL_OUTPUT_DP_MST) - continue; - - dig_port = enc_to_dig_port(&encoder->base); - if (WARN_ON(!dig_port)) - continue; - - if (dig_port->aux_ch != aux_ch) { - dig_port = NULL; - continue; - } - - break; - } - if (WARN_ON(!dig_port)) return; + if (INTEL_GEN(dev_priv) == 11 && dig_port->tc_legacy_port) + return; + WARN_ON(!intel_tc_port_ref_held(dig_port)); } #else static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv, - struct i915_power_well *power_well) + struct i915_power_well *power_well, + struct intel_digital_port *dig_port) { } #endif +static void icl_tc_cold_exit(struct drm_i915_private *i915) +{ + int ret, tries = 0; + + while (1) { + ret = sandybridge_pcode_write_timeout(i915, + ICL_PCODE_EXIT_TCCOLD, + 0, 250, 1); + if (ret != -EAGAIN || ++tries == 3) + break; + msleep(1); + } + + /* Spec states that TC cold exit can take up to 1ms to complete */ + if (!ret) + msleep(1); + + /* TODO: turn failure into a error as soon i915 CI updates ICL IFWI */ + DRM_DEBUG_KMS("TC cold block %s\n", ret ? "failed" : "succeeded"); +} + static void icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { enum aux_ch aux_ch = icl_tc_phy_aux_ch(dev_priv, power_well); + struct intel_digital_port *dig_port = aux_ch_to_digital_port(dev_priv, aux_ch); u32 val; - icl_tc_port_assert_ref_held(dev_priv, power_well); + icl_tc_port_assert_ref_held(dev_priv, power_well, dig_port); val = I915_READ(DP_AUX_CH_CTL(aux_ch)); val &= ~DP_AUX_CH_CTL_TBT_IO; @@ -593,14 +650,22 @@ val |= DP_AUX_CH_CTL_TBT_IO; I915_WRITE(DP_AUX_CH_CTL(aux_ch), val); - hsw_power_well_enable(dev_priv, power_well); + hsw_power_well_enable_prepare(dev_priv, power_well); + + if (INTEL_GEN(dev_priv) == 11 && dig_port->tc_legacy_port) + icl_tc_cold_exit(dev_priv); + + hsw_power_well_enable_complete(dev_priv, power_well); } static void icl_tc_phy_aux_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - icl_tc_port_assert_ref_held(dev_priv, power_well); + enum aux_ch aux_ch = icl_tc_phy_aux_ch(dev_priv, power_well); + struct intel_digital_port *dig_port = aux_ch_to_digital_port(dev_priv, aux_ch); + + icl_tc_port_assert_ref_held(dev_priv, power_well, dig_port); hsw_power_well_disable(dev_priv, power_well); } @@ -1718,15 +1783,12 @@ static void print_power_domains(struct i915_power_domains *power_domains, const char *prefix, u64 mask) { - struct drm_i915_private *i915 = - container_of(power_domains, struct drm_i915_private, - power_domains); enum intel_display_power_domain domain; DRM_DEBUG_DRIVER("%s (%lu):\n", prefix, hweight64(mask)); for_each_power_domain(domain, mask) DRM_DEBUG_DRIVER("%s use_count %d\n", - intel_display_power_domain_str(i915, domain), + intel_display_power_domain_str(domain), power_domains->domain_use_count[domain]); } @@ -1896,7 +1958,7 @@ { struct i915_power_domains *power_domains; struct i915_power_well *power_well; - const char *name = intel_display_power_domain_str(dev_priv, domain); + const char *name = intel_display_power_domain_str(domain); power_domains = &dev_priv->power_domains; @@ -2487,10 +2549,10 @@ BIT_ULL(POWER_DOMAIN_AUX_D) | \ BIT_ULL(POWER_DOMAIN_AUX_E) | \ BIT_ULL(POWER_DOMAIN_AUX_F) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT1) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT2) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT3) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT4) | \ + BIT_ULL(POWER_DOMAIN_AUX_C_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_D_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_E_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_F_TBT) | \ BIT_ULL(POWER_DOMAIN_VGA) | \ BIT_ULL(POWER_DOMAIN_AUDIO) | \ BIT_ULL(POWER_DOMAIN_INIT)) @@ -2530,22 +2592,22 @@ BIT_ULL(POWER_DOMAIN_AUX_A)) #define ICL_AUX_B_IO_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_AUX_B)) -#define ICL_AUX_C_IO_POWER_DOMAINS ( \ +#define ICL_AUX_C_TC1_IO_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_AUX_C)) -#define ICL_AUX_D_IO_POWER_DOMAINS ( \ +#define ICL_AUX_D_TC2_IO_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_AUX_D)) -#define ICL_AUX_E_IO_POWER_DOMAINS ( \ +#define ICL_AUX_E_TC3_IO_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_AUX_E)) -#define ICL_AUX_F_IO_POWER_DOMAINS ( \ +#define ICL_AUX_F_TC4_IO_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_AUX_F)) -#define ICL_AUX_TBT1_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT1)) -#define ICL_AUX_TBT2_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT2)) -#define ICL_AUX_TBT3_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT3)) -#define ICL_AUX_TBT4_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT4)) +#define ICL_AUX_C_TBT1_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_C_TBT)) +#define ICL_AUX_D_TBT2_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_D_TBT)) +#define ICL_AUX_E_TBT3_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_E_TBT)) +#define ICL_AUX_F_TBT4_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_F_TBT)) #define TGL_PW_5_POWER_DOMAINS ( \ BIT_ULL(POWER_DOMAIN_PIPE_D) | \ @@ -2565,24 +2627,24 @@ BIT_ULL(POWER_DOMAIN_PIPE_B) | \ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC1_LANES) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC2_LANES) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC3_LANES) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC4_LANES) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC5_LANES) | \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC6_LANES) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC1) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC2) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC3) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC4) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC5) | \ - BIT_ULL(POWER_DOMAIN_AUX_TC6) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT1) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT2) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT3) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT4) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT5) | \ - BIT_ULL(POWER_DOMAIN_AUX_TBT6) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_G_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_H_LANES) | \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_I_LANES) | \ + BIT_ULL(POWER_DOMAIN_AUX_D) | \ + BIT_ULL(POWER_DOMAIN_AUX_E) | \ + BIT_ULL(POWER_DOMAIN_AUX_F) | \ + BIT_ULL(POWER_DOMAIN_AUX_G) | \ + BIT_ULL(POWER_DOMAIN_AUX_H) | \ + BIT_ULL(POWER_DOMAIN_AUX_I) | \ + BIT_ULL(POWER_DOMAIN_AUX_D_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_E_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_F_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_G_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_H_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_I_TBT) | \ BIT_ULL(POWER_DOMAIN_VGA) | \ BIT_ULL(POWER_DOMAIN_AUDIO) | \ BIT_ULL(POWER_DOMAIN_INIT)) @@ -2598,35 +2660,65 @@ BIT_ULL(POWER_DOMAIN_AUX_A) | \ BIT_ULL(POWER_DOMAIN_INIT)) -#define TGL_DDI_IO_TC1_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC1_IO)) -#define TGL_DDI_IO_TC2_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC2_IO)) -#define TGL_DDI_IO_TC3_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC3_IO)) -#define TGL_DDI_IO_TC4_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC4_IO)) -#define TGL_DDI_IO_TC5_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC5_IO)) -#define TGL_DDI_IO_TC6_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_PORT_DDI_TC6_IO)) - -#define TGL_AUX_TC1_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC1)) -#define TGL_AUX_TC2_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC2)) -#define TGL_AUX_TC3_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC3)) -#define TGL_AUX_TC4_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC4)) -#define TGL_AUX_TC5_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC5)) -#define TGL_AUX_TC6_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TC6)) -#define TGL_AUX_TBT5_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT5)) -#define TGL_AUX_TBT6_IO_POWER_DOMAINS ( \ - BIT_ULL(POWER_DOMAIN_AUX_TBT6)) +#define TGL_DDI_IO_D_TC1_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO)) +#define TGL_DDI_IO_E_TC2_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO)) +#define TGL_DDI_IO_F_TC3_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO)) +#define TGL_DDI_IO_G_TC4_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_G_IO)) +#define TGL_DDI_IO_H_TC5_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_H_IO)) +#define TGL_DDI_IO_I_TC6_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_PORT_DDI_I_IO)) + +#define TGL_AUX_A_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_IO_A) | \ + BIT_ULL(POWER_DOMAIN_AUX_A)) +#define TGL_AUX_B_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_B)) +#define TGL_AUX_C_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_C)) +#define TGL_AUX_D_TC1_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_D)) +#define TGL_AUX_E_TC2_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_E)) +#define TGL_AUX_F_TC3_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_F)) +#define TGL_AUX_G_TC4_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_G)) +#define TGL_AUX_H_TC5_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_H)) +#define TGL_AUX_I_TC6_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_I)) +#define TGL_AUX_D_TBT1_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_D_TBT)) +#define TGL_AUX_E_TBT2_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_E_TBT)) +#define TGL_AUX_F_TBT3_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_F_TBT)) +#define TGL_AUX_G_TBT4_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_G_TBT)) +#define TGL_AUX_H_TBT5_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_H_TBT)) +#define TGL_AUX_I_TBT6_IO_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_I_TBT)) + +#define TGL_TC_COLD_OFF_POWER_DOMAINS ( \ + BIT_ULL(POWER_DOMAIN_AUX_D) | \ + BIT_ULL(POWER_DOMAIN_AUX_E) | \ + BIT_ULL(POWER_DOMAIN_AUX_F) | \ + BIT_ULL(POWER_DOMAIN_AUX_G) | \ + BIT_ULL(POWER_DOMAIN_AUX_H) | \ + BIT_ULL(POWER_DOMAIN_AUX_I) | \ + BIT_ULL(POWER_DOMAIN_AUX_D_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_E_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_F_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_G_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_H_TBT) | \ + BIT_ULL(POWER_DOMAIN_AUX_I_TBT) | \ + BIT_ULL(POWER_DOMAIN_TC_COLD_OFF)) static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { .sync_hw = i9xx_power_well_sync_hw_noop, @@ -3484,8 +3576,8 @@ }, }, { - .name = "AUX C", - .domains = ICL_AUX_C_IO_POWER_DOMAINS, + .name = "AUX C TC1", + .domains = ICL_AUX_C_TC1_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3495,8 +3587,8 @@ }, }, { - .name = "AUX D", - .domains = ICL_AUX_D_IO_POWER_DOMAINS, + .name = "AUX D TC2", + .domains = ICL_AUX_D_TC2_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3506,8 +3598,8 @@ }, }, { - .name = "AUX E", - .domains = ICL_AUX_E_IO_POWER_DOMAINS, + .name = "AUX E TC3", + .domains = ICL_AUX_E_TC3_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3517,8 +3609,8 @@ }, }, { - .name = "AUX F", - .domains = ICL_AUX_F_IO_POWER_DOMAINS, + .name = "AUX F TC4", + .domains = ICL_AUX_F_TC4_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3528,8 +3620,8 @@ }, }, { - .name = "AUX TBT1", - .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS, + .name = "AUX C TBT1", + .domains = ICL_AUX_C_TBT1_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3539,8 +3631,8 @@ }, }, { - .name = "AUX TBT2", - .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS, + .name = "AUX D TBT2", + .domains = ICL_AUX_D_TBT2_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3550,8 +3642,8 @@ }, }, { - .name = "AUX TBT3", - .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS, + .name = "AUX E TBT3", + .domains = ICL_AUX_E_TBT3_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3561,8 +3653,8 @@ }, }, { - .name = "AUX TBT4", - .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS, + .name = "AUX F TBT4", + .domains = ICL_AUX_F_TBT4_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3585,6 +3677,89 @@ }, }; +static void +tgl_tc_cold_request(struct drm_i915_private *i915, bool block) +{ + u8 tries = 0; + int ret; + + while (1) { + u32 low_val = 0, high_val; + + if (block) + high_val = TGL_PCODE_EXIT_TCCOLD_DATA_H_BLOCK_REQ; + else + high_val = TGL_PCODE_EXIT_TCCOLD_DATA_H_UNBLOCK_REQ; + + /* + * Spec states that we should timeout the request after 200us + * but the function below will timeout after 500us + */ + ret = sandybridge_pcode_read(i915, TGL_PCODE_TCCOLD, &low_val, + &high_val); + if (ret == 0) { + if (block && + (low_val & TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED)) + ret = -EIO; + else + break; + } + + if (++tries == 3) + break; + + if (ret == -EAGAIN) + msleep(1); + } + + if (ret) + DRM_ERROR("TC cold %sblock failed\n", block ? "" : "un"); + else + DRM_DEBUG_KMS("TC cold %sblock succeeded\n", block ? "" : "un"); +} + +static void +tgl_tc_cold_off_power_well_enable(struct drm_i915_private *i915, + struct i915_power_well *power_well) +{ + tgl_tc_cold_request(i915, true); +} + +static void +tgl_tc_cold_off_power_well_disable(struct drm_i915_private *i915, + struct i915_power_well *power_well) +{ + tgl_tc_cold_request(i915, false); +} + +static void +tgl_tc_cold_off_power_well_sync_hw(struct drm_i915_private *i915, + struct i915_power_well *power_well) +{ + if (power_well->count > 0) + tgl_tc_cold_off_power_well_enable(i915, power_well); + else + tgl_tc_cold_off_power_well_disable(i915, power_well); +} + +static bool +tgl_tc_cold_off_power_well_is_enabled(struct drm_i915_private *dev_priv, + struct i915_power_well *power_well) +{ + /* + * Not the correctly implementation but there is no way to just read it + * from PCODE, so returning count to avoid state mismatch errors + */ + return power_well->count; +} + +static const struct i915_power_well_ops tgl_tc_cold_off_ops = { + .sync_hw = tgl_tc_cold_off_power_well_sync_hw, + .enable = tgl_tc_cold_off_power_well_enable, + .disable = tgl_tc_cold_off_power_well_disable, + .is_enabled = tgl_tc_cold_off_power_well_is_enabled, +}; + static const struct i915_power_well_desc tgl_power_wells[] = { { .name = "always-on", @@ -3667,8 +3842,8 @@ } }, { - .name = "DDI TC1 IO", - .domains = TGL_DDI_IO_TC1_POWER_DOMAINS, + .name = "DDI D TC1 IO", + .domains = TGL_DDI_IO_D_TC1_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3677,8 +3852,8 @@ }, }, { - .name = "DDI TC2 IO", - .domains = TGL_DDI_IO_TC2_POWER_DOMAINS, + .name = "DDI E TC2 IO", + .domains = TGL_DDI_IO_E_TC2_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3687,8 +3862,8 @@ }, }, { - .name = "DDI TC3 IO", - .domains = TGL_DDI_IO_TC3_POWER_DOMAINS, + .name = "DDI F TC3 IO", + .domains = TGL_DDI_IO_F_TC3_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3697,8 +3872,8 @@ }, }, { - .name = "DDI TC4 IO", - .domains = TGL_DDI_IO_TC4_POWER_DOMAINS, + .name = "DDI G TC4 IO", + .domains = TGL_DDI_IO_G_TC4_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3707,8 +3882,8 @@ }, }, { - .name = "DDI TC5 IO", - .domains = TGL_DDI_IO_TC5_POWER_DOMAINS, + .name = "DDI H TC5 IO", + .domains = TGL_DDI_IO_H_TC5_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3717,8 +3892,8 @@ }, }, { - .name = "DDI TC6 IO", - .domains = TGL_DDI_IO_TC6_POWER_DOMAINS, + .name = "DDI I TC6 IO", + .domains = TGL_DDI_IO_I_TC6_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3728,7 +3903,7 @@ }, { .name = "AUX A", - .domains = ICL_AUX_A_IO_POWER_DOMAINS, + .domains = TGL_AUX_A_IO_POWER_DOMAINS, .ops = &icl_combo_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3738,7 +3913,7 @@ }, { .name = "AUX B", - .domains = ICL_AUX_B_IO_POWER_DOMAINS, + .domains = TGL_AUX_B_IO_POWER_DOMAINS, .ops = &icl_combo_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3748,7 +3923,7 @@ }, { .name = "AUX C", - .domains = ICL_AUX_C_IO_POWER_DOMAINS, + .domains = TGL_AUX_C_IO_POWER_DOMAINS, .ops = &icl_combo_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3757,8 +3932,8 @@ }, }, { - .name = "AUX TC1", - .domains = TGL_AUX_TC1_IO_POWER_DOMAINS, + .name = "AUX D TC1", + .domains = TGL_AUX_D_TC1_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3768,8 +3943,8 @@ }, }, { - .name = "AUX TC2", - .domains = TGL_AUX_TC2_IO_POWER_DOMAINS, + .name = "AUX E TC2", + .domains = TGL_AUX_E_TC2_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3779,8 +3954,8 @@ }, }, { - .name = "AUX TC3", - .domains = TGL_AUX_TC3_IO_POWER_DOMAINS, + .name = "AUX F TC3", + .domains = TGL_AUX_F_TC3_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3790,8 +3965,8 @@ }, }, { - .name = "AUX TC4", - .domains = TGL_AUX_TC4_IO_POWER_DOMAINS, + .name = "AUX G TC4", + .domains = TGL_AUX_G_TC4_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3801,8 +3976,8 @@ }, }, { - .name = "AUX TC5", - .domains = TGL_AUX_TC5_IO_POWER_DOMAINS, + .name = "AUX H TC5", + .domains = TGL_AUX_H_TC5_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3812,8 +3987,8 @@ }, }, { - .name = "AUX TC6", - .domains = TGL_AUX_TC6_IO_POWER_DOMAINS, + .name = "AUX I TC6", + .domains = TGL_AUX_I_TC6_IO_POWER_DOMAINS, .ops = &icl_tc_phy_aux_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3823,8 +3998,8 @@ }, }, { - .name = "AUX TBT1", - .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS, + .name = "AUX D TBT1", + .domains = TGL_AUX_D_TBT1_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3834,8 +4009,8 @@ }, }, { - .name = "AUX TBT2", - .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS, + .name = "AUX E TBT2", + .domains = TGL_AUX_E_TBT2_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3845,8 +4020,8 @@ }, }, { - .name = "AUX TBT3", - .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS, + .name = "AUX F TBT3", + .domains = TGL_AUX_F_TBT3_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3856,8 +4031,8 @@ }, }, { - .name = "AUX TBT4", - .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS, + .name = "AUX G TBT4", + .domains = TGL_AUX_G_TBT4_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3867,8 +4042,8 @@ }, }, { - .name = "AUX TBT5", - .domains = TGL_AUX_TBT5_IO_POWER_DOMAINS, + .name = "AUX H TBT5", + .domains = TGL_AUX_H_TBT5_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3878,8 +4053,8 @@ }, }, { - .name = "AUX TBT6", - .domains = TGL_AUX_TBT6_IO_POWER_DOMAINS, + .name = "AUX I TBT6", + .domains = TGL_AUX_I_TBT6_IO_POWER_DOMAINS, .ops = &hsw_power_well_ops, .id = DISP_PW_ID_NONE, { @@ -3912,6 +4087,12 @@ .hsw.irq_pipe_mask = BIT(PIPE_D), }, }, + { + .name = "TC cold off", + .domains = TGL_TC_COLD_OFF_POWER_DOMAINS, + .ops = &tgl_tc_cold_off_ops, + .id = DISP_PW_ID_NONE, + }, }; static int @@ -4205,13 +4386,19 @@ static void icl_mbus_init(struct drm_i915_private *dev_priv) { - u32 val; + u32 mask, val; - val = MBUS_ABOX_BT_CREDIT_POOL1(16) | - MBUS_ABOX_BT_CREDIT_POOL2(16) | - MBUS_ABOX_B_CREDIT(1) | - MBUS_ABOX_BW_CREDIT(1); + mask = MBUS_ABOX_BT_CREDIT_POOL1_MASK | + MBUS_ABOX_BT_CREDIT_POOL2_MASK | + MBUS_ABOX_B_CREDIT_MASK | + MBUS_ABOX_BW_CREDIT_MASK; + val = I915_READ(MBUS_ABOX_CTL); + val &= ~mask; + val |= MBUS_ABOX_BT_CREDIT_POOL1(16) | + MBUS_ABOX_BT_CREDIT_POOL2(16) | + MBUS_ABOX_B_CREDIT(1) | + MBUS_ABOX_BW_CREDIT(1); I915_WRITE(MBUS_ABOX_CTL, val); } @@ -5107,8 +5294,7 @@ for_each_power_domain(domain, power_well->desc->domains) DRM_DEBUG_DRIVER(" %-23s %d\n", - intel_display_power_domain_str(i915, - domain), + intel_display_power_domain_str(domain), power_domains->domain_use_count[domain]); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_display_power.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_display_power.h @@ -36,29 +36,20 @@ POWER_DOMAIN_PORT_DDI_B_LANES, POWER_DOMAIN_PORT_DDI_C_LANES, POWER_DOMAIN_PORT_DDI_D_LANES, - POWER_DOMAIN_PORT_DDI_TC1_LANES = POWER_DOMAIN_PORT_DDI_D_LANES, POWER_DOMAIN_PORT_DDI_E_LANES, - POWER_DOMAIN_PORT_DDI_TC2_LANES = POWER_DOMAIN_PORT_DDI_E_LANES, POWER_DOMAIN_PORT_DDI_F_LANES, - POWER_DOMAIN_PORT_DDI_TC3_LANES = POWER_DOMAIN_PORT_DDI_F_LANES, - POWER_DOMAIN_PORT_DDI_TC4_LANES, - POWER_DOMAIN_PORT_DDI_TC5_LANES, - POWER_DOMAIN_PORT_DDI_TC6_LANES, + POWER_DOMAIN_PORT_DDI_G_LANES, + POWER_DOMAIN_PORT_DDI_H_LANES, + POWER_DOMAIN_PORT_DDI_I_LANES, POWER_DOMAIN_PORT_DDI_A_IO, POWER_DOMAIN_PORT_DDI_B_IO, POWER_DOMAIN_PORT_DDI_C_IO, POWER_DOMAIN_PORT_DDI_D_IO, - POWER_DOMAIN_PORT_DDI_TC1_IO = POWER_DOMAIN_PORT_DDI_D_IO, POWER_DOMAIN_PORT_DDI_E_IO, - POWER_DOMAIN_PORT_DDI_TC2_IO = POWER_DOMAIN_PORT_DDI_E_IO, POWER_DOMAIN_PORT_DDI_F_IO, - POWER_DOMAIN_PORT_DDI_TC3_IO = POWER_DOMAIN_PORT_DDI_F_IO, POWER_DOMAIN_PORT_DDI_G_IO, - POWER_DOMAIN_PORT_DDI_TC4_IO = POWER_DOMAIN_PORT_DDI_G_IO, POWER_DOMAIN_PORT_DDI_H_IO, - POWER_DOMAIN_PORT_DDI_TC5_IO = POWER_DOMAIN_PORT_DDI_H_IO, POWER_DOMAIN_PORT_DDI_I_IO, - POWER_DOMAIN_PORT_DDI_TC6_IO = POWER_DOMAIN_PORT_DDI_I_IO, POWER_DOMAIN_PORT_DSI, POWER_DOMAIN_PORT_CRT, POWER_DOMAIN_PORT_OTHER, @@ -68,25 +59,24 @@ POWER_DOMAIN_AUX_B, POWER_DOMAIN_AUX_C, POWER_DOMAIN_AUX_D, - POWER_DOMAIN_AUX_TC1 = POWER_DOMAIN_AUX_D, POWER_DOMAIN_AUX_E, - POWER_DOMAIN_AUX_TC2 = POWER_DOMAIN_AUX_E, POWER_DOMAIN_AUX_F, - POWER_DOMAIN_AUX_TC3 = POWER_DOMAIN_AUX_F, - POWER_DOMAIN_AUX_TC4, - POWER_DOMAIN_AUX_TC5, - POWER_DOMAIN_AUX_TC6, + POWER_DOMAIN_AUX_G, + POWER_DOMAIN_AUX_H, + POWER_DOMAIN_AUX_I, POWER_DOMAIN_AUX_IO_A, - POWER_DOMAIN_AUX_TBT1, - POWER_DOMAIN_AUX_TBT2, - POWER_DOMAIN_AUX_TBT3, - POWER_DOMAIN_AUX_TBT4, - POWER_DOMAIN_AUX_TBT5, - POWER_DOMAIN_AUX_TBT6, + POWER_DOMAIN_AUX_C_TBT, + POWER_DOMAIN_AUX_D_TBT, + POWER_DOMAIN_AUX_E_TBT, + POWER_DOMAIN_AUX_F_TBT, + POWER_DOMAIN_AUX_G_TBT, + POWER_DOMAIN_AUX_H_TBT, + POWER_DOMAIN_AUX_I_TBT, POWER_DOMAIN_GMBUS, POWER_DOMAIN_MODESET, POWER_DOMAIN_GT_IRQ, POWER_DOMAIN_DPLL_DC_OFF, + POWER_DOMAIN_TC_COLD_OFF, POWER_DOMAIN_INIT, POWER_DOMAIN_NUM, @@ -269,8 +259,7 @@ void intel_display_power_resume(struct drm_i915_private *i915); const char * -intel_display_power_domain_str(struct drm_i915_private *i915, - enum intel_display_power_domain domain); +intel_display_power_domain_str(enum intel_display_power_domain domain); bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, enum intel_display_power_domain domain); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_display_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_display_types.h @@ -214,6 +214,9 @@ u8 controller; /* bxt+ only */ struct pwm_device *pwm; + /* DPCD backlight */ + u8 pwmgen_bit_count; + struct backlight_device *device; /* Connector and platform specific backlight functions */ @@ -1176,6 +1179,7 @@ int max_link_rate; /* sink or branch descriptor */ struct drm_dp_desc desc; + u32 edid_quirks; struct drm_dp_aux aux; u8 train_set[4]; int panel_power_up_delay; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_dp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_dp.c @@ -166,6 +166,12 @@ enum pipe pipe); static void intel_dp_unset_edid(struct intel_dp *intel_dp); +static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp) +{ + intel_dp->sink_rates[0] = 162000; + intel_dp->num_sink_rates = 1; +} + /* update sink rates from dpcd */ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp) { @@ -567,7 +573,7 @@ return 0; } /* Also take into account max slice width */ - min_slice_count = min_t(u8, min_slice_count, + min_slice_count = max_t(u8, min_slice_count, DIV_ROUND_UP(mode_hdisplay, max_slice_width)); @@ -1292,8 +1298,7 @@ bool is_tc_port = intel_phy_is_tc(i915, phy); i915_reg_t ch_ctl, ch_data[5]; u32 aux_clock_divider; - enum intel_display_power_domain aux_domain = - intel_aux_power_domain(intel_dig_port); + enum intel_display_power_domain aux_domain; intel_wakeref_t aux_wakeref; intel_wakeref_t pps_wakeref; int i, ret, recv_bytes; @@ -1308,6 +1313,8 @@ if (is_tc_port) intel_tc_port_lock(intel_dig_port); + aux_domain = intel_aux_power_domain(intel_dig_port); + aux_wakeref = intel_display_power_get(i915, aux_domain); pps_wakeref = pps_lock(intel_dp); @@ -2251,7 +2258,7 @@ struct intel_connector *intel_connector = intel_dp->attached_connector; struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); - bool constant_n = drm_dp_has_quirk(&intel_dp->desc, + bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 0, DP_DPCD_QUIRK_CONSTANT_N); int ret = 0, output_bpp; @@ -3633,7 +3640,7 @@ * link status information */ bool -intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE]) +intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status) { return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE; @@ -4260,6 +4267,9 @@ */ intel_psr_init_dpcd(intel_dp); + /* Clear the default sink rates */ + intel_dp->num_sink_rates = 0; + /* Read the eDP 1.4+ supported link rates. */ if (intel_dp->edp_dpcd[0] >= DP_EDP_14) { __le16 sink_rates[DP_MAX_SUPPORTED_RATES]; @@ -4327,7 +4337,8 @@ * it don't care about read it here and in intel_edp_init_dpcd(). */ if (!intel_dp_is_edp(intel_dp) && - !drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_SINK_COUNT)) { + !drm_dp_has_quirk(&intel_dp->desc, 0, + DP_DPCD_QUIRK_NO_SINK_COUNT)) { u8 count; ssize_t r; @@ -4705,7 +4716,18 @@ bool bret; if (intel_dp->is_mst) { - u8 esi[DP_DPRX_ESI_LEN] = { 0 }; + /* + * The +2 is because DP_DPRX_ESI_LEN is 14, but we then + * pass in "esi+10" to drm_dp_channel_eq_ok(), which + * takes a 6-byte array. So we actually need 16 bytes + * here. + * + * Somebody who knows what the limits actually are + * should check this, but for now this is at least + * harmless and avoids a valid compiler warning about + * using more of the array than we have allocated. + */ + u8 esi[DP_DPRX_ESI_LEN+2] = {}; int ret = 0; int retry; bool handled; @@ -5328,6 +5350,7 @@ intel_dp->has_audio = drm_detect_monitor_audio(edid); drm_dp_cec_set_edid(&intel_dp->aux, edid); + intel_dp->edid_quirks = drm_dp_get_edid_quirks(edid); } static void @@ -5340,6 +5363,7 @@ intel_connector->detect_edid = NULL; intel_dp->has_audio = false; + intel_dp->edid_quirks = 0; } static int @@ -7046,8 +7070,8 @@ edid = drm_get_edid(connector, &intel_dp->aux.ddc); if (edid) { if (drm_add_edid_modes(connector, edid)) { - drm_connector_update_edid_property(connector, - edid); + drm_connector_update_edid_property(connector, edid); + intel_dp->edid_quirks = drm_dp_get_edid_quirks(edid); } else { kfree(edid); edid = ERR_PTR(-EINVAL); @@ -7155,6 +7179,8 @@ return false; intel_dp_set_source_rates(intel_dp); + intel_dp_set_default_sink_rates(intel_dp); + intel_dp_set_common_rates(intel_dp); intel_dp->reset_link_params = true; intel_dp->pps_pipe = INVALID_PIPE; @@ -7218,11 +7244,8 @@ intel_connector->get_hw_state = intel_connector_get_hw_state; /* init MST on ports that can support it */ - if (HAS_DP_MST(dev_priv) && !intel_dp_is_edp(intel_dp) && - (port == PORT_B || port == PORT_C || - port == PORT_D || port == PORT_F)) - intel_dp_mst_encoder_init(intel_dig_port, - intel_connector->base.base.id); + intel_dp_mst_encoder_init(intel_dig_port, + intel_connector->base.base.id); if (!intel_edp_init_connector(intel_dp, intel_connector)) { intel_dp_aux_fini(intel_dp); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -59,8 +59,23 @@ { struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); u8 read_val[2] = { 0x0 }; + u8 control_reg; u16 level = 0; + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER, + &control_reg) != 1) { + DRM_DEBUG_KMS("Failed to read the DPCD register 0x%x\n", + DP_EDP_DISPLAY_CONTROL_REGISTER); + return 0; + } + + /* + * If we're not in DPCD control mode yet, the programmed brightness + * value is meaningless and we should assume max brightness + */ + if (!(control_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD)) + return connector->panel.backlight.max; + if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB, &read_val, sizeof(read_val)) < 0) { DRM_DEBUG_KMS("Failed to read DPCD register 0x%x\n", @@ -111,61 +126,28 @@ { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); - int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1; - u8 pn, pn_min, pn_max; + const u8 pn = connector->panel.backlight.pwmgen_bit_count; + int freq, fxp, f, fxp_actual, fxp_min, fxp_max; - /* Find desired value of (F x P) - * Note that, if F x P is out of supported range, the maximum value or - * minimum value will applied automatically. So no need to check that. - */ freq = dev_priv->vbt.backlight.pwm_freq_hz; - DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq); if (!freq) { DRM_DEBUG_KMS("Use panel default backlight frequency\n"); return false; } fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq); + f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); + fxp_actual = f << pn; - /* Use highest possible value of Pn for more granularity of brightness - * adjustment while satifying the conditions below. - * - Pn is in the range of Pn_min and Pn_max - * - F is in the range of 1 and 255 - * - FxP is within 25% of desired value. - * Note: 25% is arbitrary value and may need some tweak. - */ - if (drm_dp_dpcd_readb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) { - DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n"); - return false; - } - if (drm_dp_dpcd_readb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) { - DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n"); - return false; - } - pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; - + /* Ensure frequency is within 25% of desired value */ fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4); - if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) { - DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n"); - return false; - } - - for (pn = pn_max; pn >= pn_min; pn--) { - f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); - fxp_actual = f << pn; - if (fxp_min <= fxp_actual && fxp_actual <= fxp_max) - break; - } - if (drm_dp_dpcd_writeb(&intel_dp->aux, - DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) { - DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); + if (fxp_min > fxp_actual || fxp_actual > fxp_max) { + DRM_DEBUG_KMS("Actual frequency out of range\n"); return false; } + if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) { DRM_DEBUG_KMS("Failed to write aux backlight freq\n"); @@ -178,6 +160,7 @@ const struct drm_connector_state *conn_state) { struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct intel_panel *panel = &connector->panel; struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode; @@ -197,6 +180,12 @@ case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT: new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; + + if (drm_dp_dpcd_writeb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT, + panel->backlight.pwmgen_bit_count) < 0) + DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); + break; /* Do nothing when it is already DPCD mode */ @@ -216,8 +205,9 @@ } } + intel_dp_aux_set_backlight(conn_state, + connector->panel.backlight.level); set_aux_backlight_enable(intel_dp, true); - intel_dp_aux_set_backlight(conn_state, connector->panel.backlight.level); } static void intel_dp_aux_disable_backlight(const struct drm_connector_state *old_conn_state) @@ -225,20 +215,91 @@ set_aux_backlight_enable(enc_to_intel_dp(old_conn_state->best_encoder), false); } +static u32 intel_dp_aux_calc_max_backlight(struct intel_connector *connector) +{ + struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); + struct intel_panel *panel = &connector->panel; + u32 max_backlight = 0; + int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1; + u8 pn, pn_min, pn_max; + + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT, &pn)) { + pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + max_backlight = (1 << pn) - 1; + } + + /* Find desired value of (F x P) + * Note that, if F x P is out of supported range, the maximum value or + * minimum value will applied automatically. So no need to check that. + */ + freq = dev_priv->vbt.backlight.pwm_freq_hz; + DRM_DEBUG_KMS("VBT defined backlight frequency %u Hz\n", freq); + if (!freq) { + DRM_DEBUG_KMS("Use panel default backlight frequency\n"); + return max_backlight; + } + + fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq); + + /* Use highest possible value of Pn for more granularity of brightness + * adjustment while satifying the conditions below. + * - Pn is in the range of Pn_min and Pn_max + * - F is in the range of 1 and 255 + * - FxP is within 25% of desired value. + * Note: 25% is arbitrary value and may need some tweak. + */ + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) { + DRM_DEBUG_KMS("Failed to read pwmgen bit count cap min\n"); + return max_backlight; + } + if (drm_dp_dpcd_readb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) { + DRM_DEBUG_KMS("Failed to read pwmgen bit count cap max\n"); + return max_backlight; + } + pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK; + + fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4); + fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4); + if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) { + DRM_DEBUG_KMS("VBT defined backlight frequency out of range\n"); + return max_backlight; + } + + for (pn = pn_max; pn >= pn_min; pn--) { + f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255); + fxp_actual = f << pn; + if (fxp_min <= fxp_actual && fxp_actual <= fxp_max) + break; + } + + DRM_DEBUG_KMS("Using eDP pwmgen bit count of %d\n", pn); + if (drm_dp_dpcd_writeb(&intel_dp->aux, + DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) { + DRM_DEBUG_KMS("Failed to write aux pwmgen bit count\n"); + return max_backlight; + } + panel->backlight.pwmgen_bit_count = pn; + + max_backlight = (1 << pn) - 1; + + return max_backlight; +} + static int intel_dp_aux_setup_backlight(struct intel_connector *connector, enum pipe pipe) { - struct intel_dp *intel_dp = enc_to_intel_dp(&connector->encoder->base); struct intel_panel *panel = &connector->panel; - if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) - panel->backlight.max = 0xFFFF; - else - panel->backlight.max = 0xFF; + panel->backlight.max = intel_dp_aux_calc_max_backlight(connector); + if (!panel->backlight.max) + return -ENODEV; panel->backlight.min = 0; panel->backlight.level = intel_dp_aux_get_backlight(connector); - panel->backlight.enabled = panel->backlight.level != 0; return 0; @@ -264,15 +325,35 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector) { struct intel_panel *panel = &intel_connector->panel; - struct drm_i915_private *dev_priv = to_i915(intel_connector->base.dev); + struct intel_dp *intel_dp = enc_to_intel_dp(&intel_connector->encoder->base); + struct drm_device *dev = intel_connector->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + bool force_dpcd; + + force_dpcd = drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks, + DP_QUIRK_FORCE_DPCD_BACKLIGHT); if (i915_modparams.enable_dpcd_backlight == 0 || - (i915_modparams.enable_dpcd_backlight == -1 && - dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)) + (!force_dpcd && !intel_dp_aux_display_control_capable(intel_connector))) return -ENODEV; - if (!intel_dp_aux_display_control_capable(intel_connector)) + /* + * There are a lot of machines that don't advertise the backlight + * control interface to use properly in their VBIOS, :\ + */ + if (dev_priv->vbt.backlight.type != + INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE && + i915_modparams.enable_dpcd_backlight != 1 && !force_dpcd) { + DRM_DEV_INFO(dev->dev, + "Panel advertises DPCD backlight support, but " + "VBT disagrees. If your backlight controls " + "don't work try booting with " + "i915.enable_dpcd_backlight=1. If your machine " + "needs this, please file a _new_ bug report on " + "bugs.freedesktop.org against DRI -> " + "DRM/Intel\n"); return -ENODEV; + } panel->backlight.setup = intel_dp_aux_setup_backlight; panel->backlight.enable = intel_dp_aux_enable_backlight; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -50,7 +50,7 @@ const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode; void *port = connector->port; - bool constant_n = drm_dp_has_quirk(&intel_dp->desc, + bool constant_n = drm_dp_has_quirk(&intel_dp->desc, 0, DP_DPCD_QUIRK_CONSTANT_N); int bpp, slots = -EINVAL; @@ -520,6 +520,7 @@ ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); if (ret) { + drm_dp_mst_put_port_malloc(port); intel_connector_free(intel_connector); return NULL; } @@ -653,21 +654,31 @@ int intel_dp_mst_encoder_init(struct intel_digital_port *intel_dig_port, int conn_base_id) { + struct drm_i915_private *i915 = to_i915(intel_dig_port->base.base.dev); struct intel_dp *intel_dp = &intel_dig_port->dp; - struct drm_device *dev = intel_dig_port->base.base.dev; + enum port port = intel_dig_port->base.port; int ret; - intel_dp->can_mst = true; + if (!HAS_DP_MST(i915) || intel_dp_is_edp(intel_dp)) + return 0; + + if (INTEL_GEN(i915) < 12 && port == PORT_A) + return 0; + + if (INTEL_GEN(i915) < 11 && port == PORT_E) + return 0; + intel_dp->mst_mgr.cbs = &mst_cbs; /* create encoders */ intel_dp_create_fake_mst_encoders(intel_dig_port); - ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, dev, + ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm, &intel_dp->aux, 16, 3, conn_base_id); - if (ret) { - intel_dp->can_mst = false; + if (ret) return ret; - } + + intel_dp->can_mst = true; + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_fbc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_fbc.c @@ -504,8 +504,7 @@ if (!ret) goto err_llb; else if (ret > 1) { - DRM_INFO("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); - + DRM_INFO_ONCE("Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n"); } fbc->threshold = ret; @@ -1284,7 +1283,7 @@ return 0; /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */ - if (IS_GEMINILAKE(dev_priv)) + if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) return 0; if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -221,11 +221,11 @@ struct intel_frontbuffer *front = container_of(ref, typeof(*front), ref); - front->obj->frontbuffer = NULL; + RCU_INIT_POINTER(front->obj->frontbuffer, NULL); spin_unlock(&to_i915(front->obj->base.dev)->fb_tracking.lock); i915_gem_object_put(front->obj); - kfree(front); + kfree_rcu(front, rcu); } struct intel_frontbuffer * @@ -234,11 +234,7 @@ struct drm_i915_private *i915 = to_i915(obj->base.dev); struct intel_frontbuffer *front; - spin_lock(&i915->fb_tracking.lock); - front = obj->frontbuffer; - if (front) - kref_get(&front->ref); - spin_unlock(&i915->fb_tracking.lock); + front = __intel_frontbuffer_get(obj); if (front) return front; @@ -253,13 +249,13 @@ frontbuffer_active, frontbuffer_retire); spin_lock(&i915->fb_tracking.lock); - if (obj->frontbuffer) { + if (rcu_access_pointer(obj->frontbuffer)) { kfree(front); - front = obj->frontbuffer; + front = rcu_dereference_protected(obj->frontbuffer, true); kref_get(&front->ref); } else { i915_gem_object_get(obj); - obj->frontbuffer = front; + rcu_assign_pointer(obj->frontbuffer, front); } spin_unlock(&i915->fb_tracking.lock); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -27,10 +27,10 @@ #include #include +#include "gem/i915_gem_object_types.h" #include "i915_active.h" struct drm_i915_private; -struct drm_i915_gem_object; enum fb_op_origin { ORIGIN_GTT, @@ -45,6 +45,7 @@ atomic_t bits; struct i915_active write; struct drm_i915_gem_object *obj; + struct rcu_head rcu; }; void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, @@ -54,6 +55,35 @@ void intel_frontbuffer_flip(struct drm_i915_private *i915, unsigned frontbuffer_bits); +void intel_frontbuffer_put(struct intel_frontbuffer *front); + +static inline struct intel_frontbuffer * +__intel_frontbuffer_get(const struct drm_i915_gem_object *obj) +{ + struct intel_frontbuffer *front; + + if (likely(!rcu_access_pointer(obj->frontbuffer))) + return NULL; + + rcu_read_lock(); + do { + front = rcu_dereference(obj->frontbuffer); + if (!front) + break; + + if (unlikely(!kref_get_unless_zero(&front->ref))) + continue; + + if (likely(front == rcu_access_pointer(obj->frontbuffer))) + break; + + intel_frontbuffer_put(front); + } while (1); + rcu_read_unlock(); + + return front; +} + struct intel_frontbuffer * intel_frontbuffer_get(struct drm_i915_gem_object *obj); @@ -119,6 +149,4 @@ struct intel_frontbuffer *new, unsigned int frontbuffer_bits); -void intel_frontbuffer_put(struct intel_frontbuffer *front); - #endif /* __INTEL_FRONTBUFFER_H__ */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -1232,6 +1232,11 @@ if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI) return; + if (dev_priv->bypass_tmds_oe) { + DRM_DEBUG_KMS("Bypassing TMDS_OE setting\n"); + return; + } + DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n", enable ? "Enabling" : "Disabling"); @@ -2129,7 +2134,11 @@ if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits, force_dvi)) return MODE_CLOCK_HIGH; - /* BXT DPLL can't generate 223-240 MHz */ + /* GLK DPLL can't generate 446-480 MHz */ + if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000) + return MODE_CLOCK_RANGE; + + /* BXT/GLK DPLL can't generate 223-240 MHz */ if (IS_GEN9_LP(dev_priv) && clock > 223333 && clock < 240000) return MODE_CLOCK_RANGE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -172,6 +172,14 @@ handle_simple_irq, "hdmi_lpe_audio_irq_handler"); + static const struct pci_device_id irq_quirk_ids[] = { + /* Dell Wyse 3040 */ + {PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x22b0, 0x1028, 0x07c1)}, + {} + }; + + if (pci_dev_present(irq_quirk_ids)) + return 0; return irq_set_chip_data(irq, dev_priv); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_overlay.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_overlay.c @@ -278,12 +278,21 @@ struct i915_vma *vma) { enum pipe pipe = overlay->crtc->pipe; + struct intel_frontbuffer *from = NULL, *to = NULL; WARN_ON(overlay->old_vma); - intel_frontbuffer_track(overlay->vma ? overlay->vma->obj->frontbuffer : NULL, - vma ? vma->obj->frontbuffer : NULL, - INTEL_FRONTBUFFER_OVERLAY(pipe)); + if (overlay->vma) + from = intel_frontbuffer_get(overlay->vma->obj); + if (vma) + to = intel_frontbuffer_get(vma->obj); + + intel_frontbuffer_track(from, to, INTEL_FRONTBUFFER_OVERLAY(pipe)); + + if (to) + intel_frontbuffer_put(to); + if (from) + intel_frontbuffer_put(from); intel_frontbuffer_flip_prepare(overlay->i915, INTEL_FRONTBUFFER_OVERLAY(pipe)); @@ -768,7 +777,7 @@ ret = PTR_ERR(vma); goto out_pin_section; } - intel_frontbuffer_flush(new_bo->frontbuffer, ORIGIN_DIRTYFB); + i915_gem_object_flush_frontbuffer(new_bo, ORIGIN_DIRTYFB); if (!overlay->active) { u32 oconfig; @@ -913,6 +922,9 @@ const struct intel_crtc_state *pipe_config = overlay->crtc->config; + if (rec->dst_height == 0 || rec->dst_width == 0) + return -EINVAL; + if (rec->dst_x < pipe_config->pipe_src_w && rec->dst_x + rec->dst_width <= pipe_config->pipe_src_w && rec->dst_y < pipe_config->pipe_src_h && --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_panel.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_panel.c @@ -1603,20 +1603,21 @@ val = pch_get_backlight(connector); else val = lpt_get_backlight(connector); - val = intel_panel_compute_brightness(connector, val); - panel->backlight.level = clamp(val, panel->backlight.min, - panel->backlight.max); if (cpu_mode) { DRM_DEBUG_KMS("CPU backlight register was enabled, switching to PCH override\n"); /* Write converted CPU PWM value to PCH override register */ - lpt_set_backlight(connector->base.state, panel->backlight.level); + lpt_set_backlight(connector->base.state, val); I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1 | BLM_PCH_OVERRIDE_ENABLE); I915_WRITE(BLC_PWM_CPU_CTL2, cpu_ctl2 & ~BLM_PWM_ENABLE); } + val = intel_panel_compute_brightness(connector, val); + panel->backlight.level = clamp(val, panel->backlight.min, + panel->backlight.max); + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_psr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_psr.c @@ -291,7 +291,7 @@ DRM_DEBUG_KMS("eDP panel supports PSR version %x\n", intel_dp->psr_dpcd[0]); - if (drm_dp_has_quirk(&intel_dp->desc, DP_DPCD_QUIRK_NO_PSR)) { + if (drm_dp_has_quirk(&intel_dp->desc, 0, DP_DPCD_QUIRK_NO_PSR)) { DRM_DEBUG_KMS("PSR support not currently available for this panel\n"); return; } @@ -1219,6 +1219,14 @@ if (!dev_priv->psr.sink_support) return; + /* + * PSR was disabled by module parameters but the underlying panel is + * depending on it, so use per-chip default to probe that automatically. + */ + if ((dev_priv->psr.dp->edid_quirks & BIT(DP_QUIRK_FORCE_PSR_CHIP_DEFAULT)) && + i915_modparams.enable_psr == 0) + i915_modparams.enable_psr = -1; + if (i915_modparams.enable_psr == -1) if (INTEL_GEN(dev_priv) < 9 || !dev_priv->vbt.psr.enable) i915_modparams.enable_psr = 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_quirks.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_quirks.c @@ -146,6 +146,11 @@ /* ASRock ITX*/ { 0x3185, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, { 0x3184, 0x1849, 0x2212, quirk_increase_ddi_disabled_time }, + /* ECS Liva Q2 */ + { 0x3185, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time }, + { 0x3184, 0x1019, 0xa94d, quirk_increase_ddi_disabled_time }, + /* HP Notebook - 14-r206nv */ + { 0x0f31, 0x103c, 0x220f, quirk_invert_brightness }, }; void intel_init_quirks(struct drm_i915_private *i915) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_sdvo.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -2693,13 +2693,10 @@ if (!intel_sdvo_connector) return false; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; - } intel_connector = &intel_sdvo_connector->base; connector = &intel_connector->base; @@ -2753,7 +2750,6 @@ encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; - intel_sdvo->controlled_output |= type; intel_sdvo_connector->output_flag = type; if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { @@ -2794,13 +2790,10 @@ encoder->encoder_type = DRM_MODE_ENCODER_DAC; connector->connector_type = DRM_MODE_CONNECTOR_VGA; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; - } if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { kfree(intel_sdvo_connector); @@ -2830,13 +2823,10 @@ encoder->encoder_type = DRM_MODE_ENCODER_LVDS; connector->connector_type = DRM_MODE_CONNECTOR_LVDS; - if (device == 0) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; + if (device == 0) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; - } else if (device == 1) { - intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; + else if (device == 1) intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; - } if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { kfree(intel_sdvo_connector); @@ -2869,16 +2859,39 @@ return false; } +static u16 intel_sdvo_filter_output_flags(u16 flags) +{ + flags &= SDVO_OUTPUT_MASK; + + /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ + if (!(flags & SDVO_OUTPUT_TMDS0)) + flags &= ~SDVO_OUTPUT_TMDS1; + + if (!(flags & SDVO_OUTPUT_RGB0)) + flags &= ~SDVO_OUTPUT_RGB1; + + if (!(flags & SDVO_OUTPUT_LVDS0)) + flags &= ~SDVO_OUTPUT_LVDS1; + + return flags; +} + static bool intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags) { - /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ + struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); + + flags = intel_sdvo_filter_output_flags(flags); + + intel_sdvo->controlled_output = flags; + + intel_sdvo_select_ddc_bus(i915, intel_sdvo); if (flags & SDVO_OUTPUT_TMDS0) if (!intel_sdvo_dvi_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) + if (flags & SDVO_OUTPUT_TMDS1) if (!intel_sdvo_dvi_init(intel_sdvo, 1)) return false; @@ -2899,7 +2912,7 @@ if (!intel_sdvo_analog_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) + if (flags & SDVO_OUTPUT_RGB1) if (!intel_sdvo_analog_init(intel_sdvo, 1)) return false; @@ -2907,14 +2920,13 @@ if (!intel_sdvo_lvds_init(intel_sdvo, 0)) return false; - if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) + if (flags & SDVO_OUTPUT_LVDS1) if (!intel_sdvo_lvds_init(intel_sdvo, 1)) return false; - if ((flags & SDVO_OUTPUT_MASK) == 0) { + if (flags == 0) { unsigned char bytes[2]; - intel_sdvo->controlled_output = 0; memcpy(bytes, &intel_sdvo->caps.output_flags, 2); DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", SDVO_NAME(intel_sdvo), @@ -3321,8 +3333,6 @@ */ intel_sdvo->base.cloneable = 0; - intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo); - /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) goto err_output; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/intel_tc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/intel_tc.c @@ -45,6 +45,62 @@ return tc_port / 2; } +static enum intel_display_power_domain +tc_cold_get_power_domain(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + if (INTEL_GEN(i915) == 11) + return intel_legacy_aux_to_power_domain(dig_port->aux_ch); + else + return POWER_DOMAIN_TC_COLD_OFF; +} + +static intel_wakeref_t +tc_cold_block(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum intel_display_power_domain domain; + + if (INTEL_GEN(i915) == 11 && !dig_port->tc_legacy_port) + return 0; + + domain = tc_cold_get_power_domain(dig_port); + return intel_display_power_get(i915, domain); +} + +static void +tc_cold_unblock(struct intel_digital_port *dig_port, intel_wakeref_t wakeref) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum intel_display_power_domain domain; + + /* + * wakeref == -1, means some error happened saving save_depot_stack but + * power should still be put down and 0 is a invalid save_depot_stack + * id so can be used to skip it for non TC legacy ports. + */ + if (wakeref == 0) + return; + + domain = tc_cold_get_power_domain(dig_port); + intel_display_power_put_async(i915, domain, wakeref); +} + +static void +assert_tc_cold_blocked(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + bool enabled; + + if (INTEL_GEN(i915) == 11 && !dig_port->tc_legacy_port) + return; + + enabled = intel_display_power_is_enabled(i915, + tc_cold_get_power_domain(dig_port)); + WARN_ON(!enabled); +} + u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -56,6 +112,7 @@ PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia)); WARN_ON(lane_mask == 0xffffffff); + assert_tc_cold_blocked(dig_port); return (lane_mask & DP_LANE_ASSIGNMENT_MASK(tc_port)) >> DP_LANE_ASSIGNMENT_SHIFT(tc_port); @@ -70,6 +127,8 @@ if (dig_port->tc_mode != TC_PORT_DP_ALT) return 4; + assert_tc_cold_blocked(dig_port); + lane_mask = 0; with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) lane_mask = intel_tc_port_get_lane_mask(dig_port); @@ -102,6 +161,8 @@ WARN_ON(lane_reversal && dig_port->tc_mode != TC_PORT_LEGACY); + assert_tc_cold_blocked(dig_port); + val = intel_uncore_read(uncore, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia)); val &= ~DFLEXDPMLE1_DPMLETC_MASK(tc_port); @@ -390,8 +451,14 @@ enum tc_port_mode old_tc_mode = dig_port->tc_mode; intel_display_power_flush_work(i915); - WARN_ON(intel_display_power_is_enabled(i915, - intel_aux_power_domain(dig_port))); + if (INTEL_GEN(i915) != 11 || !dig_port->tc_legacy_port) { + enum intel_display_power_domain aux_domain; + bool aux_powered; + + aux_domain = intel_aux_power_domain(dig_port); + aux_powered = intel_display_power_is_enabled(i915, aux_domain); + WARN_ON(aux_powered); + } icl_tc_phy_disconnect(dig_port); icl_tc_phy_connect(dig_port, required_lanes); @@ -413,9 +480,11 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port) { struct intel_encoder *encoder = &dig_port->base; + intel_wakeref_t tc_cold_wref; int active_links = 0; mutex_lock(&dig_port->tc_lock); + tc_cold_wref = tc_cold_block(dig_port); dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); if (dig_port->dp.is_mst) @@ -440,6 +509,7 @@ dig_port->tc_port_name, tc_port_mode_name(dig_port->tc_mode)); + tc_cold_unblock(dig_port, tc_cold_wref); mutex_unlock(&dig_port->tc_lock); } @@ -461,10 +531,15 @@ bool intel_tc_port_connected(struct intel_digital_port *dig_port) { bool is_connected; + intel_wakeref_t tc_cold_wref; intel_tc_port_lock(dig_port); + tc_cold_wref = tc_cold_block(dig_port); + is_connected = tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); + + tc_cold_unblock(dig_port, tc_cold_wref); intel_tc_port_unlock(dig_port); return is_connected; @@ -480,9 +555,16 @@ mutex_lock(&dig_port->tc_lock); - if (!dig_port->tc_link_refcount && - intel_tc_port_needs_reset(dig_port)) - intel_tc_port_reset_mode(dig_port, required_lanes); + if (!dig_port->tc_link_refcount) { + intel_wakeref_t tc_cold_wref; + + tc_cold_wref = tc_cold_block(dig_port); + + if (intel_tc_port_needs_reset(dig_port)) + intel_tc_port_reset_mode(dig_port, required_lanes); + + tc_cold_unblock(dig_port, tc_cold_wref); + } WARN_ON(dig_port->tc_lock_wakeref); dig_port->tc_lock_wakeref = wakeref; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/display/vlv_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -797,10 +797,20 @@ if (intel_dsi->gpio_panel) gpiod_set_value_cansleep(intel_dsi->gpio_panel, 1); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_POWER_ON); - intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); - /* Deassert reset */ - intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); + /* + * Give the panel time to power-on and then deassert its reset. + * Depending on the VBT MIPI sequences version the deassert-seq + * may contain the necessary delay, intel_dsi_msleep() will skip + * the delay in that case. If there is no deassert-seq, then an + * unconditional msleep is used to give the panel time to power-on. + */ + if (dev_priv->vbt.dsi.sequence[MIPI_SEQ_DEASSERT_RESET]) { + intel_dsi_msleep(intel_dsi, intel_dsi->panel_on_delay); + intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); + } else { + msleep(intel_dsi->panel_on_delay); + } if (IS_GEMINILAKE(dev_priv)) { glk_cold_boot = glk_dsi_enable_io(encoder); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_busy.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_busy.c @@ -9,16 +9,16 @@ #include "i915_gem_ioctls.h" #include "i915_gem_object.h" -static __always_inline u32 __busy_read_flag(u8 id) +static __always_inline u32 __busy_read_flag(u16 id) { - if (id == (u8)I915_ENGINE_CLASS_INVALID) + if (id == (u16)I915_ENGINE_CLASS_INVALID) return 0xffff0000u; GEM_BUG_ON(id >= 16); return 0x10000u << id; } -static __always_inline u32 __busy_write_id(u8 id) +static __always_inline u32 __busy_write_id(u16 id) { /* * The uABI guarantees an active writer is also amongst the read @@ -29,14 +29,14 @@ * last_read - hence we always set both read and write busy for * last_write. */ - if (id == (u8)I915_ENGINE_CLASS_INVALID) + if (id == (u16)I915_ENGINE_CLASS_INVALID) return 0xffffffffu; return (id + 1) | __busy_read_flag(id); } static __always_inline unsigned int -__busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u8 id)) +__busy_set_if_active(const struct dma_fence *fence, u32 (*flag)(u16 id)) { const struct i915_request *rq; @@ -57,7 +57,7 @@ return 0; /* Beware type-expansion follies! */ - BUILD_BUG_ON(!typecheck(u8, rq->engine->uabi_class)); + BUILD_BUG_ON(!typecheck(u16, rq->engine->uabi_class)); return flag(rq->engine->uabi_class); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_clflush.c @@ -20,7 +20,8 @@ { GEM_BUG_ON(!i915_gem_object_has_pages(obj)); drm_clflush_sg(obj->mm.pages); - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); + + i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); } static int clflush_work(struct dma_fence_work *base) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -2094,8 +2094,7 @@ ext_data.fpriv = file->driver_priv; if (client_is_banned(ext_data.fpriv)) { DRM_DEBUG("client %s[%d] banned from creating ctx\n", - current->comm, - pid_nr(get_task_pid(current, PIDTYPE_PID))); + current->comm, task_pid_nr(current)); return -EIO; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -36,13 +36,13 @@ goto err_unpin_pages; } - ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL); + ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL); if (ret) goto err_free; src = obj->mm.pages->sgl; dst = st->sgl; - for (i = 0; i < obj->mm.pages->nents; i++) { + for (i = 0; i < obj->mm.pages->orig_nents; i++) { sg_set_page(dst, sg_page(src), src->length, 0); dst = sg_next(dst); src = sg_next(src); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -606,21 +606,6 @@ return -ENOENT; /* - * Already in the desired write domain? Nothing for us to do! - * - * We apply a little bit of cunning here to catch a broader set of - * no-ops. If obj->write_domain is set, we must be in the same - * obj->read_domains, and only that domain. Therefore, if that - * obj->write_domain matches the request read_domains, we are - * already in the same read/write domain and can skip the operation, - * without having to further check the requested write_domain. - */ - if (READ_ONCE(obj->write_domain) == read_domains) { - err = 0; - goto out; - } - - /* * Try to flush the object off the GPU without holding the lock. * We will repeat the flush holding the lock in the normal manner * to catch cases where we are gazumped. @@ -657,6 +642,19 @@ if (err) goto out; + /* + * Already in the desired write domain? Nothing for us to do! + * + * We apply a little bit of cunning here to catch a broader set of + * no-ops. If obj->write_domain is set, we must be in the same + * obj->read_domains, and only that domain. Therefore, if that + * obj->write_domain matches the request read_domains, we are + * already in the same read/write domain and can skip the operation, + * without having to further check the requested write_domain. + */ + if (READ_ONCE(obj->write_domain) == read_domains) + goto out_unpin; + err = i915_gem_object_lock_interruptible(obj); if (err) goto out_unpin; @@ -674,7 +672,7 @@ i915_gem_object_unlock(obj); if (write_domain) - intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); out_unpin: i915_gem_object_unpin_pages(obj); @@ -794,7 +792,7 @@ } out: - intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); obj->mm.dirty = true; /* return with the pages pinned */ return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -367,7 +367,7 @@ return true; if (!(flags & EXEC_OBJECT_SUPPORTS_48B_ADDRESS) && - (vma->node.start + vma->node.size - 1) >> 32) + (vma->node.start + vma->node.size + 4095) >> 32) return true; if (flags & __EXEC_OBJECT_NEEDS_MAP && @@ -439,7 +439,8 @@ if (unlikely(entry->flags & eb->invalid_flags)) return -EINVAL; - if (unlikely(entry->alignment && !is_power_of_2(entry->alignment))) + if (unlikely(entry->alignment && + !is_power_of_2_u64(entry->alignment))) return -EINVAL; /* @@ -930,11 +931,13 @@ static void reloc_gpu_flush(struct reloc_cache *cache) { - GEM_BUG_ON(cache->rq_size >= cache->rq->batch->obj->base.size / sizeof(u32)); + struct drm_i915_gem_object *obj = cache->rq->batch->obj; + + GEM_BUG_ON(cache->rq_size >= obj->base.size / sizeof(u32)); cache->rq_cmd[cache->rq_size] = MI_BATCH_BUFFER_END; - __i915_gem_object_flush_map(cache->rq->batch->obj, 0, cache->rq_size); - i915_gem_object_unpin_map(cache->rq->batch->obj); + i915_gem_object_flush_map(obj); + i915_gem_object_unpin_map(obj); intel_gt_chipset_flush(cache->rq->engine->gt); @@ -1160,6 +1163,8 @@ goto out_pool; } + memset32(cmd, 0, pool->obj->base.size / sizeof(u32)); + batch = i915_vma_instance(pool->obj, vma->vm, NULL); if (IS_ERR(batch)) { err = PTR_ERR(batch); @@ -1447,7 +1452,7 @@ urelocs = u64_to_user_ptr(entry->relocs_ptr); remain = entry->relocation_count; - if (unlikely(remain > N_RELOC(ULONG_MAX))) + if (unlikely((unsigned long)remain > N_RELOC(ULONG_MAX))) return -EINVAL; /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -181,7 +181,7 @@ struct i915_ggtt_view view; if (i915_gem_object_is_tiled(obj)) - chunk = roundup(chunk, tile_row_pages(obj)); + chunk = roundup(chunk, tile_row_pages(obj) ?: 1); view.type = I915_GGTT_VIEW_PARTIAL; view.partial.offset = rounddown(page_offset, chunk); @@ -196,6 +196,39 @@ return view; } +static void set_address_limits(struct vm_area_struct *area, + struct i915_vma *vma, + unsigned long *start_vaddr, + unsigned long *end_vaddr) +{ + unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ + long start, end; /* memory boundaries */ + + /* + * Let's move into the ">> PAGE_SHIFT" + * domain to be sure not to lose bits + */ + vm_start = area->vm_start >> PAGE_SHIFT; + vm_end = area->vm_end >> PAGE_SHIFT; + vma_size = vma->size >> PAGE_SHIFT; + + /* + * Calculate the memory boundaries by considering the offset + * provided by the user during memory mapping and the offset + * provided for the partial mapping. + */ + start = vm_start; + start += vma->ggtt_view.partial.offset; + end = start + vma_size; + + start = max_t(long, start, vm_start); + end = min_t(long, end, vm_end); + + /* Let's move back into the "<< PAGE_SHIFT" domain */ + *start_vaddr = (unsigned long)start << PAGE_SHIFT; + *end_vaddr = (unsigned long)end << PAGE_SHIFT; +} + /** * i915_gem_fault - fault a page into the GTT * @vmf: fault info @@ -224,9 +257,11 @@ struct intel_runtime_pm *rpm = &i915->runtime_pm; struct i915_ggtt *ggtt = &i915->ggtt; bool write = area->vm_flags & VM_WRITE; + unsigned long start, end; /* memory boundaries */ intel_wakeref_t wakeref; struct i915_vma *vma; pgoff_t page_offset; + unsigned long pfn; int srcu; int ret; @@ -295,12 +330,14 @@ if (ret) goto err_unpin; + set_address_limits(area, vma, &start, &end); + + pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; + pfn += (start - area->vm_start) >> PAGE_SHIFT; + pfn -= vma->ggtt_view.partial.offset; + /* Finally, remap it using the new GTT offset */ - ret = remap_io_mapping(area, - area->vm_start + (vma->ggtt_view.partial.offset << PAGE_SHIFT), - (ggtt->gmadr.start + vma->node.start) >> PAGE_SHIFT, - min_t(u64, vma->size, area->vm_end - area->vm_start), - &ggtt->iomap); + ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap); if (ret) goto err_fence; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -270,7 +270,7 @@ for_each_ggtt_vma(vma, obj) intel_gt_flush_ggtt_writes(vma->vm->gt); - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); for_each_ggtt_vma(vma, obj) { if (vma->iomap) @@ -298,6 +298,30 @@ obj->write_domain = 0; } +void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin) +{ + struct intel_frontbuffer *front; + + front = __intel_frontbuffer_get(obj); + if (front) { + intel_frontbuffer_flush(front, origin); + intel_frontbuffer_put(front); + } +} + +void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin) +{ + struct intel_frontbuffer *front; + + front = __intel_frontbuffer_get(obj); + if (front) { + intel_frontbuffer_invalidate(front, origin); + intel_frontbuffer_put(front); + } +} + void i915_gem_init__objects(struct drm_i915_private *i915) { INIT_WORK(&i915->mm.free_work, __i915_gem_free_work); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -13,8 +13,8 @@ #include +#include "display/intel_frontbuffer.h" #include "i915_gem_object_types.h" - #include "i915_gem_gtt.h" void i915_gem_init__objects(struct drm_i915_private *i915); @@ -431,4 +431,25 @@ const struct i915_sched_attr *attr); #define I915_PRIORITY_DISPLAY I915_USER_PRIORITY(I915_PRIORITY_MAX) +void __i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin); +void __i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin); + +static inline void +i915_gem_object_flush_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin) +{ + if (unlikely(rcu_access_pointer(obj->frontbuffer))) + __i915_gem_object_flush_frontbuffer(obj, origin); +} + +static inline void +i915_gem_object_invalidate_frontbuffer(struct drm_i915_gem_object *obj, + enum fb_op_origin origin) +{ + if (unlikely(rcu_access_pointer(obj->frontbuffer))) + __i915_gem_object_invalidate_frontbuffer(obj, origin); +} + #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -118,6 +118,9 @@ I915_SELFTEST_DECLARE(struct list_head st_link); + unsigned long flags; +#define I915_BO_WAS_BOUND_BIT 0 + /* * Is the object to be mapped as read-only to the GPU * Only honoured if hardware has relevant pte bit @@ -143,7 +146,7 @@ */ u16 write_domain; - struct intel_frontbuffer *frontbuffer; + struct intel_frontbuffer __rcu *frontbuffer; /** Current tiling stride for the object, if it's tiled. */ unsigned int tiling_and_stride; @@ -240,9 +243,6 @@ void *gvt_info; }; - - /** for phys allocated objects */ - struct drm_dma_handle *phys_handle; }; static inline struct drm_i915_gem_object * --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -8,6 +8,8 @@ #include "i915_gem_object.h" #include "i915_scatterlist.h" +#include "gt/intel_gt.h" + void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, unsigned int sg_page_sizes) @@ -176,6 +178,14 @@ __i915_gem_object_reset_page_iter(obj); obj->mm.page_sizes.phys = obj->mm.page_sizes.sg = 0; + if (test_and_clear_bit(I915_BO_WAS_BOUND_BIT, &obj->flags)) { + struct drm_i915_private *i915 = to_i915(obj->base.dev); + intel_wakeref_t wakeref; + + with_intel_runtime_pm_if_in_use(&i915->runtime_pm, wakeref) + intel_gt_invalidate_tlbs(&i915->gt); + } + return pages; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -21,88 +21,87 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) { struct address_space *mapping = obj->base.filp->f_mapping; - struct drm_dma_handle *phys; - struct sg_table *st; struct scatterlist *sg; - char *vaddr; + struct sg_table *st; + dma_addr_t dma; + void *vaddr; + void *dst; int i; - int err; if (WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) return -EINVAL; - /* Always aligning to the object size, allows a single allocation + /* + * Always aligning to the object size, allows a single allocation * to handle all possible callers, and given typical object sizes, * the alignment of the buddy allocation will naturally match. */ - phys = drm_pci_alloc(obj->base.dev, - roundup_pow_of_two(obj->base.size), - roundup_pow_of_two(obj->base.size)); - if (!phys) + vaddr = dma_alloc_coherent(&obj->base.dev->pdev->dev, + roundup_pow_of_two(obj->base.size), + &dma, GFP_KERNEL); + if (!vaddr) return -ENOMEM; - vaddr = phys->vaddr; + st = kmalloc(sizeof(*st), GFP_KERNEL); + if (!st) + goto err_pci; + + if (sg_alloc_table(st, 1, GFP_KERNEL)) + goto err_st; + + sg = st->sgl; + sg->offset = 0; + sg->length = obj->base.size; + + sg_assign_page(sg, (struct page *)vaddr); + sg_dma_address(sg) = dma; + sg_dma_len(sg) = obj->base.size; + + dst = vaddr; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { struct page *page; - char *src; + void *src; page = shmem_read_mapping_page(mapping, i); - if (IS_ERR(page)) { - err = PTR_ERR(page); - goto err_phys; - } + if (IS_ERR(page)) + goto err_st; src = kmap_atomic(page); - memcpy(vaddr, src, PAGE_SIZE); - drm_clflush_virt_range(vaddr, PAGE_SIZE); + memcpy(dst, src, PAGE_SIZE); + drm_clflush_virt_range(dst, PAGE_SIZE); kunmap_atomic(src); put_page(page); - vaddr += PAGE_SIZE; + dst += PAGE_SIZE; } intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); - st = kmalloc(sizeof(*st), GFP_KERNEL); - if (!st) { - err = -ENOMEM; - goto err_phys; - } - - if (sg_alloc_table(st, 1, GFP_KERNEL)) { - kfree(st); - err = -ENOMEM; - goto err_phys; - } - - sg = st->sgl; - sg->offset = 0; - sg->length = obj->base.size; - - sg_dma_address(sg) = phys->busaddr; - sg_dma_len(sg) = obj->base.size; - - obj->phys_handle = phys; - __i915_gem_object_set_pages(obj, st, sg->length); return 0; -err_phys: - drm_pci_free(obj->base.dev, phys); - - return err; +err_st: + kfree(st); +err_pci: + dma_free_coherent(&obj->base.dev->pdev->dev, + roundup_pow_of_two(obj->base.size), + vaddr, dma); + return -ENOMEM; } static void i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, struct sg_table *pages) { + dma_addr_t dma = sg_dma_address(pages->sgl); + void *vaddr = sg_page(pages->sgl); + __i915_gem_object_release_shmem(obj, pages, false); if (obj->mm.dirty) { struct address_space *mapping = obj->base.filp->f_mapping; - char *vaddr = obj->phys_handle->vaddr; + void *src = vaddr; int i; for (i = 0; i < obj->base.size / PAGE_SIZE; i++) { @@ -114,15 +113,16 @@ continue; dst = kmap_atomic(page); - drm_clflush_virt_range(vaddr, PAGE_SIZE); - memcpy(dst, vaddr, PAGE_SIZE); + drm_clflush_virt_range(src, PAGE_SIZE); + memcpy(dst, src, PAGE_SIZE); kunmap_atomic(dst); set_page_dirty(page); if (obj->mm.madv == I915_MADV_WILLNEED) mark_page_accessed(page); put_page(page); - vaddr += PAGE_SIZE; + + src += PAGE_SIZE; } obj->mm.dirty = false; } @@ -130,7 +130,9 @@ sg_free_table(pages); kfree(pages); - drm_pci_free(obj->base.dev, obj->phys_handle); + dma_free_coherent(&obj->base.dev->pdev->dev, + roundup_pow_of_two(obj->base.size), + vaddr, dma); } static void phys_release(struct drm_i915_gem_object *obj) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -36,7 +36,6 @@ unsigned long last_pfn = 0; /* suppress gcc warning */ unsigned int max_segment = i915_sg_segment_size(); unsigned int sg_page_sizes; - struct pagevec pvec; gfp_t noreclaim; int ret; @@ -188,13 +187,17 @@ sg_mark_end(sg); err_pages: mapping_clear_unevictable(mapping); - pagevec_init(&pvec); - for_each_sgt_page(page, sgt_iter, st) { - if (!pagevec_add(&pvec, page)) + if (sg != st->sgl) { + struct pagevec pvec; + + pagevec_init(&pvec); + for_each_sgt_page(page, sgt_iter, st) { + if (!pagevec_add(&pvec, page)) + check_release_pagevec(&pvec); + } + if (pagevec_count(&pvec)) check_release_pagevec(&pvec); } - if (pagevec_count(&pvec)) - check_release_pagevec(&pvec); sg_free_table(st); kfree(st); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -357,8 +357,7 @@ sc->nr_to_scan, &sc->nr_scanned, I915_SHRINK_BOUND | - I915_SHRINK_UNBOUND | - I915_SHRINK_WRITEBACK); + I915_SHRINK_UNBOUND); if (sc->nr_scanned < sc->nr_to_scan && current_is_kswapd()) { intel_wakeref_t wakeref; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -427,7 +427,7 @@ static struct sg_table * __i915_gem_userptr_alloc_pages(struct drm_i915_gem_object *obj, - struct page **pvec, int num_pages) + struct page **pvec, unsigned long num_pages) { unsigned int max_segment = i915_sg_segment_size(); struct sg_table *st; @@ -473,9 +473,10 @@ { struct get_pages_work *work = container_of(_work, typeof(*work), work); struct drm_i915_gem_object *obj = work->obj; - const int npages = obj->base.size >> PAGE_SHIFT; + const unsigned long npages = obj->base.size >> PAGE_SHIFT; + unsigned long pinned; struct page **pvec; - int pinned, ret; + int ret; ret = -ENOMEM; pinned = 0; @@ -578,7 +579,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) { - const int num_pages = obj->base.size >> PAGE_SHIFT; + const unsigned long num_pages = obj->base.size >> PAGE_SHIFT; struct mm_struct *mm = obj->userptr.mm->mm; struct page **pvec; struct sg_table *pages; @@ -618,6 +619,14 @@ GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN); + /* + * Using __get_user_pages_fast() with a read-only + * access is questionable. A read-only page may be + * COW-broken, and then this might end up giving + * the wrong side of the COW.. + * + * We may or may not care. + */ if (pvec) /* defer to worker if malloc fails */ pinned = __get_user_pages_fast(obj->userptr.ptr, num_pages, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -375,7 +375,7 @@ obj = i915_gem_object_create_internal(i915, size); if (IS_ERR(obj)) - return PTR_ERR(obj); + return false; err = create_mmap_offset(obj); i915_gem_object_put(obj); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_engine.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_engine.h @@ -250,6 +250,14 @@ return pos & (ring->size - 1); } +static inline int intel_ring_direction(const struct intel_ring *ring, + u32 next, u32 prev) +{ + typecheck(typeof(ring->size), next); + typecheck(typeof(ring->size), prev); + return (next - prev) << ring->wrap; +} + static inline bool intel_ring_offset_valid(const struct intel_ring *ring, unsigned int pos) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -28,13 +28,13 @@ #include "i915_drv.h" -#include "gt/intel_gt.h" - +#include "intel_context.h" #include "intel_engine.h" #include "intel_engine_pm.h" #include "intel_engine_pool.h" #include "intel_engine_user.h" -#include "intel_context.h" +#include "intel_gt.h" +#include "intel_gt_requests.h" #include "intel_lrc.h" #include "intel_reset.h" @@ -354,7 +354,8 @@ * instances. */ if ((INTEL_GEN(i915) >= 11 && - RUNTIME_INFO(i915)->vdbox_sfc_access & engine->mask) || + (RUNTIME_INFO(i915)->vdbox_sfc_access & + BIT(engine->instance))) || (INTEL_GEN(i915) >= 9 && engine->instance == 0)) engine->uabi_capabilities |= I915_VIDEO_AND_ENHANCE_CLASS_CAPABILITY_SFC; @@ -600,6 +601,7 @@ intel_engine_init_hangcheck(engine); intel_engine_init_cmd_parser(engine); intel_engine_init__pm(engine); + intel_engine_init_retire(engine); intel_engine_pool_init(&engine->pool); @@ -807,6 +809,7 @@ cleanup_status_page(engine); + intel_engine_fini_retire(engine); intel_engine_pool_fini(&engine->pool); intel_engine_fini_breadcrumbs(engine); intel_engine_cleanup_cmd_parser(engine); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_engine_pm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_engine_pm.c @@ -70,8 +70,43 @@ #endif /* !IS_ENABLED(CONFIG_LOCKDEP) */ +static void +__queue_and_release_pm(struct i915_request *rq, + struct intel_timeline *tl, + struct intel_engine_cs *engine) +{ + struct intel_gt_timelines *timelines = &engine->gt->timelines; + unsigned long flags; + + GEM_TRACE("%s\n", engine->name); + + /* + * We have to serialise all potential retirement paths with our + * submission, as we don't want to underflow either the + * engine->wakeref.counter or our timeline->active_count. + * + * Equally, we cannot allow a new submission to start until + * after we finish queueing, nor could we allow that submitter + * to retire us before we are ready! + */ + spin_lock_irqsave(&timelines->lock, flags); + + /* Let intel_gt_retire_requests() retire us (acquired under lock) */ + if (!atomic_fetch_inc(&tl->active_count)) + list_add_tail(&tl->link, &timelines->active_list); + + /* Hand the request over to HW and so engine_retire() */ + __i915_request_queue(rq, NULL); + + /* Let new submissions commence (and maybe retire this timeline) */ + __intel_wakeref_defer_park(&engine->wakeref); + + spin_unlock_irqrestore(&timelines->lock, flags); +} + static bool switch_to_kernel_context(struct intel_engine_cs *engine) { + struct intel_context *ce = engine->kernel_context; struct i915_request *rq; unsigned long flags; bool result = true; @@ -96,15 +131,13 @@ * retiring the last request, thus all rings should be empty and * all timelines idle. */ - flags = __timeline_mark_lock(engine->kernel_context); + flags = __timeline_mark_lock(ce); - rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT); + rq = __i915_request_create(ce, GFP_NOWAIT); if (IS_ERR(rq)) /* Context switch failed, hope for the best! Maybe reset? */ goto out_unlock; - intel_timeline_enter(rq->timeline); - /* Check again on the next retirement. */ engine->wakeref_serial = engine->serial + 1; i915_request_add_active_barriers(rq); @@ -113,13 +146,12 @@ rq->sched.attr.priority = I915_PRIORITY_UNPREEMPTABLE; __i915_request_commit(rq); - /* Release our exclusive hold on the engine */ - __intel_wakeref_defer_park(&engine->wakeref); - __i915_request_queue(rq, NULL); + /* Expose ourselves to the world */ + __queue_and_release_pm(rq, ce->timeline, engine); result = false; out_unlock: - __timeline_mark_unlock(engine->kernel_context, flags); + __timeline_mark_unlock(ce, flags); return result; } @@ -145,9 +177,6 @@ intel_engine_disarm_breadcrumbs(engine); intel_engine_pool_park(&engine->pool); - /* Must be reset upon idling, or we may miss the busy wakeup. */ - GEM_BUG_ON(engine->execlists.queue_priority_hint != INT_MIN); - if (engine->park) engine->park(engine); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -107,6 +107,7 @@ u32 space; u32 size; + u32 wrap; u32 effective_size; }; @@ -300,8 +301,8 @@ u8 class; u8 instance; - u8 uabi_class; - u8 uabi_instance; + u16 uabi_class; + u16 uabi_instance; u32 context_size; u32 mmio_base; @@ -470,6 +471,14 @@ struct intel_engine_execlists execlists; + /* + * Keep track of completed timelines on this engine for early + * retirement with the goal of quickly enabling powersaving as + * soon as the engine is idle. + */ + struct intel_timeline *retire; + struct work_struct retire_work; + /* status_notifier: list of callbacks for context-switch changes */ struct atomic_notifier_head context_status_notifier; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_gt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_gt.c @@ -15,6 +15,8 @@ spin_lock_init(>->irq_lock); + mutex_init(>->tlb_invalidate_lock); + INIT_LIST_HEAD(>->closed_vma); spin_lock_init(>->closed_lock); @@ -266,3 +268,117 @@ intel_uc_driver_late_release(>->uc); intel_gt_fini_reset(gt); } + +struct reg_and_bit { + i915_reg_t reg; + u32 bit; +}; + +static struct reg_and_bit +get_reg_and_bit(const struct intel_engine_cs *engine, const bool gen8, + const i915_reg_t *regs, const unsigned int num) +{ + const unsigned int class = engine->class; + struct reg_and_bit rb = { }; + + if (WARN_ON_ONCE(class >= num || !regs[class].reg)) + return rb; + + rb.reg = regs[class]; + if (gen8 && class == VIDEO_DECODE_CLASS) + rb.reg.reg += 4 * engine->instance; /* GEN8_M2TCR */ + else + rb.bit = engine->instance; + + rb.bit = BIT(rb.bit); + + return rb; +} + +void intel_gt_invalidate_tlbs(struct intel_gt *gt) +{ + static const i915_reg_t gen8_regs[] = { + [RENDER_CLASS] = GEN8_RTCR, + [VIDEO_DECODE_CLASS] = GEN8_M1TCR, /* , GEN8_M2TCR */ + [VIDEO_ENHANCEMENT_CLASS] = GEN8_VTCR, + [COPY_ENGINE_CLASS] = GEN8_BTCR, + }; + static const i915_reg_t gen12_regs[] = { + [RENDER_CLASS] = GEN12_GFX_TLB_INV_CR, + [VIDEO_DECODE_CLASS] = GEN12_VD_TLB_INV_CR, + [VIDEO_ENHANCEMENT_CLASS] = GEN12_VE_TLB_INV_CR, + [COPY_ENGINE_CLASS] = GEN12_BLT_TLB_INV_CR, + }; + struct drm_i915_private *i915 = gt->i915; + struct intel_uncore *uncore = gt->uncore; + struct intel_engine_cs *engine; + enum intel_engine_id id; + const i915_reg_t *regs; + unsigned int num = 0; + + if (I915_SELFTEST_ONLY(gt->awake == -ENODEV)) + return; + + if (INTEL_GEN(i915) == 12) { + regs = gen12_regs; + num = ARRAY_SIZE(gen12_regs); + } else if (INTEL_GEN(i915) >= 8 && INTEL_GEN(i915) <= 11) { + regs = gen8_regs; + num = ARRAY_SIZE(gen8_regs); + } else if (INTEL_GEN(i915) < 8) { + return; + } + + if (WARN_ONCE(!num, "Platform does not implement TLB invalidation!")) + return; + + GEM_TRACE("\n"); + + assert_rpm_wakelock_held(&i915->runtime_pm); + + mutex_lock(>->tlb_invalidate_lock); + intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); + + spin_lock_irq(&uncore->lock); /* serialise invalidate with GT reset */ + + for_each_engine(engine, gt, id) { + struct reg_and_bit rb; + + rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); + if (!i915_mmio_reg_offset(rb.reg)) + continue; + + if (INTEL_GEN(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS || + engine->class == VIDEO_ENHANCEMENT_CLASS)) + rb.bit = _MASKED_BIT_ENABLE(rb.bit); + + intel_uncore_write_fw(uncore, rb.reg, rb.bit); + } + + spin_unlock_irq(&uncore->lock); + + for_each_engine(engine, gt, id) { + /* + * HW architecture suggest typical invalidation time at 40us, + * with pessimistic cases up to 100us and a recommendation to + * cap at 1ms. We go a bit higher just in case. + */ + const unsigned int timeout_us = 100; + const unsigned int timeout_ms = 4; + struct reg_and_bit rb; + + rb = get_reg_and_bit(engine, regs == gen8_regs, regs, num); + if (!i915_mmio_reg_offset(rb.reg)) + continue; + + if (__intel_wait_for_register_fw(uncore, + rb.reg, rb.bit, 0, + timeout_us, timeout_ms, + NULL)) + DRM_ERROR_RATELIMITED("%s TLB invalidation did not complete in %ums!\n", + engine->name, timeout_ms); + } + + intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL); + mutex_unlock(>->tlb_invalidate_lock); +} --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_gt.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_gt.h @@ -57,4 +57,6 @@ void intel_gt_queue_hangcheck(struct intel_gt *gt); +void intel_gt_invalidate_tlbs(struct intel_gt *gt); + #endif /* __INTEL_GT_H__ */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_gt_requests.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_gt_requests.c @@ -0,0 +1,98 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#include + +#include "i915_drv.h" /* for_each_engine() */ +#include "i915_request.h" +#include "intel_gt.h" +#include "intel_gt_pm.h" +#include "intel_gt_requests.h" +#include "intel_timeline.h" + +static void retire_requests(struct intel_timeline *tl) +{ + struct i915_request *rq, *rn; + + list_for_each_entry_safe(rq, rn, &tl->requests, link) + if (!i915_request_retire(rq)) + break; +} + +static void engine_retire(struct work_struct *work) +{ + struct intel_engine_cs *engine = + container_of(work, typeof(*engine), retire_work); + struct intel_timeline *tl = xchg(&engine->retire, NULL); + + mutex_lock(&engine->i915->drm.struct_mutex); + do { + struct intel_timeline *next = xchg(&tl->retire, NULL); + + /* + * Our goal here is to retire _idle_ timelines as soon as + * possible (as they are idle, we do not expect userspace + * to be cleaning up anytime soon). + * + * If the timeline is currently locked, either it is being + * retired elsewhere or about to be! + */ + if (mutex_trylock(&tl->mutex)) { + retire_requests(tl); + mutex_unlock(&tl->mutex); + } + intel_timeline_put(tl); + + GEM_BUG_ON(!next); + tl = ptr_mask_bits(next, 1); + } while (tl); + mutex_unlock(&engine->i915->drm.struct_mutex); +} + +static bool add_retire(struct intel_engine_cs *engine, + struct intel_timeline *tl) +{ + struct intel_timeline *first; + + /* + * We open-code a llist here to include the additional tag [BIT(0)] + * so that we know when the timeline is already on a + * retirement queue: either this engine or another. + * + * However, we rely on that a timeline can only be active on a single + * engine at any one time and that add_retire() is called before the + * engine releases the timeline and transferred to another to retire. + */ + + if (READ_ONCE(tl->retire)) /* already queued */ + return false; + + intel_timeline_get(tl); + first = READ_ONCE(engine->retire); + do + tl->retire = ptr_pack_bits(first, 1, 1); + while (!try_cmpxchg(&engine->retire, &first, tl)); + + return !first; +} + +void intel_engine_add_retire(struct intel_engine_cs *engine, + struct intel_timeline *tl) +{ + if (add_retire(engine, tl)) + schedule_work(&engine->retire_work); +} + +void intel_engine_init_retire(struct intel_engine_cs *engine) +{ + INIT_WORK(&engine->retire_work, engine_retire); +} + +void intel_engine_fini_retire(struct intel_engine_cs *engine) +{ + flush_work(&engine->retire_work); + GEM_BUG_ON(engine->retire); +} --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_gt_requests.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_gt_requests.h @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2019 Intel Corporation + */ + +#ifndef INTEL_GT_REQUESTS_H +#define INTEL_GT_REQUESTS_H + +struct intel_engine_cs; +struct intel_timeline; + +void intel_engine_init_retire(struct intel_engine_cs *engine); +void intel_engine_add_retire(struct intel_engine_cs *engine, + struct intel_timeline *tl); +void intel_engine_fini_retire(struct intel_engine_cs *engine); + +#endif /* INTEL_GT_REQUESTS_H */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_gt_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_gt_types.h @@ -40,6 +40,8 @@ struct intel_uc uc; + struct mutex tlb_invalidate_lock; + struct intel_gt_timelines { spinlock_t lock; /* protects active_list */ struct list_head active_list; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_lrc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -142,6 +142,7 @@ #include "intel_engine_pm.h" #include "intel_gt.h" #include "intel_gt_pm.h" +#include "intel_gt_requests.h" #include "intel_lrc_reg.h" #include "intel_mocs.h" #include "intel_reset.h" @@ -471,17 +472,11 @@ return desc; } -static void unwind_wa_tail(struct i915_request *rq) -{ - rq->tail = intel_ring_wrap(rq->ring, rq->wa_tail - WA_TAIL_BYTES); - assert_ring_tail_valid(rq->ring, rq->tail); -} - static struct i915_request * __unwind_incomplete_requests(struct intel_engine_cs *engine) { struct i915_request *rq, *rn, *active = NULL; - struct list_head *uninitialized_var(pl); + struct list_head *pl; int prio = I915_PRIORITY_INVALID; lockdep_assert_held(&engine->active.lock); @@ -495,7 +490,6 @@ continue; /* XXX */ __i915_request_unsubmit(rq); - unwind_wa_tail(rq); /* * Push the request back into the queue for later resubmission. @@ -525,7 +519,8 @@ */ if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &rq->fence.flags)) { - spin_lock(&rq->lock); + spin_lock_nested(&rq->lock, + SINGLE_DEPTH_NESTING); i915_request_cancel_breadcrumb(rq); spin_unlock(&rq->lock); } @@ -612,6 +607,20 @@ { struct intel_context * const ce = rq->hw_context; + /* + * NB process_csb() is not under the engine->active.lock and hence + * schedule_out can race with schedule_in meaning that we should + * refrain from doing non-trivial work here. + */ + + /* + * If we have just completed this context, the engine may now be + * idle and we want to re-enter powersaving. + */ + if (list_is_last(&rq->link, &ce->timeline->requests) && + i915_request_completed(rq)) + intel_engine_add_retire(engine, ce->timeline); + intel_engine_context_out(engine); execlists_context_status_change(rq, INTEL_CONTEXT_SCHEDULE_OUT); intel_gt_pm_put(engine->gt); @@ -649,13 +658,35 @@ i915_request_put(rq); } -static u64 execlists_update_context(const struct i915_request *rq) +static u64 execlists_update_context(struct i915_request *rq) { struct intel_context *ce = rq->hw_context; - u64 desc; + u64 desc = ce->lrc_desc; + u32 tail, prev; - ce->lrc_reg_state[CTX_RING_TAIL + 1] = - intel_ring_set_tail(rq->ring, rq->tail); + /* + * WaIdleLiteRestore:bdw,skl + * + * We should never submit the context with the same RING_TAIL twice + * just in case we submit an empty ring, which confuses the HW. + * + * We append a couple of NOOPs (gen8_emit_wa_tail) after the end of + * the normal request to be able to always advance the RING_TAIL on + * subsequent resubmissions (for lite restore). Should that fail us, + * and we try and submit the same tail again, force the context + * reload. + * + * If we need to return to a preempted context, we need to skip the + * lite-restore and force it to reload the RING_TAIL. Otherwise, the + * HW has a tendency to ignore us rewinding the TAIL to the end of + * an earlier request. + */ + tail = intel_ring_set_tail(rq->ring, rq->tail); + prev = ce->lrc_reg_state[CTX_RING_TAIL + 1]; + if (unlikely(intel_ring_direction(rq->ring, tail, prev) <= 0)) + desc |= CTX_DESC_FORCE_RESTORE; + ce->lrc_reg_state[CTX_RING_TAIL + 1] = tail; + rq->tail = rq->wa_tail; /* * Make sure the context image is complete before we submit it to HW. @@ -674,7 +705,6 @@ */ mb(); - desc = ce->lrc_desc; ce->lrc_desc &= ~CTX_DESC_FORCE_RESTORE; return desc; @@ -918,6 +948,11 @@ return *last; } +#define for_each_waiter(p__, rq__) \ + list_for_each_entry_lockless(p__, \ + &(rq__)->sched.waiters_list, \ + wait_link) + static void defer_request(struct i915_request *rq, struct list_head * const pl) { LIST_HEAD(list); @@ -935,7 +970,7 @@ GEM_BUG_ON(i915_request_is_active(rq)); list_move_tail(&rq->sched.link, pl); - list_for_each_entry(p, &rq->sched.waiters_list, wait_link) { + for_each_waiter(p, rq) { struct i915_request *w = container_of(p->waiter, typeof(*w), sched); @@ -1101,14 +1136,6 @@ */ __unwind_incomplete_requests(engine); - /* - * If we need to return to the preempted context, we - * need to skip the lite-restore and force it to - * reload the RING_TAIL. Otherwise, the HW has a - * tendency to ignore us rewinding the TAIL to the - * end of an earlier request. - */ - last->hw_context->lrc_desc |= CTX_DESC_FORCE_RESTORE; last = NULL; } else if (need_timeslice(engine, last) && !timer_pending(&engine->execlists.timer)) { @@ -1149,16 +1176,6 @@ if (!list_is_last(&last->sched.link, &engine->active.requests)) return; - - /* - * WaIdleLiteRestore:bdw,skl - * Apply the wa NOOPs to prevent - * ring:HEAD == rq:TAIL as we resubmit the - * request. See gen8_emit_fini_breadcrumb() for - * where we prepare the padding after the - * end of the request. - */ - last->tail = last->wa_tail; } } @@ -1572,6 +1589,9 @@ if (!inject_preempt_hang(execlists)) ring_set_paused(engine, 0); + /* XXX Magic delay for tgl */ + ENGINE_POSTING_READ(engine, RING_CONTEXT_STATUS_PTR); + WRITE_ONCE(execlists->pending[0], NULL); break; @@ -2131,6 +2151,14 @@ /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */ batch = gen8_emit_flush_coherentl3_wa(engine, batch); + /* WaClearSlmSpaceAtContextSwitch:skl,bxt,kbl,glk,cfl */ + batch = gen8_emit_pipe_control(batch, + PIPE_CONTROL_FLUSH_L3 | + PIPE_CONTROL_GLOBAL_GTT_IVB | + PIPE_CONTROL_CS_STALL | + PIPE_CONTROL_QW_WRITE, + slm_offset(engine)); + batch = emit_lri(batch, lri, ARRAY_SIZE(lri)); /* WaMediaPoolStateCmdInWABB:bxt,glk */ @@ -2232,6 +2260,9 @@ static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine) { i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); + + /* Called on error unwind, clear all flags to prevent further use */ + memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx)); } typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); @@ -2976,6 +3007,9 @@ static void execlists_park(struct intel_engine_cs *engine) { del_timer(&engine->execlists.timer); + + /* Reset upon idling, or we may delay the busy wakeup. */ + WRITE_ONCE(engine->execlists.queue_priority_hint, INT_MIN); } void intel_execlists_set_default_submission(struct intel_engine_cs *engine) @@ -3715,9 +3749,11 @@ ve->base.i915 = ctx->i915; ve->base.gt = siblings[0]->gt; ve->base.id = -1; + ve->base.class = OTHER_CLASS; ve->base.uabi_class = I915_ENGINE_CLASS_INVALID; ve->base.instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; + ve->base.uabi_instance = I915_ENGINE_CLASS_INVALID_VIRTUAL; /* * The decision on whether to submit a request using semaphores @@ -3739,6 +3775,7 @@ intel_engine_init_active(&ve->base, ENGINE_VIRTUAL); intel_engine_init_execlists(&ve->base); + ve->base.breadcrumbs.irq_armed = true; /* fake HW, used for irq_work */ ve->base.cops = &virtual_context_ops; ve->base.request_alloc = execlists_request_alloc; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_mocs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -130,7 +130,19 @@ GEN9_MOCS_ENTRIES, MOCS_ENTRY(I915_MOCS_CACHED, LE_3_WB | LE_TC_2_LLC_ELLC | LE_LRUM(3), - L3_3_WB) + L3_3_WB), + + /* + * mocs:63 + * - used by the L3 for all of its evictions. + * Thus it is expected to allow LLC cacheability to enable coherent + * flows to be maintained. + * - used to force L3 uncachable cycles. + * Thus it is expected to make the surface L3 uncacheable. + */ + MOCS_ENTRY(63, + LE_3_WB | LE_TC_1_LLC | LE_LRUM(3), + L3_1_UC) }; /* NOTE: the LE_TGT_CACHE is not used on Broxton */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_reset.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_reset.c @@ -257,6 +257,7 @@ static int gen6_hw_domain_reset(struct intel_gt *gt, u32 hw_domain_mask) { struct intel_uncore *uncore = gt->uncore; + int loops = 2; int err; /* @@ -264,17 +265,38 @@ * for fifo space for the write or forcewake the chip for * the read */ - intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask); + do { + intel_uncore_write_fw(uncore, GEN6_GDRST, hw_domain_mask); - /* Wait for the device to ack the reset requests */ - err = __intel_wait_for_register_fw(uncore, - GEN6_GDRST, hw_domain_mask, 0, - 500, 0, - NULL); + /* + * Wait for the device to ack the reset requests. + * + * On some platforms, e.g. Jasperlake, we see that the + * engine register state is not cleared until shortly after + * GDRST reports completion, causing a failure as we try + * to immediately resume while the internal state is still + * in flux. If we immediately repeat the reset, the second + * reset appears to serialise with the first, and since + * it is a no-op, the registers should retain their reset + * value. However, there is still a concern that upon + * leaving the second reset, the internal engine state + * is still in flux and not ready for resuming. + */ + err = __intel_wait_for_register_fw(uncore, GEN6_GDRST, + hw_domain_mask, 0, + 2000, 0, + NULL); + } while (err == 0 && --loops); if (err) DRM_DEBUG_DRIVER("Wait for 0x%08x engines reset failed\n", hw_domain_mask); + /* + * As we have observed that the engine state is still volatile + * after GDRST is acked, impose a small delay to let everything settle. + */ + udelay(50); + return err; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_ringbuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_ringbuffer.c @@ -1208,7 +1208,7 @@ if (unlikely(ret)) goto err_unpin; - if (i915_vma_is_map_and_fenceable(vma)) + if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915)) addr = (void __force *)i915_vma_pin_iomap(vma); else addr = i915_gem_object_pin_map(vma->obj, @@ -1220,9 +1220,10 @@ i915_vma_make_unshrinkable(vma); - GEM_BUG_ON(ring->vaddr); - ring->vaddr = addr; + /* Discard any unused bytes beyond that submitted to hw. */ + intel_ring_reset(ring, ring->emit); + ring->vaddr = addr; return 0; err_ring: @@ -1248,30 +1249,25 @@ if (!atomic_dec_and_test(&ring->pin_count)) return; - /* Discard any unused bytes beyond that submitted to hw. */ - intel_ring_reset(ring, ring->emit); - i915_vma_unset_ggtt_write(vma); - if (i915_vma_is_map_and_fenceable(vma)) + if (i915_vma_is_map_and_fenceable(vma) && !HAS_LLC(vma->vm->i915)) i915_vma_unpin_iomap(vma); else i915_gem_object_unpin_map(vma->obj); - GEM_BUG_ON(!ring->vaddr); - ring->vaddr = NULL; - - i915_vma_unpin(vma); i915_vma_make_purgeable(vma); + i915_vma_unpin(vma); } static struct i915_vma *create_ring_vma(struct i915_ggtt *ggtt, int size) { struct i915_address_space *vm = &ggtt->vm; struct drm_i915_private *i915 = vm->i915; - struct drm_i915_gem_object *obj; + struct drm_i915_gem_object *obj = NULL; struct i915_vma *vma; - obj = i915_gem_object_create_stolen(i915, size); + if (!HAS_LLC(i915)) + obj = i915_gem_object_create_stolen(i915, size); if (!obj) obj = i915_gem_object_create_internal(i915, size); if (IS_ERR(obj)) @@ -1310,8 +1306,9 @@ return ERR_PTR(-ENOMEM); kref_init(&ring->ref); - ring->size = size; + ring->wrap = BITS_PER_TYPE(ring->size) - ilog2(size); + /* Workaround an erratum on the i830 which causes a hang if * the TAIL pointer points to within the last 2 cachelines * of the buffer. --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_timeline.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -282,6 +282,7 @@ { GEM_BUG_ON(atomic_read(&timeline->pin_count)); GEM_BUG_ON(!list_empty(&timeline->requests)); + GEM_BUG_ON(timeline->retire); if (timeline->hwsp_cacheline) cacheline_free(timeline->hwsp_cacheline); @@ -289,6 +290,14 @@ i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); i915_vma_put(timeline->hwsp_ggtt); + + /* + * A small race exists between intel_gt_retire_requests_timeout and + * intel_timeline_exit which could result in the syncmap not getting + * free'd. Rather than work to hard to seal this race, simply cleanup + * the syncmap on fini. + */ + i915_syncmap_free(&timeline->sync); } struct intel_timeline * @@ -339,15 +348,33 @@ struct intel_gt_timelines *timelines = &tl->gt->timelines; unsigned long flags; + /* + * Pretend we are serialised by the timeline->mutex. + * + * While generally true, there are a few exceptions to the rule + * for the engine->kernel_context being used to manage power + * transitions. As the engine_park may be called from under any + * timeline, it uses the power mutex as a global serialisation + * lock to prevent any other request entering its timeline. + * + * The rule is generally tl->mutex, otherwise engine->wakeref.mutex. + * + * However, intel_gt_retire_request() does not know which engine + * it is retiring along and so cannot partake in the engine-pm + * barrier, and there we use the tl->active_count as a means to + * pin the timeline in the active_list while the locks are dropped. + * Ergo, as that is outside of the engine-pm barrier, we need to + * use atomic to manipulate tl->active_count. + */ lockdep_assert_held(&tl->mutex); - GEM_BUG_ON(!atomic_read(&tl->pin_count)); - if (tl->active_count++) + + if (atomic_add_unless(&tl->active_count, 1, 0)) return; - GEM_BUG_ON(!tl->active_count); /* overflow? */ spin_lock_irqsave(&timelines->lock, flags); - list_add(&tl->link, &timelines->active_list); + if (!atomic_fetch_inc(&tl->active_count)) + list_add_tail(&tl->link, &timelines->active_list); spin_unlock_irqrestore(&timelines->lock, flags); } @@ -356,14 +383,16 @@ struct intel_gt_timelines *timelines = &tl->gt->timelines; unsigned long flags; + /* See intel_timeline_enter() */ lockdep_assert_held(&tl->mutex); - GEM_BUG_ON(!tl->active_count); - if (--tl->active_count) + GEM_BUG_ON(!atomic_read(&tl->active_count)); + if (atomic_add_unless(&tl->active_count, -1, 1)) return; spin_lock_irqsave(&timelines->lock, flags); - list_del(&tl->link); + if (atomic_dec_and_test(&tl->active_count)) + list_del(&tl->link); spin_unlock_irqrestore(&timelines->lock, flags); /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gt/intel_timeline_types.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gt/intel_timeline_types.h @@ -42,7 +42,7 @@ * from the intel_context caller plus internal atomicity. */ atomic_t pin_count; - unsigned int active_count; + atomic_t active_count; const u32 *hwsp_seqno; struct i915_vma *hwsp_ggtt; @@ -65,6 +65,9 @@ */ struct i915_active_request last_request; + /** A chain of completed timelines ready for early retirement. */ + struct intel_timeline *retire; + /** * We track the most recent seqno that we wait on in every context so * that we only have to emit a new await and dependency on a more --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -963,18 +963,6 @@ int i, ret = 0; int cmd_len = cmd_length(s); struct intel_gvt *gvt = s->vgpu->gvt; - u32 valid_len = CMD_LEN(1); - - /* - * Official intel docs are somewhat sloppy , check the definition of - * MI_LOAD_REGISTER_IMM. - */ - #define MAX_VALID_LEN 127 - if ((cmd_len < valid_len) || (cmd_len > MAX_VALID_LEN)) { - gvt_err("len is not valid: len=%u valid_len=%u\n", - cmd_len, valid_len); - return -EFAULT; - } for (i = 1; i < cmd_len; i += 2) { if (IS_BROADWELL(gvt->dev_priv) && s->ring_id != RCS0) { @@ -1597,9 +1585,9 @@ if (!(cmd_val(s, 0) & (1 << 22))) return ret; - /* check if QWORD */ - if (DWORD_FIELD(0, 20, 19) == 1) - valid_len += 8; + /* check inline data */ + if (cmd_val(s, 0) & BIT(18)) + valid_len = CMD_LEN(9); ret = gvt_check_valid_cmd_length(cmd_length(s), valid_len); if (ret) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/display.c @@ -172,21 +172,176 @@ int pipe; if (IS_BROXTON(dev_priv)) { + enum transcoder trans; + enum port port; + + /* Clear PIPE, DDI, PHY, HPD before setting new */ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~(BXT_DE_PORT_HP_DDIA | BXT_DE_PORT_HP_DDIB | BXT_DE_PORT_HP_DDIC); + for_each_pipe(dev_priv, pipe) { + vgpu_vreg_t(vgpu, PIPECONF(pipe)) &= + ~(PIPECONF_ENABLE | I965_PIPECONF_ACTIVE); + vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE; + vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE; + vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE; + vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE; + } + + for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) { + vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &= + ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | + TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE); + } + vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= + ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | + TRANS_DDI_PORT_MASK); + + for (port = PORT_A; port <= PORT_C; port++) { + vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &= + ~BXT_PHY_LANE_ENABLED; + vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |= + (BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK); + + vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &= + ~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE | + PORT_PLL_REF_SEL | PORT_PLL_LOCK | + PORT_PLL_ENABLE); + + vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &= + ~(DDI_INIT_DISPLAY_DETECTED | + DDI_BUF_CTL_ENABLE); + vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE; + } + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK); + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK); + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK); + /* No hpd_invert set in vgpu vbt, need to clear invert mask */ + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK; + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK; + + vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1)); + vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &= + ~PHY_POWER_GOOD; + vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &= + ~PHY_POWER_GOOD; + vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30); + vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30); + + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED; + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED; + + /* + * Only 1 PIPE enabled in current vGPU display and PIPE_A is + * tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A, + * TRANSCODER_A can be enabled. PORT_x depends on the input of + * setup_virtual_dp_monitor. + */ + vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE; + vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= I965_PIPECONF_ACTIVE; + + /* + * Golden M/N are calculated based on: + * 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID), + * DP link clk 1620 MHz and non-constant_n. + * TODO: calculate DP link symbol clk and stream clk m/n. + */ + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT; + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e; + vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000; + vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e; + vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000; + + /* Enable per-DDI/PORT vreg */ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { + vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1); + vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |= + PHY_POWER_GOOD; + vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |= + BIT(30); + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |= + BXT_PHY_LANE_ENABLED; + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &= + ~(BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK); + vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |= + (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE | + PORT_PLL_REF_SEL | PORT_PLL_LOCK | + PORT_PLL_ENABLE); + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |= + (DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED); + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &= + ~DDI_BUF_IS_IDLE; + vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |= + (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | + TRANS_DDI_FUNC_ENABLE); + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTA_HOTPLUG_ENABLE; vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIA; } if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED; + vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0); + vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |= + PHY_POWER_GOOD; + vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |= + BIT(30); + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |= + BXT_PHY_LANE_ENABLED; + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &= + ~(BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK); + vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |= + (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE | + PORT_PLL_REF_SEL | PORT_PLL_LOCK | + PORT_PLL_ENABLE); + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |= + DDI_BUF_CTL_ENABLE; + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &= + ~DDI_BUF_IS_IDLE; + vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |= + (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | + (PORT_B << TRANS_DDI_PORT_SHIFT) | + TRANS_DDI_FUNC_ENABLE); + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTB_HOTPLUG_ENABLE; vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIB; } if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED; + vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0); + vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |= + PHY_POWER_GOOD; + vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |= + BIT(30); + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |= + BXT_PHY_LANE_ENABLED; + vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &= + ~(BXT_PHY_CMNLANE_POWERDOWN_ACK | + BXT_PHY_LANE_POWERDOWN_ACK); + vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |= + (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE | + PORT_PLL_REF_SEL | PORT_PLL_LOCK | + PORT_PLL_ENABLE); + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |= + DDI_BUF_CTL_ENABLE; + vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &= + ~DDI_BUF_IS_IDLE; + vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |= + (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST | + (PORT_B << TRANS_DDI_PORT_SHIFT) | + TRANS_DDI_FUNC_ENABLE); + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTC_HOTPLUG_ENABLE; vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIC; } @@ -207,14 +362,41 @@ SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | SKL_FUSE_PG_DIST_STATUS(SKL_PG2); - vgpu_vreg_t(vgpu, LCPLL1_CTL) |= - LCPLL_PLL_ENABLE | - LCPLL_PLL_LOCK; - vgpu_vreg_t(vgpu, LCPLL2_CTL) |= LCPLL_PLL_ENABLE; - + /* + * Only 1 PIPE enabled in current vGPU display and PIPE_A is + * tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A, + * TRANSCODER_A can be enabled. PORT_x depends on the input of + * setup_virtual_dp_monitor, we can bind DPLL0 to any PORT_x + * so we fixed to DPLL0 here. + * Setup DPLL0: DP link clk 1620 MHz, non SSC, DP Mode + */ + vgpu_vreg_t(vgpu, DPLL_CTRL1) = + DPLL_CTRL1_OVERRIDE(DPLL_ID_SKL_DPLL0); + vgpu_vreg_t(vgpu, DPLL_CTRL1) |= + DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1620, DPLL_ID_SKL_DPLL0); + vgpu_vreg_t(vgpu, LCPLL1_CTL) = + LCPLL_PLL_ENABLE | LCPLL_PLL_LOCK; + vgpu_vreg_t(vgpu, DPLL_STATUS) = DPLL_LOCK(DPLL_ID_SKL_DPLL0); + /* + * Golden M/N are calculated based on: + * 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID), + * DP link clk 1620 MHz and non-constant_n. + * TODO: calculate DP link symbol clk and stream clk m/n. + */ + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT; + vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e; + vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000; + vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e; + vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000; } if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_B); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_B); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_B); vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED; vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | @@ -235,6 +417,12 @@ } if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_C); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_C); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_C); vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT; vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | @@ -255,6 +443,12 @@ } if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) { + vgpu_vreg_t(vgpu, DPLL_CTRL2) &= + ~DPLL_CTRL2_DDI_CLK_OFF(PORT_D); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_CLK_SEL(DPLL_ID_SKL_DPLL0, PORT_D); + vgpu_vreg_t(vgpu, DPLL_CTRL2) |= + DPLL_CTRL2_DDI_SEL_OVERRIDE(PORT_D); vgpu_vreg_t(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT; vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &= ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK | @@ -457,7 +651,8 @@ struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; /* TODO: add more platforms support */ - if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || + IS_COFFEELAKE(dev_priv)) { if (connected) { vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED; @@ -471,6 +666,63 @@ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= PORTD_HOTPLUG_STATUS_MASK; intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG); + } else if (IS_BROXTON(dev_priv)) { + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) { + if (connected) { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= + BXT_DE_PORT_HP_DDIA; + } else { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= + ~BXT_DE_PORT_HP_DDIA; + } + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= + BXT_DE_PORT_HP_DDIA; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~PORTA_HOTPLUG_STATUS_MASK; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTA_HOTPLUG_LONG_DETECT; + intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG); + } + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) { + if (connected) { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= + BXT_DE_PORT_HP_DDIB; + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= + SFUSE_STRAP_DDIB_DETECTED; + } else { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= + ~BXT_DE_PORT_HP_DDIB; + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= + ~SFUSE_STRAP_DDIB_DETECTED; + } + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= + BXT_DE_PORT_HP_DDIB; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~PORTB_HOTPLUG_STATUS_MASK; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTB_HOTPLUG_LONG_DETECT; + intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG); + } + if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) { + if (connected) { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= + BXT_DE_PORT_HP_DDIC; + vgpu_vreg_t(vgpu, SFUSE_STRAP) |= + SFUSE_STRAP_DDIC_DETECTED; + } else { + vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= + ~BXT_DE_PORT_HP_DDIC; + vgpu_vreg_t(vgpu, SFUSE_STRAP) &= + ~SFUSE_STRAP_DDIC_DETECTED; + } + vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |= + BXT_DE_PORT_HP_DDIC; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= + ~PORTC_HOTPLUG_STATUS_MASK; + vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |= + PORTC_HOTPLUG_LONG_DETECT; + intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG); + } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/dmabuf.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -96,12 +96,12 @@ dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj, list); if (dmabuf_obj == obj) { + list_del(pos); intel_gvt_hypervisor_put_vfio_device(vgpu); idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id); kfree(dmabuf_obj->info); kfree(dmabuf_obj); - list_del(pos); break; } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/gtt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/gtt.c @@ -1186,10 +1186,8 @@ for_each_shadow_entry(sub_spt, &sub_se, sub_index) { ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, start_gfn + sub_index, PAGE_SIZE, &dma_addr); - if (ret) { - ppgtt_invalidate_spt(spt); - return ret; - } + if (ret) + goto err; sub_se.val64 = se->val64; /* Copy the PAT field from PDE. */ @@ -1208,6 +1206,17 @@ ops->set_pfn(se, sub_spt->shadow_page.mfn); ppgtt_set_shadow_entry(spt, se, index); return 0; +err: + /* Cancel the existing addess mappings of DMA addr. */ + for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) { + gvt_vdbg_mm("invalidate 4K entry\n"); + ppgtt_invalidate_pte(sub_spt, &sub_se); + } + /* Release the new allocated spt. */ + trace_spt_change(sub_spt->vgpu->id, "release", sub_spt, + sub_spt->guest_page.gfn, sub_spt->shadow_page.type); + ppgtt_free_spt(sub_spt); + return ret; } static int split_64KB_gtt_entry(struct intel_vgpu *vgpu, @@ -1956,7 +1965,11 @@ if (mm->type == INTEL_GVT_MM_PPGTT) { list_del(&mm->ppgtt_mm.list); + + mutex_lock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock); list_del(&mm->ppgtt_mm.lru_list); + mutex_unlock(&mm->vgpu->gvt->gtt.ppgtt_mm_lock); + invalidate_ppgtt_mm(mm); } else { vfree(mm->ggtt_mm.virtual_ggtt); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/gvt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/gvt.c @@ -128,7 +128,7 @@ return true; } -static bool intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt) +static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt) { int i, j; struct intel_vgpu_type *type; @@ -146,7 +146,7 @@ gvt_vgpu_type_groups[i] = group; } - return true; + return 0; unwind: for (j = 0; j < i; j++) { @@ -154,7 +154,7 @@ kfree(group); } - return false; + return -ENOMEM; } static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt) @@ -362,7 +362,7 @@ goto out_clean_thread; ret = intel_gvt_init_vgpu_type_groups(gvt); - if (ret == false) { + if (ret) { gvt_err("failed to init vgpu type groups: %d\n", ret); goto out_clean_types; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/handlers.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/handlers.c @@ -654,7 +654,7 @@ else if (FDI_RX_IMR_TO_PIPE(offset) != INVALID_INDEX) index = FDI_RX_IMR_TO_PIPE(offset); else { - gvt_vgpu_err("Unsupport registers %x\n", offset); + gvt_vgpu_err("Unsupported registers %x\n", offset); return -EINVAL; } @@ -1632,6 +1632,34 @@ return 0; } +/** + * FixMe: + * If guest fills non-priv batch buffer on ApolloLake/Broxton as Mesa i965 did: + * 717e7539124d (i965: Use a WC map and memcpy for the batch instead of pwrite.) + * Due to the missing flush of bb filled by VM vCPU, host GPU hangs on executing + * these MI_BATCH_BUFFER. + * Temporarily workaround this by setting SNOOP bit for PAT3 used by PPGTT + * PML4 PTE: PAT(0) PCD(1) PWT(1). + * The performance is still expected to be low, will need further improvement. + */ +static int bxt_ppat_low_write(struct intel_vgpu *vgpu, unsigned int offset, + void *p_data, unsigned int bytes) +{ + u64 pat = + GEN8_PPAT(0, CHV_PPAT_SNOOP) | + GEN8_PPAT(1, 0) | + GEN8_PPAT(2, 0) | + GEN8_PPAT(3, CHV_PPAT_SNOOP) | + GEN8_PPAT(4, CHV_PPAT_SNOOP) | + GEN8_PPAT(5, CHV_PPAT_SNOOP) | + GEN8_PPAT(6, CHV_PPAT_SNOOP) | + GEN8_PPAT(7, CHV_PPAT_SNOOP); + + vgpu_vreg(vgpu, offset) = lower_32_bits(pat); + + return 0; +} + static int mmio_read_from_hw(struct intel_vgpu *vgpu, unsigned int offset, void *p_data, unsigned int bytes) { @@ -2778,7 +2806,7 @@ MMIO_DH(GEN6_PCODE_MAILBOX, D_BDW_PLUS, NULL, mailbox_write); - MMIO_D(GEN8_PRIVATE_PAT_LO, D_BDW_PLUS); + MMIO_D(GEN8_PRIVATE_PAT_LO, D_BDW_PLUS & ~D_BXT); MMIO_D(GEN8_PRIVATE_PAT_HI, D_BDW_PLUS); MMIO_D(GAMTARBMODE, D_BDW_PLUS); @@ -3103,8 +3131,8 @@ MMIO_DFH(GEN9_WM_CHICKEN3, D_SKL_PLUS, F_MODE_MASK | F_CMD_ACCESS, NULL, NULL); - MMIO_D(GAMT_CHKN_BIT_REG, D_KBL); - MMIO_D(GEN9_CTX_PREEMPT_REG, D_KBL | D_SKL); + MMIO_D(GAMT_CHKN_BIT_REG, D_KBL | D_CFL); + MMIO_D(GEN9_CTX_PREEMPT_REG, D_SKL_PLUS & ~D_BXT); return 0; } @@ -3278,9 +3306,17 @@ MMIO_D(GEN8_PUSHBUS_SHIFT, D_BXT); MMIO_D(GEN6_GFXPAUSE, D_BXT); MMIO_DFH(GEN8_L3SQCREG1, D_BXT, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(GEN8_L3CNTLREG, D_BXT, F_CMD_ACCESS, NULL, NULL); + MMIO_DFH(_MMIO(0x20D8), D_BXT, F_CMD_ACCESS, NULL, NULL); + MMIO_F(HSW_CS_GPR(0), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL); + MMIO_F(_MMIO(0x12600), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL); + MMIO_F(BCS_GPR(0), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL); + MMIO_F(_MMIO(0x1a600), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL); MMIO_DFH(GEN9_CTX_PREEMPT_REG, D_BXT, F_CMD_ACCESS, NULL, NULL); + MMIO_DH(GEN8_PRIVATE_PAT_LO, D_BXT, NULL, bxt_ppat_low_write); + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/mmio.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/mmio.c @@ -271,6 +271,11 @@ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |= BXT_PHY_CMNLANE_POWERDOWN_ACK | BXT_PHY_LANE_POWERDOWN_ACK; + vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |= + SKL_FUSE_DOWNLOAD_STATUS | + SKL_FUSE_PG_DIST_STATUS(SKL_PG0) | + SKL_FUSE_PG_DIST_STATUS(SKL_PG1) | + SKL_FUSE_PG_DIST_STATUS(SKL_PG2); } } else { #define GVT_GEN8_MMIO_RESET_OFFSET (0x44200) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/scheduler.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/scheduler.c @@ -374,7 +374,11 @@ for (i = 0; i < GVT_RING_CTX_NR_PDPS; i++) { struct i915_page_directory * const pd = i915_pd_entry(ppgtt->pd, i); - + /* skip now as current i915 ppgtt alloc won't allocate + top level pdp for non 4-level table, won't impact + shadow ppgtt. */ + if (!pd) + break; px_dma(pd) = mm->ppgtt_mm.shadow_pdps[i]; } } @@ -628,6 +632,7 @@ if (workload->shadow_mm->type != INTEL_GVT_MM_PPGTT || !workload->shadow_mm->ppgtt_mm.shadowed) { + intel_vgpu_unpin_mm(workload->shadow_mm); gvt_vgpu_err("workload shadow ppgtt isn't ready\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/gvt/vgpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/gvt/vgpu.c @@ -272,10 +272,17 @@ { struct intel_gvt *gvt = vgpu->gvt; - mutex_lock(&vgpu->vgpu_lock); - WARN(vgpu->active, "vGPU is still active!\n"); + /* + * remove idr first so later clean can judge if need to stop + * service if no active vgpu. + */ + mutex_lock(&gvt->lock); + idr_remove(&gvt->vgpu_idr, vgpu->id); + mutex_unlock(&gvt->lock); + + mutex_lock(&vgpu->vgpu_lock); intel_gvt_debugfs_remove_vgpu(vgpu); intel_vgpu_clean_sched_policy(vgpu); intel_vgpu_clean_submission(vgpu); @@ -290,7 +297,6 @@ mutex_unlock(&vgpu->vgpu_lock); mutex_lock(&gvt->lock); - idr_remove(&gvt->vgpu_idr, vgpu->id); if (idr_is_empty(&gvt->vgpu_idr)) intel_gvt_clean_irq(gvt); intel_gvt_update_vgpu_types(gvt); @@ -426,8 +432,9 @@ if (ret) goto out_clean_sched_policy; - /*TODO: add more platforms support */ - if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv)) + if (IS_BROADWELL(gvt->dev_priv) || IS_BROXTON(gvt->dev_priv)) + ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B); + else ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D); if (ret) goto out_clean_sched_policy; @@ -560,9 +567,9 @@ intel_vgpu_reset_mmio(vgpu, dmlr); populate_pvinfo_page(vgpu); - intel_vgpu_reset_display(vgpu); if (dmlr) { + intel_vgpu_reset_display(vgpu); intel_vgpu_reset_cfg_space(vgpu); /* only reset the failsafe mode when dmlr reset */ vgpu->failsafe = false; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_active.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_active.c @@ -121,7 +121,7 @@ #endif static void -__active_retire(struct i915_active *ref) +__active_retire(struct i915_active *ref, bool lock) { struct active_node *it, *n; struct rb_root root; @@ -138,7 +138,8 @@ retire = true; } - mutex_unlock(&ref->mutex); + if (likely(lock)) + mutex_unlock(&ref->mutex); if (!retire) return; @@ -153,21 +154,28 @@ } static void -active_retire(struct i915_active *ref) +active_retire(struct i915_active *ref, bool lock) { GEM_BUG_ON(!atomic_read(&ref->count)); if (atomic_add_unless(&ref->count, -1, 1)) return; /* One active may be flushed from inside the acquire of another */ - mutex_lock_nested(&ref->mutex, SINGLE_DEPTH_NESTING); - __active_retire(ref); + if (likely(lock)) + mutex_lock_nested(&ref->mutex, SINGLE_DEPTH_NESTING); + __active_retire(ref, lock); } static void node_retire(struct i915_active_request *base, struct i915_request *rq) { - active_retire(node_from_active(base)->ref); + active_retire(node_from_active(base)->ref, true); +} + +static void +node_retire_nolock(struct i915_active_request *base, struct i915_request *rq) +{ + active_retire(node_from_active(base)->ref, false); } static struct i915_active_request * @@ -364,7 +372,7 @@ void i915_active_release(struct i915_active *ref) { debug_active_assert(ref); - active_retire(ref); + active_retire(ref, true); } static void __active_ungrab(struct i915_active *ref) @@ -391,7 +399,7 @@ { GEM_BUG_ON(!test_bit(I915_ACTIVE_GRAB_BIT, &ref->flags)); - active_retire(ref); + active_retire(ref, true); __active_ungrab(ref); } @@ -421,12 +429,13 @@ break; } - err = i915_active_request_retire(&it->base, BKL(ref)); + err = i915_active_request_retire(&it->base, BKL(ref), + node_retire_nolock); if (err) break; } - __active_retire(ref); + __active_retire(ref, true); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_active.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_active.h @@ -309,7 +309,7 @@ */ static inline int __must_check i915_active_request_retire(struct i915_active_request *active, - struct mutex *mutex) + struct mutex *mutex, i915_active_retire_fn retire) { struct i915_request *request; long ret; @@ -327,7 +327,7 @@ list_del_init(&active->link); RCU_INIT_POINTER(active->request, NULL); - active->retire(active, request); + retire(active, request); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_cmd_parser.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -572,6 +572,9 @@ #define REG32(_reg, ...) \ { .addr = (_reg), __VA_ARGS__ } +#define REG32_IDX(_reg, idx) \ + { .addr = _reg(idx) } + /* * Convenience macro for adding 64-bit registers. * @@ -669,6 +672,7 @@ REG64_IDX(RING_TIMESTAMP, BSD_RING_BASE), REG32(BCS_SWCTRL), REG64_IDX(RING_TIMESTAMP, BLT_RING_BASE), + REG32_IDX(RING_CTX_TIMESTAMP, BLT_RING_BASE), REG64_IDX(BCS_GPR, 0), REG64_IDX(BCS_GPR, 1), REG64_IDX(BCS_GPR, 2), @@ -1203,6 +1207,12 @@ return dst; } +static inline bool cmd_desc_is(const struct drm_i915_cmd_descriptor * const desc, + const u32 cmd) +{ + return desc->cmd.value == (cmd & desc->cmd.mask); +} + static bool check_cmd(const struct intel_engine_cs *engine, const struct drm_i915_cmd_descriptor *desc, const u32 *cmd, u32 length) @@ -1241,19 +1251,19 @@ * allowed mask/value pair given in the whitelist entry. */ if (reg->mask) { - if (desc->cmd.value == MI_LOAD_REGISTER_MEM) { + if (cmd_desc_is(desc, MI_LOAD_REGISTER_MEM)) { DRM_DEBUG_DRIVER("CMD: Rejected LRM to masked register 0x%08X\n", reg_addr); return false; } - if (desc->cmd.value == MI_LOAD_REGISTER_REG) { + if (cmd_desc_is(desc, MI_LOAD_REGISTER_REG)) { DRM_DEBUG_DRIVER("CMD: Rejected LRR to masked register 0x%08X\n", reg_addr); return false; } - if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) && + if (cmd_desc_is(desc, MI_LOAD_REGISTER_IMM(1)) && (offset + 2 > length || (cmd[offset + 1] & reg->mask) != reg->value)) { DRM_DEBUG_DRIVER("CMD: Rejected LRI to masked register 0x%08X\n", @@ -1484,7 +1494,7 @@ goto err; } - if (desc->cmd.value == MI_BATCH_BUFFER_START) { + if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) { ret = check_bbstart(ctx, cmd, offset, length, batch_len, batch_start, shadow_batch_start); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_debugfs.c @@ -2360,8 +2360,7 @@ for_each_power_domain(power_domain, power_well->desc->domains) seq_printf(m, " %-23s %d\n", - intel_display_power_domain_str(dev_priv, - power_domain), + intel_display_power_domain_str(power_domain), power_domains->domain_use_count[power_domain]); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_drv.h @@ -33,6 +33,8 @@ #include #include +#include + #include #include #include @@ -1740,6 +1742,9 @@ bool ipc_enabled; + /* Hack to bypass TMDS_OE write on DP->HDMI dongle */ + bool bypass_tmds_oe; + /* Used to save the pipe-to-encoder mapping for audio */ struct intel_encoder *av_enc_map[I915_MAX_PIPES]; @@ -1892,7 +1897,7 @@ { const unsigned int pi = __platform_mask_index(info, p); - return info->platform_mask[pi] & INTEL_SUBPLATFORM_BITS; + return info->platform_mask[pi] & ((1 << INTEL_SUBPLATFORM_BITS) - 1); } static __always_inline bool @@ -2197,7 +2202,9 @@ if (intel_iommu_gfx_mapped) return true; #endif - return false; + + /* Running as a guest, we assume the host is enforcing VT'd */ + return !hypervisor_is_type(X86_HYPER_NATIVE); } static inline bool intel_scanout_needs_vtd_wa(struct drm_i915_private *dev_priv) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_gem.c @@ -136,14 +136,14 @@ struct drm_i915_gem_pwrite *args, struct drm_file *file) { - void *vaddr = obj->phys_handle->vaddr + args->offset; + void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset; char __user *user_data = u64_to_user_ptr(args->data_ptr); /* * We manually control the domain here and pretend that it * remains coherent i.e. in the GTT domain, like shmem_pwrite. */ - intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); if (copy_from_user(vaddr, user_data, args->size)) return -EFAULT; @@ -151,7 +151,7 @@ drm_clflush_virt_range(vaddr, args->size); intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); return 0; } @@ -588,7 +588,7 @@ goto out_unpin; } - intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_invalidate_frontbuffer(obj, ORIGIN_CPU); user_data = u64_to_user_ptr(args->data_ptr); offset = args->offset; @@ -630,7 +630,7 @@ user_data += page_length; offset += page_length; } - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); i915_gem_object_unlock_fence(obj, fence); out_unpin: @@ -723,7 +723,7 @@ offset = 0; } - intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); + i915_gem_object_flush_frontbuffer(obj, ORIGIN_CPU); i915_gem_object_unlock_fence(obj, fence); return ret; @@ -802,10 +802,10 @@ ret = i915_gem_gtt_pwrite_fast(obj, args); if (ret == -EFAULT || ret == -ENOSPC) { - if (obj->phys_handle) - ret = i915_gem_phys_pwrite(obj, args, file); - else + if (i915_gem_object_has_struct_page(obj)) ret = i915_gem_shmem_pwrite(obj, args); + else + ret = i915_gem_phys_pwrite(obj, args, file); } i915_gem_object_unpin_pages(obj); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_gem_gtt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1178,6 +1178,7 @@ pd = i915_pd_entry(pdp, gen8_pd_index(idx, 2)); vaddr = kmap_atomic_px(i915_pt_entry(pd, gen8_pd_index(idx, 1))); do { + GEM_BUG_ON(iter->sg->length < I915_GTT_PAGE_SIZE); vaddr[gen8_pd_index(idx, 0)] = pte_encode | iter->dma; iter->dma += I915_GTT_PAGE_SIZE; @@ -1657,6 +1658,7 @@ vaddr = kmap_atomic_px(i915_pt_entry(pd, act_pt)); do { + GEM_BUG_ON(iter.sg->length < I915_GTT_PAGE_SIZE); vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma); iter.dma += I915_GTT_PAGE_SIZE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_gpu_error.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_gpu_error.c @@ -307,6 +307,8 @@ if (zlib_deflate(zstream, Z_NO_FLUSH) != Z_OK) return -EIO; + + cond_resched(); } while (zstream->avail_in); /* Fallback to uncompressed if we increase size? */ @@ -392,6 +394,7 @@ if (!i915_memcpy_from_wc(ptr, src, PAGE_SIZE)) memcpy(ptr, src, PAGE_SIZE); dst->pages[dst->page_count++] = ptr; + cond_resched(); return 0; } @@ -1768,7 +1771,8 @@ if (!xchg(&warned, true) && ktime_get_real_seconds() - DRIVER_TIMESTAMP < DAY_AS_SECONDS(180)) { pr_info("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); - pr_info("Please file a _new_ bug report on bugs.freedesktop.org against DRI -> DRM/Intel\n"); + pr_info("Please file a _new_ bug report at https://gitlab.freedesktop.org/drm/intel/issues/new.\n"); + pr_info("Please see https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs for details.\n"); pr_info("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); pr_info("The GPU crash dump is required to analyze GPU hangs, so please always attach it.\n"); pr_info("GPU crash dump saved to /sys/class/drm/card%d/error\n", --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_irq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_irq.c @@ -3500,6 +3500,7 @@ val = I915_READ(GEN11_DE_HPD_IMR); val &= ~hotplug_irqs; + val |= ~enabled_irqs & hotplug_irqs; I915_WRITE(GEN11_DE_HPD_IMR, val); POSTING_READ(GEN11_DE_HPD_IMR); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_params.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_params.c @@ -84,8 +84,7 @@ i915_param_named_unsafe(enable_psr, int, 0600, "Enable PSR " - "(0=disabled, 1=enabled) " - "Default: -1 (use per-chip default)"); + "(-1=use per-chip default, 0=disabled [default], 1=enabled) "); i915_param_named_unsafe(force_probe, charp, 0400, "Force probe the driver for specified devices. " @@ -171,7 +170,7 @@ i915_param_named(enable_dpcd_backlight, int, 0600, "Enable support for DPCD backlight control" - "(-1=use per-VBT LFP backlight type setting, 0=disabled [default], 1=enabled)"); + "(-1=use per-VBT LFP backlight type setting [default], 0=disabled, 1=enabled)"); #if IS_ENABLED(CONFIG_DRM_I915_GVT) i915_param_named(enable_gvt, bool, 0400, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_params.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_params.h @@ -50,7 +50,7 @@ param(int, vbt_sdvo_panel_type, -1) \ param(int, enable_dc, -1) \ param(int, enable_fbc, -1) \ - param(int, enable_psr, -1) \ + param(int, enable_psr, 0) \ param(int, disable_power_well, -1) \ param(int, enable_ips, 1) \ param(int, invert_brightness, 0) \ @@ -64,7 +64,7 @@ param(int, reset, 2) \ param(unsigned int, inject_load_failure, 0) \ param(int, fastboot, -1) \ - param(int, enable_dpcd_backlight, 0) \ + param(int, enable_dpcd_backlight, -1) \ param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE) \ /* leave bools at the end to not create holes */ \ param(bool, alpha_support, IS_ENABLED(CONFIG_DRM_I915_ALPHA_SUPPORT)) \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_pci.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_pci.c @@ -418,7 +418,8 @@ .has_coherent_ggtt = true, \ .has_llc = 1, \ .has_rc6 = 1, \ - .has_rc6p = 1, \ + /* snb does support rc6p, but enabling it causes various issues */ \ + .has_rc6p = 0, \ .has_rps = true, \ .ppgtt_type = INTEL_PPGTT_FULL, \ .ppgtt_size = 31, \ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_perf.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_perf.c @@ -2313,49 +2313,6 @@ } /** - * i915_perf_read_locked - &i915_perf_stream_ops->read with error normalisation - * @stream: An i915 perf stream - * @file: An i915 perf stream file - * @buf: destination buffer given by userspace - * @count: the number of bytes userspace wants to read - * @ppos: (inout) file seek position (unused) - * - * Besides wrapping &i915_perf_stream_ops->read this provides a common place to - * ensure that if we've successfully copied any data then reporting that takes - * precedence over any internal error status, so the data isn't lost. - * - * For example ret will be -ENOSPC whenever there is more buffered data than - * can be copied to userspace, but that's only interesting if we weren't able - * to copy some data because it implies the userspace buffer is too small to - * receive a single record (and we never split records). - * - * Another case with ret == -EFAULT is more of a grey area since it would seem - * like bad form for userspace to ask us to overrun its buffer, but the user - * knows best: - * - * http://yarchive.net/comp/linux/partial_reads_writes.html - * - * Returns: The number of bytes copied or a negative error code on failure. - */ -static ssize_t i915_perf_read_locked(struct i915_perf_stream *stream, - struct file *file, - char __user *buf, - size_t count, - loff_t *ppos) -{ - /* Note we keep the offset (aka bytes read) separate from any - * error status so that the final check for whether we return - * the bytes read with a higher precedence than any error (see - * comment below) doesn't need to be handled/duplicated in - * stream->ops->read() implementations. - */ - size_t offset = 0; - int ret = stream->ops->read(stream, buf, count, &offset); - - return offset ?: (ret ?: -EAGAIN); -} - -/** * i915_perf_read - handles read() FOP for i915 perf stream FDs * @file: An i915 perf stream file * @buf: destination buffer given by userspace @@ -2380,7 +2337,8 @@ { struct i915_perf_stream *stream = file->private_data; struct drm_i915_private *dev_priv = stream->dev_priv; - ssize_t ret; + size_t offset = 0; + int ret; /* To ensure it's handled consistently we simply treat all reads of a * disabled stream as an error. In particular it might otherwise lead @@ -2403,13 +2361,12 @@ return ret; mutex_lock(&dev_priv->perf.lock); - ret = i915_perf_read_locked(stream, file, - buf, count, ppos); + ret = stream->ops->read(stream, buf, count, &offset); mutex_unlock(&dev_priv->perf.lock); - } while (ret == -EAGAIN); + } while (!offset && !ret); } else { mutex_lock(&dev_priv->perf.lock); - ret = i915_perf_read_locked(stream, file, buf, count, ppos); + ret = stream->ops->read(stream, buf, count, &offset); mutex_unlock(&dev_priv->perf.lock); } @@ -2420,15 +2377,15 @@ * and read() returning -EAGAIN. Clearing the oa.pollin state here * effectively ensures we back off until the next hrtimer callback * before reporting another EPOLLIN event. + * The exception to this is if ops->read() returned -ENOSPC which means + * that more OA data is available than could fit in the user provided + * buffer. In this case we want the next poll() call to not block. */ - if (ret >= 0 || ret == -EAGAIN) { - /* Maybe make ->pollin per-stream state if we support multiple - * concurrent streams in the future. - */ + if (ret != -ENOSPC) stream->pollin = false; - } - return ret; + /* Possible values for ret are 0, -EFAULT, -ENOSPC, -EIO, ... */ + return offset ?: (ret ?: -EAGAIN); } static enum hrtimer_restart oa_poll_check_timer_cb(struct hrtimer *hrtimer) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_reg.h @@ -2519,6 +2519,12 @@ #define GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING (1 << 28) #define GAMT_CHKN_DISABLE_I2M_CYCLE_ON_WR_PORT (1 << 24) +#define GEN8_RTCR _MMIO(0x4260) +#define GEN8_M1TCR _MMIO(0x4264) +#define GEN8_M2TCR _MMIO(0x4268) +#define GEN8_BTCR _MMIO(0x426c) +#define GEN8_VTCR _MMIO(0x4270) + #if 0 #define PRB0_TAIL _MMIO(0x2030) #define PRB0_HEAD _MMIO(0x2034) @@ -2602,6 +2608,11 @@ #define FAULT_VA_HIGH_BITS (0xf << 0) #define FAULT_GTT_SEL (1 << 4) +#define GEN12_GFX_TLB_INV_CR _MMIO(0xced8) +#define GEN12_VD_TLB_INV_CR _MMIO(0xcedc) +#define GEN12_VE_TLB_INV_CR _MMIO(0xcee0) +#define GEN12_BLT_TLB_INV_CR _MMIO(0xcee4) + #define FPGA_DBG _MMIO(0x42300) #define FPGA_DBG_RM_NOCLAIM (1 << 31) @@ -4049,7 +4060,13 @@ #define GWUNIT_CLKGATE_DIS (1 << 16) #define UNSLICE_UNIT_LEVEL_CLKGATE _MMIO(0x9434) -#define VFUNIT_CLKGATE_DIS (1 << 20) +#define VFUNIT_CLKGATE_DIS REG_BIT(20) +#define HSUNIT_CLKGATE_DIS REG_BIT(8) +#define VSUNIT_CLKGATE_DIS REG_BIT(3) + +#define UNSLICE_UNIT_LEVEL_CLKGATE2 _MMIO(0x94e4) +#define VSUNIT_CLKGATE_DIS_TGL REG_BIT(19) +#define PSDUNIT_CLKGATE_DIS REG_BIT(5) #define INF_UNIT_LEVEL_CLKGATE _MMIO(0x9560) #define CGPSF_CLKGATE_DIS (1 << 3) @@ -8832,8 +8849,13 @@ #define ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point) (((point) << 16) | (0x1 << 8)) #define GEN6_PCODE_READ_D_COMP 0x10 #define GEN6_PCODE_WRITE_D_COMP 0x11 +#define ICL_PCODE_EXIT_TCCOLD 0x12 #define HSW_PCODE_DE_WRITE_FREQ_REQ 0x17 #define DISPLAY_IPS_CONTROL 0x19 +#define TGL_PCODE_TCCOLD 0x26 +#define TGL_PCODE_EXIT_TCCOLD_DATA_L_EXIT_FAILED REG_BIT(0) +#define TGL_PCODE_EXIT_TCCOLD_DATA_H_BLOCK_REQ 0 +#define TGL_PCODE_EXIT_TCCOLD_DATA_H_UNBLOCK_REQ REG_BIT(0) /* See also IPS_CTL */ #define IPS_PCODE_CONTROL (1 << 30) #define HSW_PCODE_DYNAMIC_DUTY_CYCLE_CONTROL 0x1A @@ -9104,6 +9126,9 @@ #define HSW_AUD_CHICKENBIT _MMIO(0x65f10) #define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15) +#define AUD_PIN_BUF_CTL _MMIO(0x48414) +#define AUD_PIN_BUF_ENABLE REG_BIT(31) + /* * HSW - ICL power wells * --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_request.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_request.c @@ -215,7 +215,7 @@ spin_unlock(&locked->active.lock); } -static bool i915_request_retire(struct i915_request *rq) +bool i915_request_retire(struct i915_request *rq) { struct i915_active_request *active, *next; @@ -560,19 +560,31 @@ return NOTIFY_DONE; } +static void irq_semaphore_cb(struct irq_work *wrk) +{ + struct i915_request *rq = + container_of(wrk, typeof(*rq), semaphore_work); + + i915_schedule_bump_priority(rq, I915_PRIORITY_NOSEMAPHORE); + i915_request_put(rq); +} + static int __i915_sw_fence_call semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) { - struct i915_request *request = - container_of(fence, typeof(*request), semaphore); + struct i915_request *rq = container_of(fence, typeof(*rq), semaphore); switch (state) { case FENCE_COMPLETE: - i915_schedule_bump_priority(request, I915_PRIORITY_NOSEMAPHORE); + if (!(READ_ONCE(rq->sched.attr.priority) & I915_PRIORITY_NOSEMAPHORE)) { + i915_request_get(rq); + init_irq_work(&rq->semaphore_work, irq_semaphore_cb); + irq_work_queue(&rq->semaphore_work); + } break; case FENCE_FREE: - i915_request_put(request); + i915_request_put(rq); break; } @@ -882,8 +894,10 @@ GEM_BUG_ON(to == from); GEM_BUG_ON(to->timeline == from->timeline); - if (i915_request_completed(from)) + if (i915_request_completed(from)) { + i915_sw_fence_set_error_once(&to->submit, from->fence.error); return 0; + } if (to->engine->schedule) { ret = i915_sched_node_add_dependency(&to->sched, &from->sched); @@ -1215,9 +1229,9 @@ * decide whether to preempt the entire chain so that it is ready to * run at the earliest possible convenience. */ - i915_sw_fence_commit(&rq->semaphore); if (attr && rq->engine->schedule) rq->engine->schedule(rq, attr); + i915_sw_fence_commit(&rq->semaphore); i915_sw_fence_commit(&rq->submit); } @@ -1513,8 +1527,8 @@ continue; intel_timeline_get(tl); - GEM_BUG_ON(!tl->active_count); - tl->active_count++; /* pin the list element */ + GEM_BUG_ON(!atomic_read(&tl->active_count)); + atomic_inc(&tl->active_count); /* pin the list element */ spin_unlock_irqrestore(&timelines->lock, flags); retire_requests(tl); @@ -1523,14 +1537,14 @@ /* Resume iteration after dropping lock */ list_safe_reset_next(tl, tn, link); - if (!--tl->active_count) + if (atomic_dec_and_test(&tl->active_count)) list_del(&tl->link); mutex_unlock(&tl->mutex); /* Defer the final release to after the spinlock */ if (refcount_dec_and_test(&tl->kref.refcount)) { - GEM_BUG_ON(tl->active_count); + GEM_BUG_ON(atomic_read(&tl->active_count)); list_add(&tl->link, &free); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_request.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_request.h @@ -26,6 +26,7 @@ #define I915_REQUEST_H #include +#include #include #include "gt/intel_context_types.h" @@ -147,6 +148,7 @@ }; struct list_head execute_cb; struct i915_sw_fence semaphore; + struct irq_work semaphore_work; /* * A list of everyone we wait upon, and everyone who waits upon us. @@ -251,6 +253,7 @@ void __i915_request_queue(struct i915_request *rq, const struct i915_sched_attr *attr); +bool i915_request_retire(struct i915_request *rq); void i915_request_retire_upto(struct i915_request *rq); static inline struct i915_request * --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_scheduler.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_scheduler.c @@ -418,8 +418,6 @@ if (!node_signaled(signal)) { INIT_LIST_HEAD(&dep->dfs_link); - list_add(&dep->wait_link, &signal->waiters_list); - list_add(&dep->signal_link, &node->signalers_list); dep->signaler = signal; dep->waiter = node; dep->flags = flags; @@ -429,6 +427,10 @@ !node_started(signal)) node->flags |= I915_SCHED_HAS_SEMAPHORE_CHAIN; + /* All set, now publish. Beware the lockless walkers. */ + list_add(&dep->signal_link, &node->signalers_list); + list_add_rcu(&dep->wait_link, &signal->waiters_list); + /* * As we do not allow WAIT to preempt inflight requests, * once we have executed a request, along with triggering @@ -531,6 +533,6 @@ return 0; err_priorities: - kmem_cache_destroy(global.slab_priorities); + kmem_cache_destroy(global.slab_dependencies); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_sw_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_sw_fence.c @@ -38,7 +38,7 @@ debug_object_init(fence, &i915_sw_fence_debug_descr); } -static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) +static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) { debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr); } @@ -64,7 +64,7 @@ debug_object_destroy(fence, &i915_sw_fence_debug_descr); } -static inline void debug_fence_free(struct i915_sw_fence *fence) +static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) { debug_object_free(fence, &i915_sw_fence_debug_descr); smp_wmb(); /* flush the change in state before reallocation */ @@ -81,7 +81,7 @@ { } -static inline void debug_fence_init_onstack(struct i915_sw_fence *fence) +static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence) { } @@ -102,7 +102,7 @@ { } -static inline void debug_fence_free(struct i915_sw_fence *fence) +static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence) { } @@ -158,9 +158,13 @@ do { list_for_each_entry_safe(pos, next, &x->head, entry) { - pos->func(pos, - TASK_NORMAL, fence->error, - &extra); + int wake_flags; + + wake_flags = fence->error; + if (pos->func == autoremove_wake_function) + wake_flags = 0; + + pos->func(pos, TASK_NORMAL, wake_flags, &extra); } if (list_empty(&extra)) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_utils.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_utils.c @@ -8,9 +8,8 @@ #include "i915_drv.h" #include "i915_utils.h" -#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" -#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ - "providing the dmesg log by booting with drm.debug=0xf" +#define FDO_BUG_URL "https://gitlab.freedesktop.org/drm/intel/-/wikis/How-to-file-i915-bugs" +#define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details." void __i915_printk(struct drm_i915_private *dev_priv, const char *level, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_utils.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_utils.h @@ -233,6 +233,11 @@ __idx; \ }) +static inline bool is_power_of_2_u64(u64 n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + static inline void __list_del_many(struct list_head *head, struct list_head *first) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/i915_vma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/i915_vma.c @@ -341,6 +341,10 @@ return ret; vma->flags |= bind_flags; + + if (vma->obj) + set_bit(I915_BO_WAS_BOUND_BIT, &vma->obj->flags); + return 0; } @@ -907,10 +911,16 @@ return err; if (flags & EXEC_OBJECT_WRITE) { - if (intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CS)) - i915_active_ref(&obj->frontbuffer->write, - rq->timeline, - rq); + struct intel_frontbuffer *front; + + front = __intel_frontbuffer_get(obj); + if (unlikely(front)) { + if (intel_frontbuffer_invalidate(front, ORIGIN_CS)) + i915_active_ref(&front->write, + rq->timeline, + rq); + intel_frontbuffer_put(front); + } dma_resv_add_excl_fence(vma->resv, &rq->fence); obj->write_domain = I915_GEM_DOMAIN_RENDER; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/intel_pch.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/intel_pch.c @@ -74,6 +74,11 @@ WARN_ON(!IS_COFFEELAKE(dev_priv)); /* CometPoint is CNP Compatible */ return PCH_CNP; + case INTEL_PCH_CMP_V_DEVICE_ID_TYPE: + DRM_DEBUG_KMS("Found Comet Lake V PCH (CMP-V)\n"); + WARN_ON(!IS_COFFEELAKE(dev_priv)); + /* Comet Lake V PCH is based on KBP, which is SPT compatible */ + return PCH_SPT; case INTEL_PCH_ICP_DEVICE_ID_TYPE: DRM_DEBUG_KMS("Found Ice Lake PCH\n"); WARN_ON(!IS_ICELAKE(dev_priv)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/intel_pch.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/intel_pch.h @@ -42,6 +42,7 @@ #define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 #define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 #define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 +#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 #define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 #define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 #define INTEL_PCH_MCC2_DEVICE_ID_TYPE 0x3880 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/intel_pm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/intel_pm.c @@ -2822,7 +2822,7 @@ } static void intel_read_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[8]) + u16 wm[]) { struct intel_uncore *uncore = &dev_priv->uncore; @@ -2966,7 +2966,7 @@ static void intel_print_wm_latency(struct drm_i915_private *dev_priv, const char *name, - const u16 wm[8]) + const u16 wm[]) { int level, max_level = ilk_wm_max_level(dev_priv); @@ -3017,9 +3017,9 @@ * The BIOS provided WM memory latency values are often * inadequate for high resolution displays. Adjust them. */ - changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12) | - ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12) | - ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); + changed = ilk_increase_wm_latency(dev_priv, dev_priv->wm.pri_latency, 12); + changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.spr_latency, 12); + changed |= ilk_increase_wm_latency(dev_priv, dev_priv->wm.cur_latency, 12); if (!changed) return; @@ -4784,7 +4784,7 @@ * WaIncreaseLatencyIPCEnabled: kbl,cfl * Display WA #1141: kbl,cfl */ - if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) || + if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv)) && dev_priv->ipc_enabled) latency += 4; @@ -9194,6 +9194,17 @@ /* WaEnable32PlaneMode:icl */ I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN11_ENABLE_32_PLANE_MODE)); + + /* + * Wa_1408615072:icl,ehl (vsunit) + * Wa_1407596294:icl,ehl (hsunit) + */ + intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE, + 0, VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS); + + /* Wa_1407352427:icl,ehl */ + intel_uncore_rmw(&dev_priv->uncore, UNSLICE_UNIT_LEVEL_CLKGATE2, + 0, PSDUNIT_CLKGATE_DIS); } static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/intel_uncore.c +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/intel_uncore.c @@ -1124,6 +1124,18 @@ spin_unlock(&uncore->debug->lock); } +#define __vgpu_read(x) \ +static u##x \ +vgpu_read##x(struct intel_uncore *uncore, i915_reg_t reg, bool trace) { \ + u##x val = __raw_uncore_read##x(uncore, reg); \ + trace_i915_reg_rw(false, reg, val, sizeof(val), trace); \ + return val; \ +} +__vgpu_read(8) +__vgpu_read(16) +__vgpu_read(32) +__vgpu_read(64) + #define GEN2_READ_HEADER(x) \ u##x val = 0; \ assert_rpm_wakelock_held(uncore->rpm); @@ -1327,6 +1339,16 @@ #undef GEN6_WRITE_FOOTER #undef GEN6_WRITE_HEADER +#define __vgpu_write(x) \ +static void \ +vgpu_write##x(struct intel_uncore *uncore, i915_reg_t reg, u##x val, bool trace) { \ + trace_i915_reg_rw(true, reg, val, sizeof(val), trace); \ + __raw_uncore_write##x(uncore, reg, val); \ +} +__vgpu_write(8) +__vgpu_write(16) +__vgpu_write(32) + #define ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, x) \ do { \ (uncore)->funcs.mmio_writeb = x##_write8; \ @@ -1647,7 +1669,10 @@ { GEM_BUG_ON(intel_uncore_has_forcewake(uncore)); - if (IS_GEN(uncore->i915, 5)) { + if (intel_vgpu_active(uncore->i915)) { + ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, vgpu); + ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, vgpu); + } else if (IS_GEN(uncore->i915, 5)) { ASSIGN_RAW_WRITE_MMIO_VFUNCS(uncore, gen5); ASSIGN_RAW_READ_MMIO_VFUNCS(uncore, gen5); } else { @@ -1901,13 +1926,14 @@ unsigned int slow_timeout_ms, u32 *out_value) { - u32 uninitialized_var(reg_value); + u32 reg_value = 0; #define done (((reg_value = intel_uncore_read_fw(uncore, reg)) & mask) == value) int ret; /* Catch any overuse of this function */ might_sleep_if(slow_timeout_ms); GEM_BUG_ON(fast_timeout_us > 20000); + GEM_BUG_ON(!fast_timeout_us && !slow_timeout_ms); ret = -ETIMEDOUT; if (fast_timeout_us && fast_timeout_us <= 20000) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/i915/selftests/i915_random.h +++ linux-oracle-5.4.0/drivers/gpu/drm/i915/selftests/i915_random.h @@ -25,6 +25,7 @@ #ifndef __I915_SELFTESTS_RANDOM_H__ #define __I915_SELFTESTS_RANDOM_H__ +#include #include #include "../i915_selftest.h" --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -212,9 +212,8 @@ if (!pdev->dev.of_node) return -ENODEV; - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) - return -ENOMEM; + hdmi = dev_get_drvdata(dev); + memset(hdmi, 0, sizeof(*hdmi)); match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node); plat_data = match->data; @@ -239,8 +238,6 @@ drm_encoder_init(drm, encoder, &dw_hdmi_imx_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); - platform_set_drvdata(pdev, hdmi); - hdmi->hdmi = dw_hdmi_bind(pdev, encoder, plat_data); /* @@ -270,6 +267,14 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev) { + struct imx_hdmi *hdmi; + + hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + if (!hdmi) + return -ENOMEM; + + platform_set_drvdata(pdev, hdmi); + return component_add(&pdev->dev, &dw_hdmi_imx_ops); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/imx-drm-core.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/imx-drm-core.c @@ -281,9 +281,10 @@ drm_kms_helper_poll_fini(drm); + component_unbind_all(drm->dev, drm); + drm_mode_config_cleanup(drm); - component_unbind_all(drm->dev, drm); dev_set_drvdata(dev, NULL); drm_dev_put(drm); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/imx-ldb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/imx-ldb.c @@ -197,6 +197,11 @@ int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); + if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { + dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); + return; + } + drm_panel_prepare(imx_ldb_ch->panel); if (dual) { @@ -255,6 +260,11 @@ int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); u32 bus_format = imx_ldb_ch->bus_format; + if (mux < 0 || mux >= ARRAY_SIZE(ldb->clk_sel)) { + dev_warn(ldb->dev, "%s: invalid mux %d\n", __func__, mux); + return; + } + if (mode->clock > 170000) { dev_warn(ldb->dev, "%s: mode exceeds 170 MHz pixel clock\n", __func__); @@ -302,18 +312,19 @@ { struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; + int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; int mux, ret; drm_panel_disable(imx_ldb_ch->panel); - if (imx_ldb_ch == &ldb->channel[0]) + if (imx_ldb_ch == &ldb->channel[0] || dual) ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; - else if (imx_ldb_ch == &ldb->channel[1]) + if (imx_ldb_ch == &ldb->channel[1] || dual) ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); - if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { + if (dual) { clk_disable_unprepare(ldb->clk[0]); clk_disable_unprepare(ldb->clk[1]); } @@ -593,9 +604,8 @@ int ret; int i; - imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL); - if (!imx_ldb) - return -ENOMEM; + imx_ldb = dev_get_drvdata(dev); + memset(imx_ldb, 0, sizeof(*imx_ldb)); imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); if (IS_ERR(imx_ldb->regmap)) { @@ -703,8 +713,6 @@ } } - dev_set_drvdata(dev, imx_ldb); - return 0; free_child: @@ -736,6 +744,14 @@ static int imx_ldb_probe(struct platform_device *pdev) { + struct imx_ldb *imx_ldb; + + imx_ldb = devm_kzalloc(&pdev->dev, sizeof(*imx_ldb), GFP_KERNEL); + if (!imx_ldb) + return -ENOMEM; + + platform_set_drvdata(pdev, imx_ldb); + return component_add(&pdev->dev, &imx_ldb_ops); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/imx-tve.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/imx-tve.c @@ -237,8 +237,9 @@ return ret; } -static int imx_tve_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +imx_tve_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { struct imx_tve *tve = con_to_tve(connector); unsigned long rate; @@ -494,6 +495,13 @@ return 0; } +static void imx_tve_disable_regulator(void *data) +{ + struct imx_tve *tve = data; + + regulator_disable(tve->dac_reg); +} + static bool imx_tve_readable_reg(struct device *dev, unsigned int reg) { return (reg % 4 == 0) && (reg <= 0xdc); @@ -546,9 +554,8 @@ int irq; int ret; - tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL); - if (!tve) - return -ENOMEM; + tve = dev_get_drvdata(dev); + memset(tve, 0, sizeof(*tve)); tve->dev = dev; spin_lock_init(&tve->lock); @@ -618,6 +625,9 @@ ret = regulator_enable(tve->dac_reg); if (ret) return ret; + ret = devm_add_action_or_reset(dev, imx_tve_disable_regulator, tve); + if (ret) + return ret; } tve->clk = devm_clk_get(dev, "tve"); @@ -659,27 +669,23 @@ if (ret) return ret; - dev_set_drvdata(dev, tve); - return 0; } -static void imx_tve_unbind(struct device *dev, struct device *master, - void *data) -{ - struct imx_tve *tve = dev_get_drvdata(dev); - - if (!IS_ERR(tve->dac_reg)) - regulator_disable(tve->dac_reg); -} - static const struct component_ops imx_tve_ops = { .bind = imx_tve_bind, - .unbind = imx_tve_unbind, }; static int imx_tve_probe(struct platform_device *pdev) { + struct imx_tve *tve; + + tve = devm_kzalloc(&pdev->dev, sizeof(*tve), GFP_KERNEL); + if (!tve) + return -ENOMEM; + + platform_set_drvdata(pdev, tve); + return component_add(&pdev->dev, &imx_tve_ops); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/ipuv3-crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -68,7 +68,7 @@ drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) { if (plane == &ipu_crtc->plane[0]->base) disable_full = true; - if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) + if (ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) disable_partial = true; } @@ -411,14 +411,12 @@ } ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]); - ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, - "imx_drm", ipu_crtc); + ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, + IRQF_NO_AUTOEN, "imx_drm", ipu_crtc); if (ret < 0) { dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); goto err_put_plane1_res; } - /* Only enable IRQ when we actually need it to trigger work. */ - disable_irq(ipu_crtc->irq); return 0; @@ -438,21 +436,13 @@ struct ipu_client_platformdata *pdata = dev->platform_data; struct drm_device *drm = data; struct ipu_crtc *ipu_crtc; - int ret; - ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL); - if (!ipu_crtc) - return -ENOMEM; + ipu_crtc = dev_get_drvdata(dev); + memset(ipu_crtc, 0, sizeof(*ipu_crtc)); ipu_crtc->dev = dev; - ret = ipu_crtc_init(ipu_crtc, pdata, drm); - if (ret) - return ret; - - dev_set_drvdata(dev, ipu_crtc); - - return 0; + return ipu_crtc_init(ipu_crtc, pdata, drm); } static void ipu_drm_unbind(struct device *dev, struct device *master, @@ -474,6 +464,7 @@ static int ipu_drm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct ipu_crtc *ipu_crtc; int ret; if (!dev->platform_data) @@ -483,6 +474,12 @@ if (ret) return ret; + ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL); + if (!ipu_crtc) + return -ENOMEM; + + dev_set_drvdata(dev, ipu_crtc); + return component_add(dev, &ipu_crtc_ops); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/imx/parallel-display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/imx/parallel-display.c @@ -63,13 +63,15 @@ int ret; if (!mode) - return -EINVAL; + return 0; ret = of_get_drm_display_mode(np, &imxpd->mode, &imxpd->bus_flags, OF_USE_NATIVE_MODE); - if (ret) - return ret; + if (ret) { + drm_mode_destroy(connector->dev, mode); + return 0; + } drm_mode_copy(mode, &imxpd->mode); mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, @@ -204,9 +206,8 @@ u32 bus_format = 0; const char *fmt; - imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); - if (!imxpd) - return -ENOMEM; + imxpd = dev_get_drvdata(dev); + memset(imxpd, 0, sizeof(*imxpd)); edidp = of_get_property(np, "edid", &imxpd->edid_len); if (edidp) @@ -236,8 +237,6 @@ if (ret) return ret; - dev_set_drvdata(dev, imxpd); - return 0; } @@ -259,6 +258,14 @@ static int imx_pd_probe(struct platform_device *pdev) { + struct imx_parallel_display *imxpd; + + imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL); + if (!imxpd) + return -ENOMEM; + + platform_set_drvdata(pdev, imxpd); + return component_add(&pdev->dev, &imx_pd_ops); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/ingenic/ingenic-drm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/ingenic/ingenic-drm.c @@ -371,14 +371,18 @@ struct ingenic_drm *priv = drm_plane_get_priv(plane); struct drm_plane_state *state = plane->state; unsigned int width, height, cpp; + dma_addr_t addr; - width = state->crtc->state->adjusted_mode.hdisplay; - height = state->crtc->state->adjusted_mode.vdisplay; - cpp = state->fb->format->cpp[plane->index]; - - priv->dma_hwdesc->addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); - priv->dma_hwdesc->cmd = width * height * cpp / 4; - priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ; + if (state && state->fb) { + addr = drm_fb_cma_get_gem_addr(state->fb, state, 0); + width = state->src_w >> 16; + height = state->src_h >> 16; + cpp = state->fb->format->cpp[0]; + + priv->dma_hwdesc->addr = addr; + priv->dma_hwdesc->cmd = width * height * cpp / 4; + priv->dma_hwdesc->cmd |= JZ_LCD_CMD_EOF_IRQ; + } } static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder, @@ -463,7 +467,7 @@ static irqreturn_t ingenic_drm_irq_handler(int irq, void *arg) { - struct ingenic_drm *priv = arg; + struct ingenic_drm *priv = drm_device_get_priv(arg); unsigned int state; regmap_read(priv->map, JZ_REG_LCD_STATE, &state); @@ -820,6 +824,7 @@ { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); static struct platform_driver ingenic_drm_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/lima/lima_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/lima/lima_device.c @@ -293,6 +293,7 @@ struct resource *res; dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); + dma_set_max_seg_size(ldev->dev, UINT_MAX); err = lima_clk_init(ldev); if (err) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/lima/lima_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/lima/lima_drv.c @@ -300,8 +300,10 @@ /* Allocate and initialize the DRM device. */ ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev); - if (IS_ERR(ddev)) - return PTR_ERR(ddev); + if (IS_ERR(ddev)) { + err = PTR_ERR(ddev); + goto err_out0; + } ddev->dev_private = ldev; ldev->ddev = ddev; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/lima/lima_gp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/lima/lima_gp.c @@ -138,6 +138,11 @@ gp_write(LIMA_GP_CMD, cmd); } +static int lima_gp_bus_stop_poll(struct lima_ip *ip) +{ + return !!(gp_read(LIMA_GP_STATUS) & LIMA_GP_STATUS_BUS_STOPPED); +} + static int lima_gp_hard_reset_poll(struct lima_ip *ip) { gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC01A0000); @@ -151,6 +156,13 @@ gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC0FFE000); gp_write(LIMA_GP_INT_MASK, 0); + + gp_write(LIMA_GP_CMD, LIMA_GP_CMD_STOP_BUS); + ret = lima_poll_timeout(ip, lima_gp_bus_stop_poll, 10, 100); + if (ret) { + dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip)); + return ret; + } gp_write(LIMA_GP_CMD, LIMA_GP_CMD_RESET); ret = lima_poll_timeout(ip, lima_gp_hard_reset_poll, 10, 100); if (ret) { @@ -244,7 +256,9 @@ void lima_gp_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } int lima_gp_pipe_init(struct lima_device *dev) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/lima/lima_mmu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/lima/lima_mmu.c @@ -97,7 +97,12 @@ void lima_mmu_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + if (ip->id == lima_ip_ppmmu_bcast) + return; + + devm_free_irq(dev->dev, ip->irq, ip); } void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/lima/lima_pp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/lima/lima_pp.c @@ -251,7 +251,9 @@ void lima_pp_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } int lima_pp_bcast_init(struct lima_ip *ip) @@ -272,7 +274,9 @@ void lima_pp_bcast_fini(struct lima_ip *ip) { + struct lima_device *dev = ip->dev; + devm_free_irq(dev->dev, ip->irq, ip); } static int lima_pp_task_validate(struct lima_sched_pipe *pipe, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mcde/mcde_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mcde/mcde_display.c @@ -946,6 +946,7 @@ struct drm_crtc *crtc = &pipe->crtc; struct drm_device *drm = crtc->dev; struct mcde *mcde = drm->dev_private; + struct drm_pending_vblank_event *event; if (mcde->te_sync) drm_crtc_vblank_off(crtc); @@ -953,6 +954,15 @@ /* Disable FIFO A flow */ mcde_disable_fifo(mcde, MCDE_FIFO_A, true); + event = crtc->state->event; + if (event) { + crtc->state->event = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irq(&crtc->dev->event_lock); + } + dev_info(drm->dev, "MCDE display is disabled\n"); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mcde/mcde_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mcde/mcde_drv.c @@ -215,7 +215,6 @@ drm_mode_config_reset(drm); drm_kms_helper_poll_init(drm); - drm_fbdev_generic_setup(drm, 32); return 0; @@ -282,6 +281,8 @@ if (ret < 0) goto unbind; + drm_fbdev_generic_setup(drm, 32); + return 0; unbind: @@ -409,8 +410,8 @@ } irq = platform_get_irq(pdev, 0); - if (!irq) { - ret = -EINVAL; + if (irq < 0) { + ret = irq; goto clk_disable; } @@ -484,7 +485,8 @@ } if (!match) { dev_err(dev, "no matching components\n"); - return -ENODEV; + ret = -ENODEV; + goto clk_disable; } if (IS_ERR(match)) { dev_err(dev, "could not create component match\n"); @@ -531,6 +533,7 @@ }, {}, }; +MODULE_DEVICE_TABLE(of, mcde_of_match); static struct platform_driver mcde_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mcde/mcde_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mcde/mcde_dsi.c @@ -935,13 +935,15 @@ for_each_available_child_of_node(dev->of_node, child) { panel = of_drm_find_panel(child); if (IS_ERR(panel)) { - dev_err(dev, "failed to find panel try bridge (%lu)\n", + dev_err(dev, "failed to find panel try bridge (%ld)\n", PTR_ERR(panel)); + panel = NULL; + bridge = of_drm_find_bridge(child); - if (IS_ERR(bridge)) { - dev_err(dev, "failed to find bridge (%lu)\n", - PTR_ERR(bridge)); - return PTR_ERR(bridge); + if (!bridge) { + dev_err(dev, "failed to find bridge\n"); + of_node_put(child); + return -EINVAL; } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_cec.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_cec.c @@ -84,7 +84,7 @@ u32 tmp = readl(cec->regs + offset) & ~mask; tmp |= val & mask; - writel(val, cec->regs + offset); + writel(tmp, cec->regs + offset); } void mtk_cec_set_hpd_event(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_dpi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_dpi.c @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include @@ -48,13 +50,7 @@ }; enum mtk_dpi_out_color_format { - MTK_DPI_COLOR_FORMAT_RGB, - MTK_DPI_COLOR_FORMAT_RGB_FULL, - MTK_DPI_COLOR_FORMAT_YCBCR_444, - MTK_DPI_COLOR_FORMAT_YCBCR_422, - MTK_DPI_COLOR_FORMAT_XV_YCC, - MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL, - MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL + MTK_DPI_COLOR_FORMAT_RGB }; struct mtk_dpi { @@ -73,6 +69,9 @@ enum mtk_dpi_out_yc_map yc_map; enum mtk_dpi_out_bit_num bit_num; enum mtk_dpi_out_channel_swap channel_swap; + struct pinctrl *pinctrl; + struct pinctrl_state *pins_gpio; + struct pinctrl_state *pins_dpi; int refcount; }; @@ -350,24 +349,11 @@ static void mtk_dpi_config_color_format(struct mtk_dpi *dpi, enum mtk_dpi_out_color_format format) { - if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_444) || - (format == MTK_DPI_COLOR_FORMAT_YCBCR_444_FULL)) { - mtk_dpi_config_yuv422_enable(dpi, false); - mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, false); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_BGR); - } else if ((format == MTK_DPI_COLOR_FORMAT_YCBCR_422) || - (format == MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL)) { - mtk_dpi_config_yuv422_enable(dpi, true); - mtk_dpi_config_csc_enable(dpi, true); - mtk_dpi_config_swap_input(dpi, true); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); - } else { - mtk_dpi_config_yuv422_enable(dpi, false); - mtk_dpi_config_csc_enable(dpi, false); - mtk_dpi_config_swap_input(dpi, false); - mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); - } + /* only support RGB888 */ + mtk_dpi_config_yuv422_enable(dpi, false); + mtk_dpi_config_csc_enable(dpi, false); + mtk_dpi_config_swap_input(dpi, false); + mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB); } static void mtk_dpi_power_off(struct mtk_dpi *dpi) @@ -402,7 +388,6 @@ goto err_pixel; } - mtk_dpi_enable(dpi); return 0; err_pixel: @@ -538,14 +523,21 @@ struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); mtk_dpi_power_off(dpi); + + if (dpi->pinctrl && dpi->pins_gpio) + pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); } static void mtk_dpi_encoder_enable(struct drm_encoder *encoder) { struct mtk_dpi *dpi = mtk_dpi_from_encoder(encoder); + if (dpi->pinctrl && dpi->pins_dpi) + pinctrl_select_state(dpi->pinctrl, dpi->pins_dpi); + mtk_dpi_power_on(dpi); mtk_dpi_set_display_mode(dpi, &dpi->mode); + mtk_dpi_enable(dpi); } static int mtk_dpi_atomic_check(struct drm_encoder *encoder, @@ -689,6 +681,26 @@ dpi->dev = dev; dpi->conf = (struct mtk_dpi_conf *)of_device_get_match_data(dev); + dpi->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(dpi->pinctrl)) { + dpi->pinctrl = NULL; + dev_dbg(&pdev->dev, "Cannot find pinctrl!\n"); + } + if (dpi->pinctrl) { + dpi->pins_gpio = pinctrl_lookup_state(dpi->pinctrl, "sleep"); + if (IS_ERR(dpi->pins_gpio)) { + dpi->pins_gpio = NULL; + dev_dbg(&pdev->dev, "Cannot find pinctrl idle!\n"); + } + if (dpi->pins_gpio) + pinctrl_select_state(dpi->pinctrl, dpi->pins_gpio); + + dpi->pins_dpi = pinctrl_lookup_state(dpi->pinctrl, "default"); + if (IS_ERR(dpi->pins_dpi)) { + dpi->pins_dpi = NULL; + dev_dbg(&pdev->dev, "Cannot find pinctrl active!\n"); + } + } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); dpi->regs = devm_ioremap_resource(dev, mem); if (IS_ERR(dpi->regs)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -73,11 +73,13 @@ struct drm_crtc *crtc = &mtk_crtc->base; unsigned long flags; - spin_lock_irqsave(&crtc->dev->event_lock, flags); - drm_crtc_send_vblank_event(crtc, mtk_crtc->event); - drm_crtc_vblank_put(crtc); - mtk_crtc->event = NULL; - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + if (mtk_crtc->event) { + spin_lock_irqsave(&crtc->dev->event_lock, flags); + drm_crtc_send_vblank_event(crtc, mtk_crtc->event); + drm_crtc_vblank_put(crtc); + mtk_crtc->event = NULL; + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + } } static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc) @@ -240,7 +242,7 @@ drm_connector_list_iter_end(&conn_iter); } - ret = pm_runtime_get_sync(crtc->dev->dev); + ret = pm_runtime_resume_and_get(crtc->dev->dev); if (ret < 0) { DRM_ERROR("Failed to enable power domain: %d\n", ret); return ret; @@ -298,6 +300,7 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc) { struct drm_device *drm = mtk_crtc->base.dev; + struct drm_crtc *crtc = &mtk_crtc->base; int i; DRM_DEBUG_DRIVER("%s\n", __func__); @@ -319,6 +322,13 @@ mtk_disp_mutex_unprepare(mtk_crtc->mutex); pm_runtime_put(drm->dev); + + if (crtc->state->event && !crtc->state->active) { + spin_lock_irq(&crtc->dev->event_lock); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + spin_unlock_irq(&crtc->dev->event_lock); + } } static void mtk_crtc_ddp_config(struct drm_crtc *crtc) @@ -488,10 +498,18 @@ static int mtk_drm_crtc_init(struct drm_device *drm, struct mtk_drm_crtc *mtk_crtc, - struct drm_plane *primary, - struct drm_plane *cursor, unsigned int pipe) + unsigned int pipe) { - int ret; + struct drm_plane *primary = NULL; + struct drm_plane *cursor = NULL; + int i, ret; + + for (i = 0; i < mtk_crtc->layer_nr; i++) { + if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_PRIMARY) + primary = &mtk_crtc->planes[i]; + else if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_CURSOR) + cursor = &mtk_crtc->planes[i]; + } ret = drm_crtc_init_with_planes(drm, &mtk_crtc->base, primary, cursor, &mtk_crtc_funcs, NULL); @@ -529,6 +547,7 @@ int pipe = priv->num_pipes; int ret; int i; + uint gamma_lut_size = 0; if (!path) return 0; @@ -579,6 +598,9 @@ } mtk_crtc->ddp_comp[i] = comp; + + if (comp->funcs && comp->funcs->gamma_set) + gamma_lut_size = MTK_LUT_SIZE; } mtk_crtc->layer_nr = mtk_ddp_comp_layer_nr(mtk_crtc->ddp_comp[0]); @@ -596,13 +618,13 @@ return ret; } - ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0], - mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] : - NULL, pipe); + ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe); if (ret < 0) return ret; - drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE); - drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE); + + if (gamma_lut_size) + drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size); + drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, gamma_lut_size); priv->num_pipes++; return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -417,6 +417,7 @@ err_deinit: mtk_drm_kms_deinit(drm); err_free: + private->drm = NULL; drm_dev_put(drm); return ret; } @@ -594,8 +595,13 @@ pm_runtime_disable(dev); err_node: of_node_put(private->mutex_node); - for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) + for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) { of_node_put(private->comp_node[i]); + if (private->ddp_comp[i]) { + put_device(private->ddp_comp[i]->larb_dev); + private->ddp_comp[i] = NULL; + } + } return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -21,6 +21,9 @@ size = round_up(size, PAGE_SIZE); + if (size == 0) + return ERR_PTR(-EINVAL); + mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL); if (!mtk_gem_obj) return ERR_PTR(-ENOMEM); @@ -142,8 +145,6 @@ ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie, mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs); - if (ret) - drm_gem_vm_close(vma); return ret; } @@ -269,9 +270,13 @@ } mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - + if (!mtk_gem->kvaddr) { + kfree(sgt); + kfree(mtk_gem->pages); + return ERR_PTR(-ENOMEM); + } out: - kfree((void *)sgt); + kfree(sgt); return mtk_gem->kvaddr; } @@ -284,6 +289,6 @@ return; vunmap(vaddr); - mtk_gem->kvaddr = 0; - kfree((void *)mtk_gem->pages); + mtk_gem->kvaddr = NULL; + kfree(mtk_gem->pages); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -101,6 +101,16 @@ true, true); } +static void mtk_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct mtk_plane_state *state = to_mtk_plane_state(plane->state); + + state->pending.enable = false; + wmb(); /* Make sure the above parameter is set before update */ + state->pending.dirty = true; +} + static void mtk_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -115,6 +125,11 @@ if (!crtc || WARN_ON(!fb)) return; + if (!plane->state->visible) { + mtk_plane_atomic_disable(plane, old_state); + return; + } + gem = fb->obj[0]; mtk_gem = to_mtk_gem_obj(gem); addr = mtk_gem->dma_addr; @@ -136,16 +151,6 @@ state->pending.dirty = true; } -static void mtk_plane_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct mtk_plane_state *state = to_mtk_plane_state(plane->state); - - state->pending.enable = false; - wmb(); /* Make sure the above parameter is set before update */ - state->pending.dirty = true; -} - static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = { .prepare_fb = drm_gem_fb_prepare_fb, .atomic_check = mtk_plane_atomic_check, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -64,8 +64,8 @@ #define DSI_PS_WC 0x3fff #define DSI_PS_SEL (3 << 16) #define PACKED_PS_16BIT_RGB565 (0 << 16) -#define LOOSELY_PS_18BIT_RGB666 (1 << 16) -#define PACKED_PS_18BIT_RGB666 (2 << 16) +#define PACKED_PS_18BIT_RGB666 (1 << 16) +#define LOOSELY_PS_24BIT_RGB666 (2 << 16) #define PACKED_PS_24BIT_RGB888 (3 << 16) #define DSI_VSA_NL 0x20 @@ -321,10 +321,10 @@ ps_bpp_mode |= PACKED_PS_24BIT_RGB888; break; case MIPI_DSI_FMT_RGB666: - ps_bpp_mode |= PACKED_PS_18BIT_RGB666; + ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666; break; case MIPI_DSI_FMT_RGB666_PACKED: - ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666; + ps_bpp_mode |= PACKED_PS_18BIT_RGB666; break; case MIPI_DSI_FMT_RGB565: ps_bpp_mode |= PACKED_PS_16BIT_RGB565; @@ -375,7 +375,7 @@ dsi_tmp_buf_bpp = 3; break; case MIPI_DSI_FMT_RGB666: - tmp_reg = LOOSELY_PS_18BIT_RGB666; + tmp_reg = LOOSELY_PS_24BIT_RGB666; dsi_tmp_buf_bpp = 3; break; case MIPI_DSI_FMT_RGB666_PACKED: @@ -645,6 +645,8 @@ mtk_dsi_reset_engine(dsi); mtk_dsi_lane0_ulp_mode_enter(dsi); mtk_dsi_clk_ulp_mode_enter(dsi); + /* set the lane number as 0 to pull down mipi */ + writel(0, dsi->regs + DSI_TXRX_CTRL); mtk_dsi_disable(dsi); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_hdmi.c @@ -1237,17 +1237,19 @@ struct drm_display_mode *mode) { struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn); + struct drm_bridge *next_bridge; dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n", mode->hdisplay, mode->vdisplay, mode->vrefresh, !!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000); - if (hdmi->bridge.next) { + next_bridge = drm_bridge_get_next_bridge(&hdmi->bridge); + if (next_bridge) { struct drm_display_mode adjusted_mode; drm_mode_copy(&adjusted_mode, mode); - if (!drm_bridge_mode_fixup(hdmi->bridge.next, mode, - &adjusted_mode)) + if (!drm_bridge_chain_mode_fixup(next_bridge, mode, + &adjusted_mode)) return MODE_BAD; } @@ -1482,25 +1484,30 @@ dev_err(dev, "Failed to get system configuration registers: %d\n", ret); - return ret; + goto put_device; } hdmi->sys_regmap = regmap; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); hdmi->regs = devm_ioremap_resource(dev, mem); - if (IS_ERR(hdmi->regs)) - return PTR_ERR(hdmi->regs); + if (IS_ERR(hdmi->regs)) { + ret = PTR_ERR(hdmi->regs); + goto put_device; + } remote = of_graph_get_remote_node(np, 1, 0); - if (!remote) - return -EINVAL; + if (!remote) { + ret = -EINVAL; + goto put_device; + } if (!of_device_is_compatible(remote, "hdmi-connector")) { hdmi->next_bridge = of_drm_find_bridge(remote); if (!hdmi->next_bridge) { dev_err(dev, "Waiting for external bridge\n"); of_node_put(remote); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto put_device; } } @@ -1509,7 +1516,8 @@ dev_err(dev, "Failed to find ddc-i2c-bus node in %pOF\n", remote); of_node_put(remote); - return -EINVAL; + ret = -EINVAL; + goto put_device; } of_node_put(remote); @@ -1517,10 +1525,14 @@ of_node_put(i2c_np); if (!hdmi->ddc_adpt) { dev_err(dev, "Failed to get ddc i2c adapter by node\n"); - return -EINVAL; + ret = -EINVAL; + goto put_device; } return 0; +put_device: + put_device(hdmi->cec_dev); + return ret; } /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mediatek/mtk_hdmi_phy.c @@ -84,8 +84,9 @@ hdmi_phy->conf->hdmi_phy_disable_tmds) return &mtk_hdmi_phy_dev_ops; - dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); - return NULL; + if (hdmi_phy) + dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n"); + return NULL; } static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_drv.c @@ -124,8 +124,11 @@ for_each_endpoint_of_node(dev->of_node, ep) { /* If the endpoint node exists, consider it enabled */ remote = of_graph_get_remote_port(ep); - if (remote) + if (remote) { + of_node_put(remote); + of_node_put(ep); return true; + } } return false; @@ -420,6 +423,17 @@ return count; } +static void meson_drv_shutdown(struct platform_device *pdev) +{ + struct meson_drm *priv = dev_get_drvdata(&pdev->dev); + + if (!priv) + return; + + drm_kms_helper_poll_fini(priv->drm); + drm_atomic_helper_shutdown(priv->drm); +} + static int meson_drv_probe(struct platform_device *pdev) { struct component_match *match = NULL; @@ -469,6 +483,7 @@ static struct platform_driver meson_drm_platform_driver = { .probe = meson_drv_probe, + .shutdown = meson_drv_shutdown, .driver = { .name = "meson-drm", .of_match_table = dt_match, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_plane.c @@ -128,7 +128,7 @@ /* Enable OSD and BLK0, set max global alpha */ priv->viu.osd1_ctrl_stat = OSD_ENABLE | - (0xFF << OSD_GLOBAL_ALPHA_SHIFT) | + (0x100 << OSD_GLOBAL_ALPHA_SHIFT) | OSD_BLK0_ENABLE; canvas_id_osd1 = priv->canvas_id_osd1; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_registers.h +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_registers.h @@ -590,6 +590,11 @@ #define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc #define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd +/* osd1 HDR */ +#define OSD1_HDR2_CTRL 0x38a0 +#define OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN BIT(13) +#define OSD1_HDR2_CTRL_REG_ONLY_MAT BIT(16) + /* osd2 scaler */ #define OSD2_VSC_PHASE_STEP 0x3d00 #define OSD2_VSC_INI_PHASE 0x3d01 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_vclk.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_vclk.c @@ -638,13 +638,18 @@ if (frac >= HDMI_FRAC_MAX_GXBB) return false; } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || - meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL) || - meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { /* Empiric supported min/max dividers */ if (m < 106 || m > 247) return false; if (frac >= HDMI_FRAC_MAX_GXL) return false; + } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { + /* Empiric supported min/max dividers */ + if (m < 106 || m > 247) + return false; + if (frac >= HDMI_FRAC_MAX_G12A) + return false; } return true; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_venc_cvbs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_venc_cvbs.c @@ -64,6 +64,25 @@ }, }; +static const struct meson_cvbs_mode * +meson_cvbs_get_mode(const struct drm_display_mode *req_mode) +{ + int i; + + for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { + struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; + + if (drm_mode_match(req_mode, &meson_mode->mode, + DRM_MODE_MATCH_TIMINGS | + DRM_MODE_MATCH_CLOCK | + DRM_MODE_MATCH_FLAGS | + DRM_MODE_MATCH_3D_FLAGS)) + return meson_mode; + } + + return NULL; +} + /* Connector */ static void meson_cvbs_connector_destroy(struct drm_connector *connector) @@ -136,14 +155,8 @@ struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - int i; - - for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { - struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; - - if (drm_mode_equal(&crtc_state->mode, &meson_mode->mode)) - return 0; - } + if (meson_cvbs_get_mode(&crtc_state->mode)) + return 0; return -EINVAL; } @@ -191,24 +204,17 @@ struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + const struct meson_cvbs_mode *meson_mode = meson_cvbs_get_mode(mode); struct meson_venc_cvbs *meson_venc_cvbs = encoder_to_meson_venc_cvbs(encoder); struct meson_drm *priv = meson_venc_cvbs->priv; - int i; - for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) { - struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i]; + if (meson_mode) { + meson_venci_cvbs_mode_set(priv, meson_mode->enci); - if (drm_mode_equal(mode, &meson_mode->mode)) { - meson_venci_cvbs_mode_set(priv, - meson_mode->enci); - - /* Setup 27MHz vclk2 for ENCI and VDAC */ - meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, - MESON_VCLK_CVBS, MESON_VCLK_CVBS, - MESON_VCLK_CVBS, true); - break; - } + /* Setup 27MHz vclk2 for ENCI and VDAC */ + meson_vclk_setup(priv, MESON_VCLK_TARGET_CVBS, MESON_VCLK_CVBS, + MESON_VCLK_CVBS, MESON_VCLK_CVBS, true); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_viu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_viu.c @@ -91,7 +91,7 @@ priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF11_12)); writel(((m[9] & 0x1fff) << 16) | (m[10] & 0x1fff), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF20_21)); - writel((m[11] & 0x1fff) << 16, + writel((m[11] & 0x1fff), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_COEF22)); writel(((m[18] & 0xfff) << 16) | (m[19] & 0xfff), @@ -356,9 +356,14 @@ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) meson_viu_load_matrix(priv); - else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff, true); + /* fix green/pink color distortion from vendor u-boot */ + writel_bits_relaxed(OSD1_HDR2_CTRL_REG_ONLY_MAT | + OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN, 0, + priv->io_base + _REG(OSD1_HDR2_CTRL)); + } /* Initialize OSD1 fifo control register */ reg = VIU_OSD_DDR_PRIORITY_URGENT | @@ -395,17 +400,17 @@ priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE)); if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { - writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) | - VIU_OSD_BLEND_REORDER(1, 0) | - VIU_OSD_BLEND_REORDER(2, 0) | - VIU_OSD_BLEND_REORDER(3, 0) | - VIU_OSD_BLEND_DIN_EN(1) | - VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | - VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | - VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | - VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) | - VIU_OSD_BLEND_HOLD_LINES(4), - priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); + u32 val = (u32)VIU_OSD_BLEND_REORDER(0, 1) | + (u32)VIU_OSD_BLEND_REORDER(1, 0) | + (u32)VIU_OSD_BLEND_REORDER(2, 0) | + (u32)VIU_OSD_BLEND_REORDER(3, 0) | + (u32)VIU_OSD_BLEND_DIN_EN(1) | + (u32)VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 | + (u32)VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 | + (u32)VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 | + (u32)VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) | + (u32)VIU_OSD_BLEND_HOLD_LINES(4); + writel_relaxed(val, priv->io_base + _REG(VIU_OSD_BLEND_CTRL)); writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE, priv->io_base + _REG(OSD1_BLEND_SRC_CTRL)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/meson/meson_vpp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/meson/meson_vpp.c @@ -100,6 +100,8 @@ priv->io_base + _REG(VPP_DOLBY_CTRL)); writel_relaxed(0x1020080, priv->io_base + _REG(VPP_DUMMY_DATA1)); + writel_relaxed(0x42020, + priv->io_base + _REG(VPP_DUMMY_DATA)); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) writel_relaxed(0xf, priv->io_base + _REG(DOLBY_PATH_CTRL)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mgag200/mgag200_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -30,7 +30,8 @@ static struct drm_driver driver; static const struct pci_device_id pciidlist[] = { - { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A }, + { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, @@ -63,6 +64,35 @@ DRM_VRAM_MM_FILE_OPERATIONS }; +static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) +{ + return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; +} + +int mgag200_driver_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args) +{ + struct mga_device *mdev = dev->dev_private; + unsigned long pg_align; + + if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) + return -EINVAL; + + pg_align = 0ul; + + /* + * Aligning scanout buffers to the size of the video ram forces + * placement at offset 0. Works around a bug where HW does not + * respect 'startadd' field. + */ + if (mgag200_pin_bo_at_0(mdev)) + pg_align = PFN_UP(mdev->mc.vram_size); + + return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, + pg_align, false, args); +} + static struct drm_driver driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET, .load = mgag200_driver_load, @@ -74,7 +104,9 @@ .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - DRM_GEM_VRAM_DRIVER + .dumb_create = mgag200_driver_dumb_create, + .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, + .gem_prime_mmap = drm_gem_prime_mmap, }; static struct pci_driver mgag200_pci_driver = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mgag200/mgag200_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -159,6 +159,12 @@ G200_EW3, }; +/* HW does not handle 'startadd' field correct. */ +#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) + +#define MGAG200_TYPE_MASK (0x000000ff) +#define MGAG200_FLAG_MASK (0x00ffff00) + #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) struct mga_device { @@ -188,6 +194,18 @@ u32 unique_rev_id; }; +static inline enum mga_type +mgag200_type_from_driver_data(kernel_ulong_t driver_data) +{ + return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); +} + +static inline unsigned long +mgag200_flags_from_driver_data(kernel_ulong_t driver_data) +{ + return driver_data & MGAG200_FLAG_MASK; +} + /* mgag200_mode.c */ int mgag200_modeset_init(struct mga_device *mdev); void mgag200_modeset_fini(struct mga_device *mdev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -135,7 +135,7 @@ i2c->adapter.algo_data = &i2c->bit; i2c->bit.udelay = 10; - i2c->bit.timeout = 2; + i2c->bit.timeout = usecs_to_jiffies(2200); i2c->bit.data = i2c; i2c->bit.setsda = mga_gpio_setsda; i2c->bit.setscl = mga_gpio_setscl; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mgag200/mgag200_main.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mgag200/mgag200_main.c @@ -94,7 +94,8 @@ struct mga_device *mdev = dev->dev_private; int ret, option; - mdev->type = flags; + mdev->flags = mgag200_flags_from_driver_data(flags); + mdev->type = mgag200_type_from_driver_data(flags); /* Hardcode the number of CRTCs to 1 */ mdev->num_crtc = 1; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -164,6 +164,11 @@ if (ret) return ret; + gpu_write(gpu, REG_AXXX_CP_RB_CNTL, + MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + + gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); + /* NOTE: PM4/micro-engine firmware registers look to be the same * for a2xx and a3xx.. we could possibly push that part down to * adreno_gpu base class. Or push both PM4 and PFP but --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -215,6 +215,16 @@ if (ret) return ret; + /* + * Use the default ringbuffer size and block size but disable the RPTR + * shadow + */ + gpu_write(gpu, REG_AXXX_CP_RB_CNTL, + MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + + /* Set the ringbuffer address */ + gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); + /* setup access protection: */ gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -265,6 +265,16 @@ if (ret) return ret; + /* + * Use the default ringbuffer size and block size but disable the RPTR + * shadow + */ + gpu_write(gpu, REG_A4XX_CP_RB_CNTL, + MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + + /* Set the ringbuffer address */ + gpu_write(gpu, REG_A4XX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova)); + /* Load PM4: */ ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data); len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -71,7 +71,7 @@ * since we've already mapped it once in * submit_reloc() */ - if (WARN_ON(!ptr)) + if (WARN_ON(IS_ERR_OR_NULL(ptr))) return; for (i = 0; i < dwords; i++) { @@ -134,9 +134,13 @@ OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1); OUT_RING(ring, 1); - /* Enable local preemption for finegrain preemption */ - OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1); - OUT_RING(ring, 0x02); + /* + * Disable local preemption by default because it requires + * user-space to be aware of it and provide additional handling + * to restore rendering state or do various flushes on switch. + */ + OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1); + OUT_RING(ring, 0x0); /* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */ OUT_PKT7(ring, CP_YIELD_ENABLE, 1); @@ -581,8 +585,6 @@ if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); - /* Enable USE_RETENTION_FLOPS */ gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); @@ -677,14 +679,21 @@ if (ret) return ret; - a5xx_preempt_hw_init(gpu); - a5xx_gpmu_ucode_init(gpu); ret = a5xx_ucode_init(gpu); if (ret) return ret; + /* Set the ringbuffer address */ + gpu_write64(gpu, REG_A5XX_CP_RB_BASE, REG_A5XX_CP_RB_BASE_HI, + gpu->rb[0]->iova); + + gpu_write(gpu, REG_A5XX_CP_RB_CNTL, + MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + + a5xx_preempt_hw_init(gpu); + /* Disable the interrupts through the initial bringup stage */ gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK); @@ -726,11 +735,18 @@ gpu->funcs->flush(gpu, gpu->rb[0]); if (!a5xx_idle(gpu, gpu->rb[0])) return -EINVAL; - } else { - /* Print a warning so if we die, we know why */ + } else if (ret == -ENODEV) { + /* + * This device does not use zap shader (but print a warning + * just in case someone got their dt wrong.. hopefully they + * have a debug UART to realize the error of their ways... + * if you mess this up you are about to crash horribly) + */ dev_warn_once(gpu->dev->dev, "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n"); gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0); + } else { + return ret; } /* Last step - yield the ringbuffer */ @@ -1119,8 +1135,8 @@ static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value) { - *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO, - REG_A5XX_RBBM_PERFCTR_CP_0_HI); + *value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO, + REG_A5XX_RBBM_ALWAYSON_COUNTER_HI); return 0; } @@ -1352,6 +1368,10 @@ { u64 busy_cycles, busy_time; + /* Only read the gpu busy if the hardware is already active */ + if (pm_runtime_get_if_in_use(&gpu->pdev->dev) == 0) + return 0; + busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO, REG_A5XX_RBBM_PERFCTR_RBBM_0_HI); @@ -1360,6 +1380,8 @@ gpu->devfreq.busy_cycles = busy_cycles; + pm_runtime_put(&gpu->pdev->dev); + if (WARN_ON(busy_time > ~0LU)) return ~0LU; @@ -1394,18 +1416,31 @@ static void check_speed_bin(struct device *dev) { struct nvmem_cell *cell; - u32 bin, val; + u32 val; + + /* + * If the OPP table specifies a opp-supported-hw property then we have + * to set something with dev_pm_opp_set_supported_hw() or the table + * doesn't get populated so pick an arbitrary value that should + * ensure the default frequencies are selected but not conflict with any + * actual bins + */ + val = 0x80; cell = nvmem_cell_get(dev, "speed_bin"); - /* If a nvmem cell isn't defined, nothing to do */ - if (IS_ERR(cell)) - return; + if (!IS_ERR(cell)) { + void *buf = nvmem_cell_read(cell, NULL); - bin = *((u32 *) nvmem_cell_read(cell, NULL)); - nvmem_cell_put(cell); + if (!IS_ERR(buf)) { + u8 bin = *((u8 *) buf); - val = (1 << bin); + val = (1 << bin); + kfree(buf); + } + + nvmem_cell_put(cell); + } dev_pm_opp_set_supported_hw(dev, &val, 1); } @@ -1438,7 +1473,8 @@ check_speed_bin(&pdev->dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 4); + /* Restricting nr_rings to 1 to temporarily disable preemption */ + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a5xx_gpu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a5xx_gpu.h @@ -35,6 +35,7 @@ uint64_t preempt_iova[MSM_GPU_MAX_RINGS]; atomic_t preempt_state; + spinlock_t preempt_start_lock; struct timer_list preempt_timer; }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a5xx_power.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a5xx_power.c @@ -300,7 +300,7 @@ /* Set up the limits management */ if (adreno_is_a530(adreno_gpu)) a530_lm_setup(gpu); - else + else if (adreno_is_a540(adreno_gpu)) a540_lm_setup(gpu); /* Set up SP/TP power collpase */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a5xx_preempt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a5xx_preempt.c @@ -99,11 +99,18 @@ return; /* + * Serialize preemption start to ensure that we always make + * decision on latest state. Otherwise we can get stuck in + * lower priority or empty ring. + */ + spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags); + + /* * Try to start preemption by moving from NONE to START. If * unsuccessful, a preemption is already in flight */ if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START)) - return; + goto out; /* Get the next ring to preempt to */ ring = get_next_ring(gpu); @@ -128,9 +135,11 @@ set_preempt_state(a5xx_gpu, PREEMPT_ABORT); update_wptr(gpu, a5xx_gpu->cur_ring); set_preempt_state(a5xx_gpu, PREEMPT_NONE); - return; + goto out; } + spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags); + /* Make sure the wptr doesn't update while we're in motion */ spin_lock_irqsave(&ring->lock, flags); a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring); @@ -154,6 +163,10 @@ /* And actually start the preemption */ gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1); + return; + +out: + spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags); } void a5xx_preempt_irq(struct msm_gpu *gpu) @@ -191,6 +204,12 @@ update_wptr(gpu, a5xx_gpu->cur_ring); set_preempt_state(a5xx_gpu, PREEMPT_NONE); + + /* + * Try to trigger preemption again in case there was a submit or + * retire during ring switch + */ + a5xx_preempt_trigger(gpu); } void a5xx_preempt_hw_init(struct msm_gpu *gpu) @@ -207,6 +226,8 @@ return; for (i = 0; i < gpu->nr_rings; i++) { + a5xx_gpu->preempt[i]->data = 0; + a5xx_gpu->preempt[i]->info = 0; a5xx_gpu->preempt[i]->wptr = 0; a5xx_gpu->preempt[i]->rptr = 0; a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova; @@ -287,5 +308,6 @@ } } + spin_lock_init(&a5xx_gpu->preempt_start_lock); timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -107,6 +107,13 @@ struct msm_gpu *gpu = &adreno_gpu->base; int ret; + /* + * This can get called from devfreq while the hardware is idle. Don't + * bring up the power if it isn't already active + */ + if (pm_runtime_get_if_in_use(gmu->dev) == 0) + return; + gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0); gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING, @@ -133,6 +140,7 @@ * for now leave it at max so that the performance is nominal. */ icc_set_bw(gpu->icc_path, 0, MBps_to_icc(7216)); + pm_runtime_put(gmu->dev); } void a6xx_gmu_set_freq(struct msm_gpu *gpu, unsigned long freq) @@ -191,12 +199,22 @@ { int ret; u32 val; + u32 mask, reset_val; + + val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8); + if (val <= 0x20010004) { + mask = 0xffffffff; + reset_val = 0xbabeface; + } else { + mask = 0x1ff; + reset_val = 0x100; + } gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1); gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0); ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val, - val == 0xbabeface, 100, 10000); + (val & mask) == reset_val, 100, 10000); if (ret) DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n"); @@ -705,10 +723,19 @@ /* Turn on the resources */ pm_runtime_get_sync(gmu->dev); + /* + * "enable" the GX power domain which won't actually do anything but it + * will make sure that the refcounting is correct in case we need to + * bring down the GX after a GMU failure + */ + if (!IS_ERR_OR_NULL(gmu->gxpd)) + pm_runtime_get_sync(gmu->gxpd); + /* Use a known rate to bring up the GMU */ clk_set_rate(gmu->core_clk, 200000000); ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks); if (ret) { + pm_runtime_put(gmu->gxpd); pm_runtime_put(gmu->dev); return ret; } @@ -744,19 +771,12 @@ /* Set the GPU to the highest power frequency */ __a6xx_gmu_set_freq(gmu, gmu->nr_gpu_freqs - 1); - /* - * "enable" the GX power domain which won't actually do anything but it - * will make sure that the refcounting is correct in case we need to - * bring down the GX after a GMU failure - */ - if (!IS_ERR_OR_NULL(gmu->gxpd)) - pm_runtime_get(gmu->gxpd); - out: /* On failure, shut down the GMU to leave it in a good state */ if (ret) { disable_irq(gmu->gmu_irq); a6xx_rpmh_stop(gmu); + pm_runtime_put(gmu->gxpd); pm_runtime_put(gmu->dev); } @@ -1213,15 +1233,13 @@ irq = platform_get_irq_byname(pdev, name); - ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu); + ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu); if (ret) { DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n", name, ret); return ret; } - disable_irq(irq); - return irq; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -512,6 +512,13 @@ if (ret) goto out; + /* Set the ringbuffer address */ + gpu_write64(gpu, REG_A6XX_CP_RB_BASE, REG_A6XX_CP_RB_BASE_HI, + gpu->rb[0]->iova); + + gpu_write(gpu, REG_A6XX_CP_RB_CNTL, + MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE); + /* Always come up on rb 0 */ a6xx_gpu->cur_ring = gpu->rb[0]; @@ -537,12 +544,19 @@ a6xx_flush(gpu, gpu->rb[0]); if (!a6xx_idle(gpu, gpu->rb[0])) return -EINVAL; - } else { - /* Print a warning so if we die, we know why */ + } else if (ret == -ENODEV) { + /* + * This device does not use zap shader (but print a warning + * just in case someone got their dt wrong.. hopefully they + * have a debug UART to realize the error of their ways... + * if you mess this up you are about to crash horribly) + */ dev_warn_once(gpu->dev->dev, "Zap shader not enabled - using SECVID_TRUST_CNTL instead\n"); gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0); ret = 0; + } else { + return ret; } out: @@ -759,8 +773,8 @@ /* Force the GPU power on so we can read this register */ a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); - *value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO, - REG_A6XX_RBBM_PERFCTR_CP_0_HI); + *value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, + REG_A6XX_CP_ALWAYS_ON_COUNTER_HI); a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET); return 0; @@ -796,6 +810,11 @@ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); u64 busy_cycles, busy_time; + + /* Only read the gpu busy if the hardware is already active */ + if (pm_runtime_get_if_in_use(a6xx_gpu->gmu.dev) == 0) + return 0; + busy_cycles = gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H); @@ -805,6 +824,8 @@ gpu->devfreq.busy_cycles = busy_cycles; + pm_runtime_put(a6xx_gpu->gmu.dev); + if (WARN_ON(busy_time > ~0LU)) return ~0LU; @@ -870,6 +891,7 @@ BUG_ON(!node); ret = a6xx_gmu_init(a6xx_gpu, node); + of_node_put(node); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -352,26 +352,26 @@ cxdbg = ioremap(res->start, resource_size(res)); if (cxdbg) { - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLT, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLT, A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf)); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_CNTLM, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLM, A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf)); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_0, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0, 0x76543210); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_1, + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1, 0xFEDCBA98); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0); - cxdbg_write(cxdbg, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0); + cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0); } a6xx_state->debugbus = state_kcalloc(a6xx_state, @@ -834,7 +834,7 @@ int i; a6xx_state->indexed_regs = state_kcalloc(a6xx_state, count, - sizeof(a6xx_state->indexed_regs)); + sizeof(*a6xx_state->indexed_regs)); if (!a6xx_state->indexed_regs) return; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h @@ -200,7 +200,7 @@ SHADER(A6XX_SP_LB_3_DATA, 0x800), SHADER(A6XX_SP_LB_4_DATA, 0x800), SHADER(A6XX_SP_LB_5_DATA, 0x200), - SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000), + SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800), SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280), SHADER(A6XX_SP_UAV_DATA, 0x80), SHADER(A6XX_SP_INST_TAG, 0x80), --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/adreno_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -233,8 +233,11 @@ if (ret) return NULL; - /* Make sure pm runtime is active and reset any previous errors */ - pm_runtime_set_active(&pdev->dev); + /* + * Now that we have firmware loaded, and are ready to begin + * booting the gpu, go ahead and enable runpm: + */ + pm_runtime_enable(&pdev->dev); ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -247,7 +247,7 @@ ret = request_firmware_direct(&fw, fwname, drm->dev); if (!ret) { DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n", - newname); + fwname); adreno_gpu->fwloc = FW_LOCATION_LEGACY; goto out; } else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) { @@ -350,30 +350,10 @@ ring->next = ring->start; /* reset completed fence seqno: */ - ring->memptrs->fence = ring->seqno; + ring->memptrs->fence = ring->fctx->completed_fence; ring->memptrs->rptr = 0; } - /* - * Setup REG_CP_RB_CNTL. The same value is used across targets (with - * the excpetion of A430 that disables the RPTR shadow) - the cacluation - * for the ringbuffer size and block size is moved to msm_gpu.h for the - * pre-processor to deal with and the A430 variant is ORed in here - */ - adreno_gpu_write(adreno_gpu, REG_ADRENO_CP_RB_CNTL, - MSM_GPU_RB_CNTL_DEFAULT | - (adreno_is_a430(adreno_gpu) ? AXXX_CP_RB_CNTL_NO_UPDATE : 0)); - - /* Setup ringbuffer address - use ringbuffer[0] for GPU init */ - adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_BASE, - REG_ADRENO_CP_RB_BASE_HI, gpu->rb[0]->iova); - - if (!adreno_is_a430(adreno_gpu)) { - adreno_gpu_write64(adreno_gpu, REG_ADRENO_CP_RB_RPTR_ADDR, - REG_ADRENO_CP_RB_RPTR_ADDR_HI, - rbmemptr(gpu->rb[0], rptr)); - } - return 0; } @@ -381,11 +361,8 @@ static uint32_t get_rptr(struct adreno_gpu *adreno_gpu, struct msm_ringbuffer *ring) { - if (adreno_is_a430(adreno_gpu)) - return ring->memptrs->rptr = adreno_gpu_read( - adreno_gpu, REG_ADRENO_CP_RB_RPTR); - else - return ring->memptrs->rptr; + return ring->memptrs->rptr = adreno_gpu_read( + adreno_gpu, REG_ADRENO_CP_RB_RPTR); } struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu) @@ -922,7 +899,6 @@ pm_runtime_set_autosuspend_delay(&pdev->dev, adreno_gpu->info->inactive_period); pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(&pdev->dev); return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base, adreno_gpu->info->name, &adreno_gpu_config); @@ -931,11 +907,15 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu) { struct msm_gpu *gpu = &adreno_gpu->base; + struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL; unsigned int i; for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) release_firmware(adreno_gpu->fw[i]); + if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev)) + pm_runtime_disable(&priv->gpu_pdev->dev); + icc_put(gpu->icc_path); msm_gpu_cleanup(&adreno_gpu->base); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -47,11 +47,9 @@ ADRENO_FW_MAX, }; -enum adreno_quirks { - ADRENO_QUIRK_TWO_PASS_USE_WFI = 1, - ADRENO_QUIRK_FAULT_DETECT_MASK = 2, - ADRENO_QUIRK_LMLOADKILL_DISABLE = 3, -}; +#define ADRENO_QUIRK_TWO_PASS_USE_WFI BIT(0) +#define ADRENO_QUIRK_FAULT_DETECT_MASK BIT(1) +#define ADRENO_QUIRK_LMLOADKILL_DISABLE BIT(2) struct adreno_rev { uint8_t core; @@ -74,7 +72,7 @@ const char *name; const char *fw[ADRENO_FW_MAX]; uint32_t gmem; - enum adreno_quirks quirks; + u64 quirks; struct msm_gpu *(*init)(struct drm_device *dev); const char *zapfw; u32 inactive_period; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -15,19 +15,6 @@ #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 /** - * enum dpu_core_perf_data_bus_id - data bus identifier - * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus - * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus - * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus - */ -enum dpu_core_perf_data_bus_id { - DPU_CORE_PERF_DATA_BUS_ID_MNOC, - DPU_CORE_PERF_DATA_BUS_ID_LLCC, - DPU_CORE_PERF_DATA_BUS_ID_EBI, - DPU_CORE_PERF_DATA_BUS_ID_MAX, -}; - -/** * struct dpu_core_perf_params - definition of performance parameters * @max_per_pipe_ib: maximum instantaneous bandwidth request * @bw_ctl: arbitrated bandwidth request --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -381,7 +381,7 @@ spin_unlock_irqrestore(&dpu_crtc->spin_lock, flags); if (!fevent) { - DRM_ERROR("crtc%d event %d overflow\n", crtc->base.id, event); + DRM_ERROR_RATELIMITED("crtc%d event %d overflow\n", crtc->base.id, event); return; } @@ -651,7 +651,10 @@ if (crtc->state) dpu_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &cstate->base); + if (cstate) + __drm_atomic_helper_crtc_reset(crtc, &cstate->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } /** @@ -819,7 +822,7 @@ struct drm_plane *plane; struct drm_display_mode *mode; - int cnt = 0, rc = 0, mixer_width, i, z_pos; + int cnt = 0, rc = 0, mixer_width = 0, i, z_pos; struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2]; int multirect_count = 0; @@ -833,6 +836,8 @@ } pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL); + if (!pstates) + return -ENOMEM; dpu_crtc = to_dpu_crtc(crtc); cstate = to_dpu_crtc_state(state); @@ -852,9 +857,11 @@ memset(pipe_staged, 0, sizeof(pipe_staged)); - mixer_width = mode->hdisplay / cstate->num_mixers; + if (cstate->num_mixers) { + mixer_width = mode->hdisplay / cstate->num_mixers; - _dpu_crtc_setup_lm_bounds(crtc, state); + _dpu_crtc_setup_lm_bounds(crtc, state); + } crtc_rect.x2 = mode->hdisplay; crtc_rect.y2 = mode->vdisplay; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -44,6 +44,9 @@ (p) ? ((p)->hw_pp ? (p)->hw_pp->idx - PINGPONG_0 : -1) : -1, \ ##__VA_ARGS__) +#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) + /* * Two to anticipate panels that can do cmd/vid dynamic switching * plan is to create all possible physical encoder types, and switch between @@ -2151,7 +2154,7 @@ return; } - DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); event = DPU_ENCODER_FRAME_EVENT_ERROR; trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); @@ -2185,7 +2188,6 @@ dpu_enc = to_dpu_encoder_virt(enc); - mutex_init(&dpu_enc->enc_lock); ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); if (ret) goto fail; @@ -2200,7 +2202,6 @@ 0); - mutex_init(&dpu_enc->rc_lock); INIT_DELAYED_WORK(&dpu_enc->delayed_off_work, dpu_encoder_off_work); dpu_enc->idle_timeout = IDLE_TIMEOUT; @@ -2232,7 +2233,7 @@ dpu_enc = devm_kzalloc(dev->dev, sizeof(*dpu_enc), GFP_KERNEL); if (!dpu_enc) - return ERR_PTR(ENOMEM); + return ERR_PTR(-ENOMEM); rc = drm_encoder_init(dev, &dpu_enc->base, &dpu_encoder_funcs, drm_enc_mode, NULL); @@ -2245,6 +2246,8 @@ spin_lock_init(&dpu_enc->enc_spinlock); dpu_enc->enabled = false; + mutex_init(&dpu_enc->enc_lock); + mutex_init(&dpu_enc->rc_lock); return &dpu_enc->base; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -479,9 +479,6 @@ _dpu_encoder_phys_cmd_pingpong_config(phys_enc); - if (!dpu_encoder_phys_cmd_is_master(phys_enc)) - return; - ctl = phys_enc->hw_ctl; ctl->ops.get_bitmask_intf(ctl, &flush_mask, phys_enc->intf_idx); ctl->ops.update_pending_flush(ctl, flush_mask); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -258,12 +258,14 @@ mode.htotal >>= 1; mode.hsync_start >>= 1; mode.hsync_end >>= 1; + mode.hskew >>= 1; DPU_DEBUG_VIDENC(phys_enc, - "split_role %d, halve horizontal %d %d %d %d\n", + "split_role %d, halve horizontal %d %d %d %d %d\n", phys_enc->split_role, mode.hdisplay, mode.htotal, - mode.hsync_start, mode.hsync_end); + mode.hsync_start, mode.hsync_end, + mode.hskew); } drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c @@ -255,13 +255,13 @@ INTERLEAVED_RGB_FMT(RGB565, 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, - C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3, + C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3, false, 2, 0, DPU_FETCH_LINEAR, 1), INTERLEAVED_RGB_FMT(BGR565, 0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT, - C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3, + C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3, false, 2, 0, DPU_FETCH_LINEAR, 1), --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -281,10 +281,12 @@ int i; for (i = 0; i < ctx->mixer_count; i++) { - DPU_REG_WRITE(c, CTL_LAYER(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT2(LM_0 + i), 0); - DPU_REG_WRITE(c, CTL_LAYER_EXT3(LM_0 + i), 0); + enum dpu_lm mixer_id = ctx->mixer_hw_caps[i].id; + + DPU_REG_WRITE(c, CTL_LAYER(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); + DPU_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c @@ -137,11 +137,13 @@ u32 *idx) { int rc = 0; - const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk; + const struct dpu_sspp_sub_blks *sblk; - if (!ctx) + if (!ctx || !ctx->cap || !ctx->cap->sblk) return -EINVAL; + sblk = ctx->cap->sblk; + switch (s_id) { case DPU_SSPP_SRC: *idx = sblk->src_blk.base; @@ -404,7 +406,7 @@ (void)pe; if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp - || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk) + || !scaler3_cfg) return; dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -88,8 +88,8 @@ &status); } else { seq_puts(s, "\nSafe signal status:\n"); - if (kms->hw_mdp->ops.get_danger_status) - kms->hw_mdp->ops.get_danger_status(kms->hw_mdp, + if (kms->hw_mdp->ops.get_safe_status) + kms->hw_mdp->ops.get_safe_status(kms->hw_mdp, &status); } pm_runtime_put_sync(&kms->pdev->dev); @@ -596,11 +596,11 @@ _dpu_kms_mmu_destroy(dpu_kms); if (dpu_kms->catalog) { - for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { - u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - - if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx]) - dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]); + for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { + if (dpu_kms->hw_vbif[i]) { + dpu_hw_vbif_destroy(dpu_kms->hw_vbif[i]); + dpu_kms->hw_vbif[i] = NULL; + } } } @@ -897,7 +897,7 @@ for (i = 0; i < dpu_kms->catalog->vbif_count; i++) { u32 vbif_idx = dpu_kms->catalog->vbif[i].id; - dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx, + dpu_kms->hw_vbif[vbif_idx] = dpu_hw_vbif_init(vbif_idx, dpu_kms->vbif[vbif_idx], dpu_kms->catalog); if (IS_ERR_OR_NULL(dpu_kms->hw_vbif[vbif_idx])) { rc = PTR_ERR(dpu_kms->hw_vbif[vbif_idx]); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -30,26 +30,17 @@ * @fmt: Pointer to format string */ #define DPU_DEBUG(fmt, ...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_KMS)) \ - DRM_DEBUG(fmt, ##__VA_ARGS__); \ - else \ - pr_debug(fmt, ##__VA_ARGS__); \ - } while (0) + DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) /** * DPU_DEBUG_DRIVER - macro for hardware driver logging * @fmt: Pointer to format string */ #define DPU_DEBUG_DRIVER(fmt, ...) \ - do { \ - if (unlikely(drm_debug & DRM_UT_DRIVER)) \ - DRM_ERROR(fmt, ##__VA_ARGS__); \ - else \ - pr_debug(fmt, ##__VA_ARGS__); \ - } while (0) + DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__) #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) /** * ktime_compare_safe - compare two ktime structures --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -853,9 +853,9 @@ crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); - min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxdwnscale); + min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale); ret = drm_atomic_helper_check_plane_state(state, crtc_state, min_scale, - pdpu->pipe_sblk->maxupscale << 16, + pdpu->pipe_sblk->maxdwnscale << 16, true, true); if (ret) { DPU_ERROR_PLANE(pdpu, "Check plane state failed (%d)\n", ret); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c @@ -11,6 +11,14 @@ #include "dpu_hw_vbif.h" #include "dpu_trace.h" +static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx) +{ + if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif)) + return dpu_kms->hw_vbif[vbif_idx]; + + return NULL; +} + /** * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt * @vbif: Pointer to hardware vbif driver @@ -148,11 +156,11 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms, struct dpu_vbif_set_ot_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; u32 ot_lim; - int ret, i; + int ret; if (!dpu_kms) { DPU_ERROR("invalid arguments\n"); @@ -160,12 +168,7 @@ } mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) - vbif = dpu_kms->hw_vbif[i]; - } - + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !mdp) { DPU_DEBUG("invalid arguments vbif %d mdp %d\n", vbif != 0, mdp != 0); @@ -208,7 +211,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms, struct dpu_vbif_set_qos_params *params) { - struct dpu_hw_vbif *vbif = NULL; + struct dpu_hw_vbif *vbif; struct dpu_hw_mdp *mdp; bool forced_on = false; const struct dpu_vbif_qos_tbl *qos_tbl; @@ -220,13 +223,7 @@ } mdp = dpu_kms->hw_mdp; - for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) { - if (dpu_kms->hw_vbif[i] && - dpu_kms->hw_vbif[i]->idx == params->vbif_idx) { - vbif = dpu_kms->hw_vbif[i]; - break; - } - } + vbif = dpu_get_vbif(dpu_kms, params->vbif_idx); if (!vbif || !vbif->cap) { DPU_ERROR("invalid vbif %d\n", params->vbif_idx); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -268,6 +268,7 @@ { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); + unsigned long flags; DBG("%s", mdp4_crtc->name); @@ -280,6 +281,14 @@ mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); mdp4_disable(mdp4_kms); + if (crtc->state->event && !crtc->state->active) { + WARN_ON(mdp4_crtc->event); + spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); + } + mdp4_crtc->enabled = false; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_dsi_encoder.c @@ -121,7 +121,7 @@ if (mdp4_dsi_encoder->enabled) return; - mdp4_crtc_set_config(encoder->crtc, + mdp4_crtc_set_config(encoder->crtc, MDP4_DMA_CONFIG_PACK_ALIGN_MSB | MDP4_DMA_CONFIG_DEFLKR_EN | MDP4_DMA_CONFIG_DITHER_EN | --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -88,8 +88,6 @@ if (mdp4_kms->rev > 1) mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1); - dev->mode_config.allow_fb_modifiers = true; - out: pm_runtime_put_sync(dev->dev); @@ -110,13 +108,6 @@ static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) { - int i; - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - - /* see 119ecb7fd */ - for_each_new_crtc_in_state(state, crtc, crtc_state, i) - drm_crtc_vblank_get(crtc); } static void mdp4_flush_commit(struct msm_kms *kms, unsigned crtc_mask) @@ -135,12 +126,6 @@ static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask) { - struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); - struct drm_crtc *crtc; - - /* see 119ecb7fd */ - for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask) - drm_crtc_vblank_put(crtc); } static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, @@ -260,6 +245,7 @@ encoder = mdp4_lcdc_encoder_init(dev, panel_node); if (IS_ERR(encoder)) { DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n"); + of_node_put(panel_node); return PTR_ERR(encoder); } @@ -269,6 +255,7 @@ connector = mdp4_lvds_connector_init(dev, panel_node, encoder); if (IS_ERR(connector)) { DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n"); + of_node_put(panel_node); return PTR_ERR(connector); } @@ -420,6 +407,7 @@ { struct platform_device *pdev = to_platform_device(dev->dev); struct mdp4_platform_config *config = mdp4_get_config(pdev); + struct msm_drm_private *priv = dev->dev_private; struct mdp4_kms *mdp4_kms; struct msm_kms *kms = NULL; struct msm_gem_address_space *aspace; @@ -434,7 +422,8 @@ mdp_kms_init(&mdp4_kms->base, &kms_funcs); - kms = &mdp4_kms->base.base; + priv->kms = &mdp4_kms->base.base; + kms = priv->kms; mdp4_kms->dev = dev; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c @@ -61,8 +61,9 @@ return ret; } -static int mdp4_lvds_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +mdp4_lvds_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { struct mdp4_lvds_connector *mdp4_lvds_connector = to_mdp4_lvds_connector(connector); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c @@ -347,6 +347,12 @@ return mdp4_plane->pipe; } +static const uint64_t supported_format_modifiers[] = { + DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* initialize plane */ struct drm_plane *mdp4_plane_init(struct drm_device *dev, enum mdp4_pipe pipe_id, bool private_plane) @@ -375,7 +381,7 @@ type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, mdp4_plane->formats, mdp4_plane->nformats, - NULL, type, NULL); + supported_format_modifiers, type, NULL); if (ret) goto fail; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_cmd_encoder.c @@ -41,7 +41,7 @@ { struct mdp5_kms *mdp5_kms = get_kms(encoder); struct device *dev = encoder->dev->dev; - u32 total_lines_x100, vclks_line, cfg; + u32 total_lines, vclks_line, cfg; long vsync_clk_speed; struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc); int pp_id = mixer->pp; @@ -51,8 +51,8 @@ return -EINVAL; } - total_lines_x100 = mode->vtotal * drm_mode_vrefresh(mode); - if (!total_lines_x100) { + total_lines = mode->vtotal * drm_mode_vrefresh(mode); + if (!total_lines) { DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n", __func__, mode->vtotal, drm_mode_vrefresh(mode)); return -EINVAL; @@ -64,15 +64,23 @@ vsync_clk_speed); return -EINVAL; } - vclks_line = vsync_clk_speed * 100 / total_lines_x100; + vclks_line = vsync_clk_speed / total_lines; cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN | MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN; cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line); + /* + * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on + * the vsync_clk equating to roughly half the desired panel refresh rate. + * This is only necessary as stability fallback if interrupts from the + * panel arrive too late or not at all, but is currently used by default + * because these panel interrupts are not wired up yet. + */ mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg); mdp5_write(mdp5_kms, - REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), 0xfff0); + REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal)); + mdp5_write(mdp5_kms, REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay); mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -534,9 +534,15 @@ if (ret) return ret; - mdp5_mixer_release(new_crtc_state->state, old_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_mixer); + if (ret) + return ret; + if (old_r_mixer) { - mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer); + if (ret) + return ret; + if (!need_right_mixer) pipeline->r_mixer = NULL; } @@ -903,8 +909,10 @@ ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &mdp5_crtc->cursor.iova); - if (ret) + if (ret) { + drm_gem_object_put(cursor_bo); return -EINVAL; + } pm_runtime_get_sync(&pdev->dev); @@ -1042,7 +1050,10 @@ if (crtc->state) mdp5_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); + if (mdp5_cstate) + __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); drm_crtc_vblank_reset(crtc); } @@ -1099,7 +1110,7 @@ struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, pp_done); - complete(&mdp5_crtc->pp_completion); + complete_all(&mdp5_crtc->pp_completion); } static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc) @@ -1112,8 +1123,8 @@ ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion, msecs_to_jiffies(50)); if (ret == 0) - dev_warn(dev->dev, "pp done time out, lm=%d\n", - mdp5_cstate->pipeline.mixer->lm); + dev_warn_ratelimited(dev->dev, "pp done time out, lm=%d\n", + mdp5_cstate->pipeline.mixer->lm); } static void mdp5_crtc_wait_for_flush_done(struct drm_crtc *crtc) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -698,9 +698,9 @@ pdev = mdp5_kms->pdev; irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (irq < 0) { - ret = irq; - DRM_DEV_ERROR(&pdev->dev, "failed to get irq: %d\n", ret); + if (!irq) { + ret = -EINVAL; + DRM_DEV_ERROR(&pdev->dev, "failed to get irq\n"); goto fail; } @@ -1037,7 +1037,8 @@ return 0; fail: - mdp5_destroy(pdev); + if (mdp5_kms) + mdp5_destroy(pdev); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.c @@ -116,21 +116,28 @@ return 0; } -void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) +int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer) { struct mdp5_global_state *global_state = mdp5_get_global_state(s); - struct mdp5_hw_mixer_state *new_state = &global_state->hwmixer; + struct mdp5_hw_mixer_state *new_state; if (!mixer) - return; + return 0; + + if (IS_ERR(global_state)) + return PTR_ERR(global_state); + + new_state = &global_state->hwmixer; if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx])) - return; + return -EINVAL; DBG("%s: release from crtc %s", mixer->name, new_state->hwmixer_to_crtc[mixer->idx]->name); new_state->hwmixer_to_crtc[mixer->idx] = NULL; + + return 0; } void mdp5_mixer_destroy(struct mdp5_hw_mixer *mixer) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_mixer.h @@ -30,7 +30,7 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc, uint32_t caps, struct mdp5_hw_mixer **mixer, struct mdp5_hw_mixer **r_mixer); -void mdp5_mixer_release(struct drm_atomic_state *s, - struct mdp5_hw_mixer *mixer); +int mdp5_mixer_release(struct drm_atomic_state *s, + struct mdp5_hw_mixer *mixer); #endif /* __MDP5_LM_H__ */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.c @@ -119,18 +119,24 @@ return 0; } -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe) { struct msm_drm_private *priv = s->dev->dev_private; struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms)); - struct mdp5_global_state *state = mdp5_get_global_state(s); - struct mdp5_hw_pipe_state *new_state = &state->hwpipe; + struct mdp5_global_state *state; + struct mdp5_hw_pipe_state *new_state; if (!hwpipe) - return; + return 0; + + state = mdp5_get_global_state(s); + if (IS_ERR(state)) + return PTR_ERR(state); + + new_state = &state->hwpipe; if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx])) - return; + return -EINVAL; DBG("%s: release from plane %s", hwpipe->name, new_state->hwpipe_to_plane[hwpipe->idx]->name); @@ -141,6 +147,8 @@ } new_state->hwpipe_to_plane[hwpipe->idx] = NULL; + + return 0; } void mdp5_pipe_destroy(struct mdp5_hw_pipe *hwpipe) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_pipe.h @@ -37,7 +37,7 @@ uint32_t caps, uint32_t blkcfg, struct mdp5_hw_pipe **hwpipe, struct mdp5_hw_pipe **r_hwpipe); -void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); +int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe); struct mdp5_hw_pipe *mdp5_pipe_init(enum mdp5_pipe pipe, uint32_t reg_offset, uint32_t caps); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -179,7 +179,10 @@ drm_framebuffer_put(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; @@ -218,8 +221,7 @@ { struct mdp5_plane_state *pstate = to_mdp5_plane_state(state); - if (state->fb) - drm_framebuffer_put(state->fb); + __drm_atomic_helper_plane_destroy_state(state); kfree(pstate); } @@ -390,12 +392,24 @@ mdp5_state->r_hwpipe = NULL; - mdp5_pipe_release(state->state, old_hwpipe); - mdp5_pipe_release(state->state, old_right_hwpipe); + ret = mdp5_pipe_release(state->state, old_hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, old_right_hwpipe); + if (ret) + return ret; + } } else { - mdp5_pipe_release(state->state, mdp5_state->hwpipe); - mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe); + if (ret) + return ret; + + ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe); + if (ret) + return ret; + mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c @@ -358,7 +358,7 @@ drm_printf(p, "%s:%d\t%d\t%s\n", pipe2name(pipe), j, inuse, - plane ? plane->name : NULL); + plane ? plane->name : "(null)"); total += inuse; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/dsi.c @@ -26,17 +26,22 @@ } phy_pdev = of_find_device_by_node(phy_node); - if (phy_pdev) + if (phy_pdev) { msm_dsi->phy = platform_get_drvdata(phy_pdev); + msm_dsi->phy_dev = &phy_pdev->dev; + } of_node_put(phy_node); - if (!phy_pdev || !msm_dsi->phy) { + if (!phy_pdev) { + DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); + return -EPROBE_DEFER; + } + if (!msm_dsi->phy) { + put_device(&phy_pdev->dev); DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__); return -EPROBE_DEFER; } - - msm_dsi->phy_dev = get_device(&phy_pdev->dev); return 0; } @@ -198,6 +203,12 @@ return -EINVAL; priv = dev->dev_private; + + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); + return -ENOSPC; + } + msm_dsi->dev = dev; ret = msm_dsi_host_modeset_init(msm_dsi->host, dev); @@ -206,8 +217,10 @@ goto fail; } - if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) + if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) { + ret = -EINVAL; goto fail; + } msm_dsi->encoder = encoder; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/dsi_cfg.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/dsi_cfg.c @@ -97,7 +97,7 @@ static const struct msm_dsi_config msm8996_dsi_cfg = { .io_offset = DSI_6G_REG_SHIFT, .reg_cfg = { - .num = 2, + .num = 3, .regs = { {"vdda", 18160, 1 }, /* 1.25 V */ {"vcca", 17000, 32 }, /* 0.925 V */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/dsi_host.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -460,7 +460,7 @@ return 0; err: - for (; i > 0; i--) + while (--i >= 0) clk_disable_unprepare(msm_host->bus_clks[i]); return ret; @@ -663,7 +663,7 @@ struct drm_display_mode *mode = msm_host->mode; u32 pclk_rate; - pclk_rate = mode->clock * 1000; + pclk_rate = mode->clock * 1000u; /* * For dual DSI mode, the current DRM mode has the complete width of the @@ -1051,9 +1051,21 @@ static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host) { + u32 data; + if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)) return; + data = dsi_read(msm_host, REG_DSI_STATUS0); + + /* if video mode engine is not busy, its because + * either timing engine was not turned on or the + * DSI controller has finished transmitting the video + * data already, so no need to wait in those cases + */ + if (!(data & DSI_STATUS0_VIDEO_MODE_ENGINE_BUSY)) + return; + if (msm_host->power_on && msm_host->enabled) { dsi_wait4video_done(msm_host); /* delay 4 ms to skip BLLP */ @@ -1348,10 +1360,10 @@ dsi_get_bpp(msm_host->format) / 8; len = dsi_cmd_dma_add(msm_host, msg); - if (!len) { + if (len < 0) { pr_err("%s: failed to add cmd type = 0x%x\n", __func__, msg->type); - return -EINVAL; + return len; } /* for video mode, do not send cmds more than @@ -1370,10 +1382,14 @@ } ret = dsi_cmd_dma_tx(msm_host, len); - if (ret < len) { - pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d\n", - __func__, msg->type, (*(u8 *)(msg->tx_buf)), len); - return -ECOMM; + if (ret < 0) { + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d, ret=%d\n", + __func__, msg->type, (*(u8 *)(msg->tx_buf)), len, ret); + return ret; + } else if (ret < len) { + pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, ret=%d len=%d\n", + __func__, msg->type, (*(u8 *)(msg->tx_buf)), ret, len); + return -EIO; } return len; @@ -1669,6 +1685,8 @@ if (!prop) { DRM_DEV_DEBUG(dev, "failed to find data lane mapping, using default\n"); + /* Set the number of date lanes to 4 by default. */ + msm_host->num_data_lanes = 4; return 0; } @@ -1871,6 +1889,9 @@ /* setup workqueue */ msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); + if (!msm_host->workqueue) + return -ENOMEM; + INIT_WORK(&msm_host->err_work, dsi_err_worker); INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker); @@ -2097,9 +2118,12 @@ } ret = dsi_cmds2buf_tx(msm_host, msg); - if (ret < msg->tx_len) { + if (ret < 0) { pr_err("%s: Read cmd Tx failed, %d\n", __func__, ret); return ret; + } else if (ret < msg->tx_len) { + pr_err("%s: Read cmd Tx failed, too short: %d\n", __func__, ret); + return -ECOMM; } /* --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -336,7 +336,7 @@ return num; } -static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, +static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { int id = dsi_mgr_connector_get_id(connector); @@ -479,6 +479,7 @@ struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); struct mipi_dsi_host *host = msm_dsi->host; struct drm_panel *panel = msm_dsi->panel; + struct msm_dsi_pll *src_pll; bool is_dual_dsi = IS_DUAL_DSI(); int ret; @@ -519,6 +520,10 @@ id, ret); } + /* Save PLL status if it is a clock source */ + src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); + msm_dsi_pll_save_state(src_pll); + ret = msm_dsi_host_power_off(host); if (ret) pr_err("%s: host %d power off failed,%d\n", __func__, id, ret); @@ -620,7 +625,7 @@ return connector; fail: - connector->funcs->destroy(msm_dsi->connector); + connector->funcs->destroy(connector); return ERR_PTR(ret); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -347,7 +347,7 @@ } else { timing->shared_timings.clk_pre = linear_inter(tmax, tmin, pcnt2, 0, false); - timing->shared_timings.clk_pre_inc_by_2 = 0; + timing->shared_timings.clk_pre_inc_by_2 = 0; } timing->ta_go = 3; @@ -464,7 +464,9 @@ struct device *dev = &phy->pdev->dev; int ret; - pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; ret = clk_prepare_enable(phy->ahb_clk); if (ret) { @@ -604,6 +606,10 @@ goto fail; } + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + /* PLL init will call into clk_register which requires * register access, so we need to enable power and ahb clock. */ @@ -665,12 +671,14 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, struct msm_dsi_phy_clk_request *clk_req) { - struct device *dev = &phy->pdev->dev; + struct device *dev; int ret; if (!phy || !phy->cfg->ops.enable) return -EINVAL; + dev = &phy->pdev->dev; + ret = dsi_phy_enable_resource(phy); if (ret) { DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n", @@ -724,10 +732,6 @@ if (!phy || !phy->cfg->ops.disable) return; - /* Save PLL status if it is a clock source */ - if (phy->usecase != MSM_DSI_PHY_SLAVE) - msm_dsi_pll_save_state(phy->pll); - phy->cfg->ops.disable(phy); dsi_phy_regulator_disable(phy); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c @@ -139,7 +139,7 @@ .disable = dsi_20nm_phy_disable, .init = msm_dsi_phy_init_common, }, - .io_start = { 0xfd998300, 0xfd9a0300 }, + .io_start = { 0xfd998500, 0xfd9a0500 }, .num_dsi_phy = 2, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c @@ -411,6 +411,12 @@ if (pll_10nm->slave) dsi_pll_enable_pll_bias(pll_10nm->slave); + rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0); + if (rc) { + pr_err("vco_set_rate failed, rc=%d\n", rc); + return rc; + } + /* Start PLL */ pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0x01); @@ -553,6 +559,7 @@ struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; void __iomem *phy_base = pll_10nm->phy_cmn_mmio; u32 val; + int ret; val = pll_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); val &= ~0x3; @@ -567,6 +574,13 @@ val |= cached->pll_mux; pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); + ret = dsi_pll_10nm_vco_set_rate(&pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); + if (ret) { + DRM_DEV_ERROR(&pll_10nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + DBG("DSI PLL%d", pll_10nm->id); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/edp/edp_ctrl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/edp/edp_ctrl.c @@ -1082,7 +1082,7 @@ int msm_edp_ctrl_init(struct msm_edp *edp) { struct edp_ctrl *ctrl = NULL; - struct device *dev = &edp->pdev->dev; + struct device *dev; int ret; if (!edp) { @@ -1090,6 +1090,7 @@ return -EINVAL; } + dev = &edp->pdev->dev; ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); if (!ctrl) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/hdmi/hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -97,10 +97,15 @@ of_node_put(phy_node); - if (!phy_pdev || !hdmi->phy) { + if (!phy_pdev) { DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); return -EPROBE_DEFER; } + if (!hdmi->phy) { + DRM_DEV_ERROR(&pdev->dev, "phy driver is not ready\n"); + put_device(&phy_pdev->dev); + return -EPROBE_DEFER; + } hdmi->phy_dev = get_device(&phy_pdev->dev); @@ -137,6 +142,10 @@ /* HDCP needs physical address of hdmi register */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, config->mmio_name); + if (!res) { + ret = -EINVAL; + goto fail; + } hdmi->mmio_phy_addr = res->start; hdmi->qfprom_mmio = msm_ioremap(pdev, @@ -239,6 +248,10 @@ pm_runtime_enable(&pdev->dev); hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0); + if (!hdmi->workq) { + ret = -ENOMEM; + goto fail; + } hdmi->i2c = msm_hdmi_i2c_init(hdmi); if (IS_ERR(hdmi->i2c)) { @@ -284,6 +297,11 @@ struct platform_device *pdev = hdmi->pdev; int ret; + if (priv->num_bridges == ARRAY_SIZE(priv->bridges)) { + DRM_DEV_ERROR(dev->dev, "too many bridges\n"); + return -ENOSPC; + } + hdmi->dev = dev; hdmi->encoder = encoder; @@ -306,9 +324,9 @@ } hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); - if (hdmi->irq < 0) { - ret = hdmi->irq; - DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret); + if (!hdmi->irq) { + ret = -EINVAL; + DRM_DEV_ERROR(dev->dev, "failed to get irq\n"); goto fail; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_atomic.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_atomic.c @@ -27,6 +27,34 @@ return msm_framebuffer_prepare(new_state->fb, kms->aspace); } +/* + * Helpers to control vblanks while we flush.. basically just to ensure + * that vblank accounting is switched on, so we get valid seqn/timestamp + * on pageflip events (if requested) + */ + +static void vblank_get(struct msm_kms *kms, unsigned crtc_mask) +{ + struct drm_crtc *crtc; + + for_each_crtc_mask(kms->dev, crtc, crtc_mask) { + if (!crtc->state->active) + continue; + drm_crtc_vblank_get(crtc); + } +} + +static void vblank_put(struct msm_kms *kms, unsigned crtc_mask) +{ + struct drm_crtc *crtc; + + for_each_crtc_mask(kms->dev, crtc, crtc_mask) { + if (!crtc->state->active) + continue; + drm_crtc_vblank_put(crtc); + } +} + static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx) { unsigned crtc_mask = BIT(crtc_idx); @@ -44,6 +72,8 @@ kms->funcs->enable_commit(kms); + vblank_get(kms, crtc_mask); + /* * Flush hardware updates: */ @@ -58,6 +88,8 @@ kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask); + vblank_put(kms, crtc_mask); + mutex_lock(&kms->commit_lock); kms->funcs->complete_commit(kms, crtc_mask); mutex_unlock(&kms->commit_lock); @@ -221,6 +253,8 @@ */ kms->pending_crtc_mask &= ~crtc_mask; + vblank_get(kms, crtc_mask); + /* * Flush hardware updates: */ @@ -235,6 +269,8 @@ kms->funcs->wait_flush(kms, crtc_mask); trace_msm_atomic_wait_flush_finish(crtc_mask); + vblank_put(kms, crtc_mask); + mutex_lock(&kms->commit_lock); kms->funcs->complete_commit(kms, crtc_mask); mutex_unlock(&kms->commit_lock); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_debugfs.c @@ -47,12 +47,8 @@ struct msm_gpu_show_priv *show_priv = m->private; struct msm_drm_private *priv = show_priv->dev->dev_private; struct msm_gpu *gpu = priv->gpu; - int ret; - - ret = mutex_lock_interruptible(&show_priv->dev->struct_mutex); - if (ret) - return ret; + mutex_lock(&show_priv->dev->struct_mutex); gpu->funcs->gpu_state_put(show_priv->state); mutex_unlock(&show_priv->dev->struct_mutex); @@ -81,6 +77,7 @@ goto free_priv; pm_runtime_get_sync(&gpu->pdev->dev); + msm_gpu_hw_init(gpu); show_priv->state = gpu->funcs->gpu_state_get(gpu); pm_runtime_put_sync(&gpu->pdev->dev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_drv.c @@ -337,7 +337,7 @@ of_node_put(node); if (ret) return ret; - size = r.end - r.start; + size = r.end - r.start + 1; DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start); /* if we have no IOMMU, then we need to use carveout allocator. @@ -432,14 +432,24 @@ drm_mode_config_init(ddev); + ret = msm_init_vram(ddev); + if (ret) + goto err_destroy_mdss; + /* Bind all our sub-components: */ ret = component_bind_all(dev, ddev); if (ret) goto err_destroy_mdss; - ret = msm_init_vram(ddev); - if (ret) - goto err_msm_uninit; + if (!dev->dma_parms) { + dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), + GFP_KERNEL); + if (!dev->dma_parms) { + ret = -ENOMEM; + goto err_msm_uninit; + } + } + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); msm_gem_shrinker_init(ddev); @@ -557,6 +567,7 @@ kfree(priv); err_put_drm_dev: drm_dev_put(ddev); + platform_set_drvdata(pdev, NULL); return ret; } @@ -1313,6 +1324,17 @@ return 0; } +static void msm_pdev_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + struct msm_drm_private *priv = drm ? drm->dev_private : NULL; + + if (!priv || !priv->kms) + return; + + drm_atomic_helper_shutdown(drm); +} + static const struct of_device_id dt_match[] = { { .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 }, { .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 }, @@ -1324,6 +1346,7 @@ static struct platform_driver msm_platform_driver = { .probe = msm_pdev_probe, .remove = msm_pdev_remove, + .shutdown = msm_pdev_shutdown, .driver = { .name = "msm", .of_match_table = dt_match, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_fence.c @@ -20,7 +20,7 @@ return ERR_PTR(-ENOMEM); fctx->dev = dev; - strncpy(fctx->name, name, sizeof(fctx->name)); + strscpy(fctx->name, name, sizeof(fctx->name)); fctx->context = dma_fence_context_alloc(1); init_waitqueue_head(&fctx->event); spin_lock_init(&fctx->spinlock); @@ -45,7 +45,7 @@ int ret; if (fence > fctx->last_fence) { - DRM_ERROR("%s: waiting on invalid fence: %u (of %u)\n", + DRM_ERROR_RATELIMITED("%s: waiting on invalid fence: %u (of %u)\n", fctx->name, fence, fctx->last_fence); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_gem.c @@ -977,10 +977,8 @@ static int msm_gem_new_impl(struct drm_device *dev, uint32_t size, uint32_t flags, - struct drm_gem_object **obj, - bool struct_mutex_locked) + struct drm_gem_object **obj) { - struct msm_drm_private *priv = dev->dev_private; struct msm_gem_object *msm_obj; switch (flags & MSM_BO_CACHE_MASK) { @@ -1006,15 +1004,6 @@ INIT_LIST_HEAD(&msm_obj->submit_entry); INIT_LIST_HEAD(&msm_obj->vmas); - if (struct_mutex_locked) { - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - list_add_tail(&msm_obj->mm_list, &priv->inactive_list); - } else { - mutex_lock(&dev->struct_mutex); - list_add_tail(&msm_obj->mm_list, &priv->inactive_list); - mutex_unlock(&dev->struct_mutex); - } - *obj = &msm_obj->base; return 0; @@ -1024,6 +1013,7 @@ uint32_t size, uint32_t flags, bool struct_mutex_locked) { struct msm_drm_private *priv = dev->dev_private; + struct msm_gem_object *msm_obj; struct drm_gem_object *obj = NULL; bool use_vram = false; int ret; @@ -1044,14 +1034,15 @@ if (size == 0) return ERR_PTR(-EINVAL); - ret = msm_gem_new_impl(dev, size, flags, &obj, struct_mutex_locked); + ret = msm_gem_new_impl(dev, size, flags, &obj); if (ret) - goto fail; + return ERR_PTR(ret); + + msm_obj = to_msm_bo(obj); if (use_vram) { struct msm_gem_vma *vma; struct page **pages; - struct msm_gem_object *msm_obj = to_msm_bo(obj); mutex_lock(&msm_obj->lock); @@ -1086,6 +1077,15 @@ mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER); } + if (struct_mutex_locked) { + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + } else { + mutex_lock(&dev->struct_mutex); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + mutex_unlock(&dev->struct_mutex); + } + return obj; fail: @@ -1108,6 +1108,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, struct dma_buf *dmabuf, struct sg_table *sgt) { + struct msm_drm_private *priv = dev->dev_private; struct msm_gem_object *msm_obj; struct drm_gem_object *obj; uint32_t size; @@ -1121,9 +1122,9 @@ size = PAGE_ALIGN(dmabuf->size); - ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj, false); + ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj); if (ret) - goto fail; + return ERR_PTR(ret); drm_gem_private_object_init(dev, obj, size); @@ -1146,6 +1147,11 @@ } mutex_unlock(&msm_obj->lock); + + mutex_lock(&dev->struct_mutex); + list_add_tail(&msm_obj->mm_list, &priv->inactive_list); + mutex_unlock(&dev->struct_mutex); + return obj; fail: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_gem_prime.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_gem_prime.c @@ -17,7 +17,7 @@ int npages = obj->size >> PAGE_SHIFT; if (WARN_ON(!msm_obj->pages)) /* should have already pinned! */ - return NULL; + return ERR_PTR(-ENOMEM); return drm_prime_pages_to_sg(msm_obj->pages, npages); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_gpu.c @@ -16,6 +16,7 @@ #include #include #include +#include /* * Power Management: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_rd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_rd.c @@ -191,6 +191,9 @@ file->private_data = rd; rd->open = true; + /* Reset fifo to clear any previously unread data: */ + rd->fifo.head = rd->fifo.tail = 0; + /* the parsing tools need to know gpu-id to know which * register database to load. */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_ringbuffer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -27,7 +27,8 @@ ring->id = id; ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ, - MSM_BO_WC, gpu->aspace, &ring->bo, &ring->iova); + MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace, &ring->bo, + &ring->iova); if (IS_ERR(ring->start)) { ret = PTR_ERR(ring->start); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/msm/msm_submitqueue.c +++ linux-oracle-5.4.0/drivers/gpu/drm/msm/msm_submitqueue.c @@ -71,8 +71,10 @@ queue->flags = flags; if (priv->gpu) { - if (prio >= priv->gpu->nr_rings) + if (prio >= priv->gpu->nr_rings) { + kfree(queue); return -EINVAL; + } queue->prio = prio; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mxsfb/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/mxsfb/Kconfig @@ -8,9 +8,9 @@ tristate "i.MX23/i.MX28/i.MX6SX MXSFB LCD controller" depends on DRM && OF depends on COMMON_CLK + depends on ARCH_MXS || ARCH_MXC || COMPILE_TEST select DRM_MXS select DRM_KMS_HELPER - select DRM_KMS_FB_HELPER select DRM_KMS_CMA_HELPER select DRM_PANEL help --- linux-oracle-5.4.0.orig/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -87,8 +88,26 @@ clk_disable_unprepare(mxsfb->clk_axi); } +static struct drm_framebuffer * +mxsfb_fb_create(struct drm_device *dev, struct drm_file *file_priv, + const struct drm_mode_fb_cmd2 *mode_cmd) +{ + const struct drm_format_info *info; + + info = drm_get_format_info(dev, mode_cmd); + if (!info) + return ERR_PTR(-EINVAL); + + if (mode_cmd->width * info->cpp[0] != mode_cmd->pitches[0]) { + dev_dbg(dev->dev, "Invalid pitch: fb width must match pitch\n"); + return ERR_PTR(-EINVAL); + } + + return drm_gem_fb_create(dev, file_priv, mode_cmd); +} + static const struct drm_mode_config_funcs mxsfb_mode_config_funcs = { - .fb_create = drm_gem_fb_create, + .fb_create = mxsfb_fb_create, .atomic_check = drm_atomic_helper_check, .atomic_commit = drm_atomic_helper_commit, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -179,7 +179,7 @@ nvif_notify_fini(&disp->flip); nouveau_display(dev)->priv = NULL; - kfree(disp); + vfree(disp); nvif_object_unmap(&drm->client.device.object); } @@ -197,7 +197,7 @@ struct nv04_display *disp; int i, ret; - disp = kzalloc(sizeof(*disp), GFP_KERNEL); + disp = vzalloc(sizeof(*disp)); if (!disp) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -208,6 +208,8 @@ struct drm_display_mode *mode; mode = drm_mode_duplicate(encoder->dev, tv_mode); + if (!mode) + continue; mode->clock = tv_norm->tv_enc_mode.vrefresh * mode->htotal / 1000 * @@ -257,6 +259,8 @@ if (modes[i].hdisplay == output_mode->hdisplay && modes[i].vdisplay == output_mode->vdisplay) { mode = drm_mode_duplicate(encoder->dev, output_mode); + if (!mode) + continue; mode->type |= DRM_MODE_TYPE_PREFERRED; } else { @@ -264,6 +268,8 @@ modes[i].vdisplay, 60, false, (output_mode->flags & DRM_MODE_FLAG_INTERLACE), false); + if (!mode) + continue; } /* CVT modes are sometimes unsuitable... */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -114,6 +114,7 @@ u8 nhsync:1; u8 nvsync:1; u8 depth:4; + u8 bpc; } or; /* Currently only used for MST */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/core.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/core.h @@ -6,6 +6,7 @@ struct nv50_core { const struct nv50_core_func *func; struct nv50_dmac chan; + bool assign_windows; }; int nv50_core_new(struct nouveau_drm *, struct nv50_core **); @@ -18,6 +19,10 @@ struct nvif_device *); void (*update)(struct nv50_core *, u32 *interlock, bool ntfy); + struct { + void (*owner)(struct nv50_core *); + } wndw; + const struct nv50_head_func *head; const struct nv50_outp_func { void (*ctrl)(struct nv50_core *, int or, u32 ctrl, @@ -48,6 +53,7 @@ int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **); int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *); void corec37d_update(struct nv50_core *, u32 *, bool); +void corec37d_wndw_owner(struct nv50_core *); extern const struct nv50_outp_func sorc37d; int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/corec37d.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/corec37d.c @@ -25,6 +25,20 @@ #include void +corec37d_wndw_owner(struct nv50_core *core) +{ + const u32 windows = 8; /*XXX*/ + u32 *push, i; + if ((push = evo_wait(&core->chan, 2 * windows))) { + for (i = 0; i < windows; i++) { + evo_mthd(push, 0x1000 + (i * 0x080), 1); + evo_data(push, i >> 1); + } + evo_kick(push, &core->chan); + } +} + +void corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy) { u32 *push; @@ -76,20 +90,18 @@ { const u32 windows = 8; /*XXX*/ u32 *push, i; - if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) { + if ((push = evo_wait(&core->chan, 2 + 5 * windows))) { evo_mthd(push, 0x0208, 1); evo_data(push, core->chan.sync.handle); for (i = 0; i < windows; i++) { - evo_mthd(push, 0x1000 + (i * 0x080), 3); - evo_data(push, i >> 1); + evo_mthd(push, 0x1004 + (i * 0x080), 2); evo_data(push, 0x0000001f); evo_data(push, 0x00000000); evo_mthd(push, 0x1010 + (i * 0x080), 1); evo_data(push, 0x00127fff); } - evo_mthd(push, 0x0200, 1); - evo_data(push, 0x00000001); evo_kick(push, &core->chan); + core->assign_windows = true; } } @@ -99,6 +111,7 @@ .ntfy_init = corec37d_ntfy_init, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, + .wndw.owner = corec37d_wndw_owner, .head = &headc37d, .sor = &sorc37d, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/corec57d.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/corec57d.c @@ -27,20 +27,18 @@ { const u32 windows = 8; /*XXX*/ u32 *push, i; - if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) { + if ((push = evo_wait(&core->chan, 2 + 5 * windows))) { evo_mthd(push, 0x0208, 1); evo_data(push, core->chan.sync.handle); for (i = 0; i < windows; i++) { - evo_mthd(push, 0x1000 + (i * 0x080), 3); - evo_data(push, i >> 1); + evo_mthd(push, 0x1004 + (i * 0x080), 2); evo_data(push, 0x0000000f); evo_data(push, 0x00000000); evo_mthd(push, 0x1010 + (i * 0x080), 1); evo_data(push, 0x00117fff); } - evo_mthd(push, 0x0200, 1); - evo_data(push, 0x00000001); evo_kick(push, &core->chan); + core->assign_windows = true; } } @@ -50,6 +48,7 @@ .ntfy_init = corec37d_ntfy_init, .ntfy_wait_done = corec37d_ntfy_wait_done, .update = corec37d_update, + .wndw.owner = corec37d_wndw_owner, .head = &headc57d, .sor = &sorc37d, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -132,7 +132,7 @@ int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, - const s32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, + const s32 *oclass, u8 head, void *data, u32 size, s64 syncbuf, struct nv50_dmac *dmac) { struct nouveau_cli *cli = (void *)device->object.client; @@ -167,7 +167,7 @@ if (ret) return ret; - if (!syncbuf) + if (syncbuf < 0) return 0; ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY, @@ -326,9 +326,9 @@ * same size as the native one (e.g. different * refresh rate) */ - if (adjusted_mode->hdisplay == native_mode->hdisplay && - adjusted_mode->vdisplay == native_mode->vdisplay && - adjusted_mode->type & DRM_MODE_TYPE_DRIVER) + if (mode->hdisplay == native_mode->hdisplay && + mode->vdisplay == native_mode->vdisplay && + mode->type & DRM_MODE_TYPE_DRIVER) break; mode = native_mode; asyc->scaler.full = true; @@ -353,10 +353,20 @@ struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct nouveau_connector *nv_connector = - nouveau_connector(conn_state->connector); - return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, - nv_connector->native_mode); + struct drm_connector *connector = conn_state->connector; + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); + int ret; + + ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, + nv_connector->native_mode); + if (ret) + return ret; + + if (crtc_state->mode_changed || crtc_state->connectors_changed) + asyh->or.bpc = connector->display_info.bpc; + + return 0; } /****************************************************************************** @@ -770,32 +780,54 @@ struct nv50_mstm *mstm = mstc->mstm; struct nv50_head_atom *asyh = nv50_head_atom(crtc_state); int slots; + int ret; + + ret = nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, + mstc->native); + if (ret) + return ret; + + if (!crtc_state->mode_changed && !crtc_state->connectors_changed) + return 0; + + /* + * When restoring duplicated states, we need to make sure that the bw + * remains the same and avoid recalculating it, as the connector's bpc + * may have changed after the state was duplicated + */ + if (!state->duplicated) { + const int clock = crtc_state->adjusted_mode.clock; - if (crtc_state->mode_changed || crtc_state->connectors_changed) { /* - * When restoring duplicated states, we need to make sure that - * the bw remains the same and avoid recalculating it, as the - * connector's bpc may have changed after the state was - * duplicated + * XXX: Since we don't use HDR in userspace quite yet, limit + * the bpc to 8 to save bandwidth on the topology. In the + * future, we'll want to properly fix this by dynamically + * selecting the highest possible bpc that would fit in the + * topology */ - if (!state->duplicated) { - const int bpp = connector->display_info.bpc * 3; - const int clock = crtc_state->adjusted_mode.clock; + asyh->or.bpc = min(connector->display_info.bpc, 8U); + asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3); + } - asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, bpp); - } + slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, mstc->port, + asyh->dp.pbn); + if (slots < 0) + return slots; - slots = drm_dp_atomic_find_vcpi_slots(state, &mstm->mgr, - mstc->port, - asyh->dp.pbn); - if (slots < 0) - return slots; + asyh->dp.tu = slots; - asyh->dp.tu = slots; - } + return 0; +} - return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, - mstc->native); +static u8 +nv50_dp_bpc_to_depth(unsigned int bpc) +{ + switch (bpc) { + case 6: return 0x2; + case 8: return 0x5; + case 10: /* fall-through */ + default: return 0x6; + } } static void @@ -808,7 +840,7 @@ struct nv50_mstm *mstm = NULL; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - u8 proto, depth; + u8 proto; bool r; drm_connector_list_iter_begin(encoder->dev, &conn_iter); @@ -837,14 +869,8 @@ else proto = 0x9; - switch (mstc->connector.display_info.bpc) { - case 6: depth = 0x2; break; - case 8: depth = 0x5; break; - case 10: - default: depth = 0x6; break; - } - - mstm->outp->update(mstm->outp, head->base.index, armh, proto, depth); + mstm->outp->update(mstm->outp, head->base.index, armh, proto, + nv50_dp_bpc_to_depth(armh->or.bpc)); msto->head = head; msto->mstc = mstc; @@ -1006,8 +1032,10 @@ return connector_status_disconnected; ret = pm_runtime_get_sync(connector->dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } conn_status = drm_dp_mst_detect_port(connector, mstc->port->mgr, mstc->port); @@ -1498,20 +1526,14 @@ lvds.lvds.script |= 0x0200; } - if (nv_connector->base.display_info.bpc == 8) + if (asyh->or.bpc == 8) lvds.lvds.script |= 0x0200; } nvif_mthd(&disp->disp->object, 0, &lvds, sizeof(lvds)); break; case DCB_OUTPUT_DP: - if (nv_connector->base.display_info.bpc == 6) - depth = 0x2; - else - if (nv_connector->base.display_info.bpc == 8) - depth = 0x5; - else - depth = 0x6; + depth = nv50_dp_bpc_to_depth(asyh->or.bpc); if (nv_encoder->link & 1) proto = 0x8; @@ -1662,7 +1684,7 @@ nv50_outp_acquire(nv_encoder); nv_connector = nouveau_encoder_connector_get(nv_encoder); - switch (nv_connector->base.display_info.bpc) { + switch (asyh->or.bpc) { case 10: asyh->or.depth = 0x6; break; case 8: asyh->or.depth = 0x5; break; case 6: asyh->or.depth = 0x2; break; @@ -1812,6 +1834,7 @@ struct nouveau_drm *drm = nouveau_drm(dev); struct nv50_disp *disp = nv50_disp(dev); struct nv50_atom *atom = nv50_atom(state); + struct nv50_core *core = disp->core; struct nv50_outp_atom *outp, *outt; u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {}; int i; @@ -1930,6 +1953,21 @@ } } + /* Update window->head assignment. + * + * This has to happen in an update that's not interlocked with + * any window channels to avoid hitting HW error checks. + * + *TODO: Proper handling of window ownership (Turing apparently + * supports non-fixed mappings). + */ + if (core->assign_windows) { + core->func->wndw.owner(core); + core->func->update(core, interlock, false); + core->assign_windows = false; + interlock[NV50_DISP_INTERLOCK_CORE] = 0; + } + /* Update plane(s). */ for_each_new_plane_in_state(state, plane, new_plane_state, i) { struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); @@ -2012,8 +2050,10 @@ int ret, i; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } ret = drm_atomic_helper_setup_commit(state, nonblock); if (ret) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/disp.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/disp.h @@ -70,7 +70,7 @@ int nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, const s32 *oclass, u8 head, void *data, u32 size, - u64 syncbuf, struct nv50_dmac *dmac); + s64 syncbuf, struct nv50_dmac *dmac); void nv50_dmac_destroy(struct nv50_dmac *); u32 *evo_wait(struct nv50_dmac *, int nr); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/head.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -81,21 +81,22 @@ struct nv50_head_atom *asyh, struct nouveau_conn_atom *asyc) { - struct drm_connector *connector = asyc->state.connector; u32 mode = 0x00; - if (asyc->dither.mode == DITHERING_MODE_AUTO) { - if (asyh->base.depth > connector->display_info.bpc * 3) - mode = DITHERING_MODE_DYNAMIC2X2; - } else { - mode = asyc->dither.mode; - } + if (asyc->dither.mode) { + if (asyc->dither.mode == DITHERING_MODE_AUTO) { + if (asyh->base.depth > asyh->or.bpc * 3) + mode = DITHERING_MODE_DYNAMIC2X2; + } else { + mode = asyc->dither.mode; + } - if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { - if (connector->display_info.bpc >= 8) - mode |= DITHERING_DEPTH_8BPC; - } else { - mode |= asyc->dither.depth; + if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { + if (asyh->or.bpc >= 8) + mode |= DITHERING_DEPTH_8BPC; + } else { + mode |= asyc->dither.depth; + } } asyh->dither.enable = mode; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c @@ -68,7 +68,7 @@ int ret; ret = nv50_dmac_create(&drm->client.device, &disp->disp->object, - &oclass, 0, &args, sizeof(args), 0, + &oclass, 0, &args, sizeof(args), -1, &wndw->wimm); if (ret) { NV_ERROR(drm, "wimm%04x allocation failed: %d\n", oclass, ret); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -451,6 +451,8 @@ asyw->clr.ntfy = armw->ntfy.handle != 0; asyw->clr.sema = armw->sema.handle != 0; asyw->clr.xlut = armw->xlut.handle != 0; + if (asyw->clr.xlut && asyw->visible) + asyw->set.xlut = asyw->xlut.handle != 0; asyw->clr.csc = armw->csc.valid; if (wndw->func->image_clr) asyw->clr.image = armw->image.handle[0] != 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h @@ -14,6 +14,7 @@ DCB_CONNECTOR_LVDS_SPWG = 0x41, DCB_CONNECTOR_DP = 0x46, DCB_CONNECTOR_eDP = 0x47, + DCB_CONNECTOR_mDP = 0x48, DCB_CONNECTOR_HDMI_0 = 0x60, DCB_CONNECTOR_HDMI_1 = 0x61, DCB_CONNECTOR_HDMI_C = 0x63, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -51,8 +51,9 @@ nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], struct nouveau_backlight *bl) { - const int nb = ida_simple_get(&bl_ida, 0, 0, GFP_KERNEL); - if (nb < 0 || nb >= 100) + const int nb = ida_alloc_max(&bl_ida, 99, GFP_KERNEL); + + if (nb < 0) return false; if (nb > 0) snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); @@ -280,7 +281,7 @@ nv_encoder, ops, &props); if (IS_ERR(bl->dev)) { if (bl->id >= 0) - ida_simple_remove(&bl_ida, bl->id); + ida_free(&bl_ida, bl->id); ret = PTR_ERR(bl->dev); goto fail_alloc; } @@ -306,7 +307,7 @@ return; if (bl->id >= 0) - ida_simple_remove(&bl_ida, bl->id); + ida_free(&bl_ida, bl->id); backlight_device_unregister(bl->dev); nv_conn->backlight = NULL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_bios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -23,6 +23,7 @@ */ #include "nouveau_drv.h" +#include "nouveau_bios.h" #include "nouveau_reg.h" #include "dispnv04/hw.h" #include "nouveau_encoder.h" @@ -1672,7 +1673,7 @@ */ if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) { if (*conn == 0xf2005014 && *conf == 0xffffffff) { - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1); + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B); return false; } } @@ -1758,26 +1759,26 @@ #ifdef __powerpc__ /* Apple iMac G4 NV17 */ if (of_machine_is_compatible("PowerMac4,5")) { - fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1); - fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2); + fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, DCB_OUTPUT_B); + fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, DCB_OUTPUT_C); return; } #endif /* Make up some sane defaults */ fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, - bios->legacy.i2c_indices.crt, 1, 1); + bios->legacy.i2c_indices.crt, 1, DCB_OUTPUT_B); if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) fabricate_dcb_output(dcb, DCB_OUTPUT_TV, bios->legacy.i2c_indices.tv, - all_heads, 0); + all_heads, DCB_OUTPUT_A); else if (bios->tmds.output0_script_ptr || bios->tmds.output1_script_ptr) fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, bios->legacy.i2c_indices.panel, - all_heads, 1); + all_heads, DCB_OUTPUT_B); } static int --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_bo.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -276,8 +276,10 @@ break; } - if (WARN_ON(pi < 0)) + if (WARN_ON(pi < 0)) { + kfree(nvbo); return ERR_PTR(-EINVAL); + } /* Disable compression if suitable settings couldn't be found. */ if (nvbo->comp && !vmm->page[pi].comp) { @@ -542,7 +544,7 @@ struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ @@ -562,7 +564,7 @@ struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_chan.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -497,6 +497,7 @@ if (ret) { NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret); nouveau_channel_del(pchan); + goto done; } ret = nouveau_svmm_join((*pchan)->vmm->svmm, (*pchan)->inst); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_connector.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -245,14 +245,22 @@ void nouveau_conn_reset(struct drm_connector *connector) { + struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_conn_atom *asyc; - if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) - return; + if (drm_drv_uses_atomic_modeset(connector->dev)) { + if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) + return; + + if (connector->state) + nouveau_conn_atomic_destroy_state(connector, + connector->state); + + __drm_atomic_helper_connector_reset(connector, &asyc->state); + } else { + asyc = &nv_connector->properties_state; + } - if (connector->state) - nouveau_conn_atomic_destroy_state(connector, connector->state); - __drm_atomic_helper_connector_reset(connector, &asyc->state); asyc->dither.mode = DITHERING_MODE_AUTO; asyc->dither.depth = DITHERING_DEPTH_AUTO; asyc->scaler.mode = DRM_MODE_SCALE_NONE; @@ -276,8 +284,14 @@ nouveau_conn_attach_properties(struct drm_connector *connector) { struct drm_device *dev = connector->dev; - struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); struct nouveau_display *disp = nouveau_display(dev); + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct nouveau_conn_atom *armc; + + if (drm_drv_uses_atomic_modeset(connector->dev)) + armc = nouveau_conn_atom(connector->state); + else + armc = &nv_connector->properties_state; /* Init DVI-I specific properties. */ if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) @@ -524,6 +538,19 @@ } } +static void +nouveau_connector_set_edid(struct nouveau_connector *nv_connector, + struct edid *edid) +{ + if (nv_connector->edid != edid) { + struct edid *old_edid = nv_connector->edid; + + drm_connector_update_edid_property(&nv_connector->base, edid); + kfree(old_edid); + nv_connector->edid = edid; + } +} + static enum drm_connector_status nouveau_connector_detect(struct drm_connector *connector, bool force) { @@ -537,13 +564,6 @@ int ret; enum drm_connector_status conn_status = connector_status_disconnected; - /* Cleanup the previous EDID block. */ - if (nv_connector->edid) { - drm_connector_update_edid_property(connector, NULL); - kfree(nv_connector->edid); - nv_connector->edid = NULL; - } - /* Outputs are only polled while runtime active, so resuming the * device here is unnecessary (and would deadlock upon runtime suspend * because it waits for polling to finish). We do however, want to @@ -554,22 +574,25 @@ pm_runtime_get_noresume(dev->dev); } else { ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev->dev); + nouveau_connector_set_edid(nv_connector, NULL); return conn_status; + } } nv_encoder = nouveau_connector_ddc_detect(connector); if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) { + struct edid *new_edid; + if ((vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) && nv_connector->type == DCB_CONNECTOR_LVDS) - nv_connector->edid = drm_get_edid_switcheroo(connector, - i2c); + new_edid = drm_get_edid_switcheroo(connector, i2c); else - nv_connector->edid = drm_get_edid(connector, i2c); + new_edid = drm_get_edid(connector, i2c); - drm_connector_update_edid_property(connector, - nv_connector->edid); + nouveau_connector_set_edid(nv_connector, new_edid); if (!nv_connector->edid) { NV_ERROR(drm, "DDC responded, but no EDID for %s\n", connector->name); @@ -603,6 +626,8 @@ conn_status = connector_status_connected; drm_dp_cec_set_edid(&nv_connector->aux, nv_connector->edid); goto out; + } else { + nouveau_connector_set_edid(nv_connector, NULL); } nv_encoder = nouveau_connector_of_detect(connector); @@ -645,24 +670,20 @@ struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = NULL; + struct edid *edid = NULL; enum drm_connector_status status = connector_status_disconnected; - /* Cleanup the previous EDID block. */ - if (nv_connector->edid) { - drm_connector_update_edid_property(connector, NULL); - kfree(nv_connector->edid); - nv_connector->edid = NULL; - } - nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); if (!nv_encoder) - return connector_status_disconnected; + goto out; /* Try retrieving EDID via DDC */ if (!drm->vbios.fp_no_ddc) { status = nouveau_connector_detect(connector, force); - if (status == connector_status_connected) + if (status == connector_status_connected) { + edid = nv_connector->edid; goto out; + } } /* On some laptops (Sony, i'm looking at you) there appears to @@ -675,7 +696,8 @@ * valid - it's not (rh#613284) */ if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { - if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { + edid = nouveau_acpi_edid(dev, connector); + if (edid) { status = connector_status_connected; goto out; } @@ -695,12 +717,10 @@ * stored for the panel stored in them. */ if (!drm->vbios.fp_no_ddc) { - struct edid *edid = - (struct edid *)nouveau_bios_embedded_edid(dev); + edid = (struct edid *)nouveau_bios_embedded_edid(dev); if (edid) { - nv_connector->edid = - kmemdup(edid, EDID_LENGTH, GFP_KERNEL); - if (nv_connector->edid) + edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL); + if (edid) status = connector_status_connected; } } @@ -713,8 +733,9 @@ status = connector_status_unknown; #endif - drm_connector_update_edid_property(connector, nv_connector->edid); - nouveau_connector_set_encoder(connector, nv_encoder); + nouveau_connector_set_edid(nv_connector, edid); + if (nv_encoder) + nouveau_connector_set_encoder(connector, nv_encoder); return status; } @@ -749,9 +770,9 @@ nouveau_connector_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { - struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state); struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; + struct nouveau_conn_atom *asyc = &nv_connector->properties_state; struct drm_encoder *encoder = to_drm_encoder(nv_encoder); int ret; @@ -947,6 +968,9 @@ struct drm_display_mode *mode; mode = drm_mode_duplicate(dev, nv_connector->native_mode); + if (!mode) + return 0; + drm_mode_probed_add(connector, mode); ret = 1; } @@ -955,7 +979,7 @@ * "native" mode as some VBIOS tables require us to use the * pixel clock as part of the lookup... */ - if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) + if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && nv_connector->native_mode) nouveau_connector_detect_depth(connector); if (nv_encoder->dcb->type == DCB_OUTPUT_TV) @@ -1131,6 +1155,16 @@ const char *name = connector->name; struct nouveau_encoder *nv_encoder; int ret; + bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); + + if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { + NV_DEBUG(drm, "service %s\n", name); + drm_dp_cec_irq(&nv_connector->aux); + if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) + nv50_mstm_service(nv_encoder->dp.mstm); + + return NVIF_NOTIFY_KEEP; + } ret = pm_runtime_get(drm->dev->dev); if (ret == 0) { @@ -1151,25 +1185,16 @@ return NVIF_NOTIFY_DROP; } - if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { - NV_DEBUG(drm, "service %s\n", name); - drm_dp_cec_irq(&nv_connector->aux); - if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) - nv50_mstm_service(nv_encoder->dp.mstm); - } else { - bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); - + if (!plugged) + drm_dp_cec_unset_edid(&nv_connector->aux); + NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); + if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) { if (!plugged) - drm_dp_cec_unset_edid(&nv_connector->aux); - NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); - if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) { - if (!plugged) - nv50_mstm_remove(nv_encoder->dp.mstm); - } - - drm_helper_hpd_irq_event(connector->dev); + nv50_mstm_remove(nv_encoder->dp.mstm); } + drm_helper_hpd_irq_event(connector->dev); + pm_runtime_mark_last_busy(drm->dev->dev); pm_runtime_put_autosuspend(drm->dev->dev); return NVIF_NOTIFY_KEEP; @@ -1223,6 +1248,7 @@ case DCB_CONNECTOR_DMS59_DP0: case DCB_CONNECTOR_DMS59_DP1: case DCB_CONNECTOR_DP : + case DCB_CONNECTOR_mDP : case DCB_CONNECTOR_USB_C : return DRM_MODE_CONNECTOR_DisplayPort; case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; case DCB_CONNECTOR_HDMI_0 : --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_connector.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -29,6 +29,7 @@ #include +#include #include #include #include @@ -44,6 +45,60 @@ struct nouveau_backlight; #endif +#define nouveau_conn_atom(p) \ + container_of((p), struct nouveau_conn_atom, state) + +struct nouveau_conn_atom { + struct drm_connector_state state; + + struct { + /* The enum values specifically defined here match nv50/gf119 + * hw values, and the code relies on this. + */ + enum { + DITHERING_MODE_OFF = 0x00, + DITHERING_MODE_ON = 0x01, + DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, + DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, + DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, + DITHERING_MODE_AUTO + } mode; + enum { + DITHERING_DEPTH_6BPC = 0x00, + DITHERING_DEPTH_8BPC = 0x02, + DITHERING_DEPTH_AUTO + } depth; + } dither; + + struct { + int mode; /* DRM_MODE_SCALE_* */ + struct { + enum { + UNDERSCAN_OFF, + UNDERSCAN_ON, + UNDERSCAN_AUTO, + } mode; + u32 hborder; + u32 vborder; + } underscan; + bool full; + } scaler; + + struct { + int color_vibrance; + int vibrant_hue; + } procamp; + + union { + struct { + bool dither:1; + bool scaler:1; + bool procamp:1; + }; + u8 mask; + } set; +}; + struct nouveau_connector { struct drm_connector base; enum dcb_connector_type type; @@ -63,6 +118,12 @@ #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT struct nouveau_backlight *backlight; #endif + /* + * Our connector property code expects a nouveau_conn_atom struct + * even on pre-nv50 where we do not support atomic. This embedded + * version gets used in the non atomic modeset case. + */ + struct nouveau_conn_atom properties_state; }; static inline struct nouveau_connector *nouveau_connector( @@ -121,61 +182,6 @@ extern int nouveau_duallink; extern int nouveau_hdmimhz; -#include -#define nouveau_conn_atom(p) \ - container_of((p), struct nouveau_conn_atom, state) - -struct nouveau_conn_atom { - struct drm_connector_state state; - - struct { - /* The enum values specifically defined here match nv50/gf119 - * hw values, and the code relies on this. - */ - enum { - DITHERING_MODE_OFF = 0x00, - DITHERING_MODE_ON = 0x01, - DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, - DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, - DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, - DITHERING_MODE_AUTO - } mode; - enum { - DITHERING_DEPTH_6BPC = 0x00, - DITHERING_DEPTH_8BPC = 0x02, - DITHERING_DEPTH_AUTO - } depth; - } dither; - - struct { - int mode; /* DRM_MODE_SCALE_* */ - struct { - enum { - UNDERSCAN_OFF, - UNDERSCAN_ON, - UNDERSCAN_AUTO, - } mode; - u32 hborder; - u32 vborder; - } underscan; - bool full; - } scaler; - - struct { - int color_vibrance; - int vibrant_hue; - } procamp; - - union { - struct { - bool dither:1; - bool scaler:1; - bool procamp:1; - }; - u8 mask; - } set; -}; - void nouveau_conn_attach_properties(struct drm_connector *); void nouveau_conn_reset(struct drm_connector *); struct drm_connector_state * --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -54,8 +54,10 @@ int ret; ret = pm_runtime_get_sync(drm->dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(drm->dev->dev); return ret; + } seq_printf(m, "0x%08x\n", nvif_rd32(&drm->client.device.object, 0x101000)); @@ -181,8 +183,11 @@ } ret = pm_runtime_get_sync(drm->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(drm->dev); return ret; + } + ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args)); pm_runtime_put_autosuspend(drm->dev); if (ret < 0) @@ -202,6 +207,7 @@ .open = nouveau_debugfs_pstate_open, .read = seq_read, .write = nouveau_debugfs_pstate_set, + .release = single_release, }; static struct drm_info_list nouveau_debugfs_list[] = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -139,7 +139,7 @@ if (!spage || !(args->src[0] & MIGRATE_PFN_MIGRATE)) return 0; - dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address); + dpage = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vmf->vma, vmf->address); if (!dpage) return VM_FAULT_SIGBUS; lock_page(dpage); @@ -635,10 +635,10 @@ unsigned long c, i; int ret = -ENOMEM; - args.src = kcalloc(max, sizeof(args.src), GFP_KERNEL); + args.src = kcalloc(max, sizeof(*args.src), GFP_KERNEL); if (!args.src) goto out; - args.dst = kcalloc(max, sizeof(args.dst), GFP_KERNEL); + args.dst = kcalloc(max, sizeof(*args.dst), GFP_KERNEL); if (!args.dst) goto out_free_src; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_drm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -123,10 +123,16 @@ static inline bool nouveau_cli_work_ready(struct dma_fence *fence) { - if (!dma_fence_is_signaled(fence)) - return false; - dma_fence_put(fence); - return true; + bool ret = true; + + spin_lock_irq(fence->lock); + if (!dma_fence_is_signaled_locked(fence)) + ret = false; + spin_unlock_irq(fence->lock); + + if (ret == true) + dma_fence_put(fence); + return ret; } static void @@ -520,6 +526,7 @@ nvkm_dbgopt(nouveau_debug, "DRM"); INIT_LIST_HEAD(&drm->clients); + mutex_init(&drm->clients_lock); spin_lock_init(&drm->tile.lock); /* workaround an odd issue on nvc1 by disabling the device's @@ -589,6 +596,7 @@ static void nouveau_drm_device_fini(struct drm_device *dev) { + struct nouveau_cli *cli, *temp_cli; struct nouveau_drm *drm = nouveau_drm(dev); if (nouveau_pmops_runtime()) { @@ -613,11 +621,88 @@ nouveau_ttm_fini(drm); nouveau_vga_fini(drm); + /* + * There may be existing clients from as-yet unclosed files. For now, + * clean them up here rather than deferring until the file is closed, + * but this likely not correct if we want to support hot-unplugging + * properly. + */ + mutex_lock(&drm->clients_lock); + list_for_each_entry_safe(cli, temp_cli, &drm->clients, head) { + list_del(&cli->head); + mutex_lock(&cli->mutex); + if (cli->abi16) + nouveau_abi16_fini(cli->abi16); + mutex_unlock(&cli->mutex); + nouveau_cli_fini(cli); + kfree(cli); + } + mutex_unlock(&drm->clients_lock); + nouveau_cli_fini(&drm->client); nouveau_cli_fini(&drm->master); + mutex_destroy(&drm->clients_lock); kfree(drm); } +/* + * On some Intel PCIe bridge controllers doing a + * D0 -> D3hot -> D3cold -> D0 sequence causes Nvidia GPUs to not reappear. + * Skipping the intermediate D3hot step seems to make it work again. This is + * probably caused by not meeting the expectation the involved AML code has + * when the GPU is put into D3hot state before invoking it. + * + * This leads to various manifestations of this issue: + * - AML code execution to power on the GPU hits an infinite loop (as the + * code waits on device memory to change). + * - kernel crashes, as all PCI reads return -1, which most code isn't able + * to handle well enough. + * + * In all cases dmesg will contain at least one line like this: + * 'nouveau 0000:01:00.0: Refused to change power state, currently in D3' + * followed by a lot of nouveau timeouts. + * + * In the \_SB.PCI0.PEG0.PG00._OFF code deeper down writes bit 0x80 to the not + * documented PCI config space register 0x248 of the Intel PCIe bridge + * controller (0x1901) in order to change the state of the PCIe link between + * the PCIe port and the GPU. There are alternative code paths using other + * registers, which seem to work fine (executed pre Windows 8): + * - 0xbc bit 0x20 (publicly available documentation claims 'reserved') + * - 0xb0 bit 0x10 (link disable) + * Changing the conditions inside the firmware by poking into the relevant + * addresses does resolve the issue, but it seemed to be ACPI private memory + * and not any device accessible memory at all, so there is no portable way of + * changing the conditions. + * On a XPS 9560 that means bits [0,3] on \CPEX need to be cleared. + * + * The only systems where this behavior can be seen are hybrid graphics laptops + * with a secondary Nvidia Maxwell, Pascal or Turing GPU. It's unclear whether + * this issue only occurs in combination with listed Intel PCIe bridge + * controllers and the mentioned GPUs or other devices as well. + * + * documentation on the PCIe bridge controller can be found in the + * "7th Generation Intel® Processor Families for H Platforms Datasheet Volume 2" + * Section "12 PCI Express* Controller (x16) Registers" + */ + +static void quirk_broken_nv_runpm(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct pci_dev *bridge = pci_upstream_bridge(pdev); + + if (!bridge || bridge->vendor != PCI_VENDOR_ID_INTEL) + return; + + switch (bridge->device) { + case 0x1901: + drm->old_pm_cap = pdev->pm_cap; + pdev->pm_cap = 0; + NV_INFO(drm, "Disabling PCI power management to avoid bug\n"); + break; + } +} + static int nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) { @@ -699,6 +784,7 @@ if (ret) goto fail_drm_dev_init; + quirk_broken_nv_runpm(pdev); return 0; fail_drm_dev_init: @@ -720,7 +806,7 @@ struct nvkm_client *client; struct nvkm_device *device; - drm_dev_unregister(dev); + drm_dev_unplug(dev); dev->irq_enabled = false; client = nvxx_client(&drm->client.base); @@ -736,7 +822,11 @@ nouveau_drm_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_drm(dev); + /* revert our workaround */ + if (drm->old_pm_cap) + pdev->pm_cap = drm->old_pm_cap; nouveau_drm_device_remove(dev); } @@ -989,8 +1079,10 @@ /* need to bring up power immediately if opening device */ ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } get_task_comm(tmpname, current); snprintf(name, sizeof(name), "%s[%d]", tmpname, pid_nr(fpriv->pid)); @@ -1008,9 +1100,9 @@ fpriv->driver_priv = cli; - mutex_lock(&drm->client.mutex); + mutex_lock(&drm->clients_lock); list_add(&cli->head, &drm->clients); - mutex_unlock(&drm->client.mutex); + mutex_unlock(&drm->clients_lock); done: if (ret && cli) { @@ -1028,6 +1120,16 @@ { struct nouveau_cli *cli = nouveau_cli(fpriv); struct nouveau_drm *drm = nouveau_drm(dev); + int dev_index; + + /* + * The device is gone, and as it currently stands all clients are + * cleaned up in the removal codepath. In the future this may change + * so that we can support hot-unplugging, but for now we immediately + * return to avoid a double-free situation. + */ + if (!drm_dev_enter(dev, &dev_index)) + return; pm_runtime_get_sync(dev->dev); @@ -1036,14 +1138,15 @@ nouveau_abi16_fini(cli->abi16); mutex_unlock(&cli->mutex); - mutex_lock(&drm->client.mutex); + mutex_lock(&drm->clients_lock); list_del(&cli->head); - mutex_unlock(&drm->client.mutex); + mutex_unlock(&drm->clients_lock); nouveau_cli_fini(cli); kfree(cli); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); + drm_dev_exit(dev_index); } static const struct drm_ioctl_desc @@ -1072,8 +1175,10 @@ long ret; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } switch (_IOC_NR(cmd) - DRM_COMMAND_BASE) { case DRM_NOUVEAU_NVIF: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -138,6 +138,13 @@ struct list_head clients; + /** + * @clients_lock: Protects access to the @clients list of &struct nouveau_cli. + */ + struct mutex clients_lock; + + u8 old_pm_cap; + struct { struct agp_bridge_data *bridge; u32 base; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -189,8 +189,10 @@ struct nouveau_fbdev *fbcon = info->par; struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); int ret = pm_runtime_get_sync(drm->dev->dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put(drm->dev->dev); return ret; + } return 0; } @@ -315,7 +317,7 @@ struct nouveau_framebuffer *fb; struct nouveau_channel *chan; struct nouveau_bo *nvbo; - struct drm_mode_fb_cmd2 mode_cmd; + struct drm_mode_fb_cmd2 mode_cmd = {}; int ret; mode_cmd.width = sizes->surface_width; @@ -592,6 +594,7 @@ drm_fb_helper_fini(&fbcon->helper); free: kfree(fbcon); + drm->fbcon = NULL; return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -156,7 +156,7 @@ fence = list_entry(fctx->pending.next, typeof(*fence), head); chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock)); - if (nouveau_fence_update(fence->channel, fctx)) + if (nouveau_fence_update(chan, fctx)) ret = NVIF_NOTIFY_DROP; } spin_unlock_irqrestore(&fctx->lock, flags); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -45,8 +45,10 @@ int ret; ret = pm_runtime_get_sync(dev); - if (WARN_ON(ret < 0 && ret != -EACCES)) + if (WARN_ON(ret < 0 && ret != -EACCES)) { + pm_runtime_put_autosuspend(dev); return; + } if (gem->import_attach) drm_prime_gem_destroy(gem, nvbo->bo.sg); @@ -76,8 +78,10 @@ return ret; ret = pm_runtime_get_sync(dev); - if (ret < 0 && ret != -EACCES) + if (ret < 0 && ret != -EACCES) { + pm_runtime_put_autosuspend(dev); goto out; + } ret = nouveau_vma_new(nvbo, vmm, &vma); pm_runtime_mark_last_busy(dev); @@ -193,7 +197,8 @@ * to the caller, instead of a normal nouveau_bo ttm reference. */ ret = drm_gem_object_init(drm->dev, &nvbo->bo.base, size); if (ret) { - nouveau_bo_ref(NULL, &nvbo); + drm_gem_object_release(&nvbo->bo.base); + kfree(nvbo); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_mem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -176,6 +176,8 @@ nouveau_mem_del(struct ttm_mem_reg *reg) { struct nouveau_mem *mem = nouveau_mem(reg); + if (!mem) + return; nouveau_mem_fini(mem); kfree(reg->mm_node); reg->mm_node = NULL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_prime.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -83,14 +83,14 @@ * to the caller, instead of a normal nouveau_bo ttm reference. */ ret = drm_gem_object_init(dev, &nvbo->bo.base, size); if (ret) { - nouveau_bo_ref(NULL, &nvbo); + drm_gem_object_release(&nvbo->bo.base); + kfree(nvbo); obj = ERR_PTR(-ENOMEM); goto unlock; } ret = nouveau_bo_init(nvbo, size, align, flags, sg, robj); if (ret) { - nouveau_bo_ref(NULL, &nvbo); obj = ERR_PTR(ret); goto unlock; } @@ -112,7 +112,22 @@ if (ret) return -EINVAL; - return 0; + ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); + if (ret) + goto error; + + if (nvbo->bo.moving) + ret = dma_fence_wait(nvbo->bo.moving, true); + + ttm_bo_unreserve(&nvbo->bo); + if (ret) + goto error; + + return ret; + +error: + nouveau_bo_unpin(nvbo); + return ret; } void nouveau_gem_prime_unpin(struct drm_gem_object *obj) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -96,12 +96,9 @@ else nvbe->ttm.ttm.func = &nv50_sgdma_backend; - if (ttm_dma_tt_init(&nvbe->ttm, bo, page_flags)) - /* - * A failing ttm_dma_tt_init() will call ttm_tt_destroy() - * and thus our nouveau_sgdma_destroy() hook, so we don't need - * to free nvbe here. - */ + if (ttm_dma_tt_init(&nvbe->ttm, bo, page_flags)) { + kfree(nvbe); return NULL; + } return &nvbe->ttm.ttm; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_svm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -112,11 +112,11 @@ struct nouveau_cli *cli = nouveau_cli(file_priv); struct drm_nouveau_svm_bind *args = data; unsigned target, cmd, priority; - unsigned long addr, end, size; + unsigned long addr, end; struct mm_struct *mm; args->va_start &= PAGE_MASK; - args->va_end &= PAGE_MASK; + args->va_end = ALIGN(args->va_end, PAGE_SIZE); /* Sanity check arguments */ if (args->reserved0 || args->reserved1) @@ -125,8 +125,6 @@ return -EINVAL; if (args->va_start >= args->va_end) return -EINVAL; - if (!args->npages) - return -EINVAL; cmd = args->header >> NOUVEAU_SVM_BIND_COMMAND_SHIFT; cmd &= NOUVEAU_SVM_BIND_COMMAND_MASK; @@ -158,12 +156,6 @@ if (args->stride) return -EINVAL; - size = ((unsigned long)args->npages) << PAGE_SHIFT; - if ((args->va_start + size) <= args->va_start) - return -EINVAL; - if ((args->va_start + size) > args->va_end) - return -EINVAL; - /* * Ok we are ask to do something sane, for now we only support migrate * commands but we will add things like memory policy (what to do on @@ -173,7 +165,12 @@ mm = get_task_mm(current); down_read(&mm->mmap_sem); - for (addr = args->va_start, end = args->va_start + size; addr < end;) { + if (!cli->svm.svmm) { + up_read(&mm->mmap_sem); + return -EINVAL; + } + + for (addr = args->va_start, end = args->va_end; addr < end;) { struct vm_area_struct *vma; unsigned long next; @@ -181,6 +178,7 @@ if (!vma) break; + addr = max(addr, vma->vm_start); next = min(vma->vm_end, end); /* This is a best effort so we ignore errors */ nouveau_dmem_migrate_vma(cli->drm, vma, addr, next); @@ -308,6 +306,10 @@ struct drm_nouveau_svm_init *args = data; int ret; + /* We need to fail if svm is disabled */ + if (!cli->drm->svm) + return -ENOSYS; + /* Allocate tracking for SVM-enabled VMM. */ if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL))) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -63,14 +63,12 @@ { struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_drm *drm = nouveau_bdev(bo->bdev); - struct nouveau_mem *mem; int ret; if (drm->client.device.info.ram_size == 0) return -ENOMEM; ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); - mem = nouveau_mem(reg); if (ret) return ret; @@ -103,11 +101,9 @@ { struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_drm *drm = nouveau_bdev(bo->bdev); - struct nouveau_mem *mem; int ret; ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg); - mem = nouveau_mem(reg); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -108,6 +108,9 @@ } else { ret = nvif_vmm_get(&vmm->vmm, PTES, false, mem->mem.page, 0, mem->mem.size, &tmp); + if (ret) + goto done; + vma->addr = tmp.addr; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -91,8 +91,8 @@ } refcount_set(&tags->refcount, 1); + *ptags = memory->tags = tags; mutex_unlock(&fb->subdev.mutex); - *ptags = tags; return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c @@ -57,7 +57,7 @@ args->v0.count = 0; args->v0.ustate_ac = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; args->v0.ustate_dc = NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE; - args->v0.pwrsrc = -ENOSYS; + args->v0.pwrsrc = -ENODEV; args->v0.pstate = NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -123,7 +123,7 @@ mutex_init(&tdev->iommu.mutex); - if (iommu_present(&platform_bus_type)) { + if (device_iommu_mapped(dev)) { tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); if (!tdev->iommu.domain) goto error; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c @@ -74,6 +74,8 @@ if (debug > subdev->debug) return; + if (!mthd) + return; for (i = 0; (list = mthd->data[i].mthd) != NULL; i++) { u32 base = chan->head * mthd->addr; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c @@ -419,7 +419,7 @@ return ret; } -static void +void nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) { struct nvkm_dp *dp = nvkm_dp(outp); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h @@ -32,6 +32,7 @@ int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *, struct nvkm_outp **); +void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); /* DPCD Receiver Capabilities */ #define DPCD_RC00_DPCD_REV 0x00000 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -144,6 +144,12 @@ if (stat & 0x00000008) stat &= ~0x00000008; + if (stat & 0x00000080) { + u32 error = nvkm_mask(device, 0x611848, 0x00000000, 0x00000000); + nvkm_warn(subdev, "error %08x\n", error); + stat &= ~0x00000080; + } + if (stat & 0x00000100) { unsigned long wndws = nvkm_rd32(device, 0x611858); unsigned long other = nvkm_rd32(device, 0x61185c); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigm200.c @@ -27,10 +27,10 @@ gm200_hdmi_scdc(struct nvkm_ior *ior, int head, u8 scdc) { struct nvkm_device *device = ior->disp->engine.subdev.device; - const u32 hoff = head * 0x800; + const u32 soff = nv50_ior_base(ior); const u32 ctrl = scdc & 0x3; - nvkm_mask(device, 0x61c5bc + hoff, 0x00000003, ctrl); + nvkm_mask(device, 0x61c5bc + soff, 0x00000003, ctrl); ior->tmds.high_speed = !!(scdc & 0x2); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/hdmigv100.c @@ -62,7 +62,6 @@ nvkm_wr32(device, 0x6f0108 + hdmi, vendor_infoframe.header); nvkm_wr32(device, 0x6f010c + hdmi, vendor_infoframe.subpack0_low); nvkm_wr32(device, 0x6f0110 + hdmi, vendor_infoframe.subpack0_high); - nvkm_wr32(device, 0x6f0110 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f0114 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f0118 + hdmi, 0x00000000); nvkm_wr32(device, 0x6f011c + hdmi, 0x00000000); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "outp.h" +#include "dp.h" #include "ior.h" #include @@ -216,6 +217,14 @@ if (!ior->arm.head || ior->arm.proto != proto) { OUTP_DBG(outp, "no heads (%x %d %d)", ior->arm.head, ior->arm.proto, proto); + + /* The EFI GOP driver on Ampere can leave unused DP links routed, + * which we don't expect. The DisableLT IED script *should* get + * us back to where we need to be. + */ + if (ior->func->route.get && !ior->arm.head && outp->info.type == DCB_OUTPUT_DP) + nvkm_dp_disable(outp, ior); + return; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h @@ -121,6 +121,7 @@ extern const struct gf100_grctx_func gk110_grctx; void gk110_grctx_generate_r419eb0(struct gf100_gr *); +void gk110_grctx_generate_r419f78(struct gf100_gr *); extern const struct gf100_grctx_func gk110b_grctx; extern const struct gf100_grctx_func gk208_grctx; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c @@ -916,7 +916,9 @@ gk104_grctx_generate_r419f78(struct gf100_gr *gr) { struct nvkm_device *device = gr->base.engine.subdev.device; - nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); + + /* bit 3 set disables loads in fp helper invocations, we need it enabled */ + nvkm_mask(device, 0x419f78, 0x00000009, 0x00000000); } void --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c @@ -820,6 +820,15 @@ nvkm_mask(device, 0x419eb0, 0x00001000, 0x00001000); } +void +gk110_grctx_generate_r419f78(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + + /* bit 3 set disables loads in fp helper invocations, we need it enabled */ + nvkm_mask(device, 0x419f78, 0x00000008, 0x00000000); +} + const struct gf100_grctx_func gk110_grctx = { .main = gf100_grctx_generate_main, @@ -852,4 +861,5 @@ .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r418800 = gk104_grctx_generate_r418800, .r419eb0 = gk110_grctx_generate_r419eb0, + .r419f78 = gk110_grctx_generate_r419f78, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c @@ -101,4 +101,5 @@ .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r418800 = gk104_grctx_generate_r418800, .r419eb0 = gk110_grctx_generate_r419eb0, + .r419f78 = gk110_grctx_generate_r419f78, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c @@ -566,4 +566,5 @@ .dist_skip_table = gf117_grctx_generate_dist_skip_table, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r418800 = gk104_grctx_generate_r418800, + .r419f78 = gk110_grctx_generate_r419f78, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c @@ -991,4 +991,5 @@ .r406500 = gm107_grctx_generate_r406500, .gpc_tpc_nr = gk104_grctx_generate_gpc_tpc_nr, .r419e00 = gm107_grctx_generate_r419e00, + .r419f78 = gk110_grctx_generate_r419f78, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -1988,8 +1988,34 @@ { struct gf100_gr *gr = gf100_gr(base); struct nvkm_subdev *subdev = &base->engine.subdev; + struct nvkm_device *device = subdev->device; + bool reset = device->chipset == 0x137 || device->chipset == 0x138; u32 ret; + /* On certain GP107/GP108 boards, we trigger a weird issue where + * GR will stop responding to PRI accesses after we've asked the + * SEC2 RTOS to boot the GR falcons. This happens with far more + * frequency when cold-booting a board (ie. returning from D3). + * + * The root cause for this is not known and has proven difficult + * to isolate, with many avenues being dead-ends. + * + * A workaround was discovered by Karol, whereby putting GR into + * reset for an extended period right before initialisation + * prevents the problem from occuring. + * + * XXX: As RM does not require any such workaround, this is more + * of a hack than a true fix. + */ + reset = nvkm_boolopt(device->cfgopt, "NvGrResetWar", reset); + if (reset) { + nvkm_mask(device, 0x000200, 0x00001000, 0x00000000); + nvkm_rd32(device, 0x000200); + msleep(50); + nvkm_mask(device, 0x000200, 0x00001000, 0x00001000); + nvkm_rd32(device, 0x000200); + } + nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false); ret = nvkm_falcon_get(gr->fecs.falcon, subdev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c @@ -143,23 +143,24 @@ nent = (fuc.size / sizeof(struct gk20a_fw_av)); - pack = vzalloc((sizeof(*pack) * max_classes) + - (sizeof(*init) * (nent + 1))); + pack = vzalloc((sizeof(*pack) * (max_classes + 1)) + + (sizeof(*init) * (nent + max_classes + 1))); if (!pack) { ret = -ENOMEM; goto end; } - init = (void *)(pack + max_classes); + init = (void *)(pack + max_classes + 1); - for (i = 0; i < nent; i++) { - struct gf100_gr_init *ent = &init[i]; + for (i = 0; i < nent; i++, init++) { struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i]; u32 class = av->addr & 0xffff; u32 addr = (av->addr & 0xffff0000) >> 14; if (prevclass != class) { - pack[classidx].init = ent; + if (prevclass) /* Add terminator to the method list. */ + init++; + pack[classidx].init = init; pack[classidx].type = class; prevclass = class; if (++classidx >= max_classes) { @@ -169,10 +170,10 @@ } } - ent->addr = addr; - ent->data = av->data; - ent->count = 1; - ent->pitch = 1; + init->addr = addr; + init->data = av->data; + init->count = 1; + init->pitch = 1; } *ppack = pack; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c @@ -33,12 +33,12 @@ { u32 p = *addr; - if (*addr > bios->image0_size && bios->imaged_addr) { + if (*addr >= bios->image0_size && bios->imaged_addr) { *addr -= bios->image0_size; *addr += bios->imaged_addr; } - if (unlikely(*addr + size >= bios->size)) { + if (unlikely(*addr + size > bios->size)) { nvkm_error(&bios->subdev, "OOB %d %08x %08x\n", size, p, *addr); return false; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c @@ -75,7 +75,7 @@ nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", image.base, image.type, image.size); - if (!shadow_fetch(bios, mthd, image.size)) { + if (!shadow_fetch(bios, mthd, image.base + image.size)) { nvkm_debug(subdev, "%08x: fetch failed\n", image.base); return 0; } @@ -154,11 +154,17 @@ return (void *)fw; } +static void +shadow_fw_release(void *fw) +{ + release_firmware(fw); +} + static const struct nvbios_source shadow_fw = { .name = "firmware", .init = shadow_fw_init, - .fini = (void(*)(void *))release_firmware, + .fini = shadow_fw_release, .read = shadow_fw_read, .rw = false, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c @@ -66,11 +66,16 @@ return ERR_PTR(-EINVAL); } +static void of_fini(void *p) +{ + kfree(p); +} + const struct nvbios_source nvbios_of = { .name = "OpenFirmware", .init = of_init, - .fini = (void(*)(void *))kfree, + .fini = of_fini, .read = of_read, .size = of_size, .rw = false, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c @@ -101,9 +101,13 @@ else return ERR_PTR(-ENODEV); + if (!pdev->rom || pdev->romlen == 0) + return ERR_PTR(-ENODEV); + if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + priv->size = pdev->romlen; if (ret = -ENODEV, - (priv->rom = pci_platform_rom(pdev, &priv->size))) + (priv->rom = ioremap(pdev->rom, pdev->romlen))) return priv; kfree(priv); } @@ -111,11 +115,20 @@ return ERR_PTR(ret); } +static void +platform_fini(void *data) +{ + struct priv *priv = data; + + iounmap(priv->rom); + kfree(priv); +} + const struct nvbios_source nvbios_platform = { .name = "PLATFORM", .init = platform_init, - .fini = (void(*)(void *))kfree, + .fini = platform_fini, .read = pcirom_read, .rw = true, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -135,10 +135,10 @@ list_for_each_entry_from_reverse(cstate, &pstate->list, head) { if (nvkm_cstate_valid(clk, cstate, max_volt, clk->temp)) - break; + return cstate; } - return cstate; + return NULL; } static struct nvkm_cstate * @@ -169,6 +169,8 @@ if (!list_empty(&pstate->list)) { cstate = nvkm_cstate_get(clk, pstate, cstatei); cstate = nvkm_cstate_find_best(clk, pstate, cstate); + if (!cstate) + return -EINVAL; } else { cstate = &pstate->base; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -146,6 +146,7 @@ struct nvkm_fault *fault = nvkm_fault(subdev); int i; + nvkm_notify_fini(&fault->nrpfb); nvkm_event_fini(&fault->event); for (i = 0; i < fault->buffer_nr; i++) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -118,10 +118,10 @@ if (retries) udelay(400); - /* transaction request, wait up to 1ms for it to complete */ + /* transaction request, wait up to 2ms for it to complete */ nvkm_wr32(device, 0x00e4e4 + base, 0x00010000 | ctrl); - timeout = 1000; + timeout = 2000; do { ctrl = nvkm_rd32(device, 0x00e4e4 + base); udelay(1); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -33,7 +33,7 @@ gm200_i2c_aux_fini(struct gm200_i2c_aux *aux) { struct nvkm_device *device = aux->base.pad->i2c->subdev.device; - nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00310000, 0x00000000); + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00710000, 0x00000000); } static int @@ -54,10 +54,10 @@ AUX_ERR(&aux->base, "begin idle timeout %08x", ctrl); return -EBUSY; } - } while (ctrl & 0x03010000); + } while (ctrl & 0x07010000); /* set some magic, and wait up to 1ms for it to appear */ - nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00300000, ureq); + nvkm_mask(device, 0x00d954 + (aux->ch * 0x50), 0x00700000, ureq); timeout = 1000; do { ctrl = nvkm_rd32(device, 0x00d954 + (aux->ch * 0x50)); @@ -67,7 +67,7 @@ gm200_i2c_aux_fini(aux); return -EBUSY; } - } while ((ctrl & 0x03000000) != urep); + } while ((ctrl & 0x07000000) != urep); return 0; } @@ -118,10 +118,10 @@ if (retries) udelay(400); - /* transaction request, wait up to 1ms for it to complete */ + /* transaction request, wait up to 2ms for it to complete */ nvkm_wr32(device, 0x00d954 + base, 0x00010000 | ctrl); - timeout = 1000; + timeout = 2000; do { ctrl = nvkm_rd32(device, 0x00d954 + base); udelay(1); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" +#include static void gf100_ibus_intr_hub(struct nvkm_subdev *ibus, int i) @@ -31,7 +32,6 @@ u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0400)); u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0400)); nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x122128 + (i * 0x0400), 0x00000200, 0x00000000); } static void @@ -42,7 +42,6 @@ u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0400)); u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0400)); nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x124128 + (i * 0x0400), 0x00000200, 0x00000000); } static void @@ -53,7 +52,6 @@ u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0400)); u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0400)); nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x128128 + (i * 0x0400), 0x00000200, 0x00000000); } void @@ -90,6 +88,12 @@ intr1 &= ~stat; } } + + nvkm_mask(device, 0x121c4c, 0x0000003f, 0x00000002); + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x121c4c) & 0x0000003f)) + break; + ); } static int --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "priv.h" +#include static void gk104_ibus_intr_hub(struct nvkm_subdev *ibus, int i) @@ -31,7 +32,6 @@ u32 data = nvkm_rd32(device, 0x122124 + (i * 0x0800)); u32 stat = nvkm_rd32(device, 0x122128 + (i * 0x0800)); nvkm_debug(ibus, "HUB%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x122128 + (i * 0x0800), 0x00000200, 0x00000000); } static void @@ -42,7 +42,6 @@ u32 data = nvkm_rd32(device, 0x124124 + (i * 0x0800)); u32 stat = nvkm_rd32(device, 0x124128 + (i * 0x0800)); nvkm_debug(ibus, "ROP%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x124128 + (i * 0x0800), 0x00000200, 0x00000000); } static void @@ -53,7 +52,6 @@ u32 data = nvkm_rd32(device, 0x128124 + (i * 0x0800)); u32 stat = nvkm_rd32(device, 0x128128 + (i * 0x0800)); nvkm_debug(ibus, "GPC%d: %06x %08x (%08x)\n", i, addr, data, stat); - nvkm_mask(device, 0x128128 + (i * 0x0800), 0x00000200, 0x00000000); } void @@ -90,6 +88,12 @@ intr1 &= ~stat; } } + + nvkm_mask(device, 0x12004c, 0x0000003f, 0x00000002); + nvkm_msec(device, 2000, + if (!(nvkm_rd32(device, 0x12004c) & 0x0000003f)) + break; + ); } static int --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -221,8 +221,11 @@ void __iomem *map = NULL; /* Already mapped? */ - if (refcount_inc_not_zero(&iobj->maps)) + if (refcount_inc_not_zero(&iobj->maps)) { + /* read barrier match the wmb on refcount set */ + smp_rmb(); return iobj->map; + } /* Take the lock, and re-check that another thread hasn't * already mapped the object in the meantime. @@ -249,6 +252,8 @@ iobj->base.memory.ptrs = &nv50_instobj_fast; else iobj->base.memory.ptrs = &nv50_instobj_slow; + /* barrier to ensure the ptrs are written before refcount is set */ + smp_wmb(); refcount_set(&iobj->maps, 1); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -316,9 +316,9 @@ { struct nvkm_device *device = mmu->subdev.device; struct nvkm_mm *mm = &device->fb->ram->vram; - const u32 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); - const u32 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); - const u32 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); + const u64 sizeN = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NORMAL); + const u64 sizeU = nvkm_mm_heap_size(mm, NVKM_RAM_MM_NOMAP); + const u64 sizeM = nvkm_mm_heap_size(mm, NVKM_RAM_MM_MIXED); u8 type = NVKM_MEM_KIND * !!mmu->func->kind; u8 heap = NVKM_MEM_VRAM; int heapM, heapN, heapU; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmtu102.c @@ -32,7 +32,7 @@ type = 0x00000001; /* PAGE_ALL */ if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR])) - type |= 0x00000004; /* HUB_ONLY */ + type |= 0x00000006; /* HUB_ONLY | ALL PDB (hack) */ mutex_lock(&subdev->mutex); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c +++ linux-oracle-5.4.0/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c @@ -108,6 +108,7 @@ struct gm200_secboot *gsb; struct nvkm_acr *acr; + *psb = NULL; acr = acr_r352_new(BIT(NVKM_SECBOOT_FALCON_FECS) | BIT(NVKM_SECBOOT_FALCON_PMU)); if (IS_ERR(acr)) @@ -116,10 +117,8 @@ acr->optional_falcons = BIT(NVKM_SECBOOT_FALCON_PMU); gsb = kzalloc(sizeof(*gsb), GFP_KERNEL); - if (!gsb) { - psb = NULL; + if (!gsb) return -ENOMEM; - } *psb = &gsb->base; ret = nvkm_secboot_ctor(&gm20b_secboot, acr, device, index, &gsb->base); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/dss/dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1444,22 +1444,26 @@ { struct dsi_data *dsi = s->private; unsigned long flags; - struct dsi_irq_stats stats; + struct dsi_irq_stats *stats; + + stats = kmalloc(sizeof(*stats), GFP_KERNEL); + if (!stats) + return -ENOMEM; spin_lock_irqsave(&dsi->irq_stats_lock, flags); - stats = dsi->irq_stats; + *stats = dsi->irq_stats; memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats)); dsi->irq_stats.last_reset = jiffies; spin_unlock_irqrestore(&dsi->irq_stats_lock, flags); seq_printf(s, "period %u ms\n", - jiffies_to_msecs(jiffies - stats.last_reset)); + jiffies_to_msecs(jiffies - stats->last_reset)); - seq_printf(s, "irqs %d\n", stats.irq_count); + seq_printf(s, "irqs %d\n", stats->irq_count); #define PIS(x) \ - seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); + seq_printf(s, "%-20s %10d\n", #x, stats->dsi_irqs[ffs(DSI_IRQ_##x)-1]); seq_printf(s, "-- DSI%d interrupts --\n", dsi->module_id + 1); PIS(VC0); @@ -1483,10 +1487,10 @@ #define PIS(x) \ seq_printf(s, "%-20s %10d %10d %10d %10d\n", #x, \ - stats.vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ - stats.vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); + stats->vc_irqs[0][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[1][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[2][ffs(DSI_VC_IRQ_##x)-1], \ + stats->vc_irqs[3][ffs(DSI_VC_IRQ_##x)-1]); seq_printf(s, "-- VC interrupts --\n"); PIS(CS); @@ -1502,7 +1506,7 @@ #define PIS(x) \ seq_printf(s, "%-20s %10d\n", #x, \ - stats.cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); + stats->cio_irqs[ffs(DSI_CIO_IRQ_##x)-1]); seq_printf(s, "-- CIO interrupts --\n"); PIS(ERRSYNCESC1); @@ -1527,6 +1531,8 @@ PIS(ULPSACTIVENOT_ALL1); #undef PIS + kfree(stats); + return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/dss/dss.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/dss/dss.c @@ -1151,46 +1151,39 @@ .has_lcd_clk_src = true, }; -static int dss_init_ports(struct dss_device *dss) +static void __dss_uninit_ports(struct dss_device *dss, unsigned int num_ports) { struct platform_device *pdev = dss->pdev; struct device_node *parent = pdev->dev.of_node; struct device_node *port; unsigned int i; - int r; - for (i = 0; i < dss->feat->num_ports; i++) { + for (i = 0; i < num_ports; i++) { port = of_graph_get_port_by_id(parent, i); if (!port) continue; switch (dss->feat->ports[i]) { case OMAP_DISPLAY_TYPE_DPI: - r = dpi_init_port(dss, pdev, port, dss->feat->model); - if (r) - return r; + dpi_uninit_port(port); break; - case OMAP_DISPLAY_TYPE_SDI: - r = sdi_init_port(dss, pdev, port); - if (r) - return r; + sdi_uninit_port(port); break; - default: break; } + of_node_put(port); } - - return 0; } -static void dss_uninit_ports(struct dss_device *dss) +static int dss_init_ports(struct dss_device *dss) { struct platform_device *pdev = dss->pdev; struct device_node *parent = pdev->dev.of_node; struct device_node *port; - int i; + unsigned int i; + int r; for (i = 0; i < dss->feat->num_ports; i++) { port = of_graph_get_port_by_id(parent, i); @@ -1199,15 +1192,34 @@ switch (dss->feat->ports[i]) { case OMAP_DISPLAY_TYPE_DPI: - dpi_uninit_port(port); + r = dpi_init_port(dss, pdev, port, dss->feat->model); + if (r) + goto error; break; + case OMAP_DISPLAY_TYPE_SDI: - sdi_uninit_port(port); + r = sdi_init_port(dss, pdev, port); + if (r) + goto error; break; + default: break; } + of_node_put(port); } + + return 0; + +error: + of_node_put(port); + __dss_uninit_ports(dss, i); + return r; +} + +static void dss_uninit_ports(struct dss_device *dss) +{ + __dss_uninit_ports(dss, dss->feat->num_ports); } static int dss_video_pll_probe(struct dss_device *dss) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/dss/omapdss-boot-init.c @@ -192,7 +192,7 @@ dss = of_find_matching_node(NULL, omapdss_of_match); if (dss == NULL || !of_device_is_available(dss)) - return 0; + goto put_node; omapdss_walk_device(dss, true); @@ -217,6 +217,8 @@ kfree(n); } +put_node: + of_node_put(dss); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/omap_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -451,11 +451,12 @@ if (omap_state->manually_updated) return; - spin_lock_irq(&crtc->dev->event_lock); drm_crtc_vblank_on(crtc); + ret = drm_crtc_vblank_get(crtc); WARN_ON(ret != 0); + spin_lock_irq(&crtc->dev->event_lock); omap_crtc_arm_event(crtc); spin_unlock_irq(&crtc->dev->event_lock); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -891,6 +891,7 @@ &omap_dmm->refill_pa, GFP_KERNEL); if (!omap_dmm->refill_va) { dev_err(&dev->dev, "could not allocate refill memory\n"); + ret = -ENOMEM; goto fail; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/omap_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/omap_drv.c @@ -216,8 +216,8 @@ } else if (output->bridge) { struct drm_bridge *bridge = output->bridge; - while (bridge->next) - bridge = bridge->next; + while (drm_bridge_get_next_bridge(bridge)) + bridge = drm_bridge_get_next_bridge(bridge); node = bridge->of_node; } else if (output->panel) { @@ -580,6 +580,10 @@ soc = soc_device_match(omapdrm_soc_devices); priv->omaprev = soc ? (unsigned int)soc->data : 0; priv->wq = alloc_ordered_workqueue("omapdrm", 0); + if (!priv->wq) { + ret = -ENOMEM; + goto err_alloc_workqueue; + } mutex_init(&priv->list_lock); INIT_LIST_HEAD(&priv->obj_list); @@ -633,6 +637,7 @@ err_gem_deinit: omap_gem_deinit(ddev); destroy_workqueue(priv->wq); +err_alloc_workqueue: omap_disconnect_pipelines(ddev); omap_crtc_pre_uninit(priv); drm_dev_put(ddev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/omap_encoder.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -125,7 +125,8 @@ for (dssdev = output; dssdev; dssdev = dssdev->next) omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags); - for (bridge = output->bridge; bridge; bridge = bridge->next) { + for (bridge = output->bridge; bridge; + bridge = drm_bridge_get_next_bridge(bridge)) { if (!bridge->timings) continue; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/omapdrm/omap_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1244,8 +1244,6 @@ omap_obj = to_omap_bo(obj); - mutex_lock(&omap_obj->lock); - omap_obj->sgt = sgt; if (sgt->orig_nents == 1) { @@ -1261,8 +1259,7 @@ pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); if (!pages) { omap_gem_free_object(obj); - obj = ERR_PTR(-ENOMEM); - goto done; + return ERR_PTR(-ENOMEM); } omap_obj->pages = pages; @@ -1275,13 +1272,10 @@ if (WARN_ON(i != npages)) { omap_gem_free_object(obj); - obj = ERR_PTR(-ENOMEM); - goto done; + return ERR_PTR(-ENOMEM); } } -done: - mutex_unlock(&omap_obj->lock); return obj; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/Kconfig @@ -141,6 +141,7 @@ depends on OF depends on I2C depends on BACKLIGHT_CLASS_DEVICE + select CRC32 help The panel is used with different sizes LCDs, from 480x272 to 1280x800, and 24 bit per pixel. --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-arm-versatile.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-arm-versatile.c @@ -271,6 +271,8 @@ connector->display_info.bus_flags = vpanel->panel_type->bus_flags; mode = drm_mode_duplicate(panel->drm, &vpanel->panel_type->mode); + if (!mode) + return -ENOMEM; drm_mode_set_name(mode); mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; @@ -350,9 +352,8 @@ dev_info(dev, "panel mounted on IB2 daughterboard\n"); } - drm_panel_init(&vpanel->panel); - vpanel->panel.dev = dev; - vpanel->panel.funcs = &versatile_panel_drm_funcs; + drm_panel_init(&vpanel->panel, dev, &versatile_panel_drm_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&vpanel->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c @@ -204,9 +204,8 @@ mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - drm_panel_init(&ctx->panel); - ctx->panel.dev = &dsi->dev; - ctx->panel.funcs = &feiyang_funcs; + drm_panel_init(&ctx->panel, &dsi->dev, &feiyang_funcs, + DRM_MODE_CONNECTOR_DSI); ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd"); if (IS_ERR(ctx->dvdd)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9322.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-ilitek-ili9322.c @@ -895,9 +895,8 @@ ili->input = ili->conf->input; } - drm_panel_init(&ili->panel); - ili->panel.dev = dev; - ili->panel.funcs = &ili9322_drm_funcs; + drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&ili->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c @@ -307,10 +307,10 @@ msleep(5); /* And reset it */ - gpiod_set_value(ctx->reset, 1); + gpiod_set_value_cansleep(ctx->reset, 1); msleep(20); - gpiod_set_value(ctx->reset, 0); + gpiod_set_value_cansleep(ctx->reset, 0); msleep(20); for (i = 0; i < ARRAY_SIZE(ili9881c_init); i++) { @@ -367,7 +367,7 @@ mipi_dsi_dcs_enter_sleep_mode(ctx->dsi); regulator_disable(ctx->power); - gpiod_set_value(ctx->reset, 1); + gpiod_set_value_cansleep(ctx->reset, 1); return 0; } @@ -433,9 +433,8 @@ mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - drm_panel_init(&ctx->panel); - ctx->panel.dev = &dsi->dev; - ctx->panel.funcs = &ili9881c_funcs; + drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs, + DRM_MODE_CONNECTOR_DSI); ctx->power = devm_regulator_get(&dsi->dev, "power"); if (IS_ERR(ctx->power)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-innolux-p079zca.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-innolux-p079zca.c @@ -487,9 +487,8 @@ if (IS_ERR(innolux->backlight)) return PTR_ERR(innolux->backlight); - drm_panel_init(&innolux->base); - innolux->base.funcs = &innolux_panel_funcs; - innolux->base.dev = dev; + drm_panel_init(&innolux->base, dev, &innolux_panel_funcs, + DRM_MODE_CONNECTOR_DSI); err = drm_panel_add(&innolux->base); if (err < 0) @@ -509,6 +508,7 @@ static int innolux_panel_probe(struct mipi_dsi_device *dsi) { const struct panel_desc *desc; + struct innolux_panel *innolux; int err; desc = of_device_get_match_data(&dsi->dev); @@ -520,7 +520,14 @@ if (err < 0) return err; - return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err < 0) { + innolux = mipi_dsi_get_drvdata(dsi); + innolux_panel_del(innolux); + return err; + } + + return 0; } static int innolux_panel_remove(struct mipi_dsi_device *dsi) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c @@ -437,9 +437,8 @@ return ret; } - drm_panel_init(&jdi->base); - jdi->base.funcs = &jdi_panel_funcs; - jdi->base.dev = &jdi->dsi->dev; + drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs, + DRM_MODE_CONNECTOR_DSI); ret = drm_panel_add(&jdi->base); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c @@ -391,9 +391,8 @@ if (IS_ERR(kingdisplay->backlight)) return PTR_ERR(kingdisplay->backlight); - drm_panel_init(&kingdisplay->base); - kingdisplay->base.funcs = &kingdisplay_panel_funcs; - kingdisplay->base.dev = &kingdisplay->link->dev; + drm_panel_init(&kingdisplay->base, &kingdisplay->link->dev, + &kingdisplay_panel_funcs, DRM_MODE_CONNECTOR_DSI); return drm_panel_add(&kingdisplay->base); } @@ -424,7 +423,13 @@ if (err < 0) return err; - return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err < 0) { + kingdisplay_panel_del(kingdisplay); + return err; + } + + return 0; } static int kingdisplay_panel_remove(struct mipi_dsi_device *dsi) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-lg-lb035q02.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-lg-lb035q02.c @@ -196,9 +196,8 @@ if (ret < 0) return ret; - drm_panel_init(&lcd->panel); - lcd->panel.dev = &lcd->spi->dev; - lcd->panel.funcs = &lb035q02_funcs; + drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&lcd->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-lg-lg4573.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-lg-lg4573.c @@ -259,9 +259,8 @@ return ret; } - drm_panel_init(&ctx->panel); - ctx->panel.dev = &spi->dev; - ctx->panel.funcs = &lg4573_drm_funcs; + drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&ctx->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-lvds.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-lvds.c @@ -197,7 +197,6 @@ static int panel_lvds_probe(struct platform_device *pdev) { struct panel_lvds *lvds; - struct device_node *np; int ret; lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); @@ -243,14 +242,9 @@ return ret; } - np = of_parse_phandle(lvds->dev->of_node, "backlight", 0); - if (np) { - lvds->backlight = of_find_backlight_by_node(np); - of_node_put(np); - - if (!lvds->backlight) - return -EPROBE_DEFER; - } + lvds->backlight = devm_of_find_backlight(lvds->dev); + if (IS_ERR(lvds->backlight)) + return PTR_ERR(lvds->backlight); /* * TODO: Handle all power supplies specified in the DT node in a generic @@ -260,20 +254,15 @@ */ /* Register the panel. */ - drm_panel_init(&lvds->panel); - lvds->panel.dev = lvds->dev; - lvds->panel.funcs = &panel_lvds_funcs; + drm_panel_init(&lvds->panel, lvds->dev, &panel_lvds_funcs, + DRM_MODE_CONNECTOR_LVDS); ret = drm_panel_add(&lvds->panel); if (ret < 0) - goto error; + return ret; dev_set_drvdata(lvds->dev, lvds); return 0; - -error: - put_device(&lvds->backlight->dev); - return ret; } static int panel_lvds_remove(struct platform_device *pdev) @@ -284,9 +273,6 @@ panel_lvds_disable(&lvds->panel); - if (lvds->backlight) - put_device(&lvds->backlight->dev); - return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c @@ -205,9 +205,8 @@ if (ret < 0) return ret; - drm_panel_init(&lcd->panel); - lcd->panel.dev = &lcd->spi->dev; - lcd->panel.funcs = &nl8048_funcs; + drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&lcd->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-novatek-nt39016.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-novatek-nt39016.c @@ -292,9 +292,8 @@ return err; } - drm_panel_init(&panel->drm_panel); - panel->drm_panel.dev = dev; - panel->drm_panel.funcs = &nt39016_funcs; + drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs, + DRM_MODE_CONNECTOR_DPI); err = drm_panel_add(&panel->drm_panel); if (err < 0) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c @@ -288,9 +288,8 @@ if (IS_ERR(lcd->backlight)) return PTR_ERR(lcd->backlight); - drm_panel_init(&lcd->panel); - lcd->panel.dev = dev; - lcd->panel.funcs = &lcd_olinuxino_funcs; + drm_panel_init(&lcd->panel, dev, &lcd_olinuxino_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&lcd->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-orisetech-otm8009a.c @@ -455,12 +455,11 @@ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &otm8009a_drm_funcs; + drm_panel_init(&ctx->panel, dev, &otm8009a_drm_funcs, + DRM_MODE_CONNECTOR_DSI); ctx->bl_dev = devm_backlight_device_register(dev, dev_name(dev), - dsi->host->dev, ctx, + dev, ctx, &otm8009a_backlight_ops, NULL); if (IS_ERR(ctx->bl_dev)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c @@ -166,9 +166,8 @@ if (IS_ERR(osd101t2587->backlight)) return PTR_ERR(osd101t2587->backlight); - drm_panel_init(&osd101t2587->base); - osd101t2587->base.funcs = &osd101t2587_panel_funcs; - osd101t2587->base.dev = &osd101t2587->dsi->dev; + drm_panel_init(&osd101t2587->base, &osd101t2587->dsi->dev, + &osd101t2587_panel_funcs, DRM_MODE_CONNECTOR_DSI); return drm_panel_add(&osd101t2587->base); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c @@ -223,9 +223,8 @@ return -EPROBE_DEFER; } - drm_panel_init(&wuxga_nt->base); - wuxga_nt->base.funcs = &wuxga_nt_panel_funcs; - wuxga_nt->base.dev = &wuxga_nt->dsi->dev; + drm_panel_init(&wuxga_nt->base, &wuxga_nt->dsi->dev, + &wuxga_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI); ret = drm_panel_add(&wuxga_nt->base); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -232,7 +232,7 @@ ret = i2c_smbus_write_byte_data(ts->i2c, reg, val); if (ret) - dev_err(&ts->dsi->dev, "I2C write failed: %d\n", ret); + dev_err(&ts->i2c->dev, "I2C write failed: %d\n", ret); } static int rpi_touchscreen_write(struct rpi_touchscreen *ts, u16 reg, u32 val) @@ -268,7 +268,7 @@ return 0; } -static int rpi_touchscreen_enable(struct drm_panel *panel) +static int rpi_touchscreen_prepare(struct drm_panel *panel) { struct rpi_touchscreen *ts = panel_to_ts(panel); int i; @@ -298,6 +298,13 @@ rpi_touchscreen_write(ts, DSI_STARTDSI, 0x01); msleep(100); + return 0; +} + +static int rpi_touchscreen_enable(struct drm_panel *panel) +{ + struct rpi_touchscreen *ts = panel_to_ts(panel); + /* Turn on the backlight. */ rpi_touchscreen_i2c_write(ts, REG_PWM, 255); @@ -352,7 +359,7 @@ static const struct drm_panel_funcs rpi_touchscreen_funcs = { .disable = rpi_touchscreen_disable, .unprepare = rpi_touchscreen_noop, - .prepare = rpi_touchscreen_noop, + .prepare = rpi_touchscreen_prepare, .enable = rpi_touchscreen_enable, .get_modes = rpi_touchscreen_get_modes, }; @@ -426,8 +433,8 @@ return PTR_ERR(ts->dsi); } - ts->base.dev = dev; - ts->base.funcs = &rpi_touchscreen_funcs; + drm_panel_init(&ts->base, dev, &rpi_touchscreen_funcs, + DRM_MODE_CONNECTOR_DSI); /* This appears last, as it's what will unblock the DSI host * driver's component bind function. @@ -452,7 +459,6 @@ drm_panel_remove(&ts->base); mipi_dsi_device_unregister(ts->dsi); - kfree(ts->dsi); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-raydium-rm67191.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-raydium-rm67191.c @@ -606,9 +606,8 @@ if (ret) return ret; - drm_panel_init(&panel->panel); - panel->panel.funcs = &rad_panel_funcs; - panel->panel.dev = dev; + drm_panel_init(&panel->panel, dev, &rad_panel_funcs, + DRM_MODE_CONNECTOR_DSI); dev_set_drvdata(dev, panel); ret = drm_panel_add(&panel->panel); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-raydium-rm68200.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-raydium-rm68200.c @@ -404,9 +404,8 @@ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM; - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &rm68200_drm_funcs; + drm_panel_init(&ctx->panel, dev, &rm68200_drm_funcs, + DRM_MODE_CONNECTOR_DSI); drm_panel_add(&ctx->panel); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-rocktech-jh057n00900.c @@ -343,9 +343,8 @@ return ret; } - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &jh057n_drm_funcs; + drm_panel_init(&ctx->panel, dev, &jh057n_drm_funcs, + DRM_MODE_CONNECTOR_DSI); drm_panel_add(&ctx->panel); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c @@ -173,9 +173,8 @@ mipi_dsi_set_drvdata(dsi, ctx); ctx->dsi = dsi; - drm_panel_init(&ctx->panel); - ctx->panel.dev = &dsi->dev; - ctx->panel.funcs = &rb070d30_panel_funcs; + drm_panel_init(&ctx->panel, &dsi->dev, &rb070d30_panel_funcs, + DRM_MODE_CONNECTOR_DSI); ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ctx->gpios.reset)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-ld9040.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-ld9040.c @@ -351,9 +351,8 @@ return ret; } - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &ld9040_drm_funcs; + drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&ctx->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-s6d16d0.c @@ -215,9 +215,8 @@ return ret; } - drm_panel_init(&s6->panel); - s6->panel.dev = dev; - s6->panel.funcs = &s6d16d0_drm_funcs; + drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs, + DRM_MODE_CONNECTOR_DSI); ret = drm_panel_add(&s6->panel); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c @@ -732,9 +732,8 @@ ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS; ctx->bl_dev->props.power = FB_BLANK_POWERDOWN; - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &s6e3ha2_drm_funcs; + drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs, + DRM_MODE_CONNECTOR_DSI); ret = drm_panel_add(&ctx->panel); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c @@ -466,9 +466,8 @@ return PTR_ERR(ctx->reset_gpio); } - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &s6e63j0x03_funcs; + drm_panel_init(&ctx->panel, dev, &s6e63j0x03_funcs, + DRM_MODE_CONNECTOR_DSI); ctx->bl_dev = backlight_device_register("s6e63j0x03", dev, ctx, &s6e63j0x03_bl_ops, NULL); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c @@ -473,9 +473,8 @@ return ret; } - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &s6e63m0_drm_funcs; + drm_panel_init(&ctx->panel, dev, &s6e63m0_drm_funcs, + DRM_MODE_CONNECTOR_DPI); ret = s6e63m0_backlight_register(ctx); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c @@ -1017,9 +1017,8 @@ ctx->brightness = GAMMA_LEVEL_NUM - 1; - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &s6e8aa0_drm_funcs; + drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs, + DRM_MODE_CONNECTOR_DSI); ret = drm_panel_add(&ctx->panel); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-seiko-43wvf1g.c @@ -274,9 +274,8 @@ return -EPROBE_DEFER; } - drm_panel_init(&panel->base); - panel->base.dev = dev; - panel->base.funcs = &seiko_panel_funcs; + drm_panel_init(&panel->base, dev, &seiko_panel_funcs, + DRM_MODE_CONNECTOR_DPI); err = drm_panel_add(&panel->base); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c @@ -329,9 +329,8 @@ if (IS_ERR(sharp->backlight)) return PTR_ERR(sharp->backlight); - drm_panel_init(&sharp->base); - sharp->base.funcs = &sharp_panel_funcs; - sharp->base.dev = &sharp->link1->dev; + drm_panel_init(&sharp->base, &sharp->link1->dev, &sharp_panel_funcs, + DRM_MODE_CONNECTOR_DSI); return drm_panel_add(&sharp->base); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c @@ -185,9 +185,8 @@ return PTR_ERR(lcd->ud_gpio); } - drm_panel_init(&lcd->panel); - lcd->panel.dev = &pdev->dev; - lcd->panel.funcs = &ls037v7dw01_funcs; + drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&lcd->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c @@ -264,9 +264,8 @@ if (IS_ERR(sharp_nt->backlight)) return PTR_ERR(sharp_nt->backlight); - drm_panel_init(&sharp_nt->base); - sharp_nt->base.funcs = &sharp_nt_panel_funcs; - sharp_nt->base.dev = &sharp_nt->dsi->dev; + drm_panel_init(&sharp_nt->base, &sharp_nt->dsi->dev, + &sharp_nt_panel_funcs, DRM_MODE_CONNECTOR_DSI); return drm_panel_add(&sharp_nt->base); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-simple.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-simple.c @@ -94,6 +94,7 @@ u32 bus_format; u32 bus_flags; + int connector_type; }; struct panel_simple { @@ -464,9 +465,8 @@ if (!of_get_display_timing(dev->of_node, "panel-timing", &dt)) panel_simple_parse_panel_timing_node(dev, panel, &dt); - drm_panel_init(&panel->base); - panel->base.dev = dev; - panel->base.funcs = &panel_simple_funcs; + drm_panel_init(&panel->base, dev, &panel_simple_funcs, + desc->connector_type); err = drm_panel_add(&panel->base); if (err < 0) @@ -531,8 +531,8 @@ .num_modes = 1, .bpc = 8, .size = { - .width = 105, - .height = 67, + .width = 99, + .height = 58, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, }; @@ -833,6 +833,7 @@ .unprepare = 1000, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing auo_g185han01_timings = { @@ -862,6 +863,7 @@ .unprepare = 1000, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing auo_p320hvn03_timings = { @@ -890,6 +892,7 @@ .unprepare = 500, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode auo_t215hvn01_mode = { @@ -916,7 +919,9 @@ .delay = { .disable = 5, .unprepare = 1000, - } + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode avic_tm070ddh03_mode = { @@ -1205,6 +1210,7 @@ .disable = 200, }, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing dlc_dlc1010gig_timing = { @@ -1235,6 +1241,7 @@ .unprepare = 60, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode edt_et035012dm6_mode = { @@ -1501,6 +1508,7 @@ .height = 94, }, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing hannstar_hsd100pxn1_timing = { @@ -1525,6 +1533,7 @@ .height = 152, }, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = { @@ -1577,6 +1586,7 @@ .height = 54, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .connector_type = DRM_MODE_CONNECTOR_DPI, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, }; @@ -1619,7 +1629,7 @@ static const struct panel_desc innolux_g070y2_l01 = { .timings = &innolux_g070y2_l01_timing, .num_timings = 1, - .bpc = 6, + .bpc = 8, .size = { .width = 152, .height = 91, @@ -1631,18 +1641,19 @@ .unprepare = 800, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing innolux_g101ice_l01_timing = { .pixelclock = { 60400000, 71100000, 74700000 }, .hactive = { 1280, 1280, 1280 }, - .hfront_porch = { 41, 80, 100 }, - .hback_porch = { 40, 79, 99 }, - .hsync_len = { 1, 1, 1 }, + .hfront_porch = { 30, 60, 70 }, + .hback_porch = { 30, 60, 70 }, + .hsync_len = { 22, 40, 60 }, .vactive = { 800, 800, 800 }, - .vfront_porch = { 5, 11, 14 }, - .vback_porch = { 4, 11, 14 }, - .vsync_len = { 1, 1, 1 }, + .vfront_porch = { 3, 8, 14 }, + .vback_porch = { 3, 8, 14 }, + .vsync_len = { 4, 7, 12 }, .flags = DISPLAY_FLAGS_DE_HIGH, }; @@ -1659,6 +1670,8 @@ .disable = 200, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing innolux_g121i1_l01_timing = { @@ -1686,6 +1699,7 @@ .disable = 20, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode innolux_g121x1_l03_mode = { @@ -1715,6 +1729,9 @@ .unprepare = 200, .disable = 400, }, + .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; /* @@ -1869,6 +1886,7 @@ .height = 109, }, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing kyo_tcg121xglp_timing = { @@ -1893,6 +1911,7 @@ .height = 184, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode lemaker_bl035_rgb_002_mode = { @@ -1935,12 +1954,13 @@ static const struct panel_desc lg_lb070wv8 = { .modes = &lg_lb070wv8_mode, .num_modes = 1, - .bpc = 16, + .bpc = 8, .size = { .width = 151, .height = 91, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { @@ -2048,6 +2068,40 @@ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, }; +static const struct drm_display_mode logicpd_type_28_mode = { + .clock = 9000, + .hdisplay = 480, + .hsync_start = 480 + 3, + .hsync_end = 480 + 3 + 42, + .htotal = 480 + 3 + 42 + 2, + + .vdisplay = 272, + .vsync_start = 272 + 2, + .vsync_end = 272 + 2 + 11, + .vtotal = 272 + 2 + 11 + 3, + .vrefresh = 60, + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct panel_desc logicpd_type_28 = { + .modes = &logicpd_type_28_mode, + .num_modes = 1, + .bpc = 8, + .size = { + .width = 105, + .height = 67, + }, + .delay = { + .prepare = 200, + .enable = 200, + .unprepare = 200, + .disable = 200, + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | + DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, +}; + static const struct panel_desc mitsubishi_aa070mc01 = { .modes = &mitsubishi_aa070mc01_mode, .num_modes = 1, @@ -2063,6 +2117,7 @@ .disable = 400, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, .bus_flags = DRM_BUS_FLAG_DE_HIGH, }; @@ -2091,6 +2146,7 @@ .disable = 50, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode nec_nl4827hc19_05b_mode = { @@ -2193,6 +2249,7 @@ .unprepare = 500, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode nvd_9128_mode = { @@ -2216,6 +2273,7 @@ .height = 88, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing okaya_rs800480t_7x0gp_timing = { @@ -2348,12 +2406,12 @@ static const struct panel_desc ortustech_com43h4m85ulc = { .modes = &ortustech_com43h4m85ulc_mode, .num_modes = 1, - .bpc = 8, + .bpc = 6, .size = { .width = 56, .height = 93, }, - .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_format = MEDIA_BUS_FMT_RGB666_1X18, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, }; @@ -2628,6 +2686,7 @@ .height = 136, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing sharp_lq123p1jx31_timing = { @@ -2807,6 +2866,7 @@ .height = 95, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct display_timing tianma_tm070rvhg71_timing = { @@ -2831,6 +2891,7 @@ .height = 86, }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode ti_nspire_cx_lcd_mode[] = { @@ -2913,6 +2974,7 @@ }, .bus_format = MEDIA_BUS_FMT_RGB888_1X24, .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode tpk_f07a_0102_mode = { @@ -2983,6 +3045,7 @@ .height = 91, }, .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct panel_desc urt_umsh_8596md_parallel = { @@ -3265,6 +3328,9 @@ .compatible = "lg,lp129qe", .data = &lg_lp129qe, }, { + .compatible = "logicpd,type28", + .data = &logicpd_type_28, + }, { .compatible = "mitsubishi,aa070mc01-ca1", .data = &mitsubishi_aa070mc01, }, { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7701.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sitronix-st7701.c @@ -369,7 +369,8 @@ if (IS_ERR(st7701->backlight)) return PTR_ERR(st7701->backlight); - drm_panel_init(&st7701->panel); + drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs, + DRM_MODE_CONNECTOR_DSI); /** * Once sleep out has been issued, ST7701 IC required to wait 120ms @@ -381,8 +382,6 @@ * ts8550b and there is no valid documentation for that. */ st7701->sleep_delay = 120 + desc->panel_sleep_delay; - st7701->panel.funcs = &st7701_funcs; - st7701->panel.dev = &dsi->dev; ret = drm_panel_add(&st7701->panel); if (ret < 0) @@ -392,7 +391,15 @@ st7701->dsi = dsi; st7701->desc = desc; - return mipi_dsi_attach(dsi); + ret = mipi_dsi_attach(dsi); + if (ret) + goto err_attach; + + return 0; + +err_attach: + drm_panel_remove(&st7701->panel); + return ret; } static int st7701_dsi_remove(struct mipi_dsi_device *dsi) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7789v.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sitronix-st7789v.c @@ -381,8 +381,8 @@ spi_set_drvdata(spi, ctx); ctx->spi = spi; - ctx->panel.dev = &spi->dev; - ctx->panel.funcs = &st7789v_drm_funcs; + drm_panel_init(&ctx->panel, &spi->dev, &st7789v_drm_funcs, + DRM_MODE_CONNECTOR_DPI); ctx->power = devm_regulator_get(&spi->dev, "power"); if (IS_ERR(ctx->power)) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-sony-acx565akm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-sony-acx565akm.c @@ -648,9 +648,8 @@ return ret; } - drm_panel_init(&lcd->panel); - lcd->panel.dev = &lcd->spi->dev; - lcd->panel.funcs = &acx565akm_funcs; + drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs, + DRM_MODE_CONNECTOR_DPI); ret = drm_panel_add(&lcd->panel); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c @@ -347,9 +347,8 @@ return ret; } - drm_panel_init(&lcd->panel); - lcd->panel.dev = &lcd->spi->dev; - lcd->panel.funcs = &td028ttec1_funcs; + drm_panel_init(&lcd->panel, &lcd->spi->dev, &td028ttec1_funcs, + DRM_MODE_CONNECTOR_DPI); return drm_panel_add(&lcd->panel); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c @@ -458,9 +458,8 @@ return ret; } - drm_panel_init(&lcd->panel); - lcd->panel.dev = &lcd->spi->dev; - lcd->panel.funcs = &td043mtea1_funcs; + drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs, + DRM_MODE_CONNECTOR_DPI); ret = drm_panel_add(&lcd->panel); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-tpo-tpg110.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-tpo-tpg110.c @@ -457,9 +457,8 @@ if (ret) return ret; - drm_panel_init(&tpg->panel); - tpg->panel.dev = dev; - tpg->panel.funcs = &tpg110_drm_funcs; + drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs, + DRM_MODE_CONNECTOR_DPI); spi_set_drvdata(spi, tpg); return drm_panel_add(&tpg->panel); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panel/panel-truly-nt35597.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panel/panel-truly-nt35597.c @@ -518,9 +518,8 @@ /* dual port */ gpiod_set_value(ctx->mode_gpio, 0); - drm_panel_init(&ctx->panel); - ctx->panel.dev = dev; - ctx->panel.funcs = &truly_nt35597_drm_funcs; + drm_panel_init(&ctx->panel, dev, &truly_nt35597_drm_funcs, + DRM_MODE_CONNECTOR_DSI); drm_panel_add(&ctx->panel); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/Kconfig @@ -3,7 +3,8 @@ config DRM_PANFROST tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)" depends on DRM - depends on ARM || ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64) + depends on ARM || ARM64 || COMPILE_TEST + depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE depends on MMU select DRM_SCHED select IOMMU_SUPPORT --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_devfreq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_devfreq.c @@ -53,8 +53,10 @@ if (err) { dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate, err); - regulator_set_voltage(pfdev->regulator, pfdev->devfreq.cur_volt, - pfdev->devfreq.cur_volt); + if (pfdev->regulator) + regulator_set_voltage(pfdev->regulator, + pfdev->devfreq.cur_volt, + pfdev->devfreq.cur_volt); return err; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_device.c @@ -59,7 +59,8 @@ if (IS_ERR(pfdev->bus_clock)) { dev_err(pfdev->dev, "get bus_clock failed %ld\n", PTR_ERR(pfdev->bus_clock)); - return PTR_ERR(pfdev->bus_clock); + err = PTR_ERR(pfdev->bus_clock); + goto disable_clock; } if (pfdev->bus_clock) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -78,8 +78,10 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, struct drm_file *file) { + struct panfrost_file_priv *priv = file->driver_priv; struct panfrost_gem_object *bo; struct drm_panfrost_create_bo *args = data; + struct panfrost_gem_mapping *mapping; if (!args->size || args->pad || (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP))) @@ -95,7 +97,14 @@ if (IS_ERR(bo)) return PTR_ERR(bo); - args->offset = bo->node.start << PAGE_SHIFT; + mapping = panfrost_gem_mapping_get(bo, priv); + if (!mapping) { + drm_gem_object_put_unlocked(&bo->base.base); + return -EINVAL; + } + + args->offset = mapping->mmnode.start << PAGE_SHIFT; + panfrost_gem_mapping_put(mapping); return 0; } @@ -119,6 +128,11 @@ struct drm_panfrost_submit *args, struct panfrost_job *job) { + struct panfrost_file_priv *priv = file_priv->driver_priv; + struct panfrost_gem_object *bo; + unsigned int i; + int ret; + job->bo_count = args->bo_handle_count; if (!job->bo_count) @@ -130,9 +144,33 @@ if (!job->implicit_fences) return -ENOMEM; - return drm_gem_objects_lookup(file_priv, - (void __user *)(uintptr_t)args->bo_handles, - job->bo_count, &job->bos); + ret = drm_gem_objects_lookup(file_priv, + (void __user *)(uintptr_t)args->bo_handles, + job->bo_count, &job->bos); + if (ret) + return ret; + + job->mappings = kvmalloc_array(job->bo_count, + sizeof(struct panfrost_gem_mapping *), + GFP_KERNEL | __GFP_ZERO); + if (!job->mappings) + return -ENOMEM; + + for (i = 0; i < job->bo_count; i++) { + struct panfrost_gem_mapping *mapping; + + bo = to_panfrost_bo(job->bos[i]); + mapping = panfrost_gem_mapping_get(bo, priv); + if (!mapping) { + ret = -EINVAL; + break; + } + + atomic_inc(&bo->gpu_usecount); + job->mappings[i] = mapping; + } + + return ret; } /** @@ -303,21 +341,26 @@ } /* Don't allow mmapping of heap objects as pages are not pinned. */ - if (to_panfrost_bo(gem_obj)->is_heap) - return -EINVAL; + if (to_panfrost_bo(gem_obj)->is_heap) { + ret = -EINVAL; + goto out; + } ret = drm_gem_create_mmap_offset(gem_obj); if (ret == 0) args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); - drm_gem_object_put_unlocked(gem_obj); +out: + drm_gem_object_put_unlocked(gem_obj); return ret; } static int panfrost_ioctl_get_bo_offset(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct panfrost_file_priv *priv = file_priv->driver_priv; struct drm_panfrost_get_bo_offset *args = data; + struct panfrost_gem_mapping *mapping; struct drm_gem_object *gem_obj; struct panfrost_gem_object *bo; @@ -328,18 +371,26 @@ } bo = to_panfrost_bo(gem_obj); - args->offset = bo->node.start << PAGE_SHIFT; - + mapping = panfrost_gem_mapping_get(bo, priv); drm_gem_object_put_unlocked(gem_obj); + + if (!mapping) + return -EINVAL; + + args->offset = mapping->mmnode.start << PAGE_SHIFT; + panfrost_gem_mapping_put(mapping); return 0; } static int panfrost_ioctl_madvise(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct panfrost_file_priv *priv = file_priv->driver_priv; struct drm_panfrost_madvise *args = data; struct panfrost_device *pfdev = dev->dev_private; struct drm_gem_object *gem_obj; + struct panfrost_gem_object *bo; + int ret = 0; gem_obj = drm_gem_object_lookup(file_priv, args->handle); if (!gem_obj) { @@ -347,23 +398,48 @@ return -ENOENT; } - args->retained = drm_gem_shmem_madvise(gem_obj, args->madv); + bo = to_panfrost_bo(gem_obj); - if (args->retained) { - struct panfrost_gem_object *bo = to_panfrost_bo(gem_obj); + mutex_lock(&pfdev->shrinker_lock); + mutex_lock(&bo->mappings.lock); + if (args->madv == PANFROST_MADV_DONTNEED) { + struct panfrost_gem_mapping *first; + + first = list_first_entry(&bo->mappings.list, + struct panfrost_gem_mapping, + node); + + /* + * If we want to mark the BO purgeable, there must be only one + * user: the caller FD. + * We could do something smarter and mark the BO purgeable only + * when all its users have marked it purgeable, but globally + * visible/shared BOs are likely to never be marked purgeable + * anyway, so let's not bother. + */ + if (!list_is_singular(&bo->mappings.list) || + WARN_ON_ONCE(first->mmu != &priv->mmu)) { + ret = -EINVAL; + goto out_unlock_mappings; + } + } - mutex_lock(&pfdev->shrinker_lock); + args->retained = drm_gem_shmem_madvise(gem_obj, args->madv); + if (args->retained) { if (args->madv == PANFROST_MADV_DONTNEED) - list_add_tail(&bo->base.madv_list, &pfdev->shrinker_list); + list_move_tail(&bo->base.madv_list, + &pfdev->shrinker_list); else if (args->madv == PANFROST_MADV_WILLNEED) list_del_init(&bo->base.madv_list); - - mutex_unlock(&pfdev->shrinker_lock); } +out_unlock_mappings: + mutex_unlock(&bo->mappings.lock); + mutex_unlock(&pfdev->shrinker_lock); + drm_gem_object_put_unlocked(gem_obj); - return 0; + return ret; } int panfrost_unstable_ioctl_check(void) @@ -443,7 +519,7 @@ { struct panfrost_file_priv *panfrost_priv = file->driver_priv; - panfrost_perfcnt_close(panfrost_priv); + panfrost_perfcnt_close(file); panfrost_job_close(panfrost_priv); panfrost_mmu_pgtable_free(panfrost_priv); @@ -616,3 +692,4 @@ MODULE_AUTHOR("Panfrost Project Developers"); MODULE_DESCRIPTION("Panfrost DRM Driver"); MODULE_LICENSE("GPL v2"); +MODULE_SOFTDEP("pre: governor_simpleondemand"); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -19,6 +19,22 @@ struct panfrost_gem_object *bo = to_panfrost_bo(obj); struct panfrost_device *pfdev = obj->dev->dev_private; + /* + * Make sure the BO is no longer inserted in the shrinker list before + * taking care of the destruction itself. If we don't do that we have a + * race condition between this function and what's done in + * panfrost_gem_shrinker_scan(). + */ + mutex_lock(&pfdev->shrinker_lock); + list_del_init(&bo->base.madv_list); + mutex_unlock(&pfdev->shrinker_lock); + + /* + * If we still have mappings attached to the BO, there's a problem in + * our refcounting. + */ + WARN_ON_ONCE(!list_empty(&bo->mappings.list)); + if (bo->sgts) { int i; int n_sgt = bo->base.base.size / SZ_2M; @@ -30,18 +46,74 @@ sg_free_table(&bo->sgts[i]); } } - kfree(bo->sgts); + kvfree(bo->sgts); } - mutex_lock(&pfdev->shrinker_lock); - if (!list_empty(&bo->base.madv_list)) - list_del(&bo->base.madv_list); - mutex_unlock(&pfdev->shrinker_lock); - drm_gem_shmem_free_object(obj); } -static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) +struct panfrost_gem_mapping * +panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + struct panfrost_file_priv *priv) +{ + struct panfrost_gem_mapping *iter, *mapping = NULL; + + mutex_lock(&bo->mappings.lock); + list_for_each_entry(iter, &bo->mappings.list, node) { + if (iter->mmu == &priv->mmu) { + kref_get(&iter->refcount); + mapping = iter; + break; + } + } + mutex_unlock(&bo->mappings.lock); + + return mapping; +} + +static void +panfrost_gem_teardown_mapping(struct panfrost_gem_mapping *mapping) +{ + struct panfrost_file_priv *priv; + + if (mapping->active) + panfrost_mmu_unmap(mapping); + + priv = container_of(mapping->mmu, struct panfrost_file_priv, mmu); + spin_lock(&priv->mm_lock); + if (drm_mm_node_allocated(&mapping->mmnode)) + drm_mm_remove_node(&mapping->mmnode); + spin_unlock(&priv->mm_lock); +} + +static void panfrost_gem_mapping_release(struct kref *kref) +{ + struct panfrost_gem_mapping *mapping; + + mapping = container_of(kref, struct panfrost_gem_mapping, refcount); + + panfrost_gem_teardown_mapping(mapping); + drm_gem_object_put_unlocked(&mapping->obj->base.base); + kfree(mapping); +} + +void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping) +{ + if (!mapping) + return; + + kref_put(&mapping->refcount, panfrost_gem_mapping_release); +} + +void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo) +{ + struct panfrost_gem_mapping *mapping; + + list_for_each_entry(mapping, &bo->mappings.list, node) + panfrost_gem_teardown_mapping(mapping); +} + +int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) { int ret; size_t size = obj->size; @@ -49,6 +121,16 @@ struct panfrost_gem_object *bo = to_panfrost_bo(obj); unsigned long color = bo->noexec ? PANFROST_BO_NOEXEC : 0; struct panfrost_file_priv *priv = file_priv->driver_priv; + struct panfrost_gem_mapping *mapping; + + mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + if (!mapping) + return -ENOMEM; + + INIT_LIST_HEAD(&mapping->node); + kref_init(&mapping->refcount); + drm_gem_object_get(obj); + mapping->obj = bo; /* * Executable buffers cannot cross a 16MB boundary as the program @@ -61,37 +143,48 @@ else align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0; - bo->mmu = &priv->mmu; + mapping->mmu = &priv->mmu; spin_lock(&priv->mm_lock); - ret = drm_mm_insert_node_generic(&priv->mm, &bo->node, + ret = drm_mm_insert_node_generic(&priv->mm, &mapping->mmnode, size >> PAGE_SHIFT, align, color, 0); spin_unlock(&priv->mm_lock); if (ret) - return ret; + goto err; if (!bo->is_heap) { - ret = panfrost_mmu_map(bo); - if (ret) { - spin_lock(&priv->mm_lock); - drm_mm_remove_node(&bo->node); - spin_unlock(&priv->mm_lock); - } + ret = panfrost_mmu_map(mapping); + if (ret) + goto err; } + + mutex_lock(&bo->mappings.lock); + WARN_ON(bo->base.madv != PANFROST_MADV_WILLNEED); + list_add_tail(&mapping->node, &bo->mappings.list); + mutex_unlock(&bo->mappings.lock); + +err: + if (ret) + panfrost_gem_mapping_put(mapping); return ret; } -static void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv) +void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv) { - struct panfrost_gem_object *bo = to_panfrost_bo(obj); struct panfrost_file_priv *priv = file_priv->driver_priv; + struct panfrost_gem_object *bo = to_panfrost_bo(obj); + struct panfrost_gem_mapping *mapping = NULL, *iter; - if (bo->is_mapped) - panfrost_mmu_unmap(bo); + mutex_lock(&bo->mappings.lock); + list_for_each_entry(iter, &bo->mappings.list, node) { + if (iter->mmu == &priv->mmu) { + mapping = iter; + list_del(&iter->node); + break; + } + } + mutex_unlock(&bo->mappings.lock); - spin_lock(&priv->mm_lock); - if (drm_mm_node_allocated(&bo->node)) - drm_mm_remove_node(&bo->node); - spin_unlock(&priv->mm_lock); + panfrost_gem_mapping_put(mapping); } static int panfrost_gem_pin(struct drm_gem_object *obj) @@ -131,6 +224,8 @@ if (!obj) return NULL; + INIT_LIST_HEAD(&obj->mappings.list); + mutex_init(&obj->mappings.lock); obj->base.base.funcs = &panfrost_gem_funcs; return &obj->base.base; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_gem.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -13,23 +13,52 @@ struct drm_gem_shmem_object base; struct sg_table *sgts; - struct panfrost_mmu *mmu; - struct drm_mm_node node; - bool is_mapped :1; + /* + * Use a list for now. If searching a mapping ever becomes the + * bottleneck, we should consider using an RB-tree, or even better, + * let the core store drm_gem_object_mapping entries (where we + * could place driver specific data) instead of drm_gem_object ones + * in its drm_file->object_idr table. + * + * struct drm_gem_object_mapping { + * struct drm_gem_object *obj; + * void *driver_priv; + * }; + */ + struct { + struct list_head list; + struct mutex lock; + } mappings; + + /* + * Count the number of jobs referencing this BO so we don't let the + * shrinker reclaim this object prematurely. + */ + atomic_t gpu_usecount; + bool noexec :1; bool is_heap :1; }; +struct panfrost_gem_mapping { + struct list_head node; + struct kref refcount; + struct panfrost_gem_object *obj; + struct drm_mm_node mmnode; + struct panfrost_mmu *mmu; + bool active :1; +}; + static inline struct panfrost_gem_object *to_panfrost_bo(struct drm_gem_object *obj) { return container_of(to_drm_gem_shmem_obj(obj), struct panfrost_gem_object, base); } -static inline -struct panfrost_gem_object *drm_mm_node_to_panfrost_bo(struct drm_mm_node *node) +static inline struct panfrost_gem_mapping * +drm_mm_node_to_panfrost_mapping(struct drm_mm_node *node) { - return container_of(node, struct panfrost_gem_object, node); + return container_of(node, struct panfrost_gem_mapping, mmnode); } struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size); @@ -45,6 +74,16 @@ u32 flags, uint32_t *handle); +int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv); +void panfrost_gem_close(struct drm_gem_object *obj, + struct drm_file *file_priv); + +struct panfrost_gem_mapping * +panfrost_gem_mapping_get(struct panfrost_gem_object *bo, + struct panfrost_file_priv *priv); +void panfrost_gem_mapping_put(struct panfrost_gem_mapping *mapping); +void panfrost_gem_teardown_mappings_locked(struct panfrost_gem_object *bo); + void panfrost_gem_shrinker_init(struct drm_device *dev); void panfrost_gem_shrinker_cleanup(struct drm_device *dev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c @@ -39,15 +39,27 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj) { struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); + struct panfrost_gem_object *bo = to_panfrost_bo(obj); + bool ret = false; - if (!mutex_trylock(&shmem->pages_lock)) + if (atomic_read(&bo->gpu_usecount)) + return false; + + if (!mutex_trylock(&bo->mappings.lock)) return false; - panfrost_mmu_unmap(to_panfrost_bo(obj)); + if (!mutex_trylock(&shmem->pages_lock)) + goto unlock_mappings; + + panfrost_gem_teardown_mappings_locked(bo); drm_gem_shmem_purge_locked(obj); + ret = true; mutex_unlock(&shmem->pages_lock); - return true; + +unlock_mappings: + mutex_unlock(&bo->mappings.lock); + return ret; } static unsigned long --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -75,6 +75,17 @@ return 0; } +void panfrost_gpu_amlogic_quirk(struct panfrost_device *pfdev) +{ + /* + * The Amlogic integrated Mali-T820, Mali-G31 & Mali-G52 needs + * these undocumented bits in GPU_PWR_OVERRIDE1 to be set in order + * to operate correctly. + */ + gpu_write(pfdev, GPU_PWR_KEY, GPU_PWR_KEY_UNLOCK); + gpu_write(pfdev, GPU_PWR_OVERRIDE1, 0xfff | (0x20 << 16)); +} + static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev) { u32 quirks = 0; @@ -142,7 +153,6 @@ struct panfrost_model { const char *name; u32 id; - u32 id_mask; u64 features; u64 issues; struct { @@ -304,6 +314,8 @@ int ret; u32 val; + panfrost_gpu_init_quirks(pfdev); + /* Just turn on everything for now */ gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present); ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, @@ -357,7 +369,6 @@ return err; } - panfrost_gpu_init_quirks(pfdev); panfrost_gpu_power_on(pfdev); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_gpu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_gpu.h @@ -16,4 +16,6 @@ void panfrost_gpu_power_on(struct panfrost_device *pfdev); void panfrost_gpu_power_off(struct panfrost_device *pfdev); +void panfrost_gpu_amlogic_quirk(struct panfrost_device *pfdev); + #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_job.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_job.c @@ -269,9 +269,25 @@ dma_fence_put(job->done_fence); dma_fence_put(job->render_done_fence); + if (job->mappings) { + for (i = 0; i < job->bo_count; i++) { + if (!job->mappings[i]) + break; + + atomic_dec(&job->mappings[i]->obj->gpu_usecount); + panfrost_gem_mapping_put(job->mappings[i]); + } + kvfree(job->mappings); + } + if (job->bos) { - for (i = 0; i < job->bo_count; i++) + struct panfrost_gem_object *bo; + + for (i = 0; i < job->bo_count; i++) { + bo = to_panfrost_bo(job->bos[i]); drm_gem_object_put_unlocked(job->bos[i]); + } + kvfree(job->bos); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_job.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_job.h @@ -32,6 +32,7 @@ /* Exclusive fences we have taken from the BOs to wait for */ struct dma_fence **implicit_fences; + struct panfrost_gem_mapping **mappings; struct drm_gem_object **bos; u32 bo_count; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -52,25 +52,16 @@ } static void lock_region(struct panfrost_device *pfdev, u32 as_nr, - u64 iova, size_t size) + u64 iova, u64 size) { u8 region_width; u64 region = iova & PAGE_MASK; - /* - * fls returns: - * 1 .. 32 - * - * 10 + fls(num_pages) - * results in the range (11 .. 42) - */ - - size = round_up(size, PAGE_SIZE); - region_width = 10 + fls(size >> PAGE_SHIFT); - if ((size >> PAGE_SHIFT) != (1ul << (region_width - 11))) { - /* not pow2, so must go up to the next pow2 */ - region_width += 1; - } + /* The size is encoded as ceil(log2) minus(1), which may be calculated + * with fls. The size must be clamped to hardware bounds. + */ + size = max_t(u64, size, AS_LOCK_REGION_MIN_SIZE); + region_width = fls64(size - 1) - 1; region |= region_width; /* Lock the region that needs to be updated */ @@ -81,7 +72,7 @@ static int mmu_hw_do_operation_locked(struct panfrost_device *pfdev, int as_nr, - u64 iova, size_t size, u32 op) + u64 iova, u64 size, u32 op) { if (as_nr < 0) return 0; @@ -98,7 +89,7 @@ static int mmu_hw_do_operation(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, - u64 iova, size_t size, u32 op) + u64 iova, u64 size, u32 op) { int ret; @@ -115,7 +106,7 @@ u64 transtab = cfg->arm_mali_lpae_cfg.transtab; u64 memattr = cfg->arm_mali_lpae_cfg.memattr; - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0UL, AS_COMMAND_FLUSH_MEM); + mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM); mmu_write(pfdev, AS_TRANSTAB_LO(as_nr), transtab & 0xffffffffUL); mmu_write(pfdev, AS_TRANSTAB_HI(as_nr), transtab >> 32); @@ -131,7 +122,7 @@ static void panfrost_mmu_disable(struct panfrost_device *pfdev, u32 as_nr) { - mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0UL, AS_COMMAND_FLUSH_MEM); + mmu_hw_do_operation_locked(pfdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM); mmu_write(pfdev, AS_TRANSTAB_LO(as_nr), 0); mmu_write(pfdev, AS_TRANSTAB_HI(as_nr), 0); @@ -151,7 +142,12 @@ as = mmu->as; if (as >= 0) { int en = atomic_inc_return(&mmu->as_count); - WARN_ON(en >= NUM_JOB_SLOTS); + + /* + * AS can be retained by active jobs or a perfcnt context, + * hence the '+ 1' here. + */ + WARN_ON(en >= (NUM_JOB_SLOTS + 1)); list_move(&mmu->list, &pfdev->as_lru_list); goto out; @@ -226,7 +222,7 @@ static void panfrost_mmu_flush_range(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, - u64 iova, size_t size) + u64 iova, u64 size) { if (mmu->as < 0) return; @@ -237,7 +233,7 @@ if (pm_runtime_active(pfdev->dev)) mmu_hw_do_operation(pfdev, mmu, iova, size, AS_COMMAND_FLUSH_PT); - pm_runtime_put_sync_autosuspend(pfdev->dev); + pm_runtime_put_autosuspend(pfdev->dev); } static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu, @@ -269,14 +265,15 @@ return 0; } -int panfrost_mmu_map(struct panfrost_gem_object *bo) +int panfrost_mmu_map(struct panfrost_gem_mapping *mapping) { + struct panfrost_gem_object *bo = mapping->obj; struct drm_gem_object *obj = &bo->base.base; struct panfrost_device *pfdev = to_panfrost_device(obj->dev); struct sg_table *sgt; int prot = IOMMU_READ | IOMMU_WRITE; - if (WARN_ON(bo->is_mapped)) + if (WARN_ON(mapping->active)) return 0; if (bo->noexec) @@ -286,25 +283,28 @@ if (WARN_ON(IS_ERR(sgt))) return PTR_ERR(sgt); - mmu_map_sg(pfdev, bo->mmu, bo->node.start << PAGE_SHIFT, prot, sgt); - bo->is_mapped = true; + mmu_map_sg(pfdev, mapping->mmu, mapping->mmnode.start << PAGE_SHIFT, + prot, sgt); + mapping->active = true; return 0; } -void panfrost_mmu_unmap(struct panfrost_gem_object *bo) +void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping) { + struct panfrost_gem_object *bo = mapping->obj; struct drm_gem_object *obj = &bo->base.base; struct panfrost_device *pfdev = to_panfrost_device(obj->dev); - struct io_pgtable_ops *ops = bo->mmu->pgtbl_ops; - u64 iova = bo->node.start << PAGE_SHIFT; - size_t len = bo->node.size << PAGE_SHIFT; + struct io_pgtable_ops *ops = mapping->mmu->pgtbl_ops; + u64 iova = mapping->mmnode.start << PAGE_SHIFT; + size_t len = mapping->mmnode.size << PAGE_SHIFT; size_t unmapped_len = 0; - if (WARN_ON(!bo->is_mapped)) + if (WARN_ON(!mapping->active)) return; - dev_dbg(pfdev->dev, "unmap: as=%d, iova=%llx, len=%zx", bo->mmu->as, iova, len); + dev_dbg(pfdev->dev, "unmap: as=%d, iova=%llx, len=%zx", + mapping->mmu->as, iova, len); while (unmapped_len < len) { size_t unmapped_page; @@ -318,8 +318,9 @@ unmapped_len += pgsize; } - panfrost_mmu_flush_range(pfdev, bo->mmu, bo->node.start << PAGE_SHIFT, len); - bo->is_mapped = false; + panfrost_mmu_flush_range(pfdev, mapping->mmu, + mapping->mmnode.start << PAGE_SHIFT, len); + mapping->active = false; } static void mmu_tlb_inv_context_s1(void *cookie) @@ -394,10 +395,10 @@ free_io_pgtable_ops(mmu->pgtbl_ops); } -static struct panfrost_gem_object * -addr_to_drm_mm_node(struct panfrost_device *pfdev, int as, u64 addr) +static struct panfrost_gem_mapping * +addr_to_mapping(struct panfrost_device *pfdev, int as, u64 addr) { - struct panfrost_gem_object *bo = NULL; + struct panfrost_gem_mapping *mapping = NULL; struct panfrost_file_priv *priv; struct drm_mm_node *node; u64 offset = addr >> PAGE_SHIFT; @@ -418,8 +419,9 @@ drm_mm_for_each_node(node, &priv->mm) { if (offset >= node->start && offset < (node->start + node->size)) { - bo = drm_mm_node_to_panfrost_bo(node); - drm_gem_object_get(&bo->base.base); + mapping = drm_mm_node_to_panfrost_mapping(node); + + kref_get(&mapping->refcount); break; } } @@ -427,7 +429,7 @@ spin_unlock(&priv->mm_lock); out: spin_unlock(&pfdev->as_lock); - return bo; + return mapping; } #define NUM_FAULT_PAGES (SZ_2M / PAGE_SIZE) @@ -436,28 +438,30 @@ u64 addr) { int ret, i; + struct panfrost_gem_mapping *bomapping; struct panfrost_gem_object *bo; struct address_space *mapping; pgoff_t page_offset; struct sg_table *sgt; struct page **pages; - bo = addr_to_drm_mm_node(pfdev, as, addr); - if (!bo) + bomapping = addr_to_mapping(pfdev, as, addr); + if (!bomapping) return -ENOENT; + bo = bomapping->obj; if (!bo->is_heap) { dev_WARN(pfdev->dev, "matching BO is not heap type (GPU VA = %llx)", - bo->node.start << PAGE_SHIFT); + bomapping->mmnode.start << PAGE_SHIFT); ret = -EINVAL; goto err_bo; } - WARN_ON(bo->mmu->as != as); + WARN_ON(bomapping->mmu->as != as); /* Assume 2MB alignment and size multiple */ addr &= ~((u64)SZ_2M - 1); page_offset = addr >> PAGE_SHIFT; - page_offset -= bo->node.start; + page_offset -= bomapping->mmnode.start; mutex_lock(&bo->base.pages_lock); @@ -473,7 +477,7 @@ pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); if (!pages) { - kfree(bo->sgts); + kvfree(bo->sgts); bo->sgts = NULL; mutex_unlock(&bo->base.pages_lock); ret = -ENOMEM; @@ -481,18 +485,32 @@ } bo->base.pages = pages; bo->base.pages_use_count = 1; - } else + } else { pages = bo->base.pages; + if (pages[page_offset]) { + /* Pages are already mapped, bail out. */ + mutex_unlock(&bo->base.pages_lock); + goto out; + } + } mapping = bo->base.base.filp->f_mapping; mapping_set_unevictable(mapping); for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { + /* Can happen if the last fault only partially filled this + * section of the pages array before failing. In that case + * we skip already filled pages. + */ + if (pages[i]) + continue; + pages[i] = shmem_read_mapping_page(mapping, i); if (IS_ERR(pages[i])) { mutex_unlock(&bo->base.pages_lock); ret = PTR_ERR(pages[i]); - goto err_pages; + pages[i] = NULL; + goto err_bo; } } @@ -502,27 +520,27 @@ ret = sg_alloc_table_from_pages(sgt, pages + page_offset, NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL); if (ret) - goto err_pages; + goto err_bo; if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) { ret = -EINVAL; goto err_map; } - mmu_map_sg(pfdev, bo->mmu, addr, IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt); + mmu_map_sg(pfdev, bomapping->mmu, addr, + IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt); - bo->is_mapped = true; + bomapping->active = true; dev_dbg(pfdev->dev, "mapped page fault @ AS%d %llx", as, addr); - drm_gem_object_put_unlocked(&bo->base.base); +out: + panfrost_gem_mapping_put(bomapping); return 0; err_map: sg_free_table(sgt); -err_pages: - drm_gem_shmem_put_pages(&bo->base); err_bo: drm_gem_object_put_unlocked(&bo->base.base); return ret; @@ -586,36 +604,30 @@ access_type = (fault_status >> 8) & 0x3; source_id = (fault_status >> 16); - /* Page fault only */ - if ((status & mask) == BIT(i)) { - WARN_ON(exception_type < 0xC1 || exception_type > 0xC4); + mmu_write(pfdev, MMU_INT_CLEAR, mask); + /* Page fault only */ + ret = -1; + if ((status & mask) == BIT(i) && (exception_type & 0xF8) == 0xC0) ret = panfrost_mmu_map_fault_addr(pfdev, i, addr); - if (!ret) { - mmu_write(pfdev, MMU_INT_CLEAR, BIT(i)); - status &= ~mask; - continue; - } - } - /* terminal fault, print info about the fault */ - dev_err(pfdev->dev, - "Unhandled Page fault in AS%d at VA 0x%016llX\n" - "Reason: %s\n" - "raw fault status: 0x%X\n" - "decoded fault status: %s\n" - "exception type 0x%X: %s\n" - "access type 0x%X: %s\n" - "source id 0x%X\n", - i, addr, - "TODO", - fault_status, - (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), - exception_type, panfrost_exception_name(pfdev, exception_type), - access_type, access_type_name(pfdev, fault_status), - source_id); - - mmu_write(pfdev, MMU_INT_CLEAR, mask); + if (ret) + /* terminal fault, print info about the fault */ + dev_err(pfdev->dev, + "Unhandled Page fault in AS%d at VA 0x%016llX\n" + "Reason: %s\n" + "raw fault status: 0x%X\n" + "decoded fault status: %s\n" + "exception type 0x%X: %s\n" + "access type 0x%X: %s\n" + "source id 0x%X\n", + i, addr, + "TODO", + fault_status, + (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), + exception_type, panfrost_exception_name(pfdev, exception_type), + access_type, access_type_name(pfdev, fault_status), + source_id); status &= ~mask; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_mmu.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_mmu.h @@ -4,12 +4,12 @@ #ifndef __PANFROST_MMU_H__ #define __PANFROST_MMU_H__ -struct panfrost_gem_object; +struct panfrost_gem_mapping; struct panfrost_file_priv; struct panfrost_mmu; -int panfrost_mmu_map(struct panfrost_gem_object *bo); -void panfrost_mmu_unmap(struct panfrost_gem_object *bo); +int panfrost_mmu_map(struct panfrost_gem_mapping *mapping); +void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping); int panfrost_mmu_init(struct panfrost_device *pfdev); void panfrost_mmu_fini(struct panfrost_device *pfdev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_perfcnt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_perfcnt.c @@ -25,7 +25,7 @@ #define V4_SHADERS_PER_COREGROUP 4 struct panfrost_perfcnt { - struct panfrost_gem_object *bo; + struct panfrost_gem_mapping *mapping; size_t bosize; void *buf; struct panfrost_file_priv *user; @@ -49,7 +49,7 @@ int ret; reinit_completion(&pfdev->perfcnt->dump_comp); - gpuva = pfdev->perfcnt->bo->node.start << PAGE_SHIFT; + gpuva = pfdev->perfcnt->mapping->mmnode.start << PAGE_SHIFT; gpu_write(pfdev, GPU_PERFCNT_BASE_LO, gpuva); gpu_write(pfdev, GPU_PERFCNT_BASE_HI, gpuva >> 32); gpu_write(pfdev, GPU_INT_CLEAR, @@ -67,12 +67,13 @@ } static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, - struct panfrost_file_priv *user, + struct drm_file *file_priv, unsigned int counterset) { + struct panfrost_file_priv *user = file_priv->driver_priv; struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; struct drm_gem_shmem_object *bo; - u32 cfg; + u32 cfg, as; int ret; if (user == perfcnt->user) @@ -88,17 +89,22 @@ if (IS_ERR(bo)) return PTR_ERR(bo); - perfcnt->bo = to_panfrost_bo(&bo->base); - /* Map the perfcnt buf in the address space attached to file_priv. */ - ret = panfrost_mmu_map(perfcnt->bo); + ret = panfrost_gem_open(&bo->base, file_priv); if (ret) goto err_put_bo; + perfcnt->mapping = panfrost_gem_mapping_get(to_panfrost_bo(&bo->base), + user); + if (!perfcnt->mapping) { + ret = -EINVAL; + goto err_close_bo; + } + perfcnt->buf = drm_gem_shmem_vmap(&bo->base); if (IS_ERR(perfcnt->buf)) { ret = PTR_ERR(perfcnt->buf); - goto err_put_bo; + goto err_put_mapping; } /* @@ -120,12 +126,8 @@ perfcnt->user = user; - /* - * Always use address space 0 for now. - * FIXME: this needs to be updated when we start using different - * address space. - */ - cfg = GPU_PERFCNT_CFG_AS(0) | + as = panfrost_mmu_as_get(pfdev, perfcnt->mapping->mmu); + cfg = GPU_PERFCNT_CFG_AS(as) | GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_MANUAL); /* @@ -153,18 +155,26 @@ if (panfrost_has_hw_issue(pfdev, HW_ISSUE_8186)) gpu_write(pfdev, GPU_PRFCNT_TILER_EN, 0xffffffff); + /* The BO ref is retained by the mapping. */ + drm_gem_object_put_unlocked(&bo->base); + return 0; err_vunmap: - drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf); + drm_gem_shmem_vunmap(&bo->base, perfcnt->buf); +err_put_mapping: + panfrost_gem_mapping_put(perfcnt->mapping); +err_close_bo: + panfrost_gem_close(&bo->base, file_priv); err_put_bo: drm_gem_object_put_unlocked(&bo->base); return ret; } static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev, - struct panfrost_file_priv *user) + struct drm_file *file_priv) { + struct panfrost_file_priv *user = file_priv->driver_priv; struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; if (user != perfcnt->user) @@ -178,10 +188,12 @@ GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF)); perfcnt->user = NULL; - drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf); + drm_gem_shmem_vunmap(&perfcnt->mapping->obj->base.base, perfcnt->buf); perfcnt->buf = NULL; - drm_gem_object_put_unlocked(&perfcnt->bo->base.base); - perfcnt->bo = NULL; + panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv); + panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu); + panfrost_gem_mapping_put(perfcnt->mapping); + perfcnt->mapping = NULL; pm_runtime_mark_last_busy(pfdev->dev); pm_runtime_put_autosuspend(pfdev->dev); @@ -191,7 +203,6 @@ int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct panfrost_file_priv *pfile = file_priv->driver_priv; struct panfrost_device *pfdev = dev->dev_private; struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; struct drm_panfrost_perfcnt_enable *req = data; @@ -207,10 +218,10 @@ mutex_lock(&perfcnt->lock); if (req->enable) - ret = panfrost_perfcnt_enable_locked(pfdev, pfile, + ret = panfrost_perfcnt_enable_locked(pfdev, file_priv, req->counterset); else - ret = panfrost_perfcnt_disable_locked(pfdev, pfile); + ret = panfrost_perfcnt_disable_locked(pfdev, file_priv); mutex_unlock(&perfcnt->lock); return ret; @@ -248,15 +259,16 @@ return ret; } -void panfrost_perfcnt_close(struct panfrost_file_priv *pfile) +void panfrost_perfcnt_close(struct drm_file *file_priv) { + struct panfrost_file_priv *pfile = file_priv->driver_priv; struct panfrost_device *pfdev = pfile->pfdev; struct panfrost_perfcnt *perfcnt = pfdev->perfcnt; pm_runtime_get_sync(pfdev->dev); mutex_lock(&perfcnt->lock); if (perfcnt->user == pfile) - panfrost_perfcnt_disable_locked(pfdev, pfile); + panfrost_perfcnt_disable_locked(pfdev, file_priv); mutex_unlock(&perfcnt->lock); pm_runtime_mark_last_busy(pfdev->dev); pm_runtime_put_autosuspend(pfdev->dev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_perfcnt.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_perfcnt.h @@ -9,7 +9,7 @@ void panfrost_perfcnt_clean_cache_done(struct panfrost_device *pfdev); int panfrost_perfcnt_init(struct panfrost_device *pfdev); void panfrost_perfcnt_fini(struct panfrost_device *pfdev); -void panfrost_perfcnt_close(struct panfrost_file_priv *pfile); +void panfrost_perfcnt_close(struct drm_file *file_priv); int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data, struct drm_file *file_priv); int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/panfrost/panfrost_regs.h +++ linux-oracle-5.4.0/drivers/gpu/drm/panfrost/panfrost_regs.h @@ -51,6 +51,10 @@ #define GPU_STATUS 0x34 #define GPU_STATUS_PRFCNT_ACTIVE BIT(2) #define GPU_LATEST_FLUSH_ID 0x38 +#define GPU_PWR_KEY 0x50 /* (WO) Power manager key register */ +#define GPU_PWR_KEY_UNLOCK 0x2968A819 +#define GPU_PWR_OVERRIDE0 0x54 /* (RW) Power manager override settings */ +#define GPU_PWR_OVERRIDE1 0x58 /* (RW) Power manager override settings */ #define GPU_FAULT_STATUS 0x3C #define GPU_FAULT_ADDRESS_LO 0x40 #define GPU_FAULT_ADDRESS_HI 0x44 @@ -314,6 +318,8 @@ #define AS_FAULTSTATUS_ACCESS_TYPE_READ (0x2 << 8) #define AS_FAULTSTATUS_ACCESS_TYPE_WRITE (0x3 << 8) +#define AS_LOCK_REGION_MIN_SIZE (1ULL << 15) + #define gpu_write(dev, reg, data) writel(data, dev->iomem + reg) #define gpu_read(dev, reg) readl(dev->iomem + reg) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_cmd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_cmd.c @@ -480,9 +480,10 @@ return ret; ret = qxl_release_reserve_list(release, true); - if (ret) + if (ret) { + qxl_release_free(qdev, release); return ret; - + } cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); cmd->type = QXL_SURFACE_CMD_CREATE; cmd->flags = QXL_SURF_FLAG_KEEP_DATA; @@ -499,8 +500,8 @@ /* no need to add a release to the fence for this surface bo, since it is only released when we ask to destroy the surface and it would never signal otherwise */ - qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); qxl_release_fence_buffer_objects(release); + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); surf->hw_surf_alloc = true; spin_lock(&qdev->surf_id_idr_lock); @@ -542,9 +543,8 @@ cmd->surface_id = id; qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); - qxl_release_fence_buffer_objects(release); + qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_display.c @@ -230,6 +230,9 @@ return 0; mode = drm_cvt_mode(dev, width, height, 60, false, false, false); + if (!mode) + return 0; + if (preferred) mode->type |= DRM_MODE_TYPE_PREFERRED; mode->hdisplay = width; @@ -325,6 +328,7 @@ head.id = i; head.flags = 0; + head.surface_id = 0; oldcount = qdev->monitors_config->count; if (crtc->state->active) { struct drm_display_mode *mode = &crtc->mode; @@ -523,8 +527,8 @@ cmd->u.set.visible = 1; qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); qxl_release_fence_buffer_objects(release); + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); return ret; @@ -665,8 +669,8 @@ cmd->u.position.y = plane->state->crtc_y + fb->hot_y; qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); qxl_release_fence_buffer_objects(release); + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); if (old_cursor_bo != NULL) qxl_bo_unpin(old_cursor_bo); @@ -713,8 +717,8 @@ cmd->type = QXL_CURSOR_HIDE; qxl_release_unmap(qdev, release, &cmd->release_info); - qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); qxl_release_fence_buffer_objects(release); + qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); } static void qxl_update_dumb_head(struct qxl_device *qdev, @@ -1236,6 +1240,10 @@ void qxl_modeset_fini(struct qxl_device *qdev) { + if (qdev->dumb_shadow_bo) { + drm_gem_object_put(&qdev->dumb_shadow_bo->tbo.base); + qdev->dumb_shadow_bo = NULL; + } qxl_destroy_monitors_object(qdev); drm_mode_config_cleanup(&qdev->ddev); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_draw.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_draw.c @@ -209,9 +209,10 @@ goto out_release_backoff; rects = drawable_set_clipping(qdev, num_clips, clips_bo); - if (!rects) + if (!rects) { + ret = -EINVAL; goto out_release_backoff; - + } drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); drawable->clip.type = SPICE_CLIP_TYPE_RECTS; @@ -242,8 +243,8 @@ } qxl_bo_kunmap(clips_bo); - qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); qxl_release_fence_buffer_objects(release); + qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); out_release_backoff: if (ret) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_dumb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_dumb.c @@ -58,6 +58,8 @@ surf.height = args->height; surf.stride = pitch; surf.format = format; + surf.data = 0; + r = qxl_gem_object_create_with_handle(qdev, file_priv, QXL_GEM_DOMAIN_SURFACE, args->size, &surf, &qobj, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_image.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_image.c @@ -212,7 +212,8 @@ break; default: DRM_ERROR("unsupported image bit depth\n"); - return -EINVAL; /* TODO: cleanup */ + qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); + return -EINVAL; } image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; image->u.bitmap.x = width; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_ioctl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -261,11 +261,8 @@ apply_surf_reloc(qdev, &reloc_info[i]); } + qxl_release_fence_buffer_objects(release); ret = qxl_push_command_ring_release(qdev, release, cmd->type, true); - if (ret) - qxl_release_backoff_reserve_list(release); - else - qxl_release_fence_buffer_objects(release); out_free_bos: out_free_release: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/qxl/qxl_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/qxl/qxl_kms.c @@ -184,7 +184,7 @@ if (!qxl_check_device(qdev)) { r = -ENODEV; - goto surface_mapping_free; + goto rom_unmap; } r = qxl_bo_init(qdev); @@ -218,7 +218,7 @@ &(qdev->ram_header->cursor_ring_hdr), sizeof(struct qxl_command), QXL_CURSOR_RING_SIZE, - qdev->io_base + QXL_IO_NOTIFY_CMD, + qdev->io_base + QXL_IO_NOTIFY_CURSOR, false, &qdev->cursor_event); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/atombios.h +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/atombios.h @@ -3615,7 +3615,7 @@ { UCHAR ucRecordType; UCHAR ucFakeEDIDLength; - UCHAR ucFakeEDIDString[1]; // This actually has ucFakeEdidLength elements. + UCHAR ucFakeEDIDString[]; // This actually has ucFakeEdidLength elements. } ATOM_FAKE_EDID_PATCH_RECORD; typedef struct _ATOM_PANEL_RESOLUTION_PATCH_RECORD --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/atombios_encoders.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/atombios_encoders.c @@ -197,7 +197,8 @@ * so don't register a backlight device */ if ((rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) && - (rdev->pdev->device == 0x6741)) + (rdev->pdev->device == 0x6741) && + !dmi_match(DMI_PRODUCT_NAME, "iMac12,1")) return; if (!radeon_encoder->enc_priv) @@ -2191,11 +2192,12 @@ /* * On DCE32 any encoder can drive any block so usually just use crtc id, - * but Apple thinks different at least on iMac10,1, so there use linkb, + * but Apple thinks different at least on iMac10,1 and iMac11,2, so there use linkb, * otherwise the internal eDP panel will stay dark. */ if (ASIC_IS_DCE32(rdev)) { - if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1")) + if (dmi_match(DMI_PRODUCT_NAME, "iMac10,1") || + dmi_match(DMI_PRODUCT_NAME, "iMac11,2")) enc_idx = (dig->linkb) ? 1 : 0; else enc_idx = radeon_crtc->crtc_id; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/ci_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/ci_dpm.c @@ -4366,7 +4366,7 @@ table->mc_reg_table_entry[k].mc_data[j] |= 0x100; } j++; - if (j > SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE) + if (j >= SMU7_DISCRETE_MC_REGISTER_ARRAY_SIZE) return -EINVAL; if (!pi->mem_gddr5) { @@ -5556,6 +5556,7 @@ u8 frev, crev; u8 *power_state_offset; struct ci_ps *ps; + int ret; if (!atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset)) @@ -5578,18 +5579,21 @@ if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; + rdev->pm.dpm.num_ps = 0; for (i = 0; i < state_array->ucNumEntries; i++) { u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) - return -EINVAL; + if (!rdev->pm.power_state[i].clock_info) { + ret = -EINVAL; + goto err_free_ps; + } ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); if (ps == NULL) { - kfree(rdev->pm.dpm.ps); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_ps; } rdev->pm.dpm.ps[i].ps_priv = ps; ci_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i], @@ -5612,8 +5616,8 @@ k++; } power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + rdev->pm.dpm.num_ps = i + 1; } - rdev->pm.dpm.num_ps = state_array->ucNumEntries; /* fill in the vce power states */ for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) { @@ -5630,6 +5634,12 @@ } return 0; + +err_free_ps: + for (i = 0; i < rdev->pm.dpm.num_ps; i++) + kfree(rdev->pm.dpm.ps[i].ps_priv); + kfree(rdev->pm.dpm.ps); + return ret; } static int ci_get_vbios_boot_values(struct radeon_device *rdev, @@ -5718,25 +5728,26 @@ ret = ci_get_vbios_boot_values(rdev, &pi->vbios_boot_state); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; } ret = r600_get_platform_caps(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; } ret = r600_parse_extended_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); return ret; } ret = ci_parse_power_table(rdev); if (ret) { - ci_dpm_fini(rdev); + kfree(rdev->pm.dpm.priv); + r600_free_extended_power_table(rdev); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/cik.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/cik.c @@ -6969,8 +6969,8 @@ } /* setup interrupt control */ - /* XXX this should actually be a bus address, not an MC address. same on older asics */ - WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); + /* set dummy read address to dummy page address */ + WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8); interrupt_cntl = RREG32(INTERRUPT_CNTL); /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN @@ -9504,7 +9504,6 @@ { struct pci_dev *root = rdev->pdev->bus->self; enum pci_bus_speed speed_cap; - int bridge_pos, gpu_pos; u32 speed_cntl, current_data_rate; int i; u16 tmp16; @@ -9546,12 +9545,7 @@ DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); } - bridge_pos = pci_pcie_cap(root); - if (!bridge_pos) - return; - - gpu_pos = pci_pcie_cap(rdev->pdev); - if (!gpu_pos) + if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev)) return; if (speed_cap == PCIE_SPEED_8_0GT) { @@ -9561,14 +9555,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -9586,15 +9574,23 @@ for (i = 0; i < 10; i++) { /* check status */ - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_DEVSTA, + &tmp16); if (tmp16 & PCI_EXP_DEVSTA_TRPND) break; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2); + pcie_capability_read_word(root, PCI_EXP_LNKCTL, + &bridge_cfg); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL, + &gpu_cfg); + + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &bridge_cfg2); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL2, + &gpu_cfg2); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp |= LC_SET_QUIESCE; @@ -9607,26 +9603,38 @@ msleep(100); /* linkctl */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16); - - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(root, + PCI_EXP_LNKCTL2, + tmp16); + + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(rdev->pdev, + PCI_EXP_LNKCTL2, + tmp16); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -9640,15 +9648,15 @@ speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~0xf; + pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); + tmp16 &= ~PCI_EXP_LNKCTL2_TLS; if (speed_cap == PCIE_SPEED_8_0GT) - tmp16 |= 3; /* gen3 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (speed_cap == PCIE_SPEED_5_0GT) - tmp16 |= 2; /* gen2 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else - tmp16 |= 1; /* gen1 */ - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ + pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/cypress_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/cypress_dpm.c @@ -559,8 +559,12 @@ ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); mpll_ss1 &= ~CLKV_MASK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/evergreen.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/evergreen.c @@ -4819,14 +4819,15 @@ break; case 44: /* hdmi */ afmt_idx = src_data; - if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) - DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); - if (afmt_idx > 5) { DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); break; } + + if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG; queue_hdmi = true; DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/evergreen_cs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/evergreen_cs.c @@ -396,7 +396,7 @@ struct evergreen_cs_track *track = p->track; struct eg_surface surf; unsigned pitch, slice, mslice; - unsigned long offset; + u64 offset; int r; mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1; @@ -434,14 +434,14 @@ return r; } - offset = track->cb_color_bo_offset[id] << 8; + offset = (u64)track->cb_color_bo_offset[id] << 8; if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n", + dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n", __func__, __LINE__, id, offset, surf.base_align); return -EINVAL; } - offset += surf.layer_size * mslice; + offset += (u64)surf.layer_size * mslice; if (offset > radeon_bo_size(track->cb_color_bo[id])) { /* old ddx are broken they allocate bo with w*h*bpp but * program slice with ALIGN(h, 8), catch this and patch @@ -449,14 +449,14 @@ */ if (!surf.mode) { uint32_t *ib = p->ib.ptr; - unsigned long tmp, nby, bsize, size, min = 0; + u64 tmp, nby, bsize, size, min = 0; /* find the height the ddx wants */ if (surf.nby > 8) { min = surf.nby - 8; } bsize = radeon_bo_size(track->cb_color_bo[id]); - tmp = track->cb_color_bo_offset[id] << 8; + tmp = (u64)track->cb_color_bo_offset[id] << 8; for (nby = surf.nby; nby > min; nby--) { size = nby * surf.nbx * surf.bpe * surf.nsamples; if ((tmp + size * mslice) <= bsize) { @@ -468,7 +468,7 @@ slice = ((nby * surf.nbx) / 64) - 1; if (!evergreen_surface_check(p, &surf, "cb")) { /* check if this one works */ - tmp += surf.layer_size * mslice; + tmp += (u64)surf.layer_size * mslice; if (tmp <= bsize) { ib[track->cb_color_slice_idx[id]] = slice; goto old_ddx_ok; @@ -477,9 +477,9 @@ } } dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " - "offset %d, max layer %d, bo size %ld, slice %d)\n", + "offset %llu, max layer %d, bo size %ld, slice %d)\n", __func__, __LINE__, id, surf.layer_size, - track->cb_color_bo_offset[id] << 8, mslice, + (u64)track->cb_color_bo_offset[id] << 8, mslice, radeon_bo_size(track->cb_color_bo[id]), slice); dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", __func__, __LINE__, surf.nbx, surf.nby, @@ -563,7 +563,7 @@ struct evergreen_cs_track *track = p->track; struct eg_surface surf; unsigned pitch, slice, mslice; - unsigned long offset; + u64 offset; int r; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; @@ -609,18 +609,18 @@ return r; } - offset = track->db_s_read_offset << 8; + offset = (u64)track->db_s_read_offset << 8; if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", + dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n", __func__, __LINE__, offset, surf.base_align); return -EINVAL; } - offset += surf.layer_size * mslice; + offset += (u64)surf.layer_size * mslice; if (offset > radeon_bo_size(track->db_s_read_bo)) { dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", + "offset %llu, max layer %d, bo size %ld)\n", __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_s_read_offset << 8, mslice, + (u64)track->db_s_read_offset << 8, mslice, radeon_bo_size(track->db_s_read_bo)); dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", __func__, __LINE__, track->db_depth_size, @@ -628,18 +628,18 @@ return -EINVAL; } - offset = track->db_s_write_offset << 8; + offset = (u64)track->db_s_write_offset << 8; if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", + dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n", __func__, __LINE__, offset, surf.base_align); return -EINVAL; } - offset += surf.layer_size * mslice; + offset += (u64)surf.layer_size * mslice; if (offset > radeon_bo_size(track->db_s_write_bo)) { dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", + "offset %llu, max layer %d, bo size %ld)\n", __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_s_write_offset << 8, mslice, + (u64)track->db_s_write_offset << 8, mslice, radeon_bo_size(track->db_s_write_bo)); return -EINVAL; } @@ -660,7 +660,7 @@ struct evergreen_cs_track *track = p->track; struct eg_surface surf; unsigned pitch, slice, mslice; - unsigned long offset; + u64 offset; int r; mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; @@ -707,34 +707,34 @@ return r; } - offset = track->db_z_read_offset << 8; + offset = (u64)track->db_z_read_offset << 8; if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", + dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n", __func__, __LINE__, offset, surf.base_align); return -EINVAL; } - offset += surf.layer_size * mslice; + offset += (u64)surf.layer_size * mslice; if (offset > radeon_bo_size(track->db_z_read_bo)) { dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", + "offset %llu, max layer %d, bo size %ld)\n", __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_z_read_offset << 8, mslice, + (u64)track->db_z_read_offset << 8, mslice, radeon_bo_size(track->db_z_read_bo)); return -EINVAL; } - offset = track->db_z_write_offset << 8; + offset = (u64)track->db_z_write_offset << 8; if (offset & (surf.base_align - 1)) { - dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", + dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n", __func__, __LINE__, offset, surf.base_align); return -EINVAL; } - offset += surf.layer_size * mslice; + offset += (u64)surf.layer_size * mslice; if (offset > radeon_bo_size(track->db_z_write_bo)) { dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, " - "offset %ld, max layer %d, bo size %ld)\n", + "offset %llu, max layer %d, bo size %ld)\n", __func__, __LINE__, surf.layer_size, - (unsigned long)track->db_z_write_offset << 8, mslice, + (u64)track->db_z_write_offset << 8, mslice, radeon_bo_size(track->db_z_write_bo)); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/ni.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/ni.c @@ -826,7 +826,7 @@ err = 0; } else if (rdev->smc_fw->size != smc_req_size) { pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n", - rdev->mc_fw->size, fw_name); + rdev->smc_fw->size, fw_name); err = -EINVAL; } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/ni_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/ni_dpm.c @@ -2128,7 +2128,7 @@ if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) ret = -EINVAL; - if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT)) + if (fb_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT)) ret = -EINVAL; if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT)) @@ -2241,8 +2241,12 @@ ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = ss.percentage * (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625); mpll_ss1 &= ~CLKV_MASK; @@ -2740,10 +2744,10 @@ table->mc_reg_table_entry[k].mc_data[j] |= 0x100; } j++; - if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; break; case MC_SEQ_RESERVE_M >> 2: + if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) + return -EINVAL; temp_reg = RREG32(MC_PMG_CMD_MRS1); table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2; table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2; @@ -2752,8 +2756,6 @@ (temp_reg & 0xffff0000) | (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff); j++; - if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE) - return -EINVAL; break; default: break; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/r100.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/r100.c @@ -1005,45 +1005,65 @@ DRM_DEBUG_KMS("\n"); - if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || - (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || - (rdev->family == CHIP_RS200)) { + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RV200: + case CHIP_RS100: + case CHIP_RS200: DRM_INFO("Loading R100 Microcode\n"); fw_name = FIRMWARE_R100; - } else if ((rdev->family == CHIP_R200) || - (rdev->family == CHIP_RV250) || - (rdev->family == CHIP_RV280) || - (rdev->family == CHIP_RS300)) { + break; + + case CHIP_R200: + case CHIP_RV250: + case CHIP_RV280: + case CHIP_RS300: DRM_INFO("Loading R200 Microcode\n"); fw_name = FIRMWARE_R200; - } else if ((rdev->family == CHIP_R300) || - (rdev->family == CHIP_R350) || - (rdev->family == CHIP_RV350) || - (rdev->family == CHIP_RV380) || - (rdev->family == CHIP_RS400) || - (rdev->family == CHIP_RS480)) { + break; + + case CHIP_R300: + case CHIP_R350: + case CHIP_RV350: + case CHIP_RV380: + case CHIP_RS400: + case CHIP_RS480: DRM_INFO("Loading R300 Microcode\n"); fw_name = FIRMWARE_R300; - } else if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { + break; + + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: DRM_INFO("Loading R400 Microcode\n"); fw_name = FIRMWARE_R420; - } else if ((rdev->family == CHIP_RS690) || - (rdev->family == CHIP_RS740)) { + break; + + case CHIP_RS690: + case CHIP_RS740: DRM_INFO("Loading RS690/RS740 Microcode\n"); fw_name = FIRMWARE_RS690; - } else if (rdev->family == CHIP_RS600) { + break; + + case CHIP_RS600: DRM_INFO("Loading RS600 Microcode\n"); fw_name = FIRMWARE_RS600; - } else if ((rdev->family == CHIP_RV515) || - (rdev->family == CHIP_R520) || - (rdev->family == CHIP_RV530) || - (rdev->family == CHIP_R580) || - (rdev->family == CHIP_RV560) || - (rdev->family == CHIP_RV570)) { + break; + + case CHIP_RV515: + case CHIP_R520: + case CHIP_RV530: + case CHIP_R580: + case CHIP_RV560: + case CHIP_RV570: DRM_INFO("Loading R500 Microcode\n"); fw_name = FIRMWARE_R520; + break; + + default: + DRM_ERROR("Unsupported Radeon family %u\n", rdev->family); + return -EINVAL; } err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); @@ -1826,8 +1846,8 @@ track->textures[i].use_pitch = 1; } else { track->textures[i].use_pitch = 0; - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); + track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); + track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); } if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) track->textures[i].tex_coord_type = 2; @@ -2313,7 +2333,7 @@ switch (prim_walk) { case 1: for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * track->max_indx * 4; + size = track->arrays[i].esize * track->max_indx * 4UL; if (track->arrays[i].robj == NULL) { DRM_ERROR("(PW %u) Vertex array %u no buffer " "bound\n", prim_walk, i); @@ -2332,7 +2352,7 @@ break; case 2: for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * (nverts - 1) * 4; + size = track->arrays[i].esize * (nverts - 1) * 4UL; if (track->arrays[i].robj == NULL) { DRM_ERROR("(PW %u) Vertex array %u no buffer " "bound\n", prim_walk, i); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/r200.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/r200.c @@ -476,8 +476,8 @@ track->textures[i].use_pitch = 1; } else { track->textures[i].use_pitch = 0; - track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); - track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); + track->textures[i].width = 1 << ((idx_value & RADEON_TXFORMAT_WIDTH_MASK) >> RADEON_TXFORMAT_WIDTH_SHIFT); + track->textures[i].height = 1 << ((idx_value & RADEON_TXFORMAT_HEIGHT_MASK) >> RADEON_TXFORMAT_HEIGHT_SHIFT); } if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE) track->textures[i].lookup_disable = true; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/r300.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/r300.c @@ -361,7 +361,8 @@ return -1; } -static void r300_gpu_init(struct radeon_device *rdev) +/* rs400_gpu_init also calls this! */ +void r300_gpu_init(struct radeon_device *rdev) { uint32_t gb_tile_config, tmp; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/r600.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/r600.c @@ -3696,8 +3696,8 @@ } /* setup interrupt control */ - /* set dummy read address to ring address */ - WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); + /* set dummy read address to dummy page address */ + WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8); interrupt_cntl = RREG32(INTERRUPT_CNTL); /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/r600_cs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/r600_cs.c @@ -1278,7 +1278,7 @@ return -EINVAL; } tmp = (reg - CB_COLOR0_BASE) / 4; - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; + track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); track->cb_color_base_last[tmp] = ib[idx]; track->cb_color_bo[tmp] = reloc->robj; @@ -1305,7 +1305,7 @@ "0x%04X\n", reg); return -EINVAL; } - track->htile_offset = radeon_get_ib_value(p, idx) << 8; + track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); track->htile_bo = reloc->robj; track->db_dirty = true; @@ -2104,7 +2104,7 @@ return -EINVAL; } - offset = radeon_get_ib_value(p, idx+1) << 8; + offset = (u64)radeon_get_ib_value(p, idx+1) << 8; if (offset != track->vgt_strmout_bo_offset[idx_value]) { DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", offset, track->vgt_strmout_bo_offset[idx_value]); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon.h +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon.h @@ -1554,6 +1554,7 @@ void *priv; u32 new_active_crtcs; int new_active_crtc_count; + int high_pixelclock_count; u32 current_active_crtcs; int current_active_crtc_count; bool single_display; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_asic.h +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_asic.h @@ -165,6 +165,7 @@ */ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); +extern void r300_gpu_init(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); extern int r300_asic_reset(struct radeon_device *rdev, bool hard); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_atombios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1730,23 +1730,29 @@ fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; if (fake_edid_record->ucFakeEDIDLength) { struct edid *edid; - int edid_size = - max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength); - edid = kmalloc(edid_size, GFP_KERNEL); - if (edid) { - memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], - fake_edid_record->ucFakeEDIDLength); + int edid_size; + if (fake_edid_record->ucFakeEDIDLength == 128) + edid_size = fake_edid_record->ucFakeEDIDLength; + else + edid_size = fake_edid_record->ucFakeEDIDLength * 128; + edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0], + edid_size, GFP_KERNEL); + if (edid) { if (drm_edid_is_valid(edid)) { rdev->mode_info.bios_hardcoded_edid = edid; rdev->mode_info.bios_hardcoded_edid_size = edid_size; - } else + } else { kfree(edid); + } } + record += struct_size(fake_edid_record, + ucFakeEDIDString, + edid_size); + } else { + /* empty fake edid record must be 3 bytes long */ + record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1; } - record += fake_edid_record->ucFakeEDIDLength ? - fake_edid_record->ucFakeEDIDLength + 2 : - sizeof(ATOM_FAKE_EDID_PATCH_RECORD); break; case LCD_PANEL_RESOLUTION_RECORD_TYPE: panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; @@ -2136,11 +2142,14 @@ return state_index; /* last mode is usually default, array is low to high */ for (i = 0; i < num_modes; i++) { - rdev->pm.power_state[state_index].clock_info = - kcalloc(1, sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + /* avoid memory leaks from invalid modes or unknown frev. */ + if (!rdev->pm.power_state[state_index].clock_info) { + rdev->pm.power_state[state_index].clock_info = + kzalloc(sizeof(struct radeon_pm_clock_info), + GFP_KERNEL); + } if (!rdev->pm.power_state[state_index].clock_info) - return state_index; + goto out; rdev->pm.power_state[state_index].num_clock_modes = 1; rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; switch (frev) { @@ -2259,17 +2268,24 @@ break; } } +out: + /* free any unused clock_info allocation. */ + if (state_index && state_index < num_modes) { + kfree(rdev->pm.power_state[state_index].clock_info); + rdev->pm.power_state[state_index].clock_info = NULL; + } + /* last mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { + if (state_index && rdev->pm.default_power_state_index == -1) { rdev->pm.power_state[state_index - 1].type = POWER_STATE_TYPE_DEFAULT; rdev->pm.default_power_state_index = state_index - 1; rdev->pm.power_state[state_index - 1].default_clock_mode = &rdev->pm.power_state[state_index - 1].clock_info[0]; - rdev->pm.power_state[state_index].flags &= + rdev->pm.power_state[state_index - 1].flags &= ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = 0; - rdev->pm.power_state[state_index].misc2 = 0; + rdev->pm.power_state[state_index - 1].misc = 0; + rdev->pm.power_state[state_index - 1].misc2 = 0; } return state_index; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_bios.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_bios.c @@ -108,25 +108,33 @@ static bool radeon_read_platform_bios(struct radeon_device *rdev) { - uint8_t __iomem *bios; - size_t size; + phys_addr_t rom = rdev->pdev->rom; + size_t romlen = rdev->pdev->romlen; + void __iomem *bios; rdev->bios = NULL; - bios = pci_platform_rom(rdev->pdev, &size); - if (!bios) { + if (!rom || romlen == 0) return false; - } - if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { - return false; - } - rdev->bios = kmemdup(bios, size, GFP_KERNEL); - if (rdev->bios == NULL) { + rdev->bios = kzalloc(romlen, GFP_KERNEL); + if (!rdev->bios) return false; - } + + bios = ioremap(rom, romlen); + if (!bios) + goto free_bios; + + memcpy_fromio(rdev->bios, bios, romlen); + iounmap(bios); + + if (rdev->bios[0] != 0x55 || rdev->bios[1] != 0xaa) + goto free_bios; return true; +free_bios: + kfree(rdev->bios); + return false; } #ifdef CONFIG_ACPI @@ -219,6 +227,7 @@ if (!found) return false; + pci_dev_put(pdev); rdev->bios = kmalloc(size, GFP_KERNEL); if (!rdev->bios) { @@ -604,13 +613,14 @@ acpi_size tbl_size; UEFI_ACPI_VFCT *vfct; unsigned offset; + bool r = false; if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr))) return false; tbl_size = hdr->length; if (tbl_size < sizeof(UEFI_ACPI_VFCT)) { DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n"); - return false; + goto out; } vfct = (UEFI_ACPI_VFCT *)hdr; @@ -623,13 +633,13 @@ offset += sizeof(VFCT_IMAGE_HEADER); if (offset > tbl_size) { DRM_ERROR("ACPI VFCT image header truncated\n"); - return false; + goto out; } offset += vhdr->ImageLength; if (offset > tbl_size) { DRM_ERROR("ACPI VFCT image truncated\n"); - return false; + goto out; } if (vhdr->ImageLength && @@ -641,15 +651,18 @@ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); + if (rdev->bios) + r = true; - if (!rdev->bios) - return false; - return true; + goto out; } } DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n"); - return false; + +out: + acpi_put_table(hdr); + return r; } #else static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_connectors.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_connectors.c @@ -477,6 +477,8 @@ native_mode->vdisplay != 0 && native_mode->clock != 0) { mode = drm_mode_duplicate(dev, native_mode); + if (!mode) + return NULL; mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; drm_mode_set_name(mode); @@ -491,6 +493,8 @@ * simpler. */ mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); + if (!mode) + return NULL; mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); } @@ -883,8 +887,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (encoder) { @@ -1029,8 +1035,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } encoder = radeon_best_single_encoder(connector); @@ -1167,8 +1175,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } encoder = radeon_best_single_encoder(connector); @@ -1251,8 +1261,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (radeon_connector->detected_hpd_without_ddc) { @@ -1666,8 +1678,10 @@ if (!drm_kms_helper_is_poll_worker()) { r = pm_runtime_get_sync(connector->dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(connector->dev->dev); return connector_status_disconnected; + } } if (!force && radeon_check_hpd_status_unchanged(connector)) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_cs.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_cs.c @@ -271,7 +271,8 @@ { struct drm_radeon_cs *cs = data; uint64_t *chunk_array_ptr; - unsigned size, i; + u64 size; + unsigned i; u32 ring = RADEON_CS_RING_GFX; s32 priority = 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_device.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_device.c @@ -1022,6 +1022,7 @@ { if (rdev->mode_info.atom_context) { kfree(rdev->mode_info.atom_context->scratch); + kfree(rdev->mode_info.atom_context->iio); } kfree(rdev->mode_info.atom_context); rdev->mode_info.atom_context = NULL; @@ -1623,6 +1624,9 @@ if (r) { /* delay GPU reset to resume */ radeon_fence_driver_force_completion(rdev, i); + } else { + /* finish executing delayed work */ + flush_delayed_work(&rdev->fence_drv[i].lockup_work); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_display.c @@ -127,6 +127,8 @@ DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id); + msleep(10); + WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset, (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) | NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS))); @@ -629,8 +631,10 @@ dev = set->crtc->dev; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } ret = drm_crtc_helper_set_config(set, ctx); @@ -678,11 +682,16 @@ if (radeon_crtc == NULL) return; + radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); + if (!radeon_crtc->flip_queue) { + kfree(radeon_crtc); + return; + } + drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); radeon_crtc->crtc_id = index; - radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); rdev->mode_info.crtcs[index] = radeon_crtc; if (rdev->family >= CHIP_BONAIRE) { @@ -1329,6 +1338,7 @@ /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ if (obj->import_attach) { DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n"); + drm_gem_object_put(obj); return ERR_PTR(-EINVAL); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_drv.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -173,12 +174,7 @@ int radeon_modeset = -1; int radeon_dynclks = -1; int radeon_r4xx_atom = 0; -#ifdef __powerpc__ -/* Default to PCI on PowerPC (fdo #95017) */ int radeon_agpmode = -1; -#else -int radeon_agpmode = 0; -#endif int radeon_vram_limit = 0; int radeon_gart_size = -1; /* auto */ int radeon_benchmarking = 0; @@ -325,6 +321,7 @@ const struct pci_device_id *ent) { unsigned long flags = 0; + struct drm_device *dev; int ret; if (!ent) @@ -365,7 +362,44 @@ if (ret) return ret; - return drm_get_pci_dev(pdev, ent, &kms_driver); + dev = drm_dev_alloc(&kms_driver, &pdev->dev); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + ret = pci_enable_device(pdev); + if (ret) + goto err_free; + + dev->pdev = pdev; +#ifdef __alpha__ + dev->hose = pdev->sysdata; +#endif + + pci_set_drvdata(pdev, dev); + + if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) + dev->agp = drm_agp_init(dev); + if (dev->agp) { + dev->agp->agp_mtrr = arch_phys_wc_add( + dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size * + 1024 * 1024); + } + + ret = drm_dev_register(dev, ent->driver_data); + if (ret) + goto err_agp; + + return 0; + +err_agp: + if (dev->agp) + arch_phys_wc_del(dev->agp->agp_mtrr); + kfree(dev->agp); + pci_disable_device(pdev); +err_free: + drm_dev_put(dev); + return ret; } static void @@ -516,8 +550,10 @@ long ret; dev = file_priv->minor->dev; ret = pm_runtime_get_sync(dev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(dev->dev); return ret; + } ret = drm_ioctl(filp, cmd, arg); @@ -578,7 +614,7 @@ static struct drm_driver kms_driver = { .driver_features = - DRIVER_USE_AGP | DRIVER_GEM | DRIVER_RENDER, + DRIVER_GEM | DRIVER_RENDER, .load = radeon_driver_load_kms, .open = radeon_driver_open_kms, .postclose = radeon_driver_postclose_kms, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_gem.c @@ -384,7 +384,6 @@ struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_set_domain *args = data; struct drm_gem_object *gobj; - struct radeon_bo *robj; int r; /* for now if someone requests domain CPU - @@ -397,13 +396,12 @@ up_read(&rdev->exclusive_lock); return -ENOENT; } - robj = gem_to_radeon_bo(gobj); r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); drm_gem_object_put_unlocked(gobj); up_read(&rdev->exclusive_lock); - r = radeon_gem_handle_lockup(robj->rdev, r); + r = radeon_gem_handle_lockup(rdev, r); return r; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_kms.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -77,6 +78,11 @@ radeon_modeset_fini(rdev); radeon_device_fini(rdev); + if (dev->agp) + arch_phys_wc_del(dev->agp->agp_mtrr); + kfree(dev->agp); + dev->agp = NULL; + done_free: kfree(rdev); dev->dev_private = NULL; @@ -506,6 +512,7 @@ *value = rdev->config.si.backend_enable_mask; } else { DRM_DEBUG_KMS("BACKEND_ENABLED_MASK is si+ only!\n"); + return -EINVAL; } break; case RADEON_INFO_MAX_SCLK: @@ -627,58 +634,66 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) { struct radeon_device *rdev = dev->dev_private; + struct radeon_fpriv *fpriv; + struct radeon_vm *vm; int r; file_priv->driver_priv = NULL; r = pm_runtime_get_sync(dev->dev); - if (r < 0) + if (r < 0) { + pm_runtime_put_autosuspend(dev->dev); return r; + } /* new gpu have virtual address space support */ if (rdev->family >= CHIP_CAYMAN) { - struct radeon_fpriv *fpriv; - struct radeon_vm *vm; fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); if (unlikely(!fpriv)) { r = -ENOMEM; - goto out_suspend; + goto err_suspend; } if (rdev->accel_working) { vm = &fpriv->vm; r = radeon_vm_init(rdev, vm); - if (r) { - kfree(fpriv); - goto out_suspend; - } + if (r) + goto err_fpriv; r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); - if (r) { - radeon_vm_fini(rdev, vm); - kfree(fpriv); - goto out_suspend; - } + if (r) + goto err_vm_fini; /* map the ib pool buffer read only into * virtual address space */ vm->ib_bo_va = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo); + if (!vm->ib_bo_va) { + r = -ENOMEM; + goto err_vm_fini; + } + r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va, RADEON_VA_IB_OFFSET, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); - if (r) { - radeon_vm_fini(rdev, vm); - kfree(fpriv); - goto out_suspend; - } + if (r) + goto err_vm_fini; } file_priv->driver_priv = fpriv; } -out_suspend: + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); + return 0; + +err_vm_fini: + radeon_vm_fini(rdev, vm); +err_fpriv: + kfree(fpriv); + +err_suspend: pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); return r; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_pm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_pm.c @@ -1720,6 +1720,7 @@ struct drm_device *ddev = rdev->ddev; struct drm_crtc *crtc; struct radeon_crtc *radeon_crtc; + struct radeon_connector *radeon_connector; if (!rdev->pm.dpm_enabled) return; @@ -1729,6 +1730,7 @@ /* update active crtc counts */ rdev->pm.dpm.new_active_crtcs = 0; rdev->pm.dpm.new_active_crtc_count = 0; + rdev->pm.dpm.high_pixelclock_count = 0; if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { @@ -1736,6 +1738,12 @@ if (crtc->enabled) { rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); rdev->pm.dpm.new_active_crtc_count++; + if (!radeon_crtc->connector) + continue; + + radeon_connector = to_radeon_connector(radeon_crtc->connector); + if (radeon_connector->pixelclock_for_modeset > 297000) + rdev->pm.dpm.high_pixelclock_count++; } } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_prime.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_prime.c @@ -94,9 +94,19 @@ /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (likely(ret == 0)) - bo->prime_shared_count++; + if (unlikely(ret)) + goto error; + if (bo->tbo.moving) { + ret = dma_fence_wait(bo->tbo.moving, false); + if (unlikely(ret)) { + radeon_bo_unpin(bo); + goto error; + } + } + + bo->prime_shared_count++; +error: radeon_bo_unreserve(bo); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_uvd.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_uvd.c @@ -286,7 +286,7 @@ if (rdev->uvd.vcpu_bo == NULL) return -EINVAL; - memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); + memcpy_toio((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); size = radeon_bo_size(rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size; @@ -294,7 +294,7 @@ ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size; - memset(ptr, 0, size); + memset_io((void __iomem *)ptr, 0, size); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/radeon_vm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/radeon_vm.c @@ -1206,13 +1206,17 @@ r = radeon_bo_create(rdev, pd_size, align, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &vm->page_directory); - if (r) + if (r) { + kfree(vm->page_tables); + vm->page_tables = NULL; return r; - + } r = radeon_vm_clear_bo(rdev, vm->page_directory); if (r) { radeon_bo_unref(&vm->page_directory); vm->page_directory = NULL; + kfree(vm->page_tables); + vm->page_tables = NULL; return r; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/rs400.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/rs400.c @@ -257,8 +257,22 @@ static void rs400_gpu_init(struct radeon_device *rdev) { - /* FIXME: is this correct ? */ - r420_pipes_init(rdev); + /* Earlier code was calling r420_pipes_init and then + * rs400_mc_wait_for_idle(rdev). The problem is that + * at least on my Mobility Radeon Xpress 200M RC410 card + * that ends up in this code path ends up num_gb_pipes == 3 + * while the card seems to have only one pipe. With the + * r420 pipe initialization method. + * + * Problems shown up as HyperZ glitches, see: + * https://bugs.freedesktop.org/show_bug.cgi?id=110897 + * + * Delegating initialization to r300 code seems to work + * and results in proper pipe numbers. The rs400 cards + * are said to be not r400, but r300 kind of cards. + */ + r300_gpu_init(rdev); + if (rs400_mc_wait_for_idle(rdev)) { pr_warn("rs400: Failed to wait MC idle while programming pipes. Bad things might happen. %08x\n", RREG32(RADEON_MC_STATUS)); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/rv740_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/rv740_dpm.c @@ -250,8 +250,12 @@ ASIC_INTERNAL_MEMORY_SS, vco_freq)) { u32 reference_clock = rdev->clock.mpll.reference_freq; u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div); - u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); - u32 clk_v = 0x40000 * ss.percentage * + u32 clk_s, clk_v; + + if (!decoded_ref) + return -EINVAL; + clk_s = reference_clock * 5 / (decoded_ref * ss.rate); + clk_v = 0x40000 * ss.percentage * (dividers.whole_fb_div + (dividers.frac_fb_div / 8)) / (clk_s * 10000); mpll_ss1 &= ~CLKV_MASK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/si.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/si.c @@ -3257,7 +3257,7 @@ /* XXX what about 12? */ rdev->config.si.tile_config |= (3 << 0); break; - } + } switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { case 0: /* four banks */ rdev->config.si.tile_config |= 0 << 4; @@ -3616,6 +3616,10 @@ for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { ring = &rdev->ring[i]; r = radeon_ring_lock(rdev, ring, 2); + if (r) { + DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); + return r; + } /* clear the compute context state */ radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); @@ -5997,8 +6001,8 @@ } /* setup interrupt control */ - /* set dummy read address to ring address */ - WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); + /* set dummy read address to dummy page address */ + WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8); interrupt_cntl = RREG32(INTERRUPT_CNTL); /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN @@ -7087,7 +7091,6 @@ { struct pci_dev *root = rdev->pdev->bus->self; enum pci_bus_speed speed_cap; - int bridge_pos, gpu_pos; u32 speed_cntl, current_data_rate; int i; u16 tmp16; @@ -7129,12 +7132,7 @@ DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); } - bridge_pos = pci_pcie_cap(root); - if (!bridge_pos) - return; - - gpu_pos = pci_pcie_cap(rdev->pdev); - if (!gpu_pos) + if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev)) return; if (speed_cap == PCIE_SPEED_8_0GT) { @@ -7144,14 +7142,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -7169,15 +7161,23 @@ for (i = 0; i < 10; i++) { /* check status */ - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_DEVSTA, + &tmp16); if (tmp16 & PCI_EXP_DEVSTA_TRPND) break; - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg); - - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2); + pcie_capability_read_word(root, PCI_EXP_LNKCTL, + &bridge_cfg); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL, + &gpu_cfg); + + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &bridge_cfg2); + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL2, + &gpu_cfg2); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp |= LC_SET_QUIESCE; @@ -7190,26 +7190,38 @@ msleep(100); /* linkctl */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16); - - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ - pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16); - - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~((1 << 4) | (7 << 9)); - tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9))); - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + pcie_capability_read_word(root, PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (bridge_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(root, + PCI_EXP_LNKCTL2, + tmp16); + + pcie_capability_read_word(rdev->pdev, + PCI_EXP_LNKCTL2, + &tmp16); + tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN); + tmp16 |= (gpu_cfg2 & + (PCI_EXP_LNKCTL2_ENTER_COMP | + PCI_EXP_LNKCTL2_TX_MARGIN)); + pcie_capability_write_word(rdev->pdev, + PCI_EXP_LNKCTL2, + tmp16); tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); tmp &= ~LC_SET_QUIESCE; @@ -7223,15 +7235,15 @@ speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); - pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16); - tmp16 &= ~0xf; + pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); + tmp16 &= ~PCI_EXP_LNKCTL2_TLS; if (speed_cap == PCIE_SPEED_8_0GT) - tmp16 |= 3; /* gen3 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ else if (speed_cap == PCIE_SPEED_5_0GT) - tmp16 |= 2; /* gen2 */ + tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ else - tmp16 |= 1; /* gen1 */ - pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16); + tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ + pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/si_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/si_dpm.c @@ -3002,6 +3002,9 @@ (rdev->pdev->device == 0x6605)) { max_sclk = 75000; } + + if (rdev->pm.dpm.high_pixelclock_count > 1) + disable_sclk_switching = true; } if (rps->vce_active) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/sumo_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1493,8 +1493,10 @@ non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) + if (!rdev->pm.power_state[i].clock_info) { + kfree(rdev->pm.dpm.ps); return -EINVAL; + } ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); if (ps == NULL) { kfree(rdev->pm.dpm.ps); @@ -1619,6 +1621,8 @@ for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) { if (table[i].ulSupportedSCLK != 0) { + if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES) + continue; vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit = table[i].usVoltageID; vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit = --- linux-oracle-5.4.0.orig/drivers/gpu/drm/radeon/trinity_dpm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1771,8 +1771,10 @@ non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) + if (!rdev->pm.power_state[i].clock_info) { + kfree(rdev->pm.dpm.ps); return -EINVAL; + } ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); if (ps == NULL) { kfree(rdev->pm.dpm.ps); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rcar-du/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/rcar-du/Kconfig @@ -23,6 +23,7 @@ config DRM_RCAR_LVDS tristate "R-Car DU LVDS Encoder Support" depends on DRM && DRM_BRIDGE && OF + select DRM_KMS_HELPER select DRM_PANEL select OF_FLATTREE select OF_OVERLAY --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -785,13 +785,15 @@ drm_plane_create_alpha_property(&plane->plane); - if (type == DRM_PLANE_TYPE_PRIMARY) - continue; - - drm_object_attach_property(&plane->plane.base, - rcdu->props.colorkey, - RCAR_DU_COLORKEY_NONE); - drm_plane_create_zpos_property(&plane->plane, 1, 1, 7); + if (type == DRM_PLANE_TYPE_PRIMARY) { + drm_plane_create_zpos_immutable_property(&plane->plane, + 0); + } else { + drm_object_attach_property(&plane->plane.base, + rcdu->props.colorkey, + RCAR_DU_COLORKEY_NONE); + drm_plane_create_zpos_property(&plane->plane, 1, 1, 7); + } } return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -392,12 +392,14 @@ drm_plane_helper_add(&plane->plane, &rcar_du_vsp_plane_helper_funcs); - if (type == DRM_PLANE_TYPE_PRIMARY) - continue; - - drm_plane_create_alpha_property(&plane->plane); - drm_plane_create_zpos_property(&plane->plane, 1, 1, - vsp->num_planes - 1); + if (type == DRM_PLANE_TYPE_PRIMARY) { + drm_plane_create_zpos_immutable_property(&plane->plane, + 0); + } else { + drm_plane_create_alpha_property(&plane->plane); + drm_plane_create_zpos_property(&plane->plane, 1, 1, + vsp->num_planes - 1); + } } return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -842,8 +843,23 @@ return 0; } +static const struct rcar_lvds_device_info rcar_lvds_r8a7790es1_info = { + .gen = 2, + .quirks = RCAR_LVDS_QUIRK_LANES, + .pll_setup = rcar_lvds_pll_setup_gen2, +}; + +static const struct soc_device_attribute lvds_quirk_matches[] = { + { + .soc_id = "r8a7790", .revision = "ES1.*", + .data = &rcar_lvds_r8a7790es1_info, + }, + { /* sentinel */ } +}; + static int rcar_lvds_probe(struct platform_device *pdev) { + const struct soc_device_attribute *attr; struct rcar_lvds *lvds; struct resource *mem; int ret; @@ -857,6 +873,10 @@ lvds->dev = &pdev->dev; lvds->info = of_device_get_match_data(&pdev->dev); + attr = soc_device_match(lvds_quirk_matches); + if (attr) + lvds->info = attr->data; + ret = rcar_lvds_parse_dt(lvds); if (ret < 0) return ret; @@ -893,12 +913,6 @@ .pll_setup = rcar_lvds_pll_setup_gen2, }; -static const struct rcar_lvds_device_info rcar_lvds_r8a7790_info = { - .gen = 2, - .quirks = RCAR_LVDS_QUIRK_LANES, - .pll_setup = rcar_lvds_pll_setup_gen2, -}; - static const struct rcar_lvds_device_info rcar_lvds_gen3_info = { .gen = 3, .quirks = RCAR_LVDS_QUIRK_PWD, @@ -930,7 +944,7 @@ { .compatible = "renesas,r8a7744-lvds", .data = &rcar_lvds_gen2_info }, { .compatible = "renesas,r8a774a1-lvds", .data = &rcar_lvds_gen3_info }, { .compatible = "renesas,r8a774c0-lvds", .data = &rcar_lvds_r8a77990_info }, - { .compatible = "renesas,r8a7790-lvds", .data = &rcar_lvds_r8a7790_info }, + { .compatible = "renesas,r8a7790-lvds", .data = &rcar_lvds_gen2_info }, { .compatible = "renesas,r8a7791-lvds", .data = &rcar_lvds_gen2_info }, { .compatible = "renesas,r8a7793-lvds", .data = &rcar_lvds_gen2_info }, { .compatible = "renesas,r8a7795-lvds", .data = &rcar_lvds_gen3_info }, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -325,15 +325,9 @@ void *data) { struct rockchip_dp_device *dp = dev_get_drvdata(dev); - const struct rockchip_dp_chip_data *dp_data; struct drm_device *drm_dev = data; int ret; - dp_data = of_device_get_match_data(dev); - if (!dp_data) - return -ENODEV; - - dp->data = dp_data; dp->drm_dev = drm_dev; ret = rockchip_dp_drm_create_encoder(dp); @@ -344,16 +338,9 @@ dp->plat_data.encoder = &dp->encoder; - dp->plat_data.dev_type = dp->data->chip_type; - dp->plat_data.power_on_start = rockchip_dp_poweron_start; - dp->plat_data.power_off = rockchip_dp_powerdown; - dp->plat_data.get_modes = rockchip_dp_get_modes; - - dp->adp = analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); - if (IS_ERR(dp->adp)) { - ret = PTR_ERR(dp->adp); + ret = analogix_dp_bind(dp->adp, drm_dev); + if (ret) goto err_cleanup_encoder; - } return 0; err_cleanup_encoder: @@ -368,8 +355,6 @@ analogix_dp_unbind(dp->adp); dp->encoder.funcs->destroy(&dp->encoder); - - dp->adp = ERR_PTR(-ENODEV); } static const struct component_ops rockchip_dp_component_ops = { @@ -380,10 +365,15 @@ static int rockchip_dp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct rockchip_dp_chip_data *dp_data; struct drm_panel *panel = NULL; struct rockchip_dp_device *dp; int ret; + dp_data = of_device_get_match_data(dev); + if (!dp_data) + return -ENODEV; + ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL); if (ret < 0) return ret; @@ -394,7 +384,12 @@ dp->dev = dev; dp->adp = ERR_PTR(-ENODEV); + dp->data = dp_data; dp->plat_data.panel = panel; + dp->plat_data.dev_type = dp->data->chip_type; + dp->plat_data.power_on_start = rockchip_dp_poweron_start; + dp->plat_data.power_off = rockchip_dp_powerdown; + dp->plat_data.get_modes = rockchip_dp_get_modes; ret = rockchip_dp_of_probe(dp); if (ret < 0) @@ -402,12 +397,27 @@ platform_set_drvdata(pdev, dp); - return component_add(dev, &rockchip_dp_component_ops); + dp->adp = analogix_dp_probe(dev, &dp->plat_data); + if (IS_ERR(dp->adp)) + return PTR_ERR(dp->adp); + + ret = component_add(dev, &rockchip_dp_component_ops); + if (ret) + goto err_dp_remove; + + return 0; + +err_dp_remove: + analogix_dp_remove(dp->adp); + return ret; } static int rockchip_dp_remove(struct platform_device *pdev) { + struct rockchip_dp_device *dp = platform_get_drvdata(pdev); + component_del(&pdev->dev, &rockchip_dp_component_ops); + analogix_dp_remove(dp->adp); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -72,6 +72,7 @@ ret = regmap_write(dp->grf, reg, val); if (ret) { DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); + clk_disable_unprepare(dp->grf_clk); return ret; } @@ -274,8 +275,9 @@ return ret; } -static int cdn_dp_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +cdn_dp_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { struct cdn_dp_device *dp = connector_to_dp(connector); struct drm_display_info *display_info = &dp->connector.display_info; @@ -561,7 +563,7 @@ video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); - memcpy(&dp->mode, adjusted, sizeof(*mode)); + drm_mode_copy(&dp->mode, adjusted); } static bool cdn_dp_check_link_status(struct cdn_dp_device *dp) @@ -1145,6 +1147,7 @@ struct cdn_dp_device *dp; struct extcon_dev *extcon; struct phy *phy; + int ret; int i; dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); @@ -1185,9 +1188,19 @@ mutex_init(&dp->lock); dev_set_drvdata(dev, dp); - cdn_dp_audio_codec_init(dp, dev); + ret = cdn_dp_audio_codec_init(dp, dev); + if (ret) + return ret; + + ret = component_add(dev, &cdn_dp_component_ops); + if (ret) + goto err_audio_deinit; + + return 0; - return component_add(dev, &cdn_dp_component_ops); +err_audio_deinit: + platform_device_unregister(dp->audio_pdev); + return ret; } static int cdn_dp_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -231,7 +231,8 @@ struct dw_mipi_dsi *dmd; const struct rockchip_dw_dsi_chip_data *cdata; struct dw_mipi_dsi_plat_data pdata; - int devcnt; + + bool dsi_bound; }; struct dphy_pll_parameter_map { @@ -480,8 +481,8 @@ unsigned long best_freq = 0; unsigned long fvco_min, fvco_max, fin, fout; unsigned int min_prediv, max_prediv; - unsigned int _prediv, uninitialized_var(best_prediv); - unsigned long _fbdiv, uninitialized_var(best_fbdiv); + unsigned int _prediv, best_prediv; + unsigned long _fbdiv, best_fbdiv; unsigned long min_delta = ULONG_MAX; dsi->format = format; @@ -564,13 +565,8 @@ .get_lane_mbps = dw_mipi_dsi_get_lane_mbps, }; -static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi, - int mux) +static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi) { - if (dsi->cdata->lcdsel_grf_reg) - regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, - mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); - if (dsi->cdata->lanecfg1_grf_reg) regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg, dsi->cdata->lanecfg1); @@ -584,6 +580,13 @@ dsi->cdata->enable); } +static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi, + int mux) +{ + regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, + mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); +} + static int dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, @@ -624,10 +627,6 @@ if (mux < 0) return; - pm_runtime_get_sync(dsi->dev); - if (dsi->slave) - pm_runtime_get_sync(dsi->slave->dev); - /* * For the RK3399, the clk of grf must be enabled before writing grf * register. And for RK3288 or other soc, this grf_clk must be NULL, @@ -639,27 +638,17 @@ return; } - dw_mipi_dsi_rockchip_config(dsi, mux); + dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux); if (dsi->slave) - dw_mipi_dsi_rockchip_config(dsi->slave, mux); + dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux); clk_disable_unprepare(dsi->grf_clk); } -static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) -{ - struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder); - - if (dsi->slave) - pm_runtime_put(dsi->slave->dev); - pm_runtime_put(dsi->dev); -} - static const struct drm_encoder_helper_funcs dw_mipi_dsi_encoder_helper_funcs = { .atomic_check = dw_mipi_dsi_encoder_atomic_check, .enable = dw_mipi_dsi_encoder_enable, - .disable = dw_mipi_dsi_encoder_disable, }; static const struct drm_encoder_funcs dw_mipi_dsi_encoder_funcs = { @@ -794,25 +783,56 @@ put_device(second); } + pm_runtime_get_sync(dsi->dev); + if (dsi->slave) + pm_runtime_get_sync(dsi->slave->dev); + ret = clk_prepare_enable(dsi->pllref_clk); if (ret) { DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n", ret); - return ret; + goto out_pm_runtime; + } + + /* + * With the GRF clock running, write lane and dual-mode configurations + * that won't change immediately. If we waited until enable() to do + * this, things like panel preparation would not be able to send + * commands over DSI. + */ + ret = clk_prepare_enable(dsi->grf_clk); + if (ret) { + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); + goto out_pm_runtime; } + dw_mipi_dsi_rockchip_config(dsi); + if (dsi->slave) + dw_mipi_dsi_rockchip_config(dsi->slave); + + clk_disable_unprepare(dsi->grf_clk); + ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); if (ret) { DRM_DEV_ERROR(dev, "Failed to create drm encoder\n"); - return ret; + goto out_pm_runtime; } ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder); if (ret) { DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret); - return ret; + goto out_pm_runtime; } + dsi->dsi_bound = true; + return 0; + +out_pm_runtime: + pm_runtime_put(dsi->dev); + if (dsi->slave) + pm_runtime_put(dsi->slave->dev); + + return ret; } static void dw_mipi_dsi_rockchip_unbind(struct device *dev, @@ -824,9 +844,15 @@ if (dsi->is_slave) return; + dsi->dsi_bound = false; + dw_mipi_dsi_unbind(dsi->dmd); clk_disable_unprepare(dsi->pllref_clk); + + pm_runtime_put(dsi->dev); + if (dsi->slave) + pm_runtime_put(dsi->slave->dev); } static const struct component_ops dw_mipi_dsi_rockchip_ops = { @@ -884,6 +910,36 @@ .detach = dw_mipi_dsi_rockchip_host_detach, }; +static int __maybe_unused dw_mipi_dsi_rockchip_resume(struct device *dev) +{ + struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); + int ret; + + /* + * Re-configure DSI state, if we were previously initialized. We need + * to do this before rockchip_drm_drv tries to re-enable() any panels. + */ + if (dsi->dsi_bound) { + ret = clk_prepare_enable(dsi->grf_clk); + if (ret) { + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); + return ret; + } + + dw_mipi_dsi_rockchip_config(dsi); + if (dsi->slave) + dw_mipi_dsi_rockchip_config(dsi->slave); + + clk_disable_unprepare(dsi->grf_clk); + } + + return 0; +} + +static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_mipi_dsi_rockchip_resume) +}; + static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -967,23 +1023,16 @@ if (ret != -EPROBE_DEFER) DRM_DEV_ERROR(dev, "Failed to probe dw_mipi_dsi: %d\n", ret); - goto err_clkdisable; + return ret; } return 0; - -err_clkdisable: - clk_disable_unprepare(dsi->pllref_clk); - return ret; } static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev) { struct dw_mipi_dsi_rockchip *dsi = platform_get_drvdata(pdev); - if (dsi->devcnt == 0) - component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops); - dw_mipi_dsi_remove(dsi->dmd); return 0; @@ -1072,6 +1121,13 @@ .remove = dw_mipi_dsi_rockchip_remove, .driver = { .of_match_table = dw_mipi_dsi_rockchip_dt_ids, + .pm = &dw_mipi_dsi_rockchip_pm_ops, .name = "dw-mipi-dsi-rockchip", + /* + * For dual-DSI display, one DSI pokes at the other DSI's + * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not + * safe for asynchronous probe. + */ + .probe_type = PROBE_FORCE_SYNCHRONOUS, }, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -390,6 +390,8 @@ HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK, RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK | RK3328_HDMI_HPD_IOE)); + + dw_hdmi_rk3328_read_hpd(dw_hdmi, data); } static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = { @@ -528,13 +530,6 @@ return ret; } - ret = clk_prepare_enable(hdmi->vpll_clk); - if (ret) { - DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", - ret); - return ret; - } - hdmi->phy = devm_phy_optional_get(dev, "hdmi"); if (IS_ERR(hdmi->phy)) { ret = PTR_ERR(hdmi->phy); @@ -543,6 +538,13 @@ return ret; } + ret = clk_prepare_enable(hdmi->vpll_clk); + if (ret) { + DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n", + ret); + return ret; + } + drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs); drm_encoder_init(drm, encoder, &dw_hdmi_rockchip_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/inno_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/inno_hdmi.c @@ -401,7 +401,7 @@ hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF); hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF); - value = mode->hsync_start - mode->hdisplay; + value = mode->htotal - mode->hsync_start; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF); hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF); @@ -416,7 +416,7 @@ value = mode->vtotal - mode->vdisplay; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF); - value = mode->vsync_start - mode->vdisplay; + value = mode->vtotal - mode->vsync_start; hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF); value = mode->vsync_end - mode->vsync_start; @@ -487,7 +487,7 @@ inno_hdmi_setup(hdmi, adj_mode); /* Store the display mode for plugin/DPMS poweron events */ - memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode)); + drm_mode_copy(&hdmi->previous_mode, adj_mode); } static void inno_hdmi_encoder_enable(struct drm_encoder *encoder) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/rk3066_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/rk3066_hdmi.c @@ -382,7 +382,7 @@ struct rk3066_hdmi *hdmi = to_rk3066_hdmi(encoder); /* Store the display mode for plugin/DPMS poweron events. */ - memcpy(&hdmi->previous_mode, adj_mode, sizeof(hdmi->previous_mode)); + drm_mode_copy(&hdmi->previous_mode, adj_mode); } static void rk3066_hdmi_encoder_enable(struct drm_encoder *encoder) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -249,9 +249,6 @@ else ret = rockchip_drm_gem_object_mmap_dma(obj, vma); - if (ret) - drm_gem_vm_close(vma); - return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -234,14 +234,22 @@ VOP_REG_SET(vop, common, cfg_done, 1); } -static bool has_rb_swapped(uint32_t format) +static bool has_rb_swapped(uint32_t version, uint32_t format) { switch (format) { case DRM_FORMAT_XBGR8888: case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_BGR888: case DRM_FORMAT_BGR565: return true; + /* + * full framework (IP version 3.x) only need rb swapped for RGB888 and + * little framework (IP version 2.x) only need rb swapped for BGR888, + * check for 3.x to also only rb swap BGR888 for unknown vop version + */ + case DRM_FORMAT_RGB888: + return VOP_MAJOR(version) == 3; + case DRM_FORMAT_BGR888: + return VOP_MAJOR(version) != 3; default: return false; } @@ -325,8 +333,8 @@ if (info->is_yuv) is_yuv = true; - if (dst_w > 3840) { - DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n"); + if (dst_w > 4096) { + DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n"); return; } @@ -654,13 +662,13 @@ if (crtc->state->self_refresh_active) rockchip_drm_set_win_enabled(crtc, false); + if (crtc->state->self_refresh_active) + goto out; + mutex_lock(&vop->vop_lock); drm_crtc_vblank_off(crtc); - if (crtc->state->self_refresh_active) - goto out; - /* * Vop standby will take effect at end of current frame, * if dsp hold valid irq happen, it means standby complete. @@ -692,9 +700,9 @@ vop_core_clks_disable(vop); pm_runtime_put(vop->dev); -out: mutex_unlock(&vop->vop_lock); +out: if (crtc->state->event && !crtc->state->active) { spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); @@ -886,7 +894,7 @@ VOP_WIN_SET(vop, win, dsp_info, dsp_info); VOP_WIN_SET(vop, win, dsp_st, dsp_st); - rb_swap = has_rb_swapped(fb->format->format); + rb_swap = has_rb_swapped(vop->data->version, fb->format->format); VOP_WIN_SET(vop, win, rb_swap, rb_swap); /* @@ -1040,10 +1048,41 @@ struct drm_display_mode *adjusted_mode) { struct vop *vop = to_vop(crtc); + unsigned long rate; - adjusted_mode->clock = - DIV_ROUND_UP(clk_round_rate(vop->dclk, - adjusted_mode->clock * 1000), 1000); + /* + * Clock craziness. + * + * Key points: + * + * - DRM works in in kHz. + * - Clock framework works in Hz. + * - Rockchip's clock driver picks the clock rate that is the + * same _OR LOWER_ than the one requested. + * + * Action plan: + * + * 1. When DRM gives us a mode, we should add 999 Hz to it. That way + * if the clock we need is 60000001 Hz (~60 MHz) and DRM tells us to + * make 60000 kHz then the clock framework will actually give us + * the right clock. + * + * NOTE: if the PLL (maybe through a divider) could actually make + * a clock rate 999 Hz higher instead of the one we want then this + * could be a problem. Unfortunately there's not much we can do + * since it's baked into DRM to use kHz. It shouldn't matter in + * practice since Rockchip PLLs are controlled by tables and + * even if there is a divider in the middle I wouldn't expect PLL + * rates in the table that are just a few kHz different. + * + * 2. Get the clock framework to round the rate for us to tell us + * what it will actually make. + * + * 3. Store the rounded up rate so that we don't need to worry about + * this in the actual clk_set_rate(). + */ + rate = clk_round_rate(vop->dclk, adjusted_mode->clock * 1000 + 999); + adjusted_mode->clock = DIV_ROUND_UP(rate, 1000); return true; } @@ -1257,7 +1296,11 @@ { struct rockchip_crtc_state *rockchip_state; - rockchip_state = kzalloc(sizeof(*rockchip_state), GFP_KERNEL); + if (WARN_ON(!crtc->state)) + return NULL; + + rockchip_state = kmemdup(to_rockchip_crtc_state(crtc->state), + sizeof(*rockchip_state), GFP_KERNEL); if (!rockchip_state) return NULL; @@ -1282,7 +1325,10 @@ if (crtc->state) vop_crtc_destroy_state(crtc, crtc->state); - __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); + if (crtc_state) + __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); } #ifdef CONFIG_DRM_ANALOGIX_DP @@ -1817,10 +1863,10 @@ vop_win_init(vop); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vop->len = resource_size(res); vop->regs = devm_ioremap_resource(dev, res); if (IS_ERR(vop->regs)) return PTR_ERR(vop->regs); + vop->len = resource_size(res); vop->regsbak = devm_kzalloc(dev, vop->len, GFP_KERNEL); if (!vop->regsbak) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ linux-oracle-5.4.0/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -366,7 +366,6 @@ goto err_put_port; } else if (ret) { DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n"); - ret = -EPROBE_DEFER; goto err_put_port; } if (lvds->panel) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h +++ linux-oracle-5.4.0/drivers/gpu/drm/scheduler/gpu_scheduler_trace.h @@ -21,7 +21,7 @@ * */ -#if !defined(_GPU_SCHED_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#if !defined(_GPU_SCHED_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) #define _GPU_SCHED_TRACE_H_ #include @@ -96,7 +96,7 @@ __entry->seqno) ); -#endif +#endif /* _GPU_SCHED_TRACE_H_ */ /* This part must be outside protection */ #undef TRACE_INCLUDE_PATH --- linux-oracle-5.4.0.orig/drivers/gpu/drm/scheduler/sched_entity.c +++ linux-oracle-5.4.0/drivers/gpu/drm/scheduler/sched_entity.c @@ -235,11 +235,16 @@ static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity) { struct drm_sched_job *job; + struct dma_fence *f; int r; while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) { struct drm_sched_fence *s_fence = job->s_fence; + /* Wait for all dependencies to avoid data corruptions */ + while ((f = job->sched->ops->dependency(job, entity))) + dma_fence_wait(f, false); + drm_sched_fence_scheduled(s_fence); dma_fence_set_error(&s_fence->finished, -ESRCH); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/scheduler/sched_main.c +++ linux-oracle-5.4.0/drivers/gpu/drm/scheduler/sched_main.c @@ -284,10 +284,21 @@ unsigned long flags; sched = container_of(work, struct drm_gpu_scheduler, work_tdr.work); + + /* Protects against concurrent deletion in drm_sched_get_cleanup_job */ + spin_lock_irqsave(&sched->job_list_lock, flags); job = list_first_entry_or_null(&sched->ring_mirror_list, struct drm_sched_job, node); if (job) { + /* + * Remove the bad job so it cannot be freed by concurrent + * drm_sched_cleanup_jobs. It will be reinserted back after sched->thread + * is parked at which point it's safe. + */ + list_del_init(&job->node); + spin_unlock_irqrestore(&sched->job_list_lock, flags); + job->sched->ops->timedout_job(job); /* @@ -298,6 +309,8 @@ job->sched->ops->free_job(job); sched->free_guilty = false; } + } else { + spin_unlock_irqrestore(&sched->job_list_lock, flags); } spin_lock_irqsave(&sched->job_list_lock, flags); @@ -370,6 +383,20 @@ kthread_park(sched->thread); /* + * Reinsert back the bad job here - now it's safe as + * drm_sched_get_cleanup_job cannot race against us and release the + * bad job at this point - we parked (waited for) any in progress + * (earlier) cleanups and drm_sched_get_cleanup_job will not be called + * now until the scheduler thread is unparked. + */ + if (bad && bad->sched == sched) + /* + * Add at the head of the queue to reflect it was the earliest + * job extracted. + */ + list_add(&bad->node, &sched->ring_mirror_list); + + /* * Iterate the job list from later to earlier one and either deactive * their HW callbacks or remove them from mirror list if they already * signaled. @@ -496,8 +523,10 @@ fence = sched->ops->run_job(s_job); if (IS_ERR_OR_NULL(fence)) { + if (IS_ERR(fence)) + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); + s_job->s_fence->parent = NULL; - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); } else { s_job->s_fence->parent = fence; } @@ -627,48 +656,48 @@ trace_drm_sched_process_job(s_fence); + dma_fence_get(&s_fence->finished); drm_sched_fence_finished(s_fence); + dma_fence_put(&s_fence->finished); wake_up_interruptible(&sched->wake_up_worker); } /** - * drm_sched_cleanup_jobs - destroy finished jobs + * drm_sched_get_cleanup_job - fetch the next finished job to be destroyed * * @sched: scheduler instance * - * Remove all finished jobs from the mirror list and destroy them. + * Returns the next finished job from the mirror list (if there is one) + * ready for it to be destroyed. */ -static void drm_sched_cleanup_jobs(struct drm_gpu_scheduler *sched) +static struct drm_sched_job * +drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched) { + struct drm_sched_job *job; unsigned long flags; /* Don't destroy jobs while the timeout worker is running */ if (sched->timeout != MAX_SCHEDULE_TIMEOUT && !cancel_delayed_work(&sched->work_tdr)) - return; - + return NULL; - while (!list_empty(&sched->ring_mirror_list)) { - struct drm_sched_job *job; + spin_lock_irqsave(&sched->job_list_lock, flags); - job = list_first_entry(&sched->ring_mirror_list, + job = list_first_entry_or_null(&sched->ring_mirror_list, struct drm_sched_job, node); - if (!dma_fence_is_signaled(&job->s_fence->finished)) - break; - spin_lock_irqsave(&sched->job_list_lock, flags); + if (job && dma_fence_is_signaled(&job->s_fence->finished)) { /* remove job from ring_mirror_list */ list_del_init(&job->node); - spin_unlock_irqrestore(&sched->job_list_lock, flags); - - sched->ops->free_job(job); + } else { + job = NULL; + /* queue timeout for next job */ + drm_sched_start_timeout(sched); } - /* queue timeout for next job */ - spin_lock_irqsave(&sched->job_list_lock, flags); - drm_sched_start_timeout(sched); spin_unlock_irqrestore(&sched->job_list_lock, flags); + return job; } /** @@ -708,12 +737,19 @@ struct drm_sched_fence *s_fence; struct drm_sched_job *sched_job; struct dma_fence *fence; + struct drm_sched_job *cleanup_job = NULL; wait_event_interruptible(sched->wake_up_worker, - (drm_sched_cleanup_jobs(sched), + (cleanup_job = drm_sched_get_cleanup_job(sched)) || (!drm_sched_blocked(sched) && (entity = drm_sched_select_entity(sched))) || - kthread_should_stop())); + kthread_should_stop()); + + if (cleanup_job) { + sched->ops->free_job(cleanup_job); + /* queue timeout for next job */ + drm_sched_start_timeout(sched); + } if (!entity) continue; @@ -741,8 +777,9 @@ r); dma_fence_put(fence); } else { + if (IS_ERR(fence)) + dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); - dma_fence_set_error(&s_fence->finished, PTR_ERR(fence)); drm_sched_process_job(NULL, &sched_job->cb); } @@ -814,6 +851,9 @@ if (sched->thread) kthread_stop(sched->thread); + /* Confirm no work left behind accessing device structures */ + cancel_delayed_work_sync(&sched->work_tdr); + sched->ready = false; } EXPORT_SYMBOL(drm_sched_fini); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/selftests/drm_cmdline_selftests.h +++ linux-oracle-5.4.0/drivers/gpu/drm/selftests/drm_cmdline_selftests.h @@ -53,6 +53,7 @@ cmdline_test(drm_cmdline_test_rotate_90) cmdline_test(drm_cmdline_test_rotate_180) cmdline_test(drm_cmdline_test_rotate_270) +cmdline_test(drm_cmdline_test_rotate_multiple) cmdline_test(drm_cmdline_test_rotate_invalid_val) cmdline_test(drm_cmdline_test_rotate_truncated) cmdline_test(drm_cmdline_test_hmirror) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c +++ linux-oracle-5.4.0/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c @@ -856,6 +856,17 @@ return 0; } +static int drm_cmdline_test_rotate_multiple(void *ignored) +{ + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=0,rotate=90", + &no_connector, + &mode)); + + return 0; +} + static int drm_cmdline_test_rotate_invalid_val(void *ignored) { struct drm_cmdline_mode mode = { }; @@ -888,7 +899,7 @@ FAIL_ON(!mode.specified); FAIL_ON(mode.xres != 720); FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_X); + FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X)); FAIL_ON(mode.refresh_specified); @@ -913,7 +924,7 @@ FAIL_ON(!mode.specified); FAIL_ON(mode.xres != 720); FAIL_ON(mode.yres != 480); - FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_Y); + FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y)); FAIL_ON(mode.refresh_specified); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sti/sti_dvo.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sti/sti_dvo.c @@ -287,7 +287,7 @@ DRM_DEBUG_DRIVER("\n"); - memcpy(&dvo->mode, mode, sizeof(struct drm_display_mode)); + drm_mode_copy(&dvo->mode, mode); /* According to the path used (main or aux), the dvo clocks should * have a different parent clock. */ @@ -345,8 +345,9 @@ #define CLK_TOLERANCE_HZ 50 -static int sti_dvo_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +sti_dvo_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { int target = mode->clock * 1000; int target_min = target - CLK_TOLERANCE_HZ; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sti/sti_hda.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sti/sti_hda.c @@ -522,7 +522,7 @@ DRM_DEBUG_DRIVER("\n"); - memcpy(&hda->mode, mode, sizeof(struct drm_display_mode)); + drm_mode_copy(&hda->mode, mode); if (!hda_get_mode_idx(hda->mode, &mode_idx)) { DRM_ERROR("Undefined mode\n"); @@ -600,8 +600,9 @@ #define CLK_TOLERANCE_HZ 50 -static int sti_hda_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +sti_hda_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { int target = mode->clock * 1000; int target_min = target - CLK_TOLERANCE_HZ; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sti/sti_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sti/sti_hdmi.c @@ -933,7 +933,7 @@ DRM_DEBUG_DRIVER("\n"); /* Copy the drm display mode in the connector local structure */ - memcpy(&hdmi->mode, mode, sizeof(struct drm_display_mode)); + drm_mode_copy(&hdmi->mode, mode); /* Update clock framerate according to the selected mode */ ret = clk_set_rate(hdmi->clk_pix, mode->clock * 1000); @@ -996,8 +996,9 @@ #define CLK_TOLERANCE_HZ 50 -static int sti_hdmi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) +static enum drm_mode_status +sti_hdmi_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) { int target = mode->clock * 1000; int target_min = target - CLK_TOLERANCE_HZ; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sti/sti_mixer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sti/sti_mixer.c @@ -137,7 +137,7 @@ } } -static void mixer_dbg_mxn(struct seq_file *s, void *addr) +static void mixer_dbg_mxn(struct seq_file *s, void __iomem *addr) { int i; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/stm/drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/stm/drv.c @@ -208,12 +208,14 @@ ret = drm_dev_register(ddev, 0); if (ret) - goto err_put; + goto err_unload; drm_fbdev_generic_setup(ddev, 16); return 0; +err_unload: + drv_unload(ddev); err_put: drm_dev_put(ddev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/stm/ltdc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/stm/ltdc.c @@ -424,9 +424,12 @@ struct drm_crtc_state *old_state) { struct ltdc_device *ldev = crtc_to_ltdc(crtc); + struct drm_device *ddev = crtc->dev; DRM_DEBUG_DRIVER("\n"); + pm_runtime_get_sync(ddev->dev); + /* Sets the background color value */ reg_write(ldev->regs, LTDC_BCCR, BCCR_BCBLACK); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/Kconfig @@ -46,6 +46,7 @@ default MACH_SUN8I select CRC_CCITT select DRM_MIPI_DSI + select RESET_CONTROLLER select PHY_SUN6I_MIPI_DPHY help Choose this option if you want have an Allwinner SoC with --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_backend.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -589,8 +589,7 @@ /* We can't have an alpha plane at the lowest position */ if (!backend->quirks->supports_lowest_plane_alpha && - (plane_states[0]->fb->format->has_alpha || - (plane_states[0]->alpha != DRM_BLEND_ALPHA_OPAQUE))) + (plane_states[0]->alpha != DRM_BLEND_ALPHA_OPAQUE)) return -EINVAL; for (i = 1; i < num_planes; i++) { @@ -986,7 +985,6 @@ static const struct sun4i_backend_quirks sun7i_backend_quirks = { .needs_output_muxing = true, - .supports_lowest_plane_alpha = true, }; static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -85,7 +85,6 @@ } drm_mode_config_init(drm); - drm->mode_config.allow_fb_modifiers = true; ret = component_bind_all(drm->dev, drm); if (ret) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_frontend.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_frontend.c @@ -407,6 +407,7 @@ struct drm_framebuffer *fb = state->fb; const struct drm_format_info *format = fb->format; uint64_t modifier = fb->modifier; + unsigned int ch1_phase_idx; u32 out_fmt_val; u32 in_fmt_val, in_mod_val, in_ps_val; unsigned int i; @@ -442,18 +443,19 @@ * I have no idea what this does exactly, but it seems to be * related to the scaler FIR filter phase parameters. */ + ch1_phase_idx = (format->num_planes > 1) ? 1 : 0; regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZPHASE_REG, - frontend->data->ch_phase[0].horzphase); + frontend->data->ch_phase[0]); regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZPHASE_REG, - frontend->data->ch_phase[1].horzphase); + frontend->data->ch_phase[ch1_phase_idx]); regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE0_REG, - frontend->data->ch_phase[0].vertphase[0]); + frontend->data->ch_phase[0]); regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE0_REG, - frontend->data->ch_phase[1].vertphase[0]); + frontend->data->ch_phase[ch1_phase_idx]); regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG, - frontend->data->ch_phase[0].vertphase[1]); + frontend->data->ch_phase[0]); regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG, - frontend->data->ch_phase[1].vertphase[1]); + frontend->data->ch_phase[ch1_phase_idx]); /* * Checking the input format is sufficient since we currently only @@ -687,30 +689,12 @@ }; static const struct sun4i_frontend_data sun4i_a10_frontend = { - .ch_phase = { - { - .horzphase = 0, - .vertphase = { 0, 0 }, - }, - { - .horzphase = 0xfc000, - .vertphase = { 0xfc000, 0xfc000 }, - }, - }, + .ch_phase = { 0x000, 0xfc000 }, .has_coef_rdy = true, }; static const struct sun4i_frontend_data sun8i_a33_frontend = { - .ch_phase = { - { - .horzphase = 0x400, - .vertphase = { 0x400, 0x400 }, - }, - { - .horzphase = 0x400, - .vertphase = { 0x400, 0x400 }, - }, - }, + .ch_phase = { 0x400, 0xfc400 }, .has_coef_access_ctrl = true, }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_frontend.h +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_frontend.h @@ -115,11 +115,7 @@ struct sun4i_frontend_data { bool has_coef_access_ctrl; bool has_coef_rdy; - - struct { - u32 horzphase; - u32 vertphase[2]; - } ch_phase[2]; + u32 ch_phase[2]; }; struct sun4i_frontend { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_hdmi.h +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_hdmi.h @@ -148,7 +148,7 @@ #define SUN4I_HDMI_DDC_CMD_IMPLICIT_WRITE 3 #define SUN4I_HDMI_DDC_CLK_REG 0x528 -#define SUN4I_HDMI_DDC_CLK_M(m) (((m) & 0x7) << 3) +#define SUN4I_HDMI_DDC_CLK_M(m) (((m) & 0xf) << 3) #define SUN4I_HDMI_DDC_CLK_N(n) ((n) & 0x7) #define SUN4I_HDMI_DDC_LINE_CTRL_REG 0x540 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c @@ -33,7 +33,7 @@ unsigned long best_rate = 0; u8 best_m = 0, best_n = 0, _m, _n; - for (_m = 0; _m < 8; _m++) { + for (_m = 0; _m < 16; _m++) { for (_n = 0; _n < 8; _n++) { unsigned long tmp_rate; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c @@ -262,9 +262,8 @@ struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector); unsigned long reg; - if (readl_poll_timeout(hdmi->base + SUN4I_HDMI_HPD_REG, reg, - reg & SUN4I_HDMI_HPD_HIGH, - 0, 500000)) { + reg = readl(hdmi->base + SUN4I_HDMI_HPD_REG); + if (!(reg & SUN4I_HDMI_HPD_HIGH)) { cec_phys_addr_invalidate(hdmi->cec_adap); return connector_status_disconnected; } @@ -683,8 +682,6 @@ struct sun4i_hdmi *hdmi = dev_get_drvdata(dev); cec_unregister_adapter(hdmi->cec_adap); - drm_connector_cleanup(&hdmi->connector); - drm_encoder_cleanup(&hdmi->encoder); i2c_del_adapter(hdmi->i2c); i2c_put_adapter(hdmi->ddc_i2c); clk_disable_unprepare(hdmi->mod_clk); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -488,7 +488,7 @@ WARN_ON(!tcon->quirks->has_channel_0); - tcon->dclk_min_div = 1; + tcon->dclk_min_div = tcon->quirks->dclk_min_div; tcon->dclk_max_div = 127; sun4i_tcon0_mode_set_common(tcon, mode); @@ -545,30 +545,13 @@ if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) val |= SUN4I_TCON0_IO_POL_DE_NEGATIVE; - /* - * On A20 and similar SoCs, the only way to achieve Positive Edge - * (Rising Edge), is setting dclk clock phase to 2/3(240°). - * By default TCON works in Negative Edge(Falling Edge), - * this is why phase is set to 0 in that case. - * Unfortunately there's no way to logically invert dclk through - * IO_POL register. - * The only acceptable way to work, triple checked with scope, - * is using clock phase set to 0° for Negative Edge and set to 240° - * for Positive Edge. - * On A33 and similar SoCs there would be a 90° phase option, - * but it divides also dclk by 2. - * Following code is a way to avoid quirks all around TCON - * and DOTCLOCK drivers. - */ - if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) - clk_set_phase(tcon->dclk, 240); - if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) - clk_set_phase(tcon->dclk, 0); + val |= SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE; regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG, SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE | + SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE | SUN4I_TCON0_IO_POL_DE_NEGATIVE, val); @@ -665,6 +648,30 @@ SUN4I_TCON1_BASIC5_V_SYNC(vsync) | SUN4I_TCON1_BASIC5_H_SYNC(hsync)); + /* Setup the polarity of multiple signals */ + if (tcon->quirks->polarity_in_ch0) { + val = 0; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON0_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON0_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON0_IO_POL_REG, val); + } else { + /* according to vendor driver, this bit must be always set */ + val = SUN4I_TCON1_IO_POL_UNKNOWN; + + if (mode->flags & DRM_MODE_FLAG_PHSYNC) + val |= SUN4I_TCON1_IO_POL_HSYNC_POSITIVE; + + if (mode->flags & DRM_MODE_FLAG_PVSYNC) + val |= SUN4I_TCON1_IO_POL_VSYNC_POSITIVE; + + regmap_write(tcon->regs, SUN4I_TCON1_IO_POL_REG, val); + } + /* Map output pins to channel 1 */ regmap_update_bits(tcon->regs, SUN4I_TCON_GCTL_REG, SUN4I_TCON_GCTL_IOMAP_MASK, @@ -746,21 +753,19 @@ static int sun4i_tcon_init_clocks(struct device *dev, struct sun4i_tcon *tcon) { - tcon->clk = devm_clk_get(dev, "ahb"); + tcon->clk = devm_clk_get_enabled(dev, "ahb"); if (IS_ERR(tcon->clk)) { dev_err(dev, "Couldn't get the TCON bus clock\n"); return PTR_ERR(tcon->clk); } - clk_prepare_enable(tcon->clk); if (tcon->quirks->has_channel_0) { - tcon->sclk0 = devm_clk_get(dev, "tcon-ch0"); + tcon->sclk0 = devm_clk_get_enabled(dev, "tcon-ch0"); if (IS_ERR(tcon->sclk0)) { dev_err(dev, "Couldn't get the TCON channel 0 clock\n"); return PTR_ERR(tcon->sclk0); } } - clk_prepare_enable(tcon->sclk0); if (tcon->quirks->has_channel_1) { tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); @@ -773,12 +778,6 @@ return 0; } -static void sun4i_tcon_free_clocks(struct sun4i_tcon *tcon) -{ - clk_disable_unprepare(tcon->sclk0); - clk_disable_unprepare(tcon->clk); -} - static int sun4i_tcon_init_irq(struct device *dev, struct sun4i_tcon *tcon) { @@ -1195,14 +1194,14 @@ ret = sun4i_tcon_init_regmap(dev, tcon); if (ret) { dev_err(dev, "Couldn't init our TCON regmap\n"); - goto err_free_clocks; + goto err_assert_reset; } if (tcon->quirks->has_channel_0) { ret = sun4i_dclk_create(dev, tcon); if (ret) { dev_err(dev, "Couldn't create our TCON dot clock\n"); - goto err_free_clocks; + goto err_assert_reset; } } @@ -1265,8 +1264,6 @@ err_free_dotclock: if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); -err_free_clocks: - sun4i_tcon_free_clocks(tcon); err_assert_reset: reset_control_assert(tcon->lcd_rst); return ret; @@ -1280,7 +1277,6 @@ list_del(&tcon->list); if (tcon->quirks->has_channel_0) sun4i_dclk_free(tcon); - sun4i_tcon_free_clocks(tcon); } static const struct component_ops sun4i_tcon_ops = { @@ -1409,14 +1405,18 @@ if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) && encoder->encoder_type == DRM_MODE_ENCODER_TMDS) { ret = sun8i_tcon_top_set_hdmi_src(&pdev->dev, id); - if (ret) + if (ret) { + put_device(&pdev->dev); return ret; + } } if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP)) { ret = sun8i_tcon_top_de_config(&pdev->dev, tcon->id, id); - if (ret) + if (ret) { + put_device(&pdev->dev); return ret; + } } return 0; @@ -1425,12 +1425,14 @@ static const struct sun4i_tcon_quirks sun4i_a10_quirks = { .has_channel_0 = true, .has_channel_1 = true, + .dclk_min_div = 4, .set_mux = sun4i_a10_tcon_set_mux, }; static const struct sun4i_tcon_quirks sun5i_a13_quirks = { .has_channel_0 = true, .has_channel_1 = true, + .dclk_min_div = 4, .set_mux = sun5i_a13_tcon_set_mux, }; @@ -1439,6 +1441,7 @@ .has_channel_1 = true, .has_lvds_alt = true, .needs_de_be_mux = true, + .dclk_min_div = 1, .set_mux = sun6i_tcon_set_mux, }; @@ -1446,11 +1449,13 @@ .has_channel_0 = true, .has_channel_1 = true, .needs_de_be_mux = true, + .dclk_min_div = 1, }; static const struct sun4i_tcon_quirks sun7i_a20_quirks = { .has_channel_0 = true, .has_channel_1 = true, + .dclk_min_div = 4, /* Same display pipeline structure as A10 */ .set_mux = sun4i_a10_tcon_set_mux, }; @@ -1458,11 +1463,13 @@ static const struct sun4i_tcon_quirks sun8i_a33_quirks = { .has_channel_0 = true, .has_lvds_alt = true, + .dclk_min_div = 1, }; static const struct sun4i_tcon_quirks sun8i_a83t_lcd_quirks = { .supports_lvds = true, .has_channel_0 = true, + .dclk_min_div = 1, }; static const struct sun4i_tcon_quirks sun8i_a83t_tv_quirks = { @@ -1471,16 +1478,19 @@ static const struct sun4i_tcon_quirks sun8i_r40_tv_quirks = { .has_channel_1 = true, + .polarity_in_ch0 = true, .set_mux = sun8i_r40_tcon_tv_set_mux, }; static const struct sun4i_tcon_quirks sun8i_v3s_quirks = { .has_channel_0 = true, + .dclk_min_div = 1, }; static const struct sun4i_tcon_quirks sun9i_a80_tcon_lcd_quirks = { - .has_channel_0 = true, - .needs_edp_reset = true, + .has_channel_0 = true, + .needs_edp_reset = true, + .dclk_min_div = 1, }; static const struct sun4i_tcon_quirks sun9i_a80_tcon_tv_quirks = { @@ -1495,6 +1505,8 @@ { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, { .compatible = "allwinner,sun7i-a20-tcon", .data = &sun7i_a20_quirks }, + { .compatible = "allwinner,sun7i-a20-tcon0", .data = &sun7i_a20_quirks }, + { .compatible = "allwinner,sun7i-a20-tcon1", .data = &sun7i_a20_quirks }, { .compatible = "allwinner,sun8i-a23-tcon", .data = &sun8i_a33_quirks }, { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, { .compatible = "allwinner,sun8i-a83t-tcon-lcd", .data = &sun8i_a83t_lcd_quirks }, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -113,6 +113,7 @@ #define SUN4I_TCON0_IO_POL_REG 0x88 #define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase) ((phase & 3) << 28) #define SUN4I_TCON0_IO_POL_DE_NEGATIVE BIT(27) +#define SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE BIT(26) #define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE BIT(25) #define SUN4I_TCON0_IO_POL_VSYNC_POSITIVE BIT(24) @@ -153,6 +154,11 @@ #define SUN4I_TCON1_BASIC5_V_SYNC(height) (((height) - 1) & 0x3ff) #define SUN4I_TCON1_IO_POL_REG 0xf0 +/* there is no documentation about this bit */ +#define SUN4I_TCON1_IO_POL_UNKNOWN BIT(26) +#define SUN4I_TCON1_IO_POL_HSYNC_POSITIVE BIT(25) +#define SUN4I_TCON1_IO_POL_VSYNC_POSITIVE BIT(24) + #define SUN4I_TCON1_IO_TRI_REG 0xf4 #define SUN4I_TCON_ECC_FIFO_REG 0xf8 @@ -224,6 +230,8 @@ bool needs_de_be_mux; /* sun6i needs mux to select backend */ bool needs_edp_reset; /* a80 edp reset needed for tcon0 access */ bool supports_lvds; /* Does the TCON support an LVDS output? */ + bool polarity_in_ch0; /* some tcon1 channels have polarity bits in tcon0 pol register */ + u8 dclk_min_div; /* minimum divider for TCON0 DCLK */ /* callback to handle tcon muxing options */ int (*set_mux)(struct sun4i_tcon *, const struct drm_encoder *); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c @@ -365,8 +365,7 @@ static u16 sun6i_dsi_get_video_start_delay(struct sun6i_dsi *dsi, struct drm_display_mode *mode) { - u16 start = clamp(mode->vtotal - mode->vdisplay - 10, 8, 100); - u16 delay = mode->vtotal - (mode->vsync_end - mode->vdisplay) + start; + u16 delay = mode->vtotal - (mode->vsync_end - mode->vdisplay) + 1; if (delay > mode->vtotal) delay = delay % mode->vtotal; @@ -437,9 +436,9 @@ SUN6I_DSI_BURST_LINE_SYNC_POINT(SUN6I_DSI_SYNC_POINT)); val = SUN6I_DSI_TCON_DRQ_ENABLE_MODE; - } else if ((mode->hsync_end - mode->hdisplay) > 20) { + } else if ((mode->hsync_start - mode->hdisplay) > 20) { /* Maaaaaagic */ - u16 drq = (mode->hsync_end - mode->hdisplay) - 20; + u16 drq = (mode->hsync_start - mode->hdisplay) - 20; drq *= mipi_dsi_pixel_format_to_bpp(device->format); drq /= 32; @@ -718,7 +717,7 @@ struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder); struct mipi_dsi_device *device = dsi->device; - union phy_configure_opts opts = { 0 }; + union phy_configure_opts opts = { }; struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy; u16 delay; @@ -867,7 +866,7 @@ regmap_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(0), sun6i_dsi_dcs_build_pkt_hdr(dsi, msg)); - bounce = kzalloc(msg->tx_len + sizeof(crc), GFP_KERNEL); + bounce = kzalloc(ALIGN(msg->tx_len + sizeof(crc), 4), GFP_KERNEL); if (!bounce) return -ENOMEM; @@ -878,7 +877,7 @@ memcpy((u8 *)bounce + msg->tx_len, &crc, sizeof(crc)); len += sizeof(crc); - regmap_bulk_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(1), bounce, len); + regmap_bulk_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(1), bounce, DIV_ROUND_UP(len, 4)); regmap_write(dsi->regs, SUN6I_DSI_CMD_CTL_REG, len + 4 - 1); kfree(bounce); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_csc.h +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_csc.h @@ -12,7 +12,7 @@ /* VI channel CSC units offsets */ #define CCSC00_OFFSET 0xAA050 -#define CCSC01_OFFSET 0xFA000 +#define CCSC01_OFFSET 0xFA050 #define CCSC10_OFFSET 0xA0000 #define CCSC11_OFFSET 0xF0000 --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -49,11 +49,9 @@ { /* * Controller support maximum of 594 MHz, which correlates to - * 4K@60Hz 4:4:4 or RGB. However, for frequencies greater than - * 340 MHz scrambling has to be enabled. Because scrambling is - * not yet implemented, just limit to 340 MHz for now. + * 4K@60Hz 4:4:4 or RGB. */ - if (mode->clock > 340000) + if (mode->clock > 594000) return MODE_CLOCK_HIGH; return MODE_OK; @@ -209,6 +207,7 @@ phy_node = of_parse_phandle(dev->of_node, "phys", 0); if (!phy_node) { dev_err(dev, "Can't found PHY phandle\n"); + ret = -EINVAL; goto err_disable_clk_tmds; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -104,29 +104,21 @@ static const struct dw_hdmi_curr_ctrl sun50i_h6_cur_ctr[] = { /* pixelclk bpp8 bpp10 bpp12 */ - { 25175000, { 0x0000, 0x0000, 0x0000 }, }, { 27000000, { 0x0012, 0x0000, 0x0000 }, }, - { 59400000, { 0x0008, 0x0008, 0x0008 }, }, - { 72000000, { 0x0008, 0x0008, 0x001b }, }, - { 74250000, { 0x0013, 0x0013, 0x0013 }, }, - { 90000000, { 0x0008, 0x001a, 0x001b }, }, - { 118800000, { 0x001b, 0x001a, 0x001b }, }, - { 144000000, { 0x001b, 0x001a, 0x0034 }, }, - { 180000000, { 0x001b, 0x0033, 0x0034 }, }, - { 216000000, { 0x0036, 0x0033, 0x0034 }, }, - { 237600000, { 0x0036, 0x0033, 0x001b }, }, - { 288000000, { 0x0036, 0x001b, 0x001b }, }, - { 297000000, { 0x0019, 0x001b, 0x0019 }, }, - { 330000000, { 0x0036, 0x001b, 0x001b }, }, - { 594000000, { 0x003f, 0x001b, 0x001b }, }, + { 74250000, { 0x0013, 0x001a, 0x001b }, }, + { 148500000, { 0x0019, 0x0033, 0x0034 }, }, + { 297000000, { 0x0019, 0x001b, 0x001b }, }, + { 594000000, { 0x0010, 0x001b, 0x001b }, }, { ~0UL, { 0x0000, 0x0000, 0x0000 }, } }; static const struct dw_hdmi_phy_config sun50i_h6_phy_config[] = { /*pixelclk symbol term vlev*/ - { 74250000, 0x8009, 0x0004, 0x0232}, - { 148500000, 0x8029, 0x0004, 0x0273}, - { 594000000, 0x8039, 0x0004, 0x014a}, + { 27000000, 0x8009, 0x0007, 0x02b0 }, + { 74250000, 0x8009, 0x0006, 0x022d }, + { 148500000, 0x8029, 0x0006, 0x0270 }, + { 297000000, 0x8039, 0x0005, 0x01ab }, + { 594000000, 0x8029, 0x0000, 0x008a }, { ~0UL, 0x0000, 0x0000, 0x0000} }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -107,48 +107,128 @@ .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_XRGB4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_ABGR4444, .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_XBGR4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_RGBA4444, .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_RGBX4444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_BGRA4444, .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_BGRX4444, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_ARGB1555, .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_XRGB1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_ABGR1555, .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_XBGR1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_RGBA5551, .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_RGBX5551, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_BGRA5551, .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, .rgb = true, .csc = SUN8I_CSC_MODE_OFF, }, { + /* for DE2 VI layer which ignores alpha */ + .drm_fmt = DRM_FORMAT_BGRX5551, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { + .drm_fmt = DRM_FORMAT_ARGB2101010, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { + .drm_fmt = DRM_FORMAT_ABGR2101010, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR2101010, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { + .drm_fmt = DRM_FORMAT_RGBA1010102, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA1010102, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { + .drm_fmt = DRM_FORMAT_BGRA1010102, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA1010102, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, + { .drm_fmt = DRM_FORMAT_UYVY, .de2_fmt = SUN8I_MIXER_FBFMT_UYVY, .rgb = false, @@ -197,12 +277,6 @@ .csc = SUN8I_CSC_MODE_YUV2RGB, }, { - .drm_fmt = DRM_FORMAT_YUV444, - .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, - .rgb = true, - .csc = SUN8I_CSC_MODE_YUV2RGB, - }, - { .drm_fmt = DRM_FORMAT_YUV422, .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, .rgb = false, @@ -221,12 +295,6 @@ .csc = SUN8I_CSC_MODE_YUV2RGB, }, { - .drm_fmt = DRM_FORMAT_YVU444, - .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, - .rgb = true, - .csc = SUN8I_CSC_MODE_YVU2RGB, - }, - { .drm_fmt = DRM_FORMAT_YVU422, .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, .rgb = false, @@ -244,6 +312,18 @@ .rgb = false, .csc = SUN8I_CSC_MODE_YVU2RGB, }, + { + .drm_fmt = DRM_FORMAT_P010, + .de2_fmt = SUN8I_MIXER_FBFMT_P010_YUV, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, + { + .drm_fmt = DRM_FORMAT_P210, + .de2_fmt = SUN8I_MIXER_FBFMT_P210_YUV, + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, }; const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) @@ -316,7 +396,7 @@ .reg_bits = 32, .val_bits = 32, .reg_stride = 4, - .max_register = 0xbfffc, /* guessed */ + .max_register = 0xffffc, /* guessed */ }; static int sun8i_mixer_of_get_id(struct device_node *node) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -93,6 +93,10 @@ #define SUN8I_MIXER_FBFMT_ABGR1555 17 #define SUN8I_MIXER_FBFMT_RGBA5551 18 #define SUN8I_MIXER_FBFMT_BGRA5551 19 +#define SUN8I_MIXER_FBFMT_ARGB2101010 20 +#define SUN8I_MIXER_FBFMT_ABGR2101010 21 +#define SUN8I_MIXER_FBFMT_RGBA1010102 22 +#define SUN8I_MIXER_FBFMT_BGRA1010102 23 #define SUN8I_MIXER_FBFMT_YUYV 0 #define SUN8I_MIXER_FBFMT_UYVY 1 @@ -109,6 +113,13 @@ /* format 12 is semi-planar YUV411 UVUV */ /* format 13 is semi-planar YUV411 VUVU */ #define SUN8I_MIXER_FBFMT_YUV411 14 +/* format 15 doesn't exist */ +#define SUN8I_MIXER_FBFMT_P010_YUV 16 +/* format 17 is P010 YVU */ +#define SUN8I_MIXER_FBFMT_P210_YUV 18 +/* format 19 is P210 YVU */ +/* format 20 is packed YVU444 10-bit */ +/* format 21 is packed YUV444 10-bit */ /* * Sub-engines listed bellow are unused for now. The EN registers are here only --- linux-oracle-5.4.0.orig/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -398,24 +398,66 @@ }; /* - * While all RGB formats are supported, VI planes don't support - * alpha blending, so there is no point having formats with alpha - * channel if their opaque analog exist. + * While DE2 VI layer supports same RGB formats as UI layer, alpha + * channel is ignored. This structure lists all unique variants + * where alpha channel is replaced with "don't care" (X) channel. */ static const u32 sun8i_vi_layer_formats[] = { + DRM_FORMAT_BGR565, + DRM_FORMAT_BGR888, + DRM_FORMAT_BGRX4444, + DRM_FORMAT_BGRX5551, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, + DRM_FORMAT_RGBX4444, + DRM_FORMAT_RGBX5551, + DRM_FORMAT_RGBX8888, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_XBGR4444, + DRM_FORMAT_XBGR8888, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_XRGB4444, + DRM_FORMAT_XRGB8888, + + DRM_FORMAT_NV16, + DRM_FORMAT_NV12, + DRM_FORMAT_NV21, + DRM_FORMAT_NV61, + DRM_FORMAT_UYVY, + DRM_FORMAT_VYUY, + DRM_FORMAT_YUYV, + DRM_FORMAT_YVYU, + DRM_FORMAT_YUV411, + DRM_FORMAT_YUV420, + DRM_FORMAT_YUV422, + DRM_FORMAT_YVU411, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, +}; + +static const u32 sun8i_vi_layer_de3_formats[] = { DRM_FORMAT_ABGR1555, + DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR4444, + DRM_FORMAT_ABGR8888, DRM_FORMAT_ARGB1555, + DRM_FORMAT_ARGB2101010, DRM_FORMAT_ARGB4444, + DRM_FORMAT_ARGB8888, DRM_FORMAT_BGR565, DRM_FORMAT_BGR888, + DRM_FORMAT_BGRA1010102, DRM_FORMAT_BGRA5551, DRM_FORMAT_BGRA4444, + DRM_FORMAT_BGRA8888, DRM_FORMAT_BGRX8888, DRM_FORMAT_RGB565, DRM_FORMAT_RGB888, + DRM_FORMAT_RGBA1010102, DRM_FORMAT_RGBA4444, DRM_FORMAT_RGBA5551, + DRM_FORMAT_RGBA8888, DRM_FORMAT_RGBX8888, DRM_FORMAT_XBGR8888, DRM_FORMAT_XRGB8888, @@ -424,6 +466,8 @@ DRM_FORMAT_NV12, DRM_FORMAT_NV21, DRM_FORMAT_NV61, + DRM_FORMAT_P010, + DRM_FORMAT_P210, DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, @@ -431,11 +475,9 @@ DRM_FORMAT_YUV411, DRM_FORMAT_YUV420, DRM_FORMAT_YUV422, - DRM_FORMAT_YUV444, DRM_FORMAT_YVU411, DRM_FORMAT_YVU420, DRM_FORMAT_YVU422, - DRM_FORMAT_YVU444, }; struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, @@ -443,19 +485,27 @@ int index) { u32 supported_encodings, supported_ranges; + unsigned int plane_cnt, format_count; struct sun8i_vi_layer *layer; - unsigned int plane_cnt; + const u32 *formats; int ret; layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); if (!layer) return ERR_PTR(-ENOMEM); + if (mixer->cfg->is_de3) { + formats = sun8i_vi_layer_de3_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); + } else { + formats = sun8i_vi_layer_formats; + format_count = ARRAY_SIZE(sun8i_vi_layer_formats); + } + /* possible crtcs are set later */ ret = drm_universal_plane_init(drm, &layer->plane, 0, &sun8i_vi_layer_funcs, - sun8i_vi_layer_formats, - ARRAY_SIZE(sun8i_vi_layer_formats), + formats, format_count, NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (ret) { dev_err(drm->dev, "Couldn't initialize layer\n"); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/dc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/dc.c @@ -919,6 +919,11 @@ .atomic_disable = tegra_cursor_atomic_disable, }; +static const uint64_t linear_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, struct tegra_dc *dc) { @@ -947,7 +952,7 @@ err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, + num_formats, linear_modifiers, DRM_PLANE_TYPE_CURSOR, NULL); if (err < 0) { kfree(plane); @@ -1065,7 +1070,8 @@ err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, type, NULL); + num_formats, linear_modifiers, + type, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -1667,6 +1673,11 @@ dev_err(dc->dev, "failed to set clock rate to %lu Hz\n", state->pclk); + + err = clk_set_rate(dc->clk, state->pclk); + if (err < 0) + dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", + dc->clk, state->pclk, err); } DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), @@ -1677,11 +1688,6 @@ value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1; tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL); } - - err = clk_set_rate(dc->clk, state->pclk); - if (err < 0) - dev_err(dc->dev, "failed to set clock %pC to %lu Hz: %d\n", - dc->clk, state->pclk, err); } static void tegra_dc_stop(struct tegra_dc *dc) @@ -2452,8 +2458,10 @@ usleep_range(2000, 4000); err = reset_control_assert(dc->rst); - if (err < 0) + if (err < 0) { + clk_disable_unprepare(dc->clk); return err; + } usleep_range(2000, 4000); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/dpaux.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/dpaux.c @@ -447,10 +447,8 @@ return PTR_ERR(dpaux->regs); dpaux->irq = platform_get_irq(pdev, 0); - if (dpaux->irq < 0) { - dev_err(&pdev->dev, "failed to get IRQ\n"); - return -ENXIO; - } + if (dpaux->irq < 0) + return dpaux->irq; if (!pdev->dev.pm_domain) { dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux"); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/drm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/drm.c @@ -122,8 +122,6 @@ drm->mode_config.max_width = 4096; drm->mode_config.max_height = 4096; - drm->mode_config.allow_fb_modifiers = true; - drm->mode_config.normalize_zpos = true; drm->mode_config.funcs = &tegra_drm_mode_config_funcs; @@ -201,19 +199,19 @@ if (tegra->hub) tegra_display_hub_cleanup(tegra->hub); device: - host1x_device_exit(device); -fbdev: - drm_kms_helper_poll_fini(drm); - tegra_drm_fb_free(drm); -config: - drm_mode_config_cleanup(drm); - if (tegra->domain) { mutex_destroy(&tegra->mm_lock); drm_mm_takedown(&tegra->mm); put_iova_domain(&tegra->carveout.domain); iova_cache_put(); } + + host1x_device_exit(device); +fbdev: + drm_kms_helper_poll_fini(drm); + tegra_drm_fb_free(drm); +config: + drm_mode_config_cleanup(drm); domain: if (tegra->domain) iommu_domain_free(tegra->domain); @@ -256,7 +254,7 @@ if (!fpriv) return -ENOMEM; - idr_init(&fpriv->contexts); + idr_init_base(&fpriv->contexts, 1); mutex_init(&fpriv->lock); filp->driver_priv = fpriv; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/dsi.c @@ -1451,12 +1451,16 @@ np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0); if (np) { struct platform_device *gangster = of_find_device_by_node(np); + of_node_put(np); + if (!gangster) + return -EPROBE_DEFER; dsi->slave = platform_get_drvdata(gangster); - of_node_put(np); - if (!dsi->slave) + if (!dsi->slave) { + put_device(&gangster->dev); return -EPROBE_DEFER; + } dsi->slave->master = dsi; } @@ -1499,48 +1503,58 @@ if (!pdev->dev.pm_domain) { dsi->rst = devm_reset_control_get(&pdev->dev, "dsi"); - if (IS_ERR(dsi->rst)) - return PTR_ERR(dsi->rst); + if (IS_ERR(dsi->rst)) { + err = PTR_ERR(dsi->rst); + goto remove; + } } dsi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dsi->clk)) { - dev_err(&pdev->dev, "cannot get DSI clock\n"); - return PTR_ERR(dsi->clk); + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk), + "cannot get DSI clock\n"); + goto remove; } dsi->clk_lp = devm_clk_get(&pdev->dev, "lp"); if (IS_ERR(dsi->clk_lp)) { - dev_err(&pdev->dev, "cannot get low-power clock\n"); - return PTR_ERR(dsi->clk_lp); + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp), + "cannot get low-power clock\n"); + goto remove; } dsi->clk_parent = devm_clk_get(&pdev->dev, "parent"); if (IS_ERR(dsi->clk_parent)) { - dev_err(&pdev->dev, "cannot get parent clock\n"); - return PTR_ERR(dsi->clk_parent); + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent), + "cannot get parent clock\n"); + goto remove; } dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi"); if (IS_ERR(dsi->vdd)) { - dev_err(&pdev->dev, "cannot get VDD supply\n"); - return PTR_ERR(dsi->vdd); + err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd), + "cannot get VDD supply\n"); + goto remove; } err = tegra_dsi_setup_clocks(dsi); if (err < 0) { dev_err(&pdev->dev, "cannot setup clocks\n"); - return err; + goto remove; } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->regs = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(dsi->regs)) - return PTR_ERR(dsi->regs); + if (IS_ERR(dsi->regs)) { + err = PTR_ERR(dsi->regs); + goto remove; + } - dsi->mipi = tegra_mipi_request(&pdev->dev); - if (IS_ERR(dsi->mipi)) - return PTR_ERR(dsi->mipi); + dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node); + if (IS_ERR(dsi->mipi)) { + err = PTR_ERR(dsi->mipi); + goto remove; + } dsi->host.ops = &tegra_dsi_host_ops; dsi->host.dev = &pdev->dev; @@ -1568,9 +1582,12 @@ return 0; unregister: + pm_runtime_disable(&pdev->dev); mipi_dsi_host_unregister(&dsi->host); mipi_free: tegra_mipi_free(dsi->mipi); +remove: + tegra_output_remove(&dsi->output); return err; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/fb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/fb.c @@ -155,6 +155,7 @@ if (gem->size < size) { err = -EINVAL; + drm_gem_object_put(gem); goto unreference; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/hub.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/hub.c @@ -141,7 +141,9 @@ for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - tegra_windowgroup_enable(wgrp); + /* Skip orphaned window group whose parent DC is disabled */ + if (wgrp->parent) + tegra_windowgroup_enable(wgrp); } return 0; @@ -158,7 +160,9 @@ for (i = 0; i < hub->soc->num_wgrps; i++) { struct tegra_windowgroup *wgrp = &hub->wgrps[i]; - tegra_windowgroup_disable(wgrp); + /* Skip orphaned window group whose parent DC is disabled */ + if (wgrp->parent) + tegra_windowgroup_disable(wgrp); } } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/output.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/output.c @@ -127,8 +127,10 @@ GPIOD_IN, "HDMI hotplug detect"); if (IS_ERR(output->hpd_gpio)) { - if (PTR_ERR(output->hpd_gpio) != -ENOENT) - return PTR_ERR(output->hpd_gpio); + if (PTR_ERR(output->hpd_gpio) != -ENOENT) { + err = PTR_ERR(output->hpd_gpio); + goto put_i2c; + } output->hpd_gpio = NULL; } @@ -137,7 +139,7 @@ err = gpiod_to_irq(output->hpd_gpio); if (err < 0) { dev_err(output->dev, "gpiod_to_irq(): %d\n", err); - return err; + goto put_i2c; } output->hpd_irq = err; @@ -150,7 +152,7 @@ if (err < 0) { dev_err(output->dev, "failed to request IRQ#%u: %d\n", output->hpd_irq, err); - return err; + goto put_i2c; } output->connector.polled = DRM_CONNECTOR_POLL_HPD; @@ -168,6 +170,12 @@ return -ENOMEM; return 0; + +put_i2c: + if (output->ddc) + i2c_put_adapter(output->ddc); + + return err; } void tegra_output_remove(struct tegra_output *output) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tegra/sor.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tegra/sor.c @@ -906,7 +906,7 @@ struct drm_dp_link *link) { const u64 f = 100000, link_rate = link->rate * 1000; - const u64 pclk = mode->clock * 1000; + const u64 pclk = (u64)mode->clock * 1000; u64 input, output, watermark, num; struct tegra_sor_params params; u32 num_syms_per_line; @@ -2875,21 +2875,21 @@ if (err < 0) { dev_err(sor->dev, "failed to acquire SOR reset: %d\n", err); - return err; + goto rpm_put; } err = reset_control_assert(sor->rst); if (err < 0) { dev_err(sor->dev, "failed to assert SOR reset: %d\n", err); - return err; + goto rpm_put; } } err = clk_prepare_enable(sor->clk); if (err < 0) { dev_err(sor->dev, "failed to enable clock: %d\n", err); - return err; + goto rpm_put; } usleep_range(1000, 3000); @@ -2899,19 +2899,25 @@ if (err < 0) { dev_err(sor->dev, "failed to deassert SOR reset: %d\n", err); - return err; + clk_disable_unprepare(sor->clk); + goto rpm_put; } reset_control_release(sor->rst); } err = clk_prepare_enable(sor->clk_safe); - if (err < 0) + if (err < 0) { + clk_disable_unprepare(sor->clk); return err; + } err = clk_prepare_enable(sor->clk_dp); - if (err < 0) + if (err < 0) { + clk_disable_unprepare(sor->clk_safe); + clk_disable_unprepare(sor->clk); return err; + } /* * Enable and unmask the HDA codec SCRATCH0 register interrupt. This @@ -2923,6 +2929,12 @@ tegra_sor_writel(sor, value, SOR_INT_MASK); return 0; + +rpm_put: + if (sor->rst) + pm_runtime_put(sor->dev); + + return err; } static int tegra_sor_exit(struct host1x_client *client) @@ -3200,6 +3212,11 @@ * earlier */ sor->pad = TEGRA_IO_PAD_HDMI_DP0 + sor->index; + } else { + if (sor->soc->supports_edp) + sor->index = 0; + else + sor->index = 1; } err = of_property_read_u32_array(np, "nvidia,xbar-cfg", xbar_cfg, 5); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tilcdc/tilcdc_external.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tilcdc/tilcdc_external.c @@ -58,11 +58,13 @@ int tilcdc_add_component_encoder(struct drm_device *ddev) { struct tilcdc_drm_private *priv = ddev->dev_private; - struct drm_encoder *encoder; + struct drm_encoder *encoder = NULL, *iter; - list_for_each_entry(encoder, &ddev->mode_config.encoder_list, head) - if (encoder->possible_crtcs & (1 << priv->crtc->index)) + list_for_each_entry(iter, &ddev->mode_config.encoder_list, head) + if (iter->possible_crtcs & (1 << priv->crtc->index)) { + encoder = iter; break; + } if (!encoder) { dev_err(ddev->dev, "%s: No suitable encoder found\n", __func__); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -143,12 +143,16 @@ int i; for (i = 0; i < timings->num_timings; i++) { - struct drm_display_mode *mode = drm_mode_create(dev); + struct drm_display_mode *mode; struct videomode vm; if (videomode_from_timings(timings, &vm, i)) break; + mode = drm_mode_create(dev); + if (!mode) + break; + drm_display_mode_from_videomode(&vm, mode); mode->type = DRM_MODE_TYPE_DRIVER; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/ttm/ttm_bo.c +++ linux-oracle-5.4.0/drivers/gpu/drm/ttm/ttm_bo.c @@ -517,8 +517,10 @@ dma_resv_unlock(bo->base.resv); } - if (bo->base.resv != &bo->base._resv) + if (bo->base.resv != &bo->base._resv) { + ttm_bo_flush_all_fences(bo); dma_resv_unlock(&bo->base._resv); + } error: kref_get(&bo->list_kref); @@ -759,7 +761,7 @@ /* Don't evict this BO if it's outside of the * requested placement range */ - if (place->fpfn >= (bo->mem.start + bo->mem.size) || + if (place->fpfn >= (bo->mem.start + bo->mem.num_pages) || (place->lpfn && place->lpfn <= bo->mem.start)) return false; @@ -926,7 +928,8 @@ */ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, struct ttm_mem_type_manager *man, - struct ttm_mem_reg *mem) + struct ttm_mem_reg *mem, + bool no_wait_gpu) { struct dma_fence *fence; int ret; @@ -935,19 +938,24 @@ fence = dma_fence_get(man->move); spin_unlock(&man->move_lock); - if (fence) { - dma_resv_add_shared_fence(bo->base.resv, fence); + if (!fence) + return 0; - ret = dma_resv_reserve_shared(bo->base.resv, 1); - if (unlikely(ret)) { - dma_fence_put(fence); - return ret; - } + if (no_wait_gpu) { + dma_fence_put(fence); + return -EBUSY; + } + + dma_resv_add_shared_fence(bo->base.resv, fence); - dma_fence_put(bo->moving); - bo->moving = fence; + ret = dma_resv_reserve_shared(bo->base.resv, 1); + if (unlikely(ret)) { + dma_fence_put(fence); + return ret; } + dma_fence_put(bo->moving); + bo->moving = fence; return 0; } @@ -978,7 +986,7 @@ return ret; } while (1); - return ttm_bo_add_move_fence(bo, man, mem); + return ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu); } static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man, @@ -1120,14 +1128,18 @@ if (unlikely(ret)) goto error; - if (mem->mm_node) { - ret = ttm_bo_add_move_fence(bo, man, mem); - if (unlikely(ret)) { - (*man->func->put_node)(man, mem); - goto error; - } - return 0; + if (!mem->mm_node) + continue; + + ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu); + if (unlikely(ret)) { + (*man->func->put_node)(man, mem); + if (ret == -EBUSY) + continue; + + goto error; } + return 0; } for (i = 0; i < placement->num_busy_placement; ++i) { --- linux-oracle-5.4.0.orig/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ linux-oracle-5.4.0/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -358,8 +358,10 @@ static int ttm_bo_vm_access(struct vm_area_struct *vma, unsigned long addr, void *buf, int len, int write) { - unsigned long offset = (addr) - vma->vm_start; struct ttm_buffer_object *bo = vma->vm_private_data; + unsigned long offset = (addr) - vma->vm_start + + ((vma->vm_pgoff - drm_vma_node_start(&bo->base.vma_node)) + << PAGE_SHIFT); int ret; if (len < 1 || (offset + len) >> PAGE_SHIFT > bo->num_pages) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/ttm/ttm_tt.c +++ linux-oracle-5.4.0/drivers/gpu/drm/ttm/ttm_tt.c @@ -241,7 +241,6 @@ ttm_tt_init_fields(ttm, bo, page_flags); if (ttm_tt_alloc_page_directory(ttm)) { - ttm_tt_destroy(ttm); pr_err("Failed allocating page table\n"); return -ENOMEM; } @@ -265,7 +264,6 @@ INIT_LIST_HEAD(&ttm_dma->pages_list); if (ttm_dma_tt_alloc_page_directory(ttm_dma)) { - ttm_tt_destroy(ttm); pr_err("Failed allocating page table\n"); return -ENOMEM; } @@ -287,7 +285,6 @@ else ret = ttm_dma_tt_alloc_page_directory(ttm_dma); if (ret) { - ttm_tt_destroy(ttm); pr_err("Failed allocating page table\n"); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tve200/tve200_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tve200/tve200_display.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -130,9 +131,25 @@ struct drm_connector *connector = priv->connector; u32 format = fb->format->format; u32 ctrl1 = 0; + int retries; clk_prepare_enable(priv->clk); + /* Reset the TVE200 and wait for it to come back online */ + writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4); + for (retries = 0; retries < 5; retries++) { + usleep_range(30000, 50000); + if (readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET) + continue; + else + break; + } + if (retries == 5 && + readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET) { + dev_err(drm->dev, "can't get hardware out of reset\n"); + return; + } + /* Function 1 */ ctrl1 |= TVE200_CTRL_CSMODE; /* Interlace mode for CCIR656: parameterize? */ @@ -230,8 +247,9 @@ drm_crtc_vblank_off(crtc); - /* Disable and Power Down */ + /* Disable put into reset and Power Down */ writel(0, priv->regs + TVE200_CTRL); + writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4); clk_disable_unprepare(priv->clk); } @@ -279,6 +297,8 @@ struct drm_device *drm = crtc->dev; struct tve200_drm_dev_private *priv = drm->dev_private; + /* Clear any IRQs and enable */ + writel(0xFF, priv->regs + TVE200_INT_CLR); writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN); return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/tve200/tve200_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/tve200/tve200_drv.c @@ -210,8 +210,8 @@ } irq = platform_get_irq(pdev, 0); - if (!irq) { - ret = -EINVAL; + if (irq < 0) { + ret = irq; goto clk_disable; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/udl/udl_connector.c +++ linux-oracle-5.4.0/drivers/gpu/drm/udl/udl_connector.c @@ -29,7 +29,7 @@ ret = usb_control_msg(udl->udev, usb_rcvctrlpipe(udl->udev, 0), (0x02), (0x80 | (0x02 << 5)), bval, - 0xA1, read_buff, 2, HZ); + 0xA1, read_buff, 2, 1000); if (ret < 1) { DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret); kfree(read_buff); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/v3d/v3d_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/v3d/v3d_gem.c @@ -195,8 +195,8 @@ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF); if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) & - V3D_L2TCACTL_L2TFLS), 100)) { - DRM_ERROR("Timeout waiting for L1T write combiner flush\n"); + V3D_L2TCACTL_TMUWCF), 100)) { + DRM_ERROR("Timeout waiting for TMU write combiner flush\n"); } mutex_lock(&v3d->cache_clean_lock); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/v3d/v3d_irq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/v3d/v3d_irq.c @@ -102,7 +102,10 @@ to_v3d_fence(v3d->bin_job->base.irq_fence); trace_v3d_bcl_irq(&v3d->drm, fence->seqno); + + v3d->bin_job = NULL; dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -111,7 +114,10 @@ to_v3d_fence(v3d->render_job->base.irq_fence); trace_v3d_rcl_irq(&v3d->drm, fence->seqno); + + v3d->render_job = NULL; dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -120,7 +126,10 @@ to_v3d_fence(v3d->csd_job->base.irq_fence); trace_v3d_csd_irq(&v3d->drm, fence->seqno); + + v3d->csd_job = NULL; dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } @@ -156,7 +165,10 @@ to_v3d_fence(v3d->tfu_job->base.irq_fence); trace_v3d_tfu_irq(&v3d->drm, fence->seqno); + + v3d->tfu_job = NULL; dma_fence_signal(&fence->base); + status = IRQ_HANDLED; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vboxvideo/hgsmi_base.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vboxvideo/hgsmi_base.c @@ -135,7 +135,15 @@ flags |= VBOX_MOUSE_POINTER_VISIBLE; } - p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA, + /* + * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape + * from having a 4 bytes fixed array at the end to using a proper VLA + * at the end. These 4 extra bytes were not subtracted from sizeof(*p) + * before the switch to the VLA, so this way the behavior is unchanged. + * Chances are these 4 extra bytes are not necessary but they are kept + * to avoid regressions. + */ + p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA, VBVA_MOUSE_POINTER_SHAPE); if (!p) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vboxvideo/vboxvideo.h +++ linux-oracle-5.4.0/drivers/gpu/drm/vboxvideo/vboxvideo.h @@ -351,10 +351,8 @@ * Bytes in the gap between the AND and the XOR mask are undefined. * XOR mask scanlines have no gap between them and size of XOR mask is: * xor_len = width * 4 * height. - * - * Preallocate 4 bytes for accessing actual data as p->data. */ - u8 data[4]; + u8 data[]; } __packed; /* pointer is visible */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_bo.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_bo.c @@ -389,7 +389,7 @@ bo = kzalloc(sizeof(*bo), GFP_KERNEL); if (!bo) - return ERR_PTR(-ENOMEM); + return NULL; bo->madv = VC4_MADV_WILLNEED; refcount_set(&bo->usecnt, 0); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_dpi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_dpi.c @@ -151,35 +151,45 @@ } drm_connector_list_iter_end(&conn_iter); - if (connector && connector->display_info.num_bus_formats) { - u32 bus_format = connector->display_info.bus_formats[0]; + if (connector) { + if (connector->display_info.num_bus_formats) { + u32 bus_format = connector->display_info.bus_formats[0]; - switch (bus_format) { - case MEDIA_BUS_FMT_RGB888_1X24: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_BGR888_1X24: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, - DPI_FORMAT); - dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER); - break; - case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_RGB666_1X18: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, - DPI_FORMAT); - break; - case MEDIA_BUS_FMT_RGB565_1X16: - dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_3, - DPI_FORMAT); - break; - default: - DRM_ERROR("Unknown media bus format %d\n", bus_format); - break; + switch (bus_format) { + case MEDIA_BUS_FMT_RGB888_1X24: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_BGR888_1X24: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, + DPI_FORMAT); + dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, + DPI_ORDER); + break; + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_RGB666_1X18: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, + DPI_FORMAT); + break; + case MEDIA_BUS_FMT_RGB565_1X16: + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1, + DPI_FORMAT); + break; + default: + DRM_ERROR("Unknown media bus format %d\n", + bus_format); + break; + } } + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) + dpi_c |= DPI_PIXEL_CLK_INVERT; + + if (connector->display_info.bus_flags & DRM_BUS_FLAG_DE_LOW) + dpi_c |= DPI_OUTPUT_ENABLE_INVERT; } else { /* Default to 24bit if no connector found. */ dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_drv.c @@ -309,6 +309,7 @@ component_unbind_all(dev, drm); gem_destroy: vc4_gem_destroy(drm); + drm_mode_config_cleanup(drm); vc4_bo_cache_destroy(drm); dev_put: drm_dev_put(drm); @@ -391,7 +392,12 @@ if (ret) return ret; - return platform_driver_register(&vc4_platform_driver); + ret = platform_driver_register(&vc4_platform_driver); + if (ret) + platform_unregister_drivers(component_drivers, + ARRAY_SIZE(component_drivers)); + + return ret; } static void __exit vc4_drm_unregister(void) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_drv.h @@ -750,7 +750,7 @@ void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); void vc4_crtc_txp_armed(struct drm_crtc_state *state); void vc4_crtc_get_margins(struct drm_crtc_state *state, - unsigned int *right, unsigned int *left, + unsigned int *left, unsigned int *right, unsigned int *top, unsigned int *bottom); /* vc4_debugfs.c */ --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_dsi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_dsi.c @@ -752,9 +752,9 @@ struct vc4_dsi *dsi = vc4_encoder->dsi; struct device *dev = &dsi->pdev->dev; - drm_bridge_disable(dsi->bridge); + drm_bridge_chain_disable(dsi->bridge); vc4_dsi_ulps(dsi, true); - drm_bridge_post_disable(dsi->bridge); + drm_bridge_chain_post_disable(dsi->bridge); clk_disable_unprepare(dsi->pll_phy_clock); clk_disable_unprepare(dsi->escape_clock); @@ -791,11 +791,9 @@ /* Find what divider gets us a faster clock than the requested * pixel clock. */ - for (divider = 1; divider < 8; divider++) { - if (parent_rate / divider < pll_clock) { - divider--; + for (divider = 1; divider < 255; divider++) { + if (parent_rate / (divider + 1) < pll_clock) break; - } } /* Now that we've picked a PLL divider, calculate back to its @@ -831,7 +829,7 @@ unsigned long phy_clock; int ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret) { DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->port); return; @@ -1054,7 +1052,7 @@ vc4_dsi_ulps(dsi, false); - drm_bridge_pre_enable(dsi->bridge); + drm_bridge_chain_pre_enable(dsi->bridge); if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { DSI_PORT_WRITE(DISP0_CTRL, @@ -1071,7 +1069,7 @@ DSI_DISP0_ENABLE); } - drm_bridge_enable(dsi->bridge); + drm_bridge_chain_enable(dsi->bridge); if (debug_dump_regs) { struct drm_printer p = drm_info_printer(&dsi->pdev->dev); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_hdmi.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -236,7 +236,7 @@ edid = drm_get_edid(connector, vc4->hdmi->ddc); cec_s_phys_addr_from_edid(vc4->hdmi->cec_adap, edid); if (!edid) - return -ENODEV; + return 0; vc4_encoder->hdmi_monitor = drm_detect_hdmi_monitor(edid); @@ -681,11 +681,23 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *crtc, const struct drm_display_mode *mode) { - /* HSM clock must be 108% of the pixel clock. Additionally, - * the AXI clock needs to be at least 25% of pixel clock, but - * HSM ends up being the limiting factor. + /* + * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must + * be faster than pixel clock, infinitesimally faster, tested in + * simulation. Otherwise, exact value is unimportant for HDMI + * operation." This conflicts with bcm2835's vc4 documentation, which + * states HSM's clock has to be at least 108% of the pixel clock. + * + * Real life tests reveal that vc4's firmware statement holds up, and + * users are able to use pixel clocks closer to HSM's, namely for + * 1920x1200@60Hz. So it was decided to have leave a 1% margin between + * both clocks. Which, for RPi0-3 implies a maximum pixel clock of + * 162MHz. + * + * Additionally, the AXI clock needs to be at least 25% of + * pixel clock, but HSM ends up being the limiting factor. */ - if (mode->clock > HSM_CLOCK_FREQ / (1000 * 108 / 100)) + if (mode->clock > HSM_CLOCK_FREQ / (1000 * 101 / 100)) return MODE_CLOCK_HIGH; return MODE_OK; @@ -1113,6 +1125,7 @@ card->num_links = 1; card->name = "vc4-hdmi"; card->dev = dev; + card->owner = THIS_MODULE; /* * Be careful, snd_soc_register_card() calls dev_set_drvdata() and @@ -1285,6 +1298,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) { +#ifdef CONFIG_DRM_VC4_HDMI_CEC + struct cec_connector_info conn_info; +#endif struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = dev_get_drvdata(master); struct vc4_dev *vc4 = drm->dev_private; @@ -1403,13 +1419,15 @@ #ifdef CONFIG_DRM_VC4_HDMI_CEC hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops, vc4, "vc4", - CEC_CAP_TRANSMIT | - CEC_CAP_LOG_ADDRS | - CEC_CAP_PASSTHROUGH | - CEC_CAP_RC, 1); + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, 1); ret = PTR_ERR_OR_ZERO(hdmi->cec_adap); if (ret < 0) goto err_destroy_conn; + + cec_fill_conn_info_from_drm(&conn_info, hdmi->connector); + cec_s_conn_info(hdmi->cec_adap, &conn_info); + HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff); value = HDMI_READ(VC4_HDMI_CEC_CNTRL_1); value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_plane.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_plane.c @@ -205,7 +205,7 @@ __drm_atomic_helper_plane_reset(plane, &vc4_state->base); } -static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) +static void vc4_dlist_counter_increment(struct vc4_plane_state *vc4_state) { if (vc4_state->dlist_count == vc4_state->dlist_size) { u32 new_size = max(4u, vc4_state->dlist_count * 2); @@ -220,7 +220,15 @@ vc4_state->dlist_size = new_size; } - vc4_state->dlist[vc4_state->dlist_count++] = val; + vc4_state->dlist_count++; +} + +static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val) +{ + unsigned int idx = vc4_state->dlist_count; + + vc4_dlist_counter_increment(vc4_state); + vc4_state->dlist[idx] = val; } /* Returns the scl0/scl1 field based on whether the dimensions need to @@ -280,16 +288,16 @@ adjhdisplay, crtc_state->mode.hdisplay); vc4_pstate->crtc_x += left; - if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - left) - vc4_pstate->crtc_x = crtc_state->mode.hdisplay - left; + if (vc4_pstate->crtc_x > crtc_state->mode.hdisplay - right) + vc4_pstate->crtc_x = crtc_state->mode.hdisplay - right; adjvdisplay = crtc_state->mode.vdisplay - (top + bottom); vc4_pstate->crtc_y = DIV_ROUND_CLOSEST(vc4_pstate->crtc_y * adjvdisplay, crtc_state->mode.vdisplay); vc4_pstate->crtc_y += top; - if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - top) - vc4_pstate->crtc_y = crtc_state->mode.vdisplay - top; + if (vc4_pstate->crtc_y > crtc_state->mode.vdisplay - bottom) + vc4_pstate->crtc_y = crtc_state->mode.vdisplay - bottom; vc4_pstate->crtc_w = DIV_ROUND_CLOSEST(vc4_pstate->crtc_w * adjhdisplay, @@ -309,7 +317,6 @@ struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); struct drm_framebuffer *fb = state->fb; struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0); - u32 subpixel_src_mask = (1 << 16) - 1; int num_planes = fb->format->num_planes; struct drm_crtc_state *crtc_state; u32 h_subsample = fb->format->hsub; @@ -331,18 +338,15 @@ for (i = 0; i < num_planes; i++) vc4_state->offsets[i] = bo->paddr + fb->offsets[i]; - /* We don't support subpixel source positioning for scaling. */ - if ((state->src.x1 & subpixel_src_mask) || - (state->src.x2 & subpixel_src_mask) || - (state->src.y1 & subpixel_src_mask) || - (state->src.y2 & subpixel_src_mask)) { - return -EINVAL; - } - - vc4_state->src_x = state->src.x1 >> 16; - vc4_state->src_y = state->src.y1 >> 16; - vc4_state->src_w[0] = (state->src.x2 - state->src.x1) >> 16; - vc4_state->src_h[0] = (state->src.y2 - state->src.y1) >> 16; + /* + * We don't support subpixel source positioning for scaling, + * but fractional coordinates can be generated by clipping + * so just round for now + */ + vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16); + vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16); + vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x; + vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y; vc4_state->crtc_x = state->dst.x1; vc4_state->crtc_y = state->dst.y1; @@ -871,8 +875,10 @@ * be set when calling vc4_plane_allocate_lbm(). */ if (vc4_state->y_scaling[0] != VC4_SCALING_NONE || - vc4_state->y_scaling[1] != VC4_SCALING_NONE) - vc4_state->lbm_offset = vc4_state->dlist_count++; + vc4_state->y_scaling[1] != VC4_SCALING_NONE) { + vc4_state->lbm_offset = vc4_state->dlist_count; + vc4_dlist_counter_increment(vc4_state); + } if (num_planes > 1) { /* Emit Cb/Cr as channel 0 and Y as channel --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_txp.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_txp.c @@ -285,12 +285,18 @@ if (WARN_ON(i == ARRAY_SIZE(drm_fmts))) return; - ctrl = TXP_GO | TXP_VSTART_AT_EOF | TXP_EI | + ctrl = TXP_GO | TXP_EI | VC4_SET_FIELD(0xf, TXP_BYTE_ENABLE) | VC4_SET_FIELD(txp_fmts[i], TXP_FORMAT); if (fb->format->has_alpha) ctrl |= TXP_ALPHA_ENABLE; + else + /* + * If TXP_ALPHA_ENABLE isn't set and TXP_ALPHA_INVERT is, the + * hardware will force the output padding to be 0xff. + */ + ctrl |= TXP_ALPHA_INVERT; gem = drm_fb_cma_get_gem_obj(fb, 0); TXP_WRITE(TXP_DST_PTR, gem->paddr + fb->offsets[0]); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vc4/vc4_vec.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vc4/vc4_vec.c @@ -256,7 +256,7 @@ static const struct drm_display_mode ntsc_mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, - 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0, + 480, 480 + 7, 480 + 7 + 6, 525, 0, DRM_MODE_FLAG_INTERLACE) }; @@ -278,7 +278,7 @@ static const struct drm_display_mode pal_mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, - 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0, + 576, 576 + 4, 576 + 4 + 6, 625, 0, DRM_MODE_FLAG_INTERLACE) }; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vgem/vgem_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vgem/vgem_drv.c @@ -196,9 +196,10 @@ return ERR_CAST(obj); ret = drm_gem_handle_create(file, &obj->base, handle); - drm_gem_object_put_unlocked(&obj->base); - if (ret) + if (ret) { + drm_gem_object_put_unlocked(&obj->base); return ERR_PTR(ret); + } return &obj->base; } @@ -221,35 +222,11 @@ args->size = gem_object->size; args->pitch = pitch; - DRM_DEBUG("Created object of size %lld\n", size); + drm_gem_object_put_unlocked(gem_object); - return 0; -} - -static int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev, - uint32_t handle, uint64_t *offset) -{ - struct drm_gem_object *obj; - int ret; + DRM_DEBUG("Created object of size %llu\n", args->size); - obj = drm_gem_object_lookup(file, handle); - if (!obj) - return -ENOENT; - - if (!obj->filp) { - ret = -EINVAL; - goto unref; - } - - ret = drm_gem_create_mmap_offset(obj); - if (ret) - goto unref; - - *offset = drm_vma_node_offset_addr(&obj->vma_node); -unref: - drm_gem_object_put_unlocked(obj); - - return ret; + return 0; } static struct drm_ioctl_desc vgem_ioctls[] = { @@ -445,7 +422,6 @@ .fops = &vgem_driver_fops, .dumb_create = vgem_gem_dumb_create, - .dumb_map_offset = vgem_gem_dumb_map, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vgem/vgem_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vgem/vgem_fence.c @@ -249,4 +249,5 @@ { idr_for_each(&vfile->fence_idr, __vgem_fence_idr_fini, vfile); idr_destroy(&vfile->fence_idr); + mutex_destroy(&vfile->fence_mutex); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/virtio/virtgpu_display.c +++ linux-oracle-5.4.0/drivers/gpu/drm/virtio/virtgpu_display.c @@ -174,6 +174,8 @@ DRM_DEBUG("add mode: %dx%d\n", width, height); mode = drm_cvt_mode(connector->dev, width, height, 60, false, false, false); + if (!mode) + return count; mode->type |= DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, mode); count++; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -327,10 +327,18 @@ drm_gem_object_release(obj); return ret; } - drm_gem_object_put_unlocked(obj); rc->res_handle = qobj->hw_res_handle; /* similiar to a VM address */ rc->bo_handle = handle; + + /* + * The handle owns the reference now. But we must drop our + * remaining reference *after* we no longer need to dereference + * the obj. Otherwise userspace could guess the handle and + * race closing it from another thread. + */ + drm_gem_object_put_unlocked(obj); + return 0; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/virtio/virtgpu_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -96,8 +96,10 @@ vgdev->capsets[i].id > 0, 5 * HZ); if (ret == 0) { DRM_ERROR("timed out waiting for cap set %d\n", i); + spin_lock(&vgdev->display_info_lock); kfree(vgdev->capsets); vgdev->capsets = NULL; + spin_unlock(&vgdev->display_info_lock); return; } DRM_INFO("cap set %d: id %d, max-version %d, max-size %d\n", @@ -216,6 +218,7 @@ err_vbufs: vgdev->vdev->config->del_vqs(vgdev->vdev); err_vqs: + dev->dev_private = NULL; kfree(vgdev); return ret; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/virtio/virtgpu_object.c +++ linux-oracle-5.4.0/drivers/gpu/drm/virtio/virtgpu_object.c @@ -23,38 +23,44 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include + #include #include "virtgpu_drv.h" +static int virtio_gpu_virglrenderer_workaround = 1; +module_param_named(virglhack, virtio_gpu_virglrenderer_workaround, int, 0400); + static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, uint32_t *resid) { -#if 0 - int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); - - if (handle < 0) - return handle; -#else - static int handle; - - /* - * FIXME: dirty hack to avoid re-using IDs, virglrenderer - * can't deal with that. Needs fixing in virglrenderer, also - * should figure a better way to handle that in the guest. - */ - handle++; -#endif - - *resid = handle + 1; + if (virtio_gpu_virglrenderer_workaround) { + /* + * Hack to avoid re-using resource IDs. + * + * virglrenderer versions up to (and including) 0.7.0 + * can't deal with that. virglrenderer commit + * "f91a9dd35715 Fix unlinking resources from hash + * table." (Feb 2019) fixes the bug. + */ + static atomic_t seqno = ATOMIC_INIT(0); + int handle = atomic_inc_return(&seqno); + *resid = handle + 1; + } else { + int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); + if (handle < 0) + return handle; + *resid = handle + 1; + } return 0; } static void virtio_gpu_resource_id_put(struct virtio_gpu_device *vgdev, uint32_t id) { -#if 0 - ida_free(&vgdev->resource_ida, id - 1); -#endif + if (!virtio_gpu_virglrenderer_workaround) { + ida_free(&vgdev->resource_ida, id - 1); + } } static void virtio_gpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/virtio/virtgpu_vq.c +++ linux-oracle-5.4.0/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -80,9 +80,7 @@ { struct virtio_gpu_vbuffer *vbuf; - vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL); - if (!vbuf) - return ERR_PTR(-ENOMEM); + vbuf = kmem_cache_zalloc(vgdev->vbufs, GFP_KERNEL | __GFP_NOFAIL); BUG_ON(size > MAX_INLINE_CMD_SIZE); vbuf->buf = (void *)vbuf + sizeof(*vbuf); @@ -142,10 +140,6 @@ vbuf = virtio_gpu_get_vbuf(vgdev, cmd_size, resp_size, resp_buf, cb); - if (IS_ERR(vbuf)) { - *vbuffer_p = NULL; - return ERR_CAST(vbuf); - } *vbuffer_p = vbuf; return (struct virtio_gpu_command *)vbuf->buf; } @@ -572,9 +566,13 @@ int i = le32_to_cpu(cmd->capset_index); spin_lock(&vgdev->display_info_lock); - vgdev->capsets[i].id = le32_to_cpu(resp->capset_id); - vgdev->capsets[i].max_version = le32_to_cpu(resp->capset_max_version); - vgdev->capsets[i].max_size = le32_to_cpu(resp->capset_max_size); + if (vgdev->capsets) { + vgdev->capsets[i].id = le32_to_cpu(resp->capset_id); + vgdev->capsets[i].max_version = le32_to_cpu(resp->capset_max_version); + vgdev->capsets[i].max_size = le32_to_cpu(resp->capset_max_size); + } else { + DRM_ERROR("invalid capset memory."); + } spin_unlock(&vgdev->display_info_lock); wake_up(&vgdev->resp_wq); } @@ -988,8 +986,9 @@ } /* gets freed when the ring has consumed it */ - ents = kmalloc_array(nents, sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); + ents = kvmalloc_array(nents, + sizeof(struct virtio_gpu_mem_entry), + GFP_KERNEL); if (!ents) { DRM_ERROR("failed to allocate ent list\n"); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vkms/vkms_composer.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vkms/vkms_composer.c @@ -33,7 +33,7 @@ + (i * composer->pitch) + (j * composer->cpp); /* XRGB format ignores Alpha channel */ - memset(vaddr_out + src_offset + 24, 0, 8); + bitmap_clear(vaddr_out + src_offset, 24, 8); crc = crc32_le(crc, vaddr_out + src_offset, sizeof(u32)); } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vkms/vkms_crtc.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vkms/vkms_crtc.c @@ -20,7 +20,8 @@ ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer, output->period_ns); - WARN_ON(ret_overrun != 1); + if (ret_overrun != 1) + pr_warn("%s: vblank timer overrun\n", __func__); ret = drm_crtc_handle_vblank(crtc); if (!ret) --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vkms/vkms_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vkms/vkms_drv.c @@ -60,7 +60,6 @@ struct vkms_device *vkms = container_of(dev, struct vkms_device, drm); platform_device_unregister(vkms->platform); - drm_atomic_helper_shutdown(&vkms->drm); drm_mode_config_cleanup(&vkms->drm); drm_dev_fini(&vkms->drm); destroy_workqueue(vkms->output.composer_workq); @@ -194,6 +193,7 @@ } drm_dev_unregister(&vkms_device->drm); + drm_atomic_helper_shutdown(&vkms_device->drm); drm_dev_put(&vkms_device->drm); kfree(vkms_device); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vkms/vkms_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/vkms/vkms_drv.h @@ -121,11 +121,6 @@ enum drm_plane_type type, int index); /* Gem stuff */ -struct drm_gem_object *vkms_gem_create(struct drm_device *dev, - struct drm_file *file, - u32 *handle, - u64 size); - vm_fault_t vkms_gem_fault(struct vm_fault *vmf); int vkms_dumb_create(struct drm_file *file, struct drm_device *dev, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vkms/vkms_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vkms/vkms_gem.c @@ -95,10 +95,10 @@ return ret; } -struct drm_gem_object *vkms_gem_create(struct drm_device *dev, - struct drm_file *file, - u32 *handle, - u64 size) +static struct drm_gem_object *vkms_gem_create(struct drm_device *dev, + struct drm_file *file, + u32 *handle, + u64 size) { struct vkms_gem_object *obj; int ret; @@ -111,7 +111,6 @@ return ERR_CAST(obj); ret = drm_gem_handle_create(file, &obj->gem, handle); - drm_gem_object_put_unlocked(&obj->gem); if (ret) return ERR_PTR(ret); @@ -140,6 +139,8 @@ args->size = gem_obj->size; args->pitch = pitch; + drm_gem_object_put_unlocked(gem_obj); + DRM_DEBUG_DRIVER("Created object of size %lld\n", size); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -209,8 +209,10 @@ cres->hash.key = user_key | (res_type << 24); ret = drm_ht_insert_item(&man->resources, &cres->hash); - if (unlikely(ret != 0)) + if (unlikely(ret != 0)) { + kfree(cres); goto out_invalid_key; + } cres->state = VMW_CMDBUF_RES_ADD; cres->res = vmw_resource_reference(res); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -731,7 +731,7 @@ }; int ret; - if (!dev_priv->has_dx && dx) { + if (!has_sm4_context(dev_priv) && dx) { VMW_DEBUG_USER("DX contexts not supported by device.\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -442,7 +442,7 @@ dev_priv->cman = vmw_cmdbuf_man_create(dev_priv); if (IS_ERR(dev_priv->cman)) { dev_priv->cman = NULL; - dev_priv->has_dx = false; + dev_priv->sm_type = VMW_SM_LEGACY; } ret = vmw_request_device_late(dev_priv); @@ -870,11 +870,22 @@ if (dev_priv->has_mob) { spin_lock(&dev_priv->cap_lock); vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_DXCONTEXT); - dev_priv->has_dx = !!vmw_read(dev_priv, SVGA_REG_DEV_CAP); + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4; spin_unlock(&dev_priv->cap_lock); } vmw_validation_mem_init_ttm(dev_priv, VMWGFX_VALIDATION_MEM_GRAN); + + /* SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 support */ + if (has_sm4_context(dev_priv) && + (dev_priv->capabilities2 & SVGA_CAP2_DX2)) { + vmw_write(dev_priv, SVGA_REG_DEV_CAP, SVGA3D_DEVCAP_SM41); + + if (vmw_read(dev_priv, SVGA_REG_DEV_CAP)) + dev_priv->sm_type = VMW_SM_4_1; + } + ret = vmw_kms_init(dev_priv); if (unlikely(ret != 0)) goto out_no_kms; @@ -884,23 +895,12 @@ if (ret) goto out_no_fifo; - if (dev_priv->has_dx) { - /* - * SVGA_CAP2_DX2 (DefineGBSurface_v3) is needed for SM4_1 - * support - */ - if ((dev_priv->capabilities2 & SVGA_CAP2_DX2) != 0) { - vmw_write(dev_priv, SVGA_REG_DEV_CAP, - SVGA3D_DEVCAP_SM41); - dev_priv->has_sm4_1 = vmw_read(dev_priv, - SVGA_REG_DEV_CAP); - } - } - - DRM_INFO("DX: %s\n", dev_priv->has_dx ? "yes." : "no."); DRM_INFO("Atomic: %s\n", (dev->driver->driver_features & DRIVER_ATOMIC) ? "yes." : "no."); - DRM_INFO("SM4_1: %s\n", dev_priv->has_sm4_1 ? "yes." : "no."); + if (dev_priv->sm_type == VMW_SM_4_1) + DRM_INFO("SM4_1 support available.\n"); + if (dev_priv->sm_type == VMW_SM_4) + DRM_INFO("SM4 support available.\n"); snprintf(host_log, sizeof(host_log), "vmwgfx: %s-%s", VMWGFX_REPO, VMWGFX_GIT_VERSION); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -432,6 +432,20 @@ VMW_IRQTHREAD_MAX }; +/** + * enum vmw_sm_type - Graphics context capability supported by device. + * @VMW_SM_LEGACY: Pre DX context. + * @VMW_SM_4: Context support upto SM4. + * @VMW_SM_4_1: Context support upto SM4_1. + * @VMW_SM_MAX: Should be the last. + */ +enum vmw_sm_type { + VMW_SM_LEGACY = 0, + VMW_SM_4, + VMW_SM_4_1, + VMW_SM_MAX +}; + struct vmw_private { struct ttm_bo_device bdev; @@ -465,9 +479,9 @@ bool has_mob; spinlock_t hw_lock; spinlock_t cap_lock; - bool has_dx; bool assume_16bpp; - bool has_sm4_1; + + enum vmw_sm_type sm_type; /* * VGA registers. @@ -651,6 +665,28 @@ return val; } +/** + * has_sm4_context - Does the device support SM4 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4 context or not. + */ +static inline bool has_sm4_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4); +} + +/** + * has_sm4_1_context - Does the device support SM4_1 context. + * @dev_priv: Device private. + * + * Return: Bool value if device support SM4_1 context or not. + */ +static inline bool has_sm4_1_context(const struct vmw_private *dev_priv) +{ + return (dev_priv->sm_type >= VMW_SM_4_1); +} + extern void vmw_svga_enable(struct vmw_private *dev_priv); extern void vmw_svga_disable(struct vmw_private *dev_priv); @@ -1002,15 +1038,14 @@ struct vmw_private *dev_priv, struct vmw_fence_obj **p_fence, uint32_t *p_handle); -extern void vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, +extern int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, struct vmw_fpriv *vmw_fp, int ret, struct drm_vmw_fence_rep __user *user_fence_rep, struct vmw_fence_obj *fence, uint32_t fence_handle, - int32_t out_fence_fd, - struct sync_file *sync_file); + int32_t out_fence_fd); bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd); /** @@ -1487,4 +1522,15 @@ { WRITE_ONCE(*addr, value); } + +static inline bool vmw_shadertype_is_valid(enum vmw_sm_type shader_model, + u32 shader_type) +{ + SVGA3dShaderType max_allowed = SVGA3D_SHADERTYPE_PREDX_MAX; + + if (shader_model >= VMW_SM_4) + max_allowed = SVGA3D_SHADERTYPE_DX10_MAX; + return shader_type >= SVGA3D_SHADERTYPE_MIN && shader_type < max_allowed; +} + #endif --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -461,10 +461,11 @@ u32 i; /* Add all cotables to the validation list. */ - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) { res = vmw_context_cotable(ctx, i); - if (IS_ERR(res)) + if (IS_ERR_OR_NULL(res)) continue; ret = vmw_execbuf_res_noctx_val_add(sw_context, res, @@ -489,7 +490,8 @@ break; } - if (dev_priv->has_dx && vmw_res_type(ctx) == vmw_res_dx_context) { + if (has_sm4_context(dev_priv) && + vmw_res_type(ctx) == vmw_res_dx_context) { struct vmw_buffer_object *dx_query_mob; dx_query_mob = vmw_context_get_dx_query_mob(ctx); @@ -1268,6 +1270,8 @@ return -EINVAL; cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY); + if (IS_ERR_OR_NULL(cotable_res)) + return cotable_res ? PTR_ERR(cotable_res) : -EINVAL; ret = vmw_cotable_notify(cotable_res, cmd->body.queryId); return ret; @@ -1623,7 +1627,7 @@ { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetTextureState); SVGA3dTextureState *last_state = (SVGA3dTextureState *) - ((unsigned long) header + header->size + sizeof(header)); + ((unsigned long) header + header->size + sizeof(*header)); SVGA3dTextureState *cur_state = (SVGA3dTextureState *) ((unsigned long) header + sizeof(*cmd)); struct vmw_resource *ctx; @@ -1994,7 +1998,7 @@ cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) { + if (!vmw_shadertype_is_valid(VMW_SM_LEGACY, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); return -EINVAL; @@ -2131,6 +2135,14 @@ if (unlikely(ret != 0)) return ret; + if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type) || + cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { + VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", + (unsigned int) cmd->body.type, + (unsigned int) cmd->body.slot); + return -EINVAL; + } + binding.bi.ctx = ctx_node->ctx; binding.bi.res = res; binding.bi.bt = vmw_ctx_binding_cb; @@ -2139,14 +2151,6 @@ binding.size = cmd->body.sizeInBytes; binding.slot = cmd->body.slot; - if (binding.shader_slot >= SVGA3D_NUM_SHADERTYPE_DX10 || - binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) { - VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n", - (unsigned int) cmd->body.type, - (unsigned int) binding.slot); - return -EINVAL; - } - vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, binding.slot); @@ -2167,12 +2171,13 @@ { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) = container_of(header, typeof(*cmd), header); + u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dShaderResourceViewId); if ((u64) cmd->body.startView + (u64) num_sr_view > (u64) SVGA3D_DX_MAX_SRVIEWS || - cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { + !vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { VMW_DEBUG_USER("Invalid shader binding.\n"); return -EINVAL; } @@ -2206,8 +2211,7 @@ cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || - cmd->body.type < SVGA3D_SHADERTYPE_MIN) { + if (!vmw_shadertype_is_valid(dev_priv->sm_type, cmd->body.type)) { VMW_DEBUG_USER("Illegal shader type %u.\n", (unsigned int) cmd->body.type); return -EINVAL; @@ -2439,6 +2443,8 @@ return ret; res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->defined_id); if (unlikely(ret != 0)) return ret; @@ -2524,6 +2530,8 @@ so_type = vmw_so_cmd_to_type(header->id); res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; cmd = container_of(header, typeof(*cmd), header); ret = vmw_cotable_notify(res, cmd->defined_id); @@ -2643,6 +2651,8 @@ return -EINVAL; res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER); + if (IS_ERR_OR_NULL(res)) + return res ? PTR_ERR(res) : -EINVAL; ret = vmw_cotable_notify(res, cmd->body.shaderId); if (ret) return ret; @@ -3413,17 +3423,17 @@ * Also if copying fails, user-space will be unable to signal the fence object * so we wait for it immediately, and then unreference the user-space reference. */ -void +int vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv, struct vmw_fpriv *vmw_fp, int ret, struct drm_vmw_fence_rep __user *user_fence_rep, struct vmw_fence_obj *fence, uint32_t fence_handle, - int32_t out_fence_fd, struct sync_file *sync_file) + int32_t out_fence_fd) { struct drm_vmw_fence_rep fence_rep; if (user_fence_rep == NULL) - return; + return 0; memset(&fence_rep, 0, sizeof(fence_rep)); @@ -3451,20 +3461,14 @@ * handle. */ if (unlikely(ret != 0) && (fence_rep.error == 0)) { - if (sync_file) - fput(sync_file->file); - - if (fence_rep.fd != -1) { - put_unused_fd(fence_rep.fd); - fence_rep.fd = -1; - } - ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle, TTM_REF_USAGE); VMW_DEBUG_USER("Fence copy error. Syncing.\n"); (void) vmw_fence_obj_wait(fence, false, false, VMW_FENCE_WAIT_TIMEOUT); } + + return ret ? -EFAULT : 0; } /** @@ -3806,16 +3810,23 @@ (void) vmw_fence_obj_wait(fence, false, false, VMW_FENCE_WAIT_TIMEOUT); + } + } + + ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, + user_fence_rep, fence, handle, out_fence_fd); + + if (sync_file) { + if (ret) { + /* usercopy of fence failed, put the file object */ + fput(sync_file->file); + put_unused_fd(out_fence_fd); } else { /* Link the fence with the FD created earlier */ fd_install(out_fence_fd, sync_file->file); } } - vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, - user_fence_rep, fence, handle, out_fence_fd, - sync_file); - /* Don't unreference when handing fence out */ if (unlikely(out_fence != NULL)) { *out_fence = fence; @@ -3833,7 +3844,7 @@ */ vmw_validation_unref_lists(&val_ctx); - return 0; + return ret; out_unlock_binding: mutex_unlock(&dev_priv->binding_mutex); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -498,7 +498,7 @@ static int vmw_fb_kms_framebuffer(struct fb_info *info) { - struct drm_mode_fb_cmd2 mode_cmd; + struct drm_mode_fb_cmd2 mode_cmd = {0}; struct vmw_fb_par *par = info->par; struct fb_var_screeninfo *var = &info->var; struct drm_framebuffer *cur_fb; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -32,7 +32,6 @@ #define VMW_FENCE_WRAP (1 << 31) struct vmw_fence_manager { - int num_fence_objects; struct vmw_private *dev_priv; spinlock_t lock; struct list_head fence_list; @@ -113,13 +112,13 @@ { struct vmw_fence_obj *fence = container_of(f, struct vmw_fence_obj, base); - struct vmw_fence_manager *fman = fman_from_fence(fence); - spin_lock(&fman->lock); - list_del_init(&fence->head); - --fman->num_fence_objects; - spin_unlock(&fman->lock); + if (!list_empty(&fence->head)) { + spin_lock(&fman->lock); + list_del_init(&fence->head); + spin_unlock(&fman->lock); + } fence->destroy(fence); } @@ -353,7 +352,6 @@ goto out_unlock; } list_add_tail(&fence->head, &fman->fence_list); - ++fman->num_fence_objects; out_unlock: spin_unlock(&fman->lock); @@ -402,7 +400,7 @@ { u32 goal_seqno; u32 *fifo_mem; - struct vmw_fence_obj *fence; + struct vmw_fence_obj *fence, *next_fence; if (likely(!fman->seqno_valid)) return false; @@ -413,7 +411,7 @@ return false; fman->seqno_valid = false; - list_for_each_entry(fence, &fman->fence_list, head) { + list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) { if (!list_empty(&fence->seq_passed_actions)) { fman->seqno_valid = true; vmw_mmio_write(fence->base.seqno, @@ -1066,7 +1064,7 @@ } event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; - event->event.base.length = sizeof(*event); + event->event.base.length = sizeof(event->event); event->event.user_data = user_data; ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base); @@ -1171,7 +1169,7 @@ } vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, - handle, -1, NULL); + handle, -1); vmw_fence_obj_unreference(&fence); return 0; out_no_create: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -114,10 +114,10 @@ (dev_priv->active_display_unit == vmw_du_screen_target); break; case DRM_VMW_PARAM_DX: - param->value = dev_priv->has_dx; + param->value = has_sm4_context(dev_priv); break; case DRM_VMW_PARAM_SM4_1: - param->value = dev_priv->has_sm4_1; + param->value = has_sm4_1_context(dev_priv); break; default: return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -182,7 +182,8 @@ if (cmd->dma.guest.ptr.offset % PAGE_SIZE || box->x != 0 || box->y != 0 || box->z != 0 || box->srcx != 0 || box->srcy != 0 || box->srcz != 0 || - box->d != 1 || box_count != 1) { + box->d != 1 || box_count != 1 || + box->w > 64 || box->h > 64) { /* TODO handle none page aligned offsets */ /* TODO handle more dst & src != 0 */ /* TODO handle more then one copy */ @@ -941,7 +942,7 @@ * For DX, surface format validation is done when surface->scanout * is set. */ - if (!dev_priv->has_dx && format != surface->format) { + if (!has_sm4_context(dev_priv) && format != surface->format) { DRM_ERROR("Invalid surface format for requested mode.\n"); return -EINVAL; } @@ -1409,6 +1410,7 @@ DRM_ERROR("Surface size cannot exceed %dx%d", dev_priv->texture_max_width, dev_priv->texture_max_height); + ret = -EINVAL; goto err_out; } @@ -2570,7 +2572,7 @@ if (file_priv) vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, user_fence_rep, fence, - handle, -1, NULL); + handle, -1); if (out_fence) *out_fence = fence; else @@ -2666,7 +2668,7 @@ ++i; } - if (i != unit) { + if (&con->head == &dev_priv->dev->mode_config.connector_list) { DRM_ERROR("Could not find initial display unit.\n"); ret = -EINVAL; goto out_unlock; @@ -2690,13 +2692,13 @@ break; } - if (mode->type & DRM_MODE_TYPE_PREFERRED) - *p_mode = mode; - else { + if (&mode->head == &con->modes) { WARN_ONCE(true, "Could not find initial preferred mode.\n"); *p_mode = list_first_entry(&con->modes, struct drm_display_mode, head); + } else { + *p_mode = mode; } out_unlock: --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -81,7 +81,7 @@ struct vmw_legacy_display_unit *entry; struct drm_framebuffer *fb = NULL; struct drm_crtc *crtc = NULL; - int i = 0; + int i; /* If there is no display topology the host just assumes * that the guest will set the same layout as the host. @@ -92,12 +92,11 @@ crtc = &entry->base.crtc; w = max(w, crtc->x + crtc->mode.hdisplay); h = max(h, crtc->y + crtc->mode.vdisplay); - i++; } if (crtc == NULL) return 0; - fb = entry->base.crtc.primary->state->fb; + fb = crtc->primary->state->fb; return vmw_kms_write_svga(dev_priv, w, h, fb->pitches[0], fb->format->cpp[0] * 8, --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -320,7 +320,7 @@ struct vmw_otable **otables = &dev_priv->otable_batch.otables; int ret; - if (dev_priv->has_dx) { + if (has_sm4_context(dev_priv)) { *otables = kmemdup(dx_tables, sizeof(dx_tables), GFP_KERNEL); if (!(*otables)) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -98,7 +98,7 @@ { struct vmw_escape_video_flush *flush; size_t fifo_size; - bool have_so = (dev_priv->active_display_unit == vmw_du_screen_object); + bool have_so = (dev_priv->active_display_unit != vmw_du_legacy); int i, num_items; SVGAGuestPtr ptr; --- linux-oracle-5.4.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ linux-oracle-5.4.0/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1059,12 +1059,12 @@ goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V3; cmd_len = sizeof(cmd3->body); submit_len = sizeof(*cmd3); } else if (srf->array_size > 0) { - /* has_dx checked on creation time. */ + /* VMW_SM_4 support verified at creation time. */ cmd_id = SVGA_3D_CMD_DEFINE_GB_SURFACE_V2; cmd_len = sizeof(cmd2->body); submit_len = sizeof(*cmd2); @@ -1082,7 +1082,7 @@ goto out_no_fifo; } - if (dev_priv->has_sm4_1 && srf->array_size > 0) { + if (has_sm4_1_context(dev_priv) && srf->array_size > 0) { cmd3->header.id = cmd_id; cmd3->header.size = cmd_len; cmd3->body.sid = srf->res.id; @@ -1404,7 +1404,7 @@ } /* array_size must be null for non-GL3 host. */ - if (array_size > 0 && !dev_priv->has_dx) { + if (array_size > 0 && !has_sm4_context(dev_priv)) { VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n"); return -EINVAL; } @@ -1562,7 +1562,7 @@ SVGA3D_FLAGS_64(req->svga3d_flags_upper_32_bits, req->base.svga3d_flags); - if (!dev_priv->has_sm4_1) { + if (!has_sm4_1_context(dev_priv)) { /* * If SM4_1 is not support then cannot send 64-bit flag to * device. --- linux-oracle-5.4.0.orig/drivers/gpu/drm/xen/xen_drm_front.c +++ linux-oracle-5.4.0/drivers/gpu/drm/xen/xen_drm_front.c @@ -400,7 +400,7 @@ args->size = args->pitch * args->height; obj = xen_drm_front_gem_create(dev, args->size); - if (IS_ERR_OR_NULL(obj)) { + if (IS_ERR(obj)) { ret = PTR_ERR(obj); goto fail; } --- linux-oracle-5.4.0.orig/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ linux-oracle-5.4.0/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -83,7 +83,7 @@ size = round_up(size, PAGE_SIZE); xen_obj = gem_create_obj(dev, size); - if (IS_ERR_OR_NULL(xen_obj)) + if (IS_ERR(xen_obj)) return xen_obj; if (drm_info->front_info->cfg.be_alloc) { @@ -117,7 +117,7 @@ */ xen_obj->num_pages = DIV_ROUND_UP(size, PAGE_SIZE); xen_obj->pages = drm_gem_get_pages(&xen_obj->base); - if (IS_ERR_OR_NULL(xen_obj->pages)) { + if (IS_ERR(xen_obj->pages)) { ret = PTR_ERR(xen_obj->pages); xen_obj->pages = NULL; goto fail; @@ -136,7 +136,7 @@ struct xen_gem_object *xen_obj; xen_obj = gem_create(dev, size); - if (IS_ERR_OR_NULL(xen_obj)) + if (IS_ERR(xen_obj)) return ERR_CAST(xen_obj); return &xen_obj->base; @@ -194,7 +194,7 @@ size = attach->dmabuf->size; xen_obj = gem_create_obj(dev, size); - if (IS_ERR_OR_NULL(xen_obj)) + if (IS_ERR(xen_obj)) return ERR_CAST(xen_obj); ret = gem_alloc_pages_array(xen_obj, size); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/xen/xen_drm_front_kms.c +++ linux-oracle-5.4.0/drivers/gpu/drm/xen/xen_drm_front_kms.c @@ -60,7 +60,7 @@ int ret; fb = drm_gem_fb_create_with_funcs(dev, filp, mode_cmd, &fb_funcs); - if (IS_ERR_OR_NULL(fb)) + if (IS_ERR(fb)) return fb; gem_obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); --- linux-oracle-5.4.0.orig/drivers/gpu/drm/zte/Kconfig +++ linux-oracle-5.4.0/drivers/gpu/drm/zte/Kconfig @@ -3,7 +3,6 @@ tristate "DRM Support for ZTE SoCs" depends on DRM && ARCH_ZX select DRM_KMS_CMA_HELPER - select DRM_KMS_FB_HELPER select DRM_KMS_HELPER select SND_SOC_HDMI_CODEC if SND_SOC select VIDEOMODE_HELPERS --- linux-oracle-5.4.0.orig/drivers/gpu/host1x/bus.c +++ linux-oracle-5.4.0/drivers/gpu/host1x/bus.c @@ -335,11 +335,6 @@ return 0; } -static int host1x_dma_configure(struct device *dev) -{ - return of_dma_configure(dev, dev->of_node, true); -} - static const struct dev_pm_ops host1x_device_pm_ops = { .suspend = pm_generic_suspend, .resume = pm_generic_resume, @@ -353,7 +348,6 @@ .name = "host1x", .match = host1x_device_match, .uevent = host1x_device_uevent, - .dma_configure = host1x_dma_configure, .pm = &host1x_device_pm_ops, }; @@ -442,8 +436,6 @@ device->dev.bus = &host1x_bus_type; device->dev.parent = host1x->dev; - of_dma_configure(&device->dev, host1x->dev->of_node, true); - device->dev.dma_parms = &device->dma_parms; dma_set_max_seg_size(&device->dev, SZ_4M); @@ -686,8 +678,17 @@ */ void host1x_driver_unregister(struct host1x_driver *driver) { + struct host1x *host1x; + driver_unregister(&driver->driver); + mutex_lock(&devices_lock); + + list_for_each_entry(host1x, &devices, list) + host1x_detach_driver(host1x, driver); + + mutex_unlock(&devices_lock); + mutex_lock(&drivers_lock); list_del_init(&driver->list); mutex_unlock(&drivers_lock); --- linux-oracle-5.4.0.orig/drivers/gpu/host1x/debug.c +++ linux-oracle-5.4.0/drivers/gpu/host1x/debug.c @@ -16,6 +16,8 @@ #include "debug.h" #include "channel.h" +static DEFINE_MUTEX(debug_lock); + unsigned int host1x_debug_trace_cmdbuf; static pid_t host1x_debug_force_timeout_pid; @@ -52,12 +54,14 @@ struct output *o = data; mutex_lock(&ch->cdma.lock); + mutex_lock(&debug_lock); if (show_fifo) host1x_hw_show_channel_fifo(m, ch, o); host1x_hw_show_channel_cdma(m, ch, o); + mutex_unlock(&debug_lock); mutex_unlock(&ch->cdma.lock); return 0; --- linux-oracle-5.4.0.orig/drivers/gpu/host1x/hw/syncpt_hw.c +++ linux-oracle-5.4.0/drivers/gpu/host1x/hw/syncpt_hw.c @@ -106,9 +106,6 @@ #if HOST1X_HW >= 6 struct host1x *host = sp->host; - if (!host->hv_regs) - return; - host1x_sync_writel(host, HOST1X_SYNC_SYNCPT_CH_APP_CH(ch ? ch->id : 0xff), HOST1X_SYNC_SYNCPT_CH_APP(sp->id)); --- linux-oracle-5.4.0.orig/drivers/gpu/host1x/job.c +++ linux-oracle-5.4.0/drivers/gpu/host1x/job.c @@ -436,7 +436,8 @@ return err; } -static inline int copy_gathers(struct host1x_job *job, struct device *dev) +static inline int copy_gathers(struct device *host, struct host1x_job *job, + struct device *dev) { struct host1x_firewall fw; size_t size = 0; @@ -459,12 +460,12 @@ * Try a non-blocking allocation from a higher priority pools first, * as awaiting for the allocation here is a major performance hit. */ - job->gather_copy_mapped = dma_alloc_wc(dev, size, &job->gather_copy, + job->gather_copy_mapped = dma_alloc_wc(host, size, &job->gather_copy, GFP_NOWAIT); /* the higher priority allocation failed, try the generic-blocking */ if (!job->gather_copy_mapped) - job->gather_copy_mapped = dma_alloc_wc(dev, size, + job->gather_copy_mapped = dma_alloc_wc(host, size, &job->gather_copy, GFP_KERNEL); if (!job->gather_copy_mapped) @@ -512,7 +513,7 @@ goto out; if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) { - err = copy_gathers(job, dev); + err = copy_gathers(host->dev, job, dev); if (err) goto out; } @@ -573,7 +574,7 @@ job->num_unpins = 0; if (job->gather_copy_size) - dma_free_wc(job->channel->dev, job->gather_copy_size, + dma_free_wc(host->dev, job->gather_copy_size, job->gather_copy_mapped, job->gather_copy); } EXPORT_SYMBOL(host1x_job_unpin); --- linux-oracle-5.4.0.orig/drivers/gpu/host1x/mipi.c +++ linux-oracle-5.4.0/drivers/gpu/host1x/mipi.c @@ -206,9 +206,9 @@ return 0; } -struct tegra_mipi_device *tegra_mipi_request(struct device *device) +struct tegra_mipi_device *tegra_mipi_request(struct device *device, + struct device_node *np) { - struct device_node *np = device->of_node; struct tegra_mipi_device *dev; struct of_phandle_args args; int err; --- linux-oracle-5.4.0.orig/drivers/gpu/ipu-v3/ipu-common.c +++ linux-oracle-5.4.0/drivers/gpu/ipu-v3/ipu-common.c @@ -124,6 +124,8 @@ case V4L2_PIX_FMT_RGBX32: case V4L2_PIX_FMT_ARGB32: case V4L2_PIX_FMT_XRGB32: + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: return IPUV3_COLORSPACE_RGB; default: return IPUV3_COLORSPACE_UNKNOWN; @@ -1233,6 +1235,7 @@ pdev = platform_device_alloc(reg->name, id++); if (!pdev) { ret = -ENOMEM; + of_node_put(of_node); goto err_register; } --- linux-oracle-5.4.0.orig/drivers/gpu/ipu-v3/ipu-cpmem.c +++ linux-oracle-5.4.0/drivers/gpu/ipu-v3/ipu-cpmem.c @@ -585,21 +585,21 @@ .bits_per_pixel = 16, }; -#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) -#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * ((y) / 2) / 2) + (x) / 2) -#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * pix->height / 4) + \ - (pix->width * ((y) / 2) / 2) + (x) / 2) -#define U2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * (y) / 2) + (x) / 2) -#define V2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * pix->height / 2) + \ - (pix->width * (y) / 2) + (x) / 2) -#define UV_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * ((y) / 2)) + (x)) -#define UV2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * y) + (x)) +#define Y_OFFSET(pix, x, y) ((x) + pix->bytesperline * (y)) +#define U_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) +#define V_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * pix->height / 4) + \ + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) +#define U2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * (y) / 2) + (x) / 2) +#define V2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * pix->height / 2) + \ + (pix->bytesperline * (y) / 2) + (x) / 2) +#define UV_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * ((y) / 2)) + (x)) +#define UV2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * y) + (x)) #define NUM_ALPHA_CHANNELS 7 --- linux-oracle-5.4.0.orig/drivers/gpu/ipu-v3/ipu-di.c +++ linux-oracle-5.4.0/drivers/gpu/ipu-v3/ipu-di.c @@ -451,8 +451,9 @@ error = rate / (sig->mode.pixelclock / 1000); - dev_dbg(di->ipu->dev, " IPU clock can give %lu with divider %u, error %d.%u%%\n", - rate, div, (signed)(error - 1000) / 10, error % 10); + dev_dbg(di->ipu->dev, " IPU clock can give %lu with divider %u, error %c%d.%d%%\n", + rate, div, error < 1000 ? '-' : '+', + abs(error - 1000) / 10, abs(error - 1000) % 10); /* Allow a 1% error */ if (error < 1010 && error >= 990) { --- linux-oracle-5.4.0.orig/drivers/gpu/ipu-v3/ipu-image-convert.c +++ linux-oracle-5.4.0/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -137,6 +137,17 @@ struct ipu_image_convert_chan; struct ipu_image_convert_priv; +enum eof_irq_mask { + EOF_IRQ_IN = BIT(0), + EOF_IRQ_ROT_IN = BIT(1), + EOF_IRQ_OUT = BIT(2), + EOF_IRQ_ROT_OUT = BIT(3), +}; + +#define EOF_IRQ_COMPLETE (EOF_IRQ_IN | EOF_IRQ_OUT) +#define EOF_IRQ_ROT_COMPLETE (EOF_IRQ_IN | EOF_IRQ_OUT | \ + EOF_IRQ_ROT_IN | EOF_IRQ_ROT_OUT) + struct ipu_image_convert_ctx { struct ipu_image_convert_chan *chan; @@ -173,6 +184,9 @@ /* where to place converted tile in dest image */ unsigned int out_tile_map[MAX_TILES]; + /* mask of completed EOF irqs at every tile conversion */ + enum eof_irq_mask eof_mask; + struct list_head list; }; @@ -189,6 +203,8 @@ struct ipuv3_channel *rotation_out_chan; /* the IPU end-of-frame irqs */ + int in_eof_irq; + int rot_in_eof_irq; int out_eof_irq; int rot_out_eof_irq; @@ -1380,6 +1396,9 @@ dev_dbg(priv->ipu->dev, "%s: task %u: starting ctx %p run %p tile %u -> %u\n", __func__, chan->ic_task, ctx, run, tile, dst_tile); + /* clear EOF irq mask */ + ctx->eof_mask = 0; + if (ipu_rot_mode_is_irt(ctx->rot_mode)) { /* swap width/height for resizer */ dest_width = d_image->tile[dst_tile].height; @@ -1615,7 +1634,7 @@ } /* hold irqlock when calling */ -static irqreturn_t do_irq(struct ipu_image_convert_run *run) +static irqreturn_t do_tile_complete(struct ipu_image_convert_run *run) { struct ipu_image_convert_ctx *ctx = run->ctx; struct ipu_image_convert_chan *chan = ctx->chan; @@ -1700,6 +1719,7 @@ ctx->cur_buf_num ^= 1; } + ctx->eof_mask = 0; /* clear EOF irq mask for next tile */ ctx->next_tile++; return IRQ_HANDLED; done: @@ -1709,13 +1729,15 @@ return IRQ_WAKE_THREAD; } -static irqreturn_t norotate_irq(int irq, void *data) +static irqreturn_t eof_irq(int irq, void *data) { struct ipu_image_convert_chan *chan = data; + struct ipu_image_convert_priv *priv = chan->priv; struct ipu_image_convert_ctx *ctx; struct ipu_image_convert_run *run; + irqreturn_t ret = IRQ_HANDLED; + bool tile_complete = false; unsigned long flags; - irqreturn_t ret; spin_lock_irqsave(&chan->irqlock, flags); @@ -1728,46 +1750,33 @@ ctx = run->ctx; - if (ipu_rot_mode_is_irt(ctx->rot_mode)) { - /* this is a rotation operation, just ignore */ - spin_unlock_irqrestore(&chan->irqlock, flags); - return IRQ_HANDLED; - } - - ret = do_irq(run); -out: - spin_unlock_irqrestore(&chan->irqlock, flags); - return ret; -} - -static irqreturn_t rotate_irq(int irq, void *data) -{ - struct ipu_image_convert_chan *chan = data; - struct ipu_image_convert_priv *priv = chan->priv; - struct ipu_image_convert_ctx *ctx; - struct ipu_image_convert_run *run; - unsigned long flags; - irqreturn_t ret; - - spin_lock_irqsave(&chan->irqlock, flags); - - /* get current run and its context */ - run = chan->current_run; - if (!run) { + if (irq == chan->in_eof_irq) { + ctx->eof_mask |= EOF_IRQ_IN; + } else if (irq == chan->out_eof_irq) { + ctx->eof_mask |= EOF_IRQ_OUT; + } else if (irq == chan->rot_in_eof_irq || + irq == chan->rot_out_eof_irq) { + if (!ipu_rot_mode_is_irt(ctx->rot_mode)) { + /* this was NOT a rotation op, shouldn't happen */ + dev_err(priv->ipu->dev, + "Unexpected rotation interrupt\n"); + goto out; + } + ctx->eof_mask |= (irq == chan->rot_in_eof_irq) ? + EOF_IRQ_ROT_IN : EOF_IRQ_ROT_OUT; + } else { + dev_err(priv->ipu->dev, "Received unknown irq %d\n", irq); ret = IRQ_NONE; goto out; } - ctx = run->ctx; - - if (!ipu_rot_mode_is_irt(ctx->rot_mode)) { - /* this was NOT a rotation operation, shouldn't happen */ - dev_err(priv->ipu->dev, "Unexpected rotation interrupt\n"); - spin_unlock_irqrestore(&chan->irqlock, flags); - return IRQ_HANDLED; - } + if (ipu_rot_mode_is_irt(ctx->rot_mode)) + tile_complete = (ctx->eof_mask == EOF_IRQ_ROT_COMPLETE); + else + tile_complete = (ctx->eof_mask == EOF_IRQ_COMPLETE); - ret = do_irq(run); + if (tile_complete) + ret = do_tile_complete(run); out: spin_unlock_irqrestore(&chan->irqlock, flags); return ret; @@ -1801,6 +1810,10 @@ static void release_ipu_resources(struct ipu_image_convert_chan *chan) { + if (chan->in_eof_irq >= 0) + free_irq(chan->in_eof_irq, chan); + if (chan->rot_in_eof_irq >= 0) + free_irq(chan->rot_in_eof_irq, chan); if (chan->out_eof_irq >= 0) free_irq(chan->out_eof_irq, chan); if (chan->rot_out_eof_irq >= 0) @@ -1819,7 +1832,27 @@ chan->in_chan = chan->out_chan = chan->rotation_in_chan = chan->rotation_out_chan = NULL; - chan->out_eof_irq = chan->rot_out_eof_irq = -1; + chan->in_eof_irq = -1; + chan->rot_in_eof_irq = -1; + chan->out_eof_irq = -1; + chan->rot_out_eof_irq = -1; +} + +static int get_eof_irq(struct ipu_image_convert_chan *chan, + struct ipuv3_channel *channel) +{ + struct ipu_image_convert_priv *priv = chan->priv; + int ret, irq; + + irq = ipu_idmac_channel_irq(priv->ipu, channel, IPU_IRQ_EOF); + + ret = request_threaded_irq(irq, eof_irq, do_bh, 0, "ipu-ic", chan); + if (ret < 0) { + dev_err(priv->ipu->dev, "could not acquire irq %d\n", irq); + return ret; + } + + return irq; } static int get_ipu_resources(struct ipu_image_convert_chan *chan) @@ -1855,31 +1888,33 @@ } /* acquire the EOF interrupts */ - chan->out_eof_irq = ipu_idmac_channel_irq(priv->ipu, - chan->out_chan, - IPU_IRQ_EOF); + ret = get_eof_irq(chan, chan->in_chan); + if (ret < 0) { + chan->in_eof_irq = -1; + goto err; + } + chan->in_eof_irq = ret; - ret = request_threaded_irq(chan->out_eof_irq, norotate_irq, do_bh, - 0, "ipu-ic", chan); + ret = get_eof_irq(chan, chan->rotation_in_chan); if (ret < 0) { - dev_err(priv->ipu->dev, "could not acquire irq %d\n", - chan->out_eof_irq); - chan->out_eof_irq = -1; + chan->rot_in_eof_irq = -1; goto err; } + chan->rot_in_eof_irq = ret; - chan->rot_out_eof_irq = ipu_idmac_channel_irq(priv->ipu, - chan->rotation_out_chan, - IPU_IRQ_EOF); + ret = get_eof_irq(chan, chan->out_chan); + if (ret < 0) { + chan->out_eof_irq = -1; + goto err; + } + chan->out_eof_irq = ret; - ret = request_threaded_irq(chan->rot_out_eof_irq, rotate_irq, do_bh, - 0, "ipu-ic", chan); + ret = get_eof_irq(chan, chan->rotation_out_chan); if (ret < 0) { - dev_err(priv->ipu->dev, "could not acquire irq %d\n", - chan->rot_out_eof_irq); chan->rot_out_eof_irq = -1; goto err; } + chan->rot_out_eof_irq = ret; return 0; err: @@ -2458,6 +2493,8 @@ chan->ic_task = i; chan->priv = priv; chan->dma_ch = &image_convert_dma_chan[i]; + chan->in_eof_irq = -1; + chan->rot_in_eof_irq = -1; chan->out_eof_irq = -1; chan->rot_out_eof_irq = -1; --- linux-oracle-5.4.0.orig/drivers/greybus/interface.c +++ linux-oracle-5.4.0/drivers/greybus/interface.c @@ -694,6 +694,7 @@ trace_gb_interface_release(intf); + cancel_work_sync(&intf->mode_switch_work); kfree(intf); } --- linux-oracle-5.4.0.orig/drivers/greybus/svc.c +++ linux-oracle-5.4.0/drivers/greybus/svc.c @@ -866,8 +866,14 @@ gb_svc_debugfs_init(svc); - return gb_svc_queue_deferred_request(op); + ret = gb_svc_queue_deferred_request(op); + if (ret) + goto err_remove_debugfs; + return 0; + +err_remove_debugfs: + gb_svc_debugfs_exit(svc); err_unregister_device: gb_svc_watchdog_destroy(svc); device_del(&svc->dev); --- linux-oracle-5.4.0.orig/drivers/hid/Kconfig +++ linux-oracle-5.4.0/drivers/hid/Kconfig @@ -149,6 +149,7 @@ config HID_ASUS tristate "Asus" + depends on USB_HID depends on LEDS_CLASS depends on ASUS_WMI || ASUS_WMI=n select POWER_SUPPLY @@ -206,14 +207,14 @@ config HID_CHICONY tristate "Chicony devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Chicony Tactical pad and special keys on Chicony keyboards. config HID_CORSAIR tristate "Corsair devices" - depends on HID && USB && LEDS_CLASS + depends on USB_HID && LEDS_CLASS ---help--- Support for Corsair devices that are not fully compliant with the HID standard. @@ -244,7 +245,7 @@ config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" - depends on HID && SND + depends on USB_HID && SND select SND_RAWMIDI ---help--- Support for Prodikeys PC-MIDI Keyboard device support. @@ -524,7 +525,7 @@ config HID_LOGITECH tristate "Logitech devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -871,7 +872,7 @@ config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" - depends on HID + depends on USB_HID ---help--- Support for Samsung InfraRed remote control or keyboards. --- linux-oracle-5.4.0.orig/drivers/hid/hid-alps.c +++ linux-oracle-5.4.0/drivers/hid/hid-alps.c @@ -25,6 +25,7 @@ #define U1_MOUSE_REPORT_ID 0x01 /* Mouse data ReportID */ #define U1_ABSOLUTE_REPORT_ID 0x03 /* Absolute data ReportID */ +#define U1_ABSOLUTE_REPORT_ID_SECD 0x02 /* FW-PTP Absolute data ReportID */ #define U1_FEATURE_REPORT_ID 0x05 /* Feature ReportID */ #define U1_SP_ABSOLUTE_REPORT_ID 0x06 /* Feature ReportID */ @@ -368,6 +369,7 @@ case U1_FEATURE_REPORT_ID: break; case U1_ABSOLUTE_REPORT_ID: + case U1_ABSOLUTE_REPORT_ID_SECD: for (i = 0; i < hdata->max_fingers; i++) { u8 *contact = &data[i * 5]; @@ -730,7 +732,7 @@ if (data->has_sp) { input2 = input_allocate_device(); if (!input2) { - input_free_device(input2); + ret = -ENOMEM; goto exit; } @@ -760,6 +762,7 @@ if (input_register_device(data->input2)) { input_free_device(input2); + ret = -ENOENT; goto exit; } } @@ -802,6 +805,7 @@ break; case HID_DEVICE_ID_ALPS_U1_DUAL: case HID_DEVICE_ID_ALPS_U1: + case HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY: data->dev_type = U1; break; default: @@ -828,6 +832,8 @@ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1) }, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, + USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_T4_BTNLESS) }, { } }; --- linux-oracle-5.4.0.orig/drivers/hid/hid-apple.c +++ linux-oracle-5.4.0/drivers/hid/hid-apple.c @@ -51,9 +51,16 @@ "(For people who want to keep Windows PC keyboard muscle memory. " "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); +static unsigned int swap_fn_leftctrl; +module_param(swap_fn_leftctrl, uint, 0644); +MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " + "(For people who want to keep PC keyboard muscle memory. " + "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); + struct apple_sc { unsigned long quirks; unsigned int fn_on; + unsigned int fn_found; DECLARE_BITMAP(pressed_numlock, KEY_CNT); }; @@ -63,6 +70,28 @@ u8 flags; }; +static const struct apple_key_translation apple2021_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_ENTER, KEY_INSERT }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_SEARCH, APPLE_FLAG_FKEY }, + { KEY_F5, KEY_MICMUTE, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_SLEEP, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; + static const struct apple_key_translation macbookair_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, @@ -162,6 +191,11 @@ { } }; +static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { + { KEY_FN, KEY_LEFTCTRL }, + { } +}; + static const struct apple_key_translation *apple_find_translation( const struct apple_key_translation *table, u16 from) { @@ -183,14 +217,18 @@ bool do_translate; u16 code = 0; - if (usage->code == KEY_FN) { + u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); + + if (usage->code == fn_keycode) { asc->fn_on = !!value; - input_event(input, usage->type, usage->code, value); + input_event(input, usage->type, KEY_FN, value); return 1; } if (fnmode) { - if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + if (hid->product == USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) + table = apple2021_fn_keys; + else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) table = macbookair_fn_keys; else if (hid->product < 0x21d || hid->product >= 0x300) @@ -270,6 +308,14 @@ } } + if (swap_fn_leftctrl) { + trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + return 0; } @@ -300,12 +346,19 @@ /* * MacBook JIS keyboard has wrong logical maximum + * Magic Keyboard JIS has wrong logical maximum */ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { struct apple_sc *asc = hid_get_drvdata(hdev); + if(*rsize >=71 && rdesc[70] == 0x65 && rdesc[64] == 0x65) { + hid_info(hdev, + "fixing up Magic Keyboard JIS report descriptor\n"); + rdesc[64] = rdesc[70] = 0xe7; + } + if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && rdesc[53] == 0x65 && rdesc[59] == 0x65) { hid_info(hdev, @@ -333,17 +386,29 @@ for (trans = apple_iso_keyboard; trans->from; trans++) set_bit(trans->to, input->keybit); + + for (trans = apple2021_fn_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + + if (swap_fn_leftctrl) { + for (trans = swapped_fn_leftctrl_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + } } static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { + struct apple_sc *asc = hid_get_drvdata(hdev); + if (usage->hid == (HID_UP_CUSTOM | 0x0003) || - usage->hid == (HID_UP_MSVENDOR | 0x0003)) { + usage->hid == (HID_UP_MSVENDOR | 0x0003) || + usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { /* The fn key on Apple USB keyboards */ set_bit(EV_REP, hi->input->evbit); hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); + asc->fn_found = true; apple_setup_input(hi->input); return 1; } @@ -370,6 +435,19 @@ return 0; } +static int apple_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + struct apple_sc *asc = hid_get_drvdata(hdev); + + if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { + hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n"); + asc->quirks &= ~APPLE_HAS_FN; + } + + return 0; +} + static int apple_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -571,6 +649,10 @@ .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021), + .driver_data = APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021), + .driver_data = APPLE_HAS_FN }, { } }; @@ -584,6 +666,7 @@ .event = apple_event, .input_mapping = apple_input_mapping, .input_mapped = apple_input_mapped, + .input_configured = apple_input_configured, }; module_hid_driver(apple_driver); --- linux-oracle-5.4.0.orig/drivers/hid/hid-appleir.c +++ linux-oracle-5.4.0/drivers/hid/hid-appleir.c @@ -188,7 +188,7 @@ static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 }; unsigned long flags; - if (len != 5) + if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT)) goto out; if (!memcmp(data, keydown, sizeof(keydown))) { --- linux-oracle-5.4.0.orig/drivers/hid/hid-asus.c +++ linux-oracle-5.4.0/drivers/hid/hid-asus.c @@ -40,7 +40,9 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define T100_TPAD_INTF 2 +#define MEDION_E1239T_TPAD_INTF 1 +#define E1239T_TP_TOGGLE_REPORT_ID 0x05 #define T100CHI_MOUSE_REPORT_ID 0x06 #define FEATURE_REPORT_ID 0x0d #define INPUT_REPORT_ID 0x5d @@ -77,6 +79,7 @@ #define QUIRK_G752_KEYBOARD BIT(8) #define QUIRK_T101HA_DOCK BIT(9) #define QUIRK_T90CHI BIT(10) +#define QUIRK_MEDION_E1239T BIT(11) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -92,6 +95,7 @@ struct hid_device *hdev; struct work_struct work; unsigned int brightness; + spinlock_t lock; bool removed; }; @@ -102,12 +106,14 @@ int res_y; int contact_size; int max_contacts; + int report_size; }; struct asus_drvdata { unsigned long quirks; struct hid_device *hdev; struct input_dev *input; + struct input_dev *tp_kbd_input; struct asus_kbd_leds *kbd_backlight; const struct asus_touchpad_info *tp; bool enable_backlight; @@ -126,6 +132,7 @@ .max_y = 1758, .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100ta_tp = { @@ -135,6 +142,7 @@ .res_y = 27, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100ha_tp = { @@ -144,6 +152,7 @@ .res_y = 29, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t200ta_tp = { @@ -153,6 +162,7 @@ .res_y = 28, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100chi_tp = { @@ -162,6 +172,17 @@ .res_y = 29, /* units/mm */ .contact_size = 3, .max_contacts = 4, + .report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */, +}; + +static const struct asus_touchpad_info medion_e1239t_tp = { + .max_x = 2640, + .max_y = 1380, + .res_x = 29, /* units/mm */ + .res_y = 28, /* units/mm */ + .contact_size = 5, + .max_contacts = 5, + .report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */, }; static void asus_report_contact_down(struct asus_drvdata *drvdat, @@ -229,7 +250,7 @@ int i, toolType = MT_TOOL_FINGER; u8 *contactData = data + 2; - if (size != 3 + drvdat->tp->contact_size * drvdat->tp->max_contacts) + if (size != drvdat->tp->report_size) return 0; for (i = 0; i < drvdat->tp->max_contacts; i++) { @@ -257,11 +278,40 @@ return 1; } +static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size) +{ + if (size != 3) + return 0; + + /* Handle broken mute key which only sends press events */ + if (!drvdat->tp && + data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) { + input_report_key(drvdat->input, KEY_MUTE, 1); + input_sync(drvdat->input); + input_report_key(drvdat->input, KEY_MUTE, 0); + input_sync(drvdat->input); + return 1; + } + + /* Handle custom touchpad toggle key which only sends press events */ + if (drvdat->tp_kbd_input && + data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) { + input_report_key(drvdat->tp_kbd_input, KEY_F21, 1); + input_sync(drvdat->tp_kbd_input); + input_report_key(drvdat->tp_kbd_input, KEY_F21, 0); + input_sync(drvdat->tp_kbd_input); + return 1; + } + + return 0; +} + static int asus_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { if ((usage->hid & HID_USAGE_PAGE) == 0xff310000 && - (usage->hid & HID_USAGE) != 0x00 && !usage->type) { + (usage->hid & HID_USAGE) != 0x00 && + (usage->hid & HID_USAGE) != 0xff && !usage->type) { hid_warn(hdev, "Unmapped Asus vendor usagepage code 0x%02x\n", usage->hid & HID_USAGE); } @@ -280,10 +330,13 @@ if (drvdata->tp && data[0] == INPUT_REPORT_ID) return asus_report_input(drvdata, data, size); + if (drvdata->quirks & QUIRK_MEDION_E1239T) + return asus_e1239t_event(drvdata, data, size); + return 0; } -static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) +static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) { unsigned char *dmabuf; int ret; @@ -302,7 +355,7 @@ static int asus_kbd_init(struct hid_device *hdev) { - u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; int ret; @@ -316,7 +369,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, unsigned char *kbd_func) { - u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; u8 *readbuf; int ret; @@ -345,24 +398,42 @@ return ret; } +static void asus_schedule_work(struct asus_kbd_leds *led) +{ + unsigned long flags; + + spin_lock_irqsave(&led->lock, flags); + if (!led->removed) + schedule_work(&led->work); + spin_unlock_irqrestore(&led->lock, flags); +} + static void asus_kbd_backlight_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, cdev); - if (led->brightness == brightness) - return; + unsigned long flags; + spin_lock_irqsave(&led->lock, flags); led->brightness = brightness; - schedule_work(&led->work); + spin_unlock_irqrestore(&led->lock, flags); + + asus_schedule_work(led); } static enum led_brightness asus_kbd_backlight_get(struct led_classdev *led_cdev) { struct asus_kbd_leds *led = container_of(led_cdev, struct asus_kbd_leds, cdev); + enum led_brightness brightness; + unsigned long flags; + + spin_lock_irqsave(&led->lock, flags); + brightness = led->brightness; + spin_unlock_irqrestore(&led->lock, flags); - return led->brightness; + return brightness; } static void asus_kbd_backlight_work(struct work_struct *work) @@ -370,11 +441,11 @@ struct asus_kbd_leds *led = container_of(work, struct asus_kbd_leds, work); u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, 0x00 }; int ret; + unsigned long flags; - if (led->removed) - return; - + spin_lock_irqsave(&led->lock, flags); buf[4] = led->brightness; + spin_unlock_irqrestore(&led->lock, flags); ret = asus_kbd_set_report(led->hdev, buf, sizeof(buf)); if (ret < 0) @@ -436,6 +507,7 @@ drvdata->kbd_backlight->cdev.brightness_set = asus_kbd_backlight_set; drvdata->kbd_backlight->cdev.brightness_get = asus_kbd_backlight_get; INIT_WORK(&drvdata->kbd_backlight->work, asus_kbd_backlight_work); + spin_lock_init(&drvdata->kbd_backlight->lock); ret = devm_led_classdev_register(&hdev->dev, &drvdata->kbd_backlight->cdev); if (ret < 0) { @@ -614,6 +686,21 @@ hi->report->id != T100CHI_MOUSE_REPORT_ID) return 0; + /* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */ + if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) { + switch (hi->report->id) { + case E1239T_TP_TOGGLE_REPORT_ID: + input_set_capability(input, EV_KEY, KEY_F21); + input->name = "Asus Touchpad Keys"; + drvdata->tp_kbd_input = input; + return 0; + case INPUT_REPORT_ID: + break; /* Touchpad report, handled below */ + default: + return 0; /* Ignore other reports */ + } + } + if (drvdata->tp) { int ret; @@ -693,7 +780,6 @@ /* ASUS-specific keyboard hotkeys */ if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) { - set_bit(EV_REP, hi->input->evbit); switch (usage->hid & HID_USAGE) { case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; @@ -736,11 +822,11 @@ if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) drvdata->enable_backlight = true; + set_bit(EV_REP, hi->input->evbit); return 1; } if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) { - set_bit(EV_REP, hi->input->evbit); switch (usage->hid & HID_USAGE) { case 0xff01: asus_map_key_clear(BTN_1); break; case 0xff02: asus_map_key_clear(BTN_2); break; @@ -763,6 +849,7 @@ return 0; } + set_bit(EV_REP, hi->input->evbit); return 1; } @@ -781,6 +868,16 @@ } } + /* + * The mute button is broken and only sends press events, we + * deal with this in our raw_event handler, so do not map it. + */ + if ((drvdata->quirks & QUIRK_MEDION_E1239T) && + usage->hid == (HID_UP_CONSUMER | 0xe2)) { + input_set_capability(hi->input, EV_KEY, KEY_MUTE); + return -1; + } + return 0; } @@ -811,6 +908,24 @@ return 0; } +static int __maybe_unused asus_resume(struct hid_device *hdev) { + struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + int ret = 0; + + if (drvdata->kbd_backlight) { + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, + drvdata->kbd_backlight->cdev.brightness }; + ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); + if (ret < 0) { + hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); + goto asus_resume_err; + } + } + +asus_resume_err: + return ret; +} + static int __maybe_unused asus_reset_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); @@ -848,7 +963,7 @@ if (drvdata->quirks & QUIRK_IS_MULTITOUCH) drvdata->tp = &asus_i2c_tp; - if (drvdata->quirks & QUIRK_T100_KEYBOARD) { + if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && hid_is_usb(hdev)) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) { @@ -876,6 +991,19 @@ drvdata->tp = &asus_t100chi_tp; } + if ((drvdata->quirks & QUIRK_MEDION_E1239T) && + hid_is_using_ll_driver(hdev, &usb_hid_driver)) { + struct usb_host_interface *alt = + to_usb_interface(hdev->dev.parent)->altsetting; + + if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) { + /* For separate input-devs for tp and tp toggle key */ + hdev->quirks |= HID_QUIRK_MULTI_INPUT; + drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING; + drvdata->tp = &medion_e1239t_tp; + } + } + if (drvdata->quirks & QUIRK_NO_INIT_REPORTS) hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; @@ -934,9 +1062,13 @@ static void asus_remove(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + unsigned long flags; if (drvdata->kbd_backlight) { + spin_lock_irqsave(&drvdata->kbd_backlight->lock, flags); drvdata->kbd_backlight->removed = true; + spin_unlock_irqrestore(&drvdata->kbd_backlight->lock, flags); + cancel_work_sync(&drvdata->kbd_backlight->work); } @@ -1055,7 +1187,8 @@ { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI }, - + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T), + QUIRK_MEDION_E1239T }, { } }; MODULE_DEVICE_TABLE(hid, asus_devices); @@ -1070,6 +1203,7 @@ .input_configured = asus_input_configured, #ifdef CONFIG_PM .reset_resume = asus_reset_resume, + .resume = asus_resume, #endif .event = asus_event, .raw_event = asus_raw_event --- linux-oracle-5.4.0.orig/drivers/hid/hid-betopff.c +++ linux-oracle-5.4.0/drivers/hid/hid-betopff.c @@ -56,15 +56,21 @@ { struct betopff_device *betopff; struct hid_report *report; - struct hid_input *hidinput = - list_first_entry(&hid->inputs, struct hid_input, list); + struct hid_input *hidinput; struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - struct input_dev *dev = hidinput->input; - int field_count = 0; + struct input_dev *dev; int error; int i, j; + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } + + hidinput = list_first_entry(&hid->inputs, struct hid_input, list); + dev = hidinput->input; + if (list_empty(report_list)) { hid_err(hid, "no output reports found\n"); return -ENODEV; @@ -79,19 +85,21 @@ * ----------------------------------------- * Do init them with default value. */ + if (report->maxfield < 4) { + hid_err(hid, "not enough fields in the report: %d\n", + report->maxfield); + return -ENODEV; + } for (i = 0; i < report->maxfield; i++) { + if (report->field[i]->report_count < 1) { + hid_err(hid, "no values in the field\n"); + return -ENODEV; + } for (j = 0; j < report->field[i]->report_count; j++) { report->field[i]->value[j] = 0x00; - field_count++; } } - if (field_count < 4) { - hid_err(hid, "not enough fields in the report: %d\n", - field_count); - return -ENODEV; - } - betopff = kzalloc(sizeof(*betopff), GFP_KERNEL); if (!betopff) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/hid/hid-bigbenff.c +++ linux-oracle-5.4.0/drivers/hid/hid-bigbenff.c @@ -174,6 +174,8 @@ struct bigben_device { struct hid_device *hid; struct hid_report *report; + spinlock_t lock; + bool removed; u8 led_state; /* LED1 = 1 .. LED4 = 8 */ u8 right_motor_on; /* right motor off/on 0/1 */ u8 left_motor_force; /* left motor force 0-255 */ @@ -183,15 +185,39 @@ struct work_struct worker; }; +static inline void bigben_schedule_work(struct bigben_device *bigben) +{ + unsigned long flags; + + spin_lock_irqsave(&bigben->lock, flags); + if (!bigben->removed) + schedule_work(&bigben->worker); + spin_unlock_irqrestore(&bigben->lock, flags); +} static void bigben_worker(struct work_struct *work) { struct bigben_device *bigben = container_of(work, struct bigben_device, worker); struct hid_field *report_field = bigben->report->field[0]; + bool do_work_led = false; + bool do_work_ff = false; + u8 *buf; + u32 len; + unsigned long flags; + + buf = hid_alloc_report_buf(bigben->report, GFP_KERNEL); + if (!buf) + return; + + len = hid_report_len(bigben->report); + + /* LED work */ + spin_lock_irqsave(&bigben->lock, flags); if (bigben->work_led) { bigben->work_led = false; + do_work_led = true; report_field->value[0] = 0x01; /* 1 = led message */ report_field->value[1] = 0x08; /* reserved value, always 8 */ report_field->value[2] = bigben->led_state; @@ -200,11 +226,22 @@ report_field->value[5] = 0x00; /* padding */ report_field->value[6] = 0x00; /* padding */ report_field->value[7] = 0x00; /* padding */ - hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT); + hid_output_report(bigben->report, buf); } + spin_unlock_irqrestore(&bigben->lock, flags); + + if (do_work_led) { + hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len, + bigben->report->type, HID_REQ_SET_REPORT); + } + + /* FF work */ + spin_lock_irqsave(&bigben->lock, flags); + if (bigben->work_ff) { bigben->work_ff = false; + do_work_ff = true; report_field->value[0] = 0x02; /* 2 = rumble effect message */ report_field->value[1] = 0x08; /* reserved value, always 8 */ report_field->value[2] = bigben->right_motor_on; @@ -213,16 +250,32 @@ report_field->value[5] = 0x00; /* padding */ report_field->value[6] = 0x00; /* padding */ report_field->value[7] = 0x00; /* padding */ - hid_hw_request(bigben->hid, bigben->report, HID_REQ_SET_REPORT); + hid_output_report(bigben->report, buf); } + + spin_unlock_irqrestore(&bigben->lock, flags); + + if (do_work_ff) { + hid_hw_raw_request(bigben->hid, bigben->report->id, buf, len, + bigben->report->type, HID_REQ_SET_REPORT); + } + + kfree(buf); } static int hid_bigben_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) { - struct bigben_device *bigben = data; + struct hid_device *hid = input_get_drvdata(dev); + struct bigben_device *bigben = hid_get_drvdata(hid); u8 right_motor_on; u8 left_motor_force; + unsigned long flags; + + if (!bigben) { + hid_err(hid, "no device data\n"); + return 0; + } if (effect->type != FF_RUMBLE) return 0; @@ -232,10 +285,13 @@ if (right_motor_on != bigben->right_motor_on || left_motor_force != bigben->left_motor_force) { + spin_lock_irqsave(&bigben->lock, flags); bigben->right_motor_on = right_motor_on; bigben->left_motor_force = left_motor_force; bigben->work_ff = true; - schedule_work(&bigben->worker); + spin_unlock_irqrestore(&bigben->lock, flags); + + bigben_schedule_work(bigben); } return 0; @@ -249,6 +305,7 @@ struct bigben_device *bigben = hid_get_drvdata(hid); int n; bool work; + unsigned long flags; if (!bigben) { hid_err(hid, "no device data\n"); @@ -257,6 +314,7 @@ for (n = 0; n < NUM_LEDS; n++) { if (led == bigben->leds[n]) { + spin_lock_irqsave(&bigben->lock, flags); if (value == LED_OFF) { work = (bigben->led_state & BIT(n)); bigben->led_state &= ~BIT(n); @@ -264,10 +322,11 @@ work = !(bigben->led_state & BIT(n)); bigben->led_state |= BIT(n); } + spin_unlock_irqrestore(&bigben->lock, flags); if (work) { bigben->work_led = true; - schedule_work(&bigben->worker); + bigben_schedule_work(bigben); } return; } @@ -297,9 +356,13 @@ static void bigben_remove(struct hid_device *hid) { struct bigben_device *bigben = hid_get_drvdata(hid); + unsigned long flags; + + spin_lock_irqsave(&bigben->lock, flags); + bigben->removed = true; + spin_unlock_irqrestore(&bigben->lock, flags); cancel_work_sync(&bigben->worker); - hid_hw_close(hid); hid_hw_stop(hid); } @@ -308,7 +371,6 @@ { struct bigben_device *bigben; struct hid_input *hidinput; - struct list_head *report_list; struct led_classdev *led; char *name; size_t name_sz; @@ -319,6 +381,7 @@ return -ENOMEM; hid_set_drvdata(hid, bigben); bigben->hid = hid; + bigben->removed = false; error = hid_parse(hid); if (error) { @@ -332,19 +395,29 @@ return error; } - report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; - bigben->report = list_entry(report_list->next, - struct hid_report, list); + bigben->report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, 0, 8); + if (!bigben->report) { + hid_err(hid, "no output report found\n"); + error = -ENODEV; + goto error_hw_stop; + } + + if (list_empty(&hid->inputs)) { + hid_err(hid, "no inputs found\n"); + error = -ENODEV; + goto error_hw_stop; + } hidinput = list_first_entry(&hid->inputs, struct hid_input, list); set_bit(FF_RUMBLE, hidinput->input->ffbit); INIT_WORK(&bigben->worker, bigben_worker); + spin_lock_init(&bigben->lock); - error = input_ff_create_memless(hidinput->input, bigben, + error = input_ff_create_memless(hidinput->input, NULL, hid_bigben_play_effect); if (error) - return error; + goto error_hw_stop; name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1; @@ -354,8 +427,10 @@ sizeof(struct led_classdev) + name_sz, GFP_KERNEL ); - if (!led) - return -ENOMEM; + if (!led) { + error = -ENOMEM; + goto error_hw_stop; + } name = (void *)(&led[1]); snprintf(name, name_sz, "%s:red:bigben%d", @@ -369,7 +444,7 @@ bigben->leds[n] = led; error = devm_led_classdev_register(&hid->dev, led); if (error) - return error; + goto error_hw_stop; } /* initial state: LED1 is on, no rumble effect */ @@ -378,11 +453,15 @@ bigben->left_motor_force = 0; bigben->work_led = true; bigben->work_ff = true; - schedule_work(&bigben->worker); + bigben_schedule_work(bigben); hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); return 0; + +error_hw_stop: + hid_hw_stop(hid); + return error; } static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc, --- linux-oracle-5.4.0.orig/drivers/hid/hid-chicony.c +++ linux-oracle-5.4.0/drivers/hid/hid-chicony.c @@ -58,8 +58,12 @@ static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - + struct usb_interface *intf; + + if (!hid_is_usb(hdev)) + return rdesc; + + intf = to_usb_interface(hdev->dev.parent); if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { /* Change usage maximum and logical maximum from 0x7fff to * 0x2fff, so they don't exceed HID_MAX_USAGES */ --- linux-oracle-5.4.0.orig/drivers/hid/hid-core.c +++ linux-oracle-5.4.0/drivers/hid/hid-core.c @@ -90,7 +90,7 @@ * Register a new field for this report. */ -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) +static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages) { struct hid_field *field; @@ -101,7 +101,7 @@ field = kzalloc((sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + - values * sizeof(unsigned)), GFP_KERNEL); + usages * sizeof(unsigned)), GFP_KERNEL); if (!field) return NULL; @@ -212,6 +212,18 @@ } /* + * Concatenate usage which defines 16 bits or less with the + * currently defined usage page to form a 32 bit usage + */ + +static void complete_usage(struct hid_parser *parser, unsigned int index) +{ + parser->local.usage[index] &= 0xFFFF; + parser->local.usage[index] |= + (parser->global.usage_page & 0xFFFF) << 16; +} + +/* * Add a usage to the temporary parser table. */ @@ -222,6 +234,14 @@ return -1; } parser->local.usage[parser->local.usage_index] = usage; + + /* + * If Usage item only includes usage id, concatenate it with + * currently defined usage page + */ + if (size <= 2) + complete_usage(parser, parser->local.usage_index); + parser->local.usage_size[parser->local.usage_index] = size; parser->local.collection_index[parser->local.usage_index] = parser->collection_stack_ptr ? @@ -238,6 +258,7 @@ { struct hid_report *report; struct hid_field *field; + unsigned int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int usages; unsigned int offset; unsigned int i; @@ -268,13 +289,22 @@ offset = report->size; report->size += parser->global.report_size * parser->global.report_count; + if (parser->device->ll_driver->max_buffer_size) + max_buffer_size = parser->device->ll_driver->max_buffer_size; + + /* Total size check: Allow for possible report index byte */ + if (report->size > (max_buffer_size - 1) << 3) { + hid_err(parser->device, "report is too long\n"); + return -1; + } + if (!parser->local.usage_index) /* Ignore padding fields */ return 0; usages = max_t(unsigned, parser->local.usage_index, parser->global.report_count); - field = hid_register_field(report, usages, parser->global.report_count); + field = hid_register_field(report, usages); if (!field) return 0; @@ -543,13 +573,32 @@ * usage value." */ -static void hid_concatenate_usage_page(struct hid_parser *parser) +static void hid_concatenate_last_usage_page(struct hid_parser *parser) { int i; + unsigned int usage_page; + unsigned int current_page; + + if (!parser->local.usage_index) + return; + + usage_page = parser->global.usage_page; + + /* + * Concatenate usage page again only if last declared Usage Page + * has not been already used in previous usages concatenation + */ + for (i = parser->local.usage_index - 1; i >= 0; i--) { + if (parser->local.usage_size[i] > 2) + /* Ignore extended usages */ + continue; + + current_page = parser->local.usage[i] >> 16; + if (current_page == usage_page) + break; - for (i = 0; i < parser->local.usage_index; i++) - if (parser->local.usage_size[i] <= 2) - parser->local.usage[i] += parser->global.usage_page << 16; + complete_usage(parser, i); + } } /* @@ -561,7 +610,7 @@ __u32 data; int ret; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item); @@ -653,15 +702,22 @@ * Free a device structure, all reports, and all fields. */ -static void hid_device_release(struct device *dev) +void hiddev_free(struct kref *ref) { - struct hid_device *hid = to_hid_device(dev); + struct hid_device *hid = container_of(ref, struct hid_device, ref); hid_close_report(hid); kfree(hid->dev_rdesc); kfree(hid); } +static void hid_device_release(struct device *dev) +{ + struct hid_device *hid = to_hid_device(dev); + + kref_put(&hid->ref, hiddev_free); +} + /* * Fetch a report description item from the data stream. We support long * items, though they are not used yet. @@ -742,6 +798,10 @@ if (usage == 0xff0000c5 && parser->global.report_count == 256 && parser->global.report_size == 8) parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; + + if (usage == 0xff0000c6 && parser->global.report_count == 1 && + parser->global.report_size == 8) + parser->scan_flags |= HID_SCAN_FLAG_MT_WIN_8; } static void hid_scan_collection(struct hid_parser *parser, unsigned type) @@ -772,7 +832,7 @@ __u32 data; int i; - hid_concatenate_usage_page(parser); + hid_concatenate_last_usage_page(parser); data = item_udata(item); @@ -932,8 +992,8 @@ * Validating on id 0 means we should examine the first * report in the list. */ - report = list_entry( - hid->report_enum[type].report_list.next, + report = list_first_entry_or_null( + &hid->report_enum[type].report_list, struct hid_report, list); } else { report = hid->report_enum[type].report_id_hash[id]; @@ -1057,6 +1117,8 @@ while (multiplier_collection->parent_idx != -1 && multiplier_collection->type != HID_COLLECTION_LOGICAL) multiplier_collection = &hid->collection[multiplier_collection->parent_idx]; + if (multiplier_collection->type != HID_COLLECTION_LOGICAL) + multiplier_collection = NULL; effective_multiplier = hid_calculate_multiplier(hid, multiplier); @@ -1141,6 +1203,7 @@ __u8 *end; __u8 *next; int ret; + int i; static int (*dispatch_type[])(struct hid_parser *parser, struct hid_item *item) = { hid_parser_main, @@ -1191,6 +1254,8 @@ goto err; } device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) + device->collection[i].parent_idx = -1; ret = -EINVAL; while ((next = fetch_item(start, end, &item)) != NULL) { @@ -1251,6 +1316,12 @@ static s32 snto32(__u32 value, unsigned n) { + if (!value || !n) + return 0; + + if (n > 32) + n = 32; + switch (n) { case 8: return ((__s8)value); case 16: return ((__s16)value); @@ -1370,7 +1441,6 @@ hid_warn(hid, "%s() called with too large value %d (n: %d)! (%s)\n", __func__, value, n, current->comm); - WARN_ON(1); value &= m; } } @@ -1549,6 +1619,17 @@ } /* + * Compute the size of a report. + */ +static size_t hid_compute_report_size(struct hid_report *report) +{ + if (report->size) + return ((report->size - 1) >> 3) + 1; + + return 0; +} + +/* * Create a report. 'data' has to be allocated using * hid_alloc_report_buf() so that it has proper size. */ @@ -1560,7 +1641,7 @@ if (report->id > 0) *data++ = report->id; - memset(data, 0, ((report->size - 1) >> 3) + 1); + memset(data, 0, hid_compute_report_size(report)); for (n = 0; n < report->maxfield; n++) hid_output_field(report->device, report->field[n], data); } @@ -1578,7 +1659,7 @@ u32 len = hid_report_len(report) + 7; - return kmalloc(len, flags); + return kzalloc(len, flags); } EXPORT_SYMBOL_GPL(hid_alloc_report_buf); @@ -1676,6 +1757,7 @@ struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; + int max_buffer_size = HID_MAX_BUFFER_SIZE; unsigned int a; u32 rsize, csize = size; u8 *cdata = data; @@ -1690,10 +1772,15 @@ csize--; } - rsize = ((report->size - 1) >> 3) + 1; + rsize = hid_compute_report_size(report); - if (rsize > HID_MAX_BUFFER_SIZE) - rsize = HID_MAX_BUFFER_SIZE; + if (hid->ll_driver->max_buffer_size) + max_buffer_size = hid->ll_driver->max_buffer_size; + + if (report_enum->numbered && rsize >= max_buffer_size) + rsize = max_buffer_size - 1; + else if (rsize > max_buffer_size) + rsize = max_buffer_size; if (csize < rsize) { dbg_hid("report %d is too short, (%d < %d)\n", report->id, @@ -1933,6 +2020,9 @@ case BUS_I2C: bus = "I2C"; break; + case BUS_VIRTUAL: + bus = "VIRTUAL"; + break; default: bus = ""; } @@ -2231,12 +2321,8 @@ { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv; - int ret = 0; - if (down_interruptible(&hdev->driver_input_lock)) { - ret = -EINTR; - goto end; - } + down(&hdev->driver_input_lock); hdev->io_started = false; hdrv = hdev->driver; @@ -2251,8 +2337,8 @@ if (!hdev->io_started) up(&hdev->driver_input_lock); -end: - return ret; + + return 0; } static ssize_t modalias_show(struct device *dev, struct device_attribute *a, @@ -2359,10 +2445,12 @@ hid_warn(hdev, "bad device descriptor (%d)\n", ret); } + hdev->id = atomic_inc_return(&id); + /* XXX hack, any other cleaner solution after the driver core * is converted to allow more than 20 bytes as the device name? */ dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, - hdev->vendor, hdev->product, atomic_inc_return(&id)); + hdev->vendor, hdev->product, hdev->id); hid_debug_register(hdev, dev_name(&hdev->dev)); ret = device_add(&hdev->dev); @@ -2405,6 +2493,7 @@ spin_lock_init(&hdev->debug_list_lock); sema_init(&hdev->driver_input_lock, 1); mutex_init(&hdev->ll_open_lock); + kref_init(&hdev->ref); return hdev; } --- linux-oracle-5.4.0.orig/drivers/hid/hid-corsair.c +++ linux-oracle-5.4.0/drivers/hid/hid-corsair.c @@ -553,7 +553,12 @@ int ret; unsigned long quirks = id->driver_data; struct corsair_drvdata *drvdata; - struct usb_interface *usbif = to_usb_interface(dev->dev.parent); + struct usb_interface *usbif; + + if (!hid_is_usb(dev)) + return -EINVAL; + + usbif = to_usb_interface(dev->dev.parent); drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/hid/hid-cougar.c +++ linux-oracle-5.4.0/drivers/hid/hid-cougar.c @@ -106,7 +106,7 @@ static __u8 *cougar_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - if (rdesc[2] == 0x09 && rdesc[3] == 0x02 && + if (*rsize >= 117 && rdesc[2] == 0x09 && rdesc[3] == 0x02 && (rdesc[115] | rdesc[116] << 8) >= HID_MAX_USAGES) { hid_info(hdev, "usage count exceeds max: fixing up report descriptor\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-cp2112.c +++ linux-oracle-5.4.0/drivers/hid/hid-cp2112.c @@ -787,6 +787,11 @@ data->word = le16_to_cpup((__le16 *)buf); break; case I2C_SMBUS_I2C_BLOCK_DATA: + if (read_length > I2C_SMBUS_BLOCK_MAX) { + ret = -EINVAL; + goto power_normal; + } + memcpy(data->block + 1, buf, read_length); break; case I2C_SMBUS_BLOCK_DATA: @@ -1151,8 +1156,6 @@ struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct cp2112_device *dev = gpiochip_get_data(gc); - INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); - if (!dev->gpio_poll) { dev->gpio_poll = true; schedule_delayed_work(&dev->gpio_poll_worker, 0); @@ -1235,6 +1238,7 @@ struct cp2112_device *dev; u8 buf[3]; struct cp2112_smbus_config_report config; + struct gpio_irq_chip *girq; int ret; dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); @@ -1338,6 +1342,17 @@ dev->gc.can_sleep = 1; dev->gc.parent = &hdev->dev; + girq = &dev->gc.irq; + girq->chip = &cp2112_gpio_irqchip; + /* The event comes from the outside so no parent handler */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + + INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback); + ret = gpiochip_add_data(&dev->gc, dev); if (ret < 0) { hid_err(hdev, "error registering gpio chip\n"); @@ -1353,17 +1368,8 @@ chmod_sysfs_attrs(hdev); hid_hw_power(hdev, PM_HINT_NORMAL); - ret = gpiochip_irqchip_add(&dev->gc, &cp2112_gpio_irqchip, 0, - handle_simple_irq, IRQ_TYPE_NONE); - if (ret) { - dev_err(dev->gc.parent, "failed to add IRQ chip\n"); - goto err_sysfs_remove; - } - return ret; -err_sysfs_remove: - sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group); err_gpiochip_remove: gpiochip_remove(&dev->gc); err_free_i2c: --- linux-oracle-5.4.0.orig/drivers/hid/hid-cypress.c +++ linux-oracle-5.4.0/drivers/hid/hid-cypress.c @@ -23,19 +23,17 @@ #define CP_2WHEEL_MOUSE_HACK 0x02 #define CP_2WHEEL_MOUSE_HACK_ON 0x04 +#define VA_INVAL_LOGICAL_BOUNDARY 0x08 + /* * Some USB barcode readers from cypress have usage min and usage max in * the wrong order */ -static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, +static __u8 *cp_rdesc_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); unsigned int i; - if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) - return rdesc; - if (*rsize < 4) return rdesc; @@ -48,6 +46,40 @@ return rdesc; } +static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + /* + * Varmilo VA104M (with VID Cypress and device ID 07B1) incorrectly + * reports Logical Minimum of its Consumer Control device as 572 + * (0x02 0x3c). Fix this by setting its Logical Minimum to zero. + */ + if (*rsize == 25 && + rdesc[0] == 0x05 && rdesc[1] == 0x0c && + rdesc[2] == 0x09 && rdesc[3] == 0x01 && + rdesc[6] == 0x19 && rdesc[7] == 0x00 && + rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) { + hid_info(hdev, + "fixing up varmilo VA104M consumer control report descriptor\n"); + rdesc[12] = 0x00; + rdesc[13] = 0x00; + } + return rdesc; +} + +static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + + if (quirks & CP_RDESC_SWAPPED_MIN_MAX) + rdesc = cp_rdesc_fixup(hdev, rdesc, rsize); + if (quirks & VA_INVAL_LOGICAL_BOUNDARY) + rdesc = va_logical_boundary_fixup(hdev, rdesc, rsize); + + return rdesc; +} + static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) @@ -128,6 +160,8 @@ .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), .driver_data = CP_2WHEEL_MOUSE_HACK }, + { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1), + .driver_data = VA_INVAL_LOGICAL_BOUNDARY }, { } }; MODULE_DEVICE_TABLE(hid, cp_devices); --- linux-oracle-5.4.0.orig/drivers/hid/hid-debug.c +++ linux-oracle-5.4.0/drivers/hid/hid-debug.c @@ -823,7 +823,9 @@ [KEY_F22] = "F22", [KEY_F23] = "F23", [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD", [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", - [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", + [KEY_PROG4] = "Prog4", + [KEY_ALL_APPLICATIONS] = "AllApplications", + [KEY_SUSPEND] = "Suspend", [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost", [KEY_PRINT] = "Print", [KEY_HP] = "HP", @@ -929,6 +931,9 @@ [KEY_APPSELECT] = "AppSelect", [KEY_SCREENSAVER] = "ScreenSaver", [KEY_VOICECOMMAND] = "VoiceCommand", + [KEY_EMOJI_PICKER] = "EmojiPicker", + [KEY_DICTATE] = "Dictate", + [KEY_MICMUTE] = "MicrophoneMute", [KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MAX] = "BrightnessMax", [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", @@ -1077,6 +1082,7 @@ goto out; } list->hdev = (struct hid_device *) inode->i_private; + kref_get(&list->hdev->ref); file->private_data = list; mutex_init(&list->read_mutex); @@ -1169,6 +1175,8 @@ list_del(&list->node); spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags); kfifo_free(&list->hid_debug_fifo); + + kref_put(&list->hdev->ref, hiddev_free); kfree(list); return 0; --- linux-oracle-5.4.0.orig/drivers/hid/hid-elan.c +++ linux-oracle-5.4.0/drivers/hid/hid-elan.c @@ -50,7 +50,7 @@ static int is_not_elan_touchpad(struct hid_device *hdev) { - if (hdev->bus == BUS_USB) { + if (hid_is_usb(hdev)) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); return (intf->altsetting->desc.bInterfaceNumber != @@ -198,7 +198,7 @@ if (ret) { hid_err(hdev, "Failed to register elan input device: %d\n", ret); - input_free_device(input); + input_mt_destroy_slots(input); return ret; } --- linux-oracle-5.4.0.orig/drivers/hid/hid-elo.c +++ linux-oracle-5.4.0/drivers/hid/hid-elo.c @@ -229,6 +229,9 @@ struct elo_priv *priv; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/hid/hid-google-hammer.c +++ linux-oracle-5.4.0/drivers/hid/hid-google-hammer.c @@ -258,11 +258,13 @@ return 0; } +#ifdef CONFIG_ACPI static const struct acpi_device_id cbas_ec_acpi_ids[] = { { "GOOG000B", 0 }, { } }; MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids); +#endif static struct platform_driver cbas_ec_driver = { .probe = cbas_ec_probe, @@ -468,12 +470,20 @@ static const struct hid_device_id hammer_devices[] = { { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_DON) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_EEL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_HAMMER) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_JEWEL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_WAND) }, --- linux-oracle-5.4.0.orig/drivers/hid/hid-gt683r.c +++ linux-oracle-5.4.0/drivers/hid/hid-gt683r.c @@ -54,6 +54,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, { } }; +MODULE_DEVICE_TABLE(hid, gt683r_led_id); static void gt683r_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) --- linux-oracle-5.4.0.orig/drivers/hid/hid-holtek-kbd.c +++ linux-oracle-5.4.0/drivers/hid/hid-holtek-kbd.c @@ -130,6 +130,10 @@ return -ENODEV; boot_hid = usb_get_intfdata(boot_interface); + if (list_empty(&boot_hid->inputs)) { + hid_err(hid, "no inputs found\n"); + return -ENODEV; + } boot_hid_input = list_first_entry(&boot_hid->inputs, struct hid_input, list); @@ -140,12 +144,17 @@ static int holtek_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - int ret = hid_parse(hdev); + struct usb_interface *intf; + int ret; + + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + intf = to_usb_interface(hdev->dev.parent); if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { struct hid_input *hidinput; list_for_each_entry(hidinput, &hdev->inputs, list) { --- linux-oracle-5.4.0.orig/drivers/hid/hid-holtek-mouse.c +++ linux-oracle-5.4.0/drivers/hid/hid-holtek-mouse.c @@ -62,6 +62,29 @@ return rdesc; } +static int holtek_mouse_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + + if (!hid_is_usb(hdev)) + return -EINVAL; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid parse failed: %d\n", ret); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed: %d\n", ret); + return ret; + } + + return 0; +} + static const struct hid_device_id holtek_mouse_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, @@ -83,6 +106,7 @@ .name = "holtek_mouse", .id_table = holtek_mouse_devices, .report_fixup = holtek_mouse_report_fixup, + .probe = holtek_mouse_probe, }; module_hid_driver(holtek_mouse_driver); --- linux-oracle-5.4.0.orig/drivers/hid/hid-hyperv.c +++ linux-oracle-5.4.0/drivers/hid/hid-hyperv.c @@ -492,7 +492,7 @@ ret = hid_add_device(hid_dev); if (ret) - goto probe_err1; + goto probe_err2; ret = hid_parse(hid_dev); --- linux-oracle-5.4.0.orig/drivers/hid/hid-ids.h +++ linux-oracle-5.4.0/drivers/hid/hid-ids.h @@ -79,10 +79,10 @@ #define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 #define HID_DEVICE_ID_ALPS_U1 0x1215 +#define HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY 0x121E #define HID_DEVICE_ID_ALPS_T4_BTNLESS 0x120C #define HID_DEVICE_ID_ALPS_1222 0x1222 - #define USB_VENDOR_ID_AMI 0x046b #define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10 @@ -175,6 +175,7 @@ #define USB_DEVICE_ID_APPLE_IRCONTROL3 0x8241 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 #define USB_DEVICE_ID_APPLE_IRCONTROL5 0x8243 +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c #define USB_VENDOR_ID_ASUS 0x0486 #define USB_DEVICE_ID_ASUS_T91MT 0x0185 @@ -337,6 +338,8 @@ #define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 #define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 +#define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1 + #define USB_VENDOR_ID_DATA_MODUL 0x7374 #define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201 @@ -348,6 +351,7 @@ #define USB_VENDOR_ID_DELL 0x413c #define USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE 0x301a +#define USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W 0x4503 #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 @@ -363,6 +367,7 @@ #define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844 +#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846 #define USB_VENDOR_ID_DWAV 0x0eef #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 @@ -385,11 +390,13 @@ #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 +#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002 0xc002 #define USB_VENDOR_ID_ELAN 0x04f3 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 #define USB_DEVICE_ID_HP_X2 0x074d #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 +#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define USB_VENDOR_ID_ELECOM 0x056e #define USB_DEVICE_ID_ELECOM_BM084 0x0061 @@ -448,6 +455,10 @@ #define USB_VENDOR_ID_FRUCTEL 0x25B6 #define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 +#define USB_VENDOR_ID_GAMEVICE 0x27F8 +#define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE +#define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF + #define USB_VENDOR_ID_GAMERON 0x0810 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 @@ -478,6 +489,10 @@ #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d +#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 +#define USB_DEVICE_ID_GOOGLE_DON 0x5050 +#define USB_DEVICE_ID_GOOGLE_EEL 0x5057 +#define USB_DEVICE_ID_GOOGLE_JEWEL 0x5061 #define USB_VENDOR_ID_GOTOP 0x08f2 #define USB_DEVICE_ID_SUPER_Q2 0x007f @@ -485,6 +500,7 @@ #define USB_DEVICE_ID_PENPOWER 0x00f4 #define USB_VENDOR_ID_GREENASIA 0x0e8f +#define USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR 0x3010 #define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013 #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 @@ -567,12 +583,14 @@ #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 #define USB_VENDOR_ID_HP 0x03f0 +#define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A 0x094a #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941 0x0941 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641 +#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a 0x1f4a #define USB_VENDOR_ID_HUION 0x256c #define USB_DEVICE_ID_HUION_TABLET 0x006e @@ -617,6 +635,7 @@ #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 0xa0c2 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096 +#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293 0xa293 #define USB_VENDOR_ID_IMATION 0x0718 #define USB_DEVICE_ID_DISC_STAKKA 0xd000 @@ -628,10 +647,14 @@ #define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 #define USB_VENDOR_ID_ITE 0x048d +#define I2C_VENDOR_ID_ITE 0x103c +#define I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 0x184f #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 +#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 #define USB_DEVICE_ID_ITE8595 0x8595 +#define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50 #define USB_VENDOR_ID_JABRA 0x0b0e #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 @@ -724,15 +747,22 @@ #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 +#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093 #define USB_VENDOR_ID_LG 0x1fd2 #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 #define USB_DEVICE_ID_LG_MELFAS_MT 0x6007 #define I2C_DEVICE_ID_LG_8001 0x8001 +#define I2C_DEVICE_ID_LG_7010 0x7010 #define USB_VENDOR_ID_LOGITECH 0x046d #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e #define USB_DEVICE_ID_LOGITECH_T651 0xb00c +#define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309 #define USB_DEVICE_ID_LOGITECH_C007 0xc007 #define USB_DEVICE_ID_LOGITECH_C077 0xc077 #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 @@ -764,6 +794,7 @@ #define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a +#define USB_DEVICE_ID_LOGITECH_GROUP_AUDIO 0x0882 #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 @@ -792,6 +823,7 @@ #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 #define USB_DEVICE_ID_MADCATZ_RAT5 0x1705 #define USB_DEVICE_ID_MADCATZ_RAT9 0x1709 +#define USB_DEVICE_ID_MADCATZ_MMO7 0x1713 #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 @@ -833,8 +865,19 @@ #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 #define USB_DEVICE_ID_MS_POWER_COVER 0x07da -#define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd +#define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de +/* + * For a description of the Xbox controller models, refer to: + * https://en.wikipedia.org/wiki/Xbox_Wireless_Controller#Summary + */ +#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708 0x02fd +#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE 0x0b20 +#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914 0x0b13 +#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797 0x0b05 +#define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE 0x0b22 #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb +#define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 +#define USB_DEVICE_ID_MS_MOUSE_0783 0x0783 #define USB_VENDOR_ID_MOJO 0x8282 #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 @@ -907,6 +950,12 @@ #define USB_DEVICE_ID_ORTEK_IHOME_IMAC_A210S 0x8003 #define USB_VENDOR_ID_PLANTRONICS 0x047f +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055 +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c +#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e #define USB_VENDOR_ID_PANASONIC 0x04da #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 @@ -959,6 +1008,7 @@ #define I2C_VENDOR_ID_RAYDIUM 0x2386 #define I2C_PRODUCT_ID_RAYDIUM_4B33 0x4b33 +#define I2C_PRODUCT_ID_RAYDIUM_3118 0x3118 #define USB_VENDOR_ID_RAZER 0x1532 #define USB_DEVICE_ID_RAZER_BLADE_14 0x011D @@ -988,6 +1038,8 @@ #define USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO 0x3232 #define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a +#define USB_VENDOR_ID_SAI 0x17dd + #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 #define USB_DEVICE_ID_SAITEK_PS1000 0x0621 @@ -997,6 +1049,9 @@ #define USB_DEVICE_ID_SAITEK_RAT9 0x0cfa #define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0 #define USB_DEVICE_ID_SAITEK_X52 0x075c +#define USB_DEVICE_ID_SAITEK_X52_2 0x0255 +#define USB_DEVICE_ID_SAITEK_X52_PRO 0x0762 +#define USB_DEVICE_ID_SAITEK_X65 0x0b6a #define USB_VENDOR_ID_SAMSUNG 0x0419 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 @@ -1082,6 +1137,9 @@ #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 #define USB_DEVICE_ID_SYMBOL_SCANNER_3 0x1200 +#define I2C_VENDOR_ID_SYNAPTICS 0x06cb +#define I2C_PRODUCT_ID_SYNAPTICS_SYNA2393 0x7a13 + #define USB_VENDOR_ID_SYNAPTICS 0x06cb #define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 #define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 @@ -1096,7 +1154,12 @@ #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 +#define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819 +#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968 #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 +#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002 0x73f4 +#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5 +#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017 0x73f6 #define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047 @@ -1135,6 +1198,9 @@ #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882 0x8882 #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883 0x8883 +#define USB_VENDOR_ID_TRUST 0x145f +#define USB_DEVICE_ID_TRUST_PANORA_TABLET 0x0212 + #define USB_VENDOR_ID_TURBOX 0x062a #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 #define USB_DEVICE_ID_ASUS_MD_5110 0x5110 @@ -1247,6 +1313,7 @@ #define USB_VENDOR_ID_PRIMAX 0x0461 #define USB_DEVICE_ID_PRIMAX_MOUSE_4D22 0x4d22 +#define USB_DEVICE_ID_PRIMAX_MOUSE_4E2A 0x4e2a #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 #define USB_DEVICE_ID_PRIMAX_REZEL 0x4e72 #define USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F 0x4d0f @@ -1266,6 +1333,8 @@ #define USB_VENDOR_ID_UGTIZER 0x2179 #define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053 +#define USB_DEVICE_ID_UGTIZER_TABLET_GT5040 0x0077 +#define USB_DEVICE_ID_UGTIZER_TABLET_WP5540 0x0004 #define USB_VENDOR_ID_VIEWSONIC 0x0543 #define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621 --- linux-oracle-5.4.0.orig/drivers/hid/hid-input.c +++ linux-oracle-5.4.0/drivers/hid/hid-input.c @@ -319,6 +319,11 @@ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), HID_BATTERY_QUIRK_IGNORE }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, + USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD), + HID_BATTERY_QUIRK_IGNORE }, + { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), + HID_BATTERY_QUIRK_IGNORE }, {} }; @@ -350,13 +355,13 @@ u8 *buf; int ret; - buf = kmalloc(2, GFP_KERNEL); + buf = kmalloc(4, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 2, + ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 4, dev->battery_report_type, HID_REQ_GET_REPORT); - if (ret != 2) { + if (ret < 2) { kfree(buf); return -ENODATA; } @@ -410,8 +415,6 @@ if (dev->battery_status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - else if (dev->battery_capacity == 100) - val->intval = POWER_SUPPLY_STATUS_FULL; else val->intval = POWER_SUPPLY_STATUS_DISCHARGING; break; @@ -668,6 +671,14 @@ break; } + if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */ + switch (usage->hid & 0xf) { + case 0x9: map_key_clear(KEY_MICMUTE); break; + default: goto ignore; + } + break; + } + if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */ switch (usage->hid & 0xf) { case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break; @@ -797,7 +808,7 @@ case 0x3b: /* Battery Strength */ hidinput_setup_battery(device, HID_INPUT_REPORT, field); usage->type = EV_PWR; - goto ignore; + return; case 0x3c: /* Invert */ map_key_clear(BTN_TOOL_RUBBER); @@ -952,6 +963,10 @@ case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break; + + case 0x0d8: map_key_clear(KEY_DICTATE); break; + case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break; + case 0x0e0: map_abs_clear(ABS_VOLUME); break; case 0x0e2: map_key_clear(KEY_MUTE); break; case 0x0e5: map_key_clear(KEY_BASSBOOST); break; @@ -1041,6 +1056,8 @@ case 0x29d: map_key_clear(KEY_KBD_LAYOUT_NEXT); break; + case 0x2a2: map_key_clear(KEY_ALL_APPLICATIONS); break; + case 0x2c7: map_key_clear(KEY_KBDINPUTASSIST_PREV); break; case 0x2c8: map_key_clear(KEY_KBDINPUTASSIST_NEXT); break; case 0x2c9: map_key_clear(KEY_KBDINPUTASSIST_PREVGROUP); break; @@ -1059,7 +1076,7 @@ case HID_DC_BATTERYSTRENGTH: hidinput_setup_battery(device, HID_INPUT_REPORT, field); usage->type = EV_PWR; - goto ignore; + return; } goto unknown; @@ -1132,9 +1149,19 @@ } mapped: - if (device->driver->input_mapped && device->driver->input_mapped(device, - hidinput, field, usage, &bit, &max) < 0) - goto ignore; + /* Mapping failed, bail out */ + if (!bit) + return; + + if (device->driver->input_mapped && + device->driver->input_mapped(device, hidinput, field, usage, + &bit, &max) < 0) { + /* + * The driver indicated that no further generic handling + * of the usage is desired. + */ + return; + } set_bit(usage->type, input->evbit); @@ -1215,9 +1242,11 @@ set_bit(MSC_SCAN, input->mscbit); } -ignore: return; +ignore: + usage->type = 0; + usage->code = 0; } static void hidinput_handle_scroll(struct hid_usage *usage, @@ -1270,6 +1299,12 @@ input = field->hidinput->input; + if (usage->type == EV_ABS && + (((*quirks & HID_QUIRK_X_INVERT) && usage->code == ABS_X) || + ((*quirks & HID_QUIRK_Y_INVERT) && usage->code == ABS_Y))) { + value = field->logical_maximum - value; + } + if (usage->hat_min < usage->hat_max || usage->hat_dir) { int hat_dir = usage->hat_dir; if (!hat_dir) --- linux-oracle-5.4.0.orig/drivers/hid/hid-ite.c +++ linux-oracle-5.4.0/drivers/hid/hid-ite.c @@ -11,6 +11,59 @@ #include "hid-ids.h" +#define QUIRK_TOUCHPAD_ON_OFF_REPORT BIT(0) + +static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) +{ + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + + if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) { + /* For Acer Aspire Switch 10 SW5-012 keyboard-dock */ + if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) { + hid_info(hdev, "Fixing up Acer Sw5-012 ITE keyboard report descriptor\n"); + rdesc[163] = HID_MAIN_ITEM_RELATIVE; + } + /* For Acer One S1002/S1003 keyboard-dock */ + if (*rsize == 188 && rdesc[185] == 0x81 && rdesc[186] == 0x02) { + hid_info(hdev, "Fixing up Acer S1002/S1003 ITE keyboard report descriptor\n"); + rdesc[186] = HID_MAIN_ITEM_RELATIVE; + } + /* For Acer Aspire Switch 10E (SW3-016) keyboard-dock */ + if (*rsize == 210 && rdesc[184] == 0x81 && rdesc[185] == 0x02) { + hid_info(hdev, "Fixing up Acer Aspire Switch 10E (SW3-016) ITE keyboard report descriptor\n"); + rdesc[185] = HID_MAIN_ITEM_RELATIVE; + } + } + + return rdesc; +} + +static int ite_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, + int *max) +{ + + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + + if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) && + (usage->hid & HID_USAGE_PAGE) == 0x00880000) { + if (usage->hid == 0x00880078) { + /* Touchpad on, userspace expects F22 for this */ + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22); + return 1; + } + if (usage->hid == 0x00880079) { + /* Touchpad off, userspace expects F23 for this */ + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23); + return 1; + } + return -1; + } + + return 0; +} + static int ite_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -37,9 +90,42 @@ return 0; } +static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + hid_set_drvdata(hdev, (void *)id->driver_data); + + ret = hid_open_report(hdev); + if (ret) + return ret; + + return hid_hw_start(hdev, HID_CONNECT_DEFAULT); +} + static const struct hid_device_id ite_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, + /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_SYNAPTICS, + USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012), + .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, + /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_SYNAPTICS, + USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1002), + .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, + /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_SYNAPTICS, + USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003), + .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, + /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_SYNAPTICS, + USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_017), + .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, { } }; MODULE_DEVICE_TABLE(hid, ite_devices); @@ -47,6 +133,9 @@ static struct hid_driver ite_driver = { .name = "itetech", .id_table = ite_devices, + .probe = ite_probe, + .report_fixup = ite_report_fixup, + .input_mapping = ite_input_mapping, .event = ite_event, }; module_hid_driver(ite_driver); --- linux-oracle-5.4.0.orig/drivers/hid/hid-led.c +++ linux-oracle-5.4.0/drivers/hid/hid-led.c @@ -366,7 +366,7 @@ .type = DREAM_CHEEKY, .name = "Dream Cheeky Webmail Notifier", .short_name = "dream_cheeky", - .max_brightness = 31, + .max_brightness = 63, .num_leds = 1, .report_size = 9, .report_type = RAW_REQUEST, --- linux-oracle-5.4.0.orig/drivers/hid/hid-lg.c +++ linux-oracle-5.4.0/drivers/hid/hid-lg.c @@ -769,12 +769,18 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *iface = to_usb_interface(hdev->dev.parent); - __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *iface; + __u8 iface_num; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + + iface = to_usb_interface(hdev->dev.parent); + iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + /* G29 only work with the 1st interface */ if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && (iface_num != 0)) { --- linux-oracle-5.4.0.orig/drivers/hid/hid-lg4ff.c +++ linux-oracle-5.4.0/drivers/hid/hid-lg4ff.c @@ -872,6 +872,12 @@ return -ENOMEM; i = strlen(lbuf); + + if (i == 0) { + kfree(lbuf); + return -EINVAL; + } + if (lbuf[i-1] == '\n') { if (i == 1) { kfree(lbuf); --- linux-oracle-5.4.0.orig/drivers/hid/hid-logitech-dj.c +++ linux-oracle-5.4.0/drivers/hid/hid-logitech-dj.c @@ -328,7 +328,7 @@ 0x25, 0x01, /* LOGICAL_MAX (1) */ 0x75, 0x01, /* REPORT_SIZE (1) */ 0x95, 0x04, /* REPORT_COUNT (4) */ - 0x81, 0x06, /* INPUT */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ 0xC0, /* END_COLLECTION */ 0xC0, /* END_COLLECTION */ }; @@ -866,11 +866,24 @@ schedule_work(&djrcv_dev->work); } +/* + * Some quad/bluetooth keyboards have a builtin touchpad in this case we see + * only 1 paired device with a device_type of REPORT_TYPE_KEYBOARD. For the + * touchpad to work we must also forward mouse input reports to the dj_hiddev + * created for the keyboard (instead of forwarding them to a second paired + * device with a device_type of REPORT_TYPE_MOUSE as we normally would). + */ +static const u16 kbd_builtin_touchpad_ids[] = { + 0xb309, /* Dinovo Edge */ + 0xb30c, /* Dinovo Mini */ +}; + static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev, struct hidpp_event *hidpp_report, struct dj_workitem *workitem) { struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); + int i, id; workitem->type = WORKITEM_TYPE_PAIRED; workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] & @@ -882,6 +895,13 @@ workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA | POWER_KEYS | MEDIA_CENTER | HIDPP; + id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb; + for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) { + if (id == kbd_builtin_touchpad_ids[i]) { + workitem->reports_supported |= STD_MOUSE; + break; + } + } break; case REPORT_TYPE_MOUSE: workitem->reports_supported |= STD_MOUSE | HIDPP; @@ -960,6 +980,7 @@ case 0x07: device_type = "eQUAD step 4 Gaming"; logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; break; case 0x08: device_type = "eQUAD step 4 for gamepads"; @@ -974,7 +995,13 @@ workitem.reports_supported |= STD_KEYBOARD; break; case 0x0d: - device_type = "eQUAD Lightspeed 1_1"; + device_type = "eQUAD Lightspeed 1.1"; + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; + break; + case 0x0f: + case 0x11: + device_type = "eQUAD Lightspeed 1.2"; logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); workitem.reports_supported |= STD_KEYBOARD; break; @@ -1185,6 +1212,11 @@ * 50 msec should gives enough time to the receiver to be ready. */ msleep(50); + + if (retval) { + kfree(dj_report); + return retval; + } } /* @@ -1206,7 +1238,7 @@ buf[5] = 0x09; buf[6] = 0x00; - hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, + retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); @@ -1660,7 +1692,7 @@ case recvr_type_27mhz: no_dj_interfaces = 2; break; case recvr_type_bluetooth: no_dj_interfaces = 2; break; } - if (hid_is_using_ll_driver(hdev, &usb_hid_driver)) { + if (hid_is_usb(hdev)) { intf = to_usb_interface(hdev->dev.parent); if (intf && intf->altsetting->desc.bInterfaceNumber >= no_dj_interfaces) { @@ -1842,6 +1874,10 @@ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xc531), .driver_data = recvr_type_gaming_hidpp}, + { /* Logitech G602 receiver (0xc537) */ + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, + 0xc537), + .driver_data = recvr_type_gaming_hidpp}, { /* Logitech lightspeed receiver (0xc539) */ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1), --- linux-oracle-5.4.0.orig/drivers/hid/hid-logitech-hidpp.c +++ linux-oracle-5.4.0/drivers/hid/hid-logitech-hidpp.c @@ -88,6 +88,8 @@ #define HIDPP_CAPABILITY_BATTERY_MILEAGE BIT(2) #define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3) +#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) + /* * There are two hidpp protocols in use, the first version hidpp10 is known * as register access protocol or RAP, the second version hidpp20 is known as @@ -807,8 +809,7 @@ if (ret) return ret; - snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD", - hdev->product, &serial); + snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq); name = hidpp_unifying_get_name(hidpp); @@ -902,6 +903,54 @@ } /* -------------------------------------------------------------------------- */ +/* 0x0003: Device Information */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_DEVICE_INFORMATION 0x0003 + +#define CMD_GET_DEVICE_INFO 0x00 + +static int hidpp_get_serial(struct hidpp_device *hidpp, u32 *serial) +{ + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_DEVICE_INFORMATION, + &feature_index, + &feature_type); + if (ret) + return ret; + + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_GET_DEVICE_INFO, + NULL, 0, &response); + if (ret) + return ret; + + /* See hidpp_unifying_get_serial() */ + *serial = *((u32 *)&response.rap.params[1]); + return 0; +} + +static int hidpp_serial_init(struct hidpp_device *hidpp) +{ + struct hid_device *hdev = hidpp->hid_dev; + u32 serial; + int ret; + + ret = hidpp_get_serial(hidpp, &serial); + if (ret) + return ret; + + snprintf(hdev->uniq, sizeof(hdev->uniq), "%4phD", &serial); + dbg_hid("HID++ DeviceInformation: Got serial: %s\n", hdev->uniq); + + return 0; +} + +/* -------------------------------------------------------------------------- */ /* 0x0005: GetDeviceNameType */ /* -------------------------------------------------------------------------- */ @@ -1102,6 +1151,9 @@ ret = hidpp_send_fap_command_sync(hidpp, feature_index, CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS, NULL, 0, &response); + /* Ignore these intermittent errors */ + if (ret == HIDPP_ERROR_RESOURCE_ERROR) + return -EIO; if (ret > 0) { hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", __func__, ret); @@ -2766,6 +2818,26 @@ } /* -------------------------------------------------------------------------- */ +/* Logitech Dinovo Mini keyboard with builtin touchpad */ +/* -------------------------------------------------------------------------- */ +#define DINOVO_MINI_PRODUCT_ID 0xb30c + +static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) + return 0; + + switch (usage->hid & HID_USAGE) { + case 0x00d: lg_map_key_clear(KEY_MEDIA); break; + default: + return 0; + } + return 1; +} + +/* -------------------------------------------------------------------------- */ /* HID++1.0 devices which use HID++ reports for their wheels */ /* -------------------------------------------------------------------------- */ static int hidpp10_wheel_connect(struct hidpp_device *hidpp) @@ -2961,7 +3033,7 @@ multiplier = 1; hidpp->vertical_wheel_counter.wheel_multiplier = multiplier; - hid_info(hidpp->hid_dev, "multiplier = %d\n", multiplier); + hid_dbg(hidpp->hid_dev, "wheel multiplier = %d\n", multiplier); return 0; } @@ -3000,6 +3072,9 @@ field->application != HID_GD_MOUSE) return m560_input_mapping(hdev, hi, field, usage, bit, max); + if (hdev->product == DINOVO_MINI_PRODUCT_ID) + return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max); + return 0; } @@ -3623,6 +3698,8 @@ if (hidpp->quirks & HIDPP_QUIRK_UNIFYING) hidpp_unifying_init(hidpp); + else if (hid_is_usb(hidpp->hid_dev)) + hidpp_serial_init(hidpp); connected = hidpp_root_get_protocol_version(hidpp) == 0; atomic_set(&hidpp->connected, connected); @@ -3646,7 +3723,8 @@ goto hid_hw_init_fail; } - hidpp_connect_event(hidpp); + schedule_work(&hidpp->work); + flush_work(&hidpp->work); /* Reset the HID node state */ hid_device_io_stop(hdev); @@ -3738,6 +3816,7 @@ LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, { /* Mouse Logitech MX Anywhere 2 */ LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, + { LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, { LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, { LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, { LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 }, @@ -3760,6 +3839,9 @@ { /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */ LDJ_DEVICE(0xb305), .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, + { /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */ + LDJ_DEVICE(0xb309), + .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, { /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ LDJ_DEVICE(0xb30b), .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, @@ -3802,6 +3884,9 @@ { /* MX5000 keyboard over Bluetooth */ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305), .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, + { /* Dinovo Edge keyboard over Bluetooth */ + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309), + .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, { /* MX5500 keyboard over Bluetooth */ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, --- linux-oracle-5.4.0.orig/drivers/hid/hid-magicmouse.c +++ linux-oracle-5.4.0/drivers/hid/hid-magicmouse.c @@ -387,7 +387,7 @@ magicmouse_raw_event(hdev, report, data + 2, data[1]); magicmouse_raw_event(hdev, report, data + 2 + data[1], size - 2 - data[1]); - break; + return 0; default: return 0; } @@ -535,6 +535,12 @@ __set_bit(MSC_RAW, input->mscbit); } + /* + * hid-input may mark device as using autorepeat, but neither + * the trackpad, nor the mouse actually want it. + */ + __clear_bit(EV_REP, input->evbit); + return 0; } @@ -591,7 +597,7 @@ if (id->vendor == USB_VENDOR_ID_APPLE && id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && hdev->type != HID_TYPE_USBMOUSE) - return 0; + return -ENODEV; msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); if (msc == NULL) { --- linux-oracle-5.4.0.orig/drivers/hid/hid-mf.c +++ linux-oracle-5.4.0/drivers/hid/hid-mf.c @@ -153,6 +153,8 @@ .driver_data = HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2), .driver_data = 0 }, /* No quirk required */ + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), + .driver_data = HID_QUIRK_MULTI_INPUT }, { } }; MODULE_DEVICE_TABLE(hid, mf_devices); --- linux-oracle-5.4.0.orig/drivers/hid/hid-microsoft.c +++ linux-oracle-5.4.0/drivers/hid/hid-microsoft.c @@ -449,7 +449,18 @@ .driver_data = MS_PRESENTER }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B), .driver_data = MS_SURFACE_DIAL }, - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER), + + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE), + .driver_data = MS_QUIRK_FF }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS), .driver_data = MS_QUIRK_FF }, { } }; --- linux-oracle-5.4.0.orig/drivers/hid/hid-multitouch.c +++ linux-oracle-5.4.0/drivers/hid/hid-multitouch.c @@ -69,6 +69,7 @@ #define MT_QUIRK_ASUS_CUSTOM_UP BIT(17) #define MT_QUIRK_WIN8_PTP_BUTTONS BIT(18) #define MT_QUIRK_SEPARATE_APP_REPORT BIT(19) +#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) #define MT_INPUTMODE_TOUCHSCREEN 0x02 #define MT_INPUTMODE_TOUCHPAD 0x03 @@ -189,6 +190,7 @@ #define MT_CLS_WIN_8 0x0012 #define MT_CLS_EXPORT_ALL_INPUTS 0x0013 #define MT_CLS_WIN_8_DUAL 0x0014 +#define MT_CLS_WIN_8_FORCE_MULTI_INPUT 0x0015 /* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -279,6 +281,15 @@ MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_WIN8_PTP_BUTTONS, .export_all_inputs = true }, + { .name = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_IGNORE_DUPLICATES | + MT_QUIRK_HOVERING | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_STICKY_FINGERS | + MT_QUIRK_WIN8_PTP_BUTTONS | + MT_QUIRK_FORCE_MULTI_INPUT, + .export_all_inputs = true }, /* * vendor specific classes @@ -600,9 +611,13 @@ if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) continue; - for (n = 0; n < field->report_count; n++) { - if (field->usage[n].hid == HID_DG_CONTACTID) - rdata->is_mt_collection = true; + if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) { + for (n = 0; n < field->report_count; n++) { + if (field->usage[n].hid == HID_DG_CONTACTID) { + rdata->is_mt_collection = true; + break; + } + } } } @@ -853,6 +868,8 @@ code = BTN_0 + ((usage->hid - 1) & HID_USAGE); hid_map_usage(hi, usage, bit, max, EV_KEY, code); + if (!*bit) + return -1; input_set_capability(hi->input, EV_KEY, code); return 1; @@ -1019,7 +1036,7 @@ tool = MT_TOOL_DIAL; else if (unlikely(!confidence_state)) { tool = MT_TOOL_PALM; - if (!active && + if (!active && mt && input_mt_is_active(&mt->slots[slotnum])) { /* * The non-confidence was reported for @@ -1145,7 +1162,7 @@ int contact_count = -1; /* sticky fingers release in progress, abort */ - if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) return; scantime = *app->scantime; @@ -1226,7 +1243,7 @@ del_timer(&td->release_timer); } - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } static int mt_touch_input_configured(struct hid_device *hdev, @@ -1531,7 +1548,6 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) { struct mt_device *td = hid_get_drvdata(hdev); - char *name; const char *suffix = NULL; struct mt_report_data *rdata; struct mt_application *mt_application = NULL; @@ -1570,13 +1586,13 @@ /* we do not set suffix = "Touchscreen" */ hi->input->name = hdev->name; break; - case HID_DG_STYLUS: - /* force BTN_STYLUS to allow tablet matching in udev */ - __set_bit(BTN_STYLUS, hi->input->keybit); - break; case HID_VD_ASUS_CUSTOM_MEDIA_KEYS: suffix = "Custom Media Keys"; break; + case HID_DG_STYLUS: + /* force BTN_STYLUS to allow tablet matching in udev */ + __set_bit(BTN_STYLUS, hi->input->keybit); + fallthrough; case HID_DG_PEN: suffix = "Stylus"; break; @@ -1586,13 +1602,10 @@ } if (suffix) { - name = devm_kzalloc(&hi->input->dev, - strlen(hdev->name) + strlen(suffix) + 2, - GFP_KERNEL); - if (name) { - sprintf(name, "%s %s", hdev->name, suffix); - hi->input->name = name; - } + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); + if (!hi->input->name) + return -ENOMEM; } return 0; @@ -1663,11 +1676,11 @@ * An input report came in just before we release the sticky fingers, * it will take care of the sticky fingers. */ - if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) return; if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) mt_release_contacts(hdev); - clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); } static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) @@ -1714,6 +1727,11 @@ if (id->group != HID_GROUP_MULTITOUCH_WIN_8) hdev->quirks |= HID_QUIRK_MULTI_INPUT; + if (mtclass->quirks & MT_QUIRK_FORCE_MULTI_INPUT) { + hdev->quirks &= ~HID_QUIRK_INPUT_PER_APP; + hdev->quirks |= HID_QUIRK_MULTI_INPUT; + } + timer_setup(&td->release_timer, mt_expired_timeout, 0); ret = hid_parse(hdev); @@ -1922,6 +1940,18 @@ { .driver_data = MT_CLS_EGALAX_SERIAL, MT_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, + { .driver_data = MT_CLS_EGALAX, + MT_USB_DEVICE(USB_VENDOR_ID_DWAV, + USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) }, + + /* Elan devices */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_ELAN, 0x313a) }, + + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_ELAN, 0x3148) }, /* Elitegroup panel */ { .driver_data = MT_CLS_SERIAL, @@ -1976,6 +2006,16 @@ MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, + /* HONOR GLO-GXXX panel */ + { .driver_data = MT_CLS_VTL, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + 0x347d, 0x7853) }, + + /* HONOR MagicBook Art 14 touchpad */ + { .driver_data = MT_CLS_VTL, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + 0x35cc, 0x0104) }, + /* Ilitek dual touch panel */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, @@ -1985,6 +2025,9 @@ { .driver_data = MT_CLS_LG, HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MELFAS_MT) }, + { .driver_data = MT_CLS_LG, + HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, + USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) }, /* MosArt panels */ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, @@ -2050,6 +2093,23 @@ MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM)}, + /* Synaptics devices */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xcd7e) }, + + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xcddc) }, + + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce08) }, + + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce09) }, + /* TopSeed panels */ { .driver_data = MT_CLS_TOPSEED, MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, @@ -2116,6 +2176,9 @@ { .driver_data = MT_CLS_GOOGLE, HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_TOUCH_ROSE) }, + { .driver_data = MT_CLS_GOOGLE, + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_GOOGLE, + USB_DEVICE_ID_GOOGLE_WHISKERS) }, /* Generic MT device */ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) }, --- linux-oracle-5.4.0.orig/drivers/hid/hid-plantronics.c +++ linux-oracle-5.4.0/drivers/hid/hid-plantronics.c @@ -13,6 +13,7 @@ #include #include +#include #define PLT_HID_1_0_PAGE 0xffa00000 #define PLT_HID_2_0_PAGE 0xffa20000 @@ -36,6 +37,18 @@ #define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \ (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) +#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) +#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1) + +#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ +#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */ + +struct plt_drv_data { + unsigned long device_type; + unsigned long last_volume_key_ts; + u32 quirks; +}; + static int plantronics_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, @@ -43,7 +56,8 @@ unsigned long **bit, int *max) { unsigned short mapped_key; - unsigned long plt_type = (unsigned long)hid_get_drvdata(hdev); + struct plt_drv_data *drv_data = hid_get_drvdata(hdev); + unsigned long plt_type = drv_data->device_type; /* special case for PTT products */ if (field->application == HID_GD_JOYSTICK) @@ -105,6 +119,45 @@ return 1; } +static int plantronics_event(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value) +{ + struct plt_drv_data *drv_data = hid_get_drvdata(hdev); + + if (drv_data->quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS) { + unsigned long prev_ts, cur_ts; + + /* Usages are filtered in plantronics_usages. */ + + if (!value) /* Handle key presses only. */ + return 0; + + prev_ts = drv_data->last_volume_key_ts; + cur_ts = jiffies; + if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_DOUBLE_KEY_TIMEOUT) + return 1; /* Ignore the repeated key. */ + + drv_data->last_volume_key_ts = cur_ts; + } + if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) { + unsigned long prev_ts, cur_ts; + + /* Usages are filtered in plantronics_usages. */ + + if (!value) /* Handle key presses only. */ + return 0; + + prev_ts = drv_data->last_volume_key_ts; + cur_ts = jiffies; + if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT) + return 1; /* Ignore the followed opposite volume key. */ + + drv_data->last_volume_key_ts = cur_ts; + } + + return 0; +} + static unsigned long plantronics_device_type(struct hid_device *hdev) { unsigned i, col_page; @@ -133,15 +186,24 @@ static int plantronics_probe(struct hid_device *hdev, const struct hid_device_id *id) { + struct plt_drv_data *drv_data; int ret; + drv_data = devm_kzalloc(&hdev->dev, sizeof(*drv_data), GFP_KERNEL); + if (!drv_data) + return -ENOMEM; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); goto err; } - hid_set_drvdata(hdev, (void *)plantronics_device_type(hdev)); + drv_data->device_type = plantronics_device_type(hdev); + drv_data->quirks = id->driver_data; + drv_data->last_volume_key_ts = jiffies - msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT); + + hid_set_drvdata(hdev, drv_data); ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDINPUT_FORCE | HID_CONNECT_HIDDEV_FORCE); @@ -153,15 +215,41 @@ } static const struct hid_device_id plantronics_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES), + .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES), + .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES), + .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), + .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES), + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, + USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES), + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, { } }; MODULE_DEVICE_TABLE(hid, plantronics_devices); +static const struct hid_usage_id plantronics_usages[] = { + { HID_CP_VOLUMEUP, EV_KEY, HID_ANY_ID }, + { HID_CP_VOLUMEDOWN, EV_KEY, HID_ANY_ID }, + { HID_TERMINATOR, HID_TERMINATOR, HID_TERMINATOR } +}; + static struct hid_driver plantronics_driver = { .name = "plantronics", .id_table = plantronics_devices, + .usage_table = plantronics_usages, .input_mapping = plantronics_input_mapping, + .event = plantronics_event, .probe = plantronics_probe, }; module_hid_driver(plantronics_driver); --- linux-oracle-5.4.0.orig/drivers/hid/hid-prodikeys.c +++ linux-oracle-5.4.0/drivers/hid/hid-prodikeys.c @@ -798,12 +798,18 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *intf; + unsigned short ifnum; unsigned long quirks = id->driver_data; struct pk_device *pk; struct pcmidi_snd *pm = NULL; + if (!hid_is_usb(hdev)) + return -EINVAL; + + intf = to_usb_interface(hdev->dev.parent); + ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + pk = kzalloc(sizeof(*pk), GFP_KERNEL); if (pk == NULL) { hid_err(hdev, "can't alloc descriptor\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-quirks.c +++ linux-oracle-5.4.0/drivers/hid/hid-quirks.c @@ -33,6 +33,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET }, @@ -66,12 +67,14 @@ { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_STRAFE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_PRO_WIRELESS_KM5221W), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, @@ -83,17 +86,25 @@ { HID_USB_DEVICE(USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_FUTABA, USB_DEVICE_ID_LED_DISPLAY), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD), HID_QUIRK_MULTI_INPUT }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_GV186), + HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_GAMEVICE, USB_DEVICE_ID_GAMEVICE_KISHI), + HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0941), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_1f4a), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6680), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X), HID_QUIRK_MULTI_INPUT }, @@ -102,6 +113,11 @@ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, @@ -109,8 +125,10 @@ { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C05A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C06A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_MCS, USB_DEVICE_ID_MCS_GAMEPADBLOCK), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_MOUSE_0783), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PIXART_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE3_COVER), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_SURFACE_PRO_2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), HID_QUIRK_NO_INIT_REPORTS }, @@ -132,6 +150,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4D22), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_MOUSE_4E2A), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D0F), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4D65), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_PIXART_MOUSE_4E22), HID_QUIRK_ALWAYS_POLL }, @@ -144,6 +163,9 @@ { HID_USB_DEVICE(USB_VENDOR_ID_RETROUSB, USB_DEVICE_ID_RETROUSB_SNES_RETROPORT), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD), HID_QUIRK_BADPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET }, @@ -161,18 +183,23 @@ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DELL_K12A), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD), HID_QUIRK_BADPAD }, { HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_TRUST, USB_DEVICE_ID_TRUST_PANORA_TABLET), HID_QUIRK_MULTI_INPUT | HID_QUIRK_HIDINPUT_FORCE }, { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET }, { 0 } }; @@ -281,6 +308,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021) }, #endif #if IS_ENABLED(CONFIG_HID_APPLEIR) { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) }, @@ -395,9 +423,6 @@ { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2) }, #endif -#if IS_ENABLED(CONFIG_HID_ITE) - { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, -#endif #if IS_ENABLED(CONFIG_HID_ICADE) { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) }, #endif @@ -477,6 +502,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) }, #endif #if IS_ENABLED(CONFIG_HID_MICROSOFT) { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, @@ -595,6 +621,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) }, { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7) }, #endif #if IS_ENABLED(CONFIG_HID_SAMSUNG) { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, @@ -837,6 +864,7 @@ { HID_USB_DEVICE(USB_VENDOR_ID_PETZL, USB_DEVICE_ID_PETZL_HEADLAMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAI, USB_DEVICE_ID_CYPRESS_HIDCOM) }, #if IS_ENABLED(CONFIG_MOUSE_SYNAPTICS_USB) { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) }, { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) }, --- linux-oracle-5.4.0.orig/drivers/hid/hid-rmi.c +++ linux-oracle-5.4.0/drivers/hid/hid-rmi.c @@ -744,7 +744,8 @@ { struct rmi_data *hdata = hid_get_drvdata(hdev); - if (hdata->device_flags & RMI_DEVICE) { + if ((hdata->device_flags & RMI_DEVICE) + && test_bit(RMI_STARTED, &hdata->flags)) { clear_bit(RMI_STARTED, &hdata->flags); cancel_work_sync(&hdata->reset_work); rmi_unregister_transport_device(&hdata->xport); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-arvo.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-arvo.c @@ -344,6 +344,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-isku.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-isku.c @@ -324,6 +324,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-kone.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-kone.c @@ -294,31 +294,40 @@ struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev)); struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); int retval = 0, difference, old_profile; + struct kone_settings *settings = (struct kone_settings *)buf; /* I need to get my data in one piece */ if (off != 0 || count != sizeof(struct kone_settings)) return -EINVAL; mutex_lock(&kone->kone_lock); - difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings)); + difference = memcmp(settings, &kone->settings, + sizeof(struct kone_settings)); if (difference) { - retval = kone_set_settings(usb_dev, - (struct kone_settings const *)buf); - if (retval) { - mutex_unlock(&kone->kone_lock); - return retval; + if (settings->startup_profile < 1 || + settings->startup_profile > 5) { + retval = -EINVAL; + goto unlock; } + retval = kone_set_settings(usb_dev, settings); + if (retval) + goto unlock; + old_profile = kone->settings.startup_profile; - memcpy(&kone->settings, buf, sizeof(struct kone_settings)); + memcpy(&kone->settings, settings, sizeof(struct kone_settings)); kone_profile_activated(kone, kone->settings.startup_profile); if (kone->settings.startup_profile != old_profile) kone_profile_report(kone, kone->settings.startup_profile); } +unlock: mutex_unlock(&kone->kone_lock); + if (retval) + return retval; + return sizeof(struct kone_settings); } static BIN_ATTR(settings, 0660, kone_sysfs_read_settings, @@ -740,6 +749,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-koneplus.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-koneplus.c @@ -431,6 +431,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-konepure.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-konepure.c @@ -133,6 +133,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-kovaplus.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-kovaplus.c @@ -501,6 +501,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-lua.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-lua.c @@ -160,6 +160,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-pyra.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-pyra.c @@ -449,6 +449,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-ryos.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-ryos.c @@ -141,6 +141,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat-savu.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat-savu.c @@ -113,6 +113,9 @@ { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-roccat.c +++ linux-oracle-5.4.0/drivers/hid/hid-roccat.c @@ -257,6 +257,8 @@ if (!new_value) return -ENOMEM; + mutex_lock(&device->cbuf_lock); + report = &device->cbuf[device->cbuf_end]; /* passing NULL is safe */ @@ -276,6 +278,8 @@ reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE; } + mutex_unlock(&device->cbuf_lock); + wake_up_interruptible(&device->wait); return 0; } --- linux-oracle-5.4.0.orig/drivers/hid/hid-saitek.c +++ linux-oracle-5.4.0/drivers/hid/hid-saitek.c @@ -187,6 +187,8 @@ .driver_data = SAITEK_RELEASE_MODE_RAT7 }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7), .driver_data = SAITEK_RELEASE_MODE_MMO7 }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_MMO7), + .driver_data = SAITEK_RELEASE_MODE_MMO7 }, { } }; --- linux-oracle-5.4.0.orig/drivers/hid/hid-samsung.c +++ linux-oracle-5.4.0/drivers/hid/hid-samsung.c @@ -152,6 +152,9 @@ int ret; unsigned int cmask = HID_CONNECT_DEFAULT; + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); --- linux-oracle-5.4.0.orig/drivers/hid/hid-sensor-custom.c +++ linux-oracle-5.4.0/drivers/hid/hid-sensor-custom.c @@ -59,7 +59,7 @@ u32 raw_len; } __packed; -static struct attribute hid_custom_attrs[] = { +static struct attribute hid_custom_attrs[HID_CUSTOM_TOTAL_ATTRS] = { {.name = "name", .mode = S_IRUGO}, {.name = "units", .mode = S_IRUGO}, {.name = "unit-expo", .mode = S_IRUGO}, --- linux-oracle-5.4.0.orig/drivers/hid/hid-sensor-hub.c +++ linux-oracle-5.4.0/drivers/hid/hid-sensor-hub.c @@ -210,16 +210,21 @@ buffer_size = buffer_size / sizeof(__s32); if (buffer_size) { for (i = 0; i < buffer_size; ++i) { - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(*buf32)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(*buf32)); + if (ret) + goto done_proc; + ++buf32; } } if (remaining_bytes) { value = 0; memcpy(&value, (u8 *)buf32, remaining_bytes); - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(value)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(value)); + if (ret) + goto done_proc; } hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); hid_hw_wait(hsdev->hdev); @@ -483,7 +488,8 @@ return 1; ptr = raw_data; - ptr++; /* Skip report id */ + if (report->id) + ptr++; /* Skip report id */ spin_lock_irqsave(&pdata->lock, flags); @@ -724,23 +730,30 @@ return ret; } +static int sensor_hub_finalize_pending_fn(struct device *dev, void *data) +{ + struct hid_sensor_hub_device *hsdev = dev->platform_data; + + if (hsdev->pending.status) + complete(&hsdev->pending.ready); + + return 0; +} + static void sensor_hub_remove(struct hid_device *hdev) { struct sensor_hub_data *data = hid_get_drvdata(hdev); unsigned long flags; - int i; hid_dbg(hdev, " hardware removed\n"); hid_hw_close(hdev); hid_hw_stop(hdev); + spin_lock_irqsave(&data->lock, flags); - for (i = 0; i < data->hid_sensor_client_cnt; ++i) { - struct hid_sensor_hub_device *hsdev = - data->hid_sensor_hub_client_devs[i].platform_data; - if (hsdev->pending.status) - complete(&hsdev->pending.ready); - } + device_for_each_child(&hdev->dev, NULL, + sensor_hub_finalize_pending_fn); spin_unlock_irqrestore(&data->lock, flags); + mfd_remove_devices(&hdev->dev); mutex_destroy(&data->mutex); } --- linux-oracle-5.4.0.orig/drivers/hid/hid-sony.c +++ linux-oracle-5.4.0/drivers/hid/hid-sony.c @@ -867,6 +867,23 @@ if (sc->quirks & PS3REMOTE) return ps3remote_fixup(hdev, rdesc, rsize); + /* + * Some knock-off USB dongles incorrectly report their button count + * as 13 instead of 16 causing three non-functional buttons. + */ + if ((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize >= 45 && + /* Report Count (13) */ + rdesc[23] == 0x95 && rdesc[24] == 0x0D && + /* Usage Maximum (13) */ + rdesc[37] == 0x29 && rdesc[38] == 0x0D && + /* Report Count (3) */ + rdesc[43] == 0x95 && rdesc[44] == 0x03) { + hid_info(hdev, "Fixing up USB dongle report descriptor\n"); + rdesc[24] = 0x10; + rdesc[38] = 0x10; + rdesc[44] = 0x00; + } + return rdesc; } @@ -1580,16 +1597,38 @@ * of the controller, so that it sends input reports of type 0x11. */ if (sc->quirks & (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_DONGLE)) { + int retries; + buf = kmalloc(DS4_FEATURE_REPORT_0x02_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = hid_hw_raw_request(sc->hdev, 0x02, buf, - DS4_FEATURE_REPORT_0x02_SIZE, - HID_FEATURE_REPORT, - HID_REQ_GET_REPORT); - if (ret < 0) - goto err_stop; + /* We should normally receive the feature report data we asked + * for, but hidraw applications such as Steam can issue feature + * reports as well. In particular for Dongle reconnects, Steam + * and this function are competing resulting in often receiving + * data for a different HID report, so retry a few times. + */ + for (retries = 0; retries < 3; retries++) { + ret = hid_hw_raw_request(sc->hdev, 0x02, buf, + DS4_FEATURE_REPORT_0x02_SIZE, + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + if (ret < 0) + goto err_stop; + + if (buf[0] != 0x02) { + if (retries < 2) { + hid_warn(sc->hdev, "Retrying DualShock 4 get calibration report (0x02) request\n"); + continue; + } else { + ret = -EILSEQ; + goto err_stop; + } + } else { + break; + } + } } else { u8 bthdr = 0xA3; u32 crc; --- linux-oracle-5.4.0.orig/drivers/hid/hid-steam.c +++ linux-oracle-5.4.0/drivers/hid/hid-steam.c @@ -134,6 +134,11 @@ int ret; r = steam->hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0]; + if (!r) { + hid_err(steam->hdev, "No HID_FEATURE_REPORT submitted - nothing to read\n"); + return -EINVAL; + } + if (hid_report_len(r) < 64) return -EINVAL; @@ -165,6 +170,11 @@ int ret; r = steam->hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[0]; + if (!r) { + hid_err(steam->hdev, "No HID_FEATURE_REPORT submitted - nothing to read\n"); + return -EINVAL; + } + if (hid_report_len(r) < 64) return -EINVAL; @@ -526,7 +536,8 @@ steam_battery_register(steam); mutex_lock(&steam_devices_lock); - list_add(&steam->list, &steam_devices); + if (list_empty(&steam->list)) + list_add(&steam->list, &steam_devices); mutex_unlock(&steam_devices_lock); } @@ -552,7 +563,7 @@ hid_info(steam->hdev, "Steam Controller '%s' disconnected", steam->serial_no); mutex_lock(&steam_devices_lock); - list_del(&steam->list); + list_del_init(&steam->list); mutex_unlock(&steam_devices_lock); steam->serial_no[0] = 0; } @@ -738,6 +749,7 @@ mutex_init(&steam->mutex); steam->quirks = id->driver_data; INIT_WORK(&steam->work_connect, steam_work_connect_cb); + INIT_LIST_HEAD(&steam->list); steam->client_hdev = steam_create_client_hid(hdev); if (IS_ERR(steam->client_hdev)) { @@ -768,8 +780,12 @@ if (steam->quirks & STEAM_QUIRK_WIRELESS) { hid_info(hdev, "Steam wireless receiver connected"); + /* If using a wireless adaptor ask for connection status */ + steam->connected = false; steam_request_conn_status(steam); } else { + /* A wired connection is always present */ + steam->connected = true; ret = steam_register(steam); if (ret) { hid_err(hdev, --- linux-oracle-5.4.0.orig/drivers/hid/hid-u2fzero.c +++ linux-oracle-5.4.0/drivers/hid/hid-u2fzero.c @@ -132,7 +132,7 @@ ret = (wait_for_completion_timeout( &ctx.done, msecs_to_jiffies(USB_CTRL_SET_TIMEOUT))); - if (ret < 0) { + if (ret == 0) { usb_kill_urb(dev->urb); hid_err(hdev, "urb submission timed out"); } else { @@ -191,6 +191,8 @@ struct u2f_hid_msg resp; int ret; size_t actual_length; + /* valid packets must have a correct header */ + int min_length = offsetof(struct u2f_hid_msg, init.data); if (!dev->present) { hid_dbg(dev->hdev, "device not present"); @@ -198,12 +200,14 @@ } ret = u2fzero_recv(dev, &req, &resp); - if (ret < 0) + + /* ignore errors or packets without data */ + if (ret < min_length) return 0; /* only take the minimum amount of data it is safe to take */ - actual_length = min3((size_t)ret - offsetof(struct u2f_hid_msg, - init.data), U2F_HID_MSG_LEN(resp), max); + actual_length = min3((size_t)ret - min_length, + U2F_HID_MSG_LEN(resp), max); memcpy(data, resp.init.data, actual_length); @@ -286,7 +290,7 @@ unsigned int minor; int ret; - if (!hid_is_using_ll_driver(hdev, &usb_hid_driver)) + if (!hid_is_usb(hdev)) return -EINVAL; dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/hid/hid-uclogic-core.c +++ linux-oracle-5.4.0/drivers/hid/hid-uclogic-core.c @@ -164,11 +164,15 @@ struct uclogic_drvdata *drvdata = NULL; bool params_initialized = false; + if (!hid_is_usb(hdev)) + return -EINVAL; + /* * libinput requires the pad interface to be on a different node * than the pen, so use QUIRK_MULTI_INPUT for all tablets. */ hdev->quirks |= HID_QUIRK_MULTI_INPUT; + hdev->quirks |= HID_QUIRK_HIDINPUT_FORCE; /* Allocate and assign driver data */ drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); @@ -385,6 +389,8 @@ USB_DEVICE_ID_UCLOGIC_DRAWIMAGE_G3) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610) }, + { HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, + USB_DEVICE_ID_UGTIZER_TABLET_GT5040) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_TABLET_G5) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, --- linux-oracle-5.4.0.orig/drivers/hid/hid-uclogic-params.c +++ linux-oracle-5.4.0/drivers/hid/hid-uclogic-params.c @@ -65,7 +65,7 @@ __u8 idx, size_t len) { int rc; - struct usb_device *udev = hid_to_usb_dev(hdev); + struct usb_device *udev; __u8 *buf = NULL; /* Check arguments */ @@ -74,6 +74,8 @@ goto cleanup; } + udev = hid_to_usb_dev(hdev); + buf = kmalloc(len, GFP_KERNEL); if (buf == NULL) { rc = -ENOMEM; @@ -449,7 +451,7 @@ { int rc; bool found = false; - struct usb_device *usb_dev = hid_to_usb_dev(hdev); + struct usb_device *usb_dev; char *str_buf = NULL; const size_t str_len = 16; @@ -459,6 +461,8 @@ goto cleanup; } + usb_dev = hid_to_usb_dev(hdev); + /* * Enable generic button mode */ @@ -705,9 +709,9 @@ struct hid_device *hdev) { int rc; - struct usb_device *udev = hid_to_usb_dev(hdev); - struct usb_interface *iface = to_usb_interface(hdev->dev.parent); - __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; + struct usb_device *udev; + struct usb_interface *iface; + __u8 bInterfaceNumber; bool found; /* The resulting parameters (noop) */ struct uclogic_params p = {0, }; @@ -721,6 +725,10 @@ goto cleanup; } + udev = hid_to_usb_dev(hdev); + iface = to_usb_interface(hdev->dev.parent); + bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; + /* If it's not a pen interface */ if (bInterfaceNumber != 0) { /* TODO: Consider marking the interface invalid */ @@ -832,21 +840,25 @@ struct hid_device *hdev) { int rc; - struct usb_device *udev = hid_to_usb_dev(hdev); - __u8 bNumInterfaces = udev->config->desc.bNumInterfaces; - struct usb_interface *iface = to_usb_interface(hdev->dev.parent); - __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; + struct usb_device *udev; + __u8 bNumInterfaces; + struct usb_interface *iface; + __u8 bInterfaceNumber; bool found; /* The resulting parameters (noop) */ struct uclogic_params p = {0, }; /* Check arguments */ - if (params == NULL || hdev == NULL || - !hid_is_using_ll_driver(hdev, &usb_hid_driver)) { + if (params == NULL || hdev == NULL || !hid_is_usb(hdev)) { rc = -EINVAL; goto cleanup; } + udev = hid_to_usb_dev(hdev); + bNumInterfaces = udev->config->desc.bNumInterfaces; + iface = to_usb_interface(hdev->dev.parent); + bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; + /* * Set replacement report descriptor if the original matches the * specified size. Otherwise keep interface unchanged. @@ -997,6 +1009,8 @@ break; case VID_PID(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_GP0610): + case VID_PID(USB_VENDOR_ID_UGTIZER, + USB_DEVICE_ID_UGTIZER_TABLET_GT5040): case VID_PID(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540): case VID_PID(USB_VENDOR_ID_UGEE, --- linux-oracle-5.4.0.orig/drivers/hid/hidraw.c +++ linux-oracle-5.4.0/drivers/hid/hidraw.c @@ -249,13 +249,14 @@ static __poll_t hidraw_poll(struct file *file, poll_table *wait) { struct hidraw_list *list = file->private_data; + __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* hidraw is always writable */ poll_wait(file, &list->hidraw->wait, wait); if (list->head != list->tail) - return EPOLLIN | EPOLLRDNORM | EPOLLOUT; + mask |= EPOLLIN | EPOLLRDNORM; if (!list->hidraw->exist) - return EPOLLERR | EPOLLHUP; - return 0; + mask |= EPOLLERR | EPOLLHUP; + return mask; } static int hidraw_open(struct inode *inode, struct file *file) @@ -345,10 +346,13 @@ unsigned int minor = iminor(inode); struct hidraw_list *list = file->private_data; unsigned long flags; + int i; mutex_lock(&minors_lock); spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags); + for (i = list->tail; i < list->head; i++) + kfree(list->buffer[i].value); list_del(&list->node); spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); kfree(list); --- linux-oracle-5.4.0.orig/drivers/hid/i2c-hid/i2c-hid-core.c +++ linux-oracle-5.4.0/drivers/hid/i2c-hid/i2c-hid-core.c @@ -48,11 +48,14 @@ #define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) #define I2C_HID_QUIRK_NO_IRQ_AFTER_RESET BIT(1) #define I2C_HID_QUIRK_BOGUS_IRQ BIT(4) +#define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5) +#define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6) +#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(7) + /* flags */ #define I2C_HID_STARTED 0 #define I2C_HID_RESET_PENDING 1 -#define I2C_HID_READ_PENDING 2 #define I2C_HID_PWR_ON 0x00 #define I2C_HID_PWR_SLEEP 0x01 @@ -170,7 +173,21 @@ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { I2C_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { USB_VENDOR_ID_ALPS_JP, HID_ANY_ID, + I2C_HID_QUIRK_RESET_ON_RESUME }, + { I2C_VENDOR_ID_SYNAPTICS, I2C_PRODUCT_ID_SYNAPTICS_SYNA2393, + I2C_HID_QUIRK_RESET_ON_RESUME }, + { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720, + I2C_HID_QUIRK_BAD_INPUT_SIZE }, + /* + * Sending the wakeup after reset actually break ELAN touchscreen controller + */ { USB_VENDOR_ID_ELAN, HID_ANY_ID, + I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | I2C_HID_QUIRK_BOGUS_IRQ }, { 0, 0 } }; @@ -240,7 +257,6 @@ msg[1].len = data_len; msg[1].buf = buf_recv; msg_num = 2; - set_bit(I2C_HID_READ_PENDING, &ihid->flags); } if (wait) @@ -248,9 +264,6 @@ ret = i2c_transfer(client->adapter, msg, msg_num); - if (data_len > 0) - clear_bit(I2C_HID_READ_PENDING, &ihid->flags); - if (ret != msg_num) return ret < 0 ? ret : -EIO; @@ -411,6 +424,19 @@ dev_err(&client->dev, "failed to change power setting.\n"); set_pwr_exit: + + /* + * The HID over I2C specification states that if a DEVICE needs time + * after the PWR_ON request, it should utilise CLOCK stretching. + * However, it has been observered that the Windows driver provides a + * 1ms sleep between the PWR_ON and RESET requests. + * According to Goodix Windows even waits 60 ms after (other?) + * PWR_ON requests. Testing has confirmed that several devices + * will not work properly without a delay after a PWR_ON request. + */ + if (!ret && power_state == I2C_HID_PWR_ON) + msleep(60); + return ret; } @@ -432,15 +458,6 @@ if (ret) goto out_unlock; - /* - * The HID over I2C specification states that if a DEVICE needs time - * after the PWR_ON request, it should utilise CLOCK stretching. - * However, it has been observered that the Windows driver provides a - * 1ms sleep between the PWR_ON and RESET requests and that some devices - * rely on this. - */ - usleep_range(1000, 5000); - i2c_hid_dbg(ihid, "resetting...\n"); ret = i2c_hid_command(client, &hid_reset_cmd, NULL, 0); @@ -451,7 +468,8 @@ } /* At least some SIS devices need this after reset */ - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET)) + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); out_unlock: mutex_unlock(&ihid->reset_lock); @@ -493,9 +511,15 @@ } if ((ret_size > size) || (ret_size < 2)) { - dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", - __func__, size, ret_size); - return; + if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) { + ihid->inbuf[0] = size & 0xff; + ihid->inbuf[1] = size >> 8; + ret_size = size; + } else { + dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n", + __func__, size, ret_size); + return; + } } i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf); @@ -511,9 +535,6 @@ { struct i2c_hid *ihid = dev_id; - if (test_bit(I2C_HID_READ_PENDING, &ihid->flags)) - return IRQ_HANDLED; - i2c_hid_get_input(ihid); return IRQ_HANDLED; @@ -593,6 +614,17 @@ if (report_type == HID_OUTPUT_REPORT) return -EINVAL; + /* + * In case of unnumbered reports the response from the device will + * not have the report ID that the upper layers expect, so we need + * to stash it the buffer ourselves and adjust the data size. + */ + if (!report_number) { + buf[0] = 0; + buf++; + count--; + } + /* +2 bytes to include the size of the reply in the query buffer */ ask_count = min(count + 2, (size_t)ihid->bufsize); @@ -614,6 +646,9 @@ count = min(count, ret_count - 2); memcpy(buf, ihid->rawbuf + 2, count); + if (!report_number) + count++; + return count; } @@ -630,17 +665,19 @@ mutex_lock(&ihid->reset_lock); - if (report_id) { - buf++; - count--; - } - + /* + * Note that both numbered and unnumbered reports passed here + * are supposed to have report ID stored in the 1st byte of the + * buffer, so we strip it off unconditionally before passing payload + * to i2c_hid_set_or_send_report which takes care of encoding + * everything properly. + */ ret = i2c_hid_set_or_send_report(client, report_type == HID_FEATURE_REPORT ? 0x03 : 0x02, - report_id, buf, count, use_data); + report_id, buf + 1, count - 1, use_data); - if (report_id && ret >= 0) - ret++; /* add report_id to the number of transfered bytes */ + if (ret >= 0) + ret++; /* add report_id to the number of transferred bytes */ mutex_unlock(&ihid->reset_lock); @@ -1091,8 +1128,8 @@ hid->vendor = le16_to_cpu(ihid->hdesc.wVendorID); hid->product = le16_to_cpu(ihid->hdesc.wProductID); - snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", - client->name, hid->vendor, hid->product); + snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", + client->name, (u16)hid->vendor, (u16)hid->product); strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); @@ -1212,8 +1249,15 @@ * solves "incomplete reports" on Raydium devices 2386:3118 and * 2386:4B33 and fixes various SIS touchscreens no longer sending * data after a suspend/resume. + * + * However some ALPS touchpads generate IRQ storm without reset, so + * let's still reset them here. */ - ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + if (ihid->quirks & I2C_HID_QUIRK_RESET_ON_RESUME) + ret = i2c_hid_hwreset(client); + else + ret = i2c_hid_set_power(client, I2C_HID_PWR_ON); + if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ linux-oracle-5.4.0/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -342,6 +342,14 @@ .driver_data = (void *)&sipodev_desc }, { + .ident = "Trekstor SURFBOOK E11B", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), + }, + .driver_data = (void *)&sipodev_desc + }, + { .ident = "Direkt-Tek DTLAPY116-2", .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Direkt-Tek"), @@ -366,6 +374,14 @@ .driver_data = (void *)&sipodev_desc }, { + .ident = "Mediacom FlexBook edge 13", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "FlexBook_edge13-M-FBE13"), + }, + .driver_data = (void *)&sipodev_desc + }, + { .ident = "Odys Winbook 13", .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AXDIA International GmbH"), @@ -381,6 +397,22 @@ }, .driver_data = (void *)&sipodev_desc }, + { + .ident = "Schneider SCL142ALM", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"), + }, + .driver_data = (void *)&sipodev_desc + }, + { + .ident = "Vero K147", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VERO"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "K147"), + }, + .driver_data = (void *)&sipodev_desc + }, { } /* Terminate list */ }; --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ipc/hw-ish.h +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ipc/hw-ish.h @@ -24,7 +24,10 @@ #define ICL_MOBILE_DEVICE_ID 0x34FC #define SPT_H_DEVICE_ID 0xA135 #define CML_LP_DEVICE_ID 0x02FC +#define CMP_H_DEVICE_ID 0x06FC #define EHL_Ax_DEVICE_ID 0x4BB3 +#define TGL_LP_DEVICE_ID 0xA0FC +#define TGL_H_DEVICE_ID 0x43FC #define REVISION_ID_CHT_A0 0x6 #define REVISION_ID_CHT_Ax_SI 0x0 --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -34,7 +34,10 @@ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ICL_MOBILE_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CML_LP_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CMP_H_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_LP_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_H_DEVICE_ID)}, {0, } }; MODULE_DEVICE_TABLE(pci, ish_pci_tbl); @@ -157,6 +160,11 @@ /* request and enable interrupt */ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES); + if (ret < 0) { + dev_err(dev, "ISH: Failed to allocate IRQ vectors\n"); + return ret; + } + if (!pdev->msi_enabled && !pdev->msix_enabled) irq_flag = IRQF_SHARED; --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -480,6 +480,7 @@ sizeof(ldr_xfer_query_resp)); if (rv < 0) { client_data->flag_retry = true; + *fw_info = (struct shim_fw_info){}; return rv; } @@ -489,6 +490,7 @@ "data size %d is not equal to size of loader_xfer_query_response %zu\n", rv, sizeof(struct loader_xfer_query_response)); client_data->flag_retry = true; + *fw_info = (struct shim_fw_info){}; return -EMSGSIZE; } @@ -628,7 +630,7 @@ const struct firmware *fw, const struct shim_fw_info fw_info) { - int rv; + int rv = 0; void *dma_buf; dma_addr_t dma_buf_phy; u32 fragment_offset, fragment_size, payload_max_size; @@ -654,21 +656,12 @@ */ payload_max_size &= ~(L1_CACHE_BYTES - 1); - dma_buf = kmalloc(payload_max_size, GFP_KERNEL | GFP_DMA32); + dma_buf = dma_alloc_coherent(devc, payload_max_size, &dma_buf_phy, GFP_KERNEL); if (!dma_buf) { client_data->flag_retry = true; return -ENOMEM; } - dma_buf_phy = dma_map_single(devc, dma_buf, payload_max_size, - DMA_TO_DEVICE); - if (dma_mapping_error(devc, dma_buf_phy)) { - dev_err(cl_data_to_dev(client_data), "DMA map failed\n"); - client_data->flag_retry = true; - rv = -ENOMEM; - goto end_err_dma_buf_release; - } - ldr_xfer_dma_frag.fragment.hdr.command = LOADER_CMD_XFER_FRAGMENT; ldr_xfer_dma_frag.fragment.xfer_mode = LOADER_XFER_MODE_DIRECT_DMA; ldr_xfer_dma_frag.ddr_phys_addr = (u64)dma_buf_phy; @@ -688,14 +681,7 @@ ldr_xfer_dma_frag.fragment.size = fragment_size; memcpy(dma_buf, &fw->data[fragment_offset], fragment_size); - dma_sync_single_for_device(devc, dma_buf_phy, - payload_max_size, - DMA_TO_DEVICE); - - /* - * Flush cache here because the dma_sync_single_for_device() - * does not do for x86. - */ + /* Flush cache to be sure the data is in main memory. */ clflush_cache_range(dma_buf, payload_max_size); dev_dbg(cl_data_to_dev(client_data), @@ -718,15 +704,8 @@ fragment_offset += fragment_size; } - dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE); - kfree(dma_buf); - return 0; - end_err_resp_buf_release: - /* Free ISH buffer if not done already, in error case */ - dma_unmap_single(devc, dma_buf_phy, payload_max_size, DMA_TO_DEVICE); -end_err_dma_buf_release: - kfree(dma_buf); + dma_free_coherent(devc, payload_max_size, dma_buf, dma_buf_phy); return rv; } --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ishtp-hid.c +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ishtp-hid.c @@ -263,12 +263,14 @@ */ void ishtp_hid_remove(struct ishtp_cl_data *client_data) { + void *data; int i; for (i = 0; i < client_data->num_hid_devices; ++i) { if (client_data->hid_sensor_hubs[i]) { - kfree(client_data->hid_sensor_hubs[i]->driver_data); + data = client_data->hid_sensor_hubs[i]->driver_data; hid_destroy_device(client_data->hid_sensor_hubs[i]); + kfree(data); client_data->hid_sensor_hubs[i] = NULL; } } --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ishtp-hid.h +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ishtp-hid.h @@ -110,7 +110,7 @@ * @multi_packet_cnt: Count of fragmented packet count * * This structure is used to store completion flags and per client data like - * like report description, number of HID devices etc. + * report description, number of HID devices etc. */ struct ishtp_cl_data { /* completion flags */ --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ishtp/client.c +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ishtp/client.c @@ -626,13 +626,14 @@ } /** - * ipc_tx_callback() - IPC tx callback function + * ipc_tx_send() - IPC tx send function * @prm: Pointer to client device instance * - * Send message over IPC either first time or on callback on previous message - * completion + * Send message over IPC. Message will be split into fragments + * if message size is bigger than IPC FIFO size, and all + * fragments will be sent one by one. */ -static void ipc_tx_callback(void *prm) +static void ipc_tx_send(void *prm) { struct ishtp_cl *cl = prm; struct ishtp_cl_tx_ring *cl_msg; @@ -677,32 +678,41 @@ list); rem = cl_msg->send_buf.size - cl->tx_offs; - ishtp_hdr.host_addr = cl->host_client_id; - ishtp_hdr.fw_addr = cl->fw_client_id; - ishtp_hdr.reserved = 0; - pmsg = cl_msg->send_buf.data + cl->tx_offs; - - if (rem <= dev->mtu) { - ishtp_hdr.length = rem; - ishtp_hdr.msg_complete = 1; - cl->sending = 0; - list_del_init(&cl_msg->list); /* Must be before write */ - spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); - /* Submit to IPC queue with no callback */ - ishtp_write_message(dev, &ishtp_hdr, pmsg); - spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); - list_add_tail(&cl_msg->list, &cl->tx_free_list.list); - ++cl->tx_ring_free_size; - spin_unlock_irqrestore(&cl->tx_free_list_spinlock, - tx_free_flags); - } else { - /* Send IPC fragment */ - spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); - cl->tx_offs += dev->mtu; - ishtp_hdr.length = dev->mtu; - ishtp_hdr.msg_complete = 0; - ishtp_send_msg(dev, &ishtp_hdr, pmsg, ipc_tx_callback, cl); + while (rem > 0) { + ishtp_hdr.host_addr = cl->host_client_id; + ishtp_hdr.fw_addr = cl->fw_client_id; + ishtp_hdr.reserved = 0; + pmsg = cl_msg->send_buf.data + cl->tx_offs; + + if (rem <= dev->mtu) { + /* Last fragment or only one packet */ + ishtp_hdr.length = rem; + ishtp_hdr.msg_complete = 1; + /* Submit to IPC queue with no callback */ + ishtp_write_message(dev, &ishtp_hdr, pmsg); + cl->tx_offs = 0; + cl->sending = 0; + + break; + } else { + /* Send ipc fragment */ + ishtp_hdr.length = dev->mtu; + ishtp_hdr.msg_complete = 0; + /* All fregments submitted to IPC queue with no callback */ + ishtp_write_message(dev, &ishtp_hdr, pmsg); + cl->tx_offs += dev->mtu; + rem = cl_msg->send_buf.size - cl->tx_offs; + } } + + list_del_init(&cl_msg->list); + spin_unlock_irqrestore(&cl->tx_list_spinlock, tx_flags); + + spin_lock_irqsave(&cl->tx_free_list_spinlock, tx_free_flags); + list_add_tail(&cl_msg->list, &cl->tx_free_list.list); + ++cl->tx_ring_free_size; + spin_unlock_irqrestore(&cl->tx_free_list_spinlock, + tx_free_flags); } /** @@ -720,7 +730,7 @@ return; cl->tx_offs = 0; - ipc_tx_callback(cl); + ipc_tx_send(cl); ++cl->send_msg_cnt_ipc; } --- linux-oracle-5.4.0.orig/drivers/hid/intel-ish-hid/ishtp/dma-if.c +++ linux-oracle-5.4.0/drivers/hid/intel-ish-hid/ishtp/dma-if.c @@ -104,6 +104,11 @@ int required_slots = (size / DMA_SLOT_SIZE) + 1 * (size % DMA_SLOT_SIZE != 0); + if (!dev->ishtp_dma_tx_map) { + dev_err(dev->devc, "Fail to allocate Tx map\n"); + return NULL; + } + spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) { free = 1; @@ -150,6 +155,11 @@ return; } + if (!dev->ishtp_dma_tx_map) { + dev_err(dev->devc, "Fail to allocate Tx map\n"); + return; + } + i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE; spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); for (j = 0; j < acked_slots; j++) { --- linux-oracle-5.4.0.orig/drivers/hid/uhid.c +++ linux-oracle-5.4.0/drivers/hid/uhid.c @@ -28,11 +28,22 @@ struct uhid_device { struct mutex devlock; + + /* This flag tracks whether the HID device is usable for commands from + * userspace. The flag is already set before hid_add_device(), which + * runs in workqueue context, to allow hid_add_device() to communicate + * with userspace. + * However, if hid_add_device() fails, the flag is cleared without + * holding devlock. + * We guarantee that if @running changes from true to false while you're + * holding @devlock, it's still fine to access @hid. + */ bool running; __u8 *rd_data; uint rd_size; + /* When this is NULL, userspace may use UHID_CREATE/UHID_CREATE2. */ struct hid_device *hid; struct uhid_event input_buf; @@ -63,9 +74,18 @@ if (ret) { hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret); - hid_destroy_device(uhid->hid); - uhid->hid = NULL; + /* We used to call hid_destroy_device() here, but that's really + * messy to get right because we have to coordinate with + * concurrent writes from userspace that might be in the middle + * of using uhid->hid. + * Just leave uhid->hid as-is for now, and clean it up when + * userspace tries to close or reinitialize the uhid instance. + * + * However, we do have to clear the ->running flag and do a + * wakeup to make sure userspace knows that the device is gone. + */ uhid->running = false; + wake_up_interruptible(&uhid->report_wait); } } @@ -375,6 +395,7 @@ .parse = uhid_hid_parse, .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, + .max_buffer_size = UHID_DATA_MAX, }; EXPORT_SYMBOL_GPL(uhid_hid_driver); @@ -474,7 +495,7 @@ void *rd_data; int ret; - if (uhid->running) + if (uhid->hid) return -EALREADY; rd_size = ev->u.create2.rd_size; @@ -556,7 +577,7 @@ static int uhid_dev_destroy(struct uhid_device *uhid) { - if (!uhid->running) + if (!uhid->hid) return -EINVAL; uhid->running = false; @@ -565,6 +586,7 @@ cancel_work_sync(&uhid->worker); hid_destroy_device(uhid->hid); + uhid->hid = NULL; kfree(uhid->rd_data); return 0; @@ -766,13 +788,14 @@ static __poll_t uhid_char_poll(struct file *file, poll_table *wait) { struct uhid_device *uhid = file->private_data; + __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uhid is always writable */ poll_wait(file, &uhid->waitq, wait); if (uhid->head != uhid->tail) - return EPOLLIN | EPOLLRDNORM; + mask |= EPOLLIN | EPOLLRDNORM; - return 0; + return mask; } static const struct file_operations uhid_fops = { --- linux-oracle-5.4.0.orig/drivers/hid/usbhid/hid-core.c +++ linux-oracle-5.4.0/drivers/hid/usbhid/hid-core.c @@ -374,7 +374,7 @@ raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); + len = hid_report_len(report); if (dir == USB_DIR_OUT) { usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); usbhid->urbctrl->transfer_buffer_length = len; @@ -503,7 +503,7 @@ if (unplug) { usbhid->ctrltail = usbhid->ctrlhead; - } else { + } else if (usbhid->ctrlhead != usbhid->ctrltail) { usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); if (usbhid->ctrlhead != usbhid->ctrltail && @@ -682,16 +682,21 @@ struct usbhid_device *usbhid = hid->driver_data; int res; + mutex_lock(&usbhid->mutex); + set_bit(HID_OPENED, &usbhid->iofl); - if (hid->quirks & HID_QUIRK_ALWAYS_POLL) - return 0; + if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { + res = 0; + goto Done; + } res = usb_autopm_get_interface(usbhid->intf); /* the device must be awake to reliably request remote wakeup */ if (res < 0) { clear_bit(HID_OPENED, &usbhid->iofl); - return -EIO; + res = -EIO; + goto Done; } usbhid->intf->needs_remote_wakeup = 1; @@ -725,6 +730,9 @@ msleep(50); clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); + + Done: + mutex_unlock(&usbhid->mutex); return res; } @@ -732,6 +740,8 @@ { struct usbhid_device *usbhid = hid->driver_data; + mutex_lock(&usbhid->mutex); + /* * Make sure we don't restart data acquisition due to * a resumption we no longer care about by avoiding racing @@ -743,12 +753,13 @@ clear_bit(HID_IN_POLLING, &usbhid->iofl); spin_unlock_irq(&usbhid->lock); - if (hid->quirks & HID_QUIRK_ALWAYS_POLL) - return; + if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) { + hid_cancel_delayed_stuff(usbhid); + usb_kill_urb(usbhid->urbin); + usbhid->intf->needs_remote_wakeup = 0; + } - hid_cancel_delayed_stuff(usbhid); - usb_kill_urb(usbhid->urbin); - usbhid->intf->needs_remote_wakeup = 0; + mutex_unlock(&usbhid->mutex); } /* @@ -1057,6 +1068,8 @@ unsigned int n, insize = 0; int ret; + mutex_lock(&usbhid->mutex); + clear_bit(HID_DISCONNECTED, &usbhid->iofl); usbhid->bufsize = HID_MIN_BUFFER_SIZE; @@ -1177,6 +1190,8 @@ usbhid_set_leds(hid); device_set_wakeup_enable(&dev->dev, 1); } + + mutex_unlock(&usbhid->mutex); return 0; fail: @@ -1187,6 +1202,7 @@ usbhid->urbout = NULL; usbhid->urbctrl = NULL; hid_free_buffers(dev, hid); + mutex_unlock(&usbhid->mutex); return ret; } @@ -1202,10 +1218,23 @@ usbhid->intf->needs_remote_wakeup = 0; } + mutex_lock(&usbhid->mutex); + clear_bit(HID_STARTED, &usbhid->iofl); + spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */ set_bit(HID_DISCONNECTED, &usbhid->iofl); + while (usbhid->ctrltail != usbhid->ctrlhead) { + if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_OUT) { + kfree(usbhid->ctrl[usbhid->ctrltail].raw_report); + usbhid->ctrl[usbhid->ctrltail].raw_report = NULL; + } + + usbhid->ctrltail = (usbhid->ctrltail + 1) & + (HID_CONTROL_FIFO_SIZE - 1); + } spin_unlock_irq(&usbhid->lock); + usb_kill_urb(usbhid->urbin); usb_kill_urb(usbhid->urbout); usb_kill_urb(usbhid->urbctrl); @@ -1222,6 +1251,8 @@ usbhid->urbout = NULL; hid_free_buffers(hid_to_usb_dev(hid), hid); + + mutex_unlock(&usbhid->mutex); } static int usbhid_power(struct hid_device *hid, int lvl) @@ -1382,6 +1413,7 @@ INIT_WORK(&usbhid->reset_work, hid_reset); timer_setup(&usbhid->io_retry, hid_retry_timeout, 0); spin_lock_init(&usbhid->lock); + mutex_init(&usbhid->mutex); ret = hid_add_device(hid); if (ret) { --- linux-oracle-5.4.0.orig/drivers/hid/usbhid/hid-pidff.c +++ linux-oracle-5.4.0/drivers/hid/usbhid/hid-pidff.c @@ -1292,6 +1292,7 @@ if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { + error = -EPERM; hid_notice(hid, "device does not support device managed pool\n"); goto fail; --- linux-oracle-5.4.0.orig/drivers/hid/usbhid/hiddev.c +++ linux-oracle-5.4.0/drivers/hid/usbhid/hiddev.c @@ -241,12 +241,51 @@ return 0; } +static int __hiddev_open(struct hiddev *hiddev, struct file *file) +{ + struct hiddev_list *list; + int error; + + lockdep_assert_held(&hiddev->existancelock); + + list = vzalloc(sizeof(*list)); + if (!list) + return -ENOMEM; + + mutex_init(&list->thread_lock); + list->hiddev = hiddev; + + if (!hiddev->open++) { + error = hid_hw_power(hiddev->hid, PM_HINT_FULLON); + if (error < 0) + goto err_drop_count; + + error = hid_hw_open(hiddev->hid); + if (error < 0) + goto err_normal_power; + } + + spin_lock_irq(&hiddev->list_lock); + list_add_tail(&list->node, &hiddev->list); + spin_unlock_irq(&hiddev->list_lock); + + file->private_data = list; + + return 0; + +err_normal_power: + hid_hw_power(hiddev->hid, PM_HINT_NORMAL); +err_drop_count: + hiddev->open--; + vfree(list); + return error; +} + /* * open file op */ static int hiddev_open(struct inode *inode, struct file *file) { - struct hiddev_list *list; struct usb_interface *intf; struct hid_device *hid; struct hiddev *hiddev; @@ -255,66 +294,14 @@ intf = usbhid_find_interface(iminor(inode)); if (!intf) return -ENODEV; + hid = usb_get_intfdata(intf); hiddev = hid->hiddev; - if (!(list = vzalloc(sizeof(struct hiddev_list)))) - return -ENOMEM; - mutex_init(&list->thread_lock); - list->hiddev = hiddev; - file->private_data = list; - - /* - * no need for locking because the USB major number - * is shared which usbcore guards against disconnect - */ - if (list->hiddev->exist) { - if (!list->hiddev->open++) { - res = hid_hw_open(hiddev->hid); - if (res < 0) - goto bail; - } - } else { - res = -ENODEV; - goto bail; - } - - spin_lock_irq(&list->hiddev->list_lock); - list_add_tail(&list->node, &hiddev->list); - spin_unlock_irq(&list->hiddev->list_lock); - mutex_lock(&hiddev->existancelock); - /* - * recheck exist with existance lock held to - * avoid opening a disconnected device - */ - if (!list->hiddev->exist) { - res = -ENODEV; - goto bail_unlock; - } - if (!list->hiddev->open++) - if (list->hiddev->exist) { - struct hid_device *hid = hiddev->hid; - res = hid_hw_power(hid, PM_HINT_FULLON); - if (res < 0) - goto bail_unlock; - res = hid_hw_open(hid); - if (res < 0) - goto bail_normal_power; - } - mutex_unlock(&hiddev->existancelock); - return 0; -bail_normal_power: - hid_hw_power(hid, PM_HINT_NORMAL); -bail_unlock: + res = hiddev->exist ? __hiddev_open(hiddev, file) : -ENODEV; mutex_unlock(&hiddev->existancelock); - spin_lock_irq(&list->hiddev->list_lock); - list_del(&list->node); - spin_unlock_irq(&list->hiddev->list_lock); -bail: - file->private_data = NULL; - vfree(list); return res; } @@ -532,12 +519,16 @@ switch (cmd) { case HIDIOCGUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; uref->value = field->value[uref->usage_index]; if (copy_to_user(user_arg, uref, sizeof(*uref))) goto fault; goto goodreturn; case HIDIOCSUSAGE: + if (uref->usage_index >= field->report_count) + goto inval; field->value[uref->usage_index] = uref->value; goto goodreturn; @@ -954,9 +945,9 @@ hiddev->exist = 0; if (hiddev->open) { - mutex_unlock(&hiddev->existancelock); hid_hw_close(hiddev->hid); wake_up_interruptible(&hiddev->wait); + mutex_unlock(&hiddev->existancelock); } else { mutex_unlock(&hiddev->existancelock); kfree(hiddev); --- linux-oracle-5.4.0.orig/drivers/hid/usbhid/usbhid.h +++ linux-oracle-5.4.0/drivers/hid/usbhid/usbhid.h @@ -80,6 +80,7 @@ dma_addr_t outbuf_dma; /* Output buffer dma */ unsigned long last_out; /* record of last output for timeouts */ + struct mutex mutex; /* start/stop/open/close */ spinlock_t lock; /* fifo spinlock */ unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ struct timer_list io_retry; /* Retry timer */ --- linux-oracle-5.4.0.orig/drivers/hid/wacom.h +++ linux-oracle-5.4.0/drivers/hid/wacom.h @@ -91,6 +91,7 @@ #include #include #include +#include #include /* @@ -152,6 +153,7 @@ struct input_dev *input; bool registered; struct wacom_battery battery; + ktime_t active_time; } remotes[WACOM_MAX_REMOTES]; }; @@ -167,6 +169,7 @@ struct delayed_work init_work; struct wacom_remote *remote; struct work_struct mode_change_work; + struct timer_list idleprox_timer; bool generic_has_leds; struct wacom_leds { struct wacom_group_leds *groups; @@ -239,4 +242,5 @@ struct wacom_led *wacom_led_next(struct wacom *wacom, struct wacom_led *cur); int wacom_equivalent_usage(int usage); int wacom_initialize_leds(struct wacom *wacom); +void wacom_idleprox_timeout(struct timer_list *list); #endif --- linux-oracle-5.4.0.orig/drivers/hid/wacom_sys.c +++ linux-oracle-5.4.0/drivers/hid/wacom_sys.c @@ -147,9 +147,9 @@ } if (flush) - wacom_wac_queue_flush(hdev, &wacom_wac->pen_fifo); + wacom_wac_queue_flush(hdev, wacom_wac->pen_fifo); else if (insert) - wacom_wac_queue_insert(hdev, &wacom_wac->pen_fifo, + wacom_wac_queue_insert(hdev, wacom_wac->pen_fifo, raw_data, report_size); return insert && !flush; @@ -160,6 +160,9 @@ { struct wacom *wacom = hid_get_drvdata(hdev); + if (wacom->wacom_wac.features.type == BOOTLOADER) + return 0; + if (size > WACOM_PKGLEN_MAX) return 1; @@ -319,9 +322,11 @@ data[0] = field->report->id; ret = wacom_get_report(hdev, HID_FEATURE_REPORT, data, n, WAC_CMD_RETRIES); - if (ret == n) { + if (ret == n && features->type == HID_GENERIC) { ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, data, n, 0); + } else if (ret == 2 && features->type != HID_GENERIC) { + features->touch_max = data[1]; } else { features->touch_max = 16; hid_warn(hdev, "wacom_feature_mapping: " @@ -724,7 +729,7 @@ * Skip the query for this type and modify defaults based on * interface number. */ - if (features->type == WIRELESS) { + if (features->type == WIRELESS && intf) { if (intf->cur_altsetting->desc.bInterfaceNumber == 0) features->device_type = WACOM_DEVICETYPE_WL_MONITOR; else @@ -1268,6 +1273,38 @@ group); } +static void wacom_devm_kfifo_release(struct device *dev, void *res) +{ + struct kfifo_rec_ptr_2 *devres = res; + + kfifo_free(devres); +} + +static int wacom_devm_kfifo_alloc(struct wacom *wacom) +{ + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct kfifo_rec_ptr_2 *pen_fifo; + int error; + + pen_fifo = devres_alloc(wacom_devm_kfifo_release, + sizeof(struct kfifo_rec_ptr_2), + GFP_KERNEL); + + if (!pen_fifo) + return -ENOMEM; + + error = kfifo_alloc(pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); + if (error) { + devres_free(pen_fifo); + return error; + } + + devres_add(&wacom->hdev->dev, pen_fifo); + wacom_wac->pen_fifo = pen_fifo; + + return 0; +} + enum led_brightness wacom_leds_brightness_get(struct wacom_led *led) { struct wacom *wacom = led->wacom; @@ -2051,7 +2088,7 @@ return 0; } -static int wacom_register_inputs(struct wacom *wacom) +static int wacom_setup_inputs(struct wacom *wacom) { struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; struct wacom_wac *wacom_wac = &(wacom->wacom_wac); @@ -2070,10 +2107,6 @@ input_free_device(pen_input_dev); wacom_wac->pen_input = NULL; pen_input_dev = NULL; - } else { - error = input_register_device(pen_input_dev); - if (error) - goto fail; } error = wacom_setup_touch_input_capabilities(touch_input_dev, wacom_wac); @@ -2082,19 +2115,42 @@ input_free_device(touch_input_dev); wacom_wac->touch_input = NULL; touch_input_dev = NULL; - } else { - error = input_register_device(touch_input_dev); - if (error) - goto fail; } error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac); if (error) { - /* no pad in use on this interface */ + /* no pad events using this interface */ input_free_device(pad_input_dev); wacom_wac->pad_input = NULL; pad_input_dev = NULL; - } else { + } + + return 0; +} + +static int wacom_register_inputs(struct wacom *wacom) +{ + struct input_dev *pen_input_dev, *touch_input_dev, *pad_input_dev; + struct wacom_wac *wacom_wac = &(wacom->wacom_wac); + int error = 0; + + pen_input_dev = wacom_wac->pen_input; + touch_input_dev = wacom_wac->touch_input; + pad_input_dev = wacom_wac->pad_input; + + if (pen_input_dev) { + error = input_register_device(pen_input_dev); + if (error) + goto fail; + } + + if (touch_input_dev) { + error = input_register_device(touch_input_dev); + if (error) + goto fail; + } + + if (pad_input_dev) { error = input_register_device(pad_input_dev); if (error) goto fail; @@ -2183,10 +2239,11 @@ if ((features->type == HID_GENERIC) && !strcmp("Wacom HID", features->name)) { char *product_name = wacom->hdev->name; - if (hid_is_using_ll_driver(wacom->hdev, &usb_hid_driver)) { + if (hid_is_usb(wacom->hdev)) { struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent); struct usb_device *dev = interface_to_usbdev(intf); - product_name = dev->product; + if (dev->product != NULL) + product_name = dev->product; } if (wacom->hdev->bus == BUS_I2C) { @@ -2344,6 +2401,20 @@ goto fail; } + error = wacom_setup_inputs(wacom); + if (error) + goto fail; + + if (features->type == HID_GENERIC) + connect_mask |= HID_CONNECT_DRIVER; + + /* Regular HID work starts now */ + error = hid_hw_start(hdev, connect_mask); + if (error) { + hid_err(hdev, "hw start failed\n"); + goto fail; + } + error = wacom_register_inputs(wacom); if (error) goto fail; @@ -2358,16 +2429,6 @@ goto fail; } - if (features->type == HID_GENERIC) - connect_mask |= HID_CONNECT_DRIVER; - - /* Regular HID work starts now */ - error = hid_hw_start(hdev, connect_mask); - if (error) { - hid_err(hdev, "hw start failed\n"); - goto fail; - } - if (!wireless) { /* Note that if query fails it is not a hard failure */ wacom_query_tablet_data(wacom); @@ -2382,8 +2443,13 @@ goto fail_quirks; } - if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) + if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) { error = hid_hw_open(hdev); + if (error) { + hid_err(hdev, "hw open failed\n"); + goto fail_quirks; + } + } wacom_set_shared_values(wacom_wac); devres_close_group(&hdev->dev, wacom); @@ -2414,6 +2480,9 @@ wacom_destroy_battery(wacom); + if (!usbdev) + return; + /* Stylus interface */ hdev1 = usb_get_intfdata(usbdev->config->interface[1]); wacom1 = hid_get_drvdata(hdev1); @@ -2484,6 +2553,18 @@ return; } +static void wacom_remote_destroy_battery(struct wacom *wacom, int index) +{ + struct wacom_remote *remote = wacom->remote; + + if (remote->remotes[index].battery.battery) { + devres_release_group(&wacom->hdev->dev, + &remote->remotes[index].battery.bat_desc); + remote->remotes[index].battery.battery = NULL; + remote->remotes[index].active_time = 0; + } +} + static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) { struct wacom_remote *remote = wacom->remote; @@ -2498,9 +2579,7 @@ remote->remotes[i].registered = false; spin_unlock_irqrestore(&remote->remote_lock, flags); - if (remote->remotes[i].battery.battery) - devres_release_group(&wacom->hdev->dev, - &remote->remotes[i].battery.bat_desc); + wacom_remote_destroy_battery(wacom, i); if (remote->remotes[i].group.name) devres_release_group(&wacom->hdev->dev, @@ -2508,7 +2587,6 @@ remote->remotes[i].serial = 0; remote->remotes[i].group.name = NULL; - remote->remotes[i].battery.battery = NULL; wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN; } } @@ -2593,6 +2671,9 @@ if (remote->remotes[index].battery.battery) return 0; + if (!remote->remotes[index].active_time) + return 0; + if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN) return 0; @@ -2608,6 +2689,7 @@ { struct wacom *wacom = container_of(work, struct wacom, remote_work); struct wacom_remote *remote = wacom->remote; + ktime_t kt = ktime_get(); struct wacom_remote_data data; unsigned long flags; unsigned int count; @@ -2634,6 +2716,10 @@ serial = data.remote[i].serial; if (data.remote[i].connected) { + if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT + && remote->remotes[i].active_time != 0) + wacom_remote_destroy_battery(wacom, i); + if (remote->remotes[i].serial == serial) { wacom_remote_attach_battery(wacom, i); continue; @@ -2693,8 +2779,6 @@ static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *dev = interface_to_usbdev(intf); struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; @@ -2722,21 +2806,28 @@ if (features->check_for_hid_type && features->hid_type != hdev->type) return -ENODEV; - error = kfifo_alloc(&wacom_wac->pen_fifo, WACOM_PKGLEN_MAX, GFP_KERNEL); + error = wacom_devm_kfifo_alloc(wacom); if (error) return error; wacom_wac->hid_data.inputmode = -1; wacom_wac->mode_report = -1; - wacom->usbdev = dev; - wacom->intf = intf; + if (hid_is_usb(hdev)) { + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *dev = interface_to_usbdev(intf); + + wacom->usbdev = dev; + wacom->intf = intf; + } + mutex_init(&wacom->lock); INIT_DELAYED_WORK(&wacom->init_work, wacom_init_work); INIT_WORK(&wacom->wireless_work, wacom_wireless_work); INIT_WORK(&wacom->battery_work, wacom_battery_work); INIT_WORK(&wacom->remote_work, wacom_remote_work); INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work); + timer_setup(&wacom->idleprox_timer, &wacom_idleprox_timeout, TIMER_DEFERRABLE); /* ask for the report descriptor to be loaded by HID */ error = hid_parse(hdev); @@ -2745,6 +2836,11 @@ return error; } + if (features->type == BOOTLOADER) { + hid_warn(hdev, "Using device in hidraw-only mode"); + return hid_hw_start(hdev, HID_CONNECT_HIDRAW); + } + error = wacom_parse_and_register(wacom, false); if (error) return error; @@ -2776,6 +2872,7 @@ cancel_work_sync(&wacom->battery_work); cancel_work_sync(&wacom->remote_work); cancel_work_sync(&wacom->mode_change_work); + del_timer_sync(&wacom->idleprox_timer); if (hdev->bus == BUS_BLUETOOTH) device_remove_file(&hdev->dev, &dev_attr_speed); @@ -2784,8 +2881,6 @@ if (wacom->wacom_wac.features.type != REMOTE) wacom_release_resources(wacom); - - kfifo_free(&wacom_wac->pen_fifo); } #ifdef CONFIG_PM --- linux-oracle-5.4.0.orig/drivers/hid/wacom_wac.c +++ linux-oracle-5.4.0/drivers/hid/wacom_wac.c @@ -11,6 +11,7 @@ #include "wacom_wac.h" #include "wacom.h" #include +#include /* resolution for penabled devices */ #define WACOM_PL_RES 20 @@ -41,6 +42,43 @@ static void wacom_update_led(struct wacom *wacom, int button_count, int mask, int group); + +static void wacom_force_proxout(struct wacom_wac *wacom_wac) +{ + struct input_dev *input = wacom_wac->pen_input; + + wacom_wac->shared->stylus_in_proximity = 0; + + input_report_key(input, BTN_TOUCH, 0); + input_report_key(input, BTN_STYLUS, 0); + input_report_key(input, BTN_STYLUS2, 0); + input_report_key(input, BTN_STYLUS3, 0); + input_report_key(input, wacom_wac->tool[0], 0); + if (wacom_wac->serial[0]) { + input_report_abs(input, ABS_MISC, 0); + } + input_report_abs(input, ABS_PRESSURE, 0); + + wacom_wac->tool[0] = 0; + wacom_wac->id[0] = 0; + wacom_wac->serial[0] = 0; + + input_sync(input); +} + +void wacom_idleprox_timeout(struct timer_list *list) +{ + struct wacom *wacom = from_timer(wacom, list, idleprox_timer); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + + if (!wacom_wac->hid_data.sense_state) { + return; + } + + hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__); + wacom_force_proxout(wacom_wac); +} + /* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity. @@ -638,9 +676,26 @@ return (tool_id & ~0xFFF) << 4 | (tool_id & 0xFFF); } +static bool wacom_is_art_pen(int tool_id) +{ + bool is_art_pen = false; + + switch (tool_id) { + case 0x885: /* Intuos3 Marker Pen */ + case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ + case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */ + is_art_pen = true; + break; + } + return is_art_pen; +} + static int wacom_intuos_get_tool_type(int tool_id) { - int tool_type; + int tool_type = BTN_TOOL_PEN; + + if (wacom_is_art_pen(tool_id)) + return tool_type; switch (tool_id) { case 0x812: /* Inking pen */ @@ -655,17 +710,16 @@ case 0x852: case 0x823: /* Intuos3 Grip Pen */ case 0x813: /* Intuos3 Classic Pen */ - case 0x885: /* Intuos3 Marker Pen */ case 0x802: /* Intuos4/5 13HD/24HD General Pen */ - case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */ case 0x8e2: /* IntuosHT2 pen */ case 0x022: - case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */ + case 0x200: /* Pro Pen 3 */ case 0x10842: /* MobileStudio Pro Pro Pen slim */ case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */ case 0x16802: /* Cintiq 13HD Pro Pen */ case 0x18802: /* DTH2242 Pen */ case 0x10802: /* Intuos4/5 13HD/24HD General Pen */ + case 0x8842: /* Intuos Pro and Cintiq Pro 3D Pen */ tool_type = BTN_TOOL_PEN; break; @@ -718,10 +772,6 @@ case 0x10902: /* Intuos4/5 13HD/24HD Airbrush */ tool_type = BTN_TOOL_AIRBRUSH; break; - - default: /* Unknown tool */ - tool_type = BTN_TOOL_PEN; - break; } return tool_type; } @@ -780,7 +830,7 @@ /* Enter report */ if ((data[1] & 0xfc) == 0xc0) { /* serial number of the tool */ - wacom->serial[idx] = ((data[3] & 0x0f) << 28) + + wacom->serial[idx] = ((__u64)(data[3] & 0x0f) << 28) + (data[4] << 20) + (data[5] << 12) + (data[6] << 4) + (data[7] >> 4); @@ -1076,6 +1126,7 @@ if (index < 0 || !remote->remotes[index].registered) goto out; + remote->remotes[i].active_time = ktime_get(); input = remote->remotes[index].input; input_report_key(input, BTN_0, (data[9] & 0x01)); @@ -1255,6 +1306,9 @@ struct input_dev *pen_input = wacom->pen_input; unsigned char *data = wacom->data; + int number_of_valid_frames = 0; + ktime_t time_interval = 15000000; + ktime_t time_packet_received = ktime_get(); int i; if (wacom->features.type == INTUOSP2_BT || @@ -1275,12 +1329,30 @@ wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; } + /* number of valid frames */ for (i = 0; i < pen_frames; i++) { unsigned char *frame = &data[i*pen_frame_len + 1]; bool valid = frame[0] & 0x80; + + if (valid) + number_of_valid_frames++; + } + + if (number_of_valid_frames) { + if (wacom->hid_data.time_delayed) + time_interval = ktime_get() - wacom->hid_data.time_delayed; + time_interval = div_u64(time_interval, number_of_valid_frames); + wacom->hid_data.time_delayed = time_packet_received; + } + + for (i = 0; i < number_of_valid_frames; i++) { + unsigned char *frame = &data[i*pen_frame_len + 1]; + bool valid = frame[0] & 0x80; bool prox = frame[0] & 0x40; bool range = frame[0] & 0x20; bool invert = frame[0] & 0x10; + int frames_number_reversed = number_of_valid_frames - i - 1; + ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval; if (!valid) continue; @@ -1293,6 +1365,7 @@ wacom->tool[0] = 0; wacom->id[0] = 0; wacom->serial[0] = 0; + wacom->hid_data.time_delayed = 0; return; } @@ -1321,14 +1394,15 @@ rotation -= 1800; input_report_abs(pen_input, ABS_TILT_X, - (char)frame[7]); + (signed char)frame[7]); input_report_abs(pen_input, ABS_TILT_Y, - (char)frame[8]); + (signed char)frame[8]); input_report_abs(pen_input, ABS_Z, rotation); input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); } } + if (wacom->tool[0]) { input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); if (wacom->features.type == INTUOSP2_BT || @@ -1352,6 +1426,9 @@ wacom->shared->stylus_in_proximity = prox; + /* add timestamp to unpack the frames */ + input_set_timestamp(pen_input, event_timestamp); + input_sync(pen_input); } } @@ -1427,11 +1504,13 @@ { struct input_dev *pad_input = wacom->pad_input; unsigned char *data = wacom->data; + int nbuttons = wacom->features.numbered_buttons; - int buttons = data[282] | ((data[281] & 0x40) << 2); + int expresskeys = data[282]; + int center = (data[281] & 0x40) >> 6; int ring = data[285] & 0x7F; bool ringstatus = data[285] & 0x80; - bool prox = buttons || ringstatus; + bool prox = expresskeys || center || ringstatus; /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ ring = 71 - ring; @@ -1439,7 +1518,8 @@ if (ring > 71) ring -= 72; - wacom_report_numbered_buttons(pad_input, 9, buttons); + wacom_report_numbered_buttons(pad_input, nbuttons, + expresskeys | (center << (nbuttons - 1))); input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); @@ -1840,11 +1920,14 @@ int fmax = field->logical_maximum; unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); int resolution_code = code; + int resolution; if (equivalent_usage == HID_DG_TWIST) { resolution_code = ABS_RZ; } + resolution = hidinput_calc_abs_res(field, resolution_code); + if (equivalent_usage == HID_GD_X) { fmin += features->offset_left; fmax -= features->offset_right; @@ -1862,8 +1945,15 @@ switch (type) { case EV_ABS: input_set_abs_params(input, code, fmin, fmax, fuzz, 0); - input_abs_set_res(input, code, - hidinput_calc_abs_res(field, resolution_code)); + + /* older tablet may miss physical usage */ + if ((code == ABS_X || code == ABS_Y) && !resolution) { + resolution = WACOM_INTUOS_RES; + hid_warn(input, + "Wacom usage (%d) missing resolution \n", + code); + } + input_abs_set_res(input, code, resolution); break; case EV_KEY: input_set_capability(input, EV_KEY, code); @@ -1880,18 +1970,7 @@ static void wacom_wac_battery_usage_mapping(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage) { - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct wacom_features *features = &wacom_wac->features; - unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - - switch (equivalent_usage) { - case HID_DG_BATTERYSTRENGTH: - case WACOM_HID_WD_BATTERY_LEVEL: - case WACOM_HID_WD_BATTERY_CHARGING: - features->quirks |= WACOM_QUIRK_BATTERY; - break; - } + return; } static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field, @@ -1912,18 +1991,21 @@ wacom_wac->hid_data.bat_connected = 1; wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; } + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; break; case WACOM_HID_WD_BATTERY_LEVEL: value = value * 100 / (field->logical_maximum - field->logical_minimum); wacom_wac->hid_data.battery_capacity = value; wacom_wac->hid_data.bat_connected = 1; wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; break; case WACOM_HID_WD_BATTERY_CHARGING: wacom_wac->hid_data.bat_charging = value; wacom_wac->hid_data.ps_connected = value; wacom_wac->hid_data.bat_connected = 1; wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO; + wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY; break; } } @@ -1939,18 +2021,15 @@ { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct wacom_features *features = &wacom_wac->features; - if (features->quirks & WACOM_QUIRK_BATTERY) { - int status = wacom_wac->hid_data.bat_status; - int capacity = wacom_wac->hid_data.battery_capacity; - bool charging = wacom_wac->hid_data.bat_charging; - bool connected = wacom_wac->hid_data.bat_connected; - bool powered = wacom_wac->hid_data.ps_connected; + int status = wacom_wac->hid_data.bat_status; + int capacity = wacom_wac->hid_data.battery_capacity; + bool charging = wacom_wac->hid_data.bat_charging; + bool connected = wacom_wac->hid_data.bat_connected; + bool powered = wacom_wac->hid_data.ps_connected; - wacom_notify_battery(wacom_wac, status, capacity, charging, - connected, powered); - } + wacom_notify_battery(wacom_wac, status, capacity, charging, + connected, powered); } static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, @@ -2003,7 +2082,6 @@ wacom_wac->has_mute_touch_switch = true; usage->type = EV_SW; usage->code = SW_MUTE_DEVICE; - features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHSTRIP: wacom_map_usage(input, usage, field, EV_ABS, ABS_RX, 0); @@ -2083,6 +2161,30 @@ wacom_wac->hid_data.inrange_state |= value; } + /* Process touch switch state first since it is reported through touch interface, + * which is indepentent of pad interface. In the case when there are no other pad + * events, the pad interface will not even be created. + */ + if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) || + (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) { + if (wacom_wac->shared->touch_input) { + bool *is_touch_on = &wacom_wac->shared->is_touch_on; + + if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value) + *is_touch_on = !(*is_touch_on); + else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF) + *is_touch_on = value; + + input_report_switch(wacom_wac->shared->touch_input, + SW_MUTE_DEVICE, !(*is_touch_on)); + input_sync(wacom_wac->shared->touch_input); + } + return; + } + + if (!input) + return; + switch (equivalent_usage) { case WACOM_HID_WD_TOUCHRING: /* @@ -2096,14 +2198,16 @@ (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */ hdev->product == 0x392 || /* Intuos Pro 2 */ - hdev->product == 0x398 || hdev->product == 0x399)) { /* MobileStudio Pro */ + hdev->product == 0x398 || hdev->product == 0x399 || /* MobileStudio Pro */ + hdev->product == 0x3AA)) { /* MobileStudio Pro */ value = (field->logical_maximum - value); if (hdev->product == 0x357 || hdev->product == 0x358 || hdev->product == 0x392) value = wacom_offset_rotation(input, usage, value, 3, 16); else if (hdev->product == 0x34d || hdev->product == 0x34e || - hdev->product == 0x398 || hdev->product == 0x399) + hdev->product == 0x398 || hdev->product == 0x399 || + hdev->product == 0x3AA) value = wacom_offset_rotation(input, usage, value, 1, 2); } else { @@ -2116,22 +2220,6 @@ input_event(input, usage->type, usage->code, 0); break; - case WACOM_HID_WD_MUTE_DEVICE: - case WACOM_HID_WD_TOUCHONOFF: - if (wacom_wac->shared->touch_input) { - bool *is_touch_on = &wacom_wac->shared->is_touch_on; - - if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value) - *is_touch_on = !(*is_touch_on); - else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF) - *is_touch_on = value; - - input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, !(*is_touch_on)); - input_sync(wacom_wac->shared->touch_input); - } - break; - case WACOM_HID_WD_MODE_CHANGE: if (wacom_wac->is_direct_mode != value) { wacom_wac->is_direct_mode = value; @@ -2283,6 +2371,7 @@ value = field->logical_maximum - value; break; case HID_DG_INRANGE: + mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100)); wacom_wac->hid_data.inrange_state = value; if (!(features->quirks & WACOM_QUIRK_SENSE)) wacom_wac->hid_data.sense_state = value; @@ -2307,6 +2396,9 @@ } return; case HID_DG_TWIST: + /* don't modify the value if the pen doesn't support the feature */ + if (!wacom_is_art_pen(wacom_wac->id[0])) return; + /* * Userspace expects pen twist to have its zero point when * the buttons/finger is on the tablet's left. HID values @@ -2449,7 +2541,14 @@ wacom_wac->hid_data.tipswitch); input_report_key(input, wacom_wac->tool[0], sense); if (wacom_wac->serial[0]) { - input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); + /* + * xf86-input-wacom does not accept a serial number + * of '0'. Report the low 32 bits if possible, but + * if they are zero, report the upper ones instead. + */ + __u32 serial_lo = wacom_wac->serial[0] & 0xFFFFFFFFu; + __u32 serial_hi = wacom_wac->serial[0] >> 32; + input_event(input, EV_MSC, MSC_SERIAL, (int)(serial_lo ? serial_lo : serial_hi)); input_report_abs(input, ABS_MISC, sense ? id : 0); } @@ -2521,14 +2620,14 @@ { struct hid_data *hid_data = &wacom_wac->hid_data; bool mt = wacom_wac->features.touch_max > 1; - bool prox = hid_data->tipswitch && - report_touch_events(wacom_wac); + bool touch_down = hid_data->tipswitch && hid_data->confidence; + bool prox = touch_down && report_touch_events(wacom_wac); if (wacom_wac->shared->has_mute_touch_switch && !wacom_wac->shared->is_touch_on) { if (!wacom_wac->shared->touch_down) return; - prox = 0; + prox = false; } wacom_wac->hid_data.num_received++; @@ -2573,6 +2672,9 @@ return; switch (equivalent_usage) { + case HID_DG_CONFIDENCE: + wacom_wac->hid_data.confidence = value; + break; case HID_GD_X: wacom_wac->hid_data.x = value; break; @@ -2595,7 +2697,12 @@ wacom_wac->is_invalid_bt_frame = !value; return; case HID_DG_CONTACTMAX: - features->touch_max = value; + if (!features->touch_max) { + features->touch_max = value; + } else { + hid_warn(hdev, "%s: ignoring attempt to overwrite non-zero touch_max " + "%d -> %d\n", __func__, features->touch_max, value); + } return; } @@ -2615,6 +2722,12 @@ wacom_wac->is_invalid_bt_frame = false; + hid_data->confidence = true; + + hid_data->cc_report = 0; + hid_data->cc_index = -1; + hid_data->cc_value_index = -1; + for (i = 0; i < report->maxfield; i++) { struct hid_field *field = report->field[i]; int j; @@ -2635,9 +2748,28 @@ case HID_DG_TIPSWITCH: hid_data->last_slot_field = equivalent_usage; break; + case HID_DG_CONTACTCOUNT: + hid_data->cc_report = report->id; + hid_data->cc_index = i; + hid_data->cc_value_index = j; + break; } } } + + if (hid_data->cc_report != 0 && + hid_data->cc_index >= 0) { + struct hid_field *field = report->field[hid_data->cc_index]; + int value = field->value[hid_data->cc_value_index]; + if (value) { + hid_data->num_expected = value; + hid_data->num_received = 0; + } + } + else { + hid_data->num_expected = wacom_wac->features.touch_max; + hid_data->num_received = 0; + } } static void wacom_wac_finger_report(struct hid_device *hdev, @@ -2647,7 +2779,6 @@ struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; - struct hid_data *hid_data = &wacom_wac->hid_data; /* If more packets of data are expected, give us a chance to * process them rather than immediately syncing a partial @@ -2661,7 +2792,7 @@ input_sync(input); wacom_wac->hid_data.num_received = 0; - hid_data->num_expected = 0; + wacom_wac->hid_data.num_expected = 0; /* keep touch state for pen event */ wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); @@ -2702,7 +2833,7 @@ /* usage tests must precede field tests */ if (WACOM_BATTERY_USAGE(usage)) wacom_wac_battery_event(hdev, field, usage, value); - else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) + else if (WACOM_PAD_FIELD(field)) wacom_wac_pad_event(hdev, field, usage, value); else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_event(hdev, field, usage, value); @@ -2736,73 +2867,12 @@ } } -static void wacom_set_num_expected(struct hid_device *hdev, - struct hid_report *report, - int collection_index, - struct hid_field *field, - int field_index) -{ - struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct hid_data *hid_data = &wacom_wac->hid_data; - unsigned int original_collection_level = - hdev->collection[collection_index].level; - bool end_collection = false; - int i; - - if (hid_data->num_expected) - return; - - // find the contact count value for this segment - for (i = field_index; i < report->maxfield && !end_collection; i++) { - struct hid_field *field = report->field[i]; - unsigned int field_level = - hdev->collection[field->usage[0].collection_index].level; - unsigned int j; - - if (field_level != original_collection_level) - continue; - - for (j = 0; j < field->maxusage; j++) { - struct hid_usage *usage = &field->usage[j]; - - if (usage->collection_index != collection_index) { - end_collection = true; - break; - } - if (wacom_equivalent_usage(usage->hid) == HID_DG_CONTACTCOUNT) { - hid_data->cc_report = report->id; - hid_data->cc_index = i; - hid_data->cc_value_index = j; - - if (hid_data->cc_report != 0 && - hid_data->cc_index >= 0) { - - struct hid_field *field = - report->field[hid_data->cc_index]; - int value = - field->value[hid_data->cc_value_index]; - - if (value) - hid_data->num_expected = value; - } - } - } - } - - if (hid_data->cc_report == 0 || hid_data->cc_index < 0) - hid_data->num_expected = wacom_wac->features.touch_max; -} - static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, int collection_index, struct hid_field *field, int field_index) { struct wacom *wacom = hid_get_drvdata(hdev); - if (WACOM_FINGER_FIELD(field)) - wacom_set_num_expected(hdev, report, collection_index, field, - field_index); wacom_report_events(hdev, report, collection_index, field_index); /* @@ -2815,7 +2885,9 @@ if (report->type != HID_INPUT_REPORT) return -1; - if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) + if (WACOM_PAD_FIELD(field)) + return 0; + else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_report(hdev, report); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_report(hdev, report); @@ -3609,8 +3681,6 @@ { struct wacom_features *features = &wacom_wac->features; - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - if (!(features->device_type & WACOM_DEVICETYPE_PEN)) return -ENODEV; @@ -3625,6 +3695,7 @@ return 0; } + input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); __set_bit(BTN_TOUCH, input_dev->keybit); __set_bit(ABS_MISC, input_dev->absbit); @@ -3777,8 +3848,6 @@ { struct wacom_features *features = &wacom_wac->features; - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - if (!(features->device_type & WACOM_DEVICETYPE_TOUCH)) return -ENODEV; @@ -3791,6 +3860,7 @@ /* setup has already been done */ return 0; + input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); __set_bit(BTN_TOUCH, input_dev->keybit); if (features->touch_max == 1) { @@ -3866,7 +3936,7 @@ wacom_wac->shared->touch->product == 0xF6) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); - wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->has_mute_touch_switch = true; } /* fall through */ @@ -4752,10 +4822,23 @@ { "Wacom Intuos Pro S", 31920, 19950, 8191, 63, INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 10 }; +static const struct wacom_features wacom_features_0x3c6 = + { "Wacom Intuos BT S", 15200, 9500, 4095, 63, + INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; +static const struct wacom_features wacom_features_0x3c8 = + { "Wacom Intuos BT M", 21600, 13500, 4095, 63, + INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; +static const struct wacom_features wacom_features_0x3dd = + { "Wacom Intuos Pro S", 31920, 19950, 8191, 63, + INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, + .touch_max = 10 }; static const struct wacom_features wacom_features_HID_ANY_ID = { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID }; +static const struct wacom_features wacom_features_0x94 = + { "Wacom Bootloader", .type = BOOTLOADER }; + #define USB_DEVICE_WACOM(prod) \ HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ .driver_data = (kernel_ulong_t)&wacom_features_##prod @@ -4768,6 +4851,10 @@ HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ .driver_data = (kernel_ulong_t)&wacom_features_##prod +#define PCI_DEVICE_WACOM(prod) \ + HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\ + .driver_data = (kernel_ulong_t)&wacom_features_##prod + #define USB_DEVICE_LENOVO(prod) \ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \ .driver_data = (kernel_ulong_t)&wacom_features_##prod @@ -4829,6 +4916,7 @@ { USB_DEVICE_WACOM(0x84) }, { USB_DEVICE_WACOM(0x90) }, { USB_DEVICE_WACOM(0x93) }, + { USB_DEVICE_WACOM(0x94) }, { USB_DEVICE_WACOM(0x97) }, { USB_DEVICE_WACOM(0x9A) }, { USB_DEVICE_WACOM(0x9F) }, @@ -4925,6 +5013,9 @@ { USB_DEVICE_WACOM(0x37A) }, { USB_DEVICE_WACOM(0x37B) }, { BT_DEVICE_WACOM(0x393) }, + { BT_DEVICE_WACOM(0x3c6) }, + { BT_DEVICE_WACOM(0x3c8) }, + { BT_DEVICE_WACOM(0x3dd) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x4004) }, { USB_DEVICE_WACOM(0x5000) }, @@ -4933,6 +5024,7 @@ { USB_DEVICE_WACOM(HID_ANY_ID) }, { I2C_DEVICE_WACOM(HID_ANY_ID) }, + { PCI_DEVICE_WACOM(HID_ANY_ID) }, { BT_DEVICE_WACOM(HID_ANY_ID) }, { } }; --- linux-oracle-5.4.0.orig/drivers/hid/wacom_wac.h +++ linux-oracle-5.4.0/drivers/hid/wacom_wac.h @@ -15,6 +15,7 @@ #define WACOM_NAME_MAX 64 #define WACOM_MAX_REMOTES 5 #define WACOM_STATUS_UNKNOWN 255 +#define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll /* packet length for individual models */ #define WACOM_PKGLEN_BBFUN 9 @@ -122,7 +123,7 @@ #define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454) #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) -#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) +#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0940) #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) @@ -242,6 +243,7 @@ MTTPC, MTTPC_B, HID_GENERIC, + BOOTLOADER, MAX_TYPE }; @@ -300,6 +302,7 @@ bool tipswitch; bool barrelswitch; bool barrelswitch2; + bool confidence; int x; int y; int pressure; @@ -318,6 +321,7 @@ int bat_connected; int ps_connected; bool pad_input_event_flag; + ktime_t time_delayed; }; struct wacom_remote_data { @@ -342,7 +346,7 @@ struct input_dev *pen_input; struct input_dev *touch_input; struct input_dev *pad_input; - struct kfifo_rec_ptr_2 pen_fifo; + struct kfifo_rec_ptr_2 *pen_fifo; int pid; int num_contacts_left; u8 bt_features; --- linux-oracle-5.4.0.orig/drivers/hsi/controllers/omap_ssi_core.c +++ linux-oracle-5.4.0/drivers/hsi/controllers/omap_ssi_core.c @@ -355,7 +355,7 @@ err = ida_simple_get(&platform_omap_ssi_ida, 0, 0, GFP_KERNEL); if (err < 0) - goto out_err; + return err; ssi->id = err; ssi->owner = THIS_MODULE; @@ -424,7 +424,7 @@ struct omap_ssi_controller *omap_ssi = hsi_controller_drvdata(ssi); int err; - err = pm_runtime_get_sync(ssi->device.parent); + err = pm_runtime_resume_and_get(ssi->device.parent); if (err < 0) { dev_err(&ssi->device, "runtime PM failed %d\n", err); return err; @@ -502,8 +502,10 @@ platform_set_drvdata(pd, ssi); err = ssi_add_controller(ssi, pd); - if (err < 0) + if (err < 0) { + hsi_put_controller(ssi); goto out1; + } pm_runtime_enable(&pd->dev); @@ -524,6 +526,7 @@ if (!childpdev) { err = -ENODEV; dev_err(&pd->dev, "failed to create ssi controller port\n"); + of_node_put(child); goto out3; } } @@ -535,9 +538,9 @@ device_for_each_child(&pd->dev, NULL, ssi_remove_ports); out2: ssi_remove_controller(ssi); + pm_runtime_disable(&pd->dev); out1: platform_set_drvdata(pd, NULL); - pm_runtime_disable(&pd->dev); return err; } @@ -628,7 +631,13 @@ if (ret) return ret; - return platform_driver_register(&ssi_port_pdriver); + ret = platform_driver_register(&ssi_port_pdriver); + if (ret) { + platform_driver_unregister(&ssi_pdriver); + return ret; + } + + return 0; } module_init(ssi_init); --- linux-oracle-5.4.0.orig/drivers/hsi/controllers/omap_ssi_port.c +++ linux-oracle-5.4.0/drivers/hsi/controllers/omap_ssi_port.c @@ -230,10 +230,10 @@ if (msg->ttype == HSI_MSG_READ) { err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, DMA_FROM_DEVICE); - if (err < 0) { + if (!err) { dev_dbg(&ssi->device, "DMA map SG failed !\n"); pm_runtime_put_autosuspend(omap_port->pdev); - return err; + return -EIO; } csdp = SSI_DST_BURST_4x32_BIT | SSI_DST_MEMORY_PORT | SSI_SRC_SINGLE_ACCESS0 | SSI_SRC_PERIPHERAL_PORT | @@ -247,10 +247,10 @@ } else { err = dma_map_sg(&ssi->device, msg->sgt.sgl, msg->sgt.nents, DMA_TO_DEVICE); - if (err < 0) { + if (!err) { dev_dbg(&ssi->device, "DMA map SG failed !\n"); pm_runtime_put_autosuspend(omap_port->pdev); - return err; + return -EIO; } csdp = SSI_SRC_BURST_4x32_BIT | SSI_SRC_MEMORY_PORT | SSI_DST_SINGLE_ACCESS0 | SSI_DST_PERIPHERAL_PORT | --- linux-oracle-5.4.0.orig/drivers/hsi/hsi_core.c +++ linux-oracle-5.4.0/drivers/hsi/hsi_core.c @@ -102,6 +102,7 @@ if (device_register(&cl->device) < 0) { pr_err("hsi: failed to register client: %s\n", info->name); put_device(&cl->device); + goto err; } return cl; @@ -210,8 +211,6 @@ if (err) goto err; - dev_set_name(&cl->device, "%s", name); - err = hsi_of_property_parse_mode(client, "hsi-mode", &mode); if (err) { err = hsi_of_property_parse_mode(client, "hsi-rx-mode", @@ -293,6 +292,7 @@ cl->device.release = hsi_client_release; cl->device.of_node = client; + dev_set_name(&cl->device, "%s", name); if (device_register(&cl->device) < 0) { pr_err("hsi: failed to register client: %s\n", name); put_device(&cl->device); --- linux-oracle-5.4.0.orig/drivers/hv/channel_mgmt.c +++ linux-oracle-5.4.0/drivers/hv/channel_mgmt.c @@ -493,13 +493,17 @@ * Add the new device to the bus. This will kick off device-driver * binding which eventually invokes the device driver's AddDevice() * method. + * + * If vmbus_device_register() fails, the 'device_obj' is freed in + * vmbus_device_release() as called by device_unregister() in the + * error path of vmbus_device_register(). In the outside error + * path, there's no need to free it. */ ret = vmbus_device_register(newchannel->device_obj); if (ret != 0) { pr_err("unable to add child device object (relid %d)\n", newchannel->offermsg.child_relid); - kfree(newchannel->device_obj); goto err_deq_chan; } @@ -763,13 +767,19 @@ free_cpumask_var(available_mask); } +#define UNLOAD_DELAY_UNIT_MS 10 /* 10 milliseconds */ +#define UNLOAD_WAIT_MS (100*1000) /* 100 seconds */ +#define UNLOAD_WAIT_LOOPS (UNLOAD_WAIT_MS/UNLOAD_DELAY_UNIT_MS) +#define UNLOAD_MSG_MS (5*1000) /* Every 5 seconds */ +#define UNLOAD_MSG_LOOPS (UNLOAD_MSG_MS/UNLOAD_DELAY_UNIT_MS) + static void vmbus_wait_for_unload(void) { int cpu; void *page_addr; struct hv_message *msg; struct vmbus_channel_message_header *hdr; - u32 message_type; + u32 message_type, i; /* * CHANNELMSG_UNLOAD_RESPONSE is always delivered to the CPU which was @@ -779,16 +789,35 @@ * functional and vmbus_unload_response() will complete * vmbus_connection.unload_event. If not, the last thing we can do is * read message pages for all CPUs directly. + * + * Wait up to 100 seconds since an Azure host must writeback any dirty + * data in its disk cache before the VMbus UNLOAD request will + * complete. This flushing has been empirically observed to take up + * to 50 seconds in cases with a lot of dirty data, so allow additional + * leeway and for inaccuracies in mdelay(). But eventually time out so + * that the panic path can't get hung forever in case the response + * message isn't seen. */ - while (1) { + for (i = 1; i <= UNLOAD_WAIT_LOOPS; i++) { if (completion_done(&vmbus_connection.unload_event)) - break; + goto completed; - for_each_online_cpu(cpu) { + for_each_present_cpu(cpu) { struct hv_per_cpu_context *hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); + /* + * In a CoCo VM the synic_message_page is not allocated + * in hv_synic_alloc(). Instead it is set/cleared in + * hv_synic_enable_regs() and hv_synic_disable_regs() + * such that it is set only when the CPU is online. If + * not all present CPUs are online, the message page + * might be NULL, so skip such CPUs. + */ page_addr = hv_cpu->synic_message_page; + if (!page_addr) + continue; + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; @@ -805,19 +834,31 @@ vmbus_signal_eom(msg, message_type); } - mdelay(10); + /* + * Give a notice periodically so someone watching the + * serial output won't think it is completely hung. + */ + if (!(i % UNLOAD_MSG_LOOPS)) + pr_notice("Waiting for VMBus UNLOAD to complete\n"); + + mdelay(UNLOAD_DELAY_UNIT_MS); } + pr_err("Continuing even though VMBus UNLOAD did not complete\n"); +completed: /* * We're crashing and already got the UNLOAD_RESPONSE, cleanup all * maybe-pending messages on all CPUs to be able to receive new * messages after we reconnect. */ - for_each_online_cpu(cpu) { + for_each_present_cpu(cpu) { struct hv_per_cpu_context *hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); page_addr = hv_cpu->synic_message_page; + if (!page_addr) + continue; + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; msg->header.message_type = HVMSG_NONE; } @@ -831,6 +872,11 @@ /* * This is a global event; just wakeup the waiting thread. * Once we successfully unload, we can cleanup the monitor state. + * + * NB. A malicious or compromised Hyper-V could send a spurious + * message of type CHANNELMSG_UNLOAD_RESPONSE, and trigger a call + * of the complete() below. Make sure that unload_event has been + * initialized by the time this complete() is executed. */ complete(&vmbus_connection.unload_event); } @@ -839,11 +885,14 @@ { struct vmbus_channel_message_header hdr; + if (xchg(&vmbus_connection.conn_state, DISCONNECTED) == DISCONNECTED) + return; + /* Pre-Win2012R2 hosts don't support reconnect */ if (vmbus_proto_version < VERSION_WIN8_1) return; - init_completion(&vmbus_connection.unload_event); + reinit_completion(&vmbus_connection.unload_event); memset(&hdr, 0, sizeof(struct vmbus_channel_message_header)); hdr.msgtype = CHANNELMSG_UNLOAD; vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header), @@ -1095,8 +1144,7 @@ vmbus_device_unregister(channel->device_obj); put_device(dev); } - } - if (channel->primary_channel != NULL) { + } else if (channel->primary_channel != NULL) { /* * Sub-channel is being rescinded. Following is the channel * close sequence when initiated from the driveri (refer to @@ -1351,6 +1399,8 @@ { CHANNELMSG_19, 0, NULL }, { CHANNELMSG_20, 0, NULL }, { CHANNELMSG_TL_CONNECT_REQUEST, 0, NULL }, + { CHANNELMSG_22, 0, NULL }, + { CHANNELMSG_TL_CONNECT_RESULT, 0, NULL }, }; /* @@ -1362,25 +1412,16 @@ { struct hv_message *msg = context; struct vmbus_channel_message_header *hdr; - int size; hdr = (struct vmbus_channel_message_header *)msg->u.payload; - size = msg->header.payload_size; trace_vmbus_on_message(hdr); - if (hdr->msgtype >= CHANNELMSG_COUNT) { - pr_err("Received invalid channel message type %d size %d\n", - hdr->msgtype, size); - print_hex_dump_bytes("", DUMP_PREFIX_NONE, - (unsigned char *)msg->u.payload, size); - return; - } - - if (channel_message_table[hdr->msgtype].message_handler) - channel_message_table[hdr->msgtype].message_handler(hdr); - else - pr_err("Unhandled channel message type %d\n", hdr->msgtype); + /* + * vmbus_on_msg_dpc() makes sure the hdr->msgtype here can not go + * out of bound and the message_handler pointer can not be NULL. + */ + channel_message_table[hdr->msgtype].message_handler(hdr); } /* --- linux-oracle-5.4.0.orig/drivers/hv/connection.c +++ linux-oracle-5.4.0/drivers/hv/connection.c @@ -25,6 +25,8 @@ struct vmbus_connection vmbus_connection = { .conn_state = DISCONNECTED, + .unload_event = COMPLETION_INITIALIZER( + vmbus_connection.unload_event), .next_gpadl_handle = ATOMIC_INIT(0xE1E10), .ready_for_suspend_event= COMPLETION_INITIALIZER( @@ -67,7 +69,6 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version) { int ret = 0; - unsigned int cur_cpu; struct vmbus_channel_initiate_contact *msg; unsigned long flags; @@ -100,24 +101,7 @@ msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); - /* - * We want all channel messages to be delivered on CPU 0. - * This has been the behavior pre-win8. This is not - * perf issue and having all channel messages delivered on CPU 0 - * would be ok. - * For post win8 hosts, we support receiving channel messagges on - * all the CPUs. This is needed for kexec to work correctly where - * the CPU attempting to connect may not be CPU 0. - */ - if (version >= VERSION_WIN8_1) { - cur_cpu = get_cpu(); - msg->target_vcpu = hv_cpu_number_to_vp_number(cur_cpu); - vmbus_connection.connect_cpu = cur_cpu; - put_cpu(); - } else { - msg->target_vcpu = 0; - vmbus_connection.connect_cpu = 0; - } + msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU); /* * Add to list before we send the request since we may --- linux-oracle-5.4.0.orig/drivers/hv/hv.c +++ linux-oracle-5.4.0/drivers/hv/hv.c @@ -250,6 +250,17 @@ unsigned long flags; /* + * Hyper-V does not provide a way to change the connect CPU once + * it is set; we must prevent the connect CPU from going offline + * while the VM is running normally. But in the panic or kexec() + * path where the vmbus is already disconnected, the CPU must be + * allowed to shut down. + */ + if (cpu == VMBUS_CONNECT_CPU && + vmbus_connection.conn_state == CONNECTED) + return -EBUSY; + + /* * Search for channels which are bound to the CPU we're about to * cleanup. In case we find one and vmbus is still connected we need to * fail, this will effectively prevent CPU offlining. There is no way --- linux-oracle-5.4.0.orig/drivers/hv/hv_balloon.c +++ linux-oracle-5.4.0/drivers/hv/hv_balloon.c @@ -1213,10 +1213,7 @@ unsigned int i, j; struct page *pg; - if (num_pages < alloc_unit) - return 0; - - for (i = 0; (i * alloc_unit) < num_pages; i++) { + for (i = 0; i < num_pages / alloc_unit; i++) { if (bl_resp->hdr.size + sizeof(union dm_mem_page_range) > PAGE_SIZE) return i * alloc_unit; @@ -1254,7 +1251,7 @@ } - return num_pages; + return i * alloc_unit; } static void balloon_up(struct work_struct *dummy) @@ -1269,9 +1266,6 @@ long avail_pages; unsigned long floor; - /* The host balloons pages in 2M granularity. */ - WARN_ON_ONCE(num_pages % PAGES_IN_2M != 0); - /* * We will attempt 2M allocations. However, if we fail to * allocate 2M chunks, we will go back to 4k allocations. @@ -1281,14 +1275,13 @@ avail_pages = si_mem_available(); floor = compute_balloon_floor(); - /* Refuse to balloon below the floor, keep the 2M granularity. */ + /* Refuse to balloon below the floor. */ if (avail_pages < num_pages || avail_pages - num_pages < floor) { - pr_warn("Balloon request will be partially fulfilled. %s\n", + pr_info("Balloon request will be partially fulfilled. %s\n", avail_pages < num_pages ? "Not enough memory." : "Balloon floor reached."); num_pages = avail_pages > floor ? (avail_pages - floor) : 0; - num_pages -= num_pages % PAGES_IN_2M; } while (!done) { @@ -1557,7 +1550,7 @@ break; default: - pr_warn("Unhandled message: type: %d\n", dm_hdr->type); + pr_warn_ratelimited("Unhandled message: type: %d\n", dm_hdr->type); } } --- linux-oracle-5.4.0.orig/drivers/hv/hv_kvp.c +++ linux-oracle-5.4.0/drivers/hv/hv_kvp.c @@ -749,6 +749,12 @@ */ kvp_transaction.state = HVUTIL_DEVICE_INIT; + return 0; +} + +int +hv_kvp_init_transport(void) +{ hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL, kvp_on_msg, kvp_on_reset); if (!hvt) --- linux-oracle-5.4.0.orig/drivers/hv/hv_snapshot.c +++ linux-oracle-5.4.0/drivers/hv/hv_snapshot.c @@ -368,6 +368,12 @@ */ vss_transaction.state = HVUTIL_DEVICE_INIT; + return 0; +} + +int +hv_vss_init_transport(void) +{ hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL, vss_on_msg, vss_on_reset); if (!hvt) { --- linux-oracle-5.4.0.orig/drivers/hv/hv_util.c +++ linux-oracle-5.4.0/drivers/hv/hv_util.c @@ -98,12 +98,14 @@ static struct hv_util_service util_kvp = { .util_cb = hv_kvp_onchannelcallback, .util_init = hv_kvp_init, + .util_init_transport = hv_kvp_init_transport, .util_deinit = hv_kvp_deinit, }; static struct hv_util_service util_vss = { .util_cb = hv_vss_onchannelcallback, .util_init = hv_vss_init, + .util_init_transport = hv_vss_init_transport, .util_deinit = hv_vss_deinit, }; @@ -283,10 +285,23 @@ struct ictimesync_ref_data *refdata; u8 *time_txf_buf = util_timesynch.recv_buffer; - vmbus_recvpacket(channel, time_txf_buf, - PAGE_SIZE, &recvlen, &requestid); + /* + * Drain the ring buffer and use the last packet to update + * host_ts + */ + while (1) { + int ret = vmbus_recvpacket(channel, time_txf_buf, + HV_HYP_PAGE_SIZE, &recvlen, + &requestid); + if (ret) { + pr_warn_once("TimeSync IC pkt recv failed (Err: %d)\n", + ret); + break; + } + + if (!recvlen) + break; - if (recvlen > 0) { icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ sizeof(struct vmbuspipe_hdr)]; @@ -418,6 +433,13 @@ if (ret) goto error; + if (srv->util_init_transport) { + ret = srv->util_init_transport(); + if (ret) { + vmbus_close(dev->channel); + goto error; + } + } return 0; error: @@ -537,8 +559,8 @@ */ hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL); if (IS_ERR_OR_NULL(hv_ptp_clock)) { - pr_err("cannot register PTP clock: %ld\n", - PTR_ERR(hv_ptp_clock)); + pr_err("cannot register PTP clock: %d\n", + PTR_ERR_OR_ZERO(hv_ptp_clock)); hv_ptp_clock = NULL; } --- linux-oracle-5.4.0.orig/drivers/hv/hyperv_vmbus.h +++ linux-oracle-5.4.0/drivers/hv/hyperv_vmbus.h @@ -13,6 +13,7 @@ #define _HYPERV_VMBUS_H #include +#include #include #include #include @@ -212,12 +213,13 @@ #define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT -struct vmbus_connection { - /* - * CPU on which the initial host contact was made. - */ - int connect_cpu; +/* + * The CPU that Hyper-V will interrupt for VMBUS messages, such as + * CHANNELMSG_OFFERCHANNEL and CHANNELMSG_RESCIND_CHANNELOFFER. + */ +#define VMBUS_CONNECT_CPU 0 +struct vmbus_connection { u32 msg_conn_id; atomic_t offer_in_progress; @@ -351,10 +353,12 @@ void vmbus_on_msg_dpc(unsigned long data); int hv_kvp_init(struct hv_util_service *srv); +int hv_kvp_init_transport(void); void hv_kvp_deinit(void); void hv_kvp_onchannelcallback(void *context); int hv_vss_init(struct hv_util_service *srv); +int hv_vss_init_transport(void); void hv_vss_deinit(void); void hv_vss_onchannelcallback(void *context); --- linux-oracle-5.4.0.orig/drivers/hv/ring_buffer.c +++ linux-oracle-5.4.0/drivers/hv/ring_buffer.c @@ -378,7 +378,16 @@ static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi) { u32 priv_read_loc = rbi->priv_read_index; - u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index); + u32 write_loc; + + /* + * The Hyper-V host writes the packet data, then uses + * store_release() to update the write_index. Use load_acquire() + * here to prevent loads of the packet data from being re-ordered + * before the read of the write_index and potentially getting + * stale data. + */ + write_loc = virt_load_acquire(&rbi->ring_buffer->write_index); if (write_loc >= priv_read_loc) return write_loc - priv_read_loc; --- linux-oracle-5.4.0.orig/drivers/hv/vmbus_drv.c +++ linux-oracle-5.4.0/drivers/hv/vmbus_drv.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include "hyperv_vmbus.h" @@ -48,14 +49,35 @@ static void *hv_panic_page; +/* + * Boolean to control whether to report panic messages over Hyper-V. + * + * It can be set via /proc/sys/kernel/hyperv/record_panic_msg + */ +static int sysctl_record_panic_msg = 1; + +static int hyperv_report_reg(void) +{ + return !sysctl_record_panic_msg || !hv_panic_page; +} + static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, void *args) { struct pt_regs *regs; - regs = current_pt_regs(); + vmbus_initiate_unload(true); - hyperv_report_panic(regs, val); + /* + * Hyper-V should be notified only once about a panic. If we will be + * doing hyperv_report_panic_msg() later with kmsg data, don't do + * the notification here. + */ + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE + && hyperv_report_reg()) { + regs = current_pt_regs(); + hyperv_report_panic(regs, val, false); + } return NOTIFY_DONE; } @@ -65,7 +87,13 @@ struct die_args *die = (struct die_args *)args; struct pt_regs *regs = die->regs; - hyperv_report_panic(regs, val); + /* + * Hyper-V should be notified only once about a panic. If we will be + * doing hyperv_report_panic_msg() later with kmsg data, don't do + * the notification here. + */ + if (hyperv_report_reg()) + hyperv_report_panic(regs, val, true); return NOTIFY_DONE; } @@ -950,6 +978,9 @@ return drv->resume(dev); } +#else +#define vmbus_suspend NULL +#define vmbus_resume NULL #endif /* CONFIG_PM_SLEEP */ /* @@ -967,11 +998,22 @@ } /* - * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than - * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm. + * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm. + * + * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we + * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there + * is no way to wake up a Generation-2 VM. + * + * The other 4 ops are for hibernation. */ + static const struct dev_pm_ops vmbus_pm = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume) + .suspend_noirq = NULL, + .resume_noirq = NULL, + .freeze_noirq = vmbus_suspend, + .thaw_noirq = vmbus_resume, + .poweroff_noirq = vmbus_suspend, + .restore_noirq = vmbus_resume, }; /* The one and only one */ @@ -1031,6 +1073,10 @@ } entry = &channel_message_table[hdr->msgtype]; + + if (!entry->message_handler) + goto msg_handled; + if (entry->handler_type == VMHT_BLOCKING) { ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); if (ctx == NULL) @@ -1050,14 +1096,28 @@ /* * If we are handling the rescind message; * schedule the work on the global work queue. + * + * The OFFER message and the RESCIND message should + * not be handled by the same serialized work queue, + * because the OFFER handler may call vmbus_open(), + * which tries to open the channel by sending an + * OPEN_CHANNEL message to the host and waits for + * the host's response; however, if the host has + * rescinded the channel before it receives the + * OPEN_CHANNEL message, the host just silently + * ignores the OPEN_CHANNEL message; as a result, + * the guest's OFFER handler hangs for ever, if we + * handle the RESCIND message in the same serialized + * work queue: the RESCIND handler can not start to + * run before the OFFER handler finishes. */ - schedule_work_on(vmbus_connection.connect_cpu, + schedule_work_on(VMBUS_CONNECT_CPU, &ctx->work); break; case CHANNELMSG_OFFERCHANNEL: atomic_inc(&vmbus_connection.offer_in_progress); - queue_work_on(vmbus_connection.connect_cpu, + queue_work_on(VMBUS_CONNECT_CPU, vmbus_connection.work_queue, &ctx->work); break; @@ -1104,7 +1164,7 @@ INIT_WORK(&ctx->work, vmbus_onmessage_work); - queue_work_on(vmbus_connection.connect_cpu, + queue_work_on(VMBUS_CONNECT_CPU, vmbus_connection.work_queue, &ctx->work); } @@ -1243,17 +1303,10 @@ tasklet_schedule(&hv_cpu->msg_dpc); } - add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0); + add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR); } /* - * Boolean to control whether to report panic messages over Hyper-V. - * - * It can be set via /proc/sys/kernel/hyperv/record_panic_msg - */ -static int sysctl_record_panic_msg = 1; - -/* * Callback from kmsg_dump. Grab as much as possible from the end of the kmsg * buffer and call into Hyper-V to transfer the data. */ @@ -1380,19 +1433,29 @@ hv_panic_page = (void *)get_zeroed_page(GFP_KERNEL); if (hv_panic_page) { ret = kmsg_dump_register(&hv_kmsg_dumper); - if (ret) + if (ret) { pr_err("Hyper-V: kmsg dump register " "error 0x%x\n", ret); + hv_free_hyperv_page( + (unsigned long)hv_panic_page); + hv_panic_page = NULL; + } } else pr_err("Hyper-V: panic message page memory " "allocation failed"); } register_die_notifier(&hyperv_die_block); - atomic_notifier_chain_register(&panic_notifier_list, - &hyperv_panic_block); } + /* + * Always register the panic notifier because we need to unload + * the VMbus channel connection to prevent any VMbus + * activity after the VM panics. + */ + atomic_notifier_chain_register(&panic_notifier_list, + &hyperv_panic_block); + vmbus_request_offers(); return 0; @@ -1406,7 +1469,6 @@ hv_remove_vmbus_irq(); bus_unregister(&hv_bus); - free_page((unsigned long)hv_panic_page); unregister_sysctl_table(hv_ctl_table_hdr); hv_ctl_table_hdr = NULL; return ret; @@ -1725,8 +1787,10 @@ kobj->kset = dev->channels_kset; ret = kobject_init_and_add(kobj, &vmbus_chan_ktype, NULL, "%u", relid); - if (ret) + if (ret) { + kobject_put(kobj); return ret; + } ret = sysfs_create_group(kobj, &vmbus_chan_group); @@ -1735,6 +1799,7 @@ * The calling functions' error handling paths will cleanup the * empty channel directory. */ + kobject_put(kobj); dev_err(device, "Unable to set up channel sysfs files\n"); return ret; } @@ -1798,6 +1863,7 @@ ret = device_register(&child_device_obj->device); if (ret) { pr_err("Unable to register child device\n"); + put_device(&child_device_obj->device); return ret; } @@ -1842,6 +1908,7 @@ */ device_unregister(&device_obj->device); } +EXPORT_SYMBOL_GPL(vmbus_device_unregister); /* @@ -2010,7 +2077,7 @@ bool fb_overlap_ok) { struct resource *iter, *shadow; - resource_size_t range_min, range_max, start; + resource_size_t range_min, range_max, start, end; const char *dev_n = dev_name(&device_obj->device); int retval; @@ -2045,6 +2112,14 @@ range_max = iter->end; start = (range_min + align - 1) & ~(align - 1); for (; start + size - 1 <= range_max; start += align) { + end = start + size - 1; + + /* Skip the whole fb_mmio region if not fb_overlap_ok */ + if (!fb_overlap_ok && fb_mmio && + (((start >= fb_mmio->start) && (start <= fb_mmio->end)) || + ((end >= fb_mmio->start) && (end <= fb_mmio->end)))) + continue; + shadow = __request_region(iter, start, size, NULL, IORESOURCE_BUSY); if (!shadow) @@ -2169,7 +2244,10 @@ if (atomic_read(&vmbus_connection.nr_chan_close_on_suspend) > 0) wait_for_completion(&vmbus_connection.ready_for_suspend_event); - WARN_ON(atomic_read(&vmbus_connection.nr_chan_fixup_on_resume) != 0); + if (atomic_read(&vmbus_connection.nr_chan_fixup_on_resume) != 0) { + pr_err("Can not suspend due to a previous failed resuming\n"); + return -EBUSY; + } mutex_lock(&vmbus_connection.channel_mutex); @@ -2202,8 +2280,6 @@ vmbus_initiate_unload(false); - vmbus_connection.conn_state = DISCONNECTED; - /* Reset the event for the next resume. */ reinit_completion(&vmbus_connection.ready_for_resume_event); @@ -2245,13 +2321,18 @@ vmbus_request_offers(); - wait_for_completion(&vmbus_connection.ready_for_resume_event); + if (wait_for_completion_timeout( + &vmbus_connection.ready_for_resume_event, 10 * HZ) == 0) + pr_err("Some vmbus device is missing after suspending?\n"); /* Reset the event for the next suspend. */ reinit_completion(&vmbus_connection.ready_for_suspend_event); return 0; } +#else +#define vmbus_bus_suspend NULL +#define vmbus_bus_resume NULL #endif /* CONFIG_PM_SLEEP */ static const struct acpi_device_id vmbus_acpi_device_ids[] = { @@ -2262,16 +2343,24 @@ MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); /* - * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than - * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the - * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the - * pci "noirq" restore callback runs before "non-noirq" callbacks (see + * Note: we must use the "no_irq" ops, otherwise hibernation can not work with + * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in + * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's - * resume callback must also run via the "noirq" callbacks. + * resume callback must also run via the "noirq" ops. + * + * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment + * earlier in this file before vmbus_pm. */ + static const struct dev_pm_ops vmbus_bus_pm = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) + .suspend_noirq = NULL, + .resume_noirq = NULL, + .freeze_noirq = vmbus_bus_suspend, + .thaw_noirq = vmbus_bus_resume, + .poweroff_noirq = vmbus_bus_suspend, + .restore_noirq = vmbus_bus_resume }; static struct acpi_driver vmbus_acpi_driver = { @@ -2288,7 +2377,6 @@ { hv_stimer_global_cleanup(); vmbus_initiate_unload(false); - vmbus_connection.conn_state = DISCONNECTED; /* Make sure conn_state is set as hv_synic_cleanup checks for it */ mb(); cpuhp_remove_state(hyperv_cpuhp_online); @@ -2305,10 +2393,9 @@ * doing the cleanup for current CPU only. This should be sufficient * for kdump. */ - vmbus_connection.conn_state = DISCONNECTED; cpu = smp_processor_id(); hv_stimer_cleanup(cpu); - hv_synic_cleanup(cpu); + hv_synic_disable_regs(cpu); hyperv_cleanup(); }; @@ -2416,10 +2503,15 @@ if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { kmsg_dump_unregister(&hv_kmsg_dumper); unregister_die_notifier(&hyperv_die_block); - atomic_notifier_chain_unregister(&panic_notifier_list, - &hyperv_panic_block); } + /* + * The panic notifier is always registered, hence we should + * also unconditionally unregister it here as well. + */ + atomic_notifier_chain_unregister(&panic_notifier_list, + &hyperv_panic_block); + free_page((unsigned long)hv_panic_page); unregister_sysctl_table(hv_ctl_table_hdr); hv_ctl_table_hdr = NULL; --- linux-oracle-5.4.0.orig/drivers/hwmon/Kconfig +++ linux-oracle-5.4.0/drivers/hwmon/Kconfig @@ -304,6 +304,16 @@ This driver can also be built as a module. If so, the module will be called fam15h_power. +config SENSORS_ALTRA + tristate "Altra sensors driver" + depends on ARM64 + help + If you say yes here you get support for Ampere SoC core and package + sensors for Ampere Altra CPUs. + + This driver can also be built as a module. If so, the module + will be called as altra-hwmon. + config SENSORS_APPLESMC tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" depends on INPUT && X86 @@ -802,7 +812,7 @@ config SENSORS_LTQ_CPUTEMP bool "Lantiq cpu temperature sensor driver" - depends on LANTIQ + depends on SOC_XWAY help If you say yes here you get support for the temperature sensor inside your CPU. @@ -1132,10 +1142,11 @@ help If you say yes here you get support for National Semiconductor LM90, LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, - Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, - MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, - Winbond/Nuvoton W83L771W/G/AWG/ASG, Philips SA56004, GMT G781, and - Texas Instruments TMP451 sensor chips. + Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6654, MAX6657, MAX6658, + MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, + ON Semiconductor NCT1008, Winbond/Nuvoton W83L771W/G/AWG/ASG, + Philips SA56004, GMT G781, Texas Instruments TMP451 and TMP461 + sensor chips. This driver can also be built as a module. If so, the module will be called lm90. @@ -1922,6 +1933,17 @@ If you say yes here you get support for the temperature and power sensors for APM X-Gene SoC. +config SENSORS_AHC1EC0_HWMON + tristate "Advantech AHC1EC0 Hardware Monitor Function" + depends on MFD_AHC1EC0 + depends on UBUNTU_ODM_DRIVERS + help + This driver provide support for the hardware monitoring functionality + for Advantech AHC1EC0 embedded controller on the board. + + This driver provides the sysfs attributes for applications to monitor + the system status, including system temperatures, voltages, current. + if ACPI comment "ACPI drivers" --- linux-oracle-5.4.0.orig/drivers/hwmon/Makefile +++ linux-oracle-5.4.0/drivers/hwmon/Makefile @@ -44,6 +44,8 @@ obj-$(CONFIG_SENSORS_ADT7462) += adt7462.o obj-$(CONFIG_SENSORS_ADT7470) += adt7470.o obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o +obj-$(CONFIG_SENSORS_AHC1EC0_HWMON) += ahc1ec0-hwmon.o +obj-$(CONFIG_SENSORS_ALTRA) += altra-hwmon.o obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o --- linux-oracle-5.4.0.orig/drivers/hwmon/acpi_power_meter.c +++ linux-oracle-5.4.0/drivers/hwmon/acpi_power_meter.c @@ -32,6 +32,7 @@ #define POWER_METER_CAN_NOTIFY (1 << 3) #define POWER_METER_IS_BATTERY (1 << 8) #define UNKNOWN_HYSTERESIS 0xFFFFFFFF +#define UNKNOWN_POWER 0xFFFFFFFF #define METER_NOTIFY_CONFIG 0x80 #define METER_NOTIFY_TRIP 0x81 @@ -343,6 +344,9 @@ update_meter(resource); mutex_unlock(&resource->lock); + if (resource->power == UNKNOWN_POWER) + return -ENODATA; + return sprintf(buf, "%llu\n", resource->power * 1000); } @@ -883,7 +887,7 @@ res = setup_attrs(resource); if (res) - goto exit_free; + goto exit_free_capability; resource->hwmon_dev = hwmon_device_register(&device->dev); if (IS_ERR(resource->hwmon_dev)) { @@ -896,6 +900,8 @@ exit_remove: remove_attrs(resource); +exit_free_capability: + free_capabilities(resource); exit_free: kfree(resource); exit: --- linux-oracle-5.4.0.orig/drivers/hwmon/ad7314.c +++ linux-oracle-5.4.0/drivers/hwmon/ad7314.c @@ -22,11 +22,13 @@ */ #define AD7314_TEMP_MASK 0x7FE0 #define AD7314_TEMP_SHIFT 5 +#define AD7314_LEADING_ZEROS_MASK BIT(15) /* * ADT7301 and ADT7302 temperature masks */ #define ADT7301_TEMP_MASK 0x3FFF +#define ADT7301_LEADING_ZEROS_MASK (BIT(15) | BIT(14)) enum ad7314_variant { adt7301, @@ -65,12 +67,20 @@ return ret; switch (spi_get_device_id(chip->spi_dev)->driver_data) { case ad7314: + if (ret & AD7314_LEADING_ZEROS_MASK) { + /* Invalid read-out, leading zero part is missing */ + return -EIO; + } data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_SHIFT; data = sign_extend32(data, 9); return sprintf(buf, "%d\n", 250 * data); case adt7301: case adt7302: + if (ret & ADT7301_LEADING_ZEROS_MASK) { + /* Invalid read-out, leading zero part is missing */ + return -EIO; + } /* * Documented as a 13 bit twos complement register * with a sign bit - which is a 14 bit 2's complement --- linux-oracle-5.4.0.orig/drivers/hwmon/adc128d818.c +++ linux-oracle-5.4.0/drivers/hwmon/adc128d818.c @@ -176,7 +176,7 @@ mutex_lock(&data->update_lock); /* 10 mV LSB on limit registers */ - regval = clamp_val(DIV_ROUND_CLOSEST(val, 10), 0, 255); + regval = DIV_ROUND_CLOSEST(clamp_val(val, 0, 2550), 10); data->in[index][nr] = regval << 4; reg = index == 1 ? ADC128_REG_IN_MIN(nr) : ADC128_REG_IN_MAX(nr); i2c_smbus_write_byte_data(data->client, reg, regval); @@ -214,7 +214,7 @@ return err; mutex_lock(&data->update_lock); - regval = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); + regval = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); data->temp[index] = regval << 1; i2c_smbus_write_byte_data(data->client, index == 1 ? ADC128_REG_TEMP_MAX --- linux-oracle-5.4.0.orig/drivers/hwmon/adt7462.c +++ linux-oracle-5.4.0/drivers/hwmon/adt7462.c @@ -413,7 +413,7 @@ return 0x95; break; } - return -ENODEV; + return 0; } /* Provide labels for sysfs */ --- linux-oracle-5.4.0.orig/drivers/hwmon/adt7470.c +++ linux-oracle-5.4.0/drivers/hwmon/adt7470.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Addresses to scan */ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; @@ -260,11 +261,10 @@ adt7470_read_temperatures(client, data); mutex_unlock(&data->lock); - set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) break; - schedule_timeout(msecs_to_jiffies(data->auto_update_interval)); + schedule_timeout_interruptible(msecs_to_jiffies(data->auto_update_interval)); } return 0; --- linux-oracle-5.4.0.orig/drivers/hwmon/adt7475.c +++ linux-oracle-5.4.0/drivers/hwmon/adt7475.c @@ -294,9 +294,10 @@ long reg; if (bypass_attn & (1 << channel)) - reg = (volt * 1024) / 2250; + reg = DIV_ROUND_CLOSEST(volt * 1024, 2250); else - reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250); + reg = DIV_ROUND_CLOSEST(volt * r[1] * 1024, + (r[0] + r[1]) * 2250); return clamp_val(reg, 0, 1023) & (0xff << 2); } @@ -483,10 +484,10 @@ val = (temp - val) / 1000; if (sattr->index != 1) { - data->temp[HYSTERSIS][sattr->index] &= 0xF0; + data->temp[HYSTERSIS][sattr->index] &= 0x0F; data->temp[HYSTERSIS][sattr->index] |= (val & 0xF) << 4; } else { - data->temp[HYSTERSIS][sattr->index] &= 0x0F; + data->temp[HYSTERSIS][sattr->index] &= 0xF0; data->temp[HYSTERSIS][sattr->index] |= (val & 0xF); } @@ -551,11 +552,11 @@ val = data->enh_acoustics[0] & 0xf; break; case 1: - val = (data->enh_acoustics[1] >> 4) & 0xf; + val = data->enh_acoustics[1] & 0xf; break; case 2: default: - val = data->enh_acoustics[1] & 0xf; + val = (data->enh_acoustics[1] >> 4) & 0xf; break; } @@ -1680,7 +1681,7 @@ data->pwm[CONTROL][index] &= ~0xE0; data->pwm[CONTROL][index] |= (7 << 5); - i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), + i2c_smbus_write_byte_data(client, PWM_REG(index), data->pwm[INPUT][index]); i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index), --- linux-oracle-5.4.0.orig/drivers/hwmon/ahc1ec0-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/ahc1ec0-hwmon.c @@ -0,0 +1,660 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * HWMON Driver for Advantech Embedded Controller chip AHC1EC0 + * + * Copyright 2020, Advantech IIoT Group + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct ec_hwmon_attrs { + const char *name; + umode_t mode; + int (*read)(struct device *dev, long *val); +}; + +struct adv_hwmon_profile { + int offset; + unsigned long resolution, resolution_vin, resolution_sys, resolution_curr, resolution_power; + unsigned long r1, r1_vin, r1_sys, r1_curr, r1_power; + unsigned long r2, r2_vin, r2_sys, r2_curr, r2_power; + int hwmon_in_list_cnt; + int temp_list_cnt; + int *hwmon_in_list; + int *temp_list; +}; + +struct ec_hwmon_data { + struct device *dev; + struct device *hwmon_dev; + struct adv_ec_platform_data *adv_ec_data; + unsigned long temperature[3]; + unsigned long ec_current[5]; + unsigned long power[5]; + unsigned long voltage[7]; + + struct ec_hw_pin_table pin_tbl; + struct ec_smbuso_em0 ec_smboem0; + struct adv_hwmon_profile *profile; +}; + +static int get_ec_in_vbat_input(struct device *dev, long *val); +static int get_ec_in_v5_input(struct device *dev, long *val); +static int get_ec_in_v12_input(struct device *dev, long *val); +static int get_ec_in_vcore_input(struct device *dev, long *val); +static int get_ec_current1_input(struct device *dev, long *val); +static int get_ec_cpu_temp(struct device *dev, long *val); +static int get_ec_sys_temp(struct device *dev, long *val); + +const struct ec_hwmon_attrs ec_hwmon_in_attr_template[] = { + {"VBAT", 0444, get_ec_in_vbat_input}, // in1 + {"5VSB", 0444, get_ec_in_v5_input}, // in2 + {"Vin", 0444, get_ec_in_v12_input}, // in3 (== in8) + {"VCORE", 0444, get_ec_in_vcore_input}, // in4 + {"Vin1", 0444, NULL}, // in5 + {"Vin2", 0444, NULL}, // in6 + {"System Voltage", 0444, NULL}, // in7 + {"Current", 0444, get_ec_current1_input}, +}; + +const struct ec_hwmon_attrs ec_temp_attrs_template[] = { + {"CPU Temp", 0444, get_ec_cpu_temp}, + {"System Temp", 0444, get_ec_sys_temp}, +}; + +enum ec_hwmon_in_type { + EC_HWMON_IN_VBAT, + EC_HWMON_IN_5VSB, + EC_HWMON_IN_12V, + EC_HWMON_IN_VCORE, + EC_HWMON_IN_VIN1, + EC_HWMON_IN_VIN2, + EC_HWMON_IN_SYS_VOL, + EC_HWMON_IN_CURRENT, +}; + +enum ec_temp_type { + EC_TEMP_CPU, + EC_TEMP_SYS, +}; + +static int hwmon_in_list_0[] = { + EC_HWMON_IN_VBAT, + EC_HWMON_IN_5VSB, + EC_HWMON_IN_12V, + EC_HWMON_IN_VCORE, + EC_HWMON_IN_CURRENT, +}; + +static int hwmon_in_list_1[] = { + EC_HWMON_IN_VBAT, + EC_HWMON_IN_5VSB, + EC_HWMON_IN_12V, + EC_HWMON_IN_VCORE, +}; + +static int temp_list_0[] = { + EC_TEMP_CPU, +}; + +static int temp_list_1[] = { + EC_TEMP_CPU, + EC_TEMP_SYS, +}; + +static struct adv_hwmon_profile advec_profile[] = { + /* + * TPC-8100TR, TPC-651T-E3AE, TPC-1251T-E3AE, TPC-1551T-E3AE, + * TPC-1751T-E3AE, TPC-1051WP-E3AE, TPC-1551WP-E3AE, TPC-1581WP-433AE, + * TPC-1782H-433AE, UNO-1483G-434AE, UNO-2483G-434AE, UNO-3483G-374AE, + * UNO-2473G, UNO-2484G-6???AE, UNO-2484G-7???AE, UNO-3283G-674AE, + * UNO-3285G-674AE + * [0] AHC1EC0_HWMON_PRO_TEMPLATE + */ + { + .resolution = 2929, + .r1 = 1912, + .r2 = 1000, + .offset = 0, + .hwmon_in_list_cnt = ARRAY_SIZE(hwmon_in_list_0), + .temp_list_cnt = ARRAY_SIZE(temp_list_0), + .hwmon_in_list = hwmon_in_list_0, + .temp_list = temp_list_0, + }, + /* + * TPC-B500-6??AE, TPC-5???T-6??AE, TPC-5???W-6??AE, TPC-B200-???AE, + * TPC-2???T-???AE, TPC-2???W-???AE + * [1] AHC1EC0_HWMON_PRO_TPC5XXX + */ + { + .resolution = 2929, + .r1 = 1912, + .r2 = 1000, + .offset = 0, + .hwmon_in_list_cnt = ARRAY_SIZE(hwmon_in_list_1), + .temp_list_cnt = ARRAY_SIZE(temp_list_0), + .hwmon_in_list = hwmon_in_list_1, + .temp_list = temp_list_0, + }, + /* PR/VR4 + * [2] AHC1EC0_HWMON_PRO_PRVR4 + */ + { + .resolution = 2929, + .r1 = 1912, + .r2 = 1000, + .offset = 0, + .hwmon_in_list_cnt = ARRAY_SIZE(hwmon_in_list_1), + .temp_list_cnt = ARRAY_SIZE(temp_list_1), + .hwmon_in_list = hwmon_in_list_1, + .temp_list = temp_list_1, + }, + /* UNO-2271G-E22AE/E23AE/E022AE/E023AE,UNO-420 + * [3] AHC1EC0_HWMON_PRO_UNO2271G + */ + { + .resolution = 2929, + .r1 = 1912, + .r2 = 1000, + .offset = 0, + .hwmon_in_list_cnt = ARRAY_SIZE(hwmon_in_list_1), + .temp_list_cnt = ARRAY_SIZE(temp_list_0), + .hwmon_in_list = hwmon_in_list_1, + .temp_list = temp_list_0, + }, +}; + +static void adv_ec_init_hwmon_profile(u32 profile, struct ec_hwmon_data *lmsensor_data) +{ + int i; + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + struct ec_dynamic_table *dym_tbl = adv_ec_data->dym_tbl; + + if (profile >= ARRAY_SIZE(advec_profile)) + return; + + lmsensor_data->profile = &advec_profile[profile]; + + for (i = 0; i < EC_MAX_TBL_NUM ; i++) { + switch (dym_tbl[i].device_id) { + case EC_DID_CMOSBAT: + ptbl->vbat[0] = dym_tbl[i].hw_pin_num; + ptbl->vbat[1] = 1; + break; + case EC_DID_CMOSBAT_X2: + ptbl->vbat[0] = dym_tbl[i].hw_pin_num; + ptbl->vbat[1] = 2; + break; + case EC_DID_CMOSBAT_X10: + ptbl->vbat[0] = dym_tbl[i].hw_pin_num; + ptbl->vbat[1] = 10; + break; + case EC_DID_5VS0: + case EC_DID_5VS5: + ptbl->v5[0] = dym_tbl[i].hw_pin_num; + ptbl->v5[1] = 1; + break; + case EC_DID_5VS0_X2: + case EC_DID_5VS5_X2: + ptbl->v5[0] = dym_tbl[i].hw_pin_num; + ptbl->v5[1] = 2; + break; + case EC_DID_5VS0_X10: + case EC_DID_5VS5_X10: + ptbl->v5[0] = dym_tbl[i].hw_pin_num; + ptbl->v5[1] = 10; + break; + case EC_DID_12VS0: + ptbl->v12[0] = dym_tbl[i].hw_pin_num; + ptbl->v12[1] = 1; + break; + case EC_DID_12VS0_X2: + ptbl->v12[0] = dym_tbl[i].hw_pin_num; + ptbl->v12[1] = 2; + break; + case EC_DID_12VS0_X10: + ptbl->v12[0] = dym_tbl[i].hw_pin_num; + ptbl->v12[1] = 10; + break; + case EC_DID_VCOREA: + case EC_DID_VCOREB: + ptbl->vcore[0] = dym_tbl[i].hw_pin_num; + ptbl->vcore[1] = 1; + break; + case EC_DID_VCOREA_X2: + case EC_DID_VCOREB_X2: + ptbl->vcore[0] = dym_tbl[i].hw_pin_num; + ptbl->vcore[1] = 2; + break; + case EC_DID_VCOREA_X10: + case EC_DID_VCOREB_X10: + ptbl->vcore[0] = dym_tbl[i].hw_pin_num; + ptbl->vcore[1] = 10; + break; + case EC_DID_DC: + ptbl->vdc[0] = dym_tbl[i].hw_pin_num; + ptbl->vdc[1] = 1; + break; + case EC_DID_DC_X2: + ptbl->vdc[0] = dym_tbl[i].hw_pin_num; + ptbl->vdc[1] = 2; + break; + case EC_DID_DC_X10: + ptbl->vdc[0] = dym_tbl[i].hw_pin_num; + ptbl->vdc[1] = 10; + break; + case EC_DID_CURRENT: + ptbl->ec_current[0] = dym_tbl[i].hw_pin_num; + ptbl->ec_current[1] = 1; + break; + case EC_DID_SMBOEM0: + lmsensor_data->ec_smboem0.hw_pin_num = dym_tbl[i].hw_pin_num; + break; + default: + break; + } + } +} + +static int get_ec_in_vbat_input(struct device *dev, long *val) +{ + unsigned int temp = 0; + unsigned long voltage = 0; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_hwmon_profile *profile = lmsensor_data->profile; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + temp = read_ad_value(adv_ec_data, ptbl->vbat[0], ptbl->vbat[1]); + + if (profile->r2 != 0) + voltage = temp * (profile->r1 + profile->r2) / profile->r2; + + if (profile->resolution != 0) + voltage = temp * profile->resolution / 1000 / 1000; + + if (profile->offset != 0) + voltage += (int)profile->offset * 100; + + lmsensor_data->voltage[0] = 10 * voltage; + + *val = lmsensor_data->voltage[0]; + return 0; +} + +static int get_ec_in_v5_input(struct device *dev, long *val) +{ + unsigned int temp; + unsigned long voltage = 0; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_hwmon_profile *profile = lmsensor_data->profile; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + temp = read_ad_value(adv_ec_data, ptbl->v5[0], ptbl->v5[1]); + + if (profile->r2 != 0) + voltage = temp * (profile->r1 + profile->r2) / profile->r2; + + if (profile->resolution != 0) + voltage = temp * profile->resolution / 1000 / 1000; + + if (profile->offset != 0) + voltage += (int)profile->offset * 100; + + lmsensor_data->voltage[1] = 10 * voltage; + + *val = lmsensor_data->voltage[1]; + return 0; +} + +static int get_ec_in_v12_input(struct device *dev, long *val) +{ + int temp; + unsigned long voltage = 0; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_hwmon_profile *profile = lmsensor_data->profile; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + temp = read_ad_value(adv_ec_data, ptbl->v12[0], ptbl->v12[1]); + if (temp == -1) + temp = read_ad_value(adv_ec_data, ptbl->vdc[0], ptbl->vdc[1]); + + if (profile->r2 != 0) + voltage = temp * (profile->r1 + profile->r2) / profile->r2; + + if (profile->resolution != 0) + voltage = temp * profile->resolution / 1000 / 1000; + + if (profile->offset != 0) + voltage += profile->offset * 100; + + lmsensor_data->voltage[2] = 10 * voltage; + + *val = lmsensor_data->voltage[2]; + return 0; +} + +static int get_ec_in_vcore_input(struct device *dev, long *val) +{ + int temp; + unsigned int voltage = 0; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_hwmon_profile *profile = lmsensor_data->profile; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + temp = read_ad_value(adv_ec_data, ptbl->vcore[0], ptbl->vcore[1]); + + if (profile->r2 != 0) + voltage = temp * (profile->r1 + profile->r2) / profile->r2; + + if (profile->resolution != 0) + voltage = temp * profile->resolution / 1000 / 1000; + + if (profile->offset != 0) + voltage += profile->offset * 100; + + lmsensor_data->voltage[3] = 10 * voltage; + + *val = lmsensor_data->voltage[3]; + return 0; +} + +static int get_ec_current1_input(struct device *dev, long *val) +{ + int temp; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + struct ec_hw_pin_table *ptbl = &lmsensor_data->pin_tbl; + struct adv_hwmon_profile *profile = lmsensor_data->profile; + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + temp = read_ad_value(adv_ec_data, ptbl->ec_current[0], ptbl->ec_current[1]); + + if (profile->r2 != 0) + temp = temp * (profile->r1 + profile->r2) / profile->r2; + + if (profile->resolution != 0) + temp = temp * profile->resolution / 1000 / 1000; + + if (profile->offset != 0) + temp += profile->offset * 100; + + lmsensor_data->ec_current[3] = 10 * temp; + + *val = lmsensor_data->ec_current[3]; + return 0; +} + +static int get_ec_cpu_temp(struct device *dev, long *val) +{ + #define EC_ACPI_THERMAL1_REMOTE_TEMP 0x61 + + unsigned char value; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + read_acpi_value(adv_ec_data, EC_ACPI_THERMAL1_REMOTE_TEMP, &value); + *val = 1000 * value; + return 0; +} + +static int get_ec_sys_temp(struct device *dev, long *val) +{ + #define EC_ACPI_THERMAL1_LOCAL_TEMP 0x60 + + unsigned char value; + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + struct adv_ec_platform_data *adv_ec_data = lmsensor_data->adv_ec_data; + + read_acpi_value(adv_ec_data, EC_ACPI_THERMAL1_LOCAL_TEMP, &value); + *val = 1000 * value; + return 0; +} + + +static int +ahc1ec0_read_in(struct device *dev, u32 attr, int channel, long *val) +{ + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + if (!(lmsensor_data && lmsensor_data->profile)) + return -EINVAL; + + if (attr == hwmon_in_input && + lmsensor_data->profile->hwmon_in_list_cnt > channel) { + int index = lmsensor_data->profile->hwmon_in_list[channel]; + const struct ec_hwmon_attrs *ec_hwmon_attr = &ec_hwmon_in_attr_template[index]; + + return ec_hwmon_attr->read(dev, val); + } + + return -EOPNOTSUPP; +} + +static int +ahc1ec0_read_temp(struct device *dev, u32 attr, int channel, long *val) +{ + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + if (!(lmsensor_data && lmsensor_data->profile)) + return -EINVAL; + + switch (attr) { + case hwmon_temp_input: + if (lmsensor_data->profile->temp_list_cnt > channel) { + int index = lmsensor_data->profile->temp_list[channel]; + const struct ec_hwmon_attrs *devec_hwmon_attr = + &ec_temp_attrs_template[index]; + + return devec_hwmon_attr->read(dev, val); + } + return -EOPNOTSUPP; + case hwmon_temp_crit: + // both CPU temp and System temp are all this value + *val = 100000; + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int +ahc1ec0_read_string(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, + int channel, + const char **str) +{ + struct ec_hwmon_data *lmsensor_data = dev_get_drvdata(dev); + + if (!(lmsensor_data && lmsensor_data->profile)) + return -EINVAL; + + if ((type == hwmon_in && attr == hwmon_in_label) && + (lmsensor_data->profile->hwmon_in_list_cnt > channel)) { + int index = lmsensor_data->profile->hwmon_in_list[channel]; + const struct ec_hwmon_attrs *ec_hwmon_attr = &ec_hwmon_in_attr_template[index]; + + *str = ec_hwmon_attr->name; + return 0; + } + + if ((type == hwmon_temp && attr == hwmon_temp_label) && + (lmsensor_data->profile->temp_list_cnt > channel)) { + int index = lmsensor_data->profile->temp_list[channel]; + const struct ec_hwmon_attrs *ec_hwmon_attr = &ec_temp_attrs_template[index]; + + *str = ec_hwmon_attr->name; + return 0; + } + + return -EOPNOTSUPP; +} + +static int +ahc1ec0_read(struct device *dev, + enum hwmon_sensor_types type, + u32 attr, + int channel, + long *val) +{ + switch (type) { + case hwmon_in: + return ahc1ec0_read_in(dev, attr, channel, val); + case hwmon_temp: + return ahc1ec0_read_temp(dev, attr, channel, val); + default: + return -EOPNOTSUPP; + } +} + +static umode_t +ec_hwmon_in_visible(const void *data, u32 attr, int channel) +{ + switch (attr) { + case hwmon_in_input: + case hwmon_in_label: + return 0444; + default: + return 0; + } +} + +static umode_t +ec_temp_in_visible(const void *data, u32 attr, int channel) +{ + switch (attr) { + case hwmon_temp_input: + case hwmon_temp_crit: + case hwmon_temp_label: + return 0444; + default: + return 0; + } +} + +static umode_t +ahc1ec0_is_visible(const void *data, + enum hwmon_sensor_types type, u32 attr, int channel) +{ + switch (type) { + case hwmon_in: + return ec_hwmon_in_visible(data, attr, channel); + case hwmon_temp: + return ec_temp_in_visible(data, attr, channel); + default: + return 0; + } +} + +static const u32 ahc1ec0_in_config[] = { + HWMON_I_INPUT | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_LABEL, + HWMON_I_INPUT | HWMON_I_LABEL, + 0 +}; + +static const struct hwmon_channel_info ahc1ec0_in = { + .type = hwmon_in, + .config = ahc1ec0_in_config, +}; + +static const u32 ahc1ec0_temp_config[] = { + HWMON_T_INPUT | HWMON_T_CRIT | HWMON_T_LABEL, + 0 +}; + +static const struct hwmon_channel_info ahc1ec0_temp = { + .type = hwmon_temp, + .config = ahc1ec0_temp_config, +}; + +static const struct hwmon_channel_info *ahc1ec0_info[] = { + &ahc1ec0_in, + &ahc1ec0_temp, + NULL +}; + +static const struct hwmon_ops ahc1ec0_hwmon_ops = { + .is_visible = ahc1ec0_is_visible, + .read = ahc1ec0_read, + .read_string = ahc1ec0_read_string, +}; + +static const struct hwmon_chip_info ahc1ec0_chip_info = { + .ops = &ahc1ec0_hwmon_ops, + .info = ahc1ec0_info, +}; + +static int adv_ec_hwmon_probe(struct platform_device *pdev) +{ + int ret; + u32 profile; + struct device *dev = &pdev->dev; + struct adv_ec_platform_data *adv_ec_data; + struct ec_hwmon_data *lmsensor_data; + + adv_ec_data = dev_get_drvdata(dev->parent); + if (!adv_ec_data) + return -EINVAL; + + ret = device_property_read_u32(dev->parent, "advantech,hwmon-profile", &profile); + if (ret < 0) { + dev_err(dev, "get hwmon-profile failed! (%d)", ret); + return ret; + } + + if (!(profile < ARRAY_SIZE(advec_profile))) { + dev_err(dev, "not support hwmon profile(%d)!\n", profile); + return -EINVAL; + } + + lmsensor_data = devm_kzalloc(dev, sizeof(struct ec_hwmon_data), GFP_KERNEL); + if (!lmsensor_data) + return -ENOMEM; + + lmsensor_data->adv_ec_data = adv_ec_data; + lmsensor_data->dev = dev; + dev_set_drvdata(dev, lmsensor_data); + + adv_ec_init_hwmon_profile(profile, lmsensor_data); + + lmsensor_data->hwmon_dev = devm_hwmon_device_register_with_info(dev, + "ahc1ec0.hwmon", lmsensor_data, &ahc1ec0_chip_info, NULL); + + return PTR_ERR_OR_ZERO(lmsensor_data->hwmon_dev); +} + +static struct platform_driver adv_hwmon_drv = { + .driver = { + .name = "ahc1ec0-hwmon", + }, + .probe = adv_ec_hwmon_probe, +}; +module_platform_driver(adv_hwmon_drv); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_ALIAS("platform:ahc1ec0-hwmon"); +MODULE_DESCRIPTION("Advantech Embedded Controller HWMON Driver."); +MODULE_AUTHOR("Campion Kang "); +MODULE_AUTHOR("Jianfeng Dai "); +MODULE_VERSION("1.0"); --- linux-oracle-5.4.0.orig/drivers/hwmon/altra-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/altra-hwmon.c @@ -0,0 +1,435 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Ampere Altra SoC Hardware Monitoring Driver + * + * Copyright (C) 2020 Ampere Computing LLC + * Author: Loc Ho + * Hoan Tran + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "altra_hwmon" +#define ALTRA_HWMON_VER1 1 +#define ALTRA_HWMON_VER2 2 + +#define HW_SUPPORTED_VER 1 + +#define UNIT_DEGREE_CELSIUS 0x0001 +#define UNIT_JOULE 0x0010 +#define UNIT_MILLI_JOULE 0x0011 +#define UNIT_MICRO_JOULE 0x0012 + +#define HW_METRIC_LABEL_REG 0x0000 +#define HW_METRIC_LABEL_SIZE 16 +#define HW_METRIC_INFO_REG 0x0010 +#define HW_METRIC_INFO_UNIT_RD(x) ((x) & 0xFF) +#define HW_METRIC_INFO_DATASIZE_RD(x) (((x) >> 8) & 0xFF) +#define HW_METRIC_INFO_DATACNT_RD(x) (((x) >> 16) & 0xFFFF) +#define HW_METRIC_DATA_REG 0x0018 +#define HW_METRIC_HDRSIZE 24 + +#define HW_METRICS_ID_REG 0x0000 +#define HW_METRICS_ID 0x304D5748 /* HWM0 */ +#define HW_METRICS_INFO_REG 0x0004 +#define HW_METRICS_INFO_VER_RD(x) ((x) & 0xFFFF) +#define HW_METRICS_INFO_CNT_RD(x) (((x) >> 16) & 0xFFFF) +#define HW_METRICS_DATA_REG 0x0008 +#define HW_METRICS_HDRSIZE 8 + +#define SENSOR_ITEM_LABEL_SIZE (HW_METRIC_LABEL_SIZE + 3 + 1) + +struct sensor_item { + char label[SENSOR_ITEM_LABEL_SIZE]; /* NULL terminator label */ + u32 scale_factor; /* Convert HW unit to HWmon unnt */ + u8 data_size; /* 4 or 8 bytes */ + u32 hw_reg; /* Registor offset to data */ +}; + +struct altra_hwmon_context { + struct hwmon_channel_info *channel_info; + const struct hwmon_channel_info **info; + struct hwmon_chip_info chip; + struct sensor_item *sensor_list[hwmon_max]; + u32 sensor_list_cnt[hwmon_max]; + struct device *dev; + struct device *hwmon_dev; + void __iomem *base; + u32 base_size; +}; + +static u32 altra_hwmon_read32(struct altra_hwmon_context *ctx, u32 reg) +{ + return readl_relaxed(ctx->base + reg); +} + +static u64 altra_hwmon_read64(struct altra_hwmon_context *ctx, u32 reg) +{ + return readq_relaxed(ctx->base + reg); +} + +static int altra_hwmon_read_labels(struct device *dev, + enum hwmon_sensor_types type, u32 attr, + int channel, const char **str) +{ + struct altra_hwmon_context *ctx = dev_get_drvdata(dev); + struct sensor_item *item; + + if (type >= hwmon_max) + return -EINVAL; + if (channel >= ctx->sensor_list_cnt[type]) + return -EINVAL; + + item = ctx->sensor_list[type]; + *str = item[channel].label; + return 0; +} + +static int altra_hwmon_read(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long *val) +{ + struct altra_hwmon_context *ctx = dev_get_drvdata(dev); + struct sensor_item *item; + + if (type >= hwmon_max) + return -EINVAL; + if (channel >= ctx->sensor_list_cnt[type]) + return -EINVAL; + + item = ctx->sensor_list[type]; + if (item[channel].data_size == 4) + *val = altra_hwmon_read32(ctx, item[channel].hw_reg); + else + *val = altra_hwmon_read64(ctx, item[channel].hw_reg); + *val *= item[channel].scale_factor; + + return 0; +} + +static umode_t altra_hwmon_is_visible(const void *_data, + enum hwmon_sensor_types type, + u32 attr, int channel) +{ + return 0444; +} + +static const struct hwmon_ops altra_hwmon_ops = { + .is_visible = altra_hwmon_is_visible, + .read = altra_hwmon_read, + .read_string = altra_hwmon_read_labels, +}; + +static enum hwmon_sensor_types altra_hwmon_unit2type(u8 unit) +{ + switch (unit) { + case UNIT_DEGREE_CELSIUS: + return hwmon_temp; + case UNIT_JOULE: + case UNIT_MILLI_JOULE: + case UNIT_MICRO_JOULE: + return hwmon_energy; + } + return hwmon_max; +} + +static u32 altra_hwmon_scale_factor(u8 unit) +{ + switch (unit) { + case UNIT_DEGREE_CELSIUS: + return 1000; + case UNIT_JOULE: + return 1000000; + case UNIT_MILLI_JOULE: + return 1000; + case UNIT_MICRO_JOULE: + return 1; + } + return 1; +} + +static u32 altra_hwmon_type2flag(enum hwmon_sensor_types type) +{ + switch (type) { + case hwmon_energy: + return HWMON_E_INPUT | HWMON_E_LABEL; + case hwmon_temp: + return HWMON_T_LABEL | HWMON_T_INPUT; + default: + return 0; + } +} + +static int altra_sensor_is_valid(struct altra_hwmon_context *ctx, u32 reg, u32 data_size) +{ + int val; + + if (data_size == 4) + val = altra_hwmon_read32(ctx, reg); + else + val = altra_hwmon_read64(ctx, reg); + + return val ? 1 : 0; +} + +static int altra_create_sensor(struct altra_hwmon_context *ctx, + u32 metric_info, + struct hwmon_channel_info *info) +{ + enum hwmon_sensor_types type; + char label[SENSOR_ITEM_LABEL_SIZE]; + struct sensor_item *item_list; + struct sensor_item *item; + int data_size; + u32 *s_config; + u32 hw_info; + u32 total; + int i, j; + + /* Check for supported type */ + hw_info = altra_hwmon_read32(ctx, metric_info + HW_METRIC_INFO_REG); + type = altra_hwmon_unit2type(HW_METRIC_INFO_UNIT_RD(hw_info)); + if (type == hwmon_max) { + dev_err(ctx->dev, + "malform info header @ 0x%x value 0x%x. Ignore remaining\n", + metric_info + HW_METRIC_INFO_REG, hw_info); + return -ENODEV; + } + + /* Label */ + for (i = 0; i < HW_METRIC_LABEL_SIZE; i += 4) + *(u32 *)&label[i] = altra_hwmon_read32(ctx, + metric_info + HW_METRIC_LABEL_REG + i); + label[sizeof(label) - 1] = '\0'; + if (strlen(label) <= 0) { + dev_err(ctx->dev, + "malform label header 0x%x. Ignore remaining\n", + metric_info + HW_METRIC_LABEL_REG); + return -ENODEV; + } + + total = HW_METRIC_INFO_DATACNT_RD(hw_info); + data_size = HW_METRIC_INFO_DATASIZE_RD(hw_info); + /* Get the total valid sensors */ + j = 0; + for (i = 0; i < total; i++) { + if (altra_sensor_is_valid(ctx, metric_info + HW_METRIC_DATA_REG + + i * data_size, data_size)) + j++; + } + total = j; + + if (!ctx->sensor_list[type]) { + ctx->sensor_list[type] = devm_kzalloc(ctx->dev, + sizeof(struct sensor_item) * total, + GFP_KERNEL); + } else { + item_list = devm_kzalloc(ctx->dev, + sizeof(*item) * (ctx->sensor_list_cnt[type] + total), + GFP_KERNEL); + if (!item_list) + return -ENOMEM; + memcpy(item_list, ctx->sensor_list[type], + sizeof(*item) * ctx->sensor_list_cnt[type]); + devm_kfree(ctx->dev, ctx->sensor_list[type]); + ctx->sensor_list[type] = item_list; + } + + s_config = devm_kcalloc(ctx->dev, total, sizeof(u32), GFP_KERNEL); + if (!s_config) + return -ENOMEM; + info->type = type; + info->config = s_config; + + /* Set up sensor entry */ + item_list = ctx->sensor_list[type]; + j = 0; + for (i = 0; i < HW_METRIC_INFO_DATACNT_RD(hw_info); i++) { + /* Check if sensor is valid */ + if (!altra_sensor_is_valid(ctx, metric_info + HW_METRIC_DATA_REG + + i * data_size, data_size)) + continue; + + item = &item_list[ctx->sensor_list_cnt[type]]; + item->hw_reg = metric_info + HW_METRIC_DATA_REG + i * data_size; + scnprintf(item->label, SENSOR_ITEM_LABEL_SIZE, "%s %03u", label, j); + item->scale_factor = altra_hwmon_scale_factor(HW_METRIC_INFO_UNIT_RD(hw_info)); + item->data_size = data_size; + s_config[j] = altra_hwmon_type2flag(type); + ctx->sensor_list_cnt[type]++; + j++; + } + + return 0; +} + +static int altra_hwmon_create_sensors(struct altra_hwmon_context *ctx) +{ + u32 metrics_info; + u32 total_metric; + u32 hw_reg; + u32 hw_end_reg; + int ret; + u32 val; + int i; + int used; + + if (altra_hwmon_read32(ctx, HW_METRICS_ID_REG) != HW_METRICS_ID) + return -ENODEV; + + metrics_info = altra_hwmon_read32(ctx, HW_METRICS_INFO_REG); + if (HW_METRICS_INFO_VER_RD(metrics_info) != HW_SUPPORTED_VER) + return -ENODEV; + + total_metric = HW_METRICS_INFO_CNT_RD(metrics_info); + ctx->channel_info = devm_kzalloc(ctx->dev, + sizeof(struct hwmon_channel_info) * total_metric, + GFP_KERNEL); + if (!ctx->channel_info) + return -ENOMEM; + ctx->info = devm_kzalloc(ctx->dev, + sizeof(struct hwmon_channel_info *) * (total_metric + 1), + GFP_KERNEL); + if (!ctx->info) + return -ENOMEM; + + hw_reg = HW_METRICS_HDRSIZE; + for (used = 0, i = 0; i < total_metric; i++) { + /* Check for out of bound */ + if ((hw_reg + HW_METRIC_HDRSIZE) > ctx->base_size) { + dev_err(ctx->dev, + "malform metric header 0x%x (exceeded range). Ignore remaining\n", + hw_reg); + break; + } + + /* + * At least a metric header. Check with data. + */ + val = altra_hwmon_read32(ctx, hw_reg + HW_METRIC_INFO_REG); + hw_end_reg = hw_reg + HW_METRIC_HDRSIZE + + HW_METRIC_INFO_DATASIZE_RD(val) * + HW_METRIC_INFO_DATACNT_RD(val); + if (hw_end_reg > ctx->base_size) { + dev_err(ctx->dev, + "malform metric data 0x%x (exceeded range). Ignore remaining\n", + hw_reg); + break; + } + ret = altra_create_sensor(ctx, hw_reg, &ctx->channel_info[used]); + + /* 64-bit alignment */ + hw_reg = hw_end_reg; + hw_reg = ((hw_reg + 7) / 8) * 8; + if (ret == -ENODEV) + continue; + if (ret < 0) + return ret; + ctx->info[used] = &ctx->channel_info[used]; + used++; + } + ctx->info[used] = NULL; + return 0; +} + +static int altra_hwmon_probe(struct platform_device *pdev) +{ + const struct acpi_device_id *acpi_id; + struct altra_hwmon_context *ctx; + struct device *dev = &pdev->dev; + struct resource *res; + int version; + int err; + + ctx = devm_kzalloc(dev, sizeof(struct altra_hwmon_context), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + dev_set_drvdata(dev, ctx); + ctx->dev = dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; + + acpi_id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!acpi_id) + return -EINVAL; + + version = (int)acpi_id->driver_data; + + ctx->base_size = resource_size(res); + if (version == ALTRA_HWMON_VER1) + ctx->base = devm_ioremap_resource(dev, res); + else + ctx->base = memremap(res->start, ctx->base_size, MEMREMAP_WB); + if (IS_ERR(ctx->base)) + return PTR_ERR(ctx->base); + + /* Create sensors */ + err = altra_hwmon_create_sensors(ctx); + if (err != 0) { + if (err == -ENODEV) + dev_err(dev, "No sensor\n"); + else + dev_err(dev, "Failed to create sensors error %d\n", err); + return err; + } + + ctx->chip.ops = &altra_hwmon_ops; + ctx->chip.info = ctx->info; + ctx->hwmon_dev = devm_hwmon_device_register_with_info(dev, DRVNAME, ctx, + &ctx->chip, NULL); + if (IS_ERR(ctx->hwmon_dev)) { + dev_err(dev, "Fail to register with HWmon\n"); + err = PTR_ERR(ctx->hwmon_dev); + return err; + } + + return 0; +} + +static int altra_hwmon_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef CONFIG_ACPI +static const struct acpi_device_id altra_hwmon_acpi_match[] = { + {"AMPC0005", ALTRA_HWMON_VER1}, + {"AMPC0006", ALTRA_HWMON_VER2}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, altra_hwmon_acpi_match); +#endif + +static struct platform_driver altra_hwmon_driver = { + .probe = altra_hwmon_probe, + .remove = altra_hwmon_remove, + .driver = { + .name = "altra-hwmon", + .acpi_match_table = ACPI_PTR(altra_hwmon_acpi_match), + }, +}; +module_platform_driver(altra_hwmon_driver); + +MODULE_DESCRIPTION("Altra SoC hardware sensor monitor"); +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/hwmon/amc6821.c +++ linux-oracle-5.4.0/drivers/hwmon/amc6821.c @@ -935,10 +935,21 @@ MODULE_DEVICE_TABLE(i2c, amc6821_id); +static const struct of_device_id __maybe_unused amc6821_of_match[] = { + { + .compatible = "ti,amc6821", + .data = (void *)amc6821, + }, + { } +}; + +MODULE_DEVICE_TABLE(of, amc6821_of_match); + static struct i2c_driver amc6821_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "amc6821", + .of_match_table = of_match_ptr(amc6821_of_match), }, .probe = amc6821_probe, .id_table = amc6821_id, --- linux-oracle-5.4.0.orig/drivers/hwmon/applesmc.c +++ linux-oracle-5.4.0/drivers/hwmon/applesmc.c @@ -748,15 +748,18 @@ } ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length); + if (ret) + goto out; /* newer macbooks report a single 10-bit bigendian value */ if (data_length == 10) { left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2; goto out; } left = buffer[2]; + + ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); if (ret) goto out; - ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length); right = buffer[2]; out: @@ -805,12 +808,11 @@ to_index(attr)); ret = applesmc_read_key(newkey, buffer, 2); - speed = ((buffer[0] << 8 | buffer[1]) >> 2); - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); + + speed = ((buffer[0] << 8 | buffer[1]) >> 2); + return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); } static ssize_t applesmc_store_fan_speed(struct device *dev, @@ -846,12 +848,11 @@ u8 buffer[2]; ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); + + manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); } static ssize_t applesmc_store_fan_manual(struct device *dev, @@ -867,10 +868,11 @@ return -EINVAL; ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - val = (buffer[0] << 8 | buffer[1]); if (ret) goto out; + val = (buffer[0] << 8 | buffer[1]); + if (input) val = val | (0x01 << to_index(attr)); else @@ -946,13 +948,12 @@ u32 count; ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); - count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + - ((u32)buffer[2]<<8) + buffer[3]; - if (ret) return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); + + count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + + ((u32)buffer[2]<<8) + buffer[3]; + return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); } static ssize_t applesmc_key_at_index_read_show(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/hwmon/aspeed-pwm-tacho.c +++ linux-oracle-5.4.0/drivers/hwmon/aspeed-pwm-tacho.c @@ -194,6 +194,8 @@ u8 fan_tach_ch_source[16]; struct aspeed_cooling_device *cdev[8]; const struct attribute_group *groups[3]; + /* protects access to shared ASPEED_PTCR_RESULT */ + struct mutex tach_lock; }; enum type { TYPEM, TYPEN, TYPEO }; @@ -528,6 +530,8 @@ u8 fan_tach_ch_source, type, mode, both; int ret; + mutex_lock(&priv->tach_lock); + regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0); regmap_write(priv->regmap, ASPEED_PTCR_TRIGGER, 0x1 << fan_tach_ch); @@ -545,6 +549,8 @@ ASPEED_RPM_STATUS_SLEEP_USEC, usec); + mutex_unlock(&priv->tach_lock); + /* return -ETIMEDOUT if we didn't get an answer. */ if (ret) return ret; @@ -851,6 +857,8 @@ ret = of_property_read_u32(child, "reg", &pwm_port); if (ret) return ret; + if (pwm_port >= ARRAY_SIZE(pwm_port_params)) + return -EINVAL; aspeed_create_pwm_port(priv, (u8)pwm_port); ret = of_property_count_u8_elems(child, "cooling-levels"); @@ -907,6 +915,7 @@ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + mutex_init(&priv->tach_lock); priv->regmap = devm_regmap_init(dev, NULL, (__force void *)regs, &aspeed_pwm_tacho_regmap_config); if (IS_ERR(priv->regmap)) --- linux-oracle-5.4.0.orig/drivers/hwmon/coretemp.c +++ linux-oracle-5.4.0/drivers/hwmon/coretemp.c @@ -40,15 +40,12 @@ #define PKG_SYSFS_ATTR_NO 1 /* Sysfs attribute for package temp */ #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES 128 /* Number of Real cores per cpu */ -#define CORETEMP_NAME_LENGTH 19 /* String Length of attrs */ +#define NUM_REAL_CORES 512 /* Number of Real cores per cpu */ +#define CORETEMP_NAME_LENGTH 28 /* String Length of attrs */ #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) -#define TO_CORE_ID(cpu) (cpu_data(cpu).cpu_core_id) -#define TO_ATTR_NO(cpu) (TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO) - #ifdef CONFIG_SMP #define for_each_sibling(i, cpu) \ for_each_cpu(i, topology_sibling_cpumask(cpu)) @@ -91,6 +88,8 @@ struct platform_data { struct device *hwmon_dev; u16 pkg_id; + u16 cpu_map[NUM_REAL_CORES]; + struct ida ida; struct cpumask cpumask; struct temp_data *core_data[MAX_CORE_DATA]; struct device_attribute name_attr; @@ -243,10 +242,13 @@ */ if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) { for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) { - if (host_bridge->device == tjmax_pci_table[i].device) + if (host_bridge->device == tjmax_pci_table[i].device) { + pci_dev_put(host_bridge); return tjmax_pci_table[i].tjmax; + } } } + pci_dev_put(host_bridge); for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { if (strstr(c->x86_model_id, tjmax_table[i].id)) @@ -378,7 +380,7 @@ } static int create_core_attrs(struct temp_data *tdata, struct device *dev, - int attr_no) + int index) { int i; static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev, @@ -390,13 +392,20 @@ }; for (i = 0; i < tdata->attr_size; i++) { + /* + * We map the attr number to core id of the CPU + * The attr number is always core id + 2 + * The Pkgtemp will always show up as temp1_*, if available + */ + int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2; + snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, "temp%d_%s", attr_no, suffixes[i]); sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; tdata->sd_attrs[i].dev_attr.attr.mode = 0444; tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; - tdata->sd_attrs[i].index = attr_no; + tdata->sd_attrs[i].index = index; tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr; } tdata->attr_group.attrs = tdata->attrs; @@ -441,7 +450,7 @@ MSR_IA32_THERM_STATUS; tdata->is_pkg_data = pkg_flag; tdata->cpu = cpu; - tdata->cpu_core_id = TO_CORE_ID(cpu); + tdata->cpu_core_id = topology_core_id(cpu); tdata->attr_size = MAX_CORE_ATTRS; mutex_init(&tdata->update_lock); return tdata; @@ -454,22 +463,29 @@ struct platform_data *pdata = platform_get_drvdata(pdev); struct cpuinfo_x86 *c = &cpu_data(cpu); u32 eax, edx; - int err, attr_no; + int err, index; /* - * Find attr number for sysfs: - * We map the attr number to core id of the CPU - * The attr number is always core id + 2 - * The Pkgtemp will always show up as temp1_*, if available + * Get the index of tdata in pdata->core_data[] + * tdata for package: pdata->core_data[1] + * tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1] */ - attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu); + if (pkg_flag) { + index = PKG_SYSFS_ATTR_NO; + } else { + index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL); + if (index < 0) + return index; - if (attr_no > MAX_CORE_DATA - 1) - return -ERANGE; + pdata->cpu_map[index] = topology_core_id(cpu); + index += BASE_SYSFS_ATTR_NO; + } tdata = init_temp_data(cpu, pkg_flag); - if (!tdata) - return -ENOMEM; + if (!tdata) { + err = -ENOMEM; + goto ida_free; + } /* Test if we can access the status register */ err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx); @@ -494,17 +510,20 @@ } } - pdata->core_data[attr_no] = tdata; + pdata->core_data[index] = tdata; /* Create sysfs interfaces */ - err = create_core_attrs(tdata, pdata->hwmon_dev, attr_no); + err = create_core_attrs(tdata, pdata->hwmon_dev, index); if (err) goto exit_free; return 0; exit_free: - pdata->core_data[attr_no] = NULL; + pdata->core_data[index] = NULL; kfree(tdata); +ida_free: + if (!pkg_flag) + ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO); return err; } @@ -519,71 +538,63 @@ { struct temp_data *tdata = pdata->core_data[indx]; + /* if we errored on add then this is already gone */ + if (!tdata) + return; + /* Remove the sysfs attributes */ sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group); kfree(pdata->core_data[indx]); pdata->core_data[indx] = NULL; + + if (indx >= BASE_SYSFS_ATTR_NO) + ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO); } -static int coretemp_probe(struct platform_device *pdev) +static int coretemp_device_add(int zoneid) { - struct device *dev = &pdev->dev; + struct platform_device *pdev; struct platform_data *pdata; + int err; /* Initialize the per-zone data structures */ - pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL); + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - pdata->pkg_id = pdev->id; - platform_set_drvdata(pdev, pdata); + pdata->pkg_id = zoneid; + ida_init(&pdata->ida); - pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME, - pdata, NULL); - return PTR_ERR_OR_ZERO(pdata->hwmon_dev); -} - -static int coretemp_remove(struct platform_device *pdev) -{ - struct platform_data *pdata = platform_get_drvdata(pdev); - int i; + pdev = platform_device_alloc(DRVNAME, zoneid); + if (!pdev) { + err = -ENOMEM; + goto err_free_pdata; + } - for (i = MAX_CORE_DATA - 1; i >= 0; --i) - if (pdata->core_data[i]) - coretemp_remove_core(pdata, i); + err = platform_device_add(pdev); + if (err) + goto err_put_dev; + platform_set_drvdata(pdev, pdata); + zone_devices[zoneid] = pdev; return 0; -} -static struct platform_driver coretemp_driver = { - .driver = { - .name = DRVNAME, - }, - .probe = coretemp_probe, - .remove = coretemp_remove, -}; +err_put_dev: + platform_device_put(pdev); +err_free_pdata: + kfree(pdata); + return err; +} -static struct platform_device *coretemp_device_add(unsigned int cpu) +static void coretemp_device_remove(int zoneid) { - int err, zoneid = topology_logical_die_id(cpu); - struct platform_device *pdev; - - if (zoneid < 0) - return ERR_PTR(-ENOMEM); - - pdev = platform_device_alloc(DRVNAME, zoneid); - if (!pdev) - return ERR_PTR(-ENOMEM); - - err = platform_device_add(pdev); - if (err) { - platform_device_put(pdev); - return ERR_PTR(err); - } + struct platform_device *pdev = zone_devices[zoneid]; + struct platform_data *pdata = platform_get_drvdata(pdev); - zone_devices[zoneid] = pdev; - return pdev; + ida_destroy(&pdata->ida); + kfree(pdata); + platform_device_unregister(pdev); } static int coretemp_cpu_online(unsigned int cpu) @@ -607,7 +618,10 @@ if (!cpu_has(c, X86_FEATURE_DTHERM)) return -ENODEV; - if (!pdev) { + pdata = platform_get_drvdata(pdev); + if (!pdata->hwmon_dev) { + struct device *hwmon; + /* Check the microcode version of the CPU */ if (chk_ucode_version(cpu)) return -EINVAL; @@ -618,9 +632,11 @@ * online. So, initialize per-pkg data structures and * then bring this core online. */ - pdev = coretemp_device_add(cpu); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); + hwmon = hwmon_device_register_with_groups(&pdev->dev, DRVNAME, + pdata, NULL); + if (IS_ERR(hwmon)) + return PTR_ERR(hwmon); + pdata->hwmon_dev = hwmon; /* * Check whether pkgtemp support is available. @@ -630,7 +646,6 @@ coretemp_add_core(pdev, cpu, 1); } - pdata = platform_get_drvdata(pdev); /* * Check whether a thread sibling is already online. If not add the * interface for this CPU core. @@ -647,25 +662,28 @@ struct platform_device *pdev = coretemp_get_pdev(cpu); struct platform_data *pd; struct temp_data *tdata; - int indx, target; + int i, indx = -1, target; - /* - * Don't execute this on suspend as the device remove locks - * up the machine. - */ + /* No need to tear down any interfaces for suspend */ if (cpuhp_tasks_frozen) return 0; /* If the physical CPU device does not exist, just return */ - if (!pdev) + pd = platform_get_drvdata(pdev); + if (!pd->hwmon_dev) return 0; - /* The core id is too big, just return */ - indx = TO_ATTR_NO(cpu); - if (indx > MAX_CORE_DATA - 1) + for (i = 0; i < NUM_REAL_CORES; i++) { + if (pd->cpu_map[i] == topology_core_id(cpu)) { + indx = i + BASE_SYSFS_ATTR_NO; + break; + } + } + + /* Too many cores and this core is not populated, just return */ + if (indx < 0) return 0; - pd = platform_get_drvdata(pdev); tdata = pd->core_data[indx]; cpumask_clear_cpu(cpu, &pd->cpumask); @@ -685,13 +703,14 @@ } /* - * If all cores in this pkg are offline, remove the device. This - * will invoke the platform driver remove function, which cleans up - * the rest. + * If all cores in this pkg are offline, remove the interface. */ + tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; if (cpumask_empty(&pd->cpumask)) { - zone_devices[topology_logical_die_id(cpu)] = NULL; - platform_device_unregister(pdev); + if (tdata) + coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO); + hwmon_device_unregister(pd->hwmon_dev); + pd->hwmon_dev = NULL; return 0; } @@ -699,7 +718,6 @@ * Check whether this core is the target for the package * interface. We need to assign it to some other cpu. */ - tdata = pd->core_data[PKG_SYSFS_ATTR_NO]; if (tdata && tdata->cpu == cpu) { target = cpumask_first(&pd->cpumask); mutex_lock(&tdata->update_lock); @@ -718,7 +736,7 @@ static int __init coretemp_init(void) { - int err; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal @@ -734,20 +752,22 @@ if (!zone_devices) return -ENOMEM; - err = platform_driver_register(&coretemp_driver); - if (err) - goto outzone; + for (i = 0; i < max_zones; i++) { + err = coretemp_device_add(i); + if (err) + goto outzone; + } err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online", coretemp_cpu_online, coretemp_cpu_offline); if (err < 0) - goto outdrv; + goto outzone; coretemp_hp_online = err; return 0; -outdrv: - platform_driver_unregister(&coretemp_driver); outzone: + while (i--) + coretemp_device_remove(i); kfree(zone_devices); return err; } @@ -755,8 +775,11 @@ static void __exit coretemp_exit(void) { + int i; + cpuhp_remove_state(coretemp_hp_online); - platform_driver_unregister(&coretemp_driver); + for (i = 0; i < max_zones; i++) + coretemp_device_remove(i); kfree(zone_devices); } module_exit(coretemp_exit) --- linux-oracle-5.4.0.orig/drivers/hwmon/da9052-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/da9052-hwmon.c @@ -244,9 +244,9 @@ int channel = to_sensor_dev_attr(devattr)->index; int ret; - mutex_lock(&hwmon->hwmon_lock); + mutex_lock(&hwmon->da9052->auxadc_lock); ret = __da9052_read_tsi(dev, channel); - mutex_unlock(&hwmon->hwmon_lock); + mutex_unlock(&hwmon->da9052->auxadc_lock); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/hwmon/dell-smm-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/dell-smm-hwmon.c @@ -301,7 +301,7 @@ } /* - * Set the fan speed (off, low, high). Returns the new fan status. + * Set the fan speed (off, low, high, ...). */ static int i8k_set_fan(int fan, int speed) { @@ -313,7 +313,7 @@ speed = (speed < 0) ? 0 : ((speed > i8k_fan_max) ? i8k_fan_max : speed); regs.ebx = (fan & 0xff) | (speed << 8); - return i8k_smm(®s) ? : i8k_get_fan_status(fan); + return i8k_smm(®s); } static int i8k_get_temp_type(int sensor) @@ -427,7 +427,7 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg) { int val = 0; - int speed; + int speed, err; unsigned char buff[16]; int __user *argp = (int __user *)arg; @@ -488,7 +488,11 @@ if (copy_from_user(&speed, argp + 1, sizeof(int))) return -EFAULT; - val = i8k_set_fan(val, speed); + err = i8k_set_fan(val, speed); + if (err < 0) + return err; + + val = i8k_get_fan_status(val); break; default: @@ -588,15 +592,18 @@ .unlocked_ioctl = i8k_ioctl, }; +static struct proc_dir_entry *entry; + static void __init i8k_init_procfs(void) { /* Register the proc entry */ - proc_create("i8k", 0, NULL, &i8k_fops); + entry = proc_create("i8k", 0, NULL, &i8k_fops); } static void __exit i8k_exit_procfs(void) { - remove_proc_entry("i8k", NULL); + if (entry) + remove_proc_entry("i8k", NULL); } #else @@ -792,10 +799,10 @@ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr, int index) { - if (disallow_fan_support && index >= 8) + if (disallow_fan_support && index >= 20) return 0; if (disallow_fan_type_call && - (index == 9 || index == 12 || index == 15)) + (index == 21 || index == 25 || index == 28)) return 0; if (index >= 0 && index <= 1 && !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1)) --- linux-oracle-5.4.0.orig/drivers/hwmon/emc2103.c +++ linux-oracle-5.4.0/drivers/hwmon/emc2103.c @@ -443,7 +443,7 @@ } result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); - if (result) { + if (result < 0) { count = result; goto err; } --- linux-oracle-5.4.0.orig/drivers/hwmon/f71882fg.c +++ linux-oracle-5.4.0/drivers/hwmon/f71882fg.c @@ -1577,8 +1577,9 @@ temp *= 125; if (sign) temp -= 128000; - } else - temp = data->temp[nr] * 1000; + } else { + temp = ((s8)data->temp[nr]) * 1000; + } return sprintf(buf, "%d\n", temp); } --- linux-oracle-5.4.0.orig/drivers/hwmon/gpio-fan.c +++ linux-oracle-5.4.0/drivers/hwmon/gpio-fan.c @@ -391,6 +391,9 @@ if (!fan_data) return -EINVAL; + if (state >= fan_data->num_speed) + return -EINVAL; + set_fan_speed(fan_data, state); return 0; } --- linux-oracle-5.4.0.orig/drivers/hwmon/hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/hwmon.c @@ -51,6 +51,7 @@ #define to_hwmon_attr(d) \ container_of(d, struct hwmon_device_attribute, dev_attr) +#define to_dev_attr(a) container_of(a, struct device_attribute, attr) /* * Thermal zone information @@ -58,7 +59,7 @@ * also provides the sensor index. */ struct hwmon_thermal_data { - struct hwmon_device *hwdev; /* Reference to hwmon device */ + struct device *dev; /* Reference to hwmon device */ int index; /* sensor index */ }; @@ -95,9 +96,27 @@ NULL }; +static void hwmon_free_attrs(struct attribute **attrs) +{ + int i; + + for (i = 0; attrs[i]; i++) { + struct device_attribute *dattr = to_dev_attr(attrs[i]); + struct hwmon_device_attribute *hattr = to_hwmon_attr(dattr); + + kfree(hattr); + } + kfree(attrs); +} + static void hwmon_dev_release(struct device *dev) { - kfree(to_hwmon_device(dev)); + struct hwmon_device *hwdev = to_hwmon_device(dev); + + if (hwdev->group.attrs) + hwmon_free_attrs(hwdev->group.attrs); + kfree(hwdev->groups); + kfree(hwdev); } static struct class hwmon_class = { @@ -119,11 +138,11 @@ static int hwmon_thermal_get_temp(void *data, int *temp) { struct hwmon_thermal_data *tdata = data; - struct hwmon_device *hwdev = tdata->hwdev; + struct hwmon_device *hwdev = to_hwmon_device(tdata->dev); int ret; long t; - ret = hwdev->chip->ops->read(&hwdev->dev, hwmon_temp, hwmon_temp_input, + ret = hwdev->chip->ops->read(tdata->dev, hwmon_temp, hwmon_temp_input, tdata->index, &t); if (ret < 0) return ret; @@ -137,8 +156,7 @@ .get_temp = hwmon_thermal_get_temp, }; -static int hwmon_thermal_add_sensor(struct device *dev, - struct hwmon_device *hwdev, int index) +static int hwmon_thermal_add_sensor(struct device *dev, int index) { struct hwmon_thermal_data *tdata; struct thermal_zone_device *tzd; @@ -147,10 +165,10 @@ if (!tdata) return -ENOMEM; - tdata->hwdev = hwdev; + tdata->dev = dev; tdata->index = index; - tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, + tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata, &hwmon_thermal_ops); /* * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, @@ -162,8 +180,7 @@ return 0; } #else -static int hwmon_thermal_add_sensor(struct device *dev, - struct hwmon_device *hwdev, int index) +static int hwmon_thermal_add_sensor(struct device *dev, int index) { return 0; } @@ -250,8 +267,7 @@ (type == hwmon_fan && attr == hwmon_fan_label); } -static struct attribute *hwmon_genattr(struct device *dev, - const void *drvdata, +static struct attribute *hwmon_genattr(const void *drvdata, enum hwmon_sensor_types type, u32 attr, int index, @@ -279,7 +295,7 @@ if ((mode & 0222) && !ops->write) return ERR_PTR(-EINVAL); - hattr = devm_kzalloc(dev, sizeof(*hattr), GFP_KERNEL); + hattr = kzalloc(sizeof(*hattr), GFP_KERNEL); if (!hattr) return ERR_PTR(-ENOMEM); @@ -492,8 +508,7 @@ return n; } -static int hwmon_genattrs(struct device *dev, - const void *drvdata, +static int hwmon_genattrs(const void *drvdata, struct attribute **attrs, const struct hwmon_ops *ops, const struct hwmon_channel_info *info) @@ -519,7 +534,7 @@ attr_mask &= ~BIT(attr); if (attr >= template_size) return -EINVAL; - a = hwmon_genattr(dev, drvdata, info->type, attr, i, + a = hwmon_genattr(drvdata, info->type, attr, i, templates[attr], ops); if (IS_ERR(a)) { if (PTR_ERR(a) != -ENOENT) @@ -533,8 +548,7 @@ } static struct attribute ** -__hwmon_create_attrs(struct device *dev, const void *drvdata, - const struct hwmon_chip_info *chip) +__hwmon_create_attrs(const void *drvdata, const struct hwmon_chip_info *chip) { int ret, i, aindex = 0, nattrs = 0; struct attribute **attrs; @@ -545,15 +559,17 @@ if (nattrs == 0) return ERR_PTR(-EINVAL); - attrs = devm_kcalloc(dev, nattrs + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kcalloc(nattrs + 1, sizeof(*attrs), GFP_KERNEL); if (!attrs) return ERR_PTR(-ENOMEM); for (i = 0; chip->info[i]; i++) { - ret = hwmon_genattrs(dev, drvdata, &attrs[aindex], chip->ops, + ret = hwmon_genattrs(drvdata, &attrs[aindex], chip->ops, chip->info[i]); - if (ret < 0) + if (ret < 0) { + hwmon_free_attrs(attrs); return ERR_PTR(ret); + } aindex += ret; } @@ -595,14 +611,13 @@ for (i = 0; groups[i]; i++) ngroups++; - hwdev->groups = devm_kcalloc(dev, ngroups, sizeof(*groups), - GFP_KERNEL); + hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL); if (!hwdev->groups) { err = -ENOMEM; goto free_hwmon; } - attrs = __hwmon_create_attrs(dev, drvdata, chip); + attrs = __hwmon_create_attrs(drvdata, chip); if (IS_ERR(attrs)) { err = PTR_ERR(attrs); goto free_hwmon; @@ -630,8 +645,10 @@ dev_set_drvdata(hdev, drvdata); dev_set_name(hdev, HWMON_ID_FORMAT, id); err = device_register(hdev); - if (err) - goto free_hwmon; + if (err) { + put_device(hdev); + goto ida_remove; + } if (dev && dev->of_node && chip && chip->ops->read && chip->info[0]->type == hwmon_chip && @@ -647,8 +664,7 @@ hwmon_temp_input, j)) continue; if (info[i]->config[j] & HWMON_T_INPUT) { - err = hwmon_thermal_add_sensor(dev, - hwdev, j); + err = hwmon_thermal_add_sensor(hdev, j); if (err) { device_unregister(hdev); /* @@ -667,7 +683,7 @@ return hdev; free_hwmon: - kfree(hwdev); + hwmon_dev_release(hdev); ida_remove: ida_simple_remove(&hwmon_ida, id); return ERR_PTR(err); --- linux-oracle-5.4.0.orig/drivers/hwmon/i5500_temp.c +++ linux-oracle-5.4.0/drivers/hwmon/i5500_temp.c @@ -108,7 +108,7 @@ u32 tstimer; s8 tsfsc; - err = pci_enable_device(pdev); + err = pcim_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Failed to enable device\n"); return err; --- linux-oracle-5.4.0.orig/drivers/hwmon/ibmaem.c +++ linux-oracle-5.4.0/drivers/hwmon/ibmaem.c @@ -550,7 +550,7 @@ res = platform_device_add(data->pdev); if (res) - goto ipmi_err; + goto dev_add_err; platform_set_drvdata(data->pdev, data); @@ -598,7 +598,9 @@ ipmi_destroy_user(data->ipmi.user); ipmi_err: platform_set_drvdata(data->pdev, NULL); - platform_device_unregister(data->pdev); + platform_device_del(data->pdev); +dev_add_err: + platform_device_put(data->pdev); dev_err: ida_simple_remove(&aem_ida, data->id); id_err: @@ -690,7 +692,7 @@ res = platform_device_add(data->pdev); if (res) - goto ipmi_err; + goto dev_add_err; platform_set_drvdata(data->pdev, data); @@ -738,7 +740,9 @@ ipmi_destroy_user(data->ipmi.user); ipmi_err: platform_set_drvdata(data->pdev, NULL); - platform_device_unregister(data->pdev); + platform_device_del(data->pdev); +dev_add_err: + platform_device_put(data->pdev); dev_err: ida_simple_remove(&aem_ida, data->id); id_err: --- linux-oracle-5.4.0.orig/drivers/hwmon/ibmpex.c +++ linux-oracle-5.4.0/drivers/hwmon/ibmpex.c @@ -502,6 +502,7 @@ return; out_register: + list_del(&data->list); hwmon_device_unregister(data->hwmon_dev); out_user: ipmi_destroy_user(data->user); --- linux-oracle-5.4.0.orig/drivers/hwmon/ina3221.c +++ linux-oracle-5.4.0/drivers/hwmon/ina3221.c @@ -403,7 +403,7 @@ /* For enabling routine, increase refcount and resume() at first */ if (enable) { - ret = pm_runtime_get_sync(ina->pm_dev); + ret = pm_runtime_resume_and_get(ina->pm_dev); if (ret < 0) { dev_err(dev, "Failed to get PM runtime\n"); return ret; @@ -672,7 +672,7 @@ return ret; } else if (val > INA3221_CHANNEL3) { dev_err(dev, "invalid reg %d of %pOFn\n", val, child); - return ret; + return -EINVAL; } input = &ina->inputs[val]; --- linux-oracle-5.4.0.orig/drivers/hwmon/it87.c +++ linux-oracle-5.4.0/drivers/hwmon/it87.c @@ -486,6 +486,8 @@ #define has_pwm_freq2(data) ((data)->features & FEAT_PWM_FREQ2) #define has_six_temp(data) ((data)->features & FEAT_SIX_TEMP) #define has_vin3_5v(data) ((data)->features & FEAT_VIN3_5V) +#define has_scaling(data) ((data)->features & (FEAT_12MV_ADC | \ + FEAT_10_9MV_ADC)) struct it87_sio_data { int sioaddr; @@ -3098,7 +3100,7 @@ "Detected broken BIOS defaults, disabling PWM interface\n"); /* Starting with IT8721F, we handle scaling of internal voltages */ - if (has_12mv_adc(data)) { + if (has_scaling(data)) { if (sio_data->internal & BIT(0)) data->in_scaled |= BIT(3); /* in3 is AVCC */ if (sio_data->internal & BIT(1)) --- linux-oracle-5.4.0.orig/drivers/hwmon/jc42.c +++ linux-oracle-5.4.0/drivers/hwmon/jc42.c @@ -506,7 +506,7 @@ } data->config = config; - hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, + hwmon_dev = devm_hwmon_device_register_with_info(dev, "jc42", data, &jc42_chip_info, NULL); return PTR_ERR_OR_ZERO(hwmon_dev); --- linux-oracle-5.4.0.orig/drivers/hwmon/k10temp.c +++ linux-oracle-5.4.0/drivers/hwmon/k10temp.c @@ -349,6 +349,7 @@ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) }, { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) }, {} --- linux-oracle-5.4.0.orig/drivers/hwmon/lm80.c +++ linux-oracle-5.4.0/drivers/hwmon/lm80.c @@ -597,7 +597,6 @@ struct device *dev = &client->dev; struct device *hwmon_dev; struct lm80_data *data; - int rv; data = devm_kzalloc(dev, sizeof(struct lm80_data), GFP_KERNEL); if (!data) @@ -610,14 +609,8 @@ lm80_init_client(client); /* A few vars need to be filled upon startup */ - rv = lm80_read_value(client, LM80_REG_FAN_MIN(1)); - if (rv < 0) - return rv; - data->fan[f_min][0] = rv; - rv = lm80_read_value(client, LM80_REG_FAN_MIN(2)); - if (rv < 0) - return rv; - data->fan[f_min][1] = rv; + data->fan[f_min][0] = lm80_read_value(client, LM80_REG_FAN_MIN(1)); + data->fan[f_min][1] = lm80_read_value(client, LM80_REG_FAN_MIN(2)); hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, data, lm80_groups); --- linux-oracle-5.4.0.orig/drivers/hwmon/lm90.c +++ linux-oracle-5.4.0/drivers/hwmon/lm90.c @@ -35,6 +35,15 @@ * explicitly as max6659, or if its address is not 0x4c. * These chips lack the remote temperature offset feature. * + * This driver also supports the MAX6654 chip made by Maxim. This chip can be + * at 9 different addresses, similar to MAX6680/MAX6681. The MAX6654 is similar + * to MAX6657/MAX6658/MAX6659, but does not support critical temperature + * limits. Extended range is available by setting the configuration register + * accordingly, and is done during initialization. Extended precision is only + * available at conversion rates of 1 Hz and slower. Note that extended + * precision is not enabled by default, as this driver initializes all chips + * to 2 Hz by design. + * * This driver also supports the MAX6646, MAX6647, MAX6648, MAX6649 and * MAX6692 chips made by Maxim. These are again similar to the LM86, * but they use unsigned temperature values and can report temperatures @@ -61,10 +70,10 @@ * This driver also supports the G781 from GMT. This device is compatible * with the ADM1032. * - * This driver also supports TMP451 from Texas Instruments. This device is - * supported in both compatibility and extended mode. It's mostly compatible - * with ADT7461 except for local temperature low byte register and max - * conversion rate. + * This driver also supports TMP451 and TMP461 from Texas Instruments. + * Those devices are supported in both compatibility and extended mode. + * They are mostly compatible with ADT7461 except for local temperature + * low byte register and max conversion rate. * * Since the LM90 was the first chipset supported by this driver, most * comments will refer to this chipset, but are actually general and @@ -94,8 +103,8 @@ * have address 0x4d. * MAX6647 has address 0x4e. * MAX6659 can have address 0x4c, 0x4d or 0x4e. - * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, - * 0x4c, 0x4d or 0x4e. + * MAX6654, MAX6680, and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, + * 0x2a, 0x2b, 0x4c, 0x4d or 0x4e. * SA56004 can have address 0x48 through 0x4F. */ @@ -104,7 +113,7 @@ 0x4d, 0x4e, 0x4f, I2C_CLIENT_END }; enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, - max6646, w83l771, max6696, sa56004, g781, tmp451 }; + max6646, w83l771, max6696, sa56004, g781, tmp451, tmp461, max6654 }; /* * The LM90 registers @@ -145,7 +154,7 @@ #define LM90_REG_R_TCRIT_HYST 0x21 #define LM90_REG_W_TCRIT_HYST 0x21 -/* MAX6646/6647/6649/6657/6658/6659/6695/6696 registers */ +/* MAX6646/6647/6649/6654/6657/6658/6659/6695/6696 registers */ #define MAX6657_REG_R_LOCAL_TEMPL 0x11 #define MAX6696_REG_R_STATUS2 0x12 @@ -160,8 +169,12 @@ #define LM90_MAX_CONVRATE_MS 16000 /* Maximum conversion rate in ms */ -/* TMP451 registers */ +/* TMP451/TMP461 registers */ #define TMP451_REG_R_LOCAL_TEMPL 0x15 +#define TMP451_REG_CONALERT 0x22 + +#define TMP461_REG_CHEN 0x16 +#define TMP461_REG_DFC 0x24 /* * Device flags @@ -174,7 +187,10 @@ #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ #define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ #define LM90_HAVE_BROKEN_ALERT (1 << 7) /* Broken alert */ -#define LM90_PAUSE_FOR_CONFIG (1 << 8) /* Pause conversion for config */ +#define LM90_HAVE_EXTENDED_TEMP (1 << 8) /* extended temperature support*/ +#define LM90_PAUSE_FOR_CONFIG (1 << 9) /* Pause conversion for config */ +#define LM90_HAVE_CRIT (1 << 10)/* Chip supports CRIT/OVERT register */ +#define LM90_HAVE_CRIT_ALRM_SWP (1 << 11)/* critical alarm bits swapped */ /* LM90 status */ #define LM90_STATUS_LTHRM (1 << 0) /* local THERM limit tripped */ @@ -184,6 +200,7 @@ #define LM90_STATUS_RHIGH (1 << 4) /* remote high temp limit tripped */ #define LM90_STATUS_LLOW (1 << 5) /* local low temp limit tripped */ #define LM90_STATUS_LHIGH (1 << 6) /* local high temp limit tripped */ +#define LM90_STATUS_BUSY (1 << 7) /* conversion is ongoing */ #define MAX6696_STATUS2_R2THRM (1 << 1) /* remote2 THERM limit tripped */ #define MAX6696_STATUS2_R2OPEN (1 << 2) /* remote2 is an open circuit */ @@ -209,6 +226,7 @@ { "max6646", max6646 }, { "max6647", max6646 }, { "max6649", max6646 }, + { "max6654", max6654 }, { "max6657", max6657 }, { "max6658", max6657 }, { "max6659", max6659 }, @@ -220,6 +238,7 @@ { "w83l771", w83l771 }, { "sa56004", sa56004 }, { "tmp451", tmp451 }, + { "tmp461", tmp461 }, { } }; MODULE_DEVICE_TABLE(i2c, lm90_id); @@ -270,6 +289,10 @@ .data = (void *)max6646 }, { + .compatible = "dallas,max6654", + .data = (void *)max6654 + }, + { .compatible = "dallas,max6657", .data = (void *)max6657 }, @@ -313,6 +336,10 @@ .compatible = "ti,tmp451", .data = (void *)tmp451 }, + { + .compatible = "ti,tmp461", + .data = (void *)tmp461 + }, { }, }; MODULE_DEVICE_TABLE(of, lm90_of_match); @@ -331,80 +358,99 @@ static const struct lm90_params lm90_params[] = { [adm1032] = { .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT - | LM90_HAVE_BROKEN_ALERT, + | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 10, }, [adt7461] = { .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT - | LM90_HAVE_BROKEN_ALERT, + | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP + | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 10, }, [g781] = { .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT - | LM90_HAVE_BROKEN_ALERT, + | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_CRIT, .alert_alarms = 0x7c, - .max_convrate = 8, + .max_convrate = 7, }, [lm86] = { - .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT + | LM90_HAVE_CRIT, .alert_alarms = 0x7b, .max_convrate = 9, }, [lm90] = { - .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT + | LM90_HAVE_CRIT, .alert_alarms = 0x7b, .max_convrate = 9, }, [lm99] = { - .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT + | LM90_HAVE_CRIT, .alert_alarms = 0x7b, .max_convrate = 9, }, [max6646] = { + .flags = LM90_HAVE_CRIT | LM90_HAVE_BROKEN_ALERT, .alert_alarms = 0x7c, .max_convrate = 6, .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, }, + [max6654] = { + .flags = LM90_HAVE_BROKEN_ALERT, + .alert_alarms = 0x7c, + .max_convrate = 7, + .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, + }, [max6657] = { - .flags = LM90_PAUSE_FOR_CONFIG, + .flags = LM90_PAUSE_FOR_CONFIG | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 8, .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, }, [max6659] = { - .flags = LM90_HAVE_EMERGENCY, + .flags = LM90_HAVE_EMERGENCY | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 8, .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, }, [max6680] = { - .flags = LM90_HAVE_OFFSET, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_CRIT + | LM90_HAVE_CRIT_ALRM_SWP | LM90_HAVE_BROKEN_ALERT, .alert_alarms = 0x7c, .max_convrate = 7, }, [max6696] = { .flags = LM90_HAVE_EMERGENCY - | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3, + | LM90_HAVE_EMERGENCY_ALARM | LM90_HAVE_TEMP3 | LM90_HAVE_CRIT, .alert_alarms = 0x1c7c, .max_convrate = 6, .reg_local_ext = MAX6657_REG_R_LOCAL_TEMPL, }, [w83l771] = { - .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 8, }, [sa56004] = { - .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT, + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT, .alert_alarms = 0x7b, .max_convrate = 9, .reg_local_ext = SA56004_REG_R_LOCAL_TEMPL, }, [tmp451] = { .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT - | LM90_HAVE_BROKEN_ALERT, + | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT, + .alert_alarms = 0x7c, + .max_convrate = 9, + .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, + }, + [tmp461] = { + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT + | LM90_HAVE_BROKEN_ALERT | LM90_HAVE_EXTENDED_TEMP | LM90_HAVE_CRIT, .alert_alarms = 0x7c, .max_convrate = 9, .reg_local_ext = TMP451_REG_R_LOCAL_TEMPL, @@ -632,20 +678,22 @@ struct i2c_client *client = data->client; int val; - val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT); - if (val < 0) - return val; - data->temp8[LOCAL_CRIT] = val; + if (data->flags & LM90_HAVE_CRIT) { + val = lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT); + if (val < 0) + return val; + data->temp8[LOCAL_CRIT] = val; - val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT); - if (val < 0) - return val; - data->temp8[REMOTE_CRIT] = val; + val = lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT); + if (val < 0) + return val; + data->temp8[REMOTE_CRIT] = val; - val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST); - if (val < 0) - return val; - data->temp_hyst = val; + val = lm90_read_reg(client, LM90_REG_R_TCRIT_HYST); + if (val < 0) + return val; + data->temp_hyst = val; + } val = lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH); if (val < 0) @@ -773,7 +821,7 @@ val = lm90_read_reg(client, LM90_REG_R_STATUS); if (val < 0) return val; - data->alarms = val; /* lower 8 bit of alarms */ + data->alarms = val & ~LM90_STATUS_BUSY; if (data->kind == max6696) { val = lm90_select_remote_channel(data, 1); @@ -979,7 +1027,7 @@ s16 temp11 = data->temp11[index]; int temp; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) temp = temp_from_u16_adt7461(data, temp11); else if (data->kind == max6646) temp = temp_from_u16(temp11); @@ -1013,7 +1061,7 @@ if (data->kind == lm99 && index <= 2) val -= 16000; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) data->temp11[index] = temp_to_u16_adt7461(data, val); else if (data->kind == max6646) data->temp11[index] = temp_to_u8(val) << 8; @@ -1040,7 +1088,7 @@ s8 temp8 = data->temp8[index]; int temp; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) temp = temp_from_u8_adt7461(data, temp8); else if (data->kind == max6646) temp = temp_from_u8(temp8); @@ -1073,7 +1121,7 @@ if (data->kind == lm99 && index == 3) val -= 16000; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) data->temp8[index] = temp_to_u8_adt7461(data, val); else if (data->kind == max6646) data->temp8[index] = temp_to_u8(val); @@ -1091,7 +1139,7 @@ { int temp; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) temp = temp_from_u8_adt7461(data, data->temp8[index]); else if (data->kind == max6646) temp = temp_from_u8(data->temp8[index]); @@ -1111,7 +1159,7 @@ int temp; int err; - if (data->kind == adt7461 || data->kind == tmp451) + if (data->flags & LM90_HAVE_EXTENDED_TEMP) temp = temp_from_u8_adt7461(data, data->temp8[LOCAL_CRIT]); else if (data->kind == max6646) temp = temp_from_u8(data->temp8[LOCAL_CRIT]); @@ -1147,6 +1195,7 @@ static const u8 lm90_min_alarm_bits[3] = { 5, 3, 11 }; static const u8 lm90_max_alarm_bits[3] = { 6, 4, 12 }; static const u8 lm90_crit_alarm_bits[3] = { 0, 1, 9 }; +static const u8 lm90_crit_alarm_bits_swapped[3] = { 1, 0, 9 }; static const u8 lm90_emergency_alarm_bits[3] = { 15, 13, 14 }; static const u8 lm90_fault_bits[3] = { 0, 2, 10 }; @@ -1172,7 +1221,10 @@ *val = (data->alarms >> lm90_max_alarm_bits[channel]) & 1; break; case hwmon_temp_crit_alarm: - *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; + if (data->flags & LM90_HAVE_CRIT_ALRM_SWP) + *val = (data->alarms >> lm90_crit_alarm_bits_swapped[channel]) & 1; + else + *val = (data->alarms >> lm90_crit_alarm_bits[channel]) & 1; break; case hwmon_temp_emergency_alarm: *val = (data->alarms >> lm90_emergency_alarm_bits[channel]) & 1; @@ -1420,12 +1472,11 @@ if (man_id < 0 || chip_id < 0 || config1 < 0 || convrate < 0) return -ENODEV; - if (man_id == 0x01 || man_id == 0x5C || man_id == 0x41) { + if (man_id == 0x01 || man_id == 0x5C || man_id == 0xA1) { config2 = i2c_smbus_read_byte_data(client, LM90_REG_R_CONFIG2); if (config2 < 0) return -ENODEV; - } else - config2 = 0; /* Make compiler happy */ + } if ((address == 0x4C || address == 0x4D) && man_id == 0x01) { /* National Semiconductor */ @@ -1557,6 +1608,16 @@ && (config1 & 0x3f) == 0x00 && convrate <= 0x07) { name = "max6646"; + } else + /* + * The chip_id of the MAX6654 holds the revision of the chip. + * The lowest 3 bits of the config1 register are unused and + * should return zero when read. + */ + if (chip_id == 0x08 + && (config1 & 0x07) == 0x00 + && convrate <= 0x07) { + name = "max6654"; } } else if (address == 0x4C @@ -1589,18 +1650,26 @@ && convrate <= 0x08) name = "g781"; } else - if (address == 0x4C - && man_id == 0x55) { /* Texas Instruments */ - int local_ext; + if (man_id == 0x55 && chip_id == 0x00 && + (config1 & 0x1B) == 0x00 && convrate <= 0x09) { + int local_ext, conalert, chen, dfc; local_ext = i2c_smbus_read_byte_data(client, TMP451_REG_R_LOCAL_TEMPL); - - if (chip_id == 0x00 /* TMP451 */ - && (config1 & 0x1B) == 0x00 - && convrate <= 0x09 - && (local_ext & 0x0F) == 0x00) - name = "tmp451"; + conalert = i2c_smbus_read_byte_data(client, + TMP451_REG_CONALERT); + chen = i2c_smbus_read_byte_data(client, TMP461_REG_CHEN); + dfc = i2c_smbus_read_byte_data(client, TMP461_REG_DFC); + + if ((local_ext & 0x0F) == 0x00 && + (conalert & 0xf1) == 0x01 && + (chen & 0xfc) == 0x00 && + (dfc & 0xfc) == 0x00) { + if (address == 0x4c && !(chen & 0x03)) + name = "tmp451"; + else if (address >= 0x48 && address <= 0x4f) + name = "tmp461"; + } } if (!name) { /* identification failed */ @@ -1647,7 +1716,7 @@ lm90_set_convrate(client, data, 500); /* 500ms; 2Hz conversion rate */ /* Check Temperature Range Select */ - if (data->kind == adt7461 || data->kind == tmp451) { + if (data->flags & LM90_HAVE_EXTENDED_TEMP) { if (config & 0x04) data->flags |= LM90_FLAG_ADT7461_EXT; } @@ -1661,6 +1730,15 @@ config |= 0x18; /* + * Put MAX6654 into extended range (0x20, extend minimum range from + * 0 degrees to -64 degrees). Note that extended resolution is not + * possible on the MAX6654 unless conversion rate is set to 1 Hz or + * slower, which is intentionally not done by default. + */ + if (data->kind == max6654) + config |= 0x20; + + /* * Select external channel 0 for max6695/96 */ if (data->kind == max6696) @@ -1806,11 +1884,14 @@ info->config = data->channel_config; data->channel_config[0] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | - HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | - HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM; + HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM; data->channel_config[1] = HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX | - HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM | - HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT; + HWMON_T_MIN_ALARM | HWMON_T_MAX_ALARM | HWMON_T_FAULT; + + if (data->flags & LM90_HAVE_CRIT) { + data->channel_config[0] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST; + data->channel_config[1] |= HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_CRIT_HYST; + } if (data->flags & LM90_HAVE_OFFSET) data->channel_config[1] |= HWMON_T_OFFSET; --- linux-oracle-5.4.0.orig/drivers/hwmon/lm95234.c +++ linux-oracle-5.4.0/drivers/hwmon/lm95234.c @@ -301,7 +301,8 @@ if (ret < 0) return ret; - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000), + 1000); mutex_lock(&data->update_lock); data->tcrit2[index] = val; @@ -350,7 +351,7 @@ if (ret < 0) return ret; - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000); mutex_lock(&data->update_lock); data->tcrit1[index] = val; @@ -391,7 +392,7 @@ if (ret < 0) return ret; - val = DIV_ROUND_CLOSEST(val, 1000); + val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000); val = clamp_val((int)data->tcrit1[index] - val, 0, 31); mutex_lock(&data->update_lock); @@ -431,7 +432,7 @@ return ret; /* Accuracy is 1/2 degrees C */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500); mutex_lock(&data->update_lock); data->toffset[index] = val; --- linux-oracle-5.4.0.orig/drivers/hwmon/ltc2945.c +++ linux-oracle-5.4.0/drivers/hwmon/ltc2945.c @@ -248,6 +248,8 @@ /* convert to register value, then clamp and write result */ regval = ltc2945_val_to_reg(dev, reg, val); + if (regval < 0) + return regval; if (is_power_reg(reg)) { regval = clamp_val(regval, 0, 0xffffff); regbuf[0] = regval >> 16; --- linux-oracle-5.4.0.orig/drivers/hwmon/max16065.c +++ linux-oracle-5.4.0/drivers/hwmon/max16065.c @@ -114,9 +114,10 @@ return limit * range / 256; } -static inline int MV_TO_LIMIT(int mv, int range) +static inline int MV_TO_LIMIT(unsigned long mv, int range) { - return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); + mv = clamp_val(mv, 0, ULONG_MAX / 256); + return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range); } static inline int ADC_TO_CURR(int adc, int gain) --- linux-oracle-5.4.0.orig/drivers/hwmon/max31722.c +++ linux-oracle-5.4.0/drivers/hwmon/max31722.c @@ -6,7 +6,6 @@ * Copyright (c) 2016, Intel Corporation. */ -#include #include #include #include @@ -133,20 +132,12 @@ {"max31723", 0}, {} }; - -static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = { - {"MAX31722", 0}, - {"MAX31723", 0}, - {} -}; - MODULE_DEVICE_TABLE(spi, max31722_spi_id); static struct spi_driver max31722_driver = { .driver = { .name = "max31722", .pm = &max31722_pm_ops, - .acpi_match_table = ACPI_PTR(max31722_acpi_id), }, .probe = max31722_probe, .remove = max31722_remove, --- linux-oracle-5.4.0.orig/drivers/hwmon/max31790.c +++ linux-oracle-5.4.0/drivers/hwmon/max31790.c @@ -27,6 +27,7 @@ /* Fan Config register bits */ #define MAX31790_FAN_CFG_RPM_MODE 0x80 +#define MAX31790_FAN_CFG_CTRL_MON 0x10 #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08 #define MAX31790_FAN_CFG_TACH_INPUT 0x01 @@ -104,7 +105,7 @@ data->tach[NR_CHANNEL + i] = rv; } else { rv = i2c_smbus_read_word_swapped(client, - MAX31790_REG_PWMOUT(i)); + MAX31790_REG_PWM_DUTY_CYCLE(i)); if (rv < 0) goto abort; data->pwm[i] = rv; @@ -170,7 +171,7 @@ switch (attr) { case hwmon_fan_input: - sr = get_tach_period(data->fan_dynamics[channel]); + sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]); rpm = RPM_FROM_REG(data->tach[channel], sr); *val = rpm; return 0; @@ -271,12 +272,12 @@ *val = data->pwm[channel] >> 8; return 0; case hwmon_pwm_enable: - if (fan_config & MAX31790_FAN_CFG_RPM_MODE) + if (fan_config & MAX31790_FAN_CFG_CTRL_MON) + *val = 0; + else if (fan_config & MAX31790_FAN_CFG_RPM_MODE) *val = 2; - else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN) - *val = 1; else - *val = 0; + *val = 1; return 0; default: return -EOPNOTSUPP; @@ -299,31 +300,41 @@ err = -EINVAL; break; } - data->pwm[channel] = val << 8; + data->valid = false; err = i2c_smbus_write_word_swapped(client, MAX31790_REG_PWMOUT(channel), - data->pwm[channel]); + val << 8); break; case hwmon_pwm_enable: fan_config = data->fan_config[channel]; if (val == 0) { - fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN | - MAX31790_FAN_CFG_RPM_MODE); + fan_config |= MAX31790_FAN_CFG_CTRL_MON; + /* + * Disable RPM mode; otherwise disabling fan speed + * monitoring is not possible. + */ + fan_config &= ~MAX31790_FAN_CFG_RPM_MODE; } else if (val == 1) { - fan_config = (fan_config | - MAX31790_FAN_CFG_TACH_INPUT_EN) & - ~MAX31790_FAN_CFG_RPM_MODE; + fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE); } else if (val == 2) { - fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN | - MAX31790_FAN_CFG_RPM_MODE; + fan_config &= ~MAX31790_FAN_CFG_CTRL_MON; + /* + * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its + * own if MAX31790_FAN_CFG_RPM_MODE is set. + * Do it here as well to reflect the actual register + * value in the cache. + */ + fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN); } else { err = -EINVAL; break; } - data->fan_config[channel] = fan_config; - err = i2c_smbus_write_byte_data(client, - MAX31790_REG_FAN_CONFIG(channel), - fan_config); + if (fan_config != data->fan_config[channel]) { + err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel), + fan_config); + if (!err) + data->fan_config[channel] = fan_config; + } break; default: err = -EOPNOTSUPP; --- linux-oracle-5.4.0.orig/drivers/hwmon/max6697.c +++ linux-oracle-5.4.0/drivers/hwmon/max6697.c @@ -38,8 +38,9 @@ * Map device tree / platform data register bit map to chip bit map. * Applies to alert register and over-temperature register. */ -#define MAX6697_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ +#define MAX6697_ALERT_MAP_BITS(reg) ((((reg) & 0x7e) >> 1) | \ (((reg) & 0x01) << 6) | ((reg) & 0x80)) +#define MAX6697_OVERT_MAP_BITS(reg) (((reg) >> 1) | (((reg) & 0x01) << 7)) #define MAX6697_REG_STAT(n) (0x44 + (n)) @@ -304,6 +305,7 @@ return ret; mutex_lock(&data->update_lock); + temp = clamp_val(temp, -1000000, 1000000); /* prevent underflow */ temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset; temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127); data->temp[nr][index] = temp; @@ -357,14 +359,14 @@ static SENSOR_DEVICE_ATTR_RO(temp7_max_alarm, alarm, 21); static SENSOR_DEVICE_ATTR_RO(temp8_max_alarm, alarm, 23); -static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 14); +static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 15); static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 8); static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 9); static SENSOR_DEVICE_ATTR_RO(temp4_crit_alarm, alarm, 10); static SENSOR_DEVICE_ATTR_RO(temp5_crit_alarm, alarm, 11); static SENSOR_DEVICE_ATTR_RO(temp6_crit_alarm, alarm, 12); static SENSOR_DEVICE_ATTR_RO(temp7_crit_alarm, alarm, 13); -static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 15); +static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 14); static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 1); static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 2); @@ -562,12 +564,12 @@ return ret; ret = i2c_smbus_write_byte_data(client, MAX6697_REG_ALERT_MASK, - MAX6697_MAP_BITS(pdata->alert_mask)); + MAX6697_ALERT_MAP_BITS(pdata->alert_mask)); if (ret < 0) return ret; ret = i2c_smbus_write_byte_data(client, MAX6697_REG_OVERT_MASK, - MAX6697_MAP_BITS(pdata->over_temperature_mask)); + MAX6697_OVERT_MAP_BITS(pdata->over_temperature_mask)); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/hwmon/mlxreg-fan.c +++ linux-oracle-5.4.0/drivers/hwmon/mlxreg-fan.c @@ -127,6 +127,12 @@ if (err) return err; + if (MLXREG_FAN_GET_FAULT(regval, tacho->mask)) { + /* FAN is broken - return zero for FAN speed. */ + *val = 0; + return 0; + } + *val = MLXREG_FAN_GET_RPM(regval, fan->divider, fan->samples); break; @@ -291,8 +297,8 @@ { struct mlxreg_fan *fan = cdev->devdata; unsigned long cur_state; + int i, config = 0; u32 regval; - int i; int err; /* @@ -305,6 +311,12 @@ * overwritten. */ if (state >= MLXREG_FAN_SPEED_MIN && state <= MLXREG_FAN_SPEED_MAX) { + /* + * This is configuration change, which is only supported through sysfs. + * For configuration non-zero value is to be returned to avoid thermal + * statistics update. + */ + config = 1; state -= MLXREG_FAN_MAX_STATE; for (i = 0; i < state; i++) fan->cooling_levels[i] = state; @@ -319,7 +331,7 @@ cur_state = MLXREG_FAN_PWM_DUTY2STATE(regval); if (state < cur_state) - return 0; + return config; state = cur_state; } @@ -335,7 +347,7 @@ dev_err(fan->dev, "Failed to write PWM duty\n"); return err; } - return 0; + return config; } static const struct thermal_cooling_device_ops mlxreg_fan_cooling_ops = { --- linux-oracle-5.4.0.orig/drivers/hwmon/nct6775.c +++ linux-oracle-5.4.0/drivers/hwmon/nct6775.c @@ -786,13 +786,13 @@ "Agent1 Dimm1", "BYTE_TEMP0", "BYTE_TEMP1", - "", - "", + "PECI Agent 0 Calibration", /* undocumented */ + "PECI Agent 1 Calibration", /* undocumented */ "", "Virtual_TEMP" }; -#define NCT6798_TEMP_MASK 0x8fff0ffe +#define NCT6798_TEMP_MASK 0xbfff0ffe #define NCT6798_VIRT_TEMP_MASK 0x80000c00 /* NCT6102D/NCT6106D specific data */ @@ -2374,7 +2374,7 @@ if (err < 0) return err; - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000); mutex_lock(&data->update_lock); data->temp_offset[nr] = val; --- linux-oracle-5.4.0.orig/drivers/hwmon/nct7802.c +++ linux-oracle-5.4.0/drivers/hwmon/nct7802.c @@ -23,8 +23,8 @@ static const u8 REG_VOLTAGE[5] = { 0x09, 0x0a, 0x0c, 0x0d, 0x0e }; static const u8 REG_VOLTAGE_LIMIT_LSB[2][5] = { - { 0x40, 0x00, 0x42, 0x44, 0x46 }, - { 0x3f, 0x00, 0x41, 0x43, 0x45 }, + { 0x46, 0x00, 0x40, 0x42, 0x44 }, + { 0x45, 0x00, 0x3f, 0x41, 0x43 }, }; static const u8 REG_VOLTAGE_LIMIT_MSB[5] = { 0x48, 0x00, 0x47, 0x47, 0x48 }; @@ -58,6 +58,8 @@ struct nct7802_data { struct regmap *regmap; struct mutex access_lock; /* for multi-byte read and write operations */ + u8 in_status; + struct mutex in_alarm_lock; }; static ssize_t temp_type_show(struct device *dev, @@ -368,6 +370,66 @@ return err ? : count; } +static ssize_t in_alarm_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr); + struct nct7802_data *data = dev_get_drvdata(dev); + int volt, min, max, ret; + unsigned int val; + + mutex_lock(&data->in_alarm_lock); + + /* + * The SMI Voltage status register is the only register giving a status + * for voltages. A bit is set for each input crossing a threshold, in + * both direction, but the "inside" or "outside" limits info is not + * available. Also this register is cleared on read. + * Note: this is not explicitly spelled out in the datasheet, but + * from experiment. + * To deal with this we use a status cache with one validity bit and + * one status bit for each input. Validity is cleared at startup and + * each time the register reports a change, and the status is processed + * by software based on current input value and limits. + */ + ret = regmap_read(data->regmap, 0x1e, &val); /* SMI Voltage status */ + if (ret < 0) + goto abort; + + /* invalidate cached status for all inputs crossing a threshold */ + data->in_status &= ~((val & 0x0f) << 4); + + /* if cached status for requested input is invalid, update it */ + if (!(data->in_status & (0x10 << sattr->index))) { + ret = nct7802_read_voltage(data, sattr->nr, 0); + if (ret < 0) + goto abort; + volt = ret; + + ret = nct7802_read_voltage(data, sattr->nr, 1); + if (ret < 0) + goto abort; + min = ret; + + ret = nct7802_read_voltage(data, sattr->nr, 2); + if (ret < 0) + goto abort; + max = ret; + + if (volt < min || volt > max) + data->in_status |= (1 << sattr->index); + else + data->in_status &= ~(1 << sattr->index); + + data->in_status |= 0x10 << sattr->index; + } + + ret = sprintf(buf, "%u\n", !!(data->in_status & (1 << sattr->index))); +abort: + mutex_unlock(&data->in_alarm_lock); + return ret; +} + static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -646,7 +708,7 @@ if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ return 0; - if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ + if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ return 0; return attr->mode; @@ -660,7 +722,7 @@ static SENSOR_DEVICE_ATTR_2_RO(in0_input, in, 0, 0); static SENSOR_DEVICE_ATTR_2_RW(in0_min, in, 0, 1); static SENSOR_DEVICE_ATTR_2_RW(in0_max, in, 0, 2); -static SENSOR_DEVICE_ATTR_2_RO(in0_alarm, alarm, 0x1e, 3); +static SENSOR_DEVICE_ATTR_2_RO(in0_alarm, in_alarm, 0, 3); static SENSOR_DEVICE_ATTR_2_RW(in0_beep, beep, 0x5a, 3); static SENSOR_DEVICE_ATTR_2_RO(in1_input, in, 1, 0); @@ -668,19 +730,19 @@ static SENSOR_DEVICE_ATTR_2_RO(in2_input, in, 2, 0); static SENSOR_DEVICE_ATTR_2_RW(in2_min, in, 2, 1); static SENSOR_DEVICE_ATTR_2_RW(in2_max, in, 2, 2); -static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, alarm, 0x1e, 0); +static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, in_alarm, 2, 0); static SENSOR_DEVICE_ATTR_2_RW(in2_beep, beep, 0x5a, 0); static SENSOR_DEVICE_ATTR_2_RO(in3_input, in, 3, 0); static SENSOR_DEVICE_ATTR_2_RW(in3_min, in, 3, 1); static SENSOR_DEVICE_ATTR_2_RW(in3_max, in, 3, 2); -static SENSOR_DEVICE_ATTR_2_RO(in3_alarm, alarm, 0x1e, 1); +static SENSOR_DEVICE_ATTR_2_RO(in3_alarm, in_alarm, 3, 1); static SENSOR_DEVICE_ATTR_2_RW(in3_beep, beep, 0x5a, 1); static SENSOR_DEVICE_ATTR_2_RO(in4_input, in, 4, 0); static SENSOR_DEVICE_ATTR_2_RW(in4_min, in, 4, 1); static SENSOR_DEVICE_ATTR_2_RW(in4_max, in, 4, 2); -static SENSOR_DEVICE_ATTR_2_RO(in4_alarm, alarm, 0x1e, 2); +static SENSOR_DEVICE_ATTR_2_RO(in4_alarm, in_alarm, 4, 2); static SENSOR_DEVICE_ATTR_2_RW(in4_beep, beep, 0x5a, 2); static struct attribute *nct7802_in_attrs[] = { @@ -1011,6 +1073,7 @@ return PTR_ERR(data->regmap); mutex_init(&data->access_lock); + mutex_init(&data->in_alarm_lock); ret = nct7802_init_chip(data); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/hwmon/nct7904.c +++ linux-oracle-5.4.0/drivers/hwmon/nct7904.c @@ -197,7 +197,7 @@ if (ret < 0) return ret; cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); - if (cnt == 0x1fff) + if (cnt == 0 || cnt == 0x1fff) rpm = 0; else rpm = 1350000 / cnt; @@ -209,7 +209,7 @@ if (ret < 0) return ret; cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f); - if (cnt == 0x1fff) + if (cnt == 0 || cnt == 0x1fff) rpm = 0; else rpm = 1350000 / cnt; @@ -356,6 +356,7 @@ struct nct7904_data *data = dev_get_drvdata(dev); int ret, temp; unsigned int reg1, reg2, reg3; + s8 temps; switch (attr) { case hwmon_temp_input: @@ -461,7 +462,8 @@ if (ret < 0) return ret; - *val = ret * 1000; + temps = ret; + *val = temps * 1000; return 0; } --- linux-oracle-5.4.0.orig/drivers/hwmon/ntc_thermistor.c +++ linux-oracle-5.4.0/drivers/hwmon/ntc_thermistor.c @@ -58,6 +58,7 @@ [NTC_NCP21WB473] = { "ncp21wb473", TYPE_NCPXXWB473 }, [NTC_LAST] = { }, }; +MODULE_DEVICE_TABLE(platform, ntc_thermistor_id); /* * A compensation table should be sorted by the values of .ohm @@ -176,40 +177,40 @@ }; static const struct ntc_compensation ncpXXxh103[] = { - { .temp_c = -40, .ohm = 247565 }, - { .temp_c = -35, .ohm = 181742 }, - { .temp_c = -30, .ohm = 135128 }, - { .temp_c = -25, .ohm = 101678 }, - { .temp_c = -20, .ohm = 77373 }, - { .temp_c = -15, .ohm = 59504 }, - { .temp_c = -10, .ohm = 46222 }, - { .temp_c = -5, .ohm = 36244 }, - { .temp_c = 0, .ohm = 28674 }, - { .temp_c = 5, .ohm = 22878 }, - { .temp_c = 10, .ohm = 18399 }, - { .temp_c = 15, .ohm = 14910 }, - { .temp_c = 20, .ohm = 12169 }, + { .temp_c = -40, .ohm = 195652 }, + { .temp_c = -35, .ohm = 148171 }, + { .temp_c = -30, .ohm = 113347 }, + { .temp_c = -25, .ohm = 87559 }, + { .temp_c = -20, .ohm = 68237 }, + { .temp_c = -15, .ohm = 53650 }, + { .temp_c = -10, .ohm = 42506 }, + { .temp_c = -5, .ohm = 33892 }, + { .temp_c = 0, .ohm = 27219 }, + { .temp_c = 5, .ohm = 22021 }, + { .temp_c = 10, .ohm = 17926 }, + { .temp_c = 15, .ohm = 14674 }, + { .temp_c = 20, .ohm = 12081 }, { .temp_c = 25, .ohm = 10000 }, - { .temp_c = 30, .ohm = 8271 }, - { .temp_c = 35, .ohm = 6883 }, - { .temp_c = 40, .ohm = 5762 }, - { .temp_c = 45, .ohm = 4851 }, - { .temp_c = 50, .ohm = 4105 }, - { .temp_c = 55, .ohm = 3492 }, - { .temp_c = 60, .ohm = 2985 }, - { .temp_c = 65, .ohm = 2563 }, - { .temp_c = 70, .ohm = 2211 }, - { .temp_c = 75, .ohm = 1915 }, - { .temp_c = 80, .ohm = 1666 }, - { .temp_c = 85, .ohm = 1454 }, - { .temp_c = 90, .ohm = 1275 }, - { .temp_c = 95, .ohm = 1121 }, - { .temp_c = 100, .ohm = 990 }, - { .temp_c = 105, .ohm = 876 }, - { .temp_c = 110, .ohm = 779 }, - { .temp_c = 115, .ohm = 694 }, - { .temp_c = 120, .ohm = 620 }, - { .temp_c = 125, .ohm = 556 }, + { .temp_c = 30, .ohm = 8315 }, + { .temp_c = 35, .ohm = 6948 }, + { .temp_c = 40, .ohm = 5834 }, + { .temp_c = 45, .ohm = 4917 }, + { .temp_c = 50, .ohm = 4161 }, + { .temp_c = 55, .ohm = 3535 }, + { .temp_c = 60, .ohm = 3014 }, + { .temp_c = 65, .ohm = 2586 }, + { .temp_c = 70, .ohm = 2228 }, + { .temp_c = 75, .ohm = 1925 }, + { .temp_c = 80, .ohm = 1669 }, + { .temp_c = 85, .ohm = 1452 }, + { .temp_c = 90, .ohm = 1268 }, + { .temp_c = 95, .ohm = 1110 }, + { .temp_c = 100, .ohm = 974 }, + { .temp_c = 105, .ohm = 858 }, + { .temp_c = 110, .ohm = 758 }, + { .temp_c = 115, .ohm = 672 }, + { .temp_c = 120, .ohm = 596 }, + { .temp_c = 125, .ohm = 531 }, }; /* --- linux-oracle-5.4.0.orig/drivers/hwmon/occ/common.c +++ linux-oracle-5.4.0/drivers/hwmon/occ/common.c @@ -209,9 +209,9 @@ return rc; /* limit the maximum rate of polling the OCC */ - if (time_after(jiffies, occ->last_update + OCC_UPDATE_FREQUENCY)) { + if (time_after(jiffies, occ->next_update)) { rc = occ_poll(occ); - occ->last_update = jiffies; + occ->next_update = jiffies + OCC_UPDATE_FREQUENCY; } else { rc = occ->last_error; } @@ -1089,6 +1089,7 @@ return rc; } + occ->next_update = jiffies + OCC_UPDATE_FREQUENCY; occ_parse_poll_response(occ); rc = occ_setup_sensor_attrs(occ); --- linux-oracle-5.4.0.orig/drivers/hwmon/occ/common.h +++ linux-oracle-5.4.0/drivers/hwmon/occ/common.h @@ -99,7 +99,7 @@ u8 poll_cmd_data; /* to perform OCC poll command */ int (*send_cmd)(struct occ *occ, u8 *cmd); - unsigned long last_update; + unsigned long next_update; struct mutex lock; /* lock OCC access */ struct device *hwmon; --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/adm1275.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/adm1275.c @@ -454,6 +454,7 @@ static int adm1275_probe(struct i2c_client *client, const struct i2c_device_id *id) { + s32 (*config_read_fn)(const struct i2c_client *client, u8 reg); u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1]; int config, device_config; int ret; @@ -499,11 +500,16 @@ "Device mismatch: Configured %s, detected %s\n", id->name, mid->name); - config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG); + if (mid->driver_data == adm1272 || mid->driver_data == adm1278 || + mid->driver_data == adm1293 || mid->driver_data == adm1294) + config_read_fn = i2c_smbus_read_word_data; + else + config_read_fn = i2c_smbus_read_byte_data; + config = config_read_fn(client, ADM1275_PMON_CONFIG); if (config < 0) return config; - device_config = i2c_smbus_read_byte_data(client, ADM1275_DEVICE_CONFIG); + device_config = config_read_fn(client, ADM1275_DEVICE_CONFIG); if (device_config < 0) return device_config; --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/ibm-cffps.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/ibm-cffps.c @@ -39,9 +39,13 @@ #define CFFPS_MFR_VAUX_FAULT BIT(6) #define CFFPS_MFR_CURRENT_SHARE_WARNING BIT(7) +/* + * LED off state actually relinquishes LED control to PSU firmware, so it can + * turn on the LED for faults. + */ +#define CFFPS_LED_OFF 0 #define CFFPS_LED_BLINK BIT(0) #define CFFPS_LED_ON BIT(1) -#define CFFPS_LED_OFF BIT(2) #define CFFPS_BLINK_RATE_MS 250 enum { @@ -292,28 +296,38 @@ return rc; } -static void ibm_cffps_led_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brightness) +static int ibm_cffps_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) { int rc; + u8 next_led_state; struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led); if (brightness == LED_OFF) { - psu->led_state = CFFPS_LED_OFF; + next_led_state = CFFPS_LED_OFF; } else { brightness = LED_FULL; + if (psu->led_state != CFFPS_LED_BLINK) - psu->led_state = CFFPS_LED_ON; + next_led_state = CFFPS_LED_ON; + else + next_led_state = CFFPS_LED_BLINK; } + dev_dbg(&psu->client->dev, "LED brightness set: %d. Command: %d.\n", + brightness, next_led_state); + pmbus_set_page(psu->client, 0); rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD, - psu->led_state); + next_led_state); if (rc < 0) - return; + return rc; + psu->led_state = next_led_state; led_cdev->brightness = brightness; + + return 0; } static int ibm_cffps_led_blink_set(struct led_classdev *led_cdev, @@ -323,10 +337,7 @@ int rc; struct ibm_cffps *psu = container_of(led_cdev, struct ibm_cffps, led); - psu->led_state = CFFPS_LED_BLINK; - - if (led_cdev->brightness == LED_OFF) - return 0; + dev_dbg(&psu->client->dev, "LED blink set.\n"); pmbus_set_page(psu->client, 0); @@ -335,6 +346,8 @@ if (rc < 0) return rc; + psu->led_state = CFFPS_LED_BLINK; + led_cdev->brightness = LED_FULL; *delay_on = CFFPS_BLINK_RATE_MS; *delay_off = CFFPS_BLINK_RATE_MS; @@ -351,7 +364,7 @@ client->addr); psu->led.name = psu->led_name; psu->led.max_brightness = LED_FULL; - psu->led.brightness_set = ibm_cffps_led_brightness_set; + psu->led.brightness_set_blocking = ibm_cffps_led_brightness_set; psu->led.blink_set = ibm_cffps_led_blink_set; rc = devm_led_classdev_register(dev, &psu->led); --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/lm25066.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/lm25066.c @@ -51,26 +51,31 @@ #define PSC_CURRENT_IN_L (PSC_NUM_CLASSES) #define PSC_POWER_L (PSC_NUM_CLASSES + 1) -static struct __coeff lm25066_coeff[6][PSC_NUM_CLASSES + 2] = { +static struct __coeff lm25066_coeff[][PSC_NUM_CLASSES + 2] = { [lm25056] = { [PSC_VOLTAGE_IN] = { .m = 16296, + .b = 1343, .R = -2, }, [PSC_CURRENT_IN] = { .m = 13797, + .b = -1833, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 6726, + .b = -537, .R = -2, }, [PSC_POWER] = { .m = 5501, + .b = -2908, .R = -3, }, [PSC_POWER_L] = { .m = 26882, + .b = -5646, .R = -4, }, [PSC_TEMPERATURE] = { @@ -82,26 +87,32 @@ [lm25066] = { [PSC_VOLTAGE_IN] = { .m = 22070, + .b = -1800, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 22070, + .b = -1800, .R = -2, }, [PSC_CURRENT_IN] = { .m = 13661, + .b = -5200, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 6852, + .b = -3100, .R = -2, }, [PSC_POWER] = { .m = 736, + .b = -3300, .R = -2, }, [PSC_POWER_L] = { .m = 369, + .b = -1900, .R = -2, }, [PSC_TEMPERATURE] = { @@ -111,26 +122,32 @@ [lm5064] = { [PSC_VOLTAGE_IN] = { .m = 4611, + .b = -642, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 4621, + .b = 423, .R = -2, }, [PSC_CURRENT_IN] = { .m = 10742, + .b = 1552, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 5456, + .b = 2118, .R = -2, }, [PSC_POWER] = { .m = 1204, + .b = 8524, .R = -3, }, [PSC_POWER_L] = { .m = 612, + .b = 11202, .R = -3, }, [PSC_TEMPERATURE] = { @@ -140,26 +157,32 @@ [lm5066] = { [PSC_VOLTAGE_IN] = { .m = 4587, + .b = -1200, .R = -2, }, [PSC_VOLTAGE_OUT] = { .m = 4587, + .b = -2400, .R = -2, }, [PSC_CURRENT_IN] = { .m = 10753, + .b = -1200, .R = -2, }, [PSC_CURRENT_IN_L] = { .m = 5405, + .b = -600, .R = -2, }, [PSC_POWER] = { .m = 1204, + .b = -6000, .R = -3, }, [PSC_POWER_L] = { .m = 605, + .b = -8000, .R = -3, }, [PSC_TEMPERATURE] = { --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/ltc2978.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/ltc2978.c @@ -82,8 +82,8 @@ #define LTC_POLL_TIMEOUT 100 /* in milli-seconds */ -#define LTC_NOT_BUSY BIT(5) -#define LTC_NOT_PENDING BIT(4) +#define LTC_NOT_BUSY BIT(6) +#define LTC_NOT_PENDING BIT(5) /* * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/max34440.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/max34440.c @@ -387,7 +387,6 @@ .func[18] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, - .read_byte_data = max34440_read_byte_data, .read_word_data = max34440_read_word_data, .write_word_data = max34440_write_word_data, }, @@ -418,7 +417,6 @@ .func[15] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[16] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[17] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, - .read_byte_data = max34440_read_byte_data, .read_word_data = max34440_read_word_data, .write_word_data = max34440_write_word_data, }, @@ -454,7 +452,6 @@ .func[19] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[20] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, .func[21] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, - .read_byte_data = max34440_read_byte_data, .read_word_data = max34440_read_word_data, .write_word_data = max34440_write_word_data, }, --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/pmbus.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/pmbus.c @@ -101,6 +101,8 @@ if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) { int page; + info->pages = PMBUS_PAGES; + for (page = 1; page < PMBUS_PAGES; page++) { if (pmbus_set_page(client, page) < 0) break; --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/pmbus.h +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/pmbus.h @@ -292,6 +292,7 @@ /* * STATUS_VOUT, STATUS_INPUT */ +#define PB_VOLTAGE_VIN_OFF BIT(3) #define PB_VOLTAGE_UV_FAULT BIT(4) #define PB_VOLTAGE_UV_WARNING BIT(5) #define PB_VOLTAGE_OV_WARNING BIT(6) --- linux-oracle-5.4.0.orig/drivers/hwmon/pmbus/pmbus_core.c +++ linux-oracle-5.4.0/drivers/hwmon/pmbus/pmbus_core.c @@ -1324,7 +1324,7 @@ .reg = PMBUS_VIN_UV_FAULT_LIMIT, .attr = "lcrit", .alarm = "lcrit_alarm", - .sbit = PB_VOLTAGE_UV_FAULT, + .sbit = PB_VOLTAGE_UV_FAULT | PB_VOLTAGE_VIN_OFF, }, { .reg = PMBUS_VIN_OV_WARN_LIMIT, .attr = "max", @@ -2174,10 +2174,14 @@ { struct device *dev = rdev_get_dev(rdev); struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); u8 page = rdev_get_id(rdev); int ret; + mutex_lock(&data->update_lock); ret = pmbus_read_byte_data(client, page, PMBUS_OPERATION); + mutex_unlock(&data->update_lock); + if (ret < 0) return ret; @@ -2188,11 +2192,17 @@ { struct device *dev = rdev_get_dev(rdev); struct i2c_client *client = to_i2c_client(dev->parent); + struct pmbus_data *data = i2c_get_clientdata(client); u8 page = rdev_get_id(rdev); + int ret; - return pmbus_update_byte_data(client, page, PMBUS_OPERATION, - PB_OPERATION_CONTROL_ON, - enable ? PB_OPERATION_CONTROL_ON : 0); + mutex_lock(&data->update_lock); + ret = pmbus_update_byte_data(client, page, PMBUS_OPERATION, + PB_OPERATION_CONTROL_ON, + enable ? PB_OPERATION_CONTROL_ON : 0); + mutex_unlock(&data->update_lock); + + return ret; } static int pmbus_regulator_enable(struct regulator_dev *rdev) --- linux-oracle-5.4.0.orig/drivers/hwmon/pwm-fan.c +++ linux-oracle-5.4.0/drivers/hwmon/pwm-fan.c @@ -54,16 +54,18 @@ static void sample_timer(struct timer_list *t) { struct pwm_fan_ctx *ctx = from_timer(ctx, t, rpm_timer); + unsigned int delta = ktime_ms_delta(ktime_get(), ctx->sample_start); int pulses; - u64 tmp; - pulses = atomic_read(&ctx->pulses); - atomic_sub(pulses, &ctx->pulses); - tmp = (u64)pulses * ktime_ms_delta(ktime_get(), ctx->sample_start) * 60; - do_div(tmp, ctx->pulses_per_revolution * 1000); - ctx->rpm = tmp; + if (delta) { + pulses = atomic_read(&ctx->pulses); + atomic_sub(pulses, &ctx->pulses); + ctx->rpm = (unsigned int)(pulses * 1000 * 60) / + (ctx->pulses_per_revolution * delta); + + ctx->sample_start = ktime_get(); + } - ctx->sample_start = ktime_get(); mod_timer(&ctx->rpm_timer, jiffies + HZ); } @@ -328,8 +330,18 @@ ctx->pwm_value = MAX_PWM; - /* Set duty cycle to maximum allowed and enable PWM output */ pwm_init_state(ctx->pwm, &state); + /* + * __set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned + * long. Check this here to prevent the fan running at a too low + * frequency. + */ + if (state.period > ULONG_MAX / MAX_PWM + 1) { + dev_err(dev, "Configured period too big\n"); + return -EINVAL; + } + + /* Set duty cycle to maximum allowed and enable PWM output */ state.duty_cycle = ctx->pwm->args.period - 1; state.enabled = true; --- linux-oracle-5.4.0.orig/drivers/hwmon/sch56xx-common.c +++ linux-oracle-5.4.0/drivers/hwmon/sch56xx-common.c @@ -424,7 +424,7 @@ if (nowayout) set_bit(WDOG_NO_WAY_OUT, &data->wddev.status); if (output_enable & SCH56XX_WDOG_OUTPUT_ENABLE) - set_bit(WDOG_ACTIVE, &data->wddev.status); + set_bit(WDOG_HW_RUNNING, &data->wddev.status); /* Since the watchdog uses a downcounter there is no register to read the BIOS set timeout from (if any was set at all) -> --- linux-oracle-5.4.0.orig/drivers/hwmon/scmi-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/scmi-hwmon.c @@ -147,7 +147,7 @@ [ENERGY] = hwmon_energy, }; -static u32 hwmon_attributes[] = { +static u32 hwmon_attributes[hwmon_max] = { [hwmon_chip] = HWMON_C_REGISTER_TZ, [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, --- linux-oracle-5.4.0.orig/drivers/hwmon/scpi-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/scpi-hwmon.c @@ -99,6 +99,15 @@ scpi_scale_reading(&value, sensor); + /* + * Temperature sensor values are treated as signed values based on + * observation even though that is not explicitly specified, and + * because an unsigned u64 temperature does not really make practical + * sense especially when the temperature is below zero degrees Celsius. + */ + if (sensor->info.class == TEMPERATURE) + return sprintf(buf, "%lld\n", (s64)value); + return sprintf(buf, "%llu\n", value); } --- linux-oracle-5.4.0.orig/drivers/hwmon/tmp401.c +++ linux-oracle-5.4.0/drivers/hwmon/tmp401.c @@ -731,10 +731,21 @@ return 0; } +static const struct of_device_id __maybe_unused tmp4xx_of_match[] = { + { .compatible = "ti,tmp401", }, + { .compatible = "ti,tmp411", }, + { .compatible = "ti,tmp431", }, + { .compatible = "ti,tmp432", }, + { .compatible = "ti,tmp435", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tmp4xx_of_match); + static struct i2c_driver tmp401_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "tmp401", + .of_match_table = of_match_ptr(tmp4xx_of_match), }, .probe = tmp401_probe, .id_table = tmp401_id, --- linux-oracle-5.4.0.orig/drivers/hwmon/tmp421.c +++ linux-oracle-5.4.0/drivers/hwmon/tmp421.c @@ -100,23 +100,17 @@ s16 temp[4]; }; -static int temp_from_s16(s16 reg) +static int temp_from_raw(u16 reg, bool extended) { /* Mask out status bits */ int temp = reg & ~0xf; - return (temp * 1000 + 128) / 256; -} + if (extended) + temp = temp - 64 * 256; + else + temp = (s16)temp; -static int temp_from_u16(u16 reg) -{ - /* Mask out status bits */ - int temp = reg & ~0xf; - - /* Add offset for extended temperature range. */ - temp -= 64 * 256; - - return (temp * 1000 + 128) / 256; + return DIV_ROUND_CLOSEST(temp * 1000, 256); } static struct tmp421_data *tmp421_update_device(struct device *dev) @@ -153,17 +147,15 @@ switch (attr) { case hwmon_temp_input: - if (tmp421->config & TMP421_CONFIG_RANGE) - *val = temp_from_u16(tmp421->temp[channel]); - else - *val = temp_from_s16(tmp421->temp[channel]); + *val = temp_from_raw(tmp421->temp[channel], + tmp421->config & TMP421_CONFIG_RANGE); return 0; case hwmon_temp_fault: /* - * The OPEN bit signals a fault. This is bit 0 of the temperature - * register (low byte). + * Any of OPEN or /PVLD bits indicate a hardware mulfunction + * and the conversion result may be incorrect */ - *val = tmp421->temp[channel] & 0x01; + *val = !!(tmp421->temp[channel] & 0x03); return 0; default: return -EOPNOTSUPP; @@ -176,9 +168,6 @@ { switch (attr) { case hwmon_temp_fault: - if (channel == 0) - return 0; - return 0444; case hwmon_temp_input: return 0444; default: --- linux-oracle-5.4.0.orig/drivers/hwmon/w83627ehf.c +++ linux-oracle-5.4.0/drivers/hwmon/w83627ehf.c @@ -1506,7 +1506,7 @@ if (err < 0) return err; - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 127); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 127000), 1000); mutex_lock(&data->update_lock); data->target_temp[nr] = val; @@ -1532,7 +1532,7 @@ return err; /* Limit the temp to 0C - 15C */ - val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15); + val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 15000), 1000); mutex_lock(&data->update_lock); if (sio_data->kind == nct6775 || sio_data->kind == nct6776) { --- linux-oracle-5.4.0.orig/drivers/hwmon/w83791d.c +++ linux-oracle-5.4.0/drivers/hwmon/w83791d.c @@ -273,9 +273,6 @@ char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - /* array of 2 pointers to subclients */ - struct i2c_client *lm75[2]; - /* volts */ u8 in[NUMBER_OF_VIN]; /* Register value */ u8 in_max[NUMBER_OF_VIN]; /* Register value */ @@ -1258,7 +1255,6 @@ static int w83791d_detect_subclients(struct i2c_client *client) { struct i2c_adapter *adapter = client->adapter; - struct w83791d_data *data = i2c_get_clientdata(client); int address = client->addr; int i, id; u8 val; @@ -1281,22 +1277,19 @@ } val = w83791d_read(client, W83791D_REG_I2C_SUBADDR); - if (!(val & 0x08)) - data->lm75[0] = devm_i2c_new_dummy_device(&client->dev, adapter, - 0x48 + (val & 0x7)); - if (!(val & 0x80)) { - if (!IS_ERR(data->lm75[0]) && - ((val & 0x7) == ((val >> 4) & 0x7))) { - dev_err(&client->dev, - "duplicate addresses 0x%x, " - "use force_subclient\n", - data->lm75[0]->addr); - return -ENODEV; - } - data->lm75[1] = devm_i2c_new_dummy_device(&client->dev, adapter, - 0x48 + ((val >> 4) & 0x7)); + + if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) { + dev_err(&client->dev, + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7)); + return -ENODEV; } + if (!(val & 0x08)) + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + (val & 0x7)); + + if (!(val & 0x80)) + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + ((val >> 4) & 0x7)); + return 0; } --- linux-oracle-5.4.0.orig/drivers/hwmon/w83792d.c +++ linux-oracle-5.4.0/drivers/hwmon/w83792d.c @@ -264,9 +264,6 @@ char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - /* array of 2 pointers to subclients */ - struct i2c_client *lm75[2]; - u8 in[9]; /* Register value */ u8 in_max[9]; /* Register value */ u8 in_min[9]; /* Register value */ @@ -928,7 +925,6 @@ int address = new_client->addr; u8 val; struct i2c_adapter *adapter = new_client->adapter; - struct w83792d_data *data = i2c_get_clientdata(new_client); id = i2c_adapter_id(adapter); if (force_subclients[0] == id && force_subclients[1] == address) { @@ -947,21 +943,19 @@ } val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR); - if (!(val & 0x08)) - data->lm75[0] = devm_i2c_new_dummy_device(&new_client->dev, adapter, - 0x48 + (val & 0x7)); - if (!(val & 0x80)) { - if (!IS_ERR(data->lm75[0]) && - ((val & 0x7) == ((val >> 4) & 0x7))) { - dev_err(&new_client->dev, - "duplicate addresses 0x%x, use force_subclient\n", - data->lm75[0]->addr); - return -ENODEV; - } - data->lm75[1] = devm_i2c_new_dummy_device(&new_client->dev, adapter, - 0x48 + ((val >> 4) & 0x7)); + + if (!(val & 0x88) && (val & 0x7) == ((val >> 4) & 0x7)) { + dev_err(&new_client->dev, + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (val & 0x7)); + return -ENODEV; } + if (!(val & 0x08)) + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + (val & 0x7)); + + if (!(val & 0x80)) + devm_i2c_new_dummy_device(&new_client->dev, adapter, 0x48 + ((val >> 4) & 0x7)); + return 0; } --- linux-oracle-5.4.0.orig/drivers/hwmon/w83793.c +++ linux-oracle-5.4.0/drivers/hwmon/w83793.c @@ -202,7 +202,6 @@ } struct w83793_data { - struct i2c_client *lm75[2]; struct device *hwmon_dev; struct mutex update_lock; char valid; /* !=0 if following fields are valid */ @@ -1566,7 +1565,6 @@ int address = client->addr; u8 tmp; struct i2c_adapter *adapter = client->adapter; - struct w83793_data *data = i2c_get_clientdata(client); id = i2c_adapter_id(adapter); if (force_subclients[0] == id && force_subclients[1] == address) { @@ -1586,21 +1584,19 @@ } tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR); - if (!(tmp & 0x08)) - data->lm75[0] = devm_i2c_new_dummy_device(&client->dev, adapter, - 0x48 + (tmp & 0x7)); - if (!(tmp & 0x80)) { - if (!IS_ERR(data->lm75[0]) - && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) { - dev_err(&client->dev, - "duplicate addresses 0x%x, " - "use force_subclients\n", data->lm75[0]->addr); - return -ENODEV; - } - data->lm75[1] = devm_i2c_new_dummy_device(&client->dev, adapter, - 0x48 + ((tmp >> 4) & 0x7)); + + if (!(tmp & 0x88) && (tmp & 0x7) == ((tmp >> 4) & 0x7)) { + dev_err(&client->dev, + "duplicate addresses 0x%x, use force_subclient\n", 0x48 + (tmp & 0x7)); + return -ENODEV; } + if (!(tmp & 0x08)) + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + (tmp & 0x7)); + + if (!(tmp & 0x80)) + devm_i2c_new_dummy_device(&client->dev, adapter, 0x48 + ((tmp >> 4) & 0x7)); + return 0; } --- linux-oracle-5.4.0.orig/drivers/hwmon/xgene-hwmon.c +++ linux-oracle-5.4.0/drivers/hwmon/xgene-hwmon.c @@ -719,7 +719,7 @@ goto out; } - if (!ctx->pcc_comm_addr) { + if (IS_ERR_OR_NULL(ctx->pcc_comm_addr)) { dev_err(&pdev->dev, "Failed to ioremap PCC comm region\n"); rc = -ENOMEM; @@ -768,6 +768,7 @@ { struct xgene_hwmon_dev *ctx = platform_get_drvdata(pdev); + cancel_work_sync(&ctx->workq); hwmon_device_unregister(ctx->hwmon_dev); kfifo_free(&ctx->async_msg_fifo); if (acpi_disabled) --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-cpu-debug.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-cpu-debug.c @@ -379,9 +379,10 @@ int cpu; struct debug_drvdata *drvdata; - mutex_lock(&debug_lock); + /* Bail out if we can't acquire the mutex or the functionality is off */ + if (!mutex_trylock(&debug_lock)) + return NOTIFY_DONE; - /* Bail out if the functionality is disabled */ if (!debug_enable) goto skip_dump; @@ -400,7 +401,7 @@ skip_dump: mutex_unlock(&debug_lock); - return 0; + return NOTIFY_DONE; } static struct notifier_block debug_notifier = { --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-etb10.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-etb10.c @@ -176,6 +176,7 @@ unsigned long flags; struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct perf_output_handle *handle = data; + struct cs_buffers *buf = etm_perf_sink_config(handle); spin_lock_irqsave(&drvdata->spinlock, flags); @@ -186,7 +187,7 @@ } /* Get a handle on the pid of the process to monitor */ - pid = task_pid_nr(handle->event->owner); + pid = buf->pid; if (drvdata->pid != -1 && drvdata->pid != pid) { ret = -EBUSY; @@ -383,6 +384,7 @@ if (!buf) return NULL; + buf->pid = task_pid_nr(event->owner); buf->snapshot = overwrite; buf->nr_pages = nr_pages; buf->data_pages = pages; --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-etm-perf.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -126,10 +126,10 @@ cpumask_t *mask = &event_data->mask; struct coresight_device *sink; - if (WARN_ON(cpumask_empty(mask))) + if (!event_data->snk_config) return; - if (!event_data->snk_config) + if (WARN_ON(cpumask_empty(mask))) return; cpu = cpumask_first(mask); @@ -310,6 +310,16 @@ if (!event_data) goto fail; + /* + * Check if this ETM is allowed to trace, as decided + * at etm_setup_aux(). This could be due to an unreachable + * sink from this ETM. We can't do much in this case if + * the sink was specified or hinted to the driver. For + * now, simply don't record anything on this ETM. + */ + if (!cpumask_test_cpu(cpu, &event_data->mask)) + goto fail_end_stop; + path = etm_event_cpu_path(event_data, cpu); /* We need a sink, no need to continue without one */ sink = coresight_get_sink(path); --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c @@ -364,8 +364,12 @@ mode = ETM_MODE_QELEM(config->mode); /* start by clearing QE bits */ config->cfg &= ~(BIT(13) | BIT(14)); - /* if supported, Q elements with instruction counts are enabled */ - if ((mode & BIT(0)) && (drvdata->q_support & BIT(0))) + /* + * if supported, Q elements with instruction counts are enabled. + * Always set the low bit for any requested mode. Valid combos are + * 0b00, 0b01 and 0b11. + */ + if (mode && drvdata->q_support) config->cfg |= BIT(13); /* * if supported, Q elements with and without instruction @@ -652,10 +656,13 @@ if (kstrtoul(buf, 16, &val)) return -EINVAL; + + /* mask off max threshold before checking min value */ + val &= ETM_CYC_THRESHOLD_MASK; if (val < drvdata->ccitmin) return -EINVAL; - config->ccctlr = val & ETM_CYC_THRESHOLD_MASK; + config->ccctlr = val; return size; } static DEVICE_ATTR_RW(cyc_threshold); @@ -686,14 +693,16 @@ return -EINVAL; if (!drvdata->nr_addr_cmp) return -EINVAL; + /* - * Bit[7:0] selects which address range comparator is used for - * branch broadcast control. + * Bit[8] controls include(1) / exclude(0), bits[0-7] select + * individual range comparators. If include then at least 1 + * range must be selected. */ - if (BMVAL(val, 0, 7) > drvdata->nr_addr_cmp) + if ((val & BIT(8)) && (BMVAL(val, 0, 7) == 0)) return -EINVAL; - config->bb_ctrl = val; + config->bb_ctrl = val & GENMASK(8, 0); return size; } static DEVICE_ATTR_RW(bb_ctrl); @@ -1324,8 +1333,8 @@ spin_lock(&drvdata->spinlock); idx = config->seq_idx; - /* RST, bits[7:0] */ - config->seq_ctrl[idx] = val & 0xFF; + /* Seq control has two masks B[15:8] F[7:0] */ + config->seq_ctrl[idx] = val & 0xFFFF; spin_unlock(&drvdata->spinlock); return size; } @@ -1580,7 +1589,7 @@ if (idx % 2 != 0) /* PAIRINV, bit[21] */ val &= ~BIT(21); - config->res_ctrl[idx] = val; + config->res_ctrl[idx] = val & GENMASK(21, 0); spin_unlock(&drvdata->spinlock); return size; } --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-etm4x.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-etm4x.c @@ -156,7 +156,7 @@ writel_relaxed(config->ss_pe_cmp[i], drvdata->base + TRCSSPCICRn(i)); } - for (i = 0; i < drvdata->nr_addr_cmp; i++) { + for (i = 0; i < drvdata->nr_addr_cmp * 2; i++) { writeq_relaxed(config->addr_val[i], drvdata->base + TRCACVRn(i)); writeq_relaxed(config->addr_acc[i], @@ -1184,6 +1184,7 @@ return 0; err_arch_supported: + etmdrvdata[drvdata->cpu] = NULL; if (--etm4_count == 0) { cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING); if (hp_online) --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-etm4x.h +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-etm4x.h @@ -361,7 +361,7 @@ u8 ctxid_size; u8 vmid_size; u8 ccsize; - u8 ccitmin; + u16 ccitmin; u8 s_ex_level; u8 ns_ex_level; u8 q_support; --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-funnel.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-funnel.c @@ -38,12 +38,14 @@ * @atclk: optional clock for the core parts of the funnel. * @csdev: component vitals needed by the framework. * @priority: port selection order. + * @spinlock: serialize enable/disable operations. */ struct funnel_drvdata { void __iomem *base; struct clk *atclk; struct coresight_device *csdev; unsigned long priority; + spinlock_t spinlock; }; static int dynamic_funnel_enable_hw(struct funnel_drvdata *drvdata, int port) @@ -76,11 +78,21 @@ { int rc = 0; struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + bool first_enable = false; - if (drvdata->base) - rc = dynamic_funnel_enable_hw(drvdata, inport); - + spin_lock_irqsave(&drvdata->spinlock, flags); + if (atomic_read(&csdev->refcnt[inport]) == 0) { + if (drvdata->base) + rc = dynamic_funnel_enable_hw(drvdata, inport); + if (!rc) + first_enable = true; + } if (!rc) + atomic_inc(&csdev->refcnt[inport]); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + if (first_enable) dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport); return rc; } @@ -107,11 +119,19 @@ int outport) { struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + bool last_disable = false; - if (drvdata->base) - dynamic_funnel_disable_hw(drvdata, inport); + spin_lock_irqsave(&drvdata->spinlock, flags); + if (atomic_dec_return(&csdev->refcnt[inport]) == 0) { + if (drvdata->base) + dynamic_funnel_disable_hw(drvdata, inport); + last_disable = true; + } + spin_unlock_irqrestore(&drvdata->spinlock, flags); - dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); + if (last_disable) + dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport); } static const struct coresight_ops_link funnel_link_ops = { --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-priv.h +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-priv.h @@ -86,6 +86,7 @@ * struct cs_buffer - keep track of a recording session' specifics * @cur: index of the current buffer * @nr_pages: max number of pages granted to us + * @pid: PID this cs_buffer belongs to * @offset: offset within the current buffer * @data_size: how much we collected in this run * @snapshot: is this run in snapshot mode @@ -94,6 +95,7 @@ struct cs_buffers { unsigned int cur; unsigned int nr_pages; + pid_t pid; unsigned long offset; local_t data_size; bool snapshot; --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-replicator.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-replicator.c @@ -31,11 +31,13 @@ * whether this one is programmable or not. * @atclk: optional clock for the core parts of the replicator. * @csdev: component vitals needed by the framework + * @spinlock: serialize enable/disable operations. */ struct replicator_drvdata { void __iomem *base; struct clk *atclk; struct coresight_device *csdev; + spinlock_t spinlock; }; static void dynamic_replicator_reset(struct replicator_drvdata *drvdata) @@ -97,10 +99,22 @@ { int rc = 0; struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + bool first_enable = false; - if (drvdata->base) - rc = dynamic_replicator_enable(drvdata, inport, outport); + spin_lock_irqsave(&drvdata->spinlock, flags); + if (atomic_read(&csdev->refcnt[outport]) == 0) { + if (drvdata->base) + rc = dynamic_replicator_enable(drvdata, inport, + outport); + if (!rc) + first_enable = true; + } if (!rc) + atomic_inc(&csdev->refcnt[outport]); + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + if (first_enable) dev_dbg(&csdev->dev, "REPLICATOR enabled\n"); return rc; } @@ -137,10 +151,19 @@ int outport) { struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + unsigned long flags; + bool last_disable = false; - if (drvdata->base) - dynamic_replicator_disable(drvdata, inport, outport); - dev_dbg(&csdev->dev, "REPLICATOR disabled\n"); + spin_lock_irqsave(&drvdata->spinlock, flags); + if (atomic_dec_return(&csdev->refcnt[outport]) == 0) { + if (drvdata->base) + dynamic_replicator_disable(drvdata, inport, outport); + last_disable = true; + } + spin_unlock_irqrestore(&drvdata->spinlock, flags); + + if (last_disable) + dev_dbg(&csdev->dev, "REPLICATOR disabled\n"); } static const struct coresight_ops_link replicator_link_ops = { --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -227,6 +227,7 @@ unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct perf_output_handle *handle = data; + struct cs_buffers *buf = etm_perf_sink_config(handle); spin_lock_irqsave(&drvdata->spinlock, flags); do { @@ -243,7 +244,7 @@ } /* Get a handle on the pid of the process to monitor */ - pid = task_pid_nr(handle->event->owner); + pid = buf->pid; if (drvdata->pid != -1 && drvdata->pid != pid) { ret = -EBUSY; @@ -334,9 +335,10 @@ static int tmc_enable_etf_link(struct coresight_device *csdev, int inport, int outport) { - int ret; + int ret = 0; unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + bool first_enable = false; spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { @@ -344,12 +346,18 @@ return -EBUSY; } - ret = tmc_etf_enable_hw(drvdata); + if (atomic_read(&csdev->refcnt[0]) == 0) { + ret = tmc_etf_enable_hw(drvdata); + if (!ret) { + drvdata->mode = CS_MODE_SYSFS; + first_enable = true; + } + } if (!ret) - drvdata->mode = CS_MODE_SYSFS; + atomic_inc(&csdev->refcnt[0]); spin_unlock_irqrestore(&drvdata->spinlock, flags); - if (!ret) + if (first_enable) dev_dbg(&csdev->dev, "TMC-ETF enabled\n"); return ret; } @@ -359,6 +367,7 @@ { unsigned long flags; struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); + bool last_disable = false; spin_lock_irqsave(&drvdata->spinlock, flags); if (drvdata->reading) { @@ -366,11 +375,15 @@ return; } - tmc_etf_disable_hw(drvdata); - drvdata->mode = CS_MODE_DISABLED; + if (atomic_dec_return(&csdev->refcnt[0]) == 0) { + tmc_etf_disable_hw(drvdata); + drvdata->mode = CS_MODE_DISABLED; + last_disable = true; + } spin_unlock_irqrestore(&drvdata->spinlock, flags); - dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); + if (last_disable) + dev_dbg(&csdev->dev, "TMC-ETF disabled\n"); } static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, @@ -387,6 +400,7 @@ if (!buf) return NULL; + buf->pid = task_pid_nr(event->owner); buf->snapshot = overwrite; buf->nr_pages = nr_pages; buf->data_pages = pages; @@ -412,7 +426,7 @@ return -EINVAL; /* wrap head around to the amount of space we have */ - head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); + head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1); /* find the page to write to */ buf->cur = head / PAGE_SIZE; @@ -514,7 +528,7 @@ buf_ptr = buf->data_pages[cur] + offset; *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); - if (lost && *barrier) { + if (lost && i < CORESIGHT_BARRIER_PKT_SIZE) { *buf_ptr = *barrier; barrier++; } @@ -584,13 +598,6 @@ goto out; } - /* There is no point in reading a TMC in HW FIFO mode */ - mode = readl_relaxed(drvdata->base + TMC_MODE); - if (mode != TMC_MODE_CIRCULAR_BUFFER) { - ret = -EINVAL; - goto out; - } - /* Don't interfere if operated from Perf */ if (drvdata->mode == CS_MODE_PERF) { ret = -EINVAL; @@ -604,8 +611,15 @@ } /* Disable the TMC if need be */ - if (drvdata->mode == CS_MODE_SYSFS) + if (drvdata->mode == CS_MODE_SYSFS) { + /* There is no point in reading a TMC in HW FIFO mode */ + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode != TMC_MODE_CIRCULAR_BUFFER) { + ret = -EINVAL; + goto out; + } __tmc_etb_disable_hw(drvdata); + } drvdata->reading = true; out: @@ -627,15 +641,14 @@ spin_lock_irqsave(&drvdata->spinlock, flags); - /* There is no point in reading a TMC in HW FIFO mode */ - mode = readl_relaxed(drvdata->base + TMC_MODE); - if (mode != TMC_MODE_CIRCULAR_BUFFER) { - spin_unlock_irqrestore(&drvdata->spinlock, flags); - return -EINVAL; - } - /* Re-enable the TMC if need be */ if (drvdata->mode == CS_MODE_SYSFS) { + /* There is no point in reading a TMC in HW FIFO mode */ + mode = readl_relaxed(drvdata->base + TMC_MODE); + if (mode != TMC_MODE_CIRCULAR_BUFFER) { + spin_unlock_irqrestore(&drvdata->spinlock, flags); + return -EINVAL; + } /* * The trace run will continue with the same allocated trace * buffer. As such zero-out the buffer so that we don't end --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -47,7 +47,8 @@ }; /* Convert the perf index to an offset within the ETR buffer */ -#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) +#define PERF_IDX2OFF(idx, buf) \ + ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT)) /* Lower limit for ETR hardware buffer */ #define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M @@ -217,6 +218,8 @@ } else { page = alloc_pages_node(node, GFP_KERNEL | __GFP_ZERO, 0); + if (!page) + goto err; } paddr = dma_map_page(real_dev, page, 0, PAGE_SIZE, dir); if (dma_mapping_error(real_dev, paddr)) @@ -254,6 +257,7 @@ { tmc_free_table_pages(sg_table); tmc_free_data_pages(sg_table); + kfree(sg_table); } /* @@ -334,7 +338,6 @@ rc = tmc_alloc_table_pages(sg_table); if (rc) { tmc_free_sg_table(sg_table); - kfree(sg_table); return ERR_PTR(rc); } @@ -907,7 +910,7 @@ len = tmc_etr_buf_get_data(etr_buf, offset, CORESIGHT_BARRIER_PKT_SIZE, &bufp); - if (WARN_ON(len < CORESIGHT_BARRIER_PKT_SIZE)) + if (WARN_ON(len < 0 || len < CORESIGHT_BARRIER_PKT_SIZE)) return -EINVAL; coresight_insert_barrier_packet(bufp); return offset + CORESIGHT_BARRIER_PKT_SIZE; @@ -1213,7 +1216,7 @@ * than the size requested via sysfs. */ if ((nr_pages << PAGE_SHIFT) > drvdata->size) { - etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT), + etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT), 0, node, NULL); if (!IS_ERR(etr_buf)) goto done; @@ -1533,7 +1536,7 @@ /* Insert barrier packets at the beginning, if there was an overflow */ if (lost) - tmc_etr_buf_insert_barrier_packet(etr_buf, etr_buf->offset); + tmc_etr_buf_insert_barrier_packet(etr_buf, offset); tmc_etr_sync_perf_buffer(etr_perf, offset, size); /* --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight-tmc.h +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight-tmc.h @@ -320,7 +320,7 @@ static inline unsigned long tmc_sg_table_buf_size(struct tmc_sg_table *sg_table) { - return sg_table->data_pages.nr_pages << PAGE_SHIFT; + return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT; } struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); --- linux-oracle-5.4.0.orig/drivers/hwtracing/coresight/coresight.c +++ linux-oracle-5.4.0/drivers/hwtracing/coresight/coresight.c @@ -253,9 +253,9 @@ struct coresight_device *parent, struct coresight_device *child) { - int ret; + int ret = 0; int link_subtype; - int refport, inport, outport; + int inport, outport; if (!parent || !child) return -EINVAL; @@ -264,29 +264,17 @@ outport = coresight_find_link_outport(csdev, child); link_subtype = csdev->subtype.link_subtype; - if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) - refport = inport; - else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) - refport = outport; - else - refport = 0; - - if (refport < 0) - return refport; - - if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { - if (link_ops(csdev)->enable) { - ret = link_ops(csdev)->enable(csdev, inport, outport); - if (ret) { - atomic_dec(&csdev->refcnt[refport]); - return ret; - } - } - } - - csdev->enable = true; + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0) + return inport; + if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && outport < 0) + return outport; + + if (link_ops(csdev)->enable) + ret = link_ops(csdev)->enable(csdev, inport, outport); + if (!ret) + csdev->enable = true; - return 0; + return ret; } static void coresight_disable_link(struct coresight_device *csdev, @@ -295,7 +283,7 @@ { int i, nr_conns; int link_subtype; - int refport, inport, outport; + int inport, outport; if (!parent || !child) return; @@ -305,20 +293,15 @@ link_subtype = csdev->subtype.link_subtype; if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { - refport = inport; nr_conns = csdev->pdata->nr_inport; } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { - refport = outport; nr_conns = csdev->pdata->nr_outport; } else { - refport = 0; nr_conns = 1; } - if (atomic_dec_return(&csdev->refcnt[refport]) == 0) { - if (link_ops(csdev)->disable) - link_ops(csdev)->disable(csdev, inport, outport); - } + if (link_ops(csdev)->disable) + link_ops(csdev)->disable(csdev, inport, outport); for (i = 0; i < nr_conns; i++) if (atomic_read(&csdev->refcnt[i]) != 0) @@ -1090,6 +1073,7 @@ * platform data. */ fwnode_handle_put(conn->child_fwnode); + conn->child_fwnode = NULL; /* No need to continue */ break; } --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/core.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/core.c @@ -215,6 +215,22 @@ static DEVICE_ATTR_RO(port); +static void intel_th_trace_prepare(struct intel_th_device *thdev) +{ + struct intel_th_device *hub = to_intel_th_hub(thdev); + struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); + + if (hub->type != INTEL_TH_SWITCH) + return; + + if (thdev->type != INTEL_TH_OUTPUT) + return; + + pm_runtime_get_sync(&thdev->dev); + hubdrv->prepare(hub, &thdev->output); + pm_runtime_put(&thdev->dev); +} + static int intel_th_output_activate(struct intel_th_device *thdev) { struct intel_th_driver *thdrv = @@ -235,6 +251,7 @@ if (ret) goto fail_put; + intel_th_trace_prepare(thdev); if (thdrv->activate) ret = thdrv->activate(thdev); else @@ -649,10 +666,8 @@ } err = intel_th_device_add_resources(thdev, res, subdev->nres); - if (err) { - put_device(&thdev->dev); + if (err) goto fail_put_device; - } if (subdev->type == INTEL_TH_OUTPUT) { if (subdev->mknode) @@ -667,10 +682,8 @@ } err = device_add(&thdev->dev); - if (err) { - put_device(&thdev->dev); + if (err) goto fail_free_res; - } /* need switch driver to be loaded to enumerate the rest */ if (subdev->type == INTEL_TH_SWITCH && !req) { @@ -838,9 +851,6 @@ ret |= d->irq(th->thdev[i]); } - if (ret == IRQ_NONE) - pr_warn_ratelimited("nobody cared for irq\n"); - return ret; } @@ -891,6 +901,7 @@ if (th->irq == -1) th->irq = devres[r].start; + th->num_irqs++; break; default: dev_warn(dev, "Unknown resource type %lx\n", @@ -944,6 +955,9 @@ th->num_thdevs = 0; + for (i = 0; i < th->num_irqs; i++) + devm_free_irq(th->dev, th->irq + i, th); + pm_runtime_get_sync(th->dev); pm_runtime_forbid(th->dev); @@ -1024,15 +1038,30 @@ { struct intel_th_device *hub = to_intel_th_hub(thdev); struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); + int ret; /* In host mode, this is up to the external debugger, do nothing. */ if (hub->host_mode) return 0; - if (!hubdrv->set_output) - return -ENOTSUPP; + /* + * hub is instantiated together with the source device that + * calls here, so guaranteed to be present. + */ + hubdrv = to_intel_th_driver(hub->dev.driver); + if (!hubdrv || !try_module_get(hubdrv->driver.owner)) + return -EINVAL; + + if (!hubdrv->set_output) { + ret = -ENOTSUPP; + goto out; + } + + ret = hubdrv->set_output(hub, master); - return hubdrv->set_output(hub, master); +out: + module_put(hubdrv->driver.owner); + return ret; } EXPORT_SYMBOL_GPL(intel_th_set_output); --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/gth.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/gth.c @@ -543,7 +543,7 @@ output->active = false; for_each_set_bit(master, gth->output[output->port].master, - TH_CONFIGURABLE_MASTERS) { + TH_CONFIGURABLE_MASTERS + 1) { gth_master_set(gth, master, -1); } spin_unlock(>h->gth_lock); @@ -564,6 +564,21 @@ iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); } +static void intel_th_gth_prepare(struct intel_th_device *thdev, + struct intel_th_output *output) +{ + struct gth_device *gth = dev_get_drvdata(&thdev->dev); + int count; + + /* + * Wait until the output port is in reset before we start + * programming it. + */ + for (count = GTH_PLE_WAITLOOP_DEPTH; + count && !(gth_output_get(gth, output->port) & BIT(5)); count--) + cpu_relax(); +} + /** * intel_th_gth_enable() - enable tracing to an output device * @thdev: GTH device @@ -697,7 +712,7 @@ othdev->output.port = -1; othdev->output.active = false; gth->output[port].output = NULL; - for (master = 0; master <= TH_CONFIGURABLE_MASTERS; master++) + for (master = 0; master < TH_CONFIGURABLE_MASTERS + 1; master++) if (gth->master[master] == port) gth->master[master] = -1; spin_unlock(>h->gth_lock); @@ -815,6 +830,7 @@ .assign = intel_th_gth_assign, .unassign = intel_th_gth_unassign, .set_output = intel_th_gth_set_output, + .prepare = intel_th_gth_prepare, .enable = intel_th_gth_enable, .trig_switch = intel_th_gth_switch, .disable = intel_th_gth_disable, --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/intel_th.h +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/intel_th.h @@ -47,11 +47,13 @@ /** * struct intel_th_drvdata - describes hardware capabilities and quirks * @tscu_enable: device needs SW to enable time stamping unit + * @multi_is_broken: device has multiblock mode is broken * @has_mintctl: device has interrupt control (MINTCTL) register * @host_mode_only: device can only operate in 'host debugger' mode */ struct intel_th_drvdata { unsigned int tscu_enable : 1, + multi_is_broken : 1, has_mintctl : 1, host_mode_only : 1; }; @@ -141,6 +143,7 @@ * @remove: remove method * @assign: match a given output type device against available outputs * @unassign: deassociate an output type device from an output port + * @prepare: prepare output port for tracing * @enable: enable tracing for a given output device * @disable: disable tracing for a given output device * @irq: interrupt callback @@ -162,6 +165,8 @@ struct intel_th_device *othdev); void (*unassign)(struct intel_th_device *thdev, struct intel_th_device *othdev); + void (*prepare)(struct intel_th_device *thdev, + struct intel_th_output *output); void (*enable)(struct intel_th_device *thdev, struct intel_th_output *output); void (*trig_switch)(struct intel_th_device *thdev, @@ -261,6 +266,7 @@ * @num_thdevs: number of devices in the @thdev array * @num_resources: number of resources in the @resource array * @irq: irq number + * @num_irqs: number of IRQs is use * @id: this Intel TH controller's device ID in the system * @major: device node major for output devices */ @@ -277,6 +283,7 @@ unsigned int num_thdevs; unsigned int num_resources; int irq; + int num_irqs; int id; int major; --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/msu-sink.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/msu-sink.c @@ -71,6 +71,9 @@ block = dma_alloc_coherent(priv->dev->parent->parent, PAGE_SIZE, &sg_dma_address(sg_ptr), GFP_KERNEL); + if (!block) + return -ENOMEM; + sg_set_buf(sg_ptr, block, PAGE_SIZE); } --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/msu.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/msu.c @@ -157,7 +157,8 @@ /* config */ unsigned int enabled : 1, wrap : 1, - do_irq : 1; + do_irq : 1, + multi_is_broken : 1; unsigned int mode; unsigned int burst_len; unsigned int index; @@ -718,9 +719,6 @@ if (old != expect) { ret = -EINVAL; - dev_warn_ratelimited(msc_dev(win->msc), - "expected lockout state %d, got %d\n", - expect, old); goto unlock; } @@ -741,6 +739,10 @@ /* from intel_th_msc_window_unlock(), don't warn if not locked */ if (expect == WIN_LOCKED && old == new) return 0; + + dev_warn_ratelimited(msc_dev(win->msc), + "expected lockout state %d, got %d\n", + expect, old); } return ret; @@ -760,7 +762,7 @@ lockdep_assert_held(&msc->buf_mutex); if (msc->mode > MSC_MODE_MULTI) - return -ENOTSUPP; + return -EINVAL; if (msc->mode == MSC_MODE_MULTI) { if (msc_win_set_lockout(msc->cur_win, WIN_READY, WIN_INUSE)) @@ -1048,6 +1050,16 @@ static inline void msc_buffer_set_wb(struct msc_window *win) {} #endif /* CONFIG_X86 */ +static struct page *msc_sg_page(struct scatterlist *sg) +{ + void *addr = sg_virt(sg); + + if (is_vmalloc_addr(addr)) + return vmalloc_to_page(addr); + + return sg_page(sg); +} + /** * msc_buffer_win_alloc() - alloc a window for a multiblock mode * @msc: MSC device @@ -1120,7 +1132,7 @@ int i; for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) { - struct page *page = sg_page(sg); + struct page *page = msc_sg_page(sg); page->mapping = NULL; dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE, @@ -1294,7 +1306,7 @@ } else if (msc->mode == MSC_MODE_MULTI) { ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins); } else { - ret = -ENOTSUPP; + ret = -EINVAL; } if (!ret) { @@ -1382,7 +1394,7 @@ pgoff -= win->pgoff; for_each_sg(win->sgt->sgl, sg, win->nr_segs, blk) { - struct page *page = sg_page(sg); + struct page *page = msc_sg_page(sg); size_t pgsz = PFN_DOWN(sg->length); if (pgoff < pgsz) @@ -1530,7 +1542,7 @@ if (ret >= 0) *ppos = iter->offset; } else { - ret = -ENOTSUPP; + ret = -EINVAL; } put_count: @@ -1664,7 +1676,7 @@ { atomic_set(&msc->user_count, -1); - msc->mode = MSC_MODE_MULTI; + msc->mode = msc->multi_is_broken ? MSC_MODE_SINGLE : MSC_MODE_MULTI; mutex_init(&msc->buf_mutex); INIT_LIST_HEAD(&msc->win_list); INIT_LIST_HEAD(&msc->iter_list); @@ -1676,10 +1688,13 @@ return 0; } -static void msc_win_switch(struct msc *msc) +static int msc_win_switch(struct msc *msc) { struct msc_window *first; + if (list_empty(&msc->win_list)) + return -EINVAL; + first = list_first_entry(&msc->win_list, struct msc_window, entry); if (msc_is_last_win(msc->cur_win)) @@ -1691,6 +1706,8 @@ msc->base_addr = msc_win_base_dma(msc->cur_win); intel_th_trace_switch(msc->thdev); + + return 0; } /** @@ -1871,6 +1888,9 @@ return -EINVAL; found: + if (i == MSC_MODE_MULTI && msc->multi_is_broken) + return -EOPNOTSUPP; + mutex_lock(&msc->buf_mutex); ret = 0; @@ -2025,16 +2045,15 @@ if (val != 1) return -EINVAL; + ret = -EINVAL; mutex_lock(&msc->buf_mutex); /* * Window switch can only happen in the "multi" mode. * If a external buffer is engaged, they have the full * control over window switching. */ - if (msc->mode != MSC_MODE_MULTI || msc->mbuf) - ret = -ENOTSUPP; - else - msc_win_switch(msc); + if (msc->mode == MSC_MODE_MULTI && !msc->mbuf) + ret = msc_win_switch(msc); mutex_unlock(&msc->buf_mutex); return ret ? ret : size; @@ -2078,6 +2097,9 @@ if (!res) msc->do_irq = 1; + if (INTEL_TH_CAP(to_intel_th(thdev), multi_is_broken)) + msc->multi_is_broken = 1; + msc->index = thdev->id; msc->thdev = thdev; --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/pci.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/pci.c @@ -100,8 +100,10 @@ } th = intel_th_alloc(&pdev->dev, drvdata, resource, r); - if (IS_ERR(th)) - return PTR_ERR(th); + if (IS_ERR(th)) { + err = PTR_ERR(th); + goto err_free_irq; + } th->activate = intel_th_pci_activate; th->deactivate = intel_th_pci_deactivate; @@ -109,6 +111,10 @@ pci_set_master(pdev); return 0; + +err_free_irq: + pci_free_irq_vectors(pdev); + return err; } static void intel_th_pci_remove(struct pci_dev *pdev) @@ -120,6 +126,10 @@ pci_free_irq_vectors(pdev); } +static const struct intel_th_drvdata intel_th_1x_multi_is_broken = { + .multi_is_broken = 1, +}; + static const struct intel_th_drvdata intel_th_2x = { .tscu_enable = 1, .has_mintctl = 1, @@ -152,7 +162,7 @@ { /* Kaby Lake PCH-H */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), - .driver_data = (kernel_ulong_t)0, + .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, }, { /* Denverton */ @@ -205,20 +215,135 @@ .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Comet Lake PCH-V */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), + .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, + }, + { /* Ice Lake NNPI */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Ice Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Tiger Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Tiger Lake PCH */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), .driver_data = (kernel_ulong_t)&intel_th_2x, }, { + /* Tiger Lake PCH-H */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { /* Jasper Lake PCH */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), .driver_data = (kernel_ulong_t)&intel_th_2x, }, + { + /* Jasper Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Elkhart Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Elkhart Lake */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Alder Lake-P */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Emmitsburg PCH */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Alder Lake-M */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Raptor Lake-S CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Meteor Lake-P */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Meteor Lake-S CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Meteor Lake-S */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Raptor Lake-S */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Granite Rapids */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Granite Rapids SOC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Sapphire Rapids SOC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Lunar Lake */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Arrow Lake */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7724), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Panther Lake-H */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe324), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Panther Lake-P/U */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe424), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, + { + /* Rocket Lake CPU */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19), + .driver_data = (kernel_ulong_t)&intel_th_2x, + }, { 0 }, }; --- linux-oracle-5.4.0.orig/drivers/hwtracing/intel_th/sth.c +++ linux-oracle-5.4.0/drivers/hwtracing/intel_th/sth.c @@ -161,9 +161,7 @@ { struct sth_device *sth = container_of(stm_data, struct sth_device, stm); - intel_th_set_output(to_intel_th_device(sth->dev), master); - - return 0; + return intel_th_set_output(to_intel_th_device(sth->dev), master); } static int intel_th_sw_init(struct sth_device *sth) --- linux-oracle-5.4.0.orig/drivers/hwtracing/stm/core.c +++ linux-oracle-5.4.0/drivers/hwtracing/stm/core.c @@ -878,8 +878,11 @@ return -ENOMEM; stm->major = register_chrdev(0, stm_data->name, &stm_fops); - if (stm->major < 0) - goto err_free; + if (stm->major < 0) { + err = stm->major; + vfree(stm); + return err; + } device_initialize(&stm->dev); stm->dev.devt = MKDEV(stm->major, 0); @@ -923,10 +926,8 @@ err_device: unregister_chrdev(stm->major, stm_data->name); - /* matches device_initialize() above */ + /* calls stm_device_release() */ put_device(&stm->dev); -err_free: - vfree(stm); return err; } --- linux-oracle-5.4.0.orig/drivers/hwtracing/stm/heartbeat.c +++ linux-oracle-5.4.0/drivers/hwtracing/stm/heartbeat.c @@ -64,7 +64,7 @@ static int stm_heartbeat_init(void) { - int i, ret = -ENOMEM; + int i, ret; if (nr_devs < 0 || nr_devs > STM_HEARTBEAT_MAX) return -EINVAL; @@ -72,8 +72,10 @@ for (i = 0; i < nr_devs; i++) { stm_heartbeat[i].data.name = kasprintf(GFP_KERNEL, "heartbeat.%d", i); - if (!stm_heartbeat[i].data.name) + if (!stm_heartbeat[i].data.name) { + ret = -ENOMEM; goto fail_unregister; + } stm_heartbeat[i].data.nr_chans = 1; stm_heartbeat[i].data.link = stm_heartbeat_link; --- linux-oracle-5.4.0.orig/drivers/hwtracing/stm/p_sys-t.c +++ linux-oracle-5.4.0/drivers/hwtracing/stm/p_sys-t.c @@ -238,7 +238,7 @@ static inline bool sys_t_need_ts(struct sys_t_output *op) { if (op->node.ts_interval && - time_after(op->ts_jiffies + op->node.ts_interval, jiffies)) { + time_after(jiffies, op->ts_jiffies + op->node.ts_interval)) { op->ts_jiffies = jiffies; return true; @@ -250,8 +250,8 @@ static bool sys_t_need_clock_sync(struct sys_t_output *op) { if (op->node.clocksync_interval && - time_after(op->clocksync_jiffies + op->node.clocksync_interval, - jiffies)) { + time_after(jiffies, + op->clocksync_jiffies + op->node.clocksync_interval)) { op->clocksync_jiffies = jiffies; return true; --- linux-oracle-5.4.0.orig/drivers/hwtracing/stm/policy.c +++ linux-oracle-5.4.0/drivers/hwtracing/stm/policy.c @@ -345,7 +345,11 @@ stm->policy = NULL; policy->stm = NULL; + /* + * Drop the reference on the protocol driver and lose the link. + */ stm_put_protocol(stm->pdrv); + stm->pdrv = NULL; stm_put_device(stm); } --- linux-oracle-5.4.0.orig/drivers/i2c/algos/i2c-algo-pca.c +++ linux-oracle-5.4.0/drivers/i2c/algos/i2c-algo-pca.c @@ -41,8 +41,22 @@ pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); pca_outw(adap, I2C_PCA_IND, 0xA5); pca_outw(adap, I2C_PCA_IND, 0x5A); + + /* + * After a reset we need to re-apply any configuration + * (calculated in pca_init) to get the bus in a working state. + */ + pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IMODE); + pca_outw(adap, I2C_PCA_IND, adap->bus_settings.mode); + pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_ISCLL); + pca_outw(adap, I2C_PCA_IND, adap->bus_settings.tlow); + pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_ISCLH); + pca_outw(adap, I2C_PCA_IND, adap->bus_settings.thi); + + pca_set_con(adap, I2C_PCA_CON_ENSIO); } else { adap->reset_chip(adap->data); + pca_set_con(adap, I2C_PCA_CON_ENSIO | adap->bus_settings.clock_freq); } } @@ -314,7 +328,8 @@ DEB2("BUS ERROR - SDA Stuck low\n"); pca_reset(adap); goto out; - case 0x90: /* Bus error - SCL stuck low */ + case 0x78: /* Bus error - SCL stuck low (PCA9665) */ + case 0x90: /* Bus error - SCL stuck low (PCA9564) */ DEB2("BUS ERROR - SCL Stuck low\n"); pca_reset(adap); goto out; @@ -422,13 +437,14 @@ " Use the nominal frequency.\n", adap->name); } - pca_reset(pca_data); - clock = pca_clock(pca_data); printk(KERN_INFO "%s: Clock frequency is %dkHz\n", adap->name, freqs[clock]); - pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock); + /* Store settings as these will be needed when the PCA chip is reset */ + pca_data->bus_settings.clock_freq = clock; + + pca_reset(pca_data); } else { int clock; int mode; @@ -495,19 +511,15 @@ thi = tlow * min_thi / min_tlow; } + /* Store settings as these will be needed when the PCA chip is reset */ + pca_data->bus_settings.mode = mode; + pca_data->bus_settings.tlow = tlow; + pca_data->bus_settings.thi = thi; + pca_reset(pca_data); printk(KERN_INFO "%s: Clock frequency is %dHz\n", adap->name, clock * 100); - - pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE); - pca_outw(pca_data, I2C_PCA_IND, mode); - pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL); - pca_outw(pca_data, I2C_PCA_IND, tlow); - pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH); - pca_outw(pca_data, I2C_PCA_IND, thi); - - pca_set_con(pca_data, I2C_PCA_CON_ENSIO); } udelay(500); /* 500 us for oscillator to stabilise */ --- linux-oracle-5.4.0.orig/drivers/i2c/busses/Kconfig +++ linux-oracle-5.4.0/drivers/i2c/busses/Kconfig @@ -483,7 +483,7 @@ config I2C_CADENCE tristate "Cadence I2C Controller" - depends on ARCH_ZYNQ || ARM64 || XTENSA + depends on ARCH_ZYNQ || ARM64 || XTENSA || COMPILE_TEST help Say yes here to select Cadence I2C Host Controller. This controller is e.g. used by Xilinx Zynq. @@ -894,7 +894,7 @@ config I2C_QUP tristate "Qualcomm QUP based I2C controller" - depends on ARCH_QCOM + depends on ARCH_QCOM || COMPILE_TEST help If you say yes to this option, support will be included for the built-in I2C interface on the Qualcomm SoCs. @@ -1162,6 +1162,7 @@ tristate "Renesas R-Car I2C Controller" depends on ARCH_RENESAS || COMPILE_TEST select I2C_SLAVE + select RESET_CONTROLLER if ARCH_RCAR_GEN3 help If you say yes to this option, support will be included for the R-Car I2C controller. --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-altera.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-altera.c @@ -70,6 +70,7 @@ * @isr_mask: cached copy of local ISR enables. * @isr_status: cached copy of local ISR status. * @lock: spinlock for IRQ synchronization. + * @isr_mutex: mutex for IRQ thread. */ struct altr_i2c_dev { void __iomem *base; @@ -86,6 +87,7 @@ u32 isr_mask; u32 isr_status; spinlock_t lock; /* IRQ synchronization */ + struct mutex isr_mutex; }; static void @@ -171,7 +173,7 @@ /* SCL Low Time */ writel(t_low, idev->base + ALTR_I2C_SCL_LOW); /* SDA Hold Time, 300ns */ - writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD); + writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD); /* Mask all master interrupt bits */ altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); @@ -245,10 +247,11 @@ struct altr_i2c_dev *idev = _dev; u32 status = idev->isr_status; + mutex_lock(&idev->isr_mutex); if (!idev->msg) { dev_warn(idev->dev, "unexpected interrupt\n"); altr_i2c_int_clear(idev, ALTR_I2C_ALL_IRQ); - return IRQ_HANDLED; + goto out; } read = (idev->msg->flags & I2C_M_RD) != 0; @@ -301,6 +304,8 @@ complete(&idev->msg_complete); dev_dbg(idev->dev, "Message Complete\n"); } +out: + mutex_unlock(&idev->isr_mutex); return IRQ_HANDLED; } @@ -312,6 +317,7 @@ u32 value; u8 addr = i2c_8bit_addr_from_msg(msg); + mutex_lock(&idev->isr_mutex); idev->msg = msg; idev->msg_len = msg->len; idev->buf = msg->buf; @@ -336,6 +342,7 @@ altr_i2c_int_enable(idev, imask, true); altr_i2c_fill_tx_fifo(idev); } + mutex_unlock(&idev->isr_mutex); time_left = wait_for_completion_timeout(&idev->msg_complete, ALTR_I2C_XFER_TIMEOUT); @@ -384,7 +391,6 @@ struct altr_i2c_dev *idev = NULL; struct resource *res; int irq, ret; - u32 val; idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); if (!idev) @@ -410,18 +416,19 @@ idev->dev = &pdev->dev; init_completion(&idev->msg_complete); spin_lock_init(&idev->lock); + mutex_init(&idev->isr_mutex); - val = device_property_read_u32(idev->dev, "fifo-size", + ret = device_property_read_u32(idev->dev, "fifo-size", &idev->fifo_size); - if (val) { + if (ret) { dev_err(&pdev->dev, "FIFO size set to default of %d\n", ALTR_I2C_DFLT_FIFO_SZ); idev->fifo_size = ALTR_I2C_DFLT_FIFO_SZ; } - val = device_property_read_u32(idev->dev, "clock-frequency", + ret = device_property_read_u32(idev->dev, "clock-frequency", &idev->bus_clk_rate); - if (val) { + if (ret) { dev_err(&pdev->dev, "Default to 100kHz\n"); idev->bus_clk_rate = 100000; /* default clock rate */ } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -349,12 +349,12 @@ if (!privdata) return -ENOMEM; + privdata->pci_dev = pci_dev; rc = amd_mp2_pci_init(privdata, pci_dev); if (rc) return rc; mutex_init(&privdata->c2p_lock); - privdata->pci_dev = pci_dev; pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000); pm_runtime_use_autosuspend(&pci_dev->dev); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-aspeed.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-aspeed.c @@ -69,6 +69,7 @@ * These share bit definitions, so use the same values for the enable & * status bits. */ +#define ASPEED_I2CD_INTR_RECV_MASK 0xf000ffff #define ASPEED_I2CD_INTR_SDA_DL_TIMEOUT BIT(14) #define ASPEED_I2CD_INTR_BUS_RECOVER_DONE BIT(13) #define ASPEED_I2CD_INTR_SLAVE_MATCH BIT(7) @@ -171,6 +172,13 @@ static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus); +/* precondition: bus.lock has been acquired. */ +static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus) +{ + bus->master_state = ASPEED_I2C_MASTER_STOP; + writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); +} + static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus) { unsigned long time_left, flags; @@ -188,7 +196,7 @@ command); reinit_completion(&bus->cmd_complete); - writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); + aspeed_i2c_do_stop(bus); spin_unlock_irqrestore(&bus->lock, flags); time_left = wait_for_completion_timeout( @@ -249,18 +257,46 @@ if (!slave) return 0; - command = readl(bus->base + ASPEED_I2C_CMD_REG); + /* + * Handle stop conditions early, prior to SLAVE_MATCH. Some masters may drive + * transfers with low enough latency between the nak/stop phase of the current + * command and the start/address phase of the following command that the + * interrupts are coalesced by the time we process them. + */ + if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { + irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; + bus->slave_state = ASPEED_I2C_SLAVE_STOP; + } + + if (irq_status & ASPEED_I2CD_INTR_TX_NAK && + bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { + irq_handled |= ASPEED_I2CD_INTR_TX_NAK; + bus->slave_state = ASPEED_I2C_SLAVE_STOP; + } - /* Slave was requested, restart state machine. */ + /* Propagate any stop conditions to the slave implementation. */ + if (bus->slave_state == ASPEED_I2C_SLAVE_STOP) { + i2c_slave_event(slave, I2C_SLAVE_STOP, &value); + bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; + } + + /* + * Now that we've dealt with any potentially coalesced stop conditions, + * address any start conditions. + */ if (irq_status & ASPEED_I2CD_INTR_SLAVE_MATCH) { irq_handled |= ASPEED_I2CD_INTR_SLAVE_MATCH; bus->slave_state = ASPEED_I2C_SLAVE_START; } - /* Slave is not currently active, irq was for someone else. */ + /* + * If the slave has been stopped and not started then slave interrupt + * handling is complete. + */ if (bus->slave_state == ASPEED_I2C_SLAVE_INACTIVE) return irq_handled; + command = readl(bus->base + ASPEED_I2C_CMD_REG); dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n", irq_status, command); @@ -279,17 +315,6 @@ irq_handled |= ASPEED_I2CD_INTR_RX_DONE; } - /* Slave was asked to stop. */ - if (irq_status & ASPEED_I2CD_INTR_NORMAL_STOP) { - irq_handled |= ASPEED_I2CD_INTR_NORMAL_STOP; - bus->slave_state = ASPEED_I2C_SLAVE_STOP; - } - if (irq_status & ASPEED_I2CD_INTR_TX_NAK && - bus->slave_state == ASPEED_I2C_SLAVE_READ_PROCESSED) { - irq_handled |= ASPEED_I2CD_INTR_TX_NAK; - bus->slave_state = ASPEED_I2C_SLAVE_STOP; - } - switch (bus->slave_state) { case ASPEED_I2C_SLAVE_READ_REQUESTED: if (unlikely(irq_status & ASPEED_I2CD_INTR_TX_ACK)) @@ -318,8 +343,7 @@ i2c_slave_event(slave, I2C_SLAVE_WRITE_RECEIVED, &value); break; case ASPEED_I2C_SLAVE_STOP: - i2c_slave_event(slave, I2C_SLAVE_STOP, &value); - bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; + /* Stop event handling is done early. Unreachable. */ break; case ASPEED_I2C_SLAVE_START: /* Slave was just started. Waiting for the next event. */; @@ -369,13 +393,6 @@ } /* precondition: bus.lock has been acquired. */ -static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus) -{ - bus->master_state = ASPEED_I2C_MASTER_STOP; - writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG); -} - -/* precondition: bus.lock has been acquired. */ static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus) { if (bus->msgs_index + 1 < bus->msgs_count) { @@ -603,6 +620,8 @@ /* Ack all interrupts except for Rx done */ writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, bus->base + ASPEED_I2C_INTR_STS_REG); + readl(bus->base + ASPEED_I2C_INTR_STS_REG); + irq_received &= ASPEED_I2CD_INTR_RECV_MASK; irq_remaining = irq_received; #if IS_ENABLED(CONFIG_I2C_SLAVE) @@ -645,9 +664,11 @@ irq_received, irq_handled); /* Ack Rx done */ - if (irq_received & ASPEED_I2CD_INTR_RX_DONE) + if (irq_received & ASPEED_I2CD_INTR_RX_DONE) { writel(ASPEED_I2CD_INTR_RX_DONE, bus->base + ASPEED_I2C_INTR_STS_REG); + readl(bus->base + ASPEED_I2C_INTR_STS_REG); + } spin_unlock(&bus->lock); return irq_remaining ? IRQ_NONE : IRQ_HANDLED; } @@ -688,13 +709,16 @@ if (time_left == 0) { /* - * If timed out and bus is still busy in a multi master - * environment, attempt recovery at here. + * In a multi-master setup, if a timeout occurs, attempt + * recovery. But if the bus is idle, we still need to reset the + * i2c controller to clear the remaining interrupts. */ if (bus->multi_master && (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS)) aspeed_i2c_recover_bus(bus); + else + aspeed_i2c_reset(bus); /* * If timed out and the state is still pending, drop the pending @@ -732,6 +756,8 @@ func_ctrl_reg_val = readl(bus->base + ASPEED_I2C_FUN_CTRL_REG); func_ctrl_reg_val |= ASPEED_I2CD_SLAVE_EN; writel(func_ctrl_reg_val, bus->base + ASPEED_I2C_FUN_CTRL_REG); + + bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; } static int aspeed_i2c_reg_slave(struct i2c_client *client) @@ -748,7 +774,6 @@ __aspeed_i2c_reg_slave(bus, client->addr); bus->slave = client; - bus->slave_state = ASPEED_I2C_SLAVE_INACTIVE; spin_unlock_irqrestore(&bus->lock, flags); return 0; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-at91-master.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-at91-master.c @@ -609,6 +609,7 @@ unsigned int_addr_flag = 0; struct i2c_msg *m_start = msg; bool is_read; + u8 *dma_buf = NULL; dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num); @@ -656,7 +657,17 @@ dev->msg = m_start; dev->recv_len_abort = false; + if (dev->use_dma) { + dma_buf = i2c_get_dma_safe_msg_buf(m_start, 1); + if (!dma_buf) { + ret = -ENOMEM; + goto out; + } + dev->buf = dma_buf; + } + ret = at91_do_twi_transfer(dev); + i2c_put_dma_safe_msg_buf(dma_buf, m_start, !ret); ret = (ret < 0) ? ret : num; out: --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-at91-slave.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-at91-slave.c @@ -106,8 +106,7 @@ static u32 at91_twi_func(struct i2c_adapter *adapter) { - return I2C_FUNC_SLAVE | I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL - | I2C_FUNC_SMBUS_READ_BLOCK_DATA; + return I2C_FUNC_SLAVE; } static const struct i2c_algorithm at91_twi_algorithm_slave = { --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-bcm-iproc.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-bcm-iproc.c @@ -157,6 +157,11 @@ #define IE_S_ALL_INTERRUPT_SHIFT 21 #define IE_S_ALL_INTERRUPT_MASK 0x3f +/* + * It takes ~18us to reading 10bytes of data, hence to keep tasklet + * running for less time, max slave read per tasklet is set to 10 bytes. + */ +#define MAX_SLAVE_RX_PER_INT 10 enum i2c_slave_read_status { I2C_SLAVE_RX_FIFO_EMPTY = 0, @@ -203,8 +208,18 @@ /* bytes that have been read */ unsigned int rx_bytes; unsigned int thld_bytes; + + bool slave_rx_only; + bool rx_start_rcvd; + bool slave_read_complete; + u32 tx_underrun; + u32 slave_int_mask; + struct tasklet_struct slave_rx_tasklet; }; +/* tasklet to process slave rx data */ +static void slave_rx_tasklet_fn(unsigned long); + /* * Can be expanded in the future if more interrupt status bits are utilized */ @@ -213,7 +228,8 @@ #define ISR_MASK_SLAVE (BIT(IS_S_START_BUSY_SHIFT)\ | BIT(IS_S_RX_EVENT_SHIFT) | BIT(IS_S_RD_EVENT_SHIFT)\ - | BIT(IS_S_TX_UNDERRUN_SHIFT)) + | BIT(IS_S_TX_UNDERRUN_SHIFT) | BIT(IS_S_RX_FIFO_FULL_SHIFT)\ + | BIT(IS_S_RX_THLD_SHIFT)) static int bcm_iproc_i2c_reg_slave(struct i2c_client *slave); static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave); @@ -224,13 +240,14 @@ u32 offset) { u32 val; + unsigned long flags; if (iproc_i2c->idm_base) { - spin_lock(&iproc_i2c->idm_lock); + spin_lock_irqsave(&iproc_i2c->idm_lock, flags); writel(iproc_i2c->ape_addr_mask, iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); val = readl(iproc_i2c->base + offset); - spin_unlock(&iproc_i2c->idm_lock); + spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); } else { val = readl(iproc_i2c->base + offset); } @@ -241,12 +258,14 @@ static inline void iproc_i2c_wr_reg(struct bcm_iproc_i2c_dev *iproc_i2c, u32 offset, u32 val) { + unsigned long flags; + if (iproc_i2c->idm_base) { - spin_lock(&iproc_i2c->idm_lock); + spin_lock_irqsave(&iproc_i2c->idm_lock, flags); writel(iproc_i2c->ape_addr_mask, iproc_i2c->idm_base + IDM_CTRL_DIRECT_OFFSET); writel(val, iproc_i2c->base + offset); - spin_unlock(&iproc_i2c->idm_lock); + spin_unlock_irqrestore(&iproc_i2c->idm_lock, flags); } else { writel(val, iproc_i2c->base + offset); } @@ -257,6 +276,7 @@ { u32 val; + iproc_i2c->tx_underrun = 0; if (need_reset) { /* put controller in reset */ val = iproc_i2c_rd_reg(iproc_i2c, CFG_OFFSET); @@ -293,8 +313,11 @@ /* Enable interrupt register to indicate a valid byte in receive fifo */ val = BIT(IE_S_RX_EVENT_SHIFT); + /* Enable interrupt register to indicate a Master read transaction */ + val |= BIT(IE_S_RD_EVENT_SHIFT); /* Enable interrupt register for the Slave BUSY command */ val |= BIT(IE_S_START_BUSY_SHIFT); + iproc_i2c->slave_int_mask = val; iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); } @@ -319,73 +342,176 @@ } } -static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, - u32 status) +static void bcm_iproc_i2c_slave_read(struct bcm_iproc_i2c_dev *iproc_i2c) { + u8 rx_data, rx_status; + u32 rx_bytes = 0; u32 val; - u8 value, rx_status; - /* Slave RX byte receive */ - if (status & BIT(IS_S_RX_EVENT_SHIFT)) { + while (rx_bytes < MAX_SLAVE_RX_PER_INT) { val = iproc_i2c_rd_reg(iproc_i2c, S_RX_OFFSET); rx_status = (val >> S_RX_STATUS_SHIFT) & S_RX_STATUS_MASK; - if (rx_status == I2C_SLAVE_RX_START) { - /* Start of SMBUS for Master write */ - i2c_slave_event(iproc_i2c->slave, - I2C_SLAVE_WRITE_REQUESTED, &value); + rx_data = ((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); - val = iproc_i2c_rd_reg(iproc_i2c, S_RX_OFFSET); - value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); + if (rx_status == I2C_SLAVE_RX_START) { + /* Start of SMBUS Master write */ i2c_slave_event(iproc_i2c->slave, - I2C_SLAVE_WRITE_RECEIVED, &value); - } else if (status & BIT(IS_S_RD_EVENT_SHIFT)) { - /* Start of SMBUS for Master Read */ + I2C_SLAVE_WRITE_REQUESTED, &rx_data); + iproc_i2c->rx_start_rcvd = true; + iproc_i2c->slave_read_complete = false; + } else if (rx_status == I2C_SLAVE_RX_DATA && + iproc_i2c->rx_start_rcvd) { + /* Middle of SMBUS Master write */ i2c_slave_event(iproc_i2c->slave, - I2C_SLAVE_READ_REQUESTED, &value); - iproc_i2c_wr_reg(iproc_i2c, S_TX_OFFSET, value); + I2C_SLAVE_WRITE_RECEIVED, &rx_data); + } else if (rx_status == I2C_SLAVE_RX_END && + iproc_i2c->rx_start_rcvd) { + /* End of SMBUS Master write */ + if (iproc_i2c->slave_rx_only) + i2c_slave_event(iproc_i2c->slave, + I2C_SLAVE_WRITE_RECEIVED, + &rx_data); + + i2c_slave_event(iproc_i2c->slave, I2C_SLAVE_STOP, + &rx_data); + } else if (rx_status == I2C_SLAVE_RX_FIFO_EMPTY) { + iproc_i2c->rx_start_rcvd = false; + iproc_i2c->slave_read_complete = true; + break; + } - val = BIT(S_CMD_START_BUSY_SHIFT); - iproc_i2c_wr_reg(iproc_i2c, S_CMD_OFFSET, val); + rx_bytes++; + } +} - /* - * Enable interrupt for TX FIFO becomes empty and - * less than PKT_LENGTH bytes were output on the SMBUS - */ - val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); - val |= BIT(IE_S_TX_UNDERRUN_SHIFT); - iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); - } else { - /* Master write other than start */ - value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); +static void slave_rx_tasklet_fn(unsigned long data) +{ + struct bcm_iproc_i2c_dev *iproc_i2c = (struct bcm_iproc_i2c_dev *)data; + u32 int_clr; + + bcm_iproc_i2c_slave_read(iproc_i2c); + + /* clear pending IS_S_RX_EVENT_SHIFT interrupt */ + int_clr = BIT(IS_S_RX_EVENT_SHIFT); + + if (!iproc_i2c->slave_rx_only && iproc_i2c->slave_read_complete) { + /* + * In case of single byte master-read request, + * IS_S_TX_UNDERRUN_SHIFT event is generated before + * IS_S_START_BUSY_SHIFT event. Hence start slave data send + * from first IS_S_TX_UNDERRUN_SHIFT event. + * + * This means don't send any data from slave when + * IS_S_RD_EVENT_SHIFT event is generated else it will increment + * eeprom or other backend slave driver read pointer twice. + */ + iproc_i2c->tx_underrun = 0; + iproc_i2c->slave_int_mask |= BIT(IE_S_TX_UNDERRUN_SHIFT); + + /* clear IS_S_RD_EVENT_SHIFT interrupt */ + int_clr |= BIT(IS_S_RD_EVENT_SHIFT); + } + + /* clear slave interrupt */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, int_clr); + /* enable slave interrupts */ + iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, iproc_i2c->slave_int_mask); +} + +static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, + u32 status) +{ + u32 val; + u8 value; + + /* + * Slave events in case of master-write, master-write-read and, + * master-read + * + * Master-write : only IS_S_RX_EVENT_SHIFT event + * Master-write-read: both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT + * events + * Master-read : both IS_S_RX_EVENT_SHIFT and IS_S_RD_EVENT_SHIFT + * events or only IS_S_RD_EVENT_SHIFT + */ + if (status & BIT(IS_S_RX_EVENT_SHIFT) || + status & BIT(IS_S_RD_EVENT_SHIFT)) { + /* disable slave interrupts */ + val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); + val &= ~iproc_i2c->slave_int_mask; + iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); + + if (status & BIT(IS_S_RD_EVENT_SHIFT)) + /* Master-write-read request */ + iproc_i2c->slave_rx_only = false; + else + /* Master-write request only */ + iproc_i2c->slave_rx_only = true; + + /* schedule tasklet to read data later */ + tasklet_schedule(&iproc_i2c->slave_rx_tasklet); + + /* clear only IS_S_RX_EVENT_SHIFT interrupt */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, + BIT(IS_S_RX_EVENT_SHIFT)); + } + + if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { + iproc_i2c->tx_underrun++; + if (iproc_i2c->tx_underrun == 1) + /* Start of SMBUS for Master Read */ i2c_slave_event(iproc_i2c->slave, - I2C_SLAVE_WRITE_RECEIVED, &value); - } - } else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { - /* Master read other than start */ - i2c_slave_event(iproc_i2c->slave, - I2C_SLAVE_READ_PROCESSED, &value); + I2C_SLAVE_READ_REQUESTED, + &value); + else + /* Master read other than start */ + i2c_slave_event(iproc_i2c->slave, + I2C_SLAVE_READ_PROCESSED, + &value); iproc_i2c_wr_reg(iproc_i2c, S_TX_OFFSET, value); + /* start transfer */ val = BIT(S_CMD_START_BUSY_SHIFT); iproc_i2c_wr_reg(iproc_i2c, S_CMD_OFFSET, val); + + /* clear interrupt */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, + BIT(IS_S_TX_UNDERRUN_SHIFT)); } - /* Stop */ + /* Stop received from master in case of master read transaction */ if (status & BIT(IS_S_START_BUSY_SHIFT)) { - i2c_slave_event(iproc_i2c->slave, I2C_SLAVE_STOP, &value); /* * Enable interrupt for TX FIFO becomes empty and * less than PKT_LENGTH bytes were output on the SMBUS */ - val = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); - val &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); - iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, val); + iproc_i2c->slave_int_mask &= ~BIT(IE_S_TX_UNDERRUN_SHIFT); + iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, + iproc_i2c->slave_int_mask); + + /* End of SMBUS for Master Read */ + val = BIT(S_TX_WR_STATUS_SHIFT); + iproc_i2c_wr_reg(iproc_i2c, S_TX_OFFSET, val); + + val = BIT(S_CMD_START_BUSY_SHIFT); + iproc_i2c_wr_reg(iproc_i2c, S_CMD_OFFSET, val); + + /* flush TX FIFOs */ + val = iproc_i2c_rd_reg(iproc_i2c, S_FIFO_CTRL_OFFSET); + val |= (BIT(S_FIFO_TX_FLUSH_SHIFT)); + iproc_i2c_wr_reg(iproc_i2c, S_FIFO_CTRL_OFFSET, val); + + i2c_slave_event(iproc_i2c->slave, I2C_SLAVE_STOP, &value); + + /* clear interrupt */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, + BIT(IS_S_START_BUSY_SHIFT)); } - /* clear interrupt status */ - iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, status); + /* check slave transmit status only if slave is transmitting */ + if (!iproc_i2c->slave_rx_only) + bcm_iproc_i2c_check_slave_status(iproc_i2c); - bcm_iproc_i2c_check_slave_status(iproc_i2c); return true; } @@ -500,12 +626,17 @@ static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) { struct bcm_iproc_i2c_dev *iproc_i2c = data; - u32 status = iproc_i2c_rd_reg(iproc_i2c, IS_OFFSET); + u32 slave_status; + u32 status; bool ret; - u32 sl_status = status & ISR_MASK_SLAVE; - if (sl_status) { - ret = bcm_iproc_i2c_slave_isr(iproc_i2c, sl_status); + status = iproc_i2c_rd_reg(iproc_i2c, IS_OFFSET); + /* process only slave interrupt which are enabled */ + slave_status = status & iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET) & + ISR_MASK_SLAVE; + + if (slave_status) { + ret = bcm_iproc_i2c_slave_isr(iproc_i2c, slave_status); if (ret) return IRQ_HANDLED; else @@ -1022,6 +1153,10 @@ return -EAFNOSUPPORT; iproc_i2c->slave = slave; + + tasklet_init(&iproc_i2c->slave_rx_tasklet, slave_rx_tasklet_fn, + (unsigned long)iproc_i2c); + bcm_iproc_i2c_slave_init(iproc_i2c, false); return 0; } @@ -1034,7 +1169,7 @@ if (!iproc_i2c->slave) return -EINVAL; - iproc_i2c->slave = NULL; + disable_irq(iproc_i2c->irq); /* disable all slave interrupts */ tmp = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); @@ -1042,11 +1177,24 @@ IE_S_ALL_INTERRUPT_SHIFT); iproc_i2c_wr_reg(iproc_i2c, IE_OFFSET, tmp); + tasklet_kill(&iproc_i2c->slave_rx_tasklet); + /* Erase the slave address programmed */ tmp = iproc_i2c_rd_reg(iproc_i2c, S_CFG_SMBUS_ADDR_OFFSET); tmp &= ~BIT(S_CFG_EN_NIC_SMB_ADDR3_SHIFT); iproc_i2c_wr_reg(iproc_i2c, S_CFG_SMBUS_ADDR_OFFSET, tmp); + /* flush TX/RX FIFOs */ + tmp = (BIT(S_FIFO_RX_FLUSH_SHIFT) | BIT(S_FIFO_TX_FLUSH_SHIFT)); + iproc_i2c_wr_reg(iproc_i2c, S_FIFO_CTRL_OFFSET, tmp); + + /* clear all pending slave interrupts */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, ISR_MASK_SLAVE); + + iproc_i2c->slave = NULL; + + enable_irq(iproc_i2c->irq); + return 0; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-bcm2835.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-bcm2835.c @@ -23,6 +23,11 @@ #define BCM2835_I2C_FIFO 0x10 #define BCM2835_I2C_DIV 0x14 #define BCM2835_I2C_DEL 0x18 +/* + * 16-bit field for the number of SCL cycles to wait after rising SCL + * before deciding the slave is not responding. 0 disables the + * timeout detection. + */ #define BCM2835_I2C_CLKT 0x1c #define BCM2835_I2C_C_READ BIT(0) @@ -58,6 +63,7 @@ struct i2c_adapter adapter; struct completion completion; struct i2c_msg *curr_msg; + struct clk *bus_clk; int num_msgs; u32 msg_err; u8 *msg_buf; @@ -404,7 +410,6 @@ struct resource *mem, *irq; int ret; struct i2c_adapter *adap; - struct clk *bus_clk; struct clk *mclk; u32 bus_clk_rate; @@ -427,11 +432,11 @@ return PTR_ERR(mclk); } - bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); + i2c_dev->bus_clk = bcm2835_i2c_register_div(&pdev->dev, mclk, i2c_dev); - if (IS_ERR(bus_clk)) { + if (IS_ERR(i2c_dev->bus_clk)) { dev_err(&pdev->dev, "Could not register clock\n"); - return PTR_ERR(bus_clk); + return PTR_ERR(i2c_dev->bus_clk); } ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", @@ -442,13 +447,13 @@ bus_clk_rate = 100000; } - ret = clk_set_rate_exclusive(bus_clk, bus_clk_rate); + ret = clk_set_rate_exclusive(i2c_dev->bus_clk, bus_clk_rate); if (ret < 0) { dev_err(&pdev->dev, "Could not set clock frequency\n"); return ret; } - ret = clk_prepare_enable(bus_clk); + ret = clk_prepare_enable(i2c_dev->bus_clk); if (ret) { dev_err(&pdev->dev, "Couldn't prepare clock"); return ret; @@ -479,6 +484,12 @@ adap->dev.of_node = pdev->dev.of_node; adap->quirks = of_device_get_match_data(&pdev->dev); + /* + * Disable the hardware clock stretching timeout. SMBUS + * specifies a limit for how long the device can stretch the + * clock, but core I2C doesn't. + */ + bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_CLKT, 0); bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); ret = i2c_add_adapter(adap); @@ -491,10 +502,9 @@ static int bcm2835_i2c_remove(struct platform_device *pdev) { struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - struct clk *bus_clk = devm_clk_get(i2c_dev->dev, "div"); - clk_rate_exclusive_put(bus_clk); - clk_disable_unprepare(bus_clk); + clk_rate_exclusive_put(i2c_dev->bus_clk); + clk_disable_unprepare(i2c_dev->bus_clk); free_irq(i2c_dev->irq, i2c_dev); i2c_del_adapter(&i2c_dev->adapter); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-brcmstb.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-brcmstb.c @@ -316,7 +316,7 @@ goto cmd_out; } - if ((CMD_RD || CMD_WR) && + if ((cmd == CMD_RD || cmd == CMD_WR) && bsc_readl(dev, iic_enable) & BSC_IIC_EN_NOACK_MASK) { rc = -EREMOTEIO; dev_dbg(dev->device, "controller received NOACK intr for %s\n", @@ -640,7 +640,7 @@ /* set the data in/out register size for compatible SoCs */ if (of_device_is_compatible(dev->device->of_node, - "brcmstb,brcmper-i2c")) + "brcm,brcmper-i2c")) dev->data_regsz = sizeof(u8); else dev->data_regsz = sizeof(u32); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-cadence.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-cadence.c @@ -198,9 +198,9 @@ */ static irqreturn_t cdns_i2c_isr(int irq, void *ptr) { - unsigned int isr_status, avail_bytes, updatetx; + unsigned int isr_status, avail_bytes; unsigned int bytes_to_send; - bool hold_quirk; + bool updatetx; struct cdns_i2c *id = ptr; /* Signal completion only after everything is updated */ int done_flag = 0; @@ -219,11 +219,7 @@ * Check if transfer size register needs to be updated again for a * large data receive operation. */ - updatetx = 0; - if (id->recv_count > id->curr_recv_count) - updatetx = 1; - - hold_quirk = (id->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; + updatetx = id->recv_count > id->curr_recv_count; /* When receiving, handle data interrupt and completion interrupt */ if (id->p_recv_buf && @@ -246,7 +242,7 @@ id->recv_count--; id->curr_recv_count--; - if (cdns_is_holdquirk(id, hold_quirk)) + if (cdns_is_holdquirk(id, updatetx)) break; } @@ -257,7 +253,7 @@ * maintain transfer size non-zero while performing a large * receive operation. */ - if (cdns_is_holdquirk(id, hold_quirk)) { + if (cdns_is_holdquirk(id, updatetx)) { /* wait while fifo is full */ while (cdns_i2c_readreg(CDNS_I2C_XFER_SIZE_OFFSET) != (id->curr_recv_count - CDNS_I2C_FIFO_DEPTH)) @@ -279,22 +275,6 @@ CDNS_I2C_XFER_SIZE_OFFSET); id->curr_recv_count = id->recv_count; } - } else if (id->recv_count && !hold_quirk && - !id->curr_recv_count) { - - /* Set the slave address in address register*/ - cdns_i2c_writereg(id->p_msg->addr & CDNS_I2C_ADDR_MASK, - CDNS_I2C_ADDR_OFFSET); - - if (id->recv_count > CDNS_I2C_TRANSFER_SIZE) { - cdns_i2c_writereg(CDNS_I2C_TRANSFER_SIZE, - CDNS_I2C_XFER_SIZE_OFFSET); - id->curr_recv_count = CDNS_I2C_TRANSFER_SIZE; - } else { - cdns_i2c_writereg(id->recv_count, - CDNS_I2C_XFER_SIZE_OFFSET); - id->curr_recv_count = id->recv_count; - } } /* Clear hold (if not repeated start) and signal completion */ @@ -368,8 +348,13 @@ ctrl_reg = cdns_i2c_readreg(CDNS_I2C_CR_OFFSET); ctrl_reg |= CDNS_I2C_CR_RW | CDNS_I2C_CR_CLR_FIFO; + /* + * Receive up to I2C_SMBUS_BLOCK_MAX data bytes, plus one message length + * byte, plus one checksum byte if PEC is enabled. p_msg->len will be 2 if + * PEC is enabled, otherwise 1. + */ if (id->p_msg->flags & I2C_M_RECV_LEN) - id->recv_count = I2C_SMBUS_BLOCK_MAX + 1; + id->recv_count = I2C_SMBUS_BLOCK_MAX + id->p_msg->len; id->curr_recv_count = id->recv_count; @@ -377,10 +362,8 @@ * Check for the message size against FIFO depth and set the * 'hold bus' bit if it is greater than FIFO depth. */ - if ((id->recv_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) + if (id->recv_count > CDNS_I2C_FIFO_DEPTH) ctrl_reg |= CDNS_I2C_CR_HOLD; - else - ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); @@ -437,11 +420,8 @@ * Check for the message size against FIFO depth and set the * 'hold bus' bit if it is greater than FIFO depth. */ - if ((id->send_count > CDNS_I2C_FIFO_DEPTH) || id->bus_hold_flag) + if (id->send_count > CDNS_I2C_FIFO_DEPTH) ctrl_reg |= CDNS_I2C_CR_HOLD; - else - ctrl_reg = ctrl_reg & ~CDNS_I2C_CR_HOLD; - cdns_i2c_writereg(ctrl_reg, CDNS_I2C_CR_OFFSET); /* Clear the interrupts in interrupt status register. */ @@ -511,7 +491,7 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, struct i2c_msg *msg, struct i2c_adapter *adap) { - unsigned long time_left; + unsigned long time_left, msg_timeout; u32 reg; id->p_msg = msg; @@ -536,8 +516,16 @@ else cdns_i2c_msend(id); + /* Minimal time to execute this message */ + msg_timeout = msecs_to_jiffies((1000 * msg->len * BITS_PER_BYTE) / id->i2c_clk); + /* Plus some wiggle room */ + msg_timeout += msecs_to_jiffies(500); + + if (msg_timeout < adap->timeout) + msg_timeout = adap->timeout; + /* Wait for the signal of completion */ - time_left = wait_for_completion_timeout(&id->xfer_done, adap->timeout); + time_left = wait_for_completion_timeout(&id->xfer_done, msg_timeout); if (time_left == 0) { cdns_i2c_master_reset(adap); dev_err(id->adap.dev.parent, @@ -552,6 +540,9 @@ if (id->err_status & CDNS_I2C_IXR_ARB_LOST) return -EAGAIN; + if (msg->flags & I2C_M_RECV_LEN) + msg->len += min_t(unsigned int, msg->buf[0], I2C_SMBUS_BLOCK_MAX); + return 0; } @@ -906,7 +897,10 @@ if (IS_ERR(id->membase)) return PTR_ERR(id->membase); - id->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + return ret; + id->irq = ret; id->adap.owner = THIS_MODULE; id->adap.dev.of_node = pdev->dev.of_node; @@ -979,6 +973,7 @@ return 0; err_clk_dis: + clk_notifier_unregister(id->clk, &id->clk_rate_change_nb); clk_disable_unprepare(id->clk); pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-cbus-gpio.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-cbus-gpio.c @@ -195,8 +195,9 @@ } static const struct i2c_algorithm cbus_i2c_algo = { - .smbus_xfer = cbus_i2c_smbus_xfer, - .functionality = cbus_i2c_func, + .smbus_xfer = cbus_i2c_smbus_xfer, + .smbus_xfer_atomic = cbus_i2c_smbus_xfer, + .functionality = cbus_i2c_func, }; static int cbus_i2c_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-cpm.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-cpm.c @@ -65,6 +65,9 @@ char res1[4]; /* Reserved */ ushort rpbase; /* Relocation pointer */ char res2[2]; /* Reserved */ + /* The following elements are only for CPM2 */ + char res3[4]; /* Reserved */ + uint sdmatmp; /* Internal */ }; #define I2COM_START 0x80 --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-designware-common.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-designware-common.c @@ -253,9 +253,6 @@ { int ret; - if (IS_ERR(dev->clk)) - return PTR_ERR(dev->clk); - if (prepare) { /* Optional interface clock */ ret = clk_prepare_enable(dev->pclk); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-designware-pcidrv.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-designware-pcidrv.c @@ -37,10 +37,10 @@ }; struct dw_scl_sda_cfg { - u32 ss_hcnt; - u32 fs_hcnt; - u32 ss_lcnt; - u32 fs_lcnt; + u16 ss_hcnt; + u16 fs_hcnt; + u16 ss_lcnt; + u16 fs_lcnt; u32 sda_hold; }; @@ -313,6 +313,7 @@ pm_runtime_get_noresume(&pdev->dev); i2c_del_adapter(&dev->adapter); + devm_free_irq(&pdev->dev, dev->irq, dev); pci_free_irq_vectors(pdev); } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-designware-platdrv.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-designware-platdrv.c @@ -349,8 +349,17 @@ goto exit_reset; } - dev->clk = devm_clk_get(&pdev->dev, NULL); - if (!i2c_dw_prepare_clk(dev, true)) { + dev->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(dev->clk)) { + ret = PTR_ERR(dev->clk); + goto exit_reset; + } + + ret = i2c_dw_prepare_clk(dev, true); + if (ret) + goto exit_reset; + + if (dev->clk) { u64 clk_khz; dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; @@ -370,10 +379,16 @@ adap->dev.of_node = pdev->dev.of_node; adap->nr = -1; - dev_pm_set_driver_flags(&pdev->dev, - DPM_FLAG_SMART_PREPARE | - DPM_FLAG_SMART_SUSPEND | - DPM_FLAG_LEAVE_SUSPENDED); + if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { + dev_pm_set_driver_flags(&pdev->dev, + DPM_FLAG_SMART_PREPARE | + DPM_FLAG_LEAVE_SUSPENDED); + } else { + dev_pm_set_driver_flags(&pdev->dev, + DPM_FLAG_SMART_PREPARE | + DPM_FLAG_SMART_SUSPEND | + DPM_FLAG_LEAVE_SUSPENDED); + } /* The code below assumes runtime PM to be disabled. */ WARN_ON(pm_runtime_enabled(&pdev->dev)); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-eg20t.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-eg20t.c @@ -180,6 +180,7 @@ { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7831_I2C), 1, }, {0,} }; +MODULE_DEVICE_TABLE(pci, pch_pcidev_id); static irqreturn_t pch_i2c_handler(int irq, void *pData); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-emev2.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-emev2.c @@ -397,7 +397,10 @@ em_i2c_reset(&priv->adap); - priv->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto err_clk; + priv->irq = ret; ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0, "em_i2c", priv); if (ret) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-fsi.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-fsi.c @@ -98,7 +98,7 @@ #define I2C_STAT_DAT_REQ BIT(25) #define I2C_STAT_CMD_COMP BIT(24) #define I2C_STAT_STOP_ERR BIT(23) -#define I2C_STAT_MAX_PORT GENMASK(19, 16) +#define I2C_STAT_MAX_PORT GENMASK(22, 16) #define I2C_STAT_ANY_INT BIT(15) #define I2C_STAT_SCL_IN BIT(11) #define I2C_STAT_SDA_IN BIT(10) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-gpio.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-gpio.c @@ -348,7 +348,7 @@ if (ret == -ENOENT) retdesc = ERR_PTR(-EPROBE_DEFER); - if (ret != -EPROBE_DEFER) + if (PTR_ERR(retdesc) != -EPROBE_DEFER) dev_err(dev, "error trying to get descriptor: %d\n", ret); return retdesc; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-highlander.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-highlander.c @@ -379,7 +379,7 @@ platform_set_drvdata(pdev, dev); dev->irq = platform_get_irq(pdev, 0); - if (iic_force_poll) + if (dev->irq < 0 || iic_force_poll) dev->irq = 0; if (dev->irq) { --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-hix5hd2.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-hix5hd2.c @@ -477,6 +477,7 @@ i2c_del_adapter(&priv->adap); pm_runtime_disable(priv->dev); pm_runtime_set_suspended(priv->dev); + clk_disable_unprepare(priv->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-i801.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-i801.c @@ -64,6 +64,7 @@ * Cedar Fork (PCH) 0x18df 32 hard yes yes yes * Ice Lake-LP (PCH) 0x34a3 32 hard yes yes yes * Comet Lake (PCH) 0x02a3 32 hard yes yes yes + * Comet Lake-H (PCH) 0x06a3 32 hard yes yes yes * Elkhart Lake (PCH) 0x4b23 32 hard yes yes yes * Tiger Lake-LP (PCH) 0xa0a3 32 hard yes yes yes * @@ -129,11 +130,6 @@ #define TCOBASE 0x050 #define TCOCTL 0x054 -#define ACPIBASE 0x040 -#define ACPIBASE_SMI_OFF 0x030 -#define ACPICTRL 0x044 -#define ACPICTRL_EN 0x080 - #define SBREG_BAR 0x10 #define SBREG_SMBCTRL 0xc6000c #define SBREG_SMBCTRL_DNV 0xcf000c @@ -205,6 +201,7 @@ /* Older devices have their ID defined in */ #define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3 +#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3 #define PCI_DEVICE_ID_INTEL_BAYTRAIL_SMBUS 0x0f12 #define PCI_DEVICE_ID_INTEL_CDF_SMBUS 0x18df #define PCI_DEVICE_ID_INTEL_DNV_SMBUS 0x19df @@ -384,11 +381,9 @@ dev_err(&priv->pci_dev->dev, "Transaction timeout\n"); /* try to stop the current command */ dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n"); - outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL, - SMBHSTCNT(priv)); + outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv)); usleep_range(1000, 2000); - outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL), - SMBHSTCNT(priv)); + outb_p(0, SMBHSTCNT(priv)); /* Check if it worked */ status = inb_p(SMBHSTSTS(priv)); @@ -535,12 +530,13 @@ return -EOPNOTSUPP; } - inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ + /* Set block buffer mode */ + outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv)); - /* Use 32-byte buffer to process this transaction */ if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; outb_p(len, SMBHSTDAT0(priv)); + inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ for (i = 0; i < len; i++) outb_p(data->block[i+1], SMBBLKDAT(priv)); } @@ -556,6 +552,7 @@ return -EPROTO; data->block[0] = len; + inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */ for (i = 0; i < len; i++) data->block[i + 1] = inb_p(SMBBLKDAT(priv)); } @@ -730,15 +727,11 @@ return i801_check_post(priv, status); } - for (i = 1; i <= len; i++) { - if (i == len && read_write == I2C_SMBUS_READ) - smbcmd |= SMBHSTCNT_LAST_BYTE; - outb_p(smbcmd, SMBHSTCNT(priv)); - - if (i == 1) - outb_p(inb(SMBHSTCNT(priv)) | SMBHSTCNT_START, - SMBHSTCNT(priv)); + if (len == 1 && read_write == I2C_SMBUS_READ) + smbcmd |= SMBHSTCNT_LAST_BYTE; + outb_p(smbcmd | SMBHSTCNT_START, SMBHSTCNT(priv)); + for (i = 1; i <= len; i++) { status = i801_wait_byte_done(priv); if (status) goto exit; @@ -761,9 +754,12 @@ data->block[0] = len; } - /* Retrieve/store value in SMBBLKDAT */ - if (read_write == I2C_SMBUS_READ) + if (read_write == I2C_SMBUS_READ) { data->block[i] = inb_p(SMBBLKDAT(priv)); + if (i == len - 1) + outb_p(smbcmd | SMBHSTCNT_LAST_BYTE, SMBHSTCNT(priv)); + } + if (read_write == I2C_SMBUS_WRITE && i+1 <= len) outb_p(data->block[i+1], SMBBLKDAT(priv)); @@ -776,14 +772,6 @@ return i801_check_post(priv, status); } -static int i801_set_block_buffer_mode(struct i801_priv *priv) -{ - outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv)); - if ((inb_p(SMBAUXCTL(priv)) & SMBAUXCTL_E32B) == 0) - return -EIO; - return 0; -} - /* Block transaction function */ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data *data, char read_write, @@ -792,6 +780,11 @@ int result = 0; unsigned char hostc; + if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA) + data->block[0] = I2C_SMBUS_BLOCK_MAX; + else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) + return -EPROTO; + if (command == I2C_SMBUS_I2C_BLOCK_DATA) { if (read_write == I2C_SMBUS_WRITE) { /* set I2C_EN bit in configuration register */ @@ -805,22 +798,11 @@ } } - if (read_write == I2C_SMBUS_WRITE - || command == I2C_SMBUS_I2C_BLOCK_DATA) { - if (data->block[0] < 1) - data->block[0] = 1; - if (data->block[0] > I2C_SMBUS_BLOCK_MAX) - data->block[0] = I2C_SMBUS_BLOCK_MAX; - } else { - data->block[0] = 32; /* max for SMBus block reads */ - } - /* Experience has shown that the block buffer can only be used for SMBus (not I2C) block transactions, even though the datasheet doesn't mention this limitation. */ - if ((priv->features & FEATURE_BLOCK_BUFFER) - && command != I2C_SMBUS_I2C_BLOCK_DATA - && i801_set_block_buffer_mode(priv) == 0) + if ((priv->features & FEATURE_BLOCK_BUFFER) && + command != I2C_SMBUS_I2C_BLOCK_DATA) result = i801_block_transaction_by_block(priv, data, read_write, command, hwpec); @@ -1069,6 +1051,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CANNONLAKE_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) }, { 0, } @@ -1077,7 +1060,7 @@ MODULE_DEVICE_TABLE(pci, i801_ids); #if defined CONFIG_X86 && defined CONFIG_DMI -static unsigned char apanel_addr; +static unsigned char apanel_addr __ro_after_init; /* Scan the system ROM for the signature "FJKEYINF" */ static __init const void __iomem *bios_signature(const void __iomem *bios) @@ -1265,6 +1248,7 @@ * Additional individual entries were added after verification. */ { "Vostro V131", 0x1d }, + { "Vostro 5568", 0x29 }, }; static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv) @@ -1429,7 +1413,7 @@ /* Register GPIO descriptor lookup table */ lookup = devm_kzalloc(dev, - struct_size(lookup, table, mux_config->n_gpios), + struct_size(lookup, table, mux_config->n_gpios + 1), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -1544,7 +1528,7 @@ pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); spin_unlock(&p2sb_spinlock); - res = &tco_res[ICH_RES_MEM_OFF]; + res = &tco_res[1]; if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; else @@ -1554,7 +1538,7 @@ res->flags = IORESOURCE_MEM; return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, - tco_res, 3, &spt_tco_platform_data, + tco_res, 2, &spt_tco_platform_data, sizeof(spt_tco_platform_data)); } @@ -1567,17 +1551,16 @@ i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, struct resource *tco_res) { - return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, - tco_res, 2, &cnl_tco_platform_data, - sizeof(cnl_tco_platform_data)); + return platform_device_register_resndata(&pci_dev->dev, + "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, + sizeof(cnl_tco_platform_data)); } static void i801_add_tco(struct i801_priv *priv) { - u32 base_addr, tco_base, tco_ctl, ctrl_val; struct pci_dev *pci_dev = priv->pci_dev; - struct resource tco_res[3], *res; - unsigned int devfn; + struct resource tco_res[2], *res; + u32 tco_base, tco_ctl; /* If we have ACPI based watchdog use that instead */ if (acpi_has_watchdog()) @@ -1592,30 +1575,15 @@ return; memset(tco_res, 0, sizeof(tco_res)); - - res = &tco_res[ICH_RES_IO_TCO]; - res->start = tco_base & ~1; - res->end = res->start + 32 - 1; - res->flags = IORESOURCE_IO; - /* - * Power Management registers. + * Always populate the main iTCO IO resource here. The second entry + * for NO_REBOOT MMIO is filled by the SPT specific function. */ - devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2); - pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr); - - res = &tco_res[ICH_RES_IO_SMI]; - res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF; - res->end = res->start + 3; + res = &tco_res[0]; + res->start = tco_base & ~1; + res->end = res->start + 32 - 1; res->flags = IORESOURCE_IO; - /* - * Enable the ACPI I/O space. - */ - pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val); - ctrl_val |= ACPICTRL_EN; - pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val); - if (priv->features & FEATURE_TCO_CNL) priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); else @@ -1709,6 +1677,16 @@ static inline void i801_acpi_remove(struct i801_priv *priv) { } #endif +static unsigned char i801_setup_hstcfg(struct i801_priv *priv) +{ + unsigned char hstcfg = priv->original_hstcfg; + + hstcfg &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ + hstcfg |= SMBHSTCFG_HST_EN; + pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hstcfg); + return hstcfg; +} + static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) { unsigned char temp; @@ -1750,6 +1728,7 @@ case PCI_DEVICE_ID_INTEL_CDF_SMBUS: case PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS: case PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS: + case PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS: case PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS: case PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS: priv->features |= FEATURE_BLOCK_PROC; @@ -1825,14 +1804,10 @@ return err; } - pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &temp); - priv->original_hstcfg = temp; - temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ - if (!(temp & SMBHSTCFG_HST_EN)) { + pci_read_config_byte(priv->pci_dev, SMBHSTCFG, &priv->original_hstcfg); + temp = i801_setup_hstcfg(priv); + if (!(priv->original_hstcfg & SMBHSTCFG_HST_EN)) dev_info(&dev->dev, "Enabling SMBus device\n"); - temp |= SMBHSTCFG_HST_EN; - } - pci_write_config_byte(priv->pci_dev, SMBHSTCFG, temp); if (temp & SMBHSTCFG_SMB_SMI_EN) { dev_dbg(&dev->dev, "SMBus using interrupt SMI#\n"); @@ -1890,10 +1865,18 @@ i801_add_tco(priv); + /* + * adapter.name is used by platform code to find the main I801 adapter + * to instantiante i2c_clients, do not change. + */ snprintf(priv->adapter.name, sizeof(priv->adapter.name), - "SMBus I801 adapter at %04lx", priv->smba); + "SMBus %s adapter at %04lx", + (priv->features & FEATURE_IDF) ? "I801 IDF" : "I801", + priv->smba); + err = i2c_add_adapter(&priv->adapter); if (err) { + platform_device_unregister(priv->tco_pdev); i801_acpi_remove(priv); return err; } @@ -1906,6 +1889,7 @@ pci_set_drvdata(dev, priv); + dev_pm_set_driver_flags(&dev->dev, DPM_FLAG_NEVER_SKIP); pm_runtime_set_autosuspend_delay(&dev->dev, 1000); pm_runtime_use_autosuspend(&dev->dev); pm_runtime_put_autosuspend(&dev->dev); @@ -1958,6 +1942,7 @@ { struct i801_priv *priv = dev_get_drvdata(dev); + i801_setup_hstcfg(priv); i801_enable_host_notify(&priv->adapter); return 0; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-icy.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-icy.c @@ -43,6 +43,7 @@ #include #include +#include #include #include --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-img-scb.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-img-scb.c @@ -1057,7 +1057,7 @@ atomic = true; } - ret = pm_runtime_get_sync(adap->dev.parent); + ret = pm_runtime_resume_and_get(adap->dev.parent); if (ret < 0) return ret; @@ -1158,7 +1158,7 @@ u32 rev; int ret; - ret = pm_runtime_get_sync(i2c->adap.dev.parent); + ret = pm_runtime_resume_and_get(i2c->adap.dev.parent); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-imx-lpi2c.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -105,6 +105,7 @@ __u8 *rx_buf; __u8 *tx_buf; struct completion complete; + unsigned long rate_per; unsigned int msglen; unsigned int delivered; unsigned int block_data; @@ -206,14 +207,15 @@ /* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */ static int lpi2c_imx_config(struct lpi2c_imx_struct *lpi2c_imx) { - u8 prescale, filt, sethold, clkhi, clklo, datavd; - unsigned int clk_rate, clk_cycle; + u8 prescale, filt, sethold, datavd; + unsigned int clk_rate, clk_cycle, clkhi, clklo; enum lpi2c_imx_pincfg pincfg; unsigned int temp; lpi2c_imx_set_mode(lpi2c_imx); - clk_rate = clk_get_rate(lpi2c_imx->clk); + clk_rate = lpi2c_imx->rate_per; + if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST) filt = 0; else @@ -265,7 +267,7 @@ unsigned int temp; int ret; - ret = pm_runtime_get_sync(lpi2c_imx->adapter.dev.parent); + ret = pm_runtime_resume_and_get(lpi2c_imx->adapter.dev.parent); if (ret < 0) return ret; @@ -468,6 +470,8 @@ if (num == 1 && msgs[0].len == 0) goto stop; + lpi2c_imx->rx_buf = NULL; + lpi2c_imx->tx_buf = NULL; lpi2c_imx->delivered = 0; lpi2c_imx->msglen = msgs[i].len; init_completion(&lpi2c_imx->complete); @@ -508,10 +512,14 @@ static irqreturn_t lpi2c_imx_isr(int irq, void *dev_id) { struct lpi2c_imx_struct *lpi2c_imx = dev_id; + unsigned int enabled; unsigned int temp; + enabled = readl(lpi2c_imx->base + LPI2C_MIER); + lpi2c_imx_intctrl(lpi2c_imx, 0); temp = readl(lpi2c_imx->base + LPI2C_MSR); + temp &= enabled; if (temp & MSR_RDF) lpi2c_imx_read_rxfifo(lpi2c_imx); @@ -596,6 +604,20 @@ return ret; } + /* + * Lock the parent clock rate to avoid getting parent clock upon + * each transfer + */ + ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clk); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "can't lock I2C peripheral clock rate\n"); + + lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clk); + if (!lpi2c_imx->rate_per) + return dev_err_probe(&pdev->dev, -EINVAL, + "can't get I2C peripheral clock rate\n"); + pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-imx.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-imx.c @@ -414,6 +414,19 @@ dma->chan_using = NULL; } +static void i2c_imx_clear_irq(struct imx_i2c_struct *i2c_imx, unsigned int bits) +{ + unsigned int temp; + + /* + * i2sr_clr_opcode is the value to clear all interrupts. Here we want to + * clear only , so we write ~i2sr_clr_opcode with just + * toggled. This is required because i.MX needs W0C and Vybrid uses W1C. + */ + temp = ~i2c_imx->hwdata->i2sr_clr_opcode ^ bits; + imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); +} + static int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) { unsigned long orig_jiffies = jiffies; @@ -426,8 +439,7 @@ /* check for arbitration lost */ if (temp & I2SR_IAL) { - temp &= ~I2SR_IAL; - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); + i2c_imx_clear_irq(i2c_imx, I2SR_IAL); return -EAGAIN; } @@ -458,6 +470,16 @@ dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__); return -ETIMEDOUT; } + + /* check for arbitration lost */ + if (i2c_imx->i2csr & I2SR_IAL) { + dev_dbg(&i2c_imx->adapter.dev, "<%s> Arbitration lost\n", __func__); + i2c_imx_clear_irq(i2c_imx, I2SR_IAL); + + i2c_imx->i2csr = 0; + return -EAGAIN; + } + dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__); i2c_imx->i2csr = 0; return 0; @@ -567,6 +589,8 @@ /* Stop I2C transaction */ dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + if (!(temp & I2CR_MSTA)) + i2c_imx->stopped = 1; temp &= ~(I2CR_MSTA | I2CR_MTX); if (i2c_imx->dma) temp &= ~I2CR_DMAEN; @@ -597,9 +621,7 @@ if (temp & I2SR_IIF) { /* save status register */ i2c_imx->i2csr = temp; - temp &= ~I2SR_IIF; - temp |= (i2c_imx->hwdata->i2sr_clr_opcode & I2SR_IIF); - imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2SR); + i2c_imx_clear_irq(i2c_imx, I2SR_IIF); wake_up(&i2c_imx->queue); return IRQ_HANDLED; } @@ -732,9 +754,12 @@ */ dev_dbg(dev, "<%s> clear MSTA\n", __func__); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + if (!(temp & I2CR_MSTA)) + i2c_imx->stopped = 1; temp &= ~(I2CR_MSTA | I2CR_MTX); imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); - i2c_imx_bus_busy(i2c_imx, 0); + if (!i2c_imx->stopped) + i2c_imx_bus_busy(i2c_imx, 0); } else { /* * For i2c master receiver repeat restart operation like: @@ -857,9 +882,12 @@ dev_dbg(&i2c_imx->adapter.dev, "<%s> clear MSTA\n", __func__); temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); + if (!(temp & I2CR_MSTA)) + i2c_imx->stopped = 1; temp &= ~(I2CR_MSTA | I2CR_MTX); imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); - i2c_imx_bus_busy(i2c_imx, 0); + if (!i2c_imx->stopped) + i2c_imx_bus_busy(i2c_imx, 0); } else { /* * For i2c master receiver repeat restart operation like: @@ -1112,14 +1140,6 @@ return ret; } - /* Request IRQ */ - ret = devm_request_irq(&pdev->dev, irq, i2c_imx_isr, IRQF_SHARED, - pdev->name, i2c_imx); - if (ret) { - dev_err(&pdev->dev, "can't claim irq %d\n", irq); - goto clk_disable; - } - /* Init queue */ init_waitqueue_head(&i2c_imx->queue); @@ -1138,6 +1158,14 @@ if (ret < 0) goto rpm_disable; + /* Request IRQ */ + ret = request_threaded_irq(irq, i2c_imx_isr, NULL, IRQF_SHARED, + pdev->name, i2c_imx); + if (ret) { + dev_err(&pdev->dev, "can't claim irq %d\n", irq); + goto rpm_disable; + } + /* Set up clock divider */ i2c_imx->bitrate = IMX_I2C_BIT_RATE; ret = of_property_read_u32(pdev->dev.of_node, @@ -1180,13 +1208,12 @@ clk_notifier_unregister: clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb); + free_irq(irq, i2c_imx); rpm_disable: pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); - -clk_disable: clk_disable_unprepare(i2c_imx->clk); return ret; } @@ -1194,7 +1221,7 @@ static int i2c_imx_remove(struct platform_device *pdev) { struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev); - int ret; + int irq, ret; ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) @@ -1214,6 +1241,9 @@ imx_i2c_write_reg(0, i2c_imx, IMX_I2C_I2SR); clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb); + irq = platform_get_irq(pdev, 0); + if (irq >= 0) + free_irq(irq, i2c_imx); clk_disable_unprepare(i2c_imx->clk); pm_runtime_put_noidle(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-iop3xx.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-iop3xx.c @@ -433,13 +433,17 @@ adapter_data->gpio_scl = devm_gpiod_get_optional(&pdev->dev, "scl", GPIOD_ASIS); - if (IS_ERR(adapter_data->gpio_scl)) - return PTR_ERR(adapter_data->gpio_scl); + if (IS_ERR(adapter_data->gpio_scl)) { + ret = PTR_ERR(adapter_data->gpio_scl); + goto free_both; + } adapter_data->gpio_sda = devm_gpiod_get_optional(&pdev->dev, "sda", GPIOD_ASIS); - if (IS_ERR(adapter_data->gpio_sda)) - return PTR_ERR(adapter_data->gpio_sda); + if (IS_ERR(adapter_data->gpio_sda)) { + ret = PTR_ERR(adapter_data->gpio_sda); + goto free_both; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -463,16 +467,14 @@ irq = platform_get_irq(pdev, 0); if (irq < 0) { - ret = -ENXIO; + ret = irq; goto unmap; } ret = request_irq(irq, iop3xx_i2c_irq_handler, 0, pdev->name, adapter_data); - if (ret) { - ret = -EIO; + if (ret) goto unmap; - } memcpy(new_adapter->name, pdev->name, strlen(pdev->name)); new_adapter->owner = THIS_MODULE; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-isch.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-isch.c @@ -99,8 +99,7 @@ if (retries > MAX_RETRIES) { dev_err(&sch_adapter.dev, "SMBus Timeout!\n"); result = -ETIMEDOUT; - } - if (temp & 0x04) { + } else if (temp & 0x04) { result = -EIO; dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n"); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-ismt.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-ismt.c @@ -81,6 +81,7 @@ #define ISMT_DESC_ENTRIES 2 /* number of descriptor entries */ #define ISMT_MAX_RETRIES 3 /* number of SMBus retries to attempt */ +#define ISMT_LOG_ENTRIES 3 /* number of interrupt cause log entries */ /* Hardware Descriptor Constants - Control Field */ #define ISMT_DESC_CWRL 0x01 /* Command/Write Length */ @@ -174,6 +175,8 @@ u8 head; /* ring buffer head pointer */ struct completion cmp; /* interrupt completion */ u8 buffer[I2C_SMBUS_BLOCK_MAX + 16]; /* temp R/W data buffer */ + dma_addr_t log_dma; + u32 *log; }; /** @@ -408,6 +411,9 @@ memset(desc, 0, sizeof(struct ismt_desc)); desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write); + /* Always clear the log entries */ + memset(priv->log, 0, ISMT_LOG_ENTRIES * sizeof(u32)); + /* Initialize common control bits */ if (likely(pci_dev_msi_enabled(priv->pci_dev))) desc->control = ISMT_DESC_INT | ISMT_DESC_FAIR; @@ -500,6 +506,9 @@ if (read_write == I2C_SMBUS_WRITE) { /* Block Write */ dev_dbg(dev, "I2C_SMBUS_BLOCK_DATA: WRITE\n"); + if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + dma_size = data->block[0] + 1; dma_direction = DMA_TO_DEVICE; desc->wr_len_cmd = dma_size; @@ -697,6 +706,8 @@ /* initialize the Master Descriptor Base Address (MDBA) */ writeq(priv->io_rng_dma, priv->smba + ISMT_MSTR_MDBA); + writeq(priv->log_dma, priv->smba + ISMT_GR_SMTICL); + /* initialize the Master Control Register (MCTRL) */ writel(ISMT_MCTRL_MEIE, priv->smba + ISMT_MSTR_MCTRL); @@ -784,6 +795,12 @@ priv->head = 0; init_completion(&priv->cmp); + priv->log = dmam_alloc_coherent(&priv->pci_dev->dev, + ISMT_LOG_ENTRIES * sizeof(u32), + &priv->log_dma, GFP_KERNEL); + if (!priv->log) + return -ENOMEM; + return 0; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-jz4780.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-jz4780.c @@ -73,25 +73,6 @@ #define JZ4780_I2C_STA_TFNF BIT(1) #define JZ4780_I2C_STA_ACT BIT(0) -static const char * const jz4780_i2c_abrt_src[] = { - "ABRT_7B_ADDR_NOACK", - "ABRT_10ADDR1_NOACK", - "ABRT_10ADDR2_NOACK", - "ABRT_XDATA_NOACK", - "ABRT_GCALL_NOACK", - "ABRT_GCALL_READ", - "ABRT_HS_ACKD", - "SBYTE_ACKDET", - "ABRT_HS_NORSTRT", - "SBYTE_NORSTRT", - "ABRT_10B_RD_NORSTRT", - "ABRT_MASTER_DIS", - "ARB_LOST", - "SLVFLUSH_TXFIFO", - "SLV_ARBLOST", - "SLVRD_INTX", -}; - #define JZ4780_I2C_INTST_IGC BIT(11) #define JZ4780_I2C_INTST_ISTT BIT(10) #define JZ4780_I2C_INTST_ISTP BIT(9) @@ -529,21 +510,8 @@ static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src) { - int i; - - dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src); - dev_err(&i2c->adap.dev, "device addr=%x\n", - jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)); - dev_err(&i2c->adap.dev, "send cmd count:%d %d\n", - i2c->cmd, i2c->cmd_buf[i2c->cmd]); - dev_err(&i2c->adap.dev, "receive data count:%d %d\n", - i2c->cmd, i2c->data_buf[i2c->cmd]); - - for (i = 0; i < 16; i++) { - if (src & BIT(i)) - dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n", - i, jz4780_i2c_abrt_src[i]); - } + dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n", + src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]); } static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c, @@ -783,7 +751,10 @@ jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0x0); - i2c->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto err; + i2c->irq = ret; ret = devm_request_irq(&pdev->dev, i2c->irq, jz4780_i2c_irq, 0, dev_name(&pdev->dev), i2c); if (ret) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-meson.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-meson.c @@ -5,6 +5,7 @@ * Copyright (C) 2014 Beniamino Galvani */ +#include #include #include #include @@ -32,12 +33,17 @@ #define REG_CTRL_ACK_IGNORE BIT(1) #define REG_CTRL_STATUS BIT(2) #define REG_CTRL_ERROR BIT(3) -#define REG_CTRL_CLKDIV_SHIFT 12 -#define REG_CTRL_CLKDIV_MASK GENMASK(21, 12) -#define REG_CTRL_CLKDIVEXT_SHIFT 28 -#define REG_CTRL_CLKDIVEXT_MASK GENMASK(29, 28) +#define REG_CTRL_CLKDIV GENMASK(21, 12) +#define REG_CTRL_CLKDIVEXT GENMASK(29, 28) + +#define REG_SLV_ADDR GENMASK(7, 0) +#define REG_SLV_SDA_FILTER GENMASK(10, 8) +#define REG_SLV_SCL_FILTER GENMASK(13, 11) +#define REG_SLV_SCL_LOW GENMASK(27, 16) +#define REG_SLV_SCL_LOW_EN BIT(28) #define I2C_TIMEOUT_MS 500 +#define FILTER_DELAY 15 enum { TOKEN_END = 0, @@ -132,19 +138,24 @@ unsigned long clk_rate = clk_get_rate(i2c->clk); unsigned int div; - div = DIV_ROUND_UP(clk_rate, freq * i2c->data->div_factor); + div = DIV_ROUND_UP(clk_rate, freq); + div -= FILTER_DELAY; + div = DIV_ROUND_UP(div, i2c->data->div_factor); /* clock divider has 12 bits */ - if (div >= (1 << 12)) { + if (div > GENMASK(11, 0)) { dev_err(i2c->dev, "requested bus frequency too low\n"); - div = (1 << 12) - 1; + div = GENMASK(11, 0); } - meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV_MASK, - (div & GENMASK(9, 0)) << REG_CTRL_CLKDIV_SHIFT); + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIV, + FIELD_PREP(REG_CTRL_CLKDIV, div & GENMASK(9, 0))); + + meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT, + FIELD_PREP(REG_CTRL_CLKDIVEXT, div >> 10)); - meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_CLKDIVEXT_MASK, - (div >> 10) << REG_CTRL_CLKDIVEXT_SHIFT); + /* Disable HIGH/LOW mode */ + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_SCL_LOW_EN, 0); dev_dbg(i2c->dev, "%s: clk %lu, freq %u, div %u\n", __func__, clk_rate, freq, div); @@ -273,7 +284,10 @@ token = (msg->flags & I2C_M_RD) ? TOKEN_SLAVE_ADDR_READ : TOKEN_SLAVE_ADDR_WRITE; - writel(msg->addr << 1, i2c->regs + REG_SLAVE_ADDR); + + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, REG_SLV_ADDR, + FIELD_PREP(REG_SLV_ADDR, msg->addr << 1)); + meson_i2c_add_token(i2c, TOKEN_START); meson_i2c_add_token(i2c, token); } @@ -432,6 +446,10 @@ return ret; } + /* Disable filtering */ + meson_i2c_set_mask(i2c, REG_SLAVE_ADDR, + REG_SLV_SDA_FILTER | REG_SLV_SCL_FILTER, 0); + meson_i2c_set_clk_div(i2c, timings.bus_freq_hz); return 0; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-mlxcpld.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-mlxcpld.c @@ -337,9 +337,9 @@ if (priv->smbus_block && (val & MLXCPLD_I2C_SMBUS_BLK_BIT)) { mlxcpld_i2c_read_comm(priv, MLXCPLD_LPCI2C_NUM_DAT_REG, &datalen, 1); - if (unlikely(datalen > (I2C_SMBUS_BLOCK_MAX + 1))) { + if (unlikely(datalen > I2C_SMBUS_BLOCK_MAX)) { dev_err(priv->dev, "Incorrect smbus block read message len\n"); - return -E2BIG; + return -EPROTO; } } else { datalen = priv->xfer.data_len; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-mpc.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-mpc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #define CCR_MTX 0x10 #define CCR_TXAK 0x08 #define CCR_RSTA 0x04 +#define CCR_RSVD 0x02 #define CSR_MCF 0x80 #define CSR_MAAS 0x40 @@ -70,6 +72,7 @@ u8 fdr, dfsrr; #endif struct clk *clk_per; + bool has_errata_A004447; }; struct mpc_i2c_divider { @@ -102,23 +105,30 @@ /* Sometimes 9th clock pulse isn't generated, and slave doesn't release * the bus, because it wants to send ACK. * Following sequence of enabling/disabling and sending start/stop generates - * the 9 pulses, so it's all OK. + * the 9 pulses, each with a START then ending with STOP, so it's all OK. */ static void mpc_i2c_fixup(struct mpc_i2c *i2c) { int k; - u32 delay_val = 1000000 / i2c->real_clk + 1; - - if (delay_val < 2) - delay_val = 2; + unsigned long flags; for (k = 9; k; k--) { writeccr(i2c, 0); - writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); + writeb(0, i2c->base + MPC_I2C_SR); /* clear any status bits */ + writeccr(i2c, CCR_MEN | CCR_MSTA); /* START */ + readb(i2c->base + MPC_I2C_DR); /* init xfer */ + udelay(15); /* let it hit the bus */ + local_irq_save(flags); /* should not be delayed further */ + writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSTA); /* delay SDA */ readb(i2c->base + MPC_I2C_DR); - writeccr(i2c, CCR_MEN); - udelay(delay_val << 1); - } + if (k != 1) + udelay(5); + local_irq_restore(flags); + } + writeccr(i2c, CCR_MEN); /* Initiate STOP */ + readb(i2c->base + MPC_I2C_DR); + udelay(15); /* Let STOP propagate */ + writeccr(i2c, 0); } static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) @@ -176,6 +186,75 @@ return 0; } +static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) +{ + void __iomem *addr = i2c->base + MPC_I2C_SR; + u8 val; + + return readb_poll_timeout(addr, val, val & mask, 0, 100); +} + +/* + * Workaround for Erratum A004447. From the P2040CE Rev Q + * + * 1. Set up the frequency divider and sampling rate. + * 2. I2CCR - a0h + * 3. Poll for I2CSR[MBB] to get set. + * 4. If I2CSR[MAL] is set (an indication that SDA is stuck low), then go to + * step 5. If MAL is not set, then go to step 13. + * 5. I2CCR - 00h + * 6. I2CCR - 22h + * 7. I2CCR - a2h + * 8. Poll for I2CSR[MBB] to get set. + * 9. Issue read to I2CDR. + * 10. Poll for I2CSR[MIF] to be set. + * 11. I2CCR - 82h + * 12. Workaround complete. Skip the next steps. + * 13. Issue read to I2CDR. + * 14. Poll for I2CSR[MIF] to be set. + * 15. I2CCR - 80h + */ +static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c) +{ + int ret; + u32 val; + + writeccr(i2c, CCR_MEN | CCR_MSTA); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + + val = readb(i2c->base + MPC_I2C_SR); + + if (val & CSR_MAL) { + writeccr(i2c, 0x00); + writeccr(i2c, CCR_MSTA | CCR_RSVD); + writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN | CCR_RSVD); + } else { + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN); + } +} + #if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x) static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, @@ -586,7 +665,7 @@ if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -622,7 +701,7 @@ if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -637,6 +716,18 @@ | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL; } +static int fsl_i2c_bus_recovery(struct i2c_adapter *adap) +{ + struct mpc_i2c *i2c = i2c_get_adapdata(adap); + + if (i2c->has_errata_A004447) + mpc_i2c_fixup_A004447(i2c); + else + mpc_i2c_fixup(i2c); + + return 0; +} + static const struct i2c_algorithm mpc_algo = { .master_xfer = mpc_xfer, .functionality = mpc_functionality, @@ -648,6 +739,10 @@ .timeout = HZ, }; +static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { + .recover_bus = fsl_i2c_bus_recovery, +}; + static const struct of_device_id mpc_i2c_of_match[]; static int fsl_i2c_probe(struct platform_device *op) { @@ -732,6 +827,8 @@ dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); platform_set_drvdata(op, i2c); + if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) + i2c->has_errata_A004447 = true; i2c->adap = mpc_ops; of_address_to_resource(op->dev.of_node, 0, &res); @@ -740,6 +837,7 @@ i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; i2c->adap.dev.of_node = of_node_get(op->dev.of_node); + i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info; result = i2c_add_adapter(&i2c->adap); if (result < 0) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-mt65xx.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-mt65xx.c @@ -389,6 +389,10 @@ { u16 control_reg; + writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); + udelay(50); + writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); + mtk_i2c_writew(i2c, I2C_SOFT_RST, OFFSET_SOFTRESET); /* Set ioconfig */ @@ -419,10 +423,6 @@ mtk_i2c_writew(i2c, control_reg, OFFSET_CONTROL); mtk_i2c_writew(i2c, I2C_DELAY_LEN, OFFSET_DELAY_LEN); - - writel(I2C_DMA_HARD_RST, i2c->pdmabase + OFFSET_RST); - udelay(50); - writel(I2C_DMA_CLR_FLAG, i2c->pdmabase + OFFSET_RST); } /* @@ -932,7 +932,7 @@ return PTR_ERR(i2c->pdmabase); irq = platform_get_irq(pdev, 0); - if (irq <= 0) + if (irq < 0) return irq; init_completion(&i2c->msg_complete); @@ -1008,7 +1008,8 @@ mtk_i2c_clock_disable(i2c); ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, - IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); + IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE, + I2C_DRV_NAME, i2c); if (ret < 0) { dev_err(&pdev->dev, "Request I2C IRQ %d fail\n", irq); @@ -1035,7 +1036,16 @@ } #ifdef CONFIG_PM_SLEEP -static int mtk_i2c_resume(struct device *dev) +static int mtk_i2c_suspend_noirq(struct device *dev) +{ + struct mtk_i2c *i2c = dev_get_drvdata(dev); + + i2c_mark_adapter_suspended(&i2c->adap); + + return 0; +} + +static int mtk_i2c_resume_noirq(struct device *dev) { int ret; struct mtk_i2c *i2c = dev_get_drvdata(dev); @@ -1050,12 +1060,15 @@ mtk_i2c_clock_disable(i2c); + i2c_mark_adapter_resumed(&i2c->adap); + return 0; } #endif static const struct dev_pm_ops mtk_i2c_pm = { - SET_SYSTEM_SLEEP_PM_OPS(NULL, mtk_i2c_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_i2c_suspend_noirq, + mtk_i2c_resume_noirq) }; static struct platform_driver mtk_i2c_driver = { --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-mt7621.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-mt7621.c @@ -304,7 +304,8 @@ if (i2c->bus_freq == 0) { dev_warn(i2c->dev, "clock-frequency 0 not supported\n"); - return -EINVAL; + ret = -EINVAL; + goto err_disable_clk; } adap = &i2c->adap; @@ -322,10 +323,15 @@ ret = i2c_add_adapter(adap); if (ret < 0) - return ret; + goto err_disable_clk; dev_info(&pdev->dev, "clock %u kHz\n", i2c->bus_freq / 1000); + return 0; + +err_disable_clk: + clk_disable_unprepare(i2c->clk); + return ret; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-mxs.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-mxs.c @@ -25,6 +25,7 @@ #include #include #include +#include #define DRIVER_NAME "mxs-i2c" @@ -200,7 +201,8 @@ dma_map_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[0], 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_PREP_INTERRUPT | + MXS_DMA_CTRL_WAIT4END); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); @@ -228,7 +230,8 @@ dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_PREP_INTERRUPT | + MXS_DMA_CTRL_WAIT4END); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); @@ -260,7 +263,8 @@ dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE); desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_PREP_INTERRUPT | + MXS_DMA_CTRL_WAIT4END); if (!desc) { dev_err(i2c->dev, "Failed to get DMA data write descriptor.\n"); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-nvidia-gpu.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-nvidia-gpu.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -75,20 +76,15 @@ static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd) { - unsigned long target = jiffies + msecs_to_jiffies(1000); u32 val; + int ret; - do { - val = readl(i2cd->regs + I2C_MST_CNTL); - if (!(val & I2C_MST_CNTL_CYCLE_TRIGGER)) - break; - if ((val & I2C_MST_CNTL_STATUS) != - I2C_MST_CNTL_STATUS_BUS_BUSY) - break; - usleep_range(500, 600); - } while (time_is_after_jiffies(target)); + ret = readl_poll_timeout(i2cd->regs + I2C_MST_CNTL, val, + !(val & I2C_MST_CNTL_CYCLE_TRIGGER) || + (val & I2C_MST_CNTL_STATUS) != I2C_MST_CNTL_STATUS_BUS_BUSY, + 500, 1000 * USEC_PER_MSEC); - if (time_is_before_jiffies(target)) { + if (ret) { dev_err(i2cd->dev, "i2c timeout error %x\n", val); return -ETIMEDOUT; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-ocores.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-ocores.c @@ -343,18 +343,18 @@ * ocores_isr(), we just add our polling code around it. * * It can run in atomic context + * + * Return: 0 on success, -ETIMEDOUT on timeout */ -static void ocores_process_polling(struct ocores_i2c *i2c) +static int ocores_process_polling(struct ocores_i2c *i2c) { - while (1) { - irqreturn_t ret; - int err; + irqreturn_t ret; + int err = 0; + while (1) { err = ocores_poll_wait(i2c); - if (err) { - i2c->state = STATE_ERROR; + if (err) break; /* timeout */ - } ret = ocores_isr(-1, i2c); if (ret == IRQ_NONE) @@ -365,13 +365,15 @@ break; } } + + return err; } static int ocores_xfer_core(struct ocores_i2c *i2c, struct i2c_msg *msgs, int num, bool polling) { - int ret; + int ret = 0; u8 ctrl; ctrl = oc_getreg(i2c, OCI2C_CONTROL); @@ -389,15 +391,16 @@ oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); if (polling) { - ocores_process_polling(i2c); + ret = ocores_process_polling(i2c); } else { - ret = wait_event_timeout(i2c->wait, - (i2c->state == STATE_ERROR) || - (i2c->state == STATE_DONE), HZ); - if (ret == 0) { - ocores_process_timeout(i2c); - return -ETIMEDOUT; - } + if (wait_event_timeout(i2c->wait, + (i2c->state == STATE_ERROR) || + (i2c->state == STATE_DONE), HZ) == 0) + ret = -ETIMEDOUT; + } + if (ret) { + ocores_process_timeout(i2c); + return ret; } return (i2c->state == STATE_DONE) ? num : -EIO; @@ -440,8 +443,8 @@ oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); /* Init the device */ - oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN); + oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); return 0; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-octeon-core.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-octeon-core.c @@ -347,7 +347,7 @@ if (result) return result; if (recv_len && i == 0) { - if (data[i] > I2C_SMBUS_BLOCK_MAX + 1) + if (data[i] > I2C_SMBUS_BLOCK_MAX) return -EPROTO; length += data[i]; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-omap.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-omap.c @@ -1058,7 +1058,7 @@ u16 stat; stat = omap_i2c_read_reg(omap, OMAP_I2C_STAT_REG); - mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG); + mask = omap_i2c_read_reg(omap, OMAP_I2C_IE_REG) & ~OMAP_I2C_STAT_NACK; if (stat & mask) ret = IRQ_WAKE_THREAD; @@ -1408,9 +1408,9 @@ pm_runtime_set_autosuspend_delay(omap->dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(omap->dev); - r = pm_runtime_get_sync(omap->dev); + r = pm_runtime_resume_and_get(omap->dev); if (r < 0) - goto err_free_mem; + goto err_disable_pm; /* * Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2. @@ -1518,8 +1518,8 @@ omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0); pm_runtime_dont_use_autosuspend(omap->dev); pm_runtime_put_sync(omap->dev); +err_disable_pm: pm_runtime_disable(&pdev->dev); -err_free_mem: return r; } @@ -1530,7 +1530,7 @@ int ret; i2c_del_adapter(&omap->adapter); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-owl.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-owl.c @@ -179,6 +179,9 @@ fifostat = readl(i2c_dev->base + OWL_I2C_REG_FIFOSTAT); if (fifostat & OWL_I2C_FIFOSTAT_RNB) { i2c_dev->err = -ENXIO; + /* Clear NACK error bit by writing "1" */ + owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_FIFOSTAT, + OWL_I2C_FIFOSTAT_RNB, true); goto stop; } @@ -186,6 +189,9 @@ stat = readl(i2c_dev->base + OWL_I2C_REG_STAT); if (stat & OWL_I2C_STAT_BEB) { i2c_dev->err = -EIO; + /* Clear BUS error bit by writing "1" */ + owl_i2c_update_reg(i2c_dev->base + OWL_I2C_REG_STAT, + OWL_I2C_STAT_BEB, true); goto stop; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-pasemi.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-pasemi.c @@ -137,6 +137,12 @@ TXFIFO_WR(smbus, msg->buf[msg->len-1] | (stop ? MTXFIFO_STOP : 0)); + + if (stop) { + err = pasemi_smb_waitready(smbus); + if (err) + goto reset_out; + } } return 0; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-pca-platform.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-pca-platform.c @@ -140,7 +140,7 @@ int ret = 0; int irq; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); /* If irq is 0, we do polling. */ if (irq < 0) irq = 0; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-piix4.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-piix4.c @@ -977,7 +977,8 @@ } if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS) { + (dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS || + dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS)) { retval = piix4_setup_sb800(dev, id, 1); } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-pnx.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-pnx.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -32,7 +31,6 @@ int ret; /* Return value */ int mode; /* Interface mode */ struct completion complete; /* I/O completion */ - struct timer_list timer; /* Timeout */ u8 * buf; /* Data buffer */ int len; /* Length of data buffer */ int order; /* RX Bytes to order via TX */ @@ -97,7 +95,7 @@ static inline int wait_timeout(struct i2c_pnx_algo_data *data) { - long timeout = data->timeout; + long timeout = jiffies_to_msecs(data->timeout); while (timeout > 0 && (ioread32(I2C_REG_STS(data)) & mstatus_active)) { mdelay(1); @@ -108,7 +106,7 @@ static inline int wait_reset(struct i2c_pnx_algo_data *data) { - long timeout = data->timeout; + long timeout = jiffies_to_msecs(data->timeout); while (timeout > 0 && (ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) { mdelay(1); @@ -117,24 +115,6 @@ return (timeout <= 0); } -static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) -{ - struct timer_list *timer = &alg_data->mif.timer; - unsigned long expires = msecs_to_jiffies(alg_data->timeout); - - if (expires <= 1) - expires = 2; - - del_timer_sync(timer); - - dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n", - jiffies, expires); - - timer->expires = jiffies + expires; - - add_timer(timer); -} - /** * i2c_pnx_start - start a device * @slave_addr: slave address @@ -259,8 +239,6 @@ ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie), I2C_REG_CTL(alg_data)); - del_timer_sync(&alg_data->mif.timer); - dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine.\n", __func__); @@ -276,8 +254,6 @@ ~(mcntrl_afie | mcntrl_naie | mcntrl_drmie), I2C_REG_CTL(alg_data)); - /* Stop timer. */ - del_timer_sync(&alg_data->mif.timer); dev_dbg(&alg_data->adapter.dev, "%s(): Waking up xfer routine after zero-xfer.\n", __func__); @@ -364,8 +340,6 @@ mcntrl_drmie | mcntrl_daie); iowrite32(ctl, I2C_REG_CTL(alg_data)); - /* Kill timer. */ - del_timer_sync(&alg_data->mif.timer); complete(&alg_data->mif.complete); } } @@ -400,8 +374,6 @@ mcntrl_drmie); iowrite32(ctl, I2C_REG_CTL(alg_data)); - /* Stop timer, to prevent timeout. */ - del_timer_sync(&alg_data->mif.timer); complete(&alg_data->mif.complete); } else if (stat & mstatus_nai) { /* Slave did not acknowledge, generate a STOP */ @@ -419,8 +391,6 @@ /* Our return value. */ alg_data->mif.ret = -EIO; - /* Stop timer, to prevent timeout. */ - del_timer_sync(&alg_data->mif.timer); complete(&alg_data->mif.complete); } else { /* @@ -453,9 +423,8 @@ return IRQ_HANDLED; } -static void i2c_pnx_timeout(struct timer_list *t) +static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data) { - struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer); u32 ctl; dev_err(&alg_data->adapter.dev, @@ -472,7 +441,6 @@ iowrite32(ctl, I2C_REG_CTL(alg_data)); wait_reset(alg_data); alg_data->mif.ret = -EIO; - complete(&alg_data->mif.complete); } static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data) @@ -514,6 +482,7 @@ struct i2c_msg *pmsg; int rc = 0, completed = 0, i; struct i2c_pnx_algo_data *alg_data = adap->algo_data; + unsigned long time_left; u32 stat; dev_dbg(&alg_data->adapter.dev, @@ -548,7 +517,6 @@ dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n", __func__, alg_data->mif.mode, alg_data->mif.len); - i2c_pnx_arm_timer(alg_data); /* initialize the completion var */ init_completion(&alg_data->mif.complete); @@ -564,7 +532,10 @@ break; /* Wait for completion */ - wait_for_completion(&alg_data->mif.complete); + time_left = wait_for_completion_timeout(&alg_data->mif.complete, + alg_data->timeout); + if (time_left == 0) + i2c_pnx_timeout(alg_data); if (!(rc = alg_data->mif.ret)) completed++; @@ -657,7 +628,10 @@ alg_data->adapter.algo_data = alg_data; alg_data->adapter.nr = pdev->id; - alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT; + alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT); + if (alg_data->timeout <= 1) + alg_data->timeout = 2; + #ifdef CONFIG_OF alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node); if (pdev->dev.of_node) { @@ -677,8 +651,6 @@ if (IS_ERR(alg_data->clk)) return PTR_ERR(alg_data->clk); - timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0); - snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name), "%s", pdev->name); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-pxa-pci.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-pxa-pci.c @@ -105,7 +105,7 @@ int i; struct ce4100_devices *sds; - ret = pci_enable_device_mem(dev); + ret = pcim_enable_device(dev); if (ret) return ret; @@ -114,10 +114,8 @@ return -EINVAL; } sds = kzalloc(sizeof(*sds), GFP_KERNEL); - if (!sds) { - ret = -ENOMEM; - goto err_mem; - } + if (!sds) + return -ENOMEM; for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) { sds->pdev[i] = add_i2c_device(dev, i); @@ -133,8 +131,6 @@ err_dev_add: kfree(sds); -err_mem: - pci_disable_device(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-pxa.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-pxa.c @@ -312,11 +312,10 @@ dev_err(dev, "IBMR: %08x IDBR: %08x ICR: %08x ISR: %08x\n", readl(_IBMR(i2c)), readl(_IDBR(i2c)), readl(_ICR(i2c)), readl(_ISR(i2c))); - dev_dbg(dev, "log: "); + dev_err(dev, "log:"); for (i = 0; i < i2c->irqlogidx; i++) - pr_debug("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]); - - pr_debug("\n"); + pr_cont(" [%03x:%05x]", i2c->isrlog[i], i2c->icrlog[i]); + pr_cont("\n"); } #else /* ifdef DEBUG */ @@ -706,11 +705,9 @@ { u32 icr; - /* - * Clear the STOP and ACK flags - */ + /* Clear the START, STOP, ACK, TB and MA flags */ icr = readl(_ICR(i2c)); - icr &= ~(ICR_STOP | ICR_ACKNAK); + icr &= ~(ICR_START | ICR_STOP | ICR_ACKNAK | ICR_TB | ICR_MA); writel(icr, _ICR(i2c)); } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-qcom-geni.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-qcom-geni.c @@ -87,6 +87,9 @@ u32 clk_freq_out; const struct geni_i2c_clk_fld *clk_fld; int suspended; + void *dma_buf; + size_t xfer_len; + dma_addr_t dma_addr; }; struct geni_i2c_err_log { @@ -350,14 +353,39 @@ dev_err(gi2c->se.dev, "Timeout resetting TX_FSM\n"); } +static void geni_i2c_rx_msg_cleanup(struct geni_i2c_dev *gi2c, + struct i2c_msg *cur) +{ + gi2c->cur_rd = 0; + if (gi2c->dma_buf) { + if (gi2c->err) + geni_i2c_rx_fsm_rst(gi2c); + geni_se_rx_dma_unprep(&gi2c->se, gi2c->dma_addr, gi2c->xfer_len); + i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err); + } +} + +static void geni_i2c_tx_msg_cleanup(struct geni_i2c_dev *gi2c, + struct i2c_msg *cur) +{ + gi2c->cur_wr = 0; + if (gi2c->dma_buf) { + if (gi2c->err) + geni_i2c_tx_fsm_rst(gi2c); + geni_se_tx_dma_unprep(&gi2c->se, gi2c->dma_addr, gi2c->xfer_len); + i2c_put_dma_safe_msg_buf(gi2c->dma_buf, cur, !gi2c->err); + } +} + static int geni_i2c_rx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, u32 m_param) { - dma_addr_t rx_dma; + dma_addr_t rx_dma = 0; unsigned long time_left; void *dma_buf = NULL; struct geni_se *se = &gi2c->se; size_t len = msg->len; + struct i2c_msg *cur; if (!of_machine_is_compatible("lenovo,yoga-c630")) dma_buf = i2c_get_dma_safe_msg_buf(msg, 32); @@ -374,19 +402,18 @@ geni_se_select_mode(se, GENI_SE_FIFO); i2c_put_dma_safe_msg_buf(dma_buf, msg, false); dma_buf = NULL; + } else { + gi2c->xfer_len = len; + gi2c->dma_addr = rx_dma; + gi2c->dma_buf = dma_buf; } + cur = gi2c->cur; time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); if (!time_left) geni_i2c_abort_xfer(gi2c); - gi2c->cur_rd = 0; - if (dma_buf) { - if (gi2c->err) - geni_i2c_rx_fsm_rst(gi2c); - geni_se_rx_dma_unprep(se, rx_dma, len); - i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err); - } + geni_i2c_rx_msg_cleanup(gi2c, cur); return gi2c->err; } @@ -394,11 +421,12 @@ static int geni_i2c_tx_one_msg(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, u32 m_param) { - dma_addr_t tx_dma; + dma_addr_t tx_dma = 0; unsigned long time_left; void *dma_buf = NULL; struct geni_se *se = &gi2c->se; size_t len = msg->len; + struct i2c_msg *cur; if (!of_machine_is_compatible("lenovo,yoga-c630")) dma_buf = i2c_get_dma_safe_msg_buf(msg, 32); @@ -415,22 +443,21 @@ geni_se_select_mode(se, GENI_SE_FIFO); i2c_put_dma_safe_msg_buf(dma_buf, msg, false); dma_buf = NULL; + } else { + gi2c->xfer_len = len; + gi2c->dma_addr = tx_dma; + gi2c->dma_buf = dma_buf; } if (!dma_buf) /* Get FIFO IRQ */ writel_relaxed(1, se->base + SE_GENI_TX_WATERMARK_REG); + cur = gi2c->cur; time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); if (!time_left) geni_i2c_abort_xfer(gi2c); - gi2c->cur_wr = 0; - if (dma_buf) { - if (gi2c->err) - geni_i2c_tx_fsm_rst(gi2c); - geni_se_tx_dma_unprep(se, tx_dma, len); - i2c_put_dma_safe_msg_buf(dma_buf, msg, !gi2c->err); - } + geni_i2c_tx_msg_cleanup(gi2c, cur); return gi2c->err; } @@ -502,45 +529,40 @@ struct resource *res; u32 proto, tx_depth; int ret; + struct device *dev = &pdev->dev; - gi2c = devm_kzalloc(&pdev->dev, sizeof(*gi2c), GFP_KERNEL); + gi2c = devm_kzalloc(dev, sizeof(*gi2c), GFP_KERNEL); if (!gi2c) return -ENOMEM; - gi2c->se.dev = &pdev->dev; - gi2c->se.wrapper = dev_get_drvdata(pdev->dev.parent); + gi2c->se.dev = dev; + gi2c->se.wrapper = dev_get_drvdata(dev->parent); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - gi2c->se.base = devm_ioremap_resource(&pdev->dev, res); + gi2c->se.base = devm_ioremap_resource(dev, res); if (IS_ERR(gi2c->se.base)) return PTR_ERR(gi2c->se.base); - gi2c->se.clk = devm_clk_get(&pdev->dev, "se"); - if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(&pdev->dev)) { - ret = PTR_ERR(gi2c->se.clk); - dev_err(&pdev->dev, "Err getting SE Core clk %d\n", ret); - return ret; - } + gi2c->se.clk = devm_clk_get(dev, "se"); + if (IS_ERR(gi2c->se.clk) && !has_acpi_companion(dev)) + return PTR_ERR(gi2c->se.clk); - ret = device_property_read_u32(&pdev->dev, "clock-frequency", - &gi2c->clk_freq_out); + ret = device_property_read_u32(dev, "clock-frequency", + &gi2c->clk_freq_out); if (ret) { - dev_info(&pdev->dev, - "Bus frequency not specified, default to 100kHz.\n"); + dev_info(dev, "Bus frequency not specified, default to 100kHz.\n"); gi2c->clk_freq_out = KHZ(100); } - if (has_acpi_companion(&pdev->dev)) - ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(&pdev->dev)); + if (has_acpi_companion(dev)) + ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev)); gi2c->irq = platform_get_irq(pdev, 0); - if (gi2c->irq < 0) { - dev_err(&pdev->dev, "IRQ error for i2c-geni\n"); + if (gi2c->irq < 0) return gi2c->irq; - } ret = geni_i2c_clk_map_idx(gi2c); if (ret) { - dev_err(&pdev->dev, "Invalid clk frequency %d Hz: %d\n", + dev_err(dev, "Invalid clk frequency %d Hz: %d\n", gi2c->clk_freq_out, ret); return ret; } @@ -549,29 +571,27 @@ init_completion(&gi2c->done); spin_lock_init(&gi2c->lock); platform_set_drvdata(pdev, gi2c); - ret = devm_request_irq(&pdev->dev, gi2c->irq, geni_i2c_irq, - IRQF_TRIGGER_HIGH, "i2c_geni", gi2c); + ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, IRQF_NO_AUTOEN, + dev_name(dev), gi2c); if (ret) { - dev_err(&pdev->dev, "Request_irq failed:%d: err:%d\n", + dev_err(dev, "Request_irq failed:%d: err:%d\n", gi2c->irq, ret); return ret; } - /* Disable the interrupt so that the system can enter low-power mode */ - disable_irq(gi2c->irq); i2c_set_adapdata(&gi2c->adap, gi2c); - gi2c->adap.dev.parent = &pdev->dev; - gi2c->adap.dev.of_node = pdev->dev.of_node; + gi2c->adap.dev.parent = dev; + gi2c->adap.dev.of_node = dev->of_node; strlcpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); ret = geni_se_resources_on(&gi2c->se); if (ret) { - dev_err(&pdev->dev, "Error turning on resources %d\n", ret); + dev_err(dev, "Error turning on resources %d\n", ret); return ret; } proto = geni_se_read_proto(&gi2c->se); tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se); if (proto != GENI_SE_I2C) { - dev_err(&pdev->dev, "Invalid proto %d\n", proto); + dev_err(dev, "Invalid proto %d\n", proto); geni_se_resources_off(&gi2c->se); return -ENXIO; } @@ -581,11 +601,11 @@ true, true, true); ret = geni_se_resources_off(&gi2c->se); if (ret) { - dev_err(&pdev->dev, "Error turning off resources %d\n", ret); + dev_err(dev, "Error turning off resources %d\n", ret); return ret; } - dev_dbg(&pdev->dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); + dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth); gi2c->suspended = 1; pm_runtime_set_suspended(gi2c->se.dev); @@ -595,12 +615,12 @@ ret = i2c_add_adapter(&gi2c->adap); if (ret) { - dev_err(&pdev->dev, "Error adding i2c adapter %d\n", ret); + dev_err(dev, "Error adding i2c adapter %d\n", ret); pm_runtime_disable(gi2c->se.dev); return ret; } - dev_dbg(&pdev->dev, "Geni-I2C adaptor successfully added\n"); + dev_dbg(dev, "Geni-I2C adaptor successfully added\n"); return 0; } @@ -614,6 +634,14 @@ return 0; } +static void geni_i2c_shutdown(struct platform_device *pdev) +{ + struct geni_i2c_dev *gi2c = platform_get_drvdata(pdev); + + /* Make client i2c transfers start failing */ + i2c_mark_adapter_suspended(&gi2c->adap); +} + static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) { int ret; @@ -650,6 +678,8 @@ { struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); + i2c_mark_adapter_suspended(&gi2c->adap); + if (!gi2c->suspended) { geni_i2c_runtime_suspend(dev); pm_runtime_disable(dev); @@ -659,8 +689,16 @@ return 0; } +static int __maybe_unused geni_i2c_resume_noirq(struct device *dev) +{ + struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); + + i2c_mark_adapter_resumed(&gi2c->adap); + return 0; +} + static const struct dev_pm_ops geni_i2c_pm_ops = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, NULL) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, geni_i2c_resume_noirq) SET_RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume, NULL) }; @@ -674,6 +712,7 @@ static struct platform_driver geni_i2c_driver = { .probe = geni_i2c_probe, .remove = geni_i2c_remove, + .shutdown = geni_i2c_shutdown, .driver = { .name = "geni_i2c", .pm = &geni_i2c_pm_ops, --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-qup.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-qup.c @@ -806,7 +806,8 @@ if (ret || qup->bus_err || qup->qup_err) { reinit_completion(&qup->xfer); - if (qup_i2c_change_state(qup, QUP_RUN_STATE)) { + ret = qup_i2c_change_state(qup, QUP_RUN_STATE); + if (ret) { dev_err(qup->dev, "change to run state timed out"); goto desc_err; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-rcar.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-rcar.c @@ -89,7 +89,6 @@ #define RCAR_BUS_PHASE_START (MDBS | MIE | ESG) #define RCAR_BUS_PHASE_DATA (MDBS | MIE) -#define RCAR_BUS_MASK_DATA (~(ESG | FSB) & 0xFF) #define RCAR_BUS_PHASE_STOP (MDBS | MIE | FSB) #define RCAR_IRQ_SEND (MNR | MAL | MST | MAT | MDE) @@ -117,6 +116,7 @@ }; struct rcar_i2c_priv { + u32 flags; void __iomem *io; struct i2c_adapter adap; struct i2c_msg *msg; @@ -127,7 +127,6 @@ int pos; u32 icccr; - u32 flags; u8 recovery_icmcr; /* protected by adapter lock */ enum rcar_i2c_type devtype; struct i2c_client *slave; @@ -219,6 +218,14 @@ } +static void rcar_i2c_reset_slave(struct rcar_i2c_priv *priv) +{ + rcar_i2c_write(priv, ICSIER, 0); + rcar_i2c_write(priv, ICSSR, 0); + rcar_i2c_write(priv, ICSCR, SDBS); + rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */ +} + static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv) { int i; @@ -580,13 +587,15 @@ rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR); } - rcar_i2c_write(priv, ICSSR, ~SAR & 0xff); + /* Clear SSR, too, because of old STOPs to other clients than us */ + rcar_i2c_write(priv, ICSSR, ~(SAR | SSR) & 0xff); } /* master sent stop */ if (ssr_filtered & SSR) { i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value); - rcar_i2c_write(priv, ICSIER, SAR | SSR); + rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */ + rcar_i2c_write(priv, ICSIER, SAR); rcar_i2c_write(priv, ICSSR, ~SSR & 0xff); } @@ -614,7 +623,7 @@ /* * This driver has a lock-free design because there are IP cores (at least * R-Car Gen2) which have an inherent race condition in their hardware design. - * There, we need to clear RCAR_BUS_MASK_DATA bits as soon as possible after + * There, we need to switch to RCAR_BUS_PHASE_DATA as soon as possible after * the interrupt was generated, otherwise an unwanted repeated message gets * generated. It turned out that taking a spinlock at the beginning of the ISR * was already causing repeated messages. Thus, this driver was converted to @@ -623,13 +632,11 @@ static irqreturn_t rcar_i2c_irq(int irq, void *ptr) { struct rcar_i2c_priv *priv = ptr; - u32 msr, val; + u32 msr; /* Clear START or STOP immediately, except for REPSTART after read */ - if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) { - val = rcar_i2c_read(priv, ICMCR); - rcar_i2c_write(priv, ICMCR, val & RCAR_BUS_MASK_DATA); - } + if (likely(!(priv->flags & ID_P_REP_AFTER_RD))) + rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA); msr = rcar_i2c_read(priv, ICMSR); @@ -850,7 +857,7 @@ priv->slave = slave; rcar_i2c_write(priv, ICSAR, slave->addr); rcar_i2c_write(priv, ICSSR, 0); - rcar_i2c_write(priv, ICSIER, SAR | SSR); + rcar_i2c_write(priv, ICSIER, SAR); rcar_i2c_write(priv, ICSCR, SIE | SDBS); return 0; @@ -862,11 +869,11 @@ WARN_ON(!priv->slave); - /* disable irqs and ensure none is running before clearing ptr */ - rcar_i2c_write(priv, ICSIER, 0); - rcar_i2c_write(priv, ICSCR, 0); + /* ensure no irq is running before clearing ptr */ + disable_irq(priv->irq); + rcar_i2c_reset_slave(priv); + enable_irq(priv->irq); - synchronize_irq(priv->irq); priv->slave = NULL; pm_runtime_put(rcar_i2c_priv_to_dev(priv)); @@ -971,6 +978,10 @@ if (ret < 0) goto out_pm_put; + /* Bring hardware to known state */ + rcar_i2c_init(priv); + rcar_i2c_reset_slave(priv); + if (priv->devtype == I2C_RCAR_GEN3) { priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (!IS_ERR(priv->rstc)) { --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-riic.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-riic.c @@ -312,7 +312,7 @@ * frequency with only 62 clock ticks max (31 high, 31 low). * Aim for a duty of 60% LOW, 40% HIGH. */ - total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz); + total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz ?: 1); for (cks = 0; cks < 7; cks++) { /* @@ -323,7 +323,7 @@ if (brl <= (0x1F + 3)) break; - total_ticks /= 2; + total_ticks = DIV_ROUND_UP(total_ticks, 2); rate /= 2; } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-rk3x.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-rk3x.c @@ -79,7 +79,7 @@ #define DEFAULT_SCL_RATE (100 * 1000) /* Hz */ /** - * struct i2c_spec_values: + * struct i2c_spec_values - I2C specification values for various modes * @min_hold_start_ns: min hold time (repeated) START condition * @min_low_ns: min LOW period of the SCL clock * @min_high_ns: min HIGH period of the SCL cloc @@ -135,7 +135,7 @@ }; /** - * struct rk3x_i2c_calced_timings: + * struct rk3x_i2c_calced_timings - calculated V1 timings * @div_low: Divider output for low * @div_high: Divider output for high * @tuning: Used to adjust setup/hold data time, @@ -158,7 +158,7 @@ }; /** - * struct rk3x_i2c_soc_data: + * struct rk3x_i2c_soc_data - SOC-specific data * @grf_offset: offset inside the grf regmap for setting the i2c type * @calc_timings: Callback function for i2c timing information calculated */ @@ -238,7 +238,8 @@ } /** - * Generate a START condition, which triggers a REG_INT_START interrupt. + * rk3x_i2c_start - Generate a START condition, which triggers a REG_INT_START interrupt. + * @i2c: target controller data */ static void rk3x_i2c_start(struct rk3x_i2c *i2c) { @@ -257,8 +258,8 @@ } /** - * Generate a STOP condition, which triggers a REG_INT_STOP interrupt. - * + * rk3x_i2c_stop - Generate a STOP condition, which triggers a REG_INT_STOP interrupt. + * @i2c: target controller data * @error: Error code to return in rk3x_i2c_xfer */ static void rk3x_i2c_stop(struct rk3x_i2c *i2c, int error) @@ -297,7 +298,8 @@ } /** - * Setup a read according to i2c->msg + * rk3x_i2c_prepare_read - Setup a read according to i2c->msg + * @i2c: target controller data */ static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) { @@ -328,7 +330,8 @@ } /** - * Fill the transmit buffer with data from i2c->msg + * rk3x_i2c_fill_transmit_buf - Fill the transmit buffer with data from i2c->msg + * @i2c: target controller data */ static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c) { @@ -415,15 +418,15 @@ { unsigned int i; unsigned int len = i2c->msg->len - i2c->processed; - u32 uninitialized_var(val); + u32 val; u8 byte; /* we only care for MBRF here. */ if (!(ipd & REG_INT_MBRF)) return; - /* ack interrupt */ - i2c_writel(i2c, REG_INT_MBRF, REG_IPD); + /* ack interrupt (read also produces a spurious START flag, clear it too) */ + i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); /* Can only handle a maximum of 32 bytes at a time */ if (len > 32) @@ -531,11 +534,10 @@ } /** - * Get timing values of I2C specification - * + * rk3x_i2c_get_spec - Get timing values of I2C specification * @speed: Desired SCL frequency * - * Returns: Matched i2c spec values. + * Return: Matched i2c_spec_values. */ static const struct i2c_spec_values *rk3x_i2c_get_spec(unsigned int speed) { @@ -548,13 +550,12 @@ } /** - * Calculate divider values for desired SCL frequency - * + * rk3x_i2c_v0_calc_timings - Calculate divider values for desired SCL frequency * @clk_rate: I2C input clock rate * @t: Known I2C timing information * @t_calc: Caculated rk3x private timings that would be written into regs * - * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case * a best-effort divider value is returned in divs. If the target rate is * too high, we silently use the highest possible rate. */ @@ -709,13 +710,12 @@ } /** - * Calculate timing values for desired SCL frequency - * + * rk3x_i2c_v1_calc_timings - Calculate timing values for desired SCL frequency * @clk_rate: I2C input clock rate * @t: Known I2C timing information * @t_calc: Caculated rk3x private timings that would be written into regs * - * Returns: 0 on success, -EINVAL if the goal SCL rate is too slow. In that case + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case * a best-effort divider value is returned in divs. If the target rate is * too high, we silently use the highest possible rate. * The following formulas are v1's method to calculate timings. @@ -959,14 +959,14 @@ } /** - * Setup I2C registers for an I2C operation specified by msgs, num. - * - * Must be called with i2c->lock held. - * + * rk3x_i2c_setup - Setup I2C registers for an I2C operation specified by msgs, num. + * @i2c: target controller data * @msgs: I2C msgs to process * @num: Number of msgs * - * returns: Number of I2C msgs processed or negative in case of error + * Must be called with i2c->lock held. + * + * Return: Number of I2C msgs processed or negative in case of error */ static int rk3x_i2c_setup(struct rk3x_i2c *i2c, struct i2c_msg *msgs, int num) { --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-robotfuzz-osif.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -83,7 +83,7 @@ } } - ret = osif_usb_read(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); + ret = osif_usb_write(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); if (ret) { dev_err(&adapter->dev, "failure sending STOP\n"); return -EREMOTEIO; @@ -153,7 +153,7 @@ * Set bus frequency. The frequency is: * 120,000,000 / ( 16 + 2 * div * 4^prescale). * Using dev = 52, prescale = 0 give 100KHz */ - ret = osif_usb_read(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, + ret = osif_usb_write(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, NULL, 0); if (ret) { dev_err(&interface->dev, "failure sending bit rate"); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-s3c2410.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-s3c2410.c @@ -223,8 +223,17 @@ int tries; for (tries = 50; tries; --tries) { - if (readl(i2c->regs + S3C2410_IICCON) - & S3C2410_IICCON_IRQPEND) { + unsigned long tmp = readl(i2c->regs + S3C2410_IICCON); + + if (!(tmp & S3C2410_IICCON_ACKEN)) { + /* + * Wait a bit for the bus to stabilize, + * delay estimated experimentally. + */ + usleep_range(100, 200); + return true; + } + if (tmp & S3C2410_IICCON_IRQPEND) { if (!(readl(i2c->regs + S3C2410_IICSTAT) & S3C2410_IICSTAT_LASTBIT)) return true; @@ -277,16 +286,6 @@ stat |= S3C2410_IICSTAT_START; writel(stat, i2c->regs + S3C2410_IICSTAT); - - if (i2c->quirks & QUIRK_POLL) { - while ((i2c->msg_num != 0) && is_ack(i2c)) { - i2c_s3c_irq_nextbyte(i2c, stat); - stat = readl(i2c->regs + S3C2410_IICSTAT); - - if (stat & S3C2410_IICSTAT_ARBITR) - dev_err(i2c->dev, "deal with arbitration loss\n"); - } - } } static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) @@ -484,7 +483,10 @@ * forces us to send a new START * when we change direction */ + dev_dbg(i2c->dev, + "missing START before write->read\n"); s3c24xx_i2c_stop(i2c, -EINVAL); + break; } goto retry_write; @@ -691,7 +693,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int num) { - unsigned long timeout; + unsigned long timeout = 0; int ret; ret = s3c24xx_i2c_set_master(i2c); @@ -711,16 +713,19 @@ s3c24xx_i2c_message_start(i2c, msgs); if (i2c->quirks & QUIRK_POLL) { - ret = i2c->msg_idx; + while ((i2c->msg_num != 0) && is_ack(i2c)) { + unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT); - if (ret != num) - dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); + i2c_s3c_irq_nextbyte(i2c, stat); - goto out; + stat = readl(i2c->regs + S3C2410_IICSTAT); + if (stat & S3C2410_IICSTAT_ARBITR) + dev_err(i2c->dev, "deal with arbitration loss\n"); + } + } else { + timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); } - timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); - ret = i2c->msg_idx; /* @@ -1138,7 +1143,7 @@ */ if (!(i2c->quirks & QUIRK_POLL)) { i2c->irq = ret = platform_get_irq(pdev, 0); - if (ret <= 0) { + if (ret < 0) { dev_err(&pdev->dev, "cannot find IRQ\n"); clk_unprepare(i2c->clk); return ret; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-sh7760.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-sh7760.c @@ -471,7 +471,10 @@ goto out2; } - id->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto out3; + id->irq = ret; id->adap.nr = pdev->id; id->adap.algo = &sh7760_i2c_algo; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-sh_mobile.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-sh_mobile.c @@ -129,6 +129,7 @@ int sr; bool send_stop; bool stop_after_dma; + bool atomic_xfer; struct resource *res; struct dma_chan *dma_tx; @@ -333,13 +334,15 @@ ret = iic_rd(pd, ICDR); break; case OP_RX_STOP: /* enable DTE interrupt, issue stop */ - iic_wr(pd, ICIC, - ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); + if (!pd->atomic_xfer) + iic_wr(pd, ICIC, + ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK); break; case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */ - iic_wr(pd, ICIC, - ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); + if (!pd->atomic_xfer) + iic_wr(pd, ICIC, + ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE); ret = iic_rd(pd, ICDR); iic_wr(pd, ICCR, ICCR_ICE | ICCR_RACK); break; @@ -435,7 +438,8 @@ if (wakeup) { pd->sr |= SW_DONE; - wake_up(&pd->wait); + if (!pd->atomic_xfer) + wake_up(&pd->wait); } /* defeat write posting to avoid spurious WAIT interrupts */ @@ -587,6 +591,9 @@ pd->pos = -1; pd->sr = 0; + if (pd->atomic_xfer) + return; + pd->dma_buf = i2c_get_dma_safe_msg_buf(pd->msg, 8); if (pd->dma_buf) sh_mobile_i2c_xfer_dma(pd); @@ -643,15 +650,13 @@ return i ? 0 : -ETIMEDOUT; } -static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, - struct i2c_msg *msgs, - int num) +static int sh_mobile_xfer(struct sh_mobile_i2c_data *pd, + struct i2c_msg *msgs, int num) { - struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; int i; - long timeout; + long time_left; /* Wake up device and enable clock */ pm_runtime_get_sync(pd->dev); @@ -668,15 +673,35 @@ if (do_start) i2c_op(pd, OP_START); - /* The interrupt handler takes care of the rest... */ - timeout = wait_event_timeout(pd->wait, - pd->sr & (ICSR_TACK | SW_DONE), - adapter->timeout); + if (pd->atomic_xfer) { + unsigned long j = jiffies + pd->adap.timeout; - /* 'stop_after_dma' tells if DMA transfer was complete */ - i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, pd->stop_after_dma); + time_left = time_before_eq(jiffies, j); + while (time_left && + !(pd->sr & (ICSR_TACK | SW_DONE))) { + unsigned char sr = iic_rd(pd, ICSR); + + if (sr & (ICSR_AL | ICSR_TACK | + ICSR_WAIT | ICSR_DTE)) { + sh_mobile_i2c_isr(0, pd); + udelay(150); + } else { + cpu_relax(); + } + time_left = time_before_eq(jiffies, j); + } + } else { + /* The interrupt handler takes care of the rest... */ + time_left = wait_event_timeout(pd->wait, + pd->sr & (ICSR_TACK | SW_DONE), + pd->adap.timeout); + + /* 'stop_after_dma' tells if DMA xfer was complete */ + i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, + pd->stop_after_dma); + } - if (!timeout) { + if (!time_left) { dev_err(pd->dev, "Transfer request timed out\n"); if (pd->dma_direction != DMA_NONE) sh_mobile_i2c_cleanup_dma(pd); @@ -702,14 +727,35 @@ return err ?: num; } +static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, + struct i2c_msg *msgs, + int num) +{ + struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); + + pd->atomic_xfer = false; + return sh_mobile_xfer(pd, msgs, num); +} + +static int sh_mobile_i2c_xfer_atomic(struct i2c_adapter *adapter, + struct i2c_msg *msgs, + int num) +{ + struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); + + pd->atomic_xfer = true; + return sh_mobile_xfer(pd, msgs, num); +} + static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING; } static const struct i2c_algorithm sh_mobile_i2c_algorithm = { - .functionality = sh_mobile_i2c_func, - .master_xfer = sh_mobile_i2c_xfer, + .functionality = sh_mobile_i2c_func, + .master_xfer = sh_mobile_i2c_xfer, + .master_xfer_atomic = sh_mobile_i2c_xfer_atomic, }; static const struct i2c_adapter_quirks sh_mobile_i2c_quirks = { @@ -767,7 +813,7 @@ static const struct of_device_id sh_mobile_i2c_dt_ids[] = { { .compatible = "renesas,iic-r8a73a4", .data = &fast_clock_dt_config }, { .compatible = "renesas,iic-r8a7740", .data = &r8a7740_dt_config }, - { .compatible = "renesas,iic-r8a774c0", .data = &fast_clock_dt_config }, + { .compatible = "renesas,iic-r8a774c0", .data = &v2_freq_calc_dt_config }, { .compatible = "renesas,iic-r8a7790", .data = &v2_freq_calc_dt_config }, { .compatible = "renesas,iic-r8a7791", .data = &v2_freq_calc_dt_config }, { .compatible = "renesas,iic-r8a7792", .data = &v2_freq_calc_dt_config }, --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-sprd.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-sprd.c @@ -72,6 +72,8 @@ /* timeout (ms) for pm runtime autosuspend */ #define SPRD_I2C_PM_TIMEOUT 1000 +/* timeout (ms) for transfer message */ +#define I2C_XFER_TIMEOUT 1000 /* SPRD i2c data structure */ struct sprd_i2c { @@ -244,6 +246,7 @@ struct i2c_msg *msg, bool is_last_msg) { struct sprd_i2c *i2c_dev = i2c_adap->algo_data; + unsigned long time_left; i2c_dev->msg = msg; i2c_dev->buf = msg->buf; @@ -273,7 +276,10 @@ sprd_i2c_opt_start(i2c_dev); - wait_for_completion(&i2c_dev->complete); + time_left = wait_for_completion_timeout(&i2c_dev->complete, + msecs_to_jiffies(I2C_XFER_TIMEOUT)); + if (!time_left) + return -ETIMEDOUT; return i2c_dev->err; } @@ -284,7 +290,7 @@ struct sprd_i2c *i2c_dev = i2c_adap->algo_data; int im, ret; - ret = pm_runtime_get_sync(i2c_dev->dev); + ret = pm_runtime_resume_and_get(i2c_dev->dev); if (ret < 0) return ret; @@ -573,10 +579,12 @@ ret = pm_runtime_get_sync(i2c_dev->dev); if (ret < 0) - return ret; + dev_err(&pdev->dev, "Failed to resume device (%pe)\n", ERR_PTR(ret)); i2c_del_adapter(&i2c_dev->adap); - clk_disable_unprepare(i2c_dev->clk); + + if (ret >= 0) + clk_disable_unprepare(i2c_dev->clk); pm_runtime_put_noidle(i2c_dev->dev); pm_runtime_disable(i2c_dev->dev); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-st.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-st.c @@ -434,6 +434,7 @@ /** * st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode * @i2c_dev: Controller's private data + * @max: Maximum amount of data to fill into the Tx FIFO * * This functions fills the Tx FIFO with fixed pattern when * in read mode to trigger clock. --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-stm32.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-stm32.c @@ -20,13 +20,13 @@ dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); if (!dma) - return NULL; + return ERR_PTR(-ENOMEM); /* Request and configure I2C TX dma channel */ - dma->chan_tx = dma_request_slave_channel(dev, "tx"); - if (!dma->chan_tx) { + dma->chan_tx = dma_request_chan(dev, "tx"); + if (IS_ERR(dma->chan_tx)) { dev_dbg(dev, "can't request DMA tx channel\n"); - ret = -EINVAL; + ret = PTR_ERR(dma->chan_tx); goto fail_al; } @@ -42,10 +42,10 @@ } /* Request and configure I2C RX dma channel */ - dma->chan_rx = dma_request_slave_channel(dev, "rx"); - if (!dma->chan_rx) { + dma->chan_rx = dma_request_chan(dev, "rx"); + if (IS_ERR(dma->chan_rx)) { dev_err(dev, "can't request DMA rx channel\n"); - ret = -EINVAL; + ret = PTR_ERR(dma->chan_rx); goto fail_tx; } @@ -75,7 +75,7 @@ devm_kfree(dev, dma); dev_info(dev, "can't use DMA\n"); - return NULL; + return ERR_PTR(ret); } void stm32_i2c_dma_free(struct stm32_i2c_dma *dma) --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-stm32f7.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-stm32f7.c @@ -53,6 +53,8 @@ #define STM32F7_I2C_CR1_RXDMAEN BIT(15) #define STM32F7_I2C_CR1_TXDMAEN BIT(14) #define STM32F7_I2C_CR1_ANFOFF BIT(12) +#define STM32F7_I2C_CR1_DNF_MASK GENMASK(11, 8) +#define STM32F7_I2C_CR1_DNF(n) (((n) & 0xf) << 8) #define STM32F7_I2C_CR1_ERRIE BIT(7) #define STM32F7_I2C_CR1_TCIE BIT(6) #define STM32F7_I2C_CR1_STOPIE BIT(5) @@ -151,7 +153,7 @@ #define STM32F7_I2C_MAX_SLAVE 0x2 #define STM32F7_I2C_DNF_DEFAULT 0 -#define STM32F7_I2C_DNF_MAX 16 +#define STM32F7_I2C_DNF_MAX 15 #define STM32F7_I2C_ANALOG_FILTER_ENABLE 1 #define STM32F7_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */ @@ -657,6 +659,13 @@ else stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ANFOFF); + + /* Program the Digital Filter */ + stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, + STM32F7_I2C_CR1_DNF_MASK); + stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, + STM32F7_I2C_CR1_DNF(i2c_dev->setup.dnf)); + stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_PE); } @@ -965,9 +974,10 @@ /* Configure PEC */ if ((flags & I2C_CLIENT_PEC) && f7_msg->size != I2C_SMBUS_QUICK) { cr1 |= STM32F7_I2C_CR1_PECEN; - cr2 |= STM32F7_I2C_CR2_PECBYTE; - if (!f7_msg->read_write) + if (!f7_msg->read_write) { + cr2 |= STM32F7_I2C_CR2_PECBYTE; f7_msg->count++; + } } else { cr1 &= ~STM32F7_I2C_CR1_PECEN; cr2 &= ~STM32F7_I2C_CR2_PECBYTE; @@ -1055,8 +1065,10 @@ f7_msg->stop = true; /* Add one byte for PEC if needed */ - if (cr1 & STM32F7_I2C_CR1_PECEN) + if (cr1 & STM32F7_I2C_CR1_PECEN) { + cr2 |= STM32F7_I2C_CR2_PECBYTE; f7_msg->count++; + } /* Set number of bytes to be transferred */ cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK); @@ -1267,8 +1279,8 @@ * slave[0] supports 7-bit and 10-bit slave address * slave[1] supports 7-bit slave address only */ - for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) { - if (i == 1 && (slave->flags & I2C_CLIENT_PEC)) + for (i = STM32F7_I2C_MAX_SLAVE - 1; i >= 0; i--) { + if (i == 1 && (slave->flags & I2C_CLIENT_TEN)) continue; if (!i2c_dev->slave[i]) { *id = i; @@ -1385,6 +1397,7 @@ { struct stm32f7_i2c_dev *i2c_dev = data; struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg; + struct stm32_i2c_dma *dma = i2c_dev->dma; void __iomem *base = i2c_dev->base; u32 status, mask; int ret = IRQ_HANDLED; @@ -1409,6 +1422,10 @@ if (status & STM32F7_I2C_ISR_NACKF) { dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__); writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR); + if (i2c_dev->use_dma) { + stm32f7_i2c_disable_dma_req(i2c_dev); + dmaengine_terminate_all(dma->chan_using); + } f7_msg->result = -ENXIO; } @@ -1424,7 +1441,7 @@ /* Clear STOP flag */ writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR); - if (i2c_dev->use_dma) { + if (i2c_dev->use_dma && !f7_msg->result) { ret = IRQ_WAKE_THREAD; } else { i2c_dev->master_mode = false; @@ -1437,7 +1454,7 @@ if (f7_msg->stop) { mask = STM32F7_I2C_CR2_STOP; stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask); - } else if (i2c_dev->use_dma) { + } else if (i2c_dev->use_dma && !f7_msg->result) { ret = IRQ_WAKE_THREAD; } else if (f7_msg->smbus) { stm32f7_i2c_smbus_rep_start(i2c_dev); @@ -1577,12 +1594,23 @@ time_left = wait_for_completion_timeout(&i2c_dev->complete, i2c_dev->adap.timeout); ret = f7_msg->result; + if (ret) { + /* + * It is possible that some unsent data have already been + * written into TXDR. To avoid sending old data in a + * further transfer, flush TXDR in case of any error + */ + writel_relaxed(STM32F7_I2C_ISR_TXE, + i2c_dev->base + STM32F7_I2C_ISR); + goto pm_free; + } if (!time_left) { dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n", i2c_dev->msg->addr); if (i2c_dev->use_dma) dmaengine_terminate_all(dma->chan_using); + stm32f7_i2c_wait_free_bus(i2c_dev); ret = -ETIMEDOUT; } @@ -1625,13 +1653,22 @@ timeout = wait_for_completion_timeout(&i2c_dev->complete, i2c_dev->adap.timeout); ret = f7_msg->result; - if (ret) + if (ret) { + /* + * It is possible that some unsent data have already been + * written into TXDR. To avoid sending old data in a + * further transfer, flush TXDR in case of any error + */ + writel_relaxed(STM32F7_I2C_ISR_TXE, + i2c_dev->base + STM32F7_I2C_ISR); goto pm_free; + } if (!timeout) { dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr); if (i2c_dev->use_dma) dmaengine_terminate_all(dma->chan_using); + stm32f7_i2c_wait_free_bus(i2c_dev); ret = -ETIMEDOUT; goto pm_free; } @@ -1955,6 +1992,15 @@ i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr, STM32F7_I2C_TXDR, STM32F7_I2C_RXDR); + if (PTR_ERR(i2c_dev->dma) == -ENODEV) + i2c_dev->dma = NULL; + else if (IS_ERR(i2c_dev->dma)) { + ret = PTR_ERR(i2c_dev->dma); + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, + "Failed to request dma error %i\n", ret); + goto clk_free; + } platform_set_drvdata(pdev, i2c_dev); @@ -1985,6 +2031,11 @@ pm_runtime_set_suspended(i2c_dev->dev); pm_runtime_dont_use_autosuspend(i2c_dev->dev); + if (i2c_dev->dma) { + stm32_i2c_dma_free(i2c_dev->dma); + i2c_dev->dma = NULL; + } + clk_free: clk_disable_unprepare(i2c_dev->clk); @@ -1995,21 +2046,21 @@ { struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev); - if (i2c_dev->dma) { - stm32_i2c_dma_free(i2c_dev->dma); - i2c_dev->dma = NULL; - } - i2c_del_adapter(&i2c_dev->adap); pm_runtime_get_sync(i2c_dev->dev); - clk_disable_unprepare(i2c_dev->clk); - pm_runtime_put_noidle(i2c_dev->dev); pm_runtime_disable(i2c_dev->dev); pm_runtime_set_suspended(i2c_dev->dev); pm_runtime_dont_use_autosuspend(i2c_dev->dev); + if (i2c_dev->dma) { + stm32_i2c_dma_free(i2c_dev->dma); + i2c_dev->dma = NULL; + } + + clk_disable_unprepare(i2c_dev->clk); + return 0; } @@ -2019,7 +2070,7 @@ struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev); if (!stm32f7_i2c_is_slave_registered(i2c_dev)) - clk_disable_unprepare(i2c_dev->clk); + clk_disable(i2c_dev->clk); return 0; } @@ -2030,9 +2081,9 @@ int ret; if (!stm32f7_i2c_is_slave_registered(i2c_dev)) { - ret = clk_prepare_enable(i2c_dev->clk); + ret = clk_enable(i2c_dev->clk); if (ret) { - dev_err(dev, "failed to prepare_enable clock\n"); + dev_err(dev, "failed to enable clock\n"); return ret; } } --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-sun6i-p2wi.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-sun6i-p2wi.c @@ -202,6 +202,11 @@ return -EINVAL; } + if (clk_freq == 0) { + dev_err(dev, "clock-frequency is set to 0 in DT\n"); + return -EINVAL; + } + if (of_get_child_count(np) > 1) { dev_err(dev, "P2WI only supports one slave device\n"); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-tegra-bpmp.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-tegra-bpmp.c @@ -80,7 +80,7 @@ flags &= ~I2C_M_RECV_LEN; } - return (flags != 0) ? -EINVAL : 0; + return 0; } /** --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-tegra.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-tegra.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -230,7 +231,6 @@ * @base_phys: physical base address of the I2C controller * @cont_id: I2C controller ID, used for packet header * @irq: IRQ number of transfer complete interrupt - * @irq_disabled: used to track whether or not the interrupt is enabled * @is_dvc: identifies the DVC I2C controller, has a different register layout * @msg_complete: transfer completion notifier * @msg_err: error code for completed message @@ -240,7 +240,6 @@ * @bus_clk_rate: current I2C bus clock rate * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes * @is_multimaster_mode: track if I2C controller is in multi-master mode - * @xfer_lock: lock to serialize transfer submission and processing * @tx_dma_chan: DMA transmit channel * @rx_dma_chan: DMA receive channel * @dma_phys: handle to DMA resources @@ -260,7 +259,6 @@ phys_addr_t base_phys; int cont_id; int irq; - bool irq_disabled; int is_dvc; struct completion msg_complete; int msg_err; @@ -270,8 +268,6 @@ u32 bus_clk_rate; u16 clk_divisor_non_hs_mode; bool is_multimaster_mode; - /* xfer_lock: lock to serialize transfer submission and processing */ - spinlock_t xfer_lock; struct dma_chan *tx_dma_chan; struct dma_chan *rx_dma_chan; dma_addr_t dma_phys; @@ -790,11 +786,6 @@ if (err) return err; - if (i2c_dev->irq_disabled) { - i2c_dev->irq_disabled = false; - enable_irq(i2c_dev->irq); - } - return 0; } @@ -825,18 +816,12 @@ status = i2c_readl(i2c_dev, I2C_INT_STATUS); - spin_lock(&i2c_dev->xfer_lock); if (status == 0) { dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n", i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS), i2c_readl(i2c_dev, I2C_STATUS), i2c_readl(i2c_dev, I2C_CNFG)); i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT; - - if (!i2c_dev->irq_disabled) { - disable_irq_nosync(i2c_dev->irq); - i2c_dev->irq_disabled = true; - } goto err; } @@ -925,7 +910,6 @@ complete(&i2c_dev->msg_complete); done: - spin_unlock(&i2c_dev->xfer_lock); return IRQ_HANDLED; } @@ -999,6 +983,30 @@ i2c_writel(i2c_dev, val, reg); } +static unsigned long +tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev, + struct completion *complete, + unsigned int timeout_ms) +{ + unsigned long ret; + + enable_irq(i2c_dev->irq); + ret = wait_for_completion_timeout(complete, + msecs_to_jiffies(timeout_ms)); + disable_irq(i2c_dev->irq); + + /* + * There is a chance that completion may happen after IRQ + * synchronization, which is done by disable_irq(). + */ + if (ret == 0 && completion_done(complete)) { + dev_warn(i2c_dev->dev, "completion done after timeout\n"); + ret = 1; + } + + return ret; +} + static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap) { struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap); @@ -1020,8 +1028,8 @@ i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG); tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE); - time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - msecs_to_jiffies(50)); + time_left = tegra_i2c_wait_completion_timeout( + i2c_dev, &i2c_dev->msg_complete, 50); if (time_left == 0) { dev_err(i2c_dev->dev, "timed out for bus clear\n"); return -ETIMEDOUT; @@ -1044,7 +1052,6 @@ u32 packet_header; u32 int_mask; unsigned long time_left; - unsigned long flags; size_t xfer_size; u32 *buffer = NULL; int err = 0; @@ -1075,7 +1082,6 @@ */ xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC, i2c_dev->bus_clk_rate); - spin_lock_irqsave(&i2c_dev->xfer_lock, flags); int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST; tegra_i2c_unmask_irq(i2c_dev, int_mask); @@ -1090,7 +1096,7 @@ dev_err(i2c_dev->dev, "starting RX DMA failed, err %d\n", err); - goto unlock; + return err; } } else { @@ -1149,7 +1155,7 @@ dev_err(i2c_dev->dev, "starting TX DMA failed, err %d\n", err); - goto unlock; + return err; } } else { tegra_i2c_fill_tx_fifo(i2c_dev); @@ -1169,15 +1175,10 @@ dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n", i2c_readl(i2c_dev, I2C_INT_MASK)); -unlock: - spin_unlock_irqrestore(&i2c_dev->xfer_lock, flags); - if (dma) { - if (err) - return err; + time_left = tegra_i2c_wait_completion_timeout( + i2c_dev, &i2c_dev->dma_complete, xfer_time); - time_left = wait_for_completion_timeout(&i2c_dev->dma_complete, - msecs_to_jiffies(xfer_time)); if (time_left == 0) { dev_err(i2c_dev->dev, "DMA transfer timeout\n"); dmaengine_terminate_sync(i2c_dev->msg_read ? @@ -1202,13 +1203,13 @@ i2c_dev->tx_dma_chan); } - time_left = wait_for_completion_timeout(&i2c_dev->msg_complete, - msecs_to_jiffies(xfer_time)); + time_left = tegra_i2c_wait_completion_timeout( + i2c_dev, &i2c_dev->msg_complete, xfer_time); + tegra_i2c_mask_irq(i2c_dev, int_mask); if (time_left == 0) { dev_err(i2c_dev->dev, "i2c transfer timed out\n"); - tegra_i2c_init(i2c_dev, true); return -ETIMEDOUT; } @@ -1568,7 +1569,6 @@ I2C_PACKET_HEADER_SIZE; init_completion(&i2c_dev->msg_complete); init_completion(&i2c_dev->dma_complete); - spin_lock_init(&i2c_dev->xfer_lock); if (!i2c_dev->hw->has_single_clk_source) { fast_clk = devm_clk_get(&pdev->dev, "fast-clk"); @@ -1608,14 +1608,18 @@ } pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) + if (!pm_runtime_enabled(&pdev->dev)) { ret = tegra_i2c_runtime_resume(&pdev->dev); - else + if (ret < 0) { + dev_err(&pdev->dev, "runtime resume failed\n"); + goto unprepare_div_clk; + } + } else { ret = pm_runtime_get_sync(i2c_dev->dev); - - if (ret < 0) { - dev_err(&pdev->dev, "runtime resume failed\n"); - goto unprepare_div_clk; + if (ret < 0) { + dev_err(&pdev->dev, "runtime resume failed\n"); + goto disable_rpm; + } } if (i2c_dev->is_multimaster_mode) { @@ -1623,7 +1627,7 @@ if (ret < 0) { dev_err(i2c_dev->dev, "div_clk enable failed %d\n", ret); - goto disable_rpm; + goto put_rpm; } } @@ -1640,6 +1644,8 @@ goto release_dma; } + irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN); + ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev); if (ret) { @@ -1671,11 +1677,16 @@ if (i2c_dev->is_multimaster_mode) clk_disable(i2c_dev->div_clk); -disable_rpm: - pm_runtime_disable(&pdev->dev); - if (!pm_runtime_status_suspended(&pdev->dev)) +put_rpm: + if (pm_runtime_enabled(&pdev->dev)) + pm_runtime_put_sync(&pdev->dev); + else tegra_i2c_runtime_suspend(&pdev->dev); +disable_rpm: + if (pm_runtime_enabled(&pdev->dev)) + pm_runtime_disable(&pdev->dev); + unprepare_div_clk: clk_unprepare(i2c_dev->div_clk); @@ -1710,10 +1721,14 @@ static int __maybe_unused tegra_i2c_suspend(struct device *dev) { struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); + int err = 0; i2c_mark_adapter_suspended(&i2c_dev->adapter); - return 0; + if (!pm_runtime_status_suspended(dev)) + err = tegra_i2c_runtime_suspend(dev); + + return err; } static int __maybe_unused tegra_i2c_resume(struct device *dev) @@ -1721,6 +1736,10 @@ struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev); int err; + /* + * We need to ensure that clocks are enabled so that registers can be + * restored in tegra_i2c_init(). + */ err = tegra_i2c_runtime_resume(dev); if (err) return err; @@ -1729,9 +1748,16 @@ if (err) return err; - err = tegra_i2c_runtime_suspend(dev); - if (err) - return err; + /* + * In case we are runtime suspended, disable clocks again so that we + * don't unbalance the clock reference counts during the next runtime + * resume transition. + */ + if (pm_runtime_status_suspended(dev)) { + err = tegra_i2c_runtime_suspend(dev); + if (err) + return err; + } i2c_mark_adapter_resumed(&i2c_dev->adapter); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-thunderx-pcidrv.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-thunderx-pcidrv.c @@ -208,6 +208,7 @@ i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info; i2c->adap.dev.parent = dev; i2c->adap.dev.of_node = pdev->dev.of_node; + i2c->adap.dev.fwnode = dev->fwnode; snprintf(i2c->adap.name, sizeof(i2c->adap.name), "Cavium ThunderX i2c adapter at %s", dev_name(dev)); i2c_set_adapdata(&i2c->adap, i2c); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-xgene-slimpro.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-xgene-slimpro.c @@ -308,6 +308,9 @@ u32 msg[3]; int rc; + if (writelen > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + memcpy(ctx->dma_buffer, data, writelen); paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen, DMA_TO_DEVICE); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-xiic.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-xiic.c @@ -353,6 +353,9 @@ struct xiic_i2c *i2c = dev_id; u32 pend, isr, ier; u32 clr = 0; + int xfer_more = 0; + int wakeup_req = 0; + int wakeup_code = 0; /* Get the interrupt Status from the IPIF. There is no clearing of * interrupts in the IPIF. Interrupts must be cleared at the source. @@ -389,10 +392,16 @@ */ xiic_reinit(i2c); - if (i2c->rx_msg) - xiic_wakeup(i2c, STATE_ERROR); - if (i2c->tx_msg) - xiic_wakeup(i2c, STATE_ERROR); + if (i2c->rx_msg) { + wakeup_req = 1; + wakeup_code = STATE_ERROR; + } + if (i2c->tx_msg) { + wakeup_req = 1; + wakeup_code = STATE_ERROR; + } + /* don't try to handle other events */ + goto out; } if (pend & XIIC_INTR_RX_FULL_MASK) { /* Receive register/FIFO is full */ @@ -426,8 +435,7 @@ i2c->tx_msg++; dev_dbg(i2c->adap.dev.parent, "%s will start next...\n", __func__); - - __xiic_start_xfer(i2c); + xfer_more = 1; } } } @@ -441,11 +449,13 @@ if (!i2c->tx_msg) goto out; - if ((i2c->nmsgs == 1) && !i2c->rx_msg && - xiic_tx_space(i2c) == 0) - xiic_wakeup(i2c, STATE_DONE); + wakeup_req = 1; + + if (i2c->nmsgs == 1 && !i2c->rx_msg && + xiic_tx_space(i2c) == 0) + wakeup_code = STATE_DONE; else - xiic_wakeup(i2c, STATE_ERROR); + wakeup_code = STATE_ERROR; } if (pend & (XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_HALF_MASK)) { /* Transmit register/FIFO is empty or ½ empty */ @@ -459,17 +469,20 @@ goto out; } - xiic_fill_tx_fifo(i2c); - - /* current message sent and there is space in the fifo */ - if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) { + if (xiic_tx_space(i2c)) { + xiic_fill_tx_fifo(i2c); + } else { + /* current message fully written */ dev_dbg(i2c->adap.dev.parent, "%s end of message sent, nmsgs: %d\n", __func__, i2c->nmsgs); - if (i2c->nmsgs > 1) { + /* Don't move onto the next message until the TX FIFO empties, + * to ensure that a NAK is not missed. + */ + if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) { i2c->nmsgs--; i2c->tx_msg++; - __xiic_start_xfer(i2c); + xfer_more = 1; } else { xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); @@ -477,16 +490,19 @@ "%s Got TX IRQ but no more to do...\n", __func__); } - } else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1)) - /* current frame is sent and is last, - * make sure to disable tx half - */ - xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK); + } } out: dev_dbg(i2c->adap.dev.parent, "%s clr: 0x%x\n", __func__, clr); xiic_setreg32(i2c, XIIC_IISR_OFFSET, clr); + if (xfer_more) + __xiic_start_xfer(i2c); + if (wakeup_req) + xiic_wakeup(i2c, wakeup_code); + + WARN_ON(xfer_more && wakeup_req); + mutex_unlock(&i2c->lock); return IRQ_HANDLED; } @@ -715,7 +731,6 @@ static const struct i2c_adapter xiic_adapter = { .owner = THIS_MODULE, - .name = DRIVER_NAME, .class = I2C_CLASS_DEPRECATED, .algo = &xiic_algorithm, .quirks = &xiic_quirks, @@ -752,6 +767,8 @@ i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &pdev->dev; i2c->adap.dev.of_node = pdev->dev.of_node; + snprintf(i2c->adap.name, sizeof(i2c->adap.name), + DRIVER_NAME " %s", pdev->name); mutex_init(&i2c->lock); init_waitqueue_head(&i2c->wait); @@ -883,6 +900,7 @@ module_platform_driver(xiic_i2c_driver); +MODULE_ALIAS("platform:" DRIVER_NAME); MODULE_AUTHOR("info@mocean-labs.com"); MODULE_DESCRIPTION("Xilinx I2C bus driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/i2c/busses/i2c-xlr.c +++ linux-oracle-5.4.0/drivers/i2c/busses/i2c-xlr.c @@ -433,11 +433,15 @@ i2c_set_adapdata(&priv->adap, priv); ret = i2c_add_numbered_adapter(&priv->adap); if (ret < 0) - return ret; + goto err_unprepare_clk; platform_set_drvdata(pdev, priv); dev_info(&priv->adap.dev, "Added I2C Bus.\n"); return 0; + +err_unprepare_clk: + clk_unprepare(clk); + return ret; } static int xlr_i2c_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-core-acpi.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-core-acpi.c @@ -264,6 +264,7 @@ void i2c_acpi_register_devices(struct i2c_adapter *adap) { acpi_status status; + acpi_handle handle; if (!has_acpi_companion(&adap->dev)) return; @@ -274,6 +275,15 @@ adap, NULL); if (ACPI_FAILURE(status)) dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); + + if (!adap->dev.parent) + return; + + handle = ACPI_HANDLE(adap->dev.parent); + if (!handle) + return; + + acpi_walk_dep_device_list(handle); } const struct acpi_device_id * @@ -394,9 +404,17 @@ static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) { struct device *dev; + struct i2c_client *client; dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); - return dev ? i2c_verify_client(dev) : NULL; + if (!dev) + return NULL; + + client = i2c_verify_client(dev); + if (!client) + put_device(dev); + + return client; } static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, @@ -418,6 +436,7 @@ break; i2c_acpi_register_device(adapter, adev, &info); + put_device(&adapter->dev); break; case ACPI_RECONFIG_DEVICE_REMOVE: if (!acpi_device_enumerated(adev)) @@ -729,7 +748,6 @@ return -ENOMEM; } - acpi_walk_dep_device_list(handle); return 0; } --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-core-base.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-core-base.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -186,10 +187,11 @@ * If we can set SDA, we will always create a STOP to ensure additional * pulses will do no harm. This is achieved by letting SDA follow SCL * half a cycle later. Check the 'incomplete_write_byte' fault injector - * for details. + * for details. Note that we must honour tsu:sto, 4us, but lets use 5us + * here for simplicity. */ bri->set_scl(adap, scl); - ndelay(RECOVERY_NDELAY / 2); + ndelay(RECOVERY_NDELAY); if (bri->set_sda) bri->set_sda(adap, scl); ndelay(RECOVERY_NDELAY / 2); @@ -211,7 +213,13 @@ scl = !scl; bri->set_scl(adap, scl); /* Creating STOP again, see above */ - ndelay(RECOVERY_NDELAY / 2); + if (scl) { + /* Honour minimum tsu:sto */ + ndelay(RECOVERY_NDELAY); + } else { + /* Honour minimum tf and thd:dat */ + ndelay(RECOVERY_NDELAY / 2); + } if (bri->set_sda) bri->set_sda(adap, scl); ndelay(RECOVERY_NDELAY / 2); @@ -247,13 +255,14 @@ static void i2c_init_recovery(struct i2c_adapter *adap) { struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; - char *err_str; + char *err_str, *err_level = KERN_ERR; if (!bri) return; if (!bri->recover_bus) { - err_str = "no recover_bus() found"; + err_str = "no suitable method provided"; + err_level = KERN_DEBUG; goto err; } @@ -283,7 +292,7 @@ return; err: - dev_err(&adap->dev, "Not using recovery: %s\n", err_str); + dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str); adap->bus_recovery_info = NULL; } @@ -331,8 +340,10 @@ } else if (ACPI_COMPANION(dev)) { irq = i2c_acpi_get_irq(client); } - if (irq == -EPROBE_DEFER) - return irq; + if (irq == -EPROBE_DEFER) { + status = irq; + goto put_sync_adapter; + } if (irq < 0) irq = 0; @@ -345,16 +356,20 @@ * or ACPI ID table is supplied for the probing device. */ if (!driver->id_table && - !i2c_acpi_match_device(dev->driver->acpi_match_table, client) && - !i2c_of_match_device(dev->driver->of_match_table, client)) - return -ENODEV; + !acpi_driver_match_device(dev, dev->driver) && + !i2c_of_match_device(dev->driver->of_match_table, client)) { + status = -ENODEV; + goto put_sync_adapter; + } if (client->flags & I2C_CLIENT_WAKE) { int wakeirq; wakeirq = of_irq_get_byname(dev->of_node, "wakeup"); - if (wakeirq == -EPROBE_DEFER) - return wakeirq; + if (wakeirq == -EPROBE_DEFER) { + status = wakeirq; + goto put_sync_adapter; + } device_init_wakeup(&client->dev, true); @@ -401,6 +416,10 @@ err_clear_wakeup_irq: dev_pm_clear_wake_irq(&client->dev); device_init_wakeup(&client->dev, false); +put_sync_adapter: + if (client->flags & I2C_CLIENT_HOST_NOTIFY) + pm_runtime_put_sync(&client->adapter->dev); + return status; } @@ -441,6 +460,8 @@ driver = to_i2c_driver(dev->driver); if (driver->shutdown) driver->shutdown(client); + else if (client->irq > 0) + disable_irq(client->irq); } static void i2c_client_dev_release(struct device *dev) @@ -1368,8 +1389,8 @@ /* create pre-declared device nodes */ of_i2c_register_devices(adap); - i2c_acpi_register_devices(adap); i2c_acpi_install_space_handler(adap); + i2c_acpi_register_devices(adap); if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); @@ -1944,13 +1965,18 @@ * Returns negative errno, else the number of messages executed. * * Adapter lock must be held when calling this function. No debug logging - * takes place. adap->algo->master_xfer existence isn't checked. + * takes place. */ int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) { unsigned long orig_jiffies; int ret, try; + if (!adap->algo->master_xfer) { + dev_dbg(&adap->dev, "I2C level transfers not supported\n"); + return -EOPNOTSUPP; + } + if (WARN_ON(!msgs || num < 1)) return -EINVAL; @@ -2017,11 +2043,6 @@ { int ret; - if (!adap->algo->master_xfer) { - dev_dbg(&adap->dev, "I2C level transfers not supported\n"); - return -EOPNOTSUPP; - } - /* REVISIT the fault reporting model here is weak: * * - When we get an error after receiving N bytes from a slave, @@ -2337,8 +2358,9 @@ if (!adap) return; - put_device(&adap->dev); module_put(adap->owner); + /* Should be last, otherwise we risk use-after-free with 'adap' */ + put_device(&adap->dev); } EXPORT_SYMBOL(i2c_put_adapter); --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-core-slave.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-core-slave.c @@ -18,10 +18,8 @@ { int ret; - if (!client || !slave_cb) { - WARN(1, "insufficient data\n"); + if (WARN(IS_ERR_OR_NULL(client) || !slave_cb, "insufficient data\n")) return -EINVAL; - } if (!(client->flags & I2C_CLIENT_SLAVE)) dev_warn(&client->dev, "%s: client slave flag not set. You might see address collisions\n", @@ -60,6 +58,9 @@ { int ret; + if (IS_ERR_OR_NULL(client)) + return -EINVAL; + if (!client->adapter->algo->unreg_slave) { dev_err(&client->dev, "%s: not supported by adapter\n", __func__); return -EOPNOTSUPP; --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-core-smbus.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-core-smbus.c @@ -495,6 +495,13 @@ break; case I2C_SMBUS_BLOCK_DATA: case I2C_SMBUS_BLOCK_PROC_CALL: + if (msg[1].buf[0] > I2C_SMBUS_BLOCK_MAX) { + dev_err(&adapter->dev, + "Invalid block size returned: %d\n", + msg[1].buf[0]); + status = -EPROTO; + goto cleanup; + } for (i = 0; i < msg[1].buf[0] + 1; i++) data->block[i] = msg[1].buf[i]; break; --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-core.h +++ linux-oracle-5.4.0/drivers/i2c/i2c-core.h @@ -3,6 +3,7 @@ * i2c-core.h - interfaces internal to the I2C framework */ +#include #include struct i2c_devinfo { @@ -29,7 +30,8 @@ */ static inline bool i2c_in_atomic_xfer_mode(void) { - return system_state > SYSTEM_RUNNING && irqs_disabled(); + return system_state > SYSTEM_RUNNING && + (IS_ENABLED(CONFIG_PREEMPT_COUNT) ? !preemptible() : irqs_disabled()); } static inline int __i2c_lock_bus_helper(struct i2c_adapter *adap) --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-dev.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-dev.c @@ -40,7 +40,7 @@ struct i2c_dev { struct list_head list; struct i2c_adapter *adap; - struct device *dev; + struct device dev; struct cdev cdev; }; @@ -84,12 +84,14 @@ return i2c_dev; } -static void put_i2c_dev(struct i2c_dev *i2c_dev) +static void put_i2c_dev(struct i2c_dev *i2c_dev, bool del_cdev) { spin_lock(&i2c_dev_list_lock); list_del(&i2c_dev->list); spin_unlock(&i2c_dev_list_lock); - kfree(i2c_dev); + if (del_cdev) + cdev_device_del(&i2c_dev->cdev, &i2c_dev->dev); + put_device(&i2c_dev->dev); } static ssize_t name_show(struct device *dev, @@ -139,7 +141,7 @@ if (count > 8192) count = 8192; - tmp = kmalloc(count, GFP_KERNEL); + tmp = kzalloc(count, GFP_KERNEL); if (tmp == NULL) return -ENOMEM; @@ -148,7 +150,8 @@ ret = i2c_master_recv(client, tmp, count); if (ret >= 0) - ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret; + if (copy_to_user(buf, tmp, ret)) + ret = -EFAULT; kfree(tmp); return ret; } @@ -438,8 +441,13 @@ sizeof(rdwr_arg))) return -EFAULT; - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ + if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0) + return -EINVAL; + + /* + * Put an arbitrary limit on the number of messages that can + * be sent at once + */ if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) return -EINVAL; @@ -528,6 +536,9 @@ sizeof(rdwr_arg))) return -EFAULT; + if (!rdwr_arg.msgs || rdwr_arg.nmsgs == 0) + return -EINVAL; + if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) return -EINVAL; @@ -628,6 +639,14 @@ static struct class *i2c_dev_class; +static void i2cdev_dev_release(struct device *dev) +{ + struct i2c_dev *i2c_dev; + + i2c_dev = container_of(dev, struct i2c_dev, dev); + kfree(i2c_dev); +} + static int i2cdev_attach_adapter(struct device *dev, void *dummy) { struct i2c_adapter *adap; @@ -644,27 +663,23 @@ cdev_init(&i2c_dev->cdev, &i2cdev_fops); i2c_dev->cdev.owner = THIS_MODULE; - res = cdev_add(&i2c_dev->cdev, MKDEV(I2C_MAJOR, adap->nr), 1); - if (res) - goto error_cdev; - - /* register this i2c device with the driver core */ - i2c_dev->dev = device_create(i2c_dev_class, &adap->dev, - MKDEV(I2C_MAJOR, adap->nr), NULL, - "i2c-%d", adap->nr); - if (IS_ERR(i2c_dev->dev)) { - res = PTR_ERR(i2c_dev->dev); - goto error; + + device_initialize(&i2c_dev->dev); + i2c_dev->dev.devt = MKDEV(I2C_MAJOR, adap->nr); + i2c_dev->dev.class = i2c_dev_class; + i2c_dev->dev.parent = &adap->dev; + i2c_dev->dev.release = i2cdev_dev_release; + dev_set_name(&i2c_dev->dev, "i2c-%d", adap->nr); + + res = cdev_device_add(&i2c_dev->cdev, &i2c_dev->dev); + if (res) { + put_i2c_dev(i2c_dev, false); + return res; } pr_debug("i2c-dev: adapter [%s] registered as minor %d\n", adap->name, adap->nr); return 0; -error: - cdev_del(&i2c_dev->cdev); -error_cdev: - put_i2c_dev(i2c_dev); - return res; } static int i2cdev_detach_adapter(struct device *dev, void *dummy) @@ -680,9 +695,7 @@ if (!i2c_dev) /* attach_adapter must have failed */ return 0; - cdev_del(&i2c_dev->cdev); - put_i2c_dev(i2c_dev); - device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, adap->nr)); + put_i2c_dev(i2c_dev, true); pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); return 0; --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-mux.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-mux.c @@ -340,7 +340,7 @@ priv->adap.lock_ops = &i2c_parent_lock_ops; /* Sanity check on class */ - if (i2c_mux_parent_classes(parent) & class) + if (i2c_mux_parent_classes(parent) & class & ~I2C_CLASS_DEPRECATED) dev_err(&parent->dev, "Segment %d behind mux can't share classes with ancestors\n", chan_id); --- linux-oracle-5.4.0.orig/drivers/i2c/i2c-smbus.c +++ linux-oracle-5.4.0/drivers/i2c/i2c-smbus.c @@ -33,6 +33,7 @@ struct i2c_client *client = i2c_verify_client(dev); struct alert_data *data = addrp; struct i2c_driver *driver; + int ret; if (!client || client->addr != data->addr) return 0; @@ -46,16 +47,47 @@ device_lock(dev); if (client->dev.driver) { driver = to_i2c_driver(client->dev.driver); - if (driver->alert) + if (driver->alert) { + /* Stop iterating after we find the device */ driver->alert(client, data->type, data->data); - else + ret = -EBUSY; + } else { dev_warn(&client->dev, "no driver alert()!\n"); - } else + ret = -EOPNOTSUPP; + } + } else { dev_dbg(&client->dev, "alert with no driver\n"); + ret = -ENODEV; + } + device_unlock(dev); + + return ret; +} + +/* Same as above, but call back all drivers with alert handler */ + +static int smbus_do_alert_force(struct device *dev, void *addrp) +{ + struct i2c_client *client = i2c_verify_client(dev); + struct alert_data *data = addrp; + struct i2c_driver *driver; + + if (!client || (client->flags & I2C_CLIENT_TEN)) + return 0; + + /* + * Drivers should either disable alerts, or provide at least + * a minimal handler. Lock so the driver won't change. + */ + device_lock(dev); + if (client->dev.driver) { + driver = to_i2c_driver(client->dev.driver); + if (driver->alert) + driver->alert(client, data->type, data->data); + } device_unlock(dev); - /* Stop iterating after we find the device */ - return -EBUSY; + return 0; } /* @@ -66,7 +98,7 @@ { struct i2c_smbus_alert *alert = d; struct i2c_client *ara; - unsigned short prev_addr = 0; /* Not a valid address */ + unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */ ara = alert->ara; @@ -90,17 +122,28 @@ data.addr = status >> 1; data.type = I2C_PROTOCOL_SMBUS_ALERT; - if (data.addr == prev_addr) { - dev_warn(&ara->dev, "Duplicate SMBALERT# from dev " - "0x%02x, skipping\n", data.addr); - break; - } dev_dbg(&ara->dev, "SMBALERT# from dev 0x%02x, flag %d\n", data.addr, data.data); /* Notify driver for the device which issued the alert */ - device_for_each_child(&ara->adapter->dev, &data, - smbus_do_alert); + status = device_for_each_child(&ara->adapter->dev, &data, + smbus_do_alert); + /* + * If we read the same address more than once, and the alert + * was not handled by a driver, it won't do any good to repeat + * the loop because it will never terminate. Try again, this + * time calling the alert handlers of all devices connected to + * the bus, and abort the loop afterwards. If this helps, we + * are all set. If it doesn't, there is nothing else we can do, + * so we might as well abort the loop. + * Note: This assumes that a driver with alert handler handles + * the alert properly and clears it if necessary. + */ + if (data.addr == prev_addr && status != -EBUSY) { + device_for_each_child(&ara->adapter->dev, &data, + smbus_do_alert_force); + break; + } prev_addr = data.addr; } --- linux-oracle-5.4.0.orig/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ linux-oracle-5.4.0/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -61,7 +61,7 @@ if (ret) goto err; - adap = of_find_i2c_adapter_by_node(priv->chan[new_chan].parent_np); + adap = of_get_i2c_adapter_by_node(priv->chan[new_chan].parent_np); if (!adap) { ret = -ENODEV; goto err_with_revert; @@ -243,6 +243,10 @@ props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); + if (!props[i].name || !props[i].value) { + err = -ENOMEM; + goto err_rollback; + } props[i].length = 3; of_changeset_init(&priv->chan[i].chgset); @@ -257,11 +261,13 @@ pm_runtime_no_callbacks(&pdev->dev); /* switch to first parent as active master */ - i2c_demux_activate_master(priv, 0); + err = i2c_demux_activate_master(priv, 0); + if (err) + goto err_rollback; err = device_create_file(&pdev->dev, &dev_attr_available_masters); if (err) - goto err_rollback; + goto err_rollback_activation; err = device_create_file(&pdev->dev, &dev_attr_current_master); if (err) @@ -271,6 +277,8 @@ err_rollback_available: device_remove_file(&pdev->dev, &dev_attr_available_masters); +err_rollback_activation: + i2c_demux_deactivate_master(priv); err_rollback: for (j = 0; j < i; j++) { of_node_put(priv->chan[j].parent_np); --- linux-oracle-5.4.0.orig/drivers/i2c/muxes/i2c-mux-gpmux.c +++ linux-oracle-5.4.0/drivers/i2c/muxes/i2c-mux-gpmux.c @@ -52,7 +52,7 @@ dev_err(dev, "Cannot parse i2c-parent\n"); return ERR_PTR(-ENODEV); } - parent = of_find_i2c_adapter_by_node(parent_np); + parent = of_get_i2c_adapter_by_node(parent_np); of_node_put(parent_np); if (!parent) return ERR_PTR(-EPROBE_DEFER); @@ -138,6 +138,7 @@ return 0; err_children: + of_node_put(child); i2c_mux_del_adapters(muxc); err_parent: i2c_put_adapter(parent); --- linux-oracle-5.4.0.orig/drivers/i2c/muxes/i2c-mux-pinctrl.c +++ linux-oracle-5.4.0/drivers/i2c/muxes/i2c-mux-pinctrl.c @@ -62,7 +62,7 @@ dev_err(dev, "Cannot parse i2c-parent\n"); return ERR_PTR(-ENODEV); } - parent = of_find_i2c_adapter_by_node(parent_np); + parent = of_get_i2c_adapter_by_node(parent_np); of_node_put(parent_np); if (!parent) return ERR_PTR(-EPROBE_DEFER); --- linux-oracle-5.4.0.orig/drivers/i3c/master.c +++ linux-oracle-5.4.0/drivers/i3c/master.c @@ -257,7 +257,8 @@ struct i3c_device_info devinfo; u16 manuf, part, ext; - i3c_device_get_info(i3cdev, &devinfo); + if (i3cdev->desc) + devinfo = i3cdev->desc->info; manuf = I3C_PID_MANUF_ID(devinfo.pid); part = I3C_PID_PART_ID(devinfo.pid); ext = I3C_PID_EXTRA_INFO(devinfo.pid); @@ -1263,7 +1264,7 @@ I3C_ADDR_SLOT_FREE); if (dev->boardinfo && dev->boardinfo->init_dyn_addr) - i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr, + i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr, I3C_ADDR_SLOT_FREE); } @@ -1469,9 +1470,11 @@ desc->dev->dev.of_node = desc->boardinfo->of_node; ret = device_register(&desc->dev->dev); - if (ret) + if (ret) { dev_err(&master->dev, "Failed to add I3C device (err = %d)\n", ret); + put_device(&desc->dev->dev); + } } } @@ -1760,6 +1763,21 @@ i3c_master_detach_free_devs(master); } +static void i3c_master_attach_boardinfo(struct i3c_dev_desc *i3cdev) +{ + struct i3c_master_controller *master = i3cdev->common.master; + struct i3c_dev_boardinfo *i3cboardinfo; + + list_for_each_entry(i3cboardinfo, &master->boardinfo.i3c, node) { + if (i3cdev->info.pid != i3cboardinfo->pid) + continue; + + i3cdev->boardinfo = i3cboardinfo; + i3cdev->info.static_addr = i3cboardinfo->static_addr; + return; + } +} + static struct i3c_dev_desc * i3c_master_search_i3c_dev_duplicate(struct i3c_dev_desc *refdev) { @@ -1815,10 +1833,10 @@ if (ret) goto err_detach_dev; + i3c_master_attach_boardinfo(newdev); + olddev = i3c_master_search_i3c_dev_duplicate(newdev); if (olddev) { - newdev->boardinfo = olddev->boardinfo; - newdev->info.static_addr = olddev->info.static_addr; newdev->dev = olddev->dev; if (newdev->dev) newdev->dev->desc = newdev; --- linux-oracle-5.4.0.orig/drivers/i3c/master/i3c-master-cdns.c +++ linux-oracle-5.4.0/drivers/i3c/master/i3c-master-cdns.c @@ -74,7 +74,8 @@ #define PRESCL_CTRL0 0x14 #define PRESCL_CTRL0_I2C(x) ((x) << 16) #define PRESCL_CTRL0_I3C(x) (x) -#define PRESCL_CTRL0_MAX GENMASK(9, 0) +#define PRESCL_CTRL0_I3C_MAX GENMASK(9, 0) +#define PRESCL_CTRL0_I2C_MAX GENMASK(15, 0) #define PRESCL_CTRL1 0x18 #define PRESCL_CTRL1_PP_LOW_MASK GENMASK(15, 8) @@ -189,7 +190,7 @@ #define SLV_STATUS1_HJ_DIS BIT(18) #define SLV_STATUS1_MR_DIS BIT(17) #define SLV_STATUS1_PROT_ERR BIT(16) -#define SLV_STATUS1_DA(x) (((s) & GENMASK(15, 9)) >> 9) +#define SLV_STATUS1_DA(s) (((s) & GENMASK(15, 9)) >> 9) #define SLV_STATUS1_HAS_DA BIT(8) #define SLV_STATUS1_DDR_RX_FULL BIT(7) #define SLV_STATUS1_DDR_TX_FULL BIT(6) @@ -1212,7 +1213,7 @@ return -EINVAL; pres = DIV_ROUND_UP(sysclk_rate, (bus->scl_rate.i3c * 4)) - 1; - if (pres > PRESCL_CTRL0_MAX) + if (pres > PRESCL_CTRL0_I3C_MAX) return -ERANGE; bus->scl_rate.i3c = sysclk_rate / ((pres + 1) * 4); @@ -1225,7 +1226,7 @@ max_i2cfreq = bus->scl_rate.i2c; pres = (sysclk_rate / (max_i2cfreq * 5)) - 1; - if (pres > PRESCL_CTRL0_MAX) + if (pres > PRESCL_CTRL0_I2C_MAX) return -ERANGE; bus->scl_rate.i2c = sysclk_rate / ((pres + 1) * 5); @@ -1580,21 +1581,23 @@ /* Device ID0 is reserved to describe this master. */ master->maxdevs = CONF_STATUS0_DEVS_NUM(val); master->free_rr_slots = GENMASK(master->maxdevs, 1); + master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val); + master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val); val = readl(master->regs + CONF_STATUS1); master->caps.cmdfifodepth = CONF_STATUS1_CMD_DEPTH(val); master->caps.rxfifodepth = CONF_STATUS1_RX_DEPTH(val); master->caps.txfifodepth = CONF_STATUS1_TX_DEPTH(val); - master->caps.ibirfifodepth = CONF_STATUS0_IBIR_DEPTH(val); - master->caps.cmdrfifodepth = CONF_STATUS0_CMDR_DEPTH(val); spin_lock_init(&master->ibi.lock); master->ibi.num_slots = CONF_STATUS1_IBI_HW_RES(val); master->ibi.slots = devm_kcalloc(&pdev->dev, master->ibi.num_slots, sizeof(*master->ibi.slots), GFP_KERNEL); - if (!master->ibi.slots) + if (!master->ibi.slots) { + ret = -ENOMEM; goto err_disable_sysclk; + } writel(IBIR_THR(1), master->regs + CMD_IBI_THR_CTRL); writel(MST_INT_IBIR_THR, master->regs + MST_IER); --- linux-oracle-5.4.0.orig/drivers/ide/cmd64x.c +++ linux-oracle-5.4.0/drivers/ide/cmd64x.c @@ -66,6 +66,9 @@ struct ide_timing t; u8 arttim = 0; + if (drive->dn >= ARRAY_SIZE(drwtim_regs)) + return; + ide_timing_compute(drive, mode, &t, T, 0); /* --- linux-oracle-5.4.0.orig/drivers/ide/ide-acpi.c +++ linux-oracle-5.4.0/drivers/ide/ide-acpi.c @@ -180,7 +180,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) { struct device *dev = hwif->gendev.parent; - acpi_handle uninitialized_var(dev_handle); + acpi_handle dev_handle; u64 pcidevfn; acpi_handle chan_handle; int err; --- linux-oracle-5.4.0.orig/drivers/ide/ide-atapi.c +++ linux-oracle-5.4.0/drivers/ide/ide-atapi.c @@ -223,7 +223,6 @@ sense_rq->rq_disk = rq->rq_disk; sense_rq->cmd_flags = REQ_OP_DRV_IN; ide_req(sense_rq)->type = ATA_PRIV_SENSE; - sense_rq->rq_flags |= RQF_PREEMPT; req->cmd[0] = GPCMD_REQUEST_SENSE; req->cmd[4] = cmd_len; @@ -609,7 +608,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) { - struct ide_atapi_pc *uninitialized_var(pc); + struct ide_atapi_pc *pc; ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; ide_expiry_t *expiry; --- linux-oracle-5.4.0.orig/drivers/ide/ide-io-std.c +++ linux-oracle-5.4.0/drivers/ide/ide-io-std.c @@ -173,7 +173,7 @@ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { - unsigned long uninitialized_var(flags); + unsigned long flags; if ((io_32bit & 2) && !mmio) { local_irq_save(flags); @@ -217,7 +217,7 @@ u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { - unsigned long uninitialized_var(flags); + unsigned long flags; if ((io_32bit & 2) && !mmio) { local_irq_save(flags); --- linux-oracle-5.4.0.orig/drivers/ide/ide-io.c +++ linux-oracle-5.4.0/drivers/ide/ide-io.c @@ -512,11 +512,6 @@ * above to return us whatever is in the queue. Since we call * ide_do_request() ourselves, we end up taking requests while * the queue is blocked... - * - * We let requests forced at head of queue with ide-preempt - * though. I hope that doesn't happen too much, hopefully not - * unless the subdriver triggers such a thing in its own PM - * state machine. */ if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && ata_pm_request(rq) == 0 && @@ -619,12 +614,12 @@ void ide_timer_expiry (struct timer_list *t) { ide_hwif_t *hwif = from_timer(hwif, t, timer); - ide_drive_t *uninitialized_var(drive); + ide_drive_t *drive; ide_handler_t *handler; unsigned long flags; int wait = -1; int plug_device = 0; - struct request *uninitialized_var(rq_in_flight); + struct request *rq_in_flight; spin_lock_irqsave(&hwif->lock, flags); @@ -777,13 +772,13 @@ { ide_hwif_t *hwif = (ide_hwif_t *)dev_id; struct ide_host *host = hwif->host; - ide_drive_t *uninitialized_var(drive); + ide_drive_t *drive; ide_handler_t *handler; unsigned long flags; ide_startstop_t startstop; irqreturn_t irq_ret = IRQ_NONE; int plug_device = 0; - struct request *uninitialized_var(rq_in_flight); + struct request *rq_in_flight; if (host->host_flags & IDE_HFLAG_SERIALIZE) { if (hwif != host->cur_port) --- linux-oracle-5.4.0.orig/drivers/ide/ide-sysfs.c +++ linux-oracle-5.4.0/drivers/ide/ide-sysfs.c @@ -131,7 +131,7 @@ int ide_sysfs_register_port(ide_hwif_t *hwif) { - int i, uninitialized_var(rc); + int i, rc; for (i = 0; ide_port_attrs[i]; i++) { rc = device_create_file(hwif->portdev, ide_port_attrs[i]); --- linux-oracle-5.4.0.orig/drivers/ide/serverworks.c +++ linux-oracle-5.4.0/drivers/ide/serverworks.c @@ -115,6 +115,9 @@ struct pci_dev *dev = to_pci_dev(hwif->dev); const u8 pio = drive->pio_mode - XFER_PIO_0; + if (drive->dn >= ARRAY_SIZE(drive_pci)) + return; + pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]); if (svwks_csb_check(dev)) { @@ -141,6 +144,9 @@ u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0; + if (drive->dn >= ARRAY_SIZE(drive_pci2)) + return; + pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing); pci_read_config_byte(dev, 0x54, &ultra_enable); --- linux-oracle-5.4.0.orig/drivers/ide/umc8672.c +++ linux-oracle-5.4.0/drivers/ide/umc8672.c @@ -108,7 +108,7 @@ static void umc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) { ide_hwif_t *mate = hwif->mate; - unsigned long uninitialized_var(flags); + unsigned long flags; const u8 pio = drive->pio_mode - XFER_PIO_0; printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", --- linux-oracle-5.4.0.orig/drivers/idle/intel_idle.c +++ linux-oracle-5.4.0/drivers/idle/intel_idle.c @@ -46,11 +46,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include @@ -98,6 +100,12 @@ #define CPUIDLE_FLAG_TLB_FLUSHED 0x10000 /* + * Disable IBRS across idle (when KERNEL_IBRS), is exclusive vs IRQ_ENABLE + * above. + */ +#define CPUIDLE_FLAG_IBRS BIT(16) + +/* * MWAIT takes an 8-bit "hint" in EAX "suggesting" * the C-state (top nibble) and sub-state (bottom nibble) * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc. @@ -107,6 +115,24 @@ #define flg2MWAIT(flags) (((flags) >> 24) & 0xFF) #define MWAIT2flg(eax) ((eax & 0xFF) << 24) +static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + bool smt_active = sched_smt_active(); + u64 spec_ctrl = spec_ctrl_current(); + int ret; + + if (smt_active) + wrmsrl(MSR_IA32_SPEC_CTRL, 0); + + ret = intel_idle(dev, drv, index); + + if (smt_active) + wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); + + return ret; +} + /* * States are indexed by the cstate number, * which is also the index into the MWAIT hint array. @@ -605,7 +631,7 @@ { .name = "C6", .desc = "MWAIT 0x20", - .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 85, .target_residency = 200, .enter = &intel_idle, @@ -613,7 +639,7 @@ { .name = "C7s", .desc = "MWAIT 0x33", - .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x33) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 124, .target_residency = 800, .enter = &intel_idle, @@ -621,7 +647,7 @@ { .name = "C8", .desc = "MWAIT 0x40", - .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 200, .target_residency = 800, .enter = &intel_idle, @@ -629,7 +655,7 @@ { .name = "C9", .desc = "MWAIT 0x50", - .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 480, .target_residency = 5000, .enter = &intel_idle, @@ -637,7 +663,7 @@ { .name = "C10", .desc = "MWAIT 0x60", - .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 890, .target_residency = 5000, .enter = &intel_idle, @@ -666,7 +692,7 @@ { .name = "C6", .desc = "MWAIT 0x20", - .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, + .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED | CPUIDLE_FLAG_IBRS, .exit_latency = 133, .target_residency = 600, .enter = &intel_idle, @@ -1370,6 +1396,11 @@ drv->states[drv->state_count] = /* structure copy */ cpuidle_state_table[cstate]; + if (cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS) && + cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_IBRS) { + drv->states[drv->state_count].enter = intel_idle_ibrs; + } + drv->state_count += 1; } --- linux-oracle-5.4.0.orig/drivers/iio/Kconfig +++ linux-oracle-5.4.0/drivers/iio/Kconfig @@ -70,6 +70,7 @@ source "drivers/iio/accel/Kconfig" source "drivers/iio/adc/Kconfig" +source "drivers/iio/addac/Kconfig" source "drivers/iio/afe/Kconfig" source "drivers/iio/amplifiers/Kconfig" source "drivers/iio/chemical/Kconfig" --- linux-oracle-5.4.0.orig/drivers/iio/Makefile +++ linux-oracle-5.4.0/drivers/iio/Makefile @@ -15,6 +15,7 @@ obj-y += accel/ obj-y += adc/ +obj-y += addac/ obj-y += afe/ obj-y += amplifiers/ obj-y += buffer/ --- linux-oracle-5.4.0.orig/drivers/iio/accel/adis16201.c +++ linux-oracle-5.4.0/drivers/iio/accel/adis16201.c @@ -215,7 +215,7 @@ ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12), ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X, BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), - ADIS_INCLI_CHAN(X, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y, + ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y, BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), IIO_CHAN_SOFT_TIMESTAMP(7) }; --- linux-oracle-5.4.0.orig/drivers/iio/accel/adxl372.c +++ linux-oracle-5.4.0/drivers/iio/accel/adxl372.c @@ -237,6 +237,7 @@ .realbits = 12, \ .storagebits = 16, \ .shift = 4, \ + .endianness = IIO_BE, \ }, \ } --- linux-oracle-5.4.0.orig/drivers/iio/accel/bma180.c +++ linux-oracle-5.4.0/drivers/iio/accel/bma180.c @@ -47,7 +47,7 @@ u8 int_reset_reg, int_reset_mask; u8 sleep_reg, sleep_mask; - u8 bw_reg, bw_mask; + u8 bw_reg, bw_mask, bw_offset; u8 scale_reg, scale_mask; u8 power_reg, power_mask, lowpower_val; u8 int_enable_reg, int_enable_mask; @@ -103,6 +103,7 @@ #define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */ #define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */ +#define BMA250_BW_OFFSET 8 #define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */ #define BMA250_LOWPOWER_MASK BIT(6) #define BMA250_DATA_INTEN_MASK BIT(4) @@ -119,7 +120,11 @@ int scale; int bw; bool pmode; - u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chan[4]; + s64 timestamp __aligned(8); + } scan; }; enum bma180_chan { @@ -237,7 +242,8 @@ for (i = 0; i < data->part_info->num_bw; ++i) { if (data->part_info->bw_table[i] == val) { ret = bma180_set_bits(data, data->part_info->bw_reg, - data->part_info->bw_mask, i); + data->part_info->bw_mask, + i + data->part_info->bw_offset); if (ret) { dev_err(&data->client->dev, "failed to set bandwidth\n"); @@ -629,32 +635,53 @@ static const struct bma180_part_info bma180_part_info[] = { [BMA180] = { - bma180_channels, ARRAY_SIZE(bma180_channels), - bma180_scale_table, ARRAY_SIZE(bma180_scale_table), - bma180_bw_table, ARRAY_SIZE(bma180_bw_table), - BMA180_CTRL_REG0, BMA180_RESET_INT, - BMA180_CTRL_REG0, BMA180_SLEEP, - BMA180_BW_TCS, BMA180_BW, - BMA180_OFFSET_LSB1, BMA180_RANGE, - BMA180_TCO_Z, BMA180_MODE_CONFIG, BMA180_LOW_POWER, - BMA180_CTRL_REG3, BMA180_NEW_DATA_INT, - BMA180_RESET, - bma180_chip_config, - bma180_chip_disable, + .channels = bma180_channels, + .num_channels = ARRAY_SIZE(bma180_channels), + .scale_table = bma180_scale_table, + .num_scales = ARRAY_SIZE(bma180_scale_table), + .bw_table = bma180_bw_table, + .num_bw = ARRAY_SIZE(bma180_bw_table), + .int_reset_reg = BMA180_CTRL_REG0, + .int_reset_mask = BMA180_RESET_INT, + .sleep_reg = BMA180_CTRL_REG0, + .sleep_mask = BMA180_SLEEP, + .bw_reg = BMA180_BW_TCS, + .bw_mask = BMA180_BW, + .scale_reg = BMA180_OFFSET_LSB1, + .scale_mask = BMA180_RANGE, + .power_reg = BMA180_TCO_Z, + .power_mask = BMA180_MODE_CONFIG, + .lowpower_val = BMA180_LOW_POWER, + .int_enable_reg = BMA180_CTRL_REG3, + .int_enable_mask = BMA180_NEW_DATA_INT, + .softreset_reg = BMA180_RESET, + .chip_config = bma180_chip_config, + .chip_disable = bma180_chip_disable, }, [BMA250] = { - bma250_channels, ARRAY_SIZE(bma250_channels), - bma250_scale_table, ARRAY_SIZE(bma250_scale_table), - bma250_bw_table, ARRAY_SIZE(bma250_bw_table), - BMA250_INT_RESET_REG, BMA250_INT_RESET_MASK, - BMA250_POWER_REG, BMA250_SUSPEND_MASK, - BMA250_BW_REG, BMA250_BW_MASK, - BMA250_RANGE_REG, BMA250_RANGE_MASK, - BMA250_POWER_REG, BMA250_LOWPOWER_MASK, 1, - BMA250_INT_ENABLE_REG, BMA250_DATA_INTEN_MASK, - BMA250_RESET_REG, - bma250_chip_config, - bma250_chip_disable, + .channels = bma250_channels, + .num_channels = ARRAY_SIZE(bma250_channels), + .scale_table = bma250_scale_table, + .num_scales = ARRAY_SIZE(bma250_scale_table), + .bw_table = bma250_bw_table, + .num_bw = ARRAY_SIZE(bma250_bw_table), + .int_reset_reg = BMA250_INT_RESET_REG, + .int_reset_mask = BMA250_INT_RESET_MASK, + .sleep_reg = BMA250_POWER_REG, + .sleep_mask = BMA250_SUSPEND_MASK, + .bw_reg = BMA250_BW_REG, + .bw_mask = BMA250_BW_MASK, + .bw_offset = BMA250_BW_OFFSET, + .scale_reg = BMA250_RANGE_REG, + .scale_mask = BMA250_RANGE_MASK, + .power_reg = BMA250_POWER_REG, + .power_mask = BMA250_LOWPOWER_MASK, + .lowpower_val = 1, + .int_enable_reg = BMA250_INT_ENABLE_REG, + .int_enable_mask = BMA250_DATA_INTEN_MASK, + .softreset_reg = BMA250_RESET_REG, + .chip_config = bma250_chip_config, + .chip_disable = bma250_chip_disable, }, }; @@ -675,12 +702,12 @@ mutex_unlock(&data->mutex); goto err; } - ((s16 *)data->buff)[i++] = ret; + data->scan.chan[i++] = ret; } mutex_unlock(&data->mutex); - iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns); err: iio_trigger_notify_done(indio_dev->trig); @@ -766,11 +793,12 @@ data->trig->dev.parent = &client->dev; data->trig->ops = &bma180_trigger_ops; iio_trigger_set_drvdata(data->trig, indio_dev); - indio_dev->trig = iio_trigger_get(data->trig); ret = iio_trigger_register(data->trig); if (ret) goto err_trigger_free; + + indio_dev->trig = iio_trigger_get(data->trig); } ret = iio_triggered_buffer_setup(indio_dev, NULL, --- linux-oracle-5.4.0.orig/drivers/iio/accel/bma220_spi.c +++ linux-oracle-5.4.0/drivers/iio/accel/bma220_spi.c @@ -73,7 +73,11 @@ struct bma220_data { struct spi_device *spi_device; struct mutex lock; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */ + struct { + s8 chans[3]; + /* Ensure timestamp is naturally aligned. */ + s64 timestamp __aligned(8); + } scan; u8 tx_buf[2] ____cacheline_aligned; }; @@ -104,12 +108,12 @@ mutex_lock(&data->lock); data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; - ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer, + ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans, ARRAY_SIZE(bma220_channels) - 1); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); --- linux-oracle-5.4.0.orig/drivers/iio/accel/bmc150-accel-core.c +++ linux-oracle-5.4.0/drivers/iio/accel/bmc150-accel-core.c @@ -189,6 +189,14 @@ struct mutex mutex; u8 fifo_mode, watermark; s16 buffer[8]; + /* + * Ensure there is sufficient space and correct alignment for + * the timestamp if enabled + */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan; u8 bw_bits; u32 slope_dur; u32 slope_thres; @@ -922,15 +930,16 @@ * now. */ for (i = 0; i < count; i++) { - u16 sample[8]; int j, bit; j = 0; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) - memcpy(&sample[j++], &buffer[i * 3 + bit], 2); + memcpy(&data->scan.channels[j++], &buffer[i * 3 + bit], + sizeof(data->scan.channels[0])); - iio_push_to_buffers_with_timestamp(indio_dev, sample, tstamp); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + tstamp); tstamp += sample_period; } @@ -1640,11 +1649,14 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(dev, "Unable to register iio device\n"); - goto err_trigger_unregister; + goto err_pm_cleanup; } return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); err_trigger_unregister: bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); err_buffer_cleanup: --- linux-oracle-5.4.0.orig/drivers/iio/accel/hid-sensor-accel-3d.c +++ linux-oracle-5.4.0/drivers/iio/accel/hid-sensor-accel-3d.c @@ -29,8 +29,11 @@ struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; - /* Reserve for 3 channels + padding + timestamp */ - u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3]; + /* Ensure timestamp is naturally aligned */ + struct { + u32 accel_val[3]; + s64 timestamp __aligned(8); + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -241,8 +244,8 @@ accel_state->timestamp = iio_get_time_ns(indio_dev); hid_sensor_push_data(indio_dev, - accel_state->accel_val, - sizeof(accel_state->accel_val), + &accel_state->scan, + sizeof(accel_state->scan), accel_state->timestamp); accel_state->timestamp = 0; @@ -267,7 +270,7 @@ case HID_USAGE_SENSOR_ACCEL_Y_AXIS: case HID_USAGE_SENSOR_ACCEL_Z_AXIS: offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS; - accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] = + accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] = *(u32 *)raw_data; ret = 0; break; @@ -276,6 +279,7 @@ hid_sensor_convert_timestamp( &accel_state->common_attributes, *(int64_t *)raw_data); + ret = 0; break; default: break; --- linux-oracle-5.4.0.orig/drivers/iio/accel/kxcjk-1013.c +++ linux-oracle-5.4.0/drivers/iio/accel/kxcjk-1013.c @@ -126,12 +126,29 @@ KX_MAX_CHIPS /* this must be last */ }; +enum kx_acpi_type { + ACPI_GENERIC, + ACPI_SMO8500, + ACPI_KIOX010A, +}; + +enum kxcjk1013_axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_MAX +}; + struct kxcjk1013_data { struct i2c_client *client; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct mutex mutex; - s16 buffer[8]; + /* Ensure timestamp naturally aligned */ + struct { + s16 chans[AXIS_MAX]; + s64 timestamp __aligned(8); + } scan; u8 odr_bits; u8 range; int wake_thres; @@ -142,14 +159,7 @@ bool motion_trigger_on; int64_t timestamp; enum kx_chipset chipset; - bool is_smo8500_device; -}; - -enum kxcjk1013_axis { - AXIS_X, - AXIS_Y, - AXIS_Z, - AXIS_MAX, + enum kx_acpi_type acpi_type; }; enum kxcjk1013_mode { @@ -269,6 +279,32 @@ {19163, 1, 0}, {38326, 0, 1} }; +#ifdef CONFIG_ACPI +enum kiox010a_fn_index { + KIOX010A_SET_LAPTOP_MODE = 1, + KIOX010A_SET_TABLET_MODE = 2, +}; + +static int kiox010a_dsm(struct device *dev, int fn_index) +{ + acpi_handle handle = ACPI_HANDLE(dev); + guid_t kiox010a_dsm_guid; + union acpi_object *obj; + + if (!handle) + return -ENODEV; + + guid_parse("1f339696-d475-4e26-8cad-2e9f8e6d7a91", &kiox010a_dsm_guid); + + obj = acpi_evaluate_dsm(handle, &kiox010a_dsm_guid, 1, fn_index, NULL); + if (!obj) + return -EIO; + + ACPI_FREE(obj); + return 0; +} +#endif + static int kxcjk1013_set_mode(struct kxcjk1013_data *data, enum kxcjk1013_mode mode) { @@ -346,6 +382,13 @@ { int ret; +#ifdef CONFIG_ACPI + if (data->acpi_type == ACPI_KIOX010A) { + /* Make sure the kbd and touchpad on 2-in-1s using 2 KXCJ91008-s work */ + kiox010a_dsm(&data->client->dev, KIOX010A_SET_LAPTOP_MODE); + } +#endif + ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_WHO_AM_I); if (ret < 0) { dev_err(&data->client->dev, "Error reading who_am_i\n"); @@ -1039,12 +1082,12 @@ ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, KXCJK1013_REG_XOUT_L, AXIS_MAX * 2, - (u8 *)data->buffer); + (u8 *)data->scan.chans); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, data->timestamp); err: iio_trigger_notify_done(indio_dev->trig); @@ -1233,7 +1276,7 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev, enum kx_chipset *chipset, - bool *is_smo8500_device) + enum kx_acpi_type *acpi_type) { const struct acpi_device_id *id; @@ -1242,7 +1285,9 @@ return NULL; if (strcmp(id->id, "SMO8500") == 0) - *is_smo8500_device = true; + *acpi_type = ACPI_SMO8500; + else if (strcmp(id->id, "KIOX010A") == 0) + *acpi_type = ACPI_KIOX010A; *chipset = (enum kx_chipset)id->driver_data; @@ -1278,7 +1323,7 @@ } else if (ACPI_HANDLE(&client->dev)) { name = kxcjk1013_match_acpi_device(&client->dev, &data->chipset, - &data->is_smo8500_device); + &data->acpi_type); } else return -ENODEV; @@ -1296,7 +1341,7 @@ indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &kxcjk1013_info; - if (client->irq > 0 && !data->is_smo8500_device) { + if (client->irq > 0 && data->acpi_type != ACPI_SMO8500) { ret = devm_request_threaded_irq(&client->dev, client->irq, kxcjk1013_data_rdy_trig_poll, kxcjk1013_event_handler, @@ -1364,14 +1409,16 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "unable to register iio device\n"); - goto err_buffer_cleanup; + goto err_pm_cleanup; } return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(&client->dev); + pm_runtime_disable(&client->dev); err_buffer_cleanup: - if (data->dready_trig) - iio_triggered_buffer_cleanup(indio_dev); + iio_triggered_buffer_cleanup(indio_dev); err_trigger_unregister: if (data->dready_trig) iio_trigger_unregister(data->dready_trig); @@ -1394,8 +1441,8 @@ pm_runtime_set_suspended(&client->dev); pm_runtime_put_noidle(&client->dev); + iio_triggered_buffer_cleanup(indio_dev); if (data->dready_trig) { - iio_triggered_buffer_cleanup(indio_dev); iio_trigger_unregister(data->dready_trig); iio_trigger_unregister(data->motion_trig); } --- linux-oracle-5.4.0.orig/drivers/iio/accel/kxsd9.c +++ linux-oracle-5.4.0/drivers/iio/accel/kxsd9.c @@ -209,23 +209,29 @@ const struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct kxsd9_state *st = iio_priv(indio_dev); + /* + * Ensure correct positioning and alignment of timestamp. + * No need to zero initialize as all elements written. + */ + struct { + __be16 chan[4]; + s64 ts __aligned(8); + } hw_values; int ret; - /* 4 * 16bit values AND timestamp */ - __be16 hw_values[8]; ret = regmap_bulk_read(st->map, KXSD9_REG_X, - &hw_values, - 8); + hw_values.chan, + sizeof(hw_values.chan)); if (ret) { - dev_err(st->dev, - "error reading data\n"); - return ret; + dev_err(st->dev, "error reading data: %d\n", ret); + goto out; } iio_push_to_buffers_with_timestamp(indio_dev, - hw_values, + &hw_values, iio_get_time_ns(indio_dev)); +out: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; --- linux-oracle-5.4.0.orig/drivers/iio/accel/mma7455_core.c +++ linux-oracle-5.4.0/drivers/iio/accel/mma7455_core.c @@ -52,6 +52,14 @@ struct mma7455_data { struct regmap *regmap; + /* + * Used to reorganize data. Will ensure correct alignment of + * the timestamp if present + */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan; }; static int mma7455_drdy(struct mma7455_data *mma7455) @@ -82,19 +90,19 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mma7455_data *mma7455 = iio_priv(indio_dev); - u8 buf[16]; /* 3 x 16-bit channels + padding + ts */ int ret; ret = mma7455_drdy(mma7455); if (ret) goto done; - ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, buf, - sizeof(__le16) * 3); + ret = regmap_bulk_read(mma7455->regmap, MMA7455_REG_XOUTL, + mma7455->scan.channels, + sizeof(mma7455->scan.channels)); if (ret) goto done; - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &mma7455->scan, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/accel/mma8452.c +++ linux-oracle-5.4.0/drivers/iio/accel/mma8452.c @@ -110,6 +110,12 @@ int sleep_val; struct regulator *vdd_reg; struct regulator *vddio_reg; + + /* Ensure correct alignment of time stamp when present */ + struct { + __be16 channels[3]; + s64 ts __aligned(8); + } buffer; }; /** @@ -1091,14 +1097,13 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mma8452_data *data = iio_priv(indio_dev); - u8 buffer[16]; /* 3 16-bit channels + padding + ts */ int ret; - ret = mma8452_read(data, (__be16 *)buffer); + ret = mma8452_read(data, data->buffer.channels); if (ret < 0) goto done; - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer, iio_get_time_ns(indio_dev)); done: @@ -1468,7 +1473,7 @@ if (ret) return ret; - indio_dev->trig = trig; + indio_dev->trig = iio_trigger_get(trig); return 0; } @@ -1484,10 +1489,14 @@ int i; int ret; - ret = i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2, + /* + * Find on fxls8471, after config reset bit, it reset immediately, + * and will not give ACK, so here do not check the return value. + * The following code will read the reset register, and check whether + * this reset works. + */ + i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2, MMA8452_CTRL_REG2_RST); - if (ret < 0) - return ret; for (i = 0; i < 10; i++) { usleep_range(100, 200); @@ -1685,10 +1694,13 @@ ret = mma8452_set_freefall_mode(data, false); if (ret < 0) - goto buffer_cleanup; + goto unregister_device; return 0; +unregister_device: + iio_device_unregister(indio_dev); + buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/accel/mma9551.c +++ linux-oracle-5.4.0/drivers/iio/accel/mma9551.c @@ -496,11 +496,14 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "unable to register iio device\n"); - goto out_poweroff; + goto err_pm_cleanup; } return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(&client->dev); + pm_runtime_disable(&client->dev); out_poweroff: mma9551_set_device_state(client, false); --- linux-oracle-5.4.0.orig/drivers/iio/accel/mma9551_core.c +++ linux-oracle-5.4.0/drivers/iio/accel/mma9551_core.c @@ -296,9 +296,12 @@ ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG, reg, NULL, 0, (u8 *)&v, 2); + if (ret < 0) + return ret; + *val = be16_to_cpu(v); - return ret; + return 0; } EXPORT_SYMBOL(mma9551_read_config_word); @@ -354,9 +357,12 @@ ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS, reg, NULL, 0, (u8 *)&v, 2); + if (ret < 0) + return ret; + *val = be16_to_cpu(v); - return ret; + return 0; } EXPORT_SYMBOL(mma9551_read_status_word); --- linux-oracle-5.4.0.orig/drivers/iio/accel/mma9553.c +++ linux-oracle-5.4.0/drivers/iio/accel/mma9553.c @@ -1135,12 +1135,15 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "unable to register iio device\n"); - goto out_poweroff; + goto err_pm_cleanup; } dev_dbg(&indio_dev->dev, "Registered device %s\n", name); return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(&client->dev); + pm_runtime_disable(&client->dev); out_poweroff: mma9551_set_device_state(client, false); return ret; --- linux-oracle-5.4.0.orig/drivers/iio/accel/mxc4005.c +++ linux-oracle-5.4.0/drivers/iio/accel/mxc4005.c @@ -56,7 +56,11 @@ struct mutex mutex; struct regmap *regmap; struct iio_trigger *dready_trig; - __be16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + __be16 chans[3]; + s64 timestamp __aligned(8); + } scan; bool trigger_enabled; }; @@ -135,7 +139,7 @@ int ret; ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER, - (u8 *) data->buffer, sizeof(data->buffer)); + data->scan.chans, sizeof(data->scan.chans)); if (ret < 0) { dev_err(data->dev, "failed to read axes\n"); return ret; @@ -150,7 +154,7 @@ __be16 reg; int ret; - ret = regmap_bulk_read(data->regmap, addr, (u8 *) ®, sizeof(reg)); + ret = regmap_bulk_read(data->regmap, addr, ®, sizeof(reg)); if (ret < 0) { dev_err(data->dev, "failed to read reg %02x\n", addr); return ret; @@ -301,7 +305,7 @@ if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: @@ -458,8 +462,6 @@ data->dready_trig->dev.parent = &client->dev; data->dready_trig->ops = &mxc4005_trigger_ops; iio_trigger_set_drvdata(data->dready_trig, indio_dev); - indio_dev->trig = data->dready_trig; - iio_trigger_get(indio_dev->trig); ret = devm_iio_trigger_register(&client->dev, data->dready_trig); if (ret) { @@ -467,6 +469,8 @@ "failed to register trigger\n"); return ret; } + + indio_dev->trig = iio_trigger_get(data->dready_trig); } return devm_iio_device_register(&client->dev, indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/accel/sca3000.c +++ linux-oracle-5.4.0/drivers/iio/accel/sca3000.c @@ -980,7 +980,7 @@ st->tx[0] = SCA3000_READ_REG(reg_address_high); ret = spi_sync_transfer(st->us, xfer, ARRAY_SIZE(xfer)); if (ret) { - dev_err(get_device(&st->us->dev), "problem reading register"); + dev_err(&st->us->dev, "problem reading register\n"); return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/accel/st_accel_core.c +++ linux-oracle-5.4.0/drivers/iio/accel/st_accel_core.c @@ -993,6 +993,7 @@ #define ST_ACCEL_TRIGGER_OPS NULL #endif +#ifdef CONFIG_ACPI static const struct iio_mount_matrix * get_mount_matrix(const struct iio_dev *indio_dev, const struct iio_chan_spec *chan) @@ -1013,7 +1014,6 @@ static int apply_acpi_orientation(struct iio_dev *indio_dev, struct iio_chan_spec *channels) { -#ifdef CONFIG_ACPI struct st_sensor_data *adata = iio_priv(indio_dev); struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; struct acpi_device *adev; @@ -1141,10 +1141,14 @@ out: kfree(buffer.pointer); return ret; +} #else /* !CONFIG_ACPI */ +static int apply_acpi_orientation(struct iio_dev *indio_dev, + struct iio_chan_spec *channels) +{ return 0; -#endif } +#endif /* * st_accel_get_settings() - get sensor settings from device name --- linux-oracle-5.4.0.orig/drivers/iio/accel/st_accel_i2c.c +++ linux-oracle-5.4.0/drivers/iio/accel/st_accel_i2c.c @@ -114,7 +114,7 @@ #ifdef CONFIG_ACPI static const struct acpi_device_id st_accel_acpi_match[] = { - {"SMO8840", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, + {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME}, {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, { }, }; --- linux-oracle-5.4.0.orig/drivers/iio/accel/stk8312.c +++ linux-oracle-5.4.0/drivers/iio/accel/stk8312.c @@ -103,7 +103,11 @@ u8 mode; struct iio_trigger *dready_trig; bool dready_trigger_on; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s8 chans[3]; + s64 timestamp __aligned(8); + } scan; }; static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL); @@ -438,7 +442,7 @@ ret = i2c_smbus_read_i2c_block_data(data->client, STK8312_REG_XOUT, STK8312_ALL_CHANNEL_SIZE, - data->buffer); + data->scan.chans); if (ret < STK8312_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); mutex_unlock(&data->lock); @@ -452,12 +456,12 @@ mutex_unlock(&data->lock); goto err; } - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/accel/stk8ba50.c +++ linux-oracle-5.4.0/drivers/iio/accel/stk8ba50.c @@ -91,12 +91,11 @@ u8 sample_rate_idx; struct iio_trigger *dready_trig; bool dready_trigger_on; - /* - * 3 x 16-bit channels (10-bit data, 6-bit padding) + - * 1 x 16 padding + - * 4 x 16 64-bit timestamp - */ - s16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[3]; + s64 timetamp __aligned(8); + } scan; }; #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \ @@ -324,7 +323,7 @@ ret = i2c_smbus_read_i2c_block_data(data->client, STK8BA50_REG_XOUT, STK8BA50_ALL_CHANNEL_SIZE, - (u8 *)data->buffer); + (u8 *)data->scan.chans); if (ret < STK8BA50_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); goto err; @@ -337,10 +336,10 @@ if (ret < 0) goto err; - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); --- linux-oracle-5.4.0.orig/drivers/iio/adc/Kconfig +++ linux-oracle-5.4.0/drivers/iio/adc/Kconfig @@ -784,6 +784,7 @@ depends on ARCH_STM32 || COMPILE_TEST depends on OF depends on REGULATOR + depends on HAS_IOMEM select IIO_BUFFER select MFD_STM32_TIMERS select IIO_STM32_TIMER_TRIGGER @@ -839,22 +840,6 @@ Say yes here to build support for ST Microelectronics STMPE built-in ADC block (stmpe811). -config STX104 - tristate "Apex Embedded Systems STX104 driver" - depends on PC104 && X86 - select ISA_BUS_API - select GPIOLIB - help - Say yes here to build support for the Apex Embedded Systems STX104 - integrated analog PC/104 card. - - This driver supports the 16 channels of single-ended (8 channels of - differential) analog inputs, 2 channels of analog output, 4 digital - inputs, and 4 digital outputs provided by the STX104. - - The base port addresses for the devices may be configured via the base - array module parameter. - config SUN4I_GPADC tristate "Support for the Allwinner SoCs GPADC" depends on IIO @@ -995,6 +980,8 @@ config TI_ADS8688 tristate "Texas Instruments ADS8688" depends on SPI && OF + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help If you say yes here you get support for Texas Instruments ADS8684 and and ADS8688 ADC chips @@ -1005,6 +992,8 @@ config TI_ADS124S08 tristate "Texas Instruments ADS124S08" depends on SPI && OF + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help If you say yes here you get support for Texas Instruments ADS124S08 and ADS124S06 ADC chips --- linux-oracle-5.4.0.orig/drivers/iio/adc/Makefile +++ linux-oracle-5.4.0/drivers/iio/adc/Makefile @@ -72,7 +72,6 @@ obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o obj-$(CONFIG_SPEAR_ADC) += spear_adc.o -obj-$(CONFIG_STX104) += stx104.o obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7124.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7124.c @@ -39,6 +39,8 @@ #define AD7124_STATUS_POR_FLAG_MSK BIT(4) /* AD7124_ADC_CONTROL */ +#define AD7124_ADC_CTRL_REF_EN_MSK BIT(8) +#define AD7124_ADC_CTRL_REF_EN(x) FIELD_PREP(AD7124_ADC_CTRL_REF_EN_MSK, x) #define AD7124_ADC_CTRL_PWR_MSK GENMASK(7, 6) #define AD7124_ADC_CTRL_PWR(x) FIELD_PREP(AD7124_ADC_CTRL_PWR_MSK, x) #define AD7124_ADC_CTRL_MODE_MSK GENMASK(5, 2) @@ -61,7 +63,7 @@ #define AD7124_CONFIG_REF_SEL(x) FIELD_PREP(AD7124_CONFIG_REF_SEL_MSK, x) #define AD7124_CONFIG_PGA_MSK GENMASK(2, 0) #define AD7124_CONFIG_PGA(x) FIELD_PREP(AD7124_CONFIG_PGA_MSK, x) -#define AD7124_CONFIG_IN_BUFF_MSK GENMASK(7, 6) +#define AD7124_CONFIG_IN_BUFF_MSK GENMASK(6, 5) #define AD7124_CONFIG_IN_BUFF(x) FIELD_PREP(AD7124_CONFIG_IN_BUFF_MSK, x) /* AD7124_FILTER_X */ @@ -140,7 +142,6 @@ .sign = 'u', .realbits = 24, .storagebits = 32, - .shift = 8, .endianness = IIO_BE, }, }; @@ -424,7 +425,10 @@ break; case AD7124_INT_REF: st->channel_config[channel_number].vref_mv = 2500; - break; + st->adc_control &= ~AD7124_ADC_CTRL_REF_EN_MSK; + st->adc_control |= AD7124_ADC_CTRL_REF_EN(1); + return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, + 2, st->adc_control); default: dev_err(&st->sd.spi->dev, "Invalid reference %d\n", refsel); return -EINVAL; @@ -468,6 +472,13 @@ if (ret) goto err; + if (channel >= indio_dev->num_channels) { + dev_err(indio_dev->dev.parent, + "Channel index >= number of channels\n"); + ret = -EINVAL; + goto err; + } + ret = of_property_read_u32_array(child, "diff-channels", ain, 2); if (ret) @@ -489,13 +500,11 @@ st->channel_config[channel].buf_negative = of_property_read_bool(child, "adi,buffered-negative"); - *chan = ad7124_channel_template; - chan->address = channel; - chan->scan_index = channel; - chan->channel = ain[0]; - chan->channel2 = ain[1]; - - chan++; + chan[channel] = ad7124_channel_template; + chan[channel].address = channel; + chan[channel].scan_index = channel; + chan[channel].channel = ain[0]; + chan[channel].channel2 = ain[1]; } return 0; @@ -561,6 +570,11 @@ return ret; } +static void ad7124_reg_disable(void *r) +{ + regulator_disable(r); +} + static int ad7124_probe(struct spi_device *spi) { const struct spi_device_id *id; @@ -604,17 +618,20 @@ ret = regulator_enable(st->vref[i]); if (ret) return ret; + + ret = devm_add_action_or_reset(&spi->dev, ad7124_reg_disable, + st->vref[i]); + if (ret) + return ret; } st->mclk = devm_clk_get(&spi->dev, "mclk"); - if (IS_ERR(st->mclk)) { - ret = PTR_ERR(st->mclk); - goto error_regulator_disable; - } + if (IS_ERR(st->mclk)) + return PTR_ERR(st->mclk); ret = clk_prepare_enable(st->mclk); if (ret < 0) - goto error_regulator_disable; + return ret; ret = ad7124_soft_reset(st); if (ret < 0) @@ -640,11 +657,6 @@ ad_sd_cleanup_buffer_and_trigger(indio_dev); error_clk_disable_unprepare: clk_disable_unprepare(st->mclk); -error_regulator_disable: - for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { - if (!IS_ERR_OR_NULL(st->vref[i])) - regulator_disable(st->vref[i]); - } return ret; } @@ -653,17 +665,11 @@ { struct iio_dev *indio_dev = spi_get_drvdata(spi); struct ad7124_state *st = iio_priv(indio_dev); - int i; iio_device_unregister(indio_dev); ad_sd_cleanup_buffer_and_trigger(indio_dev); clk_disable_unprepare(st->mclk); - for (i = ARRAY_SIZE(st->vref) - 1; i >= 0; i--) { - if (!IS_ERR_OR_NULL(st->vref[i])) - regulator_disable(st->vref[i]); - } - return 0; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7266.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7266.c @@ -159,6 +159,8 @@ ret = ad7266_read_single(st, val, chan->address); iio_device_release_direct_mode(indio_dev); + if (ret < 0) + return ret; *val = (*val >> 2) & 0xfff; if (chan->scan_type.sign == 's') *val = sign_extend32(*val, 11); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7606.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7606.c @@ -85,7 +85,7 @@ static int ad7606_read_samples(struct ad7606_state *st) { - unsigned int num = st->chip_info->num_channels; + unsigned int num = st->chip_info->num_channels - 1; u16 *data = st->data; int ret; @@ -238,9 +238,9 @@ struct ad7606_state *st = iio_priv(indio_dev); DECLARE_BITMAP(values, 3); - values[0] = val; + values[0] = val & GENMASK(2, 0); - gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc, + gpiod_set_array_value(st->gpio_os->ndescs, st->gpio_os->desc, st->gpio_os->info, values); /* AD7616 requires a reset to update value */ @@ -445,7 +445,7 @@ return PTR_ERR(st->gpio_range); st->gpio_standby = devm_gpiod_get_optional(dev, "standby", - GPIOD_OUT_HIGH); + GPIOD_OUT_LOW); if (IS_ERR(st->gpio_standby)) return PTR_ERR(st->gpio_standby); @@ -706,7 +706,7 @@ if (st->gpio_standby) { gpiod_set_value(st->gpio_range, 1); - gpiod_set_value(st->gpio_standby, 0); + gpiod_set_value(st->gpio_standby, 1); } return 0; --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7606_spi.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7606_spi.c @@ -249,8 +249,9 @@ static int ad7606B_sw_mode_config(struct iio_dev *indio_dev) { struct ad7606_state *st = iio_priv(indio_dev); - unsigned long os[3] = {1}; + DECLARE_BITMAP(os, 3); + bitmap_fill(os, 3); /* * Software mode is enabled when all three oversampling * pins are set to high. If oversampling gpios are defined @@ -258,7 +259,7 @@ * otherwise, they must be hardwired to VDD */ if (st->gpio_os) { - gpiod_set_array_value(ARRAY_SIZE(os), + gpiod_set_array_value(st->gpio_os->ndescs, st->gpio_os->desc, st->gpio_os->info, os); } /* OS of 128 and 256 are available only in software mode */ --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7768-1.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7768-1.c @@ -166,6 +166,10 @@ * transfer buffers to live in their own cache lines. */ union { + struct { + __be32 chan; + s64 timestamp; + } scan; __be32 d32; u8 d8[2]; } data ____cacheline_aligned; @@ -459,15 +463,15 @@ mutex_lock(&st->lock); - ret = spi_read(st->spi, &st->data.d32, 3); + ret = spi_read(st->spi, &st->data.scan.chan, 3); if (ret < 0) goto err_unlock; - iio_push_to_buffers_with_timestamp(indio_dev, &st->data.d32, + iio_push_to_buffers_with_timestamp(indio_dev, &st->data.scan, iio_get_time_ns(indio_dev)); - iio_trigger_notify_done(indio_dev->trig); err_unlock: + iio_trigger_notify_done(indio_dev->trig); mutex_unlock(&st->lock); return IRQ_HANDLED; --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7780.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7780.c @@ -152,7 +152,7 @@ switch (m) { case IIO_CHAN_INFO_SCALE: - if (val != 0) + if (val != 0 || val2 == 0) return -EINVAL; vref = st->int_vref_mv * 1000000LL; @@ -309,7 +309,7 @@ ret = ad7780_init_gpios(&spi->dev, st); if (ret) - goto error_cleanup_buffer_and_trigger; + return ret; st->reg = devm_regulator_get(&spi->dev, "avdd"); if (IS_ERR(st->reg)) --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7793.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7793.c @@ -278,6 +278,7 @@ id &= AD7793_ID_MASK; if (id != st->chip_info->id) { + ret = -ENODEV; dev_err(&st->sd.spi->dev, "device ID query failed\n"); goto out; } @@ -541,7 +542,7 @@ .read_raw = &ad7793_read_raw, .write_raw = &ad7793_write_raw, .write_raw_get_fmt = &ad7793_write_raw_get_fmt, - .attrs = &ad7793_attribute_group, + .attrs = &ad7797_attribute_group, .validate_trigger = ad_sd_validate_trigger, }; --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad7949.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad7949.c @@ -57,29 +57,11 @@ u32 buffer ____cacheline_aligned; }; -static bool ad7949_spi_cfg_is_read_back(struct ad7949_adc_chip *ad7949_adc) -{ - if (!(ad7949_adc->cfg & AD7949_CFG_READ_BACK)) - return true; - - return false; -} - -static int ad7949_spi_bits_per_word(struct ad7949_adc_chip *ad7949_adc) -{ - int ret = ad7949_adc->resolution; - - if (ad7949_spi_cfg_is_read_back(ad7949_adc)) - ret += AD7949_CFG_REG_SIZE_BITS; - - return ret; -} - static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val, u16 mask) { int ret; - int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); + int bits_per_word = ad7949_adc->resolution; int shift = bits_per_word - AD7949_CFG_REG_SIZE_BITS; struct spi_message msg; struct spi_transfer tx[] = { @@ -107,8 +89,9 @@ unsigned int channel) { int ret; - int bits_per_word = ad7949_spi_bits_per_word(ad7949_adc); - int mask = GENMASK(ad7949_adc->resolution, 0); + int i; + int bits_per_word = ad7949_adc->resolution; + int mask = GENMASK(ad7949_adc->resolution - 1, 0); struct spi_message msg; struct spi_transfer tx[] = { { @@ -118,12 +101,23 @@ }, }; - ret = ad7949_spi_write_cfg(ad7949_adc, - channel << AD7949_OFFSET_CHANNEL_SEL, - AD7949_MASK_CHANNEL_SEL); - if (ret) - return ret; + /* + * 1: write CFG for sample N and read old data (sample N-2) + * 2: if CFG was not changed since sample N-1 then we'll get good data + * at the next xfer, so we bail out now, otherwise we write something + * and we read garbage (sample N-1 configuration). + */ + for (i = 0; i < 2; i++) { + ret = ad7949_spi_write_cfg(ad7949_adc, + channel << AD7949_OFFSET_CHANNEL_SEL, + AD7949_MASK_CHANNEL_SEL); + if (ret) + return ret; + if (channel == ad7949_adc->current_channel) + break; + } + /* 3: write something and read actual data */ ad7949_adc->buffer = 0; spi_message_init_with_transfers(&msg, tx, 1); ret = spi_sync(ad7949_adc->spi, &msg); @@ -138,10 +132,7 @@ ad7949_adc->current_channel = channel; - if (ad7949_spi_cfg_is_read_back(ad7949_adc)) - *val = (ad7949_adc->buffer >> AD7949_CFG_REG_SIZE_BITS) & mask; - else - *val = ad7949_adc->buffer & mask; + *val = ad7949_adc->buffer & mask; return 0; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/ad_sigma_delta.c +++ linux-oracle-5.4.0/drivers/iio/adc/ad_sigma_delta.c @@ -283,10 +283,10 @@ unsigned int data_reg; int ret = 0; - if (iio_buffer_enabled(indio_dev)) - return -EBUSY; + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; - mutex_lock(&indio_dev->mlock); ad_sigma_delta_set_channel(sigma_delta, chan->address); spi_bus_lock(sigma_delta->spi->master); @@ -325,7 +325,7 @@ ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE); sigma_delta->bus_locked = false; spi_bus_unlock(sigma_delta->spi->master); - mutex_unlock(&indio_dev->mlock); + iio_device_release_direct_mode(indio_dev); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/iio/adc/aspeed_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/aspeed_adc.c @@ -184,6 +184,7 @@ data = iio_priv(indio_dev); data->dev = &pdev->dev; + platform_set_drvdata(pdev, indio_dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->base = devm_ioremap_resource(&pdev->dev, res); --- linux-oracle-5.4.0.orig/drivers/iio/adc/at91-sama5d2_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/at91-sama5d2_adc.c @@ -73,7 +73,7 @@ #define AT91_SAMA5D2_MR_ANACH BIT(23) /* Tracking Time */ #define AT91_SAMA5D2_MR_TRACKTIM(v) ((v) << 24) -#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xff +#define AT91_SAMA5D2_MR_TRACKTIM_MAX 0xf /* Transfer Time */ #define AT91_SAMA5D2_MR_TRANSFER(v) ((v) << 28) #define AT91_SAMA5D2_MR_TRANSFER_MAX 0x3 @@ -399,7 +399,9 @@ wait_queue_head_t wq_data_available; struct at91_adc_dma dma_st; struct at91_adc_touch touch_st; - u16 buffer[AT91_BUFFER_MAX_HWORDS]; + struct iio_dev *indio_dev; + /* Ensure naturally aligned timestamp */ + u16 buffer[AT91_BUFFER_MAX_HWORDS] __aligned(8); /* * lock to prevent concurrent 'single conversion' requests through * sysfs. @@ -624,13 +626,13 @@ /* first half of register is the x or y, second half is the scale */ val = at91_adc_readl(st, reg); if (!val) - dev_dbg(&iio_priv_to_dev(st)->dev, "pos is 0\n"); + dev_dbg(&st->indio_dev->dev, "pos is 0\n"); pos = val & AT91_SAMA5D2_XYZ_MASK; result = (pos << AT91_SAMA5D2_MAX_POS_BITS) - pos; scale = (val >> 16) & AT91_SAMA5D2_XYZ_MASK; if (scale == 0) { - dev_err(&iio_priv_to_dev(st)->dev, "scale is 0\n"); + dev_err(&st->indio_dev->dev, "scale is 0\n"); return 0; } result /= scale; @@ -723,6 +725,7 @@ for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); + u32 cor; if (!chan) continue; @@ -732,6 +735,20 @@ continue; if (state) { + cor = at91_adc_readl(st, AT91_SAMA5D2_COR); + + if (chan->differential) + cor |= (BIT(chan->channel) | + BIT(chan->channel2)) << + AT91_SAMA5D2_COR_DIFF_OFFSET; + else + cor &= ~(BIT(chan->channel) << + AT91_SAMA5D2_COR_DIFF_OFFSET); + + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); + } + + if (state) { at91_adc_writel(st, AT91_SAMA5D2_CHER, BIT(chan->channel)); /* enable irq only if not using DMA */ @@ -966,7 +983,7 @@ trig = devm_iio_trigger_alloc(&indio->dev, "%s-dev%d-%s", indio->name, indio->id, trigger_name); if (!trig) - return NULL; + return ERR_PTR(-ENOMEM); trig->dev.parent = indio->dev.parent; iio_trigger_set_drvdata(trig, indio); @@ -1139,9 +1156,9 @@ return i; } -static void at91_adc_setup_samp_freq(struct at91_adc_state *st, unsigned freq) +static void at91_adc_setup_samp_freq(struct iio_dev *indio_dev, unsigned freq) { - struct iio_dev *indio_dev = iio_priv_to_dev(st); + struct at91_adc_state *st = iio_priv(indio_dev); unsigned f_per, prescal, startup, mr; f_per = clk_get_rate(st->per_clk); @@ -1210,9 +1227,9 @@ st->touch_st.touching = true; } -static void at91_adc_no_pen_detect_interrupt(struct at91_adc_state *st) +static void at91_adc_no_pen_detect_interrupt(struct iio_dev *indio_dev) { - struct iio_dev *indio_dev = iio_priv_to_dev(st); + struct at91_adc_state *st = iio_priv(indio_dev); at91_adc_writel(st, AT91_SAMA5D2_TRGR, AT91_SAMA5D2_TRGR_TRGMOD_NO_TRIGGER); @@ -1232,7 +1249,7 @@ struct at91_adc_touch, workq); struct at91_adc_state *st = container_of(touch_st, struct at91_adc_state, touch_st); - struct iio_dev *indio_dev = iio_priv_to_dev(st); + struct iio_dev *indio_dev = st->indio_dev; iio_push_to_buffers(indio_dev, st->buffer); } @@ -1253,7 +1270,7 @@ at91_adc_pen_detect_interrupt(st); } else if ((status & AT91_SAMA5D2_IER_NOPEN)) { /* nopen detected IRQ */ - at91_adc_no_pen_detect_interrupt(st); + at91_adc_no_pen_detect_interrupt(indio); } else if ((status & AT91_SAMA5D2_ISR_PENS) && ((status & rdy_mask) == rdy_mask)) { /* periodic trigger IRQ - during pen sense */ @@ -1304,10 +1321,12 @@ ret = at91_adc_read_position(st, chan->channel, &tmp_val); *val = tmp_val; + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); - return at91_adc_adjust_val_osr(st, val); + return ret; } if (chan->type == IIO_PRESSURE) { ret = iio_device_claim_direct_mode(indio_dev); @@ -1318,10 +1337,12 @@ ret = at91_adc_read_pressure(st, chan->channel, &tmp_val); *val = tmp_val; + if (ret > 0) + ret = at91_adc_adjust_val_osr(st, val); mutex_unlock(&st->lock); iio_device_release_direct_mode(indio_dev); - return at91_adc_adjust_val_osr(st, val); + return ret; } /* in this case we have a voltage channel */ @@ -1352,7 +1373,8 @@ *val = st->conversion_value; ret = at91_adc_adjust_val_osr(st, val); if (chan->scan_type.sign == 's') - *val = sign_extend32(*val, 11); + *val = sign_extend32(*val, + chan->scan_type.realbits - 1); st->conversion_done = false; } @@ -1411,16 +1433,20 @@ /* if no change, optimize out */ if (val == st->oversampling_ratio) return 0; + mutex_lock(&st->lock); st->oversampling_ratio = val; /* update ratio */ at91_adc_config_emr(st); + mutex_unlock(&st->lock); return 0; case IIO_CHAN_INFO_SAMP_FREQ: if (val < st->soc_info.min_sample_rate || val > st->soc_info.max_sample_rate) return -EINVAL; - at91_adc_setup_samp_freq(st, val); + mutex_lock(&st->lock); + at91_adc_setup_samp_freq(indio_dev, val); + mutex_unlock(&st->lock); return 0; default: return -EINVAL; @@ -1558,8 +1584,10 @@ return 0; } -static void at91_adc_hw_init(struct at91_adc_state *st) +static void at91_adc_hw_init(struct iio_dev *indio_dev) { + struct at91_adc_state *st = iio_priv(indio_dev); + at91_adc_writel(st, AT91_SAMA5D2_CR, AT91_SAMA5D2_CR_SWRST); at91_adc_writel(st, AT91_SAMA5D2_IDR, 0xffffffff); /* @@ -1569,7 +1597,7 @@ at91_adc_writel(st, AT91_SAMA5D2_MR, AT91_SAMA5D2_MR_TRANSFER(2) | AT91_SAMA5D2_MR_ANACH); - at91_adc_setup_samp_freq(st, st->soc_info.min_sample_rate); + at91_adc_setup_samp_freq(indio_dev, st->soc_info.min_sample_rate); /* configure extended mode register */ at91_adc_config_emr(st); @@ -1652,6 +1680,7 @@ indio_dev->num_channels = ARRAY_SIZE(at91_adc_channels); st = iio_priv(indio_dev); + st->indio_dev = indio_dev; bitmap_set(&st->touch_st.channels_bitmask, AT91_SAMA5D2_TOUCH_X_CHAN_IDX, 1); @@ -1763,7 +1792,7 @@ goto vref_disable; } - at91_adc_hw_init(st); + at91_adc_hw_init(indio_dev); ret = clk_prepare_enable(st->per_clk); if (ret) @@ -1879,7 +1908,7 @@ if (ret) goto vref_disable_resume; - at91_adc_hw_init(st); + at91_adc_hw_init(indio_dev); /* reconfiguring trigger hardware state */ if (!iio_buffer_enabled(indio_dev)) --- linux-oracle-5.4.0.orig/drivers/iio/adc/at91_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/at91_adc.c @@ -616,8 +616,10 @@ trig->ops = &at91_adc_trigger_ops; ret = iio_trigger_register(trig); - if (ret) + if (ret) { + iio_trigger_free(trig); return NULL; + } return trig; } @@ -1137,7 +1139,7 @@ return ret; err: - input_free_device(st->ts_input); + input_free_device(input); return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/axp20x_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/axp20x_adc.c @@ -251,19 +251,8 @@ struct iio_chan_spec const *chan, int *val) { struct axp20x_adc_iio *info = iio_priv(indio_dev); - int size; - /* - * N.B.: Unlike the Chinese datasheets tell, the charging current is - * stored on 12 bits, not 13 bits. Only discharging current is on 13 - * bits. - */ - if (chan->type == IIO_CURRENT && chan->channel == AXP22X_BATT_DISCHRG_I) - size = 13; - else - size = 12; - - *val = axp20x_read_variable_width(info->regmap, chan->address, size); + *val = axp20x_read_variable_width(info->regmap, chan->address, 12); if (*val < 0) return *val; @@ -386,9 +375,8 @@ return IIO_VAL_INT_PLUS_MICRO; case IIO_CURRENT: - *val = 0; - *val2 = 500000; - return IIO_VAL_INT_PLUS_MICRO; + *val = 1; + return IIO_VAL_INT; case IIO_TEMP: *val = 100; --- linux-oracle-5.4.0.orig/drivers/iio/adc/axp288_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/axp288_adc.c @@ -196,6 +196,14 @@ }, .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, }, + { + /* Nuvision Solo 10 Draw */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TMAX"), + DMI_MATCH(DMI_PRODUCT_NAME, "TM101W610L"), + }, + .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, + }, {} }; --- linux-oracle-5.4.0.orig/drivers/iio/adc/berlin2-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/berlin2-adc.c @@ -289,8 +289,10 @@ int ret; indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv)); - if (!indio_dev) + if (!indio_dev) { + of_node_put(parent_np); return -ENOMEM; + } priv = iio_priv(indio_dev); platform_set_drvdata(pdev, indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/adc/dln2-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/dln2-adc.c @@ -248,7 +248,6 @@ static int dln2_adc_read(struct dln2_adc *dln2, unsigned int channel) { int ret, i; - struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev); u16 conflict; __le16 value; int olen = sizeof(value); @@ -257,13 +256,9 @@ .chan = channel, }; - ret = iio_device_claim_direct_mode(indio_dev); - if (ret < 0) - return ret; - ret = dln2_adc_set_chan_enabled(dln2, channel, true); if (ret < 0) - goto release_direct; + return ret; ret = dln2_adc_set_port_enabled(dln2, true, &conflict); if (ret < 0) { @@ -300,8 +295,6 @@ dln2_adc_set_port_enabled(dln2, false, NULL); disable_chan: dln2_adc_set_chan_enabled(dln2, channel, false); -release_direct: - iio_device_release_direct_mode(indio_dev); return ret; } @@ -337,10 +330,16 @@ switch (mask) { case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret < 0) + return ret; + mutex_lock(&dln2->mutex); ret = dln2_adc_read(dln2, chan->channel); mutex_unlock(&dln2->mutex); + iio_device_release_direct_mode(indio_dev); + if (ret < 0) return ret; @@ -524,6 +523,10 @@ u16 conflict; unsigned int trigger_chan; + ret = iio_triggered_buffer_postenable(indio_dev); + if (ret) + return ret; + mutex_lock(&dln2->mutex); /* Enable ADC */ @@ -537,6 +540,7 @@ (int)conflict); ret = -EBUSY; } + iio_triggered_buffer_predisable(indio_dev); return ret; } @@ -550,6 +554,7 @@ mutex_unlock(&dln2->mutex); if (ret < 0) { dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); + iio_triggered_buffer_predisable(indio_dev); return ret; } } else { @@ -557,12 +562,12 @@ mutex_unlock(&dln2->mutex); } - return iio_triggered_buffer_postenable(indio_dev); + return 0; } static int dln2_adc_triggered_buffer_predisable(struct iio_dev *indio_dev) { - int ret; + int ret, ret2; struct dln2_adc *dln2 = iio_priv(indio_dev); mutex_lock(&dln2->mutex); @@ -577,12 +582,14 @@ ret = dln2_adc_set_port_enabled(dln2, false, NULL); mutex_unlock(&dln2->mutex); - if (ret < 0) { + if (ret < 0) dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__); - return ret; - } - return iio_triggered_buffer_predisable(indio_dev); + ret2 = iio_triggered_buffer_predisable(indio_dev); + if (ret == 0) + ret = ret2; + + return ret; } static const struct iio_buffer_setup_ops dln2_adc_buffer_setup_ops = { @@ -658,7 +665,11 @@ return -ENOMEM; } iio_trigger_set_drvdata(dln2->trig, dln2); - devm_iio_trigger_register(dev, dln2->trig); + ret = devm_iio_trigger_register(dev, dln2->trig); + if (ret) { + dev_err(dev, "failed to register trigger: %d\n", ret); + return ret; + } iio_trigger_set_immutable(indio_dev, dln2->trig); ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, --- linux-oracle-5.4.0.orig/drivers/iio/adc/exynos_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/exynos_adc.c @@ -804,16 +804,26 @@ } } + /* leave out any TS related code if unreachable */ + if (IS_REACHABLE(CONFIG_INPUT)) { + has_ts = of_property_read_bool(pdev->dev.of_node, + "has-touchscreen") || pdata; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; info->irq = irq; - irq = platform_get_irq(pdev, 1); - if (irq == -EPROBE_DEFER) - return irq; - - info->tsirq = irq; + if (has_ts) { + irq = platform_get_irq(pdev, 1); + if (irq == -EPROBE_DEFER) + return irq; + + info->tsirq = irq; + } else { + info->tsirq = -1; + } info->dev = &pdev->dev; @@ -880,12 +890,6 @@ if (info->data->init_hw) info->data->init_hw(info); - /* leave out any TS related code if unreachable */ - if (IS_REACHABLE(CONFIG_INPUT)) { - has_ts = of_property_read_bool(pdev->dev.of_node, - "has-touchscreen") || pdata; - } - if (pdata) info->delay = pdata->delay; else --- linux-oracle-5.4.0.orig/drivers/iio/adc/hx711.c +++ linux-oracle-5.4.0/drivers/iio/adc/hx711.c @@ -85,9 +85,9 @@ struct mutex lock; /* * triggered buffer - * 2x32-bit channel + 64-bit timestamp + * 2x32-bit channel + 64-bit naturally aligned timestamp */ - u32 buffer[4]; + u32 buffer[4] __aligned(8); /* * delay after a rising edge on SCK until the data is ready DOUT * this is dependent on the hx711 where the datasheet tells a --- linux-oracle-5.4.0.orig/drivers/iio/adc/ina2xx-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/ina2xx-adc.c @@ -146,6 +146,11 @@ int range_vbus; /* Bus voltage maximum in V */ int pga_gain_vshunt; /* Shunt voltage PGA gain */ bool allow_async_readout; + /* data buffer needs space for channel data and timestamp */ + struct { + u16 chan[4]; + u64 ts __aligned(8); + } scan; }; static const struct ina2xx_config ina2xx_config[] = { @@ -738,8 +743,6 @@ static int ina2xx_work_buffer(struct iio_dev *indio_dev) { struct ina2xx_chip_info *chip = iio_priv(indio_dev); - /* data buffer needs space for channel data and timestap */ - unsigned short data[4 + sizeof(s64)/sizeof(short)]; int bit, ret, i = 0; s64 time; @@ -758,10 +761,10 @@ if (ret < 0) return ret; - data[i++] = val; + chip->scan.chan[i++] = val; } - iio_push_to_buffers_with_timestamp(indio_dev, data, time); + iio_push_to_buffers_with_timestamp(indio_dev, &chip->scan, time); return 0; }; --- linux-oracle-5.4.0.orig/drivers/iio/adc/max1027.c +++ linux-oracle-5.4.0/drivers/iio/adc/max1027.c @@ -458,6 +458,14 @@ return ret; } + /* Internal reset */ + st->reg = MAX1027_RST_REG; + ret = spi_write(st->spi, &st->reg, 1); + if (ret < 0) { + dev_err(&indio_dev->dev, "Failed to reset the ADC\n"); + return ret; + } + /* Disable averaging */ st->reg = MAX1027_AVG_REG; ret = spi_write(st->spi, &st->reg, 1); --- linux-oracle-5.4.0.orig/drivers/iio/adc/max1118.c +++ linux-oracle-5.4.0/drivers/iio/adc/max1118.c @@ -35,6 +35,11 @@ struct spi_device *spi; struct mutex lock; struct regulator *reg; + /* Ensure natural alignment of buffer elements */ + struct { + u8 channels[2]; + s64 ts __aligned(8); + } scan; u8 data ____cacheline_aligned; }; @@ -159,7 +164,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct max1118 *adc = iio_priv(indio_dev); - u8 data[16] = { }; /* 2x 8-bit ADC data + padding + 8 bytes timestamp */ int scan_index; int i = 0; @@ -177,10 +181,10 @@ goto out; } - data[i] = ret; + adc->scan.channels[i] = ret; i++; } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); --- linux-oracle-5.4.0.orig/drivers/iio/adc/max9611.c +++ linux-oracle-5.4.0/drivers/iio/adc/max9611.c @@ -89,6 +89,12 @@ #define MAX9611_TEMP_SCALE_NUM 1000000 #define MAX9611_TEMP_SCALE_DIV 2083 +/* + * Conversion time is 2 ms (typically) at Ta=25 degreeC + * No maximum value is known, so play it safe. + */ +#define MAX9611_CONV_TIME_US_RANGE 3000, 3300 + struct max9611_dev { struct device *dev; struct i2c_client *i2c_client; @@ -236,11 +242,9 @@ return ret; } - /* - * need a delay here to make register configuration - * stabilize. 1 msec at least, from empirical testing. - */ - usleep_range(1000, 2000); + /* need a delay here to make register configuration stabilize. */ + + usleep_range(MAX9611_CONV_TIME_US_RANGE); ret = i2c_smbus_read_word_swapped(max9611->i2c_client, reg_addr); if (ret < 0) { @@ -507,7 +511,7 @@ MAX9611_REG_CTRL2, 0); return ret; } - usleep_range(1000, 2000); + usleep_range(MAX9611_CONV_TIME_US_RANGE); return 0; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/mcp3422.c +++ linux-oracle-5.4.0/drivers/iio/adc/mcp3422.c @@ -95,16 +95,12 @@ { int ret; - mutex_lock(&adc->lock); - ret = i2c_master_send(adc->i2c, &newconfig, 1); if (ret > 0) { adc->config = newconfig; ret = 0; } - mutex_unlock(&adc->lock); - return ret; } @@ -137,6 +133,8 @@ u8 config; u8 req_channel = channel->channel; + mutex_lock(&adc->lock); + if (req_channel != MCP3422_CHANNEL(adc->config)) { config = adc->config; config &= ~MCP3422_CHANNEL_MASK; @@ -144,12 +142,18 @@ config &= ~MCP3422_PGA_MASK; config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); ret = mcp3422_update_config(adc, config); - if (ret < 0) + if (ret < 0) { + mutex_unlock(&adc->lock); return ret; + } msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]); } - return mcp3422_read(adc, value, &config); + ret = mcp3422_read(adc, value, &config); + + mutex_unlock(&adc->lock); + + return ret; } static int mcp3422_read_raw(struct iio_dev *iio, --- linux-oracle-5.4.0.orig/drivers/iio/adc/mcp3911.c +++ linux-oracle-5.4.0/drivers/iio/adc/mcp3911.c @@ -38,8 +38,8 @@ #define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3) #define MCP3911_OFFCAL(x) (MCP3911_REG_OFFCAL_CH0 + x * 6) -/* Internal voltage reference in uV */ -#define MCP3911_INT_VREF_UV 1200000 +/* Internal voltage reference in mV */ +#define MCP3911_INT_VREF_MV 1200 #define MCP3911_REG_READ(reg, id) ((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff) #define MCP3911_REG_WRITE(reg, id) ((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff) @@ -111,6 +111,8 @@ if (ret) goto out; + *val = sign_extend32(*val, 23); + ret = IIO_VAL_INT; break; @@ -135,11 +137,18 @@ *val = ret / 1000; } else { - *val = MCP3911_INT_VREF_UV; + *val = MCP3911_INT_VREF_MV; } - *val2 = 24; - ret = IIO_VAL_FRACTIONAL_LOG2; + /* + * For 24bit Conversion + * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 + * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) + */ + + /* val2 = (2^23 * 1.5) */ + *val2 = 12582912; + ret = IIO_VAL_FRACTIONAL; break; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/men_z188_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/men_z188_adc.c @@ -103,6 +103,7 @@ struct z188_adc *adc; struct iio_dev *indio_dev; struct resource *mem; + int ret; indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc)); if (!indio_dev) @@ -129,8 +130,14 @@ adc->mem = mem; mcb_set_drvdata(dev, indio_dev); - return iio_device_register(indio_dev); + ret = iio_device_register(indio_dev); + if (ret) + goto err_unmap; + return 0; + +err_unmap: + iounmap(adc->base); err: mcb_release_mem(mem); return -ENXIO; --- linux-oracle-5.4.0.orig/drivers/iio/adc/meson_saradc.c +++ linux-oracle-5.4.0/drivers/iio/adc/meson_saradc.c @@ -71,7 +71,7 @@ #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18) #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16) #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10 - #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5 + #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 6 #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8) #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0) --- linux-oracle-5.4.0.orig/drivers/iio/adc/mt6577_auxadc.c +++ linux-oracle-5.4.0/drivers/iio/adc/mt6577_auxadc.c @@ -9,9 +9,9 @@ #include #include #include -#include -#include +#include #include +#include #include #include #include @@ -82,6 +82,10 @@ MT6577_AUXADC_CHANNEL(15), }; +/* For Voltage calculation */ +#define VOLTAGE_FULL_RANGE 1500 /* VA voltage */ +#define AUXADC_PRECISE 4096 /* 12 bits */ + static int mt_auxadc_get_cali_data(int rawdata, bool enable_cali) { return rawdata; @@ -191,6 +195,10 @@ } if (adc_dev->dev_comp->sample_data_cali) *val = mt_auxadc_get_cali_data(*val, true); + + /* Convert adc raw data to voltage: 0 - 1500 mV */ + *val = *val * VOLTAGE_FULL_RANGE / AUXADC_PRECISE; + return IIO_VAL_INT; default: @@ -279,6 +287,8 @@ goto err_disable_clk; } + adc_dev->dev_comp = device_get_match_data(&pdev->dev); + mutex_init(&adc_dev->lock); mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC, --- linux-oracle-5.4.0.orig/drivers/iio/adc/mxs-lradc-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/mxs-lradc-adc.c @@ -115,7 +115,8 @@ struct device *dev; void __iomem *base; - u32 buffer[10]; + /* Maximum of 8 channels + 8 byte ts */ + u32 buffer[10] __aligned(8); struct iio_trigger *trig; struct completion completion; spinlock_t lock; @@ -759,13 +760,13 @@ ret = mxs_lradc_adc_trigger_init(iio); if (ret) - goto err_trig; + return ret; ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time, &mxs_lradc_adc_trigger_handler, &mxs_lradc_adc_buffer_ops); if (ret) - return ret; + goto err_trig; adc->vref_mv = mxs_lradc_adc_vref_mv[lradc->soc]; @@ -803,9 +804,9 @@ err_dev: mxs_lradc_adc_hw_stop(adc); - mxs_lradc_adc_trigger_remove(iio); -err_trig: iio_triggered_buffer_cleanup(iio); +err_trig: + mxs_lradc_adc_trigger_remove(iio); return ret; } @@ -816,8 +817,8 @@ iio_device_unregister(iio); mxs_lradc_adc_hw_stop(adc); - mxs_lradc_adc_trigger_remove(iio); iio_triggered_buffer_cleanup(iio); + mxs_lradc_adc_trigger_remove(iio); return 0; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/palmas_gpadc.c +++ linux-oracle-5.4.0/drivers/iio/adc/palmas_gpadc.c @@ -630,7 +630,7 @@ static int palmas_gpadc_remove(struct platform_device *pdev) { - struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev); + struct iio_dev *indio_dev = dev_get_drvdata(&pdev->dev); struct palmas_gpadc *adc = iio_priv(indio_dev); if (adc->wakeup1_enable || adc->wakeup2_enable) @@ -656,8 +656,8 @@ adc_period = adc->auto_conversion_period; for (i = 0; i < 16; ++i) { - if (((1000 * (1 << i)) / 32) < adc_period) - continue; + if (((1000 * (1 << i)) / 32) >= adc_period) + break; } if (i > 0) i--; --- linux-oracle-5.4.0.orig/drivers/iio/adc/qcom-spmi-adc5.c +++ linux-oracle-5.4.0/drivers/iio/adc/qcom-spmi-adc5.c @@ -786,7 +786,7 @@ static struct platform_driver adc5_driver = { .driver = { - .name = "qcom-spmi-adc5.c", + .name = "qcom-spmi-adc5", .of_match_table = adc5_match_table, }, .probe = adc5_probe, --- linux-oracle-5.4.0.orig/drivers/iio/adc/qcom-spmi-vadc.c +++ linux-oracle-5.4.0/drivers/iio/adc/qcom-spmi-vadc.c @@ -598,7 +598,7 @@ VADC_CHAN_NO_SCALE(P_MUX16_1_3, 1) VADC_CHAN_NO_SCALE(LR_MUX1_BAT_THERM, 0) - VADC_CHAN_NO_SCALE(LR_MUX2_BAT_ID, 0) + VADC_CHAN_VOLT(LR_MUX2_BAT_ID, 0, SCALE_DEFAULT) VADC_CHAN_NO_SCALE(LR_MUX3_XO_THERM, 0) VADC_CHAN_NO_SCALE(LR_MUX4_AMUX_THM1, 0) VADC_CHAN_NO_SCALE(LR_MUX5_AMUX_THM2, 0) --- linux-oracle-5.4.0.orig/drivers/iio/adc/rcar-gyroadc.c +++ linux-oracle-5.4.0/drivers/iio/adc/rcar-gyroadc.c @@ -357,7 +357,7 @@ num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3); break; default: - return -EINVAL; + goto err_e_inval; } /* @@ -374,7 +374,7 @@ dev_err(dev, "Failed to get child reg property of ADC \"%pOFn\".\n", child); - return ret; + goto err_of_node_put; } /* Channel number is too high. */ @@ -382,7 +382,7 @@ dev_err(dev, "Only %i channels supported with %pOFn, but reg = <%i>.\n", num_channels, child, reg); - return -EINVAL; + goto err_e_inval; } } @@ -391,7 +391,7 @@ dev_err(dev, "Channel %i uses different ADC mode than the rest.\n", reg); - return -EINVAL; + goto err_e_inval; } /* Channel is valid, grab the regulator. */ @@ -401,7 +401,8 @@ if (IS_ERR(vref)) { dev_dbg(dev, "Channel %i 'vref' supply not connected.\n", reg); - return PTR_ERR(vref); + ret = PTR_ERR(vref); + goto err_of_node_put; } priv->vref[reg] = vref; @@ -425,8 +426,10 @@ * attached to the GyroADC at a time, so if we found it, * we can stop parsing here. */ - if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) + if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) { + of_node_put(child); break; + } } if (first) { @@ -435,6 +438,12 @@ } return 0; + +err_e_inval: + ret = -EINVAL; +err_of_node_put: + of_node_put(child); + return ret; } static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev) --- linux-oracle-5.4.0.orig/drivers/iio/adc/rockchip_saradc.c +++ linux-oracle-5.4.0/drivers/iio/adc/rockchip_saradc.c @@ -372,7 +372,7 @@ ret = clk_prepare_enable(info->clk); if (ret) - return ret; + clk_disable_unprepare(info->pclk); return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/sc27xx_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/sc27xx_adc.c @@ -36,8 +36,8 @@ /* Bits and mask definition for SC27XX_ADC_CH_CFG register */ #define SC27XX_ADC_CHN_ID_MASK GENMASK(4, 0) -#define SC27XX_ADC_SCALE_MASK GENMASK(10, 8) -#define SC27XX_ADC_SCALE_SHIFT 8 +#define SC27XX_ADC_SCALE_MASK GENMASK(10, 9) +#define SC27XX_ADC_SCALE_SHIFT 9 /* Bits definitions for SC27XX_ADC_INT_EN registers */ #define SC27XX_ADC_IRQ_EN BIT(0) @@ -103,14 +103,14 @@ 100, 341, }; -static const struct sc27xx_adc_linear_graph big_scale_graph_calib = { - 4200, 856, - 3600, 733, +static const struct sc27xx_adc_linear_graph sc2731_big_scale_graph_calib = { + 4200, 850, + 3600, 728, }; -static const struct sc27xx_adc_linear_graph small_scale_graph_calib = { - 1000, 833, - 100, 80, +static const struct sc27xx_adc_linear_graph sc2731_small_scale_graph_calib = { + 1000, 838, + 100, 84, }; static int sc27xx_adc_get_calib_data(u32 calib_data, int calib_adc) @@ -130,11 +130,11 @@ size_t len; if (big_scale) { - calib_graph = &big_scale_graph_calib; + calib_graph = &sc2731_big_scale_graph_calib; graph = &big_scale_graph; cell_name = "big_scale_calib"; } else { - calib_graph = &small_scale_graph_calib; + calib_graph = &sc2731_small_scale_graph_calib; graph = &small_scale_graph; cell_name = "small_scale_calib"; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/stm32-adc-core.c +++ linux-oracle-5.4.0/drivers/iio/adc/stm32-adc-core.c @@ -65,12 +65,14 @@ * @clk_sel: clock selection routine * @max_clk_rate_hz: maximum analog clock rate (Hz, from datasheet) * @has_syscfg: SYSCFG capability flags + * @num_irqs: number of interrupt lines */ struct stm32_adc_priv_cfg { const struct stm32_adc_common_regs *regs; int (*clk_sel)(struct platform_device *, struct stm32_adc_priv *); u32 max_clk_rate_hz; unsigned int has_syscfg; + unsigned int num_irqs; }; /** @@ -372,21 +374,15 @@ struct device_node *np = pdev->dev.of_node; unsigned int i; - for (i = 0; i < STM32_ADC_MAX_ADCS; i++) { + /* + * Interrupt(s) must be provided, depending on the compatible: + * - stm32f4/h7 shares a common interrupt line. + * - stm32mp1, has one line per ADC + */ + for (i = 0; i < priv->cfg->num_irqs; i++) { priv->irq[i] = platform_get_irq(pdev, i); - if (priv->irq[i] < 0) { - /* - * At least one interrupt must be provided, make others - * optional: - * - stm32f4/h7 shares a common interrupt. - * - stm32mp1, has one line per ADC (either for ADC1, - * ADC2 or both). - */ - if (i && priv->irq[i] == -ENXIO) - continue; - + if (priv->irq[i] < 0) return priv->irq[i]; - } } priv->domain = irq_domain_add_simple(np, STM32_ADC_MAX_ADCS, 0, @@ -397,9 +393,7 @@ return -ENOMEM; } - for (i = 0; i < STM32_ADC_MAX_ADCS; i++) { - if (priv->irq[i] < 0) - continue; + for (i = 0; i < priv->cfg->num_irqs; i++) { irq_set_chained_handler(priv->irq[i], stm32_adc_irq_handler); irq_set_handler_data(priv->irq[i], priv); } @@ -417,11 +411,8 @@ irq_dispose_mapping(irq_find_mapping(priv->domain, hwirq)); irq_domain_remove(priv->domain); - for (i = 0; i < STM32_ADC_MAX_ADCS; i++) { - if (priv->irq[i] < 0) - continue; + for (i = 0; i < priv->cfg->num_irqs; i++) irq_set_chained_handler(priv->irq[i], NULL); - } } static int stm32_adc_core_switches_supply_en(struct stm32_adc_priv *priv, @@ -789,6 +780,13 @@ { return stm32_adc_core_hw_start(dev); } + +static int stm32_adc_core_runtime_idle(struct device *dev) +{ + pm_runtime_mark_last_busy(dev); + + return 0; +} #endif static const struct dev_pm_ops stm32_adc_core_pm_ops = { @@ -796,13 +794,14 @@ pm_runtime_force_resume) SET_RUNTIME_PM_OPS(stm32_adc_core_runtime_suspend, stm32_adc_core_runtime_resume, - NULL) + stm32_adc_core_runtime_idle) }; static const struct stm32_adc_priv_cfg stm32f4_adc_priv_cfg = { .regs = &stm32f4_adc_common_regs, .clk_sel = stm32f4_adc_clk_sel, .max_clk_rate_hz = 36000000, + .num_irqs = 1, }; static const struct stm32_adc_priv_cfg stm32h7_adc_priv_cfg = { @@ -810,13 +809,15 @@ .clk_sel = stm32h7_adc_clk_sel, .max_clk_rate_hz = 36000000, .has_syscfg = HAS_VBOOSTER, + .num_irqs = 1, }; static const struct stm32_adc_priv_cfg stm32mp1_adc_priv_cfg = { .regs = &stm32h7_adc_common_regs, .clk_sel = stm32h7_adc_clk_sel, - .max_clk_rate_hz = 40000000, + .max_clk_rate_hz = 36000000, .has_syscfg = HAS_VBOOSTER | HAS_ANASWVDD, + .num_irqs = 2, }; static const struct of_device_id stm32_adc_of_match[] = { --- linux-oracle-5.4.0.orig/drivers/iio/adc/stm32-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/stm32-adc.c @@ -933,6 +933,7 @@ static void stm32h7_adc_unprepare(struct stm32_adc *adc) { + stm32_adc_writel(adc, STM32H7_ADC_PCSEL, 0); stm32h7_adc_disable(adc); stm32h7_adc_enter_pwr_down(adc); } @@ -1367,8 +1368,30 @@ static void stm32_adc_dma_buffer_done(void *data) { struct iio_dev *indio_dev = data; + struct stm32_adc *adc = iio_priv(indio_dev); + int residue = stm32_adc_dma_residue(adc); + + /* + * In DMA mode the trigger services of IIO are not used + * (e.g. no call to iio_trigger_poll). + * Calling irq handler associated to the hardware trigger is not + * relevant as the conversions have already been done. Data + * transfers are performed directly in DMA callback instead. + * This implementation avoids to call trigger irq handler that + * may sleep, in an atomic context (DMA irq handler context). + */ + dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi); + + while (residue >= indio_dev->scan_bytes) { + u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi]; - iio_trigger_poll_chained(indio_dev->trig); + iio_push_to_buffers(indio_dev, buffer); + + residue -= indio_dev->scan_bytes; + adc->bufi += indio_dev->scan_bytes; + if (adc->bufi >= adc->rx_buf_sz) + adc->bufi = 0; + } } static int stm32_adc_dma_start(struct iio_dev *indio_dev) @@ -1735,15 +1758,27 @@ return 0; } -static int stm32_adc_dma_request(struct iio_dev *indio_dev) +static int stm32_adc_dma_request(struct device *dev, struct iio_dev *indio_dev) { struct stm32_adc *adc = iio_priv(indio_dev); struct dma_slave_config config; int ret; - adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx"); - if (!adc->dma_chan) + adc->dma_chan = dma_request_chan(dev, "rx"); + if (IS_ERR(adc->dma_chan)) { + ret = PTR_ERR(adc->dma_chan); + if (ret != -ENODEV) { + if (ret != -EPROBE_DEFER) + dev_err(dev, + "DMA channel request failed with %d\n", + ret); + return ret; + } + + /* DMA is optional: fall back to IRQ mode */ + adc->dma_chan = NULL; return 0; + } adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, STM32_DMA_BUFFER_SIZE, @@ -1778,6 +1813,7 @@ { struct iio_dev *indio_dev; struct device *dev = &pdev->dev; + irqreturn_t (*handler)(int irq, void *p) = NULL; struct stm32_adc *adc; int ret; @@ -1839,13 +1875,15 @@ if (ret < 0) return ret; - ret = stm32_adc_dma_request(indio_dev); + ret = stm32_adc_dma_request(dev, indio_dev); if (ret < 0) return ret; + if (!adc->dma_chan) + handler = &stm32_adc_trigger_handler; + ret = iio_triggered_buffer_setup(indio_dev, - &iio_pollfunc_store_time, - &stm32_adc_trigger_handler, + &iio_pollfunc_store_time, handler, &stm32_adc_buffer_setup_ops); if (ret) { dev_err(&pdev->dev, "buffer setup failed\n"); --- linux-oracle-5.4.0.orig/drivers/iio/adc/stm32-dfsdm-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/stm32-dfsdm-adc.c @@ -62,7 +62,7 @@ struct stm32_dfsdm_dev_data { int type; - int (*init)(struct iio_dev *indio_dev); + int (*init)(struct device *dev, struct iio_dev *indio_dev); unsigned int num_channels; const struct regmap_config *regmap_cfg; }; @@ -842,31 +842,6 @@ } } -static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) -{ - struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->indio_dev; - struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); - int available = stm32_dfsdm_adc_dma_residue(adc); - - while (available >= indio_dev->scan_bytes) { - s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; - - stm32_dfsdm_process_data(adc, buffer); - - iio_push_to_buffers_with_timestamp(indio_dev, buffer, - pf->timestamp); - available -= indio_dev->scan_bytes; - adc->bufi += indio_dev->scan_bytes; - if (adc->bufi >= adc->buf_sz) - adc->bufi = 0; - } - - iio_trigger_notify_done(indio_dev->trig); - - return IRQ_HANDLED; -} - static void stm32_dfsdm_dma_buffer_done(void *data) { struct iio_dev *indio_dev = data; @@ -874,11 +849,6 @@ int available = stm32_dfsdm_adc_dma_residue(adc); size_t old_pos; - if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) { - iio_trigger_poll_chained(indio_dev->trig); - return; - } - /* * FIXME: In Kernel interface does not support cyclic DMA buffer,and * offers only an interface to push data samples per samples. @@ -906,7 +876,15 @@ adc->bufi = 0; old_pos = 0; } - /* regular iio buffer without trigger */ + /* + * In DMA mode the trigger services of IIO are not used + * (e.g. no call to iio_trigger_poll). + * Calling irq handler associated to the hardware trigger is not + * relevant as the conversions have already been done. Data + * transfers are performed directly in DMA callback instead. + * This implementation avoids to call trigger irq handler that + * may sleep, in an atomic context (DMA irq handler context). + */ if (adc->dev_data->type == DFSDM_IIO) iio_push_to_buffers(indio_dev, buffer); } @@ -1204,6 +1182,8 @@ stm32_dfsdm_stop_conv(adc); + stm32_dfsdm_process_data(adc, res); + stop_dfsdm: stm32_dfsdm_stop_dfsdm(adc->dfsdm); @@ -1379,13 +1359,18 @@ } } -static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev) +static int stm32_dfsdm_dma_request(struct device *dev, + struct iio_dev *indio_dev) { struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); - adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx"); - if (!adc->dma_chan) - return -EINVAL; + adc->dma_chan = dma_request_chan(dev, "rx"); + if (IS_ERR(adc->dma_chan)) { + int ret = PTR_ERR(adc->dma_chan); + + adc->dma_chan = NULL; + return ret; + } adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, DFSDM_DMA_BUFFER_SIZE, @@ -1435,7 +1420,7 @@ &adc->dfsdm->ch_list[ch->channel]); } -static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) +static int stm32_dfsdm_audio_init(struct device *dev, struct iio_dev *indio_dev) { struct iio_chan_spec *ch; struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); @@ -1462,10 +1447,10 @@ indio_dev->num_channels = 1; indio_dev->channels = ch; - return stm32_dfsdm_dma_request(indio_dev); + return stm32_dfsdm_dma_request(dev, indio_dev); } -static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) +static int stm32_dfsdm_adc_init(struct device *dev, struct iio_dev *indio_dev) { struct iio_chan_spec *ch; struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); @@ -1509,14 +1494,22 @@ init_completion(&adc->completion); /* Optionally request DMA */ - if (stm32_dfsdm_dma_request(indio_dev)) { - dev_dbg(&indio_dev->dev, "No DMA support\n"); + ret = stm32_dfsdm_dma_request(dev, indio_dev); + if (ret) { + if (ret != -ENODEV) { + if (ret != -EPROBE_DEFER) + dev_err(dev, + "DMA channel request failed with %d\n", + ret); + return ret; + } + + dev_dbg(dev, "No DMA support\n"); return 0; } ret = iio_triggered_buffer_setup(indio_dev, - &iio_pollfunc_store_time, - &stm32_dfsdm_adc_trigger_handler, + &iio_pollfunc_store_time, NULL, &stm32_dfsdm_buffer_setup_ops); if (ret) { stm32_dfsdm_dma_release(indio_dev); @@ -1551,6 +1544,7 @@ }, {} }; +MODULE_DEVICE_TABLE(of, stm32_dfsdm_adc_match); static int stm32_dfsdm_adc_probe(struct platform_device *pdev) { @@ -1624,7 +1618,7 @@ adc->dfsdm->fl_list[adc->fl_id].sync_mode = val; adc->dev_data = dev_data; - ret = dev_data->init(iio); + ret = dev_data->init(dev, iio); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/iio/adc/stmpe-adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/stmpe-adc.c @@ -61,7 +61,7 @@ static int stmpe_read_voltage(struct stmpe_adc *info, struct iio_chan_spec const *chan, int *val) { - long ret; + unsigned long ret; mutex_lock(&info->lock); @@ -79,7 +79,7 @@ ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT); - if (ret <= 0) { + if (ret == 0) { stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, STMPE_ADC_CH(info->channel)); mutex_unlock(&info->lock); @@ -96,7 +96,7 @@ static int stmpe_read_temp(struct stmpe_adc *info, struct iio_chan_spec const *chan, int *val) { - long ret; + unsigned long ret; mutex_lock(&info->lock); @@ -114,7 +114,7 @@ ret = wait_for_completion_timeout(&info->completion, STMPE_ADC_TIMEOUT); - if (ret <= 0) { + if (ret == 0) { mutex_unlock(&info->lock); return -ETIMEDOUT; } --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-adc081c.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-adc081c.c @@ -33,6 +33,12 @@ /* 8, 10 or 12 */ int bits; + + /* Ensure natural alignment of buffer elements */ + struct { + u16 channel; + s64 ts __aligned(8); + } scan; }; #define REG_CONV_RES 0x00 @@ -128,14 +134,13 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc081c *data = iio_priv(indio_dev); - u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */ int ret; ret = i2c_smbus_read_word_swapped(data->i2c, REG_CONV_RES); if (ret < 0) goto out; - buf[0] = ret; - iio_push_to_buffers_with_timestamp(indio_dev, buf, + data->scan.channel = ret; + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); out: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-adc0832.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-adc0832.c @@ -28,6 +28,12 @@ struct regulator *reg; struct mutex lock; u8 mux_bits; + /* + * Max size needed: 16x 1 byte ADC data + 8 bytes timestamp + * May be shorter if not all channels are enabled subject + * to the timestamp remaining 8 byte aligned. + */ + u8 data[24] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -199,7 +205,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc0832 *adc = iio_priv(indio_dev); - u8 data[24] = { }; /* 16x 1 byte ADC data + 8 bytes timestamp */ int scan_index; int i = 0; @@ -217,10 +222,10 @@ goto out; } - data[i] = ret; + adc->data[i] = ret; i++; } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-adc084s021.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-adc084s021.c @@ -25,6 +25,11 @@ struct spi_transfer spi_trans; struct regulator *reg; struct mutex lock; + /* Buffer used to align data */ + struct { + __be16 channels[4]; + s64 ts __aligned(8); + } scan; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache line. @@ -140,14 +145,13 @@ struct iio_poll_func *pf = pollfunc; struct iio_dev *indio_dev = pf->indio_dev; struct adc084s021 *adc = iio_priv(indio_dev); - __be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */ mutex_lock(&adc->lock); - if (adc084s021_adc_conversion(adc, &data) < 0) + if (adc084s021_adc_conversion(adc, adc->scan.channels) < 0) dev_err(&adc->spi->dev, "Failed to read data\n"); - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan, iio_get_time_ns(indio_dev)); mutex_unlock(&adc->lock); iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-adc12138.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-adc12138.c @@ -47,6 +47,12 @@ struct completion complete; /* The number of cclk periods for the S/H's acquisition time */ unsigned int acquisition_time; + /* + * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp. + * Less may be need if not all channels are enabled, as long as + * the 8 byte alignment of the timestamp is maintained. + */ + __be16 data[20] __aligned(8); u8 tx_buf[2] ____cacheline_aligned; u8 rx_buf[2]; @@ -329,7 +335,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct adc12138 *adc = iio_priv(indio_dev); - __be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */ __be16 trash; int ret; int scan_index; @@ -345,7 +350,7 @@ reinit_completion(&adc->complete); ret = adc12138_start_and_read_conv(adc, scan_chan, - i ? &data[i - 1] : &trash); + i ? &adc->data[i - 1] : &trash); if (ret) { dev_warn(&adc->spi->dev, "failed to start conversion\n"); @@ -362,7 +367,7 @@ } if (i) { - ret = adc12138_read_conv_data(adc, &data[i - 1]); + ret = adc12138_read_conv_data(adc, &adc->data[i - 1]); if (ret) { dev_warn(&adc->spi->dev, "failed to get conversion data\n"); @@ -370,7 +375,7 @@ } } - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, adc->data, iio_get_time_ns(indio_dev)); out: mutex_unlock(&adc->lock); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-adc128s052.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-adc128s052.c @@ -172,7 +172,13 @@ mutex_init(&adc->lock); ret = iio_device_register(indio_dev); + if (ret) + goto err_disable_regulator; + return 0; + +err_disable_regulator: + regulator_disable(adc->reg); return ret; } @@ -188,13 +194,13 @@ } static const struct of_device_id adc128_of_match[] = { - { .compatible = "ti,adc128s052", }, - { .compatible = "ti,adc122s021", }, - { .compatible = "ti,adc122s051", }, - { .compatible = "ti,adc122s101", }, - { .compatible = "ti,adc124s021", }, - { .compatible = "ti,adc124s051", }, - { .compatible = "ti,adc124s101", }, + { .compatible = "ti,adc128s052", .data = (void*)0L, }, + { .compatible = "ti,adc122s021", .data = (void*)1L, }, + { .compatible = "ti,adc122s051", .data = (void*)1L, }, + { .compatible = "ti,adc122s101", .data = (void*)1L, }, + { .compatible = "ti,adc124s021", .data = (void*)2L, }, + { .compatible = "ti,adc124s051", .data = (void*)2L, }, + { .compatible = "ti,adc124s101", .data = (void*)2L, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, adc128_of_match); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-ads1015.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-ads1015.c @@ -309,6 +309,7 @@ IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; +#ifdef CONFIG_PM static int ads1015_set_power_state(struct ads1015_data *data, bool on) { int ret; @@ -326,6 +327,15 @@ return ret < 0 ? ret : 0; } +#else /* !CONFIG_PM */ + +static int ads1015_set_power_state(struct ads1015_data *data, bool on) +{ + return 0; +} + +#endif /* !CONFIG_PM */ + static int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) { @@ -378,10 +388,14 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ads1015_data *data = iio_priv(indio_dev); - s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */ + /* Ensure natural alignment of timestamp */ + struct { + s16 chan; + s64 timestamp __aligned(8); + } scan; int chan, ret, res; - memset(buf, 0, sizeof(buf)); + memset(&scan, 0, sizeof(scan)); mutex_lock(&data->lock); chan = find_first_bit(indio_dev->active_scan_mask, @@ -392,10 +406,10 @@ goto err; } - buf[0] = res; + scan.chan = res; mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-ads124s08.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-ads124s08.c @@ -97,6 +97,14 @@ struct gpio_desc *reset_gpio; struct spi_device *spi; struct mutex lock; + /* + * Used to correctly align data. + * Ensure timestamp is naturally aligned. + * Note that the full buffer length may not be needed if not + * all channels are enabled, as long as the alignment of the + * timestamp is maintained. + */ + u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u32)] __aligned(8); u8 data[5] ____cacheline_aligned; }; @@ -174,9 +182,9 @@ struct ads124s_private *priv = iio_priv(indio_dev); if (priv->reset_gpio) { - gpiod_set_value(priv->reset_gpio, 0); + gpiod_set_value_cansleep(priv->reset_gpio, 0); udelay(200); - gpiod_set_value(priv->reset_gpio, 1); + gpiod_set_value_cansleep(priv->reset_gpio, 1); } else { return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET); } @@ -270,7 +278,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ads124s_private *priv = iio_priv(indio_dev); - u32 buffer[ADS124S08_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; int scan_index, j = 0; int ret; @@ -285,7 +292,7 @@ if (ret) dev_err(&priv->spi->dev, "Start ADC conversions failed\n"); - buffer[j] = ads124s_read(indio_dev, scan_index); + priv->buffer[j] = ads124s_read(indio_dev, scan_index); ret = ads124s_write_cmd(indio_dev, ADS124S08_STOP_CONV); if (ret) dev_err(&priv->spi->dev, "Stop ADC conversions failed\n"); @@ -293,7 +300,7 @@ j++; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer, pf->timestamp); iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-ads7950.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-ads7950.c @@ -569,7 +569,6 @@ st->ring_xfer.tx_buf = &st->tx_buf[0]; st->ring_xfer.rx_buf = &st->rx_buf[0]; /* len will be set later */ - st->ring_xfer.cs_change = true; spi_message_add_tail(&st->ring_xfer, &st->ring_msg); @@ -636,6 +635,7 @@ st->chip.label = dev_name(&st->spi->dev); st->chip.parent = &st->spi->dev; st->chip.owner = THIS_MODULE; + st->chip.can_sleep = true; st->chip.base = -1; st->chip.ngpio = TI_ADS7950_NUM_GPIOS; st->chip.get_direction = ti_ads7950_get_direction; --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-ads8344.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-ads8344.c @@ -29,19 +29,20 @@ struct mutex lock; u8 tx_buf ____cacheline_aligned; - u16 rx_buf; + u8 rx_buf[3]; }; -#define ADS8344_VOLTAGE_CHANNEL(chan, si) \ +#define ADS8344_VOLTAGE_CHANNEL(chan, addr) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .channel = chan, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = addr, \ } -#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si) \ +#define ADS8344_VOLTAGE_CHANNEL_DIFF(chan1, chan2, addr) \ { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ @@ -50,6 +51,7 @@ .differential = 1, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .address = addr, \ } static const struct iio_chan_spec ads8344_channels[] = { @@ -89,11 +91,11 @@ udelay(9); - ret = spi_read(spi, &adc->rx_buf, 2); + ret = spi_read(spi, adc->rx_buf, sizeof(adc->rx_buf)); if (ret) return ret; - return adc->rx_buf; + return adc->rx_buf[0] << 9 | adc->rx_buf[1] << 1 | adc->rx_buf[2] >> 7; } static int ads8344_read_raw(struct iio_dev *iio, @@ -105,7 +107,7 @@ switch (mask) { case IIO_CHAN_INFO_RAW: mutex_lock(&adc->lock); - *value = ads8344_adc_conversion(adc, channel->scan_index, + *value = ads8344_adc_conversion(adc, channel->address, channel->differential); mutex_unlock(&adc->lock); if (*value < 0) --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti-ads8688.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti-ads8688.c @@ -383,7 +383,8 @@ { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; + /* Ensure naturally aligned timestamp */ + u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { }; int i, j = 0; for (i = 0; i < indio_dev->masklength; i++) { --- linux-oracle-5.4.0.orig/drivers/iio/adc/ti_am335x_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/ti_am335x_adc.c @@ -656,8 +656,10 @@ platform_set_drvdata(pdev, indio_dev); err = tiadc_request_dma(pdev, adc_dev); - if (err && err == -EPROBE_DEFER) + if (err && err != -ENODEV) { + dev_err_probe(&pdev->dev, err, "DMA request failed\n"); goto err_dma; + } return 0; --- linux-oracle-5.4.0.orig/drivers/iio/adc/twl6030-gpadc.c +++ linux-oracle-5.4.0/drivers/iio/adc/twl6030-gpadc.c @@ -57,6 +57,18 @@ #define TWL6030_GPADCS BIT(1) #define TWL6030_GPADCR BIT(0) +#define USB_VBUS_CTRL_SET 0x04 +#define USB_ID_CTRL_SET 0x06 + +#define TWL6030_MISC1 0xE4 +#define VBUS_MEAS 0x01 +#define ID_MEAS 0x01 + +#define VAC_MEAS 0x04 +#define VBAT_MEAS 0x02 +#define BB_MEAS 0x01 + + /** * struct twl6030_chnl_calib - channel calibration * @gain: slope coefficient for ideal curve @@ -911,6 +923,8 @@ ret = devm_request_threaded_irq(dev, irq, NULL, twl6030_gpadc_irq_handler, IRQF_ONESHOT, "twl6030_gpadc", indio_dev); + if (ret) + return ret; ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK); if (ret < 0) { @@ -925,6 +939,26 @@ return ret; } + ret = twl_i2c_write_u8(TWL_MODULE_USB, VBUS_MEAS, USB_VBUS_CTRL_SET); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + + ret = twl_i2c_write_u8(TWL_MODULE_USB, ID_MEAS, USB_ID_CTRL_SET); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, + VBAT_MEAS | BB_MEAS | VAC_MEAS, + TWL6030_MISC1); + if (ret < 0) { + dev_err(dev, "failed to wire up inputs\n"); + return ret; + } + indio_dev->name = DRIVER_NAME; indio_dev->dev.parent = dev; indio_dev->info = &twl6030_gpadc_iio_info; --- linux-oracle-5.4.0.orig/drivers/iio/adc/vf610_adc.c +++ linux-oracle-5.4.0/drivers/iio/adc/vf610_adc.c @@ -167,7 +167,11 @@ u32 sample_freq_avail[5]; struct completion completion; - u16 buffer[8]; + /* Ensure the timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; @@ -579,9 +583,9 @@ if (coco & VF610_ADC_HS_COCO0) { info->value = vf610_adc_read_data(info); if (iio_buffer_enabled(indio_dev)) { - info->buffer[0] = info->value; + info->scan.chan = info->value; iio_push_to_buffers_with_timestamp(indio_dev, - info->buffer, + &info->scan, iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); } else --- linux-oracle-5.4.0.orig/drivers/iio/adc/xilinx-xadc-core.c +++ linux-oracle-5.4.0/drivers/iio/adc/xilinx-xadc-core.c @@ -102,6 +102,16 @@ #define XADC_FLAGS_BUFFERED BIT(0) +/* + * The XADC hardware supports a samplerate of up to 1MSPS. Unfortunately it does + * not have a hardware FIFO. Which means an interrupt is generated for each + * conversion sequence. At 1MSPS sample rate the CPU in ZYNQ7000 is completely + * overloaded by the interrupts that it soft-lockups. For this reason the driver + * limits the maximum samplerate 150kSPS. At this rate the CPU is fairly busy, + * but still responsive. + */ +#define XADC_MAX_SAMPLERATE 150000 + static void xadc_write_reg(struct xadc *xadc, unsigned int reg, uint32_t val) { @@ -674,7 +684,7 @@ spin_lock_irqsave(&xadc->lock, flags); xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val); - xadc_write_reg(xadc, XADC_AXI_REG_IPISR, val & XADC_AXI_INT_EOS); + xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS); if (state) val |= XADC_AXI_INT_EOS; else @@ -722,13 +732,14 @@ { uint16_t val; + /* Powerdown the ADC-B when it is not needed. */ switch (seq_mode) { case XADC_CONF1_SEQ_SIMULTANEOUS: case XADC_CONF1_SEQ_INDEPENDENT: - val = XADC_CONF2_PD_ADC_B; + val = 0; break; default: - val = 0; + val = XADC_CONF2_PD_ADC_B; break; } @@ -797,6 +808,16 @@ if (ret) goto err; + /* + * In simultaneous mode the upper and lower aux channels are samples at + * the same time. In this mode the upper 8 bits in the sequencer + * register are don't care and the lower 8 bits control two channels + * each. As such we must set the bit if either the channel in the lower + * group or the upper group is enabled. + */ + if (seq_mode == XADC_CONF1_SEQ_SIMULTANEOUS) + scan_mask = ((scan_mask >> 8) | scan_mask) & 0xff0000; + ret = xadc_write_adc_reg(xadc, XADC_REG_SEQ(1), scan_mask >> 16); if (ret) goto err; @@ -823,11 +844,27 @@ .postdisable = &xadc_postdisable, }; +static int xadc_read_samplerate(struct xadc *xadc) +{ + unsigned int div; + uint16_t val16; + int ret; + + ret = xadc_read_adc_reg(xadc, XADC_REG_CONF2, &val16); + if (ret) + return ret; + + div = (val16 & XADC_CONF2_DIV_MASK) >> XADC_CONF2_DIV_OFFSET; + if (div < 2) + div = 2; + + return xadc_get_dclk_rate(xadc) / div / 26; +} + static int xadc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long info) { struct xadc *xadc = iio_priv(indio_dev); - unsigned int div; uint16_t val16; int ret; @@ -880,41 +917,31 @@ *val = -((273150 << 12) / 503975); return IIO_VAL_INT; case IIO_CHAN_INFO_SAMP_FREQ: - ret = xadc_read_adc_reg(xadc, XADC_REG_CONF2, &val16); - if (ret) + ret = xadc_read_samplerate(xadc); + if (ret < 0) return ret; - div = (val16 & XADC_CONF2_DIV_MASK) >> XADC_CONF2_DIV_OFFSET; - if (div < 2) - div = 2; - - *val = xadc_get_dclk_rate(xadc) / div / 26; - + *val = ret; return IIO_VAL_INT; default: return -EINVAL; } } -static int xadc_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, int val, int val2, long info) +static int xadc_write_samplerate(struct xadc *xadc, int val) { - struct xadc *xadc = iio_priv(indio_dev); unsigned long clk_rate = xadc_get_dclk_rate(xadc); unsigned int div; if (!clk_rate) return -EINVAL; - if (info != IIO_CHAN_INFO_SAMP_FREQ) - return -EINVAL; - if (val <= 0) return -EINVAL; /* Max. 150 kSPS */ - if (val > 150000) - val = 150000; + if (val > XADC_MAX_SAMPLERATE) + val = XADC_MAX_SAMPLERATE; val *= 26; @@ -927,7 +954,7 @@ * limit. */ div = clk_rate / val; - if (clk_rate / div / 26 > 150000) + if (clk_rate / div / 26 > XADC_MAX_SAMPLERATE) div++; if (div < 2) div = 2; @@ -938,6 +965,17 @@ div << XADC_CONF2_DIV_OFFSET); } +static int xadc_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long info) +{ + struct xadc *xadc = iio_priv(indio_dev); + + if (info != IIO_CHAN_INFO_SAMP_FREQ) + return -EINVAL; + + return xadc_write_samplerate(xadc, val); +} + static const struct iio_event_spec xadc_temp_events[] = { { .type = IIO_EV_TYPE_THRESH, @@ -1225,6 +1263,21 @@ if (ret) goto err_free_samplerate_trigger; + /* + * Make sure not to exceed the maximum samplerate since otherwise the + * resulting interrupt storm will soft-lock the system. + */ + if (xadc->ops->flags & XADC_FLAGS_BUFFERED) { + ret = xadc_read_samplerate(xadc); + if (ret < 0) + goto err_free_samplerate_trigger; + if (ret > XADC_MAX_SAMPLERATE) { + ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE); + if (ret < 0) + goto err_free_samplerate_trigger; + } + } + ret = request_irq(xadc->irq, xadc->ops->interrupt_handler, 0, dev_name(&pdev->dev), indio_dev); if (ret) --- linux-oracle-5.4.0.orig/drivers/iio/addac/Kconfig +++ linux-oracle-5.4.0/drivers/iio/addac/Kconfig @@ -0,0 +1,24 @@ +# +# ADC DAC drivers +# +# When adding new entries keep the list in alphabetical order + +menu "Analog to digital and digital to analog converters" + +config STX104 + tristate "Apex Embedded Systems STX104 driver" + depends on PC104 && X86 + select ISA_BUS_API + select GPIOLIB + help + Say yes here to build support for the Apex Embedded Systems STX104 + integrated analog PC/104 card. + + This driver supports the 16 channels of single-ended (8 channels of + differential) analog inputs, 2 channels of analog output, 4 digital + inputs, and 4 digital outputs provided by the STX104. + + The base port addresses for the devices may be configured via the base + array module parameter. + +endmenu --- linux-oracle-5.4.0.orig/drivers/iio/addac/Makefile +++ linux-oracle-5.4.0/drivers/iio/addac/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for industrial I/O ADDAC drivers +# + +# When adding new entries keep the list in alphabetical order +obj-$(CONFIG_STX104) += stx104.o --- linux-oracle-5.4.0.orig/drivers/iio/addac/stx104.c +++ linux-oracle-5.4.0/drivers/iio/addac/stx104.c @@ -0,0 +1,415 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * IIO driver for the Apex Embedded Systems STX104 + * Copyright (C) 2016 William Breathitt Gray + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STX104_OUT_CHAN(chan) { \ + .type = IIO_VOLTAGE, \ + .channel = chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .indexed = 1, \ + .output = 1 \ +} +#define STX104_IN_CHAN(chan, diff) { \ + .type = IIO_VOLTAGE, \ + .channel = chan, \ + .channel2 = chan, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \ + BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .indexed = 1, \ + .differential = diff \ +} + +#define STX104_NUM_OUT_CHAN 2 + +#define STX104_EXTENT 16 + +static unsigned int base[max_num_isa_dev(STX104_EXTENT)]; +static unsigned int num_stx104; +module_param_hw_array(base, uint, ioport, &num_stx104, 0); +MODULE_PARM_DESC(base, "Apex Embedded Systems STX104 base addresses"); + +/** + * struct stx104_reg - device register structure + * @ssr_ad: Software Strobe Register and ADC Data + * @achan: ADC Channel + * @dio: Digital I/O + * @dac: DAC Channels + * @cir_asr: Clear Interrupts and ADC Status + * @acr: ADC Control + * @pccr_fsh: Pacer Clock Control and FIFO Status MSB + * @acfg: ADC Configuration + */ +struct stx104_reg { + u16 ssr_ad; + u8 achan; + u8 dio; + u16 dac[2]; + u8 cir_asr; + u8 acr; + u8 pccr_fsh; + u8 acfg; +}; + +/** + * struct stx104_iio - IIO device private data structure + * @lock: synchronization lock to prevent I/O race conditions + * @chan_out_states: channels' output states + * @reg: I/O address offset for the device registers + */ +struct stx104_iio { + struct mutex lock; + unsigned int chan_out_states[STX104_NUM_OUT_CHAN]; + struct stx104_reg __iomem *reg; +}; + +/** + * struct stx104_gpio - GPIO device private data structure + * @chip: instance of the gpio_chip + * @lock: synchronization lock to prevent I/O race conditions + * @base: base port address of the GPIO device + * @out_state: output bits state + */ +struct stx104_gpio { + struct gpio_chip chip; + spinlock_t lock; + u8 __iomem *base; + unsigned int out_state; +}; + +static int stx104_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, long mask) +{ + struct stx104_iio *const priv = iio_priv(indio_dev); + struct stx104_reg __iomem *const reg = priv->reg; + unsigned int adc_config; + int adbu; + int gain; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* get gain configuration */ + adc_config = ioread8(®->acfg); + gain = adc_config & 0x3; + + *val = 1 << gain; + return IIO_VAL_INT; + case IIO_CHAN_INFO_RAW: + if (chan->output) { + *val = priv->chan_out_states[chan->channel]; + return IIO_VAL_INT; + } + + mutex_lock(&priv->lock); + + /* select ADC channel */ + iowrite8(chan->channel | (chan->channel << 4), ®->achan); + + /* trigger ADC sample capture by writing to the 8-bit + * Software Strobe Register and wait for completion + */ + iowrite8(0, ®->ssr_ad); + while (ioread8(®->cir_asr) & BIT(7)); + + *val = ioread16(®->ssr_ad); + + mutex_unlock(&priv->lock); + return IIO_VAL_INT; + case IIO_CHAN_INFO_OFFSET: + /* get ADC bipolar/unipolar configuration */ + adc_config = ioread8(®->acfg); + adbu = !(adc_config & BIT(2)); + + *val = -32768 * adbu; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + /* get ADC bipolar/unipolar and gain configuration */ + adc_config = ioread8(®->acfg); + adbu = !(adc_config & BIT(2)); + gain = adc_config & 0x3; + + *val = 5; + *val2 = 15 - adbu + gain; + return IIO_VAL_FRACTIONAL_LOG2; + } + + return -EINVAL; +} + +static int stx104_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, long mask) +{ + struct stx104_iio *const priv = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* Only four gain states (x1, x2, x4, x8) */ + switch (val) { + case 1: + iowrite8(0, &priv->reg->acfg); + break; + case 2: + iowrite8(1, &priv->reg->acfg); + break; + case 4: + iowrite8(2, &priv->reg->acfg); + break; + case 8: + iowrite8(3, &priv->reg->acfg); + break; + default: + return -EINVAL; + } + + return 0; + case IIO_CHAN_INFO_RAW: + if (chan->output) { + /* DAC can only accept up to a 16-bit value */ + if ((unsigned int)val > 65535) + return -EINVAL; + + mutex_lock(&priv->lock); + + priv->chan_out_states[chan->channel] = val; + iowrite16(val, &priv->reg->dac[chan->channel]); + + mutex_unlock(&priv->lock); + return 0; + } + return -EINVAL; + } + + return -EINVAL; +} + +static const struct iio_info stx104_info = { + .read_raw = stx104_read_raw, + .write_raw = stx104_write_raw +}; + +/* single-ended input channels configuration */ +static const struct iio_chan_spec stx104_channels_sing[] = { + STX104_OUT_CHAN(0), STX104_OUT_CHAN(1), + STX104_IN_CHAN(0, 0), STX104_IN_CHAN(1, 0), STX104_IN_CHAN(2, 0), + STX104_IN_CHAN(3, 0), STX104_IN_CHAN(4, 0), STX104_IN_CHAN(5, 0), + STX104_IN_CHAN(6, 0), STX104_IN_CHAN(7, 0), STX104_IN_CHAN(8, 0), + STX104_IN_CHAN(9, 0), STX104_IN_CHAN(10, 0), STX104_IN_CHAN(11, 0), + STX104_IN_CHAN(12, 0), STX104_IN_CHAN(13, 0), STX104_IN_CHAN(14, 0), + STX104_IN_CHAN(15, 0) +}; +/* differential input channels configuration */ +static const struct iio_chan_spec stx104_channels_diff[] = { + STX104_OUT_CHAN(0), STX104_OUT_CHAN(1), + STX104_IN_CHAN(0, 1), STX104_IN_CHAN(1, 1), STX104_IN_CHAN(2, 1), + STX104_IN_CHAN(3, 1), STX104_IN_CHAN(4, 1), STX104_IN_CHAN(5, 1), + STX104_IN_CHAN(6, 1), STX104_IN_CHAN(7, 1) +}; + +static int stx104_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + /* GPIO 0-3 are input only, while the rest are output only */ + if (offset < 4) + return 1; + + return 0; +} + +static int stx104_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + if (offset >= 4) + return -EINVAL; + + return 0; +} + +static int stx104_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + if (offset < 4) + return -EINVAL; + + chip->set(chip, offset, value); + return 0; +} + +static int stx104_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + + if (offset >= 4) + return -EINVAL; + + return !!(ioread8(stx104gpio->base) & BIT(offset)); +} + +static int stx104_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, + unsigned long *bits) +{ + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + + *bits = ioread8(stx104gpio->base); + + return 0; +} + +static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + const unsigned int mask = BIT(offset) >> 4; + unsigned long flags; + + if (offset < 4) + return; + + spin_lock_irqsave(&stx104gpio->lock, flags); + + if (value) + stx104gpio->out_state |= mask; + else + stx104gpio->out_state &= ~mask; + + iowrite8(stx104gpio->out_state, stx104gpio->base); + + spin_unlock_irqrestore(&stx104gpio->lock, flags); +} + +#define STX104_NGPIO 8 +static const char *stx104_names[STX104_NGPIO] = { + "DIN0", "DIN1", "DIN2", "DIN3", "DOUT0", "DOUT1", "DOUT2", "DOUT3" +}; + +static void stx104_gpio_set_multiple(struct gpio_chip *chip, + unsigned long *mask, unsigned long *bits) +{ + struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip); + unsigned long flags; + + /* verify masked GPIO are output */ + if (!(*mask & 0xF0)) + return; + + *mask >>= 4; + *bits >>= 4; + + spin_lock_irqsave(&stx104gpio->lock, flags); + + stx104gpio->out_state &= ~*mask; + stx104gpio->out_state |= *mask & *bits; + iowrite8(stx104gpio->out_state, stx104gpio->base); + + spin_unlock_irqrestore(&stx104gpio->lock, flags); +} + +static int stx104_probe(struct device *dev, unsigned int id) +{ + struct iio_dev *indio_dev; + struct stx104_iio *priv; + struct stx104_gpio *stx104gpio; + int err; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + stx104gpio = devm_kzalloc(dev, sizeof(*stx104gpio), GFP_KERNEL); + if (!stx104gpio) + return -ENOMEM; + + if (!devm_request_region(dev, base[id], STX104_EXTENT, + dev_name(dev))) { + dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n", + base[id], base[id] + STX104_EXTENT); + return -EBUSY; + } + + priv = iio_priv(indio_dev); + priv->reg = devm_ioport_map(dev, base[id], STX104_EXTENT); + if (!priv->reg) + return -ENOMEM; + + indio_dev->info = &stx104_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + /* determine if differential inputs */ + if (ioread8(&priv->reg->cir_asr) & BIT(5)) { + indio_dev->num_channels = ARRAY_SIZE(stx104_channels_diff); + indio_dev->channels = stx104_channels_diff; + } else { + indio_dev->num_channels = ARRAY_SIZE(stx104_channels_sing); + indio_dev->channels = stx104_channels_sing; + } + + indio_dev->name = dev_name(dev); + indio_dev->dev.parent = dev; + + mutex_init(&priv->lock); + + /* configure device for software trigger operation */ + iowrite8(0, &priv->reg->acr); + + /* initialize gain setting to x1 */ + iowrite8(0, &priv->reg->acfg); + + /* initialize DAC output to 0V */ + iowrite16(0, &priv->reg->dac[0]); + iowrite16(0, &priv->reg->dac[1]); + + stx104gpio->chip.label = dev_name(dev); + stx104gpio->chip.parent = dev; + stx104gpio->chip.owner = THIS_MODULE; + stx104gpio->chip.base = -1; + stx104gpio->chip.ngpio = STX104_NGPIO; + stx104gpio->chip.names = stx104_names; + stx104gpio->chip.get_direction = stx104_gpio_get_direction; + stx104gpio->chip.direction_input = stx104_gpio_direction_input; + stx104gpio->chip.direction_output = stx104_gpio_direction_output; + stx104gpio->chip.get = stx104_gpio_get; + stx104gpio->chip.get_multiple = stx104_gpio_get_multiple; + stx104gpio->chip.set = stx104_gpio_set; + stx104gpio->chip.set_multiple = stx104_gpio_set_multiple; + stx104gpio->base = &priv->reg->dio; + stx104gpio->out_state = 0x0; + + spin_lock_init(&stx104gpio->lock); + + err = devm_gpiochip_add_data(dev, &stx104gpio->chip, stx104gpio); + if (err) { + dev_err(dev, "GPIO registering failed (%d)\n", err); + return err; + } + + return devm_iio_device_register(dev, indio_dev); +} + +static struct isa_driver stx104_driver = { + .probe = stx104_probe, + .driver = { + .name = "stx104" + }, +}; + +module_isa_driver(stx104_driver, num_stx104); + +MODULE_AUTHOR("William Breathitt Gray "); +MODULE_DESCRIPTION("Apex Embedded Systems STX104 IIO driver"); +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/iio/afe/iio-rescale.c +++ linux-oracle-5.4.0/drivers/iio/afe/iio-rescale.c @@ -38,7 +38,7 @@ int *val, int *val2, long mask) { struct rescale *rescale = iio_priv(indio_dev); - unsigned long long tmp; + s64 tmp; int ret; switch (mask) { @@ -59,10 +59,10 @@ *val2 = rescale->denominator; return IIO_VAL_FRACTIONAL; case IIO_VAL_FRACTIONAL_LOG2: - tmp = *val * 1000000000LL; - do_div(tmp, rescale->denominator); + tmp = (s64)*val * 1000000000LL; + tmp = div_s64(tmp, rescale->denominator); tmp *= rescale->numerator; - do_div(tmp, 1000000000LL); + tmp = div_s64(tmp, 1000000000LL); *val = tmp; return ret; default: --- linux-oracle-5.4.0.orig/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ linux-oracle-5.4.0/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -158,7 +158,7 @@ ret = dma_get_slave_caps(chan, &caps); if (ret < 0) - goto err_free; + goto err_release; /* Needs to be aligned to the maximum of the minimums */ if (caps.src_addr_widths) @@ -183,6 +183,8 @@ return &dmaengine_buffer->queue.buffer; +err_release: + dma_release_channel(chan); err_free: kfree(dmaengine_buffer); return ERR_PTR(ret); --- linux-oracle-5.4.0.orig/drivers/iio/chemical/Kconfig +++ linux-oracle-5.4.0/drivers/iio/chemical/Kconfig @@ -65,6 +65,7 @@ config PMS7003 tristate "Plantower PMS7003 particulate matter sensor" depends on SERIAL_DEV_BUS + select IIO_BUFFER select IIO_TRIGGERED_BUFFER help Say Y here to build support for the Plantower PMS7003 particulate @@ -90,6 +91,8 @@ tristate "SPS30 particulate matter sensor" depends on I2C select CRC8 + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say Y here to build support for the Sensirion SPS30 particulate matter sensor. --- linux-oracle-5.4.0.orig/drivers/iio/chemical/bme680.h +++ linux-oracle-5.4.0/drivers/iio/chemical/bme680.h @@ -54,7 +54,9 @@ #define BME680_NB_CONV_MASK GENMASK(3, 0) #define BME680_REG_MEAS_STAT_0 0x1D +#define BME680_NEW_DATA_BIT BIT(7) #define BME680_GAS_MEAS_BIT BIT(6) +#define BME680_MEAS_BIT BIT(5) /* Calibration Parameters */ #define BME680_T2_LSB_REG 0x8A --- linux-oracle-5.4.0.orig/drivers/iio/chemical/bme680_core.c +++ linux-oracle-5.4.0/drivers/iio/chemical/bme680_core.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include @@ -38,7 +39,7 @@ s8 par_h3; s8 par_h4; s8 par_h5; - s8 par_h6; + u8 par_h6; s8 par_h7; s8 par_gh1; s16 par_gh2; @@ -334,10 +335,10 @@ if (!calib->par_t2) bme680_read_calib(data, calib); - var1 = (adc_temp >> 3) - (calib->par_t1 << 1); + var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1); var2 = (var1 * calib->par_t2) >> 11; var3 = ((var1 >> 1) * (var1 >> 1)) >> 12; - var3 = (var3 * (calib->par_t3 << 4)) >> 14; + var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14; data->t_fine = var2 + var3; calc_temp = (data->t_fine * 5 + 128) >> 8; @@ -360,9 +361,9 @@ var1 = (data->t_fine >> 1) - 64000; var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2; var2 = var2 + (var1 * calib->par_p5 << 1); - var2 = (var2 >> 2) + (calib->par_p4 << 16); + var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16); var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * - (calib->par_p3 << 5)) >> 3) + + ((s32)calib->par_p3 << 5)) >> 3) + ((calib->par_p2 * var1) >> 1); var1 = var1 >> 18; var1 = ((32768 + var1) * calib->par_p1) >> 15; @@ -380,7 +381,7 @@ var3 = ((press_comp >> 8) * (press_comp >> 8) * (press_comp >> 8) * calib->par_p10) >> 17; - press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4; + press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4; return press_comp; } @@ -406,7 +407,7 @@ (((temp_scaled * ((temp_scaled * calib->par_h5) / 100)) >> 6) / 100) + (1 << 14))) >> 10; var3 = var1 * var2; - var4 = calib->par_h6 << 7; + var4 = (s32)calib->par_h6 << 7; var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4; var5 = ((var3 >> 14) * (var3 >> 14)) >> 10; var6 = (var4 * var5) >> 1; @@ -524,6 +525,43 @@ return ilog2(val) + 1; } +/* + * Taken from Bosch BME680 API: + * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490 + */ +static int bme680_wait_for_eoc(struct bme680_data *data) +{ + struct device *dev = regmap_get_device(data->regmap); + unsigned int check; + int ret; + /* + * (Sum of oversampling ratios * time per oversampling) + + * TPH measurement + gas measurement + wait transition from forced mode + * + heater duration + */ + int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + + data->oversampling_humid) * 1936) + (477 * 4) + + (477 * 5) + 1000 + (data->heater_dur * 1000); + + usleep_range(wait_eoc_us, wait_eoc_us + 100); + + ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); + if (ret) { + dev_err(dev, "failed to read measurement status register.\n"); + return ret; + } + if (check & BME680_MEAS_BIT) { + dev_err(dev, "Device measurement cycle incomplete.\n"); + return -EBUSY; + } + if (!(check & BME680_NEW_DATA_BIT)) { + dev_err(dev, "No new data available from the device.\n"); + return -ENODATA; + } + + return 0; +} + static int bme680_chip_config(struct bme680_data *data) { struct device *dev = regmap_get_device(data->regmap); @@ -614,6 +652,10 @@ if (ret < 0) return ret; + ret = bme680_wait_for_eoc(data); + if (ret) + return ret; + ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB, (u8 *) &tmp, 3); if (ret < 0) { @@ -670,7 +712,7 @@ } *val = bme680_compensate_press(data, adc_press); - *val2 = 100; + *val2 = 1000; return IIO_VAL_FRACTIONAL; } @@ -730,6 +772,10 @@ if (ret < 0) return ret; + ret = bme680_wait_for_eoc(data); + if (ret) + return ret; + ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check); if (check & BME680_GAS_MEAS_BIT) { dev_err(dev, "gas measurement incomplete\n"); --- linux-oracle-5.4.0.orig/drivers/iio/chemical/ccs811.c +++ linux-oracle-5.4.0/drivers/iio/chemical/ccs811.c @@ -75,6 +75,11 @@ struct ccs811_reading buffer; struct iio_trigger *drdy_trig; bool drdy_trig_on; + /* Ensures correct alignment of timestamp if present */ + struct { + s16 channels[2]; + s64 ts __aligned(8); + } scan; }; static const struct iio_chan_spec ccs811_channels[] = { @@ -306,17 +311,17 @@ struct iio_dev *indio_dev = pf->indio_dev; struct ccs811_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - s16 buf[8]; /* s16 eCO2 + s16 TVOC + padding + 8 byte timestamp */ int ret; - ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA, 4, - (u8 *)&buf); + ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA, + sizeof(data->scan.channels), + (u8 *)data->scan.channels); if (ret != 4) { dev_err(&client->dev, "cannot read sensor data\n"); goto err; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); err: @@ -413,11 +418,11 @@ data->drdy_trig->dev.parent = &client->dev; data->drdy_trig->ops = &ccs811_trigger_ops; iio_trigger_set_drvdata(data->drdy_trig, indio_dev); - indio_dev->trig = data->drdy_trig; - iio_trigger_get(indio_dev->trig); ret = iio_trigger_register(data->drdy_trig); if (ret) goto err_poweroff; + + indio_dev->trig = iio_trigger_get(data->drdy_trig); } ret = iio_triggered_buffer_setup(indio_dev, NULL, --- linux-oracle-5.4.0.orig/drivers/iio/chemical/pms7003.c +++ linux-oracle-5.4.0/drivers/iio/chemical/pms7003.c @@ -73,6 +73,11 @@ struct pms7003_frame frame; struct completion frame_ready; struct mutex lock; /* must be held whenever state gets touched */ + /* Used to construct scan to push to the IIO buffer */ + struct { + u16 data[3]; /* PM1, PM2P5, PM10 */ + s64 ts; + } scan; }; static int pms7003_do_cmd(struct pms7003_state *state, enum pms7003_cmd cmd) @@ -104,7 +109,6 @@ struct iio_dev *indio_dev = pf->indio_dev; struct pms7003_state *state = iio_priv(indio_dev); struct pms7003_frame *frame = &state->frame; - u16 data[3 + 1 + 4]; /* PM1, PM2P5, PM10, padding, timestamp */ int ret; mutex_lock(&state->lock); @@ -114,12 +118,15 @@ goto err; } - data[PM1] = pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET); - data[PM2P5] = pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET); - data[PM10] = pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET); + state->scan.data[PM1] = + pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET); + state->scan.data[PM2P5] = + pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET); + state->scan.data[PM10] = + pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET); mutex_unlock(&state->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &state->scan, iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/chemical/sps30.c +++ linux-oracle-5.4.0/drivers/iio/chemical/sps30.c @@ -230,15 +230,18 @@ struct iio_dev *indio_dev = pf->indio_dev; struct sps30_state *state = iio_priv(indio_dev); int ret; - s32 data[4 + 2]; /* PM1, PM2P5, PM4, PM10, timestamp */ + struct { + s32 data[4]; /* PM1, PM2P5, PM4, PM10 */ + s64 ts; + } scan; mutex_lock(&state->lock); - ret = sps30_do_meas(state, data, 4); + ret = sps30_do_meas(state, scan.data, ARRAY_SIZE(scan.data)); mutex_unlock(&state->lock); if (ret) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ linux-oracle-5.4.0/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -57,10 +57,13 @@ { switch (type) { case MOTIONSENSE_TYPE_ACCEL: - case MOTIONSENSE_TYPE_GYRO: *min_freq = 12500; *max_freq = 100000; break; + case MOTIONSENSE_TYPE_GYRO: + *min_freq = 25000; + *max_freq = 100000; + break; case MOTIONSENSE_TYPE_MAG: *min_freq = 5000; *max_freq = 25000; @@ -96,7 +99,7 @@ platform_set_drvdata(pdev, indio_dev); state->ec = ec->ec_dev; - state->msg = devm_kzalloc(&pdev->dev, + state->msg = devm_kzalloc(&pdev->dev, sizeof(*state->msg) + max((u16)sizeof(struct ec_params_motion_sense), state->ec->max_response), GFP_KERNEL); if (!state->msg) --- linux-oracle-5.4.0.orig/drivers/iio/common/hid-sensors/hid-sensor-trigger.c +++ linux-oracle-5.4.0/drivers/iio/common/hid-sensors/hid-sensor-trigger.c @@ -33,7 +33,7 @@ latency = integer * 1000 + fract / 1000; ret = hid_sensor_set_report_latency(attrb, latency); if (ret < 0) - return len; + return ret; attrb->latency_ms = hid_sensor_get_report_latency(attrb); --- linux-oracle-5.4.0.orig/drivers/iio/common/ms_sensors/ms_sensors_i2c.c +++ linux-oracle-5.4.0/drivers/iio/common/ms_sensors/ms_sensors_i2c.c @@ -15,8 +15,8 @@ /* Conversion times in us */ static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000, 13000, 7000 }; -static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 3000, - 5000, 8000 }; +static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 5000, + 3000, 8000 }; static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100, 4100, 8220, 16440 }; --- linux-oracle-5.4.0.orig/drivers/iio/common/ssp_sensors/ssp_spi.c +++ linux-oracle-5.4.0/drivers/iio/common/ssp_sensors/ssp_spi.c @@ -137,7 +137,7 @@ if (length > received_len - *data_index || length <= 0) { ssp_dbg("[SSP]: MSG From MCU-invalid debug length(%d/%d)\n", length, received_len); - return length ? length : -EPROTO; + return -EPROTO; } ssp_dbg("[SSP]: MSG From MCU - %s\n", &data_frame[*data_index]); @@ -273,6 +273,8 @@ for (idx = 0; idx < len;) { switch (dataframe[idx++]) { case SSP_MSG2AP_INST_BYPASS_DATA: + if (idx >= len) + return -EPROTO; sd = dataframe[idx++]; if (sd < 0 || sd >= SSP_SENSOR_MAX) { dev_err(SSP_DEV, @@ -282,10 +284,13 @@ if (indio_devs[sd]) { spd = iio_priv(indio_devs[sd]); - if (spd->process_data) + if (spd->process_data) { + if (idx >= len) + return -EPROTO; spd->process_data(indio_devs[sd], &dataframe[idx], data->timestamp); + } } else { dev_err(SSP_DEV, "no client for frame\n"); } @@ -293,6 +298,8 @@ idx += ssp_offset_map[sd]; break; case SSP_MSG2AP_INST_DEBUG_DATA: + if (idx >= len) + return -EPROTO; sd = ssp_print_mcu_debug(dataframe, &idx, len); if (sd) { dev_err(SSP_DEV, --- linux-oracle-5.4.0.orig/drivers/iio/common/st_sensors/st_sensors_core.c +++ linux-oracle-5.4.0/drivers/iio/common/st_sensors/st_sensors_core.c @@ -76,16 +76,18 @@ int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) { - int err; + int err = 0; struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); - if (!sdata->sensor_settings->odr.addr) - return 0; + mutex_lock(&sdata->odr_lock); + + if (!sdata->sensor_settings->odr.mask) + goto unlock_mutex; err = st_sensors_match_odr(sdata->sensor_settings, odr, &odr_out); if (err < 0) - goto st_sensors_match_odr_error; + goto unlock_mutex; if ((sdata->sensor_settings->odr.addr == sdata->sensor_settings->pw.addr) && @@ -108,7 +110,9 @@ if (err >= 0) sdata->odr = odr_out.hz; -st_sensors_match_odr_error: +unlock_mutex: + mutex_unlock(&sdata->odr_lock); + return err; } EXPORT_SYMBOL(st_sensors_set_odr); @@ -384,6 +388,8 @@ struct st_sensors_platform_data *of_pdata; int err = 0; + mutex_init(&sdata->odr_lock); + /* If OF/DT pdata exists, it will take precedence of anything else */ of_pdata = st_sensors_of_probe(indio_dev->dev.parent, pdata); if (of_pdata) @@ -575,18 +581,24 @@ err = -EBUSY; goto out; } else { + mutex_lock(&sdata->odr_lock); err = st_sensors_set_enable(indio_dev, true); - if (err < 0) + if (err < 0) { + mutex_unlock(&sdata->odr_lock); goto out; + } msleep((sdata->sensor_settings->bootime * 1000) / sdata->odr); err = st_sensors_read_axis_data(indio_dev, ch, val); - if (err < 0) + if (err < 0) { + mutex_unlock(&sdata->odr_lock); goto out; + } *val = *val >> ch->scan_type.shift; err = st_sensors_set_enable(indio_dev, false); + mutex_unlock(&sdata->odr_lock); } out: mutex_unlock(&indio_dev->mlock); --- linux-oracle-5.4.0.orig/drivers/iio/dac/Kconfig +++ linux-oracle-5.4.0/drivers/iio/dac/Kconfig @@ -60,8 +60,8 @@ help Say yes here to build support for Analog Devices AD5300, AD5301, AD5310, AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, - AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5601, AD5602, AD5611, AD5612, - AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs + AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5600, AD5601, AD5602, AD5611, + AD5612, AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs as well as Texas Instruments DAC081S101, DAC101S101, DAC121S101. To compile this driver as a module, choose M here: the @@ -124,6 +124,7 @@ config LTC1660 tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" depends on SPI + select REGMAP_SPI help Say yes here to build support for Linear Technology LTC1660 and LTC1665 Digital to Analog Converters. @@ -346,6 +347,7 @@ config STM32_DAC_CORE tristate + select REGMAP_MMIO config TI_DAC082S085 tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" --- linux-oracle-5.4.0.orig/drivers/iio/dac/Makefile +++ linux-oracle-5.4.0/drivers/iio/dac/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_AD5592R) += ad5592r.o obj-$(CONFIG_AD5593R) += ad5593r.o obj-$(CONFIG_AD5755) += ad5755.o -obj-$(CONFIG_AD5755) += ad5758.o +obj-$(CONFIG_AD5758) += ad5758.o obj-$(CONFIG_AD5761) += ad5761.o obj-$(CONFIG_AD5764) += ad5764.o obj-$(CONFIG_AD5791) += ad5791.o --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5446.c +++ linux-oracle-5.4.0/drivers/iio/dac/ad5446.c @@ -170,7 +170,7 @@ switch (m) { case IIO_CHAN_INFO_RAW: - *val = st->cached_val; + *val = st->cached_val >> chan->scan_type.shift; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = st->vref_mv; @@ -327,6 +327,7 @@ ID_AD5541A, ID_AD5512A, ID_AD5553, + ID_AD5600, ID_AD5601, ID_AD5611, ID_AD5621, @@ -381,6 +382,10 @@ .channel = AD5446_CHANNEL(14, 16, 0), .write = ad5446_write, }, + [ID_AD5600] = { + .channel = AD5446_CHANNEL(16, 16, 0), + .write = ad5446_write, + }, [ID_AD5601] = { .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), .write = ad5446_write, @@ -448,6 +453,7 @@ {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */ {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */ {"ad5553", ID_AD5553}, + {"ad5600", ID_AD5600}, {"ad5601", ID_AD5601}, {"ad5611", ID_AD5611}, {"ad5621", ID_AD5621}, @@ -521,8 +527,15 @@ { struct i2c_client *client = to_i2c_client(st->dev); __be16 data = cpu_to_be16(val); + int ret; - return i2c_master_send(client, (char *)&data, sizeof(data)); + ret = i2c_master_send(client, (char *)&data, sizeof(data)); + if (ret < 0) + return ret; + if (ret != sizeof(data)) + return -EIO; + + return 0; } /** --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5504.c +++ linux-oracle-5.4.0/drivers/iio/dac/ad5504.c @@ -188,9 +188,9 @@ return ret; if (pwr_down) - st->pwr_down_mask |= (1 << chan->channel); - else st->pwr_down_mask &= ~(1 << chan->channel); + else + st->pwr_down_mask |= (1 << chan->channel); ret = ad5504_spi_write(st, AD5504_ADDR_CTRL, AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) | --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5592r-base.c +++ linux-oracle-5.4.0/drivers/iio/dac/ad5592r-base.c @@ -157,7 +157,6 @@ static int ad5592r_reset(struct ad5592r_state *st) { struct gpio_desc *gpio; - struct iio_dev *iio_dev = iio_priv_to_dev(st); gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(gpio)) @@ -167,10 +166,10 @@ udelay(1); gpiod_set_value(gpio, 1); } else { - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); /* Writing this magic value resets the device */ st->ops->reg_write(st, AD5592R_REG_RESET, 0xdac); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); } udelay(250); @@ -198,7 +197,6 @@ const struct ad5592r_rw_ops *ops = st->ops; int ret; unsigned i; - struct iio_dev *iio_dev = iio_priv_to_dev(st); u8 pulldown = 0, tristate = 0, dac = 0, adc = 0; u16 read_back; @@ -248,7 +246,7 @@ } } - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); /* Pull down unused pins to GND */ ret = ops->reg_write(st, AD5592R_REG_PULLDOWN, pulldown); @@ -286,7 +284,7 @@ ret = -EIO; err_unlock: - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -315,11 +313,11 @@ if (!chan->output) return -EINVAL; - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); ret = st->ops->write_dac(st, chan->channel, val); if (!ret) st->cached_dac[chan->channel] = val; - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); return ret; case IIO_CHAN_INFO_SCALE: if (chan->type == IIO_VOLTAGE) { @@ -334,12 +332,12 @@ else return -EINVAL; - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); ret = st->ops->reg_read(st, AD5592R_REG_CTRL, &st->cached_gp_ctrl); if (ret < 0) { - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -361,7 +359,7 @@ ret = st->ops->reg_write(st, AD5592R_REG_CTRL, st->cached_gp_ctrl); - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -379,11 +377,11 @@ { struct ad5592r_state *st = iio_priv(iio_dev); u16 read_val; - int ret; + int ret, mult; switch (m) { case IIO_CHAN_INFO_RAW: - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); if (!chan->output) { ret = st->ops->read_adc(st, chan->channel, &read_val); @@ -416,29 +414,27 @@ s64 tmp = *val * (3767897513LL / 25LL); *val = div_s64_rem(tmp, 1000000000LL, val2); - ret = IIO_VAL_INT_PLUS_MICRO; - } else { - int mult; + return IIO_VAL_INT_PLUS_NANO; + } - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); - if (chan->output) - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_DAC_RANGE); - else - mult = !!(st->cached_gp_ctrl & - AD5592R_REG_CTRL_ADC_RANGE); + if (chan->output) + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_DAC_RANGE); + else + mult = !!(st->cached_gp_ctrl & + AD5592R_REG_CTRL_ADC_RANGE); - *val *= ++mult; + *val *= ++mult; - *val2 = chan->scan_type.realbits; - ret = IIO_VAL_FRACTIONAL_LOG2; - } + *val2 = chan->scan_type.realbits; + ret = IIO_VAL_FRACTIONAL_LOG2; break; case IIO_CHAN_INFO_OFFSET: ret = ad5592r_get_vref(st); - mutex_lock(&iio_dev->mlock); + mutex_lock(&st->lock); if (st->cached_gp_ctrl & AD5592R_REG_CTRL_ADC_RANGE) *val = (-34365 * 25) / ret; @@ -447,11 +443,11 @@ ret = IIO_VAL_INT; break; default: - ret = -EINVAL; + return -EINVAL; } unlock: - mutex_unlock(&iio_dev->mlock); + mutex_unlock(&st->lock); return ret; } @@ -530,7 +526,7 @@ if (!ret) st->channel_modes[reg] = tmp; - fwnode_property_read_u32(child, "adi,off-state", &tmp); + ret = fwnode_property_read_u32(child, "adi,off-state", &tmp); if (!ret) st->channel_offstate[reg] = tmp; } @@ -626,6 +622,8 @@ iio_dev->info = &ad5592r_info; iio_dev->modes = INDIO_DIRECT_MODE; + mutex_init(&st->lock); + ad5592r_init_scales(st, ad5592r_get_vref(st)); ret = ad5592r_reset(st); --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5592r-base.h +++ linux-oracle-5.4.0/drivers/iio/dac/ad5592r-base.h @@ -52,6 +52,7 @@ struct regulator *reg; struct gpio_chip gpiochip; struct mutex gpio_lock; /* Protect cached gpio_out, gpio_val, etc. */ + struct mutex lock; unsigned int num_channels; const struct ad5592r_rw_ops *ops; int scale_avail[2][2]; --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5593r.c +++ linux-oracle-5.4.0/drivers/iio/dac/ad5593r.c @@ -14,6 +14,8 @@ #include #include +#include + #define AD5593R_MODE_CONF (0 << 4) #define AD5593R_MODE_DAC_WRITE (1 << 4) #define AD5593R_MODE_ADC_READBACK (4 << 4) @@ -21,6 +23,24 @@ #define AD5593R_MODE_GPIO_READBACK (6 << 4) #define AD5593R_MODE_REG_READBACK (7 << 4) +static int ad5593r_read_word(struct i2c_client *i2c, u8 reg, u16 *value) +{ + int ret; + u8 buf[2]; + + ret = i2c_smbus_write_byte(i2c, reg); + if (ret < 0) + return ret; + + ret = i2c_master_recv(i2c, buf, sizeof(buf)); + if (ret < 0) + return ret; + + *value = get_unaligned_be16(buf); + + return 0; +} + static int ad5593r_write_dac(struct ad5592r_state *st, unsigned chan, u16 value) { struct i2c_client *i2c = to_i2c_client(st->dev); @@ -39,13 +59,7 @@ if (val < 0) return (int) val; - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_ADC_READBACK); - if (val < 0) - return (int) val; - - *value = (u16) val; - - return 0; + return ad5593r_read_word(i2c, AD5593R_MODE_ADC_READBACK, value); } static int ad5593r_reg_write(struct ad5592r_state *st, u8 reg, u16 value) @@ -59,25 +73,19 @@ static int ad5593r_reg_read(struct ad5592r_state *st, u8 reg, u16 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); - s32 val; - - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_REG_READBACK | reg); - if (val < 0) - return (int) val; - *value = (u16) val; - - return 0; + return ad5593r_read_word(i2c, AD5593R_MODE_REG_READBACK | reg, value); } static int ad5593r_gpio_read(struct ad5592r_state *st, u8 *value) { struct i2c_client *i2c = to_i2c_client(st->dev); - s32 val; + u16 val; + int ret; - val = i2c_smbus_read_word_swapped(i2c, AD5593R_MODE_GPIO_READBACK); - if (val < 0) - return (int) val; + ret = ad5593r_read_word(i2c, AD5593R_MODE_GPIO_READBACK, &val); + if (ret) + return ret; *value = (u8) val; --- linux-oracle-5.4.0.orig/drivers/iio/dac/ad5624r_spi.c +++ linux-oracle-5.4.0/drivers/iio/dac/ad5624r_spi.c @@ -229,7 +229,7 @@ if (!indio_dev) return -ENOMEM; st = iio_priv(indio_dev); - st->reg = devm_regulator_get(&spi->dev, "vcc"); + st->reg = devm_regulator_get_optional(&spi->dev, "vref"); if (!IS_ERR(st->reg)) { ret = regulator_enable(st->reg); if (ret) @@ -240,6 +240,22 @@ goto error_disable_reg; voltage_uv = ret; + } else { + if (PTR_ERR(st->reg) != -ENODEV) + return PTR_ERR(st->reg); + /* Backwards compatibility. This naming is not correct */ + st->reg = devm_regulator_get_optional(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + return ret; + + ret = regulator_get_voltage(st->reg); + if (ret < 0) + goto error_disable_reg; + + voltage_uv = ret; + } } spi_set_drvdata(spi, indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/dac/cio-dac.c +++ linux-oracle-5.4.0/drivers/iio/dac/cio-dac.c @@ -66,8 +66,8 @@ if (mask != IIO_CHAN_INFO_RAW) return -EINVAL; - /* DAC can only accept up to a 16-bit value */ - if ((unsigned int)val > 65535) + /* DAC can only accept up to a 12-bit value */ + if ((unsigned int)val > 4095) return -EINVAL; priv->chan_out_states[chan->channel] = val; --- linux-oracle-5.4.0.orig/drivers/iio/dac/mcp4725.c +++ linux-oracle-5.4.0/drivers/iio/dac/mcp4725.c @@ -47,12 +47,18 @@ struct mcp4725_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); u8 outbuf[2]; + int ret; outbuf[0] = (data->powerdown_mode + 1) << 4; outbuf[1] = 0; data->powerdown = true; - return i2c_master_send(data->client, outbuf, 2); + ret = i2c_master_send(data->client, outbuf, 2); + if (ret < 0) + return ret; + else if (ret != 2) + return -EIO; + return 0; } static int __maybe_unused mcp4725_resume(struct device *dev) @@ -60,13 +66,19 @@ struct mcp4725_data *data = iio_priv(i2c_get_clientdata( to_i2c_client(dev))); u8 outbuf[2]; + int ret; /* restore previous DAC value */ outbuf[0] = (data->dac_value >> 8) & 0xf; outbuf[1] = data->dac_value & 0xff; data->powerdown = false; - return i2c_master_send(data->client, outbuf, 2); + ret = i2c_master_send(data->client, outbuf, 2); + if (ret < 0) + return ret; + else if (ret != 2) + return -EIO; + return 0; } static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume); --- linux-oracle-5.4.0.orig/drivers/iio/dac/ti-dac5571.c +++ linux-oracle-5.4.0/drivers/iio/dac/ti-dac5571.c @@ -352,6 +352,7 @@ data->dac5571_pwrdwn = dac5571_pwrdwn_quad; break; default: + ret = -EINVAL; goto err; } --- linux-oracle-5.4.0.orig/drivers/iio/dac/vf610_dac.c +++ linux-oracle-5.4.0/drivers/iio/dac/vf610_dac.c @@ -225,6 +225,7 @@ return 0; error_iio_device_register: + vf610_dac_exit(info); clk_disable_unprepare(info->clk); return ret; --- linux-oracle-5.4.0.orig/drivers/iio/dummy/iio_simple_dummy.c +++ linux-oracle-5.4.0/drivers/iio/dummy/iio_simple_dummy.c @@ -568,10 +568,9 @@ struct iio_sw_device *swd; swd = kzalloc(sizeof(*swd), GFP_KERNEL); - if (!swd) { - ret = -ENOMEM; - goto error_kzalloc; - } + if (!swd) + return ERR_PTR(-ENOMEM); + /* * Allocate an IIO device. * @@ -583,7 +582,7 @@ indio_dev = iio_device_alloc(sizeof(*st)); if (!indio_dev) { ret = -ENOMEM; - goto error_ret; + goto error_free_swd; } st = iio_priv(indio_dev); @@ -614,6 +613,10 @@ * indio_dev->name = spi_get_device_id(spi)->name; */ indio_dev->name = kstrdup(name, GFP_KERNEL); + if (!indio_dev->name) { + ret = -ENOMEM; + goto error_free_device; + } /* Provide description of available channels */ indio_dev->channels = iio_dummy_channels; @@ -630,7 +633,7 @@ ret = iio_simple_dummy_events_register(indio_dev); if (ret < 0) - goto error_free_device; + goto error_free_name; ret = iio_simple_dummy_configure_buffer(indio_dev); if (ret < 0) @@ -647,11 +650,12 @@ iio_simple_dummy_unconfigure_buffer(indio_dev); error_unregister_events: iio_simple_dummy_events_unregister(indio_dev); +error_free_name: + kfree(indio_dev->name); error_free_device: iio_device_free(indio_dev); -error_ret: +error_free_swd: kfree(swd); -error_kzalloc: return ERR_PTR(ret); } --- linux-oracle-5.4.0.orig/drivers/iio/dummy/iio_simple_dummy_buffer.c +++ linux-oracle-5.4.0/drivers/iio/dummy/iio_simple_dummy_buffer.c @@ -48,7 +48,7 @@ int len = 0; u16 *data; - data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL); if (!data) goto done; --- linux-oracle-5.4.0.orig/drivers/iio/gyro/bmg160_core.c +++ linux-oracle-5.4.0/drivers/iio/gyro/bmg160_core.c @@ -96,7 +96,11 @@ struct iio_trigger *motion_trig; struct iio_mount_matrix orientation; struct mutex mutex; - s16 buffer[8]; + /* Ensure naturally aligned timestamp */ + struct { + s16 chans[3]; + s64 timestamp __aligned(8); + } scan; u32 dps_range; int ev_enable_state; int slope_thres; @@ -880,12 +884,12 @@ mutex_lock(&data->mutex); ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L, - data->buffer, AXIS_MAX * 2); + data->scan.chans, AXIS_MAX * 2); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); @@ -1169,11 +1173,14 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(dev, "unable to register iio device\n"); - goto err_buffer_cleanup; + goto err_pm_cleanup; } return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); err_trigger_unregister: --- linux-oracle-5.4.0.orig/drivers/iio/gyro/fxas21002c_core.c +++ linux-oracle-5.4.0/drivers/iio/gyro/fxas21002c_core.c @@ -300,14 +300,7 @@ static int fxas21002c_pm_get(struct fxas21002c_data *data) { - struct device *dev = regmap_get_device(data->regmap); - int ret; - - ret = pm_runtime_get_sync(dev); - if (ret < 0) - pm_runtime_put_noidle(dev); - - return ret; + return pm_runtime_resume_and_get(regmap_get_device(data->regmap)); } static int fxas21002c_pm_put(struct fxas21002c_data *data) @@ -333,6 +326,7 @@ ret = regmap_field_read(data->regmap_fields[F_TEMP], &temp); if (ret < 0) { dev_err(dev, "failed to read temp: %d\n", ret); + fxas21002c_pm_put(data); goto data_unlock; } @@ -366,6 +360,7 @@ &axis_be, sizeof(axis_be)); if (ret < 0) { dev_err(dev, "failed to read axis: %d: %d\n", index, ret); + fxas21002c_pm_put(data); goto data_unlock; } @@ -669,14 +664,21 @@ int ret; mutex_lock(&data->lock); + ret = fxas21002c_pm_get(data); + if (ret < 0) + goto out_unlock; + ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB, data->buffer, CHANNEL_SCAN_MAX * sizeof(s16)); if (ret < 0) - goto out_unlock; + goto out_pm_put; iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, data->timestamp); +out_pm_put: + fxas21002c_pm_put(data); + out_unlock: mutex_unlock(&data->lock); @@ -938,7 +940,6 @@ pm_disable: pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); return ret; } @@ -952,7 +953,6 @@ pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); } EXPORT_SYMBOL_GPL(fxas21002c_core_remove); --- linux-oracle-5.4.0.orig/drivers/iio/gyro/itg3200_buffer.c +++ linux-oracle-5.4.0/drivers/iio/gyro/itg3200_buffer.c @@ -46,17 +46,24 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct itg3200 *st = iio_priv(indio_dev); - __be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)]; + /* + * Ensure correct alignment and padding including for the + * timestamp that may be inserted. + */ + struct { + __be16 buf[ITG3200_SCAN_ELEMENTS]; + s64 ts __aligned(8); + } scan; - int ret = itg3200_read_all_channels(st->i2c, buf); + int ret = itg3200_read_all_channels(st->i2c, scan.buf); if (ret < 0) goto error_ret; - iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp); +error_ret: iio_trigger_notify_done(indio_dev->trig); -error_ret: return IRQ_HANDLED; } --- linux-oracle-5.4.0.orig/drivers/iio/gyro/mpu3050-core.c +++ linux-oracle-5.4.0/drivers/iio/gyro/mpu3050-core.c @@ -271,7 +271,16 @@ case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - /* The temperature scaling is (x+23000)/280 Celsius */ + /* + * The temperature scaling is (x+23000)/280 Celsius + * for the "best fit straight line" temperature range + * of -30C..85C. The 23000 includes room temperature + * offset of +35C, 280 is the precision scale and x is + * the 16-bit signed integer reported by hardware. + * + * Temperature value itself represents temperature of + * the sensor die. + */ *val = 23000; return IIO_VAL_INT; default: @@ -328,7 +337,7 @@ goto out_read_raw_unlock; } - *val = be16_to_cpu(raw_val); + *val = (s16)be16_to_cpu(raw_val); ret = IIO_VAL_INT; goto out_read_raw_unlock; @@ -550,6 +559,8 @@ MPU3050_FIFO_R, &fifo_values[offset], toread); + if (ret) + goto out_trigger_unlock; dev_dbg(mpu3050->dev, "%04x %04x %04x %04x %04x\n", @@ -863,6 +874,7 @@ ret = regmap_update_bits(mpu3050->map, MPU3050_PWR_MGM, MPU3050_PWR_MGM_SLEEP, 0); if (ret) { + regulator_bulk_disable(ARRAY_SIZE(mpu3050->regs), mpu3050->regs); dev_err(mpu3050->dev, "error setting power mode\n"); return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/gyro/st_gyro_core.c +++ linux-oracle-5.4.0/drivers/iio/gyro/st_gyro_core.c @@ -139,7 +139,6 @@ [2] = LSM330DLC_GYRO_DEV_NAME, [3] = L3G4IS_GYRO_DEV_NAME, [4] = LSM330_GYRO_DEV_NAME, - [5] = LSM9DS0_GYRO_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, .odr = { @@ -203,6 +202,80 @@ }, }, .sim = { + .addr = 0x23, + .value = BIT(0), + }, + .multi_read_bit = true, + .bootime = 2, + }, + { + .wai = 0xd4, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = LSM9DS0_GYRO_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_gyro_16bit_channels, + .odr = { + .addr = 0x20, + .mask = GENMASK(7, 6), + .odr_avl = { + { .hz = 95, .value = 0x00, }, + { .hz = 190, .value = 0x01, }, + { .hz = 380, .value = 0x02, }, + { .hz = 760, .value = 0x03, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = BIT(3), + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .enable_axis = { + .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, + .mask = ST_SENSORS_DEFAULT_AXIS_MASK, + }, + .fs = { + .addr = 0x23, + .mask = GENMASK(5, 4), + .fs_avl = { + [0] = { + .num = ST_GYRO_FS_AVL_245DPS, + .value = 0x00, + .gain = IIO_DEGREE_TO_RAD(8750), + }, + [1] = { + .num = ST_GYRO_FS_AVL_500DPS, + .value = 0x01, + .gain = IIO_DEGREE_TO_RAD(17500), + }, + [2] = { + .num = ST_GYRO_FS_AVL_2000DPS, + .value = 0x02, + .gain = IIO_DEGREE_TO_RAD(70000), + }, + }, + }, + .bdu = { + .addr = 0x23, + .mask = BIT(7), + }, + .drdy_irq = { + .int2 = { + .addr = 0x22, + .mask = BIT(3), + }, + /* + * The sensor has IHL (active low) and open + * drain settings, but only for INT1 and not + * for the DRDY line on INT2. + */ + .stat_drdy = { + .addr = ST_SENSORS_DEFAULT_STAT_ADDR, + .mask = GENMASK(2, 0), + }, + }, + .sim = { .addr = 0x23, .value = BIT(0), }, --- linux-oracle-5.4.0.orig/drivers/iio/health/afe4403.c +++ linux-oracle-5.4.0/drivers/iio/health/afe4403.c @@ -63,6 +63,7 @@ * @regulator: Pointer to the regulator for the IC * @trig: IIO trigger for this device * @irq: ADC_RDY line interrupt number + * @buffer: Used to construct data layout to push into IIO buffer. */ struct afe4403_data { struct device *dev; @@ -72,6 +73,8 @@ struct regulator *regulator; struct iio_trigger *trig; int irq; + /* Ensure suitable alignment for timestamp */ + s32 buffer[8] __aligned(8); }; enum afe4403_chan_id { @@ -242,14 +245,14 @@ int *val, int *val2, long mask) { struct afe4403_data *afe = iio_priv(indio_dev); - unsigned int reg = afe4403_channel_values[chan->address]; - unsigned int field = afe4403_channel_leds[chan->address]; + unsigned int reg, field; int ret; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_RAW: + reg = afe4403_channel_values[chan->address]; ret = afe4403_read(afe, reg, val); if (ret) return ret; @@ -259,6 +262,7 @@ case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + field = afe4403_channel_leds[chan->address]; ret = regmap_field_read(afe->fields[field], val); if (ret) return ret; @@ -309,7 +313,6 @@ struct iio_dev *indio_dev = pf->indio_dev; struct afe4403_data *afe = iio_priv(indio_dev); int ret, bit, i = 0; - s32 buffer[8]; u8 tx[4] = {AFE440X_CONTROL0, 0x0, 0x0, AFE440X_CONTROL0_READ}; u8 rx[3]; @@ -326,9 +329,9 @@ if (ret) goto err; - buffer[i++] = (rx[0] << 16) | - (rx[1] << 8) | - (rx[2]); + afe->buffer[i++] = (rx[0] << 16) | + (rx[1] << 8) | + (rx[2]); } /* Disable reading from the device */ @@ -337,7 +340,8 @@ if (ret) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer, + pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/health/afe4404.c +++ linux-oracle-5.4.0/drivers/iio/health/afe4404.c @@ -83,6 +83,7 @@ * @regulator: Pointer to the regulator for the IC * @trig: IIO trigger for this device * @irq: ADC_RDY line interrupt number + * @buffer: Used to construct a scan to push to the iio buffer. */ struct afe4404_data { struct device *dev; @@ -91,6 +92,7 @@ struct regulator *regulator; struct iio_trigger *trig; int irq; + s32 buffer[10] __aligned(8); }; enum afe4404_chan_id { @@ -248,20 +250,20 @@ int *val, int *val2, long mask) { struct afe4404_data *afe = iio_priv(indio_dev); - unsigned int value_reg = afe4404_channel_values[chan->address]; - unsigned int led_field = afe4404_channel_leds[chan->address]; - unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; + unsigned int value_reg, led_field, offdac_field; int ret; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_RAW: + value_reg = afe4404_channel_values[chan->address]; ret = regmap_read(afe->regmap, value_reg, val); if (ret) return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: + offdac_field = afe4404_channel_offdacs[chan->address]; ret = regmap_field_read(afe->fields[offdac_field], val); if (ret) return ret; @@ -271,6 +273,7 @@ case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + led_field = afe4404_channel_leds[chan->address]; ret = regmap_field_read(afe->fields[led_field], val); if (ret) return ret; @@ -293,19 +296,20 @@ int val, int val2, long mask) { struct afe4404_data *afe = iio_priv(indio_dev); - unsigned int led_field = afe4404_channel_leds[chan->address]; - unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; + unsigned int led_field, offdac_field; switch (chan->type) { case IIO_INTENSITY: switch (mask) { case IIO_CHAN_INFO_OFFSET: + offdac_field = afe4404_channel_offdacs[chan->address]; return regmap_field_write(afe->fields[offdac_field], val); } break; case IIO_CURRENT: switch (mask) { case IIO_CHAN_INFO_RAW: + led_field = afe4404_channel_leds[chan->address]; return regmap_field_write(afe->fields[led_field], val); } break; @@ -328,17 +332,17 @@ struct iio_dev *indio_dev = pf->indio_dev; struct afe4404_data *afe = iio_priv(indio_dev); int ret, bit, i = 0; - s32 buffer[10]; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { ret = regmap_read(afe->regmap, afe4404_channel_values[bit], - &buffer[i++]); + &afe->buffer[i++]); if (ret) goto err; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, afe->buffer, + pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/humidity/am2315.c +++ linux-oracle-5.4.0/drivers/iio/humidity/am2315.c @@ -33,7 +33,11 @@ struct am2315_data { struct i2c_client *client; struct mutex lock; - s16 buffer[8]; /* 2x16-bit channels + 2x16 padding + 4x16 timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[2]; + s64 timestamp __aligned(8); + } scan; }; struct am2315_sensor_data { @@ -167,20 +171,20 @@ mutex_lock(&data->lock); if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) { - data->buffer[0] = sensor_data.hum_data; - data->buffer[1] = sensor_data.temp_data; + data->scan.chans[0] = sensor_data.hum_data; + data->scan.chans[1] = sensor_data.temp_data; } else { i = 0; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { - data->buffer[i] = (bit ? sensor_data.temp_data : - sensor_data.hum_data); + data->scan.chans[i] = (bit ? sensor_data.temp_data : + sensor_data.hum_data); i++; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/humidity/hdc100x.c +++ linux-oracle-5.4.0/drivers/iio/humidity/hdc100x.c @@ -24,6 +24,8 @@ #include #include +#include + #define HDC100X_REG_TEMP 0x00 #define HDC100X_REG_HUMIDITY 0x01 @@ -38,6 +40,11 @@ /* integration time of the sensor */ int adc_int_us[2]; + /* Ensure natural alignment of timestamp */ + struct { + __be16 channels[2]; + s64 ts __aligned(8); + } scan; }; /* integration time in us */ @@ -160,7 +167,7 @@ struct iio_chan_spec const *chan) { struct i2c_client *client = data->client; - int delay = data->adc_int_us[chan->address]; + int delay = data->adc_int_us[chan->address] + 1*USEC_PER_MSEC; int ret; __be16 val; @@ -229,7 +236,7 @@ *val2 = 65536; return IIO_VAL_FRACTIONAL; } else { - *val = 100; + *val = 100000; *val2 = 65536; return IIO_VAL_FRACTIONAL; } @@ -317,9 +324,8 @@ struct iio_dev *indio_dev = pf->indio_dev; struct hdc100x_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - int delay = data->adc_int_us[0] + data->adc_int_us[1]; + int delay = data->adc_int_us[0] + data->adc_int_us[1] + 2*USEC_PER_MSEC; int ret; - s16 buf[8]; /* 2x s16 + padding + 8 byte timestamp */ /* dual read starts at temp register */ mutex_lock(&data->lock); @@ -330,13 +336,13 @@ } usleep_range(delay, delay + 1000); - ret = i2c_master_recv(client, (u8 *)buf, 4); + ret = i2c_master_recv(client, (u8 *)data->scan.channels, 4); if (ret < 0) { dev_err(&client->dev, "cannot read sensor data\n"); goto err; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); err: mutex_unlock(&data->lock); --- linux-oracle-5.4.0.orig/drivers/iio/humidity/hid-sensor-humidity.c +++ linux-oracle-5.4.0/drivers/iio/humidity/hid-sensor-humidity.c @@ -17,7 +17,10 @@ struct hid_humidity_state { struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info humidity_attr; - s32 humidity_data; + struct { + s32 humidity_data; + u64 timestamp __aligned(8); + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -127,9 +130,8 @@ struct hid_humidity_state *humid_st = iio_priv(indio_dev); if (atomic_read(&humid_st->common_attributes.data_ready)) - iio_push_to_buffers_with_timestamp(indio_dev, - &humid_st->humidity_data, - iio_get_time_ns(indio_dev)); + iio_push_to_buffers_with_timestamp(indio_dev, &humid_st->scan, + iio_get_time_ns(indio_dev)); return 0; } @@ -144,7 +146,7 @@ switch (usage_id) { case HID_USAGE_SENSOR_ATMOSPHERIC_HUMIDITY: - humid_st->humidity_data = *(s32 *)raw_data; + humid_st->scan.humidity_data = *(s32 *)raw_data; return 0; default: --- linux-oracle-5.4.0.orig/drivers/iio/humidity/hts221.h +++ linux-oracle-5.4.0/drivers/iio/humidity/hts221.h @@ -14,8 +14,6 @@ #include -#define HTS221_DATA_SIZE 2 - enum hts221_sensor_type { HTS221_SENSOR_H, HTS221_SENSOR_T, @@ -39,6 +37,11 @@ bool enabled; u8 odr; + /* Ensure natural alignment of timestamp */ + struct { + __le16 channels[2]; + s64 ts __aligned(8); + } scan; }; extern const struct dev_pm_ops hts221_pm_ops; --- linux-oracle-5.4.0.orig/drivers/iio/humidity/hts221_buffer.c +++ linux-oracle-5.4.0/drivers/iio/humidity/hts221_buffer.c @@ -162,7 +162,6 @@ static irqreturn_t hts221_buffer_handler_thread(int irq, void *p) { - u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)]; struct iio_poll_func *pf = p; struct iio_dev *iio_dev = pf->indio_dev; struct hts221_hw *hw = iio_priv(iio_dev); @@ -172,18 +171,20 @@ /* humidity data */ ch = &iio_dev->channels[HTS221_SENSOR_H]; err = regmap_bulk_read(hw->regmap, ch->address, - buffer, HTS221_DATA_SIZE); + &hw->scan.channels[0], + sizeof(hw->scan.channels[0])); if (err < 0) goto out; /* temperature data */ ch = &iio_dev->channels[HTS221_SENSOR_T]; err = regmap_bulk_read(hw->regmap, ch->address, - buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE); + &hw->scan.channels[1], + sizeof(hw->scan.channels[1])); if (err < 0) goto out; - iio_push_to_buffers_with_timestamp(iio_dev, buffer, + iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan, iio_get_time_ns(iio_dev)); out: --- linux-oracle-5.4.0.orig/drivers/iio/imu/adis16400.c +++ linux-oracle-5.4.0/drivers/iio/imu/adis16400.c @@ -464,8 +464,7 @@ if (ret) goto err_ret; - ret = sscanf(indio_dev->name, "adis%u\n", &device_id); - if (ret != 1) { + if (sscanf(indio_dev->name, "adis%u\n", &device_id) != 1) { ret = -EINVAL; goto err_ret; } @@ -652,9 +651,6 @@ void *buffer; int ret; - if (!adis->buffer) - return -ENOMEM; - if (!(st->variant->flags & ADIS16400_NO_BURST) && st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) { st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST; --- linux-oracle-5.4.0.orig/drivers/iio/imu/adis16480.c +++ linux-oracle-5.4.0/drivers/iio/imu/adis16480.c @@ -454,12 +454,14 @@ case IIO_MAGN: case IIO_PRESSURE: ret = adis_read_reg_16(&st->adis, reg, &val16); - *bias = sign_extend32(val16, 15); + if (ret == 0) + *bias = sign_extend32(val16, 15); break; case IIO_ANGL_VEL: case IIO_ACCEL: ret = adis_read_reg_32(&st->adis, reg, &val32); - *bias = sign_extend32(val32, 31); + if (ret == 0) + *bias = sign_extend32(val32, 31); break; default: ret = -EINVAL; @@ -623,9 +625,13 @@ *val2 = (st->chip_info->temp_scale % 1000) * 1000; return IIO_VAL_INT_PLUS_MICRO; case IIO_PRESSURE: - *val = 0; - *val2 = 4000; /* 40ubar = 0.004 kPa */ - return IIO_VAL_INT_PLUS_MICRO; + /* + * max scale is 1310 mbar + * max raw value is 32767 shifted for 32bits + */ + *val = 131; /* 1310mbar = 131 kPa */ + *val2 = 32767 << 16; + return IIO_VAL_FRACTIONAL; default: return -EINVAL; } @@ -786,13 +792,14 @@ .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), /* - * storing the value in rad/degree and the scale in degree - * gives us the result in rad and better precession than - * storing the scale directly in rad. + * Typically we do IIO_RAD_TO_DEGREE in the denominator, which + * is exactly the same as IIO_DEGREE_TO_RAD in numerator, since + * it gives better approximation. However, in this case we + * cannot do it since it would not fit in a 32bit variable. */ - .gyro_max_val = IIO_RAD_TO_DEGREE(22887), - .gyro_max_scale = 300, - .accel_max_val = IIO_M_S_2_TO_G(21973), + .gyro_max_val = 22887 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(300), + .accel_max_val = IIO_M_S_2_TO_G(21973 << 16), .accel_max_scale = 18, .temp_scale = 5650, /* 5.65 milli degree Celsius */ .int_clk = 2460000, @@ -802,9 +809,9 @@ [ADIS16480] = { .channels = adis16480_channels, .num_channels = ARRAY_SIZE(adis16480_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(22500), - .gyro_max_scale = 450, - .accel_max_val = IIO_M_S_2_TO_G(12500), + .gyro_max_val = 22500 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(450), + .accel_max_val = IIO_M_S_2_TO_G(12500 << 16), .accel_max_scale = 10, .temp_scale = 5650, /* 5.65 milli degree Celsius */ .int_clk = 2460000, @@ -814,9 +821,9 @@ [ADIS16485] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(22500), - .gyro_max_scale = 450, - .accel_max_val = IIO_M_S_2_TO_G(20000), + .gyro_max_val = 22500 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(450), + .accel_max_val = IIO_M_S_2_TO_G(20000 << 16), .accel_max_scale = 5, .temp_scale = 5650, /* 5.65 milli degree Celsius */ .int_clk = 2460000, @@ -826,9 +833,9 @@ [ADIS16488] = { .channels = adis16480_channels, .num_channels = ARRAY_SIZE(adis16480_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(22500), - .gyro_max_scale = 450, - .accel_max_val = IIO_M_S_2_TO_G(22500), + .gyro_max_val = 22500 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(450), + .accel_max_val = IIO_M_S_2_TO_G(22500 << 16), .accel_max_scale = 18, .temp_scale = 5650, /* 5.65 milli degree Celsius */ .int_clk = 2460000, @@ -838,9 +845,9 @@ [ADIS16495_1] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(20000), - .gyro_max_scale = 125, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 20000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(125), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 8, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -851,9 +858,9 @@ [ADIS16495_2] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(18000), - .gyro_max_scale = 450, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 18000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(450), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 8, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -864,9 +871,9 @@ [ADIS16495_3] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(20000), - .gyro_max_scale = 2000, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 20000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(2000), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 8, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -877,9 +884,9 @@ [ADIS16497_1] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(20000), - .gyro_max_scale = 125, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 20000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(125), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 40, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -890,9 +897,9 @@ [ADIS16497_2] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(18000), - .gyro_max_scale = 450, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 18000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(450), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 40, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -903,9 +910,9 @@ [ADIS16497_3] = { .channels = adis16485_channels, .num_channels = ARRAY_SIZE(adis16485_channels), - .gyro_max_val = IIO_RAD_TO_DEGREE(20000), - .gyro_max_scale = 2000, - .accel_max_val = IIO_M_S_2_TO_G(32000), + .gyro_max_val = 20000 << 16, + .gyro_max_scale = IIO_DEGREE_TO_RAD(2000), + .accel_max_val = IIO_M_S_2_TO_G(32000 << 16), .accel_max_scale = 40, .temp_scale = 12500, /* 12.5 milli degree Celsius */ .int_clk = 4250000, @@ -919,6 +926,7 @@ .read_raw = &adis16480_read_raw, .write_raw = &adis16480_write_raw, .update_scan_mode = adis_update_scan_mode, + .debugfs_reg_access = adis_debugfs_reg_access, }; static int adis16480_stop_device(struct iio_dev *indio_dev) --- linux-oracle-5.4.0.orig/drivers/iio/imu/adis_buffer.c +++ linux-oracle-5.4.0/drivers/iio/imu/adis_buffer.c @@ -125,9 +125,6 @@ struct adis *adis = iio_device_get_drvdata(indio_dev); int ret; - if (!adis->buffer) - return -ENOMEM; - if (adis->data->has_paging) { mutex_lock(&adis->txrx_lock); if (adis->current_page != 0) { --- linux-oracle-5.4.0.orig/drivers/iio/imu/bmi160/bmi160.h +++ linux-oracle-5.4.0/drivers/iio/imu/bmi160/bmi160.h @@ -7,6 +7,13 @@ struct bmi160_data { struct regmap *regmap; struct iio_trigger *trig; + /* + * Ensure natural alignment for timestamp if present. + * Max length needed: 2 * 3 channels + 4 bytes padding + 8 byte ts. + * If fewer channels are enabled, less space may be needed, as + * long as the timestamp is still aligned to 8 bytes. + */ + __le16 buf[12] __aligned(8); }; extern const struct regmap_config bmi160_regmap_config; --- linux-oracle-5.4.0.orig/drivers/iio/imu/bmi160/bmi160_core.c +++ linux-oracle-5.4.0/drivers/iio/imu/bmi160/bmi160_core.c @@ -411,8 +411,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct bmi160_data *data = iio_priv(indio_dev); - __le16 buf[16]; - /* 3 sens x 3 axis x __le16 + 3 x __le16 pad + 4 x __le16 tstamp */ int i, ret, j = 0, base = BMI160_REG_DATA_MAGN_XOUT_L; __le16 sample; @@ -422,10 +420,10 @@ &sample, sizeof(sample)); if (ret) goto done; - buf[j++] = sample; + data->buf[j++] = sample; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp); done: iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; --- linux-oracle-5.4.0.orig/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ linux-oracle-5.4.0/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -115,6 +115,7 @@ .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU6500_WHOAMI_VALUE, @@ -122,6 +123,7 @@ .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU6515_WHOAMI_VALUE, @@ -129,6 +131,7 @@ .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU6000_WHOAMI_VALUE, @@ -136,6 +139,7 @@ .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU9150_WHOAMI_VALUE, @@ -143,6 +147,7 @@ .reg = ®_set_6050, .config = &chip_config_6050, .fifo_size = 1024, + .temp = {INV_MPU6050_TEMP_OFFSET, INV_MPU6050_TEMP_SCALE}, }, { .whoami = INV_MPU9250_WHOAMI_VALUE, @@ -150,6 +155,7 @@ .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_MPU9255_WHOAMI_VALUE, @@ -157,6 +163,7 @@ .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_MPU6500_TEMP_OFFSET, INV_MPU6500_TEMP_SCALE}, }, { .whoami = INV_ICM20608_WHOAMI_VALUE, @@ -164,6 +171,7 @@ .reg = ®_set_6500, .config = &chip_config_6050, .fifo_size = 512, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, }, { .whoami = INV_ICM20602_WHOAMI_VALUE, @@ -171,6 +179,7 @@ .reg = ®_set_icm20602, .config = &chip_config_6050, .fifo_size = 1008, + .temp = {INV_ICM20608_TEMP_OFFSET, INV_ICM20608_TEMP_SCALE}, }, }; @@ -471,12 +480,8 @@ return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: - *val = 0; - if (st->chip_type == INV_ICM20602) - *val2 = INV_ICM20602_TEMP_SCALE; - else - *val2 = INV_MPU6050_TEMP_SCALE; - + *val = st->hw->temp.scale / 1000000; + *val2 = st->hw->temp.scale % 1000000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -484,11 +489,7 @@ case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - if (st->chip_type == INV_ICM20602) - *val = INV_ICM20602_TEMP_OFFSET; - else - *val = INV_MPU6050_TEMP_OFFSET; - + *val = st->hw->temp.offset; return IIO_VAL_INT; default: return -EINVAL; @@ -500,13 +501,13 @@ ret = inv_mpu6050_sensor_show(st, st->reg->gyro_offset, chan->channel2, val); mutex_unlock(&st->lock); - return IIO_VAL_INT; + return ret; case IIO_ACCEL: mutex_lock(&st->lock); ret = inv_mpu6050_sensor_show(st, st->reg->accl_offset, chan->channel2, val); mutex_unlock(&st->lock); - return IIO_VAL_INT; + return ret; default: return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ linux-oracle-5.4.0/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -101,6 +101,7 @@ * @reg: register map of the chip. * @config: configuration of the chip. * @fifo_size: size of the FIFO in bytes. + * @temp: offset and scale to apply to raw temperature. */ struct inv_mpu6050_hw { u8 whoami; @@ -108,6 +109,10 @@ const struct inv_mpu6050_reg_map *reg; const struct inv_mpu6050_chip_config *config; size_t fifo_size; + struct { + int offset; + int scale; + } temp; }; /* @@ -218,16 +223,19 @@ #define INV_MPU6050_REG_UP_TIME_MIN 5000 #define INV_MPU6050_REG_UP_TIME_MAX 10000 -#define INV_MPU6050_TEMP_OFFSET 12421 -#define INV_MPU6050_TEMP_SCALE 2941 +#define INV_MPU6050_TEMP_OFFSET 12420 +#define INV_MPU6050_TEMP_SCALE 2941176 #define INV_MPU6050_MAX_GYRO_FS_PARAM 3 #define INV_MPU6050_MAX_ACCL_FS_PARAM 3 #define INV_MPU6050_THREE_AXIS 3 #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 -#define INV_ICM20602_TEMP_OFFSET 8170 -#define INV_ICM20602_TEMP_SCALE 3060 +#define INV_MPU6500_TEMP_OFFSET 7011 +#define INV_MPU6500_TEMP_SCALE 2995178 + +#define INV_ICM20608_TEMP_OFFSET 8170 +#define INV_ICM20608_TEMP_SCALE 3059976 /* 6 + 6 round up and plus 8 */ #define INV_MPU6050_OUTPUT_DATA_SIZE 24 --- linux-oracle-5.4.0.orig/drivers/iio/imu/kmx61.c +++ linux-oracle-5.4.0/drivers/iio/imu/kmx61.c @@ -1198,7 +1198,7 @@ struct kmx61_data *data = kmx61_get_data(indio_dev); int bit, ret, i = 0; u8 base; - s16 buffer[8]; + s16 buffer[8] = { }; if (indio_dev == data->acc_indio_dev) base = KMX61_ACC_XOUT_L; @@ -1393,7 +1393,7 @@ ret = iio_device_register(data->acc_indio_dev); if (ret < 0) { dev_err(&client->dev, "Failed to register acc iio device\n"); - goto err_buffer_cleanup_mag; + goto err_pm_cleanup; } ret = iio_device_register(data->mag_indio_dev); @@ -1406,6 +1406,9 @@ err_iio_unregister_acc: iio_device_unregister(data->acc_indio_dev); +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(&client->dev); + pm_runtime_disable(&client->dev); err_buffer_cleanup_mag: if (client->irq > 0) iio_triggered_buffer_cleanup(data->mag_indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ linux-oracle-5.4.0/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -664,13 +664,29 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) { struct st_lsm6dsx_hw *hw = private; - int count; + int fifo_len = 0, len; - mutex_lock(&hw->fifo_lock); - count = hw->settings->fifo_ops.read_fifo(hw); - mutex_unlock(&hw->fifo_lock); + /* + * If we are using edge IRQs, new samples can arrive while + * processing current interrupt since there are no hw + * guarantees the irq line stays "low" long enough to properly + * detect the new interrupt. In this case the new sample will + * be missed. + * Polling FIFO status register allow us to read new + * samples even if the interrupt arrives while processing + * previous data and the timeslot where the line is "low" is + * too short to be properly detected. + */ + do { + mutex_lock(&hw->fifo_lock); + len = hw->settings->fifo_ops.read_fifo(hw); + mutex_unlock(&hw->fifo_lock); - return count ? IRQ_HANDLED : IRQ_NONE; + if (len > 0) + fifo_len += len; + } while (len > 0); + + return fifo_len ? IRQ_HANDLED : IRQ_NONE; } static int st_lsm6dsx_buffer_preenable(struct iio_dev *iio_dev) --- linux-oracle-5.4.0.orig/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ linux-oracle-5.4.0/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -152,9 +152,10 @@ .addr = 0x10, .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 }, + + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, .fs_len = 3, }, }, @@ -910,7 +911,8 @@ for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { - if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) + if (st_lsm6dsx_sensor_settings[i].id[j].name && + id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) break; } if (j < ST_LSM6DSX_MAX_ID) @@ -985,8 +987,7 @@ return -EINVAL; *val = odr_table->odr_avl[i].val; - - return 0; + return odr_table->odr_avl[i].hz; } static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr, @@ -1014,6 +1015,8 @@ int err; switch (sensor->id) { + case ST_LSM6DSX_ID_GYRO: + break; case ST_LSM6DSX_ID_EXT0: case ST_LSM6DSX_ID_EXT1: case ST_LSM6DSX_ID_EXT2: @@ -1039,8 +1042,8 @@ } break; } - default: - break; + default: /* should never occur */ + return -EINVAL; } if (req_odr > 0) { @@ -1149,8 +1152,10 @@ case IIO_CHAN_INFO_SAMP_FREQ: { u8 data; - err = st_lsm6dsx_check_odr(sensor, val, &data); - if (!err) + val = st_lsm6dsx_check_odr(sensor, val, &data); + if (val < 0) + err = val; + else sensor->odr = val; break; } --- linux-oracle-5.4.0.orig/drivers/iio/industrialio-buffer.c +++ linux-oracle-5.4.0/drivers/iio/industrialio-buffer.c @@ -566,7 +566,7 @@ const unsigned long *mask, bool timestamp) { unsigned bytes = 0; - int length, i; + int length, i, largest = 0; /* How much space will the demuxed element take? */ for_each_set_bit(i, mask, @@ -574,13 +574,17 @@ length = iio_storage_bytes_for_si(indio_dev, i); bytes = ALIGN(bytes, length); bytes += length; + largest = max(largest, length); } if (timestamp) { length = iio_storage_bytes_for_timestamp(indio_dev); bytes = ALIGN(bytes, length); bytes += length; + largest = max(largest, length); } + + bytes = ALIGN(bytes, largest); return bytes; } @@ -841,12 +845,12 @@ indio_dev->masklength, in_ind + 1); while (in_ind != out_ind) { - in_ind = find_next_bit(indio_dev->active_scan_mask, - indio_dev->masklength, - in_ind + 1); length = iio_storage_bytes_for_si(indio_dev, in_ind); /* Make sure we are aligned */ in_loc = roundup(in_loc, length) + length; + in_ind = find_next_bit(indio_dev->active_scan_mask, + indio_dev->masklength, + in_ind + 1); } length = iio_storage_bytes_for_si(indio_dev, in_ind); out_loc = roundup(out_loc, length); --- linux-oracle-5.4.0.orig/drivers/iio/industrialio-core.c +++ linux-oracle-5.4.0/drivers/iio/industrialio-core.c @@ -130,6 +130,8 @@ [IIO_MOD_PM2P5] = "pm2p5", [IIO_MOD_PM4] = "pm4", [IIO_MOD_PM10] = "pm10", + [IIO_MOD_ETHANOL] = "ethanol", + [IIO_MOD_H2] = "h2", }; /* relies on pairs of these shared then separate */ --- linux-oracle-5.4.0.orig/drivers/iio/industrialio-sw-trigger.c +++ linux-oracle-5.4.0/drivers/iio/industrialio-sw-trigger.c @@ -58,8 +58,12 @@ t->group = configfs_register_default_group(iio_triggers_group, t->name, &iio_trigger_type_group_type); - if (IS_ERR(t->group)) + if (IS_ERR(t->group)) { + mutex_lock(&iio_trigger_types_lock); + list_del(&t->list); + mutex_unlock(&iio_trigger_types_lock); ret = PTR_ERR(t->group); + } return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/industrialio-trigger.c +++ linux-oracle-5.4.0/drivers/iio/industrialio-trigger.c @@ -549,7 +549,6 @@ irq_modify_status(trig->subirq_base + i, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE); } - get_device(&trig->dev); return trig; --- linux-oracle-5.4.0.orig/drivers/iio/inkern.c +++ linux-oracle-5.4.0/drivers/iio/inkern.c @@ -136,9 +136,10 @@ idev = bus_find_device(&iio_bus_type, NULL, iiospec.np, iio_dev_node_match); - of_node_put(iiospec.np); - if (idev == NULL) + if (idev == NULL) { + of_node_put(iiospec.np); return -EPROBE_DEFER; + } indio_dev = dev_to_iio_dev(idev); channel->indio_dev = indio_dev; @@ -146,6 +147,7 @@ index = indio_dev->info->of_xlate(indio_dev, &iiospec); else index = __of_iio_simple_xlate(indio_dev, &iiospec); + of_node_put(iiospec.np); if (index < 0) goto err_put; channel->channel = &indio_dev->channels[index]; @@ -464,7 +466,7 @@ return chans; error_free_chans: - for (i = 0; i < nummaps; i++) + for (i = 0; i < mapind; i++) iio_device_put(chans[i].indio_dev); kfree(chans); error_ret: @@ -588,42 +590,64 @@ static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan, int raw, int *processed, unsigned int scale) { - int scale_type, scale_val, scale_val2, offset; + int scale_type, scale_val, scale_val2; + int offset_type, offset_val, offset_val2; s64 raw64 = raw; - int ret; - ret = iio_channel_read(chan, &offset, NULL, IIO_CHAN_INFO_OFFSET); - if (ret >= 0) - raw64 += offset; + offset_type = iio_channel_read(chan, &offset_val, &offset_val2, + IIO_CHAN_INFO_OFFSET); + if (offset_type >= 0) { + switch (offset_type) { + case IIO_VAL_INT: + break; + case IIO_VAL_INT_PLUS_MICRO: + case IIO_VAL_INT_PLUS_NANO: + /* + * Both IIO_VAL_INT_PLUS_MICRO and IIO_VAL_INT_PLUS_NANO + * implicitely truncate the offset to it's integer form. + */ + break; + case IIO_VAL_FRACTIONAL: + offset_val /= offset_val2; + break; + case IIO_VAL_FRACTIONAL_LOG2: + offset_val >>= offset_val2; + break; + default: + return -EINVAL; + } + + raw64 += offset_val; + } scale_type = iio_channel_read(chan, &scale_val, &scale_val2, IIO_CHAN_INFO_SCALE); if (scale_type < 0) { /* - * Just pass raw values as processed if no scaling is - * available. + * If no channel scaling is available apply consumer scale to + * raw value and return. */ - *processed = raw; + *processed = raw * scale; return 0; } switch (scale_type) { case IIO_VAL_INT: - *processed = raw64 * scale_val; + *processed = raw64 * scale_val * scale; break; case IIO_VAL_INT_PLUS_MICRO: if (scale_val2 < 0) - *processed = -raw64 * scale_val; + *processed = -raw64 * scale_val * scale; else - *processed = raw64 * scale_val; + *processed = raw64 * scale_val * scale; *processed += div_s64(raw64 * (s64)scale_val2 * scale, 1000000LL); break; case IIO_VAL_INT_PLUS_NANO: if (scale_val2 < 0) - *processed = -raw64 * scale_val; + *processed = -raw64 * scale_val * scale; else - *processed = raw64 * scale_val; + *processed = raw64 * scale_val * scale; *processed += div_s64(raw64 * (s64)scale_val2 * scale, 1000000000LL); break; --- linux-oracle-5.4.0.orig/drivers/iio/light/Kconfig +++ linux-oracle-5.4.0/drivers/iio/light/Kconfig @@ -239,6 +239,8 @@ tristate "ROHM RPR0521 ALS and proximity sensor driver" depends on I2C select REGMAP_I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say Y here if you want to build support for ROHM's RPR0521 ambient light and proximity sensor device. @@ -485,6 +487,7 @@ config VCNL4035 tristate "VCNL4035 combined ALS and proximity sensor" + select IIO_BUFFER select IIO_TRIGGERED_BUFFER select REGMAP_I2C depends on I2C --- linux-oracle-5.4.0.orig/drivers/iio/light/apds9960.c +++ linux-oracle-5.4.0/drivers/iio/light/apds9960.c @@ -55,9 +55,6 @@ #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2 #define APDS9960_REG_CONFIG_2 0x90 -#define APDS9960_REG_CONFIG_2_GGAIN_MASK 0x60 -#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT 5 - #define APDS9960_REG_ID 0x92 #define APDS9960_REG_STATUS 0x93 @@ -78,6 +75,9 @@ #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6 #define APDS9960_REG_GCONF_2 0xa3 +#define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60 +#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5 + #define APDS9960_REG_GOFFSET_U 0xa4 #define APDS9960_REG_GOFFSET_D 0xa5 #define APDS9960_REG_GPULSE 0xa6 @@ -397,9 +397,9 @@ } ret = regmap_update_bits(data->regmap, - APDS9960_REG_CONFIG_2, - APDS9960_REG_CONFIG_2_GGAIN_MASK, - idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT); + APDS9960_REG_GCONF_2, + APDS9960_REG_GCONF_2_GGAIN_MASK, + idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT); if (!ret) data->pxs_gain = idx; mutex_unlock(&data->lock); --- linux-oracle-5.4.0.orig/drivers/iio/light/bh1750.c +++ linux-oracle-5.4.0/drivers/iio/light/bh1750.c @@ -59,9 +59,9 @@ u16 int_time_low_mask; u16 int_time_high_mask; -} +}; -static const bh1750_chip_info_tbl[] = { +static const struct bh1750_chip_info bh1750_chip_info_tbl[] = { [BH1710] = { 140, 1022, 300, 400, 250000000, 2, 0x001F, 0x03E0 }, [BH1721] = { 140, 1020, 300, 400, 250000000, 2, 0x0010, 0x03E0 }, [BH1750] = { 31, 254, 69, 1740, 57500000, 1, 0x001F, 0x00E0 }, --- linux-oracle-5.4.0.orig/drivers/iio/light/hid-sensor-prox.c +++ linux-oracle-5.4.0/drivers/iio/light/hid-sensor-prox.c @@ -25,6 +25,9 @@ struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info prox_attr; u32 human_presence; + int scale_pre_decml; + int scale_post_decml; + int scale_precision; }; /* Channel definitions */ @@ -95,8 +98,9 @@ ret_type = IIO_VAL_INT; break; case IIO_CHAN_INFO_SCALE: - *val = prox_state->prox_attr.units; - ret_type = IIO_VAL_INT; + *val = prox_state->scale_pre_decml; + *val2 = prox_state->scale_post_decml; + ret_type = prox_state->scale_precision; break; case IIO_CHAN_INFO_OFFSET: *val = hid_sensor_convert_exponent( @@ -236,6 +240,11 @@ HID_USAGE_SENSOR_HUMAN_PRESENCE, &st->common_attributes.sensitivity); + st->scale_precision = hid_sensor_format_scale( + hsdev->usage, + &st->prox_attr, + &st->scale_pre_decml, &st->scale_post_decml); + return ret; } --- linux-oracle-5.4.0.orig/drivers/iio/light/isl29028.c +++ linux-oracle-5.4.0/drivers/iio/light/isl29028.c @@ -628,7 +628,7 @@ ISL29028_POWER_OFF_DELAY_MS); pm_runtime_use_autosuspend(&client->dev); - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "%s(): iio registration failed with error %d\n", --- linux-oracle-5.4.0.orig/drivers/iio/light/isl29125.c +++ linux-oracle-5.4.0/drivers/iio/light/isl29125.c @@ -51,7 +51,11 @@ struct isl29125_data { struct i2c_client *client; u8 conf1; - u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[3]; + s64 timestamp __aligned(8); + } scan; }; #define ISL29125_CHANNEL(_color, _si) { \ @@ -184,10 +188,10 @@ if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/light/ltr501.c +++ linux-oracle-5.4.0/drivers/iio/light/ltr501.c @@ -32,9 +32,12 @@ #define LTR501_PART_ID 0x86 #define LTR501_MANUFAC_ID 0x87 #define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */ +#define LTR501_ALS_DATA1_UPPER 0x89 /* upper 8 bits of LTR501_ALS_DATA1 */ #define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */ +#define LTR501_ALS_DATA0_UPPER 0x8b /* upper 8 bits of LTR501_ALS_DATA0 */ #define LTR501_ALS_PS_STATUS 0x8c #define LTR501_PS_DATA 0x8d /* 16-bit, little endian */ +#define LTR501_PS_DATA_UPPER 0x8e /* upper 8 bits of LTR501_PS_DATA */ #define LTR501_INTR 0x8f /* output mode, polarity, mode */ #define LTR501_PS_THRESH_UP 0x90 /* 11 bit, ps upper threshold */ #define LTR501_PS_THRESH_LOW 0x92 /* 11 bit, ps lower threshold */ @@ -405,18 +408,19 @@ static int ltr501_read_ps(struct ltr501_data *data) { - int ret, status; + __le16 status; + int ret; ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY); if (ret < 0) return ret; ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA, - &status, 2); + &status, sizeof(status)); if (ret < 0) return ret; - return status; + return le16_to_cpu(status); } static int ltr501_read_intr_prst(struct ltr501_data *data, @@ -1204,7 +1208,7 @@ .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl), .ps_gain = ltr559_ps_gain_tbl, .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl), - .als_mode_active = BIT(1), + .als_mode_active = BIT(0), .als_gain_mask = BIT(2) | BIT(3) | BIT(4), .als_gain_shift = 2, .info = <r501_info, @@ -1242,13 +1246,16 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ltr501_data *data = iio_priv(indio_dev); - u16 buf[8]; + struct { + u16 channels[3]; + s64 ts __aligned(8); + } scan; __le16 als_buf[2]; u8 mask = 0; int j = 0; int ret, psdata; - memset(buf, 0, sizeof(buf)); + memset(&scan, 0, sizeof(scan)); /* figure out which data needs to be ready */ if (test_bit(0, indio_dev->active_scan_mask) || @@ -1265,11 +1272,11 @@ ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1, (u8 *)als_buf, sizeof(als_buf)); if (ret < 0) - return ret; + goto done; if (test_bit(0, indio_dev->active_scan_mask)) - buf[j++] = le16_to_cpu(als_buf[1]); + scan.channels[j++] = le16_to_cpu(als_buf[1]); if (test_bit(1, indio_dev->active_scan_mask)) - buf[j++] = le16_to_cpu(als_buf[0]); + scan.channels[j++] = le16_to_cpu(als_buf[0]); } if (mask & LTR501_STATUS_PS_RDY) { @@ -1277,10 +1284,10 @@ &psdata, 2); if (ret < 0) goto done; - buf[j++] = psdata & LTR501_PS_DATA_MASK; + scan.channels[j++] = psdata & LTR501_PS_DATA_MASK; } - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); done: @@ -1350,9 +1357,12 @@ { switch (reg) { case LTR501_ALS_DATA1: + case LTR501_ALS_DATA1_UPPER: case LTR501_ALS_DATA0: + case LTR501_ALS_DATA0_UPPER: case LTR501_ALS_PS_STATUS: case LTR501_PS_DATA: + case LTR501_PS_DATA_UPPER: return true; default: return false; --- linux-oracle-5.4.0.orig/drivers/iio/light/max44000.c +++ linux-oracle-5.4.0/drivers/iio/light/max44000.c @@ -75,6 +75,11 @@ struct max44000_data { struct mutex lock; struct regmap *regmap; + /* Ensure naturally aligned timestamp */ + struct { + u16 channels[2]; + s64 ts __aligned(8); + } scan; }; /* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */ @@ -488,7 +493,6 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct max44000_data *data = iio_priv(indio_dev); - u16 buf[8]; /* 2x u16 + padding + 8 bytes timestamp */ int index = 0; unsigned int regval; int ret; @@ -498,17 +502,17 @@ ret = max44000_read_alsval(data); if (ret < 0) goto out_unlock; - buf[index++] = ret; + data->scan.channels[index++] = ret; } if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) { ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, ®val); if (ret < 0) goto out_unlock; - buf[index] = regval; + data->scan.channels[index] = regval; } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); return IRQ_HANDLED; --- linux-oracle-5.4.0.orig/drivers/iio/light/max44009.c +++ linux-oracle-5.4.0/drivers/iio/light/max44009.c @@ -529,6 +529,12 @@ return devm_iio_device_register(&client->dev, indio_dev); } +static const struct of_device_id max44009_of_match[] = { + { .compatible = "maxim,max44009" }, + { } +}; +MODULE_DEVICE_TABLE(of, max44009_of_match); + static const struct i2c_device_id max44009_id[] = { { "max44009", 0 }, { } @@ -538,18 +544,13 @@ static struct i2c_driver max44009_driver = { .driver = { .name = MAX44009_DRV_NAME, + .of_match_table = max44009_of_match, }, .probe = max44009_probe, .id_table = max44009_id, }; module_i2c_driver(max44009_driver); -static const struct of_device_id max44009_of_match[] = { - { .compatible = "maxim,max44009" }, - { } -}; -MODULE_DEVICE_TABLE(of, max44009_of_match); - MODULE_AUTHOR("Robert Eshleman "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MAX44009 ambient light sensor driver"); --- linux-oracle-5.4.0.orig/drivers/iio/light/opt3001.c +++ linux-oracle-5.4.0/drivers/iio/light/opt3001.c @@ -138,6 +138,10 @@ .val2 = 400000, }, { + .val = 41932, + .val2 = 800000, + }, + { .val = 83865, .val2 = 600000, }, @@ -275,6 +279,8 @@ ret = wait_event_timeout(opt->result_ready_queue, opt->result_ready, msecs_to_jiffies(OPT3001_RESULT_READY_LONG)); + if (ret == 0) + return -ETIMEDOUT; } else { /* Sleep for result ready time */ timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ? @@ -311,9 +317,7 @@ /* Disallow IRQ to access the device while lock is active */ opt->ok_to_ignore_lock = false; - if (ret == 0) - return -ETIMEDOUT; - else if (ret < 0) + if (ret < 0) return ret; if (opt->use_irq) { --- linux-oracle-5.4.0.orig/drivers/iio/light/rpr0521.c +++ linux-oracle-5.4.0/drivers/iio/light/rpr0521.c @@ -194,6 +194,17 @@ bool pxs_need_dis; struct regmap *regmap; + + /* + * Ensure correct naturally aligned timestamp. + * Note that the read will put garbage data into + * the padding but this should not be a problem + */ + struct { + __le16 channels[3]; + u8 garbage; + s64 ts __aligned(8); + } scan; }; static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL); @@ -449,8 +460,6 @@ struct rpr0521_data *data = iio_priv(indio_dev); int err; - u8 buffer[16]; /* 3 16-bit channels + padding + ts */ - /* Use irq timestamp when reasonable. */ if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) { pf->timestamp = data->irq_timestamp; @@ -461,11 +470,11 @@ pf->timestamp = iio_get_time_ns(indio_dev); err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA, - &buffer, + data->scan.channels, (3 * 2) + 1); /* 3 * 16-bit + (discarded) int clear reg. */ if (!err) iio_push_to_buffers_with_timestamp(indio_dev, - buffer, pf->timestamp); + &data->scan, pf->timestamp); else dev_err(&data->client->dev, "Trigger consumer can't read from sensor.\n"); --- linux-oracle-5.4.0.orig/drivers/iio/light/si1133.c +++ linux-oracle-5.4.0/drivers/iio/light/si1133.c @@ -102,6 +102,9 @@ #define SI1133_INPUT_FRACTION_LOW 15 #define SI1133_LUX_OUTPUT_FRACTION 12 #define SI1133_LUX_BUFFER_SIZE 9 +#define SI1133_MEASURE_BUFFER_SIZE 3 + +#define SI1133_SIGN_BIT_INDEX 23 static const int si1133_scale_available[] = { 1, 2, 4, 8, 16, 32, 64, 128}; @@ -234,13 +237,13 @@ } }; -static int si1133_calculate_polynomial_inner(u32 input, u8 fraction, u16 mag, +static int si1133_calculate_polynomial_inner(s32 input, u8 fraction, u16 mag, s8 shift) { return ((input << fraction) / mag) << shift; } -static int si1133_calculate_output(u32 x, u32 y, u8 x_order, u8 y_order, +static int si1133_calculate_output(s32 x, s32 y, u8 x_order, u8 y_order, u8 input_fraction, s8 sign, const struct si1133_coeff *coeffs) { @@ -276,7 +279,7 @@ * The algorithm is from: * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00716 */ -static int si1133_calc_polynomial(u32 x, u32 y, u8 input_fraction, u8 num_coeff, +static int si1133_calc_polynomial(s32 x, s32 y, u8 input_fraction, u8 num_coeff, const struct si1133_coeff *coeffs) { u8 x_order, y_order; @@ -614,7 +617,7 @@ { int err; - __be16 resp; + u8 buffer[SI1133_MEASURE_BUFFER_SIZE]; err = si1133_set_adcmux(data, 0, chan->channel); if (err) @@ -625,12 +628,13 @@ if (err) return err; - err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(resp), - (u8 *)&resp); + err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(buffer), + buffer); if (err) return err; - *val = be16_to_cpu(resp); + *val = sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], + SI1133_SIGN_BIT_INDEX); return err; } @@ -704,9 +708,9 @@ { int err; int lux; - u32 high_vis; - u32 low_vis; - u32 ir; + s32 high_vis; + s32 low_vis; + s32 ir; u8 buffer[SI1133_LUX_BUFFER_SIZE]; /* Activate lux channels */ @@ -719,9 +723,16 @@ if (err) return err; - high_vis = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; - low_vis = (buffer[3] << 16) | (buffer[4] << 8) | buffer[5]; - ir = (buffer[6] << 16) | (buffer[7] << 8) | buffer[8]; + high_vis = + sign_extend32((buffer[0] << 16) | (buffer[1] << 8) | buffer[2], + SI1133_SIGN_BIT_INDEX); + + low_vis = + sign_extend32((buffer[3] << 16) | (buffer[4] << 8) | buffer[5], + SI1133_SIGN_BIT_INDEX); + + ir = sign_extend32((buffer[6] << 16) | (buffer[7] << 8) | buffer[8], + SI1133_SIGN_BIT_INDEX); if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD) lux = si1133_calc_polynomial(high_vis, ir, --- linux-oracle-5.4.0.orig/drivers/iio/light/si1145.c +++ linux-oracle-5.4.0/drivers/iio/light/si1145.c @@ -169,6 +169,7 @@ * @part_info: Part information * @trig: Pointer to iio trigger * @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode + * @buffer: Used to pack data read from sensor. */ struct si1145_data { struct i2c_client *client; @@ -180,6 +181,14 @@ bool autonomous; struct iio_trigger *trig; int meas_rate; + /* + * Ensure timestamp will be naturally aligned if present. + * Maximum buffer size (may be only partly used if not all + * channels are enabled): + * 6*2 bytes channels data + 4 bytes alignment + + * 8 bytes timestamp + */ + u8 buffer[24] __aligned(8); }; /** @@ -441,12 +450,6 @@ struct iio_poll_func *pf = private; struct iio_dev *indio_dev = pf->indio_dev; struct si1145_data *data = iio_priv(indio_dev); - /* - * Maximum buffer size: - * 6*2 bytes channels data + 4 bytes alignment + - * 8 bytes timestamp - */ - u8 buffer[24]; int i, j = 0; int ret; u8 irq_status = 0; @@ -479,7 +482,7 @@ ret = i2c_smbus_read_i2c_block_data_or_emulated( data->client, indio_dev->channels[i].address, - sizeof(u16) * run, &buffer[j]); + sizeof(u16) * run, &data->buffer[j]); if (ret < 0) goto done; j += run * sizeof(u16); @@ -494,7 +497,7 @@ goto done; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/light/st_uvis25.h +++ linux-oracle-5.4.0/drivers/iio/light/st_uvis25.h @@ -27,6 +27,11 @@ struct iio_trigger *trig; bool enabled; int irq; + /* Ensure timestamp is naturally aligned */ + struct { + u8 chan; + s64 ts __aligned(8); + } scan; }; extern const struct dev_pm_ops st_uvis25_pm_ops; --- linux-oracle-5.4.0.orig/drivers/iio/light/st_uvis25_core.c +++ linux-oracle-5.4.0/drivers/iio/light/st_uvis25_core.c @@ -234,17 +234,19 @@ static irqreturn_t st_uvis25_buffer_handler_thread(int irq, void *p) { - u8 buffer[ALIGN(sizeof(u8), sizeof(s64)) + sizeof(s64)]; struct iio_poll_func *pf = p; struct iio_dev *iio_dev = pf->indio_dev; struct st_uvis25_hw *hw = iio_priv(iio_dev); + unsigned int val; int err; - err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, (int *)buffer); + err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, &val); if (err < 0) goto out; - iio_push_to_buffers_with_timestamp(iio_dev, buffer, + hw->scan.chan = val; + + iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan, iio_get_time_ns(iio_dev)); out: --- linux-oracle-5.4.0.orig/drivers/iio/light/stk3310.c +++ linux-oracle-5.4.0/drivers/iio/light/stk3310.c @@ -544,9 +544,8 @@ mutex_lock(&data->lock); ret = regmap_field_read(data->reg_flag_nf, &dir); if (ret < 0) { - dev_err(&data->client->dev, "register read failed\n"); - mutex_unlock(&data->lock); - return ret; + dev_err(&data->client->dev, "register read failed: %d\n", ret); + goto out; } event = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, @@ -558,6 +557,7 @@ ret = regmap_field_write(data->reg_flag_psint, 0); if (ret < 0) dev_err(&data->client->dev, "failed to reset interrupts\n"); +out: mutex_unlock(&data->lock); return IRQ_HANDLED; --- linux-oracle-5.4.0.orig/drivers/iio/light/tcs3414.c +++ linux-oracle-5.4.0/drivers/iio/light/tcs3414.c @@ -53,7 +53,11 @@ u8 control; u8 gain; u8 timing; - u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + s64 timestamp __aligned(8); + } scan; }; #define TCS3414_CHANNEL(_color, _si, _addr) { \ @@ -209,10 +213,10 @@ if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/light/tcs3472.c +++ linux-oracle-5.4.0/drivers/iio/light/tcs3472.c @@ -64,7 +64,11 @@ u8 control; u8 atime; u8 apers; - u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + s64 timestamp __aligned(8); + } scan; }; static const struct iio_event_spec tcs3472_events[] = { @@ -386,10 +390,10 @@ if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: @@ -532,7 +536,8 @@ return 0; free_irq: - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); return ret; @@ -560,7 +565,8 @@ struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); iio_triggered_buffer_cleanup(indio_dev); tcs3472_powerdown(iio_priv(indio_dev)); --- linux-oracle-5.4.0.orig/drivers/iio/light/tsl2583.c +++ linux-oracle-5.4.0/drivers/iio/light/tsl2583.c @@ -341,6 +341,14 @@ return lux_val; } + /* Avoid division by zero of lux_value later on */ + if (lux_val == 0) { + dev_err(&chip->client->dev, + "%s: lux_val of 0 will produce out of range trim_value\n", + __func__); + return -ENODATA; + } + gain_trim_val = (unsigned int)(((chip->als_settings.als_cal_target) * chip->als_settings.als_gain_trim) / lux_val); if ((gain_trim_val < 250) || (gain_trim_val > 4000)) { @@ -849,7 +857,7 @@ TSL2583_POWER_OFF_DELAY_MS); pm_runtime_use_autosuspend(&clientp->dev); - ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev); + ret = iio_device_register(indio_dev); if (ret) { dev_err(&clientp->dev, "%s: iio registration failed\n", __func__); --- linux-oracle-5.4.0.orig/drivers/iio/light/tsl2772.c +++ linux-oracle-5.4.0/drivers/iio/light/tsl2772.c @@ -606,6 +606,7 @@ return -EINVAL; } } + chip->settings.prox_diode = prox_diode_mask; return 0; } --- linux-oracle-5.4.0.orig/drivers/iio/light/vcnl4000.c +++ linux-oracle-5.4.0/drivers/iio/light/vcnl4000.c @@ -163,20 +163,22 @@ if (ret < 0) return ret; - data->al_scale = 24000; data->vcnl4200_al.reg = VCNL4200_AL_DATA; data->vcnl4200_ps.reg = VCNL4200_PS_DATA; switch (id) { case VCNL4200_PROD_ID: - /* Integration time is 50ms, but the experiments */ - /* show 54ms in total. */ - data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000); - data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000); + /* Default wait time is 50ms, add 20% tolerance. */ + data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000); + /* Default wait time is 4.8ms, add 20% tolerance. */ + data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000); + data->al_scale = 24000; break; case VCNL4040_PROD_ID: - /* Integration time is 80ms, add 10ms. */ - data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000); - data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000); + /* Default wait time is 80ms, add 20% tolerance. */ + data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000); + /* Default wait time is 5ms, add 20% tolerance. */ + data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000); + data->al_scale = 120000; break; } data->vcnl4200_al.last_measurement = ktime_set(0, 0); @@ -191,7 +193,6 @@ u8 rdy_mask, u8 data_reg, int *val) { int tries = 20; - __be16 buf; int ret; mutex_lock(&data->vcnl4000_lock); @@ -218,13 +219,12 @@ goto fail; } - ret = i2c_smbus_read_i2c_block_data(data->client, - data_reg, sizeof(buf), (u8 *) &buf); + ret = i2c_smbus_read_word_swapped(data->client, data_reg); if (ret < 0) goto fail; mutex_unlock(&data->vcnl4000_lock); - *val = be16_to_cpu(buf); + *val = ret; return 0; --- linux-oracle-5.4.0.orig/drivers/iio/light/vcnl4035.c +++ linux-oracle-5.4.0/drivers/iio/light/vcnl4035.c @@ -8,6 +8,7 @@ * TODO: Proximity */ #include +#include #include #include #include @@ -42,6 +43,7 @@ #define VCNL4035_ALS_PERS_MASK GENMASK(3, 2) #define VCNL4035_INT_ALS_IF_H_MASK BIT(12) #define VCNL4035_INT_ALS_IF_L_MASK BIT(13) +#define VCNL4035_DEV_ID_MASK GENMASK(7, 0) /* Default values */ #define VCNL4035_MODE_ALS_ENABLE BIT(0) @@ -102,7 +104,8 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct vcnl4035_data *data = iio_priv(indio_dev); - u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]; + /* Ensure naturally aligned timestamp */ + u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8) = { }; int ret; ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); @@ -414,6 +417,7 @@ return ret; } + id = FIELD_GET(VCNL4035_DEV_ID_MASK, id); if (id != VCNL4035_DEV_ID_VAL) { dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n", id, VCNL4035_DEV_ID_VAL); --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/ak8974.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/ak8974.c @@ -185,6 +185,11 @@ bool drdy_irq; struct completion drdy_complete; bool drdy_active_low; + /* Ensure timestamp is naturally aligned */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan; }; static const char ak8974_reg_avdd[] = "avdd"; @@ -564,7 +569,7 @@ * We read all axes and discard all but one, for optimized * reading, use the triggered buffer. */ - *val = le16_to_cpu(hw_values[chan->address]); + *val = (s16)le16_to_cpu(hw_values[chan->address]); ret = IIO_VAL_INT; } @@ -581,7 +586,6 @@ { struct ak8974 *ak8974 = iio_priv(indio_dev); int ret; - __le16 hw_values[8]; /* Three axes + 64bit padding */ pm_runtime_get_sync(&ak8974->i2c->dev); mutex_lock(&ak8974->lock); @@ -591,13 +595,13 @@ dev_err(&ak8974->i2c->dev, "error triggering measure\n"); goto out_unlock; } - ret = ak8974_getresult(ak8974, hw_values); + ret = ak8974_getresult(ak8974, ak8974->scan.channels); if (ret) { dev_err(&ak8974->i2c->dev, "error getting measures\n"); goto out_unlock; } - iio_push_to_buffers_with_timestamp(indio_dev, hw_values, + iio_push_to_buffers_with_timestamp(indio_dev, &ak8974->scan, iio_get_time_ns(indio_dev)); out_unlock: @@ -764,19 +768,21 @@ ak8974->map = devm_regmap_init_i2c(i2c, &ak8974_regmap_config); if (IS_ERR(ak8974->map)) { dev_err(&i2c->dev, "failed to allocate register map\n"); + pm_runtime_put_noidle(&i2c->dev); + pm_runtime_disable(&i2c->dev); return PTR_ERR(ak8974->map); } ret = ak8974_set_power(ak8974, AK8974_PWR_ON); if (ret) { dev_err(&i2c->dev, "could not power on\n"); - goto power_off; + goto disable_pm; } ret = ak8974_detect(ak8974); if (ret) { dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n"); - goto power_off; + goto disable_pm; } ret = ak8974_selftest(ak8974); @@ -786,14 +792,9 @@ ret = ak8974_reset(ak8974); if (ret) { dev_err(&i2c->dev, "AK8974 reset failed\n"); - goto power_off; + goto disable_pm; } - pm_runtime_set_autosuspend_delay(&i2c->dev, - AK8974_AUTOSUSPEND_DELAY); - pm_runtime_use_autosuspend(&i2c->dev); - pm_runtime_put(&i2c->dev); - indio_dev->dev.parent = &i2c->dev; indio_dev->channels = ak8974_channels; indio_dev->num_channels = ARRAY_SIZE(ak8974_channels); @@ -846,6 +847,11 @@ goto cleanup_buffer; } + pm_runtime_set_autosuspend_delay(&i2c->dev, + AK8974_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&i2c->dev); + pm_runtime_put(&i2c->dev); + return 0; cleanup_buffer: @@ -854,7 +860,6 @@ pm_runtime_put_noidle(&i2c->dev); pm_runtime_disable(&i2c->dev); ak8974_set_power(ak8974, AK8974_PWR_OFF); -power_off: regulator_bulk_disable(ARRAY_SIZE(ak8974->regs), ak8974->regs); return ret; --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/ak8975.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/ak8975.c @@ -368,6 +368,12 @@ struct iio_mount_matrix orientation; struct regulator *vdd; struct regulator *vid; + + /* Ensure natural alignment of timestamp */ + struct { + s16 channels[3]; + s64 ts __aligned(8); + } scan; }; /* Enable attached power regulator if any. */ @@ -385,6 +391,7 @@ if (ret) { dev_warn(&data->client->dev, "Failed to enable specified Vid supply\n"); + regulator_disable(data->vdd); return ret; } /* @@ -653,22 +660,8 @@ if (ret < 0) return ret; - /* This will be executed only for non-interrupt based waiting case */ - if (ret & data->def->ctrl_masks[ST1_DRDY]) { - ret = i2c_smbus_read_byte_data(client, - data->def->ctrl_regs[ST2]); - if (ret < 0) { - dev_err(&client->dev, "Error in reading ST2\n"); - return ret; - } - if (ret & (data->def->ctrl_masks[ST2_DERR] | - data->def->ctrl_masks[ST2_HOFL])) { - dev_err(&client->dev, "ST2 status error 0x%x\n", ret); - return -EINVAL; - } - } - - return 0; + /* Return with zero if the data is ready. */ + return !data->def->ctrl_regs[ST1_DRDY]; } /* Retrieve raw flux value for one of the x, y, or z axis. */ @@ -695,6 +688,20 @@ if (ret < 0) goto exit; + /* Read out ST2 for release lock on measurment data. */ + ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]); + if (ret < 0) { + dev_err(&client->dev, "Error in reading ST2\n"); + goto exit; + } + + if (ret & (data->def->ctrl_masks[ST2_DERR] | + data->def->ctrl_masks[ST2_HOFL])) { + dev_err(&client->dev, "ST2 status error 0x%x\n", ret); + ret = -EINVAL; + goto exit; + } + mutex_unlock(&data->lock); pm_runtime_mark_last_busy(&data->client->dev); @@ -805,7 +812,6 @@ const struct i2c_client *client = data->client; const struct ak_def *def = data->def; int ret; - s16 buff[8]; /* 3 x 16 bits axis values + 1 aligned 64 bits timestamp */ __le16 fval[3]; mutex_lock(&data->lock); @@ -828,12 +834,13 @@ mutex_unlock(&data->lock); /* Clamp to valid range. */ - buff[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range); - buff[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range); - buff[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range); + data->scan.channels[0] = clamp_t(s16, le16_to_cpu(fval[0]), -def->range, def->range); + data->scan.channels[1] = clamp_t(s16, le16_to_cpu(fval[1]), -def->range, def->range); + data->scan.channels[2] = clamp_t(s16, le16_to_cpu(fval[2]), -def->range, def->range); - iio_push_to_buffers_with_timestamp(indio_dev, buff, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); + return; unlock: --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/bmc150_magn.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/bmc150_magn.c @@ -136,8 +136,11 @@ struct mutex mutex; struct regmap *regmap; struct iio_mount_matrix orientation; - /* 4 x 32 bits for x, y z, 4 bytes align, 64 bits timestamp */ - s32 buffer[6]; + /* Ensure timestamp is naturally aligned */ + struct { + s32 chans[3]; + s64 timestamp __aligned(8); + } scan; struct iio_trigger *dready_trig; bool dready_trigger_on; int max_odr; @@ -260,7 +263,7 @@ int ret; if (on) { - ret = pm_runtime_get_sync(data->dev); + ret = pm_runtime_resume_and_get(data->dev); } else { pm_runtime_mark_last_busy(data->dev); ret = pm_runtime_put_autosuspend(data->dev); @@ -269,9 +272,6 @@ if (ret < 0) { dev_err(data->dev, "failed to change power state to %d\n", on); - if (on) - pm_runtime_put_noidle(data->dev); - return ret; } #endif @@ -673,11 +673,11 @@ int ret; mutex_lock(&data->mutex); - ret = bmc150_magn_read_xyz(data, data->buffer); + ret = bmc150_magn_read_xyz(data, data->scan.chans); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: @@ -944,12 +944,15 @@ ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(dev, "unable to register iio device\n"); - goto err_buffer_cleanup; + goto err_pm_cleanup; } dev_dbg(dev, "Registered device %s\n", name); return 0; +err_pm_cleanup: + pm_runtime_dont_use_autosuspend(dev); + pm_runtime_disable(dev); err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); err_free_irq: @@ -973,7 +976,6 @@ pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); iio_triggered_buffer_cleanup(indio_dev); --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/hmc5843.h +++ linux-oracle-5.4.0/drivers/iio/magnetometer/hmc5843.h @@ -33,7 +33,8 @@ * @lock: update and read regmap data * @regmap: hardware access register maps * @variant: describe chip variants - * @buffer: 3x 16-bit channels + padding + 64-bit timestamp + * @scan: buffer to pack data for passing to + * iio_push_to_buffers_with_timestamp() */ struct hmc5843_data { struct device *dev; @@ -41,7 +42,10 @@ struct regmap *regmap; const struct hmc5843_chip_info *variant; struct iio_mount_matrix orientation; - __be16 buffer[8]; + struct { + __be16 chans[3]; + s64 timestamp __aligned(8); + } scan; }; int hmc5843_common_probe(struct device *dev, struct regmap *regmap, --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/hmc5843_core.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/hmc5843_core.c @@ -446,13 +446,13 @@ } ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS, - data->buffer, 3 * sizeof(__be16)); + data->scan.chans, sizeof(data->scan.chans)); mutex_unlock(&data->lock); if (ret < 0) goto done; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/mag3110.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/mag3110.c @@ -56,6 +56,12 @@ int sleep_val; struct regulator *vdd_reg; struct regulator *vddio_reg; + /* Ensure natural alignment of timestamp */ + struct { + __be16 channels[3]; + u8 temperature; + s64 ts __aligned(8); + } scan; }; static int mag3110_request(struct mag3110_data *data) @@ -387,10 +393,9 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mag3110_data *data = iio_priv(indio_dev); - u8 buffer[16]; /* 3 16-bit channels + 1 byte temp + padding + ts */ int ret; - ret = mag3110_read(data, (__be16 *) buffer); + ret = mag3110_read(data, data->scan.channels); if (ret < 0) goto done; @@ -399,10 +404,10 @@ MAG3110_DIE_TEMP); if (ret < 0) goto done; - buffer[6] = ret; + data->scan.temperature = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: --- linux-oracle-5.4.0.orig/drivers/iio/magnetometer/rm3100-core.c +++ linux-oracle-5.4.0/drivers/iio/magnetometer/rm3100-core.c @@ -76,7 +76,8 @@ bool use_interrupt; int conversion_time; int scale; - u8 buffer[RM3100_SCAN_BYTES]; + /* Ensure naturally aligned timestamp */ + u8 buffer[RM3100_SCAN_BYTES] __aligned(8); struct iio_trigger *drdy_trig; /* @@ -538,6 +539,7 @@ struct rm3100_data *data; unsigned int tmp; int ret; + int samp_rate_index; indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) @@ -597,9 +599,14 @@ ret = regmap_read(regmap, RM3100_REG_TMRC, &tmp); if (ret < 0) return ret; + + samp_rate_index = tmp - RM3100_TMRC_OFFSET; + if (samp_rate_index < 0 || samp_rate_index >= RM3100_SAMP_NUM) { + dev_err(dev, "The value read from RM3100_REG_TMRC is invalid!\n"); + return -EINVAL; + } /* Initializing max wait time, which is double conversion time. */ - data->conversion_time = rm3100_samp_rates[tmp - RM3100_TMRC_OFFSET][2] - * 2; + data->conversion_time = rm3100_samp_rates[samp_rate_index][2] * 2; /* Cycle count values may not be what we want. */ if ((tmp - RM3100_TMRC_OFFSET) == 0) --- linux-oracle-5.4.0.orig/drivers/iio/potentiostat/lmp91000.c +++ linux-oracle-5.4.0/drivers/iio/potentiostat/lmp91000.c @@ -71,8 +71,8 @@ struct completion completion; u8 chan_select; - - u32 buffer[4]; /* 64-bit data + 64-bit timestamp */ + /* 64-bit data + 64-bit naturally aligned timestamp */ + u32 buffer[4] __aligned(8); }; static const struct iio_chan_spec lmp91000_channels[] = { --- linux-oracle-5.4.0.orig/drivers/iio/pressure/bmp280-core.c +++ linux-oracle-5.4.0/drivers/iio/pressure/bmp280-core.c @@ -264,6 +264,8 @@ + (s32)2097152) * calib->H2 + 8192) >> 14); var -= ((((var >> 15) * (var >> 15)) >> 7) * (s32)calib->H1) >> 4; + var = clamp_val(var, 0, 419430400); + return var >> 12; }; @@ -706,7 +708,7 @@ unsigned int ctrl; if (data->use_eoc) - init_completion(&data->done); + reinit_completion(&data->done); ret = regmap_write(data->regmap, BMP280_REG_CTRL_MEAS, ctrl_meas); if (ret) @@ -962,6 +964,9 @@ "trying to enforce it\n"); irq_trig = IRQF_TRIGGER_RISING; } + + init_completion(&data->done); + ret = devm_request_threaded_irq(dev, irq, bmp085_eoc_irq, @@ -1108,7 +1113,7 @@ * however as it happens, the BMP085 shares the chip ID of BMP180 * so we look for an IRQ if we have that. */ - if (irq > 0 || (chip_id == BMP180_CHIP_ID)) { + if (irq > 0 && (chip_id == BMP180_CHIP_ID)) { ret = bmp085_fetch_eoc_irq(dev, name, irq, data); if (ret) goto out_disable_vdda; --- linux-oracle-5.4.0.orig/drivers/iio/pressure/cros_ec_baro.c +++ linux-oracle-5.4.0/drivers/iio/pressure/cros_ec_baro.c @@ -114,6 +114,7 @@ static const struct iio_info cros_ec_baro_info = { .read_raw = &cros_ec_baro_read, .write_raw = &cros_ec_baro_write, + .read_avail = &cros_ec_sensors_core_read_avail, }; static int cros_ec_baro_probe(struct platform_device *pdev) @@ -149,6 +150,8 @@ BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_FREQUENCY); + channel->info_mask_shared_by_all_available = + BIT(IIO_CHAN_INFO_SAMP_FREQ); channel->scan_type.realbits = CROS_EC_SENSOR_BITS; channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; channel->scan_type.shift = 0; --- linux-oracle-5.4.0.orig/drivers/iio/pressure/dps310.c +++ linux-oracle-5.4.0/drivers/iio/pressure/dps310.c @@ -57,8 +57,8 @@ #define DPS310_RESET_MAGIC 0x09 #define DPS310_COEF_BASE 0x10 -/* Make sure sleep time is <= 20ms for usleep_range */ -#define DPS310_POLL_SLEEP_US(t) min(20000, (t) / 8) +/* Make sure sleep time is <= 30ms for usleep_range */ +#define DPS310_POLL_SLEEP_US(t) min(30000, (t) / 8) /* Silently handle error in rate value here */ #define DPS310_POLL_TIMEOUT_US(rc) ((rc) <= 0 ? 1000000 : 1000000 / (rc)) @@ -89,6 +89,7 @@ s32 c00, c10, c20, c30, c01, c11, c21; s32 pressure_raw; s32 temp_raw; + bool timeout_recovery_failed; }; static const struct iio_chan_spec dps310_channels[] = { @@ -159,6 +160,102 @@ return 0; } +/* + * Some versions of the chip will read temperatures in the ~60C range when + * it's actually ~20C. This is the manufacturer recommended workaround + * to correct the issue. The registers used below are undocumented. + */ +static int dps310_temp_workaround(struct dps310_data *data) +{ + int rc; + int reg; + + rc = regmap_read(data->regmap, 0x32, ®); + if (rc) + return rc; + + /* + * If bit 1 is set then the device is okay, and the workaround does not + * need to be applied + */ + if (reg & BIT(1)) + return 0; + + rc = regmap_write(data->regmap, 0x0e, 0xA5); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x0f, 0x96); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x62, 0x02); + if (rc) + return rc; + + rc = regmap_write(data->regmap, 0x0e, 0x00); + if (rc) + return rc; + + return regmap_write(data->regmap, 0x0f, 0x00); +} + +static int dps310_startup(struct dps310_data *data) +{ + int rc; + int ready; + + /* + * Set up pressure sensor in single sample, one measurement per second + * mode + */ + rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); + if (rc) + return rc; + + /* + * Set up external (MEMS) temperature sensor in single sample, one + * measurement per second mode + */ + rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); + if (rc) + return rc; + + /* Temp and pressure shifts are disabled when PRC <= 8 */ + rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, + DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); + if (rc) + return rc; + + /* MEAS_CFG doesn't update correctly unless first written with 0 */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, 0); + if (rc) + return rc; + + /* Turn on temperature and pressure measurement in the background */ + rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, + DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | + DPS310_TEMP_EN | DPS310_BACKGROUND); + if (rc) + return rc; + + /* + * Calibration coefficients required for reporting temperature. + * They are available 40ms after the device has started + */ + rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, + ready & DPS310_COEF_RDY, 10000, 40000); + if (rc) + return rc; + + rc = dps310_get_coefs(data); + if (rc) + return rc; + + return dps310_temp_workaround(data); +} + static int dps310_get_pres_precision(struct dps310_data *data) { int rc; @@ -297,11 +394,69 @@ return scale_factors[ilog2(rc)]; } +static int dps310_reset_wait(struct dps310_data *data) +{ + int rc; + + rc = regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); + if (rc) + return rc; + + /* Wait for device chip access: 15ms in specification */ + usleep_range(15000, 55000); + return 0; +} + +static int dps310_reset_reinit(struct dps310_data *data) +{ + int rc; + + rc = dps310_reset_wait(data); + if (rc) + return rc; + + return dps310_startup(data); +} + +static int dps310_ready_status(struct dps310_data *data, int ready_bit, int timeout) +{ + int sleep = DPS310_POLL_SLEEP_US(timeout); + int ready; + + return regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, ready & ready_bit, + sleep, timeout); +} + +static int dps310_ready(struct dps310_data *data, int ready_bit, int timeout) +{ + int rc; + + rc = dps310_ready_status(data, ready_bit, timeout); + if (rc) { + if (rc == -ETIMEDOUT && !data->timeout_recovery_failed) { + /* Reset and reinitialize the chip. */ + if (dps310_reset_reinit(data)) { + data->timeout_recovery_failed = true; + } else { + /* Try again to get sensor ready status. */ + if (dps310_ready_status(data, ready_bit, timeout)) + data->timeout_recovery_failed = true; + else + return 0; + } + } + + return rc; + } + + data->timeout_recovery_failed = false; + return 0; +} + static int dps310_read_pres_raw(struct dps310_data *data) { int rc; int rate; - int ready; int timeout; s32 raw; u8 val[3]; @@ -313,9 +468,7 @@ timeout = DPS310_POLL_TIMEOUT_US(rate); /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_PRS_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); + rc = dps310_ready(data, DPS310_PRS_RDY, timeout); if (rc) goto done; @@ -352,7 +505,6 @@ { int rc; int rate; - int ready; int timeout; if (mutex_lock_interruptible(&data->lock)) @@ -362,10 +514,8 @@ timeout = DPS310_POLL_TIMEOUT_US(rate); /* Poll for sensor readiness; base the timeout upon the sample rate. */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_TMP_RDY, - DPS310_POLL_SLEEP_US(timeout), timeout); - if (rc < 0) + rc = dps310_ready(data, DPS310_TMP_RDY, timeout); + if (rc) goto done; rc = dps310_read_temp_ready(data); @@ -580,7 +730,7 @@ } } -static int dps310_calculate_temp(struct dps310_data *data) +static int dps310_calculate_temp(struct dps310_data *data, int *val) { s64 c0; s64 t; @@ -596,7 +746,9 @@ t = c0 + ((s64)data->temp_raw * (s64)data->c1); /* Convert to milliCelsius and scale the temperature */ - return (int)div_s64(t * 1000LL, kt); + *val = (int)div_s64(t * 1000LL, kt); + + return 0; } static int dps310_read_temp(struct dps310_data *data, int *val, int *val2, @@ -618,11 +770,10 @@ if (rc) return rc; - rc = dps310_calculate_temp(data); - if (rc < 0) + rc = dps310_calculate_temp(data, val); + if (rc) return rc; - *val = rc; return IIO_VAL_INT; case IIO_CHAN_INFO_OVERSAMPLING_RATIO: @@ -660,7 +811,7 @@ { struct dps310_data *data = action_data; - regmap_write(data->regmap, DPS310_RESET, DPS310_RESET_MAGIC); + dps310_reset_wait(data); } static const struct regmap_config dps310_regmap_config = { @@ -677,52 +828,12 @@ .write_raw = dps310_write_raw, }; -/* - * Some verions of chip will read temperatures in the ~60C range when - * its actually ~20C. This is the manufacturer recommended workaround - * to correct the issue. The registers used below are undocumented. - */ -static int dps310_temp_workaround(struct dps310_data *data) -{ - int rc; - int reg; - - rc = regmap_read(data->regmap, 0x32, ®); - if (rc < 0) - return rc; - - /* - * If bit 1 is set then the device is okay, and the workaround does not - * need to be applied - */ - if (reg & BIT(1)) - return 0; - - rc = regmap_write(data->regmap, 0x0e, 0xA5); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0f, 0x96); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x62, 0x02); - if (rc < 0) - return rc; - - rc = regmap_write(data->regmap, 0x0e, 0x00); - if (rc < 0) - return rc; - - return regmap_write(data->regmap, 0x0f, 0x00); -} - static int dps310_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct dps310_data *data; struct iio_dev *iio; - int rc, ready; + int rc; iio = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!iio) @@ -748,54 +859,8 @@ if (rc) return rc; - /* - * Set up pressure sensor in single sample, one measurement per second - * mode - */ - rc = regmap_write(data->regmap, DPS310_PRS_CFG, 0); - - /* - * Set up external (MEMS) temperature sensor in single sample, one - * measurement per second mode - */ - rc = regmap_write(data->regmap, DPS310_TMP_CFG, DPS310_TMP_EXT); - if (rc < 0) - return rc; - - /* Temp and pressure shifts are disabled when PRC <= 8 */ - rc = regmap_write_bits(data->regmap, DPS310_CFG_REG, - DPS310_PRS_SHIFT_EN | DPS310_TMP_SHIFT_EN, 0); - if (rc < 0) - return rc; - - /* MEAS_CFG doesn't update correctly unless first written with 0 */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, 0); - if (rc < 0) - return rc; - - /* Turn on temperature and pressure measurement in the background */ - rc = regmap_write_bits(data->regmap, DPS310_MEAS_CFG, - DPS310_MEAS_CTRL_BITS, DPS310_PRS_EN | - DPS310_TEMP_EN | DPS310_BACKGROUND); - if (rc < 0) - return rc; - - /* - * Calibration coefficients required for reporting temperature. - * They are available 40ms after the device has started - */ - rc = regmap_read_poll_timeout(data->regmap, DPS310_MEAS_CFG, ready, - ready & DPS310_COEF_RDY, 10000, 40000); - if (rc < 0) - return rc; - - rc = dps310_get_coefs(data); - if (rc < 0) - return rc; - - rc = dps310_temp_workaround(data); - if (rc < 0) + rc = dps310_startup(data); + if (rc) return rc; rc = devm_iio_device_register(&client->dev, iio); --- linux-oracle-5.4.0.orig/drivers/iio/pressure/mpl3115.c +++ linux-oracle-5.4.0/drivers/iio/pressure/mpl3115.c @@ -144,7 +144,14 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mpl3115_data *data = iio_priv(indio_dev); - u8 buffer[16]; /* 32-bit channel + 16-bit channel + padding + ts */ + /* + * 32-bit channel + 16-bit channel + padding + ts + * Note that it is possible for only one of the first 2 + * channels to be enabled. If that happens, the first element + * of the buffer may be either 16 or 32-bits. As such we cannot + * use a simple structure definition to express this data layout. + */ + u8 buffer[16] __aligned(8); int ret, pos = 0; mutex_lock(&data->lock); --- linux-oracle-5.4.0.orig/drivers/iio/pressure/ms5611.h +++ linux-oracle-5.4.0/drivers/iio/pressure/ms5611.h @@ -25,13 +25,6 @@ MS5607, }; -struct ms5611_chip_info { - u16 prom[MS5611_PROM_WORDS_NB]; - - int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info, - s32 *temp, s32 *pressure); -}; - /* * OverSampling Rate descriptor. * Warning: cmd MUST be kept aligned on a word boundary (see @@ -50,12 +43,15 @@ const struct ms5611_osr *pressure_osr; const struct ms5611_osr *temp_osr; - int (*reset)(struct device *dev); - int (*read_prom_word)(struct device *dev, int index, u16 *word); - int (*read_adc_temp_and_pressure)(struct device *dev, + u16 prom[MS5611_PROM_WORDS_NB]; + + int (*reset)(struct ms5611_state *st); + int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word); + int (*read_adc_temp_and_pressure)(struct ms5611_state *st, s32 *temp, s32 *pressure); - struct ms5611_chip_info *chip_info; + int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp, + s32 *pressure); struct regulator *vdd; }; --- linux-oracle-5.4.0.orig/drivers/iio/pressure/ms5611_core.c +++ linux-oracle-5.4.0/drivers/iio/pressure/ms5611_core.c @@ -76,7 +76,7 @@ crc = (crc >> 12) & 0x000F; - return crc_orig != 0x0000 && crc == crc_orig; + return crc == crc_orig; } static int ms5611_read_prom(struct iio_dev *indio_dev) @@ -85,8 +85,7 @@ struct ms5611_state *st = iio_priv(indio_dev); for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { - ret = st->read_prom_word(&indio_dev->dev, - i, &st->chip_info->prom[i]); + ret = st->read_prom_word(st, i, &st->prom[i]); if (ret < 0) { dev_err(&indio_dev->dev, "failed to read prom at %d\n", i); @@ -94,7 +93,7 @@ } } - if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { + if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { dev_err(&indio_dev->dev, "PROM integrity check failed\n"); return -ENODEV; } @@ -108,28 +107,27 @@ int ret; struct ms5611_state *st = iio_priv(indio_dev); - ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure); + ret = st->read_adc_temp_and_pressure(st, temp, pressure); if (ret < 0) { dev_err(&indio_dev->dev, "failed to read temperature and pressure\n"); return ret; } - return st->chip_info->temp_and_pressure_compensate(st->chip_info, - temp, pressure); + return st->compensate_temp_and_pressure(st, temp, pressure); } -static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, +static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st, s32 *temp, s32 *pressure) { s32 t = *temp, p = *pressure; s64 off, sens, dt; - dt = t - (chip_info->prom[5] << 8); - off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); - sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); + dt = t - (st->prom[5] << 8); + off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); + sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); - t = 2000 + ((chip_info->prom[6] * dt) >> 23); + t = 2000 + ((st->prom[6] * dt) >> 23); if (t < 2000) { s64 off2, sens2, t2; @@ -155,17 +153,17 @@ return 0; } -static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, +static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st, s32 *temp, s32 *pressure) { s32 t = *temp, p = *pressure; s64 off, sens, dt; - dt = t - (chip_info->prom[5] << 8); - off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); - sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); + dt = t - (st->prom[5] << 8); + off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6); + sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7); - t = 2000 + ((chip_info->prom[6] * dt) >> 23); + t = 2000 + ((st->prom[6] * dt) >> 23); if (t < 2000) { s64 off2, sens2, t2, tmp; @@ -196,7 +194,7 @@ int ret; struct ms5611_state *st = iio_priv(indio_dev); - ret = st->reset(&indio_dev->dev); + ret = st->reset(st); if (ret < 0) { dev_err(&indio_dev->dev, "failed to reset device\n"); return ret; @@ -212,16 +210,21 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ms5611_state *st = iio_priv(indio_dev); - s32 buf[4]; /* s32 (pressure) + s32 (temp) + 2 * s32 (timestamp) */ + /* Ensure buffer elements are naturally aligned */ + struct { + s32 channels[2]; + s64 ts __aligned(8); + } scan; int ret; mutex_lock(&st->lock); - ret = ms5611_read_temp_and_pressure(indio_dev, &buf[1], &buf[0]); + ret = ms5611_read_temp_and_pressure(indio_dev, &scan.channels[1], + &scan.channels[0]); mutex_unlock(&st->lock); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: @@ -338,15 +341,6 @@ static const unsigned long ms5611_scan_masks[] = {0x3, 0}; -static struct ms5611_chip_info chip_info_tbl[] = { - [MS5611] = { - .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate, - }, - [MS5607] = { - .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate, - } -}; - static const struct iio_chan_spec ms5611_channels[] = { { .type = IIO_PRESSURE, @@ -429,7 +423,20 @@ struct ms5611_state *st = iio_priv(indio_dev); mutex_init(&st->lock); - st->chip_info = &chip_info_tbl[type]; + + switch (type) { + case MS5611: + st->compensate_temp_and_pressure = + ms5611_temp_and_pressure_compensate; + break; + case MS5607: + st->compensate_temp_and_pressure = + ms5607_temp_and_pressure_compensate; + break; + default: + return -EINVAL; + } + st->temp_osr = &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; st->pressure_osr = --- linux-oracle-5.4.0.orig/drivers/iio/pressure/ms5611_i2c.c +++ linux-oracle-5.4.0/drivers/iio/pressure/ms5611_i2c.c @@ -18,17 +18,15 @@ #include "ms5611.h" -static int ms5611_i2c_reset(struct device *dev) +static int ms5611_i2c_reset(struct ms5611_state *st) { - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); - return i2c_smbus_write_byte(st->client, MS5611_RESET); } -static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word) +static int ms5611_i2c_read_prom_word(struct ms5611_state *st, int index, + u16 *word) { int ret; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); ret = i2c_smbus_read_word_swapped(st->client, MS5611_READ_PROM_WORD + (index << 1)); @@ -55,11 +53,10 @@ return 0; } -static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev, +static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st, s32 *temp, s32 *pressure) { int ret; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); const struct ms5611_osr *osr = st->temp_osr; ret = i2c_smbus_write_byte(st->client, osr->cmd); --- linux-oracle-5.4.0.orig/drivers/iio/pressure/ms5611_spi.c +++ linux-oracle-5.4.0/drivers/iio/pressure/ms5611_spi.c @@ -13,18 +13,17 @@ #include "ms5611.h" -static int ms5611_spi_reset(struct device *dev) +static int ms5611_spi_reset(struct ms5611_state *st) { u8 cmd = MS5611_RESET; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); return spi_write_then_read(st->client, &cmd, 1, NULL, 0); } -static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word) +static int ms5611_spi_read_prom_word(struct ms5611_state *st, int index, + u16 *word) { int ret; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1)); if (ret < 0) @@ -35,11 +34,10 @@ return 0; } -static int ms5611_spi_read_adc(struct device *dev, s32 *val) +static int ms5611_spi_read_adc(struct ms5611_state *st, s32 *val) { int ret; u8 buf[3] = { MS5611_READ_ADC }; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); ret = spi_write_then_read(st->client, buf, 1, buf, 3); if (ret < 0) @@ -50,11 +48,10 @@ return 0; } -static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, +static int ms5611_spi_read_adc_temp_and_pressure(struct ms5611_state *st, s32 *temp, s32 *pressure) { int ret; - struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); const struct ms5611_osr *osr = st->temp_osr; /* @@ -66,7 +63,7 @@ return ret; usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); - ret = ms5611_spi_read_adc(dev, temp); + ret = ms5611_spi_read_adc(st, temp); if (ret < 0) return ret; @@ -76,7 +73,7 @@ return ret; usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); - return ms5611_spi_read_adc(dev, pressure); + return ms5611_spi_read_adc(st, pressure); } static int ms5611_spi_probe(struct spi_device *spi) @@ -92,7 +89,7 @@ spi_set_drvdata(spi, indio_dev); spi->mode = SPI_MODE_0; - spi->max_speed_hz = 20000000; + spi->max_speed_hz = min(spi->max_speed_hz, 20000000U); spi->bits_per_word = 8; ret = spi_setup(spi); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/iio/pressure/zpa2326.c +++ linux-oracle-5.4.0/drivers/iio/pressure/zpa2326.c @@ -585,6 +585,8 @@ } sample; int err; + memset(&sample, 0, sizeof(sample)); + if (test_bit(0, indio_dev->active_scan_mask)) { /* Get current pressure from hardware FIFO. */ err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure); @@ -664,8 +666,10 @@ int err; err = pm_runtime_get_sync(indio_dev->dev.parent); - if (err < 0) + if (err < 0) { + pm_runtime_put(indio_dev->dev.parent); return err; + } if (err > 0) { /* --- linux-oracle-5.4.0.orig/drivers/iio/proximity/Kconfig +++ linux-oracle-5.4.0/drivers/iio/proximity/Kconfig @@ -49,6 +49,8 @@ config MB1232 tristate "MaxSonar I2CXL family ultrasonic sensors" depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER help Say Y to build a driver for the ultrasonic sensors I2CXL of MaxBotix which have an i2c interface. It can be used to measure --- linux-oracle-5.4.0.orig/drivers/iio/proximity/as3935.c +++ linux-oracle-5.4.0/drivers/iio/proximity/as3935.c @@ -61,7 +61,11 @@ unsigned long noise_tripped; u32 tune_cap; u32 nflwdth_reg; - u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u8 chan; + s64 timestamp __aligned(8); + } scan; u8 buf[2] ____cacheline_aligned; }; @@ -227,8 +231,8 @@ if (ret) goto err_read; - st->buffer[0] = val & AS3935_DATA_MASK; - iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, + st->scan.chan = val & AS3935_DATA_MASK; + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, iio_get_time_ns(indio_dev)); err_read: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/proximity/isl29501.c +++ linux-oracle-5.4.0/drivers/iio/proximity/isl29501.c @@ -938,7 +938,7 @@ struct iio_dev *indio_dev = pf->indio_dev; struct isl29501_private *isl29501 = iio_priv(indio_dev); const unsigned long *active_mask = indio_dev->active_scan_mask; - u32 buffer[4] = {}; /* 1x16-bit + ts */ + u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) isl29501_register_read(isl29501, REG_DISTANCE, buffer); --- linux-oracle-5.4.0.orig/drivers/iio/proximity/mb1232.c +++ linux-oracle-5.4.0/drivers/iio/proximity/mb1232.c @@ -40,6 +40,11 @@ */ struct completion ranging; int irqnr; + /* Ensure correct alignment of data to push to IIO buffer */ + struct { + s16 distance; + s64 ts __aligned(8); + } scan; }; static irqreturn_t mb1232_handle_irq(int irq, void *dev_id) @@ -113,17 +118,13 @@ struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct mb1232_data *data = iio_priv(indio_dev); - /* - * triggered buffer - * 16-bit channel + 48-bit padding + 64-bit timestamp - */ - s16 buffer[8] = { 0 }; - buffer[0] = mb1232_read_distance(data); - if (buffer[0] < 0) + data->scan.distance = mb1232_read_distance(data); + if (data->scan.distance < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, buffer, pf->timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, + pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); --- linux-oracle-5.4.0.orig/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ linux-oracle-5.4.0/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -43,7 +43,11 @@ int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); int i2c_enabled; - u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const struct iio_chan_spec lidar_channels[] = { @@ -158,6 +162,7 @@ ret = lidar_write_control(data, LIDAR_REG_CONTROL_ACQUIRE); if (ret < 0) { dev_err(&client->dev, "cannot send start measurement command"); + pm_runtime_put_noidle(&client->dev); return ret; } @@ -227,9 +232,9 @@ struct lidar_data *data = iio_priv(indio_dev); int ret; - ret = lidar_get_measurement(data, data->buffer); + ret = lidar_get_measurement(data, &data->scan.chan); if (!ret) { - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); } else if (ret != -EINVAL) { dev_err(&data->client->dev, "cannot read LIDAR measurement"); --- linux-oracle-5.4.0.orig/drivers/iio/proximity/srf08.c +++ linux-oracle-5.4.0/drivers/iio/proximity/srf08.c @@ -63,11 +63,11 @@ int range_mm; struct mutex lock; - /* - * triggered buffer - * 1x16-bit channel + 3x16 padding + 4x16 timestamp - */ - s16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + s16 chan; + s64 timestamp __aligned(8); + } scan; /* Sensor-Type */ enum srf08_sensor_type sensor_type; @@ -190,9 +190,9 @@ mutex_lock(&data->lock); - data->buffer[0] = sensor_data; + data->scan.chan = sensor_data; iio_push_to_buffers_with_timestamp(indio_dev, - data->buffer, pf->timestamp); + &data->scan, pf->timestamp); mutex_unlock(&data->lock); err: --- linux-oracle-5.4.0.orig/drivers/iio/temperature/hid-sensor-temperature.c +++ linux-oracle-5.4.0/drivers/iio/temperature/hid-sensor-temperature.c @@ -17,7 +17,10 @@ struct temperature_state { struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info temperature_attr; - s32 temperature_data; + struct { + s32 temperature_data; + u64 timestamp __aligned(8); + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -34,7 +37,7 @@ BIT(IIO_CHAN_INFO_SAMP_FREQ) | BIT(IIO_CHAN_INFO_HYSTERESIS), }, - IIO_CHAN_SOFT_TIMESTAMP(3), + IIO_CHAN_SOFT_TIMESTAMP(1), }; /* Adjust channel real bits based on report descriptor */ @@ -125,9 +128,8 @@ struct temperature_state *temp_st = iio_priv(indio_dev); if (atomic_read(&temp_st->common_attributes.data_ready)) - iio_push_to_buffers_with_timestamp(indio_dev, - &temp_st->temperature_data, - iio_get_time_ns(indio_dev)); + iio_push_to_buffers_with_timestamp(indio_dev, &temp_st->scan, + iio_get_time_ns(indio_dev)); return 0; } @@ -142,7 +144,7 @@ switch (usage_id) { case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE: - temp_st->temperature_data = *(s32 *)raw_data; + temp_st->scan.temperature_data = *(s32 *)raw_data; return 0; default: return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/iio/temperature/max31856.c +++ linux-oracle-5.4.0/drivers/iio/temperature/max31856.c @@ -284,6 +284,8 @@ spi_set_drvdata(spi, indio_dev); indio_dev->info = &max31856_info; + indio_dev->dev.parent = &spi->dev; + indio_dev->dev.of_node = spi->dev.of_node; indio_dev->name = id->name; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = max31856_channels; --- linux-oracle-5.4.0.orig/drivers/iio/trigger/iio-trig-hrtimer.c +++ linux-oracle-5.4.0/drivers/iio/trigger/iio-trig-hrtimer.c @@ -102,7 +102,7 @@ if (state) hrtimer_start(&trig_info->timer, trig_info->period, - HRTIMER_MODE_REL); + HRTIMER_MODE_REL_HARD); else hrtimer_cancel(&trig_info->timer); @@ -132,7 +132,7 @@ trig_info->swt.trigger->ops = &iio_hrtimer_trigger_ops; trig_info->swt.trigger->dev.groups = iio_hrtimer_attr_groups; - hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&trig_info->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); trig_info->timer.function = iio_hrtimer_trig_handler; trig_info->sampling_frequency = HRTIMER_DEFAULT_SAMPLING_FREQUENCY; --- linux-oracle-5.4.0.orig/drivers/iio/trigger/iio-trig-sysfs.c +++ linux-oracle-5.4.0/drivers/iio/trigger/iio-trig-sysfs.c @@ -196,6 +196,7 @@ } iio_trigger_unregister(t->trig); + irq_work_sync(&t->work); iio_trigger_free(t->trig); list_del(&t->l); @@ -208,9 +209,13 @@ static int __init iio_sysfs_trig_init(void) { + int ret; device_initialize(&iio_sysfs_trig_dev); dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger"); - return device_add(&iio_sysfs_trig_dev); + ret = device_add(&iio_sysfs_trig_dev); + if (ret) + put_device(&iio_sysfs_trig_dev); + return ret; } module_init(iio_sysfs_trig_init); --- linux-oracle-5.4.0.orig/drivers/iio/trigger/stm32-timer-trigger.c +++ linux-oracle-5.4.0/drivers/iio/trigger/stm32-timer-trigger.c @@ -161,7 +161,8 @@ return 0; } -static void stm32_timer_stop(struct stm32_timer_trigger *priv) +static void stm32_timer_stop(struct stm32_timer_trigger *priv, + struct iio_trigger *trig) { u32 ccer, cr1; @@ -179,6 +180,12 @@ regmap_write(priv->regmap, TIM_PSC, 0); regmap_write(priv->regmap, TIM_ARR, 0); + /* Force disable master mode */ + if (stm32_timer_is_trgo2_name(trig->name)) + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0); + else + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0); + /* Make sure that registers are updated */ regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); } @@ -197,7 +204,7 @@ return ret; if (freq == 0) { - stm32_timer_stop(priv); + stm32_timer_stop(priv, trig); } else { ret = stm32_timer_start(priv, trig, freq); if (ret) @@ -793,6 +800,6 @@ }; module_platform_driver(stm32_timer_trigger_driver); -MODULE_ALIAS("platform: stm32-timer-trigger"); +MODULE_ALIAS("platform:stm32-timer-trigger"); MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/infiniband/Kconfig +++ linux-oracle-5.4.0/drivers/infiniband/Kconfig @@ -80,6 +80,9 @@ This allows the user to config the default GID type that the CM uses for each device, when initiaing new connections. +config INFINIBAND_VIRT_DMA + def_bool !HIGHMEM + if INFINIBAND_USER_ACCESS || !INFINIBAND_USER_ACCESS source "drivers/infiniband/hw/mthca/Kconfig" source "drivers/infiniband/hw/qib/Kconfig" --- linux-oracle-5.4.0.orig/drivers/infiniband/core/Makefile +++ linux-oracle-5.4.0/drivers/infiniband/core/Makefile @@ -11,7 +11,7 @@ device.o fmr_pool.o cache.o netlink.o \ roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \ multicast.o mad.o smi.o agent.o mad_rmpp.o \ - nldev.o restrack.o counters.o + nldev.o restrack.o counters.o ib_core_uverbs.o ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o @@ -34,5 +34,5 @@ uverbs_std_types_flow_action.o uverbs_std_types_dm.o \ uverbs_std_types_mr.o uverbs_std_types_counters.o \ uverbs_uapi.o uverbs_std_types_device.o -ib_uverbs-$(CONFIG_INFINIBAND_USER_MEM) += umem.o +ib_uverbs-$(CONFIG_INFINIBAND_USER_MEM) += umem.o peer_mem.o ib_uverbs-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o --- linux-oracle-5.4.0.orig/drivers/infiniband/core/addr.c +++ linux-oracle-5.4.0/drivers/infiniband/core/addr.c @@ -76,7 +76,9 @@ static const struct nla_policy ib_nl_addr_policy[LS_NLA_TYPE_MAX] = { [LS_NLA_TYPE_DGID] = {.type = NLA_BINARY, - .len = sizeof(struct rdma_nla_ls_gid)}, + .len = sizeof(struct rdma_nla_ls_gid), + .validation_type = NLA_VALIDATE_MIN, + .min = sizeof(struct rdma_nla_ls_gid)}, }; static inline bool ib_nl_is_good_ip_resp(const struct nlmsghdr *nlh) @@ -139,7 +141,7 @@ if (ib_nl_is_good_ip_resp(nlh)) ib_nl_process_good_ip_rsep(nlh); - return skb->len; + return 0; } static int ib_nl_ip_send_msg(struct rdma_dev_addr *dev_addr, @@ -421,16 +423,15 @@ (const struct sockaddr_in6 *)dst_sock; struct flowi6 fl6; struct dst_entry *dst; - int ret; memset(&fl6, 0, sizeof fl6); fl6.daddr = dst_in->sin6_addr; fl6.saddr = src_in->sin6_addr; fl6.flowi6_oif = addr->bound_dev_if; - ret = ipv6_stub->ipv6_dst_lookup(addr->net, NULL, &dst, &fl6); - if (ret < 0) - return ret; + dst = ipv6_stub->ipv6_dst_lookup_flow(addr->net, NULL, &fl6, NULL); + if (IS_ERR(dst)) + return PTR_ERR(dst); if (ipv6_addr_any(&src_in->sin6_addr)) src_in->sin6_addr = fl6.saddr; @@ -646,13 +647,12 @@ req->callback = NULL; spin_lock_bh(&lock); + /* + * Although the work will normally have been canceled by the workqueue, + * it can still be requeued as long as it is on the req_list. + */ + cancel_delayed_work(&req->work); if (!list_empty(&req->list)) { - /* - * Although the work will normally have been canceled by the - * workqueue, it can still be requeued as long as it is on the - * req_list. - */ - cancel_delayed_work(&req->work); list_del_init(&req->list); kfree(req); } --- linux-oracle-5.4.0.orig/drivers/infiniband/core/cache.c +++ linux-oracle-5.4.0/drivers/infiniband/core/cache.c @@ -51,9 +51,8 @@ struct ib_update_work { struct work_struct work; - struct ib_device *device; - u8 port_num; - bool enforce_security; + struct ib_event event; + bool enforce_security; }; union ib_gid zgid; @@ -130,7 +129,7 @@ event.element.port_num = port; event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&event); + ib_dispatch_event_clients(&event); } static const char * const gid_type_str[] = { @@ -1387,9 +1386,8 @@ return ret; } -static void ib_cache_update(struct ib_device *device, - u8 port, - bool enforce_security) +static int +ib_cache_update(struct ib_device *device, u8 port, bool enforce_security) { struct ib_port_attr *tprops = NULL; struct ib_pkey_cache *pkey_cache = NULL, *old_pkey_cache; @@ -1397,11 +1395,11 @@ int ret; if (!rdma_is_port_valid(device, port)) - return; + return -EINVAL; tprops = kmalloc(sizeof *tprops, GFP_KERNEL); if (!tprops) - return; + return -ENOMEM; ret = ib_query_port(device, port, tprops); if (ret) { @@ -1419,8 +1417,10 @@ pkey_cache = kmalloc(struct_size(pkey_cache, table, tprops->pkey_tbl_len), GFP_KERNEL); - if (!pkey_cache) + if (!pkey_cache) { + ret = -ENOMEM; goto err; + } pkey_cache->table_len = tprops->pkey_tbl_len; @@ -1452,50 +1452,84 @@ kfree(old_pkey_cache); kfree(tprops); - return; + return 0; err: kfree(pkey_cache); kfree(tprops); + return ret; } -static void ib_cache_task(struct work_struct *_work) +static void ib_cache_event_task(struct work_struct *_work) { struct ib_update_work *work = container_of(_work, struct ib_update_work, work); + int ret; + + /* Before distributing the cache update event, first sync + * the cache. + */ + ret = ib_cache_update(work->event.device, work->event.element.port_num, + work->enforce_security); + + /* GID event is notified already for individual GID entries by + * dispatch_gid_change_event(). Hence, notifiy for rest of the + * events. + */ + if (!ret && work->event.event != IB_EVENT_GID_CHANGE) + ib_dispatch_event_clients(&work->event); - ib_cache_update(work->device, - work->port_num, - work->enforce_security); kfree(work); } -static void ib_cache_event(struct ib_event_handler *handler, - struct ib_event *event) +static void ib_generic_event_task(struct work_struct *_work) +{ + struct ib_update_work *work = + container_of(_work, struct ib_update_work, work); + + ib_dispatch_event_clients(&work->event); + kfree(work); +} + +static bool is_cache_update_event(const struct ib_event *event) +{ + return (event->event == IB_EVENT_PORT_ERR || + event->event == IB_EVENT_PORT_ACTIVE || + event->event == IB_EVENT_LID_CHANGE || + event->event == IB_EVENT_PKEY_CHANGE || + event->event == IB_EVENT_CLIENT_REREGISTER || + event->event == IB_EVENT_GID_CHANGE); +} + +/** + * ib_dispatch_event - Dispatch an asynchronous event + * @event:Event to dispatch + * + * Low-level drivers must call ib_dispatch_event() to dispatch the + * event to all registered event handlers when an asynchronous event + * occurs. + */ +void ib_dispatch_event(const struct ib_event *event) { struct ib_update_work *work; - if (event->event == IB_EVENT_PORT_ERR || - event->event == IB_EVENT_PORT_ACTIVE || - event->event == IB_EVENT_LID_CHANGE || - event->event == IB_EVENT_PKEY_CHANGE || - event->event == IB_EVENT_CLIENT_REREGISTER || - event->event == IB_EVENT_GID_CHANGE) { - work = kmalloc(sizeof *work, GFP_ATOMIC); - if (work) { - INIT_WORK(&work->work, ib_cache_task); - work->device = event->device; - work->port_num = event->element.port_num; - if (event->event == IB_EVENT_PKEY_CHANGE || - event->event == IB_EVENT_GID_CHANGE) - work->enforce_security = true; - else - work->enforce_security = false; + work = kzalloc(sizeof(*work), GFP_ATOMIC); + if (!work) + return; - queue_work(ib_wq, &work->work); - } - } + if (is_cache_update_event(event)) + INIT_WORK(&work->work, ib_cache_event_task); + else + INIT_WORK(&work->work, ib_generic_event_task); + + work->event = *event; + if (event->event == IB_EVENT_PKEY_CHANGE || + event->event == IB_EVENT_GID_CHANGE) + work->enforce_security = true; + + queue_work(ib_wq, &work->work); } +EXPORT_SYMBOL(ib_dispatch_event); int ib_cache_setup_one(struct ib_device *device) { @@ -1508,12 +1542,12 @@ if (err) return err; - rdma_for_each_port (device, p) - ib_cache_update(device, p, true); + rdma_for_each_port (device, p) { + err = ib_cache_update(device, p, true); + if (err) + return err; + } - INIT_IB_EVENT_HANDLER(&device->cache.event_handler, - device, ib_cache_event); - ib_register_event_handler(&device->cache.event_handler); return 0; } @@ -1535,14 +1569,12 @@ void ib_cache_cleanup_one(struct ib_device *device) { - /* The cleanup function unregisters the event handler, - * waits for all in-progress workqueue elements and cleans - * up the GID cache. This function should be called after - * the device was removed from the devices list and all - * clients were removed, so the cache exists but is + /* The cleanup function waits for all in-progress workqueue + * elements and cleans up the GID cache. This function should be + * called after the device was removed from the devices list and + * all clients were removed, so the cache exists but is * non-functional and shouldn't be updated anymore. */ - ib_unregister_event_handler(&device->cache.event_handler); flush_workqueue(ib_wq); gid_table_cleanup_one(device); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/cm.c +++ linux-oracle-5.4.0/drivers/infiniband/core/cm.c @@ -597,18 +597,6 @@ return 0; } -static int cm_alloc_id(struct cm_id_private *cm_id_priv) -{ - int err; - u32 id; - - err = xa_alloc_cyclic_irq(&cm.local_id_table, &id, cm_id_priv, - xa_limit_32b, &cm.local_id_next, GFP_KERNEL); - - cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; - return err; -} - static u32 cm_local_id(__be32 local_id) { return (__force u32) (local_id ^ cm.random_id_operand); @@ -862,6 +850,7 @@ void *context) { struct cm_id_private *cm_id_priv; + u32 id; int ret; cm_id_priv = kzalloc(sizeof *cm_id_priv, GFP_KERNEL); @@ -873,9 +862,6 @@ cm_id_priv->id.cm_handler = cm_handler; cm_id_priv->id.context = context; cm_id_priv->id.remote_cm_qpn = 1; - ret = cm_alloc_id(cm_id_priv); - if (ret) - goto error; spin_lock_init(&cm_id_priv->lock); init_completion(&cm_id_priv->comp); @@ -884,11 +870,20 @@ INIT_LIST_HEAD(&cm_id_priv->altr_list); atomic_set(&cm_id_priv->work_count, -1); atomic_set(&cm_id_priv->refcount, 1); + + ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b, + &cm.local_id_next, GFP_KERNEL); + if (ret < 0) + goto error; + cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; + xa_store_irq(&cm.local_id_table, cm_local_id(cm_id_priv->id.local_id), + cm_id_priv, GFP_KERNEL); + return &cm_id_priv->id; error: kfree(cm_id_priv); - return ERR_PTR(-ENOMEM); + return ERR_PTR(ret); } EXPORT_SYMBOL(ib_create_cm_id); @@ -1097,14 +1092,22 @@ break; } - spin_lock_irq(&cm.lock); + spin_lock_irq(&cm_id_priv->lock); + spin_lock(&cm.lock); + /* Required for cleanup paths related cm_req_handler() */ + if (cm_id_priv->timewait_info) { + cm_cleanup_timewait(cm_id_priv->timewait_info); + kfree(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; + } if (!list_empty(&cm_id_priv->altr_list) && (!cm_id_priv->altr_send_port_not_ready)) list_del(&cm_id_priv->altr_list); if (!list_empty(&cm_id_priv->prim_list) && (!cm_id_priv->prim_send_port_not_ready)) list_del(&cm_id_priv->prim_list); - spin_unlock_irq(&cm.lock); + spin_unlock(&cm.lock); + spin_unlock_irq(&cm_id_priv->lock); cm_free_id(cm_id->local_id); cm_deref_id(cm_id_priv); @@ -1228,6 +1231,7 @@ /* Sharing an ib_cm_id with different handlers is not * supported */ spin_unlock_irqrestore(&cm.lock, flags); + ib_destroy_cm_id(cm_id); return ERR_PTR(-EINVAL); } atomic_inc(&cm_id_priv->refcount); @@ -1420,7 +1424,7 @@ /* Verify that we're not in timewait. */ cm_id_priv = container_of(cm_id, struct cm_id_private, id); spin_lock_irqsave(&cm_id_priv->lock, flags); - if (cm_id->state != IB_CM_IDLE) { + if (cm_id->state != IB_CM_IDLE || WARN_ON(cm_id_priv->timewait_info)) { spin_unlock_irqrestore(&cm_id_priv->lock, flags); ret = -EINVAL; goto out; @@ -1431,6 +1435,7 @@ id.local_id); if (IS_ERR(cm_id_priv->timewait_info)) { ret = PTR_ERR(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; goto out; } @@ -1438,12 +1443,12 @@ param->ppath_sgid_attr, &cm_id_priv->av, cm_id_priv); if (ret) - goto error1; + goto out; if (param->alternate_path) { ret = cm_init_av_by_path(param->alternate_path, NULL, &cm_id_priv->alt_av, cm_id_priv); if (ret) - goto error1; + goto out; } cm_id->service_id = param->service_id; cm_id->service_mask = ~cpu_to_be64(0); @@ -1461,7 +1466,7 @@ ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); if (ret) - goto error1; + goto out; req_msg = (struct cm_req_msg *) cm_id_priv->msg->mad; cm_format_req(req_msg, cm_id_priv, param); @@ -1484,7 +1489,6 @@ return 0; error2: cm_free_msg(cm_id_priv->msg); -error1: kfree(cm_id_priv->timewait_info); out: return ret; } EXPORT_SYMBOL(ib_send_cm_req); @@ -1958,6 +1962,7 @@ id.local_id); if (IS_ERR(cm_id_priv->timewait_info)) { ret = PTR_ERR(cm_id_priv->timewait_info); + cm_id_priv->timewait_info = NULL; goto destroy; } cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id; @@ -1969,7 +1974,7 @@ pr_debug("%s: local_id %d, no listen_cm_id_priv\n", __func__, be32_to_cpu(cm_id->local_id)); ret = -EINVAL; - goto free_timeinfo; + goto destroy; } cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; @@ -2054,8 +2059,6 @@ rejected: atomic_dec(&cm_id_priv->refcount); cm_deref_id(listen_cm_id_priv); -free_timeinfo: - kfree(cm_id_priv->timewait_info); destroy: ib_destroy_cm_id(cm_id); return ret; @@ -4333,7 +4336,7 @@ unsigned long flags; int ret; int count = 0; - u8 i; + unsigned int i; cm_dev = kzalloc(struct_size(cm_dev, port, ib_device->phys_port_cnt), GFP_KERNEL); @@ -4345,7 +4348,7 @@ cm_dev->going_down = 0; set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); - for (i = 1; i <= ib_device->phys_port_cnt; i++) { + rdma_for_each_port (ib_device, i) { if (!rdma_cap_ib_cm(ib_device, i)) continue; @@ -4424,7 +4427,7 @@ .clr_port_cap_mask = IB_PORT_CM_SUP }; unsigned long flags; - int i; + unsigned int i; if (!cm_dev) return; @@ -4437,7 +4440,7 @@ cm_dev->going_down = 1; spin_unlock_irq(&cm.lock); - for (i = 1; i <= ib_device->phys_port_cnt; i++) { + rdma_for_each_port (ib_device, i) { if (!rdma_cap_ib_cm(ib_device, i)) continue; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/cma.c +++ linux-oracle-5.4.0/drivers/infiniband/core/cma.c @@ -530,6 +530,11 @@ list_del(&id_priv->list); cma_deref_dev(id_priv->cma_dev); id_priv->cma_dev = NULL; + id_priv->id.device = NULL; + if (id_priv->id.route.addr.dev_addr.sgid_attr) { + rdma_put_gid_attr(id_priv->id.route.addr.dev_addr.sgid_attr); + id_priv->id.route.addr.dev_addr.sgid_attr = NULL; + } mutex_unlock(&lock); } @@ -815,6 +820,7 @@ u16 pkey, index; u8 p; enum ib_port_state port_state; + int ret; int i; cma_dev = NULL; @@ -833,9 +839,14 @@ if (ib_get_cached_port_state(cur_dev->device, p, &port_state)) continue; - for (i = 0; !rdma_query_gid(cur_dev->device, - p, i, &gid); - i++) { + + for (i = 0; i < cur_dev->device->port_data[p].immutable.gid_tbl_len; + ++i) { + ret = rdma_query_gid(cur_dev->device, p, i, + &gid); + if (ret) + continue; + if (!memcmp(&gid, dgid, sizeof(gid))) { cma_dev = cur_dev; sgid = gid; @@ -1423,7 +1434,7 @@ return false; memset(&fl4, 0, sizeof(fl4)); - fl4.flowi4_iif = net_dev->ifindex; + fl4.flowi4_oif = net_dev->ifindex; fl4.daddr = daddr; fl4.saddr = saddr; @@ -1631,6 +1642,8 @@ { struct rdma_id_private *id_priv, *id_priv_dev; + lockdep_assert_held(&lock); + if (!bind_list) return ERR_PTR(-EINVAL); @@ -1677,6 +1690,7 @@ } } + mutex_lock(&lock); /* * Net namespace might be getting deleted while route lookup, * cm_id lookup is in progress. Therefore, perform netdevice @@ -1705,8 +1719,8 @@ } if (!validate_net_dev(*net_dev, - (struct sockaddr *)&req->listen_addr_storage, - (struct sockaddr *)&req->src_addr_storage)) { + (struct sockaddr *)&req->src_addr_storage, + (struct sockaddr *)&req->listen_addr_storage)) { id_priv = ERR_PTR(-EHOSTUNREACH); goto err; } @@ -1718,6 +1732,7 @@ id_priv = cma_find_listener(bind_list, cm_id, ib_event, req, *net_dev); err: rcu_read_unlock(); + mutex_unlock(&lock); if (IS_ERR(id_priv) && *net_dev) { dev_put(*net_dev); *net_dev = NULL; @@ -1799,19 +1814,30 @@ mutex_unlock(&lock); } -static void cma_leave_roce_mc_group(struct rdma_id_private *id_priv, - struct cma_multicast *mc) +static void destroy_mc(struct rdma_id_private *id_priv, + struct cma_multicast *mc) { - struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; - struct net_device *ndev = NULL; + if (rdma_cap_ib_mcast(id_priv->id.device, id_priv->id.port_num)) { + ib_sa_free_multicast(mc->multicast.ib); + kfree(mc); + return; + } - if (dev_addr->bound_dev_if) - ndev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if); - if (ndev) { - cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid, false); - dev_put(ndev); + if (rdma_protocol_roce(id_priv->id.device, + id_priv->id.port_num)) { + struct rdma_dev_addr *dev_addr = + &id_priv->id.route.addr.dev_addr; + struct net_device *ndev = NULL; + + if (dev_addr->bound_dev_if) + ndev = dev_get_by_index(dev_addr->net, + dev_addr->bound_dev_if); + if (ndev) { + cma_igmp_send(ndev, &mc->multicast.ib->rec.mgid, false); + dev_put(ndev); + } + kref_put(&mc->mcref, release_mc); } - kref_put(&mc->mcref, release_mc); } static void cma_leave_mc_groups(struct rdma_id_private *id_priv) @@ -1819,16 +1845,10 @@ struct cma_multicast *mc; while (!list_empty(&id_priv->mc_list)) { - mc = container_of(id_priv->mc_list.next, - struct cma_multicast, list); + mc = list_first_entry(&id_priv->mc_list, struct cma_multicast, + list); list_del(&mc->list); - if (rdma_cap_ib_mcast(id_priv->cma_dev->device, - id_priv->id.port_num)) { - ib_sa_free_multicast(mc->multicast.ib); - kfree(mc); - } else { - cma_leave_roce_mc_group(id_priv, mc); - } + destroy_mc(id_priv, mc); } } @@ -1858,6 +1878,7 @@ iw_destroy_cm_id(id_priv->cm_id.iw); } cma_leave_mc_groups(id_priv); + rdma_restrack_del(&id_priv->res); cma_release_dev(id_priv); } @@ -1870,9 +1891,6 @@ kfree(id_priv->id.route.path_rec); - if (id_priv->id.route.addr.dev_addr.sgid_attr) - rdma_put_gid_attr(id_priv->id.route.addr.dev_addr.sgid_attr); - put_net(id_priv->id.route.addr.dev_addr.net); kfree(id_priv); } @@ -2473,6 +2491,8 @@ struct net *net = id_priv->id.route.addr.dev_addr.net; int ret; + lockdep_assert_held(&lock); + if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1)) return; @@ -2539,7 +2559,7 @@ { struct rdma_id_private *id_priv; - if (id->qp_type != IB_QPT_RC) + if (id->qp_type != IB_QPT_RC && id->qp_type != IB_QPT_XRC_INI) return -EINVAL; id_priv = container_of(id, struct rdma_id_private, id); @@ -2705,7 +2725,8 @@ cma_init_resolve_route_work(work, id_priv); - route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); + if (!route->path_rec) + route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); if (!route->path_rec) { ret = -ENOMEM; goto err1; @@ -2911,6 +2932,7 @@ err2: kfree(route->path_rec); route->path_rec = NULL; + route->num_paths = 0; err1: kfree(work); return ret; @@ -3091,6 +3113,7 @@ rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); + atomic_inc(&id_priv->refcount); cma_init_resolve_addr_work(work, id_priv); queue_work(cma_wq, &work->work); return 0; @@ -3117,6 +3140,7 @@ rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, (union ib_gid *) &(((struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr)->sib_addr)); + atomic_inc(&id_priv->refcount); cma_init_resolve_addr_work(work, id_priv); queue_work(cma_wq, &work->work); return 0; @@ -3153,19 +3177,26 @@ int ret; id_priv = container_of(id, struct rdma_id_private, id); + memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); if (id_priv->state == RDMA_CM_IDLE) { ret = cma_bind_addr(id, src_addr, dst_addr); - if (ret) + if (ret) { + memset(cma_dst_addr(id_priv), 0, + rdma_addr_size(dst_addr)); return ret; + } } - if (cma_family(id_priv) != dst_addr->sa_family) + if (cma_family(id_priv) != dst_addr->sa_family) { + memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); return -EINVAL; + } - if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) + if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { + memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); return -EINVAL; + } - memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); if (cma_any_addr(dst_addr)) { ret = cma_resolve_loopback(id_priv); } else { @@ -3235,6 +3266,8 @@ u64 sid, mask; __be16 port; + lockdep_assert_held(&lock); + addr = cma_src_addr(id_priv); port = htons(bind_list->port); @@ -3263,6 +3296,8 @@ struct rdma_bind_list *bind_list; int ret; + lockdep_assert_held(&lock); + bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); if (!bind_list) return -ENOMEM; @@ -3289,6 +3324,8 @@ struct sockaddr *saddr = cma_src_addr(id_priv); __be16 dport = cma_port(daddr); + lockdep_assert_held(&lock); + hlist_for_each_entry(cur_id, &bind_list->owners, node) { struct sockaddr *cur_daddr = cma_dst_addr(cur_id); struct sockaddr *cur_saddr = cma_src_addr(cur_id); @@ -3328,6 +3365,8 @@ unsigned int rover; struct net *net = id_priv->id.route.addr.dev_addr.net; + lockdep_assert_held(&lock); + inet_get_local_port_range(net, &low, &high); remaining = (high - low) + 1; rover = prandom_u32() % remaining + low; @@ -3375,6 +3414,8 @@ struct rdma_id_private *cur_id; struct sockaddr *addr, *cur_addr; + lockdep_assert_held(&lock); + addr = cma_src_addr(id_priv); hlist_for_each_entry(cur_id, &bind_list->owners, node) { if (id_priv == cur_id) @@ -3405,6 +3446,8 @@ unsigned short snum; int ret; + lockdep_assert_held(&lock); + snum = ntohs(cma_port(cma_src_addr(id_priv))); if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) return -EACCES; @@ -3546,7 +3589,7 @@ } id_priv->backlog = backlog; - if (id->device) { + if (id_priv->cma_dev) { if (rdma_cap_ib_cm(id->device, 1)) { ret = cma_ib_listen(id_priv); if (ret) @@ -4014,14 +4057,15 @@ int __rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param, const char *caller) { - struct rdma_id_private *id_priv; + struct rdma_id_private *id_priv = + container_of(id, struct rdma_id_private, id); int ret; - id_priv = container_of(id, struct rdma_id_private, id); + lockdep_assert_held(&id_priv->handler_mutex); rdma_restrack_set_task(&id_priv->res, caller); - if (!cma_comp(id_priv, RDMA_CM_CONNECT)) + if (READ_ONCE(id_priv->state) != RDMA_CM_CONNECT) return -EINVAL; if (!id->qp && conn_param) { @@ -4061,6 +4105,24 @@ } EXPORT_SYMBOL(__rdma_accept); +void rdma_lock_handler(struct rdma_cm_id *id) +{ + struct rdma_id_private *id_priv = + container_of(id, struct rdma_id_private, id); + + mutex_lock(&id_priv->handler_mutex); +} +EXPORT_SYMBOL(rdma_lock_handler); + +void rdma_unlock_handler(struct rdma_cm_id *id) +{ + struct rdma_id_private *id_priv = + container_of(id, struct rdma_id_private, id); + + mutex_unlock(&id_priv->handler_mutex); +} +EXPORT_SYMBOL(rdma_unlock_handler); + int rdma_notify(struct rdma_cm_id *id, enum ib_event_type event) { struct rdma_id_private *id_priv; @@ -4154,16 +4216,6 @@ else pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to join multicast. status %d\n", status); - mutex_lock(&id_priv->qp_mutex); - if (!status && id_priv->id.qp) { - status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid, - be16_to_cpu(multicast->rec.mlid)); - if (status) - pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to attach QP. status %d\n", - status); - } - mutex_unlock(&id_priv->qp_mutex); - event.status = status; event.param.ud.private_data = mc->context; if (!status) { @@ -4418,6 +4470,10 @@ struct cma_multicast *mc; int ret; + /* Not supported for kernel QPs */ + if (WARN_ON(id->qp)) + return -EINVAL; + if (!id->device) return -EINVAL; @@ -4468,25 +4524,14 @@ id_priv = container_of(id, struct rdma_id_private, id); spin_lock_irq(&id_priv->lock); list_for_each_entry(mc, &id_priv->mc_list, list) { - if (!memcmp(&mc->addr, addr, rdma_addr_size(addr))) { - list_del(&mc->list); - spin_unlock_irq(&id_priv->lock); - - if (id->qp) - ib_detach_mcast(id->qp, - &mc->multicast.ib->rec.mgid, - be16_to_cpu(mc->multicast.ib->rec.mlid)); - - BUG_ON(id_priv->cma_dev->device != id->device); - - if (rdma_cap_ib_mcast(id->device, id->port_num)) { - ib_sa_free_multicast(mc->multicast.ib); - kfree(mc); - } else if (rdma_protocol_roce(id->device, id->port_num)) { - cma_leave_roce_mc_group(id_priv, mc); - } - return; - } + if (memcmp(&mc->addr, addr, rdma_addr_size(addr)) != 0) + continue; + list_del(&mc->list); + spin_unlock_irq(&id_priv->lock); + + WARN_ON(id_priv->cma_dev->device != id->device); + destroy_mc(id_priv, mc); + return; } spin_unlock_irq(&id_priv->lock); } @@ -4710,6 +4755,19 @@ { int ret; + /* + * There is a rare lock ordering dependency in cma_netdev_callback() + * that only happens when bonding is enabled. Teach lockdep that rtnl + * must never be nested under lock so it can find these without having + * to test with bonding. + */ + if (IS_ENABLED(CONFIG_LOCKDEP)) { + rtnl_lock(); + mutex_lock(&lock); + mutex_unlock(&lock); + rtnl_unlock(); + } + cma_wq = alloc_ordered_workqueue("rdma_cm", WQ_MEM_RECLAIM); if (!cma_wq) return -ENOMEM; @@ -4736,6 +4794,7 @@ err: unregister_netdevice_notifier(&cma_nb); ib_sa_unregister_client(&sa_client); + unregister_pernet_subsys(&cma_pernet_operations); err_wq: destroy_workqueue(cma_wq); return ret; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/cma_configfs.c +++ linux-oracle-5.4.0/drivers/infiniband/core/cma_configfs.c @@ -218,7 +218,7 @@ } for (i = 0; i < ports_num; i++) { - char port_str[10]; + char port_str[11]; ports[i].port_num = i + 1; snprintf(port_str, sizeof(port_str), "%u", i + 1); @@ -322,8 +322,21 @@ return ERR_PTR(err); } +static void drop_cma_dev(struct config_group *cgroup, struct config_item *item) +{ + struct config_group *group = + container_of(item, struct config_group, cg_item); + struct cma_dev_group *cma_dev_group = + container_of(group, struct cma_dev_group, device_group); + + configfs_remove_default_groups(&cma_dev_group->ports_group); + configfs_remove_default_groups(&cma_dev_group->device_group); + config_item_put(item); +} + static struct configfs_group_operations cma_subsys_group_ops = { .make_group = make_cma_dev, + .drop_item = drop_cma_dev, }; static const struct config_item_type cma_subsys_type = { --- linux-oracle-5.4.0.orig/drivers/infiniband/core/core_priv.h +++ linux-oracle-5.4.0/drivers/infiniband/core/core_priv.h @@ -149,6 +149,7 @@ int ib_cache_setup_one(struct ib_device *device); void ib_cache_cleanup_one(struct ib_device *device); void ib_cache_release_one(struct ib_device *device); +void ib_dispatch_event_clients(struct ib_event *event); #ifdef CONFIG_CGROUP_RDMA void ib_device_register_rdmacg(struct ib_device *device); @@ -337,6 +338,21 @@ qp->pd = pd; qp->uobject = uobj; qp->real_qp = qp; + + qp->qp_type = attr->qp_type; + qp->qp_context = attr->qp_context; + qp->rwq_ind_tbl = attr->rwq_ind_tbl; + qp->send_cq = attr->send_cq; + qp->recv_cq = attr->recv_cq; + qp->srq = attr->srq; + qp->rwq_ind_tbl = attr->rwq_ind_tbl; + qp->event_handler = attr->event_handler; + + atomic_set(&qp->usecnt, 0); + spin_lock_init(&qp->mr_lock); + INIT_LIST_HEAD(&qp->rdma_mrs); + INIT_LIST_HEAD(&qp->sig_mrs); + /* * We don't track XRC QPs for now, because they don't have PD * and more importantly they are created internaly by driver, @@ -388,4 +404,15 @@ int rdma_nl_net_init(struct rdma_dev_net *rnet); void rdma_nl_net_exit(struct rdma_dev_net *rnet); + +struct rdma_umap_priv { + struct vm_area_struct *vma; + struct list_head list; + struct rdma_user_mmap_entry *entry; +}; + +void rdma_umap_priv_init(struct rdma_umap_priv *priv, + struct vm_area_struct *vma, + struct rdma_user_mmap_entry *entry); + #endif /* _CORE_PRIV_H */ --- linux-oracle-5.4.0.orig/drivers/infiniband/core/counters.c +++ linux-oracle-5.4.0/drivers/infiniband/core/counters.c @@ -195,7 +195,7 @@ return ret; } -static void counter_history_stat_update(const struct rdma_counter *counter) +static void counter_history_stat_update(struct rdma_counter *counter) { struct ib_device *dev = counter->device; struct rdma_port_counter *port_counter; @@ -205,6 +205,8 @@ if (!port_counter->hstats) return; + rdma_counter_query_stats(counter); + for (i = 0; i < counter->stats->num_counters; i++) port_counter->hstats->value[i] += counter->stats->value[i]; } @@ -282,6 +284,9 @@ struct rdma_counter *counter; int ret; + if (!qp->res.valid || rdma_is_kernel_res(&qp->res)) + return 0; + if (!rdma_is_port_valid(dev, port)) return -EINVAL; @@ -463,10 +468,15 @@ int rdma_counter_bind_qpn(struct ib_device *dev, u8 port, u32 qp_num, u32 counter_id) { + struct rdma_port_counter *port_counter; struct rdma_counter *counter; struct ib_qp *qp; int ret; + port_counter = &dev->port_data[port].port_counter; + if (port_counter->mode.mode == RDMA_COUNTER_MODE_AUTO) + return -EINVAL; + qp = rdma_counter_get_qp(dev, qp_num); if (!qp) return -ENOENT; @@ -477,7 +487,7 @@ goto err; } - if (counter->res.task != qp->res.task) { + if (rdma_is_kernel_res(&counter->res) != rdma_is_kernel_res(&qp->res)) { ret = -EINVAL; goto err_task; } @@ -503,6 +513,7 @@ int rdma_counter_bind_qpn_alloc(struct ib_device *dev, u8 port, u32 qp_num, u32 *counter_id) { + struct rdma_port_counter *port_counter; struct rdma_counter *counter; struct ib_qp *qp; int ret; @@ -510,9 +521,13 @@ if (!rdma_is_port_valid(dev, port)) return -EINVAL; - if (!dev->port_data[port].port_counter.hstats) + port_counter = &dev->port_data[port].port_counter; + if (!port_counter->hstats) return -EOPNOTSUPP; + if (port_counter->mode.mode == RDMA_COUNTER_MODE_AUTO) + return -EINVAL; + qp = rdma_counter_get_qp(dev, qp_num); if (!qp) return -ENOENT; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/device.c +++ linux-oracle-5.4.0/drivers/infiniband/core/device.c @@ -591,6 +591,7 @@ INIT_LIST_HEAD(&device->event_handler_list); spin_lock_init(&device->event_handler_lock); + init_rwsem(&device->event_handler_rwsem); mutex_init(&device->unregistration_lock); /* * client_data needs to be alloc because we don't want our mark to be @@ -898,7 +899,9 @@ cdev->dev.parent = device->dev.parent; rdma_init_coredev(cdev, device, read_pnet(&rnet->net)); cdev->dev.release = compatdev_release; - dev_set_name(&cdev->dev, "%s", dev_name(&device->dev)); + ret = dev_set_name(&cdev->dev, "%s", dev_name(&device->dev)); + if (ret) + goto add_err; ret = device_add(&cdev->dev); if (ret) @@ -1199,9 +1202,21 @@ WARN_ON_ONCE(!parent); device->dma_device = parent; } - /* Setup default max segment size for all IB devices */ - dma_set_max_seg_size(device->dma_device, SZ_2G); + if (!device->dev.dma_parms) { + if (parent) { + /* + * The caller did not provide DMA parameters, so + * 'parent' probably represents a PCI device. The PCI + * core sets the maximum segment size to 64 + * KB. Increase this parameter to 2 GB. + */ + device->dev.dma_parms = parent->dma_parms; + dma_set_max_seg_size(device->dma_device, SZ_2G); + } else { + WARN_ON_ONCE(true); + } + } } /* @@ -1315,6 +1330,10 @@ return ret; } +static void prevent_dealloc_device(struct ib_device *ib_dev) +{ +} + /** * ib_register_device - Register an IB device with IB core * @device:Device to register @@ -1368,9 +1387,6 @@ } ret = enable_device_and_get(device); - dev_set_uevent_suppress(&device->dev, false); - /* Mark for userspace that device is ready */ - kobject_uevent(&device->dev.kobj, KOBJ_ADD); if (ret) { void (*dealloc_fn)(struct ib_device *); @@ -1382,16 +1398,20 @@ * possibility for a parallel unregistration along with this * error flow. Since we have a refcount here we know any * parallel flow is stopped in disable_device and will see the - * NULL pointers, causing the responsibility to + * special dealloc_driver pointer, causing the responsibility to * ib_dealloc_device() to revert back to this thread. */ dealloc_fn = device->ops.dealloc_driver; - device->ops.dealloc_driver = NULL; + device->ops.dealloc_driver = prevent_dealloc_device; ib_device_put(device); __ib_unregister_device(device); device->ops.dealloc_driver = dealloc_fn; + dev_set_uevent_suppress(&device->dev, false); return ret; } + dev_set_uevent_suppress(&device->dev, false); + /* Mark for userspace that device is ready */ + kobject_uevent(&device->dev.kobj, KOBJ_ADD); ib_device_put(device); return 0; @@ -1434,7 +1454,8 @@ * Drivers using the new flow may not call ib_dealloc_device except * in error unwind prior to registration success. */ - if (ib_dev->ops.dealloc_driver) { + if (ib_dev->ops.dealloc_driver && + ib_dev->ops.dealloc_driver != prevent_dealloc_device) { WARN_ON(kref_read(&ib_dev->dev.kobj.kref) <= 1); ib_dealloc_device(ib_dev); } @@ -1679,7 +1700,7 @@ { int ret; - down_write(&clients_rwsem); + lockdep_assert_held(&clients_rwsem); /* * The add/remove callbacks must be called in FIFO/LIFO order. To * achieve this we assign client_ids so they are sorted in @@ -1688,14 +1709,11 @@ client->client_id = highest_client_id; ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL); if (ret) - goto out; + return ret; highest_client_id++; xa_set_mark(&clients, client->client_id, CLIENT_REGISTERED); - -out: - up_write(&clients_rwsem); - return ret; + return 0; } static void remove_client_id(struct ib_client *client) @@ -1725,25 +1743,35 @@ { struct ib_device *device; unsigned long index; + bool need_unreg = false; int ret; refcount_set(&client->uses, 1); init_completion(&client->uses_zero); + + /* + * The devices_rwsem is held in write mode to ensure that a racing + * ib_register_device() sees a consisent view of clients and devices. + */ + down_write(&devices_rwsem); + down_write(&clients_rwsem); ret = assign_client_id(client); if (ret) - return ret; + goto out; - down_read(&devices_rwsem); + need_unreg = true; xa_for_each_marked (&devices, index, device, DEVICE_REGISTERED) { ret = add_client_context(device, client); - if (ret) { - up_read(&devices_rwsem); - ib_unregister_client(client); - return ret; - } + if (ret) + goto out; } - up_read(&devices_rwsem); - return 0; + ret = 0; +out: + up_write(&clients_rwsem); + up_write(&devices_rwsem); + if (need_unreg && ret) + ib_unregister_client(client); + return ret; } EXPORT_SYMBOL(ib_register_client); @@ -1920,17 +1948,15 @@ * * ib_register_event_handler() registers an event handler that will be * called back when asynchronous IB events occur (as defined in - * chapter 11 of the InfiniBand Architecture Specification). This - * callback may occur in interrupt context. + * chapter 11 of the InfiniBand Architecture Specification). This + * callback occurs in workqueue context. */ void ib_register_event_handler(struct ib_event_handler *event_handler) { - unsigned long flags; - - spin_lock_irqsave(&event_handler->device->event_handler_lock, flags); + down_write(&event_handler->device->event_handler_rwsem); list_add_tail(&event_handler->list, &event_handler->device->event_handler_list); - spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags); + up_write(&event_handler->device->event_handler_rwsem); } EXPORT_SYMBOL(ib_register_event_handler); @@ -1943,35 +1969,23 @@ */ void ib_unregister_event_handler(struct ib_event_handler *event_handler) { - unsigned long flags; - - spin_lock_irqsave(&event_handler->device->event_handler_lock, flags); + down_write(&event_handler->device->event_handler_rwsem); list_del(&event_handler->list); - spin_unlock_irqrestore(&event_handler->device->event_handler_lock, flags); + up_write(&event_handler->device->event_handler_rwsem); } EXPORT_SYMBOL(ib_unregister_event_handler); -/** - * ib_dispatch_event - Dispatch an asynchronous event - * @event:Event to dispatch - * - * Low-level drivers must call ib_dispatch_event() to dispatch the - * event to all registered event handlers when an asynchronous event - * occurs. - */ -void ib_dispatch_event(struct ib_event *event) +void ib_dispatch_event_clients(struct ib_event *event) { - unsigned long flags; struct ib_event_handler *handler; - spin_lock_irqsave(&event->device->event_handler_lock, flags); + down_read(&event->device->event_handler_rwsem); list_for_each_entry(handler, &event->device->event_handler_list, list) handler->handler(handler, event); - spin_unlock_irqrestore(&event->device->event_handler_lock, flags); + up_read(&event->device->event_handler_rwsem); } -EXPORT_SYMBOL(ib_dispatch_event); static int iw_query_port(struct ib_device *device, u8 port_num, @@ -2111,6 +2125,9 @@ unsigned long flags; int ret; + if (!rdma_is_port_valid(ib_dev, port)) + return -EINVAL; + /* * Drivers wish to call this before ib_register_driver, so we have to * setup the port data early. @@ -2119,9 +2136,6 @@ if (ret) return ret; - if (!rdma_is_port_valid(ib_dev, port)) - return -EINVAL; - pdata = &ib_dev->port_data[port]; spin_lock_irqsave(&pdata->netdev_lock, flags); old_ndev = rcu_dereference_protected( @@ -2397,8 +2411,12 @@ rc = device->ops.modify_port(device, port_num, port_modify_mask, port_modify); + else if (rdma_protocol_roce(device, port_num) && + ((port_modify->set_port_cap_mask & ~IB_PORT_CM_SUP) == 0 || + (port_modify->clr_port_cap_mask & ~IB_PORT_CM_SUP) == 0)) + rc = 0; else - rc = rdma_protocol_roce(device, port_num) ? 0 : -ENOSYS; + rc = -EOPNOTSUPP; return rc; } EXPORT_SYMBOL(ib_modify_port); @@ -2427,7 +2445,8 @@ ++i) { ret = rdma_query_gid(device, port, i, &tmp_gid); if (ret) - return ret; + continue; + if (!memcmp(&tmp_gid, gid, sizeof *gid)) { *port_num = port; if (index) @@ -2630,6 +2649,7 @@ SET_DEVICE_OP(dev_ops, map_mr_sg_pi); SET_DEVICE_OP(dev_ops, map_phys_fmr); SET_DEVICE_OP(dev_ops, mmap); + SET_DEVICE_OP(dev_ops, mmap_free); SET_DEVICE_OP(dev_ops, modify_ah); SET_DEVICE_OP(dev_ops, modify_cq); SET_DEVICE_OP(dev_ops, modify_device); @@ -2750,10 +2770,18 @@ nldev_init(); rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table); - roce_gid_mgmt_init(); + ret = roce_gid_mgmt_init(); + if (ret) { + pr_warn("Couldn't init RoCE GID management\n"); + goto err_parent; + } return 0; +err_parent: + rdma_nl_unregister(RDMA_NL_LS); + nldev_exit(); + unregister_pernet_device(&rdma_dev_net_ops); err_compat: unregister_blocking_lsm_notifier(&ibdev_lsm_nb); err_sa: @@ -2776,8 +2804,8 @@ static void __exit ib_core_cleanup(void) { roce_gid_mgmt_cleanup(); - nldev_exit(); rdma_nl_unregister(RDMA_NL_LS); + nldev_exit(); unregister_pernet_device(&rdma_dev_net_ops); unregister_blocking_lsm_notifier(&ibdev_lsm_nb); ib_sa_cleanup(); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/ib_core_uverbs.c +++ linux-oracle-5.4.0/drivers/infiniband/core/ib_core_uverbs.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* + * Copyright (c) 2005 Mellanox Technologies. All rights reserved. + * Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All rights reserved. + * Copyright 2019 Marvell. All rights reserved. + */ +#include +#include "uverbs.h" +#include "core_priv.h" + +/** + * rdma_umap_priv_init() - Initialize the private data of a vma + * + * @priv: The already allocated private data + * @vma: The vm area struct that needs private data + * @entry: entry into the mmap_xa that needs to be linked with + * this vma + * + * Each time we map IO memory into user space this keeps track of the + * mapping. When the device is hot-unplugged we 'zap' the mmaps in user space + * to point to the zero page and allow the hot unplug to proceed. + * + * This is necessary for cases like PCI physical hot unplug as the actual BAR + * memory may vanish after this and access to it from userspace could MCE. + * + * RDMA drivers supporting disassociation must have their user space designed + * to cope in some way with their IO pages going to the zero page. + * + */ +void rdma_umap_priv_init(struct rdma_umap_priv *priv, + struct vm_area_struct *vma, + struct rdma_user_mmap_entry *entry) +{ + struct ib_uverbs_file *ufile = vma->vm_file->private_data; + + priv->vma = vma; + if (entry) { + kref_get(&entry->ref); + priv->entry = entry; + } + vma->vm_private_data = priv; + /* vm_ops is setup in ib_uverbs_mmap() to avoid module dependencies */ + + mutex_lock(&ufile->umap_lock); + list_add(&priv->list, &ufile->umaps); + mutex_unlock(&ufile->umap_lock); +} +EXPORT_SYMBOL(rdma_umap_priv_init); + +/** + * rdma_user_mmap_io() - Map IO memory into a process + * + * @ucontext: associated user context + * @vma: the vma related to the current mmap call + * @pfn: pfn to map + * @size: size to map + * @prot: pgprot to use in remap call + * @entry: mmap_entry retrieved from rdma_user_mmap_entry_get(), or NULL + * if mmap_entry is not used by the driver + * + * This is to be called by drivers as part of their mmap() functions if they + * wish to send something like PCI-E BAR memory to userspace. + * + * Return -EINVAL on wrong flags or size, -EAGAIN on failure to map. 0 on + * success. + */ +int rdma_user_mmap_io(struct ib_ucontext *ucontext, struct vm_area_struct *vma, + unsigned long pfn, unsigned long size, pgprot_t prot, + struct rdma_user_mmap_entry *entry) +{ + struct ib_uverbs_file *ufile = ucontext->ufile; + struct rdma_umap_priv *priv; + + if (!(vma->vm_flags & VM_SHARED)) + return -EINVAL; + + if (vma->vm_end - vma->vm_start != size) + return -EINVAL; + + /* Driver is using this wrong, must be called by ib_uverbs_mmap */ + if (WARN_ON(!vma->vm_file || + vma->vm_file->private_data != ufile)) + return -EINVAL; + lockdep_assert_held(&ufile->device->disassociate_srcu); + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + vma->vm_page_prot = prot; + if (io_remap_pfn_range(vma, vma->vm_start, pfn, size, prot)) { + kfree(priv); + return -EAGAIN; + } + + rdma_umap_priv_init(priv, vma, entry); + return 0; +} +EXPORT_SYMBOL(rdma_user_mmap_io); + +/** + * rdma_user_mmap_entry_get_pgoff() - Get an entry from the mmap_xa + * + * @ucontext: associated user context + * @pgoff: The mmap offset >> PAGE_SHIFT + * + * This function is called when a user tries to mmap with an offset (returned + * by rdma_user_mmap_get_offset()) it initially received from the driver. The + * rdma_user_mmap_entry was created by the function + * rdma_user_mmap_entry_insert(). This function increases the refcnt of the + * entry so that it won't be deleted from the xarray in the meantime. + * + * Return an reference to an entry if exists or NULL if there is no + * match. rdma_user_mmap_entry_put() must be called to put the reference. + */ +struct rdma_user_mmap_entry * +rdma_user_mmap_entry_get_pgoff(struct ib_ucontext *ucontext, + unsigned long pgoff) +{ + struct rdma_user_mmap_entry *entry; + + if (pgoff > U32_MAX) + return NULL; + + xa_lock(&ucontext->mmap_xa); + + entry = xa_load(&ucontext->mmap_xa, pgoff); + + /* + * If refcount is zero, entry is already being deleted, driver_removed + * indicates that the no further mmaps are possible and we waiting for + * the active VMAs to be closed. + */ + if (!entry || entry->start_pgoff != pgoff || entry->driver_removed || + !kref_get_unless_zero(&entry->ref)) + goto err; + + xa_unlock(&ucontext->mmap_xa); + + ibdev_dbg(ucontext->device, "mmap: pgoff[%#lx] npages[%#zx] returned\n", + pgoff, entry->npages); + + return entry; + +err: + xa_unlock(&ucontext->mmap_xa); + return NULL; +} +EXPORT_SYMBOL(rdma_user_mmap_entry_get_pgoff); + +/** + * rdma_user_mmap_entry_get() - Get an entry from the mmap_xa + * + * @ucontext: associated user context + * @vma: the vma being mmap'd into + * + * This function is like rdma_user_mmap_entry_get_pgoff() except that it also + * checks that the VMA is correct. + */ +struct rdma_user_mmap_entry * +rdma_user_mmap_entry_get(struct ib_ucontext *ucontext, + struct vm_area_struct *vma) +{ + struct rdma_user_mmap_entry *entry; + + if (!(vma->vm_flags & VM_SHARED)) + return NULL; + entry = rdma_user_mmap_entry_get_pgoff(ucontext, vma->vm_pgoff); + if (!entry) + return NULL; + if (entry->npages * PAGE_SIZE != vma->vm_end - vma->vm_start) { + rdma_user_mmap_entry_put(entry); + return NULL; + } + return entry; +} +EXPORT_SYMBOL(rdma_user_mmap_entry_get); + +static void rdma_user_mmap_entry_free(struct kref *kref) +{ + struct rdma_user_mmap_entry *entry = + container_of(kref, struct rdma_user_mmap_entry, ref); + struct ib_ucontext *ucontext = entry->ucontext; + unsigned long i; + + /* + * Erase all entries occupied by this single entry, this is deferred + * until all VMA are closed so that the mmap offsets remain unique. + */ + xa_lock(&ucontext->mmap_xa); + for (i = 0; i < entry->npages; i++) + __xa_erase(&ucontext->mmap_xa, entry->start_pgoff + i); + xa_unlock(&ucontext->mmap_xa); + + ibdev_dbg(ucontext->device, "mmap: pgoff[%#lx] npages[%#zx] removed\n", + entry->start_pgoff, entry->npages); + + if (ucontext->device->ops.mmap_free) + ucontext->device->ops.mmap_free(entry); +} + +/** + * rdma_user_mmap_entry_put() - Drop reference to the mmap entry + * + * @entry: an entry in the mmap_xa + * + * This function is called when the mapping is closed if it was + * an io mapping or when the driver is done with the entry for + * some other reason. + * Should be called after rdma_user_mmap_entry_get was called + * and entry is no longer needed. This function will erase the + * entry and free it if its refcnt reaches zero. + */ +void rdma_user_mmap_entry_put(struct rdma_user_mmap_entry *entry) +{ + kref_put(&entry->ref, rdma_user_mmap_entry_free); +} +EXPORT_SYMBOL(rdma_user_mmap_entry_put); + +/** + * rdma_user_mmap_entry_remove() - Drop reference to entry and + * mark it as unmmapable + * + * @entry: the entry to insert into the mmap_xa + * + * Drivers can call this to prevent userspace from creating more mappings for + * entry, however existing mmaps continue to exist and ops->mmap_free() will + * not be called until all user mmaps are destroyed. + */ +void rdma_user_mmap_entry_remove(struct rdma_user_mmap_entry *entry) +{ + if (!entry) + return; + + entry->driver_removed = true; + kref_put(&entry->ref, rdma_user_mmap_entry_free); +} +EXPORT_SYMBOL(rdma_user_mmap_entry_remove); + +/** + * rdma_user_mmap_entry_insert() - Insert an entry to the mmap_xa + * + * @ucontext: associated user context. + * @entry: the entry to insert into the mmap_xa + * @length: length of the address that will be mmapped + * + * This function should be called by drivers that use the rdma_user_mmap + * interface for implementing their mmap syscall A database of mmap offsets is + * handled in the core and helper functions are provided to insert entries + * into the database and extract entries when the user calls mmap with the + * given offset. The function allocates a unique page offset that should be + * provided to user, the user will use the offset to retrieve information such + * as address to be mapped and how. + * + * Return: 0 on success and -ENOMEM on failure + */ +int rdma_user_mmap_entry_insert(struct ib_ucontext *ucontext, + struct rdma_user_mmap_entry *entry, + size_t length) +{ + struct ib_uverbs_file *ufile = ucontext->ufile; + XA_STATE(xas, &ucontext->mmap_xa, 0); + u32 xa_first, xa_last, npages; + int err; + u32 i; + + if (!entry) + return -EINVAL; + + kref_init(&entry->ref); + entry->ucontext = ucontext; + + /* + * We want the whole allocation to be done without interruption from a + * different thread. The allocation requires finding a free range and + * storing. During the xa_insert the lock could be released, possibly + * allowing another thread to choose the same range. + */ + mutex_lock(&ufile->umap_lock); + + xa_lock(&ucontext->mmap_xa); + + /* We want to find an empty range */ + npages = (u32)DIV_ROUND_UP(length, PAGE_SIZE); + entry->npages = npages; + while (true) { + /* First find an empty index */ + xas_find_marked(&xas, U32_MAX, XA_FREE_MARK); + if (xas.xa_node == XAS_RESTART) + goto err_unlock; + + xa_first = xas.xa_index; + + /* Is there enough room to have the range? */ + if (check_add_overflow(xa_first, npages, &xa_last)) + goto err_unlock; + + /* + * Now look for the next present entry. If an entry doesn't + * exist, we found an empty range and can proceed. + */ + xas_next_entry(&xas, xa_last - 1); + if (xas.xa_node == XAS_BOUNDS || xas.xa_index >= xa_last) + break; + } + + for (i = xa_first; i < xa_last; i++) { + err = __xa_insert(&ucontext->mmap_xa, i, entry, GFP_KERNEL); + if (err) + goto err_undo; + } + + /* + * Internally the kernel uses a page offset, in libc this is a byte + * offset. Drivers should not return pgoff to userspace. + */ + entry->start_pgoff = xa_first; + xa_unlock(&ucontext->mmap_xa); + mutex_unlock(&ufile->umap_lock); + + ibdev_dbg(ucontext->device, "mmap: pgoff[%#lx] npages[%#x] inserted\n", + entry->start_pgoff, npages); + + return 0; + +err_undo: + for (; i > xa_first; i--) + __xa_erase(&ucontext->mmap_xa, i - 1); + +err_unlock: + xa_unlock(&ucontext->mmap_xa); + mutex_unlock(&ufile->umap_lock); + return -ENOMEM; +} +EXPORT_SYMBOL(rdma_user_mmap_entry_insert); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/ib_peer_mem.h +++ linux-oracle-5.4.0/drivers/infiniband/core/ib_peer_mem.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ +/* + * Copyright (c) 2014-2020, Mellanox Technologies. All rights reserved. + */ +#ifndef RDMA_IB_PEER_MEM_H +#define RDMA_IB_PEER_MEM_H + +#include +#include +#include +#include + +struct ib_peer_memory_statistics { + atomic64_t num_alloc_mrs; + atomic64_t num_dealloc_mrs; + atomic64_t num_reg_pages; + atomic64_t num_dereg_pages; + atomic64_t num_reg_bytes; + atomic64_t num_dereg_bytes; + unsigned long num_free_callbacks; +}; + +struct ib_peer_memory_client { + struct kobject kobj; + refcount_t usecnt; + struct completion usecnt_zero; + const struct peer_memory_client *peer_mem; + struct list_head core_peer_list; + struct ib_peer_memory_statistics stats; + struct xarray umem_xa; + u32 xa_cyclic_next; + bool invalidation_required; +}; + +enum ib_umem_mapped_state { + UMEM_PEER_UNMAPPED, + UMEM_PEER_MAPPED, + UMEM_PEER_INVALIDATED, +}; + +struct ib_umem_peer { + struct ib_umem umem; + struct kref kref; + /* peer memory that manages this umem */ + struct ib_peer_memory_client *ib_peer_client; + void *peer_client_context; + umem_invalidate_func_t invalidation_func; + void *invalidation_private; + struct mutex mapping_lock; + enum ib_umem_mapped_state mapped_state; + u32 xa_id; +}; + +struct ib_umem *ib_peer_umem_get(struct ib_umem *old_umem, int old_ret, + unsigned long peer_mem_flags); +void ib_peer_umem_release(struct ib_umem *umem); + +#endif --- linux-oracle-5.4.0.orig/drivers/infiniband/core/iwcm.c +++ linux-oracle-5.4.0/drivers/infiniband/core/iwcm.c @@ -159,8 +159,10 @@ { struct list_head *e, *tmp; - list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) + list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) { + list_del(e); kfree(list_entry(e, struct iwcm_work, free_list)); + } } static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) @@ -368,8 +370,10 @@ * * Clean up all resources associated with the connection and release * the initial reference taken by iw_create_cm_id. + * + * Returns true if and only if the last cm_id_priv reference has been dropped. */ -static void destroy_cm_id(struct iw_cm_id *cm_id) +static bool destroy_cm_id(struct iw_cm_id *cm_id) { struct iwcm_id_private *cm_id_priv; struct ib_qp *qp; @@ -439,7 +443,7 @@ iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM); } - (void)iwcm_deref_id(cm_id_priv); + return iwcm_deref_id(cm_id_priv); } /* @@ -450,7 +454,8 @@ */ void iw_destroy_cm_id(struct iw_cm_id *cm_id) { - destroy_cm_id(cm_id); + if (!destroy_cm_id(cm_id)) + flush_workqueue(iwcm_wq); } EXPORT_SYMBOL(iw_destroy_cm_id); @@ -1034,7 +1039,7 @@ if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) { ret = process_event(cm_id_priv, &levent); if (ret) - destroy_cm_id(&cm_id_priv->id); + WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id)); } else pr_debug("dropping event %d\n", levent.event); if (iwcm_deref_id(cm_id_priv)) @@ -1185,29 +1190,34 @@ ret = iwpm_init(RDMA_NL_IWCM); if (ret) - pr_err("iw_cm: couldn't init iwpm\n"); - else - rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); - iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0); + return ret; + + iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM); if (!iwcm_wq) - return -ENOMEM; + goto err_alloc; iwcm_ctl_table_hdr = register_net_sysctl(&init_net, "net/iw_cm", iwcm_ctl_table); if (!iwcm_ctl_table_hdr) { pr_err("iw_cm: couldn't register sysctl paths\n"); - destroy_workqueue(iwcm_wq); - return -ENOMEM; + goto err_sysctl; } + rdma_nl_register(RDMA_NL_IWCM, iwcm_nl_cb_table); return 0; + +err_sysctl: + destroy_workqueue(iwcm_wq); +err_alloc: + iwpm_exit(RDMA_NL_IWCM); + return -ENOMEM; } static void __exit iw_cm_cleanup(void) { + rdma_nl_unregister(RDMA_NL_IWCM); unregister_net_sysctl_table(iwcm_ctl_table_hdr); destroy_workqueue(iwcm_wq); - rdma_nl_unregister(RDMA_NL_IWCM); iwpm_exit(RDMA_NL_IWCM); } --- linux-oracle-5.4.0.orig/drivers/infiniband/core/mad.c +++ linux-oracle-5.4.0/drivers/infiniband/core/mad.c @@ -639,10 +639,10 @@ xa_erase(&ib_mad_clients, mad_agent_priv->agent.hi_tid); flush_workqueue(port_priv->wq); - ib_cancel_rmpp_recvs(mad_agent_priv); deref_mad_agent(mad_agent_priv); wait_for_completion(&mad_agent_priv->comp); + ib_cancel_rmpp_recvs(mad_agent_priv); ib_mad_agent_security_cleanup(&mad_agent_priv->agent); @@ -2960,6 +2960,7 @@ DMA_FROM_DEVICE); if (unlikely(ib_dma_mapping_error(qp_info->port_priv->device, sg_list.addr))) { + kfree(mad_priv); ret = -ENOMEM; break; } --- linux-oracle-5.4.0.orig/drivers/infiniband/core/nldev.c +++ linux-oracle-5.4.0/drivers/infiniband/core/nldev.c @@ -493,7 +493,7 @@ struct rdma_cm_id *cm_id = &id_priv->id; if (port && port != cm_id->port_num) - return 0; + return -EAGAIN; if (cm_id->port_num && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, cm_id->port_num)) @@ -694,6 +694,8 @@ int ret = 0; table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_RES_QP); + if (!table_attr) + return -EMSGSIZE; rt = &counter->device->res[RDMA_RESTRACK_QP]; xa_lock(&rt->xa); @@ -702,9 +704,6 @@ continue; qp = container_of(res, struct ib_qp, res); - if (qp->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW)) - continue; - if (!qp->counter || (qp->counter->id != counter->id)) continue; @@ -863,6 +862,10 @@ nla_strlcpy(name, tb[RDMA_NLDEV_ATTR_DEV_NAME], IB_DEVICE_NAME_MAX); + if (strlen(name) == 0) { + err = -EINVAL; + goto done; + } err = ib_device_rename(device, name); goto done; } @@ -1244,10 +1247,10 @@ has_cap_net_admin = netlink_capable(skb, CAP_NET_ADMIN); ret = fe->fill_res_func(msg, has_cap_net_admin, res, port); - rdma_restrack_put(res); if (ret) goto err_free; + rdma_restrack_put(res); nlmsg_end(msg, nlh); ib_device_put(device); return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid); @@ -1468,7 +1471,7 @@ nla_strlcpy(ibdev_name, tb[RDMA_NLDEV_ATTR_DEV_NAME], sizeof(ibdev_name)); - if (strchr(ibdev_name, '%')) + if (strchr(ibdev_name, '%') || strlen(ibdev_name) == 0) return -EINVAL; nla_strlcpy(type, tb[RDMA_NLDEV_ATTR_LINK_TYPE], sizeof(type)); @@ -1711,6 +1714,8 @@ if (ret) goto err_msg; } else { + if (!tb[RDMA_NLDEV_ATTR_RES_LQPN]) + goto err_msg; qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) { cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); @@ -2075,6 +2080,7 @@ }, [RDMA_NLDEV_CMD_SYS_SET] = { .doit = nldev_set_sys_set_doit, + .flags = RDMA_NL_ADMIN_PERM, }, [RDMA_NLDEV_CMD_STAT_SET] = { .doit = nldev_stat_set_doit, @@ -2095,7 +2101,7 @@ rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table); } -void __exit nldev_exit(void) +void nldev_exit(void) { rdma_nl_unregister(RDMA_NL_NLDEV); } --- linux-oracle-5.4.0.orig/drivers/infiniband/core/peer_mem.c +++ linux-oracle-5.4.0/drivers/infiniband/core/peer_mem.c @@ -0,0 +1,559 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* + * Copyright (c) 2014-2020, Mellanox Technologies. All rights reserved. + */ +#include +#include +#include +#include "ib_peer_mem.h" +static DEFINE_MUTEX(peer_memory_mutex); +static LIST_HEAD(peer_memory_list); +static struct kobject *peers_kobj; +#define PEER_NO_INVALIDATION_ID U32_MAX +static int ib_invalidate_peer_memory(void *reg_handle, u64 core_context); +struct peer_mem_attribute { + struct attribute attr; + ssize_t (*show)(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf); + ssize_t (*store)(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, const char *buf, + size_t count); +}; + +#define PEER_ATTR_RO(_name) \ + struct peer_mem_attribute peer_attr_ ## _name = __ATTR_RO(_name) + +static ssize_t version_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%s\n", + ib_peer_client->peer_mem->version); +} + +static PEER_ATTR_RO(version); +static ssize_t num_alloc_mrs_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_alloc_mrs)); +} + +static PEER_ATTR_RO(num_alloc_mrs); +static ssize_t +num_dealloc_mrs_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_dealloc_mrs)); +} + +static PEER_ATTR_RO(num_dealloc_mrs); +static ssize_t num_reg_pages_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_reg_pages)); +} + +static PEER_ATTR_RO(num_reg_pages); +static ssize_t +num_dereg_pages_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_dereg_pages)); +} + +static PEER_ATTR_RO(num_dereg_pages); +static ssize_t num_reg_bytes_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_reg_bytes)); +} + +static PEER_ATTR_RO(num_reg_bytes); +static ssize_t +num_dereg_bytes_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf( + buf, PAGE_SIZE, "%llu\n", + (u64)atomic64_read(&ib_peer_client->stats.num_dereg_bytes)); +} + +static PEER_ATTR_RO(num_dereg_bytes); +static ssize_t +num_free_callbacks_show(struct ib_peer_memory_client *ib_peer_client, + struct peer_mem_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%lu\n", + ib_peer_client->stats.num_free_callbacks); +} + +static PEER_ATTR_RO(num_free_callbacks); +static struct attribute *peer_mem_attrs[] = { + &peer_attr_version.attr, + &peer_attr_num_alloc_mrs.attr, + &peer_attr_num_dealloc_mrs.attr, + &peer_attr_num_reg_pages.attr, + &peer_attr_num_dereg_pages.attr, + &peer_attr_num_reg_bytes.attr, + &peer_attr_num_dereg_bytes.attr, + &peer_attr_num_free_callbacks.attr, + NULL, +}; + +static const struct attribute_group peer_mem_attr_group = { + .attrs = peer_mem_attrs, +}; + +static ssize_t peer_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct peer_mem_attribute *peer_attr = + container_of(attr, struct peer_mem_attribute, attr); + if (!peer_attr->show) + return -EIO; + return peer_attr->show(container_of(kobj, struct ib_peer_memory_client, + kobj), + peer_attr, buf); +} + +static const struct sysfs_ops peer_mem_sysfs_ops = { + .show = peer_attr_show, +}; + +static void ib_peer_memory_client_release(struct kobject *kobj) +{ + struct ib_peer_memory_client *ib_peer_client = + container_of(kobj, struct ib_peer_memory_client, kobj); + kfree(ib_peer_client); +} + +static struct kobj_type peer_mem_type = { + .sysfs_ops = &peer_mem_sysfs_ops, + .release = ib_peer_memory_client_release, +}; + +static int ib_memory_peer_check_mandatory(const struct peer_memory_client + *peer_client) +{ +#define PEER_MEM_MANDATORY_FUNC(x) {offsetof(struct peer_memory_client, x), #x} + int i; + static const struct { + size_t offset; + char *name; + } mandatory_table[] = { + PEER_MEM_MANDATORY_FUNC(acquire), + PEER_MEM_MANDATORY_FUNC(get_pages), + PEER_MEM_MANDATORY_FUNC(put_pages), + PEER_MEM_MANDATORY_FUNC(dma_map), + PEER_MEM_MANDATORY_FUNC(dma_unmap), + }; + for (i = 0; i < ARRAY_SIZE(mandatory_table); ++i) { + if (!*(void **)((void *)peer_client + + mandatory_table[i].offset)) { + pr_err("Peer memory %s is missing mandatory function %s\n", + peer_client->name, mandatory_table[i].name); + return -EINVAL; + } + } + return 0; +} + +void * +ib_register_peer_memory_client(const struct peer_memory_client *peer_client, + invalidate_peer_memory *invalidate_callback) +{ + struct ib_peer_memory_client *ib_peer_client; + int ret; + if (ib_memory_peer_check_mandatory(peer_client)) + return NULL; + ib_peer_client = kzalloc(sizeof(*ib_peer_client), GFP_KERNEL); + if (!ib_peer_client) + return NULL; + kobject_init(&ib_peer_client->kobj, &peer_mem_type); + refcount_set(&ib_peer_client->usecnt, 1); + init_completion(&ib_peer_client->usecnt_zero); + ib_peer_client->peer_mem = peer_client; + xa_init_flags(&ib_peer_client->umem_xa, XA_FLAGS_ALLOC); + /* + * If the peer wants the invalidation_callback then all memory users + * linked to that peer must support invalidation. + */ + if (invalidate_callback) { + *invalidate_callback = ib_invalidate_peer_memory; + ib_peer_client->invalidation_required = true; + } + mutex_lock(&peer_memory_mutex); + if (!peers_kobj) { + /* Created under /sys/kernel/mm */ + peers_kobj = kobject_create_and_add("memory_peers", mm_kobj); + if (!peers_kobj) + goto err_unlock; + } + ret = kobject_add(&ib_peer_client->kobj, peers_kobj, peer_client->name); + if (ret) + goto err_parent; + ret = sysfs_create_group(&ib_peer_client->kobj, + &peer_mem_attr_group); + if (ret) + goto err_parent; + list_add_tail(&ib_peer_client->core_peer_list, &peer_memory_list); + mutex_unlock(&peer_memory_mutex); + return ib_peer_client; +err_parent: + if (list_empty(&peer_memory_list)) { + kobject_put(peers_kobj); + peers_kobj = NULL; + } +err_unlock: + mutex_unlock(&peer_memory_mutex); + kobject_put(&ib_peer_client->kobj); + return NULL; +} +EXPORT_SYMBOL(ib_register_peer_memory_client); + +void ib_unregister_peer_memory_client(void *reg_handle) +{ + struct ib_peer_memory_client *ib_peer_client = reg_handle; + mutex_lock(&peer_memory_mutex); + list_del(&ib_peer_client->core_peer_list); + if (list_empty(&peer_memory_list)) { + kobject_put(peers_kobj); + peers_kobj = NULL; + } + mutex_unlock(&peer_memory_mutex); + /* + * Wait for all umems to be destroyed before returning. Once + * ib_unregister_peer_memory_client() returns no umems will call any + * peer_mem ops. + */ + if (refcount_dec_and_test(&ib_peer_client->usecnt)) + complete(&ib_peer_client->usecnt_zero); + wait_for_completion(&ib_peer_client->usecnt_zero); + kobject_put(&ib_peer_client->kobj); +} +EXPORT_SYMBOL(ib_unregister_peer_memory_client); + +static struct ib_peer_memory_client * +ib_get_peer_client(unsigned long addr, size_t size, + unsigned long peer_mem_flags, void **peer_client_context) +{ + struct ib_peer_memory_client *ib_peer_client; + int ret = 0; + mutex_lock(&peer_memory_mutex); + list_for_each_entry(ib_peer_client, &peer_memory_list, + core_peer_list) { + if (ib_peer_client->invalidation_required && + (!(peer_mem_flags & IB_PEER_MEM_INVAL_SUPP))) + continue; + ret = ib_peer_client->peer_mem->acquire(addr, size, NULL, NULL, + peer_client_context); + if (ret > 0) { + refcount_inc(&ib_peer_client->usecnt); + mutex_unlock(&peer_memory_mutex); + return ib_peer_client; + } + } + mutex_unlock(&peer_memory_mutex); + return NULL; +} + +static void ib_put_peer_client(struct ib_peer_memory_client *ib_peer_client, + void *peer_client_context) +{ + if (ib_peer_client->peer_mem->release) + ib_peer_client->peer_mem->release(peer_client_context); + if (refcount_dec_and_test(&ib_peer_client->usecnt)) + complete(&ib_peer_client->usecnt_zero); +} + +static void ib_peer_umem_kref_release(struct kref *kref) +{ + struct ib_umem_peer *umem_p = + container_of(kref, struct ib_umem_peer, kref); + + mutex_destroy(&umem_p->mapping_lock); + kfree(umem_p); +} + +static void ib_unmap_peer_client(struct ib_umem_peer *umem_p, + enum ib_umem_mapped_state cur_state, + enum ib_umem_mapped_state to_state) +{ + struct ib_peer_memory_client *ib_peer_client = umem_p->ib_peer_client; + const struct peer_memory_client *peer_mem = ib_peer_client->peer_mem; + struct ib_umem *umem = &umem_p->umem; + + if (cur_state == UMEM_PEER_MAPPED && + (to_state == UMEM_PEER_UNMAPPED || + to_state == UMEM_PEER_INVALIDATED)) { + if (to_state == UMEM_PEER_UNMAPPED) { + peer_mem->dma_unmap(&umem_p->umem.sg_head, umem_p->peer_client_context, + umem_p->umem.ibdev->dma_device); + peer_mem->put_pages(&umem_p->umem.sg_head, umem_p->peer_client_context); + } + memset(&umem->sg_head, 0, sizeof(umem->sg_head)); + atomic64_inc(&ib_peer_client->stats.num_dealloc_mrs); + } + + if ((cur_state == UMEM_PEER_MAPPED && to_state == UMEM_PEER_UNMAPPED) || + (cur_state == UMEM_PEER_INVALIDATED && + to_state == UMEM_PEER_UNMAPPED)) { + atomic64_add(umem->nmap, &ib_peer_client->stats.num_dereg_pages); + atomic64_add(umem->length, &ib_peer_client->stats.num_dereg_bytes); + } + + umem_p->mapped_state = to_state; +} + +static bool ib_peer_unmap_on_invalidate(struct ib_umem_peer *umem_p) +{ + const struct peer_memory_client *peer_mem = + umem_p->ib_peer_client->peer_mem; + const struct peer_memory_client_ex *peer_mem_ex; + + if (peer_mem->version[IB_PEER_MEMORY_VER_MAX - 1] == 0) + return false; + peer_mem_ex = container_of(peer_mem, const struct peer_memory_client_ex, + client); + if (peer_mem_ex->ex_size < + offsetofend(struct peer_memory_client_ex, flags)) + return false; + return peer_mem_ex->flags & PEER_MEM_INVALIDATE_UNMAPS; +} + + +static int ib_invalidate_peer_memory(void *reg_handle, u64 core_context) +{ + struct ib_peer_memory_client *ib_peer_client = reg_handle; + struct ib_umem_peer *umem_p; + + /* + * The client is not required to fence against invalidation during + * put_pages() as that would deadlock when we call put_pages() here. + * Thus the core_context cannot be a umem pointer as we have no control + * over the lifetime. Since we won't change the kABI for this to add a + * proper kref, an xarray is used. + */ + xa_lock(&ib_peer_client->umem_xa); + ib_peer_client->stats.num_free_callbacks += 1; + umem_p = xa_load(&ib_peer_client->umem_xa, core_context); + if (!umem_p) + goto out_unlock; + kref_get(&umem_p->kref); + xa_unlock(&ib_peer_client->umem_xa); + mutex_lock(&umem_p->mapping_lock); + /* + * For flows that require invalidation the invalidation_func should not + * be NULL while the device can be doing DMA. The mapping_lock ensures + * that the device is ready to receive an invalidation before one is + * triggered here. + */ + if (umem_p->mapped_state == UMEM_PEER_MAPPED && + umem_p->invalidation_func) + umem_p->invalidation_func(&umem_p->umem, + umem_p->invalidation_private); + if (ib_peer_unmap_on_invalidate(umem_p)) + ib_unmap_peer_client(umem_p, umem_p->mapped_state, + UMEM_PEER_INVALIDATED); + else + ib_unmap_peer_client(umem_p, umem_p->mapped_state, + UMEM_PEER_UNMAPPED); + mutex_unlock(&umem_p->mapping_lock); + kref_put(&umem_p->kref, ib_peer_umem_kref_release); + return 0; +out_unlock: + xa_unlock(&ib_peer_client->umem_xa); + return 0; +} + +void ib_umem_activate_invalidation_notifier(struct ib_umem *umem, + umem_invalidate_func_t func, + void *priv) +{ + struct ib_umem_peer *umem_p = + container_of(umem, struct ib_umem_peer, umem); + + if (WARN_ON(!umem->is_peer)) + return; + if (umem_p->xa_id == PEER_NO_INVALIDATION_ID) + return; + + umem_p->invalidation_func = func; + umem_p->invalidation_private = priv; + /* Pairs with the lock in ib_peer_umem_get() */ + mutex_unlock(&umem_p->mapping_lock); + + /* At this point func can be called asynchronously */ +} +EXPORT_SYMBOL(ib_umem_activate_invalidation_notifier); + +/* + * Caller has blocked DMA and will no longer be able to handle invalidate + * callbacks. Callers using invalidation must call this function before calling + * ib_peer_umem_release(). ib_umem_activate_invalidation_notifier() is optional + * before doing this. + */ +void ib_umem_stop_invalidation_notifier(struct ib_umem *umem) +{ + struct ib_umem_peer *umem_p = + container_of(umem, struct ib_umem_peer, umem); + bool unmap_on_invalidate = ib_peer_unmap_on_invalidate(umem_p); + enum ib_umem_mapped_state cur_state; + + if (umem_p->invalidation_func) { + mutex_lock(&umem_p->mapping_lock); + umem_p->invalidation_func = NULL; + } else if (umem_p->xa_id != PEER_NO_INVALIDATION_ID) { + mutex_lock(&umem_p->mapping_lock); + } else { + /* + * Haven't called ib_umem_activate_invalidation_notifier() yet, + * still have the lock + */ + } + + if (!unmap_on_invalidate) { + ib_unmap_peer_client(umem_p, umem_p->mapped_state, + UMEM_PEER_UNMAPPED); + } else { + /* Block ib_invalidate_peer_memory() */ + cur_state = umem_p->mapped_state; + umem_p->mapped_state = UMEM_PEER_UNMAPPED; + } + mutex_unlock(&umem_p->mapping_lock); + + if (unmap_on_invalidate) + ib_unmap_peer_client(umem_p, cur_state, UMEM_PEER_UNMAPPED); + +} +EXPORT_SYMBOL(ib_umem_stop_invalidation_notifier); + +struct ib_umem *ib_peer_umem_get(struct ib_umem *old_umem, int old_ret, + unsigned long peer_mem_flags) +{ + struct ib_peer_memory_client *ib_peer_client; + void *peer_client_context; + struct ib_umem_peer *umem_p; + int ret; + ib_peer_client = + ib_get_peer_client(old_umem->address, old_umem->length, + peer_mem_flags, &peer_client_context); + if (!ib_peer_client) + return ERR_PTR(old_ret); + umem_p = kzalloc(sizeof(*umem_p), GFP_KERNEL); + if (!umem_p) { + ret = -ENOMEM; + goto err_client; + } + + kref_init(&umem_p->kref); + umem_p->umem = *old_umem; + memset(&umem_p->umem.sg_head, 0, sizeof(umem_p->umem.sg_head)); + umem_p->umem.is_peer = 1; + umem_p->ib_peer_client = ib_peer_client; + umem_p->peer_client_context = peer_client_context; + mutex_init(&umem_p->mapping_lock); + umem_p->xa_id = PEER_NO_INVALIDATION_ID; + + mutex_lock(&umem_p->mapping_lock); + if (ib_peer_client->invalidation_required) { + ret = xa_alloc_cyclic(&ib_peer_client->umem_xa, &umem_p->xa_id, + umem_p, + XA_LIMIT(0, PEER_NO_INVALIDATION_ID - 1), + &ib_peer_client->xa_cyclic_next, + GFP_KERNEL); + if (ret < 0) + goto err_umem; + } + + /* + * We always request write permissions to the pages, to force breaking + * of any CoW during the registration of the MR. For read-only MRs we + * use the "force" flag to indicate that CoW breaking is required but + * the registration should not fail if referencing read-only areas. + */ + ret = ib_peer_client->peer_mem->get_pages(umem_p->umem.address, + umem_p->umem.length, 1, + !umem_p->umem.writable, NULL, + peer_client_context, + umem_p->xa_id); + if (ret) + goto err_xa; + + umem_p->umem.page_shift = + ilog2(ib_peer_client->peer_mem->get_page_size(peer_client_context)); + + ret = ib_peer_client->peer_mem->dma_map(&umem_p->umem.sg_head, + peer_client_context, + umem_p->umem.ibdev->dma_device, + 0, &umem_p->umem.nmap); + if (ret) + goto err_pages; + + umem_p->mapped_state = UMEM_PEER_MAPPED; + atomic64_add(umem_p->umem.nmap, &ib_peer_client->stats.num_reg_pages); + atomic64_add(umem_p->umem.length, &ib_peer_client->stats.num_reg_bytes); + atomic64_inc(&ib_peer_client->stats.num_alloc_mrs); + + /* + * If invalidation is allowed then the caller must call + * ib_umem_activate_invalidation_notifier() or ib_peer_umem_release() to + * unlock this mutex. The call to should be done after the last + * read to sg_head, once the caller is ready for the invalidation + * function to be called. + */ + if (umem_p->xa_id == PEER_NO_INVALIDATION_ID) + mutex_unlock(&umem_p->mapping_lock); + /* + * On success the old umem is replaced with the new, larger, allocation + */ + kfree(old_umem); + return &umem_p->umem; +err_pages: + ib_peer_client->peer_mem->put_pages(&umem_p->umem.sg_head, + umem_p->peer_client_context); +err_xa: + if (umem_p->xa_id != PEER_NO_INVALIDATION_ID) + xa_erase(&umem_p->ib_peer_client->umem_xa, umem_p->xa_id); +err_umem: + mutex_unlock(&umem_p->mapping_lock); + kref_put(&umem_p->kref, ib_peer_umem_kref_release); +err_client: + ib_put_peer_client(ib_peer_client, peer_client_context); + return ERR_PTR(ret); +} + +void ib_peer_umem_release(struct ib_umem *umem) +{ + struct ib_umem_peer *umem_p = + container_of(umem, struct ib_umem_peer, umem); + /* + * If ib_umem_activate_invalidation_notifier() is called then + * ib_umem_stop_invalidation_notifier() must be called before release. + */ + WARN_ON(umem_p->invalidation_func); + + /* For no invalidation cases, make sure it is unmapped */ + ib_unmap_peer_client(umem_p, umem_p->mapped_state, UMEM_PEER_UNMAPPED); + + if (umem_p->xa_id != PEER_NO_INVALIDATION_ID) + xa_erase(&umem_p->ib_peer_client->umem_xa, umem_p->xa_id); + ib_put_peer_client(umem_p->ib_peer_client, umem_p->peer_client_context); + umem_p->ib_peer_client = NULL; + + /* Must match ib_umem_release() */ + atomic64_sub(ib_umem_num_pages(umem), &umem->owning_mm->pinned_vm); + mmdrop(umem->owning_mm); + + kref_put(&umem_p->kref, ib_peer_umem_kref_release); +} + --- linux-oracle-5.4.0.orig/drivers/infiniband/core/rdma_core.c +++ linux-oracle-5.4.0/drivers/infiniband/core/rdma_core.c @@ -160,9 +160,9 @@ uobj->context = NULL; /* - * For DESTROY the usecnt is held write locked, the caller is expected - * to put it unlock and put the object when done with it. Only DESTROY - * can remove the IDR handle. + * For DESTROY the usecnt is not changed, the caller is expected to + * manage it via uobj_put_destroy(). Only DESTROY can remove the IDR + * handle. */ if (reason != RDMA_REMOVE_DESTROY) atomic_set(&uobj->usecnt, 0); @@ -194,7 +194,7 @@ /* * This calls uverbs_destroy_uobject() using the RDMA_REMOVE_DESTROY * sequence. It should only be used from command callbacks. On success the - * caller must pair this with rdma_lookup_put_uobject(LOOKUP_WRITE). This + * caller must pair this with uobj_put_destroy(). This * version requires the caller to have already obtained an * LOOKUP_DESTROY uobject kref. */ @@ -205,6 +205,13 @@ down_read(&ufile->hw_destroy_rwsem); + /* + * Once the uobject is destroyed by RDMA_REMOVE_DESTROY then it is left + * write locked as the callers put it back with UVERBS_LOOKUP_DESTROY. + * This is because any other concurrent thread can still see the object + * in the xarray due to RCU. Leaving it locked ensures nothing else will + * touch it. + */ ret = uverbs_try_lock_object(uobj, UVERBS_LOOKUP_WRITE); if (ret) goto out_unlock; @@ -223,7 +230,7 @@ /* * uobj_get_destroy destroys the HW object and returns a handle to the uobj * with a NULL object pointer. The caller must pair this with - * uverbs_put_destroy. + * uobj_put_destroy(). */ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, u32 id, struct uverbs_attr_bundle *attrs) @@ -257,8 +264,7 @@ uobj = __uobj_get_destroy(obj, id, attrs); if (IS_ERR(uobj)) return PTR_ERR(uobj); - - rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); + uobj_put_destroy(uobj); return 0; } @@ -362,7 +368,7 @@ * and the caller is expected to ensure that uverbs_close_fd is never * done while a call top lookup is possible. */ - if (f->f_op != fd_type->fops) { + if (f->f_op != fd_type->fops || uobject->ufile != ufile) { fput(f); return ERR_PTR(-EBADF); } @@ -689,7 +695,6 @@ enum rdma_lookup_mode mode) { assert_uverbs_usecnt(uobj, mode); - uobj->uapi_object->type_class->lookup_put(uobj, mode); /* * In order to unlock an object, either decrease its usecnt for * read access or zero it in case of exclusive access. See @@ -706,6 +711,7 @@ break; } + uobj->uapi_object->type_class->lookup_put(uobj, mode); /* Pairs with the kref obtained by type->lookup_get */ uverbs_uobject_put(uobj); } @@ -817,6 +823,7 @@ rdma_restrack_del(&ucontext->res); ib_dev->ops.dealloc_ucontext(ucontext); + WARN_ON(!xa_empty(&ucontext->mmap_xa)); kfree(ucontext); ufile->ucontext = NULL; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/restrack.c +++ linux-oracle-5.4.0/drivers/infiniband/core/restrack.c @@ -234,6 +234,7 @@ } else { ret = xa_alloc_cyclic(&rt->xa, &res->id, res, xa_limit_32b, &rt->next_id, GFP_KERNEL); + ret = (ret < 0) ? ret : 0; } if (!ret) --- linux-oracle-5.4.0.orig/drivers/infiniband/core/rw.c +++ linux-oracle-5.4.0/drivers/infiniband/core/rw.c @@ -268,6 +268,23 @@ return 1; } +static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg, + u32 sg_cnt, enum dma_data_direction dir) +{ + if (is_pci_p2pdma_page(sg_page(sg))) + pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir); + else + ib_dma_unmap_sg(dev, sg, sg_cnt, dir); +} + +static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg, + u32 sg_cnt, enum dma_data_direction dir) +{ + if (is_pci_p2pdma_page(sg_page(sg))) + return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); + return ib_dma_map_sg(dev, sg, sg_cnt, dir); +} + /** * rdma_rw_ctx_init - initialize a RDMA READ/WRITE context * @ctx: context to initialize @@ -290,11 +307,7 @@ struct ib_device *dev = qp->pd->device; int ret; - if (is_pci_p2pdma_page(sg_page(sg))) - ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); - else - ret = ib_dma_map_sg(dev, sg, sg_cnt, dir); - + ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir); if (!ret) return -ENOMEM; sg_cnt = ret; @@ -333,7 +346,7 @@ return ret; out_unmap_sg: - ib_dma_unmap_sg(dev, sg, sg_cnt, dir); + rdma_rw_unmap_sg(dev, sg, sg_cnt, dir); return ret; } EXPORT_SYMBOL(rdma_rw_ctx_init); @@ -583,11 +596,7 @@ break; } - if (is_pci_p2pdma_page(sg_page(sg))) - pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg, - sg_cnt, dir); - else - ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir); + rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir); } EXPORT_SYMBOL(rdma_rw_ctx_destroy); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/sa_query.c +++ linux-oracle-5.4.0/drivers/infiniband/core/sa_query.c @@ -760,8 +760,9 @@ /* Construct the family header first */ header = skb_put(skb, NLMSG_ALIGN(sizeof(*header))); - memcpy(header->device_name, dev_name(&query->port->agent->device->dev), - LS_DEVICE_NAME_MAX); + strscpy_pad(header->device_name, + dev_name(&query->port->agent->device->dev), + LS_DEVICE_NAME_MAX); header->port_num = query->port->port_num; if ((comp_mask & IB_SA_PATH_REC_REVERSIBLE) && @@ -829,13 +830,20 @@ return len; } -static int ib_nl_send_msg(struct ib_sa_query *query, gfp_t gfp_mask) +static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask) { struct sk_buff *skb = NULL; struct nlmsghdr *nlh; void *data; struct ib_sa_mad *mad; int len; + unsigned long flags; + unsigned long delay; + gfp_t gfp_flag; + int ret; + + INIT_LIST_HEAD(&query->list); + query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq); mad = query->mad_buf->mad; len = ib_nl_get_path_rec_attrs_len(mad->sa_hdr.comp_mask); @@ -860,36 +868,25 @@ /* Repair the nlmsg header length */ nlmsg_end(skb, nlh); - return rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_LS, gfp_mask); -} + gfp_flag = ((gfp_mask & GFP_ATOMIC) == GFP_ATOMIC) ? GFP_ATOMIC : + GFP_NOWAIT; -static int ib_nl_make_request(struct ib_sa_query *query, gfp_t gfp_mask) -{ - unsigned long flags; - unsigned long delay; - int ret; + spin_lock_irqsave(&ib_nl_request_lock, flags); + ret = rdma_nl_multicast(&init_net, skb, RDMA_NL_GROUP_LS, gfp_flag); - INIT_LIST_HEAD(&query->list); - query->seq = (u32)atomic_inc_return(&ib_nl_sa_request_seq); + if (ret) + goto out; - /* Put the request on the list first.*/ - spin_lock_irqsave(&ib_nl_request_lock, flags); + /* Put the request on the list.*/ delay = msecs_to_jiffies(sa_local_svc_timeout_ms); query->timeout = delay + jiffies; list_add_tail(&query->list, &ib_nl_request_list); /* Start the timeout if this is the only request */ if (ib_nl_request_list.next == &query->list) queue_delayed_work(ib_nl_wq, &ib_nl_timed_work, delay); - spin_unlock_irqrestore(&ib_nl_request_lock, flags); - ret = ib_nl_send_msg(query, gfp_mask); - if (ret) { - ret = -EIO; - /* Remove the request */ - spin_lock_irqsave(&ib_nl_request_lock, flags); - list_del(&query->list); - spin_unlock_irqrestore(&ib_nl_request_lock, flags); - } +out: + spin_unlock_irqrestore(&ib_nl_request_lock, flags); return ret; } @@ -1068,7 +1065,7 @@ } settimeout_out: - return skb->len; + return 0; } static inline int ib_nl_is_good_resolve_resp(const struct nlmsghdr *nlh) @@ -1139,7 +1136,7 @@ } resp_out: - return skb->len; + return 0; } static void free_sm_ah(struct kref *kref) --- linux-oracle-5.4.0.orig/drivers/infiniband/core/security.c +++ linux-oracle-5.4.0/drivers/infiniband/core/security.c @@ -339,27 +339,20 @@ if (!new_pps) return NULL; - if (qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) { - if (!qp_pps) { - new_pps->main.port_num = qp_attr->port_num; - new_pps->main.pkey_index = qp_attr->pkey_index; - } else { - new_pps->main.port_num = (qp_attr_mask & IB_QP_PORT) ? - qp_attr->port_num : - qp_pps->main.port_num; - - new_pps->main.pkey_index = - (qp_attr_mask & IB_QP_PKEY_INDEX) ? - qp_attr->pkey_index : - qp_pps->main.pkey_index; - } - new_pps->main.state = IB_PORT_PKEY_VALID; - } else if (qp_pps) { + if (qp_attr_mask & IB_QP_PORT) + new_pps->main.port_num = qp_attr->port_num; + else if (qp_pps) new_pps->main.port_num = qp_pps->main.port_num; + + if (qp_attr_mask & IB_QP_PKEY_INDEX) + new_pps->main.pkey_index = qp_attr->pkey_index; + else if (qp_pps) new_pps->main.pkey_index = qp_pps->main.pkey_index; - if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) - new_pps->main.state = IB_PORT_PKEY_VALID; - } + + if (((qp_attr_mask & IB_QP_PKEY_INDEX) && + (qp_attr_mask & IB_QP_PORT)) || + (qp_pps && qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)) + new_pps->main.state = IB_PORT_PKEY_VALID; if (qp_attr_mask & IB_QP_ALT_PATH) { new_pps->alt.port_num = qp_attr->alt_port_num; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/sysfs.c +++ linux-oracle-5.4.0/drivers/infiniband/core/sysfs.c @@ -1060,8 +1060,7 @@ coredev->ports_kobj, "%d", port_num); if (ret) { - kfree(p); - return ret; + goto err_put; } p->gid_attr_group = kzalloc(sizeof(*p->gid_attr_group), GFP_KERNEL); @@ -1074,8 +1073,7 @@ ret = kobject_init_and_add(&p->gid_attr_group->kobj, &gid_attr_type, &p->kobj, "gid_attrs"); if (ret) { - kfree(p->gid_attr_group); - goto err_put; + goto err_put_gid_attrs; } if (device->ops.process_mad && is_full_dev) { @@ -1406,8 +1404,10 @@ ret = kobject_init_and_add(kobj, ktype, &port->kobj, "%s", name); - if (ret) + if (ret) { + kobject_put(kobj); return ret; + } } return 0; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/ucma.c +++ linux-oracle-5.4.0/drivers/infiniband/core/ucma.c @@ -91,6 +91,7 @@ struct ucma_file *file; struct rdma_cm_id *cm_id; + struct mutex mutex; u64 uid; struct list_head list; @@ -216,6 +217,7 @@ init_completion(&ctx->comp); INIT_LIST_HEAD(&ctx->mc_list); ctx->file = file; + mutex_init(&ctx->mutex); if (xa_alloc(&ctx_table, &ctx->id, ctx, xa_limit_32b, GFP_KERNEL)) goto error; @@ -543,6 +545,7 @@ { struct ucma_event *uevent, *tmp; + rdma_lock_handler(mc->ctx->cm_id); list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) { if (uevent->mc != mc) continue; @@ -550,6 +553,7 @@ list_del(&uevent->list); kfree(uevent); } + rdma_unlock_handler(mc->ctx->cm_id); } /* @@ -579,6 +583,7 @@ list_move_tail(&uevent->list, &list); } list_del(&ctx->list); + events_reported = ctx->events_reported; mutex_unlock(&ctx->file->mut); list_for_each_entry_safe(uevent, tmp, &list, list) { @@ -588,7 +593,7 @@ kfree(uevent); } - events_reported = ctx->events_reported; + mutex_destroy(&ctx->mutex); kfree(ctx); return events_reported; } @@ -658,7 +663,10 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); + mutex_unlock(&ctx->mutex); + ucma_put_ctx(ctx); return ret; } @@ -681,7 +689,9 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_bind_addr(ctx->cm_id, (struct sockaddr *) &cmd.addr); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -705,8 +715,10 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -731,8 +743,10 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, (struct sockaddr *) &cmd.dst_addr, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -752,7 +766,9 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_resolve_route(ctx->cm_id, cmd.timeout_ms); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -841,6 +857,7 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); memset(&resp, 0, sizeof resp); addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; memcpy(&resp.src_addr, addr, addr->sa_family == AF_INET ? @@ -864,6 +881,7 @@ ucma_copy_iw_route(&resp, &ctx->cm_id->route); out: + mutex_unlock(&ctx->mutex); if (copy_to_user(u64_to_user_ptr(cmd.response), &resp, sizeof(resp))) ret = -EFAULT; @@ -1014,6 +1032,7 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); switch (cmd.option) { case RDMA_USER_CM_QUERY_ADDR: ret = ucma_query_addr(ctx, response, out_len); @@ -1028,6 +1047,7 @@ ret = -ENOSYS; break; } + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; @@ -1068,7 +1088,9 @@ return PTR_ERR(ctx); ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); + mutex_lock(&ctx->mutex); ret = rdma_connect(ctx->cm_id, &conn_param); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1089,7 +1111,9 @@ ctx->backlog = cmd.backlog > 0 && cmd.backlog < max_backlog ? cmd.backlog : max_backlog; + mutex_lock(&ctx->mutex); ret = rdma_listen(ctx->cm_id, ctx->backlog); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1111,14 +1135,22 @@ if (cmd.conn_param.valid) { ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); - mutex_lock(&file->mut); + mutex_lock(&ctx->mutex); + rdma_lock_handler(ctx->cm_id); ret = __rdma_accept(ctx->cm_id, &conn_param, NULL); - if (!ret) + if (!ret) { + /* The uid must be set atomically with the handler */ ctx->uid = cmd.uid; - mutex_unlock(&file->mut); - } else + } + rdma_unlock_handler(ctx->cm_id); + mutex_unlock(&ctx->mutex); + } else { + mutex_lock(&ctx->mutex); + rdma_lock_handler(ctx->cm_id); ret = __rdma_accept(ctx->cm_id, NULL, NULL); - + rdma_unlock_handler(ctx->cm_id); + mutex_unlock(&ctx->mutex); + } ucma_put_ctx(ctx); return ret; } @@ -1137,7 +1169,9 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_reject(ctx->cm_id, cmd.private_data, cmd.private_data_len); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1156,7 +1190,9 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); ret = rdma_disconnect(ctx->cm_id); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; } @@ -1187,7 +1223,9 @@ resp.qp_attr_mask = 0; memset(&qp_attr, 0, sizeof qp_attr); qp_attr.qp_state = cmd.qp_state; + mutex_lock(&ctx->mutex); ret = rdma_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask); + mutex_unlock(&ctx->mutex); if (ret) goto out; @@ -1273,9 +1311,13 @@ struct sa_path_rec opa; sa_convert_path_ib_to_opa(&opa, &sa_path); + mutex_lock(&ctx->mutex); ret = rdma_set_ib_path(ctx->cm_id, &opa); + mutex_unlock(&ctx->mutex); } else { + mutex_lock(&ctx->mutex); ret = rdma_set_ib_path(ctx->cm_id, &sa_path); + mutex_unlock(&ctx->mutex); } if (ret) return ret; @@ -1308,7 +1350,9 @@ switch (level) { case RDMA_OPTION_ID: + mutex_lock(&ctx->mutex); ret = ucma_set_option_id(ctx, optname, optval, optlen); + mutex_unlock(&ctx->mutex); break; case RDMA_OPTION_IB: ret = ucma_set_option_ib(ctx, optname, optval, optlen); @@ -1368,8 +1412,10 @@ if (IS_ERR(ctx)) return PTR_ERR(ctx); + mutex_lock(&ctx->mutex); if (ctx->cm_id->device) ret = rdma_notify(ctx->cm_id, (enum ib_event_type)cmd.event); + mutex_unlock(&ctx->mutex); ucma_put_ctx(ctx); return ret; @@ -1412,8 +1458,10 @@ mc->join_state = join_state; mc->uid = cmd->uid; memcpy(&mc->addr, addr, cmd->addr_size); + mutex_lock(&ctx->mutex); ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr, join_state, mc); + mutex_unlock(&ctx->mutex); if (ret) goto err2; @@ -1431,7 +1479,9 @@ return 0; err3: + mutex_lock(&ctx->mutex); rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr); + mutex_unlock(&ctx->mutex); ucma_cleanup_mc_events(mc); err2: xa_erase(&multicast_table, mc->id); @@ -1500,7 +1550,7 @@ mc = xa_load(&multicast_table, cmd.id); if (!mc) mc = ERR_PTR(-ENOENT); - else if (mc->ctx->file != file) + else if (READ_ONCE(mc->ctx->file) != file) mc = ERR_PTR(-EINVAL); else if (!atomic_inc_not_zero(&mc->ctx->ref)) mc = ERR_PTR(-ENXIO); @@ -1513,7 +1563,10 @@ goto out; } + mutex_lock(&mc->ctx->mutex); rdma_leave_multicast(mc->ctx->cm_id, (struct sockaddr *) &mc->addr); + mutex_unlock(&mc->ctx->mutex); + mutex_lock(&mc->ctx->file->mut); ucma_cleanup_mc_events(mc); list_del(&mc->list); @@ -1530,45 +1583,15 @@ return ret; } -static void ucma_lock_files(struct ucma_file *file1, struct ucma_file *file2) -{ - /* Acquire mutex's based on pointer comparison to prevent deadlock. */ - if (file1 < file2) { - mutex_lock(&file1->mut); - mutex_lock_nested(&file2->mut, SINGLE_DEPTH_NESTING); - } else { - mutex_lock(&file2->mut); - mutex_lock_nested(&file1->mut, SINGLE_DEPTH_NESTING); - } -} - -static void ucma_unlock_files(struct ucma_file *file1, struct ucma_file *file2) -{ - if (file1 < file2) { - mutex_unlock(&file2->mut); - mutex_unlock(&file1->mut); - } else { - mutex_unlock(&file1->mut); - mutex_unlock(&file2->mut); - } -} - -static void ucma_move_events(struct ucma_context *ctx, struct ucma_file *file) -{ - struct ucma_event *uevent, *tmp; - - list_for_each_entry_safe(uevent, tmp, &ctx->file->event_list, list) - if (uevent->ctx == ctx) - list_move_tail(&uevent->list, &file->event_list); -} - static ssize_t ucma_migrate_id(struct ucma_file *new_file, const char __user *inbuf, int in_len, int out_len) { struct rdma_ucm_migrate_id cmd; struct rdma_ucm_migrate_resp resp; + struct ucma_event *uevent, *tmp; struct ucma_context *ctx; + LIST_HEAD(event_list); struct fd f; struct ucma_file *cur_file; int ret = 0; @@ -1584,40 +1607,53 @@ ret = -EINVAL; goto file_put; } + cur_file = f.file->private_data; /* Validate current fd and prevent destruction of id. */ - ctx = ucma_get_ctx(f.file->private_data, cmd.id); + ctx = ucma_get_ctx(cur_file, cmd.id); if (IS_ERR(ctx)) { ret = PTR_ERR(ctx); goto file_put; } - cur_file = ctx->file; - if (cur_file == new_file) { - resp.events_reported = ctx->events_reported; - goto response; - } - + rdma_lock_handler(ctx->cm_id); /* - * Migrate events between fd's, maintaining order, and avoiding new - * events being added before existing events. + * ctx->file can only be changed under the handler & xa_lock. xa_load() + * must be checked again to ensure the ctx hasn't begun destruction + * since the ucma_get_ctx(). */ - ucma_lock_files(cur_file, new_file); xa_lock(&ctx_table); - - list_move_tail(&ctx->list, &new_file->ctx_list); - ucma_move_events(ctx, new_file); + if (_ucma_find_context(cmd.id, cur_file) != ctx) { + xa_unlock(&ctx_table); + ret = -ENOENT; + goto err_unlock; + } ctx->file = new_file; + xa_unlock(&ctx_table); + + mutex_lock(&cur_file->mut); + list_del(&ctx->list); + /* + * At this point lock_handler() prevents addition of new uevents for + * this ctx. + */ + list_for_each_entry_safe(uevent, tmp, &cur_file->event_list, list) + if (uevent->ctx == ctx) + list_move_tail(&uevent->list, &event_list); resp.events_reported = ctx->events_reported; + mutex_unlock(&cur_file->mut); - xa_unlock(&ctx_table); - ucma_unlock_files(cur_file, new_file); + mutex_lock(&new_file->mut); + list_add_tail(&ctx->list, &new_file->ctx_list); + list_splice_tail(&event_list, &new_file->event_list); + mutex_unlock(&new_file->mut); -response: if (copy_to_user(u64_to_user_ptr(cmd.response), &resp, sizeof(resp))) ret = -EFAULT; +err_unlock: + rdma_unlock_handler(ctx->cm_id); ucma_put_ctx(ctx); file_put: fdput(f); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/umem.c +++ linux-oracle-5.4.0/drivers/infiniband/core/umem.c @@ -42,6 +42,7 @@ #include #include "uverbs.h" +#include "ib_peer_mem.h" static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) { @@ -151,13 +152,24 @@ dma_addr_t mask; int i; + /* rdma_for_each_block() has a bug if the page size is smaller than the + * page size used to build the umem. For now prevent smaller page sizes + * from being returned. + */ + pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); + /* At minimum, drivers must support PAGE_SIZE or smaller */ if (WARN_ON(!(pgsz_bitmap & GENMASK(PAGE_SHIFT, 0)))) return 0; va = virt; - /* max page size not to exceed MR length */ - mask = roundup_pow_of_two(umem->length); + /* The best result is the smallest page size that results in the minimum + * number of required pages. Compute the largest page size that could + * work based on VA address bits that don't change. + */ + mask = pgsz_bitmap & + GENMASK(BITS_PER_LONG - 1, + bits_per((umem->length - 1 + virt) ^ virt)); /* offset into first SGL */ pgoff = umem->address & ~PAGE_MASK; @@ -166,10 +178,13 @@ * for any address. */ mask |= (sg_dma_address(sg) + pgoff) ^ va; - if (i && i != (umem->nmap - 1)) - /* restrict by length as well for interior SGEs */ - mask |= sg_dma_len(sg); va += sg_dma_len(sg) - pgoff; + /* Except for the last entry, the ending iova alignment sets + * the maximum possible page size as the low bits of the iova + * must be zero when starting the next chunk. + */ + if (i != (umem->nmap - 1)) + mask |= va; pgoff = 0; } best_pg_bit = rdma_find_pg_bit(mask, pgsz_bitmap); @@ -179,18 +194,18 @@ EXPORT_SYMBOL(ib_umem_find_best_pgsz); /** - * ib_umem_get - Pin and DMA map userspace memory. + * __ib_umem_get - Pin and DMA map userspace memory. * - * @udata: userspace context to pin memory for + * @device: IB device to connect UMEM * @addr: userspace virtual address to start at * @size: length of region to pin * @access: IB_ACCESS_xxx flags for memory being pinned - * @dmasync: flush in-flight DMA when the memory region is written + * @peer_mem_flags: IB_PEER_MEM_xxx flags for memory being used */ -struct ib_umem *ib_umem_get(struct ib_udata *udata, unsigned long addr, - size_t size, int access, int dmasync) +struct ib_umem *__ib_umem_get(struct ib_device *device, + unsigned long addr, size_t size, int access, + unsigned long peer_mem_flags) { - struct ib_ucontext *context; struct ib_umem *umem; struct page **page_list; unsigned long lock_limit; @@ -199,21 +214,9 @@ struct mm_struct *mm; unsigned long npages; int ret; - unsigned long dma_attrs = 0; struct scatterlist *sg; unsigned int gup_flags = FOLL_WRITE; - if (!udata) - return ERR_PTR(-EIO); - - context = container_of(udata, struct uverbs_attr_bundle, driver_udata) - ->context; - if (!context) - return ERR_PTR(-EIO); - - if (dmasync) - dma_attrs |= DMA_ATTR_WRITE_BARRIER; - /* * If the combination of the addr and size requested for this memory * region causes an integer overflow, return error. @@ -231,7 +234,7 @@ umem = kzalloc(sizeof(*umem), GFP_KERNEL); if (!umem) return ERR_PTR(-ENOMEM); - umem->ibdev = context->device; + umem->ibdev = device; umem->length = size; umem->address = addr; umem->writable = ib_access_writable(access); @@ -286,7 +289,7 @@ npages -= ret; sg = ib_umem_add_sg_table(sg, page_list, ret, - dma_get_max_seg_size(context->device->dma_device), + dma_get_max_seg_size(device->dma_device), &umem->sg_nents); up_read(&mm->mmap_sem); @@ -294,11 +297,10 @@ sg_mark_end(sg); - umem->nmap = ib_dma_map_sg_attrs(context->device, - umem->sg_head.sgl, - umem->sg_nents, - DMA_BIDIRECTIONAL, - dma_attrs); + umem->nmap = ib_dma_map_sg(device, + umem->sg_head.sgl, + umem->sg_nents, + DMA_BIDIRECTIONAL); if (!umem->nmap) { ret = -ENOMEM; @@ -309,7 +311,25 @@ goto out; umem_release: - __ib_umem_release(context->device, umem, 0); + __ib_umem_release(device, umem, 0); + /* + * If the address belongs to peer memory client, then the first + * call to get_user_pages will fail. In this case, try to get + * these pages from the peers. + */ + //FIXME: this placement is horrible + if (ret < 0 && peer_mem_flags & IB_PEER_MEM_ALLOW) { + struct ib_umem *new_umem; + + new_umem = ib_peer_umem_get(umem, ret, peer_mem_flags); + if (IS_ERR(new_umem)) { + ret = PTR_ERR(new_umem); + goto vma; + } + umem = new_umem; + ret = 0; + goto out; + } vma: atomic64_sub(ib_umem_num_pages(umem), &mm->pinned_vm); out: @@ -321,8 +341,23 @@ } return ret ? ERR_PTR(ret) : umem; } + +struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, + size_t size, int access) +{ + return __ib_umem_get(device, addr, size, access, 0); +} EXPORT_SYMBOL(ib_umem_get); +struct ib_umem *ib_umem_get_peer(struct ib_device *device, unsigned long addr, + size_t size, int access, + unsigned long peer_mem_flags) +{ + return __ib_umem_get(device, addr, size, access, + IB_PEER_MEM_ALLOW | peer_mem_flags); +} +EXPORT_SYMBOL(ib_umem_get_peer); + /** * ib_umem_release - release memory pinned with ib_umem_get * @umem: umem struct to release @@ -334,6 +369,8 @@ if (umem->is_odp) return ib_umem_odp_release(to_ib_umem_odp(umem)); + if (umem->is_peer) + return ib_peer_umem_release(umem); __ib_umem_release(umem->ibdev, umem, 1); atomic64_sub(ib_umem_num_pages(umem), &umem->owning_mm->pinned_vm); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/umem_odp.c +++ linux-oracle-5.4.0/drivers/infiniband/core/umem_odp.c @@ -287,15 +287,12 @@ * They exist only to hold the per_mm reference to help the driver create * children umems. * - * @udata: udata from the syscall being used to create the umem + * @device: IB device to create UMEM * @access: ib_reg_mr access flags */ -struct ib_umem_odp *ib_umem_odp_alloc_implicit(struct ib_udata *udata, +struct ib_umem_odp *ib_umem_odp_alloc_implicit(struct ib_device *device, int access) { - struct ib_ucontext *context = - container_of(udata, struct uverbs_attr_bundle, driver_udata) - ->context; struct ib_umem *umem; struct ib_umem_odp *umem_odp; int ret; @@ -303,16 +300,14 @@ if (access & IB_ACCESS_HUGETLB) return ERR_PTR(-EINVAL); - if (!context) - return ERR_PTR(-EIO); - if (WARN_ON_ONCE(!context->device->ops.invalidate_range)) + if (WARN_ON_ONCE(!device->ops.invalidate_range)) return ERR_PTR(-EINVAL); umem_odp = kzalloc(sizeof(*umem_odp), GFP_KERNEL); if (!umem_odp) return ERR_PTR(-ENOMEM); umem = &umem_odp->umem; - umem->ibdev = context->device; + umem->ibdev = device; umem->writable = ib_access_writable(access); umem->owning_mm = current->mm; umem_odp->is_implicit_odp = 1; @@ -361,19 +356,33 @@ umem->owning_mm = root->umem.owning_mm; odp_data->page_shift = PAGE_SHIFT; - ret = ib_init_umem_odp(odp_data); - if (ret) { - kfree(odp_data); - return ERR_PTR(ret); + /* + * A mmget must be held when registering a notifier, the owming_mm only + * has a mm_grab at this point. + */ + if (!mmget_not_zero(umem->owning_mm)) { + ret = -EFAULT; + goto out_free; } + + ret = ib_init_umem_odp(odp_data); + if (ret) + goto out_mmput; + mmput(umem->owning_mm); return odp_data; + +out_mmput: + mmput(umem->owning_mm); +out_free: + kfree(odp_data); + return ERR_PTR(ret); } EXPORT_SYMBOL(ib_umem_odp_alloc_child); /** * ib_umem_odp_get - Create a umem_odp for a userspace va * - * @udata: userspace context to pin memory for + * @device: IB device struct to get UMEM * @addr: userspace virtual address to start at * @size: length of region to pin * @access: IB_ACCESS_xxx flags for memory being pinned @@ -382,31 +391,23 @@ * pinning, instead, stores the mm for future page fault handling in * conjunction with MMU notifiers. */ -struct ib_umem_odp *ib_umem_odp_get(struct ib_udata *udata, unsigned long addr, - size_t size, int access) +struct ib_umem_odp *ib_umem_odp_get(struct ib_device *device, + unsigned long addr, size_t size, + int access) { struct ib_umem_odp *umem_odp; - struct ib_ucontext *context; struct mm_struct *mm; int ret; - if (!udata) - return ERR_PTR(-EIO); - - context = container_of(udata, struct uverbs_attr_bundle, driver_udata) - ->context; - if (!context) - return ERR_PTR(-EIO); - if (WARN_ON_ONCE(!(access & IB_ACCESS_ON_DEMAND)) || - WARN_ON_ONCE(!context->device->ops.invalidate_range)) + WARN_ON_ONCE(!device->ops.invalidate_range)) return ERR_PTR(-EINVAL); umem_odp = kzalloc(sizeof(struct ib_umem_odp), GFP_KERNEL); if (!umem_odp) return ERR_PTR(-ENOMEM); - umem_odp->umem.ibdev = context->device; + umem_odp->umem.ibdev = device; umem_odp->umem.length = size; umem_odp->umem.address = addr; umem_odp->umem.writable = ib_access_writable(access); @@ -632,7 +633,7 @@ while (bcnt > 0) { const size_t gup_num_pages = min_t(size_t, - (bcnt + BIT(page_shift) - 1) >> page_shift, + ALIGN(bcnt, PAGE_SIZE) / PAGE_SIZE, PAGE_SIZE / sizeof(struct page *)); down_read(&owning_mm->mmap_sem); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/user_mad.c +++ linux-oracle-5.4.0/drivers/infiniband/core/user_mad.c @@ -63,6 +63,8 @@ MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); MODULE_LICENSE("Dual BSD/GPL"); +#define MAX_UMAD_RECV_LIST_SIZE 200000 + enum { IB_UMAD_MAX_PORTS = RDMA_MAX_PORTS, IB_UMAD_MAX_AGENTS = 32, @@ -113,6 +115,7 @@ struct mutex mutex; struct ib_umad_port *port; struct list_head recv_list; + atomic_t recv_list_size; struct list_head send_list; struct list_head port_list; spinlock_t send_lock; @@ -131,6 +134,11 @@ struct ib_user_mad mad; }; +struct ib_rmpp_mad_hdr { + struct ib_mad_hdr mad_hdr; + struct ib_rmpp_hdr rmpp_hdr; +} __packed; + #define CREATE_TRACE_POINTS #include @@ -175,24 +183,28 @@ return file->agents_dead ? NULL : file->agent[id]; } -static int queue_packet(struct ib_umad_file *file, - struct ib_mad_agent *agent, - struct ib_umad_packet *packet) +static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent, + struct ib_umad_packet *packet, bool is_recv_mad) { int ret = 1; mutex_lock(&file->mutex); + if (is_recv_mad && + atomic_read(&file->recv_list_size) > MAX_UMAD_RECV_LIST_SIZE) + goto unlock; + for (packet->mad.hdr.id = 0; packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; packet->mad.hdr.id++) if (agent == __get_agent(file, packet->mad.hdr.id)) { list_add_tail(&packet->list, &file->recv_list); + atomic_inc(&file->recv_list_size); wake_up_interruptible(&file->recv_wait); ret = 0; break; } - +unlock: mutex_unlock(&file->mutex); return ret; @@ -219,7 +231,7 @@ if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { packet->length = IB_MGMT_MAD_HDR; packet->mad.hdr.status = ETIMEDOUT; - if (!queue_packet(file, agent, packet)) + if (!queue_packet(file, agent, packet, false)) return; } kfree(packet); @@ -279,7 +291,7 @@ rdma_destroy_ah_attr(&ah_attr); } - if (queue_packet(file, agent, packet)) + if (queue_packet(file, agent, packet, true)) goto err2; return; @@ -379,6 +391,11 @@ mutex_lock(&file->mutex); + if (file->agents_dead) { + mutex_unlock(&file->mutex); + return -EIO; + } + while (list_empty(&file->recv_list)) { mutex_unlock(&file->mutex); @@ -392,8 +409,14 @@ mutex_lock(&file->mutex); } + if (file->agents_dead) { + mutex_unlock(&file->mutex); + return -EIO; + } + packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); list_del(&packet->list); + atomic_dec(&file->recv_list_size); mutex_unlock(&file->mutex); @@ -406,6 +429,7 @@ /* Requeue packet */ mutex_lock(&file->mutex); list_add(&packet->list, &file->recv_list); + atomic_inc(&file->recv_list_size); mutex_unlock(&file->mutex); } else { if (packet->recv_wc) @@ -484,11 +508,11 @@ size_t count, loff_t *pos) { struct ib_umad_file *file = filp->private_data; + struct ib_rmpp_mad_hdr *rmpp_mad_hdr; struct ib_umad_packet *packet; struct ib_mad_agent *agent; struct rdma_ah_attr ah_attr; struct ib_ah *ah; - struct ib_rmpp_mad *rmpp_mad; __be64 *tid; int ret, data_len, hdr_len, copy_offset, rmpp_active; u8 base_version; @@ -496,7 +520,7 @@ if (count < hdr_size(file) + IB_MGMT_RMPP_HDR) return -EINVAL; - packet = kzalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); + packet = kzalloc(sizeof(*packet) + IB_MGMT_RMPP_HDR, GFP_KERNEL); if (!packet) return -ENOMEM; @@ -524,7 +548,7 @@ agent = __get_agent(file, packet->mad.hdr.id); if (!agent) { - ret = -EINVAL; + ret = -EIO; goto err_up; } @@ -550,13 +574,13 @@ goto err_up; } - rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; - hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); + rmpp_mad_hdr = (struct ib_rmpp_mad_hdr *)packet->mad.data; + hdr_len = ib_get_mad_data_offset(rmpp_mad_hdr->mad_hdr.mgmt_class); - if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) + if (ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class) && ib_mad_kernel_rmpp_agent(agent)) { copy_offset = IB_MGMT_RMPP_HDR; - rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & + rmpp_active = ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE; } else { copy_offset = IB_MGMT_MAD_HDR; @@ -605,12 +629,12 @@ tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | (be64_to_cpup(tid) & 0xffffffff)); - rmpp_mad->mad_hdr.tid = *tid; + rmpp_mad_hdr->mad_hdr.tid = *tid; } if (!ib_mad_kernel_rmpp_agent(agent) - && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) - && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { + && ib_is_mad_class_rmpp(rmpp_mad_hdr->mad_hdr.mgmt_class) + && (ib_get_rmpp_flags(&rmpp_mad_hdr->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { spin_lock_irq(&file->send_lock); list_add_tail(&packet->list, &file->send_list); spin_unlock_irq(&file->send_lock); @@ -653,10 +677,14 @@ /* we will always be able to post a MAD send */ __poll_t mask = EPOLLOUT | EPOLLWRNORM; + mutex_lock(&file->mutex); poll_wait(filp, &file->recv_wait, wait); if (!list_empty(&file->recv_list)) mask |= EPOLLIN | EPOLLRDNORM; + if (file->agents_dead) + mask = EPOLLERR; + mutex_unlock(&file->mutex); return mask; } @@ -1129,17 +1157,30 @@ .llseek = no_llseek, }; +static struct ib_umad_port *get_port(struct ib_device *ibdev, + struct ib_umad_device *umad_dev, + unsigned int port) +{ + if (!umad_dev) + return ERR_PTR(-EOPNOTSUPP); + if (!rdma_is_port_valid(ibdev, port)) + return ERR_PTR(-EINVAL); + if (!rdma_cap_ib_mad(ibdev, port)) + return ERR_PTR(-EOPNOTSUPP); + + return &umad_dev->ports[port - rdma_start_port(ibdev)]; +} + static int ib_umad_get_nl_info(struct ib_device *ibdev, void *client_data, struct ib_client_nl_info *res) { - struct ib_umad_device *umad_dev = client_data; + struct ib_umad_port *port = get_port(ibdev, client_data, res->port); - if (!rdma_is_port_valid(ibdev, res->port)) - return -EINVAL; + if (IS_ERR(port)) + return PTR_ERR(port); res->abi = IB_USER_MAD_ABI_VERSION; - res->cdev = &umad_dev->ports[res->port - rdma_start_port(ibdev)].dev; - + res->cdev = &port->dev; return 0; } @@ -1154,15 +1195,13 @@ static int ib_issm_get_nl_info(struct ib_device *ibdev, void *client_data, struct ib_client_nl_info *res) { - struct ib_umad_device *umad_dev = - ib_get_client_data(ibdev, &umad_client); + struct ib_umad_port *port = get_port(ibdev, client_data, res->port); - if (!rdma_is_port_valid(ibdev, res->port)) - return -EINVAL; + if (IS_ERR(port)) + return PTR_ERR(port); res->abi = IB_USER_MAD_ABI_VERSION; - res->cdev = &umad_dev->ports[res->port - rdma_start_port(ibdev)].sm_dev; - + res->cdev = &port->sm_dev; return 0; } @@ -1312,6 +1351,9 @@ struct ib_umad_file *file; int id; + cdev_device_del(&port->sm_cdev, &port->sm_dev); + cdev_device_del(&port->cdev, &port->dev); + mutex_lock(&port->file_mutex); /* Mark ib_dev NULL and block ioctl or other file ops to progress @@ -1322,6 +1364,7 @@ list_for_each_entry(file, &port->file_list, port_list) { mutex_lock(&file->mutex); file->agents_dead = 1; + wake_up_interruptible(&file->recv_wait); mutex_unlock(&file->mutex); for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) @@ -1331,8 +1374,6 @@ mutex_unlock(&port->file_mutex); - cdev_device_del(&port->sm_cdev, &port->sm_dev); - cdev_device_del(&port->cdev, &port->dev); ida_free(&umad_ida, port->dev_num); /* balances device_initialize() */ --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_cmd.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_cmd.c @@ -161,7 +161,7 @@ { const void __user *res = iter->cur; - if (iter->cur + len > iter->end) + if (len > iter->end - iter->cur) return (void __force __user *)ERR_PTR(-ENOSPC); iter->cur += len; return res; @@ -252,6 +252,8 @@ ucontext->closing = false; ucontext->cleanup_retryable = false; + xa_init_flags(&ucontext->mmap_xa, XA_FLAGS_ALLOC); + ret = get_unused_fd_flags(O_CLOEXEC); if (ret < 0) goto err_free; @@ -757,6 +759,7 @@ mr->uobject = uobj; atomic_inc(&pd->usecnt); mr->res.type = RDMA_RESTRACK_MR; + mr->iova = cmd.hca_va; rdma_restrack_uadd(&mr->res); uobj->object = mr; @@ -847,6 +850,9 @@ atomic_dec(&old_pd->usecnt); } + if (cmd.flags & IB_MR_REREG_TRANS) + mr->iova = cmd.hca_va; + memset(&resp, 0, sizeof(resp)); resp.lkey = mr->lkey; resp.rkey = mr->rkey; @@ -1431,17 +1437,7 @@ if (ret) goto err_cb; - qp->pd = pd; - qp->send_cq = attr.send_cq; - qp->recv_cq = attr.recv_cq; - qp->srq = attr.srq; - qp->rwq_ind_tbl = ind_tbl; - qp->event_handler = attr.event_handler; - qp->qp_context = attr.qp_context; - qp->qp_type = attr.qp_type; - atomic_set(&qp->usecnt, 0); atomic_inc(&pd->usecnt); - qp->port = 0; if (attr.send_cq) atomic_inc(&attr.send_cq->usecnt); if (attr.recv_cq) @@ -1563,7 +1559,7 @@ struct ib_uverbs_create_qp_resp resp; struct ib_uqp_object *obj; struct ib_xrcd *xrcd; - struct ib_uobject *uninitialized_var(xrcd_uobj); + struct ib_uobject *xrcd_uobj; struct ib_qp *qp; struct ib_qp_open_attr attr; int ret; @@ -1869,8 +1865,13 @@ attr->path_mtu = cmd->base.path_mtu; if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE) attr->path_mig_state = cmd->base.path_mig_state; - if (cmd->base.attr_mask & IB_QP_QKEY) + if (cmd->base.attr_mask & IB_QP_QKEY) { + if (cmd->base.qkey & IB_QP_SET_QKEY && !capable(CAP_NET_RAW)) { + ret = -EPERM; + goto release_qp; + } attr->qkey = cmd->base.qkey; + } if (cmd->base.attr_mask & IB_QP_RQ_PSN) attr->rq_psn = cmd->base.rq_psn; if (cmd->base.attr_mask & IB_QP_SQ_PSN) @@ -1958,7 +1959,7 @@ * Last bit is reserved for extending the attr_mask by * using another field. */ - BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1 << 31)); + BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1ULL << 31)); if (cmd.base.attr_mask & ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1)) @@ -2025,11 +2026,13 @@ ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd)); if (ret) return ret; - wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count); + wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size, + cmd.wr_count)); if (IS_ERR(wqes)) return PTR_ERR(wqes); - sgls = uverbs_request_next_ptr( - &iter, cmd.sge_count * sizeof(struct ib_uverbs_sge)); + sgls = uverbs_request_next_ptr(&iter, + size_mul(cmd.sge_count, + sizeof(struct ib_uverbs_sge))); if (IS_ERR(sgls)) return PTR_ERR(sgls); ret = uverbs_request_finish(&iter); @@ -2214,11 +2217,11 @@ if (wqe_size < sizeof (struct ib_uverbs_recv_wr)) return ERR_PTR(-EINVAL); - wqes = uverbs_request_next_ptr(iter, wqe_size * wr_count); + wqes = uverbs_request_next_ptr(iter, size_mul(wqe_size, wr_count)); if (IS_ERR(wqes)) return ERR_CAST(wqes); - sgls = uverbs_request_next_ptr( - iter, sge_count * sizeof(struct ib_uverbs_sge)); + sgls = uverbs_request_next_ptr(iter, size_mul(sge_count, + sizeof(struct ib_uverbs_sge))); if (IS_ERR(sgls)) return ERR_CAST(sgls); ret = uverbs_request_finish(iter); @@ -2718,12 +2721,6 @@ return 0; } -static size_t kern_spec_filter_sz(const struct ib_uverbs_flow_spec_hdr *spec) -{ - /* Returns user space filter size, includes padding */ - return (spec->size - sizeof(struct ib_uverbs_flow_spec_hdr)) / 2; -} - static ssize_t spec_filter_size(const void *kern_spec_filter, u16 kern_filter_size, u16 ib_real_filter_sz) { @@ -2867,11 +2864,16 @@ static int kern_spec_to_ib_spec_filter(struct ib_uverbs_flow_spec *kern_spec, union ib_flow_spec *ib_spec) { - ssize_t kern_filter_sz; + size_t kern_filter_sz; void *kern_spec_mask; void *kern_spec_val; - kern_filter_sz = kern_spec_filter_sz(&kern_spec->hdr); + if (check_sub_overflow((size_t)kern_spec->hdr.size, + sizeof(struct ib_uverbs_flow_spec_hdr), + &kern_filter_sz)) + return -EINVAL; + + kern_filter_sz /= 2; kern_spec_val = (void *)kern_spec + sizeof(struct ib_uverbs_flow_spec_hdr); @@ -3038,12 +3040,29 @@ if (!wq) return -EINVAL; - wq_attr.curr_wq_state = cmd.curr_wq_state; - wq_attr.wq_state = cmd.wq_state; if (cmd.attr_mask & IB_WQ_FLAGS) { wq_attr.flags = cmd.flags; wq_attr.flags_mask = cmd.flags_mask; } + + if (cmd.attr_mask & IB_WQ_CUR_STATE) { + if (cmd.curr_wq_state > IB_WQS_ERR) + return -EINVAL; + + wq_attr.curr_wq_state = cmd.curr_wq_state; + } else { + wq_attr.curr_wq_state = wq->state; + } + + if (cmd.attr_mask & IB_WQ_STATE) { + if (cmd.wq_state > IB_WQS_ERR) + return -EINVAL; + + wq_attr.wq_state = cmd.wq_state; + } else { + wq_attr.wq_state = wq_attr.curr_wq_state; + } + ret = wq->device->ops.modify_wq(wq, &wq_attr, cmd.attr_mask, &attrs->driver_udata); uobj_put_obj_read(wq); @@ -3368,7 +3387,7 @@ struct ib_usrq_object *obj; struct ib_pd *pd; struct ib_srq *srq; - struct ib_uobject *uninitialized_var(xrcd_uobj); + struct ib_uobject *xrcd_uobj; struct ib_srq_init_attr attr; int ret; struct ib_device *ib_dev; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_main.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_main.c @@ -220,7 +220,6 @@ } static ssize_t ib_uverbs_event_read(struct ib_uverbs_event_queue *ev_queue, - struct ib_uverbs_file *uverbs_file, struct file *filp, char __user *buf, size_t count, loff_t *pos, size_t eventsz) @@ -231,25 +230,20 @@ spin_lock_irq(&ev_queue->lock); while (list_empty(&ev_queue->event_list)) { - spin_unlock_irq(&ev_queue->lock); + if (ev_queue->is_closed) { + spin_unlock_irq(&ev_queue->lock); + return -EIO; + } + spin_unlock_irq(&ev_queue->lock); if (filp->f_flags & O_NONBLOCK) return -EAGAIN; if (wait_event_interruptible(ev_queue->poll_wait, (!list_empty(&ev_queue->event_list) || - /* The barriers built into wait_event_interruptible() - * and wake_up() guarentee this will see the null set - * without using RCU - */ - !uverbs_file->device->ib_dev))) + ev_queue->is_closed))) return -ERESTARTSYS; - /* If device was disassociated and no event exists set an error */ - if (list_empty(&ev_queue->event_list) && - !uverbs_file->device->ib_dev) - return -EIO; - spin_lock_irq(&ev_queue->lock); } @@ -285,8 +279,7 @@ { struct ib_uverbs_async_event_file *file = filp->private_data; - return ib_uverbs_event_read(&file->ev_queue, file->uverbs_file, filp, - buf, count, pos, + return ib_uverbs_event_read(&file->ev_queue, filp, buf, count, pos, sizeof(struct ib_uverbs_async_event_desc)); } @@ -296,9 +289,8 @@ struct ib_uverbs_completion_event_file *comp_ev_file = filp->private_data; - return ib_uverbs_event_read(&comp_ev_file->ev_queue, - comp_ev_file->uobj.ufile, filp, - buf, count, pos, + return ib_uverbs_event_read(&comp_ev_file->ev_queue, filp, buf, count, + pos, sizeof(struct ib_uverbs_comp_event_desc)); } @@ -313,6 +305,8 @@ spin_lock_irq(&ev_queue->lock); if (!list_empty(&ev_queue->event_list)) pollflags = EPOLLIN | EPOLLRDNORM; + else if (ev_queue->is_closed) + pollflags = EPOLLERR; spin_unlock_irq(&ev_queue->lock); return pollflags; @@ -321,7 +315,9 @@ static __poll_t ib_uverbs_async_event_poll(struct file *filp, struct poll_table_struct *wait) { - return ib_uverbs_event_poll(filp->private_data, filp, wait); + struct ib_uverbs_async_event_file *file = filp->private_data; + + return ib_uverbs_event_poll(&file->ev_queue, filp, wait); } static __poll_t ib_uverbs_comp_event_poll(struct file *filp, @@ -335,9 +331,9 @@ static int ib_uverbs_async_event_fasync(int fd, struct file *filp, int on) { - struct ib_uverbs_event_queue *ev_queue = filp->private_data; + struct ib_uverbs_async_event_file *file = filp->private_data; - return fasync_helper(fd, filp, on, &ev_queue->async_queue); + return fasync_helper(fd, filp, on, &file->ev_queue.async_queue); } static int ib_uverbs_comp_event_fasync(int fd, struct file *filp, int on) @@ -637,7 +633,7 @@ if (hdr->in_words * 4 != count) return -EINVAL; - if (count < method_elm->req_size + sizeof(hdr)) { + if (count < method_elm->req_size + sizeof(*hdr)) { /* * rdma-core v18 and v19 have a bug where they send DESTROY_CQ * with a 16 byte write instead of 24. Old kernels didn't @@ -772,6 +768,8 @@ return (ret) ? : count; } +static const struct vm_operations_struct rdma_umap_ops; + static int ib_uverbs_mmap(struct file *filp, struct vm_area_struct *vma) { struct ib_uverbs_file *file = filp->private_data; @@ -785,7 +783,7 @@ ret = PTR_ERR(ucontext); goto out; } - + vma->vm_ops = &rdma_umap_ops; ret = ucontext->device->ops.mmap(ucontext, vma); out: srcu_read_unlock(&file->device->disassociate_srcu, srcu_key); @@ -793,38 +791,6 @@ } /* - * Each time we map IO memory into user space this keeps track of the mapping. - * When the device is hot-unplugged we 'zap' the mmaps in user space to point - * to the zero page and allow the hot unplug to proceed. - * - * This is necessary for cases like PCI physical hot unplug as the actual BAR - * memory may vanish after this and access to it from userspace could MCE. - * - * RDMA drivers supporting disassociation must have their user space designed - * to cope in some way with their IO pages going to the zero page. - */ -struct rdma_umap_priv { - struct vm_area_struct *vma; - struct list_head list; -}; - -static const struct vm_operations_struct rdma_umap_ops; - -static void rdma_umap_priv_init(struct rdma_umap_priv *priv, - struct vm_area_struct *vma) -{ - struct ib_uverbs_file *ufile = vma->vm_file->private_data; - - priv->vma = vma; - vma->vm_private_data = priv; - vma->vm_ops = &rdma_umap_ops; - - mutex_lock(&ufile->umap_lock); - list_add(&priv->list, &ufile->umaps); - mutex_unlock(&ufile->umap_lock); -} - -/* * The VMA has been dup'd, initialize the vm_private_data with a new tracking * struct */ @@ -849,7 +815,7 @@ priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) goto out_unlock; - rdma_umap_priv_init(priv, vma); + rdma_umap_priv_init(priv, vma, opriv->entry); up_read(&ufile->hw_destroy_rwsem); return; @@ -880,6 +846,9 @@ * this point. */ mutex_lock(&ufile->umap_lock); + if (priv->entry) + rdma_user_mmap_entry_put(priv->entry); + list_del(&priv->list); mutex_unlock(&ufile->umap_lock); kfree(priv); @@ -931,44 +900,6 @@ .fault = rdma_umap_fault, }; -/* - * Map IO memory into a process. This is to be called by drivers as part of - * their mmap() functions if they wish to send something like PCI-E BAR memory - * to userspace. - */ -int rdma_user_mmap_io(struct ib_ucontext *ucontext, struct vm_area_struct *vma, - unsigned long pfn, unsigned long size, pgprot_t prot) -{ - struct ib_uverbs_file *ufile = ucontext->ufile; - struct rdma_umap_priv *priv; - - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - if (vma->vm_end - vma->vm_start != size) - return -EINVAL; - - /* Driver is using this wrong, must be called by ib_uverbs_mmap */ - if (WARN_ON(!vma->vm_file || - vma->vm_file->private_data != ufile)) - return -EINVAL; - lockdep_assert_held(&ufile->device->disassociate_srcu); - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - vma->vm_page_prot = prot; - if (io_remap_pfn_range(vma, vma->vm_start, pfn, size, prot)) { - kfree(priv); - return -EAGAIN; - } - - rdma_umap_priv_init(priv, vma); - return 0; -} -EXPORT_SYMBOL(rdma_user_mmap_io); - void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile) { struct rdma_umap_priv *priv, *next_priv; @@ -1018,6 +949,11 @@ zap_vma_ptes(vma, vma->vm_start, vma->vm_end - vma->vm_start); + + if (priv->entry) { + rdma_user_mmap_entry_put(priv->entry); + priv->entry = NULL; + } } mutex_unlock(&ufile->umap_lock); skip_mm: --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_marshall.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_marshall.c @@ -66,7 +66,7 @@ struct rdma_ah_attr *src = ah_attr; struct rdma_ah_attr conv_ah; - memset(&dst->grh.reserved, 0, sizeof(dst->grh.reserved)); + memset(&dst->grh, 0, sizeof(dst->grh)); if ((ah_attr->type == RDMA_AH_ATTR_TYPE_OPA) && (rdma_ah_get_dlid(ah_attr) > be16_to_cpu(IB_LID_PERMISSIVE)) && --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_std_types_counters.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_std_types_counters.c @@ -105,6 +105,8 @@ return ret; uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF); + if (IS_ERR(uattr)) + return PTR_ERR(uattr); read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64); read_attr.counters_buff = uverbs_zalloc( attrs, array_size(read_attr.ncounters, sizeof(u64))); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_std_types_device.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_std_types_device.c @@ -110,8 +110,8 @@ return ret; uapi_object = uapi_get_object(attrs->ufile->device->uapi, object_id); - if (!uapi_object) - return -EINVAL; + if (IS_ERR(uapi_object)) + return PTR_ERR(uapi_object); handles = gather_objects_handle(attrs->ufile, uapi_object, attrs, out_len, &total); --- linux-oracle-5.4.0.orig/drivers/infiniband/core/uverbs_uapi.c +++ linux-oracle-5.4.0/drivers/infiniband/core/uverbs_uapi.c @@ -450,6 +450,9 @@ uapi->num_write_ex = max_write_ex + 1; data = kmalloc_array(uapi->num_write + uapi->num_write_ex, sizeof(*uapi->write_methods), GFP_KERNEL); + if (!data) + return -ENOMEM; + for (i = 0; i != uapi->num_write + uapi->num_write_ex; i++) data[i] = &uapi->notsupp_method; uapi->write_methods = data; --- linux-oracle-5.4.0.orig/drivers/infiniband/core/verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/core/verbs.c @@ -521,6 +521,8 @@ ret = device->ops.create_ah(ah, ah_attr, flags, udata); if (ret) { + if (ah->sgid_attr) + rdma_put_gid_attr(ah->sgid_attr); kfree(ah); return ERR_PTR(ret); } @@ -1180,16 +1182,6 @@ if (ret) goto err; - qp->qp_type = qp_init_attr->qp_type; - qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; - - atomic_set(&qp->usecnt, 0); - qp->mrs_used = 0; - spin_lock_init(&qp->mr_lock); - INIT_LIST_HEAD(&qp->rdma_mrs); - INIT_LIST_HEAD(&qp->sig_mrs); - qp->port = 0; - if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { struct ib_qp *xrc_qp = create_xrc_qp_user(qp, qp_init_attr, udata); @@ -1658,7 +1650,7 @@ if (!(rdma_protocol_ib(qp->device, attr->alt_ah_attr.port_num) && rdma_protocol_ib(qp->device, port))) { - ret = EINVAL; + ret = -EINVAL; goto out; } } @@ -1759,7 +1751,7 @@ dev_put(netdev); - if (!rc) { + if (!rc && lksettings.base.speed != (u32)SPEED_UNKNOWN) { netdev_speed = lksettings.base.speed; } else { netdev_speed = SPEED_1000; @@ -2850,15 +2842,18 @@ bool __rdma_block_iter_next(struct ib_block_iter *biter) { unsigned int block_offset; + unsigned int sg_delta; if (!biter->__sg_nents || !biter->__sg) return false; biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance; block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1); - biter->__sg_advance += BIT_ULL(biter->__pg_bit) - block_offset; + sg_delta = BIT_ULL(biter->__pg_bit) - block_offset; - if (biter->__sg_advance >= sg_dma_len(biter->__sg)) { + if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) { + biter->__sg_advance += sg_delta; + } else { biter->__sg_advance = 0; biter->__sg = sg_next(biter->__sg); biter->__sg_nents--; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/bnxt_re.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/bnxt_re.h @@ -104,10 +104,19 @@ struct bnxt_re_qp *qp1_qp; }; +#define BNXT_RE_MAX_GSI_SQP_ENTRIES 1024 +struct bnxt_re_gsi_context { + struct bnxt_re_qp *gsi_qp; + struct bnxt_re_qp *gsi_sqp; + struct bnxt_re_ah *gsi_sah; + struct bnxt_re_sqp_entries *sqp_tbl; +}; + #define BNXT_RE_MIN_MSIX 2 #define BNXT_RE_MAX_MSIX 9 #define BNXT_RE_AEQ_IDX 0 #define BNXT_RE_NQ_IDX 1 +#define BNXT_RE_GEN_P5_MAX_VF 64 struct bnxt_re_dev { struct ib_device ibdev; @@ -164,10 +173,7 @@ u16 cosq[2]; /* QP for for handling QP1 packets */ - u32 sqp_id; - struct bnxt_re_qp *qp1_sqp; - struct bnxt_re_ah *sqp_ah; - struct bnxt_re_sqp_entries sqp_tbl[1024]; + struct bnxt_re_gsi_context gsi_ctx; atomic_t nq_alloc_cnt; u32 is_virtfn; u32 num_vfs; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -137,7 +137,7 @@ ib_attr->vendor_id = rdev->en_dev->pdev->vendor; ib_attr->vendor_part_id = rdev->en_dev->pdev->device; - ib_attr->hw_ver = rdev->en_dev->pdev->subsystem_device; + ib_attr->hw_ver = rdev->en_dev->pdev->revision; ib_attr->max_qp = dev_attr->max_qp; ib_attr->max_qp_wr = dev_attr->max_qp_wqes; ib_attr->device_cap_flags = @@ -330,7 +330,7 @@ */ if (ctx->idx == 0 && rdma_link_local_addr((struct in6_addr *)gid_to_del) && - ctx->refcnt == 1 && rdev->qp1_sqp) { + ctx->refcnt == 1 && rdev->gsi_ctx.gsi_sqp) { dev_dbg(rdev_to_dev(rdev), "Trying to delete GID0 while QP1 is alive\n"); return -EFAULT; @@ -760,6 +760,49 @@ spin_unlock_irqrestore(&qp->scq->cq_lock, flags); } +static int bnxt_re_destroy_gsi_sqp(struct bnxt_re_qp *qp) +{ + struct bnxt_re_qp *gsi_sqp; + struct bnxt_re_ah *gsi_sah; + struct bnxt_re_dev *rdev; + int rc = 0; + + rdev = qp->rdev; + gsi_sqp = rdev->gsi_ctx.gsi_sqp; + gsi_sah = rdev->gsi_ctx.gsi_sah; + + dev_dbg(rdev_to_dev(rdev), "Destroy the shadow AH\n"); + bnxt_qplib_destroy_ah(&rdev->qplib_res, + &gsi_sah->qplib_ah, + true); + bnxt_qplib_clean_qp(&qp->qplib_qp); + + dev_dbg(rdev_to_dev(rdev), "Destroy the shadow QP\n"); + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &gsi_sqp->qplib_qp); + if (rc) { + dev_err(rdev_to_dev(rdev), "Destroy Shadow QP failed"); + goto fail; + } + bnxt_qplib_free_qp_res(&rdev->qplib_res, &gsi_sqp->qplib_qp); + + /* remove from active qp list */ + mutex_lock(&rdev->qp_lock); + list_del(&gsi_sqp->list); + mutex_unlock(&rdev->qp_lock); + atomic_dec(&rdev->qp_count); + + kfree(rdev->gsi_ctx.sqp_tbl); + kfree(gsi_sah); + kfree(gsi_sqp); + rdev->gsi_ctx.gsi_sqp = NULL; + rdev->gsi_ctx.gsi_sah = NULL; + rdev->gsi_ctx.sqp_tbl = NULL; + + return 0; +fail: + return rc; +} + /* Queue Pairs */ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) { @@ -769,6 +812,7 @@ int rc; bnxt_qplib_flush_cqn_wq(&qp->qplib_qp); + rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, &qp->qplib_qp); if (rc) { dev_err(rdev_to_dev(rdev), "Failed to destroy HW QP"); @@ -783,40 +827,24 @@ bnxt_qplib_free_qp_res(&rdev->qplib_res, &qp->qplib_qp); - if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) { - bnxt_qplib_destroy_ah(&rdev->qplib_res, &rdev->sqp_ah->qplib_ah, - false); - - bnxt_qplib_clean_qp(&qp->qplib_qp); - rc = bnxt_qplib_destroy_qp(&rdev->qplib_res, - &rdev->qp1_sqp->qplib_qp); - if (rc) { - dev_err(rdev_to_dev(rdev), - "Failed to destroy Shadow QP"); - return rc; - } - bnxt_qplib_free_qp_res(&rdev->qplib_res, - &rdev->qp1_sqp->qplib_qp); - mutex_lock(&rdev->qp_lock); - list_del(&rdev->qp1_sqp->list); - atomic_dec(&rdev->qp_count); - mutex_unlock(&rdev->qp_lock); - - kfree(rdev->sqp_ah); - kfree(rdev->qp1_sqp); - rdev->qp1_sqp = NULL; - rdev->sqp_ah = NULL; + if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) { + rc = bnxt_re_destroy_gsi_sqp(qp); + if (rc) + goto sh_fail; } - ib_umem_release(qp->rumem); - ib_umem_release(qp->sumem); - mutex_lock(&rdev->qp_lock); list_del(&qp->list); - atomic_dec(&rdev->qp_count); mutex_unlock(&rdev->qp_lock); + atomic_dec(&rdev->qp_count); + + ib_umem_release(qp->rumem); + ib_umem_release(qp->sumem); + kfree(qp); return 0; +sh_fail: + return rc; } static u8 __from_ib_qp_type(enum ib_qp_type type) @@ -855,7 +883,8 @@ bytes += (qplib_qp->sq.max_wqe * psn_sz); } bytes = PAGE_ALIGN(bytes); - umem = ib_umem_get(udata, ureq.qpsva, bytes, IB_ACCESS_LOCAL_WRITE, 1); + umem = ib_umem_get(&rdev->ibdev, ureq.qpsva, bytes, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(umem)) return PTR_ERR(umem); @@ -868,8 +897,8 @@ if (!qp->qplib_qp.srq) { bytes = (qplib_qp->rq.max_wqe * BNXT_QPLIB_MAX_RQE_ENTRY_SIZE); bytes = PAGE_ALIGN(bytes); - umem = ib_umem_get(udata, ureq.qprva, bytes, - IB_ACCESS_LOCAL_WRITE, 1); + umem = ib_umem_get(&rdev->ibdev, ureq.qprva, bytes, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(umem)) goto rqfail; qp->rumem = umem; @@ -984,8 +1013,6 @@ if (rc) goto fail; - rdev->sqp_id = qp->qplib_qp.id; - spin_lock_init(&qp->sq_lock); INIT_LIST_HEAD(&qp->list); mutex_lock(&rdev->qp_lock); @@ -998,205 +1025,375 @@ return NULL; } -struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, - struct ib_qp_init_attr *qp_init_attr, - struct ib_udata *udata) +static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, + struct ib_qp_init_attr *init_attr) { - struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); - struct bnxt_re_dev *rdev = pd->rdev; - struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; - struct bnxt_re_qp *qp; - struct bnxt_re_cq *cq; - struct bnxt_re_srq *srq; - int rc, entries; + struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_qplib_qp *qplqp; + struct bnxt_re_dev *rdev; + int entries; - if ((qp_init_attr->cap.max_send_wr > dev_attr->max_qp_wqes) || - (qp_init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes) || - (qp_init_attr->cap.max_send_sge > dev_attr->max_qp_sges) || - (qp_init_attr->cap.max_recv_sge > dev_attr->max_qp_sges) || - (qp_init_attr->cap.max_inline_data > dev_attr->max_inline_data)) - return ERR_PTR(-EINVAL); + rdev = qp->rdev; + qplqp = &qp->qplib_qp; + dev_attr = &rdev->dev_attr; - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) - return ERR_PTR(-ENOMEM); + if (init_attr->srq) { + struct bnxt_re_srq *srq; - qp->rdev = rdev; - ether_addr_copy(qp->qplib_qp.smac, rdev->netdev->dev_addr); - qp->qplib_qp.pd = &pd->qplib_pd; - qp->qplib_qp.qp_handle = (u64)(unsigned long)(&qp->qplib_qp); - qp->qplib_qp.type = __from_ib_qp_type(qp_init_attr->qp_type); + srq = container_of(init_attr->srq, struct bnxt_re_srq, ib_srq); + if (!srq) { + dev_err(rdev_to_dev(rdev), "SRQ not found"); + return -EINVAL; + } + qplqp->srq = &srq->qplib_srq; + qplqp->rq.max_wqe = 0; + } else { + /* Allocate 1 more than what's provided so posting max doesn't + * mean empty. + */ + entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1); + qplqp->rq.max_wqe = min_t(u32, entries, + dev_attr->max_qp_wqes + 1); - if (qp_init_attr->qp_type == IB_QPT_GSI && - bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) - qp->qplib_qp.type = CMDQ_CREATE_QP_TYPE_GSI; - if (qp->qplib_qp.type == IB_QPT_MAX) { + qplqp->rq.q_full_delta = qplqp->rq.max_wqe - + init_attr->cap.max_recv_wr; + qplqp->rq.max_sge = init_attr->cap.max_recv_sge; + if (qplqp->rq.max_sge > dev_attr->max_qp_sges) + qplqp->rq.max_sge = dev_attr->max_qp_sges; + } + + return 0; +} + +static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp) +{ + struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_qplib_qp *qplqp; + struct bnxt_re_dev *rdev; + + rdev = qp->rdev; + qplqp = &qp->qplib_qp; + dev_attr = &rdev->dev_attr; + + qplqp->rq.max_sge = dev_attr->max_qp_sges; + if (qplqp->rq.max_sge > dev_attr->max_qp_sges) + qplqp->rq.max_sge = dev_attr->max_qp_sges; +} + +static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) +{ + struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_qplib_qp *qplqp; + struct bnxt_re_dev *rdev; + int entries; + + rdev = qp->rdev; + qplqp = &qp->qplib_qp; + dev_attr = &rdev->dev_attr; + + qplqp->sq.max_sge = init_attr->cap.max_send_sge; + if (qplqp->sq.max_sge > dev_attr->max_qp_sges) + qplqp->sq.max_sge = dev_attr->max_qp_sges; + /* + * Change the SQ depth if user has requested minimum using + * configfs. Only supported for kernel consumers + */ + entries = init_attr->cap.max_send_wr; + /* Allocate 128 + 1 more than what's provided */ + entries = roundup_pow_of_two(entries + BNXT_QPLIB_RESERVED_QP_WRS + 1); + qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + + BNXT_QPLIB_RESERVED_QP_WRS + 1); + qplqp->sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; + /* + * Reserving one slot for Phantom WQE. Application can + * post one extra entry in this case. But allowing this to avoid + * unexpected Queue full condition + */ + qplqp->sq.q_full_delta -= 1; +} + +static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, + struct ib_qp_init_attr *init_attr) +{ + struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_qplib_qp *qplqp; + struct bnxt_re_dev *rdev; + int entries; + + rdev = qp->rdev; + qplqp = &qp->qplib_qp; + dev_attr = &rdev->dev_attr; + + entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1); + qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1); + qplqp->sq.q_full_delta = qplqp->sq.max_wqe - + init_attr->cap.max_send_wr; + qplqp->sq.max_sge++; /* Need one extra sge to put UD header */ + if (qplqp->sq.max_sge > dev_attr->max_qp_sges) + qplqp->sq.max_sge = dev_attr->max_qp_sges; +} + +static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev, + struct ib_qp_init_attr *init_attr) +{ + struct bnxt_qplib_chip_ctx *chip_ctx; + int qptype; + + chip_ctx = &rdev->chip_ctx; + + qptype = __from_ib_qp_type(init_attr->qp_type); + if (qptype == IB_QPT_MAX) { dev_err(rdev_to_dev(rdev), "QP type 0x%x not supported", - qp->qplib_qp.type); - rc = -EINVAL; - goto fail; + qptype); + qptype = -EINVAL; + goto out; } - qp->qplib_qp.max_inline_data = qp_init_attr->cap.max_inline_data; - qp->qplib_qp.sig_type = ((qp_init_attr->sq_sig_type == - IB_SIGNAL_ALL_WR) ? true : false); - - qp->qplib_qp.sq.max_sge = qp_init_attr->cap.max_send_sge; - if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) - qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; - - if (qp_init_attr->send_cq) { - cq = container_of(qp_init_attr->send_cq, struct bnxt_re_cq, - ib_cq); + if (bnxt_qplib_is_chip_gen_p5(chip_ctx) && + init_attr->qp_type == IB_QPT_GSI) + qptype = CMDQ_CREATE_QP_TYPE_GSI; +out: + return qptype; +} + +static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata) +{ + struct bnxt_qplib_dev_attr *dev_attr; + struct bnxt_qplib_qp *qplqp; + struct bnxt_re_dev *rdev; + struct bnxt_re_cq *cq; + int rc = 0, qptype; + + rdev = qp->rdev; + qplqp = &qp->qplib_qp; + dev_attr = &rdev->dev_attr; + + /* Setup misc params */ + ether_addr_copy(qplqp->smac, rdev->netdev->dev_addr); + qplqp->pd = &pd->qplib_pd; + qplqp->qp_handle = (u64)qplqp; + qplqp->max_inline_data = init_attr->cap.max_inline_data; + qplqp->sig_type = ((init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? + true : false); + qptype = bnxt_re_init_qp_type(rdev, init_attr); + if (qptype < 0) { + rc = qptype; + goto out; + } + qplqp->type = (u8)qptype; + + if (init_attr->qp_type == IB_QPT_RC) { + qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom; + qplqp->max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; + } + qplqp->mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); + qplqp->dpi = &rdev->dpi_privileged; /* Doorbell page */ + if (init_attr->create_flags) + dev_dbg(rdev_to_dev(rdev), + "QP create flags 0x%x not supported", + init_attr->create_flags); + + /* Setup CQs */ + if (init_attr->send_cq) { + cq = container_of(init_attr->send_cq, struct bnxt_re_cq, ib_cq); if (!cq) { dev_err(rdev_to_dev(rdev), "Send CQ not found"); rc = -EINVAL; - goto fail; + goto out; } - qp->qplib_qp.scq = &cq->qplib_cq; + qplqp->scq = &cq->qplib_cq; qp->scq = cq; } - if (qp_init_attr->recv_cq) { - cq = container_of(qp_init_attr->recv_cq, struct bnxt_re_cq, - ib_cq); + if (init_attr->recv_cq) { + cq = container_of(init_attr->recv_cq, struct bnxt_re_cq, ib_cq); if (!cq) { dev_err(rdev_to_dev(rdev), "Receive CQ not found"); rc = -EINVAL; - goto fail; + goto out; } - qp->qplib_qp.rcq = &cq->qplib_cq; + qplqp->rcq = &cq->qplib_cq; qp->rcq = cq; } - if (qp_init_attr->srq) { - srq = container_of(qp_init_attr->srq, struct bnxt_re_srq, - ib_srq); - if (!srq) { - dev_err(rdev_to_dev(rdev), "SRQ not found"); - rc = -EINVAL; - goto fail; - } - qp->qplib_qp.srq = &srq->qplib_srq; - qp->qplib_qp.rq.max_wqe = 0; - } else { - /* Allocate 1 more than what's provided so posting max doesn't - * mean empty - */ - entries = roundup_pow_of_two(qp_init_attr->cap.max_recv_wr + 1); - qp->qplib_qp.rq.max_wqe = min_t(u32, entries, - dev_attr->max_qp_wqes + 1); + /* Setup RQ/SRQ */ + rc = bnxt_re_init_rq_attr(qp, init_attr); + if (rc) + goto out; + if (init_attr->qp_type == IB_QPT_GSI) + bnxt_re_adjust_gsi_rq_attr(qp); - qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe - - qp_init_attr->cap.max_recv_wr; + /* Setup SQ */ + bnxt_re_init_sq_attr(qp, init_attr, udata); + if (init_attr->qp_type == IB_QPT_GSI) + bnxt_re_adjust_gsi_sq_attr(qp, init_attr); + + if (udata) /* This will update DPI and qp_handle */ + rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); +out: + return rc; +} + +static int bnxt_re_create_shadow_gsi(struct bnxt_re_qp *qp, + struct bnxt_re_pd *pd) +{ + struct bnxt_re_sqp_entries *sqp_tbl = NULL; + struct bnxt_re_dev *rdev; + struct bnxt_re_qp *sqp; + struct bnxt_re_ah *sah; + int rc = 0; - qp->qplib_qp.rq.max_sge = qp_init_attr->cap.max_recv_sge; - if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) - qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; + rdev = qp->rdev; + /* Create a shadow QP to handle the QP1 traffic */ + sqp_tbl = kzalloc(sizeof(*sqp_tbl) * BNXT_RE_MAX_GSI_SQP_ENTRIES, + GFP_KERNEL); + if (!sqp_tbl) + return -ENOMEM; + rdev->gsi_ctx.sqp_tbl = sqp_tbl; + + sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, &qp->qplib_qp); + if (!sqp) { + rc = -ENODEV; + dev_err(rdev_to_dev(rdev), + "Failed to create Shadow QP for QP1"); + goto out; } + rdev->gsi_ctx.gsi_sqp = sqp; - qp->qplib_qp.mtu = ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); + sqp->rcq = qp->rcq; + sqp->scq = qp->scq; + sah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, + &qp->qplib_qp); + if (!sah) { + bnxt_qplib_destroy_qp(&rdev->qplib_res, + &sqp->qplib_qp); + rc = -ENODEV; + dev_err(rdev_to_dev(rdev), + "Failed to create AH entry for ShadowQP"); + goto out; + } + rdev->gsi_ctx.gsi_sah = sah; - if (qp_init_attr->qp_type == IB_QPT_GSI && - !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { - /* Allocate 1 more than what's provided */ - entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + 1); - qp->qplib_qp.sq.max_wqe = min_t(u32, entries, - dev_attr->max_qp_wqes + 1); - qp->qplib_qp.sq.q_full_delta = qp->qplib_qp.sq.max_wqe - - qp_init_attr->cap.max_send_wr; - qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; - if (qp->qplib_qp.rq.max_sge > dev_attr->max_qp_sges) - qp->qplib_qp.rq.max_sge = dev_attr->max_qp_sges; - qp->qplib_qp.sq.max_sge++; - if (qp->qplib_qp.sq.max_sge > dev_attr->max_qp_sges) - qp->qplib_qp.sq.max_sge = dev_attr->max_qp_sges; - - qp->qplib_qp.rq_hdr_buf_size = - BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; - - qp->qplib_qp.sq_hdr_buf_size = - BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; - qp->qplib_qp.dpi = &rdev->dpi_privileged; - rc = bnxt_qplib_create_qp1(&rdev->qplib_res, &qp->qplib_qp); - if (rc) { - dev_err(rdev_to_dev(rdev), "Failed to create HW QP1"); - goto fail; - } - /* Create a shadow QP to handle the QP1 traffic */ - rdev->qp1_sqp = bnxt_re_create_shadow_qp(pd, &rdev->qplib_res, - &qp->qplib_qp); - if (!rdev->qp1_sqp) { - rc = -EINVAL; - dev_err(rdev_to_dev(rdev), - "Failed to create Shadow QP for QP1"); - goto qp_destroy; - } - rdev->sqp_ah = bnxt_re_create_shadow_qp_ah(pd, &rdev->qplib_res, - &qp->qplib_qp); - if (!rdev->sqp_ah) { - bnxt_qplib_destroy_qp(&rdev->qplib_res, - &rdev->qp1_sqp->qplib_qp); - rc = -EINVAL; - dev_err(rdev_to_dev(rdev), - "Failed to create AH entry for ShadowQP"); - goto qp_destroy; - } + return 0; +out: + kfree(sqp_tbl); + return rc; +} - } else { - /* Allocate 128 + 1 more than what's provided */ - entries = roundup_pow_of_two(qp_init_attr->cap.max_send_wr + - BNXT_QPLIB_RESERVED_QP_WRS + 1); - qp->qplib_qp.sq.max_wqe = min_t(u32, entries, - dev_attr->max_qp_wqes + - BNXT_QPLIB_RESERVED_QP_WRS + 1); - qp->qplib_qp.sq.q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1; +static int bnxt_re_create_gsi_qp(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, + struct ib_qp_init_attr *init_attr) +{ + struct bnxt_re_dev *rdev; + struct bnxt_qplib_qp *qplqp; + int rc = 0; - /* - * Reserving one slot for Phantom WQE. Application can - * post one extra entry in this case. But allowing this to avoid - * unexpected Queue full condition - */ + rdev = qp->rdev; + qplqp = &qp->qplib_qp; - qp->qplib_qp.sq.q_full_delta -= 1; + qplqp->rq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_RQ_HDR_SIZE_V2; + qplqp->sq_hdr_buf_size = BNXT_QPLIB_MAX_QP1_SQ_HDR_SIZE_V2; - qp->qplib_qp.max_rd_atomic = dev_attr->max_qp_rd_atom; - qp->qplib_qp.max_dest_rd_atomic = dev_attr->max_qp_init_rd_atom; - if (udata) { - rc = bnxt_re_init_user_qp(rdev, pd, qp, udata); - if (rc) - goto fail; - } else { - qp->qplib_qp.dpi = &rdev->dpi_privileged; - } + rc = bnxt_qplib_create_qp1(&rdev->qplib_res, qplqp); + if (rc) { + dev_err(rdev_to_dev(rdev), "create HW QP1 failed!"); + goto out; + } + + rc = bnxt_re_create_shadow_gsi(qp, pd); +out: + return rc; +} + +static bool bnxt_re_test_qp_limits(struct bnxt_re_dev *rdev, + struct ib_qp_init_attr *init_attr, + struct bnxt_qplib_dev_attr *dev_attr) +{ + bool rc = true; + + if (init_attr->cap.max_send_wr > dev_attr->max_qp_wqes || + init_attr->cap.max_recv_wr > dev_attr->max_qp_wqes || + init_attr->cap.max_send_sge > dev_attr->max_qp_sges || + init_attr->cap.max_recv_sge > dev_attr->max_qp_sges || + init_attr->cap.max_inline_data > dev_attr->max_inline_data) { + dev_err(rdev_to_dev(rdev), + "Create QP failed - max exceeded! 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x 0x%x/0x%x", + init_attr->cap.max_send_wr, dev_attr->max_qp_wqes, + init_attr->cap.max_recv_wr, dev_attr->max_qp_wqes, + init_attr->cap.max_send_sge, dev_attr->max_qp_sges, + init_attr->cap.max_recv_sge, dev_attr->max_qp_sges, + init_attr->cap.max_inline_data, + dev_attr->max_inline_data); + rc = false; + } + return rc; +} + +struct ib_qp *bnxt_re_create_qp(struct ib_pd *ib_pd, + struct ib_qp_init_attr *qp_init_attr, + struct ib_udata *udata) +{ + struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd); + struct bnxt_re_dev *rdev = pd->rdev; + struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; + struct bnxt_re_qp *qp; + int rc; + + rc = bnxt_re_test_qp_limits(rdev, qp_init_attr, dev_attr); + if (!rc) { + rc = -EINVAL; + goto exit; + } + + qp = kzalloc(sizeof(*qp), GFP_KERNEL); + if (!qp) { + rc = -ENOMEM; + goto exit; + } + qp->rdev = rdev; + rc = bnxt_re_init_qp_attr(qp, pd, qp_init_attr, udata); + if (rc) + goto fail; + if (qp_init_attr->qp_type == IB_QPT_GSI && + !(bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx))) { + rc = bnxt_re_create_gsi_qp(qp, pd, qp_init_attr); + if (rc == -ENODEV) + goto qp_destroy; + if (rc) + goto fail; + } else { rc = bnxt_qplib_create_qp(&rdev->qplib_res, &qp->qplib_qp); if (rc) { dev_err(rdev_to_dev(rdev), "Failed to create HW QP"); goto free_umem; } + if (udata) { + struct bnxt_re_qp_resp resp; + + resp.qpid = qp->qplib_qp.id; + resp.rsvd = 0; + rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); + if (rc) { + dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); + goto qp_destroy; + } + } } qp->ib_qp.qp_num = qp->qplib_qp.id; + if (qp_init_attr->qp_type == IB_QPT_GSI) + rdev->gsi_ctx.gsi_qp = qp; spin_lock_init(&qp->sq_lock); spin_lock_init(&qp->rq_lock); - - if (udata) { - struct bnxt_re_qp_resp resp; - - resp.qpid = qp->ib_qp.qp_num; - resp.rsvd = 0; - rc = ib_copy_to_udata(udata, &resp, sizeof(resp)); - if (rc) { - dev_err(rdev_to_dev(rdev), "Failed to copy QP udata"); - goto qp_destroy; - } - } INIT_LIST_HEAD(&qp->list); mutex_lock(&rdev->qp_lock); list_add_tail(&qp->list, &rdev->qp_list); - atomic_inc(&rdev->qp_count); mutex_unlock(&rdev->qp_lock); + atomic_inc(&rdev->qp_count); return &qp->ib_qp; qp_destroy: @@ -1206,6 +1403,7 @@ ib_umem_release(qp->sumem); fail: kfree(qp); +exit: return ERR_PTR(rc); } @@ -1322,7 +1520,8 @@ bytes = (qplib_srq->max_wqe * BNXT_QPLIB_MAX_RQE_ENTRY_SIZE); bytes = PAGE_ALIGN(bytes); - umem = ib_umem_get(udata, ureq.srqva, bytes, IB_ACCESS_LOCAL_WRITE, 1); + umem = ib_umem_get(&rdev->ibdev, ureq.srqva, bytes, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(umem)) return PTR_ERR(umem); @@ -1404,6 +1603,7 @@ if (nq) nq->budget++; atomic_inc(&rdev->srq_count); + spin_lock_init(&srq->lock); return 0; @@ -1425,7 +1625,7 @@ switch (srq_attr_mask) { case IB_SRQ_MAX_WR: /* SRQ resize is not supported */ - break; + return -EINVAL; case IB_SRQ_LIMIT: /* Change the SRQ threshold */ if (srq_attr->srq_limit > srq->qplib_srq.max_wqe) @@ -1440,13 +1640,12 @@ /* On success, update the shadow */ srq->srq_limit = srq_attr->srq_limit; /* No need to Build and send response back to udata */ - break; + return 0; default: dev_err(rdev_to_dev(rdev), "Unsupported srq_attr_mask 0x%x", srq_attr_mask); return -EINVAL; } - return 0; } int bnxt_re_query_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr) @@ -1503,7 +1702,7 @@ struct bnxt_re_qp *qp1_qp, int qp_attr_mask) { - struct bnxt_re_qp *qp = rdev->qp1_sqp; + struct bnxt_re_qp *qp = rdev->gsi_ctx.gsi_sqp; int rc = 0; if (qp_attr_mask & IB_QP_STATE) { @@ -1655,18 +1854,20 @@ } } - if (qp_attr_mask & IB_QP_PATH_MTU) { - qp->qplib_qp.modify_flags |= - CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; - qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu); - qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu); - } else if (qp_attr->qp_state == IB_QPS_RTR) { - qp->qplib_qp.modify_flags |= - CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; - qp->qplib_qp.path_mtu = - __from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu)); - qp->qplib_qp.mtu = - ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu)); + if (qp_attr->qp_state == IB_QPS_RTR) { + enum ib_mtu qpmtu; + + qpmtu = iboe_get_mtu(rdev->netdev->mtu); + if (qp_attr_mask & IB_QP_PATH_MTU) { + if (ib_mtu_enum_to_int(qp_attr->path_mtu) > + ib_mtu_enum_to_int(qpmtu)) + return -EINVAL; + qpmtu = qp_attr->path_mtu; + } + + qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU; + qp->qplib_qp.path_mtu = __from_ib_mtu(qpmtu); + qp->qplib_qp.mtu = ib_mtu_enum_to_int(qpmtu); } if (qp_attr_mask & IB_QP_TIMEOUT) { @@ -1767,7 +1968,7 @@ dev_err(rdev_to_dev(rdev), "Failed to modify HW QP"); return rc; } - if (ib_qp->qp_type == IB_QPT_GSI && rdev->qp1_sqp) + if (ib_qp->qp_type == IB_QPT_GSI && rdev->gsi_ctx.gsi_sqp) rc = bnxt_re_modify_shadow_qp(rdev, qp, qp_attr_mask); return rc; } @@ -1793,6 +1994,7 @@ goto out; } qp_attr->qp_state = __to_ib_qp_state(qplib_qp->state); + qp_attr->cur_qp_state = __to_ib_qp_state(qplib_qp->cur_qp_state); qp_attr->en_sqd_async_notify = qplib_qp->en_sqd_async_notify ? 1 : 0; qp_attr->qp_access_flags = __to_ib_access_flags(qplib_qp->access); qp_attr->pkey_index = qplib_qp->pkey_index; @@ -2011,9 +2213,12 @@ struct bnxt_qplib_swqe *wqe, int payload_size) { + struct bnxt_re_sqp_entries *sqp_entry; struct bnxt_qplib_sge ref, sge; + struct bnxt_re_dev *rdev; u32 rq_prod_index; - struct bnxt_re_sqp_entries *sqp_entry; + + rdev = qp->rdev; rq_prod_index = bnxt_qplib_get_rq_prod_index(&qp->qplib_qp); @@ -2028,7 +2233,7 @@ ref.lkey = wqe->sg_list[0].lkey; ref.size = wqe->sg_list[0].size; - sqp_entry = &qp->rdev->sqp_tbl[rq_prod_index]; + sqp_entry = &rdev->gsi_ctx.sqp_tbl[rq_prod_index]; /* SGE 1 */ wqe->sg_list[0].addr = sge.addr; @@ -2070,7 +2275,7 @@ break; case IB_WR_SEND_WITH_IMM: wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM; - wqe->send.imm_data = wr->ex.imm_data; + wqe->send.imm_data = be32_to_cpu(wr->ex.imm_data); break; case IB_WR_SEND_WITH_INV: wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV; @@ -2100,7 +2305,7 @@ break; case IB_WR_RDMA_WRITE_WITH_IMM: wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM; - wqe->rdma.imm_data = wr->ex.imm_data; + wqe->rdma.imm_data = be32_to_cpu(wr->ex.imm_data); break; case IB_WR_RDMA_READ: wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_READ; @@ -2563,9 +2768,9 @@ goto fail; } - cq->umem = ib_umem_get(udata, req.cq_va, + cq->umem = ib_umem_get(&rdev->ibdev, req.cq_va, entries * sizeof(struct cq_base), - IB_ACCESS_LOCAL_WRITE, 1); + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(cq->umem)) { rc = PTR_ERR(cq->umem); goto fail; @@ -2848,12 +3053,13 @@ return rc; } -static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *qp1_qp, +static int bnxt_re_process_raw_qp_pkt_rx(struct bnxt_re_qp *gsi_qp, struct bnxt_qplib_cqe *cqe) { - struct bnxt_re_dev *rdev = qp1_qp->rdev; + struct bnxt_re_dev *rdev = gsi_qp->rdev; struct bnxt_re_sqp_entries *sqp_entry = NULL; - struct bnxt_re_qp *qp = rdev->qp1_sqp; + struct bnxt_re_qp *gsi_sqp = rdev->gsi_ctx.gsi_sqp; + struct bnxt_re_ah *gsi_sah; struct ib_send_wr *swr; struct ib_ud_wr udwr; struct ib_recv_wr rwr; @@ -2876,19 +3082,19 @@ swr = &udwr.wr; tbl_idx = cqe->wr_id; - rq_hdr_buf = qp1_qp->qplib_qp.rq_hdr_buf + - (tbl_idx * qp1_qp->qplib_qp.rq_hdr_buf_size); - rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp1_qp->qplib_qp, + rq_hdr_buf = gsi_qp->qplib_qp.rq_hdr_buf + + (tbl_idx * gsi_qp->qplib_qp.rq_hdr_buf_size); + rq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, tbl_idx); /* Shadow QP header buffer */ - shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&qp->qplib_qp, + shrq_hdr_buf_map = bnxt_qplib_get_qp_buf_from_index(&gsi_qp->qplib_qp, tbl_idx); - sqp_entry = &rdev->sqp_tbl[tbl_idx]; + sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; /* Store this cqe */ memcpy(&sqp_entry->cqe, cqe, sizeof(struct bnxt_qplib_cqe)); - sqp_entry->qp1_qp = qp1_qp; + sqp_entry->qp1_qp = gsi_qp; /* Find packet type from the cqe */ @@ -2942,7 +3148,7 @@ rwr.wr_id = tbl_idx; rwr.next = NULL; - rc = bnxt_re_post_recv_shadow_qp(rdev, qp, &rwr); + rc = bnxt_re_post_recv_shadow_qp(rdev, gsi_sqp, &rwr); if (rc) { dev_err(rdev_to_dev(rdev), "Failed to post Rx buffers to shadow QP"); @@ -2954,15 +3160,13 @@ swr->wr_id = tbl_idx; swr->opcode = IB_WR_SEND; swr->next = NULL; - - udwr.ah = &rdev->sqp_ah->ib_ah; - udwr.remote_qpn = rdev->qp1_sqp->qplib_qp.id; - udwr.remote_qkey = rdev->qp1_sqp->qplib_qp.qkey; + gsi_sah = rdev->gsi_ctx.gsi_sah; + udwr.ah = &gsi_sah->ib_ah; + udwr.remote_qpn = gsi_sqp->qplib_qp.id; + udwr.remote_qkey = gsi_sqp->qplib_qp.qkey; /* post data received in the send queue */ - rc = bnxt_re_post_send_shadow_qp(rdev, qp, swr); - - return 0; + return bnxt_re_post_send_shadow_qp(rdev, gsi_sqp, swr); } static void bnxt_re_process_res_rawqp1_wc(struct ib_wc *wc, @@ -2973,6 +3177,19 @@ wc->wc_flags |= IB_WC_GRH; } +static bool bnxt_re_check_if_vlan_valid(struct bnxt_re_dev *rdev, + u16 vlan_id) +{ + /* + * Check if the vlan is configured in the host. If not configured, it + * can be a transparent VLAN. So dont report the vlan id. + */ + if (!__vlan_find_dev_deep_rcu(rdev->netdev, + htons(ETH_P_8021Q), vlan_id)) + return false; + return true; +} + static bool bnxt_re_is_vlan_pkt(struct bnxt_qplib_cqe *orig_cqe, u16 *vid, u8 *sl) { @@ -3014,12 +3231,12 @@ wc->opcode = IB_WC_RECV_RDMA_WITH_IMM; } -static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *qp, +static void bnxt_re_process_res_shadow_qp_wc(struct bnxt_re_qp *gsi_sqp, struct ib_wc *wc, struct bnxt_qplib_cqe *cqe) { - struct bnxt_re_dev *rdev = qp->rdev; - struct bnxt_re_qp *qp1_qp = NULL; + struct bnxt_re_dev *rdev = gsi_sqp->rdev; + struct bnxt_re_qp *gsi_qp = NULL; struct bnxt_qplib_cqe *orig_cqe = NULL; struct bnxt_re_sqp_entries *sqp_entry = NULL; int nw_type; @@ -3029,21 +3246,23 @@ tbl_idx = cqe->wr_id; - sqp_entry = &rdev->sqp_tbl[tbl_idx]; - qp1_qp = sqp_entry->qp1_qp; + sqp_entry = &rdev->gsi_ctx.sqp_tbl[tbl_idx]; + gsi_qp = sqp_entry->qp1_qp; orig_cqe = &sqp_entry->cqe; wc->wr_id = sqp_entry->wrid; wc->byte_len = orig_cqe->length; - wc->qp = &qp1_qp->ib_qp; + wc->qp = &gsi_qp->ib_qp; - wc->ex.imm_data = orig_cqe->immdata; + wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata); wc->src_qp = orig_cqe->src_qp; memcpy(wc->smac, orig_cqe->smac, ETH_ALEN); if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) { - wc->vlan_id = vlan_id; - wc->sl = sl; - wc->wc_flags |= IB_WC_WITH_VLAN; + if (bnxt_re_check_if_vlan_valid(rdev, vlan_id)) { + wc->vlan_id = vlan_id; + wc->sl = sl; + wc->wc_flags |= IB_WC_WITH_VLAN; + } } wc->port_num = 1; wc->vendor_err = orig_cqe->status; @@ -3064,8 +3283,11 @@ struct ib_wc *wc, struct bnxt_qplib_cqe *cqe) { + struct bnxt_re_dev *rdev; + u16 vlan_id = 0; u8 nw_type; + rdev = qp->rdev; wc->opcode = IB_WC_RECV; wc->status = __rc_to_ib_wc_status(cqe->status); @@ -3077,9 +3299,12 @@ memcpy(wc->smac, cqe->smac, ETH_ALEN); wc->wc_flags |= IB_WC_WITH_SMAC; if (cqe->flags & CQ_RES_UD_FLAGS_META_FORMAT_VLAN) { - wc->vlan_id = (cqe->cfa_meta & 0xFFF); - if (wc->vlan_id < 0x1000) - wc->wc_flags |= IB_WC_WITH_VLAN; + vlan_id = (cqe->cfa_meta & 0xFFF); + } + /* Mark only if vlan_id is non zero */ + if (vlan_id && bnxt_re_check_if_vlan_valid(rdev, vlan_id)) { + wc->vlan_id = vlan_id; + wc->wc_flags |= IB_WC_WITH_VLAN; } nw_type = (cqe->flags & CQ_RES_UD_FLAGS_ROCE_IP_VER_MASK) >> CQ_RES_UD_FLAGS_ROCE_IP_VER_SFT; @@ -3114,7 +3339,7 @@ int bnxt_re_poll_cq(struct ib_cq *ib_cq, int num_entries, struct ib_wc *wc) { struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq); - struct bnxt_re_qp *qp; + struct bnxt_re_qp *qp, *sh_qp; struct bnxt_qplib_cqe *cqe; int i, ncqe, budget; struct bnxt_qplib_q *sq; @@ -3170,7 +3395,10 @@ continue; } wc->qp = &qp->ib_qp; - wc->ex.imm_data = cqe->immdata; + if (cqe->flags & CQ_RES_RC_FLAGS_IMM) + wc->ex.imm_data = cpu_to_be32(cqe->immdata); + else + wc->ex.invalidate_rkey = cqe->invrkey; wc->src_qp = cqe->src_qp; memcpy(wc->smac, cqe->smac, ETH_ALEN); wc->port_num = 1; @@ -3178,8 +3406,9 @@ switch (cqe->opcode) { case CQ_BASE_CQE_TYPE_REQ: - if (qp->rdev->qp1_sqp && qp->qplib_qp.id == - qp->rdev->qp1_sqp->qplib_qp.id) { + sh_qp = qp->rdev->gsi_ctx.gsi_sqp; + if (sh_qp && + qp->qplib_qp.id == sh_qp->qplib_qp.id) { /* Handle this completion with * the stored completion */ @@ -3205,7 +3434,7 @@ * stored in the table */ tbl_idx = cqe->wr_id; - sqp_entry = &cq->rdev->sqp_tbl[tbl_idx]; + sqp_entry = &cq->rdev->gsi_ctx.sqp_tbl[tbl_idx]; wc->wr_id = sqp_entry->wrid; bnxt_re_process_res_rawqp1_wc(wc, cqe); break; @@ -3213,8 +3442,9 @@ bnxt_re_process_res_rc_wc(wc, cqe); break; case CQ_BASE_CQE_TYPE_RES_UD: - if (qp->rdev->qp1_sqp && qp->qplib_qp.id == - qp->rdev->qp1_sqp->qplib_qp.id) { + sh_qp = qp->rdev->gsi_ctx.gsi_sqp; + if (sh_qp && + qp->qplib_qp.id == sh_qp->qplib_qp.id) { /* Handle this completion with * the stored completion */ @@ -3323,8 +3553,10 @@ int rc; rc = bnxt_qplib_free_mrw(&rdev->qplib_res, &mr->qplib_mr); - if (rc) + if (rc) { dev_err(rdev_to_dev(rdev), "Dereg MR failed: %#x\n", rc); + return rc; + } if (mr->pages) { rc = bnxt_qplib_free_fast_reg_page_list(&rdev->qplib_res, @@ -3530,7 +3762,7 @@ /* The fixed portion of the rkey is the same as the lkey */ mr->ib_mr.rkey = mr->qplib_mr.rkey; - umem = ib_umem_get(udata, start, length, mr_access_flags, 0); + umem = ib_umem_get(&rdev->ibdev, start, length, mr_access_flags); if (IS_ERR(umem)) { dev_err(rdev_to_dev(rdev), "Failed to get umem"); rc = -EFAULT; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/main.c @@ -70,7 +70,7 @@ BNXT_RE_DESC "\n"; MODULE_AUTHOR("Eddie Wai "); -MODULE_DESCRIPTION(BNXT_RE_DESC " Driver"); +MODULE_DESCRIPTION(BNXT_RE_DESC); MODULE_LICENSE("Dual BSD/GPL"); /* globals */ @@ -119,61 +119,76 @@ * reserved for the function. The driver may choose to allocate fewer * resources than the firmware maximum. */ -static void bnxt_re_set_resource_limits(struct bnxt_re_dev *rdev) +static void bnxt_re_limit_pf_res(struct bnxt_re_dev *rdev) { - u32 vf_qps = 0, vf_srqs = 0, vf_cqs = 0, vf_mrws = 0, vf_gids = 0; - u32 i; + struct bnxt_qplib_dev_attr *attr; + struct bnxt_qplib_ctx *ctx; + int i; + + attr = &rdev->dev_attr; + ctx = &rdev->qplib_ctx; + + ctx->qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT, + attr->max_qp); + ctx->mrw_count = BNXT_RE_MAX_MRW_COUNT_256K; + /* Use max_mr from fw since max_mrw does not get set */ + ctx->mrw_count = min_t(u32, ctx->mrw_count, attr->max_mr); + ctx->srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, + attr->max_srq); + ctx->cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, attr->max_cq); + if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) + for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) + rdev->qplib_ctx.tqm_count[i] = + rdev->dev_attr.tqm_alloc_reqs[i]; +} + +static void bnxt_re_limit_vf_res(struct bnxt_qplib_ctx *qplib_ctx, u32 num_vf) +{ + struct bnxt_qplib_vf_res *vf_res; + u32 mrws = 0; u32 vf_pct; + u32 nvfs; + + vf_res = &qplib_ctx->vf_res; + /* + * Reserve a set of resources for the PF. Divide the remaining + * resources among the VFs + */ + vf_pct = 100 - BNXT_RE_PCT_RSVD_FOR_PF; + nvfs = num_vf; + num_vf = 100 * num_vf; + vf_res->max_qp_per_vf = (qplib_ctx->qpc_count * vf_pct) / num_vf; + vf_res->max_srq_per_vf = (qplib_ctx->srqc_count * vf_pct) / num_vf; + vf_res->max_cq_per_vf = (qplib_ctx->cq_count * vf_pct) / num_vf; + /* + * The driver allows many more MRs than other resources. If the + * firmware does also, then reserve a fixed amount for the PF and + * divide the rest among VFs. VFs may use many MRs for NFS + * mounts, ISER, NVME applications, etc. If the firmware severely + * restricts the number of MRs, then let PF have half and divide + * the rest among VFs, as for the other resource types. + */ + if (qplib_ctx->mrw_count < BNXT_RE_MAX_MRW_COUNT_64K) { + mrws = qplib_ctx->mrw_count * vf_pct; + nvfs = num_vf; + } else { + mrws = qplib_ctx->mrw_count - BNXT_RE_RESVD_MR_FOR_PF; + } + vf_res->max_mrw_per_vf = (mrws / nvfs); + vf_res->max_gid_per_vf = BNXT_RE_MAX_GID_PER_VF; +} + +static void bnxt_re_set_resource_limits(struct bnxt_re_dev *rdev) +{ u32 num_vfs; - struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr; - rdev->qplib_ctx.qpc_count = min_t(u32, BNXT_RE_MAX_QPC_COUNT, - dev_attr->max_qp); + memset(&rdev->qplib_ctx.vf_res, 0, sizeof(struct bnxt_qplib_vf_res)); + bnxt_re_limit_pf_res(rdev); - rdev->qplib_ctx.mrw_count = BNXT_RE_MAX_MRW_COUNT_256K; - /* Use max_mr from fw since max_mrw does not get set */ - rdev->qplib_ctx.mrw_count = min_t(u32, rdev->qplib_ctx.mrw_count, - dev_attr->max_mr); - rdev->qplib_ctx.srqc_count = min_t(u32, BNXT_RE_MAX_SRQC_COUNT, - dev_attr->max_srq); - rdev->qplib_ctx.cq_count = min_t(u32, BNXT_RE_MAX_CQ_COUNT, - dev_attr->max_cq); - - for (i = 0; i < MAX_TQM_ALLOC_REQ; i++) - rdev->qplib_ctx.tqm_count[i] = - rdev->dev_attr.tqm_alloc_reqs[i]; - - if (rdev->num_vfs) { - /* - * Reserve a set of resources for the PF. Divide the remaining - * resources among the VFs - */ - vf_pct = 100 - BNXT_RE_PCT_RSVD_FOR_PF; - num_vfs = 100 * rdev->num_vfs; - vf_qps = (rdev->qplib_ctx.qpc_count * vf_pct) / num_vfs; - vf_srqs = (rdev->qplib_ctx.srqc_count * vf_pct) / num_vfs; - vf_cqs = (rdev->qplib_ctx.cq_count * vf_pct) / num_vfs; - /* - * The driver allows many more MRs than other resources. If the - * firmware does also, then reserve a fixed amount for the PF - * and divide the rest among VFs. VFs may use many MRs for NFS - * mounts, ISER, NVME applications, etc. If the firmware - * severely restricts the number of MRs, then let PF have - * half and divide the rest among VFs, as for the other - * resource types. - */ - if (rdev->qplib_ctx.mrw_count < BNXT_RE_MAX_MRW_COUNT_64K) - vf_mrws = rdev->qplib_ctx.mrw_count * vf_pct / num_vfs; - else - vf_mrws = (rdev->qplib_ctx.mrw_count - - BNXT_RE_RESVD_MR_FOR_PF) / rdev->num_vfs; - vf_gids = BNXT_RE_MAX_GID_PER_VF; - } - rdev->qplib_ctx.vf_res.max_mrw_per_vf = vf_mrws; - rdev->qplib_ctx.vf_res.max_gid_per_vf = vf_gids; - rdev->qplib_ctx.vf_res.max_qp_per_vf = vf_qps; - rdev->qplib_ctx.vf_res.max_srq_per_vf = vf_srqs; - rdev->qplib_ctx.vf_res.max_cq_per_vf = vf_cqs; + num_vfs = bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? + BNXT_RE_GEN_P5_MAX_VF : rdev->num_vfs; + if (num_vfs) + bnxt_re_limit_vf_res(&rdev->qplib_ctx, num_vfs); } /* for handling bnxt_en callbacks later */ @@ -193,9 +208,11 @@ return; rdev->num_vfs = num_vfs; - bnxt_re_set_resource_limits(rdev); - bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, - &rdev->qplib_ctx); + if (!bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)) { + bnxt_re_set_resource_limits(rdev); + bnxt_qplib_set_func_resources(&rdev->qplib_res, &rdev->rcfw, + &rdev->qplib_ctx); + } } static void bnxt_re_shutdown(void *p) @@ -477,6 +494,7 @@ bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1); req.update_period_ms = cpu_to_le32(1000); req.stats_dma_addr = cpu_to_le64(dma_map); + req.stats_dma_length = cpu_to_le16(sizeof(struct ctx_hw_stats_ext)); req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); @@ -788,7 +806,8 @@ struct ib_event event; unsigned int flags; - if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR) { + if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && + rdma_is_kernel_res(&qp->ib_qp.res)) { flags = bnxt_re_lock_cqs(qp); bnxt_qplib_add_flush_qp(&qp->qplib_qp); bnxt_re_unlock_cqs(qp, flags); @@ -895,10 +914,14 @@ return 0; } +#define BNXT_RE_GEN_P5_PF_NQ_DB 0x10000 +#define BNXT_RE_GEN_P5_VF_NQ_DB 0x4000 static u32 bnxt_re_get_nqdb_offset(struct bnxt_re_dev *rdev, u16 indx) { return bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx) ? - 0x10000 : rdev->msix_entries[indx].db_offset; + (rdev->is_virtfn ? BNXT_RE_GEN_P5_VF_NQ_DB : + BNXT_RE_GEN_P5_PF_NQ_DB) : + rdev->msix_entries[indx].db_offset; } static void bnxt_re_cleanup_res(struct bnxt_re_dev *rdev) @@ -1104,7 +1127,8 @@ static bool bnxt_re_is_qp1_or_shadow_qp(struct bnxt_re_dev *rdev, struct bnxt_re_qp *qp) { - return (qp->ib_qp.qp_type == IB_QPT_GSI) || (qp == rdev->qp1_sqp); + return (qp->ib_qp.qp_type == IB_QPT_GSI) || + (qp == rdev->gsi_ctx.gsi_sqp); } static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev) @@ -1270,10 +1294,10 @@ return; } rdev->qplib_ctx.hwrm_intf_ver = - (u64)resp.hwrm_intf_major << 48 | - (u64)resp.hwrm_intf_minor << 32 | - (u64)resp.hwrm_intf_build << 16 | - resp.hwrm_intf_patch; + (u64)le16_to_cpu(resp.hwrm_intf_major) << 48 | + (u64)le16_to_cpu(resp.hwrm_intf_minor) << 32 | + (u64)le16_to_cpu(resp.hwrm_intf_build) << 16 | + le16_to_cpu(resp.hwrm_intf_patch); } static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev) @@ -1408,8 +1432,8 @@ rdev->is_virtfn); if (rc) goto disable_rcfw; - if (!rdev->is_virtfn) - bnxt_re_set_resource_limits(rdev); + + bnxt_re_set_resource_limits(rdev); rc = bnxt_qplib_alloc_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx, 0, bnxt_qplib_is_chip_gen_p5(&rdev->chip_ctx)); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -642,12 +642,13 @@ int rc = 0; RCFW_CMD_PREP(req, QUERY_SRQ, cmd_flags); - req.srq_cid = cpu_to_le32(srq->id); /* Configure the request */ sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb)); if (!sbuf) return -ENOMEM; + req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS; + req.srq_cid = cpu_to_le32(srq->id); sb = sbuf->sb; rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp, (void *)sbuf, 0); @@ -2283,13 +2284,13 @@ /* Add qp to flush list of the CQ */ bnxt_qplib_add_flush_qp(qp); } else { + /* Before we complete, do WA 9060 */ + if (do_wa9060(qp, cq, cq_cons, sw_sq_cons, + cqe_sq_cons)) { + *lib_qp = qp; + goto out; + } if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) { - /* Before we complete, do WA 9060 */ - if (do_wa9060(qp, cq, cq_cons, sw_sq_cons, - cqe_sq_cons)) { - *lib_qp = qp; - goto out; - } cqe->status = CQ_REQ_STATUS_OK; cqe++; (*budget)--; @@ -2605,11 +2606,8 @@ qp = (struct bnxt_qplib_qp *)((unsigned long) le64_to_cpu(hwcqe->qp_handle)); - if (!qp) { - dev_err(&cq->hwq.pdev->dev, - "FP: CQ Process terminal qp is NULL\n"); + if (!qp) return -EINVAL; - } /* Must block new posting of SQ and RQ */ qp->state = CMDQ_MODIFY_QP_NEW_STATE_ERR; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_fp.h @@ -145,12 +145,12 @@ /* Send, with imm, inval key */ struct { union { - __be32 imm_data; + u32 imm_data; u32 inv_key; }; u32 q_key; u32 dst_qp; - u16 avid; + u32 avid; } send; /* Send Raw Ethernet and QP1 */ @@ -163,7 +163,7 @@ /* RDMA write, with imm, read */ struct { union { - __be32 imm_data; + u32 imm_data; u32 inv_key; }; u64 remote_va; @@ -350,7 +350,7 @@ u16 cfa_meta; u64 wr_id; union { - __be32 immdata; + u32 immdata; u32 invrkey; }; u64 qp_handle; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -244,7 +244,7 @@ /* failed with status */ dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", cookie, opcode, evnt->status); - rc = -EFAULT; + rc = -EIO; } return rc; @@ -494,8 +494,10 @@ * shall setup this area for VF. Skipping the * HW programming */ - if (is_virtfn || bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) + if (is_virtfn) goto skip_ctx_setup; + if (bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx)) + goto config_vf_res; level = ctx->qpc_tbl.level; req.qpc_pg_size_qpc_lvl = (level << CMDQ_INITIALIZE_FW_QPC_LVL_SFT) | @@ -540,6 +542,7 @@ req.number_of_srq = cpu_to_le32(ctx->srqc_tbl.max_elements); req.number_of_cq = cpu_to_le32(ctx->cq_tbl.max_elements); +config_vf_res: req.max_qp_per_vf = cpu_to_le32(ctx->vf_res.max_qp_per_vf); req.max_mrw_per_vf = cpu_to_le32(ctx->vf_res.max_mrw_per_vf); req.max_srq_per_vf = cpu_to_le32(ctx->vf_res.max_srq_per_vf); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -736,6 +736,7 @@ unmap_io: pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem); + dpit->dbr_bar_reg_iomem = NULL; return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_res.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_res.h @@ -186,7 +186,9 @@ u8 chip_metal; }; -#define CHIP_NUM_57500 0x1750 +#define CHIP_NUM_57508 0x1750 +#define CHIP_NUM_57504 0x1751 +#define CHIP_NUM_57502 0x1752 struct bnxt_qplib_res { struct pci_dev *pdev; @@ -203,7 +205,9 @@ static inline bool bnxt_qplib_is_chip_gen_p5(struct bnxt_qplib_chip_ctx *cctx) { - return (cctx->chip_num == CHIP_NUM_57500); + return (cctx->chip_num == CHIP_NUM_57508 || + cctx->chip_num == CHIP_NUM_57504 || + cctx->chip_num == CHIP_NUM_57502); } static inline u8 bnxt_qplib_get_hwq_type(struct bnxt_qplib_res *res) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_sp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_sp.c @@ -118,7 +118,7 @@ * 128 WQEs needs to be reserved for the HW (8916). Prevent * reporting the max number */ - attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS; + attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1; attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5(rcfw->res->cctx) ? 6 : sb->max_sge; attr->max_cq = le32_to_cpu(sb->max_cq); @@ -152,7 +152,7 @@ attr->max_inline_data = le32_to_cpu(sb->max_inline_data); attr->l2_db_size = (sb->l2_db_space_size + 1) * (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); - attr->max_sgid = le32_to_cpu(sb->max_gid); + attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED; bnxt_qplib_query_version(rcfw, attr->fw_ver); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/bnxt_re/qplib_sp.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/bnxt_re/qplib_sp.h @@ -47,6 +47,7 @@ struct bnxt_qplib_dev_attr { #define FW_VER_ARR_LEN 4 u8 fw_ver[FW_VER_ARR_LEN]; +#define BNXT_QPLIB_NUM_GIDS_SUPPORTED 256 u16 max_sgid; u16 max_mrw; u32 max_qp; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -451,7 +451,7 @@ mhp->rhp = rhp; - mhp->umem = ib_umem_get(udata, start, length, acc, 0); + mhp->umem = ib_umem_get(pd->device, start, length, acc); if (IS_ERR(mhp->umem)) { err = PTR_ERR(mhp->umem); kfree(mhp); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/cm.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/cm.c @@ -1222,6 +1222,8 @@ int ret; ep = lookup_atid(t, atid); + if (!ep) + return -EINVAL; pr_debug("ep %p tid %u snd_isn %u rcv_isn %u\n", ep, tid, be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn)); @@ -1965,6 +1967,9 @@ int win; skb = get_skb(NULL, sizeof(*req), GFP_KERNEL); + if (!skb) + return -ENOMEM; + req = __skb_put_zero(skb, sizeof(*req)); req->op_compl = htonl(WR_OP_V(FW_OFLD_CONNECTION_WR)); req->len16_pkd = htonl(FW_WR_LEN16_V(DIV_ROUND_UP(sizeof(*req), 16))); @@ -2081,7 +2086,7 @@ err = -ENOMEM; if (n->dev->flags & IFF_LOOPBACK) { if (iptype == 4) - pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip); + pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false); else if (IS_ENABLED(CONFIG_IPV6)) for_each_netdev(&init_net, pdev) { if (ipv6_chk_addr(&init_net, @@ -2096,12 +2101,12 @@ err = -ENODEV; goto out; } + if (is_vlan_dev(pdev)) + pdev = vlan_dev_real_dev(pdev); ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, n, pdev, rt_tos2priority(tos)); - if (!ep->l2t) { - dev_put(pdev); + if (!ep->l2t) goto out; - } ep->mtu = pdev->mtu; ep->tx_chan = cxgb4_port_chan(pdev); ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx; @@ -2114,7 +2119,6 @@ ep->rss_qid = cdev->rdev.lldi.rxq_ids[ cxgb4_port_idx(pdev) * step]; set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); - dev_put(pdev); } else { pdev = get_real_dev(n->dev); ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, @@ -2276,6 +2280,9 @@ int ret = 0; ep = lookup_atid(t, atid); + if (!ep) + return -EINVAL; + la = (struct sockaddr_in *)&ep->com.local_addr; ra = (struct sockaddr_in *)&ep->com.remote_addr; la6 = (struct sockaddr_in6 *)&ep->com.local_addr; @@ -2891,8 +2898,7 @@ srqidx = ABORT_RSS_SRQIDX_G( be32_to_cpu(req->srqidx_status)); if (srqidx) { - complete_cached_srq_buffers(ep, - req->srqidx_status); + complete_cached_srq_buffers(ep, srqidx); } else { /* Hold ep ref until finish_peer_abort() */ c4iw_get_ep(&ep->com); @@ -3036,6 +3042,10 @@ C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); } + /* As per draft-hilland-iwarp-verbs-v1.0, sec 6.2.3, + * when entering the TERM state the RNIC MUST initiate a CLOSE. + */ + c4iw_ep_disconnect(ep, 1, GFP_KERNEL); c4iw_put_ep(&ep->com); } else pr_warn("TERM received tid %u no ep/qp\n", tid); @@ -3279,7 +3289,7 @@ static int pick_local_ip6addrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id) { - struct in6_addr uninitialized_var(addr); + struct in6_addr addr; struct sockaddr_in6 *la6 = (struct sockaddr_in6 *)&cm_id->m_local_addr; struct sockaddr_in6 *ra6 = (struct sockaddr_in6 *)&cm_id->m_remote_addr; @@ -3379,7 +3389,7 @@ if (raddr->sin_addr.s_addr == htonl(INADDR_ANY)) { err = pick_local_ipaddrs(dev, cm_id); if (err) - goto fail2; + goto fail3; } /* find a route */ @@ -3401,7 +3411,7 @@ if (ipv6_addr_type(&raddr6->sin6_addr) == IPV6_ADDR_ANY) { err = pick_local_ip6addrs(dev, cm_id); if (err) - goto fail2; + goto fail3; } /* find a route */ @@ -3607,13 +3617,14 @@ ep->com.local_addr.ss_family == AF_INET) { err = cxgb4_remove_server_filter( ep->com.dev->rdev.lldi.ports[0], ep->stid, - ep->com.dev->rdev.lldi.rxq_ids[0], 0); + ep->com.dev->rdev.lldi.rxq_ids[0], false); } else { struct sockaddr_in6 *sin6; c4iw_init_wr_wait(ep->com.wr_waitp); err = cxgb4_remove_server( ep->com.dev->rdev.lldi.ports[0], ep->stid, - ep->com.dev->rdev.lldi.rxq_ids[0], 0); + ep->com.dev->rdev.lldi.rxq_ids[0], + ep->com.local_addr.ss_family == AF_INET6); if (err) goto done; err = c4iw_wait_for_reply(&ep->com.dev->rdev, ep->com.wr_waitp, @@ -3874,8 +3885,8 @@ return 0; } - ep->srqe_idx = t4_tcb_get_field32(tcb, TCB_RQ_START_W, TCB_RQ_START_W, - TCB_RQ_START_S); + ep->srqe_idx = t4_tcb_get_field32(tcb, TCB_RQ_START_W, TCB_RQ_START_M, + TCB_RQ_START_S); cleanup: pr_debug("ep %p tid %u %016x\n", ep, ep->hwtid, ep->srqe_idx); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/cq.c @@ -754,7 +754,7 @@ static int __c4iw_poll_cq_one(struct c4iw_cq *chp, struct c4iw_qp *qhp, struct ib_wc *wc, struct c4iw_srq *srq) { - struct t4_cqe uninitialized_var(cqe); + struct t4_cqe cqe; struct t4_wq *wq = qhp ? &qhp->wq : NULL; u32 credit = 0; u8 cqe_flushed; @@ -1007,6 +1007,9 @@ if (attr->flags) return -EINVAL; + if (entries < 1 || entries > ibdev->attrs.max_cqe) + return -EINVAL; + if (vector >= rhp->rdev.lldi.nciq) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/device.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/device.c @@ -953,6 +953,7 @@ static void c4iw_remove(struct uld_ctx *ctx) { pr_debug("c4iw_dev %p\n", ctx->dev); + debugfs_remove_recursive(ctx->dev->debugfs_root); c4iw_unregister_device(ctx->dev); c4iw_dealloc(ctx); } @@ -1113,8 +1114,10 @@ * The math here assumes sizeof cpl_pass_accept_req >= sizeof * cpl_rx_pkt. */ - skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) + - sizeof(struct rss_header) - pktshift, GFP_ATOMIC); + skb = alloc_skb(size_add(gl->tot_len, + sizeof(struct cpl_pass_accept_req) + + sizeof(struct rss_header)) - pktshift, + GFP_ATOMIC); if (unlikely(!skb)) return NULL; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/mem.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/mem.c @@ -399,7 +399,6 @@ mmid = stag >> 8; mhp->ibmr.rkey = mhp->ibmr.lkey = stag; mhp->ibmr.length = mhp->attr.len; - mhp->ibmr.iova = mhp->attr.va_fbo; mhp->ibmr.page_size = 1U << (mhp->attr.page_size + 12); pr_debug("mmid 0x%x mhp %p\n", mmid, mhp); return xa_insert_irq(&mhp->rhp->mrs, mmid, mhp, GFP_KERNEL); @@ -543,7 +542,7 @@ mhp->rhp = rhp; - mhp->umem = ib_umem_get(udata, start, length, acc, 0); + mhp->umem = ib_umem_get(pd->device, start, length, acc); if (IS_ERR(mhp->umem)) goto err_free_skb; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/qp.c @@ -295,6 +295,7 @@ if (user && (!wq->sq.bar2_pa || (need_rq && !wq->rq.bar2_pa))) { pr_warn("%s: sqid %u or rqid %u not in BAR2 range\n", pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); + ret = -EINVAL; goto free_dma; } @@ -1948,10 +1949,10 @@ qhp->attr.layer_etype = attrs->layer_etype; qhp->attr.ecode = attrs->ecode; ep = qhp->ep; - c4iw_get_ep(&ep->com); - disconnect = 1; if (!internal) { + c4iw_get_ep(&ep->com); terminate = 1; + disconnect = 1; } else { terminate = qhp->attr.send_term; ret = rdma_fini(rhp, qhp, ep); @@ -2468,10 +2469,11 @@ memset(attr, 0, sizeof(*attr)); memset(init_attr, 0, sizeof(*init_attr)); attr->qp_state = to_ib_qp_state(qhp->attr.state); + attr->cur_qp_state = to_ib_qp_state(qhp->attr.state); init_attr->cap.max_send_wr = qhp->attr.sq_num_entries; init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries; init_attr->cap.max_send_sge = qhp->attr.sq_max_sges; - init_attr->cap.max_recv_sge = qhp->attr.sq_max_sges; + init_attr->cap.max_recv_sge = qhp->attr.rq_max_sges; init_attr->cap.max_inline_data = T4_MAX_SEND_INLINE; init_attr->sq_sig_type = qhp->sq_sig_all ? IB_SIGNAL_ALL_WR : 0; return 0; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/cxgb4/resource.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/cxgb4/resource.c @@ -216,7 +216,7 @@ goto out; entry->qid = qid; list_add_tail(&entry->entry, &uctx->cqids); - for (i = qid; i & rdev->qpmask; i++) { + for (i = qid + 1; i & rdev->qpmask; i++) { entry = kmalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto out; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h @@ -579,7 +579,8 @@ /* Number of sub-CQs to be created for each CQ */ u16 sub_cqs_per_cq; - u16 reserved; + /* Minimum number of WQEs per SQ */ + u16 min_sq_depth; /* * Maximum number of SGEs (buffs) allowed for a single send work @@ -604,6 +605,20 @@ /* The maximum size of LLQ in bytes */ u32 max_llq_size; + + /* Maximum number of SGEs for a single RDMA read WQE */ + u16 max_wr_rdma_sges; + + /* + * Maximum number of bytes that can be written to SQ between two + * consecutive doorbells (in units of 64B). Driver must ensure that only + * complete WQEs are written to queue before issuing a doorbell. + * Examples: max_tx_batch=16 and WQE size = 64B, means up to 16 WQEs can + * be written to SQ between two consecutive doorbells. max_tx_batch=11 + * and WQE size = 128B, means up to 5 WQEs can be written to SQ between + * two consecutive doorbells. Zero means unlimited. + */ + u16 max_tx_batch; }; struct efa_admin_feature_aenq_desc { --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_com.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_com.c @@ -317,6 +317,7 @@ struct efa_admin_acq_entry *comp, size_t comp_size_in_bytes) { + struct efa_admin_aq_entry *aqe; struct efa_comp_ctx *comp_ctx; u16 queue_size_mask; u16 cmd_id; @@ -350,7 +351,9 @@ reinit_completion(&comp_ctx->wait_event); - memcpy(&aq->sq.entries[pi], cmd, cmd_size_in_bytes); + aqe = &aq->sq.entries[pi]; + memset(aqe, 0, sizeof(*aqe)); + memcpy(aqe, cmd, cmd_size_in_bytes); aq->sq.pc++; atomic64_inc(&aq->stats.submitted_cmd); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_com_cmd.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_com_cmd.c @@ -500,6 +500,8 @@ result->max_ah = resp.u.queue_attr.max_ah; result->max_llq_size = resp.u.queue_attr.max_llq_size; result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq; + result->max_tx_batch = resp.u.queue_attr.max_tx_batch; + result->min_sq_depth = resp.u.queue_attr.min_sq_depth; return 0; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_com_cmd.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_com_cmd.h @@ -127,6 +127,8 @@ u16 sub_cqs_per_cq; u16 max_sq_sge; u16 max_rq_sge; + u16 max_tx_batch; + u16 min_sq_depth; u8 db_bar; }; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_main.c @@ -10,10 +10,12 @@ #include "efa.h" -#define PCI_DEV_ID_EFA_VF 0xefa0 +#define PCI_DEV_ID_EFA0_VF 0xefa0 +#define PCI_DEV_ID_EFA1_VF 0xefa1 static const struct pci_device_id efa_pci_tbl[] = { - { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA_VF) }, + { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) }, + { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) }, { } }; @@ -340,6 +342,7 @@ } if (irq_num != msix_vecs) { + efa_disable_msix(dev); dev_err(&dev->pdev->dev, "Allocated %d MSI-X (out of %d requested)\n", irq_num, msix_vecs); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/efa/efa_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/efa/efa_verbs.c @@ -745,7 +745,6 @@ rq_entry_inserted = true; qp->qp_handle = create_qp_resp.qp_handle; qp->ibqp.qp_num = create_qp_resp.qp_num; - qp->ibqp.qp_type = init_attr->qp_type; qp->max_send_wr = init_attr->cap.max_send_wr; qp->max_recv_wr = init_attr->cap.max_recv_wr; qp->max_send_sge = init_attr->cap.max_send_sge; @@ -1232,7 +1231,7 @@ */ static int pbl_indirect_initialize(struct efa_dev *dev, struct pbl_context *pbl) { - u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, PAGE_SIZE); + u32 size_in_pages = DIV_ROUND_UP(pbl->pbl_buf_size_in_bytes, EFA_CHUNK_PAYLOAD_SIZE); struct scatterlist *sgl; int sg_dma_cnt, err; @@ -1423,7 +1422,7 @@ goto err_out; } - mr->umem = ib_umem_get(udata, start, length, access_flags, 0); + mr->umem = ib_umem_get(ibpd->device, start, length, access_flags); if (IS_ERR(mr->umem)) { err = PTR_ERR(mr->umem); ibdev_dbg(&dev->ibdev, @@ -1538,11 +1537,39 @@ return efa_com_dealloc_uar(&dev->edev, ¶ms); } +#define EFA_CHECK_USER_COMP(_dev, _comp_mask, _attr, _mask, _attr_str) \ + (_attr_str = (!(_dev)->dev_attr._attr || ((_comp_mask) & (_mask))) ? \ + NULL : #_attr) + +static int efa_user_comp_handshake(const struct ib_ucontext *ibucontext, + const struct efa_ibv_alloc_ucontext_cmd *cmd) +{ + struct efa_dev *dev = to_edev(ibucontext->device); + char *attr_str; + + if (EFA_CHECK_USER_COMP(dev, cmd->comp_mask, max_tx_batch, + EFA_ALLOC_UCONTEXT_CMD_COMP_TX_BATCH, attr_str)) + goto err; + + if (EFA_CHECK_USER_COMP(dev, cmd->comp_mask, min_sq_depth, + EFA_ALLOC_UCONTEXT_CMD_COMP_MIN_SQ_WR, + attr_str)) + goto err; + + return 0; + +err: + ibdev_dbg(&dev->ibdev, "Userspace handshake failed for %s attribute\n", + attr_str); + return -EOPNOTSUPP; +} + int efa_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata) { struct efa_ucontext *ucontext = to_eucontext(ibucontext); struct efa_dev *dev = to_edev(ibucontext->device); struct efa_ibv_alloc_ucontext_resp resp = {}; + struct efa_ibv_alloc_ucontext_cmd cmd = {}; struct efa_com_alloc_uar_result result; int err; @@ -1551,6 +1578,18 @@ * we will ack input fields in our response. */ + err = ib_copy_from_udata(&cmd, udata, + min(sizeof(cmd), udata->inlen)); + if (err) { + ibdev_dbg(&dev->ibdev, + "Cannot copy udata for alloc_ucontext\n"); + goto err_out; + } + + err = efa_user_comp_handshake(ibucontext, &cmd); + if (err) + goto err_out; + err = efa_com_alloc_uar(&dev->edev, &result); if (err) goto err_out; @@ -1563,6 +1602,8 @@ resp.sub_cqs_per_cq = dev->dev_attr.sub_cqs_per_cq; resp.inline_buf_size = dev->dev_attr.inline_buf_size; resp.max_llq_size = dev->dev_attr.max_llq_size; + resp.max_tx_batch = dev->dev_attr.max_tx_batch; + resp.min_sq_wr = dev->dev_attr.min_sq_depth; if (udata && udata->outlen) { err = ib_copy_to_udata(udata, &resp, @@ -1612,11 +1653,13 @@ switch (entry->mmap_flag) { case EFA_MMAP_IO_NC: err = rdma_user_mmap_io(&ucontext->ibucontext, vma, pfn, length, - pgprot_noncached(vma->vm_page_prot)); + pgprot_noncached(vma->vm_page_prot), + NULL); break; case EFA_MMAP_IO_WC: err = rdma_user_mmap_io(&ucontext->ibucontext, vma, pfn, length, - pgprot_writecombine(vma->vm_page_prot)); + pgprot_writecombine(vma->vm_page_prot), + NULL); break; case EFA_MMAP_DMA_PAGE: for (va = vma->vm_start; va < vma->vm_end; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/affinity.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/affinity.c @@ -218,6 +218,8 @@ for (node = 0; node < node_affinity.num_possible_nodes; node++) hfi1_per_node_cntr[node] = 1; + pci_dev_put(dev); + return 0; } @@ -479,6 +481,8 @@ rvt_get_ibdev_name(&(dd)->verbs_dev.rdi), i, cpu); } + free_cpumask_var(available_cpus); + free_cpumask_var(non_intr_cpus); return 0; fail: --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/chip.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/chip.c @@ -1685,6 +1685,14 @@ return dd->verbs_dev.n_piodrain; } +static u64 access_sw_ctx0_seq_drop(const struct cntr_entry *entry, + void *context, int vl, int mode, u64 data) +{ + struct hfi1_devdata *dd = context; + + return dd->ctx0_seq_drop; +} + static u64 access_sw_vtx_wait(const struct cntr_entry *entry, void *context, int vl, int mode, u64 data) { @@ -4106,6 +4114,7 @@ static struct cntr_entry dev_cntrs[DEV_CNTR_LAST] = { [C_RCV_OVF] = RXE32_DEV_CNTR_ELEM(RcvOverflow, RCV_BUF_OVFL_CNT, CNTR_SYNTH), [C_RX_LEN_ERR] = RXE32_DEV_CNTR_ELEM(RxLenErr, RCV_LENGTH_ERR_CNT, CNTR_SYNTH), +[C_RX_SHORT_ERR] = RXE32_DEV_CNTR_ELEM(RxShrErr, RCV_SHORT_ERR_CNT, CNTR_SYNTH), [C_RX_ICRC_ERR] = RXE32_DEV_CNTR_ELEM(RxICrcErr, RCV_ICRC_ERR_CNT, CNTR_SYNTH), [C_RX_EBP] = RXE32_DEV_CNTR_ELEM(RxEbpCnt, RCV_EBP_CNT, CNTR_SYNTH), [C_RX_TID_FULL] = RXE32_DEV_CNTR_ELEM(RxTIDFullEr, RCV_TID_FULL_ERR_CNT, @@ -4249,6 +4258,8 @@ access_sw_cpu_intr), [C_SW_CPU_RCV_LIM] = CNTR_ELEM("RcvLimit", 0, 0, CNTR_NORMAL, access_sw_cpu_rcv_limit), +[C_SW_CTX0_SEQ_DROP] = CNTR_ELEM("SeqDrop0", 0, 0, CNTR_NORMAL, + access_sw_ctx0_seq_drop), [C_SW_VTX_WAIT] = CNTR_ELEM("vTxWait", 0, 0, CNTR_NORMAL, access_sw_vtx_wait), [C_SW_PIO_WAIT] = CNTR_ELEM("PioWait", 0, 0, CNTR_NORMAL, @@ -12180,6 +12191,7 @@ if (dd->synth_stats_timer.function) del_timer_sync(&dd->synth_stats_timer); + cancel_work_sync(&dd->update_cntr_work); ppd = (struct hfi1_pportdata *)(dd + 1); for (i = 0; i < dd->num_pports; i++, ppd++) { kfree(ppd->cntrs); @@ -13055,15 +13067,16 @@ { u64 reg; u16 idx = src / BITS_PER_REGISTER; + unsigned long flags; - spin_lock(&dd->irq_src_lock); + spin_lock_irqsave(&dd->irq_src_lock, flags); reg = read_csr(dd, CCE_INT_MASK + (8 * idx)); if (set) reg |= bits; else reg &= ~bits; write_csr(dd, CCE_INT_MASK + (8 * idx), reg); - spin_unlock(&dd->irq_src_lock); + spin_unlock_irqrestore(&dd->irq_src_lock, flags); } /** --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/chip.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/chip.h @@ -859,6 +859,7 @@ enum { C_RCV_OVF = 0, C_RX_LEN_ERR, + C_RX_SHORT_ERR, C_RX_ICRC_ERR, C_RX_EBP, C_RX_TID_FULL, @@ -926,6 +927,7 @@ C_DC_PG_STS_TX_MBE_CNT, C_SW_CPU_INTR, C_SW_CPU_RCV_LIM, + C_SW_CTX0_SEQ_DROP, C_SW_VTX_WAIT, C_SW_PIO_WAIT, C_SW_PIO_DRAIN, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/chip_registers.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/chip_registers.h @@ -381,6 +381,7 @@ #define DC_LCB_STS_LINK_TRANSFER_ACTIVE (DC_LCB_CSRS + 0x000000000468) #define DC_LCB_STS_ROUND_TRIP_LTP_CNT (DC_LCB_CSRS + 0x0000000004B0) #define RCV_LENGTH_ERR_CNT 0 +#define RCV_SHORT_ERR_CNT 2 #define RCV_ICRC_ERR_CNT 6 #define RCV_EBP_CNT 9 #define RCV_BUF_OVFL_CNT 10 --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/debugfs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/debugfs.c @@ -985,15 +985,10 @@ static int __i2c_debugfs_open(struct inode *in, struct file *fp, u32 target) { struct hfi1_pportdata *ppd; - int ret; ppd = private2ppd(fp); - ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0); - if (ret) /* failed - release the module */ - module_put(THIS_MODULE); - - return ret; + return acquire_chip_resource(ppd->dd, i2c_target(target), 0); } static int i2c1_debugfs_open(struct inode *in, struct file *fp) @@ -1013,7 +1008,6 @@ ppd = private2ppd(fp); release_chip_resource(ppd->dd, i2c_target(target)); - module_put(THIS_MODULE); return 0; } @@ -1031,18 +1025,10 @@ static int __qsfp_debugfs_open(struct inode *in, struct file *fp, u32 target) { struct hfi1_pportdata *ppd; - int ret; - - if (!try_module_get(THIS_MODULE)) - return -ENODEV; ppd = private2ppd(fp); - ret = acquire_chip_resource(ppd->dd, i2c_target(target), 0); - if (ret) /* failed - release the module */ - module_put(THIS_MODULE); - - return ret; + return acquire_chip_resource(ppd->dd, i2c_target(target), 0); } static int qsfp1_debugfs_open(struct inode *in, struct file *fp) @@ -1062,7 +1048,6 @@ ppd = private2ppd(fp); release_chip_resource(ppd->dd, i2c_target(target)); - module_put(THIS_MODULE); return 0; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/driver.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/driver.c @@ -734,6 +734,7 @@ { int ret; + packet->rcd->dd->ctx0_seq_drop++; /* Set up for the next packet */ packet->rhqoff += packet->rsize; if (packet->rhqoff >= packet->maxcnt) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/efivar.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/efivar.c @@ -152,7 +152,7 @@ unsigned long *size, void **return_data) { char prefix_name[64]; - char name[64]; + char name[128]; int result; int i; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/file_ops.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/file_ops.c @@ -200,23 +200,24 @@ fd = kzalloc(sizeof(*fd), GFP_KERNEL); - if (fd) { - fd->rec_cpu_num = -1; /* no cpu affinity by default */ - fd->mm = current->mm; - mmgrab(fd->mm); - fd->dd = dd; - kobject_get(&fd->dd->kobj); - fp->private_data = fd; - } else { - fp->private_data = NULL; - - if (atomic_dec_and_test(&dd->user_refcount)) - complete(&dd->user_comp); - - return -ENOMEM; - } - + if (!fd || init_srcu_struct(&fd->pq_srcu)) + goto nomem; + spin_lock_init(&fd->pq_rcu_lock); + spin_lock_init(&fd->tid_lock); + spin_lock_init(&fd->invalid_lock); + fd->rec_cpu_num = -1; /* no cpu affinity by default */ + fd->mm = current->mm; + mmgrab(fd->mm); + fd->dd = dd; + kobject_get(&fd->dd->kobj); + fp->private_data = fd; return 0; +nomem: + kfree(fd); + fp->private_data = NULL; + if (atomic_dec_and_test(&dd->user_refcount)) + complete(&dd->user_comp); + return -ENOMEM; } static long hfi1_file_ioctl(struct file *fp, unsigned int cmd, @@ -301,21 +302,32 @@ static ssize_t hfi1_write_iter(struct kiocb *kiocb, struct iov_iter *from) { struct hfi1_filedata *fd = kiocb->ki_filp->private_data; - struct hfi1_user_sdma_pkt_q *pq = fd->pq; + struct hfi1_user_sdma_pkt_q *pq; struct hfi1_user_sdma_comp_q *cq = fd->cq; int done = 0, reqs = 0; unsigned long dim = from->nr_segs; + int idx; - if (!cq || !pq) + if (!HFI1_CAP_IS_KSET(SDMA)) + return -EINVAL; + idx = srcu_read_lock(&fd->pq_srcu); + pq = srcu_dereference(fd->pq, &fd->pq_srcu); + if (!cq || !pq) { + srcu_read_unlock(&fd->pq_srcu, idx); return -EIO; + } - if (!iter_is_iovec(from) || !dim) + if (!iter_is_iovec(from) || !dim) { + srcu_read_unlock(&fd->pq_srcu, idx); return -EINVAL; + } trace_hfi1_sdma_request(fd->dd, fd->uctxt->ctxt, fd->subctxt, dim); - if (atomic_read(&pq->n_reqs) == pq->n_max_reqs) + if (atomic_read(&pq->n_reqs) == pq->n_max_reqs) { + srcu_read_unlock(&fd->pq_srcu, idx); return -ENOSPC; + } while (dim) { int ret; @@ -333,6 +345,7 @@ reqs++; } + srcu_read_unlock(&fd->pq_srcu, idx); return reqs; } @@ -707,6 +720,7 @@ if (atomic_dec_and_test(&dd->user_refcount)) complete(&dd->user_comp); + cleanup_srcu_struct(&fdata->pq_srcu); kfree(fdata); return 0; } @@ -1210,8 +1224,10 @@ goto done; ret = init_user_ctxt(fd, uctxt); - if (ret) + if (ret) { + hfi1_free_ctxt_rcv_groups(uctxt); goto done; + } user_init(uctxt); @@ -1347,12 +1363,15 @@ addr = arg + offsetof(struct hfi1_tid_info, tidcnt); if (copy_to_user((void __user *)addr, &tinfo.tidcnt, sizeof(tinfo.tidcnt))) - return -EFAULT; + ret = -EFAULT; addr = arg + offsetof(struct hfi1_tid_info, length); - if (copy_to_user((void __user *)addr, &tinfo.length, + if (!ret && copy_to_user((void __user *)addr, &tinfo.length, sizeof(tinfo.length))) ret = -EFAULT; + + if (ret) + hfi1_user_exp_rcv_invalid(fd, &tinfo); } return ret; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/firmware.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/firmware.c @@ -1786,6 +1786,7 @@ if (!dd->platform_config.data) { dd_dev_err(dd, "%s: Missing config file\n", __func__); + ret = -EINVAL; goto bail; } ptr = (u32 *)dd->platform_config.data; @@ -1794,6 +1795,7 @@ ptr++; if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) { dd_dev_err(dd, "%s: Bad config file\n", __func__); + ret = -EINVAL; goto bail; } @@ -1817,6 +1819,7 @@ if (file_length > dd->platform_config.size) { dd_dev_info(dd, "%s:File claims to be larger than read size\n", __func__); + ret = -EINVAL; goto bail; } else if (file_length < dd->platform_config.size) { dd_dev_info(dd, @@ -1837,6 +1840,7 @@ dd_dev_err(dd, "%s: Failed validation at offset %ld\n", __func__, (ptr - (u32 *) dd->platform_config.data)); + ret = -EINVAL; goto bail; } @@ -1883,6 +1887,7 @@ __func__, table_type, (ptr - (u32 *) dd->platform_config.data)); + ret = -EINVAL; goto bail; /* We don't trust this file now */ } pcfgcache->config_tables[table_type].table = ptr; @@ -1907,6 +1912,7 @@ __func__, table_type, (ptr - (u32 *)dd->platform_config.data)); + ret = -EINVAL; goto bail; /* We don't trust this file now */ } pcfgcache->config_tables[table_type].table_metadata = @@ -1924,6 +1930,7 @@ dd_dev_err(dd, "%s: Failed CRC check at offset %ld\n", __func__, (ptr - (u32 *)dd->platform_config.data)); + ret = -EINVAL; goto bail; } /* Jump the CRC DWORD */ --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/hfi.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/hfi.h @@ -1153,6 +1153,8 @@ char *boardname; /* human readable board info */ + u64 ctx0_seq_drop; + /* reset value */ u64 z_int_counter; u64 z_rcv_limit; @@ -1436,10 +1438,13 @@ /* Private data for file operations */ struct hfi1_filedata { + struct srcu_struct pq_srcu; struct hfi1_devdata *dd; struct hfi1_ctxtdata *uctxt; struct hfi1_user_sdma_comp_q *cq; - struct hfi1_user_sdma_pkt_q *pq; + /* update side lock for SRCU */ + spinlock_t pq_rcu_lock; + struct hfi1_user_sdma_pkt_q __rcu *pq; u16 subctxt; /* for cpu affinity; -1 if none */ int rec_cpu_num; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/init.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/init.c @@ -543,7 +543,7 @@ u16 shift, mult; u64 src; u32 current_egress_rate; /* Mbits /sec */ - u32 max_pkt_time; + u64 max_pkt_time; /* * max_pkt_time is the maximum packet egress time in units * of the fabric clock period 1/(805 MHz). @@ -664,12 +664,7 @@ ppd->pkeys[default_pkey_idx] = DEFAULT_P_KEY; ppd->part_enforce |= HFI1_PART_ENFORCE_IN; - - if (loopback) { - dd_dev_err(dd, "Faking data partition 0x8001 in idx %u\n", - !default_pkey_idx); - ppd->pkeys[!default_pkey_idx] = 0x8001; - } + ppd->pkeys[0] = 0x8001; INIT_WORK(&ppd->link_vc_work, handle_verify_cap); INIT_WORK(&ppd->link_up_work, handle_link_up); @@ -845,6 +840,29 @@ } /** + * destroy_workqueues - destroy per port workqueues + * @dd: the hfi1_ib device + */ +static void destroy_workqueues(struct hfi1_devdata *dd) +{ + int pidx; + struct hfi1_pportdata *ppd; + + for (pidx = 0; pidx < dd->num_pports; ++pidx) { + ppd = dd->pport + pidx; + + if (ppd->hfi1_wq) { + destroy_workqueue(ppd->hfi1_wq); + ppd->hfi1_wq = NULL; + } + if (ppd->link_wq) { + destroy_workqueue(ppd->link_wq); + ppd->link_wq = NULL; + } + } +} + +/** * enable_general_intr() - Enable the IRQs that will be handled by the * general interrupt handler. * @dd: valid devdata @@ -1117,15 +1135,10 @@ * We can't count on interrupts since we are stopping. */ hfi1_quiet_serdes(ppd); - - if (ppd->hfi1_wq) { - destroy_workqueue(ppd->hfi1_wq); - ppd->hfi1_wq = NULL; - } - if (ppd->link_wq) { - destroy_workqueue(ppd->link_wq); - ppd->link_wq = NULL; - } + if (ppd->hfi1_wq) + flush_workqueue(ppd->hfi1_wq); + if (ppd->link_wq) + flush_workqueue(ppd->link_wq); } sdma_exit(dd); } @@ -1162,7 +1175,7 @@ rcd->egrbufs.rcvtids = NULL; for (e = 0; e < rcd->egrbufs.alloced; e++) { - if (rcd->egrbufs.buffers[e].dma) + if (rcd->egrbufs.buffers[e].addr) dma_free_coherent(&dd->pcidev->dev, rcd->egrbufs.buffers[e].len, rcd->egrbufs.buffers[e].addr, @@ -1814,6 +1827,7 @@ * clear dma engines, etc. */ shutdown_device(dd); + destroy_workqueues(dd); stop_timers(dd); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/iowait.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/iowait.c @@ -81,7 +81,9 @@ void iowait_cancel_work(struct iowait *w) { cancel_work_sync(&iowait_get_ib_work(w)->iowork); - cancel_work_sync(&iowait_get_tid_work(w)->iowork); + /* Make sure that the iowork for TID RDMA is used */ + if (iowait_get_tid_work(w)->iowork.func) + cancel_work_sync(&iowait_get_tid_work(w)->iowork); } /** --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/mmu_rb.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/mmu_rb.c @@ -173,7 +173,7 @@ goto unlock; } __mmu_int_rb_insert(mnode, &handler->root); - list_add(&mnode->list, &handler->lru_list); + list_add_tail(&mnode->list, &handler->lru_list); ret = handler->ops->insert(handler->ops_arg, mnode); if (ret) { @@ -220,8 +220,10 @@ spin_lock_irqsave(&handler->lock, flags); node = __mmu_rb_search(handler, addr, len); if (node) { - if (node->addr == addr && node->len == len) + if (node->addr == addr && node->len == len) { + list_move_tail(&node->list, &handler->lru_list); goto unlock; + } __mmu_int_rb_remove(node, &handler->root); list_del(&node->list); /* remove from LRU list */ ret = true; @@ -242,8 +244,7 @@ INIT_LIST_HEAD(&del_list); spin_lock_irqsave(&handler->lock, flags); - list_for_each_entry_safe_reverse(rbnode, ptr, &handler->lru_list, - list) { + list_for_each_entry_safe(rbnode, ptr, &handler->lru_list, list) { if (handler->ops->evict(handler->ops_arg, rbnode, evict_arg, &stop)) { __mmu_int_rb_remove(rbnode, &handler->root); @@ -255,9 +256,7 @@ } spin_unlock_irqrestore(&handler->lock, flags); - while (!list_empty(&del_list)) { - rbnode = list_first_entry(&del_list, struct mmu_rb_node, list); - list_del(&rbnode->list); + list_for_each_entry_safe(rbnode, ptr, &del_list, list) { handler->ops->remove(handler->ops_arg, rbnode); } } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/pcie.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/pcie.c @@ -45,6 +45,7 @@ * */ +#include #include #include #include @@ -261,12 +262,6 @@ return speed; } -/* return the PCIe link speed from the given link status */ -static u32 extract_width(u16 linkstat) -{ - return (linkstat & PCI_EXP_LNKSTA_NLW) >> PCI_EXP_LNKSTA_NLW_SHIFT; -} - /* read the link status and set dd->{lbus_width,lbus_speed,lbus_info} */ static void update_lbus_info(struct hfi1_devdata *dd) { @@ -279,7 +274,7 @@ return; } - dd->lbus_width = extract_width(linkstat); + dd->lbus_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, linkstat); dd->lbus_speed = extract_speed(linkstat); snprintf(dd->lbus_info, sizeof(dd->lbus_info), "PCIe,%uMHz,x%u", dd->lbus_speed, dd->lbus_width); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/pio.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/pio.c @@ -920,6 +920,7 @@ { u64 reg; struct pio_buf *pbuf; + LIST_HEAD(wake_list); if (!sc) return; @@ -954,19 +955,20 @@ spin_unlock(&sc->release_lock); write_seqlock(&sc->waitlock); - while (!list_empty(&sc->piowait)) { + list_splice_init(&sc->piowait, &wake_list); + write_sequnlock(&sc->waitlock); + while (!list_empty(&wake_list)) { struct iowait *wait; struct rvt_qp *qp; struct hfi1_qp_priv *priv; - wait = list_first_entry(&sc->piowait, struct iowait, list); + wait = list_first_entry(&wake_list, struct iowait, list); qp = iowait_to_qp(wait); priv = qp->priv; list_del_init(&priv->s_iowait.list); priv->s_iowait.lock = NULL; hfi1_qp_wakeup(qp, RVT_S_WAIT_PIO | HFI1_S_WAIT_PIO_DRAIN); } - write_sequnlock(&sc->waitlock); spin_unlock_irq(&sc->alloc_lock); } @@ -2129,7 +2131,7 @@ "Unable to allocate credit return DMA range for NUMA %d\n", i); ret = -ENOMEM; - goto done; + goto free_cr_base; } } set_dev_node(&dd->pcidev->dev, dd->node); @@ -2137,6 +2139,10 @@ ret = 0; done: return ret; + +free_cr_base: + free_credit_return(dd); + goto done; } void free_credit_return(struct hfi1_devdata *dd) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/qp.c @@ -381,7 +381,10 @@ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); - struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device); + struct hfi1_devdata *dd = ppd->dd; + + if (dd->flags & HFI1_SHUTDOWN) + return true; return iowait_schedule(&priv->s_iowait, ppd->hfi1_wq, priv->s_sde ? --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/sdma.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/sdma.c @@ -1329,11 +1329,13 @@ kvfree(sde->tx_ring); sde->tx_ring = NULL; } - spin_lock_irq(&dd->sde_map_lock); - sdma_map_free(rcu_access_pointer(dd->sdma_map)); - RCU_INIT_POINTER(dd->sdma_map, NULL); - spin_unlock_irq(&dd->sde_map_lock); - synchronize_rcu(); + if (rcu_access_pointer(dd->sdma_map)) { + spin_lock_irq(&dd->sde_map_lock); + sdma_map_free(rcu_access_pointer(dd->sdma_map)); + RCU_INIT_POINTER(dd->sdma_map, NULL); + spin_unlock_irq(&dd->sde_map_lock); + synchronize_rcu(); + } kfree(dd->per_sdma); dd->per_sdma = NULL; @@ -3056,6 +3058,7 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) { int i; + struct sdma_desc *descp; /* Handle last descriptor */ if (unlikely((tx->num_desc == (MAX_DESC - 1)))) { @@ -3076,12 +3079,10 @@ if (unlikely(tx->num_desc == MAX_DESC)) goto enomem; - tx->descp = kmalloc_array( - MAX_DESC, - sizeof(struct sdma_desc), - GFP_ATOMIC); - if (!tx->descp) + descp = kmalloc_array(MAX_DESC, sizeof(struct sdma_desc), GFP_ATOMIC); + if (!descp) goto enomem; + tx->descp = descp; /* reserve last descriptor for coalescing */ tx->desc_limit = MAX_DESC - 1; @@ -3202,7 +3203,6 @@ { int rval = 0; - tx->num_desc++; if ((unlikely(tx->num_desc == tx->desc_limit))) { rval = _extend_sdma_tx_descs(dd, tx); if (rval) { @@ -3216,6 +3216,7 @@ SDMA_MAP_NONE, dd->sdma_pad_phys, sizeof(u32) - (tx->packet_len & (sizeof(u32) - 1))); + tx->num_desc++; _sdma_close_tx(dd, tx); return rval; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/sdma.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/sdma.h @@ -672,14 +672,13 @@ static inline void _sdma_close_tx(struct hfi1_devdata *dd, struct sdma_txreq *tx) { - tx->descp[tx->num_desc].qw[0] |= - SDMA_DESC0_LAST_DESC_FLAG; - tx->descp[tx->num_desc].qw[1] |= - dd->default_desc1; + u16 last_desc = tx->num_desc - 1; + + tx->descp[last_desc].qw[0] |= SDMA_DESC0_LAST_DESC_FLAG; + tx->descp[last_desc].qw[1] |= dd->default_desc1; if (tx->flags & SDMA_TXREQ_F_URGENT) - tx->descp[tx->num_desc].qw[1] |= - (SDMA_DESC1_HEAD_TO_HOST_FLAG | - SDMA_DESC1_INT_REQ_FLAG); + tx->descp[last_desc].qw[1] |= (SDMA_DESC1_HEAD_TO_HOST_FLAG | + SDMA_DESC1_INT_REQ_FLAG); } static inline int _sdma_txadd_daddr( @@ -696,6 +695,7 @@ type, addr, len); WARN_ON(len > tx->tlen); + tx->num_desc++; tx->tlen -= len; /* special cases for last */ if (!tx->tlen) { @@ -707,7 +707,6 @@ _sdma_close_tx(dd, tx); } } - tx->num_desc++; return rval; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/sysfs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/sysfs.c @@ -674,7 +674,11 @@ dd_dev_err(dd, "Skipping sc2vl sysfs info, (err %d) port %u\n", ret, port_num); - goto bail; + /* + * Based on the documentation for kobject_init_and_add(), the + * caller should call kobject_put even if this call fails. + */ + goto bail_sc2vl; } kobject_uevent(&ppd->sc2vl_kobj, KOBJ_ADD); @@ -684,7 +688,7 @@ dd_dev_err(dd, "Skipping sl2sc sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sc2vl; + goto bail_sl2sc; } kobject_uevent(&ppd->sl2sc_kobj, KOBJ_ADD); @@ -694,7 +698,7 @@ dd_dev_err(dd, "Skipping vl2mtu sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sl2sc; + goto bail_vl2mtu; } kobject_uevent(&ppd->vl2mtu_kobj, KOBJ_ADD); @@ -704,7 +708,7 @@ dd_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_vl2mtu; + goto bail_cc; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); @@ -742,7 +746,6 @@ kobject_put(&ppd->sl2sc_kobj); bail_sc2vl: kobject_put(&ppd->sc2vl_kobj); -bail: return ret; } @@ -853,8 +856,13 @@ return 0; bail: - for (i = 0; i < dd->num_sdma; i++) - kobject_del(&dd->per_sdma[i].kobj); + /* + * The function kobject_put() will call kobject_del() if the kobject + * has been added successfully. The sysfs files created under the + * kobject directory will also be removed during the process. + */ + for (; i >= 0; i--) + kobject_put(&dd->per_sdma[i].kobj); return ret; } @@ -867,6 +875,10 @@ struct hfi1_pportdata *ppd; int i; + /* Unwind operations in hfi1_verbs_register_sysfs() */ + for (i = 0; i < dd->num_sdma; i++) + kobject_put(&dd->per_sdma[i].kobj); + for (i = 0; i < dd->num_pports; i++) { ppd = &dd->pport[i]; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/tid_rdma.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/tid_rdma.c @@ -3215,6 +3215,7 @@ case IB_WR_ATOMIC_CMP_AND_SWP: case IB_WR_ATOMIC_FETCH_AND_ADD: case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_WRITE_WITH_IMM: switch (prev->wr.opcode) { case IB_WR_TID_RDMA_WRITE: req = wqe_to_tid_req(prev); @@ -4633,6 +4634,15 @@ */ fpsn = full_flow_psn(flow, flow->flow_state.spsn); req->r_ack_psn = psn; + /* + * If resync_psn points to the last flow PSN for a + * segment and the new segment (likely from a new + * request) starts with a new generation number, we + * need to adjust resync_psn accordingly. + */ + if (flow->flow_state.generation != + (resync_psn >> HFI1_KDETH_BTH_SEQ_SHIFT)) + resync_psn = mask_psn(fpsn - 1); flow->resync_npkts += delta_psn(mask_psn(resync_psn + 1), fpsn); /* @@ -5397,7 +5407,10 @@ struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); struct hfi1_pportdata *ppd = ppd_from_ibp(ibp); - struct hfi1_devdata *dd = dd_from_ibdev(qp->ibqp.device); + struct hfi1_devdata *dd = ppd->dd; + + if ((dd->flags & HFI1_SHUTDOWN)) + return true; return iowait_tid_schedule(&priv->s_iowait, ppd->hfi1_wq, priv->s_sde ? --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -90,9 +90,6 @@ struct hfi1_devdata *dd = uctxt->dd; int ret = 0; - spin_lock_init(&fd->tid_lock); - spin_lock_init(&fd->invalid_lock); - fd->entry_to_rb = kcalloc(uctxt->expected_count, sizeof(struct rb_node *), GFP_KERNEL); @@ -165,10 +162,12 @@ if (fd->handler) { hfi1_mmu_rb_unregister(fd->handler); } else { + mutex_lock(&uctxt->exp_mutex); if (!EXP_TID_SET_EMPTY(uctxt->tid_full_list)) unlock_exp_tids(uctxt, &uctxt->tid_full_list, fd); if (!EXP_TID_SET_EMPTY(uctxt->tid_used_list)) unlock_exp_tids(uctxt, &uctxt->tid_used_list, fd); + mutex_unlock(&uctxt->exp_mutex); } kfree(fd->invalid_tids); @@ -216,16 +215,11 @@ static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf) { int pinned; - unsigned int npages; + unsigned int npages = tidbuf->npages; unsigned long vaddr = tidbuf->vaddr; struct page **pages = NULL; struct hfi1_devdata *dd = fd->uctxt->dd; - /* Get the number of pages the user buffer spans */ - npages = num_user_pages(vaddr, tidbuf->length); - if (!npages) - return -EINVAL; - if (npages > fd->uctxt->expected_count) { dd_dev_err(dd, "Expected buffer too big\n"); return -EINVAL; @@ -259,7 +253,6 @@ return pinned; } tidbuf->pages = pages; - tidbuf->npages = npages; fd->tid_n_pinned += pinned; return pinned; } @@ -326,6 +319,8 @@ if (!PAGE_ALIGNED(tinfo->vaddr)) return -EINVAL; + if (tinfo->length == 0) + return -EINVAL; tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL); if (!tidbuf) @@ -333,43 +328,42 @@ tidbuf->vaddr = tinfo->vaddr; tidbuf->length = tinfo->length; + tidbuf->npages = num_user_pages(tidbuf->vaddr, tidbuf->length); tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets), GFP_KERNEL); if (!tidbuf->psets) { - kfree(tidbuf); - return -ENOMEM; + ret = -ENOMEM; + goto fail_release_mem; } pinned = pin_rcv_pages(fd, tidbuf); if (pinned <= 0) { - kfree(tidbuf->psets); - kfree(tidbuf); - return pinned; + ret = (pinned < 0) ? pinned : -ENOSPC; + goto fail_unpin; } /* Find sets of physically contiguous pages */ tidbuf->n_psets = find_phys_blocks(tidbuf, pinned); - /* - * We don't need to access this under a lock since tid_used is per - * process and the same process cannot be in hfi1_user_exp_rcv_clear() - * and hfi1_user_exp_rcv_setup() at the same time. - */ + /* Reserve the number of expected tids to be used. */ spin_lock(&fd->tid_lock); if (fd->tid_used + tidbuf->n_psets > fd->tid_limit) pageset_count = fd->tid_limit - fd->tid_used; else pageset_count = tidbuf->n_psets; + fd->tid_used += pageset_count; spin_unlock(&fd->tid_lock); - if (!pageset_count) - goto bail; + if (!pageset_count) { + ret = -ENOSPC; + goto fail_unreserve; + } ngroups = pageset_count / dd->rcv_entries.group_size; tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL); if (!tidlist) { ret = -ENOMEM; - goto nomem; + goto fail_unreserve; } tididx = 0; @@ -465,43 +459,60 @@ } unlock: mutex_unlock(&uctxt->exp_mutex); -nomem: hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx, mapped_pages, ret); - if (tididx) { - spin_lock(&fd->tid_lock); - fd->tid_used += tididx; - spin_unlock(&fd->tid_lock); - tinfo->tidcnt = tididx; - tinfo->length = mapped_pages * PAGE_SIZE; - - if (copy_to_user(u64_to_user_ptr(tinfo->tidlist), - tidlist, sizeof(tidlist[0]) * tididx)) { - /* - * On failure to copy to the user level, we need to undo - * everything done so far so we don't leak resources. - */ - tinfo->tidlist = (unsigned long)&tidlist; - hfi1_user_exp_rcv_clear(fd, tinfo); - tinfo->tidlist = 0; - ret = -EFAULT; - goto bail; - } + + /* fail if nothing was programmed, set error if none provided */ + if (tididx == 0) { + if (ret >= 0) + ret = -ENOSPC; + goto fail_unreserve; } - /* - * If not everything was mapped (due to insufficient RcvArray entries, - * for example), unpin all unmapped pages so we can pin them nex time. - */ - if (mapped_pages != pinned) - unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, - (pinned - mapped_pages), false); -bail: + /* adjust reserved tid_used to actual count */ + spin_lock(&fd->tid_lock); + fd->tid_used -= pageset_count - tididx; + spin_unlock(&fd->tid_lock); + + /* unpin all pages not covered by a TID */ + unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages, + false); + + tinfo->tidcnt = tididx; + tinfo->length = mapped_pages * PAGE_SIZE; + + if (copy_to_user(u64_to_user_ptr(tinfo->tidlist), + tidlist, sizeof(tidlist[0]) * tididx)) { + ret = -EFAULT; + goto fail_unprogram; + } + + kfree(tidbuf->pages); kfree(tidbuf->psets); + kfree(tidbuf); kfree(tidlist); + return 0; + +fail_unprogram: + /* unprogram, unmap, and unpin all allocated TIDs */ + tinfo->tidlist = (unsigned long)tidlist; + hfi1_user_exp_rcv_clear(fd, tinfo); + tinfo->tidlist = 0; + pinned = 0; /* nothing left to unpin */ + pageset_count = 0; /* nothing left reserved */ +fail_unreserve: + spin_lock(&fd->tid_lock); + fd->tid_used -= pageset_count; + spin_unlock(&fd->tid_lock); +fail_unpin: + if (pinned > 0) + unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false); +fail_release_mem: kfree(tidbuf->pages); + kfree(tidbuf->psets); kfree(tidbuf); - return ret > 0 ? 0 : ret; + kfree(tidlist); + return ret; } int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/user_sdma.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/user_sdma.c @@ -141,6 +141,7 @@ */ xchg(&pq->state, SDMA_PKT_Q_DEFERRED); if (list_empty(&pq->busy.list)) { + pq->busy.lock = &sde->waitlock; iowait_get_priority(&pq->busy); iowait_queue(pkts_sent, &pq->busy, &sde->dmawait); } @@ -155,6 +156,7 @@ { struct hfi1_user_sdma_pkt_q *pq = container_of(wait, struct hfi1_user_sdma_pkt_q, busy); + pq->busy.lock = NULL; xchg(&pq->state, SDMA_PKT_Q_ACTIVE); wake_up(&wait->wait_dma); }; @@ -179,7 +181,6 @@ pq = kzalloc(sizeof(*pq), GFP_KERNEL); if (!pq) return -ENOMEM; - pq->dd = dd; pq->ctxt = uctxt->ctxt; pq->subctxt = fd->subctxt; @@ -236,7 +237,7 @@ goto pq_mmu_fail; } - fd->pq = pq; + rcu_assign_pointer(fd->pq, pq); fd->cq = cq; return 0; @@ -257,6 +258,21 @@ return ret; } +static void flush_pq_iowait(struct hfi1_user_sdma_pkt_q *pq) +{ + unsigned long flags; + seqlock_t *lock = pq->busy.lock; + + if (!lock) + return; + write_seqlock_irqsave(lock, flags); + if (!list_empty(&pq->busy.list)) { + list_del_init(&pq->busy.list); + pq->busy.lock = NULL; + } + write_sequnlock_irqrestore(lock, flags); +} + int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd, struct hfi1_ctxtdata *uctxt) { @@ -264,8 +280,14 @@ trace_hfi1_sdma_user_free_queues(uctxt->dd, uctxt->ctxt, fd->subctxt); - pq = fd->pq; + spin_lock(&fd->pq_rcu_lock); + pq = srcu_dereference_check(fd->pq, &fd->pq_srcu, + lockdep_is_held(&fd->pq_rcu_lock)); if (pq) { + rcu_assign_pointer(fd->pq, NULL); + spin_unlock(&fd->pq_rcu_lock); + synchronize_srcu(&fd->pq_srcu); + /* at this point there can be no more new requests */ if (pq->handler) hfi1_mmu_rb_unregister(pq->handler); iowait_sdma_drain(&pq->busy); @@ -276,8 +298,10 @@ kfree(pq->reqs); kfree(pq->req_in_use); kmem_cache_destroy(pq->txreq_cache); + flush_pq_iowait(pq); kfree(pq); - fd->pq = NULL; + } else { + spin_unlock(&fd->pq_rcu_lock); } if (fd->cq) { vfree(fd->cq->comps); @@ -321,7 +345,8 @@ { int ret = 0, i; struct hfi1_ctxtdata *uctxt = fd->uctxt; - struct hfi1_user_sdma_pkt_q *pq = fd->pq; + struct hfi1_user_sdma_pkt_q *pq = + srcu_dereference(fd->pq, &fd->pq_srcu); struct hfi1_user_sdma_comp_q *cq = fd->cq; struct hfi1_devdata *dd = pq->dd; unsigned long idx = 0; @@ -564,10 +589,6 @@ set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); pq->state = SDMA_PKT_Q_ACTIVE; - /* Send the first N packets in the request to buy us some time */ - ret = user_sdma_send_pkts(req, pcount); - if (unlikely(ret < 0 && ret != -EBUSY)) - goto free_req; /* * This is a somewhat blocking send implementation. @@ -580,11 +601,12 @@ if (ret < 0) { if (ret != -EBUSY) goto free_req; - wait_event_interruptible_timeout( + if (wait_event_interruptible_timeout( pq->busy.wait_dma, - (pq->state == SDMA_PKT_Q_ACTIVE), + pq->state == SDMA_PKT_Q_ACTIVE, msecs_to_jiffies( - SDMA_IOWAIT_TIMEOUT)); + SDMA_IOWAIT_TIMEOUT)) <= 0) + flush_pq_iowait(pq); } } *count += idx; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hfi1/verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hfi1/verbs.c @@ -515,10 +515,11 @@ opa_get_lid(packet->dlid, 9B)); if (!mcast) goto drop; + rcu_read_lock(); list_for_each_entry_rcu(p, &mcast->qp_list, list) { packet->qp = p->qp; if (hfi1_do_pkey_check(packet)) - goto drop; + goto unlock_drop; spin_lock_irqsave(&packet->qp->r_lock, flags); packet_handler = qp_ok(packet); if (likely(packet_handler)) @@ -527,6 +528,7 @@ ibp->rvp.n_pkt_drops++; spin_unlock_irqrestore(&packet->qp->r_lock, flags); } + rcu_read_unlock(); /* * Notify rvt_multicast_detach() if it is waiting for us * to finish. --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/Kconfig +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/Kconfig @@ -1,23 +1,34 @@ # SPDX-License-Identifier: GPL-2.0-only config INFINIBAND_HNS - bool "HNS RoCE Driver" + tristate "HNS RoCE Driver" depends on NET_VENDOR_HISILICON depends on ARM64 || (COMPILE_TEST && 64BIT) + depends on (HNS_DSAF && HNS_ENET) || HNS3 ---help--- This is a RoCE/RDMA driver for the Hisilicon RoCE engine. The engine is used in Hisilicon Hip06 and more further ICT SoC based on platform device. + To compile HIP06 or HIP08 driver as module, choose M here. + config INFINIBAND_HNS_HIP06 - tristate "Hisilicon Hip06 Family RoCE support" + bool "Hisilicon Hip06 Family RoCE support" depends on INFINIBAND_HNS && HNS && HNS_DSAF && HNS_ENET + depends on INFINIBAND_HNS=m || (HNS_DSAF=y && HNS_ENET=y) ---help--- RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip06 and Hip07 SoC. These RoCE engines are platform devices. + To compile this driver, choose Y here: if INFINIBAND_HNS is m, this + module will be called hns-roce-hw-v1 + config INFINIBAND_HNS_HIP08 - tristate "Hisilicon Hip08 Family RoCE support" + bool "Hisilicon Hip08 Family RoCE support" depends on INFINIBAND_HNS && PCI && HNS3 + depends on INFINIBAND_HNS=m || HNS3=y ---help--- RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip08 SoC. The RoCE engine is a PCI device. + + To compile this driver, choose Y here: if INFINIBAND_HNS is m, this + module will be called hns-roce-hw-v2. --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/Makefile +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/Makefile @@ -9,8 +9,12 @@ hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \ hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o +ifdef CONFIG_INFINIBAND_HNS_HIP06 hns-roce-hw-v1-objs := hns_roce_hw_v1.o $(hns-roce-objs) -obj-$(CONFIG_INFINIBAND_HNS_HIP06) += hns-roce-hw-v1.o +obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v1.o +endif +ifdef CONFIG_INFINIBAND_HNS_HIP08 hns-roce-hw-v2-objs := hns_roce_hw_v2.o hns_roce_hw_v2_dfx.o $(hns-roce-objs) -obj-$(CONFIG_INFINIBAND_HNS_HIP08) += hns-roce-hw-v2.o +obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v2.o +endif --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_ah.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_ah.c @@ -46,32 +46,32 @@ const struct ib_gid_attr *gid_attr; struct device *dev = hr_dev->dev; struct hns_roce_ah *ah = to_hr_ah(ibah); - u16 vlan_tag = 0xffff; const struct ib_global_route *grh = rdma_ah_read_grh(ah_attr); + u16 vlan_id = 0xffff; bool vlan_en = false; int ret; gid_attr = ah_attr->grh.sgid_attr; - ret = rdma_read_gid_l2_fields(gid_attr, &vlan_tag, NULL); + ret = rdma_read_gid_l2_fields(gid_attr, &vlan_id, NULL); if (ret) return ret; /* Get mac address */ memcpy(ah->av.mac, ah_attr->roce.dmac, ETH_ALEN); - if (vlan_tag < VLAN_CFI_MASK) { + if (vlan_id < VLAN_N_VID) { vlan_en = true; - vlan_tag |= (rdma_ah_get_sl(ah_attr) & + vlan_id |= (rdma_ah_get_sl(ah_attr) & HNS_ROCE_VLAN_SL_BIT_MASK) << HNS_ROCE_VLAN_SL_SHIFT; } ah->av.port = rdma_ah_get_port_num(ah_attr); ah->av.gid_index = grh->sgid_index; - ah->av.vlan = vlan_tag; + ah->av.vlan_id = vlan_id; ah->av.vlan_en = vlan_en; - dev_dbg(dev, "gid_index = 0x%x,vlan = 0x%x\n", ah->av.gid_index, - ah->av.vlan); + dev_dbg(dev, "gid_index = 0x%x,vlan_id = 0x%x\n", ah->av.gid_index, + ah->av.vlan_id); if (rdma_ah_get_static_rate(ah_attr)) ah->av.stat_rate = IB_RATE_10_GBPS; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_alloc.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_alloc.c @@ -55,7 +55,7 @@ bitmap->last = 0; *obj |= bitmap->top; } else { - ret = -1; + ret = -EINVAL; } spin_unlock(&bitmap->lock); @@ -100,7 +100,7 @@ } *obj |= bitmap->top; } else { - ret = -1; + ret = -EINVAL; } spin_unlock(&bitmap->lock); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_cmd.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_cmd.h @@ -115,12 +115,12 @@ enum { /* TPT commands */ - HNS_ROCE_CMD_SW2HW_MPT = 0xd, - HNS_ROCE_CMD_HW2SW_MPT = 0xf, + HNS_ROCE_CMD_CREATE_MPT = 0xd, + HNS_ROCE_CMD_DESTROY_MPT = 0xf, /* CQ commands */ - HNS_ROCE_CMD_SW2HW_CQ = 0x16, - HNS_ROCE_CMD_HW2SW_CQ = 0x17, + HNS_ROCE_CMD_CREATE_CQC = 0x16, + HNS_ROCE_CMD_DESTROY_CQC = 0x17, /* QP/EE commands */ HNS_ROCE_CMD_RST2INIT_QP = 0x19, @@ -129,14 +129,14 @@ HNS_ROCE_CMD_RTS2RTS_QP = 0x1c, HNS_ROCE_CMD_2ERR_QP = 0x1e, HNS_ROCE_CMD_RTS2SQD_QP = 0x1f, - HNS_ROCE_CMD_SQD2SQD_QP = 0x38, HNS_ROCE_CMD_SQD2RTS_QP = 0x20, HNS_ROCE_CMD_2RST_QP = 0x21, HNS_ROCE_CMD_QUERY_QP = 0x22, - HNS_ROCE_CMD_SW2HW_SRQ = 0x70, + HNS_ROCE_CMD_SQD2SQD_QP = 0x38, + HNS_ROCE_CMD_CREATE_SRQ = 0x70, HNS_ROCE_CMD_MODIFY_SRQC = 0x72, HNS_ROCE_CMD_QUERY_SRQC = 0x73, - HNS_ROCE_CMD_HW2SW_SRQ = 0x74, + HNS_ROCE_CMD_DESTROY_SRQ = 0x74, }; int hns_roce_cmd_mbox(struct hns_roce_dev *hr_dev, u64 in_param, u64 out_param, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_cq.c @@ -39,51 +39,8 @@ #include #include "hns_roce_common.h" -static void hns_roce_ib_cq_comp(struct hns_roce_cq *hr_cq) -{ - struct ib_cq *ibcq = &hr_cq->ib_cq; - - ibcq->comp_handler(ibcq, ibcq->cq_context); -} - -static void hns_roce_ib_cq_event(struct hns_roce_cq *hr_cq, - enum hns_roce_event event_type) -{ - struct hns_roce_dev *hr_dev; - struct ib_event event; - struct ib_cq *ibcq; - - ibcq = &hr_cq->ib_cq; - hr_dev = to_hr_dev(ibcq->device); - - if (event_type != HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID && - event_type != HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR && - event_type != HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) { - dev_err(hr_dev->dev, - "hns_roce_ib: Unexpected event type 0x%x on CQ %06lx\n", - event_type, hr_cq->cqn); - return; - } - - if (ibcq->event_handler) { - event.device = ibcq->device; - event.event = IB_EVENT_CQ_ERR; - event.element.cq = ibcq; - ibcq->event_handler(&event, ibcq->cq_context); - } -} - -static int hns_roce_sw2hw_cq(struct hns_roce_dev *dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long cq_num) -{ - return hns_roce_cmd_mbox(dev, mailbox->dma, 0, cq_num, 0, - HNS_ROCE_CMD_SW2HW_CQ, HNS_ROCE_CMD_TIMEOUT_MSECS); -} - -static int hns_roce_cq_alloc(struct hns_roce_dev *hr_dev, int nent, - struct hns_roce_mtt *hr_mtt, - struct hns_roce_cq *hr_cq, int vector) +static int hns_roce_alloc_cqc(struct hns_roce_dev *hr_dev, + struct hns_roce_cq *hr_cq) { struct hns_roce_cmd_mailbox *mailbox; struct hns_roce_hem_table *mtt_table; @@ -101,35 +58,32 @@ else mtt_table = &hr_dev->mr_table.mtt_table; - mtts = hns_roce_table_find(hr_dev, mtt_table, - hr_mtt->first_seg, &dma_handle); - if (!mtts) { - dev_err(dev, "CQ alloc.Failed to find cq buf addr.\n"); - return -EINVAL; - } + mtts = hns_roce_table_find(hr_dev, mtt_table, hr_cq->mtt.first_seg, + &dma_handle); - if (vector >= hr_dev->caps.num_comp_vectors) { - dev_err(dev, "CQ alloc.Invalid vector.\n"); + if (!mtts) { + dev_err(dev, "Failed to find mtt for CQ buf.\n"); return -EINVAL; } - hr_cq->vector = vector; ret = hns_roce_bitmap_alloc(&cq_table->bitmap, &hr_cq->cqn); - if (ret == -1) { - dev_err(dev, "CQ alloc.Failed to alloc index.\n"); - return -ENOMEM; + if (ret) { + dev_err(dev, "Num of CQ out of range.\n"); + return ret; } /* Get CQC memory HEM(Hardware Entry Memory) table */ ret = hns_roce_table_get(hr_dev, &cq_table->table, hr_cq->cqn); if (ret) { - dev_err(dev, "CQ alloc.Failed to get context mem.\n"); + dev_err(dev, + "Get context mem failed(%d) when CQ(0x%lx) alloc.\n", + ret, hr_cq->cqn); goto err_out; } ret = xa_err(xa_store(&cq_table->array, hr_cq->cqn, hr_cq, GFP_KERNEL)); if (ret) { - dev_err(dev, "CQ alloc failed xa_store.\n"); + dev_err(dev, "Failed to xa_store CQ.\n"); goto err_put; } @@ -140,14 +94,16 @@ goto err_xa; } - hr_dev->hw->write_cqc(hr_dev, hr_cq, mailbox->buf, mtts, dma_handle, - nent, vector); + hr_dev->hw->write_cqc(hr_dev, hr_cq, mailbox->buf, mtts, dma_handle); /* Send mailbox to hw */ - ret = hns_roce_sw2hw_cq(hr_dev, mailbox, hr_cq->cqn); + ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, hr_cq->cqn, 0, + HNS_ROCE_CMD_CREATE_CQC, HNS_ROCE_CMD_TIMEOUT_MSECS); hns_roce_free_cmd_mailbox(hr_dev, mailbox); if (ret) { - dev_err(dev, "CQ alloc.Failed to cmd mailbox.\n"); + dev_err(dev, + "Send cmd mailbox failed(%d) when CQ(0x%lx) alloc.\n", + ret, hr_cq->cqn); goto err_xa; } @@ -170,24 +126,17 @@ return ret; } -static int hns_roce_hw2sw_cq(struct hns_roce_dev *dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long cq_num) -{ - return hns_roce_cmd_mbox(dev, 0, mailbox ? mailbox->dma : 0, cq_num, - mailbox ? 0 : 1, HNS_ROCE_CMD_HW2SW_CQ, - HNS_ROCE_CMD_TIMEOUT_MSECS); -} - -void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) +void hns_roce_free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) { struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; struct device *dev = hr_dev->dev; int ret; - ret = hns_roce_hw2sw_cq(hr_dev, NULL, hr_cq->cqn); + ret = hns_roce_cmd_mbox(hr_dev, 0, 0, hr_cq->cqn, 1, + HNS_ROCE_CMD_DESTROY_CQC, + HNS_ROCE_CMD_TIMEOUT_MSECS); if (ret) - dev_err(dev, "HW2SW_CQ failed (%d) for CQN %06lx\n", ret, + dev_err(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n", ret, hr_cq->cqn); xa_erase(&cq_table->array, hr_cq->cqn); @@ -204,103 +153,91 @@ hns_roce_bitmap_free(&cq_table->bitmap, hr_cq->cqn, BITMAP_NO_RR); } -static int hns_roce_ib_get_cq_umem(struct hns_roce_dev *hr_dev, - struct ib_udata *udata, - struct hns_roce_cq_buf *buf, - struct ib_umem **umem, u64 buf_addr, int cqe) -{ - int ret; - u32 page_shift; +static int get_cq_umem(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, + struct hns_roce_ib_create_cq ucmd, + struct ib_udata *udata) +{ + struct hns_roce_buf *buf = &hr_cq->buf; + struct hns_roce_mtt *mtt = &hr_cq->mtt; + struct ib_umem **umem = &hr_cq->umem; u32 npages; + int ret; - *umem = ib_umem_get(udata, buf_addr, cqe * hr_dev->caps.cq_entry_sz, - IB_ACCESS_LOCAL_WRITE, 1); + *umem = ib_umem_get(&hr_dev->ib_dev, ucmd.buf_addr, buf->size, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(*umem)) return PTR_ERR(*umem); if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) - buf->hr_mtt.mtt_type = MTT_TYPE_CQE; + mtt->mtt_type = MTT_TYPE_CQE; else - buf->hr_mtt.mtt_type = MTT_TYPE_WQE; + mtt->mtt_type = MTT_TYPE_WQE; - if (hr_dev->caps.cqe_buf_pg_sz) { - npages = (ib_umem_page_count(*umem) + - (1 << hr_dev->caps.cqe_buf_pg_sz) - 1) / - (1 << hr_dev->caps.cqe_buf_pg_sz); - page_shift = PAGE_SHIFT + hr_dev->caps.cqe_buf_pg_sz; - ret = hns_roce_mtt_init(hr_dev, npages, page_shift, - &buf->hr_mtt); - } else { - ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(*umem), - PAGE_SHIFT, &buf->hr_mtt); - } + npages = DIV_ROUND_UP(ib_umem_page_count(*umem), + 1 << hr_dev->caps.cqe_buf_pg_sz); + ret = hns_roce_mtt_init(hr_dev, npages, buf->page_shift, mtt); if (ret) goto err_buf; - ret = hns_roce_ib_umem_write_mtt(hr_dev, &buf->hr_mtt, *umem); + ret = hns_roce_ib_umem_write_mtt(hr_dev, mtt, *umem); if (ret) goto err_mtt; return 0; err_mtt: - hns_roce_mtt_cleanup(hr_dev, &buf->hr_mtt); + hns_roce_mtt_cleanup(hr_dev, mtt); err_buf: ib_umem_release(*umem); return ret; } -static int hns_roce_ib_alloc_cq_buf(struct hns_roce_dev *hr_dev, - struct hns_roce_cq_buf *buf, u32 nent) +static int alloc_cq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) { + struct hns_roce_buf *buf = &hr_cq->buf; + struct hns_roce_mtt *mtt = &hr_cq->mtt; int ret; - u32 page_shift = PAGE_SHIFT + hr_dev->caps.cqe_buf_pg_sz; - ret = hns_roce_buf_alloc(hr_dev, nent * hr_dev->caps.cq_entry_sz, - (1 << page_shift) * 2, &buf->hr_buf, - page_shift); + ret = hns_roce_buf_alloc(hr_dev, buf->size, (1 << buf->page_shift) * 2, + buf, buf->page_shift); if (ret) goto out; if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) - buf->hr_mtt.mtt_type = MTT_TYPE_CQE; + mtt->mtt_type = MTT_TYPE_CQE; else - buf->hr_mtt.mtt_type = MTT_TYPE_WQE; + mtt->mtt_type = MTT_TYPE_WQE; - ret = hns_roce_mtt_init(hr_dev, buf->hr_buf.npages, - buf->hr_buf.page_shift, &buf->hr_mtt); + ret = hns_roce_mtt_init(hr_dev, buf->npages, buf->page_shift, mtt); if (ret) goto err_buf; - ret = hns_roce_buf_write_mtt(hr_dev, &buf->hr_mtt, &buf->hr_buf); + ret = hns_roce_buf_write_mtt(hr_dev, mtt, buf); if (ret) goto err_mtt; return 0; err_mtt: - hns_roce_mtt_cleanup(hr_dev, &buf->hr_mtt); + hns_roce_mtt_cleanup(hr_dev, mtt); err_buf: - hns_roce_buf_free(hr_dev, nent * hr_dev->caps.cq_entry_sz, - &buf->hr_buf); + hns_roce_buf_free(hr_dev, buf->size, buf); + out: return ret; } -static void hns_roce_ib_free_cq_buf(struct hns_roce_dev *hr_dev, - struct hns_roce_cq_buf *buf, int cqe) +static void free_cq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) { - hns_roce_buf_free(hr_dev, (cqe + 1) * hr_dev->caps.cq_entry_sz, - &buf->hr_buf); + hns_roce_buf_free(hr_dev, hr_cq->buf.size, &hr_cq->buf); } static int create_user_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, struct ib_udata *udata, - struct hns_roce_ib_create_cq_resp *resp, - int cq_entries) + struct hns_roce_ib_create_cq_resp *resp) { struct hns_roce_ib_create_cq ucmd; struct device *dev = hr_dev->dev; @@ -314,9 +251,7 @@ } /* Get user space address, write it into mtt table */ - ret = hns_roce_ib_get_cq_umem(hr_dev, udata, &hr_cq->hr_buf, - &hr_cq->umem, ucmd.buf_addr, - cq_entries); + ret = get_cq_umem(hr_dev, hr_cq, ucmd, udata); if (ret) { dev_err(dev, "Failed to get_cq_umem.\n"); return ret; @@ -337,17 +272,16 @@ return 0; err_mtt: - hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); + hns_roce_mtt_cleanup(hr_dev, &hr_cq->mtt); ib_umem_release(hr_cq->umem); return ret; } static int create_kernel_cq(struct hns_roce_dev *hr_dev, - struct hns_roce_cq *hr_cq, int cq_entries) + struct hns_roce_cq *hr_cq) { struct device *dev = hr_dev->dev; - struct hns_roce_uar *uar; int ret; if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) { @@ -361,15 +295,14 @@ } /* Init mtt table and write buff address to mtt table */ - ret = hns_roce_ib_alloc_cq_buf(hr_dev, &hr_cq->hr_buf, cq_entries); + ret = alloc_cq_buf(hr_dev, hr_cq); if (ret) { dev_err(dev, "Failed to alloc_cq_buf.\n"); goto err_db; } - uar = &hr_dev->priv_uar; hr_cq->cq_db_l = hr_dev->reg_base + hr_dev->odb_offset + - DB_REG_OFFSET * uar->index; + DB_REG_OFFSET * hr_dev->priv_uar.index; return 0; @@ -392,64 +325,71 @@ (udata->outlen >= sizeof(*resp))) hns_roce_db_unmap_user(context, &hr_cq->db); - hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); + hns_roce_mtt_cleanup(hr_dev, &hr_cq->mtt); ib_umem_release(hr_cq->umem); } static void destroy_kernel_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq) { - hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); - hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, hr_cq->ib_cq.cqe); + hns_roce_mtt_cleanup(hr_dev, &hr_cq->mtt); + free_cq_buf(hr_dev, hr_cq); if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) hns_roce_free_db(hr_dev, &hr_cq->db); } -int hns_roce_ib_create_cq(struct ib_cq *ib_cq, - const struct ib_cq_init_attr *attr, - struct ib_udata *udata) +int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, + struct ib_udata *udata) { struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device); - struct device *dev = hr_dev->dev; struct hns_roce_ib_create_cq_resp resp = {}; struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq); + struct device *dev = hr_dev->dev; int vector = attr->comp_vector; - int cq_entries = attr->cqe; + u32 cq_entries = attr->cqe; int ret; if (cq_entries < 1 || cq_entries > hr_dev->caps.max_cqes) { - dev_err(dev, "Creat CQ failed. entries=%d, max=%d\n", + dev_err(dev, "Create CQ failed. entries=%d, max=%d\n", cq_entries, hr_dev->caps.max_cqes); return -EINVAL; } - if (hr_dev->caps.min_cqes) - cq_entries = max(cq_entries, hr_dev->caps.min_cqes); + if (vector >= hr_dev->caps.num_comp_vectors) { + dev_err(dev, "Create CQ failed, vector=%d, max=%d\n", + vector, hr_dev->caps.num_comp_vectors); + return -EINVAL; + } - cq_entries = roundup_pow_of_two((unsigned int)cq_entries); - hr_cq->ib_cq.cqe = cq_entries - 1; + cq_entries = max(cq_entries, hr_dev->caps.min_cqes); + cq_entries = roundup_pow_of_two(cq_entries); + hr_cq->ib_cq.cqe = cq_entries - 1; /* used as cqe index */ + hr_cq->cq_depth = cq_entries; + hr_cq->vector = vector; + hr_cq->buf.size = hr_cq->cq_depth * hr_dev->caps.cq_entry_sz; + hr_cq->buf.page_shift = PAGE_SHIFT + hr_dev->caps.cqe_buf_pg_sz; spin_lock_init(&hr_cq->lock); + INIT_LIST_HEAD(&hr_cq->sq_list); + INIT_LIST_HEAD(&hr_cq->rq_list); if (udata) { - ret = create_user_cq(hr_dev, hr_cq, udata, &resp, cq_entries); + ret = create_user_cq(hr_dev, hr_cq, udata, &resp); if (ret) { dev_err(dev, "Create cq failed in user mode!\n"); goto err_cq; } } else { - ret = create_kernel_cq(hr_dev, hr_cq, cq_entries); + ret = create_kernel_cq(hr_dev, hr_cq); if (ret) { dev_err(dev, "Create cq failed in kernel mode!\n"); goto err_cq; } } - /* Allocate cq index, fill cq_context */ - ret = hns_roce_cq_alloc(hr_dev, cq_entries, &hr_cq->hr_buf.hr_mtt, - hr_cq, vector); + ret = hns_roce_alloc_cqc(hr_dev, hr_cq); if (ret) { - dev_err(dev, "Creat CQ .Failed to cq_alloc.\n"); + dev_err(dev, "Alloc CQ failed(%d).\n", ret); goto err_dbmap; } @@ -462,11 +402,6 @@ if (!udata && hr_cq->tptr_addr) *hr_cq->tptr_addr = 0; - /* Get created cq handler and carry out event */ - hr_cq->comp = hns_roce_ib_cq_comp; - hr_cq->event = hns_roce_ib_cq_event; - hr_cq->cq_depth = cq_entries; - if (udata) { resp.cqn = hr_cq->cqn; ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); @@ -477,7 +412,7 @@ return 0; err_cqc: - hns_roce_free_cq(hr_dev, hr_cq); + hns_roce_free_cqc(hr_dev, hr_cq); err_dbmap: if (udata) @@ -489,7 +424,7 @@ return ret; } -void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata) +void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata) { struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device); struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq); @@ -499,8 +434,8 @@ return; } - hns_roce_free_cq(hr_dev, hr_cq); - hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); + hns_roce_free_cqc(hr_dev, hr_cq); + hns_roce_mtt_cleanup(hr_dev, &hr_cq->mtt); ib_umem_release(hr_cq->umem); if (udata) { @@ -512,7 +447,7 @@ &hr_cq->db); } else { /* Free the buff of stored cq */ - hns_roce_ib_free_cq_buf(hr_dev, &hr_cq->hr_buf, ib_cq->cqe); + free_cq_buf(hr_dev, hr_cq); if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) hns_roce_free_db(hr_dev, &hr_cq->db); } @@ -520,38 +455,57 @@ void hns_roce_cq_completion(struct hns_roce_dev *hr_dev, u32 cqn) { - struct device *dev = hr_dev->dev; - struct hns_roce_cq *cq; + struct hns_roce_cq *hr_cq; + struct ib_cq *ibcq; - cq = xa_load(&hr_dev->cq_table.array, cqn & (hr_dev->caps.num_cqs - 1)); - if (!cq) { - dev_warn(dev, "Completion event for bogus CQ 0x%08x\n", cqn); + hr_cq = xa_load(&hr_dev->cq_table.array, + cqn & (hr_dev->caps.num_cqs - 1)); + if (!hr_cq) { + dev_warn(hr_dev->dev, "Completion event for bogus CQ 0x%06x\n", + cqn); return; } - ++cq->arm_sn; - cq->comp(cq); + ++hr_cq->arm_sn; + ibcq = &hr_cq->ib_cq; + if (ibcq->comp_handler) + ibcq->comp_handler(ibcq, ibcq->cq_context); } void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type) { - struct hns_roce_cq_table *cq_table = &hr_dev->cq_table; struct device *dev = hr_dev->dev; - struct hns_roce_cq *cq; + struct hns_roce_cq *hr_cq; + struct ib_event event; + struct ib_cq *ibcq; - cq = xa_load(&cq_table->array, cqn & (hr_dev->caps.num_cqs - 1)); - if (cq) - atomic_inc(&cq->refcount); + hr_cq = xa_load(&hr_dev->cq_table.array, + cqn & (hr_dev->caps.num_cqs - 1)); + if (!hr_cq) { + dev_warn(dev, "Async event for bogus CQ 0x%06x\n", cqn); + return; + } - if (!cq) { - dev_warn(dev, "Async event for bogus CQ %08x\n", cqn); + if (event_type != HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID && + event_type != HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR && + event_type != HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) { + dev_err(dev, "Unexpected event type 0x%x on CQ 0x%06x\n", + event_type, cqn); return; } - cq->event(cq, (enum hns_roce_event)event_type); + atomic_inc(&hr_cq->refcount); + + ibcq = &hr_cq->ib_cq; + if (ibcq->event_handler) { + event.device = ibcq->device; + event.element.cq = ibcq; + event.event = IB_EVENT_CQ_ERR; + ibcq->event_handler(&event, ibcq->cq_context); + } - if (atomic_dec_and_test(&cq->refcount)) - complete(&cq->free); + if (atomic_dec_and_test(&hr_cq->refcount)) + complete(&hr_cq->free); } int hns_roce_init_cq_table(struct hns_roce_dev *hr_dev) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_db.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_db.c @@ -31,7 +31,8 @@ refcount_set(&page->refcount, 1); page->user_virt = page_addr; - page->umem = ib_umem_get(udata, page_addr, PAGE_SIZE, 0, 0); + page->umem = ib_umem_get(context->ibucontext.device, page_addr, + PAGE_SIZE, 0); if (IS_ERR(page->umem)) { ret = PTR_ERR(page->umem); kfree(page); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_device.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_device.h @@ -45,16 +45,12 @@ #define HNS_ROCE_MAX_MSG_LEN 0x80000000 -#define HNS_ROCE_ALOGN_UP(a, b) ((((a) + (b) - 1) / (b)) * (b)) - #define HNS_ROCE_IB_MIN_SQ_STRIDE 6 #define HNS_ROCE_BA_SIZE (32 * 4096) #define BA_BYTE_LEN 8 -#define BITS_PER_BYTE 8 - /* Hardware specification only for v1 engine */ #define HNS_ROCE_MIN_CQE_NUM 0x40 #define HNS_ROCE_MIN_WQE_NUM 0x20 @@ -109,11 +105,6 @@ #define NODE_DESC_SIZE 64 #define DB_REG_OFFSET 0x1000 -#define SERV_TYPE_RC 0 -#define SERV_TYPE_RD 1 -#define SERV_TYPE_UC 2 -#define SERV_TYPE_UD 3 - /* Configure to HW for PAGE_SIZE larger than 4KB */ #define PG_SHIFT_OFFSET (PAGE_SHIFT - 12) @@ -133,6 +124,13 @@ #define EQ_DEPTH_COEFF 2 enum { + SERV_TYPE_RC, + SERV_TYPE_UC, + SERV_TYPE_RD, + SERV_TYPE_UD, +}; + +enum { HNS_ROCE_SUPPORT_RQ_RECORD_DB = 1 << 0, HNS_ROCE_SUPPORT_SQ_RECORD_DB = 1 << 1, }; @@ -425,8 +423,7 @@ struct hns_roce_wq { u64 *wrid; /* Work request ID */ spinlock_t lock; - int wqe_cnt; /* WQE num */ - u32 max_post; + u32 wqe_cnt; /* WQE num */ int max_gs; int offset; int wqe_shift; /* WQE size */ @@ -451,6 +448,7 @@ struct hns_roce_buf_list *page_list; int nbufs; u32 npages; + u32 size; int page_shift; }; @@ -482,22 +480,14 @@ int order; }; -struct hns_roce_cq_buf { - struct hns_roce_buf hr_buf; - struct hns_roce_mtt hr_mtt; -}; - struct hns_roce_cq { struct ib_cq ib_cq; - struct hns_roce_cq_buf hr_buf; + struct hns_roce_buf buf; + struct hns_roce_mtt mtt; struct hns_roce_db db; u8 db_en; spinlock_t lock; struct ib_umem *umem; - void (*comp)(struct hns_roce_cq *cq); - void (*event)(struct hns_roce_cq *cq, enum hns_roce_event event_type); - - struct hns_roce_uar *uar; u32 cq_depth; u32 cons_index; u32 *set_ci_db; @@ -508,6 +498,10 @@ u32 vector; atomic_t refcount; struct completion free; + struct list_head sq_list; /* all qps on this send cq */ + struct list_head rq_list; /* all qps on this recv cq */ + int is_armed; /* cq is armed */ + struct list_head node; /* all armed cqs are on a list */ }; struct hns_roce_idx_que { @@ -521,9 +515,8 @@ struct hns_roce_srq { struct ib_srq ibsrq; - void (*event)(struct hns_roce_srq *srq, enum hns_roce_event event); unsigned long srqn; - int max; + u32 wqe_cnt; int max_gs; int wqe_shift; void __iomem *db_reg_l; @@ -539,8 +532,8 @@ spinlock_t lock; int head; int tail; - u16 wqe_ctr; struct mutex mutex; + void (*event)(struct hns_roce_srq *srq, enum hns_roce_event event); }; struct hns_roce_uar_table { @@ -582,7 +575,7 @@ u8 tclass; u8 dgid[HNS_ROCE_GID_SIZE]; u8 mac[ETH_ALEN]; - u16 vlan; + u16 vlan_id; bool vlan_en; }; @@ -648,6 +641,19 @@ u32 wqe_cnt; }; +enum { + HNS_ROCE_FLUSH_FLAG = 0, +}; + +struct hns_roce_work { + struct hns_roce_dev *hr_dev; + struct work_struct work; + u32 qpn; + u32 cqn; + int event_type; + int sub_type; +}; + struct hns_roce_qp { struct ib_qp ibqp; struct hns_roce_buf hr_buf; @@ -657,8 +663,7 @@ u8 rdb_en; u8 sdb_en; u32 doorbell_qpn; - u32 sq_signal_bits; - u32 sq_next_wqe; + enum ib_sig_type sq_signal_bits; struct hns_roce_wq sq; struct ib_umem *umem; @@ -668,7 +673,6 @@ /* this define must less than HNS_ROCE_MAX_BT_REGION */ #define HNS_ROCE_WQE_REGION_MAX 3 struct hns_roce_buf_region regions[HNS_ROCE_WQE_REGION_MAX]; - int region_cnt; int wqe_bt_pg_shift; u32 buff_size; @@ -692,11 +696,13 @@ struct hns_roce_sge sge; u32 next_sge; + /* 0: flush needed, 1: unneeded */ + unsigned long flush_flag; + struct hns_roce_work flush_work; struct hns_roce_rinl_buf rq_inl_buf; -}; - -struct hns_roce_sqp { - struct hns_roce_qp hr_qp; + struct list_head node; /* all qps are on a list */ + struct list_head rq_node; /* all recv qps are on a list */ + struct list_head sq_node; /* all send qps are on a list */ }; struct hns_roce_ib_iboe { @@ -771,14 +777,8 @@ int eqe_ba_pg_sz; int eqe_buf_pg_sz; int hop_num; - u64 *bt_l0; /* Base address table for L0 */ - u64 **bt_l1; /* Base address table for L1 */ - u64 **buf; - dma_addr_t l0_dma; - dma_addr_t *l1_dma; - dma_addr_t *buf_dma; - u32 l0_last_num; /* L0 last chunk num */ - u32 l1_last_num; /* L1 last chunk num */ + struct hns_roce_mtr mtr; + struct hns_roce_buf buf; int eq_max_cnt; int eq_period; int shift; @@ -809,10 +809,8 @@ int reserved_qps; int num_qpc_timer; int num_cqc_timer; - u32 max_srq_sg; int num_srqs; u32 max_wqes; - u32 max_srqs; u32 max_srq_wrs; u32 max_srq_sges; u32 max_sq_desc_sz; @@ -821,12 +819,11 @@ int max_qp_init_rdma; int max_qp_dest_rdma; int num_cqs; - int max_cqes; - int min_cqes; + u32 max_cqes; + u32 min_cqes; u32 min_wqes; int reserved_cqs; int reserved_srqs; - u32 max_srqwqes; int num_aeq_vectors; int num_comp_vectors; int num_other_vectors; @@ -893,7 +890,7 @@ u32 cqc_timer_ba_pg_sz; u32 cqc_timer_buf_pg_sz; u32 cqc_timer_hop_num; - u32 cqe_ba_pg_sz; + u32 cqe_ba_pg_sz; /* page_size = 4K*(2^cqe_ba_pg_sz) */ u32 cqe_buf_pg_sz; u32 cqe_hop_num; u32 srqwqe_ba_pg_sz; @@ -910,15 +907,12 @@ u32 tpq_buf_pg_sz; u32 chunk_sz; /* chunk size in non multihop mode */ u64 flags; -}; - -struct hns_roce_work { - struct hns_roce_dev *hr_dev; - struct work_struct work; - u32 qpn; - u32 cqn; - int event_type; - int sub_type; + u16 default_ceq_max_cnt; + u16 default_ceq_period; + u16 default_aeq_max_cnt; + u16 default_aeq_period; + u16 default_aeq_arm_st; + u16 default_ceq_arm_st; }; struct hns_roce_dfx_hw { @@ -926,6 +920,12 @@ int *buffer); }; +enum hns_roce_device_state { + HNS_ROCE_DEVICE_STATE_INITED, + HNS_ROCE_DEVICE_STATE_RST_DOWN, + HNS_ROCE_DEVICE_STATE_UNINIT, +}; + struct hns_roce_hw { int (*reset)(struct hns_roce_dev *hr_dev, bool enable); int (*cmq_init)(struct hns_roce_dev *hr_dev); @@ -953,7 +953,7 @@ int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw); void (*write_cqc)(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts, - dma_addr_t dma_handle, int nent, u32 vector); + dma_addr_t dma_handle); int (*set_hem)(struct hns_roce_dev *hr_dev, struct hns_roce_hem_table *table, int obj, int step_idx); int (*clear_hem)(struct hns_roce_dev *hr_dev, @@ -1008,6 +1008,9 @@ bool dis_db; unsigned long reset_cnt; struct hns_roce_ib_iboe iboe; + enum hns_roce_device_state state; + struct list_head qp_list; /* list of all qps on this dev */ + spinlock_t qp_list_lock; /* protect qp_list */ struct list_head pgdir_list; struct mutex pgdir_mutex; @@ -1092,11 +1095,6 @@ return container_of(ibsrq, struct hns_roce_srq, ibsrq); } -static inline struct hns_roce_sqp *hr_to_hr_sqp(struct hns_roce_qp *hr_qp) -{ - return container_of(hr_qp, struct hns_roce_sqp, hr_qp); -} - static inline void hns_roce_write64_k(__le32 val[2], void __iomem *dest) { __raw_writeq(*(u64 *) val, dest); @@ -1153,7 +1151,6 @@ int hns_roce_init_pd_table(struct hns_roce_dev *hr_dev); int hns_roce_init_mr_table(struct hns_roce_dev *hr_dev); -int hns_roce_init_eq_table(struct hns_roce_dev *hr_dev); int hns_roce_init_cq_table(struct hns_roce_dev *hr_dev); int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev); int hns_roce_init_srq_table(struct hns_roce_dev *hr_dev); @@ -1198,9 +1195,9 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, unsigned int *sg_offset); int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata); -int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long mpt_index); +int hns_roce_hw_destroy_mpt(struct hns_roce_dev *hr_dev, + struct hns_roce_cmd_mailbox *mailbox, + unsigned long mpt_index); unsigned long key_to_hw_index(u32 key); struct ib_mw *hns_roce_alloc_mw(struct ib_pd *pd, enum ib_mw_type, @@ -1240,6 +1237,7 @@ struct ib_udata *udata); int hns_roce_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata); +void init_flush_work(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp); void *get_recv_wqe(struct hns_roce_qp *hr_qp, int n); void *get_send_wqe(struct hns_roce_qp *hr_qp, int n); void *get_send_extend_sge(struct hns_roce_qp *hr_qp, int n); @@ -1251,18 +1249,16 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq); void hns_roce_qp_remove(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp); -void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp); -void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn, - int cnt); +void hns_roce_qp_destroy(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_udata *udata); __be32 send_ieth(const struct ib_send_wr *wr); int to_hr_qp_type(int qp_type); -int hns_roce_ib_create_cq(struct ib_cq *ib_cq, - const struct ib_cq_init_attr *attr, - struct ib_udata *udata); +int hns_roce_create_cq(struct ib_cq *ib_cq, const struct ib_cq_init_attr *attr, + struct ib_udata *udata); -void hns_roce_ib_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata); -void hns_roce_free_cq(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq); +void hns_roce_destroy_cq(struct ib_cq *ib_cq, struct ib_udata *udata); +void hns_roce_free_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq); int hns_roce_db_map_user(struct hns_roce_ucontext *context, struct ib_udata *udata, unsigned long virt, @@ -1278,6 +1274,7 @@ void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type); void hns_roce_srq_event(struct hns_roce_dev *hr_dev, u32 srqn, int event_type); int hns_get_gid_index(struct hns_roce_dev *hr_dev, u8 port, int gid_index); +void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev); int hns_roce_init(struct hns_roce_dev *hr_dev); void hns_roce_exit(struct hns_roce_dev *hr_dev); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_hem.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -1323,10 +1323,12 @@ /* config L1 bt to last bt and link them to corresponding parent */ for (level = 1; level < hopnum; level++) { - cur = hem_list_search_item(&mid_bt[level], offset); - if (cur) { - hem_ptrs[level] = cur; - continue; + if (!hem_list_is_bottom_bt(hopnum, level)) { + cur = hem_list_search_item(&mid_bt[level], offset); + if (cur) { + hem_ptrs[level] = cur; + continue; + } } step = hem_list_calc_ba_range(hopnum, level, unit); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_hem.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_hem.h @@ -62,16 +62,16 @@ (sizeof(struct scatterlist) + sizeof(void *))) #define check_whether_bt_num_3(type, hop_num) \ - (type < HEM_TYPE_MTT && hop_num == 2) + ((type) < HEM_TYPE_MTT && (hop_num) == 2) #define check_whether_bt_num_2(type, hop_num) \ - ((type < HEM_TYPE_MTT && hop_num == 1) || \ - (type >= HEM_TYPE_MTT && hop_num == 2)) + (((type) < HEM_TYPE_MTT && (hop_num) == 1) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == 2)) #define check_whether_bt_num_1(type, hop_num) \ - ((type < HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0) || \ - (type >= HEM_TYPE_MTT && hop_num == 1) || \ - (type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0)) + (((type) < HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == 1) || \ + ((type) >= HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0)) enum { HNS_ROCE_HEM_PAGE_SHIFT = 12, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_hw_v1.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_hw_v1.c @@ -69,13 +69,13 @@ struct hns_roce_wqe_data_seg *dseg = NULL; struct hns_roce_qp *qp = to_hr_qp(ibqp); struct device *dev = &hr_dev->pdev->dev; - struct hns_roce_sq_db sq_db; + struct hns_roce_sq_db sq_db = {}; int ps_opcode = 0, i = 0; unsigned long flags = 0; void *wqe = NULL; __le32 doorbell[2]; + u32 wqe_idx = 0; int nreq = 0; - u32 ind = 0; int ret = 0; u8 *smac; int loopback; @@ -88,7 +88,7 @@ } spin_lock_irqsave(&qp->sq.lock, flags); - ind = qp->sq_next_wqe; + for (nreq = 0; wr; ++nreq, wr = wr->next) { if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { ret = -ENOMEM; @@ -96,6 +96,8 @@ goto out; } + wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); + if (unlikely(wr->num_sge > qp->sq.max_gs)) { dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", wr->num_sge, qp->sq.max_gs); @@ -104,9 +106,8 @@ goto out; } - wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); - qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = - wr->wr_id; + wqe = get_send_wqe(qp, wqe_idx); + qp->sq.wrid[wqe_idx] = wr->wr_id; /* Corresponding to the RC and RD type wqe process separately */ if (ibqp->qp_type == IB_QPT_GSI) { @@ -210,7 +211,6 @@ cpu_to_le32((wr->sg_list[1].addr) >> 32); ud_sq_wqe->l_key1 = cpu_to_le32(wr->sg_list[1].lkey); - ind++; } else if (ibqp->qp_type == IB_QPT_RC) { u32 tmp_len = 0; @@ -271,7 +271,6 @@ ps_opcode = HNS_ROCE_WQE_OPCODE_SEND; break; case IB_WR_LOCAL_INV: - break; case IB_WR_ATOMIC_CMP_AND_SWP: case IB_WR_ATOMIC_FETCH_AND_ADD: case IB_WR_LSO: @@ -308,7 +307,6 @@ ctrl->flag |= cpu_to_le32(wr->num_sge << HNS_ROCE_WQE_SGE_NUM_BIT); } - ind++; } } @@ -319,8 +317,6 @@ /* Memory barrier */ wmb(); - sq_db.u32_4 = 0; - sq_db.u32_8 = 0; roce_set_field(sq_db.u32_4, SQ_DOORBELL_U32_4_SQ_HEAD_M, SQ_DOORBELL_U32_4_SQ_HEAD_S, (qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1))); @@ -336,7 +332,6 @@ doorbell[1] = sq_db.u32_8; hns_roce_write64_k(doorbell, qp->sq.db_reg_l); - qp->sq_next_wqe = ind; } spin_unlock_irqrestore(&qp->sq.lock, flags); @@ -348,22 +343,21 @@ const struct ib_recv_wr *wr, const struct ib_recv_wr **bad_wr) { - int ret = 0; - int nreq = 0; - int ind = 0; - int i = 0; - u32 reg_val; - unsigned long flags = 0; struct hns_roce_rq_wqe_ctrl *ctrl = NULL; struct hns_roce_wqe_data_seg *scat = NULL; struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); struct device *dev = &hr_dev->pdev->dev; - struct hns_roce_rq_db rq_db; + struct hns_roce_rq_db rq_db = {}; __le32 doorbell[2] = {0}; + unsigned long flags = 0; + unsigned int wqe_idx; + int ret = 0; + int nreq = 0; + int i = 0; + u32 reg_val; spin_lock_irqsave(&hr_qp->rq.lock, flags); - ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); for (nreq = 0; wr; ++nreq, wr = wr->next) { if (hns_roce_wq_overflow(&hr_qp->rq, nreq, @@ -373,6 +367,8 @@ goto out; } + wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", wr->num_sge, hr_qp->rq.max_gs); @@ -381,7 +377,7 @@ goto out; } - ctrl = get_recv_wqe(hr_qp, ind); + ctrl = get_recv_wqe(hr_qp, wqe_idx); roce_set_field(ctrl->rwqe_byte_12, RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_M, @@ -393,9 +389,7 @@ for (i = 0; i < wr->num_sge; i++) set_data_seg(scat + i, wr->sg_list + i); - hr_qp->rq.wrid[ind] = wr->wr_id; - - ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); + hr_qp->rq.wrid[wqe_idx] = wr->wr_id; } out: @@ -421,9 +415,6 @@ ROCEE_QP1C_CFG3_0_REG + QP1C_CFGN_OFFSET * hr_qp->phy_port, reg_val); } else { - rq_db.u32_4 = 0; - rq_db.u32_8 = 0; - roce_set_field(rq_db.u32_4, RQ_DOORBELL_U32_4_RQ_HEAD_M, RQ_DOORBELL_U32_4_RQ_HEAD_S, hr_qp->rq.head); @@ -732,7 +723,7 @@ if (!cq) return -ENOMEM; - ret = hns_roce_ib_create_cq(cq, &cq_init_attr, NULL); + ret = hns_roce_create_cq(cq, &cq_init_attr, NULL); if (ret) { dev_err(dev, "Create cq for reserved loop qp failed!"); goto alloc_cq_failed; @@ -868,7 +859,7 @@ kfree(pd); alloc_mem_failed: - hns_roce_ib_destroy_cq(cq, NULL); + hns_roce_destroy_cq(cq, NULL); alloc_cq_failed: kfree(cq); return ret; @@ -897,7 +888,7 @@ i, ret); } - hns_roce_ib_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL); + hns_roce_destroy_cq(&free_mr->mr_free_cq->ib_cq, NULL); kfree(&free_mr->mr_free_cq->ib_cq); hns_roce_dealloc_pd(&free_mr->mr_free_pd->ibpd, NULL); kfree(&free_mr->mr_free_pd->ibpd); @@ -1114,9 +1105,10 @@ free_mr = &priv->free_mr; if (mr->enabled) { - if (hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mr->key) - & (hr_dev->caps.num_mtpts - 1))) - dev_warn(dev, "HW2SW_MPT failed!\n"); + if (hns_roce_hw_destroy_mpt(hr_dev, NULL, + key_to_hw_index(mr->key) & + (hr_dev->caps.num_mtpts - 1))) + dev_warn(dev, "DESTROY_MPT failed!\n"); } mr_work = kzalloc(sizeof(*mr_work), GFP_KERNEL); @@ -1979,8 +1971,7 @@ static void *get_cqe(struct hns_roce_cq *hr_cq, int n) { - return hns_roce_buf_offset(&hr_cq->hr_buf.hr_buf, - n * HNS_ROCE_V1_CQE_ENTRY_SIZE); + return hns_roce_buf_offset(&hr_cq->buf, n * HNS_ROCE_V1_CQE_ENTRY_SIZE); } static void *get_sw_cqe(struct hns_roce_cq *hr_cq, int n) @@ -1989,7 +1980,7 @@ /* Get cqe when Owner bit is Conversely with the MSB of cons_idx */ return (roce_get_bit(hr_cqe->cqe_byte_4, CQE_BYTE_4_OWNER_S) ^ - !!(n & (hr_cq->ib_cq.cqe + 1))) ? hr_cqe : NULL; + !!(n & hr_cq->cq_depth)) ? hr_cqe : NULL; } static struct hns_roce_cqe *next_cqe_sw(struct hns_roce_cq *hr_cq) @@ -2072,8 +2063,7 @@ static void hns_roce_v1_write_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, void *mb_buf, - u64 *mtts, dma_addr_t dma_handle, int nent, - u32 vector) + u64 *mtts, dma_addr_t dma_handle) { struct hns_roce_cq_context *cq_context = NULL; struct hns_roce_buf_list *tptr_buf; @@ -2108,9 +2098,9 @@ roce_set_field(cq_context->cqc_byte_12, CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_M, CQ_CONTEXT_CQC_BYTE_12_CQ_CQE_SHIFT_S, - ilog2((unsigned int)nent)); + ilog2(hr_cq->cq_depth)); roce_set_field(cq_context->cqc_byte_12, CQ_CONTEXT_CQC_BYTE_12_CEQN_M, - CQ_CONTEXT_CQC_BYTE_12_CEQN_S, vector); + CQ_CONTEXT_CQC_BYTE_12_CEQN_S, hr_cq->vector); cq_context->cur_cqe_ba0_l = cpu_to_le32((u32)(mtts[0])); @@ -2702,7 +2692,6 @@ hr_qp->rq.tail = 0; hr_qp->sq.head = 0; hr_qp->sq.tail = 0; - hr_qp->sq_next_wqe = 0; } kfree(context); @@ -3316,7 +3305,6 @@ hr_qp->rq.tail = 0; hr_qp->sq.head = 0; hr_qp->sq.tail = 0; - hr_qp->sq_next_wqe = 0; } out: kfree(context); @@ -3615,39 +3603,25 @@ if (ret) return ret; - send_cq = to_hr_cq(hr_qp->ibqp.send_cq); - recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq); + send_cq = hr_qp->ibqp.send_cq ? to_hr_cq(hr_qp->ibqp.send_cq) : NULL; + recv_cq = hr_qp->ibqp.recv_cq ? to_hr_cq(hr_qp->ibqp.recv_cq) : NULL; hns_roce_lock_cqs(send_cq, recv_cq); if (!udata) { - __hns_roce_v1_cq_clean(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ? - to_hr_srq(hr_qp->ibqp.srq) : NULL); - if (send_cq != recv_cq) + if (recv_cq) + __hns_roce_v1_cq_clean(recv_cq, hr_qp->qpn, + (hr_qp->ibqp.srq ? + to_hr_srq(hr_qp->ibqp.srq) : + NULL)); + + if (send_cq && send_cq != recv_cq) __hns_roce_v1_cq_clean(send_cq, hr_qp->qpn, NULL); } - hns_roce_unlock_cqs(send_cq, recv_cq); - hns_roce_qp_remove(hr_dev, hr_qp); - hns_roce_qp_free(hr_dev, hr_qp); - - /* RC QP, release QPN */ - if (hr_qp->ibqp.qp_type == IB_QPT_RC) - hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1); - - hns_roce_mtt_cleanup(hr_dev, &hr_qp->mtt); - - ib_umem_release(hr_qp->umem); - if (!udata) { - kfree(hr_qp->sq.wrid); - kfree(hr_qp->rq.wrid); + hns_roce_unlock_cqs(send_cq, recv_cq); - hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); - } + hns_roce_qp_destroy(hr_dev, hr_qp, udata); - if (hr_qp->ibqp.qp_type == IB_QPT_RC) - kfree(hr_qp); - else - kfree(hr_to_hr_sqp(hr_qp)); return 0; } @@ -3658,10 +3632,9 @@ struct device *dev = &hr_dev->pdev->dev; u32 cqe_cnt_ori; u32 cqe_cnt_cur; - u32 cq_buf_size; int wait_time = 0; - hns_roce_free_cq(hr_dev, hr_cq); + hns_roce_free_cqc(hr_dev, hr_cq); /* * Before freeing cq buffer, we need to ensure that the outstanding CQE @@ -3686,13 +3659,12 @@ wait_time++; } - hns_roce_mtt_cleanup(hr_dev, &hr_cq->hr_buf.hr_mtt); + hns_roce_mtt_cleanup(hr_dev, &hr_cq->mtt); ib_umem_release(hr_cq->umem); if (!udata) { /* Free the buff of stored cq */ - cq_buf_size = (ibcq->cqe + 1) * hr_dev->caps.cq_entry_sz; - hns_roce_buf_free(hr_dev, cq_buf_size, &hr_cq->hr_buf.hr_buf); + hns_roce_buf_free(hr_dev, hr_cq->buf.size, &hr_cq->buf); } } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -63,20 +63,15 @@ struct hns_roce_mr *mr = to_hr_mr(wr->mr); /* use ib_access_flags */ - roce_set_bit(rc_sq_wqe->byte_4, - V2_RC_FRMR_WQE_BYTE_4_BIND_EN_S, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_BIND_EN_S, wr->access & IB_ACCESS_MW_BIND ? 1 : 0); - roce_set_bit(rc_sq_wqe->byte_4, - V2_RC_FRMR_WQE_BYTE_4_ATOMIC_S, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_ATOMIC_S, wr->access & IB_ACCESS_REMOTE_ATOMIC ? 1 : 0); - roce_set_bit(rc_sq_wqe->byte_4, - V2_RC_FRMR_WQE_BYTE_4_RR_S, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_RR_S, wr->access & IB_ACCESS_REMOTE_READ ? 1 : 0); - roce_set_bit(rc_sq_wqe->byte_4, - V2_RC_FRMR_WQE_BYTE_4_RW_S, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_RW_S, wr->access & IB_ACCESS_REMOTE_WRITE ? 1 : 0); - roce_set_bit(rc_sq_wqe->byte_4, - V2_RC_FRMR_WQE_BYTE_4_LW_S, + roce_set_bit(rc_sq_wqe->byte_4, V2_RC_FRMR_WQE_BYTE_4_LW_S, wr->access & IB_ACCESS_LOCAL_WRITE ? 1 : 0); /* Data structure reuse may lead to confusion */ @@ -110,7 +105,7 @@ } static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, - unsigned int *sge_ind) + unsigned int *sge_ind, int valid_num_sge) { struct hns_roce_v2_wqe_data_seg *dseg; struct ib_sge *sg; @@ -123,7 +118,7 @@ if (qp->ibqp.qp_type == IB_QPT_RC || qp->ibqp.qp_type == IB_QPT_UC) num_in_wqe = HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; - extend_sge_num = wr->num_sge - num_in_wqe; + extend_sge_num = valid_num_sge - num_in_wqe; sg = wr->sg_list + num_in_wqe; shift = qp->hr_buf.page_shift; @@ -159,14 +154,16 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr, struct hns_roce_v2_rc_send_wqe *rc_sq_wqe, void *wqe, unsigned int *sge_ind, + int valid_num_sge, const struct ib_send_wr **bad_wr) { struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device); struct hns_roce_v2_wqe_data_seg *dseg = wqe; struct hns_roce_qp *qp = to_hr_qp(ibqp); + int j = 0; int i; - if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) { + if (wr->send_flags & IB_SEND_INLINE && valid_num_sge) { if (le32_to_cpu(rc_sq_wqe->msg_len) > hr_dev->caps.max_sq_inline) { *bad_wr = wr; @@ -190,7 +187,7 @@ roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_INLINE_S, 1); } else { - if (wr->num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { + if (valid_num_sge <= HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE) { for (i = 0; i < wr->num_sge; i++) { if (likely(wr->sg_list[i].length)) { set_data_seg_v2(dseg, wr->sg_list + i); @@ -203,28 +200,81 @@ V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, (*sge_ind) & (qp->sge.sge_cnt - 1)); - for (i = 0; i < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { + for (i = 0; i < wr->num_sge && + j < HNS_ROCE_V2_UC_RC_SGE_NUM_IN_WQE; i++) { if (likely(wr->sg_list[i].length)) { set_data_seg_v2(dseg, wr->sg_list + i); dseg++; + j++; } } - set_extend_sge(qp, wr, sge_ind); + set_extend_sge(qp, wr, sge_ind, valid_num_sge); } roce_set_field(rc_sq_wqe->byte_16, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, - V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, wr->num_sge); + V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, valid_num_sge); } return 0; } -static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, - const struct ib_qp_attr *attr, - int attr_mask, enum ib_qp_state cur_state, - enum ib_qp_state new_state); +static int check_send_valid(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp) +{ + struct ib_qp *ibqp = &hr_qp->ibqp; + struct device *dev = hr_dev->dev; + + if (unlikely(ibqp->qp_type != IB_QPT_RC && + ibqp->qp_type != IB_QPT_GSI && + ibqp->qp_type != IB_QPT_UD)) { + dev_err(dev, "Not supported QP(0x%x)type!\n", ibqp->qp_type); + return -EOPNOTSUPP; + } else if (unlikely(hr_qp->state == IB_QPS_RESET || + hr_qp->state == IB_QPS_INIT || + hr_qp->state == IB_QPS_RTR)) { + dev_err(dev, "Post WQE fail, QP state %d!\n", hr_qp->state); + return -EINVAL; + } else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) { + dev_err(dev, "Post WQE fail, dev state %d!\n", hr_dev->state); + return -EIO; + } + + return 0; +} + +static inline void update_sq_db(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *qp) +{ + /* + * Hip08 hardware cannot flush the WQEs in SQ if the QP state + * gets into errored mode. Hence, as a workaround to this + * hardware limitation, driver needs to assist in flushing. But + * the flushing operation uses mailbox to convey the QP state to + * the hardware and which can sleep due to the mutex protection + * around the mailbox calls. Hence, use the deferred flush for + * now. + */ + if (qp->state == IB_QPS_ERR) { + if (!test_and_set_bit(HNS_ROCE_FLUSH_FLAG, &qp->flush_flag)) + init_flush_work(hr_dev, qp); + } else { + struct hns_roce_v2_db sq_db = {}; + + roce_set_field(sq_db.byte_4, V2_DB_BYTE_4_TAG_M, + V2_DB_BYTE_4_TAG_S, qp->doorbell_qpn); + roce_set_field(sq_db.byte_4, V2_DB_BYTE_4_CMD_M, + V2_DB_BYTE_4_CMD_S, HNS_ROCE_V2_SQ_DB); + roce_set_field(sq_db.parameter, V2_DB_PARAMETER_IDX_M, + V2_DB_PARAMETER_IDX_S, + qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)); + roce_set_field(sq_db.parameter, V2_DB_PARAMETER_SL_M, + V2_DB_PARAMETER_SL_S, qp->sl); + + hns_roce_write64(hr_dev, (__le32 *)&sq_db, qp->sq.db_reg_l); + } +} static int hns_roce_v2_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr, @@ -237,40 +287,30 @@ struct hns_roce_qp *qp = to_hr_qp(ibqp); struct hns_roce_wqe_frmr_seg *fseg; struct device *dev = hr_dev->dev; - struct hns_roce_v2_db sq_db; - struct ib_qp_attr attr; - unsigned int sge_ind; unsigned int owner_bit; + unsigned int sge_idx; + unsigned int wqe_idx; unsigned long flags; - unsigned int ind; + int valid_num_sge; void *wqe = NULL; bool loopback; - int attr_mask; u32 tmp_len; - int ret = 0; u32 hr_op; u8 *smac; int nreq; + int ret; int i; - if (unlikely(ibqp->qp_type != IB_QPT_RC && - ibqp->qp_type != IB_QPT_GSI && - ibqp->qp_type != IB_QPT_UD)) { - dev_err(dev, "Not supported QP(0x%x)type!\n", ibqp->qp_type); - *bad_wr = wr; - return -EOPNOTSUPP; - } + spin_lock_irqsave(&qp->sq.lock, flags); - if (unlikely(qp->state == IB_QPS_RESET || qp->state == IB_QPS_INIT || - qp->state == IB_QPS_RTR)) { - dev_err(dev, "Post WQE fail, QP state %d err!\n", qp->state); + ret = check_send_valid(hr_dev, qp); + if (ret) { *bad_wr = wr; - return -EINVAL; + nreq = 0; + goto out; } - spin_lock_irqsave(&qp->sq.lock, flags); - ind = qp->sq_next_wqe; - sge_ind = qp->next_sge; + sge_idx = qp->next_sge; for (nreq = 0; wr; ++nreq, wr = wr->next) { if (hns_roce_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)) { @@ -279,6 +319,8 @@ goto out; } + wqe_idx = (qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1); + if (unlikely(wr->num_sge > qp->sq.max_gs)) { dev_err(dev, "num_sge=%d > qp->sq.max_gs=%d\n", wr->num_sge, qp->sq.max_gs); @@ -287,14 +329,20 @@ goto out; } - wqe = get_send_wqe(qp, ind & (qp->sq.wqe_cnt - 1)); - qp->sq.wrid[(qp->sq.head + nreq) & (qp->sq.wqe_cnt - 1)] = - wr->wr_id; - + wqe = get_send_wqe(qp, wqe_idx); + qp->sq.wrid[wqe_idx] = wr->wr_id; owner_bit = ~(((qp->sq.head + nreq) >> ilog2(qp->sq.wqe_cnt)) & 0x1); + valid_num_sge = 0; tmp_len = 0; + for (i = 0; i < wr->num_sge; i++) { + if (likely(wr->sg_list[i].length)) { + tmp_len += wr->sg_list[i].length; + valid_num_sge++; + } + } + /* Corresponding to the QP type, wqe process separately */ if (ibqp->qp_type == IB_QPT_GSI) { ud_sq_wqe = wqe; @@ -330,9 +378,6 @@ V2_UD_SEND_WQE_BYTE_4_OPCODE_S, HNS_ROCE_V2_WQE_OP_SEND); - for (i = 0; i < wr->num_sge; i++) - tmp_len += wr->sg_list[i].length; - ud_sq_wqe->msg_len = cpu_to_le32(le32_to_cpu(ud_sq_wqe->msg_len) + tmp_len); @@ -368,12 +413,12 @@ roce_set_field(ud_sq_wqe->byte_16, V2_UD_SEND_WQE_BYTE_16_SGE_NUM_M, V2_UD_SEND_WQE_BYTE_16_SGE_NUM_S, - wr->num_sge); + valid_num_sge); roce_set_field(ud_sq_wqe->byte_20, V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M, V2_UD_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_S, - sge_ind & (qp->sge.sge_cnt - 1)); + sge_idx & (qp->sge.sge_cnt - 1)); roce_set_field(ud_sq_wqe->byte_24, V2_UD_SEND_WQE_BYTE_24_UDPSPN_M, @@ -389,7 +434,7 @@ roce_set_field(ud_sq_wqe->byte_36, V2_UD_SEND_WQE_BYTE_36_VLAN_M, V2_UD_SEND_WQE_BYTE_36_VLAN_S, - le16_to_cpu(ah->av.vlan)); + ah->av.vlan_id); roce_set_field(ud_sq_wqe->byte_36, V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_M, V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_S, @@ -423,13 +468,10 @@ memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], GID_LEN_V2); - set_extend_sge(qp, wr, &sge_ind); - ind++; + set_extend_sge(qp, wr, &sge_idx, valid_num_sge); } else if (ibqp->qp_type == IB_QPT_RC) { rc_sq_wqe = wqe; memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe)); - for (i = 0; i < wr->num_sge; i++) - tmp_len += wr->sg_list[i].length; rc_sq_wqe->msg_len = cpu_to_le32(le32_to_cpu(rc_sq_wqe->msg_len) + tmp_len); @@ -550,15 +592,14 @@ roce_set_field(rc_sq_wqe->byte_16, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_S, - wr->num_sge); + valid_num_sge); } else if (wr->opcode != IB_WR_REG_MR) { ret = set_rwqe_data_seg(ibqp, wr, rc_sq_wqe, - wqe, &sge_ind, bad_wr); + wqe, &sge_idx, + valid_num_sge, bad_wr); if (ret) goto out; } - - ind++; } else { dev_err(dev, "Illegal qp_type(0x%x)\n", ibqp->qp_type); spin_unlock_irqrestore(&qp->sq.lock, flags); @@ -570,39 +611,10 @@ out: if (likely(nreq)) { qp->sq.head += nreq; + qp->next_sge = sge_idx; /* Memory barrier */ wmb(); - - sq_db.byte_4 = 0; - sq_db.parameter = 0; - - roce_set_field(sq_db.byte_4, V2_DB_BYTE_4_TAG_M, - V2_DB_BYTE_4_TAG_S, qp->doorbell_qpn); - roce_set_field(sq_db.byte_4, V2_DB_BYTE_4_CMD_M, - V2_DB_BYTE_4_CMD_S, HNS_ROCE_V2_SQ_DB); - roce_set_field(sq_db.parameter, V2_DB_PARAMETER_IDX_M, - V2_DB_PARAMETER_IDX_S, - qp->sq.head & ((qp->sq.wqe_cnt << 1) - 1)); - roce_set_field(sq_db.parameter, V2_DB_PARAMETER_SL_M, - V2_DB_PARAMETER_SL_S, qp->sl); - - hns_roce_write64(hr_dev, (__le32 *)&sq_db, qp->sq.db_reg_l); - - qp->sq_next_wqe = ind; - qp->next_sge = sge_ind; - - if (qp->state == IB_QPS_ERR) { - attr_mask = IB_QP_STATE; - attr.qp_state = IB_QPS_ERR; - - ret = hns_roce_v2_modify_qp(&qp->ibqp, &attr, attr_mask, - qp->state, IB_QPS_ERR); - if (ret) { - spin_unlock_irqrestore(&qp->sq.lock, flags); - *bad_wr = wr; - return ret; - } - } + update_sq_db(hr_dev, qp); } spin_unlock_irqrestore(&qp->sq.lock, flags); @@ -610,6 +622,17 @@ return ret; } +static int check_recv_valid(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp) +{ + if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) + return -EIO; + else if (hr_qp->state == IB_QPS_RESET) + return -EINVAL; + + return 0; +} + static int hns_roce_v2_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr, const struct ib_recv_wr **bad_wr) @@ -619,22 +642,20 @@ struct hns_roce_v2_wqe_data_seg *dseg; struct hns_roce_rinl_sge *sge_list; struct device *dev = hr_dev->dev; - struct ib_qp_attr attr; unsigned long flags; void *wqe = NULL; - int attr_mask; - int ret = 0; + u32 wqe_idx; int nreq; - int ind; + int ret; int i; spin_lock_irqsave(&hr_qp->rq.lock, flags); - ind = hr_qp->rq.head & (hr_qp->rq.wqe_cnt - 1); - if (hr_qp->state == IB_QPS_RESET) { - spin_unlock_irqrestore(&hr_qp->rq.lock, flags); + ret = check_recv_valid(hr_dev, hr_qp); + if (ret) { *bad_wr = wr; - return -EINVAL; + nreq = 0; + goto out; } for (nreq = 0; wr; ++nreq, wr = wr->next) { @@ -645,6 +666,8 @@ goto out; } + wqe_idx = (hr_qp->rq.head + nreq) & (hr_qp->rq.wqe_cnt - 1); + if (unlikely(wr->num_sge > hr_qp->rq.max_gs)) { dev_err(dev, "rq:num_sge=%d > qp->sq.max_gs=%d\n", wr->num_sge, hr_qp->rq.max_gs); @@ -653,7 +676,7 @@ goto out; } - wqe = get_recv_wqe(hr_qp, ind); + wqe = get_recv_wqe(hr_qp, wqe_idx); dseg = (struct hns_roce_v2_wqe_data_seg *)wqe; for (i = 0; i < wr->num_sge; i++) { if (!wr->sg_list[i].length) @@ -669,8 +692,8 @@ /* rq support inline data */ if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) { - sge_list = hr_qp->rq_inl_buf.wqe_list[ind].sg_list; - hr_qp->rq_inl_buf.wqe_list[ind].sge_cnt = + sge_list = hr_qp->rq_inl_buf.wqe_list[wqe_idx].sg_list; + hr_qp->rq_inl_buf.wqe_list[wqe_idx].sge_cnt = (u32)wr->num_sge; for (i = 0; i < wr->num_sge; i++) { sge_list[i].addr = @@ -679,9 +702,7 @@ } } - hr_qp->rq.wrid[ind] = wr->wr_id; - - ind = (ind + 1) & (hr_qp->rq.wqe_cnt - 1); + hr_qp->rq.wrid[wqe_idx] = wr->wr_id; } out: @@ -690,20 +711,21 @@ /* Memory barrier */ wmb(); - *hr_qp->rdb.db_record = hr_qp->rq.head & 0xffff; - + /* + * Hip08 hardware cannot flush the WQEs in RQ if the QP state + * gets into errored mode. Hence, as a workaround to this + * hardware limitation, driver needs to assist in flushing. But + * the flushing operation uses mailbox to convey the QP state to + * the hardware and which can sleep due to the mutex protection + * around the mailbox calls. Hence, use the deferred flush for + * now. + */ if (hr_qp->state == IB_QPS_ERR) { - attr_mask = IB_QP_STATE; - attr.qp_state = IB_QPS_ERR; - - ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, &attr, - attr_mask, hr_qp->state, - IB_QPS_ERR); - if (ret) { - spin_unlock_irqrestore(&hr_qp->rq.lock, flags); - *bad_wr = wr; - return ret; - } + if (!test_and_set_bit(HNS_ROCE_FLUSH_FLAG, + &hr_qp->flush_flag)) + init_flush_work(hr_dev, hr_qp); + } else { + *hr_qp->rdb.db_record = hr_qp->rq.head & 0xffff; } } spin_unlock_irqrestore(&hr_qp->rq.lock, flags); @@ -1006,7 +1028,7 @@ u32 timeout = 0; int handle = 0; u16 desc_ret; - int ret = 0; + int ret; int ntc; spin_lock_bh(&csq->lock); @@ -1051,15 +1073,14 @@ if (hns_roce_cmq_csq_done(hr_dev)) { complete = true; handle = 0; + ret = 0; while (handle < num) { /* get the result of hardware write back */ desc_to_use = &csq->desc[ntc]; desc[handle] = *desc_to_use; dev_dbg(hr_dev->dev, "Get cmq desc:\n"); desc_ret = le16_to_cpu(desc[handle].retval); - if (desc_ret == CMD_EXEC_SUCCESS) - ret = 0; - else + if (unlikely(desc_ret != CMD_EXEC_SUCCESS)) ret = -EIO; priv->cmq.last_status = desc_ret; ntc++; @@ -1254,7 +1275,6 @@ } out: - dev_err(hr_dev->dev, "Func clear fail.\n"); hns_roce_func_clr_rst_prc(hr_dev, ret, fclr_write_fail_flag); } @@ -1346,40 +1366,31 @@ static int hns_roce_query_pf_timer_resource(struct hns_roce_dev *hr_dev) { struct hns_roce_pf_timer_res_a *req_a; - struct hns_roce_cmq_desc desc[2]; - int ret, i; - - for (i = 0; i < 2; i++) { - hns_roce_cmq_setup_basic_desc(&desc[i], - HNS_ROCE_OPC_QUERY_PF_TIMER_RES, - true); + struct hns_roce_cmq_desc desc; + int ret; - if (i == 0) - desc[i].flag |= cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT); - else - desc[i].flag &= ~cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT); - } + hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_QUERY_PF_TIMER_RES, + true); - ret = hns_roce_cmq_send(hr_dev, desc, 2); + ret = hns_roce_cmq_send(hr_dev, &desc, 1); if (ret) return ret; - req_a = (struct hns_roce_pf_timer_res_a *)desc[0].data; + req_a = (struct hns_roce_pf_timer_res_a *)desc.data; hr_dev->caps.qpc_timer_bt_num = - roce_get_field(req_a->qpc_timer_bt_idx_num, - PF_RES_DATA_1_PF_QPC_TIMER_BT_NUM_M, - PF_RES_DATA_1_PF_QPC_TIMER_BT_NUM_S); + roce_get_field(req_a->qpc_timer_bt_idx_num, + PF_RES_DATA_1_PF_QPC_TIMER_BT_NUM_M, + PF_RES_DATA_1_PF_QPC_TIMER_BT_NUM_S); hr_dev->caps.cqc_timer_bt_num = - roce_get_field(req_a->cqc_timer_bt_idx_num, - PF_RES_DATA_2_PF_CQC_TIMER_BT_NUM_M, - PF_RES_DATA_2_PF_CQC_TIMER_BT_NUM_S); + roce_get_field(req_a->cqc_timer_bt_idx_num, + PF_RES_DATA_2_PF_CQC_TIMER_BT_NUM_M, + PF_RES_DATA_2_PF_CQC_TIMER_BT_NUM_S); return 0; } -static int hns_roce_set_vf_switch_param(struct hns_roce_dev *hr_dev, - int vf_id) +static int hns_roce_set_vf_switch_param(struct hns_roce_dev *hr_dev, int vf_id) { struct hns_roce_cmq_desc desc; struct hns_roce_vf_switch *swt; @@ -1388,13 +1399,12 @@ swt = (struct hns_roce_vf_switch *)desc.data; hns_roce_cmq_setup_basic_desc(&desc, HNS_SWITCH_PARAMETER_CFG, true); swt->rocee_sel |= cpu_to_le32(HNS_ICL_SWITCH_CMD_ROCEE_SEL); - roce_set_field(swt->fun_id, - VF_SWITCH_DATA_FUN_ID_VF_ID_M, - VF_SWITCH_DATA_FUN_ID_VF_ID_S, - vf_id); + roce_set_field(swt->fun_id, VF_SWITCH_DATA_FUN_ID_VF_ID_M, + VF_SWITCH_DATA_FUN_ID_VF_ID_S, vf_id); ret = hns_roce_cmq_send(hr_dev, &desc, 1); if (ret) return ret; + desc.flag = cpu_to_le16(HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN); desc.flag &= cpu_to_le16(~HNS_ROCE_CMD_FLAG_WR); @@ -1574,69 +1584,9 @@ return hns_roce_cmq_send(hr_dev, &desc, 1); } -static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) +static void set_default_caps(struct hns_roce_dev *hr_dev) { struct hns_roce_caps *caps = &hr_dev->caps; - int ret; - - ret = hns_roce_cmq_query_hw_info(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "Query hardware version fail, ret = %d.\n", - ret); - return ret; - } - - ret = hns_roce_query_fw_ver(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "Query firmware version fail, ret = %d.\n", - ret); - return ret; - } - - ret = hns_roce_config_global_param(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "Configure global param fail, ret = %d.\n", - ret); - return ret; - } - - /* Get pf resource owned by every pf */ - ret = hns_roce_query_pf_resource(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "Query pf resource fail, ret = %d.\n", - ret); - return ret; - } - - if (hr_dev->pci_dev->revision == 0x21) { - ret = hns_roce_query_pf_timer_resource(hr_dev); - if (ret) { - dev_err(hr_dev->dev, - "Query pf timer resource fail, ret = %d.\n", - ret); - return ret; - } - } - - ret = hns_roce_alloc_vf_resource(hr_dev); - if (ret) { - dev_err(hr_dev->dev, "Allocate vf resource fail, ret = %d.\n", - ret); - return ret; - } - - if (hr_dev->pci_dev->revision == 0x21) { - ret = hns_roce_set_vf_switch_param(hr_dev, 0); - if (ret) { - dev_err(hr_dev->dev, - "Set function switch param fail, ret = %d.\n", - ret); - return ret; - } - } - - hr_dev->vendor_part_id = hr_dev->pci_dev->device; - hr_dev->sys_image_guid = be64_to_cpu(hr_dev->ib_dev.node_guid); caps->num_qps = HNS_ROCE_V2_MAX_QP_NUM; caps->max_wqes = HNS_ROCE_V2_MAX_WQE_NUM; @@ -1644,17 +1594,15 @@ caps->num_srqs = HNS_ROCE_V2_MAX_SRQ_NUM; caps->min_cqes = HNS_ROCE_MIN_CQE_NUM; caps->max_cqes = HNS_ROCE_V2_MAX_CQE_NUM; - caps->max_srqwqes = HNS_ROCE_V2_MAX_SRQWQE_NUM; caps->max_sq_sg = HNS_ROCE_V2_MAX_SQ_SGE_NUM; caps->max_extend_sg = HNS_ROCE_V2_MAX_EXTEND_SGE_NUM; caps->max_rq_sg = HNS_ROCE_V2_MAX_RQ_SGE_NUM; caps->max_sq_inline = HNS_ROCE_V2_MAX_SQ_INLINE; - caps->max_srq_sg = HNS_ROCE_V2_MAX_SRQ_SGE_NUM; caps->num_uars = HNS_ROCE_V2_UAR_NUM; caps->phy_num_uars = HNS_ROCE_V2_PHY_UAR_NUM; caps->num_aeq_vectors = HNS_ROCE_V2_AEQE_VEC_NUM; caps->num_comp_vectors = HNS_ROCE_V2_COMP_VEC_NUM; - caps->num_other_vectors = HNS_ROCE_V2_ABNORMAL_VEC_NUM; + caps->num_other_vectors = HNS_ROCE_V2_ABNORMAL_VEC_NUM; caps->num_mtpts = HNS_ROCE_V2_MAX_MTPT_NUM; caps->num_mtt_segs = HNS_ROCE_V2_MAX_MTT_SEGS; caps->num_cqe_segs = HNS_ROCE_V2_MAX_CQE_SEGS; @@ -1668,12 +1616,12 @@ caps->max_srq_desc_sz = HNS_ROCE_V2_MAX_SRQ_DESC_SZ; caps->qpc_entry_sz = HNS_ROCE_V2_QPC_ENTRY_SZ; caps->irrl_entry_sz = HNS_ROCE_V2_IRRL_ENTRY_SZ; - caps->trrl_entry_sz = HNS_ROCE_V2_TRRL_ENTRY_SZ; + caps->trrl_entry_sz = HNS_ROCE_V2_EXT_ATOMIC_TRRL_ENTRY_SZ; caps->cqc_entry_sz = HNS_ROCE_V2_CQC_ENTRY_SZ; caps->srqc_entry_sz = HNS_ROCE_V2_SRQC_ENTRY_SZ; caps->mtpt_entry_sz = HNS_ROCE_V2_MTPT_ENTRY_SZ; caps->mtt_entry_sz = HNS_ROCE_V2_MTT_ENTRY_SZ; - caps->idx_entry_sz = 4; + caps->idx_entry_sz = HNS_ROCE_V2_IDX_ENTRY_SZ; caps->cq_entry_sz = HNS_ROCE_V2_CQE_ENTRY_SIZE; caps->page_size_cap = HNS_ROCE_V2_PAGE_SIZE_SUPPORTED; caps->reserved_lkey = 0; @@ -1696,16 +1644,13 @@ caps->mpt_ba_pg_sz = 0; caps->mpt_buf_pg_sz = 0; caps->mpt_hop_num = HNS_ROCE_CONTEXT_HOP_NUM; - caps->pbl_ba_pg_sz = 2; - caps->pbl_buf_pg_sz = 0; - caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM; caps->mtt_ba_pg_sz = 0; caps->mtt_buf_pg_sz = 0; caps->mtt_hop_num = HNS_ROCE_MTT_HOP_NUM; - caps->wqe_sq_hop_num = 2; - caps->wqe_sge_hop_num = 1; - caps->wqe_rq_hop_num = 2; - caps->cqe_ba_pg_sz = 6; + caps->wqe_sq_hop_num = HNS_ROCE_SQWQE_HOP_NUM; + caps->wqe_sge_hop_num = HNS_ROCE_EXT_SGE_HOP_NUM; + caps->wqe_rq_hop_num = HNS_ROCE_RQWQE_HOP_NUM; + caps->cqe_ba_pg_sz = HNS_ROCE_BA_PG_SZ_SUPPORTED_256K; caps->cqe_buf_pg_sz = 0; caps->cqe_hop_num = HNS_ROCE_CQE_HOP_NUM; caps->srqwqe_ba_pg_sz = 0; @@ -1714,10 +1659,6 @@ caps->idx_ba_pg_sz = 0; caps->idx_buf_pg_sz = 0; caps->idx_hop_num = HNS_ROCE_IDX_HOP_NUM; - caps->eqe_ba_pg_sz = 0; - caps->eqe_buf_pg_sz = 0; - caps->eqe_hop_num = HNS_ROCE_EQE_HOP_NUM; - caps->tsq_buf_pg_sz = 0; caps->chunk_sz = HNS_ROCE_V2_TABLE_CHUNK_SIZE; caps->flags = HNS_ROCE_CAP_FLAG_REREG_MR | @@ -1726,24 +1667,19 @@ HNS_ROCE_CAP_FLAG_RECORD_DB | HNS_ROCE_CAP_FLAG_SQ_RECORD_DB; - if (hr_dev->pci_dev->revision == 0x21) - caps->flags |= HNS_ROCE_CAP_FLAG_MW | - HNS_ROCE_CAP_FLAG_FRMR; - caps->pkey_table_len[0] = 1; - caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM; + caps->gid_table_len[0] = HNS_ROCE_V2_GID_INDEX_NUM; caps->ceqe_depth = HNS_ROCE_V2_COMP_EQE_NUM; caps->aeqe_depth = HNS_ROCE_V2_ASYNC_EQE_NUM; caps->local_ca_ack_delay = 0; caps->max_mtu = IB_MTU_4096; - caps->max_srqs = HNS_ROCE_V2_MAX_SRQ; caps->max_srq_wrs = HNS_ROCE_V2_MAX_SRQ_WR; caps->max_srq_sges = HNS_ROCE_V2_MAX_SRQ_SGE; - if (hr_dev->pci_dev->revision == 0x21) { - caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | - HNS_ROCE_CAP_FLAG_SRQ | + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) { + caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW | + HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR | HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL; caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM; @@ -1757,12 +1693,343 @@ caps->cqc_timer_buf_pg_sz = 0; caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0; - caps->sccc_entry_sz = HNS_ROCE_V2_SCCC_ENTRY_SZ; - caps->sccc_ba_pg_sz = 0; - caps->sccc_buf_pg_sz = 0; - caps->sccc_hop_num = HNS_ROCE_SCCC_HOP_NUM; + caps->sccc_entry_sz = HNS_ROCE_V2_SCCC_ENTRY_SZ; + caps->sccc_ba_pg_sz = 0; + caps->sccc_buf_pg_sz = 0; + caps->sccc_hop_num = HNS_ROCE_SCCC_HOP_NUM; + } +} + +static void calc_pg_sz(int obj_num, int obj_size, int hop_num, int ctx_bt_num, + int *buf_page_size, int *bt_page_size, u32 hem_type) +{ + u64 obj_per_chunk; + int bt_chunk_size = 1 << PAGE_SHIFT; + int buf_chunk_size = 1 << PAGE_SHIFT; + int obj_per_chunk_default = buf_chunk_size / obj_size; + + *buf_page_size = 0; + *bt_page_size = 0; + + switch (hop_num) { + case 3: + obj_per_chunk = ctx_bt_num * (bt_chunk_size / BA_BYTE_LEN) * + (bt_chunk_size / BA_BYTE_LEN) * + (bt_chunk_size / BA_BYTE_LEN) * + obj_per_chunk_default; + break; + case 2: + obj_per_chunk = ctx_bt_num * (bt_chunk_size / BA_BYTE_LEN) * + (bt_chunk_size / BA_BYTE_LEN) * + obj_per_chunk_default; + break; + case 1: + obj_per_chunk = ctx_bt_num * (bt_chunk_size / BA_BYTE_LEN) * + obj_per_chunk_default; + break; + case HNS_ROCE_HOP_NUM_0: + obj_per_chunk = ctx_bt_num * obj_per_chunk_default; + break; + default: + pr_err("Table %d not support hop_num = %d!\n", hem_type, + hop_num); + return; + } + + if (hem_type >= HEM_TYPE_MTT) + *bt_page_size = ilog2(DIV_ROUND_UP(obj_num, obj_per_chunk)); + else + *buf_page_size = ilog2(DIV_ROUND_UP(obj_num, obj_per_chunk)); +} + +static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev) +{ + struct hns_roce_cmq_desc desc[HNS_ROCE_QUERY_PF_CAPS_CMD_NUM]; + struct hns_roce_caps *caps = &hr_dev->caps; + struct hns_roce_query_pf_caps_a *resp_a; + struct hns_roce_query_pf_caps_b *resp_b; + struct hns_roce_query_pf_caps_c *resp_c; + struct hns_roce_query_pf_caps_d *resp_d; + struct hns_roce_query_pf_caps_e *resp_e; + int ctx_hop_num; + int pbl_hop_num; + int ret; + int i; + + for (i = 0; i < HNS_ROCE_QUERY_PF_CAPS_CMD_NUM; i++) { + hns_roce_cmq_setup_basic_desc(&desc[i], + HNS_ROCE_OPC_QUERY_PF_CAPS_NUM, + true); + if (i < (HNS_ROCE_QUERY_PF_CAPS_CMD_NUM - 1)) + desc[i].flag |= cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT); + else + desc[i].flag &= ~cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT); + } + + ret = hns_roce_cmq_send(hr_dev, desc, HNS_ROCE_QUERY_PF_CAPS_CMD_NUM); + if (ret) + return ret; + + resp_a = (struct hns_roce_query_pf_caps_a *)desc[0].data; + resp_b = (struct hns_roce_query_pf_caps_b *)desc[1].data; + resp_c = (struct hns_roce_query_pf_caps_c *)desc[2].data; + resp_d = (struct hns_roce_query_pf_caps_d *)desc[3].data; + resp_e = (struct hns_roce_query_pf_caps_e *)desc[4].data; + + caps->local_ca_ack_delay = resp_a->local_ca_ack_delay; + caps->max_sq_sg = le16_to_cpu(resp_a->max_sq_sg); + caps->max_sq_inline = le16_to_cpu(resp_a->max_sq_inline); + caps->max_rq_sg = le16_to_cpu(resp_a->max_rq_sg); + caps->max_extend_sg = le32_to_cpu(resp_a->max_extend_sg); + caps->num_qpc_timer = le16_to_cpu(resp_a->num_qpc_timer); + caps->num_cqc_timer = le16_to_cpu(resp_a->num_cqc_timer); + caps->max_srq_sges = le16_to_cpu(resp_a->max_srq_sges); + caps->num_aeq_vectors = resp_a->num_aeq_vectors; + caps->num_other_vectors = resp_a->num_other_vectors; + caps->max_sq_desc_sz = resp_a->max_sq_desc_sz; + caps->max_rq_desc_sz = resp_a->max_rq_desc_sz; + caps->max_srq_desc_sz = resp_a->max_srq_desc_sz; + caps->cq_entry_sz = resp_a->cq_entry_sz; + + caps->mtpt_entry_sz = resp_b->mtpt_entry_sz; + caps->irrl_entry_sz = resp_b->irrl_entry_sz; + caps->trrl_entry_sz = resp_b->trrl_entry_sz; + caps->cqc_entry_sz = resp_b->cqc_entry_sz; + caps->srqc_entry_sz = resp_b->srqc_entry_sz; + caps->idx_entry_sz = resp_b->idx_entry_sz; + caps->sccc_entry_sz = resp_b->scc_ctx_entry_sz; + caps->max_mtu = resp_b->max_mtu; + caps->qpc_entry_sz = le16_to_cpu(resp_b->qpc_entry_sz); + caps->min_cqes = resp_b->min_cqes; + caps->min_wqes = resp_b->min_wqes; + caps->page_size_cap = le32_to_cpu(resp_b->page_size_cap); + caps->pkey_table_len[0] = resp_b->pkey_table_len; + caps->phy_num_uars = resp_b->phy_num_uars; + ctx_hop_num = resp_b->ctx_hop_num; + pbl_hop_num = resp_b->pbl_hop_num; + + caps->num_pds = 1 << roce_get_field(resp_c->cap_flags_num_pds, + V2_QUERY_PF_CAPS_C_NUM_PDS_M, + V2_QUERY_PF_CAPS_C_NUM_PDS_S); + caps->flags = roce_get_field(resp_c->cap_flags_num_pds, + V2_QUERY_PF_CAPS_C_CAP_FLAGS_M, + V2_QUERY_PF_CAPS_C_CAP_FLAGS_S); + caps->num_cqs = 1 << roce_get_field(resp_c->max_gid_num_cqs, + V2_QUERY_PF_CAPS_C_NUM_CQS_M, + V2_QUERY_PF_CAPS_C_NUM_CQS_S); + caps->gid_table_len[0] = roce_get_field(resp_c->max_gid_num_cqs, + V2_QUERY_PF_CAPS_C_MAX_GID_M, + V2_QUERY_PF_CAPS_C_MAX_GID_S); + caps->max_cqes = 1 << roce_get_field(resp_c->cq_depth, + V2_QUERY_PF_CAPS_C_CQ_DEPTH_M, + V2_QUERY_PF_CAPS_C_CQ_DEPTH_S); + caps->num_mtpts = 1 << roce_get_field(resp_c->num_mrws, + V2_QUERY_PF_CAPS_C_NUM_MRWS_M, + V2_QUERY_PF_CAPS_C_NUM_MRWS_S); + caps->num_qps = 1 << roce_get_field(resp_c->ord_num_qps, + V2_QUERY_PF_CAPS_C_NUM_QPS_M, + V2_QUERY_PF_CAPS_C_NUM_QPS_S); + caps->max_qp_init_rdma = roce_get_field(resp_c->ord_num_qps, + V2_QUERY_PF_CAPS_C_MAX_ORD_M, + V2_QUERY_PF_CAPS_C_MAX_ORD_S); + caps->max_qp_dest_rdma = caps->max_qp_init_rdma; + caps->max_wqes = 1 << le16_to_cpu(resp_c->sq_depth); + caps->num_srqs = 1 << roce_get_field(resp_d->wq_hop_num_max_srqs, + V2_QUERY_PF_CAPS_D_NUM_SRQS_M, + V2_QUERY_PF_CAPS_D_NUM_SRQS_S); + caps->max_srq_wrs = 1 << le16_to_cpu(resp_d->srq_depth); + caps->ceqe_depth = 1 << roce_get_field(resp_d->num_ceqs_ceq_depth, + V2_QUERY_PF_CAPS_D_CEQ_DEPTH_M, + V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S); + caps->num_comp_vectors = roce_get_field(resp_d->num_ceqs_ceq_depth, + V2_QUERY_PF_CAPS_D_NUM_CEQS_M, + V2_QUERY_PF_CAPS_D_NUM_CEQS_S); + caps->aeqe_depth = 1 << roce_get_field(resp_d->arm_st_aeq_depth, + V2_QUERY_PF_CAPS_D_AEQ_DEPTH_M, + V2_QUERY_PF_CAPS_D_AEQ_DEPTH_S); + caps->default_aeq_arm_st = roce_get_field(resp_d->arm_st_aeq_depth, + V2_QUERY_PF_CAPS_D_AEQ_ARM_ST_M, + V2_QUERY_PF_CAPS_D_AEQ_ARM_ST_S); + caps->default_ceq_arm_st = roce_get_field(resp_d->arm_st_aeq_depth, + V2_QUERY_PF_CAPS_D_CEQ_ARM_ST_M, + V2_QUERY_PF_CAPS_D_CEQ_ARM_ST_S); + caps->reserved_pds = roce_get_field(resp_d->num_uars_rsv_pds, + V2_QUERY_PF_CAPS_D_RSV_PDS_M, + V2_QUERY_PF_CAPS_D_RSV_PDS_S); + caps->num_uars = 1 << roce_get_field(resp_d->num_uars_rsv_pds, + V2_QUERY_PF_CAPS_D_NUM_UARS_M, + V2_QUERY_PF_CAPS_D_NUM_UARS_S); + caps->reserved_qps = roce_get_field(resp_d->rsv_uars_rsv_qps, + V2_QUERY_PF_CAPS_D_RSV_QPS_M, + V2_QUERY_PF_CAPS_D_RSV_QPS_S); + caps->reserved_uars = roce_get_field(resp_d->rsv_uars_rsv_qps, + V2_QUERY_PF_CAPS_D_RSV_UARS_M, + V2_QUERY_PF_CAPS_D_RSV_UARS_S); + caps->reserved_mrws = roce_get_field(resp_e->chunk_size_shift_rsv_mrws, + V2_QUERY_PF_CAPS_E_RSV_MRWS_M, + V2_QUERY_PF_CAPS_E_RSV_MRWS_S); + caps->chunk_sz = 1 << roce_get_field(resp_e->chunk_size_shift_rsv_mrws, + V2_QUERY_PF_CAPS_E_CHUNK_SIZE_SHIFT_M, + V2_QUERY_PF_CAPS_E_CHUNK_SIZE_SHIFT_S); + caps->reserved_cqs = roce_get_field(resp_e->rsv_cqs, + V2_QUERY_PF_CAPS_E_RSV_CQS_M, + V2_QUERY_PF_CAPS_E_RSV_CQS_S); + caps->reserved_srqs = roce_get_field(resp_e->rsv_srqs, + V2_QUERY_PF_CAPS_E_RSV_SRQS_M, + V2_QUERY_PF_CAPS_E_RSV_SRQS_S); + caps->reserved_lkey = roce_get_field(resp_e->rsv_lkey, + V2_QUERY_PF_CAPS_E_RSV_LKEYS_M, + V2_QUERY_PF_CAPS_E_RSV_LKEYS_S); + caps->default_ceq_max_cnt = le16_to_cpu(resp_e->ceq_max_cnt); + caps->default_ceq_period = le16_to_cpu(resp_e->ceq_period); + caps->default_aeq_max_cnt = le16_to_cpu(resp_e->aeq_max_cnt); + caps->default_aeq_period = le16_to_cpu(resp_e->aeq_period); + + caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ; + caps->cqc_timer_entry_sz = HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ; + caps->mtt_entry_sz = HNS_ROCE_V2_MTT_ENTRY_SZ; + caps->num_mtt_segs = HNS_ROCE_V2_MAX_MTT_SEGS; + caps->mtt_ba_pg_sz = 0; + caps->num_cqe_segs = HNS_ROCE_V2_MAX_CQE_SEGS; + caps->num_srqwqe_segs = HNS_ROCE_V2_MAX_SRQWQE_SEGS; + caps->num_idx_segs = HNS_ROCE_V2_MAX_IDX_SEGS; + + caps->qpc_hop_num = ctx_hop_num; + caps->srqc_hop_num = ctx_hop_num; + caps->cqc_hop_num = ctx_hop_num; + caps->mpt_hop_num = ctx_hop_num; + caps->mtt_hop_num = pbl_hop_num; + caps->cqe_hop_num = pbl_hop_num; + caps->srqwqe_hop_num = pbl_hop_num; + caps->idx_hop_num = pbl_hop_num; + caps->wqe_sq_hop_num = roce_get_field(resp_d->wq_hop_num_max_srqs, + V2_QUERY_PF_CAPS_D_SQWQE_HOP_NUM_M, + V2_QUERY_PF_CAPS_D_SQWQE_HOP_NUM_S); + caps->wqe_sge_hop_num = roce_get_field(resp_d->wq_hop_num_max_srqs, + V2_QUERY_PF_CAPS_D_EX_SGE_HOP_NUM_M, + V2_QUERY_PF_CAPS_D_EX_SGE_HOP_NUM_S); + caps->wqe_rq_hop_num = roce_get_field(resp_d->wq_hop_num_max_srqs, + V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_M, + V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_S); + + calc_pg_sz(caps->num_qps, caps->qpc_entry_sz, caps->qpc_hop_num, + caps->qpc_bt_num, &caps->qpc_buf_pg_sz, &caps->qpc_ba_pg_sz, + HEM_TYPE_QPC); + calc_pg_sz(caps->num_mtpts, caps->mtpt_entry_sz, caps->mpt_hop_num, + caps->mpt_bt_num, &caps->mpt_buf_pg_sz, &caps->mpt_ba_pg_sz, + HEM_TYPE_MTPT); + calc_pg_sz(caps->num_cqs, caps->cqc_entry_sz, caps->cqc_hop_num, + caps->cqc_bt_num, &caps->cqc_buf_pg_sz, &caps->cqc_ba_pg_sz, + HEM_TYPE_CQC); + calc_pg_sz(caps->num_srqs, caps->srqc_entry_sz, caps->srqc_hop_num, + caps->srqc_bt_num, &caps->srqc_buf_pg_sz, + &caps->srqc_ba_pg_sz, HEM_TYPE_SRQC); + + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) { + caps->sccc_hop_num = ctx_hop_num; + caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0; + caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0; + + calc_pg_sz(caps->num_qps, caps->sccc_entry_sz, + caps->sccc_hop_num, caps->sccc_bt_num, + &caps->sccc_buf_pg_sz, &caps->sccc_ba_pg_sz, + HEM_TYPE_SCCC); + calc_pg_sz(caps->num_cqc_timer, caps->cqc_timer_entry_sz, + caps->cqc_timer_hop_num, caps->cqc_timer_bt_num, + &caps->cqc_timer_buf_pg_sz, + &caps->cqc_timer_ba_pg_sz, HEM_TYPE_CQC_TIMER); + } + + calc_pg_sz(caps->num_cqe_segs, caps->mtt_entry_sz, caps->cqe_hop_num, + 1, &caps->cqe_buf_pg_sz, &caps->cqe_ba_pg_sz, HEM_TYPE_CQE); + calc_pg_sz(caps->num_srqwqe_segs, caps->mtt_entry_sz, + caps->srqwqe_hop_num, 1, &caps->srqwqe_buf_pg_sz, + &caps->srqwqe_ba_pg_sz, HEM_TYPE_SRQWQE); + calc_pg_sz(caps->num_idx_segs, caps->idx_entry_sz, caps->idx_hop_num, + 1, &caps->idx_buf_pg_sz, &caps->idx_ba_pg_sz, HEM_TYPE_IDX); + + return 0; +} + +static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) +{ + struct hns_roce_caps *caps = &hr_dev->caps; + int ret; + + ret = hns_roce_cmq_query_hw_info(hr_dev); + if (ret) { + dev_err(hr_dev->dev, "Query hardware version fail, ret = %d.\n", + ret); + return ret; + } + + ret = hns_roce_query_fw_ver(hr_dev); + if (ret) { + dev_err(hr_dev->dev, "Query firmware version fail, ret = %d.\n", + ret); + return ret; + } + + ret = hns_roce_config_global_param(hr_dev); + if (ret) { + dev_err(hr_dev->dev, "Configure global param fail, ret = %d.\n", + ret); + return ret; + } + + /* Get pf resource owned by every pf */ + ret = hns_roce_query_pf_resource(hr_dev); + if (ret) { + dev_err(hr_dev->dev, "Query pf resource fail, ret = %d.\n", + ret); + return ret; + } + + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) { + ret = hns_roce_query_pf_timer_resource(hr_dev); + if (ret) { + dev_err(hr_dev->dev, + "Query pf timer resource fail, ret = %d.\n", + ret); + return ret; + } + + ret = hns_roce_set_vf_switch_param(hr_dev, 0); + if (ret) { + dev_err(hr_dev->dev, + "Set function switch param fail, ret = %d.\n", + ret); + return ret; + } + } + + ret = hns_roce_alloc_vf_resource(hr_dev); + if (ret) { + dev_err(hr_dev->dev, "Allocate vf resource fail, ret = %d.\n", + ret); + return ret; } + hr_dev->vendor_part_id = hr_dev->pci_dev->device; + hr_dev->sys_image_guid = be64_to_cpu(hr_dev->ib_dev.node_guid); + + caps->num_mtt_segs = HNS_ROCE_V2_MAX_MTT_SEGS; + caps->num_cqe_segs = HNS_ROCE_V2_MAX_CQE_SEGS; + caps->num_srqwqe_segs = HNS_ROCE_V2_MAX_SRQWQE_SEGS; + caps->num_idx_segs = HNS_ROCE_V2_MAX_IDX_SEGS; + + caps->pbl_ba_pg_sz = HNS_ROCE_BA_PG_SZ_SUPPORTED_16K; + caps->pbl_buf_pg_sz = 0; + caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM; + caps->eqe_ba_pg_sz = 0; + caps->eqe_buf_pg_sz = 0; + caps->eqe_hop_num = HNS_ROCE_EQE_HOP_NUM; + caps->tsq_buf_pg_sz = 0; + + ret = hns_roce_query_pf_caps(hr_dev); + if (ret) + set_default_caps(hr_dev); + ret = hns_roce_v2_set_bt(hr_dev); if (ret) dev_err(hr_dev->dev, "Configure bt attribute fail, ret = %d.\n", @@ -1818,37 +2085,32 @@ req_a->base_addr_h = cpu_to_le32(link_tbl->table.map >> 32); roce_set_field(req_a->depth_pgsz_init_en, - CFG_LLM_QUE_DEPTH_M, - CFG_LLM_QUE_DEPTH_S, + CFG_LLM_QUE_DEPTH_M, CFG_LLM_QUE_DEPTH_S, link_tbl->npages); roce_set_field(req_a->depth_pgsz_init_en, - CFG_LLM_QUE_PGSZ_M, - CFG_LLM_QUE_PGSZ_S, + CFG_LLM_QUE_PGSZ_M, CFG_LLM_QUE_PGSZ_S, link_tbl->pg_sz); req_a->head_ba_l = cpu_to_le32(entry[0].blk_ba0); req_a->head_ba_h_nxtptr = cpu_to_le32(entry[0].blk_ba1_nxt_ptr); - roce_set_field(req_a->head_ptr, - CFG_LLM_HEAD_PTR_M, + roce_set_field(req_a->head_ptr, CFG_LLM_HEAD_PTR_M, CFG_LLM_HEAD_PTR_S, 0); } else { req_b->tail_ba_l = cpu_to_le32(entry[page_num - 1].blk_ba0); - roce_set_field(req_b->tail_ba_h, - CFG_LLM_TAIL_BA_H_M, + roce_set_field(req_b->tail_ba_h, CFG_LLM_TAIL_BA_H_M, CFG_LLM_TAIL_BA_H_S, entry[page_num - 1].blk_ba1_nxt_ptr & - HNS_ROCE_LINK_TABLE_BA1_M); - roce_set_field(req_b->tail_ptr, - CFG_LLM_TAIL_PTR_M, + HNS_ROCE_LINK_TABLE_BA1_M); + roce_set_field(req_b->tail_ptr, CFG_LLM_TAIL_PTR_M, CFG_LLM_TAIL_PTR_S, (entry[page_num - 2].blk_ba1_nxt_ptr & - HNS_ROCE_LINK_TABLE_NXT_PTR_M) >> - HNS_ROCE_LINK_TABLE_NXT_PTR_S); + HNS_ROCE_LINK_TABLE_NXT_PTR_M) >> + HNS_ROCE_LINK_TABLE_NXT_PTR_S); } } - roce_set_field(req_a->depth_pgsz_init_en, - CFG_LLM_INIT_EN_M, CFG_LLM_INIT_EN_S, 1); + roce_set_field(req_a->depth_pgsz_init_en, CFG_LLM_INIT_EN_M, + CFG_LLM_INIT_EN_S, 1); return hns_roce_cmq_send(hr_dev, desc, 2); } @@ -2020,7 +2282,7 @@ { struct hns_roce_v2_priv *priv = hr_dev->priv; - if (hr_dev->pci_dev->revision == 0x21) + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) hns_roce_function_clear(hr_dev); hns_roce_free_link_table(hr_dev, &priv->tpq); @@ -2141,11 +2403,9 @@ hns_roce_cmq_setup_basic_desc(&desc, HNS_ROCE_OPC_CFG_SGID_TB, false); - roce_set_field(sgid_tb->table_idx_rsv, - CFG_SGID_TB_TABLE_IDX_M, + roce_set_field(sgid_tb->table_idx_rsv, CFG_SGID_TB_TABLE_IDX_M, CFG_SGID_TB_TABLE_IDX_S, gid_index); - roce_set_field(sgid_tb->vf_sgid_type_rsv, - CFG_SGID_TB_VF_SGID_TYPE_M, + roce_set_field(sgid_tb->vf_sgid_type_rsv, CFG_SGID_TB_VF_SGID_TYPE_M, CFG_SGID_TB_VF_SGID_TYPE_S, sgid_type); p = (u32 *)&gid->raw[0]; @@ -2416,11 +2676,10 @@ V2_MPT_BYTE_4_MPT_ST_S, V2_MPT_ST_FREE); roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PD_M, V2_MPT_BYTE_4_PD_S, mw->pdn); - roce_set_field(mpt_entry->byte_4_pd_hop_st, - V2_MPT_BYTE_4_PBL_HOP_NUM_M, + roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_HOP_NUM_M, V2_MPT_BYTE_4_PBL_HOP_NUM_S, - mw->pbl_hop_num == HNS_ROCE_HOP_NUM_0 ? - 0 : mw->pbl_hop_num); + mw->pbl_hop_num == HNS_ROCE_HOP_NUM_0 ? 0 : + mw->pbl_hop_num); roce_set_field(mpt_entry->byte_4_pd_hop_st, V2_MPT_BYTE_4_PBL_BA_PG_SZ_M, V2_MPT_BYTE_4_PBL_BA_PG_SZ_S, @@ -2428,6 +2687,7 @@ roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_R_INV_EN_S, 1); roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_L_INV_EN_S, 1); + roce_set_bit(mpt_entry->byte_8_mw_cnt_en, V2_MPT_BYTE_8_LW_EN_S, 1); roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_PA_S, 0); roce_set_bit(mpt_entry->byte_12_mw_pa, V2_MPT_BYTE_12_MR_MW_S, 1); @@ -2447,8 +2707,7 @@ static void *get_cqe_v2(struct hns_roce_cq *hr_cq, int n) { - return hns_roce_buf_offset(&hr_cq->hr_buf.hr_buf, - n * HNS_ROCE_V2_CQE_ENTRY_SIZE); + return hns_roce_buf_offset(&hr_cq->buf, n * HNS_ROCE_V2_CQE_ENTRY_SIZE); } static void *get_sw_cqe_v2(struct hns_roce_cq *hr_cq, int n) @@ -2457,7 +2716,7 @@ /* Get cqe when Owner bit is Conversely with the MSB of cons_idx */ return (roce_get_bit(cqe->byte_4, V2_CQE_BYTE_4_OWNER_S) ^ - !!(n & (hr_cq->ib_cq.cqe + 1))) ? cqe : NULL; + !!(n & hr_cq->cq_depth)) ? cqe : NULL; } static struct hns_roce_v2_cqe *next_cqe_sw_v2(struct hns_roce_cq *hr_cq) @@ -2483,7 +2742,7 @@ static void hns_roce_v2_cq_set_ci(struct hns_roce_cq *hr_cq, u32 cons_index) { - *hr_cq->set_ci_db = cons_index & 0xffffff; + *hr_cq->set_ci_db = cons_index & V2_CQ_DB_PARAMETER_CONS_IDX_M; } static void __hns_roce_v2_cq_clean(struct hns_roce_cq *hr_cq, u32 qpn, @@ -2550,8 +2809,7 @@ static void hns_roce_v2_write_cqc(struct hns_roce_dev *hr_dev, struct hns_roce_cq *hr_cq, void *mb_buf, - u64 *mtts, dma_addr_t dma_handle, int nent, - u32 vector) + u64 *mtts, dma_addr_t dma_handle) { struct hns_roce_v2_cq_context *cq_context; @@ -2563,9 +2821,9 @@ roce_set_field(cq_context->byte_4_pg_ceqn, V2_CQC_BYTE_4_ARM_ST_M, V2_CQC_BYTE_4_ARM_ST_S, REG_NXT_CEQE); roce_set_field(cq_context->byte_4_pg_ceqn, V2_CQC_BYTE_4_SHIFT_M, - V2_CQC_BYTE_4_SHIFT_S, ilog2((unsigned int)nent)); + V2_CQC_BYTE_4_SHIFT_S, ilog2(hr_cq->cq_depth)); roce_set_field(cq_context->byte_4_pg_ceqn, V2_CQC_BYTE_4_CEQN_M, - V2_CQC_BYTE_4_CEQN_S, vector); + V2_CQC_BYTE_4_CEQN_S, hr_cq->vector); roce_set_field(cq_context->byte_8_cqn, V2_CQC_BYTE_8_CQN_M, V2_CQC_BYTE_8_CQN_S, hr_cq->cqn); @@ -2688,16 +2946,63 @@ return 0; } +static int sw_comp(struct hns_roce_qp *hr_qp, struct hns_roce_wq *wq, + int num_entries, struct ib_wc *wc) +{ + unsigned int left; + int npolled = 0; + + left = wq->head - wq->tail; + if (left == 0) + return 0; + + left = min_t(unsigned int, (unsigned int)num_entries, left); + while (npolled < left) { + wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)]; + wc->status = IB_WC_WR_FLUSH_ERR; + wc->vendor_err = 0; + wc->qp = &hr_qp->ibqp; + + wq->tail++; + wc++; + npolled++; + } + + return npolled; +} + +static int hns_roce_v2_sw_poll_cq(struct hns_roce_cq *hr_cq, int num_entries, + struct ib_wc *wc) +{ + struct hns_roce_qp *hr_qp; + int npolled = 0; + + list_for_each_entry(hr_qp, &hr_cq->sq_list, sq_node) { + npolled += sw_comp(hr_qp, &hr_qp->sq, + num_entries - npolled, wc + npolled); + if (npolled >= num_entries) + goto out; + } + + list_for_each_entry(hr_qp, &hr_cq->rq_list, rq_node) { + npolled += sw_comp(hr_qp, &hr_qp->rq, + num_entries - npolled, wc + npolled); + if (npolled >= num_entries) + goto out; + } + +out: + return npolled; +} + static int hns_roce_v2_poll_one(struct hns_roce_cq *hr_cq, struct hns_roce_qp **cur_qp, struct ib_wc *wc) { + struct hns_roce_dev *hr_dev = to_hr_dev(hr_cq->ib_cq.device); struct hns_roce_srq *srq = NULL; - struct hns_roce_dev *hr_dev; struct hns_roce_v2_cqe *cqe; struct hns_roce_qp *hr_qp; struct hns_roce_wq *wq; - struct ib_qp_attr attr; - int attr_mask; int is_send; u16 wqe_ctr; u32 opcode; @@ -2721,7 +3026,6 @@ V2_CQE_BYTE_16_LCL_QPN_S); if (!*cur_qp || (qpn & HNS_ROCE_V2_CQE_QPN_MASK) != (*cur_qp)->qpn) { - hr_dev = to_hr_dev(hr_cq->ib_cq.device); hr_qp = __hns_roce_qp_lookup(hr_dev, qpn); if (unlikely(!hr_qp)) { dev_err(hr_dev->dev, "CQ %06lx with entry for unknown QPN %06x\n", @@ -2731,6 +3035,7 @@ *cur_qp = hr_qp; } + hr_qp = *cur_qp; wc->qp = &(*cur_qp)->ibqp; wc->vendor_err = 0; @@ -2815,14 +3120,24 @@ break; } - /* flush cqe if wc status is error, excluding flush error */ - if ((wc->status != IB_WC_SUCCESS) && - (wc->status != IB_WC_WR_FLUSH_ERR)) { - attr_mask = IB_QP_STATE; - attr.qp_state = IB_QPS_ERR; - return hns_roce_v2_modify_qp(&(*cur_qp)->ibqp, - &attr, attr_mask, - (*cur_qp)->state, IB_QPS_ERR); + /* + * Hip08 hardware cannot flush the WQEs in SQ/RQ if the QP state gets + * into errored mode. Hence, as a workaround to this hardware + * limitation, driver needs to assist in flushing. But the flushing + * operation uses mailbox to convey the QP state to the hardware and + * which can sleep due to the mutex protection around the mailbox calls. + * Hence, use the deferred flush for now. Once wc error detected, the + * flushing operation is needed. + */ + if (wc->status != IB_WC_SUCCESS && + wc->status != IB_WC_WR_FLUSH_ERR) { + dev_err(hr_dev->dev, "error cqe status is: 0x%x\n", + status & HNS_ROCE_V2_CQE_STATUS_MASK); + + if (!test_and_set_bit(HNS_ROCE_FLUSH_FLAG, &hr_qp->flush_flag)) + init_flush_work(hr_dev, hr_qp); + + return 0; } if (wc->status == IB_WC_WR_FLUSH_ERR) @@ -2968,6 +3283,7 @@ static int hns_roce_v2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc) { + struct hns_roce_dev *hr_dev = to_hr_dev(ibcq->device); struct hns_roce_cq *hr_cq = to_hr_cq(ibcq); struct hns_roce_qp *cur_qp = NULL; unsigned long flags; @@ -2975,6 +3291,18 @@ spin_lock_irqsave(&hr_cq->lock, flags); + /* + * When the device starts to reset, the state is RST_DOWN. At this time, + * there may still be some valid CQEs in the hardware that are not + * polled. Therefore, it is not allowed to switch to the software mode + * immediately. When the state changes to UNINIT, CQE no longer exists + * in the hardware, and then switch to software mode. + */ + if (hr_dev->state == HNS_ROCE_DEVICE_STATE_UNINIT) { + npolled = hns_roce_v2_sw_poll_cq(hr_cq, num_entries, wc); + goto out; + } + for (npolled = 0; npolled < num_entries; ++npolled) { if (hns_roce_v2_poll_one(hr_cq, &cur_qp, wc + npolled)) break; @@ -2986,6 +3314,7 @@ hns_roce_v2_cq_set_ci(hr_cq, hr_cq->cons_index); } +out: spin_unlock_irqrestore(&hr_cq->lock, flags); return npolled; @@ -3160,8 +3489,6 @@ } static int hns_roce_v2_qp_modify(struct hns_roce_dev *hr_dev, - enum ib_qp_state cur_state, - enum ib_qp_state new_state, struct hns_roce_v2_qp_context *context, struct hns_roce_qp *hr_qp) { @@ -3211,6 +3538,9 @@ roce_set_bit(context->byte_76_srqn_op_en, V2_QPC_BYTE_76_ATE_S, !!(access_flags & IB_ACCESS_REMOTE_ATOMIC)); roce_set_bit(qpc_mask->byte_76_srqn_op_en, V2_QPC_BYTE_76_ATE_S, 0); + roce_set_bit(context->byte_76_srqn_op_en, V2_QPC_BYTE_76_EXT_ATE_S, + !!(access_flags & IB_ACCESS_REMOTE_ATOMIC)); + roce_set_bit(qpc_mask->byte_76_srqn_op_en, V2_QPC_BYTE_76_EXT_ATE_S, 0); } static void set_qpc_wqe_cnt(struct hns_roce_qp *hr_qp, @@ -3578,6 +3908,12 @@ IB_ACCESS_REMOTE_ATOMIC)); roce_set_bit(qpc_mask->byte_76_srqn_op_en, V2_QPC_BYTE_76_ATE_S, 0); + roce_set_bit(context->byte_76_srqn_op_en, + V2_QPC_BYTE_76_EXT_ATE_S, + !!(attr->qp_access_flags & + IB_ACCESS_REMOTE_ATOMIC)); + roce_set_bit(qpc_mask->byte_76_srqn_op_en, + V2_QPC_BYTE_76_EXT_ATE_S, 0); } else { roce_set_bit(context->byte_76_srqn_op_en, V2_QPC_BYTE_76_RRE_S, !!(hr_qp->access_flags & IB_ACCESS_REMOTE_READ)); @@ -3593,6 +3929,11 @@ !!(hr_qp->access_flags & IB_ACCESS_REMOTE_ATOMIC)); roce_set_bit(qpc_mask->byte_76_srqn_op_en, V2_QPC_BYTE_76_ATE_S, 0); + roce_set_bit(context->byte_76_srqn_op_en, + V2_QPC_BYTE_76_EXT_ATE_S, + !!(hr_qp->access_flags & IB_ACCESS_REMOTE_ATOMIC)); + roce_set_bit(qpc_mask->byte_76_srqn_op_en, + V2_QPC_BYTE_76_EXT_ATE_S, 0); } roce_set_field(context->byte_16_buf_ba_pg_sz, V2_QPC_BYTE_16_PD_M, @@ -3839,13 +4180,11 @@ /* Configure GID index */ port_num = rdma_ah_get_port_num(&attr->ah_attr); roce_set_field(context->byte_20_smac_sgid_idx, - V2_QPC_BYTE_20_SGID_IDX_M, - V2_QPC_BYTE_20_SGID_IDX_S, + V2_QPC_BYTE_20_SGID_IDX_M, V2_QPC_BYTE_20_SGID_IDX_S, hns_get_gid_index(hr_dev, port_num - 1, grh->sgid_index)); roce_set_field(qpc_mask->byte_20_smac_sgid_idx, - V2_QPC_BYTE_20_SGID_IDX_M, - V2_QPC_BYTE_20_SGID_IDX_S, 0); + V2_QPC_BYTE_20_SGID_IDX_M, V2_QPC_BYTE_20_SGID_IDX_S, 0); memcpy(&(context->dmac), dmac, sizeof(u32)); roce_set_field(context->byte_52_udpspn_dmac, V2_QPC_BYTE_52_DMAC_M, V2_QPC_BYTE_52_DMAC_S, *((u16 *)(&dmac[4]))); @@ -4061,8 +4400,8 @@ struct hns_roce_qp *hr_qp = to_hr_qp(ibqp); const struct ib_gid_attr *gid_attr = NULL; int is_roce_protocol; + u16 vlan_id = 0xffff; bool is_udp = false; - u16 vlan = 0xffff; u8 ib_port; u8 hr_port; int ret; @@ -4074,7 +4413,7 @@ if (is_roce_protocol) { gid_attr = attr->ah_attr.grh.sgid_attr; - ret = rdma_read_gid_l2_fields(gid_attr, &vlan, NULL); + ret = rdma_read_gid_l2_fields(gid_attr, &vlan_id, NULL); if (ret) return ret; @@ -4083,7 +4422,7 @@ IB_GID_TYPE_ROCE_UDP_ENCAP); } - if (vlan < VLAN_CFI_MASK) { + if (vlan_id < VLAN_N_VID) { roce_set_bit(context->byte_76_srqn_op_en, V2_QPC_BYTE_76_RQ_VLAN_EN_S, 1); roce_set_bit(qpc_mask->byte_76_srqn_op_en, @@ -4095,7 +4434,7 @@ } roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_VLAN_ID_M, - V2_QPC_BYTE_24_VLAN_ID_S, vlan); + V2_QPC_BYTE_24_VLAN_ID_S, vlan_id); roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_VLAN_ID_M, V2_QPC_BYTE_24_VLAN_ID_S, 0); @@ -4129,7 +4468,7 @@ roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_HOP_LIMIT_M, V2_QPC_BYTE_24_HOP_LIMIT_S, 0); - if (hr_dev->pci_dev->revision == 0x21 && is_udp) + if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B && is_udp) roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M, V2_QPC_BYTE_24_TC_S, grh->traffic_class >> 2); else @@ -4235,8 +4574,7 @@ roce_set_field(context->byte_212_lsn, V2_QPC_BYTE_212_RETRY_CNT_M, - V2_QPC_BYTE_212_RETRY_CNT_S, - attr->retry_cnt); + V2_QPC_BYTE_212_RETRY_CNT_S, attr->retry_cnt); roce_set_field(qpc_mask->byte_212_lsn, V2_QPC_BYTE_212_RETRY_CNT_M, V2_QPC_BYTE_212_RETRY_CNT_S, 0); @@ -4390,6 +4728,8 @@ struct hns_roce_v2_qp_context *context = ctx; struct hns_roce_v2_qp_context *qpc_mask = ctx + 1; struct device *dev = hr_dev->dev; + unsigned long sq_flag = 0; + unsigned long rq_flag = 0; int ret; /* @@ -4407,6 +4747,8 @@ /* When QP state is err, SQ and RQ WQE should be flushed */ if (new_state == IB_QPS_ERR) { + spin_lock_irqsave(&hr_qp->sq.lock, sq_flag); + hr_qp->state = IB_QPS_ERR; roce_set_field(context->byte_160_sq_ci_pi, V2_QPC_BYTE_160_SQ_PRODUCER_IDX_M, V2_QPC_BYTE_160_SQ_PRODUCER_IDX_S, @@ -4414,8 +4756,10 @@ roce_set_field(qpc_mask->byte_160_sq_ci_pi, V2_QPC_BYTE_160_SQ_PRODUCER_IDX_M, V2_QPC_BYTE_160_SQ_PRODUCER_IDX_S, 0); + spin_unlock_irqrestore(&hr_qp->sq.lock, sq_flag); if (!ibqp->srq) { + spin_lock_irqsave(&hr_qp->rq.lock, rq_flag); roce_set_field(context->byte_84_rq_ci_pi, V2_QPC_BYTE_84_RQ_PRODUCER_IDX_M, V2_QPC_BYTE_84_RQ_PRODUCER_IDX_S, @@ -4423,6 +4767,7 @@ roce_set_field(qpc_mask->byte_84_rq_ci_pi, V2_QPC_BYTE_84_RQ_PRODUCER_IDX_M, V2_QPC_BYTE_84_RQ_PRODUCER_IDX_S, 0); + spin_unlock_irqrestore(&hr_qp->rq.lock, rq_flag); } } @@ -4444,7 +4789,7 @@ V2_QPC_BYTE_60_QP_ST_S, 0); /* SW pass context to HW */ - ret = hns_roce_v2_qp_modify(hr_dev, cur_state, new_state, ctx, hr_qp); + ret = hns_roce_v2_qp_modify(hr_dev, ctx, hr_qp); if (ret) { dev_err(dev, "hns_roce_qp_modify failed(%d)\n", ret); goto out; @@ -4465,7 +4810,6 @@ hr_qp->rq.tail = 0; hr_qp->sq.head = 0; hr_qp->sq.tail = 0; - hr_qp->sq_next_wqe = 0; hr_qp->next_sge = 0; if (hr_qp->rq.wqe_cnt) *hr_qp->rdb.db_record = 0; @@ -4562,7 +4906,7 @@ qp_attr->path_mig_state = IB_MIG_ARMED; qp_attr->ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE; if (hr_qp->ibqp.qp_type == IB_QPT_UD) - qp_attr->qkey = V2_QKEY_VAL; + qp_attr->qkey = le32_to_cpu(context.qkey_xrcd); qp_attr->rq_psn = roce_get_field(context.byte_108_rx_reqepsn, V2_QPC_BYTE_108_RX_REQ_EPSN_M, @@ -4620,9 +4964,11 @@ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S); qp_attr->retry_cnt = roce_get_field(context.byte_212_lsn, - V2_QPC_BYTE_212_RETRY_CNT_M, - V2_QPC_BYTE_212_RETRY_CNT_S); - qp_attr->rnr_retry = le32_to_cpu(context.rq_rnr_timer); + V2_QPC_BYTE_212_RETRY_NUM_INIT_M, + V2_QPC_BYTE_212_RETRY_NUM_INIT_S); + qp_attr->rnr_retry = roce_get_field(context.byte_244_rnr_rxack, + V2_QPC_BYTE_244_RNR_NUM_INIT_M, + V2_QPC_BYTE_244_RNR_NUM_INIT_S); done: qp_attr->cur_qp_state = qp_attr->qp_state; @@ -4638,6 +4984,7 @@ } qp_init_attr->cap = qp_attr->cap; + qp_init_attr->sq_sig_type = hr_qp->sq_signal_bits; out: mutex_unlock(&hr_qp->mutex); @@ -4650,72 +4997,41 @@ { struct hns_roce_cq *send_cq, *recv_cq; struct ib_device *ibdev = &hr_dev->ib_dev; - int ret; + unsigned long flags; + int ret = 0; if (hr_qp->ibqp.qp_type == IB_QPT_RC && hr_qp->state != IB_QPS_RESET) { /* Modify qp to reset before destroying qp */ ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, NULL, 0, hr_qp->state, IB_QPS_RESET); - if (ret) { + if (ret) ibdev_err(ibdev, "modify QP to Reset failed.\n"); - return ret; - } } - send_cq = to_hr_cq(hr_qp->ibqp.send_cq); - recv_cq = to_hr_cq(hr_qp->ibqp.recv_cq); + send_cq = hr_qp->ibqp.send_cq ? to_hr_cq(hr_qp->ibqp.send_cq) : NULL; + recv_cq = hr_qp->ibqp.recv_cq ? to_hr_cq(hr_qp->ibqp.recv_cq) : NULL; + spin_lock_irqsave(&hr_dev->qp_list_lock, flags); hns_roce_lock_cqs(send_cq, recv_cq); if (!udata) { - __hns_roce_v2_cq_clean(recv_cq, hr_qp->qpn, hr_qp->ibqp.srq ? - to_hr_srq(hr_qp->ibqp.srq) : NULL); - if (send_cq != recv_cq) + if (recv_cq) + __hns_roce_v2_cq_clean(recv_cq, hr_qp->qpn, + (hr_qp->ibqp.srq ? + to_hr_srq(hr_qp->ibqp.srq) : + NULL)); + + if (send_cq && send_cq != recv_cq) __hns_roce_v2_cq_clean(send_cq, hr_qp->qpn, NULL); + } hns_roce_qp_remove(hr_dev, hr_qp); hns_roce_unlock_cqs(send_cq, recv_cq); + spin_unlock_irqrestore(&hr_dev->qp_list_lock, flags); - hns_roce_qp_free(hr_dev, hr_qp); - - /* Not special_QP, free their QPN */ - if ((hr_qp->ibqp.qp_type == IB_QPT_RC) || - (hr_qp->ibqp.qp_type == IB_QPT_UC) || - (hr_qp->ibqp.qp_type == IB_QPT_UD)) - hns_roce_release_range_qp(hr_dev, hr_qp->qpn, 1); - - hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr); - - if (udata) { - struct hns_roce_ucontext *context = - rdma_udata_to_drv_context( - udata, - struct hns_roce_ucontext, - ibucontext); - - if (hr_qp->sq.wqe_cnt && (hr_qp->sdb_en == 1)) - hns_roce_db_unmap_user(context, &hr_qp->sdb); - - if (hr_qp->rq.wqe_cnt && (hr_qp->rdb_en == 1)) - hns_roce_db_unmap_user(context, &hr_qp->rdb); - } else { - kfree(hr_qp->sq.wrid); - kfree(hr_qp->rq.wrid); - hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); - if (hr_qp->rq.wqe_cnt) - hns_roce_free_db(hr_dev, &hr_qp->rdb); - } - ib_umem_release(hr_qp->umem); - - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) && - hr_qp->rq.wqe_cnt) { - kfree(hr_qp->rq_inl_buf.wqe_list[0].sg_list); - kfree(hr_qp->rq_inl_buf.wqe_list); - } - - return 0; + return ret; } static int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) @@ -4725,16 +5041,11 @@ int ret; ret = hns_roce_v2_destroy_qp_common(hr_dev, hr_qp, udata); - if (ret) { + if (ret) ibdev_err(&hr_dev->ib_dev, "Destroy qp 0x%06lx failed(%d)\n", hr_qp->qpn, ret); - return ret; - } - if (hr_qp->ibqp.qp_type == IB_QPT_GSI) - kfree(hr_to_hr_sqp(hr_qp)); - else - kfree(hr_qp); + hns_roce_qp_destroy(hr_dev, hr_qp, udata); return 0; } @@ -4833,39 +5144,6 @@ return ret; } -static void hns_roce_set_qps_to_err(struct hns_roce_dev *hr_dev, u32 qpn) -{ - struct hns_roce_qp *hr_qp; - struct ib_qp_attr attr; - int attr_mask; - int ret; - - hr_qp = __hns_roce_qp_lookup(hr_dev, qpn); - if (!hr_qp) { - dev_warn(hr_dev->dev, "no hr_qp can be found!\n"); - return; - } - - if (hr_qp->ibqp.uobject) { - if (hr_qp->sdb_en == 1) { - hr_qp->sq.head = *(int *)(hr_qp->sdb.virt_addr); - if (hr_qp->rdb_en == 1) - hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr); - } else { - dev_warn(hr_dev->dev, "flush cqe is unsupported in userspace!\n"); - return; - } - } - - attr_mask = IB_QP_STATE; - attr.qp_state = IB_QPS_ERR; - ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, &attr, attr_mask, - hr_qp->state, IB_QPS_ERR); - if (ret) - dev_err(hr_dev->dev, "failed to modify qp %d to err state.\n", - qpn); -} - static void hns_roce_irq_work_handle(struct work_struct *work) { struct hns_roce_work *irq_work = @@ -4889,17 +5167,14 @@ case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR: dev_err(dev, "Local work queue 0x%x catas error, sub_type:%d\n", qpn, irq_work->sub_type); - hns_roce_set_qps_to_err(irq_work->hr_dev, qpn); break; case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR: dev_err(dev, "Invalid request local work queue 0x%x error.\n", qpn); - hns_roce_set_qps_to_err(irq_work->hr_dev, qpn); break; case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR: dev_err(dev, "Local access violation work queue 0x%x error, sub_type:%d\n", qpn, irq_work->sub_type); - hns_roce_set_qps_to_err(irq_work->hr_dev, qpn); break; case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH: dev_warn(dev, "SRQ limit reach.\n"); @@ -4951,10 +5226,7 @@ static void set_eq_cons_index_v2(struct hns_roce_eq *eq) { struct hns_roce_dev *hr_dev = eq->hr_dev; - __le32 doorbell[2]; - - doorbell[0] = 0; - doorbell[1] = 0; + __le32 doorbell[2] = {}; if (eq->type_flag == HNS_ROCE_AEQ) { roce_set_field(doorbell[0], HNS_ROCE_V2_EQ_DB_CMD_M, @@ -4980,44 +5252,24 @@ hns_roce_write64(hr_dev, doorbell, eq->doorbell); } -static struct hns_roce_aeqe *get_aeqe_v2(struct hns_roce_eq *eq, u32 entry) -{ - u32 buf_chk_sz; - unsigned long off; - - buf_chk_sz = 1 << (eq->eqe_buf_pg_sz + PAGE_SHIFT); - off = (entry & (eq->entries - 1)) * HNS_ROCE_AEQ_ENTRY_SIZE; - - return (struct hns_roce_aeqe *)((char *)(eq->buf_list->buf) + - off % buf_chk_sz); -} - -static struct hns_roce_aeqe *mhop_get_aeqe(struct hns_roce_eq *eq, u32 entry) +static inline void *get_eqe_buf(struct hns_roce_eq *eq, unsigned long offset) { u32 buf_chk_sz; - unsigned long off; buf_chk_sz = 1 << (eq->eqe_buf_pg_sz + PAGE_SHIFT); - - off = (entry & (eq->entries - 1)) * HNS_ROCE_AEQ_ENTRY_SIZE; - - if (eq->hop_num == HNS_ROCE_HOP_NUM_0) - return (struct hns_roce_aeqe *)((u8 *)(eq->bt_l0) + - off % buf_chk_sz); + if (eq->buf.nbufs == 1) + return eq->buf.direct.buf + offset % buf_chk_sz; else - return (struct hns_roce_aeqe *)((u8 *) - (eq->buf[off / buf_chk_sz]) + off % buf_chk_sz); + return eq->buf.page_list[offset / buf_chk_sz].buf + + offset % buf_chk_sz; } static struct hns_roce_aeqe *next_aeqe_sw_v2(struct hns_roce_eq *eq) { struct hns_roce_aeqe *aeqe; - if (!eq->hop_num) - aeqe = get_aeqe_v2(eq, eq->cons_index); - else - aeqe = mhop_get_aeqe(eq, eq->cons_index); - + aeqe = get_eqe_buf(eq, (eq->cons_index & (eq->entries - 1)) * + HNS_ROCE_AEQ_ENTRY_SIZE); return (roce_get_bit(aeqe->asyn, HNS_ROCE_V2_AEQ_AEQE_OWNER_S) ^ !!(eq->cons_index & eq->entries)) ? aeqe : NULL; } @@ -5110,44 +5362,12 @@ return aeqe_found; } -static struct hns_roce_ceqe *get_ceqe_v2(struct hns_roce_eq *eq, u32 entry) -{ - u32 buf_chk_sz; - unsigned long off; - - buf_chk_sz = 1 << (eq->eqe_buf_pg_sz + PAGE_SHIFT); - off = (entry & (eq->entries - 1)) * HNS_ROCE_CEQ_ENTRY_SIZE; - - return (struct hns_roce_ceqe *)((char *)(eq->buf_list->buf) + - off % buf_chk_sz); -} - -static struct hns_roce_ceqe *mhop_get_ceqe(struct hns_roce_eq *eq, u32 entry) -{ - u32 buf_chk_sz; - unsigned long off; - - buf_chk_sz = 1 << (eq->eqe_buf_pg_sz + PAGE_SHIFT); - - off = (entry & (eq->entries - 1)) * HNS_ROCE_CEQ_ENTRY_SIZE; - - if (eq->hop_num == HNS_ROCE_HOP_NUM_0) - return (struct hns_roce_ceqe *)((u8 *)(eq->bt_l0) + - off % buf_chk_sz); - else - return (struct hns_roce_ceqe *)((u8 *)(eq->buf[off / - buf_chk_sz]) + off % buf_chk_sz); -} - static struct hns_roce_ceqe *next_ceqe_sw_v2(struct hns_roce_eq *eq) { struct hns_roce_ceqe *ceqe; - if (!eq->hop_num) - ceqe = get_ceqe_v2(eq, eq->cons_index); - else - ceqe = mhop_get_ceqe(eq, eq->cons_index); - + ceqe = get_eqe_buf(eq, (eq->cons_index & (eq->entries - 1)) * + HNS_ROCE_CEQ_ENTRY_SIZE); return (!!(roce_get_bit(ceqe->comp, HNS_ROCE_V2_CEQ_CEQE_OWNER_S))) ^ (!!(eq->cons_index & eq->entries)) ? ceqe : NULL; } @@ -5166,8 +5386,7 @@ */ dma_rmb(); - cqn = roce_get_field(ceqe->comp, - HNS_ROCE_V2_CEQE_COMP_CQN_M, + cqn = roce_get_field(ceqe->comp, HNS_ROCE_V2_CEQE_COMP_CQN_M, HNS_ROCE_V2_CEQE_COMP_CQN_S); hns_roce_cq_completion(hr_dev, cqn); @@ -5223,8 +5442,8 @@ dev_err(dev, "AEQ overflow!\n"); - int_st |= 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S; - roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, int_st); + roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG, + 1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S); /* Set reset level for reset_event() */ if (ops->set_default_reset_request) @@ -5308,90 +5527,11 @@ dev_err(dev, "[mailbox cmd] destroy eqc(%d) failed.\n", eqn); } -static void hns_roce_mhop_free_eq(struct hns_roce_dev *hr_dev, - struct hns_roce_eq *eq) -{ - struct device *dev = hr_dev->dev; - u64 idx; - u64 size; - u32 buf_chk_sz; - u32 bt_chk_sz; - u32 mhop_num; - int eqe_alloc; - int i = 0; - int j = 0; - - mhop_num = hr_dev->caps.eqe_hop_num; - buf_chk_sz = 1 << (hr_dev->caps.eqe_buf_pg_sz + PAGE_SHIFT); - bt_chk_sz = 1 << (hr_dev->caps.eqe_ba_pg_sz + PAGE_SHIFT); - - if (mhop_num == HNS_ROCE_HOP_NUM_0) { - dma_free_coherent(dev, (unsigned int)(eq->entries * - eq->eqe_size), eq->bt_l0, eq->l0_dma); - return; - } - - dma_free_coherent(dev, bt_chk_sz, eq->bt_l0, eq->l0_dma); - if (mhop_num == 1) { - for (i = 0; i < eq->l0_last_num; i++) { - if (i == eq->l0_last_num - 1) { - eqe_alloc = i * (buf_chk_sz / eq->eqe_size); - size = (eq->entries - eqe_alloc) * eq->eqe_size; - dma_free_coherent(dev, size, eq->buf[i], - eq->buf_dma[i]); - break; - } - dma_free_coherent(dev, buf_chk_sz, eq->buf[i], - eq->buf_dma[i]); - } - } else if (mhop_num == 2) { - for (i = 0; i < eq->l0_last_num; i++) { - dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i], - eq->l1_dma[i]); - - for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) { - idx = i * (bt_chk_sz / BA_BYTE_LEN) + j; - if ((i == eq->l0_last_num - 1) - && j == eq->l1_last_num - 1) { - eqe_alloc = (buf_chk_sz / eq->eqe_size) - * idx; - size = (eq->entries - eqe_alloc) - * eq->eqe_size; - dma_free_coherent(dev, size, - eq->buf[idx], - eq->buf_dma[idx]); - break; - } - dma_free_coherent(dev, buf_chk_sz, eq->buf[idx], - eq->buf_dma[idx]); - } - } - } - kfree(eq->buf_dma); - kfree(eq->buf); - kfree(eq->l1_dma); - kfree(eq->bt_l1); - eq->buf_dma = NULL; - eq->buf = NULL; - eq->l1_dma = NULL; - eq->bt_l1 = NULL; -} - -static void hns_roce_v2_free_eq(struct hns_roce_dev *hr_dev, - struct hns_roce_eq *eq) +static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq) { - u32 buf_chk_sz; - - buf_chk_sz = 1 << (eq->eqe_buf_pg_sz + PAGE_SHIFT); - - if (hr_dev->caps.eqe_hop_num) { - hns_roce_mhop_free_eq(hr_dev, eq); - return; - } - - dma_free_coherent(hr_dev->dev, buf_chk_sz, eq->buf_list->buf, - eq->buf_list->map); - kfree(eq->buf_list); + if (!eq->hop_num || eq->hop_num == HNS_ROCE_HOP_NUM_0) + hns_roce_mtr_cleanup(hr_dev, &eq->mtr); + hns_roce_buf_free(hr_dev, eq->buf.size, &eq->buf); } static void hns_roce_config_eqc(struct hns_roce_dev *hr_dev, @@ -5399,6 +5539,8 @@ void *mb_buf) { struct hns_roce_eq_context *eqc; + u64 ba[MTT_MIN_COUNT] = { 0 }; + int count; eqc = mb_buf; memset(eqc, 0, sizeof(struct hns_roce_eq_context)); @@ -5414,349 +5556,211 @@ eq->eqe_buf_pg_sz = hr_dev->caps.eqe_buf_pg_sz; eq->shift = ilog2((unsigned int)eq->entries); - if (!eq->hop_num) - eq->eqe_ba = eq->buf_list->map; - else - eq->eqe_ba = eq->l0_dma; + /* if not muti-hop, eqe buffer only use one trunk */ + if (!eq->hop_num || eq->hop_num == HNS_ROCE_HOP_NUM_0) { + eq->eqe_ba = eq->buf.direct.map; + eq->cur_eqe_ba = eq->eqe_ba; + if (eq->buf.npages > 1) + eq->nxt_eqe_ba = eq->eqe_ba + (1 << eq->eqe_buf_pg_sz); + else + eq->nxt_eqe_ba = eq->eqe_ba; + } else { + count = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, ba, + MTT_MIN_COUNT, &eq->eqe_ba); + eq->cur_eqe_ba = ba[0]; + if (count > 1) + eq->nxt_eqe_ba = ba[1]; + else + eq->nxt_eqe_ba = ba[0]; + } /* set eqc state */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_EQ_ST_M, - HNS_ROCE_EQC_EQ_ST_S, + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_EQ_ST_M, HNS_ROCE_EQC_EQ_ST_S, HNS_ROCE_V2_EQ_STATE_VALID); /* set eqe hop num */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_HOP_NUM_M, + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_HOP_NUM_M, HNS_ROCE_EQC_HOP_NUM_S, eq->hop_num); /* set eqc over_ignore */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_OVER_IGNORE_M, + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_OVER_IGNORE_M, HNS_ROCE_EQC_OVER_IGNORE_S, eq->over_ignore); /* set eqc coalesce */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_COALESCE_M, + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_COALESCE_M, HNS_ROCE_EQC_COALESCE_S, eq->coalesce); /* set eqc arm_state */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_ARM_ST_M, + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_ARM_ST_M, HNS_ROCE_EQC_ARM_ST_S, eq->arm_st); /* set eqn */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_EQN_M, - HNS_ROCE_EQC_EQN_S, eq->eqn); + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_EQN_M, HNS_ROCE_EQC_EQN_S, + eq->eqn); /* set eqe_cnt */ - roce_set_field(eqc->byte_4, - HNS_ROCE_EQC_EQE_CNT_M, - HNS_ROCE_EQC_EQE_CNT_S, - HNS_ROCE_EQ_INIT_EQE_CNT); + roce_set_field(eqc->byte_4, HNS_ROCE_EQC_EQE_CNT_M, + HNS_ROCE_EQC_EQE_CNT_S, HNS_ROCE_EQ_INIT_EQE_CNT); /* set eqe_ba_pg_sz */ - roce_set_field(eqc->byte_8, - HNS_ROCE_EQC_BA_PG_SZ_M, + roce_set_field(eqc->byte_8, HNS_ROCE_EQC_BA_PG_SZ_M, HNS_ROCE_EQC_BA_PG_SZ_S, eq->eqe_ba_pg_sz + PG_SHIFT_OFFSET); /* set eqe_buf_pg_sz */ - roce_set_field(eqc->byte_8, - HNS_ROCE_EQC_BUF_PG_SZ_M, + roce_set_field(eqc->byte_8, HNS_ROCE_EQC_BUF_PG_SZ_M, HNS_ROCE_EQC_BUF_PG_SZ_S, eq->eqe_buf_pg_sz + PG_SHIFT_OFFSET); /* set eq_producer_idx */ - roce_set_field(eqc->byte_8, - HNS_ROCE_EQC_PROD_INDX_M, - HNS_ROCE_EQC_PROD_INDX_S, - HNS_ROCE_EQ_INIT_PROD_IDX); + roce_set_field(eqc->byte_8, HNS_ROCE_EQC_PROD_INDX_M, + HNS_ROCE_EQC_PROD_INDX_S, HNS_ROCE_EQ_INIT_PROD_IDX); /* set eq_max_cnt */ - roce_set_field(eqc->byte_12, - HNS_ROCE_EQC_MAX_CNT_M, + roce_set_field(eqc->byte_12, HNS_ROCE_EQC_MAX_CNT_M, HNS_ROCE_EQC_MAX_CNT_S, eq->eq_max_cnt); /* set eq_period */ - roce_set_field(eqc->byte_12, - HNS_ROCE_EQC_PERIOD_M, + roce_set_field(eqc->byte_12, HNS_ROCE_EQC_PERIOD_M, HNS_ROCE_EQC_PERIOD_S, eq->eq_period); /* set eqe_report_timer */ - roce_set_field(eqc->eqe_report_timer, - HNS_ROCE_EQC_REPORT_TIMER_M, + roce_set_field(eqc->eqe_report_timer, HNS_ROCE_EQC_REPORT_TIMER_M, HNS_ROCE_EQC_REPORT_TIMER_S, HNS_ROCE_EQ_INIT_REPORT_TIMER); /* set eqe_ba [34:3] */ - roce_set_field(eqc->eqe_ba0, - HNS_ROCE_EQC_EQE_BA_L_M, + roce_set_field(eqc->eqe_ba0, HNS_ROCE_EQC_EQE_BA_L_M, HNS_ROCE_EQC_EQE_BA_L_S, eq->eqe_ba >> 3); /* set eqe_ba [64:35] */ - roce_set_field(eqc->eqe_ba1, - HNS_ROCE_EQC_EQE_BA_H_M, + roce_set_field(eqc->eqe_ba1, HNS_ROCE_EQC_EQE_BA_H_M, HNS_ROCE_EQC_EQE_BA_H_S, eq->eqe_ba >> 35); /* set eq shift */ - roce_set_field(eqc->byte_28, - HNS_ROCE_EQC_SHIFT_M, - HNS_ROCE_EQC_SHIFT_S, eq->shift); + roce_set_field(eqc->byte_28, HNS_ROCE_EQC_SHIFT_M, HNS_ROCE_EQC_SHIFT_S, + eq->shift); /* set eq MSI_IDX */ - roce_set_field(eqc->byte_28, - HNS_ROCE_EQC_MSI_INDX_M, - HNS_ROCE_EQC_MSI_INDX_S, - HNS_ROCE_EQ_INIT_MSI_IDX); + roce_set_field(eqc->byte_28, HNS_ROCE_EQC_MSI_INDX_M, + HNS_ROCE_EQC_MSI_INDX_S, HNS_ROCE_EQ_INIT_MSI_IDX); /* set cur_eqe_ba [27:12] */ - roce_set_field(eqc->byte_28, - HNS_ROCE_EQC_CUR_EQE_BA_L_M, + roce_set_field(eqc->byte_28, HNS_ROCE_EQC_CUR_EQE_BA_L_M, HNS_ROCE_EQC_CUR_EQE_BA_L_S, eq->cur_eqe_ba >> 12); /* set cur_eqe_ba [59:28] */ - roce_set_field(eqc->byte_32, - HNS_ROCE_EQC_CUR_EQE_BA_M_M, + roce_set_field(eqc->byte_32, HNS_ROCE_EQC_CUR_EQE_BA_M_M, HNS_ROCE_EQC_CUR_EQE_BA_M_S, eq->cur_eqe_ba >> 28); /* set cur_eqe_ba [63:60] */ - roce_set_field(eqc->byte_36, - HNS_ROCE_EQC_CUR_EQE_BA_H_M, + roce_set_field(eqc->byte_36, HNS_ROCE_EQC_CUR_EQE_BA_H_M, HNS_ROCE_EQC_CUR_EQE_BA_H_S, eq->cur_eqe_ba >> 60); /* set eq consumer idx */ - roce_set_field(eqc->byte_36, - HNS_ROCE_EQC_CONS_INDX_M, - HNS_ROCE_EQC_CONS_INDX_S, - HNS_ROCE_EQ_INIT_CONS_IDX); + roce_set_field(eqc->byte_36, HNS_ROCE_EQC_CONS_INDX_M, + HNS_ROCE_EQC_CONS_INDX_S, HNS_ROCE_EQ_INIT_CONS_IDX); /* set nex_eqe_ba[43:12] */ - roce_set_field(eqc->nxt_eqe_ba0, - HNS_ROCE_EQC_NXT_EQE_BA_L_M, + roce_set_field(eqc->nxt_eqe_ba0, HNS_ROCE_EQC_NXT_EQE_BA_L_M, HNS_ROCE_EQC_NXT_EQE_BA_L_S, eq->nxt_eqe_ba >> 12); /* set nex_eqe_ba[63:44] */ - roce_set_field(eqc->nxt_eqe_ba1, - HNS_ROCE_EQC_NXT_EQE_BA_H_M, + roce_set_field(eqc->nxt_eqe_ba1, HNS_ROCE_EQC_NXT_EQE_BA_H_M, HNS_ROCE_EQC_NXT_EQE_BA_H_S, eq->nxt_eqe_ba >> 44); } -static int hns_roce_mhop_alloc_eq(struct hns_roce_dev *hr_dev, - struct hns_roce_eq *eq) +static int map_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq, + u32 page_shift) { - struct device *dev = hr_dev->dev; - int eq_alloc_done = 0; - int eq_buf_cnt = 0; - int eqe_alloc; - u32 buf_chk_sz; - u32 bt_chk_sz; - u32 mhop_num; - u64 size; - u64 idx; + struct hns_roce_buf_region region = {}; + dma_addr_t *buf_list = NULL; int ba_num; - int bt_num; - int record_i; - int record_j; - int i = 0; - int j = 0; - - mhop_num = hr_dev->caps.eqe_hop_num; - buf_chk_sz = 1 << (hr_dev->caps.eqe_buf_pg_sz + PAGE_SHIFT); - bt_chk_sz = 1 << (hr_dev->caps.eqe_ba_pg_sz + PAGE_SHIFT); + int ret; ba_num = DIV_ROUND_UP(PAGE_ALIGN(eq->entries * eq->eqe_size), - buf_chk_sz); - bt_num = DIV_ROUND_UP(ba_num, bt_chk_sz / BA_BYTE_LEN); - - if (mhop_num == HNS_ROCE_HOP_NUM_0) { - if (eq->entries > buf_chk_sz / eq->eqe_size) { - dev_err(dev, "eq entries %d is larger than buf_pg_sz!", - eq->entries); - return -EINVAL; - } - eq->bt_l0 = dma_alloc_coherent(dev, eq->entries * eq->eqe_size, - &(eq->l0_dma), GFP_KERNEL); - if (!eq->bt_l0) - return -ENOMEM; + 1 << page_shift); + hns_roce_init_buf_region(®ion, hr_dev->caps.eqe_hop_num, 0, ba_num); - eq->cur_eqe_ba = eq->l0_dma; - eq->nxt_eqe_ba = 0; + /* alloc a tmp list for storing eq buf address */ + ret = hns_roce_alloc_buf_list(®ion, &buf_list, 1); + if (ret) { + dev_err(hr_dev->dev, "alloc eq buf_list error\n"); + return ret; + } - return 0; + ba_num = hns_roce_get_kmem_bufs(hr_dev, buf_list, region.count, + region.offset, &eq->buf); + if (ba_num != region.count) { + dev_err(hr_dev->dev, "get eqe buf err,expect %d,ret %d.\n", + region.count, ba_num); + ret = -ENOBUFS; + goto done; } - eq->buf_dma = kcalloc(ba_num, sizeof(*eq->buf_dma), GFP_KERNEL); - if (!eq->buf_dma) - return -ENOMEM; - eq->buf = kcalloc(ba_num, sizeof(*eq->buf), GFP_KERNEL); - if (!eq->buf) - goto err_kcalloc_buf; - - if (mhop_num == 2) { - eq->l1_dma = kcalloc(bt_num, sizeof(*eq->l1_dma), GFP_KERNEL); - if (!eq->l1_dma) - goto err_kcalloc_l1_dma; - - eq->bt_l1 = kcalloc(bt_num, sizeof(*eq->bt_l1), GFP_KERNEL); - if (!eq->bt_l1) - goto err_kcalloc_bt_l1; - } - - /* alloc L0 BT */ - eq->bt_l0 = dma_alloc_coherent(dev, bt_chk_sz, &eq->l0_dma, GFP_KERNEL); - if (!eq->bt_l0) - goto err_dma_alloc_l0; - - if (mhop_num == 1) { - if (ba_num > (bt_chk_sz / BA_BYTE_LEN)) - dev_err(dev, "ba_num %d is too large for 1 hop\n", - ba_num); - - /* alloc buf */ - for (i = 0; i < bt_chk_sz / BA_BYTE_LEN; i++) { - if (eq_buf_cnt + 1 < ba_num) { - size = buf_chk_sz; - } else { - eqe_alloc = i * (buf_chk_sz / eq->eqe_size); - size = (eq->entries - eqe_alloc) * eq->eqe_size; - } - eq->buf[i] = dma_alloc_coherent(dev, size, - &(eq->buf_dma[i]), - GFP_KERNEL); - if (!eq->buf[i]) - goto err_dma_alloc_buf; + hns_roce_mtr_init(&eq->mtr, PAGE_SHIFT + hr_dev->caps.eqe_ba_pg_sz, + page_shift); + ret = hns_roce_mtr_attach(hr_dev, &eq->mtr, &buf_list, ®ion, 1); + if (ret) + dev_err(hr_dev->dev, "mtr attach error for eqe\n"); - *(eq->bt_l0 + i) = eq->buf_dma[i]; + goto done; - eq_buf_cnt++; - if (eq_buf_cnt >= ba_num) - break; - } - eq->cur_eqe_ba = eq->buf_dma[0]; - if (ba_num > 1) - eq->nxt_eqe_ba = eq->buf_dma[1]; - - } else if (mhop_num == 2) { - /* alloc L1 BT and buf */ - for (i = 0; i < bt_chk_sz / BA_BYTE_LEN; i++) { - eq->bt_l1[i] = dma_alloc_coherent(dev, bt_chk_sz, - &(eq->l1_dma[i]), - GFP_KERNEL); - if (!eq->bt_l1[i]) - goto err_dma_alloc_l1; - *(eq->bt_l0 + i) = eq->l1_dma[i]; - - for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) { - idx = i * bt_chk_sz / BA_BYTE_LEN + j; - if (eq_buf_cnt + 1 < ba_num) { - size = buf_chk_sz; - } else { - eqe_alloc = (buf_chk_sz / eq->eqe_size) - * idx; - size = (eq->entries - eqe_alloc) - * eq->eqe_size; - } - eq->buf[idx] = dma_alloc_coherent(dev, size, - &(eq->buf_dma[idx]), - GFP_KERNEL); - if (!eq->buf[idx]) - goto err_dma_alloc_buf; - - *(eq->bt_l1[i] + j) = eq->buf_dma[idx]; - - eq_buf_cnt++; - if (eq_buf_cnt >= ba_num) { - eq_alloc_done = 1; - break; - } - } + hns_roce_mtr_cleanup(hr_dev, &eq->mtr); +done: + hns_roce_free_buf_list(&buf_list, 1); - if (eq_alloc_done) - break; - } - eq->cur_eqe_ba = eq->buf_dma[0]; - if (ba_num > 1) - eq->nxt_eqe_ba = eq->buf_dma[1]; - } + return ret; +} - eq->l0_last_num = i + 1; - if (mhop_num == 2) - eq->l1_last_num = j + 1; +static int alloc_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq) +{ + struct hns_roce_buf *buf = &eq->buf; + bool is_mhop = false; + u32 page_shift; + u32 mhop_num; + u32 max_size; + int ret; - return 0; + page_shift = PAGE_SHIFT + hr_dev->caps.eqe_buf_pg_sz; + mhop_num = hr_dev->caps.eqe_hop_num; + if (!mhop_num) { + max_size = 1 << page_shift; + buf->size = max_size; + } else if (mhop_num == HNS_ROCE_HOP_NUM_0) { + max_size = eq->entries * eq->eqe_size; + buf->size = max_size; + } else { + max_size = 1 << page_shift; + buf->size = PAGE_ALIGN(eq->entries * eq->eqe_size); + is_mhop = true; + } -err_dma_alloc_l1: - dma_free_coherent(dev, bt_chk_sz, eq->bt_l0, eq->l0_dma); - eq->bt_l0 = NULL; - eq->l0_dma = 0; - for (i -= 1; i >= 0; i--) { - dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i], - eq->l1_dma[i]); - - for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) { - idx = i * bt_chk_sz / BA_BYTE_LEN + j; - dma_free_coherent(dev, buf_chk_sz, eq->buf[idx], - eq->buf_dma[idx]); - } - } - goto err_dma_alloc_l0; - -err_dma_alloc_buf: - dma_free_coherent(dev, bt_chk_sz, eq->bt_l0, eq->l0_dma); - eq->bt_l0 = NULL; - eq->l0_dma = 0; - - if (mhop_num == 1) - for (i -= 1; i >= 0; i--) - dma_free_coherent(dev, buf_chk_sz, eq->buf[i], - eq->buf_dma[i]); - else if (mhop_num == 2) { - record_i = i; - record_j = j; - for (; i >= 0; i--) { - dma_free_coherent(dev, bt_chk_sz, eq->bt_l1[i], - eq->l1_dma[i]); - - for (j = 0; j < bt_chk_sz / BA_BYTE_LEN; j++) { - if (i == record_i && j >= record_j) - break; - - idx = i * bt_chk_sz / BA_BYTE_LEN + j; - dma_free_coherent(dev, buf_chk_sz, - eq->buf[idx], - eq->buf_dma[idx]); - } - } + ret = hns_roce_buf_alloc(hr_dev, buf->size, max_size, buf, page_shift); + if (ret) { + dev_err(hr_dev->dev, "alloc eq buf error\n"); + return ret; } -err_dma_alloc_l0: - kfree(eq->bt_l1); - eq->bt_l1 = NULL; - -err_kcalloc_bt_l1: - kfree(eq->l1_dma); - eq->l1_dma = NULL; - -err_kcalloc_l1_dma: - kfree(eq->buf); - eq->buf = NULL; - -err_kcalloc_buf: - kfree(eq->buf_dma); - eq->buf_dma = NULL; + if (is_mhop) { + ret = map_eq_buf(hr_dev, eq, page_shift); + if (ret) { + dev_err(hr_dev->dev, "map roce buf error\n"); + goto err_alloc; + } + } - return -ENOMEM; + return 0; +err_alloc: + hns_roce_buf_free(hr_dev, buf->size, buf); + return ret; } static int hns_roce_v2_create_eq(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq, unsigned int eq_cmd) { - struct device *dev = hr_dev->dev; struct hns_roce_cmd_mailbox *mailbox; - u32 buf_chk_sz = 0; int ret; /* Allocate mailbox memory */ @@ -5764,38 +5768,17 @@ if (IS_ERR(mailbox)) return PTR_ERR(mailbox); - if (!hr_dev->caps.eqe_hop_num) { - buf_chk_sz = 1 << (hr_dev->caps.eqe_buf_pg_sz + PAGE_SHIFT); - - eq->buf_list = kzalloc(sizeof(struct hns_roce_buf_list), - GFP_KERNEL); - if (!eq->buf_list) { - ret = -ENOMEM; - goto free_cmd_mbox; - } - - eq->buf_list->buf = dma_alloc_coherent(dev, buf_chk_sz, - &(eq->buf_list->map), - GFP_KERNEL); - if (!eq->buf_list->buf) { - ret = -ENOMEM; - goto err_alloc_buf; - } - - } else { - ret = hns_roce_mhop_alloc_eq(hr_dev, eq); - if (ret) { - ret = -ENOMEM; - goto free_cmd_mbox; - } + ret = alloc_eq_buf(hr_dev, eq); + if (ret) { + ret = -ENOMEM; + goto free_cmd_mbox; } - hns_roce_config_eqc(hr_dev, eq, mailbox->buf); ret = hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, eq->eqn, 0, eq_cmd, HNS_ROCE_CMD_TIMEOUT_MSECS); if (ret) { - dev_err(dev, "[mailbox cmd] create eqc failed.\n"); + dev_err(hr_dev->dev, "[mailbox cmd] create eqc failed.\n"); goto err_cmd_mbox; } @@ -5804,16 +5787,7 @@ return 0; err_cmd_mbox: - if (!hr_dev->caps.eqe_hop_num) - dma_free_coherent(dev, buf_chk_sz, eq->buf_list->buf, - eq->buf_list->map); - else { - hns_roce_mhop_free_eq(hr_dev, eq); - goto free_cmd_mbox; - } - -err_alloc_buf: - kfree(eq->buf_list); + free_eq_buf(hr_dev, eq); free_cmd_mbox: hns_roce_free_cmd_mailbox(hr_dev, mailbox); @@ -5839,18 +5813,16 @@ /* irq contains: abnormal + AEQ + CEQ */ for (j = 0; j < other_num; j++) - snprintf((char *)hr_dev->irq_names[j], - HNS_ROCE_INT_NAME_LEN, "hns-abn-%d", j); + snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, + "hns-abn-%d", j); for (j = other_num; j < (other_num + aeq_num); j++) - snprintf((char *)hr_dev->irq_names[j], - HNS_ROCE_INT_NAME_LEN, "hns-aeq-%d", - j - other_num); + snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, + "hns-aeq-%d", j - other_num); for (j = (other_num + aeq_num); j < irq_num; j++) - snprintf((char *)hr_dev->irq_names[j], - HNS_ROCE_INT_NAME_LEN, "hns-ceq-%d", - j - other_num - aeq_num); + snprintf((char *)hr_dev->irq_names[j], HNS_ROCE_INT_NAME_LEN, + "hns-ceq-%d", j - other_num - aeq_num); for (j = 0; j < irq_num; j++) { if (j < other_num) @@ -5977,8 +5949,7 @@ goto err_request_irq_fail; } - hr_dev->irq_workq = - create_singlethread_workqueue("hns_roce_irq_workqueue"); + hr_dev->irq_workq = alloc_ordered_workqueue("hns_roce_irq_workq", 0); if (!hr_dev->irq_workq) { dev_err(dev, "Create irq workqueue failed!\n"); ret = -ENOMEM; @@ -5995,7 +5966,7 @@ err_create_eq_fail: for (i -= 1; i >= 0; i--) - hns_roce_v2_free_eq(hr_dev, &eq_table->eq[i]); + free_eq_buf(hr_dev, &eq_table->eq[i]); kfree(eq_table->eq); return ret; @@ -6017,7 +5988,7 @@ for (i = 0; i < eq_num; i++) { hns_roce_v2_destroy_eqc(hr_dev, i); - hns_roce_v2_free_eq(hr_dev, &eq_table->eq[i]); + free_eq_buf(hr_dev, &eq_table->eq[i]); } kfree(eq_table->eq); @@ -6047,7 +6018,7 @@ hr_dev->caps.srqwqe_hop_num)); roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQ_SHIFT_M, SRQC_BYTE_4_SRQ_SHIFT_S, - ilog2(srq->max)); + ilog2(srq->wqe_cnt)); roce_set_field(srq_context->byte_4_srqn_srqst, SRQC_BYTE_4_SRQN_M, SRQC_BYTE_4_SRQN_S, srq->srqn); @@ -6092,11 +6063,11 @@ roce_set_field(srq_context->byte_44_idxbufpgsz_addr, SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_M, SRQC_BYTE_44_SRQ_IDX_BA_PG_SZ_S, - hr_dev->caps.idx_ba_pg_sz); + hr_dev->caps.idx_ba_pg_sz + PG_SHIFT_OFFSET); roce_set_field(srq_context->byte_44_idxbufpgsz_addr, SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_M, SRQC_BYTE_44_SRQ_IDX_BUF_PG_SZ_S, - hr_dev->caps.idx_buf_pg_sz); + hr_dev->caps.idx_buf_pg_sz + PG_SHIFT_OFFSET); srq_context->idx_nxt_blk_addr = cpu_to_le32(mtts_idx[1] >> PAGE_ADDR_SHIFT); @@ -6133,7 +6104,7 @@ int ret; if (srq_attr_mask & IB_SRQ_LIMIT) { - if (srq_attr->srq_limit >= srq->max) + if (srq_attr->srq_limit >= srq->wqe_cnt) return -EINVAL; mailbox = hns_roce_alloc_cmd_mailbox(hr_dev); @@ -6193,7 +6164,7 @@ SRQC_BYTE_8_SRQ_LIMIT_WL_S); attr->srq_limit = limit_wl; - attr->max_wr = srq->max - 1; + attr->max_wr = srq->wqe_cnt - 1; attr->max_sge = srq->max_gs; memcpy(srq_context, mailbox->buf, sizeof(*srq_context)); @@ -6246,7 +6217,7 @@ spin_lock_irqsave(&srq->lock, flags); - ind = srq->head & (srq->max - 1); + ind = srq->head & (srq->wqe_cnt - 1); for (nreq = 0; wr; ++nreq, wr = wr->next) { if (unlikely(wr->num_sge > srq->max_gs)) { @@ -6261,7 +6232,7 @@ break; } - wqe_idx = find_empty_entry(&srq->idx_que, srq->max); + wqe_idx = find_empty_entry(&srq->idx_que, srq->wqe_cnt); if (wqe_idx < 0) { ret = -ENOMEM; *bad_wr = wr; @@ -6285,7 +6256,7 @@ } srq->wrid[wqe_idx] = wr->wr_id; - ind = (ind + 1) & (srq->max - 1); + ind = (ind + 1) & (srq->wqe_cnt - 1); } if (likely(nreq)) { @@ -6380,12 +6351,14 @@ MODULE_DEVICE_TABLE(pci, hns_roce_hw_v2_pci_tbl); -static int hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev, +static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev, struct hnae3_handle *handle) { struct hns_roce_v2_priv *priv = hr_dev->priv; int i; + hr_dev->pci_dev = handle->pdev; + hr_dev->dev = &handle->pdev->dev; hr_dev->hw = &hns_roce_hw_v2; hr_dev->dfx = &hns_roce_dfx_hw_v2; hr_dev->sdb_offset = ROCEE_DB_SQ_L_0_REG; @@ -6410,8 +6383,6 @@ hr_dev->reset_cnt = handle->ae_algo->ops->ae_dev_reset_cnt(handle); priv->handle = handle; - - return 0; } static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) @@ -6429,14 +6400,7 @@ goto error_failed_kzalloc; } - hr_dev->pci_dev = handle->pdev; - hr_dev->dev = &handle->pdev->dev; - - ret = hns_roce_hw_v2_get_cfg(hr_dev, handle); - if (ret) { - dev_err(hr_dev->dev, "Get Configuration failed!\n"); - goto error_failed_get_cfg; - } + hns_roce_hw_v2_get_cfg(hr_dev, handle); ret = hns_roce_init(hr_dev); if (ret) { @@ -6466,6 +6430,10 @@ return; handle->priv = NULL; + + hr_dev->state = HNS_ROCE_DEVICE_STATE_UNINIT; + hns_roce_handle_device_err(hr_dev); + hns_roce_exit(hr_dev); kfree(hr_dev->priv); ib_dealloc_device(&hr_dev->ib_dev); @@ -6527,7 +6495,6 @@ static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle) { struct hns_roce_dev *hr_dev; - struct ib_event event; if (handle->rinfo.instance_state != HNS_ROCE_STATE_INITED) { set_bit(HNS_ROCE_RST_DIRECT_RETURN, &handle->rinfo.state); @@ -6545,10 +6512,7 @@ hr_dev->active = false; hr_dev->dis_db = true; - event.event = IB_EVENT_DEVICE_FATAL; - event.device = &hr_dev->ib_dev; - event.element.port_num = 1; - ib_dispatch_event(&event); + hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN; return 0; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.h @@ -81,15 +81,17 @@ #define HNS_ROCE_V2_QPC_ENTRY_SZ 256 #define HNS_ROCE_V2_IRRL_ENTRY_SZ 64 #define HNS_ROCE_V2_TRRL_ENTRY_SZ 48 +#define HNS_ROCE_V2_EXT_ATOMIC_TRRL_ENTRY_SZ 100 #define HNS_ROCE_V2_CQC_ENTRY_SZ 64 #define HNS_ROCE_V2_SRQC_ENTRY_SZ 64 #define HNS_ROCE_V2_MTPT_ENTRY_SZ 64 #define HNS_ROCE_V2_MTT_ENTRY_SZ 64 +#define HNS_ROCE_V2_IDX_ENTRY_SZ 4 #define HNS_ROCE_V2_CQE_ENTRY_SIZE 32 #define HNS_ROCE_V2_SCCC_ENTRY_SZ 32 -#define HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ 4096 -#define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ 4096 -#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFFF000 +#define HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ PAGE_SIZE +#define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ PAGE_SIZE +#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED 0xFFFF000 #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM 2 #define HNS_ROCE_INVALID_LKEY 0x100 #define HNS_ROCE_CMQ_TX_TIMEOUT 30000 @@ -109,7 +111,12 @@ #define HNS_ROCE_PBL_HOP_NUM 2 #define HNS_ROCE_EQE_HOP_NUM 2 #define HNS_ROCE_IDX_HOP_NUM 1 +#define HNS_ROCE_SQWQE_HOP_NUM 2 +#define HNS_ROCE_EXT_SGE_HOP_NUM 1 +#define HNS_ROCE_RQWQE_HOP_NUM 2 +#define HNS_ROCE_BA_PG_SZ_SUPPORTED_256K 6 +#define HNS_ROCE_BA_PG_SZ_SUPPORTED_16K 2 #define HNS_ROCE_V2_GID_INDEX_NUM 256 #define HNS_ROCE_V2_TABLE_CHUNK_SIZE (1 << 18) @@ -237,6 +244,7 @@ HNS_ROCE_OPC_CFG_EXT_LLM = 0x8403, HNS_ROCE_OPC_CFG_TMOUT_LLM = 0x8404, HNS_ROCE_OPC_QUERY_PF_TIMER_RES = 0x8406, + HNS_ROCE_OPC_QUERY_PF_CAPS_NUM = 0x8408, HNS_ROCE_OPC_CFG_SGID_TB = 0x8500, HNS_ROCE_OPC_CFG_SMAC_TB = 0x8501, HNS_ROCE_OPC_POST_MB = 0x8504, @@ -643,7 +651,7 @@ #define V2_QPC_BYTE_76_ATE_S 27 #define V2_QPC_BYTE_76_RQIE_S 28 - +#define V2_QPC_BYTE_76_EXT_ATE_S 29 #define V2_QPC_BYTE_76_RQ_VLAN_EN_S 30 #define V2_QPC_BYTE_80_RX_CQN_S 0 #define V2_QPC_BYTE_80_RX_CQN_M GENMASK(23, 0) @@ -1569,6 +1577,155 @@ #define CFG_SMAC_TB_VF_SMAC_H_S 0 #define CFG_SMAC_TB_VF_SMAC_H_M GENMASK(15, 0) +#define HNS_ROCE_QUERY_PF_CAPS_CMD_NUM 5 +struct hns_roce_query_pf_caps_a { + u8 number_ports; + u8 local_ca_ack_delay; + __le16 max_sq_sg; + __le16 max_sq_inline; + __le16 max_rq_sg; + __le32 max_extend_sg; + __le16 num_qpc_timer; + __le16 num_cqc_timer; + __le16 max_srq_sges; + u8 num_aeq_vectors; + u8 num_other_vectors; + u8 max_sq_desc_sz; + u8 max_rq_desc_sz; + u8 max_srq_desc_sz; + u8 cq_entry_sz; +}; + +struct hns_roce_query_pf_caps_b { + u8 mtpt_entry_sz; + u8 irrl_entry_sz; + u8 trrl_entry_sz; + u8 cqc_entry_sz; + u8 srqc_entry_sz; + u8 idx_entry_sz; + u8 scc_ctx_entry_sz; + u8 max_mtu; + __le16 qpc_entry_sz; + __le16 qpc_timer_entry_sz; + __le16 cqc_timer_entry_sz; + u8 min_cqes; + u8 min_wqes; + __le32 page_size_cap; + u8 pkey_table_len; + u8 phy_num_uars; + u8 ctx_hop_num; + u8 pbl_hop_num; +}; + +struct hns_roce_query_pf_caps_c { + __le32 cap_flags_num_pds; + __le32 max_gid_num_cqs; + __le32 cq_depth; + __le32 num_mrws; + __le32 ord_num_qps; + __le16 sq_depth; + __le16 rq_depth; +}; + +#define V2_QUERY_PF_CAPS_C_NUM_PDS_S 0 +#define V2_QUERY_PF_CAPS_C_NUM_PDS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_C_CAP_FLAGS_S 20 +#define V2_QUERY_PF_CAPS_C_CAP_FLAGS_M GENMASK(31, 20) + +#define V2_QUERY_PF_CAPS_C_NUM_CQS_S 0 +#define V2_QUERY_PF_CAPS_C_NUM_CQS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_C_MAX_GID_S 20 +#define V2_QUERY_PF_CAPS_C_MAX_GID_M GENMASK(28, 20) + +#define V2_QUERY_PF_CAPS_C_CQ_DEPTH_S 0 +#define V2_QUERY_PF_CAPS_C_CQ_DEPTH_M GENMASK(22, 0) + +#define V2_QUERY_PF_CAPS_C_NUM_MRWS_S 0 +#define V2_QUERY_PF_CAPS_C_NUM_MRWS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_C_NUM_QPS_S 0 +#define V2_QUERY_PF_CAPS_C_NUM_QPS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_C_MAX_ORD_S 20 +#define V2_QUERY_PF_CAPS_C_MAX_ORD_M GENMASK(27, 20) + +struct hns_roce_query_pf_caps_d { + __le32 wq_hop_num_max_srqs; + __le16 srq_depth; + __le16 rsv; + __le32 num_ceqs_ceq_depth; + __le32 arm_st_aeq_depth; + __le32 num_uars_rsv_pds; + __le32 rsv_uars_rsv_qps; +}; +#define V2_QUERY_PF_CAPS_D_NUM_SRQS_S 0 +#define V2_QUERY_PF_CAPS_D_NUM_SRQS_M GENMASK(20, 0) + +#define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_S 20 +#define V2_QUERY_PF_CAPS_D_RQWQE_HOP_NUM_M GENMASK(21, 20) + +#define V2_QUERY_PF_CAPS_D_EX_SGE_HOP_NUM_S 22 +#define V2_QUERY_PF_CAPS_D_EX_SGE_HOP_NUM_M GENMASK(23, 22) + +#define V2_QUERY_PF_CAPS_D_SQWQE_HOP_NUM_S 24 +#define V2_QUERY_PF_CAPS_D_SQWQE_HOP_NUM_M GENMASK(25, 24) + + +#define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_S 0 +#define V2_QUERY_PF_CAPS_D_CEQ_DEPTH_M GENMASK(21, 0) + +#define V2_QUERY_PF_CAPS_D_NUM_CEQS_S 22 +#define V2_QUERY_PF_CAPS_D_NUM_CEQS_M GENMASK(31, 22) + +#define V2_QUERY_PF_CAPS_D_AEQ_DEPTH_S 0 +#define V2_QUERY_PF_CAPS_D_AEQ_DEPTH_M GENMASK(21, 0) + +#define V2_QUERY_PF_CAPS_D_AEQ_ARM_ST_S 22 +#define V2_QUERY_PF_CAPS_D_AEQ_ARM_ST_M GENMASK(23, 22) + +#define V2_QUERY_PF_CAPS_D_CEQ_ARM_ST_S 24 +#define V2_QUERY_PF_CAPS_D_CEQ_ARM_ST_M GENMASK(25, 24) + +#define V2_QUERY_PF_CAPS_D_RSV_PDS_S 0 +#define V2_QUERY_PF_CAPS_D_RSV_PDS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_D_NUM_UARS_S 20 +#define V2_QUERY_PF_CAPS_D_NUM_UARS_M GENMASK(27, 20) + +#define V2_QUERY_PF_CAPS_D_RSV_QPS_S 0 +#define V2_QUERY_PF_CAPS_D_RSV_QPS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_D_RSV_UARS_S 20 +#define V2_QUERY_PF_CAPS_D_RSV_UARS_M GENMASK(27, 20) + +struct hns_roce_query_pf_caps_e { + __le32 chunk_size_shift_rsv_mrws; + __le32 rsv_cqs; + __le32 rsv_srqs; + __le32 rsv_lkey; + __le16 ceq_max_cnt; + __le16 ceq_period; + __le16 aeq_max_cnt; + __le16 aeq_period; +}; + +#define V2_QUERY_PF_CAPS_E_RSV_MRWS_S 0 +#define V2_QUERY_PF_CAPS_E_RSV_MRWS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_E_CHUNK_SIZE_SHIFT_S 20 +#define V2_QUERY_PF_CAPS_E_CHUNK_SIZE_SHIFT_M GENMASK(31, 20) + +#define V2_QUERY_PF_CAPS_E_RSV_CQS_S 0 +#define V2_QUERY_PF_CAPS_E_RSV_CQS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_E_RSV_SRQS_S 0 +#define V2_QUERY_PF_CAPS_E_RSV_SRQS_M GENMASK(19, 0) + +#define V2_QUERY_PF_CAPS_E_RSV_LKEYS_S 0 +#define V2_QUERY_PF_CAPS_E_RSV_LKEYS_M GENMASK(19, 0) + struct hns_roce_cmq_desc { __le16 opcode; __le16 flag; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_main.c @@ -90,7 +90,7 @@ static int hns_roce_del_gid(const struct ib_gid_attr *attr, void **context) { struct hns_roce_dev *hr_dev = to_hr_dev(attr->device); - struct ib_gid_attr zattr = { }; + struct ib_gid_attr zattr = {}; u8 port = attr->port_num - 1; int ret; @@ -111,7 +111,7 @@ netdev = hr_dev->iboe.netdevs[port]; if (!netdev) { - dev_err(dev, "port(%d) can't find netdev\n", port); + dev_err(dev, "Can't find netdev on port(%u)!\n", port); return -ENODEV; } @@ -210,7 +210,7 @@ props->max_pkeys = 1; props->local_ca_ack_delay = hr_dev->caps.local_ca_ack_delay; if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) { - props->max_srq = hr_dev->caps.max_srqs; + props->max_srq = hr_dev->caps.num_srqs; props->max_srq_wr = hr_dev->caps.max_srq_wrs; props->max_srq_sge = hr_dev->caps.max_srq_sges; } @@ -253,17 +253,18 @@ net_dev = hr_dev->iboe.netdevs[port]; if (!net_dev) { spin_unlock_irqrestore(&hr_dev->iboe.lock, flags); - dev_err(dev, "find netdev %d failed!\r\n", port); + dev_err(dev, "Find netdev %u failed!\n", port); return -EINVAL; } mtu = iboe_get_mtu(net_dev->mtu); props->active_mtu = mtu ? min(props->max_mtu, mtu) : IB_MTU_256; - props->state = (netif_running(net_dev) && netif_carrier_ok(net_dev)) ? - IB_PORT_ACTIVE : IB_PORT_DOWN; - props->phys_state = (props->state == IB_PORT_ACTIVE) ? - IB_PORT_PHYS_STATE_LINK_UP : - IB_PORT_PHYS_STATE_DISABLED; + props->state = netif_running(net_dev) && netif_carrier_ok(net_dev) ? + IB_PORT_ACTIVE : + IB_PORT_DOWN; + props->phys_state = props->state == IB_PORT_ACTIVE ? + IB_PORT_PHYS_STATE_LINK_UP : + IB_PORT_PHYS_STATE_DISABLED; spin_unlock_irqrestore(&hr_dev->iboe.lock, flags); @@ -279,6 +280,9 @@ static int hns_roce_query_pkey(struct ib_device *ib_dev, u8 port, u16 index, u16 *pkey) { + if (index > 0) + return -EINVAL; + *pkey = PKEY_ID; return 0; @@ -301,12 +305,6 @@ return 0; } -static int hns_roce_modify_port(struct ib_device *ib_dev, u8 port_num, int mask, - struct ib_port_modify *props) -{ - return 0; -} - static int hns_roce_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) { @@ -359,7 +357,8 @@ return rdma_user_mmap_io(context, vma, to_hr_ucontext(context)->uar.pfn, PAGE_SIZE, - pgprot_noncached(vma->vm_page_prot)); + pgprot_device(vma->vm_page_prot), + NULL); /* vm_pgoff: 1 -- TPTR */ case 1: @@ -372,7 +371,8 @@ return rdma_user_mmap_io(context, vma, hr_dev->tptr_dma_addr >> PAGE_SHIFT, hr_dev->tptr_size, - vma->vm_page_prot); + vma->vm_page_prot, + NULL); default: return -EINVAL; @@ -423,14 +423,14 @@ .alloc_pd = hns_roce_alloc_pd, .alloc_ucontext = hns_roce_alloc_ucontext, .create_ah = hns_roce_create_ah, - .create_cq = hns_roce_ib_create_cq, + .create_cq = hns_roce_create_cq, .create_qp = hns_roce_create_qp, .dealloc_pd = hns_roce_dealloc_pd, .dealloc_ucontext = hns_roce_dealloc_ucontext, .del_gid = hns_roce_del_gid, .dereg_mr = hns_roce_dereg_mr, .destroy_ah = hns_roce_destroy_ah, - .destroy_cq = hns_roce_ib_destroy_cq, + .destroy_cq = hns_roce_destroy_cq, .disassociate_ucontext = hns_roce_disassociate_ucontext, .fill_res_entry = hns_roce_fill_res_entry, .get_dma_mr = hns_roce_get_dma_mr, @@ -438,7 +438,6 @@ .get_port_immutable = hns_roce_port_immutable, .mmap = hns_roce_mmap, .modify_device = hns_roce_modify_device, - .modify_port = hns_roce_modify_port, .modify_qp = hns_roce_modify_qp, .query_ah = hns_roce_query_ah, .query_device = hns_roce_query_device, @@ -486,13 +485,13 @@ ib_dev = &hr_dev->ib_dev; - ib_dev->node_type = RDMA_NODE_IB_CA; - ib_dev->dev.parent = dev; + ib_dev->node_type = RDMA_NODE_IB_CA; + ib_dev->dev.parent = dev; - ib_dev->phys_port_cnt = hr_dev->caps.num_ports; - ib_dev->local_dma_lkey = hr_dev->caps.reserved_lkey; - ib_dev->num_comp_vectors = hr_dev->caps.num_comp_vectors; - ib_dev->uverbs_cmd_mask = + ib_dev->phys_port_cnt = hr_dev->caps.num_ports; + ib_dev->local_dma_lkey = hr_dev->caps.reserved_lkey; + ib_dev->num_comp_vectors = hr_dev->caps.num_comp_vectors; + ib_dev->uverbs_cmd_mask = (1ULL << IB_USER_VERBS_CMD_GET_CONTEXT) | (1ULL << IB_USER_VERBS_CMD_QUERY_DEVICE) | (1ULL << IB_USER_VERBS_CMD_QUERY_PORT) | @@ -508,8 +507,7 @@ (1ULL << IB_USER_VERBS_CMD_QUERY_QP) | (1ULL << IB_USER_VERBS_CMD_DESTROY_QP); - ib_dev->uverbs_ex_cmd_mask |= - (1ULL << IB_USER_VERBS_EX_CMD_MODIFY_CQ); + ib_dev->uverbs_ex_cmd_mask |= (1ULL << IB_USER_VERBS_EX_CMD_MODIFY_CQ); if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_REREG_MR) { ib_dev->uverbs_cmd_mask |= (1ULL << IB_USER_VERBS_CMD_REREG_MR); @@ -594,11 +592,13 @@ if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE)) { ret = hns_roce_init_hem_table(hr_dev, - &hr_dev->mr_table.mtt_cqe_table, - HEM_TYPE_CQE, hr_dev->caps.mtt_entry_sz, - hr_dev->caps.num_cqe_segs, 1); + &hr_dev->mr_table.mtt_cqe_table, + HEM_TYPE_CQE, + hr_dev->caps.mtt_entry_sz, + hr_dev->caps.num_cqe_segs, 1); if (ret) { - dev_err(dev, "Failed to init MTT CQE context memory, aborting.\n"); + dev_err(dev, + "Failed to init CQE context memory, aborting.\n"); goto err_unmap_cqe; } } @@ -638,7 +638,7 @@ hr_dev->caps.num_qps, 1); if (ret) { dev_err(dev, - "Failed to init trrl_table memory, aborting.\n"); + "Failed to init trrl_table memory, aborting.\n"); goto err_unmap_irrl; } } @@ -658,7 +658,7 @@ hr_dev->caps.num_srqs, 1); if (ret) { dev_err(dev, - "Failed to init SRQ context memory, aborting.\n"); + "Failed to init SRQ context memory, aborting.\n"); goto err_unmap_cq; } } @@ -697,33 +697,31 @@ hr_dev->caps.num_qps, 1); if (ret) { dev_err(dev, - "Failed to init SCC context memory, aborting.\n"); + "Failed to init SCC context memory, aborting.\n"); goto err_unmap_idx; } } if (hr_dev->caps.qpc_timer_entry_sz) { - ret = hns_roce_init_hem_table(hr_dev, - &hr_dev->qpc_timer_table, + ret = hns_roce_init_hem_table(hr_dev, &hr_dev->qpc_timer_table, HEM_TYPE_QPC_TIMER, hr_dev->caps.qpc_timer_entry_sz, hr_dev->caps.num_qpc_timer, 1); if (ret) { dev_err(dev, - "Failed to init QPC timer memory, aborting.\n"); + "Failed to init QPC timer memory, aborting.\n"); goto err_unmap_ctx; } } if (hr_dev->caps.cqc_timer_entry_sz) { - ret = hns_roce_init_hem_table(hr_dev, - &hr_dev->cqc_timer_table, + ret = hns_roce_init_hem_table(hr_dev, &hr_dev->cqc_timer_table, HEM_TYPE_CQC_TIMER, hr_dev->caps.cqc_timer_entry_sz, hr_dev->caps.num_cqc_timer, 1); if (ret) { dev_err(dev, - "Failed to init CQC timer memory, aborting.\n"); + "Failed to init CQC timer memory, aborting.\n"); goto err_unmap_qpc_timer; } } @@ -732,8 +730,7 @@ err_unmap_qpc_timer: if (hr_dev->caps.qpc_timer_entry_sz) - hns_roce_cleanup_hem_table(hr_dev, - &hr_dev->qpc_timer_table); + hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qpc_timer_table); err_unmap_ctx: if (hr_dev->caps.sccc_entry_sz) @@ -848,8 +845,7 @@ return 0; err_qp_table_free: - if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) - hns_roce_cleanup_qp_table(hr_dev); + hns_roce_cleanup_qp_table(hr_dev); err_cq_table_free: hns_roce_cleanup_cq_table(hr_dev); @@ -868,6 +864,50 @@ return ret; } +static void check_and_get_armed_cq(struct list_head *cq_list, struct ib_cq *cq) +{ + struct hns_roce_cq *hr_cq = to_hr_cq(cq); + unsigned long flags; + + spin_lock_irqsave(&hr_cq->lock, flags); + if (cq->comp_handler) { + if (!hr_cq->is_armed) { + hr_cq->is_armed = 1; + list_add_tail(&hr_cq->node, cq_list); + } + } + spin_unlock_irqrestore(&hr_cq->lock, flags); +} + +void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev) +{ + struct hns_roce_qp *hr_qp; + struct hns_roce_cq *hr_cq; + struct list_head cq_list; + unsigned long flags_qp; + unsigned long flags; + + INIT_LIST_HEAD(&cq_list); + + spin_lock_irqsave(&hr_dev->qp_list_lock, flags); + list_for_each_entry(hr_qp, &hr_dev->qp_list, node) { + spin_lock_irqsave(&hr_qp->sq.lock, flags_qp); + if (hr_qp->sq.tail != hr_qp->sq.head) + check_and_get_armed_cq(&cq_list, hr_qp->ibqp.send_cq); + spin_unlock_irqrestore(&hr_qp->sq.lock, flags_qp); + + spin_lock_irqsave(&hr_qp->rq.lock, flags_qp); + if ((!hr_qp->ibqp.srq) && (hr_qp->rq.tail != hr_qp->rq.head)) + check_and_get_armed_cq(&cq_list, hr_qp->ibqp.recv_cq); + spin_unlock_irqrestore(&hr_qp->rq.lock, flags_qp); + } + + list_for_each_entry(hr_cq, &cq_list, node) + hns_roce_cq_completion(hr_dev, hr_cq->cqn); + + spin_unlock_irqrestore(&hr_dev->qp_list_lock, flags); +} + int hns_roce_init(struct hns_roce_dev *hr_dev) { int ret; @@ -938,6 +978,9 @@ } } + INIT_LIST_HEAD(&hr_dev->qp_list); + spin_lock_init(&hr_dev->qp_list_lock); + ret = hns_roce_register_device(hr_dev); if (ret) goto error_failed_register_device; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_mr.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -48,21 +48,21 @@ return (key << 24) | (key >> 8); } -static int hns_roce_sw2hw_mpt(struct hns_roce_dev *hr_dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long mpt_index) +static int hns_roce_hw_create_mpt(struct hns_roce_dev *hr_dev, + struct hns_roce_cmd_mailbox *mailbox, + unsigned long mpt_index) { return hns_roce_cmd_mbox(hr_dev, mailbox->dma, 0, mpt_index, 0, - HNS_ROCE_CMD_SW2HW_MPT, + HNS_ROCE_CMD_CREATE_MPT, HNS_ROCE_CMD_TIMEOUT_MSECS); } -int hns_roce_hw2sw_mpt(struct hns_roce_dev *hr_dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long mpt_index) +int hns_roce_hw_destroy_mpt(struct hns_roce_dev *hr_dev, + struct hns_roce_cmd_mailbox *mailbox, + unsigned long mpt_index) { return hns_roce_cmd_mbox(hr_dev, 0, mailbox ? mailbox->dma : 0, - mpt_index, !mailbox, HNS_ROCE_CMD_HW2SW_MPT, + mpt_index, !mailbox, HNS_ROCE_CMD_DESTROY_MPT, HNS_ROCE_CMD_TIMEOUT_MSECS); } @@ -83,7 +83,7 @@ } } spin_unlock(&buddy->lock); - return -1; + return -EINVAL; found: clear_bit(*seg, buddy->bits[o]); @@ -206,13 +206,14 @@ } ret = hns_roce_buddy_alloc(buddy, order, seg); - if (ret == -1) - return -1; + if (ret) + return ret; - if (hns_roce_table_get_range(hr_dev, table, *seg, - *seg + (1 << order) - 1)) { + ret = hns_roce_table_get_range(hr_dev, table, *seg, + *seg + (1 << order) - 1); + if (ret) { hns_roce_buddy_free(buddy, *seg, order); - return -1; + return ret; } return 0; @@ -578,7 +579,7 @@ /* Allocate a key for mr from mr_table */ ret = hns_roce_bitmap_alloc(&hr_dev->mr_table.mtpt_bitmap, &index); - if (ret == -1) + if (ret) return -ENOMEM; mr->iova = iova; /* MR va starting addr */ @@ -707,10 +708,11 @@ int ret; if (mr->enabled) { - ret = hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mr->key) - & (hr_dev->caps.num_mtpts - 1)); + ret = hns_roce_hw_destroy_mpt(hr_dev, NULL, + key_to_hw_index(mr->key) & + (hr_dev->caps.num_mtpts - 1)); if (ret) - dev_warn(dev, "HW2SW_MPT failed (%d)\n", ret); + dev_warn(dev, "DESTROY_MPT failed (%d)\n", ret); } if (mr->size != ~0ULL) { @@ -763,10 +765,10 @@ goto err_page; } - ret = hns_roce_sw2hw_mpt(hr_dev, mailbox, - mtpt_idx & (hr_dev->caps.num_mtpts - 1)); + ret = hns_roce_hw_create_mpt(hr_dev, mailbox, + mtpt_idx & (hr_dev->caps.num_mtpts - 1)); if (ret) { - dev_err(dev, "SW2HW_MPT failed (%d)\n", ret); + dev_err(dev, "CREATE_MPT failed (%d)\n", ret); goto err_page; } @@ -1062,8 +1064,8 @@ if (!(npage % (1 << (mtt->page_shift - PAGE_SHIFT)))) { if (page_addr & ((1 << mtt->page_shift) - 1)) { dev_err(dev, - "page_addr 0x%llx is not page_shift %d alignment!\n", - page_addr, mtt->page_shift); + "page_addr is not page_shift %d alignment!\n", + mtt->page_shift); ret = -EINVAL; goto out; } @@ -1143,7 +1145,7 @@ if (!mr) return ERR_PTR(-ENOMEM); - mr->umem = ib_umem_get(udata, start, length, access_flags, 0); + mr->umem = ib_umem_get(pd->device, start, length, access_flags); if (IS_ERR(mr->umem)) { ret = PTR_ERR(mr->umem); goto err_free; @@ -1228,7 +1230,7 @@ } ib_umem_release(mr->umem); - mr->umem = ib_umem_get(udata, start, length, mr_access_flags, 0); + mr->umem = ib_umem_get(ibmr->device, start, length, mr_access_flags); if (IS_ERR(mr->umem)) { ret = PTR_ERR(mr->umem); mr->umem = NULL; @@ -1308,9 +1310,9 @@ if (ret) goto free_cmd_mbox; - ret = hns_roce_hw2sw_mpt(hr_dev, NULL, mtpt_idx); + ret = hns_roce_hw_destroy_mpt(hr_dev, NULL, mtpt_idx); if (ret) - dev_warn(dev, "HW2SW_MPT failed (%d)\n", ret); + dev_warn(dev, "DESTROY_MPT failed (%d)\n", ret); mr->enabled = 0; @@ -1332,9 +1334,9 @@ goto free_cmd_mbox; } - ret = hns_roce_sw2hw_mpt(hr_dev, mailbox, mtpt_idx); + ret = hns_roce_hw_create_mpt(hr_dev, mailbox, mtpt_idx); if (ret) { - dev_err(dev, "SW2HW_MPT failed (%d)\n", ret); + dev_err(dev, "CREATE_MPT failed (%d)\n", ret); ib_umem_release(mr->umem); goto free_cmd_mbox; } @@ -1448,10 +1450,11 @@ int ret; if (mw->enabled) { - ret = hns_roce_hw2sw_mpt(hr_dev, NULL, key_to_hw_index(mw->rkey) - & (hr_dev->caps.num_mtpts - 1)); + ret = hns_roce_hw_destroy_mpt(hr_dev, NULL, + key_to_hw_index(mw->rkey) & + (hr_dev->caps.num_mtpts - 1)); if (ret) - dev_warn(dev, "MW HW2SW_MPT failed (%d)\n", ret); + dev_warn(dev, "MW DESTROY_MPT failed (%d)\n", ret); hns_roce_table_put(hr_dev, &hr_dev->mr_table.mtpt_table, key_to_hw_index(mw->rkey)); @@ -1487,10 +1490,10 @@ goto err_page; } - ret = hns_roce_sw2hw_mpt(hr_dev, mailbox, - mtpt_idx & (hr_dev->caps.num_mtpts - 1)); + ret = hns_roce_hw_create_mpt(hr_dev, mailbox, + mtpt_idx & (hr_dev->caps.num_mtpts - 1)); if (ret) { - dev_err(dev, "MW sw2hw_mpt failed (%d)\n", ret); + dev_err(dev, "MW CREATE_MPT failed (%d)\n", ret); goto err_page; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_pd.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -96,7 +96,7 @@ /* Using bitmap to manager UAR index */ ret = hns_roce_bitmap_alloc(&hr_dev->uar_table.bitmap, &uar->logic_idx); - if (ret == -1) + if (ret) return -ENOMEM; if (uar->logic_idx > 0 && hr_dev->caps.phy_num_uars > 1) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -43,6 +43,45 @@ #define SQP_NUM (2 * HNS_ROCE_MAX_PORTS) +static void flush_work_handle(struct work_struct *work) +{ + struct hns_roce_work *flush_work = container_of(work, + struct hns_roce_work, work); + struct hns_roce_qp *hr_qp = container_of(flush_work, + struct hns_roce_qp, flush_work); + struct device *dev = flush_work->hr_dev->dev; + struct ib_qp_attr attr; + int attr_mask; + int ret; + + attr_mask = IB_QP_STATE; + attr.qp_state = IB_QPS_ERR; + + if (test_and_clear_bit(HNS_ROCE_FLUSH_FLAG, &hr_qp->flush_flag)) { + ret = hns_roce_modify_qp(&hr_qp->ibqp, &attr, attr_mask, NULL); + if (ret) + dev_err(dev, "Modify QP to error state failed(%d) during CQE flush\n", + ret); + } + + /* + * make sure we signal QP destroy leg that flush QP was completed + * so that it can safely proceed ahead now and destroy QP + */ + if (atomic_dec_and_test(&hr_qp->refcount)) + complete(&hr_qp->free); +} + +void init_flush_work(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) +{ + struct hns_roce_work *flush_work = &hr_qp->flush_work; + + flush_work->hr_dev = hr_dev; + INIT_WORK(&flush_work->work, flush_work_handle); + atomic_inc(&hr_qp->refcount); + queue_work(hr_dev->irq_workq, &flush_work->work); +} + void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type) { struct device *dev = hr_dev->dev; @@ -59,6 +98,15 @@ return; } + if (hr_dev->hw_rev != HNS_ROCE_HW_VER1 && + (event_type == HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR || + event_type == HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR || + event_type == HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR)) { + qp->state = IB_QPS_ERR; + if (!test_and_set_bit(HNS_ROCE_FLUSH_FLAG, &qp->flush_flag)) + init_flush_work(hr_dev, qp); + } + qp->event(qp, (enum hns_roce_event)event_type); if (atomic_dec_and_test(&qp->refcount)) @@ -108,15 +156,34 @@ } } -static int hns_roce_reserve_range_qp(struct hns_roce_dev *hr_dev, int cnt, - int align, unsigned long *base) +static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) { - struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; + unsigned long num = 0; + int ret; - return hns_roce_bitmap_alloc_range(&qp_table->bitmap, cnt, align, - base) ? - -ENOMEM : - 0; + if (hr_qp->ibqp.qp_type == IB_QPT_GSI) { + /* when hw version is v1, the sqpn is allocated */ + if (hr_dev->hw_rev == HNS_ROCE_HW_VER1) + num = HNS_ROCE_MAX_PORTS + + hr_dev->iboe.phy_port[hr_qp->port]; + else + num = 1; + + hr_qp->doorbell_qpn = 1; + } else { + ret = hns_roce_bitmap_alloc_range(&hr_dev->qp_table.bitmap, + 1, 1, &num); + if (ret) { + ibdev_err(&hr_dev->ib_dev, "Failed to alloc bitmap\n"); + return -ENOMEM; + } + + hr_qp->doorbell_qpn = (u32)num; + } + + hr_qp->qpn = num; + + return 0; } enum hns_roce_qp_state to_hns_roce_state(enum ib_qp_state state) @@ -139,50 +206,75 @@ } } -static int hns_roce_gsi_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn, - struct hns_roce_qp *hr_qp) +static void add_qp_to_list(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp, + struct ib_cq *send_cq, struct ib_cq *recv_cq) +{ + struct hns_roce_cq *hr_send_cq, *hr_recv_cq; + unsigned long flags; + + hr_send_cq = send_cq ? to_hr_cq(send_cq) : NULL; + hr_recv_cq = recv_cq ? to_hr_cq(recv_cq) : NULL; + + spin_lock_irqsave(&hr_dev->qp_list_lock, flags); + hns_roce_lock_cqs(hr_send_cq, hr_recv_cq); + + list_add_tail(&hr_qp->node, &hr_dev->qp_list); + if (hr_send_cq) + list_add_tail(&hr_qp->sq_node, &hr_send_cq->sq_list); + if (hr_recv_cq) + list_add_tail(&hr_qp->rq_node, &hr_recv_cq->rq_list); + + hns_roce_unlock_cqs(hr_send_cq, hr_recv_cq); + spin_unlock_irqrestore(&hr_dev->qp_list_lock, flags); +} + +static int hns_roce_qp_store(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp, + struct ib_qp_init_attr *init_attr) { struct xarray *xa = &hr_dev->qp_table_xa; int ret; - if (!qpn) + if (!hr_qp->qpn) return -EINVAL; - hr_qp->qpn = qpn; - atomic_set(&hr_qp->refcount, 1); - init_completion(&hr_qp->free); - - ret = xa_err(xa_store_irq(xa, hr_qp->qpn & (hr_dev->caps.num_qps - 1), - hr_qp, GFP_KERNEL)); + ret = xa_err(xa_store_irq(xa, hr_qp->qpn, hr_qp, GFP_KERNEL)); if (ret) - dev_err(hr_dev->dev, "QPC xa_store failed\n"); + dev_err(hr_dev->dev, "Failed to xa store for QPC\n"); + else + /* add QP to device's QP list for softwc */ + add_qp_to_list(hr_dev, hr_qp, init_attr->send_cq, + init_attr->recv_cq); return ret; } -static int hns_roce_qp_alloc(struct hns_roce_dev *hr_dev, unsigned long qpn, - struct hns_roce_qp *hr_qp) +static int alloc_qpc(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; struct device *dev = hr_dev->dev; int ret; - if (!qpn) + if (!hr_qp->qpn) return -EINVAL; - hr_qp->qpn = qpn; + /* In v1 engine, GSI QP context is saved in the RoCE hw's register */ + if (hr_qp->ibqp.qp_type == IB_QPT_GSI && + hr_dev->hw_rev == HNS_ROCE_HW_VER1) + return 0; /* Alloc memory for QPC */ ret = hns_roce_table_get(hr_dev, &qp_table->qp_table, hr_qp->qpn); if (ret) { - dev_err(dev, "QPC table get failed\n"); + dev_err(dev, "Failed to get QPC table\n"); goto err_out; } /* Alloc memory for IRRL */ ret = hns_roce_table_get(hr_dev, &qp_table->irrl_table, hr_qp->qpn); if (ret) { - dev_err(dev, "IRRL table get failed\n"); + dev_err(dev, "Failed to get IRRL table\n"); goto err_put_qp; } @@ -191,7 +283,7 @@ ret = hns_roce_table_get(hr_dev, &qp_table->trrl_table, hr_qp->qpn); if (ret) { - dev_err(dev, "TRRL table get failed\n"); + dev_err(dev, "Failed to get TRRL table\n"); goto err_put_irrl; } } @@ -201,22 +293,13 @@ ret = hns_roce_table_get(hr_dev, &qp_table->sccc_table, hr_qp->qpn); if (ret) { - dev_err(dev, "SCC CTX table get failed\n"); + dev_err(dev, "Failed to get SCC CTX table\n"); goto err_put_trrl; } } - ret = hns_roce_gsi_qp_alloc(hr_dev, qpn, hr_qp); - if (ret) - goto err_put_sccc; - return 0; -err_put_sccc: - if (hr_dev->caps.sccc_entry_sz) - hns_roce_table_put(hr_dev, &qp_table->sccc_table, - hr_qp->qpn); - err_put_trrl: if (hr_dev->caps.trrl_entry_sz) hns_roce_table_put(hr_dev, &qp_table->trrl_table, hr_qp->qpn); @@ -236,89 +319,85 @@ struct xarray *xa = &hr_dev->qp_table_xa; unsigned long flags; + list_del(&hr_qp->node); + list_del(&hr_qp->sq_node); + list_del(&hr_qp->rq_node); + xa_lock_irqsave(xa, flags); __xa_erase(xa, hr_qp->qpn & (hr_dev->caps.num_qps - 1)); xa_unlock_irqrestore(xa, flags); } -void hns_roce_qp_free(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) +static void free_qpc(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - if (atomic_dec_and_test(&hr_qp->refcount)) - complete(&hr_qp->free); - wait_for_completion(&hr_qp->free); + /* In v1 engine, GSI QP context is saved in the RoCE hw's register */ + if (hr_qp->ibqp.qp_type == IB_QPT_GSI && + hr_dev->hw_rev == HNS_ROCE_HW_VER1) + return; - if ((hr_qp->ibqp.qp_type) != IB_QPT_GSI) { - if (hr_dev->caps.trrl_entry_sz) - hns_roce_table_put(hr_dev, &qp_table->trrl_table, - hr_qp->qpn); - hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn); - } + if (hr_dev->caps.trrl_entry_sz) + hns_roce_table_put(hr_dev, &qp_table->trrl_table, hr_qp->qpn); + hns_roce_table_put(hr_dev, &qp_table->irrl_table, hr_qp->qpn); } -void hns_roce_release_range_qp(struct hns_roce_dev *hr_dev, int base_qpn, - int cnt) +static void free_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; - if (base_qpn < hr_dev->caps.reserved_qps) + if (hr_qp->ibqp.qp_type == IB_QPT_GSI) return; - hns_roce_bitmap_free_range(&qp_table->bitmap, base_qpn, cnt, BITMAP_RR); + if (hr_qp->qpn < hr_dev->caps.reserved_qps) + return; + + hns_roce_bitmap_free_range(&qp_table->bitmap, hr_qp->qpn, 1, BITMAP_RR); } -static int hns_roce_set_rq_size(struct hns_roce_dev *hr_dev, +static int set_rq_size(struct hns_roce_dev *hr_dev, struct ib_qp_cap *cap, bool is_user, int has_rq, struct hns_roce_qp *hr_qp) { - struct device *dev = hr_dev->dev; u32 max_cnt; - /* Check the validity of QP support capacity */ - if (cap->max_recv_wr > hr_dev->caps.max_wqes || - cap->max_recv_sge > hr_dev->caps.max_rq_sg) { - dev_err(dev, "RQ WR or sge error!max_recv_wr=%d max_recv_sge=%d\n", - cap->max_recv_wr, cap->max_recv_sge); - return -EINVAL; - } - /* If srq exist, set zero for relative number of rq */ if (!has_rq) { hr_qp->rq.wqe_cnt = 0; hr_qp->rq.max_gs = 0; cap->max_recv_wr = 0; cap->max_recv_sge = 0; - } else { - if (is_user && (!cap->max_recv_wr || !cap->max_recv_sge)) { - dev_err(dev, "user space no need config max_recv_wr max_recv_sge\n"); - return -EINVAL; - } - if (hr_dev->caps.min_wqes) - max_cnt = max(cap->max_recv_wr, hr_dev->caps.min_wqes); - else - max_cnt = cap->max_recv_wr; + return 0; + } - hr_qp->rq.wqe_cnt = roundup_pow_of_two(max_cnt); + /* Check the validity of QP support capacity */ + if (!cap->max_recv_wr || cap->max_recv_wr > hr_dev->caps.max_wqes || + cap->max_recv_sge > hr_dev->caps.max_rq_sg) { + ibdev_err(&hr_dev->ib_dev, "RQ config error, depth=%u, sge=%d\n", + cap->max_recv_wr, cap->max_recv_sge); + return -EINVAL; + } - if ((u32)hr_qp->rq.wqe_cnt > hr_dev->caps.max_wqes) { - dev_err(dev, "while setting rq size, rq.wqe_cnt too large\n"); - return -EINVAL; - } + max_cnt = max(cap->max_recv_wr, hr_dev->caps.min_wqes); - max_cnt = max(1U, cap->max_recv_sge); - hr_qp->rq.max_gs = roundup_pow_of_two(max_cnt); - if (hr_dev->caps.max_rq_sg <= 2) - hr_qp->rq.wqe_shift = - ilog2(hr_dev->caps.max_rq_desc_sz); - else - hr_qp->rq.wqe_shift = - ilog2(hr_dev->caps.max_rq_desc_sz - * hr_qp->rq.max_gs); + hr_qp->rq.wqe_cnt = roundup_pow_of_two(max_cnt); + if ((u32)hr_qp->rq.wqe_cnt > hr_dev->caps.max_wqes) { + ibdev_err(&hr_dev->ib_dev, "rq depth %u too large\n", + cap->max_recv_wr); + return -EINVAL; } - cap->max_recv_wr = hr_qp->rq.max_post = hr_qp->rq.wqe_cnt; + max_cnt = max(1U, cap->max_recv_sge); + hr_qp->rq.max_gs = roundup_pow_of_two(max_cnt); + + if (hr_dev->caps.max_rq_sg <= HNS_ROCE_SGE_IN_WQE) + hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz); + else + hr_qp->rq.wqe_shift = ilog2(hr_dev->caps.max_rq_desc_sz * + hr_qp->rq.max_gs); + + cap->max_recv_wr = hr_qp->rq.wqe_cnt; cap->max_recv_sge = hr_qp->rq.max_gs; return 0; @@ -332,15 +411,14 @@ u8 max_sq_stride = ilog2(roundup_sq_stride); /* Sanity check SQ size before proceeding */ - if ((u32)(1 << ucmd->log_sq_bb_count) > hr_dev->caps.max_wqes || - ucmd->log_sq_stride > max_sq_stride || - ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) { - ibdev_err(&hr_dev->ib_dev, "check SQ size error!\n"); + if (ucmd->log_sq_stride > max_sq_stride || + ucmd->log_sq_stride < HNS_ROCE_IB_MIN_SQ_STRIDE) { + ibdev_err(&hr_dev->ib_dev, "Failed to check SQ stride size\n"); return -EINVAL; } if (cap->max_send_sge > hr_dev->caps.max_sq_sg) { - ibdev_err(&hr_dev->ib_dev, "SQ sge error! max_send_sge=%d\n", + ibdev_err(&hr_dev->ib_dev, "Failed to check SQ SGE size %d\n", cap->max_send_sge); return -EINVAL; } @@ -348,40 +426,43 @@ return 0; } -static int hns_roce_set_user_sq_size(struct hns_roce_dev *hr_dev, - struct ib_qp_cap *cap, - struct hns_roce_qp *hr_qp, - struct hns_roce_ib_create_qp *ucmd) +static int set_user_sq_size(struct hns_roce_dev *hr_dev, + struct ib_qp_cap *cap, struct hns_roce_qp *hr_qp, + struct hns_roce_ib_create_qp *ucmd) { u32 ex_sge_num; u32 page_size; u32 max_cnt; int ret; + if (check_shl_overflow(1, ucmd->log_sq_bb_count, &hr_qp->sq.wqe_cnt) || + hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) + return -EINVAL; + ret = check_sq_size_with_integrity(hr_dev, cap, ucmd); if (ret) { - ibdev_err(&hr_dev->ib_dev, "Sanity check sq size failed\n"); + ibdev_err(&hr_dev->ib_dev, "Failed to check user SQ size limit\n"); return ret; } - hr_qp->sq.wqe_cnt = 1 << ucmd->log_sq_bb_count; hr_qp->sq.wqe_shift = ucmd->log_sq_stride; max_cnt = max(1U, cap->max_send_sge); - if (hr_dev->caps.max_sq_sg <= 2) + if (hr_dev->hw_rev == HNS_ROCE_HW_VER1) hr_qp->sq.max_gs = roundup_pow_of_two(max_cnt); else hr_qp->sq.max_gs = max_cnt; - if (hr_qp->sq.max_gs > 2) + if (hr_qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE) hr_qp->sge.sge_cnt = roundup_pow_of_two(hr_qp->sq.wqe_cnt * (hr_qp->sq.max_gs - 2)); - if ((hr_qp->sq.max_gs > 2) && (hr_dev->pci_dev->revision == 0x20)) { + if (hr_qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE && + hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08_A) { if (hr_qp->sge.sge_cnt > hr_dev->caps.max_extend_sg) { - dev_err(hr_dev->dev, - "The extended sge cnt error! sge_cnt=%d\n", - hr_qp->sge.sge_cnt); + ibdev_err(&hr_dev->ib_dev, + "Failed to check extended SGE size limit %d\n", + hr_qp->sge.sge_cnt); return -EINVAL; } } @@ -390,41 +471,39 @@ ex_sge_num = hr_qp->sge.sge_cnt; /* Get buf size, SQ and RQ are aligned to page_szie */ - if (hr_dev->caps.max_sq_sg <= 2) { - hr_qp->buff_size = HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt << + if (hr_dev->hw_rev == HNS_ROCE_HW_VER1) { + hr_qp->buff_size = round_up((hr_qp->rq.wqe_cnt << hr_qp->rq.wqe_shift), PAGE_SIZE) + - HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt << + round_up((hr_qp->sq.wqe_cnt << hr_qp->sq.wqe_shift), PAGE_SIZE); hr_qp->sq.offset = 0; - hr_qp->rq.offset = HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt << + hr_qp->rq.offset = round_up((hr_qp->sq.wqe_cnt << hr_qp->sq.wqe_shift), PAGE_SIZE); } else { page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT); hr_qp->sge.sge_cnt = ex_sge_num ? max(page_size / (1 << hr_qp->sge.sge_shift), ex_sge_num) : 0; - hr_qp->buff_size = HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt << + hr_qp->buff_size = round_up((hr_qp->rq.wqe_cnt << hr_qp->rq.wqe_shift), page_size) + - HNS_ROCE_ALOGN_UP((hr_qp->sge.sge_cnt << + round_up((hr_qp->sge.sge_cnt << hr_qp->sge.sge_shift), page_size) + - HNS_ROCE_ALOGN_UP((hr_qp->sq.wqe_cnt << + round_up((hr_qp->sq.wqe_cnt << hr_qp->sq.wqe_shift), page_size); hr_qp->sq.offset = 0; if (ex_sge_num) { - hr_qp->sge.offset = HNS_ROCE_ALOGN_UP( - (hr_qp->sq.wqe_cnt << - hr_qp->sq.wqe_shift), - page_size); + hr_qp->sge.offset = round_up((hr_qp->sq.wqe_cnt << + hr_qp->sq.wqe_shift), + page_size); hr_qp->rq.offset = hr_qp->sge.offset + - HNS_ROCE_ALOGN_UP((hr_qp->sge.sge_cnt << - hr_qp->sge.sge_shift), - page_size); + round_up((hr_qp->sge.sge_cnt << + hr_qp->sge.sge_shift), + page_size); } else { - hr_qp->rq.offset = HNS_ROCE_ALOGN_UP( - (hr_qp->sq.wqe_cnt << - hr_qp->sq.wqe_shift), - page_size); + hr_qp->rq.offset = round_up((hr_qp->sq.wqe_cnt << + hr_qp->sq.wqe_shift), + page_size); } } @@ -528,13 +607,15 @@ } /* ud sqwqe's sge use extend sge */ - if (hr_dev->caps.max_sq_sg > 2 && hr_qp->ibqp.qp_type == IB_QPT_GSI) { + if (hr_dev->hw_rev != HNS_ROCE_HW_VER1 && + hr_qp->ibqp.qp_type == IB_QPT_GSI) { hr_qp->sge.sge_cnt = roundup_pow_of_two(hr_qp->sq.wqe_cnt * hr_qp->sq.max_gs); hr_qp->sge.sge_shift = 4; } - if ((hr_qp->sq.max_gs > 2) && hr_dev->pci_dev->revision == 0x20) { + if (hr_qp->sq.max_gs > 2 && + hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08_A) { if (hr_qp->sge.sge_cnt > hr_dev->caps.max_extend_sg) { dev_err(dev, "The extended sge cnt error! sge_cnt=%d\n", hr_qp->sge.sge_cnt); @@ -545,70 +626,65 @@ return 0; } -static int hns_roce_set_kernel_sq_size(struct hns_roce_dev *hr_dev, - struct ib_qp_cap *cap, - struct hns_roce_qp *hr_qp) +static int set_kernel_sq_size(struct hns_roce_dev *hr_dev, + struct ib_qp_cap *cap, struct hns_roce_qp *hr_qp) { - struct device *dev = hr_dev->dev; u32 page_size; u32 max_cnt; int size; int ret; - if (cap->max_send_wr > hr_dev->caps.max_wqes || + if (!cap->max_send_wr || cap->max_send_wr > hr_dev->caps.max_wqes || cap->max_send_sge > hr_dev->caps.max_sq_sg || cap->max_inline_data > hr_dev->caps.max_sq_inline) { - dev_err(dev, "SQ WR or sge or inline data error!\n"); + ibdev_err(&hr_dev->ib_dev, + "SQ WR or sge or inline data error!\n"); return -EINVAL; } hr_qp->sq.wqe_shift = ilog2(hr_dev->caps.max_sq_desc_sz); - if (hr_dev->caps.min_wqes) - max_cnt = max(cap->max_send_wr, hr_dev->caps.min_wqes); - else - max_cnt = cap->max_send_wr; + max_cnt = max(cap->max_send_wr, hr_dev->caps.min_wqes); hr_qp->sq.wqe_cnt = roundup_pow_of_two(max_cnt); if ((u32)hr_qp->sq.wqe_cnt > hr_dev->caps.max_wqes) { - dev_err(dev, "while setting kernel sq size, sq.wqe_cnt too large\n"); + ibdev_err(&hr_dev->ib_dev, + "while setting kernel sq size, sq.wqe_cnt too large\n"); return -EINVAL; } /* Get data_seg numbers */ max_cnt = max(1U, cap->max_send_sge); - if (hr_dev->caps.max_sq_sg <= 2) + if (hr_dev->hw_rev == HNS_ROCE_HW_VER1) hr_qp->sq.max_gs = roundup_pow_of_two(max_cnt); else hr_qp->sq.max_gs = max_cnt; ret = set_extend_sge_param(hr_dev, hr_qp); if (ret) { - dev_err(dev, "set extend sge parameters fail\n"); + ibdev_err(&hr_dev->ib_dev, "set extend sge parameters fail\n"); return ret; } /* Get buf size, SQ and RQ are aligned to PAGE_SIZE */ page_size = 1 << (hr_dev->caps.mtt_buf_pg_sz + PAGE_SHIFT); hr_qp->sq.offset = 0; - size = HNS_ROCE_ALOGN_UP(hr_qp->sq.wqe_cnt << hr_qp->sq.wqe_shift, - page_size); + size = round_up(hr_qp->sq.wqe_cnt << hr_qp->sq.wqe_shift, page_size); - if (hr_dev->caps.max_sq_sg > 2 && hr_qp->sge.sge_cnt) { + if (hr_dev->hw_rev != HNS_ROCE_HW_VER1 && hr_qp->sge.sge_cnt) { hr_qp->sge.sge_cnt = max(page_size/(1 << hr_qp->sge.sge_shift), - (u32)hr_qp->sge.sge_cnt); + (u32)hr_qp->sge.sge_cnt); hr_qp->sge.offset = size; - size += HNS_ROCE_ALOGN_UP(hr_qp->sge.sge_cnt << - hr_qp->sge.sge_shift, page_size); + size += round_up(hr_qp->sge.sge_cnt << hr_qp->sge.sge_shift, + page_size); } hr_qp->rq.offset = size; - size += HNS_ROCE_ALOGN_UP((hr_qp->rq.wqe_cnt << hr_qp->rq.wqe_shift), - page_size); + size += round_up((hr_qp->rq.wqe_cnt << hr_qp->rq.wqe_shift), page_size); hr_qp->buff_size = size; /* Get wr and sge number which send */ - cap->max_send_wr = hr_qp->sq.max_post = hr_qp->sq.wqe_cnt; + cap->max_send_wr = hr_qp->sq.wqe_cnt; cap->max_send_sge = hr_qp->sq.max_gs; /* We don't support inline sends for kernel QPs (yet) */ @@ -679,336 +755,447 @@ kfree(hr_qp->rq_inl_buf.wqe_list); } -static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, - struct ib_pd *ib_pd, - struct ib_qp_init_attr *init_attr, - struct ib_udata *udata, unsigned long sqpn, - struct hns_roce_qp *hr_qp) +static int map_wqe_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + u32 page_shift, bool is_user) { dma_addr_t *buf_list[ARRAY_SIZE(hr_qp->regions)] = { NULL }; - struct device *dev = hr_dev->dev; - struct hns_roce_ib_create_qp ucmd; - struct hns_roce_ib_create_qp_resp resp = {}; - struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context( - udata, struct hns_roce_ucontext, ibucontext); + struct ib_device *ibdev = &hr_dev->ib_dev; struct hns_roce_buf_region *r; - unsigned long qpn = 0; - u32 page_shift; + int region_count; int buf_count; int ret; int i; - mutex_init(&hr_qp->mutex); - spin_lock_init(&hr_qp->sq.lock); - spin_lock_init(&hr_qp->rq.lock); + region_count = split_wqe_buf_region(hr_dev, hr_qp, hr_qp->regions, + ARRAY_SIZE(hr_qp->regions), page_shift); - hr_qp->state = IB_QPS_RESET; - - hr_qp->ibqp.qp_type = init_attr->qp_type; - - if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) - hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR; - else - hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR; - - ret = hns_roce_set_rq_size(hr_dev, &init_attr->cap, udata, - hns_roce_qp_has_rq(init_attr), hr_qp); + /* alloc a tmp list to store WQE buffers address */ + ret = hns_roce_alloc_buf_list(hr_qp->regions, buf_list, region_count); if (ret) { - dev_err(dev, "hns_roce_set_rq_size failed\n"); - goto err_out; + ibdev_err(ibdev, "Failed to alloc WQE buffer list\n"); + return ret; } - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) && - hns_roce_qp_has_rq(init_attr)) { - ret = alloc_rq_inline_buf(hr_qp, init_attr); - if (ret) { - dev_err(dev, "allocate receive inline buffer failed\n"); - goto err_out; + for (i = 0; i < region_count; i++) { + r = &hr_qp->regions[i]; + if (is_user) + buf_count = hns_roce_get_umem_bufs(hr_dev, buf_list[i], + r->count, r->offset, hr_qp->umem, + page_shift); + else + buf_count = hns_roce_get_kmem_bufs(hr_dev, buf_list[i], + r->count, r->offset, &hr_qp->hr_buf); + + if (buf_count != r->count) { + ibdev_err(ibdev, "Failed to get %s WQE buf, expect %d = %d.\n", + is_user ? "user" : "kernel", + r->count, buf_count); + ret = -ENOBUFS; + goto done; } } - page_shift = PAGE_SHIFT + hr_dev->caps.mtt_buf_pg_sz; - if (udata) { - if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) { - dev_err(dev, "ib_copy_from_udata error for create qp\n"); - ret = -EFAULT; - goto err_alloc_rq_inline_buf; - } + hr_qp->wqe_bt_pg_shift = calc_wqe_bt_page_shift(hr_dev, hr_qp->regions, + region_count); + hns_roce_mtr_init(&hr_qp->mtr, PAGE_SHIFT + hr_qp->wqe_bt_pg_shift, + page_shift); + ret = hns_roce_mtr_attach(hr_dev, &hr_qp->mtr, buf_list, hr_qp->regions, + region_count); + if (ret) + ibdev_err(ibdev, "Failed to attatch WQE's mtr\n"); + + goto done; + + hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr); +done: + hns_roce_free_buf_list(buf_list, region_count); - ret = hns_roce_set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, - &ucmd); + return ret; +} + +static int alloc_qp_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, unsigned long addr) +{ + u32 page_shift = PAGE_SHIFT + hr_dev->caps.mtt_buf_pg_sz; + struct ib_device *ibdev = &hr_dev->ib_dev; + bool is_rq_buf_inline; + int ret; + + is_rq_buf_inline = (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) && + hns_roce_qp_has_rq(init_attr); + if (is_rq_buf_inline) { + ret = alloc_rq_inline_buf(hr_qp, init_attr); if (ret) { - dev_err(dev, "hns_roce_set_user_sq_size error for create qp\n"); - goto err_alloc_rq_inline_buf; + ibdev_err(ibdev, "Failed to alloc inline RQ buffer\n"); + return ret; } + } - hr_qp->umem = ib_umem_get(udata, ucmd.buf_addr, - hr_qp->buff_size, 0, 0); + if (udata) { + hr_qp->umem = ib_umem_get(ibdev, addr, hr_qp->buff_size, 0); if (IS_ERR(hr_qp->umem)) { - dev_err(dev, "ib_umem_get error for create qp\n"); ret = PTR_ERR(hr_qp->umem); - goto err_alloc_rq_inline_buf; - } - hr_qp->region_cnt = split_wqe_buf_region(hr_dev, hr_qp, - hr_qp->regions, ARRAY_SIZE(hr_qp->regions), - page_shift); - ret = hns_roce_alloc_buf_list(hr_qp->regions, buf_list, - hr_qp->region_cnt); - if (ret) { - dev_err(dev, "alloc buf_list error for create qp\n"); - goto err_alloc_list; + goto err_inline; } + } else { + ret = hns_roce_buf_alloc(hr_dev, hr_qp->buff_size, + (1 << page_shift) * 2, + &hr_qp->hr_buf, page_shift); + if (ret) + goto err_inline; + } - for (i = 0; i < hr_qp->region_cnt; i++) { - r = &hr_qp->regions[i]; - buf_count = hns_roce_get_umem_bufs(hr_dev, - buf_list[i], r->count, r->offset, - hr_qp->umem, page_shift); - if (buf_count != r->count) { - dev_err(dev, - "get umem buf err, expect %d,ret %d.\n", - r->count, buf_count); - ret = -ENOBUFS; - goto err_get_bufs; - } - } + ret = map_wqe_buf(hr_dev, hr_qp, page_shift, udata); + if (ret) + goto err_alloc; + + return 0; + +err_inline: + if (is_rq_buf_inline) + free_rq_inline_buf(hr_qp); + +err_alloc: + if (udata) { + ib_umem_release(hr_qp->umem); + hr_qp->umem = NULL; + } else { + hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); + } - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SQ_RECORD_DB) && - (udata->inlen >= sizeof(ucmd)) && - (udata->outlen >= sizeof(resp)) && - hns_roce_qp_has_sq(init_attr)) { - ret = hns_roce_db_map_user(uctx, udata, ucmd.sdb_addr, + ibdev_err(ibdev, "Failed to alloc WQE buffer, ret %d.\n", ret); + + return ret; +} + +static void free_qp_buf(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) +{ + hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr); + if (hr_qp->umem) { + ib_umem_release(hr_qp->umem); + hr_qp->umem = NULL; + } + + if (hr_qp->hr_buf.nbufs > 0) + hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); + + if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) && + hr_qp->rq.wqe_cnt) + free_rq_inline_buf(hr_qp); +} + +static inline bool user_qp_has_sdb(struct hns_roce_dev *hr_dev, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_ib_create_qp_resp *resp, + struct hns_roce_ib_create_qp *ucmd) +{ + return ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SQ_RECORD_DB) && + udata->outlen >= offsetofend(typeof(*resp), cap_flags) && + hns_roce_qp_has_sq(init_attr) && + udata->inlen >= offsetofend(typeof(*ucmd), sdb_addr)); +} + +static inline bool user_qp_has_rdb(struct hns_roce_dev *hr_dev, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_ib_create_qp_resp *resp) +{ + return ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && + udata->outlen >= offsetofend(typeof(*resp), cap_flags) && + hns_roce_qp_has_rq(init_attr)); +} + +static inline bool kernel_qp_has_rdb(struct hns_roce_dev *hr_dev, + struct ib_qp_init_attr *init_attr) +{ + return ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && + hns_roce_qp_has_rq(init_attr)); +} + +static int alloc_qp_db(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_ib_create_qp *ucmd, + struct hns_roce_ib_create_qp_resp *resp) +{ + struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context( + udata, struct hns_roce_ucontext, ibucontext); + struct ib_device *ibdev = &hr_dev->ib_dev; + int ret; + + if (udata) { + if (user_qp_has_sdb(hr_dev, init_attr, udata, resp, ucmd)) { + ret = hns_roce_db_map_user(uctx, udata, ucmd->sdb_addr, &hr_qp->sdb); if (ret) { - dev_err(dev, "sq record doorbell map failed!\n"); - goto err_get_bufs; + ibdev_err(ibdev, + "Failed to map user SQ doorbell\n"); + goto err_out; } - - /* indicate kernel supports sq record db */ - resp.cap_flags |= HNS_ROCE_SUPPORT_SQ_RECORD_DB; hr_qp->sdb_en = 1; + resp->cap_flags |= HNS_ROCE_SUPPORT_SQ_RECORD_DB; } - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && - (udata->outlen >= sizeof(resp)) && - hns_roce_qp_has_rq(init_attr)) { - ret = hns_roce_db_map_user(uctx, udata, ucmd.db_addr, + if (user_qp_has_rdb(hr_dev, init_attr, udata, resp)) { + ret = hns_roce_db_map_user(uctx, udata, ucmd->db_addr, &hr_qp->rdb); if (ret) { - dev_err(dev, "rq record doorbell map failed!\n"); - goto err_sq_dbmap; + ibdev_err(ibdev, + "Failed to map user RQ doorbell\n"); + goto err_sdb; } - - /* indicate kernel supports rq record db */ - resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB; hr_qp->rdb_en = 1; + resp->cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB; } } else { - if (init_attr->create_flags & - IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) { - dev_err(dev, "init_attr->create_flags error!\n"); - ret = -EINVAL; - goto err_alloc_rq_inline_buf; - } - - if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) { - dev_err(dev, "init_attr->create_flags error!\n"); - ret = -EINVAL; - goto err_alloc_rq_inline_buf; - } - - /* Set SQ size */ - ret = hns_roce_set_kernel_sq_size(hr_dev, &init_attr->cap, - hr_qp); - if (ret) { - dev_err(dev, "hns_roce_set_kernel_sq_size error!\n"); - goto err_alloc_rq_inline_buf; - } - /* QP doorbell register address */ hr_qp->sq.db_reg_l = hr_dev->reg_base + hr_dev->sdb_offset + DB_REG_OFFSET * hr_dev->priv_uar.index; hr_qp->rq.db_reg_l = hr_dev->reg_base + hr_dev->odb_offset + DB_REG_OFFSET * hr_dev->priv_uar.index; - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && - hns_roce_qp_has_rq(init_attr)) { + if (kernel_qp_has_rdb(hr_dev, init_attr)) { ret = hns_roce_alloc_db(hr_dev, &hr_qp->rdb, 0); if (ret) { - dev_err(dev, "rq record doorbell alloc failed!\n"); - goto err_alloc_rq_inline_buf; + ibdev_err(ibdev, + "Failed to alloc kernel RQ doorbell\n"); + goto err_out; } *hr_qp->rdb.db_record = 0; hr_qp->rdb_en = 1; } + } - /* Allocate QP buf */ - if (hns_roce_buf_alloc(hr_dev, hr_qp->buff_size, - (1 << page_shift) * 2, - &hr_qp->hr_buf, page_shift)) { - dev_err(dev, "hns_roce_buf_alloc error!\n"); + return 0; +err_sdb: + if (udata && hr_qp->sdb_en) + hns_roce_db_unmap_user(uctx, &hr_qp->sdb); +err_out: + return ret; +} + +static void free_qp_db(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_udata *udata) +{ + struct hns_roce_ucontext *uctx = rdma_udata_to_drv_context( + udata, struct hns_roce_ucontext, ibucontext); + + if (udata) { + if (hr_qp->rdb_en) + hns_roce_db_unmap_user(uctx, &hr_qp->rdb); + if (hr_qp->sdb_en) + hns_roce_db_unmap_user(uctx, &hr_qp->sdb); + } else { + if (hr_qp->rdb_en) + hns_roce_free_db(hr_dev, &hr_qp->rdb); + } +} + +static int alloc_kernel_wrid(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp) +{ + struct ib_device *ibdev = &hr_dev->ib_dev; + u64 *sq_wrid = NULL; + u64 *rq_wrid = NULL; + int ret; + + sq_wrid = kcalloc(hr_qp->sq.wqe_cnt, sizeof(u64), GFP_KERNEL); + if (ZERO_OR_NULL_PTR(sq_wrid)) { + ibdev_err(ibdev, "Failed to alloc SQ wrid\n"); + return -ENOMEM; + } + + if (hr_qp->rq.wqe_cnt) { + rq_wrid = kcalloc(hr_qp->rq.wqe_cnt, sizeof(u64), GFP_KERNEL); + if (ZERO_OR_NULL_PTR(rq_wrid)) { + ibdev_err(ibdev, "Failed to alloc RQ wrid\n"); ret = -ENOMEM; - goto err_db; - } - hr_qp->region_cnt = split_wqe_buf_region(hr_dev, hr_qp, - hr_qp->regions, ARRAY_SIZE(hr_qp->regions), - page_shift); - ret = hns_roce_alloc_buf_list(hr_qp->regions, buf_list, - hr_qp->region_cnt); - if (ret) { - dev_err(dev, "alloc buf_list error for create qp!\n"); - goto err_alloc_list; + goto err_sq; } + } - for (i = 0; i < hr_qp->region_cnt; i++) { - r = &hr_qp->regions[i]; - buf_count = hns_roce_get_kmem_bufs(hr_dev, - buf_list[i], r->count, r->offset, - &hr_qp->hr_buf); - if (buf_count != r->count) { - dev_err(dev, - "get kmem buf err, expect %d,ret %d.\n", - r->count, buf_count); - ret = -ENOBUFS; - goto err_get_bufs; - } + hr_qp->sq.wrid = sq_wrid; + hr_qp->rq.wrid = rq_wrid; + return 0; +err_sq: + kfree(sq_wrid); + + return ret; +} + +static void free_kernel_wrid(struct hns_roce_dev *hr_dev, + struct hns_roce_qp *hr_qp) +{ + kfree(hr_qp->rq.wrid); + kfree(hr_qp->sq.wrid); +} + +static int set_qp_param(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_ib_create_qp *ucmd) +{ + struct ib_device *ibdev = &hr_dev->ib_dev; + int ret; + + hr_qp->ibqp.qp_type = init_attr->qp_type; + + if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) + hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR; + else + hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR; + + ret = set_rq_size(hr_dev, &init_attr->cap, udata, + hns_roce_qp_has_rq(init_attr), hr_qp); + if (ret) { + ibdev_err(ibdev, "Failed to set user RQ size\n"); + return ret; + } + + if (udata) { + if (ib_copy_from_udata(ucmd, udata, sizeof(*ucmd))) { + ibdev_err(ibdev, "Failed to copy QP ucmd\n"); + return -EFAULT; } - hr_qp->sq.wrid = kcalloc(hr_qp->sq.wqe_cnt, sizeof(u64), - GFP_KERNEL); - if (ZERO_OR_NULL_PTR(hr_qp->sq.wrid)) { - ret = -ENOMEM; - goto err_get_bufs; + ret = set_user_sq_size(hr_dev, &init_attr->cap, hr_qp, ucmd); + if (ret) + ibdev_err(ibdev, "Failed to set user SQ size\n"); + } else { + if (init_attr->create_flags & + IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) { + ibdev_err(ibdev, "Failed to check multicast loopback\n"); + return -EINVAL; } - if (hr_qp->rq.wqe_cnt) { - hr_qp->rq.wrid = kcalloc(hr_qp->rq.wqe_cnt, sizeof(u64), - GFP_KERNEL); - if (ZERO_OR_NULL_PTR(hr_qp->rq.wrid)) { - ret = -ENOMEM; - goto err_sq_wrid; - } + if (init_attr->create_flags & IB_QP_CREATE_IPOIB_UD_LSO) { + ibdev_err(ibdev, "Failed to check ipoib ud lso\n"); + return -EINVAL; } + + ret = set_kernel_sq_size(hr_dev, &init_attr->cap, hr_qp); + if (ret) + ibdev_err(ibdev, "Failed to set kernel SQ size\n"); } - if (sqpn) { - qpn = sqpn; - } else { - /* Get QPN */ - ret = hns_roce_reserve_range_qp(hr_dev, 1, 1, &qpn); + return ret; +} + +static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev, + struct ib_pd *ib_pd, + struct ib_qp_init_attr *init_attr, + struct ib_udata *udata, + struct hns_roce_qp *hr_qp) +{ + struct hns_roce_ib_create_qp_resp resp = {}; + struct ib_device *ibdev = &hr_dev->ib_dev; + struct hns_roce_ib_create_qp ucmd; + int ret; + + mutex_init(&hr_qp->mutex); + spin_lock_init(&hr_qp->sq.lock); + spin_lock_init(&hr_qp->rq.lock); + + hr_qp->state = IB_QPS_RESET; + hr_qp->flush_flag = 0; + + ret = set_qp_param(hr_dev, hr_qp, init_attr, udata, &ucmd); + if (ret) { + ibdev_err(ibdev, "Failed to set QP param\n"); + return ret; + } + + if (!udata) { + ret = alloc_kernel_wrid(hr_dev, hr_qp); if (ret) { - dev_err(dev, "hns_roce_reserve_range_qp alloc qpn error\n"); - goto err_wrid; + ibdev_err(ibdev, "Failed to alloc wrid\n"); + return ret; } } - hr_qp->wqe_bt_pg_shift = calc_wqe_bt_page_shift(hr_dev, hr_qp->regions, - hr_qp->region_cnt); - hns_roce_mtr_init(&hr_qp->mtr, PAGE_SHIFT + hr_qp->wqe_bt_pg_shift, - page_shift); - ret = hns_roce_mtr_attach(hr_dev, &hr_qp->mtr, buf_list, - hr_qp->regions, hr_qp->region_cnt); + ret = alloc_qp_db(hr_dev, hr_qp, init_attr, udata, &ucmd, &resp); if (ret) { - dev_err(dev, "mtr attach error for create qp\n"); - goto err_mtr; + ibdev_err(ibdev, "Failed to alloc QP doorbell\n"); + goto err_wrid; } - if (init_attr->qp_type == IB_QPT_GSI && - hr_dev->hw_rev == HNS_ROCE_HW_VER1) { - /* In v1 engine, GSI QP context in RoCE engine's register */ - ret = hns_roce_gsi_qp_alloc(hr_dev, qpn, hr_qp); - if (ret) { - dev_err(dev, "hns_roce_qp_alloc failed!\n"); - goto err_qpn; - } - } else { - ret = hns_roce_qp_alloc(hr_dev, qpn, hr_qp); - if (ret) { - dev_err(dev, "hns_roce_qp_alloc failed!\n"); - goto err_qpn; - } + ret = alloc_qp_buf(hr_dev, hr_qp, init_attr, udata, ucmd.buf_addr); + if (ret) { + ibdev_err(ibdev, "Failed to alloc QP buffer\n"); + goto err_db; } - if (sqpn) - hr_qp->doorbell_qpn = 1; - else - hr_qp->doorbell_qpn = (u32)hr_qp->qpn; + ret = alloc_qpn(hr_dev, hr_qp); + if (ret) { + ibdev_err(ibdev, "Failed to alloc QPN\n"); + goto err_buf; + } + + ret = alloc_qpc(hr_dev, hr_qp); + if (ret) { + ibdev_err(ibdev, "Failed to alloc QP context\n"); + goto err_qpn; + } + + ret = hns_roce_qp_store(hr_dev, hr_qp, init_attr); + if (ret) { + ibdev_err(ibdev, "Failed to store QP\n"); + goto err_qpc; + } if (udata) { ret = ib_copy_to_udata(udata, &resp, min(udata->outlen, sizeof(resp))); - if (ret) - goto err_qp; + if (ret) { + ibdev_err(ibdev, "copy qp resp failed!\n"); + goto err_store; + } } if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL) { ret = hr_dev->hw->qp_flow_control_init(hr_dev, hr_qp); if (ret) - goto err_qp; + goto err_store; } + hr_qp->ibqp.qp_num = hr_qp->qpn; hr_qp->event = hns_roce_ib_qp_event; - hns_roce_free_buf_list(buf_list, hr_qp->region_cnt); + atomic_set(&hr_qp->refcount, 1); + init_completion(&hr_qp->free); return 0; -err_qp: - if (init_attr->qp_type == IB_QPT_GSI && - hr_dev->hw_rev == HNS_ROCE_HW_VER1) - hns_roce_qp_remove(hr_dev, hr_qp); - else - hns_roce_qp_free(hr_dev, hr_qp); - +err_store: + hns_roce_qp_remove(hr_dev, hr_qp); +err_qpc: + free_qpc(hr_dev, hr_qp); err_qpn: - if (!sqpn) - hns_roce_release_range_qp(hr_dev, qpn, 1); - -err_mtr: - hns_roce_mtr_cleanup(hr_dev, &hr_qp->mtr); - + free_qpn(hr_dev, hr_qp); +err_buf: + free_qp_buf(hr_dev, hr_qp); +err_db: + free_qp_db(hr_dev, hr_qp, udata); err_wrid: - if (udata) { - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB) && - (udata->outlen >= sizeof(resp)) && - hns_roce_qp_has_rq(init_attr)) - hns_roce_db_unmap_user(uctx, &hr_qp->rdb); - } else { - if (hr_qp->rq.wqe_cnt) - kfree(hr_qp->rq.wrid); - } - -err_sq_dbmap: - if (udata) - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SQ_RECORD_DB) && - (udata->inlen >= sizeof(ucmd)) && - (udata->outlen >= sizeof(resp)) && - hns_roce_qp_has_sq(init_attr)) - hns_roce_db_unmap_user(uctx, &hr_qp->sdb); - -err_sq_wrid: - if (!udata) - kfree(hr_qp->sq.wrid); - -err_get_bufs: - hns_roce_free_buf_list(buf_list, hr_qp->region_cnt); - -err_alloc_list: - if (!hr_qp->umem) - hns_roce_buf_free(hr_dev, hr_qp->buff_size, &hr_qp->hr_buf); - ib_umem_release(hr_qp->umem); + free_kernel_wrid(hr_dev, hr_qp); + return ret; +} -err_db: - if (!udata && hns_roce_qp_has_rq(init_attr) && - (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)) - hns_roce_free_db(hr_dev, &hr_qp->rdb); +void hns_roce_qp_destroy(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_udata *udata) +{ + if (atomic_dec_and_test(&hr_qp->refcount)) + complete(&hr_qp->free); + wait_for_completion(&hr_qp->free); -err_alloc_rq_inline_buf: - if ((hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RQ_INLINE) && - hns_roce_qp_has_rq(init_attr)) - free_rq_inline_buf(hr_qp); + free_qpc(hr_dev, hr_qp); + free_qpn(hr_dev, hr_qp); + free_qp_buf(hr_dev, hr_qp); + free_kernel_wrid(hr_dev, hr_qp); + free_qp_db(hr_dev, hr_qp, udata); -err_out: - return ret; + kfree(hr_qp); } struct ib_qp *hns_roce_create_qp(struct ib_pd *pd, @@ -1017,7 +1204,6 @@ { struct hns_roce_dev *hr_dev = to_hr_dev(pd->device); struct ib_device *ibdev = &hr_dev->ib_dev; - struct hns_roce_sqp *hr_sqp; struct hns_roce_qp *hr_qp; int ret; @@ -1027,17 +1213,15 @@ if (!hr_qp) return ERR_PTR(-ENOMEM); - ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, 0, + ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, hr_qp); if (ret) { - ibdev_err(ibdev, "Create RC QP 0x%06lx failed(%d)\n", + ibdev_err(ibdev, "Create QP 0x%06lx failed(%d)\n", hr_qp->qpn, ret); kfree(hr_qp); return ERR_PTR(ret); } - hr_qp->ibqp.qp_num = hr_qp->qpn; - break; } case IB_QPT_GSI: { @@ -1047,26 +1231,18 @@ return ERR_PTR(-EINVAL); } - hr_sqp = kzalloc(sizeof(*hr_sqp), GFP_KERNEL); - if (!hr_sqp) + hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL); + if (!hr_qp) return ERR_PTR(-ENOMEM); - hr_qp = &hr_sqp->hr_qp; hr_qp->port = init_attr->port_num - 1; hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port]; - /* when hw version is v1, the sqpn is allocated */ - if (hr_dev->caps.max_sq_sg <= 2) - hr_qp->ibqp.qp_num = HNS_ROCE_MAX_PORTS + - hr_dev->iboe.phy_port[hr_qp->port]; - else - hr_qp->ibqp.qp_num = 1; - ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, - hr_qp->ibqp.qp_num, hr_qp); + hr_qp); if (ret) { ibdev_err(ibdev, "Create GSI QP failed!\n"); - kfree(hr_sqp); + kfree(hr_qp); return ERR_PTR(ret); } @@ -1179,8 +1355,10 @@ mutex_lock(&hr_qp->mutex); - cur_state = attr_mask & IB_QP_CUR_STATE ? - attr->cur_qp_state : (enum ib_qp_state)hr_qp->state; + if (attr_mask & IB_QP_CUR_STATE && attr->cur_qp_state != hr_qp->state) + goto out; + + cur_state = hr_qp->state; new_state = attr_mask & IB_QP_STATE ? attr->qp_state : cur_state; if (ibqp->uobject && @@ -1208,11 +1386,10 @@ goto out; if (cur_state == new_state && cur_state == IB_QPS_RESET) { - if (hr_dev->caps.min_wqes) { + if (hr_dev->hw_rev == HNS_ROCE_HW_VER1) { ret = -EPERM; ibdev_err(&hr_dev->ib_dev, - "cur_state=%d new_state=%d\n", cur_state, - new_state); + "RST2RST state is not supported\n"); } else { ret = 0; } @@ -1232,7 +1409,16 @@ void hns_roce_lock_cqs(struct hns_roce_cq *send_cq, struct hns_roce_cq *recv_cq) __acquires(&send_cq->lock) __acquires(&recv_cq->lock) { - if (send_cq == recv_cq) { + if (unlikely(send_cq == NULL && recv_cq == NULL)) { + __acquire(&send_cq->lock); + __acquire(&recv_cq->lock); + } else if (unlikely(send_cq != NULL && recv_cq == NULL)) { + spin_lock_irq(&send_cq->lock); + __acquire(&recv_cq->lock); + } else if (unlikely(send_cq == NULL && recv_cq != NULL)) { + spin_lock_irq(&recv_cq->lock); + __acquire(&send_cq->lock); + } else if (send_cq == recv_cq) { spin_lock_irq(&send_cq->lock); __acquire(&recv_cq->lock); } else if (send_cq->cqn < recv_cq->cqn) { @@ -1248,7 +1434,16 @@ struct hns_roce_cq *recv_cq) __releases(&send_cq->lock) __releases(&recv_cq->lock) { - if (send_cq == recv_cq) { + if (unlikely(send_cq == NULL && recv_cq == NULL)) { + __release(&recv_cq->lock); + __release(&send_cq->lock); + } else if (unlikely(send_cq != NULL && recv_cq == NULL)) { + __release(&recv_cq->lock); + spin_unlock(&send_cq->lock); + } else if (unlikely(send_cq == NULL && recv_cq != NULL)) { + __release(&send_cq->lock); + spin_unlock(&recv_cq->lock); + } else if (send_cq == recv_cq) { __release(&recv_cq->lock); spin_unlock_irq(&send_cq->lock); } else if (send_cq->cqn < recv_cq->cqn) { @@ -1289,7 +1484,7 @@ u32 cur; cur = hr_wq->head - hr_wq->tail; - if (likely(cur + nreq < hr_wq->max_post)) + if (likely(cur + nreq < hr_wq->wqe_cnt)) return false; hr_cq = to_hr_cq(ib_cq); @@ -1297,7 +1492,7 @@ cur = hr_wq->head - hr_wq->tail; spin_unlock(&hr_cq->lock); - return cur + nreq >= hr_wq->max_post; + return cur + nreq >= hr_wq->wqe_cnt; } int hns_roce_init_qp_table(struct hns_roce_dev *hr_dev) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_restrack.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_restrack.c @@ -95,14 +95,18 @@ ret = hr_dev->dfx->query_cqc_info(hr_dev, hr_cq->cqn, (int *)context); if (ret) - goto err; + return -EINVAL; table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER); - if (!table_attr) + if (!table_attr) { + ret = -EMSGSIZE; goto err; + } - if (hns_roce_fill_cq(msg, context)) + if (hns_roce_fill_cq(msg, context)) { + ret = -EMSGSIZE; goto err_cancel_table; + } nla_nest_end(msg, table_attr); kfree(context); @@ -113,7 +117,7 @@ nla_nest_cancel(msg, table_attr); err: kfree(context); - return -EMSGSIZE; + return ret; } int hns_roce_fill_res_entry(struct sk_buff *msg, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/hns/hns_roce_srq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/hns/hns_roce_srq.c @@ -59,21 +59,21 @@ } } -static int hns_roce_sw2hw_srq(struct hns_roce_dev *dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long srq_num) +static int hns_roce_hw_create_srq(struct hns_roce_dev *dev, + struct hns_roce_cmd_mailbox *mailbox, + unsigned long srq_num) { return hns_roce_cmd_mbox(dev, mailbox->dma, 0, srq_num, 0, - HNS_ROCE_CMD_SW2HW_SRQ, + HNS_ROCE_CMD_CREATE_SRQ, HNS_ROCE_CMD_TIMEOUT_MSECS); } -static int hns_roce_hw2sw_srq(struct hns_roce_dev *dev, - struct hns_roce_cmd_mailbox *mailbox, - unsigned long srq_num) +static int hns_roce_hw_destroy_srq(struct hns_roce_dev *dev, + struct hns_roce_cmd_mailbox *mailbox, + unsigned long srq_num) { return hns_roce_cmd_mbox(dev, 0, mailbox ? mailbox->dma : 0, srq_num, - mailbox ? 0 : 1, HNS_ROCE_CMD_HW2SW_SRQ, + mailbox ? 0 : 1, HNS_ROCE_CMD_DESTROY_SRQ, HNS_ROCE_CMD_TIMEOUT_MSECS); } @@ -95,8 +95,7 @@ srq->mtt.first_seg, &dma_handle_wqe); if (!mtts_wqe) { - dev_err(hr_dev->dev, - "SRQ alloc.Failed to find srq buf addr.\n"); + dev_err(hr_dev->dev, "Failed to find mtt for srq buf.\n"); return -EINVAL; } @@ -106,13 +105,14 @@ &dma_handle_idx); if (!mtts_idx) { dev_err(hr_dev->dev, - "SRQ alloc.Failed to find idx que buf addr.\n"); + "Failed to find mtt for srq idx queue buf.\n"); return -EINVAL; } ret = hns_roce_bitmap_alloc(&srq_table->bitmap, &srq->srqn); - if (ret == -1) { - dev_err(hr_dev->dev, "SRQ alloc.Failed to alloc index.\n"); + if (ret) { + dev_err(hr_dev->dev, + "Failed to alloc a bit from srq bitmap.\n"); return -ENOMEM; } @@ -134,7 +134,7 @@ mtts_wqe, mtts_idx, dma_handle_wqe, dma_handle_idx); - ret = hns_roce_sw2hw_srq(hr_dev, mailbox, srq->srqn); + ret = hns_roce_hw_create_srq(hr_dev, mailbox, srq->srqn); hns_roce_free_cmd_mailbox(hr_dev, mailbox); if (ret) goto err_xa; @@ -160,9 +160,9 @@ struct hns_roce_srq_table *srq_table = &hr_dev->srq_table; int ret; - ret = hns_roce_hw2sw_srq(hr_dev, NULL, srq->srqn); + ret = hns_roce_hw_destroy_srq(hr_dev, NULL, srq->srqn); if (ret) - dev_err(hr_dev->dev, "HW2SW_SRQ failed (%d) for CQN %06lx\n", + dev_err(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n", ret, srq->srqn); xa_erase(&srq_table->xa, srq->srqn); @@ -180,22 +180,24 @@ { struct hns_roce_dev *hr_dev = to_hr_dev(srq->ibsrq.device); struct hns_roce_ib_create_srq ucmd; - u32 page_shift; - u32 npages; + struct hns_roce_buf *buf; int ret; if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) return -EFAULT; - srq->umem = ib_umem_get(udata, ucmd.buf_addr, srq_buf_size, 0, 0); + srq->umem = + ib_umem_get(srq->ibsrq.device, ucmd.buf_addr, srq_buf_size, 0); if (IS_ERR(srq->umem)) return PTR_ERR(srq->umem); - npages = (ib_umem_page_count(srq->umem) + - (1 << hr_dev->caps.srqwqe_buf_pg_sz) - 1) / - (1 << hr_dev->caps.srqwqe_buf_pg_sz); - page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz; - ret = hns_roce_mtt_init(hr_dev, npages, page_shift, &srq->mtt); + buf = &srq->buf; + buf->npages = (ib_umem_page_count(srq->umem) + + (1 << hr_dev->caps.srqwqe_buf_pg_sz) - 1) / + (1 << hr_dev->caps.srqwqe_buf_pg_sz); + buf->page_shift = PAGE_SHIFT + hr_dev->caps.srqwqe_buf_pg_sz; + ret = hns_roce_mtt_init(hr_dev, buf->npages, buf->page_shift, + &srq->mtt); if (ret) goto err_user_buf; @@ -204,17 +206,20 @@ goto err_user_srq_mtt; /* config index queue BA */ - srq->idx_que.umem = ib_umem_get(udata, ucmd.que_addr, - srq->idx_que.buf_size, 0, 0); + srq->idx_que.umem = ib_umem_get(srq->ibsrq.device, ucmd.que_addr, + srq->idx_que.buf_size, 0); if (IS_ERR(srq->idx_que.umem)) { dev_err(hr_dev->dev, "ib_umem_get error for index queue\n"); ret = PTR_ERR(srq->idx_que.umem); goto err_user_srq_mtt; } - ret = hns_roce_mtt_init(hr_dev, ib_umem_page_count(srq->idx_que.umem), - PAGE_SHIFT, &srq->idx_que.mtt); - + buf = &srq->idx_que.idx_buf; + buf->npages = DIV_ROUND_UP(ib_umem_page_count(srq->idx_que.umem), + 1 << hr_dev->caps.idx_buf_pg_sz); + buf->page_shift = PAGE_SHIFT + hr_dev->caps.idx_buf_pg_sz; + ret = hns_roce_mtt_init(hr_dev, buf->npages, buf->page_shift, + &srq->idx_que.mtt); if (ret) { dev_err(hr_dev->dev, "hns_roce_mtt_init error for idx que\n"); goto err_user_idx_mtt; @@ -251,7 +256,7 @@ struct hns_roce_dev *hr_dev = to_hr_dev(pd->device); struct hns_roce_idx_que *idx_que = &srq->idx_que; - idx_que->bitmap = bitmap_zalloc(srq->max, GFP_KERNEL); + idx_que->bitmap = bitmap_zalloc(srq->wqe_cnt, GFP_KERNEL); if (!idx_que->bitmap) return -ENOMEM; @@ -277,7 +282,7 @@ return -ENOMEM; srq->head = 0; - srq->tail = srq->max - 1; + srq->tail = srq->wqe_cnt - 1; ret = hns_roce_mtt_init(hr_dev, srq->buf.npages, srq->buf.page_shift, &srq->mtt); @@ -308,7 +313,7 @@ if (ret) goto err_kernel_idx_buf; - srq->wrid = kvmalloc_array(srq->max, sizeof(u64), GFP_KERNEL); + srq->wrid = kvmalloc_array(srq->wqe_cnt, sizeof(u64), GFP_KERNEL); if (!srq->wrid) { ret = -ENOMEM; goto err_kernel_idx_buf; @@ -354,7 +359,7 @@ } int hns_roce_create_srq(struct ib_srq *ib_srq, - struct ib_srq_init_attr *srq_init_attr, + struct ib_srq_init_attr *init_attr, struct ib_udata *udata) { struct hns_roce_dev *hr_dev = to_hr_dev(ib_srq->device); @@ -366,24 +371,25 @@ u32 cqn; /* Check the actual SRQ wqe and SRQ sge num */ - if (srq_init_attr->attr.max_wr >= hr_dev->caps.max_srq_wrs || - srq_init_attr->attr.max_sge > hr_dev->caps.max_srq_sges) + if (init_attr->attr.max_wr >= hr_dev->caps.max_srq_wrs || + init_attr->attr.max_sge > hr_dev->caps.max_srq_sges) return -EINVAL; mutex_init(&srq->mutex); spin_lock_init(&srq->lock); - srq->max = roundup_pow_of_two(srq_init_attr->attr.max_wr + 1); - srq->max_gs = srq_init_attr->attr.max_sge; + srq->wqe_cnt = roundup_pow_of_two(init_attr->attr.max_wr + 1); + srq->max_gs = init_attr->attr.max_sge; - srq_desc_size = roundup_pow_of_two(max(16, 16 * srq->max_gs)); + srq_desc_size = roundup_pow_of_two(max(HNS_ROCE_SGE_SIZE, + HNS_ROCE_SGE_SIZE * srq->max_gs)); srq->wqe_shift = ilog2(srq_desc_size); - srq_buf_size = srq->max * srq_desc_size; + srq_buf_size = srq->wqe_cnt * srq_desc_size; srq->idx_que.entry_sz = HNS_ROCE_IDX_QUE_ENTRY_SZ; - srq->idx_que.buf_size = srq->max * srq->idx_que.entry_sz; + srq->idx_que.buf_size = srq->wqe_cnt * srq->idx_que.entry_sz; srq->mtt.mtt_type = MTT_TYPE_SRQWQE; srq->idx_que.mtt.mtt_type = MTT_TYPE_IDX; @@ -401,8 +407,8 @@ } } - cqn = ib_srq_has_cq(srq_init_attr->srq_type) ? - to_hr_cq(srq_init_attr->ext.cq)->cqn : 0; + cqn = ib_srq_has_cq(init_attr->srq_type) ? + to_hr_cq(init_attr->ext.cq)->cqn : 0; srq->db_reg_l = hr_dev->reg_base + SRQ_DB_REG; @@ -449,7 +455,7 @@ hns_roce_mtt_cleanup(hr_dev, &srq->idx_que.mtt); } else { kvfree(srq->wrid); - hns_roce_buf_free(hr_dev, srq->max << srq->wqe_shift, + hns_roce_buf_free(hr_dev, srq->wqe_cnt << srq->wqe_shift, &srq->buf); } ib_umem_release(srq->idx_que.umem); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw.h @@ -398,8 +398,8 @@ } /* i40iw.c */ -void i40iw_add_ref(struct ib_qp *); -void i40iw_rem_ref(struct ib_qp *); +void i40iw_qp_add_ref(struct ib_qp *ibqp); +void i40iw_qp_rem_ref(struct ib_qp *ibqp); struct ib_qp *i40iw_get_qp(struct ib_device *, int); void i40iw_flush_wqes(struct i40iw_device *iwdev, @@ -411,9 +411,8 @@ bool ipv4, u32 action); -int i40iw_manage_apbvt(struct i40iw_device *iwdev, - u16 accel_local_port, - bool add_port); +enum i40iw_status_code i40iw_manage_apbvt(struct i40iw_device *iwdev, + u16 accel_local_port, bool add_port); struct i40iw_cqp_request *i40iw_get_cqp_request(struct i40iw_cqp *cqp, bool wait); void i40iw_free_cqp_request(struct i40iw_cqp *cqp, struct i40iw_cqp_request *cqp_request); @@ -543,9 +542,8 @@ bool wait); void i40iw_receive_ilq(struct i40iw_sc_vsi *vsi, struct i40iw_puda_buf *rbuf); void i40iw_free_sqbuf(struct i40iw_sc_vsi *vsi, void *bufp); -void i40iw_free_qp_resources(struct i40iw_device *iwdev, - struct i40iw_qp *iwqp, - u32 qp_num); +void i40iw_free_qp_resources(struct i40iw_qp *iwqp); + enum i40iw_status_code i40iw_obj_aligned_mem(struct i40iw_device *iwdev, struct i40iw_dma_mem *memptr, u32 size, u32 mask); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1987,7 +1987,6 @@ struct rtable *rt; struct neighbour *neigh; int rc = arpindex; - struct net_device *netdev = iwdev->netdev; __be32 dst_ipaddr = htonl(dst_ip); __be32 src_ipaddr = htonl(src_ip); @@ -1997,9 +1996,6 @@ return rc; } - if (netif_is_bond_slave(netdev)) - netdev = netdev_master_upper_dev_get(netdev); - neigh = dst_neigh_lookup(&rt->dst, &dst_ipaddr); rcu_read_lock(); @@ -2065,7 +2061,6 @@ { struct neighbour *neigh; int rc = arpindex; - struct net_device *netdev = iwdev->netdev; struct dst_entry *dst; struct sockaddr_in6 dst_addr; struct sockaddr_in6 src_addr; @@ -2079,16 +2074,13 @@ dst = i40iw_get_dst_ipv6(&src_addr, &dst_addr); if (!dst || dst->error) { if (dst) { - dst_release(dst); i40iw_pr_err("ip6_route_output returned dst->error = %d\n", dst->error); + dst_release(dst); } return rc; } - if (netif_is_bond_slave(netdev)) - netdev = netdev_master_upper_dev_get(netdev); - neigh = dst_neigh_lookup(dst, dst_addr.sin6_addr.in6_u.u6_addr32); rcu_read_lock(); @@ -2330,7 +2322,7 @@ iwqp = cm_node->iwqp; if (iwqp) { iwqp->cm_node = NULL; - i40iw_rem_ref(&iwqp->ibqp); + i40iw_qp_rem_ref(&iwqp->ibqp); cm_node->iwqp = NULL; } else if (cm_node->qhash_set) { i40iw_get_addr_info(cm_node, &nfo); @@ -3460,7 +3452,7 @@ kfree(work); return; } - i40iw_add_ref(&iwqp->ibqp); + i40iw_qp_add_ref(&iwqp->ibqp); spin_unlock_irqrestore(&iwdev->qptable_lock, flags); work->iwqp = iwqp; @@ -3631,7 +3623,7 @@ kfree(dwork); i40iw_cm_disconn_true(iwqp); - i40iw_rem_ref(&iwqp->ibqp); + i40iw_qp_rem_ref(&iwqp->ibqp); } /** @@ -3753,7 +3745,7 @@ cm_node->lsmm_size = accept.size + conn_param->private_data_len; i40iw_cm_init_tsa_conn(iwqp, cm_node); cm_id->add_ref(cm_id); - i40iw_add_ref(&iwqp->ibqp); + i40iw_qp_add_ref(&iwqp->ibqp); attr.qp_state = IB_QPS_RTS; cm_node->qhash_set = false; @@ -3916,7 +3908,7 @@ iwqp->cm_node = cm_node; cm_node->iwqp = iwqp; iwqp->cm_id = cm_id; - i40iw_add_ref(&iwqp->ibqp); + i40iw_qp_add_ref(&iwqp->ibqp); if (cm_node->state != I40IW_CM_STATE_OFFLOADED) { cm_node->state = I40IW_CM_STATE_SYN_SENT; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_ctrl.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_ctrl.c @@ -2945,6 +2945,9 @@ u64 header; enum i40iw_page_size page_size; + if (!info->total_len && !info->all_memory) + return -EINVAL; + page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K; cqp = dev->cqp; wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch); @@ -3003,6 +3006,9 @@ u8 addr_type; enum i40iw_page_size page_size; + if (!info->total_len && !info->all_memory) + return -EINVAL; + page_size = (info->page_size == 0x200000) ? I40IW_PAGE_SIZE_2M : I40IW_PAGE_SIZE_4K; if (info->access_rights & (I40IW_ACCESS_FLAGS_REMOTEREAD_ONLY | I40IW_ACCESS_FLAGS_REMOTEWRITE_ONLY)) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_hw.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_hw.c @@ -313,7 +313,7 @@ __func__, info->qp_cq_id); continue; } - i40iw_add_ref(&iwqp->ibqp); + i40iw_qp_add_ref(&iwqp->ibqp); spin_unlock_irqrestore(&iwdev->qptable_lock, flags); qp = &iwqp->sc_qp; spin_lock_irqsave(&iwqp->lock, flags); @@ -427,7 +427,7 @@ break; } if (info->qp) - i40iw_rem_ref(&iwqp->ibqp); + i40iw_qp_rem_ref(&iwqp->ibqp); } while (1); if (aeqcnt) @@ -534,7 +534,7 @@ int arp_index; arp_index = i40iw_arp_table(iwdev, ip_addr, ipv4, mac_addr, action); - if (arp_index == -1) + if (arp_index < 0) return; cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false); if (!cqp_request) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_main.c @@ -54,10 +54,6 @@ #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \ __stringify(DRV_VERSION_MINOR) "." __stringify(DRV_VERSION_BUILD) -static int push_mode; -module_param(push_mode, int, 0644); -MODULE_PARM_DESC(push_mode, "Low latency mode: 0=disabled (default), 1=enabled)"); - static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "debug flags: 0=disabled (default), 0x7fffffff=all"); @@ -1225,6 +1221,8 @@ const struct in_ifaddr *ifa; idev = in_dev_get(dev); + if (!idev) + continue; in_dev_for_each_ifa_rtnl(ifa, idev) { i40iw_debug(&iwdev->sc_dev, I40IW_DEBUG_CM, "IP=%pI4, vlan_id=%d, MAC=%pM\n", &ifa->ifa_address, @@ -1586,7 +1584,6 @@ if (status) goto exit; iwdev->obj_next = iwdev->obj_mem; - iwdev->push_mode = push_mode; init_waitqueue_head(&iwdev->vchnl_waitq); init_waitqueue_head(&dev->vf_reqs); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_pble.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_pble.c @@ -392,12 +392,9 @@ i40iw_debug(dev, I40IW_DEBUG_PBLE, "next_fpm_addr = %llx chunk_size[%u] = 0x%x\n", pble_rsrc->next_fpm_addr, chunk->size, chunk->size); pble_rsrc->unallocated_pble -= (chunk->size >> 3); - list_add(&chunk->list, &pble_rsrc->pinfo.clist); sd_reg_val = (sd_entry_type == I40IW_SD_TYPE_PAGED) ? sd_entry->u.pd_table.pd_page_addr.pa : sd_entry->u.bp.addr.pa; - if (sd_entry->valid) - return 0; - if (dev->is_pf) { + if (dev->is_pf && !sd_entry->valid) { ret_code = i40iw_hmc_sd_one(dev, hmc_info->hmc_fn_id, sd_reg_val, idx->sd_idx, sd_entry->entry_type, true); @@ -408,6 +405,7 @@ } sd_entry->valid = true; + list_add(&chunk->list, &pble_rsrc->pinfo.clist); return 0; error: kfree(chunk); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_type.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_type.h @@ -779,6 +779,7 @@ bool use_hmc_fcn_index; u8 hmc_fcn_index; bool use_pf_rid; + bool all_memory; }; struct i40iw_reg_ns_stag_info { @@ -797,6 +798,7 @@ bool use_hmc_fcn_index; u8 hmc_fcn_index; bool use_pf_rid; + bool all_memory; }; struct i40iw_fast_reg_stag_info { --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_utils.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_utils.c @@ -480,25 +480,6 @@ } /** - * i40iw_free_qp - callback after destroy cqp completes - * @cqp_request: cqp request for destroy qp - * @num: not used - */ -static void i40iw_free_qp(struct i40iw_cqp_request *cqp_request, u32 num) -{ - struct i40iw_sc_qp *qp = (struct i40iw_sc_qp *)cqp_request->param; - struct i40iw_qp *iwqp = (struct i40iw_qp *)qp->back_qp; - struct i40iw_device *iwdev; - u32 qp_num = iwqp->ibqp.qp_num; - - iwdev = iwqp->iwdev; - - i40iw_rem_pdusecount(iwqp->iwpd, iwdev); - i40iw_free_qp_resources(iwdev, iwqp, qp_num); - i40iw_rem_devusecount(iwdev); -} - -/** * i40iw_wait_event - wait for completion * @iwdev: iwarp device * @cqp_request: cqp request to wait @@ -618,26 +599,23 @@ } /** - * i40iw_add_ref - add refcount for qp + * i40iw_qp_add_ref - add refcount for qp * @ibqp: iqarp qp */ -void i40iw_add_ref(struct ib_qp *ibqp) +void i40iw_qp_add_ref(struct ib_qp *ibqp) { struct i40iw_qp *iwqp = (struct i40iw_qp *)ibqp; - atomic_inc(&iwqp->refcount); + refcount_inc(&iwqp->refcount); } /** - * i40iw_rem_ref - rem refcount for qp and free if 0 + * i40iw_qp_rem_ref - rem refcount for qp and free if 0 * @ibqp: iqarp qp */ -void i40iw_rem_ref(struct ib_qp *ibqp) +void i40iw_qp_rem_ref(struct ib_qp *ibqp) { struct i40iw_qp *iwqp; - enum i40iw_status_code status; - struct i40iw_cqp_request *cqp_request; - struct cqp_commands_info *cqp_info; struct i40iw_device *iwdev; u32 qp_num; unsigned long flags; @@ -645,7 +623,7 @@ iwqp = to_iwqp(ibqp); iwdev = iwqp->iwdev; spin_lock_irqsave(&iwdev->qptable_lock, flags); - if (!atomic_dec_and_test(&iwqp->refcount)) { + if (!refcount_dec_and_test(&iwqp->refcount)) { spin_unlock_irqrestore(&iwdev->qptable_lock, flags); return; } @@ -653,25 +631,8 @@ qp_num = iwqp->ibqp.qp_num; iwdev->qp_table[qp_num] = NULL; spin_unlock_irqrestore(&iwdev->qptable_lock, flags); - cqp_request = i40iw_get_cqp_request(&iwdev->cqp, false); - if (!cqp_request) - return; - - cqp_request->callback_fcn = i40iw_free_qp; - cqp_request->param = (void *)&iwqp->sc_qp; - cqp_info = &cqp_request->info; - cqp_info->cqp_cmd = OP_QP_DESTROY; - cqp_info->post_sq = 1; - cqp_info->in.u.qp_destroy.qp = &iwqp->sc_qp; - cqp_info->in.u.qp_destroy.scratch = (uintptr_t)cqp_request; - cqp_info->in.u.qp_destroy.remove_hash_idx = true; - status = i40iw_handle_cqp_op(iwdev, cqp_request); - if (!status) - return; + complete(&iwqp->free_qp); - i40iw_rem_pdusecount(iwqp->iwpd, iwdev); - i40iw_free_qp_resources(iwdev, iwqp, qp_num); - i40iw_rem_devusecount(iwdev); } /** @@ -938,7 +899,7 @@ struct i40iw_sc_qp *qp = (struct i40iw_sc_qp *)&iwqp->sc_qp; i40iw_terminate_done(qp, 1); - i40iw_rem_ref(&iwqp->ibqp); + i40iw_qp_rem_ref(&iwqp->ibqp); } /** @@ -950,7 +911,7 @@ struct i40iw_qp *iwqp; iwqp = (struct i40iw_qp *)qp->back_qp; - i40iw_add_ref(&iwqp->ibqp); + i40iw_qp_add_ref(&iwqp->ibqp); timer_setup(&iwqp->terminate_timer, i40iw_terminate_timeout, 0); iwqp->terminate_timer.expires = jiffies + HZ; add_timer(&iwqp->terminate_timer); @@ -966,7 +927,7 @@ iwqp = (struct i40iw_qp *)qp->back_qp; if (del_timer(&iwqp->terminate_timer)) - i40iw_rem_ref(&iwqp->ibqp); + i40iw_qp_rem_ref(&iwqp->ibqp); } /** --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_verbs.c @@ -168,38 +168,16 @@ */ static int i40iw_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) { - struct i40iw_ucontext *ucontext; - u64 db_addr_offset; - u64 push_offset; - - ucontext = to_ucontext(context); - if (ucontext->iwdev->sc_dev.is_pf) { - db_addr_offset = I40IW_DB_ADDR_OFFSET; - push_offset = I40IW_PUSH_OFFSET; - if (vma->vm_pgoff) - vma->vm_pgoff += I40IW_PF_FIRST_PUSH_PAGE_INDEX - 1; - } else { - db_addr_offset = I40IW_VF_DB_ADDR_OFFSET; - push_offset = I40IW_VF_PUSH_OFFSET; - if (vma->vm_pgoff) - vma->vm_pgoff += I40IW_VF_FIRST_PUSH_PAGE_INDEX - 1; - } + struct i40iw_ucontext *ucontext = to_ucontext(context); + u64 dbaddr; - vma->vm_pgoff += db_addr_offset >> PAGE_SHIFT; + if (vma->vm_pgoff || vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; - if (vma->vm_pgoff == (db_addr_offset >> PAGE_SHIFT)) { - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - vma->vm_private_data = ucontext; - } else { - if ((vma->vm_pgoff - (push_offset >> PAGE_SHIFT)) % 2) - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - else - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - } + dbaddr = I40IW_DB_ADDR_OFFSET + pci_resource_start(ucontext->iwdev->ldev->pcidev, 0); - if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff + (pci_resource_start(ucontext->iwdev->ldev->pcidev, 0) >> PAGE_SHIFT), - PAGE_SIZE, vma->vm_page_prot)) + if (io_remap_pfn_range(vma, vma->vm_start, dbaddr >> PAGE_SHIFT, PAGE_SIZE, + pgprot_noncached(vma->vm_page_prot))) return -EAGAIN; return 0; @@ -366,11 +344,11 @@ * @iwqp: qp ptr (user or kernel) * @qp_num: qp number assigned */ -void i40iw_free_qp_resources(struct i40iw_device *iwdev, - struct i40iw_qp *iwqp, - u32 qp_num) +void i40iw_free_qp_resources(struct i40iw_qp *iwqp) { struct i40iw_pbl *iwpbl = &iwqp->iwpbl; + struct i40iw_device *iwdev = iwqp->iwdev; + u32 qp_num = iwqp->ibqp.qp_num; i40iw_ieq_cleanup_qp(iwdev->vsi.ieq, &iwqp->sc_qp); i40iw_dealloc_push_page(iwdev, &iwqp->sc_qp); @@ -404,6 +382,10 @@ static int i40iw_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) { struct i40iw_qp *iwqp = to_iwqp(ibqp); + struct ib_qp_attr attr; + struct i40iw_device *iwdev = iwqp->iwdev; + + memset(&attr, 0, sizeof(attr)); iwqp->destroyed = 1; @@ -418,7 +400,15 @@ } } - i40iw_rem_ref(&iwqp->ibqp); + attr.qp_state = IB_QPS_ERR; + i40iw_modify_qp(&iwqp->ibqp, &attr, IB_QP_STATE, NULL); + i40iw_qp_rem_ref(&iwqp->ibqp); + wait_for_completion(&iwqp->free_qp); + i40iw_cqp_qp_destroy_cmd(&iwdev->sc_dev, &iwqp->sc_qp); + i40iw_rem_pdusecount(iwqp->iwpd, iwdev); + i40iw_free_qp_resources(iwqp); + i40iw_rem_devusecount(iwdev); + return 0; } @@ -579,6 +569,7 @@ qp->back_qp = (void *)iwqp; qp->push_idx = I40IW_INVALID_PUSH_PAGE_INDEX; + iwqp->iwdev = iwdev; iwqp->ctx_info.iwarp_info = &iwqp->iwarp_info; if (i40iw_allocate_dma_mem(dev->hw, @@ -603,7 +594,6 @@ goto error; } - iwqp->iwdev = iwdev; iwqp->iwpd = iwpd; iwqp->ibqp.qp_num = qp_num; qp = &iwqp->sc_qp; @@ -717,7 +707,7 @@ goto error; } - i40iw_add_ref(&iwqp->ibqp); + refcount_set(&iwqp->refcount, 1); spin_lock_init(&iwqp->lock); iwqp->sig_all = (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) ? 1 : 0; iwdev->qp_table[qp_num] = iwqp; @@ -739,10 +729,11 @@ } init_completion(&iwqp->sq_drained); init_completion(&iwqp->rq_drained); + init_completion(&iwqp->free_qp); return &iwqp->ibqp; error: - i40iw_free_qp_resources(iwdev, iwqp, qp_num); + i40iw_free_qp_resources(iwqp); return ERR_PTR(err_code); } @@ -1509,7 +1500,8 @@ static int i40iw_hw_alloc_stag(struct i40iw_device *iwdev, struct i40iw_mr *iwmr) { struct i40iw_allocate_stag_info *info; - struct i40iw_pd *iwpd = to_iwpd(iwmr->ibmr.pd); + struct ib_pd *pd = iwmr->ibmr.pd; + struct i40iw_pd *iwpd = to_iwpd(pd); enum i40iw_status_code status; int err = 0; struct i40iw_cqp_request *cqp_request; @@ -1526,6 +1518,7 @@ info->stag_idx = iwmr->stag >> I40IW_CQPSQ_STAG_IDX_SHIFT; info->pd_id = iwpd->sc_pd.pd_id; info->total_len = iwmr->length; + info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; info->remote_access = true; cqp_info->cqp_cmd = OP_ALLOC_STAG; cqp_info->post_sq = 1; @@ -1579,6 +1572,8 @@ iwmr->type = IW_MEMREG_TYPE_MEM; palloc = &iwpbl->pble_alloc; iwmr->page_cnt = max_num_sg; + /* Use system PAGE_SIZE as the sg page sizes are unknown at this point */ + iwmr->length = max_num_sg * PAGE_SIZE; mutex_lock(&iwdev->pbl_mutex); status = i40iw_get_pble(&iwdev->sc_dev, iwdev->pble_rsrc, palloc, iwmr->page_cnt); mutex_unlock(&iwdev->pbl_mutex); @@ -1675,7 +1670,8 @@ { struct i40iw_pbl *iwpbl = &iwmr->iwpbl; struct i40iw_reg_ns_stag_info *stag_info; - struct i40iw_pd *iwpd = to_iwpd(iwmr->ibmr.pd); + struct ib_pd *pd = iwmr->ibmr.pd; + struct i40iw_pd *iwpd = to_iwpd(pd); struct i40iw_pble_alloc *palloc = &iwpbl->pble_alloc; enum i40iw_status_code status; int err = 0; @@ -1695,6 +1691,7 @@ stag_info->total_len = iwmr->length; stag_info->access_rights = access; stag_info->pd_id = iwpd->sc_pd.pd_id; + stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; stag_info->addr_type = I40IW_ADDR_TYPE_VA_BASED; stag_info->page_size = iwmr->page_size; @@ -1763,7 +1760,7 @@ if (length > I40IW_MAX_MR_SIZE) return ERR_PTR(-EINVAL); - region = ib_umem_get(udata, start, length, acc, 0); + region = ib_umem_get(pd->device, start, length, acc); if (IS_ERR(region)) return (struct ib_mr *)region; @@ -2654,13 +2651,13 @@ .get_hw_stats = i40iw_get_hw_stats, .get_port_immutable = i40iw_port_immutable, .iw_accept = i40iw_accept, - .iw_add_ref = i40iw_add_ref, + .iw_add_ref = i40iw_qp_add_ref, .iw_connect = i40iw_connect, .iw_create_listen = i40iw_create_listen, .iw_destroy_listen = i40iw_destroy_listen, .iw_get_qp = i40iw_get_qp, .iw_reject = i40iw_reject, - .iw_rem_ref = i40iw_rem_ref, + .iw_rem_ref = i40iw_qp_rem_ref, .map_mr_sg = i40iw_map_mr_sg, .mmap = i40iw_mmap, .modify_qp = i40iw_modify_qp, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/i40iw/i40iw_verbs.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/i40iw/i40iw_verbs.h @@ -140,7 +140,7 @@ struct i40iw_qp_host_ctx_info ctx_info; struct i40iwarp_offload_info iwarp_info; void *allocated_buffer; - atomic_t refcount; + refcount_t refcount; struct iw_cm_id *cm_id; void *cm_node; struct ib_mr *lsmm_mr; @@ -175,5 +175,6 @@ struct i40iw_dma_mem ietf_mem; struct completion sq_drained; struct completion rq_drained; + struct completion free_qp; }; #endif --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/alias_GUID.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/alias_GUID.c @@ -832,7 +832,7 @@ int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev) { - char alias_wq_name[15]; + char alias_wq_name[22]; int ret = 0; int i, j; union ib_gid gid; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/cm.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/cm.c @@ -186,23 +186,6 @@ kfree(ent); } -static void id_map_find_del(struct ib_device *ibdev, int pv_cm_id) -{ - struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov; - struct rb_root *sl_id_map = &sriov->sl_id_map; - struct id_map_entry *ent, *found_ent; - - spin_lock(&sriov->id_map_lock); - ent = xa_erase(&sriov->pv_id_table, pv_cm_id); - if (!ent) - goto out; - found_ent = id_map_find_by_sl_id(ibdev, ent->slave_id, ent->sl_cm_id); - if (found_ent && found_ent == ent) - rb_erase(&found_ent->node, sl_id_map); -out: - spin_unlock(&sriov->id_map_lock); -} - static void sl_id_map_add(struct ib_device *ibdev, struct id_map_entry *new) { struct rb_root *sl_id_map = &to_mdev(ibdev)->sriov.sl_id_map; @@ -294,9 +277,12 @@ spin_lock(&sriov->id_map_lock); spin_lock_irqsave(&sriov->going_down_lock, flags); /*make sure that there is no schedule inside the scheduled work.*/ - if (!sriov->is_going_down) { + if (!sriov->is_going_down && !id->scheduled_delete) { id->scheduled_delete = 1; schedule_delayed_work(&id->timeout, CM_CLEANUP_CACHE_TIMEOUT); + } else if (id->scheduled_delete) { + /* Adjust timeout if already scheduled */ + mod_delayed_work(system_wq, &id->timeout, CM_CLEANUP_CACHE_TIMEOUT); } spin_unlock_irqrestore(&sriov->going_down_lock, flags); spin_unlock(&sriov->id_map_lock); @@ -341,9 +327,6 @@ if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID) schedule_delayed(ibdev, id); - else if (mad->mad_hdr.attr_id == CM_DREP_ATTR_ID) - id_map_find_del(ibdev, pv_cm_id); - return 0; } @@ -382,12 +365,9 @@ *slave = id->slave_id; set_remote_comm_id(mad, id->sl_cm_id); - if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID) + if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID || + mad->mad_hdr.attr_id == CM_REJ_ATTR_ID) schedule_delayed(ibdev, id); - else if (mad->mad_hdr.attr_id == CM_REJ_ATTR_ID || - mad->mad_hdr.attr_id == CM_DREP_ATTR_ID) { - id_map_find_del(ibdev, (int) pv_cm_id); - } return 0; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/cq.c @@ -144,8 +144,8 @@ int shift; int n; - *umem = ib_umem_get(udata, buf_addr, cqe * cqe_size, - IB_ACCESS_LOCAL_WRITE, 1); + *umem = ib_umem_get(&dev->ib_dev, buf_addr, cqe * cqe_size, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(*umem)) return PTR_ERR(*umem); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/doorbell.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/doorbell.c @@ -64,7 +64,8 @@ page->user_virt = (virt & PAGE_MASK); page->refcnt = 0; - page->umem = ib_umem_get(udata, virt & PAGE_MASK, PAGE_SIZE, 0, 0); + page->umem = ib_umem_get(context->ibucontext.device, virt & PAGE_MASK, + PAGE_SIZE, 0); if (IS_ERR(page->umem)) { err = PTR_ERR(page->umem); kfree(page); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/mad.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/mad.c @@ -1307,6 +1307,18 @@ spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags); } +static void mlx4_ib_wire_comp_handler(struct ib_cq *cq, void *arg) +{ + unsigned long flags; + struct mlx4_ib_demux_pv_ctx *ctx = cq->cq_context; + struct mlx4_ib_dev *dev = to_mdev(ctx->ib_dev); + + spin_lock_irqsave(&dev->sriov.going_down_lock, flags); + if (!dev->sriov.is_going_down && ctx->state == DEMUX_PV_STATE_ACTIVE) + queue_work(ctx->wi_wq, &ctx->work); + spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags); +} + static int mlx4_ib_post_pv_qp_buf(struct mlx4_ib_demux_pv_ctx *ctx, struct mlx4_ib_demux_pv_qp *tun_qp, int index) @@ -2009,7 +2021,8 @@ cq_size *= 2; cq_attr.cqe = cq_size; - ctx->cq = ib_create_cq(ctx->ib_dev, mlx4_ib_tunnel_comp_handler, + ctx->cq = ib_create_cq(ctx->ib_dev, + create_tun ? mlx4_ib_tunnel_comp_handler : mlx4_ib_wire_comp_handler, NULL, ctx, &cq_attr); if (IS_ERR(ctx->cq)) { ret = PTR_ERR(ctx->cq); @@ -2046,6 +2059,7 @@ INIT_WORK(&ctx->work, mlx4_ib_sqp_comp_worker); ctx->wq = to_mdev(ibdev)->sriov.demux[port - 1].wq; + ctx->wi_wq = to_mdev(ibdev)->sriov.demux[port - 1].wi_wq; ret = ib_req_notify_cq(ctx->cq, IB_CQ_NEXT_COMP); if (ret) { @@ -2153,7 +2167,7 @@ struct mlx4_ib_demux_ctx *ctx, int port) { - char name[12]; + char name[21]; int ret = 0; int i; @@ -2189,7 +2203,7 @@ goto err_mcg; } - snprintf(name, sizeof name, "mlx4_ibt%d", port); + snprintf(name, sizeof(name), "mlx4_ibt%d", port); ctx->wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); if (!ctx->wq) { pr_err("Failed to create tunnelling WQ for port %d\n", port); @@ -2197,7 +2211,15 @@ goto err_wq; } - snprintf(name, sizeof name, "mlx4_ibud%d", port); + snprintf(name, sizeof(name), "mlx4_ibwi%d", port); + ctx->wi_wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); + if (!ctx->wi_wq) { + pr_err("Failed to create wire WQ for port %d\n", port); + ret = -ENOMEM; + goto err_wiwq; + } + + snprintf(name, sizeof(name), "mlx4_ibud%d", port); ctx->ud_wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); if (!ctx->ud_wq) { pr_err("Failed to create up/down WQ for port %d\n", port); @@ -2208,6 +2230,10 @@ return 0; err_udwq: + destroy_workqueue(ctx->wi_wq); + ctx->wi_wq = NULL; + +err_wiwq: destroy_workqueue(ctx->wq); ctx->wq = NULL; @@ -2255,12 +2281,14 @@ ctx->tun[i]->state = DEMUX_PV_STATE_DOWNING; } flush_workqueue(ctx->wq); + flush_workqueue(ctx->wi_wq); for (i = 0; i < dev->dev->caps.sqp_demux; i++) { destroy_pv_resources(dev, i, ctx->port, ctx->tun[i], 0); free_pv_object(dev, i, ctx->port); } kfree(ctx->tun); destroy_workqueue(ctx->ud_wq); + destroy_workqueue(ctx->wi_wq); destroy_workqueue(ctx->wq); } } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/main.c @@ -246,6 +246,13 @@ return mlx4_ib_update_gids_v1(gids, ibdev, port_num); } +static void free_gid_entry(struct gid_entry *entry) +{ + memset(&entry->gid, 0, sizeof(entry->gid)); + kfree(entry->ctx); + entry->ctx = NULL; +} + static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) { struct mlx4_ib_dev *ibdev = to_mdev(attr->device); @@ -306,6 +313,8 @@ GFP_ATOMIC); if (!gids) { ret = -ENOMEM; + *context = NULL; + free_gid_entry(&port_gid_table->gids[free]); } else { for (i = 0; i < MLX4_MAX_PORT_GIDS; i++) { memcpy(&gids[i].gid, &port_gid_table->gids[i].gid, sizeof(union ib_gid)); @@ -317,6 +326,12 @@ if (!ret && hw_update) { ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num); + if (ret) { + spin_lock_bh(&iboe->lock); + *context = NULL; + free_gid_entry(&port_gid_table->gids[free]); + spin_unlock_bh(&iboe->lock); + } kfree(gids); } @@ -346,10 +361,7 @@ if (!ctx->refcount) { unsigned int real_index = ctx->real_index; - memset(&port_gid_table->gids[real_index].gid, 0, - sizeof(port_gid_table->gids[real_index].gid)); - kfree(port_gid_table->gids[real_index].ctx); - port_gid_table->gids[real_index].ctx = NULL; + free_gid_entry(&port_gid_table->gids[real_index]); hw_update = 1; } } @@ -372,10 +384,10 @@ } spin_unlock_bh(&iboe->lock); - if (!ret && hw_update) { + if (gids) ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num); - kfree(gids); - } + + kfree(gids); return ret; } @@ -565,12 +577,9 @@ props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT; props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD; - if (!mlx4_is_slave(dev->dev)) - err = mlx4_get_internal_clock_params(dev->dev, &clock_params); - if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) { resp.response_length += sizeof(resp.hca_core_clock_offset); - if (!err && !mlx4_is_slave(dev->dev)) { + if (!mlx4_get_internal_clock_params(dev->dev, &clock_params)) { resp.comp_mask |= MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET; resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE; } @@ -769,7 +778,8 @@ props->ip_gids = true; props->gid_tbl_len = mdev->dev->caps.gid_table_len[port]; props->max_msg_sz = mdev->dev->caps.max_msg_sz; - props->pkey_tbl_len = 1; + if (mdev->dev->caps.pkey_table_len[port]) + props->pkey_tbl_len = 1; props->max_mtu = IB_MTU_4096; props->max_vl_num = 2; props->state = IB_PORT_DOWN; @@ -1146,7 +1156,8 @@ return rdma_user_mmap_io(context, vma, to_mucontext(context)->uar.pfn, PAGE_SIZE, - pgprot_noncached(vma->vm_page_prot)); + pgprot_noncached(vma->vm_page_prot), + NULL); case 1: if (dev->dev->caps.bf_reg_size == 0) @@ -1155,7 +1166,8 @@ context, vma, to_mucontext(context)->uar.pfn + dev->dev->caps.num_uars, - PAGE_SIZE, pgprot_writecombine(vma->vm_page_prot)); + PAGE_SIZE, pgprot_writecombine(vma->vm_page_prot), + NULL); case 3: { struct mlx4_clock_params params; @@ -1171,7 +1183,8 @@ params.bar) + params.offset) >> PAGE_SHIFT, - PAGE_SIZE, pgprot_noncached(vma->vm_page_prot)); + PAGE_SIZE, pgprot_noncached(vma->vm_page_prot), + NULL); } default: @@ -1480,8 +1493,9 @@ int i; for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { + union ib_flow_spec ib_spec = {}; int ret; - union ib_flow_spec ib_spec; + switch (pdefault_rules->rules_create_list[i]) { case 0: /* no rule */ @@ -3008,16 +3022,17 @@ ibdev->ib_active = false; flush_workqueue(wq); - mlx4_ib_close_sriov(ibdev); - mlx4_ib_mad_cleanup(ibdev); - ib_unregister_device(&ibdev->ib_dev); - mlx4_ib_diag_cleanup(ibdev); if (ibdev->iboe.nb.notifier_call) { if (unregister_netdevice_notifier(&ibdev->iboe.nb)) pr_warn("failure unregistering notifier\n"); ibdev->iboe.nb.notifier_call = NULL; } + mlx4_ib_close_sriov(ibdev); + mlx4_ib_mad_cleanup(ibdev); + ib_unregister_device(&ibdev->ib_dev); + mlx4_ib_diag_cleanup(ibdev); + mlx4_qp_release_range(dev, ibdev->steer_qpn_base, ibdev->steer_qpn_count); kfree(ibdev->ib_uc_qpns_bitmap); @@ -3279,7 +3294,7 @@ case MLX4_DEV_EVENT_PORT_MGMT_CHANGE: ew = kmalloc(sizeof *ew, GFP_ATOMIC); if (!ew) - break; + return; INIT_WORK(&ew->work, handle_port_mgmt_change_event); memcpy(&ew->ib_eqe, eqe, sizeof *eqe); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/mlx4_ib.h @@ -459,6 +459,7 @@ struct ib_pd *pd; struct work_struct work; struct workqueue_struct *wq; + struct workqueue_struct *wi_wq; struct mlx4_ib_demux_pv_qp qp[2]; }; @@ -466,6 +467,7 @@ struct ib_device *ib_dev; int port; struct workqueue_struct *wq; + struct workqueue_struct *wi_wq; struct workqueue_struct *ud_wq; spinlock_t ud_lock; atomic64_t subnet_prefix; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/mr.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/mr.c @@ -367,7 +367,7 @@ return block_shift; } -static struct ib_umem *mlx4_get_umem_mr(struct ib_udata *udata, u64 start, +static struct ib_umem *mlx4_get_umem_mr(struct ib_device *device, u64 start, u64 length, int access_flags) { /* @@ -398,7 +398,7 @@ up_read(¤t->mm->mmap_sem); } - return ib_umem_get(udata, start, length, access_flags, 0); + return ib_umem_get(device, start, length, access_flags); } struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, @@ -415,7 +415,7 @@ if (!mr) return ERR_PTR(-ENOMEM); - mr->umem = mlx4_get_umem_mr(udata, start, length, access_flags); + mr->umem = mlx4_get_umem_mr(pd->device, start, length, access_flags); if (IS_ERR(mr->umem)) { err = PTR_ERR(mr->umem); goto err_free; @@ -439,7 +439,6 @@ mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key; mr->ibmr.length = length; - mr->ibmr.iova = virt_addr; mr->ibmr.page_size = 1U << shift; return &mr->ibmr; @@ -504,7 +503,7 @@ mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr); ib_umem_release(mmr->umem); - mmr->umem = mlx4_get_umem_mr(udata, start, length, + mmr->umem = mlx4_get_umem_mr(mr->device, start, length, mr_access_flags); if (IS_ERR(mmr->umem)) { err = PTR_ERR(mmr->umem); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/qp.c @@ -438,9 +438,13 @@ struct mlx4_ib_qp *qp, struct mlx4_ib_create_qp *ucmd) { + u32 cnt; + /* Sanity check SQ size before proceeding */ - if ((1 << ucmd->log_sq_bb_count) > dev->dev->caps.max_wqes || - ucmd->log_sq_stride > + if (check_shl_overflow(1, ucmd->log_sq_bb_count, &cnt) || + cnt > dev->dev->caps.max_wqes) + return -EINVAL; + if (ucmd->log_sq_stride > ilog2(roundup_pow_of_two(dev->dev->caps.max_sq_desc_sz)) || ucmd->log_sq_stride < MLX4_IB_MIN_SQ_STRIDE) return -EINVAL; @@ -552,15 +556,15 @@ return (-EOPNOTSUPP); } - if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | - MLX4_IB_RX_HASH_DST_IPV4 | - MLX4_IB_RX_HASH_SRC_IPV6 | - MLX4_IB_RX_HASH_DST_IPV6 | - MLX4_IB_RX_HASH_SRC_PORT_TCP | - MLX4_IB_RX_HASH_DST_PORT_TCP | - MLX4_IB_RX_HASH_SRC_PORT_UDP | - MLX4_IB_RX_HASH_DST_PORT_UDP | - MLX4_IB_RX_HASH_INNER)) { + if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | + MLX4_IB_RX_HASH_DST_IPV4 | + MLX4_IB_RX_HASH_SRC_IPV6 | + MLX4_IB_RX_HASH_DST_IPV6 | + MLX4_IB_RX_HASH_SRC_PORT_TCP | + MLX4_IB_RX_HASH_DST_PORT_TCP | + MLX4_IB_RX_HASH_SRC_PORT_UDP | + MLX4_IB_RX_HASH_DST_PORT_UDP | + MLX4_IB_RX_HASH_INNER)) { pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", ucmd->rx_hash_fields_mask); return (-EOPNOTSUPP); @@ -916,7 +920,7 @@ qp->buf_size = (qp->rq.wqe_cnt << qp->rq.wqe_shift) + (qp->sq.wqe_cnt << qp->sq.wqe_shift); - qp->umem = ib_umem_get(udata, wq.buf_addr, qp->buf_size, 0, 0); + qp->umem = ib_umem_get(pd->device, wq.buf_addr, qp->buf_size, 0); if (IS_ERR(qp->umem)) { err = PTR_ERR(qp->umem); goto err; @@ -1111,7 +1115,7 @@ goto err; qp->umem = - ib_umem_get(udata, ucmd.buf_addr, qp->buf_size, 0, 0); + ib_umem_get(pd->device, ucmd.buf_addr, qp->buf_size, 0); if (IS_ERR(qp->umem)) { err = PTR_ERR(qp->umem); goto err; @@ -1149,8 +1153,10 @@ if (dev->steering_support == MLX4_STEERING_MODE_DEVICE_MANAGED) qp->flags |= MLX4_IB_QP_NETIF; - else + else { + err = -EINVAL; goto err; + } } err = set_kernel_sq_size(dev, &init_attr->cap, qp_type, qp); @@ -2891,6 +2897,7 @@ int send_size; int header_size; int spc; + int err; int i; if (wr->wr.opcode != IB_WR_SEND) @@ -2925,7 +2932,9 @@ sqp->ud_header.lrh.virtual_lane = 0; sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); - ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, 0, &pkey); + if (err) + return err; sqp->ud_header.bth.pkey = cpu_to_be16(pkey); if (sqp->qp.mlx4_ib_qp_type == MLX4_IB_QPT_TUN_SMI_OWNER) sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); @@ -3212,9 +3221,14 @@ } sqp->ud_header.bth.solicited_event = !!(wr->wr.send_flags & IB_SEND_SOLICITED); if (!sqp->qp.ibqp.qp_num) - ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, sqp->pkey_index, + &pkey); else - ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, &pkey); + err = ib_get_cached_pkey(ib_dev, sqp->qp.port, wr->pkey_index, + &pkey); + if (err) + return err; + sqp->ud_header.bth.pkey = cpu_to_be16(pkey); sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn); sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1)); @@ -3533,11 +3547,11 @@ int nreq; int err = 0; unsigned ind; - int uninitialized_var(size); - unsigned uninitialized_var(seglen); + int size; + unsigned seglen; __be32 dummy; __be32 *lso_wqe; - __be32 uninitialized_var(lso_hdr_sz); + __be32 lso_hdr_sz; __be32 blh; int i; struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); @@ -4286,13 +4300,8 @@ if (wq_attr_mask & IB_WQ_FLAGS) return -EOPNOTSUPP; - cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state : - ibwq->state; - new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state; - - if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR || - new_state < IB_WQS_RESET || new_state > IB_WQS_ERR) - return -EINVAL; + cur_state = wq_attr->curr_wq_state; + new_state = wq_attr->wq_state; if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR)) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/srq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/srq.c @@ -110,7 +110,8 @@ if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) return -EFAULT; - srq->umem = ib_umem_get(udata, ucmd.buf_addr, buf_size, 0, 0); + srq->umem = + ib_umem_get(ib_srq->device, ucmd.buf_addr, buf_size, 0); if (IS_ERR(srq->umem)) return PTR_ERR(srq->umem); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx4/sysfs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx4/sysfs.c @@ -221,7 +221,7 @@ static int add_port_entries(struct mlx4_ib_dev *device, int port_num) { int i; - char buff[11]; + char buff[12]; struct mlx4_ib_iov_port *port = NULL; int ret = 0 ; struct ib_port_attr attr; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/cq.c @@ -167,7 +167,7 @@ { enum rdma_link_layer ll = rdma_port_get_link_layer(qp->ibqp.device, 1); struct mlx5_ib_dev *dev = to_mdev(qp->ibqp.device); - struct mlx5_ib_srq *srq; + struct mlx5_ib_srq *srq = NULL; struct mlx5_ib_wq *wq; u16 wqe_ctr; u8 roce_packet_type; @@ -179,7 +179,8 @@ if (qp->ibqp.xrcd) { msrq = mlx5_cmd_get_srq(dev, be32_to_cpu(cqe->srqn)); - srq = to_mibsrq(msrq); + if (msrq) + srq = to_mibsrq(msrq); } else { srq = to_msrq(qp->ibqp.srq); } @@ -330,6 +331,22 @@ dump_cqe(dev, cqe); } +static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64, + u16 tail, u16 head) +{ + u16 idx; + + do { + idx = tail & (qp->sq.wqe_cnt - 1); + if (idx == head) + break; + + tail = qp->sq.w_list[idx].next; + } while (1); + tail = qp->sq.w_list[idx].next; + qp->sq.last_poll = tail; +} + static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf) { mlx5_frag_buf_free(dev->mdev, &buf->frag_buf); @@ -368,7 +385,7 @@ } static void sw_comp(struct mlx5_ib_qp *qp, int num_entries, struct ib_wc *wc, - int *npolled, int is_send) + int *npolled, bool is_send) { struct mlx5_ib_wq *wq; unsigned int cur; @@ -383,10 +400,16 @@ return; for (i = 0; i < cur && np < num_entries; i++) { - wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)]; + unsigned int idx; + + idx = (is_send) ? wq->last_poll : wq->tail; + idx &= (wq->wqe_cnt - 1); + wc->wr_id = wq->wrid[idx]; wc->status = IB_WC_WR_FLUSH_ERR; wc->vendor_err = MLX5_CQE_SYNDROME_WR_FLUSH_ERR; wq->tail++; + if (is_send) + wq->last_poll = wq->w_list[idx].next; np++; wc->qp = &qp->ibqp; wc++; @@ -476,6 +499,7 @@ wqe_ctr = be16_to_cpu(cqe64->wqe_counter); idx = wqe_ctr & (wq->wqe_cnt - 1); handle_good_req(wc, cqe64, wq, idx); + handle_atomics(*cur_qp, cqe64, wq->last_poll, idx); wc->wr_id = wq->wrid[idx]; wq->tail = wq->wqe_head[idx] + 1; wc->status = IB_WC_SUCCESS; @@ -709,8 +733,9 @@ *cqe_size = ucmd.cqe_size; cq->buf.umem = - ib_umem_get(udata, ucmd.buf_addr, entries * ucmd.cqe_size, - IB_ACCESS_LOCAL_WRITE, 1); + ib_umem_get_peer(&dev->ib_dev, ucmd.buf_addr, + entries * ucmd.cqe_size, + IB_ACCESS_LOCAL_WRITE, 0); if (IS_ERR(cq->buf.umem)) { err = PTR_ERR(cq->buf.umem); return err; @@ -805,15 +830,14 @@ ib_umem_release(cq->buf.umem); } -static void init_cq_frag_buf(struct mlx5_ib_cq *cq, - struct mlx5_ib_cq_buf *buf) +static void init_cq_frag_buf(struct mlx5_ib_cq_buf *buf) { int i; void *cqe; struct mlx5_cqe64 *cqe64; for (i = 0; i < buf->nent; i++) { - cqe = get_cqe(cq, i); + cqe = mlx5_frag_buf_get_wqe(&buf->fbc, i); cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64; cqe64->op_own = MLX5_CQE_INVALID << 4; } @@ -839,7 +863,7 @@ if (err) goto err_db; - init_cq_frag_buf(cq, &cq->buf); + init_cq_frag_buf(&cq->buf); *inlen = MLX5_ST_SZ_BYTES(create_cq_in) + MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * @@ -893,8 +917,8 @@ struct mlx5_ib_dev *dev = to_mdev(ibdev); struct mlx5_ib_cq *cq = to_mcq(ibcq); u32 out[MLX5_ST_SZ_DW(create_cq_out)]; - int uninitialized_var(index); - int uninitialized_var(inlen); + int index; + int inlen; u32 *cqb = NULL; void *cqc; int cqe_size; @@ -1109,9 +1133,9 @@ if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1) return -EINVAL; - umem = ib_umem_get(udata, ucmd.buf_addr, - (size_t)ucmd.cqe_size * entries, - IB_ACCESS_LOCAL_WRITE, 1); + umem = ib_umem_get_peer(&dev->ib_dev, ucmd.buf_addr, + (size_t)ucmd.cqe_size * entries, + IB_ACCESS_LOCAL_WRITE, 0); if (IS_ERR(umem)) { err = PTR_ERR(umem); return err; @@ -1139,7 +1163,7 @@ if (err) goto ex; - init_cq_frag_buf(cq, cq->resize_buf); + init_cq_frag_buf(cq->resize_buf); return 0; @@ -1214,7 +1238,7 @@ __be64 *pas; int page_shift; int inlen; - int uninitialized_var(cqe_size); + int cqe_size; unsigned long flags; if (!MLX5_CAP_GEN(dev->mdev, cq_resize)) { --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/devx.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/devx.c @@ -100,6 +100,7 @@ struct mlx5_ib_devx_mr devx_mr; struct mlx5_core_dct core_dct; struct mlx5_core_cq core_cq; + u32 flow_counter_bulk_size; }; struct list_head event_sub; /* holds devx_event_subscription entries */ }; @@ -192,15 +193,20 @@ } } -bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id) +bool mlx5_ib_devx_is_flow_counter(void *obj, u32 offset, u32 *counter_id) { struct devx_obj *devx_obj = obj; u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode); if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) { + + if (offset && offset >= devx_obj->flow_counter_bulk_size) + return false; + *counter_id = MLX5_GET(dealloc_flow_counter_in, devx_obj->dinbox, flow_counter_id); + *counter_id += offset; return true; } @@ -489,6 +495,10 @@ obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, MLX5_GET(rst2init_qp_in, in, qpn)); break; + case MLX5_CMD_OP_INIT2INIT_QP: + obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, + MLX5_GET(init2init_qp_in, in, qpn)); + break; case MLX5_CMD_OP_INIT2RTR_QP: obj_id = get_enc_obj_id(MLX5_CMD_OP_CREATE_QP, MLX5_GET(init2rtr_qp_in, in, qpn)); @@ -814,6 +824,7 @@ case MLX5_CMD_OP_SET_L2_TABLE_ENTRY: case MLX5_CMD_OP_RST2INIT_QP: case MLX5_CMD_OP_INIT2RTR_QP: + case MLX5_CMD_OP_INIT2INIT_QP: case MLX5_CMD_OP_RTR2RTS_QP: case MLX5_CMD_OP_RTS2RTS_QP: case MLX5_CMD_OP_SQERR2RTS_QP: @@ -1113,7 +1124,9 @@ MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_RQT); break; case MLX5_CMD_OP_CREATE_TIR: - MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIR); + *obj_id = MLX5_GET(create_tir_out, out, tirn); + MLX5_SET(destroy_tir_in, din, opcode, MLX5_CMD_OP_DESTROY_TIR); + MLX5_SET(destroy_tir_in, din, tirn, *obj_id); break; case MLX5_CMD_OP_CREATE_TIS: MLX5_SET(general_obj_in_cmd_hdr, din, opcode, MLX5_CMD_OP_DESTROY_TIS); @@ -1463,6 +1476,13 @@ if (err) goto obj_free; + if (opcode == MLX5_CMD_OP_ALLOC_FLOW_COUNTER) { + u8 bulk = MLX5_GET(alloc_flow_counter_in, + cmd_in, + flow_counter_bulk); + obj->flow_counter_bulk_size = 128UL * bulk; + } + uobj->object = obj; INIT_LIST_HEAD(&obj->event_sub); obj->ib_dev = dev; @@ -1837,8 +1857,10 @@ key_level2, obj_event, GFP_KERNEL); - if (err) + if (err) { + kfree(obj_event); return err; + } INIT_LIST_HEAD(&obj_event->obj_sub_list); } @@ -2015,8 +2037,10 @@ num_alloc_xa_entries++; event_sub = kzalloc(sizeof(*event_sub), GFP_KERNEL); - if (!event_sub) + if (!event_sub) { + err = -ENOMEM; goto err; + } list_add_tail(&event_sub->event_list, &sub_list); if (use_eventfd) { @@ -2121,7 +2145,7 @@ if (err) return err; - obj->umem = ib_umem_get(&attrs->driver_udata, addr, size, access, 0); + obj->umem = ib_umem_get_peer(&dev->ib_dev, addr, size, access, 0); if (IS_ERR(obj->umem)) return PTR_ERR(obj->umem); @@ -2168,6 +2192,8 @@ mlx5_ib_populate_pas(dev, obj->umem, obj->page_shift, mtt, (obj->umem->writable ? MLX5_IB_MTT_WRITE : 0) | MLX5_IB_MTT_READ); + if (obj->umem->is_peer && MLX5_CAP_GEN(dev->mdev, ats)) + MLX5_SET(umem, umem, ats, 1); } static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_UMEM_REG)( @@ -2545,7 +2571,7 @@ { struct devx_async_event_file *ev_file = filp->private_data; struct devx_event_subscription *event_sub; - struct devx_async_event_data *uninitialized_var(event); + struct devx_async_event_data *event; int ret = 0; size_t eventsz; bool omit_data; @@ -2800,7 +2826,7 @@ MLX5_IB_METHOD_DEVX_OBJ_MODIFY, UVERBS_ATTR_IDR(MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE, UVERBS_IDR_ANY_OBJECT, - UVERBS_ACCESS_WRITE, + UVERBS_ACCESS_READ, UA_MANDATORY), UVERBS_ATTR_PTR_IN( MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/doorbell.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/doorbell.c @@ -64,7 +64,8 @@ page->user_virt = (virt & PAGE_MASK); page->refcnt = 0; - page->umem = ib_umem_get(udata, virt & PAGE_MASK, PAGE_SIZE, 0, 0); + page->umem = ib_umem_get_peer(context->ibucontext.device, virt & PAGE_MASK, + PAGE_SIZE, 0, 0); if (IS_ERR(page->umem)) { err = PTR_ERR(page->umem); kfree(page); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/flow.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/flow.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "mlx5_ib.h" #define UVERBS_MODULE_NAME mlx5_ib @@ -85,6 +86,8 @@ struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata); int len, ret, i; u32 counter_id = 0; + u32 *offset_attr; + u32 offset = 0; if (!capable(CAP_NET_RAW)) return -EPERM; @@ -151,8 +154,27 @@ if (len) { devx_obj = arr_flow_actions[0]->object; - if (!mlx5_ib_devx_is_flow_counter(devx_obj, &counter_id)) + if (uverbs_attr_is_valid(attrs, + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET)) { + + int num_offsets = uverbs_attr_ptr_get_array_size( + attrs, + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, + sizeof(u32)); + + if (num_offsets != 1) + return -EINVAL; + + offset_attr = uverbs_attr_get_alloced_ptr( + attrs, + MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET); + offset = *offset_attr; + } + + if (!mlx5_ib_devx_is_flow_counter(devx_obj, offset, + &counter_id)) return -EINVAL; + flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; } @@ -316,6 +338,13 @@ if (err) goto end; + if (obj->ns_type == MLX5_FLOW_NAMESPACE_FDB && + mlx5_eswitch_mode(dev->mdev->priv.eswitch) != + MLX5_ESWITCH_OFFLOADS) { + err = -EINVAL; + goto end; + } + uobj->object = obj; obj->mdev = dev->mdev; atomic_set(&obj->usecnt, 0); @@ -598,7 +627,11 @@ UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, MLX5_IB_OBJECT_DEVX_OBJ, UVERBS_ACCESS_READ, 1, 1, - UA_OPTIONAL)); + UA_OPTIONAL), + UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET, + UVERBS_ATTR_MIN_SIZE(sizeof(u32)), + UA_OPTIONAL, + UA_ALLOC_AND_COPY)); DECLARE_UVERBS_NAMED_METHOD_DESTROY( MLX5_IB_METHOD_DESTROY_FLOW, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/gsi.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/gsi.c @@ -507,8 +507,7 @@ ret = ib_post_send(tx_qp, &cur_wr.wr, bad_wr); if (ret) { /* Undo the effect of adding the outstanding wr */ - gsi->outstanding_pi = (gsi->outstanding_pi - 1) % - gsi->cap.max_send_wr; + gsi->outstanding_pi--; goto err; } spin_unlock_irqrestore(&gsi->lock, flags); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/ib_rep.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/ib_rep.c @@ -35,7 +35,7 @@ int vport_index; if (rep->vport == MLX5_VPORT_UPLINK) - profile = &uplink_rep_profile; + profile = &raw_eth_profile; else return mlx5_ib_set_vport_rep(dev, rep); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/ib_rep.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/ib_rep.h @@ -10,7 +10,7 @@ #include "mlx5_ib.h" #ifdef CONFIG_MLX5_ESWITCH -extern const struct mlx5_ib_profile uplink_rep_profile; +extern const struct mlx5_ib_profile raw_eth_profile; u8 mlx5_ib_eswitch_mode(struct mlx5_eswitch *esw); struct mlx5_ib_dev *mlx5_ib_get_rep_ibdev(struct mlx5_eswitch *esw, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/mad.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/mad.c @@ -219,6 +219,13 @@ mdev = dev->mdev; mdev_port_num = 1; } + if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1 && + !mlx5_core_mp_enabled(mdev)) { + /* set local port to one for Function-Per-Port HCA. */ + mdev = dev->mdev; + mdev_port_num = 1; + } + /* Declaring support of extended counters */ if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) { struct ib_class_port_info cpi = {}; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/main.c @@ -517,7 +517,7 @@ mdev_port_num); if (err) goto out; - ext = MLX5_CAP_PCAM_FEATURE(dev->mdev, ptys_extended_ethernet); + ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability); eth_prot_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper); props->active_width = IB_WIDTH_4X; @@ -829,6 +829,7 @@ struct ib_device_attr *props, struct ib_udata *uhw) { + size_t uhw_outlen = (uhw) ? uhw->outlen : 0; struct mlx5_ib_dev *dev = to_mdev(ibdev); struct mlx5_core_dev *mdev = dev->mdev; int err = -ENOMEM; @@ -842,12 +843,12 @@ u64 max_tso; resp_len = sizeof(resp.comp_mask) + sizeof(resp.response_length); - if (uhw->outlen && uhw->outlen < resp_len) + if (uhw_outlen && uhw_outlen < resp_len) return -EINVAL; else resp.response_length = resp_len; - if (uhw->inlen && !ib_is_udata_cleared(uhw, 0, uhw->inlen)) + if (uhw && uhw->inlen && !ib_is_udata_cleared(uhw, 0, uhw->inlen)) return -EINVAL; memset(props, 0, sizeof(*props)); @@ -887,7 +888,9 @@ /* We support 'Gappy' memory registration too */ props->device_cap_flags |= IB_DEVICE_SG_GAPS_REG; } - props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; + /* IB_WR_REG_MR always requires changing the entity size with UMR */ + if (!MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled)) + props->device_cap_flags |= IB_DEVICE_MEM_MGT_EXTENSIONS; if (MLX5_CAP_GEN(mdev, sho)) { props->device_cap_flags |= IB_DEVICE_INTEGRITY_HANDOVER; /* At this stage no support for signature handover */ @@ -911,7 +914,7 @@ props->raw_packet_caps |= IB_RAW_PACKET_CAP_CVLAN_STRIPPING; - if (field_avail(typeof(resp), tso_caps, uhw->outlen)) { + if (field_avail(typeof(resp), tso_caps, uhw_outlen)) { max_tso = MLX5_CAP_ETH(mdev, max_lso_cap); if (max_tso) { resp.tso_caps.max_tso = 1 << max_tso; @@ -921,7 +924,7 @@ } } - if (field_avail(typeof(resp), rss_caps, uhw->outlen)) { + if (field_avail(typeof(resp), rss_caps, uhw_outlen)) { resp.rss_caps.rx_hash_function = MLX5_RX_HASH_FUNC_TOEPLITZ; resp.rss_caps.rx_hash_fields_mask = @@ -941,9 +944,9 @@ resp.response_length += sizeof(resp.rss_caps); } } else { - if (field_avail(typeof(resp), tso_caps, uhw->outlen)) + if (field_avail(typeof(resp), tso_caps, uhw_outlen)) resp.response_length += sizeof(resp.tso_caps); - if (field_avail(typeof(resp), rss_caps, uhw->outlen)) + if (field_avail(typeof(resp), rss_caps, uhw_outlen)) resp.response_length += sizeof(resp.rss_caps); } @@ -1031,7 +1034,7 @@ if (MLX5_CAP_GEN(mdev, cd)) props->device_cap_flags |= IB_DEVICE_CROSS_CHANNEL; - if (!mlx5_core_is_pf(mdev)) + if (mlx5_core_is_vf(mdev)) props->device_cap_flags |= IB_DEVICE_VIRTUAL_FUNCTION; if (mlx5_ib_port_link_layer(ibdev, 1) == @@ -1066,7 +1069,7 @@ MLX5_MAX_CQ_PERIOD; } - if (field_avail(typeof(resp), cqe_comp_caps, uhw->outlen)) { + if (field_avail(typeof(resp), cqe_comp_caps, uhw_outlen)) { resp.response_length += sizeof(resp.cqe_comp_caps); if (MLX5_CAP_GEN(dev->mdev, cqe_compression)) { @@ -1084,7 +1087,7 @@ } } - if (field_avail(typeof(resp), packet_pacing_caps, uhw->outlen) && + if (field_avail(typeof(resp), packet_pacing_caps, uhw_outlen) && raw_support) { if (MLX5_CAP_QOS(mdev, packet_pacing) && MLX5_CAP_GEN(mdev, qos)) { @@ -1103,7 +1106,7 @@ } if (field_avail(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes, - uhw->outlen)) { + uhw_outlen)) { if (MLX5_CAP_ETH(mdev, multi_pkt_send_wqe)) resp.mlx5_ib_support_multi_pkt_send_wqes = MLX5_IB_ALLOW_MPW; @@ -1116,7 +1119,7 @@ sizeof(resp.mlx5_ib_support_multi_pkt_send_wqes); } - if (field_avail(typeof(resp), flags, uhw->outlen)) { + if (field_avail(typeof(resp), flags, uhw_outlen)) { resp.response_length += sizeof(resp.flags); if (MLX5_CAP_GEN(mdev, cqe_compression_128)) @@ -1132,8 +1135,7 @@ resp.flags |= MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT; } - if (field_avail(typeof(resp), sw_parsing_caps, - uhw->outlen)) { + if (field_avail(typeof(resp), sw_parsing_caps, uhw_outlen)) { resp.response_length += sizeof(resp.sw_parsing_caps); if (MLX5_CAP_ETH(mdev, swp)) { resp.sw_parsing_caps.sw_parsing_offloads |= @@ -1153,7 +1155,7 @@ } } - if (field_avail(typeof(resp), striding_rq_caps, uhw->outlen) && + if (field_avail(typeof(resp), striding_rq_caps, uhw_outlen) && raw_support) { resp.response_length += sizeof(resp.striding_rq_caps); if (MLX5_CAP_GEN(mdev, striding_rq)) { @@ -1170,8 +1172,7 @@ } } - if (field_avail(typeof(resp), tunnel_offloads_caps, - uhw->outlen)) { + if (field_avail(typeof(resp), tunnel_offloads_caps, uhw_outlen)) { resp.response_length += sizeof(resp.tunnel_offloads_caps); if (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan)) resp.tunnel_offloads_caps |= @@ -1182,17 +1183,15 @@ if (MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) resp.tunnel_offloads_caps |= MLX5_IB_TUNNELED_OFFLOADS_GRE; - if (MLX5_CAP_GEN(mdev, flex_parser_protocols) & - MLX5_FLEX_PROTO_CW_MPLS_GRE) + if (MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_gre)) resp.tunnel_offloads_caps |= MLX5_IB_TUNNELED_OFFLOADS_MPLS_GRE; - if (MLX5_CAP_GEN(mdev, flex_parser_protocols) & - MLX5_FLEX_PROTO_CW_MPLS_UDP) + if (MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_udp)) resp.tunnel_offloads_caps |= MLX5_IB_TUNNELED_OFFLOADS_MPLS_UDP; } - if (uhw->outlen) { + if (uhw_outlen) { err = ib_copy_to_udata(uhw, &resp, resp.response_length); if (err) @@ -2054,7 +2053,7 @@ case MLX5_IB_MMAP_DEVICE_MEM: return "Device Memory"; default: - return NULL; + return "Unknown"; } } @@ -2168,7 +2167,7 @@ mlx5_ib_dbg(dev, "uar idx 0x%lx, pfn %pa\n", idx, &pfn); err = rdma_user_mmap_io(&context->ibucontext, vma, pfn, PAGE_SIZE, - prot); + prot, NULL); if (err) { mlx5_ib_err(dev, "rdma_user_mmap_io failed with error=%d, mmap_cmd=%s\n", @@ -2210,7 +2209,8 @@ PAGE_SHIFT) + page_idx; return rdma_user_mmap_io(context, vma, pfn, map_size, - pgprot_writecombine(vma->vm_page_prot)); + pgprot_writecombine(vma->vm_page_prot), + NULL); } static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vma) @@ -2248,7 +2248,8 @@ PAGE_SHIFT; return rdma_user_mmap_io(&context->ibucontext, vma, pfn, PAGE_SIZE, - pgprot_noncached(vma->vm_page_prot)); + pgprot_noncached(vma->vm_page_prot), + NULL); case MLX5_IB_MMAP_CLOCK_INFO: return mlx5_ib_mmap_clock_info_page(dev, vma, context); @@ -3548,10 +3549,6 @@ } INIT_LIST_HEAD(&handler->list); - if (dst) { - memcpy(&dest_arr[0], dst, sizeof(*dst)); - dest_num++; - } for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) { err = parse_flow_attr(dev->mdev, spec, @@ -3564,6 +3561,11 @@ ib_flow += ((union ib_flow_spec *)ib_flow)->size; } + if (dst && !(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP)) { + memcpy(&dest_arr[0], dst, sizeof(*dst)); + dest_num++; + } + if (!flow_is_multicast_only(flow_attr)) set_underlay_qp(dev, spec, underlay_qpn); @@ -3604,10 +3606,8 @@ } if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) { - if (!(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT)) { + if (!dest_num) rule_dst = NULL; - dest_num = 0; - } } else { if (is_egress) flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW; @@ -4739,7 +4739,6 @@ struct ib_device_attr *dprops = NULL; struct ib_port_attr *pprops = NULL; int err = -ENOMEM; - struct ib_udata uhw = {.inlen = 0, .outlen = 0}; pprops = kzalloc(sizeof(*pprops), GFP_KERNEL); if (!pprops) @@ -4749,7 +4748,7 @@ if (!dprops) goto out; - err = mlx5_ib_query_device(&dev->ib_dev, dprops, &uhw); + err = mlx5_ib_query_device(&dev->ib_dev, dprops, NULL); if (err) { mlx5_ib_warn(dev, "query_device failed %d\n", err); goto out; @@ -5145,8 +5144,7 @@ immutable->pkey_tbl_len = attr.pkey_tbl_len; immutable->gid_tbl_len = attr.gid_tbl_len; immutable->core_cap_flags = get_core_cap_flags(ibdev, &rep); - if ((ll == IB_LINK_LAYER_INFINIBAND) || MLX5_CAP_GEN(dev->mdev, roce)) - immutable->max_mad_size = IB_MGMT_MAD_SIZE; + immutable->max_mad_size = IB_MGMT_MAD_SIZE; return 0; } @@ -5249,11 +5247,9 @@ { int err; - if (MLX5_CAP_GEN(dev->mdev, roce)) { - err = mlx5_nic_vport_enable_roce(dev->mdev); - if (err) - return err; - } + err = mlx5_nic_vport_enable_roce(dev->mdev); + if (err) + return err; err = mlx5_eth_lag_init(dev); if (err) @@ -5262,8 +5258,7 @@ return 0; err_disable_roce: - if (MLX5_CAP_GEN(dev->mdev, roce)) - mlx5_nic_vport_disable_roce(dev->mdev); + mlx5_nic_vport_disable_roce(dev->mdev); return err; } @@ -5271,8 +5266,7 @@ static void mlx5_disable_eth(struct mlx5_ib_dev *dev) { mlx5_eth_lag_cleanup(dev); - if (MLX5_CAP_GEN(dev->mdev, roce)) - mlx5_nic_vport_disable_roce(dev->mdev); + mlx5_nic_vport_disable_roce(dev->mdev); } struct mlx5_ib_counter { @@ -5641,9 +5635,10 @@ const struct mlx5_ib_counters *cnts = get_counters(dev, counter->port - 1); - /* Q counters are in the beginning of all counters */ return rdma_alloc_hw_stats_struct(cnts->names, - cnts->num_q_counters, + cnts->num_q_counters + + cnts->num_cong_counters + + cnts->num_ext_ppcnt_counters, RDMA_HW_STATS_DEFAULT_LIFESPAN); } @@ -5873,8 +5868,6 @@ port->mp.mpi = NULL; - list_add_tail(&mpi->list, &mlx5_ib_unaffiliated_port_list); - spin_unlock(&port->mp.mpi_lock); err = mlx5_nic_vport_unaffiliate_multiport(mpi->mdev); @@ -5984,7 +5977,8 @@ list_for_each_entry(mpi, &mlx5_ib_unaffiliated_port_list, list) { if (dev->sys_image_guid == mpi->sys_image_guid && - (mlx5_core_native_port_num(mpi->mdev) - 1) == i) { + (mlx5_core_native_port_num(mpi->mdev) - 1) == i && + mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) { bound = mlx5_ib_bind_slave_port(dev, mpi); } @@ -6027,6 +6021,8 @@ dev->port[i].mp.mpi = NULL; } else { mlx5_ib_dbg(dev, "unbinding port_num: %d\n", i + 1); + list_add_tail(&dev->port[i].mp.mpi->list, + &mlx5_ib_unaffiliated_port_list); mlx5_ib_unbind_slave_port(dev, dev->port[i].mp.mpi); } } @@ -6175,7 +6171,7 @@ err = set_has_smi_cap(dev); if (err) - return err; + goto err_mp; if (!mlx5_core_mp_enabled(mdev)) { for (i = 1; i <= dev->num_ports; i++) { @@ -6215,8 +6211,7 @@ err_mp: mlx5_ib_cleanup_multiport_master(dev); - - return -ENOMEM; + return err; } static int mlx5_ib_stage_flow_db_init(struct mlx5_ib_dev *dev) @@ -6444,7 +6439,7 @@ .query_port = mlx5_ib_rep_query_port, }; -static int mlx5_ib_stage_rep_non_default_cb(struct mlx5_ib_dev *dev) +static int mlx5_ib_stage_raw_eth_non_default_cb(struct mlx5_ib_dev *dev) { ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_port_rep_ops); return 0; @@ -6484,7 +6479,7 @@ mlx5_remove_netdev_notifier(dev, port_num); } -static int mlx5_ib_stage_rep_roce_init(struct mlx5_ib_dev *dev) +static int mlx5_ib_stage_raw_eth_roce_init(struct mlx5_ib_dev *dev) { struct mlx5_core_dev *mdev = dev->mdev; enum rdma_link_layer ll; @@ -6500,7 +6495,7 @@ return err; } -static void mlx5_ib_stage_rep_roce_cleanup(struct mlx5_ib_dev *dev) +static void mlx5_ib_stage_raw_eth_roce_cleanup(struct mlx5_ib_dev *dev) { mlx5_ib_stage_common_roce_cleanup(dev); } @@ -6628,7 +6623,7 @@ err = mlx5_alloc_bfreg(dev->mdev, &dev->fp_bfreg, false, true); if (err) - mlx5_free_bfreg(dev->mdev, &dev->fp_bfreg); + mlx5_free_bfreg(dev->mdev, &dev->bfreg); return err; } @@ -6714,6 +6709,8 @@ const struct mlx5_ib_profile *profile, int stage) { + dev->ib_active = false; + /* Number of stages to cleanup */ while (stage) { stage--; @@ -6807,7 +6804,7 @@ mlx5_ib_stage_delay_drop_cleanup), }; -const struct mlx5_ib_profile uplink_rep_profile = { +const struct mlx5_ib_profile raw_eth_profile = { STAGE_CREATE(MLX5_IB_STAGE_INIT, mlx5_ib_stage_init_init, mlx5_ib_stage_init_cleanup), @@ -6818,11 +6815,11 @@ mlx5_ib_stage_caps_init, NULL), STAGE_CREATE(MLX5_IB_STAGE_NON_DEFAULT_CB, - mlx5_ib_stage_rep_non_default_cb, + mlx5_ib_stage_raw_eth_non_default_cb, NULL), STAGE_CREATE(MLX5_IB_STAGE_ROCE, - mlx5_ib_stage_rep_roce_init, - mlx5_ib_stage_rep_roce_cleanup), + mlx5_ib_stage_raw_eth_roce_init, + mlx5_ib_stage_raw_eth_roce_cleanup), STAGE_CREATE(MLX5_IB_STAGE_SRQ, mlx5_init_srq_table, mlx5_cleanup_srq_table), @@ -6877,11 +6874,13 @@ mutex_lock(&mlx5_ib_multiport_mutex); list_for_each_entry(dev, &mlx5_ib_dev_list, ib_dev_list) { - if (dev->sys_image_guid == mpi->sys_image_guid) + if (dev->sys_image_guid == mpi->sys_image_guid && + mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) bound = mlx5_ib_bind_slave_port(dev, mpi); if (bound) { rdma_roce_rescan_device(&dev->ib_dev); + mpi->ibdev->ib_active = true; break; } } @@ -6898,6 +6897,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev) { + const struct mlx5_ib_profile *profile; enum rdma_link_layer ll; struct mlx5_ib_dev *dev; int port_type_cap; @@ -6933,7 +6933,12 @@ dev->mdev = mdev; dev->num_ports = num_ports; - return __mlx5_ib_add(dev, &pf_profile); + if (ll == IB_LINK_LAYER_ETHERNET && !mlx5_is_roce_enabled(mdev)) + profile = &raw_eth_profile; + else + profile = &pf_profile; + + return __mlx5_ib_add(dev, profile); } static void mlx5_ib_remove(struct mlx5_core_dev *mdev, void *context) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/mem.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/mem.c @@ -55,16 +55,17 @@ int i = 0; struct scatterlist *sg; int entry; + int page_shift = umem->is_peer ? umem->page_shift : PAGE_SHIFT; - addr = addr >> PAGE_SHIFT; + addr = addr >> page_shift; tmp = (unsigned long)addr; m = find_first_bit(&tmp, BITS_PER_LONG); if (max_page_shift) - m = min_t(unsigned long, max_page_shift - PAGE_SHIFT, m); + m = min_t(unsigned long, max_page_shift - page_shift, m); for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { - len = sg_dma_len(sg) >> PAGE_SHIFT; - pfn = sg_dma_address(sg) >> PAGE_SHIFT; + len = sg_dma_len(sg) >> page_shift; + pfn = sg_dma_address(sg) >> page_shift; if (base + p != pfn) { /* If either the offset or the new * base are unaligned update m @@ -96,7 +97,7 @@ *ncont = 0; } - *shift = PAGE_SHIFT + m; + *shift = page_shift + m; *count = i; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/mlx5_ib.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/mlx5_ib.h @@ -283,6 +283,7 @@ unsigned head; unsigned tail; u16 cur_post; + u16 last_poll; void *cur_edge; }; @@ -1349,7 +1350,7 @@ struct mlx5_flow_act *flow_act, u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type); bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type); -bool mlx5_ib_devx_is_flow_counter(void *obj, u32 *counter_id); +bool mlx5_ib_devx_is_flow_counter(void *obj, u32 offset, u32 *counter_id); int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root); void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction); #else --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/mr.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/mr.c @@ -41,6 +41,8 @@ #include #include "mlx5_ib.h" +static void mlx5_invalidate_umem(struct ib_umem *umem, void *priv); + enum { MAX_PENDING_REG_MR = 8, }; @@ -428,7 +430,7 @@ if (entry < 0 || entry >= MAX_MR_CACHE_ENTRIES) { mlx5_ib_err(dev, "cache entry %d is out of range\n", entry); - return NULL; + return ERR_PTR(-EINVAL); } ent = &cache->ent[entry]; @@ -752,10 +754,9 @@ return MLX5_MAX_UMR_SHIFT; } -static int mr_umem_get(struct mlx5_ib_dev *dev, struct ib_udata *udata, - u64 start, u64 length, int access_flags, - struct ib_umem **umem, int *npages, int *page_shift, - int *ncont, int *order) +static int mr_umem_get(struct mlx5_ib_dev *dev, u64 start, u64 length, + int access_flags, struct ib_umem **umem, int *npages, + int *page_shift, int *ncont, int *order, bool allow_peer) { struct ib_umem *u; @@ -764,7 +765,8 @@ if (access_flags & IB_ACCESS_ON_DEMAND) { struct ib_umem_odp *odp; - odp = ib_umem_odp_get(udata, start, length, access_flags); + odp = ib_umem_odp_get(&dev->ib_dev, start, length, + access_flags); if (IS_ERR(odp)) { mlx5_ib_dbg(dev, "umem get failed (%ld)\n", PTR_ERR(odp)); @@ -779,7 +781,13 @@ if (order) *order = ilog2(roundup_pow_of_two(*ncont)); } else { - u = ib_umem_get(udata, start, length, access_flags, 0); + if (allow_peer) + u = ib_umem_get_peer(&dev->ib_dev, start, length, + access_flags, + IB_PEER_MEM_INVAL_SUPP); + else + u = ib_umem_get(&dev->ib_dev, start, length, + access_flags); if (IS_ERR(u)) { mlx5_ib_dbg(dev, "umem get failed (%ld)\n", PTR_ERR(u)); return PTR_ERR(u); @@ -1109,6 +1117,9 @@ get_octo_len(virt_addr, length, page_shift)); } + if (umem->is_peer && MLX5_CAP_GEN(dev->mdev, ats)) + MLX5_SET(mkc, mkc, ma_tranlation_mode, 1); + err = mlx5_core_create_mkey(dev->mdev, &mr->mmkey, in, inlen); if (err) { mlx5_ib_warn(dev, "create mkey failed\n"); @@ -1279,15 +1290,17 @@ return &mr->ibmr; } - err = mr_umem_get(dev, udata, start, length, access_flags, &umem, - &npages, &page_shift, &ncont, &order); + err = mr_umem_get(dev, start, length, access_flags, &umem, + &npages, &page_shift, &ncont, &order, true); if (err < 0) return ERR_PTR(err); use_umr = mlx5_ib_can_use_umr(dev, true); - if (order <= mr_cache_max_order(dev) && use_umr) { + if (umem->is_peer && MLX5_CAP_GEN(dev->mdev, ats)) { + use_umr = false; + } else if (order <= mr_cache_max_order(dev) && use_umr) { mr = alloc_mr_from_cache(pd, umem, virt_addr, length, ncont, page_shift, order, access_flags); if (PTR_ERR(mr) == -EAGAIN) { @@ -1312,6 +1325,8 @@ if (IS_ERR(mr)) { err = PTR_ERR(mr); + if (umem->is_peer) + ib_umem_stop_invalidation_notifier(umem); goto error; } @@ -1335,6 +1350,12 @@ } } + if (umem->is_peer) { + ib_umem_activate_invalidation_notifier( + umem, mlx5_invalidate_umem, mr); + /* After this point the MR can be invalidated */ + } + if (is_odp_mr(mr)) { to_ib_umem_odp(mr->umem)->private = mr; atomic_set(&mr->num_pending_prefetch, 0); @@ -1412,6 +1433,10 @@ atomic_sub(mr->npages, &dev->mdev->priv.reg_pages); + /* Peer memory isn't supported */ + if (mr->umem->is_peer) + return -EOPNOTSUPP; + if (!mr->umem) return -EINVAL; @@ -1434,9 +1459,8 @@ flags |= IB_MR_REREG_TRANS; ib_umem_release(mr->umem); mr->umem = NULL; - err = mr_umem_get(dev, udata, addr, len, access_flags, - &mr->umem, &npages, &page_shift, &ncont, - &order); + err = mr_umem_get(dev, addr, len, access_flags, &mr->umem, + &npages, &page_shift, &ncont, &order, false); if (err) goto err; } @@ -1609,6 +1633,17 @@ /* Avoid double-freeing the umem. */ umem = NULL; } + else { + /* + * For peers, need to disable the invalidation notifier + * before calling destroy_mkey(). + */ + if (umem && umem->is_peer) { + if (unreg_umr(mr->dev ,mr)) + return; + ib_umem_stop_invalidation_notifier(umem); + } + } clean_mr(dev, mr); @@ -1616,13 +1651,14 @@ * We should unregister the DMA address from the HCA before * remove the DMA mapping. */ - mlx5_mr_cache_free(dev, mr); + if (mr->allocated_from_cache) + mlx5_mr_cache_free(dev, mr); + else + kfree(mr); + ib_umem_release(umem); if (umem) atomic_sub(npages, &dev->mdev->priv.reg_pages); - - if (!mr->allocated_from_cache) - kfree(mr); } int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) @@ -2332,3 +2368,15 @@ return n; } + +static void mlx5_invalidate_umem(struct ib_umem *umem, void *priv) +{ + struct mlx5_ib_mr *mr = priv; + + /* + * DMA is turned off for the mkey, but the mkey remains otherwise + * untouched until the normal flow of dereg_mr happens. Any access to + * this mkey will generate CQEs. + */ + unreg_umr(mr->dev ,mr); +} --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/odp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/odp.c @@ -553,7 +553,7 @@ struct mlx5_ib_mr *imr; struct ib_umem_odp *umem_odp; - umem_odp = ib_umem_odp_alloc_implicit(udata, access_flags); + umem_odp = ib_umem_odp_alloc_implicit(pd->ibpd.device, access_flags); if (IS_ERR(umem_odp)) return ERR_CAST(umem_odp); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/qp.c @@ -749,7 +749,7 @@ { int err; - *umem = ib_umem_get(udata, addr, size, 0, 0); + *umem = ib_umem_get_peer(&dev->ib_dev, addr, size, 0, 0); if (IS_ERR(*umem)) { mlx5_ib_dbg(dev, "umem_get failed\n"); return PTR_ERR(*umem); @@ -806,7 +806,7 @@ if (!ucmd->buf_addr) return -EINVAL; - rwq->umem = ib_umem_get(udata, ucmd->buf_addr, rwq->buf_size, 0, 0); + rwq->umem = ib_umem_get(&dev->ib_dev, ucmd->buf_addr, rwq->buf_size, 0); if (IS_ERR(rwq->umem)) { mlx5_ib_dbg(dev, "umem_get failed\n"); err = PTR_ERR(rwq->umem); @@ -1463,6 +1463,8 @@ u16 uid = to_mpd(pd)->uid; u32 out[MLX5_ST_SZ_DW(create_tir_out)] = {}; + if (!qp->sq.wqe_cnt && !qp->rq.wqe_cnt) + return -EINVAL; if (qp->sq.wqe_cnt) { err = create_raw_packet_qp_tis(dev, qp, sq, tdn, pd); if (err) @@ -3391,9 +3393,6 @@ struct mlx5_ib_qp_base *base; u32 set_id; - if (!MLX5_CAP_GEN(dev->mdev, rts2rts_qp_counters_set_id)) - return 0; - if (counter) set_id = counter->id; else @@ -3728,6 +3727,7 @@ qp->sq.cur_post = 0; if (qp->sq.wqe_cnt) qp->sq.cur_edge = get_sq_edge(&qp->sq, 0); + qp->sq.last_poll = 0; qp->db.db[MLX5_RCV_DBR] = 0; qp->db.db[MLX5_SND_DBR] = 0; } @@ -3821,7 +3821,7 @@ return -EINVAL; if (attr->port_num == 0 || - attr->port_num > MLX5_CAP_GEN(dev->mdev, num_ports)) { + attr->port_num > dev->num_ports) { mlx5_ib_dbg(dev, "invalid port number %d. number of ports is %d\n", attr->port_num, dev->num_ports); return -EINVAL; @@ -3865,6 +3865,8 @@ MLX5_SET(dctc, dctc, mtu, attr->path_mtu); MLX5_SET(dctc, dctc, my_addr_index, attr->ah_attr.grh.sgid_index); MLX5_SET(dctc, dctc, hop_limit, attr->ah_attr.grh.hop_limit); + if (attr->ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE) + MLX5_SET(dctc, dctc, eth_prio, attr->ah_attr.sl & 0x7); err = mlx5_core_create_dct(dev->mdev, &qp->dct.mdct, qp->dct.in, MLX5_ST_SZ_BYTES(create_dct_in), out, @@ -3888,6 +3890,40 @@ return err; } +static int validate_rd_atomic(struct mlx5_ib_dev *dev, struct ib_qp_attr *attr, + int attr_mask, enum ib_qp_type qp_type) +{ + int log_max_ra_res; + int log_max_ra_req; + + if (qp_type == MLX5_IB_QPT_DCI) { + log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev, + log_max_ra_res_dc); + log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev, + log_max_ra_req_dc); + } else { + log_max_ra_res = 1 << MLX5_CAP_GEN(dev->mdev, + log_max_ra_res_qp); + log_max_ra_req = 1 << MLX5_CAP_GEN(dev->mdev, + log_max_ra_req_qp); + } + + if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && + attr->max_rd_atomic > log_max_ra_res) { + mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n", + attr->max_rd_atomic); + return false; + } + + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && + attr->max_dest_rd_atomic > log_max_ra_req) { + mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n", + attr->max_dest_rd_atomic); + return false; + } + return true; +} + int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata) { @@ -3984,21 +4020,8 @@ } } - if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && - attr->max_rd_atomic > - (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_res_qp))) { - mlx5_ib_dbg(dev, "invalid max_rd_atomic value %d\n", - attr->max_rd_atomic); + if (!validate_rd_atomic(dev, attr, attr_mask, qp_type)) goto out; - } - - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && - attr->max_dest_rd_atomic > - (1 << MLX5_CAP_GEN(dev->mdev, log_max_ra_req_qp))) { - mlx5_ib_dbg(dev, "invalid max_dest_rd_atomic value %d\n", - attr->max_dest_rd_atomic); - goto out; - } if (cur_state == new_state && cur_state == IB_QPS_RESET) { err = 0; @@ -4121,7 +4144,7 @@ */ copysz = min_t(u64, *cur_edge - (void *)eseg->inline_hdr.start, left); - memcpy(eseg->inline_hdr.start, pdata, copysz); + memcpy(eseg->inline_hdr.data, pdata, copysz); stride = ALIGN(sizeof(struct mlx5_wqe_eth_seg) - sizeof(eseg->inline_hdr.start) + copysz, 16); *size += stride / 16; @@ -5498,7 +5521,9 @@ rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); rdma_ah_set_static_rate(ah_attr, path->static_rate ? path->static_rate - 5 : 0); - if (path->grh_mlid & (1 << 7)) { + + if (path->grh_mlid & (1 << 7) || + ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { u32 tc_fl = be32_to_cpu(path->tclass_flowlabel); rdma_ah_set_grh(ah_attr, NULL, @@ -6134,6 +6159,10 @@ if (udata->outlen && udata->outlen < min_resp_len) return ERR_PTR(-EINVAL); + if (!capable(CAP_SYS_RAWIO) && + init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) + return ERR_PTR(-EPERM); + dev = to_mdev(pd->device); switch (init_attr->wq_type) { case IB_WQT_RQ: @@ -6311,10 +6340,8 @@ rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); - curr_wq_state = (wq_attr_mask & IB_WQ_CUR_STATE) ? - wq_attr->curr_wq_state : wq->state; - wq_state = (wq_attr_mask & IB_WQ_STATE) ? - wq_attr->wq_state : curr_wq_state; + curr_wq_state = wq_attr->curr_wq_state; + wq_state = wq_attr->wq_state; if (curr_wq_state == IB_WQS_ERR) curr_wq_state = MLX5_RQC_STATE_ERR; if (wq_state == IB_WQS_ERR) @@ -6503,6 +6530,7 @@ */ int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter) { + struct mlx5_ib_dev *dev = to_mdev(qp->device); struct mlx5_ib_qp *mqp = to_mqp(qp); int err = 0; @@ -6512,6 +6540,11 @@ goto out; } + if (!MLX5_CAP_GEN(dev->mdev, rts2rts_qp_counters_set_id)) { + err = -EOPNOTSUPP; + goto out; + } + if (mqp->state == IB_QPS_RTS) { err = __mlx5_ib_qp_set_counter(qp, counter); if (!err) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/srq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/srq.c @@ -80,7 +80,7 @@ srq->wq_sig = !!(ucmd.flags & MLX5_SRQ_FLAG_SIGNATURE); - srq->umem = ib_umem_get(udata, ucmd.buf_addr, buf_size, 0, 0); + srq->umem = ib_umem_get_peer(pd->device, ucmd.buf_addr, buf_size, 0, 0); if (IS_ERR(srq->umem)) { mlx5_ib_dbg(dev, "failed umem get, size %d\n", buf_size); err = PTR_ERR(srq->umem); @@ -310,12 +310,18 @@ srq->msrq.event = mlx5_ib_srq_event; srq->ibsrq.ext.xrc.srq_num = srq->msrq.srqn; - if (udata) - if (ib_copy_to_udata(udata, &srq->msrq.srqn, sizeof(__u32))) { + if (udata) { + struct mlx5_ib_create_srq_resp resp = { + .srqn = srq->msrq.srqn, + }; + + if (ib_copy_to_udata(udata, &resp, min(udata->outlen, + sizeof(resp)))) { mlx5_ib_dbg(dev, "copy to user failed\n"); err = -EFAULT; goto err_core; } + } init_attr->attr.max_wr = srq->msrq.max - 1; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mlx5/srq_cmd.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mlx5/srq_cmd.c @@ -83,11 +83,11 @@ struct mlx5_srq_table *table = &dev->srq_table; struct mlx5_core_srq *srq; - xa_lock(&table->array); + xa_lock_irq(&table->array); srq = xa_load(&table->array, srqn); if (srq) refcount_inc(&srq->common.refcount); - xa_unlock(&table->array); + xa_unlock_irq(&table->array); return srq; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_cmd.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -635,7 +635,7 @@ int mthca_SYS_EN(struct mthca_dev *dev) { - u64 out; + u64 out = 0; int ret; ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); @@ -1955,7 +1955,7 @@ int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, u16 *hash) { - u64 imm; + u64 imm = 0; int err; err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_cq.c @@ -604,7 +604,7 @@ entry->byte_len = MTHCA_ATOMIC_BYTE_LEN; break; default: - entry->opcode = MTHCA_OPCODE_INVALID; + entry->opcode = 0xFF; break; } } else { @@ -803,8 +803,10 @@ } mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); - if (IS_ERR(mailbox)) + if (IS_ERR(mailbox)) { + err = PTR_ERR(mailbox); goto err_out_arm; + } cq_context = mailbox->buf; @@ -846,9 +848,9 @@ } spin_lock_irq(&dev->cq_table.lock); - if (mthca_array_set(&dev->cq_table.cq, - cq->cqn & (dev->limits.num_cqs - 1), - cq)) { + err = mthca_array_set(&dev->cq_table.cq, + cq->cqn & (dev->limits.num_cqs - 1), cq); + if (err) { spin_unlock_irq(&dev->cq_table.lock); goto err_out_free_mr; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_dev.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_dev.h @@ -105,7 +105,6 @@ MTHCA_OPCODE_ATOMIC_CS = 0x11, MTHCA_OPCODE_ATOMIC_FA = 0x12, MTHCA_OPCODE_BIND_MW = 0x18, - MTHCA_OPCODE_INVALID = 0xff }; enum { --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_main.c @@ -382,7 +382,7 @@ struct mthca_init_hca_param *init_hca, u64 icm_size) { - u64 aux_pages; + u64 aux_pages = 0; int err; err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_provider.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_provider.c @@ -880,9 +880,7 @@ if (!mr) return ERR_PTR(-ENOMEM); - mr->umem = ib_umem_get(udata, start, length, acc, - ucmd.mr_attrs & MTHCA_MR_DMASYNC); - + mr->umem = ib_umem_get(pd->device, start, length, acc); if (IS_ERR(mr->umem)) { err = PTR_ERR(mr->umem); goto err; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/mthca/mthca_qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1639,8 +1639,8 @@ * without initializing f0 and size0, and they are in fact * never used uninitialized. */ - int uninitialized_var(size0); - u32 uninitialized_var(f0); + int size0; + u32 f0; int ind; u8 op0 = 0; @@ -1835,7 +1835,7 @@ * without initializing size0, and it is in fact never used * uninitialized. */ - int uninitialized_var(size0); + int size0; int ind; void *wqe; void *prev_wqe; @@ -1943,8 +1943,8 @@ * without initializing f0 and size0, and they are in fact * never used uninitialized. */ - int uninitialized_var(size0); - u32 uninitialized_var(f0); + int size0; + u32 f0; int ind; u8 op0 = 0; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -442,9 +442,9 @@ pr_err("%s(%d) Freeing in use pdid=0x%x.\n", __func__, dev->id, pd->id); } - kfree(uctx->cntxt_pd); uctx->cntxt_pd = NULL; _ocrdma_dealloc_pd(dev, pd); + kfree(pd); } static struct ocrdma_pd *ocrdma_get_ucontext_pd(struct ocrdma_ucontext *uctx) @@ -875,7 +875,7 @@ mr = kzalloc(sizeof(*mr), GFP_KERNEL); if (!mr) return ERR_PTR(status); - mr->umem = ib_umem_get(udata, start, len, acc, 0); + mr->umem = ib_umem_get(ibpd->device, start, len, acc); if (IS_ERR(mr->umem)) { status = -EFAULT; goto umem_err; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qedr/main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qedr/main.c @@ -357,10 +357,15 @@ return -ENOMEM; spin_lock_init(&dev->sgid_lock); + xa_init_flags(&dev->srqs, XA_FLAGS_LOCK_IRQ); if (IS_IWARP(dev)) { - xa_init_flags(&dev->qps, XA_FLAGS_LOCK_IRQ); + xa_init(&dev->qps); dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq"); + if (!dev->iwarp_wq) { + rc = -ENOMEM; + goto err1; + } } /* Allocate Status blocks for CNQ */ @@ -368,7 +373,7 @@ GFP_KERNEL); if (!dev->sb_array) { rc = -ENOMEM; - goto err1; + goto err_destroy_wq; } dev->cnq_array = kcalloc(dev->num_cnq, @@ -422,6 +427,9 @@ kfree(dev->cnq_array); err2: kfree(dev->sb_array); +err_destroy_wq: + if (IS_IWARP(dev)) + destroy_workqueue(dev->iwarp_wq); err1: kfree(dev->sgid_tbl); return rc; @@ -600,7 +608,7 @@ qed_attr = dev->ops->rdma_query_device(dev->rdma_ctx); /* Part 2 - check capabilities */ - page_size = ~dev->attr.page_size_caps + 1; + page_size = ~qed_attr->page_size_caps + 1; if (page_size > PAGE_SIZE) { DP_ERR(dev, "Kernel PAGE_SIZE is %ld which is smaller than minimum page size (%d) required by qedr\n", --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qedr/qedr.h +++ linux-oracle-5.4.0/drivers/infiniband/hw/qedr/qedr.h @@ -40,6 +40,7 @@ #include #include #include +#include #include "qedr_hsi_rdma.h" #define QEDR_NODE_DESC "QLogic 579xx RoCE HCA" @@ -348,10 +349,10 @@ u32 wqe_prod; u32 sge_prod; u32 wr_prod_cnt; - u32 wr_cons_cnt; + atomic_t wr_cons_cnt; u32 num_elems; - u32 *virt_prod_pair_addr; + struct rdma_srq_producers *virt_prod_pair_addr; dma_addr_t phy_prod_pair_addr; }; @@ -377,10 +378,20 @@ QEDR_QP_ERR_RQ_PBL_FULL = 32, }; +enum qedr_qp_create_type { + QEDR_QP_CREATE_NONE, + QEDR_QP_CREATE_USER, + QEDR_QP_CREATE_KERNEL, +}; + +enum qedr_iwarp_cm_flags { + QEDR_IWARP_CM_WAIT_FOR_CONNECT = BIT(0), + QEDR_IWARP_CM_WAIT_FOR_DISCONNECT = BIT(1), +}; + struct qedr_qp { struct ib_qp ibqp; /* must be first */ struct qedr_dev *dev; - struct qedr_iw_ep *ep; struct qedr_qp_hwq_info sq; struct qedr_qp_hwq_info rq; @@ -395,6 +406,7 @@ u32 id; struct qedr_pd *pd; enum ib_qp_type qp_type; + enum qedr_qp_create_type create_type; struct qed_rdma_qp *qed_qp; u32 qp_id; u16 icid; @@ -404,6 +416,7 @@ u32 sq_psn; u32 qkey; u32 dest_qp_num; + u8 timeout; /* Relevant to qps created from kernel space only (ULPs) */ u8 prev_wqe_size; @@ -437,8 +450,11 @@ /* Relevant to qps created from user space only (applications) */ struct qedr_userq usq; struct qedr_userq urq; - atomic_t refcnt; - bool destroyed; + + /* synchronization objects used with iwarp ep */ + struct kref refcnt; + struct completion iwarp_cm_comp; + unsigned long iwarp_cm_flags; /* enum iwarp_cm_flags */ }; struct qedr_ah { @@ -531,7 +547,7 @@ struct iw_cm_id *cm_id; struct qedr_qp *qp; void *qed_context; - u8 during_connect; + struct kref refcnt; }; static inline --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qedr/qedr_iw_cm.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qedr/qedr_iw_cm.c @@ -79,6 +79,27 @@ } } +static void qedr_iw_free_qp(struct kref *ref) +{ + struct qedr_qp *qp = container_of(ref, struct qedr_qp, refcnt); + + kfree(qp); +} + +static void +qedr_iw_free_ep(struct kref *ref) +{ + struct qedr_iw_ep *ep = container_of(ref, struct qedr_iw_ep, refcnt); + + if (ep->qp) + kref_put(&ep->qp->refcnt, qedr_iw_free_qp); + + if (ep->cm_id) + ep->cm_id->rem_ref(ep->cm_id); + + kfree(ep); +} + static void qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params) { @@ -93,6 +114,7 @@ ep->dev = dev; ep->qed_context = params->ep_context; + kref_init(&ep->refcnt); memset(&event, 0, sizeof(event)); event.event = IW_CM_EVENT_CONNECT_REQUEST; @@ -128,8 +150,17 @@ if (params->cm_info) { event.ird = params->cm_info->ird; event.ord = params->cm_info->ord; - event.private_data_len = params->cm_info->private_data_len; - event.private_data = (void *)params->cm_info->private_data; + /* Only connect_request and reply have valid private data + * the rest of the events this may be left overs from + * connection establishment. CONNECT_REQUEST is issued via + * qedr_iw_mpa_request + */ + if (event_type == IW_CM_EVENT_CONNECT_REPLY) { + event.private_data_len = + params->cm_info->private_data_len; + event.private_data = + (void *)params->cm_info->private_data; + } } if (ep->cm_id) @@ -141,12 +172,10 @@ { struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; - if (ep->cm_id) { + if (ep->cm_id) qedr_iw_issue_event(context, params, IW_CM_EVENT_CLOSE); - ep->cm_id->rem_ref(ep->cm_id); - ep->cm_id = NULL; - } + kref_put(&ep->refcnt, qedr_iw_free_ep); } static void @@ -186,11 +215,13 @@ struct qedr_qp *qp = ep->qp; struct iw_cm_event event; - if (qp->destroyed) { - kfree(dwork); - qedr_iw_qp_rem_ref(&qp->ibqp); - return; - } + /* The qp won't be released until we release the ep. + * the ep's refcnt was increased before calling this + * function, therefore it is safe to access qp + */ + if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT, + &qp->iwarp_cm_flags)) + goto out; memset(&event, 0, sizeof(event)); event.status = dwork->status; @@ -204,7 +235,6 @@ else qp_params.new_state = QED_ROCE_QP_STATE_SQD; - kfree(dwork); if (ep->cm_id) ep->cm_id->event_handler(ep->cm_id, &event); @@ -214,7 +244,10 @@ dev->ops->rdma_modify_qp(dev->rdma_ctx, qp->qed_qp, &qp_params); - qedr_iw_qp_rem_ref(&qp->ibqp); + complete(&ep->qp->iwarp_cm_comp); +out: + kfree(dwork); + kref_put(&ep->refcnt, qedr_iw_free_ep); } static void @@ -224,13 +257,17 @@ struct qedr_discon_work *work; struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; struct qedr_dev *dev = ep->dev; - struct qedr_qp *qp = ep->qp; work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) return; - qedr_iw_qp_add_ref(&qp->ibqp); + /* We can't get a close event before disconnect, but since + * we're scheduling a work queue we need to make sure close + * won't delete the ep, so we increase the refcnt + */ + kref_get(&ep->refcnt); + work->ep = ep; work->event = params->event; work->status = params->status; @@ -252,16 +289,30 @@ if ((params->status == -ECONNREFUSED) && (!ep->qp)) { DP_DEBUG(dev, QEDR_MSG_IWARP, "PASSIVE connection refused releasing ep...\n"); - kfree(ep); + kref_put(&ep->refcnt, qedr_iw_free_ep); return; } + complete(&ep->qp->iwarp_cm_comp); qedr_iw_issue_event(context, params, IW_CM_EVENT_ESTABLISHED); if (params->status < 0) qedr_iw_close_event(context, params); } +static void +qedr_iw_active_complete(void *context, + struct qed_iwarp_cm_event_params *params) +{ + struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; + + complete(&ep->qp->iwarp_cm_comp); + qedr_iw_issue_event(context, params, IW_CM_EVENT_CONNECT_REPLY); + + if (params->status < 0) + kref_put(&ep->refcnt, qedr_iw_free_ep); +} + static int qedr_iw_mpa_reply(void *context, struct qed_iwarp_cm_event_params *params) { @@ -288,27 +339,15 @@ qedr_iw_mpa_reply(context, params); break; case QED_IWARP_EVENT_PASSIVE_COMPLETE: - ep->during_connect = 0; qedr_iw_passive_complete(context, params); break; - case QED_IWARP_EVENT_ACTIVE_COMPLETE: - ep->during_connect = 0; - qedr_iw_issue_event(context, - params, - IW_CM_EVENT_CONNECT_REPLY); - if (params->status < 0) { - struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; - - ep->cm_id->rem_ref(ep->cm_id); - ep->cm_id = NULL; - } + qedr_iw_active_complete(context, params); break; case QED_IWARP_EVENT_DISCONNECT: qedr_iw_disconnect_event(context, params); break; case QED_IWARP_EVENT_CLOSE: - ep->during_connect = 0; qedr_iw_close_event(context, params); break; case QED_IWARP_EVENT_RQ_EMPTY: @@ -451,10 +490,10 @@ if ((!dst) || dst->error) { if (dst) { - dst_release(dst); DP_ERR(dev, "ip6_route_output returned dst->error = %d\n", dst->error); + dst_release(dst); } return -EINVAL; } @@ -476,6 +515,19 @@ return rc; } +struct qedr_qp *qedr_iw_load_qp(struct qedr_dev *dev, u32 qpn) +{ + struct qedr_qp *qp; + + xa_lock(&dev->qps); + qp = xa_load(&dev->qps, qpn); + if (qp) + kref_get(&qp->refcnt); + xa_unlock(&dev->qps); + + return qp; +} + int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) { struct qedr_dev *dev = get_qedr_dev(cm_id->device); @@ -491,10 +543,6 @@ int rc = 0; int i; - qp = xa_load(&dev->qps, conn_param->qpn); - if (unlikely(!qp)) - return -EINVAL; - laddr = (struct sockaddr_in *)&cm_id->m_local_addr; raddr = (struct sockaddr_in *)&cm_id->m_remote_addr; laddr6 = (struct sockaddr_in6 *)&cm_id->m_local_addr; @@ -516,8 +564,15 @@ return -ENOMEM; ep->dev = dev; + kref_init(&ep->refcnt); + + qp = qedr_iw_load_qp(dev, conn_param->qpn); + if (!qp) { + rc = -EINVAL; + goto err; + } + ep->qp = qp; - qp->ep = ep; cm_id->add_ref(cm_id); ep->cm_id = cm_id; @@ -580,16 +635,22 @@ in_params.qp = qp->qed_qp; memcpy(in_params.local_mac_addr, dev->ndev->dev_addr, ETH_ALEN); - ep->during_connect = 1; + if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT, + &qp->iwarp_cm_flags)) { + rc = -ENODEV; + goto err; /* QP already being destroyed */ + } + rc = dev->ops->iwarp_connect(dev->rdma_ctx, &in_params, &out_params); - if (rc) + if (rc) { + complete(&qp->iwarp_cm_comp); goto err; + } return rc; err: - cm_id->rem_ref(cm_id); - kfree(ep); + kref_put(&ep->refcnt, qedr_iw_free_ep); return rc; } @@ -668,6 +729,7 @@ listener->qed_handle); cm_id->rem_ref(cm_id); + kfree(listener); return rc; } @@ -681,14 +743,13 @@ DP_DEBUG(dev, QEDR_MSG_IWARP, "Accept on qpid=%d\n", conn_param->qpn); - qp = xa_load(&dev->qps, conn_param->qpn); + qp = qedr_iw_load_qp(dev, conn_param->qpn); if (!qp) { DP_ERR(dev, "Invalid QP number %d\n", conn_param->qpn); return -EINVAL; } ep->qp = qp; - qp->ep = ep; cm_id->add_ref(cm_id); ep->cm_id = cm_id; @@ -700,15 +761,23 @@ params.ird = conn_param->ird; params.ord = conn_param->ord; - ep->during_connect = 1; + if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT, + &qp->iwarp_cm_flags)) { + rc = -EINVAL; + goto err; /* QP already destroyed */ + } + rc = dev->ops->iwarp_accept(dev->rdma_ctx, ¶ms); - if (rc) + if (rc) { + complete(&qp->iwarp_cm_comp); goto err; + } return rc; + err: - ep->during_connect = 0; - cm_id->rem_ref(cm_id); + kref_put(&ep->refcnt, qedr_iw_free_ep); + return rc; } @@ -731,17 +800,14 @@ { struct qedr_qp *qp = get_qedr_qp(ibqp); - atomic_inc(&qp->refcnt); + kref_get(&qp->refcnt); } void qedr_iw_qp_rem_ref(struct ib_qp *ibqp) { struct qedr_qp *qp = get_qedr_qp(ibqp); - if (atomic_dec_and_test(&qp->refcnt)) { - xa_erase_irq(&qp->dev->qps, qp->qp_id); - kfree(qp); - } + kref_put(&qp->refcnt, qedr_iw_free_qp); } struct ib_qp *qedr_iw_get_qp(struct ib_device *ibdev, int qpn) --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qedr/verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qedr/verbs.c @@ -51,6 +51,7 @@ #include "verbs.h" #include #include "qedr_roce_cm.h" +#include "qedr_iw_cm.h" #define QEDR_SRQ_WQE_ELEM_SIZE sizeof(union rdma_srq_elm) #define RDMA_MAX_SGE_PER_SRQ (4) @@ -697,7 +698,7 @@ static inline int qedr_init_user_queue(struct ib_udata *udata, struct qedr_dev *dev, struct qedr_userq *q, u64 buf_addr, - size_t buf_len, int access, int dmasync, + size_t buf_len, int access, int alloc_and_init) { u32 fw_pages; @@ -705,7 +706,7 @@ q->buf_addr = buf_addr; q->buf_len = buf_len; - q->umem = ib_umem_get(udata, q->buf_addr, q->buf_len, access, dmasync); + q->umem = ib_umem_get(&dev->ibdev, q->buf_addr, q->buf_len, access); if (IS_ERR(q->umem)) { DP_ERR(dev, "create user queue: failed ib_umem_get, got %ld\n", PTR_ERR(q->umem)); @@ -856,8 +857,7 @@ cq->cq_type = QEDR_CQ_TYPE_USER; rc = qedr_init_user_queue(udata, dev, &cq->q, ureq.addr, - ureq.len, IB_ACCESS_LOCAL_WRITE, 1, - 1); + ureq.len, IB_ACCESS_LOCAL_WRITE, 1); if (rc) goto err0; @@ -1193,7 +1193,10 @@ struct ib_qp_init_attr *attrs) { spin_lock_init(&qp->q_lock); - atomic_set(&qp->refcnt, 1); + if (rdma_protocol_iwarp(&dev->ibdev, 1)) { + kref_init(&qp->refcnt); + init_completion(&qp->iwarp_cm_comp); + } qp->pd = pd; qp->qp_type = attrs->qp_type; qp->max_inline_data = attrs->cap.max_inline_data; @@ -1279,19 +1282,18 @@ static int qedr_init_srq_user_params(struct ib_udata *udata, struct qedr_srq *srq, struct qedr_create_srq_ureq *ureq, - int access, int dmasync) + int access) { struct scatterlist *sg; int rc; rc = qedr_init_user_queue(udata, srq->dev, &srq->usrq, ureq->srq_addr, - ureq->srq_len, access, dmasync, 1); + ureq->srq_len, access, 1); if (rc) return rc; - srq->prod_umem = - ib_umem_get(udata, ureq->prod_pair_addr, - sizeof(struct rdma_srq_producers), access, dmasync); + srq->prod_umem = ib_umem_get(srq->ibsrq.device, ureq->prod_pair_addr, + sizeof(struct rdma_srq_producers), access); if (IS_ERR(srq->prod_umem)) { qedr_free_pbl(srq->dev, &srq->usrq.pbl_info, srq->usrq.pbl_tbl); ib_umem_release(srq->usrq.umem); @@ -1387,7 +1389,7 @@ goto err0; } - rc = qedr_init_srq_user_params(udata, srq, &ureq, 0, 0); + rc = qedr_init_srq_user_params(udata, srq, &ureq, 0); if (rc) goto err0; @@ -1577,6 +1579,14 @@ ib_umem_release(qp->urq.umem); qp->urq.umem = NULL; + + if (rdma_protocol_roce(&dev->ibdev, 1)) { + qedr_free_pbl(dev, &qp->usq.pbl_info, qp->usq.pbl_tbl); + qedr_free_pbl(dev, &qp->urq.pbl_info, qp->urq.pbl_tbl); + } else { + kfree(qp->usq.pbl_tbl); + kfree(qp->urq.pbl_tbl); + } } static int qedr_create_user_qp(struct qedr_dev *dev, @@ -1592,6 +1602,7 @@ int alloc_and_init = rdma_protocol_roce(&dev->ibdev, 1); int rc = -EINVAL; + qp->create_type = QEDR_QP_CREATE_USER; memset(&ureq, 0, sizeof(ureq)); rc = ib_copy_from_udata(&ureq, udata, sizeof(ureq)); if (rc) { @@ -1599,16 +1610,16 @@ return rc; } - /* SQ - read access only (0), dma sync not required (0) */ + /* SQ - read access only (0) */ rc = qedr_init_user_queue(udata, dev, &qp->usq, ureq.sq_addr, - ureq.sq_len, 0, 0, alloc_and_init); + ureq.sq_len, 0, alloc_and_init); if (rc) return rc; if (!qp->srq) { - /* RQ - read access only (0), dma sync not required (0) */ + /* RQ - read access only (0) */ rc = qedr_init_user_queue(udata, dev, &qp->urq, ureq.rq_addr, - ureq.rq_len, 0, 0, alloc_and_init); + ureq.rq_len, 0, alloc_and_init); if (rc) return rc; } @@ -1805,6 +1816,7 @@ u32 n_sq_entries; memset(&in_params, 0, sizeof(in_params)); + qp->create_type = QEDR_QP_CREATE_KERNEL; /* A single work request may take up to QEDR_MAX_SQ_WQE_SIZE elements in * the ring. The ring should allow at least a single WR, even if the @@ -1918,7 +1930,7 @@ qp->ibqp.qp_num = qp->qp_id; if (rdma_protocol_iwarp(&dev->ibdev, 1)) { - rc = xa_insert_irq(&dev->qps, qp->qp_id, qp, GFP_KERNEL); + rc = xa_insert(&dev->qps, qp->qp_id, qp, GFP_KERNEL); if (rc) goto err; } @@ -2245,6 +2257,8 @@ 1 << max_t(int, attr->timeout - 8, 0); else qp_params.ack_timeout = 0; + + qp->timeout = attr->timeout; } if (attr_mask & IB_QP_RETRY_CNT) { @@ -2369,15 +2383,18 @@ int rc = 0; memset(¶ms, 0, sizeof(params)); - - rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms); - if (rc) - goto err; - memset(qp_attr, 0, sizeof(*qp_attr)); memset(qp_init_attr, 0, sizeof(*qp_init_attr)); - qp_attr->qp_state = qedr_get_ibqp_state(params.state); + if (qp->qp_type != IB_QPT_GSI) { + rc = dev->ops->rdma_query_qp(dev->rdma_ctx, qp->qed_qp, ¶ms); + if (rc) + goto err; + qp_attr->qp_state = qedr_get_ibqp_state(params.state); + } else { + qp_attr->qp_state = qedr_get_ibqp_state(QED_ROCE_QP_STATE_RTS); + } + qp_attr->cur_qp_state = qedr_get_ibqp_state(params.state); qp_attr->path_mtu = ib_mtu_int_to_enum(params.mtu); qp_attr->path_mig_state = IB_MIG_MIGRATED; @@ -2391,7 +2408,7 @@ qp_attr->cap.max_recv_wr = qp->rq.max_wr; qp_attr->cap.max_send_sge = qp->sq.max_sges; qp_attr->cap.max_recv_sge = qp->rq.max_sges; - qp_attr->cap.max_inline_data = ROCE_REQ_MAX_INLINE_DATA_SIZE; + qp_attr->cap.max_inline_data = dev->attr.max_inline; qp_init_attr->cap = qp_attr->cap; qp_attr->ah_attr.type = RDMA_AH_ATTR_TYPE_ROCE; @@ -2401,7 +2418,7 @@ rdma_ah_set_dgid_raw(&qp_attr->ah_attr, ¶ms.dgid.bytes[0]); rdma_ah_set_port_num(&qp_attr->ah_attr, 1); rdma_ah_set_sl(&qp_attr->ah_attr, 0); - qp_attr->timeout = params.timeout; + qp_attr->timeout = qp->timeout; qp_attr->rnr_retry = params.rnr_retry; qp_attr->retry_cnt = params.retry_cnt; qp_attr->min_rnr_timer = params.min_rnr_nak_timer; @@ -2437,7 +2454,7 @@ return rc; } - if (udata) + if (qp->create_type == QEDR_QP_CREATE_USER) qedr_cleanup_user(dev, qp); else qedr_cleanup_kernel(dev, qp); @@ -2467,34 +2484,46 @@ qedr_modify_qp(ibqp, &attr, attr_mask, NULL); } } else { - /* Wait for the connect/accept to complete */ - if (qp->ep) { - int wait_count = 1; - - while (qp->ep->during_connect) { - DP_DEBUG(dev, QEDR_MSG_QP, - "Still in during connect/accept\n"); - - msleep(100); - if (wait_count++ > 200) { - DP_NOTICE(dev, - "during connect timeout\n"); - break; - } - } - } + /* If connection establishment started the WAIT_FOR_CONNECT + * bit will be on and we need to Wait for the establishment + * to complete before destroying the qp. + */ + if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_CONNECT, + &qp->iwarp_cm_flags)) + wait_for_completion(&qp->iwarp_cm_comp); + + /* If graceful disconnect started, the WAIT_FOR_DISCONNECT + * bit will be on, and we need to wait for the disconnect to + * complete before continuing. We can use the same completion, + * iwarp_cm_comp, since this is the only place that waits for + * this completion and it is sequential. In addition, + * disconnect can't occur before the connection is fully + * established, therefore if WAIT_FOR_DISCONNECT is on it + * means WAIT_FOR_CONNECT is also on and the completion for + * CONNECT already occurred. + */ + if (test_and_set_bit(QEDR_IWARP_CM_WAIT_FOR_DISCONNECT, + &qp->iwarp_cm_flags)) + wait_for_completion(&qp->iwarp_cm_comp); } if (qp->qp_type == IB_QPT_GSI) qedr_destroy_gsi_qp(dev); + /* We need to remove the entry from the xarray before we release the + * qp_id to avoid a race of the qp_id being reallocated and failing + * on xa_insert + */ + if (rdma_protocol_iwarp(&dev->ibdev, 1)) + xa_erase(&dev->qps, qp->qp_id); + qedr_free_qp_resources(dev, qp, udata); - if (atomic_dec_and_test(&qp->refcnt) && - rdma_protocol_iwarp(&dev->ibdev, 1)) { - xa_erase_irq(&dev->qps, qp->qp_id); + if (rdma_protocol_iwarp(&dev->ibdev, 1)) + qedr_iw_qp_rem_ref(&qp->ibqp); + else kfree(qp); - } + return 0; } @@ -2597,7 +2626,7 @@ mr->type = QEDR_MR_USER; - mr->umem = ib_umem_get(udata, start, len, acc, 0); + mr->umem = ib_umem_get(ibpd->device, start, len, acc); if (IS_ERR(mr->umem)) { rc = -EFAULT; goto err0; @@ -2673,8 +2702,8 @@ dev->ops->rdma_free_tid(dev->rdma_ctx, mr->hw_mr.itid); - if ((mr->type != QEDR_MR_DMA) && (mr->type != QEDR_MR_FRMR)) - qedr_free_pbl(dev, &mr->info.pbl_info, mr->info.pbl_table); + if (mr->type != QEDR_MR_DMA) + free_mr_info(dev, &mr->info); /* it could be user registered memory. */ ib_umem_release(mr->umem); @@ -3436,7 +3465,7 @@ * count and consumer count and subtract it from max * work request supported so that we get elements left. */ - used = hw_srq->wr_prod_cnt - hw_srq->wr_cons_cnt; + used = hw_srq->wr_prod_cnt - (u32)atomic_read(&hw_srq->wr_cons_cnt); return hw_srq->max_wr - used; } @@ -3451,7 +3480,6 @@ unsigned long flags; int status = 0; u32 num_sge; - u32 offset; spin_lock_irqsave(&srq->lock, flags); @@ -3464,7 +3492,8 @@ if (!qedr_srq_elem_left(hw_srq) || wr->num_sge > srq->hw_srq.max_sges) { DP_ERR(dev, "Can't post WR (%d,%d) || (%d > %d)\n", - hw_srq->wr_prod_cnt, hw_srq->wr_cons_cnt, + hw_srq->wr_prod_cnt, + atomic_read(&hw_srq->wr_cons_cnt), wr->num_sge, srq->hw_srq.max_sges); status = -ENOMEM; *bad_wr = wr; @@ -3498,22 +3527,20 @@ hw_srq->sge_prod++; } - /* Flush WQE and SGE information before + /* Update WQE and SGE information before * updating producer. */ - wmb(); + dma_wmb(); /* SRQ producer is 8 bytes. Need to update SGE producer index * in first 4 bytes and need to update WQE producer in * next 4 bytes. */ - *srq->hw_srq.virt_prod_pair_addr = hw_srq->sge_prod; - offset = offsetof(struct rdma_srq_producers, wqe_prod); - *((u8 *)srq->hw_srq.virt_prod_pair_addr + offset) = - hw_srq->wqe_prod; + srq->hw_srq.virt_prod_pair_addr->sge_prod = hw_srq->sge_prod; + /* Make sure sge producer is updated first */ + dma_wmb(); + srq->hw_srq.virt_prod_pair_addr->wqe_prod = hw_srq->wqe_prod; - /* Flush producer after updating it. */ - wmb(); wr = wr->next; } @@ -3932,7 +3959,7 @@ } else { __process_resp_one(dev, qp, cq, wc, resp, wr_id); } - srq->hw_srq.wr_cons_cnt++; + atomic_inc(&srq->hw_srq.wr_cons_cnt); return 1; } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qib/qib_sysfs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qib/qib_sysfs.c @@ -301,6 +301,9 @@ struct qib_pportdata *ppd = container_of(kobj, struct qib_pportdata, pport_kobj); + if (!pattr->show) + return -EIO; + return pattr->show(ppd, buf); } @@ -312,6 +315,9 @@ struct qib_pportdata *ppd = container_of(kobj, struct qib_pportdata, pport_kobj); + if (!pattr->store) + return -EIO; + return pattr->store(ppd, buf, len); } @@ -754,7 +760,7 @@ qib_dev_err(dd, "Skipping linkcontrol sysfs info, (err %d) port %u\n", ret, port_num); - goto bail; + goto bail_link; } kobject_uevent(&ppd->pport_kobj, KOBJ_ADD); @@ -764,7 +770,7 @@ qib_dev_err(dd, "Skipping sl2vl sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_link; + goto bail_sl; } kobject_uevent(&ppd->sl2vl_kobj, KOBJ_ADD); @@ -774,7 +780,7 @@ qib_dev_err(dd, "Skipping diag_counters sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_sl; + goto bail_diagc; } kobject_uevent(&ppd->diagc_kobj, KOBJ_ADD); @@ -787,7 +793,7 @@ qib_dev_err(dd, "Skipping Congestion Control sysfs info, (err %d) port %u\n", ret, port_num); - goto bail_diagc; + goto bail_cc; } kobject_uevent(&ppd->pport_cc_kobj, KOBJ_ADD); @@ -848,6 +854,7 @@ &cc_table_bin_attr); kobject_put(&ppd->pport_cc_kobj); } + kobject_put(&ppd->diagc_kobj); kobject_put(&ppd->sl2vl_kobj); kobject_put(&ppd->pport_kobj); } --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qib/qib_user_sdma.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qib/qib_user_sdma.c @@ -602,7 +602,7 @@ /* * How many pages in this iovec element? */ -static int qib_user_sdma_num_pages(const struct iovec *iov) +static size_t qib_user_sdma_num_pages(const struct iovec *iov) { const unsigned long addr = (unsigned long) iov->iov_base; const unsigned long len = iov->iov_len; @@ -658,7 +658,7 @@ static int qib_user_sdma_pin_pages(const struct qib_devdata *dd, struct qib_user_sdma_queue *pq, struct qib_user_sdma_pkt *pkt, - unsigned long addr, int tlen, int npages) + unsigned long addr, int tlen, size_t npages) { struct page *pages[8]; int i, j; @@ -722,7 +722,7 @@ unsigned long idx; for (idx = 0; idx < niov; idx++) { - const int npages = qib_user_sdma_num_pages(iov + idx); + const size_t npages = qib_user_sdma_num_pages(iov + idx); const unsigned long addr = (unsigned long) iov[idx].iov_base; ret = qib_user_sdma_pin_pages(dd, pq, pkt, addr, @@ -824,8 +824,8 @@ unsigned pktnw; unsigned pktnwc; int nfrags = 0; - int npages = 0; - int bytes_togo = 0; + size_t npages = 0; + size_t bytes_togo = 0; int tiddma = 0; int cfur; @@ -885,7 +885,11 @@ npages += qib_user_sdma_num_pages(&iov[idx]); - bytes_togo += slen; + if (check_add_overflow(bytes_togo, slen, &bytes_togo) || + bytes_togo > type_max(typeof(pkt->bytes_togo))) { + ret = -EINVAL; + goto free_pbc; + } pktnwc += slen >> 2; idx++; nfrags++; @@ -904,8 +908,7 @@ } if (frag_size) { - int tidsmsize, n; - size_t pktsize; + size_t tidsmsize, n, pktsize, sz, addrlimit; n = npages*((2*PAGE_SIZE/frag_size)+1); pktsize = struct_size(pkt, addr, n); @@ -923,14 +926,24 @@ else tidsmsize = 0; - pkt = kmalloc(pktsize+tidsmsize, GFP_KERNEL); + if (check_add_overflow(pktsize, tidsmsize, &sz)) { + ret = -EINVAL; + goto free_pbc; + } + pkt = kmalloc(sz, GFP_KERNEL); if (!pkt) { ret = -ENOMEM; goto free_pbc; } pkt->largepkt = 1; pkt->frag_size = frag_size; - pkt->addrlimit = n + ARRAY_SIZE(pkt->addr); + if (check_add_overflow(n, ARRAY_SIZE(pkt->addr), + &addrlimit) || + addrlimit > type_max(typeof(pkt->addrlimit))) { + ret = -EINVAL; + goto free_pkt; + } + pkt->addrlimit = addrlimit; if (tiddma) { char *tidsm = (char *)pkt + pktsize; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/qib/qib_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/qib/qib_verbs.c @@ -329,8 +329,10 @@ if (mcast == NULL) goto drop; this_cpu_inc(ibp->pmastats->n_multicast_rcv); + rcu_read_lock(); list_for_each_entry_rcu(p, &mcast->qp_list, list) qib_qp_rcv(rcd, hdr, 1, data, tlen, p->qp); + rcu_read_unlock(); /* * Notify rvt_multicast_detach() if it is waiting for us * to finish. --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/usnic/usnic_ib_verbs.c @@ -214,6 +214,7 @@ } usnic_uiom_free_dev_list(dev_list); + dev_list = NULL; } /* Try to find resources on an unused vf */ @@ -239,6 +240,8 @@ qp_grp_check: if (IS_ERR_OR_NULL(qp_grp)) { usnic_err("Failed to allocate qp_grp\n"); + if (usnic_ib_share_vf) + usnic_uiom_free_dev_list(dev_list); return ERR_PTR(qp_grp ? PTR_ERR(qp_grp) : -ENOMEM); } return qp_grp; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/usnic/usnic_uiom.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/usnic/usnic_uiom.c @@ -281,8 +281,8 @@ size = pa_end - pa_start + PAGE_SIZE; usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x", va_start, &pa_start, size, flags); - err = iommu_map(pd->domain, va_start, pa_start, - size, flags); + err = iommu_map_atomic(pd->domain, va_start, + pa_start, size, flags); if (err) { usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n", va_start, &pa_start, size, err); @@ -298,8 +298,8 @@ size = pa - pa_start + PAGE_SIZE; usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n", va_start, &pa_start, size, flags); - err = iommu_map(pd->domain, va_start, pa_start, - size, flags); + err = iommu_map_atomic(pd->domain, va_start, + pa_start, size, flags); if (err) { usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n", va_start, &pa_start, size, err); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c @@ -135,8 +135,8 @@ goto err_cq; } - cq->umem = ib_umem_get(udata, ucmd.buf_addr, ucmd.buf_size, - IB_ACCESS_LOCAL_WRITE, 1); + cq->umem = ib_umem_get(ibdev, ucmd.buf_addr, ucmd.buf_size, + IB_ACCESS_LOCAL_WRITE); if (IS_ERR(cq->umem)) { ret = PTR_ERR(cq->umem); goto err_cq; --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c @@ -266,7 +266,7 @@ } ret = ib_device_set_netdev(&dev->ib_dev, dev->netdev, 1); if (ret) - return ret; + goto err_srq_free; spin_lock_init(&dev->srq_tbl_lock); rdma_set_device_sysfs_group(&dev->ib_dev, &pvrdma_attr_group); @@ -829,7 +829,7 @@ !(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { dev_err(&pdev->dev, "PCI BAR region not MMIO\n"); ret = -ENOMEM; - goto err_free_device; + goto err_disable_pdev; } ret = pci_request_regions(pdev, DRV_NAME); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c @@ -126,7 +126,7 @@ return ERR_PTR(-EINVAL); } - umem = ib_umem_get(udata, start, length, access_flags, 0); + umem = ib_umem_get(pd->device, start, length, access_flags); if (IS_ERR(umem)) { dev_warn(&dev->pdev->dev, "could not get umem for mem region\n"); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/vmw_pvrdma/pvrdma_qp.c @@ -262,8 +262,9 @@ if (!is_srq) { /* set qp->sq.wqe_cnt, shift, buf_size.. */ - qp->rumem = ib_umem_get(udata, ucmd.rbuf_addr, - ucmd.rbuf_size, 0, 0); + qp->rumem = + ib_umem_get(pd->device, ucmd.rbuf_addr, + ucmd.rbuf_size, 0); if (IS_ERR(qp->rumem)) { ret = PTR_ERR(qp->rumem); goto err_qp; @@ -274,8 +275,8 @@ qp->srq = to_vsrq(init_attr->srq); } - qp->sumem = ib_umem_get(udata, ucmd.sbuf_addr, - ucmd.sbuf_size, 0, 0); + qp->sumem = ib_umem_get(pd->device, ucmd.sbuf_addr, + ucmd.sbuf_size, 0); if (IS_ERR(qp->sumem)) { if (!is_srq) ib_umem_release(qp->rumem); --- linux-oracle-5.4.0.orig/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c +++ linux-oracle-5.4.0/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c @@ -146,7 +146,7 @@ goto err_srq; } - srq->umem = ib_umem_get(udata, ucmd.buf_addr, ucmd.buf_size, 0, 0); + srq->umem = ib_umem_get(ibsrq->device, ucmd.buf_addr, ucmd.buf_size, 0); if (IS_ERR(srq->umem)) { ret = PTR_ERR(srq->umem); goto err_srq; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/Kconfig +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/Kconfig @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only config INFINIBAND_RDMAVT tristate "RDMA verbs transport library" - depends on X86_64 && ARCH_DMA_ADDR_T_64BIT + depends on INFINIBAND_VIRT_DMA + depends on X86_64 depends on PCI select DMA_VIRT_OPS ---help--- --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/cq.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/cq.c @@ -248,8 +248,8 @@ */ if (udata && udata->outlen >= sizeof(__u64)) { cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc); - if (!cq->ip) { - err = -ENOMEM; + if (IS_ERR(cq->ip)) { + err = PTR_ERR(cq->ip); goto bail_wc; } @@ -327,7 +327,7 @@ if (cq->ip) kref_put(&cq->ip->ref, rvt_release_mmap_info); else - vfree(cq->queue); + vfree(cq->kqueue); } /** --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/mmap.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/mmap.c @@ -154,7 +154,7 @@ * @udata: user data (must be valid!) * @obj: opaque pointer to a cq, wq etc * - * Return: rvt_mmap struct on success + * Return: rvt_mmap struct on success, ERR_PTR on failure */ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, struct ib_udata *udata, void *obj) @@ -166,7 +166,7 @@ ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node); if (!ip) - return ip; + return ERR_PTR(-ENOMEM); size = PAGE_ALIGN(size); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/mr.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/mr.c @@ -390,7 +390,7 @@ if (length == 0) return ERR_PTR(-EINVAL); - umem = ib_umem_get(udata, start, length, mr_access_flags, 0); + umem = ib_umem_get(pd->device, start, length, mr_access_flags); if (IS_ERR(umem)) return (void *)umem; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/qp.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/qp.c @@ -61,6 +61,8 @@ #define RVT_RWQ_COUNT_THRESHOLD 16 static void rvt_rc_timeout(struct timer_list *t); +static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type); /* * Convert the AETH RNR timeout code into the number of microseconds. @@ -452,40 +454,41 @@ } /** - * free_all_qps - check for QPs still in use + * rvt_free_qp_cb - callback function to reset a qp + * @qp: the qp to reset + * @v: a 64-bit value + * + * This function resets the qp and removes it from the + * qp hash table. + */ +static void rvt_free_qp_cb(struct rvt_qp *qp, u64 v) +{ + unsigned int *qp_inuse = (unsigned int *)v; + struct rvt_dev_info *rdi = ib_to_rvt(qp->ibqp.device); + + /* Reset the qp and remove it from the qp hash list */ + rvt_reset_qp(rdi, qp, qp->ibqp.qp_type); + + /* Increment the qp_inuse count */ + (*qp_inuse)++; +} + +/** + * rvt_free_all_qps - check for QPs still in use * @rdi: rvt device info structure * * There should not be any QPs still in use. * Free memory for table. + * Return the number of QPs still in use. */ static unsigned rvt_free_all_qps(struct rvt_dev_info *rdi) { - unsigned long flags; - struct rvt_qp *qp; - unsigned n, qp_inuse = 0; - spinlock_t *ql; /* work around too long line below */ - - if (rdi->driver_f.free_all_qps) - qp_inuse = rdi->driver_f.free_all_qps(rdi); + unsigned int qp_inuse = 0; qp_inuse += rvt_mcast_tree_empty(rdi); - if (!rdi->qp_dev) - return qp_inuse; + rvt_qp_iter(rdi, (u64)&qp_inuse, rvt_free_qp_cb); - ql = &rdi->qp_dev->qpt_lock; - spin_lock_irqsave(ql, flags); - for (n = 0; n < rdi->qp_dev->qp_table_size; n++) { - qp = rcu_dereference_protected(rdi->qp_dev->qp_table[n], - lockdep_is_held(ql)); - RCU_INIT_POINTER(rdi->qp_dev->qp_table[n], NULL); - - for (; qp; qp = rcu_dereference_protected(qp->next, - lockdep_is_held(ql))) - qp_inuse++; - } - spin_unlock_irqrestore(ql, flags); - synchronize_rcu(); return qp_inuse; } @@ -502,8 +505,6 @@ if (qps_inuse) rvt_pr_err(rdi, "QP memory leak! %u still in use\n", qps_inuse); - if (!rdi->qp_dev) - return; kfree(rdi->qp_dev->qp_table); free_qpn_table(&rdi->qp_dev->qpn_table); @@ -895,21 +896,19 @@ qp->s_tail_ack_queue = 0; qp->s_acked_ack_queue = 0; qp->s_num_rd_atomic = 0; - if (qp->r_rq.kwq) - qp->r_rq.kwq->count = qp->r_rq.size; qp->r_sge.num_sge = 0; atomic_set(&qp->s_reserved_used, 0); } /** - * rvt_reset_qp - initialize the QP state to the reset state + * _rvt_reset_qp - initialize the QP state to the reset state * @qp: the QP to reset * @type: the QP type * * r_lock, s_hlock, and s_lock are required to be held by the caller */ -static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, - enum ib_qp_type type) +static void _rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type) __must_hold(&qp->s_lock) __must_hold(&qp->s_hlock) __must_hold(&qp->r_lock) @@ -955,6 +954,27 @@ lockdep_assert_held(&qp->s_lock); } +/** + * rvt_reset_qp - initialize the QP state to the reset state + * @rdi: the device info + * @qp: the QP to reset + * @type: the QP type + * + * This is the wrapper function to acquire the r_lock, s_hlock, and s_lock + * before calling _rvt_reset_qp(). + */ +static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp, + enum ib_qp_type type) +{ + spin_lock_irq(&qp->r_lock); + spin_lock(&qp->s_hlock); + spin_lock(&qp->s_lock); + _rvt_reset_qp(rdi, qp, type); + spin_unlock(&qp->s_lock); + spin_unlock(&qp->s_hlock); + spin_unlock_irq(&qp->r_lock); +} + /** rvt_free_qpn - Free a qpn from the bit map * @qpt: QP table * @qpn: queue pair number to free @@ -1172,7 +1192,7 @@ err = alloc_ud_wq_attr(qp, rdi->dparms.node); if (err) { ret = (ERR_PTR(err)); - goto bail_driver_priv; + goto bail_rq_rvt; } err = alloc_qpn(rdi, &rdi->qp_dev->qpn_table, @@ -1220,8 +1240,8 @@ qp->ip = rvt_create_mmap_info(rdi, s, udata, qp->r_rq.wq); - if (!qp->ip) { - ret = ERR_PTR(-ENOMEM); + if (IS_ERR(qp->ip)) { + ret = ERR_CAST(qp->ip); goto bail_qpn; } @@ -1276,9 +1296,11 @@ rvt_free_qpn(&rdi->qp_dev->qpn_table, qp->ibqp.qp_num); bail_rq_wq: - rvt_free_rq(&qp->r_rq); free_ud_wq_attr(qp); +bail_rq_rvt: + rvt_free_rq(&qp->r_rq); + bail_driver_priv: rdi->driver_f.qp_priv_free(rdi, qp); @@ -1546,7 +1568,7 @@ switch (new_state) { case IB_QPS_RESET: if (qp->state != IB_QPS_RESET) - rvt_reset_qp(rdi, qp, ibqp->qp_type); + _rvt_reset_qp(rdi, qp, ibqp->qp_type); break; case IB_QPS_RTR: @@ -1695,13 +1717,7 @@ struct rvt_qp *qp = ibqp_to_rvtqp(ibqp); struct rvt_dev_info *rdi = ib_to_rvt(ibqp->device); - spin_lock_irq(&qp->r_lock); - spin_lock(&qp->s_hlock); - spin_lock(&qp->s_lock); rvt_reset_qp(rdi, qp, ibqp->qp_type); - spin_unlock(&qp->s_lock); - spin_unlock(&qp->s_hlock); - spin_unlock_irq(&qp->r_lock); wait_event(qp->wait, !atomic_read(&qp->refcount)); /* qpn is now available for use again */ @@ -2333,31 +2349,6 @@ } /** - * get_count - count numbers of request work queue entries - * in circular buffer - * @rq: data structure for request queue entry - * @tail: tail indices of the circular buffer - * @head: head indices of the circular buffer - * - * Return - total number of entries in the circular buffer - */ -static u32 get_count(struct rvt_rq *rq, u32 tail, u32 head) -{ - u32 count; - - count = head; - - if (count >= rq->size) - count = 0; - if (count < tail) - count += rq->size - tail; - else - count -= tail; - - return count; -} - -/** * get_rvt_head - get head indices of the circular buffer * @rq: data structure for request queue entry * @ip: the QP @@ -2431,7 +2422,7 @@ if (kwq->count < RVT_RWQ_COUNT_THRESHOLD) { head = get_rvt_head(rq, ip); - kwq->count = get_count(rq, tail, head); + kwq->count = rvt_get_rq_count(rq, head, tail); } if (unlikely(kwq->count == 0)) { ret = 0; @@ -2466,7 +2457,9 @@ * the number of remaining WQEs. */ if (kwq->count < srq->limit) { - kwq->count = get_count(rq, tail, get_rvt_head(rq, ip)); + kwq->count = + rvt_get_rq_count(rq, + get_rvt_head(rq, ip), tail); if (kwq->count < srq->limit) { struct ib_event ev; @@ -2817,7 +2810,7 @@ EXPORT_SYMBOL(rvt_qp_iter); /* - * This should be called with s_lock held. + * This should be called with s_lock and r_lock held. */ void rvt_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe, enum ib_wc_status status) @@ -3115,6 +3108,8 @@ case IB_WR_ATOMIC_FETCH_AND_ADD: if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC))) goto inv_err; + if (unlikely(wqe->atomic_wr.remote_addr & (sizeof(u64) - 1))) + goto inv_err; if (unlikely(!rvt_rkey_ok(qp, &qp->r_sge.sge, sizeof(u64), wqe->atomic_wr.remote_addr, wqe->atomic_wr.rkey, @@ -3174,7 +3169,9 @@ rvp->n_loop_pkts++; flush_send: sqp->s_rnr_retry = sqp->s_rnr_retry_cnt; + spin_lock(&sqp->r_lock); rvt_send_complete(sqp, wqe, send_status); + spin_unlock(&sqp->r_lock); if (local_ops) { atomic_dec(&sqp->local_ops_pending); local_ops = 0; @@ -3228,9 +3225,15 @@ spin_unlock_irqrestore(&qp->r_lock, flags); serr_no_r_lock: spin_lock_irqsave(&sqp->s_lock, flags); + spin_lock(&sqp->r_lock); rvt_send_complete(sqp, wqe, send_status); + spin_unlock(&sqp->r_lock); if (sqp->ibqp.qp_type == IB_QPT_RC) { - int lastwqe = rvt_error_qp(sqp, IB_WC_WR_FLUSH_ERR); + int lastwqe; + + spin_lock(&sqp->r_lock); + lastwqe = rvt_error_qp(sqp, IB_WC_WR_FLUSH_ERR); + spin_unlock(&sqp->r_lock); sqp->s_flags &= ~RVT_S_BUSY; spin_unlock_irqrestore(&sqp->s_lock, flags); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/rc.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/rc.c @@ -127,9 +127,7 @@ * not atomic, which is OK, since the fuzziness is * resolved as further ACKs go out. */ - credits = head - tail; - if ((int)credits < 0) - credits += qp->r_rq.size; + credits = rvt_get_rq_count(&qp->r_rq, head, tail); } /* * Binary search the credit table to find the code to --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/srq.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/srq.c @@ -111,8 +111,8 @@ u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz; srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); - if (!srq->ip) { - ret = -ENOMEM; + if (IS_ERR(srq->ip)) { + ret = PTR_ERR(srq->ip); goto bail_wq; } --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rdmavt/vt.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rdmavt/vt.c @@ -95,9 +95,7 @@ if (!rdi) return rdi; - rdi->ports = kcalloc(nports, - sizeof(struct rvt_ibport **), - GFP_KERNEL); + rdi->ports = kcalloc(nports, sizeof(*rdi->ports), GFP_KERNEL); if (!rdi->ports) ib_dealloc_device(&rdi->ibdev); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/Kconfig +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/Kconfig @@ -2,8 +2,9 @@ config RDMA_RXE tristate "Software RDMA over Ethernet (RoCE) driver" depends on INET && PCI && INFINIBAND - depends on !64BIT || ARCH_DMA_ADDR_T_64BIT + depends on INFINIBAND_VIRT_DMA select NET_UDP_TUNNEL + select CRYPTO select CRYPTO_CRC32 select DMA_VIRT_OPS ---help--- --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe.c @@ -48,6 +48,8 @@ } +bool rxe_initialized; + /* free resources for a rxe device all objects created for this device must * have been destroyed */ @@ -70,6 +72,8 @@ if (rxe->tfm) crypto_free_shash(rxe->tfm); + + mutex_destroy(&rxe->usdev_lock); } /* initialize rxe device parameters */ @@ -116,6 +120,8 @@ rxe->attr.max_fast_reg_page_list_len = RXE_MAX_FMR_PAGE_LIST_LEN; rxe->attr.max_pkeys = RXE_MAX_PKEYS; rxe->attr.local_ca_ack_delay = RXE_LOCAL_CA_ACK_DELAY; + addrconf_addr_eui48((unsigned char *)&rxe->attr.sys_image_guid, + rxe->ndev->dev_addr); rxe->max_ucontext = RXE_MAX_UCONTEXT; } @@ -157,9 +163,6 @@ rxe_init_port_param(port); - if (!port->attr.pkey_tbl_len || !port->attr.gid_tbl_len) - return -EINVAL; - port->pkey_tbl = kcalloc(port->attr.pkey_tbl_len, sizeof(*port->pkey_tbl), GFP_KERNEL); @@ -358,6 +361,7 @@ return err; rdma_link_register(&rxe_link_ops); + rxe_initialized = true; pr_info("loaded\n"); return 0; } @@ -369,6 +373,7 @@ rxe_net_exit(); rxe_cache_exit(); + rxe_initialized = false; pr_info("unloaded\n"); } --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe.h +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe.h @@ -67,6 +67,8 @@ #define RXE_ROCE_V2_SPORT (0xc000) +extern bool rxe_initialized; + static inline u32 rxe_crc32(struct rxe_dev *rxe, u32 crc, void *next, size_t len) { --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_comp.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_comp.c @@ -150,12 +150,12 @@ { int must_sched; - skb_queue_tail(&qp->resp_pkts, skb); - - must_sched = skb_queue_len(&qp->resp_pkts) > 1; + must_sched = skb_queue_len(&qp->resp_pkts) > 0; if (must_sched != 0) rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED); + skb_queue_tail(&qp->resp_pkts, skb); + rxe_run_task(&qp->comp.task, must_sched); } @@ -329,7 +329,7 @@ qp->comp.psn = pkt->psn; if (qp->req.wait_psn) { qp->req.wait_psn = 0; - rxe_run_task(&qp->req.task, 1); + rxe_run_task(&qp->req.task, 0); } } return COMPST_ERROR_RETRY; @@ -373,13 +373,15 @@ ret = copy_data(qp->pd, IB_ACCESS_LOCAL_WRITE, &wqe->dma, payload_addr(pkt), payload_size(pkt), to_mem_obj, NULL); - if (ret) + if (ret) { + wqe->status = IB_WC_LOC_PROT_ERR; return COMPST_ERROR; + } if (wqe->dma.resid == 0 && (pkt->mask & RXE_END_MASK)) return COMPST_COMP_ACK; - else - return COMPST_UPDATE_COMP; + + return COMPST_UPDATE_COMP; } static inline enum comp_state do_atomic(struct rxe_qp *qp, @@ -393,10 +395,12 @@ ret = copy_data(qp->pd, IB_ACCESS_LOCAL_WRITE, &wqe->dma, &atomic_orig, sizeof(u64), to_mem_obj, NULL); - if (ret) + if (ret) { + wqe->status = IB_WC_LOC_PROT_ERR; return COMPST_ERROR; - else - return COMPST_COMP_ACK; + } + + return COMPST_COMP_ACK; } static void make_send_cqe(struct rxe_qp *qp, struct rxe_send_wqe *wqe, @@ -463,7 +467,7 @@ */ if (qp->req.wait_fence) { qp->req.wait_fence = 0; - rxe_run_task(&qp->req.task, 1); + rxe_run_task(&qp->req.task, 0); } } @@ -479,7 +483,7 @@ if (qp->req.need_rd_atomic) { qp->comp.timeout_retry = 0; qp->req.need_rd_atomic = 0; - rxe_run_task(&qp->req.task, 1); + rxe_run_task(&qp->req.task, 0); } } @@ -725,7 +729,7 @@ RXE_CNT_COMP_RETRY); qp->req.need_retry = 1; qp->comp.started_retry = 1; - rxe_run_task(&qp->req.task, 1); + rxe_run_task(&qp->req.task, 0); } if (pkt) { --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_mmap.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_mmap.c @@ -151,7 +151,7 @@ ip = kmalloc(sizeof(*ip), GFP_KERNEL); if (!ip) - return NULL; + return ERR_PTR(-ENOMEM); size = PAGE_ALIGN(size); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_mr.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_mr.c @@ -169,11 +169,11 @@ void *vaddr; int err; - umem = ib_umem_get(udata, start, length, access, 0); + umem = ib_umem_get(pd->ibpd.device, start, length, access); if (IS_ERR(umem)) { pr_warn("err %d from rxe_umem_get\n", (int)PTR_ERR(umem)); - err = -EINVAL; + err = PTR_ERR(umem); goto err1; } @@ -207,6 +207,7 @@ vaddr = page_address(sg_page_iter_page(&sg_iter)); if (!vaddr) { pr_warn("null vaddr\n"); + ib_umem_release(umem); err = -ENOMEM; goto err1; } --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_net.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_net.c @@ -117,10 +117,12 @@ memcpy(&fl6.daddr, daddr, sizeof(*daddr)); fl6.flowi6_proto = IPPROTO_UDP; - if (unlikely(ipv6_stub->ipv6_dst_lookup(sock_net(recv_sockets.sk6->sk), - recv_sockets.sk6->sk, &ndst, &fl6))) { + ndst = ipv6_stub->ipv6_dst_lookup_flow(sock_net(recv_sockets.sk6->sk), + recv_sockets.sk6->sk, &fl6, + NULL); + if (unlikely(IS_ERR(ndst))) { pr_err_ratelimited("no route to %pI6\n", daddr); - goto put; + return NULL; } if (unlikely(ndst->error)) { @@ -249,10 +251,8 @@ /* Create UDP socket */ err = udp_sock_create(net, &udp_cfg, &sock); - if (err < 0) { - pr_err("failed to create udp socket. err = %d\n", err); + if (err < 0) return ERR_PTR(err); - } tnl_cfg.encap_type = 1; tnl_cfg.encap_rcv = rxe_udp_encap_recv; @@ -451,6 +451,11 @@ void rxe_loopback(struct sk_buff *skb) { + if (skb->protocol == htons(ETH_P_IP)) + skb_pull(skb, sizeof(struct iphdr)); + else + skb_pull(skb, sizeof(struct ipv6hdr)); + rxe_rcv(skb); } @@ -653,6 +658,12 @@ recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, htons(ROCE_V2_UDP_DPORT), true); + if (PTR_ERR(recv_sockets.sk6) == -EAFNOSUPPORT) { + recv_sockets.sk6 = NULL; + pr_warn("IPv6 is not supported, can not create a UDPv6 socket\n"); + return 0; + } + if (IS_ERR(recv_sockets.sk6)) { recv_sockets.sk6 = NULL; pr_err("Failed to create IPv6 UDP tunnel\n"); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_opcode.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_opcode.c @@ -137,7 +137,7 @@ } }, [IB_OPCODE_RC_SEND_MIDDLE] = { - .name = "IB_OPCODE_RC_SEND_MIDDLE]", + .name = "IB_OPCODE_RC_SEND_MIDDLE", .mask = RXE_PAYLOAD_MASK | RXE_REQ_MASK | RXE_SEND_MASK | RXE_MIDDLE_MASK, .length = RXE_BTH_BYTES, --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_param.h +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_param.h @@ -140,7 +140,7 @@ /* default/initial rxe port parameters */ enum rxe_port_param { RXE_PORT_GID_TBL_LEN = 1024, - RXE_PORT_PORT_CAP_FLAGS = RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP, + RXE_PORT_PORT_CAP_FLAGS = IB_PORT_CM_SUP, RXE_PORT_MAX_MSG_SZ = 0x800000, RXE_PORT_BAD_PKEY_CNTR = 0, RXE_PORT_QKEY_VIOL_CNTR = 0, --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_qp.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_qp.c @@ -152,7 +152,6 @@ void free_rd_atomic_resource(struct rxe_qp *qp, struct resp_res *res) { if (res->type == RXE_ATOMIC_MASK) { - rxe_drop_ref(qp); kfree_skb(res->atomic.skb); } else if (res->type == RXE_READ_MASK) { if (res->read.mr) @@ -212,6 +211,17 @@ spin_lock_init(&qp->grp_lock); spin_lock_init(&qp->state_lock); + spin_lock_init(&qp->req.task.state_lock); + spin_lock_init(&qp->resp.task.state_lock); + spin_lock_init(&qp->comp.task.state_lock); + + spin_lock_init(&qp->sq.sq_lock); + spin_lock_init(&qp->rq.producer_lock); + spin_lock_init(&qp->rq.consumer_lock); + + skb_queue_head_init(&qp->req_pkts); + skb_queue_head_init(&qp->resp_pkts); + atomic_set(&qp->ssn, 0); atomic_set(&qp->skb_out, 0); } @@ -260,6 +270,7 @@ if (err) { vfree(qp->sq.queue->buf); kfree(qp->sq.queue); + qp->sq.queue = NULL; return err; } @@ -268,13 +279,8 @@ qp->req.opcode = -1; qp->comp.opcode = -1; - spin_lock_init(&qp->sq.sq_lock); - skb_queue_head_init(&qp->req_pkts); - - rxe_init_task(rxe, &qp->req.task, qp, - rxe_requester, "req"); - rxe_init_task(rxe, &qp->comp.task, qp, - rxe_completer, "comp"); + rxe_init_task(&qp->req.task, qp, rxe_requester); + rxe_init_task(&qp->comp.task, qp, rxe_completer); qp->qp_timeout_jiffies = 0; /* Can't be set for UD/UC in modify_qp */ if (init->qp_type == IB_QPT_RC) { @@ -313,17 +319,12 @@ if (err) { vfree(qp->rq.queue->buf); kfree(qp->rq.queue); + qp->rq.queue = NULL; return err; } } - spin_lock_init(&qp->rq.producer_lock); - spin_lock_init(&qp->rq.consumer_lock); - - skb_queue_head_init(&qp->resp_pkts); - - rxe_init_task(rxe, &qp->resp.task, qp, - rxe_responder, "resp"); + rxe_init_task(&qp->resp.task, qp, rxe_responder); qp->resp.opcode = OPCODE_NONE; qp->resp.msn = 0; @@ -373,6 +374,11 @@ err2: rxe_queue_cleanup(qp->sq.queue); err1: + qp->pd = NULL; + qp->rcq = NULL; + qp->scq = NULL; + qp->srq = NULL; + if (srq) rxe_drop_ref(srq); rxe_drop_ref(scq); @@ -592,15 +598,16 @@ int err; if (mask & IB_QP_MAX_QP_RD_ATOMIC) { - int max_rd_atomic = __roundup_pow_of_two(attr->max_rd_atomic); + int max_rd_atomic = attr->max_rd_atomic ? + roundup_pow_of_two(attr->max_rd_atomic) : 0; qp->attr.max_rd_atomic = max_rd_atomic; atomic_set(&qp->req.rd_atomic, max_rd_atomic); } if (mask & IB_QP_MAX_DEST_RD_ATOMIC) { - int max_dest_rd_atomic = - __roundup_pow_of_two(attr->max_dest_rd_atomic); + int max_dest_rd_atomic = attr->max_dest_rd_atomic ? + roundup_pow_of_two(attr->max_dest_rd_atomic) : 0; qp->attr.max_dest_rd_atomic = max_dest_rd_atomic; @@ -794,7 +801,9 @@ rxe_cleanup_task(&qp->comp.task); /* flush out any receive wr's or pending requests */ - __rxe_do_task(&qp->req.task); + if (qp->req.task.func) + __rxe_do_task(&qp->req.task); + if (qp->sq.queue) { __rxe_do_task(&qp->comp.task); __rxe_do_task(&qp->req.task); @@ -829,13 +838,15 @@ qp->resp.mr = NULL; } - if (qp_type(qp) == IB_QPT_RC) - sk_dst_reset(qp->sk->sk); - free_rd_atomic_resources(qp); - kernel_sock_shutdown(qp->sk, SHUT_RDWR); - sock_release(qp->sk); + if (qp->sk) { + if (qp_type(qp) == IB_QPT_RC) + sk_dst_reset(qp->sk->sk); + + kernel_sock_shutdown(qp->sk, SHUT_RDWR); + sock_release(qp->sk); + } } /* called when the last reference to the qp is dropped */ --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_queue.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_queue.c @@ -45,12 +45,15 @@ if (outbuf) { ip = rxe_create_mmap_info(rxe, buf_size, udata, buf); - if (!ip) + if (IS_ERR(ip)) { + err = PTR_ERR(ip); goto err1; + } - err = copy_to_user(outbuf, &ip->info, sizeof(ip->info)); - if (err) + if (copy_to_user(outbuf, &ip->info, sizeof(ip->info))) { + err = -EFAULT; goto err2; + } spin_lock_bh(&rxe->pending_lock); list_add(&ip->pending_mmaps, &rxe->pending_mmaps); @@ -64,7 +67,7 @@ err2: kfree(ip); err1: - return -EINVAL; + return err; } inline void rxe_queue_reset(struct rxe_queue *q) --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_recv.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_recv.c @@ -36,21 +36,26 @@ #include "rxe.h" #include "rxe_loc.h" +/* check that QP matches packet opcode type and is in a valid state */ static int check_type_state(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct rxe_qp *qp) { + unsigned int pkt_type; + if (unlikely(!qp->valid)) goto err1; + pkt_type = pkt->opcode & 0xe0; + switch (qp_type(qp)) { case IB_QPT_RC: - if (unlikely((pkt->opcode & IB_OPCODE_RC) != 0)) { + if (unlikely(pkt_type != IB_OPCODE_RC)) { pr_warn_ratelimited("bad qp type\n"); goto err1; } break; case IB_QPT_UC: - if (unlikely(!(pkt->opcode & IB_OPCODE_UC))) { + if (unlikely(pkt_type != IB_OPCODE_UC)) { pr_warn_ratelimited("bad qp type\n"); goto err1; } @@ -58,7 +63,7 @@ case IB_QPT_UD: case IB_QPT_SMI: case IB_QPT_GSI: - if (unlikely(!(pkt->opcode & IB_OPCODE_UD))) { + if (unlikely(pkt_type != IB_OPCODE_UD)) { pr_warn_ratelimited("bad qp type\n"); goto err1; } @@ -281,6 +286,8 @@ struct rxe_mc_elem *mce; struct rxe_qp *qp; union ib_gid dgid; + struct sk_buff *per_qp_skb; + struct rxe_pkt_info *per_qp_pkt; int err; if (skb->protocol == htons(ETH_P_IP)) @@ -298,7 +305,6 @@ list_for_each_entry(mce, &mcg->qp_list, qp_list) { qp = mce->qp; - pkt = SKB_TO_PKT(skb); /* validate qp for incoming packet */ err = check_type_state(rxe, pkt, qp); @@ -309,15 +315,27 @@ if (err) continue; - /* if *not* the last qp in the list - * increase the users of the skb then post to the next qp + /* for all but the last qp create a new clone of the + * skb and pass to the qp. If an error occurs in the + * checks for the last qp in the list we need to + * free the skb since it hasn't been passed on to + * rxe_rcv_pkt() which would free it later. */ - if (mce->qp_list.next != &mcg->qp_list) - skb_get(skb); + if (mce->qp_list.next != &mcg->qp_list) { + per_qp_skb = skb_clone(skb, GFP_ATOMIC); + } else { + per_qp_skb = skb; + /* show we have consumed the skb */ + skb = NULL; + } - pkt->qp = qp; + if (unlikely(!per_qp_skb)) + continue; + + per_qp_pkt = SKB_TO_PKT(per_qp_skb); + per_qp_pkt->qp = qp; rxe_add_ref(qp); - rxe_rcv_pkt(pkt, skb); + rxe_rcv_pkt(per_qp_pkt, per_qp_skb); } spin_unlock_bh(&mcg->mcg_lock); @@ -325,15 +343,20 @@ rxe_drop_ref(mcg); /* drop ref from rxe_pool_get_key. */ err1: + /* free skb if not consumed */ kfree_skb(skb); } static int rxe_match_dgid(struct rxe_dev *rxe, struct sk_buff *skb) { + struct rxe_pkt_info *pkt = SKB_TO_PKT(skb); const struct ib_gid_attr *gid_attr; union ib_gid dgid; union ib_gid *pdgid; + if (pkt->mask & RXE_LOOPBACK_MASK) + return 0; + if (skb->protocol == htons(ETH_P_IP)) { ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr, (struct in6_addr *)&dgid); @@ -366,7 +389,7 @@ if (unlikely(skb->len < pkt->offset + RXE_BTH_BYTES)) goto drop; - if (unlikely(rxe_match_dgid(rxe, skb) < 0)) { + if (rxe_match_dgid(rxe, skb) < 0) { pr_warn_ratelimited("failed matching dgid\n"); goto drop; } @@ -389,7 +412,7 @@ calc_icrc = rxe_icrc_hdr(pkt, skb); calc_icrc = rxe_crc32(rxe, calc_icrc, (u8 *)payload_addr(pkt), - payload_size(pkt)); + payload_size(pkt) + bth_pad(pkt)); calc_icrc = (__force u32)cpu_to_be32(~calc_icrc); if (unlikely(calc_icrc != pack_icrc)) { if (skb->protocol == htons(ETH_P_IPV6)) --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_req.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_req.c @@ -390,7 +390,7 @@ int solicited; u16 pkey; u32 qp_num; - int ack_req; + int ack_req = 0; /* length from start of bth to end of icrc */ paylen = rxe_opcode[opcode].length + payload + pad + RXE_ICRC_SIZE; @@ -426,8 +426,9 @@ qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn : qp->attr.dest_qp_num; - ack_req = ((pkt->mask & RXE_END_MASK) || - (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK)); + if (qp_type(qp) != IB_QPT_UD && qp_type(qp) != IB_QPT_UC) + ack_req = ((pkt->mask & RXE_END_MASK) || + (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK)); if (ack_req) qp->req.noack_pkts = 0; @@ -500,6 +501,12 @@ if (err) return err; } + if (bth_pad(pkt)) { + u8 *pad = payload_addr(pkt) + paylen; + + memset(pad, 0, bth_pad(pkt)); + crc = rxe_crc32(rxe, crc, pad, bth_pad(pkt)); + } } p = payload_addr(pkt) + paylen + bth_pad(pkt); @@ -658,7 +665,8 @@ } if (unlikely(qp_type(qp) == IB_QPT_RC && - qp->req.psn > (qp->comp.psn + RXE_MAX_UNACKED_PSNS))) { + psn_compare(qp->req.psn, (qp->comp.psn + + RXE_MAX_UNACKED_PSNS)) > 0)) { qp->req.wait_psn = 1; goto exit; } @@ -673,7 +681,7 @@ opcode = next_opcode(qp, wqe, wqe->wr.opcode); if (unlikely(opcode < 0)) { wqe->status = IB_WC_LOC_QP_OP_ERR; - goto exit; + goto err; } mask = rxe_opcode[opcode].mask; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_resp.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_resp.c @@ -732,6 +732,13 @@ if (err) pr_err("Failed copying memory\n"); + if (bth_pad(&ack_pkt)) { + struct rxe_dev *rxe = to_rdev(qp->ibqp.device); + u8 *pad = payload_addr(&ack_pkt) + payload; + + memset(pad, 0, bth_pad(&ack_pkt)); + icrc = rxe_crc32(rxe, icrc, pad, bth_pad(&ack_pkt)); + } p = payload_addr(&ack_pkt) + payload + bth_pad(&ack_pkt); *p = ~icrc; @@ -986,8 +993,6 @@ goto out; } - rxe_add_ref(qp); - res = &qp->resp.resources[qp->resp.res_head]; free_rd_atomic_resource(qp, res); rxe_advance_resp_resource(qp); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_sysfs.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_sysfs.c @@ -61,6 +61,11 @@ struct net_device *ndev; struct rxe_dev *exists; + if (!rxe_initialized) { + pr_err("Module parameters are not supported, use rdma link add or rxe_cfg\n"); + return -EAGAIN; + } + len = sanitize_arg(val, intf, sizeof(intf)); if (!len) { pr_err("add: invalid interface name\n"); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_task.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_task.c @@ -114,13 +114,10 @@ task->ret = ret; } -int rxe_init_task(void *obj, struct rxe_task *task, - void *arg, int (*func)(void *), char *name) +int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *)) { - task->obj = obj; task->arg = arg; task->func = func; - snprintf(task->name, sizeof(task->name), "%s", name); task->destroyed = false; tasklet_init(&task->tasklet, rxe_do_task, (unsigned long)task); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_task.h +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_task.h @@ -46,14 +46,12 @@ * called again. */ struct rxe_task { - void *obj; struct tasklet_struct tasklet; int state; spinlock_t state_lock; /* spinlock for task state */ void *arg; int (*func)(void *arg); int ret; - char name[16]; bool destroyed; }; @@ -62,8 +60,7 @@ * arg => parameter to pass to fcn * fcn => function to call until it returns != 0 */ -int rxe_init_task(void *obj, struct rxe_task *task, - void *arg, int (*func)(void *), char *name); +int rxe_init_task(struct rxe_task *task, void *arg, int (*func)(void *)); /* cleanup task */ void rxe_cleanup_task(struct rxe_task *task); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -679,6 +679,7 @@ unsigned int mask; unsigned int length = 0; int i; + struct ib_send_wr *next; while (wr) { mask = wr_opcode_mask(wr->opcode, qp); @@ -695,6 +696,8 @@ break; } + next = wr->next; + length = 0; for (i = 0; i < wr->num_sge; i++) length += wr->sg_list[i].length; @@ -705,7 +708,7 @@ *bad_wr = wr; break; } - wr = wr->next; + wr = next; } rxe_run_task(&qp->req.task, 1); @@ -1075,7 +1078,7 @@ struct rxe_dev *rxe = rdma_device_to_drv_device(device, struct rxe_dev, ib_dev); - return snprintf(buf, 16, "%s\n", rxe_parent_name(rxe, 1)); + return scnprintf(buf, PAGE_SIZE, "%s\n", rxe_parent_name(rxe, 1)); } static DEVICE_ATTR_RO(parent); --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/rxe/rxe_verbs.h +++ linux-oracle-5.4.0/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -407,7 +407,7 @@ struct list_head pending_mmaps; spinlock_t mmap_offset_lock; /* guard mmap_offset */ - int mmap_offset; + u64 mmap_offset; atomic64_t stats_counters[RXE_NUM_OF_COUNTERS]; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/Kconfig +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/Kconfig @@ -1,6 +1,7 @@ config RDMA_SIW tristate "Software RDMA over TCP/IP (iWARP) driver" depends on INET && INFINIBAND && LIBCRC32C + depends on INFINIBAND_VIRT_DMA select DMA_VIRT_OPS help This driver implements the iWARP RDMA transport over --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw.h +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw.h @@ -658,16 +658,11 @@ return &qp->orq[qp->orq_get % qp->attrs.orq_size]; } -static inline struct siw_sqe *orq_get_tail(struct siw_qp *qp) -{ - return &qp->orq[qp->orq_put % qp->attrs.orq_size]; -} - static inline struct siw_sqe *orq_get_free(struct siw_qp *qp) { - struct siw_sqe *orq_e = orq_get_tail(qp); + struct siw_sqe *orq_e = &qp->orq[qp->orq_put % qp->attrs.orq_size]; - if (orq_e && READ_ONCE(orq_e->flags) == 0) + if (READ_ONCE(orq_e->flags) == 0) return orq_e; return NULL; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_cm.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_cm.c @@ -725,11 +725,11 @@ enum mpa_v2_ctrl mpa_p2p_mode = MPA_V2_RDMA_NO_RTR; rv = siw_recv_mpa_rr(cep); - if (rv != -EAGAIN) - siw_cancel_mpatimer(cep); if (rv) goto out_err; + siw_cancel_mpatimer(cep); + rep = &cep->mpa.hdr; if (__mpa_rr_revision(rep->params.bits) > MPA_REVISION_2) { @@ -895,7 +895,8 @@ } out_err: - siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL); + if (rv != -EAGAIN) + siw_cm_upcall(cep, IW_CM_EVENT_CONNECT_REPLY, -EINVAL); return rv; } @@ -976,14 +977,16 @@ siw_cep_set_inuse(new_cep); rv = siw_proc_mpareq(new_cep); - siw_cep_set_free(new_cep); - if (rv != -EAGAIN) { siw_cep_put(cep); new_cep->listen_cep = NULL; - if (rv) + if (rv) { + siw_cancel_mpatimer(new_cep); + siw_cep_set_free(new_cep); goto error; + } } + siw_cep_set_free(new_cep); } return; @@ -1103,9 +1106,12 @@ /* * Socket close before MPA request received. */ - siw_dbg_cep(cep, "no mpareq: drop listener\n"); - siw_cep_put(cep->listen_cep); - cep->listen_cep = NULL; + if (cep->listen_cep) { + siw_dbg_cep(cep, + "no mpareq: drop listener\n"); + siw_cep_put(cep->listen_cep); + cep->listen_cep = NULL; + } } } release_cep = 1; @@ -1225,11 +1231,14 @@ read_lock(&sk->sk_callback_lock); cep = sk_to_cep(sk); - if (!cep) { - WARN_ON(1); + if (!cep) + goto out; + + siw_dbg_cep(cep, "cep state: %d, socket state %d\n", + cep->state, sk->sk_state); + + if (sk->sk_state != TCP_ESTABLISHED) goto out; - } - siw_dbg_cep(cep, "state: %d\n", cep->state); switch (cep->state) { case SIW_EPSTATE_RDMA_MODE: @@ -1524,7 +1533,6 @@ cep->cm_id = NULL; id->rem_ref(id); - siw_cep_put(cep); qp->cep = NULL; siw_cep_put(cep); @@ -1784,14 +1792,23 @@ return 0; } -static int siw_listen_address(struct iw_cm_id *id, int backlog, - struct sockaddr *laddr, int addr_family) +/* + * siw_create_listen - Create resources for a listener's IWCM ID @id + * + * Starts listen on the socket address id->local_addr. + * + */ +int siw_create_listen(struct iw_cm_id *id, int backlog) { struct socket *s; struct siw_cep *cep = NULL; struct siw_device *sdev = to_siw_dev(id->device); + int addr_family = id->local_addr.ss_family; int rv = 0, s_val; + if (addr_family != AF_INET && addr_family != AF_INET6) + return -EAFNOSUPPORT; + rv = sock_create(addr_family, SOCK_STREAM, IPPROTO_TCP, &s); if (rv < 0) return rv; @@ -1806,9 +1823,25 @@ siw_dbg(id->device, "setsockopt error: %d\n", rv); goto error; } - rv = s->ops->bind(s, laddr, addr_family == AF_INET ? - sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6)); + if (addr_family == AF_INET) { + struct sockaddr_in *laddr = &to_sockaddr_in(id->local_addr); + + /* For wildcard addr, limit binding to current device only */ + if (ipv4_is_zeronet(laddr->sin_addr.s_addr)) + s->sk->sk_bound_dev_if = sdev->netdev->ifindex; + + rv = s->ops->bind(s, (struct sockaddr *)laddr, + sizeof(struct sockaddr_in)); + } else { + struct sockaddr_in6 *laddr = &to_sockaddr_in6(id->local_addr); + + /* For wildcard addr, limit binding to current device only */ + if (ipv6_addr_any(&laddr->sin6_addr)) + s->sk->sk_bound_dev_if = sdev->netdev->ifindex; + + rv = s->ops->bind(s, (struct sockaddr *)laddr, + sizeof(struct sockaddr_in6)); + } if (rv) { siw_dbg(id->device, "socket bind error: %d\n", rv); goto error; @@ -1867,14 +1900,7 @@ list_add_tail(&cep->listenq, (struct list_head *)id->provider_data); cep->state = SIW_EPSTATE_LISTENING; - if (addr_family == AF_INET) - siw_dbg(id->device, "Listen at laddr %pI4 %u\n", - &(((struct sockaddr_in *)laddr)->sin_addr), - ((struct sockaddr_in *)laddr)->sin_port); - else - siw_dbg(id->device, "Listen at laddr %pI6 %u\n", - &(((struct sockaddr_in6 *)laddr)->sin6_addr), - ((struct sockaddr_in6 *)laddr)->sin6_port); + siw_dbg(id->device, "Listen at laddr %pISp\n", &id->local_addr); return 0; @@ -1932,114 +1958,6 @@ } } -/* - * siw_create_listen - Create resources for a listener's IWCM ID @id - * - * Listens on the socket addresses id->local_addr and id->remote_addr. - * - * If the listener's @id provides a specific local IP address, at most one - * listening socket is created and associated with @id. - * - * If the listener's @id provides the wildcard (zero) local IP address, - * a separate listen is performed for each local IP address of the device - * by creating a listening socket and binding to that local IP address. - * - */ -int siw_create_listen(struct iw_cm_id *id, int backlog) -{ - struct net_device *dev = to_siw_dev(id->device)->netdev; - int rv = 0, listeners = 0; - - siw_dbg(id->device, "backlog %d\n", backlog); - - /* - * For each attached address of the interface, create a - * listening socket, if id->local_addr is the wildcard - * IP address or matches the IP address. - */ - if (id->local_addr.ss_family == AF_INET) { - struct in_device *in_dev = in_dev_get(dev); - struct sockaddr_in s_laddr, *s_raddr; - const struct in_ifaddr *ifa; - - if (!in_dev) { - rv = -ENODEV; - goto out; - } - memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr)); - s_raddr = (struct sockaddr_in *)&id->remote_addr; - - siw_dbg(id->device, - "laddr %pI4:%d, raddr %pI4:%d\n", - &s_laddr.sin_addr, ntohs(s_laddr.sin_port), - &s_raddr->sin_addr, ntohs(s_raddr->sin_port)); - - rtnl_lock(); - in_dev_for_each_ifa_rtnl(ifa, in_dev) { - if (ipv4_is_zeronet(s_laddr.sin_addr.s_addr) || - s_laddr.sin_addr.s_addr == ifa->ifa_address) { - s_laddr.sin_addr.s_addr = ifa->ifa_address; - - rv = siw_listen_address(id, backlog, - (struct sockaddr *)&s_laddr, - AF_INET); - if (!rv) - listeners++; - } - } - rtnl_unlock(); - in_dev_put(in_dev); - } else if (id->local_addr.ss_family == AF_INET6) { - struct inet6_dev *in6_dev = in6_dev_get(dev); - struct inet6_ifaddr *ifp; - struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr), - *s_raddr = &to_sockaddr_in6(id->remote_addr); - - if (!in6_dev) { - rv = -ENODEV; - goto out; - } - siw_dbg(id->device, - "laddr %pI6:%d, raddr %pI6:%d\n", - &s_laddr->sin6_addr, ntohs(s_laddr->sin6_port), - &s_raddr->sin6_addr, ntohs(s_raddr->sin6_port)); - - rtnl_lock(); - list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { - if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) - continue; - if (ipv6_addr_any(&s_laddr->sin6_addr) || - ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) { - struct sockaddr_in6 bind_addr = { - .sin6_family = AF_INET6, - .sin6_port = s_laddr->sin6_port, - .sin6_flowinfo = 0, - .sin6_addr = ifp->addr, - .sin6_scope_id = dev->ifindex }; - - rv = siw_listen_address(id, backlog, - (struct sockaddr *)&bind_addr, - AF_INET6); - if (!rv) - listeners++; - } - } - rtnl_unlock(); - in6_dev_put(in6_dev); - } else { - rv = -EAFNOSUPPORT; - } -out: - if (listeners) - rv = 0; - else if (!rv) - rv = -EINVAL; - - siw_dbg(id->device, "%s\n", rv ? "FAIL" : "OK"); - - return rv; -} - int siw_destroy_listen(struct iw_cm_id *id) { if (!id->provider_data) { --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_cq.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_cq.c @@ -56,8 +56,6 @@ if (READ_ONCE(cqe->flags) & SIW_WQE_VALID) { memset(wc, 0, sizeof(*wc)); wc->wr_id = cqe->id; - wc->status = map_cqe_status[cqe->status].ib; - wc->opcode = map_wc_opcode[cqe->opcode]; wc->byte_len = cqe->bytes; /* @@ -71,10 +69,32 @@ wc->wc_flags = IB_WC_WITH_INVALIDATE; } wc->qp = cqe->base_qp; + wc->opcode = map_wc_opcode[cqe->opcode]; + wc->status = map_cqe_status[cqe->status].ib; siw_dbg_cq(cq, "idx %u, type %d, flags %2x, id 0x%pK\n", cq->cq_get % cq->num_cqe, cqe->opcode, cqe->flags, (void *)(uintptr_t)cqe->id); + } else { + /* + * A malicious user may set invalid opcode or + * status in the user mmapped CQE array. + * Sanity check and correct values in that case + * to avoid out-of-bounds access to global arrays + * for opcode and status mapping. + */ + u8 opcode = cqe->opcode; + u16 status = cqe->status; + + if (opcode >= SIW_NUM_OPCODES) { + opcode = 0; + status = SIW_WC_GENERAL_ERR; + } else if (status >= SIW_NUM_WC_STATUS) { + status = SIW_WC_GENERAL_ERR; + } + wc->opcode = map_wc_opcode[opcode]; + wc->status = map_cqe_status[status].ib; + } WRITE_ONCE(cqe->flags, 0); cq->cq_get++; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_main.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_main.c @@ -66,12 +66,13 @@ static int dev_id = 1; int rv; + sdev->vendor_part_id = dev_id++; + rv = ib_register_device(base_dev, name); if (rv) { pr_warn("siw: device registration error %d\n", rv); return rv; } - sdev->vendor_part_id = dev_id++; siw_dbg(base_dev, "HWaddr=%pM\n", sdev->netdev->dev_addr); @@ -133,7 +134,7 @@ static int siw_init_cpulist(void) { - int i, num_nodes = num_possible_nodes(); + int i, num_nodes = nr_node_ids; memset(siw_tx_thread, 0, sizeof(siw_tx_thread)); @@ -248,24 +249,6 @@ return NULL; } -static void siw_verbs_sq_flush(struct ib_qp *base_qp) -{ - struct siw_qp *qp = to_siw_qp(base_qp); - - down_write(&qp->state_lock); - siw_sq_flush(qp); - up_write(&qp->state_lock); -} - -static void siw_verbs_rq_flush(struct ib_qp *base_qp) -{ - struct siw_qp *qp = to_siw_qp(base_qp); - - down_write(&qp->state_lock); - siw_rq_flush(qp); - up_write(&qp->state_lock); -} - static const struct ib_device_ops siw_device_ops = { .owner = THIS_MODULE, .uverbs_abi_ver = SIW_ABI_VERSION, @@ -284,8 +267,6 @@ .destroy_cq = siw_destroy_cq, .destroy_qp = siw_destroy_qp, .destroy_srq = siw_destroy_srq, - .drain_rq = siw_verbs_rq_flush, - .drain_sq = siw_verbs_sq_flush, .get_dma_mr = siw_get_dma_mr, .get_port_immutable = siw_get_port_immutable, .iw_accept = siw_accept, @@ -399,6 +380,9 @@ base_dev->dev.dma_ops = &dma_virt_ops; base_dev->num_comp_vectors = num_possible_cpus(); + xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); + xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); + ib_set_device_ops(base_dev, &siw_device_ops); rv = ib_device_set_netdev(base_dev, netdev, 1); if (rv) @@ -426,9 +410,6 @@ sdev->attrs.max_srq_wr = SIW_MAX_SRQ_WR; sdev->attrs.max_srq_sge = SIW_MAX_SGE; - xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); - xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); - INIT_LIST_HEAD(&sdev->cep_list); INIT_LIST_HEAD(&sdev->qp_list); @@ -491,9 +472,6 @@ dev_dbg(&netdev->dev, "siw: event %lu\n", event); - if (dev_net(netdev) != &init_net) - return NOTIFY_OK; - base_dev = ib_device_get_by_netdev(netdev, RDMA_DRIVER_SIW); if (!base_dev) return NOTIFY_OK; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_mem.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_mem.c @@ -106,8 +106,6 @@ mem->perms = rights & IWARP_ACCESS_MASK; kref_init(&mem->ref); - mr->mem = mem; - get_random_bytes(&next, 4); next &= 0x00ffffff; @@ -116,6 +114,8 @@ kfree(mem); return -ENOMEM; } + + mr->mem = mem; /* Set the STag index part */ mem->stag = id << 8; mr->base_mr.lkey = mr->base_mr.rkey = mem->stag; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_qp.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_qp.c @@ -199,26 +199,26 @@ static int siw_qp_readq_init(struct siw_qp *qp, int irq_size, int orq_size) { - irq_size = roundup_pow_of_two(irq_size); - orq_size = roundup_pow_of_two(orq_size); - + if (irq_size) { + irq_size = roundup_pow_of_two(irq_size); + qp->irq = vzalloc(irq_size * sizeof(struct siw_sqe)); + if (!qp->irq) { + qp->attrs.irq_size = 0; + return -ENOMEM; + } + } + if (orq_size) { + orq_size = roundup_pow_of_two(orq_size); + qp->orq = vzalloc(orq_size * sizeof(struct siw_sqe)); + if (!qp->orq) { + qp->attrs.orq_size = 0; + qp->attrs.irq_size = 0; + vfree(qp->irq); + return -ENOMEM; + } + } qp->attrs.irq_size = irq_size; qp->attrs.orq_size = orq_size; - - qp->irq = vzalloc(irq_size * sizeof(struct siw_sqe)); - if (!qp->irq) { - siw_dbg_qp(qp, "irq malloc for %d failed\n", irq_size); - qp->attrs.irq_size = 0; - return -ENOMEM; - } - qp->orq = vzalloc(orq_size * sizeof(struct siw_sqe)); - if (!qp->orq) { - siw_dbg_qp(qp, "orq malloc for %d failed\n", orq_size); - qp->attrs.orq_size = 0; - qp->attrs.irq_size = 0; - vfree(qp->irq); - return -ENOMEM; - } siw_dbg_qp(qp, "ORD %d, IRD %d\n", orq_size, irq_size); return 0; } @@ -288,13 +288,14 @@ if (ctrl & MPA_V2_RDMA_WRITE_RTR) wqe->sqe.opcode = SIW_OP_WRITE; else if (ctrl & MPA_V2_RDMA_READ_RTR) { - struct siw_sqe *rreq; + struct siw_sqe *rreq = NULL; wqe->sqe.opcode = SIW_OP_READ; spin_lock(&qp->orq_lock); - rreq = orq_get_free(qp); + if (qp->attrs.orq_size) + rreq = orq_get_free(qp); if (rreq) { siw_read_to_orq(rreq, &wqe->sqe); qp->orq_put++; @@ -877,135 +878,88 @@ rreq->num_sge = 1; } -/* - * Must be called with SQ locked. - * To avoid complete SQ starvation by constant inbound READ requests, - * the active IRQ will not be served after qp->irq_burst, if the - * SQ has pending work. - */ -int siw_activate_tx(struct siw_qp *qp) +static int siw_activate_tx_from_sq(struct siw_qp *qp) { - struct siw_sqe *irqe, *sqe; + struct siw_sqe *sqe; struct siw_wqe *wqe = tx_wqe(qp); int rv = 1; - irqe = &qp->irq[qp->irq_get % qp->attrs.irq_size]; - - if (irqe->flags & SIW_WQE_VALID) { - sqe = sq_get_next(qp); - - /* - * Avoid local WQE processing starvation in case - * of constant inbound READ request stream - */ - if (sqe && ++qp->irq_burst >= SIW_IRQ_MAXBURST_SQ_ACTIVE) { - qp->irq_burst = 0; - goto skip_irq; - } - memset(wqe->mem, 0, sizeof(*wqe->mem) * SIW_MAX_SGE); - wqe->wr_status = SIW_WR_QUEUED; - - /* start READ RESPONSE */ - wqe->sqe.opcode = SIW_OP_READ_RESPONSE; - wqe->sqe.flags = 0; - if (irqe->num_sge) { - wqe->sqe.num_sge = 1; - wqe->sqe.sge[0].length = irqe->sge[0].length; - wqe->sqe.sge[0].laddr = irqe->sge[0].laddr; - wqe->sqe.sge[0].lkey = irqe->sge[0].lkey; - } else { - wqe->sqe.num_sge = 0; - } - - /* Retain original RREQ's message sequence number for - * potential error reporting cases. - */ - wqe->sqe.sge[1].length = irqe->sge[1].length; - - wqe->sqe.rkey = irqe->rkey; - wqe->sqe.raddr = irqe->raddr; + sqe = sq_get_next(qp); + if (!sqe) + return 0; - wqe->processed = 0; - qp->irq_get++; + memset(wqe->mem, 0, sizeof(*wqe->mem) * SIW_MAX_SGE); + wqe->wr_status = SIW_WR_QUEUED; - /* mark current IRQ entry free */ - smp_store_mb(irqe->flags, 0); + /* First copy SQE to kernel private memory */ + memcpy(&wqe->sqe, sqe, sizeof(*sqe)); + if (wqe->sqe.opcode >= SIW_NUM_OPCODES) { + rv = -EINVAL; goto out; } - sqe = sq_get_next(qp); - if (sqe) { -skip_irq: - memset(wqe->mem, 0, sizeof(*wqe->mem) * SIW_MAX_SGE); - wqe->wr_status = SIW_WR_QUEUED; - - /* First copy SQE to kernel private memory */ - memcpy(&wqe->sqe, sqe, sizeof(*sqe)); - - if (wqe->sqe.opcode >= SIW_NUM_OPCODES) { + if (wqe->sqe.flags & SIW_WQE_INLINE) { + if (wqe->sqe.opcode != SIW_OP_SEND && + wqe->sqe.opcode != SIW_OP_WRITE) { rv = -EINVAL; goto out; } - if (wqe->sqe.flags & SIW_WQE_INLINE) { - if (wqe->sqe.opcode != SIW_OP_SEND && - wqe->sqe.opcode != SIW_OP_WRITE) { - rv = -EINVAL; - goto out; - } - if (wqe->sqe.sge[0].length > SIW_MAX_INLINE) { - rv = -EINVAL; - goto out; - } - wqe->sqe.sge[0].laddr = (uintptr_t)&wqe->sqe.sge[1]; - wqe->sqe.sge[0].lkey = 0; - wqe->sqe.num_sge = 1; - } - if (wqe->sqe.flags & SIW_WQE_READ_FENCE) { - /* A READ cannot be fenced */ - if (unlikely(wqe->sqe.opcode == SIW_OP_READ || - wqe->sqe.opcode == - SIW_OP_READ_LOCAL_INV)) { - siw_dbg_qp(qp, "cannot fence read\n"); - rv = -EINVAL; - goto out; - } - spin_lock(&qp->orq_lock); + if (wqe->sqe.sge[0].length > SIW_MAX_INLINE) { + rv = -EINVAL; + goto out; + } + wqe->sqe.sge[0].laddr = (uintptr_t)&wqe->sqe.sge[1]; + wqe->sqe.sge[0].lkey = 0; + wqe->sqe.num_sge = 1; + } + if (wqe->sqe.flags & SIW_WQE_READ_FENCE) { + /* A READ cannot be fenced */ + if (unlikely(wqe->sqe.opcode == SIW_OP_READ || + wqe->sqe.opcode == + SIW_OP_READ_LOCAL_INV)) { + siw_dbg_qp(qp, "cannot fence read\n"); + rv = -EINVAL; + goto out; + } + spin_lock(&qp->orq_lock); - if (!siw_orq_empty(qp)) { - qp->tx_ctx.orq_fence = 1; - rv = 0; - } - spin_unlock(&qp->orq_lock); + if (qp->attrs.orq_size && !siw_orq_empty(qp)) { + qp->tx_ctx.orq_fence = 1; + rv = 0; + } + spin_unlock(&qp->orq_lock); - } else if (wqe->sqe.opcode == SIW_OP_READ || - wqe->sqe.opcode == SIW_OP_READ_LOCAL_INV) { - struct siw_sqe *rreq; + } else if (wqe->sqe.opcode == SIW_OP_READ || + wqe->sqe.opcode == SIW_OP_READ_LOCAL_INV) { + struct siw_sqe *rreq; - wqe->sqe.num_sge = 1; + if (unlikely(!qp->attrs.orq_size)) { + /* We negotiated not to send READ req's */ + rv = -EINVAL; + goto out; + } + wqe->sqe.num_sge = 1; - spin_lock(&qp->orq_lock); + spin_lock(&qp->orq_lock); - rreq = orq_get_free(qp); - if (rreq) { - /* - * Make an immediate copy in ORQ to be ready - * to process loopback READ reply - */ - siw_read_to_orq(rreq, &wqe->sqe); - qp->orq_put++; - } else { - qp->tx_ctx.orq_fence = 1; - rv = 0; - } - spin_unlock(&qp->orq_lock); + rreq = orq_get_free(qp); + if (rreq) { + /* + * Make an immediate copy in ORQ to be ready + * to process loopback READ reply + */ + siw_read_to_orq(rreq, &wqe->sqe); + qp->orq_put++; + } else { + qp->tx_ctx.orq_fence = 1; + rv = 0; } - - /* Clear SQE, can be re-used by application */ - smp_store_mb(sqe->flags, 0); - qp->sq_get++; - } else { - rv = 0; + spin_unlock(&qp->orq_lock); } + + /* Clear SQE, can be re-used by application */ + smp_store_mb(sqe->flags, 0); + qp->sq_get++; out: if (unlikely(rv < 0)) { siw_dbg_qp(qp, "error %d\n", rv); @@ -1015,6 +969,65 @@ } /* + * Must be called with SQ locked. + * To avoid complete SQ starvation by constant inbound READ requests, + * the active IRQ will not be served after qp->irq_burst, if the + * SQ has pending work. + */ +int siw_activate_tx(struct siw_qp *qp) +{ + struct siw_sqe *irqe; + struct siw_wqe *wqe = tx_wqe(qp); + + if (!qp->attrs.irq_size) + return siw_activate_tx_from_sq(qp); + + irqe = &qp->irq[qp->irq_get % qp->attrs.irq_size]; + + if (!(irqe->flags & SIW_WQE_VALID)) + return siw_activate_tx_from_sq(qp); + + /* + * Avoid local WQE processing starvation in case + * of constant inbound READ request stream + */ + if (sq_get_next(qp) && ++qp->irq_burst >= SIW_IRQ_MAXBURST_SQ_ACTIVE) { + qp->irq_burst = 0; + return siw_activate_tx_from_sq(qp); + } + memset(wqe->mem, 0, sizeof(*wqe->mem) * SIW_MAX_SGE); + wqe->wr_status = SIW_WR_QUEUED; + + /* start READ RESPONSE */ + wqe->sqe.opcode = SIW_OP_READ_RESPONSE; + wqe->sqe.flags = 0; + if (irqe->num_sge) { + wqe->sqe.num_sge = 1; + wqe->sqe.sge[0].length = irqe->sge[0].length; + wqe->sqe.sge[0].laddr = irqe->sge[0].laddr; + wqe->sqe.sge[0].lkey = irqe->sge[0].lkey; + } else { + wqe->sqe.num_sge = 0; + } + + /* Retain original RREQ's message sequence number for + * potential error reporting cases. + */ + wqe->sqe.sge[1].length = irqe->sge[1].length; + + wqe->sqe.rkey = irqe->rkey; + wqe->sqe.raddr = irqe->raddr; + + wqe->processed = 0; + qp->irq_get++; + + /* mark current IRQ entry free */ + smp_store_mb(irqe->flags, 0); + + return 1; +} + +/* * Check if current CQ state qualifies for calling CQ completion * handler. Must be called with CQ lock held. */ --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_qp_rx.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_qp_rx.c @@ -139,7 +139,8 @@ break; bytes = min(bytes, len); - if (siw_rx_kva(srx, (void *)buf_addr, bytes) == bytes) { + if (siw_rx_kva(srx, (void *)(uintptr_t)buf_addr, bytes) == + bytes) { copied += bytes; offset += bytes; len -= bytes; @@ -679,6 +680,10 @@ } spin_lock_irqsave(&qp->sq_lock, flags); + if (unlikely(!qp->attrs.irq_size)) { + run_sq = 0; + goto error_irq; + } if (tx_work->wr_status == SIW_WR_IDLE) { /* * immediately schedule READ response w/o @@ -711,8 +716,9 @@ /* RRESP now valid as current TX wqe or placed into IRQ */ smp_store_mb(resp->flags, SIW_WQE_VALID); } else { - pr_warn("siw: [QP %u]: irq %d exceeded %d\n", qp_id(qp), - qp->irq_put % qp->attrs.irq_size, qp->attrs.irq_size); +error_irq: + pr_warn("siw: [QP %u]: IRQ exceeded or null, size %d\n", + qp_id(qp), qp->attrs.irq_size); siw_init_terminate(qp, TERM_ERROR_LAYER_RDMAP, RDMAP_ETYPE_REMOTE_OPERATION, @@ -739,6 +745,9 @@ struct siw_sqe *orqe; struct siw_wqe *wqe = NULL; + if (unlikely(!qp->attrs.orq_size)) + return -EPROTO; + /* make sure ORQ indices are current */ smp_mb(); @@ -795,8 +804,8 @@ */ rv = siw_orqe_start_rx(qp); if (rv) { - pr_warn("siw: [QP %u]: ORQ empty at idx %d\n", - qp_id(qp), qp->orq_get % qp->attrs.orq_size); + pr_warn("siw: [QP %u]: ORQ empty, size %d\n", + qp_id(qp), qp->attrs.orq_size); goto error_term; } rv = siw_rresp_check_ntoh(srx, frx); @@ -952,27 +961,28 @@ static int siw_get_trailer(struct siw_qp *qp, struct siw_rx_stream *srx) { struct sk_buff *skb = srx->skb; + int avail = min(srx->skb_new, srx->fpdu_part_rem); u8 *tbuf = (u8 *)&srx->trailer.crc - srx->pad; __wsum crc_in, crc_own = 0; siw_dbg_qp(qp, "expected %d, available %d, pad %u\n", srx->fpdu_part_rem, srx->skb_new, srx->pad); - if (srx->skb_new < srx->fpdu_part_rem) - return -EAGAIN; - - skb_copy_bits(skb, srx->skb_offset, tbuf, srx->fpdu_part_rem); + skb_copy_bits(skb, srx->skb_offset, tbuf, avail); - if (srx->mpa_crc_hd && srx->pad) - crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad); + srx->skb_new -= avail; + srx->skb_offset += avail; + srx->skb_copied += avail; + srx->fpdu_part_rem -= avail; - srx->skb_new -= srx->fpdu_part_rem; - srx->skb_offset += srx->fpdu_part_rem; - srx->skb_copied += srx->fpdu_part_rem; + if (srx->fpdu_part_rem) + return -EAGAIN; if (!srx->mpa_crc_hd) return 0; + if (srx->pad) + crypto_shash_update(srx->mpa_crc_hd, tbuf, srx->pad); /* * CRC32 is computed, transmitted and received directly in NBO, * so there's never a reason to convert byte order. @@ -1074,10 +1084,9 @@ * completely received. */ if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) { - bytes = iwarp_pktinfo[opcode].hdr_len - MIN_DDP_HDR; + int hdrlen = iwarp_pktinfo[opcode].hdr_len; - if (srx->skb_new < bytes) - return -EAGAIN; + bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new); skb_copy_bits(skb, srx->skb_offset, (char *)c_hdr + srx->fpdu_part_rcvd, bytes); @@ -1087,6 +1096,9 @@ srx->skb_new -= bytes; srx->skb_offset += bytes; srx->skb_copied += bytes; + + if (srx->fpdu_part_rcvd < hdrlen) + return -EAGAIN; } /* @@ -1144,11 +1156,12 @@ spin_lock_irqsave(&qp->orq_lock, flags); - rreq = orq_get_current(qp); - /* free current orq entry */ + rreq = orq_get_current(qp); WRITE_ONCE(rreq->flags, 0); + qp->orq_get++; + if (qp->tx_ctx.orq_fence) { if (unlikely(tx_waiting->wr_status != SIW_WR_QUEUED)) { pr_warn("siw: [QP %u]: fence resume: bad status %d\n", @@ -1156,10 +1169,12 @@ rv = -EPROTO; goto out; } - /* resume SQ processing */ + /* resume SQ processing, if possible */ if (tx_waiting->sqe.opcode == SIW_OP_READ || tx_waiting->sqe.opcode == SIW_OP_READ_LOCAL_INV) { - rreq = orq_get_tail(qp); + + /* SQ processing was stopped because of a full ORQ */ + rreq = orq_get_free(qp); if (unlikely(!rreq)) { pr_warn("siw: [QP %u]: no ORQE\n", qp_id(qp)); rv = -EPROTO; @@ -1172,15 +1187,14 @@ resume_tx = 1; } else if (siw_orq_empty(qp)) { + /* + * SQ processing was stopped by fenced work request. + * Resume since all previous Read's are now completed. + */ qp->tx_ctx.orq_fence = 0; resume_tx = 1; - } else { - pr_warn("siw: [QP %u]: fence resume: orq idx: %d:%d\n", - qp_id(qp), qp->orq_get, qp->orq_put); - rv = -EPROTO; } } - qp->orq_get++; out: spin_unlock_irqrestore(&qp->orq_lock, flags); @@ -1289,11 +1303,13 @@ wc_status); siw_wqe_put_mem(wqe, SIW_OP_READ); - if (!error) + if (!error) { rv = siw_check_tx_fence(qp); - else - /* Disable current ORQ eleement */ - WRITE_ONCE(orq_get_current(qp)->flags, 0); + } else { + /* Disable current ORQ element */ + if (qp->attrs.orq_size) + WRITE_ONCE(orq_get_current(qp)->flags, 0); + } break; case RDMAP_RDMA_READ_REQ: --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_qp_tx.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -29,7 +29,7 @@ dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx); if (paddr) - return virt_to_page(paddr); + return virt_to_page((void *)(uintptr_t)paddr); return NULL; } @@ -523,13 +523,23 @@ kunmap(p); } } else { - u64 va = sge->laddr + sge_off; + /* + * Cast to an uintptr_t to preserve all 64 bits + * in sge->laddr. + */ + uintptr_t va = (uintptr_t)(sge->laddr + sge_off); - page_array[seg] = virt_to_page(va & PAGE_MASK); + /* + * virt_to_page() takes a (void *) pointer + * so cast to a (void *) meaning it will be 64 + * bits on a 64 bit platform and 32 bits on a + * 32 bit platform. + */ + page_array[seg] = virt_to_page((void *)(va & PAGE_MASK)); if (do_crc) crypto_shash_update( c_tx->mpa_crc_hd, - (void *)(uintptr_t)va, + (void *)va, plen); } @@ -538,7 +548,7 @@ data_len -= plen; fp_off = 0; - if (++seg > (int)MAX_ARRAY) { + if (++seg >= (int)MAX_ARRAY) { siw_dbg_qp(tx_qp(c_tx), "to many fragments\n"); siw_unmap_pages(page_array, kmap_mask); wqe->processed -= c_tx->bytes_unsent; @@ -920,20 +930,27 @@ { struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr; struct siw_device *sdev = to_siw_dev(pd->device); - struct siw_mem *mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); + struct siw_mem *mem; int rv = 0; siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey); - if (unlikely(!mem || !base_mr)) { + if (unlikely(!base_mr)) { pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); return -EINVAL; } + if (unlikely(base_mr->rkey >> 8 != sqe->rkey >> 8)) { pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey); - rv = -EINVAL; - goto out; + return -EINVAL; + } + + mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); + if (unlikely(!mem)) { + pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); + return -EINVAL; } + if (unlikely(mem->pd != pd)) { pr_warn("siw: fastreg: PD mismatch\n"); rv = -EINVAL; @@ -1100,8 +1117,8 @@ /* * RREQ may have already been completed by inbound RRESP! */ - if (tx_type == SIW_OP_READ || - tx_type == SIW_OP_READ_LOCAL_INV) { + if ((tx_type == SIW_OP_READ || + tx_type == SIW_OP_READ_LOCAL_INV) && qp->attrs.orq_size) { /* Cleanup pending entry in ORQ */ qp->orq_put--; qp->orq[qp->orq_put % qp->attrs.orq_size].flags = 0; --- linux-oracle-5.4.0.orig/drivers/infiniband/sw/siw/siw_verbs.c +++ linux-oracle-5.4.0/drivers/infiniband/sw/siw/siw_verbs.c @@ -314,7 +314,6 @@ struct siw_ucontext *uctx = rdma_udata_to_drv_context(udata, struct siw_ucontext, base_ucontext); - struct siw_cq *scq = NULL, *rcq = NULL; unsigned long flags; int num_sqe, num_rqe, rv = 0; @@ -353,10 +352,8 @@ rv = -EINVAL; goto err_out; } - scq = to_siw_cq(attrs->send_cq); - rcq = to_siw_cq(attrs->recv_cq); - if (!scq || (!rcq && !attrs->srq)) { + if (!attrs->send_cq || (!attrs->recv_cq && !attrs->srq)) { siw_dbg(base_dev, "send CQ or receive CQ invalid\n"); rv = -EINVAL; goto err_out; @@ -387,13 +384,23 @@ if (rv) goto err_out; + num_sqe = attrs->cap.max_send_wr; + num_rqe = attrs->cap.max_recv_wr; + /* All queue indices are derived from modulo operations * on a free running 'get' (consumer) and 'put' (producer) * unsigned counter. Having queue sizes at power of two * avoids handling counter wrap around. */ - num_sqe = roundup_pow_of_two(attrs->cap.max_send_wr); - num_rqe = roundup_pow_of_two(attrs->cap.max_recv_wr); + if (num_sqe) + num_sqe = roundup_pow_of_two(num_sqe); + else { + /* Zero sized SQ is not supported */ + rv = -EINVAL; + goto err_out_xa; + } + if (num_rqe) + num_rqe = roundup_pow_of_two(num_rqe); if (qp->kernel_verbs) qp->sendq = vzalloc(num_sqe * sizeof(struct siw_sqe)); @@ -401,7 +408,6 @@ qp->sendq = vmalloc_user(num_sqe * sizeof(struct siw_sqe)); if (qp->sendq == NULL) { - siw_dbg(base_dev, "SQ size %d alloc failed\n", num_sqe); rv = -ENOMEM; goto err_out_xa; } @@ -414,8 +420,8 @@ } } qp->pd = pd; - qp->scq = scq; - qp->rcq = rcq; + qp->scq = to_siw_cq(attrs->send_cq); + qp->rcq = to_siw_cq(attrs->recv_cq); if (attrs->srq) { /* @@ -434,7 +440,6 @@ vmalloc_user(num_rqe * sizeof(struct siw_rqe)); if (qp->recvq == NULL) { - siw_dbg(base_dev, "RQ size %d alloc failed\n", num_rqe); rv = -ENOMEM; goto err_out_xa; } @@ -685,6 +690,79 @@ return bytes; } +/* Complete SQ WR's without processing */ +static int siw_sq_flush_wr(struct siw_qp *qp, const struct ib_send_wr *wr, + const struct ib_send_wr **bad_wr) +{ + int rv = 0; + + while (wr) { + struct siw_sqe sqe = {}; + + switch (wr->opcode) { + case IB_WR_RDMA_WRITE: + sqe.opcode = SIW_OP_WRITE; + break; + case IB_WR_RDMA_READ: + sqe.opcode = SIW_OP_READ; + break; + case IB_WR_RDMA_READ_WITH_INV: + sqe.opcode = SIW_OP_READ_LOCAL_INV; + break; + case IB_WR_SEND: + sqe.opcode = SIW_OP_SEND; + break; + case IB_WR_SEND_WITH_IMM: + sqe.opcode = SIW_OP_SEND_WITH_IMM; + break; + case IB_WR_SEND_WITH_INV: + sqe.opcode = SIW_OP_SEND_REMOTE_INV; + break; + case IB_WR_LOCAL_INV: + sqe.opcode = SIW_OP_INVAL_STAG; + break; + case IB_WR_REG_MR: + sqe.opcode = SIW_OP_REG_MR; + break; + default: + rv = -EINVAL; + break; + } + if (!rv) { + sqe.id = wr->wr_id; + rv = siw_sqe_complete(qp, &sqe, 0, + SIW_WC_WR_FLUSH_ERR); + } + if (rv) { + if (bad_wr) + *bad_wr = wr; + break; + } + wr = wr->next; + } + return rv; +} + +/* Complete RQ WR's without processing */ +static int siw_rq_flush_wr(struct siw_qp *qp, const struct ib_recv_wr *wr, + const struct ib_recv_wr **bad_wr) +{ + struct siw_rqe rqe = {}; + int rv = 0; + + while (wr) { + rqe.id = wr->wr_id; + rv = siw_rqe_complete(qp, &rqe, 0, 0, SIW_WC_WR_FLUSH_ERR); + if (rv) { + if (bad_wr) + *bad_wr = wr; + break; + } + wr = wr->next; + } + return rv; +} + /* * siw_post_send() * @@ -703,26 +781,54 @@ unsigned long flags; int rv = 0; + if (wr && !qp->kernel_verbs) { + siw_dbg_qp(qp, "wr must be empty for user mapped sq\n"); + *bad_wr = wr; + return -EINVAL; + } + /* * Try to acquire QP state lock. Must be non-blocking * to accommodate kernel clients needs. */ if (!down_read_trylock(&qp->state_lock)) { - *bad_wr = wr; - siw_dbg_qp(qp, "QP locked, state %d\n", qp->attrs.state); - return -ENOTCONN; + if (qp->attrs.state == SIW_QP_STATE_ERROR) { + /* + * ERROR state is final, so we can be sure + * this state will not change as long as the QP + * exists. + * + * This handles an ib_drain_sq() call with + * a concurrent request to set the QP state + * to ERROR. + */ + rv = siw_sq_flush_wr(qp, wr, bad_wr); + } else { + siw_dbg_qp(qp, "QP locked, state %d\n", + qp->attrs.state); + *bad_wr = wr; + rv = -ENOTCONN; + } + return rv; } if (unlikely(qp->attrs.state != SIW_QP_STATE_RTS)) { + if (qp->attrs.state == SIW_QP_STATE_ERROR) { + /* + * Immediately flush this WR to CQ, if QP + * is in ERROR state. SQ is guaranteed to + * be empty, so WR complets in-order. + * + * Typically triggered by ib_drain_sq(). + */ + rv = siw_sq_flush_wr(qp, wr, bad_wr); + } else { + siw_dbg_qp(qp, "QP out of state %d\n", + qp->attrs.state); + *bad_wr = wr; + rv = -ENOTCONN; + } up_read(&qp->state_lock); - *bad_wr = wr; - siw_dbg_qp(qp, "QP out of state %d\n", qp->attrs.state); - return -ENOTCONN; - } - if (wr && !qp->kernel_verbs) { - siw_dbg_qp(qp, "wr must be empty for user mapped sq\n"); - up_read(&qp->state_lock); - *bad_wr = wr; - return -EINVAL; + return rv; } spin_lock_irqsave(&qp->sq_lock, flags); @@ -913,28 +1019,58 @@ unsigned long flags; int rv = 0; - if (qp->srq) { + if (qp->srq || qp->attrs.rq_size == 0) { *bad_wr = wr; - return -EOPNOTSUPP; /* what else from errno.h? */ + return -EINVAL; + } + if (!qp->kernel_verbs) { + siw_dbg_qp(qp, "no kernel post_recv for user mapped sq\n"); + *bad_wr = wr; + return -EINVAL; } + /* * Try to acquire QP state lock. Must be non-blocking * to accommodate kernel clients needs. */ if (!down_read_trylock(&qp->state_lock)) { - *bad_wr = wr; - return -ENOTCONN; - } - if (!qp->kernel_verbs) { - siw_dbg_qp(qp, "no kernel post_recv for user mapped sq\n"); - up_read(&qp->state_lock); - *bad_wr = wr; - return -EINVAL; + if (qp->attrs.state == SIW_QP_STATE_ERROR) { + /* + * ERROR state is final, so we can be sure + * this state will not change as long as the QP + * exists. + * + * This handles an ib_drain_rq() call with + * a concurrent request to set the QP state + * to ERROR. + */ + rv = siw_rq_flush_wr(qp, wr, bad_wr); + } else { + siw_dbg_qp(qp, "QP locked, state %d\n", + qp->attrs.state); + *bad_wr = wr; + rv = -ENOTCONN; + } + return rv; } if (qp->attrs.state > SIW_QP_STATE_RTS) { + if (qp->attrs.state == SIW_QP_STATE_ERROR) { + /* + * Immediately flush this WR to CQ, if QP + * is in ERROR state. RQ is guaranteed to + * be empty, so WR complets in-order. + * + * Typically triggered by ib_drain_rq(). + */ + rv = siw_rq_flush_wr(qp, wr, bad_wr); + } else { + siw_dbg_qp(qp, "QP out of state %d\n", + qp->attrs.state); + *bad_wr = wr; + rv = -ENOTCONN; + } up_read(&qp->state_lock); - *bad_wr = wr; - return -EINVAL; + return rv; } /* * Serialize potentially multiple producers. @@ -1373,7 +1509,7 @@ if (pbl->max_buf < num_sle) { siw_dbg_mem(mem, "too many SGE's: %d > %d\n", - mem->pbl->max_buf, num_sle); + num_sle, pbl->max_buf); return -ENOMEM; } for_each_sg(sl, slp, num_sle, i) { --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib.h +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib.h @@ -377,8 +377,12 @@ struct ipoib_rx_buf *rx_ring; struct ipoib_tx_buf *tx_ring; + /* cyclic ring variables for managing tx_ring, for UD only */ unsigned int tx_head; unsigned int tx_tail; + /* cyclic ring variables for counting overall outstanding send WRs */ + unsigned int global_tx_head; + unsigned int global_tx_tail; struct ib_sge tx_sge[MAX_SKB_FRAGS + 1]; struct ib_ud_wr tx_wr; struct ib_wc send_wc[MAX_SEND_CQE]; @@ -511,7 +515,7 @@ int ipoib_ib_dev_open_default(struct net_device *dev); int ipoib_ib_dev_open(struct net_device *dev); -int ipoib_ib_dev_stop(struct net_device *dev); +void ipoib_ib_dev_stop(struct net_device *dev); void ipoib_ib_dev_up(struct net_device *dev); void ipoib_ib_dev_down(struct net_device *dev); int ipoib_ib_dev_stop_default(struct net_device *dev); --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -756,7 +756,8 @@ return; } - if ((priv->tx_head - priv->tx_tail) == ipoib_sendq_size - 1) { + if ((priv->global_tx_head - priv->global_tx_tail) == + ipoib_sendq_size - 1) { ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", tx->qp->qp_num); netif_stop_queue(dev); @@ -786,7 +787,7 @@ } else { netif_trans_update(dev); ++tx->tx_head; - ++priv->tx_head; + ++priv->global_tx_head; } } @@ -820,10 +821,11 @@ netif_tx_lock(dev); ++tx->tx_tail; - ++priv->tx_tail; + ++priv->global_tx_tail; if (unlikely(netif_queue_stopped(dev) && - (priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1 && + ((priv->global_tx_head - priv->global_tx_tail) <= + ipoib_sendq_size >> 1) && test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))) netif_wake_queue(dev); @@ -1232,8 +1234,9 @@ dev_kfree_skb_any(tx_req->skb); netif_tx_lock_bh(p->dev); ++p->tx_tail; - ++priv->tx_tail; - if (unlikely(priv->tx_head - priv->tx_tail == ipoib_sendq_size >> 1) && + ++priv->global_tx_tail; + if (unlikely((priv->global_tx_head - priv->global_tx_tail) <= + ipoib_sendq_size >> 1) && netif_queue_stopped(p->dev) && test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) netif_wake_queue(p->dev); --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -407,9 +407,11 @@ dev_kfree_skb_any(tx_req->skb); ++priv->tx_tail; + ++priv->global_tx_tail; if (unlikely(netif_queue_stopped(dev) && - ((priv->tx_head - priv->tx_tail) <= ipoib_sendq_size >> 1) && + ((priv->global_tx_head - priv->global_tx_tail) <= + ipoib_sendq_size >> 1) && test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))) netif_wake_queue(dev); @@ -634,7 +636,8 @@ else priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; /* increase the tx_head after send success, but use it for queue state */ - if (priv->tx_head - priv->tx_tail == ipoib_sendq_size - 1) { + if ((priv->global_tx_head - priv->global_tx_tail) == + ipoib_sendq_size - 1) { ipoib_dbg(priv, "TX ring full, stopping kernel net queue\n"); netif_stop_queue(dev); } @@ -662,17 +665,17 @@ rc = priv->tx_head; ++priv->tx_head; + ++priv->global_tx_head; } return rc; } -static void __ipoib_reap_ah(struct net_device *dev) +static void ipoib_reap_dead_ahs(struct ipoib_dev_priv *priv) { - struct ipoib_dev_priv *priv = ipoib_priv(dev); struct ipoib_ah *ah, *tah; unsigned long flags; - netif_tx_lock_bh(dev); + netif_tx_lock_bh(priv->dev); spin_lock_irqsave(&priv->lock, flags); list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) @@ -683,37 +686,37 @@ } spin_unlock_irqrestore(&priv->lock, flags); - netif_tx_unlock_bh(dev); + netif_tx_unlock_bh(priv->dev); } void ipoib_reap_ah(struct work_struct *work) { struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, ah_reap_task.work); - struct net_device *dev = priv->dev; - __ipoib_reap_ah(dev); + ipoib_reap_dead_ahs(priv); if (!test_bit(IPOIB_STOP_REAPER, &priv->flags)) queue_delayed_work(priv->wq, &priv->ah_reap_task, round_jiffies_relative(HZ)); } -static void ipoib_flush_ah(struct net_device *dev) +static void ipoib_start_ah_reaper(struct ipoib_dev_priv *priv) { - struct ipoib_dev_priv *priv = ipoib_priv(dev); - - cancel_delayed_work(&priv->ah_reap_task); - flush_workqueue(priv->wq); - ipoib_reap_ah(&priv->ah_reap_task.work); + clear_bit(IPOIB_STOP_REAPER, &priv->flags); + queue_delayed_work(priv->wq, &priv->ah_reap_task, + round_jiffies_relative(HZ)); } -static void ipoib_stop_ah(struct net_device *dev) +static void ipoib_stop_ah_reaper(struct ipoib_dev_priv *priv) { - struct ipoib_dev_priv *priv = ipoib_priv(dev); - set_bit(IPOIB_STOP_REAPER, &priv->flags); - ipoib_flush_ah(dev); + cancel_delayed_work(&priv->ah_reap_task); + /* + * After ipoib_stop_ah_reaper() we always go through + * ipoib_reap_dead_ahs() which ensures the work is really stopped and + * does a final flush out of the dead_ah's list + */ } static int recvs_pending(struct net_device *dev) @@ -807,6 +810,7 @@ ipoib_dma_unmap_tx(priv, tx_req); dev_kfree_skb_any(tx_req->skb); ++priv->tx_tail; + ++priv->global_tx_tail; } for (i = 0; i < ipoib_recvq_size; ++i) { @@ -841,18 +845,6 @@ return 0; } -int ipoib_ib_dev_stop(struct net_device *dev) -{ - struct ipoib_dev_priv *priv = ipoib_priv(dev); - - priv->rn_ops->ndo_stop(dev); - - clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); - ipoib_flush_ah(dev); - - return 0; -} - int ipoib_ib_dev_open_default(struct net_device *dev) { struct ipoib_dev_priv *priv = ipoib_priv(dev); @@ -896,10 +888,7 @@ return -1; } - clear_bit(IPOIB_STOP_REAPER, &priv->flags); - queue_delayed_work(priv->wq, &priv->ah_reap_task, - round_jiffies_relative(HZ)); - + ipoib_start_ah_reaper(priv); if (priv->rn_ops->ndo_open(dev)) { pr_warn("%s: Failed to open dev\n", dev->name); goto dev_stop; @@ -910,13 +899,20 @@ return 0; dev_stop: - set_bit(IPOIB_STOP_REAPER, &priv->flags); - cancel_delayed_work(&priv->ah_reap_task); - set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); - ipoib_ib_dev_stop(dev); + ipoib_stop_ah_reaper(priv); return -1; } +void ipoib_ib_dev_stop(struct net_device *dev) +{ + struct ipoib_dev_priv *priv = ipoib_priv(dev); + + priv->rn_ops->ndo_stop(dev); + + clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); + ipoib_stop_ah_reaper(priv); +} + void ipoib_pkey_dev_check_presence(struct net_device *dev) { struct ipoib_dev_priv *priv = ipoib_priv(dev); @@ -1227,7 +1223,7 @@ ipoib_mcast_dev_flush(dev); if (oper_up) set_bit(IPOIB_FLAG_OPER_UP, &priv->flags); - ipoib_flush_ah(dev); + ipoib_reap_dead_ahs(priv); } if (level >= IPOIB_FLUSH_NORMAL) @@ -1302,7 +1298,7 @@ * the neighbor garbage collection is stopped and reaped. * That should all be done now, so make a final ah flush. */ - ipoib_stop_ah(dev); + ipoib_reap_dead_ahs(priv); clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -1188,9 +1188,11 @@ ipoib_warn(priv, "transmit timeout: latency %d msecs\n", jiffies_to_msecs(jiffies - dev_trans_start(dev))); - ipoib_warn(priv, "queue stopped %d, tx_head %u, tx_tail %u\n", - netif_queue_stopped(dev), - priv->tx_head, priv->tx_tail); + ipoib_warn(priv, + "queue stopped %d, tx_head %u, tx_tail %u, global_tx_head %u, global_tx_tail %u\n", + netif_queue_stopped(dev), priv->tx_head, priv->tx_tail, + priv->global_tx_head, priv->global_tx_tail); + /* XXX reset QP, etc. */ } @@ -1705,7 +1707,7 @@ goto out_rx_ring_cleanup; } - /* priv->tx_head, tx_tail & tx_outstanding are already 0 */ + /* priv->tx_head, tx_tail and global_tx_tail/head are already 0 */ if (ipoib_transport_dev_init(dev, priv->ca)) { pr_warn("%s: ipoib_transport_dev_init failed\n", @@ -1977,6 +1979,8 @@ /* no more works over the priv->wq */ if (priv->wq) { + /* See ipoib_mcast_carrier_on_task() */ + WARN_ON(test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)); flush_workqueue(priv->wq); destroy_workqueue(priv->wq); priv->wq = NULL; @@ -2167,6 +2171,14 @@ rn->attach_mcast = ipoib_mcast_attach; rn->detach_mcast = ipoib_mcast_detach; rn->hca = hca; + + rc = netif_set_real_num_tx_queues(dev, 1); + if (rc) + goto out; + + rc = netif_set_real_num_rx_queues(dev, 1); + if (rc) + goto out; } priv->rn_ops = dev->netdev_ops; @@ -2459,6 +2471,8 @@ /* call event handler to ensure pkey in sync */ queue_work(ipoib_workqueue, &priv->flush_heavy); + ndev->rtnl_link_ops = ipoib_get_link_ops(); + result = register_netdev(ndev); if (result) { pr_warn("%s: couldn't register ipoib port %d; error %d\n", --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -543,21 +543,18 @@ /* SM supports sendonly-fullmember, otherwise fallback to full-member */ rec.join_state = SENDONLY_FULLMEMBER_JOIN; } - spin_unlock_irq(&priv->lock); multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, - &rec, comp_mask, GFP_KERNEL, + &rec, comp_mask, GFP_ATOMIC, ipoib_mcast_join_complete, mcast); - spin_lock_irq(&priv->lock); if (IS_ERR(multicast)) { ret = PTR_ERR(multicast); ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret); /* Requeue this join task with a backoff delay */ __ipoib_mcast_schedule_join_thread(priv, mcast, 1); clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); - spin_unlock_irq(&priv->lock); complete(&mcast->done); - spin_lock_irq(&priv->lock); + return ret; } return 0; } --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_netlink.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_netlink.c @@ -42,6 +42,11 @@ [IFLA_IPOIB_UMCAST] = { .type = NLA_U16 }, }; +static unsigned int ipoib_get_max_num_queues(void) +{ + return min_t(unsigned int, num_possible_cpus(), 128); +} + static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev) { struct ipoib_dev_priv *priv = ipoib_priv(dev); @@ -144,6 +149,16 @@ return 0; } +static void ipoib_del_child_link(struct net_device *dev, struct list_head *head) +{ + struct ipoib_dev_priv *priv = ipoib_priv(dev); + + if (!priv->parent) + return; + + unregister_netdevice_queue(dev, head); +} + static size_t ipoib_get_size(const struct net_device *dev) { return nla_total_size(2) + /* IFLA_IPOIB_PKEY */ @@ -153,14 +168,18 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = { .kind = "ipoib", + .netns_refund = true, .maxtype = IFLA_IPOIB_MAX, .policy = ipoib_policy, .priv_size = sizeof(struct ipoib_dev_priv), .setup = ipoib_setup_common, .newlink = ipoib_new_child_link, + .dellink = ipoib_del_child_link, .changelink = ipoib_changelink, .get_size = ipoib_get_size, .fill_info = ipoib_fill_info, + .get_num_rx_queues = ipoib_get_max_num_queues, + .get_num_tx_queues = ipoib_get_max_num_queues, }; struct rtnl_link_ops *ipoib_get_link_ops(void) --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -182,8 +182,12 @@ ppriv = ipoib_priv(pdev); - snprintf(intf_name, sizeof(intf_name), "%s.%04x", - ppriv->dev->name, pkey); + /* If you increase IFNAMSIZ, update snprintf below + * to allow longer names. + */ + BUILD_BUG_ON(IFNAMSIZ != 16); + snprintf(intf_name, sizeof(intf_name), "%.10s.%04x", ppriv->dev->name, + pkey); ndev = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name); if (IS_ERR(ndev)) { @@ -192,6 +196,8 @@ } priv = ipoib_priv(ndev); + ndev->rtnl_link_ops = ipoib_get_link_ops(); + result = __ipoib_vlan_add(ppriv, priv, pkey, IPOIB_LEGACY_CHILD); if (result && ndev->reg_state == NETREG_UNINITIALIZED) --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/iser/iscsi_iser.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -646,6 +646,7 @@ if (ib_conn->pi_support) { u32 sig_caps = ib_dev->attrs.sig_prot_cap; + shost->sg_prot_tablesize = shost->sg_tablesize; scsi_host_set_prot(shost, iser_dif_prot_caps(sig_caps)); scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP | SHOST_DIX_GUARD_CRC); --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/iser/iser_memory.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/iser/iser_memory.c @@ -292,12 +292,27 @@ { struct iser_device *device = iser_task->iser_conn->ib_conn.device; struct iser_mem_reg *reg = &iser_task->rdma_reg[cmd_dir]; + struct iser_fr_desc *desc; + struct ib_mr_status mr_status; - if (!reg->mem_h) + desc = reg->mem_h; + if (!desc) return; - device->reg_ops->reg_desc_put(&iser_task->iser_conn->ib_conn, - reg->mem_h); + /* + * The signature MR cannot be invalidated and reused without checking. + * libiscsi calls the check_protection transport handler only if + * SCSI-Response is received. And the signature MR is not checked if + * the task is completed for some other reason like a timeout or error + * handling. That's why we must check the signature MR here before + * putting it to the free pool. + */ + if (unlikely(desc->sig_protected)) { + desc->sig_protected = false; + ib_check_mr_status(desc->rsc.sig_mr, IB_MR_CHECK_SIG_STATUS, + &mr_status); + } + device->reg_ops->reg_desc_put(&iser_task->iser_conn->ib_conn, desc); reg->mem_h = NULL; } --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/isert/ib_isert.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/isert/ib_isert.c @@ -182,15 +182,15 @@ rx_desc = isert_conn->rx_descs; for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) { - dma_addr = ib_dma_map_single(ib_dev, (void *)rx_desc, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + dma_addr = ib_dma_map_single(ib_dev, rx_desc->buf, + ISER_RX_SIZE, DMA_FROM_DEVICE); if (ib_dma_mapping_error(ib_dev, dma_addr)) goto dma_map_fail; rx_desc->dma_addr = dma_addr; rx_sg = &rx_desc->rx_sg; - rx_sg->addr = rx_desc->dma_addr; + rx_sg->addr = rx_desc->dma_addr + isert_get_hdr_offset(rx_desc); rx_sg->length = ISER_RX_PAYLOAD_SIZE; rx_sg->lkey = device->pd->local_dma_lkey; rx_desc->rx_cqe.done = isert_recv_done; @@ -202,7 +202,7 @@ rx_desc = isert_conn->rx_descs; for (j = 0; j < i; j++, rx_desc++) { ib_dma_unmap_single(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ISER_RX_SIZE, DMA_FROM_DEVICE); } kfree(isert_conn->rx_descs); isert_conn->rx_descs = NULL; @@ -223,7 +223,7 @@ rx_desc = isert_conn->rx_descs; for (i = 0; i < ISERT_QP_MAX_RECV_DTOS; i++, rx_desc++) { ib_dma_unmap_single(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ISER_RX_SIZE, DMA_FROM_DEVICE); } kfree(isert_conn->rx_descs); @@ -408,10 +408,9 @@ ISER_RX_PAYLOAD_SIZE, DMA_TO_DEVICE); kfree(isert_conn->login_rsp_buf); - ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma, - ISER_RX_PAYLOAD_SIZE, - DMA_FROM_DEVICE); - kfree(isert_conn->login_req_buf); + ib_dma_unmap_single(ib_dev, isert_conn->login_desc->dma_addr, + ISER_RX_SIZE, DMA_FROM_DEVICE); + kfree(isert_conn->login_desc); } static int @@ -420,25 +419,25 @@ { int ret; - isert_conn->login_req_buf = kzalloc(sizeof(*isert_conn->login_req_buf), + isert_conn->login_desc = kzalloc(sizeof(*isert_conn->login_desc), GFP_KERNEL); - if (!isert_conn->login_req_buf) + if (!isert_conn->login_desc) return -ENOMEM; - isert_conn->login_req_dma = ib_dma_map_single(ib_dev, - isert_conn->login_req_buf, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); - ret = ib_dma_mapping_error(ib_dev, isert_conn->login_req_dma); + isert_conn->login_desc->dma_addr = ib_dma_map_single(ib_dev, + isert_conn->login_desc->buf, + ISER_RX_SIZE, DMA_FROM_DEVICE); + ret = ib_dma_mapping_error(ib_dev, isert_conn->login_desc->dma_addr); if (ret) { - isert_err("login_req_dma mapping error: %d\n", ret); - isert_conn->login_req_dma = 0; - goto out_free_login_req_buf; + isert_err("login_desc dma mapping error: %d\n", ret); + isert_conn->login_desc->dma_addr = 0; + goto out_free_login_desc; } isert_conn->login_rsp_buf = kzalloc(ISER_RX_PAYLOAD_SIZE, GFP_KERNEL); if (!isert_conn->login_rsp_buf) { ret = -ENOMEM; - goto out_unmap_login_req_buf; + goto out_unmap_login_desc; } isert_conn->login_rsp_dma = ib_dma_map_single(ib_dev, @@ -455,11 +454,11 @@ out_free_login_rsp_buf: kfree(isert_conn->login_rsp_buf); -out_unmap_login_req_buf: - ib_dma_unmap_single(ib_dev, isert_conn->login_req_dma, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); -out_free_login_req_buf: - kfree(isert_conn->login_req_buf); +out_unmap_login_desc: + ib_dma_unmap_single(ib_dev, isert_conn->login_desc->dma_addr, + ISER_RX_SIZE, DMA_FROM_DEVICE); +out_free_login_desc: + kfree(isert_conn->login_desc); return ret; } @@ -578,7 +577,7 @@ ib_destroy_qp(isert_conn->qp); } - if (isert_conn->login_req_buf) + if (isert_conn->login_desc) isert_free_login_buf(isert_conn); isert_device_put(device); @@ -734,9 +733,13 @@ isert_connect_error(struct rdma_cm_id *cma_id) { struct isert_conn *isert_conn = cma_id->qp->qp_context; + struct isert_np *isert_np = cma_id->context; ib_drain_qp(isert_conn->qp); + + mutex_lock(&isert_np->mutex); list_del_init(&isert_conn->node); + mutex_unlock(&isert_np->mutex); isert_conn->cm_id = NULL; isert_put_conn(isert_conn); @@ -964,17 +967,18 @@ int ret; memset(&sge, 0, sizeof(struct ib_sge)); - sge.addr = isert_conn->login_req_dma; + sge.addr = isert_conn->login_desc->dma_addr + + isert_get_hdr_offset(isert_conn->login_desc); sge.length = ISER_RX_PAYLOAD_SIZE; sge.lkey = isert_conn->device->pd->local_dma_lkey; isert_dbg("Setup sge: addr: %llx length: %d 0x%08x\n", sge.addr, sge.length, sge.lkey); - isert_conn->login_req_buf->rx_cqe.done = isert_login_recv_done; + isert_conn->login_desc->rx_cqe.done = isert_login_recv_done; memset(&rx_wr, 0, sizeof(struct ib_recv_wr)); - rx_wr.wr_cqe = &isert_conn->login_req_buf->rx_cqe; + rx_wr.wr_cqe = &isert_conn->login_desc->rx_cqe; rx_wr.sg_list = &sge; rx_wr.num_sge = 1; @@ -1051,7 +1055,7 @@ static void isert_rx_login_req(struct isert_conn *isert_conn) { - struct iser_rx_desc *rx_desc = isert_conn->login_req_buf; + struct iser_rx_desc *rx_desc = isert_conn->login_desc; int rx_buflen = isert_conn->login_req_len; struct iscsi_conn *conn = isert_conn->conn; struct iscsi_login *login = conn->conn_login; @@ -1063,7 +1067,7 @@ if (login->first_request) { struct iscsi_login_req *login_req = - (struct iscsi_login_req *)&rx_desc->iscsi_header; + (struct iscsi_login_req *)isert_get_iscsi_hdr(rx_desc); /* * Setup the initial iscsi_login values from the leading * login request PDU. @@ -1082,13 +1086,13 @@ login->tsih = be16_to_cpu(login_req->tsih); } - memcpy(&login->req[0], (void *)&rx_desc->iscsi_header, ISCSI_HDR_LEN); + memcpy(&login->req[0], isert_get_iscsi_hdr(rx_desc), ISCSI_HDR_LEN); size = min(rx_buflen, MAX_KEY_VALUE_PAIRS); isert_dbg("Using login payload size: %d, rx_buflen: %d " "MAX_KEY_VALUE_PAIRS: %d\n", size, rx_buflen, MAX_KEY_VALUE_PAIRS); - memcpy(login->req_buf, &rx_desc->data[0], size); + memcpy(login->req_buf, isert_get_data(rx_desc), size); if (login->first_request) { complete(&isert_conn->login_comp); @@ -1153,14 +1157,15 @@ if (imm_data_len != data_len) { sg_nents = max(1UL, DIV_ROUND_UP(imm_data_len, PAGE_SIZE)); sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents, - &rx_desc->data[0], imm_data_len); + isert_get_data(rx_desc), imm_data_len); isert_dbg("Copy Immediate sg_nents: %u imm_data_len: %d\n", sg_nents, imm_data_len); } else { sg_init_table(&isert_cmd->sg, 1); cmd->se_cmd.t_data_sg = &isert_cmd->sg; cmd->se_cmd.t_data_nents = 1; - sg_set_buf(&isert_cmd->sg, &rx_desc->data[0], imm_data_len); + sg_set_buf(&isert_cmd->sg, isert_get_data(rx_desc), + imm_data_len); isert_dbg("Transfer Immediate imm_data_len: %d\n", imm_data_len); } @@ -1229,9 +1234,9 @@ } isert_dbg("Copying DataOut: sg_start: %p, sg_off: %u " "sg_nents: %u from %p %u\n", sg_start, sg_off, - sg_nents, &rx_desc->data[0], unsol_data_len); + sg_nents, isert_get_data(rx_desc), unsol_data_len); - sg_copy_from_buffer(sg_start, sg_nents, &rx_desc->data[0], + sg_copy_from_buffer(sg_start, sg_nents, isert_get_data(rx_desc), unsol_data_len); rc = iscsit_check_dataout_payload(cmd, hdr, false); @@ -1290,7 +1295,7 @@ } cmd->text_in_ptr = text_in; - memcpy(cmd->text_in_ptr, &rx_desc->data[0], payload_length); + memcpy(cmd->text_in_ptr, isert_get_data(rx_desc), payload_length); return iscsit_process_text_cmd(conn, cmd, hdr); } @@ -1300,7 +1305,7 @@ uint32_t read_stag, uint64_t read_va, uint32_t write_stag, uint64_t write_va) { - struct iscsi_hdr *hdr = &rx_desc->iscsi_header; + struct iscsi_hdr *hdr = isert_get_iscsi_hdr(rx_desc); struct iscsi_conn *conn = isert_conn->conn; struct iscsi_cmd *cmd; struct isert_cmd *isert_cmd; @@ -1398,8 +1403,8 @@ struct isert_conn *isert_conn = wc->qp->qp_context; struct ib_device *ib_dev = isert_conn->cm_id->device; struct iser_rx_desc *rx_desc = cqe_to_rx_desc(wc->wr_cqe); - struct iscsi_hdr *hdr = &rx_desc->iscsi_header; - struct iser_ctrl *iser_ctrl = &rx_desc->iser_header; + struct iscsi_hdr *hdr = isert_get_iscsi_hdr(rx_desc); + struct iser_ctrl *iser_ctrl = isert_get_iser_hdr(rx_desc); uint64_t read_va = 0, write_va = 0; uint32_t read_stag = 0, write_stag = 0; @@ -1413,7 +1418,7 @@ rx_desc->in_use = true; ib_dma_sync_single_for_cpu(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ISER_RX_SIZE, DMA_FROM_DEVICE); isert_dbg("DMA: 0x%llx, iSCSI opcode: 0x%02x, ITT: 0x%08x, flags: 0x%02x dlen: %d\n", rx_desc->dma_addr, hdr->opcode, hdr->itt, hdr->flags, @@ -1448,7 +1453,7 @@ read_stag, read_va, write_stag, write_va); ib_dma_sync_single_for_device(ib_dev, rx_desc->dma_addr, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ISER_RX_SIZE, DMA_FROM_DEVICE); } static void @@ -1462,8 +1467,8 @@ return; } - ib_dma_sync_single_for_cpu(ib_dev, isert_conn->login_req_dma, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ib_dma_sync_single_for_cpu(ib_dev, isert_conn->login_desc->dma_addr, + ISER_RX_SIZE, DMA_FROM_DEVICE); isert_conn->login_req_len = wc->byte_len - ISER_HEADERS_LEN; @@ -1478,8 +1483,8 @@ complete(&isert_conn->login_req_comp); mutex_unlock(&isert_conn->mutex); - ib_dma_sync_single_for_device(ib_dev, isert_conn->login_req_dma, - ISER_RX_PAYLOAD_SIZE, DMA_FROM_DEVICE); + ib_dma_sync_single_for_device(ib_dev, isert_conn->login_desc->dma_addr, + ISER_RX_SIZE, DMA_FROM_DEVICE); } static void @@ -2506,6 +2511,7 @@ { struct isert_np *isert_np = np->np_context; struct isert_conn *isert_conn, *n; + LIST_HEAD(drop_conn_list); if (isert_np->cm_id) rdma_destroy_id(isert_np->cm_id); @@ -2525,7 +2531,7 @@ node) { isert_info("cleaning isert_conn %p state (%d)\n", isert_conn, isert_conn->state); - isert_connect_release(isert_conn); + list_move_tail(&isert_conn->node, &drop_conn_list); } } @@ -2536,11 +2542,16 @@ node) { isert_info("cleaning isert_conn %p state (%d)\n", isert_conn, isert_conn->state); - isert_connect_release(isert_conn); + list_move_tail(&isert_conn->node, &drop_conn_list); } } mutex_unlock(&isert_np->mutex); + list_for_each_entry_safe(isert_conn, n, &drop_conn_list, node) { + list_del_init(&isert_conn->node); + isert_connect_release(isert_conn); + } + np->np_context = NULL; kfree(isert_np); } --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/isert/ib_isert.h +++ linux-oracle-5.4.0/drivers/infiniband/ulp/isert/ib_isert.h @@ -59,9 +59,11 @@ ISERT_MAX_TX_MISC_PDUS + \ ISERT_MAX_RX_MISC_PDUS) -#define ISER_RX_PAD_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 4096 - \ - (ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \ - sizeof(struct ib_cqe) + sizeof(bool))) +/* + * RX size is default of 8k plus headers, but data needs to align to + * 512 boundary, so use 1024 to have the extra space for alignment. + */ +#define ISER_RX_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 1024) #define ISCSI_ISER_SG_TABLESIZE 256 @@ -80,21 +82,41 @@ }; struct iser_rx_desc { - struct iser_ctrl iser_header; - struct iscsi_hdr iscsi_header; - char data[ISCSI_DEF_MAX_RECV_SEG_LEN]; + char buf[ISER_RX_SIZE]; u64 dma_addr; struct ib_sge rx_sg; struct ib_cqe rx_cqe; bool in_use; - char pad[ISER_RX_PAD_SIZE]; -} __packed; +}; static inline struct iser_rx_desc *cqe_to_rx_desc(struct ib_cqe *cqe) { return container_of(cqe, struct iser_rx_desc, rx_cqe); } +static void *isert_get_iser_hdr(struct iser_rx_desc *desc) +{ + return PTR_ALIGN(desc->buf + ISER_HEADERS_LEN, 512) - ISER_HEADERS_LEN; +} + +static size_t isert_get_hdr_offset(struct iser_rx_desc *desc) +{ + return isert_get_iser_hdr(desc) - (void *)desc->buf; +} + +static void *isert_get_iscsi_hdr(struct iser_rx_desc *desc) +{ + return isert_get_iser_hdr(desc) + sizeof(struct iser_ctrl); +} + +static void *isert_get_data(struct iser_rx_desc *desc) +{ + void *data = isert_get_iser_hdr(desc) + ISER_HEADERS_LEN; + + WARN_ON((uintptr_t)data & 511); + return data; +} + struct iser_tx_desc { struct iser_ctrl iser_header; struct iscsi_hdr iscsi_header; @@ -141,9 +163,8 @@ u32 responder_resources; u32 initiator_depth; bool pi_support; - struct iser_rx_desc *login_req_buf; + struct iser_rx_desc *login_desc; char *login_rsp_buf; - u64 login_req_dma; int login_req_len; u64 login_rsp_dma; struct iser_rx_desc *rx_descs; --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/srp/ib_srp.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/srp/ib_srp.c @@ -2536,7 +2536,8 @@ if (lrsp->opcode == SRP_LOGIN_RSP) { ch->max_ti_iu_len = be32_to_cpu(lrsp->max_ti_iu_len); ch->req_lim = be32_to_cpu(lrsp->req_lim_delta); - ch->use_imm_data = lrsp->rsp_flags & SRP_LOGIN_RSP_IMMED_SUPP; + ch->use_imm_data = srp_use_imm_data && + (lrsp->rsp_flags & SRP_LOGIN_RSP_IMMED_SUPP); ch->max_it_iu_len = srp_max_it_iu_len(target->cmd_sg_cnt, ch->use_imm_data); WARN_ON_ONCE(ch->max_it_iu_len > @@ -4221,9 +4222,11 @@ spin_unlock(&host->target_lock); /* - * Wait for tl_err and target port removal tasks. + * srp_queue_remove_work() queues a call to + * srp_remove_target(). The latter function cancels + * target->tl_err_work so waiting for the remove works to + * finish is sufficient. */ - flush_workqueue(system_long_wq); flush_workqueue(srp_remove_wq); kfree(host); --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/srp/ib_srp.h +++ linux-oracle-5.4.0/drivers/infiniband/ulp/srp/ib_srp.h @@ -63,9 +63,6 @@ SRP_DEFAULT_CMD_SQ_SIZE = SRP_DEFAULT_QUEUE_SIZE - SRP_RSP_SQ_SIZE - SRP_TSK_MGMT_SQ_SIZE, - SRP_TAG_NO_REQ = ~0U, - SRP_TAG_TSK_MGMT = 1U << 31, - SRP_MAX_PAGES_PER_MR = 512, SRP_MAX_ADD_CDB_LEN = 16, @@ -80,6 +77,11 @@ sizeof(struct srp_imm_buf), }; +enum { + SRP_TAG_NO_REQ = ~0U, + SRP_TAG_TSK_MGMT = BIT(31), +}; + enum srp_target_state { SRP_TARGET_SCANNING, SRP_TARGET_LIVE, --- linux-oracle-5.4.0.orig/drivers/infiniband/ulp/srpt/ib_srpt.c +++ linux-oracle-5.4.0/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -213,12 +213,15 @@ /** * srpt_qp_event - QP event callback function * @event: Description of the event that occurred. - * @ch: SRPT RDMA channel. + * @ptr: SRPT RDMA channel. */ -static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch) +static void srpt_qp_event(struct ib_event *event, void *ptr) { - pr_debug("QP event %d on ch=%p sess_name=%s state=%d\n", - event->event, ch, ch->sess_name, ch->state); + struct srpt_rdma_ch *ch = ptr; + + pr_debug("QP event %d on ch=%p sess_name=%s-%d state=%s\n", + event->event, ch, ch->sess_name, ch->qp->qp_num, + get_ch_state_name(ch->state)); switch (event->event) { case IB_EVENT_COMM_EST: @@ -1364,9 +1367,11 @@ struct srpt_send_ioctx *ioctx, u64 tag, int status) { + struct se_cmd *cmd = &ioctx->cmd; struct srp_rsp *srp_rsp; const u8 *sense_data; int sense_data_len, max_sense_len; + u32 resid = cmd->residual_count; /* * The lowest bit of all SAM-3 status codes is zero (see also @@ -1388,6 +1393,28 @@ srp_rsp->tag = tag; srp_rsp->status = status; + if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { + if (cmd->data_direction == DMA_TO_DEVICE) { + /* residual data from an underflow write */ + srp_rsp->flags = SRP_RSP_FLAG_DOUNDER; + srp_rsp->data_out_res_cnt = cpu_to_be32(resid); + } else if (cmd->data_direction == DMA_FROM_DEVICE) { + /* residual data from an underflow read */ + srp_rsp->flags = SRP_RSP_FLAG_DIUNDER; + srp_rsp->data_in_res_cnt = cpu_to_be32(resid); + } + } else if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { + if (cmd->data_direction == DMA_TO_DEVICE) { + /* residual data from an overflow write */ + srp_rsp->flags = SRP_RSP_FLAG_DOOVER; + srp_rsp->data_out_res_cnt = cpu_to_be32(resid); + } else if (cmd->data_direction == DMA_FROM_DEVICE) { + /* residual data from an overflow read */ + srp_rsp->flags = SRP_RSP_FLAG_DIOVER; + srp_rsp->data_in_res_cnt = cpu_to_be32(resid); + } + } + if (sense_data_len) { BUILD_BUG_ON(MIN_MAX_RSP_SIZE <= sizeof(*srp_rsp)); max_sense_len = ch->max_ti_iu_len - sizeof(*srp_rsp); @@ -1777,8 +1804,7 @@ } qp_init->qp_context = (void *)ch; - qp_init->event_handler - = (void(*)(struct ib_event *, void*))srpt_qp_event; + qp_init->event_handler = srpt_qp_event; qp_init->send_cq = ch->cq; qp_init->recv_cq = ch->cq; qp_init->sq_sig_type = IB_SIGNAL_REQ_WR; @@ -1981,8 +2007,8 @@ list_for_each_entry(nexus, &sport->nexus_list, entry) { list_for_each_entry(ch, &nexus->ch_list, list) { if (srpt_disconnect_ch(ch) >= 0) - pr_info("Closing channel %s because target %s_%d has been disabled\n", - ch->sess_name, + pr_info("Closing channel %s-%d because target %s_%d has been disabled\n", + ch->sess_name, ch->qp->qp_num, dev_name(&sport->sdev->device->dev), sport->port); srpt_close_ch(ch); @@ -2349,6 +2375,7 @@ pr_info("rejected SRP_LOGIN_REQ because target %s_%d is not enabled\n", dev_name(&sdev->device->dev), port_num); mutex_unlock(&sport->mutex); + ret = -EINVAL; goto reject; } --- linux-oracle-5.4.0.orig/drivers/input/evdev.c +++ linux-oracle-5.4.0/drivers/input/evdev.c @@ -224,13 +224,13 @@ */ client->tail = (client->head - 2) & (client->bufsize - 1); - client->buffer[client->tail].input_event_sec = - event->input_event_sec; - client->buffer[client->tail].input_event_usec = - event->input_event_usec; - client->buffer[client->tail].type = EV_SYN; - client->buffer[client->tail].code = SYN_DROPPED; - client->buffer[client->tail].value = 0; + client->buffer[client->tail] = (struct input_event) { + .input_event_sec = event->input_event_sec, + .input_event_usec = event->input_event_usec, + .type = EV_SYN, + .code = SYN_DROPPED, + .value = 0, + }; client->packet_head = client->tail; } @@ -326,20 +326,6 @@ return fasync_helper(fd, file, on, &client->fasync); } -static int evdev_flush(struct file *file, fl_owner_t id) -{ - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; - - mutex_lock(&evdev->mutex); - - if (evdev->exist && !client->revoked) - input_flush_device(&evdev->handle, file); - - mutex_unlock(&evdev->mutex); - return 0; -} - static void evdev_free(struct device *dev) { struct evdev *evdev = container_of(dev, struct evdev, dev); @@ -453,6 +439,10 @@ unsigned int i; mutex_lock(&evdev->mutex); + + if (evdev->exist && !client->revoked) + input_flush_device(&evdev->handle, file); + evdev_ungrab(evdev, client); mutex_unlock(&evdev->mutex); @@ -484,10 +474,7 @@ struct evdev_client *client; int error; - client = kzalloc(struct_size(client, buffer, bufsize), - GFP_KERNEL | __GFP_NOWARN); - if (!client) - client = vzalloc(struct_size(client, buffer, bufsize)); + client = kvzalloc(struct_size(client, buffer, bufsize), GFP_KERNEL); if (!client) return -ENOMEM; @@ -1313,7 +1300,6 @@ .compat_ioctl = evdev_ioctl_compat, #endif .fasync = evdev_fasync, - .flush = evdev_flush, .llseek = no_llseek, }; --- linux-oracle-5.4.0.orig/drivers/input/ff-core.c +++ linux-oracle-5.4.0/drivers/input/ff-core.c @@ -12,8 +12,10 @@ /* #define DEBUG */ #include +#include #include #include +#include #include #include @@ -318,9 +320,8 @@ return -EINVAL; } - ff_dev_size = sizeof(struct ff_device) + - max_effects * sizeof(struct file *); - if (ff_dev_size < max_effects) /* overflow */ + ff_dev_size = struct_size(ff, effect_owners, max_effects); + if (ff_dev_size == SIZE_MAX) /* overflow */ return -EINVAL; ff = kzalloc(ff_dev_size, GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/input/input-mt.c +++ linux-oracle-5.4.0/drivers/input/input-mt.c @@ -45,6 +45,9 @@ return 0; if (mt) return mt->num_slots != num_slots ? -EINVAL : 0; + /* Arbitrary limit for avoiding too large memory allocation. */ + if (num_slots > 1024) + return -EINVAL; mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); if (!mt) --- linux-oracle-5.4.0.orig/drivers/input/input.c +++ linux-oracle-5.4.0/drivers/input/input.c @@ -47,6 +47,17 @@ static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; +static const unsigned int input_max_code[EV_CNT] = { + [EV_KEY] = KEY_MAX, + [EV_REL] = REL_MAX, + [EV_ABS] = ABS_MAX, + [EV_MSC] = MSC_MAX, + [EV_SW] = SW_MAX, + [EV_LED] = LED_MAX, + [EV_SND] = SND_MAX, + [EV_FF] = FF_MAX, +}; + static inline int is_event_supported(unsigned int code, unsigned long *bm, unsigned int max) { @@ -190,6 +201,7 @@ input_value_sync }; + input_set_timestamp(dev, ktime_get()); input_pass_values(dev, vals, ARRAY_SIZE(vals)); if (dev->rep[REP_PERIOD]) @@ -878,16 +890,18 @@ } } - __clear_bit(*old_keycode, dev->keybit); - __set_bit(ke->keycode, dev->keybit); - - for (i = 0; i < dev->keycodemax; i++) { - if (input_fetch_keycode(dev, i) == *old_keycode) { - __set_bit(*old_keycode, dev->keybit); - break; /* Setting the bit twice is useless, so break */ + if (*old_keycode <= KEY_MAX) { + __clear_bit(*old_keycode, dev->keybit); + for (i = 0; i < dev->keycodemax; i++) { + if (input_fetch_keycode(dev, i) == *old_keycode) { + __set_bit(*old_keycode, dev->keybit); + /* Setting the bit twice is useless, so break */ + break; + } } } + __set_bit(ke->keycode, dev->keybit); return 0; } @@ -943,9 +957,13 @@ * Simulate keyup event if keycode is not present * in the keymap anymore */ - if (test_bit(EV_KEY, dev->evbit) && - !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && - __test_and_clear_bit(old_keycode, dev->key)) { + if (old_keycode > KEY_MAX) { + dev_warn(dev->dev.parent ?: &dev->dev, + "%s: got too big old keycode %#x\n", + __func__, old_keycode); + } else if (test_bit(EV_KEY, dev->evbit) && + !is_event_supported(old_keycode, dev->keybit, KEY_MAX) && + __test_and_clear_bit(old_keycode, dev->key)) { struct input_value vals[] = { { EV_KEY, old_keycode, 0 }, input_value_sync @@ -1340,19 +1358,19 @@ char name, unsigned long *bm, unsigned int min_bit, unsigned int max_bit) { - int len = 0, i; + int bit = min_bit; + int len = 0; len += snprintf(buf, max(size, 0), "%c", name); - for (i = min_bit; i < max_bit; i++) - if (bm[BIT_WORD(i)] & BIT_MASK(i)) - len += snprintf(buf + len, max(size - len, 0), "%X,", i); + for_each_set_bit_from(bit, bm, max_bit) + len += snprintf(buf + len, max(size - len, 0), "%X,", bit); return len; } -static int input_print_modalias(char *buf, int size, struct input_dev *id, - int add_cr) +static int input_print_modalias_parts(char *buf, int size, int full_len, + struct input_dev *id) { - int len; + int len, klen, remainder, space; len = snprintf(buf, max(size, 0), "input:b%04Xv%04Xp%04Xe%04X-", @@ -1361,8 +1379,49 @@ len += input_print_modalias_bits(buf + len, size - len, 'e', id->evbit, 0, EV_MAX); - len += input_print_modalias_bits(buf + len, size - len, + + /* + * Calculate the remaining space in the buffer making sure we + * have place for the terminating 0. + */ + space = max(size - (len + 1), 0); + + klen = input_print_modalias_bits(buf + len, size - len, 'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX); + len += klen; + + /* + * If we have more data than we can fit in the buffer, check + * if we can trim key data to fit in the rest. We will indicate + * that key data is incomplete by adding "+" sign at the end, like + * this: * "k1,2,3,45,+,". + * + * Note that we shortest key info (if present) is "k+," so we + * can only try to trim if key data is longer than that. + */ + if (full_len && size < full_len + 1 && klen > 3) { + remainder = full_len - len; + /* + * We can only trim if we have space for the remainder + * and also for at least "k+," which is 3 more characters. + */ + if (remainder <= space - 3) { + int i; + /* + * We are guaranteed to have 'k' in the buffer, so + * we need at least 3 additional bytes for storing + * "+," in addition to the remainder. + */ + for (i = size - 1 - remainder - 3; i >= 0; i--) { + if (buf[i] == 'k' || buf[i] == ',') { + strcpy(buf + i + 1, "+,"); + len = i + 3; /* Not counting '\0' */ + break; + } + } + } + } + len += input_print_modalias_bits(buf + len, size - len, 'r', id->relbit, 0, REL_MAX); len += input_print_modalias_bits(buf + len, size - len, @@ -1378,12 +1437,25 @@ len += input_print_modalias_bits(buf + len, size - len, 'w', id->swbit, 0, SW_MAX); - if (add_cr) - len += snprintf(buf + len, max(size - len, 0), "\n"); - return len; } +static int input_print_modalias(char *buf, int size, struct input_dev *id) +{ + int full_len; + + /* + * Printing is done in 2 passes: first one figures out total length + * needed for the modalias string, second one will try to trim key + * data in case when buffer is too small for the entire modalias. + * If the buffer is too small regardless, it will fill as much as it + * can (without trimming key data) into the buffer and leave it to + * the caller to figure out what to do with the result. + */ + full_len = input_print_modalias_parts(NULL, 0, 0, id); + return input_print_modalias_parts(buf, size, full_len, id); +} + static ssize_t input_dev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) @@ -1391,7 +1463,9 @@ struct input_dev *id = to_input_dev(dev); ssize_t len; - len = input_print_modalias(buf, PAGE_SIZE, id, 1); + len = input_print_modalias(buf, PAGE_SIZE, id); + if (len < PAGE_SIZE - 2) + len += snprintf(buf + len, PAGE_SIZE - len, "\n"); return min_t(int, len, PAGE_SIZE); } @@ -1566,6 +1640,23 @@ return 0; } +/* + * This is a pretty gross hack. When building uevent data the driver core + * may try adding more environment variables to kobj_uevent_env without + * telling us, so we have no idea how much of the buffer we can use to + * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially + * reduce amount of memory we will use for the modalias environment variable. + * + * The potential additions are: + * + * SEQNUM=18446744073709551615 - (%llu - 28 bytes) + * HOME=/ (6 bytes) + * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes) + * + * 68 bytes total. Allow extra buffer - 96 bytes + */ +#define UEVENT_ENV_EXTRA_LEN 96 + static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, struct input_dev *dev) { @@ -1575,9 +1666,11 @@ return -ENOMEM; len = input_print_modalias(&env->buf[env->buflen - 1], - sizeof(env->buf) - env->buflen, - dev, 0); - if (len >= (sizeof(env->buf) - env->buflen)) + (int)sizeof(env->buf) - env->buflen - + UEVENT_ENV_EXTRA_LEN, + dev); + if (len >= ((int)sizeof(env->buf) - env->buflen - + UEVENT_ENV_EXTRA_LEN)) return -ENOMEM; env->buflen += len; @@ -1971,6 +2064,14 @@ */ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) { + if (type < EV_CNT && input_max_code[type] && + code > input_max_code[type]) { + pr_err("%s: invalid code %u for type %u\n", __func__, code, + type); + dump_stack(); + return; + } + switch (type) { case EV_KEY: __set_bit(code, dev->keybit); --- linux-oracle-5.4.0.orig/drivers/input/joydev.c +++ linux-oracle-5.4.0/drivers/input/joydev.c @@ -456,7 +456,7 @@ if (IS_ERR(abspam)) return PTR_ERR(abspam); - for (i = 0; i < joydev->nabs; i++) { + for (i = 0; i < len && i < joydev->nabs; i++) { if (abspam[i] > ABS_MAX) { retval = -EINVAL; goto out; @@ -480,6 +480,9 @@ int i; int retval = 0; + if (len % sizeof(*keypam)) + return -EINVAL; + len = min(len, sizeof(joydev->keypam)); /* Validate the map. */ @@ -487,7 +490,7 @@ if (IS_ERR(keypam)) return PTR_ERR(keypam); - for (i = 0; i < joydev->nkey; i++) { + for (i = 0; i < (len / 2) && i < joydev->nkey; i++) { if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) { retval = -EINVAL; goto out; @@ -497,7 +500,7 @@ memcpy(joydev->keypam, keypam, len); for (i = 0; i < joydev->nkey; i++) - joydev->keymap[keypam[i] - BTN_MISC] = i; + joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; out: kfree(keypam); --- linux-oracle-5.4.0.orig/drivers/input/joystick/iforce/iforce-main.c +++ linux-oracle-5.4.0/drivers/input/joystick/iforce/iforce-main.c @@ -50,6 +50,7 @@ { 0x046d, 0xc291, "Logitech WingMan Formula Force", btn_wheel, abs_wheel, ff_iforce }, { 0x05ef, 0x020a, "AVB Top Shot Pegasus", btn_joystick_avb, abs_avb_pegasus, ff_iforce }, { 0x05ef, 0x8884, "AVB Mag Turbo Force", btn_wheel, abs_wheel, ff_iforce }, + { 0x05ef, 0x8886, "Boeder Force Feedback Wheel", btn_wheel, abs_wheel, ff_iforce }, { 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? { 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //? { 0x061c, 0xc084, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, @@ -272,22 +273,22 @@ * Get device info. */ - if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'M', buf, &len) && len >= 3) input_dev->id.vendor = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n"); - if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'P', buf, &len) && len >= 3) input_dev->id.product = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n"); - if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3) + if (!iforce_get_id_packet(iforce, 'B', buf, &len) && len >= 3) iforce->device_memory.end = get_unaligned_le16(buf + 1); else dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n"); - if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2) + if (!iforce_get_id_packet(iforce, 'N', buf, &len) && len >= 2) ff_effects = buf[1]; else dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n"); --- linux-oracle-5.4.0.orig/drivers/input/joystick/iforce/iforce-serio.c +++ linux-oracle-5.4.0/drivers/input/joystick/iforce/iforce-serio.c @@ -39,7 +39,7 @@ again: if (iforce->xmit.head == iforce->xmit.tail) { - clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); + iforce_clear_xmit_and_wake(iforce); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return; } @@ -64,7 +64,7 @@ if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags)) goto again; - clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); + iforce_clear_xmit_and_wake(iforce); spin_unlock_irqrestore(&iforce->xmit_lock, flags); } @@ -169,7 +169,7 @@ iforce_serio->cmd_response_len = iforce_serio->len; /* Signal that command is done */ - wake_up(&iforce->wait); + wake_up_all(&iforce->wait); } else if (likely(iforce->type)) { iforce_process_packet(iforce, iforce_serio->id, iforce_serio->data_in, --- linux-oracle-5.4.0.orig/drivers/input/joystick/iforce/iforce-usb.c +++ linux-oracle-5.4.0/drivers/input/joystick/iforce/iforce-usb.c @@ -30,7 +30,7 @@ spin_lock_irqsave(&iforce->xmit_lock, flags); if (iforce->xmit.head == iforce->xmit.tail) { - clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); + iforce_clear_xmit_and_wake(iforce); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return; } @@ -58,9 +58,9 @@ XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC)) ) { - clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); dev_warn(&iforce_usb->intf->dev, "usb_submit_urb failed %d\n", n); + iforce_clear_xmit_and_wake(iforce); } /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. @@ -92,7 +92,7 @@ id, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, - 0, 0, buf, IFORCE_MAX_LENGTH, HZ); + 0, 0, buf, IFORCE_MAX_LENGTH, 1000); if (status < 0) { dev_err(&iforce_usb->intf->dev, "usb_submit_urb failed: %d\n", status); @@ -175,15 +175,15 @@ struct iforce *iforce = &iforce_usb->iforce; if (urb->status) { - clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); dev_dbg(&iforce_usb->intf->dev, "urb->status %d, exiting\n", urb->status); + iforce_clear_xmit_and_wake(iforce); return; } __iforce_usb_xmit(iforce); - wake_up(&iforce->wait); + wake_up_all(&iforce->wait); } static int iforce_usb_probe(struct usb_interface *intf, --- linux-oracle-5.4.0.orig/drivers/input/joystick/iforce/iforce.h +++ linux-oracle-5.4.0/drivers/input/joystick/iforce/iforce.h @@ -119,6 +119,12 @@ response_data, response_len); } +static inline void iforce_clear_xmit_and_wake(struct iforce *iforce) +{ + clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags); + wake_up_all(&iforce->wait); +} + /* Public functions */ /* iforce-main.c */ int iforce_init_device(struct device *parent, u16 bustype, --- linux-oracle-5.4.0.orig/drivers/input/joystick/psxpad-spi.c +++ linux-oracle-5.4.0/drivers/input/joystick/psxpad-spi.c @@ -292,7 +292,7 @@ if (!pad) return -ENOMEM; - pdev = input_allocate_polled_device(); + pdev = devm_input_allocate_polled_device(&spi->dev); if (!pdev) { dev_err(&spi->dev, "failed to allocate input device\n"); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/input/joystick/spaceball.c +++ linux-oracle-5.4.0/drivers/input/joystick/spaceball.c @@ -19,6 +19,7 @@ #include #include #include +#include #define DRIVER_DESC "SpaceTec SpaceBall 2003/3003/4000 FLX driver" @@ -75,9 +76,15 @@ case 'D': /* Ball data */ if (spaceball->idx != 15) return; - for (i = 0; i < 6; i++) + /* + * Skip first three bytes; read six axes worth of data. + * Axis values are signed 16-bit big-endian. + */ + data += 3; + for (i = 0; i < ARRAY_SIZE(spaceball_axes); i++) { input_report_abs(dev, spaceball_axes[i], - (__s16)((data[2 * i + 3] << 8) | data[2 * i + 2])); + (__s16)get_unaligned_be16(&data[i * 2])); + } break; case 'K': /* Button data */ --- linux-oracle-5.4.0.orig/drivers/input/joystick/xpad.c +++ linux-oracle-5.4.0/drivers/input/joystick/xpad.c @@ -112,11 +112,14 @@ u8 xtype; } xpad_device[] = { { 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 }, + { 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 }, + { 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 }, { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, { 0x044f, 0x0f10, "Thrustmaster Modena GT Wheel", 0, XTYPE_XBOX }, { 0x044f, 0xb326, "Thrustmaster Gamepad GP XID", 0, XTYPE_XBOX360 }, + { 0x03f0, 0x0495, "HyperX Clutch Gladiate", 0, XTYPE_XBOXONE }, { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", 0, XTYPE_XBOX }, { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", 0, XTYPE_XBOX }, { 0x045e, 0x0287, "Microsoft Xbox Controller S", 0, XTYPE_XBOX }, @@ -125,6 +128,7 @@ { 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 }, { 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 }, { 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, + { 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W }, { 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE }, { 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE }, { 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", 0, XTYPE_XBOXONE }, @@ -215,9 +219,17 @@ { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, - { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x02a4, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x02a6, "PDP Wired Controller for Xbox One - Camo Series", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a7, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02a8, "PDP Xbox One Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02ad, "PDP Wired Controller for Xbox One - Stealth Series", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02b3, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE }, + { 0x0e6f, 0x02b8, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, @@ -234,6 +246,7 @@ { 0x0f0d, 0x0063, "Hori Real Arcade Pro Hayabusa (USA) Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x0f0d, 0x0067, "HORIPAD ONE", 0, XTYPE_XBOXONE }, { 0x0f0d, 0x0078, "Hori Real Arcade Pro V Kai Xbox One", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x0f0d, 0x00c5, "Hori Fighting Commander ONE", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x0f30, 0x010b, "Philips Recoil", 0, XTYPE_XBOX }, { 0x0f30, 0x0202, "Joytech Advanced Controller", 0, XTYPE_XBOX }, { 0x0f30, 0x8888, "BigBen XBMiniPad Controller", 0, XTYPE_XBOX }, @@ -241,6 +254,8 @@ { 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 }, { 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 }, + { 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 }, + { 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 }, { 0x12ab, 0x0004, "Honey Bee Xbox360 dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x12ab, 0x0301, "PDP AFTERGLOW AX.1", 0, XTYPE_XBOX360 }, { 0x12ab, 0x0303, "Mortal Kombat Klassic FightStick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, @@ -249,9 +264,10 @@ { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 }, { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, - { 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 }, + { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, + { 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE }, { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 }, @@ -295,6 +311,10 @@ { 0x1bad, 0xfa01, "MadCatz GamePad", 0, XTYPE_XBOX360 }, { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 }, { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 }, + { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE }, + { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE }, + { 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 }, + { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, { 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 }, { 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, @@ -309,6 +329,7 @@ { 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, + { 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 }, { 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE }, @@ -318,6 +339,16 @@ { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 }, { 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 }, { 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, + { 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 }, + { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, + { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, + { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, { 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } @@ -402,7 +433,9 @@ static const struct usb_device_id xpad_table[] = { { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ + XPAD_XBOX360_VENDOR(0x03eb), /* Wooting Keyboards (Legacy) */ XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ + XPAD_XBOXONE_VENDOR(0x03f0), /* HP HyperX Xbox One Controllers */ XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ @@ -412,12 +445,15 @@ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */ XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz GamePad */ + XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */ XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */ XPAD_XBOX360_VENDOR(0x1038), /* SteelSeries Controllers */ XPAD_XBOX360_VENDOR(0x11c9), /* Nacon GC100XF */ + XPAD_XBOX360_VENDOR(0x11ff), /* PXN V900 */ + XPAD_XBOX360_VENDOR(0x1209), /* Ardwiino Controllers */ XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ @@ -427,8 +463,17 @@ XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ + XPAD_XBOX360_VENDOR(0x20d6), /* PowerA Controllers */ + XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA Controllers */ XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */ XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */ + XPAD_XBOX360_VENDOR(0x2563), /* OneXPlayer Gamepad */ + XPAD_XBOX360_VENDOR(0x260d), /* Dareu H101 */ + XPAD_XBOXONE_VENDOR(0x2dc8), /* 8BitDo Pro 2 Wired Controller for Xbox */ + XPAD_XBOXONE_VENDOR(0x2e24), /* Hyperkin Duke X-Box One pad */ + XPAD_XBOX360_VENDOR(0x2f24), /* GameSir Controllers */ + XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */ + XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */ { } }; @@ -450,6 +495,9 @@ } +#define GIP_WIRED_INTF_DATA 0 +#define GIP_WIRED_INTF_AUDIO 1 + /* * This packet is required for all Xbox One pads with 2015 * or later firmware installed (or present from the factory). @@ -459,6 +507,16 @@ }; /* + * This packet is required for Xbox One S (0x045e:0x02ea) + * and Xbox One Elite Series 2 (0x045e:0x0b00) pads to + * initialize the controller that was previously used in + * Bluetooth mode. + */ +static const u8 xboxone_s_init[] = { + 0x05, 0x20, 0x00, 0x0f, 0x06 +}; + +/* * This packet is required for the Titanfall 2 Xbox One pads * (0x0e6f:0x0165) to finish initialization and for Hori pads * (0x0f0d:0x0067) to make the analog sticks work. @@ -516,6 +574,8 @@ XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), + XBOXONE_INIT_PKT(0x045e, 0x02ea, xboxone_s_init), + XBOXONE_INIT_PKT(0x045e, 0x0b00, xboxone_s_init), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), @@ -1762,7 +1822,7 @@ } if (xpad->xtype == XTYPE_XBOXONE && - intf->cur_altsetting->desc.bInterfaceNumber != 0) { + intf->cur_altsetting->desc.bInterfaceNumber != GIP_WIRED_INTF_DATA) { /* * The Xbox One controller lists three interfaces all with the * same interface class, subclass and protocol. Differentiate by @@ -1932,7 +1992,6 @@ .disconnect = xpad_disconnect, .suspend = xpad_suspend, .resume = xpad_resume, - .reset_resume = xpad_resume, .id_table = xpad_table, }; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/Kconfig +++ linux-oracle-5.4.0/drivers/input/keyboard/Kconfig @@ -68,9 +68,6 @@ To compile this driver as a module, choose M here: the module will be called amikbd. -config ATARI_KBD_CORE - bool - config KEYBOARD_APPLESPI tristate "Apple SPI keyboard and trackpad" depends on ACPI && EFI --- linux-oracle-5.4.0.orig/drivers/input/keyboard/adp5589-keys.c +++ linux-oracle-5.4.0/drivers/input/keyboard/adp5589-keys.c @@ -390,10 +390,17 @@ struct adp5589_kpad *kpad = gpiochip_get_data(chip); unsigned int bank = kpad->var->bank(kpad->gpiomap[off]); unsigned int bit = kpad->var->bit(kpad->gpiomap[off]); + int val; - return !!(adp5589_read(kpad->client, - kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) & - bit); + mutex_lock(&kpad->gpio_lock); + if (kpad->dir[bank] & bit) + val = kpad->dat_out[bank]; + else + val = adp5589_read(kpad->client, + kpad->var->reg(ADP5589_GPI_STATUS_A) + bank); + mutex_unlock(&kpad->gpio_lock); + + return !!(val & bit); } static void adp5589_gpio_set_value(struct gpio_chip *chip, --- linux-oracle-5.4.0.orig/drivers/input/keyboard/applespi.c +++ linux-oracle-5.4.0/drivers/input/keyboard/applespi.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -400,7 +401,7 @@ unsigned int cmd_msg_cntr; /* lock to protect the above parameters and flags below */ spinlock_t cmd_msg_lock; - bool cmd_msg_queued; + ktime_t cmd_msg_queued; enum applespi_evt_type cmd_evt_type; struct led_classdev backlight_info; @@ -716,7 +717,7 @@ wake_up_all(&applespi->drain_complete); if (is_write_msg) { - applespi->cmd_msg_queued = false; + applespi->cmd_msg_queued = 0; applespi_send_cmd_msg(applespi); } @@ -758,8 +759,16 @@ return 0; /* check whether send is in progress */ - if (applespi->cmd_msg_queued) - return 0; + if (applespi->cmd_msg_queued) { + if (ktime_ms_delta(ktime_get(), applespi->cmd_msg_queued) < 1000) + return 0; + + dev_warn(&applespi->spi->dev, "Command %d timed out\n", + applespi->cmd_evt_type); + + applespi->cmd_msg_queued = 0; + applespi->write_active = false; + } /* set up packet */ memset(packet, 0, APPLESPI_PACKET_SIZE); @@ -856,7 +865,7 @@ return sts; } - applespi->cmd_msg_queued = true; + applespi->cmd_msg_queued = ktime_get_coarse(); applespi->write_active = true; return 0; @@ -1908,7 +1917,7 @@ applespi->drain = false; applespi->have_cl_led_on = false; applespi->have_bl_level = 0; - applespi->cmd_msg_queued = false; + applespi->cmd_msg_queued = 0; applespi->read_active = false; applespi->write_active = false; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/atkbd.c +++ linux-oracle-5.4.0/drivers/input/keyboard/atkbd.c @@ -84,7 +84,7 @@ 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183, 0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185, 0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0, - 0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85, + 0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85, 0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0, 82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99, @@ -715,6 +715,44 @@ ps2dev->serio->phys); } +#ifdef CONFIG_X86 +static bool atkbd_is_portable_device(void) +{ + static const char * const chassis_types[] = { + "8", /* Portable */ + "9", /* Laptop */ + "10", /* Notebook */ + "14", /* Sub-Notebook */ + "31", /* Convertible */ + "32", /* Detachable */ + }; + int i; + + for (i = 0; i < ARRAY_SIZE(chassis_types); i++) + if (dmi_match(DMI_CHASSIS_TYPE, chassis_types[i])) + return true; + + return false; +} + +/* + * On many modern laptops ATKBD_CMD_GETID may cause problems, on these laptops + * the controller is always in translated mode. In this mode mice/touchpads will + * not work. So in this case simply assume a keyboard is connected to avoid + * confusing some laptop keyboards. + * + * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard + * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id + * and in translated mode that is a no-op. + */ +static bool atkbd_skip_getid(struct atkbd *atkbd) +{ + return atkbd->translated && atkbd_is_portable_device(); +} +#else +static inline bool atkbd_skip_getid(struct atkbd *atkbd) { return false; } +#endif + /* * atkbd_probe() probes for an AT keyboard on a serio port. */ @@ -736,6 +774,11 @@ "keyboard reset failed on %s\n", ps2dev->serio->phys); + if (atkbd_skip_getid(atkbd)) { + atkbd->id = 0xab83; + return 0; + } + /* * Then we check the keyboard ID. We should get 0xab83 under normal conditions. * Some keyboards report different values, but the first byte is always 0xab or @@ -747,9 +790,9 @@ if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { /* - * If the get ID command failed, we check if we can at least set the LEDs on - * the keyboard. This should work on every keyboard out there. It also turns - * the LEDs off, which we want anyway. + * If the get ID command failed, we check if we can at least set + * the LEDs on the keyboard. This should work on every keyboard out there. + * It also turns the LEDs off, which we want anyway. */ param[0] = 0; if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) --- linux-oracle-5.4.0.orig/drivers/input/keyboard/cros_ec_keyb.c +++ linux-oracle-5.4.0/drivers/input/keyboard/cros_ec_keyb.c @@ -183,6 +183,7 @@ "changed: [r%d c%d]: byte %02x\n", row, col, new_state); + input_event(idev, EV_MSC, MSC_SCAN, pos); input_report_key(idev, keycodes[pos], new_state); } --- linux-oracle-5.4.0.orig/drivers/input/keyboard/dlink-dir685-touchkeys.c +++ linux-oracle-5.4.0/drivers/input/keyboard/dlink-dir685-touchkeys.c @@ -143,7 +143,7 @@ static struct i2c_driver dir685_tk_i2c_driver = { .driver = { - .name = "dlin-dir685-touchkeys", + .name = "dlink-dir685-touchkeys", .of_match_table = of_match_ptr(dir685_tk_of_match), }, .probe = dir685_tk_probe, --- linux-oracle-5.4.0.orig/drivers/input/keyboard/ep93xx_keypad.c +++ linux-oracle-5.4.0/drivers/input/keyboard/ep93xx_keypad.c @@ -250,8 +250,8 @@ } keypad->irq = platform_get_irq(pdev, 0); - if (!keypad->irq) { - err = -ENXIO; + if (keypad->irq < 0) { + err = keypad->irq; goto failed_free; } --- linux-oracle-5.4.0.orig/drivers/input/keyboard/gpio_keys_polled.c +++ linux-oracle-5.4.0/drivers/input/keyboard/gpio_keys_polled.c @@ -325,12 +325,10 @@ error = devm_gpio_request_one(dev, button->gpio, flags, button->desc ? : DRV_NAME); - if (error) { - dev_err(dev, - "unable to claim gpio %u, err=%d\n", - button->gpio, error); - return error; - } + if (error) + return dev_err_probe(dev, error, + "unable to claim gpio %u\n", + button->gpio); bdata->gpiod = gpio_to_desc(button->gpio); if (!bdata->gpiod) { --- linux-oracle-5.4.0.orig/drivers/input/keyboard/hil_kbd.c +++ linux-oracle-5.4.0/drivers/input/keyboard/hil_kbd.c @@ -512,6 +512,7 @@ HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "combo devices are not supported.\n"); + error = -EINVAL; goto bail1; } --- linux-oracle-5.4.0.orig/drivers/input/keyboard/ipaq-micro-keys.c +++ linux-oracle-5.4.0/drivers/input/keyboard/ipaq-micro-keys.c @@ -105,6 +105,9 @@ keys->codes = devm_kmemdup(&pdev->dev, micro_keycodes, keys->input->keycodesize * keys->input->keycodemax, GFP_KERNEL); + if (!keys->codes) + return -ENOMEM; + keys->input->keycode = keys->codes; __set_bit(EV_KEY, keys->input->evbit); --- linux-oracle-5.4.0.orig/drivers/input/keyboard/nspire-keypad.c +++ linux-oracle-5.4.0/drivers/input/keyboard/nspire-keypad.c @@ -93,9 +93,15 @@ return IRQ_HANDLED; } -static int nspire_keypad_chip_init(struct nspire_keypad *keypad) +static int nspire_keypad_open(struct input_dev *input) { + struct nspire_keypad *keypad = input_get_drvdata(input); unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles; + int error; + + error = clk_prepare_enable(keypad->clk); + if (error) + return error; cycles_per_us = (clk_get_rate(keypad->clk) / 1000000); if (cycles_per_us == 0) @@ -121,30 +127,6 @@ keypad->int_mask = 1 << 1; writel(keypad->int_mask, keypad->reg_base + KEYPAD_INTMSK); - /* Disable GPIO interrupts to prevent hanging on touchpad */ - /* Possibly used to detect touchpad events */ - writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT); - /* Acknowledge existing interrupts */ - writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS); - - return 0; -} - -static int nspire_keypad_open(struct input_dev *input) -{ - struct nspire_keypad *keypad = input_get_drvdata(input); - int error; - - error = clk_prepare_enable(keypad->clk); - if (error) - return error; - - error = nspire_keypad_chip_init(keypad); - if (error) { - clk_disable_unprepare(keypad->clk); - return error; - } - return 0; } @@ -152,6 +134,11 @@ { struct nspire_keypad *keypad = input_get_drvdata(input); + /* Disable interrupts */ + writel(0, keypad->reg_base + KEYPAD_INTMSK); + /* Acknowledge existing interrupts */ + writel(~0, keypad->reg_base + KEYPAD_INT); + clk_disable_unprepare(keypad->clk); } @@ -210,6 +197,25 @@ return -ENOMEM; } + error = clk_prepare_enable(keypad->clk); + if (error) { + dev_err(&pdev->dev, "failed to enable clock\n"); + return error; + } + + /* Disable interrupts */ + writel(0, keypad->reg_base + KEYPAD_INTMSK); + /* Acknowledge existing interrupts */ + writel(~0, keypad->reg_base + KEYPAD_INT); + + /* Disable GPIO interrupts to prevent hanging on touchpad */ + /* Possibly used to detect touchpad events */ + writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT); + /* Acknowledge existing GPIO interrupts */ + writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS); + + clk_disable_unprepare(keypad->clk); + input_set_drvdata(input, keypad); input->id.bustype = BUS_HOST; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/omap-keypad.c +++ linux-oracle-5.4.0/drivers/input/keyboard/omap-keypad.c @@ -46,7 +46,7 @@ unsigned short keymap[]; }; -static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0); +static DECLARE_TASKLET_DISABLED_OLD(kp_tasklet, omap_kp_tasklet); static unsigned int *row_gpios; static unsigned int *col_gpios; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/omap4-keypad.c +++ linux-oracle-5.4.0/drivers/input/keyboard/omap4-keypad.c @@ -186,12 +186,8 @@ return 0; } -static void omap4_keypad_close(struct input_dev *input) +static void omap4_keypad_stop(struct omap4_keypad *keypad_data) { - struct omap4_keypad *keypad_data = input_get_drvdata(input); - - disable_irq(keypad_data->irq); - /* Disable interrupts and wake-up events */ kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, OMAP4_VAL_IRQDISABLE); @@ -200,7 +196,15 @@ /* clear pending interrupts */ kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); +} + +static void omap4_keypad_close(struct input_dev *input) +{ + struct omap4_keypad *keypad_data; + keypad_data = input_get_drvdata(input); + disable_irq(keypad_data->irq); + omap4_keypad_stop(keypad_data); enable_irq(keypad_data->irq); pm_runtime_put_sync(input->dev.parent); @@ -223,13 +227,37 @@ return 0; } +static int omap4_keypad_check_revision(struct device *dev, + struct omap4_keypad *keypad_data) +{ + unsigned int rev; + + rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); + rev &= 0x03 << 30; + rev >>= 30; + switch (rev) { + case KBD_REVISION_OMAP4: + keypad_data->reg_offset = 0x00; + keypad_data->irqreg_offset = 0x00; + break; + case KBD_REVISION_OMAP5: + keypad_data->reg_offset = 0x10; + keypad_data->irqreg_offset = 0x0c; + break; + default: + dev_err(dev, "Keypad reports unsupported revision %d", rev); + return -EINVAL; + } + + return 0; +} + static int omap4_keypad_probe(struct platform_device *pdev) { struct omap4_keypad *keypad_data; struct input_dev *input_dev; struct resource *res; unsigned int max_keys; - int rev; int irq; int error; @@ -240,10 +268,8 @@ } irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(&pdev->dev, "no keyboard irq assigned\n"); - return -EINVAL; - } + if (irq < 0) + return irq; keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); if (!keypad_data) { @@ -271,41 +297,33 @@ goto err_release_mem; } + pm_runtime_enable(&pdev->dev); /* * Enable clocks for the keypad module so that we can read * revision register. */ - pm_runtime_enable(&pdev->dev); error = pm_runtime_get_sync(&pdev->dev); if (error) { dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); - goto err_unmap; - } - rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); - rev &= 0x03 << 30; - rev >>= 30; - switch (rev) { - case KBD_REVISION_OMAP4: - keypad_data->reg_offset = 0x00; - keypad_data->irqreg_offset = 0x00; - break; - case KBD_REVISION_OMAP5: - keypad_data->reg_offset = 0x10; - keypad_data->irqreg_offset = 0x0c; - break; - default: - dev_err(&pdev->dev, - "Keypad reports unsupported revision %d", rev); - error = -EINVAL; - goto err_pm_put_sync; + pm_runtime_put_noidle(&pdev->dev); + } else { + error = omap4_keypad_check_revision(&pdev->dev, + keypad_data); + if (!error) { + /* Ensure device does not raise interrupts */ + omap4_keypad_stop(keypad_data); + } + pm_runtime_put_sync(&pdev->dev); } + if (error) + goto err_pm_disable; /* input device allocation */ keypad_data->input = input_dev = input_allocate_device(); if (!input_dev) { error = -ENOMEM; - goto err_pm_put_sync; + goto err_pm_disable; } input_dev->name = pdev->name; @@ -351,28 +369,25 @@ goto err_free_keymap; } - device_init_wakeup(&pdev->dev, true); - pm_runtime_put_sync(&pdev->dev); - error = input_register_device(keypad_data->input); if (error < 0) { dev_err(&pdev->dev, "failed to register input device\n"); - goto err_pm_disable; + goto err_free_irq; } + device_init_wakeup(&pdev->dev, true); platform_set_drvdata(pdev, keypad_data); + return 0; -err_pm_disable: - pm_runtime_disable(&pdev->dev); +err_free_irq: free_irq(keypad_data->irq, keypad_data); err_free_keymap: kfree(keypad_data->keymap); err_free_input: input_free_device(input_dev); -err_pm_put_sync: - pm_runtime_put_sync(&pdev->dev); -err_unmap: +err_pm_disable: + pm_runtime_disable(&pdev->dev); iounmap(keypad_data->base); err_release_mem: release_mem_region(res->start, resource_size(res)); --- linux-oracle-5.4.0.orig/drivers/input/keyboard/qt1050.c +++ linux-oracle-5.4.0/drivers/input/keyboard/qt1050.c @@ -226,7 +226,12 @@ int err; /* Read Chip ID */ - regmap_read(ts->regmap, QT1050_CHIP_ID, &val); + err = regmap_read(ts->regmap, QT1050_CHIP_ID, &val); + if (err) { + dev_err(&ts->client->dev, "Failed to read chip ID: %d\n", err); + return false; + } + if (val != QT1050_CHIP_ID_VER) { dev_err(&ts->client->dev, "ID %d not supported\n", val); return false; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/snvs_pwrkey.c +++ linux-oracle-5.4.0/drivers/input/keyboard/snvs_pwrkey.c @@ -3,6 +3,7 @@ // Driver for the IMX SNVS ON/OFF Power Key // Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved. +#include #include #include #include @@ -81,6 +82,11 @@ return IRQ_HANDLED; } +static void imx_snvs_pwrkey_disable_clk(void *data) +{ + clk_disable_unprepare(data); +} + static void imx_snvs_pwrkey_act(void *pdata) { struct pwrkey_drv_data *pd = pdata; @@ -93,6 +99,7 @@ struct pwrkey_drv_data *pdata = NULL; struct input_dev *input = NULL; struct device_node *np; + struct clk *clk; int error; /* Get SNVS register Page */ @@ -115,6 +122,28 @@ dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n"); } + clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Failed to get snvs clock (%pe)\n", clk); + return PTR_ERR(clk); + } + + error = clk_prepare_enable(clk); + if (error) { + dev_err(&pdev->dev, "Failed to enable snvs clock (%pe)\n", + ERR_PTR(error)); + return error; + } + + error = devm_add_action_or_reset(&pdev->dev, + imx_snvs_pwrkey_disable_clk, clk); + if (error) { + dev_err(&pdev->dev, + "Failed to register clock cleanup handler (%pe)\n", + ERR_PTR(error)); + return error; + } + pdata->wakeup = of_property_read_bool(np, "wakeup-source"); pdata->irq = platform_get_irq(pdev, 0); --- linux-oracle-5.4.0.orig/drivers/input/keyboard/sunkbd.c +++ linux-oracle-5.4.0/drivers/input/keyboard/sunkbd.c @@ -99,7 +99,8 @@ switch (data) { case SUNKBD_RET_RESET: - schedule_work(&sunkbd->tq); + if (sunkbd->enabled) + schedule_work(&sunkbd->tq); sunkbd->reset = -1; break; @@ -200,16 +201,12 @@ } /* - * sunkbd_reinit() sets leds and beeps to a state the computer remembers they - * were in. + * sunkbd_set_leds_beeps() sets leds and beeps to a state the computer remembers + * they were in. */ -static void sunkbd_reinit(struct work_struct *work) +static void sunkbd_set_leds_beeps(struct sunkbd *sunkbd) { - struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq); - - wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); - serio_write(sunkbd->serio, SUNKBD_CMD_SETLED); serio_write(sunkbd->serio, (!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | @@ -222,11 +219,39 @@ SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd)); } + +/* + * sunkbd_reinit() wait for the keyboard reset to complete and restores state + * of leds and beeps. + */ + +static void sunkbd_reinit(struct work_struct *work) +{ + struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq); + + /* + * It is OK that we check sunkbd->enabled without pausing serio, + * as we only want to catch true->false transition that will + * happen once and we will be woken up for it. + */ + wait_event_interruptible_timeout(sunkbd->wait, + sunkbd->reset >= 0 || !sunkbd->enabled, + HZ); + + if (sunkbd->reset >= 0 && sunkbd->enabled) + sunkbd_set_leds_beeps(sunkbd); +} + static void sunkbd_enable(struct sunkbd *sunkbd, bool enable) { serio_pause_rx(sunkbd->serio); sunkbd->enabled = enable; serio_continue_rx(sunkbd->serio); + + if (!enable) { + wake_up_interruptible(&sunkbd->wait); + cancel_work_sync(&sunkbd->tq); + } } /* --- linux-oracle-5.4.0.orig/drivers/input/keyboard/tm2-touchkey.c +++ linux-oracle-5.4.0/drivers/input/keyboard/tm2-touchkey.c @@ -75,6 +75,14 @@ .cmd_led_off = ARIES_TOUCHKEY_CMD_LED_OFF, }; +static const struct touchkey_variant tc360_touchkey_variant = { + .keycode_reg = 0x00, + .base_reg = 0x00, + .fixed_regulator = true, + .cmd_led_on = TM2_TOUCHKEY_CMD_LED_ON, + .cmd_led_off = TM2_TOUCHKEY_CMD_LED_OFF, +}; + static int tm2_touchkey_led_brightness_set(struct led_classdev *led_dev, enum led_brightness brightness) { @@ -327,6 +335,9 @@ }, { .compatible = "cypress,aries-touchkey", .data = &aries_touchkey_variant, + }, { + .compatible = "coreriver,tc360-touchkey", + .data = &tc360_touchkey_variant, }, { }, }; --- linux-oracle-5.4.0.orig/drivers/input/keyboard/twl4030_keypad.c +++ linux-oracle-5.4.0/drivers/input/keyboard/twl4030_keypad.c @@ -50,7 +50,7 @@ bool autorepeat; unsigned int n_rows; unsigned int n_cols; - unsigned int irq; + int irq; struct device *dbg_dev; struct input_dev *input; @@ -376,10 +376,8 @@ } kp->irq = platform_get_irq(pdev, 0); - if (!kp->irq) { - dev_err(&pdev->dev, "no keyboard irq assigned\n"); - return -EINVAL; - } + if (kp->irq < 0) + return kp->irq; error = matrix_keypad_build_keymap(keymap_data, NULL, TWL4030_MAX_ROWS, --- linux-oracle-5.4.0.orig/drivers/input/misc/adxl34x.c +++ linux-oracle-5.4.0/drivers/input/misc/adxl34x.c @@ -696,7 +696,7 @@ struct input_dev *input_dev; const struct adxl34x_platform_data *pdata; int err, range, i; - unsigned char revid; + int revid; if (!irq) { dev_err(dev, "no IRQ?\n"); @@ -811,8 +811,7 @@ AC_WRITE(ac, POWER_CTL, 0); err = request_threaded_irq(ac->irq, NULL, adxl34x_irq, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - dev_name(dev), ac); + IRQF_ONESHOT, dev_name(dev), ac); if (err) { dev_err(dev, "irq %d busy?\n", ac->irq); goto err_free_mem; --- linux-oracle-5.4.0.orig/drivers/input/misc/ati_remote2.c +++ linux-oracle-5.4.0/drivers/input/misc/ati_remote2.c @@ -68,7 +68,7 @@ { pr_debug("%s()\n", __func__); - return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); + return sprintf(buffer, "0x%04x\n", *(unsigned int *)kp->arg); } static int ati_remote2_set_mode_mask(const char *val, @@ -84,7 +84,7 @@ { pr_debug("%s()\n", __func__); - return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg); + return sprintf(buffer, "0x%02x\n", *(unsigned int *)kp->arg); } static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; --- linux-oracle-5.4.0.orig/drivers/input/misc/cm109.c +++ linux-oracle-5.4.0/drivers/input/misc/cm109.c @@ -568,12 +568,15 @@ dev->ctl_data->byte[HID_OR2] = dev->keybit; dev->ctl_data->byte[HID_OR3] = 0x00; + dev->ctl_urb_pending = 1; error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL); - if (error) + if (error) { + dev->ctl_urb_pending = 0; dev_err(&dev->intf->dev, "%s: usb_submit_urb (urb_ctl) failed %d\n", __func__, error); - else + } else { dev->open = 1; + } mutex_unlock(&dev->pm_mutex); --- linux-oracle-5.4.0.orig/drivers/input/misc/drv260x.c +++ linux-oracle-5.4.0/drivers/input/misc/drv260x.c @@ -435,6 +435,7 @@ } do { + usleep_range(15000, 15500); error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); if (error) { dev_err(&haptics->client->dev, --- linux-oracle-5.4.0.orig/drivers/input/misc/ims-pcu.c +++ linux-oracle-5.4.0/drivers/input/misc/ims-pcu.c @@ -42,8 +42,8 @@ #define IMS_PCU_PART_NUMBER_LEN 15 #define IMS_PCU_SERIAL_NUMBER_LEN 8 #define IMS_PCU_DOM_LEN 8 -#define IMS_PCU_FW_VERSION_LEN (9 + 1) -#define IMS_PCU_BL_VERSION_LEN (9 + 1) +#define IMS_PCU_FW_VERSION_LEN 16 +#define IMS_PCU_BL_VERSION_LEN 16 #define IMS_PCU_BL_RESET_REASON_LEN (2 + 1) #define IMS_PCU_PCU_B_DEVICE_ID 5 --- linux-oracle-5.4.0.orig/drivers/input/misc/keyspan_remote.c +++ linux-oracle-5.4.0/drivers/input/misc/keyspan_remote.c @@ -336,7 +336,8 @@ int retval = 0; retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0); + 0x11, 0x40, 0x5601, 0x0, NULL, 0, + USB_CTRL_SET_TIMEOUT); if (retval) { dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n", __func__, retval); @@ -344,7 +345,8 @@ } retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x44, 0x40, 0x0, 0x0, NULL, 0, 0); + 0x44, 0x40, 0x0, 0x0, NULL, 0, + USB_CTRL_SET_TIMEOUT); if (retval) { dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n", __func__, retval); @@ -352,7 +354,8 @@ } retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - 0x22, 0x40, 0x0, 0x0, NULL, 0, 0); + 0x22, 0x40, 0x0, 0x0, NULL, 0, + USB_CTRL_SET_TIMEOUT); if (retval) { dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n", __func__, retval); --- linux-oracle-5.4.0.orig/drivers/input/misc/max77650-onkey.c +++ linux-oracle-5.4.0/drivers/input/misc/max77650-onkey.c @@ -108,9 +108,16 @@ return input_register_device(onkey->input); } +static const struct of_device_id max77650_onkey_of_match[] = { + { .compatible = "maxim,max77650-onkey" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77650_onkey_of_match); + static struct platform_driver max77650_onkey_driver = { .driver = { .name = "max77650-onkey", + .of_match_table = max77650_onkey_of_match, }, .probe = max77650_onkey_probe, }; --- linux-oracle-5.4.0.orig/drivers/input/misc/pm8xxx-vibrator.c +++ linux-oracle-5.4.0/drivers/input/misc/pm8xxx-vibrator.c @@ -14,7 +14,8 @@ #define VIB_MAX_LEVEL_mV (3100) #define VIB_MIN_LEVEL_mV (1200) -#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV) +#define VIB_PER_STEP_mV (100) +#define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV + VIB_PER_STEP_mV) #define MAX_FF_SPEED 0xff @@ -90,7 +91,7 @@ if (regs->enable_mask) rc = regmap_update_bits(vib->regmap, regs->enable_addr, - on ? regs->enable_mask : 0, val); + regs->enable_mask, on ? ~0 : 0); return rc; } @@ -118,10 +119,10 @@ vib->active = true; vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) + VIB_MIN_LEVEL_mV; - vib->level /= 100; + vib->level /= VIB_PER_STEP_mV; } else { vib->active = false; - vib->level = VIB_MIN_LEVEL_mV / 100; + vib->level = VIB_MIN_LEVEL_mV / VIB_PER_STEP_mV; } pm8xxx_vib_set(vib, vib->active); --- linux-oracle-5.4.0.orig/drivers/input/misc/powermate.c +++ linux-oracle-5.4.0/drivers/input/misc/powermate.c @@ -425,6 +425,7 @@ pm->requires_update = 0; usb_kill_urb(pm->irq); input_unregister_device(pm->input); + usb_kill_urb(pm->config); usb_free_urb(pm->irq); usb_free_urb(pm->config); powermate_free_buffers(interface_to_usbdev(intf), pm); --- linux-oracle-5.4.0.orig/drivers/input/misc/rk805-pwrkey.c +++ linux-oracle-5.4.0/drivers/input/misc/rk805-pwrkey.c @@ -98,6 +98,7 @@ }; module_platform_driver(rk805_pwrkey_driver); +MODULE_ALIAS("platform:rk805-pwrkey"); MODULE_AUTHOR("Joseph Chen "); MODULE_DESCRIPTION("RK805 PMIC Power Key driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/input/misc/sparcspkr.c +++ linux-oracle-5.4.0/drivers/input/misc/sparcspkr.c @@ -205,6 +205,7 @@ info = &state->u.bbc; info->clock_freq = of_getintprop_default(dp, "clock-frequency", 0); + of_node_put(dp); if (!info->clock_freq) goto out_free; --- linux-oracle-5.4.0.orig/drivers/input/misc/uinput.c +++ linux-oracle-5.4.0/drivers/input/misc/uinput.c @@ -74,12 +74,16 @@ struct uinput_device *udev = input_get_drvdata(dev); struct timespec64 ts; - udev->buff[udev->head].type = type; - udev->buff[udev->head].code = code; - udev->buff[udev->head].value = value; ktime_get_ts64(&ts); - udev->buff[udev->head].input_event_sec = ts.tv_sec; - udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC; + + udev->buff[udev->head] = (struct input_event) { + .input_event_sec = ts.tv_sec, + .input_event_usec = ts.tv_nsec / NSEC_PER_USEC, + .type = type, + .code = code, + .value = value, + }; + udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; wake_up_interruptible(&udev->waitq); @@ -412,6 +416,20 @@ return -EINVAL; } + /* + * Limit number of contacts to a reasonable value (100). This + * ensures that we need less than 2 pages for struct input_mt + * (we are not using in-kernel slot assignment so not going to + * allocate memory for the "red" table), and we should have no + * trouble getting this much memory. + */ + if (code == ABS_MT_SLOT && max > 99) { + printk(KERN_DEBUG + "%s: unreasonably large number of slots requested: %d\n", + UINPUT_NAME, max); + return -EINVAL; + } + return 0; } --- linux-oracle-5.4.0.orig/drivers/input/mouse/alps.c +++ linux-oracle-5.4.0/drivers/input/mouse/alps.c @@ -852,8 +852,8 @@ x = y = z = 0; /* Divide 4 since trackpoint's speed is too fast */ - input_report_rel(dev2, REL_X, (char)x / 4); - input_report_rel(dev2, REL_Y, -((char)y / 4)); + input_report_rel(dev2, REL_X, (s8)x / 4); + input_report_rel(dev2, REL_Y, -((s8)y / 4)); psmouse_report_standard_buttons(dev2, packet[3]); @@ -1104,8 +1104,8 @@ ((packet[3] & 0x20) << 1); z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1); - input_report_rel(dev2, REL_X, (char)x); - input_report_rel(dev2, REL_Y, -((char)y)); + input_report_rel(dev2, REL_X, (s8)x); + input_report_rel(dev2, REL_Y, -((s8)y)); input_report_abs(dev2, ABS_PRESSURE, z); psmouse_report_standard_buttons(dev2, packet[1]); @@ -2294,20 +2294,20 @@ if (reg < 0) return reg; - x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ + x_pitch = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */ x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */ - y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */ + y_pitch = (s8)reg >> 4; /* sign extend upper 4 bits */ y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */ reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1); if (reg < 0) return reg; - x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ + x_electrode = (s8)(reg << 4) >> 4; /* sign extend lower 4 bits */ x_electrode = 17 + x_electrode; - y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */ + y_electrode = (s8)reg >> 4; /* sign extend upper 4 bits */ y_electrode = 13 + y_electrode; x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */ --- linux-oracle-5.4.0.orig/drivers/input/mouse/appletouch.c +++ linux-oracle-5.4.0/drivers/input/mouse/appletouch.c @@ -916,6 +916,8 @@ set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); set_bit(BTN_LEFT, input_dev->keybit); + INIT_WORK(&dev->work, atp_reinit); + error = input_register_device(dev->input); if (error) goto err_free_buffer; @@ -923,8 +925,6 @@ /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); - INIT_WORK(&dev->work, atp_reinit); - return 0; err_free_buffer: --- linux-oracle-5.4.0.orig/drivers/input/mouse/bcm5974.c +++ linux-oracle-5.4.0/drivers/input/mouse/bcm5974.c @@ -942,17 +942,22 @@ if (!dev->tp_data) goto err_free_bt_buffer; - if (dev->bt_urb) + if (dev->bt_urb) { usb_fill_int_urb(dev->bt_urb, udev, usb_rcvintpipe(udev, cfg->bt_ep), dev->bt_data, dev->cfg.bt_datalen, bcm5974_irq_button, dev, 1); + dev->bt_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + } + usb_fill_int_urb(dev->tp_urb, udev, usb_rcvintpipe(udev, cfg->tp_ep), dev->tp_data, dev->cfg.tp_datalen, bcm5974_irq_trackpad, dev, 1); + dev->tp_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + /* create bcm5974 device */ usb_make_path(udev, dev->phys, sizeof(dev->phys)); strlcat(dev->phys, "/input0", sizeof(dev->phys)); --- linux-oracle-5.4.0.orig/drivers/input/mouse/cyapa_gen6.c +++ linux-oracle-5.4.0/drivers/input/mouse/cyapa_gen6.c @@ -573,7 +573,7 @@ memset(&cmd, 0, sizeof(cmd)); put_unaligned_le16(PIP_OUTPUT_REPORT_ADDR, &cmd.head.addr); - put_unaligned_le16(sizeof(cmd), &cmd.head.length - 2); + put_unaligned_le16(sizeof(cmd) - 2, &cmd.head.length); cmd.head.report_id = PIP_APP_CMD_REPORT_ID; cmd.head.cmd_code = PIP_RETRIEVE_DATA_STRUCTURE; put_unaligned_le16(read_offset, &cmd.read_offset); --- linux-oracle-5.4.0.orig/drivers/input/mouse/cypress_ps2.c +++ linux-oracle-5.4.0/drivers/input/mouse/cypress_ps2.c @@ -387,7 +387,9 @@ if (ret < 0) return ret; +#if ( CYPRESS_SIMULATED_MT != 1 ) __set_bit(INPUT_PROP_SEMI_MT, input->propbit); +#endif input_abs_set_res(input, ABS_X, cytp->tp_res_x); input_abs_set_res(input, ABS_Y, cytp->tp_res_y); @@ -473,6 +475,22 @@ ((packet[5] & 0x0f) << 8) | packet[7]; if (cytp->mode & CYTP_BIT_ABS_PRESSURE) report_data->contacts[1].z = report_data->contacts[0].z; +#if ( CYPRESS_SIMULATED_MT == 1 ) + /* simulate contact positions for >2 fingers */ + if ( report_data->contact_cnt >= 3 ) { + int i; + for ( i=1; icontact_cnt; i++ ) { + report_data->contacts[i].x = + report_data->contacts[0].x + + 100*(i)*((i%2)?-1:1); + report_data->contacts[i].y = + report_data->contacts[0].y; + if (cytp->mode & CYTP_BIT_ABS_PRESSURE) + report_data->contacts[i].z = + report_data->contacts[0].z; + } + } +#endif } report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0; --- linux-oracle-5.4.0.orig/drivers/input/mouse/cypress_ps2.h +++ linux-oracle-5.4.0/drivers/input/mouse/cypress_ps2.h @@ -131,7 +131,18 @@ #define RESP_REMOTE_BIT 0x40 #define RESP_SMBUS_BIT 0x80 -#define CYTP_MAX_MT_SLOTS 2 +/* + * CYPRESS_SIMULATED_MT + * set to 1 for simulated multitouch (up to 5 contact points) + * set to 0 for SEMI_MT (only 2 corner points, and count of fingers) + */ +#define CYPRESS_SIMULATED_MT 1 + +#if ( CYPRESS_SIMULATED_MT == 1 ) +# define CYTP_MAX_MT_SLOTS 5 +#else +# define CYTP_MAX_MT_SLOTS 2 +#endif struct cytp_contact { int x; --- linux-oracle-5.4.0.orig/drivers/input/mouse/elan_i2c.h +++ linux-oracle-5.4.0/drivers/input/mouse/elan_i2c.h @@ -26,6 +26,24 @@ #define ETP_CALIBRATE_MAX_LEN 3 +#define ETP_FEATURE_REPORT_MK BIT(0) + +#define ETP_REPORT_ID 0x5D +#define ETP_TP_REPORT_ID 0x5E +#define ETP_TP_REPORT_ID2 0x5F +#define ETP_REPORT_ID2 0x60 /* High precision report */ + +#define ETP_REPORT_ID_OFFSET 2 +#define ETP_TOUCH_INFO_OFFSET 3 +#define ETP_FINGER_DATA_OFFSET 4 +#define ETP_HOVER_INFO_OFFSET 30 +#define ETP_MK_DATA_OFFSET 33 /* For high precision reports */ + +#define ETP_MAX_REPORT_LEN 39 + +#define ETP_MAX_FINGERS 5 +#define ETP_FINGER_DATA_LEN 5 + /* IAP Firmware handling */ #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" @@ -78,7 +96,11 @@ int (*finish_fw_update)(struct i2c_client *client, struct completion *reset_done); - int (*get_report)(struct i2c_client *client, u8 *report); + int (*get_report_features)(struct i2c_client *client, u8 pattern, + unsigned int *features, + unsigned int *report_len); + int (*get_report)(struct i2c_client *client, u8 *report, + unsigned int report_len); int (*get_pressure_adjustment)(struct i2c_client *client, int *adjustment); int (*get_pattern)(struct i2c_client *client, u8 *pattern); --- linux-oracle-5.4.0.orig/drivers/input/mouse/elan_i2c_core.c +++ linux-oracle-5.4.0/drivers/input/mouse/elan_i2c_core.c @@ -47,16 +47,6 @@ #define ETP_FINGER_WIDTH 15 #define ETP_RETRY_COUNT 3 -#define ETP_MAX_FINGERS 5 -#define ETP_FINGER_DATA_LEN 5 -#define ETP_REPORT_ID 0x5D -#define ETP_TP_REPORT_ID 0x5E -#define ETP_REPORT_ID_OFFSET 2 -#define ETP_TOUCH_INFO_OFFSET 3 -#define ETP_FINGER_DATA_OFFSET 4 -#define ETP_HOVER_INFO_OFFSET 30 -#define ETP_MAX_REPORT_LEN 34 - /* The main device structure */ struct elan_tp_data { struct i2c_client *client; @@ -85,6 +75,8 @@ u8 sm_version; u8 iap_version; u16 fw_checksum; + unsigned int report_features; + unsigned int report_len; int pressure_adjustment; u8 mode; u16 ic_type; @@ -139,55 +131,21 @@ return 0; } -static int elan_enable_power(struct elan_tp_data *data) +static int elan_set_power(struct elan_tp_data *data, bool on) { int repeat = ETP_RETRY_COUNT; int error; - error = regulator_enable(data->vcc); - if (error) { - dev_err(&data->client->dev, - "failed to enable regulator: %d\n", error); - return error; - } - do { - error = data->ops->power_control(data->client, true); + error = data->ops->power_control(data->client, on); if (error >= 0) return 0; msleep(30); } while (--repeat > 0); - dev_err(&data->client->dev, "failed to enable power: %d\n", error); - return error; -} - -static int elan_disable_power(struct elan_tp_data *data) -{ - int repeat = ETP_RETRY_COUNT; - int error; - - do { - error = data->ops->power_control(data->client, false); - if (!error) { - error = regulator_disable(data->vcc); - if (error) { - dev_err(&data->client->dev, - "failed to disable regulator: %d\n", - error); - /* Attempt to power the chip back up */ - data->ops->power_control(data->client, true); - break; - } - - return 0; - } - - msleep(30); - } while (--repeat > 0); - - dev_err(&data->client->dev, "failed to disable power: %d\n", error); + dev_err(&data->client->dev, "failed to set power %s: %d\n", + on ? "on" : "off", error); return error; } @@ -341,6 +299,12 @@ else ic_type = data->iap_version; + error = data->ops->get_report_features(data->client, data->pattern, + &data->report_features, + &data->report_len); + if (error) + return error; + error = elan_get_fwinfo(ic_type, &data->fw_validpage_count, &data->fw_signature_address); if (error) @@ -351,16 +315,21 @@ return 0; } -static unsigned int elan_convert_resolution(u8 val) +static unsigned int elan_convert_resolution(u8 val, u8 pattern) { /* - * (value from firmware) * 10 + 790 = dpi - * + * pattern <= 0x01: + * (value from firmware) * 10 + 790 = dpi + * else + * ((value from firmware) + 3) * 100 = dpi + */ + int res = pattern <= 0x01 ? + (int)(char)val * 10 + 790 : ((int)(char)val + 3) * 100; + /* * We also have to convert dpi to dots/mm (*10/254 to avoid floating * point). */ - - return ((int)(char)val * 10 + 790) * 10 / 254; + return res * 10 / 254; } static int elan_query_device_parameters(struct elan_tp_data *data) @@ -409,8 +378,8 @@ if (error) return error; - data->x_res = elan_convert_resolution(hw_x_res); - data->y_res = elan_convert_resolution(hw_y_res); + data->x_res = elan_convert_resolution(hw_x_res, data->pattern); + data->y_res = elan_convert_resolution(hw_y_res, data->pattern); } else { data->x_res = (data->max_x + 1) / x_mm; data->y_res = (data->max_y + 1) / y_mm; @@ -886,24 +855,22 @@ * Elan isr functions ****************************************************************** */ -static void elan_report_contact(struct elan_tp_data *data, - int contact_num, bool contact_valid, - u8 *finger_data) +static void elan_report_contact(struct elan_tp_data *data, int contact_num, + bool contact_valid, bool high_precision, + u8 *packet, u8 *finger_data) { struct input_dev *input = data->input; unsigned int pos_x, pos_y; - unsigned int pressure, mk_x, mk_y; - unsigned int area_x, area_y, major, minor; - unsigned int scaled_pressure; + unsigned int pressure, scaled_pressure; if (contact_valid) { - pos_x = ((finger_data[0] & 0xf0) << 4) | - finger_data[1]; - pos_y = ((finger_data[0] & 0x0f) << 8) | - finger_data[2]; - mk_x = (finger_data[3] & 0x0f); - mk_y = (finger_data[3] >> 4); - pressure = finger_data[4]; + if (high_precision) { + pos_x = get_unaligned_be16(&finger_data[0]); + pos_y = get_unaligned_be16(&finger_data[2]); + } else { + pos_x = ((finger_data[0] & 0xf0) << 4) | finger_data[1]; + pos_y = ((finger_data[0] & 0x0f) << 8) | finger_data[2]; + } if (pos_x > data->max_x || pos_y > data->max_y) { dev_dbg(input->dev.parent, @@ -913,18 +880,8 @@ return; } - /* - * To avoid treating large finger as palm, let's reduce the - * width x and y per trace. - */ - area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); - area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); - - major = max(area_x, area_y); - minor = min(area_x, area_y); - + pressure = finger_data[4]; scaled_pressure = pressure + data->pressure_adjustment; - if (scaled_pressure > ETP_MAX_PRESSURE) scaled_pressure = ETP_MAX_PRESSURE; @@ -933,16 +890,37 @@ input_report_abs(input, ABS_MT_POSITION_X, pos_x); input_report_abs(input, ABS_MT_POSITION_Y, data->max_y - pos_y); input_report_abs(input, ABS_MT_PRESSURE, scaled_pressure); - input_report_abs(input, ABS_TOOL_WIDTH, mk_x); - input_report_abs(input, ABS_MT_TOUCH_MAJOR, major); - input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); + + if (data->report_features & ETP_FEATURE_REPORT_MK) { + unsigned int mk_x, mk_y, area_x, area_y; + u8 mk_data = high_precision ? + packet[ETP_MK_DATA_OFFSET + contact_num] : + finger_data[3]; + + mk_x = mk_data & 0x0f; + mk_y = mk_data >> 4; + + /* + * To avoid treating large finger as palm, let's reduce + * the width x and y per trace. + */ + area_x = mk_x * (data->width_x - ETP_FWIDTH_REDUCE); + area_y = mk_y * (data->width_y - ETP_FWIDTH_REDUCE); + + input_report_abs(input, ABS_TOOL_WIDTH, mk_x); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, + max(area_x, area_y)); + input_report_abs(input, ABS_MT_TOUCH_MINOR, + min(area_x, area_y)); + } } else { input_mt_slot(input, contact_num); input_mt_report_slot_state(input, MT_TOOL_FINGER, false); } } -static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) +static void elan_report_absolute(struct elan_tp_data *data, u8 *packet, + bool high_precision) { struct input_dev *input = data->input; u8 *finger_data = &packet[ETP_FINGER_DATA_OFFSET]; @@ -951,11 +929,14 @@ u8 hover_info = packet[ETP_HOVER_INFO_OFFSET]; bool contact_valid, hover_event; - hover_event = hover_info & 0x40; - for (i = 0; i < ETP_MAX_FINGERS; i++) { - contact_valid = tp_info & (1U << (3 + i)); - elan_report_contact(data, i, contact_valid, finger_data); + pm_wakeup_event(&data->client->dev, 0); + hover_event = hover_info & BIT(6); + + for (i = 0; i < ETP_MAX_FINGERS; i++) { + contact_valid = tp_info & BIT(3 + i); + elan_report_contact(data, i, contact_valid, high_precision, + packet, finger_data); if (contact_valid) finger_data += ETP_FINGER_DATA_LEN; } @@ -974,6 +955,8 @@ u8 *packet = &report[ETP_REPORT_ID_OFFSET + 1]; int x, y; + pm_wakeup_event(&data->client->dev, 0); + if (!data->tp_input) { dev_warn_once(&data->client->dev, "received a trackpoint report while no trackpoint device has been created. Please report upstream.\n"); @@ -998,7 +981,6 @@ static irqreturn_t elan_isr(int irq, void *dev_id) { struct elan_tp_data *data = dev_id; - struct device *dev = &data->client->dev; int error; u8 report[ETP_MAX_REPORT_LEN]; @@ -1012,21 +994,23 @@ goto out; } - error = data->ops->get_report(data->client, report); + error = data->ops->get_report(data->client, report, data->report_len); if (error) goto out; - pm_wakeup_event(dev, 0); - switch (report[ETP_REPORT_ID_OFFSET]) { case ETP_REPORT_ID: - elan_report_absolute(data, report); + elan_report_absolute(data, report, false); + break; + case ETP_REPORT_ID2: + elan_report_absolute(data, report, true); break; case ETP_TP_REPORT_ID: + case ETP_TP_REPORT_ID2: elan_report_trackpoint(data, report); break; default: - dev_err(dev, "invalid report id data (%x)\n", + dev_err(&data->client->dev, "invalid report id data (%x)\n", report[ETP_REPORT_ID_OFFSET]); } @@ -1111,7 +1095,9 @@ input_abs_set_res(input, ABS_X, data->x_res); input_abs_set_res(input, ABS_Y, data->y_res); input_set_abs_params(input, ABS_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); - input_set_abs_params(input, ABS_TOOL_WIDTH, 0, ETP_FINGER_WIDTH, 0, 0); + if (data->report_features & ETP_FEATURE_REPORT_MK) + input_set_abs_params(input, ABS_TOOL_WIDTH, + 0, ETP_FINGER_WIDTH, 0, 0); input_set_abs_params(input, ABS_DISTANCE, 0, 1, 0, 0); /* And MT parameters */ @@ -1121,10 +1107,12 @@ input_abs_set_res(input, ABS_MT_POSITION_Y, data->y_res); input_set_abs_params(input, ABS_MT_PRESSURE, 0, ETP_MAX_PRESSURE, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, - ETP_FINGER_WIDTH * max_width, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, - ETP_FINGER_WIDTH * min_width, 0, 0); + if (data->report_features & ETP_FEATURE_REPORT_MK) { + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, + 0, ETP_FINGER_WIDTH * max_width, 0, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, + 0, ETP_FINGER_WIDTH * min_width, 0, 0); + } data->input = input; @@ -1315,9 +1303,21 @@ /* Enable wake from IRQ */ data->irq_wake = (enable_irq_wake(client->irq) == 0); } else { - ret = elan_disable_power(data); + ret = elan_set_power(data, false); + if (ret) + goto err; + + ret = regulator_disable(data->vcc); + if (ret) { + dev_err(dev, "error %d disabling regulator\n", ret); + /* Attempt to power the chip back up */ + elan_set_power(data, true); + } } +err: + if (ret) + enable_irq(client->irq); mutex_unlock(&data->sysfs_mutex); return ret; } @@ -1328,12 +1328,18 @@ struct elan_tp_data *data = i2c_get_clientdata(client); int error; - if (device_may_wakeup(dev) && data->irq_wake) { + if (!device_may_wakeup(dev)) { + error = regulator_enable(data->vcc); + if (error) { + dev_err(dev, "error %d enabling regulator\n", error); + goto err; + } + } else if (data->irq_wake) { disable_irq_wake(client->irq); data->irq_wake = false; } - error = elan_enable_power(data); + error = elan_set_power(data, true); if (error) { dev_err(dev, "power up when resuming failed: %d\n", error); goto err; --- linux-oracle-5.4.0.orig/drivers/input/mouse/elan_i2c_i2c.c +++ linux-oracle-5.4.0/drivers/input/mouse/elan_i2c_i2c.c @@ -55,6 +55,8 @@ #define ETP_I2C_MIN_BASELINE_CMD 0x0318 #define ETP_I2C_REPORT_LEN 34 +#define ETP_I2C_REPORT_LEN_ID2 39 +#define ETP_I2C_REPORT_MAX_LEN 39 #define ETP_I2C_DESC_LENGTH 30 #define ETP_I2C_REPORT_DESC_LENGTH 158 #define ETP_I2C_INF_LENGTH 2 @@ -386,7 +388,7 @@ return error; } - *max_x = le16_to_cpup((__le16 *)val) & 0x0fff; + *max_x = le16_to_cpup((__le16 *)val); error = elan_i2c_read_cmd(client, ETP_I2C_MAX_Y_AXIS_CMD, val); if (error) { @@ -394,7 +396,7 @@ return error; } - *max_y = le16_to_cpup((__le16 *)val) & 0x0fff; + *max_y = le16_to_cpup((__le16 *)val); return 0; } @@ -617,12 +619,12 @@ struct completion *completion) { struct device *dev = &client->dev; - int error; + int error = 0; int len; - u8 buffer[ETP_I2C_REPORT_LEN]; + u8 buffer[ETP_I2C_REPORT_MAX_LEN]; - len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_LEN); - if (len != ETP_I2C_REPORT_LEN) { + len = i2c_master_recv(client, buffer, ETP_I2C_REPORT_MAX_LEN); + if (len <= 0) { error = len < 0 ? len : -EIO; dev_warn(dev, "failed to read I2C data after FW WDT reset: %d (%d)\n", error, len); @@ -656,20 +658,31 @@ return 0; } -static int elan_i2c_get_report(struct i2c_client *client, u8 *report) +static int elan_i2c_get_report_features(struct i2c_client *client, u8 pattern, + unsigned int *features, + unsigned int *report_len) +{ + *features = ETP_FEATURE_REPORT_MK; + *report_len = pattern <= 0x01 ? + ETP_I2C_REPORT_LEN : ETP_I2C_REPORT_LEN_ID2; + return 0; +} + +static int elan_i2c_get_report(struct i2c_client *client, + u8 *report, unsigned int report_len) { int len; - len = i2c_master_recv(client, report, ETP_I2C_REPORT_LEN); + len = i2c_master_recv(client, report, report_len); if (len < 0) { dev_err(&client->dev, "failed to read report data: %d\n", len); return len; } - if (len != ETP_I2C_REPORT_LEN) { + if (len != report_len) { dev_err(&client->dev, "wrong report length (%d vs %d expected)\n", - len, ETP_I2C_REPORT_LEN); + len, report_len); return -EIO; } @@ -706,5 +719,6 @@ .get_pattern = elan_i2c_get_pattern, + .get_report_features = elan_i2c_get_report_features, .get_report = elan_i2c_get_report, }; --- linux-oracle-5.4.0.orig/drivers/input/mouse/elan_i2c_smbus.c +++ linux-oracle-5.4.0/drivers/input/mouse/elan_i2c_smbus.c @@ -45,6 +45,7 @@ #define ETP_SMBUS_CALIBRATE_QUERY 0xC5 #define ETP_SMBUS_REPORT_LEN 32 +#define ETP_SMBUS_REPORT_LEN2 7 #define ETP_SMBUS_REPORT_OFFSET 2 #define ETP_SMBUS_HELLOPACKET_LEN 5 #define ETP_SMBUS_IAP_PASSWORD 0x1234 @@ -469,7 +470,21 @@ return 0; } -static int elan_smbus_get_report(struct i2c_client *client, u8 *report) +static int elan_smbus_get_report_features(struct i2c_client *client, u8 pattern, + unsigned int *features, + unsigned int *report_len) +{ + /* + * SMBus controllers with pattern 2 lack area info, as newer + * high-precision packets use that space for coordinates. + */ + *features = pattern <= 0x01 ? ETP_FEATURE_REPORT_MK : 0; + *report_len = ETP_SMBUS_REPORT_LEN; + return 0; +} + +static int elan_smbus_get_report(struct i2c_client *client, + u8 *report, unsigned int report_len) { int len; @@ -483,10 +498,13 @@ return len; } - if (len != ETP_SMBUS_REPORT_LEN) { + if (report[ETP_REPORT_ID_OFFSET] == ETP_TP_REPORT_ID2) + report_len = ETP_SMBUS_REPORT_LEN2; + + if (len != report_len) { dev_err(&client->dev, "wrong report length (%d vs %d expected)\n", - len, ETP_SMBUS_REPORT_LEN); + len, report_len); return -EIO; } @@ -534,6 +552,7 @@ .write_fw_block = elan_smbus_write_fw_block, .finish_fw_update = elan_smbus_finish_fw_update, + .get_report_features = elan_smbus_get_report_features, .get_report = elan_smbus_get_report, .get_pattern = elan_smbus_get_pattern, }; --- linux-oracle-5.4.0.orig/drivers/input/mouse/elantech.c +++ linux-oracle-5.4.0/drivers/input/mouse/elantech.c @@ -90,6 +90,47 @@ } /* + * Send an Elantech style special command to read 3 bytes from a register + */ +static int elantech_read_reg_params(struct psmouse *psmouse, u8 reg, u8 *param) +{ + if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || + elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, reg) || + elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) { + psmouse_err(psmouse, + "failed to read register %#02x\n", reg); + return -EIO; + } + + return 0; +} + +/* + * Send an Elantech style special command to write a register with a parameter + */ +static int elantech_write_reg_params(struct psmouse *psmouse, u8 reg, u8 *param) +{ + if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || + elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, reg) || + elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, param[0]) || + elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || + elantech_ps2_command(psmouse, NULL, param[1]) || + elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { + psmouse_err(psmouse, + "failed to write register %#02x with value %#02x%#02x\n", + reg, param[0], param[1]); + return -EIO; + } + + return 0; +} + +/* * Send an Elantech style special command to read a value from a register */ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, @@ -476,6 +517,19 @@ case 0x16008020U: case 0x26800010U: case 0x36808000U: + + /* + * This firmware misreport coordinates for trackpoint + * occasionally. Discard packets outside of [-127, 127] range + * to prevent cursor jumps. + */ + if (packet[4] == 0x80 || packet[5] == 0x80 || + packet[1] >> 7 == packet[4] >> 7 || + packet[2] >> 7 == packet[5] >> 7) { + elantech_debug("discarding packet [%6ph]\n", packet); + break; + + } x = packet[4] - (int)((packet[1]^0x80) << 1); y = (int)((packet[2]^0x80) << 1) - packet[5]; @@ -620,10 +674,11 @@ struct input_dev *dev = psmouse->dev; struct elantech_data *etd = psmouse->private; unsigned char *packet = psmouse->packet; - int id = ((packet[3] & 0xe0) >> 5) - 1; + int id; int pres, traces; - if (id < 0) + id = ((packet[3] & 0xe0) >> 5) - 1; + if (id < 0 || id >= ETP_MAX_FINGERS) return; etd->mt[id].x = ((packet[1] & 0x0f) << 8) | packet[2]; @@ -653,7 +708,7 @@ int id, sid; id = ((packet[0] & 0xe0) >> 5) - 1; - if (id < 0) + if (id < 0 || id >= ETP_MAX_FINGERS) return; sid = ((packet[3] & 0xe0) >> 5) - 1; @@ -674,7 +729,7 @@ input_report_abs(dev, ABS_MT_POSITION_X, etd->mt[id].x); input_report_abs(dev, ABS_MT_POSITION_Y, etd->mt[id].y); - if (sid >= 0) { + if (sid >= 0 && sid < ETP_MAX_FINGERS) { etd->mt[sid].x += delta_x2 * weight; etd->mt[sid].y -= delta_y2 * weight; input_mt_slot(dev, sid); @@ -1422,15 +1477,46 @@ } /* + * Some hw_version 4 models fail to properly activate absolute mode on + * resume without going through disable/enable cycle. + */ +static const struct dmi_system_id elantech_needs_reenable[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + /* Lenovo N24 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "81AF"), + }, + }, +#endif + { } +}; + +/* * Put the touchpad back into absolute mode when reconnecting */ static int elantech_reconnect(struct psmouse *psmouse) { + int err; + psmouse_reset(psmouse); if (elantech_detect(psmouse, 0)) return -1; + if (dmi_check_system(elantech_needs_reenable)) { + err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE); + if (err) + psmouse_warn(psmouse, "failed to deactivate mouse on %s: %d\n", + psmouse->ps2dev.serio->phys, err); + + err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); + if (err) + psmouse_warn(psmouse, "failed to reactivate mouse on %s: %d\n", + psmouse->ps2dev.serio->phys, err); + } + if (elantech_set_absolute_mode(psmouse)) { psmouse_err(psmouse, "failed to put touchpad back into absolute mode.\n"); @@ -1530,18 +1616,40 @@ }; /* + * Change Report id 0x5E to 0x5F. + */ +static int elantech_change_report_id(struct psmouse *psmouse) +{ + /* + * NOTE: the code is expecting to receive param[] as an array of 3 + * items (see __ps2_command()), even if in this case only 2 are + * actually needed. Make sure the array size is 3 to avoid potential + * stack out-of-bound accesses. + */ + unsigned char param[3] = { 0x10, 0x03 }; + + if (elantech_write_reg_params(psmouse, 0x7, param) || + elantech_read_reg_params(psmouse, 0x7, param) || + param[0] != 0x10 || param[1] != 0x03) { + psmouse_err(psmouse, "Unable to change report ID to 0x5f.\n"); + return -EIO; + } + + return 0; +} +/* * determine hardware version and set some properties according to it. */ static int elantech_set_properties(struct elantech_device_info *info) { /* This represents the version of IC body. */ - int ver = (info->fw_version & 0x0f0000) >> 16; + info->ic_version = (info->fw_version & 0x0f0000) >> 16; /* Early version of Elan touchpads doesn't obey the rule. */ if (info->fw_version < 0x020030 || info->fw_version == 0x020600) info->hw_version = 1; else { - switch (ver) { + switch (info->ic_version) { case 2: case 4: info->hw_version = 2; @@ -1557,6 +1665,11 @@ } } + /* Get information pattern for hw_version 4 */ + info->pattern = 0x00; + if (info->ic_version == 0x0f && (info->fw_version & 0xff) <= 0x02) + info->pattern = info->fw_version & 0xff; + /* decide which send_cmd we're gonna use early */ info->send_cmd = info->hw_version >= 3 ? elantech_send_cmd : synaptics_send_cmd; @@ -1598,6 +1711,7 @@ { unsigned char param[3]; unsigned char traces; + unsigned char ic_body[3]; memset(info, 0, sizeof(*info)); @@ -1640,6 +1754,21 @@ info->samples[2]); } + if (info->pattern > 0x00 && info->ic_version == 0xf) { + if (info->send_cmd(psmouse, ETP_ICBODY_QUERY, ic_body)) { + psmouse_err(psmouse, "failed to query ic body\n"); + return -EINVAL; + } + info->ic_version = be16_to_cpup((__be16 *)ic_body); + psmouse_info(psmouse, + "Elan ic body: %#04x, current fw version: %#02x\n", + info->ic_version, ic_body[2]); + } + + info->product_id = be16_to_cpup((__be16 *)info->samples); + if (info->pattern == 0x00) + info->product_id &= 0xff; + if (info->samples[1] == 0x74 && info->hw_version == 0x03) { /* * This module has a bug which makes absolute mode @@ -1654,6 +1783,23 @@ /* The MSB indicates the presence of the trackpoint */ info->has_trackpoint = (info->capabilities[0] & 0x80) == 0x80; + if (info->has_trackpoint && info->ic_version == 0x0011 && + (info->product_id == 0x08 || info->product_id == 0x09 || + info->product_id == 0x0d || info->product_id == 0x0e)) { + /* + * This module has a bug which makes trackpoint in SMBus + * mode return invalid data unless trackpoint is switched + * from using 0x5e reports to 0x5f. If we are not able to + * make the switch, let's abort initialization so we'll be + * using standard PS/2 protocol. + */ + if (elantech_change_report_id(psmouse)) { + psmouse_info(psmouse, + "Trackpoint report is broken, forcing standard PS/2 protocol\n"); + return -ENODEV; + } + } + info->x_res = 31; info->y_res = 31; if (info->hw_version == 4) { @@ -1999,6 +2145,7 @@ psmouse->protocol_handler = elantech_process_byte; psmouse->disconnect = elantech_disconnect; psmouse->reconnect = elantech_reconnect; + psmouse->fast_reconnect = NULL; psmouse->pktsize = info->hw_version > 1 ? 6 : 4; return 0; --- linux-oracle-5.4.0.orig/drivers/input/mouse/elantech.h +++ linux-oracle-5.4.0/drivers/input/mouse/elantech.h @@ -18,6 +18,7 @@ #define ETP_CAPABILITIES_QUERY 0x02 #define ETP_SAMPLE_QUERY 0x03 #define ETP_RESOLUTION_QUERY 0x04 +#define ETP_ICBODY_QUERY 0x05 /* * Command values for register reading or writing @@ -140,7 +141,10 @@ unsigned char samples[3]; unsigned char debug; unsigned char hw_version; + unsigned char pattern; unsigned int fw_version; + unsigned int ic_version; + unsigned int product_id; unsigned int x_min; unsigned int y_min; unsigned int x_max; --- linux-oracle-5.4.0.orig/drivers/input/mouse/focaltech.c +++ linux-oracle-5.4.0/drivers/input/mouse/focaltech.c @@ -202,8 +202,8 @@ state->pressed = packet[0] >> 7; finger1 = ((packet[0] >> 4) & 0x7) - 1; if (finger1 < FOC_MAX_FINGERS) { - state->fingers[finger1].x += (char)packet[1]; - state->fingers[finger1].y += (char)packet[2]; + state->fingers[finger1].x += (s8)packet[1]; + state->fingers[finger1].y += (s8)packet[2]; } else { psmouse_err(psmouse, "First finger in rel packet invalid: %d\n", finger1); @@ -218,8 +218,8 @@ */ finger2 = ((packet[3] >> 4) & 0x7) - 1; if (finger2 < FOC_MAX_FINGERS) { - state->fingers[finger2].x += (char)packet[4]; - state->fingers[finger2].y += (char)packet[5]; + state->fingers[finger2].x += (s8)packet[4]; + state->fingers[finger2].y += (s8)packet[5]; } } --- linux-oracle-5.4.0.orig/drivers/input/mouse/psmouse-base.c +++ linux-oracle-5.4.0/drivers/input/mouse/psmouse-base.c @@ -2042,7 +2042,7 @@ { int type = *((unsigned int *)kp->arg); - return sprintf(buffer, "%s", psmouse_protocol_by_type(type)->name); + return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name); } static int __init psmouse_init(void) --- linux-oracle-5.4.0.orig/drivers/input/mouse/sentelic.c +++ linux-oracle-5.4.0/drivers/input/mouse/sentelic.c @@ -441,7 +441,7 @@ fsp_reg_write_enable(psmouse, false); - return count; + return retval; } PSMOUSE_DEFINE_WO_ATTR(setreg, S_IWUSR, NULL, fsp_attr_set_setreg); --- linux-oracle-5.4.0.orig/drivers/input/mouse/synaptics.c +++ linux-oracle-5.4.0/drivers/input/mouse/synaptics.c @@ -146,7 +146,6 @@ "LEN0042", /* Yoga */ "LEN0045", "LEN0047", - "LEN0049", "LEN2000", /* S540 */ "LEN2001", /* Edge E431 */ "LEN2002", /* Edge E531 */ @@ -166,23 +165,30 @@ /* all of the topbuttonpad_pnp_ids are valid, we just add some extras */ "LEN0048", /* X1 Carbon 3 */ "LEN0046", /* X250 */ + "LEN0049", /* Yoga 11e */ "LEN004a", /* W541 */ "LEN005b", /* P50 */ "LEN005e", /* T560 */ + "LEN006c", /* T470s */ + "LEN007a", /* T470s */ "LEN0071", /* T480 */ "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */ "LEN0073", /* X1 Carbon G5 (Elantech) */ + "LEN0091", /* X1 Carbon 6 */ "LEN0092", /* X1 Carbon 6 */ "LEN0093", /* T480 */ "LEN0096", /* X280 */ "LEN0097", /* X280 -> ALPS trackpoint */ + "LEN0099", /* X1 Extreme 1st */ "LEN009b", /* T580 */ "LEN200f", /* T450s */ + "LEN2044", /* L470 */ "LEN2054", /* E480 */ "LEN2055", /* E580 */ "SYN3052", /* HP EliteBook 840 G4 */ "SYN3221", /* HP 15-ay000 */ "SYN323d", /* HP Spectre X360 13-w013dx */ + "SYN3257", /* HP Envy 13-ad105ng */ NULL }; @@ -1611,6 +1617,7 @@ psmouse->set_rate = synaptics_set_rate; psmouse->disconnect = synaptics_disconnect; psmouse->reconnect = synaptics_reconnect; + psmouse->fast_reconnect = NULL; psmouse->cleanup = synaptics_reset; /* Synaptics can usually stay in sync without extra help */ psmouse->resync_time = 0; @@ -1740,6 +1747,7 @@ psmouse_matches_pnp_id(psmouse, topbuttonpad_pnp_ids) && !SYN_CAP_EXT_BUTTONS_STICK(info->ext_cap_10); const struct rmi_device_platform_data pdata = { + .reset_delay_ms = 30, .sensor_pdata = { .sensor_type = rmi_sensor_touchpad, .axis_align.flip_y = true, --- linux-oracle-5.4.0.orig/drivers/input/mouse/trackpoint.c +++ linux-oracle-5.4.0/drivers/input/mouse/trackpoint.c @@ -17,10 +17,12 @@ #include "trackpoint.h" static const char * const trackpoint_variants[] = { - [TP_VARIANT_IBM] = "IBM", - [TP_VARIANT_ALPS] = "ALPS", - [TP_VARIANT_ELAN] = "Elan", - [TP_VARIANT_NXP] = "NXP", + [TP_VARIANT_IBM] = "IBM", + [TP_VARIANT_ALPS] = "ALPS", + [TP_VARIANT_ELAN] = "Elan", + [TP_VARIANT_NXP] = "NXP", + [TP_VARIANT_JYT_SYNAPTICS] = "JYT_Synaptics", + [TP_VARIANT_SYNAPTICS] = "Synaptics", }; /* @@ -280,6 +282,8 @@ case TP_VARIANT_ALPS: case TP_VARIANT_ELAN: case TP_VARIANT_NXP: + case TP_VARIANT_JYT_SYNAPTICS: + case TP_VARIANT_SYNAPTICS: if (variant_id) *variant_id = param[0]; if (firmware_id) --- linux-oracle-5.4.0.orig/drivers/input/mouse/trackpoint.h +++ linux-oracle-5.4.0/drivers/input/mouse/trackpoint.h @@ -24,10 +24,12 @@ * 0x01 was the original IBM trackpoint, others implement very limited * subset of trackpoint features. */ -#define TP_VARIANT_IBM 0x01 -#define TP_VARIANT_ALPS 0x02 -#define TP_VARIANT_ELAN 0x03 -#define TP_VARIANT_NXP 0x04 +#define TP_VARIANT_IBM 0x01 +#define TP_VARIANT_ALPS 0x02 +#define TP_VARIANT_ELAN 0x03 +#define TP_VARIANT_NXP 0x04 +#define TP_VARIANT_JYT_SYNAPTICS 0x05 +#define TP_VARIANT_SYNAPTICS 0x06 /* * Commands --- linux-oracle-5.4.0.orig/drivers/input/rmi4/rmi_bus.c +++ linux-oracle-5.4.0/drivers/input/rmi4/rmi_bus.c @@ -276,11 +276,11 @@ device_del(&fn->dev); of_node_put(fn->dev.of_node); - put_device(&fn->dev); for (i = 0; i < fn->num_of_irqs; i++) irq_dispose_mapping(fn->irq[i]); + put_device(&fn->dev); } /** --- linux-oracle-5.4.0.orig/drivers/input/rmi4/rmi_driver.c +++ linux-oracle-5.4.0/drivers/input/rmi4/rmi_driver.c @@ -205,7 +205,7 @@ if (count) { kfree(attn_data.data); - attn_data.data = NULL; + drvdata->attn_data.data = NULL; } if (!kfifo_is_empty(&drvdata->attn_fifo)) @@ -978,12 +978,12 @@ rmi_disable_irq(rmi_dev, false); - irq_domain_remove(data->irqdomain); - data->irqdomain = NULL; - rmi_f34_remove_sysfs(rmi_dev); rmi_free_function_list(rmi_dev); + irq_domain_remove(data->irqdomain); + data->irqdomain = NULL; + return 0; } @@ -1196,7 +1196,11 @@ } rmi_driver_set_input_params(rmi_dev, data->input); data->input->phys = devm_kasprintf(dev, GFP_KERNEL, - "%s/input0", dev_name(dev)); + "%s/input0", dev_name(dev)); + if (!data->input->phys) { + retval = -ENOMEM; + goto err; + } } retval = rmi_init_functions(data); @@ -1210,7 +1214,8 @@ if (data->input) { rmi_driver_set_input_name(rmi_dev, data->input); if (!rmi_dev->xport->input) { - if (input_register_device(data->input)) { + retval = input_register_device(data->input); + if (retval) { dev_err(dev, "%s: Failed to register input device.\n", __func__); goto err_destroy_functions; --- linux-oracle-5.4.0.orig/drivers/input/rmi4/rmi_f34v7.c +++ linux-oracle-5.4.0/drivers/input/rmi4/rmi_f34v7.c @@ -1189,6 +1189,9 @@ { int ret; + f34->fn->rmi_dev->driver->set_irq_bits(f34->fn->rmi_dev, + f34->fn->irq_mask); + rmi_f34v7_read_queries_bl_version(f34); f34->v7.image = fw->data; --- linux-oracle-5.4.0.orig/drivers/input/rmi4/rmi_smbus.c +++ linux-oracle-5.4.0/drivers/input/rmi4/rmi_smbus.c @@ -235,12 +235,29 @@ static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb) { - int retval; + struct i2c_client *client = rmi_smb->client; + int smbus_version; + + /* + * psmouse driver resets the controller, we only need to wait + * to give the firmware chance to fully reinitialize. + */ + if (rmi_smb->xport.pdata.reset_delay_ms) + msleep(rmi_smb->xport.pdata.reset_delay_ms); /* we need to get the smbus version to activate the touchpad */ - retval = rmi_smb_get_version(rmi_smb); - if (retval < 0) - return retval; + smbus_version = rmi_smb_get_version(rmi_smb); + if (smbus_version < 0) + return smbus_version; + + rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", + smbus_version); + + if (smbus_version != 2 && smbus_version != 3) { + dev_err(&client->dev, "Unrecognized SMB version %d\n", + smbus_version); + return -ENODEV; + } return 0; } @@ -253,11 +270,10 @@ rmi_smb_clear_state(rmi_smb); /* - * we do not call the actual reset command, it has to be handled in - * PS/2 or there will be races between PS/2 and SMBus. - * PS/2 should ensure that a psmouse_reset is called before - * intializing the device and after it has been removed to be in a known - * state. + * We do not call the actual reset command, it has to be handled in + * PS/2 or there will be races between PS/2 and SMBus. PS/2 should + * ensure that a psmouse_reset is called before initializing the + * device and after it has been removed to be in a known state. */ return rmi_smb_enable_smbus_mode(rmi_smb); } @@ -273,7 +289,6 @@ { struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev); struct rmi_smb_xport *rmi_smb; - int smbus_version; int error; if (!pdata) { @@ -312,18 +327,9 @@ rmi_smb->xport.proto_name = "smb"; rmi_smb->xport.ops = &rmi_smb_ops; - smbus_version = rmi_smb_get_version(rmi_smb); - if (smbus_version < 0) - return smbus_version; - - rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d", - smbus_version); - - if (smbus_version != 2 && smbus_version != 3) { - dev_err(&client->dev, "Unrecognized SMB version %d\n", - smbus_version); - return -ENODEV; - } + error = rmi_smb_enable_smbus_mode(rmi_smb); + if (error) + return error; i2c_set_clientdata(client, rmi_smb); --- linux-oracle-5.4.0.orig/drivers/input/serio/hil_mlc.c +++ linux-oracle-5.4.0/drivers/input/serio/hil_mlc.c @@ -74,10 +74,10 @@ static LIST_HEAD(hil_mlcs); static DEFINE_RWLOCK(hil_mlcs_lock); static struct timer_list hil_mlcs_kicker; -static int hil_mlcs_probe; +static int hil_mlcs_probe, hil_mlc_stop; static void hil_mlcs_process(unsigned long unused); -static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); +static DECLARE_TASKLET_DISABLED_OLD(hil_mlcs_tasklet, hil_mlcs_process); /* #define HIL_MLC_DEBUG */ @@ -702,9 +702,13 @@ if (!mlc->ostarted) { mlc->ostarted = 1; mlc->opacket = pack; - mlc->out(mlc); + rc = mlc->out(mlc); nextidx = HILSEN_DOZE; write_unlock_irqrestore(&mlc->lock, flags); + if (rc) { + hil_mlc_stop = 1; + return 1; + } break; } mlc->ostarted = 0; @@ -715,8 +719,13 @@ case HILSE_CTS: write_lock_irqsave(&mlc->lock, flags); - nextidx = mlc->cts(mlc) ? node->bad : node->good; + rc = mlc->cts(mlc); + nextidx = rc ? node->bad : node->good; write_unlock_irqrestore(&mlc->lock, flags); + if (rc) { + hil_mlc_stop = 1; + return 1; + } break; default: @@ -780,6 +789,12 @@ static void hil_mlcs_timer(struct timer_list *unused) { + if (hil_mlc_stop) { + /* could not send packet - stop immediately. */ + pr_warn(PREFIX "HIL seems stuck - Disabling HIL MLC.\n"); + return; + } + hil_mlcs_probe = 1; tasklet_schedule(&hil_mlcs_tasklet); /* Re-insert the periodic task. */ --- linux-oracle-5.4.0.orig/drivers/input/serio/hp_sdc_mlc.c +++ linux-oracle-5.4.0/drivers/input/serio/hp_sdc_mlc.c @@ -210,7 +210,7 @@ priv->tseq[2] = 1; priv->tseq[3] = 0; priv->tseq[4] = 0; - __hp_sdc_enqueue_transaction(&priv->trans); + return __hp_sdc_enqueue_transaction(&priv->trans); busy: return 1; done: @@ -219,7 +219,7 @@ return 0; } -static void hp_sdc_mlc_out(hil_mlc *mlc) +static int hp_sdc_mlc_out(hil_mlc *mlc) { struct hp_sdc_mlc_priv_s *priv; @@ -234,7 +234,7 @@ do_data: if (priv->emtestmode) { up(&mlc->osem); - return; + return 0; } /* Shouldn't be sending commands when loop may be busy */ BUG_ON(down_trylock(&mlc->csem)); @@ -296,7 +296,7 @@ BUG_ON(down_trylock(&mlc->csem)); } enqueue: - hp_sdc_enqueue_transaction(&priv->trans); + return hp_sdc_enqueue_transaction(&priv->trans); } static int __init hp_sdc_mlc_init(void) --- linux-oracle-5.4.0.orig/drivers/input/serio/i8042-x86ia64io.h +++ linux-oracle-5.4.0/drivers/input/serio/i8042-x86ia64io.h @@ -67,25 +67,84 @@ #include -static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { +#define SERIO_QUIRK_NOKBD BIT(0) +#define SERIO_QUIRK_NOAUX BIT(1) +#define SERIO_QUIRK_NOMUX BIT(2) +#define SERIO_QUIRK_FORCEMUX BIT(3) +#define SERIO_QUIRK_UNLOCK BIT(4) +#define SERIO_QUIRK_PROBE_DEFER BIT(5) +#define SERIO_QUIRK_RESET_ALWAYS BIT(6) +#define SERIO_QUIRK_RESET_NEVER BIT(7) +#define SERIO_QUIRK_DIECT BIT(8) +#define SERIO_QUIRK_DUMBKBD BIT(9) +#define SERIO_QUIRK_NOLOOP BIT(10) +#define SERIO_QUIRK_NOTIMEOUT BIT(11) +#define SERIO_QUIRK_KBDRESET BIT(12) +#define SERIO_QUIRK_DRITEK BIT(13) +#define SERIO_QUIRK_NOPNP BIT(14) + +/* Quirk table for different mainboards. Options similar or identical to i8042 + * module parameters. + * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored. + * This allows entries to overwrite vendor wide quirks on a per device basis. + * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR + * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries. + */ +static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { { - /* - * Arima-Rioworks HDAMB - - * AUX LOOP command does not raise AUX IRQ - */ .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), - DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), - DMI_MATCH(DMI_BOARD_VERSION, "Rev E"), + DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* ASUS G1S */ .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), - DMI_MATCH(DMI_BOARD_NAME, "G1S"), - DMI_MATCH(DMI_BOARD_VERSION, "1.0"), + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + /* Asus X450LCP */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) + }, + { + /* ASUS ZenBook UX425UA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"), + }, + .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) + }, + { + /* ASUS ZenBook UM325UA */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), + }, + .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) + }, + /* + * On some Asus laptops, just running self tests cause problems. + */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ }, + .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible Notebook */ + }, + .driver_data = (void *)(SERIO_QUIRK_RESET_NEVER) }, { /* ASUS P65UP5 - AUX LOOP command does not raise AUX IRQ */ @@ -94,156 +153,338 @@ DMI_MATCH(DMI_BOARD_NAME, "P/I-P65UP5"), DMI_MATCH(DMI_BOARD_VERSION, "REV 2.X"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { + /* ASUS G1S */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_BOARD_NAME, "G1S"), + DMI_MATCH(DMI_BOARD_VERSION, "1.0"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), - DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { + /* Acer Aspire 5710 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), - DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), - DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Dell Embedded Box PC 3000 */ + /* Acer Aspire 7738 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* OQO Model 01 */ + /* Acer Aspire 5536 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "OQO"), - DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "00"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), + DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* ULI EV4873 - AUX LOOP does not work properly */ + /* + * Acer Aspire 5738z + * Touchpad stops working in mux mode when dis- + re-enabled + * with the touchpad enable/disable toggle hotkey + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ULI"), - DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), - DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5738"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Microsoft Virtual Machine */ + /* Acer Aspire One 150 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Medion MAM 2070 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), - DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), - DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A114-31"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Medion Akoya E7225 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Medion"), - DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), - DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A314-31"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Blue FB5601 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "blue"), - DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), - DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire A315-31"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Gigabyte M912 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "M912"), - DMI_MATCH(DMI_PRODUCT_VERSION, "01"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Gigabyte M1022M netbook */ .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), - DMI_MATCH(DMI_BOARD_NAME, "M1022E"), - DMI_MATCH(DMI_BOARD_VERSION, "1.02"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-332"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Gigabyte Spring Peak - defines wrong chassis type */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-432"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Gigabyte T1005 - defines wrong chassis type ("Other") */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate Spin B118-RN"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, + /* + * Some Wistron based laptops need us to explicitly enable the 'Dritek + * keyboard extension' to make their extra keys start generating scancodes. + * Originally, this was just confined to older laptops, but a few Acer laptops + * have turned up in 2007 that also need this again. + */ { - /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ + /* Acer Aspire 5100 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) }, { + /* Acer Aspire 5610 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer Aspire 5630 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) }, { + /* Acer Aspire 5650 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), - DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) }, - { } -}; - -/* - * Some Fujitsu notebooks are having trouble with touchpads if - * active multiplexing mode is activated. Luckily they don't have - * external PS/2 ports so we can safely disable it. - * ... apparently some Toshibas don't like MUX mode either and - * die horrible death on reboot. - */ -static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { { - /* Fujitsu Lifebook P7010/P7010D */ + /* Acer Aspire 5680 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) }, { - /* Fujitsu Lifebook P7010 */ + /* Acer Aspire 5720 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), - DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer Aspire 9110 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer TravelMate 660 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer TravelMate 2490 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer TravelMate 4280 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), + }, + .driver_data = (void *)(SERIO_QUIRK_DRITEK) + }, + { + /* Acer TravelMate P459-G2-M */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate P459-G2-M"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + /* Amoi M636/A737 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ByteSpeed LLC"), + DMI_MATCH(DMI_PRODUCT_NAME, "ByteSpeed Laptop C15B"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + /* Compal HEL80I */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), + DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), + DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant"), + DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + /* Advent 4211 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), + DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), + }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) + }, + { + /* Dell Embedded Box PC 3000 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Embedded Box PC 3000"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + /* Dell XPS M1530 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + /* Dell Vostro 1510 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + /* Dell Vostro V13 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) + }, + { + /* Dell Vostro 1320 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), + }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) + }, + { + /* Dell Vostro 1520 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), + }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) + }, + { + /* Dell Vostro 1720 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) + }, + { + /* Entroware Proteus */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Entroware"), + DMI_MATCH(DMI_PRODUCT_NAME, "Proteus"), + DMI_MATCH(DMI_PRODUCT_VERSION, "EL07R4"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS) + }, + /* + * Some Fujitsu notebooks are having trouble with touchpads if + * active multiplexing mode is activated. Luckily they don't have + * external PS/2 ports so we can safely disable it. + * ... apparently some Toshibas don't like MUX mode either and + * die horrible death on reboot. + */ + { + /* Fujitsu Lifebook P7010/P7010D */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu Lifebook P5020D */ @@ -251,6 +492,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu Lifebook S2000 */ @@ -258,6 +500,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu Lifebook S6230 */ @@ -265,6 +508,15 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + /* Fujitsu Lifebook T725 laptop */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) }, { /* Fujitsu Lifebook U745 */ @@ -272,6 +524,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U745"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu T70H */ @@ -279,6 +532,50 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) + }, + { + /* Fujitsu A544 laptop */ + /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) + }, + { + /* Fujitsu AH544 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) + }, + { + /* Fujitsu U574 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) + }, + { + /* Fujitsu UH554 laptop */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOTIMEOUT) + }, + { + /* Fujitsu Lifebook P7010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu-Siemens Lifebook T3010 */ @@ -286,6 +583,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu-Siemens Lifebook E4010 */ @@ -293,6 +591,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu-Siemens Amilo Pro 2010 */ @@ -300,6 +599,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { /* Fujitsu-Siemens Amilo Pro 2030 */ @@ -307,578 +607,654 @@ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* - * No data is coming from the touchscreen unless KBC - * is in legacy mode. - */ - /* Panasonic CF-29 */ + /* Fujitsu Lifebook A574/H */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), - DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "FMVA0501PZ"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* - * HP Pavilion DV4017EA - - * errors on MUX ports are reported without raising AUXDATA - * causing "spurious NAK" messages. - */ + /* Fujitsu Lifebook E5411 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED"), + DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E5411"), }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) }, { - /* - * HP Pavilion ZT1000 - - * like DV4017EA does not raise AUXERR for errors on MUX ports. - */ + /* Gigabyte M912 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), - DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "M912"), + DMI_MATCH(DMI_PRODUCT_VERSION, "01"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* - * HP Pavilion DV4270ca - - * like DV4017EA does not raise AUXERR for errors on MUX ports. - */ + /* Gigabyte Spring Peak - defines wrong chassis type */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "Spring Peak"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { + /* Gigabyte T1005 - defines wrong chassis type ("Other") */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "T1005"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { + /* Gigabyte T1005M/P - defines wrong chassis type ("Other") */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "T1005M/P"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, + /* + * Some laptops need keyboard reset before probing for the trackpad to get + * it detected, initialised & finally work. + */ { + /* Gigabyte P35 v2 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), }, + .driver_data = (void *)(SERIO_QUIRK_KBDRESET) + }, + { + /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "X3"), + }, + .driver_data = (void *)(SERIO_QUIRK_KBDRESET) }, { + /* Gigabyte P34 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), - DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P34"), }, + .driver_data = (void *)(SERIO_QUIRK_KBDRESET) }, { - /* Sharp Actius MM20 */ + /* Gigabyte P57 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), - DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "P57"), }, + .driver_data = (void *)(SERIO_QUIRK_KBDRESET) }, { - /* Sony Vaio FS-115b */ + /* Gericom Bellagio */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), + DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* - * Sony Vaio FZ-240E - - * reset and GET ID commands issued via KBD port are - * sometimes being delivered to AUX3. - */ + /* Gigabyte M1022M netbook */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), + DMI_MATCH(DMI_BOARD_NAME, "M1022E"), + DMI_MATCH(DMI_BOARD_VERSION, "1.02"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { /* - * Most (all?) VAIOs do not have external PS/2 ports nor - * they implement active multiplexing properly, and - * MUX discovery usually messes up keyboard/touchpad. + * HP Pavilion DV4017EA - + * errors on MUX ports are reported without raising AUXDATA + * causing "spurious NAK" messages. */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "VAIO"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Amoi M636/A737 */ + /* + * HP Pavilion ZT1000 - + * like DV4017EA does not raise AUXERR for errors on MUX ports. + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), + DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Lenovo 3000 n100 */ + /* + * HP Pavilion DV4270ca - + * like DV4017EA does not raise AUXERR for errors on MUX ports. + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { + /* Newer HP Pavilion dv4 models */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_NOTIMEOUT) }, { - /* Acer Aspire 5710 */ + /* IBM 2656 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), + DMI_MATCH(DMI_PRODUCT_NAME, "2656"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Acer Aspire 7738 */ + /* Avatar AVIU-145A6 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7738"), + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), + DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Gericom Bellagio */ + /* Intel MBO Desktop D845PESV */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), - DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), }, + .driver_data = (void *)(SERIO_QUIRK_NOPNP) }, { - /* IBM 2656 */ + /* + * Intel NUC D54250WYK - does not have i8042 controller but + * declares PS/2 devices in DSDT. + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), - DMI_MATCH(DMI_PRODUCT_NAME, "2656"), + DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), }, + .driver_data = (void *)(SERIO_QUIRK_NOPNP) }, { - /* Dell XPS M1530 */ + /* Lenovo 3000 n100 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Compal HEL80I */ + /* Lenovo XiaoXin Air 12 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), - DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80UN"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Dell Vostro 1510 */ + /* Lenovo LaVie Z */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Acer Aspire 5536 */ + /* Lenovo Ideapad U455 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), - DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "20046"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Dell Vostro V13 */ + /* Lenovo ThinkPad L460 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Newer HP Pavilion dv4 models */ + /* Lenovo ThinkPad Twist S230u */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "33474HU"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Asus X450LCP */ + /* LG Electronics X110 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), + DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), + DMI_MATCH(DMI_BOARD_NAME, "X110"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Avatar AVIU-145A6 */ + /* Medion Akoya Mini E1210 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel"), - DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* TUXEDO BU1406 */ + /* Medion Akoya E1222 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), - DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), + DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), + DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Lenovo LaVie Z */ + /* MSI Wind U-100 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo LaVie Z"), + DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_BOARD_NAME, "U-100"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOPNP) }, - { } -}; - -static const struct dmi_system_id i8042_dmi_forcemux_table[] __initconst = { { /* - * Sony Vaio VGN-CS series require MUX or the touch sensor - * buttons will disturb touchpad operation + * No data is coming from the touchscreen unless KBC + * is in legacy mode. */ + /* Panasonic CF-29 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), + DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), + DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, - { } -}; - -/* - * On some Asus laptops, just running self tests cause problems. - */ -static const struct dmi_system_id i8042_dmi_noselftest_table[] = { { + /* Medion Akoya E7225 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ + DMI_MATCH(DMI_SYS_VENDOR, "Medion"), + DMI_MATCH(DMI_PRODUCT_NAME, "Akoya E7225"), + DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, - { } -}; -static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = { { - /* MSI Wind U-100 */ + /* Microsoft Virtual Machine */ .matches = { - DMI_MATCH(DMI_BOARD_NAME, "U-100"), - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* LG Electronics X110 */ + /* Medion MAM 2070 */ .matches = { - DMI_MATCH(DMI_BOARD_NAME, "X110"), - DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."), + DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), + DMI_MATCH(DMI_PRODUCT_NAME, "MAM 2070"), + DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* Acer Aspire One 150 */ + /* TUXEDO BU1406 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), + DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), + DMI_MATCH(DMI_PRODUCT_NAME, "N24_25BU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Advent 4211 */ + /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "DIXONSXP"), - DMI_MATCH(DMI_PRODUCT_NAME, "Advent 4211"), + DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), + DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, { - /* Medion Akoya Mini E1210 */ + /* OQO Model 01 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), - DMI_MATCH(DMI_PRODUCT_NAME, "E1210"), + DMI_MATCH(DMI_SYS_VENDOR, "OQO"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "00"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* Medion Akoya E1222 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDION"), - DMI_MATCH(DMI_PRODUCT_NAME, "E122X"), + DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"), + DMI_MATCH(DMI_PRODUCT_NAME, "C15B"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* Mivvy M310 */ + /* Acer Aspire 5 A515 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), - DMI_MATCH(DMI_PRODUCT_NAME, "N10"), + DMI_MATCH(DMI_BOARD_VENDOR, "PK"), + DMI_MATCH(DMI_BOARD_NAME, "Grumpy_PK"), }, + .driver_data = (void *)(SERIO_QUIRK_NOPNP) }, { - /* Dell Vostro 1320 */ + /* ULI EV4873 - AUX LOOP does not work properly */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"), + DMI_MATCH(DMI_SYS_VENDOR, "ULI"), + DMI_MATCH(DMI_PRODUCT_NAME, "EV4873"), + DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* Dell Vostro 1520 */ + /* + * Arima-Rioworks HDAMB - + * AUX LOOP command does not raise AUX IRQ + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"), + DMI_MATCH(DMI_BOARD_VENDOR, "RIOWORKS"), + DMI_MATCH(DMI_BOARD_NAME, "HDAMB"), + DMI_MATCH(DMI_BOARD_VERSION, "Rev E"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, { - /* Dell Vostro 1720 */ + /* Sharp Actius MM20 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"), + DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), + DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Lenovo Ideapad U455 */ + /* + * Sony Vaio FZ-240E - + * reset and GET ID commands issued via KBD port are + * sometimes being delivered to AUX3. + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "20046"), + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Lenovo ThinkPad L460 */ + /* + * Most (all?) VAIOs do not have external PS/2 ports nor + * they implement active multiplexing properly, and + * MUX discovery usually messes up keyboard/touchpad. + */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L460"), + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "VAIO"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* Clevo P650RS, 650RP6, Sager NP8152-S, and others */ + /* Sony Vaio FS-115b */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Notebook"), - DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"), + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, - { } -}; - -#ifdef CONFIG_PNP -static const struct dmi_system_id __initconst i8042_dmi_nopnp_table[] = { { - /* Intel MBO Desktop D845PESV */ + /* + * Sony Vaio VGN-CS series require MUX or the touch sensor + * buttons will disturb touchpad operation + */ .matches = { - DMI_MATCH(DMI_BOARD_NAME, "D845PESV"), - DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-CS"), }, + .driver_data = (void *)(SERIO_QUIRK_FORCEMUX) }, { - /* - * Intel NUC D54250WYK - does not have i8042 controller but - * declares PS/2 devices in DSDT. - */ .matches = { - DMI_MATCH(DMI_BOARD_NAME, "D54250WYK"), - DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, { - /* MSI Wind U-100 */ .matches = { - DMI_MATCH(DMI_BOARD_NAME, "U-100"), - DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, - { } -}; - -static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = { { .matches = { - DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX) }, + /* + * A lot of modern Clevo barebones have touchpad and/or keyboard issues + * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, + * none of them have an external PS/2 port so this can safely be set for + * all of them. These two are based on a Clevo design, but have the + * board_name changed. + */ { .matches = { - DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ + DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "AURA1501"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { .matches = { - DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ + DMI_MATCH(DMI_BOARD_VENDOR, "TUXEDO"), + DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { + /* Mivvy M310 */ .matches = { - DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ + DMI_MATCH(DMI_SYS_VENDOR, "VIOOO"), + DMI_MATCH(DMI_PRODUCT_NAME, "N10"), }, + .driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS) }, - { } -}; -#endif - -static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { + /* + * Some laptops need keyboard reset before probing for the trackpad to get + * it detected, initialised & finally work. + */ { - /* Dell Vostro V13 */ + /* Schenker XMG C504 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), + DMI_MATCH(DMI_SYS_VENDOR, "XMG"), + DMI_MATCH(DMI_PRODUCT_NAME, "C504"), }, + .driver_data = (void *)(SERIO_QUIRK_KBDRESET) }, { - /* Newer HP Pavilion dv4 models */ + /* Blue FB5601 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), + DMI_MATCH(DMI_SYS_VENDOR, "blue"), + DMI_MATCH(DMI_PRODUCT_NAME, "FB5601"), + DMI_MATCH(DMI_PRODUCT_VERSION, "M606"), }, + .driver_data = (void *)(SERIO_QUIRK_NOLOOP) }, + /* + * A lot of modern Clevo barebones have touchpad and/or keyboard issues + * after suspend fixable with nomux + reset + noloop + nopnp. Luckily, + * none of them have an external PS/2 port so this can safely be set for + * all of them. + * Clevo barebones come with board_vendor and/or system_vendor set to + * either the very generic string "Notebook" and/or a different value + * for each individual reseller. The only somewhat universal way to + * identify them is by board_name. + */ { - /* Fujitsu A544 laptop */ - /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), + DMI_MATCH(DMI_BOARD_NAME, "LAPQC71A"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Fujitsu AH544 laptop */ - /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), + DMI_MATCH(DMI_BOARD_NAME, "LAPQC71B"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Fujitsu U574 laptop */ - /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK U574"), + DMI_MATCH(DMI_BOARD_NAME, "N140CU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Fujitsu UH554 laptop */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), - DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK UH544"), + DMI_MATCH(DMI_BOARD_NAME, "N141CU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, - { } -}; - -/* - * Some Wistron based laptops need us to explicitly enable the 'Dritek - * keyboard extension' to make their extra keys start generating scancodes. - * Originally, this was just confined to older laptops, but a few Acer laptops - * have turned up in 2007 that also need this again. - */ -static const struct dmi_system_id __initconst i8042_dmi_dritek_table[] = { { - /* Acer Aspire 5100 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"), + DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Acer Aspire 5610 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"), + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + /* + * At least one modern Clevo barebone has the touchpad connected both + * via PS/2 and i2c interface. This causes a race condition between the + * psmouse and i2c-hid driver. Since the full capability of the touchpad + * is available via the i2c interface and the device has no external + * PS/2 port, it is safe to just ignore all ps2 mouses here to avoid + * this issue. The known affected device is the + * TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU which comes with one of + * the two different dmi strings below. NS50MU is not a typo! + */ { - /* Acer Aspire 5630 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5630"), + DMI_MATCH(DMI_BOARD_NAME, "NS50MU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | + SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | + SERIO_QUIRK_NOPNP) }, { - /* Acer Aspire 5650 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5650"), + DMI_MATCH(DMI_BOARD_NAME, "NS50_70MU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX | SERIO_QUIRK_NOMUX | + SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | + SERIO_QUIRK_NOPNP) }, { - /* Acer Aspire 5680 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5680"), + DMI_MATCH(DMI_BOARD_NAME, "NS5x_7xPU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) }, { - /* Acer Aspire 5720 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"), + DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Acer Aspire 9110 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 9110"), + DMI_MATCH(DMI_BOARD_NAME, "PB50_70DFx,DDx"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, { - /* Acer TravelMate 660 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), + DMI_MATCH(DMI_BOARD_NAME, "PCX0DX"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */ { - /* Acer TravelMate 2490 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), + DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"), }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) }, { - /* Acer TravelMate 4280 */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), + DMI_MATCH(DMI_BOARD_NAME, "X170SM"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, - { } -}; - -/* - * Some laptops need keyboard reset before probing for the trackpad to get - * it detected, initialised & finally work. - */ -static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { { - /* Gigabyte P35 v2 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "P35V2"), + DMI_MATCH(DMI_BOARD_NAME, "X170KM-G"), }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, - { - /* Aorus branded Gigabyte X3 Plus - Elantech touchpad */ + { } +}; + +#ifdef CONFIG_PNP +static const struct dmi_system_id i8042_dmi_laptop_table[] __initconst = { + { .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "X3"), + DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ }, }, { - /* Gigabyte P34 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "P34"), + DMI_MATCH(DMI_CHASSIS_TYPE, "9"), /* Laptop */ }, }, { - /* Gigabyte P57 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), - DMI_MATCH(DMI_PRODUCT_NAME, "P57"), + DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */ }, }, { - /* Schenker XMG C504 - Elantech touchpad */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "XMG"), - DMI_MATCH(DMI_PRODUCT_NAME, "C504"), + DMI_MATCH(DMI_CHASSIS_TYPE, "14"), /* Sub-Notebook */ }, }, { } }; +#endif #endif /* CONFIG_X86 */ @@ -1033,11 +1409,6 @@ bool pnp_data_busted = false; int err; -#ifdef CONFIG_X86 - if (dmi_check_system(i8042_dmi_nopnp_table)) - i8042_nopnp = true; -#endif - if (i8042_nopnp) { pr_info("PNP detection disabled\n"); return 0; @@ -1141,6 +1512,59 @@ static inline void i8042_pnp_exit(void) { } #endif /* CONFIG_PNP */ + +#ifdef CONFIG_X86 +static void __init i8042_check_quirks(void) +{ + const struct dmi_system_id *device_quirk_info; + uintptr_t quirks; + + device_quirk_info = dmi_first_match(i8042_dmi_quirk_table); + if (!device_quirk_info) + return; + + quirks = (uintptr_t)device_quirk_info->driver_data; + + if (quirks & SERIO_QUIRK_NOKBD) + i8042_nokbd = true; + if (quirks & SERIO_QUIRK_NOAUX) + i8042_noaux = true; + if (quirks & SERIO_QUIRK_NOMUX) + i8042_nomux = true; + if (quirks & SERIO_QUIRK_FORCEMUX) + i8042_nomux = false; + if (quirks & SERIO_QUIRK_UNLOCK) + i8042_unlock = true; + if (quirks & SERIO_QUIRK_PROBE_DEFER) + i8042_probe_defer = true; + /* Honor module parameter when value is not default */ + if (i8042_reset == I8042_RESET_DEFAULT) { + if (quirks & SERIO_QUIRK_RESET_ALWAYS) + i8042_reset = I8042_RESET_ALWAYS; + if (quirks & SERIO_QUIRK_RESET_NEVER) + i8042_reset = I8042_RESET_NEVER; + } + if (quirks & SERIO_QUIRK_DIECT) + i8042_direct = true; + if (quirks & SERIO_QUIRK_DUMBKBD) + i8042_dumbkbd = true; + if (quirks & SERIO_QUIRK_NOLOOP) + i8042_noloop = true; + if (quirks & SERIO_QUIRK_NOTIMEOUT) + i8042_notimeout = true; + if (quirks & SERIO_QUIRK_KBDRESET) + i8042_kbdreset = true; + if (quirks & SERIO_QUIRK_DRITEK) + i8042_dritek = true; +#ifdef CONFIG_PNP + if (quirks & SERIO_QUIRK_NOPNP) + i8042_nopnp = true; +#endif +} +#else +static inline void i8042_check_quirks(void) {} +#endif + static int __init i8042_platform_init(void) { int retval; @@ -1163,42 +1587,17 @@ i8042_kbd_irq = I8042_MAP_IRQ(1); i8042_aux_irq = I8042_MAP_IRQ(12); - retval = i8042_pnp_init(); - if (retval) - return retval; - #if defined(__ia64__) - i8042_reset = I8042_RESET_ALWAYS; + i8042_reset = I8042_RESET_ALWAYS; #endif -#ifdef CONFIG_X86 - /* Honor module parameter when value is not default */ - if (i8042_reset == I8042_RESET_DEFAULT) { - if (dmi_check_system(i8042_dmi_reset_table)) - i8042_reset = I8042_RESET_ALWAYS; - - if (dmi_check_system(i8042_dmi_noselftest_table)) - i8042_reset = I8042_RESET_NEVER; - } - - if (dmi_check_system(i8042_dmi_noloop_table)) - i8042_noloop = true; - - if (dmi_check_system(i8042_dmi_nomux_table)) - i8042_nomux = true; - - if (dmi_check_system(i8042_dmi_forcemux_table)) - i8042_nomux = false; + i8042_check_quirks(); - if (dmi_check_system(i8042_dmi_notimeout_table)) - i8042_notimeout = true; - - if (dmi_check_system(i8042_dmi_dritek_table)) - i8042_dritek = true; - - if (dmi_check_system(i8042_dmi_kbdreset_table)) - i8042_kbdreset = true; + retval = i8042_pnp_init(); + if (retval) + return retval; +#ifdef CONFIG_X86 /* * A20 was already enabled during early kernel init. But some buggy * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to --- linux-oracle-5.4.0.orig/drivers/input/serio/i8042.c +++ linux-oracle-5.4.0/drivers/input/serio/i8042.c @@ -44,6 +44,10 @@ module_param_named(unlock, i8042_unlock, bool, 0); MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); +static bool i8042_probe_defer; +module_param_named(probe_defer, i8042_probe_defer, bool, 0); +MODULE_PARM_DESC(probe_defer, "Allow deferred probing."); + enum i8042_controller_reset_mode { I8042_RESET_NEVER, I8042_RESET_ALWAYS, @@ -121,6 +125,7 @@ MODULE_PARM_DESC(unmask_kbd_data, "Unconditional enable (may reveal sensitive data) of normally sanitize-filtered kbd data traffic debug log [pre-condition: i8042.debug=1 enabled]"); #endif +static bool i8042_present; static bool i8042_bypass_aux_irq_test; static char i8042_kbd_firmware_id[128]; static char i8042_aux_firmware_id[128]; @@ -341,6 +346,9 @@ unsigned long flags; int retval; + if (!i8042_present) + return -1; + spin_lock_irqsave(&i8042_lock, flags); retval = __i8042_command(param, command); spin_unlock_irqrestore(&i8042_lock, flags); @@ -611,7 +619,7 @@ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { i8042_ctr &= ~I8042_CTR_KBDINT; i8042_ctr |= I8042_CTR_KBDDIS; - pr_err("Failed to enable KBD port\n"); + pr_info("Failed to enable KBD port\n"); return -EIO; } @@ -630,7 +638,7 @@ if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { i8042_ctr &= ~I8042_CTR_AUXINT; i8042_ctr |= I8042_CTR_AUXDIS; - pr_err("Failed to enable AUX port\n"); + pr_info("Failed to enable AUX port\n"); return -EIO; } @@ -705,7 +713,7 @@ * LCS/Telegraphics. */ -static int __init i8042_check_mux(void) +static int i8042_check_mux(void) { unsigned char mux_version; @@ -722,7 +730,7 @@ i8042_ctr &= ~I8042_CTR_AUXINT; if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { - pr_err("Failed to disable AUX port, can't use MUX\n"); + pr_info("Failed to disable AUX port, can't use MUX\n"); return -EIO; } @@ -734,10 +742,10 @@ /* * The following is used to test AUX IRQ delivery. */ -static struct completion i8042_aux_irq_delivered __initdata; -static bool i8042_irq_being_tested __initdata; +static struct completion i8042_aux_irq_delivered; +static bool i8042_irq_being_tested; -static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) +static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id) { unsigned long flags; unsigned char str, data; @@ -764,7 +772,7 @@ * verifies success by readinng CTR. Used when testing for presence of AUX * port. */ -static int __init i8042_toggle_aux(bool on) +static int i8042_toggle_aux(bool on) { unsigned char param; int i; @@ -792,7 +800,7 @@ * the presence of an AUX interface. */ -static int __init i8042_check_aux(void) +static int i8042_check_aux(void) { int retval = -1; bool irq_registered = false; @@ -937,25 +945,28 @@ { unsigned char param; int i = 0; + int ret; /* * We try this 5 times; on some really fragile systems this does not * take the first time... */ - do { - - if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { - pr_err("i8042 controller selftest timeout\n"); - return -ENODEV; - } + while (i++ < 5) { - if (param == I8042_RET_CTL_TEST) + ret = i8042_command(¶m, I8042_CMD_CTL_TEST); + if (ret) + pr_info("i8042 controller selftest timeout (%d/5)\n", i); + else if (param == I8042_RET_CTL_TEST) return 0; + else + dbg("i8042 controller selftest: %#x != %#x\n", + param, I8042_RET_CTL_TEST); - dbg("i8042 controller selftest: %#x != %#x\n", - param, I8042_RET_CTL_TEST); msleep(50); - } while (i++ < 5); + } + + if (ret) + return -ENODEV; #ifdef CONFIG_X86 /* @@ -967,7 +978,7 @@ pr_info("giving up on controller selftest, continuing anyway...\n"); return 0; #else - pr_err("i8042 controller selftest failed\n"); + pr_info("i8042 controller selftest failed\n"); return -EIO; #endif } @@ -999,7 +1010,7 @@ if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { pr_err("Can't read CTR while initializing i8042\n"); - return -EIO; + return i8042_probe_defer ? -EPROBE_DEFER : -EIO; } } while (n < 2 || ctr[0] != ctr[1]); @@ -1314,7 +1325,7 @@ i8042_controller_reset(false); } -static int __init i8042_create_kbd_port(void) +static int i8042_create_kbd_port(void) { struct serio *serio; struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; @@ -1342,7 +1353,7 @@ return 0; } -static int __init i8042_create_aux_port(int idx) +static int i8042_create_aux_port(int idx) { struct serio *serio; int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; @@ -1379,13 +1390,13 @@ return 0; } -static void __init i8042_free_kbd_port(void) +static void i8042_free_kbd_port(void) { kfree(i8042_ports[I8042_KBD_PORT_NO].serio); i8042_ports[I8042_KBD_PORT_NO].serio = NULL; } -static void __init i8042_free_aux_ports(void) +static void i8042_free_aux_ports(void) { int i; @@ -1395,7 +1406,7 @@ } } -static void __init i8042_register_ports(void) +static void i8042_register_ports(void) { int i; @@ -1436,7 +1447,7 @@ i8042_aux_irq_registered = i8042_kbd_irq_registered = false; } -static int __init i8042_setup_aux(void) +static int i8042_setup_aux(void) { int (*aux_enable)(void); int error; @@ -1464,7 +1475,8 @@ if (error) goto err_free_ports; - if (aux_enable()) + error = aux_enable(); + if (error) goto err_free_irq; i8042_aux_irq_registered = true; @@ -1477,7 +1489,7 @@ return error; } -static int __init i8042_setup_kbd(void) +static int i8042_setup_kbd(void) { int error; @@ -1527,12 +1539,10 @@ return 0; } -static int __init i8042_probe(struct platform_device *dev) +static int i8042_probe(struct platform_device *dev) { int error; - i8042_platform_device = dev; - if (i8042_reset == I8042_RESET_ALWAYS) { error = i8042_controller_selftest(); if (error) @@ -1570,7 +1580,6 @@ i8042_free_aux_ports(); /* in case KBD failed but AUX not */ i8042_free_irqs(); i8042_controller_reset(false); - i8042_platform_device = NULL; return error; } @@ -1580,7 +1589,6 @@ i8042_unregister_ports(); i8042_free_irqs(); i8042_controller_reset(false); - i8042_platform_device = NULL; return 0; } @@ -1592,6 +1600,7 @@ .pm = &i8042_pm_ops, #endif }, + .probe = i8042_probe, .remove = i8042_remove, .shutdown = i8042_shutdown, }; @@ -1602,30 +1611,44 @@ static int __init i8042_init(void) { - struct platform_device *pdev; int err; dbg_init(); err = i8042_platform_init(); if (err) - return err; + return (err == -ENODEV) ? 0 : err; err = i8042_controller_check(); if (err) goto err_platform_exit; - pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); - if (IS_ERR(pdev)) { - err = PTR_ERR(pdev); + /* Set this before creating the dev to allow i8042_command to work right away */ + i8042_present = true; + + err = platform_driver_register(&i8042_driver); + if (err) goto err_platform_exit; + + i8042_platform_device = platform_device_alloc("i8042", -1); + if (!i8042_platform_device) { + err = -ENOMEM; + goto err_unregister_driver; } + err = platform_device_add(i8042_platform_device); + if (err) + goto err_free_device; + bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block); panic_blink = i8042_panic_blink; return 0; +err_free_device: + platform_device_put(i8042_platform_device); +err_unregister_driver: + platform_driver_unregister(&i8042_driver); err_platform_exit: i8042_platform_exit(); return err; @@ -1633,6 +1656,9 @@ static void __exit i8042_exit(void) { + if (!i8042_present) + return; + platform_device_unregister(i8042_platform_device); platform_driver_unregister(&i8042_driver); i8042_platform_exit(); --- linux-oracle-5.4.0.orig/drivers/input/serio/i8042.h +++ linux-oracle-5.4.0/drivers/input/serio/i8042.h @@ -17,8 +17,6 @@ #include "i8042-ip22io.h" #elif defined(CONFIG_SNI_RM) #include "i8042-snirm.h" -#elif defined(CONFIG_PPC) -#include "i8042-ppcio.h" #elif defined(CONFIG_SPARC) #include "i8042-sparcio.h" #elif defined(CONFIG_X86) || defined(CONFIG_IA64) --- linux-oracle-5.4.0.orig/drivers/input/serio/serio_raw.c +++ linux-oracle-5.4.0/drivers/input/serio/serio_raw.c @@ -159,7 +159,7 @@ { struct serio_raw_client *client = file->private_data; struct serio_raw *serio_raw = client->serio_raw; - char uninitialized_var(c); + char c; ssize_t read = 0; int error; --- linux-oracle-5.4.0.orig/drivers/input/serio/sun4i-ps2.c +++ linux-oracle-5.4.0/drivers/input/serio/sun4i-ps2.c @@ -211,7 +211,6 @@ struct sun4i_ps2data *drvdata; struct serio *serio; struct device *dev = &pdev->dev; - unsigned int irq; int error; drvdata = kzalloc(sizeof(struct sun4i_ps2data), GFP_KERNEL); @@ -264,14 +263,12 @@ writel(0, drvdata->reg_base + PS2_REG_GCTL); /* Get IRQ for the device */ - irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(dev, "no IRQ found\n"); - error = -ENXIO; + drvdata->irq = platform_get_irq(pdev, 0); + if (drvdata->irq < 0) { + error = drvdata->irq; goto err_disable_clk; } - drvdata->irq = irq; drvdata->serio = serio; drvdata->dev = dev; --- linux-oracle-5.4.0.orig/drivers/input/tablet/aiptek.c +++ linux-oracle-5.4.0/drivers/input/tablet/aiptek.c @@ -1801,15 +1801,13 @@ input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0); input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0); - /* Verify that a device really has an endpoint */ - if (intf->altsetting[0].desc.bNumEndpoints < 1) { + err = usb_find_common_endpoints(intf->cur_altsetting, + NULL, NULL, &endpoint, NULL); + if (err) { dev_err(&intf->dev, - "interface has %d endpoints, but must have minimum 1\n", - intf->altsetting[0].desc.bNumEndpoints); - err = -EINVAL; + "interface has no int in endpoints, but must have minimum 1\n"); goto fail3; } - endpoint = &intf->altsetting[0].endpoint[0].desc; /* Go set up our URB, which is called when the tablet receives * input. --- linux-oracle-5.4.0.orig/drivers/input/tablet/gtco.c +++ linux-oracle-5.4.0/drivers/input/tablet/gtco.c @@ -875,18 +875,14 @@ } /* Sanity check that a device has an endpoint */ - if (usbinterface->altsetting[0].desc.bNumEndpoints < 1) { + if (usbinterface->cur_altsetting->desc.bNumEndpoints < 1) { dev_err(&usbinterface->dev, "Invalid number of endpoints\n"); error = -EINVAL; goto err_free_urb; } - /* - * The endpoint is always altsetting 0, we know this since we know - * this device only has one interrupt endpoint - */ - endpoint = &usbinterface->altsetting[0].endpoint[0].desc; + endpoint = &usbinterface->cur_altsetting->endpoint[0].desc; /* Some debug */ dev_dbg(&usbinterface->dev, "gtco # interfaces: %d\n", usbinterface->num_altsetting); @@ -973,7 +969,7 @@ input_dev->dev.parent = &usbinterface->dev; /* Setup the URB, it will be posted later on open of input device */ - endpoint = &usbinterface->altsetting[0].endpoint[0].desc; + endpoint = &usbinterface->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(gtco->urbinfo, udev, --- linux-oracle-5.4.0.orig/drivers/input/tablet/pegasus_notetaker.c +++ linux-oracle-5.4.0/drivers/input/tablet/pegasus_notetaker.c @@ -275,7 +275,7 @@ return -ENODEV; /* Sanity check that the device has an endpoint */ - if (intf->altsetting[0].desc.bNumEndpoints < 1) { + if (intf->cur_altsetting->desc.bNumEndpoints < 1) { dev_err(&intf->dev, "Invalid number of endpoints\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/Kconfig +++ linux-oracle-5.4.0/drivers/input/touchscreen/Kconfig @@ -96,6 +96,7 @@ config TOUCHSCREEN_ADC tristate "Generic ADC based resistive touchscreen" depends on IIO + select IIO_BUFFER select IIO_BUFFER_CB help Say Y here if you want to use the generic ADC --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/ads7846.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/ads7846.c @@ -33,6 +33,7 @@ #include #include #include +#include /* * This code has been heavily tested on a Nokia 770, and lightly @@ -199,6 +200,26 @@ #define REF_ON (READ_12BIT_DFR(x, 1, 1)) #define REF_OFF (READ_12BIT_DFR(y, 0, 0)) +static int get_pendown_state(struct ads7846 *ts) +{ + if (ts->get_pendown_state) + return ts->get_pendown_state(); + + return !gpio_get_value(ts->gpio_pendown); +} + +static void ads7846_report_pen_up(struct ads7846 *ts) +{ + struct input_dev *input = ts->input; + + input_report_key(input, BTN_TOUCH, 0); + input_report_abs(input, ABS_PRESSURE, 0); + input_sync(input); + + ts->pendown = false; + dev_vdbg(&ts->spi->dev, "UP\n"); +} + /* Must be called with ts->lock held */ static void ads7846_stop(struct ads7846 *ts) { @@ -215,6 +236,10 @@ static void ads7846_restart(struct ads7846 *ts) { if (!ts->disabled && !ts->suspended) { + /* Check if pen was released since last stop */ + if (ts->pendown && !get_pendown_state(ts)) + ads7846_report_pen_up(ts); + /* Tell IRQ thread that it may poll the device. */ ts->stopped = false; mb(); @@ -410,7 +435,7 @@ if (status == 0) { /* BE12 value, then padding */ - status = be16_to_cpu(*((u16 *)&req->sample[1])); + status = get_unaligned_be16(&req->sample[1]); status = status >> 3; status &= 0x0fff; } @@ -605,14 +630,6 @@ /*--------------------------------------------------------------------------*/ -static int get_pendown_state(struct ads7846 *ts) -{ - if (ts->get_pendown_state) - return ts->get_pendown_state(); - - return !gpio_get_value(ts->gpio_pendown); -} - static void null_wait_for_sync(void) { } @@ -773,22 +790,17 @@ if (x == MAX_12BIT) x = 0; - if (ts->model == 7843) { + if (ts->model == 7843 || ts->model == 7845) { Rt = ts->pressure_max / 2; - } else if (ts->model == 7845) { - if (get_pendown_state(ts)) - Rt = ts->pressure_max / 2; - else - Rt = 0; - dev_vdbg(&ts->spi->dev, "x/y: %d/%d, PD %d\n", x, y, Rt); } else if (likely(x && z1)) { /* compute touch pressure resistance using equation #2 */ Rt = z2; Rt -= z1; - Rt *= x; Rt *= ts->x_plate_ohms; + Rt = DIV_ROUND_CLOSEST(Rt, 16); + Rt *= x; Rt /= z1; - Rt = (Rt + 2047) >> 12; + Rt = DIV_ROUND_CLOSEST(Rt, 256); } else { Rt = 0; } @@ -867,16 +879,8 @@ msecs_to_jiffies(TS_POLL_PERIOD)); } - if (ts->pendown && !ts->stopped) { - struct input_dev *input = ts->input; - - input_report_key(input, BTN_TOUCH, 0); - input_report_abs(input, ABS_PRESSURE, 0); - input_sync(input); - - ts->pendown = false; - dev_vdbg(&ts->spi->dev, "UP\n"); - } + if (ts->pendown && !ts->stopped) + ads7846_report_pen_up(ts); return IRQ_HANDLED; } @@ -1366,8 +1370,9 @@ pdata->y_min ? : 0, pdata->y_max ? : MAX_12BIT, 0, 0); - input_set_abs_params(input_dev, ABS_PRESSURE, - pdata->pressure_min, pdata->pressure_max, 0, 0); + if (ts->model != 7845) + input_set_abs_params(input_dev, ABS_PRESSURE, + pdata->pressure_min, pdata->pressure_max, 0, 0); /* * Parse common framework properties. Must be done here to ensure the --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/atmel_mxt_ts.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1794,7 +1794,7 @@ if (error) { dev_err(&client->dev, "Error %d parsing object table\n", error); mxt_free_object_table(data); - goto err_free_mem; + return error; } data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START); @@ -3156,6 +3156,8 @@ mutex_unlock(&input_dev->mutex); + disable_irq(data->irq); + return 0; } @@ -3168,6 +3170,8 @@ if (!input_dev) return 0; + enable_irq(data->irq); + mutex_lock(&input_dev->mutex); if (input_dev->users) --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/edt-ft5x06.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/edt-ft5x06.c @@ -935,19 +935,25 @@ error = device_property_read_u32(dev, "offset", &val); if (!error) { - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset, val); + if (reg_addr->reg_offset != NO_REGISTER) + edt_ft5x06_register_write(tsdata, + reg_addr->reg_offset, val); tsdata->offset = val; } error = device_property_read_u32(dev, "offset-x", &val); if (!error) { - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_x, val); + if (reg_addr->reg_offset_x != NO_REGISTER) + edt_ft5x06_register_write(tsdata, + reg_addr->reg_offset_x, val); tsdata->offset_x = val; } error = device_property_read_u32(dev, "offset-y", &val); if (!error) { - edt_ft5x06_register_write(tsdata, reg_addr->reg_offset_y, val); + if (reg_addr->reg_offset_y != NO_REGISTER) + edt_ft5x06_register_write(tsdata, + reg_addr->reg_offset_y, val); tsdata->offset_y = val; } } @@ -1041,6 +1047,7 @@ { const struct edt_i2c_chip_data *chip_data; struct edt_ft5x06_ts_data *tsdata; + u8 buf[2] = { 0xfc, 0x00 }; struct input_dev *input; unsigned long irq_flags; int error; @@ -1110,6 +1117,12 @@ return error; } + /* + * Dummy read access. EP0700MLP1 returns bogus data on the first + * register read access and ignores writes. + */ + edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf); + edt_ft5x06_ts_set_regs(tsdata); edt_ft5x06_ts_get_defaults(&client->dev, tsdata); edt_ft5x06_ts_get_parameters(tsdata); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/elants_i2c.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/elants_i2c.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* Device, Driver information */ @@ -1077,14 +1078,12 @@ if (IS_ERR_OR_NULL(ts->reset_gpio)) return 0; - gpiod_set_value_cansleep(ts->reset_gpio, 1); - error = regulator_enable(ts->vcc33); if (error) { dev_err(&ts->client->dev, "failed to enable vcc33 regulator: %d\n", error); - goto release_reset_gpio; + return error; } error = regulator_enable(ts->vccio); @@ -1093,7 +1092,7 @@ "failed to enable vccio regulator: %d\n", error); regulator_disable(ts->vcc33); - goto release_reset_gpio; + return error; } /* @@ -1102,7 +1101,6 @@ */ udelay(ELAN_POWERON_DELAY_USEC); -release_reset_gpio: gpiod_set_value_cansleep(ts->reset_gpio, 0); if (error) return error; @@ -1127,6 +1125,40 @@ } } +#ifdef CONFIG_ACPI +static const struct acpi_device_id i2c_hid_ids[] = { + {"ACPI0C50", 0 }, + {"PNP0C50", 0 }, + { }, +}; + +static const guid_t i2c_hid_guid = + GUID_INIT(0x3CDFF6F7, 0x4267, 0x4555, + 0xAD, 0x05, 0xB3, 0x0A, 0x3D, 0x89, 0x38, 0xDE); + +static bool elants_acpi_is_hid_device(struct device *dev) +{ + acpi_handle handle = ACPI_HANDLE(dev); + union acpi_object *obj; + + if (acpi_match_device_ids(ACPI_COMPANION(dev), i2c_hid_ids)) + return false; + + obj = acpi_evaluate_dsm_typed(handle, &i2c_hid_guid, 1, 1, NULL, ACPI_TYPE_INTEGER); + if (obj) { + ACPI_FREE(obj); + return true; + } + + return false; +} +#else +static bool elants_acpi_is_hid_device(struct device *dev) +{ + return false; +} +#endif + static int elants_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1135,9 +1167,14 @@ unsigned long irqflags; int error; + /* Don't bind to i2c-hid compatible devices, these are handled by the i2c-hid drv. */ + if (elants_acpi_is_hid_device(&client->dev)) { + dev_warn(&client->dev, "This device appears to be an I2C-HID device, not binding\n"); + return -ENODEV; + } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - dev_err(&client->dev, - "%s: i2c check functionality error\n", DEVICE_NAME); + dev_err(&client->dev, "I2C check functionality error\n"); return -ENXIO; } @@ -1171,7 +1208,7 @@ return error; } - ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW); + ts->reset_gpio = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ts->reset_gpio)) { error = PTR_ERR(ts->reset_gpio); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/elo.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/elo.c @@ -341,8 +341,10 @@ switch (elo->id) { case 0: /* 10-byte protocol */ - if (elo_setup_10(elo)) + if (elo_setup_10(elo)) { + err = -EIO; goto fail3; + } break; --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/goodix.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/goodix.c @@ -129,6 +129,27 @@ static const struct dmi_system_id rotated_screen[] = { #if defined(CONFIG_DMI) && defined(CONFIG_X86) { + .ident = "Teclast X89", + .matches = { + /* tPAD is too generic, also match on bios date */ + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), + DMI_MATCH(DMI_BOARD_NAME, "tPAD"), + DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), + }, + }, + { + .ident = "Teclast X98 Pro", + .matches = { + /* + * Only match BIOS date, because the manufacturers + * BIOS does not report the board name at all + * (sometimes)... + */ + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), + DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), + }, + }, + { .ident = "WinBook TW100", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), @@ -149,16 +170,40 @@ static const struct dmi_system_id nine_bytes_report[] = { #if defined(CONFIG_DMI) && defined(CONFIG_X86) { - .ident = "Lenovo YogaBook", - /* YB1-X91L/F and YB1-X90L/F */ + /* Lenovo Yoga Book X90F / X90L */ .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9") + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), + } + }, + { + /* Lenovo Yoga Book X91F / X91L */ + .matches = { + /* Non exact match to match F + L versions */ + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"), } }, #endif {} }; +/* + * Those tablets have their x coordinate inverted + */ +static const struct dmi_system_id inverted_x_screen[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + .ident = "Cube I15-TC", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Cube"), + DMI_MATCH(DMI_PRODUCT_NAME, "I15-TC") + }, + }, +#endif + {} +}; + /** * goodix_i2c_read - read data from a register of the i2c slave device. * @@ -298,7 +343,7 @@ * The Goodix panel will send spurious interrupts after a * 'finger up' event, which will always cause a timeout. */ - return 0; + return -ENOMSG; } static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data) @@ -771,6 +816,12 @@ "Non-standard 9-bytes report format quirk\n"); } + if (dmi_check_system(inverted_x_screen)) { + ts->prop.invert_x = true; + dev_dbg(&ts->client->dev, + "Applying 'inverted x screen' quirk\n"); + } + error = input_mt_init_slots(ts->input_dev, ts->max_touch_num, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); if (error) { --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/hideep.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/hideep.c @@ -361,13 +361,16 @@ return -EIO; } -static void hideep_nvm_unlock(struct hideep_ts *ts) +static int hideep_nvm_unlock(struct hideep_ts *ts) { u32 unmask_code; + int error; hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_SFR_RPAGE); - hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code); + error = hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code); hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE); + if (error) + return error; /* make it unprotected code */ unmask_code &= ~HIDEEP_PROT_MODE; @@ -384,6 +387,8 @@ NVM_W_SFR(HIDEEP_NVM_MASK_OFS, ts->nvm_mask); SET_FLASH_HWCONTROL(); hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE); + + return 0; } static int hideep_check_status(struct hideep_ts *ts) @@ -462,7 +467,9 @@ u32 addr = 0; int error; - hideep_nvm_unlock(ts); + error = hideep_nvm_unlock(ts); + if (error) + return error; while (ucode_len > 0) { xfer_len = min_t(size_t, ucode_len, HIDEEP_NVM_PAGE_SIZE); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/ili210x.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/ili210x.c @@ -109,7 +109,7 @@ if (finger >= ILI210X_TOUCHES) return false; - if (touchdata[0] & BIT(finger)) + if (!(touchdata[0] & BIT(finger))) return false; *x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0); @@ -290,9 +290,9 @@ if (error) return error; - usleep_range(50, 100); + usleep_range(12000, 15000); gpiod_set_value_cansleep(reset_gpio, 0); - msleep(100); + msleep(160); } priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -334,7 +334,12 @@ input_set_abs_params(input, ABS_MT_POSITION_X, 0, 0xffff, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 0xffff, 0, 0); touchscreen_parse_properties(input, true, &priv->prop); - input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + + error = input_mt_init_slots(input, priv->max_touches, INPUT_MT_DIRECT); + if (error) { + dev_err(dev, "Unable to set up slots, err: %d\n", error); + return error; + } error = devm_add_action(dev, ili210x_cancel_work, priv); if (error) --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/imx6ul_tsc.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/imx6ul_tsc.c @@ -530,20 +530,25 @@ mutex_lock(&input_dev->mutex); - if (input_dev->users) { - retval = clk_prepare_enable(tsc->adc_clk); - if (retval) - goto out; + if (!input_dev->users) + goto out; - retval = clk_prepare_enable(tsc->tsc_clk); - if (retval) { - clk_disable_unprepare(tsc->adc_clk); - goto out; - } + retval = clk_prepare_enable(tsc->adc_clk); + if (retval) + goto out; - retval = imx6ul_tsc_init(tsc); + retval = clk_prepare_enable(tsc->tsc_clk); + if (retval) { + clk_disable_unprepare(tsc->adc_clk); + goto out; } + retval = imx6ul_tsc_init(tsc); + if (retval) { + clk_disable_unprepare(tsc->tsc_clk); + clk_disable_unprepare(tsc->adc_clk); + goto out; + } out: mutex_unlock(&input_dev->mutex); return retval; --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/melfas_mip4.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/melfas_mip4.c @@ -1453,7 +1453,7 @@ "ce", GPIOD_OUT_LOW); if (IS_ERR(ts->gpio_ce)) { error = PTR_ERR(ts->gpio_ce); - if (error != EPROBE_DEFER) + if (error != -EPROBE_DEFER) dev_err(&client->dev, "Failed to get gpio: %d\n", error); return error; --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/mms114.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/mms114.c @@ -54,6 +54,7 @@ enum mms_type { TYPE_MMS114 = 114, TYPE_MMS152 = 152, + TYPE_MMS345L = 345, }; struct mms114_data { @@ -91,15 +92,15 @@ if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL) BUG(); - /* Write register: use repeated start */ + /* Write register */ xfer[0].addr = client->addr; - xfer[0].flags = I2C_M_TEN | I2C_M_NOSTART; + xfer[0].flags = client->flags & I2C_M_TEN; xfer[0].len = 1; xfer[0].buf = &buf; /* Read data */ xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; + xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD; xfer[1].len = len; xfer[1].buf = val; @@ -250,6 +251,15 @@ int error; switch (data->type) { + case TYPE_MMS345L: + error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); + if (error) + return error; + + dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n", + buf[0], buf[1], buf[2]); + break; + case TYPE_MMS152: error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf); if (error) @@ -287,8 +297,8 @@ if (error < 0) return error; - /* MMS152 has no configuration or power on registers */ - if (data->type == TYPE_MMS152) + /* Only MMS114 has configuration and power on registers */ + if (data->type != TYPE_MMS114) return 0; error = mms114_set_active(data, true); @@ -428,10 +438,8 @@ const void *match_data; int error; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_PROTOCOL_MANGLING)) { - dev_err(&client->dev, - "Need i2c bus that supports protocol mangling\n"); + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "Not supported I2C adapter\n"); return -ENODEV; } @@ -600,6 +608,9 @@ }, { .compatible = "melfas,mms152", .data = (void *)TYPE_MMS152, + }, { + .compatible = "melfas,mms345l", + .data = (void *)TYPE_MMS345L, }, { } }; --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/of_touchscreen.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/of_touchscreen.c @@ -77,12 +77,12 @@ axis = multitouch ? ABS_MT_POSITION_X : ABS_X; data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-x", input_abs_get_min(input, axis), - &minimum) | - touchscreen_get_prop_u32(dev, "touchscreen-size-x", + &minimum); + data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-x", input_abs_get_max(input, axis) + 1, - &maximum) | - touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x", + &maximum); + data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-x", input_abs_get_fuzz(input, axis), &fuzz); if (data_present) @@ -91,12 +91,12 @@ axis = multitouch ? ABS_MT_POSITION_Y : ABS_Y; data_present = touchscreen_get_prop_u32(dev, "touchscreen-min-y", input_abs_get_min(input, axis), - &minimum) | - touchscreen_get_prop_u32(dev, "touchscreen-size-y", + &minimum); + data_present |= touchscreen_get_prop_u32(dev, "touchscreen-size-y", input_abs_get_max(input, axis) + 1, - &maximum) | - touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y", + &maximum); + data_present |= touchscreen_get_prop_u32(dev, "touchscreen-fuzz-y", input_abs_get_fuzz(input, axis), &fuzz); if (data_present) @@ -106,11 +106,11 @@ data_present = touchscreen_get_prop_u32(dev, "touchscreen-max-pressure", input_abs_get_max(input, axis), - &maximum) | - touchscreen_get_prop_u32(dev, - "touchscreen-fuzz-pressure", - input_abs_get_fuzz(input, axis), - &fuzz); + &maximum); + data_present |= touchscreen_get_prop_u32(dev, + "touchscreen-fuzz-pressure", + input_abs_get_fuzz(input, axis), + &fuzz); if (data_present) touchscreen_set_params(input, axis, 0, maximum, fuzz); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/raspberrypi-ts.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/raspberrypi-ts.c @@ -137,7 +137,7 @@ return -ENOENT; } - fw = rpi_firmware_get(fw_node); + fw = devm_rpi_firmware_get(&pdev->dev, fw_node); of_node_put(fw_node); if (!fw) return -EPROBE_DEFER; @@ -164,7 +164,6 @@ touchbuf = (u32)ts->fw_regs_phys; error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, &touchbuf, sizeof(touchbuf)); - if (error || touchbuf != 0) { dev_warn(dev, "Failed to set touchbuf, %d\n", error); return error; --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/raydium_i2c_ts.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/raydium_i2c_ts.c @@ -410,6 +410,7 @@ enum raydium_bl_ack state) { int error; + static const u8 cmd[] = { 0xFF, 0x39 }; error = raydium_i2c_send(client, RM_CMD_BOOT_WRT, data, len); if (error) { @@ -418,7 +419,7 @@ return error; } - error = raydium_i2c_send(client, RM_CMD_BOOT_ACK, NULL, 0); + error = raydium_i2c_send(client, RM_CMD_BOOT_ACK, cmd, sizeof(cmd)); if (error) { dev_err(&client->dev, "Ack obj command failed: %d\n", error); return error; @@ -432,7 +433,7 @@ return 0; } -static bool raydium_i2c_boot_trigger(struct i2c_client *client) +static int raydium_i2c_boot_trigger(struct i2c_client *client) { static const u8 cmd[7][6] = { { 0x08, 0x0C, 0x09, 0x00, 0x50, 0xD7 }, @@ -457,10 +458,10 @@ } } - return false; + return 0; } -static bool raydium_i2c_fw_trigger(struct i2c_client *client) +static int raydium_i2c_fw_trigger(struct i2c_client *client) { static const u8 cmd[5][11] = { { 0, 0x09, 0x71, 0x0C, 0x09, 0x00, 0x50, 0xD7, 0, 0, 0 }, @@ -483,7 +484,7 @@ } } - return false; + return 0; } static int raydium_i2c_check_path(struct i2c_client *client) --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/s6sy761.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/s6sy761.c @@ -145,8 +145,8 @@ u8 major = event[4]; u8 minor = event[5]; u8 z = event[6] & S6SY761_MASK_Z; - u16 x = (event[1] << 3) | ((event[3] & S6SY761_MASK_X) >> 4); - u16 y = (event[2] << 3) | (event[3] & S6SY761_MASK_Y); + u16 x = (event[1] << 4) | ((event[3] & S6SY761_MASK_X) >> 4); + u16 y = (event[2] << 4) | (event[3] & S6SY761_MASK_Y); input_mt_slot(sdata->input, tid); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/silead.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/silead.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -69,7 +70,6 @@ struct regulator_bulk_data regulators[2]; char fw_name[64]; struct touchscreen_properties prop; - u32 max_fingers; u32 chip_id; struct input_mt_pos pos[SILEAD_MAX_FINGERS]; int slots[SILEAD_MAX_FINGERS]; @@ -97,7 +97,7 @@ input_set_abs_params(data->input, ABS_MT_POSITION_Y, 0, 4095, 0, 0); touchscreen_parse_properties(data->input, true, &data->prop); - input_mt_init_slots(data->input, data->max_fingers, + input_mt_init_slots(data->input, SILEAD_MAX_FINGERS, INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); @@ -144,10 +144,10 @@ return; } - if (buf[0] > data->max_fingers) { + if (buf[0] > SILEAD_MAX_FINGERS) { dev_warn(dev, "More touches reported then supported %d > %d\n", - buf[0], data->max_fingers); - buf[0] = data->max_fingers; + buf[0], SILEAD_MAX_FINGERS); + buf[0] = SILEAD_MAX_FINGERS; } touch_nr = 0; @@ -199,7 +199,6 @@ static int silead_ts_init(struct i2c_client *client) { - struct silead_ts_data *data = i2c_get_clientdata(client); int error; error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET, @@ -209,7 +208,7 @@ usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR, - data->max_fingers); + SILEAD_MAX_FINGERS); if (error) goto i2c_write_err; usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX); @@ -335,10 +334,8 @@ error = i2c_smbus_read_i2c_block_data(client, SILEAD_REG_ID, sizeof(chip_id), (u8 *)&chip_id); - if (error < 0) { - dev_err(&client->dev, "Chip ID read error %d\n", error); + if (error < 0) return error; - } data->chip_id = le32_to_cpu(chip_id); dev_info(&client->dev, "Silead chip ID: 0x%8X", data->chip_id); @@ -351,12 +348,49 @@ int error; u32 status; + /* + * Some buggy BIOS-es bring up the chip in a stuck state where it + * blocks the I2C bus. The following steps are necessary to + * unstuck the chip / bus: + * 1. Turn off the Silead chip. + * 2. Try to do an I2C transfer with the chip, this will fail in + * response to which the I2C-bus-driver will call: + * i2c_recover_bus() which will unstuck the I2C-bus. Note the + * unstuck-ing of the I2C bus only works if we first drop the + * chip off the bus by turning it off. + * 3. Turn the chip back on. + * + * On the x86/ACPI systems were this problem is seen, step 1. and + * 3. require making ACPI calls and dealing with ACPI Power + * Resources. The workaround below runtime-suspends the chip to + * turn it off, leaving it up to the ACPI subsystem to deal with + * this. + */ + + if (device_property_read_bool(&client->dev, + "silead,stuck-controller-bug")) { + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_allow(&client->dev); + + pm_runtime_suspend(&client->dev); + + dev_warn(&client->dev, FW_BUG "Stuck I2C bus: please ignore the next 'controller timed out' error\n"); + silead_ts_get_id(client); + + /* The forbid will also resume the device */ + pm_runtime_forbid(&client->dev); + pm_runtime_disable(&client->dev); + } + silead_ts_set_power(client, SILEAD_POWER_OFF); silead_ts_set_power(client, SILEAD_POWER_ON); error = silead_ts_get_id(client); - if (error) + if (error) { + dev_err(&client->dev, "Chip ID read error %d\n", error); return error; + } error = silead_ts_init(client); if (error) @@ -401,13 +435,6 @@ const char *str; int error; - error = device_property_read_u32(dev, "silead,max-fingers", - &data->max_fingers); - if (error) { - dev_dbg(dev, "Max fingers read error %d\n", error); - data->max_fingers = 5; /* Most devices handle up-to 5 fingers */ - } - error = device_property_read_string(dev, "firmware-name", &str); if (!error) snprintf(data->fw_name, sizeof(data->fw_name), --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/st1232.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/st1232.c @@ -149,6 +149,11 @@ gpiod_set_value_cansleep(ts->reset_gpio, !poweron); } +static void st1232_ts_power_off(void *data) +{ + st1232_ts_power(data, false); +} + static const struct st_chip_info st1232_chip_info = { .have_z = true, .max_x = 0x31f, /* 800 - 1 */ @@ -229,6 +234,13 @@ st1232_ts_power(ts, true); + error = devm_add_action_or_reset(&client->dev, st1232_ts_power_off, ts); + if (error) { + dev_err(&client->dev, + "Failed to install power off action: %d\n", error); + return error; + } + input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = &client->dev; @@ -271,15 +283,6 @@ return 0; } -static int st1232_ts_remove(struct i2c_client *client) -{ - struct st1232_ts_data *ts = i2c_get_clientdata(client); - - st1232_ts_power(ts, false); - - return 0; -} - static int __maybe_unused st1232_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -329,7 +332,6 @@ static struct i2c_driver st1232_ts_driver = { .probe = st1232_ts_probe, - .remove = st1232_ts_remove, .id_table = st1232_ts_id, .driver = { .name = ST1232_TS_NAME, --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/stmfts.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/stmfts.c @@ -337,13 +337,15 @@ struct stmfts_data *sdata = input_get_drvdata(dev); int err; - err = pm_runtime_get_sync(&sdata->client->dev); - if (err < 0) + err = pm_runtime_resume_and_get(&sdata->client->dev); + if (err) return err; err = i2c_smbus_write_byte(sdata->client, STMFTS_MS_MT_SENSE_ON); - if (err) + if (err) { + pm_runtime_put_sync(&sdata->client->dev); return err; + } mutex_lock(&sdata->mutex); sdata->running = true; @@ -479,7 +481,7 @@ mutex_lock(&sdata->mutex); - if (value & sdata->hover_enabled) + if (value && sdata->hover_enabled) goto out; if (sdata->running) --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/sun4i-ts.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/sun4i-ts.c @@ -237,6 +237,7 @@ struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device *hwmon; + struct thermal_zone_device *thermal; int error; u32 reg; bool ts_attached; @@ -355,7 +356,10 @@ if (IS_ERR(hwmon)) return PTR_ERR(hwmon); - devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, &sun4i_ts_tz_ops); + thermal = devm_thermal_zone_of_sensor_register(ts->dev, 0, ts, + &sun4i_ts_tz_ops); + if (IS_ERR(thermal)) + return PTR_ERR(thermal); writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/sur40.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/sur40.c @@ -653,7 +653,7 @@ int error; /* Check if we really have the right interface. */ - iface_desc = &interface->altsetting[0]; + iface_desc = interface->cur_altsetting; if (iface_desc->desc.bInterfaceClass != 0xFF) return -ENODEV; @@ -774,6 +774,7 @@ dev_err(&interface->dev, "Unable to register video controls."); v4l2_ctrl_handler_free(&sur40->hdl); + error = sur40->hdl.error; goto err_unreg_v4l2; } --- linux-oracle-5.4.0.orig/drivers/input/touchscreen/usbtouchscreen.c +++ linux-oracle-5.4.0/drivers/input/touchscreen/usbtouchscreen.c @@ -182,6 +182,7 @@ #endif #ifdef CONFIG_TOUCHSCREEN_USB_IRTOUCH + {USB_DEVICE(0x255e, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x595a, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x6615, 0x0001), .driver_info = DEVTYPE_IRTOUCH}, {USB_DEVICE(0x6615, 0x0012), .driver_info = DEVTYPE_IRTOUCH_HIRES}, @@ -250,7 +251,7 @@ int ret; struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, 0x02, 0x0000, 0x0081, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -530,7 +531,7 @@ if (ret) return ret; - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_RESET, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -542,7 +543,7 @@ msleep(150); for (i = 0; i < 3; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_ASYNC_REPORT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -721,7 +722,7 @@ } /* start sending data */ - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), TSC10_CMD_DATA1, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); --- linux-oracle-5.4.0.orig/drivers/interconnect/core.c +++ linux-oracle-5.4.0/drivers/interconnect/core.c @@ -19,39 +19,13 @@ #include #include +#include "internal.h" + static DEFINE_IDR(icc_idr); static LIST_HEAD(icc_providers); static DEFINE_MUTEX(icc_lock); static struct dentry *icc_debugfs_dir; -/** - * struct icc_req - constraints that are attached to each node - * @req_node: entry in list of requests for the particular @node - * @node: the interconnect node to which this constraint applies - * @dev: reference to the device that sets the constraints - * @tag: path tag (optional) - * @avg_bw: an integer describing the average bandwidth in kBps - * @peak_bw: an integer describing the peak bandwidth in kBps - */ -struct icc_req { - struct hlist_node req_node; - struct icc_node *node; - struct device *dev; - u32 tag; - u32 avg_bw; - u32 peak_bw; -}; - -/** - * struct icc_path - interconnect path structure - * @num_nodes: number of hops (nodes) - * @reqs: array of the requests applicable to this path of nodes - */ -struct icc_path { - size_t num_nodes; - struct icc_req reqs[]; -}; - static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) { if (!n) @@ -117,6 +91,7 @@ hlist_add_head(&path->reqs[i].req_node, &node->req_list); path->reqs[i].node = node; path->reqs[i].dev = dev; + path->reqs[i].enabled = true; /* reference to previous node was saved during path traversal */ node = node->reverse; } @@ -201,6 +176,7 @@ { struct icc_provider *p = node->provider; struct icc_req *r; + u32 avg_bw, peak_bw; node->avg_bw = 0; node->peak_bw = 0; @@ -208,9 +184,17 @@ if (p->pre_aggregate) p->pre_aggregate(node); - hlist_for_each_entry(r, &node->req_list, req_node) - p->aggregate(node, r->tag, r->avg_bw, r->peak_bw, + hlist_for_each_entry(r, &node->req_list, req_node) { + if (r->enabled) { + avg_bw = r->avg_bw; + peak_bw = r->peak_bw; + } else { + avg_bw = 0; + peak_bw = 0; + } + p->aggregate(node, r->tag, avg_bw, peak_bw, &node->avg_bw, &node->peak_bw); + } return 0; } @@ -296,6 +280,9 @@ } mutex_unlock(&icc_lock); + if (!node) + return ERR_PTR(-EINVAL); + return node; } @@ -475,6 +462,39 @@ } EXPORT_SYMBOL_GPL(icc_set_bw); +static int __icc_enable(struct icc_path *path, bool enable) +{ + int i; + + if (!path) + return 0; + + if (WARN_ON(IS_ERR(path) || !path->num_nodes)) + return -EINVAL; + + mutex_lock(&icc_lock); + + for (i = 0; i < path->num_nodes; i++) + path->reqs[i].enabled = enable; + + mutex_unlock(&icc_lock); + + return icc_set_bw(path, path->reqs[0].avg_bw, + path->reqs[0].peak_bw); +} + +int icc_enable(struct icc_path *path) +{ + return __icc_enable(path, true); +} +EXPORT_SYMBOL_GPL(icc_enable); + +int icc_disable(struct icc_path *path) +{ + return __icc_enable(path, false); +} +EXPORT_SYMBOL_GPL(icc_disable); + /** * icc_get() - return a handle for path between two endpoints * @dev: the device requesting the path @@ -612,6 +632,10 @@ mutex_unlock(&icc_lock); + if (!node) + return; + + kfree(node->links); kfree(node); } EXPORT_SYMBOL_GPL(icc_node_destroy); @@ -704,6 +728,8 @@ GFP_KERNEL); if (new) src->links = new; + else + ret = -ENOMEM; out: mutex_unlock(&icc_lock); --- linux-oracle-5.4.0.orig/drivers/interconnect/internal.h +++ linux-oracle-5.4.0/drivers/interconnect/internal.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Interconnect framework internal structs + * + * Copyright (c) 2019, Linaro Ltd. + * Author: Georgi Djakov + */ + +#ifndef __DRIVERS_INTERCONNECT_INTERNAL_H +#define __DRIVERS_INTERCONNECT_INTERNAL_H + +/** + * struct icc_req - constraints that are attached to each node + * @req_node: entry in list of requests for the particular @node + * @node: the interconnect node to which this constraint applies + * @dev: reference to the device that sets the constraints + * @enabled: indicates whether the path with this request is enabled + * @tag: path tag (optional) + * @avg_bw: an integer describing the average bandwidth in kBps + * @peak_bw: an integer describing the peak bandwidth in kBps + */ +struct icc_req { + struct hlist_node req_node; + struct icc_node *node; + struct device *dev; + bool enabled; + u32 tag; + u32 avg_bw; + u32 peak_bw; +}; + +/** + * struct icc_path - interconnect path structure + * @num_nodes: number of hops (nodes) + * @reqs: array of the requests applicable to this path of nodes + */ +struct icc_path { + size_t num_nodes; + struct icc_req reqs[]; +}; + +#endif --- linux-oracle-5.4.0.orig/drivers/interconnect/qcom/qcs404.c +++ linux-oracle-5.4.0/drivers/interconnect/qcom/qcs404.c @@ -157,8 +157,8 @@ } DEFINE_QNODE(mas_apps_proc, QCS404_MASTER_AMPSS_M0, 8, 0, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); -DEFINE_QNODE(mas_oxili, QCS404_MASTER_GRAPHICS_3D, 8, 6, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); -DEFINE_QNODE(mas_mdp, QCS404_MASTER_MDP_PORT0, 8, 8, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); +DEFINE_QNODE(mas_oxili, QCS404_MASTER_GRAPHICS_3D, 8, -1, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); +DEFINE_QNODE(mas_mdp, QCS404_MASTER_MDP_PORT0, 8, -1, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); DEFINE_QNODE(mas_snoc_bimc_1, QCS404_SNOC_BIMC_1_MAS, 8, 76, -1, QCS404_SLAVE_EBI_CH0); DEFINE_QNODE(mas_tcu_0, QCS404_MASTER_TCU_0, 8, -1, -1, QCS404_SLAVE_EBI_CH0, QCS404_BIMC_SNOC_SLV); DEFINE_QNODE(mas_spdm, QCS404_MASTER_SPDM, 4, -1, -1, QCS404_PNOC_INT_3); @@ -414,7 +414,7 @@ struct icc_provider *provider; struct qcom_icc_node **qnodes; struct qcom_icc_provider *qp; - struct icc_node *node; + struct icc_node *node, *tmp; size_t num_nodes, i; int ret; @@ -494,7 +494,7 @@ return 0; err: - list_for_each_entry(node, &provider->nodes, node_list) { + list_for_each_entry_safe(node, tmp, &provider->nodes, node_list) { icc_node_del(node); icc_node_destroy(node->id); } @@ -508,9 +508,9 @@ { struct qcom_icc_provider *qp = platform_get_drvdata(pdev); struct icc_provider *provider = &qp->provider; - struct icc_node *n; + struct icc_node *n, *tmp; - list_for_each_entry(n, &provider->nodes, node_list) { + list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) { icc_node_del(n); icc_node_destroy(n->id); } --- linux-oracle-5.4.0.orig/drivers/interconnect/qcom/sdm845.c +++ linux-oracle-5.4.0/drivers/interconnect/qcom/sdm845.c @@ -868,9 +868,9 @@ { struct qcom_icc_provider *qp = platform_get_drvdata(pdev); struct icc_provider *provider = &qp->provider; - struct icc_node *n; + struct icc_node *n, *tmp; - list_for_each_entry(n, &provider->nodes, node_list) { + list_for_each_entry_safe(n, tmp, &provider->nodes, node_list) { icc_node_del(n); icc_node_destroy(n->id); } --- linux-oracle-5.4.0.orig/drivers/iommu/Kconfig +++ linux-oracle-5.4.0/drivers/iommu/Kconfig @@ -138,7 +138,7 @@ select PCI_PASID select IOMMU_API select IOMMU_IOVA - depends on X86_64 && PCI && ACPI + depends on X86_64 && PCI && ACPI && HAVE_CMPXCHG_DOUBLE ---help--- With this option you can enable support for AMD IOMMU hardware in your system. An IOMMU is a hardware component which provides @@ -205,7 +205,7 @@ config INTEL_IOMMU_SVM bool "Support for Shared Virtual Memory with Intel IOMMU" - depends on INTEL_IOMMU && X86 + depends on INTEL_IOMMU && X86_64 select PCI_PASID select MMU_NOTIFIER help --- linux-oracle-5.4.0.orig/drivers/iommu/amd_iommu.c +++ linux-oracle-5.4.0/drivers/iommu/amd_iommu.c @@ -226,71 +226,58 @@ return NULL; } -static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) +static int clone_alias(struct pci_dev *pdev, u16 alias, void *data) { - *(u16 *)data = alias; - return 0; -} - -static u16 get_alias(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - u16 devid, ivrs_alias, pci_alias; + u16 devid = pci_dev_id(pdev); - /* The callers make sure that get_device_id() does not fail here */ - devid = get_device_id(dev); - - /* For ACPI HID devices, we simply return the devid as such */ - if (!dev_is_pci(dev)) - return devid; + if (devid == alias) + return 0; - ivrs_alias = amd_iommu_alias_table[devid]; + amd_iommu_rlookup_table[alias] = + amd_iommu_rlookup_table[devid]; + memcpy(amd_iommu_dev_table[alias].data, + amd_iommu_dev_table[devid].data, + sizeof(amd_iommu_dev_table[alias].data)); - pci_for_each_dma_alias(pdev, __last_alias, &pci_alias); + return 0; +} - if (ivrs_alias == pci_alias) - return ivrs_alias; +static void clone_aliases(struct pci_dev *pdev) +{ + if (!pdev) + return; /* - * DMA alias showdown - * - * The IVRS is fairly reliable in telling us about aliases, but it - * can't know about every screwy device. If we don't have an IVRS - * reported alias, use the PCI reported alias. In that case we may - * still need to initialize the rlookup and dev_table entries if the - * alias is to a non-existent device. + * The IVRS alias stored in the alias table may not be + * part of the PCI DMA aliases if it's bus differs + * from the original device. */ - if (ivrs_alias == devid) { - if (!amd_iommu_rlookup_table[pci_alias]) { - amd_iommu_rlookup_table[pci_alias] = - amd_iommu_rlookup_table[devid]; - memcpy(amd_iommu_dev_table[pci_alias].data, - amd_iommu_dev_table[devid].data, - sizeof(amd_iommu_dev_table[pci_alias].data)); - } + clone_alias(pdev, amd_iommu_alias_table[pci_dev_id(pdev)], NULL); - return pci_alias; - } + pci_for_each_dma_alias(pdev, clone_alias, NULL); +} - pci_info(pdev, "Using IVRS reported alias %02x:%02x.%d " - "for device [%04x:%04x], kernel reported alias " - "%02x:%02x.%d\n", PCI_BUS_NUM(ivrs_alias), PCI_SLOT(ivrs_alias), - PCI_FUNC(ivrs_alias), pdev->vendor, pdev->device, - PCI_BUS_NUM(pci_alias), PCI_SLOT(pci_alias), - PCI_FUNC(pci_alias)); +static struct pci_dev *setup_aliases(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + u16 ivrs_alias; + + /* For ACPI HID devices, there are no aliases */ + if (!dev_is_pci(dev)) + return NULL; /* - * If we don't have a PCI DMA alias and the IVRS alias is on the same - * bus, then the IVRS table may know about a quirk that we don't. + * Add the IVRS alias to the pci aliases if it is on the same + * bus. The IVRS table may know about a quirk that we don't. */ - if (pci_alias == devid && - PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) { - pci_add_dma_alias(pdev, ivrs_alias & 0xff); - pci_info(pdev, "Added PCI DMA alias %02x.%d\n", - PCI_SLOT(ivrs_alias), PCI_FUNC(ivrs_alias)); - } + ivrs_alias = amd_iommu_alias_table[pci_dev_id(pdev)]; + if (ivrs_alias != pci_dev_id(pdev) && + PCI_BUS_NUM(ivrs_alias) == pdev->bus->number) + pci_add_dma_alias(pdev, ivrs_alias & 0xff, 1); + + clone_aliases(pdev); - return ivrs_alias; + return pdev; } static struct iommu_dev_data *find_dev_data(u16 devid) @@ -428,7 +415,7 @@ if (!dev_data) return -ENOMEM; - dev_data->alias = get_alias(dev); + dev_data->pdev = setup_aliases(dev); /* * By default we use passthrough mode for IOMMUv2 capable device. @@ -453,20 +440,16 @@ static void iommu_ignore_device(struct device *dev) { - u16 alias; int devid; devid = get_device_id(dev); if (devid < 0) return; - alias = get_alias(dev); - + amd_iommu_rlookup_table[devid] = NULL; memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry)); - memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry)); - amd_iommu_rlookup_table[devid] = NULL; - amd_iommu_rlookup_table[alias] = NULL; + setup_aliases(dev); } static void iommu_uninit_device(struct device *dev) @@ -1236,6 +1219,13 @@ return iommu_queue_command(iommu, &cmd); } +static int device_flush_dte_alias(struct pci_dev *pdev, u16 alias, void *data) +{ + struct amd_iommu *iommu = data; + + return iommu_flush_dte(iommu, alias); +} + /* * Command send function for invalidating a device table entry */ @@ -1246,14 +1236,22 @@ int ret; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = dev_data->alias; - ret = iommu_flush_dte(iommu, dev_data->devid); - if (!ret && alias != dev_data->devid) - ret = iommu_flush_dte(iommu, alias); + if (dev_data->pdev) + ret = pci_for_each_dma_alias(dev_data->pdev, + device_flush_dte_alias, iommu); + else + ret = iommu_flush_dte(iommu, dev_data->devid); if (ret) return ret; + alias = amd_iommu_alias_table[dev_data->devid]; + if (alias != dev_data->devid) { + ret = iommu_flush_dte(iommu, alias); + if (ret) + return ret; + } + if (dev_data->ats.enabled) ret = device_flush_iotlb(dev_data, 0, ~0UL); @@ -1471,25 +1469,27 @@ bool ret = false; u64 *pte; + pte = (void *)get_zeroed_page(gfp); + if (!pte) + return false; + spin_lock_irqsave(&domain->lock, flags); if (address <= PM_LEVEL_SIZE(domain->mode) || WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) goto out; - pte = (void *)get_zeroed_page(gfp); - if (!pte) - goto out; - *pte = PM_LEVEL_PDE(domain->mode, iommu_virt_to_phys(domain->pt_root)); domain->pt_root = pte; domain->mode += 1; + pte = NULL; ret = true; out: spin_unlock_irqrestore(&domain->lock, flags); + free_page((unsigned long)pte); return ret; } @@ -2035,11 +2035,9 @@ struct protection_domain *domain) { struct amd_iommu *iommu; - u16 alias; bool ats; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = dev_data->alias; ats = dev_data->ats.enabled; /* Update data structures */ @@ -2052,8 +2050,7 @@ /* Update device table */ set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2); - if (alias != dev_data->devid) - set_dte_entry(alias, domain, ats, dev_data->iommu_v2); + clone_aliases(dev_data->pdev); device_flush_dte(dev_data); } @@ -2062,17 +2059,14 @@ { struct protection_domain *domain = dev_data->domain; struct amd_iommu *iommu; - u16 alias; iommu = amd_iommu_rlookup_table[dev_data->devid]; - alias = dev_data->alias; /* Update data structures */ dev_data->domain = NULL; list_del(&dev_data->list); clear_dte_entry(dev_data->devid); - if (alias != dev_data->devid) - clear_dte_entry(alias); + clone_aliases(dev_data->pdev); /* Flush the DTE entry */ device_flush_dte(dev_data); @@ -2384,13 +2378,7 @@ list_for_each_entry(dev_data, &domain->dev_list, list) { set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled, dev_data->iommu_v2); - - if (dev_data->devid == dev_data->alias) - continue; - - /* There is an alias, update device table entry for it */ - set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled, - dev_data->iommu_v2); + clone_aliases(dev_data->pdev); } } @@ -2400,6 +2388,7 @@ domain_flush_devices(domain); domain_flush_tlb_pde(domain); + domain_flush_complete(domain); } static int dir2prot(enum dma_data_direction direction) @@ -3109,7 +3098,8 @@ } static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, - phys_addr_t paddr, size_t page_size, int iommu_prot) + phys_addr_t paddr, size_t page_size, int iommu_prot, + gfp_t gfp) { struct protection_domain *domain = to_pdomain(dom); int prot = 0; @@ -3124,7 +3114,7 @@ prot |= IOMMU_PROT_IW; mutex_lock(&domain->api_lock); - ret = iommu_map_page(domain, iova, paddr, page_size, prot, GFP_KERNEL); + ret = iommu_map_page(domain, iova, paddr, page_size, prot, gfp); mutex_unlock(&domain->api_lock); domain_flush_np_cache(domain, iova, page_size); @@ -3752,7 +3742,20 @@ iommu_flush_dte(iommu, devid); } -static struct irq_remap_table *alloc_irq_table(u16 devid) +static int set_remap_table_entry_alias(struct pci_dev *pdev, u16 alias, + void *data) +{ + struct irq_remap_table *table = data; + + irq_lookup_table[alias] = table; + set_dte_irq_entry(alias, table); + + iommu_flush_dte(amd_iommu_rlookup_table[alias], alias); + + return 0; +} + +static struct irq_remap_table *alloc_irq_table(u16 devid, struct pci_dev *pdev) { struct irq_remap_table *table = NULL; struct irq_remap_table *new_table = NULL; @@ -3798,7 +3801,12 @@ table = new_table; new_table = NULL; - set_remap_table_entry(iommu, devid, table); + if (pdev) + pci_for_each_dma_alias(pdev, set_remap_table_entry_alias, + table); + else + set_remap_table_entry(iommu, devid, table); + if (devid != alias) set_remap_table_entry(iommu, alias, table); @@ -3815,7 +3823,8 @@ return table; } -static int alloc_irq_index(u16 devid, int count, bool align) +static int alloc_irq_index(u16 devid, int count, bool align, + struct pci_dev *pdev) { struct irq_remap_table *table; int index, c, alignment = 1; @@ -3825,7 +3834,7 @@ if (!iommu) return -ENODEV; - table = alloc_irq_table(devid); + table = alloc_irq_table(devid, pdev); if (!table) return -ENODEV; @@ -3867,6 +3876,7 @@ static int modify_irte_ga(u16 devid, int index, struct irte_ga *irte, struct amd_ir_data *data) { + bool ret; struct irq_remap_table *table; struct amd_iommu *iommu; unsigned long flags; @@ -3884,10 +3894,18 @@ entry = (struct irte_ga *)table->table; entry = &entry[index]; - entry->lo.fields_remap.valid = 0; - entry->hi.val = irte->hi.val; - entry->lo.val = irte->lo.val; - entry->lo.fields_remap.valid = 1; + + ret = cmpxchg_double(&entry->lo.val, &entry->hi.val, + entry->lo.val, entry->hi.val, + irte->lo.val, irte->hi.val); + /* + * We use cmpxchg16 to atomically update the 128-bit IRTE, + * and it cannot be updated by the hardware or other processors + * behind us, so the return value of cmpxchg16 should be the + * same as the old value. + */ + WARN_ON(!ret); + if (data) data->ref = entry; @@ -4258,7 +4276,7 @@ struct irq_remap_table *table; struct amd_iommu *iommu; - table = alloc_irq_table(devid); + table = alloc_irq_table(devid, NULL); if (table) { if (!table->min_index) { /* @@ -4275,11 +4293,15 @@ } else { index = -ENOMEM; } - } else { + } else if (info->type == X86_IRQ_ALLOC_TYPE_MSI || + info->type == X86_IRQ_ALLOC_TYPE_MSIX) { bool align = (info->type == X86_IRQ_ALLOC_TYPE_MSI); - index = alloc_irq_index(devid, nr_irqs, align); + index = alloc_irq_index(devid, nr_irqs, align, info->msi_dev); + } else { + index = alloc_irq_index(devid, nr_irqs, false, NULL); } + if (index < 0) { pr_warn("Failed to allocate IRTE\n"); ret = index; @@ -4398,8 +4420,7 @@ struct amd_ir_data *ir_data = (struct amd_ir_data *)data; struct irte_ga *entry = (struct irte_ga *) ir_data->entry; - if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || - !entry || entry->lo.fields_vapic.guest_mode) + if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || !entry) return 0; entry->lo.val = 0; @@ -4412,7 +4433,7 @@ entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; return modify_irte_ga(ir_data->irq_2_irte.devid, - ir_data->irq_2_irte.index, entry, NULL); + ir_data->irq_2_irte.index, entry, ir_data); } EXPORT_SYMBOL(amd_iommu_activate_guest_mode); @@ -4421,14 +4442,18 @@ struct amd_ir_data *ir_data = (struct amd_ir_data *)data; struct irte_ga *entry = (struct irte_ga *) ir_data->entry; struct irq_cfg *cfg = ir_data->cfg; + u64 valid; if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) || !entry || !entry->lo.fields_vapic.guest_mode) return 0; + valid = entry->lo.fields_remap.valid; + entry->lo.val = 0; entry->hi.val = 0; + entry->lo.fields_remap.valid = valid; entry->lo.fields_remap.dm = apic->irq_dest_mode; entry->lo.fields_remap.int_type = apic->irq_delivery_mode; entry->hi.fields.vector = cfg->vector; @@ -4438,7 +4463,7 @@ APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); return modify_irte_ga(ir_data->irq_2_irte.devid, - ir_data->irq_2_irte.index, entry, NULL); + ir_data->irq_2_irte.index, entry, ir_data); } EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode); @@ -4565,9 +4590,10 @@ if (!fn) return -ENOMEM; iommu->ir_domain = irq_domain_create_tree(fn, &amd_ir_domain_ops, iommu); - irq_domain_free_fwnode(fn); - if (!iommu->ir_domain) + if (!iommu->ir_domain) { + irq_domain_free_fwnode(fn); return -ENOMEM; + } iommu->ir_domain->parent = arch_get_ir_parent_domain(); iommu->msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain, --- linux-oracle-5.4.0.orig/drivers/iommu/amd_iommu_init.c +++ linux-oracle-5.4.0/drivers/iommu/amd_iommu_init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -82,7 +83,11 @@ #define ACPI_DEVFLAG_LINT1 0x80 #define ACPI_DEVFLAG_ATSDIS 0x10000000 -#define LOOP_TIMEOUT 100000 +#define LOOP_TIMEOUT 2000000 + +#define IVRS_GET_SBDF_ID(seg, bus, dev, fd) (((seg & 0xffff) << 16) | ((bus & 0xff) << 8) \ + | ((dev & 0x1f) << 3) | (fn & 0x7)) + /* * ACPI table definitions * @@ -147,7 +152,7 @@ bool amd_iommu_irq_remap __read_mostly; int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC; -static int amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE; +static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE; static bool amd_iommu_detected; static bool __initdata amd_iommu_disabled; @@ -759,6 +764,7 @@ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); if (status & (MMIO_STATUS_GALOG_RUN_MASK)) break; + udelay(10); } if (i >= LOOP_TIMEOUT) @@ -1331,8 +1337,8 @@ } case IVHD_DEV_ACPI_HID: { u16 devid; - u8 hid[ACPIHID_HID_LEN] = {0}; - u8 uid[ACPIHID_UID_LEN] = {0}; + u8 hid[ACPIHID_HID_LEN]; + u8 uid[ACPIHID_UID_LEN]; int ret; if (h->type != 0x40) { @@ -1349,6 +1355,7 @@ break; } + uid[0] = '\0'; switch (e->uidf) { case UID_NOT_PRESENT: @@ -1363,8 +1370,8 @@ break; case UID_IS_CHARACTER: - memcpy(uid, (u8 *)(&e->uid), ACPIHID_UID_LEN - 1); - uid[ACPIHID_UID_LEN - 1] = '\0'; + memcpy(uid, &e->uid, e->uidl); + uid[e->uidl] = '\0'; break; default: @@ -1403,8 +1410,17 @@ return 0; } +static void __init free_sysfs(struct amd_iommu *iommu) +{ + if (iommu->iommu.dev) { + iommu_device_unregister(&iommu->iommu); + iommu_device_sysfs_remove(&iommu->iommu); + } +} + static void __init free_iommu_one(struct amd_iommu *iommu) { + free_sysfs(iommu); free_command_buffer(iommu); free_event_buffer(iommu); free_ppr_log(iommu); @@ -1521,10 +1537,15 @@ iommu->mmio_phys_end = MMIO_REG_END_OFFSET; else iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET; - if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0)) + + /* + * Note: GA (128-bit IRTE) mode requires cmpxchg16b supports. + * GAM also requires GA mode. Therefore, we need to + * check cmpxchg16b support before enabling it. + */ + if (!boot_cpu_has(X86_FEATURE_CX16) || + ((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0)) amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; - if (((h->efr_attr & (0x1 << IOMMU_FEAT_XTSUP_SHIFT)) == 0)) - amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE; break; case 0x11: case 0x40: @@ -1532,10 +1553,27 @@ iommu->mmio_phys_end = MMIO_REG_END_OFFSET; else iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET; - if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0)) + + /* + * Note: GA (128-bit IRTE) mode requires cmpxchg16b supports. + * XT, GAM also requires GA mode. Therefore, we need to + * check cmpxchg16b support before enabling them. + */ + if (!boot_cpu_has(X86_FEATURE_CX16) || + ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0)) { amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; - if (((h->efr_reg & (0x1 << IOMMU_EFR_XTSUP_SHIFT)) == 0)) - amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE; + break; + } + + /* + * Note: Since iommu_update_intcapxt() leverages + * the IOMMU MMIO access to MSI capability block registers + * for MSI address lo/hi/data, we need to check both + * EFR[XtSup] and EFR[MsiCapMmioSup] for x2APIC support. + */ + if ((h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) && + (h->efr_reg & BIT(IOMMU_EFR_MSICAPMMIOSUP_SHIFT))) + amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE; break; default: return -EINVAL; @@ -1649,33 +1687,23 @@ return 0; } -static int iommu_pc_get_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, - u8 fxn, u64 *value, bool is_write); - static void init_iommu_perf_ctr(struct amd_iommu *iommu) { + u64 val; struct pci_dev *pdev = iommu->dev; - u64 val = 0xabcd, val2 = 0; if (!iommu_feature(iommu, FEATURE_PC)) return; amd_iommu_pc_present = true; - /* Check if the performance counters can be written to */ - if ((iommu_pc_get_set_reg(iommu, 0, 0, 0, &val, true)) || - (iommu_pc_get_set_reg(iommu, 0, 0, 0, &val2, false)) || - (val != val2)) { - pci_err(pdev, "Unable to write to IOMMU perf counter.\n"); - amd_iommu_pc_present = false; - return; - } - pci_info(pdev, "IOMMU performance counters supported\n"); val = readl(iommu->mmio_base + MMIO_CNTR_CONF_OFFSET); iommu->max_banks = (u8) ((val >> 12) & 0x3f); iommu->max_counters = (u8) ((val >> 7) & 0xf); + + return; } static ssize_t amd_iommu_show_cap(struct device *dev, @@ -1726,6 +1754,9 @@ /* Prevent binding other PCI device drivers to IOMMU devices */ iommu->dev->match_driver = false; + /* ACPI _PRT won't have an IRQ for IOMMU */ + iommu->dev->irq_managed = 1; + pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET, &iommu->cap); pci_read_config_dword(iommu->dev, cap_ptr + MMIO_RANGE_OFFSET, @@ -1984,8 +2015,8 @@ struct irq_affinity_notify *notify = &iommu->intcapxt_notify; /** - * IntCapXT requires XTSup=1, which can be inferred - * amd_iommu_xt_mode. + * IntCapXT requires XTSup=1 and MsiCapMmioSup=1, + * which can be inferred from amd_iommu_xt_mode. */ if (amd_iommu_xt_mode != IRQ_REMAP_X2APIC_MODE) return 0; @@ -2516,6 +2547,7 @@ struct acpi_table_header *ivrs_base; acpi_status status; int i, remap_cache_sz, ret = 0; + u32 pci_id; if (!amd_iommu_detected) return -ENODEV; @@ -2603,6 +2635,16 @@ if (ret) goto out; + /* Disable IOMMU if there's Stoney Ridge graphics */ + for (i = 0; i < 32; i++) { + pci_id = read_pci_config(0, i, 0, 0); + if ((pci_id & 0xffff) == 0x1002 && (pci_id >> 16) == 0x98e4) { + pr_info("Disable IOMMU on Stoney Ridge\n"); + amd_iommu_disabled = true; + break; + } + } + /* Disable any previously enabled IOMMUs */ if (!is_kdump_kernel() || amd_iommu_disabled) disable_iommus(); @@ -2711,7 +2753,7 @@ ret = early_amd_iommu_init(); init_state = ret ? IOMMU_INIT_ERROR : IOMMU_ACPI_FINISHED; if (init_state == IOMMU_ACPI_FINISHED && amd_iommu_disabled) { - pr_info("AMD IOMMU disabled on kernel command-line\n"); + pr_info("AMD IOMMU disabled\n"); init_state = IOMMU_CMDLINE_DISABLED; ret = -EINVAL; } @@ -2918,7 +2960,7 @@ { for (; *str; ++str) { if (strncmp(str, "legacy", 6) == 0) { - amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; + amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA; break; } if (strncmp(str, "vapic", 5) == 0) { @@ -2945,24 +2987,32 @@ static int __init parse_ivrs_ioapic(char *str) { - unsigned int bus, dev, fn; - int ret, id, i; - u16 devid; - - ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); + u32 seg = 0, bus, dev, fn; + int id, i; + u32 devid; - if (ret != 4) { - pr_err("Invalid command line: ivrs_ioapic%s\n", str); - return 1; + if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 || + sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) + goto found; + + if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 || + sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) { + pr_warn("ivrs_ioapic%s option format deprecated; use ivrs_ioapic=%d@%04x:%02x:%02x.%d instead\n", + str, id, seg, bus, dev, fn); + goto found; } + pr_err("Invalid command line: ivrs_ioapic%s\n", str); + return 1; + +found: if (early_ioapic_map_size == EARLY_MAP_SIZE) { pr_err("Early IOAPIC map overflow - ignoring ivrs_ioapic%s\n", str); return 1; } - devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7); + devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn); cmdline_maps = true; i = early_ioapic_map_size++; @@ -2975,24 +3025,32 @@ static int __init parse_ivrs_hpet(char *str) { - unsigned int bus, dev, fn; - int ret, id, i; - u16 devid; - - ret = sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn); + u32 seg = 0, bus, dev, fn; + int id, i; + u32 devid; - if (ret != 4) { - pr_err("Invalid command line: ivrs_hpet%s\n", str); - return 1; + if (sscanf(str, "=%d@%x:%x.%x", &id, &bus, &dev, &fn) == 4 || + sscanf(str, "=%d@%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) + goto found; + + if (sscanf(str, "[%d]=%x:%x.%x", &id, &bus, &dev, &fn) == 4 || + sscanf(str, "[%d]=%x:%x:%x.%x", &id, &seg, &bus, &dev, &fn) == 5) { + pr_warn("ivrs_hpet%s option format deprecated; use ivrs_hpet=%d@%04x:%02x:%02x.%d instead\n", + str, id, seg, bus, dev, fn); + goto found; } + pr_err("Invalid command line: ivrs_hpet%s\n", str); + return 1; + +found: if (early_hpet_map_size == EARLY_MAP_SIZE) { pr_err("Early HPET map overflow - ignoring ivrs_hpet%s\n", str); return 1; } - devid = ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7); + devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn); cmdline_maps = true; i = early_hpet_map_size++; @@ -3003,19 +3061,53 @@ return 1; } +#define ACPIID_LEN (ACPIHID_UID_LEN + ACPIHID_HID_LEN) + static int __init parse_ivrs_acpihid(char *str) { - u32 bus, dev, fn; - char *hid, *uid, *p; - char acpiid[ACPIHID_UID_LEN + ACPIHID_HID_LEN] = {0}; - int ret, i; - - ret = sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid); - if (ret != 4) { - pr_err("Invalid command line: ivrs_acpihid(%s)\n", str); - return 1; + u32 seg = 0, bus, dev, fn; + char *hid, *uid, *p, *addr; + char acpiid[ACPIID_LEN] = {0}; + int i; + + addr = strchr(str, '@'); + if (!addr) { + addr = strchr(str, '='); + if (!addr) + goto not_found; + + ++addr; + + if (strlen(addr) > ACPIID_LEN) + goto not_found; + + if (sscanf(str, "[%x:%x.%x]=%s", &bus, &dev, &fn, acpiid) == 4 || + sscanf(str, "[%x:%x:%x.%x]=%s", &seg, &bus, &dev, &fn, acpiid) == 5) { + pr_warn("ivrs_acpihid%s option format deprecated; use ivrs_acpihid=%s@%04x:%02x:%02x.%d instead\n", + str, acpiid, seg, bus, dev, fn); + goto found; + } + goto not_found; } + /* We have the '@', make it the terminator to get just the acpiid */ + *addr++ = 0; + + if (strlen(str) > ACPIID_LEN + 1) + goto not_found; + + if (sscanf(str, "=%s", acpiid) != 1) + goto not_found; + + if (sscanf(addr, "%x:%x.%x", &bus, &dev, &fn) == 3 || + sscanf(addr, "%x:%x:%x.%x", &seg, &bus, &dev, &fn) == 4) + goto found; + +not_found: + pr_err("Invalid command line: ivrs_acpihid%s\n", str); + return 1; + +found: p = acpiid; hid = strsep(&p, ":"); uid = p; @@ -3025,11 +3117,17 @@ return 1; } + /* + * Ignore leading zeroes after ':', so e.g., AMDI0095:00 + * will match AMDI0095:0 in the second strcmp in acpi_dev_hid_uid_match + */ + while (*uid == '0' && *(uid + 1)) + uid++; + i = early_acpihid_map_size++; memcpy(early_acpihid_map[i].hid, hid, strlen(hid)); memcpy(early_acpihid_map[i].uid, uid, strlen(uid)); - early_acpihid_map[i].devid = - ((bus & 0xff) << 8) | ((dev & 0x1f) << 3) | (fn & 0x7); + early_acpihid_map[i].devid = IVRS_GET_SBDF_ID(seg, bus, dev, fn); early_acpihid_map[i].cmd_line = true; return 1; --- linux-oracle-5.4.0.orig/drivers/iommu/amd_iommu_types.h +++ linux-oracle-5.4.0/drivers/iommu/amd_iommu_types.h @@ -254,7 +254,7 @@ #define DTE_IRQ_REMAP_INTCTL_MASK (0x3ULL << 60) #define DTE_IRQ_TABLE_LEN_MASK (0xfULL << 1) #define DTE_IRQ_REMAP_INTCTL (2ULL << 60) -#define DTE_IRQ_TABLE_LEN (8ULL << 1) +#define DTE_IRQ_TABLE_LEN (9ULL << 1) #define DTE_IRQ_REMAP_ENABLE 1ULL #define PAGE_MODE_NONE 0x00 @@ -348,7 +348,7 @@ #define DTE_GCR3_VAL_A(x) (((x) >> 12) & 0x00007ULL) #define DTE_GCR3_VAL_B(x) (((x) >> 15) & 0x0ffffULL) -#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0xfffffULL) +#define DTE_GCR3_VAL_C(x) (((x) >> 31) & 0x1fffffULL) #define DTE_GCR3_INDEX_A 0 #define DTE_GCR3_INDEX_B 1 @@ -377,12 +377,12 @@ #define IOMMU_CAP_EFR 27 /* IOMMU Feature Reporting Field (for IVHD type 10h */ -#define IOMMU_FEAT_XTSUP_SHIFT 0 #define IOMMU_FEAT_GASUP_SHIFT 6 /* IOMMU Extended Feature Register (EFR) */ #define IOMMU_EFR_XTSUP_SHIFT 2 #define IOMMU_EFR_GASUP_SHIFT 7 +#define IOMMU_EFR_MSICAPMMIOSUP_SHIFT 46 #define MAX_DOMAIN_ID 65536 @@ -406,7 +406,11 @@ /* Only true if all IOMMUs support device IOTLBs */ extern bool amd_iommu_iotlb_sup; -#define MAX_IRQS_PER_TABLE 256 +/* + * AMD IOMMU hardware only support 512 IRTEs despite + * the architectural limitation of 2048 entries. + */ +#define MAX_IRQS_PER_TABLE 512 #define IRQ_TABLE_ALIGNMENT 128 struct irq_remap_table { @@ -639,8 +643,8 @@ struct list_head list; /* For domain->dev_list */ struct llist_node dev_data_list; /* For global dev_data_list */ struct protection_domain *domain; /* Domain the device is bound to */ + struct pci_dev *pdev; u16 devid; /* PCI Device ID */ - u16 alias; /* Alias Device ID */ bool iommu_v2; /* Device can make use of IOMMUv2 */ bool passthrough; /* Device is identity mapped */ struct { @@ -882,8 +886,8 @@ */ struct irq_cfg *cfg; int ga_vector; - int ga_root_ptr; - int ga_tag; + u64 ga_root_ptr; + u32 ga_tag; }; struct amd_irte_ops { --- linux-oracle-5.4.0.orig/drivers/iommu/amd_iommu_v2.c +++ linux-oracle-5.4.0/drivers/iommu/amd_iommu_v2.c @@ -591,6 +591,7 @@ put_device_state(dev_state); out: + pci_dev_put(pdev); return ret; } @@ -741,6 +742,13 @@ might_sleep(); + /* + * When memory encryption is active the device is likely not in a + * direct-mapped domain. Forbid using IOMMUv2 functionality for now. + */ + if (mem_encrypt_active()) + return -ENODEV; + if (!amd_iommu_v2_supported()) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/iommu/arm-smmu-v3.c +++ linux-oracle-5.4.0/drivers/iommu/arm-smmu-v3.c @@ -169,6 +169,8 @@ #define ARM_SMMU_PRIQ_IRQ_CFG1 0xd8 #define ARM_SMMU_PRIQ_IRQ_CFG2 0xdc +#define ARM_SMMU_REG_SZ 0xe00 + /* Common MSI config fields */ #define MSI_CFG0_ADDR_MASK GENMASK_ULL(51, 2) #define MSI_CFG2_SH GENMASK(5, 4) @@ -579,6 +581,7 @@ struct arm_smmu_device { struct device *dev; void __iomem *base; + void __iomem *page1; #define ARM_SMMU_FEAT_2_LVL_STRTAB (1 << 0) #define ARM_SMMU_FEAT_2_LVL_CDTAB (1 << 1) @@ -682,9 +685,8 @@ static inline void __iomem *arm_smmu_page1_fixup(unsigned long offset, struct arm_smmu_device *smmu) { - if ((offset > SZ_64K) && - (smmu->options & ARM_SMMU_OPT_PAGE0_REGS_ONLY)) - offset -= SZ_64K; + if (offset > SZ_64K) + return smmu->page1 + offset - SZ_64K; return smmu->base + offset; } @@ -760,6 +762,18 @@ q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons); } +static void queue_sync_cons_ovf(struct arm_smmu_queue *q) +{ + struct arm_smmu_ll_queue *llq = &q->llq; + + if (likely(Q_OVF(llq->prod) == Q_OVF(llq->cons))) + return; + + llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | + Q_IDX(llq, llq->cons); + queue_sync_cons_out(q); +} + static int queue_sync_prod_in(struct arm_smmu_queue *q) { int ret = 0; @@ -856,6 +870,7 @@ cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_RANGE, 31); break; case CMDQ_OP_TLBI_NH_VA: + cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid); cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid); cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf); cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK; @@ -1642,7 +1657,8 @@ STRTAB_STE_1_EATS_TRANS)); arm_smmu_sync_ste_for_sid(smmu, sid); - dst[0] = cpu_to_le64(val); + /* See comment in arm_smmu_write_ctx_desc() */ + WRITE_ONCE(dst[0], cpu_to_le64(val)); arm_smmu_sync_ste_for_sid(smmu, sid); /* It's likely that we'll want to use the new STE soon */ @@ -1706,6 +1722,7 @@ dev_info(smmu->dev, "\t0x%016llx\n", (unsigned long long)evt[i]); + cond_resched(); } /* @@ -1717,8 +1734,7 @@ } while (!queue_empty(llq)); /* Sync our overflow flag, as we believe we're up to speed */ - llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | - Q_IDX(llq, llq->cons); + queue_sync_cons_ovf(q); return IRQ_HANDLED; } @@ -1776,9 +1792,7 @@ } while (!queue_empty(llq)); /* Sync our overflow flag, as we believe we're up to speed */ - llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) | - Q_IDX(llq, llq->cons); - queue_sync_cons_out(q); + queue_sync_cons_ovf(q); return IRQ_HANDLED; } @@ -2448,7 +2462,7 @@ } static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; @@ -3570,6 +3584,18 @@ return SZ_128K; } +static void __iomem *arm_smmu_ioremap(struct device *dev, resource_size_t start, + resource_size_t size) +{ + struct resource res = { + .flags = IORESOURCE_MEM, + .start = start, + .end = start + size - 1, + }; + + return devm_ioremap_resource(dev, &res); +} + static int arm_smmu_device_probe(struct platform_device *pdev) { int irq, ret; @@ -3605,25 +3631,38 @@ } ioaddr = res->start; - smmu->base = devm_ioremap_resource(dev, res); + /* + * Don't map the IMPLEMENTATION DEFINED regions, since they may contain + * the PMCG registers which are reserved by the PMU driver. + */ + smmu->base = arm_smmu_ioremap(dev, ioaddr, ARM_SMMU_REG_SZ); if (IS_ERR(smmu->base)) return PTR_ERR(smmu->base); + if (arm_smmu_resource_size(smmu) > SZ_64K) { + smmu->page1 = arm_smmu_ioremap(dev, ioaddr + SZ_64K, + ARM_SMMU_REG_SZ); + if (IS_ERR(smmu->page1)) + return PTR_ERR(smmu->page1); + } else { + smmu->page1 = smmu->base; + } + /* Interrupt lines */ - irq = platform_get_irq_byname(pdev, "combined"); + irq = platform_get_irq_byname_optional(pdev, "combined"); if (irq > 0) smmu->combined_irq = irq; else { - irq = platform_get_irq_byname(pdev, "eventq"); + irq = platform_get_irq_byname_optional(pdev, "eventq"); if (irq > 0) smmu->evtq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "priq"); + irq = platform_get_irq_byname_optional(pdev, "priq"); if (irq > 0) smmu->priq.q.irq = irq; - irq = platform_get_irq_byname(pdev, "gerror"); + irq = platform_get_irq_byname_optional(pdev, "gerror"); if (irq > 0) smmu->gerr_irq = irq; } --- linux-oracle-5.4.0.orig/drivers/iommu/arm-smmu.c +++ linux-oracle-5.4.0/drivers/iommu/arm-smmu.c @@ -114,7 +114,7 @@ static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu) { if (pm_runtime_enabled(smmu->dev)) - return pm_runtime_get_sync(smmu->dev); + return pm_runtime_resume_and_get(smmu->dev); return 0; } @@ -1160,7 +1160,7 @@ } static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops; struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu; @@ -1231,6 +1231,7 @@ u64 phys; unsigned long va, flags; int ret, idx = cfg->cbndx; + phys_addr_t addr = 0; ret = arm_smmu_rpm_get(smmu); if (ret < 0) @@ -1249,6 +1250,7 @@ dev_err(dev, "iova to phys timed out on %pad. Falling back to software table walk.\n", &iova); + arm_smmu_rpm_put(smmu); return ops->iova_to_phys(ops, iova); } @@ -1257,12 +1259,14 @@ if (phys & CB_PAR_F) { dev_err(dev, "translation fault!\n"); dev_err(dev, "PAR = 0x%llx\n", phys); - return 0; + goto out; } + addr = (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff); +out: arm_smmu_rpm_put(smmu); - return (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff); + return addr; } static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, --- linux-oracle-5.4.0.orig/drivers/iommu/dma-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/dma-iommu.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -43,7 +44,6 @@ dma_addr_t msi_iova; }; struct list_head msi_page_list; - spinlock_t msi_lock; /* Domain for flush queue callback; NULL if flush queue not in use */ struct iommu_domain *fq_domain; @@ -62,7 +62,6 @@ cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); if (cookie) { - spin_lock_init(&cookie->msi_lock); INIT_LIST_HEAD(&cookie->msi_page_list); cookie->type = type; } @@ -177,15 +176,15 @@ start -= iova_offset(iovad, start); num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); - msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); - if (!msi_page) - return -ENOMEM; - for (i = 0; i < num_pages; i++) { - msi_page[i].phys = start; - msi_page[i].iova = start; - INIT_LIST_HEAD(&msi_page[i].list); - list_add(&msi_page[i].list, &cookie->msi_page_list); + msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); + if (!msi_page) + return -ENOMEM; + + msi_page->phys = start; + msi_page->iova = start; + INIT_LIST_HEAD(&msi_page->list); + list_add(&msi_page->list, &cookie->msi_page_list); start += iovad->granule; } @@ -217,9 +216,11 @@ lo = iova_pfn(iovad, start); hi = iova_pfn(iovad, end); reserve_iova(iovad, lo, hi); - } else { + } else if (end < start) { /* dma_ranges list should be sorted */ - dev_err(&dev->dev, "Failed to reserve IOVA\n"); + dev_err(&dev->dev, + "Failed to reserve IOVA [%pa-%pa]\n", + &start, &end); return -EINVAL; } @@ -476,7 +477,7 @@ if (!iova) return DMA_MAPPING_ERROR; - if (iommu_map(domain, iova, phys - iova_off, size, prot)) { + if (iommu_map_atomic(domain, iova, phys - iova_off, size, prot)) { iommu_dma_free_iova(cookie, iova, size); return DMA_MAPPING_ERROR; } @@ -611,7 +612,7 @@ arch_dma_prep_coherent(sg_page(sg), sg->length); } - if (iommu_map_sg(domain, iova, sgt.sgl, sgt.orig_nents, ioprot) + if (iommu_map_sg_atomic(domain, iova, sgt.sgl, sgt.orig_nents, ioprot) < size) goto out_free_sg; @@ -659,7 +660,7 @@ return; phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), dma_handle); - arch_sync_dma_for_cpu(dev, phys, size, dir); + arch_sync_dma_for_cpu(phys, size, dir); } static void iommu_dma_sync_single_for_device(struct device *dev, @@ -671,7 +672,7 @@ return; phys = iommu_iova_to_phys(iommu_get_dma_domain(dev), dma_handle); - arch_sync_dma_for_device(dev, phys, size, dir); + arch_sync_dma_for_device(phys, size, dir); } static void iommu_dma_sync_sg_for_cpu(struct device *dev, @@ -685,7 +686,7 @@ return; for_each_sg(sgl, sg, nelems, i) - arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir); + arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); } static void iommu_dma_sync_sg_for_device(struct device *dev, @@ -699,7 +700,7 @@ return; for_each_sg(sgl, sg, nelems, i) - arch_sync_dma_for_device(dev, sg_phys(sg), sg->length, dir); + arch_sync_dma_for_device(sg_phys(sg), sg->length, dir); } static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, @@ -714,7 +715,7 @@ dma_handle =__iommu_dma_map(dev, phys, size, prot); if (!coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC) && dma_handle != DMA_MAPPING_ERROR) - arch_sync_dma_for_device(dev, phys, size, dir); + arch_sync_dma_for_device(phys, size, dir); return dma_handle; } @@ -871,7 +872,7 @@ * We'll leave any physical concatenation to the IOMMU driver's * implementation - it knows better than we do. */ - if (iommu_map_sg(domain, iova, sg, nents, prot) < iova_len) + if (iommu_map_sg_atomic(domain, iova, sg, nents, prot) < iova_len) goto out_free_iova; return __finalise_sg(dev, sg, nents, iova); @@ -1150,7 +1151,7 @@ if (msi_page->phys == msi_addr) return msi_page; - msi_page = kzalloc(sizeof(*msi_page), GFP_ATOMIC); + msi_page = kzalloc(sizeof(*msi_page), GFP_KERNEL); if (!msi_page) return NULL; @@ -1178,25 +1179,22 @@ { struct device *dev = msi_desc_to_dev(desc); struct iommu_domain *domain = iommu_get_domain_for_dev(dev); - struct iommu_dma_cookie *cookie; struct iommu_dma_msi_page *msi_page; - unsigned long flags; + static DEFINE_MUTEX(msi_prepare_lock); /* see below */ if (!domain || !domain->iova_cookie) { desc->iommu_cookie = NULL; return 0; } - cookie = domain->iova_cookie; - /* - * We disable IRQs to rule out a possible inversion against - * irq_desc_lock if, say, someone tries to retarget the affinity - * of an MSI from within an IPI handler. + * In fact the whole prepare operation should already be serialised by + * irq_domain_mutex further up the callchain, but that's pretty subtle + * on its own, so consider this locking as failsafe documentation... */ - spin_lock_irqsave(&cookie->msi_lock, flags); + mutex_lock(&msi_prepare_lock); msi_page = iommu_dma_get_msi_page(dev, msi_addr, domain); - spin_unlock_irqrestore(&cookie->msi_lock, flags); + mutex_unlock(&msi_prepare_lock); msi_desc_set_iommu_cookie(desc, msi_page); --- linux-oracle-5.4.0.orig/drivers/iommu/dmar.c +++ linux-oracle-5.4.0/drivers/iommu/dmar.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -128,6 +129,13 @@ BUG_ON(dev->is_virtfn); + /* + * Ignore devices that have a domain number higher than what can + * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 + */ + if (pci_domain_nr(dev->bus) > U16_MAX) + return NULL; + /* Only generate path[] for device addition event */ if (event == BUS_NOTIFY_ADD_DEVICE) for (tmp = dev; tmp; tmp = tmp->bus->self) @@ -355,7 +363,7 @@ static struct notifier_block dmar_pci_bus_nb = { .notifier_call = dmar_pci_bus_notifier, - .priority = INT_MIN, + .priority = 1, }; static struct dmar_drhd_unit * @@ -363,7 +371,8 @@ { struct dmar_drhd_unit *dmaru; - list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list) + list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list, + dmar_rcu_check()) if (dmaru->segment == drhd->segment && dmaru->reg_base_addr == drhd->address) return dmaru; @@ -440,12 +449,13 @@ /* Check for NUL termination within the designated length */ if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { - WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, + pr_warn(FW_BUG "Your BIOS is broken; ANDD object name is not NUL-terminated\n" "BIOS vendor: %s; Ver: %s; Product Version: %s\n", dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); return -EINVAL; } pr_info("ANDD device: %x name: %s\n", andd->device_number, @@ -465,20 +475,20 @@ if (drhd->reg_base_addr == rhsa->base_address) { int node = acpi_map_pxm_to_node(rhsa->proximity_domain); - if (!node_online(node)) + if (node != NUMA_NO_NODE && !node_online(node)) node = NUMA_NO_NODE; drhd->iommu->node = node; return 0; } } - WARN_TAINT( - 1, TAINT_FIRMWARE_WORKAROUND, + pr_warn(FW_BUG "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" "BIOS vendor: %s; Ver: %s; Product Version: %s\n", - drhd->reg_base_addr, + rhsa->base_address, dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); return 0; } @@ -784,6 +794,7 @@ info = dmar_alloc_pci_notify_info(dev, BUS_NOTIFY_ADD_DEVICE); if (!info) { + pci_dev_put(dev); return dmar_dev_scope_status; } else { dmar_pci_bus_add_dev(info); @@ -827,14 +838,14 @@ static void warn_invalid_dmar(u64 addr, const char *message) { - WARN_TAINT_ONCE( - 1, TAINT_FIRMWARE_WORKAROUND, + pr_warn_once(FW_BUG "Your BIOS is broken; DMAR reported at address %llx%s!\n" "BIOS vendor: %s; Ver: %s; Product Version: %s\n", addr, message, dmi_get_system_info(DMI_BIOS_VENDOR), dmi_get_system_info(DMI_BIOS_VERSION), dmi_get_system_info(DMI_PRODUCT_VERSION)); + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); } static int __ref @@ -888,7 +899,8 @@ if (!ret) ret = dmar_walk_dmar_table((struct acpi_table_dmar *)dmar_tbl, &validate_drhd_cb); - if (!ret && !no_iommu && !iommu_detected && !dmar_disabled) { + if (!ret && !no_iommu && !iommu_detected && + (!dmar_disabled || dmar_platform_optin())) { iommu_detected = 1; /* Make sure ACS will be enabled */ pci_request_acs(); @@ -1009,8 +1021,8 @@ { struct intel_iommu *iommu; u32 ver, sts; - int agaw = 0; - int msagaw = 0; + int agaw = -1; + int msagaw = -1; int err; if (!drhd->reg_base_addr) { @@ -1035,17 +1047,28 @@ } err = -EINVAL; - agaw = iommu_calculate_agaw(iommu); - if (agaw < 0) { - pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", - iommu->seq_id); - goto err_unmap; - } - msagaw = iommu_calculate_max_sagaw(iommu); - if (msagaw < 0) { - pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", - iommu->seq_id); - goto err_unmap; + if (cap_sagaw(iommu->cap) == 0) { + pr_info("%s: No supported address widths. Not attempting DMA translation.\n", + iommu->name); + drhd->ignored = 1; + } + + if (!drhd->ignored) { + agaw = iommu_calculate_agaw(iommu); + if (agaw < 0) { + pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", + iommu->seq_id); + drhd->ignored = 1; + } + } + if (!drhd->ignored) { + msagaw = iommu_calculate_max_sagaw(iommu); + if (msagaw < 0) { + pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", + iommu->seq_id); + drhd->ignored = 1; + agaw = -1; + } } iommu->agaw = agaw; iommu->msagaw = msagaw; @@ -1072,7 +1095,12 @@ raw_spin_lock_init(&iommu->register_lock); - if (intel_iommu_enabled) { + /* + * This is only for hotplug; at boot time intel_iommu_enabled won't + * be set yet. When intel_iommu_init() runs, it registers the units + * present at boot time, then sets intel_iommu_enabled. + */ + if (intel_iommu_enabled && !drhd->ignored) { err = iommu_device_sysfs_add(&iommu->iommu, NULL, intel_iommu_groups, "%s", iommu->name); @@ -1083,13 +1111,16 @@ err = iommu_device_register(&iommu->iommu); if (err) - goto err_unmap; + goto err_sysfs; } drhd->iommu = iommu; + iommu->drhd = drhd; return 0; +err_sysfs: + iommu_device_sysfs_remove(&iommu->iommu); err_unmap: unmap_iommu(iommu); error_free_seq_id: @@ -1101,7 +1132,7 @@ static void free_iommu(struct intel_iommu *iommu) { - if (intel_iommu_enabled) { + if (intel_iommu_enabled && !iommu->drhd->ignored) { iommu_device_unregister(&iommu->iommu); iommu_device_sysfs_remove(&iommu->iommu); } @@ -1263,7 +1294,7 @@ */ writel(qi->free_head << shift, iommu->reg + DMAR_IQT_REG); - while (qi->desc_status[wait_index] != QI_DONE) { + while (READ_ONCE(qi->desc_status[wait_index]) != QI_DONE) { /* * We will leave the interrupts disabled, to prevent interrupt * context to queue another cmd while a cmd is already submitted @@ -1351,7 +1382,6 @@ struct qi_desc desc; if (mask) { - WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1)); addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; } else --- linux-oracle-5.4.0.orig/drivers/iommu/exynos-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/exynos-iommu.c @@ -635,7 +635,7 @@ ret = iommu_device_register(&data->iommu); if (ret) - return ret; + goto err_iommu_register; platform_set_drvdata(pdev, data); @@ -662,6 +662,10 @@ pm_runtime_enable(dev); return 0; + +err_iommu_register: + iommu_device_sysfs_remove(&data->iommu); + return ret; } static int __maybe_unused exynos_sysmmu_suspend(struct device *dev) @@ -1073,7 +1077,7 @@ */ static int exynos_iommu_map(struct iommu_domain *iommu_domain, unsigned long l_iova, phys_addr_t paddr, size_t size, - int prot) + int prot, gfp_t gfp) { struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain); sysmmu_pte_t *entry; @@ -1299,13 +1303,17 @@ return -ENODEV; data = platform_get_drvdata(sysmmu); - if (!data) + if (!data) { + put_device(&sysmmu->dev); return -ENODEV; + } if (!owner) { owner = kzalloc(sizeof(*owner), GFP_KERNEL); - if (!owner) + if (!owner) { + put_device(&sysmmu->dev); return -ENOMEM; + } INIT_LIST_HEAD(&owner->controllers); mutex_init(&owner->rpm_lock); --- linux-oracle-5.4.0.orig/drivers/iommu/fsl_pamu.c +++ linux-oracle-5.4.0/drivers/iommu/fsl_pamu.c @@ -1122,7 +1122,7 @@ ret = create_csd(ppaact_phys, mem_size, csd_port_id); if (ret) { dev_err(dev, "could not create coherence subdomain\n"); - return ret; + goto error; } } --- linux-oracle-5.4.0.orig/drivers/iommu/hyperv-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/hyperv-iommu.c @@ -155,7 +155,10 @@ 0, IOAPIC_REMAPPING_ENTRY, fn, &hyperv_ir_domain_ops, NULL); - irq_domain_free_fwnode(fn); + if (!ioapic_ir_domain) { + irq_domain_free_fwnode(fn); + return -ENOMEM; + } /* * Hyper-V doesn't provide irq remapping function for --- linux-oracle-5.4.0.orig/drivers/iommu/intel-iommu-debugfs.c +++ linux-oracle-5.4.0/drivers/iommu/intel-iommu-debugfs.c @@ -32,38 +32,42 @@ #define IOMMU_REGSET_ENTRY(_reg_) \ { DMAR_##_reg_##_REG, __stringify(_reg_) } -static const struct iommu_regset iommu_regs[] = { + +static const struct iommu_regset iommu_regs_32[] = { IOMMU_REGSET_ENTRY(VER), - IOMMU_REGSET_ENTRY(CAP), - IOMMU_REGSET_ENTRY(ECAP), IOMMU_REGSET_ENTRY(GCMD), IOMMU_REGSET_ENTRY(GSTS), - IOMMU_REGSET_ENTRY(RTADDR), - IOMMU_REGSET_ENTRY(CCMD), IOMMU_REGSET_ENTRY(FSTS), IOMMU_REGSET_ENTRY(FECTL), IOMMU_REGSET_ENTRY(FEDATA), IOMMU_REGSET_ENTRY(FEADDR), IOMMU_REGSET_ENTRY(FEUADDR), - IOMMU_REGSET_ENTRY(AFLOG), IOMMU_REGSET_ENTRY(PMEN), IOMMU_REGSET_ENTRY(PLMBASE), IOMMU_REGSET_ENTRY(PLMLIMIT), + IOMMU_REGSET_ENTRY(ICS), + IOMMU_REGSET_ENTRY(PRS), + IOMMU_REGSET_ENTRY(PECTL), + IOMMU_REGSET_ENTRY(PEDATA), + IOMMU_REGSET_ENTRY(PEADDR), + IOMMU_REGSET_ENTRY(PEUADDR), +}; + +static const struct iommu_regset iommu_regs_64[] = { + IOMMU_REGSET_ENTRY(CAP), + IOMMU_REGSET_ENTRY(ECAP), + IOMMU_REGSET_ENTRY(RTADDR), + IOMMU_REGSET_ENTRY(CCMD), + IOMMU_REGSET_ENTRY(AFLOG), IOMMU_REGSET_ENTRY(PHMBASE), IOMMU_REGSET_ENTRY(PHMLIMIT), IOMMU_REGSET_ENTRY(IQH), IOMMU_REGSET_ENTRY(IQT), IOMMU_REGSET_ENTRY(IQA), - IOMMU_REGSET_ENTRY(ICS), IOMMU_REGSET_ENTRY(IRTA), IOMMU_REGSET_ENTRY(PQH), IOMMU_REGSET_ENTRY(PQT), IOMMU_REGSET_ENTRY(PQA), - IOMMU_REGSET_ENTRY(PRS), - IOMMU_REGSET_ENTRY(PECTL), - IOMMU_REGSET_ENTRY(PEDATA), - IOMMU_REGSET_ENTRY(PEADDR), - IOMMU_REGSET_ENTRY(PEUADDR), IOMMU_REGSET_ENTRY(MTRRCAP), IOMMU_REGSET_ENTRY(MTRRDEF), IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000), @@ -126,10 +130,16 @@ * by adding the offset to the pointer (virtual address). */ raw_spin_lock_irqsave(&iommu->register_lock, flag); - for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) { - value = dmar_readq(iommu->reg + iommu_regs[i].offset); + for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) { + value = dmar_readl(iommu->reg + iommu_regs_32[i].offset); seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", - iommu_regs[i].regs, iommu_regs[i].offset, + iommu_regs_32[i].regs, iommu_regs_32[i].offset, + value); + } + for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) { + value = dmar_readq(iommu->reg + iommu_regs_64[i].offset); + seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", + iommu_regs_64[i].regs, iommu_regs_64[i].offset, value); } raw_spin_unlock_irqrestore(&iommu->register_lock, flag); @@ -271,9 +281,16 @@ { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; + u32 sts; rcu_read_lock(); for_each_active_iommu(iommu, drhd) { + sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); + if (!(sts & DMA_GSTS_TES)) { + seq_printf(m, "DMA Remapping is not enabled on %s\n", + iommu->name); + continue; + } root_tbl_walk(m, iommu); seq_putc(m, '\n'); } @@ -343,6 +360,7 @@ struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; u64 irta; + u32 sts; rcu_read_lock(); for_each_active_iommu(iommu, drhd) { @@ -352,7 +370,8 @@ seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n", iommu->name); - if (iommu->ir_table) { + sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); + if (iommu->ir_table && (sts & DMA_GSTS_IRES)) { irta = virt_to_phys(iommu->ir_table->base); seq_printf(m, " IR table address:%llx\n", irta); ir_tbl_remap_entry_show(m, iommu); --- linux-oracle-5.4.0.orig/drivers/iommu/intel-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/intel-iommu.c @@ -123,29 +123,29 @@ return (level - 1) * LEVEL_STRIDE; } -static inline int pfn_level_offset(unsigned long pfn, int level) +static inline int pfn_level_offset(u64 pfn, int level) { return (pfn >> level_to_offset_bits(level)) & LEVEL_MASK; } -static inline unsigned long level_mask(int level) +static inline u64 level_mask(int level) { - return -1UL << level_to_offset_bits(level); + return -1ULL << level_to_offset_bits(level); } -static inline unsigned long level_size(int level) +static inline u64 level_size(int level) { - return 1UL << level_to_offset_bits(level); + return 1ULL << level_to_offset_bits(level); } -static inline unsigned long align_to_level(unsigned long pfn, int level) +static inline u64 align_to_level(u64 pfn, int level) { return (pfn + level_size(level) - 1) & level_mask(level); } static inline unsigned long lvl_to_nr_pages(unsigned int lvl) { - return 1 << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH); + return 1UL << min_t(int, (lvl - 1) * LEVEL_STRIDE, MAX_AGAW_PFN_WIDTH); } /* VT-d pages must always be _smaller_ than MM pages. Otherwise things @@ -179,7 +179,7 @@ * (used when kernel is launched w/ TXT) */ static int force_on = 0; -int intel_iommu_tboot_noforce; +static int intel_iommu_tboot_noforce; static int no_platform_optin; #define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) @@ -611,6 +611,12 @@ return g_iommus[iommu_id]; } +static inline bool iommu_paging_structure_coherency(struct intel_iommu *iommu) +{ + return sm_supported(iommu) ? + ecap_smpwc(iommu->ecap) : ecap_coherent(iommu->ecap); +} + static void domain_update_iommu_coherency(struct dmar_domain *domain) { struct dmar_drhd_unit *drhd; @@ -622,7 +628,7 @@ for_each_domain_iommu(i, domain) { found = true; - if (!ecap_coherent(g_iommus[i]->ecap)) { + if (!iommu_paging_structure_coherency(g_iommus[i])) { domain->iommu_coherency = 0; break; } @@ -633,7 +639,7 @@ /* No hardware attached; use lowest common denominator */ rcu_read_lock(); for_each_active_iommu(iommu, drhd) { - if (!ecap_coherent(iommu->ecap)) { + if (!iommu_paging_structure_coherency(iommu)) { domain->iommu_coherency = 0; break; } @@ -732,6 +738,11 @@ return dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO; } +static bool attach_deferred(struct device *dev) +{ + return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO; +} + /** * is_downstream_to_pci_bridge - test if a device belongs to the PCI * sub-hierarchy of a candidate PCI-PCI bridge @@ -1847,7 +1858,7 @@ static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu, int guest_width) { - int adjust_width, agaw; + int adjust_width, agaw, cap_width; unsigned long sagaw; int err; @@ -1861,8 +1872,9 @@ domain_reserve_special_ranges(domain); /* calculate AGAW */ - if (guest_width > cap_mgaw(iommu->cap)) - guest_width = cap_mgaw(iommu->cap); + cap_width = min_t(int, cap_mgaw(iommu->cap), agaw_to_width(iommu->agaw)); + if (guest_width > cap_width) + guest_width = cap_width; domain->gaw = guest_width; adjust_width = guestwidth_to_adjustwidth(guest_width); agaw = width_to_agaw(adjust_width); @@ -2090,7 +2102,8 @@ context_set_fault_enable(context); context_set_present(context); - domain_flush_cache(domain, context, sizeof(*context)); + if (!ecap_coherent(iommu->ecap)) + clflush_cache_range(context, sizeof(*context)); /* * It's a non-present to present mapping. If hardware doesn't cache @@ -2420,31 +2433,31 @@ spin_unlock_irqrestore(&device_domain_lock, flags); } -/* - * find_domain - * Note: we use struct device->archdata.iommu stores the info - */ static struct dmar_domain *find_domain(struct device *dev) { struct device_domain_info *info; - if (unlikely(dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO)) { - struct iommu_domain *domain; - - dev->archdata.iommu = NULL; - domain = iommu_get_domain_for_dev(dev); - if (domain) - intel_iommu_attach_device(domain, dev); - } + if (unlikely(attach_deferred(dev) || iommu_dummy(dev))) + return NULL; /* No lock here, assumes no domain exit in normal case */ info = dev->archdata.iommu; - if (likely(info)) return info->domain; + return NULL; } +static void do_deferred_attach(struct device *dev) +{ + struct iommu_domain *domain; + + dev->archdata.iommu = NULL; + domain = iommu_get_domain_for_dev(dev); + if (domain) + intel_iommu_attach_device(domain, dev); +} + static inline struct device_domain_info * dmar_search_domain_by_dev_info(int segment, int bus, int devfn) { @@ -2553,14 +2566,14 @@ } /* Setup the PASID entry for requests without PASID: */ - spin_lock(&iommu->lock); + spin_lock_irqsave(&iommu->lock, flags); if (hw_pass_through && domain_type_is_si(domain)) ret = intel_pasid_setup_pass_through(iommu, domain, dev, PASID_RID2PASID); else ret = intel_pasid_setup_second_level(iommu, domain, dev, PASID_RID2PASID); - spin_unlock(&iommu->lock); + spin_unlock_irqrestore(&iommu->lock, flags); if (ret) { dev_err(dev, "Setup RID2PASID failed\n"); dmar_remove_one_dev_info(dev); @@ -2743,6 +2756,7 @@ if (md_domain_init(si_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) { domain_exit(si_domain); + si_domain = NULL; return -EFAULT; } @@ -2762,10 +2776,8 @@ } /* - * Normally we use DMA domains for devices which have RMRRs. But we - * loose this requirement for graphic and usb devices. Identity map - * the RMRRs for graphic and USB devices so that they could use the - * si_domain. + * Identity map the RMRRs so that devices with RMRRs could also use + * the si_domain. */ for_each_rmrr_units(rmrr) { for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt, @@ -2773,9 +2785,6 @@ unsigned long long start = rmrr->base_address; unsigned long long end = rmrr->end_address; - if (device_is_rmrr_locked(dev)) - continue; - if (WARN_ON(end < start || end >> agaw_to_width(si_domain->agaw))) continue; @@ -2794,7 +2803,7 @@ struct device_domain_info *info; info = dev->archdata.iommu; - if (info && info != DUMMY_DEVICE_DOMAIN_INFO && info != DEFER_DEVICE_DOMAIN_INFO) + if (info) return (info->domain == si_domain); return 0; @@ -2914,9 +2923,6 @@ if (dev_is_pci(dev)) { struct pci_dev *pdev = to_pci_dev(dev); - if (device_is_rmrr_locked(dev)) - return IOMMU_DOMAIN_DMA; - /* * Prevent any device marked as untrusted from getting * placed into the statically identity mapping domain. @@ -2954,9 +2960,6 @@ return IOMMU_DOMAIN_DMA; } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE) return IOMMU_DOMAIN_DMA; - } else { - if (device_has_rmrr(dev)) - return IOMMU_DOMAIN_DMA; } return (iommu_identity_mapping & IDENTMAP_ALL) ? @@ -3289,6 +3292,12 @@ if (!ecap_pass_through(iommu->ecap)) hw_pass_through = 0; + + if (!intel_iommu_strict && cap_caching_mode(iommu->cap)) { + pr_info("Disable batched IOTLB flush due to virtualization"); + intel_iommu_strict = 1; + } + #ifdef CONFIG_INTEL_IOMMU_SVM if (pasid_supported(iommu)) intel_svm_init(iommu); @@ -3368,6 +3377,10 @@ disable_dmar_iommu(iommu); free_dmar_iommu(iommu); } + if (si_domain) { + domain_exit(si_domain); + si_domain = NULL; + } kfree(g_iommus); @@ -3401,7 +3414,8 @@ iova_pfn = alloc_iova_fast(&domain->iovad, nrpages, IOVA_PFN(dma_mask), true); if (unlikely(!iova_pfn)) { - dev_err(dev, "Allocating %ld-page iova failed", nrpages); + dev_err_once(dev, "Allocating %ld-page iova failed\n", + nrpages); return 0; } @@ -3464,6 +3478,9 @@ if (iommu_dummy(dev)) return false; + if (unlikely(attach_deferred(dev))) + do_deferred_attach(dev); + ret = identity_mapping(dev); if (ret) { u64 dma_mask = *dev->dma_mask; @@ -3827,7 +3844,11 @@ int prot = 0; int ret; + if (unlikely(attach_deferred(dev))) + do_deferred_attach(dev); + domain = find_domain(dev); + if (WARN_ON(dir == DMA_NONE || !domain)) return DMA_MAPPING_ERROR; @@ -4128,10 +4149,11 @@ /* we know that the this iommu should be at offset 0xa000 from vtbar */ drhd = dmar_find_matched_drhd_unit(pdev); - if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, - TAINT_FIRMWARE_WORKAROUND, - "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) + if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { + pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; + } } DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); @@ -4344,7 +4366,8 @@ struct dmar_atsr_unit *atsru; struct acpi_dmar_atsr *tmp; - list_for_each_entry_rcu(atsru, &dmar_atsr_units, list) { + list_for_each_entry_rcu(atsru, &dmar_atsr_units, list, + dmar_rcu_check()) { tmp = (struct acpi_dmar_atsr *)atsru->hdr; if (atsr->segment != tmp->segment) continue; @@ -4928,7 +4951,8 @@ * Intel IOMMU is required for a TXT/tboot launch or platform * opt in, so enforce that. */ - force_on = tboot_force_iommu() || platform_optin_force_iommu(); + force_on = (!intel_iommu_tboot_noforce && tboot_force_iommu()) || + platform_optin_force_iommu(); if (iommu_init_mempool()) { if (force_on) @@ -4959,6 +4983,9 @@ down_write(&dmar_global_lock); + if (!no_iommu) + intel_iommu_debugfs_init(); + if (no_iommu || dmar_disabled) { /* * We exit the function here to ensure IOMMU's remapping and @@ -5022,6 +5049,7 @@ init_iommu_pm_ops(); + down_read(&dmar_global_lock); for_each_active_iommu(iommu, drhd) { iommu_device_sysfs_add(&iommu->iommu, NULL, intel_iommu_groups, @@ -5029,6 +5057,7 @@ iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); iommu_device_register(&iommu->iommu); } + up_read(&dmar_global_lock); bus_set_iommu(&pci_bus_type, &intel_iommu_ops); if (si_domain && !hw_pass_through) @@ -5039,7 +5068,6 @@ down_read(&dmar_global_lock); if (probe_acpi_namespace_devices()) pr_warn("ACPI name space devices didn't probe correctly\n"); - up_read(&dmar_global_lock); /* Finally, we enable the DMA remapping hardware. */ for_each_iommu(iommu, drhd) { @@ -5048,10 +5076,11 @@ iommu_disable_protect_mem_regions(iommu); } + up_read(&dmar_global_lock); + pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); intel_iommu_enabled = 1; - intel_iommu_debugfs_init(); return 0; @@ -5132,7 +5161,8 @@ spin_lock_irqsave(&device_domain_lock, flags); info = dev->archdata.iommu; - if (info) + if (info && info != DEFER_DEVICE_DOMAIN_INFO + && info != DUMMY_DEVICE_DOMAIN_INFO) __dmar_remove_one_dev_info(info); spin_unlock_irqrestore(&device_domain_lock, flags); } @@ -5440,16 +5470,13 @@ static int intel_iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t hpa, - size_t size, int iommu_prot) + size_t size, int iommu_prot, gfp_t gfp) { struct dmar_domain *dmar_domain = to_dmar_domain(domain); u64 max_addr; int prot = 0; int ret; - if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN) - return -EINVAL; - if (iommu_prot & IOMMU_READ) prot |= DMA_PTE_READ; if (iommu_prot & IOMMU_WRITE) @@ -5492,8 +5519,6 @@ /* Cope with horrid API which requires us to unmap more than the size argument if it happens to be a large-page mapping. */ BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level)); - if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN) - return 0; if (size < VTD_PAGE_SIZE << level_to_offset_bits(level)) size = VTD_PAGE_SIZE << level_to_offset_bits(level); @@ -5525,12 +5550,11 @@ int level = 0; u64 phys = 0; - if (dmar_domain->flags & DOMAIN_FLAG_LOSE_CHILDREN) - return 0; - pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); - if (pte) - phys = dma_pte_addr(pte); + if (pte && dma_pte_present(pte)) + phys = dma_pte_addr(pte) + + (iova & (BIT_MASK(level_to_offset_bits(level) + + VTD_PAGE_SHIFT) - 1)); return phys; } @@ -5601,8 +5625,10 @@ group = iommu_group_get_for_dev(dev); - if (IS_ERR(group)) - return PTR_ERR(group); + if (IS_ERR(group)) { + ret = PTR_ERR(group); + goto unlink; + } iommu_group_put(group); @@ -5628,7 +5654,8 @@ if (!get_private_domain_for_dev(dev)) { dev_warn(dev, "Failed to get a private domain.\n"); - return -ENOMEM; + ret = -ENOMEM; + goto unlink; } dev_info(dev, @@ -5643,6 +5670,10 @@ } return 0; + +unlink: + iommu_device_unlink(&iommu->iommu, dev); + return ret; } static void intel_iommu_remove_device(struct device *dev) @@ -5705,8 +5736,8 @@ struct pci_dev *pdev = to_pci_dev(device); if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) { - reg = iommu_alloc_resv_region(0, 1UL << 24, 0, - IOMMU_RESV_DIRECT); + reg = iommu_alloc_resv_region(0, 1UL << 24, prot, + IOMMU_RESV_DIRECT_RELAXABLE); if (reg) list_add_tail(®->list, head); } @@ -5794,6 +5825,13 @@ WARN_ON_ONCE(!reserve_iova(&dmar_domain->iovad, start, end)); } +static struct iommu_group *intel_iommu_device_group(struct device *dev) +{ + if (dev_is_pci(dev)) + return pci_device_group(dev); + return generic_device_group(dev); +} + #ifdef CONFIG_INTEL_IOMMU_SVM struct intel_iommu *intel_svm_device_to_iommu(struct device *dev) { @@ -5946,7 +5984,24 @@ static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain, struct device *dev) { - return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO; + return attach_deferred(dev); +} + +/* + * Check that the device does not live on an external facing PCI port that is + * marked as untrusted. Such devices should not be able to apply quirks and + * thus not be able to bypass the IOMMU restrictions. + */ +static bool risky_device(struct pci_dev *pdev) +{ + if (pdev->untrusted) { + pci_info(pdev, + "Skipping IOMMU quirk for dev [%04X:%04X] on untrusted PCI link\n", + pdev->vendor, pdev->device); + pci_info(pdev, "Please check with your BIOS/Platform vendor about this\n"); + return true; + } + return false; } const struct iommu_ops intel_iommu_ops = { @@ -5966,7 +6021,7 @@ .get_resv_regions = intel_iommu_get_resv_regions, .put_resv_regions = intel_iommu_put_resv_regions, .apply_resv_region = intel_iommu_apply_resv_region, - .device_group = pci_device_group, + .device_group = intel_iommu_device_group, .dev_has_feat = intel_iommu_dev_has_feat, .dev_feat_enabled = intel_iommu_dev_feat_enabled, .dev_enable_feat = intel_iommu_dev_enable_feat, @@ -5977,6 +6032,9 @@ static void quirk_iommu_igfx(struct pci_dev *dev) { + if (risky_device(dev)) + return; + pci_info(dev, "Disabling IOMMU for graphics on this chipset\n"); dmar_map_gfx = 0; } @@ -6018,6 +6076,9 @@ static void quirk_iommu_rwbf(struct pci_dev *dev) { + if (risky_device(dev)) + return; + /* * Mobile 4 Series Chipset neglects to set RWBF capability, * but needs it. Same seems to hold for the desktop versions. @@ -6048,6 +6109,9 @@ { unsigned short ggc; + if (risky_device(dev)) + return; + if (pci_read_config_word(dev, GGC, &ggc)) return; @@ -6081,6 +6145,12 @@ pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL); if (!pdev) return; + + if (risky_device(pdev)) { + pci_dev_put(pdev); + return; + } + pci_dev_put(pdev); /* System Management Registers. Might be hidden, in which case @@ -6090,6 +6160,11 @@ if (!pdev) return; + if (risky_device(pdev)) { + pci_dev_put(pdev); + return; + } + if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) { pci_dev_put(pdev); return; --- linux-oracle-5.4.0.orig/drivers/iommu/intel-pasid.c +++ linux-oracle-5.4.0/drivers/iommu/intel-pasid.c @@ -166,6 +166,9 @@ attach_out: device_attach_pasid_table(info, pasid_table); + if (!ecap_coherent(info->iommu->ecap)) + clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE); + return 0; } @@ -250,6 +253,10 @@ WRITE_ONCE(dir[dir_index].val, (u64)virt_to_phys(entries) | PASID_PTE_PRESENT); + if (!ecap_coherent(info->iommu->ecap)) { + clflush_cache_range(entries, VTD_PAGE_SIZE); + clflush_cache_range(&dir[dir_index].val, sizeof(*dir)); + } } spin_unlock(&pasid_lock); @@ -434,6 +441,9 @@ if (!info || !info->ats_enabled) return; + if (pci_dev_is_disconnected(to_pci_dev(dev))) + return; + sid = info->bus << 8 | info->devfn; qdep = info->ats_qdep; pfsid = info->pfsid; @@ -499,8 +509,16 @@ } #ifdef CONFIG_X86 - if (cpu_feature_enabled(X86_FEATURE_LA57)) - pasid_set_flpm(pte, 1); + /* Both CPU and IOMMU paging mode need to match */ + if (cpu_feature_enabled(X86_FEATURE_LA57)) { + if (cap_5lp_support(iommu->cap)) { + pasid_set_flpm(pte, 1); + } else { + pr_err("VT-d has no 5-level paging support for CPU\n"); + pasid_clear_entry(pte); + return -EINVAL; + } + } #endif /* CONFIG_X86 */ pasid_set_domain_id(pte, did); --- linux-oracle-5.4.0.orig/drivers/iommu/intel-svm.c +++ linux-oracle-5.4.0/drivers/iommu/intel-svm.c @@ -99,16 +99,14 @@ return 0; } -static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev, - unsigned long address, unsigned long pages, int ih) +static void __flush_svm_range_dev(struct intel_svm *svm, + struct intel_svm_dev *sdev, + unsigned long address, + unsigned long pages, int ih) { struct qi_desc desc; - /* - * Do PASID granu IOTLB invalidation if page selective capability is - * not available. - */ - if (pages == -1 || !cap_pgsel_inv(svm->iommu->cap)) { + if (pages == -1) { desc.qw0 = QI_EIOTLB_PASID(svm->pasid) | QI_EIOTLB_DID(sdev->did) | QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) | @@ -155,6 +153,22 @@ } } +static void intel_flush_svm_range_dev(struct intel_svm *svm, + struct intel_svm_dev *sdev, + unsigned long address, + unsigned long pages, int ih) +{ + unsigned long shift = ilog2(__roundup_pow_of_two(pages)); + unsigned long align = (1ULL << (VTD_PAGE_SHIFT + shift)); + unsigned long start = ALIGN_DOWN(address, align); + unsigned long end = ALIGN(address + (pages << VTD_PAGE_SHIFT), align); + + while (start < end) { + __flush_svm_range_dev(svm, sdev, start, align >> VTD_PAGE_SHIFT, ih); + start += align; + } +} + static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address, unsigned long pages, int ih) { @@ -321,7 +335,7 @@ /* Do not use PASID 0 in caching mode (virtualised IOMMU) */ ret = intel_pasid_alloc_id(svm, !!cap_caching_mode(iommu->cap), - pasid_max - 1, GFP_KERNEL); + pasid_max, GFP_KERNEL); if (ret < 0) { kfree(svm); kfree(sdev); @@ -506,7 +520,7 @@ u64 priv_data[2]; }; -#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x10) +#define PRQ_RING_MASK ((0x1000 << PRQ_ORDER) - 0x20) static bool access_error(struct vm_area_struct *vma, struct page_req_dsc *req) { @@ -587,14 +601,15 @@ * any faults on kernel addresses. */ if (!svm->mm) goto bad_req; - /* If the mm is already defunct, don't handle faults. */ - if (!mmget_not_zero(svm->mm)) - goto bad_req; /* If address is not canonical, return invalid response */ if (!is_canonical_address(address)) goto bad_req; + /* If the mm is already defunct, don't handle faults. */ + if (!mmget_not_zero(svm->mm)) + goto bad_req; + down_read(&svm->mm->mmap_sem); vma = find_extend_vma(svm->mm, address); if (!vma || address < vma->vm_start) @@ -649,7 +664,7 @@ resp.qw0 = QI_PGRP_PASID(req->pasid) | QI_PGRP_DID(req->rid) | QI_PGRP_PASID_P(req->pasid_present) | - QI_PGRP_PDP(req->pasid_present) | + QI_PGRP_PDP(req->priv_data_present) | QI_PGRP_RESP_CODE(result) | QI_PGRP_RESP_TYPE; resp.qw1 = QI_PGRP_IDX(req->prg_index) | @@ -658,11 +673,10 @@ if (req->priv_data_present) memcpy(&resp.qw2, req->priv_data, sizeof(req->priv_data)); + resp.qw2 = 0; + resp.qw3 = 0; + qi_submit_sync(&resp, iommu); } - resp.qw2 = 0; - resp.qw3 = 0; - qi_submit_sync(&resp, iommu); - head = (head + sizeof(*req)) & PRQ_RING_MASK; } --- linux-oracle-5.4.0.orig/drivers/iommu/intel_irq_remapping.c +++ linux-oracle-5.4.0/drivers/iommu/intel_irq_remapping.c @@ -507,12 +507,18 @@ /* Enable interrupt-remapping */ iommu->gcmd |= DMA_GCMD_IRE; - iommu->gcmd &= ~DMA_GCMD_CFI; /* Block compatibility-format MSIs */ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); - IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_IRES), sts); + /* Block compatibility-format MSIs */ + if (sts & DMA_GSTS_CFIS) { + iommu->gcmd &= ~DMA_GCMD_CFI; + writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); + IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, + readl, !(sts & DMA_GSTS_CFIS), sts); + } + /* * With CFI clear in the Global Command register, we should be * protected from dangerous (i.e. compatibility) interrupts @@ -563,10 +569,9 @@ 0, INTR_REMAP_TABLE_ENTRIES, fn, &intel_ir_domain_ops, iommu); - irq_domain_free_fwnode(fn); if (!iommu->ir_domain) { pr_err("IR%d: failed to allocate irqdomain\n", iommu->seq_id); - goto out_free_bitmap; + goto out_free_fwnode; } iommu->ir_msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain, @@ -590,7 +595,7 @@ if (dmar_enable_qi(iommu)) { pr_err("Failed to enable queued invalidation\n"); - goto out_free_bitmap; + goto out_free_ir_domain; } } @@ -614,6 +619,14 @@ return 0; +out_free_ir_domain: + if (iommu->ir_msi_domain) + irq_domain_remove(iommu->ir_msi_domain); + iommu->ir_msi_domain = NULL; + irq_domain_remove(iommu->ir_domain); + iommu->ir_domain = NULL; +out_free_fwnode: + irq_domain_free_fwnode(fn); out_free_bitmap: bitmap_free(bitmap); out_free_pages: @@ -628,13 +641,21 @@ static void intel_teardown_irq_remapping(struct intel_iommu *iommu) { + struct fwnode_handle *fn; + if (iommu && iommu->ir_table) { if (iommu->ir_msi_domain) { + fn = iommu->ir_msi_domain->fwnode; + irq_domain_remove(iommu->ir_msi_domain); + irq_domain_free_fwnode(fn); iommu->ir_msi_domain = NULL; } if (iommu->ir_domain) { + fn = iommu->ir_domain->fwnode; + irq_domain_remove(iommu->ir_domain); + irq_domain_free_fwnode(fn); iommu->ir_domain = NULL; } free_pages((unsigned long)iommu->ir_table->base, @@ -1386,6 +1407,8 @@ irq_data = irq_domain_get_irq_data(domain, virq + i); irq_cfg = irqd_cfg(irq_data); if (!irq_data || !irq_cfg) { + if (!i) + kfree(data); ret = -EINVAL; goto out_free_data; } --- linux-oracle-5.4.0.orig/drivers/iommu/io-pgtable-arm-v7s.c +++ linux-oracle-5.4.0/drivers/iommu/io-pgtable-arm-v7s.c @@ -244,13 +244,17 @@ __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size)); else if (lvl == 2) table = kmem_cache_zalloc(data->l2_tables, gfp); + + if (!table) + return NULL; + phys = virt_to_phys(table); if (phys != (arm_v7s_iopte)phys) { /* Doesn't fit in PTE */ dev_err(dev, "Page table does not fit in PTE: %pa", &phys); goto out_free; } - if (table && !cfg->coherent_walk) { + if (!cfg->coherent_walk) { dma = dma_map_single(dev, table, size, DMA_TO_DEVICE); if (dma_mapping_error(dev, dma)) goto out_free; --- linux-oracle-5.4.0.orig/drivers/iommu/io-pgtable-arm.c +++ linux-oracle-5.4.0/drivers/iommu/io-pgtable-arm.c @@ -351,11 +351,12 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, arm_lpae_iopte *ptep, arm_lpae_iopte curr, - struct io_pgtable_cfg *cfg) + struct arm_lpae_io_pgtable *data) { arm_lpae_iopte old, new; + struct io_pgtable_cfg *cfg = &data->iop.cfg; - new = __pa(table) | ARM_LPAE_PTE_TYPE_TABLE; + new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE; if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) new |= ARM_LPAE_PTE_NSTABLE; @@ -406,7 +407,7 @@ if (!cptep) return -ENOMEM; - pte = arm_lpae_install_table(cptep, ptep, 0, cfg); + pte = arm_lpae_install_table(cptep, ptep, 0, data); if (pte) __arm_lpae_free_pages(cptep, tblsz, cfg); } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { @@ -575,7 +576,7 @@ __arm_lpae_init_pte(data, blk_paddr, pte, lvl, &tablep[i]); } - pte = arm_lpae_install_table(tablep, ptep, blk_pte, cfg); + pte = arm_lpae_install_table(tablep, ptep, blk_pte, data); if (pte != blk_pte) { __arm_lpae_free_pages(tablep, tablesz, cfg); /* --- linux-oracle-5.4.0.orig/drivers/iommu/iommu.c +++ linux-oracle-5.4.0/drivers/iommu/iommu.c @@ -312,8 +312,8 @@ list_for_each_entry_safe(iter, tmp, regions, list) { phys_addr_t top_end, iter_end = iter->start + iter->length - 1; - /* no merge needed on elements of different types than @nr */ - if (iter->type != nr->type) { + /* no merge needed on elements of different types than @new */ + if (iter->type != new->type) { list_move_tail(&iter->list, &stack); continue; } @@ -492,7 +492,7 @@ NULL, "%d", group->id); if (ret) { ida_simple_remove(&iommu_group_ida, group->id); - kfree(group); + kobject_put(&group->kobj); return ERR_PTR(ret); } @@ -751,6 +751,7 @@ mutex_unlock(&group->mutex); dev->iommu_group = NULL; kobject_put(group->devices_kobj); + sysfs_remove_link(group->devices_kobj, device->name); err_free_name: kfree(device->name); err_remove_link: @@ -774,6 +775,9 @@ struct iommu_group *group = dev->iommu_group; struct group_device *tmp_device, *device = NULL; + if (!group) + return; + dev_info(dev, "Removing from iommu group %d\n", group->id); /* Pre-notify listeners that a device is being removed. */ @@ -1854,8 +1858,8 @@ return pgsize; } -int iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) +int __iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { const struct iommu_ops *ops = domain->ops; unsigned long orig_iova = iova; @@ -1892,8 +1896,8 @@ pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", iova, &paddr, pgsize); + ret = ops->map(domain, iova, paddr, pgsize, prot, gfp); - ret = ops->map(domain, iova, paddr, pgsize, prot); if (ret) break; @@ -1913,8 +1917,22 @@ return ret; } + +int iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot) +{ + might_sleep(); + return __iommu_map(domain, iova, paddr, size, prot, GFP_KERNEL); +} EXPORT_SYMBOL_GPL(iommu_map); +int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova, + phys_addr_t paddr, size_t size, int prot) +{ + return __iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC); +} +EXPORT_SYMBOL_GPL(iommu_map_atomic); + static size_t __iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size, struct iommu_iotlb_gather *iotlb_gather) @@ -1991,8 +2009,9 @@ } EXPORT_SYMBOL_GPL(iommu_unmap_fast); -size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, - struct scatterlist *sg, unsigned int nents, int prot) +size_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot, + gfp_t gfp) { size_t len = 0, mapped = 0; phys_addr_t start; @@ -2003,7 +2022,9 @@ phys_addr_t s_phys = sg_phys(sg); if (len && s_phys != start + len) { - ret = iommu_map(domain, iova + mapped, start, len, prot); + ret = __iommu_map(domain, iova + mapped, start, + len, prot, gfp); + if (ret) goto out_err; @@ -2031,8 +2052,22 @@ return 0; } + +size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot) +{ + might_sleep(); + return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_KERNEL); +} EXPORT_SYMBOL_GPL(iommu_map_sg); +size_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot) +{ + return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC); +} +EXPORT_SYMBOL_GPL(iommu_map_sg_atomic); + int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr, phys_addr_t paddr, u64 size, int prot) { @@ -2221,13 +2256,13 @@ goto out; } - iommu_group_create_direct_mappings(group, dev); - /* Make the domain the default for this group */ if (group->default_domain) iommu_domain_free(group->default_domain); group->default_domain = domain; + iommu_group_create_direct_mappings(group, dev); + dev_info(dev, "Using iommu %s mapping\n", type == IOMMU_DOMAIN_DMA ? "dma" : "direct"); --- linux-oracle-5.4.0.orig/drivers/iommu/iova.c +++ linux-oracle-5.4.0/drivers/iommu/iova.c @@ -64,8 +64,7 @@ if (!has_iova_flush_queue(iovad)) return; - if (timer_pending(&iovad->fq_timer)) - del_timer(&iovad->fq_timer); + del_timer_sync(&iovad->fq_timer); fq_destroy_all_entries(iovad); @@ -139,10 +138,11 @@ cached_iova = rb_entry(iovad->cached32_node, struct iova, node); if (free == cached_iova || (free->pfn_hi < iovad->dma_32bit_pfn && - free->pfn_lo >= cached_iova->pfn_lo)) { + free->pfn_lo >= cached_iova->pfn_lo)) iovad->cached32_node = rb_next(&free->node); + + if (free->pfn_lo < iovad->dma_32bit_pfn) iovad->max32_alloc_size = iovad->dma_32bit_pfn; - } cached_iova = rb_entry(iovad->cached_node, struct iova, node); if (free->pfn_lo >= cached_iova->pfn_lo) @@ -233,7 +233,7 @@ struct iova *alloc_iova_mem(void) { - return kmem_cache_alloc(iova_cache, GFP_ATOMIC); + return kmem_cache_zalloc(iova_cache, GFP_ATOMIC | __GFP_NOWARN); } EXPORT_SYMBOL(alloc_iova_mem); @@ -811,7 +811,9 @@ for (i = 0 ; i < mag->size; ++i) { struct iova *iova = private_find_iova(iovad, mag->pfns[i]); - BUG_ON(!iova); + if (WARN_ON(!iova)) + continue; + private_free_iova(iovad, iova); } --- linux-oracle-5.4.0.orig/drivers/iommu/ipmmu-vmsa.c +++ linux-oracle-5.4.0/drivers/iommu/ipmmu-vmsa.c @@ -724,7 +724,7 @@ } static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); @@ -1061,7 +1061,9 @@ bitmap_zero(mmu->ctx, IPMMU_CTX_MAX); mmu->features = of_device_get_match_data(&pdev->dev); memset(mmu->utlb_ctx, IPMMU_CTX_INVALID, mmu->features->num_utlbs); - dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); + ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40)); + if (ret) + return ret; /* Map I/O memory and request IRQ. */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); --- linux-oracle-5.4.0.orig/drivers/iommu/msm_iommu.c +++ linux-oracle-5.4.0/drivers/iommu/msm_iommu.c @@ -504,7 +504,7 @@ } static int msm_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t pa, size_t len, int prot) + phys_addr_t pa, size_t len, int prot, gfp_t gfp) { struct msm_priv *priv = to_msm_priv(domain); unsigned long flags; @@ -636,16 +636,19 @@ static int qcom_iommu_of_xlate(struct device *dev, struct of_phandle_args *spec) { - struct msm_iommu_dev *iommu; + struct msm_iommu_dev *iommu = NULL, *iter; unsigned long flags; int ret = 0; spin_lock_irqsave(&msm_iommu_lock, flags); - list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) - if (iommu->dev->of_node == spec->np) + list_for_each_entry(iter, &qcom_iommu_devices, dev_node) { + if (iter->dev->of_node == spec->np) { + iommu = iter; break; + } + } - if (!iommu || iommu->dev->of_node != spec->np) { + if (!iommu) { ret = -ENODEV; goto fail; } --- linux-oracle-5.4.0.orig/drivers/iommu/mtk_iommu.c +++ linux-oracle-5.4.0/drivers/iommu/mtk_iommu.c @@ -219,22 +219,37 @@ static void mtk_iommu_tlb_flush_walk(unsigned long iova, size_t size, size_t granule, void *cookie) { + struct mtk_iommu_data *data = cookie; + unsigned long flags; + + spin_lock_irqsave(&data->tlb_lock, flags); mtk_iommu_tlb_add_flush_nosync(iova, size, granule, false, cookie); mtk_iommu_tlb_sync(cookie); + spin_unlock_irqrestore(&data->tlb_lock, flags); } static void mtk_iommu_tlb_flush_leaf(unsigned long iova, size_t size, size_t granule, void *cookie) { + struct mtk_iommu_data *data = cookie; + unsigned long flags; + + spin_lock_irqsave(&data->tlb_lock, flags); mtk_iommu_tlb_add_flush_nosync(iova, size, granule, true, cookie); mtk_iommu_tlb_sync(cookie); + spin_unlock_irqrestore(&data->tlb_lock, flags); } static void mtk_iommu_tlb_flush_page_nosync(struct iommu_iotlb_gather *gather, unsigned long iova, size_t granule, void *cookie) { + struct mtk_iommu_data *data = cookie; + unsigned long flags; + + spin_lock_irqsave(&data->tlb_lock, flags); mtk_iommu_tlb_add_flush_nosync(iova, granule, granule, true, cookie); + spin_unlock_irqrestore(&data->tlb_lock, flags); } static const struct iommu_flush_ops mtk_iommu_flush_ops = { @@ -412,7 +427,7 @@ } static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); @@ -447,13 +462,18 @@ static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain) { - mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data()); + mtk_iommu_tlb_flush_all(mtk_iommu_get_m4u_data()); } static void mtk_iommu_iotlb_sync(struct iommu_domain *domain, struct iommu_iotlb_gather *gather) { - mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data()); + struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); + unsigned long flags; + + spin_lock_irqsave(&data->tlb_lock, flags); + mtk_iommu_tlb_sync(data); + spin_unlock_irqrestore(&data->tlb_lock, flags); } static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, @@ -733,6 +753,7 @@ if (ret) return ret; + spin_lock_init(&data->tlb_lock); list_add_tail(&data->list, &m4ulist); if (!iommu_present(&platform_bus_type)) @@ -748,8 +769,7 @@ iommu_device_sysfs_remove(&data->iommu); iommu_device_unregister(&data->iommu); - if (iommu_present(&platform_bus_type)) - bus_set_iommu(&platform_bus_type, NULL); + list_del(&data->list); clk_disable_unprepare(data->bclk); devm_free_irq(&pdev->dev, data->irq, data); --- linux-oracle-5.4.0.orig/drivers/iommu/mtk_iommu.h +++ linux-oracle-5.4.0/drivers/iommu/mtk_iommu.h @@ -58,6 +58,7 @@ struct iommu_group *m4u_group; bool enable_4GB; bool tlb_flush_active; + spinlock_t tlb_lock; /* lock for tlb range flush */ struct iommu_device iommu; const struct mtk_iommu_plat_data *plat_data; --- linux-oracle-5.4.0.orig/drivers/iommu/mtk_iommu_v1.c +++ linux-oracle-5.4.0/drivers/iommu/mtk_iommu_v1.c @@ -295,7 +295,7 @@ } static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT; @@ -626,18 +626,34 @@ ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, dev_name(&pdev->dev)); if (ret) - return ret; + goto out_clk_unprepare; iommu_device_set_ops(&data->iommu, &mtk_iommu_ops); ret = iommu_device_register(&data->iommu); if (ret) - return ret; + goto out_sysfs_remove; + + if (!iommu_present(&platform_bus_type)) { + ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); + if (ret) + goto out_dev_unreg; + } - if (!iommu_present(&platform_bus_type)) - bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); + ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); + if (ret) + goto out_bus_set_null; + return ret; - return component_master_add_with_match(dev, &mtk_iommu_com_ops, match); +out_bus_set_null: + bus_set_iommu(&platform_bus_type, NULL); +out_dev_unreg: + iommu_device_unregister(&data->iommu); +out_sysfs_remove: + iommu_device_sysfs_remove(&data->iommu); +out_clk_unprepare: + clk_disable_unprepare(data->bclk); + return ret; } static int mtk_iommu_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/iommu/of_iommu.c +++ linux-oracle-5.4.0/drivers/iommu/of_iommu.c @@ -121,7 +121,7 @@ struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", + err = of_map_id(info->np, alias, "iommu-map", "iommu-map-mask", &iommu_spec.np, iommu_spec.args); if (err) return err == -ENODEV ? NO_IOMMU : err; @@ -137,7 +137,7 @@ struct of_phandle_args iommu_spec = { .args_count = 1 }; int err; - err = of_map_rid(master_np, mc_dev->icid, "iommu-map", + err = of_map_id(master_np, mc_dev->icid, "iommu-map", "iommu-map-mask", &iommu_spec.np, iommu_spec.args); if (err) --- linux-oracle-5.4.0.orig/drivers/iommu/omap-iommu-debug.c +++ linux-oracle-5.4.0/drivers/iommu/omap-iommu-debug.c @@ -32,12 +32,12 @@ ssize_t bytes; \ const char *str = "%20s: %08x\n"; \ const int maxcol = 32; \ - bytes = snprintf(p, maxcol, str, __stringify(name), \ + if (len < maxcol) \ + goto out; \ + bytes = scnprintf(p, maxcol, str, __stringify(name), \ iommu_read_reg(obj, MMU_##name)); \ p += bytes; \ len -= bytes; \ - if (len < maxcol) \ - goto out; \ } while (0) static ssize_t @@ -98,8 +98,11 @@ mutex_lock(&iommu_debug_lock); bytes = omap_iommu_dump_ctx(obj, p, count); + if (bytes < 0) + goto err; bytes = simple_read_from_buffer(userbuf, count, ppos, buf, bytes); +err: mutex_unlock(&iommu_debug_lock); kfree(buf); --- linux-oracle-5.4.0.orig/drivers/iommu/omap-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/omap-iommu.c @@ -1339,7 +1339,7 @@ } static int omap_iommu_map(struct iommu_domain *domain, unsigned long da, - phys_addr_t pa, size_t bytes, int prot) + phys_addr_t pa, size_t bytes, int prot, gfp_t gfp) { struct omap_iommu_domain *omap_domain = to_omap_domain(domain); struct device *dev = omap_domain->dev; --- linux-oracle-5.4.0.orig/drivers/iommu/qcom_iommu.c +++ linux-oracle-5.4.0/drivers/iommu/qcom_iommu.c @@ -345,21 +345,19 @@ { struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); - if (WARN_ON(qcom_domain->iommu)) /* forgot to detach? */ - return; - iommu_put_dma_cookie(domain); - /* NOTE: unmap can be called after client device is powered off, - * for example, with GPUs or anything involving dma-buf. So we - * cannot rely on the device_link. Make sure the IOMMU is on to - * avoid unclocked accesses in the TLB inv path: - */ - pm_runtime_get_sync(qcom_domain->iommu->dev); - - free_io_pgtable_ops(qcom_domain->pgtbl_ops); - - pm_runtime_put_sync(qcom_domain->iommu->dev); + if (qcom_domain->iommu) { + /* + * NOTE: unmap can be called after client device is powered + * off, for example, with GPUs or anything involving dma-buf. + * So we cannot rely on the device_link. Make sure the IOMMU + * is on to avoid unclocked accesses in the TLB inv path: + */ + pm_runtime_get_sync(qcom_domain->iommu->dev); + free_io_pgtable_ops(qcom_domain->pgtbl_ops); + pm_runtime_put_sync(qcom_domain->iommu->dev); + } kfree(qcom_domain); } @@ -405,7 +403,7 @@ struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain); unsigned i; - if (!qcom_domain->iommu) + if (WARN_ON(!qcom_domain->iommu)) return; pm_runtime_get_sync(qcom_iommu->dev); @@ -418,12 +416,10 @@ ctx->domain = NULL; } pm_runtime_put_sync(qcom_iommu->dev); - - qcom_domain->iommu = NULL; } static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { int ret; unsigned long flags; @@ -789,9 +785,12 @@ { struct device_node *child; - for_each_child_of_node(qcom_iommu->dev->of_node, child) - if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) + for_each_child_of_node(qcom_iommu->dev->of_node, child) { + if (of_device_is_compatible(child, "qcom,msm-iommu-v1-sec")) { + of_node_put(child); return true; + } + } return false; } @@ -818,8 +817,11 @@ qcom_iommu->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) + if (res) { qcom_iommu->local_base = devm_ioremap_resource(dev, res); + if (IS_ERR(qcom_iommu->local_base)) + return PTR_ERR(qcom_iommu->local_base); + } qcom_iommu->iface_clk = devm_clk_get(dev, "iface"); if (IS_ERR(qcom_iommu->iface_clk)) { --- linux-oracle-5.4.0.orig/drivers/iommu/rockchip-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/rockchip-iommu.c @@ -758,7 +758,7 @@ } static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct rk_iommu_domain *rk_domain = to_rk_domain(domain); unsigned long flags; @@ -980,13 +980,13 @@ if (!dma_dev) return NULL; - rk_domain = devm_kzalloc(dma_dev, sizeof(*rk_domain), GFP_KERNEL); + rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL); if (!rk_domain) return NULL; if (type == IOMMU_DOMAIN_DMA && iommu_get_dma_cookie(&rk_domain->domain)) - return NULL; + goto err_free_domain; /* * rk32xx iommus use a 2 level pagetable. @@ -1021,6 +1021,8 @@ err_put_cookie: if (type == IOMMU_DOMAIN_DMA) iommu_put_dma_cookie(&rk_domain->domain); +err_free_domain: + kfree(rk_domain); return NULL; } @@ -1049,6 +1051,7 @@ if (domain->type == IOMMU_DOMAIN_DMA) iommu_put_dma_cookie(&rk_domain->domain); + kfree(rk_domain); } static int rk_iommu_add_device(struct device *dev) @@ -1227,18 +1230,20 @@ for (i = 0; i < iommu->num_irq; i++) { int irq = platform_get_irq(pdev, i); - if (irq < 0) - return irq; + if (irq < 0) { + err = irq; + goto err_pm_disable; + } err = devm_request_irq(iommu->dev, irq, rk_iommu_irq, IRQF_SHARED, dev_name(dev), iommu); - if (err) { - pm_runtime_disable(dev); - goto err_remove_sysfs; - } + if (err) + goto err_pm_disable; } return 0; +err_pm_disable: + pm_runtime_disable(dev); err_remove_sysfs: iommu_device_sysfs_remove(&iommu->iommu); err_put_group: --- linux-oracle-5.4.0.orig/drivers/iommu/s390-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/s390-iommu.c @@ -87,7 +87,7 @@ struct device *dev) { struct s390_domain *s390_domain = to_s390_domain(domain); - struct zpci_dev *zdev = to_pci_dev(dev)->sysdata; + struct zpci_dev *zdev = to_zpci_dev(dev); struct s390_domain_device *domain_device; unsigned long flags; int rc; @@ -139,7 +139,7 @@ struct device *dev) { struct s390_domain *s390_domain = to_s390_domain(domain); - struct zpci_dev *zdev = to_pci_dev(dev)->sysdata; + struct zpci_dev *zdev = to_zpci_dev(dev); struct s390_domain_device *domain_device, *tmp; unsigned long flags; int found = 0; @@ -169,7 +169,7 @@ static int s390_iommu_add_device(struct device *dev) { struct iommu_group *group = iommu_group_get_for_dev(dev); - struct zpci_dev *zdev = to_pci_dev(dev)->sysdata; + struct zpci_dev *zdev = to_zpci_dev(dev); if (IS_ERR(group)) return PTR_ERR(group); @@ -182,7 +182,7 @@ static void s390_iommu_remove_device(struct device *dev) { - struct zpci_dev *zdev = to_pci_dev(dev)->sysdata; + struct zpci_dev *zdev = to_zpci_dev(dev); struct iommu_domain *domain; /* @@ -265,7 +265,7 @@ } static int s390_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct s390_domain *s390_domain = to_s390_domain(domain); int flags = ZPCI_PTE_VALID, rc = 0; --- linux-oracle-5.4.0.orig/drivers/iommu/tegra-gart.c +++ linux-oracle-5.4.0/drivers/iommu/tegra-gart.c @@ -178,7 +178,7 @@ } static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t pa, size_t bytes, int prot) + phys_addr_t pa, size_t bytes, int prot, gfp_t gfp) { struct gart_device *gart = gart_handle; int ret; --- linux-oracle-5.4.0.orig/drivers/iommu/tegra-smmu.c +++ linux-oracle-5.4.0/drivers/iommu/tegra-smmu.c @@ -159,9 +159,9 @@ return (addr & smmu->pfn_mask) == addr; } -static dma_addr_t smmu_pde_to_dma(u32 pde) +static dma_addr_t smmu_pde_to_dma(struct tegra_smmu *smmu, u32 pde) { - return pde << 12; + return (dma_addr_t)(pde & smmu->pfn_mask) << 12; } static void smmu_flush_ptc_all(struct tegra_smmu *smmu) @@ -549,6 +549,7 @@ dma_addr_t *dmap) { unsigned int pd_index = iova_pd_index(iova); + struct tegra_smmu *smmu = as->smmu; struct page *pt_page; u32 *pd; @@ -557,7 +558,7 @@ return NULL; pd = page_address(as->pd); - *dmap = smmu_pde_to_dma(pd[pd_index]); + *dmap = smmu_pde_to_dma(smmu, pd[pd_index]); return tegra_smmu_pte_offset(pt_page, iova); } @@ -599,7 +600,7 @@ } else { u32 *pd = page_address(as->pd); - *dmap = smmu_pde_to_dma(pd[pde]); + *dmap = smmu_pde_to_dma(smmu, pd[pde]); } return tegra_smmu_pte_offset(as->pts[pde], iova); @@ -624,7 +625,7 @@ if (--as->count[pde] == 0) { struct tegra_smmu *smmu = as->smmu; u32 *pd = page_address(as->pd); - dma_addr_t pte_dma = smmu_pde_to_dma(pd[pde]); + dma_addr_t pte_dma = smmu_pde_to_dma(smmu, pd[pde]); tegra_smmu_set_pde(as, iova, 0); @@ -650,7 +651,7 @@ } static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { struct tegra_smmu_as *as = to_smmu_as(domain); dma_addr_t pte_dma; --- linux-oracle-5.4.0.orig/drivers/iommu/virtio-iommu.c +++ linux-oracle-5.4.0/drivers/iommu/virtio-iommu.c @@ -454,7 +454,7 @@ if (!region) return -ENOMEM; - list_add(&vdev->resv_regions, ®ion->list); + list_add(®ion->list, &vdev->resv_regions); return 0; } @@ -614,18 +614,20 @@ int ret; struct viommu_domain *vdomain = to_viommu_domain(domain); - vdomain->viommu = viommu; - vdomain->map_flags = viommu->map_flags; + ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain, + viommu->last_domain, GFP_KERNEL); + if (ret < 0) + return ret; + + vdomain->id = (unsigned int)ret; domain->pgsize_bitmap = viommu->pgsize_bitmap; domain->geometry = viommu->geometry; - ret = ida_alloc_range(&viommu->domain_ids, viommu->first_domain, - viommu->last_domain, GFP_KERNEL); - if (ret >= 0) - vdomain->id = (unsigned int)ret; + vdomain->map_flags = viommu->map_flags; + vdomain->viommu = viommu; - return ret > 0 ? 0 : ret; + return 0; } static void viommu_domain_free(struct iommu_domain *domain) @@ -713,7 +715,7 @@ } static int viommu_map(struct iommu_domain *domain, unsigned long iova, - phys_addr_t paddr, size_t size, int prot) + phys_addr_t paddr, size_t size, int prot, gfp_t gfp) { int ret; u32 flags; --- linux-oracle-5.4.0.orig/drivers/ipack/carriers/tpci200.c +++ linux-oracle-5.4.0/drivers/ipack/carriers/tpci200.c @@ -91,16 +91,13 @@ free_irq(tpci200->info->pdev->irq, (void *) tpci200); pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); - pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); pci_disable_device(tpci200->info->pdev); - pci_dev_put(tpci200->info->pdev); } static void tpci200_enable_irq(struct tpci200_board *tpci200, @@ -259,7 +256,7 @@ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_disable_pci; + goto err_disable_device; } /* Request IO ID INT space (Bar 3) */ @@ -271,7 +268,7 @@ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ip_space; + goto err_ip_interface_bar; } /* Request MEM8 space (Bar 5) */ @@ -282,7 +279,7 @@ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; + goto err_io_id_int_spaces_bar; } /* Request MEM16 space (Bar 4) */ @@ -293,7 +290,7 @@ "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_mem8_space; + goto err_mem8_space_bar; } /* Map internal tpci200 driver user space */ @@ -306,7 +303,8 @@ "(bn 0x%X, sn 0x%X) failed to map driver user space!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_mem8_space; + res = -ENOMEM; + goto err_mem16_space_bar; } /* Initialize lock that protects interface_regs */ @@ -345,18 +343,22 @@ "(bn 0x%X, sn 0x%X) unable to register IRQ !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; + goto err_interface_regs; } return 0; -out_release_mem8_space: +err_interface_regs: + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); +err_mem16_space_bar: + pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); +err_mem8_space_bar: pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); -out_release_ioid_int_space: +err_io_id_int_spaces_bar: pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); -out_release_ip_space: +err_ip_interface_bar: pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); -out_disable_pci: +err_disable_device: pci_disable_device(tpci200->info->pdev); return res; } @@ -528,7 +530,7 @@ tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); if (!tpci200->info) { ret = -ENOMEM; - goto out_err_info; + goto err_tpci200; } pci_dev_get(pdev); @@ -539,7 +541,7 @@ if (ret) { dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); ret = -EBUSY; - goto out_err_pci_request; + goto err_tpci200_info; } tpci200->info->cfg_regs = ioremap_nocache( pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), @@ -547,7 +549,7 @@ if (!tpci200->info->cfg_regs) { dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); ret = -EFAULT; - goto out_err_ioremap; + goto err_request_region; } /* Disable byte swapping for 16 bit IP module access. This will ensure @@ -570,7 +572,7 @@ if (ret) { dev_err(&pdev->dev, "error during tpci200 install\n"); ret = -ENODEV; - goto out_err_install; + goto err_cfg_regs; } /* Register the carrier in the industry pack bus driver */ @@ -582,7 +584,7 @@ dev_err(&pdev->dev, "error registering the carrier on ipack driver\n"); ret = -EFAULT; - goto out_err_bus_register; + goto err_tpci200_install; } /* save the bus number given by ipack to logging purpose */ @@ -593,16 +595,16 @@ tpci200_create_device(tpci200, i); return 0; -out_err_bus_register: +err_tpci200_install: tpci200_uninstall(tpci200); -out_err_install: - iounmap(tpci200->info->cfg_regs); -out_err_ioremap: +err_cfg_regs: + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); +err_request_region: pci_release_region(pdev, TPCI200_CFG_MEM_BAR); -out_err_pci_request: - pci_dev_put(pdev); +err_tpci200_info: kfree(tpci200->info); -out_err_info: + pci_dev_put(pdev); +err_tpci200: kfree(tpci200); return ret; } @@ -612,6 +614,12 @@ ipack_bus_unregister(tpci200->info->ipack_bus); tpci200_uninstall(tpci200); + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); + + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); + + pci_dev_put(tpci200->info->pdev); + kfree(tpci200->info); kfree(tpci200); } --- linux-oracle-5.4.0.orig/drivers/ipack/devices/ipoctal.c +++ linux-oracle-5.4.0/drivers/ipack/devices/ipoctal.c @@ -35,6 +35,7 @@ unsigned int pointer_read; unsigned int pointer_write; struct tty_port tty_port; + bool tty_registered; union scc2698_channel __iomem *regs; union scc2698_block __iomem *block_regs; unsigned int board_id; @@ -83,22 +84,34 @@ return 0; } -static int ipoctal_open(struct tty_struct *tty, struct file *file) +static int ipoctal_install(struct tty_driver *driver, struct tty_struct *tty) { struct ipoctal_channel *channel = dev_get_drvdata(tty->dev); struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); - int err; - - tty->driver_data = channel; + int res; if (!ipack_get_carrier(ipoctal->dev)) return -EBUSY; - err = tty_port_open(&channel->tty_port, tty, file); - if (err) - ipack_put_carrier(ipoctal->dev); + res = tty_standard_install(driver, tty); + if (res) + goto err_put_carrier; + + tty->driver_data = channel; + + return 0; + +err_put_carrier: + ipack_put_carrier(ipoctal->dev); + + return res; +} + +static int ipoctal_open(struct tty_struct *tty, struct file *file) +{ + struct ipoctal_channel *channel = tty->driver_data; - return err; + return tty_port_open(&channel->tty_port, tty, file); } static void ipoctal_reset_stats(struct ipoctal_stats *stats) @@ -266,7 +279,6 @@ int res; int i; struct tty_driver *tty; - char name[20]; struct ipoctal_channel *channel; struct ipack_region *region; void __iomem *addr; @@ -357,8 +369,11 @@ /* Fill struct tty_driver with ipoctal data */ tty->owner = THIS_MODULE; tty->driver_name = KBUILD_MODNAME; - sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); - tty->name = name; + tty->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); + if (!tty->name) { + res = -ENOMEM; + goto err_put_driver; + } tty->major = 0; tty->minor_start = 0; @@ -374,8 +389,7 @@ res = tty_register_driver(tty); if (res) { dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); - put_tty_driver(tty); - return res; + goto err_free_name; } /* Save struct tty_driver for use it when uninstalling the device */ @@ -386,7 +400,9 @@ channel = &ipoctal->channel[i]; tty_port_init(&channel->tty_port); - tty_port_alloc_xmit_buf(&channel->tty_port); + res = tty_port_alloc_xmit_buf(&channel->tty_port); + if (res) + continue; channel->tty_port.ops = &ipoctal_tty_port_ops; ipoctal_reset_stats(&channel->stats); @@ -394,13 +410,15 @@ spin_lock_init(&channel->lock); channel->pointer_read = 0; channel->pointer_write = 0; - tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); + tty_dev = tty_port_register_device_attr(&channel->tty_port, tty, + i, NULL, channel, NULL); if (IS_ERR(tty_dev)) { dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port); continue; } - dev_set_drvdata(tty_dev, channel); + channel->tty_registered = true; } /* @@ -412,6 +430,13 @@ ipoctal_irq_handler, ipoctal); return 0; + +err_free_name: + kfree(tty->name); +err_put_driver: + put_tty_driver(tty); + + return res; } static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, @@ -652,6 +677,7 @@ static const struct tty_operations ipoctal_fops = { .ioctl = NULL, + .install = ipoctal_install, .open = ipoctal_open, .close = ipoctal_close, .write = ipoctal_write_tty, @@ -694,12 +720,17 @@ for (i = 0; i < NR_CHANNELS; i++) { struct ipoctal_channel *channel = &ipoctal->channel[i]; + + if (!channel->tty_registered) + continue; + tty_unregister_device(ipoctal->tty_drv, i); tty_port_free_xmit_buf(&channel->tty_port); tty_port_destroy(&channel->tty_port); } tty_unregister_driver(ipoctal->tty_drv); + kfree(ipoctal->tty_drv->name); put_tty_driver(ipoctal->tty_drv); kfree(ipoctal); } --- linux-oracle-5.4.0.orig/drivers/irqchip/Kconfig +++ linux-oracle-5.4.0/drivers/irqchip/Kconfig @@ -415,6 +415,7 @@ config GOLDFISH_PIC bool "Goldfish programmable interrupt controller" depends on MIPS && (GOLDFISH || COMPILE_TEST) + select GENERIC_IRQ_CHIP select IRQ_DOMAIN help Say yes here to enable Goldfish interrupt controller driver used @@ -483,8 +484,6 @@ If you wish to use interrupt aggregator irq resources managed by the TI System Controller, say Y here. Otherwise, say N. -endmenu - config SIFIVE_PLIC bool "SiFive Platform-Level Interrupt Controller" depends on RISCV @@ -496,3 +495,5 @@ interrupt sources are subordinate to the PLIC. If you don't know what to do here, say Y. + +endmenu --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-alpine-msi.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-alpine-msi.c @@ -165,8 +165,7 @@ return 0; err_sgi: - while (--i >= 0) - irq_domain_free_irqs_parent(domain, virq, i); + irq_domain_free_irqs_parent(domain, virq, i); alpine_msix_free_sgi(priv, sgi, nr_irqs); return err; } @@ -200,6 +199,7 @@ } gic_domain = irq_find_host(gic_node); + of_node_put(gic_node); if (!gic_domain) { pr_err("Failed to find the GIC domain\n"); return -ENXIO; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-armada-370-xp.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-armada-370-xp.c @@ -232,16 +232,12 @@ int hwirq, i; mutex_lock(&msi_used_lock); + hwirq = bitmap_find_free_region(msi_used, PCI_MSI_DOORBELL_NR, + order_base_2(nr_irqs)); + mutex_unlock(&msi_used_lock); - hwirq = bitmap_find_next_zero_area(msi_used, PCI_MSI_DOORBELL_NR, - 0, nr_irqs, 0); - if (hwirq >= PCI_MSI_DOORBELL_NR) { - mutex_unlock(&msi_used_lock); + if (hwirq < 0) return -ENOSPC; - } - - bitmap_set(msi_used, hwirq, nr_irqs); - mutex_unlock(&msi_used_lock); for (i = 0; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, hwirq + i, @@ -250,7 +246,7 @@ NULL, NULL); } - return hwirq; + return 0; } static void armada_370_xp_msi_free(struct irq_domain *domain, @@ -259,7 +255,7 @@ struct irq_data *d = irq_domain_get_irq_data(domain, virq); mutex_lock(&msi_used_lock); - bitmap_clear(msi_used, d->hwirq, nr_irqs); + bitmap_release_region(msi_used, d->hwirq, order_base_2(nr_irqs)); mutex_unlock(&msi_used_lock); } @@ -350,6 +346,10 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { + /* IRQs 0 and 1 cannot be mapped, they are handled internally */ + if (hw <= 1) + return -EINVAL; + armada_370_xp_irq_mask(irq_get_irq_data(virq)); if (!is_percpu_irq(hw)) writel(hw, per_cpu_int_base + @@ -396,7 +396,16 @@ static void armada_xp_mpic_perf_init(void) { - unsigned long cpuid = cpu_logical_map(smp_processor_id()); + unsigned long cpuid; + + /* + * This Performance Counter Overflow interrupt is specific for + * Armada 370 and XP. It is not available on Armada 375, 38x and 39x. + */ + if (!of_machine_is_compatible("marvell,armada-370-xp")) + return; + + cpuid = cpu_logical_map(smp_processor_id()); /* Enable Performance Counter Overflow interrupts */ writel(ARMADA_370_XP_INT_CAUSE_PERF(cpuid), --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-aspeed-i2c-ic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-aspeed-i2c-ic.c @@ -79,8 +79,8 @@ } i2c_ic->parent_irq = irq_of_parse_and_map(node, 0); - if (i2c_ic->parent_irq < 0) { - ret = i2c_ic->parent_irq; + if (!i2c_ic->parent_irq) { + ret = -EINVAL; goto err_iounmap; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-bcm6345-l1.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-bcm6345-l1.c @@ -82,6 +82,7 @@ }; struct bcm6345_l1_cpu { + struct bcm6345_l1_chip *intc; void __iomem *map_base; unsigned int parent_irq; u32 enable_cache[]; @@ -115,17 +116,11 @@ static void bcm6345_l1_irq_handle(struct irq_desc *desc) { - struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); - struct bcm6345_l1_cpu *cpu; + struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); + struct bcm6345_l1_chip *intc = cpu->intc; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int idx; -#ifdef CONFIG_SMP - cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; -#else - cpu = intc->cpus[0]; -#endif - chained_irq_enter(chip, desc); for (idx = 0; idx < intc->n_words; idx++) { @@ -140,7 +135,7 @@ for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { irq = irq_linear_revmap(intc->domain, base + hwirq); if (irq) - do_IRQ(irq); + generic_handle_irq(irq); else spurious_interrupt(); } @@ -257,6 +252,7 @@ if (!cpu) return -ENOMEM; + cpu->intc = intc; cpu->map_base = ioremap(res.start, sz); if (!cpu->map_base) return -ENOMEM; @@ -272,7 +268,7 @@ return -EINVAL; } irq_set_chained_handler_and_data(cpu->parent_irq, - bcm6345_l1_irq_handle, intc); + bcm6345_l1_irq_handle, cpu); return 0; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-bcm7038-l1.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-bcm7038-l1.c @@ -281,6 +281,10 @@ pr_err("failed to map parent interrupt %d\n", parent_irq); return -EINVAL; } + + if (of_property_read_bool(dn, "brcm,irq-can-wake")) + enable_irq_wake(parent_irq); + irq_set_chained_handler_and_data(parent_irq, bcm7038_l1_irq_handle, intc); --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-bcm7120-l2.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-bcm7120-l2.c @@ -268,7 +268,8 @@ flags |= IRQ_GC_BE_IO; ret = irq_alloc_domain_generic_chips(data->domain, IRQS_PER_WORD, 1, - dn->full_name, handle_level_irq, clr, 0, flags); + dn->full_name, handle_level_irq, clr, + IRQ_LEVEL, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-brcmstb-l2.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-brcmstb-l2.c @@ -2,7 +2,7 @@ /* * Generic Broadcom Set Top Box Level 2 Interrupt controller driver * - * Copyright (C) 2014-2017 Broadcom + * Copyright (C) 2014-2024 Broadcom */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -113,6 +113,9 @@ generic_handle_irq(irq_linear_revmap(b->domain, irq)); } while (status); out: + /* Don't ack parent before all device writes are done */ + wmb(); + chained_irq_exit(chip, desc); } @@ -161,6 +164,7 @@ *init_params) { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; struct brcmstb_l2_intc_data *data; struct irq_chip_type *ct; int ret; @@ -208,9 +212,12 @@ if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) flags |= IRQ_GC_BE_IO; + if (init_params->handler == handle_level_irq) + set |= IRQ_LEVEL; + /* Allocate a single Generic IRQ chip for this node */ ret = irq_alloc_domain_generic_chips(data->domain, 32, 1, - np->full_name, init_params->handler, clr, 0, flags); + np->full_name, init_params->handler, clr, set, flags); if (ret) { pr_err("failed to allocate generic irq chip\n"); goto out_free_domain; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-pm.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-pm.c @@ -104,7 +104,7 @@ pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) goto rpm_disable; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-realview.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-realview.c @@ -57,6 +57,7 @@ /* The PB11MPCore GIC needs to be configured in the syscon */ map = syscon_node_to_regmap(np); + of_node_put(np); if (!IS_ERR(map)) { /* new irq mode with no DCC */ regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-v2m.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-v2m.c @@ -441,12 +441,12 @@ ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res, 0); - if (ret) { - of_node_put(child); + if (ret) break; - } } + if (ret && child) + of_node_put(child); if (!ret) ret = gicv2m_allocate_domains(parent); if (ret) --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-v3-its.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-v3-its.c @@ -40,7 +40,6 @@ #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) #define ITS_FLAGS_WORKAROUND_CAVIUM_23144 (1ULL << 2) -#define ITS_FLAGS_SAVE_SUSPEND_STATE (1ULL << 3) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) #define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1) @@ -571,11 +570,11 @@ struct its_cmd_desc *desc) { its_encode_cmd(cmd, GITS_CMD_INVALL); - its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id); + its_encode_collection(cmd, desc->its_invall_cmd.col->col_id); its_fixup_cmd(cmd); - return NULL; + return desc->its_invall_cmd.col; } static struct its_vpe *its_build_vinvall_cmd(struct its_node *its, @@ -2581,6 +2580,7 @@ msi_alloc_info_t *info = args; struct its_device *its_dev = info->scratchpad[0].ptr; struct its_node *its = its_dev->its; + struct irq_data *irqd; irq_hw_number_t hwirq; int err; int i; @@ -2600,7 +2600,9 @@ irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i, &its_irq_chip, its_dev); - irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(virq + i))); + irqd = irq_get_irq_data(virq + i); + irqd_set_single_target(irqd); + irqd_set_affinity_on_activate(irqd); pr_debug("ID:%d pID:%d vID:%d\n", (int)(hwirq + i - its_dev->event_map.lpi_base), (int)(hwirq + i), virq + i); @@ -2985,12 +2987,18 @@ return 0; } +static int its_vpe_retrigger(struct irq_data *d) +{ + return !its_vpe_set_irqchip_state(d, IRQCHIP_STATE_PENDING, true); +} + static struct irq_chip its_vpe_irq_chip = { .name = "GICv4-vpe", .irq_mask = its_vpe_mask_irq, .irq_unmask = its_vpe_unmask_irq, .irq_eoi = irq_chip_eoi_parent, .irq_set_affinity = its_vpe_set_affinity, + .irq_retrigger = its_vpe_retrigger, .irq_set_irqchip_state = its_vpe_set_irqchip_state, .irq_set_vcpu_affinity = its_vpe_set_vcpu_affinity, }; @@ -3077,8 +3085,6 @@ struct page *vprop_page; int base, nr_ids, i, err = 0; - BUG_ON(!vm); - bitmap = its_lpi_alloc(roundup_pow_of_two(nr_irqs), &base, &nr_ids); if (!bitmap) return -ENOMEM; @@ -3113,13 +3119,8 @@ set_bit(i, bitmap); } - if (err) { - if (i > 0) - its_vpe_irq_domain_free(domain, virq, i - 1); - - its_lpi_free(bitmap, base, nr_ids); - its_free_prop_table(vprop_page); - } + if (err) + its_vpe_irq_domain_free(domain, virq, i); return err; } @@ -3358,9 +3359,6 @@ list_for_each_entry(its, &its_nodes, entry) { void __iomem *base; - if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) - continue; - base = its->base; its->ctlr_save = readl_relaxed(base + GITS_CTLR); err = its_force_quiescent(base); @@ -3379,9 +3377,6 @@ list_for_each_entry_continue_reverse(its, &its_nodes, entry) { void __iomem *base; - if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) - continue; - base = its->base; writel_relaxed(its->ctlr_save, base + GITS_CTLR); } @@ -3401,9 +3396,6 @@ void __iomem *base; int i; - if (!(its->flags & ITS_FLAGS_SAVE_SUSPEND_STATE)) - continue; - base = its->base; /* @@ -3411,7 +3403,10 @@ * don't restore it since writing to CBASER or BASER * registers is undefined according to the GIC v3 ITS * Specification. + * + * Firmware resuming with the ITS enabled is terminally broken. */ + WARN_ON(readl_relaxed(base + GITS_CTLR) & GITS_CTLR_ENABLE); ret = its_force_quiescent(base); if (ret) { pr_err("ITS@%pa: failed to quiesce on resume: %d\n", @@ -3678,9 +3673,6 @@ ctlr |= GITS_CTLR_ImDe; writel_relaxed(ctlr, its->base + GITS_CTLR); - if (GITS_TYPER_HCC(typer)) - its->flags |= ITS_FLAGS_SAVE_SUSPEND_STATE; - err = its_init_domain(handle, its); if (err) goto out_free_tables; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-v3-mbi.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-v3-mbi.c @@ -303,7 +303,7 @@ reg = of_get_property(np, "mbi-alias", NULL); if (reg) { mbi_phys_base = of_translate_address(np, reg); - if (mbi_phys_base == OF_BAD_ADDR) { + if (mbi_phys_base == (phys_addr_t)OF_BAD_ADDR) { ret = -ENXIO; goto err_free_mbi; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic-v3.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic-v3.c @@ -162,11 +162,11 @@ } } -static void gic_do_wait_for_rwp(void __iomem *base) +static void gic_do_wait_for_rwp(void __iomem *base, u32 bit) { u32 count = 1000000; /* 1s! */ - while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { + while (readl_relaxed(base + GICD_CTLR) & bit) { count--; if (!count) { pr_err_ratelimited("RWP timeout, gone fishing\n"); @@ -180,13 +180,13 @@ /* Wait for completion of a distributor change */ static void gic_dist_wait_for_rwp(void) { - gic_do_wait_for_rwp(gic_data.dist_base); + gic_do_wait_for_rwp(gic_data.dist_base, GICD_CTLR_RWP); } /* Wait for completion of a redistributor change */ static void gic_redist_wait_for_rwp(void) { - gic_do_wait_for_rwp(gic_data_rdist_rd_base()); + gic_do_wait_for_rwp(gic_data_rdist_rd_base(), GICR_CTLR_RWP); } #ifdef CONFIG_ARM64 @@ -383,6 +383,13 @@ } gic_poke_irq(d, reg); + + /* + * Force read-back to guarantee that the active state has taken + * effect, and won't race with a guest-driven deactivation. + */ + if (reg == GICD_ISACTIVER) + gic_peek_irq(d, reg); return 0; } @@ -621,6 +628,10 @@ irqnr = gic_read_iar(); + /* Check for special IDs first */ + if ((irqnr >= 1020 && irqnr <= 1023)) + return; + if (gic_supports_nmi() && unlikely(gic_read_rpr() == GICD_INT_NMI_PRI)) { gic_handle_nmi(irqnr, regs); @@ -632,10 +643,6 @@ gic_arch_enable_irqs(); } - /* Check for special IDs first */ - if ((irqnr >= 1020 && irqnr <= 1023)) - return; - /* Treat anything but SGIs in a uniform way */ if (likely(irqnr > 15)) { int err; @@ -1178,7 +1185,7 @@ static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) { - if (cmd == CPU_PM_EXIT) { + if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) { if (gic_dist_security_disabled()) gic_enable_redist(true); gic_cpu_sys_reg_init(); @@ -1616,7 +1623,7 @@ gic_data.ppi_descs = kcalloc(gic_data.ppi_nr, sizeof(*gic_data.ppi_descs), GFP_KERNEL); if (!gic_data.ppi_descs) - return; + goto out_put_node; nr_parts = of_get_child_count(parts_node); @@ -1657,12 +1664,15 @@ continue; cpu = of_cpu_node_to_id(cpu_node); - if (WARN_ON(cpu < 0)) + if (WARN_ON(cpu < 0)) { + of_node_put(cpu_node); continue; + } pr_cont("%pOF[%d] ", cpu_node, cpu); cpumask_set_cpu(cpu, &part->mask); + of_node_put(cpu_node); } pr_cont("}\n"); @@ -1801,6 +1811,7 @@ struct redist_region *redist_regs; u32 nr_redist_regions; bool single_redist; + int enabled_rdists; u32 maint_irq; int maint_irq_mode; phys_addr_t vcpu_base; @@ -1895,8 +1906,10 @@ * If GICC is enabled and has valid gicr base address, then it means * GICR base is presented via GICC */ - if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) + if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) { + acpi_data.enabled_rdists++; return 0; + } /* * It's perfectly valid firmware can pass disabled GICC entry, driver @@ -1926,8 +1939,10 @@ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT, gic_acpi_match_gicc, 0); - if (count > 0) + if (count > 0) { acpi_data.single_redist = true; + count = acpi_data.enabled_rdists; + } return count; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-gic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-gic.c @@ -62,7 +62,7 @@ union gic_base { void __iomem *common_base; - void __percpu * __iomem *percpu_base; + void __iomem * __percpu *percpu_base; }; struct gic_chip_data { @@ -329,10 +329,8 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { - void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); - unsigned int cpu, shift = (gic_irq(d) % 4) * 8; - u32 val, mask, bit; - unsigned long flags; + void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + gic_irq(d); + unsigned int cpu; if (!force) cpu = cpumask_any_and(mask_val, cpu_online_mask); @@ -342,13 +340,7 @@ if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; - gic_lock_irqsave(flags); - mask = 0xff << shift; - bit = gic_cpu_map[cpu] << shift; - val = readl_relaxed(reg) & ~mask; - writel_relaxed(val | bit, reg); - gic_unlock_irqrestore(flags); - + writeb_relaxed(gic_cpu_map[cpu], reg); irq_data_update_effective_affinity(d, cpumask_of(cpu)); return IRQ_SET_MASK_OK_DONE; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-imx-irqsteer.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-imx-irqsteer.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #define CTRL_STRIDE_OFF(_t, _r) (_t * 4 * _r) @@ -34,6 +35,7 @@ int channel; struct irq_domain *domain; u32 *saved_reg; + struct device *dev; }; static int imx_irqsteer_get_reg_index(struct irqsteer_data *data, @@ -70,10 +72,26 @@ raw_spin_unlock_irqrestore(&data->lock, flags); } -static struct irq_chip imx_irqsteer_irq_chip = { - .name = "irqsteer", - .irq_mask = imx_irqsteer_irq_mask, - .irq_unmask = imx_irqsteer_irq_unmask, +static void imx_irqsteer_irq_bus_lock(struct irq_data *d) +{ + struct irqsteer_data *data = d->chip_data; + + pm_runtime_get_sync(data->dev); +} + +static void imx_irqsteer_irq_bus_sync_unlock(struct irq_data *d) +{ + struct irqsteer_data *data = d->chip_data; + + pm_runtime_put_autosuspend(data->dev); +} + +static const struct irq_chip imx_irqsteer_irq_chip = { + .name = "irqsteer", + .irq_mask = imx_irqsteer_irq_mask, + .irq_unmask = imx_irqsteer_irq_unmask, + .irq_bus_lock = imx_irqsteer_irq_bus_lock, + .irq_bus_sync_unlock = imx_irqsteer_irq_bus_sync_unlock, }; static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq, @@ -151,6 +169,7 @@ if (!data) return -ENOMEM; + data->dev = &pdev->dev; data->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(data->regs)) { dev_err(&pdev->dev, "failed to initialize reg\n"); @@ -181,7 +200,7 @@ data->irq_count = DIV_ROUND_UP(irqs_num, 64); data->reg_num = irqs_num / 32; - if (IS_ENABLED(CONFIG_PM_SLEEP)) { + if (IS_ENABLED(CONFIG_PM)) { data->saved_reg = devm_kzalloc(&pdev->dev, sizeof(u32) * data->reg_num, GFP_KERNEL); @@ -205,6 +224,7 @@ ret = -ENOMEM; goto out; } + irq_domain_set_pm_device(data->domain, &pdev->dev); if (!data->irq_count || data->irq_count > CHAN_MAX_OUTPUT_INT) { ret = -EINVAL; @@ -225,6 +245,9 @@ platform_set_drvdata(pdev, data); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; out: clk_disable_unprepare(data->ipg_clk); @@ -247,7 +270,7 @@ return 0; } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static void imx_irqsteer_save_regs(struct irqsteer_data *data) { int i; @@ -294,7 +317,10 @@ #endif static const struct dev_pm_ops imx_irqsteer_pm_ops = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_irqsteer_suspend, imx_irqsteer_resume) + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) + SET_RUNTIME_PM_OPS(imx_irqsteer_suspend, + imx_irqsteer_resume, NULL) }; static const struct of_device_id imx_irqsteer_dt_ids[] = { --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-ingenic-tcu.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-ingenic-tcu.c @@ -179,4 +179,5 @@ } IRQCHIP_DECLARE(jz4740_tcu_irq, "ingenic,jz4740-tcu", ingenic_tcu_irq_init); IRQCHIP_DECLARE(jz4725b_tcu_irq, "ingenic,jz4725b-tcu", ingenic_tcu_irq_init); +IRQCHIP_DECLARE(jz4760_tcu_irq, "ingenic,jz4760-tcu", ingenic_tcu_irq_init); IRQCHIP_DECLARE(jz4770_tcu_irq, "ingenic,jz4770-tcu", ingenic_tcu_irq_init); --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-ingenic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-ingenic.c @@ -108,6 +108,14 @@ goto out_unmap_irq; } + domain = irq_domain_add_legacy(node, num_chips * 32, + JZ4740_IRQ_BASE, 0, + &irq_domain_simple_ops, NULL); + if (!domain) { + err = -ENOMEM; + goto out_unmap_base; + } + for (i = 0; i < num_chips; i++) { /* Mask all irqs */ writel(0xffffffff, intc->base + (i * CHIP_SIZE) + @@ -134,14 +142,11 @@ IRQ_NOPROBE | IRQ_LEVEL); } - domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0, - &irq_domain_simple_ops, NULL); - if (!domain) - pr_warn("unable to register IRQ domain\n"); - setup_irq(parent_irq, &intc_cascade_action); return 0; +out_unmap_base: + iounmap(intc->base); out_unmap_irq: irq_dispose_mapping(parent_irq); out_free: @@ -163,6 +168,7 @@ { return ingenic_intc_of_init(node, 2); } +IRQCHIP_DECLARE(jz4760_intc, "ingenic,jz4760-intc", intc_2chip_of_init); IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init); IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init); IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init); --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-jcore-aic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-jcore-aic.c @@ -68,6 +68,7 @@ unsigned min_irq = JCORE_AIC2_MIN_HWIRQ; unsigned dom_sz = JCORE_AIC_MAX_HWIRQ+1; struct irq_domain *domain; + int ret; pr_info("Initializing J-Core AIC\n"); @@ -100,11 +101,17 @@ jcore_aic.irq_unmask = noop; jcore_aic.name = "AIC"; - domain = irq_domain_add_linear(node, dom_sz, &jcore_aic_irqdomain_ops, + ret = irq_alloc_descs(-1, min_irq, dom_sz - min_irq, + of_node_to_nid(node)); + + if (ret < 0) + return ret; + + domain = irq_domain_add_legacy(node, dom_sz - min_irq, min_irq, min_irq, + &jcore_aic_irqdomain_ops, &jcore_aic); if (!domain) return -ENOMEM; - irq_create_strict_mappings(domain, min_irq, min_irq, dom_sz - min_irq); return 0; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-mbigen.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-mbigen.c @@ -64,6 +64,20 @@ void __iomem *base; }; +static inline unsigned int get_mbigen_node_offset(unsigned int nid) +{ + unsigned int offset = nid * MBIGEN_NODE_OFFSET; + + /* + * To avoid touched clear register in unexpected way, we need to directly + * skip clear register when access to more than 10 mbigen nodes. + */ + if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET)) + offset += MBIGEN_NODE_OFFSET; + + return offset; +} + static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq) { unsigned int nid, pin; @@ -72,8 +86,7 @@ nid = hwirq / IRQS_PER_MBIGEN_NODE + 1; pin = hwirq % IRQS_PER_MBIGEN_NODE; - return pin * 4 + nid * MBIGEN_NODE_OFFSET - + REG_MBIGEN_VEC_OFFSET; + return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET; } static inline void get_mbigen_type_reg(irq_hw_number_t hwirq, @@ -88,8 +101,7 @@ *mask = 1 << (irq_ofst % 32); ofst = irq_ofst / 32 * 4; - *addr = ofst + nid * MBIGEN_NODE_OFFSET - + REG_MBIGEN_TYPE_OFFSET; + *addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET; } static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq, @@ -220,10 +232,16 @@ return 0; } +static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + platform_msi_domain_free(domain, virq, nr_irqs); +} + static const struct irq_domain_ops mbigen_domain_ops = { .translate = mbigen_domain_translate, .alloc = mbigen_irq_domain_alloc, - .free = irq_domain_free_irqs_common, + .free = mbigen_irq_domain_free, }; static int mbigen_of_create_domain(struct platform_device *pdev, @@ -374,6 +392,7 @@ .name = "Hisilicon MBIGEN-V2", .of_match_table = mbigen_of_match, .acpi_match_table = ACPI_PTR(mbigen_acpi_match), + .suppress_bind_attrs = true, }, .probe = mbigen_device_probe, }; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-meson-gpio.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-meson-gpio.c @@ -70,7 +70,7 @@ .support_edge_both = true, }; -static const struct of_device_id meson_irq_gpio_matches[] = { +static const struct of_device_id meson_irq_gpio_matches[] __maybe_unused = { { .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params }, { .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params }, { .compatible = "amlogic,meson-gxbb-gpio-intc", .data = &gxbb_params }, --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-mips-cpu.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-mips-cpu.c @@ -197,6 +197,13 @@ if (ret) return ret; + ret = irq_domain_set_hwirq_and_chip(domain->parent, virq + i, hwirq, + &mips_mt_cpu_irq_controller, + NULL); + + if (ret) + return ret; + ret = irq_set_irq_type(virq + i, IRQ_TYPE_LEVEL_HIGH); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-mips-gic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-mips-gic.c @@ -48,7 +48,7 @@ DEFINE_PER_CPU_READ_MOSTLY(unsigned long[GIC_MAX_LONGS], pcpu_masks); -static DEFINE_SPINLOCK(gic_lock); +static DEFINE_RAW_SPINLOCK(gic_lock); static struct irq_domain *gic_irq_domain; static struct irq_domain *gic_ipi_domain; static int gic_shared_intrs; @@ -207,7 +207,7 @@ irq = GIC_HWIRQ_TO_SHARED(d->hwirq); - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_FALLING: pol = GIC_POL_FALLING_EDGE; @@ -247,7 +247,7 @@ else irq_set_chip_handler_name_locked(d, &gic_level_irq_controller, handle_level_irq, NULL); - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); return 0; } @@ -265,7 +265,7 @@ return -EINVAL; /* Assumption : cpumask refers to a single CPU */ - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); /* Re-route this IRQ */ write_gic_map_vp(irq, BIT(mips_cm_vp_id(cpu))); @@ -276,7 +276,7 @@ set_bit(irq, per_cpu_ptr(pcpu_masks, cpu)); irq_data_update_effective_affinity(d, cpumask_of(cpu)); - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); return IRQ_SET_MASK_OK; } @@ -354,12 +354,12 @@ cd = irq_data_get_irq_chip_data(d); cd->mask = false; - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); for_each_online_cpu(cpu) { write_gic_vl_other(mips_cm_vp_id(cpu)); write_gic_vo_rmask(BIT(intr)); } - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); } static void gic_unmask_local_irq_all_vpes(struct irq_data *d) @@ -372,32 +372,45 @@ cd = irq_data_get_irq_chip_data(d); cd->mask = true; - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); for_each_online_cpu(cpu) { write_gic_vl_other(mips_cm_vp_id(cpu)); write_gic_vo_smask(BIT(intr)); } - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); } -static void gic_all_vpes_irq_cpu_online(struct irq_data *d) +static void gic_all_vpes_irq_cpu_online(void) { - struct gic_all_vpes_chip_data *cd; - unsigned int intr; + static const unsigned int local_intrs[] = { + GIC_LOCAL_INT_TIMER, + GIC_LOCAL_INT_PERFCTR, + GIC_LOCAL_INT_FDC, + }; + unsigned long flags; + int i; - intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); - cd = irq_data_get_irq_chip_data(d); + raw_spin_lock_irqsave(&gic_lock, flags); - write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); - if (cd->mask) - write_gic_vl_smask(BIT(intr)); + for (i = 0; i < ARRAY_SIZE(local_intrs); i++) { + unsigned int intr = local_intrs[i]; + struct gic_all_vpes_chip_data *cd; + + if (!gic_local_irq_is_routable(intr)) + continue; + cd = &gic_all_vpes_chip_data[intr]; + write_gic_vl_map(mips_gic_vx_map_reg(intr), cd->map); + if (cd->mask) + write_gic_vl_smask(BIT(intr)); + } + + raw_spin_unlock_irqrestore(&gic_lock, flags); } static struct irq_chip gic_all_vpes_local_irq_controller = { .name = "MIPS GIC Local", .irq_mask = gic_mask_local_irq_all_vpes, .irq_unmask = gic_unmask_local_irq_all_vpes, - .irq_cpu_online = gic_all_vpes_irq_cpu_online, }; static void __gic_irq_dispatch(void) @@ -421,11 +434,11 @@ data = irq_get_irq_data(virq); - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); write_gic_map_pin(intr, GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin); write_gic_map_vp(intr, BIT(mips_cm_vp_id(cpu))); irq_data_update_effective_affinity(data, cpumask_of(cpu)); - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); return 0; } @@ -476,6 +489,10 @@ intr = GIC_HWIRQ_TO_LOCAL(hwirq); map = GIC_MAP_PIN_MAP_TO_PIN | gic_cpu_pin; + /* + * If adding support for more per-cpu interrupts, keep the the + * array in gic_all_vpes_irq_cpu_online() in sync. + */ switch (intr) { case GIC_LOCAL_INT_TIMER: /* CONFIG_MIPS_CMP workaround (see __gic_init) */ @@ -514,12 +531,12 @@ if (!gic_local_irq_is_routable(intr)) return -EPERM; - spin_lock_irqsave(&gic_lock, flags); + raw_spin_lock_irqsave(&gic_lock, flags); for_each_online_cpu(cpu) { write_gic_vl_other(mips_cm_vp_id(cpu)); write_gic_vo_map(mips_gic_vx_map_reg(intr), map); } - spin_unlock_irqrestore(&gic_lock, flags); + raw_spin_unlock_irqrestore(&gic_lock, flags); return 0; } @@ -662,8 +679,8 @@ /* Clear all local IRQ masks (ie. disable all local interrupts) */ write_gic_vl_rmask(~0); - /* Invoke irq_cpu_online callbacks to enable desired interrupts */ - irq_cpu_online(); + /* Enable desired interrupts */ + gic_all_vpes_irq_cpu_online(); return 0; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-mtk-sysirq.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-mtk-sysirq.c @@ -15,7 +15,7 @@ #include struct mtk_sysirq_chip_data { - spinlock_t lock; + raw_spinlock_t lock; u32 nr_intpol_bases; void __iomem **intpol_bases; u32 *intpol_words; @@ -37,7 +37,7 @@ reg_index = chip_data->which_word[hwirq]; offset = hwirq & 0x1f; - spin_lock_irqsave(&chip_data->lock, flags); + raw_spin_lock_irqsave(&chip_data->lock, flags); value = readl_relaxed(base + reg_index * 4); if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING) { if (type == IRQ_TYPE_LEVEL_LOW) @@ -53,7 +53,7 @@ data = data->parent_data; ret = data->chip->irq_set_type(data, type); - spin_unlock_irqrestore(&chip_data->lock, flags); + raw_spin_unlock_irqrestore(&chip_data->lock, flags); return ret; } @@ -212,7 +212,7 @@ ret = -ENOMEM; goto out_free_which_word; } - spin_lock_init(&chip_data->lock); + raw_spin_lock_init(&chip_data->lock); return 0; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-mvebu-gicp.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-mvebu-gicp.c @@ -223,6 +223,7 @@ } parent_domain = irq_find_host(irq_parent_dn); + of_node_put(irq_parent_dn); if (!parent_domain) { dev_err(&pdev->dev, "failed to find parent IRQ domain\n"); return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-nvic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-nvic.c @@ -26,7 +26,7 @@ #define NVIC_ISER 0x000 #define NVIC_ICER 0x080 -#define NVIC_IPR 0x300 +#define NVIC_IPR 0x400 #define NVIC_MAX_BANKS 16 /* @@ -105,6 +105,7 @@ if (!nvic_irq_domain) { pr_warn("Failed to allocate irq domain\n"); + iounmap(nvic_base); return -ENOMEM; } @@ -114,6 +115,7 @@ if (ret) { pr_warn("Failed to allocate irq chips\n"); irq_domain_remove(nvic_irq_domain); + iounmap(nvic_base); return ret; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-or1k-pic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-or1k-pic.c @@ -66,7 +66,6 @@ .name = "or1k-PIC-level", .irq_unmask = or1k_pic_unmask, .irq_mask = or1k_pic_mask, - .irq_mask_ack = or1k_pic_mask_ack, }, .handle = handle_level_irq, .flags = IRQ_LEVEL | IRQ_NOPROBE, --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-s3c24xx.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-s3c24xx.c @@ -359,11 +359,25 @@ asmlinkage void __exception_irq_entry s3c24xx_handle_irq(struct pt_regs *regs) { do { - if (likely(s3c_intc[0])) - if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) - continue; + /* + * For platform based machines, neither ERR nor NULL can happen here. + * The s3c24xx_handle_irq() will be set as IRQ handler iff this succeeds: + * + * s3c_intc[0] = s3c24xx_init_intc() + * + * If this fails, the next calls to s3c24xx_init_intc() won't be executed. + * + * For DT machine, s3c_init_intc_of() could set the IRQ handler without + * setting s3c_intc[0] only if it was called with num_ctrl=0. There is no + * such code path, so again the s3c_intc[0] will have a valid pointer if + * set_handle_irq() is called. + * + * Therefore in s3c24xx_handle_irq(), the s3c_intc[0] is always something. + */ + if (s3c24xx_handle_intc(s3c_intc[0], regs, 0)) + continue; - if (s3c_intc[2]) + if (!IS_ERR_OR_NULL(s3c_intc[2])) if (s3c24xx_handle_intc(s3c_intc[2], regs, 64)) continue; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-sifive-plic.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-sifive-plic.c @@ -138,7 +138,13 @@ { struct plic_handler *handler = this_cpu_ptr(&plic_handlers); - writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + if (irqd_irq_masked(d)) { + plic_irq_unmask(d); + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + plic_irq_mask(d); + } else { + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); + } } static struct irq_chip plic_chip = { @@ -307,3 +313,4 @@ IRQCHIP_DECLARE(sifive_plic, "sifive,plic-1.0.0", plic_init); IRQCHIP_DECLARE(riscv_plic0, "riscv,plic0", plic_init); /* for legacy systems */ +IRQCHIP_DECLARE(thead_c900_plic, "thead,c900-plic", plic_init); /* for firmware driver */ --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-sni-exiu.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-sni-exiu.c @@ -37,11 +37,26 @@ u32 spi_base; }; -static void exiu_irq_eoi(struct irq_data *d) +static void exiu_irq_ack(struct irq_data *d) { struct exiu_irq_data *data = irq_data_get_irq_chip_data(d); writel(BIT(d->hwirq), data->base + EIREQCLR); +} + +static void exiu_irq_eoi(struct irq_data *d) +{ + struct exiu_irq_data *data = irq_data_get_irq_chip_data(d); + + /* + * Level triggered interrupts are latched and must be cleared during + * EOI or the interrupt will be jammed on. Of course if a level + * triggered interrupt is still asserted then the write will not clear + * the interrupt. + */ + if (irqd_is_level_type(d)) + writel(BIT(d->hwirq), data->base + EIREQCLR); + irq_chip_eoi_parent(d); } @@ -91,10 +106,13 @@ writel_relaxed(val, data->base + EILVL); val = readl_relaxed(data->base + EIEDG); - if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) + if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) { val &= ~BIT(d->hwirq); - else + irq_set_handler_locked(d, handle_fasteoi_irq); + } else { val |= BIT(d->hwirq); + irq_set_handler_locked(d, handle_fasteoi_ack_irq); + } writel_relaxed(val, data->base + EIEDG); writel_relaxed(BIT(d->hwirq), data->base + EIREQCLR); @@ -104,6 +122,7 @@ static struct irq_chip exiu_irq_chip = { .name = "EXIU", + .irq_ack = exiu_irq_ack, .irq_eoi = exiu_irq_eoi, .irq_enable = exiu_irq_enable, .irq_mask = exiu_irq_mask, @@ -136,7 +155,7 @@ if (fwspec->param_count != 2) return -EINVAL; *hwirq = fwspec->param[0]; - *type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK; + *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK; } return 0; } --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-stm32-exti.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-stm32-exti.c @@ -414,6 +414,7 @@ .map = irq_map_generic_chip, .alloc = stm32_exti_alloc, .free = stm32_exti_free, + .xlate = irq_domain_xlate_twocell, }; static void stm32_irq_ack(struct irq_data *d) @@ -431,6 +432,16 @@ irq_gc_unlock(gc); } +/* directly set the target bit without reading first. */ +static inline void stm32_exti_write_bit(struct irq_data *d, u32 reg) +{ + struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d); + void __iomem *base = chip_data->host_data->base; + u32 val = BIT(d->hwirq % IRQS_PER_BANK); + + writel_relaxed(val, base + reg); +} + static inline u32 stm32_exti_set_bit(struct irq_data *d, u32 reg) { struct stm32_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d); @@ -464,9 +475,9 @@ raw_spin_lock(&chip_data->rlock); - stm32_exti_set_bit(d, stm32_bank->rpr_ofst); + stm32_exti_write_bit(d, stm32_bank->rpr_ofst); if (stm32_bank->fpr_ofst != UNDEF_REG) - stm32_exti_set_bit(d, stm32_bank->fpr_ofst); + stm32_exti_write_bit(d, stm32_bank->fpr_ofst); raw_spin_unlock(&chip_data->rlock); --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-sunxi-nmi.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-sunxi-nmi.c @@ -200,7 +200,8 @@ gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit; gc->chip_types[0].chip.irq_eoi = irq_gc_ack_set_bit; gc->chip_types[0].chip.irq_set_type = sunxi_sc_nmi_set_type; - gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED; + gc->chip_types[0].chip.flags = IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED | + IRQCHIP_SKIP_SET_WAKE; gc->chip_types[0].regs.ack = reg_offs->pend; gc->chip_types[0].regs.mask = reg_offs->enable; gc->chip_types[0].regs.type = reg_offs->ctrl; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-tegra.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-tegra.c @@ -148,10 +148,10 @@ lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS); /* Disable COP interrupts */ - writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); + writel_relaxed(GENMASK(31, 0), ictlr + ICTLR_COP_IER_CLR); /* Disable CPU interrupts */ - writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); + writel_relaxed(GENMASK(31, 0), ictlr + ICTLR_CPU_IER_CLR); /* Enable the wakeup sources of ictlr */ writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET); @@ -172,12 +172,12 @@ writel_relaxed(lic->cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS); - writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR); + writel_relaxed(GENMASK(31, 0), ictlr + ICTLR_CPU_IER_CLR); writel_relaxed(lic->cpu_ier[i], ictlr + ICTLR_CPU_IER_SET); writel_relaxed(lic->cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS); - writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR); + writel_relaxed(GENMASK(31, 0), ictlr + ICTLR_COP_IER_CLR); writel_relaxed(lic->cop_ier[i], ictlr + ICTLR_COP_IER_SET); } @@ -312,7 +312,7 @@ lic->base[i] = base; /* Disable all interrupts */ - writel_relaxed(~0UL, base + ICTLR_CPU_IER_CLR); + writel_relaxed(GENMASK(31, 0), base + ICTLR_CPU_IER_CLR); /* All interrupts target IRQ */ writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS); --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-ti-sci-inta.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-ti-sci-inta.c @@ -2,7 +2,7 @@ /* * Texas Instruments' K3 Interrupt Aggregator irqchip driver * - * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/ * Lokesh Vutla */ @@ -37,6 +37,7 @@ #define VINT_ENABLE_SET_OFFSET 0x0 #define VINT_ENABLE_CLR_OFFSET 0x8 #define VINT_STATUS_OFFSET 0x18 +#define VINT_STATUS_MASKED_OFFSET 0x20 /** * struct ti_sci_inta_event_desc - Description of an event coming to @@ -116,7 +117,7 @@ chained_irq_enter(irq_desc_get_chip(desc), desc); val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 + - VINT_STATUS_OFFSET); + VINT_STATUS_MASKED_OFFSET); for_each_set_bit(bit, &val, MAX_EVENTS_PER_VINT) { virq = irq_find_mapping(domain, vint_desc->events[bit].hwirq); @@ -570,7 +571,7 @@ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); inta->base = devm_ioremap_resource(dev, res); if (IS_ERR(inta->base)) - return -ENODEV; + return PTR_ERR(inta->base); domain = irq_domain_add_linear(dev_of_node(dev), ti_sci_get_num_resources(inta->vint), --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-ti-sci-intr.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-ti-sci-intr.c @@ -2,7 +2,7 @@ /* * Texas Instruments' K3 Interrupt Router irqchip driver * - * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2018-2019 Texas Instruments Incorporated - https://www.ti.com/ * Lokesh Vutla */ @@ -205,6 +205,7 @@ } parent_domain = irq_find_host(parent_node); + of_node_put(parent_node); if (!parent_domain) { dev_err(dev, "Failed to find IRQ parent domain\n"); return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-versatile-fpga.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-versatile-fpga.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -68,12 +69,16 @@ static void fpga_irq_handle(struct irq_desc *desc) { + struct irq_chip *chip = irq_desc_get_chip(desc); struct fpga_irq_data *f = irq_desc_get_handler_data(desc); - u32 status = readl(f->base + IRQ_STATUS); + u32 status; + + chained_irq_enter(chip, desc); + status = readl(f->base + IRQ_STATUS); if (status == 0) { do_bad_IRQ(desc); - return; + goto out; } do { @@ -82,6 +87,9 @@ status &= ~(1 << irq); generic_handle_irq(irq_find_mapping(f->domain, irq)); } while (status); + +out: + chained_irq_exit(chip, desc); } /* @@ -204,6 +212,9 @@ if (of_property_read_u32(node, "valid-mask", &valid_mask)) valid_mask = 0; + writel(clear_mask, base + IRQ_ENABLE_CLEAR); + writel(clear_mask, base + FIQ_ENABLE_CLEAR); + /* Some chips are cascaded from a parent IRQ */ parent_irq = irq_of_parse_and_map(node, 0); if (!parent_irq) { @@ -213,9 +224,6 @@ fpga_irq_init(base, node->name, 0, parent_irq, valid_mask, node); - writel(clear_mask, base + IRQ_ENABLE_CLEAR); - writel(clear_mask, base + FIQ_ENABLE_CLEAR); - /* * On Versatile AB/PB, some secondary interrupts have a direct * pass-thru to the primary controller for IRQs 20 and 22-31 which need --- linux-oracle-5.4.0.orig/drivers/irqchip/irq-xtensa-mx.c +++ linux-oracle-5.4.0/drivers/irqchip/irq-xtensa-mx.c @@ -151,14 +151,25 @@ .irq_set_affinity = xtensa_mx_irq_set_affinity, }; +static void __init xtensa_mx_init_common(struct irq_domain *root_domain) +{ + unsigned int i; + + irq_set_default_host(root_domain); + secondary_init_irq(); + + /* Initialize default IRQ routing to CPU 0 */ + for (i = 0; i < XCHAL_NUM_EXTINTERRUPTS; ++i) + set_er(1, MIROUT(i)); +} + int __init xtensa_mx_init_legacy(struct device_node *interrupt_parent) { struct irq_domain *root_domain = irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0, &xtensa_mx_irq_domain_ops, &xtensa_mx_irq_chip); - irq_set_default_host(root_domain); - secondary_init_irq(); + xtensa_mx_init_common(root_domain); return 0; } @@ -168,8 +179,7 @@ struct irq_domain *root_domain = irq_domain_add_linear(np, NR_IRQS, &xtensa_mx_irq_domain_ops, &xtensa_mx_irq_chip); - irq_set_default_host(root_domain); - secondary_init_irq(); + xtensa_mx_init_common(root_domain); return 0; } IRQCHIP_DECLARE(xtensa_mx_irq_chip, "cdns,xtensa-mx", xtensa_mx_init); --- linux-oracle-5.4.0.orig/drivers/irqchip/qcom-pdc.c +++ linux-oracle-5.4.0/drivers/irqchip/qcom-pdc.c @@ -50,17 +50,18 @@ static void pdc_enable_intr(struct irq_data *d, bool on) { int pin_out = d->hwirq; + unsigned long flags; u32 index, mask; u32 enable; index = pin_out / 32; mask = pin_out % 32; - raw_spin_lock(&pdc_lock); + raw_spin_lock_irqsave(&pdc_lock, flags); enable = pdc_reg_read(IRQ_ENABLE_BANK, index); enable = on ? ENABLE_INTR(enable, mask) : CLEAR_INTR(enable, mask); pdc_reg_write(IRQ_ENABLE_BANK, index, enable); - raw_spin_unlock(&pdc_lock); + raw_spin_unlock_irqrestore(&pdc_lock, flags); } static void qcom_pdc_gic_mask(struct irq_data *d) --- linux-oracle-5.4.0.orig/drivers/isdn/capi/kcapi.c +++ linux-oracle-5.4.0/drivers/isdn/capi/kcapi.c @@ -565,6 +565,11 @@ ctr_down(ctr, CAPI_CTR_DETACHED); + if (ctr->cnr < 1 || ctr->cnr - 1 >= CAPI_MAXCONTR) { + err = -EINVAL; + goto unlock_out; + } + if (capi_controller[ctr->cnr - 1] != ctr) { err = -EINVAL; goto unlock_out; @@ -846,7 +851,7 @@ * Return value: CAPI result code */ -u16 capi20_get_manufacturer(u32 contr, u8 *buf) +u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) { struct capi_ctr *ctr; u16 ret; @@ -916,7 +921,7 @@ * Return value: CAPI result code */ -u16 capi20_get_serial(u32 contr, u8 *serial) +u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]) { struct capi_ctr *ctr; u16 ret; --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/hfcmulti.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -1931,7 +1931,7 @@ static void hfcmulti_tx(struct hfc_multi *hc, int ch) { - int i, ii, temp, len = 0; + int i, ii, temp, tmp_len, len = 0; int Zspace, z1, z2; /* must be int for calculation */ int Fspace, f1, f2; u_char *d; @@ -2152,14 +2152,15 @@ HFC_wait_nodebug(hc); } + tmp_len = (*sp)->len; dev_kfree_skb(*sp); /* check for next frame */ if (bch && get_next_bframe(bch)) { - len = (*sp)->len; + len = tmp_len; goto next_frame; } if (dch && get_next_dframe(dch)) { - len = (*sp)->len; + len = tmp_len; goto next_frame; } @@ -3219,6 +3220,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) { struct hfc_multi *hc = dch->hw; + struct sk_buff_head free_queue; u_long flags; switch (cmd) { @@ -3247,6 +3249,7 @@ l1_event(dch->l1, HW_POWERUP_IND); break; case HW_DEACT_REQ: + __skb_queue_head_init(&free_queue); /* start deactivation */ spin_lock_irqsave(&hc->lock, flags); if (hc->ctype == HFC_TYPE_E1) { @@ -3266,20 +3269,21 @@ plxsd_checksync(hc, 0); } } - skb_queue_purge(&dch->squeue); + skb_queue_splice_init(&dch->squeue, &free_queue); if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); + __skb_queue_tail(&free_queue, dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); + __skb_queue_tail(&free_queue, dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) del_timer(&dch->timer); spin_unlock_irqrestore(&hc->lock, flags); + __skb_queue_purge(&free_queue); break; case HW_POWERUP_REQ: spin_lock_irqsave(&hc->lock, flags); @@ -3386,6 +3390,9 @@ case PH_DEACTIVATE_REQ: test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); if (dch->dev.D.protocol != ISDN_P_TE_S0) { + struct sk_buff_head free_queue; + + __skb_queue_head_init(&free_queue); spin_lock_irqsave(&hc->lock, flags); if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG @@ -3407,14 +3414,14 @@ /* deactivate */ dch->state = 1; } - skb_queue_purge(&dch->squeue); + skb_queue_splice_init(&dch->squeue, &free_queue); if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); + __skb_queue_tail(&free_queue, dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); + __skb_queue_tail(&free_queue, dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); @@ -3426,6 +3433,7 @@ #endif ret = 0; spin_unlock_irqrestore(&hc->lock, flags); + __skb_queue_purge(&free_queue); } else ret = l1_event(dch->l1, hh->prim); break; --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/hfcpci.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/hfcpci.c @@ -839,7 +839,7 @@ *z1t = cpu_to_le16(new_z1); /* now send data */ if (bch->tx_idx < bch->tx_skb->len) return; - dev_kfree_skb(bch->tx_skb); + dev_kfree_skb_any(bch->tx_skb); if (get_next_bframe(bch)) goto next_t_frame; return; @@ -895,7 +895,7 @@ } bz->za[new_f1].z1 = cpu_to_le16(new_z1); /* for next buffer */ bz->f1 = new_f1; /* next frame */ - dev_kfree_skb(bch->tx_skb); + dev_kfree_skb_any(bch->tx_skb); get_next_bframe(bch); } @@ -1119,7 +1119,7 @@ if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len) hfcpci_fill_fifo(bch); else { - dev_kfree_skb(bch->tx_skb); + dev_kfree_skb_any(bch->tx_skb); if (get_next_bframe(bch)) hfcpci_fill_fifo(bch); } @@ -1617,16 +1617,19 @@ test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); spin_lock_irqsave(&hc->lock, flags); if (hc->hw.protocol == ISDN_P_NT_S0) { + struct sk_buff_head free_queue; + + __skb_queue_head_init(&free_queue); /* prepare deactivation */ Write_hfc(hc, HFCPCI_STATES, 0x40); - skb_queue_purge(&dch->squeue); + skb_queue_splice_init(&dch->squeue, &free_queue); if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); + __skb_queue_tail(&free_queue, dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); + __skb_queue_tail(&free_queue, dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); @@ -1639,10 +1642,12 @@ hc->hw.mst_m &= ~HFCPCI_MASTER; Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m); ret = 0; + spin_unlock_irqrestore(&hc->lock, flags); + __skb_queue_purge(&free_queue); } else { ret = l1_event(dch->l1, hh->prim); + spin_unlock_irqrestore(&hc->lock, flags); } - spin_unlock_irqrestore(&hc->lock, flags); break; } if (!ret) @@ -2267,7 +2272,7 @@ return 0; if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { - spin_lock(&hc->lock); + spin_lock_irq(&hc->lock); bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ main_rec_hfcpci(bch); @@ -2278,7 +2283,7 @@ main_rec_hfcpci(bch); tx_birq(bch); } - spin_unlock(&hc->lock); + spin_unlock_irq(&hc->lock); } return 0; } @@ -2341,7 +2346,7 @@ HFC_cleanup(void) { if (timer_pending(&hfc_tl)) - del_timer(&hfc_tl); + del_timer_sync(&hfc_tl); pci_unregister_driver(&hfc_driver); } --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/hfcsusb.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -46,7 +46,7 @@ static void hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel); static int hfcsusb_setup_bch(struct bchannel *bch, int protocol); static void deactivate_bchannel(struct bchannel *bch); -static void hfcsusb_ph_info(struct hfcsusb *hw); +static int hfcsusb_ph_info(struct hfcsusb *hw); /* start next background transfer for control channel */ static void @@ -241,7 +241,7 @@ * send full D/B channel status information * as MPH_INFORMATION_IND */ -static void +static int hfcsusb_ph_info(struct hfcsusb *hw) { struct ph_info *phi; @@ -250,7 +250,7 @@ phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC); if (!phi) - return; + return -ENOMEM; phi->dch.ch.protocol = hw->protocol; phi->dch.ch.Flags = dch->Flags; @@ -264,6 +264,8 @@ sizeof(struct ph_info_dch) + dch->dev.nrbchan * sizeof(struct ph_info_ch), phi, GFP_ATOMIC); kfree(phi); + + return 0; } /* @@ -325,20 +327,24 @@ test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); if (hw->protocol == ISDN_P_NT_S0) { + struct sk_buff_head free_queue; + + __skb_queue_head_init(&free_queue); hfcsusb_ph_command(hw, HFC_L1_DEACTIVATE_NT); spin_lock_irqsave(&hw->lock, flags); - skb_queue_purge(&dch->squeue); + skb_queue_splice_init(&dch->squeue, &free_queue); if (dch->tx_skb) { - dev_kfree_skb(dch->tx_skb); + __skb_queue_tail(&free_queue, dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { - dev_kfree_skb(dch->rx_skb); + __skb_queue_tail(&free_queue, dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); spin_unlock_irqrestore(&hw->lock, flags); + __skb_queue_purge(&free_queue); #ifdef FIXME if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) dchannel_sched_event(&hc->dch, D_CLEARBUSY); @@ -348,8 +354,7 @@ ret = l1_event(dch->l1, hh->prim); break; case MPH_INFORMATION_REQ: - hfcsusb_ph_info(hw); - ret = 0; + ret = hfcsusb_ph_info(hw); break; } @@ -404,8 +409,7 @@ hw->name, __func__, cmd); return -1; } - hfcsusb_ph_info(hw); - return 0; + return hfcsusb_ph_info(hw); } static int @@ -747,8 +751,7 @@ handle_led(hw, (bch->nr == 1) ? LED_B1_OFF : LED_B2_OFF); } - hfcsusb_ph_info(hw); - return 0; + return hfcsusb_ph_info(hw); } static void @@ -1332,7 +1335,7 @@ printk("\n"); } - dev_kfree_skb(tx_skb); + dev_consume_skb_irq(tx_skb); tx_skb = NULL; if (fifo->dch && get_next_dframe(fifo->dch)) tx_skb = fifo->dch->tx_skb; --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -630,17 +630,19 @@ release_io(struct inf_hw *hw) { if (hw->cfg.mode) { - if (hw->cfg.p) { + if (hw->cfg.mode == AM_MEMIO) { release_mem_region(hw->cfg.start, hw->cfg.size); - iounmap(hw->cfg.p); + if (hw->cfg.p) + iounmap(hw->cfg.p); } else release_region(hw->cfg.start, hw->cfg.size); hw->cfg.mode = AM_NONE; } if (hw->addr.mode) { - if (hw->addr.p) { + if (hw->addr.mode == AM_MEMIO) { release_mem_region(hw->addr.start, hw->addr.size); - iounmap(hw->addr.p); + if (hw->addr.p) + iounmap(hw->addr.p); } else release_region(hw->addr.start, hw->addr.size); hw->addr.mode = AM_NONE; @@ -670,9 +672,12 @@ (ulong)hw->cfg.start, (ulong)hw->cfg.size); return err; } - if (hw->ci->cfg_mode == AM_MEMIO) - hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); hw->cfg.mode = hw->ci->cfg_mode; + if (hw->ci->cfg_mode == AM_MEMIO) { + hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size); + if (!hw->cfg.p) + return -ENOMEM; + } if (debug & DEBUG_HW) pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n", hw->name, (ulong)hw->cfg.start, @@ -697,12 +702,12 @@ (ulong)hw->addr.start, (ulong)hw->addr.size); return err; } + hw->addr.mode = hw->ci->addr_mode; if (hw->ci->addr_mode == AM_MEMIO) { hw->addr.p = ioremap(hw->addr.start, hw->addr.size); - if (unlikely(!hw->addr.p)) + if (!hw->addr.p) return -ENOMEM; } - hw->addr.mode = hw->ci->addr_mode; if (debug & DEBUG_HW) pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n", hw->name, (ulong)hw->addr.start, --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/mISDNipac.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -694,7 +694,7 @@ { if (isac->type & IPAC_TYPE_ISACX) WriteISAC(isac, ISACX_MASK, 0xff); - else + else if (isac->type != 0) WriteISAC(isac, ISAC_MASK, 0xff); if (isac->dch.timer.function != NULL) { del_timer(&isac->dch.timer); --- linux-oracle-5.4.0.orig/drivers/isdn/hardware/mISDN/netjet.c +++ linux-oracle-5.4.0/drivers/isdn/hardware/mISDN/netjet.c @@ -949,14 +949,14 @@ nj_disable_hwirq(card); mode_tiger(&card->bc[0], ISDN_P_NONE); mode_tiger(&card->bc[1], ISDN_P_NONE); - card->isac.release(&card->isac); spin_unlock_irqrestore(&card->lock, flags); + card->isac.release(&card->isac); release_region(card->base, card->base_s); card->base_s = 0; } if (card->irq > 0) free_irq(card->irq, card); - if (card->isac.dch.dev.dev.class) + if (device_is_registered(&card->isac.dch.dev.dev)) mISDN_unregister_device(&card->isac.dch.dev); for (i = 0; i < 2; i++) { @@ -1100,7 +1100,6 @@ card->typ = NETJET_S_TJ300; card->base = pci_resource_start(pdev, 0); - card->irq = pdev->irq; pci_set_drvdata(pdev, card); err = setup_instance(card); if (err) --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/Kconfig +++ linux-oracle-5.4.0/drivers/isdn/mISDN/Kconfig @@ -13,6 +13,7 @@ config MISDN_DSP tristate "Digital Audio Processing of transparent data" depends on MISDN + select BITREVERSE help Enable support for digital audio processing capability. --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/core.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/core.c @@ -222,7 +222,7 @@ err = get_free_devid(); if (err < 0) - goto error1; + return err; dev->id = err; device_initialize(&dev->dev); @@ -233,11 +233,12 @@ if (debug & DEBUG_CORE) printk(KERN_DEBUG "mISDN_register %s %d\n", dev_name(&dev->dev), dev->id); + dev->dev.class = &mISDN_class; + err = create_stack(dev); if (err) goto error1; - dev->dev.class = &mISDN_class; dev->dev.platform_data = dev; dev->dev.parent = parent; dev_set_drvdata(&dev->dev, dev); @@ -249,8 +250,8 @@ error3: delete_stack(dev); - return err; error1: + put_device(&dev->dev); return err; } @@ -381,7 +382,7 @@ err = mISDN_inittimer(&debug); if (err) goto error2; - err = l1_init(&debug); + err = Isdnl1_Init(&debug); if (err) goto error3; err = Isdnl2_Init(&debug); @@ -395,7 +396,7 @@ error5: Isdnl2_cleanup(); error4: - l1_cleanup(); + Isdnl1_cleanup(); error3: mISDN_timer_cleanup(); error2: @@ -408,7 +409,7 @@ { misdn_sock_cleanup(); Isdnl2_cleanup(); - l1_cleanup(); + Isdnl1_cleanup(); mISDN_timer_cleanup(); class_unregister(&mISDN_class); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/core.h +++ linux-oracle-5.4.0/drivers/isdn/mISDN/core.h @@ -60,8 +60,8 @@ extern int mISDN_inittimer(u_int *); extern void mISDN_timer_cleanup(void); -extern int l1_init(u_int *); -extern void l1_cleanup(void); +extern int Isdnl1_Init(u_int *); +extern void Isdnl1_cleanup(void); extern int Isdnl2_Init(u_int *); extern void Isdnl2_cleanup(void); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/dsp.h +++ linux-oracle-5.4.0/drivers/isdn/mISDN/dsp.h @@ -247,7 +247,7 @@ extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id); extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb); extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb); -extern void dsp_cmx_send(void *arg); +extern void dsp_cmx_send(struct timer_list *arg); extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb); extern int dsp_cmx_del_conf_member(struct dsp *dsp); extern int dsp_cmx_del_conf(struct dsp_conf *conf); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/dsp_cmx.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/dsp_cmx.c @@ -1625,7 +1625,7 @@ static int dsp_count_valid; /* if we have last sample count */ void -dsp_cmx_send(void *arg) +dsp_cmx_send(struct timer_list *arg) { struct dsp_conf *conf; struct dsp_conf_member *member; --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/dsp_core.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/dsp_core.c @@ -1200,7 +1200,7 @@ } /* set sample timer */ - timer_setup(&dsp_spl_tl, (void *)dsp_cmx_send, 0); + timer_setup(&dsp_spl_tl, dsp_cmx_send, 0); dsp_spl_tl.expires = jiffies + dsp_tics; dsp_spl_jiffies = dsp_spl_tl.expires; add_timer(&dsp_spl_tl); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/dsp_pipeline.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/dsp_pipeline.c @@ -80,6 +80,7 @@ if (!entry) return -ENOMEM; + INIT_LIST_HEAD(&entry->list); entry->elem = elem; entry->dev.class = elements_class; @@ -114,7 +115,7 @@ device_unregister(&entry->dev); return ret; err1: - kfree(entry); + put_device(&entry->dev); return ret; } EXPORT_SYMBOL(mISDN_dsp_element_register); @@ -219,7 +220,7 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg) { int incomplete = 0, found = 0; - char *dup, *tok, *name, *args; + char *dup, *next, *tok, *name, *args; struct dsp_element_entry *entry, *n; struct dsp_pipeline_entry *pipeline_entry; struct mISDN_dsp_element *elem; @@ -230,10 +231,10 @@ if (!list_empty(&pipeline->list)) _dsp_pipeline_destroy(pipeline); - dup = kstrdup(cfg, GFP_ATOMIC); + dup = next = kstrdup(cfg, GFP_ATOMIC); if (!dup) return 0; - while ((tok = strsep(&dup, "|"))) { + while ((tok = strsep(&next, "|"))) { if (!strlen(tok)) continue; name = strsep(&tok, "("); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/l1oip.h +++ linux-oracle-5.4.0/drivers/isdn/mISDN/l1oip.h @@ -59,6 +59,7 @@ int bundle; /* bundle channels in one frm */ int codec; /* codec to use for transmis. */ int limit; /* limit number of bchannels */ + bool shutdown; /* if card is released */ /* timer */ struct timer_list keep_tl; --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/l1oip_core.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/l1oip_core.c @@ -275,7 +275,7 @@ p = frame; /* restart timer */ - if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) + if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ) && !hc->shutdown) mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); else hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; @@ -601,7 +601,9 @@ goto multiframe; /* restart timer */ - if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { + if ((time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || + !hc->timeout_on) && + !hc->shutdown) { hc->timeout_on = 1; mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); } else /* only adjust timer */ @@ -1232,11 +1234,10 @@ { int ch; - if (timer_pending(&hc->keep_tl)) - del_timer(&hc->keep_tl); + hc->shutdown = true; - if (timer_pending(&hc->timeout_tl)) - del_timer(&hc->timeout_tl); + del_timer_sync(&hc->keep_tl); + del_timer_sync(&hc->timeout_tl); cancel_work_sync(&hc->workq); --- linux-oracle-5.4.0.orig/drivers/isdn/mISDN/layer1.c +++ linux-oracle-5.4.0/drivers/isdn/mISDN/layer1.c @@ -398,7 +398,7 @@ EXPORT_SYMBOL(create_l1); int -l1_init(u_int *deb) +Isdnl1_Init(u_int *deb) { debug = deb; l1fsm_s.state_count = L1S_STATE_COUNT; @@ -409,7 +409,7 @@ } void -l1_cleanup(void) +Isdnl1_cleanup(void) { mISDN_FsmFree(&l1fsm_s); } --- linux-oracle-5.4.0.orig/drivers/leds/Kconfig +++ linux-oracle-5.4.0/drivers/leds/Kconfig @@ -144,6 +144,7 @@ config LEDS_LM3532 tristate "LCD Backlight driver for LM3532" + select REGMAP_I2C depends on LEDS_CLASS depends on I2C help @@ -344,7 +345,6 @@ tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501" depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501 select FW_LOADER - select FW_LOADER_USER_HELPER help This option supports common operations for LP5521/5523/55231/5562/8501 devices. @@ -801,7 +801,7 @@ config LEDS_TI_LMU_COMMON tristate "LED driver for TI LMU" depends on LEDS_CLASS - depends on REGMAP + select REGMAP help Say Y to enable the LED driver for TI LMU devices. This supports common features between the TI LM3532, LM3631, LM3632, --- linux-oracle-5.4.0.orig/drivers/leds/led-class.c +++ linux-oracle-5.4.0/drivers/leds/led-class.c @@ -27,11 +27,14 @@ struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + unsigned int brightness; - /* no lock needed for this */ + mutex_lock(&led_cdev->led_access); led_update_brightness(led_cdev); + brightness = led_cdev->brightness; + mutex_unlock(&led_cdev->led_access); - return sprintf(buf, "%u\n", led_cdev->brightness); + return sprintf(buf, "%u\n", brightness); } static ssize_t brightness_store(struct device *dev, @@ -68,8 +71,13 @@ struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + unsigned int max_brightness; + + mutex_lock(&led_cdev->led_access); + max_brightness = led_cdev->max_brightness; + mutex_unlock(&led_cdev->led_access); - return sprintf(buf, "%u\n", led_cdev->max_brightness); + return sprintf(buf, "%u\n", max_brightness); } static DEVICE_ATTR_RO(max_brightness); @@ -172,6 +180,7 @@ { led_cdev->flags |= LED_SUSPENDED; led_set_brightness_nopm(led_cdev, 0); + flush_work(&led_cdev->set_brightness_work); } EXPORT_SYMBOL_GPL(led_classdev_suspend); @@ -281,7 +290,7 @@ if (ret) dev_warn(parent, "Led %s renamed to %s due to name collision", - led_cdev->name, dev_name(led_cdev->dev)); + proposed_name, dev_name(led_cdev->dev)); if (led_cdev->flags & LED_BRIGHT_HW_CHANGED) { ret = led_add_brightness_hw_changed(led_cdev); --- linux-oracle-5.4.0.orig/drivers/leds/led-triggers.c +++ linux-oracle-5.4.0/drivers/leds/led-triggers.c @@ -121,9 +121,9 @@ flags); cancel_work_sync(&led_cdev->set_brightness_work); led_stop_software_blink(led_cdev); + device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); - device_remove_groups(led_cdev->dev, led_cdev->trigger->groups); led_cdev->trigger = NULL; led_cdev->trigger_data = NULL; led_cdev->activated = false; @@ -318,14 +318,15 @@ enum led_brightness brightness) { struct led_classdev *led_cdev; + unsigned long flags; if (!trig) return; - read_lock(&trig->leddev_list_lock); + read_lock_irqsave(&trig->leddev_list_lock, flags); list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); - read_unlock(&trig->leddev_list_lock); + read_unlock_irqrestore(&trig->leddev_list_lock, flags); } EXPORT_SYMBOL_GPL(led_trigger_event); @@ -336,11 +337,12 @@ int invert) { struct led_classdev *led_cdev; + unsigned long flags; if (!trig) return; - read_lock(&trig->leddev_list_lock); + read_lock_irqsave(&trig->leddev_list_lock, flags); list_for_each_entry(led_cdev, &trig->led_cdevs, trig_list) { if (oneshot) led_blink_set_oneshot(led_cdev, delay_on, delay_off, @@ -348,7 +350,7 @@ else led_blink_set(led_cdev, delay_on, delay_off); } - read_unlock(&trig->leddev_list_lock); + read_unlock_irqrestore(&trig->leddev_list_lock, flags); } void led_trigger_blink(struct led_trigger *trig, --- linux-oracle-5.4.0.orig/drivers/leds/leds-88pm860x.c +++ linux-oracle-5.4.0/drivers/leds/leds-88pm860x.c @@ -203,21 +203,33 @@ data->cdev.brightness_set_blocking = pm860x_led_set; mutex_init(&data->lock); - ret = devm_led_classdev_register(chip->dev, &data->cdev); + ret = led_classdev_register(chip->dev, &data->cdev); if (ret < 0) { dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); return ret; } pm860x_led_set(&data->cdev, 0); + + platform_set_drvdata(pdev, data); + return 0; } +static int pm860x_led_remove(struct platform_device *pdev) +{ + struct pm860x_led *data = platform_get_drvdata(pdev); + + led_classdev_unregister(&data->cdev); + + return 0; +} static struct platform_driver pm860x_led_driver = { .driver = { .name = "88pm860x-led", }, .probe = pm860x_led_probe, + .remove = pm860x_led_remove, }; module_platform_driver(pm860x_led_driver); --- linux-oracle-5.4.0.orig/drivers/leds/leds-an30259a.c +++ linux-oracle-5.4.0/drivers/leds/leds-an30259a.c @@ -305,6 +305,13 @@ chip->regmap = devm_regmap_init_i2c(client, &an30259a_regmap_config); + if (IS_ERR(chip->regmap)) { + err = PTR_ERR(chip->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + err); + goto exit; + } + for (i = 0; i < chip->num_leds; i++) { struct led_init_data init_data = {}; --- linux-oracle-5.4.0.orig/drivers/leds/leds-as3645a.c +++ linux-oracle-5.4.0/drivers/leds/leds-as3645a.c @@ -544,6 +544,7 @@ if (!flash->indicator_node) { dev_warn(&flash->client->dev, "can't find indicator node\n"); + rval = -ENODEV; goto out_err; } --- linux-oracle-5.4.0.orig/drivers/leds/leds-bcm6328.c +++ linux-oracle-5.4.0/drivers/leds/leds-bcm6328.c @@ -332,7 +332,7 @@ led->cdev.brightness_set = bcm6328_led_set; led->cdev.blink_set = bcm6328_blink_set; - rc = led_classdev_register(dev, &led->cdev); + rc = devm_led_classdev_register(dev, &led->cdev); if (rc < 0) return rc; --- linux-oracle-5.4.0.orig/drivers/leds/leds-bcm6358.c +++ linux-oracle-5.4.0/drivers/leds/leds-bcm6358.c @@ -137,7 +137,7 @@ led->cdev.brightness_set = bcm6358_led_set; - rc = led_classdev_register(dev, &led->cdev); + rc = devm_led_classdev_register(dev, &led->cdev); if (rc < 0) return rc; --- linux-oracle-5.4.0.orig/drivers/leds/leds-da903x.c +++ linux-oracle-5.4.0/drivers/leds/leds-da903x.c @@ -110,12 +110,23 @@ led->flags = pdata->flags; led->master = pdev->dev.parent; - ret = devm_led_classdev_register(led->master, &led->cdev); + ret = led_classdev_register(led->master, &led->cdev); if (ret) { dev_err(&pdev->dev, "failed to register LED %d\n", id); return ret; } + platform_set_drvdata(pdev, led); + + return 0; +} + +static int da903x_led_remove(struct platform_device *pdev) +{ + struct da903x_led *led = platform_get_drvdata(pdev); + + led_classdev_unregister(&led->cdev); + return 0; } @@ -124,6 +135,7 @@ .name = "da903x-led", }, .probe = da903x_led_probe, + .remove = da903x_led_remove, }; module_platform_driver(da903x_led_driver); --- linux-oracle-5.4.0.orig/drivers/leds/leds-gpio.c +++ linux-oracle-5.4.0/drivers/leds/leds-gpio.c @@ -151,9 +151,14 @@ struct gpio_led led = {}; const char *state = NULL; + /* + * Acquire gpiod from DT with uninitialized label, which + * will be updated after LED class device is registered, + * Only then the final LED name is known. + */ led.gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, child, GPIOD_ASIS, - led.name); + NULL); if (IS_ERR(led.gpiod)) { fwnode_handle_put(child); return ERR_CAST(led.gpiod); @@ -186,6 +191,9 @@ fwnode_handle_put(child); return ERR_PTR(ret); } + /* Set gpiod label to match the corresponding LED name. */ + gpiod_set_consumer_name(led_dat->gpiod, + led_dat->cdev.dev->kobj.name); priv->num_leds++; } --- linux-oracle-5.4.0.orig/drivers/leds/leds-ktd2692.c +++ linux-oracle-5.4.0/drivers/leds/leds-ktd2692.c @@ -256,6 +256,17 @@ | KTD2692_REG_FLASH_CURRENT_BASE); } +static void regulator_disable_action(void *_data) +{ + struct device *dev = _data; + struct ktd2692_context *led = dev_get_drvdata(dev); + int ret; + + ret = regulator_disable(led->regulator); + if (ret) + dev_err(dev, "Failed to disable supply: %d\n", ret); +} + static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, struct ktd2692_led_config_data *cfg) { @@ -286,8 +297,14 @@ if (led->regulator) { ret = regulator_enable(led->regulator); - if (ret) + if (ret) { dev_err(dev, "Failed to enable supply: %d\n", ret); + } else { + ret = devm_add_action_or_reset(dev, + regulator_disable_action, dev); + if (ret) + return ret; + } } child_node = of_get_next_available_child(np, NULL); @@ -377,17 +394,9 @@ static int ktd2692_remove(struct platform_device *pdev) { struct ktd2692_context *led = platform_get_drvdata(pdev); - int ret; led_classdev_flash_unregister(&led->fled_cdev); - if (led->regulator) { - ret = regulator_disable(led->regulator); - if (ret) - dev_err(&pdev->dev, - "Failed to disable supply: %d\n", ret); - } - mutex_destroy(&led->lock); return 0; --- linux-oracle-5.4.0.orig/drivers/leds/leds-lm3533.c +++ linux-oracle-5.4.0/drivers/leds/leds-lm3533.c @@ -694,7 +694,7 @@ platform_set_drvdata(pdev, led); - ret = devm_led_classdev_register(pdev->dev.parent, &led->cdev); + ret = led_classdev_register(pdev->dev.parent, &led->cdev); if (ret) { dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id); return ret; @@ -704,13 +704,18 @@ ret = lm3533_led_setup(led, pdata); if (ret) - return ret; + goto err_deregister; ret = lm3533_ctrlbank_enable(&led->cb); if (ret) - return ret; + goto err_deregister; return 0; + +err_deregister: + led_classdev_unregister(&led->cdev); + + return ret; } static int lm3533_led_remove(struct platform_device *pdev) @@ -720,6 +725,7 @@ dev_dbg(&pdev->dev, "%s\n", __func__); lm3533_ctrlbank_disable(&led->cb); + led_classdev_unregister(&led->cdev); return 0; } --- linux-oracle-5.4.0.orig/drivers/leds/leds-lm355x.c +++ linux-oracle-5.4.0/drivers/leds/leds-lm355x.c @@ -165,18 +165,19 @@ /* input and output pins configuration */ switch (chip->type) { case CHIP_LM3554: - reg_val = pdata->pin_tx2 | pdata->ntc_pin; + reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin; ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val); if (ret < 0) goto out; - reg_val = pdata->pass_mode; + reg_val = (u32)pdata->pass_mode; ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val); if (ret < 0) goto out; break; case CHIP_LM3556: - reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode; + reg_val = (u32)pdata->pin_tx2 | (u32)pdata->ntc_pin | + (u32)pdata->pass_mode; ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val); if (ret < 0) goto out; --- linux-oracle-5.4.0.orig/drivers/leds/leds-lm36274.c +++ linux-oracle-5.4.0/drivers/leds/leds-lm36274.c @@ -41,37 +41,36 @@ }; static int lm36274_brightness_set(struct led_classdev *led_cdev, - enum led_brightness brt_val) + enum led_brightness brt_val) { - struct lm36274 *led = container_of(led_cdev, struct lm36274, led_dev); + struct lm36274 *chip = container_of(led_cdev, struct lm36274, led_dev); - return ti_lmu_common_set_brightness(&led->lmu_data, brt_val); + return ti_lmu_common_set_brightness(&chip->lmu_data, brt_val); } -static int lm36274_init(struct lm36274 *lm36274_data) +static int lm36274_init(struct lm36274 *chip) { int enable_val = 0; int i; - for (i = 0; i < lm36274_data->num_leds; i++) - enable_val |= (1 << lm36274_data->led_sources[i]); + for (i = 0; i < chip->num_leds; i++) + enable_val |= (1 << chip->led_sources[i]); if (!enable_val) { - dev_err(lm36274_data->dev, "No LEDs were enabled\n"); + dev_err(chip->dev, "No LEDs were enabled\n"); return -EINVAL; } enable_val |= LM36274_BL_EN; - return regmap_write(lm36274_data->regmap, LM36274_REG_BL_EN, - enable_val); + return regmap_write(chip->regmap, LM36274_REG_BL_EN, enable_val); } -static int lm36274_parse_dt(struct lm36274 *lm36274_data) +static int lm36274_parse_dt(struct lm36274 *chip) { struct fwnode_handle *child = NULL; char label[LED_MAX_NAME_SIZE]; - struct device *dev = &lm36274_data->pdev->dev; + struct device *dev = &chip->pdev->dev; const char *name; int child_cnt; int ret = -EINVAL; @@ -84,37 +83,37 @@ device_for_each_child_node(dev, child) { ret = fwnode_property_read_string(child, "label", &name); if (ret) - snprintf(label, sizeof(label), - "%s::", lm36274_data->pdev->name); + snprintf(label, sizeof(label), "%s::", + chip->pdev->name); else - snprintf(label, sizeof(label), - "%s:%s", lm36274_data->pdev->name, name); + snprintf(label, sizeof(label), "%s:%s", + chip->pdev->name, name); - lm36274_data->num_leds = fwnode_property_count_u32(child, "led-sources"); - if (lm36274_data->num_leds <= 0) + chip->num_leds = fwnode_property_count_u32(child, "led-sources"); + if (chip->num_leds <= 0) return -ENODEV; ret = fwnode_property_read_u32_array(child, "led-sources", - lm36274_data->led_sources, - lm36274_data->num_leds); + chip->led_sources, + chip->num_leds); if (ret) { dev_err(dev, "led-sources property missing\n"); return ret; } fwnode_property_read_string(child, "linux,default-trigger", - &lm36274_data->led_dev.default_trigger); + &chip->led_dev.default_trigger); } - lm36274_data->lmu_data.regmap = lm36274_data->regmap; - lm36274_data->lmu_data.max_brightness = MAX_BRIGHTNESS_11BIT; - lm36274_data->lmu_data.msb_brightness_reg = LM36274_REG_BRT_MSB; - lm36274_data->lmu_data.lsb_brightness_reg = LM36274_REG_BRT_LSB; - - lm36274_data->led_dev.name = label; - lm36274_data->led_dev.max_brightness = MAX_BRIGHTNESS_11BIT; - lm36274_data->led_dev.brightness_set_blocking = lm36274_brightness_set; + chip->lmu_data.regmap = chip->regmap; + chip->lmu_data.max_brightness = MAX_BRIGHTNESS_11BIT; + chip->lmu_data.msb_brightness_reg = LM36274_REG_BRT_MSB; + chip->lmu_data.lsb_brightness_reg = LM36274_REG_BRT_LSB; + + chip->led_dev.name = label; + chip->led_dev.max_brightness = MAX_BRIGHTNESS_11BIT; + chip->led_dev.brightness_set_blocking = lm36274_brightness_set; return 0; } @@ -122,33 +121,40 @@ static int lm36274_probe(struct platform_device *pdev) { struct ti_lmu *lmu = dev_get_drvdata(pdev->dev.parent); - struct lm36274 *lm36274_data; + struct lm36274 *chip; int ret; - lm36274_data = devm_kzalloc(&pdev->dev, sizeof(*lm36274_data), - GFP_KERNEL); - if (!lm36274_data) + chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) return -ENOMEM; - lm36274_data->pdev = pdev; - lm36274_data->dev = lmu->dev; - lm36274_data->regmap = lmu->regmap; - dev_set_drvdata(&pdev->dev, lm36274_data); + chip->pdev = pdev; + chip->dev = lmu->dev; + chip->regmap = lmu->regmap; + platform_set_drvdata(pdev, chip); - ret = lm36274_parse_dt(lm36274_data); + ret = lm36274_parse_dt(chip); if (ret) { - dev_err(lm36274_data->dev, "Failed to parse DT node\n"); + dev_err(chip->dev, "Failed to parse DT node\n"); return ret; } - ret = lm36274_init(lm36274_data); + ret = lm36274_init(chip); if (ret) { - dev_err(lm36274_data->dev, "Failed to init the device\n"); + dev_err(chip->dev, "Failed to init the device\n"); return ret; } - return devm_led_classdev_register(lm36274_data->dev, - &lm36274_data->led_dev); + return led_classdev_register(chip->dev, &chip->led_dev); +} + +static int lm36274_remove(struct platform_device *pdev) +{ + struct lm36274 *chip = platform_get_drvdata(pdev); + + led_classdev_unregister(&chip->led_dev); + + return 0; } static const struct of_device_id of_lm36274_leds_match[] = { @@ -159,6 +165,7 @@ static struct platform_driver lm36274_driver = { .probe = lm36274_probe, + .remove = lm36274_remove, .driver = { .name = "lm36274-leds", }, --- linux-oracle-5.4.0.orig/drivers/leds/leds-lm3692x.c +++ linux-oracle-5.4.0/drivers/leds/leds-lm3692x.c @@ -334,9 +334,18 @@ return ret; } - led->regulator = devm_regulator_get(&led->client->dev, "vled"); - if (IS_ERR(led->regulator)) + led->regulator = devm_regulator_get_optional(&led->client->dev, "vled"); + if (IS_ERR(led->regulator)) { + ret = PTR_ERR(led->regulator); + if (ret != -ENODEV) { + if (ret != -EPROBE_DEFER) + dev_err(&led->client->dev, + "Failed to get vled regulator: %d\n", + ret); + return ret; + } led->regulator = NULL; + } child = device_get_next_child_node(&led->client->dev, child); if (!child) { @@ -349,6 +358,7 @@ ret = fwnode_property_read_u32(child, "reg", &led->led_enable); if (ret) { + fwnode_handle_put(child); dev_err(&led->client->dev, "reg DT property missing\n"); return ret; } @@ -359,12 +369,11 @@ ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev, &init_data); - if (ret) { + if (ret) dev_err(&led->client->dev, "led register err: %d\n", ret); - return ret; - } - return 0; + fwnode_handle_put(init_data.fwnode); + return ret; } static int lm3692x_probe(struct i2c_client *client, --- linux-oracle-5.4.0.orig/drivers/leds/leds-lp5523.c +++ linux-oracle-5.4.0/drivers/leds/leds-lp5523.c @@ -307,7 +307,7 @@ usleep_range(3000, 6000); ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); if (ret) - return ret; + goto out; status &= LP5523_ENG_STATUS_MASK; if (status != LP5523_ENG_STATUS_MASK) { --- linux-oracle-5.4.0.orig/drivers/leds/leds-lp8860.c +++ linux-oracle-5.4.0/drivers/leds/leds-lp8860.c @@ -267,7 +267,7 @@ goto out; } - reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]); + reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs); for (i = 0; i < reg_count; i++) { ret = regmap_write(led->eeprom_regmap, lp8860_eeprom_disp_regs[i].reg, --- linux-oracle-5.4.0.orig/drivers/leds/leds-lt3593.c +++ linux-oracle-5.4.0/drivers/leds/leds-lt3593.c @@ -103,10 +103,9 @@ init_data.default_label = ":"; ret = devm_led_classdev_register_ext(dev, &led_data->cdev, &init_data); - if (ret < 0) { - fwnode_handle_put(child); + fwnode_handle_put(child); + if (ret < 0) return ret; - } led_data->cdev.dev->of_node = dev->of_node; platform_set_drvdata(pdev, led_data); --- linux-oracle-5.4.0.orig/drivers/leds/leds-max77650.c +++ linux-oracle-5.4.0/drivers/leds/leds-max77650.c @@ -135,9 +135,16 @@ return rv; } +static const struct of_device_id max77650_led_of_match[] = { + { .compatible = "maxim,max77650-led" }, + { } +}; +MODULE_DEVICE_TABLE(of, max77650_led_of_match); + static struct platform_driver max77650_led_driver = { .driver = { .name = "max77650-led", + .of_match_table = max77650_led_of_match, }, .probe = max77650_led_probe, }; --- linux-oracle-5.4.0.orig/drivers/leds/leds-mlxreg.c +++ linux-oracle-5.4.0/drivers/leds/leds-mlxreg.c @@ -228,8 +228,8 @@ brightness = LED_OFF; led_data->base_color = MLXREG_LED_GREEN_SOLID; } - sprintf(led_data->led_cdev_name, "%s:%s", "mlxreg", - data->label); + snprintf(led_data->led_cdev_name, sizeof(led_data->led_cdev_name), + "mlxreg:%s", data->label); led_cdev->name = led_data->led_cdev_name; led_cdev->brightness = brightness; led_cdev->max_brightness = LED_ON; --- linux-oracle-5.4.0.orig/drivers/leds/leds-pca963x.c +++ linux-oracle-5.4.0/drivers/leds/leds-pca963x.c @@ -40,6 +40,8 @@ #define PCA963X_LED_PWM 0x2 /* Controlled through PWM */ #define PCA963X_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */ +#define PCA963X_MODE2_OUTDRV 0x04 /* Open-drain or totem pole */ +#define PCA963X_MODE2_INVRT 0x10 /* Normal or inverted direction */ #define PCA963X_MODE2_DMBLNK 0x20 /* Enable blinking */ #define PCA963X_MODE1 0x00 @@ -438,12 +440,12 @@ PCA963X_MODE2); /* Configure output: open-drain or totem pole (push-pull) */ if (pdata->outdrv == PCA963X_OPEN_DRAIN) - mode2 |= 0x01; + mode2 &= ~PCA963X_MODE2_OUTDRV; else - mode2 |= 0x05; + mode2 |= PCA963X_MODE2_OUTDRV; /* Configure direction: normal or inverted */ if (pdata->dir == PCA963X_INVERTED) - mode2 |= 0x10; + mode2 |= PCA963X_MODE2_INVRT; i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2, mode2); } --- linux-oracle-5.4.0.orig/drivers/leds/leds-pwm.c +++ linux-oracle-5.4.0/drivers/leds/leds-pwm.c @@ -22,9 +22,8 @@ struct led_pwm_data { struct led_classdev cdev; struct pwm_device *pwm; + struct pwm_state pwmstate; unsigned int active_low; - unsigned int period; - int duty; }; struct led_pwm_priv { @@ -32,44 +31,29 @@ struct led_pwm_data leds[0]; }; -static void __led_pwm_set(struct led_pwm_data *led_dat) -{ - int new_duty = led_dat->duty; - - pwm_config(led_dat->pwm, new_duty, led_dat->period); - - if (new_duty == 0) - pwm_disable(led_dat->pwm); - else - pwm_enable(led_dat->pwm); -} - static int led_pwm_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct led_pwm_data *led_dat = container_of(led_cdev, struct led_pwm_data, cdev); unsigned int max = led_dat->cdev.max_brightness; - unsigned long long duty = led_dat->period; + unsigned long long duty = led_dat->pwmstate.period; duty *= brightness; do_div(duty, max); if (led_dat->active_low) - duty = led_dat->period - duty; - - led_dat->duty = duty; + duty = led_dat->pwmstate.period - duty; - __led_pwm_set(led_dat); - - return 0; + led_dat->pwmstate.duty_cycle = duty; + led_dat->pwmstate.enabled = true; + return pwm_apply_state(led_dat->pwm, &led_dat->pwmstate); } static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, struct led_pwm *led, struct fwnode_handle *fwnode) { struct led_pwm_data *led_data = &priv->leds[priv->num_leds]; - struct pwm_args pargs; int ret; led_data->active_low = led->active_low; @@ -93,17 +77,10 @@ led_data->cdev.brightness_set_blocking = led_pwm_set; - /* - * FIXME: pwm_apply_args() should be removed when switching to the - * atomic PWM API. - */ - pwm_apply_args(led_data->pwm); - - pwm_get_args(led_data->pwm, &pargs); - - led_data->period = pargs.period; - if (!led_data->period && (led->pwm_period_ns > 0)) - led_data->period = led->pwm_period_ns; + pwm_init_state(led_data->pwm, &led_data->pwmstate); + + if (!led_data->pwmstate.period) + led_data->pwmstate.period = led->pwm_period_ns; ret = devm_led_classdev_register(dev, &led_data->cdev); if (ret == 0) { --- linux-oracle-5.4.0.orig/drivers/leds/leds-ss4200.c +++ linux-oracle-5.4.0/drivers/leds/leds-ss4200.c @@ -356,8 +356,10 @@ nas_gpio_pci_dev = dev; status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base); - if (status) + if (status) { + status = pcibios_err_to_errno(status); goto out; + } g_pm_io_base &= 0x00000ff80; status = pci_read_config_dword(dev, GPIO_CTRL, &gc); @@ -369,8 +371,9 @@ } status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base); - if (0 > status) { + if (status) { dev_info(&dev->dev, "Unable to read GPIOBASE.\n"); + status = pcibios_err_to_errno(status); goto out; } dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base); --- linux-oracle-5.4.0.orig/drivers/leds/leds-tlc591xx.c +++ linux-oracle-5.4.0/drivers/leds/leds-tlc591xx.c @@ -13,6 +13,7 @@ #include #define TLC591XX_MAX_LEDS 16 +#define TLC591XX_MAX_BRIGHTNESS 256 #define TLC591XX_REG_MODE1 0x00 #define MODE1_RESPON_ADDR_MASK 0xF0 @@ -112,11 +113,11 @@ struct tlc591xx_priv *priv = led->priv; int err; - switch (brightness) { + switch ((int)brightness) { case 0: err = tlc591xx_set_ledout(priv, led, LEDOUT_OFF); break; - case LED_FULL: + case TLC591XX_MAX_BRIGHTNESS: err = tlc591xx_set_ledout(priv, led, LEDOUT_ON); break; default: @@ -157,7 +158,7 @@ led->priv = priv; led->led_no = i; led->ldev.brightness_set_blocking = tlc591xx_brightness_set; - led->ldev.max_brightness = LED_FULL; + led->ldev.max_brightness = TLC591XX_MAX_BRIGHTNESS; err = led_classdev_register(dev, &led->ldev); if (err < 0) { dev_err(dev, "couldn't register LED %s\n", --- linux-oracle-5.4.0.orig/drivers/leds/leds-wm831x-status.c +++ linux-oracle-5.4.0/drivers/leds/leds-wm831x-status.c @@ -269,12 +269,23 @@ drvdata->cdev.blink_set = wm831x_status_blink_set; drvdata->cdev.groups = wm831x_status_groups; - ret = devm_led_classdev_register(wm831x->dev, &drvdata->cdev); + ret = led_classdev_register(wm831x->dev, &drvdata->cdev); if (ret < 0) { dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); return ret; } + platform_set_drvdata(pdev, drvdata); + + return 0; +} + +static int wm831x_status_remove(struct platform_device *pdev) +{ + struct wm831x_status *drvdata = platform_get_drvdata(pdev); + + led_classdev_unregister(&drvdata->cdev); + return 0; } @@ -283,6 +294,7 @@ .name = "wm831x-status", }, .probe = wm831x_status_probe, + .remove = wm831x_status_remove, }; module_platform_driver(wm831x_status_driver); --- linux-oracle-5.4.0.orig/drivers/leds/trigger/ledtrig-audio.c +++ linux-oracle-5.4.0/drivers/leds/trigger/ledtrig-audio.c @@ -6,10 +6,33 @@ #include #include #include +#include "../leds.h" -static struct led_trigger *ledtrig_audio[NUM_AUDIO_LEDS]; static enum led_brightness audio_state[NUM_AUDIO_LEDS]; +static int ledtrig_audio_mute_activate(struct led_classdev *led_cdev) +{ + led_set_brightness_nosleep(led_cdev, audio_state[LED_AUDIO_MUTE]); + return 0; +} + +static int ledtrig_audio_micmute_activate(struct led_classdev *led_cdev) +{ + led_set_brightness_nosleep(led_cdev, audio_state[LED_AUDIO_MICMUTE]); + return 0; +} + +static struct led_trigger ledtrig_audio[NUM_AUDIO_LEDS] = { + [LED_AUDIO_MUTE] = { + .name = "audio-mute", + .activate = ledtrig_audio_mute_activate, + }, + [LED_AUDIO_MICMUTE] = { + .name = "audio-micmute", + .activate = ledtrig_audio_micmute_activate, + }, +}; + enum led_brightness ledtrig_audio_get(enum led_audio type) { return audio_state[type]; @@ -19,24 +42,22 @@ void ledtrig_audio_set(enum led_audio type, enum led_brightness state) { audio_state[type] = state; - led_trigger_event(ledtrig_audio[type], state); + led_trigger_event(&ledtrig_audio[type], state); } EXPORT_SYMBOL_GPL(ledtrig_audio_set); static int __init ledtrig_audio_init(void) { - led_trigger_register_simple("audio-mute", - &ledtrig_audio[LED_AUDIO_MUTE]); - led_trigger_register_simple("audio-micmute", - &ledtrig_audio[LED_AUDIO_MICMUTE]); + led_trigger_register(&ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_register(&ledtrig_audio[LED_AUDIO_MICMUTE]); return 0; } module_init(ledtrig_audio_init); static void __exit ledtrig_audio_exit(void) { - led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MUTE]); - led_trigger_unregister_simple(ledtrig_audio[LED_AUDIO_MICMUTE]); + led_trigger_unregister(&ledtrig_audio[LED_AUDIO_MUTE]); + led_trigger_unregister(&ledtrig_audio[LED_AUDIO_MICMUTE]); } module_exit(ledtrig_audio_exit); --- linux-oracle-5.4.0.orig/drivers/leds/trigger/ledtrig-cpu.c +++ linux-oracle-5.4.0/drivers/leds/trigger/ledtrig-cpu.c @@ -2,14 +2,18 @@ /* * ledtrig-cpu.c - LED trigger based on CPU activity * - * This LED trigger will be registered for each possible CPU and named as - * cpu0, cpu1, cpu2, cpu3, etc. + * This LED trigger will be registered for first 8 CPUs and named + * as cpu0..cpu7. There's additional trigger called cpu that + * is on when any CPU is active. + * + * If you want support for arbitrary number of CPUs, make it one trigger, + * with additional sysfs file selecting which CPU to watch. * * It can be bound to any LED just like other triggers using either a * board file or via sysfs interface. * * An API named ledtrig_cpu is exported for any user, who want to add CPU - * activity indication in their code + * activity indication in their code. * * Copyright 2011 Linus Walleij * Copyright 2011 - 2012 Bryan Wu @@ -126,7 +130,7 @@ static int __init ledtrig_cpu_init(void) { - int cpu; + unsigned int cpu; int ret; /* Supports up to 9999 cpu cores */ @@ -145,7 +149,10 @@ for_each_possible_cpu(cpu) { struct led_trigger_cpu *trig = &per_cpu(cpu_trig, cpu); - snprintf(trig->name, MAX_NAME_LEN, "cpu%d", cpu); + if (cpu >= 8) + continue; + + snprintf(trig->name, MAX_NAME_LEN, "cpu%u", cpu); led_trigger_register_simple(trig->name, &trig->_trig); } --- linux-oracle-5.4.0.orig/drivers/leds/trigger/ledtrig-netdev.c +++ linux-oracle-5.4.0/drivers/leds/trigger/ledtrig-netdev.c @@ -302,10 +302,12 @@ container_of(nb, struct led_netdev_data, notifier); if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE - && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER) + && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER + && evt != NETDEV_CHANGENAME) return NOTIFY_DONE; if (!(dev == trigger_data->net_dev || + (evt == NETDEV_CHANGENAME && !strcmp(dev->name, trigger_data->device_name)) || (evt == NETDEV_REGISTER && !strcmp(dev->name, trigger_data->device_name)))) return NOTIFY_DONE; @@ -315,6 +317,10 @@ clear_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); switch (evt) { + case NETDEV_CHANGENAME: + if (netif_carrier_ok(dev)) + set_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode); + fallthrough; case NETDEV_REGISTER: if (trigger_data->net_dev) dev_put(trigger_data->net_dev); --- linux-oracle-5.4.0.orig/drivers/leds/trigger/ledtrig-panic.c +++ linux-oracle-5.4.0/drivers/leds/trigger/ledtrig-panic.c @@ -63,10 +63,13 @@ static int __init ledtrig_panic_init(void) { + led_trigger_register_simple("panic", &trigger); + if (!trigger) + return -ENOMEM; + atomic_notifier_chain_register(&panic_notifier_list, &led_trigger_panic_nb); - led_trigger_register_simple("panic", &trigger); panic_blink = led_panic_blink; return 0; } --- linux-oracle-5.4.0.orig/drivers/lightnvm/Kconfig +++ linux-oracle-5.4.0/drivers/lightnvm/Kconfig @@ -5,7 +5,7 @@ menuconfig NVM bool "Open-Channel SSD target support" - depends on BLOCK + depends on BLOCK && BROKEN help Say Y here to get to enable Open-channel SSDs. @@ -19,6 +19,7 @@ config NVM_PBLK tristate "Physical Block Device Open-Channel SSD target" + select CRC32 help Allows an open-channel SSD to be exposed as a block device to the host. The target assumes the device exposes raw flash and must be --- linux-oracle-5.4.0.orig/drivers/lightnvm/core.c +++ linux-oracle-5.4.0/drivers/lightnvm/core.c @@ -849,11 +849,10 @@ rqd.ppa_addr = generic_to_dev_addr(dev, ppa); ret = nvm_submit_io_sync_raw(dev, &rqd); + __free_page(page); if (ret) return ret; - __free_page(page); - return rqd.error; } @@ -1316,8 +1315,9 @@ strlcpy(info->bmname, "gennvm", sizeof(info->bmname)); i++; - if (i > 31) { - pr_err("max 31 devices can be reported.\n"); + if (i >= ARRAY_SIZE(devices->info)) { + pr_err("max %zd devices can be reported.\n", + ARRAY_SIZE(devices->info)); break; } } --- linux-oracle-5.4.0.orig/drivers/macintosh/Kconfig +++ linux-oracle-5.4.0/drivers/macintosh/Kconfig @@ -44,6 +44,7 @@ config ADB_CUDA bool "Support for Cuda/Egret based Macs and PowerMacs" depends on (ADB || PPC_PMAC) && !PPC_PMAC64 + select RTC_LIB help This provides support for Cuda/Egret based Macintosh and Power Macintosh systems. This includes most m68k based Macs, @@ -57,6 +58,7 @@ config ADB_PMU bool "Support for PMU based PowerMacs and PowerBooks" depends on PPC_PMAC || MAC + select RTC_LIB help On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the PMU is an embedded microprocessor whose primary function is to @@ -67,6 +69,10 @@ this device; you should do so if your machine is one of those mentioned above. +config ADB_PMU_EVENT + def_bool y + depends on ADB_PMU && INPUT=y + config ADB_PMU_LED bool "Support for the Power/iBook front LED" depends on PPC_PMAC && ADB_PMU @@ -80,6 +86,7 @@ config ADB_PMU_LED_DISK bool "Use front LED as DISK LED by default" + depends on ATA depends on ADB_PMU_LED depends on LEDS_CLASS select LEDS_TRIGGERS --- linux-oracle-5.4.0.orig/drivers/macintosh/Makefile +++ linux-oracle-5.4.0/drivers/macintosh/Makefile @@ -12,7 +12,8 @@ obj-$(CONFIG_INPUT_ADBHID) += adbhid.o obj-$(CONFIG_ANSLCD) += ans-lcd.o -obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o +obj-$(CONFIG_ADB_PMU) += via-pmu.o +obj-$(CONFIG_ADB_PMU_EVENT) += via-pmu-event.o obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o --- linux-oracle-5.4.0.orig/drivers/macintosh/adb.c +++ linux-oracle-5.4.0/drivers/macintosh/adb.c @@ -647,7 +647,7 @@ switch(req->data[1]) { case ADB_QUERY_GETDEVINFO: - if (req->nbytes < 3) + if (req->nbytes < 3 || req->data[2] >= 16) break; mutex_lock(&adb_handler_mutex); req->reply[0] = adb_handler[req->data[2]].original_address; --- linux-oracle-5.4.0.orig/drivers/macintosh/macio-adb.c +++ linux-oracle-5.4.0/drivers/macintosh/macio-adb.c @@ -106,6 +106,10 @@ return -ENXIO; } adb = ioremap(r.start, sizeof(struct adb_regs)); + if (!adb) { + of_node_put(adbs); + return -ENOMEM; + } out_8(&adb->ctrl.r, 0); out_8(&adb->intr.r, 0); --- linux-oracle-5.4.0.orig/drivers/macintosh/macio_asic.c +++ linux-oracle-5.4.0/drivers/macintosh/macio_asic.c @@ -425,7 +425,7 @@ if (of_device_register(&dev->ofdev) != 0) { printk(KERN_DEBUG"macio: device registration error for %s!\n", dev_name(&dev->ofdev.dev)); - kfree(dev); + put_device(&dev->ofdev.dev); return NULL; } --- linux-oracle-5.4.0.orig/drivers/macintosh/therm_windtunnel.c +++ linux-oracle-5.4.0/drivers/macintosh/therm_windtunnel.c @@ -300,9 +300,11 @@ /* i2c probing and setup */ /************************************************************************/ -static int -do_attach( struct i2c_adapter *adapter ) +static void do_attach(struct i2c_adapter *adapter) { + struct i2c_board_info info = { }; + struct device_node *np; + /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ static const unsigned short scan_ds1775[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, @@ -313,25 +315,24 @@ I2C_CLIENT_END }; - if( strncmp(adapter->name, "uni-n", 5) ) - return 0; - - if( !x.running ) { - struct i2c_board_info info; + if (x.running || strncmp(adapter->name, "uni-n", 5)) + return; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); + np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775"); + if (np) { + of_node_put(np); + } else { + strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE); i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); + } - strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); + np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030"); + if (np) { + of_node_put(np); + } else { + strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE); i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); - - if( x.thermostat && x.fan ) { - x.running = 1; - x.poll_task = kthread_run(control_loop, NULL, "g4fand"); - } } - return 0; } static int @@ -404,8 +405,8 @@ enum chip { ds1775, adm1030 }; static const struct i2c_device_id therm_windtunnel_id[] = { - { "therm_ds1775", ds1775 }, - { "therm_adm1030", adm1030 }, + { "MAC,ds1775", ds1775 }, + { "MAC,adm1030", adm1030 }, { } }; MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); @@ -414,6 +415,7 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id) { struct i2c_adapter *adapter = cl->adapter; + int ret = 0; if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WRITE_BYTE) ) @@ -421,11 +423,19 @@ switch (id->driver_data) { case adm1030: - return attach_fan( cl ); + ret = attach_fan(cl); + break; case ds1775: - return attach_thermostat(cl); + ret = attach_thermostat(cl); + break; } - return 0; + + if (!x.running && x.thermostat && x.fan) { + x.running = 1; + x.poll_task = kthread_run(control_loop, NULL, "g4fand"); + } + + return ret; } static struct i2c_driver g4fan_driver = { @@ -539,7 +549,7 @@ platform_driver_unregister( &therm_of_driver ); if( x.of_dev ) - of_device_unregister( x.of_dev ); + of_platform_device_destroy(&x.of_dev->dev, NULL); } module_init(g4fan_init); --- linux-oracle-5.4.0.orig/drivers/macintosh/via-macii.c +++ linux-oracle-5.4.0/drivers/macintosh/via-macii.c @@ -135,24 +135,19 @@ /* Initialize the driver */ int macii_init(void) { - unsigned long flags; int err; - local_irq_save(flags); - err = macii_init_via(); if (err) - goto out; + return err; err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB", macii_interrupt); if (err) - goto out; + return err; macii_state = idle; -out: - local_irq_restore(flags); - return err; + return 0; } /* initialize the hardware */ @@ -270,15 +265,12 @@ unsigned long flags; int err = 0; + local_irq_save(flags); + /* bit 1 == device 1, and so on. */ autopoll_devs = devs & 0xFFFE; - if (!autopoll_devs) - return 0; - - local_irq_save(flags); - - if (current_req == NULL) { + if (autopoll_devs && !current_req) { /* Send a Talk Reg 0. The controller will repeatedly transmit * this as long as it is idle. */ --- linux-oracle-5.4.0.orig/drivers/macintosh/via-pmu.c +++ linux-oracle-5.4.0/drivers/macintosh/via-pmu.c @@ -1464,7 +1464,7 @@ pmu_pass_intr(data, len); /* len == 6 is probably a bad check. But how do I * know what PMU versions send what events here? */ - if (len == 6) { + if (IS_ENABLED(CONFIG_ADB_PMU_EVENT) && len == 6) { via_pmu_event(PMU_EVT_POWER, !!(data[1]&8)); via_pmu_event(PMU_EVT_LID, data[1]&1); } --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_ad7417_sensor.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_ad7417_sensor.c @@ -312,9 +312,16 @@ }; MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); +static const struct of_device_id wf_ad7417_of_id[] = { + { .compatible = "ad7417", }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_ad7417_of_id); + static struct i2c_driver wf_ad7417_driver = { .driver = { .name = "wf_ad7417", + .of_match_table = wf_ad7417_of_id, }, .probe = wf_ad7417_probe, .remove = wf_ad7417_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_fcu_controls.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_fcu_controls.c @@ -582,9 +582,16 @@ }; MODULE_DEVICE_TABLE(i2c, wf_fcu_id); +static const struct of_device_id wf_fcu_of_id[] = { + { .compatible = "fcu", }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_fcu_of_id); + static struct i2c_driver wf_fcu_driver = { .driver = { .name = "wf_fcu", + .of_match_table = wf_fcu_of_id, }, .probe = wf_fcu_probe, .remove = wf_fcu_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_lm75_sensor.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_lm75_sensor.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -33,8 +34,8 @@ #endif struct wf_lm75_sensor { - int ds1775 : 1; - int inited : 1; + unsigned int ds1775 : 1; + unsigned int inited : 1; struct i2c_client *i2c; struct wf_sensor sens; }; @@ -91,9 +92,14 @@ const struct i2c_device_id *id) { struct wf_lm75_sensor *lm; - int rc, ds1775 = id->driver_data; + int rc, ds1775; const char *name, *loc; + if (id) + ds1775 = id->driver_data; + else + ds1775 = !!of_device_get_match_data(&client->dev); + DBG("wf_lm75: creating %s device at address 0x%02x\n", ds1775 ? "ds1775" : "lm75", client->addr); @@ -164,9 +170,17 @@ }; MODULE_DEVICE_TABLE(i2c, wf_lm75_id); +static const struct of_device_id wf_lm75_of_id[] = { + { .compatible = "lm75", .data = (void *)0}, + { .compatible = "ds1775", .data = (void *)1 }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_lm75_of_id); + static struct i2c_driver wf_lm75_driver = { .driver = { .name = "wf_lm75", + .of_match_table = wf_lm75_of_id, }, .probe = wf_lm75_probe, .remove = wf_lm75_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_lm87_sensor.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_lm87_sensor.c @@ -166,9 +166,16 @@ }; MODULE_DEVICE_TABLE(i2c, wf_lm87_id); +static const struct of_device_id wf_lm87_of_id[] = { + { .compatible = "lm87cimt", }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_lm87_of_id); + static struct i2c_driver wf_lm87_driver = { .driver = { .name = "wf_lm87", + .of_match_table = wf_lm87_of_id, }, .probe = wf_lm87_probe, .remove = wf_lm87_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_max6690_sensor.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_max6690_sensor.c @@ -120,9 +120,16 @@ }; MODULE_DEVICE_TABLE(i2c, wf_max6690_id); +static const struct of_device_id wf_max6690_of_id[] = { + { .compatible = "max6690", }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_max6690_of_id); + static struct i2c_driver wf_max6690_driver = { .driver = { .name = "wf_max6690", + .of_match_table = wf_max6690_of_id, }, .probe = wf_max6690_probe, .remove = wf_max6690_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_pm112.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_pm112.c @@ -132,14 +132,6 @@ s32 tmax; int fmin; - /* Get PID params from the appropriate SAT */ - hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); - if (hdr == NULL) { - printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); - return -EINVAL; - } - piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; - /* Get FVT params to get Tmax; if not found, assume default */ hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); if (hdr) { @@ -152,6 +144,16 @@ if (tmax < cpu_all_tmax) cpu_all_tmax = tmax; + kfree(hdr); + + /* Get PID params from the appropriate SAT */ + hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); + if (hdr == NULL) { + printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); + return -EINVAL; + } + piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; + /* * Darwin has a minimum fan speed of 1000 rpm for the 4-way and * 515 for the 2-way. That appears to be overkill, so for now, @@ -174,6 +176,9 @@ pid.min = fmin; wf_cpu_pid_init(&cpu_pid[cpu], &pid); + + kfree(hdr); + return 0; } --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_smu_sat.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_smu_sat.c @@ -171,6 +171,7 @@ if (sat->nr >= 0) sats[sat->nr] = NULL; + of_node_put(sat->node); kfree(sat); } @@ -341,9 +342,16 @@ }; MODULE_DEVICE_TABLE(i2c, wf_sat_id); +static const struct of_device_id wf_sat_of_id[] = { + { .compatible = "smu-sat", }, + { } +}; +MODULE_DEVICE_TABLE(of, wf_sat_of_id); + static struct i2c_driver wf_sat_driver = { .driver = { .name = "wf_smu_sat", + .of_match_table = wf_sat_of_id, }, .probe = wf_sat_probe, .remove = wf_sat_remove, --- linux-oracle-5.4.0.orig/drivers/macintosh/windfarm_smu_sensors.c +++ linux-oracle-5.4.0/drivers/macintosh/windfarm_smu_sensors.c @@ -273,8 +273,8 @@ struct list_head link; struct wf_sensor *volts; struct wf_sensor *amps; - int fake_volts : 1; - int quadratic : 1; + unsigned int fake_volts : 1; + unsigned int quadratic : 1; struct wf_sensor sens; }; #define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens) --- linux-oracle-5.4.0.orig/drivers/mailbox/bcm-flexrm-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/bcm-flexrm-mailbox.c @@ -632,15 +632,15 @@ rc = dma_map_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - if (rc < 0) - return rc; + if (!rc) + return -EIO; rc = dma_map_sg(dev, msg->spu.dst, sg_nents(msg->spu.dst), DMA_FROM_DEVICE); - if (rc < 0) { + if (!rc) { dma_unmap_sg(dev, msg->spu.src, sg_nents(msg->spu.src), DMA_TO_DEVICE); - return rc; + return -EIO; } return 0; --- linux-oracle-5.4.0.orig/drivers/mailbox/bcm2835-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/bcm2835-mailbox.c @@ -146,7 +146,8 @@ spin_lock_init(&mbox->lock); ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0), - bcm2835_mbox_irq, 0, dev_name(dev), mbox); + bcm2835_mbox_irq, IRQF_NO_SUSPEND, dev_name(dev), + mbox); if (ret) { dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n", ret); --- linux-oracle-5.4.0.orig/drivers/mailbox/imx-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/imx-mailbox.c @@ -214,11 +214,24 @@ struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox); struct imx_mu_con_priv *cp = chan->con_priv; - if (cp->type == IMX_MU_TYPE_TXDB) + if (cp->type == IMX_MU_TYPE_TXDB) { tasklet_kill(&cp->txdb_tasklet); + return; + } - imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx) | - IMX_MU_xCR_RIEn(cp->idx) | IMX_MU_xCR_GIEn(cp->idx)); + switch (cp->type) { + case IMX_MU_TYPE_TX: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_TIEn(cp->idx)); + break; + case IMX_MU_TYPE_RX: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_RIEn(cp->idx)); + break; + case IMX_MU_TYPE_RXDB: + imx_mu_xcr_rmw(priv, 0, IMX_MU_xCR_GIEn(cp->idx)); + break; + default: + break; + } free_irq(priv->irq, chan); } --- linux-oracle-5.4.0.orig/drivers/mailbox/mailbox-test.c +++ linux-oracle-5.4.0/drivers/mailbox/mailbox-test.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ char *signal; char *message; spinlock_t lock; + struct mutex mutex; wait_queue_head_t waitq; struct fasync_struct *async_queue; struct dentry *root_debugfs_dir; @@ -95,6 +97,7 @@ size_t count, loff_t *ppos) { struct mbox_test_device *tdev = filp->private_data; + char *message; void *data; int ret; @@ -110,10 +113,13 @@ return -EINVAL; } - tdev->message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); - if (!tdev->message) + message = kzalloc(MBOX_MAX_MSG_LEN, GFP_KERNEL); + if (!message) return -ENOMEM; + mutex_lock(&tdev->mutex); + + tdev->message = message; ret = copy_from_user(tdev->message, userbuf, count); if (ret) { ret = -EFAULT; @@ -144,6 +150,8 @@ kfree(tdev->message); tdev->signal = NULL; + mutex_unlock(&tdev->mutex); + return ret < 0 ? ret : count; } @@ -392,6 +400,7 @@ platform_set_drvdata(pdev, tdev); spin_lock_init(&tdev->lock); + mutex_init(&tdev->mutex); if (tdev->rx_channel) { tdev->rx_buffer = devm_kzalloc(&pdev->dev, --- linux-oracle-5.4.0.orig/drivers/mailbox/mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/mailbox.c @@ -82,9 +82,12 @@ exit: spin_unlock_irqrestore(&chan->lock, flags); - if (!err && (chan->txdone_method & TXDONE_BY_POLL)) + if (!err && (chan->txdone_method & TXDONE_BY_POLL)) { /* kick start the timer immediately to avoid delays */ + spin_lock_irqsave(&chan->mbox->poll_hrt_lock, flags); hrtimer_start(&chan->mbox->poll_hrt, 0, HRTIMER_MODE_REL); + spin_unlock_irqrestore(&chan->mbox->poll_hrt_lock, flags); + } } static void tx_tick(struct mbox_chan *chan, int r) @@ -117,6 +120,7 @@ container_of(hrtimer, struct mbox_controller, poll_hrt); bool txdone, resched = false; int i; + unsigned long flags; for (i = 0; i < mbox->num_chans; i++) { struct mbox_chan *chan = &mbox->chans[i]; @@ -131,7 +135,11 @@ } if (resched) { - hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); + spin_lock_irqsave(&mbox->poll_hrt_lock, flags); + if (!hrtimer_is_queued(hrtimer)) + hrtimer_forward_now(hrtimer, ms_to_ktime(mbox->txpoll_period)); + spin_unlock_irqrestore(&mbox->poll_hrt_lock, flags); + return HRTIMER_RESTART; } return HRTIMER_NORESTART; @@ -498,6 +506,7 @@ hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); mbox->poll_hrt.function = txdone_hrtimer; + spin_lock_init(&mbox->poll_hrt_lock); } for (i = 0; i < mbox->num_chans; i++) { --- linux-oracle-5.4.0.orig/drivers/mailbox/mtk-cmdq-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/mtk-cmdq-mailbox.c @@ -70,7 +70,7 @@ struct cmdq { struct mbox_controller mbox; void __iomem *base; - u32 irq; + int irq; u32 thread_nr; u32 irq_mask; struct cmdq_thread *thread; @@ -474,10 +474,8 @@ } cmdq->irq = platform_get_irq(pdev, 0); - if (!cmdq->irq) { - dev_err(dev, "failed to get irq\n"); - return -EINVAL; - } + if (cmdq->irq < 0) + return cmdq->irq; cmdq->thread_nr = (u32)(unsigned long)of_device_get_match_data(dev); cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0); --- linux-oracle-5.4.0.orig/drivers/mailbox/rockchip-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/rockchip-mailbox.c @@ -159,7 +159,7 @@ { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data}, { }, }; -MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match); +MODULE_DEVICE_TABLE(of, rockchip_mbox_of_match); static int rockchip_mbox_probe(struct platform_device *pdev) { --- linux-oracle-5.4.0.orig/drivers/mailbox/tegra-hsp.c +++ linux-oracle-5.4.0/drivers/mailbox/tegra-hsp.c @@ -403,6 +403,11 @@ value = tegra_hsp_channel_readl(ch, HSP_SM_SHRD_MBOX); if ((value & HSP_SM_SHRD_MBOX_FULL) == 0) { mbox_chan_txdone(chan, 0); + + /* Wait until channel is empty */ + if (chan->active_req != NULL) + continue; + return 0; } @@ -657,7 +662,7 @@ hsp->num_db = (value >> HSP_nDB_SHIFT) & HSP_nINT_MASK; hsp->num_si = (value >> HSP_nSI_SHIFT) & HSP_nINT_MASK; - err = platform_get_irq_byname(pdev, "doorbell"); + err = platform_get_irq_byname_optional(pdev, "doorbell"); if (err >= 0) hsp->doorbell_irq = err; @@ -677,7 +682,7 @@ if (!name) return -ENOMEM; - err = platform_get_irq_byname(pdev, name); + err = platform_get_irq_byname_optional(pdev, name); if (err >= 0) { hsp->shared_irqs[i] = err; count++; --- linux-oracle-5.4.0.orig/drivers/mailbox/ti-msgmgr.c +++ linux-oracle-5.4.0/drivers/mailbox/ti-msgmgr.c @@ -385,14 +385,20 @@ /* Ensure all unused data is 0 */ data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); writel(data_trail, data_reg); - data_reg++; + data_reg += sizeof(u32); } + /* * 'data_reg' indicates next register to write. If we did not already * write on tx complete reg(last reg), we must do so for transmit + * In addition, we also need to make sure all intermediate data + * registers(if any required), are reset to 0 for TISCI backward + * compatibility to be maintained. */ - if (data_reg <= qinst->queue_buff_end) - writel(0, qinst->queue_buff_end); + while (data_reg <= qinst->queue_buff_end) { + writel(0, data_reg); + data_reg += sizeof(u32); + } return 0; } --- linux-oracle-5.4.0.orig/drivers/mailbox/zynqmp-ipi-mailbox.c +++ linux-oracle-5.4.0/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -110,7 +110,7 @@ unsigned int method; u32 local_id; int num_mboxes; - struct zynqmp_ipi_mbox *ipi_mboxes; + struct zynqmp_ipi_mbox ipi_mboxes[]; }; static struct device_driver zynqmp_ipi_mbox_driver = { @@ -152,7 +152,7 @@ struct zynqmp_ipi_message *msg; u64 arg0, arg3; struct arm_smccc_res res; - int ret, i; + int ret, i, status = IRQ_NONE; (void)irq; arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY; @@ -170,11 +170,11 @@ memcpy_fromio(msg->data, mchan->req_buf, msg->len); mbox_chan_received_data(chan, (void *)msg); - return IRQ_HANDLED; + status = IRQ_HANDLED; } } } - return IRQ_NONE; + return status; } /** @@ -493,6 +493,7 @@ ret = device_register(&ipi_mbox->dev); if (ret) { dev_err(dev, "Failed to register ipi mbox dev.\n"); + put_device(&ipi_mbox->dev); return ret; } mdev = &ipi_mbox->dev; @@ -504,10 +505,9 @@ mchan->req_buf_size = resource_size(&res); mchan->req_buf = devm_ioremap(mdev, res.start, mchan->req_buf_size); - if (IS_ERR(mchan->req_buf)) { + if (!mchan->req_buf) { dev_err(mdev, "Unable to map IPI buffer I/O memory\n"); - ret = PTR_ERR(mchan->req_buf); - return ret; + return -ENOMEM; } } else if (ret != -ENODEV) { dev_err(mdev, "Unmatched resource %s, %d.\n", name, ret); @@ -520,10 +520,9 @@ mchan->resp_buf_size = resource_size(&res); mchan->resp_buf = devm_ioremap(mdev, res.start, mchan->resp_buf_size); - if (IS_ERR(mchan->resp_buf)) { + if (!mchan->resp_buf) { dev_err(mdev, "Unable to map IPI buffer I/O memory\n"); - ret = PTR_ERR(mchan->resp_buf); - return ret; + return -ENOMEM; } } else if (ret != -ENODEV) { dev_err(mdev, "Unmatched resource %s.\n", name); @@ -543,10 +542,9 @@ mchan->req_buf_size = resource_size(&res); mchan->req_buf = devm_ioremap(mdev, res.start, mchan->req_buf_size); - if (IS_ERR(mchan->req_buf)) { + if (!mchan->req_buf) { dev_err(mdev, "Unable to map IPI buffer I/O memory\n"); - ret = PTR_ERR(mchan->req_buf); - return ret; + return -ENOMEM; } } else if (ret != -ENODEV) { dev_err(mdev, "Unmatched resource %s.\n", name); @@ -559,10 +557,9 @@ mchan->resp_buf_size = resource_size(&res); mchan->resp_buf = devm_ioremap(mdev, res.start, mchan->resp_buf_size); - if (IS_ERR(mchan->resp_buf)) { + if (!mchan->resp_buf) { dev_err(mdev, "Unable to map IPI buffer I/O memory\n"); - ret = PTR_ERR(mchan->resp_buf); - return ret; + return -ENOMEM; } } else if (ret != -ENODEV) { dev_err(mdev, "Unmatched resource %s.\n", name); @@ -623,7 +620,8 @@ ipi_mbox = &pdata->ipi_mboxes[i]; if (ipi_mbox->dev.parent) { mbox_controller_unregister(&ipi_mbox->mbox); - device_unregister(&ipi_mbox->dev); + if (device_is_registered(&ipi_mbox->dev)) + device_unregister(&ipi_mbox->dev); } } } @@ -636,8 +634,13 @@ struct zynqmp_ipi_mbox *mbox; int num_mboxes, ret = -EINVAL; - num_mboxes = of_get_child_count(np); - pdata = devm_kzalloc(dev, sizeof(*pdata) + (num_mboxes * sizeof(*mbox)), + num_mboxes = of_get_available_child_count(np); + if (num_mboxes == 0) { + dev_err(dev, "mailbox nodes not available\n"); + return -EINVAL; + } + + pdata = devm_kzalloc(dev, struct_size(pdata, ipi_mboxes, num_mboxes), GFP_KERNEL); if (!pdata) return -ENOMEM; @@ -651,8 +654,6 @@ } pdata->num_mboxes = num_mboxes; - pdata->ipi_mboxes = (struct zynqmp_ipi_mbox *) - ((char *)pdata + sizeof(*pdata)); mbox = pdata->ipi_mboxes; for_each_available_child_of_node(np, nc) { --- linux-oracle-5.4.0.orig/drivers/mcb/mcb-core.c +++ linux-oracle-5.4.0/drivers/mcb/mcb-core.c @@ -71,8 +71,10 @@ get_device(dev); ret = mdrv->probe(mdev, found_id); - if (ret) + if (ret) { module_put(carrier_mod); + put_device(dev); + } return ret; } @@ -246,6 +248,7 @@ return 0; out: + put_device(&dev->dev); return ret; } @@ -277,8 +280,8 @@ bus_nr = ida_simple_get(&mcb_ida, 0, 0, GFP_KERNEL); if (bus_nr < 0) { - rc = bus_nr; - goto err_free; + kfree(bus); + return ERR_PTR(bus_nr); } bus->bus_nr = bus_nr; @@ -293,12 +296,12 @@ dev_set_name(&bus->dev, "mcb:%d", bus_nr); rc = device_add(&bus->dev); if (rc) - goto err_free; + goto err_put; return bus; -err_free: - put_device(carrier); - kfree(bus); + +err_put: + put_device(&bus->dev); return ERR_PTR(rc); } EXPORT_SYMBOL_GPL(mcb_alloc_bus); @@ -387,17 +390,13 @@ static int __mcb_bus_add_devices(struct device *dev, void *data) { - struct mcb_device *mdev = to_mcb_device(dev); int retval; - if (mdev->is_added) - return 0; - retval = device_attach(dev); - if (retval < 0) + if (retval < 0) { dev_err(dev, "Error adding device (%d)\n", retval); - - mdev->is_added = true; + return retval; + } return 0; } --- linux-oracle-5.4.0.orig/drivers/mcb/mcb-lpc.c +++ linux-oracle-5.4.0/drivers/mcb/mcb-lpc.c @@ -23,7 +23,7 @@ { struct resource *res; struct priv *priv; - int ret = 0; + int ret = 0, table_size; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -58,16 +58,43 @@ ret = chameleon_parse_cells(priv->bus, priv->mem->start, priv->base); if (ret < 0) { - mcb_release_bus(priv->bus); - return ret; + goto out_mcb_bus; } - dev_dbg(&pdev->dev, "Found %d cells\n", ret); + table_size = ret; + + if (table_size < CHAM_HEADER_SIZE) { + /* Release the previous resources */ + devm_iounmap(&pdev->dev, priv->base); + devm_release_mem_region(&pdev->dev, priv->mem->start, resource_size(priv->mem)); + + /* Then, allocate it again with the actual chameleon table size */ + res = devm_request_mem_region(&pdev->dev, priv->mem->start, + table_size, + KBUILD_MODNAME); + if (!res) { + dev_err(&pdev->dev, "Failed to request PCI memory\n"); + ret = -EBUSY; + goto out_mcb_bus; + } + + priv->base = devm_ioremap(&pdev->dev, priv->mem->start, table_size); + if (!priv->base) { + dev_err(&pdev->dev, "Cannot ioremap\n"); + ret = -ENOMEM; + goto out_mcb_bus; + } + + platform_set_drvdata(pdev, priv); + } mcb_bus_add_devices(priv->bus); return 0; +out_mcb_bus: + mcb_release_bus(priv->bus); + return ret; } static int mcb_lpc_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/mcb/mcb-parse.c +++ linux-oracle-5.4.0/drivers/mcb/mcb-parse.c @@ -99,8 +99,6 @@ mdev->mem.end = mdev->mem.start + size - 1; mdev->mem.flags = IORESOURCE_MEM; - mdev->is_added = false; - ret = mcb_device_register(bus, mdev); if (ret < 0) goto err; @@ -130,7 +128,7 @@ } } -static int chameleon_get_bar(char __iomem **base, phys_addr_t mapbase, +static int chameleon_get_bar(void __iomem **base, phys_addr_t mapbase, struct chameleon_bar **cb) { struct chameleon_bar *c; @@ -179,12 +177,13 @@ { struct chameleon_fpga_header *header; struct chameleon_bar *cb; - char __iomem *p = base; + void __iomem *p = base; int num_cells = 0; uint32_t dtype; int bar_count; int ret; u32 hsize; + u32 table_size; hsize = sizeof(struct chameleon_fpga_header); @@ -239,12 +238,16 @@ num_cells++; } - if (num_cells == 0) - num_cells = -EINVAL; + if (num_cells == 0) { + ret = -EINVAL; + goto free_bar; + } + table_size = p - base; + pr_debug("%d cell(s) found. Chameleon table size: 0x%04x bytes\n", num_cells, table_size); kfree(cb); kfree(header); - return num_cells; + return table_size; free_bar: kfree(cb); --- linux-oracle-5.4.0.orig/drivers/mcb/mcb-pci.c +++ linux-oracle-5.4.0/drivers/mcb/mcb-pci.c @@ -31,7 +31,7 @@ { struct resource *res; struct priv *priv; - int ret; + int ret, table_size; unsigned long flags; priv = devm_kzalloc(&pdev->dev, sizeof(struct priv), GFP_KERNEL); @@ -90,7 +90,30 @@ if (ret < 0) goto out_mcb_bus; - dev_dbg(&pdev->dev, "Found %d cells\n", ret); + table_size = ret; + + if (table_size < CHAM_HEADER_SIZE) { + /* Release the previous resources */ + devm_iounmap(&pdev->dev, priv->base); + devm_release_mem_region(&pdev->dev, priv->mapbase, CHAM_HEADER_SIZE); + + /* Then, allocate it again with the actual chameleon table size */ + res = devm_request_mem_region(&pdev->dev, priv->mapbase, + table_size, + KBUILD_MODNAME); + if (!res) { + dev_err(&pdev->dev, "Failed to request PCI memory\n"); + ret = -EBUSY; + goto out_mcb_bus; + } + + priv->base = devm_ioremap(&pdev->dev, priv->mapbase, table_size); + if (!priv->base) { + dev_err(&pdev->dev, "Cannot ioremap\n"); + ret = -ENOMEM; + goto out_mcb_bus; + } + } mcb_bus_add_devices(priv->bus); --- linux-oracle-5.4.0.orig/drivers/md/Kconfig +++ linux-oracle-5.4.0/drivers/md/Kconfig @@ -565,6 +565,7 @@ select BLK_DEV_INTEGRITY select DM_BUFIO select CRYPTO + select CRYPTO_SKCIPHER select ASYNC_XOR ---help--- This device-mapper target emulates a block device that has --- linux-oracle-5.4.0.orig/drivers/md/bcache/alloc.c +++ linux-oracle-5.4.0/drivers/md/bcache/alloc.c @@ -49,7 +49,7 @@ * * bch_bucket_alloc() allocates a single bucket from a specific cache. * - * bch_bucket_alloc_set() allocates one or more buckets from different caches + * bch_bucket_alloc_set() allocates one bucket from different caches * out of a cache set. * * free_some_buckets() drives all the processes described above. It's called @@ -377,7 +377,10 @@ if (!fifo_full(&ca->free_inc)) goto retry_invalidate; - bch_prio_write(ca); + if (bch_prio_write(ca, false) < 0) { + ca->invalidate_needs_gc = 1; + wake_up_gc(ca->set); + } } } out: @@ -485,34 +488,29 @@ } int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, - struct bkey *k, int n, bool wait) + struct bkey *k, bool wait) { - int i; + struct cache *ca; + long b; /* No allocation if CACHE_SET_IO_DISABLE bit is set */ if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) return -1; lockdep_assert_held(&c->bucket_lock); - BUG_ON(!n || n > c->caches_loaded || n > MAX_CACHES_PER_SET); bkey_init(k); - /* sort by free space/prio of oldest data in caches */ - - for (i = 0; i < n; i++) { - struct cache *ca = c->cache_by_alloc[i]; - long b = bch_bucket_alloc(ca, reserve, wait); + ca = c->cache_by_alloc[0]; + b = bch_bucket_alloc(ca, reserve, wait); + if (b == -1) + goto err; + + k->ptr[0] = MAKE_PTR(ca->buckets[b].gen, + bucket_to_sector(c, b), + ca->sb.nr_this_dev); - if (b == -1) - goto err; - - k->ptr[i] = MAKE_PTR(ca->buckets[b].gen, - bucket_to_sector(c, b), - ca->sb.nr_this_dev); - - SET_KEY_PTRS(k, i + 1); - } + SET_KEY_PTRS(k, 1); return 0; err: @@ -522,12 +520,12 @@ } int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, - struct bkey *k, int n, bool wait) + struct bkey *k, bool wait) { int ret; mutex_lock(&c->bucket_lock); - ret = __bch_bucket_alloc_set(c, reserve, k, n, wait); + ret = __bch_bucket_alloc_set(c, reserve, k, wait); mutex_unlock(&c->bucket_lock); return ret; } @@ -635,7 +633,7 @@ spin_unlock(&c->data_bucket_lock); - if (bch_bucket_alloc_set(c, watermark, &alloc.key, 1, wait)) + if (bch_bucket_alloc_set(c, watermark, &alloc.key, wait)) return false; spin_lock(&c->data_bucket_lock); --- linux-oracle-5.4.0.orig/drivers/md/bcache/bcache.h +++ linux-oracle-5.4.0/drivers/md/bcache/bcache.h @@ -264,7 +264,8 @@ #define BCACHE_DEV_UNLINK_DONE 2 #define BCACHE_DEV_WB_RUNNING 3 #define BCACHE_DEV_RATE_DW_RUNNING 4 - unsigned int nr_stripes; + int nr_stripes; +#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT) unsigned int stripe_size; atomic_t *stripe_sectors_dirty; unsigned long *full_dirty_stripes; @@ -329,6 +330,9 @@ */ atomic_t has_dirty; +#define BCH_CACHE_READA_ALL 0 +#define BCH_CACHE_READA_META_ONLY 1 + unsigned int cache_readahead_policy; struct bch_ratelimit writeback_rate; struct delayed_work writeback_rate_update; @@ -369,6 +373,7 @@ unsigned int partial_stripes_expensive:1; unsigned int writeback_metadata:1; unsigned int writeback_running:1; + unsigned int writeback_consider_fragment:1; unsigned char writeback_percent; unsigned int writeback_delay; @@ -381,6 +386,9 @@ unsigned int writeback_rate_update_seconds; unsigned int writeback_rate_i_term_inverse; unsigned int writeback_rate_p_term_inverse; + unsigned int writeback_rate_fp_term_low; + unsigned int writeback_rate_fp_term_mid; + unsigned int writeback_rate_fp_term_high; unsigned int writeback_rate_minimum; enum stop_on_failure stop_when_cache_set_failed; @@ -582,6 +590,7 @@ */ wait_queue_head_t btree_cache_wait; struct task_struct *btree_cache_alloc_lock; + spinlock_t btree_cannibalize_lock; /* * When we free a btree node, we increment the gen of the bucket the @@ -966,9 +975,9 @@ long bch_bucket_alloc(struct cache *ca, unsigned int reserve, bool wait); int __bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, - struct bkey *k, int n, bool wait); + struct bkey *k, bool wait); int bch_bucket_alloc_set(struct cache_set *c, unsigned int reserve, - struct bkey *k, int n, bool wait); + struct bkey *k, bool wait); bool bch_alloc_sectors(struct cache_set *c, struct bkey *k, unsigned int sectors, unsigned int write_point, unsigned int write_prio, bool wait); @@ -977,11 +986,12 @@ __printf(2, 3) bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...); -void bch_prio_write(struct cache *ca); +int bch_prio_write(struct cache *ca, bool wait); void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent); extern struct workqueue_struct *bcache_wq; extern struct workqueue_struct *bch_journal_wq; +extern struct workqueue_struct *bch_flush_wq; extern struct mutex bch_register_lock; extern struct list_head bch_cache_sets; @@ -1004,6 +1014,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c, uint8_t *set_uuid); void bch_cached_dev_detach(struct cached_dev *dc); +void bch_cached_dev_emit_change(struct cached_dev *); int bch_cached_dev_run(struct cached_dev *dc); void bcache_device_stop(struct bcache_device *d); @@ -1023,5 +1034,7 @@ void bch_debug_init(void); void bch_request_exit(void); int bch_request_init(void); +void bch_btree_exit(void); +int bch_btree_init(void); #endif /* _BCACHE_H */ --- linux-oracle-5.4.0.orig/drivers/md/bcache/bset.c +++ linux-oracle-5.4.0/drivers/md/bcache/bset.c @@ -321,7 +321,7 @@ b->page_order = page_order; - t->data = (void *) __get_free_pages(gfp, b->page_order); + t->data = (void *) __get_free_pages(__GFP_COMP|gfp, b->page_order); if (!t->data) goto err; --- linux-oracle-5.4.0.orig/drivers/md/bcache/bset.h +++ linux-oracle-5.4.0/drivers/md/bcache/bset.h @@ -397,7 +397,8 @@ /* Bkey utility code */ -#define bset_bkey_last(i) bkey_idx((struct bkey *) (i)->d, (i)->keys) +#define bset_bkey_last(i) bkey_idx((struct bkey *) (i)->d, \ + (unsigned int)(i)->keys) static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned int idx) { --- linux-oracle-5.4.0.orig/drivers/md/bcache/btree.c +++ linux-oracle-5.4.0/drivers/md/bcache/btree.c @@ -99,6 +99,8 @@ #define PTR_HASH(c, k) \ (((k)->ptr[0] >> c->bucket_bits) | PTR_GEN(k, 0)) +static struct workqueue_struct *btree_io_wq; + #define insert_lock(s, b) ((b)->level <= (s)->lock) /* @@ -366,7 +368,7 @@ btree_complete_write(b, w); if (btree_node_dirty(b)) - schedule_delayed_work(&b->work, 30 * HZ); + queue_delayed_work(btree_io_wq, &b->work, 30 * HZ); closure_return_with_destructor(cl, btree_node_write_unlock); } @@ -539,7 +541,7 @@ BUG_ON(!i->keys); if (!btree_node_dirty(b)) - schedule_delayed_work(&b->work, 30 * HZ); + queue_delayed_work(btree_io_wq, &b->work, 30 * HZ); set_btree_node_dirty(b); @@ -723,38 +725,38 @@ * IO can always make forward progress: */ nr /= c->btree_pages; + if (nr == 0) + nr = 1; nr = min_t(unsigned long, nr, mca_can_free(c)); i = 0; btree_cache_used = c->btree_cache_used; - list_for_each_entry_safe(b, t, &c->btree_cache_freeable, list) { + list_for_each_entry_safe_reverse(b, t, &c->btree_cache_freeable, list) { if (nr <= 0) goto out; - if (++i > 3 && - !mca_reap(b, 0, false)) { + if (!mca_reap(b, 0, false)) { mca_data_free(b); rw_unlock(true, b); freed++; } nr--; + i++; } - for (; (nr--) && i < btree_cache_used; i++) { - if (list_empty(&c->btree_cache)) + list_for_each_entry_safe_reverse(b, t, &c->btree_cache, list) { + if (nr <= 0 || i >= btree_cache_used) goto out; - b = list_first_entry(&c->btree_cache, struct btree, list); - list_rotate_left(&c->btree_cache); - - if (!b->accessed && - !mca_reap(b, 0, false)) { + if (!mca_reap(b, 0, false)) { mca_bucket_free(b); mca_data_free(b); rw_unlock(true, b); freed++; - } else - b->accessed = 0; + } + + nr--; + i++; } out: mutex_unlock(&c->bucket_lock); @@ -838,7 +840,7 @@ mutex_init(&c->verify_lock); c->verify_ondisk = (void *) - __get_free_pages(GFP_KERNEL, ilog2(bucket_pages(c))); + __get_free_pages(GFP_KERNEL|__GFP_COMP, ilog2(bucket_pages(c))); c->verify_data = mca_bucket_alloc(c, &ZERO_KEY, GFP_KERNEL); @@ -884,15 +886,17 @@ static int mca_cannibalize_lock(struct cache_set *c, struct btree_op *op) { - struct task_struct *old; - - old = cmpxchg(&c->btree_cache_alloc_lock, NULL, current); - if (old && old != current) { + spin_lock(&c->btree_cannibalize_lock); + if (likely(c->btree_cache_alloc_lock == NULL)) { + c->btree_cache_alloc_lock = current; + } else if (c->btree_cache_alloc_lock != current) { if (op) prepare_to_wait(&c->btree_cache_wait, &op->wait, TASK_UNINTERRUPTIBLE); + spin_unlock(&c->btree_cannibalize_lock); return -EINTR; } + spin_unlock(&c->btree_cannibalize_lock); return 0; } @@ -927,10 +931,12 @@ */ static void bch_cannibalize_unlock(struct cache_set *c) { + spin_lock(&c->btree_cannibalize_lock); if (c->btree_cache_alloc_lock == current) { c->btree_cache_alloc_lock = NULL; wake_up(&c->btree_cache_wait); } + spin_unlock(&c->btree_cannibalize_lock); } static struct btree *mca_alloc(struct cache_set *c, struct btree_op *op, @@ -1012,6 +1018,9 @@ * * The btree node will have either a read or a write lock held, depending on * level and op->lock. + * + * Note: Only error code or btree pointer will be returned, it is unncessary + * for callers to check NULL pointer. */ struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, struct bkey *k, int level, bool write, @@ -1058,7 +1067,6 @@ BUG_ON(!b->written); b->parent = parent; - b->accessed = 1; for (; i <= b->keys.nsets && b->keys.set[i].size; i++) { prefetch(b->keys.set[i].tree); @@ -1124,16 +1132,22 @@ mutex_unlock(&b->c->bucket_lock); } +/* + * Only error code or btree pointer will be returned, it is unncessary for + * callers to check NULL pointer. + */ struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, int level, bool wait, struct btree *parent) { BKEY_PADDED(key) k; - struct btree *b = ERR_PTR(-EAGAIN); + struct btree *b; mutex_lock(&c->bucket_lock); retry: - if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, wait)) + /* return ERR_PTR(-EAGAIN) when it fails */ + b = ERR_PTR(-EAGAIN); + if (__bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, wait)) goto err; bkey_put(c, &k.key); @@ -1149,7 +1163,6 @@ goto retry; } - b->accessed = 1; b->parent = parent; bch_bset_init_next(&b->keys, b->keys.set->data, bset_magic(&b->c->sb)); @@ -1178,7 +1191,7 @@ { struct btree *n = bch_btree_node_alloc(b->c, op, b->level, b->parent); - if (!IS_ERR_OR_NULL(n)) { + if (!IS_ERR(n)) { mutex_lock(&n->write_lock); bch_btree_sort_into(&b->keys, &n->keys, &b->c->sort); bkey_copy_key(&n->key, &b->key); @@ -1393,7 +1406,7 @@ for (i = 0; i < nodes; i++) { new_nodes[i] = btree_node_alloc_replacement(r[i].b, NULL); - if (IS_ERR_OR_NULL(new_nodes[i])) + if (IS_ERR(new_nodes[i])) goto out_nocoalesce; } @@ -1440,7 +1453,7 @@ if (__set_blocks(n1, n1->keys + n2->keys, block_bytes(b->c)) > btree_blocks(new_nodes[i])) - goto out_nocoalesce; + goto out_unlock_nocoalesce; keys = n2->keys; /* Take the key of the node we're getting rid of */ @@ -1469,7 +1482,7 @@ if (__bch_keylist_realloc(&keylist, bkey_u64s(&new_nodes[i]->key))) - goto out_nocoalesce; + goto out_unlock_nocoalesce; bch_btree_node_write(new_nodes[i], &cl); bch_keylist_add(&keylist, &new_nodes[i]->key); @@ -1515,6 +1528,10 @@ /* Invalidated our iterator */ return -EINTR; +out_unlock_nocoalesce: + for (i = 0; i < nodes; i++) + mutex_unlock(&new_nodes[i]->write_lock); + out_nocoalesce: closure_sync(&cl); @@ -1541,6 +1558,8 @@ return 0; n = btree_node_alloc_replacement(replace, NULL); + if (IS_ERR(n)) + return 0; /* recheck reserve after allocating replacement node */ if (btree_check_reserve(b, NULL)) { @@ -1706,7 +1725,7 @@ if (should_rewrite) { n = btree_node_alloc_replacement(b, NULL); - if (!IS_ERR_OR_NULL(n)) { + if (!IS_ERR(n)) { bch_btree_node_write_sync(n); bch_btree_set_root(n); @@ -2649,3 +2668,18 @@ spin_lock_init(&buf->lock); array_allocator_init(&buf->freelist); } + +void bch_btree_exit(void) +{ + if (btree_io_wq) + destroy_workqueue(btree_io_wq); +} + +int __init bch_btree_init(void) +{ + btree_io_wq = alloc_workqueue("bch_btree_io", WQ_MEM_RECLAIM, 0); + if (!btree_io_wq) + return -ENOMEM; + + return 0; +} --- linux-oracle-5.4.0.orig/drivers/md/bcache/btree.h +++ linux-oracle-5.4.0/drivers/md/bcache/btree.h @@ -121,8 +121,6 @@ /* Key/pointer for this btree node */ BKEY_PADDED(key); - /* Single bit - set when accessed, cleared by shrinker */ - unsigned long accessed; unsigned long seq; struct rw_semaphore lock; struct cache_set *c; --- linux-oracle-5.4.0.orig/drivers/md/bcache/closure.c +++ linux-oracle-5.4.0/drivers/md/bcache/closure.c @@ -17,10 +17,16 @@ { int r = flags & CLOSURE_REMAINING_MASK; - BUG_ON(flags & CLOSURE_GUARD_MASK); - BUG_ON(!r && (flags & ~CLOSURE_DESTRUCTOR)); + if (WARN(flags & CLOSURE_GUARD_MASK, + "closure has guard bits set: %x (%u)", + flags & CLOSURE_GUARD_MASK, (unsigned) __fls(r))) + r &= ~CLOSURE_GUARD_MASK; if (!r) { + WARN(flags & ~CLOSURE_DESTRUCTOR, + "closure ref hit 0 with incorrect flags set: %x (%u)", + flags & ~CLOSURE_DESTRUCTOR, (unsigned) __fls(flags)); + if (cl->fn && !(flags & CLOSURE_DESTRUCTOR)) { atomic_set(&cl->remaining, CLOSURE_REMAINING_INITIALIZER); --- linux-oracle-5.4.0.orig/drivers/md/bcache/journal.c +++ linux-oracle-5.4.0/drivers/md/bcache/journal.c @@ -417,10 +417,15 @@ /* Journalling */ +#define nr_to_fifo_front(p, front_p, mask) (((p) - (front_p)) & (mask)) + static void btree_flush_write(struct cache_set *c) { struct btree *b, *t, *btree_nodes[BTREE_FLUSH_NR]; - unsigned int i, n; + unsigned int i, nr; + int ref_nr; + atomic_t *fifo_front_p, *now_fifo_front_p; + size_t mask; if (c->journal.btree_flushing) return; @@ -433,12 +438,50 @@ c->journal.btree_flushing = true; spin_unlock(&c->journal.flush_write_lock); + /* get the oldest journal entry and check its refcount */ + spin_lock(&c->journal.lock); + fifo_front_p = &fifo_front(&c->journal.pin); + ref_nr = atomic_read(fifo_front_p); + if (ref_nr <= 0) { + /* + * do nothing if no btree node references + * the oldest journal entry + */ + spin_unlock(&c->journal.lock); + goto out; + } + spin_unlock(&c->journal.lock); + + mask = c->journal.pin.mask; + nr = 0; atomic_long_inc(&c->flush_write); memset(btree_nodes, 0, sizeof(btree_nodes)); - n = 0; mutex_lock(&c->bucket_lock); list_for_each_entry_safe_reverse(b, t, &c->btree_cache, list) { + /* + * It is safe to get now_fifo_front_p without holding + * c->journal.lock here, because we don't need to know + * the exactly accurate value, just check whether the + * front pointer of c->journal.pin is changed. + */ + now_fifo_front_p = &fifo_front(&c->journal.pin); + /* + * If the oldest journal entry is reclaimed and front + * pointer of c->journal.pin changes, it is unnecessary + * to scan c->btree_cache anymore, just quit the loop and + * flush out what we have already. + */ + if (now_fifo_front_p != fifo_front_p) + break; + /* + * quit this loop if all matching btree nodes are + * scanned and record in btree_nodes[] already. + */ + ref_nr = atomic_read(fifo_front_p); + if (nr >= ref_nr) + break; + if (btree_node_journal_flush(b)) pr_err("BUG: flush_write bit should not be set here!"); @@ -454,17 +497,44 @@ continue; } + /* + * Only select the btree node which exactly references + * the oldest journal entry. + * + * If the journal entry pointed by fifo_front_p is + * reclaimed in parallel, don't worry: + * - the list_for_each_xxx loop will quit when checking + * next now_fifo_front_p. + * - If there are matched nodes recorded in btree_nodes[], + * they are clean now (this is why and how the oldest + * journal entry can be reclaimed). These selected nodes + * will be ignored and skipped in the folowing for-loop. + */ + if (nr_to_fifo_front(btree_current_write(b)->journal, + fifo_front_p, + mask) != 0) { + mutex_unlock(&b->write_lock); + continue; + } + set_btree_node_journal_flush(b); mutex_unlock(&b->write_lock); - btree_nodes[n++] = b; - if (n == BTREE_FLUSH_NR) + btree_nodes[nr++] = b; + /* + * To avoid holding c->bucket_lock too long time, + * only scan for BTREE_FLUSH_NR matched btree nodes + * at most. If there are more btree nodes reference + * the oldest journal entry, try to flush them next + * time when btree_flush_write() is called. + */ + if (nr == BTREE_FLUSH_NR) break; } mutex_unlock(&c->bucket_lock); - for (i = 0; i < n; i++) { + for (i = 0; i < nr; i++) { b = btree_nodes[i]; if (!b) { pr_err("BUG: btree_nodes[%d] is NULL", i); @@ -497,6 +567,7 @@ mutex_unlock(&b->write_lock); } +out: spin_lock(&c->journal.flush_write_lock); c->journal.btree_flushing = false; spin_unlock(&c->journal.flush_write_lock); @@ -887,8 +958,8 @@ journal_try_write(c); } else if (!w->dirty) { w->dirty = true; - schedule_delayed_work(&c->journal.work, - msecs_to_jiffies(c->journal_delay_ms)); + queue_delayed_work(bch_flush_wq, &c->journal.work, + msecs_to_jiffies(c->journal_delay_ms)); spin_unlock(&c->journal.lock); } else { spin_unlock(&c->journal.lock); @@ -931,8 +1002,8 @@ j->w[1].c = c; if (!(init_fifo(&j->pin, JOURNAL_PIN, GFP_KERNEL)) || - !(j->w[0].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS)) || - !(j->w[1].data = (void *) __get_free_pages(GFP_KERNEL, JSET_BITS))) + !(j->w[0].data = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP, JSET_BITS)) || + !(j->w[1].data = (void *) __get_free_pages(GFP_KERNEL|__GFP_COMP, JSET_BITS))) return -ENOMEM; return 0; --- linux-oracle-5.4.0.orig/drivers/md/bcache/request.c +++ linux-oracle-5.4.0/drivers/md/bcache/request.c @@ -391,13 +391,20 @@ goto skip; /* - * Flag for bypass if the IO is for read-ahead or background, - * unless the read-ahead request is for metadata + * If the bio is for read-ahead or background IO, bypass it or + * not depends on the following situations, + * - If the IO is for meta data, always cache it and no bypass + * - If the IO is not meta data, check dc->cache_reada_policy, + * BCH_CACHE_READA_ALL: cache it and not bypass + * BCH_CACHE_READA_META_ONLY: not cache it and bypass + * That is, read-ahead request for metadata always get cached * (eg, for gfs2 or xfs). */ - if (bio->bi_opf & (REQ_RAHEAD|REQ_BACKGROUND) && - !(bio->bi_opf & (REQ_META|REQ_PRIO))) - goto skip; + if ((bio->bi_opf & (REQ_RAHEAD|REQ_BACKGROUND))) { + if (!(bio->bi_opf & (REQ_META|REQ_PRIO)) && + (dc->cache_readahead_policy != BCH_CACHE_READA_ALL)) + goto skip; + } if (bio->bi_iter.bi_sector & (c->sb.block_size - 1) || bio_sectors(bio) & (c->sb.block_size - 1)) { @@ -1112,6 +1119,12 @@ * which would call closure_get(&dc->disk.cl) */ ddip = kzalloc(sizeof(struct detached_dev_io_private), GFP_NOIO); + if (!ddip) { + bio->bi_status = BLK_STS_RESOURCE; + bio->bi_end_io(bio); + return; + } + ddip->d = d; ddip->start_time = jiffies; ddip->bi_end_io = bio->bi_end_io; --- linux-oracle-5.4.0.orig/drivers/md/bcache/stats.c +++ linux-oracle-5.4.0/drivers/md/bcache/stats.c @@ -109,9 +109,13 @@ void bch_cache_accounting_clear(struct cache_accounting *acc) { - memset(&acc->total.cache_hits, - 0, - sizeof(struct cache_stats)); + acc->total.cache_hits = 0; + acc->total.cache_misses = 0; + acc->total.cache_bypass_hits = 0; + acc->total.cache_bypass_misses = 0; + acc->total.cache_readaheads = 0; + acc->total.cache_miss_collisions = 0; + acc->total.sectors_bypassed = 0; } void bch_cache_accounting_destroy(struct cache_accounting *acc) --- linux-oracle-5.4.0.orig/drivers/md/bcache/super.c +++ linux-oracle-5.4.0/drivers/md/bcache/super.c @@ -48,6 +48,7 @@ static DEFINE_IDA(bcache_device_idx); static wait_queue_head_t unregister_wait; struct workqueue_struct *bcache_wq; +struct workqueue_struct *bch_flush_wq; struct workqueue_struct *bch_journal_wq; @@ -427,7 +428,7 @@ closure_init_stack(&cl); lockdep_assert_held(&bch_register_lock); - if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, 1, true)) + if (bch_bucket_alloc_set(c, RESERVE_BTREE, &k.key, true)) return 1; SET_KEY_SIZE(&k.key, c->sb.bucket_size); @@ -529,12 +530,29 @@ closure_sync(cl); } -void bch_prio_write(struct cache *ca) +int bch_prio_write(struct cache *ca, bool wait) { int i; struct bucket *b; struct closure cl; + pr_debug("free_prio=%zu, free_none=%zu, free_inc=%zu", + fifo_used(&ca->free[RESERVE_PRIO]), + fifo_used(&ca->free[RESERVE_NONE]), + fifo_used(&ca->free_inc)); + + /* + * Pre-check if there are enough free buckets. In the non-blocking + * scenario it's better to fail early rather than starting to allocate + * buckets and do a cleanup later in case of failure. + */ + if (!wait) { + size_t avail = fifo_used(&ca->free[RESERVE_PRIO]) + + fifo_used(&ca->free[RESERVE_NONE]); + if (prio_buckets(ca) > avail) + return -ENOMEM; + } + closure_init_stack(&cl); lockdep_assert_held(&ca->set->bucket_lock); @@ -544,9 +562,6 @@ atomic_long_add(ca->sb.bucket_size * prio_buckets(ca), &ca->meta_sectors_written); - //pr_debug("free %zu, free_inc %zu, unused %zu", fifo_used(&ca->free), - // fifo_used(&ca->free_inc), fifo_used(&ca->unused)); - for (i = prio_buckets(ca) - 1; i >= 0; --i) { long bucket; struct prio_set *p = ca->disk_buckets; @@ -564,7 +579,7 @@ p->magic = pset_magic(&ca->sb); p->csum = bch_crc64(&p->magic, bucket_bytes(ca) - 8); - bucket = bch_bucket_alloc(ca, RESERVE_PRIO, true); + bucket = bch_bucket_alloc(ca, RESERVE_PRIO, wait); BUG_ON(bucket == -1); mutex_unlock(&ca->set->bucket_lock); @@ -593,6 +608,7 @@ ca->prio_last_buckets[i] = ca->prio_buckets[i]; } + return 0; } static void prio_read(struct cache *ca, uint64_t bucket) @@ -761,20 +777,31 @@ static void bcache_device_free(struct bcache_device *d) { + struct gendisk *disk = d->disk; + lockdep_assert_held(&bch_register_lock); - pr_info("%s stopped", d->disk->disk_name); + if (disk) + pr_info("%s stopped", disk->disk_name); + else + pr_err("bcache device (NULL gendisk) stopped"); if (d->c) bcache_device_detach(d); - if (d->disk && d->disk->flags & GENHD_FL_UP) - del_gendisk(d->disk); - if (d->disk && d->disk->queue) - blk_cleanup_queue(d->disk->queue); - if (d->disk) { + + if (disk) { + bool disk_added = (disk->flags & GENHD_FL_UP) != 0; + + if (disk_added) + del_gendisk(disk); + + if (disk->queue) + blk_cleanup_queue(disk->queue); + ida_simple_remove(&bcache_device_idx, - first_minor_to_idx(d->disk->first_minor)); - put_disk(d->disk); + first_minor_to_idx(disk->first_minor)); + if (disk_added) + put_disk(disk); } bioset_exit(&d->bio_split); @@ -785,24 +812,26 @@ } static int bcache_device_init(struct bcache_device *d, unsigned int block_size, - sector_t sectors) + sector_t sectors, struct block_device *cached_bdev) { struct request_queue *q; const size_t max_stripes = min_t(size_t, INT_MAX, SIZE_MAX / sizeof(atomic_t)); - size_t n; + uint64_t n; int idx; if (!d->stripe_size) d->stripe_size = 1 << 31; + else if (d->stripe_size < BCH_MIN_STRIPE_SZ) + d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size); - d->nr_stripes = DIV_ROUND_UP_ULL(sectors, d->stripe_size); - - if (!d->nr_stripes || d->nr_stripes > max_stripes) { - pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)", - (unsigned int)d->nr_stripes); + n = DIV_ROUND_UP_ULL(sectors, d->stripe_size); + if (!n || n > max_stripes) { + pr_err("nr_stripes too large or invalid: %llu (start sector beyond end of disk?)\n", + n); return -ENOMEM; } + d->nr_stripes = n; n = d->nr_stripes * sizeof(atomic_t); d->stripe_sectors_dirty = kvzalloc(n, GFP_KERNEL); @@ -812,20 +841,20 @@ n = BITS_TO_LONGS(d->nr_stripes) * sizeof(unsigned long); d->full_dirty_stripes = kvzalloc(n, GFP_KERNEL); if (!d->full_dirty_stripes) - return -ENOMEM; + goto out_free_stripe_sectors_dirty; idx = ida_simple_get(&bcache_device_idx, 0, BCACHE_DEVICE_IDX_MAX, GFP_KERNEL); if (idx < 0) - return idx; + goto out_free_full_dirty_stripes; if (bioset_init(&d->bio_split, 4, offsetof(struct bbio, bio), BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER)) - goto err; + goto out_ida_remove; d->disk = alloc_disk(BCACHE_MINORS); if (!d->disk) - goto err; + goto out_bioset_exit; set_capacity(d->disk, sectors); snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", idx); @@ -852,6 +881,21 @@ q->limits.io_min = block_size; q->limits.logical_block_size = block_size; q->limits.physical_block_size = block_size; + + if (q->limits.logical_block_size > PAGE_SIZE && cached_bdev) { + /* + * This should only happen with BCACHE_SB_VERSION_BDEV. + * Block/page size is checked for BCACHE_SB_VERSION_CDEV. + */ + pr_info("%s: sb/logical block size (%u) greater than page size " + "(%lu) falling back to device logical block size (%u)", + d->disk->disk_name, q->limits.logical_block_size, + PAGE_SIZE, bdev_logical_block_size(cached_bdev)); + + /* This also adjusts physical block size/min io size if needed */ + blk_queue_logical_block_size(q, bdev_logical_block_size(cached_bdev)); + } + blk_queue_flag_set(QUEUE_FLAG_NONROT, d->disk->queue); blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, d->disk->queue); blk_queue_flag_set(QUEUE_FLAG_DISCARD, d->disk->queue); @@ -860,8 +904,14 @@ return 0; -err: +out_bioset_exit: + bioset_exit(&d->bio_split); +out_ida_remove: ida_simple_remove(&bcache_device_idx, idx); +out_free_full_dirty_stripes: + kvfree(d->full_dirty_stripes); +out_free_stripe_sectors_dirty: + kvfree(d->stripe_sectors_dirty); return -ENOMEM; } @@ -917,7 +967,7 @@ } -int bch_cached_dev_run(struct cached_dev *dc) +void bch_cached_dev_emit_change(struct cached_dev *dc) { struct bcache_device *d = &dc->disk; char *buf = kmemdup_nul(dc->sb.label, SB_LABEL_SIZE, GFP_KERNEL); @@ -928,19 +978,26 @@ NULL, }; + /* + * won't show up in the uevent file, use udevadm monitor -e instead + * only class / kset properties are persistent + */ + kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env); + kfree(env[1]); + kfree(env[2]); + kfree(buf); +} + +int bch_cached_dev_run(struct cached_dev *dc) +{ + struct bcache_device *d = &dc->disk; if (dc->io_disable) { pr_err("I/O disabled on cached dev %s", dc->backing_dev_name); - kfree(env[1]); - kfree(env[2]); - kfree(buf); return -EIO; } if (atomic_xchg(&dc->running, 1)) { - kfree(env[1]); - kfree(env[2]); - kfree(buf); pr_info("cached dev %s is running already", dc->backing_dev_name); return -EBUSY; @@ -959,14 +1016,9 @@ add_disk(d->disk); bd_link_disk_holder(dc->bdev, dc->disk.disk); - /* - * won't show up in the uevent file, use udevadm monitor -e instead - * only class / kset properties are persistent - */ - kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env); - kfree(env[1]); - kfree(env[2]); - kfree(buf); + + /* emit change event */ + bch_cached_dev_emit_change(dc); if (sysfs_create_link(&d->kobj, &disk_to_dev(d->disk)->kobj, "dev") || sysfs_create_link(&disk_to_dev(d->disk)->kobj, @@ -1251,6 +1303,9 @@ mutex_unlock(&bch_register_lock); + if (dc->sb_bio.bi_inline_vecs[0].bv_page) + put_page(bio_first_page_all(&dc->sb_bio)); + if (!IS_ERR_OR_NULL(dc->bdev)) blkdev_put(dc->bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); @@ -1305,7 +1360,7 @@ q->limits.raid_partial_stripes_expensive; ret = bcache_device_init(&dc->disk, block_size, - dc->bdev->bd_part->nr_sects - dc->sb.data_offset); + dc->bdev->bd_part->nr_sects - dc->sb.data_offset, dc->bdev); if (ret) return ret; @@ -1421,7 +1476,7 @@ kobject_init(&d->kobj, &bch_flash_dev_ktype); - if (bcache_device_init(d, block_bytes(c), u->sectors)) + if (bcache_device_init(d, block_bytes(c), u->sectors, NULL)) goto err; bcache_device_attach(d, c, u - c->uuids); @@ -1725,7 +1780,7 @@ } #define alloc_bucket_pages(gfp, c) \ - ((void *) __get_free_pages(__GFP_ZERO|gfp, ilog2(bucket_pages(c)))) + ((void *) __get_free_pages(__GFP_ZERO|__GFP_COMP|gfp, ilog2(bucket_pages(c)))) struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) { @@ -1769,6 +1824,7 @@ sema_init(&c->sb_write_mutex, 1); mutex_init(&c->bucket_lock); init_waitqueue_head(&c->btree_cache_wait); + spin_lock_init(&c->btree_cannibalize_lock); init_waitqueue_head(&c->bucket_wait); init_waitqueue_head(&c->gc_wait); sema_init(&c->uuid_write_mutex, 1); @@ -1869,7 +1925,7 @@ c->root = bch_btree_node_get(c, NULL, k, j->btree_level, true, NULL); - if (IS_ERR_OR_NULL(c->root)) + if (IS_ERR(c->root)) goto err; list_del_init(&c->root->list); @@ -1954,7 +2010,7 @@ mutex_lock(&c->bucket_lock); for_each_cache(ca, c, i) - bch_prio_write(ca); + bch_prio_write(ca, true); mutex_unlock(&c->bucket_lock); err = "cannot allocate new UUID bucket"; @@ -1963,7 +2019,7 @@ err = "cannot allocate new btree root"; c->root = __bch_btree_node_alloc(c, NULL, 0, true, NULL); - if (IS_ERR_OR_NULL(c->root)) + if (IS_ERR(c->root)) goto err; mutex_lock(&c->root->write_lock); @@ -2062,7 +2118,14 @@ sysfs_create_link(&c->kobj, &ca->kobj, buf)) goto err; - if (ca->sb.seq > c->sb.seq) { + /* + * A special case is both ca->sb.seq and c->sb.seq are 0, + * such condition happens on a new created cache device whose + * super block is never flushed yet. In this case c->sb.version + * and other members should be updated too, otherwise we will + * have a mistaken super block version in cache set. + */ + if (ca->sb.seq > c->sb.seq || c->sb.seq == 0) { c->sb.version = ca->sb.version; memcpy(c->sb.set_uuid, ca->sb.set_uuid, 16); c->sb.flags = ca->sb.flags; @@ -2325,6 +2388,21 @@ return false; } +static struct cached_dev *bch_find_cached_dev(struct block_device *bdev) { + struct cache_set *c, *tc; + struct cached_dev *dc, *t; + + list_for_each_entry_safe(c, tc, &bch_cache_sets, list) + list_for_each_entry_safe(dc, t, &c->cached_devs, list) + if (dc->bdev == bdev) + return dc; + list_for_each_entry_safe(dc, t, &uncached_devices, list) + if (dc->bdev == bdev) + return dc; + + return NULL; +} + static bool bch_is_open_cache(struct block_device *bdev) { struct cache_set *c, *tc; @@ -2346,29 +2424,36 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, const char *buffer, size_t size) { - ssize_t ret = -EINVAL; - const char *err = "cannot allocate memory"; + const char *err; char *path = NULL; - struct cache_sb *sb = NULL; + struct cache_sb *sb; struct block_device *bdev = NULL; - struct page *sb_page = NULL; + struct cached_dev *dc = NULL; + struct page *sb_page; + ssize_t ret; + ret = -EBUSY; + err = "failed to reference bcache module"; if (!try_module_get(THIS_MODULE)) - return -EBUSY; + goto out; /* For latest state of bcache_is_reboot */ smp_mb(); + err = "bcache is in reboot"; if (bcache_is_reboot) - return -EBUSY; + goto out_module_put; + ret = -ENOMEM; + err = "cannot allocate memory"; path = kstrndup(buffer, size, GFP_KERNEL); if (!path) - goto err; + goto out_module_put; sb = kmalloc(sizeof(struct cache_sb), GFP_KERNEL); if (!sb) - goto err; + goto out_free_path; + ret = -EINVAL; err = "failed to open device"; bdev = blkdev_get_by_path(strim(path), FMODE_READ|FMODE_WRITE|FMODE_EXCL, @@ -2377,65 +2462,87 @@ if (bdev == ERR_PTR(-EBUSY)) { bdev = lookup_bdev(strim(path)); mutex_lock(&bch_register_lock); - if (!IS_ERR(bdev) && bch_is_open(bdev)) + if (!IS_ERR(bdev) && bch_is_open(bdev)) { err = "device already registered"; - else + /* emit CHANGE event for backing devices to export + * CACHED_{UUID/LABEL} values to udev */ + if (bch_is_open_backing(bdev)) { + dc = bch_find_cached_dev(bdev); + if (dc) { + bch_cached_dev_emit_change(dc); + err = "device already registered (emitting change event)"; + } + } + } else { err = "device busy"; + } mutex_unlock(&bch_register_lock); if (!IS_ERR(bdev)) bdput(bdev); if (attr == &ksysfs_register_quiet) - goto quiet_out; + goto done; } - goto err; + goto out_free_sb; } err = "failed to set blocksize"; if (set_blocksize(bdev, 4096)) - goto err_close; + goto out_blkdev_put; err = read_super(sb, bdev, &sb_page); if (err) - goto err_close; + goto out_blkdev_put; err = "failed to register device"; if (SB_IS_BDEV(sb)) { struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); if (!dc) - goto err_close; + goto out_put_sb_page; mutex_lock(&bch_register_lock); ret = register_bdev(sb, sb_page, bdev, dc); mutex_unlock(&bch_register_lock); /* blkdev_put() will be called in cached_dev_free() */ - if (ret < 0) - goto err; + if (ret < 0) { + bdev = NULL; + goto out_put_sb_page; + } } else { struct cache *ca = kzalloc(sizeof(*ca), GFP_KERNEL); if (!ca) - goto err_close; + goto out_put_sb_page; /* blkdev_put() will be called in bch_cache_release() */ - if (register_cache(sb, sb_page, bdev, ca) != 0) - goto err; + if (register_cache(sb, sb_page, bdev, ca) != 0) { + bdev = NULL; + goto out_put_sb_page; + } } -quiet_out: - ret = size; -out: - if (sb_page) - put_page(sb_page); + + put_page(sb_page); +done: kfree(sb); kfree(path); module_put(THIS_MODULE); - return ret; + return size; -err_close: - blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); -err: - pr_info("error %s: %s", path, err); - goto out; +out_put_sb_page: + put_page(sb_page); +out_blkdev_put: + if (bdev) + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); +out_free_sb: + kfree(sb); +out_free_path: + kfree(path); + path = NULL; +out_module_put: + module_put(THIS_MODULE); +out: + pr_info("error %s: %s", path?path:"", err); + return ret; } @@ -2597,6 +2704,9 @@ destroy_workqueue(bcache_wq); if (bch_journal_wq) destroy_workqueue(bch_journal_wq); + if (bch_flush_wq) + destroy_workqueue(bch_flush_wq); + bch_btree_exit(); if (bcache_major) unregister_blkdev(bcache_major, "bcache"); @@ -2652,10 +2762,26 @@ return bcache_major; } + if (bch_btree_init()) + goto err; + bcache_wq = alloc_workqueue("bcache", WQ_MEM_RECLAIM, 0); if (!bcache_wq) goto err; + /* + * Let's not make this `WQ_MEM_RECLAIM` for the following reasons: + * + * 1. It used `system_wq` before which also does no memory reclaim. + * 2. With `WQ_MEM_RECLAIM` desktop stalls, increased boot times, and + * reduced throughput can be observed. + * + * We still want to user our own queue to not congest the `system_wq`. + */ + bch_flush_wq = alloc_workqueue("bch_flush", 0, 0); + if (!bch_flush_wq) + goto err; + bch_journal_wq = alloc_workqueue("bch_journal", WQ_MEM_RECLAIM, 0); if (!bch_journal_wq) goto err; --- linux-oracle-5.4.0.orig/drivers/md/bcache/sysfs.c +++ linux-oracle-5.4.0/drivers/md/bcache/sysfs.c @@ -27,6 +27,12 @@ NULL }; +static const char * const bch_reada_cache_policies[] = { + "all", + "meta-only", + NULL +}; + /* Default is 0 ("auto") */ static const char * const bch_stop_on_failure_modes[] = { "auto", @@ -100,16 +106,21 @@ rw_attribute(sequential_cutoff); rw_attribute(data_csum); rw_attribute(cache_mode); +rw_attribute(readahead_cache_policy); rw_attribute(stop_when_cache_set_failed); rw_attribute(writeback_metadata); rw_attribute(writeback_running); rw_attribute(writeback_percent); rw_attribute(writeback_delay); rw_attribute(writeback_rate); +rw_attribute(writeback_consider_fragment); rw_attribute(writeback_rate_update_seconds); rw_attribute(writeback_rate_i_term_inverse); rw_attribute(writeback_rate_p_term_inverse); +rw_attribute(writeback_rate_fp_term_low); +rw_attribute(writeback_rate_fp_term_mid); +rw_attribute(writeback_rate_fp_term_high); rw_attribute(writeback_rate_minimum); read_attribute(writeback_rate_debug); @@ -167,6 +178,11 @@ bch_cache_modes, BDEV_CACHE_MODE(&dc->sb)); + if (attr == &sysfs_readahead_cache_policy) + return bch_snprint_string_list(buf, PAGE_SIZE, + bch_reada_cache_policies, + dc->cache_readahead_policy); + if (attr == &sysfs_stop_when_cache_set_failed) return bch_snprint_string_list(buf, PAGE_SIZE, bch_stop_on_failure_modes, @@ -178,6 +194,7 @@ var_printf(bypass_torture_test, "%i"); var_printf(writeback_metadata, "%i"); var_printf(writeback_running, "%i"); + var_printf(writeback_consider_fragment, "%i"); var_print(writeback_delay); var_print(writeback_percent); sysfs_hprint(writeback_rate, @@ -188,6 +205,9 @@ var_print(writeback_rate_update_seconds); var_print(writeback_rate_i_term_inverse); var_print(writeback_rate_p_term_inverse); + var_print(writeback_rate_fp_term_low); + var_print(writeback_rate_fp_term_mid); + var_print(writeback_rate_fp_term_high); var_print(writeback_rate_minimum); if (attr == &sysfs_writeback_rate_debug) { @@ -286,6 +306,7 @@ sysfs_strtoul_bool(bypass_torture_test, dc->bypass_torture_test); sysfs_strtoul_bool(writeback_metadata, dc->writeback_metadata); sysfs_strtoul_bool(writeback_running, dc->writeback_running); + sysfs_strtoul_bool(writeback_consider_fragment, dc->writeback_consider_fragment); sysfs_strtoul_clamp(writeback_delay, dc->writeback_delay, 0, UINT_MAX); sysfs_strtoul_clamp(writeback_percent, dc->writeback_percent, @@ -314,6 +335,16 @@ sysfs_strtoul_clamp(writeback_rate_p_term_inverse, dc->writeback_rate_p_term_inverse, 1, UINT_MAX); + sysfs_strtoul_clamp(writeback_rate_fp_term_low, + dc->writeback_rate_fp_term_low, + 1, dc->writeback_rate_fp_term_mid - 1); + sysfs_strtoul_clamp(writeback_rate_fp_term_mid, + dc->writeback_rate_fp_term_mid, + dc->writeback_rate_fp_term_low + 1, + dc->writeback_rate_fp_term_high - 1); + sysfs_strtoul_clamp(writeback_rate_fp_term_high, + dc->writeback_rate_fp_term_high, + dc->writeback_rate_fp_term_mid + 1, UINT_MAX); sysfs_strtoul_clamp(writeback_rate_minimum, dc->writeback_rate_minimum, 1, UINT_MAX); @@ -352,6 +383,15 @@ } } + if (attr == &sysfs_readahead_cache_policy) { + v = __sysfs_match_string(bch_reada_cache_policies, -1, buf); + if (v < 0) + return v; + + if ((unsigned int) v != dc->cache_readahead_policy) + dc->cache_readahead_policy = v; + } + if (attr == &sysfs_stop_when_cache_set_failed) { v = __sysfs_match_string(bch_stop_on_failure_modes, -1, buf); if (v < 0) @@ -466,15 +506,20 @@ &sysfs_data_csum, #endif &sysfs_cache_mode, + &sysfs_readahead_cache_policy, &sysfs_stop_when_cache_set_failed, &sysfs_writeback_metadata, &sysfs_writeback_running, &sysfs_writeback_delay, &sysfs_writeback_percent, &sysfs_writeback_rate, + &sysfs_writeback_consider_fragment, &sysfs_writeback_rate_update_seconds, &sysfs_writeback_rate_i_term_inverse, &sysfs_writeback_rate_p_term_inverse, + &sysfs_writeback_rate_fp_term_low, + &sysfs_writeback_rate_fp_term_mid, + &sysfs_writeback_rate_fp_term_high, &sysfs_writeback_rate_minimum, &sysfs_writeback_rate_debug, &sysfs_io_errors, @@ -1035,7 +1080,7 @@ sum += INITIAL_PRIO - cached[i]; if (n) - do_div(sum, n); + sum = div64_u64(sum, n); for (i = 0; i < ARRAY_SIZE(q); i++) q[i] = INITIAL_PRIO - cached[n * (i + 1) / --- linux-oracle-5.4.0.orig/drivers/md/bcache/writeback.c +++ linux-oracle-5.4.0/drivers/md/bcache/writeback.c @@ -88,6 +88,44 @@ int64_t integral_scaled; uint32_t new_rate; + /* + * We need to consider the number of dirty buckets as well + * when calculating the proportional_scaled, Otherwise we might + * have an unreasonable small writeback rate at a highly fragmented situation + * when very few dirty sectors consumed a lot dirty buckets, the + * worst case is when dirty buckets reached cutoff_writeback_sync and + * dirty data is still not even reached to writeback percent, so the rate + * still will be at the minimum value, which will cause the write + * stuck at a non-writeback mode. + */ + struct cache_set *c = dc->disk.c; + + int64_t dirty_buckets = c->nbuckets - c->avail_nbuckets; + + if (dc->writeback_consider_fragment && + c->gc_stats.in_use > BCH_WRITEBACK_FRAGMENT_THRESHOLD_LOW && dirty > 0) { + int64_t fragment = + div_s64((dirty_buckets * c->sb.bucket_size), dirty); + int64_t fp_term; + int64_t fps; + + if (c->gc_stats.in_use <= BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID) { + fp_term = dc->writeback_rate_fp_term_low * + (c->gc_stats.in_use - BCH_WRITEBACK_FRAGMENT_THRESHOLD_LOW); + } else if (c->gc_stats.in_use <= BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH) { + fp_term = dc->writeback_rate_fp_term_mid * + (c->gc_stats.in_use - BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID); + } else { + fp_term = dc->writeback_rate_fp_term_high * + (c->gc_stats.in_use - BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH); + } + fps = div_s64(dirty, dirty_buckets) * fp_term; + if (fragment > 3 && fps > proportional_scaled) { + /* Only overrite the p when fragment > 3 */ + proportional_scaled = fps; + } + } + if ((error < 0 && dc->writeback_rate_integral > 0) || (error > 0 && time_before64(local_clock(), dc->writeback_rate.next + NSEC_PER_MSEC))) { @@ -119,27 +157,61 @@ dc->writeback_rate_target = target; } +static bool idle_counter_exceeded(struct cache_set *c) +{ + int counter, dev_nr; + + /* + * If c->idle_counter is overflow (idel for really long time), + * reset as 0 and not set maximum rate this time for code + * simplicity. + */ + counter = atomic_inc_return(&c->idle_counter); + if (counter <= 0) { + atomic_set(&c->idle_counter, 0); + return false; + } + + dev_nr = atomic_read(&c->attached_dev_nr); + if (dev_nr == 0) + return false; + + /* + * c->idle_counter is increased by writeback thread of all + * attached backing devices, in order to represent a rough + * time period, counter should be divided by dev_nr. + * Otherwise the idle time cannot be larger with more backing + * device attached. + * The following calculation equals to checking + * (counter / dev_nr) < (dev_nr * 6) + */ + if (counter < (dev_nr * dev_nr * 6)) + return false; + + return true; +} + +/* + * Idle_counter is increased every time when update_writeback_rate() is + * called. If all backing devices attached to the same cache set have + * identical dc->writeback_rate_update_seconds values, it is about 6 + * rounds of update_writeback_rate() on each backing device before + * c->at_max_writeback_rate is set to 1, and then max wrteback rate set + * to each dc->writeback_rate.rate. + * In order to avoid extra locking cost for counting exact dirty cached + * devices number, c->attached_dev_nr is used to calculate the idle + * throushold. It might be bigger if not all cached device are in write- + * back mode, but it still works well with limited extra rounds of + * update_writeback_rate(). + */ static bool set_at_max_writeback_rate(struct cache_set *c, struct cached_dev *dc) { /* Don't set max writeback rate if gc is running */ if (!c->gc_mark_valid) return false; - /* - * Idle_counter is increased everytime when update_writeback_rate() is - * called. If all backing devices attached to the same cache set have - * identical dc->writeback_rate_update_seconds values, it is about 6 - * rounds of update_writeback_rate() on each backing device before - * c->at_max_writeback_rate is set to 1, and then max wrteback rate set - * to each dc->writeback_rate.rate. - * In order to avoid extra locking cost for counting exact dirty cached - * devices number, c->attached_dev_nr is used to calculate the idle - * throushold. It might be bigger if not all cached device are in write- - * back mode, but it still works well with limited extra rounds of - * update_writeback_rate(). - */ - if (atomic_inc_return(&c->idle_counter) < - atomic_read(&c->attached_dev_nr) * 6) + + if (!idle_counter_exceeded(c)) return false; if (atomic_read(&c->at_max_writeback_rate) != 1) @@ -153,13 +225,10 @@ dc->writeback_rate_change = 0; /* - * Check c->idle_counter and c->at_max_writeback_rate agagain in case - * new I/O arrives during before set_at_max_writeback_rate() returns. - * Then the writeback rate is set to 1, and its new value should be - * decided via __update_writeback_rate(). + * In case new I/O arrives during before + * set_at_max_writeback_rate() returns. */ - if ((atomic_read(&c->idle_counter) < - atomic_read(&c->attached_dev_nr) * 6) || + if (!idle_counter_exceeded(c) || !atomic_read(&c->at_max_writeback_rate)) return false; @@ -519,15 +588,19 @@ uint64_t offset, int nr_sectors) { struct bcache_device *d = c->devices[inode]; - unsigned int stripe_offset, stripe, sectors_dirty; + unsigned int stripe_offset, sectors_dirty; + int stripe; if (!d) return; + stripe = offset_to_stripe(d, offset); + if (stripe < 0) + return; + if (UUID_FLASH_ONLY(&c->uuids[inode])) atomic_long_add(nr_sectors, &c->flash_dev_dirty_sectors); - stripe = offset_to_stripe(d, offset); stripe_offset = offset & (d->stripe_size - 1); while (nr_sectors) { @@ -567,12 +640,12 @@ static void refill_full_stripes(struct cached_dev *dc) { struct keybuf *buf = &dc->writeback_keys; - unsigned int start_stripe, stripe, next_stripe; + unsigned int start_stripe, next_stripe; + int stripe; bool wrapped = false; stripe = offset_to_stripe(&dc->disk, KEY_OFFSET(&buf->last_scanned)); - - if (stripe >= dc->disk.nr_stripes) + if (stripe < 0) stripe = 0; start_stripe = stripe; @@ -812,6 +885,7 @@ dc->writeback_metadata = true; dc->writeback_running = false; + dc->writeback_consider_fragment = true; dc->writeback_percent = 10; dc->writeback_delay = 30; atomic_long_set(&dc->writeback_rate.rate, 1024); @@ -819,6 +893,9 @@ dc->writeback_rate_update_seconds = WRITEBACK_RATE_UPDATE_SECS_DEFAULT; dc->writeback_rate_p_term_inverse = 40; + dc->writeback_rate_fp_term_low = 1; + dc->writeback_rate_fp_term_mid = 10; + dc->writeback_rate_fp_term_high = 1000; dc->writeback_rate_i_term_inverse = 10000; WARN_ON(test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags)); --- linux-oracle-5.4.0.orig/drivers/md/bcache/writeback.h +++ linux-oracle-5.4.0/drivers/md/bcache/writeback.h @@ -16,6 +16,10 @@ #define BCH_AUTO_GC_DIRTY_THRESHOLD 50 +#define BCH_WRITEBACK_FRAGMENT_THRESHOLD_LOW 50 +#define BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID 57 +#define BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH 64 + /* * 14 (16384ths) is chosen here as something that each backing device * should be a reasonable fraction of the share, and not to blow up @@ -33,10 +37,22 @@ return ret; } -static inline unsigned int offset_to_stripe(struct bcache_device *d, +static inline int offset_to_stripe(struct bcache_device *d, uint64_t offset) { do_div(offset, d->stripe_size); + + /* d->nr_stripes is in range [1, INT_MAX] */ + if (unlikely(offset >= d->nr_stripes)) { + pr_err("Invalid stripe %llu (>= nr_stripes %d).\n", + offset, d->nr_stripes); + return -EINVAL; + } + + /* + * Here offset is definitly smaller than INT_MAX, + * return it as int will never overflow. + */ return offset; } @@ -44,7 +60,10 @@ uint64_t offset, unsigned int nr_sectors) { - unsigned int stripe = offset_to_stripe(&dc->disk, offset); + int stripe = offset_to_stripe(&dc->disk, offset); + + if (stripe < 0) + return false; while (1) { if (atomic_read(dc->disk.stripe_sectors_dirty + stripe)) --- linux-oracle-5.4.0.orig/drivers/md/dm-bio-record.h +++ linux-oracle-5.4.0/drivers/md/dm-bio-record.h @@ -20,8 +20,13 @@ struct dm_bio_details { struct gendisk *bi_disk; u8 bi_partno; + int __bi_remaining; unsigned long bi_flags; struct bvec_iter bi_iter; + bio_end_io_t *bi_end_io; +#if defined(CONFIG_BLK_DEV_INTEGRITY) + struct bio_integrity_payload *bi_integrity; +#endif }; static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio) @@ -30,6 +35,11 @@ bd->bi_partno = bio->bi_partno; bd->bi_flags = bio->bi_flags; bd->bi_iter = bio->bi_iter; + bd->__bi_remaining = atomic_read(&bio->__bi_remaining); + bd->bi_end_io = bio->bi_end_io; +#if defined(CONFIG_BLK_DEV_INTEGRITY) + bd->bi_integrity = bio_integrity(bio); +#endif } static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio) @@ -38,6 +48,11 @@ bio->bi_partno = bd->bi_partno; bio->bi_flags = bd->bi_flags; bio->bi_iter = bd->bi_iter; + atomic_set(&bio->__bi_remaining, bd->__bi_remaining); + bio->bi_end_io = bd->bi_end_io; +#if defined(CONFIG_BLK_DEV_INTEGRITY) + bio->bi_integrity = bd->bi_integrity; +#endif } #endif --- linux-oracle-5.4.0.orig/drivers/md/dm-bufio.c +++ linux-oracle-5.4.0/drivers/md/dm-bufio.c @@ -1438,6 +1438,10 @@ sector_t dm_bufio_get_device_size(struct dm_bufio_client *c) { sector_t s = i_size_read(c->bdev->bd_inode) >> SECTOR_SHIFT; + if (s >= c->start) + s -= c->start; + else + s = 0; if (likely(c->sectors_per_block_bits >= 0)) s >>= c->sectors_per_block_bits; else @@ -1446,6 +1450,12 @@ } EXPORT_SYMBOL_GPL(dm_bufio_get_device_size); +struct dm_io_client *dm_bufio_get_dm_io_client(struct dm_bufio_client *c) +{ + return c->dm_io; +} +EXPORT_SYMBOL_GPL(dm_bufio_get_dm_io_client); + sector_t dm_bufio_get_block_number(struct dm_buffer *b) { return b->block; --- linux-oracle-5.4.0.orig/drivers/md/dm-cache-metadata.c +++ linux-oracle-5.4.0/drivers/md/dm-cache-metadata.c @@ -537,21 +537,27 @@ CACHE_MAX_CONCURRENT_LOCKS); if (IS_ERR(cmd->bm)) { DMERR("could not create block manager"); - return PTR_ERR(cmd->bm); + r = PTR_ERR(cmd->bm); + cmd->bm = NULL; + return r; } r = __open_or_format_metadata(cmd, may_format_device); - if (r) + if (r) { dm_block_manager_destroy(cmd->bm); + cmd->bm = NULL; + } return r; } -static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd) +static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd, + bool destroy_bm) { dm_sm_destroy(cmd->metadata_sm); dm_tm_destroy(cmd->tm); - dm_block_manager_destroy(cmd->bm); + if (destroy_bm) + dm_block_manager_destroy(cmd->bm); } typedef unsigned long (*flags_mutator)(unsigned long); @@ -822,7 +828,7 @@ cmd2 = lookup(bdev); if (cmd2) { mutex_unlock(&table_lock); - __destroy_persistent_data_objects(cmd); + __destroy_persistent_data_objects(cmd, true); kfree(cmd); return cmd2; } @@ -870,7 +876,7 @@ mutex_unlock(&table_lock); if (!cmd->fail_io) - __destroy_persistent_data_objects(cmd); + __destroy_persistent_data_objects(cmd, true); kfree(cmd); } } @@ -1804,14 +1810,52 @@ int dm_cache_metadata_abort(struct dm_cache_metadata *cmd) { - int r; + int r = -EINVAL; + struct dm_block_manager *old_bm = NULL, *new_bm = NULL; + + /* fail_io is double-checked with cmd->root_lock held below */ + if (unlikely(cmd->fail_io)) + return r; + + /* + * Replacement block manager (new_bm) is created and old_bm destroyed outside of + * cmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of + * shrinker associated with the block manager's bufio client vs cmd root_lock). + * - must take shrinker_rwsem without holding cmd->root_lock + */ + new_bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE << SECTOR_SHIFT, + CACHE_MAX_CONCURRENT_LOCKS); WRITE_LOCK(cmd); - __destroy_persistent_data_objects(cmd); - r = __create_persistent_data_objects(cmd, false); + if (cmd->fail_io) { + WRITE_UNLOCK(cmd); + goto out; + } + + __destroy_persistent_data_objects(cmd, false); + old_bm = cmd->bm; + if (IS_ERR(new_bm)) { + DMERR("could not create block manager during abort"); + cmd->bm = NULL; + r = PTR_ERR(new_bm); + goto out_unlock; + } + + cmd->bm = new_bm; + r = __open_or_format_metadata(cmd, false); + if (r) { + cmd->bm = NULL; + goto out_unlock; + } + new_bm = NULL; +out_unlock: if (r) cmd->fail_io = true; WRITE_UNLOCK(cmd); + dm_block_manager_destroy(old_bm); +out: + if (new_bm && !IS_ERR(new_bm)) + dm_block_manager_destroy(new_bm); return r; } --- linux-oracle-5.4.0.orig/drivers/md/dm-cache-policy-smq.c +++ linux-oracle-5.4.0/drivers/md/dm-cache-policy-smq.c @@ -854,7 +854,13 @@ struct background_tracker *bg_work; - bool migrations_allowed; + bool migrations_allowed:1; + + /* + * If this is set the policy will try and clean the whole cache + * even if the device is not idle. + */ + bool cleaner:1; }; /*----------------------------------------------------------------*/ @@ -1133,7 +1139,7 @@ * Cache entries may not be populated. So we cannot rely on the * size of the clean queue. */ - if (idle) { + if (idle || mq->cleaner) { /* * We'd like to clean everything. */ @@ -1716,11 +1722,9 @@ *hotspot_block_size /= 2u; } -static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, - sector_t origin_size, - sector_t cache_block_size, - bool mimic_mq, - bool migrations_allowed) +static struct dm_cache_policy * +__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size, + bool mimic_mq, bool migrations_allowed, bool cleaner) { unsigned i; unsigned nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; @@ -1807,6 +1811,7 @@ goto bad_btracker; mq->migrations_allowed = migrations_allowed; + mq->cleaner = cleaner; return &mq->policy; @@ -1830,21 +1835,24 @@ sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, true); + return __smq_create(cache_size, origin_size, cache_block_size, + false, true, false); } static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, true, true); + return __smq_create(cache_size, origin_size, cache_block_size, + true, true, false); } static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, false); + return __smq_create(cache_size, origin_size, cache_block_size, + false, false, true); } /*----------------------------------------------------------------*/ --- linux-oracle-5.4.0.orig/drivers/md/dm-cache-target.c +++ linux-oracle-5.4.0/drivers/md/dm-cache-target.c @@ -1011,16 +1011,16 @@ if (get_cache_mode(cache) >= CM_READ_ONLY) return; - if (dm_cache_metadata_set_needs_check(cache->cmd)) { - DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name); - set_cache_mode(cache, CM_FAIL); - } - DMERR_LIMIT("%s: aborting current metadata transaction", dev_name); if (dm_cache_metadata_abort(cache->cmd)) { DMERR("%s: failed to abort metadata transaction", dev_name); set_cache_mode(cache, CM_FAIL); } + + if (dm_cache_metadata_set_needs_check(cache->cmd)) { + DMERR("%s: failed to set 'needs_check' flag in metadata", dev_name); + set_cache_mode(cache, CM_FAIL); + } } static void metadata_operation_failed(struct cache *cache, const char *op, int r) @@ -1910,6 +1910,7 @@ else commit_needed = process_bio(cache, bio) || commit_needed; + cond_resched(); } if (commit_needed) @@ -1932,6 +1933,7 @@ while ((bio = bio_list_pop(&bios))) { bio->bi_status = BLK_STS_DM_REQUEUE; bio_endio(bio); + cond_resched(); } } @@ -1972,6 +1974,8 @@ r = mg_start(cache, op, NULL); if (r) break; + + cond_resched(); } } @@ -1992,6 +1996,7 @@ if (cache->prison) dm_bio_prison_destroy_v2(cache->prison); + cancel_delayed_work_sync(&cache->waker); if (cache->wq) destroy_workqueue(cache->wq); @@ -2080,7 +2085,6 @@ sector_t cache_sectors; struct dm_dev *origin_dev; - sector_t origin_sectors; uint32_t block_size; @@ -2162,6 +2166,7 @@ static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as, char **error) { + sector_t origin_sectors; int r; if (!at_least_one_arg(as, error)) @@ -2174,8 +2179,8 @@ return r; } - ca->origin_sectors = get_dev_size(ca->origin_dev); - if (ca->ti->len > ca->origin_sectors) { + origin_sectors = get_dev_size(ca->origin_dev); + if (ca->ti->len > origin_sectors) { *error = "Device size larger than cached device"; return -EINVAL; } @@ -2501,7 +2506,7 @@ ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL; - origin_blocks = cache->origin_sectors = ca->origin_sectors; + origin_blocks = cache->origin_sectors = ti->len; origin_blocks = block_div(origin_blocks, ca->block_size); cache->origin_blocks = to_oblock(origin_blocks); @@ -2867,8 +2872,8 @@ prevent_background_work(cache); BUG_ON(atomic_read(&cache->nr_io_migrations)); - cancel_delayed_work(&cache->waker); - flush_workqueue(cache->wq); + cancel_delayed_work_sync(&cache->waker); + drain_workqueue(cache->wq); WARN_ON(cache->tracker.in_flight); /* @@ -2994,19 +2999,19 @@ static bool can_resize(struct cache *cache, dm_cblock_t new_size) { if (from_cblock(new_size) > from_cblock(cache->cache_size)) { - if (cache->sized) { - DMERR("%s: unable to extend cache due to missing cache table reload", - cache_device_name(cache)); - return false; - } + DMERR("%s: unable to extend cache due to missing cache table reload", + cache_device_name(cache)); + return false; } /* * We can't drop a dirty block when shrinking the cache. */ - while (from_cblock(new_size) < from_cblock(cache->cache_size)) { - new_size = to_cblock(from_cblock(new_size) + 1); - if (is_dirty(cache, new_size)) { + if (cache->loaded_mappings) { + new_size = to_cblock(find_next_bit(cache->dirty_bitset, + from_cblock(cache->cache_size), + from_cblock(new_size))); + if (new_size != cache->cache_size) { DMERR("%s: unable to shrink cache; cache block %llu is dirty", cache_device_name(cache), (unsigned long long) from_cblock(new_size)); @@ -3042,20 +3047,15 @@ /* * Check to see if the cache has resized. */ - if (!cache->sized) { - r = resize_cache_dev(cache, csize); - if (r) - return r; - - cache->sized = true; - - } else if (csize != cache->cache_size) { + if (!cache->sized || csize != cache->cache_size) { if (!can_resize(cache, csize)) return -EINVAL; r = resize_cache_dev(cache, csize); if (r) return r; + + cache->sized = true; } if (!cache->loaded_mappings) { --- linux-oracle-5.4.0.orig/drivers/md/dm-clone-metadata.c +++ linux-oracle-5.4.0/drivers/md/dm-clone-metadata.c @@ -67,23 +67,34 @@ * To save constantly doing look ups on disk we keep an in core copy of the * on-disk bitmap, the region_map. * - * To further reduce metadata I/O overhead we use a second bitmap, the dmap - * (dirty bitmap), which tracks the dirty words, i.e. longs, of the region_map. + * In order to track which regions are hydrated during a metadata transaction, + * we use a second set of bitmaps, the dmap (dirty bitmap), which includes two + * bitmaps, namely dirty_regions and dirty_words. The dirty_regions bitmap + * tracks the regions that got hydrated during the current metadata + * transaction. The dirty_words bitmap tracks the dirty words, i.e. longs, of + * the dirty_regions bitmap. + * + * This allows us to precisely track the regions that were hydrated during the + * current metadata transaction and update the metadata accordingly, when we + * commit the current transaction. This is important because dm-clone should + * only commit the metadata of regions that were properly flushed to the + * destination device beforehand. Otherwise, in case of a crash, we could end + * up with a corrupted dm-clone device. * * When a region finishes hydrating dm-clone calls * dm_clone_set_region_hydrated(), or for discard requests * dm_clone_cond_set_range(), which sets the corresponding bits in region_map * and dmap. * - * During a metadata commit we scan the dmap for dirty region_map words (longs) - * and update accordingly the on-disk metadata. Thus, we don't have to flush to - * disk the whole region_map. We can just flush the dirty region_map words. + * During a metadata commit we scan dmap->dirty_words and dmap->dirty_regions + * and update the on-disk metadata accordingly. Thus, we don't have to flush to + * disk the whole region_map. We can just flush the dirty region_map bits. * - * We use a dirty bitmap, which is smaller than the original region_map, to - * reduce the amount of memory accesses during a metadata commit. As dm-bitset - * accesses the on-disk bitmap in 64-bit word granularity, there is no - * significant benefit in tracking the dirty region_map bits with a smaller - * granularity. + * We use the helper dmap->dirty_words bitmap, which is smaller than the + * original region_map, to reduce the amount of memory accesses during a + * metadata commit. Moreover, as dm-bitset also accesses the on-disk bitmap in + * 64-bit word granularity, the dirty_words bitmap helps us avoid useless disk + * accesses. * * We could update directly the on-disk bitmap, when dm-clone calls either * dm_clone_set_region_hydrated() or dm_clone_cond_set_range(), buts this @@ -92,12 +103,13 @@ * e.g., in a hooked overwrite bio's completion routine, and further reduce the * I/O completion latency. * - * We maintain two dirty bitmaps. During a metadata commit we atomically swap - * the currently used dmap with the unused one. This allows the metadata update - * functions to run concurrently with an ongoing commit. + * We maintain two dirty bitmap sets. During a metadata commit we atomically + * swap the currently used dmap with the unused one. This allows the metadata + * update functions to run concurrently with an ongoing commit. */ struct dirty_map { unsigned long *dirty_words; + unsigned long *dirty_regions; unsigned int changed; }; @@ -115,6 +127,9 @@ struct dirty_map dmap[2]; struct dirty_map *current_dmap; + /* Protected by lock */ + struct dirty_map *committing_dmap; + /* * In core copy of the on-disk bitmap to save constantly doing look ups * on disk. @@ -456,39 +471,53 @@ /*---------------------------------------------------------------------------*/ -static size_t bitmap_size(unsigned long nr_bits) +static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words, + unsigned long nr_regions) { - return BITS_TO_LONGS(nr_bits) * sizeof(long); + dmap->changed = 0; + + dmap->dirty_words = kvzalloc(bitmap_size(nr_words), GFP_KERNEL); + if (!dmap->dirty_words) + return -ENOMEM; + + dmap->dirty_regions = kvzalloc(bitmap_size(nr_regions), GFP_KERNEL); + if (!dmap->dirty_regions) { + kvfree(dmap->dirty_words); + return -ENOMEM; + } + + return 0; } -static int dirty_map_init(struct dm_clone_metadata *cmd) +static void __dirty_map_exit(struct dirty_map *dmap) { - cmd->dmap[0].changed = 0; - cmd->dmap[0].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); + kvfree(dmap->dirty_words); + kvfree(dmap->dirty_regions); +} - if (!cmd->dmap[0].dirty_words) { +static int dirty_map_init(struct dm_clone_metadata *cmd) +{ + if (__dirty_map_init(&cmd->dmap[0], cmd->nr_words, cmd->nr_regions)) { DMERR("Failed to allocate dirty bitmap"); return -ENOMEM; } - cmd->dmap[1].changed = 0; - cmd->dmap[1].dirty_words = kvzalloc(bitmap_size(cmd->nr_words), GFP_KERNEL); - - if (!cmd->dmap[1].dirty_words) { + if (__dirty_map_init(&cmd->dmap[1], cmd->nr_words, cmd->nr_regions)) { DMERR("Failed to allocate dirty bitmap"); - kvfree(cmd->dmap[0].dirty_words); + __dirty_map_exit(&cmd->dmap[0]); return -ENOMEM; } cmd->current_dmap = &cmd->dmap[0]; + cmd->committing_dmap = NULL; return 0; } static void dirty_map_exit(struct dm_clone_metadata *cmd) { - kvfree(cmd->dmap[0].dirty_words); - kvfree(cmd->dmap[1].dirty_words); + __dirty_map_exit(&cmd->dmap[0]); + __dirty_map_exit(&cmd->dmap[1]); } static int __load_bitset_in_core(struct dm_clone_metadata *cmd) @@ -622,7 +651,7 @@ return (bit >= (start + nr_regions)); } -unsigned long dm_clone_nr_of_hydrated_regions(struct dm_clone_metadata *cmd) +unsigned int dm_clone_nr_of_hydrated_regions(struct dm_clone_metadata *cmd) { return bitmap_weight(cmd->region_map, cmd->nr_regions); } @@ -633,21 +662,23 @@ return find_next_zero_bit(cmd->region_map, cmd->nr_regions, start); } -static int __update_metadata_word(struct dm_clone_metadata *cmd, unsigned long word) +static int __update_metadata_word(struct dm_clone_metadata *cmd, + unsigned long *dirty_regions, + unsigned long word) { int r; unsigned long index = word * BITS_PER_LONG; unsigned long max_index = min(cmd->nr_regions, (word + 1) * BITS_PER_LONG); while (index < max_index) { - if (test_bit(index, cmd->region_map)) { + if (test_bit(index, dirty_regions)) { r = dm_bitset_set_bit(&cmd->bitset_info, cmd->bitset_root, index, &cmd->bitset_root); - if (r) { DMERR("dm_bitset_set_bit failed"); return r; } + __clear_bit(index, dirty_regions); } index++; } @@ -712,7 +743,7 @@ static int __flush_dmap(struct dm_clone_metadata *cmd, struct dirty_map *dmap) { int r; - unsigned long word, flags; + unsigned long word; word = 0; do { @@ -721,7 +752,7 @@ if (word == cmd->nr_words) break; - r = __update_metadata_word(cmd, word); + r = __update_metadata_word(cmd, dmap->dirty_regions, word); if (r) return r; @@ -736,23 +767,24 @@ return r; /* Update the changed flag */ - spin_lock_irqsave(&cmd->bitmap_lock, flags); + spin_lock_irq(&cmd->bitmap_lock); dmap->changed = 0; - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); + spin_unlock_irq(&cmd->bitmap_lock); return 0; } -int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) +int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd) { - int r = -EPERM; - unsigned long flags; + int r = 0; struct dirty_map *dmap, *next_dmap; down_write(&cmd->lock); - if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { + r = -EPERM; goto out; + } /* Get current dirty bitmap */ dmap = cmd->current_dmap; @@ -764,21 +796,43 @@ * The last commit failed, so we don't have a clean dirty-bitmap to * use. */ - if (WARN_ON(next_dmap->changed)) { + if (WARN_ON(next_dmap->changed || cmd->committing_dmap)) { r = -EINVAL; goto out; } /* Swap dirty bitmaps */ - spin_lock_irqsave(&cmd->bitmap_lock, flags); + spin_lock_irq(&cmd->bitmap_lock); cmd->current_dmap = next_dmap; - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); + spin_unlock_irq(&cmd->bitmap_lock); - /* - * No one is accessing the old dirty bitmap anymore, so we can flush - * it. - */ - r = __flush_dmap(cmd, dmap); + /* Set old dirty bitmap as currently committing */ + cmd->committing_dmap = dmap; +out: + up_write(&cmd->lock); + + return r; +} + +int dm_clone_metadata_commit(struct dm_clone_metadata *cmd) +{ + int r = -EPERM; + + down_write(&cmd->lock); + + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) + goto out; + + if (WARN_ON(!cmd->committing_dmap)) { + r = -EINVAL; + goto out; + } + + r = __flush_dmap(cmd, cmd->committing_dmap); + if (!r) { + /* Clear committing dmap */ + cmd->committing_dmap = NULL; + } out: up_write(&cmd->lock); @@ -791,6 +845,12 @@ struct dirty_map *dmap; unsigned long word, flags; + if (unlikely(region_nr >= cmd->nr_regions)) { + DMERR("Region %lu out of range (total number of regions %lu)", + region_nr, cmd->nr_regions); + return -ERANGE; + } + word = region_nr / BITS_PER_LONG; spin_lock_irqsave(&cmd->bitmap_lock, flags); @@ -803,6 +863,7 @@ dmap = cmd->current_dmap; __set_bit(word, dmap->dirty_words); + __set_bit(region_nr, dmap->dirty_regions); __set_bit(region_nr, cmd->region_map); dmap->changed = 1; @@ -817,9 +878,16 @@ { int r = 0; struct dirty_map *dmap; - unsigned long word, region_nr, flags; + unsigned long word, region_nr; - spin_lock_irqsave(&cmd->bitmap_lock, flags); + if (unlikely(start >= cmd->nr_regions || (start + nr_regions) < start || + (start + nr_regions) > cmd->nr_regions)) { + DMERR("Invalid region range: start %lu, nr_regions %lu (total number of regions %lu)", + start, nr_regions, cmd->nr_regions); + return -ERANGE; + } + + spin_lock_irq(&cmd->bitmap_lock); if (cmd->read_only) { r = -EPERM; @@ -831,12 +899,13 @@ if (!test_bit(region_nr, cmd->region_map)) { word = region_nr / BITS_PER_LONG; __set_bit(word, dmap->dirty_words); + __set_bit(region_nr, dmap->dirty_regions); __set_bit(region_nr, cmd->region_map); dmap->changed = 1; } } out: - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); + spin_unlock_irq(&cmd->bitmap_lock); return r; } @@ -903,13 +972,11 @@ void dm_clone_metadata_set_read_only(struct dm_clone_metadata *cmd) { - unsigned long flags; - down_write(&cmd->lock); - spin_lock_irqsave(&cmd->bitmap_lock, flags); + spin_lock_irq(&cmd->bitmap_lock); cmd->read_only = 1; - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); + spin_unlock_irq(&cmd->bitmap_lock); if (!cmd->fail_io) dm_bm_set_read_only(cmd->bm); @@ -919,13 +986,11 @@ void dm_clone_metadata_set_read_write(struct dm_clone_metadata *cmd) { - unsigned long flags; - down_write(&cmd->lock); - spin_lock_irqsave(&cmd->bitmap_lock, flags); + spin_lock_irq(&cmd->bitmap_lock); cmd->read_only = 0; - spin_unlock_irqrestore(&cmd->bitmap_lock, flags); + spin_unlock_irq(&cmd->bitmap_lock); if (!cmd->fail_io) dm_bm_set_read_write(cmd->bm); --- linux-oracle-5.4.0.orig/drivers/md/dm-clone-metadata.h +++ linux-oracle-5.4.0/drivers/md/dm-clone-metadata.h @@ -44,7 +44,9 @@ * @start: Starting region number * @nr_regions: Number of regions in the range * - * This function doesn't block, so it's safe to call it from interrupt context. + * This function doesn't block, but since it uses spin_lock_irq()/spin_unlock_irq() + * it's NOT safe to call it from any context where interrupts are disabled, e.g., + * from interrupt context. */ int dm_clone_cond_set_range(struct dm_clone_metadata *cmd, unsigned long start, unsigned long nr_regions); @@ -73,7 +75,23 @@ /* * Commit dm-clone metadata to disk. + * + * We use a two phase commit: + * + * 1. dm_clone_metadata_pre_commit(): Prepare the current transaction for + * committing. After this is called, all subsequent metadata updates, done + * through either dm_clone_set_region_hydrated() or + * dm_clone_cond_set_range(), will be part of the **next** transaction. + * + * 2. dm_clone_metadata_commit(): Actually commit the current transaction to + * disk and start a new transaction. + * + * This allows dm-clone to flush the destination device after step (1) to + * ensure that all freshly hydrated regions, for which we are updating the + * metadata, are properly written to non-volatile storage and won't be lost in + * case of a crash. */ +int dm_clone_metadata_pre_commit(struct dm_clone_metadata *cmd); int dm_clone_metadata_commit(struct dm_clone_metadata *cmd); /* @@ -110,6 +128,7 @@ * Switches metadata to a read only mode. Once read-only mode has been entered * the following functions will return -EPERM: * + * dm_clone_metadata_pre_commit() * dm_clone_metadata_commit() * dm_clone_set_region_hydrated() * dm_clone_cond_set_range() @@ -137,7 +156,7 @@ /* * Returns the number of hydrated regions. */ -unsigned long dm_clone_nr_of_hydrated_regions(struct dm_clone_metadata *cmd); +unsigned int dm_clone_nr_of_hydrated_regions(struct dm_clone_metadata *cmd); /* * Returns the first unhydrated region with region_nr >= @start --- linux-oracle-5.4.0.orig/drivers/md/dm-clone-target.c +++ linux-oracle-5.4.0/drivers/md/dm-clone-target.c @@ -86,6 +86,12 @@ struct dm_clone_metadata *cmd; + /* + * bio used to flush the destination device, before committing the + * metadata. + */ + struct bio flush_bio; + /* Region hydration hash table */ struct hash_table_bucket *ht; @@ -276,7 +282,7 @@ /* Get the address of the region in sectors */ static inline sector_t region_to_sector(struct clone *clone, unsigned long region_nr) { - return (region_nr << clone->region_shift); + return ((sector_t)region_nr << clone->region_shift); } /* Get the region number of the bio */ @@ -287,10 +293,17 @@ /* Get the region range covered by the bio */ static void bio_region_range(struct clone *clone, struct bio *bio, - unsigned long *rs, unsigned long *re) + unsigned long *rs, unsigned long *nr_regions) { + unsigned long end; + *rs = dm_sector_div_up(bio->bi_iter.bi_sector, clone->region_size); - *re = bio_end_sector(bio) >> clone->region_shift; + end = bio_end_sector(bio) >> clone->region_shift; + + if (*rs >= end) + *nr_regions = 0; + else + *nr_regions = end - *rs; } /* Check whether a bio overwrites a region */ @@ -332,8 +345,6 @@ */ static void issue_bio(struct clone *clone, struct bio *bio) { - unsigned long flags; - if (!bio_triggers_commit(clone, bio)) { generic_make_request(bio); return; @@ -352,9 +363,9 @@ * Batch together any bios that trigger commits and then issue a single * commit for them in process_deferred_flush_bios(). */ - spin_lock_irqsave(&clone->lock, flags); + spin_lock_irq(&clone->lock); bio_list_add(&clone->deferred_flush_bios, bio); - spin_unlock_irqrestore(&clone->lock, flags); + spin_unlock_irq(&clone->lock); wake_worker(clone); } @@ -450,7 +461,7 @@ static void complete_discard_bio(struct clone *clone, struct bio *bio, bool success) { - unsigned long rs, re; + unsigned long rs, nr_regions; /* * If the destination device supports discards, remap and trim the @@ -459,9 +470,9 @@ */ if (test_bit(DM_CLONE_DISCARD_PASSDOWN, &clone->flags) && success) { remap_to_dest(clone, bio); - bio_region_range(clone, bio, &rs, &re); - trim_bio(bio, rs << clone->region_shift, - (re - rs) << clone->region_shift); + bio_region_range(clone, bio, &rs, &nr_regions); + trim_bio(bio, region_to_sector(clone, rs), + nr_regions << clone->region_shift); generic_make_request(bio); } else bio_endio(bio); @@ -469,12 +480,21 @@ static void process_discard_bio(struct clone *clone, struct bio *bio) { - unsigned long rs, re, flags; + unsigned long rs, nr_regions; - bio_region_range(clone, bio, &rs, &re); - BUG_ON(re > clone->nr_regions); + bio_region_range(clone, bio, &rs, &nr_regions); + if (!nr_regions) { + bio_endio(bio); + return; + } - if (unlikely(rs == re)) { + if (WARN_ON(rs >= clone->nr_regions || (rs + nr_regions) < rs || + (rs + nr_regions) > clone->nr_regions)) { + DMERR("%s: Invalid range (%lu + %lu, total regions %lu) for discard (%llu + %u)", + clone_device_name(clone), rs, nr_regions, + clone->nr_regions, + (unsigned long long)bio->bi_iter.bi_sector, + bio_sectors(bio)); bio_endio(bio); return; } @@ -483,7 +503,7 @@ * The covered regions are already hydrated so we just need to pass * down the discard. */ - if (dm_clone_is_range_hydrated(clone->cmd, rs, re - rs)) { + if (dm_clone_is_range_hydrated(clone->cmd, rs, nr_regions)) { complete_discard_bio(clone, bio, true); return; } @@ -501,9 +521,9 @@ /* * Defer discard processing. */ - spin_lock_irqsave(&clone->lock, flags); + spin_lock_irq(&clone->lock); bio_list_add(&clone->deferred_discard_bios, bio); - spin_unlock_irqrestore(&clone->lock, flags); + spin_unlock_irq(&clone->lock); wake_worker(clone); } @@ -778,11 +798,14 @@ struct dm_io_region from, to; struct clone *clone = hd->clone; + if (WARN_ON(!nr_regions)) + return; + region_size = clone->region_size; region_start = hd->region_nr; region_end = region_start + nr_regions - 1; - total_size = (nr_regions - 1) << clone->region_shift; + total_size = region_to_sector(clone, nr_regions - 1); if (region_end == clone->nr_regions - 1) { /* @@ -1106,10 +1129,13 @@ /* * A non-zero return indicates read-only or fail mode. */ -static int commit_metadata(struct clone *clone) +static int commit_metadata(struct clone *clone, bool *dest_dev_flushed) { int r = 0; + if (dest_dev_flushed) + *dest_dev_flushed = false; + mutex_lock(&clone->commit_lock); if (!dm_clone_changed_this_transaction(clone->cmd)) @@ -1120,8 +1146,26 @@ goto out; } - r = dm_clone_metadata_commit(clone->cmd); + r = dm_clone_metadata_pre_commit(clone->cmd); + if (unlikely(r)) { + __metadata_operation_failed(clone, "dm_clone_metadata_pre_commit", r); + goto out; + } + + bio_reset(&clone->flush_bio); + bio_set_dev(&clone->flush_bio, clone->dest_dev->bdev); + clone->flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; + + r = submit_bio_wait(&clone->flush_bio); + if (unlikely(r)) { + __metadata_operation_failed(clone, "flush destination device", r); + goto out; + } + if (dest_dev_flushed) + *dest_dev_flushed = true; + + r = dm_clone_metadata_commit(clone->cmd); if (unlikely(r)) { __metadata_operation_failed(clone, "dm_clone_metadata_commit", r); goto out; @@ -1140,13 +1184,13 @@ int r = -EPERM; struct bio *bio; struct blk_plug plug; - unsigned long rs, re, flags; + unsigned long rs, nr_regions; struct bio_list discards = BIO_EMPTY_LIST; - spin_lock_irqsave(&clone->lock, flags); + spin_lock_irq(&clone->lock); bio_list_merge(&discards, &clone->deferred_discard_bios); bio_list_init(&clone->deferred_discard_bios); - spin_unlock_irqrestore(&clone->lock, flags); + spin_unlock_irq(&clone->lock); if (bio_list_empty(&discards)) return; @@ -1156,14 +1200,13 @@ /* Update the metadata */ bio_list_for_each(bio, &discards) { - bio_region_range(clone, bio, &rs, &re); + bio_region_range(clone, bio, &rs, &nr_regions); /* * A discard request might cover regions that have been already * hydrated. There is no need to update the metadata for these * regions. */ - r = dm_clone_cond_set_range(clone->cmd, rs, re - rs); - + r = dm_clone_cond_set_range(clone->cmd, rs, nr_regions); if (unlikely(r)) break; } @@ -1176,13 +1219,12 @@ static void process_deferred_bios(struct clone *clone) { - unsigned long flags; struct bio_list bios = BIO_EMPTY_LIST; - spin_lock_irqsave(&clone->lock, flags); + spin_lock_irq(&clone->lock); bio_list_merge(&bios, &clone->deferred_bios); bio_list_init(&clone->deferred_bios); - spin_unlock_irqrestore(&clone->lock, flags); + spin_unlock_irq(&clone->lock); if (bio_list_empty(&bios)) return; @@ -1193,7 +1235,7 @@ static void process_deferred_flush_bios(struct clone *clone) { struct bio *bio; - unsigned long flags; + bool dest_dev_flushed; struct bio_list bios = BIO_EMPTY_LIST; struct bio_list bio_completions = BIO_EMPTY_LIST; @@ -1201,19 +1243,19 @@ * If there are any deferred flush bios, we must commit the metadata * before issuing them or signaling their completion. */ - spin_lock_irqsave(&clone->lock, flags); + spin_lock_irq(&clone->lock); bio_list_merge(&bios, &clone->deferred_flush_bios); bio_list_init(&clone->deferred_flush_bios); bio_list_merge(&bio_completions, &clone->deferred_flush_completions); bio_list_init(&clone->deferred_flush_completions); - spin_unlock_irqrestore(&clone->lock, flags); + spin_unlock_irq(&clone->lock); if (bio_list_empty(&bios) && bio_list_empty(&bio_completions) && !(dm_clone_changed_this_transaction(clone->cmd) && need_commit_due_to_time(clone))) return; - if (commit_metadata(clone)) { + if (commit_metadata(clone, &dest_dev_flushed)) { bio_list_merge(&bios, &bio_completions); while ((bio = bio_list_pop(&bios))) @@ -1227,8 +1269,17 @@ while ((bio = bio_list_pop(&bio_completions))) bio_endio(bio); - while ((bio = bio_list_pop(&bios))) - generic_make_request(bio); + while ((bio = bio_list_pop(&bios))) { + if ((bio->bi_opf & REQ_PREFLUSH) && dest_dev_flushed) { + /* We just flushed the destination device as part of + * the metadata commit, so there is no reason to send + * another flush. + */ + bio_endio(bio); + } else { + generic_make_request(bio); + } + } } static void do_worker(struct work_struct *work) @@ -1400,7 +1451,7 @@ /* Commit to ensure statistics aren't out-of-date */ if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) - (void) commit_metadata(clone); + (void) commit_metadata(clone, NULL); r = dm_clone_get_free_metadata_block_count(clone->cmd, &nr_free_metadata_blocks); @@ -1418,7 +1469,7 @@ goto error; } - DMEMIT("%u %llu/%llu %llu %lu/%lu %u ", + DMEMIT("%u %llu/%llu %llu %u/%lu %u ", DM_CLONE_METADATA_BLOCK_SIZE, (unsigned long long)(nr_metadata_blocks - nr_free_metadata_blocks), (unsigned long long)nr_metadata_blocks, @@ -1738,6 +1789,7 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv) { int r; + sector_t nr_regions; struct clone *clone; struct dm_arg_set as; @@ -1779,7 +1831,16 @@ goto out_with_source_dev; clone->region_shift = __ffs(clone->region_size); - clone->nr_regions = dm_sector_div_up(ti->len, clone->region_size); + nr_regions = dm_sector_div_up(ti->len, clone->region_size); + + /* Check for overflow */ + if (nr_regions != (unsigned long)nr_regions) { + ti->error = "Too many regions. Consider increasing the region size"; + r = -EOVERFLOW; + goto out_with_source_dev; + } + + clone->nr_regions = nr_regions; r = validate_nr_regions(clone->nr_regions, &ti->error); if (r) @@ -1834,6 +1895,7 @@ bio_list_init(&clone->deferred_flush_completions); clone->hydration_offset = 0; atomic_set(&clone->hydrations_in_flight, 0); + bio_init(&clone->flush_bio, NULL, 0); clone->wq = alloc_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM, 0); if (!clone->wq) { @@ -1907,6 +1969,7 @@ struct clone *clone = ti->private; mutex_destroy(&clone->commit_lock); + bio_uninit(&clone->flush_bio); for (i = 0; i < clone->nr_ctr_args; i++) kfree(clone->ctr_args[i]); @@ -1914,6 +1977,7 @@ mempool_exit(&clone->hydration_pool); dm_kcopyd_client_destroy(clone->kcopyd_client); + cancel_delayed_work_sync(&clone->waker); destroy_workqueue(clone->wq); hash_table_exit(clone); dm_clone_metadata_close(clone->cmd); @@ -1961,7 +2025,7 @@ wait_event(clone->hydration_stopped, !atomic_read(&clone->hydrations_in_flight)); flush_workqueue(clone->wq); - (void) commit_metadata(clone); + (void) commit_metadata(clone, NULL); } static void clone_resume(struct dm_target *ti) @@ -2168,6 +2232,7 @@ r = dm_register_target(&clone_target); if (r < 0) { DMERR("Failed to register clone target"); + kmem_cache_destroy(_hydration_cache); return r; } --- linux-oracle-5.4.0.orig/drivers/md/dm-core.h +++ linux-oracle-5.4.0/drivers/md/dm-core.h @@ -18,6 +18,8 @@ #include "dm.h" #define DM_RESERVED_MAX_IOS 1024 +#define DM_MAX_TARGETS 1048576 +#define DM_MAX_TARGET_PARAMS 1024 struct dm_kobject_holder { struct kobject kobj; @@ -106,6 +108,10 @@ struct block_device *bdev; + int swap_bios; + struct semaphore swap_bios_semaphore; + struct mutex swap_bios_lock; + struct dm_stats stats; /* for blk-mq request-based DM support */ --- linux-oracle-5.4.0.orig/drivers/md/dm-crypt.c +++ linux-oracle-5.4.0/drivers/md/dm-crypt.c @@ -46,11 +46,11 @@ struct convert_context { struct completion restart; struct bio *bio_in; - struct bio *bio_out; struct bvec_iter iter_in; + struct bio *bio_out; struct bvec_iter iter_out; - u64 cc_sector; atomic_t cc_pending; + u64 cc_sector; union { struct skcipher_request *req; struct aead_request *req_aead; @@ -331,8 +331,14 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, const char *opts) { - unsigned bs = crypto_skcipher_blocksize(any_tfm(cc)); - int log = ilog2(bs); + unsigned bs; + int log; + + if (test_bit(CRYPT_MODE_INTEGRITY_AEAD, &cc->cipher_flags)) + bs = crypto_aead_blocksize(any_tfm_aead(cc)); + else + bs = crypto_skcipher_blocksize(any_tfm(cc)); + log = ilog2(bs); /* we need to calculate how far we must shift the sector count * to get the cipher block count, we use this shift in _gen */ @@ -714,10 +720,10 @@ u8 buf[MAX_CIPHER_BLOCKSIZE] __aligned(__alignof__(__le64)); struct skcipher_request *req; struct scatterlist src, dst; - struct crypto_wait wait; + DECLARE_CRYPTO_WAIT(wait); int err; - req = skcipher_request_alloc(any_tfm(cc), GFP_KERNEL | GFP_NOFS); + req = skcipher_request_alloc(any_tfm(cc), GFP_NOIO); if (!req) return -ENOMEM; @@ -1548,6 +1554,7 @@ io = crypt_io_from_node(rb_first(&write_tree)); rb_erase(&io->rb_node, &write_tree); kcryptd_io_write(io); + cond_resched(); } while (!RB_EMPTY_ROOT(&write_tree)); blk_finish_plug(&plug); } @@ -1620,6 +1627,12 @@ io->ctx.bio_out = clone; io->ctx.iter_out = clone->bi_iter; + if (crypt_integrity_aead(cc)) { + bio_copy_data(clone, io->base_bio); + io->ctx.bio_in = clone; + io->ctx.iter_in = clone->bi_iter; + } + sector += bio_sectors(clone); crypt_inc_pending(io); @@ -2004,7 +2017,7 @@ static int get_key_size(char **key_string) { - return (*key_string[0] == ':') ? -EINVAL : strlen(*key_string) >> 1; + return (*key_string[0] == ':') ? -EINVAL : (int)(strlen(*key_string) >> 1); } #endif @@ -2086,7 +2099,12 @@ struct crypt_config *cc = pool_data; struct page *page; - if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) && + /* + * Note, percpu_counter_read_positive() may over (and under) estimate + * the current usage by at most (batch - 1) * num_online_cpus() pages, + * but avoids potential spinlock contention of an exact result. + */ + if (unlikely(percpu_counter_read_positive(&cc->n_allocated_pages) >= dm_crypt_pages_per_client) && likely(gfp_mask & __GFP_NORETRY)) return NULL; @@ -2700,21 +2718,18 @@ } ret = -ENOMEM; - cc->io_queue = alloc_workqueue("kcryptd_io/%s", - WQ_HIGHPRI | WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, - 1, devname); + cc->io_queue = alloc_workqueue("kcryptd_io/%s", WQ_MEM_RECLAIM, 1, devname); if (!cc->io_queue) { ti->error = "Couldn't create kcryptd io queue"; goto bad; } if (test_bit(DM_CRYPT_SAME_CPU, &cc->flags)) - cc->crypt_queue = alloc_workqueue("kcryptd/%s", - WQ_HIGHPRI | WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, + cc->crypt_queue = alloc_workqueue("kcryptd/%s", WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM, 1, devname); else cc->crypt_queue = alloc_workqueue("kcryptd/%s", - WQ_HIGHPRI | WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, + WQ_CPU_INTENSIVE | WQ_MEM_RECLAIM | WQ_UNBOUND, num_online_cpus(), devname); if (!cc->crypt_queue) { ti->error = "Couldn't create kcryptd queue"; @@ -2734,6 +2749,7 @@ wake_up_process(cc->write_thread); ti->num_flush_bios = 1; + ti->limit_swap_bios = true; return 0; @@ -2808,6 +2824,11 @@ return DM_MAPIO_SUBMITTED; } +static char hex2asc(unsigned char c) +{ + return c + '0' + ((unsigned)(9 - c) >> 4 & 0x27); +} + static void crypt_status(struct dm_target *ti, status_type_t type, unsigned status_flags, char *result, unsigned maxlen) { @@ -2826,9 +2847,12 @@ if (cc->key_size > 0) { if (cc->key_string) DMEMIT(":%u:%s", cc->key_size, cc->key_string); - else - for (i = 0; i < cc->key_size; i++) - DMEMIT("%02x", cc->key[i]); + else { + for (i = 0; i < cc->key_size; i++) { + DMEMIT("%c%c", hex2asc(cc->key[i] >> 4), + hex2asc(cc->key[i] & 0xf)); + } + } } else DMEMIT("-"); @@ -2954,7 +2978,7 @@ limits->max_segment_size = PAGE_SIZE; limits->logical_block_size = - max_t(unsigned short, limits->logical_block_size, cc->sector_size); + max_t(unsigned, limits->logical_block_size, cc->sector_size); limits->physical_block_size = max_t(unsigned, limits->physical_block_size, cc->sector_size); limits->io_min = max_t(unsigned, limits->io_min, cc->sector_size); --- linux-oracle-5.4.0.orig/drivers/md/dm-delay.c +++ linux-oracle-5.4.0/drivers/md/dm-delay.c @@ -30,7 +30,7 @@ struct workqueue_struct *kdelayd_wq; struct work_struct flush_expired_bios; struct list_head delayed_bios; - atomic_t may_delay; + bool may_delay; struct delay_class read; struct delay_class write; @@ -191,7 +191,7 @@ INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); INIT_LIST_HEAD(&dc->delayed_bios); mutex_init(&dc->timer_lock); - atomic_set(&dc->may_delay, 1); + dc->may_delay = true; dc->argc = argc; ret = delay_class_ctr(ti, &dc->read, argv); @@ -245,7 +245,7 @@ struct dm_delay_info *delayed; unsigned long expires = 0; - if (!c->delay || !atomic_read(&dc->may_delay)) + if (!c->delay) return DM_MAPIO_REMAPPED; delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info)); @@ -254,6 +254,10 @@ delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay); mutex_lock(&delayed_bios_lock); + if (unlikely(!dc->may_delay)) { + mutex_unlock(&delayed_bios_lock); + return DM_MAPIO_REMAPPED; + } c->ops++; list_add_tail(&delayed->list, &dc->delayed_bios); mutex_unlock(&delayed_bios_lock); @@ -267,7 +271,10 @@ { struct delay_c *dc = ti->private; - atomic_set(&dc->may_delay, 0); + mutex_lock(&delayed_bios_lock); + dc->may_delay = false; + mutex_unlock(&delayed_bios_lock); + del_timer_sync(&dc->delay_timer); flush_bios(flush_delayed_bios(dc, 1)); } @@ -276,7 +283,7 @@ { struct delay_c *dc = ti->private; - atomic_set(&dc->may_delay, 1); + dc->may_delay = true; } static int delay_map(struct dm_target *ti, struct bio *bio) --- linux-oracle-5.4.0.orig/drivers/md/dm-era-target.c +++ linux-oracle-5.4.0/drivers/md/dm-era-target.c @@ -47,6 +47,7 @@ static void writeset_free(struct writeset *ws) { vfree(ws->bits); + ws->bits = NULL; } static int setup_on_disk_bitset(struct dm_disk_bitset *info, @@ -71,8 +72,6 @@ */ static int writeset_alloc(struct writeset *ws, dm_block_t nr_blocks) { - ws->md.nr_bits = nr_blocks; - ws->md.root = INVALID_WRITESET_ROOT; ws->bits = vzalloc(bitset_size(nr_blocks)); if (!ws->bits) { DMERR("%s: couldn't allocate in memory bitset", __func__); @@ -85,12 +84,14 @@ /* * Wipes the in-core bitset, and creates a new on disk bitset. */ -static int writeset_init(struct dm_disk_bitset *info, struct writeset *ws) +static int writeset_init(struct dm_disk_bitset *info, struct writeset *ws, + dm_block_t nr_blocks) { int r; - memset(ws->bits, 0, bitset_size(ws->md.nr_bits)); + memset(ws->bits, 0, bitset_size(nr_blocks)); + ws->md.nr_bits = nr_blocks; r = setup_on_disk_bitset(info, ws->md.nr_bits, &ws->md.root); if (r) { DMERR("%s: setup_on_disk_bitset failed", __func__); @@ -134,7 +135,7 @@ { int r; - if (!test_and_set_bit(block, ws->bits)) { + if (!test_bit(block, ws->bits)) { r = dm_bitset_set_bit(info, ws->md.root, block, &ws->md.root); if (r) { /* FIXME: fail mode */ @@ -388,7 +389,7 @@ static int ws_eq(void *context, const void *value1, const void *value2) { - return !memcmp(value1, value2, sizeof(struct writeset_metadata)); + return !memcmp(value1, value2, sizeof(struct writeset_disk)); } /*----------------------------------------------------------------*/ @@ -564,6 +565,15 @@ } disk = dm_block_data(sblock); + + /* Verify the data block size hasn't changed */ + if (le32_to_cpu(disk->data_block_size) != md->block_size) { + DMERR("changing the data block size (from %u to %llu) is not supported", + le32_to_cpu(disk->data_block_size), md->block_size); + r = -EINVAL; + goto bad; + } + r = dm_tm_open_with_sm(md->bm, SUPERBLOCK_LOCATION, disk->metadata_space_map_root, sizeof(disk->metadata_space_map_root), @@ -575,10 +585,10 @@ setup_infos(md); - md->block_size = le32_to_cpu(disk->data_block_size); md->nr_blocks = le32_to_cpu(disk->nr_blocks); md->current_era = le32_to_cpu(disk->current_era); + ws_unpack(&disk->current_writeset, &md->current_writeset->md); md->writeset_tree_root = le64_to_cpu(disk->writeset_tree_root); md->era_array_root = le64_to_cpu(disk->era_array_root); md->metadata_snap = le64_to_cpu(disk->metadata_snap); @@ -746,6 +756,12 @@ ws_unpack(&disk, &d->writeset); d->value = cpu_to_le32(key); + /* + * We initialise another bitset info to avoid any caching side effects + * with the previous one. + */ + dm_disk_bitset_init(md->tm, &d->info); + d->nr_bits = min(d->writeset.nr_bits, md->nr_blocks); d->current_bit = 0; d->step = metadata_digest_transcribe_writeset; @@ -759,12 +775,6 @@ return 0; memset(d, 0, sizeof(*d)); - - /* - * We initialise another bitset info to avoid any caching side - * effects with the previous one. - */ - dm_disk_bitset_init(md->tm, &d->info); d->step = metadata_digest_lookup_writeset; return 0; @@ -802,6 +812,8 @@ static void metadata_close(struct era_metadata *md) { + writeset_free(&md->writesets[0]); + writeset_free(&md->writesets[1]); destroy_persistent_data_objects(md); kfree(md); } @@ -839,6 +851,7 @@ r = writeset_alloc(&md->writesets[1], *new_size); if (r) { DMERR("%s: writeset_alloc failed for writeset 1", __func__); + writeset_free(&md->writesets[0]); return r; } @@ -849,6 +862,8 @@ &value, &md->era_array_root); if (r) { DMERR("%s: dm_array_resize failed", __func__); + writeset_free(&md->writesets[0]); + writeset_free(&md->writesets[1]); return r; } @@ -870,7 +885,6 @@ } ws_pack(&md->current_writeset->md, &value); - md->current_writeset->md.root = INVALID_WRITESET_ROOT; keys[0] = md->current_era; __dm_bless_for_disk(&value); @@ -882,6 +896,7 @@ return r; } + md->current_writeset->md.root = INVALID_WRITESET_ROOT; md->archived_writesets = true; return 0; @@ -898,7 +913,7 @@ int r; struct writeset *new_writeset = next_writeset(md); - r = writeset_init(&md->bitset_info, new_writeset); + r = writeset_init(&md->bitset_info, new_writeset, md->nr_blocks); if (r) { DMERR("%s: writeset_init failed", __func__); return r; @@ -951,7 +966,7 @@ int r; struct dm_block *sblock; - if (md->current_writeset->md.root != SUPERBLOCK_LOCATION) { + if (md->current_writeset->md.root != INVALID_WRITESET_ROOT) { r = dm_bitset_flush(&md->bitset_info, md->current_writeset->md.root, &md->current_writeset->md.root); if (r) { @@ -1226,8 +1241,10 @@ int r; struct bio_list deferred_bios, marked_bios; struct bio *bio; + struct blk_plug plug; bool commit_needed = false; bool failed = false; + struct writeset *ws = era->md->current_writeset; bio_list_init(&deferred_bios); bio_list_init(&marked_bios); @@ -1237,9 +1254,11 @@ bio_list_init(&era->deferred_bios); spin_unlock(&era->deferred_lock); + if (bio_list_empty(&deferred_bios)) + return; + while ((bio = bio_list_pop(&deferred_bios))) { - r = writeset_test_and_set(&era->md->bitset_info, - era->md->current_writeset, + r = writeset_test_and_set(&era->md->bitset_info, ws, get_block(era, bio)); if (r < 0) { /* @@ -1247,7 +1266,6 @@ * FIXME: finish. */ failed = true; - } else if (r == 0) commit_needed = true; @@ -1263,9 +1281,19 @@ if (failed) while ((bio = bio_list_pop(&marked_bios))) bio_io_error(bio); - else - while ((bio = bio_list_pop(&marked_bios))) + else { + blk_start_plug(&plug); + while ((bio = bio_list_pop(&marked_bios))) { + /* + * Only update the in-core writeset if the on-disk one + * was updated too. + */ + if (commit_needed) + set_bit(get_block(era, bio), ws->bits); generic_make_request(bio); + } + blk_finish_plug(&plug); + } } static void process_rpc_calls(struct era *era) @@ -1369,7 +1397,7 @@ static void stop_worker(struct era *era) { atomic_set(&era->suspended, 1); - flush_workqueue(era->wq); + drain_workqueue(era->wq); } /*---------------------------------------------------------------- @@ -1486,15 +1514,6 @@ } era->md = md; - era->nr_blocks = calc_nr_blocks(era); - - r = metadata_resize(era->md, &era->nr_blocks); - if (r) { - ti->error = "couldn't resize metadata"; - era_destroy(era); - return -ENOMEM; - } - era->wq = alloc_ordered_workqueue("dm-" DM_MSG_PREFIX, WQ_MEM_RECLAIM); if (!era->wq) { ti->error = "could not create workqueue for metadata object"; @@ -1562,6 +1581,12 @@ } stop_worker(era); + + r = metadata_commit(era->md); + if (r) { + DMERR("%s: metadata_commit failed", __func__); + /* FIXME: fail mode */ + } } static int era_preresume(struct dm_target *ti) @@ -1571,16 +1596,24 @@ dm_block_t new_size = calc_nr_blocks(era); if (era->nr_blocks != new_size) { - r = in_worker1(era, metadata_resize, &new_size); - if (r) + r = metadata_resize(era->md, &new_size); + if (r) { + DMERR("%s: metadata_resize failed", __func__); return r; + } + + r = metadata_commit(era->md); + if (r) { + DMERR("%s: metadata_commit failed", __func__); + return r; + } era->nr_blocks = new_size; } start_worker(era); - r = in_worker0(era, metadata_new_era); + r = in_worker0(era, metadata_era_rollover); if (r) { DMERR("%s: metadata_era_rollover failed", __func__); return r; --- linux-oracle-5.4.0.orig/drivers/md/dm-flakey.c +++ linux-oracle-5.4.0/drivers/md/dm-flakey.c @@ -124,9 +124,9 @@ * Direction r or w? */ arg_name = dm_shift_arg(as); - if (!strcasecmp(arg_name, "w")) + if (arg_name && !strcasecmp(arg_name, "w")) fc->corrupt_bio_rw = WRITE; - else if (!strcasecmp(arg_name, "r")) + else if (arg_name && !strcasecmp(arg_name, "r")) fc->corrupt_bio_rw = READ; else { ti->error = "Invalid corrupt bio direction (r or w)"; @@ -301,8 +301,11 @@ */ bio_for_each_segment(bvec, bio, iter) { if (bio_iter_len(bio, iter) > corrupt_bio_byte) { - char *segment = (page_address(bio_iter_page(bio, iter)) - + bio_iter_offset(bio, iter)); + char *segment; + struct page *page = bio_iter_page(bio, iter); + if (unlikely(page == ZERO_PAGE(0))) + break; + segment = (page_address(page) + bio_iter_offset(bio, iter)); segment[corrupt_bio_byte] = fc->corrupt_bio_value; DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " "(rw=%c bi_opf=%u bi_sector=%llu size=%u)\n", @@ -360,9 +363,11 @@ /* * Corrupt matching writes. */ - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) { - if (all_corrupt_bio_flags_match(bio, fc)) - corrupt_bio_data(bio, fc); + if (fc->corrupt_bio_byte) { + if (fc->corrupt_bio_rw == WRITE) { + if (all_corrupt_bio_flags_match(bio, fc)) + corrupt_bio_data(bio, fc); + } goto map_bio; } @@ -388,13 +393,14 @@ return DM_ENDIO_DONE; if (!*error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && - all_corrupt_bio_flags_match(bio, fc)) { - /* - * Corrupt successful matching READs while in down state. - */ - corrupt_bio_data(bio, fc); - + if (fc->corrupt_bio_byte) { + if ((fc->corrupt_bio_rw == READ) && + all_corrupt_bio_flags_match(bio, fc)) { + /* + * Corrupt successful matching READs while in down state. + */ + corrupt_bio_data(bio, fc); + } } else if (!test_bit(DROP_WRITES, &fc->flags) && !test_bit(ERROR_WRITES, &fc->flags)) { /* --- linux-oracle-5.4.0.orig/drivers/md/dm-init.c +++ linux-oracle-5.4.0/drivers/md/dm-init.c @@ -207,8 +207,10 @@ strscpy(dev->dmi.uuid, field[1], sizeof(dev->dmi.uuid)); /* minor */ if (strlen(field[2])) { - if (kstrtoull(field[2], 0, &dev->dmi.dev)) + if (kstrtoull(field[2], 0, &dev->dmi.dev) || + dev->dmi.dev >= (1 << MINORBITS)) return ERR_PTR(-EINVAL); + dev->dmi.dev = huge_encode_dev((dev_t)dev->dmi.dev); dev->dmi.flags |= DM_PERSISTENT_DEV_FLAG; } /* flags */ --- linux-oracle-5.4.0.orig/drivers/md/dm-integrity.c +++ linux-oracle-5.4.0/drivers/md/dm-integrity.c @@ -6,6 +6,8 @@ * This file is released under the GPL. */ +#include "dm-bio-record.h" + #include #include #include @@ -29,11 +31,11 @@ #define DEFAULT_BUFFER_SECTORS 128 #define DEFAULT_JOURNAL_WATERMARK 50 #define DEFAULT_SYNC_MSEC 10000 -#define DEFAULT_MAX_JOURNAL_SECTORS 131072 +#define DEFAULT_MAX_JOURNAL_SECTORS (IS_ENABLED(CONFIG_64BIT) ? 131072 : 8192) #define MIN_LOG2_INTERLEAVE_SECTORS 3 #define MAX_LOG2_INTERLEAVE_SECTORS 31 #define METADATA_WORKQUEUE_MAX_ACTIVE 16 -#define RECALC_SECTORS 8192 +#define RECALC_SECTORS (IS_ENABLED(CONFIG_64BIT) ? 32768 : 2048) #define RECALC_WRITE_SUPER 16 #define BITMAP_BLOCK_SIZE 4096 /* don't change it */ #define BITMAP_FLUSH_INTERVAL (10 * HZ) @@ -199,17 +201,19 @@ __u8 log2_blocks_per_bitmap_bit; unsigned char mode; - int suspending; int failed; struct crypto_shash *internal_hash; + struct dm_target *ti; + /* these variables are locked with endio_wait.lock */ struct rb_root in_progress; struct list_head wait_list; wait_queue_head_t endio_wait; struct workqueue_struct *wait_wq; + struct workqueue_struct *offload_wq; unsigned char commit_seq; commit_id_t commit_ids[N_COMMIT_IDS]; @@ -250,6 +254,7 @@ bool journal_uptodate; bool just_formatted; bool recalculate_flag; + bool legacy_recalculate; struct alg_spec internal_hash_alg; struct alg_spec journal_crypt_alg; @@ -290,11 +295,7 @@ struct completion *completion; - struct gendisk *orig_bi_disk; - u8 orig_bi_partno; - bio_end_io_t *orig_bi_end_io; - struct bio_integrity_payload *orig_bi_integrity; - struct bvec_iter orig_bi_iter; + struct dm_bio_details bio_details; }; struct journal_completion { @@ -381,6 +382,14 @@ return READ_ONCE(ic->failed); } +static bool dm_integrity_disable_recalculate(struct dm_integrity_c *ic) +{ + if ((ic->internal_hash_alg.key || ic->journal_mac_alg.key) && + !ic->legacy_recalculate) + return true; + return false; +} + static commit_id_t dm_integrity_commit_id(struct dm_integrity_c *ic, unsigned i, unsigned j, unsigned char seq) { @@ -1343,12 +1352,52 @@ return 0; } -static void dm_integrity_flush_buffers(struct dm_integrity_c *ic) +struct flush_request { + struct dm_io_request io_req; + struct dm_io_region io_reg; + struct dm_integrity_c *ic; + struct completion comp; +}; + +static void flush_notify(unsigned long error, void *fr_) +{ + struct flush_request *fr = fr_; + if (unlikely(error != 0)) + dm_integrity_io_error(fr->ic, "flusing disk cache", -EIO); + complete(&fr->comp); +} + +static void dm_integrity_flush_buffers(struct dm_integrity_c *ic, bool flush_data) { int r; + + struct flush_request fr; + + if (!ic->meta_dev) + flush_data = false; + if (flush_data) { + fr.io_req.bi_op = REQ_OP_WRITE, + fr.io_req.bi_op_flags = REQ_PREFLUSH | REQ_SYNC, + fr.io_req.mem.type = DM_IO_KMEM, + fr.io_req.mem.ptr.addr = NULL, + fr.io_req.notify.fn = flush_notify, + fr.io_req.notify.context = &fr; + fr.io_req.client = dm_bufio_get_dm_io_client(ic->bufio), + fr.io_reg.bdev = ic->dev->bdev, + fr.io_reg.sector = 0, + fr.io_reg.count = 0, + fr.ic = ic; + init_completion(&fr.comp); + r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL); + BUG_ON(r); + } + r = dm_bufio_write_dirty_buffers(ic->bufio); if (unlikely(r)) dm_integrity_io_error(ic, "writing tags", r); + + if (flush_data) + wait_for_completion(&fr.comp); } static void sleep_on_endio_wait(struct dm_integrity_c *ic) @@ -1434,7 +1483,7 @@ dio->range.logical_sector += dio->range.n_sectors; bio_advance(bio, dio->range.n_sectors << SECTOR_SHIFT); INIT_WORK(&dio->work, integrity_bio_wait); - queue_work(ic->wait_wq, &dio->work); + queue_work(ic->offload_wq, &dio->work); return; } do_endio_flush(ic, dio); @@ -1445,14 +1494,9 @@ { struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io)); - bio->bi_iter = dio->orig_bi_iter; - bio->bi_disk = dio->orig_bi_disk; - bio->bi_partno = dio->orig_bi_partno; - if (dio->orig_bi_integrity) { - bio->bi_integrity = dio->orig_bi_integrity; + dm_bio_restore(&dio->bio_details, bio); + if (bio->bi_integrity) bio->bi_opf |= REQ_INTEGRITY; - } - bio->bi_end_io = dio->orig_bi_end_io; if (dio->completion) complete(dio->completion); @@ -1519,7 +1563,7 @@ struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); char *checksums; unsigned extra_space = unlikely(digest_size > ic->tag_size) ? digest_size - ic->tag_size : 0; - char checksums_onstack[HASH_MAX_DIGESTSIZE]; + char checksums_onstack[max((size_t)HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; unsigned sectors_to_process = dio->range.n_sectors; sector_t sector = dio->range.logical_sector; @@ -1537,12 +1581,13 @@ } } - __bio_for_each_segment(bv, bio, iter, dio->orig_bi_iter) { + __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { + struct bio_vec bv_copy = bv; unsigned pos; char *mem, *checksums_ptr; again: - mem = (char *)kmap_atomic(bv.bv_page) + bv.bv_offset; + mem = (char *)kmap_atomic(bv_copy.bv_page) + bv_copy.bv_offset; pos = 0; checksums_ptr = checksums; do { @@ -1551,7 +1596,7 @@ sectors_to_process -= ic->sectors_per_block; pos += ic->sectors_per_block << SECTOR_SHIFT; sector += ic->sectors_per_block; - } while (pos < bv.bv_len && sectors_to_process && checksums != checksums_onstack); + } while (pos < bv_copy.bv_len && sectors_to_process && checksums != checksums_onstack); kunmap_atomic(mem); r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset, @@ -1571,9 +1616,9 @@ if (!sectors_to_process) break; - if (unlikely(pos < bv.bv_len)) { - bv.bv_offset += pos; - bv.bv_len -= pos; + if (unlikely(pos < bv_copy.bv_len)) { + bv_copy.bv_offset += pos; + bv_copy.bv_len -= pos; goto again; } } @@ -1581,7 +1626,7 @@ if (likely(checksums != checksums_onstack)) kfree(checksums); } else { - struct bio_integrity_payload *bip = dio->orig_bi_integrity; + struct bio_integrity_payload *bip = dio->bio_details.bi_integrity; if (bip) { struct bio_vec biv; @@ -1748,7 +1793,7 @@ } while (++s < ic->sectors_per_block); #ifdef INTERNAL_VERIFY if (ic->internal_hash) { - char checksums_onstack[max(HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; + char checksums_onstack[max((size_t)HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; integrity_sector_checksum(ic, logical_sector, mem + bv.bv_offset, checksums_onstack); if (unlikely(memcmp(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) { @@ -1860,7 +1905,7 @@ if (need_sync_io && from_map) { INIT_WORK(&dio->work, integrity_bio_wait); - queue_work(ic->metadata_wq, &dio->work); + queue_work(ic->offload_wq, &dio->work); return; } @@ -2000,20 +2045,13 @@ } else dio->completion = NULL; - dio->orig_bi_iter = bio->bi_iter; - - dio->orig_bi_disk = bio->bi_disk; - dio->orig_bi_partno = bio->bi_partno; + dm_bio_record(&dio->bio_details, bio); bio_set_dev(bio, ic->dev->bdev); - - dio->orig_bi_integrity = bio_integrity(bio); bio->bi_integrity = NULL; bio->bi_opf &= ~REQ_INTEGRITY; - - dio->orig_bi_end_io = bio->bi_end_io; bio->bi_end_io = integrity_end_io; - bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT; + generic_make_request(bio); if (need_sync_io) { @@ -2089,7 +2127,7 @@ flushes = bio_list_get(&ic->flush_bio_list); if (unlikely(ic->mode != 'J')) { spin_unlock_irq(&ic->endio_wait.lock); - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, true); goto release_flush_bios; } @@ -2299,7 +2337,7 @@ complete_journal_op(&comp); wait_for_completion_io(&comp.comp); - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, true); } static void integrity_writer(struct work_struct *w) @@ -2309,10 +2347,6 @@ unsigned prev_free_sectors; - /* the following test is not needed, but it tests the replay code */ - if (READ_ONCE(ic->suspending) && !ic->meta_dev) - return; - spin_lock_irq(&ic->endio_wait.lock); write_start = ic->committed_section; write_sections = ic->n_committed_sections; @@ -2341,7 +2375,7 @@ { int r; - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, false); if (dm_integrity_failed(ic)) return; @@ -2371,12 +2405,13 @@ next_chunk: - if (unlikely(READ_ONCE(ic->suspending))) + if (unlikely(dm_post_suspending(ic->ti))) goto unlock_ret; range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); if (unlikely(range.logical_sector >= ic->provided_data_sectors)) { if (ic->mode == 'B') { + block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); DEBUG_print("queue_delayed_work: bitmap_flush_work\n"); queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, 0); } @@ -2454,6 +2489,17 @@ goto err; } + if (ic->mode == 'B') { + sector_t start, end; + start = (range.logical_sector >> + (ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit)) << + (ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit); + end = ((range.logical_sector + range.n_sectors) >> + (ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit)) << + (ic->sb->log2_sectors_per_block + ic->log2_blocks_per_bitmap_bit); + block_bitmap_op(ic, ic->recalc_bitmap, start, end - start, BITMAP_OP_CLEAR); + } + advance_and_next: cond_resched(); @@ -2496,7 +2542,7 @@ dio->range.n_sectors, BITMAP_OP_TEST_ALL_SET)) { remove_range(ic, &dio->range); INIT_WORK(&dio->work, integrity_bio_wait); - queue_work(ic->wait_wq, &dio->work); + queue_work(ic->offload_wq, &dio->work); } else { block_bitmap_op(ic, ic->journal, dio->range.logical_sector, dio->range.n_sectors, BITMAP_OP_SET); @@ -2519,7 +2565,7 @@ remove_range(ic, &dio->range); INIT_WORK(&dio->work, integrity_bio_wait); - queue_work(ic->wait_wq, &dio->work); + queue_work(ic->offload_wq, &dio->work); } queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, ic->bitmap_flush_interval); @@ -2532,7 +2578,7 @@ unsigned long limit; struct bio *bio; - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, false); range.logical_sector = 0; range.n_sectors = ic->provided_data_sectors; @@ -2541,7 +2587,7 @@ add_new_range_and_wait(ic, &range); spin_unlock_irq(&ic->endio_wait.lock); - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, true); if (ic->meta_dev) blkdev_issue_flush(ic->dev->bdev, GFP_NOIO, NULL); @@ -2799,8 +2845,6 @@ del_timer_sync(&ic->autocommit_timer); - WRITE_ONCE(ic->suspending, 1); - if (ic->recalc_wq) drain_workqueue(ic->recalc_wq); @@ -2811,14 +2855,13 @@ drain_workqueue(ic->commit_wq); if (ic->mode == 'J') { - if (ic->meta_dev) - queue_work(ic->writer_wq, &ic->writer_work); + queue_work(ic->writer_wq, &ic->writer_work); drain_workqueue(ic->writer_wq); - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, true); } if (ic->mode == 'B') { - dm_integrity_flush_buffers(ic); + dm_integrity_flush_buffers(ic, true); #if 1 /* set to 0 to test bitmap replay code */ init_journal(ic, 0, ic->journal_sections, 0); @@ -2829,8 +2872,6 @@ #endif } - WRITE_ONCE(ic->suspending, 0); - BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); ic->journal_uptodate = true; @@ -2883,17 +2924,24 @@ } else { replay_journal(ic); if (ic->mode == 'B') { - int mode; ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP); ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit; r = sync_rw_sb(ic, REQ_OP_WRITE, REQ_FUA); if (unlikely(r)) dm_integrity_io_error(ic, "writing superblock", r); - mode = ic->recalculate_flag ? BITMAP_OP_SET : BITMAP_OP_CLEAR; - block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, mode); - block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, mode); - block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, mode); + block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); + block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); + block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && + le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors) { + block_bitmap_op(ic, ic->journal, le64_to_cpu(ic->sb->recalc_sector), + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); + block_bitmap_op(ic, ic->recalc_bitmap, le64_to_cpu(ic->sb->recalc_sector), + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); + block_bitmap_op(ic, ic->may_write_bitmap, le64_to_cpu(ic->sb->recalc_sector), + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); + } rw_journal_sectors(ic, REQ_OP_WRITE, REQ_FUA | REQ_SYNC, 0, ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL); } @@ -2955,13 +3003,14 @@ arg_count += !!ic->internal_hash_alg.alg_string; arg_count += !!ic->journal_crypt_alg.alg_string; arg_count += !!ic->journal_mac_alg.alg_string; + arg_count += ic->legacy_recalculate; DMEMIT("%s %llu %u %c %u", ic->dev->name, (unsigned long long)ic->start, ic->tag_size, ic->mode, arg_count); if (ic->meta_dev) DMEMIT(" meta_device:%s", ic->meta_dev->name); if (ic->sectors_per_block != 1) DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT); - if (ic->recalculate_flag) + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) DMEMIT(" recalculate"); DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS); DMEMIT(" interleave_sectors:%u", 1U << ic->sb->log2_interleave_sectors); @@ -2974,6 +3023,8 @@ DMEMIT(" sectors_per_bit:%llu", (unsigned long long)ic->sectors_per_block << ic->log2_blocks_per_bitmap_bit); DMEMIT(" bitmap_flush_interval:%u", jiffies_to_msecs(ic->bitmap_flush_interval)); } + if (ic->legacy_recalculate) + DMEMIT(" legacy_recalculate"); #define EMIT_ALG(a, n) \ do { \ @@ -3582,7 +3633,7 @@ unsigned extra_args; struct dm_arg_set as; static const struct dm_arg _args[] = { - {0, 9, "Invalid number of feature args"}, + {0, 14, "Invalid number of feature args"}, }; unsigned journal_sectors, interleave_sectors, buffer_sectors, journal_watermark, sync_msec; bool should_write_sb; @@ -3607,6 +3658,7 @@ } ti->private = ic; ti->per_io_data_size = sizeof(struct dm_integrity_io); + ic->ti = ti; ic->in_progress = RB_ROOT; INIT_LIST_HEAD(&ic->wait_list); @@ -3703,9 +3755,10 @@ } else if (sscanf(opt_string, "sectors_per_bit:%llu%c", &llval, &dummy) == 1) { log2_sectors_per_bitmap_bit = !llval ? 0 : __ilog2_u64(llval); } else if (sscanf(opt_string, "bitmap_flush_interval:%u%c", &val, &dummy) == 1) { - if (val >= (uint64_t)UINT_MAX * 1000 / HZ) { + if ((uint64_t)val >= (uint64_t)UINT_MAX * 1000 / HZ) { r = -EINVAL; ti->error = "Invalid bitmap_flush_interval argument"; + goto bad; } ic->bitmap_flush_interval = msecs_to_jiffies(val); } else if (!strncmp(opt_string, "internal_hash:", strlen("internal_hash:"))) { @@ -3725,6 +3778,8 @@ goto bad; } else if (!strcmp(opt_string, "recalculate")) { ic->recalculate_flag = true; + } else if (!strcmp(opt_string, "legacy_recalculate")) { + ic->legacy_recalculate = true; } else { r = -EINVAL; ti->error = "Invalid argument"; @@ -3818,6 +3873,14 @@ goto bad; } + ic->offload_wq = alloc_workqueue("dm-integrity-offload", WQ_MEM_RECLAIM, + METADATA_WORKQUEUE_MAX_ACTIVE); + if (!ic->offload_wq) { + ti->error = "Cannot allocate workqueue"; + r = -ENOMEM; + goto bad; + } + ic->commit_wq = alloc_workqueue("dm-integrity-commit", WQ_MEM_RECLAIM, 1); if (!ic->commit_wq) { ti->error = "Cannot allocate workqueue"; @@ -3987,6 +4050,7 @@ } if (ic->internal_hash) { + size_t recalc_tags_size; ic->recalc_wq = alloc_workqueue("dm-integrity-recalc", WQ_MEM_RECLAIM, 1); if (!ic->recalc_wq ) { ti->error = "Cannot allocate workqueue"; @@ -4000,13 +4064,29 @@ r = -ENOMEM; goto bad; } - ic->recalc_tags = kvmalloc_array(RECALC_SECTORS >> ic->sb->log2_sectors_per_block, - ic->tag_size, GFP_KERNEL); + recalc_tags_size = (RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size; + if (crypto_shash_digestsize(ic->internal_hash) > ic->tag_size) + recalc_tags_size += crypto_shash_digestsize(ic->internal_hash) - ic->tag_size; + ic->recalc_tags = kvmalloc(recalc_tags_size, GFP_KERNEL); if (!ic->recalc_tags) { ti->error = "Cannot allocate tags for recalculating"; r = -ENOMEM; goto bad; } + } else { + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) { + ti->error = "Recalculate can only be specified with internal_hash"; + r = -EINVAL; + goto bad; + } + } + + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && + le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors && + dm_integrity_disable_recalculate(ic)) { + ti->error = "Recalculating with HMAC is disabled for security reasons - if you really need it, use the argument \"legacy_recalculate\""; + r = -EOPNOTSUPP; + goto bad; } ic->bufio = dm_bufio_client_create(ic->meta_dev ? ic->meta_dev->bdev : ic->dev->bdev, @@ -4065,8 +4145,6 @@ } if (should_write_sb) { - int r; - init_journal(ic, 0, ic->journal_sections, 0); r = dm_integrity_failed(ic); if (unlikely(r)) { @@ -4118,10 +4196,14 @@ BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); BUG_ON(!list_empty(&ic->wait_list)); + if (ic->mode == 'B') + cancel_delayed_work_sync(&ic->bitmap_flush_work); if (ic->metadata_wq) destroy_workqueue(ic->metadata_wq); if (ic->wait_wq) destroy_workqueue(ic->wait_wq); + if (ic->offload_wq) + destroy_workqueue(ic->offload_wq); if (ic->commit_wq) destroy_workqueue(ic->commit_wq); if (ic->writer_wq) @@ -4207,11 +4289,13 @@ } r = dm_register_target(&integrity_target); - - if (r < 0) + if (r < 0) { DMERR("register failed %d", r); + kmem_cache_destroy(journal_io_cache); + return r; + } - return r; + return 0; } static void __exit dm_integrity_exit(void) --- linux-oracle-5.4.0.orig/drivers/md/dm-io.c +++ linux-oracle-5.4.0/drivers/md/dm-io.c @@ -306,7 +306,7 @@ struct request_queue *q = bdev_get_queue(where->bdev); unsigned short logical_block_size = queue_logical_block_size(q); sector_t num_sectors; - unsigned int uninitialized_var(special_cmd_max_sectors); + unsigned int special_cmd_max_sectors; /* * Reject unsupported discard and write same requests. --- linux-oracle-5.4.0.orig/drivers/md/dm-ioctl.c +++ linux-oracle-5.4.0/drivers/md/dm-ioctl.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -529,7 +530,7 @@ * Grab our output buffer. */ nl = orig_nl = get_result_buffer(param, param_size, &len); - if (len < needed) { + if (len < needed || len < sizeof(nl->dev)) { param->flags |= DM_BUFFER_FULL_FLAG; goto out; } @@ -572,7 +573,7 @@ size_t *needed = needed_param; *needed += sizeof(struct dm_target_versions); - *needed += strlen(tt->name); + *needed += strlen(tt->name) + 1; *needed += ALIGN_MASK; } @@ -637,7 +638,7 @@ iter_info.old_vers = NULL; iter_info.vers = vers; iter_info.flags = 0; - iter_info.end = (char *)vers+len; + iter_info.end = (char *)vers + needed; /* * Now loop through filling out the names & versions. @@ -808,15 +809,21 @@ struct hash_cell *hc = NULL; if (*param->uuid) { - if (*param->name || param->dev) + if (*param->name || param->dev) { + DMERR("Invalid ioctl structure: uuid %s, name %s, dev %llx", + param->uuid, param->name, (unsigned long long)param->dev); return NULL; + } hc = __get_uuid_cell(param->uuid); if (!hc) return NULL; } else if (*param->name) { - if (param->dev) + if (param->dev) { + DMERR("Invalid ioctl structure: name %s, dev %llx", + param->name, (unsigned long long)param->dev); return NULL; + } hc = __get_name_cell(param->name); if (!hc) @@ -1063,8 +1070,26 @@ suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; if (param->flags & DM_NOFLUSH_FLAG) suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG; - if (!dm_suspended_md(md)) - dm_suspend(md, suspend_flags); + if (!dm_suspended_md(md)) { + r = dm_suspend(md, suspend_flags); + if (r) { + down_write(&_hash_lock); + hc = dm_get_mdptr(md); + if (hc && !hc->new_map) { + hc->new_map = new_map; + new_map = NULL; + } else { + r = -ENXIO; + } + up_write(&_hash_lock); + if (new_map) { + dm_sync_table(md); + dm_table_destroy(new_map); + } + dm_put(md); + return r; + } + } old_map = dm_swap_table(md, new_map); if (IS_ERR(old_map)) { @@ -1434,11 +1459,12 @@ hc->new_map = NULL; } - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; - - __dev_status(hc->md, param); md = hc->md; up_write(&_hash_lock); + + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + __dev_status(md, param); + if (old_map) { dm_sync_table(md); dm_table_destroy(old_map); @@ -1600,6 +1626,7 @@ if (!argc) { DMWARN("Empty message received."); + r = -EINVAL; goto out_argv; } @@ -1695,6 +1722,7 @@ if (unlikely(cmd >= ARRAY_SIZE(_ioctls))) return NULL; + cmd = array_index_nospec(cmd, ARRAY_SIZE(_ioctls)); *ioctl_flags = _ioctls[cmd].flags; return _ioctls[cmd].fn; } @@ -1756,8 +1784,12 @@ if (copy_from_user(param_kernel, user, minimum_data_size)) return -EFAULT; - if (param_kernel->data_size < minimum_data_size) + if (unlikely(param_kernel->data_size < minimum_data_size) || + unlikely(param_kernel->data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS)) { + DMERR("Invalid data size in the ioctl structure: %u", + param_kernel->data_size); return -EINVAL; + } secure_data = param_kernel->flags & DM_SECURE_DATA_FLAG; @@ -1844,7 +1876,7 @@ int ioctl_flags; int param_flags; unsigned int cmd; - struct dm_ioctl *uninitialized_var(param); + struct dm_ioctl *param; ioctl_fn fn = NULL; size_t input_param_size; struct dm_ioctl param_kernel; --- linux-oracle-5.4.0.orig/drivers/md/dm-log.c +++ linux-oracle-5.4.0/drivers/md/dm-log.c @@ -415,8 +415,7 @@ /* * Work out how many "unsigned long"s we need to hold the bitset. */ - bitset_size = dm_round_up(region_count, - sizeof(*lc->clean_bits) << BYTE_SHIFT); + bitset_size = dm_round_up(region_count, BITS_PER_LONG); bitset_size >>= BYTE_SHIFT; lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits); @@ -616,7 +615,7 @@ log_clear_bit(lc, lc->clean_bits, i); /* clear any old bits -- device has shrunk */ - for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++) + for (i = lc->region_count; i % BITS_PER_LONG; i++) log_clear_bit(lc, lc->clean_bits, i); /* copy clean across to sync */ --- linux-oracle-5.4.0.orig/drivers/md/dm-mpath.c +++ linux-oracle-5.4.0/drivers/md/dm-mpath.c @@ -558,7 +558,8 @@ if (pgpath && pgpath->pg->ps.type->end_io) pgpath->pg->ps.type->end_io(&pgpath->pg->ps, &pgpath->path, - mpio->nr_bytes); + mpio->nr_bytes, + clone->io_start_time_ns); } blk_put_request(clone); @@ -576,10 +577,12 @@ /* Do we need to select a new pgpath? */ pgpath = READ_ONCE(m->current_pgpath); - queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); - if (!pgpath || !queue_io) + if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) pgpath = choose_pgpath(m, bio->bi_iter.bi_size); + /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ + queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); + if ((pgpath && queue_io) || (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { /* Queue for the daemon to resubmit */ @@ -599,45 +602,10 @@ return pgpath; } -static struct pgpath *__map_bio_fast(struct multipath *m, struct bio *bio) -{ - struct pgpath *pgpath; - unsigned long flags; - - /* Do we need to select a new pgpath? */ - /* - * FIXME: currently only switching path if no path (due to failure, etc) - * - which negates the point of using a path selector - */ - pgpath = READ_ONCE(m->current_pgpath); - if (!pgpath) - pgpath = choose_pgpath(m, bio->bi_iter.bi_size); - - if (!pgpath) { - if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) { - /* Queue for the daemon to resubmit */ - spin_lock_irqsave(&m->lock, flags); - bio_list_add(&m->queued_bios, bio); - spin_unlock_irqrestore(&m->lock, flags); - queue_work(kmultipathd, &m->process_queued_bios); - - return ERR_PTR(-EAGAIN); - } - return NULL; - } - - return pgpath; -} - static int __multipath_map_bio(struct multipath *m, struct bio *bio, struct dm_mpath_io *mpio) { - struct pgpath *pgpath; - - if (!m->hw_handler_name) - pgpath = __map_bio_fast(m, bio); - else - pgpath = __map_bio(m, bio); + struct pgpath *pgpath = __map_bio(m, bio); if (IS_ERR(pgpath)) return DM_MAPIO_SUBMITTED; @@ -1223,17 +1191,25 @@ static void flush_multipath_work(struct multipath *m) { if (m->hw_handler_name) { - set_bit(MPATHF_PG_INIT_DISABLED, &m->flags); - smp_mb__after_atomic(); + unsigned long flags; + + if (!atomic_read(&m->pg_init_in_progress)) + goto skip; + + spin_lock_irqsave(&m->lock, flags); + if (atomic_read(&m->pg_init_in_progress) && + !test_and_set_bit(MPATHF_PG_INIT_DISABLED, &m->flags)) { + spin_unlock_irqrestore(&m->lock, flags); - if (atomic_read(&m->pg_init_in_progress)) flush_workqueue(kmpath_handlerd); - multipath_wait_for_pg_init_completion(m); + multipath_wait_for_pg_init_completion(m); - clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags); - smp_mb__after_atomic(); + spin_lock_irqsave(&m->lock, flags); + clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags); + } + spin_unlock_irqrestore(&m->lock, flags); } - +skip: if (m->queue_mode == DM_TYPE_BIO_BASED) flush_work(&m->process_queued_bios); flush_work(&m->trigger_event); @@ -1593,7 +1569,8 @@ struct path_selector *ps = &pgpath->pg->ps; if (ps->type->end_io) - ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); + ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes, + clone->io_start_time_ns); } return r; @@ -1637,7 +1614,8 @@ struct path_selector *ps = &pgpath->pg->ps; if (ps->type->end_io) - ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes); + ps->type->end_io(ps, &pgpath->path, mpio->nr_bytes, + dm_start_time_ns_from_clone(clone)); } return r; @@ -1889,7 +1867,7 @@ int r; current_pgpath = READ_ONCE(m->current_pgpath); - if (!current_pgpath) + if (!current_pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) current_pgpath = choose_pgpath(m, 0); if (current_pgpath) { --- linux-oracle-5.4.0.orig/drivers/md/dm-path-selector.h +++ linux-oracle-5.4.0/drivers/md/dm-path-selector.h @@ -74,7 +74,7 @@ int (*start_io) (struct path_selector *ps, struct dm_path *path, size_t nr_bytes); int (*end_io) (struct path_selector *ps, struct dm_path *path, - size_t nr_bytes); + size_t nr_bytes, u64 start_time); }; /* Register a path selector */ --- linux-oracle-5.4.0.orig/drivers/md/dm-queue-length.c +++ linux-oracle-5.4.0/drivers/md/dm-queue-length.c @@ -227,7 +227,7 @@ } static int ql_end_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) + size_t nr_bytes, u64 start_time) { struct path_info *pi = path->pscontext; --- linux-oracle-5.4.0.orig/drivers/md/dm-raid.c +++ linux-oracle-5.4.0/drivers/md/dm-raid.c @@ -998,12 +998,13 @@ static int validate_raid_redundancy(struct raid_set *rs) { unsigned int i, rebuild_cnt = 0; - unsigned int rebuilds_per_group = 0, copies; + unsigned int rebuilds_per_group = 0, copies, raid_disks; unsigned int group_size, last_group_start; - for (i = 0; i < rs->md.raid_disks; i++) - if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || - !rs->dev[i].rdev.sb_page) + for (i = 0; i < rs->raid_disks; i++) + if (!test_bit(FirstUse, &rs->dev[i].rdev.flags) && + ((!test_bit(In_sync, &rs->dev[i].rdev.flags) || + !rs->dev[i].rdev.sb_page))) rebuild_cnt++; switch (rs->md.level) { @@ -1043,8 +1044,9 @@ * A A B B C * C D D E E */ + raid_disks = min(rs->raid_disks, rs->md.raid_disks); if (__is_raid10_near(rs->md.new_layout)) { - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1067,10 +1069,10 @@ * results in the need to treat the last (potentially larger) * set differently. */ - group_size = (rs->md.raid_disks / copies); - last_group_start = (rs->md.raid_disks / group_size) - 1; + group_size = (raid_disks / copies); + last_group_start = (raid_disks / group_size) - 1; last_group_start *= group_size; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies) && !(i > last_group_start)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1585,7 +1587,7 @@ { int i; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < rs->raid_disks; i++) { struct md_rdev *rdev = &rs->dev[i].rdev; if (!test_bit(Journal, &rdev->flags) && @@ -1892,6 +1894,14 @@ return rs->md.new_level != rs->md.level; } +/* True if layout is set to reshape. */ +static bool rs_is_layout_change(struct raid_set *rs, bool use_mddev) +{ + return (use_mddev ? rs->md.delta_disks : rs->delta_disks) || + rs->md.new_layout != rs->md.layout || + rs->md.new_chunk_sectors != rs->md.chunk_sectors; +} + /* True if @rs is requested to reshape by ctr */ static bool rs_reshape_requested(struct raid_set *rs) { @@ -1904,9 +1914,7 @@ if (rs_is_raid0(rs)) return false; - change = mddev->new_layout != mddev->layout || - mddev->new_chunk_sectors != mddev->chunk_sectors || - rs->delta_disks; + change = rs_is_layout_change(rs, false); /* Historical case to support raid1 reshape without delta disks */ if (rs_is_raid1(rs)) { @@ -2843,7 +2851,7 @@ } /* - * + * Reshape: * - change raid layout * - change chunk size * - add disks @@ -2953,6 +2961,20 @@ } /* + * If the md resync thread has updated superblock with max reshape position + * at the end of a reshape but not (yet) reset the layout configuration + * changes -> reset the latter. + */ +static void rs_reset_inconclusive_reshape(struct raid_set *rs) +{ + if (!rs_is_reshaping(rs) && rs_is_layout_change(rs, true)) { + rs_set_cur(rs); + rs->md.delta_disks = 0; + rs->md.reshape_backwards = 0; + } +} + +/* * Enable/disable discard support on RAID set depending on * RAID level and discard properties of underlying RAID members. */ @@ -3216,11 +3238,14 @@ if (r) goto bad; + /* Catch any inconclusive reshape superblock content. */ + rs_reset_inconclusive_reshape(rs); + /* Start raid set read-only and assumed clean to change in raid_resume() */ rs->md.ro = 1; rs->md.in_sync = 1; - /* Keep array frozen */ + /* Keep array frozen until resume. */ set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery); /* Has to be held on running the array */ @@ -3234,7 +3259,6 @@ } r = md_start(&rs->md); - if (r) { ti->error = "Failed to start raid array"; mddev_unlock(&rs->md); @@ -3260,15 +3284,19 @@ /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456(rs)) { r = rs_set_raid456_stripe_cache(rs); - if (r) + if (r) { + mddev_unlock(&rs->md); goto bad_stripe_cache; + } } /* Now do an early reshape check */ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { r = rs_check_reshape(rs); - if (r) + if (r) { + mddev_unlock(&rs->md); goto bad_check_reshape; + } /* Restore new, ctr requested layout to perform check */ rs_config_restore(rs, &rs_layout); @@ -3277,6 +3305,7 @@ r = rs->md.pers->check_reshape(&rs->md); if (r) { ti->error = "Reshape check failed"; + mddev_unlock(&rs->md); goto bad_check_reshape; } } @@ -3314,14 +3343,14 @@ struct mddev *mddev = &rs->md; /* - * If we're reshaping to add disk(s)), ti->len and + * If we're reshaping to add disk(s), ti->len and * mddev->array_sectors will differ during the process * (ti->len > mddev->array_sectors), so we have to requeue * bios with addresses > mddev->array_sectors here or * there will occur accesses past EOD of the component * data images thus erroring the raid set. */ - if (unlikely(bio_end_sector(bio) > mddev->array_sectors)) + if (unlikely(bio_has_data(bio) && bio_end_sector(bio) > mddev->array_sectors)) return DM_MAPIO_REQUEUE; md_handle_request(mddev, bio); @@ -3504,7 +3533,7 @@ { struct raid_set *rs = ti->private; struct mddev *mddev = &rs->md; - struct r5conf *conf = mddev->private; + struct r5conf *conf = rs_is_raid456(rs) ? mddev->private : NULL; int i, max_nr_stripes = conf ? conf->max_nr_stripes : 0; unsigned long recovery; unsigned int raid_param_cnt = 1; /* at least 1 for chunksize */ @@ -3724,13 +3753,13 @@ unsigned int i; int r = 0; - for (i = 0; !r && i < rs->md.raid_disks; i++) - if (rs->dev[i].data_dev) - r = fn(ti, - rs->dev[i].data_dev, - 0, /* No offset on data devs */ - rs->md.dev_sectors, - data); + for (i = 0; !r && i < rs->raid_disks; i++) { + if (rs->dev[i].data_dev) { + r = fn(ti, rs->dev[i].data_dev, + 0, /* No offset on data devs */ + rs->md.dev_sectors, data); + } + } return r; } @@ -3742,15 +3771,6 @@ blk_limits_io_min(limits, chunk_size_bytes); blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs)); - - /* - * RAID1 and RAID10 personalities require bio splitting, - * RAID0/4/5/6 don't and process large discard bios properly. - */ - if (rs_is_raid1(rs) || rs_is_raid10(rs)) { - limits->discard_granularity = chunk_size_bytes; - limits->max_discard_sectors = rs->md.chunk_sectors; - } } static void raid_postsuspend(struct dm_target *ti) @@ -3784,7 +3804,7 @@ memset(cleared_failed_devices, 0, sizeof(cleared_failed_devices)); - for (i = 0; i < mddev->raid_disks; i++) { + for (i = 0; i < rs->raid_disks; i++) { r = &rs->dev[i].rdev; /* HM FIXME: enhance journal device recovery processing */ if (test_bit(Journal, &r->flags)) @@ -3998,7 +4018,9 @@ * Take this opportunity to check whether any failed * devices are reachable again. */ + mddev_lock_nointr(mddev); attempt_restore_of_faulty_devices(rs); + mddev_unlock(mddev); } if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) { --- linux-oracle-5.4.0.orig/drivers/md/dm-rq.c +++ linux-oracle-5.4.0/drivers/md/dm-rq.c @@ -70,9 +70,6 @@ void dm_stop_queue(struct request_queue *q) { - if (blk_mq_queue_stopped(q)) - return; - blk_mq_quiesce_queue(q); } @@ -146,10 +143,6 @@ */ static void rq_completed(struct mapped_device *md) { - /* nudge anyone waiting on suspend queue */ - if (unlikely(wq_has_sleeper(&md->wait))) - wake_up(&md->wait); - /* * dm_put() must be at the end of this function. See the comment above */ @@ -288,7 +281,8 @@ struct dm_rq_target_io *tio = tio_from_request(rq); tio->error = error; - blk_mq_complete_request(rq); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); } /* @@ -575,6 +569,7 @@ blk_mq_free_tag_set(md->tag_set); out_kfree_tag_set: kfree(md->tag_set); + md->tag_set = NULL; return err; } @@ -584,6 +579,7 @@ if (md->tag_set) { blk_mq_free_tag_set(md->tag_set); kfree(md->tag_set); + md->tag_set = NULL; } } --- linux-oracle-5.4.0.orig/drivers/md/dm-service-time.c +++ linux-oracle-5.4.0/drivers/md/dm-service-time.c @@ -309,7 +309,7 @@ } static int st_end_io(struct path_selector *ps, struct dm_path *path, - size_t nr_bytes) + size_t nr_bytes, u64 start_time) { struct path_info *pi = path->pscontext; --- linux-oracle-5.4.0.orig/drivers/md/dm-snap-persistent.c +++ linux-oracle-5.4.0/drivers/md/dm-snap-persistent.c @@ -17,7 +17,7 @@ #include #define DM_MSG_PREFIX "persistent snapshot" -#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32 /* 16KB */ +#define DM_CHUNK_SIZE_DEFAULT_SECTORS 32U /* 16KB */ #define DM_PREFETCH_CHUNKS 12 @@ -613,7 +613,7 @@ chunk_t old, chunk_t new), void *callback_context) { - int r, uninitialized_var(new_snapshot); + int r, new_snapshot; struct pstore *ps = get_info(store); /* --- linux-oracle-5.4.0.orig/drivers/md/dm-snap.c +++ linux-oracle-5.4.0/drivers/md/dm-snap.c @@ -141,6 +141,11 @@ * for them to be committed. */ struct bio_list bios_queued_during_merge; + + /* + * Flush data after merge. + */ + struct bio flush_bio; }; /* @@ -680,8 +685,10 @@ for (i = 0; i < size; i++) { slot = et->table + i; - hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) + hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) { kmem_cache_free(mem, ex); + cond_resched(); + } } vfree(et->table); @@ -849,7 +856,7 @@ static uint32_t __minimum_chunk_size(struct origin *o) { struct dm_snapshot *snap; - unsigned chunk_size = 0; + unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); if (o) list_for_each_entry(snap, &o->snapshots, list) @@ -1121,6 +1128,17 @@ static void error_bios(struct bio *bio); +static int flush_data(struct dm_snapshot *s) +{ + struct bio *flush_bio = &s->flush_bio; + + bio_reset(flush_bio); + bio_set_dev(flush_bio, s->origin->bdev); + flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; + + return submit_bio_wait(flush_bio); +} + static void merge_callback(int read_err, unsigned long write_err, void *context) { struct dm_snapshot *s = context; @@ -1134,6 +1152,11 @@ goto shut; } + if (flush_data(s) < 0) { + DMERR("Flush after merge failed: shutting down merge"); + goto shut; + } + if (s->store->type->commit_merge(s->store, s->num_merging_chunks) < 0) { DMERR("Write error in exception store: shutting down merge"); @@ -1318,6 +1341,7 @@ s->first_merging_chunk = 0; s->num_merging_chunks = 0; bio_list_init(&s->bios_queued_during_merge); + bio_init(&s->flush_bio, NULL, 0); /* Allocate hash table for COW data */ if (init_hash_tables(s)) { @@ -1386,6 +1410,7 @@ if (!s->store->chunk_size) { ti->error = "Chunk size not set"; + r = -EINVAL; goto bad_read_metadata; } @@ -1504,6 +1529,8 @@ dm_exception_store_destroy(s->store); + bio_uninit(&s->flush_bio); + dm_put_device(ti, s->cow); dm_put_device(ti, s->origin); --- linux-oracle-5.4.0.orig/drivers/md/dm-stats.c +++ linux-oracle-5.4.0/drivers/md/dm-stats.c @@ -188,7 +188,7 @@ atomic_read(&shared->in_flight[WRITE]); } -void dm_stats_init(struct dm_stats *stats) +int dm_stats_init(struct dm_stats *stats) { int cpu; struct dm_stats_last_position *last; @@ -196,11 +196,16 @@ mutex_init(&stats->mutex); INIT_LIST_HEAD(&stats->list); stats->last = alloc_percpu(struct dm_stats_last_position); + if (!stats->last) + return -ENOMEM; + for_each_possible_cpu(cpu) { last = per_cpu_ptr(stats->last, cpu); last->last_sector = (sector_t)ULLONG_MAX; last->last_rw = UINT_MAX; } + + return 0; } void dm_stats_cleanup(struct dm_stats *stats) @@ -224,6 +229,7 @@ atomic_read(&shared->in_flight[READ]), atomic_read(&shared->in_flight[WRITE])); } + cond_resched(); } dm_stat_free(&s->rcu_head); } @@ -313,6 +319,7 @@ for (ni = 0; ni < n_entries; ni++) { atomic_set(&s->stat_shared[ni].in_flight[READ], 0); atomic_set(&s->stat_shared[ni].in_flight[WRITE], 0); + cond_resched(); } if (s->n_histogram_entries) { @@ -325,6 +332,7 @@ for (ni = 0; ni < n_entries; ni++) { s->stat_shared[ni].tmp.histogram = hi; hi += s->n_histogram_entries + 1; + cond_resched(); } } @@ -345,6 +353,7 @@ for (ni = 0; ni < n_entries; ni++) { p[ni].histogram = hi; hi += s->n_histogram_entries + 1; + cond_resched(); } } } @@ -474,6 +483,7 @@ } DMEMIT("\n"); } + cond_resched(); } mutex_unlock(&stats->mutex); @@ -750,6 +760,7 @@ local_irq_enable(); } } + cond_resched(); } } @@ -865,6 +876,8 @@ if (unlikely(sz + 1 >= maxlen)) goto buffer_overflow; + + cond_resched(); } if (clear) --- linux-oracle-5.4.0.orig/drivers/md/dm-stats.h +++ linux-oracle-5.4.0/drivers/md/dm-stats.h @@ -22,7 +22,7 @@ unsigned long long duration_ns; }; -void dm_stats_init(struct dm_stats *st); +int dm_stats_init(struct dm_stats *st); void dm_stats_cleanup(struct dm_stats *st); struct mapped_device; --- linux-oracle-5.4.0.orig/drivers/md/dm-table.c +++ linux-oracle-5.4.0/drivers/md/dm-table.c @@ -184,7 +184,12 @@ int dm_table_create(struct dm_table **result, fmode_t mode, unsigned num_targets, struct mapped_device *md) { - struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); + struct dm_table *t; + + if (num_targets > DM_MAX_TARGETS) + return -EOVERFLOW; + + t = kzalloc(sizeof(*t), GFP_KERNEL); if (!t) return -ENOMEM; @@ -199,7 +204,7 @@ if (!num_targets) { kfree(t); - return -ENOMEM; + return -EOVERFLOW; } if (alloc_targets(t, num_targets)) { @@ -428,14 +433,23 @@ { int r; dev_t dev; + unsigned int major, minor; + char dummy; struct dm_dev_internal *dd; struct dm_table *t = ti->table; BUG_ON(!t); - dev = dm_get_dev_t(path); - if (!dev) - return -ENODEV; + if (sscanf(path, "%u:%u%c", &major, &minor, &dummy) == 2) { + /* Extract the major/minor numbers */ + dev = MKDEV(major, minor); + if (MAJOR(dev) != major || MINOR(dev) != minor) + return -EOVERFLOW; + } else { + dev = dm_get_dev_t(path); + if (!dev) + return -ENODEV; + } dd = find_device(&t->devices, dev); if (!dd) { @@ -659,7 +673,7 @@ */ unsigned short remaining = 0; - struct dm_target *uninitialized_var(ti); + struct dm_target *ti; struct queue_limits ti_limits; unsigned i; @@ -863,8 +877,7 @@ static bool __table_type_bio_based(enum dm_queue_mode table_type) { return (table_type == DM_TYPE_BIO_BASED || - table_type == DM_TYPE_DAX_BIO_BASED || - table_type == DM_TYPE_NVME_BIO_BASED); + table_type == DM_TYPE_DAX_BIO_BASED); } static bool __table_type_request_based(enum dm_queue_mode table_type) @@ -879,20 +892,24 @@ EXPORT_SYMBOL_GPL(dm_table_set_type); /* validate the dax capability of the target device span */ -int device_supports_dax(struct dm_target *ti, struct dm_dev *dev, +int device_not_dax_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) { - int blocksize = *(int *) data; + int blocksize = *(int *) data, id; + bool rc; + + id = dax_read_lock(); + rc = !dax_supported(dev->dax_dev, dev->bdev, blocksize, start, len); + dax_read_unlock(id); - return generic_fsdax_supported(dev->dax_dev, dev->bdev, blocksize, - start, len); + return rc; } /* Check devices support synchronous DAX */ -static int device_dax_synchronous(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_not_dax_synchronous_capable(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { - return dev->dax_dev && dax_synchronous(dev->dax_dev); + return !dev->dax_dev || !dax_synchronous(dev->dax_dev); } bool dm_table_supports_dax(struct dm_table *t, @@ -909,30 +926,22 @@ return false; if (!ti->type->iterate_devices || - !ti->type->iterate_devices(ti, iterate_fn, blocksize)) + ti->type->iterate_devices(ti, iterate_fn, blocksize)) return false; } return true; } -static bool dm_table_does_not_support_partial_completion(struct dm_table *t); - -struct verify_rq_based_data { - unsigned sq_count; - unsigned mq_count; -}; - -static int device_is_rq_based(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_is_rq_stackable(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { - struct request_queue *q = bdev_get_queue(dev->bdev); - struct verify_rq_based_data *v = data; + struct block_device *bdev = dev->bdev; + struct request_queue *q = bdev_get_queue(bdev); - if (queue_is_mq(q)) - v->mq_count++; - else - v->sq_count++; + /* request-based cannot stack on partitions! */ + if (bdev != bdev->bd_contains) + return false; return queue_is_mq(q); } @@ -941,7 +950,6 @@ { unsigned i; unsigned bio_based = 0, request_based = 0, hybrid = 0; - struct verify_rq_based_data v = {.sq_count = 0, .mq_count = 0}; struct dm_target *tgt; struct list_head *devices = dm_table_get_devices(t); enum dm_queue_mode live_md_type = dm_get_md_type(t->md); @@ -954,7 +962,6 @@ goto verify_bio_based; } BUG_ON(t->type == DM_TYPE_DAX_BIO_BASED); - BUG_ON(t->type == DM_TYPE_NVME_BIO_BASED); goto verify_rq_based; } @@ -990,18 +997,9 @@ verify_bio_based: /* We must use this table as bio-based */ t->type = DM_TYPE_BIO_BASED; - if (dm_table_supports_dax(t, device_supports_dax, &page_size) || + if (dm_table_supports_dax(t, device_not_dax_capable, &page_size) || (list_empty(devices) && live_md_type == DM_TYPE_DAX_BIO_BASED)) { t->type = DM_TYPE_DAX_BIO_BASED; - } else { - /* Check if upgrading to NVMe bio-based is valid or required */ - tgt = dm_table_get_immutable_target(t); - if (tgt && !tgt->max_io_len && dm_table_does_not_support_partial_completion(t)) { - t->type = DM_TYPE_NVME_BIO_BASED; - goto verify_rq_based; /* must be stacked directly on NVMe (blk-mq) */ - } else if (list_empty(devices) && live_md_type == DM_TYPE_NVME_BIO_BASED) { - t->type = DM_TYPE_NVME_BIO_BASED; - } } return 0; } @@ -1018,8 +1016,7 @@ * (e.g. request completion process for partial completion.) */ if (t->num_targets > 1) { - DMERR("%s DM doesn't support multiple targets", - t->type == DM_TYPE_NVME_BIO_BASED ? "nvme bio-based" : "request-based"); + DMERR("request-based DM doesn't support multiple targets"); return -EINVAL; } @@ -1045,14 +1042,10 @@ /* Non-request-stackable devices can't be used for request-based dm */ if (!tgt->type->iterate_devices || - !tgt->type->iterate_devices(tgt, device_is_rq_based, &v)) { + !tgt->type->iterate_devices(tgt, device_is_rq_stackable, NULL)) { DMERR("table load rejected: including non-request-stackable devices"); return -EINVAL; } - if (v.sq_count > 0) { - DMERR("table load rejected: not all devices are blk-mq request-stackable"); - return -EINVAL; - } return 0; } @@ -1327,12 +1320,6 @@ void dm_table_event(struct dm_table *t) { - /* - * You can no longer call dm_table_event() from interrupt - * context, use a bottom half instead. - */ - BUG_ON(in_interrupt()); - mutex_lock(&_event_lock); if (t->event_fn) t->event_fn(t->event_context); @@ -1380,6 +1367,46 @@ return &t->targets[(KEYS_PER_NODE * n) + k]; } +/* + * type->iterate_devices() should be called when the sanity check needs to + * iterate and check all underlying data devices. iterate_devices() will + * iterate all underlying data devices until it encounters a non-zero return + * code, returned by whether the input iterate_devices_callout_fn, or + * iterate_devices() itself internally. + * + * For some target type (e.g. dm-stripe), one call of iterate_devices() may + * iterate multiple underlying devices internally, in which case a non-zero + * return code returned by iterate_devices_callout_fn will stop the iteration + * in advance. + * + * Cases requiring _any_ underlying device supporting some kind of attribute, + * should use the iteration structure like dm_table_any_dev_attr(), or call + * it directly. @func should handle semantics of positive examples, e.g. + * capable of something. + * + * Cases requiring _all_ underlying devices supporting some kind of attribute, + * should use the iteration structure like dm_table_supports_nowait() or + * dm_table_supports_discards(). Or introduce dm_table_all_devs_attr() that + * uses an @anti_func that handle semantics of counter examples, e.g. not + * capable of something. So: return !dm_table_any_dev_attr(t, anti_func, data); + */ +static bool dm_table_any_dev_attr(struct dm_table *t, + iterate_devices_callout_fn func, void *data) +{ + struct dm_target *ti; + unsigned int i; + + for (i = 0; i < dm_table_get_num_targets(t); i++) { + ti = dm_table_get_target(t, i); + + if (ti->type->iterate_devices && + ti->type->iterate_devices(ti, func, data)) + return true; + } + + return false; +} + static int count_device(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) { @@ -1416,13 +1443,13 @@ return true; } -static int device_is_zoned_model(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { struct request_queue *q = bdev_get_queue(dev->bdev); enum blk_zoned_model *zoned_model = data; - return q && blk_queue_zoned_model(q) == *zoned_model; + return !q || blk_queue_zoned_model(q) != *zoned_model; } static bool dm_table_supports_zoned_model(struct dm_table *t, @@ -1439,37 +1466,20 @@ return false; if (!ti->type->iterate_devices || - !ti->type->iterate_devices(ti, device_is_zoned_model, &zoned_model)) + ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model)) return false; } return true; } -static int device_matches_zone_sectors(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { struct request_queue *q = bdev_get_queue(dev->bdev); unsigned int *zone_sectors = data; - return q && blk_queue_zone_sectors(q) == *zone_sectors; -} - -static bool dm_table_matches_zone_sectors(struct dm_table *t, - unsigned int zone_sectors) -{ - struct dm_target *ti; - unsigned i; - - for (i = 0; i < dm_table_get_num_targets(t); i++) { - ti = dm_table_get_target(t, i); - - if (!ti->type->iterate_devices || - !ti->type->iterate_devices(ti, device_matches_zone_sectors, &zone_sectors)) - return false; - } - - return true; + return !q || blk_queue_zone_sectors(q) != *zone_sectors; } static int validate_hardware_zoned_model(struct dm_table *table, @@ -1489,7 +1499,7 @@ if (!zone_sectors || !is_power_of_2(zone_sectors)) return -EINVAL; - if (!dm_table_matches_zone_sectors(table, zone_sectors)) { + if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) { DMERR("%s: zone sectors is not consistent across all devices", dm_device_name(table->md)); return -EINVAL; @@ -1679,29 +1689,12 @@ return false; } -static int dm_table_supports_dax_write_cache(struct dm_table *t) -{ - struct dm_target *ti; - unsigned i; - - for (i = 0; i < dm_table_get_num_targets(t); i++) { - ti = dm_table_get_target(t, i); - - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, - device_dax_write_cache_enabled, NULL)) - return true; - } - - return false; -} - -static int device_is_nonrot(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) +static int device_is_rotational(struct dm_target *ti, struct dm_dev *dev, + sector_t start, sector_t len, void *data) { struct request_queue *q = bdev_get_queue(dev->bdev); - return q && blk_queue_nonrot(q); + return q && !blk_queue_nonrot(q); } static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev, @@ -1712,37 +1705,6 @@ return q && !blk_queue_add_random(q); } -static bool dm_table_all_devices_attribute(struct dm_table *t, - iterate_devices_callout_fn func) -{ - struct dm_target *ti; - unsigned i; - - for (i = 0; i < dm_table_get_num_targets(t); i++) { - ti = dm_table_get_target(t, i); - - if (!ti->type->iterate_devices || - !ti->type->iterate_devices(ti, func, NULL)) - return false; - } - - return true; -} - -static int device_no_partial_completion(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) -{ - char b[BDEVNAME_SIZE]; - - /* For now, NVMe devices are the only devices of this class */ - return (strncmp(bdevname(dev->bdev, b), "nvme", 4) == 0); -} - -static bool dm_table_does_not_support_partial_completion(struct dm_table *t) -{ - return dm_table_all_devices_attribute(t, device_no_partial_completion); -} - static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) { @@ -1867,27 +1829,6 @@ return q && bdi_cap_stable_pages_required(q->backing_dev_info); } -/* - * If any underlying device requires stable pages, a table must require - * them as well. Only targets that support iterate_devices are considered: - * don't want error, zero, etc to require stable pages. - */ -static bool dm_table_requires_stable_pages(struct dm_table *t) -{ - struct dm_target *ti; - unsigned i; - - for (i = 0; i < dm_table_get_num_targets(t); i++) { - ti = dm_table_get_target(t, i); - - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, device_requires_stable_pages, NULL)) - return true; - } - - return false; -} - void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, struct queue_limits *limits) { @@ -1920,22 +1861,22 @@ } blk_queue_write_cache(q, wc, fua); - if (dm_table_supports_dax(t, device_supports_dax, &page_size)) { + if (dm_table_supports_dax(t, device_not_dax_capable, &page_size)) { blk_queue_flag_set(QUEUE_FLAG_DAX, q); - if (dm_table_supports_dax(t, device_dax_synchronous, NULL)) + if (dm_table_supports_dax(t, device_not_dax_synchronous_capable, NULL)) set_dax_synchronous(t->md->dax_dev); } else blk_queue_flag_clear(QUEUE_FLAG_DAX, q); - if (dm_table_supports_dax_write_cache(t)) + if (dm_table_any_dev_attr(t, device_dax_write_cache_enabled, NULL)) dax_write_cache(t->md->dax_dev, true); /* Ensure that all underlying devices are non-rotational. */ - if (dm_table_all_devices_attribute(t, device_is_nonrot)) - blk_queue_flag_set(QUEUE_FLAG_NONROT, q); - else + if (dm_table_any_dev_attr(t, device_is_rotational, NULL)) blk_queue_flag_clear(QUEUE_FLAG_NONROT, q); + else + blk_queue_flag_set(QUEUE_FLAG_NONROT, q); if (!dm_table_supports_write_same(t)) q->limits.max_write_same_sectors = 0; @@ -1947,8 +1888,11 @@ /* * Some devices don't use blk_integrity but still want stable pages * because they do their own checksumming. + * If any underlying device requires stable pages, a table must require + * them as well. Only targets that support iterate_devices are considered: + * don't want error, zero, etc to require stable pages. */ - if (dm_table_requires_stable_pages(t)) + if (dm_table_any_dev_attr(t, device_requires_stable_pages, NULL)) q->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES; else q->backing_dev_info->capabilities &= ~BDI_CAP_STABLE_WRITES; @@ -1959,7 +1903,8 @@ * Clear QUEUE_FLAG_ADD_RANDOM if any underlying device does not * have it set. */ - if (blk_queue_add_random(q) && dm_table_all_devices_attribute(t, device_is_not_random)) + if (blk_queue_add_random(q) && + dm_table_any_dev_attr(t, device_is_not_random, NULL)) blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q); /* --- linux-oracle-5.4.0.orig/drivers/md/dm-thin-metadata.c +++ linux-oracle-5.4.0/drivers/md/dm-thin-metadata.c @@ -189,6 +189,15 @@ sector_t data_block_size; /* + * Pre-commit callback. + * + * This allows the thin provisioning target to run a callback before + * the metadata are committed. + */ + dm_pool_pre_commit_fn pre_commit_fn; + void *pre_commit_context; + + /* * We reserve a section of the metadata for commit overhead. * All reported space does *not* include this. */ @@ -378,16 +387,15 @@ * Variant that is used for in-core only changes or code that * shouldn't put the pool in service on its own (e.g. commit). */ -static inline void __pmd_write_lock(struct dm_pool_metadata *pmd) +static inline void pmd_write_lock_in_core(struct dm_pool_metadata *pmd) __acquires(pmd->root_lock) { down_write(&pmd->root_lock); } -#define pmd_write_lock_in_core(pmd) __pmd_write_lock((pmd)) static inline void pmd_write_lock(struct dm_pool_metadata *pmd) { - __pmd_write_lock(pmd); + pmd_write_lock_in_core(pmd); if (unlikely(!pmd->in_service)) pmd->in_service = true; } @@ -693,6 +701,15 @@ goto bad_cleanup_data_sm; } + /* + * For pool metadata opening process, root setting is redundant + * because it will be set again in __begin_transaction(). But dm + * pool aborting process really needs to get last transaction's + * root to avoid accessing broken btree. + */ + pmd->root = le64_to_cpu(disk_super->data_mapping_root); + pmd->details_root = le64_to_cpu(disk_super->device_details_root); + __setup_btree_details(pmd); dm_bm_unlock(sblock); @@ -731,23 +748,29 @@ THIN_MAX_CONCURRENT_LOCKS); if (IS_ERR(pmd->bm)) { DMERR("could not create block manager"); - return PTR_ERR(pmd->bm); + r = PTR_ERR(pmd->bm); + pmd->bm = NULL; + return r; } r = __open_or_format_metadata(pmd, format_device); - if (r) + if (r) { dm_block_manager_destroy(pmd->bm); + pmd->bm = NULL; + } return r; } -static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd) +static void __destroy_persistent_data_objects(struct dm_pool_metadata *pmd, + bool destroy_bm) { dm_sm_destroy(pmd->data_sm); dm_sm_destroy(pmd->metadata_sm); dm_tm_destroy(pmd->nb_tm); dm_tm_destroy(pmd->tm); - dm_block_manager_destroy(pmd->bm); + if (destroy_bm) + dm_block_manager_destroy(pmd->bm); } static int __begin_transaction(struct dm_pool_metadata *pmd) @@ -822,10 +845,19 @@ * We need to know if the thin_disk_superblock exceeds a 512-byte sector. */ BUILD_BUG_ON(sizeof(struct thin_disk_superblock) > 512); + BUG_ON(!rwsem_is_locked(&pmd->root_lock)); if (unlikely(!pmd->in_service)) return 0; + if (pmd->pre_commit_fn) { + r = pmd->pre_commit_fn(pmd->pre_commit_context); + if (r < 0) { + DMERR("pre-commit callback failed"); + return r; + } + } + r = __write_changed_details(pmd); if (r < 0) return r; @@ -892,6 +924,8 @@ pmd->in_service = false; pmd->bdev = bdev; pmd->data_block_size = data_block_size; + pmd->pre_commit_fn = NULL; + pmd->pre_commit_context = NULL; r = __create_persistent_data_objects(pmd, format_device); if (r) { @@ -934,14 +968,16 @@ return -EBUSY; } - if (!dm_bm_is_read_only(pmd->bm) && !pmd->fail_io) { + pmd_write_lock_in_core(pmd); + if (!pmd->fail_io && !dm_bm_is_read_only(pmd->bm)) { r = __commit_transaction(pmd); if (r < 0) DMWARN("%s: __commit_transaction() failed, error = %d", __func__, r); } + pmd_write_unlock(pmd); if (!pmd->fail_io) - __destroy_persistent_data_objects(pmd); + __destroy_persistent_data_objects(pmd, true); kfree(pmd); return 0; @@ -1822,7 +1858,7 @@ * Care is taken to not have commit be what * triggers putting the thin-pool in-service. */ - __pmd_write_lock(pmd); + pmd_write_lock_in_core(pmd); if (pmd->fail_io) goto out; @@ -1850,19 +1886,52 @@ int dm_pool_abort_metadata(struct dm_pool_metadata *pmd) { int r = -EINVAL; + struct dm_block_manager *old_bm = NULL, *new_bm = NULL; + + /* fail_io is double-checked with pmd->root_lock held below */ + if (unlikely(pmd->fail_io)) + return r; + + /* + * Replacement block manager (new_bm) is created and old_bm destroyed outside of + * pmd root_lock to avoid ABBA deadlock that would result (due to life-cycle of + * shrinker associated with the block manager's bufio client vs pmd root_lock). + * - must take shrinker_rwsem without holding pmd->root_lock + */ + new_bm = dm_block_manager_create(pmd->bdev, THIN_METADATA_BLOCK_SIZE << SECTOR_SHIFT, + THIN_MAX_CONCURRENT_LOCKS); pmd_write_lock(pmd); - if (pmd->fail_io) + if (pmd->fail_io) { + pmd_write_unlock(pmd); goto out; + } __set_abort_with_changes_flags(pmd); - __destroy_persistent_data_objects(pmd); - r = __create_persistent_data_objects(pmd, false); + __destroy_persistent_data_objects(pmd, false); + old_bm = pmd->bm; + if (IS_ERR(new_bm)) { + DMERR("could not create block manager during abort"); + pmd->bm = NULL; + r = PTR_ERR(new_bm); + goto out_unlock; + } + + pmd->bm = new_bm; + r = __open_or_format_metadata(pmd, false); + if (r) { + pmd->bm = NULL; + goto out_unlock; + } + new_bm = NULL; +out_unlock: if (r) pmd->fail_io = true; - -out: pmd_write_unlock(pmd); + dm_block_manager_destroy(old_bm); +out: + if (new_bm && !IS_ERR(new_bm)) + dm_block_manager_destroy(new_bm); return r; } @@ -2035,15 +2104,28 @@ dm_sm_threshold_fn fn, void *context) { - int r; + int r = -EINVAL; pmd_write_lock_in_core(pmd); - r = dm_sm_register_threshold_callback(pmd->metadata_sm, threshold, fn, context); + if (!pmd->fail_io) { + r = dm_sm_register_threshold_callback(pmd->metadata_sm, + threshold, fn, context); + } pmd_write_unlock(pmd); return r; } +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context) +{ + pmd_write_lock_in_core(pmd); + pmd->pre_commit_fn = fn; + pmd->pre_commit_context = context; + pmd_write_unlock(pmd); +} + int dm_pool_metadata_set_needs_check(struct dm_pool_metadata *pmd) { int r = -EINVAL; --- linux-oracle-5.4.0.orig/drivers/md/dm-thin-metadata.h +++ linux-oracle-5.4.0/drivers/md/dm-thin-metadata.h @@ -230,6 +230,13 @@ */ void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd); +/* Pre-commit callback */ +typedef int (*dm_pool_pre_commit_fn)(void *context); + +void dm_pool_register_pre_commit_callback(struct dm_pool_metadata *pmd, + dm_pool_pre_commit_fn fn, + void *context); + /*----------------------------------------------------------------*/ #endif --- linux-oracle-5.4.0.orig/drivers/md/dm-thin.c +++ linux-oracle-5.4.0/drivers/md/dm-thin.c @@ -231,6 +231,7 @@ struct dm_target *ti; /* Only set if a pool target is bound */ struct mapped_device *pool_md; + struct block_device *data_dev; struct block_device *md_dev; struct dm_pool_metadata *pmd; @@ -328,6 +329,7 @@ dm_block_t low_water_blocks; struct pool_features requested_pf; /* Features requested during table load */ struct pool_features adjusted_pf; /* Features used after adjusting for constituent devices */ + struct bio flush_bio; }; /* @@ -2222,6 +2224,7 @@ throttle_work_update(&pool->throttle); dm_pool_issue_prefetches(pool->pmd); } + cond_resched(); } blk_finish_plug(&plug); } @@ -2305,6 +2308,7 @@ else pool->process_cell(tc, cell); } + cond_resched(); } while (!list_empty(&cells)); } @@ -2321,10 +2325,9 @@ struct thin_c *tc = NULL; rcu_read_lock(); - if (!list_empty(&pool->active_thins)) { - tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); + tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list); + if (tc) thin_get(tc); - } rcu_read_unlock(); return tc; @@ -2392,8 +2395,16 @@ while ((bio = bio_list_pop(&bio_completions))) bio_endio(bio); - while ((bio = bio_list_pop(&bios))) - generic_make_request(bio); + while ((bio = bio_list_pop(&bios))) { + /* + * The data device was flushed as part of metadata commit, + * so complete redundant flushes immediately. + */ + if (bio->bi_opf & REQ_PREFLUSH) + bio_endio(bio); + else + generic_make_request(bio); + } } static void do_worker(struct work_struct *ws) @@ -2465,6 +2476,7 @@ init_completion(&pw->complete); queue_work(pool->wq, &pw->worker); wait_for_completion(&pw->complete); + destroy_work_on_stack(&pw->worker); } /*----------------------------------------------------------------*/ @@ -2921,6 +2933,8 @@ dm_bio_prison_destroy(pool->prison); dm_kcopyd_client_destroy(pool->copier); + cancel_delayed_work_sync(&pool->waker); + cancel_delayed_work_sync(&pool->no_space_timeout); if (pool->wq) destroy_workqueue(pool->wq); @@ -2936,6 +2950,7 @@ static struct pool *pool_create(struct mapped_device *pool_md, struct block_device *metadata_dev, + struct block_device *data_dev, unsigned long block_size, int read_only, char **error) { @@ -3043,6 +3058,7 @@ pool->last_commit_jiffies = jiffies; pool->pool_md = pool_md; pool->md_dev = metadata_dev; + pool->data_dev = data_dev; __pool_table_insert(pool); return pool; @@ -3084,6 +3100,7 @@ static struct pool *__pool_find(struct mapped_device *pool_md, struct block_device *metadata_dev, + struct block_device *data_dev, unsigned long block_size, int read_only, char **error, int *created) { @@ -3094,19 +3111,23 @@ *error = "metadata device already in use by a pool"; return ERR_PTR(-EBUSY); } + if (pool->data_dev != data_dev) { + *error = "data device already in use by a pool"; + return ERR_PTR(-EBUSY); + } __pool_inc(pool); } else { pool = __pool_table_lookup(pool_md); if (pool) { - if (pool->md_dev != metadata_dev) { + if (pool->md_dev != metadata_dev || pool->data_dev != data_dev) { *error = "different pool cannot replace a pool"; return ERR_PTR(-EINVAL); } __pool_inc(pool); } else { - pool = pool_create(pool_md, metadata_dev, block_size, read_only, error); + pool = pool_create(pool_md, metadata_dev, data_dev, block_size, read_only, error); *created = 1; } } @@ -3127,6 +3148,7 @@ __pool_dec(pt->pool); dm_put_device(ti, pt->metadata_dev); dm_put_device(ti, pt->data_dev); + bio_uninit(&pt->flush_bio); kfree(pt); mutex_unlock(&dm_thin_pool_table.mutex); @@ -3192,6 +3214,29 @@ dm_table_event(pool->ti->table); } +/* + * We need to flush the data device **before** committing the metadata. + * + * This ensures that the data blocks of any newly inserted mappings are + * properly written to non-volatile storage and won't be lost in case of a + * crash. + * + * Failure to do so can result in data corruption in the case of internal or + * external snapshots and in the case of newly provisioned blocks, when block + * zeroing is enabled. + */ +static int metadata_pre_commit_callback(void *context) +{ + struct pool_c *pt = context; + struct bio *flush_bio = &pt->flush_bio; + + bio_reset(flush_bio); + bio_set_dev(flush_bio, pt->data_dev->bdev); + flush_bio->bi_opf = REQ_OP_WRITE | REQ_PREFLUSH; + + return submit_bio_wait(flush_bio); +} + static sector_t get_dev_size(struct block_device *bdev) { return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT; @@ -3335,7 +3380,7 @@ goto out; } - pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev, + pool = __pool_find(dm_table_get_md(ti->table), metadata_dev->bdev, data_dev->bdev, block_size, pf.mode == PM_READ_ONLY, &ti->error, &pool_created); if (IS_ERR(pool)) { r = PTR_ERR(pool); @@ -3360,7 +3405,9 @@ pt->data_dev = data_dev; pt->low_water_blocks = low_water_blocks; pt->adjusted_pf = pt->requested_pf = pf; + bio_init(&pt->flush_bio, NULL, 0); ti->num_flush_bios = 1; + ti->limit_swap_bios = true; /* * Only need to enable discards if the pool should pass @@ -3383,8 +3430,10 @@ calc_metadata_threshold(pt), metadata_low_callback, pool); - if (r) + if (r) { + ti->error = "Error registering metadata threshold"; goto out_flags_changed; + } pt->callbacks.congested_fn = pool_is_congested; dm_table_add_target_callbacks(ti->table, &pt->callbacks); @@ -3547,20 +3596,31 @@ */ r = bind_control_target(pool, ti); if (r) - return r; + goto out; + + dm_pool_register_pre_commit_callback(pool->pmd, + metadata_pre_commit_callback, pt); r = maybe_resize_data_dev(ti, &need_commit1); if (r) - return r; + goto out; r = maybe_resize_metadata_dev(ti, &need_commit2); if (r) - return r; + goto out; if (need_commit1 || need_commit2) (void) commit(pool); +out: + /* + * When a thin-pool is PM_FAIL, it cannot be rebuilt if + * bio is in deferred list. Therefore need to return 0 + * to allow pool_resume() to flush IO. + */ + if (r && get_pool_mode(pool) == PM_FAIL) + r = 0; - return 0; + return r; } static void pool_suspend_active_thins(struct pool *pool) @@ -4077,7 +4137,7 @@ .name = "thin-pool", .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | DM_TARGET_IMMUTABLE, - .version = {1, 21, 0}, + .version = {1, 22, 0}, .module = THIS_MODULE, .ctr = pool_ctr, .dtr = pool_dtr, @@ -4233,6 +4293,7 @@ goto bad; ti->num_flush_bios = 1; + ti->limit_swap_bios = true; ti->flush_supported = true; ti->per_io_data_size = sizeof(struct dm_thin_endio_hook); @@ -4456,7 +4517,7 @@ static struct target_type thin_target = { .name = "thin", - .version = {1, 21, 0}, + .version = {1, 22, 0}, .module = THIS_MODULE, .ctr = thin_ctr, .dtr = thin_dtr, --- linux-oracle-5.4.0.orig/drivers/md/dm-unstripe.c +++ linux-oracle-5.4.0/drivers/md/dm-unstripe.c @@ -84,8 +84,8 @@ } uc->physical_start = start; - uc->unstripe_offset = uc->unstripe * uc->chunk_size; - uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size; + uc->unstripe_offset = (sector_t)uc->unstripe * uc->chunk_size; + uc->unstripe_width = (sector_t)(uc->stripes - 1) * uc->chunk_size; uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0; tmp_len = ti->len; --- linux-oracle-5.4.0.orig/drivers/md/dm-verity-fec.c +++ linux-oracle-5.4.0/drivers/md/dm-verity-fec.c @@ -24,7 +24,8 @@ */ static inline struct dm_verity_fec_io *fec_io(struct dm_verity_io *io) { - return (struct dm_verity_fec_io *) verity_io_digest_end(io->v, io); + return (struct dm_verity_fec_io *) + ((char *)io + io->v->ti->per_io_data_size - sizeof(struct dm_verity_fec_io)); } /* @@ -61,19 +62,18 @@ static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, unsigned *offset, struct dm_buffer **buf) { - u64 position, block; + u64 position, block, rem; u8 *res; position = (index + rsb) * v->fec->roots; - block = position >> v->data_dev_block_bits; - *offset = (unsigned)(position - (block << v->data_dev_block_bits)); + block = div64_u64_rem(position, v->fec->io_size, &rem); + *offset = (unsigned)rem; - res = dm_bufio_read(v->fec->bufio, v->fec->start + block, buf); + res = dm_bufio_read(v->fec->bufio, block, buf); if (IS_ERR(res)) { DMERR("%s: FEC %llu: parity read failed (block %llu): %ld", v->data_dev->name, (unsigned long long)rsb, - (unsigned long long)(v->fec->start + block), - PTR_ERR(res)); + (unsigned long long)block, PTR_ERR(res)); *buf = NULL; } @@ -155,7 +155,7 @@ /* read the next block when we run out of parity bytes */ offset += v->fec->roots; - if (offset >= 1 << v->data_dev_block_bits) { + if (offset >= v->fec->io_size) { dm_bufio_release(buf); par = fec_read_parity(v, rsb, block_offset, &offset, &buf); @@ -435,7 +435,7 @@ fio->level++; if (type == DM_VERITY_BLOCK_TYPE_METADATA) - block += v->data_blocks; + block = block - v->hash_start + v->data_blocks; /* * For RS(M, N), the continuous FEC data is divided into blocks of N @@ -551,6 +551,7 @@ mempool_exit(&f->rs_pool); mempool_exit(&f->prealloc_pool); mempool_exit(&f->extra_pool); + mempool_exit(&f->output_pool); kmem_cache_destroy(f->cache); if (f->data_bufio) @@ -673,7 +674,7 @@ { struct dm_verity_fec *f = v->fec; struct dm_target *ti = v->ti; - u64 hash_blocks; + u64 hash_blocks, fec_blocks; int ret; if (!verity_fec_is_enabled(v)) { @@ -742,16 +743,23 @@ return -E2BIG; } + if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1)) + f->io_size = 1 << v->data_dev_block_bits; + else + f->io_size = v->fec->roots << SECTOR_SHIFT; + f->bufio = dm_bufio_client_create(f->dev->bdev, - 1 << v->data_dev_block_bits, + f->io_size, 1, 0, NULL, NULL); if (IS_ERR(f->bufio)) { ti->error = "Cannot initialize FEC bufio client"; return PTR_ERR(f->bufio); } - if (dm_bufio_get_device_size(f->bufio) < - ((f->start + f->rounds * f->roots) >> v->data_dev_block_bits)) { + dm_bufio_set_sector_offset(f->bufio, f->start << (v->data_dev_block_bits - SECTOR_SHIFT)); + + fec_blocks = div64_u64(f->rounds * f->roots, v->fec->roots << SECTOR_SHIFT); + if (dm_bufio_get_device_size(f->bufio) < fec_blocks) { ti->error = "FEC device is too small"; return -E2BIG; } --- linux-oracle-5.4.0.orig/drivers/md/dm-verity-fec.h +++ linux-oracle-5.4.0/drivers/md/dm-verity-fec.h @@ -36,6 +36,7 @@ struct dm_dev *dev; /* parity data device */ struct dm_bufio_client *data_bufio; /* for data dev access */ struct dm_bufio_client *bufio; /* for parity data access */ + size_t io_size; /* IO size for roots */ sector_t start; /* parity data start in blocks */ sector_t blocks; /* number of blocks covered */ sector_t rounds; /* number of interleaving rounds */ --- linux-oracle-5.4.0.orig/drivers/md/dm-verity-target.c +++ linux-oracle-5.4.0/drivers/md/dm-verity-target.c @@ -33,7 +33,7 @@ #define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks" #define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once" -#define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC + \ +#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \ DM_VERITY_ROOT_HASH_VERIFICATION_OPTS) static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE; @@ -471,13 +471,14 @@ struct bvec_iter start; unsigned b; struct crypto_wait wait; + struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); for (b = 0; b < io->n_blocks; b++) { int r; sector_t cur_block = io->block + b; struct ahash_request *req = verity_io_hash_req(v, io); - if (v->validated_blocks && + if (v->validated_blocks && bio->bi_status == BLK_STS_OK && likely(test_bit(cur_block, v->validated_blocks))) { verity_bv_skip_block(v, io, &io->iter); continue; @@ -525,15 +526,32 @@ else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, cur_block, NULL, &start) == 0) continue; - else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, - cur_block)) - return -EIO; + else { + if (bio->bi_status) { + /* + * Error correction failed; Just return error + */ + return -EIO; + } + if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, + cur_block)) + return -EIO; + } } return 0; } /* + * Skip verity work in response to I/O error when system is shutting down. + */ +static inline bool verity_is_system_shutting_down(void) +{ + return system_state == SYSTEM_HALT || system_state == SYSTEM_POWER_OFF + || system_state == SYSTEM_RESTART; +} + +/* * End one "io" structure with a given error. */ static void verity_finish_io(struct dm_verity_io *io, blk_status_t status) @@ -560,7 +578,10 @@ { struct dm_verity_io *io = bio->bi_private; - if (bio->bi_status && !verity_fec_is_enabled(io->v)) { + if (bio->bi_status && + (!verity_fec_is_enabled(io->v) || + verity_is_system_shutting_down() || + (bio->bi_opf & REQ_RAHEAD))) { verity_finish_io(io, bio->bi_status); return; } @@ -1207,6 +1228,7 @@ static struct target_type verity_target = { .name = "verity", + .features = DM_TARGET_IMMUTABLE, .version = {1, 5, 0}, .module = THIS_MODULE, .ctr = verity_ctr, --- linux-oracle-5.4.0.orig/drivers/md/dm-verity-verify-sig.c +++ linux-oracle-5.4.0/drivers/md/dm-verity-verify-sig.c @@ -15,7 +15,7 @@ #define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s static bool require_signatures; -module_param(require_signatures, bool, false); +module_param(require_signatures, bool, 0444); MODULE_PARM_DESC(require_signatures, "Verify the roothash of dm-verity hash tree"); --- linux-oracle-5.4.0.orig/drivers/md/dm-verity.h +++ linux-oracle-5.4.0/drivers/md/dm-verity.h @@ -73,11 +73,11 @@ /* original value of bio->bi_end_io */ bio_end_io_t *orig_bi_end_io; + struct bvec_iter iter; + sector_t block; unsigned n_blocks; - struct bvec_iter iter; - struct work_struct work; /* @@ -110,12 +110,6 @@ return (u8 *)(io + 1) + v->ahash_reqsize + v->digest_size; } -static inline u8 *verity_io_digest_end(struct dm_verity *v, - struct dm_verity_io *io) -{ - return verity_io_want_digest(v, io) + v->digest_size; -} - extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, struct bvec_iter *iter, int (*process)(struct dm_verity *v, --- linux-oracle-5.4.0.orig/drivers/md/dm-writecache.c +++ linux-oracle-5.4.0/drivers/md/dm-writecache.c @@ -20,7 +20,7 @@ #define HIGH_WATERMARK 50 #define LOW_WATERMARK 45 -#define MAX_WRITEBACK_JOBS 0 +#define MAX_WRITEBACK_JOBS min(0x10000000 / PAGE_SIZE, totalram_pages() / 16) #define ENDIO_LATENCY 16 #define WRITEBACK_LATENCY 64 #define AUTOCOMMIT_BLOCKS_SSD 65536 @@ -142,6 +142,7 @@ size_t metadata_sectors; size_t n_blocks; uint64_t seq_count; + sector_t data_device_sectors; void *block_start; struct wc_entry *entries; unsigned block_size; @@ -153,6 +154,7 @@ bool overwrote_committed:1; bool memory_vmapped:1; + bool start_sector_set:1; bool high_wm_percent_set:1; bool low_wm_percent_set:1; bool max_writeback_jobs_set:1; @@ -161,6 +163,10 @@ bool writeback_fua_set:1; bool flush_on_suspend:1; + unsigned high_wm_percent_value; + unsigned low_wm_percent_value; + unsigned autocommit_time_value; + unsigned writeback_all; struct workqueue_struct *writeback_wq; struct work_struct writeback_work; @@ -224,6 +230,7 @@ pfn_t pfn; int id; struct page **pages; + sector_t offset; wc->memory_vmapped = false; @@ -242,9 +249,16 @@ goto err1; } + offset = get_start_sect(wc->ssd_dev->bdev); + if (offset & (PAGE_SIZE / 512 - 1)) { + r = -EINVAL; + goto err1; + } + offset >>= PAGE_SHIFT - 9; + id = dax_read_lock(); - da = dax_direct_access(wc->ssd_dev->dax_dev, 0, p, &wc->memory_map, &pfn); + da = dax_direct_access(wc->ssd_dev->dax_dev, offset, p, &wc->memory_map, &pfn); if (da < 0) { wc->memory_map = NULL; r = da; @@ -266,7 +280,7 @@ i = 0; do { long daa; - daa = dax_direct_access(wc->ssd_dev->dax_dev, i, p - i, + daa = dax_direct_access(wc->ssd_dev->dax_dev, offset + i, p - i, NULL, &pfn); if (daa <= 0) { r = daa ? daa : -EINVAL; @@ -279,6 +293,8 @@ while (daa-- && i < p) { pages[i++] = pfn_t_to_page(pfn); pfn.val++; + if (!(i & 15)) + cond_resched(); } } while (i < p); wc->memory_map = vmap(pages, p, VM_MAP, PAGE_KERNEL); @@ -306,7 +322,7 @@ #else static int persistent_memory_claim(struct dm_writecache *wc) { - BUG(); + return -EOPNOTSUPP; } #endif @@ -442,7 +458,13 @@ complete(&endio->c); } -static void ssd_commit_flushed(struct dm_writecache *wc) +static void writecache_wait_for_ios(struct dm_writecache *wc, int direction) +{ + wait_event(wc->bio_in_progress_wait[direction], + !atomic_read(&wc->bio_in_progress[direction])); +} + +static void ssd_commit_flushed(struct dm_writecache *wc, bool wait_for_ios) { struct dm_io_region region; struct dm_io_request req; @@ -488,17 +510,20 @@ writecache_notify_io(0, &endio); wait_for_completion_io(&endio.c); + if (wait_for_ios) + writecache_wait_for_ios(wc, WRITE); + writecache_disk_flush(wc, wc->ssd_dev); memset(wc->dirty_bitmap, 0, wc->dirty_bitmap_size); } -static void writecache_commit_flushed(struct dm_writecache *wc) +static void writecache_commit_flushed(struct dm_writecache *wc, bool wait_for_ios) { if (WC_MODE_PMEM(wc)) wmb(); else - ssd_commit_flushed(wc); + ssd_commit_flushed(wc, wait_for_ios); } static void writecache_disk_flush(struct dm_writecache *wc, struct dm_dev *dev) @@ -522,12 +547,6 @@ writecache_error(wc, r, "error flushing metadata: %d", r); } -static void writecache_wait_for_ios(struct dm_writecache *wc, int direction) -{ - wait_event(wc->bio_in_progress_wait[direction], - !atomic_read(&wc->bio_in_progress[direction])); -} - #define WFE_RETURN_FOLLOWING 1 #define WFE_LOWEST_SEQ 2 @@ -622,6 +641,12 @@ wc->freelist_size++; } +static inline void writecache_verify_watermark(struct dm_writecache *wc) +{ + if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) + queue_work(wc->writeback_wq, &wc->writeback_work); +} + static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc) { struct wc_entry *e; @@ -643,8 +668,8 @@ list_del(&e->lru); } wc->freelist_size--; - if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) - queue_work(wc->writeback_wq, &wc->writeback_work); + + writecache_verify_watermark(wc); return e; } @@ -724,15 +749,12 @@ e = e2; cond_resched(); } - writecache_commit_flushed(wc); - - if (!WC_MODE_PMEM(wc)) - writecache_wait_for_ios(wc, WRITE); + writecache_commit_flushed(wc, true); wc->seq_count++; pmem_assign(sb(wc)->seq_count, cpu_to_le64(wc->seq_count)); writecache_flush_region(wc, &sb(wc)->seq_count, sizeof sb(wc)->seq_count); - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); wc->overwrote_committed = false; @@ -756,7 +778,7 @@ } if (need_flush_after_free) - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); } static void writecache_flush_work(struct work_struct *work) @@ -799,6 +821,8 @@ writecache_wait_for_ios(wc, WRITE); discarded_something = true; } + if (!writecache_entry_is_committed(wc, e)) + wc->uncommitted_blocks--; writecache_free_entry(wc, e); } @@ -809,7 +833,7 @@ } if (discarded_something) - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); } static bool writecache_wait_for_writeback(struct dm_writecache *wc) @@ -838,7 +862,7 @@ } wc_unlock(wc); - flush_workqueue(wc->writeback_wq); + drain_workqueue(wc->writeback_wq); wc_lock(wc); if (flush_on_suspend) @@ -866,11 +890,30 @@ struct wc_entry *e = &wc->entries[b]; e->index = b; e->write_in_progress = false; + cond_resched(); } return 0; } +static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors) +{ + struct dm_io_region region; + struct dm_io_request req; + + region.bdev = wc->ssd_dev->bdev; + region.sector = wc->start_sector; + region.count = n_sectors; + req.bi_op = REQ_OP_READ; + req.bi_op_flags = REQ_SYNC; + req.mem.type = DM_IO_VMA; + req.mem.ptr.vma = (char *)wc->memory_map; + req.client = wc->dm_io; + req.notify.fn = NULL; + + return dm_io(&req, 1, ®ion, NULL); +} + static void writecache_resume(struct dm_target *ti) { struct dm_writecache *wc = ti->private; @@ -881,8 +924,20 @@ wc_lock(wc); - if (WC_MODE_PMEM(wc)) + wc->data_device_sectors = i_size_read(wc->dev->bdev->bd_inode) >> SECTOR_SHIFT; + + if (WC_MODE_PMEM(wc)) { persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size); + } else { + r = writecache_read_metadata(wc, wc->metadata_sectors); + if (r) { + size_t sb_entries_offset; + writecache_error(wc, r, "unable to read metadata: %d", r); + sb_entries_offset = offsetof(struct wc_memory_superblock, entries); + memset((char *)wc->memory_map + sb_entries_offset, -1, + (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset); + } + } wc->tree = RB_ROOT; INIT_LIST_HEAD(&wc->lru); @@ -920,6 +975,7 @@ e->original_sector = le64_to_cpu(wme.original_sector); e->seq_count = le64_to_cpu(wme.seq_count); } + cond_resched(); } #endif for (b = 0; b < wc->n_blocks; b++) { @@ -958,9 +1014,11 @@ if (need_flush) { writecache_flush_all_metadata(wc); - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); } + writecache_verify_watermark(wc); + wc_unlock(wc); } @@ -1218,7 +1276,8 @@ } } while (bio->bi_iter.bi_size); - if (unlikely(wc->uncommitted_blocks >= wc->autocommit_blocks)) + if (unlikely(bio->bi_opf & REQ_FUA || + wc->uncommitted_blocks >= wc->autocommit_blocks)) writecache_flush(wc); else writecache_schedule_autocommit(wc); @@ -1341,7 +1400,7 @@ wc->writeback_size--; n_walked++; if (unlikely(n_walked >= ENDIO_LATENCY)) { - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); wc_unlock(wc); wc_lock(wc); n_walked = 0; @@ -1422,7 +1481,7 @@ writecache_wait_for_ios(wc, READ); } - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); wc_unlock(wc); } @@ -1437,6 +1496,10 @@ void *address = memory_data(wc, e); persistent_memory_flush_cache(address, block_size); + + if (unlikely(bio_end_sector(&wb->bio) >= wc->data_device_sectors)) + return true; + return bio_add_page(&wb->bio, persistent_memory_page(address), block_size, persistent_memory_page_offset(address)) != 0; } @@ -1508,6 +1571,9 @@ if (writecache_has_error(wc)) { bio->bi_status = BLK_STS_IOERR; bio_endio(bio); + } else if (unlikely(!bio_sectors(bio))) { + bio->bi_status = BLK_STS_OK; + bio_endio(bio); } else { submit_bio(bio); } @@ -1551,6 +1617,14 @@ e = f; } + if (unlikely(to.sector + to.count > wc->data_device_sectors)) { + if (to.sector >= wc->data_device_sectors) { + writecache_copy_endio(0, 0, c); + continue; + } + from.count = to.count = wc->data_device_sectors - to.sector; + } + dm_kcopyd_copy(wc->dm_kcopyd, &from, 1, &to, 0, writecache_copy_endio, c); __writeback_throttle(wc, wbl); @@ -1761,14 +1835,16 @@ pmem_assign(sb(wc)->n_blocks, cpu_to_le64(wc->n_blocks)); pmem_assign(sb(wc)->seq_count, cpu_to_le64(0)); - for (b = 0; b < wc->n_blocks; b++) + for (b = 0; b < wc->n_blocks; b++) { write_original_sector_seq_count(wc, &wc->entries[b], -1, -1); + cond_resched(); + } writecache_flush_all_metadata(wc); - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); pmem_assign(sb(wc)->magic, cpu_to_le32(MEMORY_SUPERBLOCK_MAGIC)); writecache_flush_region(wc, &sb(wc)->magic, sizeof sb(wc)->magic); - writecache_commit_flushed(wc); + writecache_commit_flushed(wc, false); return 0; } @@ -1836,7 +1912,7 @@ struct wc_memory_superblock s; static struct dm_arg _args[] = { - {0, 10, "Invalid number of feature args"}, + {0, 16, "Invalid number of feature args"}, }; as.argc = argc; @@ -1971,6 +2047,12 @@ ti->error = "Invalid block size"; goto bad; } + if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) || + wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) { + r = -EINVAL; + ti->error = "Block size is smaller than device logical block size"; + goto bad; + } wc->block_size_bits = __ffs(wc->block_size); wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; @@ -1992,6 +2074,7 @@ if (sscanf(string, "%llu%c", &start_sector, &dummy) != 1) goto invalid_optional; wc->start_sector = start_sector; + wc->start_sector_set = true; if (wc->start_sector != start_sector || wc->start_sector >= wc->memory_map_size >> SECTOR_SHIFT) goto invalid_optional; @@ -2001,6 +2084,7 @@ goto invalid_optional; if (high_wm_percent < 0 || high_wm_percent > 100) goto invalid_optional; + wc->high_wm_percent_value = high_wm_percent; wc->high_wm_percent_set = true; } else if (!strcasecmp(string, "low_watermark") && opt_params >= 1) { string = dm_shift_arg(&as), opt_params--; @@ -2008,6 +2092,7 @@ goto invalid_optional; if (low_wm_percent < 0 || low_wm_percent > 100) goto invalid_optional; + wc->low_wm_percent_value = low_wm_percent; wc->low_wm_percent_set = true; } else if (!strcasecmp(string, "writeback_jobs") && opt_params >= 1) { string = dm_shift_arg(&as), opt_params--; @@ -2027,6 +2112,7 @@ if (autocommit_msecs > 3600000) goto invalid_optional; wc->autocommit_jiffies = msecs_to_jiffies(autocommit_msecs); + wc->autocommit_time_value = autocommit_msecs; wc->autocommit_time_set = true; } else if (!strcasecmp(string, "fua")) { if (WC_MODE_PMEM(wc)) { @@ -2053,14 +2139,18 @@ } if (WC_MODE_PMEM(wc)) { + if (!dax_synchronous(wc->ssd_dev->dax_dev)) { + r = -EOPNOTSUPP; + ti->error = "Asynchronous persistent memory not supported as pmem cache"; + goto bad; + } + r = persistent_memory_claim(wc); if (r) { ti->error = "Unable to map persistent memory for cache"; goto bad; } } else { - struct dm_io_region region; - struct dm_io_request req; size_t n_blocks, n_metadata_blocks; uint64_t n_bitmap_bits; @@ -2117,19 +2207,9 @@ goto bad; } - region.bdev = wc->ssd_dev->bdev; - region.sector = wc->start_sector; - region.count = wc->metadata_sectors; - req.bi_op = REQ_OP_READ; - req.bi_op_flags = REQ_SYNC; - req.mem.type = DM_IO_VMA; - req.mem.ptr.vma = (char *)wc->memory_map; - req.client = wc->dm_io; - req.notify.fn = NULL; - - r = dm_io(&req, 1, ®ion, NULL); + r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT); if (r) { - ti->error = "Unable to read metadata"; + ti->error = "Unable to read first block of metadata"; goto bad; } } @@ -2234,7 +2314,6 @@ struct dm_writecache *wc = ti->private; unsigned extra_args; unsigned sz = 0; - uint64_t x; switch (type) { case STATUSTYPE_INFO: @@ -2246,7 +2325,7 @@ DMEMIT("%c %s %s %u ", WC_MODE_PMEM(wc) ? 'p' : 's', wc->dev->name, wc->ssd_dev->name, wc->block_size); extra_args = 0; - if (wc->start_sector) + if (wc->start_sector_set) extra_args += 2; if (wc->high_wm_percent_set) extra_args += 2; @@ -2262,26 +2341,18 @@ extra_args++; DMEMIT("%u", extra_args); - if (wc->start_sector) + if (wc->start_sector_set) DMEMIT(" start_sector %llu", (unsigned long long)wc->start_sector); - if (wc->high_wm_percent_set) { - x = (uint64_t)wc->freelist_high_watermark * 100; - x += wc->n_blocks / 2; - do_div(x, (size_t)wc->n_blocks); - DMEMIT(" high_watermark %u", 100 - (unsigned)x); - } - if (wc->low_wm_percent_set) { - x = (uint64_t)wc->freelist_low_watermark * 100; - x += wc->n_blocks / 2; - do_div(x, (size_t)wc->n_blocks); - DMEMIT(" low_watermark %u", 100 - (unsigned)x); - } + if (wc->high_wm_percent_set) + DMEMIT(" high_watermark %u", wc->high_wm_percent_value); + if (wc->low_wm_percent_set) + DMEMIT(" low_watermark %u", wc->low_wm_percent_value); if (wc->max_writeback_jobs_set) DMEMIT(" writeback_jobs %u", wc->max_writeback_jobs); if (wc->autocommit_blocks_set) DMEMIT(" autocommit_blocks %u", wc->autocommit_blocks); if (wc->autocommit_time_set) - DMEMIT(" autocommit_time %u", jiffies_to_msecs(wc->autocommit_jiffies)); + DMEMIT(" autocommit_time %u", wc->autocommit_time_value); if (wc->writeback_fua_set) DMEMIT(" %sfua", wc->writeback_fua ? "" : "no"); break; --- linux-oracle-5.4.0.orig/drivers/md/dm-zoned-metadata.c +++ linux-oracle-5.4.0/drivers/md/dm-zoned-metadata.c @@ -134,6 +134,7 @@ sector_t zone_bitmap_size; unsigned int zone_nr_bitmap_blocks; + unsigned int zone_bits_per_mblk; unsigned int nr_bitmap_blocks; unsigned int nr_map_blocks; @@ -554,6 +555,7 @@ TASK_UNINTERRUPTIBLE); if (test_bit(DMZ_META_ERROR, &mblk->state)) { dmz_release_mblock(zmd, mblk); + dmz_check_bdev(zmd->dev); return ERR_PTR(-EIO); } @@ -625,6 +627,8 @@ ret = submit_bio_wait(bio); bio_put(bio); + if (ret) + dmz_check_bdev(zmd->dev); return ret; } @@ -691,6 +695,7 @@ TASK_UNINTERRUPTIBLE); if (test_bit(DMZ_META_ERROR, &mblk->state)) { clear_bit(DMZ_META_ERROR, &mblk->state); + dmz_check_bdev(zmd->dev); ret = -EIO; } nr_mblks_submitted--; @@ -768,7 +773,7 @@ /* If there are no dirty metadata blocks, just flush the device cache */ if (list_empty(&write_list)) { ret = blkdev_issue_flush(zmd->dev->bdev, GFP_NOIO, NULL); - goto out; + goto err; } /* @@ -778,7 +783,7 @@ */ ret = dmz_log_dirty_mblocks(zmd, &write_list); if (ret) - goto out; + goto err; /* * The log is on disk. It is now safe to update in place @@ -786,11 +791,11 @@ */ ret = dmz_write_dirty_mblocks(zmd, &write_list, zmd->mblk_primary); if (ret) - goto out; + goto err; ret = dmz_write_sb(zmd, zmd->mblk_primary); if (ret) - goto out; + goto err; while (!list_empty(&write_list)) { mblk = list_first_entry(&write_list, struct dmz_mblock, link); @@ -805,16 +810,20 @@ zmd->sb_gen++; out: - if (ret && !list_empty(&write_list)) { - spin_lock(&zmd->mblk_lock); - list_splice(&write_list, &zmd->mblk_dirty_list); - spin_unlock(&zmd->mblk_lock); - } - dmz_unlock_flush(zmd); up_write(&zmd->mblk_sem); return ret; + +err: + if (!list_empty(&write_list)) { + spin_lock(&zmd->mblk_lock); + list_splice(&write_list, &zmd->mblk_dirty_list); + spin_unlock(&zmd->mblk_lock); + } + if (!dmz_check_bdev(zmd->dev)) + ret = -EIO; + goto out; } /* @@ -1098,7 +1107,6 @@ if (blkz->type == BLK_ZONE_TYPE_CONVENTIONAL) { set_bit(DMZ_RND, &zone->flags); - zmd->nr_rnd_zones++; } else if (blkz->type == BLK_ZONE_TYPE_SEQWRITE_REQ || blkz->type == BLK_ZONE_TYPE_SEQWRITE_PREF) { set_bit(DMZ_SEQ, &zone->flags); @@ -1159,7 +1167,10 @@ /* Init */ zmd->zone_bitmap_size = dev->zone_nr_blocks >> 3; - zmd->zone_nr_bitmap_blocks = zmd->zone_bitmap_size >> DMZ_BLOCK_SHIFT; + zmd->zone_nr_bitmap_blocks = + max_t(sector_t, 1, zmd->zone_bitmap_size >> DMZ_BLOCK_SHIFT); + zmd->zone_bits_per_mblk = min_t(sector_t, dev->zone_nr_blocks, + DMZ_BLOCK_SIZE_BITS); /* Allocate zone array */ zmd->zones = kcalloc(dev->nr_zones, sizeof(struct dm_zone), GFP_KERNEL); @@ -1244,6 +1255,7 @@ if (ret) { dmz_dev_err(zmd->dev, "Get zone %u report failed", dmz_id(zmd, zone)); + dmz_check_bdev(zmd->dev); return ret; } @@ -1577,7 +1589,7 @@ return dzone; } - return ERR_PTR(-EBUSY); + return NULL; } /* @@ -1597,7 +1609,7 @@ return zone; } - return ERR_PTR(-EBUSY); + return NULL; } /* @@ -1982,7 +1994,7 @@ dmz_release_mblock(zmd, to_mblk); dmz_release_mblock(zmd, from_mblk); - chunk_block += DMZ_BLOCK_SIZE_BITS; + chunk_block += zmd->zone_bits_per_mblk; } to_zone->weight = from_zone->weight; @@ -2043,7 +2055,7 @@ /* Set bits */ bit = chunk_block & DMZ_BLOCK_MASK_BITS; - nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); + nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); count = dmz_set_bits((unsigned long *)mblk->data, bit, nr_bits); if (count) { @@ -2122,7 +2134,7 @@ /* Clear bits */ bit = chunk_block & DMZ_BLOCK_MASK_BITS; - nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); + nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); count = dmz_clear_bits((unsigned long *)mblk->data, bit, nr_bits); @@ -2182,6 +2194,7 @@ { struct dmz_mblock *mblk; unsigned int bit, set_bit, nr_bits; + unsigned int zone_bits = zmd->zone_bits_per_mblk; unsigned long *bitmap; int n = 0; @@ -2196,15 +2209,15 @@ /* Get offset */ bitmap = (unsigned long *) mblk->data; bit = chunk_block & DMZ_BLOCK_MASK_BITS; - nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); + nr_bits = min(nr_blocks, zone_bits - bit); if (set) - set_bit = find_next_bit(bitmap, DMZ_BLOCK_SIZE_BITS, bit); + set_bit = find_next_bit(bitmap, zone_bits, bit); else - set_bit = find_next_zero_bit(bitmap, DMZ_BLOCK_SIZE_BITS, bit); + set_bit = find_next_zero_bit(bitmap, zone_bits, bit); dmz_release_mblock(zmd, mblk); n += set_bit - bit; - if (set_bit < DMZ_BLOCK_SIZE_BITS) + if (set_bit < zone_bits) break; nr_blocks -= nr_bits; @@ -2307,7 +2320,7 @@ /* Count bits in this block */ bitmap = mblk->data; bit = chunk_block & DMZ_BLOCK_MASK_BITS; - nr_bits = min(nr_blocks, DMZ_BLOCK_SIZE_BITS - bit); + nr_bits = min(nr_blocks, zmd->zone_bits_per_mblk - bit); n += dmz_count_bits(bitmap, bit, nr_bits); dmz_release_mblock(zmd, mblk); --- linux-oracle-5.4.0.orig/drivers/md/dm-zoned-reclaim.c +++ linux-oracle-5.4.0/drivers/md/dm-zoned-reclaim.c @@ -82,6 +82,7 @@ "Align zone %u wp %llu to %llu (wp+%u) blocks failed %d", dmz_id(zmd, zone), (unsigned long long)wp_block, (unsigned long long)block, nr_blocks, ret); + dmz_check_bdev(zrc->dev); return ret; } @@ -348,8 +349,8 @@ /* Get a data zone */ dzone = dmz_get_zone_for_reclaim(zmd); - if (IS_ERR(dzone)) - return PTR_ERR(dzone); + if (!dzone) + return -EBUSY; start = jiffies; @@ -489,12 +490,7 @@ ret = dmz_do_reclaim(zrc); if (ret) { dmz_dev_debug(zrc->dev, "Reclaim error %d\n", ret); - if (ret == -EIO) - /* - * LLD might be performing some error handling sequence - * at the underlying device. To not interfere, do not - * attempt to schedule the next reclaim run immediately. - */ + if (!dmz_check_bdev(zrc->dev)) return; } --- linux-oracle-5.4.0.orig/drivers/md/dm-zoned-target.c +++ linux-oracle-5.4.0/drivers/md/dm-zoned-target.c @@ -80,6 +80,8 @@ if (status != BLK_STS_OK && bio->bi_status == BLK_STS_OK) bio->bi_status = status; + if (bio->bi_status != BLK_STS_OK) + bioctx->target->dev->flags |= DMZ_CHECK_BDEV; if (refcount_dec_and_test(&bioctx->ref)) { struct dm_zone *zone = bioctx->zone; @@ -531,8 +533,9 @@ /* Get the BIO chunk work. If one is not active yet, create one */ cw = radix_tree_lookup(&dmz->chunk_rxtree, chunk); - if (!cw) { - + if (cw) { + dmz_get_chunk_work(cw); + } else { /* Create a new chunk work */ cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO); if (unlikely(!cw)) { @@ -541,7 +544,7 @@ } INIT_WORK(&cw->work, dmz_chunk_work); - refcount_set(&cw->refcount, 0); + refcount_set(&cw->refcount, 1); cw->target = dmz; cw->chunk = chunk; bio_list_init(&cw->bio_list); @@ -554,7 +557,6 @@ } bio_list_add(&cw->bio_list, bio); - dmz_get_chunk_work(cw); dmz_reclaim_bio_acc(dmz->reclaim); if (queue_work(dmz->chunk_wq, &cw->work)) @@ -565,32 +567,52 @@ } /* - * Check the backing device availability. If it's on the way out, + * Check if the backing device is being removed. If it's on the way out, * start failing I/O. Reclaim and metadata components also call this * function to cleanly abort operation in the event of such failure. */ bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev) { - struct gendisk *disk; + if (dmz_dev->flags & DMZ_BDEV_DYING) + return true; - if (!(dmz_dev->flags & DMZ_BDEV_DYING)) { - disk = dmz_dev->bdev->bd_disk; - if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { - dmz_dev_warn(dmz_dev, "Backing device queue dying"); - dmz_dev->flags |= DMZ_BDEV_DYING; - } else if (disk->fops->check_events) { - if (disk->fops->check_events(disk, 0) & - DISK_EVENT_MEDIA_CHANGE) { - dmz_dev_warn(dmz_dev, "Backing device offline"); - dmz_dev->flags |= DMZ_BDEV_DYING; - } - } + if (dmz_dev->flags & DMZ_CHECK_BDEV) + return !dmz_check_bdev(dmz_dev); + + if (blk_queue_dying(bdev_get_queue(dmz_dev->bdev))) { + dmz_dev_warn(dmz_dev, "Backing device queue dying"); + dmz_dev->flags |= DMZ_BDEV_DYING; } return dmz_dev->flags & DMZ_BDEV_DYING; } /* + * Check the backing device availability. This detects such events as + * backing device going offline due to errors, media removals, etc. + * This check is less efficient than dmz_bdev_is_dying() and should + * only be performed as a part of error handling. + */ +bool dmz_check_bdev(struct dmz_dev *dmz_dev) +{ + struct gendisk *disk; + + dmz_dev->flags &= ~DMZ_CHECK_BDEV; + + if (dmz_bdev_is_dying(dmz_dev)) + return false; + + disk = dmz_dev->bdev->bd_disk; + if (disk->fops->check_events && + disk->fops->check_events(disk, 0) & DISK_EVENT_MEDIA_CHANGE) { + dmz_dev_warn(dmz_dev, "Backing device offline"); + dmz_dev->flags |= DMZ_BDEV_DYING; + } + + return !(dmz_dev->flags & DMZ_BDEV_DYING); +} + +/* * Process a new BIO. */ static int dmz_map(struct dm_target *ti, struct bio *bio) @@ -768,7 +790,7 @@ } /* Set target (no write same support) */ - ti->max_io_len = dev->zone_nr_sectors << 9; + ti->max_io_len = dev->zone_nr_sectors; ti->num_flush_bios = 1; ti->num_discard_bios = 1; ti->num_write_zeroes_bios = 1; @@ -902,8 +924,8 @@ { struct dmz_target *dmz = ti->private; - if (dmz_bdev_is_dying(dmz->dev)) - return -ENODEV; + if (!dmz_check_bdev(dmz->dev)) + return -EIO; *bdev = dmz->dev->bdev; --- linux-oracle-5.4.0.orig/drivers/md/dm-zoned.h +++ linux-oracle-5.4.0/drivers/md/dm-zoned.h @@ -72,6 +72,7 @@ /* Device flags. */ #define DMZ_BDEV_DYING (1 << 0) +#define DMZ_CHECK_BDEV (2 << 0) /* * Zone descriptor. @@ -255,5 +256,6 @@ * Functions defined in dm-zoned-target.c */ bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev); +bool dmz_check_bdev(struct dmz_dev *dmz_dev); #endif /* DM_ZONED_H */ --- linux-oracle-5.4.0.orig/drivers/md/dm.c +++ linux-oracle-5.4.0/drivers/md/dm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -140,10 +141,21 @@ #define DMF_NOFLUSH_SUSPENDING 5 #define DMF_DEFERRED_REMOVE 6 #define DMF_SUSPENDED_INTERNALLY 7 +#define DMF_POST_SUSPENDING 8 #define DM_NUMA_NODE NUMA_NO_NODE static int dm_numa_node = DM_NUMA_NODE; +#define DEFAULT_SWAP_BIOS (8 * 1048576 / PAGE_SIZE) +static int swap_bios = DEFAULT_SWAP_BIOS; +static int get_swap_bios(void) +{ + int latch = READ_ONCE(swap_bios); + if (unlikely(latch <= 0)) + latch = DEFAULT_SWAP_BIOS; + return latch; +} + /* * For mempools pre-allocation at the table loading time. */ @@ -251,7 +263,6 @@ static void local_exit(void) { - flush_scheduled_work(); destroy_workqueue(deferred_remove_workqueue); unregister_blkdev(_major, _name); @@ -453,8 +464,10 @@ return -EAGAIN; map = dm_get_live_table(md, &srcu_idx); - if (!map) - return -EIO; + if (!map) { + ret = -EIO; + goto out; + } tgt = dm_table_find_target(map, sector); if (!tgt) { @@ -491,7 +504,6 @@ static int dm_prepare_ioctl(struct mapped_device *md, int *srcu_idx, struct block_device **bdev) - __acquires(md->io_barrier) { struct dm_target *tgt; struct dm_table *map; @@ -525,7 +537,6 @@ } static void dm_unprepare_ioctl(struct mapped_device *md, int srcu_idx) - __releases(md->io_barrier) { dm_put_live_table(md, srcu_idx); } @@ -546,7 +557,7 @@ * subset of the parent bdev; require extra privileges. */ if (!capable(CAP_SYS_RAWIO)) { - DMWARN_LIMIT( + DMDEBUG_LIMIT( "%s: sending ioctl %x to DM device without required privilege.", current->comm, cmd); r = -ENOIOCTLCMD; @@ -626,27 +637,14 @@ bio_put(&tio->clone); } -static bool md_in_flight_bios(struct mapped_device *md) +u64 dm_start_time_ns_from_clone(struct bio *bio) { - int cpu; - struct hd_struct *part = &dm_disk(md)->part0; - long sum = 0; - - for_each_possible_cpu(cpu) { - sum += part_stat_local_read_cpu(part, in_flight[0], cpu); - sum += part_stat_local_read_cpu(part, in_flight[1], cpu); - } + struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone); + struct dm_io *io = tio->io; - return sum != 0; -} - -static bool md_in_flight(struct mapped_device *md) -{ - if (queue_is_mq(md->queue)) - return blk_mq_queue_inflight(md->queue); - else - return md_in_flight_bios(md); + return jiffies_to_nsecs(io->start_time); } +EXPORT_SYMBOL_GPL(dm_start_time_ns_from_clone); static void start_io_acct(struct dm_io *io) { @@ -664,19 +662,20 @@ false, 0, &io->stats_aux); } -static void end_io_acct(struct dm_io *io) +static void end_io_acct(struct mapped_device *md, struct bio *bio, + unsigned long start_time, struct dm_stats_aux *stats_aux) { - struct mapped_device *md = io->md; - struct bio *bio = io->orig_bio; - unsigned long duration = jiffies - io->start_time; - - generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, - io->start_time); + unsigned long duration = jiffies - start_time; if (unlikely(dm_stats_used(&md->stats))) dm_stats_account_io(&md->stats, bio_data_dir(bio), bio->bi_iter.bi_sector, bio_sectors(bio), - true, duration, &io->stats_aux); + true, duration, stats_aux); + + smp_wmb(); + + generic_end_io_acct(md->queue, bio_op(bio), &dm_disk(md)->part0, + start_time); /* nudge anyone waiting on suspend queue */ if (unlikely(wq_has_sleeper(&md->wait))) @@ -897,6 +896,8 @@ blk_status_t io_error; struct bio *bio; struct mapped_device *md = io->md; + unsigned long start_time = 0; + struct dm_stats_aux stats_aux; /* Push-back supersedes any I/O errors */ if (unlikely(error)) { @@ -923,8 +924,10 @@ io_error = io->status; bio = io->orig_bio; - end_io_acct(io); + start_time = io->start_time; + stats_aux = io->stats_aux; free_io(md, io); + end_io_acct(md, bio, start_time, &stats_aux); if (io_error == BLK_STS_DM_REQUEUE) return; @@ -970,6 +973,11 @@ limits->max_write_zeroes_sectors = 0; } +static bool swap_bios_limit(struct dm_target *ti, struct bio *bio) +{ + return unlikely((bio->bi_opf & REQ_SWAP) != 0) && unlikely(ti->limit_swap_bios); +} + static void clone_endio(struct bio *bio) { blk_status_t error = bio->bi_status; @@ -978,7 +986,7 @@ struct mapped_device *md = tio->io->md; dm_endio_fn endio = tio->ti->type->end_io; - if (unlikely(error == BLK_STS_TARGET) && md->type != DM_TYPE_NVME_BIO_BASED) { + if (unlikely(error == BLK_STS_TARGET)) { if (bio_op(bio) == REQ_OP_DISCARD && !bio->bi_disk->queue->limits.max_discard_sectors) disable_discard(md); @@ -1007,6 +1015,11 @@ } } + if (unlikely(swap_bios_limit(tio->ti, bio))) { + struct mapped_device *md = io->md; + up(&md->swap_bios_semaphore); + } + free_tio(tio); dec_pending(io, error); } @@ -1110,15 +1123,16 @@ { struct mapped_device *md = dax_get_private(dax_dev); struct dm_table *map; + bool ret = false; int srcu_idx; - bool ret; map = dm_get_live_table(md, &srcu_idx); if (!map) - return false; + goto out; - ret = dm_table_supports_dax(map, device_supports_dax, &blocksize); + ret = dm_table_supports_dax(map, device_not_dax_capable, &blocksize); +out: dm_put_live_table(md, srcu_idx); return ret; @@ -1260,6 +1274,22 @@ } EXPORT_SYMBOL_GPL(dm_remap_zone_report); +static noinline void __set_swap_bios_limit(struct mapped_device *md, int latch) +{ + mutex_lock(&md->swap_bios_lock); + while (latch < md->swap_bios) { + cond_resched(); + down(&md->swap_bios_semaphore); + md->swap_bios--; + } + while (latch > md->swap_bios) { + cond_resched(); + up(&md->swap_bios_semaphore); + md->swap_bios++; + } + mutex_unlock(&md->swap_bios_lock); +} + static blk_qc_t __map_bio(struct dm_target_io *tio) { int r; @@ -1280,6 +1310,13 @@ atomic_inc(&io->io_count); sector = clone->bi_iter.bi_sector; + if (unlikely(swap_bios_limit(ti, clone))) { + int latch = get_swap_bios(); + if (unlikely(latch != md->swap_bios)) + __set_swap_bios_limit(md, latch); + down(&md->swap_bios_semaphore); + } + r = ti->type->map(ti, clone); switch (r) { case DM_MAPIO_SUBMITTED: @@ -1288,16 +1325,17 @@ /* the bio has been remapped so dispatch it */ trace_block_bio_remap(clone->bi_disk->queue, clone, bio_dev(io->orig_bio), sector); - if (md->type == DM_TYPE_NVME_BIO_BASED) - ret = direct_make_request(clone); - else - ret = generic_make_request(clone); + ret = generic_make_request(clone); break; case DM_MAPIO_KILL: + if (unlikely(swap_bios_limit(ti, clone))) + up(&md->swap_bios_semaphore); free_tio(tio); dec_pending(io, BLK_STS_IOERR); break; case DM_MAPIO_REQUEUE: + if (unlikely(swap_bios_limit(ti, clone))) + up(&md->swap_bios_semaphore); free_tio(tio); dec_pending(io, BLK_STS_DM_REQUEUE); break; @@ -1436,9 +1474,6 @@ BUG_ON(bio_has_data(ci->bio)); while ((ti = dm_table_get_target(ci->map, target_nr++))) __send_duplicate_bios(ci, ti, ti->num_flush_bios, NULL); - - bio_disassociate_blkg(ci->bio); - return 0; } @@ -1626,6 +1661,7 @@ ci.bio = &flush_bio; ci.sector_count = 0; error = __send_empty_flush(&ci); + bio_uninit(ci.bio); /* dec_pending submits any data associated with flush */ } else if (bio_op(bio) == REQ_OP_ZONE_RESET) { ci.bio = bio; @@ -1674,67 +1710,6 @@ return ret; } -/* - * Optimized variant of __split_and_process_bio that leverages the - * fact that targets that use it do _not_ have a need to split bios. - */ -static blk_qc_t __process_bio(struct mapped_device *md, struct dm_table *map, - struct bio *bio, struct dm_target *ti) -{ - struct clone_info ci; - blk_qc_t ret = BLK_QC_T_NONE; - int error = 0; - - init_clone_info(&ci, md, map, bio); - - if (bio->bi_opf & REQ_PREFLUSH) { - struct bio flush_bio; - - /* - * Use an on-stack bio for this, it's safe since we don't - * need to reference it after submit. It's just used as - * the basis for the clone(s). - */ - bio_init(&flush_bio, NULL, 0); - flush_bio.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC; - ci.bio = &flush_bio; - ci.sector_count = 0; - error = __send_empty_flush(&ci); - /* dec_pending submits any data associated with flush */ - } else { - struct dm_target_io *tio; - - ci.bio = bio; - ci.sector_count = bio_sectors(bio); - if (__process_abnormal_io(&ci, ti, &error)) - goto out; - - tio = alloc_tio(&ci, ti, 0, GFP_NOIO); - ret = __clone_and_map_simple_bio(&ci, tio, NULL); - } -out: - /* drop the extra reference count */ - dec_pending(ci.io, errno_to_blk_status(error)); - return ret; -} - -static void dm_queue_split(struct mapped_device *md, struct dm_target *ti, struct bio **bio) -{ - unsigned len, sector_count; - - sector_count = bio_sectors(*bio); - len = min_t(sector_t, max_io_len((*bio)->bi_iter.bi_sector, ti), sector_count); - - if (sector_count > len) { - struct bio *split = bio_split(*bio, len, GFP_NOIO, &md->queue->bio_split); - - bio_chain(split, *bio); - trace_block_split(md->queue, split, (*bio)->bi_iter.bi_sector); - generic_make_request(*bio); - *bio = split; - } -} - static blk_qc_t dm_process_bio(struct mapped_device *md, struct dm_table *map, struct bio *bio) { @@ -1760,15 +1735,12 @@ * won't be imposed. */ if (current->bio_list) { - blk_queue_split(md->queue, &bio); - if (!is_abnormal_io(bio)) - dm_queue_split(md, ti, &bio); + if (is_abnormal_io(bio)) + blk_queue_split(md->queue, &bio); + /* regular IO is split by __split_and_process_bio */ } - if (dm_get_md_type(md) == DM_TYPE_NVME_BIO_BASED) - return __process_bio(md, map, bio, ti); - else - return __split_and_process_bio(md, map, bio); + return __split_and_process_bio(md, map, bio); } static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio) @@ -1809,7 +1781,8 @@ * With request-based DM we only need to check the * top-level queue for congestion. */ - r = md->queue->backing_dev_info->wb.state & bdi_bits; + struct backing_dev_info *bdi = md->queue->backing_dev_info; + r = bdi->wb.congested->state & bdi_bits; } else { map = dm_get_live_table_fast(md); if (map) @@ -1875,14 +1848,6 @@ static void dm_wq_work(struct work_struct *work); -static void dm_init_normal_md_queue(struct mapped_device *md) -{ - /* - * Initialize aspects of queue that aren't relevant for blk-mq - */ - md->queue->backing_dev_info->congested_fn = dm_any_congested; -} - static void cleanup_mapped_device(struct mapped_device *md) { if (md->wq) @@ -1917,6 +1882,7 @@ mutex_destroy(&md->suspend_lock); mutex_destroy(&md->type_lock); mutex_destroy(&md->table_devices_lock); + mutex_destroy(&md->swap_bios_lock); dm_mq_cleanup_mapped_device(md); } @@ -1970,7 +1936,12 @@ if (!md->queue) goto bad; md->queue->queuedata = md; - md->queue->backing_dev_info->congested_data = md; + /* + * default to bio-based required ->make_request_fn until DM + * table is loaded and md->type established. If request-based + * table is loaded: blk-mq will override accordingly. + */ + blk_queue_make_request(md->queue, dm_make_request); md->disk = alloc_disk_node(1, md->numa_node_id); if (!md->disk) @@ -1981,6 +1952,10 @@ init_waitqueue_head(&md->eventq); init_completion(&md->kobj_holder.completion); + md->swap_bios = get_swap_bios(); + sema_init(&md->swap_bios_semaphore, md->swap_bios); + mutex_init(&md->swap_bios_lock); + md->disk->major = _major; md->disk->first_minor = minor; md->disk->fops = &dm_blk_dops; @@ -2006,7 +1981,9 @@ if (!md->bdev) goto bad; - dm_stats_init(&md->stats); + r = dm_stats_init(&md->stats); + if (r < 0) + goto bad; /* Populate the mapping, nobody knows we exist yet */ spin_lock(&_minor_lock); @@ -2156,12 +2133,10 @@ if (request_based) dm_stop_queue(q); - if (request_based || md->type == DM_TYPE_NVME_BIO_BASED) { + if (request_based) { /* - * Leverage the fact that request-based DM targets and - * NVMe bio based targets are immutable singletons - * - used to optimize both dm_request_fn and dm_mq_queue_rq; - * and __process_bio. + * Leverage the fact that request-based DM targets are + * immutable singletons - used to optimize dm_mq_queue_rq. */ md->immutable_target = dm_table_get_immutable_target(t); } @@ -2264,6 +2239,12 @@ } EXPORT_SYMBOL_GPL(dm_get_queue_limits); +static void dm_init_congested_fn(struct mapped_device *md) +{ + md->queue->backing_dev_info->congested_data = md; + md->queue->backing_dev_info->congested_fn = dm_any_congested; +} + /* * Setup the DM device's queue based on md's type */ @@ -2280,12 +2261,11 @@ DMERR("Cannot initialize queue for request-based dm-mq mapped device"); return r; } + dm_init_congested_fn(md); break; case DM_TYPE_BIO_BASED: case DM_TYPE_DAX_BIO_BASED: - case DM_TYPE_NVME_BIO_BASED: - dm_init_normal_md_queue(md); - blk_queue_make_request(md->queue, dm_make_request); + dm_init_congested_fn(md); break; case DM_TYPE_NONE: WARN_ON_ONCE(true); @@ -2384,6 +2364,8 @@ map = dm_get_live_table(md, &srcu_idx); if (!dm_suspended_md(md)) { dm_table_presuspend_targets(map); + set_bit(DMF_SUSPENDED, &md->flags); + set_bit(DMF_POST_SUSPENDING, &md->flags); dm_table_postsuspend_targets(map); } /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ @@ -2424,19 +2406,33 @@ } EXPORT_SYMBOL_GPL(dm_put); -static int dm_wait_for_completion(struct mapped_device *md, long task_state) +static bool md_in_flight_bios(struct mapped_device *md) +{ + int cpu; + struct hd_struct *part = &dm_disk(md)->part0; + long sum = 0; + + for_each_possible_cpu(cpu) { + sum += part_stat_local_read_cpu(part, in_flight[0], cpu); + sum += part_stat_local_read_cpu(part, in_flight[1], cpu); + } + + return sum != 0; +} + +static int dm_wait_for_bios_completion(struct mapped_device *md, long task_state) { int r = 0; DEFINE_WAIT(wait); - while (1) { + while (true) { prepare_to_wait(&md->wait, &wait, task_state); - if (!md_in_flight(md)) + if (!md_in_flight_bios(md)) break; if (signal_pending_state(task_state, current)) { - r = -EINTR; + r = -ERESTARTSYS; break; } @@ -2444,6 +2440,30 @@ } finish_wait(&md->wait, &wait); + smp_rmb(); + + return r; +} + +static int dm_wait_for_completion(struct mapped_device *md, long task_state) +{ + int r = 0; + + if (!queue_is_mq(md->queue)) + return dm_wait_for_bios_completion(md, task_state); + + while (true) { + if (!blk_mq_queue_inflight(md->queue)) + break; + + if (signal_pending_state(task_state, current)) { + r = -ERESTARTSYS; + break; + } + + msleep(5); + } + return r; } @@ -2706,7 +2726,9 @@ if (r) goto out_unlock; + set_bit(DMF_POST_SUSPENDING, &md->flags); dm_table_postsuspend_targets(map); + clear_bit(DMF_POST_SUSPENDING, &md->flags); out_unlock: mutex_unlock(&md->suspend_lock); @@ -2803,11 +2825,16 @@ (void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE, DMF_SUSPENDED_INTERNALLY); + set_bit(DMF_POST_SUSPENDING, &md->flags); dm_table_postsuspend_targets(map); + clear_bit(DMF_POST_SUSPENDING, &md->flags); } static void __dm_internal_resume(struct mapped_device *md) { + int r; + struct dm_table *map; + BUG_ON(!md->internal_suspend_count); if (--md->internal_suspend_count) @@ -2816,12 +2843,23 @@ if (dm_suspended_md(md)) goto done; /* resume from nested suspend */ - /* - * NOTE: existing callers don't need to call dm_table_resume_targets - * (which may fail -- so best to avoid it for now by passing NULL map) - */ - (void) __dm_resume(md, NULL); - + map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock)); + r = __dm_resume(md, map); + if (r) { + /* + * If a preresume method of some target failed, we are in a + * tricky situation. We can't return an error to the caller. We + * can't fake success because then the "resume" and + * "postsuspend" methods would not be paired correctly, and it + * would break various targets, for example it would cause list + * corruption in the "origin" target. + * + * So, we fake normal suspend here, to make sure that the + * "resume" and "postsuspend" methods will be paired correctly. + */ + DMERR("Preresume method failed: %d", r); + set_bit(DMF_SUSPENDED, &md->flags); + } done: clear_bit(DMF_SUSPENDED_INTERNALLY, &md->flags); smp_mb__after_atomic(); @@ -2880,17 +2918,25 @@ int dm_kobject_uevent(struct mapped_device *md, enum kobject_action action, unsigned cookie) { + int r; + unsigned noio_flag; char udev_cookie[DM_COOKIE_LENGTH]; char *envp[] = { udev_cookie, NULL }; + noio_flag = memalloc_noio_save(); + if (!cookie) - return kobject_uevent(&disk_to_dev(md->disk)->kobj, action); + r = kobject_uevent(&disk_to_dev(md->disk)->kobj, action); else { snprintf(udev_cookie, DM_COOKIE_LENGTH, "%s=%u", DM_COOKIE_ENV_VAR_NAME, cookie); - return kobject_uevent_env(&disk_to_dev(md->disk)->kobj, - action, envp); + r = kobject_uevent_env(&disk_to_dev(md->disk)->kobj, + action, envp); } + + memalloc_noio_restore(noio_flag); + + return r; } uint32_t dm_next_uevent_seq(struct mapped_device *md) @@ -2956,6 +3002,11 @@ return test_bit(DMF_SUSPENDED, &md->flags); } +static int dm_post_suspending_md(struct mapped_device *md) +{ + return test_bit(DMF_POST_SUSPENDING, &md->flags); +} + int dm_suspended_internally_md(struct mapped_device *md) { return test_bit(DMF_SUSPENDED_INTERNALLY, &md->flags); @@ -2972,6 +3023,12 @@ } EXPORT_SYMBOL_GPL(dm_suspended); +int dm_post_suspending(struct dm_target *ti) +{ + return dm_post_suspending_md(dm_table_get_md(ti->table)); +} +EXPORT_SYMBOL_GPL(dm_post_suspending); + int dm_noflush_suspending(struct dm_target *ti) { return __noflush_suspending(dm_table_get_md(ti->table)); @@ -2993,7 +3050,6 @@ switch (type) { case DM_TYPE_BIO_BASED: case DM_TYPE_DAX_BIO_BASED: - case DM_TYPE_NVME_BIO_BASED: pool_size = max(dm_get_reserved_bio_based_ios(), min_pool_size); front_pad = roundup(per_io_data_size, __alignof__(struct dm_target_io)) + offsetof(struct dm_target_io, clone); io_front_pad = roundup(front_pad, __alignof__(struct dm_io)) + offsetof(struct dm_io, tio); @@ -3062,6 +3118,11 @@ goto out; ti = dm_table_get_target(table, 0); + if (dm_suspended_md(md)) { + ret = -EAGAIN; + goto out; + } + ret = -EINVAL; if (!ti->type->iterate_devices) goto out; @@ -3232,6 +3293,9 @@ module_param(dm_numa_node, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(dm_numa_node, "NUMA node for DM device memory allocations"); +module_param(swap_bios, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(swap_bios, "Maximum allowed inflight swap IOs"); + MODULE_DESCRIPTION(DM_NAME " driver"); MODULE_AUTHOR("Joe Thornber "); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/md/dm.h +++ linux-oracle-5.4.0/drivers/md/dm.h @@ -74,7 +74,7 @@ struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); bool dm_table_supports_dax(struct dm_table *t, iterate_devices_callout_fn fn, int *blocksize); -int device_supports_dax(struct dm_target *ti, struct dm_dev *dev, +int device_not_dax_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data); void dm_lock_md_type(struct mapped_device *md); --- linux-oracle-5.4.0.orig/drivers/md/md-bitmap.c +++ linux-oracle-5.4.0/drivers/md/md-bitmap.c @@ -54,14 +54,7 @@ { unsigned char *mappage; - if (page >= bitmap->pages) { - /* This can happen if bitmap_start_sync goes beyond - * End-of-device while looking for a whole page. - * It is harmless. - */ - return -EINVAL; - } - + WARN_ON_ONCE(page >= bitmap->pages); if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */ return 0; @@ -489,7 +482,7 @@ sb = kmap_atomic(bitmap->storage.sb_page); pr_debug("%s: bitmap file superblock:\n", bmname(bitmap)); pr_debug(" magic: %08x\n", le32_to_cpu(sb->magic)); - pr_debug(" version: %d\n", le32_to_cpu(sb->version)); + pr_debug(" version: %u\n", le32_to_cpu(sb->version)); pr_debug(" uuid: %08x.%08x.%08x.%08x\n", le32_to_cpu(*(__le32 *)(sb->uuid+0)), le32_to_cpu(*(__le32 *)(sb->uuid+4)), @@ -500,11 +493,11 @@ pr_debug("events cleared: %llu\n", (unsigned long long) le64_to_cpu(sb->events_cleared)); pr_debug(" state: %08x\n", le32_to_cpu(sb->state)); - pr_debug(" chunksize: %d B\n", le32_to_cpu(sb->chunksize)); - pr_debug(" daemon sleep: %ds\n", le32_to_cpu(sb->daemon_sleep)); + pr_debug(" chunksize: %u B\n", le32_to_cpu(sb->chunksize)); + pr_debug(" daemon sleep: %us\n", le32_to_cpu(sb->daemon_sleep)); pr_debug(" sync size: %llu KB\n", (unsigned long long)le64_to_cpu(sb->sync_size)/2); - pr_debug("max write behind: %d\n", le32_to_cpu(sb->write_behind)); + pr_debug("max write behind: %u\n", le32_to_cpu(sb->write_behind)); kunmap_atomic(sb); } @@ -642,14 +635,6 @@ daemon_sleep = le32_to_cpu(sb->daemon_sleep) * HZ; write_behind = le32_to_cpu(sb->write_behind); sectors_reserved = le32_to_cpu(sb->sectors_reserved); - /* Setup nodes/clustername only if bitmap version is - * cluster-compatible - */ - if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { - nodes = le32_to_cpu(sb->nodes); - strlcpy(bitmap->mddev->bitmap_info.cluster_name, - sb->cluster_name, 64); - } /* verify that the bitmap-specific fields are valid */ if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) @@ -671,6 +656,16 @@ goto out; } + /* + * Setup nodes/clustername only if bitmap version is + * cluster-compatible + */ + if (sb->version == cpu_to_le32(BITMAP_MAJOR_CLUSTERED)) { + nodes = le32_to_cpu(sb->nodes); + strlcpy(bitmap->mddev->bitmap_info.cluster_name, + sb->cluster_name, 64); + } + /* keep the array size field of the bitmap superblock up to date */ sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors); @@ -703,9 +698,9 @@ out: kunmap_atomic(sb); - /* Assigning chunksize is required for "re_read" */ - bitmap->mddev->bitmap_info.chunksize = chunksize; if (err == 0 && nodes && (bitmap->cluster_slot < 0)) { + /* Assigning chunksize is required for "re_read" */ + bitmap->mddev->bitmap_info.chunksize = chunksize; err = md_setup_cluster(bitmap->mddev, nodes); if (err) { pr_warn("%s: Could not setup cluster service (%d)\n", @@ -716,18 +711,18 @@ goto re_read; } - out_no_sb: - if (test_bit(BITMAP_STALE, &bitmap->flags)) - bitmap->events_cleared = bitmap->mddev->events; - bitmap->mddev->bitmap_info.chunksize = chunksize; - bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; - bitmap->mddev->bitmap_info.max_write_behind = write_behind; - bitmap->mddev->bitmap_info.nodes = nodes; - if (bitmap->mddev->bitmap_info.space == 0 || - bitmap->mddev->bitmap_info.space > sectors_reserved) - bitmap->mddev->bitmap_info.space = sectors_reserved; - if (err) { + if (err == 0) { + if (test_bit(BITMAP_STALE, &bitmap->flags)) + bitmap->events_cleared = bitmap->mddev->events; + bitmap->mddev->bitmap_info.chunksize = chunksize; + bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep; + bitmap->mddev->bitmap_info.max_write_behind = write_behind; + bitmap->mddev->bitmap_info.nodes = nodes; + if (bitmap->mddev->bitmap_info.space == 0 || + bitmap->mddev->bitmap_info.space > sectors_reserved) + bitmap->mddev->bitmap_info.space = sectors_reserved; + } else { md_bitmap_print_sb(bitmap); if (bitmap->cluster_slot < 0) md_cluster_stop(bitmap->mddev); @@ -1364,17 +1359,25 @@ sector_t chunk = offset >> bitmap->chunkshift; unsigned long page = chunk >> PAGE_COUNTER_SHIFT; unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT; - sector_t csize; + sector_t csize = ((sector_t)1) << bitmap->chunkshift; int err; + if (page >= bitmap->pages) { + /* + * This can happen if bitmap_start_sync goes beyond + * End-of-device while looking for a whole page or + * user set a huge number to sysfs bitmap_set_bits. + */ + *blocks = csize - (offset & (csize - 1)); + return NULL; + } err = md_bitmap_checkpage(bitmap, page, create, 0); if (bitmap->bp[page].hijacked || bitmap->bp[page].map == NULL) csize = ((sector_t)1) << (bitmap->chunkshift + - PAGE_COUNTER_SHIFT - 1); - else - csize = ((sector_t)1) << bitmap->chunkshift; + PAGE_COUNTER_SHIFT); + *blocks = csize - (offset & (csize - 1)); if (err < 0) @@ -1726,6 +1729,8 @@ md_bitmap_daemon_work(mddev); bitmap->daemon_lastrun -= sleep; md_bitmap_daemon_work(mddev); + if (mddev->bitmap_info.external) + md_super_wait(mddev); md_bitmap_update_sb(bitmap); } @@ -1954,6 +1959,7 @@ } EXPORT_SYMBOL_GPL(md_bitmap_load); +/* caller need to free returned bitmap with md_bitmap_free() */ struct bitmap *get_bitmap_from_slot(struct mddev *mddev, int slot) { int rv = 0; @@ -2017,6 +2023,7 @@ md_bitmap_unplug(mddev->bitmap); *low = lo; *high = hi; + md_bitmap_free(bitmap); return rv; } @@ -2104,7 +2111,8 @@ bytes = DIV_ROUND_UP(chunks, 8); if (!bitmap->mddev->bitmap_info.external) bytes += sizeof(bitmap_super_t); - } while (bytes > (space << 9)); + } while (bytes > (space << 9) && (chunkshift + BITMAP_BLOCK_SHIFT) < + (BITS_PER_BYTE * sizeof(((bitmap_super_t *)0)->chunksize) - 1)); } else chunkshift = ffz(~chunksize) - BITMAP_BLOCK_SHIFT; @@ -2139,6 +2147,7 @@ memcpy(page_address(store.sb_page), page_address(bitmap->storage.sb_page), sizeof(bitmap_super_t)); + spin_lock_irq(&bitmap->counts.lock); md_bitmap_file_unmap(&bitmap->storage); bitmap->storage = store; @@ -2148,13 +2157,12 @@ bitmap->counts.missing_pages = pages; bitmap->counts.chunkshift = chunkshift; bitmap->counts.chunks = chunks; - bitmap->mddev->bitmap_info.chunksize = 1 << (chunkshift + + bitmap->mddev->bitmap_info.chunksize = 1UL << (chunkshift + BITMAP_BLOCK_SHIFT); blocks = min(old_counts.chunks << old_counts.chunkshift, chunks << chunkshift); - spin_lock_irq(&bitmap->counts.lock); /* For cluster raid, need to pre-allocate bitmap */ if (mddev_is_clustered(bitmap->mddev)) { unsigned long page; @@ -2175,8 +2183,8 @@ bitmap->counts.missing_pages = old_counts.pages; bitmap->counts.chunkshift = old_counts.chunkshift; bitmap->counts.chunks = old_counts.chunks; - bitmap->mddev->bitmap_info.chunksize = 1 << (old_counts.chunkshift + - BITMAP_BLOCK_SHIFT); + bitmap->mddev->bitmap_info.chunksize = + 1UL << (old_counts.chunkshift + BITMAP_BLOCK_SHIFT); blocks = old_counts.chunks << old_counts.chunkshift; pr_warn("Could not pre-allocate in-memory bitmap for cluster raid\n"); break; @@ -2194,20 +2202,23 @@ if (set) { bmc_new = md_bitmap_get_counter(&bitmap->counts, block, &new_blocks, 1); - if (*bmc_new == 0) { - /* need to set on-disk bits too. */ - sector_t end = block + new_blocks; - sector_t start = block >> chunkshift; - start <<= chunkshift; - while (start < end) { - md_bitmap_file_set_bit(bitmap, block); - start += 1 << chunkshift; + if (bmc_new) { + if (*bmc_new == 0) { + /* need to set on-disk bits too. */ + sector_t end = block + new_blocks; + sector_t start = block >> chunkshift; + + start <<= chunkshift; + while (start < end) { + md_bitmap_file_set_bit(bitmap, block); + start += 1 << chunkshift; + } + *bmc_new = 2; + md_bitmap_count_page(&bitmap->counts, block, 1); + md_bitmap_set_pending(&bitmap->counts, block); } - *bmc_new = 2; - md_bitmap_count_page(&bitmap->counts, block, 1); - md_bitmap_set_pending(&bitmap->counts, block); + *bmc_new |= NEEDED_MASK; } - *bmc_new |= NEEDED_MASK; if (new_blocks < old_blocks) old_blocks = new_blocks; } @@ -2469,11 +2480,35 @@ { unsigned long backlog; unsigned long old_mwb = mddev->bitmap_info.max_write_behind; + struct md_rdev *rdev; + bool has_write_mostly = false; int rv = kstrtoul(buf, 10, &backlog); if (rv) return rv; if (backlog > COUNTER_MAX) return -EINVAL; + + rv = mddev_lock(mddev); + if (rv) + return rv; + + /* + * Without write mostly device, it doesn't make sense to set + * backlog for max_write_behind. + */ + rdev_for_each(rdev, mddev) { + if (test_bit(WriteMostly, &rdev->flags)) { + has_write_mostly = true; + break; + } + } + if (!has_write_mostly) { + pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n", + mdname(mddev)); + mddev_unlock(mddev); + return -EINVAL; + } + mddev->bitmap_info.max_write_behind = backlog; if (!backlog && mddev->wb_info_pool) { /* wb_info_pool is not needed if backlog is zero */ @@ -2488,6 +2523,8 @@ } if (old_mwb != backlog) md_bitmap_update_sb(mddev->bitmap); + + mddev_unlock(mddev); return len; } @@ -2514,6 +2551,9 @@ if (csize < 512 || !is_power_of_2(csize)) return -EINVAL; + if (BITS_PER_LONG > 32 && csize >= (1ULL << (BITS_PER_BYTE * + sizeof(((bitmap_super_t *)0)->chunksize)))) + return -EOVERFLOW; mddev->bitmap_info.chunksize = csize; return len; } @@ -2620,4 +2660,3 @@ .name = "bitmap", .attrs = md_bitmap_attrs, }; - --- linux-oracle-5.4.0.orig/drivers/md/md-cluster.c +++ linux-oracle-5.4.0/drivers/md/md-cluster.c @@ -664,9 +664,27 @@ * Takes the lock on the TOKEN lock resource so no other * node can communicate while the operation is underway. */ -static int lock_token(struct md_cluster_info *cinfo, bool mddev_locked) +static int lock_token(struct md_cluster_info *cinfo) { - int error, set_bit = 0; + int error; + + error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX); + if (error) { + pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n", + __func__, __LINE__, error); + } else { + /* Lock the receive sequence */ + mutex_lock(&cinfo->recv_mutex); + } + return error; +} + +/* lock_comm() + * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel. + */ +static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked) +{ + int rv, set_bit = 0; struct mddev *mddev = cinfo->mddev; /* @@ -677,34 +695,19 @@ */ if (mddev_locked && !test_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state)) { - error = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, + rv = test_and_set_bit_lock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state); - WARN_ON_ONCE(error); + WARN_ON_ONCE(rv); md_wakeup_thread(mddev->thread); set_bit = 1; } - error = dlm_lock_sync(cinfo->token_lockres, DLM_LOCK_EX); - if (set_bit) - clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state); - if (error) - pr_err("md-cluster(%s:%d): failed to get EX on TOKEN (%d)\n", - __func__, __LINE__, error); - - /* Lock the receive sequence */ - mutex_lock(&cinfo->recv_mutex); - return error; -} - -/* lock_comm() - * Sets the MD_CLUSTER_SEND_LOCK bit to lock the send channel. - */ -static int lock_comm(struct md_cluster_info *cinfo, bool mddev_locked) -{ wait_event(cinfo->wait, !test_and_set_bit(MD_CLUSTER_SEND_LOCK, &cinfo->state)); - - return lock_token(cinfo, mddev_locked); + rv = lock_token(cinfo); + if (set_bit) + clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state); + return rv; } static void unlock_comm(struct md_cluster_info *cinfo) @@ -784,9 +787,11 @@ { int ret; - lock_comm(cinfo, mddev_locked); - ret = __sendmsg(cinfo, cmsg); - unlock_comm(cinfo); + ret = lock_comm(cinfo, mddev_locked); + if (!ret) { + ret = __sendmsg(cinfo, cmsg); + unlock_comm(cinfo); + } return ret; } @@ -1061,7 +1066,7 @@ return 0; } - ret = lock_token(cinfo, 1); + ret = lock_token(cinfo); clear_bit_unlock(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state); return ret; } @@ -1139,6 +1144,7 @@ bitmap = get_bitmap_from_slot(mddev, i); if (IS_ERR(bitmap)) { pr_err("can't get bitmap from slot %d\n", i); + bitmap = NULL; goto out; } counts = &bitmap->counts; @@ -1165,6 +1171,7 @@ * can't resize bitmap */ goto out; + md_bitmap_free(bitmap); } return 0; @@ -1253,7 +1260,10 @@ int raid_slot = -1; md_update_sb(mddev, 1); - lock_comm(cinfo, 1); + if (lock_comm(cinfo, 1)) { + pr_err("%s: lock_comm failed\n", __func__); + return; + } memset(&cmsg, 0, sizeof(cmsg)); cmsg.type = cpu_to_le32(METADATA_UPDATED); @@ -1405,7 +1415,8 @@ cmsg.type = cpu_to_le32(NEWDISK); memcpy(cmsg.uuid, uuid, 16); cmsg.raid_slot = cpu_to_le32(rdev->desc_nr); - lock_comm(cinfo, 1); + if (lock_comm(cinfo, 1)) + return -EAGAIN; ret = __sendmsg(cinfo, &cmsg); if (ret) { unlock_comm(cinfo); @@ -1518,6 +1529,7 @@ } } kfree(cinfo->other_bitmap_lockres); + cinfo->other_bitmap_lockres = NULL; } } --- linux-oracle-5.4.0.orig/drivers/md/md-linear.c +++ linux-oracle-5.4.0/drivers/md/md-linear.c @@ -244,10 +244,9 @@ sector_t start_sector, end_sector, data_offset; sector_t bio_sector = bio->bi_iter.bi_sector; - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - } tmp_dev = which_dev(mddev, bio_sector); start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors; --- linux-oracle-5.4.0.orig/drivers/md/md-multipath.c +++ linux-oracle-5.4.0/drivers/md/md-multipath.c @@ -104,10 +104,9 @@ struct multipath_bh * mp_bh; struct multipath_info *multipath; - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - } mp_bh = mempool_alloc(&conf->pool, GFP_NOIO); --- linux-oracle-5.4.0.orig/drivers/md/md.c +++ linux-oracle-5.4.0/drivers/md/md.c @@ -376,17 +376,18 @@ struct mddev *mddev = q->queuedata; unsigned int sectors; - if (unlikely(test_bit(MD_BROKEN, &mddev->flags)) && (rw == WRITE)) { + if (mddev == NULL || mddev->pers == NULL) { bio_io_error(bio); return BLK_QC_T_NONE; } - blk_queue_split(q, &bio); - - if (mddev == NULL || mddev->pers == NULL) { + if (unlikely(test_bit(MD_BROKEN, &mddev->flags)) && (rw == WRITE)) { bio_io_error(bio); return BLK_QC_T_NONE; } + + blk_queue_split(q, &bio); + if (mddev->ro == 1 && unlikely(rw == WRITE)) { if (bio_sectors(bio) != 0) bio->bi_status = BLK_STS_IOERR; @@ -480,13 +481,14 @@ struct md_rdev *rdev = bio->bi_private; struct mddev *mddev = rdev->mddev; + bio_put(bio); + rdev_dec_pending(rdev, mddev); if (atomic_dec_and_test(&mddev->flush_pending)) { /* The pre-request flush has finished */ queue_work(md_wq, &mddev->flush_work); } - bio_put(bio); } static void md_submit_flush_data(struct work_struct *ws); @@ -537,8 +539,10 @@ * could wait for this and below md_handle_request could wait for those * bios because of suspend check */ + spin_lock_irq(&mddev->lock); mddev->last_flush = mddev->start_flush; mddev->flush_bio = NULL; + spin_unlock_irq(&mddev->lock); wake_up(&mddev->sb_wait); if (bio->bi_iter.bi_size == 0) { @@ -550,7 +554,13 @@ } } -void md_flush_request(struct mddev *mddev, struct bio *bio) +/* + * Manages consolidation of flushes and submitting any flushes needed for + * a bio with REQ_PREFLUSH. Returns true if the bio is finished or is + * being finished in another context. Returns false if the flushing is + * complete but still needs the I/O portion of the bio to be processed. + */ +bool md_flush_request(struct mddev *mddev, struct bio *bio) { ktime_t start = ktime_get_boottime(); spin_lock_irq(&mddev->lock); @@ -575,9 +585,10 @@ bio_endio(bio); else { bio->bi_opf &= ~REQ_PREFLUSH; - mddev->pers->make_request(mddev, bio); + return false; } } + return true; } EXPORT_SYMBOL(md_flush_request); @@ -637,8 +648,35 @@ } EXPORT_SYMBOL_GPL(mddev_init); +static struct mddev *mddev_find_locked(dev_t unit) +{ + struct mddev *mddev; + + list_for_each_entry(mddev, &all_mddevs, all_mddevs) + if (mddev->unit == unit) + return mddev; + + return NULL; +} + static struct mddev *mddev_find(dev_t unit) { + struct mddev *mddev; + + if (MAJOR(unit) != MD_MAJOR) + unit &= ~((1 << MdpMinorShift) - 1); + + spin_lock(&all_mddevs_lock); + mddev = mddev_find_locked(unit); + if (mddev) + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); + + return mddev; +} + +static struct mddev *mddev_find_or_alloc(dev_t unit) +{ struct mddev *mddev, *new = NULL; if (unit && MAJOR(unit) != MD_MAJOR) @@ -648,13 +686,13 @@ spin_lock(&all_mddevs_lock); if (unit) { - list_for_each_entry(mddev, &all_mddevs, all_mddevs) - if (mddev->unit == unit) { - mddev_get(mddev); - spin_unlock(&all_mddevs_lock); - kfree(new); - return mddev; - } + mddev = mddev_find_locked(unit); + if (mddev) { + mddev_get(mddev); + spin_unlock(&all_mddevs_lock); + kfree(new); + return mddev; + } if (new) { list_add(&new->all_mddevs, &all_mddevs); @@ -680,12 +718,7 @@ return NULL; } - is_free = 1; - list_for_each_entry(mddev, &all_mddevs, all_mddevs) - if (mddev->unit == dev) { - is_free = 0; - break; - } + is_free = !mddev_find_locked(dev); } new->unit = dev; new->md_minor = MINOR(dev); @@ -853,10 +886,12 @@ } else clear_bit(LastDev, &rdev->flags); + bio_put(bio); + + rdev_dec_pending(rdev, mddev); + if (atomic_dec_and_test(&mddev->pending_writes)) wake_up(&mddev->sb_wait); - rdev_dec_pending(rdev, mddev); - bio_put(bio); } void md_super_write(struct mddev *mddev, struct md_rdev *rdev, @@ -1063,6 +1098,7 @@ struct md_rdev *refdev, int minor_version); int (*validate_super)(struct mddev *mddev, + struct md_rdev *freshest, struct md_rdev *rdev); void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); @@ -1098,6 +1134,7 @@ char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; mdp_super_t *sb; int ret; + bool spare_disk = true; /* * Calculate the position of the superblock (512byte sectors), @@ -1148,8 +1185,19 @@ else rdev->desc_nr = sb->this_disk.number; + /* not spare disk, or LEVEL_MULTIPATH */ + if (sb->level == LEVEL_MULTIPATH || + (rdev->desc_nr >= 0 && + rdev->desc_nr < MD_SB_DISKS && + sb->disks[rdev->desc_nr].state & + ((1<sb_page); @@ -1165,7 +1213,8 @@ } ev1 = md_event(sb); ev2 = md_event(refsb); - if (ev1 > ev2) + + if (!spare_disk && ev1 > ev2) ret = 1; else ret = 0; @@ -1188,8 +1237,9 @@ /* * validate_super for 0.90.0 + * note: we are not using "freshest" for 0.9 superblock */ -static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) +static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) { mdp_disk_t *desc; mdp_super_t *sb = page_address(rdev->sb_page); @@ -1525,6 +1575,7 @@ sector_t sectors; char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; int bmask; + bool spare_disk = true; /* * Calculate the position of the superblock in 512byte sectors. @@ -1658,8 +1709,19 @@ sb->level != 0) return -EINVAL; + /* not spare disk, or LEVEL_MULTIPATH */ + if (sb->level == cpu_to_le32(LEVEL_MULTIPATH) || + (rdev->desc_nr >= 0 && + rdev->desc_nr < le32_to_cpu(sb->max_dev) && + (le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX || + le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL))) + spare_disk = false; + if (!refdev) { - ret = 1; + if (!spare_disk) + ret = 1; + else + ret = 0; } else { __u64 ev1, ev2; struct mdp_superblock_1 *refsb = page_address(refdev->sb_page); @@ -1676,7 +1738,7 @@ ev1 = le64_to_cpu(sb->events); ev2 = le64_to_cpu(refsb->events); - if (ev1 > ev2) + if (!spare_disk && ev1 > ev2) ret = 1; else ret = 0; @@ -1692,7 +1754,7 @@ return ret; } -static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) +static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) { struct mdp_superblock_1 *sb = page_address(rdev->sb_page); __u64 ev1 = le64_to_cpu(sb->events); @@ -1788,13 +1850,15 @@ } } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling, except for - * spares (which don't need an event count) */ - ++ev1; + * spares (which don't need an event count). + * Similar to mdadm, we allow event counter difference of 1 + * from the freshest device. + */ if (rdev->desc_nr >= 0 && rdev->desc_nr < le32_to_cpu(sb->max_dev) && (le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX || le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL)) - if (ev1 < mddev->events) + if (ev1 + 1 < mddev->events) return -EINVAL; } else if (mddev->bitmap) { /* If adding to array with a bitmap, then we can accept an @@ -1815,8 +1879,38 @@ rdev->desc_nr >= le32_to_cpu(sb->max_dev)) { role = MD_DISK_ROLE_SPARE; rdev->desc_nr = -1; - } else + } else if (mddev->pers == NULL && freshest && ev1 < mddev->events) { + /* + * If we are assembling, and our event counter is smaller than the + * highest event counter, we cannot trust our superblock about the role. + * It could happen that our rdev was marked as Faulty, and all other + * superblocks were updated with +1 event counter. + * Then, before the next superblock update, which typically happens when + * remove_and_add_spares() removes the device from the array, there was + * a crash or reboot. + * If we allow current rdev without consulting the freshest superblock, + * we could cause data corruption. + * Note that in this case our event counter is smaller by 1 than the + * highest, otherwise, this rdev would not be allowed into array; + * both kernel and mdadm allow event counter difference of 1. + */ + struct mdp_superblock_1 *freshest_sb = page_address(freshest->sb_page); + u32 freshest_max_dev = le32_to_cpu(freshest_sb->max_dev); + + if (rdev->desc_nr >= freshest_max_dev) { + /* this is unexpected, better not proceed */ + pr_warn("md: %s: rdev[%pg]: desc_nr(%d) >= freshest(%pg)->sb->max_dev(%u)\n", + mdname(mddev), rdev->bdev, rdev->desc_nr, + freshest->bdev, freshest_max_dev); + return -EUCLEAN; + } + + role = le16_to_cpu(freshest_sb->dev_roles[rdev->desc_nr]); + pr_debug("md: %s: rdev[%pg]: role=%d(0x%x) according to freshest %pg\n", + mdname(mddev), rdev->bdev, role, role, freshest->bdev); + } else { role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); + } switch(role) { case MD_DISK_ROLE_SPARE: /* spare */ break; @@ -2475,14 +2569,16 @@ static bool does_sb_need_changing(struct mddev *mddev) { - struct md_rdev *rdev; + struct md_rdev *rdev = NULL, *iter; struct mdp_superblock_1 *sb; int role; /* Find a good rdev */ - rdev_for_each(rdev, mddev) - if ((rdev->raid_disk >= 0) && !test_bit(Faulty, &rdev->flags)) + rdev_for_each(iter, mddev) + if ((iter->raid_disk >= 0) && !test_bit(Faulty, &iter->flags)) { + rdev = iter; break; + } /* No good device found. */ if (!rdev) @@ -2718,7 +2814,7 @@ * and should be added immediately. */ super_types[mddev->major_version]. - validate_super(mddev, rdev); + validate_super(mddev, NULL/*freshest*/, rdev); if (add_journal) mddev_suspend(mddev); err = mddev->pers->hot_add_disk(mddev, rdev); @@ -3020,6 +3116,9 @@ err = kstrtouint(buf, 10, (unsigned int *)&slot); if (err < 0) return err; + if (slot < 0) + /* overflow */ + return -ENOSPC; } if (rdev->mddev->pers && slot == -1) { /* Setting 'slot' on an active array requires also @@ -3597,7 +3696,7 @@ * Check a full RAID array for plausibility */ -static void analyze_sbs(struct mddev *mddev) +static int analyze_sbs(struct mddev *mddev) { int i; struct md_rdev *rdev, *freshest, *tmp; @@ -3618,8 +3717,14 @@ md_kick_rdev_from_array(rdev); } + /* Cannot find a valid fresh disk */ + if (!freshest) { + pr_warn("md: cannot find a valid disk\n"); + return -EINVAL; + } + super_types[mddev->major_version]. - validate_super(mddev, freshest); + validate_super(mddev, NULL/*freshest*/, freshest); i = 0; rdev_for_each_safe(rdev, tmp, mddev) { @@ -3634,7 +3739,7 @@ } if (rdev != freshest) { if (super_types[mddev->major_version]. - validate_super(mddev, rdev)) { + validate_super(mddev, freshest, rdev)) { pr_warn("md: kicking non-fresh %s from array!\n", bdevname(rdev->bdev,b)); md_kick_rdev_from_array(rdev); @@ -3652,6 +3757,8 @@ clear_bit(In_sync, &rdev->flags); } } + + return 0; } /* Read a fixed-point number. @@ -3693,8 +3800,9 @@ static ssize_t safe_delay_show(struct mddev *mddev, char *page) { - int msec = (mddev->safemode_delay*1000)/HZ; - return sprintf(page, "%d.%03d\n", msec/1000, msec%1000); + unsigned int msec = ((unsigned long)mddev->safemode_delay*1000)/HZ; + + return sprintf(page, "%u.%03u\n", msec/1000, msec%1000); } static ssize_t safe_delay_store(struct mddev *mddev, const char *cbuf, size_t len) @@ -3706,7 +3814,7 @@ return -EINVAL; } - if (strict_strtoul_scaled(cbuf, &msec, 3) < 0) + if (strict_strtoul_scaled(cbuf, &msec, 3) < 0 || msec > UINT_MAX / HZ) return -EINVAL; if (msec == 0) mddev->safemode_delay = 0; @@ -4367,6 +4475,8 @@ rv = kstrtouint(buf, 10, &n); if (rv < 0) return rv; + if (n > INT_MAX) + return -EINVAL; atomic_set(&mddev->max_corr_read_errors, n); return len; } @@ -4667,11 +4777,21 @@ return -EINVAL; err = mddev_lock(mddev); if (!err) { - if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) + if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { err = -EBUSY; - else { + } else if (mddev->reshape_position == MaxSector || + mddev->pers->check_reshape == NULL || + mddev->pers->check_reshape(mddev)) { clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); err = mddev->pers->start_reshape(mddev); + } else { + /* + * If reshape is still in progress, and + * md_check_recovery() can continue to reshape, + * don't restart reshape because data can be + * corrupted for raid456. + */ + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); } mddev_unlock(mddev); } @@ -5393,7 +5513,7 @@ * writing to /sys/module/md_mod/parameters/new_array. */ static DEFINE_MUTEX(disks_mutex); - struct mddev *mddev = mddev_find(dev); + struct mddev *mddev = mddev_find_or_alloc(dev); struct gendisk *disk; int partitioned; int shift; @@ -5470,10 +5590,6 @@ */ disk->flags |= GENHD_FL_EXT_DEVT; mddev->gendisk = disk; - /* As soon as we call add_disk(), another thread could get - * through to md_open, so make sure it doesn't get too far - */ - mutex_lock(&mddev->open_mutex); add_disk(disk); error = kobject_add(&mddev->kobj, &disk_to_dev(disk)->kobj, "%s", "md"); @@ -5488,7 +5604,6 @@ if (mddev->kobj.sd && sysfs_create_group(&mddev->kobj, &md_bitmap_group)) pr_debug("pointless warning\n"); - mutex_unlock(&mddev->open_mutex); abort: mutex_unlock(&disks_mutex); if (!error && mddev->kobj.sd) { @@ -5570,7 +5685,9 @@ if (!mddev->raid_disks) { if (!mddev->persistent) return -EINVAL; - analyze_sbs(mddev); + err = analyze_sbs(mddev); + if (err) + return -EINVAL; } if (mddev->level != LEVEL_NONE) @@ -5998,7 +6115,7 @@ static void mddev_detach(struct mddev *mddev) { md_bitmap_wait_behind_writes(mddev); - if (mddev->pers && mddev->pers->quiesce) { + if (mddev->pers && mddev->pers->quiesce && !mddev->suspended) { mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 0); } @@ -6030,6 +6147,7 @@ /* stop the array and free an attached data structures. * This is called from dm-raid */ + __md_stop_writes(mddev); __md_stop(mddev); bioset_exit(&mddev->bio_set); bioset_exit(&mddev->sync_set); @@ -6267,11 +6385,9 @@ md_probe(dev, NULL, NULL); mddev = mddev_find(dev); - if (!mddev || !mddev->gendisk) { - if (mddev) - mddev_put(mddev); + if (!mddev) break; - } + if (mddev_lock(mddev)) pr_warn("md: %s locked, cannot run\n", mdname(mddev)); else if (mddev->raid_disks || mddev->major_version @@ -6528,7 +6644,7 @@ rdev->saved_raid_disk = rdev->raid_disk; } else super_types[mddev->major_version]. - validate_super(mddev, rdev); + validate_super(mddev, NULL/*freshest*/, rdev); if ((info->state & (1<raid_disk != info->raid_disk) { /* This was a hot-add request, but events doesn't @@ -6678,8 +6794,10 @@ goto busy; kick_rdev: - if (mddev_is_clustered(mddev)) - md_cluster_ops->remove_disk(mddev, rdev); + if (mddev_is_clustered(mddev)) { + if (md_cluster_ops->remove_disk(mddev, rdev)) + goto busy; + } md_kick_rdev_from_array(rdev); set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags); @@ -7009,6 +7127,7 @@ return -EINVAL; if (mddev->sync_thread || test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || + test_bit(MD_RESYNCING_REMOTE, &mddev->recovery) || mddev->reshape_position != MaxSector) return -EBUSY; @@ -7277,11 +7396,6 @@ mddev = bdev->bd_disk->private_data; - if (!mddev) { - BUG(); - goto out; - } - /* Some actions do not requires the mutex */ switch (cmd) { case GET_ARRAY_INFO: @@ -7328,8 +7442,11 @@ err = -EBUSY; goto out; } - WARN_ON_ONCE(test_bit(MD_CLOSING, &mddev->flags)); - set_bit(MD_CLOSING, &mddev->flags); + if (test_and_set_bit(MD_CLOSING, &mddev->flags)) { + mutex_unlock(&mddev->open_mutex); + err = -EBUSY; + goto out; + } did_set_md_closing = true; mutex_unlock(&mddev->open_mutex); sync_blockdev(bdev); @@ -7565,9 +7682,9 @@ */ mddev_put(mddev); /* Wait until bdev->bd_disk is definitely gone */ - flush_workqueue(md_misc_wq); - /* Then retry the open from the top */ - return -ERESTARTSYS; + if (work_pending(&mddev->del_work)) + flush_workqueue(md_misc_wq); + return -EBUSY; } BUG_ON(mddev != bdev->bd_disk->private_data); @@ -7709,17 +7826,22 @@ void md_unregister_thread(struct md_thread **threadp) { - struct md_thread *thread = *threadp; - if (!thread) - return; - pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); - /* Locking ensures that mddev_unlock does not wake_up a + struct md_thread *thread; + + /* + * Locking ensures that mddev_unlock does not wake_up a * non-existent thread */ spin_lock(&pers_lock); + thread = *threadp; + if (!thread) { + spin_unlock(&pers_lock); + return; + } *threadp = NULL; spin_unlock(&pers_lock); + pr_debug("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); kthread_stop(thread->tsk); kfree(thread); } @@ -7900,7 +8022,11 @@ loff_t l = *pos; struct mddev *mddev; - if (l >= 0x10000) + if (l == 0x10000) { + ++*pos; + return (void *)2; + } + if (l > 0x10000) return NULL; if (!l--) /* header */ @@ -8319,6 +8445,26 @@ EXPORT_SYMBOL(md_write_end); +/* This is used by raid0 and raid10 */ +void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, + struct bio *bio, sector_t start, sector_t size) +{ + struct bio *discard_bio = NULL; + + if (__blkdev_issue_discard(rdev->bdev, start, size, GFP_NOIO, 0, + &discard_bio) || !discard_bio) + return; + + bio_chain(discard_bio, bio); + bio_clone_blkg_association(discard_bio, bio); + if (mddev->gendisk) + trace_block_bio_remap(bdev_get_queue(rdev->bdev), + discard_bio, disk_devt(mddev->gendisk), + bio->bi_iter.bi_sector); + generic_make_request(discard_bio); +} +EXPORT_SYMBOL_GPL(md_submit_discard_bio); + /* md_allow_write(mddev) * Calling this ensures that the array is marked 'active' so that writes * may proceed without blocking. It is important to call this before @@ -8997,11 +9143,11 @@ } if (mddev_is_clustered(mddev)) { - struct md_rdev *rdev; + struct md_rdev *rdev, *tmp; /* kick the device if another node issued a * remove disk. */ - rdev_for_each(rdev, mddev) { + rdev_for_each_safe(rdev, tmp, mddev) { if (test_and_clear_bit(ClusterRemove, &rdev->flags) && rdev->raid_disk < 0) md_kick_rdev_from_array(rdev); @@ -9314,7 +9460,7 @@ static void check_sb_changes(struct mddev *mddev, struct md_rdev *rdev) { struct mdp_superblock_1 *sb = page_address(rdev->sb_page); - struct md_rdev *rdev2; + struct md_rdev *rdev2, *tmp; int role, ret; char b[BDEVNAME_SIZE]; @@ -9331,7 +9477,7 @@ } /* Check for change of roles in the active devices */ - rdev_for_each(rdev2, mddev) { + rdev_for_each_safe(rdev2, tmp, mddev) { if (test_bit(Faulty, &rdev2->flags)) continue; @@ -9376,8 +9522,11 @@ } } - if (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) - update_raid_disks(mddev, le32_to_cpu(sb->raid_disks)); + if (mddev->raid_disks != le32_to_cpu(sb->raid_disks)) { + ret = update_raid_disks(mddev, le32_to_cpu(sb->raid_disks)); + if (ret) + pr_warn("md: updating array disks failed. %d\n", ret); + } /* * Since mddev->delta_disks has already updated in update_raid_disks, @@ -9456,16 +9605,18 @@ void md_reload_sb(struct mddev *mddev, int nr) { - struct md_rdev *rdev; + struct md_rdev *rdev = NULL, *iter; int err; /* Find the rdev */ - rdev_for_each_rcu(rdev, mddev) { - if (rdev->desc_nr == nr) + rdev_for_each_rcu(iter, mddev) { + if (iter->desc_nr == nr) { + rdev = iter; break; + } } - if (!rdev || rdev->desc_nr != nr) { + if (!rdev) { pr_warn("%s: %d Could not find rdev with nr %d\n", __func__, __LINE__, nr); return; } --- linux-oracle-5.4.0.orig/drivers/md/md.h +++ linux-oracle-5.4.0/drivers/md/md.h @@ -550,7 +550,7 @@ int level; struct list_head list; struct module *owner; - bool (*make_request)(struct mddev *mddev, struct bio *bio); + bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio); /* * start up works that do NOT require md_thread. tasks that * requires md_thread should go into start() @@ -701,9 +701,11 @@ extern void md_done_sync(struct mddev *mddev, int blocks, int ok); extern void md_error(struct mddev *mddev, struct md_rdev *rdev); extern void md_finish_reshape(struct mddev *mddev); +void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, + struct bio *bio, sector_t start, sector_t size); extern int mddev_congested(struct mddev *mddev, int bits); -extern void md_flush_request(struct mddev *mddev, struct bio *bio); +extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio); extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev, sector_t sector, int size, struct page *page); extern int md_super_wait(struct mddev *mddev); --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-array.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-array.c @@ -907,23 +907,27 @@ if (c->block) unlock_ablock(c->info, c->block); - c->block = NULL; - c->ab = NULL; c->index = 0; r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le); if (r) { DMERR("dm_btree_cursor_get_value failed"); - dm_btree_cursor_end(&c->cursor); + goto out; } else { r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab); if (r) { DMERR("get_ablock failed"); - dm_btree_cursor_end(&c->cursor); + goto out; } } + return 0; + +out: + dm_btree_cursor_end(&c->cursor); + c->block = NULL; + c->ab = NULL; return r; } @@ -946,10 +950,10 @@ void dm_array_cursor_end(struct dm_array_cursor *c) { - if (c->block) { + if (c->block) unlock_ablock(c->info, c->block); - dm_btree_cursor_end(&c->cursor); - } + + dm_btree_cursor_end(&c->cursor); } EXPORT_SYMBOL_GPL(dm_array_cursor_end); @@ -989,6 +993,7 @@ } count -= remaining; + c->index += (remaining - 1); r = dm_array_cursor_next(c); } while (!r); --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-block-manager.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-block-manager.c @@ -493,7 +493,7 @@ void *p; int r; - if (bm->read_only) + if (dm_bm_is_read_only(bm)) return -EPERM; p = dm_bufio_read(bm->bufio, b, (struct dm_buffer **) result); @@ -562,7 +562,7 @@ struct buffer_aux *aux; void *p; - if (bm->read_only) + if (dm_bm_is_read_only(bm)) return -EPERM; p = dm_bufio_new(bm->bufio, b, (struct dm_buffer **) result); @@ -602,7 +602,7 @@ int dm_bm_flush(struct dm_block_manager *bm) { - if (bm->read_only) + if (dm_bm_is_read_only(bm)) return -EPERM; return dm_bufio_write_dirty_buffers(bm->bufio); @@ -616,19 +616,21 @@ bool dm_bm_is_read_only(struct dm_block_manager *bm) { - return bm->read_only; + return (bm ? bm->read_only : true); } EXPORT_SYMBOL_GPL(dm_bm_is_read_only); void dm_bm_set_read_only(struct dm_block_manager *bm) { - bm->read_only = true; + if (bm) + bm->read_only = true; } EXPORT_SYMBOL_GPL(dm_bm_set_read_only); void dm_bm_set_read_write(struct dm_block_manager *bm) { - bm->read_only = false; + if (bm) + bm->read_only = false; } EXPORT_SYMBOL_GPL(dm_bm_set_read_write); --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-btree-internal.h +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-btree-internal.h @@ -34,12 +34,12 @@ __le32 max_entries; __le32 value_size; __le32 padding; -} __packed; +} __attribute__((packed, aligned(8))); struct btree_node { struct node_header header; __le64 keys[0]; -} __packed; +} __attribute__((packed, aligned(8))); /* --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-btree-remove.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-btree-remove.c @@ -203,7 +203,13 @@ struct btree_node *right = r->n; uint32_t nr_left = le32_to_cpu(left->header.nr_entries); uint32_t nr_right = le32_to_cpu(right->header.nr_entries); - unsigned threshold = 2 * merge_threshold(left) + 1; + /* + * Ensure the number of entries in each child will be greater + * than or equal to (max_entries / 3 + 1), so no matter which + * child is used for removal, the number will still be not + * less than (max_entries / 3). + */ + unsigned int threshold = 2 * (merge_threshold(left) + 1); if (nr_left + nr_right < threshold) { /* @@ -417,9 +423,9 @@ memcpy(n, dm_block_data(child), dm_bm_block_size(dm_tm_get_bm(info->tm))); - dm_tm_unlock(info->tm, child); dm_tm_dec(info->tm, dm_block_location(child)); + dm_tm_unlock(info->tm, child); return 0; } @@ -543,7 +549,8 @@ delete_at(n, index); } - *new_root = shadow_root(&spine); + if (!r) + *new_root = shadow_root(&spine); exit_shadow_spine(&spine); return r; --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-btree.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-btree.c @@ -83,14 +83,16 @@ } static int insert_at(size_t value_size, struct btree_node *node, unsigned index, - uint64_t key, void *value) - __dm_written_to_disk(value) + uint64_t key, void *value) + __dm_written_to_disk(value) { uint32_t nr_entries = le32_to_cpu(node->header.nr_entries); + uint32_t max_entries = le32_to_cpu(node->header.max_entries); __le64 key_le = cpu_to_le64(key); if (index > nr_entries || - index >= le32_to_cpu(node->header.max_entries)) { + index >= max_entries || + nr_entries >= max_entries) { DMERR("too many entries in btree node for insert"); __dm_unbless_for_disk(value); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-space-map-common.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-space-map-common.c @@ -281,6 +281,11 @@ struct disk_index_entry ie_disk; struct dm_block *blk; + if (b >= ll->nr_blocks) { + DMERR_LIMIT("metadata block out of bounds"); + return -EINVAL; + } + b = do_div(index, ll->entries_per_block); r = ll->load_ie(ll, index, &ie_disk); if (r < 0) @@ -339,6 +344,8 @@ */ begin = do_div(index_begin, ll->entries_per_block); end = do_div(end, ll->entries_per_block); + if (end == 0) + end = ll->entries_per_block; for (i = index_begin; i < index_end; i++, begin = 0) { struct dm_block *blk; @@ -380,6 +387,33 @@ return -ENOSPC; } +int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, + dm_block_t begin, dm_block_t end, dm_block_t *b) +{ + int r; + uint32_t count; + + do { + r = sm_ll_find_free_block(new_ll, begin, new_ll->nr_blocks, b); + if (r) + break; + + /* double check this block wasn't used in the old transaction */ + if (*b >= old_ll->nr_blocks) + count = 0; + else { + r = sm_ll_lookup(old_ll, *b, &count); + if (r) + break; + + if (count) + begin = *b + 1; + } + } while (count); + + return r; +} + static int sm_ll_mutate(struct ll_disk *ll, dm_block_t b, int (*mutator)(void *context, uint32_t old, uint32_t *new), void *context, enum allocation_event *ev) --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-space-map-common.h +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-space-map-common.h @@ -33,7 +33,7 @@ __le64 blocknr; __le32 nr_free; __le32 none_free_before; -} __packed; +} __attribute__ ((packed, aligned(8))); #define MAX_METADATA_BITMAPS 255 @@ -43,7 +43,7 @@ __le64 blocknr; struct disk_index_entry index[MAX_METADATA_BITMAPS]; -} __packed; +} __attribute__ ((packed, aligned(8))); struct ll_disk; @@ -86,7 +86,7 @@ __le64 nr_allocated; __le64 bitmap_root; __le64 ref_count_root; -} __packed; +} __attribute__ ((packed, aligned(8))); #define ENTRIES_PER_BYTE 4 @@ -94,7 +94,7 @@ __le32 csum; __le32 not_used; __le64 blocknr; -} __packed; +} __attribute__ ((packed, aligned(8))); enum allocation_event { SM_NONE, @@ -109,6 +109,8 @@ int sm_ll_lookup(struct ll_disk *ll, dm_block_t b, uint32_t *result); int sm_ll_find_free_block(struct ll_disk *ll, dm_block_t begin, dm_block_t end, dm_block_t *result); +int sm_ll_find_common_free_block(struct ll_disk *old_ll, struct ll_disk *new_ll, + dm_block_t begin, dm_block_t end, dm_block_t *result); int sm_ll_insert(struct ll_disk *ll, dm_block_t b, uint32_t ref_count, enum allocation_event *ev); int sm_ll_inc(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev); int sm_ll_dec(struct ll_disk *ll, dm_block_t b, enum allocation_event *ev); --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-space-map-disk.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-space-map-disk.c @@ -167,8 +167,18 @@ enum allocation_event ev; struct sm_disk *smd = container_of(sm, struct sm_disk, sm); - /* FIXME: we should loop round a couple of times */ - r = sm_ll_find_free_block(&smd->old_ll, smd->begin, smd->old_ll.nr_blocks, b); + /* + * Any block we allocate has to be free in both the old and current ll. + */ + r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smd->begin and the end of the metadata device. + * We search before smd->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, 0, smd->begin, b); + } + if (r) return r; @@ -197,7 +207,6 @@ return r; memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll)); - smd->begin = 0; smd->nr_allocated_this_transaction = 0; r = sm_disk_get_nr_free(sm, &nr_free); --- linux-oracle-5.4.0.orig/drivers/md/persistent-data/dm-space-map-metadata.c +++ linux-oracle-5.4.0/drivers/md/persistent-data/dm-space-map-metadata.c @@ -275,7 +275,7 @@ { struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); - kfree(smm); + kvfree(smm); } static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) @@ -448,7 +448,18 @@ enum allocation_event ev; struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); - r = sm_ll_find_free_block(&smm->old_ll, smm->begin, smm->old_ll.nr_blocks, b); + /* + * Any block we allocate has to be free in both the old and current ll. + */ + r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smm->begin and the end of the metadata device. + * We search before smm->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b); + } + if (r) return r; @@ -500,7 +511,6 @@ return r; memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); - smm->begin = 0; smm->allocated_this_transaction = 0; return 0; @@ -749,7 +759,7 @@ { struct sm_metadata *smm; - smm = kmalloc(sizeof(*smm), GFP_KERNEL); + smm = kvmalloc(sizeof(*smm), GFP_KERNEL); if (!smm) return ERR_PTR(-ENOMEM); --- linux-oracle-5.4.0.orig/drivers/md/raid0.c +++ linux-oracle-5.4.0/drivers/md/raid0.c @@ -63,7 +63,7 @@ int len = 0; for (k = 0; k < conf->strip_zone[j].nb_dev; k++) - len += snprintf(line+len, 200-len, "%s%s", k?"/":"", + len += scnprintf(line+len, 200-len, "%s%s", k?"/":"", bdevname(conf->devlist[j*raid_disks + k]->bdev, b)); pr_debug("md: zone%d=[%s]\n", j, line); @@ -87,7 +87,7 @@ char b[BDEVNAME_SIZE]; char b2[BDEVNAME_SIZE]; struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); - unsigned short blksize = 512; + unsigned blksize = 512; *private_conf = ERR_PTR(-ENOMEM); if (!conf) @@ -143,21 +143,6 @@ pr_debug("md/raid0:%s: FINAL %d zones\n", mdname(mddev), conf->nr_strip_zones); - if (conf->nr_strip_zones == 1) { - conf->layout = RAID0_ORIG_LAYOUT; - } else if (mddev->layout == RAID0_ORIG_LAYOUT || - mddev->layout == RAID0_ALT_MULTIZONE_LAYOUT) { - conf->layout = mddev->layout; - } else if (default_layout == RAID0_ORIG_LAYOUT || - default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { - conf->layout = default_layout; - } else { - pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", - mdname(mddev)); - pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n"); - err = -ENOTSUPP; - goto abort; - } /* * now since we have the hard sector sizes, we can make sure * chunk size is a multiple of that sector size @@ -288,6 +273,36 @@ (unsigned long long)smallest->sectors); } + if (conf->nr_strip_zones == 1 || conf->strip_zone[1].nb_dev == 1) { + conf->layout = RAID0_ORIG_LAYOUT; + } else if (mddev->layout == RAID0_ORIG_LAYOUT || + mddev->layout == RAID0_ALT_MULTIZONE_LAYOUT) { + conf->layout = mddev->layout; + } else if (default_layout == RAID0_ORIG_LAYOUT || + default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { + conf->layout = default_layout; + } else { + pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", + mdname(mddev)); + pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n"); + pr_err("md/raid0: Read the following page for more information:\n"); + pr_err("md/raid0: https://wiki.ubuntu.com/Kernel/Raid0LayoutMigration\n"); + err = -EOPNOTSUPP; + goto abort; + } + + if (conf->layout == RAID0_ORIG_LAYOUT) { + for (i = 1; i < conf->nr_strip_zones; i++) { + sector_t first_sector = conf->strip_zone[i-1].zone_end; + + sector_div(first_sector, mddev->chunk_sectors); + zone = conf->strip_zone + i; + /* disk_shift is first disk index used in the zone */ + zone->disk_shift = sector_div(first_sector, + zone->nb_dev); + } + } + pr_debug("md/raid0:%s: done.\n", mdname(mddev)); *private_conf = conf; @@ -474,6 +489,20 @@ } } +/* + * Convert disk_index to the disk order in which it is read/written. + * For example, if we have 4 disks, they are numbered 0,1,2,3. If we + * write the disks starting at disk 3, then the read/write order would + * be disk 3, then 0, then 1, and then disk 2 and we want map_disk_shift() + * to map the disks as follows 0,1,2,3 => 1,2,3,0. So disk 0 would map + * to 1, 1 to 2, 2 to 3, and 3 to 0. That way we can compare disks in + * that 'output' space to understand the read/write disk ordering. + */ +static int map_disk_shift(int disk_index, int num_disks, int disk_shift) +{ + return ((disk_index + num_disks - disk_shift) % num_disks); +} + static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) { struct r0conf *conf = mddev->private; @@ -487,7 +516,9 @@ sector_t end_disk_offset; unsigned int end_disk_index; unsigned int disk; + sector_t orig_start, orig_end; + orig_start = start; zone = find_zone(conf, &start); if (bio_end_sector(bio) > zone->zone_end) { @@ -501,6 +532,7 @@ } else end = bio_end_sector(bio); + orig_end = end; if (zone != conf->strip_zone) end = end - zone[-1].zone_end; @@ -512,33 +544,49 @@ last_stripe_index = end; sector_div(last_stripe_index, stripe_size); - start_disk_index = (int)(start - first_stripe_index * stripe_size) / - mddev->chunk_sectors; + /* In the first zone the original and alternate layouts are the same */ + if ((conf->layout == RAID0_ORIG_LAYOUT) && (zone != conf->strip_zone)) { + sector_div(orig_start, mddev->chunk_sectors); + start_disk_index = sector_div(orig_start, zone->nb_dev); + start_disk_index = map_disk_shift(start_disk_index, + zone->nb_dev, + zone->disk_shift); + sector_div(orig_end, mddev->chunk_sectors); + end_disk_index = sector_div(orig_end, zone->nb_dev); + end_disk_index = map_disk_shift(end_disk_index, + zone->nb_dev, zone->disk_shift); + } else { + start_disk_index = (int)(start - first_stripe_index * stripe_size) / + mddev->chunk_sectors; + end_disk_index = (int)(end - last_stripe_index * stripe_size) / + mddev->chunk_sectors; + } start_disk_offset = ((int)(start - first_stripe_index * stripe_size) % mddev->chunk_sectors) + first_stripe_index * mddev->chunk_sectors; - end_disk_index = (int)(end - last_stripe_index * stripe_size) / - mddev->chunk_sectors; end_disk_offset = ((int)(end - last_stripe_index * stripe_size) % mddev->chunk_sectors) + last_stripe_index * mddev->chunk_sectors; for (disk = 0; disk < zone->nb_dev; disk++) { sector_t dev_start, dev_end; - struct bio *discard_bio = NULL; struct md_rdev *rdev; + int compare_disk; + + compare_disk = map_disk_shift(disk, zone->nb_dev, + zone->disk_shift); - if (disk < start_disk_index) + if (compare_disk < start_disk_index) dev_start = (first_stripe_index + 1) * mddev->chunk_sectors; - else if (disk > start_disk_index) + else if (compare_disk > start_disk_index) dev_start = first_stripe_index * mddev->chunk_sectors; else dev_start = start_disk_offset; - if (disk < end_disk_index) + if (compare_disk < end_disk_index) dev_end = (last_stripe_index + 1) * mddev->chunk_sectors; - else if (disk > end_disk_index) + else if (compare_disk > end_disk_index) dev_end = last_stripe_index * mddev->chunk_sectors; else dev_end = end_disk_offset; @@ -548,18 +596,9 @@ rdev = conf->devlist[(zone - conf->strip_zone) * conf->strip_zone[0].nb_dev + disk]; - if (__blkdev_issue_discard(rdev->bdev, + md_submit_discard_bio(mddev, rdev, bio, dev_start + zone->dev_start + rdev->data_offset, - dev_end - dev_start, GFP_NOIO, 0, &discard_bio) || - !discard_bio) - continue; - bio_chain(discard_bio, bio); - bio_clone_blkg_association(discard_bio, bio); - if (mddev->gendisk) - trace_block_bio_remap(bdev_get_queue(rdev->bdev), - discard_bio, disk_devt(mddev->gendisk), - bio->bi_iter.bi_sector); - generic_make_request(discard_bio); + dev_end - dev_start); } bio_endio(bio); } @@ -575,10 +614,9 @@ unsigned chunk_sects; unsigned sectors; - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - } if (unlikely((bio_op(bio) == REQ_OP_DISCARD))) { raid0_handle_discard(mddev, bio); @@ -615,7 +653,7 @@ tmp_dev = map_sector(mddev, zone, sector, §or); break; default: - WARN("md/raid0:%s: Invalid layout\n", mdname(mddev)); + WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev)); bio_io_error(bio); return true; } --- linux-oracle-5.4.0.orig/drivers/md/raid0.h +++ linux-oracle-5.4.0/drivers/md/raid0.h @@ -6,6 +6,7 @@ sector_t zone_end; /* Start of the next zone (in sectors) */ sector_t dev_start; /* Zone offset in real dev (in sectors) */ int nb_dev; /* # of devices attached to the zone */ + int disk_shift; /* start disk for the original layout */ }; /* Linux 3.14 (20d0189b101) made an unintended change to --- linux-oracle-5.4.0.orig/drivers/md/raid1.c +++ linux-oracle-5.4.0/drivers/md/raid1.c @@ -452,12 +452,12 @@ /* * When the device is faulty, it is not necessary to * handle write error. - * For failfast, this is the only remaining device, - * We need to retry the write without FailFast. */ if (!test_bit(Faulty, &rdev->flags)) set_bit(R1BIO_WriteError, &r1_bio->state); else { + /* Fail the request */ + set_bit(R1BIO_Degraded, &r1_bio->state); /* Finished with this branch */ r1_bio->bios[mirror] = NULL; to_put = bio; @@ -1567,10 +1567,9 @@ { sector_t sectors; - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - } /* * There is a limit to the maximum size, but @@ -1811,6 +1810,9 @@ int number = rdev->raid_disk; struct raid1_info *p = conf->mirrors + number; + if (unlikely(number >= conf->raid_disks)) + goto abort; + if (rdev != p->rdev) p = conf->mirrors + conf->raid_disks + number; @@ -2782,7 +2784,7 @@ write_targets++; } } - if (bio->bi_end_io) { + if (rdev && bio->bi_end_io) { atomic_inc(&rdev->nr_pending); bio->bi_iter.bi_sector = sector_nr + rdev->data_offset; bio_set_dev(bio, rdev->bdev); @@ -3133,6 +3135,7 @@ * RAID1 needs at least one disk in active */ if (conf->raid_disks - mddev->degraded < 1) { + md_unregister_thread(&conf->thread); ret = -EINVAL; goto abort; } --- linux-oracle-5.4.0.orig/drivers/md/raid10.c +++ linux-oracle-5.4.0/drivers/md/raid10.c @@ -91,7 +91,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) { struct r10conf *conf = data; - int size = offsetof(struct r10bio, devs[conf->copies]); + int size = offsetof(struct r10bio, devs[conf->geo.raid_disks]); /* allocate a r10bio with room for raid_disks entries in the * bios array */ @@ -191,7 +191,7 @@ out_free_pages: while (--j >= 0) - resync_free_pages(&rps[j * 2]); + resync_free_pages(&rps[j]); j = 0; out_free_bio: @@ -238,7 +238,7 @@ { int i; - for (i = 0; i < conf->copies; i++) { + for (i = 0; i < conf->geo.raid_disks; i++) { struct bio **bio = & r10_bio->devs[i].bio; if (!BIO_SPECIAL(*bio)) bio_put(*bio); @@ -327,7 +327,7 @@ int slot; int repl = 0; - for (slot = 0; slot < conf->copies; slot++) { + for (slot = 0; slot < conf->geo.raid_disks; slot++) { if (r10_bio->devs[slot].bio == bio) break; if (r10_bio->devs[slot].repl_bio == bio) { @@ -336,7 +336,6 @@ } } - BUG_ON(slot == conf->copies); update_head_pos(slot, r10_bio); if (slotp) @@ -470,12 +469,12 @@ /* * When the device is faulty, it is not necessary to * handle write error. - * For failfast, this is the only remaining device, - * We need to retry the write without FailFast. */ if (!test_bit(Faulty, &rdev->flags)) set_bit(R10BIO_WriteError, &r10_bio->state); else { + /* Fail the request */ + set_bit(R10BIO_Degraded, &r10_bio->state); r10_bio->devs[slot].bio = NULL; to_put = bio; dec_rdev = 1; @@ -751,8 +750,16 @@ disk = r10_bio->devs[slot].devnum; rdev = rcu_dereference(conf->mirrors[disk].replacement); if (rdev == NULL || test_bit(Faulty, &rdev->flags) || - r10_bio->devs[slot].addr + sectors > rdev->recovery_offset) + r10_bio->devs[slot].addr + sectors > + rdev->recovery_offset) { + /* + * Read replacement first to prevent reading both rdev + * and replacement as NULL during replacement replace + * rdev. + */ + smp_mb(); rdev = rcu_dereference(conf->mirrors[disk].rdev); + } if (rdev == NULL || test_bit(Faulty, &rdev->flags)) continue; @@ -919,6 +926,7 @@ else generic_make_request(bio); bio = next; + cond_resched(); } blk_finish_plug(&plug); } else @@ -1104,6 +1112,7 @@ else generic_make_request(bio); bio = next; + cond_resched(); } kfree(plug); } @@ -1145,7 +1154,7 @@ struct md_rdev *err_rdev = NULL; gfp_t gfp = GFP_NOIO; - if (r10_bio->devs[slot].rdev) { + if (slot >= 0 && r10_bio->devs[slot].rdev) { /* * This is an error retry, but we cannot * safely dereference the rdev in the r10_bio, @@ -1293,12 +1302,77 @@ } } +static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio) +{ + int i; + struct r10conf *conf = mddev->private; + struct md_rdev *blocked_rdev; + +retry_wait: + blocked_rdev = NULL; + rcu_read_lock(); + for (i = 0; i < conf->copies; i++) { + struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); + struct md_rdev *rrdev = rcu_dereference( + conf->mirrors[i].replacement); + if (rdev == rrdev) + rrdev = NULL; + if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { + atomic_inc(&rdev->nr_pending); + blocked_rdev = rdev; + break; + } + if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) { + atomic_inc(&rrdev->nr_pending); + blocked_rdev = rrdev; + break; + } + + if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) { + sector_t first_bad; + sector_t dev_sector = r10_bio->devs[i].addr; + int bad_sectors; + int is_bad; + + /* + * Discard request doesn't care the write result + * so it doesn't need to wait blocked disk here. + */ + if (!r10_bio->sectors) + continue; + + is_bad = is_badblock(rdev, dev_sector, r10_bio->sectors, + &first_bad, &bad_sectors); + if (is_bad < 0) { + /* + * Mustn't write here until the bad block + * is acknowledged + */ + atomic_inc(&rdev->nr_pending); + set_bit(BlockedBadBlocks, &rdev->flags); + blocked_rdev = rdev; + break; + } + } + } + rcu_read_unlock(); + + if (unlikely(blocked_rdev)) { + /* Have to wait for this device to get unblocked, then retry */ + allow_barrier(conf); + raid10_log(conf->mddev, "%s wait rdev %d blocked", + __func__, blocked_rdev->raid_disk); + md_wait_for_blocked_rdev(blocked_rdev, mddev); + wait_barrier(conf); + goto retry_wait; + } +} + static void raid10_write_request(struct mddev *mddev, struct bio *bio, struct r10bio *r10_bio) { struct r10conf *conf = mddev->private; int i; - struct md_rdev *blocked_rdev; sector_t sectors; int max_sectors; @@ -1356,28 +1430,25 @@ r10_bio->read_slot = -1; /* make sure repl_bio gets freed */ raid10_find_phys(conf, r10_bio); -retry_write: - blocked_rdev = NULL; + + wait_blocked_dev(mddev, r10_bio); + rcu_read_lock(); max_sectors = r10_bio->sectors; for (i = 0; i < conf->copies; i++) { int d = r10_bio->devs[i].devnum; - struct md_rdev *rdev = rcu_dereference(conf->mirrors[d].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[d].replacement); + struct md_rdev *rdev, *rrdev; + + rrdev = rcu_dereference(conf->mirrors[d].replacement); + /* + * Read replacement first to prevent reading both rdev and + * replacement as NULL during replacement replace rdev. + */ + smp_mb(); + rdev = rcu_dereference(conf->mirrors[d].rdev); if (rdev == rrdev) rrdev = NULL; - if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { - atomic_inc(&rdev->nr_pending); - blocked_rdev = rdev; - break; - } - if (rrdev && unlikely(test_bit(Blocked, &rrdev->flags))) { - atomic_inc(&rrdev->nr_pending); - blocked_rdev = rrdev; - break; - } if (rdev && (test_bit(Faulty, &rdev->flags))) rdev = NULL; if (rrdev && (test_bit(Faulty, &rrdev->flags))) @@ -1398,15 +1469,6 @@ is_bad = is_badblock(rdev, dev_sector, max_sectors, &first_bad, &bad_sectors); - if (is_bad < 0) { - /* Mustn't write here until the bad block - * is acknowledged - */ - atomic_inc(&rdev->nr_pending); - set_bit(BlockedBadBlocks, &rdev->flags); - blocked_rdev = rdev; - break; - } if (is_bad && first_bad <= dev_sector) { /* Cannot write here at all */ bad_sectors -= (dev_sector - first_bad); @@ -1442,35 +1504,6 @@ } rcu_read_unlock(); - if (unlikely(blocked_rdev)) { - /* Have to wait for this device to get unblocked, then retry */ - int j; - int d; - - for (j = 0; j < i; j++) { - if (r10_bio->devs[j].bio) { - d = r10_bio->devs[j].devnum; - rdev_dec_pending(conf->mirrors[d].rdev, mddev); - } - if (r10_bio->devs[j].repl_bio) { - struct md_rdev *rdev; - d = r10_bio->devs[j].devnum; - rdev = conf->mirrors[d].replacement; - if (!rdev) { - /* Race with remove_disk */ - smp_mb(); - rdev = conf->mirrors[d].rdev; - } - rdev_dec_pending(rdev, mddev); - } - } - allow_barrier(conf); - raid10_log(conf->mddev, "wait rdev %d blocked", blocked_rdev->raid_disk); - md_wait_for_blocked_rdev(blocked_rdev, mddev); - wait_barrier(conf); - goto retry_write; - } - if (max_sectors < r10_bio->sectors) r10_bio->sectors = max_sectors; @@ -1510,7 +1543,9 @@ r10_bio->mddev = mddev; r10_bio->sector = bio->bi_iter.bi_sector; r10_bio->state = 0; - memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * conf->copies); + r10_bio->read_slot = -1; + memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * + conf->geo.raid_disks); if (bio_data_dir(bio) == READ) raid10_read_request(mddev, bio, r10_bio); @@ -1518,6 +1553,304 @@ raid10_write_request(mddev, bio, r10_bio); } +static void raid_end_discard_bio(struct r10bio *r10bio) +{ + struct r10conf *conf = r10bio->mddev->private; + struct r10bio *first_r10bio; + + while (atomic_dec_and_test(&r10bio->remaining)) { + + allow_barrier(conf); + + if (!test_bit(R10BIO_Discard, &r10bio->state)) { + first_r10bio = (struct r10bio *)r10bio->master_bio; + free_r10bio(r10bio); + r10bio = first_r10bio; + } else { + md_write_end(r10bio->mddev); + bio_endio(r10bio->master_bio); + free_r10bio(r10bio); + break; + } + } +} + +static void raid10_end_discard_request(struct bio *bio) +{ + struct r10bio *r10_bio = bio->bi_private; + struct r10conf *conf = r10_bio->mddev->private; + struct md_rdev *rdev = NULL; + int dev; + int slot, repl; + + /* + * We don't care the return value of discard bio + */ + if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) + set_bit(R10BIO_Uptodate, &r10_bio->state); + + dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl); + if (repl) + rdev = conf->mirrors[dev].replacement; + if (!rdev) { + /* + * raid10_remove_disk uses smp_mb to make sure rdev is set to + * replacement before setting replacement to NULL. It can read + * rdev first without barrier protect even replacment is NULL + */ + smp_rmb(); + rdev = conf->mirrors[dev].rdev; + } + + raid_end_discard_bio(r10_bio); + rdev_dec_pending(rdev, conf->mddev); +} + +/* + * There are some limitations to handle discard bio + * 1st, the discard size is bigger than stripe_size*2. + * 2st, if the discard bio spans reshape progress, we use the old way to + * handle discard bio + */ +static int raid10_handle_discard(struct mddev *mddev, struct bio *bio) +{ + struct r10conf *conf = mddev->private; + struct geom *geo = &conf->geo; + int far_copies = geo->far_copies; + bool first_copy = true; + struct r10bio *r10_bio, *first_r10bio; + struct bio *split; + int disk; + sector_t chunk; + unsigned int stripe_size; + unsigned int stripe_data_disks; + sector_t split_size; + sector_t bio_start, bio_end; + sector_t first_stripe_index, last_stripe_index; + sector_t start_disk_offset; + unsigned int start_disk_index; + sector_t end_disk_offset; + unsigned int end_disk_index; + unsigned int remainder; + + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) + return -EAGAIN; + + wait_barrier(conf); + + /* + * Check reshape again to avoid reshape happens after checking + * MD_RECOVERY_RESHAPE and before wait_barrier + */ + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) + goto out; + + if (geo->near_copies) + stripe_data_disks = geo->raid_disks / geo->near_copies + + geo->raid_disks % geo->near_copies; + else + stripe_data_disks = geo->raid_disks; + + stripe_size = stripe_data_disks << geo->chunk_shift; + + bio_start = bio->bi_iter.bi_sector; + bio_end = bio_end_sector(bio); + + /* + * Maybe one discard bio is smaller than strip size or across one + * stripe and discard region is larger than one stripe size. For far + * offset layout, if the discard region is not aligned with stripe + * size, there is hole when we submit discard bio to member disk. + * For simplicity, we only handle discard bio which discard region + * is bigger than stripe_size * 2 + */ + if (bio_sectors(bio) < stripe_size*2) + goto out; + + /* + * Keep bio aligned with strip size. + */ + div_u64_rem(bio_start, stripe_size, &remainder); + if (remainder) { + split_size = stripe_size - remainder; + split = bio_split(bio, split_size, GFP_NOIO, &conf->bio_split); + bio_chain(split, bio); + allow_barrier(conf); + /* Resend the fist split part */ + generic_make_request(split); + wait_barrier(conf); + } + div_u64_rem(bio_end, stripe_size, &remainder); + if (remainder) { + split_size = bio_sectors(bio) - remainder; + split = bio_split(bio, split_size, GFP_NOIO, &conf->bio_split); + bio_chain(split, bio); + allow_barrier(conf); + /* Resend the second split part */ + generic_make_request(bio); + bio = split; + wait_barrier(conf); + } + + bio_start = bio->bi_iter.bi_sector; + bio_end = bio_end_sector(bio); + + /* + * Raid10 uses chunk as the unit to store data. It's similar like raid0. + * One stripe contains the chunks from all member disk (one chunk from + * one disk at the same HBA address). For layout detail, see 'man md 4' + */ + chunk = bio_start >> geo->chunk_shift; + chunk *= geo->near_copies; + first_stripe_index = chunk; + start_disk_index = sector_div(first_stripe_index, geo->raid_disks); + if (geo->far_offset) + first_stripe_index *= geo->far_copies; + start_disk_offset = (bio_start & geo->chunk_mask) + + (first_stripe_index << geo->chunk_shift); + + chunk = bio_end >> geo->chunk_shift; + chunk *= geo->near_copies; + last_stripe_index = chunk; + end_disk_index = sector_div(last_stripe_index, geo->raid_disks); + if (geo->far_offset) + last_stripe_index *= geo->far_copies; + end_disk_offset = (bio_end & geo->chunk_mask) + + (last_stripe_index << geo->chunk_shift); + +retry_discard: + r10_bio = mempool_alloc(&conf->r10bio_pool, GFP_NOIO); + r10_bio->mddev = mddev; + r10_bio->state = 0; + r10_bio->sectors = 0; + memset(r10_bio->devs, 0, sizeof(r10_bio->devs[0]) * geo->raid_disks); + wait_blocked_dev(mddev, r10_bio); + + /* + * For far layout it needs more than one r10bio to cover all regions. + * Inspired by raid10_sync_request, we can use the first r10bio->master_bio + * to record the discard bio. Other r10bio->master_bio record the first + * r10bio. The first r10bio only release after all other r10bios finish. + * The discard bio returns only first r10bio finishes + */ + if (first_copy) { + r10_bio->master_bio = bio; + set_bit(R10BIO_Discard, &r10_bio->state); + first_copy = false; + first_r10bio = r10_bio; + } else + r10_bio->master_bio = (struct bio *)first_r10bio; + + rcu_read_lock(); + for (disk = 0; disk < geo->raid_disks; disk++) { + struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev); + struct md_rdev *rrdev = rcu_dereference( + conf->mirrors[disk].replacement); + + r10_bio->devs[disk].bio = NULL; + r10_bio->devs[disk].repl_bio = NULL; + + if (rdev && (test_bit(Faulty, &rdev->flags))) + rdev = NULL; + if (rrdev && (test_bit(Faulty, &rrdev->flags))) + rrdev = NULL; + if (!rdev && !rrdev) + continue; + + if (rdev) { + r10_bio->devs[disk].bio = bio; + atomic_inc(&rdev->nr_pending); + } + if (rrdev) { + r10_bio->devs[disk].repl_bio = bio; + atomic_inc(&rrdev->nr_pending); + } + } + rcu_read_unlock(); + + atomic_set(&r10_bio->remaining, 1); + for (disk = 0; disk < geo->raid_disks; disk++) { + sector_t dev_start, dev_end; + struct bio *mbio, *rbio = NULL; + struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev); + struct md_rdev *rrdev = rcu_dereference( + conf->mirrors[disk].replacement); + + /* + * Now start to calculate the start and end address for each disk. + * The space between dev_start and dev_end is the discard region. + * + * For dev_start, it needs to consider three conditions: + * 1st, the disk is before start_disk, you can imagine the disk in + * the next stripe. So the dev_start is the start address of next + * stripe. + * 2st, the disk is after start_disk, it means the disk is at the + * same stripe of first disk + * 3st, the first disk itself, we can use start_disk_offset directly + */ + if (disk < start_disk_index) + dev_start = (first_stripe_index + 1) * mddev->chunk_sectors; + else if (disk > start_disk_index) + dev_start = first_stripe_index * mddev->chunk_sectors; + else + dev_start = start_disk_offset; + + if (disk < end_disk_index) + dev_end = (last_stripe_index + 1) * mddev->chunk_sectors; + else if (disk > end_disk_index) + dev_end = last_stripe_index * mddev->chunk_sectors; + else + dev_end = end_disk_offset; + + /* + * It only handles discard bio which size is >= stripe size, so + * dev_end > dev_start all the time + */ + if (r10_bio->devs[disk].bio) { + mbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set); + mbio->bi_end_io = raid10_end_discard_request; + mbio->bi_private = r10_bio; + r10_bio->devs[disk].bio = mbio; + r10_bio->devs[disk].devnum = disk; + atomic_inc(&r10_bio->remaining); + md_submit_discard_bio(mddev, rdev, mbio, + dev_start + choose_data_offset(r10_bio, rdev), + dev_end - dev_start); + bio_endio(mbio); + } + if (r10_bio->devs[disk].repl_bio) { + rbio = bio_clone_fast(bio, GFP_NOIO, &mddev->bio_set); + rbio->bi_end_io = raid10_end_discard_request; + rbio->bi_private = r10_bio; + r10_bio->devs[disk].repl_bio = rbio; + r10_bio->devs[disk].devnum = disk; + atomic_inc(&r10_bio->remaining); + md_submit_discard_bio(mddev, rrdev, rbio, + dev_start + choose_data_offset(r10_bio, rrdev), + dev_end - dev_start); + bio_endio(rbio); + } + } + + if (!geo->far_offset && --far_copies) { + first_stripe_index += geo->stride >> geo->chunk_shift; + start_disk_offset += geo->stride; + last_stripe_index += geo->stride >> geo->chunk_shift; + end_disk_offset += geo->stride; + atomic_inc(&first_r10bio->remaining); + raid_end_discard_bio(r10_bio); + wait_barrier(conf); + goto retry_discard; + } + + raid_end_discard_bio(r10_bio); + + return 0; +out: + allow_barrier(conf); + return -EAGAIN; +} + static bool raid10_make_request(struct mddev *mddev, struct bio *bio) { struct r10conf *conf = mddev->private; @@ -1525,14 +1858,17 @@ int chunk_sects = chunk_mask + 1; int sectors = bio_sectors(bio); - if (unlikely(bio->bi_opf & REQ_PREFLUSH)) { - md_flush_request(mddev, bio); + if (unlikely(bio->bi_opf & REQ_PREFLUSH) + && md_flush_request(mddev, bio)) return true; - } if (!md_write_start(mddev, bio)) return false; + if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) + if (!raid10_handle_discard(mddev, bio)) + return true; + /* * If this request crosses a chunk boundary, we need to split * it. @@ -1826,9 +2162,12 @@ int err = 0; int number = rdev->raid_disk; struct md_rdev **rdevp; - struct raid10_info *p = conf->mirrors + number; + struct raid10_info *p; print_conf(conf); + if (unlikely(number >= mddev->raid_disks)) + return 0; + p = conf->mirrors + number; if (rdev == p->rdev) rdevp = &p->rdev; else if (rdev == p->replacement) @@ -2226,11 +2565,22 @@ { struct r10conf *conf = mddev->private; int d; - struct bio *wbio, *wbio2; + struct bio *wbio = r10_bio->devs[1].bio; + struct bio *wbio2 = r10_bio->devs[1].repl_bio; + + /* Need to test wbio2->bi_end_io before we call + * generic_make_request as if the former is NULL, + * the latter is free to free wbio2. + */ + if (wbio2 && !wbio2->bi_end_io) + wbio2 = NULL; if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) { fix_recovery_read_error(r10_bio); - end_sync_request(r10_bio); + if (wbio->bi_end_io) + end_sync_request(r10_bio); + if (wbio2) + end_sync_request(r10_bio); return; } @@ -2239,14 +2589,6 @@ * and submit the write request */ d = r10_bio->devs[1].devnum; - wbio = r10_bio->devs[1].bio; - wbio2 = r10_bio->devs[1].repl_bio; - /* Need to test wbio2->bi_end_io before we call - * generic_make_request as if the former is NULL, - * the latter is free to free wbio2. - */ - if (wbio2 && !wbio2->bi_end_io) - wbio2 = NULL; if (wbio->bi_end_io) { atomic_inc(&conf->mirrors[d].rdev->nr_pending); md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio)); @@ -2914,10 +3256,6 @@ sector_t chunk_mask = conf->geo.chunk_mask; int page_idx = 0; - if (!mempool_initialized(&conf->r10buf_pool)) - if (init_resync(conf)) - return 0; - /* * Allow skipping a full rebuild for incremental assembly * of a clean array, like RAID1 does. @@ -2933,6 +3271,10 @@ return mddev->dev_sectors - sector_nr; } + if (!mempool_initialized(&conf->r10buf_pool)) + if (init_resync(conf)) + return 0; + skipped: max_sector = mddev->dev_sectors; if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) || @@ -3047,8 +3389,6 @@ sector_t sect; int must_sync; int any_working; - int need_recover = 0; - int need_replace = 0; struct raid10_info *mirror = &conf->mirrors[i]; struct md_rdev *mrdev, *mreplace; @@ -3056,15 +3396,13 @@ mrdev = rcu_dereference(mirror->rdev); mreplace = rcu_dereference(mirror->replacement); - if (mrdev != NULL && - !test_bit(Faulty, &mrdev->flags) && - !test_bit(In_sync, &mrdev->flags)) - need_recover = 1; - if (mreplace != NULL && - !test_bit(Faulty, &mreplace->flags)) - need_replace = 1; + if (mrdev && (test_bit(Faulty, &mrdev->flags) || + test_bit(In_sync, &mrdev->flags))) + mrdev = NULL; + if (mreplace && test_bit(Faulty, &mreplace->flags)) + mreplace = NULL; - if (!need_recover && !need_replace) { + if (!mrdev && !mreplace) { rcu_read_unlock(); continue; } @@ -3080,8 +3418,6 @@ rcu_read_unlock(); continue; } - if (mreplace && test_bit(Faulty, &mreplace->flags)) - mreplace = NULL; /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3100,7 +3436,8 @@ rcu_read_unlock(); continue; } - atomic_inc(&mrdev->nr_pending); + if (mrdev) + atomic_inc(&mrdev->nr_pending); if (mreplace) atomic_inc(&mreplace->nr_pending); rcu_read_unlock(); @@ -3187,7 +3524,7 @@ r10_bio->devs[1].devnum = i; r10_bio->devs[1].addr = to_addr; - if (need_recover) { + if (mrdev) { bio = r10_bio->devs[1].bio; bio->bi_next = biolist; biolist = bio; @@ -3204,11 +3541,11 @@ bio = r10_bio->devs[1].repl_bio; if (bio) bio->bi_end_io = NULL; - /* Note: if need_replace, then bio + /* Note: if replace is not NULL, then bio * cannot be NULL as r10buf_pool_alloc will * have allocated it. */ - if (!need_replace) + if (!mreplace) break; bio->bi_next = biolist; biolist = bio; @@ -3232,7 +3569,7 @@ for (k = 0; k < conf->copies; k++) if (r10_bio->devs[k].devnum == i) break; - if (!test_bit(In_sync, + if (mrdev && !test_bit(In_sync, &mrdev->flags) && !rdev_set_badblocks( mrdev, @@ -3258,12 +3595,14 @@ if (rb2) atomic_dec(&rb2->remaining); r10_bio = rb2; - rdev_dec_pending(mrdev, mddev); + if (mrdev) + rdev_dec_pending(mrdev, mddev); if (mreplace) rdev_dec_pending(mreplace, mddev); break; } - rdev_dec_pending(mrdev, mddev); + if (mrdev) + rdev_dec_pending(mrdev, mddev); if (mreplace) rdev_dec_pending(mreplace, mddev); if (r10_bio->devs[0].bio->bi_opf & MD_FAILFAST) { @@ -3629,6 +3968,20 @@ return nc*fc; } +static void raid10_free_conf(struct r10conf *conf) +{ + if (!conf) + return; + + mempool_exit(&conf->r10bio_pool); + kfree(conf->mirrors); + kfree(conf->mirrors_old); + kfree(conf->mirrors_new); + safe_put_page(conf->tmppage); + bioset_exit(&conf->bio_split); + kfree(conf); +} + static struct r10conf *setup_conf(struct mddev *mddev) { struct r10conf *conf = NULL; @@ -3711,20 +4064,24 @@ return conf; out: - if (conf) { - mempool_exit(&conf->r10bio_pool); - kfree(conf->mirrors); - safe_put_page(conf->tmppage); - bioset_exit(&conf->bio_split); - kfree(conf); - } + raid10_free_conf(conf); return ERR_PTR(err); } +static void raid10_set_io_opt(struct r10conf *conf) +{ + int raid_disks = conf->geo.raid_disks; + + if (!(conf->geo.raid_disks % conf->geo.near_copies)) + raid_disks /= conf->geo.near_copies; + blk_queue_io_opt(conf->mddev->queue, (conf->mddev->chunk_sectors << 9) * + raid_disks); +} + static int raid10_run(struct mddev *mddev) { struct r10conf *conf; - int i, disk_idx, chunk_size; + int i, disk_idx; struct raid10_info *disk; struct md_rdev *rdev; sector_t size; @@ -3745,6 +4102,9 @@ if (!conf) goto out; + mddev->thread = conf->thread; + conf->thread = NULL; + if (mddev_is_clustered(conf->mddev)) { int fc, fo; @@ -3757,21 +4117,13 @@ } } - mddev->thread = conf->thread; - conf->thread = NULL; - - chunk_size = mddev->chunk_sectors << 9; if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, - mddev->chunk_sectors); + UINT_MAX); blk_queue_max_write_same_sectors(mddev->queue, 0); blk_queue_max_write_zeroes_sectors(mddev->queue, 0); - blk_queue_io_min(mddev->queue, chunk_size); - if (conf->geo.raid_disks % conf->geo.near_copies) - blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); - else - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->geo.raid_disks / conf->geo.near_copies)); + blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); + raid10_set_io_opt(conf); } rdev_for_each(rdev, mddev) { @@ -3931,10 +4283,7 @@ out_free_conf: md_unregister_thread(&mddev->thread); - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf); + raid10_free_conf(conf); mddev->private = NULL; out: return -EIO; @@ -3942,15 +4291,7 @@ static void raid10_free(struct mddev *mddev, void *priv) { - struct r10conf *conf = priv; - - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf->mirrors_old); - kfree(conf->mirrors_new); - bioset_exit(&conf->bio_split); - kfree(conf); + raid10_free_conf(priv); } static void raid10_quiesce(struct mddev *mddev, int quiesce) @@ -4745,6 +5086,7 @@ stripe /= conf->geo.near_copies; if (conf->mddev->queue->backing_dev_info->ra_pages < 2 * stripe) conf->mddev->queue->backing_dev_info->ra_pages = 2 * stripe; + raid10_set_io_opt(conf); } conf->fullsync = 0; } --- linux-oracle-5.4.0.orig/drivers/md/raid10.h +++ linux-oracle-5.4.0/drivers/md/raid10.h @@ -179,5 +179,6 @@ R10BIO_Previous, /* failfast devices did receive failfast requests. */ R10BIO_FailFast, + R10BIO_Discard, }; #endif --- linux-oracle-5.4.0.orig/drivers/md/raid5.c +++ linux-oracle-5.4.0/drivers/md/raid5.c @@ -609,17 +609,17 @@ return degraded; } -static int has_failed(struct r5conf *conf) +static bool has_failed(struct r5conf *conf) { - int degraded; + int degraded = conf->mddev->degraded; - if (conf->mddev->reshape_position == MaxSector) - return conf->mddev->degraded > conf->max_degraded; + if (test_bit(MD_BROKEN, &conf->mddev->flags)) + return true; - degraded = raid5_calc_degraded(conf); - if (degraded > conf->max_degraded) - return 1; - return 0; + if (conf->mddev->reshape_position != MaxSector) + degraded = raid5_calc_degraded(conf); + + return degraded > conf->max_degraded; } struct stripe_head * @@ -2181,7 +2181,7 @@ atomic_inc(&conf->active_stripes); raid5_release_stripe(sh); - conf->max_nr_stripes++; + WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes + 1); return 1; } @@ -2228,14 +2228,19 @@ * of the P and Q blocks. */ static int scribble_alloc(struct raid5_percpu *percpu, - int num, int cnt, gfp_t flags) + int num, int cnt) { size_t obj_size = sizeof(struct page *) * (num+2) + sizeof(addr_conv_t) * (num+2); void *scribble; - scribble = kvmalloc_array(cnt, obj_size, flags); + /* + * If here is in raid array suspend context, it is in memalloc noio + * context as well, there is no potential recursive memory reclaim + * I/Os with the GFP_KERNEL flag. + */ + scribble = kvmalloc_array(cnt, obj_size, GFP_KERNEL); if (!scribble) return -ENOMEM; @@ -2267,8 +2272,7 @@ percpu = per_cpu_ptr(conf->percpu, cpu); err = scribble_alloc(percpu, new_disks, - new_sectors / STRIPE_SECTORS, - GFP_NOIO); + new_sectors / STRIPE_SECTORS); if (err) break; } @@ -2403,8 +2407,6 @@ } else err = -ENOMEM; - mutex_unlock(&conf->cache_size_mutex); - conf->slab_cache = sc; conf->active_name = 1-conf->active_name; @@ -2427,6 +2429,8 @@ if (!err) conf->pool_size = newsize; + mutex_unlock(&conf->cache_size_mutex); + return err; } @@ -2444,7 +2448,7 @@ shrink_buffers(sh); free_stripe(conf->slab_cache, sh); atomic_dec(&conf->active_stripes); - conf->max_nr_stripes--; + WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes - 1); return 1; } @@ -2594,7 +2598,7 @@ struct stripe_head *sh = bi->bi_private; struct r5conf *conf = sh->raid_conf; int disks = sh->disks, i; - struct md_rdev *uninitialized_var(rdev); + struct md_rdev *rdev; sector_t first_bad; int bad_sectors; int replacement = 0; @@ -2662,10 +2666,10 @@ if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags)) clear_bit(R5_LOCKED, &sh->dev[i].flags); set_bit(STRIPE_HANDLE, &sh->state); - raid5_release_stripe(sh); if (sh->batch_head && sh != sh->batch_head) raid5_release_stripe(sh->batch_head); + raid5_release_stripe(sh); } static void raid5_error(struct mddev *mddev, struct md_rdev *rdev) @@ -2675,34 +2679,31 @@ unsigned long flags; pr_debug("raid456: error called\n"); + pr_crit("md/raid:%s: Disk failure on %s, disabling device.\n", + mdname(mddev), bdevname(rdev->bdev, b)); + spin_lock_irqsave(&conf->device_lock, flags); + set_bit(Faulty, &rdev->flags); + clear_bit(In_sync, &rdev->flags); + mddev->degraded = raid5_calc_degraded(conf); - if (test_bit(In_sync, &rdev->flags) && - mddev->degraded == conf->max_degraded) { - /* - * Don't allow to achieve failed state - * Don't try to recover this device - */ + if (has_failed(conf)) { + set_bit(MD_BROKEN, &conf->mddev->flags); conf->recovery_disabled = mddev->recovery_disabled; - spin_unlock_irqrestore(&conf->device_lock, flags); - return; + + pr_crit("md/raid:%s: Cannot continue operation (%d/%d failed).\n", + mdname(mddev), mddev->degraded, conf->raid_disks); + } else { + pr_crit("md/raid:%s: Operation continuing on %d devices.\n", + mdname(mddev), conf->raid_disks - mddev->degraded); } - set_bit(Faulty, &rdev->flags); - clear_bit(In_sync, &rdev->flags); - mddev->degraded = raid5_calc_degraded(conf); spin_unlock_irqrestore(&conf->device_lock, flags); set_bit(MD_RECOVERY_INTR, &mddev->recovery); set_bit(Blocked, &rdev->flags); set_mask_bits(&mddev->sb_flags, 0, BIT(MD_SB_CHANGE_DEVS) | BIT(MD_SB_CHANGE_PENDING)); - pr_crit("md/raid:%s: Disk failure on %s, disabling device.\n" - "md/raid:%s: Operation continuing on %d devices.\n", - mdname(mddev), - bdevname(rdev->bdev, b), - mdname(mddev), - conf->raid_disks - mddev->degraded); r5c_update_on_rdev_error(mddev, rdev); } @@ -3600,6 +3601,7 @@ * is missing/faulty, then we need to read everything we can. */ if (sh->raid_conf->level != 6 && + sh->raid_conf->rmw_level != PARITY_DISABLE_RMW && sh->sector < sh->raid_conf->mddev->recovery_cp) /* reconstruct-write isn't being forced */ return 0; @@ -3726,7 +3728,7 @@ * back cache (prexor with orig_page, and then xor with * page) in the read path */ - if (s->injournal && s->failed) { + if (s->to_read && s->injournal && s->failed) { if (test_bit(STRIPE_R5C_CACHING, &sh->state)) r5c_make_stripe_write_out(sh); goto out; @@ -4835,7 +4837,7 @@ * or to load a block that is being partially written. */ if (s.to_read || s.non_overwrite - || (conf->level == 6 && s.to_write && s.failed) + || (s.to_write && s.failed) || (s.syncing && (s.uptodate + s.compute < disks)) || s.replacing || s.expanding) @@ -5592,8 +5594,8 @@ if (ret == 0) return true; if (ret == -ENODEV) { - md_flush_request(mddev, bi); - return true; + if (md_flush_request(mddev, bi)) + return true; } /* ret == -EAGAIN, fallback */ /* @@ -5726,7 +5728,7 @@ do_flush = false; } - if (!sh->batch_head) + if (!sh->batch_head || sh == sh->batch_head) set_bit(STRIPE_HANDLE, &sh->state); clear_bit(STRIPE_DELAYED, &sh->state); if ((!sh->batch_head || sh == sh->batch_head) && @@ -5819,7 +5821,9 @@ safepos = conf->reshape_safe; sector_div(safepos, data_disks); if (mddev->reshape_backwards) { - BUG_ON(writepos < reshape_sectors); + if (WARN_ON(writepos < reshape_sectors)) + return MaxSector; + writepos -= reshape_sectors; readpos += reshape_sectors; safepos += reshape_sectors; @@ -5837,14 +5841,18 @@ * to set 'stripe_addr' which is where we will write to. */ if (mddev->reshape_backwards) { - BUG_ON(conf->reshape_progress == 0); + if (WARN_ON(conf->reshape_progress == 0)) + return MaxSector; + stripe_addr = writepos; - BUG_ON((mddev->dev_sectors & - ~((sector_t)reshape_sectors - 1)) - - reshape_sectors - stripe_addr - != sector_nr); + if (WARN_ON((mddev->dev_sectors & + ~((sector_t)reshape_sectors - 1)) - + reshape_sectors - stripe_addr != sector_nr)) + return MaxSector; } else { - BUG_ON(writepos != sector_nr + reshape_sectors); + if (WARN_ON(writepos != sector_nr + reshape_sectors)) + return MaxSector; + stripe_addr = sector_nr; } @@ -6296,6 +6304,9 @@ int batch_size, released; unsigned int offset; + if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + released = release_stripe_list(conf, conf->temp_inactive_list); if (released) clear_bit(R5_DID_ALLOC, &conf->cache_state); @@ -6379,7 +6390,7 @@ if (size <= 16 || size > 32768) return -EINVAL; - conf->min_nr_stripes = size; + WRITE_ONCE(conf->min_nr_stripes, size); mutex_lock(&conf->cache_size_mutex); while (size < conf->max_nr_stripes && drop_one_stripe(conf)) @@ -6391,7 +6402,7 @@ mutex_lock(&conf->cache_size_mutex); while (size > conf->max_nr_stripes) if (!grow_one_stripe(conf, GFP_KERNEL)) { - conf->min_nr_stripes = conf->max_nr_stripes; + WRITE_ONCE(conf->min_nr_stripes, conf->max_nr_stripes); result = -ENOMEM; break; } @@ -6765,8 +6776,7 @@ conf->previous_raid_disks), max(conf->chunk_sectors, conf->prev_chunk_sectors) - / STRIPE_SECTORS, - GFP_KERNEL)) { + / STRIPE_SECTORS)) { free_scratch_buffer(conf, percpu); return -ENOMEM; } @@ -6867,11 +6877,13 @@ struct shrink_control *sc) { struct r5conf *conf = container_of(shrink, struct r5conf, shrinker); + int max_stripes = READ_ONCE(conf->max_nr_stripes); + int min_stripes = READ_ONCE(conf->min_nr_stripes); - if (conf->max_nr_stripes < conf->min_nr_stripes) + if (max_stripes < min_stripes) /* unlikely, but not impossible */ return 0; - return conf->max_nr_stripes - conf->min_nr_stripes; + return max_stripes - min_stripes; } static struct r5conf *setup_conf(struct mddev *mddev) @@ -7146,6 +7158,12 @@ return 0; } +static void raid5_set_io_opt(struct r5conf *conf) +{ + blk_queue_io_opt(conf->mddev->queue, (conf->chunk_sectors << 9) * + (conf->raid_disks - conf->max_degraded)); +} + static int raid5_run(struct mddev *mddev) { struct r5conf *conf; @@ -7435,8 +7453,7 @@ chunk_size = mddev->chunk_sectors << 9; blk_queue_io_min(mddev->queue, chunk_size); - blk_queue_io_opt(mddev->queue, chunk_size * - (conf->raid_disks - conf->max_degraded)); + raid5_set_io_opt(conf); mddev->queue->limits.raid_partial_stripes_expensive = 1; /* * We can only discard a whole stripe. It doesn't make sense to @@ -7721,6 +7738,7 @@ */ if (rdev->saved_raid_disk >= 0 && rdev->saved_raid_disk >= first && + rdev->saved_raid_disk <= last && conf->disks[rdev->saved_raid_disk].rdev == NULL) first = rdev->saved_raid_disk; @@ -8029,6 +8047,7 @@ / PAGE_SIZE); if (conf->mddev->queue->backing_dev_info->ra_pages < 2 * stripe) conf->mddev->queue->backing_dev_info->ra_pages = 2 * stripe; + raid5_set_io_opt(conf); } } } --- linux-oracle-5.4.0.orig/drivers/media/cec/cec-adap.c +++ linux-oracle-5.4.0/drivers/media/cec/cec-adap.c @@ -378,7 +378,8 @@ } else { list_del_init(&data->list); if (!(data->msg.tx_status & CEC_TX_STATUS_OK)) - data->adap->transmit_queue_sz--; + if (!WARN_ON(!data->adap->transmit_queue_sz)) + data->adap->transmit_queue_sz--; } if (data->msg.tx_status & CEC_TX_STATUS_OK) { @@ -417,7 +418,7 @@ cec_data_cancel(data, CEC_TX_STATUS_ABORTED); } if (adap->transmitting) - cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED); + adap->transmit_in_progress_aborted = true; /* Cancel the pending timeout work. */ list_for_each_entry_safe(data, n, &adap->wait_queue, list) { @@ -430,6 +431,14 @@ * need to do anything special in that case. */ } + /* + * If something went wrong and this counter isn't what it should + * be, then this will reset it back to 0. Warn if it is not 0, + * since it indicates a bug, either in this framework or in a + * CEC driver. + */ + if (WARN_ON(adap->transmit_queue_sz)) + adap->transmit_queue_sz = 0; } /* @@ -454,7 +463,7 @@ bool timeout = false; u8 attempts; - if (adap->transmitting) { + if (adap->transmit_in_progress) { int err; /* @@ -489,7 +498,16 @@ goto unlock; } - if (adap->transmitting && timeout) { + if (adap->transmit_in_progress && + adap->transmit_in_progress_aborted) { + if (adap->transmitting) + cec_data_cancel(adap->transmitting, + CEC_TX_STATUS_ABORTED); + adap->transmit_in_progress = false; + adap->transmit_in_progress_aborted = false; + goto unlock; + } + if (adap->transmit_in_progress && timeout) { /* * If we timeout, then log that. Normally this does * not happen and it is an indication of a faulty CEC @@ -498,14 +516,18 @@ * so much traffic on the bus that the adapter was * unable to transmit for CEC_XFER_TIMEOUT_MS (2.1s). */ - pr_warn("cec-%s: message %*ph timed out\n", adap->name, - adap->transmitting->msg.len, - adap->transmitting->msg.msg); + if (adap->transmitting) { + pr_warn("cec-%s: message %*ph timed out\n", adap->name, + adap->transmitting->msg.len, + adap->transmitting->msg.msg); + /* Just give up on this. */ + cec_data_cancel(adap->transmitting, + CEC_TX_STATUS_TIMEOUT); + } else { + pr_warn("cec-%s: transmit timed out\n", adap->name); + } adap->transmit_in_progress = false; adap->tx_timeouts++; - /* Just give up on this. */ - cec_data_cancel(adap->transmitting, - CEC_TX_STATUS_TIMEOUT); goto unlock; } @@ -520,7 +542,8 @@ data = list_first_entry(&adap->transmit_queue, struct cec_data, list); list_del_init(&data->list); - adap->transmit_queue_sz--; + if (!WARN_ON(!data->adap->transmit_queue_sz)) + adap->transmit_queue_sz--; /* Make this the current transmitting message */ adap->transmitting = data; @@ -555,6 +578,7 @@ if (data->attempts == 0) data->attempts = attempts; + adap->transmit_in_progress_aborted = false; /* Tell the adapter to transmit, cancel on error */ if (adap->ops->adap_transmit(adap, data->attempts, signal_free_time, &data->msg)) @@ -582,6 +606,8 @@ struct cec_msg *msg; unsigned int attempts_made = arb_lost_cnt + nack_cnt + low_drive_cnt + error_cnt; + bool done = status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK); + bool aborted = adap->transmit_in_progress_aborted; dprintk(2, "%s: status 0x%02x\n", __func__, status); if (attempts_made < 1) @@ -602,6 +628,7 @@ goto wake_thread; } adap->transmit_in_progress = false; + adap->transmit_in_progress_aborted = false; msg = &data->msg; @@ -622,8 +649,7 @@ * the hardware didn't signal that it retried itself (by setting * CEC_TX_STATUS_MAX_RETRIES), then we will retry ourselves. */ - if (data->attempts > attempts_made && - !(status & (CEC_TX_STATUS_MAX_RETRIES | CEC_TX_STATUS_OK))) { + if (!aborted && data->attempts > attempts_made && !done) { /* Retry this message */ data->attempts -= attempts_made; if (msg->timeout) @@ -638,6 +664,8 @@ goto wake_thread; } + if (aborted && !done) + status |= CEC_TX_STATUS_ABORTED; data->attempts = 0; /* Always set CEC_TX_STATUS_MAX_RETRIES on error */ @@ -734,6 +762,7 @@ { struct cec_data *data; bool is_raw = msg_is_raw(msg); + int err; msg->rx_ts = 0; msg->tx_ts = 0; @@ -893,11 +922,13 @@ * Release the lock and wait, retake the lock afterwards. */ mutex_unlock(&adap->lock); - wait_for_completion_killable(&data->c); - if (!data->completed) - cancel_delayed_work_sync(&data->work); + err = wait_for_completion_killable(&data->c); + cancel_delayed_work_sync(&data->work); mutex_lock(&adap->lock); + if (err) + adap->transmit_in_progress_aborted = true; + /* Cancel the transmit if it was interrupted */ if (!data->completed) cec_data_cancel(data, CEC_TX_STATUS_ABORTED); @@ -1063,7 +1094,8 @@ mutex_lock(&adap->lock); dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg); - adap->last_initiator = 0xff; + if (!adap->transmit_in_progress) + adap->last_initiator = 0xff; /* Check if this message was for us (directed or broadcast). */ if (!cec_msg_is_broadcast(msg)) @@ -1083,11 +1115,11 @@ valid_la = false; else if (!cec_msg_is_broadcast(msg) && !(dir_fl & DIRECTED)) valid_la = false; - else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST1_4)) + else if (cec_msg_is_broadcast(msg) && !(dir_fl & BCAST)) valid_la = false; else if (cec_msg_is_broadcast(msg) && - adap->log_addrs.cec_version >= CEC_OP_CEC_VERSION_2_0 && - !(dir_fl & BCAST2_0)) + adap->log_addrs.cec_version < CEC_OP_CEC_VERSION_2_0 && + !(dir_fl & BCAST1_4)) valid_la = false; } if (valid_la && min_len) { @@ -1177,6 +1209,7 @@ if (abort) dst->rx_status |= CEC_RX_STATUS_FEATURE_ABORT; msg->flags = dst->flags; + msg->sequence = dst->sequence; /* Remove it from the wait_queue */ list_del_init(&data->list); @@ -1248,7 +1281,7 @@ * While trying to poll the physical address was reset * and the adapter was unconfigured, so bail out. */ - if (!adap->is_configuring) + if (adap->phys_addr == CEC_PHYS_ADDR_INVALID) return -EINTR; if (err) @@ -1306,7 +1339,6 @@ adap->phys_addr != CEC_PHYS_ADDR_INVALID) WARN_ON(adap->ops->adap_log_addr(adap, CEC_LOG_ADDR_INVALID)); adap->log_addrs.log_addr_mask = 0; - adap->is_configuring = false; adap->is_configured = false; memset(adap->phys_addrs, 0xff, sizeof(adap->phys_addrs)); cec_flush(adap); @@ -1499,9 +1531,10 @@ for (i = 0; i < las->num_log_addrs; i++) las->log_addr[i] = CEC_LOG_ADDR_INVALID; cec_adap_unconfigure(adap); + adap->is_configuring = false; adap->kthread_config = NULL; - mutex_unlock(&adap->lock); complete(&adap->config_completion); + mutex_unlock(&adap->lock); return 0; } @@ -1513,9 +1546,12 @@ */ static void cec_claim_log_addrs(struct cec_adapter *adap, bool block) { - if (WARN_ON(adap->is_configuring || adap->is_configured)) + if (WARN_ON(adap->is_claiming_log_addrs || + adap->is_configuring || adap->is_configured)) return; + adap->is_claiming_log_addrs = true; + init_completion(&adap->config_completion); /* Ready to kick off the thread */ @@ -1529,6 +1565,7 @@ wait_for_completion(&adap->config_completion); mutex_lock(&adap->lock); } + adap->is_claiming_log_addrs = false; } /* Set a new physical address and send an event notifying userspace of this. @@ -1556,6 +1593,9 @@ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { WARN_ON(adap->ops->adap_enable(adap, false)); adap->transmit_in_progress = false; + adap->transmit_in_progress_aborted = false; + if (adap->transmitting) + cec_data_cancel(adap->transmitting, CEC_TX_STATUS_ABORTED); wake_up_interruptible(&adap->kthread_waitq); } mutex_unlock(&adap->devnode.lock); @@ -1718,6 +1758,10 @@ unsigned j; log_addrs->log_addr[i] = CEC_LOG_ADDR_INVALID; + if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { + dprintk(1, "unknown logical address type\n"); + return -EINVAL; + } if (type_mask & (1 << log_addrs->log_addr_type[i])) { dprintk(1, "duplicate logical address type\n"); return -EINVAL; @@ -1738,10 +1782,6 @@ dprintk(1, "invalid primary device type\n"); return -EINVAL; } - if (log_addrs->log_addr_type[i] > CEC_LOG_ADDR_TYPE_UNREGISTERED) { - dprintk(1, "unknown logical address type\n"); - return -EINVAL; - } for (j = 0; j < feature_sz; j++) { if ((features[j] & 0x80) == 0) { if (op_is_dev_features) --- linux-oracle-5.4.0.orig/drivers/media/cec/cec-api.c +++ linux-oracle-5.4.0/drivers/media/cec/cec-api.c @@ -147,7 +147,13 @@ struct cec_log_addrs log_addrs; mutex_lock(&adap->lock); - log_addrs = adap->log_addrs; + /* + * We use memcpy here instead of assignment since there is a + * hole at the end of struct cec_log_addrs that an assignment + * might ignore. So when we do copy_to_user() we could leak + * one byte of memory. + */ + memcpy(&log_addrs, &adap->log_addrs, sizeof(log_addrs)); if (!adap->is_configured) memset(log_addrs.log_addr, CEC_LOG_ADDR_INVALID, sizeof(log_addrs.log_addr)); @@ -172,7 +178,7 @@ CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU | CEC_LOG_ADDRS_FL_CDC_ONLY; mutex_lock(&adap->lock); - if (!adap->is_configuring && + if (!adap->is_claiming_log_addrs && !adap->is_configuring && (!log_addrs.num_log_addrs || !adap->is_configured) && !cec_is_busy(adap, fh)) { err = __cec_s_log_addrs(adap, &log_addrs, block); @@ -646,6 +652,8 @@ list_del(&data->xfer_list); } mutex_unlock(&adap->lock); + + mutex_lock(&fh->lock); while (!list_empty(&fh->msgs)) { struct cec_msg_entry *entry = list_first_entry(&fh->msgs, struct cec_msg_entry, list); @@ -663,6 +671,7 @@ kfree(entry); } } + mutex_unlock(&fh->lock); kfree(fh); cec_put_device(devnode); --- linux-oracle-5.4.0.orig/drivers/media/common/saa7146/saa7146_fops.c +++ linux-oracle-5.4.0/drivers/media/common/saa7146/saa7146_fops.c @@ -525,7 +525,7 @@ ERR("out of memory. aborting.\n"); kfree(vv); v4l2_ctrl_handler_free(hdl); - return -1; + return -ENOMEM; } saa7146_video_uops.init(dev,vv); --- linux-oracle-5.4.0.orig/drivers/media/common/siano/smscoreapi.c +++ linux-oracle-5.4.0/drivers/media/common/siano/smscoreapi.c @@ -908,7 +908,7 @@ void *buffer, size_t size) { struct sms_firmware *firmware = (struct sms_firmware *) buffer; - struct sms_msg_data4 *msg; + struct sms_msg_data5 *msg; u32 mem_address, calc_checksum = 0; u32 i, *ptr; u8 *payload = firmware->payload; @@ -989,24 +989,20 @@ goto exit_fw_download; if (coredev->mode == DEVICE_MODE_NONE) { - struct sms_msg_data *trigger_msg = - (struct sms_msg_data *) msg; - pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n"); SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct sms_msg_hdr) + - sizeof(u32) * 5); + sizeof(*msg)); - trigger_msg->msg_data[0] = firmware->start_address; + msg->msg_data[0] = firmware->start_address; /* Entry point */ - trigger_msg->msg_data[1] = 6; /* Priority */ - trigger_msg->msg_data[2] = 0x200; /* Stack size */ - trigger_msg->msg_data[3] = 0; /* Parameter */ - trigger_msg->msg_data[4] = 4; /* Task ID */ + msg->msg_data[1] = 6; /* Priority */ + msg->msg_data[2] = 0x200; /* Stack size */ + msg->msg_data[3] = 0; /* Parameter */ + msg->msg_data[4] = 4; /* Task ID */ - rc = smscore_sendrequest_and_wait(coredev, trigger_msg, - trigger_msg->x_msg_header.msg_length, + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->x_msg_header.msg_length, &coredev->trigger_done); } else { SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ, --- linux-oracle-5.4.0.orig/drivers/media/common/siano/smscoreapi.h +++ linux-oracle-5.4.0/drivers/media/common/siano/smscoreapi.h @@ -629,9 +629,9 @@ u32 msg_data[2]; }; -struct sms_msg_data4 { +struct sms_msg_data5 { struct sms_msg_hdr x_msg_header; - u32 msg_data[4]; + u32 msg_data[5]; }; struct sms_data_download { --- linux-oracle-5.4.0.orig/drivers/media/common/siano/smsdvb-main.c +++ linux-oracle-5.4.0/drivers/media/common/siano/smsdvb-main.c @@ -1169,12 +1169,19 @@ rc = dvb_create_media_graph(&client->adapter, true); if (rc < 0) { pr_err("dvb_create_media_graph failed %d\n", rc); - goto client_error; + goto media_graph_error; } pr_info("DVB interface registered.\n"); return 0; +media_graph_error: + mutex_lock(&g_smsdvb_clientslock); + list_del(&client->entry); + mutex_unlock(&g_smsdvb_clientslock); + + smsdvb_debugfs_release(client); + client_error: dvb_unregister_frontend(&client->frontend); --- linux-oracle-5.4.0.orig/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c +++ linux-oracle-5.4.0/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c @@ -113,6 +113,7 @@ { unsigned pat; unsigned plane; + int ret = 0; tpg->max_line_width = max_w; for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { @@ -121,14 +122,18 @@ tpg->lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->lines[pat][plane]) - return -ENOMEM; + if (!tpg->lines[pat][plane]) { + ret = -ENOMEM; + goto free_lines; + } if (plane == 0) continue; tpg->downsampled_lines[pat][plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->downsampled_lines[pat][plane]) - return -ENOMEM; + if (!tpg->downsampled_lines[pat][plane]) { + ret = -ENOMEM; + goto free_lines; + } } } for (plane = 0; plane < TPG_MAX_PLANES; plane++) { @@ -136,18 +141,45 @@ tpg->contrast_line[plane] = vzalloc(array_size(pixelsz, max_w)); - if (!tpg->contrast_line[plane]) - return -ENOMEM; + if (!tpg->contrast_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } tpg->black_line[plane] = vzalloc(array_size(pixelsz, max_w)); - if (!tpg->black_line[plane]) - return -ENOMEM; + if (!tpg->black_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } tpg->random_line[plane] = vzalloc(array3_size(max_w, 2, pixelsz)); - if (!tpg->random_line[plane]) - return -ENOMEM; + if (!tpg->random_line[plane]) { + ret = -ENOMEM; + goto free_contrast_line; + } } return 0; + +free_contrast_line: + for (plane = 0; plane < TPG_MAX_PLANES; plane++) { + vfree(tpg->contrast_line[plane]); + vfree(tpg->black_line[plane]); + vfree(tpg->random_line[plane]); + tpg->contrast_line[plane] = NULL; + tpg->black_line[plane] = NULL; + tpg->random_line[plane] = NULL; + } +free_lines: + for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) + for (plane = 0; plane < TPG_MAX_PLANES; plane++) { + vfree(tpg->lines[pat][plane]); + tpg->lines[pat][plane] = NULL; + if (plane == 0) + continue; + vfree(tpg->downsampled_lines[pat][plane]); + tpg->downsampled_lines[pat][plane] = NULL; + } + return ret; } EXPORT_SYMBOL_GPL(tpg_alloc); @@ -1757,6 +1789,9 @@ unsigned p; unsigned x; + if (WARN_ON_ONCE(!tpg->src_width || !tpg->scaled_width)) + return; + switch (tpg->pattern) { case TPG_PAT_GREEN: contrast = TPG_COLOR_100_RED; --- linux-oracle-5.4.0.orig/drivers/media/common/videobuf2/videobuf2-core.c +++ linux-oracle-5.4.0/drivers/media/common/videobuf2/videobuf2-core.c @@ -282,6 +282,10 @@ p->mem_priv = NULL; p->dbuf = NULL; p->dbuf_mapped = 0; + p->bytesused = 0; + p->length = 0; + p->m.fd = 0; + p->data_offset = 0; } /* @@ -1177,10 +1181,6 @@ /* Release previously acquired memory if present */ __vb2_plane_dmabuf_put(vb, &vb->planes[plane]); - vb->planes[plane].bytesused = 0; - vb->planes[plane].length = 0; - vb->planes[plane].m.fd = 0; - vb->planes[plane].data_offset = 0; /* Acquire each plane's memory */ mem_priv = call_ptr_memop(vb, attach_dmabuf, @@ -1512,6 +1512,7 @@ struct media_request *req) { struct vb2_buffer *vb; + enum vb2_buffer_state orig_state; int ret; if (q->error) { @@ -1611,6 +1612,7 @@ * Add to the queued buffers list, a buffer will stay on it until * dequeued in dqbuf. */ + orig_state = vb->state; list_add_tail(&vb->queued_entry, &q->queued_list); q->queued_count++; q->waiting_for_buffers = false; @@ -1641,8 +1643,17 @@ if (q->streaming && !q->start_streaming_called && q->queued_count >= q->min_buffers_needed) { ret = vb2_start_streaming(q); - if (ret) + if (ret) { + /* + * Since vb2_core_qbuf will return with an error, + * we should return it to state DEQUEUED since + * the error indicates that the buffer wasn't queued. + */ + list_del(&vb->queued_entry); + q->queued_count--; + vb->state = orig_state; return ret; + } } dprintk(2, "qbuf of buffer %d succeeded\n", vb->index); --- linux-oracle-5.4.0.orig/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ linux-oracle-5.4.0/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -154,7 +154,7 @@ buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr, GFP_KERNEL | gfp_flags, buf->attrs); if (!buf->cookie) { - dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); + dev_err(dev, "dma_alloc_coherent of size %lu failed\n", size); kfree(buf); return ERR_PTR(-ENOMEM); } @@ -200,9 +200,9 @@ vma->vm_ops->open(vma); - pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n", - __func__, (unsigned long)buf->dma_addr, vma->vm_start, - buf->size); + pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %lu\n", + __func__, (unsigned long)buf->dma_addr, vma->vm_start, + buf->size); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dmxdev.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dmxdev.c @@ -800,6 +800,11 @@ if (mutex_lock_interruptible(&dmxdev->mutex)) return -ERESTARTSYS; + if (dmxdev->exit) { + mutex_unlock(&dmxdev->mutex); + return -ENODEV; + } + for (i = 0; i < dmxdev->filternum; i++) if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) break; @@ -1413,7 +1418,7 @@ }; int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) { - int i; + int i, ret; if (dmxdev->demux->open(dmxdev->demux) < 0) return -EUSERS; @@ -1432,21 +1437,36 @@ DMXDEV_STATE_FREE); } - dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, + ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, DVB_DEVICE_DEMUX, dmxdev->filternum); - dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, + if (ret < 0) + goto err_register_dvbdev; + + ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, dmxdev, DVB_DEVICE_DVR, dmxdev->filternum); + if (ret < 0) + goto err_register_dvr_dvbdev; dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); return 0; + +err_register_dvr_dvbdev: + dvb_unregister_device(dmxdev->dvbdev); +err_register_dvbdev: + vfree(dmxdev->filter); + dmxdev->filter = NULL; + return ret; } EXPORT_SYMBOL(dvb_dmxdev_init); void dvb_dmxdev_release(struct dmxdev *dmxdev) { + mutex_lock(&dmxdev->mutex); dmxdev->exit = 1; + mutex_unlock(&dmxdev->mutex); + if (dmxdev->dvbdev->users > 1) { wait_event(dmxdev->dvbdev->wait_queue, dmxdev->dvbdev->users == 1); --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dvb_ca_en50221.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dvb_ca_en50221.c @@ -151,13 +151,19 @@ /* mutex serializing ioctls */ struct mutex ioctl_mutex; + + /* A mutex used when a device is disconnected */ + struct mutex remove_mutex; + + /* Whether the device is disconnected */ + int exit; }; static void dvb_ca_private_free(struct dvb_ca_private *ca) { unsigned int i; - dvb_free_device(ca->dvbdev); + dvb_device_put(ca->dvbdev); for (i = 0; i < ca->slot_count; i++) vfree(ca->slot_info[i].rx_buffer.data); @@ -187,7 +193,7 @@ static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 *ebuf, int ecount); static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, - u8 *ebuf, int ecount); + u8 *ebuf, int ecount, int size_write_flag); /** * Safely find needle in haystack. @@ -370,7 +376,7 @@ ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10); if (ret) return ret; - ret = dvb_ca_en50221_write_data(ca, slot, buf, 2); + ret = dvb_ca_en50221_write_data(ca, slot, buf, 2, CMDREG_SW); if (ret != 2) return -EIO; ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN); @@ -778,11 +784,13 @@ * @buf: The data in this buffer is treated as a complete link-level packet to * be written. * @bytes_write: Size of ebuf. + * @size_write_flag: A flag on Command Register which says whether the link size + * information will be writen or not. * * return: Number of bytes written, or < 0 on error. */ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, - u8 *buf, int bytes_write) + u8 *buf, int bytes_write, int size_write_flag) { struct dvb_ca_slot *sl = &ca->slot_info[slot]; int status; @@ -817,7 +825,7 @@ /* OK, set HC bit */ status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, - IRQEN | CMDREG_HC); + IRQEN | CMDREG_HC | size_write_flag); if (status) goto exit; @@ -1505,7 +1513,7 @@ mutex_lock(&sl->slot_lock); status = dvb_ca_en50221_write_data(ca, slot, fragbuf, - fraglen + 2); + fraglen + 2, 0); mutex_unlock(&sl->slot_lock); if (status == (fraglen + 2)) { written = 1; @@ -1706,12 +1714,22 @@ dprintk("%s\n", __func__); - if (!try_module_get(ca->pub->owner)) + mutex_lock(&ca->remove_mutex); + + if (ca->exit) { + mutex_unlock(&ca->remove_mutex); + return -ENODEV; + } + + if (!try_module_get(ca->pub->owner)) { + mutex_unlock(&ca->remove_mutex); return -EIO; + } err = dvb_generic_open(inode, file); if (err < 0) { module_put(ca->pub->owner); + mutex_unlock(&ca->remove_mutex); return err; } @@ -1736,6 +1754,7 @@ dvb_ca_private_get(ca); + mutex_unlock(&ca->remove_mutex); return 0; } @@ -1755,6 +1774,8 @@ dprintk("%s\n", __func__); + mutex_lock(&ca->remove_mutex); + /* mark the CA device as closed */ ca->open = 0; dvb_ca_en50221_thread_update_delay(ca); @@ -1765,6 +1786,13 @@ dvb_ca_private_put(ca); + if (dvbdev->users == 1 && ca->exit == 1) { + mutex_unlock(&ca->remove_mutex); + wake_up(&dvbdev->wait_queue); + } else { + mutex_unlock(&ca->remove_mutex); + } + return err; } @@ -1888,6 +1916,7 @@ } mutex_init(&ca->ioctl_mutex); + mutex_init(&ca->remove_mutex); if (signal_pending(current)) { ret = -EINTR; @@ -1930,6 +1959,14 @@ dprintk("%s\n", __func__); + mutex_lock(&ca->remove_mutex); + ca->exit = 1; + mutex_unlock(&ca->remove_mutex); + + if (ca->dvbdev->users < 1) + wait_event(ca->dvbdev->wait_queue, + ca->dvbdev->users == 1); + /* shutdown the thread if there was one */ kthread_stop(ca->thread); --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dvb_demux.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dvb_demux.c @@ -125,12 +125,12 @@ cc = buf[3] & 0x0f; ccok = ((feed->cc + 1) & 0x0f) == cc; - feed->cc = cc; if (!ccok) { set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); dprintk_sect_loss("missed packet: %d instead of %d!\n", cc, (feed->cc + 1) & 0x0f); } + feed->cc = cc; if (buf[1] & 0x40) // PUSI ? feed->peslen = 0xfffa; @@ -310,7 +310,6 @@ cc = buf[3] & 0x0f; ccok = ((feed->cc + 1) & 0x0f) == cc; - feed->cc = cc; if (buf[3] & 0x20) { /* adaption field present, check for discontinuity_indicator */ @@ -346,6 +345,7 @@ feed->pusi_seen = false; dvb_dmx_swfilter_section_new(feed); } + feed->cc = cc; if (buf[1] & 0x40) { /* PUSI=1 (is set), section boundary is here */ --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dvb_frontend.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dvb_frontend.c @@ -135,7 +135,7 @@ struct dvb_frontend_private *fepriv = fe->frontend_priv; if (fepriv) - dvb_free_device(fepriv->dvbdev); + dvb_device_put(fepriv->dvbdev); dvb_frontend_invoke_release(fe, fe->ops.release); @@ -292,14 +292,22 @@ } if (events->eventw == events->eventr) { - int ret; + struct wait_queue_entry wait; + int ret = 0; if (flags & O_NONBLOCK) return -EWOULDBLOCK; - ret = wait_event_interruptible(events->wait_queue, - dvb_frontend_test_event(fepriv, events)); - + init_waitqueue_entry(&wait, current); + add_wait_queue(&events->wait_queue, &wait); + while (!dvb_frontend_test_event(fepriv, events)) { + wait_woken(&wait, TASK_INTERRUPTIBLE, 0); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + } + remove_wait_queue(&events->wait_queue, &wait); if (ret < 0) return ret; } @@ -434,8 +442,8 @@ default: fepriv->auto_step++; - fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */ - break; + fepriv->auto_sub_step = 0; + continue; } if (!ready) fepriv->auto_sub_step++; @@ -2961,6 +2969,7 @@ .name = fe->ops.info.name, #endif }; + int ret; dev_dbg(dvb->device, "%s:\n", __func__); @@ -2994,8 +3003,13 @@ "DVB: registering adapter %i frontend %i (%s)...\n", fe->dvb->num, fe->id, fe->ops.info.name); - dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template, + ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template, fe, DVB_DEVICE_FRONTEND, 0); + if (ret) { + dvb_frontend_put(fe); + mutex_unlock(&frontend_mutex); + return ret; + } /* * Initialize the cache to the proper values according with the --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dvb_net.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dvb_net.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1462,14 +1463,20 @@ struct net_device *netdev; struct dvb_net_priv *priv_data; struct dvb_net_if *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { ret = -EINVAL; goto ioctl_error; } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); - netdev = dvbnet->device[dvbnetif->if_num]; + if (!dvbnet->state[if_num]) { + ret = -EINVAL; + goto ioctl_error; + } + + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; @@ -1522,14 +1529,20 @@ struct net_device *netdev; struct dvb_net_priv *priv_data; struct __dvb_net_if_old *dvbnetif = parg; + int if_num = dvbnetif->if_num; + + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; @@ -1551,15 +1564,43 @@ return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); } +static int locked_dvb_net_open(struct inode *inode, struct file *file) +{ + struct dvb_device *dvbdev = file->private_data; + struct dvb_net *dvbnet = dvbdev->priv; + int ret; + + if (mutex_lock_interruptible(&dvbnet->remove_mutex)) + return -ERESTARTSYS; + + if (dvbnet->exit) { + mutex_unlock(&dvbnet->remove_mutex); + return -ENODEV; + } + + ret = dvb_generic_open(inode, file); + + mutex_unlock(&dvbnet->remove_mutex); + + return ret; +} + static int dvb_net_close(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct dvb_net *dvbnet = dvbdev->priv; + mutex_lock(&dvbnet->remove_mutex); + dvb_generic_release(inode, file); - if(dvbdev->users == 1 && dvbnet->exit == 1) + if (dvbdev->users == 1 && dvbnet->exit == 1) { + mutex_unlock(&dvbnet->remove_mutex); wake_up(&dvbdev->wait_queue); + } else { + mutex_unlock(&dvbnet->remove_mutex); + } + return 0; } @@ -1567,7 +1608,7 @@ static const struct file_operations dvb_net_fops = { .owner = THIS_MODULE, .unlocked_ioctl = dvb_net_ioctl, - .open = dvb_generic_open, + .open = locked_dvb_net_open, .release = dvb_net_close, .llseek = noop_llseek, }; @@ -1586,10 +1627,13 @@ { int i; + mutex_lock(&dvbnet->remove_mutex); dvbnet->exit = 1; + mutex_unlock(&dvbnet->remove_mutex); + if (dvbnet->dvbdev->users < 1) wait_event(dvbnet->dvbdev->wait_queue, - dvbnet->dvbdev->users==1); + dvbnet->dvbdev->users == 1); dvb_unregister_device(dvbnet->dvbdev); @@ -1608,6 +1652,7 @@ int i; mutex_init(&dvbnet->ioctl_mutex); + mutex_init(&dvbnet->remove_mutex); dvbnet->demux = dmx; for (i=0; ivb_q; + + if (b->index >= q->num_buffers) { + dprintk(1, "[%s] buffer index out of range\n", ctx->name); + return -EINVAL; + } vb2_core_querybuf(&ctx->vb_q, b->index, b); dprintk(3, "[%s] index=%d\n", ctx->name, b->index); return 0; @@ -382,8 +388,13 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) { + struct vb2_queue *q = &ctx->vb_q; int ret; + if (b->index >= q->num_buffers) { + dprintk(1, "[%s] buffer index out of range\n", ctx->name); + return -EINVAL; + } ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL); if (ret) { dprintk(1, "[%s] index=%d errno=%d\n", ctx->name, --- linux-oracle-5.4.0.orig/drivers/media/dvb-core/dvbdev.c +++ linux-oracle-5.4.0/drivers/media/dvb-core/dvbdev.c @@ -37,6 +37,7 @@ #include static DEFINE_MUTEX(dvbdev_mutex); +static LIST_HEAD(dvbdevfops_list); static int dvbdev_debug; module_param(dvbdev_debug, int, 0644); @@ -95,10 +96,15 @@ static int dvb_device_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev; + unsigned int minor = iminor(inode); + + if (minor >= MAX_DVB_MINORS) + return -ENODEV; mutex_lock(&dvbdev_mutex); down_read(&minor_rwsem); - dvbdev = dvb_minors[iminor(inode)]; + + dvbdev = dvb_minors[minor]; if (dvbdev && dvbdev->fops) { int err = 0; @@ -107,12 +113,14 @@ new_fops = fops_get(dvbdev->fops); if (!new_fops) goto fail; - file->private_data = dvbdev; + file->private_data = dvb_device_get(dvbdev); replace_fops(file, new_fops); if (file->f_op->open) err = file->f_op->open(inode, file); up_read(&minor_rwsem); mutex_unlock(&dvbdev_mutex); + if (err) + dvb_device_put(dvbdev); return err; } fail: @@ -171,6 +179,9 @@ } dvbdev->users++; + + dvb_device_put(dvbdev); + return 0; } EXPORT_SYMBOL(dvb_generic_release); @@ -241,6 +252,7 @@ if (dvbdev->adapter->conn) { media_device_unregister_entity(dvbdev->adapter->conn); + kfree(dvbdev->adapter->conn); dvbdev->adapter->conn = NULL; kfree(dvbdev->adapter->conn_pads); dvbdev->adapter->conn_pads = NULL; @@ -341,6 +353,7 @@ GFP_KERNEL); if (!dvbdev->pads) { kfree(dvbdev->entity); + dvbdev->entity = NULL; return -ENOMEM; } } @@ -457,14 +470,15 @@ enum dvb_device_type type, int demux_sink_pads) { struct dvb_device *dvbdev; - struct file_operations *dvbdevfops; + struct file_operations *dvbdevfops = NULL; + struct dvbdevfops_node *node = NULL, *new_node = NULL; struct device *clsdev; int minor; int id, ret; mutex_lock(&dvbdev_register_lock); - if ((id = dvbdev_get_free_id (adap, type)) < 0){ + if ((id = dvbdev_get_free_id (adap, type)) < 0) { mutex_unlock(&dvbdev_register_lock); *pdvbdev = NULL; pr_err("%s: couldn't find free device id\n", __func__); @@ -472,78 +486,124 @@ } *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL); - if (!dvbdev){ mutex_unlock(&dvbdev_register_lock); return -ENOMEM; } - dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); + /* + * When a device of the same type is probe()d more than once, + * the first allocated fops are used. This prevents memory leaks + * that can occur when the same device is probe()d repeatedly. + */ + list_for_each_entry(node, &dvbdevfops_list, list_head) { + if (node->fops->owner == adap->module && + node->type == type && + node->template == template) { + dvbdevfops = node->fops; + break; + } + } - if (!dvbdevfops){ - kfree (dvbdev); - mutex_unlock(&dvbdev_register_lock); - return -ENOMEM; + if (dvbdevfops == NULL) { + dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); + if (!dvbdevfops) { + kfree(dvbdev); + *pdvbdev = NULL; + mutex_unlock(&dvbdev_register_lock); + return -ENOMEM; + } + + new_node = kzalloc(sizeof(struct dvbdevfops_node), GFP_KERNEL); + if (!new_node) { + kfree(dvbdevfops); + kfree(dvbdev); + *pdvbdev = NULL; + mutex_unlock(&dvbdev_register_lock); + return -ENOMEM; + } + + new_node->fops = dvbdevfops; + new_node->type = type; + new_node->template = template; + list_add_tail (&new_node->list_head, &dvbdevfops_list); } memcpy(dvbdev, template, sizeof(struct dvb_device)); + kref_init(&dvbdev->ref); dvbdev->type = type; dvbdev->id = id; dvbdev->adapter = adap; dvbdev->priv = priv; dvbdev->fops = dvbdevfops; init_waitqueue_head (&dvbdev->wait_queue); - dvbdevfops->owner = adap->module; - list_add_tail (&dvbdev->list_head, &adap->device_list); - down_write(&minor_rwsem); #ifdef CONFIG_DVB_DYNAMIC_MINORS for (minor = 0; minor < MAX_DVB_MINORS; minor++) if (dvb_minors[minor] == NULL) break; - - if (minor == MAX_DVB_MINORS) { - kfree(dvbdevfops); +#else + minor = nums2minor(adap->num, type, id); +#endif + if (minor >= MAX_DVB_MINORS) { + if (new_node) { + list_del (&new_node->list_head); + kfree(dvbdevfops); + kfree(new_node); + } + list_del (&dvbdev->list_head); kfree(dvbdev); + *pdvbdev = NULL; up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); return -EINVAL; } -#else - minor = nums2minor(adap->num, type, id); -#endif dvbdev->minor = minor; - dvb_minors[minor] = dvbdev; + dvb_minors[minor] = dvb_device_get(dvbdev); up_write(&minor_rwsem); - ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); if (ret) { pr_err("%s: dvb_register_media_device failed to create the mediagraph\n", __func__); - + if (new_node) { + list_del (&new_node->list_head); + kfree(dvbdevfops); + kfree(new_node); + } dvb_media_device_free(dvbdev); - kfree(dvbdevfops); + list_del (&dvbdev->list_head); kfree(dvbdev); + *pdvbdev = NULL; mutex_unlock(&dvbdev_register_lock); return ret; } - mutex_unlock(&dvbdev_register_lock); - clsdev = device_create(dvb_class, adap->device, MKDEV(DVB_MAJOR, minor), dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); if (IS_ERR(clsdev)) { pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + if (new_node) { + list_del (&new_node->list_head); + kfree(dvbdevfops); + kfree(new_node); + } + dvb_media_device_free(dvbdev); + list_del (&dvbdev->list_head); + kfree(dvbdev); + *pdvbdev = NULL; + mutex_unlock(&dvbdev_register_lock); return PTR_ERR(clsdev); } + dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", adap->num, dnames[type], id, minor, minor); + mutex_unlock(&dvbdev_register_lock); return 0; } EXPORT_SYMBOL(dvb_register_device); @@ -556,6 +616,7 @@ down_write(&minor_rwsem); dvb_minors[dvbdev->minor] = NULL; + dvb_device_put(dvbdev); up_write(&minor_rwsem); dvb_media_device_free(dvbdev); @@ -567,21 +628,33 @@ EXPORT_SYMBOL(dvb_remove_device); -void dvb_free_device(struct dvb_device *dvbdev) +static void dvb_free_device(struct kref *ref) { - if (!dvbdev) - return; + struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref); - kfree (dvbdev->fops); kfree (dvbdev); } -EXPORT_SYMBOL(dvb_free_device); + + +struct dvb_device *dvb_device_get(struct dvb_device *dvbdev) +{ + kref_get(&dvbdev->ref); + return dvbdev; +} +EXPORT_SYMBOL(dvb_device_get); + + +void dvb_device_put(struct dvb_device *dvbdev) +{ + if (dvbdev) + kref_put(&dvbdev->ref, dvb_free_device); +} void dvb_unregister_device(struct dvb_device *dvbdev) { dvb_remove_device(dvbdev); - dvb_free_device(dvbdev); + dvb_device_put(dvbdev); } EXPORT_SYMBOL(dvb_unregister_device); @@ -707,9 +780,10 @@ } if (ntuner && ndemod) { - pad_source = media_get_pad_index(tuner, true, + /* NOTE: first found tuner source pad presumed correct */ + pad_source = media_get_pad_index(tuner, false, PAD_SIGNAL_ANALOG); - if (pad_source) + if (pad_source < 0) return -EINVAL; ret = media_create_pad_links(mdev, MEDIA_ENT_F_TUNER, @@ -906,7 +980,7 @@ int (*func)(struct file *file, unsigned int cmd, void *arg)) { - char sbuf[128]; + char sbuf[128] = {}; void *mbuf = NULL; void *parg = NULL; int err = -EINVAL; @@ -1063,9 +1137,17 @@ static void __exit exit_dvbdev(void) { + struct dvbdevfops_node *node, *next; + class_destroy(dvb_class); cdev_del(&dvb_device_cdev); unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); + + list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) { + list_del (&node->list_head); + kfree(node->fops); + kfree(node); + } } subsys_initcall(init_dvbdev); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/as102_fe_types.h +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/as102_fe_types.h @@ -174,6 +174,6 @@ uint32_t addr; /* register mode access */ uint8_t mode; -}; +} __packed; #endif --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ascot2e.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ascot2e.c @@ -533,7 +533,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(ascot2e_attach); +EXPORT_SYMBOL_GPL(ascot2e_attach); MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver"); MODULE_AUTHOR("info@netup.ru"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/atbm8830.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/atbm8830.c @@ -489,7 +489,7 @@ return NULL; } -EXPORT_SYMBOL(atbm8830_attach); +EXPORT_SYMBOL_GPL(atbm8830_attach); MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver"); MODULE_AUTHOR("David T. L. Wong "); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/au8522_dig.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/au8522_dig.c @@ -879,7 +879,7 @@ au8522_release_state(state); return NULL; } -EXPORT_SYMBOL(au8522_attach); +EXPORT_SYMBOL_GPL(au8522_attach); static const struct dvb_frontend_ops au8522_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/bcm3510.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/bcm3510.c @@ -649,6 +649,7 @@ deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { err("firmware download failed: %d\n",ret); + release_firmware(fw); return ret; } i += 4 + len; @@ -834,7 +835,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(bcm3510_attach); +EXPORT_SYMBOL_GPL(bcm3510_attach); static const struct dvb_frontend_ops bcm3510_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx22700.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx22700.c @@ -432,4 +432,4 @@ MODULE_AUTHOR("Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(cx22700_attach); +EXPORT_SYMBOL_GPL(cx22700_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx22702.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx22702.c @@ -604,7 +604,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(cx22702_attach); +EXPORT_SYMBOL_GPL(cx22702_attach); static const struct dvb_frontend_ops cx22702_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx24110.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx24110.c @@ -653,4 +653,4 @@ MODULE_AUTHOR("Peter Hettkamp"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(cx24110_attach); +EXPORT_SYMBOL_GPL(cx24110_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx24113.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx24113.c @@ -590,7 +590,7 @@ return NULL; } -EXPORT_SYMBOL(cx24113_attach); +EXPORT_SYMBOL_GPL(cx24113_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx24116.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx24116.c @@ -741,6 +741,7 @@ { struct cx24116_state *state = fe->demodulator_priv; u8 snr_reading; + int ret; static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, @@ -749,7 +750,11 @@ dprintk("%s()\n", __func__); - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); + ret = cx24116_readreg(state, CX24116_REG_QUALITY0); + if (ret < 0) + return ret; + + snr_reading = ret; if (snr_reading >= 0xa0 /* 100% */) *snr = 0xffff; @@ -1133,7 +1138,7 @@ state->frontend.demodulator_priv = state; return &state->frontend; } -EXPORT_SYMBOL(cx24116_attach); +EXPORT_SYMBOL_GPL(cx24116_attach); /* * Initialise or wake up device --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx24120.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx24120.c @@ -305,7 +305,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(cx24120_attach); +EXPORT_SYMBOL_GPL(cx24120_attach); static int cx24120_test_rom(struct cx24120_state *state) { @@ -972,7 +972,9 @@ cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff; cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; - cx24120_message_send(state, &cmd); + ret = cx24120_message_send(state, &cmd); + if (ret != 0) + return; /* Calculate ber window rates for stat work */ cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cx24123.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cx24123.c @@ -1096,7 +1096,7 @@ return NULL; } -EXPORT_SYMBOL(cx24123_attach); +EXPORT_SYMBOL_GPL(cx24123_attach); static const struct dvb_frontend_ops cx24123_ops = { .delsys = { SYS_DVBS }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cxd2820r_core.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cxd2820r_core.c @@ -536,7 +536,7 @@ return pdata.get_dvb_frontend(client); } -EXPORT_SYMBOL(cxd2820r_attach); +EXPORT_SYMBOL_GPL(cxd2820r_attach); static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client) { --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cxd2841er.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cxd2841er.c @@ -310,12 +310,8 @@ static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz) { - u64 tmp; - - tmp = (u64) ifhz * 16777216; - do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000)); - - return (u32) tmp; + return div_u64(ifhz * 16777216ull, + (xtal == SONY_XTAL_24000) ? 48000000 : 41000000); } static u32 cxd2841er_calc_iffreq(u32 ifhz) @@ -3920,14 +3916,14 @@ { return cxd2841er_attach(cfg, i2c, SYS_DVBS); } -EXPORT_SYMBOL(cxd2841er_attach_s); +EXPORT_SYMBOL_GPL(cxd2841er_attach_s); struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, struct i2c_adapter *i2c) { return cxd2841er_attach(cfg, i2c, 0); } -EXPORT_SYMBOL(cxd2841er_attach_t_c); +EXPORT_SYMBOL_GPL(cxd2841er_attach_t_c); static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c @@ -1950,7 +1950,7 @@ return fe; } -EXPORT_SYMBOL(cxd2880_attach); +EXPORT_SYMBOL_GPL(cxd2880_attach); MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver"); MODULE_AUTHOR("Sony Semiconductor Solutions Corporation"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib0070.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib0070.c @@ -755,7 +755,7 @@ fe->tuner_priv = NULL; return NULL; } -EXPORT_SYMBOL(dib0070_attach); +EXPORT_SYMBOL_GPL(dib0070_attach); MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib0090.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib0090.c @@ -2631,7 +2631,7 @@ return NULL; } -EXPORT_SYMBOL(dib0090_register); +EXPORT_SYMBOL_GPL(dib0090_register); struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { @@ -2657,7 +2657,7 @@ fe->tuner_priv = NULL; return NULL; } -EXPORT_SYMBOL(dib0090_fw_register); +EXPORT_SYMBOL_GPL(dib0090_fw_register); MODULE_AUTHOR("Patrick Boettcher "); MODULE_AUTHOR("Olivier Grenie "); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib3000mb.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib3000mb.c @@ -51,7 +51,7 @@ static int dib3000_read_reg(struct dib3000_state *state, u16 reg) { u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; - u8 rb[2]; + u8 rb[2] = {}; struct i2c_msg msg[] = { { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 }, { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, @@ -815,4 +815,4 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(dib3000mb_attach); +EXPORT_SYMBOL_GPL(dib3000mb_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib3000mc.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib3000mc.c @@ -935,7 +935,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib3000mc_attach); +EXPORT_SYMBOL_GPL(dib3000mc_attach); static const struct dvb_frontend_ops dib3000mc_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib7000m.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib7000m.c @@ -1434,7 +1434,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib7000m_attach); +EXPORT_SYMBOL_GPL(dib7000m_attach); static const struct dvb_frontend_ops dib7000m_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib7000p.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib7000p.c @@ -497,7 +497,7 @@ prediv = reg_1856 & 0x3f; loopdiv = (reg_1856 >> 6) & 0x3f; - if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { + if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); reg_1856 &= 0xf000; reg_1857 = dib7000p_read_word(state, 1857); @@ -2822,7 +2822,7 @@ return ops; } -EXPORT_SYMBOL(dib7000p_attach); +EXPORT_SYMBOL_GPL(dib7000p_attach); static const struct dvb_frontend_ops dib7000p_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib8000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib8000.c @@ -2107,32 +2107,55 @@ dib8000_write_word(state, 117 + mode, ana_fe[mode]); } -static const u16 lut_prbs_2k[14] = { - 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213 +static const u16 lut_prbs_2k[13] = { + 0x423, 0x009, 0x5C7, + 0x7A6, 0x3D8, 0x527, + 0x7FF, 0x79B, 0x3D6, + 0x3A2, 0x53B, 0x2F4, + 0x213 }; -static const u16 lut_prbs_4k[14] = { - 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E + +static const u16 lut_prbs_4k[13] = { + 0x208, 0x0C3, 0x7B9, + 0x423, 0x5C7, 0x3D8, + 0x7FF, 0x3D6, 0x53B, + 0x213, 0x029, 0x0D0, + 0x48E }; -static const u16 lut_prbs_8k[14] = { - 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684 + +static const u16 lut_prbs_8k[13] = { + 0x740, 0x069, 0x7DD, + 0x208, 0x7B9, 0x5C7, + 0x7FF, 0x53B, 0x029, + 0x48E, 0x4C4, 0x367, + 0x684 }; static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel) { int sub_channel_prbs_group = 0; + int prbs_group; - sub_channel_prbs_group = (subchannel / 3) + 1; - dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]); + sub_channel_prbs_group = subchannel / 3; + if (sub_channel_prbs_group >= ARRAY_SIZE(lut_prbs_2k)) + return 0; switch (state->fe[0]->dtv_property_cache.transmission_mode) { case TRANSMISSION_MODE_2K: - return lut_prbs_2k[sub_channel_prbs_group]; + prbs_group = lut_prbs_2k[sub_channel_prbs_group]; + break; case TRANSMISSION_MODE_4K: - return lut_prbs_4k[sub_channel_prbs_group]; + prbs_group = lut_prbs_4k[sub_channel_prbs_group]; + break; default: case TRANSMISSION_MODE_8K: - return lut_prbs_8k[sub_channel_prbs_group]; + prbs_group = lut_prbs_8k[sub_channel_prbs_group]; } + + dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x\n", + sub_channel_prbs_group, subchannel, prbs_group); + + return prbs_group; } static void dib8000_set_13seg_channel(struct dib8000_state *state) @@ -2409,10 +2432,8 @@ /* TSB or ISDBT ? apply it now */ if (c->isdbt_sb_mode) { dib8000_set_sb_channel(state); - if (c->isdbt_sb_subchannel < 14) - init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel); - else - init_prbs = 0; + init_prbs = dib8000_get_init_prbs(state, + c->isdbt_sb_subchannel); } else { dib8000_set_13seg_channel(state); init_prbs = 0xfff; @@ -3004,6 +3025,7 @@ unsigned long *timeout = &state->timeout; unsigned long now = jiffies; + u16 init_prbs; #ifdef DIB8000_AGC_FREEZE u16 agc1, agc2; #endif @@ -3302,8 +3324,10 @@ break; case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */ - if (state->subchannel <= 41) { - dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel)); + init_prbs = dib8000_get_init_prbs(state, state->subchannel); + + if (init_prbs) { + dib8000_set_subchannel_prbs(state, init_prbs); *tune_state = CT_DEMOD_STEP_9; } else { *tune_state = CT_DEMOD_STOP; @@ -4449,8 +4473,10 @@ state->timf_default = cfg->pll->timf; - if (dib8000_identify(&state->i2c) == 0) + if (dib8000_identify(&state->i2c) == 0) { + kfree(fe); goto error; + } dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); @@ -4501,7 +4527,7 @@ return ops; } -EXPORT_SYMBOL(dib8000_attach); +EXPORT_SYMBOL_GPL(dib8000_attach); MODULE_AUTHOR("Olivier Grenie "); MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dib9000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dib9000.c @@ -2546,7 +2546,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib9000_attach); +EXPORT_SYMBOL_GPL(dib9000_attach); static const struct dvb_frontend_ops dib9000_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -12366,7 +12366,7 @@ return NULL; } -EXPORT_SYMBOL(drx39xxj_attach); +EXPORT_SYMBOL_GPL(drx39xxj_attach); static const struct dvb_frontend_ops drx39xxj_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/drxd_hard.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/drxd_hard.c @@ -2948,7 +2948,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(drxd_attach); +EXPORT_SYMBOL_GPL(drxd_attach); MODULE_DESCRIPTION("DRXD driver"); MODULE_AUTHOR("Micronas"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/drxk_hard.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/drxk_hard.c @@ -6684,7 +6684,7 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) { struct drxk_state *state = fe->demodulator_priv; - u16 err; + u16 err = 0; dprintk(1, "\n"); @@ -6857,7 +6857,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(drxk_attach); +EXPORT_SYMBOL_GPL(drxk_attach); MODULE_DESCRIPTION("DRX-K driver"); MODULE_AUTHOR("Ralph Metzler"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ds3000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ds3000.c @@ -859,7 +859,7 @@ ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF); return &state->frontend; } -EXPORT_SYMBOL(ds3000_attach); +EXPORT_SYMBOL_GPL(ds3000_attach); static int ds3000_set_carrier_offset(struct dvb_frontend *fe, s32 carrier_offset_khz) --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/dvb-pll.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/dvb-pll.c @@ -866,7 +866,7 @@ return NULL; } -EXPORT_SYMBOL(dvb_pll_attach); +EXPORT_SYMBOL_GPL(dvb_pll_attach); static int --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ec100.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ec100.c @@ -299,7 +299,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(ec100_attach); +EXPORT_SYMBOL_GPL(ec100_attach); static const struct dvb_frontend_ops ec100_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/helene.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/helene.c @@ -1025,7 +1025,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(helene_attach_s); +EXPORT_SYMBOL_GPL(helene_attach_s); struct dvb_frontend *helene_attach(struct dvb_frontend *fe, const struct helene_config *config, @@ -1061,7 +1061,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(helene_attach); +EXPORT_SYMBOL_GPL(helene_attach); static int helene_probe(struct i2c_client *client, const struct i2c_device_id *id) --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/horus3a.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/horus3a.c @@ -395,7 +395,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(horus3a_attach); +EXPORT_SYMBOL_GPL(horus3a_attach); MODULE_DESCRIPTION("Sony HORUS3A satellite tuner driver"); MODULE_AUTHOR("Sergey Kozlov "); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/isl6405.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/isl6405.c @@ -141,7 +141,7 @@ return fe; } -EXPORT_SYMBOL(isl6405_attach); +EXPORT_SYMBOL_GPL(isl6405_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405"); MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/isl6421.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/isl6421.c @@ -213,7 +213,7 @@ return fe; } -EXPORT_SYMBOL(isl6421_attach); +EXPORT_SYMBOL_GPL(isl6421_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/isl6423.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/isl6423.c @@ -289,7 +289,7 @@ fe->sec_priv = NULL; return NULL; } -EXPORT_SYMBOL(isl6423_attach); +EXPORT_SYMBOL_GPL(isl6423_attach); MODULE_DESCRIPTION("ISL6423 SEC"); MODULE_AUTHOR("Manu Abraham"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/itd1000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/itd1000.c @@ -389,7 +389,7 @@ return fe; } -EXPORT_SYMBOL(itd1000_attach); +EXPORT_SYMBOL_GPL(itd1000_attach); MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Integrant ITD1000 driver"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ix2505v.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ix2505v.c @@ -302,7 +302,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(ix2505v_attach); +EXPORT_SYMBOL_GPL(ix2505v_attach); module_param_named(debug, ix2505v_debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/l64781.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/l64781.c @@ -593,4 +593,4 @@ MODULE_AUTHOR("Holger Waechtler, Marko Kohtala"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(l64781_attach); +EXPORT_SYMBOL_GPL(l64781_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lg2160.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lg2160.c @@ -1426,7 +1426,7 @@ return &state->frontend; } -EXPORT_SYMBOL(lg2160_attach); +EXPORT_SYMBOL_GPL(lg2160_attach); MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); MODULE_AUTHOR("Michael Krufky "); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lgdt3305.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lgdt3305.c @@ -1148,7 +1148,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(lgdt3305_attach); +EXPORT_SYMBOL_GPL(lgdt3305_attach); static const struct dvb_frontend_ops lgdt3304_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lgdt3306a.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lgdt3306a.c @@ -1881,7 +1881,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(lgdt3306a_attach); +EXPORT_SYMBOL_GPL(lgdt3306a_attach); #ifdef DBG_DUMP @@ -2199,6 +2199,11 @@ struct dvb_frontend *fe; int ret; + if (!client->dev.platform_data) { + dev_err(&client->dev, "platform data is mandatory\n"); + return -EINVAL; + } + config = kmemdup(client->dev.platform_data, sizeof(struct lgdt3306a_config), GFP_KERNEL); if (config == NULL) { --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lgdt330x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lgdt330x.c @@ -928,7 +928,7 @@ return lgdt330x_get_dvb_frontend(client); } -EXPORT_SYMBOL(lgdt330x_attach); +EXPORT_SYMBOL_GPL(lgdt330x_attach); static const struct dvb_frontend_ops lgdt3302_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lgs8gxx.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lgs8gxx.c @@ -1043,7 +1043,7 @@ return NULL; } -EXPORT_SYMBOL(lgs8gxx_attach); +EXPORT_SYMBOL_GPL(lgs8gxx_attach); MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); MODULE_AUTHOR("David T. L. Wong "); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lnbh25.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lnbh25.c @@ -173,7 +173,7 @@ __func__, priv->i2c_address); return fe; } -EXPORT_SYMBOL(lnbh25_attach); +EXPORT_SYMBOL_GPL(lnbh25_attach); MODULE_DESCRIPTION("ST LNBH25 driver"); MODULE_AUTHOR("info@netup.ru"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lnbp21.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lnbp21.c @@ -155,7 +155,7 @@ return lnbx2x_attach(fe, i2c, override_set, override_clear, i2c_addr, LNBH24_TTX); } -EXPORT_SYMBOL(lnbh24_attach); +EXPORT_SYMBOL_GPL(lnbh24_attach); struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, @@ -164,7 +164,7 @@ return lnbx2x_attach(fe, i2c, override_set, override_clear, 0x08, LNBP21_ISEL); } -EXPORT_SYMBOL(lnbp21_attach); +EXPORT_SYMBOL_GPL(lnbp21_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/lnbp22.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/lnbp22.c @@ -125,7 +125,7 @@ return fe; } -EXPORT_SYMBOL(lnbp22_attach); +EXPORT_SYMBOL_GPL(lnbp22_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22"); MODULE_AUTHOR("Dominik Kuhlen"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/m88ds3103.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/m88ds3103.c @@ -1284,7 +1284,7 @@ *tuner_i2c_adapter = pdata.get_i2c_adapter(client); return pdata.get_dvb_frontend(client); } -EXPORT_SYMBOL(m88ds3103_attach); +EXPORT_SYMBOL_GPL(m88ds3103_attach); static const struct dvb_frontend_ops m88ds3103_ops = { .delsys = {SYS_DVBS, SYS_DVBS2}, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/m88rs2000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/m88rs2000.c @@ -807,7 +807,7 @@ return NULL; } -EXPORT_SYMBOL(m88rs2000_attach); +EXPORT_SYMBOL_GPL(m88rs2000_attach); MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mb86a16.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mb86a16.c @@ -1851,6 +1851,6 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(mb86a16_attach); +EXPORT_SYMBOL_GPL(mb86a16_attach); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Manu Abraham"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mb86a20s.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mb86a20s.c @@ -2089,7 +2089,7 @@ dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n"); return &state->frontend; } -EXPORT_SYMBOL(mb86a20s_attach); +EXPORT_SYMBOL_GPL(mb86a20s_attach); static const struct dvb_frontend_ops mb86a20s_ops = { .delsys = { SYS_ISDBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mn88443x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mn88443x.c @@ -204,11 +204,18 @@ struct regmap *regmap_t; }; -static void mn88443x_cmn_power_on(struct mn88443x_priv *chip) +static int mn88443x_cmn_power_on(struct mn88443x_priv *chip) { + struct device *dev = &chip->client_s->dev; struct regmap *r_t = chip->regmap_t; + int ret; - clk_prepare_enable(chip->mclk); + ret = clk_prepare_enable(chip->mclk); + if (ret) { + dev_err(dev, "Failed to prepare and enable mclk: %d\n", + ret); + return ret; + } gpiod_set_value_cansleep(chip->reset_gpio, 1); usleep_range(100, 1000); @@ -222,6 +229,8 @@ } else { regmap_write(r_t, HIZSET3, 0x8f); } + + return 0; } static void mn88443x_cmn_power_off(struct mn88443x_priv *chip) @@ -738,7 +747,10 @@ chip->fe.demodulator_priv = chip; i2c_set_clientdata(client, chip); - mn88443x_cmn_power_on(chip); + ret = mn88443x_cmn_power_on(chip); + if (ret) + goto err_i2c_t; + mn88443x_s_sleep(chip); mn88443x_t_sleep(chip); @@ -788,7 +800,7 @@ static struct i2c_driver mn88443x_driver = { .driver = { .name = "mn88443x", - .of_match_table = of_match_ptr(mn88443x_of_match), + .of_match_table = mn88443x_of_match, }, .probe = mn88443x_probe, .remove = mn88443x_remove, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mt312.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mt312.c @@ -832,7 +832,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(mt312_attach); +EXPORT_SYMBOL_GPL(mt312_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mt352.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mt352.c @@ -593,4 +593,4 @@ MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(mt352_attach); +EXPORT_SYMBOL_GPL(mt352_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/mxl5xx.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/mxl5xx.c @@ -1391,57 +1391,57 @@ u32 nco_count_min = 0; u32 clk_type = 0; - struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 8, 1}, {0x90700010, 9, 1}, {0x90700010, 10, 1}, {0x90700010, 11, 1}, {0x90700010, 12, 1}, {0x90700010, 13, 1}, {0x90700010, 14, 1}, {0x90700010, 15, 1} }; - struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 16, 1}, {0x90700010, 17, 1}, {0x90700010, 18, 1}, {0x90700010, 19, 1}, {0x90700010, 20, 1}, {0x90700010, 21, 1}, {0x90700010, 22, 1}, {0x90700010, 23, 1} }; - struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { {0x90700014, 0, 1}, {0x90700014, 1, 1}, {0x90700014, 2, 1}, {0x90700014, 3, 1}, {0x90700014, 4, 1}, {0x90700014, 5, 1}, {0x90700014, 6, 1}, {0x90700014, 7, 1} }; - struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { {0x90700018, 0, 3}, {0x90700018, 4, 3}, {0x90700018, 8, 3}, {0x90700018, 12, 3}, {0x90700018, 16, 3}, {0x90700018, 20, 3}, {0x90700018, 24, 3}, {0x90700018, 28, 3} }; - struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 16, 1}, {0x9070000C, 17, 1}, {0x9070000C, 18, 1}, {0x9070000C, 19, 1}, {0x9070000C, 20, 1}, {0x9070000C, 21, 1}, {0x9070000C, 22, 1}, {0x9070000C, 23, 1} }; - struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { {0x90700010, 0, 1}, {0x90700010, 1, 1}, {0x90700010, 2, 1}, {0x90700010, 3, 1}, {0x90700010, 4, 1}, {0x90700010, 5, 1}, {0x90700010, 6, 1}, {0x90700010, 7, 1} }; - struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 0, 1}, {0x9070000C, 1, 1}, {0x9070000C, 2, 1}, {0x9070000C, 3, 1}, {0x9070000C, 4, 1}, {0x9070000C, 5, 1}, {0x9070000C, 6, 1}, {0x9070000C, 7, 1} }; - struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { {0x9070000C, 24, 1}, {0x9070000C, 25, 1}, {0x9070000C, 26, 1}, {0x9070000C, 27, 1}, {0x9070000C, 28, 1}, {0x9070000C, 29, 1}, {0x9070000C, 30, 1}, {0x9070000C, 31, 1} }; - struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { {0x90700014, 8, 1}, {0x90700014, 9, 1}, {0x90700014, 10, 1}, {0x90700014, 11, 1}, {0x90700014, 12, 1}, {0x90700014, 13, 1}, {0x90700014, 14, 1}, {0x90700014, 15, 1} }; - struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { {0x907001D4, 0, 1}, {0x907001D4, 1, 1}, {0x907001D4, 2, 1}, {0x907001D4, 3, 1}, {0x907001D4, 4, 1}, {0x907001D4, 5, 1}, {0x907001D4, 6, 1}, {0x907001D4, 7, 1} }; - struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { + static const struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { {0x90700044, 16, 80}, {0x90700044, 16, 81}, {0x90700044, 16, 82}, {0x90700044, 16, 83}, {0x90700044, 16, 84}, {0x90700044, 16, 85}, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/nxt200x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/nxt200x.c @@ -1232,5 +1232,5 @@ MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(nxt200x_attach); +EXPORT_SYMBOL_GPL(nxt200x_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/nxt6000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/nxt6000.c @@ -621,4 +621,4 @@ MODULE_AUTHOR("Florian Schirmer"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(nxt6000_attach); +EXPORT_SYMBOL_GPL(nxt6000_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/or51132.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/or51132.c @@ -605,4 +605,4 @@ MODULE_AUTHOR("Trent Piepho"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(or51132_attach); +EXPORT_SYMBOL_GPL(or51132_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/or51211.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/or51211.c @@ -551,5 +551,5 @@ MODULE_AUTHOR("Kirk Lapray"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(or51211_attach); +EXPORT_SYMBOL_GPL(or51211_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/rtl2830.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/rtl2830.c @@ -609,7 +609,7 @@ index, pid, onoff); /* skip invalid PIDs (0x2000) */ - if (pid > 0x1fff || index > 32) + if (pid > 0x1fff || index >= 32) return 0; if (onoff) --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/rtl2832.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/rtl2832.c @@ -640,7 +640,7 @@ struct i2c_client *client = dev->client; struct dtv_frontend_properties *c = &fe->dtv_property_cache; int ret; - u32 uninitialized_var(tmp); + u32 tmp; u8 u8tmp, buf[2]; u16 u16tmp; @@ -982,7 +982,7 @@ index, pid, onoff, dev->slave_ts); /* skip invalid PIDs (0x2000) */ - if (pid > 0x1fff || index > 32) + if (pid > 0x1fff || index >= 32) return 0; if (onoff) --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/s5h1409.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/s5h1409.c @@ -981,7 +981,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1409_attach); +EXPORT_SYMBOL_GPL(s5h1409_attach); static const struct dvb_frontend_ops s5h1409_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/s5h1411.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/s5h1411.c @@ -900,7 +900,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1411_attach); +EXPORT_SYMBOL_GPL(s5h1411_attach); static const struct dvb_frontend_ops s5h1411_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/s5h1420.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/s5h1420.c @@ -918,7 +918,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1420_attach); +EXPORT_SYMBOL_GPL(s5h1420_attach); static const struct dvb_frontend_ops s5h1420_ops = { .delsys = { SYS_DVBS }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/s5h1432.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/s5h1432.c @@ -355,7 +355,7 @@ return &state->frontend; } -EXPORT_SYMBOL(s5h1432_attach); +EXPORT_SYMBOL_GPL(s5h1432_attach); static const struct dvb_frontend_ops s5h1432_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/s921.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/s921.c @@ -495,7 +495,7 @@ return &state->frontend; } -EXPORT_SYMBOL(s921_attach); +EXPORT_SYMBOL_GPL(s921_attach); static const struct dvb_frontend_ops s921_ops = { .delsys = { SYS_ISDBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/si21xx.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/si21xx.c @@ -938,7 +938,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(si21xx_attach); +EXPORT_SYMBOL_GPL(si21xx_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/sp8870.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/sp8870.c @@ -281,7 +281,7 @@ // read status reg in order to clear pending irqs err = sp8870_readreg(state, 0x200); - if (err) + if (err < 0) return err; // system controller start --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/sp887x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/sp887x.c @@ -626,4 +626,4 @@ MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(sp887x_attach); +EXPORT_SYMBOL_GPL(sp887x_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stb0899_algo.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stb0899_algo.c @@ -269,7 +269,7 @@ short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; int index = 0; - u8 cfr[2]; + u8 cfr[2] = {0}; u8 reg; internal->status = NOCARRIER; --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stb0899_drv.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stb0899_drv.c @@ -1638,7 +1638,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stb0899_attach); +EXPORT_SYMBOL_GPL(stb0899_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); MODULE_AUTHOR("Manu Abraham"); MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stb6000.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stb6000.c @@ -232,7 +232,7 @@ return fe; } -EXPORT_SYMBOL(stb6000_attach); +EXPORT_SYMBOL_GPL(stb6000_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stb6100.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stb6100.c @@ -557,7 +557,7 @@ kfree(state); } -EXPORT_SYMBOL(stb6100_attach); +EXPORT_SYMBOL_GPL(stb6100_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); MODULE_AUTHOR("Manu Abraham"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv0288.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv0288.c @@ -440,9 +440,8 @@ struct stv0288_state *state = fe->demodulator_priv; struct dtv_frontend_properties *c = &fe->dtv_property_cache; - char tm; - unsigned char tda[3]; - u8 reg, time_out = 0; + u8 tda[3], reg, time_out = 0; + s8 tm; dprintk("%s : FE_SET_FRONTEND\n", __func__); @@ -591,7 +590,7 @@ return NULL; } -EXPORT_SYMBOL(stv0288_attach); +EXPORT_SYMBOL_GPL(stv0288_attach); module_param(debug_legacy_dish_switch, int, 0444); MODULE_PARM_DESC(debug_legacy_dish_switch, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv0297.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv0297.c @@ -710,4 +710,4 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(stv0297_attach); +EXPORT_SYMBOL_GPL(stv0297_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv0299.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv0299.c @@ -751,4 +751,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(stv0299_attach); +EXPORT_SYMBOL_GPL(stv0299_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv0367.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv0367.c @@ -118,50 +118,32 @@ } }; -static -int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len) +static noinline_for_stack +int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) { - u8 buf[MAX_XFER_SIZE]; + u8 buf[3] = { MSB(reg), LSB(reg), data }; struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, - .len = len + 2 + .len = 3, }; int ret; - if (2 + len > sizeof(buf)) { - printk(KERN_WARNING - "%s: i2c wr reg=%04x: len=%d is too big!\n", - KBUILD_MODNAME, reg, len); - return -EINVAL; - } - - - buf[0] = MSB(reg); - buf[1] = LSB(reg); - memcpy(buf + 2, data, len); - if (i2cdebug) printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__, - state->config->demod_address, reg, buf[2]); + state->config->demod_address, reg, data); ret = i2c_transfer(state->i2c, &msg, 1); if (ret != 1) printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n", - __func__, state->config->demod_address, reg, buf[2]); + __func__, state->config->demod_address, reg, data); return (ret != 1) ? -EREMOTEIO : 0; } -static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data) -{ - u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ - - return stv0367_writeregs(state, reg, &tmp, 1); -} - -static u8 stv0367_readreg(struct stv0367_state *state, u16 reg) +static noinline_for_stack +u8 stv0367_readreg(struct stv0367_state *state, u16 reg) { u8 b0[] = { 0, 0 }; u8 b1[] = { 0 }; @@ -1750,7 +1732,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367ter_attach); +EXPORT_SYMBOL_GPL(stv0367ter_attach); static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable) { @@ -2923,7 +2905,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367cab_attach); +EXPORT_SYMBOL_GPL(stv0367cab_attach); /* * Functions for operation on Digital Devices hardware @@ -3344,7 +3326,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367ddb_attach); +EXPORT_SYMBOL_GPL(stv0367ddb_attach); MODULE_PARM_DESC(debug, "Set debug"); MODULE_PARM_DESC(i2c_debug, "Set i2c debug"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv0900_core.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv0900_core.c @@ -1957,7 +1957,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0900_attach); +EXPORT_SYMBOL_GPL(stv0900_attach); MODULE_PARM_DESC(debug, "Set debug"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv090x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv090x.c @@ -5073,7 +5073,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv090x_attach); +EXPORT_SYMBOL_GPL(stv090x_attach); static const struct i2c_device_id stv090x_id_table[] = { {"stv090x", 0}, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv6110.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv6110.c @@ -427,7 +427,7 @@ return fe; } -EXPORT_SYMBOL(stv6110_attach); +EXPORT_SYMBOL_GPL(stv6110_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/stv6110x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/stv6110x.c @@ -469,7 +469,7 @@ dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n"); return stv6110x->devctl; } -EXPORT_SYMBOL(stv6110x_attach); +EXPORT_SYMBOL_GPL(stv6110x_attach); static const struct i2c_device_id stv6110x_id_table[] = { {"stv6110x", 0}, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda10021.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda10021.c @@ -513,4 +513,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10021_attach); +EXPORT_SYMBOL_GPL(tda10021_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda10023.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda10023.c @@ -594,4 +594,4 @@ MODULE_AUTHOR("Georg Acher, Hartmut Birr"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10023_attach); +EXPORT_SYMBOL_GPL(tda10023_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda10048.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda10048.c @@ -410,6 +410,7 @@ struct tda10048_config *config = &state->config; int i; u32 if_freq_khz; + u64 sample_freq; dprintk(1, "%s(bw = %d)\n", __func__, bw); @@ -451,9 +452,11 @@ dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor); /* Calculate the sample frequency */ - state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45); - state->sample_freq /= (state->pll_nfactor + 1); - state->sample_freq /= (state->pll_pfactor + 4); + sample_freq = state->xtal_hz; + sample_freq *= state->pll_mfactor + 45; + do_div(sample_freq, state->pll_nfactor + 1); + do_div(sample_freq, state->pll_pfactor + 4); + state->sample_freq = sample_freq; dprintk(1, "- sample_freq = %d\n", state->sample_freq); /* Update the I/F */ @@ -1138,7 +1141,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(tda10048_attach); +EXPORT_SYMBOL_GPL(tda10048_attach); static const struct dvb_frontend_ops tda10048_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda1004x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda1004x.c @@ -1378,5 +1378,5 @@ MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10045_attach); -EXPORT_SYMBOL(tda10046_attach); +EXPORT_SYMBOL_GPL(tda10045_attach); +EXPORT_SYMBOL_GPL(tda10046_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda10071.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda10071.c @@ -470,10 +470,11 @@ goto error; if (dev->delivery_system == SYS_DVBS) { - dev->dvbv3_ber = buf[0] << 24 | buf[1] << 16 | - buf[2] << 8 | buf[3] << 0; - dev->post_bit_error += buf[0] << 24 | buf[1] << 16 | - buf[2] << 8 | buf[3] << 0; + u32 bit_error = buf[0] << 24 | buf[1] << 16 | + buf[2] << 8 | buf[3] << 0; + + dev->dvbv3_ber = bit_error; + dev->post_bit_error += bit_error; c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; c->post_bit_error.stat[0].uvalue = dev->post_bit_error; dev->block_error += buf[4] << 8 | buf[5] << 0; --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda10086.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda10086.c @@ -764,4 +764,4 @@ MODULE_AUTHOR("Andrew de Quincey"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10086_attach); +EXPORT_SYMBOL_GPL(tda10086_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda18271c2dd.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda18271c2dd.c @@ -331,7 +331,7 @@ OscFreq = (u64) freq * (u64) Div; OscFreq *= (u64) 16384; - do_div(OscFreq, (u64)16000000); + do_div(OscFreq, 16000000); MainDiv = OscFreq; state->m_Regs[MPD] = PostDiv & 0x77; @@ -355,7 +355,7 @@ OscFreq = (u64)freq * (u64)Div; /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */ OscFreq *= (u64)16384; - do_div(OscFreq, (u64)16000000); + do_div(OscFreq, 16000000); CalDiv = OscFreq; state->m_Regs[CPD] = PostDiv; --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda665x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda665x.c @@ -227,7 +227,7 @@ return fe; } -EXPORT_SYMBOL(tda665x_attach); +EXPORT_SYMBOL_GPL(tda665x_attach); MODULE_DESCRIPTION("TDA665x driver"); MODULE_AUTHOR("Manu Abraham"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda8083.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda8083.c @@ -481,4 +481,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda8083_attach); +EXPORT_SYMBOL_GPL(tda8083_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda8261.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda8261.c @@ -188,7 +188,7 @@ return NULL; } -EXPORT_SYMBOL(tda8261_attach); +EXPORT_SYMBOL_GPL(tda8261_attach); MODULE_AUTHOR("Manu Abraham"); MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tda826x.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tda826x.c @@ -164,7 +164,7 @@ return fe; } -EXPORT_SYMBOL(tda826x_attach); +EXPORT_SYMBOL_GPL(tda826x_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ts2020.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ts2020.c @@ -525,7 +525,7 @@ return fe; } -EXPORT_SYMBOL(ts2020_attach); +EXPORT_SYMBOL_GPL(ts2020_attach); /* * We implement own regmap locking due to legacy DVB attach which uses frontend @@ -554,13 +554,19 @@ const struct i2c_device_id *id) { struct ts2020_config *pdata = client->dev.platform_data; - struct dvb_frontend *fe = pdata->fe; + struct dvb_frontend *fe; struct ts2020_priv *dev; int ret; u8 u8tmp; unsigned int utmp; char *chip_str; + if (!pdata) { + dev_err(&client->dev, "platform data is mandatory\n"); + return -EINVAL; + } + + fe = pdata->fe; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { ret = -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/tua6100.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/tua6100.c @@ -186,7 +186,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(tua6100_attach); +EXPORT_SYMBOL_GPL(tua6100_attach); MODULE_DESCRIPTION("DVB tua6100 driver"); MODULE_AUTHOR("Andrew de Quincey"); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ves1820.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ves1820.c @@ -434,4 +434,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ves1820_attach); +EXPORT_SYMBOL_GPL(ves1820_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/ves1x93.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/ves1x93.c @@ -540,4 +540,4 @@ MODULE_AUTHOR("Ralph Metzler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ves1x93_attach); +EXPORT_SYMBOL_GPL(ves1x93_attach); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/zl10036.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/zl10036.c @@ -496,7 +496,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(zl10036_attach); +EXPORT_SYMBOL_GPL(zl10036_attach); module_param_named(debug, zl10036_debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/zl10039.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/zl10039.c @@ -295,7 +295,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(zl10039_attach); +EXPORT_SYMBOL_GPL(zl10039_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); --- linux-oracle-5.4.0.orig/drivers/media/dvb-frontends/zl10353.c +++ linux-oracle-5.4.0/drivers/media/dvb-frontends/zl10353.c @@ -665,4 +665,4 @@ MODULE_AUTHOR("Chris Pascoe"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(zl10353_attach); +EXPORT_SYMBOL_GPL(zl10353_attach); --- linux-oracle-5.4.0.orig/drivers/media/firewire/firedtv-avc.c +++ linux-oracle-5.4.0/drivers/media/firewire/firedtv-avc.c @@ -1165,7 +1165,11 @@ read_pos += program_info_length; write_pos += program_info_length; } - while (read_pos < length) { + while (read_pos + 4 < length) { + if (write_pos + 4 >= sizeof(c->operand) - 4) { + ret = -EINVAL; + goto out; + } c->operand[write_pos++] = msg[read_pos++]; c->operand[write_pos++] = msg[read_pos++]; c->operand[write_pos++] = msg[read_pos++]; @@ -1177,13 +1181,17 @@ c->operand[write_pos++] = es_info_length >> 8; c->operand[write_pos++] = es_info_length & 0xff; if (es_info_length > 0) { + if (read_pos >= length) { + ret = -EINVAL; + goto out; + } pmt_cmd_id = msg[read_pos++]; if (pmt_cmd_id != 1 && pmt_cmd_id != 4) dev_err(fdtv->device, "invalid pmt_cmd_id %d at stream level\n", pmt_cmd_id); - if (es_info_length > sizeof(c->operand) - 4 - - write_pos) { + if (es_info_length > sizeof(c->operand) - 4 - write_pos || + es_info_length > length - read_pos) { ret = -EINVAL; goto out; } --- linux-oracle-5.4.0.orig/drivers/media/firewire/firedtv-ci.c +++ linux-oracle-5.4.0/drivers/media/firewire/firedtv-ci.c @@ -134,6 +134,8 @@ } else { data_length = msg->msg[3]; } + if (data_length > sizeof(msg->msg) - data_pos) + return -EINVAL; return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length); } --- linux-oracle-5.4.0.orig/drivers/media/firewire/firedtv-fw.c +++ linux-oracle-5.4.0/drivers/media/firewire/firedtv-fw.c @@ -272,6 +272,10 @@ name_len = fw_csr_string(unit->directory, CSR_MODEL, name, sizeof(name)); + if (name_len < 0) { + err = name_len; + goto fail_free; + } for (i = ARRAY_SIZE(model_names); --i; ) if (strlen(model_names[i]) <= name_len && strncmp(name, model_names[i], name_len) == 0) --- linux-oracle-5.4.0.orig/drivers/media/i2c/Kconfig +++ linux-oracle-5.4.0/drivers/media/i2c/Kconfig @@ -1113,6 +1113,7 @@ config SDR_MAX2175 tristate "Maxim 2175 RF to Bits tuner" depends on VIDEO_V4L2 && MEDIA_SDR_SUPPORT && I2C + select REGMAP_I2C help Support for Maxim 2175 tuner. It is an advanced analog/digital radio receiver with RF-to-Bits front-end designed for SDR solutions. --- linux-oracle-5.4.0.orig/drivers/media/i2c/Makefile +++ linux-oracle-5.4.0/drivers/media/i2c/Makefile @@ -35,7 +35,6 @@ obj-$(CONFIG_VIDEO_ADV7604) += adv7604.o obj-$(CONFIG_VIDEO_ADV7842) += adv7842.o obj-$(CONFIG_VIDEO_AD9389B) += ad9389b.o -obj-$(CONFIG_VIDEO_ADV7511) += adv7511-v4l2.o obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o obj-$(CONFIG_VIDEO_VS6624) += vs6624.o obj-$(CONFIG_VIDEO_BT819) += bt819.o --- linux-oracle-5.4.0.orig/drivers/media/i2c/ad5820.c +++ linux-oracle-5.4.0/drivers/media/i2c/ad5820.c @@ -309,22 +309,23 @@ v4l2_i2c_subdev_init(&coil->subdev, client, &ad5820_ops); coil->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; coil->subdev.internal_ops = &ad5820_internal_ops; + coil->subdev.entity.function = MEDIA_ENT_F_LENS; strscpy(coil->subdev.name, "ad5820 focus", sizeof(coil->subdev.name)); ret = media_entity_pads_init(&coil->subdev.entity, 0, NULL); if (ret < 0) - goto cleanup2; + goto clean_mutex; ret = v4l2_async_register_subdev(&coil->subdev); if (ret < 0) - goto cleanup; + goto clean_entity; return ret; -cleanup2: - mutex_destroy(&coil->power_lock); -cleanup: +clean_entity: media_entity_cleanup(&coil->subdev.entity); +clean_mutex: + mutex_destroy(&coil->power_lock); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/adv748x/adv748x.h +++ linux-oracle-5.4.0/drivers/media/i2c/adv748x/adv748x.h @@ -394,10 +394,10 @@ #define io_read(s, r) adv748x_read(s, ADV748X_PAGE_IO, r) #define io_write(s, r, v) adv748x_write(s, ADV748X_PAGE_IO, r, v) -#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~m) | v) +#define io_clrset(s, r, m, v) io_write(s, r, (io_read(s, r) & ~(m)) | (v)) #define hdmi_read(s, r) adv748x_read(s, ADV748X_PAGE_HDMI, r) -#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, r+1)) & m) +#define hdmi_read16(s, r, m) (((hdmi_read(s, r) << 8) | hdmi_read(s, (r)+1)) & (m)) #define hdmi_write(s, r, v) adv748x_write(s, ADV748X_PAGE_HDMI, r, v) #define repeater_read(s, r) adv748x_read(s, ADV748X_PAGE_REPEATER, r) @@ -405,11 +405,11 @@ #define sdp_read(s, r) adv748x_read(s, ADV748X_PAGE_SDP, r) #define sdp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_SDP, r, v) -#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~m) | v) +#define sdp_clrset(s, r, m, v) sdp_write(s, r, (sdp_read(s, r) & ~(m)) | (v)) #define cp_read(s, r) adv748x_read(s, ADV748X_PAGE_CP, r) #define cp_write(s, r, v) adv748x_write(s, ADV748X_PAGE_CP, r, v) -#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~m) | v) +#define cp_clrset(s, r, m, v) cp_write(s, r, (cp_read(s, r) & ~(m)) | (v)) #define tx_read(t, r) adv748x_read(t->state, t->page, r) #define tx_write(t, r, v) adv748x_write(t->state, t->page, r, v) --- linux-oracle-5.4.0.orig/drivers/media/i2c/adv7511-v4l2.c +++ linux-oracle-5.4.0/drivers/media/i2c/adv7511-v4l2.c @@ -555,7 +555,7 @@ buffer[3] = 0; buffer[3] = hdmi_infoframe_checksum(buffer, len + 4); - if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) { + if (hdmi_infoframe_unpack(&frame, buffer, len + 4) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } @@ -1964,7 +1964,7 @@ adv7511_set_isr(sd, false); adv7511_init_setup(sd); - cancel_delayed_work(&state->edid_handler); + cancel_delayed_work_sync(&state->edid_handler); i2c_unregister_device(state->i2c_edid); i2c_unregister_device(state->i2c_cec); i2c_unregister_device(state->i2c_pktmem); --- linux-oracle-5.4.0.orig/drivers/media/i2c/adv7604.c +++ linux-oracle-5.4.0/drivers/media/i2c/adv7604.c @@ -2444,7 +2444,7 @@ buffer[i + 3] = infoframe_read(sd, adv76xx_cri[index].payload_addr + i); - if (hdmi_infoframe_unpack(frame, buffer, sizeof(buffer)) < 0) { + if (hdmi_infoframe_unpack(frame, buffer, len + 3) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, adv76xx_cri[index].desc); return -ENOENT; @@ -2477,10 +2477,10 @@ const struct adv76xx_chip_info *info = state->info; struct v4l2_dv_timings timings; struct stdi_readback stdi; - u8 reg_io_0x02 = io_read(sd, 0x02); + int ret; + u8 reg_io_0x02; u8 edid_enabled; u8 cable_det; - static const char * const csc_coeff_sel_rb[16] = { "bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB", "reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709", @@ -2579,13 +2579,21 @@ v4l2_info(sd, "-----Color space-----\n"); v4l2_info(sd, "RGB quantization range ctrl: %s\n", rgb_quantization_range_txt[state->rgb_quantization_range]); - v4l2_info(sd, "Input color space: %s\n", - input_color_space_txt[reg_io_0x02 >> 4]); - v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", - (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", - (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? - "(16-235)" : "(0-255)", - (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); + + ret = io_read(sd, 0x02); + if (ret < 0) { + v4l2_info(sd, "Can't read Input/Output color space\n"); + } else { + reg_io_0x02 = ret; + + v4l2_info(sd, "Input color space: %s\n", + input_color_space_txt[reg_io_0x02 >> 4]); + v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n", + (reg_io_0x02 & 0x02) ? "RGB" : "YCbCr", + (((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ? + "(16-235)" : "(0-255)", + (reg_io_0x02 & 0x08) ? "enabled" : "disabled"); + } v4l2_info(sd, "Color space conversion: %s\n", csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]); @@ -3606,7 +3614,7 @@ io_write(sd, 0x6e, 0); io_write(sd, 0x73, 0); - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv76xx_unregister_clients(to_state(sd)); --- linux-oracle-5.4.0.orig/drivers/media/i2c/adv7842.c +++ linux-oracle-5.4.0/drivers/media/i2c/adv7842.c @@ -2574,7 +2574,7 @@ for (i = 0; i < len; i++) buffer[i + 3] = infoframe_read(sd, cri->payload_addr + i); - if (hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)) < 0) { + if (hdmi_infoframe_unpack(&frame, buffer, len + 3) < 0) { v4l2_err(sd, "%s: unpack of %s infoframe failed\n", __func__, cri->desc); return; } @@ -3586,7 +3586,7 @@ struct adv7842_state *state = to_state(sd); adv7842_irq_enable(sd, false); - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); v4l2_device_unregister_subdev(sd); media_entity_cleanup(&sd->entity); adv7842_unregister_clients(sd); --- linux-oracle-5.4.0.orig/drivers/media/i2c/et8ek8/et8ek8_driver.c +++ linux-oracle-5.4.0/drivers/media/i2c/et8ek8/et8ek8_driver.c @@ -1460,7 +1460,7 @@ return ret; } -static int __exit et8ek8_remove(struct i2c_client *client) +static int et8ek8_remove(struct i2c_client *client) { struct v4l2_subdev *subdev = i2c_get_clientdata(client); struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev); @@ -1504,7 +1504,7 @@ .of_match_table = et8ek8_of_table, }, .probe_new = et8ek8_probe, - .remove = __exit_p(et8ek8_remove), + .remove = et8ek8_remove, .id_table = et8ek8_id_table, }; --- linux-oracle-5.4.0.orig/drivers/media/i2c/imx214.c +++ linux-oracle-5.4.0/drivers/media/i2c/imx214.c @@ -785,7 +785,7 @@ if (ret < 0) goto err_rpm_put; } else { - ret = imx214_start_streaming(imx214); + ret = imx214_stop_streaming(imx214); if (ret < 0) goto err_rpm_put; pm_runtime_put(imx214->dev); --- linux-oracle-5.4.0.orig/drivers/media/i2c/imx258.c +++ linux-oracle-5.4.0/drivers/media/i2c/imx258.c @@ -22,7 +22,7 @@ #define IMX258_CHIP_ID 0x0258 /* V_TIMING internal */ -#define IMX258_VTS_30FPS 0x0c98 +#define IMX258_VTS_30FPS 0x0c50 #define IMX258_VTS_30FPS_2K 0x0638 #define IMX258_VTS_30FPS_VGA 0x034c #define IMX258_VTS_MAX 0xffff @@ -46,7 +46,7 @@ /* Analog gain control */ #define IMX258_REG_ANALOG_GAIN 0x0204 #define IMX258_ANA_GAIN_MIN 0 -#define IMX258_ANA_GAIN_MAX 0x1fff +#define IMX258_ANA_GAIN_MAX 480 #define IMX258_ANA_GAIN_STEP 1 #define IMX258_ANA_GAIN_DEFAULT 0x0 --- linux-oracle-5.4.0.orig/drivers/media/i2c/imx274.c +++ linux-oracle-5.4.0/drivers/media/i2c/imx274.c @@ -1235,6 +1235,8 @@ ret = imx274_set_frame_interval(imx274, fi->interval); if (!ret) { + fi->interval = imx274->frame_interval; + /* * exposure time range is decided by frame interval * need to update it after frame interval changes @@ -1730,9 +1732,9 @@ __func__, frame_interval.numerator, frame_interval.denominator); - if (frame_interval.numerator == 0) { - err = -EINVAL; - goto fail; + if (frame_interval.numerator == 0 || frame_interval.denominator == 0) { + frame_interval.denominator = IMX274_DEF_FRAME_RATE; + frame_interval.numerator = 1; } req_frame_rate = (u32)(frame_interval.denominator --- linux-oracle-5.4.0.orig/drivers/media/i2c/ir-kbd-i2c.c +++ linux-oracle-5.4.0/drivers/media/i2c/ir-kbd-i2c.c @@ -678,8 +678,8 @@ goto out_unlock; } - i = i2c_master_recv(ir->tx_c, buf, 1); - if (i != 1) { + ret = i2c_master_recv(ir->tx_c, buf, 1); + if (ret != 1) { dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret); ret = -EIO; goto out_unlock; @@ -791,6 +791,7 @@ rc_proto = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_RC6_6A_32; ir_codes = RC_MAP_HAUPPAUGE; + ir->polling_interval = 125; probe_tx = true; break; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/m5mols/m5mols_core.c +++ linux-oracle-5.4.0/drivers/media/i2c/m5mols/m5mols_core.c @@ -488,7 +488,7 @@ do { if (code == m5mols_default_ffmt[type].code) return type; - } while (type++ != SIZE_DEFAULT_FFMT); + } while (++type != SIZE_DEFAULT_FFMT); return 0; } @@ -764,7 +764,8 @@ ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies); if (ret) { - info->set_power(&client->dev, 0); + if (info->set_power) + info->set_power(&client->dev, 0); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/max2175.c +++ linux-oracle-5.4.0/drivers/media/i2c/max2175.c @@ -503,7 +503,7 @@ } } -static bool max2175_set_csm_mode(struct max2175 *ctx, +static int max2175_set_csm_mode(struct max2175 *ctx, enum max2175_csm_mode new_mode) { int ret = max2175_poll_csm_ready(ctx); --- linux-oracle-5.4.0.orig/drivers/media/i2c/mt9p031.c +++ linux-oracle-5.4.0/drivers/media/i2c/mt9p031.c @@ -78,7 +78,9 @@ #define MT9P031_PIXEL_CLOCK_INVERT (1 << 15) #define MT9P031_PIXEL_CLOCK_SHIFT(n) ((n) << 8) #define MT9P031_PIXEL_CLOCK_DIVIDE(n) ((n) << 0) -#define MT9P031_FRAME_RESTART 0x0b +#define MT9P031_RESTART 0x0b +#define MT9P031_FRAME_PAUSE_RESTART (1 << 1) +#define MT9P031_FRAME_RESTART (1 << 0) #define MT9P031_SHUTTER_DELAY 0x0c #define MT9P031_RST 0x0d #define MT9P031_RST_ENABLE 1 @@ -445,9 +447,23 @@ static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable) { struct mt9p031 *mt9p031 = to_mt9p031(subdev); + struct i2c_client *client = v4l2_get_subdevdata(subdev); + int val; int ret; if (!enable) { + /* enable pause restart */ + val = MT9P031_FRAME_PAUSE_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + + /* enable restart + keep pause restart set */ + val |= MT9P031_FRAME_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + /* Stop sensor readout */ ret = mt9p031_set_output_control(mt9p031, MT9P031_OUTPUT_CONTROL_CEN, 0); @@ -467,6 +483,16 @@ if (ret < 0) return ret; + /* + * - clear pause restart + * - don't clear restart as clearing restart manually can cause + * undefined behavior + */ + val = MT9P031_FRAME_RESTART; + ret = mt9p031_write(client, MT9P031_RESTART, val); + if (ret < 0) + return ret; + return mt9p031_pll_enable(mt9p031); } --- linux-oracle-5.4.0.orig/drivers/media/i2c/mt9v032.c +++ linux-oracle-5.4.0/drivers/media/i2c/mt9v032.c @@ -428,10 +428,12 @@ struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { + struct mt9v032 *mt9v032 = to_mt9v032(subdev); + if (code->index > 0) return -EINVAL; - code->code = MEDIA_BUS_FMT_SGRBG10_1X10; + code->code = mt9v032->format.code; return 0; } @@ -439,7 +441,11 @@ struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { - if (fse->index >= 3 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) + struct mt9v032 *mt9v032 = to_mt9v032(subdev); + + if (fse->index >= 3) + return -EINVAL; + if (mt9v032->format.code != fse->code) return -EINVAL; fse->min_width = MT9V032_WINDOW_WIDTH_DEF / (1 << fse->index); --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov2659.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov2659.c @@ -419,10 +419,14 @@ { REG_TIMING_YINC, 0x11 }, { REG_TIMING_VERT_FORMAT, 0x80 }, { REG_TIMING_HORIZ_FORMAT, 0x00 }, + { 0x370a, 0x12 }, { 0x3a03, 0xe8 }, { 0x3a09, 0x6f }, { 0x3a0b, 0x5d }, { 0x3a15, 0x9a }, + { REG_VFIFO_READ_START_H, 0x00 }, + { REG_VFIFO_READ_START_L, 0x80 }, + { REG_ISP_CTRL02, 0x00 }, { REG_NULL, 0x00 }, }; @@ -1201,11 +1205,15 @@ goto unlock; } - ov2659_set_pixel_clock(ov2659); - ov2659_set_frame_size(ov2659); - ov2659_set_format(ov2659); - ov2659_set_streaming(ov2659, 1); - ov2659->streaming = on; + ret = ov2659_set_pixel_clock(ov2659); + if (!ret) + ret = ov2659_set_frame_size(ov2659); + if (!ret) + ret = ov2659_set_format(ov2659); + if (!ret) { + ov2659_set_streaming(ov2659, 1); + ov2659->streaming = on; + } unlock: mutex_unlock(&ov2659->lock); --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov2680.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov2680.c @@ -85,15 +85,8 @@ struct ov2680_ctrls { struct v4l2_ctrl_handler handler; - struct { - struct v4l2_ctrl *auto_exp; - struct v4l2_ctrl *exposure; - }; - struct { - struct v4l2_ctrl *auto_gain; - struct v4l2_ctrl *gain; - }; - + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; struct v4l2_ctrl *hflip; struct v4l2_ctrl *vflip; struct v4l2_ctrl *test_pattern; @@ -143,6 +136,7 @@ {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, + {0x3503, 0x03}, }; static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { @@ -321,70 +315,49 @@ usleep_range(5000, 10000); } -static int ov2680_bayer_order(struct ov2680_dev *sensor) +static void ov2680_set_bayer_order(struct ov2680_dev *sensor) { - u32 format1; - u32 format2; - u32 hv_flip; - int ret; - - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1); - if (ret < 0) - return ret; + int hv_flip = 0; - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2); - if (ret < 0) - return ret; + if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) + hv_flip += 1; - hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2)); + if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) + hv_flip += 2; sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; - - return 0; } -static int ov2680_vflip_enable(struct ov2680_dev *sensor) +static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2)); - if (ret < 0) - return ret; + if (sensor->is_streaming) + return -EBUSY; - return ov2680_bayer_order(sensor); -} - -static int ov2680_vflip_disable(struct ov2680_dev *sensor) -{ - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0)); + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor); + return 0; } -static int ov2680_hflip_enable(struct ov2680_dev *sensor) +static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2)); - if (ret < 0) - return ret; + if (sensor->is_streaming) + return -EBUSY; - return ov2680_bayer_order(sensor); -} - -static int ov2680_hflip_disable(struct ov2680_dev *sensor) -{ - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0)); + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor); + return 0; } static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) @@ -405,69 +378,15 @@ return 0; } -static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain) +static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 gain; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), - auto_gain ? 0 : BIT(1)); - if (ret < 0) - return ret; - - if (auto_gain || !ctrls->gain->is_new) - return 0; - - gain = ctrls->gain->val; - - ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); - - return 0; + return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); } -static int ov2680_gain_get(struct ov2680_dev *sensor) +static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) { - u32 gain; - int ret; - - ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain); - if (ret) - return ret; - - return gain; -} - -static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp) -{ - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 exp; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0), - auto_exp ? 0 : BIT(0)); - if (ret < 0) - return ret; - - if (auto_exp || !ctrls->exposure->is_new) - return 0; - - exp = (u32)ctrls->exposure->val; - exp <<= 4; - - return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp); -} - -static int ov2680_exposure_get(struct ov2680_dev *sensor) -{ - int ret; - u32 exp; - - ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp); - if (ret) - return ret; - - return exp >> 4; + return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, + exp << 4); } static int ov2680_stream_enable(struct ov2680_dev *sensor) @@ -482,33 +401,17 @@ static int ov2680_mode_set(struct ov2680_dev *sensor) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; int ret; - ret = ov2680_gain_set(sensor, false); - if (ret < 0) - return ret; - - ret = ov2680_exposure_set(sensor, false); + ret = ov2680_load_regs(sensor, sensor->current_mode); if (ret < 0) return ret; - ret = ov2680_load_regs(sensor, sensor->current_mode); + /* Restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); if (ret < 0) return ret; - if (ctrls->auto_gain->val) { - ret = ov2680_gain_set(sensor, true); - if (ret < 0) - return ret; - } - - if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) { - ret = ov2680_exposure_set(sensor, true); - if (ret < 0) - return ret; - } - sensor->mode_pending_changes = false; return 0; @@ -556,7 +459,7 @@ ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); if (ret != 0) { dev_err(dev, "sensor soft reset failed\n"); - return ret; + goto err_disable_regulators; } usleep_range(1000, 2000); } else { @@ -566,7 +469,7 @@ ret = clk_prepare_enable(sensor->xvclk); if (ret < 0) - return ret; + goto err_disable_regulators; sensor->is_enabled = true; @@ -576,6 +479,10 @@ ov2680_stream_disable(sensor); return 0; + +err_disable_regulators: + regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); + return ret; } static int ov2680_s_power(struct v4l2_subdev *sd, int on) @@ -590,15 +497,10 @@ else ret = ov2680_power_off(sensor); - mutex_unlock(&sensor->lock); - - if (on && ret == 0) { - ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret < 0) - return ret; - + if (on && ret == 0) ret = ov2680_mode_restore(sensor); - } + + mutex_unlock(&sensor->lock); return ret; } @@ -793,66 +695,23 @@ return 0; } -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); - struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; - int val; - - if (!sensor->is_enabled) - return 0; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - val = ov2680_gain_get(sensor); - if (val < 0) - return val; - ctrls->gain->val = val; - break; - case V4L2_CID_EXPOSURE: - val = ov2680_exposure_get(sensor); - if (val < 0) - return val; - ctrls->exposure->val = val; - break; - } - - return 0; -} - static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; if (!sensor->is_enabled) return 0; switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - return ov2680_gain_set(sensor, !!ctrl->val); case V4L2_CID_GAIN: - return ov2680_gain_set(sensor, !!ctrls->auto_gain->val); - case V4L2_CID_EXPOSURE_AUTO: - return ov2680_exposure_set(sensor, !!ctrl->val); + return ov2680_gain_set(sensor, ctrl->val); case V4L2_CID_EXPOSURE: - return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val); + return ov2680_exposure_set(sensor, ctrl->val); case V4L2_CID_VFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_vflip_enable(sensor); - else - return ov2680_vflip_disable(sensor); + return ov2680_set_vflip(sensor, ctrl->val); case V4L2_CID_HFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_hflip_enable(sensor); - else - return ov2680_hflip_disable(sensor); + return ov2680_set_hflip(sensor, ctrl->val); case V4L2_CID_TEST_PATTERN: return ov2680_test_pattern_set(sensor, ctrl->val); default: @@ -863,7 +722,6 @@ } static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { - .g_volatile_ctrl = ov2680_g_volatile_ctrl, .s_ctrl = ov2680_s_ctrl, }; @@ -935,7 +793,7 @@ if (ret < 0) return ret; - v4l2_ctrl_handler_init(hdl, 7); + v4l2_ctrl_handler_init(hdl, 5); hdl->lock = &sensor->lock; @@ -947,16 +805,9 @@ ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, test_pattern_menu); - ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, - V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, - V4L2_EXPOSURE_AUTO); - ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, 32767, 1, 0); - ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, - 0, 1, 1, 1); ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); if (hdl->error) { @@ -964,11 +815,8 @@ goto cleanup_entity; } - ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; - ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; - - v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); - v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); + ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; sensor->sd.ctrl_handler = hdl; --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov5640.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov5640.c @@ -34,6 +34,8 @@ #define OV5640_REG_SYS_RESET02 0x3002 #define OV5640_REG_SYS_CLOCK_ENABLE02 0x3006 #define OV5640_REG_SYS_CTRL0 0x3008 +#define OV5640_REG_SYS_CTRL0_SW_PWDN 0x42 +#define OV5640_REG_SYS_CTRL0_SW_PWUP 0x02 #define OV5640_REG_CHIP_ID 0x300a #define OV5640_REG_IO_MIPI_CTRL00 0x300e #define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017 @@ -272,8 +274,7 @@ /* YUV422 UYVY VGA@30fps */ static const struct reg_value ov5640_init_setting_30fps_VGA[] = { {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, - {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, - {0x3630, 0x36, 0, 0}, + {0x3103, 0x03, 0, 0}, {0x3630, 0x36, 0, 0}, {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0}, {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0}, {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0}, @@ -740,7 +741,7 @@ * +->| PLL Root Div | - reg 0x3037, bit 4 * +-+------------+ * | +---------+ - * +->| Bit Div | - reg 0x3035, bits 0-3 + * +->| Bit Div | - reg 0x3034, bits 0-3 * +-+-------+ * | +-------------+ * +->| SCLK Div | - reg 0x3108, bits 0-1 @@ -874,7 +875,7 @@ * We have reached the maximum allowed PLL1 output, * increase sysdiv. */ - if (!rate) + if (!_rate) break; /* @@ -1109,6 +1110,12 @@ val = regs->val; mask = regs->mask; + /* remain in power down mode for DVP */ + if (regs->reg_addr == OV5640_REG_SYS_CTRL0 && + val == OV5640_REG_SYS_CTRL0_SW_PWUP && + sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) + continue; + if (mask) ret = ov5640_mod_reg(sensor, reg_addr, mask, val); else @@ -1199,96 +1206,9 @@ static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on) { - int ret; - unsigned int flags = sensor->ep.bus.parallel.flags; - u8 pclk_pol = 0; - u8 hsync_pol = 0; - u8 vsync_pol = 0; - - /* - * Note about parallel port configuration. - * - * When configured in parallel mode, the OV5640 will - * output 10 bits data on DVP data lines [9:0]. - * If only 8 bits data are wanted, the 8 bits data lines - * of the camera interface must be physically connected - * on the DVP data lines [9:2]. - * - * Control lines polarity can be configured through - * devicetree endpoint control lines properties. - * If no endpoint control lines properties are set, - * polarity will be as below: - * - VSYNC: active high - * - HREF: active low - * - PCLK: active low - */ - - if (on) { - /* - * configure parallel port control lines polarity - * - * POLARITY CTRL0 - * - [5]: PCLK polarity (0: active low, 1: active high) - * - [1]: HREF polarity (0: active low, 1: active high) - * - [0]: VSYNC polarity (mismatch here between - * datasheet and hardware, 0 is active high - * and 1 is active low...) - */ - if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) - pclk_pol = 1; - if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) - hsync_pol = 1; - if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) - vsync_pol = 1; - - ret = ov5640_write_reg(sensor, - OV5640_REG_POLARITY_CTRL00, - (pclk_pol << 5) | - (hsync_pol << 1) | - vsync_pol); - - if (ret) - return ret; - } - - /* - * powerdown MIPI TX/RX PHY & disable MIPI - * - * MIPI CONTROL 00 - * 4: PWDN PHY TX - * 3: PWDN PHY RX - * 2: MIPI enable - */ - ret = ov5640_write_reg(sensor, - OV5640_REG_IO_MIPI_CTRL00, on ? 0x18 : 0); - if (ret) - return ret; - - /* - * enable VSYNC/HREF/PCLK DVP control lines - * & D[9:6] DVP data lines - * - * PAD OUTPUT ENABLE 01 - * - 6: VSYNC output enable - * - 5: HREF output enable - * - 4: PCLK output enable - * - [3:0]: D[9:6] output enable - */ - ret = ov5640_write_reg(sensor, - OV5640_REG_PAD_OUTPUT_ENABLE01, - on ? 0x7f : 0); - if (ret) - return ret; - - /* - * enable D[5:0] DVP data lines - * - * PAD OUTPUT ENABLE 02 - * - [7:2]: D[5:0] output enable - */ - return ov5640_write_reg(sensor, - OV5640_REG_PAD_OUTPUT_ENABLE02, - on ? 0xfc : 0); + return ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, on ? + OV5640_REG_SYS_CTRL0_SW_PWUP : + OV5640_REG_SYS_CTRL0_SW_PWDN); } static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on) @@ -1448,6 +1368,7 @@ light_freq = 50; } else { /* 60Hz */ + light_freq = 60; } } @@ -1611,6 +1532,11 @@ !(mode->hact == 640 && mode->vact == 480)) return NULL; + /* 2592x1944 only works at 15fps max */ + if ((mode->hact == 2592 && mode->vact == 1944) && + fr > OV5640_15_FPS) + return NULL; + return mode; } @@ -1982,6 +1908,153 @@ clk_disable_unprepare(sensor->xclk); } +static int ov5640_set_power_mipi(struct ov5640_dev *sensor, bool on) +{ + int ret; + + if (!on) { + /* Reset MIPI bus settings to their default values. */ + ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58); + ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x04); + ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x00); + return 0; + } + + /* + * Power up MIPI HS Tx and LS Rx; 2 data lanes mode + * + * 0x300e = 0x40 + * [7:5] = 010 : 2 data lanes mode (see FIXME note in + * "ov5640_set_stream_mipi()") + * [4] = 0 : Power up MIPI HS Tx + * [3] = 0 : Power up MIPI LS Rx + * [2] = 1 : MIPI interface enabled + */ + ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x44); + if (ret) + return ret; + + /* + * Gate clock and set LP11 in 'no packets mode' (idle) + * + * 0x4800 = 0x24 + * [5] = 1 : Gate clock when 'no packets' + * [2] = 1 : MIPI bus in LP11 when 'no packets' + */ + ret = ov5640_write_reg(sensor, OV5640_REG_MIPI_CTRL00, 0x24); + if (ret) + return ret; + + /* + * Set data lanes and clock in LP11 when 'sleeping' + * + * 0x3019 = 0x70 + * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping' + * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping' + * [4] = 1 : MIPI clock lane in LP11 when 'sleeping' + */ + ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT00, 0x70); + if (ret) + return ret; + + /* Give lanes some time to coax into LP11 state. */ + usleep_range(500, 1000); + + return 0; +} + +static int ov5640_set_power_dvp(struct ov5640_dev *sensor, bool on) +{ + unsigned int flags = sensor->ep.bus.parallel.flags; + u8 pclk_pol = 0; + u8 hsync_pol = 0; + u8 vsync_pol = 0; + int ret; + + if (!on) { + /* Reset settings to their default values. */ + ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x58); + ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, 0x20); + ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x00); + ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0x00); + return 0; + } + + /* + * Note about parallel port configuration. + * + * When configured in parallel mode, the OV5640 will + * output 10 bits data on DVP data lines [9:0]. + * If only 8 bits data are wanted, the 8 bits data lines + * of the camera interface must be physically connected + * on the DVP data lines [9:2]. + * + * Control lines polarity can be configured through + * devicetree endpoint control lines properties. + * If no endpoint control lines properties are set, + * polarity will be as below: + * - VSYNC: active high + * - HREF: active low + * - PCLK: active low + */ + /* + * configure parallel port control lines polarity + * + * POLARITY CTRL0 + * - [5]: PCLK polarity (0: active low, 1: active high) + * - [1]: HREF polarity (0: active low, 1: active high) + * - [0]: VSYNC polarity (mismatch here between + * datasheet and hardware, 0 is active high + * and 1 is active low...) + */ + if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING) + pclk_pol = 1; + if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) + hsync_pol = 1; + if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) + vsync_pol = 1; + + ret = ov5640_write_reg(sensor, OV5640_REG_POLARITY_CTRL00, + (pclk_pol << 5) | (hsync_pol << 1) | vsync_pol); + + if (ret) + return ret; + + /* + * powerdown MIPI TX/RX PHY & disable MIPI + * + * MIPI CONTROL 00 + * 4: PWDN PHY TX + * 3: PWDN PHY RX + * 2: MIPI enable + */ + ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x18); + if (ret) + return ret; + + /* + * enable VSYNC/HREF/PCLK DVP control lines + * & D[9:6] DVP data lines + * + * PAD OUTPUT ENABLE 01 + * - 6: VSYNC output enable + * - 5: HREF output enable + * - 4: PCLK output enable + * - [3:0]: D[9:6] output enable + */ + ret = ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE01, 0x7f); + if (ret) + return ret; + + /* + * enable D[5:0] DVP data lines + * + * PAD OUTPUT ENABLE 02 + * - [7:2]: D[5:0] output enable + */ + return ov5640_write_reg(sensor, OV5640_REG_PAD_OUTPUT_ENABLE02, 0xfc); +} + static int ov5640_set_power(struct ov5640_dev *sensor, bool on) { int ret = 0; @@ -1994,67 +2067,17 @@ ret = ov5640_restore_mode(sensor); if (ret) goto power_off; + } - /* We're done here for DVP bus, while CSI-2 needs setup. */ - if (sensor->ep.bus_type != V4L2_MBUS_CSI2_DPHY) - return 0; - - /* - * Power up MIPI HS Tx and LS Rx; 2 data lanes mode - * - * 0x300e = 0x40 - * [7:5] = 010 : 2 data lanes mode (see FIXME note in - * "ov5640_set_stream_mipi()") - * [4] = 0 : Power up MIPI HS Tx - * [3] = 0 : Power up MIPI LS Rx - * [2] = 0 : MIPI interface disabled - */ - ret = ov5640_write_reg(sensor, - OV5640_REG_IO_MIPI_CTRL00, 0x40); - if (ret) - goto power_off; - - /* - * Gate clock and set LP11 in 'no packets mode' (idle) - * - * 0x4800 = 0x24 - * [5] = 1 : Gate clock when 'no packets' - * [2] = 1 : MIPI bus in LP11 when 'no packets' - */ - ret = ov5640_write_reg(sensor, - OV5640_REG_MIPI_CTRL00, 0x24); - if (ret) - goto power_off; - - /* - * Set data lanes and clock in LP11 when 'sleeping' - * - * 0x3019 = 0x70 - * [6] = 1 : MIPI data lane 2 in LP11 when 'sleeping' - * [5] = 1 : MIPI data lane 1 in LP11 when 'sleeping' - * [4] = 1 : MIPI clock lane in LP11 when 'sleeping' - */ - ret = ov5640_write_reg(sensor, - OV5640_REG_PAD_OUTPUT00, 0x70); - if (ret) - goto power_off; - - /* Give lanes some time to coax into LP11 state. */ - usleep_range(500, 1000); - - } else { - if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) { - /* Reset MIPI bus settings to their default values. */ - ov5640_write_reg(sensor, - OV5640_REG_IO_MIPI_CTRL00, 0x58); - ov5640_write_reg(sensor, - OV5640_REG_MIPI_CTRL00, 0x04); - ov5640_write_reg(sensor, - OV5640_REG_PAD_OUTPUT00, 0x00); - } + if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY) + ret = ov5640_set_power_mipi(sensor, on); + else + ret = ov5640_set_power_dvp(sensor, on); + if (ret) + goto power_off; + if (!on) ov5640_set_power_off(sensor); - } return 0; @@ -2675,7 +2698,7 @@ /* Auto/manual gain */ ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); - ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, + ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_ANALOGUE_GAIN, 0, 1023, 1, 0); ctrls->saturation = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, @@ -3063,8 +3086,8 @@ free_ctrls: v4l2_ctrl_handler_free(&sensor->ctrls.handler); entity_cleanup: - mutex_destroy(&sensor->lock); media_entity_cleanup(&sensor->sd.entity); + mutex_destroy(&sensor->lock); return ret; } @@ -3074,9 +3097,9 @@ struct ov5640_dev *sensor = to_ov5640_dev(sd); v4l2_async_unregister_subdev(&sensor->sd); - mutex_destroy(&sensor->lock); media_entity_cleanup(&sensor->sd.entity); v4l2_ctrl_handler_free(&sensor->ctrls.handler); + mutex_destroy(&sensor->lock); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov5670.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov5670.c @@ -2081,7 +2081,8 @@ /* By default, V4L2_CID_PIXEL_RATE is read only */ ov5670->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov5670_ctrl_ops, - V4L2_CID_PIXEL_RATE, 0, + V4L2_CID_PIXEL_RATE, + link_freq_configs[0].pixel_rate, link_freq_configs[0].pixel_rate, 1, link_freq_configs[0].pixel_rate); --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov5675.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov5675.c @@ -722,8 +722,10 @@ V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov5675_test_pattern_menu) - 1, 0, 0, ov5675_test_pattern_menu); - if (ctrl_hdlr->error) + if (ctrl_hdlr->error) { + v4l2_ctrl_handler_free(ctrl_hdlr); return ctrl_hdlr->error; + } ov5675->sd.ctrl_handler = ctrl_hdlr; --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov5695.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov5695.c @@ -971,16 +971,9 @@ return ret; } -/* Calculate the delay in us by clock rate and clock cycles */ -static inline u32 ov5695_cal_delay(u32 cycles) -{ - return DIV_ROUND_UP(cycles, OV5695_XVCLK_FREQ / 1000 / 1000); -} - static int __ov5695_power_on(struct ov5695 *ov5695) { - int ret; - u32 delay_us; + int i, ret; struct device *dev = &ov5695->client->dev; ret = clk_prepare_enable(ov5695->xvclk); @@ -991,21 +984,28 @@ gpiod_set_value_cansleep(ov5695->reset_gpio, 1); - ret = regulator_bulk_enable(OV5695_NUM_SUPPLIES, ov5695->supplies); - if (ret < 0) { - dev_err(dev, "Failed to enable regulators\n"); - goto disable_clk; + /* + * The hardware requires the regulators to be powered on in order, + * so enable them one by one. + */ + for (i = 0; i < OV5695_NUM_SUPPLIES; i++) { + ret = regulator_enable(ov5695->supplies[i].consumer); + if (ret) { + dev_err(dev, "Failed to enable %s: %d\n", + ov5695->supplies[i].supply, ret); + goto disable_reg_clk; + } } gpiod_set_value_cansleep(ov5695->reset_gpio, 0); - /* 8192 cycles prior to first SCCB transaction */ - delay_us = ov5695_cal_delay(8192); - usleep_range(delay_us, delay_us * 2); + usleep_range(1000, 1200); return 0; -disable_clk: +disable_reg_clk: + for (--i; i >= 0; i--) + regulator_disable(ov5695->supplies[i].consumer); clk_disable_unprepare(ov5695->xvclk); return ret; @@ -1013,9 +1013,22 @@ static void __ov5695_power_off(struct ov5695 *ov5695) { + struct device *dev = &ov5695->client->dev; + int i, ret; + clk_disable_unprepare(ov5695->xvclk); gpiod_set_value_cansleep(ov5695->reset_gpio, 1); - regulator_bulk_disable(OV5695_NUM_SUPPLIES, ov5695->supplies); + + /* + * The hardware requires the regulators to be powered off in order, + * so disable them one by one. + */ + for (i = OV5695_NUM_SUPPLIES - 1; i >= 0; i--) { + ret = regulator_disable(ov5695->supplies[i].consumer); + if (ret) + dev_err(dev, "Failed to disable %s: %d\n", + ov5695->supplies[i].supply, ret); + } } static int __maybe_unused ov5695_runtime_resume(struct device *dev) @@ -1285,7 +1298,7 @@ if (clk_get_rate(ov5695->xvclk) != OV5695_XVCLK_FREQ) dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n"); - ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + ov5695->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ov5695->reset_gpio)) { dev_err(dev, "Failed to get reset-gpios\n"); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov6650.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov6650.c @@ -130,6 +130,7 @@ #define CLKRC_24MHz 0xc0 #define CLKRC_DIV_MASK 0x3f #define GET_CLKRC_DIV(x) (((x) & CLKRC_DIV_MASK) + 1) +#define DEF_CLKRC 0x00 #define COMA_RESET BIT(7) #define COMA_QCIF BIT(5) @@ -200,7 +201,6 @@ unsigned long pclk_max; /* from resolution and format */ struct v4l2_fract tpf; /* as requested with s_frame_interval */ u32 code; - enum v4l2_colorspace colorspace; }; @@ -213,6 +213,17 @@ MEDIA_BUS_FMT_Y8_1X8, }; +static const struct v4l2_mbus_framefmt ov6650_def_fmt = { + .width = W_CIF, + .height = H_CIF, + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT, + .quantization = V4L2_QUANTIZATION_DEFAULT, + .xfer_func = V4L2_XFER_FUNC_DEFAULT, +}; + /* read a register */ static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) { @@ -465,38 +476,39 @@ { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov6650 *priv = to_ov6650(client); - struct v4l2_rect rect = sel->r; int ret; if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - v4l_bound_align_image(&rect.width, 2, W_CIF, 1, - &rect.height, 2, H_CIF, 1, 0); - v4l_bound_align_image(&rect.left, DEF_HSTRT << 1, - (DEF_HSTRT << 1) + W_CIF - (__s32)rect.width, 1, - &rect.top, DEF_VSTRT << 1, - (DEF_VSTRT << 1) + H_CIF - (__s32)rect.height, 1, - 0); + v4l_bound_align_image(&sel->r.width, 2, W_CIF, 1, + &sel->r.height, 2, H_CIF, 1, 0); + v4l_bound_align_image(&sel->r.left, DEF_HSTRT << 1, + (DEF_HSTRT << 1) + W_CIF - (__s32)sel->r.width, 1, + &sel->r.top, DEF_VSTRT << 1, + (DEF_VSTRT << 1) + H_CIF - (__s32)sel->r.height, + 1, 0); - ret = ov6650_reg_write(client, REG_HSTRT, rect.left >> 1); + ret = ov6650_reg_write(client, REG_HSTRT, sel->r.left >> 1); if (!ret) { - priv->rect.left = rect.left; + priv->rect.width += priv->rect.left - sel->r.left; + priv->rect.left = sel->r.left; ret = ov6650_reg_write(client, REG_HSTOP, - (rect.left + rect.width) >> 1); + (sel->r.left + sel->r.width) >> 1); } if (!ret) { - priv->rect.width = rect.width; - ret = ov6650_reg_write(client, REG_VSTRT, rect.top >> 1); + priv->rect.width = sel->r.width; + ret = ov6650_reg_write(client, REG_VSTRT, sel->r.top >> 1); } if (!ret) { - priv->rect.top = rect.top; + priv->rect.height += priv->rect.top - sel->r.top; + priv->rect.top = sel->r.top; ret = ov6650_reg_write(client, REG_VSTOP, - (rect.top + rect.height) >> 1); + (sel->r.top + sel->r.height) >> 1); } if (!ret) - priv->rect.height = rect.height; + priv->rect.height = sel->r.height; return ret; } @@ -512,12 +524,20 @@ if (format->pad) return -EINVAL; - mf->width = priv->rect.width >> priv->half_scale; - mf->height = priv->rect.height >> priv->half_scale; - mf->code = priv->code; - mf->colorspace = priv->colorspace; - mf->field = V4L2_FIELD_NONE; + /* initialize response with default media bus frame format */ + *mf = ov6650_def_fmt; + /* update media bus format code and frame size */ + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + mf->width = cfg->try_fmt.width; + mf->height = cfg->try_fmt.height; + mf->code = cfg->try_fmt.code; + + } else { + mf->width = priv->rect.width >> priv->half_scale; + mf->height = priv->rect.height >> priv->half_scale; + mf->code = priv->code; + } return 0; } @@ -610,7 +630,6 @@ dev_err(&client->dev, "Pixel format not handled: 0x%x\n", code); return -EINVAL; } - priv->code = code; if (code == MEDIA_BUS_FMT_Y8_1X8 || code == MEDIA_BUS_FMT_SBGGR8_1X8) { @@ -623,11 +642,6 @@ priv->pclk_max = 8000000; } - if (code == MEDIA_BUS_FMT_SBGGR8_1X8) - priv->colorspace = V4L2_COLORSPACE_SRGB; - else if (code != 0) - priv->colorspace = V4L2_COLORSPACE_JPEG; - if (half_scale) { dev_dbg(&client->dev, "max resolution: QCIF\n"); coma_set |= COMA_QCIF; @@ -636,7 +650,6 @@ dev_dbg(&client->dev, "max resolution: CIF\n"); coma_mask |= COMA_QCIF; } - priv->half_scale = half_scale; clkrc = CLKRC_12MHz; mclk = 12000000; @@ -654,14 +667,14 @@ ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); if (!ret) ret = ov6650_reg_write(client, REG_CLKRC, clkrc); - if (!ret) - ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); - if (!ret) { - mf->colorspace = priv->colorspace; - mf->width = priv->rect.width >> half_scale; - mf->height = priv->rect.height >> half_scale; + priv->half_scale = half_scale; + + ret = ov6650_reg_rmw(client, REG_COML, coml_set, coml_mask); } + if (!ret) + priv->code = code; + return ret; } @@ -680,8 +693,6 @@ v4l_bound_align_image(&mf->width, 2, W_CIF, 1, &mf->height, 2, H_CIF, 1, 0); - mf->field = V4L2_FIELD_NONE; - switch (mf->code) { case MEDIA_BUS_FMT_Y10_1X10: mf->code = MEDIA_BUS_FMT_Y8_1X8; @@ -691,20 +702,39 @@ case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_UYVY8_2X8: - mf->colorspace = V4L2_COLORSPACE_JPEG; break; default: mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; /* fall through */ case MEDIA_BUS_FMT_SBGGR8_1X8: - mf->colorspace = V4L2_COLORSPACE_SRGB; break; } - if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) - return ov6650_s_fmt(sd, mf); - cfg->try_fmt = *mf; + if (format->which == V4L2_SUBDEV_FORMAT_TRY) { + /* store media bus format code and frame size in pad config */ + cfg->try_fmt.width = mf->width; + cfg->try_fmt.height = mf->height; + cfg->try_fmt.code = mf->code; + + /* return default mbus frame format updated with pad config */ + *mf = ov6650_def_fmt; + mf->width = cfg->try_fmt.width; + mf->height = cfg->try_fmt.height; + mf->code = cfg->try_fmt.code; + + } else { + /* apply new media bus format code and frame size */ + int ret = ov6650_s_fmt(sd, mf); + if (ret) + return ret; + + /* return default format updated with active size and code */ + *mf = ov6650_def_fmt; + mf->width = priv->rect.width >> priv->half_scale; + mf->height = priv->rect.height >> priv->half_scale; + mf->code = priv->code; + } return 0; } @@ -754,19 +784,17 @@ else if (div > GET_CLKRC_DIV(CLKRC_DIV_MASK)) div = GET_CLKRC_DIV(CLKRC_DIV_MASK); - /* - * Keep result to be used as tpf limit - * for subsequent clock divider calculations - */ - priv->tpf.numerator = div; - priv->tpf.denominator = FRAME_RATE_MAX; + tpf->numerator = div; + tpf->denominator = FRAME_RATE_MAX; - clkrc = to_clkrc(&priv->tpf, priv->pclk_limit, priv->pclk_max); + clkrc = to_clkrc(tpf, priv->pclk_limit, priv->pclk_max); ret = ov6650_reg_rmw(client, REG_CLKRC, clkrc, CLKRC_DIV_MASK); if (!ret) { - tpf->numerator = GET_CLKRC_DIV(clkrc); - tpf->denominator = FRAME_RATE_MAX; + priv->tpf.numerator = GET_CLKRC_DIV(clkrc); + priv->tpf.denominator = FRAME_RATE_MAX; + + *tpf = priv->tpf; } return ret; @@ -849,6 +877,11 @@ ret = ov6650_reset(client); if (!ret) ret = ov6650_prog_dflt(client); + if (!ret) { + struct v4l2_mbus_framefmt mf = ov6650_def_fmt; + + ret = ov6650_s_fmt(sd, &mf); + } if (!ret) ret = v4l2_ctrl_handler_setup(&priv->hdl); @@ -989,8 +1022,10 @@ V4L2_CID_GAMMA, 0, 0xff, 1, 0x12); priv->subdev.ctrl_handler = &priv->hdl; - if (priv->hdl.error) - return priv->hdl.error; + if (priv->hdl.error) { + ret = priv->hdl.error; + goto ectlhdlfree; + } v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true); v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true); @@ -1001,15 +1036,18 @@ priv->rect.top = DEF_VSTRT << 1; priv->rect.width = W_CIF; priv->rect.height = H_CIF; - priv->half_scale = false; - priv->code = MEDIA_BUS_FMT_YUYV8_2X8; - priv->colorspace = V4L2_COLORSPACE_JPEG; + + /* Hardware default frame interval */ + priv->tpf.numerator = GET_CLKRC_DIV(DEF_CLKRC); + priv->tpf.denominator = FRAME_RATE_MAX; priv->subdev.internal_ops = &ov6650_internal_ops; ret = v4l2_async_register_subdev(&priv->subdev); - if (ret) - v4l2_ctrl_handler_free(&priv->hdl); + if (!ret) + return 0; +ectlhdlfree: + v4l2_ctrl_handler_free(&priv->hdl); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov7670.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov7670.c @@ -1824,7 +1824,7 @@ if (bus_cfg.bus_type != V4L2_MBUS_PARALLEL) { dev_err(dev, "Unsupported media bus type\n"); - return ret; + return -EINVAL; } info->mbus_config = bus_cfg.bus.parallel.flags; @@ -2000,7 +2000,6 @@ v4l2_async_unregister_subdev(sd); v4l2_ctrl_handler_free(&info->hdl); media_entity_cleanup(&info->sd.entity); - ov7670_power_off(sd); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/ov772x.c +++ linux-oracle-5.4.0/drivers/media/i2c/ov772x.c @@ -1397,7 +1397,7 @@ priv->subdev.ctrl_handler = &priv->hdl; if (priv->hdl.error) { ret = priv->hdl.error; - goto error_mutex_destroy; + goto error_ctrl_free; } priv->clk = clk_get(&client->dev, NULL); @@ -1446,7 +1446,6 @@ clk_put(priv->clk); error_ctrl_free: v4l2_ctrl_handler_free(&priv->hdl); -error_mutex_destroy: mutex_destroy(&priv->lock); return ret; --- linux-oracle-5.4.0.orig/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ linux-oracle-5.4.0/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1386,7 +1386,7 @@ s5c73m3_gpio_deassert(state, STBY); usleep_range(100, 200); - s5c73m3_gpio_deassert(state, RST); + s5c73m3_gpio_deassert(state, RSET); usleep_range(50, 100); return 0; @@ -1401,7 +1401,7 @@ { int i, ret; - if (s5c73m3_gpio_assert(state, RST)) + if (s5c73m3_gpio_assert(state, RSET)) usleep_range(10, 50); if (s5c73m3_gpio_assert(state, STBY)) @@ -1606,7 +1606,7 @@ state->mclk_frequency = pdata->mclk_frequency; state->gpio[STBY] = pdata->gpio_stby; - state->gpio[RST] = pdata->gpio_reset; + state->gpio[RSET] = pdata->gpio_reset; return 0; } --- linux-oracle-5.4.0.orig/drivers/media/i2c/s5c73m3/s5c73m3.h +++ linux-oracle-5.4.0/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -353,7 +353,7 @@ enum s5c73m3_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; --- linux-oracle-5.4.0.orig/drivers/media/i2c/s5k4ecgx.c +++ linux-oracle-5.4.0/drivers/media/i2c/s5k4ecgx.c @@ -173,7 +173,7 @@ enum s5k4ecgx_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -476,7 +476,7 @@ if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level)) usleep_range(30, 50); - if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level)) usleep_range(30, 50); return 0; @@ -484,7 +484,7 @@ static int __s5k4ecgx_power_off(struct s5k4ecgx *priv) { - if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level)) usleep_range(30, 50); if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level)) @@ -872,7 +872,7 @@ int ret; priv->gpio[STBY].gpio = -EINVAL; - priv->gpio[RST].gpio = -EINVAL; + priv->gpio[RSET].gpio = -EINVAL; ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY"); @@ -891,7 +891,7 @@ s5k4ecgx_free_gpios(priv); return ret; } - priv->gpio[RST] = *gpio; + priv->gpio[RSET] = *gpio; if (gpio_is_valid(gpio->gpio)) gpio_set_value(gpio->gpio, 0); --- linux-oracle-5.4.0.orig/drivers/media/i2c/s5k5baf.c +++ linux-oracle-5.4.0/drivers/media/i2c/s5k5baf.c @@ -235,7 +235,7 @@ enum s5k5baf_gpio_id { STBY, - RST, + RSET, NUM_GPIOS, }; @@ -970,7 +970,7 @@ s5k5baf_gpio_deassert(state, STBY); usleep_range(50, 100); - s5k5baf_gpio_deassert(state, RST); + s5k5baf_gpio_deassert(state, RSET); return 0; err_reg_dis: @@ -988,7 +988,7 @@ state->apply_cfg = 0; state->apply_crop = 0; - s5k5baf_gpio_assert(state, RST); + s5k5baf_gpio_assert(state, RSET); s5k5baf_gpio_assert(state, STBY); if (!IS_ERR(state->clock)) --- linux-oracle-5.4.0.orig/drivers/media/i2c/s5k6aa.c +++ linux-oracle-5.4.0/drivers/media/i2c/s5k6aa.c @@ -177,7 +177,7 @@ enum s5k6aa_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -841,7 +841,7 @@ ret = s5k6aa->s_power(1); usleep_range(4000, 5000); - if (s5k6aa_gpio_deassert(s5k6aa, RST)) + if (s5k6aa_gpio_deassert(s5k6aa, RSET)) msleep(20); return ret; @@ -851,7 +851,7 @@ { int ret; - if (s5k6aa_gpio_assert(s5k6aa, RST)) + if (s5k6aa_gpio_assert(s5k6aa, RSET)) usleep_range(100, 150); if (s5k6aa->s_power) { @@ -1510,7 +1510,7 @@ int ret; s5k6aa->gpio[STBY].gpio = -EINVAL; - s5k6aa->gpio[RST].gpio = -EINVAL; + s5k6aa->gpio[RSET].gpio = -EINVAL; gpio = &pdata->gpio_stby; if (gpio_is_valid(gpio->gpio)) { @@ -1533,7 +1533,7 @@ if (ret < 0) return ret; - s5k6aa->gpio[RST] = *gpio; + s5k6aa->gpio[RSET] = *gpio; } return 0; --- linux-oracle-5.4.0.orig/drivers/media/i2c/saa6588.c +++ linux-oracle-5.4.0/drivers/media/i2c/saa6588.c @@ -380,7 +380,7 @@ /* ---------------------------------------------------------------------- */ -static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct saa6588 *s = to_saa6588(sd); struct saa6588_command *a = arg; @@ -433,7 +433,7 @@ /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa6588_core_ops = { - .ioctl = saa6588_ioctl, + .command = saa6588_command, }; static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = { --- linux-oracle-5.4.0.orig/drivers/media/i2c/smiapp/smiapp-core.c +++ linux-oracle-5.4.0/drivers/media/i2c/smiapp/smiapp-core.c @@ -2327,11 +2327,12 @@ if (rval < 0) { if (rval != -EBUSY && rval != -EAGAIN) pm_runtime_set_active(&client->dev); - pm_runtime_put(&client->dev); + pm_runtime_put_noidle(&client->dev); return -ENODEV; } if (smiapp_read_nvm(sensor, sensor->nvm)) { + pm_runtime_put(&client->dev); dev_err(&client->dev, "nvm read failed\n"); return -ENODEV; } @@ -3101,19 +3102,23 @@ if (rval < 0) goto out_media_entity_cleanup; - rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd); - if (rval < 0) - goto out_media_entity_cleanup; - pm_runtime_set_active(&client->dev); pm_runtime_get_noresume(&client->dev); pm_runtime_enable(&client->dev); + + rval = v4l2_async_register_subdev_sensor_common(&sensor->src->sd); + if (rval < 0) + goto out_disable_runtime_pm; + pm_runtime_set_autosuspend_delay(&client->dev, 1000); pm_runtime_use_autosuspend(&client->dev); pm_runtime_put_autosuspend(&client->dev); return 0; +out_disable_runtime_pm: + pm_runtime_disable(&client->dev); + out_media_entity_cleanup: media_entity_cleanup(&sensor->src->sd.entity); --- linux-oracle-5.4.0.orig/drivers/media/i2c/st-mipid02.c +++ linux-oracle-5.4.0/drivers/media/i2c/st-mipid02.c @@ -971,6 +971,11 @@ bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(bridge->reset_gpio)) { + dev_err(dev, "failed to get reset GPIO\n"); + return PTR_ERR(bridge->reset_gpio); + } + ret = mipid02_get_regulators(bridge); if (ret) { dev_err(dev, "failed to get regulators %d", ret); --- linux-oracle-5.4.0.orig/drivers/media/i2c/tc358743.c +++ linux-oracle-5.4.0/drivers/media/i2c/tc358743.c @@ -919,8 +919,8 @@ .adap_monitor_all_enable = tc358743_cec_adap_monitor_all_enable, }; -static void tc358743_cec_isr(struct v4l2_subdev *sd, u16 intstatus, - bool *handled) +static void tc358743_cec_handler(struct v4l2_subdev *sd, u16 intstatus, + bool *handled) { struct tc358743_state *state = to_state(sd); unsigned int cec_rxint, cec_txint; @@ -953,7 +953,8 @@ cec_transmit_attempt_done(state->cec_adap, CEC_TX_STATUS_ERROR); } - *handled = true; + if (handled) + *handled = true; } if ((intstatus & MASK_CEC_RINT) && (cec_rxint & MASK_CECRIEND)) { @@ -968,7 +969,8 @@ msg.msg[i] = v & 0xff; } cec_received_msg(state->cec_adap, &msg); - *handled = true; + if (handled) + *handled = true; } i2c_wr16(sd, INTSTATUS, intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)); @@ -1432,7 +1434,7 @@ #ifdef CONFIG_VIDEO_TC358743_CEC if (intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)) { - tc358743_cec_isr(sd, intstatus, handled); + tc358743_cec_handler(sd, intstatus, handled); i2c_wr16(sd, INTSTATUS, intstatus & (MASK_CEC_RINT | MASK_CEC_TINT)); intstatus &= ~(MASK_CEC_RINT | MASK_CEC_TINT); @@ -1461,7 +1463,7 @@ static irqreturn_t tc358743_irq_handler(int irq, void *dev_id) { struct tc358743_state *state = dev_id; - bool handled; + bool handled = false; tc358743_isr(&state->sd, 0, &handled); @@ -1971,6 +1973,7 @@ bps_pr_lane = 2 * endpoint.link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); + ret = -EINVAL; goto disable_clk; } @@ -2104,9 +2107,6 @@ state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24; sd->dev = &client->dev; - err = v4l2_async_register_subdev(sd); - if (err < 0) - goto err_hdl; mutex_init(&state->confctl_mutex); @@ -2164,6 +2164,10 @@ if (err) goto err_work_queues; + err = v4l2_async_register_subdev(sd); + if (err < 0) + goto err_work_queues; + v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); @@ -2171,8 +2175,10 @@ err_work_queues: cec_unregister_adapter(state->cec_adap); - if (!state->i2c_client->irq) + if (!state->i2c_client->irq) { + del_timer(&state->timer); flush_work(&state->work_i2c_poll); + } cancel_delayed_work(&state->delayed_work_enable_hotplug); mutex_destroy(&state->confctl_mutex); err_hdl: @@ -2190,7 +2196,7 @@ del_timer_sync(&state->timer); flush_work(&state->work_i2c_poll); } - cancel_delayed_work(&state->delayed_work_enable_hotplug); + cancel_delayed_work_sync(&state->delayed_work_enable_hotplug); cec_unregister_adapter(state->cec_adap); v4l2_async_unregister_subdev(sd); v4l2_device_unregister_subdev(sd); --- linux-oracle-5.4.0.orig/drivers/media/i2c/tda1997x.c +++ linux-oracle-5.4.0/drivers/media/i2c/tda1997x.c @@ -1247,13 +1247,13 @@ { struct v4l2_subdev *sd = &state->sd; union hdmi_infoframe frame; - u8 buffer[40]; + u8 buffer[40] = { 0 }; u8 reg; int len, err; /* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); - err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); + err = hdmi_infoframe_unpack(&frame, buffer, len); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", @@ -1695,14 +1695,15 @@ struct v4l2_dv_timings *timings) { struct tda1997x_state *state = to_state(sd); + int ret; v4l_dbg(1, debug, state->client, "%s\n", __func__); memset(timings, 0, sizeof(struct v4l2_dv_timings)); mutex_lock(&state->lock); - tda1997x_detect_std(state, timings); + ret = tda1997x_detect_std(state, timings); mutex_unlock(&state->lock); - return 0; + return ret; } static const struct v4l2_subdev_video_ops tda1997x_video_ops = { @@ -1926,13 +1927,13 @@ { struct tda1997x_state *state = to_state(sd); union hdmi_infoframe frame; - u8 buffer[40]; + u8 buffer[40] = { 0 }; int len, err; /* read data */ len = io_readn(sd, addr, sizeof(buffer), buffer); v4l2_dbg(1, debug, sd, "infoframe: addr=%d len=%d\n", addr, len); - err = hdmi_infoframe_unpack(&frame, buffer, sizeof(buffer)); + err = hdmi_infoframe_unpack(&frame, buffer, len); if (err) { v4l_err(state->client, "failed parsing %d byte infoframe: 0x%04x/0x%02x\n", @@ -2233,6 +2234,7 @@ /* get initial HDMI status */ state->hdmi_status = io_read(sd, REG_HDMI_FLAGS); + io_write(sd, REG_EDID_ENABLE, EDID_ENABLE_A_EN | EDID_ENABLE_B_EN); return 0; } @@ -2804,7 +2806,7 @@ media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(&state->hdl); regulator_bulk_disable(TDA1997X_NUM_SUPPLIES, state->supplies); - cancel_delayed_work(&state->delayed_work_enable_hpd); + cancel_delayed_work_sync(&state->delayed_work_enable_hpd); mutex_destroy(&state->page_lock); mutex_destroy(&state->lock); --- linux-oracle-5.4.0.orig/drivers/media/i2c/video-i2c.c +++ linux-oracle-5.4.0/drivers/media/i2c/video-i2c.c @@ -255,7 +255,7 @@ return amg88xx_set_power_off(data); } -#if IS_ENABLED(CONFIG_HWMON) +#if IS_REACHABLE(CONFIG_HWMON) static const u32 amg88xx_temp_config[] = { HWMON_T_INPUT, --- linux-oracle-5.4.0.orig/drivers/media/mc/Makefile +++ linux-oracle-5.4.0/drivers/media/mc/Makefile @@ -3,7 +3,7 @@ mc-objs := mc-device.o mc-devnode.o mc-entity.o \ mc-request.o -ifeq ($(CONFIG_USB),y) +ifneq ($(CONFIG_USB),) mc-objs += mc-dev-allocator.o endif --- linux-oracle-5.4.0.orig/drivers/media/mc/mc-device.c +++ linux-oracle-5.4.0/drivers/media/mc/mc-device.c @@ -575,6 +575,38 @@ dev_dbg(devnode->parent, "Media device released\n"); } +static void __media_device_unregister_entity(struct media_entity *entity) +{ + struct media_device *mdev = entity->graph_obj.mdev; + struct media_link *link, *tmp; + struct media_interface *intf; + unsigned int i; + + ida_free(&mdev->entity_internal_idx, entity->internal_idx); + + /* Remove all interface links pointing to this entity */ + list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { + list_for_each_entry_safe(link, tmp, &intf->links, list) { + if (link->entity == entity) + __media_remove_intf_link(link); + } + } + + /* Remove all data links that belong to this entity */ + __media_entity_remove_links(entity); + + /* Remove all pads that belong to this entity */ + for (i = 0; i < entity->num_pads; i++) + media_gobj_destroy(&entity->pads[i].graph_obj); + + /* Remove the entity */ + media_gobj_destroy(&entity->graph_obj); + + /* invoke entity_notify callbacks to handle entity removal?? */ + + entity->graph_obj.mdev = NULL; +} + /** * media_device_register_entity - Register an entity with a media device * @mdev: The media device @@ -632,6 +664,7 @@ */ ret = media_graph_walk_init(&new, mdev); if (ret) { + __media_device_unregister_entity(entity); mutex_unlock(&mdev->graph_mutex); return ret; } @@ -644,38 +677,6 @@ } EXPORT_SYMBOL_GPL(media_device_register_entity); -static void __media_device_unregister_entity(struct media_entity *entity) -{ - struct media_device *mdev = entity->graph_obj.mdev; - struct media_link *link, *tmp; - struct media_interface *intf; - unsigned int i; - - ida_free(&mdev->entity_internal_idx, entity->internal_idx); - - /* Remove all interface links pointing to this entity */ - list_for_each_entry(intf, &mdev->interfaces, graph_obj.list) { - list_for_each_entry_safe(link, tmp, &intf->links, list) { - if (link->entity == entity) - __media_remove_intf_link(link); - } - } - - /* Remove all data links that belong to this entity */ - __media_entity_remove_links(entity); - - /* Remove all pads that belong to this entity */ - for (i = 0; i < entity->num_pads; i++) - media_gobj_destroy(&entity->pads[i].graph_obj); - - /* Remove the entity */ - media_gobj_destroy(&entity->graph_obj); - - /* invoke entity_notify callbacks to handle entity removal?? */ - - entity->graph_obj.mdev = NULL; -} - void media_device_unregister_entity(struct media_entity *entity) { struct media_device *mdev = entity->graph_obj.mdev; --- linux-oracle-5.4.0.orig/drivers/media/mc/mc-devnode.c +++ linux-oracle-5.4.0/drivers/media/mc/mc-devnode.c @@ -246,15 +246,14 @@ kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor); /* Part 3: Add the media and char device */ + set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); ret = cdev_device_add(&devnode->cdev, &devnode->dev); if (ret < 0) { + clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); pr_err("%s: cdev_device_add failed\n", __func__); goto cdev_add_error; } - /* Part 4: Activate this minor. The char device can now be used. */ - set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags); - return 0; cdev_add_error: --- linux-oracle-5.4.0.orig/drivers/media/mc/mc-entity.c +++ linux-oracle-5.4.0/drivers/media/mc/mc-entity.c @@ -639,9 +639,9 @@ return -EINVAL; for (i = 0; i < entity->num_pads; i++) { - if (entity->pads[i].flags == MEDIA_PAD_FL_SINK) + if (entity->pads[i].flags & MEDIA_PAD_FL_SINK) pad_is_sink = true; - else if (entity->pads[i].flags == MEDIA_PAD_FL_SOURCE) + else if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE) pad_is_sink = false; else continue; /* This is an error! */ --- linux-oracle-5.4.0.orig/drivers/media/mc/mc-request.c +++ linux-oracle-5.4.0/drivers/media/mc/mc-request.c @@ -296,9 +296,18 @@ if (WARN_ON(!mdev->ops->req_alloc ^ !mdev->ops->req_free)) return -ENOMEM; + if (mdev->ops->req_alloc) + req = mdev->ops->req_alloc(mdev); + else + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + fd = get_unused_fd_flags(O_CLOEXEC); - if (fd < 0) - return fd; + if (fd < 0) { + ret = fd; + goto err_free_req; + } filp = anon_inode_getfile("request", &request_fops, NULL, O_CLOEXEC); if (IS_ERR(filp)) { @@ -306,15 +315,6 @@ goto err_put_fd; } - if (mdev->ops->req_alloc) - req = mdev->ops->req_alloc(mdev); - else - req = kzalloc(sizeof(*req), GFP_KERNEL); - if (!req) { - ret = -ENOMEM; - goto err_fput; - } - filp->private_data = req; req->mdev = mdev; req->state = MEDIA_REQUEST_STATE_IDLE; @@ -336,12 +336,15 @@ return 0; -err_fput: - fput(filp); - err_put_fd: put_unused_fd(fd); +err_free_req: + if (mdev->ops->req_free) + mdev->ops->req_free(req); + else + kfree(req); + return ret; } --- linux-oracle-5.4.0.orig/drivers/media/pci/b2c2/flexcop-pci.c +++ linux-oracle-5.4.0/drivers/media/pci/b2c2/flexcop-pci.c @@ -185,6 +185,8 @@ dma_addr_t cur_addr = fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; + if (cur_pos > fc_pci->dma[0].size * 2) + goto error; deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", jiffies_to_usecs(jiffies - fc_pci->last_irq), @@ -225,6 +227,7 @@ ret = IRQ_NONE; } +error: spin_unlock_irqrestore(&fc_pci->irq_lock, flags); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/pci/bt8xx/bt878.c +++ linux-oracle-5.4.0/drivers/media/pci/bt8xx/bt878.c @@ -477,6 +477,9 @@ btwrite(0, BT878_AINT_MASK); bt878_num++; + if (!bt->tasklet.func) + tasklet_disable(&bt->tasklet); + return 0; fail2: --- linux-oracle-5.4.0.orig/drivers/media/pci/bt8xx/bttv-driver.c +++ linux-oracle-5.4.0/drivers/media/pci/bt8xx/bttv-driver.c @@ -2964,7 +2964,7 @@ dprintk("open dev=%s\n", video_device_node_name(vdev)); - if (vdev->vfl_type == VFL_TYPE_GRABBER) { + if (vdev->vfl_type == VFL_TYPE_VIDEO) { type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } else if (vdev->vfl_type == VFL_TYPE_VBI) { type = V4L2_BUF_TYPE_VBI_CAPTURE; @@ -3187,7 +3187,7 @@ btv->radio_user--; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd); if (btv->radio_user == 0) btv->has_radio_tuner = 0; @@ -3268,7 +3268,7 @@ cmd.result = -ENODEV; radio_enable(btv); - bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd); return cmd.result; } @@ -3289,7 +3289,7 @@ cmd.instance = file; cmd.event_list = wait; cmd.poll_mask = res; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd); return cmd.poll_mask; } @@ -3898,14 +3898,14 @@ /* video */ vdev_init(btv, &btv->video_dev, &bttv_video_template, "video"); - btv->video_dev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + btv->video_dev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; if (btv->tuner_type != TUNER_ABSENT) btv->video_dev.device_caps |= V4L2_CAP_TUNER; if (no_overlay <= 0) btv->video_dev.device_caps |= V4L2_CAP_VIDEO_OVERLAY; - if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER, + if (video_register_device(&btv->video_dev, VFL_TYPE_VIDEO, video_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", @@ -3919,7 +3919,7 @@ /* vbi */ vdev_init(btv, &btv->vbi_dev, &bttv_video_template, "vbi"); btv->vbi_dev.device_caps = V4L2_CAP_VBI_CAPTURE | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | V4L2_CAP_TUNER; + V4L2_CAP_STREAMING; if (btv->tuner_type != TUNER_ABSENT) btv->vbi_dev.device_caps |= V4L2_CAP_TUNER; @@ -4013,11 +4013,13 @@ btv->id = dev->device; if (pci_enable_device(dev)) { pr_warn("%d: Can't enable device\n", btv->c.nr); - return -EIO; + result = -EIO; + goto free_mem; } if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { pr_warn("%d: No suitable DMA available\n", btv->c.nr); - return -EIO; + result = -EIO; + goto free_mem; } if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), @@ -4025,7 +4027,8 @@ pr_warn("%d: can't request iomem (0x%llx)\n", btv->c.nr, (unsigned long long)pci_resource_start(dev, 0)); - return -EBUSY; + result = -EBUSY; + goto free_mem; } pci_set_master(dev); pci_set_command(dev); @@ -4211,6 +4214,10 @@ release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); pci_disable_device(btv->c.pci); + +free_mem: + bttvs[btv->c.nr] = NULL; + kfree(btv); return result; } @@ -4251,6 +4258,7 @@ /* free resources */ free_irq(btv->c.pci->irq,btv); + del_timer_sync(&btv->timeout); iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); --- linux-oracle-5.4.0.orig/drivers/media/pci/bt8xx/dst.c +++ linux-oracle-5.4.0/drivers/media/pci/bt8xx/dst.c @@ -1722,7 +1722,7 @@ return state; /* Manu (DST is a card not a frontend) */ } -EXPORT_SYMBOL(dst_attach); +EXPORT_SYMBOL_GPL(dst_attach); static const struct dvb_frontend_ops dst_dvbt_ops = { .delsys = { SYS_DVBT }, --- linux-oracle-5.4.0.orig/drivers/media/pci/bt8xx/dst_ca.c +++ linux-oracle-5.4.0/drivers/media/pci/bt8xx/dst_ca.c @@ -668,7 +668,7 @@ return NULL; } -EXPORT_SYMBOL(dst_ca_attach); +EXPORT_SYMBOL_GPL(dst_ca_attach); MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); MODULE_AUTHOR("Manu Abraham"); --- linux-oracle-5.4.0.orig/drivers/media/pci/cobalt/cobalt-driver.c +++ linux-oracle-5.4.0/drivers/media/pci/cobalt/cobalt-driver.c @@ -8,6 +8,7 @@ * All rights reserved. */ +#include #include #include #include @@ -210,17 +211,17 @@ pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &stat); cobalt_info("PCIe link capability 0x%08x: %s per lane and %u lanes\n", capa, get_link_speed(capa), - (capa & PCI_EXP_LNKCAP_MLW) >> 4); + FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); cobalt_info("PCIe link control 0x%04x\n", ctrl); cobalt_info("PCIe link status 0x%04x: %s per lane and %u lanes\n", stat, get_link_speed(stat), - (stat & PCI_EXP_LNKSTA_NLW) >> 4); + FIELD_GET(PCI_EXP_LNKSTA_NLW, stat)); /* Bus */ pcie_capability_read_dword(pci_bus_dev, PCI_EXP_LNKCAP, &capa); cobalt_info("PCIe bus link capability 0x%08x: %s per lane and %u lanes\n", capa, get_link_speed(capa), - (capa & PCI_EXP_LNKCAP_MLW) >> 4); + FIELD_GET(PCI_EXP_LNKCAP_MLW, capa)); /* Slot */ pcie_capability_read_dword(pci_dev, PCI_EXP_SLTCAP, &capa); @@ -239,7 +240,7 @@ if (!pci_is_pcie(pci_dev)) return 0; pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &link); - return (link & PCI_EXP_LNKSTA_NLW) >> 4; + return FIELD_GET(PCI_EXP_LNKSTA_NLW, link); } static unsigned pcie_bus_link_get_lanes(struct cobalt *cobalt) @@ -250,7 +251,7 @@ if (!pci_is_pcie(pci_dev)) return 0; pcie_capability_read_dword(pci_dev, PCI_EXP_LNKCAP, &link); - return (link & PCI_EXP_LNKCAP_MLW) >> 4; + return FIELD_GET(PCI_EXP_LNKCAP_MLW, link); } static void msi_config_show(struct cobalt *cobalt, struct pci_dev *pci_dev) @@ -667,6 +668,7 @@ return -ENOMEM; cobalt->pci_dev = pci_dev; cobalt->instance = i; + mutex_init(&cobalt->pci_lock); retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); if (retval) { --- linux-oracle-5.4.0.orig/drivers/media/pci/cobalt/cobalt-driver.h +++ linux-oracle-5.4.0/drivers/media/pci/cobalt/cobalt-driver.h @@ -251,6 +251,8 @@ int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; + /* serialize PCI access in cobalt_s_bit_sysctrl() */ + struct mutex pci_lock; void __iomem *bar0, *bar1; @@ -320,10 +322,13 @@ static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, int bit, int val) { - u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + u32 ctrl; + mutex_lock(&cobalt->pci_lock); + ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, (ctrl & ~(1UL << bit)) | (val << bit)); + mutex_unlock(&cobalt->pci_lock); } static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) --- linux-oracle-5.4.0.orig/drivers/media/pci/cobalt/cobalt-v4l2.c +++ linux-oracle-5.4.0/drivers/media/pci/cobalt/cobalt-v4l2.c @@ -1272,7 +1272,7 @@ video_set_drvdata(vdev, s); ret = vb2_queue_init(q); if (!s->is_audio && ret == 0) - ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); else if (!s->is_dummy) ret = cobalt_alsa_init(s); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx18/cx18-streams.c +++ linux-oracle-5.4.0/drivers/media/pci/cx18/cx18-streams.c @@ -48,19 +48,19 @@ } cx18_stream_info[] = { { /* CX18_ENC_STREAM_TYPE_MPG */ "encoder MPEG", - VFL_TYPE_GRABBER, 0, + VFL_TYPE_VIDEO, 0, PCI_DMA_FROMDEVICE, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_AUDIO | V4L2_CAP_TUNER }, { /* CX18_ENC_STREAM_TYPE_TS */ "TS", - VFL_TYPE_GRABBER, -1, + VFL_TYPE_VIDEO, -1, PCI_DMA_FROMDEVICE, }, { /* CX18_ENC_STREAM_TYPE_YUV */ "encoder YUV", - VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, + VFL_TYPE_VIDEO, CX18_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_TUNER @@ -74,13 +74,13 @@ }, { /* CX18_ENC_STREAM_TYPE_PCM */ "encoder PCM audio", - VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, + VFL_TYPE_VIDEO, CX18_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, }, { /* CX18_ENC_STREAM_TYPE_IDX */ "encoder IDX", - VFL_TYPE_GRABBER, -1, + VFL_TYPE_VIDEO, -1, PCI_DMA_FROMDEVICE, }, { /* CX18_ENC_STREAM_TYPE_RAD */ @@ -434,7 +434,7 @@ name = video_device_node_name(&s->video_dev); switch (vfl_type) { - case VFL_TYPE_GRABBER: + case VFL_TYPE_VIDEO: CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n", name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type] / 1024, --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885-417.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885-417.c @@ -1545,7 +1545,7 @@ if (dev->tuner_type != TUNER_ABSENT) dev->v4l_device->device_caps |= V4L2_CAP_TUNER; err = video_register_device(dev->v4l_device, - VFL_TYPE_GRABBER, -1); + VFL_TYPE_VIDEO, -1); if (err < 0) { pr_info("%s: can't register mpeg device\n", dev->name); return err; --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885-alsa.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885-alsa.c @@ -550,7 +550,7 @@ SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, THIS_MODULE, sizeof(struct cx23885_audio_dev), &card); if (err < 0) - goto error; + goto error_msg; chip = (struct cx23885_audio_dev *) card->private_data; chip->dev = dev; @@ -576,6 +576,7 @@ error: snd_card_free(card); +error_msg: pr_err("%s(): Failed to register analog audio adapter\n", __func__); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885-cards.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885-cards.c @@ -801,6 +801,25 @@ .name = "Hauppauge WinTV-Starburst2", .portb = CX23885_MPEG_DVB, }, + [CX23885_BOARD_AVERMEDIA_CE310B] = { + .name = "AVerMedia CE310B", + .porta = CX23885_ANALOG_VIDEO, + .force_bff = 1, + .input = {{ + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_VIN1_CH1 | + CX25840_NONE_CH2 | + CX25840_NONE0_CH3, + .amux = CX25840_AUDIO7, + }, { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_VIN8_CH1 | + CX25840_NONE_CH2 | + CX25840_VIN7_CH3 | + CX25840_SVIDEO_ON, + .amux = CX25840_AUDIO7, + } }, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -1124,6 +1143,10 @@ .subvendor = 0x0070, .subdevice = 0xf02a, .card = CX23885_BOARD_HAUPPAUGE_STARBURST2, + }, { + .subvendor = 0x1461, + .subdevice = 0x3100, + .card = CX23885_BOARD_AVERMEDIA_CE310B, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -2348,6 +2371,7 @@ case CX23885_BOARD_DVBSKY_T982: case CX23885_BOARD_VIEWCAST_260E: case CX23885_BOARD_VIEWCAST_460E: + case CX23885_BOARD_AVERMEDIA_CE310B: dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_bus[2].i2c_adap, "cx25840", 0x88 >> 1, NULL); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885-core.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885-core.c @@ -2074,6 +2074,10 @@ * 0x1451 is PCI ID for the IOMMU found on Ryzen */ { PCI_VENDOR_ID_AMD, 0x1451 }, + /* According to sudo lspci -nn, + * 0x1423 is the PCI ID for the IOMMU found on Kaveri + */ + { PCI_VENDOR_ID_AMD, 0x1423 }, }; static bool cx23885_does_need_dma_reset(void) @@ -2150,7 +2154,7 @@ err = pci_set_dma_mask(pci_dev, 0xffffffff); if (err) { pr_err("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - goto fail_ctrl; + goto fail_dma_set_mask; } err = request_irq(pci_dev->irq, cx23885_irq, @@ -2158,7 +2162,7 @@ if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); - goto fail_irq; + goto fail_dma_set_mask; } switch (dev->board) { @@ -2180,7 +2184,7 @@ return 0; -fail_irq: +fail_dma_set_mask: cx23885_dev_unregister(dev); fail_ctrl: v4l2_ctrl_handler_free(hdl); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885-video.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885-video.c @@ -257,7 +257,8 @@ (dev->board == CX23885_BOARD_MYGICA_X8507) || (dev->board == CX23885_BOARD_AVERMEDIA_HC81R) || (dev->board == CX23885_BOARD_VIEWCAST_260E) || - (dev->board == CX23885_BOARD_VIEWCAST_460E)) { + (dev->board == CX23885_BOARD_VIEWCAST_460E) || + (dev->board == CX23885_BOARD_AVERMEDIA_CE310B)) { /* Configure audio routing */ v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, INPUT(input)->amux, 0, 0); @@ -408,7 +409,7 @@ dev->height >> 1); break; default: - BUG(); + return -EINVAL; /* should not happen */ } dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", buf, buf->vb.vb2_buf.index, @@ -1298,12 +1299,16 @@ /* register Video device */ dev->video_dev = cx23885_vdev_init(dev, dev->pci, &cx23885_video_template, "video"); + if (!dev->video_dev) { + err = -ENOMEM; + goto fail_unreg; + } dev->video_dev->queue = &dev->vb2_vidq; dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE; if (dev->tuner_type != TUNER_ABSENT) dev->video_dev->device_caps |= V4L2_CAP_TUNER; - err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, + err = video_register_device(dev->video_dev, VFL_TYPE_VIDEO, video_nr[dev->nr]); if (err < 0) { pr_info("%s: can't register video device\n", @@ -1316,6 +1321,10 @@ /* register VBI device */ dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, &cx23885_vbi_template, "vbi"); + if (!dev->vbi_dev) { + err = -ENOMEM; + goto fail_unreg; + } dev->vbi_dev->queue = &dev->vb2_vbiq; dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE; --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23885.h +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23885.h @@ -101,6 +101,7 @@ #define CX23885_BOARD_HAUPPAUGE_STARBURST2 59 #define CX23885_BOARD_HAUPPAUGE_QUADHD_DVB_885 60 #define CX23885_BOARD_HAUPPAUGE_QUADHD_ATSC_885 61 +#define CX23885_BOARD_AVERMEDIA_CE310B 62 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 --- linux-oracle-5.4.0.orig/drivers/media/pci/cx23885/cx23888-ir.c +++ linux-oracle-5.4.0/drivers/media/pci/cx23885/cx23888-ir.c @@ -1167,8 +1167,11 @@ return -ENOMEM; spin_lock_init(&state->rx_kfifo_lock); - if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) + if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, + GFP_KERNEL)) { + kfree(state); return -ENOMEM; + } state->dev = dev; sd = &state->sd; --- linux-oracle-5.4.0.orig/drivers/media/pci/cx25821/cx25821-core.c +++ linux-oracle-5.4.0/drivers/media/pci/cx25821/cx25821-core.c @@ -976,8 +976,10 @@ __le32 *cpu; dma_addr_t dma = 0; - if (NULL != risc->cpu && risc->size < size) + if (risc->cpu && risc->size < size) { pci_free_consistent(pci, risc->size, risc->cpu, risc->dma); + risc->cpu = NULL; + } if (NULL == risc->cpu) { cpu = pci_zalloc_consistent(pci, size, &dma); if (NULL == cpu) @@ -1338,11 +1340,11 @@ struct cx25821_dev *dev = get_cx25821(v4l2_dev); cx25821_shutdown(dev); - pci_disable_device(pci_dev); /* unregister stuff */ if (pci_dev->irq) free_irq(pci_dev->irq, dev); + pci_disable_device(pci_dev); cx25821_dev_unregister(dev); v4l2_device_unregister(v4l2_dev); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx25821/cx25821-video.c +++ linux-oracle-5.4.0/drivers/media/pci/cx25821/cx25821-video.c @@ -757,7 +757,7 @@ snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i); video_set_drvdata(vdev, chan); - err = video_register_device(vdev, VFL_TYPE_GRABBER, + err = video_register_device(vdev, VFL_TYPE_VIDEO, video_nr[dev->nr]); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/media/pci/cx88/cx88-blackbird.c +++ linux-oracle-5.4.0/drivers/media/pci/cx88/cx88-blackbird.c @@ -1138,7 +1138,7 @@ V4L2_CAP_VIDEO_CAPTURE; if (dev->core->board.tuner_type != UNSET) dev->mpeg_dev.device_caps |= V4L2_CAP_TUNER; - err = video_register_device(&dev->mpeg_dev, VFL_TYPE_GRABBER, -1); + err = video_register_device(&dev->mpeg_dev, VFL_TYPE_VIDEO, -1); if (err < 0) { pr_info("can't register mpeg device\n"); return err; --- linux-oracle-5.4.0.orig/drivers/media/pci/cx88/cx88-mpeg.c +++ linux-oracle-5.4.0/drivers/media/pci/cx88/cx88-mpeg.c @@ -162,6 +162,9 @@ cx_write(MO_TS_GPCNTRL, GP_COUNT_CONTROL_RESET); q->count = 0; + /* clear interrupt status register */ + cx_write(MO_TS_INTSTAT, 0x1f1111); + /* enable irqs */ dprintk(1, "setting the interrupt mask\n"); cx_set(MO_PCI_INTMSK, core->pci_irqmask | PCI_INT_TSINT); --- linux-oracle-5.4.0.orig/drivers/media/pci/cx88/cx88-vbi.c +++ linux-oracle-5.4.0/drivers/media/pci/cx88/cx88-vbi.c @@ -144,11 +144,10 @@ return -EINVAL; vb2_set_plane_payload(vb, 0, size); - cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, - 0, VBI_LINE_LENGTH * lines, - VBI_LINE_LENGTH, 0, - lines); - return 0; + return cx88_risc_buffer(dev->pci, &buf->risc, sgt->sgl, + 0, VBI_LINE_LENGTH * lines, + VBI_LINE_LENGTH, 0, + lines); } static void buffer_finish(struct vb2_buffer *vb) --- linux-oracle-5.4.0.orig/drivers/media/pci/cx88/cx88-video.c +++ linux-oracle-5.4.0/drivers/media/pci/cx88/cx88-video.c @@ -433,6 +433,7 @@ static int buffer_prepare(struct vb2_buffer *vb) { + int ret; struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct cx8800_dev *dev = vb->vb2_queue->drv_priv; struct cx88_core *core = dev->core; @@ -447,35 +448,35 @@ switch (core->field) { case V4L2_FIELD_TOP: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, 0, UNSET, - buf->bpl, 0, core->height); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, 0, UNSET, + buf->bpl, 0, core->height); break; case V4L2_FIELD_BOTTOM: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, UNSET, 0, - buf->bpl, 0, core->height); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, UNSET, 0, + buf->bpl, 0, core->height); break; case V4L2_FIELD_SEQ_TB: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, - 0, buf->bpl * (core->height >> 1), - buf->bpl, 0, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + 0, buf->bpl * (core->height >> 1), + buf->bpl, 0, + core->height >> 1); break; case V4L2_FIELD_SEQ_BT: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, - buf->bpl * (core->height >> 1), 0, - buf->bpl, 0, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, + buf->bpl * (core->height >> 1), 0, + buf->bpl, 0, + core->height >> 1); break; case V4L2_FIELD_INTERLACED: default: - cx88_risc_buffer(dev->pci, &buf->risc, - sgt->sgl, 0, buf->bpl, - buf->bpl, buf->bpl, - core->height >> 1); + ret = cx88_risc_buffer(dev->pci, &buf->risc, + sgt->sgl, 0, buf->bpl, + buf->bpl, buf->bpl, + core->height >> 1); break; } dprintk(2, @@ -483,7 +484,7 @@ buf, buf->vb.vb2_buf.index, __func__, core->width, core->height, dev->fmt->depth, dev->fmt->fourcc, (unsigned long)buf->risc.dma); - return 0; + return ret; } static void buffer_finish(struct vb2_buffer *vb) @@ -1277,7 +1278,7 @@ core = cx88_core_get(dev->pci); if (!core) { err = -EINVAL; - goto fail_free; + goto fail_disable; } dev->core = core; @@ -1323,7 +1324,7 @@ cc->step, cc->default_value); if (!vc) { err = core->audio_hdl.error; - goto fail_core; + goto fail_irq; } vc->priv = (void *)cc; } @@ -1337,7 +1338,7 @@ cc->step, cc->default_value); if (!vc) { err = core->video_hdl.error; - goto fail_core; + goto fail_irq; } vc->priv = (void *)cc; if (vc->id == V4L2_CID_CHROMA_AGC) @@ -1451,7 +1452,7 @@ V4L2_CAP_VIDEO_CAPTURE; if (core->board.tuner_type != UNSET) dev->video_dev.device_caps |= V4L2_CAP_TUNER; - err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, + err = video_register_device(&dev->video_dev, VFL_TYPE_VIDEO, video_nr[core->nr]); if (err < 0) { pr_err("can't register video device\n"); @@ -1509,11 +1510,14 @@ fail_unreg: cx8800_unregister_video(dev); - free_irq(pci_dev->irq, dev); mutex_unlock(&core->lock); +fail_irq: + free_irq(pci_dev->irq, dev); fail_core: core->v4ldev = NULL; cx88_core_put(core, dev->pci); +fail_disable: + pci_disable_device(pci_dev); fail_free: kfree(dev); return err; --- linux-oracle-5.4.0.orig/drivers/media/pci/ddbridge/ddbridge-main.c +++ linux-oracle-5.4.0/drivers/media/pci/ddbridge/ddbridge-main.c @@ -247,7 +247,7 @@ ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -1; + return stat; } /****************************************************************************/ --- linux-oracle-5.4.0.orig/drivers/media/pci/dm1105/dm1105.c +++ linux-oracle-5.4.0/drivers/media/pci/dm1105/dm1105.c @@ -1179,6 +1179,7 @@ struct dvb_demux *dvbdemux = &dev->demux; struct dmx_demux *dmx = &dvbdemux->dmx; + cancel_work_sync(&dev->ir.work); dm1105_ir_exit(dev); dmx->close(dmx); dvb_net_release(&dev->dvbnet); --- linux-oracle-5.4.0.orig/drivers/media/pci/dt3155/dt3155.c +++ linux-oracle-5.4.0/drivers/media/pci/dt3155/dt3155.c @@ -550,7 +550,7 @@ IRQF_SHARED, DT3155_NAME, pd); if (err) goto err_iounmap; - err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1); + err = video_register_device(&pd->vdev, VFL_TYPE_VIDEO, -1); if (err) goto err_free_irq; dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor); --- linux-oracle-5.4.0.orig/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ linux-oracle-5.4.0/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -359,7 +359,7 @@ void __iomem *const base = cio2->base; u8 lanes, csi2bus = q->csi2.port; u8 sensor_vc = SENSOR_VIR_CH_DFLT; - struct cio2_csi2_timing timing; + struct cio2_csi2_timing timing = { 0 }; int i, r; fmt = cio2_find_format(NULL, &q->subdev_fmt.code); @@ -799,6 +799,7 @@ atomic_dec(&q->bufs_queued); vb2_buffer_done(&q->bufs[i]->vbb.vb2_buf, state); + q->bufs[i] = NULL; } } } @@ -1243,29 +1244,15 @@ struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); - struct v4l2_subdev_format format; - int ret; - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); - return 0; - } - if (fmt->pad == CIO2_PAD_SINK) { - format.which = V4L2_SUBDEV_FORMAT_ACTIVE; - ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, - &format); + mutex_lock(&q->subdev_lock); - if (ret) - return ret; - /* update colorspace etc */ - q->subdev_fmt.colorspace = format.format.colorspace; - q->subdev_fmt.ycbcr_enc = format.format.ycbcr_enc; - q->subdev_fmt.quantization = format.format.quantization; - q->subdev_fmt.xfer_func = format.format.xfer_func; - } + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + else + fmt->format = q->subdev_fmt; - fmt->format = q->subdev_fmt; + mutex_unlock(&q->subdev_lock); return 0; } @@ -1282,6 +1269,9 @@ struct v4l2_subdev_format *fmt) { struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev); + struct v4l2_mbus_framefmt *mbus; + u32 mbus_code = fmt->format.code; + unsigned int i; /* * Only allow setting sink pad format; @@ -1290,16 +1280,29 @@ if (fmt->pad == CIO2_PAD_SOURCE) return cio2_subdev_get_fmt(sd, cfg, fmt); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; - } else { - /* It's the sink, allow changing frame size */ - q->subdev_fmt.width = fmt->format.width; - q->subdev_fmt.height = fmt->format.height; - q->subdev_fmt.code = fmt->format.code; - fmt->format = q->subdev_fmt; + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + mbus = v4l2_subdev_get_try_format(sd, cfg, fmt->pad); + else + mbus = &q->subdev_fmt; + + fmt->format.code = formats[0].mbus_code; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (formats[i].mbus_code == mbus_code) { + fmt->format.code = mbus_code; + break; + } } + fmt->format.width = min_t(u32, fmt->format.width, CIO2_IMAGE_MAX_WIDTH); + fmt->format.height = min_t(u32, fmt->format.height, + CIO2_IMAGE_MAX_LENGTH); + fmt->format.field = V4L2_FIELD_NONE; + + mutex_lock(&q->subdev_lock); + *mbus = fmt->format; + mutex_unlock(&q->subdev_lock); + return 0; } @@ -1558,6 +1561,7 @@ /* Initialize miscellaneous variables */ mutex_init(&q->lock); + mutex_init(&q->subdev_lock); /* Initialize formats to default values */ fmt = &q->subdev_fmt; @@ -1647,7 +1651,7 @@ vdev->queue = &q->vbq; vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING; video_set_drvdata(vdev, cio2); - r = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + r = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (r) { dev_err(&cio2->pci_dev->dev, "failed to register video device (%d)\n", r); @@ -1676,6 +1680,7 @@ fail_subdev_media_entity: cio2_fbpt_exit(q, &cio2->pci_dev->dev); fail_fbpt: + mutex_destroy(&q->subdev_lock); mutex_destroy(&q->lock); return r; @@ -1689,6 +1694,7 @@ v4l2_device_unregister_subdev(&q->subdev); media_entity_cleanup(&q->subdev.entity); cio2_fbpt_exit(q, &cio2->pci_dev->dev); + mutex_destroy(&q->subdev_lock); mutex_destroy(&q->lock); } @@ -1865,6 +1871,9 @@ v4l2_device_unregister(&cio2->v4l2_dev); media_device_cleanup(&cio2->media_dev); mutex_destroy(&cio2->lock); + + pm_runtime_forbid(&pci_dev->dev); + pm_runtime_get_noresume(&pci_dev->dev); } static int __maybe_unused cio2_runtime_suspend(struct device *dev) --- linux-oracle-5.4.0.orig/drivers/media/pci/intel/ipu3/ipu3-cio2.h +++ linux-oracle-5.4.0/drivers/media/pci/intel/ipu3/ipu3-cio2.h @@ -332,6 +332,7 @@ /* Subdev, /dev/v4l-subdevX */ struct v4l2_subdev subdev; + struct mutex subdev_lock; /* Serialise acces to subdev_fmt field */ struct media_pad subdev_pads[CIO2_PADS]; struct v4l2_mbus_framefmt subdev_fmt; atomic_t frame_sequence; --- linux-oracle-5.4.0.orig/drivers/media/pci/ivtv/ivtv-driver.h +++ linux-oracle-5.4.0/drivers/media/pci/ivtv/ivtv-driver.h @@ -333,7 +333,6 @@ struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ - u32 caps; /* V4L2 capabilities */ struct v4l2_fh *fh; /* pointer to the streaming filehandle */ spinlock_t qlock; /* locks access to the queues */ --- linux-oracle-5.4.0.orig/drivers/media/pci/ivtv/ivtv-ioctl.c +++ linux-oracle-5.4.0/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -443,7 +443,7 @@ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; struct v4l2_window *winfmt = &fmt->fmt.win; - if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; if (!itv->osd_video_pbase) return -EINVAL; @@ -554,7 +554,7 @@ u32 chromakey = fmt->fmt.win.chromakey; u8 global_alpha = fmt->fmt.win.global_alpha; - if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; if (!itv->osd_video_pbase) return -EINVAL; @@ -1386,7 +1386,7 @@ 0, }; - if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -ENOTTY; if (!itv->osd_video_pbase) return -ENOTTY; @@ -1453,7 +1453,7 @@ struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; struct yuv_playback_info *yi = &itv->yuv_info; - if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -ENOTTY; if (!itv->osd_video_pbase) return -ENOTTY; @@ -1473,7 +1473,7 @@ struct ivtv *itv = id->itv; struct ivtv_stream *s = &itv->streams[fh2id(fh)->type]; - if (!(s->caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + if (!(s->vdev.device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -ENOTTY; if (!itv->osd_video_pbase) return -ENOTTY; --- linux-oracle-5.4.0.orig/drivers/media/pci/ivtv/ivtv-streams.c +++ linux-oracle-5.4.0/drivers/media/pci/ivtv/ivtv-streams.c @@ -99,7 +99,7 @@ } ivtv_stream_info[] = { { /* IVTV_ENC_STREAM_TYPE_MPG */ "encoder MPG", - VFL_TYPE_GRABBER, 0, + VFL_TYPE_VIDEO, 0, PCI_DMA_FROMDEVICE, 0, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, @@ -107,7 +107,7 @@ }, { /* IVTV_ENC_STREAM_TYPE_YUV */ "encoder YUV", - VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, + VFL_TYPE_VIDEO, IVTV_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, @@ -123,7 +123,7 @@ }, { /* IVTV_ENC_STREAM_TYPE_PCM */ "encoder PCM", - VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, + VFL_TYPE_VIDEO, IVTV_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops @@ -137,7 +137,7 @@ }, { /* IVTV_DEC_STREAM_TYPE_MPG */ "decoder MPG", - VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, + VFL_TYPE_VIDEO, IVTV_V4L2_DEC_MPG_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops @@ -158,7 +158,7 @@ }, { /* IVTV_DEC_STREAM_TYPE_YUV */ "decoder YUV", - VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, + VFL_TYPE_VIDEO, IVTV_V4L2_DEC_YUV_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops @@ -176,7 +176,7 @@ s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; - s->caps = ivtv_stream_info[type].v4l2_caps; + s->vdev.device_caps = ivtv_stream_info[type].v4l2_caps; if (ivtv_stream_info[type].pio) s->dma = PCI_DMA_NONE; @@ -299,12 +299,9 @@ if (s_mpg->vdev.v4l2_dev) num = s_mpg->vdev.num + ivtv_stream_info[type].num_offset; } - s->vdev.device_caps = s->caps; - if (itv->osd_video_pbase) { - itv->streams[IVTV_DEC_STREAM_TYPE_YUV].vdev.device_caps |= - V4L2_CAP_VIDEO_OUTPUT_OVERLAY; - itv->streams[IVTV_DEC_STREAM_TYPE_MPG].vdev.device_caps |= - V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + if (itv->osd_video_pbase && (type == IVTV_DEC_STREAM_TYPE_YUV || + type == IVTV_DEC_STREAM_TYPE_MPG)) { + s->vdev.device_caps |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY; itv->v4l2_cap |= V4L2_CAP_VIDEO_OUTPUT_OVERLAY; } video_set_drvdata(&s->vdev, s); @@ -318,7 +315,7 @@ name = video_device_node_name(&s->vdev); switch (vfl_type) { - case VFL_TYPE_GRABBER: + case VFL_TYPE_VIDEO: IVTV_INFO("Registered device %s for %s (%d kB)\n", name, s->name, itv->options.kilobytes[type]); break; --- linux-oracle-5.4.0.orig/drivers/media/pci/meye/meye.c +++ linux-oracle-5.4.0/drivers/media/pci/meye/meye.c @@ -1711,7 +1711,7 @@ v4l2_ctrl_handler_setup(&meye.hdl); meye.vdev.ctrl_handler = &meye.hdl; - if (video_register_device(&meye.vdev, VFL_TYPE_GRABBER, + if (video_register_device(&meye.vdev, VFL_TYPE_VIDEO, video_nr) < 0) { v4l2_err(v4l2_dev, "video_register_device failed\n"); goto outvideoreg; --- linux-oracle-5.4.0.orig/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ linux-oracle-5.4.0/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -258,19 +258,24 @@ if ((reg40 & AVL_IRQ_ASSERTED) != 0) { /* IRQ is being signaled */ reg_isr = readw(ndev->bmmio0 + REG_ISR); - if (reg_isr & NETUP_UNIDVB_IRQ_I2C0) { - iret = netup_i2c_interrupt(&ndev->i2c[0]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_I2C1) { - iret = netup_i2c_interrupt(&ndev->i2c[1]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_SPI) { + if (reg_isr & NETUP_UNIDVB_IRQ_SPI) iret = netup_spi_interrupt(ndev->spi); - } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA1) { - iret = netup_dma_interrupt(&ndev->dma[0]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA2) { - iret = netup_dma_interrupt(&ndev->dma[1]); - } else if (reg_isr & NETUP_UNIDVB_IRQ_CI) { - iret = netup_ci_interrupt(ndev); + else if (!ndev->old_fw) { + if (reg_isr & NETUP_UNIDVB_IRQ_I2C0) { + iret = netup_i2c_interrupt(&ndev->i2c[0]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_I2C1) { + iret = netup_i2c_interrupt(&ndev->i2c[1]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA1) { + iret = netup_dma_interrupt(&ndev->dma[0]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_DMA2) { + iret = netup_dma_interrupt(&ndev->dma[1]); + } else if (reg_isr & NETUP_UNIDVB_IRQ_CI) { + iret = netup_ci_interrupt(ndev); + } else { + goto err; + } } else { +err: dev_err(&pci_dev->dev, "%s(): unknown interrupt 0x%x\n", __func__, reg_isr); @@ -692,7 +697,7 @@ netup_unidvb_dma_enable(dma, 0); msleep(50); cancel_work_sync(&dma->work); - del_timer(&dma->timeout); + del_timer_sync(&dma->timeout); } static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev) @@ -882,12 +887,7 @@ ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0), ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1), pci_dev->irq); - if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED, - "netup_unidvb", pci_dev) < 0) { - dev_err(&pci_dev->dev, - "%s(): can't get IRQ %d\n", __func__, pci_dev->irq); - goto irq_request_err; - } + ndev->dma_size = 2 * 188 * NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT; ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev, @@ -928,6 +928,14 @@ dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n"); goto dma_setup_err; } + + if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED, + "netup_unidvb", pci_dev) < 0) { + dev_err(&pci_dev->dev, + "%s(): can't get IRQ %d\n", __func__, pci_dev->irq); + goto dma_setup_err; + } + dev_info(&pci_dev->dev, "netup_unidvb: device has been initialized\n"); return 0; @@ -946,8 +954,6 @@ dma_free_coherent(&pci_dev->dev, ndev->dma_size, ndev->dma_virt, ndev->dma_phys); dma_alloc_err: - free_irq(pci_dev->irq, pci_dev); -irq_request_err: iounmap(ndev->lmmio1); pci_bar1_error: iounmap(ndev->lmmio0); --- linux-oracle-5.4.0.orig/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c +++ linux-oracle-5.4.0/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c @@ -175,7 +175,7 @@ struct spi_master *master; struct netup_spi *nspi; - master = spi_alloc_master(&ndev->pci_dev->dev, + master = devm_spi_alloc_master(&ndev->pci_dev->dev, sizeof(struct netup_spi)); if (!master) { dev_err(&ndev->pci_dev->dev, @@ -208,6 +208,7 @@ ndev->pci_slot, ndev->pci_func); if (!spi_new_device(master, &netup_spi_board)) { + spi_unregister_master(master); ndev->spi = NULL; dev_err(&ndev->pci_dev->dev, "%s(): unable to create SPI device\n", __func__); @@ -226,13 +227,13 @@ if (!spi) return; + spi_unregister_master(spi->master); spin_lock_irqsave(&spi->lock, flags); reg = readw(&spi->regs->control_stat); writew(reg | NETUP_SPI_CTRL_IRQ, &spi->regs->control_stat); reg = readw(&spi->regs->control_stat); writew(reg & ~NETUP_SPI_CTRL_IMASK, &spi->regs->control_stat); spin_unlock_irqrestore(&spi->lock, flags); - spi_unregister_master(spi->master); ndev->spi = NULL; } --- linux-oracle-5.4.0.orig/drivers/media/pci/ngene/ngene-core.c +++ linux-oracle-5.4.0/drivers/media/pci/ngene/ngene-core.c @@ -385,7 +385,7 @@ com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; com.cmd.hdr.Length = 6; - memcpy(&com.cmd.ConfigureBuffers.config, config, 6); + memcpy(&com.cmd.ConfigureFreeBuffers.config, config, 6); com.in_len = 6; com.out_len = 0; @@ -1488,7 +1488,9 @@ } if (dev->ci.en && (io & NGENE_IO_TSOUT)) { - dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); + ret = dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); + if (ret != 0) + goto err; set_transfer(chan, 1); chan->dev->channel[2].DataFormatFlags = DF_SWAP32; set_transfer(&chan->dev->channel[2], 1); --- linux-oracle-5.4.0.orig/drivers/media/pci/ngene/ngene.h +++ linux-oracle-5.4.0/drivers/media/pci/ngene/ngene.h @@ -407,12 +407,14 @@ struct FW_CONFIGURE_FREE_BUFFERS { struct FW_HEADER hdr; - u8 UVI1_BufferLength; - u8 UVI2_BufferLength; - u8 TVO_BufferLength; - u8 AUD1_BufferLength; - u8 AUD2_BufferLength; - u8 TVA_BufferLength; + struct { + u8 UVI1_BufferLength; + u8 UVI2_BufferLength; + u8 TVO_BufferLength; + u8 AUD1_BufferLength; + u8 AUD2_BufferLength; + u8 TVA_BufferLength; + } __packed config; } __attribute__ ((__packed__)); struct FW_CONFIGURE_UART { --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-core.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-core.c @@ -1214,7 +1214,7 @@ if (saa7134_no_overlay <= 0) dev->video_dev->device_caps |= V4L2_CAP_VIDEO_OVERLAY; - err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, + err = video_register_device(dev->video_dev,VFL_TYPE_VIDEO, video_nr[dev->nr]); if (err < 0) { pr_info("%s: can't register video device\n", --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-dvb.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-dvb.c @@ -466,7 +466,9 @@ /* switch the board to analog mode */ if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(&dev->i2c_adap, &analog_msg, 1); + if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1) + return -EIO; + return 0; } @@ -1018,7 +1020,9 @@ else wbuf[1] = rbuf & 0xef; msg[0].len = 2; - i2c_transfer(&dev->i2c_adap, msg, 1); + if (i2c_transfer(&dev->i2c_adap, msg, 1) != 1) + return -EIO; + return 0; } --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-empress.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-empress.c @@ -282,8 +282,11 @@ q->lock = &dev->lock; q->dev = &dev->pci->dev; err = vb2_queue_init(q); - if (err) + if (err) { + video_device_release(dev->empress_dev); + dev->empress_dev = NULL; return err; + } dev->empress_dev->queue = q; dev->empress_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; @@ -291,7 +294,7 @@ dev->empress_dev->device_caps |= V4L2_CAP_TUNER; video_set_drvdata(dev->empress_dev, dev); - err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, + err = video_register_device(dev->empress_dev,VFL_TYPE_VIDEO, empress_nr[dev->nr]); if (err < 0) { pr_info("%s: can't register video device\n", --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-ts.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-ts.c @@ -300,6 +300,7 @@ int saa7134_ts_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->ts_q.timeout); saa7134_pgtable_free(dev->pci, &dev->ts_q.pt); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-tvaudio.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-tvaudio.c @@ -683,7 +683,8 @@ { int err; - audio_dbg(2, "dsp write reg 0x%x = 0x%06x\n", reg << 2, value); + audio_dbg(2, "dsp write reg 0x%x = 0x%06x\n", + (reg << 2) & 0xffffffff, value); err = saa_dsp_wait_bit(dev,SAA7135_DSP_RWSTATE_WRR); if (err < 0) return err; --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-vbi.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-vbi.c @@ -185,6 +185,7 @@ int saa7134_vbi_fini(struct saa7134_dev *dev) { /* nothing */ + del_timer_sync(&dev->vbi_q.timeout); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7134/saa7134-video.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7134/saa7134-video.c @@ -1179,7 +1179,7 @@ saa_call_all(dev, tuner, standby); if (vdev->vfl_type == VFL_TYPE_RADIO) - saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd); mutex_unlock(&dev->lock); return 0; @@ -1198,7 +1198,7 @@ cmd.result = -ENODEV; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd); mutex_unlock(&dev->lock); return cmd.result; @@ -1214,7 +1214,7 @@ cmd.event_list = wait; cmd.poll_mask = 0; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd); mutex_unlock(&dev->lock); return rc | cmd.poll_mask; @@ -2154,6 +2154,7 @@ void saa7134_video_fini(struct saa7134_dev *dev) { + del_timer_sync(&dev->video_q.timeout); /* free stuff */ vb2_queue_release(&dev->video_vbq); saa7134_pgtable_free(dev->pci, &dev->video_q.pt); --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7146/hexium_gemini.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7146/hexium_gemini.c @@ -284,12 +284,17 @@ hexium_set_input(hexium, 0); hexium->cur_input = 0; - saa7146_vv_init(dev, &vv_data); + ret = saa7146_vv_init(dev, &vv_data); + if (ret) { + i2c_del_adapter(&hexium->i2c_adapter); + kfree(hexium); + return ret; + } vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; vv_data.vid_ops.vidioc_g_input = vidioc_g_input; vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER); + ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_VIDEO); if (ret < 0) { pr_err("cannot register capture v4l2 device. skipping.\n"); saa7146_vv_release(dev); --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7146/hexium_orion.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7146/hexium_orion.c @@ -355,14 +355,20 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) { struct hexium *hexium = (struct hexium *) dev->ext_priv; + int ret; DEB_EE("\n"); - saa7146_vv_init(dev, &vv_data); + ret = saa7146_vv_init(dev, &vv_data); + if (ret) { + pr_err("Error in saa7146_vv_init()\n"); + return ret; + } + vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; vv_data.vid_ops.vidioc_g_input = vidioc_g_input; vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) { + if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_VIDEO)) { pr_err("cannot register capture v4l2 device. skipping.\n"); return -1; } --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7146/mxb.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7146/mxb.c @@ -641,16 +641,17 @@ struct mxb *mxb = (struct mxb *)dev->ext_priv; DEB_D("VIDIOC_S_AUDIO %d\n", a->index); - if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) { - if (mxb->cur_audinput != a->index) { - mxb->cur_audinput = a->index; - tea6420_route(mxb, a->index); - if (mxb->cur_audinput == 0) - mxb_update_audmode(mxb); - } - return 0; + if (a->index >= 32 || + !(mxb_inputs[mxb->cur_input].audioset & (1 << a->index))) + return -EINVAL; + + if (mxb->cur_audinput != a->index) { + mxb->cur_audinput = a->index; + tea6420_route(mxb, a->index); + if (mxb->cur_audinput == 0) + mxb_update_audmode(mxb); } - return -EINVAL; + return 0; } #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -682,10 +683,16 @@ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) { struct mxb *mxb; + int ret; DEB_EE("dev:%p\n", dev); - saa7146_vv_init(dev, &vv_data); + ret = saa7146_vv_init(dev, &vv_data); + if (ret) { + ERR("Error in saa7146_vv_init()"); + return ret; + } + if (mxb_probe(dev)) { saa7146_vv_release(dev); return -1; @@ -707,7 +714,7 @@ vv_data.vid_ops.vidioc_g_register = vidioc_g_register; vv_data.vid_ops.vidioc_s_register = vidioc_s_register; #endif - if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { + if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_VIDEO)) { ERR("cannot register capture v4l2 device. skipping.\n"); saa7146_vv_release(dev); return -1; --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7164/saa7164-core.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7164/saa7164-core.c @@ -1227,7 +1227,7 @@ if (saa7164_dev_setup(dev) < 0) { err = -EINVAL; - goto fail_free; + goto fail_dev; } /* print pci info */ @@ -1395,6 +1395,8 @@ fail_irq: saa7164_dev_unregister(dev); +fail_dev: + pci_disable_device(pci_dev); fail_free: v4l2_device_unregister(&dev->v4l2_dev); kfree(dev); --- linux-oracle-5.4.0.orig/drivers/media/pci/saa7164/saa7164-encoder.c +++ linux-oracle-5.4.0/drivers/media/pci/saa7164/saa7164-encoder.c @@ -1008,7 +1008,7 @@ printk(KERN_ERR "%s() failed (errno = %d), NO PCI configuration\n", __func__, result); result = -ENOMEM; - goto failed; + goto fail_pci; } /* Establish encoder defaults here */ @@ -1062,7 +1062,7 @@ 100000, ENCODER_DEF_BITRATE); if (hdl->error) { result = hdl->error; - goto failed; + goto fail_hdl; } port->std = V4L2_STD_NTSC_M; @@ -1080,21 +1080,18 @@ printk(KERN_INFO "%s: can't allocate mpeg device\n", dev->name); result = -ENOMEM; - goto failed; + goto fail_hdl; } port->v4l_device->ctrl_handler = hdl; v4l2_ctrl_handler_setup(hdl); video_set_drvdata(port->v4l_device, port); result = video_register_device(port->v4l_device, - VFL_TYPE_GRABBER, -1); + VFL_TYPE_VIDEO, -1); if (result < 0) { printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); - /* TODO: We're going to leak here if we don't dealloc - The buffers above. The unreg function can't deal wit it. - */ - goto failed; + goto fail_reg; } printk(KERN_INFO "%s: registered device video%d [mpeg]\n", @@ -1116,9 +1113,14 @@ saa7164_api_set_encoder(port); saa7164_api_get_encoder(port); + return 0; - result = 0; -failed: +fail_reg: + video_device_release(port->v4l_device); + port->v4l_device = NULL; +fail_hdl: + v4l2_ctrl_handler_free(hdl); +fail_pci: return result; } --- linux-oracle-5.4.0.orig/drivers/media/pci/smipcie/smipcie-ir.c +++ linux-oracle-5.4.0/drivers/media/pci/smipcie/smipcie-ir.c @@ -60,39 +60,45 @@ { struct smi_dev *dev = ir->dev; struct rc_dev *rc_dev = ir->rc_dev; - u32 dwIRControl, dwIRData; - u8 index, ucIRCount, readLoop; + u32 control, data; + u8 index, ir_count, read_loop; - dwIRControl = smi_read(IR_Init_Reg); + control = smi_read(IR_Init_Reg); - if (dwIRControl & rbIRVld) { - ucIRCount = (u8) smi_read(IR_Data_Cnt); + dev_dbg(&rc_dev->dev, "ircontrol: 0x%08x\n", control); - readLoop = ucIRCount/4; - if (ucIRCount % 4) - readLoop += 1; - for (index = 0; index < readLoop; index++) { - dwIRData = smi_read(IR_DATA_BUFFER_BASE + (index * 4)); - - ir->irData[index*4 + 0] = (u8)(dwIRData); - ir->irData[index*4 + 1] = (u8)(dwIRData >> 8); - ir->irData[index*4 + 2] = (u8)(dwIRData >> 16); - ir->irData[index*4 + 3] = (u8)(dwIRData >> 24); + if (control & rbIRVld) { + ir_count = (u8)smi_read(IR_Data_Cnt); + + dev_dbg(&rc_dev->dev, "ircount %d\n", ir_count); + + read_loop = ir_count / 4; + if (ir_count % 4) + read_loop += 1; + for (index = 0; index < read_loop; index++) { + data = smi_read(IR_DATA_BUFFER_BASE + (index * 4)); + dev_dbg(&rc_dev->dev, "IRData 0x%08x\n", data); + + ir->irData[index * 4 + 0] = (u8)(data); + ir->irData[index * 4 + 1] = (u8)(data >> 8); + ir->irData[index * 4 + 2] = (u8)(data >> 16); + ir->irData[index * 4 + 3] = (u8)(data >> 24); } - smi_raw_process(rc_dev, ir->irData, ucIRCount); - smi_set(IR_Init_Reg, rbIRVld); + smi_raw_process(rc_dev, ir->irData, ir_count); } - if (dwIRControl & rbIRhighidle) { + if (control & rbIRhighidle) { struct ir_raw_event rawir = {}; + dev_dbg(&rc_dev->dev, "high idle\n"); + rawir.pulse = 0; rawir.duration = US_TO_NS(SMI_SAMPLE_PERIOD * SMI_SAMPLE_IDLEMIN); ir_raw_event_store_with_filter(rc_dev, &rawir); - smi_set(IR_Init_Reg, rbIRhighidle); } + smi_set(IR_Init_Reg, rbIRVld); ir_raw_event_handle(rc_dev); } @@ -151,7 +157,7 @@ rc_dev->dev.parent = &dev->pci_dev->dev; rc_dev->map_name = dev->info->rc_map; - rc_dev->timeout = MS_TO_NS(100); + rc_dev->timeout = US_TO_NS(SMI_SAMPLE_PERIOD * SMI_SAMPLE_IDLEMIN); rc_dev->rx_resolution = US_TO_NS(SMI_SAMPLE_PERIOD); ir->rc_dev = rc_dev; @@ -174,7 +180,7 @@ struct smi_rc *ir = &dev->ir; struct rc_dev *rc_dev = ir->rc_dev; - smi_ir_stop(ir); rc_unregister_device(rc_dev); + smi_ir_stop(ir); ir->rc_dev = NULL; } --- linux-oracle-5.4.0.orig/drivers/media/pci/solo6x10/solo6x10-core.c +++ linux-oracle-5.4.0/drivers/media/pci/solo6x10/solo6x10-core.c @@ -420,6 +420,7 @@ solo_dev->nr_chans); if (device_register(dev)) { + put_device(dev); dev->parent = NULL; return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/media/pci/solo6x10/solo6x10-g723.c +++ linux-oracle-5.4.0/drivers/media/pci/solo6x10/solo6x10-g723.c @@ -399,7 +399,7 @@ ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); if (ret < 0) - return ret; + goto snd_error; ret = solo_snd_pcm_init(solo_dev); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/media/pci/solo6x10/solo6x10-offsets.h +++ linux-oracle-5.4.0/drivers/media/pci/solo6x10/solo6x10-offsets.h @@ -57,16 +57,16 @@ #define SOLO_MP4E_EXT_ADDR(__solo) \ (SOLO_EREF_EXT_ADDR(__solo) + SOLO_EREF_EXT_AREA(__solo)) #define SOLO_MP4E_EXT_SIZE(__solo) \ - max((__solo->nr_chans * 0x00080000), \ - min(((__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo)) - \ - __SOLO_JPEG_MIN_SIZE(__solo)), 0x00ff0000)) + clamp(__solo->sdram_size - SOLO_MP4E_EXT_ADDR(__solo) - \ + __SOLO_JPEG_MIN_SIZE(__solo), \ + __solo->nr_chans * 0x00080000, 0x00ff0000) #define __SOLO_JPEG_MIN_SIZE(__solo) (__solo->nr_chans * 0x00080000) #define SOLO_JPEG_EXT_ADDR(__solo) \ (SOLO_MP4E_EXT_ADDR(__solo) + SOLO_MP4E_EXT_SIZE(__solo)) #define SOLO_JPEG_EXT_SIZE(__solo) \ - max(__SOLO_JPEG_MIN_SIZE(__solo), \ - min((__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo)), 0x00ff0000)) + clamp(__solo->sdram_size - SOLO_JPEG_EXT_ADDR(__solo), \ + __SOLO_JPEG_MIN_SIZE(__solo), 0x00ff0000) #define SOLO_SDRAM_END(__solo) \ (SOLO_JPEG_EXT_ADDR(__solo) + SOLO_JPEG_EXT_SIZE(__solo)) --- linux-oracle-5.4.0.orig/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ linux-oracle-5.4.0/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -1304,7 +1304,7 @@ solo_enc->vfd->queue = &solo_enc->vidq; solo_enc->vfd->lock = &solo_enc->lock; video_set_drvdata(solo_enc->vfd, solo_enc); - ret = video_register_device(solo_enc->vfd, VFL_TYPE_GRABBER, nr); + ret = video_register_device(solo_enc->vfd, VFL_TYPE_VIDEO, nr); if (ret < 0) goto vdev_release; --- linux-oracle-5.4.0.orig/drivers/media/pci/solo6x10/solo6x10-v4l2.c +++ linux-oracle-5.4.0/drivers/media/pci/solo6x10/solo6x10-v4l2.c @@ -692,7 +692,7 @@ while (erase_off(solo_dev)) /* Do nothing */; - ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); + ret = video_register_device(solo_dev->vfd, VFL_TYPE_VIDEO, nr); if (ret < 0) goto fail; --- linux-oracle-5.4.0.orig/drivers/media/pci/sta2x11/Kconfig +++ linux-oracle-5.4.0/drivers/media/pci/sta2x11/Kconfig @@ -2,6 +2,7 @@ config STA2X11_VIP tristate "STA2X11 VIP Video For Linux" depends on STA2X11 || COMPILE_TEST + select GPIOLIB if MEDIA_SUBDRV_AUTOSELECT select VIDEO_ADV7180 if MEDIA_SUBDRV_AUTOSELECT select VIDEOBUF2_DMA_CONTIG depends on PCI && VIDEO_V4L2 && VIRT_TO_BUS --- linux-oracle-5.4.0.orig/drivers/media/pci/sta2x11/sta2x11_vip.c +++ linux-oracle-5.4.0/drivers/media/pci/sta2x11/sta2x11_vip.c @@ -760,7 +760,7 @@ /** * vip_irq - interrupt routine * @irq: Number of interrupt ( not used, correct number is assumed ) - * @vip: local data structure containing all information + * @data: local data structure containing all information * * check for both frame interrupts set ( top and bottom ). * check FIFO overflow, but limit number of log messages after open. @@ -770,8 +770,9 @@ * * IRQ_HANDLED, interrupt done. */ -static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip) +static irqreturn_t vip_irq(int irq, void *data) { + struct sta2x11_vip *vip = data; unsigned int status; status = reg_read(vip, DVP_ITS); @@ -1053,9 +1054,7 @@ spin_lock_init(&vip->slock); - ret = request_irq(pdev->irq, - (irq_handler_t) vip_irq, - IRQF_SHARED, KBUILD_MODNAME, vip); + ret = request_irq(pdev->irq, vip_irq, IRQF_SHARED, KBUILD_MODNAME, vip); if (ret) { dev_err(&pdev->dev, "request_irq failed\n"); ret = -ENODEV; @@ -1069,7 +1068,7 @@ vip->video_dev.lock = &vip->v4l_lock; video_set_drvdata(&vip->video_dev, vip); - ret = video_register_device(&vip->video_dev, VFL_TYPE_GRABBER, -1); + ret = video_register_device(&vip->video_dev, VFL_TYPE_VIDEO, -1); if (ret) goto vrelease; --- linux-oracle-5.4.0.orig/drivers/media/pci/ttpci/av7110.c +++ linux-oracle-5.4.0/drivers/media/pci/ttpci/av7110.c @@ -406,14 +406,15 @@ case DATA_CI_GET: { u8 *data = av7110->debi_virt; + u8 data_0 = data[0]; - if ((data[0] < 2) && data[2] == 0xff) { + if (data_0 < 2 && data[2] == 0xff) { int flags = 0; if (data[5] > 0) flags |= CA_CI_MODULE_PRESENT; if (data[5] > 5) flags |= CA_CI_MODULE_READY; - av7110->ci_slot[data[0]].flags = flags; + av7110->ci_slot[data_0].flags = flags; } else ci_get_data(&av7110->ci_rbuffer, av7110->debi_virt, --- linux-oracle-5.4.0.orig/drivers/media/pci/ttpci/av7110_av.c +++ linux-oracle-5.4.0/drivers/media/pci/ttpci/av7110_av.c @@ -822,10 +822,10 @@ av7110_ipack_flush(ipack); if (buf[3] & ADAPT_FIELD) { + if (buf[4] > len - 1 - 4) + return 0; len -= buf[4] + 1; buf += buf[4] + 1; - if (!len) - return 0; } av7110_ipack_instant_repack(buf + 4, len - 4, ipack); --- linux-oracle-5.4.0.orig/drivers/media/pci/ttpci/av7110_v4l.c +++ linux-oracle-5.4.0/drivers/media/pci/ttpci/av7110_v4l.c @@ -831,7 +831,7 @@ if (FW_VERSION(av7110->arm_app) < 0x2623) vv_data->capabilities &= ~V4L2_CAP_SLICED_VBI_OUTPUT; - if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { + if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_VIDEO)) { ERR("cannot register capture device. skipping\n"); saa7146_vv_release(dev); return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/media/pci/ttpci/budget-av.c +++ linux-oracle-5.4.0/drivers/media/pci/ttpci/budget-av.c @@ -1462,7 +1462,8 @@ budget_av->has_saa7113 = 1; err = saa7146_vv_init(dev, &vv_data); if (err != 0) { - /* fixme: proper cleanup here */ + ttpci_budget_deinit(&budget_av->budget); + kfree(budget_av); ERR("cannot init vv subsystem\n"); return err; } @@ -1470,10 +1471,11 @@ vv_data.vid_ops.vidioc_g_input = vidioc_g_input; vv_data.vid_ops.vidioc_s_input = vidioc_s_input; - if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { - /* fixme: proper cleanup here */ - ERR("cannot register capture v4l2 device\n"); + if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) { saa7146_vv_release(dev); + ttpci_budget_deinit(&budget_av->budget); + kfree(budget_av); + ERR("cannot register capture v4l2 device\n"); return err; } --- linux-oracle-5.4.0.orig/drivers/media/pci/ttpci/budget-core.c +++ linux-oracle-5.4.0/drivers/media/pci/ttpci/budget-core.c @@ -369,20 +369,25 @@ ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend); if (ret < 0) - return ret; + goto err_release_dmx; budget->mem_frontend.source = DMX_MEMORY_FE; ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend); if (ret < 0) - return ret; + goto err_release_dmx; ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend); if (ret < 0) - return ret; + goto err_release_dmx; dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); return 0; + +err_release_dmx: + dvb_dmxdev_release(&budget->dmxdev); + dvb_dmx_release(&budget->demux); + return ret; } static void budget_unregister(struct budget *budget) --- linux-oracle-5.4.0.orig/drivers/media/pci/tw5864/tw5864-video.c +++ linux-oracle-5.4.0/drivers/media/pci/tw5864/tw5864-video.c @@ -767,6 +767,9 @@ fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; ret = tw5864_frameinterval_get(input, &frameinterval); + if (ret) + return ret; + fintv->stepwise.step = frameinterval; fintv->stepwise.min = frameinterval; fintv->stepwise.max = frameinterval; @@ -785,6 +788,9 @@ cp->capability = V4L2_CAP_TIMEPERFRAME; ret = tw5864_frameinterval_get(input, &cp->timeperframe); + if (ret) + return ret; + cp->timeperframe.numerator *= input->frame_interval; cp->capturemode = 0; cp->readbuffers = 2; @@ -1156,7 +1162,7 @@ input->gop = GOP_SIZE; input->frame_interval = 1; - ret = video_register_device(&input->vdev, VFL_TYPE_GRABBER, video_nr); + ret = video_register_device(&input->vdev, VFL_TYPE_VIDEO, video_nr); if (ret) goto free_v4l2_hdl; --- linux-oracle-5.4.0.orig/drivers/media/pci/tw68/tw68-video.c +++ linux-oracle-5.4.0/drivers/media/pci/tw68/tw68-video.c @@ -962,7 +962,7 @@ dev->vdev.lock = &dev->lock; dev->vdev.queue = &dev->vidq; video_set_drvdata(&dev->vdev, dev); - return video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr); + return video_register_device(&dev->vdev, VFL_TYPE_VIDEO, video_nr); } /* --- linux-oracle-5.4.0.orig/drivers/media/pci/tw686x/tw686x-core.c +++ linux-oracle-5.4.0/drivers/media/pci/tw686x/tw686x-core.c @@ -315,13 +315,6 @@ spin_lock_init(&dev->lock); - err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, - dev->name, dev); - if (err < 0) { - dev_err(&pci_dev->dev, "unable to request interrupt\n"); - goto iounmap; - } - timer_setup(&dev->dma_delay_timer, tw686x_dma_delay, 0); /* @@ -333,18 +326,23 @@ err = tw686x_video_init(dev); if (err) { dev_err(&pci_dev->dev, "can't register video\n"); - goto free_irq; + goto iounmap; } err = tw686x_audio_init(dev); if (err) dev_warn(&pci_dev->dev, "can't register audio\n"); + err = request_irq(pci_dev->irq, tw686x_irq, IRQF_SHARED, + dev->name, dev); + if (err < 0) { + dev_err(&pci_dev->dev, "unable to request interrupt\n"); + goto iounmap; + } + pci_set_drvdata(pci_dev, dev); return 0; -free_irq: - free_irq(pci_dev->irq, dev); iounmap: pci_iounmap(pci_dev, dev->mmio); free_region: --- linux-oracle-5.4.0.orig/drivers/media/pci/tw686x/tw686x-video.c +++ linux-oracle-5.4.0/drivers/media/pci/tw686x/tw686x-video.c @@ -1282,7 +1282,7 @@ vc->device = vdev; video_set_drvdata(vdev, vc); - err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); + err = video_register_device(vdev, VFL_TYPE_VIDEO, -1); if (err < 0) goto error; vc->num = vdev->num; --- linux-oracle-5.4.0.orig/drivers/media/platform/am437x/am437x-vpfe.c +++ linux-oracle-5.4.0/drivers/media/platform/am437x/am437x-vpfe.c @@ -1830,6 +1830,10 @@ if (!(sdinfo->inputs[0].capabilities & V4L2_IN_CAP_STD)) return -ENODATA; + /* if trying to set the same std then nothing to do */ + if (vpfe_standards[vpfe->std_index].std_id == std_id) + return 0; + /* If streaming is started, return error */ if (vb2_is_busy(&vpfe->buffer_queue)) { vpfe_err(vpfe, "%s device busy\n", __func__); --- linux-oracle-5.4.0.orig/drivers/media/platform/aspeed-video.c +++ linux-oracle-5.4.0/drivers/media/platform/aspeed-video.c @@ -151,7 +151,7 @@ #define VE_SRC_TB_EDGE_DET_BOT GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF) #define VE_MODE_DETECT_STATUS 0x098 -#define VE_MODE_DETECT_H_PIXELS GENMASK(11, 0) +#define VE_MODE_DETECT_H_PERIOD GENMASK(11, 0) #define VE_MODE_DETECT_V_LINES_SHF 16 #define VE_MODE_DETECT_V_LINES GENMASK(27, VE_MODE_DETECT_V_LINES_SHF) #define VE_MODE_DETECT_STATUS_VSYNC BIT(28) @@ -162,6 +162,8 @@ #define VE_SYNC_STATUS_VSYNC_SHF 16 #define VE_SYNC_STATUS_VSYNC GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF) +#define VE_H_TOTAL_PIXELS 0x0A0 + #define VE_INTERRUPT_CTRL 0x304 #define VE_INTERRUPT_STATUS 0x308 #define VE_INTERRUPT_MODE_DETECT_WD BIT(0) @@ -477,6 +479,10 @@ aspeed_video_update(video, VE_INTERRUPT_CTRL, 0, VE_INTERRUPT_MODE_DETECT); + /* Disable mode detect in order to re-trigger */ + aspeed_video_update(video, VE_SEQ_CTRL, + VE_SEQ_CTRL_TRIG_MODE_DET, 0); + /* Trigger mode detect */ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET); } @@ -491,8 +497,8 @@ aspeed_video_write(video, VE_INTERRUPT_STATUS, 0xffffffff); /* Turn off the relevant clocks */ - clk_disable(video->vclk); clk_disable(video->eclk); + clk_disable(video->vclk); clear_bit(VIDEO_CLOCKS_ON, &video->flags); } @@ -503,8 +509,8 @@ return; /* Turn on the relevant clocks */ - clk_enable(video->eclk); clk_enable(video->vclk); + clk_enable(video->eclk); set_bit(VIDEO_CLOCKS_ON, &video->flags); } @@ -529,6 +535,8 @@ set_bit(VIDEO_RES_CHANGE, &video->flags); clear_bit(VIDEO_FRAME_INPRG, &video->flags); + video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL; + aspeed_video_off(video); aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR); @@ -606,6 +614,16 @@ aspeed_video_start_frame(video); } + /* + * CAPTURE_COMPLETE and FRAME_COMPLETE interrupts come even when these + * are disabled in the VE_INTERRUPT_CTRL register so clear them to + * prevent unnecessary interrupt calls. + */ + if (sts & VE_INTERRUPT_CAPTURE_COMPLETE) + sts &= ~VE_INTERRUPT_CAPTURE_COMPLETE; + if (sts & VE_INTERRUPT_FRAME_COMPLETE) + sts &= ~VE_INTERRUPT_FRAME_COMPLETE; + return sts ? IRQ_NONE : IRQ_HANDLED; } @@ -727,6 +745,7 @@ u32 src_lr_edge; u32 src_tb_edge; u32 sync; + u32 htotal; struct v4l2_bt_timings *det = &video->detected_timings; det->width = MIN_WIDTH; @@ -741,6 +760,8 @@ } set_bit(VIDEO_RES_DETECT, &video->flags); + aspeed_video_update(video, VE_CTRL, + VE_CTRL_VSYNC_POL | VE_CTRL_HSYNC_POL, 0); aspeed_video_enable_mode_detect(video); rc = wait_event_interruptible_timeout(video->wait, @@ -752,10 +773,6 @@ return; } - /* Disable mode detect in order to re-trigger */ - aspeed_video_update(video, VE_SEQ_CTRL, - VE_SEQ_CTRL_TRIG_MODE_DET, 0); - aspeed_video_check_and_set_polarity(video); aspeed_video_enable_mode_detect(video); @@ -773,6 +790,7 @@ src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET); mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS); sync = aspeed_video_read(video, VE_SYNC_STATUS); + htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS); video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >> VE_SRC_TB_EDGE_DET_BOT_SHF; @@ -789,8 +807,7 @@ VE_SRC_LR_EDGE_DET_RT_SHF; video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT; det->hfrontporch = video->frame_left; - det->hbackporch = (mds & VE_MODE_DETECT_H_PIXELS) - - video->frame_right; + det->hbackporch = htotal - video->frame_right; det->hsync = sync & VE_SYNC_STATUS_HSYNC; if (video->frame_left > video->frame_right) continue; @@ -1303,7 +1320,6 @@ struct delayed_work *dwork = to_delayed_work(work); struct aspeed_video *video = container_of(dwork, struct aspeed_video, res_work); - u32 input_status = video->v4l2_input_status; aspeed_video_on(video); @@ -1316,8 +1332,7 @@ aspeed_video_get_resolution(video); if (video->detected_timings.width != video->active_timings.width || - video->detected_timings.height != video->active_timings.height || - input_status != video->v4l2_input_status) { + video->detected_timings.height != video->active_timings.height) { static const struct v4l2_event ev = { .type = V4L2_EVENT_SOURCE_CHANGE, .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, @@ -1517,12 +1532,12 @@ V4L2_JPEG_CHROMA_SUBSAMPLING_420, mask, V4L2_JPEG_CHROMA_SUBSAMPLING_444); - if (video->ctrl_handler.error) { + rc = video->ctrl_handler.error; + if (rc) { v4l2_ctrl_handler_free(&video->ctrl_handler); v4l2_device_unregister(v4l2_dev); - dev_err(video->dev, "Failed to init controls: %d\n", - video->ctrl_handler.error); + dev_err(video->dev, "Failed to init controls: %d\n", rc); return rc; } @@ -1646,7 +1661,8 @@ { int rc; struct resource *res; - struct aspeed_video *video = kzalloc(sizeof(*video), GFP_KERNEL); + struct aspeed_video *video = + devm_kzalloc(&pdev->dev, sizeof(*video), GFP_KERNEL); if (!video) return -ENOMEM; @@ -1671,8 +1687,12 @@ return rc; rc = aspeed_video_setup_video(video); - if (rc) + if (rc) { + aspeed_video_free_buf(video, &video->jpeg); + clk_unprepare(video->vclk); + clk_unprepare(video->eclk); return rc; + } return 0; } @@ -1696,8 +1716,7 @@ v4l2_device_unregister(v4l2_dev); - dma_free_coherent(video->dev, VE_JPEG_HEADER_SIZE, video->jpeg.virt, - video->jpeg.dma); + aspeed_video_free_buf(video, &video->jpeg); of_reserved_mem_device_release(dev); --- linux-oracle-5.4.0.orig/drivers/media/platform/cadence/cdns-csi2rx.c +++ linux-oracle-5.4.0/drivers/media/platform/cadence/cdns-csi2rx.c @@ -129,7 +129,7 @@ */ for (i = csi2rx->num_lanes; i < csi2rx->max_lanes; i++) { unsigned int idx = find_first_zero_bit(&lanes_used, - sizeof(lanes_used)); + csi2rx->max_lanes); set_bit(idx, &lanes_used); reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, i + 1); } --- linux-oracle-5.4.0.orig/drivers/media/platform/coda/coda-bit.c +++ linux-oracle-5.4.0/drivers/media/platform/coda/coda-bit.c @@ -852,7 +852,7 @@ /* Only H.264BP and H.263P3 are considered */ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w64); iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w64); - if (!iram_info->buf_dbk_c_use) + if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use) goto out; iram_info->axi_sram_use |= dbk_bits; @@ -876,7 +876,7 @@ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, w128); iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, w128); - if (!iram_info->buf_dbk_c_use) + if (!iram_info->buf_dbk_y_use || !iram_info->buf_dbk_c_use) goto out; iram_info->axi_sram_use |= dbk_bits; @@ -1082,10 +1082,16 @@ } if (dst_fourcc == V4L2_PIX_FMT_JPEG) { - if (!ctx->params.jpeg_qmat_tab[0]) + if (!ctx->params.jpeg_qmat_tab[0]) { ctx->params.jpeg_qmat_tab[0] = kmalloc(64, GFP_KERNEL); - if (!ctx->params.jpeg_qmat_tab[1]) + if (!ctx->params.jpeg_qmat_tab[0]) + return -ENOMEM; + } + if (!ctx->params.jpeg_qmat_tab[1]) { ctx->params.jpeg_qmat_tab[1] = kmalloc(64, GFP_KERNEL); + if (!ctx->params.jpeg_qmat_tab[1]) + return -ENOMEM; + } coda_set_jpeg_compression_quality(ctx, ctx->params.jpeg_quality); } @@ -2023,17 +2029,25 @@ u32 src_fourcc, dst_fourcc; int ret; + q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); + q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + src_fourcc = q_data_src->fourcc; + dst_fourcc = q_data_dst->fourcc; + if (!ctx->initialized) { ret = __coda_decoder_seq_init(ctx); if (ret < 0) return ret; + } else { + ctx->frame_mem_ctrl &= ~(CODA_FRAME_CHROMA_INTERLEAVE | (0x3 << 9) | + CODA9_FRAME_TILED2LINEAR); + if (dst_fourcc == V4L2_PIX_FMT_NV12 || dst_fourcc == V4L2_PIX_FMT_YUYV) + ctx->frame_mem_ctrl |= CODA_FRAME_CHROMA_INTERLEAVE; + if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP) + ctx->frame_mem_ctrl |= (0x3 << 9) | + ((ctx->use_vdoa) ? 0 : CODA9_FRAME_TILED2LINEAR); } - q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); - q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); - src_fourcc = q_data_src->fourcc; - dst_fourcc = q_data_dst->fourcc; - coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc); --- linux-oracle-5.4.0.orig/drivers/media/platform/coda/coda-common.c +++ linux-oracle-5.4.0/drivers/media/platform/coda/coda-common.c @@ -372,6 +372,7 @@ if (!vdoa_data) vdoa_data = ERR_PTR(-EPROBE_DEFER); + put_device(&vdoa_pdev->dev); out: of_node_put(vdoa_node); @@ -1084,16 +1085,16 @@ switch (dc->cmd) { case V4L2_DEC_CMD_START: - mutex_lock(&ctx->bitstream_mutex); mutex_lock(&dev->coda_mutex); + mutex_lock(&ctx->bitstream_mutex); coda_bitstream_flush(ctx); - mutex_unlock(&dev->coda_mutex); dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); vb2_clear_last_buffer_dequeued(dst_vq); ctx->bit_stream_param &= ~CODA_BIT_STREAM_END_FLAG; coda_fill_bitstream(ctx, NULL); mutex_unlock(&ctx->bitstream_mutex); + mutex_unlock(&dev->coda_mutex); break; case V4L2_DEC_CMD_STOP: stream_end = false; @@ -1191,7 +1192,8 @@ struct v4l2_frmivalenum *f) { struct coda_ctx *ctx = fh_to_ctx(fh); - int i; + struct coda_q_data *q_data; + const struct coda_codec *codec; if (f->index) return -EINVAL; @@ -1200,12 +1202,19 @@ if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV) return -EINVAL; - for (i = 0; i < CODA_MAX_FORMATS; i++) { - if (f->pixel_format == ctx->cvd->src_formats[i] || - f->pixel_format == ctx->cvd->dst_formats[i]) - break; + if (coda_format_normalize_yuv(f->pixel_format) == V4L2_PIX_FMT_YUV420) { + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); + codec = coda_find_codec(ctx->dev, f->pixel_format, + q_data->fourcc); + } else { + codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420, + f->pixel_format); } - if (i == CODA_MAX_FORMATS) + if (!codec) + return -EINVAL; + + if (f->width < MIN_W || f->width > codec->max_w || + f->height < MIN_H || f->height > codec->max_h) return -EINVAL; f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; @@ -2163,8 +2172,8 @@ V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET, -12, 12, 1, 0); v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, 0x0, - V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE, 0x0, + V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE); if (ctx->dev->devtype->product == CODA_HX4 || ctx->dev->devtype->product == CODA_7541) { v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, @@ -2178,12 +2187,15 @@ if (ctx->dev->devtype->product == CODA_960) { v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_LEVEL, - V4L2_MPEG_VIDEO_H264_LEVEL_4_0, - ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | + V4L2_MPEG_VIDEO_H264_LEVEL_4_2, + ~((1 << V4L2_MPEG_VIDEO_H264_LEVEL_1_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_2_0) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_0) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_1) | (1 << V4L2_MPEG_VIDEO_H264_LEVEL_3_2) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0)), + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_0) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | + (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2)), V4L2_MPEG_VIDEO_H264_LEVEL_4_0); } v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, @@ -2245,7 +2257,7 @@ ctx->h264_profile_ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrls, &coda_ctrl_ops, V4L2_CID_MPEG_VIDEO_H264_PROFILE, V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | + ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)), V4L2_MPEG_VIDEO_H264_PROFILE_HIGH); --- linux-oracle-5.4.0.orig/drivers/media/platform/coda/imx-vdoa.c +++ linux-oracle-5.4.0/drivers/media/platform/coda/imx-vdoa.c @@ -287,7 +287,11 @@ struct resource *res; int ret; - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "DMA enable failed\n"); + return ret; + } vdoa = devm_kzalloc(&pdev->dev, sizeof(*vdoa), GFP_KERNEL); if (!vdoa) --- linux-oracle-5.4.0.orig/drivers/media/platform/cros-ec-cec/cros-ec-cec.c +++ linux-oracle-5.4.0/drivers/media/platform/cros-ec-cec/cros-ec-cec.c @@ -45,6 +45,8 @@ uint8_t *cec_message = cros_ec->event_data.data.cec_message; unsigned int len = cros_ec->event_size; + if (len > CEC_MAX_MSG_SIZE) + len = CEC_MAX_MSG_SIZE; cros_ec_cec->rx_msg.len = len; memcpy(cros_ec_cec->rx_msg.msg, cec_message, len); @@ -278,11 +280,7 @@ platform_set_drvdata(pdev, cros_ec_cec); cros_ec_cec->cros_ec = cros_ec; - ret = device_init_wakeup(&pdev->dev, 1); - if (ret) { - dev_err(&pdev->dev, "failed to initialize wakeup\n"); - return ret; - } + device_init_wakeup(&pdev->dev, 1); cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec, DRV_NAME, --- linux-oracle-5.4.0.orig/drivers/media/platform/davinci/vpbe_display.c +++ linux-oracle-5.4.0/drivers/media/platform/davinci/vpbe_display.c @@ -48,7 +48,7 @@ ret = v4l2_subdev_call(vpbe_dev->venc, core, - ioctl, + command, VENC_GET_FLD, &val); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/media/platform/davinci/vpbe_venc.c +++ linux-oracle-5.4.0/drivers/media/platform/davinci/vpbe_venc.c @@ -521,9 +521,7 @@ return ret; } -static long venc_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, - void *arg) +static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { u32 val; @@ -542,7 +540,7 @@ } static const struct v4l2_subdev_core_ops venc_core_ops = { - .ioctl = venc_ioctl, + .command = venc_command, }; static const struct v4l2_subdev_video_ops venc_video_ops = { --- linux-oracle-5.4.0.orig/drivers/media/platform/davinci/vpif.c +++ linux-oracle-5.4.0/drivers/media/platform/davinci/vpif.c @@ -496,6 +496,7 @@ static int vpif_remove(struct platform_device *pdev) { + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/davinci/vpif_capture.c +++ linux-oracle-5.4.0/drivers/media/platform/davinci/vpif_capture.c @@ -1482,8 +1482,6 @@ /* Unregister video device */ video_unregister_device(&ch->video_dev); } - kfree(vpif_obj.sd); - v4l2_device_unregister(&vpif_obj.v4l2_dev); return err; } --- linux-oracle-5.4.0.orig/drivers/media/platform/davinci/vpss.c +++ linux-oracle-5.4.0/drivers/media/platform/davinci/vpss.c @@ -505,19 +505,31 @@ static int __init vpss_init(void) { + int ret; + if (!request_mem_region(VPSS_CLK_CTRL, 4, "vpss_clock_control")) return -EBUSY; oper_cfg.vpss_regs_base2 = ioremap(VPSS_CLK_CTRL, 4); if (unlikely(!oper_cfg.vpss_regs_base2)) { - release_mem_region(VPSS_CLK_CTRL, 4); - return -ENOMEM; + ret = -ENOMEM; + goto err_ioremap; } writel(VPSS_CLK_CTRL_VENCCLKEN | - VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2); + VPSS_CLK_CTRL_DACCLKEN, oper_cfg.vpss_regs_base2); + + ret = platform_driver_register(&vpss_driver); + if (ret) + goto err_pd_register; + + return 0; - return platform_driver_register(&vpss_driver); +err_pd_register: + iounmap(oper_cfg.vpss_regs_base2); +err_ioremap: + release_mem_region(VPSS_CLK_CTRL, 4); + return ret; } subsys_initcall(vpss_init); module_exit(vpss_exit); --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -56,10 +56,8 @@ static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) { struct gsc_ctx *ctx = q->drv_priv; - int ret; - ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(&ctx->gsc_dev->pdev->dev); } static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx) --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-core.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-core.c @@ -1231,7 +1231,7 @@ return platform_driver_register(&fimc_driver); } -void __exit fimc_unregister_driver(void) +void fimc_unregister_driver(void) { platform_driver_unregister(&fimc_driver); } --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-is.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-is.c @@ -141,7 +141,7 @@ dev_err(&is->pdev->dev, "clock %s enable failed\n", fimc_is_clocks[i]); for (--i; i >= 0; i--) - clk_disable(is->clocks[i]); + clk_disable_unprepare(is->clocks[i]); return ret; } pr_debug("enabled clock: %s\n", fimc_is_clocks[i]); @@ -214,6 +214,7 @@ if (ret < 0 || index >= FIMC_IS_SENSORS_NUM) { of_node_put(child); + of_node_put(i2c_bus); return ret; } index++; --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -305,17 +305,20 @@ struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; struct media_device *mdev = entity->graph_obj.mdev; + bool is_singular_file; mutex_lock(&isp->video_lock); - if (v4l2_fh_is_singular_file(file) && ivc->streaming) { + is_singular_file = v4l2_fh_is_singular_file(file); + + if (is_singular_file && ivc->streaming) { media_pipeline_stop(entity); ivc->streaming = 0; } - vb2_fop_release(file); + _vb2_fop_release(file, NULL); - if (v4l2_fh_is_singular_file(file)) { + if (is_singular_file) { fimc_pipeline_call(&ivc->ve, close); mutex_lock(&mdev->graph_mutex); --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-isp-video.h +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-isp-video.h @@ -32,7 +32,7 @@ return 0; } -void fimc_isp_video_device_unregister(struct fimc_isp *isp, +static inline void fimc_isp_video_device_unregister(struct fimc_isp *isp, enum v4l2_buf_type type) { } --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-isp.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-isp.c @@ -305,8 +305,10 @@ if (on) { ret = pm_runtime_get_sync(&is->pdev->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(&is->pdev->dev); return ret; + } set_bit(IS_ST_PWR_ON, &is->state); ret = fimc_is_start_firmware(is); --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/fimc-lite.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/fimc-lite.c @@ -470,7 +470,7 @@ set_bit(ST_FLITE_IN_USE, &fimc->state); ret = pm_runtime_get_sync(&fimc->pdev->dev); if (ret < 0) - goto unlock; + goto err_pm; ret = v4l2_fh_open(file); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/media-dev.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/media-dev.c @@ -484,8 +484,10 @@ return -ENXIO; ret = pm_runtime_get_sync(fmd->pmf); - if (ret < 0) + if (ret < 0) { + pm_runtime_put(fmd->pmf); return ret; + } fmd->num_sensors = 0; @@ -1268,6 +1270,7 @@ if (IS_ERR(pctl->state_default)) return PTR_ERR(pctl->state_default); + /* PINCTRL_STATE_IDLE is optional */ pctl->state_idle = pinctrl_lookup_state(pctl->pinctrl, PINCTRL_STATE_IDLE); return 0; @@ -1457,12 +1460,12 @@ ret = v4l2_device_register(dev, &fmd->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); - return ret; + goto err_md; } ret = fimc_md_get_clocks(fmd); if (ret) - goto err_md; + goto err_v4l2dev; ret = fimc_md_get_pinctrl(fmd); if (ret < 0) { @@ -1519,9 +1522,10 @@ fimc_md_unregister_entities(fmd); err_clk: fimc_md_put_clocks(fmd); +err_v4l2dev: + v4l2_device_unregister(&fmd->v4l2_dev); err_md: media_device_cleanup(&fmd->media_dev); - v4l2_device_unregister(&fmd->v4l2_dev); return ret; } @@ -1577,7 +1581,11 @@ if (ret) return ret; - return platform_driver_register(&fimc_md_driver); + ret = platform_driver_register(&fimc_md_driver); + if (ret) + fimc_unregister_driver(); + + return ret; } static void __exit fimc_md_exit(void) --- linux-oracle-5.4.0.orig/drivers/media/platform/exynos4-is/mipi-csis.c +++ linux-oracle-5.4.0/drivers/media/platform/exynos4-is/mipi-csis.c @@ -510,8 +510,10 @@ if (enable) { s5pcsis_clear_counters(state); ret = pm_runtime_get_sync(&state->pdev->dev); - if (ret && ret != 1) + if (ret && ret != 1) { + pm_runtime_put_noidle(&state->pdev->dev); return ret; + } } mutex_lock(&state->lock); @@ -939,13 +941,19 @@ state->supplies); goto unlock; } - clk_enable(state->clock[CSIS_CLK_GATE]); + ret = clk_enable(state->clock[CSIS_CLK_GATE]); + if (ret) { + phy_power_off(state->phy); + regulator_bulk_disable(CSIS_NUM_SUPPLIES, + state->supplies); + goto unlock; + } } if (state->flags & ST_STREAMING) s5pcsis_start_stream(state); state->flags &= ~ST_SUSPENDED; - unlock: +unlock: mutex_unlock(&state->lock); return ret ? -EAGAIN : 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/imx-pxp.c +++ linux-oracle-5.4.0/drivers/media/platform/imx-pxp.c @@ -1664,6 +1664,8 @@ if (irq < 0) return irq; + spin_lock_init(&dev->irqlock); + ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler, IRQF_ONESHOT, dev_name(&pdev->dev), dev); if (ret < 0) { @@ -1681,8 +1683,6 @@ goto err_clk; } - spin_lock_init(&dev->irqlock); - ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) goto err_clk; --- linux-oracle-5.4.0.orig/drivers/media/platform/marvell-ccic/mcam-core.c +++ linux-oracle-5.4.0/drivers/media/platform/marvell-ccic/mcam-core.c @@ -1940,6 +1940,7 @@ out: v4l2_async_notifier_unregister(&cam->notifier); v4l2_device_unregister(&cam->v4l2_dev); + v4l2_async_notifier_cleanup(&cam->notifier); return ret; } EXPORT_SYMBOL_GPL(mccic_register); @@ -1961,6 +1962,7 @@ v4l2_ctrl_handler_free(&cam->ctrl_handler); v4l2_async_notifier_unregister(&cam->notifier); v4l2_device_unregister(&cam->v4l2_dev); + v4l2_async_notifier_cleanup(&cam->notifier); } EXPORT_SYMBOL_GPL(mccic_shutdown); --- linux-oracle-5.4.0.orig/drivers/media/platform/meson/ao-cec-g12a.c +++ linux-oracle-5.4.0/drivers/media/platform/meson/ao-cec-g12a.c @@ -662,34 +662,27 @@ if (IS_ERR(ao_cec->adap)) return PTR_ERR(ao_cec->adap); - ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, - ao_cec->adap); - if (!ao_cec->notify) { - ret = -ENOMEM; - goto out_probe_adapter; - } - ao_cec->adap->owner = THIS_MODULE; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) { ret = PTR_ERR(base); - goto out_probe_notify; + goto out_probe_adapter; } ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base, &meson_ao_cec_g12a_regmap_conf); if (IS_ERR(ao_cec->regmap)) { ret = PTR_ERR(ao_cec->regmap); - goto out_probe_notify; + goto out_probe_adapter; } ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec, &meson_ao_cec_g12a_cec_regmap_conf); if (IS_ERR(ao_cec->regmap_cec)) { ret = PTR_ERR(ao_cec->regmap_cec); - goto out_probe_notify; + goto out_probe_adapter; } irq = platform_get_irq(pdev, 0); @@ -699,45 +692,52 @@ 0, NULL, ao_cec); if (ret) { dev_err(&pdev->dev, "irq request failed\n"); - goto out_probe_notify; + goto out_probe_adapter; } ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin"); if (IS_ERR(ao_cec->oscin)) { dev_err(&pdev->dev, "oscin clock request failed\n"); ret = PTR_ERR(ao_cec->oscin); - goto out_probe_notify; + goto out_probe_adapter; } ret = meson_ao_cec_g12a_setup_clk(ao_cec); if (ret) - goto out_probe_notify; + goto out_probe_adapter; ret = clk_prepare_enable(ao_cec->core); if (ret) { dev_err(&pdev->dev, "core clock enable failed\n"); - goto out_probe_notify; + goto out_probe_adapter; } device_reset_optional(&pdev->dev); platform_set_drvdata(pdev, ao_cec); + ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, + ao_cec->adap); + if (!ao_cec->notify) { + ret = -ENOMEM; + goto out_probe_core_clk; + } + ret = cec_register_adapter(ao_cec->adap, &pdev->dev); if (ret < 0) - goto out_probe_core_clk; + goto out_probe_notify; /* Setup Hardware */ regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET); return 0; -out_probe_core_clk: - clk_disable_unprepare(ao_cec->core); - out_probe_notify: cec_notifier_cec_adap_unregister(ao_cec->notify); +out_probe_core_clk: + clk_disable_unprepare(ao_cec->core); + out_probe_adapter: cec_delete_adapter(ao_cec->adap); --- linux-oracle-5.4.0.orig/drivers/media/platform/meson/ao-cec.c +++ linux-oracle-5.4.0/drivers/media/platform/meson/ao-cec.c @@ -624,20 +624,13 @@ if (IS_ERR(ao_cec->adap)) return PTR_ERR(ao_cec->adap); - ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, - ao_cec->adap); - if (!ao_cec->notify) { - ret = -ENOMEM; - goto out_probe_adapter; - } - ao_cec->adap->owner = THIS_MODULE; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ao_cec->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ao_cec->base)) { ret = PTR_ERR(ao_cec->base); - goto out_probe_notify; + goto out_probe_adapter; } irq = platform_get_irq(pdev, 0); @@ -647,20 +640,20 @@ 0, NULL, ao_cec); if (ret) { dev_err(&pdev->dev, "irq request failed\n"); - goto out_probe_notify; + goto out_probe_adapter; } ao_cec->core = devm_clk_get(&pdev->dev, "core"); if (IS_ERR(ao_cec->core)) { dev_err(&pdev->dev, "core clock request failed\n"); ret = PTR_ERR(ao_cec->core); - goto out_probe_notify; + goto out_probe_adapter; } ret = clk_prepare_enable(ao_cec->core); if (ret) { dev_err(&pdev->dev, "core clock enable failed\n"); - goto out_probe_notify; + goto out_probe_adapter; } ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE); @@ -674,9 +667,16 @@ ao_cec->pdev = pdev; platform_set_drvdata(pdev, ao_cec); + ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, + ao_cec->adap); + if (!ao_cec->notify) { + ret = -ENOMEM; + goto out_probe_clk; + } + ret = cec_register_adapter(ao_cec->adap, &pdev->dev); if (ret < 0) - goto out_probe_clk; + goto out_probe_notify; /* Setup Hardware */ writel_relaxed(CEC_GEN_CNTL_RESET, @@ -684,12 +684,12 @@ return 0; -out_probe_clk: - clk_disable_unprepare(ao_cec->core); - out_probe_notify: cec_notifier_cec_adap_unregister(ao_cec->notify); +out_probe_clk: + clk_disable_unprepare(ao_cec->core); + out_probe_adapter: cec_delete_adapter(ao_cec->adap); --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c @@ -571,6 +571,13 @@ if (!q_data) return -EINVAL; + if (*num_planes) { + for (i = 0; i < *num_planes; i++) + if (sizes[i] < q_data->sizeimage[i]) + return -EINVAL; + return 0; + } + *num_planes = q_data->fmt->colplanes; for (i = 0; i < q_data->fmt->colplanes; i++) { sizes[i] = q_data->sizeimage[i]; --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h +++ linux-oracle-5.4.0/drivers/media/platform/mtk-mdp/mtk_mdp_ipi.h @@ -40,12 +40,14 @@ * @ipi_id : IPI_MDP * @ap_inst : AP mtk_mdp_vpu address * @vpu_inst_addr : VPU MDP instance address + * @padding : Alignment padding */ struct mdp_ipi_comm { uint32_t msg_id; uint32_t ipi_id; uint64_t ap_inst; uint32_t vpu_inst_addr; + uint32_t padding; }; /** --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -402,12 +402,12 @@ struct mtk_mdp_ctx *ctx = q->drv_priv; int ret; - ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev); + ret = pm_runtime_resume_and_get(&ctx->mdp_dev->pdev->dev); if (ret < 0) - mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d", + mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d", ctx->id, ret); - return 0; + return ret; } static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx, --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -142,7 +142,9 @@ mtk_vcodec_dec_set_default_params(ctx); if (v4l2_fh_is_singular(&ctx->fh)) { - mtk_vcodec_dec_pw_on(&dev->pm); + ret = mtk_vcodec_dec_pw_on(&dev->pm); + if (ret < 0) + goto err_load_fw; /* * vpu_load_firmware checks if it was loaded already and * does nothing in that case --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -48,11 +48,14 @@ dec_clk->clk_info = devm_kcalloc(&pdev->dev, dec_clk->clk_num, sizeof(*clk_info), GFP_KERNEL); - if (!dec_clk->clk_info) - return -ENOMEM; + if (!dec_clk->clk_info) { + ret = -ENOMEM; + goto put_device; + } } else { mtk_v4l2_err("Failed to get vdec clock count"); - return -EINVAL; + ret = -EINVAL; + goto put_device; } for (i = 0; i < dec_clk->clk_num; i++) { @@ -61,34 +64,40 @@ "clock-names", i, &clk_info->clk_name); if (ret) { mtk_v4l2_err("Failed to get clock name id = %d", i); - return ret; + goto put_device; } clk_info->vcodec_clk = devm_clk_get(&pdev->dev, clk_info->clk_name); if (IS_ERR(clk_info->vcodec_clk)) { mtk_v4l2_err("devm_clk_get (%d)%s fail", i, clk_info->clk_name); - return PTR_ERR(clk_info->vcodec_clk); + ret = PTR_ERR(clk_info->vcodec_clk); + goto put_device; } } pm_runtime_enable(&pdev->dev); - + return 0; +put_device: + put_device(pm->larbvdec); return ret; } void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) { pm_runtime_disable(dev->pm.dev); + put_device(dev->pm.larbvdec); } -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) { int ret; - ret = pm_runtime_get_sync(pm->dev); + ret = pm_runtime_resume_and_get(pm->dev); if (ret) - mtk_v4l2_err("pm_runtime_get_sync fail %d", ret); + mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); + + return ret; } void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -12,7 +12,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm); --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c @@ -759,6 +759,8 @@ return -EINVAL; if (*nplanes) { + if (*nplanes != q_data->fmt->num_planes) + return -EINVAL; for (i = 0; i < *nplanes; i++) if (sizes[i] < q_data->sizeimage[i]) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c @@ -209,11 +209,11 @@ mtk_v4l2_debug(1, "[%d] encoder", ctx->id); mutex_lock(&dev->dev_mutex); + v4l2_m2m_ctx_release(ctx->m2m_ctx); mtk_vcodec_enc_release(ctx); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); v4l2_ctrl_handler_free(&ctx->ctrl_hdl); - v4l2_m2m_ctx_release(ctx->m2m_ctx); list_del_init(&ctx->list); kfree(ctx); --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c @@ -49,14 +49,16 @@ node = of_parse_phandle(dev->of_node, "mediatek,larb", 1); if (!node) { mtk_v4l2_err("no mediatek,larb found"); - return -ENODEV; + ret = -ENODEV; + goto put_larbvenc; } pdev = of_find_device_by_node(node); of_node_put(node); if (!pdev) { mtk_v4l2_err("no mediatek,larb device found"); - return -ENODEV; + ret = -ENODEV; + goto put_larbvenc; } pm->larbvenclt = &pdev->dev; @@ -69,11 +71,14 @@ enc_clk->clk_info = devm_kcalloc(&pdev->dev, enc_clk->clk_num, sizeof(*clk_info), GFP_KERNEL); - if (!enc_clk->clk_info) - return -ENOMEM; + if (!enc_clk->clk_info) { + ret = -ENOMEM; + goto put_larbvenclt; + } } else { mtk_v4l2_err("Failed to get venc clock count"); - return -EINVAL; + ret = -EINVAL; + goto put_larbvenclt; } for (i = 0; i < enc_clk->clk_num; i++) { @@ -82,17 +87,24 @@ "clock-names", i, &clk_info->clk_name); if (ret) { mtk_v4l2_err("venc failed to get clk name %d", i); - return ret; + goto put_larbvenclt; } clk_info->vcodec_clk = devm_clk_get(&pdev->dev, clk_info->clk_name); if (IS_ERR(clk_info->vcodec_clk)) { mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i, clk_info->clk_name); - return PTR_ERR(clk_info->vcodec_clk); + ret = PTR_ERR(clk_info->vcodec_clk); + goto put_larbvenclt; } } + return 0; + +put_larbvenclt: + put_device(pm->larbvenclt); +put_larbvenc: + put_device(pm->larbvenc); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c @@ -222,10 +222,11 @@ if (fb->base_y.va == addr) { list_move_tail(&node->list, &inst->available_fb_node_list); - break; + return fb; } } - return fb; + + return NULL; } static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, --- linux-oracle-5.4.0.orig/drivers/media/platform/mtk-vpu/mtk_vpu.c +++ linux-oracle-5.4.0/drivers/media/platform/mtk-vpu/mtk_vpu.c @@ -529,15 +529,17 @@ int vpu_load_firmware(struct platform_device *pdev) { struct mtk_vpu *vpu; - struct device *dev = &pdev->dev; + struct device *dev; struct vpu_run *run; int ret; if (!pdev) { - dev_err(dev, "VPU platform device is invalid\n"); + pr_err("VPU platform device is invalid\n"); return -EINVAL; } + dev = &pdev->dev; + vpu = platform_get_drvdata(pdev); run = &vpu->run; @@ -809,7 +811,8 @@ vpu->wdt.wq = create_singlethread_workqueue("vpu_wdt"); if (!vpu->wdt.wq) { dev_err(dev, "initialize wdt workqueue failed\n"); - return -ENOMEM; + ret = -ENOMEM; + goto clk_unprepare; } INIT_WORK(&vpu->wdt.ws, vpu_wdt_reset_func); mutex_init(&vpu->vpu_mutex); @@ -908,6 +911,8 @@ vpu_clock_disable(vpu); workqueue_destroy: destroy_workqueue(vpu->wdt.wq); +clk_unprepare: + clk_unprepare(vpu->clk); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/mx2_emmaprp.c +++ linux-oracle-5.4.0/drivers/media/platform/mx2_emmaprp.c @@ -852,8 +852,11 @@ platform_set_drvdata(pdev, pcdev); irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + if (irq < 0) { + ret = irq; + goto rel_vdev; + } + ret = devm_request_irq(&pdev->dev, irq, emmaprp_irq, 0, dev_name(&pdev->dev), pcdev); if (ret) --- linux-oracle-5.4.0.orig/drivers/media/platform/omap3isp/isp.c +++ linux-oracle-5.4.0/drivers/media/platform/omap3isp/isp.c @@ -2312,7 +2312,16 @@ /* Regulators */ isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1"); + if (IS_ERR(isp->isp_csiphy1.vdd)) { + ret = PTR_ERR(isp->isp_csiphy1.vdd); + goto error; + } + isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2"); + if (IS_ERR(isp->isp_csiphy2.vdd)) { + ret = PTR_ERR(isp->isp_csiphy2.vdd); + goto error; + } /* Clocks * @@ -2330,8 +2339,10 @@ mem = platform_get_resource(pdev, IORESOURCE_MEM, i); isp->mmio_base[map_idx] = devm_ioremap_resource(isp->dev, mem); - if (IS_ERR(isp->mmio_base[map_idx])) - return PTR_ERR(isp->mmio_base[map_idx]); + if (IS_ERR(isp->mmio_base[map_idx])) { + ret = PTR_ERR(isp->mmio_base[map_idx]); + goto error; + } } ret = isp_get_clocks(isp); --- linux-oracle-5.4.0.orig/drivers/media/platform/omap3isp/isppreview.c +++ linux-oracle-5.4.0/drivers/media/platform/omap3isp/isppreview.c @@ -2287,7 +2287,7 @@ me->ops = &preview_media_ops; ret = media_entity_pads_init(me, PREV_PADS_NUM, pads); if (ret < 0) - return ret; + goto error_handler_free; preview_init_formats(sd, NULL); @@ -2320,6 +2320,8 @@ omap3isp_video_cleanup(&prev->video_in); error_video_in: media_entity_cleanup(&prev->subdev.entity); +error_handler_free: + v4l2_ctrl_handler_free(&prev->ctrls); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/pxa_camera.c +++ linux-oracle-5.4.0/drivers/media/platform/pxa_camera.c @@ -1447,6 +1447,9 @@ struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); int ret = 0; +#ifdef DEBUG + int i; +#endif switch (pcdev->channels) { case 1: --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/camss/camss-csiphy.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -176,8 +176,10 @@ int ret; ret = pm_runtime_get_sync(dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_sync(dev); return ret; + } ret = csiphy_set_clock_rates(csiphy); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/camss/camss-video.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/camss/camss-video.c @@ -438,7 +438,7 @@ ret = media_pipeline_start(&vdev->entity, &video->pipe); if (ret < 0) - return ret; + goto flush_buffers; ret = video_check_format(video); if (ret < 0) @@ -467,6 +467,7 @@ error: media_pipeline_stop(&vdev->entity); +flush_buffers: video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED); return ret; @@ -901,6 +902,7 @@ video->nformats = ARRAY_SIZE(formats_rdi_8x96); } } else { + ret = -EINVAL; goto error_video_register; } --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/camss/camss.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/camss/camss.c @@ -431,8 +431,11 @@ struct v4l2_fwnode_bus_mipi_csi2 *mipi_csi2; struct v4l2_fwnode_endpoint vep = { { 0 } }; unsigned int i; + int ret; - v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep); + if (ret) + return ret; csd->interface.csiphy_id = vep.base.port; @@ -504,7 +507,6 @@ return num_subdevs; err_cleanup: - v4l2_async_notifier_cleanup(&camss->notifier); of_node_put(node); return ret; } @@ -835,29 +837,38 @@ camss->csid_num = 4; camss->vfe_num = 2; } else { - return -EINVAL; + ret = -EINVAL; + goto err_free; } camss->csiphy = devm_kcalloc(dev, camss->csiphy_num, sizeof(*camss->csiphy), GFP_KERNEL); - if (!camss->csiphy) - return -ENOMEM; + if (!camss->csiphy) { + ret = -ENOMEM; + goto err_free; + } camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid), GFP_KERNEL); - if (!camss->csid) - return -ENOMEM; + if (!camss->csid) { + ret = -ENOMEM; + goto err_free; + } camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe), GFP_KERNEL); - if (!camss->vfe) - return -ENOMEM; + if (!camss->vfe) { + ret = -ENOMEM; + goto err_free; + } v4l2_async_notifier_init(&camss->notifier); num_subdevs = camss_of_parse_ports(camss); - if (num_subdevs < 0) - return num_subdevs; + if (num_subdevs < 0) { + ret = num_subdevs; + goto err_cleanup; + } ret = camss_init_subdevices(camss); if (ret < 0) @@ -936,6 +947,8 @@ v4l2_device_unregister(&camss->v4l2_dev); err_cleanup: v4l2_async_notifier_cleanup(&camss->notifier); +err_free: + kfree(camss); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/core.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/core.c @@ -289,11 +289,11 @@ ret = venus_firmware_init(core); if (ret) - goto err_runtime_disable; + goto err_of_depopulate; ret = venus_boot(core); if (ret) - goto err_runtime_disable; + goto err_firmware_deinit; ret = hfi_core_resume(core, true); if (ret) @@ -316,8 +316,10 @@ goto err_core_deinit; ret = pm_runtime_put_sync(dev); - if (ret) + if (ret) { + pm_runtime_get_noresume(dev); goto err_dev_unregister; + } return 0; @@ -327,9 +329,14 @@ hfi_core_deinit(core, false); err_venus_shutdown: venus_shutdown(core); +err_firmware_deinit: + venus_firmware_deinit(core); +err_of_depopulate: + of_platform_depopulate(dev); err_runtime_disable: - pm_runtime_set_suspended(dev); + pm_runtime_put_noidle(dev); pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); hfi_destroy(core); return ret; } @@ -340,6 +347,7 @@ struct device *dev = core->dev; int ret; + cancel_delayed_work_sync(&core->work); ret = pm_runtime_get_sync(dev); WARN_ON(ret < 0); @@ -427,10 +435,11 @@ }; static const struct freq_tbl msm8996_freq_table[] = { - { 1944000, 490000000 }, /* 4k UHD @ 60 */ - { 972000, 320000000 }, /* 4k UHD @ 30 */ - { 489600, 150000000 }, /* 1080p @ 60 */ - { 244800, 75000000 }, /* 1080p @ 30 */ + { 1944000, 520000000 }, /* 4k UHD @ 60 (decode only) */ + { 972000, 520000000 }, /* 4k UHD @ 30 */ + { 489600, 346666667 }, /* 1080p @ 60 */ + { 244800, 150000000 }, /* 1080p @ 30 */ + { 108000, 75000000 }, /* 720p @ 30 */ }; static const struct reg_val msm8996_reg_preset[] = { --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/firmware.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/firmware.c @@ -44,8 +44,14 @@ int venus_set_hw_state(struct venus_core *core, bool resume) { - if (core->use_tz) - return qcom_scm_set_remote_state(resume, 0); + int ret; + + if (core->use_tz) { + ret = qcom_scm_set_remote_state(resume, 0); + if (resume && ret == -EINVAL) + ret = 0; + return ret; + } if (resume) venus_reset_cpu(core); --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/hfi.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/hfi.c @@ -104,6 +104,9 @@ mutex_lock(&core->lock); } + if (!core->ops) + goto unlock; + ret = core->ops->core_deinit(core); if (!ret) --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/hfi_msgs.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/hfi_msgs.c @@ -350,7 +350,7 @@ memcpy(&bufreq[idx], buf_req, sizeof(*bufreq)); idx++; - if (idx > HFI_BUFFER_TYPE_MAX) + if (idx >= HFI_BUFFER_TYPE_MAX) return HFI_ERR_SESSION_INVALID_PARAMETER; req_bytes -= sizeof(struct hfi_buffer_requirements); --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/hfi_parser.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/hfi_parser.c @@ -19,6 +19,9 @@ struct venus_caps *caps = core->caps, *cap; unsigned long bit; + if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM) + return; + for_each_set_bit(bit, &core->dec_codecs, MAX_CODEC_NUM) { cap = &caps[core->codecs_count++]; cap->codec = BIT(bit); @@ -86,6 +89,9 @@ { const struct hfi_profile_level *pl = data; + if (cap->num_pl + num >= HFI_MAX_PROFILE_COUNT) + return; + memcpy(&cap->pl[cap->num_pl], pl, num * sizeof(*pl)); cap->num_pl += num; } @@ -111,6 +117,9 @@ { const struct hfi_capability *caps = data; + if (cap->num_caps + num >= MAX_CAP_ENTRIES) + return; + memcpy(&cap->caps[cap->num_caps], caps, num * sizeof(*caps)); cap->num_caps += num; } @@ -137,6 +146,9 @@ { const struct raw_formats *formats = fmts; + if (cap->num_fmts + num_fmts >= MAX_FMT_ENTRIES) + return; + memcpy(&cap->fmts[cap->num_fmts], formats, num_fmts * sizeof(*formats)); cap->num_fmts += num_fmts; } @@ -159,6 +171,9 @@ rawfmts[i].buftype = fmt->buffer_type; i++; + if (i >= MAX_FMT_ENTRIES) + return; + if (pinfo->num_planes > MAX_PLANES) break; @@ -181,6 +196,7 @@ if (IS_V1(core)) { core->dec_codecs &= ~HFI_VIDEO_CODEC_HEVC; core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK; + core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC; } } --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/hfi_venus.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/hfi_venus.c @@ -206,6 +206,11 @@ new_wr_idx = wr_idx + dwords; wr_ptr = (u32 *)(queue->qmem.kva + (wr_idx << 2)); + + if (wr_ptr < (u32 *)queue->qmem.kva || + wr_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*wr_ptr))) + return -EINVAL; + if (new_wr_idx < qsize) { memcpy(wr_ptr, packet, dwords << 2); } else { @@ -273,6 +278,11 @@ } rd_ptr = (u32 *)(queue->qmem.kva + (rd_idx << 2)); + + if (rd_ptr < (u32 *)queue->qmem.kva || + rd_ptr > (u32 *)(queue->qmem.kva + queue->qmem.size - sizeof(*rd_ptr))) + return -EINVAL; + dwords = *rd_ptr >> 2; if (!dwords) return -EINVAL; @@ -1472,6 +1482,7 @@ { struct venus_hfi_device *hdev = to_hfi_priv(core); struct device *dev = core->dev; + u32 ctrl_status; bool val; int ret; @@ -1487,6 +1498,10 @@ return -EINVAL; } + ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0); + if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY) + goto power_off; + /* * Power collapse sequence for Venus 3xx and 4xx versions: * 1. Check for ARM9 and video core to be idle by checking WFI bit @@ -1511,6 +1526,7 @@ if (ret) return ret; +power_off: mutex_lock(&hdev->lock); ret = venus_power_off(hdev); --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/vdec.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/vdec.c @@ -157,6 +157,8 @@ else return NULL; fmt = find_format(inst, pixmp->pixelformat, f->type); + if (!fmt) + return NULL; } pixmp->width = clamp(pixmp->width, frame_width_min(inst), @@ -987,11 +989,10 @@ ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT); vdec_cancel_dst_buffers(inst); inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; - INIT_LIST_HEAD(&inst->registeredbufs); venus_helper_free_dpb_bufs(inst); break; default: - return 0; + break; } return ret; @@ -1090,6 +1091,14 @@ static void vdec_buf_cleanup(struct vb2_buffer *vb) { struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct venus_buffer *buf = to_venus_buffer(vbuf); + + mutex_lock(&inst->lock); + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + if (!list_empty(&inst->registeredbufs)) + list_del_init(&buf->reg_list); + mutex_unlock(&inst->lock); inst->buf_count--; if (!inst->buf_count) @@ -1391,6 +1400,7 @@ { struct venus_inst *inst = to_inst(file); + cancel_work_sync(&inst->delayed_process_work); v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); vdec_ctrl_deinit(inst); @@ -1412,9 +1422,6 @@ .unlocked_ioctl = video_ioctl2, .poll = v4l2_m2m_fop_poll, .mmap = v4l2_m2m_fop_mmap, -#ifdef CONFIG_COMPAT - .compat_ioctl32 = v4l2_compat_ioctl32, -#endif }; static int vdec_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/media/platform/qcom/venus/venc.c +++ linux-oracle-5.4.0/drivers/media/platform/qcom/venus/venc.c @@ -308,6 +308,8 @@ else return NULL; fmt = find_format(inst, pixmp->pixelformat, f->type); + if (!fmt) + return NULL; } pixmp->width = clamp(pixmp->width, frame_width_min(inst), @@ -1235,9 +1237,6 @@ .unlocked_ioctl = video_ioctl2, .poll = v4l2_m2m_fop_poll, .mmap = v4l2_m2m_fop_mmap, -#ifdef CONFIG_COMPAT - .compat_ioctl32 = v4l2_compat_ioctl32, -#endif }; static int venc_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar-fcp.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar-fcp.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -21,6 +22,7 @@ struct rcar_fcp_device { struct list_head list; struct device *dev; + struct device_dma_parameters dma_parms; }; static LIST_HEAD(fcp_devices); @@ -101,8 +103,10 @@ return 0; ret = pm_runtime_get_sync(fcp->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(fcp->dev); return ret; + } return 0; } @@ -136,6 +140,9 @@ fcp->dev = &pdev->dev; + fcp->dev->dma_parms = &fcp->dma_parms; + dma_set_max_seg_size(fcp->dev, DMA_BIT_MASK(32)); + pm_runtime_enable(&pdev->dev); mutex_lock(&fcp_lock); --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar-vin/rcar-csi2.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar-vin/rcar-csi2.c @@ -361,7 +361,6 @@ struct media_pad pads[NR_OF_RCAR_CSI2_PAD]; struct v4l2_async_notifier notifier; - struct v4l2_async_subdev asd; struct v4l2_subdev *remote; struct v4l2_mbus_framefmt mf; @@ -431,16 +430,23 @@ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps) { const struct rcsi2_mbps_reg *hsfreq; + const struct rcsi2_mbps_reg *hsfreq_prev = NULL; - for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) + for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) { if (hsfreq->mbps >= mbps) break; + hsfreq_prev = hsfreq; + } if (!hsfreq->mbps) { dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps); return -ERANGE; } + if (hsfreq_prev && + ((mbps - hsfreq_prev->mbps) <= (hsfreq->mbps - mbps))) + hsfreq = hsfreq_prev; + rcsi2_write(priv, PHYPLL_REG, PHYPLL_HSFREQRANGE(hsfreq->reg)); return 0; @@ -489,6 +495,8 @@ /* Code is validated in set_fmt. */ format = rcsi2_code_to_fmt(priv->mf.code); + if (!format) + return -EINVAL; /* * Enable all supported CSI-2 channels with virtual channel and @@ -810,6 +818,8 @@ static int rcsi2_parse_dt(struct rcar_csi2 *priv) { + struct v4l2_async_subdev *asd; + struct fwnode_handle *fwnode; struct device_node *ep; struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; int ret; @@ -833,24 +843,19 @@ return ret; } - priv->asd.match.fwnode = - fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep)); - priv->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - + fwnode = fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep)); of_node_put(ep); - v4l2_async_notifier_init(&priv->notifier); - - ret = v4l2_async_notifier_add_subdev(&priv->notifier, &priv->asd); - if (ret) { - fwnode_handle_put(priv->asd.match.fwnode); - return ret; - } + dev_dbg(priv->dev, "Found '%pOF'\n", to_of_node(fwnode)); + v4l2_async_notifier_init(&priv->notifier); priv->notifier.ops = &rcar_csi2_notify_ops; - dev_dbg(priv->dev, "Found '%pOF'\n", - to_of_node(priv->asd.match.fwnode)); + asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, fwnode, + sizeof(*asd)); + fwnode_handle_put(fwnode); + if (IS_ERR(asd)) + return PTR_ERR(asd); ret = v4l2_async_subdev_notifier_register(&priv->subdev, &priv->notifier); @@ -906,10 +911,17 @@ const struct rcsi2_mbps_reg *values, u16 code) { const struct rcsi2_mbps_reg *value; + const struct rcsi2_mbps_reg *prev_value = NULL; - for (value = values; value->mbps; value++) + for (value = values; value->mbps; value++) { if (value->mbps >= mbps) break; + prev_value = value; + } + + if (prev_value && + ((mbps - prev_value->mbps) <= (value->mbps - mbps))) + value = prev_value; if (!value->mbps) { dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps); --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar-vin/rcar-dma.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar-vin/rcar-dma.c @@ -638,6 +638,7 @@ vnmc = VNMC_IM_FULL | VNMC_FOC; break; case V4L2_FIELD_NONE: + case V4L2_FIELD_ALTERNATE: vnmc = VNMC_IM_ODD_EVEN; progressive = true; break; @@ -1334,8 +1335,10 @@ int ret; ret = pm_runtime_get_sync(vin->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(vin->dev); return ret; + } /* Make register writes take effect immediately. */ vnmc = rvin_read(vin, VNMC_REG); --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -208,6 +208,7 @@ ret = v4l2_subdev_call(sd, pad, set_fmt, pad_cfg, &format); if (ret < 0 && ret != -ENOIOCTLCMD) goto done; + ret = 0; v4l2_fill_pix_format(pix, &format.format); @@ -242,7 +243,7 @@ done: v4l2_subdev_free_pad_config(pad_cfg); - return 0; + return ret; } static int rvin_querycap(struct file *file, void *priv, --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar_drif.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar_drif.c @@ -185,7 +185,6 @@ /* OF graph endpoint's V4L2 async data */ struct rcar_drif_graph_ep { struct v4l2_subdev *subdev; /* Async matched subdev */ - struct v4l2_async_subdev asd; /* Async sub-device descriptor */ }; /* DMA buffer */ @@ -1104,12 +1103,6 @@ struct rcar_drif_sdr *sdr = container_of(notifier, struct rcar_drif_sdr, notifier); - if (sdr->ep.asd.match.fwnode != - of_fwnode_handle(subdev->dev->of_node)) { - rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name); - return -EINVAL; - } - v4l2_set_subdev_hostdata(subdev, sdr); sdr->ep.subdev = subdev; rdrif_dbg(sdr, "bound asd %s\n", subdev->name); @@ -1213,7 +1206,7 @@ { struct v4l2_async_notifier *notifier = &sdr->notifier; struct fwnode_handle *fwnode, *ep; - int ret; + struct v4l2_async_subdev *asd; v4l2_async_notifier_init(notifier); @@ -1222,26 +1215,21 @@ if (!ep) return 0; + /* Get the endpoint properties */ + rcar_drif_get_ep_properties(sdr, ep); + fwnode = fwnode_graph_get_remote_port_parent(ep); + fwnode_handle_put(ep); if (!fwnode) { dev_warn(sdr->dev, "bad remote port parent\n"); - fwnode_handle_put(ep); return -EINVAL; } - sdr->ep.asd.match.fwnode = fwnode; - sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; - ret = v4l2_async_notifier_add_subdev(notifier, &sdr->ep.asd); - if (ret) { - fwnode_handle_put(fwnode); - return ret; - } - - /* Get the endpoint properties */ - rcar_drif_get_ep_properties(sdr, ep); - + asd = v4l2_async_notifier_add_fwnode_subdev(notifier, fwnode, + sizeof(*asd)); fwnode_handle_put(fwnode); - fwnode_handle_put(ep); + if (IS_ERR(asd)) + return PTR_ERR(asd); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/rcar_fdp1.c +++ linux-oracle-5.4.0/drivers/media/platform/rcar_fdp1.c @@ -2121,9 +2121,7 @@ if (ctx->hdl.error) { ret = ctx->hdl.error; - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; } ctx->fh.ctrl_handler = &ctx->hdl; @@ -2137,20 +2135,27 @@ if (IS_ERR(ctx->fh.m2m_ctx)) { ret = PTR_ERR(ctx->fh.m2m_ctx); - - v4l2_ctrl_handler_free(&ctx->hdl); - kfree(ctx); - goto done; + goto error_ctx; } /* Perform any power management required */ - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto error_pm; v4l2_fh_add(&ctx->fh); dprintk(fdp1, "Created instance: %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx); + mutex_unlock(&fdp1->dev_mutex); + return 0; + +error_pm: + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); +error_ctx: + v4l2_ctrl_handler_free(&ctx->hdl); + kfree(ctx); done: mutex_unlock(&fdp1->dev_mutex); return ret; @@ -2255,7 +2260,6 @@ struct fdp1_dev *fdp1; struct video_device *vfd; struct device_node *fcp_node; - struct resource *res; struct clk *clk; unsigned int i; @@ -2282,17 +2286,15 @@ platform_set_drvdata(pdev, fdp1); /* Memory-mapped registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - fdp1->regs = devm_ioremap_resource(&pdev->dev, res); + fdp1->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(fdp1->regs)) return PTR_ERR(fdp1->regs); /* Interrupt service routine registration */ - fdp1->irq = ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(&pdev->dev, "cannot find IRQ\n"); + ret = platform_get_irq(pdev, 0); + if (ret < 0) return ret; - } + fdp1->irq = ret; ret = devm_request_irq(&pdev->dev, fdp1->irq, fdp1_irq_handler, 0, dev_name(&pdev->dev), fdp1); @@ -2315,8 +2317,10 @@ /* Determine our clock rate */ clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + goto put_dev; + } fdp1->clk_rate = clk_get_rate(clk); clk_put(clk); @@ -2325,7 +2329,7 @@ ret = v4l2_device_register(&pdev->dev, &fdp1->v4l2_dev); if (ret) { v4l2_err(&fdp1->v4l2_dev, "Failed to register video device\n"); - return ret; + goto put_dev; } /* M2M registration */ @@ -2355,7 +2359,9 @@ /* Power up the cells to read HW */ pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(fdp1->dev); + ret = pm_runtime_resume_and_get(fdp1->dev); + if (ret < 0) + goto disable_pm; hw_version = fdp1_read(fdp1, FD1_IP_INTDATA); switch (hw_version) { @@ -2369,7 +2375,7 @@ dprintk(fdp1, "FDP1 Version R-Car H3\n"); break; case FD1_IP_M3N: - dprintk(fdp1, "FDP1 Version R-Car M3N\n"); + dprintk(fdp1, "FDP1 Version R-Car M3-N\n"); break; case FD1_IP_E3: dprintk(fdp1, "FDP1 Version R-Car E3\n"); @@ -2384,12 +2390,17 @@ return 0; +disable_pm: + pm_runtime_disable(fdp1->dev); + release_m2m: v4l2_m2m_release(fdp1->m2m_dev); unreg_dev: v4l2_device_unregister(&fdp1->v4l2_dev); +put_dev: + rcar_fcp_put(fdp1->fcp); return ret; } @@ -2401,6 +2412,7 @@ video_unregister_device(&fdp1->vfd); v4l2_device_unregister(&fdp1->v4l2_dev); pm_runtime_disable(&pdev->dev); + rcar_fcp_put(fdp1->fcp); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/rockchip/rga/rga-buf.c +++ linux-oracle-5.4.0/drivers/media/platform/rockchip/rga/rga-buf.c @@ -81,6 +81,7 @@ ret = pm_runtime_get_sync(rga->dev); if (ret < 0) { + pm_runtime_put_noidle(rga->dev); rga_buf_return_buffers(q, VB2_BUF_STATE_QUEUED); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/rockchip/rga/rga-hw.c +++ linux-oracle-5.4.0/drivers/media/platform/rockchip/rga/rga-hw.c @@ -200,22 +200,25 @@ dst_info.data.format = ctx->out.fmt->hw_format; dst_info.data.swap = ctx->out.fmt->color_swap; - if (ctx->in.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { - if (ctx->out.fmt->hw_format < RGA_COLOR_FMT_YUV422SP) { - switch (ctx->in.colorspace) { - case V4L2_COLORSPACE_REC709: - src_info.data.csc_mode = - RGA_SRC_CSC_MODE_BT709_R0; - break; - default: - src_info.data.csc_mode = - RGA_SRC_CSC_MODE_BT601_R0; - break; - } + /* + * CSC mode must only be set when the colorspace families differ between + * input and output. It must remain unset (zeroed) if both are the same. + */ + + if (RGA_COLOR_FMT_IS_YUV(ctx->in.fmt->hw_format) && + RGA_COLOR_FMT_IS_RGB(ctx->out.fmt->hw_format)) { + switch (ctx->in.colorspace) { + case V4L2_COLORSPACE_REC709: + src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; + break; + default: + src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT601_R0; + break; } } - if (ctx->out.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { + if (RGA_COLOR_FMT_IS_RGB(ctx->in.fmt->hw_format) && + RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) { switch (ctx->out.colorspace) { case V4L2_COLORSPACE_REC709: dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; --- linux-oracle-5.4.0.orig/drivers/media/platform/rockchip/rga/rga-hw.h +++ linux-oracle-5.4.0/drivers/media/platform/rockchip/rga/rga-hw.h @@ -95,6 +95,11 @@ #define RGA_COLOR_FMT_CP_8BPP 15 #define RGA_COLOR_FMT_MASK 15 +#define RGA_COLOR_FMT_IS_YUV(fmt) \ + (((fmt) >= RGA_COLOR_FMT_YUV422SP) && ((fmt) < RGA_COLOR_FMT_CP_1BPP)) +#define RGA_COLOR_FMT_IS_RGB(fmt) \ + ((fmt) < RGA_COLOR_FMT_YUV422SP) + #define RGA_COLOR_NONE_SWAP 0 #define RGA_COLOR_RB_SWAP 1 #define RGA_COLOR_ALPHA_SWAP 2 --- linux-oracle-5.4.0.orig/drivers/media/platform/rockchip/rga/rga.c +++ linux-oracle-5.4.0/drivers/media/platform/rockchip/rga/rga.c @@ -187,7 +187,7 @@ static struct rga_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_ARGB32, - .color_swap = RGA_COLOR_RB_SWAP, + .color_swap = RGA_COLOR_ALPHA_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -195,17 +195,8 @@ .x_div = 1, }, { - .fourcc = V4L2_PIX_FMT_XRGB32, - .color_swap = RGA_COLOR_RB_SWAP, - .hw_format = RGA_COLOR_FMT_XBGR8888, - .depth = 32, - .uv_factor = 1, - .y_div = 1, - .x_div = 1, - }, - { .fourcc = V4L2_PIX_FMT_ABGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -214,7 +205,7 @@ }, { .fourcc = V4L2_PIX_FMT_XBGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_XBGR8888, .depth = 32, .uv_factor = 1, --- linux-oracle-5.4.0.orig/drivers/media/platform/s3c-camif/camif-capture.c +++ linux-oracle-5.4.0/drivers/media/platform/s3c-camif/camif-capture.c @@ -1132,12 +1132,12 @@ ret = vb2_queue_init(q); if (ret) - goto err_vd_rel; + return ret; vp->pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&vfd->entity, 1, &vp->pad); if (ret) - goto err_vd_rel; + return ret; video_set_drvdata(vfd, vp); @@ -1170,8 +1170,6 @@ v4l2_ctrl_handler_free(&vp->ctrl_handler); err_me_cleanup: media_entity_cleanup(&vfd->entity); -err_vd_rel: - video_device_release(vfd); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/s3c-camif/camif-core.c +++ linux-oracle-5.4.0/drivers/media/platform/s3c-camif/camif-core.c @@ -464,7 +464,7 @@ ret = camif_media_dev_init(camif); if (ret < 0) - goto err_alloc; + goto err_pm; ret = camif_register_sensor(camif); if (ret < 0) @@ -498,10 +498,9 @@ media_device_unregister(&camif->media_dev); media_device_cleanup(&camif->media_dev); camif_unregister_media_entities(camif); -err_alloc: +err_pm: pm_runtime_put(dev); pm_runtime_disable(dev); -err_pm: camif_clk_put(camif); err_clk: s3c_camif_unregister_subdev(camif); @@ -530,10 +529,19 @@ static int s3c_camif_runtime_resume(struct device *dev) { struct camif_dev *camif = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(camif->clock[CLK_GATE]); + if (ret) + return ret; - clk_enable(camif->clock[CLK_GATE]); /* null op on s3c244x */ - clk_enable(camif->clock[CLK_CAM]); + ret = clk_enable(camif->clock[CLK_CAM]); + if (ret) { + clk_disable(camif->clock[CLK_GATE]); + return ret; + } + return 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-cec/s5p_cec.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-cec/s5p_cec.c @@ -35,10 +35,13 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) { + int ret; struct s5p_cec_dev *cec = cec_get_drvdata(adap); if (enable) { - pm_runtime_get_sync(cec->dev); + ret = pm_runtime_resume_and_get(cec->dev); + if (ret < 0) + return ret; s5p_cec_reset(cec); @@ -51,7 +54,7 @@ } else { s5p_cec_mask_tx_interrupts(cec); s5p_cec_mask_rx_interrupts(cec); - pm_runtime_disable(cec->dev); + pm_runtime_put(cec->dev); } return 0; @@ -112,6 +115,8 @@ dev_dbg(cec->dev, "Buffer overrun (worker did not process previous message)\n"); cec->rx = STATE_BUSY; cec->msg.len = status >> 24; + if (cec->msg.len > CEC_MAX_MSG_SIZE) + cec->msg.len = CEC_MAX_MSG_SIZE; cec->msg.rx_status = CEC_RX_STATUS_OK; s5p_cec_get_rx_buf(cec, cec->msg.len, cec->msg.msg); --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-g2d/g2d.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-g2d/g2d.c @@ -276,6 +276,9 @@ struct g2d_dev *dev = video_drvdata(file); struct g2d_ctx *ctx = fh2ctx(file->private_data); + mutex_lock(&dev->mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&dev->mutex); v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -774,11 +774,14 @@ (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2; jpeg_buffer.curr = 0; - word = 0; - if (get_word_be(&jpeg_buffer, &word)) return; - jpeg_buffer.size = (long)word - 2; + + if (word < 2) + jpeg_buffer.size = 0; + else + jpeg_buffer.size = (long)word - 2; + jpeg_buffer.data += 2; jpeg_buffer.curr = 0; @@ -1057,6 +1060,7 @@ if (byte == -1) return -1; *word = (unsigned int)byte | temp; + return 0; } @@ -1144,7 +1148,7 @@ if (get_word_be(&jpeg_buffer, &word)) break; length = (long)word - 2; - if (!length) + if (length <= 0) return false; sof = jpeg_buffer.curr; /* after 0xffc0 */ sof_len = length; @@ -1175,7 +1179,7 @@ if (get_word_be(&jpeg_buffer, &word)) break; length = (long)word - 2; - if (!length) + if (length <= 0) return false; if (n_dqt >= S5P_JPEG_MAX_MARKER) return false; @@ -1188,7 +1192,7 @@ if (get_word_be(&jpeg_buffer, &word)) break; length = (long)word - 2; - if (!length) + if (length <= 0) return false; if (n_dht >= S5P_JPEG_MAX_MARKER) return false; @@ -1213,6 +1217,7 @@ if (get_word_be(&jpeg_buffer, &word)) break; length = (long)word - 2; + /* No need to check underflows as skip() does it */ skip(&jpeg_buffer, length); break; } @@ -2579,11 +2584,8 @@ static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) { struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); - int ret; - - ret = pm_runtime_get_sync(ctx->jpeg->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(ctx->jpeg->dev); } static void s5p_jpeg_stop_streaming(struct vb2_queue *q) --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-mfc/s5p_mfc.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-mfc/s5p_mfc.c @@ -1279,11 +1279,15 @@ spin_lock_init(&dev->condlock); dev->plat_dev = pdev; if (!dev->plat_dev) { - dev_err(&pdev->dev, "No platform data specified\n"); + mfc_err("No platform data specified\n"); return -ENODEV; } dev->variant = of_device_get_match_data(&pdev->dev); + if (!dev->variant) { + dev_err(&pdev->dev, "Failed to get device MFC hardware variant information\n"); + return -ENOENT; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->regs_base = devm_ioremap_resource(&pdev->dev, res); @@ -1576,8 +1580,18 @@ .port_num = MFC_NUM_PORTS_V7, .buf_size = &buf_size_v7, .fw_name[0] = "s5p-mfc-v7.fw", - .clk_names = {"mfc", "sclk_mfc"}, - .num_clocks = 2, + .clk_names = {"mfc"}, + .num_clocks = 1, +}; + +static struct s5p_mfc_variant mfc_drvdata_v7_3250 = { + .version = MFC_VERSION_V7, + .version_bit = MFC_V7_BIT, + .port_num = MFC_NUM_PORTS_V7, + .buf_size = &buf_size_v7, + .fw_name[0] = "s5p-mfc-v7.fw", + .clk_names = {"mfc", "sclk_mfc"}, + .num_clocks = 2, }; static struct s5p_mfc_buf_size_v6 mfc_buf_size_v8 = { @@ -1648,6 +1662,9 @@ .compatible = "samsung,mfc-v7", .data = &mfc_drvdata_v7, }, { + .compatible = "samsung,exynos3250-mfc", + .data = &mfc_drvdata_v7_3250, + }, { .compatible = "samsung,mfc-v8", .data = &mfc_drvdata_v8, }, { --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c @@ -468,8 +468,10 @@ s5p_mfc_hw_call(dev->mfc_ops, try_run, dev); /* Wait until instance is returned or timeout occurred */ if (s5p_mfc_wait_for_done_ctx(ctx, - S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)) + S5P_MFC_R2H_CMD_CLOSE_INSTANCE_RET, 0)){ + clear_work_bit_irqsave(ctx); mfc_err("Err returning instance\n"); + } /* Free resources */ s5p_mfc_hw_call(dev->mfc_ops, release_codec_buffers, ctx); --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -1212,6 +1212,7 @@ unsigned long mb_y_addr, mb_c_addr; int slice_type; unsigned int strm_size; + bool src_ready; slice_type = s5p_mfc_hw_call(dev->mfc_ops, get_enc_slice_type, dev); strm_size = s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev); @@ -1251,7 +1252,8 @@ } } } - if ((ctx->src_queue_cnt > 0) && (ctx->state == MFCINST_RUNNING)) { + if (ctx->src_queue_cnt > 0 && (ctx->state == MFCINST_RUNNING || + ctx->state == MFCINST_FINISHING)) { mb_entry = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list); if (mb_entry->flags & MFC_BUF_FLAG_USED) { @@ -1282,7 +1284,13 @@ vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, strm_size); vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE); } - if ((ctx->src_queue_cnt == 0) || (ctx->dst_queue_cnt == 0)) + + src_ready = true; + if (ctx->state == MFCINST_RUNNING && ctx->src_queue_cnt == 0) + src_ready = false; + if (ctx->state == MFCINST_FINISHING && ctx->ref_queue_cnt == 0) + src_ready = false; + if (!src_ready || ctx->dst_queue_cnt == 0) clear_work_bit(ctx); return 0; --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1060,7 +1060,7 @@ } /* aspect ratio VUI */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 5); reg |= ((p_h264->vui_sar & 0x1) << 5); writel(reg, mfc_regs->e_h264_options); @@ -1083,7 +1083,7 @@ /* intra picture period for H.264 open GOP */ /* control */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 4); reg |= ((p_h264->open_gop & 0x1) << 4); writel(reg, mfc_regs->e_h264_options); @@ -1097,23 +1097,23 @@ } /* 'WEIGHTED_BI_PREDICTION' for B is disable */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x3 << 9); writel(reg, mfc_regs->e_h264_options); /* 'CONSTRAINED_INTRA_PRED_ENABLE' is disable */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 14); writel(reg, mfc_regs->e_h264_options); /* ASO */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 6); reg |= ((p_h264->aso & 0x1) << 6); writel(reg, mfc_regs->e_h264_options); /* hier qp enable */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 8); reg |= ((p_h264->open_gop & 0x1) << 8); writel(reg, mfc_regs->e_h264_options); @@ -1134,7 +1134,7 @@ writel(reg, mfc_regs->e_h264_num_t_layer); /* frame packing SEI generation */ - readl(mfc_regs->e_h264_options); + reg = readl(mfc_regs->e_h264_options); reg &= ~(0x1 << 25); reg |= ((p_h264->sei_frame_packing & 0x1) << 25); writel(reg, mfc_regs->e_h264_options); --- linux-oracle-5.4.0.orig/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c +++ linux-oracle-5.4.0/drivers/media/platform/s5p-mfc/s5p_mfc_pm.c @@ -79,8 +79,10 @@ int i, ret = 0; ret = pm_runtime_get_sync(pm->device); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(pm->device); return ret; + } /* clock control */ for (i = 0; i < pm->num_clocks; i++) { --- linux-oracle-5.4.0.orig/drivers/media/platform/seco-cec/seco-cec.c +++ linux-oracle-5.4.0/drivers/media/platform/seco-cec/seco-cec.c @@ -675,6 +675,7 @@ err_delete_adapter: cec_delete_adapter(secocec->cec_adap); err: + release_region(BRA_SMB_BASE_ADDR, 7); dev_err(dev, "%s device probe failed\n", dev_name(dev)); return ret; --- linux-oracle-5.4.0.orig/drivers/media/platform/sh_vou.c +++ linux-oracle-5.4.0/drivers/media/platform/sh_vou.c @@ -1133,7 +1133,11 @@ if (v4l2_fh_is_singular_file(file) && vou_dev->status == SH_VOU_INITIALISING) { /* First open */ - pm_runtime_get_sync(vou_dev->v4l2_dev.dev); + err = pm_runtime_resume_and_get(vou_dev->v4l2_dev.dev); + if (err < 0) { + v4l2_fh_release(file); + goto done_open; + } err = sh_vou_hw_init(vou_dev); if (err < 0) { pm_runtime_put(vou_dev->v4l2_dev.dev); --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/bdisp/Makefile +++ linux-oracle-5.4.0/drivers/media/platform/sti/bdisp/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o +obj-$(CONFIG_VIDEO_STI_BDISP) += bdisp.o bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/bdisp/bdisp-debug.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/bdisp/bdisp-debug.c @@ -480,7 +480,7 @@ int ret; unsigned int i; - ret = pm_runtime_get_sync(bdisp->dev); + ret = pm_runtime_resume_and_get(bdisp->dev); if (ret < 0) { seq_puts(s, "Cannot wake up IP\n"); return 0; --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/bdisp/bdisp-hw.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/bdisp/bdisp-hw.c @@ -14,8 +14,8 @@ #define MAX_SRC_WIDTH 2048 /* Reset & boot poll config */ -#define POLL_RST_MAX 50 -#define POLL_RST_DELAY_MS 20 +#define POLL_RST_MAX 500 +#define POLL_RST_DELAY_MS 2 enum bdisp_target_plan { BDISP_RGB, @@ -382,7 +382,7 @@ for (i = 0; i < POLL_RST_MAX; i++) { if (readl(bdisp->regs + BLT_STA1) & BLT_STA1_IDLE) break; - msleep(POLL_RST_DELAY_MS); + udelay(POLL_RST_DELAY_MS * 1000); } if (i == POLL_RST_MAX) dev_err(bdisp->dev, "Reset timeout\n"); --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -499,7 +499,7 @@ { struct bdisp_ctx *ctx = q->drv_priv; struct vb2_v4l2_buffer *buf; - int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev); + int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev); if (ret < 0) { dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); @@ -651,8 +651,7 @@ dev_dbg(bdisp->dev, "%s\n", __func__); - if (mutex_lock_interruptible(&bdisp->lock)) - return -ERESTARTSYS; + mutex_lock(&bdisp->lock); v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); @@ -1309,6 +1308,8 @@ init_waitqueue_head(&bdisp->irq_queue); INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); bdisp->work_queue = create_workqueue(BDISP_NAME); + if (!bdisp->work_queue) + return -ENOMEM; spin_lock_init(&bdisp->slock); mutex_init(&bdisp->lock); @@ -1365,10 +1366,10 @@ /* Power management */ pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "failed to set PM\n"); - goto err_dbg; + goto err_remove; } /* Filters */ @@ -1396,7 +1397,7 @@ bdisp_hw_free_filters(bdisp->dev); err_pm: pm_runtime_put(dev); -err_dbg: +err_remove: bdisp_debugfs_remove(bdisp); err_v4l2: v4l2_device_unregister(&bdisp->v4l2_dev); --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -939,6 +939,7 @@ if (ret) { dev_err(fei->dev, "configure_memdma_and_inputblock failed\n"); + of_node_put(child); goto err_unmap; } index++; --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/delta/Makefile +++ linux-oracle-5.4.0/drivers/media/platform/sti/delta/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o +obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) += st-delta.o st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o # MJPEG support --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/delta/delta-v4l2.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/delta/delta-v4l2.c @@ -954,8 +954,10 @@ /* enable the hardware */ if (!dec->pm) { ret = delta_get_sync(ctx); - if (ret) + if (ret) { + delta_put_autosuspend(ctx); goto err; + } } /* decode this access unit */ @@ -1860,7 +1862,7 @@ if (ret) { dev_err(delta->dev, "%s failed to initialize firmware ipc channel\n", DELTA_PREFIX); - goto err; + goto err_pm_disable; } /* register all available decoders */ @@ -1874,7 +1876,7 @@ if (ret) { dev_err(delta->dev, "%s failed to register V4L2 device\n", DELTA_PREFIX); - goto err; + goto err_pm_disable; } delta->work_queue = create_workqueue(DELTA_NAME); @@ -1899,6 +1901,8 @@ destroy_workqueue(delta->work_queue); err_v4l2: v4l2_device_unregister(&delta->v4l2_dev); +err_pm_disable: + pm_runtime_disable(dev); err: return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/hva/Makefile +++ linux-oracle-5.4.0/drivers/media/platform/sti/hva/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o +obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o --- linux-oracle-5.4.0.orig/drivers/media/platform/sti/hva/hva-hw.c +++ linux-oracle-5.4.0/drivers/media/platform/sti/hva/hva-hw.c @@ -130,8 +130,7 @@ ctx_id = (hva->sts_reg & 0xFF00) >> 8; if (ctx_id >= HVA_MAX_INSTANCES) { dev_err(dev, "%s %s: bad context identifier: %d\n", - ctx->name, __func__, ctx_id); - ctx->hw_err = true; + HVA_PREFIX, __func__, ctx_id); goto out; } @@ -272,6 +271,7 @@ if (pm_runtime_get_sync(dev) < 0) { dev_err(dev, "%s failed to get pm_runtime\n", HVA_PREFIX); + pm_runtime_put_noidle(dev); mutex_unlock(&hva->protect_mutex); return -EFAULT; } @@ -388,7 +388,7 @@ ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "%s failed to set PM\n", HVA_PREFIX); - goto err_clk; + goto err_pm; } /* check IP hardware version */ @@ -553,6 +553,7 @@ if (pm_runtime_get_sync(dev) < 0) { seq_puts(s, "Cannot wake up IP\n"); + pm_runtime_put_noidle(dev); mutex_unlock(&hva->protect_mutex); return; } --- linux-oracle-5.4.0.orig/drivers/media/platform/stm32/stm32-dcmi.c +++ linux-oracle-5.4.0/drivers/media/platform/stm32/stm32-dcmi.c @@ -135,6 +135,7 @@ int sequence; struct list_head buffers; struct dcmi_buf *active; + int irq; struct v4l2_device v4l2_dev; struct video_device *vdev; @@ -733,7 +734,7 @@ if (ret < 0) { dev_err(dcmi->dev, "%s: Failed to start streaming, cannot get sync (%d)\n", __func__, ret); - goto err_release_buffers; + goto err_pm_put; } ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); @@ -837,8 +838,6 @@ err_pm_put: pm_runtime_put(dcmi->dev); - -err_release_buffers: spin_lock_irq(&dcmi->irqlock); /* * Return all buffers to vb2 in QUEUED state. @@ -1722,6 +1721,14 @@ return ret; } + ret = devm_request_threaded_irq(dcmi->dev, dcmi->irq, dcmi_irq_callback, + dcmi_irq_thread, IRQF_ONESHOT, + dev_name(dcmi->dev), dcmi); + if (ret) { + dev_err(dcmi->dev, "Unable to request irq %d\n", dcmi->irq); + return ret; + } + return 0; } @@ -1883,6 +1890,8 @@ if (irq <= 0) return irq ? irq : -ENXIO; + dcmi->irq = irq; + dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dcmi->res) { dev_err(&pdev->dev, "Could not get resource\n"); @@ -1895,14 +1904,6 @@ return PTR_ERR(dcmi->regs); } - ret = devm_request_threaded_irq(&pdev->dev, irq, dcmi_irq_callback, - dcmi_irq_thread, IRQF_ONESHOT, - dev_name(&pdev->dev), dcmi); - if (ret) { - dev_err(&pdev->dev, "Unable to request irq %d\n", irq); - return ret; - } - mclk = devm_clk_get(&pdev->dev, "mclk"); if (IS_ERR(mclk)) { if (PTR_ERR(mclk) != -EPROBE_DEFER) --- linux-oracle-5.4.0.orig/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +++ linux-oracle-5.4.0/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,10 @@ .link_validate = v4l2_subdev_link_validate, }; +static const struct media_entity_operations sun4i_csi_subdev_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *subdev, struct v4l2_async_subdev *asd) @@ -155,6 +160,27 @@ subdev = &csi->subdev; vdev = &csi->vdev; + /* + * On Allwinner SoCs, some high memory bandwidth devices do DMA + * directly over the memory bus (called MBUS), instead of the + * system bus. The memory bus has a different addressing scheme + * without the DRAM starting offset. + * + * In some cases this can be described by an interconnect in + * the device tree. In other cases where the hardware is not + * fully understood and the interconnect is left out of the + * device tree, fall back to a default offset. + */ + if (of_find_property(csi->dev->of_node, "interconnects", NULL)) { + ret = of_dma_configure(csi->dev, csi->dev->of_node, true); + if (ret) + return ret; + } else { +#ifdef PHYS_PFN_OFFSET + csi->dev->dma_pfn_offset = PHYS_PFN_OFFSET; +#endif + } + csi->mdev.dev = csi->dev; strscpy(csi->mdev.model, "Allwinner Video Capture Device", sizeof(csi->mdev.model)); @@ -199,6 +225,7 @@ v4l2_subdev_init(subdev, &sun4i_csi_subdev_ops); subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + subdev->entity.ops = &sun4i_csi_subdev_entity_ops; subdev->owner = THIS_MODULE; snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0"); v4l2_set_subdevdata(subdev, csi); --- linux-oracle-5.4.0.orig/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h +++ linux-oracle-5.4.0/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h @@ -22,8 +22,8 @@ #define CSI_CFG_INPUT_FMT(fmt) ((fmt) << 20) #define CSI_CFG_OUTPUT_FMT(fmt) ((fmt) << 16) #define CSI_CFG_YUV_DATA_SEQ(seq) ((seq) << 8) -#define CSI_CFG_VSYNC_POL(pol) ((pol) << 2) -#define CSI_CFG_HSYNC_POL(pol) ((pol) << 1) +#define CSI_CFG_VREF_POL(pol) ((pol) << 2) +#define CSI_CFG_HREF_POL(pol) ((pol) << 1) #define CSI_CFG_PCLK_POL(pol) ((pol) << 0) #define CSI_CPT_CTRL_REG 0x08 --- linux-oracle-5.4.0.orig/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c +++ linux-oracle-5.4.0/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c @@ -228,7 +228,7 @@ struct sun4i_csi *csi = vb2_get_drv_priv(vq); struct v4l2_fwnode_bus_parallel *bus = &csi->bus; const struct sun4i_csi_format *csi_fmt; - unsigned long hsync_pol, pclk_pol, vsync_pol; + unsigned long href_pol, pclk_pol, vref_pol; unsigned long flags; unsigned int i; int ret; @@ -278,13 +278,21 @@ writel(CSI_WIN_CTRL_H_ACTIVE(csi->fmt.height), csi->regs + CSI_WIN_CTRL_H_REG); - hsync_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH); - pclk_pol = !!(bus->flags & V4L2_MBUS_DATA_ACTIVE_HIGH); - vsync_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH); + /* + * This hardware uses [HV]REF instead of [HV]SYNC. Based on the + * provided timing diagrams in the manual, positive polarity + * equals active high [HV]REF. + * + * When the back porch is 0, [HV]REF is more or less equivalent + * to [HV]SYNC inverted. + */ + href_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); + vref_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); + pclk_pol = !!(bus->flags & V4L2_MBUS_PCLK_SAMPLE_RISING); writel(CSI_CFG_INPUT_FMT(csi_fmt->input) | CSI_CFG_OUTPUT_FMT(csi_fmt->output) | - CSI_CFG_VSYNC_POL(vsync_pol) | - CSI_CFG_HSYNC_POL(hsync_pol) | + CSI_CFG_VREF_POL(vref_pol) | + CSI_CFG_HREF_POL(href_pol) | CSI_CFG_PCLK_POL(pclk_pol), csi->regs + CSI_CFG_REG); --- linux-oracle-5.4.0.orig/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c +++ linux-oracle-5.4.0/drivers/media/platform/sunxi/sun6i-csi/sun6i_video.c @@ -151,8 +151,10 @@ } subdev = sun6i_video_remote_subdev(video, NULL); - if (!subdev) + if (!subdev) { + ret = -EINVAL; goto stop_media_pipeline; + } config.pixelformat = video->fmt.fmt.pix.pixelformat; config.code = video->mbus_code; --- linux-oracle-5.4.0.orig/drivers/media/platform/tegra-cec/tegra_cec.c +++ linux-oracle-5.4.0/drivers/media/platform/tegra-cec/tegra_cec.c @@ -366,7 +366,11 @@ return -ENOENT; } - clk_prepare_enable(cec->clk); + ret = clk_prepare_enable(cec->clk); + if (ret) { + dev_err(&pdev->dev, "Unable to prepare clock for CEC\n"); + return ret; + } /* set context info. */ cec->dev = &pdev->dev; @@ -446,9 +450,7 @@ dev_notice(&pdev->dev, "Resuming\n"); - clk_prepare_enable(cec->clk); - - return 0; + return clk_prepare_enable(cec->clk); } #endif --- linux-oracle-5.4.0.orig/drivers/media/platform/ti-vpe/cal.c +++ linux-oracle-5.4.0/drivers/media/platform/ti-vpe/cal.c @@ -266,8 +266,6 @@ struct v4l2_subdev *sensor; struct v4l2_fwnode_endpoint endpoint; - struct v4l2_async_subdev asd; - struct v4l2_fh fh; struct cal_dev *dev; struct cc_data *cc; @@ -537,16 +535,16 @@ static void disable_irqs(struct cal_ctx *ctx) { + u32 val; + /* Disable IRQ_WDMA_END 0/1 */ - reg_write_field(ctx->dev, - CAL_HL_IRQENABLE_CLR(2), - CAL_HL_IRQ_CLEAR, - CAL_HL_IRQ_MASK(ctx->csi2_port)); + val = 0; + set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port)); + reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(2), val); /* Disable IRQ_WDMA_START 0/1 */ - reg_write_field(ctx->dev, - CAL_HL_IRQENABLE_CLR(3), - CAL_HL_IRQ_CLEAR, - CAL_HL_IRQ_MASK(ctx->csi2_port)); + val = 0; + set_field(&val, CAL_HL_IRQ_CLEAR, CAL_HL_IRQ_MASK(ctx->csi2_port)); + reg_write(ctx->dev, CAL_HL_IRQENABLE_CLR(3), val); /* Todo: Add VC_IRQ and CSI2_COMPLEXIO_IRQ handling */ reg_write(ctx->dev, CAL_CSI2_VC_IRQENABLE(1), 0); } @@ -680,12 +678,13 @@ } static void cal_wr_dma_config(struct cal_ctx *ctx, - unsigned int width) + unsigned int width, unsigned int height) { u32 val; val = reg_read(ctx->dev, CAL_WR_DMA_CTRL(ctx->csi2_port)); set_field(&val, ctx->csi2_port, CAL_WR_DMA_CTRL_CPORT_MASK); + set_field(&val, height, CAL_WR_DMA_CTRL_YSIZE_MASK); set_field(&val, CAL_WR_DMA_CTRL_DTAG_PIX_DAT, CAL_WR_DMA_CTRL_DTAG_MASK); set_field(&val, CAL_WR_DMA_CTRL_MODE_CONST, @@ -1308,7 +1307,8 @@ csi2_lane_config(ctx); csi2_ctx_config(ctx); pix_proc_config(ctx); - cal_wr_dma_config(ctx, ctx->v_fmt.fmt.pix.bytesperline); + cal_wr_dma_config(ctx, ctx->v_fmt.fmt.pix.bytesperline, + ctx->v_fmt.fmt.pix.height); cal_wr_dma_addr(ctx, addr); csi2_ppi_enable(ctx); @@ -1648,7 +1648,6 @@ parent = pdev->dev.of_node; - asd = &ctx->asd; endpoint = &ctx->endpoint; ep_node = NULL; @@ -1695,8 +1694,6 @@ ctx_dbg(3, ctx, "can't get remote parent\n"); goto cleanup_exit; } - asd->match_type = V4L2_ASYNC_MATCH_FWNODE; - asd->match.fwnode = of_fwnode_handle(sensor_node); v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), endpoint); @@ -1726,9 +1723,17 @@ v4l2_async_notifier_init(&ctx->notifier); + asd = kzalloc(sizeof(*asd), GFP_KERNEL); + if (!asd) + goto cleanup_exit; + + asd->match_type = V4L2_ASYNC_MATCH_FWNODE; + asd->match.fwnode = of_fwnode_handle(sensor_node); + ret = v4l2_async_notifier_add_subdev(&ctx->notifier, asd); if (ret) { ctx_err(ctx, "Error adding asd\n"); + kfree(asd); goto cleanup_exit; } --- linux-oracle-5.4.0.orig/drivers/media/platform/ti-vpe/vpdma.h +++ linux-oracle-5.4.0/drivers/media/platform/ti-vpe/vpdma.h @@ -57,6 +57,7 @@ * line stride of source and dest * buffers should be 16 byte aligned */ +#define VPDMA_MAX_STRIDE 65520 /* Max line stride 16 byte aligned */ #define VPDMA_DTD_DESC_SIZE 32 /* 8 words */ #define VPDMA_CFD_CTD_DESC_SIZE 16 /* 4 words */ --- linux-oracle-5.4.0.orig/drivers/media/platform/ti-vpe/vpe.c +++ linux-oracle-5.4.0/drivers/media/platform/ti-vpe/vpe.c @@ -338,20 +338,25 @@ }; /* find our format description corresponding to the passed v4l2_format */ -static struct vpe_fmt *find_format(struct v4l2_format *f) +static struct vpe_fmt *__find_format(u32 fourcc) { struct vpe_fmt *fmt; unsigned int k; for (k = 0; k < ARRAY_SIZE(vpe_formats); k++) { fmt = &vpe_formats[k]; - if (fmt->fourcc == f->fmt.pix.pixelformat) + if (fmt->fourcc == fourcc) return fmt; } return NULL; } +static struct vpe_fmt *find_format(struct v4l2_format *f) +{ + return __find_format(f->fmt.pix.pixelformat); +} + /* * there is one vpe_dev structure in the driver, it is shared by * all instances. @@ -1013,11 +1018,14 @@ dma_addr_t dma_addr; u32 flags = 0; u32 offset = 0; + u32 stride; if (port == VPE_PORT_MV_OUT) { vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; dma_addr = ctx->mv_buf_dma[mv_buf_selector]; q_data = &ctx->q_data[Q_DATA_SRC]; + stride = ALIGN((q_data->width * vpdma_fmt->depth) >> 3, + VPDMA_STRIDE_ALIGN); } else { /* to incorporate interleaved formats */ int plane = fmt->coplanar ? p_data->vb_part : 0; @@ -1044,6 +1052,7 @@ } /* Apply the offset */ dma_addr += offset; + stride = q_data->bytesperline[VPE_LUMA]; } if (q_data->flags & Q_DATA_FRAME_1D) @@ -1055,7 +1064,7 @@ MAX_W, MAX_H); vpdma_add_out_dtd(&ctx->desc_list, q_data->width, - q_data->bytesperline[VPE_LUMA], &q_data->c_rect, + stride, &q_data->c_rect, vpdma_fmt, dma_addr, MAX_OUT_WIDTH_REG1, MAX_OUT_HEIGHT_REG1, p_data->channel, flags); } @@ -1074,10 +1083,13 @@ dma_addr_t dma_addr; u32 flags = 0; u32 offset = 0; + u32 stride; if (port == VPE_PORT_MV_IN) { vpdma_fmt = &vpdma_misc_fmts[VPDMA_DATA_FMT_MV]; dma_addr = ctx->mv_buf_dma[mv_buf_selector]; + stride = ALIGN((q_data->width * vpdma_fmt->depth) >> 3, + VPDMA_STRIDE_ALIGN); } else { /* to incorporate interleaved formats */ int plane = fmt->coplanar ? p_data->vb_part : 0; @@ -1104,6 +1116,7 @@ } /* Apply the offset */ dma_addr += offset; + stride = q_data->bytesperline[VPE_LUMA]; if (q_data->flags & Q_DATA_INTERLACED_SEQ_TB) { /* @@ -1139,10 +1152,10 @@ if (p_data->vb_part && fmt->fourcc == V4L2_PIX_FMT_NV12) frame_height /= 2; - vpdma_add_in_dtd(&ctx->desc_list, q_data->width, - q_data->bytesperline[VPE_LUMA], &q_data->c_rect, - vpdma_fmt, dma_addr, p_data->channel, field, flags, frame_width, - frame_height, 0, 0); + vpdma_add_in_dtd(&ctx->desc_list, q_data->width, stride, + &q_data->c_rect, vpdma_fmt, dma_addr, + p_data->channel, field, flags, frame_width, + frame_height, 0, 0); } /* @@ -1391,9 +1404,6 @@ /* the previous dst mv buffer becomes the next src mv buffer */ ctx->src_mv_buf_selector = !ctx->src_mv_buf_selector; - if (ctx->aborting) - goto finished; - s_vb = ctx->src_vbs[0]; d_vb = ctx->dst_vb; @@ -1404,6 +1414,7 @@ d_vb->timecode = s_vb->timecode; d_vb->sequence = ctx->sequence; + s_vb->sequence = ctx->sequence; d_q_data = &ctx->q_data[Q_DATA_DST]; if (d_q_data->flags & Q_IS_INTERLACED) { @@ -1457,6 +1468,9 @@ ctx->src_vbs[0] = NULL; ctx->dst_vb = NULL; + if (ctx->aborting) + goto finished; + ctx->bufs_completed++; if (ctx->bufs_completed < ctx->bufs_per_job && job_ready(ctx)) { device_run(ctx); @@ -1566,9 +1580,9 @@ unsigned int stride = 0; if (!fmt || !(fmt->types & type)) { - vpe_err(ctx->dev, "Fourcc format (0x%08x) invalid.\n", + vpe_dbg(ctx->dev, "Fourcc format (0x%08x) invalid.\n", pix->pixelformat); - return -EINVAL; + fmt = __find_format(V4L2_PIX_FMT_YUYV); } if (pix->field != V4L2_FIELD_NONE && pix->field != V4L2_FIELD_ALTERNATE @@ -1615,7 +1629,7 @@ &pix->height, MIN_H, MAX_H, H_ALIGN, S_ALIGN); - if (!pix->num_planes) + if (!pix->num_planes || pix->num_planes > 2) pix->num_planes = fmt->coplanar ? 2 : 1; else if (pix->num_planes > 1 && !fmt->coplanar) pix->num_planes = 1; @@ -1654,6 +1668,10 @@ if (stride > plane_fmt->bytesperline) plane_fmt->bytesperline = stride; + plane_fmt->bytesperline = clamp_t(u32, plane_fmt->bytesperline, + stride, + VPDMA_MAX_STRIDE); + plane_fmt->bytesperline = ALIGN(plane_fmt->bytesperline, VPDMA_STRIDE_ALIGN); @@ -2274,7 +2292,7 @@ v4l2_ctrl_handler_setup(hdl); s_q_data = &ctx->q_data[Q_DATA_SRC]; - s_q_data->fmt = &vpe_formats[2]; + s_q_data->fmt = __find_format(V4L2_PIX_FMT_YUYV); s_q_data->width = 1920; s_q_data->height = 1080; s_q_data->nplanes = 1; @@ -2352,6 +2370,12 @@ mutex_lock(&dev->dev_mutex); free_mv_buffers(ctx); + + vpdma_unmap_desc_buf(dev->vpdma, &ctx->desc_list.buf); + vpdma_unmap_desc_buf(dev->vpdma, &ctx->mmr_adb); + vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_h); + vpdma_unmap_desc_buf(dev->vpdma, &ctx->sc_coeff_v); + vpdma_free_desc_list(&ctx->desc_list); vpdma_free_desc_buf(&ctx->mmr_adb); @@ -2411,6 +2435,8 @@ r = pm_runtime_get_sync(&pdev->dev); WARN_ON(r < 0); + if (r) + pm_runtime_put_noidle(&pdev->dev); return r < 0 ? r : 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/vicodec/codec-v4l2-fwht.c +++ linux-oracle-5.4.0/drivers/media/platform/vicodec/codec-v4l2-fwht.c @@ -27,17 +27,17 @@ { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, - { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_BGRA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_RGBA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, + { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_HSV}, { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, }; @@ -175,22 +175,14 @@ case V4L2_PIX_FMT_RGB32: case V4L2_PIX_FMT_XRGB32: case V4L2_PIX_FMT_HSV32: - rf->cr = rf->luma + 1; - rf->cb = rf->cr + 2; - rf->luma += 2; - break; - case V4L2_PIX_FMT_BGR32: - case V4L2_PIX_FMT_XBGR32: - rf->cb = rf->luma; - rf->cr = rf->cb + 2; - rf->luma++; - break; case V4L2_PIX_FMT_ARGB32: rf->alpha = rf->luma; rf->cr = rf->luma + 1; rf->cb = rf->cr + 2; rf->luma += 2; break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_XBGR32: case V4L2_PIX_FMT_ABGR32: rf->cb = rf->luma; rf->cr = rf->cb + 2; @@ -198,10 +190,6 @@ rf->alpha = rf->cr + 1; break; case V4L2_PIX_FMT_BGRX32: - rf->cb = rf->luma + 1; - rf->cr = rf->cb + 2; - rf->luma += 2; - break; case V4L2_PIX_FMT_BGRA32: rf->alpha = rf->luma; rf->cb = rf->luma + 1; @@ -209,10 +197,6 @@ rf->luma += 2; break; case V4L2_PIX_FMT_RGBX32: - rf->cr = rf->luma; - rf->cb = rf->cr + 2; - rf->luma++; - break; case V4L2_PIX_FMT_RGBA32: rf->alpha = rf->luma + 3; rf->cr = rf->luma; --- linux-oracle-5.4.0.orig/drivers/media/platform/vicodec/vicodec-core.c +++ linux-oracle-5.4.0/drivers/media/platform/vicodec/vicodec-core.c @@ -2052,6 +2052,7 @@ } ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl, vicodec_ctrl_stateless_state.id); + v4l2_ctrl_request_hdl_put(hdl); if (!ctrl) { v4l2_info(&ctx->dev->v4l2_dev, "Missing required codec control\n"); @@ -2139,6 +2140,9 @@ v4l2_m2m_release(dev->stateful_enc.m2m_dev); v4l2_m2m_release(dev->stateful_dec.m2m_dev); v4l2_m2m_release(dev->stateless_dec.m2m_dev); +#ifdef CONFIG_MEDIA_CONTROLLER + media_device_cleanup(&dev->mdev); +#endif kfree(dev); } @@ -2169,16 +2173,19 @@ platform_set_drvdata(pdev, dev); - if (register_instance(dev, &dev->stateful_enc, - "stateful-encoder", true)) + ret = register_instance(dev, &dev->stateful_enc, "stateful-encoder", + true); + if (ret) goto unreg_dev; - if (register_instance(dev, &dev->stateful_dec, - "stateful-decoder", false)) + ret = register_instance(dev, &dev->stateful_dec, "stateful-decoder", + false); + if (ret) goto unreg_sf_enc; - if (register_instance(dev, &dev->stateless_dec, - "stateless-decoder", false)) + ret = register_instance(dev, &dev->stateless_dec, "stateless-decoder", + false); + if (ret) goto unreg_sf_dec; #ifdef CONFIG_MEDIA_CONTROLLER @@ -2250,7 +2257,6 @@ v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev); v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev); v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev); - media_device_cleanup(&dev->mdev); #endif video_unregister_device(&dev->stateful_enc.vfd); --- linux-oracle-5.4.0.orig/drivers/media/platform/vim2m.c +++ linux-oracle-5.4.0/drivers/media/platform/vim2m.c @@ -1073,6 +1073,9 @@ if (!q_data) return -EINVAL; + if (V4L2_TYPE_IS_OUTPUT(q->type)) + ctx->aborting = 0; + q_data->sequence = 0; return 0; } @@ -1272,6 +1275,9 @@ v4l2_device_unregister(&dev->v4l2_dev); v4l2_m2m_release(dev->m2m_dev); +#ifdef CONFIG_MEDIA_CONTROLLER + media_device_cleanup(&dev->mdev); +#endif kfree(dev); } @@ -1327,12 +1333,6 @@ vfd->lock = &dev->dev_mutex; vfd->v4l2_dev = &dev->v4l2_dev; - ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); - if (ret) { - v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); - goto error_v4l2; - } - video_set_drvdata(vfd, dev); v4l2_info(&dev->v4l2_dev, "Device registered as /dev/video%d\n", vfd->num); @@ -1343,6 +1343,7 @@ if (IS_ERR(dev->m2m_dev)) { v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(dev->m2m_dev); + dev->m2m_dev = NULL; goto error_dev; } @@ -1354,12 +1355,20 @@ media_device_init(&dev->mdev); dev->mdev.ops = &m2m_media_ops; dev->v4l2_dev.mdev = &dev->mdev; +#endif + ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); + if (ret) { + v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); + goto error_m2m; + } + +#ifdef CONFIG_MEDIA_CONTROLLER ret = v4l2_m2m_register_media_controller(dev->m2m_dev, vfd, MEDIA_ENT_F_PROC_VIDEO_SCALER); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller\n"); - goto error_dev; + goto error_v4l2; } ret = media_device_register(&dev->mdev); @@ -1374,11 +1383,13 @@ error_m2m_mc: v4l2_m2m_unregister_media_controller(dev->m2m_dev); #endif -error_dev: +error_v4l2: video_unregister_device(&dev->vfd); /* vim2m_device_release called by video_unregister_device to release various objects */ return ret; -error_v4l2: +error_m2m: + v4l2_m2m_release(dev->m2m_dev); +error_dev: v4l2_device_unregister(&dev->v4l2_dev); error_free: kfree(dev); @@ -1395,7 +1406,6 @@ #ifdef CONFIG_MEDIA_CONTROLLER media_device_unregister(&dev->mdev); v4l2_m2m_unregister_media_controller(dev->m2m_dev); - media_device_cleanup(&dev->mdev); #endif video_unregister_device(&dev->vfd); --- linux-oracle-5.4.0.orig/drivers/media/platform/vimc/vimc-common.c +++ linux-oracle-5.4.0/drivers/media/platform/vimc/vimc-common.c @@ -375,7 +375,7 @@ { int ret; - /* Allocate the pads */ + /* Allocate the pads. Should be released from the sd_int_op release */ ved->pads = vimc_pads_init(num_pads, pads_flag); if (IS_ERR(ved->pads)) return PTR_ERR(ved->pads); @@ -424,7 +424,6 @@ void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd) { media_entity_cleanup(ved->ent); - vimc_pads_cleanup(ved->pads); v4l2_device_unregister_subdev(sd); } EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister); --- linux-oracle-5.4.0.orig/drivers/media/platform/vimc/vimc-debayer.c +++ linux-oracle-5.4.0/drivers/media/platform/vimc/vimc-debayer.c @@ -484,6 +484,7 @@ struct vimc_deb_device *vdeb = container_of(sd, struct vimc_deb_device, sd); + vimc_pads_cleanup(vdeb->ved.pads); kfree(vdeb); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vimc/vimc-scaler.c +++ linux-oracle-5.4.0/drivers/media/platform/vimc/vimc-scaler.c @@ -343,6 +343,7 @@ struct vimc_sca_device *vsca = container_of(sd, struct vimc_sca_device, sd); + vimc_pads_cleanup(vsca->ved.pads); kfree(vsca); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vimc/vimc-sensor.c +++ linux-oracle-5.4.0/drivers/media/platform/vimc/vimc-sensor.c @@ -25,7 +25,6 @@ struct v4l2_subdev sd; struct device *dev; struct tpg_data tpg; - struct task_struct *kthread_sen; u8 *frame; /* The active format */ struct v4l2_mbus_framefmt mbus_format; @@ -208,10 +207,6 @@ const struct vimc_pix_map *vpix; unsigned int frame_size; - if (vsen->kthread_sen) - /* tpg is already executing */ - return 0; - /* Calculate the frame size */ vpix = vimc_pix_map_by_code(vsen->mbus_format.code); frame_size = vsen->mbus_format.width * vpix->bpp * @@ -297,6 +292,7 @@ v4l2_ctrl_handler_free(&vsen->hdl); tpg_free(&vsen->tpg); + vimc_pads_cleanup(vsen->ved.pads); kfree(vsen); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-core.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-core.c @@ -174,13 +174,13 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7b, - 0x02, 0x03, 0x3f, 0xf0, 0x51, 0x61, 0x60, 0x5f, + 0x02, 0x03, 0x3f, 0xf1, 0x51, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, - 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3, + 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, 0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, @@ -189,7 +189,7 @@ 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, }; static int vidioc_querycap(struct file *file, void *priv, @@ -297,6 +297,28 @@ return vivid_vid_out_g_fbuf(file, fh, a); } +/* + * Only support the framebuffer of one of the vivid instances. + * Anything else is rejected. + */ +bool vivid_validate_fb(const struct v4l2_framebuffer *a) +{ + struct vivid_dev *dev; + int i; + + for (i = 0; i < n_devs; i++) { + dev = vivid_devs[i]; + if (!dev || !dev->video_pbase) + continue; + if ((unsigned long)a->base == dev->video_pbase && + a->fmt.width <= dev->display_width && + a->fmt.height <= dev->display_height && + a->fmt.bytesperline <= dev->display_byte_stride) + return true; + } + return false; +} + static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a) { struct video_device *vdev = video_devdata(file); @@ -616,6 +638,9 @@ vivid_free_controls(dev); v4l2_device_unregister(&dev->v4l2_dev); +#ifdef CONFIG_MEDIA_CONTROLLER + media_device_cleanup(&dev->mdev); +#endif vfree(dev->scaled_line); vfree(dev->blended_line); vfree(dev->edid); @@ -1580,7 +1605,6 @@ #ifdef CONFIG_MEDIA_CONTROLLER media_device_unregister(&dev->mdev); - media_device_cleanup(&dev->mdev); #endif if (dev->has_vid_cap) { --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-core.h +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-core.h @@ -564,4 +564,6 @@ return dev->output_type[dev->output] == HDMI; } +bool vivid_validate_fb(const struct v4l2_framebuffer *a); + #endif --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-kthread-cap.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-kthread-cap.c @@ -796,7 +796,11 @@ if (kthread_should_stop()) break; - mutex_lock(&dev->mutex); + if (!mutex_trylock(&dev->mutex)) { + schedule_timeout_uninterruptible(1); + continue; + } + cur_jiffies = jiffies; if (dev->cap_seq_resync) { dev->jiffies_vid_cap = cur_jiffies; @@ -956,8 +960,6 @@ /* shutdown control thread */ vivid_grab_controls(dev, false); - mutex_unlock(&dev->mutex); kthread_stop(dev->kthread_vid_cap); dev->kthread_vid_cap = NULL; - mutex_lock(&dev->mutex); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-kthread-out.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-kthread-out.c @@ -143,7 +143,11 @@ if (kthread_should_stop()) break; - mutex_lock(&dev->mutex); + if (!mutex_trylock(&dev->mutex)) { + schedule_timeout_uninterruptible(1); + continue; + } + cur_jiffies = jiffies; if (dev->out_seq_resync) { dev->jiffies_vid_out = cur_jiffies; @@ -301,8 +305,6 @@ /* shutdown control thread */ vivid_grab_controls(dev, false); - mutex_unlock(&dev->mutex); kthread_stop(dev->kthread_vid_out); dev->kthread_vid_out = NULL; - mutex_lock(&dev->mutex); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-rds-gen.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-rds-gen.c @@ -145,7 +145,7 @@ rds->ta = alt; rds->ms = true; snprintf(rds->psname, sizeof(rds->psname), "%6d.%1d", - freq / 16, ((freq & 0xf) * 10) / 16); + (freq / 16) % 1000000, (((freq & 0xf) * 10) / 16) % 10); if (alt) strscpy(rds->radiotext, " The Radio Data System can switch between different Radio Texts ", --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-sdr-cap.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-sdr-cap.c @@ -141,7 +141,11 @@ if (kthread_should_stop()) break; - mutex_lock(&dev->mutex); + if (!mutex_trylock(&dev->mutex)) { + schedule_timeout_uninterruptible(1); + continue; + } + cur_jiffies = jiffies; if (dev->sdr_cap_seq_resync) { dev->jiffies_sdr_cap = cur_jiffies; @@ -303,10 +307,8 @@ } /* shutdown control thread */ - mutex_unlock(&dev->mutex); kthread_stop(dev->kthread_sdr_cap); dev->kthread_sdr_cap = NULL; - mutex_lock(&dev->mutex); } static void sdr_cap_buf_request_complete(struct vb2_buffer *vb) --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-vid-cap.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-vid-cap.c @@ -223,9 +223,6 @@ if (vb2_is_streaming(&dev->vb_vid_out_q)) dev->can_loop_video = vivid_vid_can_loop(dev); - if (dev->kthread_vid_cap) - return 0; - dev->vid_cap_seq_count = 0; dprintk(dev, 1, "%s\n", __func__); for (i = 0; i < VIDEO_MAX_FRAME; i++) @@ -455,6 +452,12 @@ tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); dev->crop_cap = dev->src_rect; dev->crop_bounds_cap = dev->src_rect; + if (dev->bitmap_cap && + (dev->compose_cap.width != dev->crop_cap.width || + dev->compose_cap.height != dev->crop_cap.height)) { + vfree(dev->bitmap_cap); + dev->bitmap_cap = NULL; + } dev->compose_cap = dev->crop_cap; if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap)) dev->compose_cap.height /= 2; @@ -886,6 +889,8 @@ struct vivid_dev *dev = video_drvdata(file); struct v4l2_rect *crop = &dev->crop_cap; struct v4l2_rect *compose = &dev->compose_cap; + unsigned orig_compose_w = compose->width; + unsigned orig_compose_h = compose->height; unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; int ret; @@ -930,6 +935,7 @@ if (dev->has_compose_cap) { v4l2_rect_set_min_size(compose, &min_rect); v4l2_rect_set_max_size(compose, &max_rect); + v4l2_rect_map_inside(compose, &fmt); } dev->fmt_cap_rect = fmt; tpg_s_buf_height(&dev->tpg, fmt.height); @@ -1002,17 +1008,17 @@ s->r.height /= factor; } v4l2_rect_map_inside(&s->r, &dev->fmt_cap_rect); - if (dev->bitmap_cap && (compose->width != s->r.width || - compose->height != s->r.height)) { - vfree(dev->bitmap_cap); - dev->bitmap_cap = NULL; - } *compose = s->r; break; default: return -EINVAL; } + if (dev->bitmap_cap && (compose->width != orig_compose_w || + compose->height != orig_compose_h)) { + vfree(dev->bitmap_cap); + dev->bitmap_cap = NULL; + } tpg_s_crop_compose(&dev->tpg, crop, compose); return 0; } @@ -1253,7 +1259,14 @@ return -EINVAL; if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8) return -EINVAL; - if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage) + if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height) + return -EINVAL; + + /* + * Only support the framebuffer of one of the vivid instances. + * Anything else is rejected. + */ + if (!vivid_validate_fb(a)) return -EINVAL; dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base); --- linux-oracle-5.4.0.orig/drivers/media/platform/vivid/vivid-vid-out.c +++ linux-oracle-5.4.0/drivers/media/platform/vivid/vivid-vid-out.c @@ -161,9 +161,6 @@ if (vb2_is_streaming(&dev->vb_vid_cap_q)) dev->can_loop_video = vivid_vid_can_loop(dev); - if (dev->kthread_vid_out) - return 0; - dev->vid_out_seq_count = 0; dprintk(dev, 1, "%s\n", __func__); if (dev->start_streaming_error) { @@ -1028,7 +1025,7 @@ return -EINVAL; } dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags); - dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags); + dev->fbuf_out_flags |= a->flags & (chroma_flags | alpha_flags); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_dl.c +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_dl.c @@ -431,6 +431,8 @@ if (!pool) return NULL; + pool->vsp1 = vsp1; + spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->free); --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_drm.c +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_drm.c @@ -245,7 +245,7 @@ brx = &vsp1->bru->entity; else if (pipe->brx && !drm_pipe->force_brx_release) brx = pipe->brx; - else if (!vsp1->bru->entity.pipe) + else if (vsp1_feature(vsp1, VSP1_HAS_BRU) && !vsp1->bru->entity.pipe) brx = &vsp1->bru->entity; else brx = &vsp1->brs->entity; @@ -462,9 +462,9 @@ * make sure it is present in the pipeline's list of entities if it * wasn't already. */ - if (!use_uif) { + if (drm_pipe->uif && !use_uif) { drm_pipe->uif->pipe = NULL; - } else if (!drm_pipe->uif->pipe) { + } else if (drm_pipe->uif && !drm_pipe->uif->pipe) { drm_pipe->uif->pipe = pipe; list_add_tail(&drm_pipe->uif->list_pipe, &pipe->entities); } --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_drv.c +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_drv.c @@ -562,7 +562,12 @@ int ret; ret = pm_runtime_get_sync(vsp1->dev); - return ret < 0 ? ret : 0; + if (ret < 0) { + pm_runtime_put_noidle(vsp1->dev); + return ret; + } + + return 0; } /* @@ -845,12 +850,12 @@ /* Configure device parameters based on the version register. */ pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = vsp1_device_get(vsp1); if (ret < 0) goto done; vsp1->version = vsp1_read(vsp1, VI6_IP_VERSION); - pm_runtime_put_sync(&pdev->dev); + vsp1_device_put(vsp1); for (i = 0; i < ARRAY_SIZE(vsp1_device_infos); ++i) { if ((vsp1->version & VI6_IP_VERSION_MODEL_MASK) == @@ -877,8 +882,10 @@ } done: - if (ret) + if (ret) { pm_runtime_disable(&pdev->dev); + rcar_fcp_put(vsp1->fcp); + } return ret; } --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_histo.c +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_histo.c @@ -36,9 +36,8 @@ vsp1_histogram_buffer_get(struct vsp1_histogram *histo) { struct vsp1_histogram_buffer *buf = NULL; - unsigned long flags; - spin_lock_irqsave(&histo->irqlock, flags); + spin_lock(&histo->irqlock); if (list_empty(&histo->irqqueue)) goto done; @@ -49,7 +48,7 @@ histo->readout = true; done: - spin_unlock_irqrestore(&histo->irqlock, flags); + spin_unlock(&histo->irqlock); return buf; } @@ -58,7 +57,6 @@ size_t size) { struct vsp1_pipeline *pipe = histo->entity.pipe; - unsigned long flags; /* * The pipeline pointer is guaranteed to be valid as this function is @@ -70,10 +68,10 @@ vb2_set_plane_payload(&buf->buf.vb2_buf, 0, size); vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); - spin_lock_irqsave(&histo->irqlock, flags); + spin_lock(&histo->irqlock); histo->readout = false; wake_up(&histo->wait_queue); - spin_unlock_irqrestore(&histo->irqlock, flags); + spin_unlock(&histo->irqlock); } /* ----------------------------------------------------------------------------- @@ -124,11 +122,10 @@ struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vsp1_histogram *histo = vb2_get_drv_priv(vb->vb2_queue); struct vsp1_histogram_buffer *buf = to_vsp1_histogram_buffer(vbuf); - unsigned long flags; - spin_lock_irqsave(&histo->irqlock, flags); + spin_lock_irq(&histo->irqlock); list_add_tail(&buf->queue, &histo->irqqueue); - spin_unlock_irqrestore(&histo->irqlock, flags); + spin_unlock_irq(&histo->irqlock); } static int histo_start_streaming(struct vb2_queue *vq, unsigned int count) @@ -140,9 +137,8 @@ { struct vsp1_histogram *histo = vb2_get_drv_priv(vq); struct vsp1_histogram_buffer *buffer; - unsigned long flags; - spin_lock_irqsave(&histo->irqlock, flags); + spin_lock_irq(&histo->irqlock); /* Remove all buffers from the IRQ queue. */ list_for_each_entry(buffer, &histo->irqqueue, queue) @@ -152,7 +148,7 @@ /* Wait for the buffer being read out (if any) to complete. */ wait_event_lock_irq(histo->wait_queue, !histo->readout, histo->irqlock); - spin_unlock_irqrestore(&histo->irqlock, flags); + spin_unlock_irq(&histo->irqlock); } static const struct vb2_ops histo_video_queue_qops = { --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_pipe.h +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_pipe.h @@ -73,7 +73,7 @@ * @wpf: The WPF partition window configuration */ struct vsp1_partition { - struct vsp1_partition_window rpf; + struct vsp1_partition_window rpf[VSP1_MAX_RPF]; struct vsp1_partition_window uds_sink; struct vsp1_partition_window uds_source; struct vsp1_partition_window sru; --- linux-oracle-5.4.0.orig/drivers/media/platform/vsp1/vsp1_rpf.c +++ linux-oracle-5.4.0/drivers/media/platform/vsp1/vsp1_rpf.c @@ -271,8 +271,8 @@ * 'width' need to be adjusted. */ if (pipe->partitions > 1) { - crop.width = pipe->partition->rpf.width; - crop.left += pipe->partition->rpf.left; + crop.width = pipe->partition->rpf[rpf->entity.index].width; + crop.left += pipe->partition->rpf[rpf->entity.index].left; } if (pipe->interlaced) { @@ -291,11 +291,11 @@ + crop.left * fmtinfo->bpp[0] / 8; if (format->num_planes > 1) { + unsigned int bpl = format->plane_fmt[1].bytesperline; unsigned int offset; - offset = crop.top * format->plane_fmt[1].bytesperline - + crop.left / fmtinfo->hsub - * fmtinfo->bpp[1] / 8; + offset = crop.top / fmtinfo->vsub * bpl + + crop.left / fmtinfo->hsub * fmtinfo->bpp[1] / 8; mem.addr[1] += offset; mem.addr[2] += offset; } @@ -327,7 +327,9 @@ unsigned int partition_idx, struct vsp1_partition_window *window) { - partition->rpf = *window; + struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev); + + partition->rpf[rpf->entity.index] = *window; } static const struct vsp1_entity_operations rpf_entity_ops = { --- linux-oracle-5.4.0.orig/drivers/media/platform/xilinx/xilinx-vipp.c +++ linux-oracle-5.4.0/drivers/media/platform/xilinx/xilinx-vipp.c @@ -472,7 +472,7 @@ { struct device_node *ports; struct device_node *port; - int ret; + int ret = 0; ports = of_get_child_by_name(xdev->dev->of_node, "ports"); if (ports == NULL) { @@ -482,13 +482,14 @@ for_each_child_of_node(ports, port) { ret = xvip_graph_dma_init_one(xdev, port); - if (ret < 0) { + if (ret) { of_node_put(port); - return ret; + break; } } - return 0; + of_node_put(ports); + return ret; } static void xvip_graph_cleanup(struct xvip_composite_device *xdev) --- linux-oracle-5.4.0.orig/drivers/media/radio/radio-isa.c +++ linux-oracle-5.4.0/drivers/media/radio/radio-isa.c @@ -36,7 +36,7 @@ strscpy(v->driver, isa->drv->driver.driver.name, sizeof(v->driver)); strscpy(v->card, isa->drv->card, sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", isa->v4l2_dev.name); + snprintf(v->bus_info, sizeof(v->bus_info), "ISA:%s", dev_name(isa->v4l2_dev.dev)); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/radio/radio-shark.c +++ linux-oracle-5.4.0/drivers/media/radio/radio-shark.c @@ -316,6 +316,16 @@ { struct shark_device *shark; int retval = -ENOMEM; + static const u8 ep_addresses[] = { + SHARK_IN_EP | USB_DIR_IN, + SHARK_OUT_EP | USB_DIR_OUT, + 0}; + + /* Are the expected endpoints present? */ + if (!usb_check_int_endpoints(intf, ep_addresses)) { + dev_err(&intf->dev, "Invalid radioSHARK device\n"); + return -EINVAL; + } shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); if (!shark) --- linux-oracle-5.4.0.orig/drivers/media/radio/radio-shark2.c +++ linux-oracle-5.4.0/drivers/media/radio/radio-shark2.c @@ -62,7 +62,7 @@ #ifdef SHARK_USE_LEDS struct work_struct led_work; struct led_classdev leds[NO_LEDS]; - char led_names[NO_LEDS][32]; + char led_names[NO_LEDS][64]; atomic_t brightness[NO_LEDS]; unsigned long brightness_new; #endif @@ -282,6 +282,16 @@ { struct shark_device *shark; int retval = -ENOMEM; + static const u8 ep_addresses[] = { + SHARK_IN_EP | USB_DIR_IN, + SHARK_OUT_EP | USB_DIR_OUT, + 0}; + + /* Are the expected endpoints present? */ + if (!usb_check_int_endpoints(intf, ep_addresses)) { + dev_err(&intf->dev, "Invalid radioSHARK2 device\n"); + return -EINVAL; + } shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); if (!shark) --- linux-oracle-5.4.0.orig/drivers/media/radio/radio-wl1273.c +++ linux-oracle-5.4.0/drivers/media/radio/radio-wl1273.c @@ -1148,8 +1148,7 @@ if (radio->rds_users > 0) { radio->rds_users--; if (radio->rds_users == 0) { - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; + mutex_lock(&core->lock); radio->irq_flags &= ~WL1273_RDS_EVENT; @@ -1280,7 +1279,7 @@ strscpy(capability->driver, WL1273_FM_DRIVER_NAME, sizeof(capability->driver)); - strscpy(capability->card, "Texas Instruments Wl1273 FM Radio", + strscpy(capability->card, "TI Wl1273 FM Radio", sizeof(capability->card)); strscpy(capability->bus_info, radio->bus_type, sizeof(capability->bus_info)); --- linux-oracle-5.4.0.orig/drivers/media/radio/si470x/radio-si470x-i2c.c +++ linux-oracle-5.4.0/drivers/media/radio/si470x/radio-si470x-i2c.c @@ -11,7 +11,7 @@ /* driver definitions */ #define DRIVER_AUTHOR "Joonyoung Shim "; -#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" +#define DRIVER_CARD "Silicon Labs Si470x FM Radio" #define DRIVER_DESC "I2C radio driver for Si470x FM Radio Receivers" #define DRIVER_VERSION "1.0.2" @@ -368,7 +368,7 @@ if (radio->hdl.error) { retval = radio->hdl.error; dev_err(&client->dev, "couldn't register control\n"); - goto err_dev; + goto err_all; } /* video device initialization */ @@ -463,7 +463,6 @@ return 0; err_all: v4l2_ctrl_handler_free(&radio->hdl); -err_dev: v4l2_device_unregister(&radio->v4l2_dev); err_initial: return retval; @@ -482,6 +481,8 @@ if (radio->gpio_reset) gpiod_set_value(radio->gpio_reset, 0); + v4l2_ctrl_handler_free(&radio->hdl); + v4l2_device_unregister(&radio->v4l2_dev); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/radio/si470x/radio-si470x-usb.c +++ linux-oracle-5.4.0/drivers/media/radio/si470x/radio-si470x-usb.c @@ -16,7 +16,7 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " -#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" +#define DRIVER_CARD "Silicon Labs Si470x FM Radio" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" #define DRIVER_VERSION "1.0.10" @@ -733,8 +733,10 @@ /* start radio */ retval = si470x_start_usb(radio); - if (retval < 0) + if (retval < 0 && !radio->int_in_running) goto err_buf; + else if (retval < 0) /* in case of radio->int_in_running == 1 */ + goto err_all; /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ --- linux-oracle-5.4.0.orig/drivers/media/radio/wl128x/fmdrv_common.c +++ linux-oracle-5.4.0/drivers/media/radio/wl128x/fmdrv_common.c @@ -463,11 +463,12 @@ jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000); return -ETIMEDOUT; } + spin_lock_irqsave(&fmdev->resp_skb_lock, flags); if (!fmdev->resp_skb) { + spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); fmerr("Response SKB is missing\n"); return -EFAULT; } - spin_lock_irqsave(&fmdev->resp_skb_lock, flags); skb = fmdev->resp_skb; fmdev->resp_skb = NULL; spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags); --- linux-oracle-5.4.0.orig/drivers/media/rc/Makefile +++ linux-oracle-5.4.0/drivers/media/rc/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_RC_CORE) += rc-core.o rc-core-y := rc-main.o rc-ir-raw.o rc-core-$(CONFIG_LIRC) += lirc_dev.o +rc-core-$(CONFIG_MEDIA_CEC_RC) += keymaps/rc-cec.o rc-core-$(CONFIG_BPF_LIRC_MODE2) += bpf-lirc.o obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o --- linux-oracle-5.4.0.orig/drivers/media/rc/ati_remote.c +++ linux-oracle-5.4.0/drivers/media/rc/ati_remote.c @@ -835,6 +835,10 @@ err("%s: endpoint_in message size==0? \n", __func__); return -ENODEV; } + if (!usb_endpoint_is_int_out(endpoint_out)) { + err("%s: Unexpected endpoint_out\n", __func__); + return -ENODEV; + } ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); --- linux-oracle-5.4.0.orig/drivers/media/rc/bpf-lirc.c +++ linux-oracle-5.4.0/drivers/media/rc/bpf-lirc.c @@ -329,7 +329,8 @@ } if (attr->query.prog_cnt != 0 && prog_ids && cnt) - ret = bpf_prog_array_copy_to_user(progs, prog_ids, cnt); + ret = bpf_prog_array_copy_to_user(progs, prog_ids, + attr->query.prog_cnt); unlock: mutex_unlock(&ir_raw_handler_lock); --- linux-oracle-5.4.0.orig/drivers/media/rc/ene_ir.c +++ linux-oracle-5.4.0/drivers/media/rc/ene_ir.c @@ -1106,6 +1106,8 @@ struct ene_device *dev = pnp_get_drvdata(pnp_dev); unsigned long flags; + rc_unregister_device(dev->rdev); + del_timer_sync(&dev->tx_sim_timer); spin_lock_irqsave(&dev->hw_lock, flags); ene_rx_disable(dev); ene_rx_restore_hw_buffer(dev); @@ -1113,7 +1115,6 @@ free_irq(dev->irq, dev); release_region(dev->hw_io, ENE_IO_SIZE); - rc_unregister_device(dev->rdev); kfree(dev); } --- linux-oracle-5.4.0.orig/drivers/media/rc/gpio-ir-recv.c +++ linux-oracle-5.4.0/drivers/media/rc/gpio-ir-recv.c @@ -83,6 +83,8 @@ rcdev->map_name = RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; + if (of_property_read_bool(np, "wakeup-source")) + device_init_wakeup(dev, true); rc = devm_rc_register_device(dev, rcdev); if (rc < 0) { --- linux-oracle-5.4.0.orig/drivers/media/rc/gpio-ir-tx.c +++ linux-oracle-5.4.0/drivers/media/rc/gpio-ir-tx.c @@ -79,13 +79,8 @@ // space edge = ktime_add_us(edge, txbuf[i]); delta = ktime_us_delta(edge, ktime_get()); - if (delta > 10) { - spin_unlock_irqrestore(&gpio_ir->lock, flags); - usleep_range(delta, delta + 10); - spin_lock_irqsave(&gpio_ir->lock, flags); - } else if (delta > 0) { + if (delta > 0) udelay(delta); - } } else { // pulse ktime_t last = ktime_add_us(edge, txbuf[i]); --- linux-oracle-5.4.0.orig/drivers/media/rc/igorplugusb.c +++ linux-oracle-5.4.0/drivers/media/rc/igorplugusb.c @@ -64,9 +64,11 @@ if (start >= len) { dev_err(ir->dev, "receive overflow invalid: %u", overflow); } else { - if (overflow > 0) + if (overflow > 0) { dev_warn(ir->dev, "receive overflow, at least %u lost", overflow); + ir_raw_event_reset(ir->rc); + } do { rawir.duration = ir->buf_in[i] * 85333; --- linux-oracle-5.4.0.orig/drivers/media/rc/iguanair.c +++ linux-oracle-5.4.0/drivers/media/rc/iguanair.c @@ -200,8 +200,10 @@ if (rc) return rc; - if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) + if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) { + usb_kill_urb(ir->urb_out); return -ETIMEDOUT; + } return rc; } @@ -413,7 +415,7 @@ int ret, pipein, pipeout; struct usb_host_interface *idesc; - idesc = intf->altsetting; + idesc = intf->cur_altsetting; if (idesc->desc.bNumEndpoints < 2) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/media/rc/imon.c +++ linux-oracle-5.4.0/drivers/media/rc/imon.c @@ -604,15 +604,14 @@ pr_err_ratelimited("error submitting urb(%d)\n", retval); } else { /* Wait for transmission to complete (or abort) */ - mutex_unlock(&ictx->lock); retval = wait_for_completion_interruptible( &ictx->tx.finished); if (retval) { usb_kill_urb(ictx->tx_urb); pr_err_ratelimited("task interrupted\n"); } - mutex_lock(&ictx->lock); + ictx->tx.busy = false; retval = ictx->tx.status; if (retval) pr_err_ratelimited("packet tx failed (%d)\n", retval); @@ -919,7 +918,8 @@ return -ENODEV; } - mutex_lock(&ictx->lock); + if (mutex_lock_interruptible(&ictx->lock)) + return -ERESTARTSYS; if (!ictx->dev_present_intf0) { pr_err_ratelimited("no iMON device present\n"); @@ -1117,10 +1117,7 @@ memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); - if (!mutex_is_locked(&ictx->lock)) { - unlock = true; - mutex_lock(&ictx->lock); - } + unlock = mutex_trylock(&ictx->lock); retval = send_packet(ictx); if (retval) @@ -1598,8 +1595,7 @@ spin_unlock_irqrestore(&ictx->kc_lock, flags); /* send touchscreen events through input subsystem if touchpad data */ - if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && - buf[7] == 0x86) { + if (ictx->touch && len == 8 && buf[7] == 0x86) { imon_touch_event(ictx, buf); return; --- linux-oracle-5.4.0.orig/drivers/media/rc/ir-sharp-decoder.c +++ linux-oracle-5.4.0/drivers/media/rc/ir-sharp-decoder.c @@ -15,7 +15,9 @@ #define SHARP_UNIT 40000 /* ns */ #define SHARP_BIT_PULSE (8 * SHARP_UNIT) /* 320us */ #define SHARP_BIT_0_PERIOD (25 * SHARP_UNIT) /* 1ms (680us space) */ -#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680ms space) */ +#define SHARP_BIT_1_PERIOD (50 * SHARP_UNIT) /* 2ms (1680us space) */ +#define SHARP_BIT_0_SPACE (17 * SHARP_UNIT) /* 680us space */ +#define SHARP_BIT_1_SPACE (42 * SHARP_UNIT) /* 1680us space */ #define SHARP_ECHO_SPACE (1000 * SHARP_UNIT) /* 40 ms */ #define SHARP_TRAILER_SPACE (125 * SHARP_UNIT) /* 5 ms (even longer) */ @@ -168,8 +170,8 @@ .header_pulse = 0, .header_space = 0, .bit_pulse = SHARP_BIT_PULSE, - .bit_space[0] = SHARP_BIT_0_PERIOD, - .bit_space[1] = SHARP_BIT_1_PERIOD, + .bit_space[0] = SHARP_BIT_0_SPACE, + .bit_space[1] = SHARP_BIT_1_SPACE, .trailer_pulse = SHARP_BIT_PULSE, .trailer_space = SHARP_ECHO_SPACE, .msb_first = 1, --- linux-oracle-5.4.0.orig/drivers/media/rc/ite-cir.c +++ linux-oracle-5.4.0/drivers/media/rc/ite-cir.c @@ -276,6 +276,12 @@ /* read the interrupt flags */ iflags = dev->params.get_irq_causes(dev); + /* Check for RX overflow */ + if (iflags & ITE_IRQ_RX_FIFO_OVERRUN) { + dev_warn(&dev->rdev->dev, "receive overflow\n"); + ir_raw_event_reset(dev->rdev); + } + /* check for the receive interrupt */ if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) { /* read the FIFO bytes */ --- linux-oracle-5.4.0.orig/drivers/media/rc/keymaps/Makefile +++ linux-oracle-5.4.0/drivers/media/rc/keymaps/Makefile @@ -20,7 +20,6 @@ rc-behold.o \ rc-behold-columbus.o \ rc-budget-ci-old.o \ - rc-cec.o \ rc-cinergy-1400.o \ rc-cinergy.o \ rc-d680-dmb.o \ @@ -117,6 +116,7 @@ rc-videomate-m1f.o \ rc-videomate-s350.o \ rc-videomate-tv-pvr.o \ + rc-videostrong-kii-pro.o \ rc-wetek-hub.o \ rc-wetek-play2.o \ rc-winfast.o \ --- linux-oracle-5.4.0.orig/drivers/media/rc/keymaps/rc-cec.c +++ linux-oracle-5.4.0/drivers/media/rc/keymaps/rc-cec.c @@ -1,6 +1,16 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* Keytable for the CEC remote control * + * This keymap is unusual in that it can't be built as a module, + * instead it is registered directly in rc-main.c if CONFIG_MEDIA_CEC_RC + * is set. This is because it can be called from drm_dp_cec_set_edid() via + * cec_register_adapter() in an asynchronous context, and it is not + * allowed to use request_module() to load rc-cec.ko in that case. + * + * Since this keymap is only used if CONFIG_MEDIA_CEC_RC is set, we + * just compile this keymap into the rc-core module and never as a + * separate module. + * * Copyright (c) 2015 by Kamil Debski */ @@ -152,7 +162,7 @@ /* 0x77-0xff: Reserved */ }; -static struct rc_map_list cec_map = { +struct rc_map_list cec_map = { .map = { .scan = cec, .size = ARRAY_SIZE(cec), @@ -160,19 +170,3 @@ .name = RC_MAP_CEC, } }; - -static int __init init_rc_map_cec(void) -{ - return rc_map_register(&cec_map); -} - -static void __exit exit_rc_map_cec(void) -{ - rc_map_unregister(&cec_map); -} - -module_init(init_rc_map_cec); -module_exit(exit_rc_map_cec); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kamil Debski"); --- linux-oracle-5.4.0.orig/drivers/media/rc/keymaps/rc-videostrong-kii-pro.c +++ linux-oracle-5.4.0/drivers/media/rc/keymaps/rc-videostrong-kii-pro.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (C) 2019 Mohammad Rasim + +#include +#include + +// +// Keytable for the Videostrong KII Pro STB remote control +// + +static struct rc_map_table kii_pro[] = { + { 0x59, KEY_POWER }, + { 0x19, KEY_MUTE }, + { 0x42, KEY_RED }, + { 0x40, KEY_GREEN }, + { 0x00, KEY_YELLOW }, + { 0x03, KEY_BLUE }, + { 0x4a, KEY_BACK }, + { 0x48, KEY_FORWARD }, + { 0x08, KEY_PREVIOUSSONG}, + { 0x0b, KEY_NEXTSONG}, + { 0x46, KEY_PLAYPAUSE }, + { 0x44, KEY_STOP }, + { 0x1f, KEY_FAVORITES}, //KEY_F5? + { 0x04, KEY_PVR }, + { 0x4d, KEY_EPG }, + { 0x02, KEY_INFO }, + { 0x09, KEY_SUBTITLE }, + { 0x01, KEY_AUDIO }, + { 0x0d, KEY_HOMEPAGE }, + { 0x11, KEY_TV }, // DTV ? + { 0x06, KEY_UP }, + { 0x5a, KEY_LEFT }, + { 0x1a, KEY_ENTER }, // KEY_OK ? + { 0x1b, KEY_RIGHT }, + { 0x16, KEY_DOWN }, + { 0x45, KEY_MENU }, + { 0x05, KEY_ESC }, + { 0x13, KEY_VOLUMEUP }, + { 0x17, KEY_VOLUMEDOWN }, + { 0x58, KEY_APPSELECT }, + { 0x12, KEY_VENDOR }, // mouse + { 0x55, KEY_PAGEUP }, // KEY_CHANNELUP ? + { 0x15, KEY_PAGEDOWN }, // KEY_CHANNELDOWN ? + { 0x52, KEY_1 }, + { 0x50, KEY_2 }, + { 0x10, KEY_3 }, + { 0x56, KEY_4 }, + { 0x54, KEY_5 }, + { 0x14, KEY_6 }, + { 0x4e, KEY_7 }, + { 0x4c, KEY_8 }, + { 0x0c, KEY_9 }, + { 0x18, KEY_WWW }, // KEY_F7 + { 0x0f, KEY_0 }, + { 0x51, KEY_BACKSPACE }, +}; + +static struct rc_map_list kii_pro_map = { + .map = { + .scan = kii_pro, + .size = ARRAY_SIZE(kii_pro), + .rc_proto = RC_PROTO_NEC, + .name = RC_MAP_KII_PRO, + } +}; + +static int __init init_rc_map_kii_pro(void) +{ + return rc_map_register(&kii_pro_map); +} + +static void __exit exit_rc_map_kii_pro(void) +{ + rc_map_unregister(&kii_pro_map); +} + +module_init(init_rc_map_kii_pro) +module_exit(exit_rc_map_kii_pro) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Mohammad Rasim "); --- linux-oracle-5.4.0.orig/drivers/media/rc/lirc_dev.c +++ linux-oracle-5.4.0/drivers/media/rc/lirc_dev.c @@ -292,7 +292,11 @@ if (ret < 0) goto out_kfree_raw; - count = ret; + /* drop trailing space */ + if (!(ret % 2)) + count = ret - 1; + else + count = ret; txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL); if (!txbuf) { --- linux-oracle-5.4.0.orig/drivers/media/rc/mceusb.c +++ linux-oracle-5.4.0/drivers/media/rc/mceusb.c @@ -564,7 +564,7 @@ datasize = 4; break; case MCE_CMD_G_REVISION: - datasize = 2; + datasize = 4; break; case MCE_RSP_EQWAKESUPPORT: case MCE_RSP_GETWAKESOURCE: @@ -600,14 +600,9 @@ char *inout; u8 cmd, subcmd, *data; struct device *dev = ir->dev; - int start, skip = 0; u32 carrier, period; - /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ - if (ir->flags.microsoft_gen1 && !out && !offset) - skip = 2; - - if (len <= skip) + if (offset < 0 || offset >= buf_len) return; dev_dbg(dev, "%cx data[%d]: %*ph (len=%d sz=%d)", @@ -616,11 +611,32 @@ inout = out ? "Request" : "Got"; - start = offset + skip; - cmd = buf[start] & 0xff; - subcmd = buf[start + 1] & 0xff; - data = buf + start + 2; + cmd = buf[offset]; + subcmd = (offset + 1 < buf_len) ? buf[offset + 1] : 0; + data = &buf[offset] + 2; + + /* Trace meaningless 0xb1 0x60 header bytes on original receiver */ + if (ir->flags.microsoft_gen1 && !out && !offset) { + dev_dbg(dev, "MCE gen 1 header"); + return; + } + /* Trace IR data header or trailer */ + if (cmd != MCE_CMD_PORT_IR && + (cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA) { + if (cmd == MCE_IRDATA_TRAILER) + dev_dbg(dev, "End of raw IR data"); + else + dev_dbg(dev, "Raw IR data, %d pulse/space samples", + cmd & MCE_PACKET_LENGTH_MASK); + return; + } + + /* Unexpected end of buffer? */ + if (offset + len > buf_len) + return; + + /* Decode MCE command/response */ switch (cmd) { case MCE_CMD_NULL: if (subcmd == MCE_CMD_NULL) @@ -644,7 +660,7 @@ dev_dbg(dev, "Get hw/sw rev?"); else dev_dbg(dev, "hw/sw rev %*ph", - 4, &buf[start + 2]); + 4, &buf[offset + 2]); break; case MCE_CMD_RESUME: dev_dbg(dev, "Device resume requested"); @@ -685,11 +701,18 @@ data[0], data[1]); break; case MCE_RSP_EQIRCFS: + if (!data[0] && !data[1]) { + dev_dbg(dev, "%s: no carrier", inout); + break; + } + // prescaler should make sense + if (data[0] > 8) + break; period = DIV_ROUND_CLOSEST((1U << data[0] * 2) * (data[1] + 1), 10); if (!period) break; - carrier = (1000 * 1000) / period; + carrier = USEC_PER_SEC / period; dev_dbg(dev, "%s carrier of %u Hz (period %uus)", inout, carrier, period); break; @@ -746,13 +769,6 @@ default: break; } - - if (cmd == MCE_IRDATA_TRAILER) - dev_dbg(dev, "End of raw IR data"); - else if ((cmd != MCE_CMD_PORT_IR) && - ((cmd & MCE_PORT_MASK) == MCE_COMMAND_IRDATA)) - dev_dbg(dev, "Raw IR data, %d pulse/space samples", - cmd & MCE_PACKET_LENGTH_MASK); #endif } @@ -1136,32 +1152,62 @@ } /* + * Handle PORT_SYS/IR command response received from the MCE device. + * + * Assumes single response with all its data (not truncated) + * in buf_in[]. The response itself determines its total length + * (mceusb_cmd_datasize() + 2) and hence the minimum size of buf_in[]. + * * We don't do anything but print debug spew for many of the command bits * we receive from the hardware, but some of them are useful information * we want to store so that we can use them. */ -static void mceusb_handle_command(struct mceusb_dev *ir, int index) +static void mceusb_handle_command(struct mceusb_dev *ir, u8 *buf_in) { + u8 cmd = buf_in[0]; + u8 subcmd = buf_in[1]; + u8 *hi = &buf_in[2]; /* read only when required */ + u8 *lo = &buf_in[3]; /* read only when required */ struct ir_raw_event rawir = {}; - u8 hi = ir->buf_in[index + 1] & 0xff; - u8 lo = ir->buf_in[index + 2] & 0xff; u32 carrier_cycles; u32 cycles_fix; - switch (ir->buf_in[index]) { - /* the one and only 5-byte return value command */ - case MCE_RSP_GETPORTSTATUS: - if ((ir->buf_in[index + 4] & 0xff) == 0x00) - ir->txports_cabled |= 1 << hi; - break; + if (cmd == MCE_CMD_PORT_SYS) { + switch (subcmd) { + /* the one and only 5-byte return value command */ + case MCE_RSP_GETPORTSTATUS: + if (buf_in[5] == 0 && *hi < 8) + ir->txports_cabled |= 1 << *hi; + break; + + /* 1-byte return value commands */ + case MCE_RSP_EQEMVER: + ir->emver = *hi; + break; + /* No return value commands */ + case MCE_RSP_CMD_ILLEGAL: + ir->need_reset = true; + break; + + default: + break; + } + + return; + } + + if (cmd != MCE_CMD_PORT_IR) + return; + + switch (subcmd) { /* 2-byte return value commands */ case MCE_RSP_EQIRTIMEOUT: - ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT); + ir->rc->timeout = US_TO_NS((*hi << 8 | *lo) * MCE_TIME_UNIT); break; case MCE_RSP_EQIRNUMPORTS: - ir->num_txports = hi; - ir->num_rxports = lo; + ir->num_txports = *hi; + ir->num_rxports = *lo; break; case MCE_RSP_EQIRRXCFCNT: /* @@ -1174,7 +1220,7 @@ */ if (ir->carrier_report_enabled && ir->learning_active && ir->pulse_tunit > 0) { - carrier_cycles = (hi << 8 | lo); + carrier_cycles = (*hi << 8 | *lo); /* * Adjust carrier cycle count by adding * 1 missed count per pulse "on" @@ -1192,24 +1238,24 @@ break; /* 1-byte return value commands */ - case MCE_RSP_EQEMVER: - ir->emver = hi; - break; case MCE_RSP_EQIRTXPORTS: - ir->tx_mask = hi; + ir->tx_mask = *hi; break; case MCE_RSP_EQIRRXPORTEN: - ir->learning_active = ((hi & 0x02) == 0x02); - if (ir->rxports_active != hi) { + ir->learning_active = ((*hi & 0x02) == 0x02); + if (ir->rxports_active != *hi) { dev_info(ir->dev, "%s-range (0x%x) receiver active", - ir->learning_active ? "short" : "long", hi); - ir->rxports_active = hi; + ir->learning_active ? "short" : "long", *hi); + ir->rxports_active = *hi; } break; + + /* No return value commands */ case MCE_RSP_CMD_ILLEGAL: case MCE_RSP_TX_TIMEOUT: ir->need_reset = true; break; + default: break; } @@ -1235,7 +1281,8 @@ ir->rem = mceusb_cmd_datasize(ir->cmd, ir->buf_in[i]); mceusb_dev_printdata(ir, ir->buf_in, buf_len, i - 1, ir->rem + 2, false); - mceusb_handle_command(ir, i); + if (i + ir->rem < buf_len) + mceusb_handle_command(ir, &ir->buf_in[i - 1]); ir->parser_state = CMD_DATA; break; case PARSE_IRDATA: @@ -1264,15 +1311,22 @@ ir->rem--; break; case CMD_HEADER: - /* decode mce packets of the form (84),AA,BB,CC,DD */ - /* IR data packets can span USB messages - rem */ ir->cmd = ir->buf_in[i]; if ((ir->cmd == MCE_CMD_PORT_IR) || ((ir->cmd & MCE_PORT_MASK) != MCE_COMMAND_IRDATA)) { + /* + * got PORT_SYS, PORT_IR, or unknown + * command response prefix + */ ir->parser_state = SUBCMD; continue; } + /* + * got IR data prefix (0x80 + num_bytes) + * decode MCE packets of the form {0x83, AA, BB, CC} + * IR data packets can span USB messages + */ ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); mceusb_dev_printdata(ir, ir->buf_in, buf_len, i, ir->rem + 1, false); @@ -1296,6 +1350,14 @@ if (ir->parser_state != CMD_HEADER && !ir->rem) ir->parser_state = CMD_HEADER; } + + /* + * Accept IR data spanning multiple rx buffers. + * Reject MCE command response spanning multiple rx buffers. + */ + if (ir->parser_state != PARSE_IRDATA || !ir->rem) + ir->parser_state = CMD_HEADER; + if (event) { dev_dbg(ir->dev, "processed IR data"); ir_raw_event_handle(ir->rc); @@ -1324,6 +1386,7 @@ case -ECONNRESET: case -ENOENT: case -EILSEQ: + case -EPROTO: case -ESHUTDOWN: usb_unlink_urb(urb); return; @@ -1353,42 +1416,37 @@ { int ret; struct device *dev = ir->dev; - char *data; - - data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL); - if (!data) { - dev_err(dev, "%s: memory allocation failed!", __func__); - return; - } + char data[USB_CTRL_MSG_SZ]; /* * This is a strange one. Windows issues a set address to the device * on the receive control pipe and expect a certain value pair back */ - ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), - USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, - data, USB_CTRL_MSG_SZ, HZ * 3); + ret = usb_control_msg_recv(ir->usbdev, 0, USB_REQ_SET_ADDRESS, + USB_DIR_IN | USB_TYPE_VENDOR, + 0, 0, data, USB_CTRL_MSG_SZ, 3000, + GFP_KERNEL); dev_dbg(dev, "set address - ret = %d", ret); dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", data[0], data[1]); /* set feature: bit rate 38400 bps */ - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), - USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, - 0xc04e, 0x0000, NULL, 0, HZ * 3); + ret = usb_control_msg_send(ir->usbdev, 0, + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, + 0xc04e, 0x0000, NULL, 0, 3000, GFP_KERNEL); dev_dbg(dev, "set feature - ret = %d", ret); /* bRequest 4: set char length to 8 bits */ - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), - 4, USB_TYPE_VENDOR, - 0x0808, 0x0000, NULL, 0, HZ * 3); + ret = usb_control_msg_send(ir->usbdev, 0, + 4, USB_TYPE_VENDOR, + 0x0808, 0x0000, NULL, 0, 3000, GFP_KERNEL); dev_dbg(dev, "set char length - retB = %d", ret); /* bRequest 2: set handshaking to use DTR/DSR */ - ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), - 2, USB_TYPE_VENDOR, - 0x0000, 0x0100, NULL, 0, HZ * 3); + ret = usb_control_msg_send(ir->usbdev, 0, + 2, USB_TYPE_VENDOR, + 0x0000, 0x0100, NULL, 0, 3000, GFP_KERNEL); dev_dbg(dev, "set handshake - retC = %d", ret); /* device resume */ @@ -1396,8 +1454,6 @@ /* get hw/sw revision? */ mce_command_out(ir, GET_REVISION, sizeof(GET_REVISION)); - - kfree(data); } static void mceusb_gen2_init(struct mceusb_dev *ir) --- linux-oracle-5.4.0.orig/drivers/media/rc/rc-loopback.c +++ linux-oracle-5.4.0/drivers/media/rc/rc-loopback.c @@ -42,7 +42,7 @@ if ((mask & (RXMASK_REGULAR | RXMASK_LEARNING)) != mask) { dprintk("invalid tx mask: %u\n", mask); - return -EINVAL; + return 2; } dprintk("setting tx mask: %u\n", mask); --- linux-oracle-5.4.0.orig/drivers/media/rc/rc-main.c +++ linux-oracle-5.4.0/drivers/media/rc/rc-main.c @@ -1256,6 +1256,10 @@ } mutex_lock(&dev->lock); + if (!dev->registered) { + mutex_unlock(&dev->lock); + return -ENODEV; + } old_protocols = *current_protocols; new_protocols = old_protocols; @@ -1394,6 +1398,10 @@ return -EINVAL; mutex_lock(&dev->lock); + if (!dev->registered) { + mutex_unlock(&dev->lock); + return -ENODEV; + } new_filter = *filter; if (fattr->mask) @@ -1508,6 +1516,10 @@ int i; mutex_lock(&dev->lock); + if (!dev->registered) { + mutex_unlock(&dev->lock); + return -ENODEV; + } allowed = dev->allowed_wakeup_protocols; @@ -1565,25 +1577,25 @@ kfree(dev); } -#define ADD_HOTPLUG_VAR(fmt, val...) \ - do { \ - int err = add_uevent_var(env, fmt, val); \ - if (err) \ - return err; \ - } while (0) - static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env) { struct rc_dev *dev = to_rc_dev(device); + int ret = 0; + + mutex_lock(&dev->lock); - if (dev->rc_map.name) - ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name); - if (dev->driver_name) - ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name); - if (dev->device_name) - ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name); + if (!dev->registered) + ret = -ENODEV; + if (ret == 0 && dev->rc_map.name) + ret = add_uevent_var(env, "NAME=%s", dev->rc_map.name); + if (ret == 0 && dev->driver_name) + ret = add_uevent_var(env, "DRV_NAME=%s", dev->driver_name); + if (ret == 0 && dev->device_name) + ret = add_uevent_var(env, "DEV_NAME=%s", dev->device_name); - return 0; + mutex_unlock(&dev->lock); + + return ret; } /* @@ -1773,6 +1785,7 @@ set_bit(MSC_SCAN, dev->input_dev->mscbit); /* Pointer/mouse events */ + set_bit(INPUT_PROP_POINTING_STICK, dev->input_dev->propbit); set_bit(EV_REL, dev->input_dev->evbit); set_bit(REL_X, dev->input_dev->relbit); set_bit(REL_Y, dev->input_dev->relbit); @@ -1879,6 +1892,8 @@ goto out_raw; } + dev->registered = true; + rc = device_add(&dev->dev); if (rc) goto out_rx_free; @@ -1888,25 +1903,28 @@ dev->device_name ?: "Unspecified device", path ?: "N/A"); kfree(path); - dev->registered = true; + /* + * once the the input device is registered in rc_setup_rx_device, + * userspace can open the input device and rc_open() will be called + * as a result. This results in driver code being allowed to submit + * keycodes with rc_keydown, so lirc must be registered first. + */ + if (dev->allowed_protocols != RC_PROTO_BIT_CEC) { + rc = ir_lirc_register(dev); + if (rc < 0) + goto out_dev; + } if (dev->driver_type != RC_DRIVER_IR_RAW_TX) { rc = rc_setup_rx_device(dev); if (rc) - goto out_dev; - } - - /* Ensure that the lirc kfifo is setup before we start the thread */ - if (dev->allowed_protocols != RC_PROTO_BIT_CEC) { - rc = ir_lirc_register(dev); - if (rc < 0) - goto out_rx; + goto out_lirc; } if (dev->driver_type == RC_DRIVER_IR_RAW) { rc = ir_raw_event_register(dev); if (rc < 0) - goto out_lirc; + goto out_rx; } dev_dbg(&dev->dev, "Registered rc%u (driver: %s)\n", dev->minor, @@ -1914,11 +1932,11 @@ return 0; +out_rx: + rc_free_rx_device(dev); out_lirc: if (dev->allowed_protocols != RC_PROTO_BIT_CEC) ir_lirc_unregister(dev); -out_rx: - rc_free_rx_device(dev); out_dev: device_del(&dev->dev); out_rx_free: @@ -1969,14 +1987,14 @@ del_timer_sync(&dev->timer_keyup); del_timer_sync(&dev->timer_repeat); - rc_free_rx_device(dev); - mutex_lock(&dev->lock); if (dev->users && dev->close) dev->close(dev); dev->registered = false; mutex_unlock(&dev->lock); + rc_free_rx_device(dev); + /* * lirc device should be freed with dev->registered = false, so * that userspace polling will get notified. @@ -2015,6 +2033,9 @@ led_trigger_register_simple("rc-feedback", &led_feedback); rc_map_register(&empty_map); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_register(&cec_map); +#endif return 0; } @@ -2024,6 +2045,9 @@ lirc_dev_exit(); class_unregister(&rc_class); led_trigger_unregister_simple(led_feedback); +#ifdef CONFIG_MEDIA_CEC_RC + rc_map_unregister(&cec_map); +#endif rc_map_unregister(&empty_map); } --- linux-oracle-5.4.0.orig/drivers/media/rc/redrat3.c +++ linux-oracle-5.4.0/drivers/media/rc/redrat3.c @@ -405,7 +405,7 @@ udev = rr3->udev; res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0x0000, 0x0000, data, sizeof(u8), HZ * 10); + 0x0000, 0x0000, data, sizeof(u8), 10000); if (res < 0) { dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d", @@ -481,7 +481,7 @@ pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); + RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000); if (ret != len) dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); else { @@ -511,7 +511,7 @@ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout), - HZ * 25); + 25000); dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n", be32_to_cpu(*timeout), ret); @@ -543,32 +543,32 @@ *val = 0x01; rc = usb_control_msg(udev, rxpipe, RR3_RESET, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25); + RR3_CPUCS_REG_ADDR, 0, val, len, 25000); dev_dbg(dev, "reset returned 0x%02x\n", rc); *val = length_fuzz; rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25); + RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000); dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc); *val = (65536 - (minimum_pause * 2000)) / 256; rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25); + RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000); dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc); *val = periods_measure_carrier; rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25); + RR3_IR_IO_PERIODS_MF, 0, val, len, 25000); dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val, rc); *val = RR3_DRIVER_MAXLENS; rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, - RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25); + RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000); dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc); kfree(val); @@ -586,7 +586,7 @@ rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0), RR3_FW_VERSION, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5); + 0, 0, buffer, RR3_FW_VERSION_LEN, 5000); if (rc >= 0) dev_info(rr3->dev, "Firmware rev: %s", buffer); @@ -826,14 +826,14 @@ pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); ret = usb_bulk_msg(rr3->udev, pipe, irdata, - sendbuf_len, &ret_len, 10 * HZ); + sendbuf_len, &ret_len, 10000); dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret); /* now tell the hardware to transmit what we sent it */ pipe = usb_rcvctrlpipe(rr3->udev, 0); ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, - 0, 0, irdata, 2, HZ * 10); + 0, 0, irdata, 2, 10000); if (ret < 0) dev_err(dev, "Error: control msg send failed, rc %d\n", ret); --- linux-oracle-5.4.0.orig/drivers/media/rc/sunxi-cir.c +++ linux-oracle-5.4.0/drivers/media/rc/sunxi-cir.c @@ -137,6 +137,8 @@ } else if (status & REG_RXSTA_RPE) { ir_raw_event_set_idle(ir->rc, true); ir_raw_event_handle(ir->rc); + } else { + ir_raw_event_handle(ir->rc); } spin_unlock(&ir->ir_lock); --- linux-oracle-5.4.0.orig/drivers/media/spi/cxd2880-spi.c +++ linux-oracle-5.4.0/drivers/media/spi/cxd2880-spi.c @@ -524,13 +524,13 @@ if (IS_ERR(dvb_spi->vcc_supply)) { if (PTR_ERR(dvb_spi->vcc_supply) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; - goto fail_adapter; + goto fail_regulator; } dvb_spi->vcc_supply = NULL; } else { ret = regulator_enable(dvb_spi->vcc_supply); if (ret) - goto fail_adapter; + goto fail_regulator; } dvb_spi->spi = spi; @@ -618,6 +618,9 @@ fail_attach: dvb_unregister_adapter(&dvb_spi->adapter); fail_adapter: + if (dvb_spi->vcc_supply) + regulator_disable(dvb_spi->vcc_supply); +fail_regulator: kfree(dvb_spi); return ret; } --- linux-oracle-5.4.0.orig/drivers/media/tuners/fc0011.c +++ linux-oracle-5.4.0/drivers/media/tuners/fc0011.c @@ -499,7 +499,7 @@ return fe; } -EXPORT_SYMBOL(fc0011_attach); +EXPORT_SYMBOL_GPL(fc0011_attach); MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver"); MODULE_AUTHOR("Michael Buesch "); --- linux-oracle-5.4.0.orig/drivers/media/tuners/fc0012.c +++ linux-oracle-5.4.0/drivers/media/tuners/fc0012.c @@ -495,7 +495,7 @@ return fe; } -EXPORT_SYMBOL(fc0012_attach); +EXPORT_SYMBOL_GPL(fc0012_attach); MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver"); MODULE_AUTHOR("Hans-Frieder Vogt "); --- linux-oracle-5.4.0.orig/drivers/media/tuners/fc0013.c +++ linux-oracle-5.4.0/drivers/media/tuners/fc0013.c @@ -608,7 +608,7 @@ return fe; } -EXPORT_SYMBOL(fc0013_attach); +EXPORT_SYMBOL_GPL(fc0013_attach); MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver"); MODULE_AUTHOR("Hans-Frieder Vogt "); --- linux-oracle-5.4.0.orig/drivers/media/tuners/m88rs6000t.c +++ linux-oracle-5.4.0/drivers/media/tuners/m88rs6000t.c @@ -525,7 +525,7 @@ PGA2_cri = PGA2_GC >> 2; PGA2_crf = PGA2_GC & 0x03; - for (i = 0; i <= RF_GC; i++) + for (i = 0; i <= RF_GC && i < ARRAY_SIZE(RFGS); i++) RFG += RFGS[i]; if (RF_GC == 0) @@ -537,12 +537,12 @@ if (RF_GC == 3) RFG += 100; - for (i = 0; i <= IF_GC; i++) + for (i = 0; i <= IF_GC && i < ARRAY_SIZE(IFGS); i++) IFG += IFGS[i]; TIAG = TIA_GC * TIA_GS; - for (i = 0; i <= BB_GC; i++) + for (i = 0; i <= BB_GC && i < ARRAY_SIZE(BBGS); i++) BBG += BBGS[i]; PGA2G = PGA2_cri * PGA2_cri_GS + PGA2_crf * PGA2_crf_GS; --- linux-oracle-5.4.0.orig/drivers/media/tuners/max2165.c +++ linux-oracle-5.4.0/drivers/media/tuners/max2165.c @@ -410,7 +410,7 @@ return fe; } -EXPORT_SYMBOL(max2165_attach); +EXPORT_SYMBOL_GPL(max2165_attach); MODULE_AUTHOR("David T. L. Wong "); MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/mc44s803.c +++ linux-oracle-5.4.0/drivers/media/tuners/mc44s803.c @@ -356,7 +356,7 @@ kfree(priv); return NULL; } -EXPORT_SYMBOL(mc44s803_attach); +EXPORT_SYMBOL_GPL(mc44s803_attach); MODULE_AUTHOR("Jochen Friedrich"); MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/msi001.c +++ linux-oracle-5.4.0/drivers/media/tuners/msi001.c @@ -442,6 +442,13 @@ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000); + if (dev->hdl.error) { + ret = dev->hdl.error; + dev_err(&spi->dev, "Could not initialize controls\n"); + /* control init failed, free handler */ + goto err_ctrl_handler_free; + } + v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1); --- linux-oracle-5.4.0.orig/drivers/media/tuners/mt2060.c +++ linux-oracle-5.4.0/drivers/media/tuners/mt2060.c @@ -440,7 +440,7 @@ return fe; } -EXPORT_SYMBOL(mt2060_attach); +EXPORT_SYMBOL_GPL(mt2060_attach); static int mt2060_probe(struct i2c_client *client, const struct i2c_device_id *id) --- linux-oracle-5.4.0.orig/drivers/media/tuners/mt2131.c +++ linux-oracle-5.4.0/drivers/media/tuners/mt2131.c @@ -274,7 +274,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(mt2131_attach); +EXPORT_SYMBOL_GPL(mt2131_attach); MODULE_AUTHOR("Steven Toth"); MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/mt2266.c +++ linux-oracle-5.4.0/drivers/media/tuners/mt2266.c @@ -336,7 +336,7 @@ mt2266_calibrate(priv); return fe; } -EXPORT_SYMBOL(mt2266_attach); +EXPORT_SYMBOL_GPL(mt2266_attach); MODULE_AUTHOR("Olivier DANET"); MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/mxl5005s.c +++ linux-oracle-5.4.0/drivers/media/tuners/mxl5005s.c @@ -4114,7 +4114,7 @@ fe->tuner_priv = state; return fe; } -EXPORT_SYMBOL(mxl5005s_attach); +EXPORT_SYMBOL_GPL(mxl5005s_attach); MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); MODULE_AUTHOR("Steven Toth"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/qm1d1c0042.c +++ linux-oracle-5.4.0/drivers/media/tuners/qm1d1c0042.c @@ -343,8 +343,10 @@ if (val == reg_initval[reg_index][0x00]) break; } - if (reg_index >= QM1D1C0042_NUM_REG_ROWS) + if (reg_index >= QM1D1C0042_NUM_REG_ROWS) { + ret = -EINVAL; goto failed; + } memcpy(state->regs, reg_initval[reg_index], QM1D1C0042_NUM_REGS); usleep_range(2000, 3000); --- linux-oracle-5.4.0.orig/drivers/media/tuners/qt1010.c +++ linux-oracle-5.4.0/drivers/media/tuners/qt1010.c @@ -215,7 +215,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv, u8 oper, u8 reg, u8 reg_init_val, u8 *retval) { - u8 i, val1, uninitialized_var(val2); + u8 i, val1, val2; int err; qt1010_i2c_oper_t i2c_data[] = { @@ -250,7 +250,7 @@ static int qt1010_init_meas2(struct qt1010_priv *priv, u8 reg_init_val, u8 *retval) { - u8 i, uninitialized_var(val); + u8 i, val; int err; qt1010_i2c_oper_t i2c_data[] = { { QT1010_WR, 0x07, reg_init_val }, @@ -342,11 +342,12 @@ else valptr = &tmpval; - BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1); - - err = qt1010_init_meas1(priv, i2c_data[i+1].reg, - i2c_data[i].reg, - i2c_data[i].val, valptr); + if (i >= ARRAY_SIZE(i2c_data) - 1) + err = -EIO; + else + err = qt1010_init_meas1(priv, i2c_data[i + 1].reg, + i2c_data[i].reg, + i2c_data[i].val, valptr); i++; break; } @@ -437,7 +438,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(qt1010_attach); +EXPORT_SYMBOL_GPL(qt1010_attach); MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); --- linux-oracle-5.4.0.orig/drivers/media/tuners/si2157.c +++ linux-oracle-5.4.0/drivers/media/tuners/si2157.c @@ -75,24 +75,23 @@ struct si2157_cmd cmd; const struct firmware *fw; const char *fw_name; - unsigned int uitmp, chip_id; + unsigned int chip_id, xtal_trim; dev_dbg(&client->dev, "\n"); - /* Returned IF frequency is garbage when firmware is not running */ - memcpy(cmd.args, "\x15\x00\x06\x07", 4); + /* Try to get Xtal trim property, to verify tuner still running */ + memcpy(cmd.args, "\x15\x00\x02\x04", 4); cmd.wlen = 4; cmd.rlen = 4; ret = si2157_cmd_execute(client, &cmd); - if (ret) - goto err; - uitmp = cmd.args[2] << 0 | cmd.args[3] << 8; - dev_dbg(&client->dev, "if_frequency kHz=%u\n", uitmp); + xtal_trim = cmd.args[2] | (cmd.args[3] << 8); - if (uitmp == dev->if_frequency / 1000) + if (ret == 0 && xtal_trim < 16) goto warm; + dev->if_frequency = 0; /* we no longer know current tuner state */ + /* power up */ if (dev->chiptype == SI2157_CHIPTYPE_SI2146) { memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9); --- linux-oracle-5.4.0.orig/drivers/media/tuners/tda18218.c +++ linux-oracle-5.4.0/drivers/media/tuners/tda18218.c @@ -336,7 +336,7 @@ return fe; } -EXPORT_SYMBOL(tda18218_attach); +EXPORT_SYMBOL_GPL(tda18218_attach); MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); --- linux-oracle-5.4.0.orig/drivers/media/tuners/tuner-simple.c +++ linux-oracle-5.4.0/drivers/media/tuners/tuner-simple.c @@ -500,7 +500,7 @@ case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n"); - return 0; + return -EINVAL; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FMD1216ME_MK3: @@ -702,7 +702,8 @@ TUNER_RATIO_SELECT_50; /* 50 kHz step */ /* Bandswitch byte */ - simple_radio_bandswitch(fe, &buffer[0]); + if (simple_radio_bandswitch(fe, &buffer[0])) + return 0; /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) = --- linux-oracle-5.4.0.orig/drivers/media/tuners/tuner-xc2028.c +++ linux-oracle-5.4.0/drivers/media/tuners/tuner-xc2028.c @@ -1361,9 +1361,16 @@ void *context) { struct dvb_frontend *fe = context; - struct xc2028_data *priv = fe->tuner_priv; + struct xc2028_data *priv; int rc; + if (!fe) { + pr_warn("xc2028: No frontend in %s\n", __func__); + return; + } + + priv = fe->tuner_priv; + tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); if (!fw) { tuner_err("Could not load firmware %s.\n", priv->fname); --- linux-oracle-5.4.0.orig/drivers/media/tuners/xc4000.c +++ linux-oracle-5.4.0/drivers/media/tuners/xc4000.c @@ -1517,10 +1517,10 @@ { struct xc4000_priv *priv = fe->tuner_priv; + mutex_lock(&priv->lock); *freq = priv->freq_hz + priv->freq_offset; if (debug) { - mutex_lock(&priv->lock); if ((priv->cur_fw.type & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) { u16 snr = 0; @@ -1531,8 +1531,8 @@ return 0; } } - mutex_unlock(&priv->lock); } + mutex_unlock(&priv->lock); dprintk(1, "%s()\n", __func__); @@ -1744,7 +1744,7 @@ xc4000_release(fe); return NULL; } -EXPORT_SYMBOL(xc4000_attach); +EXPORT_SYMBOL_GPL(xc4000_attach); MODULE_AUTHOR("Steven Toth, Davide Ferri"); MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/tuners/xc5000.c +++ linux-oracle-5.4.0/drivers/media/tuners/xc5000.c @@ -1460,7 +1460,7 @@ xc5000_release(fe); return NULL; } -EXPORT_SYMBOL(xc5000_attach); +EXPORT_SYMBOL_GPL(xc5000_attach); MODULE_AUTHOR("Steven Toth"); MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver"); --- linux-oracle-5.4.0.orig/drivers/media/usb/au0828/au0828-core.c +++ linux-oracle-5.4.0/drivers/media/usb/au0828/au0828-core.c @@ -199,8 +199,8 @@ struct media_device *mdev; mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE); - if (!mdev) - return -ENOMEM; + if (IS_ERR(mdev)) + return PTR_ERR(mdev); dev->media_dev = mdev; #endif --- linux-oracle-5.4.0.orig/drivers/media/usb/b2c2/flexcop-usb.c +++ linux-oracle-5.4.0/drivers/media/usb/b2c2/flexcop-usb.c @@ -87,7 +87,7 @@ 0, fc_usb->data, sizeof(u32), - B2C2_WAIT_FOR_OPERATION_RDW * HZ); + B2C2_WAIT_FOR_OPERATION_RDW); if (ret != sizeof(u32)) { err("error while %s dword from %d (%d).", read ? "reading" : @@ -155,7 +155,7 @@ wIndex, fc_usb->data, buflen, - nWaitTime * HZ); + nWaitTime); if (ret != buflen) ret = -EIO; @@ -249,13 +249,13 @@ /* DKT 020208 - add this to support special case of DiSEqC */ case USB_FUNC_I2C_CHECKWRITE: pipe = B2C2_USB_CTRL_PIPE_OUT; - nWaitTime = 2; + nWaitTime = 2000; request_type |= USB_DIR_OUT; break; case USB_FUNC_I2C_READ: case USB_FUNC_I2C_REPEATREAD: pipe = B2C2_USB_CTRL_PIPE_IN; - nWaitTime = 2; + nWaitTime = 2000; request_type |= USB_DIR_IN; break; default: @@ -282,7 +282,7 @@ wIndex, fc_usb->data, buflen, - nWaitTime * HZ); + nWaitTime); if (ret != buflen) ret = -EIO; @@ -295,7 +295,7 @@ mutex_unlock(&fc_usb->data_mutex); - return 0; + return ret; } /* actual bus specific access functions, @@ -504,7 +504,16 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb) { /* use the alternate setting with the larges buffer */ - usb_set_interface(fc_usb->udev,0,1); + int ret = usb_set_interface(fc_usb->udev, 0, 1); + + if (ret) { + err("set interface failed."); + return ret; + } + + if (fc_usb->uintf->cur_altsetting->desc.bNumEndpoints < 1) + return -ENODEV; + switch (fc_usb->udev->speed) { case USB_SPEED_LOW: err("cannot handle USB speed because it is too slow."); --- linux-oracle-5.4.0.orig/drivers/media/usb/b2c2/flexcop-usb.h +++ linux-oracle-5.4.0/drivers/media/usb/b2c2/flexcop-usb.h @@ -91,13 +91,13 @@ UTILITY_SRAM_TESTVERIFY = 0x16, } flexcop_usb_utility_function_t; -#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) -#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) +#define B2C2_WAIT_FOR_OPERATION_RW 1000 +#define B2C2_WAIT_FOR_OPERATION_RDW 3000 +#define B2C2_WAIT_FOR_OPERATION_WDW 1000 -#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) -#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) +#define B2C2_WAIT_FOR_OPERATION_V8READ 3000 +#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3000 +#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3000 typedef enum { V8_MEMORY_PAGE_DVB_CI = 0x20, --- linux-oracle-5.4.0.orig/drivers/media/usb/cpia2/cpia2.h +++ linux-oracle-5.4.0/drivers/media/usb/cpia2/cpia2.h @@ -429,6 +429,7 @@ int cpia2_do_command(struct camera_data *cam, unsigned int command, unsigned char direction, unsigned char param); +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); --- linux-oracle-5.4.0.orig/drivers/media/usb/cpia2/cpia2_core.c +++ linux-oracle-5.4.0/drivers/media/usb/cpia2/cpia2_core.c @@ -2167,6 +2167,18 @@ * * cpia2_init_camera_struct * + * Deinitialize camera struct + *****************************************************************************/ +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) +{ + v4l2_device_unregister(&cam->v4l2_dev); + kfree(cam); +} + +/****************************************************************************** + * + * cpia2_init_camera_struct + * * Initializes camera struct, does not call reset to fill in defaults. *****************************************************************************/ struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf) --- linux-oracle-5.4.0.orig/drivers/media/usb/cpia2/cpia2_usb.c +++ linux-oracle-5.4.0/drivers/media/usb/cpia2/cpia2_usb.c @@ -550,7 +550,7 @@ 0, /* index */ buf, /* buffer */ size, - HZ); + 1000); kfree(buf); return ret; @@ -582,7 +582,7 @@ 0, /* index */ buf, /* buffer */ size, - HZ); + 1000); if (ret >= 0) memcpy(registers, buf, size); @@ -844,15 +844,13 @@ ret = set_alternate(cam, USBIF_CMDONLY); if (ret < 0) { ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } if((ret = cpia2_init_camera(cam)) < 0) { ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } LOG(" CPiA Version: %d.%02d (%d.%d)\n", cam->params.version.firmware_revision_hi, @@ -872,11 +870,14 @@ ret = cpia2_register_camera(cam); if (ret < 0) { ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } return 0; + +alt_err: + cpia2_deinit_camera_struct(cam, intf); + return ret; } /****************************************************************************** --- linux-oracle-5.4.0.orig/drivers/media/usb/cx231xx/cx231xx-cards.c +++ linux-oracle-5.4.0/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -994,6 +994,8 @@ /* table of devices that work with this driver */ struct usb_device_id cx231xx_id_table[] = { + {USB_DEVICE(0x1D19, 0x6108), + .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, {USB_DEVICE(0x1D19, 0x6109), .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB}, {USB_DEVICE(0x0572, 0x5A3C), --- linux-oracle-5.4.0.orig/drivers/media/usb/cx231xx/cx231xx-core.c +++ linux-oracle-5.4.0/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1028,6 +1028,7 @@ if (!dev->video_mode.isoc_ctl.urb) { dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); + kfree(dma_q->p_left_data); return -ENOMEM; } @@ -1037,6 +1038,7 @@ dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); + kfree(dma_q->p_left_data); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/af9035.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/af9035.c @@ -269,6 +269,7 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); struct state *state = d_to_priv(d); int ret; + u32 reg; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -321,8 +322,12 @@ ret = -EOPNOTSUPP; } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || (msg[0].addr == state->af9033_i2c_addr[1])) { + if (msg[0].len < 3 || msg[1].len < 1) { + ret = -EOPNOTSUPP; + goto unlock; + } /* demod access via firmware interface */ - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | msg[0].buf[2]; if (msg[0].addr == state->af9033_i2c_addr[1]) @@ -380,17 +385,18 @@ ret = -EOPNOTSUPP; } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || (msg[0].addr == state->af9033_i2c_addr[1])) { + if (msg[0].len < 3) { + ret = -EOPNOTSUPP; + goto unlock; + } /* demod access via firmware interface */ - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | msg[0].buf[2]; if (msg[0].addr == state->af9033_i2c_addr[1]) reg |= 0x100000; - ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg, - &msg[0].buf[3], - msg[0].len - 3) - : -EOPNOTSUPP; + ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3); } else { /* I2C write */ u8 buf[MAX_XFER_SIZE]; @@ -457,6 +463,7 @@ ret = -EOPNOTSUPP; } +unlock: mutex_unlock(&d->i2c_mutex); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/anysee.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/anysee.c @@ -202,7 +202,7 @@ while (i < num) { if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - if (msg[i].len > 2 || msg[i+1].len > 60) { + if (msg[i].len != 2 || msg[i + 1].len > 60) { ret = -EOPNOTSUPP; break; } --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/az6007.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/az6007.c @@ -202,7 +202,8 @@ unsigned code; enum rc_proto proto; - az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); + if (az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10) < 0) + return -EIO; if (st->data[1] == 0x44) return 0; @@ -787,6 +788,10 @@ if (az6007_xfer_debug) printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n", addr, msgs[i].len); + if (msgs[i].len < 1) { + ret = -EIO; + goto err; + } req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); @@ -801,6 +806,10 @@ if (az6007_xfer_debug) printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n", addr, msgs[i].len); + if (msgs[i].len < 1) { + ret = -EIO; + goto err; + } req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/ce6230.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/ce6230.c @@ -101,6 +101,10 @@ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (msg[i].addr == ce6230_zl10353_config.demod_address) { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } req.cmd = DEMOD_READ; req.value = msg[i].addr >> 1; req.index = msg[i].buf[0]; @@ -117,6 +121,10 @@ } else { if (msg[i].addr == ce6230_zl10353_config.demod_address) { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } req.cmd = DEMOD_WRITE; req.value = msg[i].addr >> 1; req.index = msg[i].buf[0]; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/dvbsky.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/dvbsky.c @@ -792,6 +792,9 @@ { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C, &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C", RC_MAP_TOTAL_MEDIA_IN_HAND_02) }, + { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C_LITE, + &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C Lite", + NULL) }, { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C2, &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C v2", RC_MAP_TOTAL_MEDIA_IN_HAND_02) }, --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/ec168.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/ec168.c @@ -115,6 +115,10 @@ while (i < num) { if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { if (msg[i].addr == ec168_ec100_config.demod_address) { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } req.cmd = READ_DEMOD; req.value = 0; req.index = 0xff00 + msg[i].buf[0]; /* reg */ @@ -131,6 +135,10 @@ } } else { if (msg[i].addr == ec168_ec100_config.demod_address) { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } req.cmd = WRITE_DEMOD; req.value = msg[i].buf[1]; /* val */ req.index = 0xff00 + msg[i].buf[0]; /* reg */ @@ -139,6 +147,10 @@ ret = ec168_ctrl_msg(d, &req); i += 1; } else { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } req.cmd = WRITE_I2C; req.value = msg[i].buf[0]; /* val */ req.index = 0x0100 + msg[i].addr; /* I2C addr */ --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -372,8 +372,9 @@ struct dvb_usb_device *d = adap_to_d(adap); struct lme2510_state *lme_int = adap_to_priv(adap); struct usb_host_endpoint *ep; + int ret; - lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC); + lme_int->lme_urb = usb_alloc_urb(0, GFP_KERNEL); if (lme_int->lme_urb == NULL) return -ENOMEM; @@ -389,11 +390,20 @@ /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); + if (!ep) { + usb_free_urb(lme_int->lme_urb); + return -ENODEV; + } if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) - lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa), + lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa); + + ret = usb_submit_urb(lme_int->lme_urb, GFP_KERNEL); + if (ret) { + usb_free_urb(lme_int->lme_urb); + return ret; + } - usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC); info("INT Interrupt Service Started"); return 0; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/mxl111sf.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/mxl111sf.c @@ -931,8 +931,6 @@ .len = sizeof(eeprom), .buf = eeprom }, }; - mutex_init(&state->msg_lock); - ret = get_chip_info(state); if (mxl_fail(ret)) pr_err("failed to get chip info during probe"); @@ -1074,6 +1072,14 @@ return 0; } +static int mxl111sf_probe(struct dvb_usb_device *dev) +{ + struct mxl111sf_state *state = d_to_priv(dev); + + mutex_init(&state->msg_lock); + return 0; +} + static struct dvb_usb_device_properties mxl111sf_props_dvbt = { .driver_name = KBUILD_MODNAME, .owner = THIS_MODULE, @@ -1083,6 +1089,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_dvbt, .tuner_attach = mxl111sf_attach_tuner, @@ -1124,6 +1131,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_atsc, .tuner_attach = mxl111sf_attach_tuner, @@ -1165,6 +1173,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_mh, .tuner_attach = mxl111sf_attach_tuner, @@ -1233,6 +1242,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_atsc_mh, .tuner_attach = mxl111sf_attach_tuner, @@ -1311,6 +1321,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_mercury, .tuner_attach = mxl111sf_attach_tuner, @@ -1381,6 +1392,7 @@ .generic_bulk_ctrl_endpoint = 0x02, .generic_bulk_ctrl_endpoint_response = 0x81, + .probe = mxl111sf_probe, .i2c_algo = &mxl111sf_i2c_algo, .frontend_attach = mxl111sf_frontend_attach_mercury_mh, .tuner_attach = mxl111sf_attach_tuner, --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -37,7 +37,16 @@ } else { /* read */ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); - pipe = usb_rcvctrlpipe(d->udev, 0); + + /* + * Zero-length transfers must use usb_sndctrlpipe() and + * rtl28xxu_identify_state() uses a zero-length i2c read + * command to determine the chip type. + */ + if (req->size) + pipe = usb_rcvctrlpipe(d->udev, 0); + else + pipe = usb_sndctrlpipe(d->udev, 0); } ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value, @@ -167,6 +176,10 @@ ret = -EOPNOTSUPP; goto err_mutex_unlock; } else if (msg[0].addr == 0x10) { + if (msg[0].len < 1 || msg[1].len < 1) { + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } /* method 1 - integrated demod */ if (msg[0].buf[0] == 0x00) { /* return demod page from driver cache */ @@ -180,6 +193,10 @@ ret = rtl28xxu_ctrl_msg(d, &req); } } else if (msg[0].len < 2) { + if (msg[0].len < 1) { + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } /* method 2 - old I2C */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_I2C_RD; @@ -208,8 +225,16 @@ ret = -EOPNOTSUPP; goto err_mutex_unlock; } else if (msg[0].addr == 0x10) { + if (msg[0].len < 1) { + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } /* method 1 - integrated demod */ if (msg[0].buf[0] == 0x00) { + if (msg[0].len < 2) { + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } /* save demod page for later demod access */ dev->page = msg[0].buf[1]; ret = 0; @@ -222,6 +247,10 @@ ret = rtl28xxu_ctrl_msg(d, &req); } } else if ((msg[0].len < 23) && (!dev->new_i2c_write)) { + if (msg[0].len < 1) { + ret = -EOPNOTSUPP; + goto err_mutex_unlock; + } /* method 2 - old I2C */ req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1); req.index = CMD_I2C_WR; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/Kconfig +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/Kconfig @@ -150,6 +150,7 @@ config DVB_USB_CXUSB_ANALOG bool "Analog support for the Conexant USB2.0 hybrid reference design" depends on DVB_USB_CXUSB && VIDEO_V4L2 + depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_USB_CXUSB select VIDEO_CX25840 select VIDEOBUF2_VMALLOC help --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/af9005.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/af9005.c @@ -422,6 +422,10 @@ if (ret == 0) ret = 2; } else { + if (msg[0].len < 2) { + ret = -EOPNOTSUPP; + goto unlock; + } /* write one or more registers */ reg = msg[0].buf[0]; addr = msg[0].addr; @@ -431,6 +435,7 @@ ret = 1; } +unlock: mutex_unlock(&d->i2c_mutex); return ret; } @@ -554,7 +559,7 @@ u8 *buf, int size) { u16 checksum; - int act_len, i, ret; + int act_len = 0, i, ret; memset(buf, 0, size); buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); @@ -976,8 +981,9 @@ else if (reply == 0x02) *cold = 0; else - return -EIO; - deb_info("Identify state cold = %d\n", *cold); + ret = -EIO; + if (!ret) + deb_info("Identify state cold = %d\n", *cold); err: kfree(buf); --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/az6027.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/az6027.c @@ -391,6 +391,7 @@ /* remote control stuff (does not work with my box) */ static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { + *state = REMOTE_NO_KEY_PRESSED; return 0; } @@ -974,6 +975,10 @@ if (msg[i].addr == 0x99) { req = 0xBE; index = 0; + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } value = msg[i].buf[0] & 0x00ff; length = 1; az6027_usb_out_op(d, req, value, index, data, length); @@ -983,6 +988,10 @@ /* write/read request */ if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) { req = 0xB9; + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); value = msg[i].addr + (msg[i].len << 8); length = msg[i + 1].len + 6; @@ -996,6 +1005,10 @@ /* demod 16bit addr */ req = 0xBD; + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); value = msg[i].addr + (2 << 8); length = msg[i].len - 2; @@ -1021,6 +1034,10 @@ } else { req = 0xBD; + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } index = msg[i].buf[0] & 0x00FF; value = msg[i].addr + (1 << 8); length = msg[i].len - 1; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/cinergyT2-core.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -78,6 +78,8 @@ ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); if (ret < 0) { + if (adap->fe_adap[0].fe) + adap->fe_adap[0].fe->ops.release(adap->fe_adap[0].fe); deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n"); } mutex_unlock(&d->data_mutex); --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/cxusb.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/cxusb.c @@ -521,7 +521,8 @@ { u8 ircode[4]; - cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); + if (cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4) < 0) + return 0; if (ircode[2] || ircode[3]) rc_keydown(d->rc_dev, RC_PROTO_NEC, @@ -1949,7 +1950,7 @@ .size_of_priv = sizeof(struct cxusb_state), - .num_adapters = 2, + .num_adapters = 1, .adapter = { { .num_frontends = 1, --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dib0700_core.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dib0700_core.c @@ -616,8 +616,6 @@ deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint); if (onoff) st->channel_state |= 1 << (adap->id); - else - st->channel_state |= 1 << ~(adap->id); } else { if (onoff) st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2); @@ -818,7 +816,7 @@ /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ - if (intf->altsetting[0].desc.bNumEndpoints < rc_ep + 1) + if (intf->cur_altsetting->desc.bNumEndpoints < rc_ep + 1) return -ENODEV; purb = usb_alloc_urb(0, GFP_KERNEL); @@ -838,7 +836,7 @@ * Some devices like the Hauppauge NovaTD model 52009 use an interrupt * endpoint, while others use a bulk one. */ - e = &intf->altsetting[0].endpoint[rc_ep].desc; + e = &intf->cur_altsetting->endpoint[rc_ep].desc; if (usb_endpoint_dir_in(e)) { if (usb_endpoint_xfer_bulk(e)) { pipe = usb_rcvbulkpipe(d->udev, rc_ep); --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dib0700_devices.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -2424,7 +2424,12 @@ adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); - return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; + if (!adap->fe_adap[0].fe) { + release_firmware(state->frontend_firmware); + return -ENODEV; + } + + return 0; } static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) @@ -2497,8 +2502,10 @@ dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80); adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); - if (adap->fe_adap[0].fe == NULL) + if (!adap->fe_adap[0].fe) { + release_firmware(state->frontend_firmware); return -ENODEV; + } i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82); @@ -2506,7 +2513,12 @@ fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]); dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); - return fe_slave == NULL ? -ENODEV : 0; + if (!fe_slave) { + release_firmware(state->frontend_firmware); + return -ENODEV; + } + + return 0; } static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dibusb-common.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dibusb-common.c @@ -223,7 +223,7 @@ u8 *buf; int rc; - buf = kmalloc(2, GFP_KERNEL); + buf = kzalloc(2, GFP_KERNEL); if (!buf) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dibusb-mb.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dibusb-mb.c @@ -81,7 +81,7 @@ if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { err("tuner i2c write failed."); - ret = -EREMOTEIO; + return -EREMOTEIO; } if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/digitv.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/digitv.c @@ -63,6 +63,10 @@ warn("more than 2 i2c messages at a time is not handled yet. TODO."); for (i = 0; i < num; i++) { + if (msg[i].len < 1) { + i = -EOPNOTSUPP; + break; + } /* write/read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0, @@ -230,18 +234,22 @@ static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - int i; + int ret, i; u8 key[5]; u8 b[4] = { 0 }; *event = 0; *state = REMOTE_NO_KEY_PRESSED; - digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); + ret = digitv_ctrl_msg(d, USB_READ_REMOTE, 0, NULL, 0, &key[1], 4); + if (ret) + return ret; /* Tell the device we've read the remote. Not sure how necessary this is, but the Nebula SDK does it. */ - digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); + ret = digitv_ctrl_msg(d, USB_WRITE_REMOTE, 0, b, 4, NULL, 0); + if (ret) + return ret; /* if something is inside the buffer, simulate key press */ if (key[1] != 0) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dtv5100.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dtv5100.c @@ -26,6 +26,7 @@ u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { struct dtv5100_state *st = d->priv; + unsigned int pipe; u8 request; u8 type; u16 value; @@ -34,6 +35,7 @@ switch (wlen) { case 1: /* write { reg }, read { value } */ + pipe = usb_rcvctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : DTV5100_TUNER_READ); type = USB_TYPE_VENDOR | USB_DIR_IN; @@ -41,6 +43,7 @@ break; case 2: /* write { reg, value } */ + pipe = usb_sndctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : DTV5100_TUNER_WRITE); type = USB_TYPE_VENDOR | USB_DIR_OUT; @@ -54,7 +57,7 @@ memcpy(st->data, rbuf, rlen); msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, + return usb_control_msg(d->udev, pipe, request, type, value, index, st->data, rlen, DTV5100_USB_TIMEOUT); } @@ -141,7 +144,7 @@ /* initialize non qt1010/zl10353 part? */ for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), dtv5100_init[i].request, USB_TYPE_VENDOR | USB_DIR_OUT, dtv5100_init[i].value, --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dvb-usb-i2c.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dvb-usb-i2c.c @@ -17,7 +17,8 @@ if (d->props.i2c_algo == NULL) { err("no i2c algorithm specified"); - return -EINVAL; + ret = -EINVAL; + goto err; } strscpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); @@ -27,11 +28,15 @@ i2c_set_adapdata(&d->i2c_adap, d); - if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0) + ret = i2c_add_adapter(&d->i2c_adap); + if (ret < 0) { err("could not add i2c adapter"); + goto err; + } d->state |= DVB_USB_STATE_I2C; +err: return ret; } --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -79,11 +79,17 @@ } } - if ((ret = dvb_usb_adapter_stream_init(adap)) || - (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || - (ret = dvb_usb_adapter_frontend_init(adap))) { - return ret; - } + ret = dvb_usb_adapter_stream_init(adap); + if (ret) + goto stream_init_err; + + ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs); + if (ret) + goto dvb_init_err; + + ret = dvb_usb_adapter_frontend_init(adap); + if (ret) + goto frontend_init_err; /* use exclusive FE lock if there is multiple shared FEs */ if (adap->fe_adap[1].fe) @@ -103,6 +109,14 @@ } return 0; + +frontend_init_err: + dvb_usb_adapter_dvb_exit(adap); +dvb_init_err: + dvb_usb_adapter_stream_exit(adap); +stream_init_err: + kfree(adap->priv); + return ret; } static int dvb_usb_adapter_exit(struct dvb_usb_device *d) @@ -158,22 +172,20 @@ if (d->props.priv_init != NULL) { ret = d->props.priv_init(d); - if (ret != 0) { - kfree(d->priv); - d->priv = NULL; - return ret; - } + if (ret != 0) + goto err_priv_init; } } /* check the capabilities and set appropriate variables */ dvb_usb_device_power_ctrl(d, 1); - if ((ret = dvb_usb_i2c_init(d)) || - (ret = dvb_usb_adapter_init(d, adapter_nums))) { - dvb_usb_exit(d); - return ret; - } + ret = dvb_usb_i2c_init(d); + if (ret) + goto err_i2c_init; + ret = dvb_usb_adapter_init(d, adapter_nums); + if (ret) + goto err_adapter_init; if ((ret = dvb_usb_remote_init(d))) err("could not initialize remote control."); @@ -181,6 +193,17 @@ dvb_usb_device_power_ctrl(d, 0); return 0; + +err_adapter_init: + dvb_usb_adapter_exit(d); + dvb_usb_i2c_exit(d); +err_i2c_init: + if (d->priv && d->props.priv_destroy) + d->props.priv_destroy(d); +err_priv_init: + kfree(d->priv); + d->priv = NULL; + return ret; } /* determine the name and the state of the just found USB device */ @@ -255,41 +278,50 @@ if (du != NULL) *du = NULL; - if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) { + d = kzalloc(sizeof(*d), GFP_KERNEL); + if (!d) { + err("no memory for 'struct dvb_usb_device'"); + return -ENOMEM; + } + + memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); + + desc = dvb_usb_find_device(udev, &d->props, &cold); + if (!desc) { deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); - return -ENODEV; + ret = -ENODEV; + goto error; } if (cold) { info("found a '%s' in cold state, will try to load a firmware", desc->name); ret = dvb_usb_download_firmware(udev, props); if (!props->no_reconnect || ret != 0) - return ret; + goto error; } info("found a '%s' in warm state.", desc->name); - d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); - if (d == NULL) { - err("no memory for 'struct dvb_usb_device'"); - return -ENOMEM; - } - d->udev = udev; - memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties)); d->desc = desc; d->owner = owner; usb_set_intfdata(intf, d); - if (du != NULL) + ret = dvb_usb_init(d, adapter_nums); + if (ret) { + info("%s error while loading driver (%d)", desc->name, ret); + goto error; + } + + if (du) *du = d; - ret = dvb_usb_init(d, adapter_nums); + info("%s successfully initialized and connected.", desc->name); + return 0; - if (ret == 0) - info("%s successfully initialized and connected.", desc->name); - else - info("%s error while loading driver (%d)", desc->name, ret); + error: + usb_set_intfdata(intf, NULL); + kfree(d); return ret; } EXPORT_SYMBOL(dvb_usb_device_init); --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dvb-usb-urb.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dvb-usb-urb.c @@ -12,7 +12,7 @@ int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen, int delay_ms) { - int actlen,ret = -ENOMEM; + int actlen = 0, ret = -ENOMEM; if (!d || wbuf == NULL || wlen == 0) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dvb-usb.h +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dvb-usb.h @@ -485,7 +485,7 @@ dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); /* commonly used remote control parsing */ -extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); +extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[5], u32 *, int *); /* commonly used firmware download types and function */ struct hexline { --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/dw2102.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/dw2102.c @@ -128,6 +128,10 @@ switch (num) { case 2: + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } /* read stv0299 register */ value = msg[0].buf[0];/* register */ for (i = 0; i < msg[1].len; i++) { @@ -139,6 +143,10 @@ case 1: switch (msg[0].addr) { case 0x68: + if (msg[0].len < 2) { + num = -EOPNOTSUPP; + break; + } /* write to stv0299 register */ buf6[0] = 0x2a; buf6[1] = msg[0].buf[0]; @@ -148,6 +156,10 @@ break; case 0x60: if (msg[0].flags == 0) { + if (msg[0].len < 4) { + num = -EOPNOTSUPP; + break; + } /* write to tuner pll */ buf6[0] = 0x2c; buf6[1] = 5; @@ -159,6 +171,10 @@ dw210x_op_rw(d->udev, 0xb2, 0, 0, buf6, 7, DW210X_WRITE_MSG); } else { + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } /* read from tuner */ dw210x_op_rw(d->udev, 0xb5, 0, 0, buf6, 1, DW210X_READ_MSG); @@ -166,12 +182,20 @@ } break; case (DW2102_RC_QUERY): + if (msg[0].len < 2) { + num = -EOPNOTSUPP; + break; + } dw210x_op_rw(d->udev, 0xb8, 0, 0, buf6, 2, DW210X_READ_MSG); msg[0].buf[0] = buf6[0]; msg[0].buf[1] = buf6[1]; break; case (DW2102_VOLTAGE_CTRL): + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } buf6[0] = 0x30; buf6[1] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, @@ -692,6 +716,7 @@ { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct dw2102_state *state; + int j; if (!d) return -ENODEV; @@ -705,11 +730,11 @@ return -EAGAIN; } - switch (num) { - case 1: - switch (msg[0].addr) { + j = 0; + while (j < num) { + switch (msg[j].addr) { case SU3000_STREAM_CTRL: - state->data[0] = msg[0].buf[0] + 0x36; + state->data[0] = msg[j].buf[0] + 0x36; state->data[1] = 3; state->data[2] = 0; if (dvb_usb_generic_rw(d, state->data, 3, @@ -721,61 +746,86 @@ if (dvb_usb_generic_rw(d, state->data, 1, state->data, 2, 0) < 0) err("i2c transfer failed."); - msg[0].buf[1] = state->data[0]; - msg[0].buf[0] = state->data[1]; + msg[j].buf[1] = state->data[0]; + msg[j].buf[0] = state->data[1]; break; default: - if (3 + msg[0].len > sizeof(state->data)) { - warn("i2c wr: len=%d is too big!\n", - msg[0].len); + /* if the current write msg is followed by a another + * read msg to/from the same address + */ + if ((j+1 < num) && (msg[j+1].flags & I2C_M_RD) && + (msg[j].addr == msg[j+1].addr)) { + /* join both i2c msgs to one usb read command */ + if (4 + msg[j].len > sizeof(state->data)) { + warn("i2c combined wr/rd: write len=%d is too big!\n", + msg[j].len); + num = -EOPNOTSUPP; + break; + } + if (1 + msg[j+1].len > sizeof(state->data)) { + warn("i2c combined wr/rd: read len=%d is too big!\n", + msg[j+1].len); + num = -EOPNOTSUPP; + break; + } + + state->data[0] = 0x09; + state->data[1] = msg[j].len; + state->data[2] = msg[j+1].len; + state->data[3] = msg[j].addr; + memcpy(&state->data[4], msg[j].buf, msg[j].len); + + if (dvb_usb_generic_rw(d, state->data, msg[j].len + 4, + state->data, msg[j+1].len + 1, 0) < 0) + err("i2c transfer failed."); + + memcpy(msg[j+1].buf, &state->data[1], msg[j+1].len); + j++; + break; + } + + if (msg[j].flags & I2C_M_RD) { + /* single read */ + if (4 + msg[j].len > sizeof(state->data)) { + warn("i2c rd: len=%d is too big!\n", msg[j].len); + num = -EOPNOTSUPP; + break; + } + + state->data[0] = 0x09; + state->data[1] = 0; + state->data[2] = msg[j].len; + state->data[3] = msg[j].addr; + memcpy(&state->data[4], msg[j].buf, msg[j].len); + + if (dvb_usb_generic_rw(d, state->data, 4, + state->data, msg[j].len + 1, 0) < 0) + err("i2c transfer failed."); + + memcpy(msg[j].buf, &state->data[1], msg[j].len); + break; + } + + /* single write */ + if (3 + msg[j].len > sizeof(state->data)) { + warn("i2c wr: len=%d is too big!\n", msg[j].len); num = -EOPNOTSUPP; break; } - /* always i2c write*/ state->data[0] = 0x08; - state->data[1] = msg[0].addr; - state->data[2] = msg[0].len; + state->data[1] = msg[j].addr; + state->data[2] = msg[j].len; - memcpy(&state->data[3], msg[0].buf, msg[0].len); + memcpy(&state->data[3], msg[j].buf, msg[j].len); - if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3, + if (dvb_usb_generic_rw(d, state->data, msg[j].len + 3, state->data, 1, 0) < 0) err("i2c transfer failed."); + } // switch + j++; - } - break; - case 2: - /* always i2c read */ - if (4 + msg[0].len > sizeof(state->data)) { - warn("i2c rd: len=%d is too big!\n", - msg[0].len); - num = -EOPNOTSUPP; - break; - } - if (1 + msg[1].len > sizeof(state->data)) { - warn("i2c rd: len=%d is too big!\n", - msg[1].len); - num = -EOPNOTSUPP; - break; - } - - state->data[0] = 0x09; - state->data[1] = msg[0].len; - state->data[2] = msg[1].len; - state->data[3] = msg[0].addr; - memcpy(&state->data[4], msg[0].buf, msg[0].len); - - if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4, - state->data, msg[1].len + 1, 0) < 0) - err("i2c transfer failed."); - - memcpy(msg[1].buf, &state->data[1], msg[1].len); - break; - default: - warn("more than 2 i2c messages at a time is not handled yet."); - break; - } + } // while mutex_unlock(&d->data_mutex); mutex_unlock(&d->i2c_mutex); return num; @@ -946,7 +996,7 @@ for (i = 0; i < 6; i++) { obuf[1] = 0xf0 + i; if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) - break; + return -1; else mac[i] = ibuf[0]; } @@ -2098,46 +2148,153 @@ } }; -static const struct dvb_usb_device_description d1100 = { - "Prof 1100 USB ", - {&dw2102_table[PROF_1100], NULL}, - {NULL}, -}; +static struct dvb_usb_device_properties p1100_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct dw2102_state), + .firmware = P1100_FIRMWARE, + .no_reconnect = 1, -static const struct dvb_usb_device_description d660 = { - "TeVii S660 USB", - {&dw2102_table[TEVII_S660], NULL}, - {NULL}, -}; + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval = 150, + .rc_codes = RC_MAP_TBS_NEC, + .module_name = "dw2102", + .allowed_protos = RC_PROTO_BIT_NEC, + .rc_query = prof_rc_query, + }, -static const struct dvb_usb_device_description d480_1 = { - "TeVii S480.1 USB", - {&dw2102_table[TEVII_S480_1], NULL}, - {NULL}, + .generic_bulk_ctrl_endpoint = 0x81, + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .frontend_attach = stv0288_frontend_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } }, + } + }, + .num_device_descs = 1, + .devices = { + {"Prof 1100 USB ", + {&dw2102_table[PROF_1100], NULL}, + {NULL}, + }, + } }; -static const struct dvb_usb_device_description d480_2 = { - "TeVii S480.2 USB", - {&dw2102_table[TEVII_S480_2], NULL}, - {NULL}, -}; +static struct dvb_usb_device_properties s660_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct dw2102_state), + .firmware = S660_FIRMWARE, + .no_reconnect = 1, -static const struct dvb_usb_device_description d7500 = { - "Prof 7500 USB DVB-S2", - {&dw2102_table[PROF_7500], NULL}, - {NULL}, -}; + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval = 150, + .rc_codes = RC_MAP_TEVII_NEC, + .module_name = "dw2102", + .allowed_protos = RC_PROTO_BIT_NEC, + .rc_query = dw2102_rc_query, + }, -static const struct dvb_usb_device_description d421 = { - "TeVii S421 PCI", - {&dw2102_table[TEVII_S421], NULL}, - {NULL}, + .generic_bulk_ctrl_endpoint = 0x81, + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .frontend_attach = ds3000_frontend_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } }, + } + }, + .num_device_descs = 3, + .devices = { + {"TeVii S660 USB", + {&dw2102_table[TEVII_S660], NULL}, + {NULL}, + }, + {"TeVii S480.1 USB", + {&dw2102_table[TEVII_S480_1], NULL}, + {NULL}, + }, + {"TeVii S480.2 USB", + {&dw2102_table[TEVII_S480_2], NULL}, + {NULL}, + }, + } }; -static const struct dvb_usb_device_description d632 = { - "TeVii S632 USB", - {&dw2102_table[TEVII_S632], NULL}, - {NULL}, +static struct dvb_usb_device_properties p7500_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct dw2102_state), + .firmware = P7500_FIRMWARE, + .no_reconnect = 1, + + .i2c_algo = &s6x0_i2c_algo, + .rc.core = { + .rc_interval = 150, + .rc_codes = RC_MAP_TBS_NEC, + .module_name = "dw2102", + .allowed_protos = RC_PROTO_BIT_NEC, + .rc_query = prof_rc_query, + }, + + .generic_bulk_ctrl_endpoint = 0x81, + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .read_mac_address = s6x0_read_mac_address, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .frontend_attach = prof_7500_frontend_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } }, + } + }, + .num_device_descs = 1, + .devices = { + {"Prof 7500 USB DVB-S2", + {&dw2102_table[PROF_7500], NULL}, + {NULL}, + }, + } }; static struct dvb_usb_device_properties su3000_properties = { @@ -2209,6 +2366,59 @@ } }; +static struct dvb_usb_device_properties s421_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .size_of_priv = sizeof(struct dw2102_state), + .power_ctrl = su3000_power_ctrl, + .num_adapters = 1, + .identify_state = su3000_identify_state, + .i2c_algo = &su3000_i2c_algo, + + .rc.core = { + .rc_interval = 150, + .rc_codes = RC_MAP_SU3000, + .module_name = "dw2102", + .allowed_protos = RC_PROTO_BIT_RC5, + .rc_query = su3000_rc_query, + }, + + .read_mac_address = su3000_read_mac_address, + + .generic_bulk_ctrl_endpoint = 0x01, + + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .streaming_ctrl = su3000_streaming_ctrl, + .frontend_attach = m88rs2000_frontend_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + } + } }, + } + }, + .num_device_descs = 2, + .devices = { + { "TeVii S421 PCI", + { &dw2102_table[TEVII_S421], NULL }, + { NULL }, + }, + { "TeVii S632 USB", + { &dw2102_table[TEVII_S632], NULL }, + { NULL }, + }, + } +}; + static struct dvb_usb_device_properties t220_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, @@ -2326,101 +2536,33 @@ static int dw2102_probe(struct usb_interface *intf, const struct usb_device_id *id) { - int retval = -ENOMEM; - struct dvb_usb_device_properties *p1100; - struct dvb_usb_device_properties *s660; - struct dvb_usb_device_properties *p7500; - struct dvb_usb_device_properties *s421; - - p1100 = kmemdup(&s6x0_properties, - sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!p1100) - goto err0; - - /* copy default structure */ - /* fill only different fields */ - p1100->firmware = P1100_FIRMWARE; - p1100->devices[0] = d1100; - p1100->rc.core.rc_query = prof_rc_query; - p1100->rc.core.rc_codes = RC_MAP_TBS_NEC; - p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; - - s660 = kmemdup(&s6x0_properties, - sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!s660) - goto err1; - - s660->firmware = S660_FIRMWARE; - s660->num_device_descs = 3; - s660->devices[0] = d660; - s660->devices[1] = d480_1; - s660->devices[2] = d480_2; - s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; - - p7500 = kmemdup(&s6x0_properties, - sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!p7500) - goto err2; - - p7500->firmware = P7500_FIRMWARE; - p7500->devices[0] = d7500; - p7500->rc.core.rc_query = prof_rc_query; - p7500->rc.core.rc_codes = RC_MAP_TBS_NEC; - p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach; - - - s421 = kmemdup(&su3000_properties, - sizeof(struct dvb_usb_device_properties), GFP_KERNEL); - if (!s421) - goto err3; - - s421->num_device_descs = 2; - s421->devices[0] = d421; - s421->devices[1] = d632; - s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach; - - if (0 == dvb_usb_device_init(intf, &dw2102_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dw2104_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dw3101_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &s6x0_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, p1100, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, s660, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, p7500, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, s421, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &su3000_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &t220_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties, - THIS_MODULE, NULL, adapter_nr)) { - - /* clean up copied properties */ - kfree(s421); - kfree(p7500); - kfree(s660); - kfree(p1100); + if (!(dvb_usb_device_init(intf, &dw2102_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &dw2104_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &dw3101_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &s6x0_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &p1100_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &s660_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &p7500_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &s421_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &su3000_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &t220_properties, + THIS_MODULE, NULL, adapter_nr) && + dvb_usb_device_init(intf, &tt_s2_4600_properties, + THIS_MODULE, NULL, adapter_nr))) { return 0; } - retval = -ENODEV; - kfree(s421); -err3: - kfree(p7500); -err2: - kfree(s660); -err1: - kfree(p1100); -err0: - return retval; + return -ENODEV; } static void dw2102_disconnect(struct usb_interface *intf) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/gp8psk.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/gp8psk.c @@ -182,7 +182,7 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) { - u8 status, buf; + u8 status = 0, buf; int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct); if (onoff) { --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/m920x.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/m920x.c @@ -274,6 +274,12 @@ /* Should check for ack here, if we knew how. */ } if (msg[i].flags & I2C_M_RD) { + char *read = kmalloc(1, GFP_KERNEL); + if (!read) { + ret = -ENOMEM; + goto unlock; + } + for (j = 0; j < msg[i].len; j++) { /* Last byte of transaction? * Send STOP, otherwise send ACK. */ @@ -281,9 +287,14 @@ if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, 0x20 | stop, - &msg[i].buf[j], 1)) != 0) + read, 1)) != 0) { + kfree(read); goto unlock; + } + msg[i].buf[j] = read[0]; } + + kfree(read); } else { for (j = 0; j < msg[i].len; j++) { /* Last byte of transaction? Then send STOP. */ --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/nova-t-usb2.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/nova-t-usb2.c @@ -130,7 +130,7 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) { - int i; + int i, ret; u8 b; mac[0] = 0x00; @@ -139,7 +139,9 @@ /* this is a complete guess, but works for my box */ for (i = 136; i < 139; i++) { - dibusb_read_eeprom_byte(d,i, &b); + ret = dibusb_read_eeprom_byte(d, i, &b); + if (ret) + return ret; mac[5 - (i - 136)] = b; } --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/vp702x.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/vp702x.c @@ -291,16 +291,22 @@ static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) { u8 i, *buf; + int ret; struct vp702x_device_state *st = d->priv; mutex_lock(&st->buf_mutex); buf = st->buf; - for (i = 6; i < 12; i++) - vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1); + for (i = 6; i < 12; i++) { + ret = vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, + &buf[i - 6], 1); + if (ret < 0) + goto err; + } memcpy(mac, buf, 6); +err: mutex_unlock(&st->buf_mutex); - return 0; + return ret; } static int vp702x_frontend_attach(struct dvb_usb_adapter *adap) --- linux-oracle-5.4.0.orig/drivers/media/usb/dvb-usb/vp7045.c +++ linux-oracle-5.4.0/drivers/media/usb/dvb-usb/vp7045.c @@ -96,10 +96,14 @@ static int vp7045_rc_query(struct dvb_usb_device *d) { + int ret; u8 key; - vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); - deb_rc("remote query key: %x %d\n",key,key); + ret = vp7045_usb_op(d, RC_VAL_READ, NULL, 0, &key, 1, 20); + if (ret) + return ret; + + deb_rc("remote query key: %x\n", key); if (key != 0x44) { /* @@ -115,15 +119,18 @@ static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset) { - int i = 0; - u8 v,br[2]; + int i, ret; + u8 v, br[2]; for (i=0; i < len; i++) { v = offset + i; - vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5); + ret = vp7045_usb_op(d, GET_EE_VALUE, &v, 1, br, 2, 5); + if (ret) + return ret; + buf[i] = br[1]; } - deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i); - debug_dump(buf,i,deb_info); + deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ", offset, i); + debug_dump(buf, i, deb_info); return 0; } --- linux-oracle-5.4.0.orig/drivers/media/usb/em28xx/em28xx-cards.c +++ linux-oracle-5.4.0/drivers/media/usb/em28xx/em28xx-cards.c @@ -3515,8 +3515,10 @@ if (dev->is_audio_only) { retval = em28xx_audio_setup(dev); - if (retval) - return -ENODEV; + if (retval) { + retval = -ENODEV; + goto err_deinit_media; + } em28xx_init_extension(dev); return 0; @@ -3535,7 +3537,7 @@ dev_err(&dev->intf->dev, "%s: em28xx_i2c_register bus 0 - error [%d]!\n", __func__, retval); - return retval; + goto err_deinit_media; } /* register i2c bus 1 */ @@ -3551,9 +3553,7 @@ "%s: em28xx_i2c_register bus 1 - error [%d]!\n", __func__, retval); - em28xx_i2c_unregister(dev, 0); - - return retval; + goto err_unreg_i2c; } } @@ -3561,6 +3561,12 @@ em28xx_card_setup(dev); return 0; + +err_unreg_i2c: + em28xx_i2c_unregister(dev, 0); +err_deinit_media: + em28xx_unregister_media_device(dev); + return retval; } static int em28xx_duplicate_dev(struct em28xx *dev) @@ -3815,6 +3821,8 @@ goto err_free; } + kref_init(&dev->ref); + dev->devno = nr; dev->model = id->driver_info; dev->alt = -1; @@ -3915,6 +3923,8 @@ } if (dev->board.has_dual_ts && em28xx_duplicate_dev(dev) == 0) { + kref_init(&dev->dev_next->ref); + dev->dev_next->ts = SECONDARY_TS; dev->dev_next->alt = -1; dev->dev_next->is_audio_only = has_vendor_audio && @@ -3969,12 +3979,8 @@ em28xx_write_reg(dev, 0x0b, 0x82); mdelay(100); } - - kref_init(&dev->dev_next->ref); } - kref_init(&dev->ref); - request_modules(dev); /* @@ -3983,6 +3989,10 @@ * topology will likely change after the load of the em28xx subdrivers. */ #ifdef CONFIG_MEDIA_CONTROLLER + /* + * No need to check the return value, the device will still be + * usable without media controller API. + */ retval = media_device_register(dev->media_dev); #endif --- linux-oracle-5.4.0.orig/drivers/media/usb/em28xx/em28xx-core.c +++ linux-oracle-5.4.0/drivers/media/usb/em28xx/em28xx-core.c @@ -89,7 +89,7 @@ mutex_lock(&dev->ctrl_urb_lock); ret = usb_control_msg(udev, pipe, req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, dev->urb_buf, len, HZ); + 0x0000, reg, dev->urb_buf, len, 1000); if (ret < 0) { em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", pipe, @@ -158,7 +158,7 @@ memcpy(dev->urb_buf, buf, len); ret = usb_control_msg(udev, pipe, req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, reg, dev->urb_buf, len, HZ); + 0x0000, reg, dev->urb_buf, len, 1000); mutex_unlock(&dev->ctrl_urb_lock); if (ret < 0) { @@ -956,14 +956,10 @@ usb_bufs->buf[i] = kzalloc(sb_size, GFP_KERNEL); if (!usb_bufs->buf[i]) { - em28xx_uninit_usb_xfer(dev, mode); - for (i--; i >= 0; i--) kfree(usb_bufs->buf[i]); - kfree(usb_bufs->buf); - usb_bufs->buf = NULL; - + em28xx_uninit_usb_xfer(dev, mode); return -ENOMEM; } @@ -1156,8 +1152,9 @@ dev_info(&dev->intf->dev, "Suspending extensions\n"); mutex_lock(&em28xx_devlist_mutex); list_for_each_entry(ops, &em28xx_extension_devlist, next) { - if (ops->suspend) - ops->suspend(dev); + if (!ops->suspend) + continue; + ops->suspend(dev); if (dev->dev_next) ops->suspend(dev->dev_next); } --- linux-oracle-5.4.0.orig/drivers/media/usb/em28xx/em28xx-dvb.c +++ linux-oracle-5.4.0/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1924,6 +1924,7 @@ return result; out_free: + em28xx_uninit_usb_xfer(dev, EM28XX_DIGITAL_MODE); kfree(dvb); dev->dvb = NULL; goto ret; --- linux-oracle-5.4.0.orig/drivers/media/usb/em28xx/em28xx-input.c +++ linux-oracle-5.4.0/drivers/media/usb/em28xx/em28xx-input.c @@ -720,7 +720,8 @@ dev->board.has_ir_i2c = 0; dev_warn(&dev->intf->dev, "No i2c IR remote control device found.\n"); - return -ENODEV; + err = -ENODEV; + goto ref_put; } } @@ -735,7 +736,7 @@ ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) - return -ENOMEM; + goto ref_put; rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!rc) goto error; @@ -839,6 +840,8 @@ dev->ir = NULL; rc_free_device(rc); kfree(ir); +ref_put: + em28xx_shutdown_buttons(dev); return err; } --- linux-oracle-5.4.0.orig/drivers/media/usb/go7007/go7007-driver.c +++ linux-oracle-5.4.0/drivers/media/usb/go7007/go7007-driver.c @@ -80,7 +80,7 @@ const struct firmware *fw_entry; char fw_name[] = "go7007/go7007fw.bin"; void *bounce; - int fw_len, rv = 0; + int fw_len; u16 intr_val, intr_data; if (go->boot_fw == NULL) { @@ -109,9 +109,11 @@ go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || (intr_val & ~0x1) != 0x5a5a) { v4l2_err(go, "error transferring firmware\n"); - rv = -1; + kfree(go->boot_fw); + go->boot_fw = NULL; + return -1; } - return rv; + return 0; } MODULE_FIRMWARE("go7007/go7007fw.bin"); @@ -691,49 +693,23 @@ struct device *dev) { struct go7007 *go; - int i; go = kzalloc(sizeof(struct go7007), GFP_KERNEL); if (go == NULL) return NULL; go->dev = dev; go->board_info = board; - go->board_id = 0; go->tuner_type = -1; - go->channel_number = 0; - go->name[0] = 0; mutex_init(&go->hw_lock); init_waitqueue_head(&go->frame_waitq); spin_lock_init(&go->spinlock); go->status = STATUS_INIT; - memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter)); - go->i2c_adapter_online = 0; - go->interrupt_available = 0; init_waitqueue_head(&go->interrupt_waitq); - go->input = 0; go7007_update_board(go); - go->encoder_h_halve = 0; - go->encoder_v_halve = 0; - go->encoder_subsample = 0; go->format = V4L2_PIX_FMT_MJPEG; go->bitrate = 1500000; go->fps_scale = 1; - go->pali = 0; go->aspect_ratio = GO7007_RATIO_1_1; - go->gop_size = 0; - go->ipb = 0; - go->closed_gop = 0; - go->repeat_seqhead = 0; - go->seq_header_enable = 0; - go->gop_header_enable = 0; - go->dvd_mode = 0; - go->interlace_coding = 0; - for (i = 0; i < 4; ++i) - go->modet[i].enable = 0; - for (i = 0; i < 1624; ++i) - go->modet_map[i] = 0; - go->audio_deliver = NULL; - go->audio_enabled = 0; return go; } --- linux-oracle-5.4.0.orig/drivers/media/usb/go7007/go7007-i2c.c +++ linux-oracle-5.4.0/drivers/media/usb/go7007/go7007-i2c.c @@ -165,8 +165,6 @@ } else if (msgs[i].len == 3) { if (msgs[i].flags & I2C_M_RD) return -EIO; - if (msgs[i].len != 3) - return -EIO; if (go7007_i2c_xfer(go, msgs[i].addr, 0, (msgs[i].buf[0] << 8) | msgs[i].buf[1], 0x01, &msgs[i].buf[2]) < 0) --- linux-oracle-5.4.0.orig/drivers/media/usb/go7007/go7007-usb.c +++ linux-oracle-5.4.0/drivers/media/usb/go7007/go7007-usb.c @@ -1044,6 +1044,7 @@ struct go7007_usb *usb; const struct go7007_usb_board *board; struct usb_device *usbdev = interface_to_usbdev(intf); + struct usb_host_endpoint *ep; unsigned num_i2c_devs; char *name; int video_pipe, i, v_urb_len; @@ -1140,7 +1141,8 @@ if (usb->intr_urb->transfer_buffer == NULL) goto allocfail; - if (go->board_id == GO7007_BOARDID_SENSORAY_2250) + ep = usb->usbdev->ep_in[4]; + if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) usb_fill_bulk_urb(usb->intr_urb, usb->usbdev, usb_rcvbulkpipe(usb->usbdev, 4), usb->intr_urb->transfer_buffer, 2*sizeof(u16), @@ -1196,7 +1198,9 @@ u16 channel; /* read channel number from GPIO[1:0] */ - go7007_read_addr(go, 0x3c81, &channel); + if (go7007_read_addr(go, 0x3c81, &channel)) + goto allocfail; + channel &= 0x3; go->board_id = GO7007_BOARDID_ADLINK_MPG24; usb->board = board = &board_adlink_mpg24; --- linux-oracle-5.4.0.orig/drivers/media/usb/go7007/s2250-board.c +++ linux-oracle-5.4.0/drivers/media/usb/go7007/s2250-board.c @@ -504,6 +504,7 @@ u8 *data; struct go7007 *go = i2c_get_adapdata(adapter); struct go7007_usb *usb = go->hpi_context; + int err = -EIO; audio = i2c_new_dummy_device(adapter, TLV320_ADDRESS >> 1); if (IS_ERR(audio)) @@ -532,11 +533,8 @@ V4L2_CID_HUE, -512, 511, 1, 0); sd->ctrl_handler = &state->hdl; if (state->hdl.error) { - int err = state->hdl.error; - - v4l2_ctrl_handler_free(&state->hdl); - kfree(state); - return err; + err = state->hdl.error; + goto fail; } state->std = V4L2_STD_NTSC; @@ -600,7 +598,7 @@ i2c_unregister_device(audio); v4l2_ctrl_handler_free(&state->hdl); kfree(state); - return -EIO; + return err; } static int s2250_remove(struct i2c_client *client) --- linux-oracle-5.4.0.orig/drivers/media/usb/go7007/snd-go7007.c +++ linux-oracle-5.4.0/drivers/media/usb/go7007/snd-go7007.c @@ -236,22 +236,18 @@ gosnd->capturing = 0; ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0, &gosnd->card); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_snd; + ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go, &go7007_snd_device_ops); - if (ret < 0) { - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; + strscpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver)); strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->shortname)); strscpy(gosnd->card->longname, gosnd->card->shortname, @@ -262,11 +258,8 @@ &go7007_snd_capture_ops); ret = snd_card_register(gosnd->card); - if (ret < 0) { - snd_card_free(gosnd->card); - kfree(gosnd); - return ret; - } + if (ret < 0) + goto free_card; gosnd->substream = NULL; go->snd_context = gosnd; @@ -274,6 +267,12 @@ ++dev; return 0; + +free_card: + snd_card_free(gosnd->card); +free_snd: + kfree(gosnd); + return ret; } EXPORT_SYMBOL(go7007_snd_init); --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/cpia1.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/cpia1.c @@ -18,6 +18,7 @@ #include #include +#include #include "gspca.h" @@ -1027,6 +1028,8 @@ sd->params.exposure.expMode = 2; sd->exposure_status = EXPOSURE_NORMAL; } + if (sd->params.exposure.gain >= BITS_PER_TYPE(currentexp)) + return -EINVAL; currentexp = currentexp << sd->params.exposure.gain; sd->params.exposure.gain = 0; /* round down current exposure to nearest value */ @@ -1424,7 +1427,6 @@ { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - int ret; sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ; reset_camera_params(gspca_dev); @@ -1436,10 +1438,7 @@ cam->cam_mode = mode; cam->nmodes = ARRAY_SIZE(mode); - ret = goto_low_power(gspca_dev); - if (ret) - gspca_err(gspca_dev, "Cannot go to low power mode: %d\n", - ret); + goto_low_power(gspca_dev); /* Check the firmware version. */ sd->params.version.firmwareVersion = 0; get_version_information(gspca_dev); --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/gl860/gl860.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/gl860/gl860.c @@ -561,8 +561,8 @@ len, 400 + 200 * (len > 1)); memcpy(pdata, gspca_dev->usb_buf, len); } else { - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - req, pref, val, index, NULL, len, 400); + gspca_err(gspca_dev, "zero-length read request\n"); + r = -EINVAL; } } --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/gspca.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/gspca.c @@ -1461,7 +1461,7 @@ pr_err("couldn't kzalloc gspca struct\n"); return -ENOMEM; } - gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL); + gspca_dev->usb_buf = kzalloc(USB_BUF_SZ, GFP_KERNEL); if (!gspca_dev->usb_buf) { pr_err("out of memory\n"); ret = -ENOMEM; @@ -1575,6 +1575,9 @@ input_unregister_device(gspca_dev->input_dev); #endif v4l2_ctrl_handler_free(gspca_dev->vdev.ctrl_handler); + v4l2_device_unregister(&gspca_dev->v4l2_dev); + if (sd_desc->probe_error) + sd_desc->probe_error(gspca_dev); kfree(gspca_dev->usb_buf); kfree(gspca_dev); return ret; --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/gspca.h +++ linux-oracle-5.4.0/drivers/media/usb/gspca/gspca.h @@ -105,6 +105,7 @@ cam_cf_op config; /* called on probe */ cam_op init; /* called on probe and resume */ cam_op init_controls; /* called on probe */ + cam_v_op probe_error; /* called if probe failed, do cleanup here */ cam_op start; /* called on stream on after URBs creation */ cam_pkt_op pkt_scan; /* optional operations */ --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/m5602/m5602_mt9m111.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/m5602/m5602_mt9m111.c @@ -195,7 +195,7 @@ int mt9m111_probe(struct sd *sd) { u8 data[2] = {0x00, 0x00}; - int i, rc = 0; + int i, err; struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { @@ -213,18 +213,18 @@ /* Do the preinit */ for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) { if (preinit_mt9m111[i][0] == BRIDGE) { - rc |= m5602_write_bridge(sd, - preinit_mt9m111[i][1], - preinit_mt9m111[i][2]); + err = m5602_write_bridge(sd, + preinit_mt9m111[i][1], + preinit_mt9m111[i][2]); } else { data[0] = preinit_mt9m111[i][2]; data[1] = preinit_mt9m111[i][3]; - rc |= m5602_write_sensor(sd, - preinit_mt9m111[i][1], data, 2); + err = m5602_write_sensor(sd, + preinit_mt9m111[i][1], data, 2); } + if (err < 0) + return err; } - if (rc < 0) - return rc; if (m5602_read_sensor(sd, MT9M111_SC_CHIPVER, data, 2)) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/m5602/m5602_po1030.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/m5602/m5602_po1030.c @@ -154,8 +154,8 @@ int po1030_probe(struct sd *sd) { - int rc = 0; u8 dev_id_h = 0, i; + int err; struct gspca_dev *gspca_dev = (struct gspca_dev *)sd; if (force_sensor) { @@ -174,14 +174,14 @@ for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) { u8 data = preinit_po1030[i][2]; if (preinit_po1030[i][0] == SENSOR) - rc |= m5602_write_sensor(sd, - preinit_po1030[i][1], &data, 1); + err = m5602_write_sensor(sd, preinit_po1030[i][1], + &data, 1); else - rc |= m5602_write_bridge(sd, preinit_po1030[i][1], - data); + err = m5602_write_bridge(sd, preinit_po1030[i][1], + data); + if (err < 0) + return err; } - if (rc < 0) - return rc; if (m5602_read_sensor(sd, PO1030_DEVID_H, &dev_id_h, 1)) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/ov519.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/ov519.c @@ -3477,6 +3477,11 @@ return; } + if (alt->desc.bNumEndpoints < 1) { + sd->gspca_dev.usb_err = -ENODEV; + return; + } + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5); @@ -3603,6 +3608,11 @@ return; } + if (alt->desc.bNumEndpoints < 1) { + sd->gspca_dev.usb_err = -ENODEV; + return; + } + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2); --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/ov534.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/ov534.c @@ -847,7 +847,7 @@ r = rate_1; i = ARRAY_SIZE(rate_1); } - while (--i > 0) { + while (--i >= 0) { if (sd->frame_rate >= r->fps) break; r++; --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/sq905.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/sq905.c @@ -116,7 +116,7 @@ } ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), + usb_rcvctrlpipe(gspca_dev->dev, 0), USB_REQ_SYNCH_FRAME, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQ905_PING, 0, gspca_dev->usb_buf, 1, @@ -158,7 +158,7 @@ sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size, int need_lock) { int ret; - int act_len; + int act_len = 0; gspca_dev->usb_buf[0] = '\0'; if (need_lock) --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -282,6 +282,9 @@ return -EIO; } + if (alt->desc.bNumEndpoints < 1) + return -ENODEV; + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size); if (err < 0) @@ -306,11 +309,21 @@ static int stv06xx_isoc_init(struct gspca_dev *gspca_dev) { + struct usb_interface_cache *intfc; struct usb_host_interface *alt; struct sd *sd = (struct sd *) gspca_dev; + intfc = gspca_dev->dev->actconfig->intf_cache[0]; + + if (intfc->num_altsetting < 2) + return -ENODEV; + + alt = &intfc->altsetting[1]; + + if (alt->desc.bNumEndpoints < 1) + return -ENODEV; + /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]); @@ -323,6 +336,10 @@ struct usb_host_interface *alt; struct sd *sd = (struct sd *) gspca_dev; + /* + * Existence of altsetting and endpoint was verified in + * stv06xx_isoc_init() + */ alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode]; @@ -512,12 +529,21 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id); +static void stv06xx_probe_error(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *)gspca_dev; + + kfree(sd->sensor_priv); + sd->sensor_priv = NULL; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, .config = stv06xx_config, .init = stv06xx_init, .init_controls = stv06xx_init_controls, + .probe_error = stv06xx_probe_error, .start = stv06xx_start, .stopN = stv06xx_stopN, .pkt_scan = stv06xx_pkt_scan, --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c @@ -185,6 +185,10 @@ alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt); if (!alt) return -ENODEV; + + if (alt->desc.bNumEndpoints < 1) + return -ENODEV; + packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); /* If we don't have enough bandwidth use a lower framerate */ --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/sunplus.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/sunplus.c @@ -242,6 +242,10 @@ gspca_err(gspca_dev, "reg_r: buffer overflow\n"); return; } + if (len == 0) { + gspca_err(gspca_dev, "reg_r: zero-length read\n"); + return; + } if (gspca_dev->usb_err < 0) return; ret = usb_control_msg(gspca_dev->dev, @@ -250,7 +254,7 @@ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - len ? gspca_dev->usb_buf : NULL, len, + gspca_dev->usb_buf, len, 500); if (ret < 0) { pr_err("reg_r err %d\n", ret); @@ -727,7 +731,7 @@ case MegaImageVI: reg_w_riv(gspca_dev, 0xf0, 0, 0); spca504B_WaitCmdStatus(gspca_dev); - reg_r(gspca_dev, 0xf0, 4, 0); + reg_w_riv(gspca_dev, 0xf0, 4, 0); spca504B_WaitCmdStatus(gspca_dev); break; default: --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/vicam.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/vicam.c @@ -225,7 +225,7 @@ { int ret; const struct ihex_binrec *rec; - const struct firmware *uninitialized_var(fw); + const struct firmware *fw; u8 *firmware_buf; ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, --- linux-oracle-5.4.0.orig/drivers/media/usb/gspca/xirlink_cit.c +++ linux-oracle-5.4.0/drivers/media/usb/gspca/xirlink_cit.c @@ -1442,6 +1442,9 @@ return -EIO; } + if (alt->desc.bNumEndpoints < 1) + return -ENODEV; + return le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); } @@ -2626,6 +2629,7 @@ static int sd_isoc_init(struct gspca_dev *gspca_dev) { + struct usb_interface_cache *intfc; struct usb_host_interface *alt; int max_packet_size; @@ -2641,8 +2645,17 @@ break; } + intfc = gspca_dev->dev->actconfig->intf_cache[0]; + + if (intfc->num_altsetting < 2) + return -ENODEV; + + alt = &intfc->altsetting[1]; + + if (alt->desc.bNumEndpoints < 1) + return -ENODEV; + /* Start isoc bandwidth "negotiation" at max isoc bandwidth */ - alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(max_packet_size); return 0; @@ -2665,6 +2678,9 @@ break; } + /* + * Existence of altsetting and endpoint was verified in sd_isoc_init() + */ alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1]; packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); if (packet_size <= min_packet_size) --- linux-oracle-5.4.0.orig/drivers/media/usb/hdpvr/hdpvr-video.c +++ linux-oracle-5.4.0/drivers/media/usb/hdpvr/hdpvr-video.c @@ -308,7 +308,6 @@ dev->status = STATUS_STREAMING; - INIT_WORK(&dev->worker, hdpvr_transmit_buffers); schedule_work(&dev->worker); v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, @@ -410,7 +409,7 @@ struct hdpvr_device *dev = video_drvdata(file); struct hdpvr_buffer *buf = NULL; struct urb *urb; - unsigned int ret = 0; + int ret = 0; int rem, cnt; if (*pos) @@ -1165,6 +1164,9 @@ bool ac3 = dev->flags & HDPVR_FLAG_AC3_CAP; int res; + // initialize dev->worker + INIT_WORK(&dev->worker, hdpvr_transmit_buffers); + dev->cur_std = V4L2_STD_525_60; dev->width = 720; dev->height = 480; --- linux-oracle-5.4.0.orig/drivers/media/usb/msi2500/msi2500.c +++ linux-oracle-5.4.0/drivers/media/usb/msi2500/msi2500.c @@ -1230,7 +1230,7 @@ } dev->master = master; - master->bus_num = 0; + master->bus_num = -1; master->num_chipselect = 1; master->transfer_one_message = msi2500_transfer_one_message; spi_master_set_devdata(master, dev); --- linux-oracle-5.4.0.orig/drivers/media/usb/pulse8-cec/pulse8-cec.c +++ linux-oracle-5.4.0/drivers/media/usb/pulse8-cec/pulse8-cec.c @@ -116,6 +116,7 @@ unsigned int vers; struct completion cmd_done; struct work_struct work; + u8 work_result; struct delayed_work ping_eeprom_work; struct cec_msg rx_msg; u8 data[DATA_SIZE]; @@ -137,8 +138,10 @@ { struct pulse8 *pulse8 = container_of(work, struct pulse8, work); + u8 result = pulse8->work_result; - switch (pulse8->data[0] & 0x3f) { + pulse8->work_result = 0; + switch (result & 0x3f) { case MSGCODE_FRAME_DATA: cec_received_msg(pulse8->adap, &pulse8->rx_msg); break; @@ -172,12 +175,12 @@ pulse8->escape = false; } else if (data == MSGEND) { struct cec_msg *msg = &pulse8->rx_msg; + u8 msgcode = pulse8->buf[0]; if (debug) dev_info(pulse8->dev, "received: %*ph\n", pulse8->idx, pulse8->buf); - pulse8->data[0] = pulse8->buf[0]; - switch (pulse8->buf[0] & 0x3f) { + switch (msgcode & 0x3f) { case MSGCODE_FRAME_START: msg->len = 1; msg->msg[0] = pulse8->buf[1]; @@ -186,14 +189,20 @@ if (msg->len == CEC_MAX_MSG_SIZE) break; msg->msg[msg->len++] = pulse8->buf[1]; - if (pulse8->buf[0] & MSGCODE_FRAME_EOM) + if (msgcode & MSGCODE_FRAME_EOM) { + WARN_ON(pulse8->work_result); + pulse8->work_result = msgcode; schedule_work(&pulse8->work); + break; + } break; case MSGCODE_TRANSMIT_SUCCEEDED: case MSGCODE_TRANSMIT_FAILED_LINE: case MSGCODE_TRANSMIT_FAILED_ACK: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_DATA: case MSGCODE_TRANSMIT_FAILED_TIMEOUT_LINE: + WARN_ON(pulse8->work_result); + pulse8->work_result = msgcode; schedule_work(&pulse8->work); break; case MSGCODE_HIGH_ERROR: --- linux-oracle-5.4.0.orig/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ linux-oracle-5.4.0/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -90,8 +90,10 @@ } -static void pvr2_context_notify(struct pvr2_context *mp) +static void pvr2_context_notify(void *ptr) { + struct pvr2_context *mp = ptr; + pvr2_context_set_notify(mp,!0); } @@ -106,9 +108,7 @@ pvr2_trace(PVR2_TRACE_CTXT, "pvr2_context %p (initialize)", mp); /* Finish hardware initialization */ - if (pvr2_hdw_initialize(mp->hdw, - (void (*)(void *))pvr2_context_notify, - mp)) { + if (pvr2_hdw_initialize(mp->hdw, pvr2_context_notify, mp)) { mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); /* Trigger interface initialization. By doing this @@ -267,8 +267,9 @@ void pvr2_context_disconnect(struct pvr2_context *mp) { pvr2_hdw_disconnect(mp->hdw); + if (!pvr2_context_shutok()) + pvr2_context_notify(mp); mp->disconnect_flag = !0; - pvr2_context_notify(mp); } --- linux-oracle-5.4.0.orig/drivers/media/usb/pvrusb2/pvrusb2-dvb.c +++ linux-oracle-5.4.0/drivers/media/usb/pvrusb2/pvrusb2-dvb.c @@ -88,8 +88,10 @@ return stat; } -static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap) +static void pvr2_dvb_notify(void *ptr) { + struct pvr2_dvb_adapter *adap = ptr; + wake_up(&adap->buffer_wait_data); } @@ -149,7 +151,7 @@ } pvr2_stream_set_callback(pvr->video_stream.stream, - (pvr2_stream_callback) pvr2_dvb_notify, adap); + pvr2_dvb_notify, adap); ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ linux-oracle-5.4.0/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -1468,7 +1468,7 @@ for (address = 0; address < fwsize; address += 0x800) { memcpy(fw_ptr, fw_entry->data + address, 0x800); ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, - 0, fw_ptr, 0x800, HZ); + 0, fw_ptr, 0x800, 1000); } trace_firmware("Upload done, releasing device's CPU"); @@ -1606,7 +1606,7 @@ ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, - &actual_length, HZ); + &actual_length, 1000); ret |= (actual_length != bcnt); if (ret) break; fw_done += bcnt; @@ -2570,6 +2570,11 @@ } while (0); mutex_unlock(&pvr2_unit_mtx); + INIT_WORK(&hdw->workpoll, pvr2_hdw_worker_poll); + + if (hdw->unit_number == -1) + goto fail; + cnt1 = 0; cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); cnt1 += cnt2; @@ -2581,8 +2586,6 @@ if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; hdw->name[cnt1] = 0; - INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); - pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", hdw->unit_number,hdw->name); @@ -2608,6 +2611,7 @@ del_timer_sync(&hdw->encoder_run_timer); del_timer_sync(&hdw->encoder_wait_timer); flush_work(&hdw->workpoll); + v4l2_device_unregister(&hdw->v4l2_dev); usb_free_urb(hdw->ctl_read_urb); usb_free_urb(hdw->ctl_write_urb); kfree(hdw->ctl_read_buffer); @@ -2677,9 +2681,8 @@ pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = NULL; } - pvr2_i2c_core_done(hdw); v4l2_device_unregister(&hdw->v4l2_dev); - pvr2_hdw_remove_usb_stuff(hdw); + pvr2_hdw_disconnect(hdw); mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && @@ -2706,6 +2709,7 @@ { pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); LOCK_TAKE(hdw->big_lock); + pvr2_i2c_core_done(hdw); LOCK_TAKE(hdw->ctl_lock); pvr2_hdw_remove_usb_stuff(hdw); LOCK_GIVE(hdw->ctl_lock); @@ -3439,7 +3443,7 @@ 0xa0,0xc0, address,0, hdw->fw_buffer+address, - 0x800,HZ); + 0x800,1000); if (ret < 0) break; } @@ -3978,7 +3982,7 @@ /* Write the CPUCS register on the 8051. The lsb of the register is the reset bit; a 1 asserts reset while a 0 clears it. */ pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); + ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,1000); if (ret < 0) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "cpureset_assert(%d) error=%d",val,ret); --- linux-oracle-5.4.0.orig/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ linux-oracle-5.4.0/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -898,8 +898,12 @@ pvr2_v4l2_dev_disassociate_parent(vp->dev_video); pvr2_v4l2_dev_disassociate_parent(vp->dev_radio); if (!list_empty(&vp->dev_video->devbase.fh_list) || - !list_empty(&vp->dev_radio->devbase.fh_list)) + (vp->dev_radio && + !list_empty(&vp->dev_radio->devbase.fh_list))) { + pvr2_trace(PVR2_TRACE_STRUCT, + "pvr2_v4l2 internal_check exit-empty id=%p", vp); return; + } pvr2_v4l2_destroy_no_lock(vp); } @@ -935,7 +939,8 @@ kfree(fhp); if (vp->channel.mc_head->disconnect_flag && list_empty(&vp->dev_video->devbase.fh_list) && - list_empty(&vp->dev_radio->devbase.fh_list)) { + (!vp->dev_radio || + list_empty(&vp->dev_radio->devbase.fh_list))) { pvr2_v4l2_destroy_no_lock(vp); } return 0; @@ -1032,8 +1037,10 @@ } -static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) +static void pvr2_v4l2_notify(void *ptr) { + struct pvr2_v4l2_fh *fhp = ptr; + wake_up(&fhp->wait_data); } @@ -1066,7 +1073,7 @@ hdw = fh->channel.mc_head->hdw; sp = fh->pdi->stream->stream; - pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); + pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh); pvr2_hdw_set_stream_type(hdw,fh->pdi->config); if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret; return pvr2_ioread_set_enabled(fh->rhp,!0); @@ -1197,11 +1204,6 @@ dip->minor_type = pvr2_v4l_type_video; nr_ptr = video_nr; caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO; - if (!dip->stream) { - pr_err(KBUILD_MODNAME - ": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n"); - return; - } break; case VFL_TYPE_VBI: dip->config = pvr2_config_vbi; --- linux-oracle-5.4.0.orig/drivers/media/usb/pwc/pwc-if.c +++ linux-oracle-5.4.0/drivers/media/usb/pwc/pwc-if.c @@ -147,16 +147,17 @@ /***************************************************************************/ /* Private functions */ -static void *pwc_alloc_urb_buffer(struct device *dev, +static void *pwc_alloc_urb_buffer(struct usb_device *dev, size_t size, dma_addr_t *dma_handle) { + struct device *dmadev = dev->bus->sysdev; void *buffer = kmalloc(size, GFP_KERNEL); if (!buffer) return NULL; - *dma_handle = dma_map_single(dev, buffer, size, DMA_FROM_DEVICE); - if (dma_mapping_error(dev, *dma_handle)) { + *dma_handle = dma_map_single(dmadev, buffer, size, DMA_FROM_DEVICE); + if (dma_mapping_error(dmadev, *dma_handle)) { kfree(buffer); return NULL; } @@ -164,12 +165,14 @@ return buffer; } -static void pwc_free_urb_buffer(struct device *dev, +static void pwc_free_urb_buffer(struct usb_device *dev, size_t size, void *buffer, dma_addr_t dma_handle) { - dma_unmap_single(dev, dma_handle, size, DMA_FROM_DEVICE); + struct device *dmadev = dev->bus->sysdev; + + dma_unmap_single(dmadev, dma_handle, size, DMA_FROM_DEVICE); kfree(buffer); } @@ -274,6 +277,7 @@ static void pwc_isoc_handler(struct urb *urb) { struct pwc_device *pdev = (struct pwc_device *)urb->context; + struct device *dmadev = urb->dev->bus->sysdev; int i, fst, flen; unsigned char *iso_buf = NULL; @@ -320,7 +324,7 @@ /* Reset ISOC error counter. We did get here, after all. */ pdev->visoc_errors = 0; - dma_sync_single_for_cpu(&urb->dev->dev, + dma_sync_single_for_cpu(dmadev, urb->transfer_dma, urb->transfer_buffer_length, DMA_FROM_DEVICE); @@ -371,7 +375,7 @@ pdev->vlast_packet_size = flen; } - dma_sync_single_for_device(&urb->dev->dev, + dma_sync_single_for_device(dmadev, urb->transfer_dma, urb->transfer_buffer_length, DMA_FROM_DEVICE); @@ -453,7 +457,7 @@ urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint); urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->transfer_buffer_length = ISO_BUFFER_SIZE; - urb->transfer_buffer = pwc_alloc_urb_buffer(&udev->dev, + urb->transfer_buffer = pwc_alloc_urb_buffer(udev, urb->transfer_buffer_length, &urb->transfer_dma); if (urb->transfer_buffer == NULL) { @@ -516,7 +520,7 @@ if (urb) { PWC_DEBUG_MEMORY("Freeing URB\n"); if (urb->transfer_buffer) - pwc_free_urb_buffer(&urb->dev->dev, + pwc_free_urb_buffer(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); --- linux-oracle-5.4.0.orig/drivers/media/usb/s2255/s2255drv.c +++ linux-oracle-5.4.0/drivers/media/usb/s2255/s2255drv.c @@ -247,7 +247,7 @@ struct s2255_dev { struct s2255_vc vc[MAX_CHANNELS]; struct v4l2_device v4l2_dev; - atomic_t num_channels; + refcount_t num_channels; int frames; struct mutex lock; /* channels[].vdev.lock */ struct mutex cmdlock; /* protects cmdbuf */ @@ -1552,11 +1552,11 @@ container_of(vdev, struct s2255_vc, vdev); dprintk(dev, 4, "%s, chnls: %d\n", __func__, - atomic_read(&dev->num_channels)); + refcount_read(&dev->num_channels)); v4l2_ctrl_handler_free(&vc->hdl); - if (atomic_dec_and_test(&dev->num_channels)) + if (refcount_dec_and_test(&dev->num_channels)) s2255_destroy(dev); return; } @@ -1661,7 +1661,7 @@ "failed to register video device!\n"); break; } - atomic_inc(&dev->num_channels); + refcount_inc(&dev->num_channels); v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", video_device_node_name(&vc->vdev)); @@ -1669,11 +1669,11 @@ pr_info("Sensoray 2255 V4L driver Revision: %s\n", S2255_VERSION); /* if no channels registered, return error and probe will fail*/ - if (atomic_read(&dev->num_channels) == 0) { + if (refcount_read(&dev->num_channels) == 0) { v4l2_device_unregister(&dev->v4l2_dev); return ret; } - if (atomic_read(&dev->num_channels) != MAX_CHANNELS) + if (refcount_read(&dev->num_channels) != MAX_CHANNELS) pr_warn("s2255: Not all channels available.\n"); return 0; } @@ -1884,7 +1884,7 @@ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, Value, Index, buf, - TransferBufferLength, HZ * 5); + TransferBufferLength, USB_CTRL_SET_TIMEOUT); if (r >= 0) memcpy(TransferBuffer, buf, TransferBufferLength); @@ -1893,7 +1893,7 @@ r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE, Value, Index, buf, - TransferBufferLength, HZ * 5); + TransferBufferLength, USB_CTRL_SET_TIMEOUT); } kfree(buf); return r; @@ -2222,7 +2222,7 @@ goto errorFWDATA1; } - atomic_set(&dev->num_channels, 0); + refcount_set(&dev->num_channels, 0); dev->pid = id->idProduct; dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); if (!dev->fw_data) @@ -2342,12 +2342,12 @@ { struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface)); int i; - int channels = atomic_read(&dev->num_channels); + int channels = refcount_read(&dev->num_channels); mutex_lock(&dev->lock); v4l2_device_disconnect(&dev->v4l2_dev); mutex_unlock(&dev->lock); /*see comments in the uvc_driver.c usb disconnect function */ - atomic_inc(&dev->num_channels); + refcount_inc(&dev->num_channels); /* unregister each video device. */ for (i = 0; i < channels; i++) video_unregister_device(&dev->vc[i].vdev); @@ -2360,7 +2360,7 @@ dev->vc[i].vidstatus_ready = 1; wake_up(&dev->vc[i].wait_vidstatus); } - if (atomic_dec_and_test(&dev->num_channels)) + if (refcount_dec_and_test(&dev->num_channels)) s2255_destroy(dev); dev_info(&interface->dev, "%s\n", __func__); } --- linux-oracle-5.4.0.orig/drivers/media/usb/siano/smsusb.c +++ linux-oracle-5.4.0/drivers/media/usb/siano/smsusb.c @@ -179,6 +179,8 @@ for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); + if (dev->surbs[i].wq.func) + cancel_work_sync(&dev->surbs[i].wq); if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb); @@ -453,12 +455,7 @@ rc = smscore_register_device(¶ms, &dev->coredev, 0, mdev); if (rc < 0) { pr_err("smscore_register_device(...) failed, rc %d\n", rc); - smsusb_term_device(intf); -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - media_device_unregister(mdev); -#endif - kfree(mdev); - return rc; + goto err_unregister_device; } smscore_set_board_id(dev->coredev, board_id); @@ -475,8 +472,7 @@ rc = smsusb_start_streaming(dev); if (rc < 0) { pr_err("smsusb_start_streaming(...) failed\n"); - smsusb_term_device(intf); - return rc; + goto err_unregister_device; } dev->state = SMSUSB_ACTIVE; @@ -484,13 +480,20 @@ rc = smscore_start_device(dev->coredev); if (rc < 0) { pr_err("smscore_start_device(...) failed\n"); - smsusb_term_device(intf); - return rc; + goto err_unregister_device; } pr_debug("device 0x%p created\n", dev); return rc; + +err_unregister_device: + smsusb_term_device(intf); +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + media_device_unregister(mdev); +#endif + kfree(mdev); + return rc; } static int smsusb_probe(struct usb_interface *intf, --- linux-oracle-5.4.0.orig/drivers/media/usb/stk1160/stk1160-core.c +++ linux-oracle-5.4.0/drivers/media/usb/stk1160/stk1160-core.c @@ -65,7 +65,7 @@ return -ENOMEM; ret = usb_control_msg(dev->udev, pipe, 0x00, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, reg, buf, sizeof(u8), HZ); + 0x00, reg, buf, sizeof(u8), 1000); if (ret < 0) { stk1160_err("read failed on reg 0x%x (%d)\n", reg, ret); @@ -85,7 +85,7 @@ ret = usb_control_msg(dev->udev, pipe, 0x01, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, reg, NULL, 0, HZ); + value, reg, NULL, 0, 1000); if (ret < 0) { stk1160_err("write failed on reg 0x%x (%d)\n", reg, ret); @@ -403,7 +403,7 @@ /* Here is the only place where isoc get released */ stk1160_uninit_isoc(dev); - stk1160_clear_queue(dev); + stk1160_clear_queue(dev, VB2_BUF_STATE_ERROR); video_unregister_device(&dev->vdev); v4l2_device_disconnect(&dev->v4l2_dev); --- linux-oracle-5.4.0.orig/drivers/media/usb/stk1160/stk1160-v4l.c +++ linux-oracle-5.4.0/drivers/media/usb/stk1160/stk1160-v4l.c @@ -258,7 +258,7 @@ stk1160_uninit_isoc(dev); out_stop_hw: usb_set_interface(dev->udev, 0, 0); - stk1160_clear_queue(dev); + stk1160_clear_queue(dev, VB2_BUF_STATE_QUEUED); mutex_unlock(&dev->v4l_lock); @@ -306,7 +306,7 @@ stk1160_stop_hw(dev); - stk1160_clear_queue(dev); + stk1160_clear_queue(dev, VB2_BUF_STATE_ERROR); stk1160_dbg("streaming stopped\n"); @@ -745,7 +745,7 @@ /********************************************************************/ /* Must be called with both v4l_lock and vb_queue_lock hold */ -void stk1160_clear_queue(struct stk1160 *dev) +void stk1160_clear_queue(struct stk1160 *dev, enum vb2_buffer_state vb2_state) { struct stk1160_buffer *buf; unsigned long flags; @@ -756,7 +756,7 @@ buf = list_first_entry(&dev->avail_bufs, struct stk1160_buffer, list); list_del(&buf->list); - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); stk1160_dbg("buffer [%p/%d] aborted\n", buf, buf->vb.vb2_buf.index); } @@ -766,7 +766,7 @@ buf = dev->isoc_ctl.buf; dev->isoc_ctl.buf = NULL; - vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&buf->vb.vb2_buf, vb2_state); stk1160_dbg("buffer [%p/%d] aborted\n", buf, buf->vb.vb2_buf.index); } --- linux-oracle-5.4.0.orig/drivers/media/usb/stk1160/stk1160-video.c +++ linux-oracle-5.4.0/drivers/media/usb/stk1160/stk1160-video.c @@ -99,7 +99,7 @@ static inline void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len) { - int linesdone, lineoff, lencopy; + int linesdone, lineoff, lencopy, offset; int bytesperline = dev->width * 2; struct stk1160_buffer *buf = dev->isoc_ctl.buf; u8 *dst = buf->mem; @@ -107,8 +107,7 @@ /* * TODO: These stk1160_dbg are very spammy! - * We should 1) check why we are getting them - * and 2) add ratelimit. + * We should check why we are getting them. * * UPDATE: One of the reasons (the only one?) for getting these * is incorrect standard (mismatch between expected and configured). @@ -140,8 +139,13 @@ * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "out of bounds offset\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } @@ -151,7 +155,7 @@ /* Let the bug hunt begin! sanity checks! */ if (lencopy < 0) { - stk1160_dbg("copy skipped: negative lencopy\n"); + printk_ratelimited(KERN_DEBUG "copy skipped: negative lencopy\n"); return; } @@ -183,8 +187,13 @@ * Check if we have enough space left in the buffer. * In that case, we force loop exit after copy. */ - if (lencopy > buf->bytesused - buf->length) { - lencopy = buf->bytesused - buf->length; + offset = dst - (u8 *)buf->mem; + if (offset > buf->length) { + dev_warn_ratelimited(dev->dev, "offset out of bounds\n"); + return; + } + if (lencopy > buf->length - offset) { + lencopy = buf->length - offset; remain = lencopy; } --- linux-oracle-5.4.0.orig/drivers/media/usb/stk1160/stk1160.h +++ linux-oracle-5.4.0/drivers/media/usb/stk1160/stk1160.h @@ -166,7 +166,7 @@ int stk1160_vb2_setup(struct stk1160 *dev); int stk1160_video_register(struct stk1160 *dev); void stk1160_video_unregister(struct stk1160 *dev); -void stk1160_clear_queue(struct stk1160 *dev); +void stk1160_clear_queue(struct stk1160 *dev, enum vb2_buffer_state vb2_state); /* Provided by stk1160-video.c */ int stk1160_alloc_isoc(struct stk1160 *dev); --- linux-oracle-5.4.0.orig/drivers/media/usb/stkwebcam/stk-webcam.c +++ linux-oracle-5.4.0/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1346,7 +1346,7 @@ if (!dev->isoc_ep) { pr_err("Could not find isoc-in endpoint\n"); err = -ENODEV; - goto error; + goto error_put; } dev->vsettings.palette = V4L2_PIX_FMT_RGB565; dev->vsettings.mode = MODE_VGA; @@ -1359,10 +1359,12 @@ err = stk_register_video_device(dev); if (err) - goto error; + goto error_put; return 0; +error_put: + usb_put_intf(interface); error: v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&dev->v4l2_dev); --- linux-oracle-5.4.0.orig/drivers/media/usb/tm6000/tm6000-dvb.c +++ linux-oracle-5.4.0/drivers/media/usb/tm6000/tm6000-dvb.c @@ -141,6 +141,10 @@ if (ret < 0) { printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n", ret, __func__); + + kfree(dvb->bulk_urb->transfer_buffer); + usb_free_urb(dvb->bulk_urb); + dvb->bulk_urb = NULL; return ret; } else printk(KERN_ERR "tm6000: pipe reset\n"); --- linux-oracle-5.4.0.orig/drivers/media/usb/tm6000/tm6000-video.c +++ linux-oracle-5.4.0/drivers/media/usb/tm6000/tm6000-video.c @@ -461,11 +461,12 @@ if (dev->urb_buffer) return 0; - dev->urb_buffer = kmalloc_array(num_bufs, sizeof(void *), GFP_KERNEL); + dev->urb_buffer = kmalloc_array(num_bufs, sizeof(*dev->urb_buffer), + GFP_KERNEL); if (!dev->urb_buffer) return -ENOMEM; - dev->urb_dma = kmalloc_array(num_bufs, sizeof(dma_addr_t *), + dev->urb_dma = kmalloc_array(num_bufs, sizeof(*dev->urb_dma), GFP_KERNEL); if (!dev->urb_dma) return -ENOMEM; @@ -853,8 +854,7 @@ struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; strscpy(cap->driver, "tm6000", sizeof(cap->driver)); - strscpy(cap->card, "Trident TVMaster TM5600/6000/6010", - sizeof(cap->card)); + strscpy(cap->card, "Trident TM5600/6000/6010", sizeof(cap->card)); usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; --- linux-oracle-5.4.0.orig/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ linux-oracle-5.4.0/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -1551,8 +1551,7 @@ dvb_dmx_release(&dec->demux); if (dec->fe) { dvb_unregister_frontend(dec->fe); - if (dec->fe->ops.release) - dec->fe->ops.release(dec->fe); + dvb_frontend_detach(dec->fe); } dvb_unregister_adapter(&dec->adapter); } --- linux-oracle-5.4.0.orig/drivers/media/usb/usbtv/usbtv-audio.c +++ linux-oracle-5.4.0/drivers/media/usb/usbtv/usbtv-audio.c @@ -399,7 +399,7 @@ cancel_work_sync(&usbtv->snd_trigger); if (usbtv->snd && usbtv->udev) { - snd_card_free(usbtv->snd); + snd_card_free_when_closed(usbtv->snd); usbtv->snd = NULL; } } --- linux-oracle-5.4.0.orig/drivers/media/usb/usbtv/usbtv-core.c +++ linux-oracle-5.4.0/drivers/media/usb/usbtv/usbtv-core.c @@ -56,7 +56,7 @@ ret = usb_control_msg(usbtv->udev, pipe, USBTV_REQUEST_REG, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, NULL, 0, 0); + value, index, NULL, 0, USB_CTRL_GET_TIMEOUT); if (ret < 0) return ret; } @@ -113,7 +113,8 @@ usbtv_audio_fail: /* we must not free at this point */ - usb_get_dev(usbtv->udev); + v4l2_device_get(&usbtv->v4l2_dev); + /* this will undo the v4l2_device_get() */ usbtv_video_free(usbtv); usbtv_video_fail: --- linux-oracle-5.4.0.orig/drivers/media/usb/usbtv/usbtv-video.c +++ linux-oracle-5.4.0/drivers/media/usb/usbtv/usbtv-video.c @@ -800,7 +800,8 @@ ret = usb_control_msg(usbtv->udev, usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, USBTV_BASE + 0x0244, (void *)data, 3, 0); + 0, USBTV_BASE + 0x0244, (void *)data, 3, + USB_CTRL_GET_TIMEOUT); if (ret < 0) goto error; } @@ -851,7 +852,7 @@ ret = usb_control_msg(usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, (void *)data, size, 0); + 0, index, (void *)data, size, USB_CTRL_SET_TIMEOUT); error: if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/media/usb/usbvision/usbvision-video.c +++ linux-oracle-5.4.0/drivers/media/usb/usbvision/usbvision-video.c @@ -314,6 +314,10 @@ if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto unlock; + } if (usbvision->user) { err_code = -EBUSY; } else { @@ -377,6 +381,7 @@ static int usbvision_v4l2_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, "close"); @@ -391,9 +396,10 @@ usbvision_scratch_free(usbvision); usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); usbvision_release(usbvision); return 0; @@ -453,6 +459,9 @@ { struct usb_usbvision *usbvision = video_drvdata(file); + if (!usbvision->dev) + return -ENODEV; + strscpy(vc->driver, "USBVision", sizeof(vc->driver)); strscpy(vc->card, usbvision_device_data[usbvision->dev_model].model_string, @@ -1061,6 +1070,11 @@ if (mutex_lock_interruptible(&usbvision->v4l2_lock)) return -ERESTARTSYS; + + if (usbvision->remove_pending) { + err_code = -ENODEV; + goto out; + } err_code = v4l2_fh_open(file); if (err_code) goto out; @@ -1093,21 +1107,24 @@ static int usbvision_radio_close(struct file *file) { struct usb_usbvision *usbvision = video_drvdata(file); + int r; PDEBUG(DBG_IO, ""); mutex_lock(&usbvision->v4l2_lock); /* Set packet size to 0 */ usbvision->iface_alt = 0; - usb_set_interface(usbvision->dev, usbvision->iface, - usbvision->iface_alt); + if (usbvision->dev) + usb_set_interface(usbvision->dev, usbvision->iface, + usbvision->iface_alt); usbvision_audio_off(usbvision); usbvision->radio = 0; usbvision->user--; + r = usbvision->remove_pending; mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->remove_pending) { + if (r) { printk(KERN_INFO "%s: Final disconnect\n", __func__); v4l2_fh_release(file); usbvision_release(usbvision); @@ -1539,6 +1556,7 @@ static void usbvision_disconnect(struct usb_interface *intf) { struct usb_usbvision *usbvision = to_usbvision(usb_get_intfdata(intf)); + int u; PDEBUG(DBG_PROBE, ""); @@ -1555,13 +1573,14 @@ v4l2_device_disconnect(&usbvision->v4l2_dev); usbvision_i2c_unregister(usbvision); usbvision->remove_pending = 1; /* Now all ISO data will be ignored */ + u = usbvision->user; usb_put_dev(usbvision->dev); usbvision->dev = NULL; /* USB device is no more */ mutex_unlock(&usbvision->v4l2_lock); - if (usbvision->user) { + if (u) { printk(KERN_INFO "%s: In use, disconnect pending\n", __func__); wake_up_interruptible(&usbvision->wait_frame); --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_ctrl.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_ctrl.c @@ -6,6 +6,7 @@ * Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ +#include #include #include #include @@ -773,12 +774,16 @@ offset &= 7; mask = ((1LL << bits) - 1) << offset; - for (; bits > 0; data++) { + while (1) { u8 byte = *data & mask; value |= offset > 0 ? (byte >> offset) : (byte << (-offset)); bits -= 8 - (offset > 0 ? offset : 0); + if (bits <= 0) + break; + offset -= 8; mask = (1 << bits) - 1; + data++; } /* Sign-extend the value if needed. */ @@ -987,26 +992,56 @@ return value; } -static int __uvc_ctrl_get(struct uvc_video_chain *chain, - struct uvc_control *ctrl, struct uvc_control_mapping *mapping, - s32 *value) +static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain, + struct uvc_control *ctrl) { + u8 *data; int ret; - if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) - return -EACCES; + if (ctrl->loaded) + return 0; - if (!ctrl->loaded) { - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, - chain->dev->intfnum, ctrl->info.selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info.size); - if (ret < 0) - return ret; + data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT); + if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { + memset(data, 0, ctrl->info.size); ctrl->loaded = 1; + + return 0; } + if (ctrl->entity->get_cur) + ret = ctrl->entity->get_cur(chain->dev, ctrl->entity, + ctrl->info.selector, data, + ctrl->info.size); + else + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, + ctrl->entity->id, chain->dev->intfnum, + ctrl->info.selector, data, + ctrl->info.size); + + if (ret < 0) + return ret; + + ctrl->loaded = 1; + + return ret; +} + +static int __uvc_ctrl_get(struct uvc_video_chain *chain, + struct uvc_control *ctrl, + struct uvc_control_mapping *mapping, + s32 *value) +{ + int ret; + + if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) + return -EACCES; + + ret = __uvc_ctrl_load_cur(chain, ctrl); + if (ret < 0) + return ret; + *value = __uvc_ctrl_get_value(mapping, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); @@ -1271,25 +1306,55 @@ uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); } -static void uvc_ctrl_status_event_work(struct work_struct *work) +static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, + struct uvc_fh *new_handle) +{ + lockdep_assert_held(&handle->chain->ctrl_mutex); + + if (new_handle) { + if (ctrl->handle) + dev_warn_ratelimited(&handle->stream->dev->udev->dev, + "UVC non compliance: Setting an async control with a pending operation."); + + if (new_handle == ctrl->handle) + return; + + if (ctrl->handle) { + WARN_ON(!ctrl->handle->pending_async_ctrls); + if (ctrl->handle->pending_async_ctrls) + ctrl->handle->pending_async_ctrls--; + } + + ctrl->handle = new_handle; + handle->pending_async_ctrls++; + return; + } + + /* Cannot clear the handle for a control not owned by us.*/ + if (WARN_ON(ctrl->handle != handle)) + return; + + ctrl->handle = NULL; + if (WARN_ON(!handle->pending_async_ctrls)) + return; + handle->pending_async_ctrls--; +} + +void uvc_ctrl_status_event(struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) { - struct uvc_device *dev = container_of(work, struct uvc_device, - async_ctrl.work); - struct uvc_ctrl_work *w = &dev->async_ctrl; - struct uvc_video_chain *chain = w->chain; struct uvc_control_mapping *mapping; - struct uvc_control *ctrl = w->ctrl; struct uvc_fh *handle; unsigned int i; - int ret; mutex_lock(&chain->ctrl_mutex); handle = ctrl->handle; - ctrl->handle = NULL; + if (handle) + uvc_ctrl_set_handle(handle, ctrl, NULL); list_for_each_entry(mapping, &ctrl->info.mappings, list) { - s32 value = __uvc_ctrl_get_value(mapping, w->data); + s32 value = __uvc_ctrl_get_value(mapping, data); /* * handle may be NULL here if the device sends auto-update @@ -1308,6 +1373,20 @@ } mutex_unlock(&chain->ctrl_mutex); +} + +static void uvc_ctrl_status_event_work(struct work_struct *work) +{ + struct uvc_device *dev = container_of(work, struct uvc_device, + async_ctrl.work); + struct uvc_ctrl_work *w = &dev->async_ctrl; + int ret; + + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* The barrier is needed to synchronize with uvc_status_stop(). */ + if (smp_load_acquire(&dev->flush_status)) + return; /* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval; @@ -1317,16 +1396,14 @@ ret); } -bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, - struct uvc_control *ctrl, const u8 *data) +bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data) { struct uvc_device *dev = chain->dev; struct uvc_ctrl_work *w = &dev->async_ctrl; - if (list_empty(&ctrl->info.mappings)) { - ctrl->handle = NULL; + if (list_empty(&ctrl->info.mappings)) return false; - } w->data = data; w->urb = urb; @@ -1356,13 +1433,13 @@ { struct uvc_control_mapping *mapping; struct uvc_control *ctrl; - u32 changes = V4L2_EVENT_CTRL_CH_VALUE; unsigned int i; unsigned int j; for (i = 0; i < xctrls_count; ++i) { - ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); + u32 changes = V4L2_EVENT_CTRL_CH_VALUE; + ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping); if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) /* Notification will be sent from an Interrupt event. */ continue; @@ -1484,7 +1561,9 @@ } static int uvc_ctrl_commit_entity(struct uvc_device *dev, - struct uvc_entity *entity, int rollback) + struct uvc_fh *handle, + struct uvc_entity *entity, + int rollback) { struct uvc_control *ctrl; unsigned int i; @@ -1528,6 +1607,10 @@ if (ret < 0) return ret; + + if (!rollback && handle && + ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + uvc_ctrl_set_handle(handle, ctrl, handle); } return 0; @@ -1543,7 +1626,8 @@ /* Find the control. */ list_for_each_entry(entity, &chain->entities, chain) { - ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback); + ret = uvc_ctrl_commit_entity(chain->dev, handle, entity, + rollback); if (ret < 0) goto done; } @@ -1651,21 +1735,10 @@ * needs to be loaded from the device to perform the read-modify-write * operation. */ - if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { - if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { - memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - 0, ctrl->info.size); - } else { - ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, - ctrl->entity->id, chain->dev->intfnum, - ctrl->info.selector, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), - ctrl->info.size); - if (ret < 0) - return ret; - } - - ctrl->loaded = 1; + if ((ctrl->info.size * 8) != mapping->size) { + ret = __uvc_ctrl_load_cur(chain, ctrl); + if (ret < 0) + return ret; } /* Backup the current value in case we need to rollback later. */ @@ -1678,9 +1751,6 @@ mapping->set(mapping, value, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); - if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) - ctrl->handle = handle; - ctrl->dirty = 1; ctrl->modified = 1; return 0; @@ -1704,9 +1774,19 @@ if (data == NULL) return -ENOMEM; - ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, dev->intfnum, - info->selector, data, 1); - if (!ret) + if (ctrl->entity->get_info) + ret = ctrl->entity->get_info(dev, ctrl->entity, + ctrl->info.selector, data); + else + ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, + dev->intfnum, info->selector, data, 1); + + if (!ret) { + info->flags &= ~(UVC_CTRL_FLAG_GET_CUR | + UVC_CTRL_FLAG_SET_CUR | + UVC_CTRL_FLAG_AUTO_UPDATE | + UVC_CTRL_FLAG_ASYNCHRONOUS); + info->flags |= (data[0] & UVC_CONTROL_CAP_GET ? UVC_CTRL_FLAG_GET_CUR : 0) | (data[0] & UVC_CONTROL_CAP_SET ? @@ -1715,6 +1795,7 @@ UVC_CTRL_FLAG_AUTO_UPDATE : 0) | (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ? UVC_CTRL_FLAG_ASYNCHRONOUS : 0); + } kfree(data); return ret; @@ -1844,30 +1925,35 @@ { struct uvc_entity *entity; struct uvc_control *ctrl; - unsigned int i, found = 0; + unsigned int i; + bool found; u32 reqflags; u16 size; u8 *data = NULL; int ret; /* Find the extension unit. */ + found = false; list_for_each_entry(entity, &chain->entities, chain) { if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT && - entity->id == xqry->unit) + entity->id == xqry->unit) { + found = true; break; + } } - if (entity->id != xqry->unit) { + if (!found) { uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n", xqry->unit); return -ENOENT; } /* Find the control and perform delayed initialization if needed. */ + found = false; for (i = 0; i < entity->ncontrols; ++i) { ctrl = &entity->controls[i]; if (ctrl->index == xqry->selector - 1) { - found = 1; + found = true; break; } } @@ -1993,7 +2079,7 @@ ctrl->dirty = 1; } - ret = uvc_ctrl_commit_entity(dev, entity, 0); + ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0); if (ret < 0) return ret; } @@ -2024,13 +2110,6 @@ goto done; } - /* - * Retrieve control flags from the device. Ignore errors and work with - * default flag values from the uvc_ctrl array when the device doesn't - * properly implement GET_INFO on standard controls. - */ - uvc_ctrl_get_flags(dev, ctrl, &ctrl->info); - ctrl->initialized = 1; uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " @@ -2253,6 +2332,13 @@ if (uvc_entity_match_guid(ctrl->entity, info->entity) && ctrl->index == info->index) { uvc_ctrl_add_info(dev, ctrl, info); + /* + * Retrieve control flags from the device. Ignore errors + * and work with default flag values from the uvc_ctrl + * array when the device doesn't properly implement + * GET_INFO on standard controls. + */ + uvc_ctrl_get_flags(dev, ctrl, &ctrl->info); break; } } @@ -2325,6 +2411,30 @@ return 0; } +void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) +{ + struct uvc_entity *entity; + + mutex_lock(&handle->chain->ctrl_mutex); + + if (!handle->pending_async_ctrls) { + mutex_unlock(&handle->chain->ctrl_mutex); + return; + } + + list_for_each_entry(entity, &handle->chain->dev->entities, list) { + unsigned int i; + for (i = 0; i < entity->ncontrols; ++i) { + if (entity->controls[i].handle != handle) + continue; + uvc_ctrl_set_handle(handle, &entity->controls[i], NULL); + } + } + + WARN_ON(handle->pending_async_ctrls); + mutex_unlock(&handle->chain->ctrl_mutex); +} + /* * Cleanup device controls. */ --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_driver.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_driver.c @@ -214,6 +214,11 @@ .guid = UVC_GUID_FORMAT_CNF4, .fcc = V4L2_PIX_FMT_CNF4, }, + { + .name = "HEVC", + .guid = UVC_GUID_FORMAT_HEVC, + .fcc = V4L2_PIX_FMT_HEVC, + }, }; /* ------------------------------------------------------------------------ @@ -497,6 +502,22 @@ } } + /* Some devices report bpp that doesn't match the format. */ + if (dev->quirks & UVC_QUIRK_FORCE_BPP) { + const struct v4l2_format_info *info = + v4l2_format_info(format->fcc); + + if (info) { + unsigned int div = info->hdiv * info->vdiv; + + n = info->bpp[0] * div; + for (i = 1; i < info->comp_planes; i++) + n += info->bpp[i]; + + format->bpp = DIV_ROUND_UP(8 * n, div); + } + } + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { @@ -586,7 +607,7 @@ /* Parse the frame descriptors. Only uncompressed, MJPEG and frame * based formats have frame descriptors. */ - while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && + while (ftype && buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && buffer[2] == ftype) { frame = &format->frame[format->nframes]; if (ftype != UVC_VS_FRAME_FRAME_BASED) @@ -871,16 +892,26 @@ goto error; } - size = nformats * sizeof(*format) + nframes * sizeof(*frame) + /* + * Allocate memory for the formats, the frames and the intervals, + * plus any required padding to guarantee that everything has the + * correct alignment. + */ + size = nformats * sizeof(*format); + size = ALIGN(size, __alignof__(*frame)) + nframes * sizeof(*frame); + size = ALIGN(size, __alignof__(*interval)) + nintervals * sizeof(*interval); + format = kzalloc(size, GFP_KERNEL); - if (format == NULL) { + if (!format) { ret = -ENOMEM; goto error; } - frame = (struct uvc_frame *)&format[nformats]; - interval = (u32 *)&frame[nframes]; + frame = (void *)format + nformats * sizeof(*format); + frame = PTR_ALIGN(frame, __alignof__(*frame)); + interval = (void *)frame + nframes * sizeof(*frame); + interval = PTR_ALIGN(interval, __alignof__(*interval)); streaming->format = format; streaming->nformats = nformats; @@ -951,7 +982,10 @@ unsigned int i; extra_size = roundup(extra_size, sizeof(*entity->pads)); - num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1; + if (num_pads) + num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; + else + num_inputs = 0; size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads + num_inputs; entity = kzalloc(size, GFP_KERNEL); @@ -967,7 +1001,7 @@ for (i = 0; i < num_inputs; ++i) entity->pads[i].flags = MEDIA_PAD_FL_SINK; - if (!UVC_ENTITY_IS_OTERM(entity)) + if (!UVC_ENTITY_IS_OTERM(entity) && num_pads) entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; entity->bNrInPins = num_inputs; @@ -1041,10 +1075,8 @@ + n; memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); - if (buffer[24+p+2*n] != 0) - usb_string(udev, buffer[24+p+2*n], unit->name, - sizeof(unit->name)); - else + if (buffer[24+p+2*n] == 0 || + usb_string(udev, buffer[24+p+2*n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Extension %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1169,15 +1201,15 @@ memcpy(term->media.bmTransportModes, &buffer[10+n], p); } - if (buffer[7] != 0) - usb_string(udev, buffer[7], term->name, - sizeof(term->name)); - else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) - sprintf(term->name, "Camera %u", buffer[3]); - else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) - sprintf(term->name, "Media %u", buffer[3]); - else - sprintf(term->name, "Input %u", buffer[3]); + if (buffer[7] == 0 || + usb_string(udev, buffer[7], term->name, sizeof(term->name)) < 0) { + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) + sprintf(term->name, "Camera %u", buffer[3]); + if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) + sprintf(term->name, "Media %u", buffer[3]); + else + sprintf(term->name, "Input %u", buffer[3]); + } list_add_tail(&term->list, &dev->entities); break; @@ -1209,10 +1241,8 @@ memcpy(term->baSourceID, &buffer[7], 1); - if (buffer[8] != 0) - usb_string(udev, buffer[8], term->name, - sizeof(term->name)); - else + if (buffer[8] == 0 || + usb_string(udev, buffer[8], term->name, sizeof(term->name)) < 0) sprintf(term->name, "Output %u", buffer[3]); list_add_tail(&term->list, &dev->entities); @@ -1234,10 +1264,8 @@ memcpy(unit->baSourceID, &buffer[5], p); - if (buffer[5+p] != 0) - usb_string(udev, buffer[5+p], unit->name, - sizeof(unit->name)); - else + if (buffer[5+p] == 0 || + usb_string(udev, buffer[5+p], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Selector %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1267,10 +1295,8 @@ if (dev->uvc_version >= 0x0110) unit->processing.bmVideoStandards = buffer[9+n]; - if (buffer[8+n] != 0) - usb_string(udev, buffer[8+n], unit->name, - sizeof(unit->name)); - else + if (buffer[8+n] == 0 || + usb_string(udev, buffer[8+n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Processing %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1298,10 +1324,8 @@ unit->extension.bmControls = (u8 *)unit + sizeof(*unit); memcpy(unit->extension.bmControls, &buffer[23+p], n); - if (buffer[23+p+n] != 0) - usb_string(udev, buffer[23+p+n], unit->name, - sizeof(unit->name)); - else + if (buffer[23+p+n] == 0 || + usb_string(udev, buffer[23+p+n], unit->name, sizeof(unit->name)) < 0) sprintf(unit->name, "Extension %u", buffer[3]); list_add_tail(&unit->list, &dev->entities); @@ -1493,6 +1517,11 @@ break; if (forward == prev) continue; + if (forward->chain.next || forward->chain.prev) { + uvc_trace(UVC_TRACE_DESCR, "Found reference to " + "entity %d already in chain.\n", forward->id); + return -EINVAL; + } switch (UVC_ENTITY_TYPE(forward)) { case UVC_VC_EXTENSION_UNIT: @@ -1574,6 +1603,13 @@ return -1; } + if (term->chain.next || term->chain.prev) { + uvc_trace(UVC_TRACE_DESCR, "Found reference to " + "entity %d already in chain.\n", + term->id); + return -EINVAL; + } + if (uvc_trace_param & UVC_TRACE_PROBE) printk(KERN_CONT " %d", term->id); @@ -2151,6 +2187,20 @@ sizeof(dev->name) - len); } + /* Initialize the media device. */ +#ifdef CONFIG_MEDIA_CONTROLLER + dev->mdev.dev = &intf->dev; + strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); + if (udev->serial) + strscpy(dev->mdev.serial, udev->serial, + sizeof(dev->mdev.serial)); + usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); + dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); + media_device_init(&dev->mdev); + + dev->vdev.mdev = &dev->mdev; +#endif + /* Parse the Video Class control descriptor. */ if (uvc_parse_control(dev) < 0) { uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC " @@ -2171,19 +2221,7 @@ "linux-uvc-devel mailing list.\n"); } - /* Initialize the media device and register the V4L2 device. */ -#ifdef CONFIG_MEDIA_CONTROLLER - dev->mdev.dev = &intf->dev; - strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); - if (udev->serial) - strscpy(dev->mdev.serial, udev->serial, - sizeof(dev->mdev.serial)); - usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); - dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); - media_device_init(&dev->mdev); - - dev->vdev.mdev = &dev->mdev; -#endif + /* Register the V4L2 device. */ if (v4l2_device_register(&intf->dev, &dev->vdev) < 0) goto error; @@ -2392,6 +2430,8 @@ * The Logitech cameras listed below have their interface class set to * VENDOR_SPEC because they don't announce themselves as UVC devices, even * though they are compliant. + * + * Sort these by vendor/product ID. */ static const struct usb_device_id uvc_ids[] = { /* LogiLink Wireless Webcam */ @@ -2439,6 +2479,24 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, + /* Logitech, Webcam C910 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x0821, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)}, + /* Logitech, Webcam B910 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x046d, + .idProduct = 0x0823, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)}, /* Logitech Quickcam Fusion */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2842,6 +2900,15 @@ .bInterfaceProtocol = 0, .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_IGNORE_SELECTOR_UNIT) }, + /* NXP Semiconductors IR VIDEO */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1fc9, + .idProduct = 0x009b, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax }, /* Oculus VR Positional Tracker DK2 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2860,6 +2927,15 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 }, + /* GEO Semiconductor GC6500 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x29fe, + .idProduct = 0x4d53, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) }, /* Intel RealSense D4M */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_entity.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_entity.c @@ -37,7 +37,7 @@ continue; remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]); - if (remote == NULL) + if (remote == NULL || remote->num_pads == 0) return -EINVAL; source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) @@ -73,10 +73,45 @@ int ret; if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) { + u32 function; + v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops); strscpy(entity->subdev.name, entity->name, sizeof(entity->subdev.name)); + switch (UVC_ENTITY_TYPE(entity)) { + case UVC_VC_SELECTOR_UNIT: + function = MEDIA_ENT_F_VID_MUX; + break; + case UVC_VC_PROCESSING_UNIT: + case UVC_VC_EXTENSION_UNIT: + /* For lack of a better option. */ + function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER; + break; + case UVC_COMPOSITE_CONNECTOR: + case UVC_COMPONENT_CONNECTOR: + function = MEDIA_ENT_F_CONN_COMPOSITE; + break; + case UVC_SVIDEO_CONNECTOR: + function = MEDIA_ENT_F_CONN_SVIDEO; + break; + case UVC_ITT_CAMERA: + function = MEDIA_ENT_F_CAM_SENSOR; + break; + case UVC_TT_VENDOR_SPECIFIC: + case UVC_ITT_VENDOR_SPECIFIC: + case UVC_ITT_MEDIA_TRANSPORT_INPUT: + case UVC_OTT_VENDOR_SPECIFIC: + case UVC_OTT_DISPLAY: + case UVC_OTT_MEDIA_TRANSPORT_OUTPUT: + case UVC_EXTERNAL_VENDOR_SPECIFIC: + default: + function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN; + break; + } + + entity->subdev.entity.function = function; + ret = media_entity_pads_init(&entity->subdev.entity, entity->num_pads, entity->pads); --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_queue.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_queue.c @@ -486,7 +486,8 @@ buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE; vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); - vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); + vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR : + VB2_BUF_STATE_DONE); } /* --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_status.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_status.c @@ -6,6 +6,7 @@ * Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ +#include #include #include #include @@ -179,7 +180,8 @@ switch (status->bAttribute) { case UVC_CTRL_VALUE_CHANGE: - return uvc_ctrl_status_event(urb, chain, ctrl, status->bValue); + return uvc_ctrl_status_event_async(urb, chain, ctrl, + status->bValue); case UVC_CTRL_INFO_CHANGE: case UVC_CTRL_FAILURE_CHANGE: @@ -267,6 +269,7 @@ dev->int_urb = usb_alloc_urb(0, GFP_KERNEL); if (dev->int_urb == NULL) { kfree(dev->status); + dev->status = NULL; return -ENOMEM; } @@ -309,5 +312,41 @@ void uvc_status_stop(struct uvc_device *dev) { + struct uvc_ctrl_work *w = &dev->async_ctrl; + + /* + * Prevent the asynchronous control handler from requeing the URB. The + * barrier is needed so the flush_status change is visible to other + * CPUs running the asynchronous handler before usb_kill_urb() is + * called below. + */ + smp_store_release(&dev->flush_status, true); + + /* + * Cancel any pending asynchronous work. If any status event was queued, + * process it synchronously. + */ + if (cancel_work_sync(&w->work)) + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* Kill the urb. */ usb_kill_urb(dev->int_urb); + + /* + * The URB completion handler may have queued asynchronous work. This + * won't resubmit the URB as flush_status is set, but it needs to be + * cancelled before returning or it could then race with a future + * uvc_status_start() call. + */ + if (cancel_work_sync(&w->work)) + uvc_ctrl_status_event(w->chain, w->ctrl, w->data); + + /* + * From this point, there are no events on the queue and the status URB + * is dead. No events will be queued until uvc_status_start() is called. + * The barrier is needed to make sure that flush_status is visible to + * uvc_ctrl_status_event_work() when uvc_status_start() will be called + * again. + */ + smp_store_release(&dev->flush_status, false); } --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_v4l2.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_v4l2.c @@ -247,11 +247,41 @@ if (ret < 0) goto done; + /* After the probe, update fmt with the values returned from + * negotiation with the device. Some devices return invalid bFormatIndex + * and bFrameIndex values, in which case we can only assume they have + * accepted the requested format as-is. + */ + for (i = 0; i < stream->nformats; ++i) { + if (probe->bFormatIndex == stream->format[i].index) { + format = &stream->format[i]; + break; + } + } + + if (i == stream->nformats) + uvc_trace(UVC_TRACE_FORMAT, + "Unknown bFormatIndex %u, using default\n", + probe->bFormatIndex); + + for (i = 0; i < format->nframes; ++i) { + if (probe->bFrameIndex == format->frame[i].bFrameIndex) { + frame = &format->frame[i]; + break; + } + } + + if (i == format->nframes) + uvc_trace(UVC_TRACE_FORMAT, + "Unknown bFrameIndex %u, using default\n", + probe->bFrameIndex); + fmt->fmt.pix.width = frame->wWidth; fmt->fmt.pix.height = frame->wHeight; fmt->fmt.pix.field = V4L2_FIELD_NONE; fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame); fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize; + fmt->fmt.pix.pixelformat = format->fcc; fmt->fmt.pix.colorspace = format->colorspace; if (uvc_format != NULL) @@ -437,10 +467,13 @@ uvc_simplify_fraction(&timeperframe.numerator, &timeperframe.denominator, 8, 333); - if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { parm->parm.capture.timeperframe = timeperframe; - else + parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + } else { parm->parm.output.timeperframe = timeperframe; + parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; + } return 0; } @@ -556,6 +589,8 @@ uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n"); + uvc_ctrl_cleanup_fh(handle); + /* Only free resources if this is a privileged handle. */ if (uvc_has_privileges(handle)) uvc_queue_release(&stream->queue); @@ -826,29 +861,31 @@ struct uvc_video_chain *chain = handle->chain; const struct uvc_entity *selector = chain->selector; struct uvc_entity *iterm = NULL; + struct uvc_entity *it; u32 index = input->index; - int pin = 0; if (selector == NULL || (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { if (index != 0) return -EINVAL; - list_for_each_entry(iterm, &chain->entities, chain) { - if (UVC_ENTITY_IS_ITERM(iterm)) + list_for_each_entry(it, &chain->entities, chain) { + if (UVC_ENTITY_IS_ITERM(it)) { + iterm = it; break; + } } - pin = iterm->id; } else if (index < selector->bNrInPins) { - pin = selector->baSourceID[index]; - list_for_each_entry(iterm, &chain->entities, chain) { - if (!UVC_ENTITY_IS_ITERM(iterm)) + list_for_each_entry(it, &chain->entities, chain) { + if (!UVC_ENTITY_IS_ITERM(it)) continue; - if (iterm->id == pin) + if (it->id == selector->baSourceID[index]) { + iterm = it; break; + } } } - if (iterm == NULL || iterm->id != pin) + if (iterm == NULL) return -EINVAL; memset(input, 0, sizeof(*input)); @@ -864,8 +901,8 @@ { struct uvc_fh *handle = fh; struct uvc_video_chain *chain = handle->chain; + u8 *buf; int ret; - u8 i; if (chain->selector == NULL || (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { @@ -873,22 +910,27 @@ return 0; } + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id, chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, - &i, 1); - if (ret < 0) - return ret; + buf, 1); + if (!ret) + *input = *buf - 1; - *input = i - 1; - return 0; + kfree(buf); + + return ret; } static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input) { struct uvc_fh *handle = fh; struct uvc_video_chain *chain = handle->chain; + u8 *buf; int ret; - u32 i; ret = uvc_acquire_privileges(handle); if (ret < 0) @@ -904,10 +946,17 @@ if (input >= chain->selector->bNrInPins) return -EINVAL; - i = input + 1; - return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, - chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, - &i, 1); + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + *buf = input + 1; + ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id, + chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL, + buf, 1); + kfree(buf); + + return ret; } static int uvc_ioctl_queryctrl(struct file *file, void *fh, --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvc_video.c +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvc_video.c @@ -112,6 +112,11 @@ case 5: /* Invalid unit */ case 6: /* Invalid control */ case 7: /* Invalid Request */ + /* + * The firmware has not properly implemented + * the control or there has been a HW error. + */ + return -EIO; case 8: /* Invalid value within range */ return -EINVAL; default: /* reserved or unknown */ @@ -124,10 +129,37 @@ static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl) { + static const struct usb_device_id elgato_cam_link_4k = { + USB_DEVICE(0x0fd9, 0x0066) + }; struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; unsigned int i; + /* + * The response of the Elgato Cam Link 4K is incorrect: The second byte + * contains bFormatIndex (instead of being the second byte of bmHint). + * The first byte is always zero. The third byte is always 1. + * + * The UVC 1.5 class specification defines the first five bits in the + * bmHint bitfield. The remaining bits are reserved and should be zero. + * Therefore a valid bmHint will be less than 32. + * + * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix. + * MCU: 20.02.19, FPGA: 67 + */ + if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) && + ctrl->bmHint > 255) { + u8 corrected_format_index = ctrl->bmHint >> 8; + + uvc_trace(UVC_TRACE_VIDEO, + "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n", + ctrl->bmHint, ctrl->bFormatIndex, + 1, corrected_format_index); + ctrl->bmHint = 1; + ctrl->bFormatIndex = corrected_format_index; + } + for (i = 0; i < stream->nformats; ++i) { if (stream->format[i].index == ctrl->bFormatIndex) { format = &stream->format[i]; @@ -175,13 +207,13 @@ /* Compute a bandwidth estimation by multiplying the frame * size by the number of video frames per second, divide the * result by the number of USB frames (or micro-frames for - * high-speed devices) per second and add the UVC header size - * (assumed to be 12 bytes long). + * high- and super-speed devices) per second and add the UVC + * header size (assumed to be 12 bytes long). */ bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; bandwidth *= 10000000 / interval + 1; bandwidth /= 1000; - if (stream->dev->udev->speed == USB_SPEED_HIGH) + if (stream->dev->udev->speed >= USB_SPEED_HIGH) bandwidth /= 8; bandwidth += 12; @@ -436,6 +468,7 @@ ktime_t time; u16 host_sof; u16 dev_sof; + u32 dev_stc; switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) { case UVC_STREAM_PTS | UVC_STREAM_SCR: @@ -480,6 +513,34 @@ if (dev_sof == stream->clock.last_sof) return; + dev_stc = get_unaligned_le32(&data[header_size - 6]); + + /* + * STC (Source Time Clock) is the clock used by the camera. The UVC 1.5 + * standard states that it "must be captured when the first video data + * of a video frame is put on the USB bus". This is generally understood + * as requiring devices to clear the payload header's SCR bit before + * the first packet containing video data. + * + * Most vendors follow that interpretation, but some (namely SunplusIT + * on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR + * field with 0's,and expect that the driver only processes the SCR if + * there is data in the packet. + * + * Ignore all the hardware timestamp information if we haven't received + * any data for this frame yet, the packet contains no data, and both + * STC and SOF are zero. This heuristics should be safe on compliant + * devices. This should be safe with compliant devices, as in the very + * unlikely case where a UVC 1.1 device would send timing information + * only before the first packet containing data, and both STC and SOF + * happen to be zero for a particular frame, we would only miss one + * clock sample from many and the clock recovery algorithm wouldn't + * suffer from this condition. + */ + if (buf && buf->bytesused == 0 && len == header_size && + dev_stc == 0 && dev_sof == 0) + return; + stream->clock.last_sof = dev_sof; host_sof = usb_get_current_frame_number(stream->dev->udev); @@ -517,7 +578,7 @@ spin_lock_irqsave(&stream->clock.lock, flags); sample = &stream->clock.samples[stream->clock.head]; - sample->dev_stc = get_unaligned_le32(&data[header_size - 6]); + sample->dev_stc = dev_stc; sample->dev_sof = dev_sof; sample->host_sof = host_sof; sample->host_time = time; @@ -662,11 +723,11 @@ unsigned long flags; u64 timestamp; u32 delta_stc; - u32 y1, y2; + u32 y1; u32 x1, x2; u32 mean; u32 sof; - u64 y; + u64 y, y2; if (!uvc_hw_timestamps_param) return; @@ -706,7 +767,7 @@ sof = y; uvc_trace(UVC_TRACE_CLOCK, "%s: PTS %u y %llu.%06llu SOF %u.%06llu " - "(x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n", + "(x1 %u x2 %u y1 %u y2 %llu SOF offset %u)\n", stream->dev->name, buf->pts, y >> 16, div_u64((y & 0xffff) * 1000000, 65536), sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), @@ -721,7 +782,7 @@ goto done; y1 = NSEC_PER_SEC; - y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; + y2 = ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1; /* Interpolated and host SOF timestamps can wrap around at slightly * different times. Handle this by adding or removing 2048 to or from @@ -741,7 +802,7 @@ timestamp = ktime_to_ns(first->host_time) + y - y1; uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %llu " - "buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n", + "buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %llu)\n", stream->dev->name, sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536), y, timestamp, vbuf->vb2_buf.timestamp, @@ -765,9 +826,9 @@ unsigned int header_size; bool has_pts = false; bool has_scr = false; - u16 uninitialized_var(scr_sof); - u32 uninitialized_var(scr_stc); - u32 uninitialized_var(pts); + u16 scr_sof; + u32 scr_stc; + u32 pts; if (stream->stats.stream.nb_frames == 0 && stream->stats.frame.nb_packets == 0) @@ -1276,7 +1337,9 @@ if (has_scr) memcpy(stream->clock.last_scr, scr, 6); - memcpy(&meta->length, mem, length); + meta->length = mem[0]; + meta->flags = mem[1]; + memcpy(meta->buf, &mem[2], length - 2); meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof); uvc_trace(UVC_TRACE_FRAME, @@ -1828,7 +1891,7 @@ struct usb_host_endpoint *best_ep = NULL; unsigned int best_psize = UINT_MAX; unsigned int bandwidth; - unsigned int uninitialized_var(altsetting); + unsigned int altsetting; int intfnum = stream->intfnum; /* Isochronous endpoint, select the alternate setting. */ @@ -1871,6 +1934,17 @@ uvc_trace(UVC_TRACE_VIDEO, "Selecting alternate setting %u " "(%u B/frame bandwidth).\n", altsetting, best_psize); + /* + * Some devices, namely the Logitech C910 and B910, are unable + * to recover from a USB autosuspend, unless the alternate + * setting of the streaming interface is toggled. + */ + if (stream->dev->quirks & UVC_QUIRK_WAKE_AUTOSUSPEND) { + usb_set_interface(stream->dev->udev, intfnum, + altsetting); + usb_set_interface(stream->dev->udev, intfnum, 0); + } + ret = usb_set_interface(stream->dev->udev, intfnum, altsetting); if (ret < 0) return ret; @@ -1883,6 +1957,10 @@ if (ep == NULL) return -EIO; + /* Reject broken descriptors. */ + if (usb_endpoint_maxp(&ep->desc) == 0) + return -EIO; + ret = uvc_init_video_bulk(stream, ep, gfp_flags); } --- linux-oracle-5.4.0.orig/drivers/media/usb/uvc/uvcvideo.h +++ linux-oracle-5.4.0/drivers/media/usb/uvc/uvcvideo.h @@ -165,6 +165,10 @@ {0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} +#define UVC_GUID_FORMAT_HEVC \ + { 'H', 'E', 'V', 'C', 0x00, 0x00, 0x10, 0x00, \ + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} + /* ------------------------------------------------------------------------ * Driver specific constants. @@ -179,7 +183,7 @@ /* Maximum status buffer size in bytes of interrupt URB. */ #define UVC_MAX_STATUS_SIZE 16 -#define UVC_CTRL_CONTROL_TIMEOUT 500 +#define UVC_CTRL_CONTROL_TIMEOUT 5000 #define UVC_CTRL_STREAMING_TIMEOUT 5000 /* Maximum allowed number of control mappings per device */ @@ -198,6 +202,8 @@ #define UVC_QUIRK_RESTRICT_FRAME_RATE 0x00000200 #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400 #define UVC_QUIRK_FORCE_Y8 0x00000800 +#define UVC_QUIRK_FORCE_BPP 0x00001000 +#define UVC_QUIRK_WAKE_AUTOSUSPEND 0x00002000 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -348,6 +354,11 @@ u8 bNrInPins; u8 *baSourceID; + int (*get_info)(struct uvc_device *dev, struct uvc_entity *entity, + u8 cs, u8 *caps); + int (*get_cur)(struct uvc_device *dev, struct uvc_entity *entity, + u8 cs, void *data, u16 size); + unsigned int ncontrols; struct uvc_control *controls; }; @@ -440,7 +451,11 @@ struct uvc_entity *processing; /* Processing unit */ struct uvc_entity *selector; /* Selector unit */ - struct mutex ctrl_mutex; /* Protects ctrl.info */ + struct mutex ctrl_mutex; /* + * Protects ctrl.info, + * ctrl.handle and + * uvc_fh.pending_async_ctrls + */ struct v4l2_prio_state prio; /* V4L2 priority state */ u32 caps; /* V4L2 chain-wide caps */ @@ -662,6 +677,7 @@ /* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep; struct urb *int_urb; + bool flush_status; u8 *status; struct input_dev *input; char input_phys[64]; @@ -685,6 +701,7 @@ struct uvc_video_chain *chain; struct uvc_streaming *stream; enum uvc_handle_state state; + unsigned int pending_async_ctrls; }; struct uvc_driver { @@ -831,7 +848,9 @@ int uvc_ctrl_init_device(struct uvc_device *dev); void uvc_ctrl_cleanup_device(struct uvc_device *dev); int uvc_ctrl_restore_values(struct uvc_device *dev); -bool uvc_ctrl_status_event(struct urb *urb, struct uvc_video_chain *chain, +bool uvc_ctrl_status_event_async(struct urb *urb, struct uvc_video_chain *chain, + struct uvc_control *ctrl, const u8 *data); +void uvc_ctrl_status_event(struct uvc_video_chain *chain, struct uvc_control *ctrl, const u8 *data); int uvc_ctrl_begin(struct uvc_video_chain *chain); @@ -855,6 +874,8 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); +void uvc_ctrl_cleanup_fh(struct uvc_fh *handle); + /* Utility functions */ void uvc_simplify_fraction(u32 *numerator, u32 *denominator, unsigned int n_terms, unsigned int threshold); --- linux-oracle-5.4.0.orig/drivers/media/usb/zr364xx/zr364xx.c +++ linux-oracle-5.4.0/drivers/media/usb/zr364xx/zr364xx.c @@ -1037,6 +1037,7 @@ DBG("submitting URB %p\n", pipe_info->stream_urb); retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); if (retval) { + usb_free_urb(pipe_info->stream_urb); printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n"); return retval; } @@ -1186,15 +1187,11 @@ return err; } -static void zr364xx_release(struct v4l2_device *v4l2_dev) +static void zr364xx_board_uninit(struct zr364xx_camera *cam) { - struct zr364xx_camera *cam = - container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); unsigned long i; - v4l2_device_unregister(&cam->v4l2_dev); - - videobuf_mmap_free(&cam->vb_vidq); + zr364xx_stop_readpipe(cam); /* release sys buffers */ for (i = 0; i < FRAMES; i++) { @@ -1205,9 +1202,19 @@ cam->buffer.frame[i].lpvbits = NULL; } - v4l2_ctrl_handler_free(&cam->ctrl_handler); /* release transfer buffer */ kfree(cam->pipe->transfer_buffer); +} + +static void zr364xx_release(struct v4l2_device *v4l2_dev) +{ + struct zr364xx_camera *cam = + container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); + + videobuf_mmap_free(&cam->vb_vidq); + v4l2_ctrl_handler_free(&cam->ctrl_handler); + zr364xx_board_uninit(cam); + v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); } @@ -1330,6 +1337,7 @@ { struct zr364xx_pipeinfo *pipe = cam->pipe; unsigned long i; + int err; DBG("board init: %p\n", cam); memset(pipe, 0, sizeof(*pipe)); @@ -1362,9 +1370,8 @@ if (i == 0) { printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n"); - kfree(cam->pipe->transfer_buffer); - cam->pipe->transfer_buffer = NULL; - return -ENOMEM; + err = -ENOMEM; + goto err_free; } else cam->buffer.dwFrames = i; @@ -1379,9 +1386,20 @@ /*** end create system buffers ***/ /* start read pipe */ - zr364xx_start_readpipe(cam); + err = zr364xx_start_readpipe(cam); + if (err) + goto err_free_frames; + DBG(": board initialized\n"); return 0; + +err_free_frames: + for (i = 0; i < FRAMES; i++) + vfree(cam->buffer.frame[i].lpvbits); +err_free: + kfree(cam->pipe->transfer_buffer); + cam->pipe->transfer_buffer = NULL; + return err; } static int zr364xx_probe(struct usb_interface *intf, @@ -1406,12 +1424,10 @@ if (!cam) return -ENOMEM; - cam->v4l2_dev.release = zr364xx_release; err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); if (err < 0) { dev_err(&udev->dev, "couldn't register v4l2_device\n"); - kfree(cam); - return err; + goto free_cam; } hdl = &cam->ctrl_handler; v4l2_ctrl_handler_init(hdl, 1); @@ -1420,7 +1436,7 @@ if (hdl->error) { err = hdl->error; dev_err(&udev->dev, "couldn't register control\n"); - goto fail; + goto free_hdlr_and_unreg_dev; } /* save the init method used by this camera */ cam->method = id->driver_info; @@ -1493,7 +1509,7 @@ if (!cam->read_endpoint) { err = -ENOMEM; dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); - goto fail; + goto free_hdlr_and_unreg_dev; } /* v4l */ @@ -1504,10 +1520,11 @@ /* load zr364xx board specific */ err = zr364xx_board_init(cam); - if (!err) - err = v4l2_ctrl_handler_setup(hdl); if (err) - goto fail; + goto free_hdlr_and_unreg_dev; + err = v4l2_ctrl_handler_setup(hdl); + if (err) + goto board_uninit; spin_lock_init(&cam->slock); @@ -1522,16 +1539,20 @@ err = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { dev_err(&udev->dev, "video_register_device failed\n"); - goto fail; + goto board_uninit; } + cam->v4l2_dev.release = zr364xx_release; dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", video_device_node_name(&cam->vdev)); return 0; -fail: +board_uninit: + zr364xx_board_uninit(cam); +free_hdlr_and_unreg_dev: v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&cam->v4l2_dev); +free_cam: kfree(cam); return err; } @@ -1578,10 +1599,19 @@ if (!cam->was_streaming) return 0; - zr364xx_start_readpipe(cam); + res = zr364xx_start_readpipe(cam); + if (res) + return res; + res = zr364xx_prepare(cam); - if (!res) - zr364xx_start_acquire(cam); + if (res) + goto err_prepare; + + zr364xx_start_acquire(cam); + return 0; + +err_prepare: + zr364xx_stop_readpipe(cam); return res; } #endif --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -1183,36 +1183,38 @@ u32 aux_space; int compatible_arg = 1; long err = 0; + unsigned int ncmd; /* * 1. When struct size is different, converts the command. */ switch (cmd) { - case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; - case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; - case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; - case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; - case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break; - case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; - case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; - case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; - case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; - case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; - case VIDIOC_G_EXT_CTRLS32: cmd = VIDIOC_G_EXT_CTRLS; break; - case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break; - case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break; - case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break; - case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; - case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; - case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; - case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; - case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; - case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; - case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; - case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break; - case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break; - case VIDIOC_G_EDID32: cmd = VIDIOC_G_EDID; break; - case VIDIOC_S_EDID32: cmd = VIDIOC_S_EDID; break; + case VIDIOC_G_FMT32: ncmd = VIDIOC_G_FMT; break; + case VIDIOC_S_FMT32: ncmd = VIDIOC_S_FMT; break; + case VIDIOC_QUERYBUF32: ncmd = VIDIOC_QUERYBUF; break; + case VIDIOC_G_FBUF32: ncmd = VIDIOC_G_FBUF; break; + case VIDIOC_S_FBUF32: ncmd = VIDIOC_S_FBUF; break; + case VIDIOC_QBUF32: ncmd = VIDIOC_QBUF; break; + case VIDIOC_DQBUF32: ncmd = VIDIOC_DQBUF; break; + case VIDIOC_ENUMSTD32: ncmd = VIDIOC_ENUMSTD; break; + case VIDIOC_ENUMINPUT32: ncmd = VIDIOC_ENUMINPUT; break; + case VIDIOC_TRY_FMT32: ncmd = VIDIOC_TRY_FMT; break; + case VIDIOC_G_EXT_CTRLS32: ncmd = VIDIOC_G_EXT_CTRLS; break; + case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break; + case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break; + case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break; + case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break; + case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break; + case VIDIOC_STREAMOFF32: ncmd = VIDIOC_STREAMOFF; break; + case VIDIOC_G_INPUT32: ncmd = VIDIOC_G_INPUT; break; + case VIDIOC_S_INPUT32: ncmd = VIDIOC_S_INPUT; break; + case VIDIOC_G_OUTPUT32: ncmd = VIDIOC_G_OUTPUT; break; + case VIDIOC_S_OUTPUT32: ncmd = VIDIOC_S_OUTPUT; break; + case VIDIOC_CREATE_BUFS32: ncmd = VIDIOC_CREATE_BUFS; break; + case VIDIOC_PREPARE_BUF32: ncmd = VIDIOC_PREPARE_BUF; break; + case VIDIOC_G_EDID32: ncmd = VIDIOC_G_EDID; break; + case VIDIOC_S_EDID32: ncmd = VIDIOC_S_EDID; break; + default: ncmd = cmd; break; } /* @@ -1221,11 +1223,11 @@ * argument into it. */ switch (cmd) { - case VIDIOC_OVERLAY: - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - case VIDIOC_S_INPUT: - case VIDIOC_S_OUTPUT: + case VIDIOC_OVERLAY32: + case VIDIOC_STREAMON32: + case VIDIOC_STREAMOFF32: + case VIDIOC_S_INPUT32: + case VIDIOC_S_OUTPUT32: err = alloc_userspace(sizeof(unsigned int), 0, &new_p64); if (!err && assign_in_user((unsigned int __user *)new_p64, (compat_uint_t __user *)p32)) @@ -1233,23 +1235,23 @@ compatible_arg = 0; break; - case VIDIOC_G_INPUT: - case VIDIOC_G_OUTPUT: + case VIDIOC_G_INPUT32: + case VIDIOC_G_OUTPUT32: err = alloc_userspace(sizeof(unsigned int), 0, &new_p64); compatible_arg = 0; break; - case VIDIOC_G_EDID: - case VIDIOC_S_EDID: + case VIDIOC_G_EDID32: + case VIDIOC_S_EDID32: err = alloc_userspace(sizeof(struct v4l2_edid), 0, &new_p64); if (!err) err = get_v4l2_edid32(new_p64, p32); compatible_arg = 0; break; - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: + case VIDIOC_G_FMT32: + case VIDIOC_S_FMT32: + case VIDIOC_TRY_FMT32: err = bufsize_v4l2_format(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_format), @@ -1262,7 +1264,7 @@ compatible_arg = 0; break; - case VIDIOC_CREATE_BUFS: + case VIDIOC_CREATE_BUFS32: err = bufsize_v4l2_create(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_create_buffers), @@ -1275,10 +1277,10 @@ compatible_arg = 0; break; - case VIDIOC_PREPARE_BUF: - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: + case VIDIOC_PREPARE_BUF32: + case VIDIOC_QUERYBUF32: + case VIDIOC_QBUF32: + case VIDIOC_DQBUF32: err = bufsize_v4l2_buffer(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_buffer), @@ -1291,7 +1293,7 @@ compatible_arg = 0; break; - case VIDIOC_S_FBUF: + case VIDIOC_S_FBUF32: err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, &new_p64); if (!err) @@ -1299,13 +1301,13 @@ compatible_arg = 0; break; - case VIDIOC_G_FBUF: + case VIDIOC_G_FBUF32: err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0, &new_p64); compatible_arg = 0; break; - case VIDIOC_ENUMSTD: + case VIDIOC_ENUMSTD32: err = alloc_userspace(sizeof(struct v4l2_standard), 0, &new_p64); if (!err) @@ -1313,16 +1315,16 @@ compatible_arg = 0; break; - case VIDIOC_ENUMINPUT: + case VIDIOC_ENUMINPUT32: err = alloc_userspace(sizeof(struct v4l2_input), 0, &new_p64); if (!err) err = get_v4l2_input32(new_p64, p32); compatible_arg = 0; break; - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_G_EXT_CTRLS32: + case VIDIOC_S_EXT_CTRLS32: + case VIDIOC_TRY_EXT_CTRLS32: err = bufsize_v4l2_ext_controls(p32, &aux_space); if (!err) err = alloc_userspace(sizeof(struct v4l2_ext_controls), @@ -1334,7 +1336,7 @@ } compatible_arg = 0; break; - case VIDIOC_DQEVENT: + case VIDIOC_DQEVENT32: err = alloc_userspace(sizeof(struct v4l2_event), 0, &new_p64); compatible_arg = 0; break; @@ -1352,9 +1354,9 @@ * Otherwise, it will pass the newly allocated @new_p64 argument. */ if (compatible_arg) - err = native_ioctl(file, cmd, (unsigned long)p32); + err = native_ioctl(file, ncmd, (unsigned long)p32); else - err = native_ioctl(file, cmd, (unsigned long)new_p64); + err = native_ioctl(file, ncmd, (unsigned long)new_p64); if (err == -ENOTTY) return err; @@ -1370,13 +1372,13 @@ * the blocks to maximum allowed value. */ switch (cmd) { - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_G_EXT_CTRLS32: + case VIDIOC_S_EXT_CTRLS32: + case VIDIOC_TRY_EXT_CTRLS32: if (put_v4l2_ext_controls32(file, new_p64, p32)) err = -EFAULT; break; - case VIDIOC_S_EDID: + case VIDIOC_S_EDID32: if (put_v4l2_edid32(new_p64, p32)) err = -EFAULT; break; @@ -1389,49 +1391,49 @@ * the original 32 bits structure. */ switch (cmd) { - case VIDIOC_S_INPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_G_INPUT: - case VIDIOC_G_OUTPUT: + case VIDIOC_S_INPUT32: + case VIDIOC_S_OUTPUT32: + case VIDIOC_G_INPUT32: + case VIDIOC_G_OUTPUT32: if (assign_in_user((compat_uint_t __user *)p32, ((unsigned int __user *)new_p64))) err = -EFAULT; break; - case VIDIOC_G_FBUF: + case VIDIOC_G_FBUF32: err = put_v4l2_framebuffer32(new_p64, p32); break; - case VIDIOC_DQEVENT: + case VIDIOC_DQEVENT32: err = put_v4l2_event32(new_p64, p32); break; - case VIDIOC_G_EDID: + case VIDIOC_G_EDID32: err = put_v4l2_edid32(new_p64, p32); break; - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: + case VIDIOC_G_FMT32: + case VIDIOC_S_FMT32: + case VIDIOC_TRY_FMT32: err = put_v4l2_format32(new_p64, p32); break; - case VIDIOC_CREATE_BUFS: + case VIDIOC_CREATE_BUFS32: err = put_v4l2_create32(new_p64, p32); break; - case VIDIOC_PREPARE_BUF: - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: + case VIDIOC_PREPARE_BUF32: + case VIDIOC_QUERYBUF32: + case VIDIOC_QBUF32: + case VIDIOC_DQBUF32: err = put_v4l2_buffer32(new_p64, p32); break; - case VIDIOC_ENUMSTD: + case VIDIOC_ENUMSTD32: err = put_v4l2_standard32(new_p64, p32); break; - case VIDIOC_ENUMINPUT: + case VIDIOC_ENUMINPUT32: err = put_v4l2_input32(new_p64, p32); break; } --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-ctrls.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-ctrls.c @@ -1795,7 +1795,8 @@ case V4L2_CTRL_TYPE_INTEGER_MENU: if (ptr.p_s32[idx] < ctrl->minimum || ptr.p_s32[idx] > ctrl->maximum) return -ERANGE; - if (ctrl->menu_skip_mask & (1ULL << ptr.p_s32[idx])) + if (ptr.p_s32[idx] < BITS_PER_LONG_LONG && + (ctrl->menu_skip_mask & BIT_ULL(ptr.p_s32[idx]))) return -EINVAL; if (ctrl->type == V4L2_CTRL_TYPE_MENU && ctrl->qmenu[ptr.p_s32[idx]][0] == '\0') @@ -2154,7 +2155,15 @@ if (hdl == NULL || hdl->buckets == NULL) return; - if (!hdl->req_obj.req && !list_empty(&hdl->requests)) { + /* + * If the main handler is freed and it is used by handler objects in + * outstanding requests, then unbind and put those objects before + * freeing the main handler. + * + * The main handler can be identified by having a NULL ops pointer in + * the request object. + */ + if (!hdl->req_obj.ops && !list_empty(&hdl->requests)) { struct v4l2_ctrl_handler *req, *next_req; list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { @@ -3144,6 +3153,7 @@ struct v4l2_ctrl_handler *prev_hdl = NULL; struct v4l2_ctrl_ref *ref_ctrl, *ref_ctrl_prev = NULL; + mutex_lock(main_hdl->lock); if (list_empty(&main_hdl->requests_queued)) goto queue; @@ -3175,18 +3185,22 @@ queue: list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); hdl->request_is_queued = true; + mutex_unlock(main_hdl->lock); } static void v4l2_ctrl_request_unbind(struct media_request_object *obj) { struct v4l2_ctrl_handler *hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); + struct v4l2_ctrl_handler *main_hdl = obj->priv; + mutex_lock(main_hdl->lock); list_del_init(&hdl->requests); if (hdl->request_is_queued) { list_del_init(&hdl->requests_queued); hdl->request_is_queued = false; } + mutex_unlock(main_hdl->lock); } static void v4l2_ctrl_request_release(struct media_request_object *obj) @@ -3240,8 +3254,11 @@ if (!ret) { ret = media_request_object_bind(req, &req_ops, from, false, &hdl->req_obj); - if (!ret) + if (!ret) { + mutex_lock(from->lock); list_add_tail(&hdl->requests, &from->requests); + mutex_unlock(from->lock); + } } return ret; } @@ -4128,9 +4145,11 @@ v4l2_ctrl_unlock(ctrl); } + mutex_lock(main_hdl->lock); WARN_ON(!hdl->request_is_queued); list_del_init(&hdl->requests_queued); hdl->request_is_queued = false; + mutex_unlock(main_hdl->lock); media_request_object_complete(obj); media_request_object_put(obj); } --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-dev.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-dev.c @@ -533,13 +533,23 @@ */ static void determine_valid_ioctls(struct video_device *vdev) { + const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; + const u32 meta_caps = V4L2_CAP_META_CAPTURE | + V4L2_CAP_META_OUTPUT; DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; - bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER; + bool is_vid = vdev->vfl_type == VFL_TYPE_VIDEO && + (vdev->device_caps & vid_caps); bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI; bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO; bool is_sdr = vdev->vfl_type == VFL_TYPE_SDR; bool is_tch = vdev->vfl_type == VFL_TYPE_TOUCH; + bool is_meta = vdev->vfl_type == VFL_TYPE_VIDEO && + (vdev->device_caps & meta_caps); bool is_rx = vdev->vfl_dir != VFL_DIR_TX; bool is_tx = vdev->vfl_dir != VFL_DIR_RX; @@ -587,39 +597,31 @@ set_bit(_IOC_NR(VIDIOC_ENUM_FREQ_BANDS), valid_ioctls); if (is_vid || is_tch) { - /* video and metadata specific ioctls */ + /* video and touch specific ioctls */ if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || - ops->vidioc_enum_fmt_vid_overlay || - ops->vidioc_enum_fmt_meta_cap)) || - (is_tx && (ops->vidioc_enum_fmt_vid_out || - ops->vidioc_enum_fmt_meta_out))) + ops->vidioc_enum_fmt_vid_overlay)) || + (is_tx && ops->vidioc_enum_fmt_vid_out)) set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); if ((is_rx && (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane || - ops->vidioc_g_fmt_vid_overlay || - ops->vidioc_g_fmt_meta_cap)) || + ops->vidioc_g_fmt_vid_overlay)) || (is_tx && (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane || - ops->vidioc_g_fmt_vid_out_overlay || - ops->vidioc_g_fmt_meta_out))) + ops->vidioc_g_fmt_vid_out_overlay))) set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); if ((is_rx && (ops->vidioc_s_fmt_vid_cap || ops->vidioc_s_fmt_vid_cap_mplane || - ops->vidioc_s_fmt_vid_overlay || - ops->vidioc_s_fmt_meta_cap)) || + ops->vidioc_s_fmt_vid_overlay)) || (is_tx && (ops->vidioc_s_fmt_vid_out || ops->vidioc_s_fmt_vid_out_mplane || - ops->vidioc_s_fmt_vid_out_overlay || - ops->vidioc_s_fmt_meta_out))) + ops->vidioc_s_fmt_vid_out_overlay))) set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); if ((is_rx && (ops->vidioc_try_fmt_vid_cap || ops->vidioc_try_fmt_vid_cap_mplane || - ops->vidioc_try_fmt_vid_overlay || - ops->vidioc_try_fmt_meta_cap)) || + ops->vidioc_try_fmt_vid_overlay)) || (is_tx && (ops->vidioc_try_fmt_vid_out || ops->vidioc_try_fmt_vid_out_mplane || - ops->vidioc_try_fmt_vid_out_overlay || - ops->vidioc_try_fmt_meta_out))) + ops->vidioc_try_fmt_vid_out_overlay))) set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); @@ -641,7 +643,21 @@ set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); - } else if (is_vbi) { + } + if (is_meta && is_rx) { + /* metadata capture specific ioctls */ + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_cap); + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_cap); + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_cap); + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_cap); + } else if (is_meta && is_tx) { + /* metadata output specific ioctls */ + SET_VALID_IOCTL(ops, VIDIOC_ENUM_FMT, vidioc_enum_fmt_meta_out); + SET_VALID_IOCTL(ops, VIDIOC_G_FMT, vidioc_g_fmt_meta_out); + SET_VALID_IOCTL(ops, VIDIOC_S_FMT, vidioc_s_fmt_meta_out); + SET_VALID_IOCTL(ops, VIDIOC_TRY_FMT, vidioc_try_fmt_meta_out); + } + if (is_vbi) { /* vbi specific ioctls */ if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || ops->vidioc_g_fmt_sliced_vbi_cap)) || @@ -681,8 +697,8 @@ set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); } - if (is_vid || is_vbi || is_sdr || is_tch) { - /* ioctls valid for video, metadata, vbi or sdr */ + if (is_vid || is_vbi || is_sdr || is_tch || is_meta) { + /* ioctls valid for video, vbi, sdr, touch and metadata */ SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); @@ -694,8 +710,8 @@ SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); } - if (is_vid || is_vbi || is_tch) { - /* ioctls valid for video or vbi */ + if (is_vid || is_vbi || is_tch || is_meta) { + /* ioctls valid for video, vbi, touch and metadata */ if (ops->vidioc_s_std) set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); @@ -761,7 +777,7 @@ vdev->entity.function = MEDIA_ENT_F_UNKNOWN; switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: + case VFL_TYPE_VIDEO: intf_type = MEDIA_INTF_T_V4L_VIDEO; vdev->entity.function = MEDIA_ENT_F_IO_V4L; break; @@ -869,7 +885,7 @@ /* Part 1: check device type */ switch (type) { - case VFL_TYPE_GRABBER: + case VFL_TYPE_VIDEO: name_base = "video"; break; case VFL_TYPE_VBI: @@ -913,7 +929,7 @@ * of 128-191 and just pick the first free minor there * (new style). */ switch (type) { - case VFL_TYPE_GRABBER: + case VFL_TYPE_VIDEO: minor_offset = 0; minor_cnt = 64; break; @@ -995,8 +1011,10 @@ vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); vdev->dev.parent = vdev->dev_parent; dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num); + mutex_lock(&videodev_lock); ret = device_register(&vdev->dev); if (ret < 0) { + mutex_unlock(&videodev_lock); pr_err("%s: device_register failed\n", __func__); goto cleanup; } @@ -1016,6 +1034,7 @@ /* Part 6: Activate this minor. The char device can now be used. */ set_bit(V4L2_FL_REGISTERED, &vdev->flags); + mutex_unlock(&videodev_lock); return 0; --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-device.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-device.c @@ -179,6 +179,7 @@ if (sd->internal_ops && sd->internal_ops->release) sd->internal_ops->release(sd); + sd->devnode = NULL; module_put(owner); } --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-dv-timings.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -145,6 +145,8 @@ const struct v4l2_bt_timings *bt = &t->bt; const struct v4l2_bt_timings_cap *cap = &dvcap->bt; u32 caps = cap->capabilities; + const u32 max_vert = 10240; + u32 max_hor = 3 * bt->width; if (t->type != V4L2_DV_BT_656_1120) return false; @@ -161,6 +163,26 @@ (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) || (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE))) return false; + + /* sanity checks for the blanking timings */ + if (!bt->interlaced && + (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch)) + return false; + /* + * Some video receivers cannot properly separate the frontporch, + * backporch and sync values, and instead they only have the total + * blanking. That can be assigned to any of these three fields. + * So just check that none of these are way out of range. + */ + if (bt->hfrontporch > max_hor || + bt->hsync > max_hor || bt->hbackporch > max_hor) + return false; + if (bt->vfrontporch > max_vert || + bt->vsync > max_vert || bt->vbackporch > max_vert) + return false; + if (bt->interlaced && (bt->il_vfrontporch > max_vert || + bt->il_vsync > max_vert || bt->il_vbackporch > max_vert)) + return false; return fnc == NULL || fnc(t, fnc_handle); } EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings); @@ -196,7 +218,7 @@ if (!v4l2_valid_dv_timings(t, cap, fnc, fnc_handle)) return false; - for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) { + for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { if (v4l2_valid_dv_timings(v4l2_dv_timings_presets + i, cap, fnc, fnc_handle) && v4l2_match_dv_timings(t, v4l2_dv_timings_presets + i, @@ -218,7 +240,7 @@ { unsigned int i; - for (i = 0; i < v4l2_dv_timings_presets[i].bt.width; i++) { + for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) { const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt; --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-fh.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-fh.c @@ -96,6 +96,7 @@ v4l2_fh_del(fh); v4l2_fh_exit(fh); kfree(fh); + filp->private_data = NULL; } return 0; } --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-fwnode.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-fwnode.c @@ -93,7 +93,7 @@ const struct v4l2_fwnode_bus_conv *conv = get_v4l2_fwnode_bus_conv_by_fwnode_bus(type); - return conv ? conv->mbus_type : V4L2_MBUS_UNKNOWN; + return conv ? conv->mbus_type : V4L2_MBUS_INVALID; } static const char * @@ -436,6 +436,10 @@ v4l2_fwnode_mbus_type_to_string(vep->bus_type), vep->bus_type); mbus_type = v4l2_fwnode_bus_type_to_mbus(bus_type); + if (mbus_type == V4L2_MBUS_INVALID) { + pr_debug("unsupported bus type %u\n", bus_type); + return -EINVAL; + } if (vep->bus_type != V4L2_MBUS_UNKNOWN) { if (mbus_type != V4L2_MBUS_UNKNOWN && @@ -556,35 +560,38 @@ } EXPORT_SYMBOL_GPL(v4l2_fwnode_endpoint_alloc_parse); -int v4l2_fwnode_parse_link(struct fwnode_handle *__fwnode, +int v4l2_fwnode_parse_link(struct fwnode_handle *fwnode, struct v4l2_fwnode_link *link) { - const char *port_prop = is_of_node(__fwnode) ? "reg" : "port"; - struct fwnode_handle *fwnode; + struct fwnode_endpoint fwep; memset(link, 0, sizeof(*link)); - fwnode = fwnode_get_parent(__fwnode); - fwnode_property_read_u32(fwnode, port_prop, &link->local_port); - fwnode = fwnode_get_next_parent(fwnode); - if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports")) - fwnode = fwnode_get_next_parent(fwnode); - link->local_node = fwnode; - - fwnode = fwnode_graph_get_remote_endpoint(__fwnode); - if (!fwnode) { - fwnode_handle_put(fwnode); + fwnode_graph_parse_endpoint(fwnode, &fwep); + link->local_port = fwep.port; + link->local_node = fwnode_graph_get_port_parent(fwnode); + if (!link->local_node) return -ENOLINK; - } - fwnode = fwnode_get_parent(fwnode); - fwnode_property_read_u32(fwnode, port_prop, &link->remote_port); - fwnode = fwnode_get_next_parent(fwnode); - if (is_of_node(fwnode) && of_node_name_eq(to_of_node(fwnode), "ports")) - fwnode = fwnode_get_next_parent(fwnode); - link->remote_node = fwnode; + fwnode = fwnode_graph_get_remote_endpoint(fwnode); + if (!fwnode) + goto err_put_local_node; + + fwnode_graph_parse_endpoint(fwnode, &fwep); + link->remote_port = fwep.port; + link->remote_node = fwnode_graph_get_port_parent(fwnode); + if (!link->remote_node) + goto err_put_remote_endpoint; return 0; + +err_put_remote_endpoint: + fwnode_handle_put(fwnode); + +err_put_local_node: + fwnode_handle_put(link->local_node); + + return -ENOLINK; } EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link); --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-ioctl.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-ioctl.c @@ -902,7 +902,7 @@ pr_cont("driver-specific ioctl\n"); } -static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) +static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) { __u32 i; @@ -911,33 +911,61 @@ for (i = 0; i < c->count; i++) c->controls[i].reserved2[0] = 0; - /* V4L2_CID_PRIVATE_BASE cannot be used as control class - when using extended controls. - Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL - is it allowed for backwards compatibility. - */ - if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE) - return 0; - if (!c->which) - return 1; + switch (c->which) { + case V4L2_CID_PRIVATE_BASE: + /* + * V4L2_CID_PRIVATE_BASE cannot be used as control class + * when using extended controls. + * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL + * is it allowed for backwards compatibility. + */ + if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL) + return false; + break; + case V4L2_CTRL_WHICH_DEF_VAL: + /* Default value cannot be changed */ + if (ioctl == VIDIOC_S_EXT_CTRLS || + ioctl == VIDIOC_TRY_EXT_CTRLS) { + c->error_idx = c->count; + return false; + } + return true; + case V4L2_CTRL_WHICH_CUR_VAL: + return true; + case V4L2_CTRL_WHICH_REQUEST_VAL: + c->error_idx = c->count; + return false; + } + /* Check that all controls are from the same control class. */ for (i = 0; i < c->count; i++) { if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { - c->error_idx = i; - return 0; + c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : + c->count; + return false; } } - return 1; + return true; } static int check_fmt(struct file *file, enum v4l2_buf_type type) { + const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; + const u32 meta_caps = V4L2_CAP_META_CAPTURE | + V4L2_CAP_META_OUTPUT; struct video_device *vfd = video_devdata(file); const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; - bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; + bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO && + (vfd->device_caps & vid_caps); bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; + bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO && + (vfd->device_caps & meta_caps); bool is_rx = vfd->vfl_dir != VFL_DIR_TX; bool is_tx = vfd->vfl_dir != VFL_DIR_RX; @@ -996,11 +1024,11 @@ return 0; break; case V4L2_BUF_TYPE_META_CAPTURE: - if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) + if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap) return 0; break; case V4L2_BUF_TYPE_META_OUTPUT: - if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out) + if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out) return 0; break; default: @@ -1466,10 +1494,26 @@ return ret; } +static void v4l_pix_format_touch(struct v4l2_pix_format *p) +{ + /* + * The v4l2_pix_format structure contains fields that make no sense for + * touch. Set them to default values in this case. + */ + + p->field = V4L2_FIELD_NONE; + p->colorspace = V4L2_COLORSPACE_RAW; + p->flags = 0; + p->ycbcr_enc = 0; + p->quantization = 0; + p->xfer_func = 0; +} + static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { struct v4l2_format *p = arg; + struct video_device *vfd = video_devdata(file); int ret = check_fmt(file, p->type); if (ret) @@ -1507,6 +1551,8 @@ ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); /* just in case the driver zeroed it again */ p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; + if (vfd->vfl_type == VFL_TYPE_TOUCH) + v4l_pix_format_touch(&p->fmt.pix); return ret; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); @@ -1544,21 +1590,6 @@ return -EINVAL; } -static void v4l_pix_format_touch(struct v4l2_pix_format *p) -{ - /* - * The v4l2_pix_format structure contains fields that make no sense for - * touch. Set them to default values in this case. - */ - - p->field = V4L2_FIELD_NONE; - p->colorspace = V4L2_COLORSPACE_RAW; - p->flags = 0; - p->ycbcr_enc = 0; - p->quantization = 0; - p->xfer_func = 0; -} - static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { @@ -1602,12 +1633,12 @@ case V4L2_BUF_TYPE_VBI_CAPTURE: if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.vbi); + CLEAR_AFTER_FIELD(p, fmt.vbi.flags); return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.sliced); + CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (unlikely(!ops->vidioc_s_fmt_vid_out)) @@ -1633,22 +1664,22 @@ case V4L2_BUF_TYPE_VBI_OUTPUT: if (unlikely(!ops->vidioc_s_fmt_vbi_out)) break; - CLEAR_AFTER_FIELD(p, fmt.vbi); + CLEAR_AFTER_FIELD(p, fmt.vbi.flags); return ops->vidioc_s_fmt_vbi_out(file, fh, arg); case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) break; - CLEAR_AFTER_FIELD(p, fmt.sliced); + CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); case V4L2_BUF_TYPE_SDR_CAPTURE: if (unlikely(!ops->vidioc_s_fmt_sdr_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.sdr); + CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); return ops->vidioc_s_fmt_sdr_cap(file, fh, arg); case V4L2_BUF_TYPE_SDR_OUTPUT: if (unlikely(!ops->vidioc_s_fmt_sdr_out)) break; - CLEAR_AFTER_FIELD(p, fmt.sdr); + CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); return ops->vidioc_s_fmt_sdr_out(file, fh, arg); case V4L2_BUF_TYPE_META_CAPTURE: if (unlikely(!ops->vidioc_s_fmt_meta_cap)) @@ -1704,12 +1735,12 @@ case V4L2_BUF_TYPE_VBI_CAPTURE: if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.vbi); + CLEAR_AFTER_FIELD(p, fmt.vbi.flags); return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.sliced); + CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (unlikely(!ops->vidioc_try_fmt_vid_out)) @@ -1735,22 +1766,22 @@ case V4L2_BUF_TYPE_VBI_OUTPUT: if (unlikely(!ops->vidioc_try_fmt_vbi_out)) break; - CLEAR_AFTER_FIELD(p, fmt.vbi); + CLEAR_AFTER_FIELD(p, fmt.vbi.flags); return ops->vidioc_try_fmt_vbi_out(file, fh, arg); case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) break; - CLEAR_AFTER_FIELD(p, fmt.sliced); + CLEAR_AFTER_FIELD(p, fmt.sliced.io_size); return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); case V4L2_BUF_TYPE_SDR_CAPTURE: if (unlikely(!ops->vidioc_try_fmt_sdr_cap)) break; - CLEAR_AFTER_FIELD(p, fmt.sdr); + CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); return ops->vidioc_try_fmt_sdr_cap(file, fh, arg); case V4L2_BUF_TYPE_SDR_OUTPUT: if (unlikely(!ops->vidioc_try_fmt_sdr_out)) break; - CLEAR_AFTER_FIELD(p, fmt.sdr); + CLEAR_AFTER_FIELD(p, fmt.sdr.buffersize); return ops->vidioc_try_fmt_sdr_out(file, fh, arg); case V4L2_BUF_TYPE_META_CAPTURE: if (unlikely(!ops->vidioc_try_fmt_meta_cap)) @@ -2025,6 +2056,7 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { + struct video_device *vfd = video_devdata(file); struct v4l2_streamparm *p = arg; v4l2_std_id std; int ret = check_fmt(file, p->type); @@ -2036,7 +2068,8 @@ if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) return -EINVAL; - p->parm.capture.readbuffers = 2; + if (vfd->device_caps & V4L2_CAP_READWRITE) + p->parm.capture.readbuffers = 2; ret = ops->vidioc_g_std(file, fh, &std); if (ret == 0) v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); @@ -2142,7 +2175,7 @@ ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) { + if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) { int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); if (ret == 0) @@ -2176,7 +2209,7 @@ ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) + if (check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); return -EINVAL; } @@ -2198,8 +2231,8 @@ vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_g_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ? + ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL; } static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, @@ -2219,8 +2252,8 @@ vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_s_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ? + ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL; } static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, @@ -2240,8 +2273,8 @@ vfd, vfd->v4l2_dev->mdev, p); if (ops->vidioc_try_ext_ctrls == NULL) return -ENOTTY; - return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) : - -EINVAL; + return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ? + ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL; } /* @@ -3013,7 +3046,7 @@ v4l2_kioctl func) { char sbuf[128]; - void *mbuf = NULL; + void *mbuf = NULL, *array_buf = NULL; void *parg = (void *)arg; long err = -EINVAL; bool has_array_args; @@ -3072,20 +3105,14 @@ has_array_args = err; if (has_array_args) { - /* - * When adding new types of array args, make sure that the - * parent argument to ioctl (which contains the pointer to the - * array) fits into sbuf (so that mbuf will still remain - * unused up to here). - */ - mbuf = kvmalloc(array_size, GFP_KERNEL); + array_buf = kvmalloc(array_size, GFP_KERNEL); err = -ENOMEM; - if (NULL == mbuf) + if (array_buf == NULL) goto out_array_args; err = -EFAULT; - if (copy_from_user(mbuf, user_ptr, array_size)) + if (copy_from_user(array_buf, user_ptr, array_size)) goto out_array_args; - *kernel_ptr = mbuf; + *kernel_ptr = array_buf; } /* Handles IOCTL */ @@ -3104,7 +3131,7 @@ if (has_array_args) { *kernel_ptr = (void __force *)user_ptr; - if (copy_to_user(user_ptr, mbuf, array_size)) + if (copy_to_user(user_ptr, array_buf, array_size)) err = -EFAULT; goto out_array_args; } @@ -3126,6 +3153,7 @@ } out: + kvfree(array_buf); kvfree(mbuf); return err; } --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/v4l2-mem2mem.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -460,19 +460,14 @@ } EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs); -int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, - struct v4l2_buffer *buf) +static void v4l2_m2m_adjust_mem_offset(struct vb2_queue *vq, + struct v4l2_buffer *buf) { - struct vb2_queue *vq; - int ret = 0; - unsigned int i; - - vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); - ret = vb2_querybuf(vq, buf); - /* Adjust MMAP memory offsets for the CAPTURE queue */ if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) { if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) { + unsigned int i; + for (i = 0; i < buf->length; ++i) buf->m.planes[i].m.mem_offset += DST_QUEUE_OFF_BASE; @@ -480,8 +475,23 @@ buf->m.offset += DST_QUEUE_OFF_BASE; } } +} - return ret; +int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_buffer *buf) +{ + struct vb2_queue *vq; + int ret; + + vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); + ret = vb2_querybuf(vq, buf); + if (ret) + return ret; + + /* Adjust MMAP memory offsets for the CAPTURE queue */ + v4l2_m2m_adjust_mem_offset(vq, buf); + + return 0; } EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf); @@ -500,10 +510,16 @@ return -EPERM; } ret = vb2_qbuf(vq, vdev->v4l2_dev->mdev, buf); - if (!ret && !(buf->flags & V4L2_BUF_FLAG_IN_REQUEST)) + if (ret) + return ret; + + /* Adjust MMAP memory offsets for the CAPTURE queue */ + v4l2_m2m_adjust_mem_offset(vq, buf); + + if (!(buf->flags & V4L2_BUF_FLAG_IN_REQUEST)) v4l2_m2m_try_schedule(m2m_ctx); - return ret; + return 0; } EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf); @@ -511,9 +527,17 @@ struct v4l2_buffer *buf) { struct vb2_queue *vq; + int ret; vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); - return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); + ret = vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); + if (ret) + return ret; + + /* Adjust MMAP memory offsets for the CAPTURE queue */ + v4l2_m2m_adjust_mem_offset(vq, buf); + + return 0; } EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); @@ -522,9 +546,17 @@ { struct video_device *vdev = video_devdata(file); struct vb2_queue *vq; + int ret; vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); - return vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf); + ret = vb2_prepare_buf(vq, vdev->v4l2_dev->mdev, buf); + if (ret) + return ret; + + /* Adjust MMAP memory offsets for the CAPTURE queue */ + v4l2_m2m_adjust_mem_offset(vq, buf); + + return 0; } EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf); @@ -635,10 +667,8 @@ * If the last buffer was dequeued from the capture queue, * return immediately. DQBUF will return -EPIPE. */ - if (dst_q->last_buffer_dequeued) { - spin_unlock_irqrestore(&dst_q->done_lock, flags); - return EPOLLIN | EPOLLRDNORM; - } + if (dst_q->last_buffer_dequeued) + rc |= EPOLLIN | EPOLLRDNORM; } spin_unlock_irqrestore(&dst_q->done_lock, flags); @@ -769,11 +799,17 @@ entity->function = function; ret = media_entity_pads_init(entity, num_pads, pads); - if (ret) + if (ret) { + kfree(entity->name); + entity->name = NULL; return ret; + } ret = media_device_register_entity(mdev, entity); - if (ret) + if (ret) { + kfree(entity->name); + entity->name = NULL; return ret; + } return 0; } @@ -809,12 +845,12 @@ goto err_rel_entity1; /* Connect the three entities */ - ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 1, + ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 0, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); if (ret) goto err_rel_entity2; - ret = media_create_pad_link(&m2m_dev->proc, 0, &m2m_dev->sink, 0, + ret = media_create_pad_link(&m2m_dev->proc, 1, &m2m_dev->sink, 0, MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); if (ret) goto err_rm_links0; --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/videobuf-dma-contig.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/videobuf-dma-contig.c @@ -36,12 +36,11 @@ static int __videobuf_dc_alloc(struct device *dev, struct videobuf_dma_contig_memory *mem, - unsigned long size, gfp_t flags) + unsigned long size) { mem->size = size; - mem->vaddr = dma_alloc_coherent(dev, mem->size, - &mem->dma_handle, flags); - + mem->vaddr = dma_alloc_coherent(dev, mem->size, &mem->dma_handle, + GFP_KERNEL); if (!mem->vaddr) { dev_err(dev, "memory alloc size %ld failed\n", mem->size); return -ENOMEM; @@ -258,8 +257,7 @@ return videobuf_dma_contig_user_get(mem, vb); /* allocate memory for the read() method */ - if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size), - GFP_KERNEL)) + if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(vb->size))) return -ENOMEM; break; case V4L2_MEMORY_OVERLAY: @@ -295,22 +293,18 @@ BUG_ON(!mem); MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); - if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize), - GFP_KERNEL | __GFP_COMP)) + if (__videobuf_dc_alloc(q->dev, mem, PAGE_ALIGN(buf->bsize))) goto error; - /* Try to remap memory */ - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - /* the "vm_pgoff" is just used in v4l2 to find the * corresponding buffer data structure which is allocated * earlier and it does not mean the offset from the physical * buffer start address as usual. So set it to 0 to pass - * the sanity check in vm_iomap_memory(). + * the sanity check in dma_mmap_coherent(). */ vma->vm_pgoff = 0; - - retval = vm_iomap_memory(vma, mem->dma_handle, mem->size); + retval = dma_mmap_coherent(q->dev, vma, mem->vaddr, mem->dma_handle, + mem->size); if (retval) { dev_err(q->dev, "mmap: remap failed with error %d. ", retval); --- linux-oracle-5.4.0.orig/drivers/media/v4l2-core/videobuf-dma-sg.c +++ linux-oracle-5.4.0/drivers/media/v4l2-core/videobuf-dma-sg.c @@ -349,8 +349,11 @@ BUG_ON(dma->sglen); if (dma->pages) { - for (i = 0; i < dma->nr_pages; i++) + for (i = 0; i < dma->nr_pages; i++) { + if (dma->direction == DMA_FROM_DEVICE) + set_page_dirty_lock(dma->pages[i]); put_page(dma->pages[i]); + } kfree(dma->pages); dma->pages = NULL; } --- linux-oracle-5.4.0.orig/drivers/memory/atmel-ebi.c +++ linux-oracle-5.4.0/drivers/memory/atmel-ebi.c @@ -545,20 +545,27 @@ smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0); ebi->smc.regmap = syscon_node_to_regmap(smc_np); - if (IS_ERR(ebi->smc.regmap)) - return PTR_ERR(ebi->smc.regmap); + if (IS_ERR(ebi->smc.regmap)) { + ret = PTR_ERR(ebi->smc.regmap); + goto put_node; + } ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np); - if (IS_ERR(ebi->smc.layout)) - return PTR_ERR(ebi->smc.layout); + if (IS_ERR(ebi->smc.layout)) { + ret = PTR_ERR(ebi->smc.layout); + goto put_node; + } ebi->smc.clk = of_clk_get(smc_np, 0); if (IS_ERR(ebi->smc.clk)) { - if (PTR_ERR(ebi->smc.clk) != -ENOENT) - return PTR_ERR(ebi->smc.clk); + if (PTR_ERR(ebi->smc.clk) != -ENOENT) { + ret = PTR_ERR(ebi->smc.clk); + goto put_node; + } ebi->smc.clk = NULL; } + of_node_put(smc_np); ret = clk_prepare_enable(ebi->smc.clk); if (ret) return ret; @@ -601,12 +608,18 @@ child); ret = atmel_ebi_dev_disable(ebi, child); - if (ret) + if (ret) { + of_node_put(child); return ret; + } } } return of_platform_populate(np, NULL, NULL, dev); + +put_node: + of_node_put(smc_np); + return ret; } static __maybe_unused int atmel_ebi_resume(struct device *dev) --- linux-oracle-5.4.0.orig/drivers/memory/atmel-sdramc.c +++ linux-oracle-5.4.0/drivers/memory/atmel-sdramc.c @@ -47,19 +47,17 @@ caps = of_device_get_match_data(&pdev->dev); if (caps->has_ddrck) { - clk = devm_clk_get(&pdev->dev, "ddrck"); + clk = devm_clk_get_enabled(&pdev->dev, "ddrck"); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); } if (caps->has_mpddr_clk) { - clk = devm_clk_get(&pdev->dev, "mpddr"); + clk = devm_clk_get_enabled(&pdev->dev, "mpddr"); if (IS_ERR(clk)) { pr_err("AT91 RAMC: couldn't get mpddr clock\n"); return PTR_ERR(clk); } - clk_prepare_enable(clk); } return 0; --- linux-oracle-5.4.0.orig/drivers/memory/brcmstb_dpfe.c +++ linux-oracle-5.4.0/drivers/memory/brcmstb_dpfe.c @@ -398,15 +398,17 @@ static int __send_command(struct private_data *priv, unsigned int cmd, u32 result[]) { - const u32 *msg = priv->dpfe_api->command[cmd]; void __iomem *regs = priv->regs; unsigned int i, chksum, chksum_idx; + const u32 *msg; int ret = 0; u32 resp; if (cmd >= DPFE_CMD_MAX) return -1; + msg = priv->dpfe_api->command[cmd]; + mutex_lock(&priv->lock); /* Wait for DCPU to become ready */ --- linux-oracle-5.4.0.orig/drivers/memory/emif.c +++ linux-oracle-5.4.0/drivers/memory/emif.c @@ -163,35 +163,12 @@ static int __init_or_module emif_debugfs_init(struct emif_data *emif) { - struct dentry *dentry; - int ret; - - dentry = debugfs_create_dir(dev_name(emif->dev), NULL); - if (!dentry) { - ret = -ENOMEM; - goto err0; - } - emif->debugfs_root = dentry; - - dentry = debugfs_create_file("regcache_dump", S_IRUGO, - emif->debugfs_root, emif, &emif_regdump_fops); - if (!dentry) { - ret = -ENOMEM; - goto err1; - } - - dentry = debugfs_create_file("mr4", S_IRUGO, - emif->debugfs_root, emif, &emif_mr4_fops); - if (!dentry) { - ret = -ENOMEM; - goto err1; - } - + emif->debugfs_root = debugfs_create_dir(dev_name(emif->dev), NULL); + debugfs_create_file("regcache_dump", S_IRUGO, emif->debugfs_root, emif, + &emif_regdump_fops); + debugfs_create_file("mr4", S_IRUGO, emif->debugfs_root, emif, + &emif_mr4_fops); return 0; -err1: - debugfs_remove_recursive(emif->debugfs_root); -err0: - return ret; } static void __exit emif_debugfs_exit(struct emif_data *emif) @@ -1446,7 +1423,7 @@ temp = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); dev_info = devm_kzalloc(dev, sizeof(*dev_info), GFP_KERNEL); - if (!emif || !pd || !dev_info) { + if (!emif || !temp || !dev_info) { dev_err(dev, "%s:%d: allocation error\n", __func__, __LINE__); goto error; } @@ -1538,7 +1515,7 @@ { struct emif_data *emif; struct resource *res; - int irq; + int irq, ret; if (pdev->dev.of_node) emif = of_get_memory_device_details(pdev->dev.of_node, &pdev->dev); @@ -1572,7 +1549,9 @@ emif_onetime_settings(emif); emif_debugfs_init(emif); disable_and_clear_all_interrupts(emif); - setup_interrupts(emif, irq); + ret = setup_interrupts(emif, irq); + if (ret) + goto error; /* One-time actions taken on probing the first device */ if (!emif1) { --- linux-oracle-5.4.0.orig/drivers/memory/fsl-corenet-cf.c +++ linux-oracle-5.4.0/drivers/memory/fsl-corenet-cf.c @@ -211,10 +211,8 @@ dev_set_drvdata(&pdev->dev, ccf); irq = platform_get_irq(pdev, 0); - if (!irq) { - dev_err(&pdev->dev, "%s: no irq\n", __func__); - return -ENXIO; - } + if (irq < 0) + return irq; ret = devm_request_irq(&pdev->dev, irq, ccf_irq, 0, pdev->name, ccf); if (ret) { --- linux-oracle-5.4.0.orig/drivers/memory/fsl_ifc.c +++ linux-oracle-5.4.0/drivers/memory/fsl_ifc.c @@ -96,7 +96,6 @@ iounmap(ctrl->gregs); dev_set_drvdata(&dev->dev, NULL); - kfree(ctrl); return 0; } @@ -208,7 +207,8 @@ dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); - fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); + fsl_ifc_ctrl_dev = devm_kzalloc(&dev->dev, sizeof(*fsl_ifc_ctrl_dev), + GFP_KERNEL); if (!fsl_ifc_ctrl_dev) return -ENOMEM; @@ -218,8 +218,7 @@ fsl_ifc_ctrl_dev->gregs = of_iomap(dev->dev.of_node, 0); if (!fsl_ifc_ctrl_dev->gregs) { dev_err(&dev->dev, "failed to get memory region\n"); - ret = -ENODEV; - goto err; + return -ENODEV; } if (of_property_read_bool(dev->dev.of_node, "little-endian")) { @@ -264,7 +263,7 @@ ret = fsl_ifc_ctrl_init(fsl_ifc_ctrl_dev); if (ret < 0) - goto err; + goto err_unmap_nandirq; init_waitqueue_head(&fsl_ifc_ctrl_dev->nand_wait); @@ -273,7 +272,7 @@ if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->irq); - goto err_irq; + goto err_unmap_nandirq; } if (fsl_ifc_ctrl_dev->nand_irq) { @@ -282,19 +281,19 @@ if (ret != 0) { dev_err(&dev->dev, "failed to install irq (%d)\n", fsl_ifc_ctrl_dev->nand_irq); - goto err_nandirq; + goto err_free_irq; } } return 0; -err_nandirq: - free_irq(fsl_ifc_ctrl_dev->nand_irq, fsl_ifc_ctrl_dev); - irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); -err_irq: +err_free_irq: free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); +err_unmap_nandirq: + irq_dispose_mapping(fsl_ifc_ctrl_dev->nand_irq); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: + iounmap(fsl_ifc_ctrl_dev->gregs); return ret; } --- linux-oracle-5.4.0.orig/drivers/memory/mtk-smi.c +++ linux-oracle-5.4.0/drivers/memory/mtk-smi.c @@ -127,7 +127,7 @@ int mtk_smi_larb_get(struct device *larbdev) { - int ret = pm_runtime_get_sync(larbdev); + int ret = pm_runtime_resume_and_get(larbdev); return (ret < 0) ? ret : 0; } @@ -336,7 +336,7 @@ int ret; /* Power on smi-common. */ - ret = pm_runtime_get_sync(larb->smi_common_dev); + ret = pm_runtime_resume_and_get(larb->smi_common_dev); if (ret < 0) { dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret); return ret; @@ -366,6 +366,8 @@ static const struct dev_pm_ops smi_larb_pm_ops = { SET_RUNTIME_PM_OPS(mtk_smi_larb_suspend, mtk_smi_larb_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) }; static struct platform_driver mtk_smi_larb_driver = { @@ -507,6 +509,8 @@ static const struct dev_pm_ops smi_common_pm_ops = { SET_RUNTIME_PM_OPS(mtk_smi_common_suspend, mtk_smi_common_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) }; static struct platform_driver mtk_smi_common_driver = { --- linux-oracle-5.4.0.orig/drivers/memory/mvebu-devbus.c +++ linux-oracle-5.4.0/drivers/memory/mvebu-devbus.c @@ -282,10 +282,9 @@ if (IS_ERR(devbus->base)) return PTR_ERR(devbus->base); - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); /* * Obtain clock period in picoseconds, --- linux-oracle-5.4.0.orig/drivers/memory/of_memory.c +++ linux-oracle-5.4.0/drivers/memory/of_memory.c @@ -132,6 +132,7 @@ for_each_child_of_node(np_ddr, np_tim) { if (of_device_is_compatible(np_tim, tim_compat)) { if (of_do_get_timings(np_tim, &timings[i])) { + of_node_put(np_tim); devm_kfree(dev, timings); goto default_timings; } --- linux-oracle-5.4.0.orig/drivers/memory/omap-gpmc.c +++ linux-oracle-5.4.0/drivers/memory/omap-gpmc.c @@ -949,7 +949,7 @@ int ret; u32 old_base, size; - if (cs > gpmc_cs_num) { + if (cs >= gpmc_cs_num) { pr_err("%s: requested chip-select is disabled\n", __func__); return -ENODEV; } @@ -984,7 +984,7 @@ struct resource *res = &gpmc->mem; int r = -1; - if (cs > gpmc_cs_num) { + if (cs >= gpmc_cs_num) { pr_err("%s: requested chip-select is disabled\n", __func__); return -ENODEV; } @@ -1026,8 +1026,8 @@ void gpmc_cs_free(int cs) { - struct gpmc_cs_data *gpmc = &gpmc_cs[cs]; - struct resource *res = &gpmc->mem; + struct gpmc_cs_data *gpmc; + struct resource *res; spin_lock(&gpmc_mem_lock); if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { @@ -1036,6 +1036,9 @@ spin_unlock(&gpmc_mem_lock); return; } + gpmc = &gpmc_cs[cs]; + res = &gpmc->mem; + gpmc_cs_disable_mem(cs); if (res->flags) release_resource(res); @@ -2274,6 +2277,10 @@ } } #else +void gpmc_read_settings_dt(struct device_node *np, struct gpmc_settings *p) +{ + memset(p, 0, sizeof(*p)); +} static int gpmc_probe_dt(struct platform_device *pdev) { return 0; --- linux-oracle-5.4.0.orig/drivers/memory/pl353-smc.c +++ linux-oracle-5.4.0/drivers/memory/pl353-smc.c @@ -63,7 +63,7 @@ /* ECC memory config register specific constants */ #define PL353_SMC_ECC_MEMCFG_MODE_MASK 0xC #define PL353_SMC_ECC_MEMCFG_MODE_SHIFT 2 -#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0xC +#define PL353_SMC_ECC_MEMCFG_PGSIZE_MASK 0x3 #define PL353_SMC_DC_UPT_NAND_REGS ((4 << 23) | /* CS: NAND chip */ \ (2 << 21)) /* UpdateRegs operation */ @@ -407,6 +407,7 @@ break; } if (!match) { + err = -ENODEV; dev_err(&adev->dev, "no matching children\n"); goto out_clk_disable; } @@ -415,6 +416,7 @@ if (init) init(adev, child); of_platform_device_create(child, NULL, &adev->dev); + of_node_put(child); return 0; --- linux-oracle-5.4.0.orig/drivers/memory/ti-aemif.c +++ linux-oracle-5.4.0/drivers/memory/ti-aemif.c @@ -378,8 +378,10 @@ */ for_each_available_child_of_node(np, child_np) { ret = of_aemif_parse_abus_config(pdev, child_np); - if (ret < 0) + if (ret < 0) { + of_node_put(child_np); goto error; + } } } else if (pdata && pdata->num_abus_data > 0) { for (i = 0; i < pdata->num_abus_data; i++, aemif->num_cs++) { @@ -405,8 +407,10 @@ for_each_available_child_of_node(np, child_np) { ret = of_platform_populate(child_np, NULL, dev_lookup, dev); - if (ret < 0) + if (ret < 0) { + of_node_put(child_np); goto error; + } } } else if (pdata) { for (i = 0; i < pdata->num_sub_devices; i++) { --- linux-oracle-5.4.0.orig/drivers/memstick/core/memstick.c +++ linux-oracle-5.4.0/drivers/memstick/core/memstick.c @@ -412,6 +412,7 @@ return card; err_out: host->card = old_card; + kfree_const(card->dev.kobj.name); kfree(card); return NULL; } @@ -441,6 +442,9 @@ } else if (host->card->stop) host->card->stop(host->card); + if (host->removing) + goto out_power_off; + card = memstick_alloc_card(host); if (!card) { @@ -465,11 +469,12 @@ host->card = card; if (device_register(&card->dev)) { put_device(&card->dev); - kfree(host->card); host->card = NULL; } - } else + } else { + kfree_const(card->dev.kobj.name); kfree(card); + } } out_power_off: @@ -545,6 +550,7 @@ */ void memstick_remove_host(struct memstick_host *host) { + host->removing = 1; flush_workqueue(workqueue); mutex_lock(&host->lock); if (host->card) --- linux-oracle-5.4.0.orig/drivers/memstick/core/ms_block.c +++ linux-oracle-5.4.0/drivers/memstick/core/ms_block.c @@ -1335,17 +1335,17 @@ msb->zone_count = msb->block_count / MS_BLOCKS_IN_ZONE; msb->logical_block_count = msb->zone_count * 496 - 2; - msb->used_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); - msb->erased_blocks_bitmap = kzalloc(msb->block_count / 8, GFP_KERNEL); + msb->used_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); + msb->erased_blocks_bitmap = bitmap_zalloc(msb->block_count, GFP_KERNEL); msb->lba_to_pba_table = kmalloc_array(msb->logical_block_count, sizeof(u16), GFP_KERNEL); if (!msb->used_blocks_bitmap || !msb->lba_to_pba_table || !msb->erased_blocks_bitmap) { - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); - kfree(msb->erased_blocks_bitmap); return -ENOMEM; } @@ -1727,7 +1727,7 @@ msb->pages_in_block = boot_block->attr.block_size * 2; msb->block_size = msb->page_size * msb->pages_in_block; - if (msb->page_size > PAGE_SIZE) { + if ((size_t)msb->page_size > PAGE_SIZE) { /* this isn't supported by linux at all, anyway*/ dbg("device page %d size isn't supported", msb->page_size); return -EINVAL; @@ -1953,7 +1953,8 @@ static void msb_data_clear(struct msb_data *msb) { kfree(msb->boot_page); - kfree(msb->used_blocks_bitmap); + bitmap_free(msb->used_blocks_bitmap); + bitmap_free(msb->erased_blocks_bitmap); kfree(msb->lba_to_pba_table); kfree(msb->cache); msb->card = NULL; --- linux-oracle-5.4.0.orig/drivers/memstick/host/jmb38x_ms.c +++ linux-oracle-5.4.0/drivers/memstick/host/jmb38x_ms.c @@ -314,7 +314,7 @@ } while (length) { - unsigned int uninitialized_var(p_off); + unsigned int p_off; if (host->req->long_data) { pg = nth_page(sg_page(&host->req->sg), @@ -899,7 +899,7 @@ iounmap(host->addr); err_out_free: - kfree(msh); + memstick_free_host(msh); return NULL; } --- linux-oracle-5.4.0.orig/drivers/memstick/host/r592.c +++ linux-oracle-5.4.0/drivers/memstick/host/r592.c @@ -44,12 +44,10 @@ * memstick_debug_get_tpc_name - debug helper that returns string for * a TPC number */ -const char *memstick_debug_get_tpc_name(int tpc) +static __maybe_unused const char *memstick_debug_get_tpc_name(int tpc) { return tpc_names[tpc-1]; } -EXPORT_SYMBOL(memstick_debug_get_tpc_name); - /* Read a register*/ static inline u32 r592_read_reg(struct r592_device *dev, int address) @@ -759,8 +757,10 @@ goto error3; dev->mmio = pci_ioremap_bar(pdev, 0); - if (!dev->mmio) + if (!dev->mmio) { + error = -ENOMEM; goto error4; + } dev->irq = pdev->irq; spin_lock_init(&dev->irq_lock); @@ -786,12 +786,14 @@ &dev->dummy_dma_page_physical_address, GFP_KERNEL); r592_stop_dma(dev , 0); - if (request_irq(dev->irq, &r592_irq, IRQF_SHARED, - DRV_NAME, dev)) + error = request_irq(dev->irq, &r592_irq, IRQF_SHARED, + DRV_NAME, dev); + if (error) goto error6; r592_update_card_detect(dev); - if (memstick_add_host(host)) + error = memstick_add_host(host); + if (error) goto error7; message("driver successfully loaded"); @@ -824,7 +826,7 @@ /* Stop the processing thread. That ensures that we won't take any more requests */ kthread_stop(dev->io_thread); - + del_timer_sync(&dev->detect_timer); r592_enable_device(dev, false); while (!error && dev->req) { @@ -833,15 +835,15 @@ } memstick_remove_host(dev->host); + if (dev->dummy_dma_page) + dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->dummy_dma_page, + dev->dummy_dma_page_physical_address); + free_irq(dev->irq, dev); iounmap(dev->mmio); pci_release_regions(pdev); pci_disable_device(pdev); memstick_free_host(dev->host); - - if (dev->dummy_dma_page) - dma_free_coherent(&pdev->dev, PAGE_SIZE, dev->dummy_dma_page, - dev->dummy_dma_page_physical_address); } #ifdef CONFIG_PM_SLEEP --- linux-oracle-5.4.0.orig/drivers/memstick/host/rtsx_usb_ms.c +++ linux-oracle-5.4.0/drivers/memstick/host/rtsx_usb_ms.c @@ -799,9 +799,9 @@ return 0; err_out: - memstick_free_host(msh); pm_runtime_disable(ms_dev(host)); pm_runtime_put_noidle(ms_dev(host)); + memstick_free_host(msh); return err; } @@ -828,9 +828,6 @@ } mutex_unlock(&host->host_mutex); - memstick_remove_host(msh); - memstick_free_host(msh); - /* Balance possible unbalanced usage count * e.g. unconditional module removal */ @@ -838,10 +835,11 @@ pm_runtime_put(ms_dev(host)); pm_runtime_disable(ms_dev(host)); - platform_set_drvdata(pdev, NULL); - + memstick_remove_host(msh); dev_dbg(ms_dev(host), ": Realtek USB Memstick controller has been removed\n"); + memstick_free_host(msh); + platform_set_drvdata(pdev, NULL); return 0; } --- linux-oracle-5.4.0.orig/drivers/memstick/host/tifm_ms.c +++ linux-oracle-5.4.0/drivers/memstick/host/tifm_ms.c @@ -198,7 +198,7 @@ host->block_pos); while (length) { - unsigned int uninitialized_var(p_off); + unsigned int p_off; if (host->req->long_data) { pg = nth_page(sg_page(&host->req->sg), --- linux-oracle-5.4.0.orig/drivers/message/fusion/mptctl.c +++ linux-oracle-5.4.0/drivers/message/fusion/mptctl.c @@ -100,19 +100,19 @@ * Function prototypes. Called from OS entry point mptctl_ioctl. * arg contents specific to function. */ -static int mptctl_fw_download(unsigned long arg); -static int mptctl_getiocinfo(unsigned long arg, unsigned int cmd); -static int mptctl_gettargetinfo(unsigned long arg); -static int mptctl_readtest(unsigned long arg); -static int mptctl_mpt_command(unsigned long arg); -static int mptctl_eventquery(unsigned long arg); -static int mptctl_eventenable(unsigned long arg); -static int mptctl_eventreport(unsigned long arg); -static int mptctl_replace_fw(unsigned long arg); - -static int mptctl_do_reset(unsigned long arg); -static int mptctl_hp_hostinfo(unsigned long arg, unsigned int cmd); -static int mptctl_hp_targetinfo(unsigned long arg); +static int mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_getiocinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd); +static int mptctl_gettargetinfo(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_readtest(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_mpt_command(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_eventquery(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_eventenable(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_eventreport(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_replace_fw(MPT_ADAPTER *iocp, unsigned long arg); + +static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg); +static int mptctl_hp_hostinfo(MPT_ADAPTER *iocp, unsigned long arg, unsigned int cmd); +static int mptctl_hp_targetinfo(MPT_ADAPTER *iocp, unsigned long arg); static int mptctl_probe(struct pci_dev *, const struct pci_device_id *); static void mptctl_remove(struct pci_dev *); @@ -123,8 +123,8 @@ /* * Private function calls. */ -static int mptctl_do_mpt_command(struct mpt_ioctl_command karg, void __user *mfPtr); -static int mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen); +static int mptctl_do_mpt_command(MPT_ADAPTER *iocp, struct mpt_ioctl_command karg, void __user *mfPtr); +static int mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen); static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags, struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc); static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, @@ -656,19 +656,19 @@ * by TM and FW reloads. */ if ((cmd & ~IOCSIZE_MASK) == (MPTIOCINFO & ~IOCSIZE_MASK)) { - return mptctl_getiocinfo(arg, _IOC_SIZE(cmd)); + return mptctl_getiocinfo(iocp, arg, _IOC_SIZE(cmd)); } else if (cmd == MPTTARGETINFO) { - return mptctl_gettargetinfo(arg); + return mptctl_gettargetinfo(iocp, arg); } else if (cmd == MPTTEST) { - return mptctl_readtest(arg); + return mptctl_readtest(iocp, arg); } else if (cmd == MPTEVENTQUERY) { - return mptctl_eventquery(arg); + return mptctl_eventquery(iocp, arg); } else if (cmd == MPTEVENTENABLE) { - return mptctl_eventenable(arg); + return mptctl_eventenable(iocp, arg); } else if (cmd == MPTEVENTREPORT) { - return mptctl_eventreport(arg); + return mptctl_eventreport(iocp, arg); } else if (cmd == MPTFWREPLACE) { - return mptctl_replace_fw(arg); + return mptctl_replace_fw(iocp, arg); } /* All of these commands require an interrupt or @@ -678,15 +678,15 @@ return ret; if (cmd == MPTFWDOWNLOAD) - ret = mptctl_fw_download(arg); + ret = mptctl_fw_download(iocp, arg); else if (cmd == MPTCOMMAND) - ret = mptctl_mpt_command(arg); + ret = mptctl_mpt_command(iocp, arg); else if (cmd == MPTHARDRESET) - ret = mptctl_do_reset(arg); + ret = mptctl_do_reset(iocp, arg); else if ((cmd & ~IOCSIZE_MASK) == (HP_GETHOSTINFO & ~IOCSIZE_MASK)) - ret = mptctl_hp_hostinfo(arg, _IOC_SIZE(cmd)); + ret = mptctl_hp_hostinfo(iocp, arg, _IOC_SIZE(cmd)); else if (cmd == HP_GETTARGETINFO) - ret = mptctl_hp_targetinfo(arg); + ret = mptctl_hp_targetinfo(iocp, arg); else ret = -EINVAL; @@ -705,11 +705,10 @@ return ret; } -static int mptctl_do_reset(unsigned long arg) +static int mptctl_do_reset(MPT_ADAPTER *iocp, unsigned long arg) { struct mpt_ioctl_diag_reset __user *urinfo = (void __user *) arg; struct mpt_ioctl_diag_reset krinfo; - MPT_ADAPTER *iocp; if (copy_from_user(&krinfo, urinfo, sizeof(struct mpt_ioctl_diag_reset))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_do_reset - " @@ -718,12 +717,6 @@ return -EFAULT; } - if (mpt_verify_adapter(krinfo.hdr.iocnum, &iocp) < 0) { - printk(KERN_DEBUG MYNAM "%s@%d::mptctl_do_reset - ioc%d not found!\n", - __FILE__, __LINE__, krinfo.hdr.iocnum); - return -ENODEV; /* (-6) No such device or address */ - } - dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n", iocp->name)); @@ -754,7 +747,7 @@ * -ENOMSG if FW upload returned bad status */ static int -mptctl_fw_download(unsigned long arg) +mptctl_fw_download(MPT_ADAPTER *iocp, unsigned long arg) { struct mpt_fw_xfer __user *ufwdl = (void __user *) arg; struct mpt_fw_xfer kfwdl; @@ -766,7 +759,7 @@ return -EFAULT; } - return mptctl_do_fw_download(kfwdl.iocnum, kfwdl.bufp, kfwdl.fwlen); + return mptctl_do_fw_download(iocp, kfwdl.bufp, kfwdl.fwlen); } /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -784,11 +777,10 @@ * -ENOMSG if FW upload returned bad status */ static int -mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) +mptctl_do_fw_download(MPT_ADAPTER *iocp, char __user *ufwbuf, size_t fwlen) { FWDownload_t *dlmsg; MPT_FRAME_HDR *mf; - MPT_ADAPTER *iocp; FWDownloadTCSGE_t *ptsge; MptSge_t *sgl, *sgIn; char *sgOut; @@ -808,17 +800,10 @@ pFWDownloadReply_t ReplyMsg = NULL; unsigned long timeleft; - if (mpt_verify_adapter(ioc, &iocp) < 0) { - printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n", - ioc); - return -ENODEV; /* (-6) No such device or address */ - } else { - - /* Valid device. Get a message frame and construct the FW download message. - */ - if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) - return -EAGAIN; - } + /* Valid device. Get a message frame and construct the FW download message. + */ + if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) + return -EAGAIN; dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id)); @@ -826,8 +811,6 @@ iocp->name, ufwbuf)); dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n", iocp->name, (int)fwlen)); - dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc = %04xh\n", - iocp->name, ioc)); dlmsg = (FWDownload_t*) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; @@ -1238,13 +1221,11 @@ * -ENODEV if no such device/adapter */ static int -mptctl_getiocinfo (unsigned long arg, unsigned int data_size) +mptctl_getiocinfo (MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size) { struct mpt_ioctl_iocinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_iocinfo *karg; - MPT_ADAPTER *ioc; struct pci_dev *pdev; - int iocnum; unsigned int port; int cim_rev; struct scsi_device *sdev; @@ -1272,14 +1253,6 @@ return PTR_ERR(karg); } - if (((iocnum = mpt_verify_adapter(karg->hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_getiocinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - kfree(karg); - return -ENODEV; - } - /* Verify the data transfer size is correct. */ if (karg->hdr.maxDataSize != data_size) { printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_getiocinfo - " @@ -1385,15 +1358,13 @@ * -ENODEV if no such device/adapter */ static int -mptctl_gettargetinfo (unsigned long arg) +mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg; struct mpt_ioctl_targetinfo karg; - MPT_ADAPTER *ioc; VirtDevice *vdevice; char *pmem; int *pdata; - int iocnum; int numDevices = 0; int lun; int maxWordsLeft; @@ -1408,13 +1379,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_gettargetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n", ioc->name)); /* Get the port number and set the maximum number of bytes @@ -1510,12 +1474,10 @@ * -ENODEV if no such device/adapter */ static int -mptctl_readtest (unsigned long arg) +mptctl_readtest (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_test __user *uarg = (void __user *) arg; struct mpt_ioctl_test karg; - MPT_ADAPTER *ioc; - int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_test))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_readtest - " @@ -1524,13 +1486,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_readtest() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_readtest called.\n", ioc->name)); /* Fill in the data and return the structure to the calling @@ -1571,12 +1526,10 @@ * -ENODEV if no such device/adapter */ static int -mptctl_eventquery (unsigned long arg) +mptctl_eventquery (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_eventquery __user *uarg = (void __user *) arg; struct mpt_ioctl_eventquery karg; - MPT_ADAPTER *ioc; - int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventquery))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventquery - " @@ -1585,13 +1538,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventquery() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventquery called.\n", ioc->name)); karg.eventEntries = MPTCTL_EVENT_LOG_SIZE; @@ -1610,12 +1556,10 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventenable (unsigned long arg) +mptctl_eventenable (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_eventenable __user *uarg = (void __user *) arg; struct mpt_ioctl_eventenable karg; - MPT_ADAPTER *ioc; - int iocnum; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventenable))) { printk(KERN_ERR MYNAM "%s@%d::mptctl_eventenable - " @@ -1624,13 +1568,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventenable() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventenable called.\n", ioc->name)); if (ioc->events == NULL) { @@ -1658,12 +1595,10 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_eventreport (unsigned long arg) +mptctl_eventreport (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_eventreport __user *uarg = (void __user *) arg; struct mpt_ioctl_eventreport karg; - MPT_ADAPTER *ioc; - int iocnum; int numBytes, maxEvents, max; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_eventreport))) { @@ -1673,12 +1608,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_eventreport() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_eventreport called.\n", ioc->name)); @@ -1712,12 +1641,10 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static int -mptctl_replace_fw (unsigned long arg) +mptctl_replace_fw (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_replace_fw __user *uarg = (void __user *) arg; struct mpt_ioctl_replace_fw karg; - MPT_ADAPTER *ioc; - int iocnum; int newFwSize; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_replace_fw))) { @@ -1727,13 +1654,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_replace_fw() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_replace_fw called.\n", ioc->name)); /* If caching FW, Free the old FW image @@ -1780,12 +1700,10 @@ * -ENOMEM if memory allocation error */ static int -mptctl_mpt_command (unsigned long arg) +mptctl_mpt_command (MPT_ADAPTER *ioc, unsigned long arg) { struct mpt_ioctl_command __user *uarg = (void __user *) arg; struct mpt_ioctl_command karg; - MPT_ADAPTER *ioc; - int iocnum; int rc; @@ -1796,14 +1714,7 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - - rc = mptctl_do_mpt_command (karg, &uarg->MF); + rc = mptctl_do_mpt_command (ioc, karg, &uarg->MF); return rc; } @@ -1821,9 +1732,8 @@ * -EPERM if SCSI I/O and target is untagged */ static int -mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) +mptctl_do_mpt_command (MPT_ADAPTER *ioc, struct mpt_ioctl_command karg, void __user *mfPtr) { - MPT_ADAPTER *ioc; MPT_FRAME_HDR *mf = NULL; MPIHeader_t *hdr; char *psge; @@ -1832,7 +1742,7 @@ dma_addr_t dma_addr_in; dma_addr_t dma_addr_out; int sgSize = 0; /* Num SG elements */ - int iocnum, flagsLength; + int flagsLength; int sz, rc = 0; int msgContext; u16 req_idx; @@ -1847,13 +1757,6 @@ bufIn.kptr = bufOut.kptr = NULL; bufIn.len = bufOut.len = 0; - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } - spin_lock_irqsave(&ioc->taskmgmt_lock, flags); if (ioc->ioc_reset_in_progress) { spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); @@ -2418,17 +2321,15 @@ * -ENOMEM if memory allocation error */ static int -mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) +mptctl_hp_hostinfo(MPT_ADAPTER *ioc, unsigned long arg, unsigned int data_size) { hp_host_info_t __user *uarg = (void __user *) arg; - MPT_ADAPTER *ioc; struct pci_dev *pdev; char *pbuf=NULL; dma_addr_t buf_dma; hp_host_info_t karg; CONFIGPARMS cfg; ConfigPageHeader_t hdr; - int iocnum; int rc, cim_rev; ToolboxIstwiReadWriteRequest_t *IstwiRWRequest; MPT_FRAME_HDR *mf = NULL; @@ -2452,12 +2353,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_hostinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": mptctl_hp_hostinfo called.\n", ioc->name)); @@ -2659,15 +2554,13 @@ * -ENOMEM if memory allocation error */ static int -mptctl_hp_targetinfo(unsigned long arg) +mptctl_hp_targetinfo(MPT_ADAPTER *ioc, unsigned long arg) { hp_target_info_t __user *uarg = (void __user *) arg; SCSIDevicePage0_t *pg0_alloc; SCSIDevicePage3_t *pg3_alloc; - MPT_ADAPTER *ioc; MPT_SCSI_HOST *hd = NULL; hp_target_info_t karg; - int iocnum; int data_sz; dma_addr_t page_dma; CONFIGPARMS cfg; @@ -2681,12 +2574,6 @@ return -EFAULT; } - if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || - (ioc == NULL)) { - printk(KERN_DEBUG MYNAM "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", - __FILE__, __LINE__, iocnum); - return -ENODEV; - } if (karg.hdr.id >= MPT_MAX_FC_DEVICES) return -EINVAL; dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_hp_targetinfo called.\n", @@ -2854,7 +2741,7 @@ kfw.fwlen = kfw32.fwlen; kfw.bufp = compat_ptr(kfw32.bufp); - ret = mptctl_do_fw_download(kfw.iocnum, kfw.bufp, kfw.fwlen); + ret = mptctl_do_fw_download(iocp, kfw.bufp, kfw.fwlen); mutex_unlock(&iocp->ioctl_cmds.mutex); @@ -2908,7 +2795,7 @@ /* Pass new structure to do_mpt_command */ - ret = mptctl_do_mpt_command (karg, &uarg->MF); + ret = mptctl_do_mpt_command (iocp, karg, &uarg->MF); mutex_unlock(&iocp->ioctl_cmds.mutex); --- linux-oracle-5.4.0.orig/drivers/message/fusion/mptlan.c +++ linux-oracle-5.4.0/drivers/message/fusion/mptlan.c @@ -1430,7 +1430,9 @@ { MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct net_device *dev = ioc->netdev; + struct mpt_lan_priv *priv = netdev_priv(dev); + cancel_delayed_work_sync(&priv->post_buckets_task); if(dev != NULL) { unregister_netdev(dev); free_netdev(dev); --- linux-oracle-5.4.0.orig/drivers/message/fusion/mptsas.c +++ linux-oracle-5.4.0/drivers/message/fusion/mptsas.c @@ -4205,10 +4205,8 @@ static void mptsas_reprobe_lun(struct scsi_device *sdev, void *data) { - int rc; - sdev->no_uld_attach = data ? 1 : 0; - rc = scsi_device_reprobe(sdev); + WARN_ON(scsi_device_reprobe(sdev)); } static void --- linux-oracle-5.4.0.orig/drivers/message/fusion/mptscsih.c +++ linux-oracle-5.4.0/drivers/message/fusion/mptscsih.c @@ -118,8 +118,6 @@ int mptscsih_resume(struct pci_dev *pdev); #endif -#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -1178,8 +1176,10 @@ MPT_SCSI_HOST *hd; int sz1; - if((hd = shost_priv(host)) == NULL) - return; + if (host == NULL) + hd = NULL; + else + hd = shost_priv(host); mptscsih_shutdown(pdev); @@ -1195,14 +1195,15 @@ "Free'd ScsiLookup (%d) memory\n", ioc->name, sz1)); - kfree(hd->info_kbuf); + if (hd) + kfree(hd->info_kbuf); /* NULL the Scsi_Host pointer */ ioc->sh = NULL; - scsi_host_put(host); - + if (host) + scsi_host_put(host); mpt_detach(pdev); } @@ -2422,7 +2423,7 @@ /* Copy the sense received into the scsi command block. */ req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); - memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); + memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC); /* Log SMART data (asc = 0x5D, non-IM case only) if required. */ --- linux-oracle-5.4.0.orig/drivers/mfd/Kconfig +++ linux-oracle-5.4.0/drivers/mfd/Kconfig @@ -758,6 +758,7 @@ depends on OF || COMPILE_TEST select MFD_CORE select REGMAP_I2C + select REGMAP_IRQ help Say Y here to add support for Maxim Semiconductor MAX77650 and MAX77651 Power Management ICs. This is the core multifunction @@ -1298,6 +1299,7 @@ config MFD_TI_AM335X_TSCADC tristate "TI ADC / Touch Screen chip support" + depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST select MFD_CORE select REGMAP select REGMAP_MMIO @@ -2011,5 +2013,16 @@ Select this to get support for the Supervisory Processor device found on several devices in RAVE line of hardware. +config MFD_AHC1EC0 + tristate "Advantech AHC1EC0 Embedded Controller Module" + depends on X86 + depends on UBUNTU_ODM_DRIVERS + select MFD_CORE + help + This is the core function that for Advantech EC drivers. It + includes the sub-devices such as hwmon, watchdog, etc. And also + provides expose functions for sub-devices to read/write the value + to embedded controller. + endmenu endif --- linux-oracle-5.4.0.orig/drivers/mfd/Makefile +++ linux-oracle-5.4.0/drivers/mfd/Makefile @@ -256,3 +256,5 @@ obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o +obj-$(CONFIG_MFD_AHC1EC0) += ahc1ec0.o + --- linux-oracle-5.4.0.orig/drivers/mfd/ab8500-core.c +++ linux-oracle-5.4.0/drivers/mfd/ab8500-core.c @@ -493,7 +493,7 @@ if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F) line += 1; - handle_nested_irq(irq_create_mapping(ab8500->domain, line)); + handle_nested_irq(irq_find_mapping(ab8500->domain, line)); } return 0; --- linux-oracle-5.4.0.orig/drivers/mfd/ahc1ec0.c +++ linux-oracle-5.4.0/drivers/mfd/ahc1ec0.c @@ -0,0 +1,808 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Advantech embedded controller core driver AHC1EC0 + * + * Copyright 2020 Advantech IIoT Group + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "ahc1ec0" + +enum { + ADVEC_SUBDEV_BRIGHTNESS = 0, + ADVEC_SUBDEV_EEPROM, + ADVEC_SUBDEV_GPIO, + ADVEC_SUBDEV_HWMON, + ADVEC_SUBDEV_LED, + ADVEC_SUBDEV_WDT, + ADVEC_SUBDEV_MAX, +}; + +/* Wait IBF (Input Buffer Full) clear */ +static int ec_wait_write(void) +{ + int i; + + for (i = 0; i < EC_MAX_TIMEOUT_COUNT; i++) { + if ((inb(EC_COMMAND_PORT) & EC_COMMAND_BIT_IBF) == 0) + return 0; + + udelay(EC_RETRY_UDELAY); + } + + return -ETIMEDOUT; +} + +/* Wait OBF (Output Buffer Full) data ready */ +static int ec_wait_read(void) +{ + int i; + + for (i = 0; i < EC_MAX_TIMEOUT_COUNT; i++) { + if ((inb(EC_COMMAND_PORT) & EC_COMMAND_BIT_OBF) != 0) + return 0; + + udelay(EC_RETRY_UDELAY); + } + + return -ETIMEDOUT; +} + +/* Read data from EC HW RAM, the process is the following: + * Step 0. Wait IBF clear to send command + * Step 1. Send read command to EC command port + * Step 2. Wait IBF clear that means command is got by EC + * Step 3. Send read address to EC data port + * Step 4. Wait OBF data ready + * Step 5. Get data from EC data port + */ +int read_hw_ram(struct adv_ec_platform_data *adv_ec_data, unsigned char addr, unsigned char *data) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_HW_RAM_READ, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(addr, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + *data = inb(EC_STATUS_PORT); + + mutex_unlock(&adv_ec_data->lock); + + return ret; + +error: + mutex_unlock(&adv_ec_data->lock); + dev_err(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} + +/* Write data to EC HW RAM + * Step 0. Wait IBF clear to send command + * Step 1. Send write command to EC command port + * Step 2. Wait IBF clear that means command is got by EC + * Step 3. Send write address to EC data port + * Step 4. Wait IBF clear that means command is got by EC + * Step 5. Send data to EC data port + */ +int write_hw_ram(struct adv_ec_platform_data *adv_ec_data, unsigned char addr, unsigned char data) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_HW_RAM_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(addr, EC_STATUS_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(data, EC_STATUS_PORT); + + mutex_unlock(&adv_ec_data->lock); + + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_err(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} +EXPORT_SYMBOL_GPL(write_hw_ram); + +/* Get dynamic control table */ +static int adv_get_dynamic_tab(struct adv_ec_platform_data *adv_ec_data) +{ + int i, ret; + unsigned char pin_tmp, device_id; + + mutex_lock(&adv_ec_data->lock); + + for (i = 0; i < EC_MAX_TBL_NUM; i++) { + adv_ec_data->dym_tbl[i].device_id = 0xff; + adv_ec_data->dym_tbl[i].hw_pin_num = 0xff; + } + + for (i = 0; i < EC_MAX_TBL_NUM; i++) { + ret = ec_wait_write(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_write. line: %d\n", __func__, + __LINE__); + goto error; + } + outb(EC_TBL_WRITE_ITEM, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_write. line: %d\n", __func__, + __LINE__); + goto error; + } + outb(i, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_read. line: %d\n", __func__, + __LINE__); + goto error; + } + + /* + * If item is defined, EC will return item number. + * If table item is not defined, EC will return 0xFF. + */ + pin_tmp = inb(EC_STATUS_PORT); + if (pin_tmp == 0xff) { + dev_dbg(adv_ec_data->dev, "%s: inb(EC_STATUS_PORT)=0x%02x != 0xff.\n", + __func__, pin_tmp); + goto pass; + } + + ret = ec_wait_write(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_write. line: %d\n", __func__, + __LINE__); + goto error; + } + outb(EC_TBL_GET_PIN, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_read. line: %d\n", __func__, + __LINE__); + goto error; + } + pin_tmp = inb(EC_STATUS_PORT) & 0xff; + if (pin_tmp == 0xff) { + dev_dbg(adv_ec_data->dev, "%s: pin_tmp(0x%02X). line: %d\n", __func__, + pin_tmp, __LINE__); + goto pass; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_TBL_GET_DEVID, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) { + dev_dbg(adv_ec_data->dev, "%s: ec_wait_read. line: %d\n", __func__, + __LINE__); + goto error; + } + device_id = inb(EC_STATUS_PORT) & 0xff; + + dev_dbg(adv_ec_data->dev, "%s: device_id=0x%02X. line: %d\n", __func__, + device_id, __LINE__); + + adv_ec_data->dym_tbl[i].device_id = device_id; + adv_ec_data->dym_tbl[i].hw_pin_num = pin_tmp; + } + +pass: + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + dev_err(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", + __func__, __LINE__); + return ret; +} + +int read_ad_value(struct adv_ec_platform_data *adv_ec_data, unsigned char hwpin, + unsigned char multi) +{ + int ret; + u32 ret_val; + unsigned int LSB, MSB; + + mutex_lock(&adv_ec_data->lock); + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_AD_INDEX_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(hwpin, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + + if (inb(EC_STATUS_PORT) == 0xff) { + mutex_unlock(&adv_ec_data->lock); + return -1; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_AD_LSB_READ, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + LSB = inb(EC_STATUS_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_AD_MSB_READ, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + MSB = inb(EC_STATUS_PORT); + ret_val = ((MSB << 8) | LSB) & 0x03FF; + ret_val = ret_val * multi * 100; + + mutex_unlock(&adv_ec_data->lock); + return ret_val; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} +EXPORT_SYMBOL_GPL(read_ad_value); + +int read_acpi_value(struct adv_ec_platform_data *adv_ec_data, unsigned char addr, + unsigned char *pvalue) +{ + int ret; + unsigned char value; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_ACPI_RAM_READ, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(addr, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + value = inb(EC_STATUS_PORT); + *pvalue = value; + + mutex_unlock(&adv_ec_data->lock); + + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} +EXPORT_SYMBOL_GPL(read_acpi_value); + +int write_acpi_value(struct adv_ec_platform_data *adv_ec_data, unsigned char addr, + unsigned char value) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_ACPI_DATA_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(addr, EC_STATUS_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(value, EC_STATUS_PORT); + + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} + +int read_gpio_status(struct adv_ec_platform_data *adv_ec_data, unsigned char PinNumber, + unsigned char *pvalue) +{ + int ret; + + unsigned char gpio_status_value; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_INDEX_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(PinNumber, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + + if (inb(EC_STATUS_PORT) == 0xff) { + dev_err(adv_ec_data->dev, "%s: Read Pin Number error!!\n", __func__); + mutex_unlock(&adv_ec_data->lock); + return -1; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_STATUS_READ, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + gpio_status_value = inb(EC_STATUS_PORT); + + *pvalue = gpio_status_value; + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + return ret; +} + +int write_gpio_status(struct adv_ec_platform_data *adv_ec_data, unsigned char PinNumber, + unsigned char value) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_INDEX_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(PinNumber, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + + if (inb(EC_STATUS_PORT) == 0xff) { + mutex_unlock(&adv_ec_data->lock); + dev_err(adv_ec_data->dev, "%s: Read Pin Number error!!\n", __func__); + return -1; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_STATUS_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(value, EC_STATUS_PORT); + + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + dev_err(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d", __func__, + __LINE__); + + return ret; +} + +int read_gpio_dir(struct adv_ec_platform_data *adv_ec_data, unsigned char PinNumber, + unsigned char *pvalue) +{ + int ret; + unsigned char gpio_dir_value; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_INDEX_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(PinNumber, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + + if (inb(EC_STATUS_PORT) == 0xff) { + mutex_unlock(&adv_ec_data->lock); + dev_err(adv_ec_data->dev, "%s: Read Pin Number error!! line: %d\n", __func__, + __LINE__); + return -1; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_DIR_READ, EC_COMMAND_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + gpio_dir_value = inb(EC_STATUS_PORT); + *pvalue = gpio_dir_value; + + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} + +int write_gpio_dir(struct adv_ec_platform_data *adv_ec_data, unsigned char PinNumber, + unsigned char value) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_INDEX_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(PinNumber, EC_STATUS_PORT); + + ret = ec_wait_read(); + if (ret) + goto error; + + if (inb(EC_STATUS_PORT) == 0xff) { + mutex_unlock(&adv_ec_data->lock); + dev_warn(adv_ec_data->dev, "%s: Read Pin Number error!! line: %d\n", __func__, + __LINE__); + + return -1; + } + + ret = ec_wait_write(); + if (ret) + goto error; + outb(EC_GPIO_DIR_WRITE, EC_COMMAND_PORT); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(value, EC_STATUS_PORT); + + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} + +int write_hwram_command(struct adv_ec_platform_data *adv_ec_data, unsigned char data) +{ + int ret; + + mutex_lock(&adv_ec_data->lock); + + ret = ec_wait_write(); + if (ret) + goto error; + outb(data, EC_COMMAND_PORT); + + mutex_unlock(&adv_ec_data->lock); + return 0; + +error: + mutex_unlock(&adv_ec_data->lock); + + dev_warn(adv_ec_data->dev, "%s: Wait for IBF or OBF too long. line: %d\n", __func__, + __LINE__); + + return ret; +} +EXPORT_SYMBOL_GPL(write_hwram_command); + +static int adv_ec_get_productname(struct adv_ec_platform_data *adv_ec_data, char *product) +{ + const char *vendor, *device; + int length = 0; + + /* Check it is Advantech board */ + vendor = dmi_get_system_info(DMI_SYS_VENDOR); + if (memcmp(vendor, "Advantech", sizeof("Advantech")) != 0) + return -ENODEV; + + /* Get product model name */ + device = dmi_get_system_info(DMI_PRODUCT_NAME); + if (device) { + while ((device[length] != ' ') + && (length < AMI_ADVANTECH_BOARD_ID_LENGTH)) + length++; + memset(product, 0, AMI_ADVANTECH_BOARD_ID_LENGTH); + memmove(product, device, length); + + dev_info(adv_ec_data->dev, "BIOS Product Name = %s\n", product); + + return 0; + } + + dev_warn(adv_ec_data->dev, "This device is not Advantech Board (%s)!\n", product); + + return -ENODEV; +} + +static const struct mfd_cell adv_ec_sub_cells[] = { + { .name = "adv-ec-brightness", }, + { .name = "adv-ec-eeprom", }, + { .name = "adv-ec-gpio", }, + { .name = "ahc1ec0-hwmon", }, + { .name = "adv-ec-led", }, + { .name = "ahc1ec0-wdt", }, +}; + +static int adv_ec_init_ec_data(struct adv_ec_platform_data *adv_ec_data) +{ + int ret; + + adv_ec_data->sub_dev_mask = 0; + adv_ec_data->sub_dev_nb = 0; + adv_ec_data->dym_tbl = NULL; + adv_ec_data->bios_product_name = NULL; + + mutex_init(&adv_ec_data->lock); + + /* Get product name */ + adv_ec_data->bios_product_name = + devm_kzalloc(adv_ec_data->dev, AMI_ADVANTECH_BOARD_ID_LENGTH, GFP_KERNEL); + if (!adv_ec_data->bios_product_name) + return -ENOMEM; + + memset(adv_ec_data->bios_product_name, 0, AMI_ADVANTECH_BOARD_ID_LENGTH); + ret = adv_ec_get_productname(adv_ec_data, adv_ec_data->bios_product_name); + if (ret) + return ret; + + /* Get pin table */ + adv_ec_data->dym_tbl = devm_kzalloc(adv_ec_data->dev, + EC_MAX_TBL_NUM * sizeof(struct ec_dynamic_table), + GFP_KERNEL); + if (!adv_ec_data->dym_tbl) + return -ENOMEM; + + ret = adv_get_dynamic_tab(adv_ec_data); + + return ret; +} + +static int adv_ec_parse_prop(struct adv_ec_platform_data *adv_ec_data) +{ + int i, ret; + u32 nb, sub_dev[ADVEC_SUBDEV_MAX]; + + ret = device_property_read_u32(adv_ec_data->dev, "advantech,sub-dev-nb", &nb); + if (ret < 0) { + dev_err(adv_ec_data->dev, "get sub-dev-nb failed! (%d)\n", ret); + return ret; + } + adv_ec_data->sub_dev_nb = nb; + + ret = device_property_read_u32_array(adv_ec_data->dev, "advantech,sub-dev", + sub_dev, nb); + if (ret < 0) { + dev_err(adv_ec_data->dev, "get sub-dev failed! (%d)\n", ret); + return ret; + } + + for (i = 0; i < nb; i++) { + switch (sub_dev[i]) { + case ADVEC_SUBDEV_BRIGHTNESS: + case ADVEC_SUBDEV_EEPROM: + case ADVEC_SUBDEV_GPIO: + case ADVEC_SUBDEV_HWMON: + case ADVEC_SUBDEV_LED: + case ADVEC_SUBDEV_WDT: + adv_ec_data->sub_dev_mask |= BIT(sub_dev[i]); + break; + default: + dev_err(adv_ec_data->dev, "invalid prop value(%d)!\n", + sub_dev[i]); + } + } + dev_info(adv_ec_data->dev, "sub-dev mask = 0x%x\n", adv_ec_data->sub_dev_mask); + + return 0; +} + +static int adv_ec_probe(struct platform_device *pdev) +{ + int ret, i; + struct device *dev = &pdev->dev; + struct adv_ec_platform_data *adv_ec_data; + + adv_ec_data = devm_kzalloc(dev, sizeof(struct adv_ec_platform_data), GFP_KERNEL); + if (!adv_ec_data) + return -ENOMEM; + + dev_set_drvdata(dev, adv_ec_data); + adv_ec_data->dev = dev; + + ret = adv_ec_init_ec_data(adv_ec_data); + if (ret) + goto err_init_data; + + ret = adv_ec_parse_prop(adv_ec_data); + if (ret) + goto err_prop; + + /* check whether this EC has the following subdevices. */ + for (i = 0; i < ARRAY_SIZE(adv_ec_sub_cells); i++) { + if (adv_ec_data->sub_dev_mask & BIT(i)) { + ret = mfd_add_hotplug_devices(dev, &adv_ec_sub_cells[i], 1); + dev_info(adv_ec_data->dev, "mfd_add_hotplug_devices[%d] %s\n", i, + adv_ec_sub_cells[i].name); + if (ret) + dev_err(dev, "failed to add %s subdevice: %d\n", + adv_ec_sub_cells[i].name, ret); + } + } + + dev_info(adv_ec_data->dev, "Advantech EC probe done"); + + return 0; + +err_prop: + dev_err(dev, "failed to probe\n"); + +err_init_data: + mutex_destroy(&adv_ec_data->lock); + + dev_err(dev, "failed to init data\n"); + + return ret; +} + +static int adv_ec_remove(struct platform_device *pdev) +{ + struct adv_ec_platform_data *adv_ec_data; + + adv_ec_data = dev_get_drvdata(&pdev->dev); + + mutex_destroy(&adv_ec_data->lock); + + mfd_remove_devices(&pdev->dev); + + return 0; +} + +static const struct of_device_id adv_ec_of_match[] __maybe_unused = { + { + .compatible = "advantech,ahc1ec0", + }, + {} +}; +MODULE_DEVICE_TABLE(of, adv_ec_of_match); + +static const struct acpi_device_id adv_ec_acpi_match[] __maybe_unused = { + {"AHC1EC0", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, adv_ec_acpi_match); + +static struct platform_driver adv_ec_driver = { + .driver = { + .name = DRV_NAME, + .of_match_table = of_match_ptr(adv_ec_of_match), + .acpi_match_table = ACPI_PTR(adv_ec_acpi_match), + }, + .probe = adv_ec_probe, + .remove = adv_ec_remove, +}; +module_platform_driver(adv_ec_driver); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DESCRIPTION("Advantech Embedded Controller core driver."); +MODULE_AUTHOR("Campion Kang "); +MODULE_AUTHOR("Jianfeng Dai "); +MODULE_VERSION("1.0"); --- linux-oracle-5.4.0.orig/drivers/mfd/altera-sysmgr.c +++ linux-oracle-5.4.0/drivers/mfd/altera-sysmgr.c @@ -109,7 +109,9 @@ dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver, (void *)sysmgr_np); - of_node_put(sysmgr_np); + if (property) + of_node_put(sysmgr_np); + if (!dev) return ERR_PTR(-EPROBE_DEFER); --- linux-oracle-5.4.0.orig/drivers/mfd/arizona-core.c +++ linux-oracle-5.4.0/drivers/mfd/arizona-core.c @@ -45,7 +45,7 @@ if (arizona->clk32k_ref == 1) { switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: - ret = pm_runtime_get_sync(arizona->dev); + ret = pm_runtime_resume_and_get(arizona->dev); if (ret != 0) goto err_ref; ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]); @@ -1430,6 +1430,15 @@ arizona_irq_exit(arizona); err_pm: pm_runtime_disable(arizona->dev); + + switch (arizona->pdata.clk32k_src) { + case ARIZONA_32KZ_MCLK1: + case ARIZONA_32KZ_MCLK2: + arizona_clk32k_disable(arizona); + break; + default: + break; + } err_reset: arizona_enable_reset(arizona); regulator_disable(arizona->dcvdd); @@ -1452,6 +1461,15 @@ regulator_disable(arizona->dcvdd); regulator_put(arizona->dcvdd); + switch (arizona->pdata.clk32k_src) { + case ARIZONA_32KZ_MCLK1: + case ARIZONA_32KZ_MCLK2: + arizona_clk32k_disable(arizona); + break; + default: + break; + } + mfd_remove_devices(arizona->dev); arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona); arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona); --- linux-oracle-5.4.0.orig/drivers/mfd/arizona-irq.c +++ linux-oracle-5.4.0/drivers/mfd/arizona-irq.c @@ -100,7 +100,7 @@ unsigned int val; int ret; - ret = pm_runtime_get_sync(arizona->dev); + ret = pm_runtime_resume_and_get(arizona->dev); if (ret < 0) { dev_err(arizona->dev, "Failed to resume device: %d\n", ret); return IRQ_NONE; --- linux-oracle-5.4.0.orig/drivers/mfd/asic3.c +++ linux-oracle-5.4.0/drivers/mfd/asic3.c @@ -914,14 +914,14 @@ ret = mfd_add_devices(&pdev->dev, pdev->id, &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); if (ret < 0) - goto out; + goto out_unmap; } if (mem_sdio && (irq >= 0)) { ret = mfd_add_devices(&pdev->dev, pdev->id, &asic3_cell_mmc, 1, mem_sdio, irq, NULL); if (ret < 0) - goto out; + goto out_unmap; } ret = 0; @@ -935,8 +935,12 @@ ret = mfd_add_devices(&pdev->dev, 0, asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); } + return ret; - out: +out_unmap: + if (asic->tmio_cnf) + iounmap(asic->tmio_cnf); +out: return ret; } --- linux-oracle-5.4.0.orig/drivers/mfd/axp20x.c +++ linux-oracle-5.4.0/drivers/mfd/axp20x.c @@ -125,12 +125,13 @@ static const struct regmap_range axp288_volatile_ranges[] = { regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON), + regmap_reg_range(AXP22X_PWR_OUT_CTRL1, AXP22X_ALDO3_V_OUT), regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), - regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT), + regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT), regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL), regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), - regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), + regmap_reg_range(AXP20X_GPIO1_CTRL, AXP22X_GPIO_STATE), regmap_reg_range(AXP288_RT_BATT_V_H, AXP288_RT_BATT_V_L), regmap_reg_range(AXP20X_FG_RES, AXP288_FG_CC_CAP_REG), }; --- linux-oracle-5.4.0.orig/drivers/mfd/bd9571mwv.c +++ linux-oracle-5.4.0/drivers/mfd/bd9571mwv.c @@ -185,9 +185,9 @@ return ret; } - ret = mfd_add_devices(bd->dev, PLATFORM_DEVID_AUTO, bd9571mwv_cells, - ARRAY_SIZE(bd9571mwv_cells), NULL, 0, - regmap_irq_get_domain(bd->irq_data)); + ret = devm_mfd_add_devices(bd->dev, PLATFORM_DEVID_AUTO, + bd9571mwv_cells, ARRAY_SIZE(bd9571mwv_cells), + NULL, 0, regmap_irq_get_domain(bd->irq_data)); if (ret) { regmap_del_irq_chip(bd->irq, bd->irq_data); return ret; --- linux-oracle-5.4.0.orig/drivers/mfd/da9052-i2c.c +++ linux-oracle-5.4.0/drivers/mfd/da9052-i2c.c @@ -113,6 +113,7 @@ {"da9053-bc", DA9053_BC}, {} }; +MODULE_DEVICE_TABLE(i2c, da9052_i2c_id); #ifdef CONFIG_OF static const struct of_device_id dialog_dt_ids[] = { --- linux-oracle-5.4.0.orig/drivers/mfd/da9052-spi.c +++ linux-oracle-5.4.0/drivers/mfd/da9052-spi.c @@ -37,7 +37,7 @@ spi_set_drvdata(spi, da9052); config = da9052_regmap_config; - config.read_flag_mask = 1; + config.write_flag_mask = 1; config.reg_bits = 7; config.pad_bits = 1; config.val_bits = 8; --- linux-oracle-5.4.0.orig/drivers/mfd/da9062-core.c +++ linux-oracle-5.4.0/drivers/mfd/da9062-core.c @@ -248,7 +248,7 @@ .name = "da9062-watchdog", .num_resources = ARRAY_SIZE(da9062_wdt_resources), .resources = da9062_wdt_resources, - .of_compatible = "dlg,da9062-wdt", + .of_compatible = "dlg,da9062-watchdog", }, { .name = "da9062-thermal", --- linux-oracle-5.4.0.orig/drivers/mfd/davinci_voicecodec.c +++ linux-oracle-5.4.0/drivers/mfd/davinci_voicecodec.c @@ -46,14 +46,12 @@ } clk_enable(davinci_vc->clk); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - fifo_base = (dma_addr_t)res->start; - davinci_vc->base = devm_ioremap_resource(&pdev->dev, res); + davinci_vc->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(davinci_vc->base)) { ret = PTR_ERR(davinci_vc->base); goto fail; } + fifo_base = (dma_addr_t)res->start; davinci_vc->regmap = devm_regmap_init_mmio(&pdev->dev, davinci_vc->base, --- linux-oracle-5.4.0.orig/drivers/mfd/db8500-prcmu.c +++ linux-oracle-5.4.0/drivers/mfd/db8500-prcmu.c @@ -1695,22 +1695,20 @@ } static const unsigned long db8500_armss_freqs[] = { - 200000000, - 400000000, - 800000000, + 199680000, + 399360000, + 798720000, 998400000 }; /* The DB8520 has slightly higher ARMSS max frequency */ static const unsigned long db8520_armss_freqs[] = { - 200000000, - 400000000, - 800000000, + 199680000, + 399360000, + 798720000, 1152000000 }; - - static long round_armss_rate(unsigned long rate) { unsigned long freq = 0; --- linux-oracle-5.4.0.orig/drivers/mfd/dln2.c +++ linux-oracle-5.4.0/drivers/mfd/dln2.c @@ -90,6 +90,11 @@ spinlock_t lock; }; +enum dln2_endpoint { + DLN2_EP_OUT = 0, + DLN2_EP_IN = 1, +}; + struct dln2_dev { struct usb_device *usb_dev; struct usb_interface *interface; @@ -282,7 +287,11 @@ len = urb->actual_length - sizeof(struct dln2_header); if (handle == DLN2_HANDLE_EVENT) { + unsigned long flags; + + spin_lock_irqsave(&dln2->event_cb_lock, flags); dln2_run_event_callbacks(dln2, id, echo, data, len); + spin_unlock_irqrestore(&dln2->event_cb_lock, flags); } else { /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */ if (dln2_transfer_complete(dln2, urb, handle, echo)) @@ -722,6 +731,8 @@ const struct usb_device_id *usb_id) { struct usb_host_interface *hostif = interface->cur_altsetting; + struct usb_endpoint_descriptor *epin; + struct usb_endpoint_descriptor *epout; struct device *dev = &interface->dev; struct dln2_dev *dln2; int ret; @@ -731,12 +742,19 @@ hostif->desc.bNumEndpoints < 2) return -ENODEV; + epout = &hostif->endpoint[DLN2_EP_OUT].desc; + if (!usb_endpoint_is_bulk_out(epout)) + return -ENODEV; + epin = &hostif->endpoint[DLN2_EP_IN].desc; + if (!usb_endpoint_is_bulk_in(epin)) + return -ENODEV; + dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL); if (!dln2) return -ENOMEM; - dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress; - dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress; + dln2->ep_out = epout->bEndpointAddress; + dln2->ep_in = epin->bEndpointAddress; dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface)); dln2->interface = interface; usb_set_intfdata(interface, dln2); --- linux-oracle-5.4.0.orig/drivers/mfd/fsl-imx25-tsadc.c +++ linux-oracle-5.4.0/drivers/mfd/fsl-imx25-tsadc.c @@ -69,7 +69,7 @@ int irq; irq = platform_get_irq(pdev, 0); - if (irq <= 0) + if (irq < 0) return irq; tsadc->domain = irq_domain_add_simple(np, 2, 0, &mx25_tsadc_domain_ops, @@ -84,6 +84,19 @@ return 0; } +static int mx25_tsadc_unset_irq(struct platform_device *pdev) +{ + struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); + int irq = platform_get_irq(pdev, 0); + + if (irq >= 0) { + irq_set_chained_handler_and_data(irq, NULL, NULL); + irq_domain_remove(tsadc->domain); + } + + return 0; +} + static void mx25_tsadc_setup_clk(struct platform_device *pdev, struct mx25_tsadc *tsadc) { @@ -171,18 +184,21 @@ platform_set_drvdata(pdev, tsadc); - return devm_of_platform_populate(dev); + ret = devm_of_platform_populate(dev); + if (ret) + goto err_irq; + + return 0; + +err_irq: + mx25_tsadc_unset_irq(pdev); + + return ret; } static int mx25_tsadc_remove(struct platform_device *pdev) { - struct mx25_tsadc *tsadc = platform_get_drvdata(pdev); - int irq = platform_get_irq(pdev, 0); - - if (irq) { - irq_set_chained_handler_and_data(irq, NULL, NULL); - irq_domain_remove(tsadc->domain); - } + mx25_tsadc_unset_irq(pdev); return 0; } --- linux-oracle-5.4.0.orig/drivers/mfd/intel-lpss-acpi.c +++ linux-oracle-5.4.0/drivers/mfd/intel-lpss-acpi.c @@ -102,6 +102,7 @@ { struct intel_lpss_platform_info *info; const struct acpi_device_id *id; + int ret; id = acpi_match_device(intel_lpss_acpi_ids, &pdev->dev); if (!id) @@ -113,12 +114,19 @@ return -ENOMEM; info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!info->mem) + return -ENODEV; + info->irq = platform_get_irq(pdev, 0); + ret = intel_lpss_probe(&pdev->dev, info); + if (ret) + return ret; + pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); - return intel_lpss_probe(&pdev->dev, info); + return 0; } static int intel_lpss_acpi_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/mfd/intel-lpss-pci.c +++ linux-oracle-5.4.0/drivers/mfd/intel-lpss-pci.c @@ -122,13 +122,25 @@ .properties = apl_i2c_properties, }; +static struct property_entry glk_i2c_properties[] = { + PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 313), + PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), + PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 290), + { }, +}; + +static const struct intel_lpss_platform_info glk_i2c_info = { + .clk_rate = 133000000, + .properties = glk_i2c_properties, +}; + static const struct intel_lpss_platform_info cnl_i2c_info = { .clk_rate = 216000000, .properties = spt_i2c_properties, }; static const struct pci_device_id intel_lpss_pci_ids[] = { - /* CML */ + /* CML-LP */ { PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&spt_info }, @@ -141,6 +153,17 @@ { PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info }, { PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info }, { PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&spt_info }, + /* CML-H */ + { PCI_VDEVICE(INTEL, 0x06a8), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x06a9), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&spt_info }, + { PCI_VDEVICE(INTEL, 0x06c7), (kernel_ulong_t)&spt_uart_info }, + { PCI_VDEVICE(INTEL, 0x06e8), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x06e9), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x06ea), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x06eb), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&spt_info }, /* BXT A-Step */ { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info }, @@ -173,15 +196,18 @@ { PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info }, { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info }, + /* EBG */ + { PCI_VDEVICE(INTEL, 0x1bad), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x1bae), (kernel_ulong_t)&bxt_uart_info }, /* GLK */ - { PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31b0), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31b2), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31b4), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31b6), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31b8), (kernel_ulong_t)&bxt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x31ba), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31b0), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31b2), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31b4), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31b6), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31b8), (kernel_ulong_t)&glk_i2c_info }, + { PCI_VDEVICE(INTEL, 0x31ba), (kernel_ulong_t)&glk_i2c_info }, { PCI_VDEVICE(INTEL, 0x31bc), (kernel_ulong_t)&bxt_uart_info }, { PCI_VDEVICE(INTEL, 0x31be), (kernel_ulong_t)&bxt_uart_info }, { PCI_VDEVICE(INTEL, 0x31c0), (kernel_ulong_t)&bxt_uart_info }, @@ -202,6 +228,22 @@ { PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&spt_info }, + /* TGL-H */ + { PCI_VDEVICE(INTEL, 0x43a7), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x43a8), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x43a9), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x43ad), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43ae), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43d8), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43da), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x43e8), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43e9), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43ea), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43eb), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&bxt_info }, /* EHL */ { PCI_VDEVICE(INTEL, 0x4b28), (kernel_ulong_t)&bxt_uart_info }, { PCI_VDEVICE(INTEL, 0x4b29), (kernel_ulong_t)&bxt_uart_info }, --- linux-oracle-5.4.0.orig/drivers/mfd/intel-lpss.c +++ linux-oracle-5.4.0/drivers/mfd/intel-lpss.c @@ -384,7 +384,7 @@ if (!lpss) return -ENOMEM; - lpss->priv = devm_ioremap(dev, info->mem->start + LPSS_PRIV_OFFSET, + lpss->priv = devm_ioremap_uc(dev, info->mem->start + LPSS_PRIV_OFFSET, LPSS_PRIV_SIZE); if (!lpss->priv) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/mfd/intel_soc_pmic_bxtwc.c +++ linux-oracle-5.4.0/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -227,43 +227,54 @@ static struct mfd_cell bxt_wc_dev[] = { { - .name = "bxt_wcove_gpadc", - .num_resources = ARRAY_SIZE(adc_resources), - .resources = adc_resources, - }, - { .name = "bxt_wcove_thermal", .num_resources = ARRAY_SIZE(thermal_resources), .resources = thermal_resources, }, { - .name = "bxt_wcove_usbc", - .num_resources = ARRAY_SIZE(usbc_resources), - .resources = usbc_resources, + .name = "bxt_wcove_gpio", + .num_resources = ARRAY_SIZE(gpio_resources), + .resources = gpio_resources, }, { - .name = "bxt_wcove_ext_charger", - .num_resources = ARRAY_SIZE(charger_resources), - .resources = charger_resources, + .name = "bxt_wcove_region", }, +}; + +static const struct mfd_cell bxt_wc_tmu_dev[] = { + { + .name = "bxt_wcove_tmu", + .num_resources = ARRAY_SIZE(tmu_resources), + .resources = tmu_resources, + }, +}; + +static const struct mfd_cell bxt_wc_bcu_dev[] = { { .name = "bxt_wcove_bcu", .num_resources = ARRAY_SIZE(bcu_resources), .resources = bcu_resources, }, +}; + +static const struct mfd_cell bxt_wc_adc_dev[] = { { - .name = "bxt_wcove_tmu", - .num_resources = ARRAY_SIZE(tmu_resources), - .resources = tmu_resources, + .name = "bxt_wcove_gpadc", + .num_resources = ARRAY_SIZE(adc_resources), + .resources = adc_resources, }, +}; +static struct mfd_cell bxt_wc_chgr_dev[] = { { - .name = "bxt_wcove_gpio", - .num_resources = ARRAY_SIZE(gpio_resources), - .resources = gpio_resources, + .name = "bxt_wcove_usbc", + .num_resources = ARRAY_SIZE(usbc_resources), + .resources = usbc_resources, }, { - .name = "bxt_wcove_region", + .name = "bxt_wcove_ext_charger", + .num_resources = ARRAY_SIZE(charger_resources), + .resources = charger_resources, }, }; @@ -414,19 +425,37 @@ int irq; irq = regmap_irq_get_virq(pdata, pirq); - if (irq < 0) { - dev_err(pmic->dev, - "Failed to get parent vIRQ(%d) for chip %s, ret:%d\n", - pirq, chip->name, irq); - return irq; - } + if (irq < 0) + return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", + pirq, chip->name); return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags, 0, chip, data); } +static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic, + const struct mfd_cell *cells, int n_devs, + struct regmap_irq_chip_data *pdata, + int pirq, int irq_flags, + const struct regmap_irq_chip *chip, + struct regmap_irq_chip_data **data) +{ + struct device *dev = pmic->dev; + struct irq_domain *domain; + int ret; + + ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data); + if (ret) + return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name); + + domain = regmap_irq_get_domain(*data); + + return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain); +} + static int bxtwc_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; int ret; acpi_handle handle; acpi_status status; @@ -435,15 +464,10 @@ handle = ACPI_HANDLE(&pdev->dev); status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); - if (ACPI_FAILURE(status)) { - dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n"); - return -ENODEV; - } - if (hrv != BROXTON_PMIC_WC_HRV) { - dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n", - hrv); - return -ENODEV; - } + if (ACPI_FAILURE(status)) + return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n"); + if (hrv != BROXTON_PMIC_WC_HRV) + return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv); pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) @@ -459,79 +483,59 @@ pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic, &bxtwc_regmap_config); - if (IS_ERR(pmic->regmap)) { - ret = PTR_ERR(pmic->regmap); - dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret); - return ret; - } + if (IS_ERR(pmic->regmap)) + return dev_err_probe(dev, PTR_ERR(pmic->regmap), "Failed to initialise regmap\n"); ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq, IRQF_ONESHOT | IRQF_SHARED, 0, &bxtwc_regmap_irq_chip, &pmic->irq_chip_data); - if (ret) { - dev_err(&pdev->dev, "Failed to add IRQ chip\n"); + if (ret) + return dev_err_probe(dev, ret, "Failed to add IRQ chip\n"); + + ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev), + pmic->irq_chip_data, + BXTWC_TMU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_tmu, + &pmic->irq_chip_data_tmu); + if (ret) return ret; - } ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, BXTWC_PWRBTN_LVL1_IRQ, IRQF_ONESHOT, &bxtwc_regmap_irq_chip_pwrbtn, &pmic->irq_chip_data_pwrbtn); - if (ret) { - dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n"); - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_TMU_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_tmu, - &pmic->irq_chip_data_tmu); - if (ret) { - dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev), + pmic->irq_chip_data, + BXTWC_BCU_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_bcu, + &pmic->irq_chip_data_bcu); + if (ret) return ret; - } - /* Add chained IRQ handler for BCU IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_BCU_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_bcu, - &pmic->irq_chip_data_bcu); - - - if (ret) { - dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n"); - return ret; - } - - /* Add chained IRQ handler for ADC IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_ADC_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_adc, - &pmic->irq_chip_data_adc); - - - if (ret) { - dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n"); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev), + pmic->irq_chip_data, + BXTWC_ADC_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_adc, + &pmic->irq_chip_data_adc); + if (ret) return ret; - } - - /* Add chained IRQ handler for CHGR IRQs */ - ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, - BXTWC_CHGR_LVL1_IRQ, - IRQF_ONESHOT, - &bxtwc_regmap_irq_chip_chgr, - &pmic->irq_chip_data_chgr); - - if (ret) { - dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n"); + ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev), + pmic->irq_chip_data, + BXTWC_CHGR_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_chgr, + &pmic->irq_chip_data_chgr); + if (ret) return ret; - } /* Add chained IRQ handler for CRIT IRQs */ ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, @@ -539,19 +543,13 @@ IRQF_ONESHOT, &bxtwc_regmap_irq_chip_crit, &pmic->irq_chip_data_crit); - - - if (ret) { - dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n"); ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); - if (ret) { - dev_err(&pdev->dev, "Failed to add devices\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to add devices\n"); ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); if (ret) { --- linux-oracle-5.4.0.orig/drivers/mfd/intel_soc_pmic_core.c +++ linux-oracle-5.4.0/drivers/mfd/intel_soc_pmic_core.c @@ -111,6 +111,7 @@ return 0; err_del_irq_chip: + pwm_remove_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); return ret; } --- linux-oracle-5.4.0.orig/drivers/mfd/ipaq-micro.c +++ linux-oracle-5.4.0/drivers/mfd/ipaq-micro.c @@ -407,7 +407,7 @@ micro_reset_comm(micro); irq = platform_get_irq(pdev, 0); - if (!irq) + if (irq < 0) return -EINVAL; ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr, IRQF_SHARED, "ipaq-micro", --- linux-oracle-5.4.0.orig/drivers/mfd/lp8788-irq.c +++ linux-oracle-5.4.0/drivers/mfd/lp8788-irq.c @@ -175,6 +175,7 @@ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lp8788-irq", irqd); if (ret) { + irq_domain_remove(lp->irqdm); dev_err(lp->dev, "failed to create a thread for IRQ_N\n"); return ret; } @@ -188,4 +189,6 @@ { if (lp->irq) free_irq(lp->irq, lp->irqdm); + if (lp->irqdm) + irq_domain_remove(lp->irqdm); } --- linux-oracle-5.4.0.orig/drivers/mfd/lp8788.c +++ linux-oracle-5.4.0/drivers/mfd/lp8788.c @@ -195,8 +195,16 @@ if (ret) return ret; - return mfd_add_devices(lp->dev, -1, lp8788_devs, - ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); + ret = mfd_add_devices(lp->dev, -1, lp8788_devs, + ARRAY_SIZE(lp8788_devs), NULL, 0, NULL); + if (ret) + goto err_exit_irq; + + return 0; + +err_exit_irq: + lp8788_irq_exit(lp); + return ret; } static int lp8788_remove(struct i2c_client *cl) --- linux-oracle-5.4.0.orig/drivers/mfd/lpc_ich.c +++ linux-oracle-5.4.0/drivers/mfd/lpc_ich.c @@ -685,8 +685,9 @@ { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, - { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, { PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN}, + { PCI_VDEVICE(INTEL, 0x3197), LPC_GLK}, + { PCI_VDEVICE(INTEL, 0x31e8), LPC_GLK}, { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, --- linux-oracle-5.4.0.orig/drivers/mfd/max77620.c +++ linux-oracle-5.4.0/drivers/mfd/max77620.c @@ -418,9 +418,11 @@ ret = max77620_config_fps(chip, fps_child); if (ret < 0) { of_node_put(fps_child); + of_node_put(fps_np); return ret; } } + of_node_put(fps_np); config = chip->enable_global_lpm ? MAX77620_ONOFFCNFG2_SLP_LPM_MSK : 0; ret = regmap_update_bits(chip->rmap, MAX77620_REG_ONOFFCNFG2, --- linux-oracle-5.4.0.orig/drivers/mfd/mc13xxx-core.c +++ linux-oracle-5.4.0/drivers/mfd/mc13xxx-core.c @@ -323,8 +323,10 @@ adc1 |= MC13783_ADC1_ATOX; dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); - mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, + ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, mc13xxx_handler_adcdone, __func__, &adcdone_data); + if (ret) + goto out; mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); --- linux-oracle-5.4.0.orig/drivers/mfd/mfd-core.c +++ linux-oracle-5.4.0/drivers/mfd/mfd-core.c @@ -28,6 +28,11 @@ const struct mfd_cell *cell = mfd_get_cell(pdev); int err = 0; + if (!cell->enable) { + dev_dbg(&pdev->dev, "No .enable() call-back registered\n"); + return 0; + } + /* only call enable hook if the cell wasn't previously enabled */ if (atomic_inc_return(cell->usage_count) == 1) err = cell->enable(pdev); @@ -45,6 +50,11 @@ const struct mfd_cell *cell = mfd_get_cell(pdev); int err = 0; + if (!cell->disable) { + dev_dbg(&pdev->dev, "No .disable() call-back registered\n"); + return 0; + } + /* only disable if no other clients are using it */ if (atomic_dec_return(cell->usage_count) == 0) err = cell->disable(pdev); --- linux-oracle-5.4.0.orig/drivers/mfd/motorola-cpcap.c +++ linux-oracle-5.4.0/drivers/mfd/motorola-cpcap.c @@ -305,6 +305,10 @@ if (ret) return ret; + /* Parent SPI controller uses DMA, CPCAP and child devices do not */ + spi->dev.coherent_dma_mask = 0; + spi->dev.dma_mask = &spi->dev.coherent_dma_mask; + return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); } --- linux-oracle-5.4.0.orig/drivers/mfd/omap-usb-tll.c +++ linux-oracle-5.4.0/drivers/mfd/omap-usb-tll.c @@ -235,8 +235,7 @@ break; } - tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]), - GFP_KERNEL); + tll = devm_kzalloc(dev, struct_size(tll, ch_clk, nch), GFP_KERNEL); if (!tll) { pm_runtime_put_sync(dev); pm_runtime_disable(dev); --- linux-oracle-5.4.0.orig/drivers/mfd/pcf50633-adc.c +++ linux-oracle-5.4.0/drivers/mfd/pcf50633-adc.c @@ -136,6 +136,7 @@ void *callback_param) { struct pcf50633_adc_request *req; + int ret; /* req is freed when the result is ready, in interrupt handler */ req = kmalloc(sizeof(*req), GFP_KERNEL); @@ -147,7 +148,11 @@ req->callback = callback; req->callback_param = callback_param; - return adc_enqueue_request(pcf, req); + ret = adc_enqueue_request(pcf, req); + if (ret) + kfree(req); + + return ret; } EXPORT_SYMBOL_GPL(pcf50633_adc_async_read); --- linux-oracle-5.4.0.orig/drivers/mfd/rn5t618.c +++ linux-oracle-5.4.0/drivers/mfd/rn5t618.c @@ -26,6 +26,7 @@ case RN5T618_WATCHDOGCNT: case RN5T618_DCIRQ: case RN5T618_ILIMDATAH ... RN5T618_AIN0DATAL: + case RN5T618_ADCCNT3: case RN5T618_IR_ADC1 ... RN5T618_IR_ADC3: case RN5T618_IR_GPR: case RN5T618_IR_GPF: --- linux-oracle-5.4.0.orig/drivers/mfd/rt5033.c +++ linux-oracle-5.4.0/drivers/mfd/rt5033.c @@ -42,9 +42,6 @@ .name = "rt5033-charger", .of_compatible = "richtek,rt5033-charger", }, { - .name = "rt5033-battery", - .of_compatible = "richtek,rt5033-battery", - }, { .name = "rt5033-led", .of_compatible = "richtek,rt5033-led", }, @@ -85,8 +82,8 @@ } dev_info(&i2c->dev, "Device found Device ID: %04x\n", dev_id); - ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap, + rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0, &rt5033_irq_chip, &rt5033->irq_data); if (ret) { dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", --- linux-oracle-5.4.0.orig/drivers/mfd/sm501.c +++ linux-oracle-5.4.0/drivers/mfd/sm501.c @@ -1424,8 +1424,14 @@ goto err_claim; } - return sm501_init_dev(sm); + ret = sm501_init_dev(sm); + if (ret) + goto err_unmap; + return 0; + + err_unmap: + iounmap(sm->regs); err_claim: release_resource(sm->regs_claim); kfree(sm->regs_claim); @@ -1727,7 +1733,12 @@ static int __init sm501_base_init(void) { - platform_driver_register(&sm501_plat_driver); + int ret; + + ret = platform_driver_register(&sm501_plat_driver); + if (ret < 0) + return ret; + return pci_register_driver(&sm501_pci_driver); } --- linux-oracle-5.4.0.orig/drivers/mfd/sprd-sc27xx-spi.c +++ linux-oracle-5.4.0/drivers/mfd/sprd-sc27xx-spi.c @@ -204,7 +204,7 @@ } ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq, - IRQF_ONESHOT | IRQF_NO_SUSPEND, 0, + IRQF_ONESHOT, 0, &ddata->irq_chip, &ddata->irq_data); if (ret) { dev_err(&spi->dev, "Failed to add PMIC irq chip %d\n", ret); @@ -220,9 +220,34 @@ return ret; } + device_init_wakeup(&spi->dev, true); return 0; } +#ifdef CONFIG_PM_SLEEP +static int sprd_pmic_suspend(struct device *dev) +{ + struct sprd_pmic *ddata = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + enable_irq_wake(ddata->irq); + + return 0; +} + +static int sprd_pmic_resume(struct device *dev) +{ + struct sprd_pmic *ddata = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + disable_irq_wake(ddata->irq); + + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(sprd_pmic_pm_ops, sprd_pmic_suspend, sprd_pmic_resume); + static const struct of_device_id sprd_pmic_match[] = { { .compatible = "sprd,sc2731", .data = &sc2731_data }, {}, @@ -234,6 +259,7 @@ .name = "sc27xx-pmic", .bus = &spi_bus_type, .of_match_table = sprd_pmic_match, + .pm = &sprd_pmic_pm_ops, }, .probe = sprd_pmic_probe, }; --- linux-oracle-5.4.0.orig/drivers/mfd/stm32-timers.c +++ linux-oracle-5.4.0/drivers/mfd/stm32-timers.c @@ -158,13 +158,18 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata) { + u32 arr; + + /* Backup ARR to restore it after getting the maximum value */ + regmap_read(ddata->regmap, TIM_ARR, &arr); + /* * Only the available bits will be written so when readback * we get the maximum value of auto reload register */ regmap_write(ddata->regmap, TIM_ARR, ~0L); regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr); - regmap_write(ddata->regmap, TIM_ARR, 0x0); + regmap_write(ddata->regmap, TIM_ARR, arr); } static void stm32_timers_dma_probe(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/mfd/stmfx.c +++ linux-oracle-5.4.0/drivers/mfd/stmfx.c @@ -287,14 +287,21 @@ ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin); if (ret) - return ret; + goto irq_exit; ret = devm_request_threaded_irq(stmfx->dev, client->irq, NULL, stmfx_irq_handler, irqtrigger | IRQF_ONESHOT, "stmfx", stmfx); if (ret) - stmfx_irq_exit(client); + goto irq_exit; + + stmfx->irq = client->irq; + + return 0; + +irq_exit: + stmfx_irq_exit(client); return ret; } @@ -382,7 +389,7 @@ err: if (stmfx->vdd) - return regulator_disable(stmfx->vdd); + regulator_disable(stmfx->vdd); return ret; } @@ -481,6 +488,8 @@ if (ret) return ret; + disable_irq(stmfx->irq); + if (stmfx->vdd) return regulator_disable(stmfx->vdd); @@ -501,6 +510,13 @@ } } + /* Reset STMFX - supply has been stopped during suspend */ + ret = stmfx_chip_reset(stmfx); + if (ret) { + dev_err(stmfx->dev, "Failed to reset chip: %d\n", ret); + return ret; + } + ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL, &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); if (ret) @@ -517,6 +533,8 @@ if (ret) return ret; + enable_irq(stmfx->irq); + return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/mfd/stmpe-i2c.c +++ linux-oracle-5.4.0/drivers/mfd/stmpe-i2c.c @@ -109,7 +109,7 @@ { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(i2c, stmpe_id); +MODULE_DEVICE_TABLE(i2c, stmpe_i2c_id); static struct i2c_driver stmpe_i2c_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/mfd/stmpe.c +++ linux-oracle-5.4.0/drivers/mfd/stmpe.c @@ -1091,7 +1091,7 @@ if (variant->id_val == STMPE801_ID || variant->id_val == STMPE1600_ID) { - int base = irq_create_mapping(stmpe->domain, 0); + int base = irq_find_mapping(stmpe->domain, 0); handle_nested_irq(base); return IRQ_HANDLED; @@ -1119,7 +1119,7 @@ while (status) { int bit = __ffs(status); int line = bank * 8 + bit; - int nestedirq = irq_create_mapping(stmpe->domain, line); + int nestedirq = irq_find_mapping(stmpe->domain, line); handle_nested_irq(nestedirq); status &= ~(1 << bit); @@ -1494,9 +1494,9 @@ int stmpe_remove(struct stmpe *stmpe) { - if (!IS_ERR(stmpe->vio)) + if (!IS_ERR(stmpe->vio) && regulator_is_enabled(stmpe->vio)) regulator_disable(stmpe->vio); - if (!IS_ERR(stmpe->vcc)) + if (!IS_ERR(stmpe->vcc) && regulator_is_enabled(stmpe->vcc)) regulator_disable(stmpe->vcc); __stmpe_disable(stmpe, STMPE_BLOCK_ADC); --- linux-oracle-5.4.0.orig/drivers/mfd/syscon.c +++ linux-oracle-5.4.0/drivers/mfd/syscon.c @@ -219,7 +219,9 @@ return ERR_PTR(-ENODEV); regmap = syscon_node_to_regmap(syscon_np); - of_node_put(syscon_np); + + if (property) + of_node_put(syscon_np); return regmap; } --- linux-oracle-5.4.0.orig/drivers/mfd/t7l66xb.c +++ linux-oracle-5.4.0/drivers/mfd/t7l66xb.c @@ -405,11 +405,8 @@ static int t7l66xb_remove(struct platform_device *dev) { - struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev); struct t7l66xb *t7l66xb = platform_get_drvdata(dev); - int ret; - ret = pdata->disable(dev); clk_disable_unprepare(t7l66xb->clk48m); clk_put(t7l66xb->clk48m); clk_disable_unprepare(t7l66xb->clk32k); @@ -420,8 +417,7 @@ mfd_remove_devices(&dev->dev); kfree(t7l66xb); - return ret; - + return 0; } static struct platform_driver t7l66xb_platform_driver = { --- linux-oracle-5.4.0.orig/drivers/mfd/tc3589x.c +++ linux-oracle-5.4.0/drivers/mfd/tc3589x.c @@ -187,7 +187,7 @@ while (status) { int bit = __ffs(status); - int virq = irq_create_mapping(tc3589x->domain, bit); + int virq = irq_find_mapping(tc3589x->domain, bit); handle_nested_irq(virq); status &= ~(1 << bit); --- linux-oracle-5.4.0.orig/drivers/mfd/tps65010.c +++ linux-oracle-5.4.0/drivers/mfd/tps65010.c @@ -550,17 +550,13 @@ */ if (client->irq > 0) { status = request_irq(client->irq, tps65010_irq, - IRQF_TRIGGER_FALLING, DRIVER_NAME, tps); + IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN, + DRIVER_NAME, tps); if (status < 0) { dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", client->irq, status); return status; } - /* annoying race here, ideally we'd have an option - * to claim the irq now and enable it later. - * FIXME genirq IRQF_NOAUTOEN now solves that ... - */ - disable_irq(client->irq); set_bit(FLAG_IRQ_ENABLE, &tps->flags); } else dev_warn(&client->dev, "IRQ not configured!\n"); --- linux-oracle-5.4.0.orig/drivers/mfd/tqmx86.c +++ linux-oracle-5.4.0/drivers/mfd/tqmx86.c @@ -210,6 +210,8 @@ /* Assumes the IRQ resource is first. */ tqmx_gpio_resources[0].start = gpio_irq; + } else { + tqmx_gpio_resources[0].flags = 0; } ocores_platfom_data.clock_khz = tqmx86_board_id_to_clk_rate(board_id); --- linux-oracle-5.4.0.orig/drivers/mfd/wm831x-auxadc.c +++ linux-oracle-5.4.0/drivers/mfd/wm831x-auxadc.c @@ -93,11 +93,10 @@ wait_for_completion_timeout(&req->done, msecs_to_jiffies(500)); mutex_lock(&wm831x->auxadc_lock); - - list_del(&req->list); ret = req->val; out: + list_del(&req->list); mutex_unlock(&wm831x->auxadc_lock); kfree(req); --- linux-oracle-5.4.0.orig/drivers/mfd/wm8994-core.c +++ linux-oracle-5.4.0/drivers/mfd/wm8994-core.c @@ -690,3 +690,4 @@ MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Mark Brown "); +MODULE_SOFTDEP("pre: wm8994_regulator"); --- linux-oracle-5.4.0.orig/drivers/mfd/wm8994-irq.c +++ linux-oracle-5.4.0/drivers/mfd/wm8994-irq.c @@ -154,7 +154,7 @@ struct wm8994 *wm8994 = data; while (gpio_get_value_cansleep(wm8994->pdata.irq_gpio)) - handle_nested_irq(irq_create_mapping(wm8994->edge_irq, 0)); + handle_nested_irq(irq_find_mapping(wm8994->edge_irq, 0)); return IRQ_HANDLED; } --- linux-oracle-5.4.0.orig/drivers/misc/altera-stapl/altera.c +++ linux-oracle-5.4.0/drivers/misc/altera-stapl/altera.c @@ -2112,8 +2112,8 @@ return status; } -static int altera_get_note(u8 *p, s32 program_size, - s32 *offset, char *key, char *value, int length) +static int altera_get_note(u8 *p, s32 program_size, s32 *offset, + char *key, char *value, int keylen, int vallen) /* * Gets key and value of NOTE fields in the JBC file. * Can be called in two modes: if offset pointer is NULL, @@ -2170,7 +2170,7 @@ &p[note_table + (8 * i) + 4])]; if (value != NULL) - strlcpy(value, value_ptr, length); + strlcpy(value, value_ptr, vallen); } } @@ -2189,13 +2189,13 @@ strlcpy(key, &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i)])], - length); + keylen); if (value != NULL) strlcpy(value, &p[note_strings + get_unaligned_be32( &p[note_table + (8 * i) + 4])], - length); + vallen); *offset = i + 1; } @@ -2449,7 +2449,7 @@ __func__, (format_version == 2) ? "Jam STAPL" : "pre-standardized Jam 1.1"); while (altera_get_note((u8 *)fw->data, fw->size, - &offset, key, value, 256) == 0) + &offset, key, value, 32, 256) == 0) printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n", __func__, key, value); } --- linux-oracle-5.4.0.orig/drivers/misc/apds990x.c +++ linux-oracle-5.4.0/drivers/misc/apds990x.c @@ -1148,7 +1148,7 @@ err = chip->pdata->setup_resources(); if (err) { err = -EINVAL; - goto fail3; + goto fail4; } } @@ -1156,7 +1156,7 @@ apds990x_attribute_group); if (err < 0) { dev_err(&chip->client->dev, "Sysfs registration failed\n"); - goto fail4; + goto fail5; } err = request_threaded_irq(client->irq, NULL, @@ -1167,15 +1167,17 @@ if (err) { dev_err(&client->dev, "could not get IRQ %d\n", client->irq); - goto fail5; + goto fail6; } return err; -fail5: +fail6: sysfs_remove_group(&chip->client->dev.kobj, &apds990x_attribute_group[0]); -fail4: +fail5: if (chip->pdata && chip->pdata->release_resources) chip->pdata->release_resources(); +fail4: + pm_runtime_disable(&client->dev); fail3: regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); fail2: --- linux-oracle-5.4.0.orig/drivers/misc/atmel-ssc.c +++ linux-oracle-5.4.0/drivers/misc/atmel-ssc.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -20,7 +20,7 @@ #include "../../sound/soc/atmel/atmel_ssc_dai.h" /* Serialize access to ssc_list and user count */ -static DEFINE_SPINLOCK(user_lock); +static DEFINE_MUTEX(user_lock); static LIST_HEAD(ssc_list); struct ssc_device *ssc_request(unsigned int ssc_num) @@ -28,7 +28,7 @@ int ssc_valid = 0; struct ssc_device *ssc; - spin_lock(&user_lock); + mutex_lock(&user_lock); list_for_each_entry(ssc, &ssc_list, list) { if (ssc->pdev->dev.of_node) { if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc") @@ -44,18 +44,18 @@ } if (!ssc_valid) { - spin_unlock(&user_lock); + mutex_unlock(&user_lock); pr_err("ssc: ssc%d platform device is missing\n", ssc_num); return ERR_PTR(-ENODEV); } if (ssc->user) { - spin_unlock(&user_lock); + mutex_unlock(&user_lock); dev_dbg(&ssc->pdev->dev, "module busy\n"); return ERR_PTR(-EBUSY); } ssc->user++; - spin_unlock(&user_lock); + mutex_unlock(&user_lock); clk_prepare(ssc->clk); @@ -67,14 +67,14 @@ { bool disable_clk = true; - spin_lock(&user_lock); + mutex_lock(&user_lock); if (ssc->user) ssc->user--; else { disable_clk = false; dev_dbg(&ssc->pdev->dev, "device already free\n"); } - spin_unlock(&user_lock); + mutex_unlock(&user_lock); if (disable_clk) clk_unprepare(ssc->clk); @@ -232,14 +232,14 @@ clk_disable_unprepare(ssc->clk); ssc->irq = platform_get_irq(pdev, 0); - if (!ssc->irq) { + if (ssc->irq < 0) { dev_dbg(&pdev->dev, "could not get irq\n"); - return -ENXIO; + return ssc->irq; } - spin_lock(&user_lock); + mutex_lock(&user_lock); list_add_tail(&ssc->list, &ssc_list); - spin_unlock(&user_lock); + mutex_unlock(&user_lock); platform_set_drvdata(pdev, ssc); @@ -258,9 +258,9 @@ ssc_sound_dai_remove(ssc); - spin_lock(&user_lock); + mutex_lock(&user_lock); list_del(&ssc->list); - spin_unlock(&user_lock); + mutex_unlock(&user_lock); return 0; } --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/alcor_pci.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/alcor_pci.c @@ -133,7 +133,13 @@ u32 val32; priv->pdev_cap_off = alcor_pci_find_cap_offset(priv, priv->pdev); - priv->parent_cap_off = alcor_pci_find_cap_offset(priv, + /* + * A device might be attached to root complex directly and + * priv->parent_pdev will be NULL. In this case we don't check its + * capability and disable ASPM completely. + */ + if (priv->parent_pdev) + priv->parent_cap_off = alcor_pci_find_cap_offset(priv, priv->parent_pdev); if ((priv->pdev_cap_off == 0) || (priv->parent_cap_off == 0)) { @@ -254,7 +260,7 @@ if (!priv) return -ENOMEM; - ret = ida_simple_get(&alcor_pci_idr, 0, 0, GFP_KERNEL); + ret = ida_alloc(&alcor_pci_idr, GFP_KERNEL); if (ret < 0) return ret; priv->id = ret; @@ -268,7 +274,8 @@ ret = pci_request_regions(pdev, DRV_NAME_ALCOR_PCI); if (ret) { dev_err(&pdev->dev, "Cannot request region\n"); - return -ENOMEM; + ret = -ENOMEM; + goto error_free_ida; } if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { @@ -312,6 +319,8 @@ error_release_regions: pci_release_regions(pdev); +error_free_ida: + ida_free(&alcor_pci_idr, priv->id); return ret; } @@ -325,7 +334,7 @@ mfd_remove_devices(&pdev->dev); - ida_simple_remove(&alcor_pci_idr, priv->id); + ida_free(&alcor_pci_idr, priv->id); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/rts5227.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/rts5227.c @@ -338,6 +338,11 @@ { rts5227_extra_init_hw(pcr); + /* Power down OCP for power consumption */ + if (!pcr->card_exist) + rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, + OC_POWER_DOWN); + rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG, FUNC_FORCE_UPME_XMT_DBG); rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04); @@ -394,7 +399,8 @@ void rts522a_init_params(struct rtsx_pcr *pcr) { rts5227_init_params(pcr); - + pcr->ops = &rts522a_pcr_ops; + pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11); pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; pcr->option.ocp_en = 1; --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/rts5249.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/rts5249.c @@ -618,6 +618,7 @@ void rts524a_init_params(struct rtsx_pcr *pcr) { rts5249_init_params(pcr); + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; pcr->option.ltr_l1off_snooze_sspwrgate = LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; @@ -733,6 +734,7 @@ void rts525a_init_params(struct rtsx_pcr *pcr) { rts5249_init_params(pcr); + pcr->tx_initial_phase = SET_CLOCK_PHASE(25, 29, 11); pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; pcr->option.ltr_l1off_snooze_sspwrgate = LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/rts5260.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/rts5260.c @@ -663,7 +663,7 @@ pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; pcr->aspm_en = ASPM_L1_EN; - pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16); + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); pcr->ic_version = rts5260_get_ic_version(pcr); --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/rtsx_pcr.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/rtsx_pcr.c @@ -143,6 +143,9 @@ rtsx_disable_aspm(pcr); + /* Fixes DMA transfer timout issue after disabling ASPM on RTS5260 */ + msleep(1); + if (option->ltr_enabled) rtsx_set_ltr_latency(pcr, option->ltr_active_latency); @@ -1186,10 +1189,6 @@ rtsx_pci_write_register(pcr, REG_OCPGLITCH, SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch); rtsx_pci_enable_ocp(pcr); - } else { - /* OC power down */ - rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, - OC_POWER_DOWN); } } } @@ -1486,7 +1485,7 @@ pcr->remap_addr = ioremap_nocache(base, len); if (!pcr->remap_addr) { ret = -ENOMEM; - goto free_handle; + goto free_idr; } pcr->rtsx_resv_buf = dma_alloc_coherent(&(pcidev->dev), @@ -1531,12 +1530,14 @@ ret = mfd_add_devices(&pcidev->dev, pcr->id, rtsx_pcr_cells, ARRAY_SIZE(rtsx_pcr_cells), NULL, 0, NULL); if (ret < 0) - goto disable_irq; + goto free_slots; schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200)); return 0; +free_slots: + kfree(pcr->slots); disable_irq: free_irq(pcr->irq, (void *)pcr); disable_msi: @@ -1546,6 +1547,10 @@ pcr->rtsx_resv_buf, pcr->rtsx_resv_buf_addr); unmap: iounmap(pcr->remap_addr); +free_idr: + spin_lock(&rtsx_pci_lock); + idr_remove(&rtsx_pci_idr, pcr->id); + spin_unlock(&rtsx_pci_lock); free_handle: kfree(handle); free_pcr: --- linux-oracle-5.4.0.orig/drivers/misc/cardreader/rtsx_usb.c +++ linux-oracle-5.4.0/drivers/misc/cardreader/rtsx_usb.c @@ -631,16 +631,20 @@ ucr->pusb_dev = usb_dev; - ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE, - GFP_KERNEL, &ucr->iobuf_dma); - if (!ucr->iobuf) + ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); + if (!ucr->cmd_buf) return -ENOMEM; + ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); + if (!ucr->rsp_buf) { + ret = -ENOMEM; + goto out_free_cmd_buf; + } + usb_set_intfdata(intf, ucr); ucr->vendor_id = id->idVendor; ucr->product_id = id->idProduct; - ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf; mutex_init(&ucr->dev_mutex); @@ -667,8 +671,12 @@ return 0; out_init_fail: - usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, - ucr->iobuf_dma); + usb_set_intfdata(ucr->pusb_intf, NULL); + kfree(ucr->rsp_buf); + ucr->rsp_buf = NULL; +out_free_cmd_buf: + kfree(ucr->cmd_buf); + ucr->cmd_buf = NULL; return ret; } @@ -681,8 +689,12 @@ mfd_remove_devices(&intf->dev); usb_set_intfdata(ucr->pusb_intf, NULL); - usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, - ucr->iobuf_dma); + + kfree(ucr->cmd_buf); + ucr->cmd_buf = NULL; + + kfree(ucr->rsp_buf); + ucr->rsp_buf = NULL; } #ifdef CONFIG_PM --- linux-oracle-5.4.0.orig/drivers/misc/cb710/sgbuf2.c +++ linux-oracle-5.4.0/drivers/misc/cb710/sgbuf2.c @@ -47,7 +47,7 @@ #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS return false; #else - return ((ptr - NULL) & 3) != 0; + return ((uintptr_t)ptr & 3) != 0; #endif } --- linux-oracle-5.4.0.orig/drivers/misc/cxl/flash.c +++ linux-oracle-5.4.0/drivers/misc/cxl/flash.c @@ -473,12 +473,6 @@ return -EINVAL; } -static long device_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - return device_ioctl(file, cmd, arg); -} - static int device_close(struct inode *inode, struct file *file) { struct cxl *adapter = file->private_data; @@ -514,7 +508,7 @@ .owner = THIS_MODULE, .open = device_open, .unlocked_ioctl = device_ioctl, - .compat_ioctl = device_compat_ioctl, + .compat_ioctl = compat_ptr_ioctl, .release = device_close, }; --- linux-oracle-5.4.0.orig/drivers/misc/cxl/guest.c +++ linux-oracle-5.4.0/drivers/misc/cxl/guest.c @@ -959,10 +959,10 @@ * if it returns an error! */ if ((rc = cxl_register_afu(afu))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_afu_add(afu))) - goto err_put1; + goto err_del_dev; /* * pHyp doesn't expose the programming models supported by the @@ -978,7 +978,7 @@ afu->modes_supported = CXL_MODE_DIRECTED; if ((rc = cxl_afu_select_best_mode(afu))) - goto err_put2; + goto err_remove_sysfs; adapter->afu[afu->slice] = afu; @@ -998,10 +998,12 @@ return 0; -err_put2: +err_remove_sysfs: cxl_sysfs_afu_remove(afu); -err_put1: - device_unregister(&afu->dev); +err_del_dev: + device_del(&afu->dev); +err_put_dev: + put_device(&afu->dev); free = false; guest_release_serr_irq(afu); err2: @@ -1135,18 +1137,20 @@ * even if it returns an error! */ if ((rc = cxl_register_adapter(adapter))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_adapter_add(adapter))) - goto err_put1; + goto err_del_dev; /* release the context lock as the adapter is configured */ cxl_adapter_context_unlock(adapter); return adapter; -err_put1: - device_unregister(&adapter->dev); +err_del_dev: + device_del(&adapter->dev); +err_put_dev: + put_device(&adapter->dev); free = false; cxl_guest_remove_chardev(adapter); err1: --- linux-oracle-5.4.0.orig/drivers/misc/cxl/irq.c +++ linux-oracle-5.4.0/drivers/misc/cxl/irq.c @@ -349,6 +349,7 @@ out: cxl_ops->release_irq_ranges(&ctx->irqs, ctx->afu->adapter); + bitmap_free(ctx->irq_bitmap); afu_irq_name_free(ctx); return -ENOMEM; } --- linux-oracle-5.4.0.orig/drivers/misc/cxl/pci.c +++ linux-oracle-5.4.0/drivers/misc/cxl/pci.c @@ -387,14 +387,15 @@ rc = get_phb_index(np, phb_index); if (rc) { pr_err("cxl: invalid phb index\n"); + of_node_put(np); return rc; } *capp_unit_id = get_capp_unit_id(np, *phb_index); of_node_put(np); if (!*capp_unit_id) { - pr_err("cxl: invalid capp unit id (phb_index: %d)\n", - *phb_index); + pr_err("cxl: No capp unit found for PHB[%lld,%d]. Make sure the adapter is on a capi-compatible slot\n", + *chipid, *phb_index); return -ENODEV; } @@ -1164,10 +1165,10 @@ * if it returns an error! */ if ((rc = cxl_register_afu(afu))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_afu_add(afu))) - goto err_put1; + goto err_del_dev; adapter->afu[afu->slice] = afu; @@ -1176,10 +1177,12 @@ return 0; -err_put1: +err_del_dev: + device_del(&afu->dev); +err_put_dev: pci_deconfigure_afu(afu); cxl_debugfs_afu_remove(afu); - device_unregister(&afu->dev); + put_device(&afu->dev); return rc; err_free_native: @@ -1667,23 +1670,25 @@ * even if it returns an error! */ if ((rc = cxl_register_adapter(adapter))) - goto err_put1; + goto err_put_dev; if ((rc = cxl_sysfs_adapter_add(adapter))) - goto err_put1; + goto err_del_dev; /* Release the context lock as adapter is configured */ cxl_adapter_context_unlock(adapter); return adapter; -err_put1: +err_del_dev: + device_del(&adapter->dev); +err_put_dev: /* This should mirror cxl_remove_adapter, except without the * sysfs parts */ cxl_debugfs_adapter_remove(adapter); cxl_deconfigure_adapter(adapter); - device_unregister(&adapter->dev); + put_device(&adapter->dev); return ERR_PTR(rc); err_release: --- linux-oracle-5.4.0.orig/drivers/misc/cxl/sysfs.c +++ linux-oracle-5.4.0/drivers/misc/cxl/sysfs.c @@ -624,7 +624,7 @@ rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type, &afu->dev.kobj, "cr%i", cr->cr); if (rc) - goto err; + goto err1; rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr); if (rc) --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/Kconfig +++ linux-oracle-5.4.0/drivers/misc/eeprom/Kconfig @@ -6,6 +6,7 @@ depends on I2C && SYSFS select NVMEM select NVMEM_SYSFS + select REGMAP select REGMAP_I2C help Enable this driver to get read/write support to most I2C EEPROMs --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/at24.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/at24.c @@ -695,10 +695,6 @@ nvmem_config.word_size = 1; nvmem_config.size = byte_len; - at24->nvmem = devm_nvmem_register(dev, &nvmem_config); - if (IS_ERR(at24->nvmem)) - return PTR_ERR(at24->nvmem); - i2c_set_clientdata(client, at24); /* enable runtime pm */ @@ -710,12 +706,19 @@ * chip is functional. */ err = at24_read(at24, 0, &test_byte, 1); - pm_runtime_idle(dev); if (err) { pm_runtime_disable(dev); return -ENODEV; } + at24->nvmem = devm_nvmem_register(dev, &nvmem_config); + if (IS_ERR(at24->nvmem)) { + pm_runtime_disable(dev); + return PTR_ERR(at24->nvmem); + } + + pm_runtime_idle(dev); + dev_info(dev, "%u byte %s EEPROM, %s, %u bytes/write\n", byte_len, client->name, writable ? "writable" : "read-only", at24->write_max); --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/at25.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/at25.c @@ -358,7 +358,7 @@ at25->nvmem_config.reg_read = at25_ee_read; at25->nvmem_config.reg_write = at25_ee_write; at25->nvmem_config.priv = at25; - at25->nvmem_config.stride = 4; + at25->nvmem_config.stride = 1; at25->nvmem_config.word_size = 1; at25->nvmem_config.size = chip.byte_len; --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/digsy_mtc_eeprom.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/digsy_mtc_eeprom.c @@ -60,7 +60,7 @@ }; static struct gpiod_lookup_table eeprom_spi_gpiod_table = { - .dev_id = "spi_gpio", + .dev_id = "spi_gpio.1", .table = { GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CLK, "sck", GPIO_ACTIVE_HIGH), --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/ee1004.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/ee1004.c @@ -82,6 +82,9 @@ if (unlikely(offset + count > EE1004_PAGE_SIZE)) count = EE1004_PAGE_SIZE - offset; + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + status = i2c_smbus_read_i2c_block_data_or_emulated(client, offset, count, buf); dev_dbg(&client->dev, "read %zu@%d --> %d\n", count, offset, status); --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/eeprom_93cx6.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/eeprom_93cx6.c @@ -186,6 +186,11 @@ eeprom_93cx6_write_bits(eeprom, command, PCI_EEPROM_WIDTH_OPCODE + eeprom->width); + if (has_quirk_extra_read_cycle(eeprom)) { + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); + } + /* * Read the requested 16 bits. */ @@ -252,6 +257,11 @@ eeprom_93cx6_write_bits(eeprom, command, PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1); + if (has_quirk_extra_read_cycle(eeprom)) { + eeprom_93cx6_pulse_high(eeprom); + eeprom_93cx6_pulse_low(eeprom); + } + /* * Read the requested 8 bits. */ --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/eeprom_93xx46.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/eeprom_93xx46.c @@ -35,6 +35,10 @@ EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, }; +static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = { + .quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE, +}; + struct eeprom_93xx46_dev { struct spi_device *spi; struct eeprom_93xx46_platform_data *pdata; @@ -55,6 +59,11 @@ return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; } +static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; +} + static int eeprom_93xx46_read(void *priv, unsigned int off, void *val, size_t count) { @@ -96,6 +105,11 @@ dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", cmd_addr, edev->spi->max_speed_hz); + if (has_quirk_extra_read_cycle(edev)) { + cmd_addr <<= 1; + bits += 1; + } + spi_message_init(&m); t[0].tx_buf = (char *)&cmd_addr; @@ -363,6 +377,7 @@ static const struct of_device_id eeprom_93xx46_of_table[] = { { .compatible = "eeprom-93xx46", }, { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, + { .compatible = "microchip,93lc46b", .data = µchip_93lc46b_data, }, {} }; MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); @@ -511,3 +526,4 @@ MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); MODULE_AUTHOR("Anatolij Gustschin "); MODULE_ALIAS("spi:93xx46"); +MODULE_ALIAS("spi:eeprom-93xx46"); --- linux-oracle-5.4.0.orig/drivers/misc/eeprom/idt_89hpesx.c +++ linux-oracle-5.4.0/drivers/misc/eeprom/idt_89hpesx.c @@ -1126,11 +1126,10 @@ device_for_each_child_node(dev, fwnode) { ee_id = idt_ee_match_id(fwnode); - if (!ee_id) { - dev_warn(dev, "Skip unsupported EEPROM device"); - continue; - } else + if (ee_id) break; + + dev_warn(dev, "Skip unsupported EEPROM device %pfw\n", fwnode); } /* If there is no fwnode EEPROM device, then set zero size */ @@ -1161,6 +1160,7 @@ else /* if (!fwnode_property_read_bool(node, "read-only")) */ pdev->eero = false; + fwnode_handle_put(fwnode); dev_info(dev, "EEPROM of %d bytes found by 0x%x", pdev->eesize, pdev->eeaddr); } --- linux-oracle-5.4.0.orig/drivers/misc/enclosure.c +++ linux-oracle-5.4.0/drivers/misc/enclosure.c @@ -406,10 +406,9 @@ cdev = &edev->component[i]; if (cdev->dev == dev) { enclosure_remove_links(cdev); - device_del(&cdev->cdev); put_device(dev); cdev->dev = NULL; - return device_add(&cdev->cdev); + return 0; } } return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/misc/fastrpc.c +++ linux-oracle-5.4.0/drivers/misc/fastrpc.c @@ -218,6 +218,13 @@ dma_buf_put(map->buf); } + if (map->fl) { + spin_lock(&map->fl->lock); + list_del(&map->node); + spin_unlock(&map->fl->lock); + map->fl = NULL; + } + kfree(map); } @@ -227,10 +234,12 @@ kref_put(&map->refcount, fastrpc_free_map); } -static void fastrpc_map_get(struct fastrpc_map *map) +static int fastrpc_map_get(struct fastrpc_map *map) { - if (map) - kref_get(&map->refcount); + if (!map) + return -ENOENT; + + return kref_get_unless_zero(&map->refcount) ? 0 : -ENOENT; } static int fastrpc_map_find(struct fastrpc_user *fl, int fd, @@ -693,16 +702,18 @@ static u64 fastrpc_get_payload_size(struct fastrpc_invoke_ctx *ctx, int metalen) { u64 size = 0; - int i; + int oix; size = ALIGN(metalen, FASTRPC_ALIGN); - for (i = 0; i < ctx->nscalars; i++) { + for (oix = 0; oix < ctx->nbufs; oix++) { + int i = ctx->olaps[oix].raix; + if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1) { - if (ctx->olaps[i].offset == 0) + if (ctx->olaps[oix].offset == 0) size = ALIGN(size, FASTRPC_ALIGN); - size += (ctx->olaps[i].mend - ctx->olaps[i].mstart); + size += (ctx->olaps[oix].mend - ctx->olaps[oix].mstart); } } @@ -790,7 +801,7 @@ vma = find_vma(current->mm, ctx->args[i].ptr); if (vma) - pages[i].addr += ctx->args[i].ptr - + pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) - vma->vm_start; pg_start = (ctx->args[i].ptr & PAGE_MASK) >> PAGE_SHIFT; @@ -886,6 +897,7 @@ struct fastrpc_channel_ctx *cctx; struct fastrpc_user *fl = ctx->fl; struct fastrpc_msg *msg = &ctx->msg; + int ret; cctx = fl->cctx; msg->pid = fl->tgid; @@ -901,7 +913,13 @@ msg->size = roundup(ctx->msg_sz, PAGE_SIZE); fastrpc_context_get(ctx); - return rpmsg_send(cctx->rpdev->ept, (void *)msg, sizeof(*msg)); + ret = rpmsg_send(cctx->rpdev->ept, (void *)msg, sizeof(*msg)); + + if (ret) + fastrpc_context_put(ctx); + + return ret; + } static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel, @@ -917,6 +935,11 @@ if (!fl->cctx->rpdev) return -EPIPE; + if (handle == FASTRPC_INIT_HANDLE && !kernel) { + dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n", handle); + return -EPERM; + } + ctx = fastrpc_context_alloc(fl, kernel, sc, args); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -1051,7 +1074,7 @@ sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); if (init.attrs) - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0); err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, args); @@ -1066,12 +1089,7 @@ fl->init_mem = NULL; fastrpc_buf_free(imem); err_alloc: - if (map) { - spin_lock(&fl->lock); - list_del(&map->node); - spin_unlock(&fl->lock); - fastrpc_map_put(map); - } + fastrpc_map_put(map); err: kfree(args); @@ -1147,10 +1165,8 @@ fastrpc_context_put(ctx); } - list_for_each_entry_safe(map, m, &fl->maps, node) { - list_del(&map->node); + list_for_each_entry_safe(map, m, &fl->maps, node) fastrpc_map_put(map); - } fastrpc_session_free(cctx, fl->sctx); fastrpc_channel_ctx_put(cctx); @@ -1231,7 +1247,14 @@ } if (copy_to_user(argp, &bp, sizeof(bp))) { - dma_buf_put(buf->dmabuf); + /* + * The usercopy failed, but we can't do much about it, as + * dma_buf_fd() already called fd_install() and made the + * file descriptor accessible for the current process. It + * might already be closed and dmabuf no longer valid when + * we reach this point. Therefore "leak" the fd and rely on + * the process exit path to do any required cleanup. + */ return -EFAULT; } @@ -1336,7 +1359,12 @@ of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions); spin_lock_irqsave(&cctx->lock, flags); - sess = &cctx->session[cctx->sesscount]; + if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) { + dev_err(&pdev->dev, "too many sessions\n"); + spin_unlock_irqrestore(&cctx->lock, flags); + return -ENOSPC; + } + sess = &cctx->session[cctx->sesscount++]; sess->used = false; sess->valid = true; sess->dev = dev; @@ -1349,13 +1377,12 @@ struct fastrpc_session_ctx *dup_sess; for (i = 1; i < sessions; i++) { - if (cctx->sesscount++ >= FASTRPC_MAX_SESSIONS) + if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) break; - dup_sess = &cctx->session[cctx->sesscount]; + dup_sess = &cctx->session[cctx->sesscount++]; memcpy(dup_sess, sess, sizeof(*dup_sess)); } } - cctx->sesscount++; spin_unlock_irqrestore(&cctx->lock, flags); rc = dma_set_mask(dev, DMA_BIT_MASK(32)); if (rc) { @@ -1374,7 +1401,7 @@ int i; spin_lock_irqsave(&cctx->lock, flags); - for (i = 1; i < FASTRPC_MAX_SESSIONS; i++) { + for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) { if (cctx->session[i].sid == sess->sid) { cctx->session[i].valid = false; cctx->sesscount--; @@ -1430,12 +1457,14 @@ return -ENOMEM; data->miscdev.minor = MISC_DYNAMIC_MINOR; - data->miscdev.name = kasprintf(GFP_KERNEL, "fastrpc-%s", - domains[domain_id]); + data->miscdev.name = devm_kasprintf(rdev, GFP_KERNEL, "fastrpc-%s", + domains[domain_id]); data->miscdev.fops = &fastrpc_fops; err = misc_register(&data->miscdev); - if (err) + if (err) { + kfree(data); return err; + } kref_init(&data->refcount); @@ -1455,8 +1484,10 @@ struct fastrpc_invoke_ctx *ctx; spin_lock(&user->lock); - list_for_each_entry(ctx, &user->pending, node) + list_for_each_entry(ctx, &user->pending, node) { + ctx->retval = -EPIPE; complete(&ctx->work); + } spin_unlock(&user->lock); } @@ -1466,7 +1497,9 @@ struct fastrpc_user *user; unsigned long flags; + /* No invocations past this point */ spin_lock_irqsave(&cctx->lock, flags); + cctx->rpdev = NULL; list_for_each_entry(user, &cctx->users, user) fastrpc_notify_users(user); spin_unlock_irqrestore(&cctx->lock, flags); @@ -1474,7 +1507,6 @@ misc_deregister(&cctx->miscdev); of_platform_depopulate(&rpdev->dev); - cctx->rpdev = NULL; fastrpc_channel_ctx_put(cctx); } --- linux-oracle-5.4.0.orig/drivers/misc/genwqe/card_dev.c +++ linux-oracle-5.4.0/drivers/misc/genwqe/card_dev.c @@ -1215,34 +1215,13 @@ return rc; } -#if defined(CONFIG_COMPAT) -/** - * genwqe_compat_ioctl() - Compatibility ioctl - * - * Called whenever a 32-bit process running under a 64-bit kernel - * performs an ioctl on /dev/genwqe_card. - * - * @filp: file pointer. - * @cmd: command. - * @arg: user argument. - * Return: zero on success or negative number on failure. - */ -static long genwqe_compat_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - return genwqe_ioctl(filp, cmd, arg); -} -#endif /* defined(CONFIG_COMPAT) */ - static const struct file_operations genwqe_fops = { .owner = THIS_MODULE, .open = genwqe_open, .fasync = genwqe_fasync, .mmap = genwqe_mmap, .unlocked_ioctl = genwqe_ioctl, -#if defined(CONFIG_COMPAT) - .compat_ioctl = genwqe_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, .release = genwqe_release, }; --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/command_submission.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/command_submission.c @@ -777,8 +777,9 @@ memset(args, 0, sizeof(*args)); if (rc < 0) { - dev_err(hdev->dev, "Error %ld on waiting for CS handle %llu\n", - rc, seq); + dev_err_ratelimited(hdev->dev, + "Error %ld on waiting for CS handle %llu\n", + rc, seq); if (rc == -ERESTARTSYS) { args->out.status = HL_WAIT_CS_STATUS_INTERRUPTED; rc = -EINTR; --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/context.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/context.c @@ -176,7 +176,7 @@ spin_lock(&ctx->cs_lock); if (seq >= ctx->cs_sequence) { - dev_notice(hdev->dev, + dev_notice_ratelimited(hdev->dev, "Can't wait on seq %llu because current CS is at seq %llu\n", seq, ctx->cs_sequence); spin_unlock(&ctx->cs_lock); --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/device.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/device.c @@ -108,6 +108,8 @@ list_del(&hpriv->dev_node); mutex_unlock(&hdev->fpriv_list_lock); + put_pid(hpriv->taskpid); + kfree(hpriv); return 0; @@ -229,16 +231,16 @@ static void device_cdev_sysfs_del(struct hl_device *hdev) { - /* device_release() won't be called so must free devices explicitly */ - if (!hdev->cdev_sysfs_created) { - kfree(hdev->dev_ctrl); - kfree(hdev->dev); - return; - } + if (!hdev->cdev_sysfs_created) + goto put_devices; hl_sysfs_fini(hdev); cdev_device_del(&hdev->cdev_ctrl, hdev->dev_ctrl); cdev_device_del(&hdev->cdev, hdev->dev); + +put_devices: + put_device(hdev->dev); + put_device(hdev->dev_ctrl); } /* @@ -600,7 +602,9 @@ goto out; } - hdev->asic_funcs->halt_coresight(hdev); + if (!hdev->hard_reset_pending) + hdev->asic_funcs->halt_coresight(hdev); + hdev->in_debug = 0; goto out; @@ -957,6 +961,7 @@ GFP_KERNEL); if (!hdev->kernel_ctx) { rc = -ENOMEM; + hl_mmu_fini(hdev); goto out_err; } @@ -968,6 +973,7 @@ "failed to init kernel ctx in hard reset\n"); kfree(hdev->kernel_ctx); hdev->kernel_ctx = NULL; + hl_mmu_fini(hdev); goto out_err; } } @@ -1185,6 +1191,7 @@ if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { dev_info(hdev->dev, "H/W state is dirty, must reset before initializing\n"); + hdev->asic_funcs->halt_engines(hdev, true); hdev->asic_funcs->hw_fini(hdev, true); } @@ -1282,9 +1289,9 @@ early_fini: device_early_fini(hdev); free_dev_ctrl: - kfree(hdev->dev_ctrl); + put_device(hdev->dev_ctrl); free_dev: - kfree(hdev->dev); + put_device(hdev->dev); out_disabled: hdev->disabled = true; if (add_cdev_sysfs_on_err) --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/firmware_if.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/firmware_if.c @@ -11,6 +11,7 @@ #include #include +#define FW_FILE_MAX_SIZE 0x1400000 /* maximum size of 20MB */ /** * hl_fw_push_fw_to_device() - Push FW code to device. * @hdev: pointer to hl_device structure. @@ -43,6 +44,14 @@ dev_dbg(hdev->dev, "%s firmware size == %zu\n", fw_name, fw_size); + if (fw_size > FW_FILE_MAX_SIZE) { + dev_err(hdev->dev, + "FW file size %zu exceeds maximum of %u bytes\n", + fw_size, FW_FILE_MAX_SIZE); + rc = -EINVAL; + goto out; + } + fw_data = (const u64 *) fw->data; memcpy_toio(dst, fw_data, fw_size); --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/goya/goya.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/goya/goya.c @@ -869,6 +869,11 @@ */ static void goya_disable_external_queues(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_DMA)) + return; + WREG32(mmDMA_QM_0_GLBL_CFG0, 0); WREG32(mmDMA_QM_1_GLBL_CFG0, 0); WREG32(mmDMA_QM_2_GLBL_CFG0, 0); @@ -930,6 +935,11 @@ { int rc, retval = 0; + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_DMA)) + return retval; + rc = goya_stop_queue(hdev, mmDMA_QM_0_GLBL_CFG1, mmDMA_QM_0_CP_STS, @@ -1719,9 +1729,18 @@ */ static void goya_disable_internal_queues(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_MME)) + goto disable_tpc; + WREG32(mmMME_QM_GLBL_CFG0, 0); WREG32(mmMME_CMDQ_GLBL_CFG0, 0); +disable_tpc: + if (!(goya->hw_cap_initialized & HW_CAP_TPC)) + return; + WREG32(mmTPC0_QM_GLBL_CFG0, 0); WREG32(mmTPC0_CMDQ_GLBL_CFG0, 0); @@ -1757,8 +1776,12 @@ */ static int goya_stop_internal_queues(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; int rc, retval = 0; + if (!(goya->hw_cap_initialized & HW_CAP_MME)) + goto stop_tpc; + /* * Each queue (QMAN) is a separate H/W logic. That means that each * QMAN can be stopped independently and failure to stop one does NOT @@ -1785,6 +1808,10 @@ retval = -EIO; } +stop_tpc: + if (!(goya->hw_cap_initialized & HW_CAP_TPC)) + return retval; + rc = goya_stop_queue(hdev, mmTPC0_QM_GLBL_CFG1, mmTPC0_QM_CP_STS, @@ -1950,6 +1977,11 @@ static void goya_dma_stall(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_DMA)) + return; + WREG32(mmDMA_QM_0_GLBL_CFG1, 1 << DMA_QM_0_GLBL_CFG1_DMA_STOP_SHIFT); WREG32(mmDMA_QM_1_GLBL_CFG1, 1 << DMA_QM_1_GLBL_CFG1_DMA_STOP_SHIFT); WREG32(mmDMA_QM_2_GLBL_CFG1, 1 << DMA_QM_2_GLBL_CFG1_DMA_STOP_SHIFT); @@ -1959,6 +1991,11 @@ static void goya_tpc_stall(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_TPC)) + return; + WREG32(mmTPC0_CFG_TPC_STALL, 1 << TPC0_CFG_TPC_STALL_V_SHIFT); WREG32(mmTPC1_CFG_TPC_STALL, 1 << TPC1_CFG_TPC_STALL_V_SHIFT); WREG32(mmTPC2_CFG_TPC_STALL, 1 << TPC2_CFG_TPC_STALL_V_SHIFT); @@ -1971,6 +2008,11 @@ static void goya_mme_stall(struct hl_device *hdev) { + struct goya_device *goya = hdev->asic_specific; + + if (!(goya->hw_cap_initialized & HW_CAP_MME)) + return; + WREG32(mmMME_STALL, 0xFFFFFFFF); } @@ -2171,7 +2213,7 @@ static int goya_pldm_init_cpu(struct hl_device *hdev) { - u32 val, unit_rst_val; + u32 unit_rst_val; int rc; /* Must initialize SRAM scrambler before pushing u-boot to SRAM */ @@ -2179,14 +2221,14 @@ /* Put ARM cores into reset */ WREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL, CPU_RESET_ASSERT); - val = RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL); + RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL); /* Reset the CA53 MACRO */ unit_rst_val = RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N); WREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N, CA53_RESET); - val = RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N); + RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N); WREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N, unit_rst_val); - val = RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N); + RREG32(mmPSOC_GLOBAL_CONF_UNIT_RST_N); rc = goya_push_uboot_to_device(hdev); if (rc) @@ -2207,7 +2249,7 @@ /* Release ARM core 0 from reset */ WREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL, CPU_RESET_CORE0_DEASSERT); - val = RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL); + RREG32(mmCPU_CA53_CFG_ARM_RST_CONTROL); return 0; } @@ -2475,13 +2517,12 @@ static int goya_hw_init(struct hl_device *hdev) { struct asic_fixed_properties *prop = &hdev->asic_prop; - u32 val; int rc; dev_info(hdev->dev, "Starting initialization of H/W\n"); /* Perform read from the device to make sure device is up */ - val = RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); + RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); /* * Let's mark in the H/W that we have reached this point. We check @@ -2533,7 +2574,7 @@ goto disable_queues; /* Perform read from the device to flush all MSI-X configuration */ - val = RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); + RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); return 0; @@ -4625,8 +4666,6 @@ rc = goya_send_job_on_qman0(hdev, job); - hl_cb_put(job->patched_cb); - hl_debugfs_remove_job(hdev, job); kfree(job); cb->cs_cnt--; --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/goya/goya_security.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/goya/goya_security.c @@ -695,7 +695,6 @@ mask |= 1 << ((mmTPC0_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC0_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC0_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); - mask |= 1 << ((mmTPC0_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC0_CFG_TPC_STALL & 0x7F) >> 2); mask |= 1 << ((mmTPC0_CFG_MSS_CONFIG & 0x7F) >> 2); mask |= 1 << ((mmTPC0_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); @@ -875,6 +874,16 @@ goya_pb_set_block(hdev, mmTPC1_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC1_WR_REGULATOR_BASE); + pb_addr = (mmTPC1_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC1_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC1_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC1_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC1_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -882,6 +891,10 @@ mask |= 1 << ((mmTPC1_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC1_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC1_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC1_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1057,6 +1070,16 @@ goya_pb_set_block(hdev, mmTPC2_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC2_WR_REGULATOR_BASE); + pb_addr = (mmTPC2_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC2_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC2_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC2_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC2_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1064,6 +1087,10 @@ mask |= 1 << ((mmTPC2_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC2_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC2_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC2_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1239,6 +1266,16 @@ goya_pb_set_block(hdev, mmTPC3_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC3_WR_REGULATOR_BASE); + pb_addr = (mmTPC3_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC3_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC3_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC3_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC3_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1246,6 +1283,10 @@ mask |= 1 << ((mmTPC3_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC3_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC3_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC3_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1421,6 +1462,16 @@ goya_pb_set_block(hdev, mmTPC4_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC4_WR_REGULATOR_BASE); + pb_addr = (mmTPC4_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC4_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC4_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC4_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC4_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1428,6 +1479,10 @@ mask |= 1 << ((mmTPC4_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC4_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC4_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC4_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1603,6 +1658,16 @@ goya_pb_set_block(hdev, mmTPC5_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC5_WR_REGULATOR_BASE); + pb_addr = (mmTPC5_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC5_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC5_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC5_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC5_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1610,6 +1675,10 @@ mask |= 1 << ((mmTPC5_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC5_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC5_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC5_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1785,6 +1854,16 @@ goya_pb_set_block(hdev, mmTPC6_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC6_WR_REGULATOR_BASE); + pb_addr = (mmTPC6_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC6_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC6_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC6_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC6_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1792,6 +1871,10 @@ mask |= 1 << ((mmTPC6_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC6_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC6_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC6_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); @@ -1967,6 +2050,16 @@ goya_pb_set_block(hdev, mmTPC7_RD_REGULATOR_BASE); goya_pb_set_block(hdev, mmTPC7_WR_REGULATOR_BASE); + pb_addr = (mmTPC7_CFG_SEMAPHORE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmTPC7_CFG_SEMAPHORE & PROT_BITS_OFFS) >> 7) << 2; + + mask = 1 << ((mmTPC7_CFG_SEMAPHORE & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_VFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_SFLAGS & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_STATUS & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + pb_addr = (mmTPC7_CFG_CFG_BASE_ADDRESS_HIGH & ~0xFFF) + PROT_BITS_OFFS; word_offset = ((mmTPC7_CFG_CFG_BASE_ADDRESS_HIGH & PROT_BITS_OFFS) >> 7) << 2; @@ -1974,6 +2067,10 @@ mask |= 1 << ((mmTPC7_CFG_CFG_SUBTRACT_VALUE & 0x7F) >> 2); mask |= 1 << ((mmTPC7_CFG_SM_BASE_ADDRESS_LOW & 0x7F) >> 2); mask |= 1 << ((mmTPC7_CFG_SM_BASE_ADDRESS_HIGH & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_TPC_STALL & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_MSS_CONFIG & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_TPC_INTR_CAUSE & 0x7F) >> 2); + mask |= 1 << ((mmTPC7_CFG_TPC_INTR_MASK & 0x7F) >> 2); WREG32(pb_addr + word_offset, ~mask); --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/habanalabs.h +++ linux-oracle-5.4.0/drivers/misc/habanalabs/habanalabs.h @@ -23,7 +23,7 @@ #define HL_MMAP_CB_MASK (0x8000000000000000ull >> PAGE_SHIFT) -#define HL_PENDING_RESET_PER_SEC 5 +#define HL_PENDING_RESET_PER_SEC 30 #define HL_DEVICE_TIMEOUT_USEC 1000000 /* 1 s */ --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/habanalabs_drv.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/habanalabs_drv.c @@ -443,6 +443,7 @@ .id_table = ids, .probe = hl_pci_probe, .remove = hl_pci_remove, + .shutdown = hl_pci_remove, .driver.pm = &hl_pm_ops, }; --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/memory.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/memory.c @@ -67,6 +67,11 @@ num_pgs = (args->alloc.mem_size + (page_size - 1)) >> page_shift; total_size = num_pgs << page_shift; + if (!total_size) { + dev_err(hdev->dev, "Cannot allocate 0 bytes\n"); + return -EINVAL; + } + contiguous = args->flags & HL_MEM_CONTIGUOUS; if (contiguous) { @@ -94,7 +99,7 @@ phys_pg_pack->contiguous = contiguous; phys_pg_pack->pages = kvmalloc_array(num_pgs, sizeof(u64), GFP_KERNEL); - if (!phys_pg_pack->pages) { + if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) { rc = -ENOMEM; goto pages_arr_err; } @@ -689,7 +694,7 @@ phys_pg_pack->pages = kvmalloc_array(total_npages, sizeof(u64), GFP_KERNEL); - if (!phys_pg_pack->pages) { + if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) { rc = -ENOMEM; goto page_pack_arr_mem_err; } @@ -965,17 +970,19 @@ * * @ctx : current context * @vaddr : device virtual address to unmap + * @ctx_free : true if in context free flow, false otherwise. * * This function does the following: * - Unmap the physical pages related to the given virtual address * - return the device virtual block to the virtual block list */ -static int unmap_device_va(struct hl_ctx *ctx, u64 vaddr) +static int unmap_device_va(struct hl_ctx *ctx, u64 vaddr, bool ctx_free) { struct hl_device *hdev = ctx->hdev; struct hl_vm_phys_pg_pack *phys_pg_pack = NULL; struct hl_vm_hash_node *hnode = NULL; struct hl_userptr *userptr = NULL; + struct hl_va_range *va_range; enum vm_type_t *vm_type; u64 next_vaddr, i; u32 page_size; @@ -1003,6 +1010,7 @@ if (*vm_type == VM_TYPE_USERPTR) { is_userptr = true; + va_range = &ctx->host_va_range; userptr = hnode->ptr; rc = init_phys_pg_pack_from_userptr(ctx, userptr, &phys_pg_pack); @@ -1014,6 +1022,7 @@ } } else if (*vm_type == VM_TYPE_PHYS_PACK) { is_userptr = false; + va_range = &ctx->dram_va_range; phys_pg_pack = hnode->ptr; } else { dev_warn(hdev->dev, @@ -1052,12 +1061,18 @@ mutex_unlock(&ctx->mmu_lock); - if (add_va_block(hdev, - is_userptr ? &ctx->host_va_range : &ctx->dram_va_range, - vaddr, - vaddr + phys_pg_pack->total_size - 1)) - dev_warn(hdev->dev, "add va block failed for vaddr: 0x%llx\n", - vaddr); + /* + * No point in maintaining the free VA block list if the context is + * closing as the list will be freed anyway + */ + if (!ctx_free) { + rc = add_va_block(hdev, va_range, vaddr, + vaddr + phys_pg_pack->total_size - 1); + if (rc) + dev_warn(hdev->dev, + "add va block failed for vaddr: 0x%llx\n", + vaddr); + } atomic_dec(&phys_pg_pack->mapping_cnt); kfree(hnode); @@ -1189,8 +1204,8 @@ break; case HL_MEM_OP_UNMAP: - rc = unmap_device_va(ctx, - args->in.unmap.device_virt_addr); + rc = unmap_device_va(ctx, args->in.unmap.device_virt_addr, + false); break; default: @@ -1620,7 +1635,7 @@ dev_dbg(hdev->dev, "hl_mem_hash_node of vaddr 0x%llx of asid %d is still alive\n", hnode->vaddr, ctx->asid); - unmap_device_va(ctx, hnode->vaddr); + unmap_device_va(ctx, hnode->vaddr, true); } spin_lock(&vm->idr_lock); --- linux-oracle-5.4.0.orig/drivers/misc/habanalabs/mmu.c +++ linux-oracle-5.4.0/drivers/misc/habanalabs/mmu.c @@ -422,7 +422,7 @@ hdev->mmu_shadow_hop0 = kvmalloc_array(prop->max_asid, prop->mmu_hop_table_size, GFP_KERNEL | __GFP_ZERO); - if (!hdev->mmu_shadow_hop0) { + if (ZERO_OR_NULL_PTR(hdev->mmu_shadow_hop0)) { rc = -ENOMEM; goto err_pool_add; } --- linux-oracle-5.4.0.orig/drivers/misc/ibmasm/module.c +++ linux-oracle-5.4.0/drivers/misc/ibmasm/module.c @@ -111,7 +111,7 @@ result = ibmasm_init_remote_input_dev(sp); if (result) { dev_err(sp->dev, "Failed to initialize remote queue\n"); - goto error_send_message; + goto error_init_remote; } result = ibmasm_send_driver_vpd(sp); @@ -131,8 +131,9 @@ return 0; error_send_message: - disable_sp_interrupts(sp->base_address); ibmasm_free_remote_input_dev(sp); +error_init_remote: + disable_sp_interrupts(sp->base_address); free_irq(sp->irq, (void *)sp); error_request_irq: iounmap(sp->base_address); --- linux-oracle-5.4.0.orig/drivers/misc/ics932s401.c +++ linux-oracle-5.4.0/drivers/misc/ics932s401.c @@ -134,7 +134,7 @@ for (i = 0; i < NUM_MIRRORED_REGS; i++) { temp = i2c_smbus_read_word_data(client, regs_to_copy[i]); if (temp < 0) - data->regs[regs_to_copy[i]] = 0; + temp = 0; data->regs[regs_to_copy[i]] = temp >> 8; } --- linux-oracle-5.4.0.orig/drivers/misc/kgdbts.c +++ linux-oracle-5.4.0/drivers/misc/kgdbts.c @@ -95,19 +95,20 @@ #include -#define v1printk(a...) do { \ - if (verbose) \ - printk(KERN_INFO a); \ - } while (0) -#define v2printk(a...) do { \ - if (verbose > 1) \ - printk(KERN_INFO a); \ - touch_nmi_watchdog(); \ - } while (0) -#define eprintk(a...) do { \ - printk(KERN_ERR a); \ - WARN_ON(1); \ - } while (0) +#define v1printk(a...) do { \ + if (verbose) \ + printk(KERN_INFO a); \ +} while (0) +#define v2printk(a...) do { \ + if (verbose > 1) { \ + printk(KERN_INFO a); \ + } \ + touch_nmi_watchdog(); \ +} while (0) +#define eprintk(a...) do { \ + printk(KERN_ERR a); \ + WARN_ON(1); \ +} while (0) #define MAX_CONFIG_LEN 40 static struct kgdb_io kgdbts_io_ops; @@ -1059,10 +1060,10 @@ { if (strlen(opt) >= MAX_CONFIG_LEN) { printk(KERN_ERR "kgdbts: config string too long\n"); - return -ENOSPC; + return 1; } strcpy(config, opt); - return 0; + return 1; } __setup("kgdbts=", kgdbts_option_setup); --- linux-oracle-5.4.0.orig/drivers/misc/lattice-ecp3-config.c +++ linux-oracle-5.4.0/drivers/misc/lattice-ecp3-config.c @@ -77,12 +77,12 @@ if (fw == NULL) { dev_err(&spi->dev, "Cannot load firmware, aborting\n"); - return; + goto out; } if (fw->size == 0) { dev_err(&spi->dev, "Error: Firmware size is 0!\n"); - return; + goto out; } /* Fill dummy data (24 stuffing bits for commands) */ @@ -104,7 +104,7 @@ dev_err(&spi->dev, "Error: No supported FPGA detected (JEDEC_ID=%08x)!\n", jedec_id); - return; + goto out; } dev_info(&spi->dev, "FPGA %s detected\n", ecp3_dev[i].name); @@ -117,7 +117,7 @@ buffer = kzalloc(fw->size + 8, GFP_KERNEL); if (!buffer) { dev_err(&spi->dev, "Error: Can't allocate memory!\n"); - return; + goto out; } /* @@ -156,7 +156,7 @@ "Error: Timeout waiting for FPGA to clear (status=%08x)!\n", status); kfree(buffer); - return; + goto out; } dev_info(&spi->dev, "Configuring the FPGA...\n"); @@ -182,7 +182,7 @@ release_firmware(fw); kfree(buffer); - +out: complete(&data->fw_loaded); } --- linux-oracle-5.4.0.orig/drivers/misc/lis3lv02d/lis3lv02d.c +++ linux-oracle-5.4.0/drivers/misc/lis3lv02d/lis3lv02d.c @@ -208,7 +208,7 @@ static int lis3_3dlh_rates[4] = {50, 100, 400, 1000}; /* ODR is Output Data Rate */ -static int lis3lv02d_get_odr(struct lis3lv02d *lis3) +static int lis3lv02d_get_odr_index(struct lis3lv02d *lis3) { u8 ctrl; int shift; @@ -216,15 +216,23 @@ lis3->read(lis3, CTRL_REG1, &ctrl); ctrl &= lis3->odr_mask; shift = ffs(lis3->odr_mask) - 1; - return lis3->odrs[(ctrl >> shift)]; + return (ctrl >> shift); } static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) { - int div = lis3lv02d_get_odr(lis3); + int odr_idx = lis3lv02d_get_odr_index(lis3); + int div = lis3->odrs[odr_idx]; - if (WARN_ONCE(div == 0, "device returned spurious data")) + if (div == 0) { + if (odr_idx == 0) { + /* Power-down mode, not sampling no need to sleep */ + return 0; + } + + dev_err(&lis3->pdev->dev, "Error unknown odrs-index: %d\n", odr_idx); return -ENXIO; + } /* LIS3 power on delay is quite long */ msleep(lis3->pwron_delay / div); @@ -807,9 +815,12 @@ struct device_attribute *attr, char *buf) { struct lis3lv02d *lis3 = dev_get_drvdata(dev); + int odr_idx; lis3lv02d_sysfs_poweron(lis3); - return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3)); + + odr_idx = lis3lv02d_get_odr_index(lis3); + return sprintf(buf, "%d\n", lis3->odrs[odr_idx]); } static ssize_t lis3lv02d_rate_set(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/misc/lis3lv02d/lis3lv02d.h +++ linux-oracle-5.4.0/drivers/misc/lis3lv02d/lis3lv02d.h @@ -271,6 +271,7 @@ int regs_size; u8 *reg_cache; bool regs_stored; + bool init_required; u8 odr_mask; /* ODR bit mask */ u8 whoami; /* indicates measurement precision */ s16 (*read_data) (struct lis3lv02d *lis3, int reg); --- linux-oracle-5.4.0.orig/drivers/misc/lkdtm/Makefile +++ linux-oracle-5.4.0/drivers/misc/lkdtm/Makefile @@ -16,7 +16,7 @@ OBJCOPYFLAGS := OBJCOPYFLAGS_rodata_objcopy.o := \ - --rename-section .text=.rodata,alloc,readonly,load + --rename-section .noinstr.text=.rodata,alloc,readonly,load,contents targets += rodata.o rodata_objcopy.o $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE $(call if_changed,objcopy) --- linux-oracle-5.4.0.orig/drivers/misc/lkdtm/bugs.c +++ linux-oracle-5.4.0/drivers/misc/lkdtm/bugs.c @@ -274,7 +274,7 @@ void lkdtm_UNSET_SMEP(void) { -#ifdef CONFIG_X86_64 +#if IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_UML) #define MOV_CR4_DEPTH 64 void (*direct_write_cr4)(unsigned long val); unsigned char *insn; --- linux-oracle-5.4.0.orig/drivers/misc/lkdtm/refcount.c +++ linux-oracle-5.4.0/drivers/misc/lkdtm/refcount.c @@ -6,14 +6,6 @@ #include "lkdtm.h" #include -#ifdef CONFIG_REFCOUNT_FULL -#define REFCOUNT_MAX (UINT_MAX - 1) -#define REFCOUNT_SATURATED UINT_MAX -#else -#define REFCOUNT_MAX INT_MAX -#define REFCOUNT_SATURATED (INT_MIN / 2) -#endif - static void overflow_check(refcount_t *ref) { switch (refcount_read(ref)) { --- linux-oracle-5.4.0.orig/drivers/misc/lkdtm/rodata.c +++ linux-oracle-5.4.0/drivers/misc/lkdtm/rodata.c @@ -5,7 +5,7 @@ */ #include "lkdtm.h" -void notrace lkdtm_rodata_do_nothing(void) +void noinstr lkdtm_rodata_do_nothing(void) { /* Does nothing. We just want an architecture agnostic "return". */ } --- linux-oracle-5.4.0.orig/drivers/misc/lkdtm/usercopy.c +++ linux-oracle-5.4.0/drivers/misc/lkdtm/usercopy.c @@ -30,12 +30,12 @@ */ static noinline unsigned char *trick_compiler(unsigned char *stack) { - return stack + 0; + return stack + unconst; } static noinline unsigned char *do_usercopy_stack_callee(int value) { - unsigned char buf[32]; + unsigned char buf[128]; int i; /* Exercise stack to avoid everything living in registers. */ @@ -43,7 +43,12 @@ buf[i] = value & 0xff; } - return trick_compiler(buf); + /* + * Put the target buffer in the middle of stack allocation + * so that we don't step on future stack users regardless + * of stack growth direction. + */ + return trick_compiler(&buf[(128/2)-32]); } static noinline void do_usercopy_stack(bool to_user, bool bad_frame) @@ -66,6 +71,12 @@ bad_stack -= sizeof(unsigned long); } +#ifdef ARCH_HAS_CURRENT_STACK_POINTER + pr_info("stack : %px\n", (void *)current_stack_pointer); +#endif + pr_info("good_stack: %px-%px\n", good_stack, good_stack + sizeof(good_stack)); + pr_info("bad_stack : %px-%px\n", bad_stack, bad_stack + sizeof(good_stack)); + user_addr = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0); --- linux-oracle-5.4.0.orig/drivers/misc/mei/bus-fixup.c +++ linux-oracle-5.4.0/drivers/misc/mei/bus-fixup.c @@ -178,7 +178,7 @@ ret = __mei_cl_send(cldev->cl, buf, sizeof(struct mkhi_msg_hdr), MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); + dev_err(&cldev->dev, "Could not send ReqFWVersion cmd ret = %d\n", ret); return ret; } @@ -190,7 +190,7 @@ * Should be at least one version block, * error out if nothing found */ - dev_err(&cldev->dev, "Could not read FW version\n"); + dev_err(&cldev->dev, "Could not read FW version ret = %d\n", bytes_recv); return -EIO; } @@ -339,7 +339,7 @@ ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(struct mei_nfc_cmd), MEI_CL_IO_TX_BLOCKING); if (ret < 0) { - dev_err(bus->dev, "Could not send IF version cmd\n"); + dev_err(bus->dev, "Could not send IF version cmd ret = %d\n", ret); return ret; } @@ -354,7 +354,7 @@ ret = 0; bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0); if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) { - dev_err(bus->dev, "Could not read IF version\n"); + dev_err(bus->dev, "Could not read IF version ret = %d\n", bytes_recv); ret = -EIO; goto err; } --- linux-oracle-5.4.0.orig/drivers/misc/mei/bus.c +++ linux-oracle-5.4.0/drivers/misc/mei/bus.c @@ -745,9 +745,8 @@ mei_cl_bus_module_put(cldev); module_put(THIS_MODULE); - dev->driver = NULL; - return ret; + return ret; } static ssize_t name_show(struct device *dev, struct device_attribute *a, @@ -873,15 +872,16 @@ /** * mei_cl_bus_set_name - set device name for me client device + * - + * Example: 0000:00:16.0-55213584-9a29-4916-badf-0fb7ed682aeb * * @cldev: me client device */ static inline void mei_cl_bus_set_name(struct mei_cl_device *cldev) { - dev_set_name(&cldev->dev, "mei:%s:%pUl:%02X", - cldev->name, - mei_me_cl_uuid(cldev->me_cl), - mei_me_cl_ver(cldev->me_cl)); + dev_set_name(&cldev->dev, "%s-%pUl", + dev_name(cldev->bus->dev), + mei_me_cl_uuid(cldev->me_cl)); } /** --- linux-oracle-5.4.0.orig/drivers/misc/mei/client.c +++ linux-oracle-5.4.0/drivers/misc/mei/client.c @@ -266,6 +266,7 @@ down_write(&dev->me_clients_rwsem); me_cl = __mei_me_cl_by_uuid(dev, uuid); __mei_me_cl_del(dev, me_cl); + mei_me_cl_put(me_cl); up_write(&dev->me_clients_rwsem); } @@ -287,6 +288,7 @@ down_write(&dev->me_clients_rwsem); me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id); __mei_me_cl_del(dev, me_cl); + mei_me_cl_put(me_cl); up_write(&dev->me_clients_rwsem); } --- linux-oracle-5.4.0.orig/drivers/misc/mei/client.h +++ linux-oracle-5.4.0/drivers/misc/mei/client.h @@ -128,11 +128,11 @@ * * @cl: host client * - * Return: mtu + * Return: mtu or 0 if client is not connected */ static inline size_t mei_cl_mtu(const struct mei_cl *cl) { - return cl->me_cl->props.max_msg_length; + return cl->me_cl ? cl->me_cl->props.max_msg_length : 0; } /** --- linux-oracle-5.4.0.orig/drivers/misc/mei/hbm.c +++ linux-oracle-5.4.0/drivers/misc/mei/hbm.c @@ -1300,7 +1300,7 @@ return -EPROTO; } - dev->dev_state = MEI_DEV_POWER_DOWN; + mei_set_devstate(dev, MEI_DEV_POWER_DOWN); dev_info(dev->dev, "hbm: stop response: resetting.\n"); /* force the reset */ return -EPROTO; --- linux-oracle-5.4.0.orig/drivers/misc/mei/hdcp/mei_hdcp.c +++ linux-oracle-5.4.0/drivers/misc/mei/hdcp/mei_hdcp.c @@ -758,11 +758,38 @@ .unbind = mei_component_master_unbind, }; +/** + * mei_hdcp_component_match - compare function for matching mei hdcp. + * + * The function checks if the driver is i915, the subcomponent is HDCP + * and the grand parent of hdcp and the parent of i915 are the same + * PCH device. + * + * @dev: master device + * @subcomponent: subcomponent to match (I915_COMPONENT_HDCP) + * @data: compare data (mei hdcp device) + * + * Return: + * * 1 - if components match + * * 0 - otherwise + */ static int mei_hdcp_component_match(struct device *dev, int subcomponent, void *data) { - return !strcmp(dev->driver->name, "i915") && - subcomponent == I915_COMPONENT_HDCP; + struct device *base = data; + + if (strcmp(dev->driver->name, "i915") || + subcomponent != I915_COMPONENT_HDCP) + return 0; + + base = base->parent; + if (!base) + return 0; + + base = base->parent; + dev = dev->parent; + + return (base && dev && dev == base); } static int mei_hdcp_probe(struct mei_cl_device *cldev, @@ -786,7 +813,7 @@ master_match = NULL; component_match_add_typed(&cldev->dev, &master_match, - mei_hdcp_component_match, comp_master); + mei_hdcp_component_match, &cldev->dev); if (IS_ERR_OR_NULL(master_match)) { ret = -ENOMEM; goto err_exit; --- linux-oracle-5.4.0.orig/drivers/misc/mei/hw-me-regs.h +++ linux-oracle-5.4.0/drivers/misc/mei/hw-me-regs.h @@ -82,7 +82,15 @@ #define MEI_DEV_ID_CMP_LP 0x02e0 /* Comet Point LP */ #define MEI_DEV_ID_CMP_LP_3 0x02e4 /* Comet Point LP 3 (iTouch) */ +#define MEI_DEV_ID_CMP_V 0xA3BA /* Comet Point Lake V */ + +#define MEI_DEV_ID_CMP_H 0x06e0 /* Comet Lake H */ +#define MEI_DEV_ID_CMP_H_3 0x06e4 /* Comet Lake H 3 (iTouch) */ + +#define MEI_DEV_ID_CDF 0x18D3 /* Cedar Fork */ + #define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */ +#define MEI_DEV_ID_ICP_N 0x38E0 /* Ice Lake Point N */ #define MEI_DEV_ID_TGP_LP 0xA0E0 /* Tiger Lake Point LP */ --- linux-oracle-5.4.0.orig/drivers/misc/mei/interrupt.c +++ linux-oracle-5.4.0/drivers/misc/mei/interrupt.c @@ -222,6 +222,9 @@ return ret; } + pm_runtime_mark_last_busy(dev->dev); + pm_request_autosuspend(dev->dev); + list_move_tail(&cb->list, &cl->rd_pending); return 0; --- linux-oracle-5.4.0.orig/drivers/misc/mei/main.c +++ linux-oracle-5.4.0/drivers/misc/mei/main.c @@ -268,7 +268,7 @@ } if (!mei_cl_is_connected(cl)) { - cl_err(dev, cl, "is not connected"); + cl_dbg(dev, cl, "is not connected"); rets = -ENODEV; goto out; } --- linux-oracle-5.4.0.orig/drivers/misc/mei/pci-me.c +++ linux-oracle-5.4.0/drivers/misc/mei/pci-me.c @@ -32,6 +32,9 @@ #include "hw-me-regs.h" #include "hw-me.h" +static bool disable_msi; +module_param(disable_msi, bool, 0); + /* mei_pci_tbl - PCI Device ID Table */ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, MEI_ME_ICH_CFG)}, @@ -98,14 +101,20 @@ {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_V, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_N, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_CDF, MEI_ME_PCH8_CFG)}, + /* required last entry */ {0, } }; @@ -199,7 +208,8 @@ hw = to_me_hw(dev); hw->mem_addr = pcim_iomap_table(pdev)[0]; - pci_enable_msi(pdev); + if (!disable_msi) + pci_enable_msi(pdev); /* request and enable interrupt */ irqflags = pci_dev_msi_enabled(pdev) ? IRQF_ONESHOT : IRQF_SHARED; @@ -373,8 +383,10 @@ } err = mei_restart(dev); - if (err) + if (err) { + free_irq(pdev->irq, dev); return err; + } /* Start timer if stopped in suspend */ schedule_delayed_work(&dev->timer_work, HZ); --- linux-oracle-5.4.0.orig/drivers/misc/mic/scif/scif_rma.c +++ linux-oracle-5.4.0/drivers/misc/mic/scif/scif_rma.c @@ -1381,6 +1381,8 @@ (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0, pinned_pages->pages); if (nr_pages != pinned_pages->nr_pages) { + if (pinned_pages->nr_pages < 0) + pinned_pages->nr_pages = 0; if (try_upgrade) { if (ulimit) __scif_dec_pinned_vm_lock(mm, nr_pages); @@ -1400,7 +1402,6 @@ if (pinned_pages->nr_pages < nr_pages) { err = -EFAULT; - pinned_pages->nr_pages = nr_pages; goto dec_pinned; } @@ -1413,7 +1414,6 @@ __scif_dec_pinned_vm_lock(mm, nr_pages); /* Something went wrong! Rollback */ error_unmap: - pinned_pages->nr_pages = nr_pages; scif_destroy_pinned_pages(pinned_pages); *pages = NULL; dev_dbg(scif_info.mdev.this_device, --- linux-oracle-5.4.0.orig/drivers/misc/mic/vop/vop_main.c +++ linux-oracle-5.4.0/drivers/misc/mic/vop/vop_main.c @@ -320,7 +320,7 @@ /* First assign the vring's allocated in host memory */ vqconfig = _vop_vq_config(vdev->desc) + index; memcpy_fromio(&config, vqconfig, sizeof(config)); - _vr_size = vring_size(le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN); + _vr_size = round_up(vring_size(le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN), 4); vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info)); va = vpdev->hw_ops->remap(vpdev, le64_to_cpu(config.address), vr_size); if (!va) --- linux-oracle-5.4.0.orig/drivers/misc/mic/vop/vop_vringh.c +++ linux-oracle-5.4.0/drivers/misc/mic/vop/vop_vringh.c @@ -296,7 +296,7 @@ num = le16_to_cpu(vqconfig[i].num); mutex_init(&vvr->vr_mutex); - vr_size = PAGE_ALIGN(vring_size(num, MIC_VIRTIO_RING_ALIGN) + + vr_size = PAGE_ALIGN(round_up(vring_size(num, MIC_VIRTIO_RING_ALIGN), 4) + sizeof(struct _mic_vring_info)); vr->va = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, @@ -308,7 +308,7 @@ goto err; } vr->len = vr_size; - vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN); + vr->info = vr->va + round_up(vring_size(num, MIC_VIRTIO_RING_ALIGN), 4); vr->info->magic = cpu_to_le32(MIC_MAGIC + vdev->virtio_id + i); vr_addr = dma_map_single(&vpdev->dev, vr->va, vr_size, DMA_BIDIRECTIONAL); @@ -602,6 +602,7 @@ size_t partlen; bool dma = VOP_USE_DMA && vi->dma_ch; int err = 0; + size_t offset = 0; if (dma) { dma_alignment = 1 << vi->dma_ch->device->copy_align; @@ -655,13 +656,20 @@ * We are copying to IO below and should ideally use something * like copy_from_user_toio(..) if it existed. */ - if (copy_from_user((void __force *)dbuf, ubuf, len)) { - err = -EFAULT; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; + while (len) { + partlen = min_t(size_t, len, VOP_INT_DMA_BUF_SIZE); + + if (copy_from_user(vvr->buf, ubuf + offset, partlen)) { + err = -EFAULT; + dev_err(vop_dev(vdev), "%s %d err %d\n", + __func__, __LINE__, err); + goto err; + } + memcpy_toio(dbuf + offset, vvr->buf, partlen); + offset += partlen; + vdev->out_bytes += partlen; + len -= partlen; } - vdev->out_bytes += len; err = 0; err: vpdev->hw_ops->unmap(vpdev, dbuf); --- linux-oracle-5.4.0.orig/drivers/misc/ocxl/Kconfig +++ linux-oracle-5.4.0/drivers/misc/ocxl/Kconfig @@ -11,6 +11,7 @@ tristate "OpenCAPI coherent accelerator support" depends on PPC_POWERNV && PCI && EEH select OCXL_BASE + select HOTPLUG_PCI_POWERNV default m help Select this option to enable the ocxl driver for Open --- linux-oracle-5.4.0.orig/drivers/misc/ocxl/context.c +++ linux-oracle-5.4.0/drivers/misc/ocxl/context.c @@ -10,18 +10,17 @@ int pasid; struct ocxl_context *ctx; - *context = kzalloc(sizeof(struct ocxl_context), GFP_KERNEL); - if (!*context) + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) return -ENOMEM; - ctx = *context; - ctx->afu = afu; mutex_lock(&afu->contexts_lock); pasid = idr_alloc(&afu->contexts_idr, ctx, afu->pasid_base, afu->pasid_base + afu->pasid_max, GFP_KERNEL); if (pasid < 0) { mutex_unlock(&afu->contexts_lock); + kfree(ctx); return pasid; } afu->pasid_count++; @@ -43,6 +42,7 @@ * duration of the life of the context */ ocxl_afu_get(afu); + *context = ctx; return 0; } EXPORT_SYMBOL_GPL(ocxl_context_alloc); --- linux-oracle-5.4.0.orig/drivers/misc/ocxl/file.c +++ linux-oracle-5.4.0/drivers/misc/ocxl/file.c @@ -18,18 +18,15 @@ static struct mutex minors_idr_lock; static struct idr minors_idr; -static struct ocxl_file_info *find_file_info(dev_t devno) +static struct ocxl_file_info *find_and_get_file_info(dev_t devno) { struct ocxl_file_info *info; - /* - * We don't declare an RCU critical section here, as our AFU - * is protected by a reference counter on the device. By the time the - * info reference is removed from the idr, the ref count of - * the device is already at 0, so no user API will access that AFU and - * this function can't return it. - */ + mutex_lock(&minors_idr_lock); info = idr_find(&minors_idr, MINOR(devno)); + if (info) + get_device(&info->dev); + mutex_unlock(&minors_idr_lock); return info; } @@ -58,14 +55,16 @@ pr_debug("%s for device %x\n", __func__, inode->i_rdev); - info = find_file_info(inode->i_rdev); + info = find_and_get_file_info(inode->i_rdev); if (!info) return -ENODEV; rc = ocxl_context_alloc(&ctx, info->afu, inode->i_mapping); - if (rc) + if (rc) { + put_device(&info->dev); return rc; - + } + put_device(&info->dev); file->private_data = ctx; return 0; } @@ -260,6 +259,8 @@ if (IS_ERR(ev_ctx)) return PTR_ERR(ev_ctx); rc = ocxl_irq_set_handler(ctx, irq_id, irq_handler, irq_free, ev_ctx); + if (rc) + eventfd_ctx_put(ev_ctx); break; case OCXL_IOCTL_GET_METADATA: @@ -487,7 +488,6 @@ { struct ocxl_file_info *info = container_of(dev, struct ocxl_file_info, dev); - free_minor(info); ocxl_afu_put(info->afu); kfree(info); } @@ -543,8 +543,11 @@ goto err_put; rc = device_register(&info->dev); - if (rc) - goto err_put; + if (rc) { + free_minor(info); + put_device(&info->dev); + return rc; + } rc = ocxl_sysfs_register_afu(info); if (rc) @@ -560,7 +563,9 @@ err_unregister: ocxl_sysfs_unregister_afu(info); // safe to call even if register failed + free_minor(info); device_unregister(&info->dev); + return rc; err_put: ocxl_afu_put(afu); free_minor(info); @@ -577,6 +582,7 @@ ocxl_file_make_invisible(info); ocxl_sysfs_unregister_afu(info); + free_minor(info); device_unregister(&info->dev); } --- linux-oracle-5.4.0.orig/drivers/misc/pci_endpoint_test.c +++ linux-oracle-5.4.0/drivers/misc/pci_endpoint_test.c @@ -98,6 +98,7 @@ struct completion irq_raised; int last_irq; int num_irqs; + int irq_type; /* mutex to protect the ioctls */ struct mutex mutex; struct miscdevice miscdev; @@ -157,6 +158,7 @@ struct pci_dev *pdev = test->pdev; pci_free_irq_vectors(pdev); + test->irq_type = IRQ_TYPE_UNDEFINED; } static bool pci_endpoint_test_alloc_irq_vectors(struct pci_endpoint_test *test, @@ -191,6 +193,8 @@ irq = 0; res = false; } + + test->irq_type = type; test->num_irqs = irq; return res; @@ -330,6 +334,7 @@ dma_addr_t orig_dst_phys_addr; size_t offset; size_t alignment = test->alignment; + int irq_type = test->irq_type; u32 src_crc32; u32 dst_crc32; @@ -426,6 +431,7 @@ dma_addr_t orig_phys_addr; size_t offset; size_t alignment = test->alignment; + int irq_type = test->irq_type; u32 crc32; if (size > SIZE_MAX - alignment) @@ -494,6 +500,7 @@ dma_addr_t orig_phys_addr; size_t offset; size_t alignment = test->alignment; + int irq_type = test->irq_type; u32 crc32; if (size > SIZE_MAX - alignment) @@ -555,7 +562,7 @@ return false; } - if (irq_type == req_irq_type) + if (test->irq_type == req_irq_type) return true; pci_endpoint_test_release_irq(test); @@ -567,12 +574,10 @@ if (!pci_endpoint_test_request_irq(test)) goto err; - irq_type = req_irq_type; return true; err: pci_endpoint_test_free_irq_vectors(test); - irq_type = IRQ_TYPE_UNDEFINED; return false; } @@ -585,6 +590,10 @@ struct pci_dev *pdev = test->pdev; mutex_lock(&test->mutex); + + reinit_completion(&test->irq_raised); + test->last_irq = -ENODATA; + switch (cmd) { case PCITEST_BAR: bar = arg; @@ -633,7 +642,7 @@ { int err; int id; - char name[20]; + char name[24]; enum pci_barno bar; void __iomem *base; struct device *dev = &pdev->dev; @@ -652,6 +661,7 @@ test->test_reg_bar = 0; test->alignment = 0; test->pdev = pdev; + test->irq_type = IRQ_TYPE_UNDEFINED; if (no_msi) irq_type = IRQ_TYPE_LEGACY; @@ -768,6 +778,9 @@ if (id < 0) return; + pci_endpoint_test_release_irq(test); + pci_endpoint_test_free_irq_vectors(test); + misc_deregister(&test->miscdev); kfree(misc_device->name); ida_simple_remove(&pci_endpoint_test_ida, id); @@ -776,9 +789,6 @@ pci_iounmap(pdev, test->bar[bar]); } - pci_endpoint_test_release_irq(test); - pci_endpoint_test_free_irq_vectors(test); - pci_release_regions(pdev); pci_disable_device(pdev); } --- linux-oracle-5.4.0.orig/drivers/misc/pvpanic.c +++ linux-oracle-5.4.0/drivers/misc/pvpanic.c @@ -166,6 +166,7 @@ { .compatible = "qemu,pvpanic-mmio", }, {} }; +MODULE_DEVICE_TABLE(of, pvpanic_mmio_match); static struct platform_driver pvpanic_mmio_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/misc/sgi-gru/grufault.c +++ linux-oracle-5.4.0/drivers/misc/sgi-gru/grufault.c @@ -648,6 +648,7 @@ if ((cb & (GRU_HANDLE_STRIDE - 1)) || ucbnum >= GRU_NUM_CB) return -EINVAL; +again: gts = gru_find_lock_gts(cb); if (!gts) return -EINVAL; @@ -656,7 +657,11 @@ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) goto exit; - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + gru_unlock_gts(gts); + gru_unload_context(gts, 1); + goto again; + } /* * CCH may contain stale data if ts_force_cch_reload is set. @@ -874,7 +879,11 @@ } else { gts->ts_user_blade_id = req.val1; gts->ts_user_chiplet_id = req.val0; - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + gru_unlock_gts(gts); + gru_unload_context(gts, 1); + return ret; + } } break; case sco_gseg_owner: --- linux-oracle-5.4.0.orig/drivers/misc/sgi-gru/grukservices.c +++ linux-oracle-5.4.0/drivers/misc/sgi-gru/grukservices.c @@ -257,7 +257,6 @@ int lcpu; BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); - preempt_disable(); bs = gru_lock_kernel_context(-1); lcpu = uv_blade_processor_id(); *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; @@ -271,7 +270,6 @@ static void gru_free_cpu_resources(void *cb, void *dsr) { gru_unlock_kernel_context(uv_numa_blade_id()); - preempt_enable(); } /* --- linux-oracle-5.4.0.orig/drivers/misc/sgi-gru/grumain.c +++ linux-oracle-5.4.0/drivers/misc/sgi-gru/grumain.c @@ -716,9 +716,10 @@ * chiplet. Misassignment can occur if the process migrates to a different * blade or if the user changes the selected blade/chiplet. */ -void gru_check_context_placement(struct gru_thread_state *gts) +int gru_check_context_placement(struct gru_thread_state *gts) { struct gru_state *gru; + int ret = 0; /* * If the current task is the context owner, verify that the @@ -726,15 +727,23 @@ * references. Pthread apps use non-owner references to the CBRs. */ gru = gts->ts_gru; + /* + * If gru or gts->ts_tgid_owner isn't initialized properly, return + * success to indicate that the caller does not need to unload the + * gru context.The caller is responsible for their inspection and + * reinitialization if needed. + */ if (!gru || gts->ts_tgid_owner != current->tgid) - return; + return ret; if (!gru_check_chiplet_assignment(gru, gts)) { STAT(check_context_unload); - gru_unload_context(gts, 1); + ret = -EINVAL; } else if (gru_retarget_intr(gts)) { STAT(check_context_retarget_intr); } + + return ret; } @@ -932,14 +941,16 @@ again: mutex_lock(>s->ts_ctxlock); - preempt_disable(); - gru_check_context_placement(gts); + if (gru_check_context_placement(gts)) { + mutex_unlock(>s->ts_ctxlock); + gru_unload_context(gts, 1); + return VM_FAULT_NOPAGE; + } if (!gts->ts_gru) { STAT(load_user_context); if (!gru_assign_gru_context(gts)) { - preempt_enable(); mutex_unlock(>s->ts_ctxlock); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ @@ -955,7 +966,6 @@ vma->vm_page_prot); } - preempt_enable(); mutex_unlock(>s->ts_ctxlock); return VM_FAULT_NOPAGE; --- linux-oracle-5.4.0.orig/drivers/misc/sgi-gru/grutables.h +++ linux-oracle-5.4.0/drivers/misc/sgi-gru/grutables.h @@ -637,7 +637,7 @@ extern int gru_user_unload_context(unsigned long arg); extern int gru_get_exception_detail(unsigned long arg); extern int gru_set_context_option(unsigned long address); -extern void gru_check_context_placement(struct gru_thread_state *gts); +extern int gru_check_context_placement(struct gru_thread_state *gts); extern int gru_cpu_fault_map_id(void); extern struct vm_area_struct *gru_find_vma(unsigned long vaddr); extern void gru_flush_all_tlb(struct gru_state *gru); --- linux-oracle-5.4.0.orig/drivers/misc/sgi-gru/grutlbpurge.c +++ linux-oracle-5.4.0/drivers/misc/sgi-gru/grutlbpurge.c @@ -65,7 +65,6 @@ struct gru_tlb_global_handle *tgh; int n; - preempt_disable(); if (uv_numa_blade_id() == gru->gs_blade_id) n = get_on_blade_tgh(gru); else @@ -79,7 +78,6 @@ static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) { unlock_tgh_handle(tgh); - preempt_enable(); } /* --- linux-oracle-5.4.0.orig/drivers/misc/sgi-xp/xpc_partition.c +++ linux-oracle-5.4.0/drivers/misc/sgi-xp/xpc_partition.c @@ -290,7 +290,7 @@ /* cancel the timer function, provided it's not us */ if (!in_interrupt()) - del_singleshot_timer_sync(&part->disengage_timer); + del_timer_sync(&part->disengage_timer); DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING && part->act_state != XPC_P_AS_INACTIVE); --- linux-oracle-5.4.0.orig/drivers/misc/ti-st/st_core.c +++ linux-oracle-5.4.0/drivers/misc/ti-st/st_core.c @@ -15,6 +15,7 @@ #include #include +#include extern void st_kim_recv(void *, const unsigned char *, long); void st_int_recv(void *, const unsigned char *, long); @@ -423,7 +424,7 @@ case ST_LL_AWAKE_TO_ASLEEP: pr_err("ST LL is illegal state(%ld)," "purging received skb.", st_ll_getstate(st_gdata)); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; case ST_LL_ASLEEP: skb_queue_tail(&st_gdata->tx_waitq, skb); @@ -432,7 +433,7 @@ default: pr_err("ST LL is illegal state(%ld)," "purging received skb.", st_ll_getstate(st_gdata)); - kfree_skb(skb); + dev_kfree_skb_irq(skb); break; } @@ -486,7 +487,7 @@ spin_unlock_irqrestore(&st_data->lock, flags); break; } - kfree_skb(skb); + dev_kfree_skb_irq(skb); spin_unlock_irqrestore(&st_data->lock, flags); } /* if wake-up is set in another context- restart sending */ @@ -708,7 +709,6 @@ */ static int st_tty_open(struct tty_struct *tty) { - int err = 0; struct st_data_s *st_gdata; pr_info("%s ", __func__); @@ -731,7 +731,8 @@ */ st_kim_complete(st_gdata->kim_data); pr_debug("done %s", __func__); - return err; + + return 0; } static void st_tty_close(struct tty_struct *tty) --- linux-oracle-5.4.0.orig/drivers/misc/tifm_7xx1.c +++ linux-oracle-5.4.0/drivers/misc/tifm_7xx1.c @@ -190,7 +190,7 @@ spin_unlock_irqrestore(&fm->lock, flags); } if (sock) - tifm_free_device(&sock->dev); + put_device(&sock->dev); } spin_lock_irqsave(&fm->lock, flags); } --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_context.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_context.c @@ -743,7 +743,7 @@ return VMCI_ERROR_MORE_DATA; } - dbells = kmalloc(data_size, GFP_ATOMIC); + dbells = kzalloc(data_size, GFP_ATOMIC); if (!dbells) return VMCI_ERROR_NO_MEM; --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_datagram.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_datagram.c @@ -234,7 +234,8 @@ dg_info->in_dg_host_queue = true; dg_info->entry = dst_entry; - memcpy(&dg_info->msg, dg, dg_size); + dg_info->msg = *dg; + memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size); INIT_WORK(&dg_info->work, dg_delayed_dispatch); schedule_work(&dg_info->work); @@ -377,7 +378,8 @@ dg_info->in_dg_host_queue = false; dg_info->entry = dst_entry; - memcpy(&dg_info->msg, dg, VMCI_DG_SIZE(dg)); + dg_info->msg = *dg; + memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size); INIT_WORK(&dg_info->work, dg_delayed_dispatch); schedule_work(&dg_info->work); --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_doorbell.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_doorbell.c @@ -326,7 +326,7 @@ bool vmci_dbell_register_notification_bitmap(u64 bitmap_ppn) { int result; - struct vmci_notify_bm_set_msg bitmap_set_msg; + struct vmci_notify_bm_set_msg bitmap_set_msg = { }; bitmap_set_msg.hdr.dst = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_SET_NOTIFY_BITMAP); --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_event.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_event.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -86,9 +87,12 @@ { struct vmci_subscription *cur; struct list_head *subscriber_list; + u32 sanitized_event, max_vmci_event; rcu_read_lock(); - subscriber_list = &subscriber_array[event_msg->event_data.event]; + max_vmci_event = ARRAY_SIZE(subscriber_array); + sanitized_event = array_index_nospec(event_msg->event_data.event, max_vmci_event); + subscriber_list = &subscriber_array[sanitized_event]; list_for_each_entry_rcu(cur, subscriber_list, node) { cur->callback(cur->id, &event_msg->event_data, cur->callback_data); --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_guest.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_guest.c @@ -168,7 +168,7 @@ VMCI_UTIL_NUM_RESOURCES * sizeof(u32); struct vmci_datagram *check_msg; - check_msg = kmalloc(msg_size, GFP_KERNEL); + check_msg = kzalloc(msg_size, GFP_KERNEL); if (!check_msg) { dev_err(&pdev->dev, "%s: Insufficient memory\n", __func__); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_host.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_host.c @@ -160,10 +160,16 @@ static __poll_t vmci_host_poll(struct file *filp, poll_table *wait) { struct vmci_host_dev *vmci_host_dev = filp->private_data; - struct vmci_ctx *context = vmci_host_dev->context; + struct vmci_ctx *context; __poll_t mask = 0; if (vmci_host_dev->ct_type == VMCIOBJ_CONTEXT) { + /* + * Read context only if ct_type == VMCIOBJ_CONTEXT to make + * sure that context is initialized + */ + context = vmci_host_dev->context; + /* Check for VMCI calls to this VM context. */ if (wait) poll_wait(filp, &context->host_context.wait_queue, --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -537,6 +537,9 @@ queue_page_size = num_pages * sizeof(*queue->kernel_if->u.h.page); + if (queue_size + queue_page_size > KMALLOC_MAX_SIZE) + return NULL; + queue = kzalloc(queue_size + queue_page_size, GFP_KERNEL); if (queue) { queue->q_header = NULL; @@ -630,7 +633,7 @@ for (i = 0; i < num_pages; i++) { if (dirty) - set_page_dirty(pages[i]); + set_page_dirty_lock(pages[i]); put_page(pages[i]); pages[i] = NULL; @@ -657,8 +660,9 @@ if (retval < (int)produce_q->kernel_if->num_pages) { pr_debug("get_user_pages_fast(produce) failed (retval=%d)", retval); - qp_release_pages(produce_q->kernel_if->u.h.header_page, - retval, false); + if (retval > 0) + qp_release_pages(produce_q->kernel_if->u.h.header_page, + retval, false); err = VMCI_ERROR_NO_MEM; goto out; } @@ -670,8 +674,9 @@ if (retval < (int)consume_q->kernel_if->num_pages) { pr_debug("get_user_pages_fast(consume) failed (retval=%d)", retval); - qp_release_pages(consume_q->kernel_if->u.h.header_page, - retval, false); + if (retval > 0) + qp_release_pages(consume_q->kernel_if->u.h.header_page, + retval, false); qp_release_pages(produce_q->kernel_if->u.h.header_page, produce_q->kernel_if->num_pages, false); err = VMCI_ERROR_NO_MEM; @@ -847,6 +852,7 @@ u32 context_id = vmci_get_context_id(); struct vmci_event_qp ev; + memset(&ev, 0, sizeof(ev)); ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER); ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); @@ -1460,6 +1466,7 @@ * kernel. */ + memset(&ev, 0, sizeof(ev)); ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER); ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, VMCI_CONTEXT_RESOURCE_ID); @@ -2233,7 +2240,8 @@ result = VMCI_SUCCESS; - if (context_id != VMCI_HOST_CONTEXT_ID) { + if (context_id != VMCI_HOST_CONTEXT_ID && + !QPBROKERSTATE_HAS_MEM(entry)) { struct vmci_qp_page_store page_store; page_store.pages = guest_mem; @@ -2340,7 +2348,8 @@ goto out; } - if (context_id != VMCI_HOST_CONTEXT_ID) { + if (context_id != VMCI_HOST_CONTEXT_ID && + QPBROKERSTATE_HAS_MEM(entry)) { qp_acquire_queue_mutex(entry->produce_q); result = qp_save_headers(entry); if (result < VMCI_SUCCESS) --- linux-oracle-5.4.0.orig/drivers/misc/vmw_vmci/vmci_resource.c +++ linux-oracle-5.4.0/drivers/misc/vmw_vmci/vmci_resource.c @@ -144,7 +144,8 @@ spin_lock(&vmci_resource_table.lock); hlist_for_each_entry(r, &vmci_resource_table.entries[idx], node) { - if (vmci_handle_is_equal(r->handle, resource->handle)) { + if (vmci_handle_is_equal(r->handle, resource->handle) && + resource->type == r->type) { hlist_del_init_rcu(&r->node); break; } --- linux-oracle-5.4.0.orig/drivers/misc/xilinx_sdfec.c +++ linux-oracle-5.4.0/drivers/misc/xilinx_sdfec.c @@ -602,10 +602,10 @@ const u32 depth) { u32 reg = 0; - u32 res; - u32 n, i; + int res, i, nr_pages; + u32 n; u32 *addr = NULL; - struct page *page[MAX_NUM_PAGES]; + struct page *pages[MAX_NUM_PAGES]; /* * Writes that go beyond the length of @@ -622,15 +622,22 @@ if ((len * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE) n += 1; - res = get_user_pages_fast((unsigned long)src_ptr, n, 0, page); - if (res < n) { - for (i = 0; i < res; i++) - put_page(page[i]); + if (WARN_ON_ONCE(n > INT_MAX)) + return -EINVAL; + + nr_pages = n; + + res = get_user_pages_fast((unsigned long)src_ptr, nr_pages, 0, pages); + if (res < nr_pages) { + if (res > 0) { + for (i = 0; i < res; i++) + put_page(pages[i]); + } return -EINVAL; } - for (i = 0; i < n; i++) { - addr = kmap(page[i]); + for (i = 0; i < nr_pages; i++) { + addr = kmap(pages[i]); do { xsdfec_regwrite(xsdfec, base_addr + ((offset + reg) * @@ -639,7 +646,7 @@ reg++; } while ((reg < len) && ((reg * XSDFEC_REG_WIDTH_JUMP) % PAGE_SIZE)); - put_page(page[i]); + put_page(pages[i]); } return reg; } @@ -1025,25 +1032,25 @@ } #endif -static unsigned int xsdfec_poll(struct file *file, poll_table *wait) +static __poll_t xsdfec_poll(struct file *file, poll_table *wait) { - unsigned int mask = 0; + __poll_t mask = 0; struct xsdfec_dev *xsdfec; xsdfec = container_of(file->private_data, struct xsdfec_dev, miscdev); if (!xsdfec) - return POLLNVAL | POLLHUP; + return EPOLLNVAL | EPOLLHUP; poll_wait(file, &xsdfec->waitq, wait); /* XSDFEC ISR detected an error */ spin_lock_irqsave(&xsdfec->error_data_lock, xsdfec->flags); if (xsdfec->state_updated) - mask |= POLLIN | POLLPRI; + mask |= EPOLLIN | EPOLLPRI; if (xsdfec->stats_updated) - mask |= POLLIN | POLLRDNORM; + mask |= EPOLLIN | EPOLLRDNORM; spin_unlock_irqrestore(&xsdfec->error_data_lock, xsdfec->flags); return mask; --- linux-oracle-5.4.0.orig/drivers/mmc/core/block.c +++ linux-oracle-5.4.0/drivers/mmc/core/block.c @@ -249,6 +249,7 @@ goto out_put; } req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP; + req_to_mmc_queue_req(req)->drv_op_result = -EIO; blk_execute_rq(mq->queue, NULL, req, 0); ret = req_to_mmc_queue_req(req)->drv_op_result; blk_put_request(req); @@ -344,6 +345,10 @@ struct mmc_ioc_cmd ic; unsigned char *buf; u64 buf_bytes; + unsigned int flags; +#define MMC_BLK_IOC_DROP BIT(0) /* drop this mrq */ +#define MMC_BLK_IOC_SBC BIT(1) /* use mrq.sbc */ + struct mmc_rpmb_data *rpmb; }; @@ -353,7 +358,7 @@ struct mmc_blk_ioc_data *idata; int err; - idata = kmalloc(sizeof(*idata), GFP_KERNEL); + idata = kzalloc(sizeof(*idata), GFP_KERNEL); if (!idata) { err = -ENOMEM; goto out; @@ -408,38 +413,6 @@ return 0; } -static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, - u32 retries_max) -{ - int err; - u32 retry_count = 0; - - if (!status || !retries_max) - return -EINVAL; - - do { - err = __mmc_send_status(card, status, 5); - if (err) - break; - - if (!R1_STATUS(*status) && - (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) - break; /* RPMB programming operation complete */ - - /* - * Rechedule to give the MMC device a chance to continue - * processing the previous command without being polled too - * frequently. - */ - usleep_range(1000, 5000); - } while (++retry_count < retries_max); - - if (retry_count == retries_max) - err = -EPERM; - - return err; -} - static int ioctl_do_sanitize(struct mmc_card *card) { int err; @@ -468,8 +441,60 @@ return err; } +static inline bool mmc_blk_in_tran_state(u32 status) +{ + /* + * Some cards mishandle the status bits, so make sure to check both the + * busy indication and the card state. + */ + return status & R1_READY_FOR_DATA && + (R1_CURRENT_STATE(status) == R1_STATE_TRAN); +} + +static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, + u32 *resp_errs) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + int err = 0; + u32 status; + + do { + bool done = time_after(jiffies, timeout); + + err = __mmc_send_status(card, &status, 5); + if (err) { + dev_err(mmc_dev(card->host), + "error %d requesting status\n", err); + return err; + } + + /* Accumulate any response error bits seen */ + if (resp_errs) + *resp_errs |= status; + + /* + * Timeout if the device never becomes ready for data and never + * leaves the program state. + */ + if (done) { + dev_err(mmc_dev(card->host), + "Card stuck in wrong state! %s status: %#x\n", + __func__, status); + return -ETIMEDOUT; + } + + /* + * Some cards mishandle the status bits, + * so make sure to check both the busy + * indication and the card state. + */ + } while (!mmc_blk_in_tran_state(status)); + + return err; +} + static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct mmc_blk_ioc_data *idata) + struct mmc_blk_ioc_data **idatas, int i) { struct mmc_command cmd = {}, sbc = {}; struct mmc_data data = {}; @@ -477,11 +502,18 @@ struct scatterlist sg; int err; unsigned int target_part; - u32 status = 0; + struct mmc_blk_ioc_data *idata = idatas[i]; + struct mmc_blk_ioc_data *prev_idata = NULL; if (!card || !md || !idata) return -EINVAL; + if (idata->flags & MMC_BLK_IOC_DROP) + return 0; + + if (idata->flags & MMC_BLK_IOC_SBC && i > 0) + prev_idata = idatas[i - 1]; + /* * The RPMB accesses comes in from the character device, so we * need to target these explicitly. Else we just target the @@ -548,7 +580,7 @@ return err; } - if (idata->rpmb) { + if (idata->rpmb || prev_idata) { sbc.opcode = MMC_SET_BLOCK_COUNT; /* * We don't do any blockcount validation because the max size @@ -556,6 +588,8 @@ * 'Reliable Write' bit here. */ sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31)); + if (prev_idata) + sbc.arg = prev_idata->ic.arg; sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; mrq.sbc = &sbc; } @@ -572,6 +606,16 @@ } mmc_wait_for_req(card->host, &mrq); + memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); + + if (prev_idata) { + memcpy(&prev_idata->ic.response, sbc.resp, sizeof(sbc.resp)); + if (sbc.error) { + dev_err(mmc_dev(card->host), "%s: sbc error %d\n", + __func__, sbc.error); + return sbc.error; + } + } if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", @@ -603,24 +647,30 @@ } /* + * Make sure to update CACHE_CTRL in case it was changed. The cache + * will get turned back on if the card is re-initialized, e.g. + * suspend/resume or hw reset in recovery. + */ + if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_CACHE_CTRL) && + (cmd.opcode == MMC_SWITCH)) { + u8 value = MMC_EXTRACT_VALUE_FROM_ARG(cmd.arg) & 1; + + card->ext_csd.cache_ctrl = value; + } + + /* * According to the SD specs, some commands require a delay after * issuing the command. */ if (idata->ic.postsleep_min_us) usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); - memcpy(&(idata->ic.response), cmd.resp, sizeof(cmd.resp)); - - if (idata->rpmb) { + if (idata->rpmb || (cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { /* - * Ensure RPMB command has completed by polling CMD13 + * Ensure RPMB/R1B command has completed by polling CMD13 * "Send Status". */ - err = ioctl_rpmb_card_status_poll(card, &status, 5); - if (err) - dev_err(mmc_dev(card->host), - "%s: Card Status=0x%08X, error %d\n", - __func__, status, err); + err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, NULL); } return err; @@ -662,6 +712,7 @@ idatas[0] = idata; req_to_mmc_queue_req(req)->drv_op = rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; + req_to_mmc_queue_req(req)->drv_op_result = -EIO; req_to_mmc_queue_req(req)->drv_op_data = idatas; req_to_mmc_queue_req(req)->ioc_count = 1; blk_execute_rq(mq->queue, NULL, req, 0); @@ -731,6 +782,7 @@ } req_to_mmc_queue_req(req)->drv_op = rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL; + req_to_mmc_queue_req(req)->drv_op_result = -EIO; req_to_mmc_queue_req(req)->drv_op_data = idata; req_to_mmc_queue_req(req)->ioc_count = num_of_cmds; blk_execute_rq(mq->queue, NULL, req, 0); @@ -821,9 +873,11 @@ static int mmc_blk_part_switch_pre(struct mmc_card *card, unsigned int part_type) { + const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK; + const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB; int ret = 0; - if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { + if ((part_type & mask) == rpmb) { if (card->ext_csd.cmdq_en) { ret = mmc_cmdq_disable(card); if (ret) @@ -838,9 +892,11 @@ static int mmc_blk_part_switch_post(struct mmc_card *card, unsigned int part_type) { + const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK; + const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB; int ret = 0; - if (part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) { + if ((part_type & mask) == rpmb) { mmc_retune_unpause(card->host); if (card->reenable_cmdq && !card->ext_csd.cmdq_en) ret = mmc_cmdq_enable(card); @@ -970,58 +1026,6 @@ return ms; } -static inline bool mmc_blk_in_tran_state(u32 status) -{ - /* - * Some cards mishandle the status bits, so make sure to check both the - * busy indication and the card state. - */ - return status & R1_READY_FOR_DATA && - (R1_CURRENT_STATE(status) == R1_STATE_TRAN); -} - -static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, - struct request *req, u32 *resp_errs) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - int err = 0; - u32 status; - - do { - bool done = time_after(jiffies, timeout); - - err = __mmc_send_status(card, &status, 5); - if (err) { - pr_err("%s: error %d requesting status\n", - req->rq_disk->disk_name, err); - return err; - } - - /* Accumulate any response error bits seen */ - if (resp_errs) - *resp_errs |= status; - - /* - * Timeout if the device never becomes ready for data and never - * leaves the program state. - */ - if (done) { - pr_err("%s: Card stuck in wrong state! %s %s status: %#x\n", - mmc_hostname(card->host), - req->rq_disk->disk_name, __func__, status); - return -ETIMEDOUT; - } - - /* - * Some cards mishandle the status bits, - * so make sure to check both the busy - * indication and the card state. - */ - } while (!mmc_blk_in_tran_state(status)); - - return err; -} - static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, int type) { @@ -1056,6 +1060,20 @@ md->reset_done &= ~type; } +static void mmc_blk_check_sbc(struct mmc_queue_req *mq_rq) +{ + struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data; + int i; + + for (i = 1; i < mq_rq->ioc_count; i++) { + if (idata[i - 1]->ic.opcode == MMC_SET_BLOCK_COUNT && + mmc_op_multi(idata[i]->ic.opcode)) { + idata[i - 1]->flags |= MMC_BLK_IOC_DROP; + idata[i]->flags |= MMC_BLK_IOC_SBC; + } + } +} + /* * The non-block commands come back from the block layer after it queued it and * processed it with all other requests and then they get issued in this @@ -1078,16 +1096,27 @@ switch (mq_rq->drv_op) { case MMC_DRV_OP_IOCTL: + if (card->ext_csd.cmdq_en) { + ret = mmc_cmdq_disable(card); + if (ret) + break; + } + + mmc_blk_check_sbc(mq_rq); + + fallthrough; case MMC_DRV_OP_IOCTL_RPMB: idata = mq_rq->drv_op_data; for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { - ret = __mmc_blk_ioctl_cmd(card, md, idata[i]); + ret = __mmc_blk_ioctl_cmd(card, md, idata, i); if (ret) break; } /* Always switch back to main area after RPMB access */ if (rpmb_ioctl) mmc_blk_part_switch(card, 0); + else if (card->reenable_cmdq && !card->ext_csd.cmdq_en) + mmc_cmdq_enable(card); break; case MMC_DRV_OP_BOOT_WP: ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, @@ -1144,7 +1173,7 @@ card->erase_arg == MMC_TRIM_ARG ? INAND_CMD38_ARG_TRIM : INAND_CMD38_ARG_ERASE, - 0); + card->ext_csd.generic_cmd6_time); } if (!err) err = mmc_erase(card, from, nr, card->erase_arg); @@ -1186,7 +1215,7 @@ arg == MMC_SECURE_TRIM1_ARG ? INAND_CMD38_ARG_SECTRIM1 : INAND_CMD38_ARG_SECERASE, - 0); + card->ext_csd.generic_cmd6_time); if (err) goto out_retry; } @@ -1204,7 +1233,7 @@ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, - 0); + card->ext_csd.generic_cmd6_time); if (err) goto out_retry; } @@ -1454,6 +1483,7 @@ struct mmc_request *mrq = &mqrq->brq.mrq; struct request_queue *q = req->q; struct mmc_host *host = mq->card->host; + enum mmc_issue_type issue_type = mmc_issue_type(mq, req); unsigned long flags; bool put_card; int err; @@ -1477,13 +1507,15 @@ blk_mq_requeue_request(req, true); else __blk_mq_end_request(req, BLK_STS_OK); + } else if (mq->in_recovery) { + blk_mq_requeue_request(req, true); } else { blk_mq_end_request(req, BLK_STS_OK); } spin_lock_irqsave(&mq->lock, flags); - mq->in_flight[mmc_issue_type(mq, req)] -= 1; + mq->in_flight[issue_type] -= 1; put_card = (mmc_tot_in_flight(mq) == 0); @@ -1509,8 +1541,7 @@ err = mmc_cqe_recovery(host); if (err) mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY); - else - mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); + mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY); pr_debug("%s: CQE recovery done\n", mmc_hostname(host)); } @@ -1529,7 +1560,7 @@ */ if (mq->in_recovery) mmc_blk_cqe_complete_rq(mq, req); - else + else if (likely(!blk_should_fake_timeout(req->q))) blk_mq_complete_request(req); } @@ -1671,7 +1702,7 @@ mmc_blk_send_stop(card, timeout); - err = card_busy_detect(card, timeout, req, NULL); + err = card_busy_detect(card, timeout, NULL); mmc_retune_release(card->host); @@ -1688,31 +1719,31 @@ struct mmc_card *card = mq->card; struct mmc_host *host = card->host; blk_status_t error = BLK_STS_OK; - int retries = 0; do { u32 status; int err; + int retries = 0; - mmc_blk_rw_rq_prep(mqrq, card, 1, mq); + while (retries++ <= MMC_READ_SINGLE_RETRIES) { + mmc_blk_rw_rq_prep(mqrq, card, 1, mq); - mmc_wait_for_req(host, mrq); + mmc_wait_for_req(host, mrq); - err = mmc_send_status(card, &status); - if (err) - goto error_exit; - - if (!mmc_host_is_spi(host) && - !mmc_blk_in_tran_state(status)) { - err = mmc_blk_fix_state(card, req); + err = mmc_send_status(card, &status); if (err) goto error_exit; - } - if (mrq->cmd->error && retries++ < MMC_READ_SINGLE_RETRIES) - continue; + if (!mmc_host_is_spi(host) && + !mmc_blk_in_tran_state(status)) { + err = mmc_blk_fix_state(card, req); + if (err) + goto error_exit; + } - retries = 0; + if (!mrq->cmd->error) + break; + } if (mrq->cmd->error || mrq->data->error || @@ -1895,7 +1926,7 @@ if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ) return 0; - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, req, &status); + err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, &status); /* * Do not assume data transferred correctly if there are any error bits @@ -1963,7 +1994,7 @@ if (mq->use_cqe) mmc_blk_cqe_complete_rq(mq, req); - else + else if (likely(!blk_should_fake_timeout(req->q))) mmc_blk_mq_complete_rq(mq, req); } @@ -1984,14 +2015,14 @@ mmc_blk_urgent_bkops(mq, mqrq); } -static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, struct request *req) +static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type) { unsigned long flags; bool put_card; spin_lock_irqsave(&mq->lock, flags); - mq->in_flight[mmc_issue_type(mq, req)] -= 1; + mq->in_flight[issue_type] -= 1; put_card = (mmc_tot_in_flight(mq) == 0); @@ -2003,6 +2034,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req) { + enum mmc_issue_type issue_type = mmc_issue_type(mq, req); struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req); struct mmc_request *mrq = &mqrq->brq.mrq; struct mmc_host *host = mq->card->host; @@ -2015,10 +2047,10 @@ */ if (mq->in_recovery) mmc_blk_mq_complete_rq(mq, req); - else + else if (likely(!blk_should_fake_timeout(req->q))) blk_mq_complete_request(req); - mmc_blk_mq_dec_in_flight(mq, req); + mmc_blk_mq_dec_in_flight(mq, issue_type); } void mmc_blk_mq_recovery(struct mmc_queue *mq) @@ -2251,6 +2283,10 @@ case MMC_ISSUE_ASYNC: switch (req_op(req)) { case REQ_OP_FLUSH: + if (!mmc_cache_enabled(host)) { + blk_mq_end_request(req, BLK_STS_OK); + return MMC_REQ_FINISHED; + } ret = mmc_blk_cqe_issue_flush(mq, req); break; case REQ_OP_READ: @@ -2511,8 +2547,8 @@ struct mmc_rpmb_data *rpmb = container_of(inode->i_cdev, struct mmc_rpmb_data, chrdev); - put_device(&rpmb->dev); mmc_blk_put(rpmb->md); + put_device(&rpmb->dev); return 0; } @@ -2752,6 +2788,7 @@ if (IS_ERR(req)) return PTR_ERR(req); req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS; + req_to_mmc_queue_req(req)->drv_op_result = -EIO; blk_execute_rq(mq->queue, NULL, req, 0); ret = req_to_mmc_queue_req(req)->drv_op_result; if (ret >= 0) { @@ -2790,6 +2827,7 @@ goto out_free; } req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD; + req_to_mmc_queue_req(req)->drv_op_result = -EIO; req_to_mmc_queue_req(req)->drv_op_data = &ext_csd; blk_execute_rq(mq->queue, NULL, req, 0); err = req_to_mmc_queue_req(req)->drv_op_result; @@ -3097,4 +3135,3 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); - --- linux-oracle-5.4.0.orig/drivers/mmc/core/bus.c +++ linux-oracle-5.4.0/drivers/mmc/core/bus.c @@ -134,6 +134,8 @@ if (dev->driver && drv->shutdown) drv->shutdown(card); + __mmc_stop_host(host); + if (host->bus_ops->shutdown) { ret = host->bus_ops->shutdown(host); if (ret) @@ -373,11 +375,6 @@ mmc_remove_card_debugfs(card); #endif - if (host->cqe_enabled) { - host->cqe_ops->cqe_disable(host); - host->cqe_enabled = false; - } - if (mmc_card_present(card)) { if (mmc_host_is_spi(card->host)) { pr_info("%s: SPI card removed\n", @@ -390,6 +387,10 @@ of_node_put(card->dev.of_node); } + if (host->cqe_enabled) { + host->cqe_ops->cqe_disable(host); + host->cqe_enabled = false; + } + put_device(&card->dev); } - --- linux-oracle-5.4.0.orig/drivers/mmc/core/core.c +++ linux-oracle-5.4.0/drivers/mmc/core/core.c @@ -564,22 +564,27 @@ host->cqe_ops->cqe_recovery_start(host); memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = MMC_STOP_TRANSMISSION, - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC, + cmd.opcode = MMC_STOP_TRANSMISSION; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, - mmc_wait_for_cmd(host, &cmd, 0); + cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; + mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); + + mmc_poll_for_busy(host->card, MMC_CQE_RECOVERY_TIMEOUT, true, true); memset(&cmd, 0, sizeof(cmd)); cmd.opcode = MMC_CMDQ_TASK_MGMT; cmd.arg = 1; /* Discard entire queue */ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ - cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT, - err = mmc_wait_for_cmd(host, &cmd, 0); + cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); host->cqe_ops->cqe_recovery_finish(host); + if (err) + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); + mmc_retune_release(host); return err; @@ -953,11 +958,14 @@ err = host->ops->execute_tuning(host, opcode); - if (err) + if (err) { pr_err("%s: tuning execution failed: %d\n", mmc_hostname(host), err); - else + } else { + host->retune_now = 0; + host->need_retune = 0; mmc_retune_enable(host); + } return err; } @@ -1142,7 +1150,13 @@ mmc_power_cycle(host, ocr); } else { bit = fls(ocr) - 1; - ocr &= 3 << bit; + /* + * The bit variable represents the highest voltage bit set in + * the OCR register. + * To keep a range of 2 values (e.g. 3.2V/3.3V and 3.3V/3.4V), + * we must shift the mask '3' with (bit - 1). + */ + ocr &= 3 << (bit - 1); if (bit != host->ios.vdd) dev_warn(mmc_dev(host), "exceeding card's volts\n"); } @@ -1221,7 +1235,7 @@ err = mmc_wait_for_cmd(host, &cmd, 0); if (err) - return err; + goto power_cycle; if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR)) return -EIO; @@ -1469,8 +1483,7 @@ mmc_bus_put(host); } -static void _mmc_detect_change(struct mmc_host *host, unsigned long delay, - bool cd_irq) +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, bool cd_irq) { /* * If the device is configured as wakeup, we prevent a new sleep for @@ -1548,6 +1561,11 @@ card->pref_erase = 0; } +static bool is_trim_arg(unsigned int arg) +{ + return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG; +} + static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, unsigned int arg, unsigned int qty) { @@ -1733,8 +1751,11 @@ * the erase operation does not exceed the max_busy_timeout, we should * use R1B response. Or we need to prevent the host from doing hw busy * detection, which is done by converting to a R1 response instead. + * Note, some hosts requires R1B, which also means they are on their own + * when it comes to deal with the busy timeout. */ - if (card->host->max_busy_timeout && + if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) && + card->host->max_busy_timeout && busy_timeout > card->host->max_busy_timeout) { cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; } else { @@ -1876,7 +1897,7 @@ !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) return -EOPNOTSUPP; - if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) && + if (mmc_card_mmc(card) && is_trim_arg(arg) && !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) return -EOPNOTSUPP; @@ -1906,7 +1927,7 @@ * identified by the card->eg_boundary flag. */ rem = card->erase_size - (from % card->erase_size); - if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) { + if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) { err = mmc_do_erase(card, from, from + rem - 1, arg); from += rem; if ((err) || (to <= from)) @@ -2129,7 +2150,7 @@ ret = host->bus_ops->hw_reset(host); mmc_bus_put(host); - if (ret) + if (ret < 0) pr_warn("%s: tried to HW reset card, got error %d\n", mmc_hostname(host), ret); @@ -2297,11 +2318,8 @@ mmc_bus_get(host); - /* - * if there is a _removable_ card registered, check whether it is - * still present - */ - if (host->bus_ops && !host->bus_dead && mmc_card_is_removable(host)) + /* Verify a registered card to be functional, else remove it. */ + if (host->bus_ops && !host->bus_dead) host->bus_ops->detect(host); host->detect_change = 0; @@ -2362,8 +2380,11 @@ _mmc_detect_change(host, 0, false); } -void mmc_stop_host(struct mmc_host *host) +void __mmc_stop_host(struct mmc_host *host) { + if (host->rescan_disable) + return; + if (host->slot.cd_irq >= 0) { mmc_gpio_set_cd_wake(host, false); disable_irq(host->slot.cd_irq); @@ -2371,6 +2392,11 @@ host->rescan_disable = 1; cancel_delayed_work_sync(&host->detect); +} + +void mmc_stop_host(struct mmc_host *host) +{ + __mmc_stop_host(host); /* clear pm flags now and let card drivers set them as needed */ host->pm_flags = 0; @@ -2393,80 +2419,6 @@ mmc_release_host(host); } -#ifdef CONFIG_PM_SLEEP -/* Do the card removal on suspend if card is assumed removeable - * Do that in pm notifier while userspace isn't yet frozen, so we will be able - to sync the card. -*/ -static int mmc_pm_notify(struct notifier_block *notify_block, - unsigned long mode, void *unused) -{ - struct mmc_host *host = container_of( - notify_block, struct mmc_host, pm_notify); - unsigned long flags; - int err = 0; - - switch (mode) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - case PM_RESTORE_PREPARE: - spin_lock_irqsave(&host->lock, flags); - host->rescan_disable = 1; - spin_unlock_irqrestore(&host->lock, flags); - cancel_delayed_work_sync(&host->detect); - - if (!host->bus_ops) - break; - - /* Validate prerequisites for suspend */ - if (host->bus_ops->pre_suspend) - err = host->bus_ops->pre_suspend(host); - if (!err) - break; - - if (!mmc_card_is_removable(host)) { - dev_warn(mmc_dev(host), - "pre_suspend failed for non-removable host: " - "%d\n", err); - /* Avoid removing non-removable hosts */ - break; - } - - /* Calling bus_ops->remove() with a claimed host can deadlock */ - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); - mmc_release_host(host); - host->pm_flags = 0; - break; - - case PM_POST_SUSPEND: - case PM_POST_HIBERNATION: - case PM_POST_RESTORE: - - spin_lock_irqsave(&host->lock, flags); - host->rescan_disable = 0; - spin_unlock_irqrestore(&host->lock, flags); - _mmc_detect_change(host, 0, false); - - } - - return 0; -} - -void mmc_register_pm_notifier(struct mmc_host *host) -{ - host->pm_notify.notifier_call = mmc_pm_notify; - register_pm_notifier(&host->pm_notify); -} - -void mmc_unregister_pm_notifier(struct mmc_host *host) -{ - unregister_pm_notifier(&host->pm_notify); -} -#endif - static int __init mmc_init(void) { int ret; --- linux-oracle-5.4.0.orig/drivers/mmc/core/core.h +++ linux-oracle-5.4.0/drivers/mmc/core/core.h @@ -29,6 +29,7 @@ int (*shutdown)(struct mmc_host *); int (*hw_reset)(struct mmc_host *); int (*sw_reset)(struct mmc_host *); + bool (*cache_enabled)(struct mmc_host *); }; void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); @@ -68,8 +69,11 @@ void mmc_rescan(struct work_struct *work); void mmc_start_host(struct mmc_host *host); +void __mmc_stop_host(struct mmc_host *host); void mmc_stop_host(struct mmc_host *host); +void _mmc_detect_change(struct mmc_host *host, unsigned long delay, + bool cd_irq); int _mmc_detect_card_removed(struct mmc_host *host); int mmc_detect_card_removed(struct mmc_host *host); @@ -91,14 +95,6 @@ int mmc_hs200_to_hs400(struct mmc_card *card); int mmc_hs400_to_hs200(struct mmc_card *card); -#ifdef CONFIG_PM_SLEEP -void mmc_register_pm_notifier(struct mmc_host *host); -void mmc_unregister_pm_notifier(struct mmc_host *host); -#else -static inline void mmc_register_pm_notifier(struct mmc_host *host) { } -static inline void mmc_unregister_pm_notifier(struct mmc_host *host) { } -#endif - void mmc_wait_for_req_done(struct mmc_host *host, struct mmc_request *mrq); bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq); @@ -169,4 +165,12 @@ host->ops->post_req(host, mrq, err); } +static inline bool mmc_cache_enabled(struct mmc_host *host) +{ + if (host->bus_ops->cache_enabled) + return host->bus_ops->cache_enabled(host); + + return false; +} + #endif --- linux-oracle-5.4.0.orig/drivers/mmc/core/host.c +++ linux-oracle-5.4.0/drivers/mmc/core/host.c @@ -33,6 +33,42 @@ static DEFINE_IDA(mmc_host_ida); +#ifdef CONFIG_PM_SLEEP +static int mmc_host_class_prepare(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + + /* + * It's safe to access the bus_ops pointer, as both userspace and the + * workqueue for detecting cards are frozen at this point. + */ + if (!host->bus_ops) + return 0; + + /* Validate conditions for system suspend. */ + if (host->bus_ops->pre_suspend) + return host->bus_ops->pre_suspend(host); + + return 0; +} + +static void mmc_host_class_complete(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + + _mmc_detect_change(host, 0, false); +} + +static const struct dev_pm_ops mmc_host_class_dev_pm_ops = { + .prepare = mmc_host_class_prepare, + .complete = mmc_host_class_complete, +}; + +#define MMC_HOST_CLASS_DEV_PM_OPS (&mmc_host_class_dev_pm_ops) +#else +#define MMC_HOST_CLASS_DEV_PM_OPS NULL +#endif + static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); @@ -40,9 +76,19 @@ kfree(host); } +static int mmc_host_classdev_shutdown(struct device *dev) +{ + struct mmc_host *host = cls_dev_to_mmc_host(dev); + + __mmc_stop_host(host); + return 0; +} + static struct class mmc_host_class = { .name = "mmc_host", .dev_release = mmc_host_classdev_release, + .shutdown_pre = mmc_host_classdev_shutdown, + .pm = MMC_HOST_CLASS_DEV_PM_OPS, }; int mmc_register_host_class(void) @@ -65,13 +111,12 @@ /* * Pause re-tuning for a small set of operations. The pause begins after the - * next command and after first doing re-tuning. + * next command. */ void mmc_retune_pause(struct mmc_host *host) { if (!host->retune_paused) { host->retune_paused = 1; - mmc_retune_needed(host); mmc_retune_hold(host); } } @@ -176,7 +221,6 @@ u32 bus_width, drv_type, cd_debounce_delay_ms; int ret; bool cd_cap_invert, cd_gpio_invert = false; - bool ro_cap_invert, ro_gpio_invert = false; if (!dev || !dev_fwnode(dev)) return 0; @@ -255,9 +299,11 @@ } /* Parse Write Protection */ - ro_cap_invert = device_property_read_bool(dev, "wp-inverted"); - ret = mmc_gpiod_request_ro(host, "wp", 0, 0, &ro_gpio_invert); + if (device_property_read_bool(dev, "wp-inverted")) + host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + + ret = mmc_gpiod_request_ro(host, "wp", 0, 0, NULL); if (!ret) dev_info(host->parent, "Got WP GPIO\n"); else if (ret != -ENOENT && ret != -ENOSYS) @@ -266,10 +312,6 @@ if (device_property_read_bool(dev, "disable-wp")) host->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; - /* See the comment on CD inversion above */ - if (ro_cap_invert ^ ro_gpio_invert) - host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; - if (device_property_read_bool(dev, "cap-sd-highspeed")) host->caps |= MMC_CAP_SD_HIGHSPEED; if (device_property_read_bool(dev, "cap-mmc-highspeed")) @@ -454,6 +496,16 @@ EXPORT_SYMBOL(mmc_alloc_host); +static int mmc_validate_host_caps(struct mmc_host *host) +{ + if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) { + dev_warn(host->parent, "missing ->enable_sdio_irq() ops\n"); + return -EINVAL; + } + + return 0; +} + /** * mmc_add_host - initialise host hardware * @host: mmc host @@ -466,8 +518,9 @@ { int err; - WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && - !host->ops->enable_sdio_irq); + err = mmc_validate_host_caps(host); + if (err) + return err; err = device_add(&host->class_dev); if (err) @@ -480,8 +533,6 @@ #endif mmc_start_host(host); - mmc_register_pm_notifier(host); - return 0; } @@ -497,7 +548,6 @@ */ void mmc_remove_host(struct mmc_host *host) { - mmc_unregister_pm_notifier(host); mmc_stop_host(host); #ifdef CONFIG_DEBUG_FS @@ -519,6 +569,7 @@ */ void mmc_free_host(struct mmc_host *host) { + cancel_delayed_work_sync(&host->detect); mmc_pwrseq_free(host); put_device(&host->class_dev); } --- linux-oracle-5.4.0.orig/drivers/mmc/core/mmc.c +++ linux-oracle-5.4.0/drivers/mmc/core/mmc.c @@ -297,7 +297,7 @@ } } -static void mmc_part_add(struct mmc_card *card, unsigned int size, +static void mmc_part_add(struct mmc_card *card, u64 size, unsigned int part_cfg, char *name, int idx, bool ro, int area_type) { @@ -313,7 +313,7 @@ { int idx; u8 hc_erase_grp_sz, hc_wp_grp_sz; - unsigned int part_size; + u64 part_size; /* * General purpose partition feature support -- @@ -343,8 +343,7 @@ (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] << 8) + ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3]; - part_size *= (size_t)(hc_erase_grp_sz * - hc_wp_grp_sz); + part_size *= (hc_erase_grp_sz * hc_wp_grp_sz); mmc_part_add(card, part_size << 19, EXT_CSD_PART_CONFIG_ACC_GP0 + idx, "gp%d", idx, false, @@ -362,7 +361,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd) { int err = 0, idx; - unsigned int part_size; + u64 part_size; struct device_node *np; bool broken_hpi = false; @@ -424,10 +423,6 @@ /* EXT_CSD value is in units of 10ms, but we store in ms */ card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME]; - /* Some eMMC set the value too low so set a minimum */ - if (card->ext_csd.part_time && - card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) - card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; /* Sleep / awake timeout in 100ns units */ if (sa_shift > 0 && sa_shift <= 0x17) @@ -617,6 +612,17 @@ card->ext_csd.data_sector_size = 512; } + /* + * GENERIC_CMD6_TIME is to be used "unless a specific timeout is defined + * when accessing a specific field", so use it here if there is no + * PARTITION_SWITCH_TIME. + */ + if (!card->ext_csd.part_time) + card->ext_csd.part_time = card->ext_csd.generic_cmd6_time; + /* Some eMMC set the value too low so set a minimum */ + if (card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME) + card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME; + /* eMMC v5 or later */ if (card->ext_csd.rev >= 7) { memcpy(card->ext_csd.fwrev, &ext_csd[EXT_CSD_FIRMWARE_VERSION], @@ -985,10 +991,12 @@ static unsigned ext_csd_bits[] = { EXT_CSD_BUS_WIDTH_8, EXT_CSD_BUS_WIDTH_4, + EXT_CSD_BUS_WIDTH_1, }; static unsigned bus_widths[] = { MMC_BUS_WIDTH_8, MMC_BUS_WIDTH_4, + MMC_BUS_WIDTH_1, }; struct mmc_host *host = card->host; unsigned idx, bus_width = 0; @@ -1911,9 +1919,12 @@ * If the max_busy_timeout of the host is specified, validate it against * the sleep cmd timeout. A failure means we need to prevent the host * from doing hw busy detection, which is done by converting to a R1 - * response instead of a R1B. + * response instead of a R1B. Note, some hosts requires R1B, which also + * means they are on their own when it comes to deal with the busy + * timeout. */ - if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && + (timeout_ms > host->max_busy_timeout)) { cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; } else { cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; @@ -2010,6 +2021,12 @@ } } +static bool _mmc_cache_enabled(struct mmc_host *host) +{ + return host->card->ext_csd.cache_size > 0 && + host->card->ext_csd.cache_ctrl & 1; +} + static int _mmc_suspend(struct mmc_host *host, bool is_suspend) { int err = 0; @@ -2188,6 +2205,7 @@ .alive = mmc_alive, .shutdown = mmc_shutdown, .hw_reset = _mmc_hw_reset, + .cache_enabled = _mmc_cache_enabled, }; /* --- linux-oracle-5.4.0.orig/drivers/mmc/core/mmc_ops.c +++ linux-oracle-5.4.0/drivers/mmc/core/mmc_ops.c @@ -19,7 +19,9 @@ #include "host.h" #include "mmc_ops.h" -#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ +#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10min*/ +#define MMC_BKOPS_TIMEOUT_MS (120 * 1000) /* 120s */ +#define MMC_CACHE_FLUSH_TIMEOUT_MS (30 * 1000) /* 30s */ static const u8 tuning_blk_pattern_4bit[] = { 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, @@ -448,8 +450,8 @@ return __mmc_switch_status(card, true); } -static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, - bool send_status, bool retry_crc_err) +int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, + bool send_status, bool retry_crc_err) { struct mmc_host *host = card->host; int err; @@ -458,10 +460,6 @@ bool expired = false; bool busy = false; - /* We have an unspecified cmd timeout, use the fallback value. */ - if (!timeout_ms) - timeout_ms = MMC_OPS_TIMEOUT_MS; - /* * In cases when not allowed to poll by using CMD13 or because we aren't * capable of polling by using ->card_busy(), then rely on waiting the @@ -506,6 +504,7 @@ return 0; } +EXPORT_SYMBOL_GPL(mmc_poll_for_busy); /** * __mmc_switch - modify EXT_CSD register @@ -534,14 +533,22 @@ mmc_retune_hold(host); + if (!timeout_ms) { + pr_warn("%s: unspecified timeout for CMD6 - use generic\n", + mmc_hostname(host)); + timeout_ms = card->ext_csd.generic_cmd6_time; + } + /* * If the cmd timeout and the max_busy_timeout of the host are both * specified, let's validate them. A failure means we need to prevent * the host from doing hw busy detection, which is done by converting - * to a R1 response instead of a R1B. + * to a R1 response instead of a R1B. Note, some hosts requires R1B, + * which also means they are on their own when it comes to deal with the + * busy timeout. */ - if (timeout_ms && host->max_busy_timeout && - (timeout_ms > host->max_busy_timeout)) + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && + host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) use_r1b_resp = false; cmd.opcode = MMC_SWITCH; @@ -552,10 +559,6 @@ cmd.flags = MMC_CMD_AC; if (use_r1b_resp) { cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B; - /* - * A busy_timeout of zero means the host can decide to use - * whatever value it finds suitable. - */ cmd.busy_timeout = timeout_ms; } else { cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1; @@ -941,7 +944,7 @@ * urgent levels by using an asynchronous background task, when idle. */ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BKOPS_START, 1, MMC_OPS_TIMEOUT_MS); + EXT_CSD_BKOPS_START, 1, MMC_BKOPS_TIMEOUT_MS); if (err) pr_warn("%s: Error %d starting bkops\n", mmc_hostname(card->host), err); @@ -957,11 +960,10 @@ { int err = 0; - if (mmc_card_mmc(card) && - (card->ext_csd.cache_size > 0) && - (card->ext_csd.cache_ctrl & 1)) { + if (mmc_cache_enabled(card->host)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_FLUSH_CACHE, 1, 0); + EXT_CSD_FLUSH_CACHE, 1, + MMC_CACHE_FLUSH_TIMEOUT_MS); if (err) pr_err("%s: cache flush error %d\n", mmc_hostname(card->host), err); --- linux-oracle-5.4.0.orig/drivers/mmc/core/mmc_ops.h +++ linux-oracle-5.4.0/drivers/mmc/core/mmc_ops.h @@ -31,6 +31,8 @@ int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); int mmc_switch_status(struct mmc_card *card); int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal); +int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms, + bool send_status, bool retry_crc_err); int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, unsigned int timeout_ms, unsigned char timing, bool use_busy_signal, bool send_status, bool retry_crc_err); --- linux-oracle-5.4.0.orig/drivers/mmc/core/mmc_test.c +++ linux-oracle-5.4.0/drivers/mmc/core/mmc_test.c @@ -3097,13 +3097,13 @@ test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); #ifdef CONFIG_HIGHMEM test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER); + if (!test->highmem) { + count = -ENOMEM; + goto free_test_buffer; + } #endif -#ifdef CONFIG_HIGHMEM - if (test->buffer && test->highmem) { -#else if (test->buffer) { -#endif mutex_lock(&mmc_test_lock); mmc_test_run(test, testcase); mutex_unlock(&mmc_test_lock); @@ -3111,6 +3111,7 @@ #ifdef CONFIG_HIGHMEM __free_pages(test->highmem, BUFFER_ORDER); +free_test_buffer: #endif kfree(test->buffer); kfree(test); @@ -3167,7 +3168,8 @@ struct mmc_test_dbgfs_file *df; if (card->debugfs_root) - debugfs_create_file(name, mode, card->debugfs_root, card, fops); + file = debugfs_create_file(name, mode, card->debugfs_root, + card, fops); df = kmalloc(sizeof(*df), GFP_KERNEL); if (!df) { --- linux-oracle-5.4.0.orig/drivers/mmc/core/queue.c +++ linux-oracle-5.4.0/drivers/mmc/core/queue.c @@ -107,11 +107,10 @@ case MMC_ISSUE_DCMD: if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) { if (recovery_needed) - __mmc_cqe_recovery_notifier(mq); + mmc_cqe_recovery_notifier(mrq); return BLK_EH_RESET_TIMER; } - /* No timeout (XXX: huh? comment doesn't make much sense) */ - blk_mq_complete_request(req); + /* The request has gone already */ return BLK_EH_DONE; default: /* Timeout is handled by mmc core */ @@ -125,18 +124,13 @@ struct request_queue *q = req->q; struct mmc_queue *mq = q->queuedata; unsigned long flags; - int ret; + bool ignore_tout; spin_lock_irqsave(&mq->lock, flags); - - if (mq->recovery_needed || !mq->use_cqe) - ret = BLK_EH_RESET_TIMER; - else - ret = mmc_cqe_timed_out(req); - + ignore_tout = mq->recovery_needed || !mq->use_cqe; spin_unlock_irqrestore(&mq->lock, flags); - return ret; + return ignore_tout ? BLK_EH_RESET_TIMER : mmc_cqe_timed_out(req); } static void mmc_mq_recovery_handler(struct work_struct *work) @@ -190,7 +184,7 @@ q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ if (card->pref_erase > max_discard) - q->limits.discard_granularity = 0; + q->limits.discard_granularity = SECTOR_SIZE; if (mmc_can_secure_erase_trim(card)) blk_queue_flag_set(QUEUE_FLAG_SECERASE, q); } @@ -376,8 +370,10 @@ "merging was advertised but not possible"); blk_queue_max_segments(mq->queue, mmc_get_max_segments(host)); - if (mmc_card_mmc(card)) + if (mmc_card_mmc(card) && card->ext_csd.data_sector_size) { block_size = card->ext_csd.data_sector_size; + WARN_ON(block_size != 512 && block_size != 4096); + } blk_queue_logical_block_size(mq->queue, block_size); /* --- linux-oracle-5.4.0.orig/drivers/mmc/core/quirks.h +++ linux-oracle-5.4.0/drivers/mmc/core/quirks.h @@ -91,6 +91,20 @@ MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), /* + * Kingston EMMC04G-M627 advertises TRIM but it does not seems to + * support being used to offload WRITE_ZEROES. + */ + MMC_FIXUP("M62704", CID_MANFID_KINGSTON, 0x0100, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + + /* + * Micron MTFC4GACAJCN-1M advertises TRIM but it does not seems to + * support being used to offload WRITE_ZEROES. + */ + MMC_FIXUP("Q2J54A", CID_MANFID_MICRON, 0x014e, add_quirk_mmc, + MMC_QUIRK_TRIM_BROKEN), + + /* * On Some Kingston eMMCs, performing trim can result in * unrecoverable data conrruption occasionally due to a firmware bug. */ @@ -119,7 +133,14 @@ END_FIXUP }; + static const struct mmc_fixup sdio_fixup_methods[] = { + SDIO_FIXUP(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251, + add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), + + SDIO_FIXUP(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251, + add_quirk, MMC_QUIRK_DISABLE_CD), + SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271, add_quirk, MMC_QUIRK_NONSTD_FUNC_IF), --- linux-oracle-5.4.0.orig/drivers/mmc/core/regulator.c +++ linux-oracle-5.4.0/drivers/mmc/core/regulator.c @@ -258,3 +258,44 @@ return 0; } EXPORT_SYMBOL_GPL(mmc_regulator_get_supply); + +/** + * mmc_regulator_enable_vqmmc - enable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Enables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +int mmc_regulator_enable_vqmmc(struct mmc_host *mmc) +{ + int ret = 0; + + if (!IS_ERR(mmc->supply.vqmmc) && !mmc->vqmmc_enabled) { + ret = regulator_enable(mmc->supply.vqmmc); + if (ret < 0) + dev_err(mmc_dev(mmc), "enabling vqmmc regulator failed\n"); + else + mmc->vqmmc_enabled = true; + } + + return ret; +} +EXPORT_SYMBOL_GPL(mmc_regulator_enable_vqmmc); + +/** + * mmc_regulator_disable_vqmmc - disable VQMMC regulator for a host + * @mmc: the host to regulate + * + * Returns 0 or errno. Disables the regulator for vqmmc. + * Keeps track of the enable status for ensuring that calls to + * regulator_enable/disable are balanced. + */ +void mmc_regulator_disable_vqmmc(struct mmc_host *mmc) +{ + if (!IS_ERR(mmc->supply.vqmmc) && mmc->vqmmc_enabled) { + regulator_disable(mmc->supply.vqmmc); + mmc->vqmmc_enabled = false; + } +} +EXPORT_SYMBOL_GPL(mmc_regulator_disable_vqmmc); --- linux-oracle-5.4.0.orig/drivers/mmc/core/sd.c +++ linux-oracle-5.4.0/drivers/mmc/core/sd.c @@ -135,6 +135,9 @@ csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1; csd->erase_size <<= csd->write_blkbits - 9; } + + if (UNSTUFF_BITS(resp, 13, 1)) + mmc_card_set_readonly(card); break; case 1: /* @@ -169,6 +172,9 @@ csd->write_blkbits = 9; csd->write_partial = 0; csd->erase_size = 1; + + if (UNSTUFF_BITS(resp, 13, 1)) + mmc_card_set_readonly(card); break; default: pr_err("%s: unrecognised CSD structure version %d\n", @@ -787,11 +793,14 @@ return err; /* - * In case CCS and S18A in the response is set, start Signal Voltage - * Switch procedure. SPI mode doesn't support CMD11. + * In case the S18A bit is set in the response, let's start the signal + * voltage switch procedure. SPI mode doesn't support CMD11. + * Note that, according to the spec, the S18A bit is not valid unless + * the CCS bit is set as well. We deliberately deviate from the spec in + * regards to this, which allows UHS-I to be supported for SDSC cards. */ - if (!mmc_host_is_spi(host) && rocr && - ((*rocr & 0x41000000) == 0x41000000)) { + if (!mmc_host_is_spi(host) && (ocr & SD_OCR_S18R) && + rocr && (*rocr & SD_ROCR_S18A)) { err = mmc_set_uhs_voltage(host, pocr); if (err == -EAGAIN) { retries--; --- linux-oracle-5.4.0.orig/drivers/mmc/core/sdio.c +++ linux-oracle-5.4.0/drivers/mmc/core/sdio.c @@ -379,6 +379,8 @@ if (card->type == MMC_TYPE_SD_COMBO) max_dtr = min(max_dtr, mmc_sd_get_max_clock(card)); + max_dtr = min_not_zero(max_dtr, card->quirk_max_rate); + return max_dtr; } @@ -584,7 +586,7 @@ */ err = mmc_send_io_op_cond(host, ocr, &rocr); if (err) - goto err; + return err; /* * For SPI, enable CRC as appropriate. @@ -592,17 +594,15 @@ if (mmc_host_is_spi(host)) { err = mmc_spi_set_crc(host, use_spi_crc); if (err) - goto err; + return err; } /* * Allocate card structure. */ card = mmc_alloc_card(host, NULL); - if (IS_ERR(card)) { - err = PTR_ERR(card); - goto err; - } + if (IS_ERR(card)) + return PTR_ERR(card); if ((rocr & R4_MEMORY_PRESENT) && mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) { @@ -610,19 +610,15 @@ if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO || memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) { - mmc_remove_card(card); - pr_debug("%s: Perhaps the card was replaced\n", - mmc_hostname(host)); - return -ENOENT; + err = -ENOENT; + goto mismatch; } } else { card->type = MMC_TYPE_SDIO; if (oldcard && oldcard->type != MMC_TYPE_SDIO) { - mmc_remove_card(card); - pr_debug("%s: Perhaps the card was replaced\n", - mmc_hostname(host)); - return -ENOENT; + err = -ENOENT; + goto mismatch; } } @@ -632,6 +628,8 @@ if (host->ops->init_card) host->ops->init_card(host, card); + card->ocr = ocr_card; + /* * If the host and card support UHS-I mode request the card * to switch to 1.8V signaling level. No 1.8v signalling if @@ -677,7 +675,7 @@ if (!oldcard && card->type == MMC_TYPE_SD_COMBO) { err = mmc_sd_get_csd(host, card); if (err) - return err; + goto remove; mmc_decode_cid(card); } @@ -704,7 +702,12 @@ mmc_set_timing(card->host, MMC_TIMING_SD_HS); } - goto finish; + if (oldcard) + mmc_remove_card(card); + else + host->card = card; + + return 0; } /* @@ -718,9 +721,8 @@ /* Retry init sequence, but without R4_18V_PRESENT. */ retries = 0; goto try_again; - } else { - goto remove; } + return err; } /* @@ -731,18 +733,16 @@ goto remove; if (oldcard) { - int same = (card->cis.vendor == oldcard->cis.vendor && - card->cis.device == oldcard->cis.device); - mmc_remove_card(card); - if (!same) { - pr_debug("%s: Perhaps the card was replaced\n", - mmc_hostname(host)); - return -ENOENT; + if (card->cis.vendor == oldcard->cis.vendor && + card->cis.device == oldcard->cis.device) { + mmc_remove_card(card); + card = oldcard; + } else { + err = -ENOENT; + goto mismatch; } - - card = oldcard; } - card->ocr = ocr_card; + mmc_fixup_device(card, sdio_fixup_methods); if (card->type == MMC_TYPE_SD_COMBO) { @@ -801,16 +801,15 @@ err = -EINVAL; goto remove; } -finish: - if (!oldcard) - host->card = card; + + host->card = card; return 0; +mismatch: + pr_debug("%s: Perhaps the card was replaced\n", mmc_hostname(host)); remove: - if (!oldcard) + if (oldcard != card) mmc_remove_card(card); - -err: return err; } @@ -929,21 +928,37 @@ */ static int mmc_sdio_pre_suspend(struct mmc_host *host) { - int i, err = 0; + int i; for (i = 0; i < host->card->sdio_funcs; i++) { struct sdio_func *func = host->card->sdio_func[i]; if (func && sdio_func_present(func) && func->dev.driver) { const struct dev_pm_ops *pmops = func->dev.driver->pm; - if (!pmops || !pmops->suspend || !pmops->resume) { + if (!pmops || !pmops->suspend || !pmops->resume) /* force removal of entire card in that case */ - err = -ENOSYS; - break; - } + goto remove; } } - return err; + return 0; + +remove: + if (!mmc_card_is_removable(host)) { + dev_warn(mmc_dev(host), + "missing suspend/resume ops for non-removable SDIO card\n"); + /* Don't remove a non-removable card - we can't re-detect it. */ + return 0; + } + + /* Remove the SDIO card and let it be re-detected later on. */ + mmc_sdio_remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + + return 0; } /* @@ -1001,8 +1016,14 @@ } err = mmc_sdio_reinit_card(host); } else if (mmc_card_wake_sdio_irq(host)) { - /* We may have switched to 1-bit mode during suspend */ + /* + * We may have switched to 1-bit mode during suspend, + * need to hold retuning, because tuning only supprt + * 4-bit mode or 8 bit mode. + */ + mmc_retune_hold_now(host); err = sdio_enable_4bit_bus(host->card); + mmc_retune_release(host); } if (err) @@ -1048,9 +1069,35 @@ return ret; } +/* + * SDIO HW reset + * + * Returns 0 if the HW reset was executed synchronously, returns 1 if the HW + * reset was asynchronously scheduled, else a negative error code. + */ static int mmc_sdio_hw_reset(struct mmc_host *host) { - mmc_power_cycle(host, host->card->ocr); + struct mmc_card *card = host->card; + + /* + * In case the card is shared among multiple func drivers, reset the + * card through a rescan work. In this way it will be removed and + * re-detected, thus all func drivers becomes informed about it. + */ + if (atomic_read(&card->sdio_funcs_probed) > 1) { + if (mmc_card_removed(card)) + return 1; + host->rescan_entered = 0; + mmc_card_set_removed(card); + _mmc_detect_change(host, 0, false); + return 1; + } + + /* + * A single func driver has been probed, then let's skip the heavy + * hotplug dance above and execute the reset immediately. + */ + mmc_power_cycle(host, card->ocr); return mmc_sdio_reinit_card(host); } --- linux-oracle-5.4.0.orig/drivers/mmc/core/sdio_bus.c +++ linux-oracle-5.4.0/drivers/mmc/core/sdio_bus.c @@ -138,6 +138,8 @@ if (ret) return ret; + atomic_inc(&func->card->sdio_funcs_probed); + /* Unbound SDIO functions are always suspended. * During probe, the function is set active and the usage count * is incremented. If the driver supports runtime PM, @@ -153,7 +155,10 @@ /* Set the default block size so the driver is sure it's something * sensible. */ sdio_claim_host(func); - ret = sdio_set_block_size(func, 0); + if (mmc_card_removed(func->card)) + ret = -ENOMEDIUM; + else + ret = sdio_set_block_size(func, 0); sdio_release_host(func); if (ret) goto disable_runtimepm; @@ -165,6 +170,7 @@ return 0; disable_runtimepm: + atomic_dec(&func->card->sdio_funcs_probed); if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) pm_runtime_put_noidle(dev); dev_pm_domain_detach(dev, false); @@ -181,6 +187,7 @@ pm_runtime_get_sync(dev); drv->remove(func); + atomic_dec(&func->card->sdio_funcs_probed); if (func->irq_handler) { pr_warn("WARNING: driver %s did not remove its interrupt handler!\n", @@ -259,7 +266,14 @@ { struct sdio_func *func = dev_to_sdio_func(dev); - sdio_free_func_cis(func); + if (!(func->card->quirks & MMC_QUIRK_NONSTD_SDIO)) + sdio_free_func_cis(func); + + /* + * We have now removed the link to the tuples in the + * card structure, so remove the reference. + */ + put_device(&func->card->dev); kfree(func->info); kfree(func->tmpbuf); @@ -291,6 +305,12 @@ device_initialize(&func->dev); + /* + * We may link to tuples in the card structure, + * we need make sure we have a reference to it. + */ + get_device(&func->card->dev); + func->dev.parent = &card->dev; func->dev.bus = &sdio_bus_type; func->dev.release = sdio_release_func; @@ -344,10 +364,9 @@ */ void sdio_remove_func(struct sdio_func *func) { - if (!sdio_func_present(func)) - return; + if (sdio_func_present(func)) + device_del(&func->dev); - device_del(&func->dev); of_node_put(func->dev.of_node); put_device(&func->dev); } --- linux-oracle-5.4.0.orig/drivers/mmc/core/sdio_cis.c +++ linux-oracle-5.4.0/drivers/mmc/core/sdio_cis.c @@ -20,12 +20,17 @@ #include "sdio_cis.h" #include "sdio_ops.h" +#define SDIO_READ_CIS_TIMEOUT_MS (10 * 1000) /* 10s */ + static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, const unsigned char *buf, unsigned size) { unsigned i, nr_strings; char **buffer, *string; + if (size < 2) + return 0; + /* Find all null-terminated (including zero length) strings in the TPLLV1_INFO field. Trailing garbage is ignored. */ buf += 2; @@ -263,6 +268,8 @@ do { unsigned char tpl_code, tpl_link; + unsigned long timeout = jiffies + + msecs_to_jiffies(SDIO_READ_CIS_TIMEOUT_MS); ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_code); if (ret) @@ -315,6 +322,8 @@ prev = &this->next; if (ret == -ENOENT) { + if (time_after(jiffies, timeout)) + break; /* warn about unknown tuples */ pr_warn_ratelimited("%s: queuing unknown" " CIS tuple 0x%02x (%u bytes)\n", @@ -375,12 +384,6 @@ return ret; /* - * Since we've linked to tuples in the card structure, - * we must make sure we have a reference to it. - */ - get_device(&func->card->dev); - - /* * Vendor/device id is optional for function CIS, so * copy it from the card structure as needed. */ @@ -405,11 +408,5 @@ } func->tuples = NULL; - - /* - * We have now removed the link to the tuples in the - * card structure, so remove the reference. - */ - put_device(&func->card->dev); } --- linux-oracle-5.4.0.orig/drivers/mmc/core/sdio_ops.c +++ linux-oracle-5.4.0/drivers/mmc/core/sdio_ops.c @@ -121,6 +121,7 @@ struct sg_table sgtable; unsigned int nents, left_size, i; unsigned int seg_size = card->host->max_seg_size; + int err; WARN_ON(blksz == 0); @@ -170,28 +171,32 @@ mmc_set_data_timeout(&data, card); - mmc_wait_for_req(card->host, &mrq); + mmc_pre_req(card->host, &mrq); - if (nents > 1) - sg_free_table(&sgtable); + mmc_wait_for_req(card->host, &mrq); if (cmd.error) - return cmd.error; - if (data.error) - return data.error; - - if (mmc_host_is_spi(card->host)) { + err = cmd.error; + else if (data.error) + err = data.error; + else if (mmc_host_is_spi(card->host)) /* host driver already reported errors */ - } else { - if (cmd.resp[0] & R5_ERROR) - return -EIO; - if (cmd.resp[0] & R5_FUNCTION_NUMBER) - return -EINVAL; - if (cmd.resp[0] & R5_OUT_OF_RANGE) - return -ERANGE; - } + err = 0; + else if (cmd.resp[0] & R5_ERROR) + err = -EIO; + else if (cmd.resp[0] & R5_FUNCTION_NUMBER) + err = -EINVAL; + else if (cmd.resp[0] & R5_OUT_OF_RANGE) + err = -ERANGE; + else + err = 0; + + mmc_post_req(card->host, &mrq, err); + + if (nents > 1) + sg_free_table(&sgtable); - return 0; + return err; } int sdio_reset(struct mmc_host *host) --- linux-oracle-5.4.0.orig/drivers/mmc/core/slot-gpio.c +++ linux-oracle-5.4.0/drivers/mmc/core/slot-gpio.c @@ -63,11 +63,15 @@ int mmc_gpio_get_ro(struct mmc_host *host) { struct mmc_gpio *ctx = host->slot.handler_priv; + int cansleep; if (!ctx || !ctx->ro_gpio) return -ENOSYS; - return gpiod_get_value_cansleep(ctx->ro_gpio); + cansleep = gpiod_cansleep(ctx->ro_gpio); + return cansleep ? + gpiod_get_value_cansleep(ctx->ro_gpio) : + gpiod_get_value(ctx->ro_gpio); } EXPORT_SYMBOL(mmc_gpio_get_ro); @@ -241,6 +245,9 @@ return ret; } + if (host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH) + gpiod_toggle_active_low(desc); + if (gpio_invert) *gpio_invert = !gpiod_is_active_low(desc); --- linux-oracle-5.4.0.orig/drivers/mmc/host/Kconfig +++ linux-oracle-5.4.0/drivers/mmc/host/Kconfig @@ -449,7 +449,7 @@ config MMC_WBSD tristate "Winbond W83L51xD SD/MMC Card Interface support" - depends on ISA_DMA_API + depends on ISA_DMA_API && !M68K help This selects the Winbond(R) W83L51xD Secure digital and Multimedia card Interface. @@ -466,11 +466,12 @@ of Alcor Micro PCI-E card reader config MMC_AU1X - tristate "Alchemy AU1XX0 MMC Card Interface support" + bool "Alchemy AU1XX0 MMC Card Interface support" depends on MIPS_ALCHEMY + depends on MMC=y help This selects the AMD Alchemy(R) Multimedia card interface. - If you have a Alchemy platform with a MMC slot, say Y or M here. + If you have a Alchemy platform with a MMC slot, say Y here. If unsure, say N. @@ -995,13 +996,14 @@ config MMC_SDHCI_OMAP tristate "TI SDHCI Controller Support" + depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST depends on MMC_SDHCI_PLTFM && OF select THERMAL imply TI_SOC_THERMAL help This selects the Secure Digital Host Controller Interface (SDHCI) - support present in TI's DRA7 SOCs. The controller supports - SD/MMC/SDIO devices. + support present in TI's Keystone/OMAP2+/DRA7 SOCs. The controller + supports SD/MMC/SDIO devices. If you have a controller with this interface, say Y or M here. --- linux-oracle-5.4.0.orig/drivers/mmc/host/alcor.c +++ linux-oracle-5.4.0/drivers/mmc/host/alcor.c @@ -1104,7 +1104,7 @@ if (ret) { dev_err(&pdev->dev, "Failed to get irq for data line\n"); - return ret; + goto free_host; } mutex_init(&host->cmd_mutex); @@ -1114,8 +1114,15 @@ alcor_hw_init(host); dev_set_drvdata(&pdev->dev, host); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto free_host; + return 0; + +free_host: + mmc_free_host(mmc); + return ret; } static int alcor_pci_sdmmc_drv_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/mmc/host/atmel-mci.c +++ linux-oracle-5.4.0/drivers/mmc/host/atmel-mci.c @@ -1812,7 +1812,6 @@ atmci_writel(host, ATMCI_IER, ATMCI_NOTBUSY); state = STATE_WAITING_NOTBUSY; } else if (host->mrq->stop) { - atmci_writel(host, ATMCI_IER, ATMCI_CMDRDY); atmci_send_stop_cmd(host, data); state = STATE_SENDING_STOP; } else { @@ -1845,8 +1844,6 @@ * command to send. */ if (host->mrq->stop) { - atmci_writel(host, ATMCI_IER, - ATMCI_CMDRDY); atmci_send_stop_cmd(host, data); state = STATE_SENDING_STOP; } else { @@ -2217,6 +2214,7 @@ { struct mmc_host *mmc; struct atmel_mci_slot *slot; + int ret; mmc = mmc_alloc_host(sizeof(struct atmel_mci_slot), &host->pdev->dev); if (!mmc) @@ -2300,11 +2298,13 @@ host->slot[id] = slot; mmc_regulator_get_supply(mmc); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) { + mmc_free_host(mmc); + return ret; + } if (gpio_is_valid(slot->detect_pin)) { - int ret; - timer_setup(&slot->detect_timer, atmci_detect_change, 0); ret = request_irq(gpio_to_irq(slot->detect_pin), --- linux-oracle-5.4.0.orig/drivers/mmc/host/au1xmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/au1xmmc.c @@ -1116,8 +1116,9 @@ if (host->platdata && host->platdata->cd_setup && !(mmc->caps & MMC_CAP_NEEDS_POLL)) host->platdata->cd_setup(mmc, 0); -out_clk: + clk_disable_unprepare(host->clk); +out_clk: clk_put(host->clk); out_irq: free_irq(host->irq, host); --- linux-oracle-5.4.0.orig/drivers/mmc/host/bcm2835.c +++ linux-oracle-5.4.0/drivers/mmc/host/bcm2835.c @@ -1408,8 +1408,8 @@ host->max_clk = clk_get_rate(clk); host->irq = platform_get_irq(pdev, 0); - if (host->irq <= 0) { - ret = -EINVAL; + if (host->irq < 0) { + ret = host->irq; goto err; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/cavium-octeon.c +++ linux-oracle-5.4.0/drivers/mmc/host/cavium-octeon.c @@ -288,6 +288,7 @@ if (ret) { dev_err(&pdev->dev, "Error populating slots\n"); octeon_mmc_set_shared_power(host, 0); + of_node_put(cn); goto error; } i++; --- linux-oracle-5.4.0.orig/drivers/mmc/host/cavium-thunderx.c +++ linux-oracle-5.4.0/drivers/mmc/host/cavium-thunderx.c @@ -138,8 +138,10 @@ continue; ret = cvm_mmc_of_slot_probe(&host->slot_pdev[i]->dev, host); - if (ret) + if (ret) { + of_node_put(child_node); goto error; + } } i++; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/cqhci.c +++ linux-oracle-5.4.0/drivers/mmc/host/cqhci.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -272,6 +273,9 @@ cqhci_writel(cq_host, cqcfg, CQHCI_CFG); + if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) + cqhci_writel(cq_host, 0, CQHCI_CTL); + mmc->cqe_on = true; if (cq_host->ops->enable) @@ -298,16 +302,16 @@ cq_host->activated = false; } -int cqhci_suspend(struct mmc_host *mmc) +int cqhci_deactivate(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; - if (cq_host->enabled) + if (cq_host->enabled && cq_host->activated) __cqhci_disable(cq_host); return 0; } -EXPORT_SYMBOL(cqhci_suspend); +EXPORT_SYMBOL(cqhci_deactivate); int cqhci_resume(struct mmc_host *mmc) { @@ -343,12 +347,16 @@ /* CQHCI is idle and should halt immediately, so set a small timeout */ #define CQHCI_OFF_TIMEOUT 100 +static u32 cqhci_read_ctl(struct cqhci_host *cq_host) +{ + return cqhci_readl(cq_host, CQHCI_CTL); +} + static void cqhci_off(struct mmc_host *mmc) { struct cqhci_host *cq_host = mmc->cqe_private; - ktime_t timeout; - bool timed_out; u32 reg; + int err; if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) return; @@ -358,15 +366,9 @@ cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); - timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT); - while (1) { - timed_out = ktime_compare(ktime_get(), timeout) > 0; - reg = cqhci_readl(cq_host, CQHCI_CTL); - if ((reg & CQHCI_HALT) || timed_out) - break; - } - - if (timed_out) + err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg, + reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT); + if (err < 0) pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); else pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); @@ -876,8 +878,8 @@ ret = cqhci_tasks_cleared(cq_host); if (!ret) - pr_debug("%s: cqhci: Failed to clear tasks\n", - mmc_hostname(mmc)); + pr_warn("%s: cqhci: Failed to clear tasks\n", + mmc_hostname(mmc)); return ret; } @@ -910,7 +912,7 @@ ret = cqhci_halted(cq_host); if (!ret) - pr_debug("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); + pr_warn("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); return ret; } @@ -918,10 +920,10 @@ /* * After halting we expect to be able to use the command line. We interpret the * failure to halt to mean the data lines might still be in use (and the upper - * layers will need to send a STOP command), so we set the timeout based on a - * generous command timeout. + * layers will need to send a STOP command), however failing to halt complicates + * the recovery, so set a timeout that would reasonably allow I/O to complete. */ -#define CQHCI_START_HALT_TIMEOUT 5 +#define CQHCI_START_HALT_TIMEOUT 500 static void cqhci_recovery_start(struct mmc_host *mmc) { @@ -1009,28 +1011,28 @@ ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); - if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) - ok = false; - /* * The specification contradicts itself, by saying that tasks cannot be * cleared if CQHCI does not halt, but if CQHCI does not halt, it should * be disabled/re-enabled, but not to disable before clearing tasks. * Have a go anyway. */ - if (!ok) { - pr_debug("%s: cqhci: disable / re-enable\n", mmc_hostname(mmc)); - cqcfg = cqhci_readl(cq_host, CQHCI_CFG); - cqcfg &= ~CQHCI_ENABLE; - cqhci_writel(cq_host, cqcfg, CQHCI_CFG); - cqcfg |= CQHCI_ENABLE; - cqhci_writel(cq_host, cqcfg, CQHCI_CFG); - /* Be sure that there are no tasks */ - ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); - if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) - ok = false; - WARN_ON(!ok); - } + if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) + ok = false; + + /* Disable to make sure tasks really are cleared */ + cqcfg = cqhci_readl(cq_host, CQHCI_CFG); + cqcfg &= ~CQHCI_ENABLE; + cqhci_writel(cq_host, cqcfg, CQHCI_CFG); + + cqcfg = cqhci_readl(cq_host, CQHCI_CFG); + cqcfg |= CQHCI_ENABLE; + cqhci_writel(cq_host, cqcfg, CQHCI_CFG); + + cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); + + if (!ok) + cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT); cqhci_recover_mrqs(cq_host); --- linux-oracle-5.4.0.orig/drivers/mmc/host/cqhci.h +++ linux-oracle-5.4.0/drivers/mmc/host/cqhci.h @@ -230,7 +230,11 @@ int data_error); int cqhci_init(struct cqhci_host *cq_host, struct mmc_host *mmc, bool dma64); struct cqhci_host *cqhci_pltfm_init(struct platform_device *pdev); -int cqhci_suspend(struct mmc_host *mmc); +int cqhci_deactivate(struct mmc_host *mmc); +static inline int cqhci_suspend(struct mmc_host *mmc) +{ + return cqhci_deactivate(mmc); +} int cqhci_resume(struct mmc_host *mmc); #endif --- linux-oracle-5.4.0.orig/drivers/mmc/host/davinci_mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/davinci_mmc.c @@ -1348,7 +1348,7 @@ return ret; } -static int __exit davinci_mmcsd_remove(struct platform_device *pdev) +static int davinci_mmcsd_remove(struct platform_device *pdev) { struct mmc_davinci_host *host = platform_get_drvdata(pdev); @@ -1376,8 +1376,12 @@ static int davinci_mmcsd_resume(struct device *dev) { struct mmc_davinci_host *host = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(host->clk); + if (ret) + return ret; - clk_enable(host->clk); mmc_davinci_reset_ctrl(host, 0); return 0; @@ -1400,7 +1404,7 @@ .of_match_table = davinci_mmc_dt_ids, }, .probe = davinci_mmcsd_probe, - .remove = __exit_p(davinci_mmcsd_remove), + .remove = davinci_mmcsd_remove, .id_table = davinci_mmc_devtype, }; --- linux-oracle-5.4.0.orig/drivers/mmc/host/dw_mmc-exynos.c +++ linux-oracle-5.4.0/drivers/mmc/host/dw_mmc-exynos.c @@ -462,6 +462,18 @@ } } + /* + * If there is no cadiates value, then it needs to return -EIO. + * If there are candiates values and don't find bset clk sample value, + * then use a first candiates clock sample value. + */ + for (i = 0; i < iter; i++) { + __c = ror8(candiates, i); + if ((__c & 0x1) == 0x1) { + loc = i; + goto out; + } + } out: return loc; } @@ -492,6 +504,8 @@ priv->tuned_sample = found; } else { ret = -EIO; + dev_warn(&mmc->class_dev, + "There is no candiates value about clksmpl!\n"); } return ret; --- linux-oracle-5.4.0.orig/drivers/mmc/host/dw_mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/dw_mmc.c @@ -782,6 +782,7 @@ int ret = 0; /* Set external dma config: burst size, burst width */ + memset(&cfg, 0, sizeof(cfg)); cfg.dst_addr = host->phy_regs + fifo_offset; cfg.src_addr = cfg.dst_addr; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -2012,13 +2013,14 @@ * delayed. Allowing the transfer to take place * avoids races and keeps things simple. */ - if (err != -ETIMEDOUT) { + if (err != -ETIMEDOUT && + host->dir_status == DW_MCI_RECV_STATUS) { state = STATE_SENDING_DATA; continue; } - dw_mci_stop_dma(host); send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_SENDING_STOP; break; } @@ -2042,10 +2044,10 @@ */ if (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) { - dw_mci_stop_dma(host); if (!(host->data_status & (SDMMC_INT_DRTO | SDMMC_INT_EBE))) send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_DATA_ERROR; break; } @@ -2078,10 +2080,10 @@ */ if (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) { - dw_mci_stop_dma(host); if (!(host->data_status & (SDMMC_INT_DRTO | SDMMC_INT_EBE))) send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_DATA_ERROR; break; } @@ -3177,6 +3179,10 @@ host->biu_clk = devm_clk_get(host->dev, "biu"); if (IS_ERR(host->biu_clk)) { dev_dbg(host->dev, "biu clock not available\n"); + ret = PTR_ERR(host->biu_clk); + if (ret == -EPROBE_DEFER) + return ret; + } else { ret = clk_prepare_enable(host->biu_clk); if (ret) { @@ -3188,6 +3194,10 @@ host->ciu_clk = devm_clk_get(host->dev, "ciu"); if (IS_ERR(host->ciu_clk)) { dev_dbg(host->dev, "ciu clock not available\n"); + ret = PTR_ERR(host->ciu_clk); + if (ret == -EPROBE_DEFER) + goto err_clk_biu; + host->bus_hz = host->pdata->bus_hz; } else { ret = clk_prepare_enable(host->ciu_clk); --- linux-oracle-5.4.0.orig/drivers/mmc/host/jz4740_mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/jz4740_mmc.c @@ -224,6 +224,26 @@ return PTR_ERR(host->dma_rx); } + /* + * Limit the maximum segment size in any SG entry according to + * the parameters of the DMA engine device. + */ + if (host->dma_tx) { + struct device *dev = host->dma_tx->device->dev; + unsigned int max_seg_size = dma_get_max_seg_size(dev); + + if (max_seg_size < host->mmc->max_seg_size) + host->mmc->max_seg_size = max_seg_size; + } + + if (host->dma_rx) { + struct device *dev = host->dma_rx->device->dev; + unsigned int max_seg_size = dma_get_max_seg_size(dev); + + if (max_seg_size < host->mmc->max_seg_size) + host->mmc->max_seg_size = max_seg_size; + } + return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/meson-gx-mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/meson-gx-mmc.c @@ -166,6 +166,7 @@ unsigned int bounce_buf_size; void *bounce_buf; + void __iomem *bounce_iomem_buf; dma_addr_t bounce_dma_addr; struct sd_emmc_desc *descs; dma_addr_t descs_dma_addr; @@ -173,6 +174,8 @@ int irq; bool vqmmc_enabled; + bool needs_pre_post_req; + }; #define CMD_CFG_LENGTH_MASK GENMASK(8, 0) @@ -654,6 +657,8 @@ struct meson_host *host = mmc_priv(mmc); host->cmd = NULL; + if (host->needs_pre_post_req) + meson_mmc_post_req(mmc, mrq, 0); mmc_request_done(host->mmc, mrq); } @@ -737,6 +742,53 @@ writel(start, host->regs + SD_EMMC_START); } +/* local sg copy for dram_access_quirk */ +static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, + size_t buflen, bool to_buffer) +{ + unsigned int sg_flags = SG_MITER_ATOMIC; + struct scatterlist *sgl = data->sg; + unsigned int nents = data->sg_len; + struct sg_mapping_iter miter; + unsigned int offset = 0; + + if (to_buffer) + sg_flags |= SG_MITER_FROM_SG; + else + sg_flags |= SG_MITER_TO_SG; + + sg_miter_start(&miter, sgl, nents, sg_flags); + + while ((offset < buflen) && sg_miter_next(&miter)) { + unsigned int buf_offset = 0; + unsigned int len, left; + u32 *buf = miter.addr; + + len = min(miter.length, buflen - offset); + left = len; + + if (to_buffer) { + do { + writel(*buf++, host->bounce_iomem_buf + offset + buf_offset); + + buf_offset += 4; + left -= 4; + } while (left); + } else { + do { + *buf++ = readl(host->bounce_iomem_buf + offset + buf_offset); + + buf_offset += 4; + left -= 4; + } while (left); + } + + offset += len; + } + + sg_miter_stop(&miter); +} + static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_host *host = mmc_priv(mmc); @@ -751,7 +803,6 @@ cmd_cfg |= FIELD_PREP(CMD_CFG_CMD_INDEX_MASK, cmd->opcode); cmd_cfg |= CMD_CFG_OWNER; /* owned by CPU */ - cmd_cfg |= CMD_CFG_ERROR; /* stop in case of error */ meson_mmc_set_response_bits(cmd, &cmd_cfg); @@ -780,8 +831,11 @@ if (data->flags & MMC_DATA_WRITE) { cmd_cfg |= CMD_CFG_DATA_WR; WARN_ON(xfer_bytes > host->bounce_buf_size); - sg_copy_to_buffer(data->sg, data->sg_len, - host->bounce_buf, xfer_bytes); + if (host->dram_access_quirk) + meson_mmc_copy_buffer(host, data, xfer_bytes, true); + else + sg_copy_to_buffer(data->sg, data->sg_len, + host->bounce_buf, xfer_bytes); dma_wmb(); } @@ -800,28 +854,56 @@ writel(cmd->arg, host->regs + SD_EMMC_CMD_ARG); } +static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data *data) +{ + struct scatterlist *sg; + int i; + + /* Reject request if any element offset or size is not 32bit aligned */ + for_each_sg(data->sg, sg, data->sg_len, i) { + if (!IS_ALIGNED(sg->offset, sizeof(u32)) || + !IS_ALIGNED(sg->length, sizeof(u32))) { + dev_err(mmc_dev(mmc), "unaligned sg offset %u len %u\n", + data->sg->offset, data->sg->length); + return -EINVAL; + } + } + + return 0; +} + static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) { struct meson_host *host = mmc_priv(mmc); - bool needs_pre_post_req = mrq->data && + host->needs_pre_post_req = mrq->data && !(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE); - if (needs_pre_post_req) { + /* + * The memory at the end of the controller used as bounce buffer for + * the dram_access_quirk only accepts 32bit read/write access, + * check the aligment and length of the data before starting the request. + */ + if (host->dram_access_quirk && mrq->data) { + mrq->cmd->error = meson_mmc_validate_dram_access(mmc, mrq->data); + if (mrq->cmd->error) { + mmc_request_done(mmc, mrq); + return; + } + } + + if (host->needs_pre_post_req) { meson_mmc_get_transfer_mode(mmc, mrq); if (!meson_mmc_desc_chain_mode(mrq->data)) - needs_pre_post_req = false; + host->needs_pre_post_req = false; } - if (needs_pre_post_req) + if (host->needs_pre_post_req) meson_mmc_pre_req(mmc, mrq); /* Stop execution */ writel(0, host->regs + SD_EMMC_START); meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd); - - if (needs_pre_post_req) - meson_mmc_post_req(mmc, mrq, 0); } static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd) @@ -890,11 +972,8 @@ if (status & (IRQ_END_OF_CHAIN | IRQ_RESP_STATUS)) { if (data && !cmd->error) data->bytes_xfered = data->blksz * data->blocks; - if (meson_mmc_bounce_buf_read(data) || - meson_mmc_get_next_command(cmd)) - ret = IRQ_WAKE_THREAD; - else - ret = IRQ_HANDLED; + + return IRQ_WAKE_THREAD; } out: @@ -906,9 +985,6 @@ writel(start, host->regs + SD_EMMC_START); } - if (ret == IRQ_HANDLED) - meson_mmc_request_done(host->mmc, cmd->mrq); - return ret; } @@ -950,8 +1026,11 @@ if (meson_mmc_bounce_buf_read(data)) { xfer_bytes = data->blksz * data->blocks; WARN_ON(xfer_bytes > host->bounce_buf_size); - sg_copy_from_buffer(data->sg, data->sg_len, - host->bounce_buf, xfer_bytes); + if (host->dram_access_quirk) + meson_mmc_copy_buffer(host, data, xfer_bytes, false); + else + sg_copy_from_buffer(data->sg, data->sg_len, + host->bounce_buf, xfer_bytes); } next_cmd = meson_mmc_get_next_command(cmd); @@ -1151,9 +1230,11 @@ mmc->caps |= MMC_CAP_CMD23; if (host->dram_access_quirk) { + /* Limit segments to 1 due to low available sram memory */ + mmc->max_segs = 1; /* Limit to the available sram memory */ - mmc->max_segs = SD_EMMC_SRAM_DATA_BUF_LEN / mmc->max_blk_size; - mmc->max_blk_count = mmc->max_segs; + mmc->max_blk_count = SD_EMMC_SRAM_DATA_BUF_LEN / + mmc->max_blk_size; } else { mmc->max_blk_count = CMD_CFG_LENGTH_MASK; mmc->max_segs = SD_EMMC_DESC_BUF_LEN / @@ -1177,7 +1258,7 @@ * instead of the DDR memory */ host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN; - host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; + host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF; } else { /* data bounce buffer */ @@ -1201,7 +1282,9 @@ } mmc->ops = &meson_mmc_ops; - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto err_free_irq; return 0; --- linux-oracle-5.4.0.orig/drivers/mmc/host/meson-mx-sdio.c +++ linux-oracle-5.4.0/drivers/mmc/host/meson-mx-sdio.c @@ -246,6 +246,9 @@ mrq = host->mrq; + if (host->cmd->error) + meson_mx_mmc_soft_reset(host); + host->mrq = NULL; host->cmd = NULL; @@ -357,14 +360,6 @@ meson_mx_mmc_start_cmd(mmc, mrq->cmd); } -static int meson_mx_mmc_card_busy(struct mmc_host *mmc) -{ - struct meson_mx_mmc_host *host = mmc_priv(mmc); - u32 irqc = readl(host->base + MESON_MX_SDIO_IRQC); - - return !!(irqc & MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK); -} - static void meson_mx_mmc_read_response(struct mmc_host *mmc, struct mmc_command *cmd) { @@ -506,7 +501,6 @@ static struct mmc_host_ops meson_mx_mmc_ops = { .request = meson_mx_mmc_request, .set_ios = meson_mx_mmc_set_ios, - .card_busy = meson_mx_mmc_card_busy, .get_cd = mmc_gpio_get_cd, .get_ro = mmc_gpio_get_ro, }; @@ -570,7 +564,7 @@ mmc->f_max = clk_round_rate(host->cfg_div_clk, clk_get_rate(host->parent_clk)); - mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; + mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY; mmc->ops = &meson_mx_mmc_ops; ret = mmc_of_parse(mmc); @@ -671,6 +665,11 @@ } irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto error_free_mmc; + } + ret = devm_request_threaded_irq(host->controller_dev, irq, meson_mx_mmc_irq, meson_mx_mmc_irq_thread, IRQF_ONESHOT, --- linux-oracle-5.4.0.orig/drivers/mmc/host/mmc_spi.c +++ linux-oracle-5.4.0/drivers/mmc/host/mmc_spi.c @@ -255,10 +255,6 @@ u8 leftover = 0; unsigned short rotator; int i; - char tag[32]; - - snprintf(tag, sizeof(tag), " ... CMD%d response SPI_%s", - cmd->opcode, maptype(cmd)); /* Except for data block reads, the whole response will already * be stored in the scratch buffer. It's somewhere after the @@ -408,8 +404,9 @@ } if (value < 0) - dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n", - tag, cmd->resp[0], cmd->resp[1]); + dev_dbg(&host->spi->dev, + " ... CMD%d response SPI_%s: resp %04x %08x\n", + cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]); /* disable chipselect on errors and some success cases */ if (value >= 0 && cs_on) @@ -1134,17 +1131,22 @@ * SPI protocol. Another is that when chipselect is released while * the card returns BUSY status, the clock must issue several cycles * with chipselect high before the card will stop driving its output. + * + * SPI_CS_HIGH means "asserted" here. In some cases like when using + * GPIOs for chip select, SPI_CS_HIGH is set but this will be logically + * inverted by gpiolib, so if we want to ascertain to drive it high + * we should toggle the default with an XOR as we do here. */ - host->spi->mode |= SPI_CS_HIGH; + host->spi->mode ^= SPI_CS_HIGH; if (spi_setup(host->spi) != 0) { /* Just warn; most cards work without it. */ dev_warn(&host->spi->dev, "can't change chip-select polarity\n"); - host->spi->mode &= ~SPI_CS_HIGH; + host->spi->mode ^= SPI_CS_HIGH; } else { mmc_spi_readbytes(host, 18); - host->spi->mode &= ~SPI_CS_HIGH; + host->spi->mode ^= SPI_CS_HIGH; if (spi_setup(host->spi) != 0) { /* Wot, we can't get the same setup we had before? */ dev_err(&host->spi->dev, @@ -1415,7 +1417,7 @@ status = mmc_add_host(mmc); if (status != 0) - goto fail_add_host; + goto fail_glue_init; /* * Index 0 is card detect @@ -1423,7 +1425,7 @@ */ status = mmc_gpiod_request_cd(mmc, NULL, 0, false, 1, NULL); if (status == -EPROBE_DEFER) - goto fail_add_host; + goto fail_gpiod_request; if (!status) { /* * The platform has a CD GPIO signal that may support @@ -1438,7 +1440,7 @@ /* Index 1 is write protect/read only */ status = mmc_gpiod_request_ro(mmc, NULL, 1, 0, NULL); if (status == -EPROBE_DEFER) - goto fail_add_host; + goto fail_gpiod_request; if (!status) has_ro = true; @@ -1452,7 +1454,7 @@ ? ", cd polling" : ""); return 0; -fail_add_host: +fail_gpiod_request: mmc_remove_host(mmc); fail_glue_init: if (host->dma_dev) --- linux-oracle-5.4.0.orig/drivers/mmc/host/mmci.c +++ linux-oracle-5.4.0/drivers/mmc/host/mmci.c @@ -168,6 +168,8 @@ .cmdreg_srsp = MCI_CPSM_RESPONSE, .datalength_bits = 24, .datactrl_blocksz = 11, + .datactrl_any_blocksz = true, + .dma_power_of_2 = true, .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, .st_sdio = true, .st_clkdiv = true, @@ -201,6 +203,8 @@ .datactrl_mask_ddrmode = MCI_DPSM_ST_DDRMODE, .datalength_bits = 24, .datactrl_blocksz = 11, + .datactrl_any_blocksz = true, + .dma_power_of_2 = true, .datactrl_mask_sdio = MCI_DPSM_ST_SDIOEN, .st_sdio = true, .st_clkdiv = true, @@ -260,6 +264,7 @@ .datacnt_useless = true, .datalength_bits = 25, .datactrl_blocksz = 14, + .datactrl_any_blocksz = true, .stm32_idmabsize_mask = GENMASK(12, 5), .init = sdmmc_variant_init, }; @@ -279,6 +284,7 @@ .data_cmd_enable = MCI_CPSM_QCOM_DATCMD, .datalength_bits = 24, .datactrl_blocksz = 11, + .datactrl_any_blocksz = true, .pwrreg_powerup = MCI_PWR_UP, .f_max = 208000000, .explicit_mclk_control = true, @@ -447,10 +453,11 @@ static int mmci_validate_data(struct mmci_host *host, struct mmc_data *data) { + struct variant_data *variant = host->variant; + if (!data) return 0; - - if (!is_power_of_2(data->blksz)) { + if (!is_power_of_2(data->blksz) && !variant->datactrl_any_blocksz) { dev_err(mmc_dev(host->mmc), "unsupported block size (%d bytes)\n", data->blksz); return -EINVAL; @@ -515,7 +522,9 @@ "Submit MMCI DMA job, sglen %d blksz %04x blks %04x flags %08x\n", data->sg_len, data->blksz, data->blocks, data->flags); - host->ops->dma_start(host, &datactrl); + ret = host->ops->dma_start(host, &datactrl); + if (ret) + return ret; /* Trigger the DMA transfer */ mmci_write_datactrlreg(host, datactrl); @@ -822,6 +831,18 @@ if (data->blksz * data->blocks <= variant->fifosize) return -EINVAL; + /* + * This is necessary to get SDIO working on the Ux500. We do not yet + * know if this is a bug in: + * - The Ux500 DMA controller (DMA40) + * - The MMCI DMA interface on the Ux500 + * some power of two blocks (such as 64 bytes) are sent regularly + * during SDIO traffic and those work fine so for these we enable DMA + * transfers. + */ + if (host->variant->dma_power_of_2 && !is_power_of_2(data->blksz)) + return -EINVAL; + device = chan->device; nr_sg = dma_map_sg(device->dev, data->sg, data->sg_len, mmc_get_dma_dir(data)); @@ -872,9 +893,14 @@ int mmci_dmae_start(struct mmci_host *host, unsigned int *datactrl) { struct mmci_dmae_priv *dmae = host->dma_priv; + int ret; host->dma_in_progress = true; - dmaengine_submit(dmae->desc_current); + ret = dma_submit_error(dmaengine_submit(dmae->desc_current)); + if (ret < 0) { + host->dma_in_progress = false; + return ret; + } dma_async_issue_pending(dmae->cur); *datactrl |= MCI_DPSM_DMAENABLE; @@ -2053,7 +2079,9 @@ pm_runtime_set_autosuspend_delay(&dev->dev, 50); pm_runtime_use_autosuspend(&dev->dev); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto clk_disable; pm_runtime_put(&dev->dev); return 0; --- linux-oracle-5.4.0.orig/drivers/mmc/host/mmci.h +++ linux-oracle-5.4.0/drivers/mmc/host/mmci.h @@ -278,7 +278,11 @@ * @stm32_clkdiv: true if using a STM32-specific clock divider algorithm * @datactrl_mask_ddrmode: ddr mode mask in datactrl register. * @datactrl_mask_sdio: SDIO enable mask in datactrl register - * @datactrl_blksz: block size in power of two + * @datactrl_blocksz: block size in power of two + * @datactrl_any_blocksz: true if block any block sizes are accepted by + * hardware, such as with some SDIO traffic that send + * odd packets. + * @dma_power_of_2: DMA only works with blocks that are a power of 2. * @datactrl_first: true if data must be setup before send command * @datacnt_useless: true if you could not use datacnt register to read * remaining data @@ -323,6 +327,8 @@ unsigned int datactrl_mask_ddrmode; unsigned int datactrl_mask_sdio; unsigned int datactrl_blocksz; + u8 datactrl_any_blocksz:1; + u8 dma_power_of_2:1; u8 datactrl_first:1; u8 datacnt_useless:1; u8 st_sdio:1; --- linux-oracle-5.4.0.orig/drivers/mmc/host/mmci_stm32_sdmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/mmci_stm32_sdmmc.c @@ -20,14 +20,19 @@ u32 idmasize; }; -struct sdmmc_priv { +struct sdmmc_idma { dma_addr_t sg_dma; void *sg_cpu; + dma_addr_t bounce_dma_addr; + void *bounce_buf; + bool use_bounce_buffer; }; int sdmmc_idma_validate_data(struct mmci_host *host, struct mmc_data *data) { + struct sdmmc_idma *idma = host->dma_priv; + struct device *dev = mmc_dev(host->mmc); struct scatterlist *sg; int i; @@ -35,41 +40,69 @@ * idma has constraints on idmabase & idmasize for each element * excepted the last element which has no constraint on idmasize */ + idma->use_bounce_buffer = false; for_each_sg(data->sg, sg, data->sg_len - 1, i) { - if (!IS_ALIGNED(sg_dma_address(data->sg), sizeof(u32)) || - !IS_ALIGNED(sg_dma_len(data->sg), SDMMC_IDMA_BURST)) { - dev_err(mmc_dev(host->mmc), + if (!IS_ALIGNED(sg->offset, sizeof(u32)) || + !IS_ALIGNED(sg->length, SDMMC_IDMA_BURST)) { + dev_dbg(mmc_dev(host->mmc), "unaligned scatterlist: ofst:%x length:%d\n", data->sg->offset, data->sg->length); - return -EINVAL; + goto use_bounce_buffer; } } - if (!IS_ALIGNED(sg_dma_address(data->sg), sizeof(u32))) { - dev_err(mmc_dev(host->mmc), + if (!IS_ALIGNED(sg->offset, sizeof(u32))) { + dev_dbg(mmc_dev(host->mmc), "unaligned last scatterlist: ofst:%x length:%d\n", data->sg->offset, data->sg->length); - return -EINVAL; + goto use_bounce_buffer; } return 0; + +use_bounce_buffer: + if (!idma->bounce_buf) { + idma->bounce_buf = dmam_alloc_coherent(dev, + host->mmc->max_req_size, + &idma->bounce_dma_addr, + GFP_KERNEL); + if (!idma->bounce_buf) { + dev_err(dev, "Unable to map allocate DMA bounce buffer.\n"); + return -ENOMEM; + } + } + + idma->use_bounce_buffer = true; + + return 0; } static int _sdmmc_idma_prep_data(struct mmci_host *host, struct mmc_data *data) { - int n_elem; + struct sdmmc_idma *idma = host->dma_priv; - n_elem = dma_map_sg(mmc_dev(host->mmc), - data->sg, - data->sg_len, - mmc_get_dma_dir(data)); - - if (!n_elem) { - dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); - return -EINVAL; - } + if (idma->use_bounce_buffer) { + if (data->flags & MMC_DATA_WRITE) { + unsigned int xfer_bytes = data->blksz * data->blocks; + + sg_copy_to_buffer(data->sg, data->sg_len, + idma->bounce_buf, xfer_bytes); + dma_wmb(); + } + } else { + int n_elem; + + n_elem = dma_map_sg(mmc_dev(host->mmc), + data->sg, + data->sg_len, + mmc_get_dma_dir(data)); + if (!n_elem) { + dev_err(mmc_dev(host->mmc), "dma_map_sg failed\n"); + return -EINVAL; + } + } return 0; } @@ -86,13 +119,24 @@ static void sdmmc_idma_unprep_data(struct mmci_host *host, struct mmc_data *data, int err) { - dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, - mmc_get_dma_dir(data)); + struct sdmmc_idma *idma = host->dma_priv; + + if (idma->use_bounce_buffer) { + if (data->flags & MMC_DATA_READ) { + unsigned int xfer_bytes = data->blksz * data->blocks; + + sg_copy_from_buffer(data->sg, data->sg_len, + idma->bounce_buf, xfer_bytes); + } + } else { + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + mmc_get_dma_dir(data)); + } } static int sdmmc_idma_setup(struct mmci_host *host) { - struct sdmmc_priv *idma; + struct sdmmc_idma *idma; idma = devm_kzalloc(mmc_dev(host->mmc), sizeof(*idma), GFP_KERNEL); if (!idma) @@ -112,6 +156,8 @@ host->mmc->max_segs = SDMMC_LLI_BUF_LEN / sizeof(struct sdmmc_lli_desc); host->mmc->max_seg_size = host->variant->stm32_idmabsize_mask; + + host->mmc->max_req_size = SZ_1M; } else { host->mmc->max_segs = 1; host->mmc->max_seg_size = host->mmc->max_req_size; @@ -123,14 +169,24 @@ static int sdmmc_idma_start(struct mmci_host *host, unsigned int *datactrl) { - struct sdmmc_priv *idma = host->dma_priv; + struct sdmmc_idma *idma = host->dma_priv; struct sdmmc_lli_desc *desc = (struct sdmmc_lli_desc *)idma->sg_cpu; struct mmc_data *data = host->data; struct scatterlist *sg; int i; - if (!host->variant->dma_lli || data->sg_len == 1) { - writel_relaxed(sg_dma_address(data->sg), + host->dma_in_progress = true; + + if (!host->variant->dma_lli || data->sg_len == 1 || + idma->use_bounce_buffer) { + u32 dma_addr; + + if (idma->use_bounce_buffer) + dma_addr = idma->bounce_dma_addr; + else + dma_addr = sg_dma_address(data->sg); + + writel_relaxed(dma_addr, host->base + MMCI_STM32_IDMABASE0R); writel_relaxed(MMCI_STM32_IDMAEN, host->base + MMCI_STM32_IDMACTRLR); @@ -159,9 +215,33 @@ return 0; } +static void sdmmc_idma_error(struct mmci_host *host) +{ + struct mmc_data *data = host->data; + struct sdmmc_idma *idma = host->dma_priv; + + if (!dma_inprogress(host)) + return; + + writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR); + host->dma_in_progress = false; + data->host_cookie = 0; + + if (!idma->use_bounce_buffer) + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + mmc_get_dma_dir(data)); +} + static void sdmmc_idma_finalize(struct mmci_host *host, struct mmc_data *data) { + if (!dma_inprogress(host)) + return; + writel_relaxed(0, host->base + MMCI_STM32_IDMACTRLR); + host->dma_in_progress = false; + + if (!data->host_cookie) + sdmmc_idma_unprep_data(host, data, 0); } static void mmci_sdmmc_set_clkreg(struct mmci_host *host, unsigned int desired) @@ -290,6 +370,7 @@ .dma_setup = sdmmc_idma_setup, .dma_start = sdmmc_idma_start, .dma_finalize = sdmmc_idma_finalize, + .dma_error = sdmmc_idma_error, .set_clkreg = mmci_sdmmc_set_clkreg, .set_pwrreg = mmci_sdmmc_set_pwrreg, }; --- linux-oracle-5.4.0.orig/drivers/mmc/host/moxart-mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/moxart-mmc.c @@ -111,8 +111,8 @@ #define CLK_DIV_MASK 0x7f /* REG_BUS_WIDTH */ -#define BUS_WIDTH_8 BIT(2) -#define BUS_WIDTH_4 BIT(1) +#define BUS_WIDTH_4_SUPPORT BIT(3) +#define BUS_WIDTH_4 BIT(2) #define BUS_WIDTH_1 BIT(0) #define MMC_VDD_360 23 @@ -339,13 +339,7 @@ return; } for (len = 0; len < remain && len < host->fifo_width;) { - /* SCR data must be read in big endian. */ - if (data->mrq->cmd->opcode == SD_APP_SEND_SCR) - *sgp = ioread32be(host->base + - REG_DATA_WINDOW); - else - *sgp = ioread32(host->base + - REG_DATA_WINDOW); + *sgp = ioread32(host->base + REG_DATA_WINDOW); sgp++; len += 4; } @@ -527,9 +521,6 @@ case MMC_BUS_WIDTH_4: writel(BUS_WIDTH_4, host->base + REG_BUS_WIDTH); break; - case MMC_BUS_WIDTH_8: - writel(BUS_WIDTH_8, host->base + REG_BUS_WIDTH); - break; default: writel(BUS_WIDTH_1, host->base + REG_BUS_WIDTH); break; @@ -631,6 +622,7 @@ host->dma_chan_tx, host->dma_chan_rx); host->have_dma = true; + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -645,16 +637,8 @@ dmaengine_slave_config(host->dma_chan_rx, &cfg); } - switch ((readl(host->base + REG_BUS_WIDTH) >> 3) & 3) { - case 1: + if (readl(host->base + REG_BUS_WIDTH) & BUS_WIDTH_4_SUPPORT) mmc->caps |= MMC_CAP_4_BIT_DATA; - break; - case 2: - mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA; - break; - default: - break; - } writel(0, host->base + REG_INTERRUPT_MASK); @@ -670,7 +654,9 @@ goto out; dev_set_drvdata(dev, mmc); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto out; dev_dbg(dev, "IRQ=%d, FIFO is %d bytes\n", irq, host->fifo_width); @@ -695,12 +681,12 @@ if (!IS_ERR(host->dma_chan_rx)) dma_release_channel(host->dma_chan_rx); mmc_remove_host(mmc); - mmc_free_host(mmc); writel(0, host->base + REG_INTERRUPT_MASK); writel(0, host->base + REG_POWER_CONTROL); writel(readl(host->base + REG_CLOCK_CONTROL) | CLK_OFF, host->base + REG_CLOCK_CONTROL); + mmc_free_host(mmc); } return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/mtk-sd.c +++ linux-oracle-5.4.0/drivers/mmc/host/mtk-sd.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -228,6 +229,7 @@ #define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ #define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ +#define MSDC_PATCH_BIT1_CMDTA (0x7 << 3) /* RW */ #define MSDC_PATCH_BIT1_STOP_DLY (0xf << 8) /* RW */ #define MSDC_PATCH_BIT2_CFGRESP (0x1 << 15) /* RW */ @@ -411,6 +413,7 @@ struct pinctrl_state *pins_uhs; struct delayed_work req_timeout; int irq; /* host interrupt */ + struct reset_control *reset; struct clk *src_clk; /* msdc source clock */ struct clk *h_clk; /* msdc h_clk */ @@ -1017,13 +1020,13 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) { unsigned long flags; - bool ret; - ret = cancel_delayed_work(&host->req_timeout); - if (!ret) { - /* delay work already running */ - return; - } + /* + * No need check the return value of cancel_delayed_work, as only ONE + * path will go here! + */ + cancel_delayed_work(&host->req_timeout); + spin_lock_irqsave(&host->lock, flags); host->mrq = NULL; spin_unlock_irqrestore(&host->lock, flags); @@ -1043,7 +1046,7 @@ bool done = false; bool sbc_error; unsigned long flags; - u32 *rsp = cmd->resp; + u32 *rsp; if (mrq->sbc && cmd == mrq->cmd && (events & (MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR @@ -1064,6 +1067,7 @@ if (done) return true; + rsp = cmd->resp; sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask); @@ -1251,7 +1255,7 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, struct mmc_request *mrq, struct mmc_data *data) { - struct mmc_command *stop = data->stop; + struct mmc_command *stop; unsigned long flags; bool done; unsigned int check_data = events & @@ -1267,6 +1271,7 @@ if (done) return true; + stop = data->stop; if (check_data || (stop && stop->error)) { dev_dbg(host->dev, "DMA status: 0x%8X\n", @@ -1473,6 +1478,12 @@ u32 val; u32 tune_reg = host->dev_comp->pad_tune_reg; + if (host->reset) { + reset_control_assert(host->reset); + usleep_range(10, 50); + reset_control_deassert(host->reset); + } + /* Configure to MMC/SD mode, clock free running */ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN); @@ -1881,6 +1892,7 @@ /* select EMMC50 PAD CMD tune */ sdr_set_bits(host->base + PAD_CMD_TUNE, BIT(0)); + sdr_set_field(host->base + MSDC_PATCH_BIT1, MSDC_PATCH_BIT1_CMDTA, 2); if (mmc->ios.timing == MMC_TIMING_MMC_HS200 || mmc->ios.timing == MMC_TIMING_UHS_SDR104) @@ -2230,9 +2242,14 @@ if (IS_ERR(host->src_clk_cg)) host->src_clk_cg = NULL; + host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev, + "hrst"); + if (IS_ERR(host->reset)) + return PTR_ERR(host->reset); + host->irq = platform_get_irq(pdev, 0); if (host->irq < 0) { - ret = -EINVAL; + ret = host->irq; goto host_free; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/mvsdio.c +++ linux-oracle-5.4.0/drivers/mmc/host/mvsdio.c @@ -696,17 +696,15 @@ struct mmc_host *mmc = NULL; struct mvsd_host *host = NULL; const struct mbus_dram_target_info *dram; - struct resource *r; int ret, irq; if (!np) { dev_err(&pdev->dev, "no DT node\n"); return -ENODEV; } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); - if (!r || irq < 0) - return -ENXIO; + if (irq < 0) + return irq; mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev); if (!mmc) { @@ -758,7 +756,7 @@ spin_lock_init(&host->lock); - host->base = devm_ioremap_resource(&pdev->dev, r); + host->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(host->base)) { ret = PTR_ERR(host->base); goto out; --- linux-oracle-5.4.0.orig/drivers/mmc/host/mxcmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/mxcmmc.c @@ -1158,7 +1158,9 @@ timer_setup(&host->watchdog, mxcmci_watchdog, 0); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto out_free_dma; return 0; --- linux-oracle-5.4.0.orig/drivers/mmc/host/mxs-mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/mxs-mmc.c @@ -565,6 +565,11 @@ }; MODULE_DEVICE_TABLE(of, mxs_mmc_dt_ids); +static void mxs_mmc_regulator_disable(void *regulator) +{ + regulator_disable(regulator); +} + static int mxs_mmc_probe(struct platform_device *pdev) { const struct of_device_id *of_id = @@ -606,6 +611,11 @@ "Failed to enable vmmc regulator: %d\n", ret); goto out_mmc_free; } + + ret = devm_add_action_or_reset(&pdev->dev, mxs_mmc_regulator_disable, + reg_vmmc); + if (ret) + goto out_mmc_free; } ssp->clk = devm_clk_get(&pdev->dev, NULL); @@ -644,7 +654,7 @@ ret = mmc_of_parse(mmc); if (ret) - goto out_clk_disable; + goto out_free_dma; mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; --- linux-oracle-5.4.0.orig/drivers/mmc/host/omap.c +++ linux-oracle-5.4.0/drivers/mmc/host/omap.c @@ -1344,7 +1344,7 @@ irq = platform_get_irq(pdev, 0); if (irq < 0) - return -ENXIO; + return irq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->virt_base = devm_ioremap_resource(&pdev->dev, res); --- linux-oracle-5.4.0.orig/drivers/mmc/host/omap_hsmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/omap_hsmmc.c @@ -1512,6 +1512,36 @@ if (mmc_pdata(host)->init_card) mmc_pdata(host)->init_card(card); + else if (card->type == MMC_TYPE_SDIO || + card->type == MMC_TYPE_SD_COMBO) { + struct device_node *np = mmc_dev(mmc)->of_node; + + /* + * REVISIT: should be moved to sdio core and made more + * general e.g. by expanding the DT bindings of child nodes + * to provide a mechanism to provide this information: + * Documentation/devicetree/bindings/mmc/mmc-card.txt + */ + + np = of_get_compatible_child(np, "ti,wl1251"); + if (np) { + /* + * We have TI wl1251 attached to MMC3. Pass this + * information to the SDIO core because it can't be + * probed by normal methods. + */ + + dev_info(host->dev, "found wl1251\n"); + card->quirks |= MMC_QUIRK_NONSTD_SDIO; + card->cccr.wide_bus = 1; + card->cis.vendor = 0x104c; + card->cis.device = 0x9066; + card->cis.blksize = 512; + card->cis.max_dtr = 24000000; + card->ocr = 0x80; + of_node_put(np); + } + } } static void omap_hsmmc_enable_sdio_irq(struct mmc_host *mmc, int enable) @@ -1813,9 +1843,11 @@ } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (res == NULL || irq < 0) + if (!res) return -ENXIO; + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) @@ -1968,7 +2000,9 @@ if (!ret) mmc->caps |= MMC_CAP_SDIO_IRQ; - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto err_irq; if (mmc_pdata(host)->name != NULL) { ret = device_create_file(&mmc->class_dev, &dev_attr_slot_name); --- linux-oracle-5.4.0.orig/drivers/mmc/host/pxamci.c +++ linux-oracle-5.4.0/drivers/mmc/host/pxamci.c @@ -648,7 +648,7 @@ ret = pxamci_of_init(pdev, mmc); if (ret) - return ret; + goto out; host = mmc_priv(mmc); host->mmc = mmc; @@ -672,7 +672,7 @@ ret = pxamci_init_ocr(host); if (ret < 0) - return ret; + goto out; mmc->caps = 0; host->cmdat = 0; @@ -729,6 +729,7 @@ host->power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); if (IS_ERR(host->power)) { + ret = PTR_ERR(host->power); dev_err(dev, "Failed requesting gpio_power\n"); goto out; } @@ -740,16 +741,16 @@ goto out; } + if (!host->pdata->gpio_card_ro_invert) + mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL); if (ret && ret != -ENOENT) { dev_err(dev, "Failed requesting gpio_ro\n"); goto out; } - if (!ret) { + if (!ret) host->use_ro_gpio = true; - mmc->caps2 |= host->pdata->gpio_card_ro_invert ? - 0 : MMC_CAP2_RO_ACTIVE_HIGH; - } if (host->pdata->init) host->pdata->init(dev, pxamci_detect_irq, mmc); @@ -760,7 +761,12 @@ dev_warn(dev, "gpio_ro and get_ro() both defined\n"); } - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) { + if (host->pdata && host->pdata->exit) + host->pdata->exit(dev, mmc); + goto out; + } return 0; --- linux-oracle-5.4.0.orig/drivers/mmc/host/renesas_sdhi_core.c +++ linux-oracle-5.4.0/drivers/mmc/host/renesas_sdhi_core.c @@ -349,10 +349,10 @@ SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) | sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2)); - /* Set the sampling clock selection range of HS400 mode */ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL, SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN | - 0x4 << SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT); + sd_scc_read32(host, priv, + SH_MOBILE_SDHI_SCC_DTCNTL)); if (host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400) @@ -874,6 +874,7 @@ tmio_mmc_host_remove(host); renesas_sdhi_clk_disable(host); + tmio_mmc_host_free(host); return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ linux-oracle-5.4.0/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -186,8 +186,8 @@ mmc_get_dma_dir(data))) goto force_pio; - /* This DMAC cannot handle if buffer is not 8-bytes alignment */ - if (!IS_ALIGNED(sg_dma_address(sg), 8)) + /* This DMAC cannot handle if buffer is not 128-bytes alignment */ + if (!IS_ALIGNED(sg_dma_address(sg), 128)) goto force_pio_with_unmap; if (data->flags & MMC_DATA_READ) { @@ -229,15 +229,12 @@ DTRAN_CTRL_DM_START); } -static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg) +static bool renesas_sdhi_internal_dmac_complete(struct tmio_mmc_host *host) { - struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg; enum dma_data_direction dir; - spin_lock_irq(&host->lock); - if (!host->data) - goto out; + return false; if (host->data->flags & MMC_DATA_READ) dir = DMA_FROM_DEVICE; @@ -250,6 +247,17 @@ if (dir == DMA_FROM_DEVICE) clear_bit(SDHI_INTERNAL_DMAC_RX_IN_USE, &global_flags); + return true; +} + +static void renesas_sdhi_internal_dmac_complete_tasklet_fn(unsigned long arg) +{ + struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg; + + spin_lock_irq(&host->lock); + if (!renesas_sdhi_internal_dmac_complete(host)) + goto out; + tmio_mmc_do_data_irq(host); out: spin_unlock_irq(&host->lock); --- linux-oracle-5.4.0.orig/drivers/mmc/host/rtsx_pci_sdmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -37,10 +37,7 @@ bool double_clk; bool eject; bool initial_mode; - int power_state; -#define SDMMC_POWER_ON 1 -#define SDMMC_POWER_OFF 0 - + int prev_power_state; int sg_count; s32 cookie; int cookie_sg_count; @@ -539,9 +536,22 @@ return 0; } +static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); +} + +static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) +{ + rtsx_pci_write_register(host->pcr, SD_CFG1, + SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); +} + static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) { struct mmc_data *data = mrq->data; + int err; if (host->sg_count < 0) { data->error = host->sg_count; @@ -550,22 +560,19 @@ return data->error; } - if (data->flags & MMC_DATA_READ) - return sd_read_long_data(host, mrq); + if (data->flags & MMC_DATA_READ) { + if (host->initial_mode) + sd_disable_initial_mode(host); - return sd_write_long_data(host, mrq); -} + err = sd_read_long_data(host, mrq); -static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_128); -} + if (host->initial_mode) + sd_enable_initial_mode(host); -static inline void sd_disable_initial_mode(struct realtek_pci_sdmmc *host) -{ - rtsx_pci_write_register(host->pcr, SD_CFG1, - SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + return err; + } + + return sd_write_long_data(host, mrq); } static void sd_normal_rw(struct realtek_pci_sdmmc *host, @@ -606,19 +613,22 @@ u8 sample_point, bool rx) { struct rtsx_pcr *pcr = host->pcr; - + u16 SD_VP_CTL = 0; dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", __func__, rx ? "RX" : "TX", sample_point); rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, CHANGE_CLK); - if (rx) + if (rx) { + SD_VP_CTL = SD_VPRX_CTL; rtsx_pci_write_register(pcr, SD_VPRX_CTL, PHASE_SELECT_MASK, sample_point); - else + } else { + SD_VP_CTL = SD_VPTX_CTL; rtsx_pci_write_register(pcr, SD_VPTX_CTL, PHASE_SELECT_MASK, sample_point); - rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); - rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, + } + rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, 0); + rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); @@ -889,14 +899,21 @@ return err; } -static int sd_power_on(struct realtek_pci_sdmmc *host) +static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode) { struct rtsx_pcr *pcr = host->pcr; int err; - if (host->power_state == SDMMC_POWER_ON) + if (host->prev_power_state == MMC_POWER_ON) return 0; + if (host->prev_power_state == MMC_POWER_UP) { + rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0); + goto finish; + } + + msleep(100); + rtsx_pci_init_cmd(pcr); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_SHARE_MODE, @@ -915,11 +932,17 @@ if (err < 0) return err; + mdelay(1); + err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); if (err < 0) return err; - host->power_state = SDMMC_POWER_ON; + /* send at least 74 clocks */ + rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); + +finish: + host->prev_power_state = power_mode; return 0; } @@ -928,7 +951,7 @@ struct rtsx_pcr *pcr = host->pcr; int err; - host->power_state = SDMMC_POWER_OFF; + host->prev_power_state = MMC_POWER_OFF; rtsx_pci_init_cmd(pcr); @@ -954,7 +977,7 @@ if (power_mode == MMC_POWER_OFF) err = sd_power_off(host); else - err = sd_power_on(host); + err = sd_power_on(host, power_mode); return err; } @@ -1389,10 +1412,11 @@ host = mmc_priv(mmc); host->pcr = pcr; + mmc->ios.power_delay_ms = 5; host->mmc = mmc; host->pdev = pdev; host->cookie = -1; - host->power_state = SDMMC_POWER_OFF; + host->prev_power_state = MMC_POWER_OFF; INIT_WORK(&host->work, sd_request); platform_set_drvdata(pdev, host); pcr->slots[RTSX_SD_CARD].p_dev = pdev; --- linux-oracle-5.4.0.orig/drivers/mmc/host/rtsx_usb_sdmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/rtsx_usb_sdmmc.c @@ -1338,6 +1338,7 @@ #ifdef RTSX_USB_USE_LEDS_CLASS int err; #endif + int ret; ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent)); if (!ucr) @@ -1374,7 +1375,15 @@ INIT_WORK(&host->led_work, rtsx_usb_update_led); #endif - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) { +#ifdef RTSX_USB_USE_LEDS_CLASS + led_classdev_unregister(&host->led); +#endif + mmc_free_host(mmc); + pm_runtime_disable(&pdev->dev); + return ret; + } return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-acpi.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-acpi.c @@ -532,6 +532,11 @@ .caps = MMC_CAP_NONREMOVABLE, }; +struct amd_sdhci_host { + bool tuned_clock; + bool dll_enabled; +}; + /* AMD sdhci reset dll register. */ #define SDHCI_AMD_RESET_DLL_REGISTER 0x908 @@ -542,39 +547,96 @@ return MMC_SET_DRIVER_TYPE_A; } -static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host) +static void sdhci_acpi_amd_hs400_dll(struct sdhci_host *host, bool enable) { + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); + /* AMD Platform requires dll setting */ sdhci_writel(host, 0x40003210, SDHCI_AMD_RESET_DLL_REGISTER); usleep_range(10, 20); - sdhci_writel(host, 0x40033210, SDHCI_AMD_RESET_DLL_REGISTER); + if (enable) + sdhci_writel(host, 0x40033210, SDHCI_AMD_RESET_DLL_REGISTER); + + amd_host->dll_enabled = enable; } /* - * For AMD Platform it is required to disable the tuning - * bit first controller to bring to HS Mode from HS200 - * mode, later enable to tune to HS400 mode. + * The initialization sequence for HS400 is: + * HS->HS200->Perform Tuning->HS->HS400 + * + * The re-tuning sequence is: + * HS400->DDR52->HS->HS200->Perform Tuning->HS->HS400 + * + * The AMD eMMC Controller can only use the tuned clock while in HS200 and HS400 + * mode. If we switch to a different mode, we need to disable the tuned clock. + * If we have previously performed tuning and switch back to HS200 or + * HS400, we can re-enable the tuned clock. + * */ static void amd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); unsigned int old_timing = host->timing; + u16 val; sdhci_set_ios(mmc, ios); - if (old_timing == MMC_TIMING_MMC_HS200 && - ios->timing == MMC_TIMING_MMC_HS) - sdhci_writew(host, 0x9, SDHCI_HOST_CONTROL2); - if (old_timing != MMC_TIMING_MMC_HS400 && - ios->timing == MMC_TIMING_MMC_HS400) { - sdhci_writew(host, 0x80, SDHCI_HOST_CONTROL2); - sdhci_acpi_amd_hs400_dll(host); + + if (old_timing != host->timing && amd_host->tuned_clock) { + if (host->timing == MMC_TIMING_MMC_HS400 || + host->timing == MMC_TIMING_MMC_HS200) { + val = sdhci_readw(host, SDHCI_HOST_CONTROL2); + val |= SDHCI_CTRL_TUNED_CLK; + sdhci_writew(host, val, SDHCI_HOST_CONTROL2); + } else { + val = sdhci_readw(host, SDHCI_HOST_CONTROL2); + val &= ~SDHCI_CTRL_TUNED_CLK; + sdhci_writew(host, val, SDHCI_HOST_CONTROL2); + } + + /* DLL is only required for HS400 */ + if (host->timing == MMC_TIMING_MMC_HS400 && + !amd_host->dll_enabled) + sdhci_acpi_amd_hs400_dll(host, true); } } +static int amd_sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + int err; + struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); + + amd_host->tuned_clock = false; + + err = sdhci_execute_tuning(mmc, opcode); + + if (!err && !host->tuning_err) + amd_host->tuned_clock = true; + + return err; +} + +static void amd_sdhci_reset(struct sdhci_host *host, u8 mask) +{ + struct sdhci_acpi_host *acpi_host = sdhci_priv(host); + struct amd_sdhci_host *amd_host = sdhci_acpi_priv(acpi_host); + + if (mask & SDHCI_RESET_ALL) { + amd_host->tuned_clock = false; + sdhci_acpi_amd_hs400_dll(host, false); + } + + sdhci_reset(host, mask); +} + static const struct sdhci_ops sdhci_acpi_ops_amd = { .set_clock = sdhci_set_clock, .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, + .reset = amd_sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, }; @@ -596,17 +658,58 @@ (host->mmc->caps & MMC_CAP_1_8V_DDR)) host->mmc->caps2 = MMC_CAP2_HS400_1_8V; + /* + * There are two types of presets out in the wild: + * 1) Default/broken presets. + * These presets have two sets of problems: + * a) The clock divisor for SDR12, SDR25, and SDR50 is too small. + * This results in clock frequencies that are 2x higher than + * acceptable. i.e., SDR12 = 25 MHz, SDR25 = 50 MHz, SDR50 = + * 100 MHz.x + * b) The HS200 and HS400 driver strengths don't match. + * By default, the SDR104 preset register has a driver strength of + * A, but the (internal) HS400 preset register has a driver + * strength of B. As part of initializing HS400, HS200 tuning + * needs to be performed. Having different driver strengths + * between tuning and operation is wrong. It results in different + * rise/fall times that lead to incorrect sampling. + * 2) Firmware with properly initialized presets. + * These presets have proper clock divisors. i.e., SDR12 => 12MHz, + * SDR25 => 25 MHz, SDR50 => 50 MHz. Additionally the HS200 and + * HS400 preset driver strengths match. + * + * Enabling presets for HS400 doesn't work for the following reasons: + * 1) sdhci_set_ios has a hard coded list of timings that are used + * to determine if presets should be enabled. + * 2) sdhci_get_preset_value is using a non-standard register to + * read out HS400 presets. The AMD controller doesn't support this + * non-standard register. In fact, it doesn't expose the HS400 + * preset register anywhere in the SDHCI memory map. This results + * in reading a garbage value and using the wrong presets. + * + * Since HS400 and HS200 presets must be identical, we could + * instead use the the SDR104 preset register. + * + * If the above issues are resolved we could remove this quirk for + * firmware that that has valid presets (i.e., SDR12 <= 12 MHz). + */ + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; + host->mmc_host_ops.select_drive_strength = amd_select_drive_strength; host->mmc_host_ops.set_ios = amd_set_ios; + host->mmc_host_ops.execute_tuning = amd_sdhci_execute_tuning; return 0; } static const struct sdhci_acpi_slot sdhci_acpi_slot_amd_emmc = { - .chip = &sdhci_acpi_chip_amd, - .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, - .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_32BIT_DMA_SIZE | - SDHCI_QUIRK_32BIT_ADMA_SIZE, + .chip = &sdhci_acpi_chip_amd, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + .quirks = SDHCI_QUIRK_32BIT_DMA_ADDR | + SDHCI_QUIRK_32BIT_DMA_SIZE | + SDHCI_QUIRK_32BIT_ADMA_SIZE, + .quirks2 = SDHCI_QUIRK2_BROKEN_64_BIT_DMA, .probe_slot = sdhci_acpi_emmc_amd_probe_slot, + .priv_size = sizeof(struct amd_sdhci_host), }; struct sdhci_acpi_uid_slot { @@ -732,7 +835,7 @@ host->ops = &sdhci_acpi_ops_dflt; host->irq = platform_get_irq(pdev, 0); if (host->irq < 0) { - err = -EINVAL; + err = host->irq; goto err_free; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-cadence.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-cadence.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "sdhci-pltfm.h" @@ -193,52 +194,6 @@ return FIELD_GET(SDHCI_CDNS_HRS06_MODE, tmp); } -static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, - unsigned int timing) -{ - struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); - u32 mode; - - switch (timing) { - case MMC_TIMING_MMC_HS: - mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR; - break; - case MMC_TIMING_MMC_DDR52: - mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR; - break; - case MMC_TIMING_MMC_HS200: - mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200; - break; - case MMC_TIMING_MMC_HS400: - if (priv->enhanced_strobe) - mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400ES; - else - mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400; - break; - default: - mode = SDHCI_CDNS_HRS06_MODE_SD; - break; - } - - sdhci_cdns_set_emmc_mode(priv, mode); - - /* For SD, fall back to the default handler */ - if (mode == SDHCI_CDNS_HRS06_MODE_SD) - sdhci_set_uhs_signaling(host, timing); -} - -static const struct sdhci_ops sdhci_cdns_ops = { - .set_clock = sdhci_set_clock, - .get_timeout_clock = sdhci_cdns_get_timeout_clock, - .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, -}; - -static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { - .ops = &sdhci_cdns_ops, -}; - static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) { struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); @@ -272,23 +227,24 @@ return 0; } -static int sdhci_cdns_execute_tuning(struct mmc_host *mmc, u32 opcode) +/* + * In SD mode, software must not use the hardware tuning and instead perform + * an almost identical procedure to eMMC. + */ +static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode) { - struct sdhci_host *host = mmc_priv(mmc); int cur_streak = 0; int max_streak = 0; int end_of_streak = 0; int i; /* - * This handler only implements the eMMC tuning that is specific to - * this controller. Fall back to the standard method for SD timing. + * Do not execute tuning for UHS_SDR50 or UHS_DDR50. + * The delay is set by probe, based on the DT properties. */ - if (host->timing != MMC_TIMING_MMC_HS200) - return sdhci_execute_tuning(mmc, opcode); - - if (WARN_ON(opcode != MMC_SEND_TUNING_BLOCK_HS200)) - return -EINVAL; + if (host->timing != MMC_TIMING_MMC_HS200 && + host->timing != MMC_TIMING_UHS_SDR104) + return 0; for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) { if (sdhci_cdns_set_tune_val(host, i) || @@ -311,6 +267,58 @@ return sdhci_cdns_set_tune_val(host, end_of_streak - max_streak / 2); } +static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, + unsigned int timing) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + u32 mode; + + switch (timing) { + case MMC_TIMING_MMC_HS: + mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR; + break; + case MMC_TIMING_MMC_DDR52: + mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR; + break; + case MMC_TIMING_MMC_HS200: + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200; + break; + case MMC_TIMING_MMC_HS400: + if (priv->enhanced_strobe) + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400ES; + else + mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400; + break; + default: + mode = SDHCI_CDNS_HRS06_MODE_SD; + break; + } + + sdhci_cdns_set_emmc_mode(priv, mode); + + /* For SD, fall back to the default handler */ + if (mode == SDHCI_CDNS_HRS06_MODE_SD) + sdhci_set_uhs_signaling(host, timing); +} + +static const struct sdhci_ops sdhci_cdns_ops = { + .set_clock = sdhci_set_clock, + .get_timeout_clock = sdhci_cdns_get_timeout_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .platform_execute_tuning = sdhci_cdns_execute_tuning, + .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, +}; + +static const struct sdhci_pltfm_data sdhci_cdns_uniphier_pltfm_data = { + .ops = &sdhci_cdns_ops, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, +}; + +static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { + .ops = &sdhci_cdns_ops, +}; + static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios) { @@ -334,6 +342,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev) { struct sdhci_host *host; + const struct sdhci_pltfm_data *data; struct sdhci_pltfm_host *pltfm_host; struct sdhci_cdns_priv *priv; struct clk *clk; @@ -350,8 +359,12 @@ if (ret) return ret; + data = of_device_get_match_data(dev); + if (!data) + data = &sdhci_cdns_pltfm_data; + nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); - host = sdhci_pltfm_init(pdev, &sdhci_cdns_pltfm_data, + host = sdhci_pltfm_init(pdev, data, struct_size(priv, phy_params, nr_phy_params)); if (IS_ERR(host)) { ret = PTR_ERR(host); @@ -366,7 +379,6 @@ priv->hrs_addr = host->ioaddr; priv->enhanced_strobe = false; host->ioaddr += SDHCI_CDNS_SRS_BASE; - host->mmc_host_ops.execute_tuning = sdhci_cdns_execute_tuning; host->mmc_host_ops.hs400_enhanced_strobe = sdhci_cdns_hs400_enhanced_strobe; sdhci_enable_v4_mode(host); @@ -431,7 +443,10 @@ }; static const struct of_device_id sdhci_cdns_match[] = { - { .compatible = "socionext,uniphier-sd4hc" }, + { + .compatible = "socionext,uniphier-sd4hc", + .data = &sdhci_cdns_uniphier_pltfm_data, + }, { .compatible = "cdns,sd4hc" }, { /* sentinel */ } }; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-cqhci.h +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-cqhci.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2022 The Chromium OS Authors + * + * Support that applies to the combination of SDHCI and CQHCI, while not + * expressing a dependency between the two modules. + */ + +#ifndef __MMC_HOST_SDHCI_CQHCI_H__ +#define __MMC_HOST_SDHCI_CQHCI_H__ + +#include "cqhci.h" +#include "sdhci.h" + +static inline void sdhci_and_cqhci_reset(struct sdhci_host *host, u8 mask) +{ + if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) && + host->mmc->cqe_private) + cqhci_deactivate(host->mmc); + + sdhci_reset(host, mask); +} + +#endif /* __MMC_HOST_SDHCI_CQHCI_H__ */ --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-esdhc-imx.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-esdhc-imx.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" #include "cqhci.h" @@ -87,7 +88,9 @@ #define ESDHC_STD_TUNING_EN (1 << 24) /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */ #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 -#define ESDHC_TUNING_START_TAP_MASK 0xff +#define ESDHC_TUNING_START_TAP_MASK 0x7f +#define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE (1 << 7) +#define ESDHC_TUNING_STEP_DEFAULT 0x1 #define ESDHC_TUNING_STEP_MASK 0x00070000 #define ESDHC_TUNING_STEP_SHIFT 16 @@ -150,8 +153,8 @@ #define ESDHC_FLAG_HS400 BIT(9) /* * The IP has errata ERR010450 - * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't - * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. + * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card + * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. */ #define ESDHC_FLAG_ERR010450 BIT(10) /* The IP supports HS400ES mode */ @@ -217,8 +220,7 @@ static struct esdhc_soc_data usdhc_imx8qxp_data = { .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200 - | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES - | ESDHC_FLAG_CQHCI, + | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES, }; struct pltfm_imx_data { @@ -775,7 +777,8 @@ | ESDHC_CLOCK_MASK); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); - if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) { + if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && + (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { unsigned int max_clock; max_clock = imx_data->is_ddr ? 45000000 : 150000000; @@ -1022,6 +1025,7 @@ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); u32 ctrl; + int ret; /* Reset the tuning circuit */ if (esdhc_is_usdhc(imx_data)) { @@ -1034,7 +1038,22 @@ } else if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { ctrl = readl(host->ioaddr + SDHCI_AUTO_CMD_STATUS); ctrl &= ~ESDHC_MIX_CTRL_SMPCLK_SEL; + ctrl &= ~ESDHC_MIX_CTRL_EXE_TUNE; writel(ctrl, host->ioaddr + SDHCI_AUTO_CMD_STATUS); + /* Make sure ESDHC_MIX_CTRL_EXE_TUNE cleared */ + ret = readl_poll_timeout(host->ioaddr + SDHCI_AUTO_CMD_STATUS, + ctrl, !(ctrl & ESDHC_MIX_CTRL_EXE_TUNE), 1, 50); + if (ret == -ETIMEDOUT) + dev_warn(mmc_dev(host->mmc), + "Warning! clear execute tuning bit failed\n"); + /* + * SDHCI_INT_DATA_AVAIL is W1C bit, set this bit will clear the + * usdhc IP internal logic flag execute_tuning_with_clr_buf, which + * will finally make sure the normal data transfer logic correct. + */ + ctrl = readl(host->ioaddr + SDHCI_INT_STATUS); + ctrl |= SDHCI_INT_DATA_AVAIL; + writel(ctrl, host->ioaddr + SDHCI_INT_STATUS); } } } @@ -1164,7 +1183,8 @@ { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); - int tmp; + struct cqhci_host *cq_host = host->mmc->cqe_private; + u32 tmp; if (esdhc_is_usdhc(imx_data)) { /* @@ -1217,18 +1237,37 @@ if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); - tmp |= ESDHC_STD_TUNING_EN | - ESDHC_TUNING_START_TAP_DEFAULT; - if (imx_data->boarddata.tuning_start_tap) { - tmp &= ~ESDHC_TUNING_START_TAP_MASK; + tmp |= ESDHC_STD_TUNING_EN; + + /* + * ROM code or bootloader may config the start tap + * and step, unmask them first. + */ + tmp &= ~(ESDHC_TUNING_START_TAP_MASK | ESDHC_TUNING_STEP_MASK); + if (imx_data->boarddata.tuning_start_tap) tmp |= imx_data->boarddata.tuning_start_tap; - } + else + tmp |= ESDHC_TUNING_START_TAP_DEFAULT; if (imx_data->boarddata.tuning_step) { - tmp &= ~ESDHC_TUNING_STEP_MASK; tmp |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT; + } else { + tmp |= ESDHC_TUNING_STEP_DEFAULT + << ESDHC_TUNING_STEP_SHIFT; } + + /* Disable the CMD CRC check for tuning, if not, need to + * add some delay after every tuning command, because + * hardware standard tuning logic will directly go to next + * step once it detect the CMD CRC error, will not wait for + * the card side to finally send out the tuning data, trigger + * the buffer read ready interrupt immediately. If usdhc send + * the next tuning command some eMMC card will stuck, can't + * response, block the tuning procedure or the first command + * after the whole tuning procedure always can't get any response. + */ + tmp |= ESDHC_TUNING_CMD_CRC_CHECK_DISABLE; writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) { /* @@ -1240,6 +1279,21 @@ tmp &= ~ESDHC_STD_TUNING_EN; writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL); } + + /* + * On i.MX8MM, we are running Dual Linux OS, with 1st Linux using SD Card + * as rootfs storage, 2nd Linux using eMMC as rootfs storage. We let the + * the 1st linux configure power/clock for the 2nd Linux. + * + * When the 2nd Linux is booting into rootfs stage, we let the 1st Linux + * to destroy the 2nd linux, then restart the 2nd linux, we met SDHCI dump. + * After we clear the pending interrupt and halt CQCTL, issue gone. + */ + if (cq_host) { + tmp = cqhci_readl(cq_host, CQHCI_IS); + cqhci_writel(cq_host, tmp, CQHCI_IS); + cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); + } } } @@ -1286,7 +1340,7 @@ * system resume back. */ cqhci_writel(cq_host, 0, CQHCI_CTL); - if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) + if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) dev_err(mmc_dev(host->mmc), "failed to exit halt state when enable CQE\n"); @@ -1381,13 +1435,14 @@ host->mmc->parent->platform_data); /* write_protect */ if (boarddata->wp_type == ESDHC_WP_GPIO) { + host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; + err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL); if (err) { dev_err(mmc_dev(host->mmc), "failed to request write-protect gpio!\n"); return err; } - host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH; } /* card_detect */ @@ -1554,8 +1609,6 @@ if (err) goto disable_ahb_clk; - host->tuning_delay = 1; - sdhci_esdhc_imx_hwinit(host); err = sdhci_add_host(host); @@ -1588,9 +1641,10 @@ struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); - int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); + int dead; pm_runtime_get_sync(&pdev->dev); + dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-esdhc.h +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-esdhc.h @@ -51,6 +51,11 @@ #define ESDHC_CLOCK_HCKEN 0x00000002 #define ESDHC_CLOCK_IPGEN 0x00000001 +/* System Control 2 Register */ +#define ESDHC_SYSTEM_CONTROL_2 0x3c +#define ESDHC_SMPCLKSEL 0x00800000 +#define ESDHC_EXTN 0x00400000 + /* Host Controller Capabilities Register 2 */ #define ESDHC_CAPABILITIES_1 0x114 @@ -59,7 +64,16 @@ #define ESDHC_HS400_WNDW_ADJUST 0x00000040 #define ESDHC_HS400_MODE 0x00000010 #define ESDHC_TB_EN 0x00000004 +#define ESDHC_TB_MODE_MASK 0x00000003 +#define ESDHC_TB_MODE_SW 0x00000003 +#define ESDHC_TB_MODE_3 0x00000002 + +#define ESDHC_TBSTAT 0x124 + #define ESDHC_TBPTR 0x128 +#define ESDHC_WNDW_STRT_PTR_SHIFT 8 +#define ESDHC_WNDW_STRT_PTR_MASK (0x7f << 8) +#define ESDHC_WNDW_END_PTR_MASK 0x7f /* SD Clock Control Register */ #define ESDHC_SDCLKCTL 0x144 --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-msm.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-msm.c @@ -99,7 +99,7 @@ #define CORE_PWRSAVE_DLL BIT(3) -#define DDR_CONFIG_POR_VAL 0x80040853 +#define DDR_CONFIG_POR_VAL 0x80040873 #define INVALID_TUNING_PHASE -1 @@ -148,8 +148,9 @@ u32 core_ddr_200_cfg; u32 core_vendor_spec3; u32 core_dll_config_2; + u32 core_dll_config_3; + u32 core_ddr_config_old; /* Applicable to sdcc minor ver < 0x49 */ u32 core_ddr_config; - u32 core_ddr_config_2; }; static const struct sdhci_msm_offset sdhci_msm_v5_offset = { @@ -177,8 +178,8 @@ .core_ddr_200_cfg = 0x224, .core_vendor_spec3 = 0x250, .core_dll_config_2 = 0x254, - .core_ddr_config = 0x258, - .core_ddr_config_2 = 0x25c, + .core_dll_config_3 = 0x258, + .core_ddr_config = 0x25c, }; static const struct sdhci_msm_offset sdhci_msm_mci_offset = { @@ -207,8 +208,8 @@ .core_ddr_200_cfg = 0x184, .core_vendor_spec3 = 0x1b0, .core_dll_config_2 = 0x1b4, - .core_ddr_config = 0x1b8, - .core_ddr_config_2 = 0x1bc, + .core_ddr_config_old = 0x1b8, + .core_ddr_config = 0x1bc, }; struct sdhci_msm_variant_ops { @@ -253,6 +254,7 @@ const struct sdhci_msm_offset *offset; bool use_cdr; u32 transfer_mode; + bool updated_ddr_cfg; }; static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host) @@ -924,8 +926,10 @@ static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host) { struct mmc_host *mmc = host->mmc; - u32 dll_status, config; + u32 dll_status, config, ddr_cfg_offset; int ret; + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host); const struct sdhci_msm_offset *msm_offset = sdhci_priv_msm_offset(host); @@ -938,8 +942,11 @@ * bootloaders. In the future, if this changes, then the desired * values will need to be programmed appropriately. */ - writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + - msm_offset->core_ddr_config); + if (msm_host->updated_ddr_cfg) + ddr_cfg_offset = msm_offset->core_ddr_config; + else + ddr_cfg_offset = msm_offset->core_ddr_config_old; + writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr + ddr_cfg_offset); if (mmc->ios.enhanced_strobe) { config = readl_relaxed(host->ioaddr + @@ -1089,7 +1096,7 @@ static int sdhci_msm_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct sdhci_host *host = mmc_priv(mmc); - int tuning_seq_cnt = 3; + int tuning_seq_cnt = 10; u8 phase, tuned_phases[16], tuned_phase_cnt = 0; int rc; struct mmc_ios ios = host->mmc->ios; @@ -1106,6 +1113,12 @@ msm_host->use_cdr = true; /* + * Clear tuning_done flag before tuning to ensure proper + * HS400 settings. + */ + msm_host->tuning_done = 0; + + /* * For HS400 tuning in HS200 timing requires: * - select MCLK/2 in VENDOR_SPEC * - program MCLK to 400MHz (or nearest supported) in GCC @@ -1139,6 +1152,22 @@ } while (++phase < ARRAY_SIZE(tuned_phases)); if (tuned_phase_cnt) { + if (tuned_phase_cnt == ARRAY_SIZE(tuned_phases)) { + /* + * All phases valid is _almost_ as bad as no phases + * valid. Probably all phases are not really reliable + * but we didn't detect where the unreliable place is. + * That means we'll essentially be guessing and hoping + * we get a good phase. Better to try a few times. + */ + dev_dbg(mmc_dev(mmc), "%s: All phases valid; try again\n", + mmc_hostname(mmc)); + if (--tuning_seq_cnt) { + tuned_phase_cnt = 0; + goto retry; + } + } + rc = msm_find_most_appropriate_phase(host, tuned_phases, tuned_phase_cnt); if (rc < 0) @@ -1560,6 +1589,23 @@ __sdhci_msm_set_clock(host, clock); } +static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) +{ + u32 count, start = 15; + + __sdhci_set_timeout(host, cmd); + count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL); + /* + * Update software timeout value if its value is less than hardware data + * timeout value. Qcom SoC hardware data timeout value was calculated + * using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock. + */ + if (cmd && cmd->data && host->clock > 400000 && + host->clock <= 50000000 && + ((1 << (count + start)) > (10 * host->clock))) + host->data_timeout = 22LL * NSEC_PER_SEC; +} + /* * Platform specific register write functions. This is so that, if any * register write needs to be followed up by platform specific actions, @@ -1709,6 +1755,7 @@ static const struct of_device_id sdhci_msm_dt_match[] = { {.compatible = "qcom,sdhci-msm-v4", .data = &sdhci_msm_mci_var}, {.compatible = "qcom,sdhci-msm-v5", .data = &sdhci_msm_v5_var}, + {.compatible = "qcom,sdm670-sdhci", .data = &sdm845_sdhci_var}, {.compatible = "qcom,sdm845-sdhci", .data = &sdm845_sdhci_var}, {}, }; @@ -1724,12 +1771,15 @@ .set_uhs_signaling = sdhci_msm_set_uhs_signaling, .write_w = sdhci_msm_writew, .write_b = sdhci_msm_writeb, + .set_timeout = sdhci_msm_set_timeout, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_SINGLE_POWER_WRITE | - SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .ops = &sdhci_msm_ops, }; @@ -1899,6 +1949,9 @@ msm_offset->core_vendor_spec_capabilities0); } + if (core_major == 1 && core_minor >= 0x49) + msm_host->updated_ddr_cfg = true; + /* * Power on reset state may trigger power irq if previous status of * PWRCTL was either BUS_ON or IO_HIGH_V. So before enabling pwr irq @@ -1934,6 +1987,8 @@ goto clk_disable; } + msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; + pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-of-arasan.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-of-arasan.c @@ -24,6 +24,7 @@ #include #include "cqhci.h" +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 @@ -192,7 +193,12 @@ * through low speeds without power cycling. */ sdhci_set_clock(host, host->max_clk); - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true; /* @@ -228,7 +234,12 @@ msleep(20); if (ctrl_phy) { - phy_power_on(sdhci_arasan->phy); + if (phy_power_on(sdhci_arasan->phy)) { + pr_err("%s: Cannot power on phy.\n", + mmc_hostname(host->mmc)); + return; + } + sdhci_arasan->is_phy_on = true; } } @@ -254,7 +265,7 @@ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) { ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); @@ -416,7 +427,9 @@ ret = phy_power_off(sdhci_arasan->phy); if (ret) { dev_err(dev, "Cannot power off phy.\n"); - sdhci_resume_host(host); + if (sdhci_resume_host(host)) + dev_err(dev, "Cannot resume host.\n"); + return ret; } sdhci_arasan->is_phy_on = false; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-of-aspeed.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-of-aspeed.c @@ -68,7 +68,7 @@ if (WARN_ON(clock > host->max_clk)) clock = host->max_clk; - for (div = 1; div < 256; div *= 2) { + for (div = 2; div < 256; div *= 2) { if ((parent / div) <= clock) break; } @@ -224,6 +224,7 @@ { .compatible = "aspeed,ast2600-sdhci", }, { } }; +MODULE_DEVICE_TABLE(of, aspeed_sdhci_of_match); static struct platform_driver aspeed_sdhci_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-of-at91.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-of-at91.c @@ -109,8 +109,13 @@ static void sdhci_at91_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) { - if (timing == MMC_TIMING_MMC_DDR52) - sdhci_writeb(host, SDMMC_MC1R_DDR, SDMMC_MC1R); + u8 mc1r; + + if (timing == MMC_TIMING_MMC_DDR52) { + mc1r = sdhci_readb(host, SDMMC_MC1R); + mc1r |= SDMMC_MC1R_DDR; + sdhci_writeb(host, mc1r, SDMMC_MC1R); + } sdhci_set_uhs_signaling(host, timing); } @@ -118,7 +123,8 @@ { sdhci_reset(host, mask); - if (host->mmc->caps & MMC_CAP_NONREMOVABLE) + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) + || mmc_gpio_get_cd(host->mmc) >= 0) sdhci_at91_set_force_card_detect(host); } @@ -324,19 +330,22 @@ priv->mainck = devm_clk_get(&pdev->dev, "baseclk"); if (IS_ERR(priv->mainck)) { dev_err(&pdev->dev, "failed to get baseclk\n"); - return PTR_ERR(priv->mainck); + ret = PTR_ERR(priv->mainck); + goto sdhci_pltfm_free; } priv->hclock = devm_clk_get(&pdev->dev, "hclock"); if (IS_ERR(priv->hclock)) { dev_err(&pdev->dev, "failed to get hclock\n"); - return PTR_ERR(priv->hclock); + ret = PTR_ERR(priv->hclock); + goto sdhci_pltfm_free; } priv->gck = devm_clk_get(&pdev->dev, "multclk"); if (IS_ERR(priv->gck)) { dev_err(&pdev->dev, "failed to get multclk\n"); - return PTR_ERR(priv->gck); + ret = PTR_ERR(priv->gck); + goto sdhci_pltfm_free; } ret = sdhci_at91_set_clks_presets(&pdev->dev); @@ -394,8 +403,11 @@ * detection procedure using the SDMCC_CD signal is bypassed. * This bit is reset when a software reset for all command is performed * so we need to implement our own reset function to set back this bit. + * + * WA: SAMA5D2 doesn't drive CMD if using CD GPIO line. */ - if (host->mmc->caps & MMC_CAP_NONREMOVABLE) + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) + || mmc_gpio_get_cd(host->mmc) >= 0) sdhci_at91_set_force_card_detect(host); pm_runtime_put_autosuspend(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-of-dwcmshc.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -58,6 +58,7 @@ static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { .ops = &sdhci_dwcmshc_ops, .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }; static int dwcmshc_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-of-esdhc.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-of-esdhc.c @@ -77,8 +77,12 @@ bool quirk_incorrect_hostver; bool quirk_limited_clk_division; bool quirk_unreliable_pulse_detection; - bool quirk_fixup_tuning; + bool quirk_tuning_erratum_type1; + bool quirk_tuning_erratum_type2; bool quirk_ignore_data_inhibit; + bool quirk_delay_before_data_reset; + bool quirk_trans_complete_erratum; + bool in_sw_tuning; unsigned int peripheral_clock; const struct esdhc_clk_fixup *clk_fixup; u32 div_ratio; @@ -120,6 +124,7 @@ return ret; } } + /* * The DAT[3:0] line signal levels and the CMD line signal level are * not compatible with standard SDHC register. The line signal levels @@ -131,6 +136,16 @@ ret = value & 0x000fffff; ret |= (value >> 4) & SDHCI_DATA_LVL_MASK; ret |= (value << 1) & SDHCI_CMD_LVL; + + /* + * Some controllers have unreliable Data Line Active + * bit for commands with busy signal. This affects + * Command Inhibit (data) bit. Just ignore it since + * MMC core driver has already polled card status + * with CMD13 after any command with busy siganl. + */ + if (esdhc->quirk_ignore_data_inhibit) + ret &= ~SDHCI_DATA_INHIBIT; return ret; } @@ -145,19 +160,6 @@ return ret; } - /* - * Some controllers have unreliable Data Line Active - * bit for commands with busy signal. This affects - * Command Inhibit (data) bit. Just ignore it since - * MMC core driver has already polled card status - * with CMD13 after any command with busy siganl. - */ - if ((spec_reg == SDHCI_PRESENT_STATE) && - (esdhc->quirk_ignore_data_inhibit == true)) { - ret = value & ~SDHCI_DATA_INHIBIT; - return ret; - } - ret = value; return ret; } @@ -408,6 +410,8 @@ static void esdhc_be_writew(struct sdhci_host *host, u16 val, int reg) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); int base = reg & ~0x3; u32 value; u32 ret; @@ -416,10 +420,24 @@ ret = esdhc_writew_fixup(host, reg, val, value); if (reg != SDHCI_TRANSFER_MODE) iowrite32be(ret, host->ioaddr + base); + + /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set + * 1us later after ESDHC_EXTN is set. + */ + if (base == ESDHC_SYSTEM_CONTROL_2) { + if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && + esdhc->in_sw_tuning) { + udelay(1); + ret |= ESDHC_SMPCLKSEL; + iowrite32be(ret, host->ioaddr + base); + } + } } static void esdhc_le_writew(struct sdhci_host *host, u16 val, int reg) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); int base = reg & ~0x3; u32 value; u32 ret; @@ -428,6 +446,18 @@ ret = esdhc_writew_fixup(host, reg, val, value); if (reg != SDHCI_TRANSFER_MODE) iowrite32(ret, host->ioaddr + base); + + /* Starting SW tuning requires ESDHC_SMPCLKSEL to be set + * 1us later after ESDHC_EXTN is set. + */ + if (base == ESDHC_SYSTEM_CONTROL_2) { + if (!(value & ESDHC_EXTN) && (ret & ESDHC_EXTN) && + esdhc->in_sw_tuning) { + udelay(1); + ret |= ESDHC_SMPCLKSEL; + iowrite32(ret, host->ioaddr + base); + } + } } static void esdhc_be_writeb(struct sdhci_host *host, u8 val, int reg) @@ -487,12 +517,16 @@ static int esdhc_of_enable_dma(struct sdhci_host *host) { + int ret; u32 value; struct device *dev = mmc_dev(host->mmc); if (of_device_is_compatible(dev->of_node, "fsl,ls1043a-esdhc") || - of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) - dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); + of_device_is_compatible(dev->of_node, "fsl,ls1046a-esdhc")) { + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); + if (ret) + return ret; + } value = sdhci_readl(host, ESDHC_DMA_SYSCTL); @@ -703,21 +737,58 @@ { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); - u32 val; + u32 val, bus_width = 0; + + /* + * Add delay to make sure all the DMA transfers are finished + * for quirk. + */ + if (esdhc->quirk_delay_before_data_reset && + (mask & SDHCI_RESET_DATA) && + (host->flags & SDHCI_REQ_USE_DMA)) + mdelay(5); + + /* + * Save bus-width for eSDHC whose vendor version is 2.2 + * or lower for data reset. + */ + if ((mask & SDHCI_RESET_DATA) && + (esdhc->vendor_ver <= VENDOR_V_22)) { + val = sdhci_readl(host, ESDHC_PROCTL); + bus_width = val & ESDHC_CTRL_BUSWIDTH_MASK; + } sdhci_reset(host, mask); - sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); - sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + /* + * Restore bus-width setting and interrupt registers for eSDHC + * whose vendor version is 2.2 or lower for data reset. + */ + if ((mask & SDHCI_RESET_DATA) && + (esdhc->vendor_ver <= VENDOR_V_22)) { + val = sdhci_readl(host, ESDHC_PROCTL); + val &= ~ESDHC_CTRL_BUSWIDTH_MASK; + val |= bus_width; + sdhci_writel(host, val, ESDHC_PROCTL); - if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) - mdelay(5); + sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); + sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); + } - if (mask & SDHCI_RESET_ALL) { + /* + * Some bits have to be cleaned manually for eSDHC whose spec + * version is higher than 3.0 for all reset. + */ + if ((mask & SDHCI_RESET_ALL) && + (esdhc->spec_ver >= SDHCI_SPEC_300)) { val = sdhci_readl(host, ESDHC_TBCTL); val &= ~ESDHC_TB_EN; sdhci_writel(host, val, ESDHC_TBCTL); + /* + * Initialize eSDHC_DLLCFG1[DLL_PD_PULSE_STRETCH_SEL] to + * 0 for quirk. + */ if (esdhc->quirk_unreliable_pulse_detection) { val = sdhci_readl(host, ESDHC_DLLCFG1); val &= ~ESDHC_DLL_PD_PULSE_STRETCH_SEL; @@ -771,6 +842,7 @@ scfg_node = of_find_matching_node(NULL, scfg_device_ids); if (scfg_node) scfg_base = of_iomap(scfg_node, 0); + of_node_put(scfg_node); if (scfg_base) { sdhciovselcr = SDHCIOVSELCR_TGLEN | SDHCIOVSELCR_VSELVAL; @@ -796,16 +868,21 @@ } } -static struct soc_device_attribute soc_fixup_tuning[] = { +static struct soc_device_attribute soc_tuning_erratum_type1[] = { + { .family = "QorIQ T1023", .revision = "1.0", }, { .family = "QorIQ T1040", .revision = "1.0", }, { .family = "QorIQ T2080", .revision = "1.0", }, - { .family = "QorIQ T1023", .revision = "1.0", }, { .family = "QorIQ LS1021A", .revision = "1.0", }, - { .family = "QorIQ LS1080A", .revision = "1.0", }, - { .family = "QorIQ LS2080A", .revision = "1.0", }, + { }, +}; + +static struct soc_device_attribute soc_tuning_erratum_type2[] = { { .family = "QorIQ LS1012A", .revision = "1.0", }, { .family = "QorIQ LS1043A", .revision = "1.*", }, { .family = "QorIQ LS1046A", .revision = "1.0", }, + { .family = "QorIQ LS1080A", .revision = "1.0", }, + { .family = "QorIQ LS2080A", .revision = "1.0", }, + { .family = "QorIQ LA1575A", .revision = "1.0", }, { }, }; @@ -829,15 +906,97 @@ esdhc_clock_enable(host, true); } +static void esdhc_prepare_sw_tuning(struct sdhci_host *host, u8 *window_start, + u8 *window_end) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); + u8 tbstat_15_8, tbstat_7_0; + u32 val; + + if (esdhc->quirk_tuning_erratum_type1) { + *window_start = 5 * esdhc->div_ratio; + *window_end = 3 * esdhc->div_ratio; + return; + } + + /* Write TBCTL[11:8]=4'h8 */ + val = sdhci_readl(host, ESDHC_TBCTL); + val &= ~(0xf << 8); + val |= 8 << 8; + sdhci_writel(host, val, ESDHC_TBCTL); + + mdelay(1); + + /* Read TBCTL[31:0] register and rewrite again */ + val = sdhci_readl(host, ESDHC_TBCTL); + sdhci_writel(host, val, ESDHC_TBCTL); + + mdelay(1); + + /* Read the TBSTAT[31:0] register twice */ + val = sdhci_readl(host, ESDHC_TBSTAT); + val = sdhci_readl(host, ESDHC_TBSTAT); + + /* Reset data lines by setting ESDHCCTL[RSTD] */ + sdhci_reset(host, SDHCI_RESET_DATA); + /* Write 32'hFFFF_FFFF to IRQSTAT register */ + sdhci_writel(host, 0xFFFFFFFF, SDHCI_INT_STATUS); + + /* If TBSTAT[15:8]-TBSTAT[7:0] > 4 * div_ratio + * or TBSTAT[7:0]-TBSTAT[15:8] > 4 * div_ratio, + * then program TBPTR[TB_WNDW_END_PTR] = 4 * div_ratio + * and program TBPTR[TB_WNDW_START_PTR] = 8 * div_ratio. + */ + tbstat_7_0 = val & 0xff; + tbstat_15_8 = (val >> 8) & 0xff; + + if (abs(tbstat_15_8 - tbstat_7_0) > (4 * esdhc->div_ratio)) { + *window_start = 8 * esdhc->div_ratio; + *window_end = 4 * esdhc->div_ratio; + } else { + *window_start = 5 * esdhc->div_ratio; + *window_end = 3 * esdhc->div_ratio; + } +} + +static int esdhc_execute_sw_tuning(struct mmc_host *mmc, u32 opcode, + u8 window_start, u8 window_end) +{ + struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); + u32 val; + int ret; + + /* Program TBPTR[TB_WNDW_END_PTR] and TBPTR[TB_WNDW_START_PTR] */ + val = ((u32)window_start << ESDHC_WNDW_STRT_PTR_SHIFT) & + ESDHC_WNDW_STRT_PTR_MASK; + val |= window_end & ESDHC_WNDW_END_PTR_MASK; + sdhci_writel(host, val, ESDHC_TBPTR); + + /* Program the software tuning mode by setting TBCTL[TB_MODE]=2'h3 */ + val = sdhci_readl(host, ESDHC_TBCTL); + val &= ~ESDHC_TB_MODE_MASK; + val |= ESDHC_TB_MODE_SW; + sdhci_writel(host, val, ESDHC_TBCTL); + + esdhc->in_sw_tuning = true; + ret = sdhci_execute_tuning(mmc, opcode); + esdhc->in_sw_tuning = false; + return ret; +} + static int esdhc_execute_tuning(struct mmc_host *mmc, u32 opcode) { struct sdhci_host *host = mmc_priv(mmc); struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); + u8 window_start, window_end; + int ret, retries = 1; bool hs400_tuning; unsigned int clk; u32 val; - int ret; /* For tuning mode, the sd clock divisor value * must be larger than 3 according to reference manual. @@ -846,39 +1005,84 @@ if (host->clock > clk) esdhc_of_set_clock(host, clk); - if (esdhc->quirk_limited_clk_division && - host->flags & SDHCI_HS400_TUNING) - esdhc_of_set_clock(host, host->clock); - esdhc_tuning_block_enable(host, true); + /* + * The eSDHC controller takes the data timeout value into account + * during tuning. If the SD card is too slow sending the response, the + * timer will expire and a "Buffer Read Ready" interrupt without data + * is triggered. This leads to tuning errors. + * + * Just set the timeout to the maximum value because the core will + * already take care of it in sdhci_send_tuning(). + */ + sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL); + hs400_tuning = host->flags & SDHCI_HS400_TUNING; - ret = sdhci_execute_tuning(mmc, opcode); - if (hs400_tuning) { - val = sdhci_readl(host, ESDHC_SDTIMNGCTL); - val |= ESDHC_FLW_CTL_BG; - sdhci_writel(host, val, ESDHC_SDTIMNGCTL); - } + do { + if (esdhc->quirk_limited_clk_division && + hs400_tuning) + esdhc_of_set_clock(host, host->clock); - if (host->tuning_err == -EAGAIN && esdhc->quirk_fixup_tuning) { + /* Do HW tuning */ + val = sdhci_readl(host, ESDHC_TBCTL); + val &= ~ESDHC_TB_MODE_MASK; + val |= ESDHC_TB_MODE_3; + sdhci_writel(host, val, ESDHC_TBCTL); - /* program TBPTR[TB_WNDW_END_PTR] = 3*DIV_RATIO and - * program TBPTR[TB_WNDW_START_PTR] = 5*DIV_RATIO - */ - val = sdhci_readl(host, ESDHC_TBPTR); - val = (val & ~((0x7f << 8) | 0x7f)) | - (3 * esdhc->div_ratio) | ((5 * esdhc->div_ratio) << 8); - sdhci_writel(host, val, ESDHC_TBPTR); + ret = sdhci_execute_tuning(mmc, opcode); + if (ret) + break; - /* program the software tuning mode by setting - * TBCTL[TB_MODE]=2'h3 + /* If HW tuning fails and triggers erratum, + * try workaround. */ - val = sdhci_readl(host, ESDHC_TBCTL); - val |= 0x3; - sdhci_writel(host, val, ESDHC_TBCTL); - sdhci_execute_tuning(mmc, opcode); + ret = host->tuning_err; + if (ret == -EAGAIN && + (esdhc->quirk_tuning_erratum_type1 || + esdhc->quirk_tuning_erratum_type2)) { + /* Recover HS400 tuning flag */ + if (hs400_tuning) + host->flags |= SDHCI_HS400_TUNING; + pr_info("%s: Hold on to use fixed sampling clock. Try SW tuning!\n", + mmc_hostname(mmc)); + /* Do SW tuning */ + esdhc_prepare_sw_tuning(host, &window_start, + &window_end); + ret = esdhc_execute_sw_tuning(mmc, opcode, + window_start, + window_end); + if (ret) + break; + + /* Retry both HW/SW tuning with reduced clock. */ + ret = host->tuning_err; + if (ret == -EAGAIN && retries) { + /* Recover HS400 tuning flag */ + if (hs400_tuning) + host->flags |= SDHCI_HS400_TUNING; + + clk = host->max_clk / (esdhc->div_ratio + 1); + esdhc_of_set_clock(host, clk); + pr_info("%s: Hold on to use fixed sampling clock. Try tuning with reduced clock!\n", + mmc_hostname(mmc)); + } else { + break; + } + } else { + break; + } + } while (retries--); + + if (ret) { + esdhc_tuning_block_enable(host, false); + } else if (hs400_tuning) { + val = sdhci_readl(host, ESDHC_SDTIMNGCTL); + val |= ESDHC_FLW_CTL_BG; + sdhci_writel(host, val, ESDHC_SDTIMNGCTL); } + return ret; } @@ -893,10 +1097,11 @@ static u32 esdhc_irq(struct sdhci_host *host, u32 intmask) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); u32 command; - if (of_find_compatible_node(NULL, NULL, - "fsl,p2020-esdhc")) { + if (esdhc->quirk_trans_complete_erratum) { command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); if (command == MMC_WRITE_MULTIPLE_BLOCK && @@ -1010,6 +1215,8 @@ static struct soc_device_attribute soc_unreliable_pulse_detection[] = { { .family = "QorIQ LX2160A", .revision = "1.0", }, + { .family = "QorIQ LX2160A", .revision = "2.0", }, + { .family = "QorIQ LS1028A", .revision = "1.0", }, { }, }; @@ -1049,6 +1256,12 @@ if (match) esdhc->clk_fixup = match->data; np = pdev->dev.of_node; + + if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { + esdhc->quirk_delay_before_data_reset = true; + esdhc->quirk_trans_complete_erratum = true; + } + clk = of_clk_get(np, 0); if (!IS_ERR(clk)) { /* @@ -1114,10 +1327,15 @@ pltfm_host = sdhci_priv(host); esdhc = sdhci_pltfm_priv(pltfm_host); - if (soc_device_match(soc_fixup_tuning)) - esdhc->quirk_fixup_tuning = true; + if (soc_device_match(soc_tuning_erratum_type1)) + esdhc->quirk_tuning_erratum_type1 = true; + else + esdhc->quirk_tuning_erratum_type1 = false; + + if (soc_device_match(soc_tuning_erratum_type2)) + esdhc->quirk_tuning_erratum_type2 = true; else - esdhc->quirk_fixup_tuning = false; + esdhc->quirk_tuning_erratum_type2 = false; if (esdhc->vendor_ver == VENDOR_V_22) host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; @@ -1126,8 +1344,8 @@ host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ; if (of_find_compatible_node(NULL, NULL, "fsl,p2020-esdhc")) { - host->quirks2 |= SDHCI_QUIRK_RESET_AFTER_REQUEST; - host->quirks2 |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + host->quirks |= SDHCI_QUIRK_RESET_AFTER_REQUEST; + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; } if (of_device_is_compatible(np, "fsl,p5040-esdhc") || --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-omap.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-omap.c @@ -675,7 +675,8 @@ { struct mmc_host *mmc = host->mmc; - mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); + if (!IS_ERR(mmc->supply.vmmc)) + mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); } static int sdhci_omap_enable_dma(struct sdhci_host *host) @@ -1134,6 +1135,9 @@ host->mmc_host_ops.execute_tuning = sdhci_omap_execute_tuning; host->mmc_host_ops.enable_sdio_irq = sdhci_omap_enable_sdio_irq; + /* R1B responses is required to properly manage HW busy detection. */ + mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + ret = sdhci_setup_host(host); if (ret) goto err_put_sync; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-pci-core.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-pci-core.c @@ -21,11 +21,15 @@ #include #include #include +#include #include #include +#include +#include #include #include #include +#include #ifdef CONFIG_X86 #include @@ -230,6 +234,14 @@ sdhci_dumpregs(mmc_priv(mmc)); } +static void sdhci_cqhci_reset(struct sdhci_host *host, u8 mask) +{ + if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) && + host->mmc->cqe_private) + cqhci_deactivate(host->mmc); + sdhci_reset(host, mask); +} + /*****************************************************************************\ * * * Hardware specific quirk handling * @@ -508,8 +520,11 @@ int drv_strength; bool d3_retune; bool rpm_retune_ok; + bool needs_pwr_off; u32 glk_rx_ctrl1; u32 glk_tun_val; + u32 active_ltr; + u32 idle_ltr; }; static const guid_t intel_dsm_guid = @@ -599,6 +614,9 @@ struct sdhci_pci_slot *slot = sdhci_priv(host); struct intel_host *intel_host = sdhci_pci_priv(slot); + if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv)) + return 0; + return intel_host->drv_strength; } @@ -630,9 +648,25 @@ static void sdhci_intel_set_power(struct sdhci_host *host, unsigned char mode, unsigned short vdd) { + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct intel_host *intel_host = sdhci_pci_priv(slot); int cntr; u8 reg; + /* + * Bus power may control card power, but a full reset still may not + * reset the power, whereas a direct write to SDHCI_POWER_CONTROL can. + * That might be needed to initialize correctly, if the card was left + * powered on previously. + */ + if (intel_host->needs_pwr_off) { + intel_host->needs_pwr_off = false; + if (mode != MMC_POWER_OFF) { + sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); + usleep_range(10000, 12500); + } + } + sdhci_set_power(host, mode, vdd); if (mode == MMC_POWER_OFF) @@ -652,6 +686,15 @@ } } +static void sdhci_intel_set_uhs_signaling(struct sdhci_host *host, + unsigned int timing) +{ + /* Set UHS timing to SDR25 for High Speed mode */ + if (timing == MMC_TIMING_MMC_HS || timing == MMC_TIMING_SD_HS) + timing = MMC_TIMING_UHS_SDR25; + sdhci_set_uhs_signaling(host, timing); +} + #define INTEL_HS400_ES_REG 0x78 #define INTEL_HS400_ES_BIT BIT(0) @@ -708,7 +751,7 @@ .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, + .set_uhs_signaling = sdhci_intel_set_uhs_signaling, .hw_reset = sdhci_pci_hw_reset, }; @@ -717,8 +760,8 @@ .set_power = sdhci_intel_set_power, .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, - .set_uhs_signaling = sdhci_set_uhs_signaling, + .reset = sdhci_cqhci_reset, + .set_uhs_signaling = sdhci_intel_set_uhs_signaling, .hw_reset = sdhci_pci_hw_reset, .irq = sdhci_cqhci_irq, }; @@ -751,6 +794,108 @@ return 0; } +#define INTEL_ACTIVELTR 0x804 +#define INTEL_IDLELTR 0x808 + +#define INTEL_LTR_REQ BIT(15) +#define INTEL_LTR_SCALE_MASK GENMASK(11, 10) +#define INTEL_LTR_SCALE_1US (2 << 10) +#define INTEL_LTR_SCALE_32US (3 << 10) +#define INTEL_LTR_VALUE_MASK GENMASK(9, 0) + +static void intel_cache_ltr(struct sdhci_pci_slot *slot) +{ + struct intel_host *intel_host = sdhci_pci_priv(slot); + struct sdhci_host *host = slot->host; + + intel_host->active_ltr = readl(host->ioaddr + INTEL_ACTIVELTR); + intel_host->idle_ltr = readl(host->ioaddr + INTEL_IDLELTR); +} + +static void intel_ltr_set(struct device *dev, s32 val) +{ + struct sdhci_pci_chip *chip = dev_get_drvdata(dev); + struct sdhci_pci_slot *slot = chip->slots[0]; + struct intel_host *intel_host = sdhci_pci_priv(slot); + struct sdhci_host *host = slot->host; + u32 ltr; + + pm_runtime_get_sync(dev); + + /* + * Program latency tolerance (LTR) accordingly what has been asked + * by the PM QoS layer or disable it in case we were passed + * negative value or PM_QOS_LATENCY_ANY. + */ + ltr = readl(host->ioaddr + INTEL_ACTIVELTR); + + if (val == PM_QOS_LATENCY_ANY || val < 0) { + ltr &= ~INTEL_LTR_REQ; + } else { + ltr |= INTEL_LTR_REQ; + ltr &= ~INTEL_LTR_SCALE_MASK; + ltr &= ~INTEL_LTR_VALUE_MASK; + + if (val > INTEL_LTR_VALUE_MASK) { + val >>= 5; + if (val > INTEL_LTR_VALUE_MASK) + val = INTEL_LTR_VALUE_MASK; + ltr |= INTEL_LTR_SCALE_32US | val; + } else { + ltr |= INTEL_LTR_SCALE_1US | val; + } + } + + if (ltr == intel_host->active_ltr) + goto out; + + writel(ltr, host->ioaddr + INTEL_ACTIVELTR); + writel(ltr, host->ioaddr + INTEL_IDLELTR); + + /* Cache the values into lpss structure */ + intel_cache_ltr(slot); +out: + pm_runtime_put_autosuspend(dev); +} + +static bool intel_use_ltr(struct sdhci_pci_chip *chip) +{ + switch (chip->pdev->device) { + case PCI_DEVICE_ID_INTEL_BYT_EMMC: + case PCI_DEVICE_ID_INTEL_BYT_EMMC2: + case PCI_DEVICE_ID_INTEL_BYT_SDIO: + case PCI_DEVICE_ID_INTEL_BYT_SD: + case PCI_DEVICE_ID_INTEL_BSW_EMMC: + case PCI_DEVICE_ID_INTEL_BSW_SDIO: + case PCI_DEVICE_ID_INTEL_BSW_SD: + return false; + default: + return true; + } +} + +static void intel_ltr_expose(struct sdhci_pci_chip *chip) +{ + struct device *dev = &chip->pdev->dev; + + if (!intel_use_ltr(chip)) + return; + + dev->power.set_latency_tolerance = intel_ltr_set; + dev_pm_qos_expose_latency_tolerance(dev); +} + +static void intel_ltr_hide(struct sdhci_pci_chip *chip) +{ + struct device *dev = &chip->pdev->dev; + + if (!intel_use_ltr(chip)) + return; + + dev_pm_qos_hide_latency_tolerance(dev); + dev->power.set_latency_tolerance = NULL; +} + static void byt_probe_slot(struct sdhci_pci_slot *slot) { struct mmc_host_ops *ops = &slot->host->mmc_host_ops; @@ -765,6 +910,43 @@ ops->start_signal_voltage_switch = intel_start_signal_voltage_switch; device_property_read_u32(dev, "max-frequency", &mmc->f_max); + + if (!mmc->slotno) { + slot->chip->slots[mmc->slotno] = slot; + intel_ltr_expose(slot->chip); + } +} + +static void byt_add_debugfs(struct sdhci_pci_slot *slot) +{ + struct intel_host *intel_host = sdhci_pci_priv(slot); + struct mmc_host *mmc = slot->host->mmc; + struct dentry *dir = mmc->debugfs_root; + + if (!intel_use_ltr(slot->chip)) + return; + + debugfs_create_x32("active_ltr", 0444, dir, &intel_host->active_ltr); + debugfs_create_x32("idle_ltr", 0444, dir, &intel_host->idle_ltr); + + intel_cache_ltr(slot); +} + +static int byt_add_host(struct sdhci_pci_slot *slot) +{ + int ret = sdhci_add_host(slot->host); + + if (!ret) + byt_add_debugfs(slot); + return ret; +} + +static void byt_remove_slot(struct sdhci_pci_slot *slot, int dead) +{ + struct mmc_host *mmc = slot->host->mmc; + + if (!mmc->slotno) + intel_ltr_hide(slot->chip); } static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot) @@ -782,11 +964,19 @@ return 0; } +static bool glk_broken_cqhci(struct sdhci_pci_slot *slot) +{ + return slot->chip->pdev->device == PCI_DEVICE_ID_INTEL_GLK_EMMC && + (dmi_match(DMI_BIOS_VENDOR, "LENOVO") || + dmi_match(DMI_SYS_VENDOR, "IRBIS")); +} + static int glk_emmc_probe_slot(struct sdhci_pci_slot *slot) { int ret = byt_emmc_probe_slot(slot); - slot->host->mmc->caps2 |= MMC_CAP2_CQE; + if (!glk_broken_cqhci(slot)) + slot->host->mmc->caps2 |= MMC_CAP2_CQE; if (slot->chip->pdev->device != PCI_DEVICE_ID_INTEL_GLK_EMMC) { slot->host->mmc->caps2 |= MMC_CAP2_HS400_ES, @@ -838,6 +1028,8 @@ if (ret) goto cleanup; + byt_add_debugfs(slot); + return 0; cleanup: @@ -964,6 +1156,14 @@ return 0; } +static void byt_needs_pwr_off(struct sdhci_pci_slot *slot) +{ + struct intel_host *intel_host = sdhci_pci_priv(slot); + u8 reg = sdhci_readb(slot->host, SDHCI_POWER_CONTROL); + + intel_host->needs_pwr_off = reg & SDHCI_POWER_ON; +} + static int byt_sd_probe_slot(struct sdhci_pci_slot *slot) { byt_probe_slot(slot); @@ -981,6 +1181,8 @@ slot->chip->pdev->subsystem_device == PCI_SUBDEVICE_ID_NI_78E3) slot->host->mmc->caps2 |= MMC_CAP2_AVOID_3_3V; + byt_needs_pwr_off(slot); + return 0; } @@ -1015,6 +1217,8 @@ #endif .allow_runtime_pm = true, .probe_slot = byt_emmc_probe_slot, + .add_host = byt_add_host, + .remove_slot = byt_remove_slot, .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | SDHCI_QUIRK_NO_LED, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | @@ -1028,6 +1232,7 @@ .allow_runtime_pm = true, .probe_slot = glk_emmc_probe_slot, .add_host = glk_emmc_add_host, + .remove_slot = byt_remove_slot, #ifdef CONFIG_PM_SLEEP .suspend = sdhci_cqhci_suspend, .resume = sdhci_cqhci_resume, @@ -1058,6 +1263,8 @@ SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .allow_runtime_pm = true, .probe_slot = ni_byt_sdio_probe_slot, + .add_host = byt_add_host, + .remove_slot = byt_remove_slot, .ops = &sdhci_intel_byt_ops, .priv_size = sizeof(struct intel_host), }; @@ -1075,6 +1282,8 @@ SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .allow_runtime_pm = true, .probe_slot = byt_sdio_probe_slot, + .add_host = byt_add_host, + .remove_slot = byt_remove_slot, .ops = &sdhci_intel_byt_ops, .priv_size = sizeof(struct intel_host), }; @@ -1094,6 +1303,8 @@ .allow_runtime_pm = true, .own_cd_for_runtime_pm = true, .probe_slot = byt_sd_probe_slot, + .add_host = byt_add_host, + .remove_slot = byt_remove_slot, .ops = &sdhci_intel_byt_ops, .priv_size = sizeof(struct intel_host), }; @@ -1165,7 +1376,7 @@ ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch); if (ret) - return ret; + goto fail; /* * Turn PMOS on [bit 0], set over current detection to 2.4 V @@ -1176,7 +1387,10 @@ else scratch &= ~0x47; - return pci_write_config_byte(chip->pdev, 0xAE, scratch); + ret = pci_write_config_byte(chip->pdev, 0xAE, scratch); + +fail: + return pcibios_err_to_errno(ret); } static int jmicron_probe(struct sdhci_pci_chip *chip) @@ -1584,17 +1798,67 @@ } } + pci_dev_put(smbus_dev); + if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; return 0; } +static u32 sdhci_read_present_state(struct sdhci_host *host) +{ + return sdhci_readl(host, SDHCI_PRESENT_STATE); +} + +static void amd_sdhci_reset(struct sdhci_host *host, u8 mask) +{ + struct sdhci_pci_slot *slot = sdhci_priv(host); + struct pci_dev *pdev = slot->chip->pdev; + u32 present_state; + + /* + * SDHC 0x7906 requires a hard reset to clear all internal state. + * Otherwise it can get into a bad state where the DATA lines are always + * read as zeros. + */ + if (pdev->device == 0x7906 && (mask & SDHCI_RESET_ALL)) { + pci_clear_master(pdev); + + pci_save_state(pdev); + + pci_set_power_state(pdev, PCI_D3cold); + pr_debug("%s: power_state=%u\n", mmc_hostname(host->mmc), + pdev->current_state); + pci_set_power_state(pdev, PCI_D0); + + pci_restore_state(pdev); + + /* + * SDHCI_RESET_ALL says the card detect logic should not be + * reset, but since we need to reset the entire controller + * we should wait until the card detect logic has stabilized. + * + * This normally takes about 40ms. + */ + readx_poll_timeout( + sdhci_read_present_state, + host, + present_state, + present_state & SDHCI_CD_STABLE, + 10000, + 100000 + ); + } + + return sdhci_reset(host, mask); +} + static const struct sdhci_ops amd_sdhci_pci_ops = { .set_clock = sdhci_set_clock, .enable_dma = sdhci_pci_enable_dma, .set_bus_width = sdhci_set_bus_width, - .reset = sdhci_reset, + .reset = amd_sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, }; @@ -1673,6 +1937,11 @@ SDHCI_PCI_DEVICE(INTEL, CML_EMMC, intel_glk_emmc), SDHCI_PCI_DEVICE(INTEL, CML_SD, intel_byt_sd), SDHCI_PCI_DEVICE(INTEL, CMLH_SD, intel_byt_sd), + SDHCI_PCI_DEVICE(INTEL, JSL_EMMC, intel_glk_emmc), + SDHCI_PCI_DEVICE(INTEL, JSL_SD, intel_byt_sd), + SDHCI_PCI_DEVICE(INTEL, LKF_EMMC, intel_glk_emmc), + SDHCI_PCI_DEVICE(INTEL, LKF_SD, intel_byt_sd), + SDHCI_PCI_DEVICE(INTEL, ADL_EMMC, intel_glk_emmc), SDHCI_PCI_DEVICE(O2, 8120, o2), SDHCI_PCI_DEVICE(O2, 8220, o2), SDHCI_PCI_DEVICE(O2, 8221, o2), @@ -2037,7 +2306,7 @@ ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots); if (ret) - return ret; + return pcibios_err_to_errno(ret); slots = PCI_SLOT_INFO_SLOTS(slots) + 1; dev_dbg(&pdev->dev, "found %d slot(s)\n", slots); @@ -2046,7 +2315,7 @@ ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar); if (ret) - return ret; + return pcibios_err_to_errno(ret); first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-pci-gli.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-pci-gli.c @@ -26,6 +26,9 @@ #define SDHCI_GLI_9750_DRIVING_2 GENMASK(27, 26) #define GLI_9750_DRIVING_1_VALUE 0xFFF #define GLI_9750_DRIVING_2_VALUE 0x3 +#define SDHCI_GLI_9750_SEL_1 BIT(29) +#define SDHCI_GLI_9750_SEL_2 BIT(31) +#define SDHCI_GLI_9750_ALL_RST (BIT(24)|BIT(25)|BIT(28)|BIT(30)) #define SDHCI_GLI_9750_PLL 0x864 #define SDHCI_GLI_9750_PLL_TX2_INV BIT(23) @@ -122,6 +125,8 @@ GLI_9750_DRIVING_1_VALUE); driving_value |= FIELD_PREP(SDHCI_GLI_9750_DRIVING_2, GLI_9750_DRIVING_2_VALUE); + driving_value &= ~(SDHCI_GLI_9750_SEL_1|SDHCI_GLI_9750_SEL_2|SDHCI_GLI_9750_ALL_RST); + driving_value |= SDHCI_GLI_9750_SEL_2; sdhci_writel(host, driving_value, SDHCI_GLI_9750_DRIVING); sw_ctrl_value &= ~SDHCI_GLI_9750_SW_CTRL_4; @@ -262,10 +267,26 @@ return 0; } +static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot) +{ + int ret; + + ret = pci_alloc_irq_vectors(slot->chip->pdev, 1, 1, + PCI_IRQ_MSI | PCI_IRQ_MSIX); + if (ret < 0) { + pr_warn("%s: enable PCI MSI failed, error=%d\n", + mmc_hostname(slot->host->mmc), ret); + return; + } + + slot->host->irq = pci_irq_vector(slot->chip->pdev, 0); +} + static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) { struct sdhci_host *host = slot->host; + gli_pcie_enable_msi(slot); slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; sdhci_enable_v4_mode(host); @@ -276,6 +297,7 @@ { struct sdhci_host *host = slot->host; + gli_pcie_enable_msi(slot); slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; sdhci_enable_v4_mode(host); @@ -296,8 +318,13 @@ * * Wait 5ms after set 1.8V signal enable in Host Control 2 register * to ensure 1.8V signal enable bit is set by GL9750/GL9755. + * + * ...however, the controller in the NUC10i3FNK4 (a 9755) requires + * slightly longer than 5ms before the control register reports that + * 1.8V is ready, and far longer still before the card will actually + * work reliably. */ - usleep_range(5000, 5500); + usleep_range(100000, 110000); } static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask) @@ -317,6 +344,18 @@ return value; } +#ifdef CONFIG_PM_SLEEP +static int sdhci_pci_gli_resume(struct sdhci_pci_chip *chip) +{ + struct sdhci_pci_slot *slot = chip->slots[0]; + + pci_free_irq_vectors(slot->chip->pdev); + gli_pcie_enable_msi(slot); + + return sdhci_pci_resume_host(chip); +} +#endif + static const struct sdhci_ops sdhci_gl9755_ops = { .set_clock = sdhci_set_clock, .enable_dma = sdhci_pci_enable_dma, @@ -331,6 +370,9 @@ .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, .probe_slot = gli_probe_slot_gl9755, .ops = &sdhci_gl9755_ops, +#ifdef CONFIG_PM_SLEEP + .resume = sdhci_pci_gli_resume, +#endif }; static const struct sdhci_ops sdhci_gl9750_ops = { @@ -349,4 +391,7 @@ .quirks2 = SDHCI_QUIRK2_BROKEN_DDR50, .probe_slot = gli_probe_slot_gl9750, .ops = &sdhci_gl9750_ops, +#ifdef CONFIG_PM_SLEEP + .resume = sdhci_pci_gli_resume, +#endif }; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-pci-o2micro.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-pci-o2micro.c @@ -31,6 +31,7 @@ #define O2_SD_CAPS 0xE0 #define O2_SD_ADMA1 0xE2 #define O2_SD_ADMA2 0xE7 +#define O2_SD_MISC_CTRL2 0xF0 #define O2_SD_INF_MOD 0xF1 #define O2_SD_MISC_CTRL4 0xFC #define O2_SD_TUNING_CTRL 0x300 @@ -145,6 +146,8 @@ if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS)) sdhci_o2_enable_internal_clock(host); + else + sdhci_o2_wait_card_detect_stable(host); return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); } @@ -561,6 +564,12 @@ slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd; } + if (chip->pdev->device == PCI_DEVICE_ID_O2_SEABIRD1) { + slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd; + host->mmc->caps2 |= MMC_CAP2_NO_SDIO; + host->quirks2 |= SDHCI_QUIRK2_PRESET_VALUE_BROKEN; + } + host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning; if (chip->pdev->device != PCI_DEVICE_ID_O2_FUJIN2) @@ -769,6 +778,12 @@ /* Set Tuning Windows to 5 */ pci_write_config_byte(chip->pdev, O2_SD_TUNING_CTRL, 0x55); + //Adjust 1st and 2nd CD debounce time + pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32); + scratch_32 &= 0xFFE7FFFF; + scratch_32 |= 0x00180000; + pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32); + pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1); /* Lock WP */ ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-pci.h +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-pci.h @@ -55,6 +55,11 @@ #define PCI_DEVICE_ID_INTEL_CML_EMMC 0x02c4 #define PCI_DEVICE_ID_INTEL_CML_SD 0x02f5 #define PCI_DEVICE_ID_INTEL_CMLH_SD 0x06f5 +#define PCI_DEVICE_ID_INTEL_JSL_EMMC 0x4dc4 +#define PCI_DEVICE_ID_INTEL_JSL_SD 0x4df8 +#define PCI_DEVICE_ID_INTEL_LKF_EMMC 0x98c4 +#define PCI_DEVICE_ID_INTEL_LKF_SD 0x98f8 +#define PCI_DEVICE_ID_INTEL_ADL_EMMC 0x54c4 #define PCI_DEVICE_ID_SYSKONNECT_8000 0x8000 #define PCI_DEVICE_ID_VIA_95D0 0x95d0 --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-sprd.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-sprd.c @@ -223,13 +223,19 @@ div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8); sdhci_enable_clk(host, div); - /* enable auto gate sdhc_enable_auto_gate */ val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI); - mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | - SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; - if (mask != (val & mask)) { - val |= mask; - sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); + mask = SDHCI_SPRD_BIT_OUTR_CLK_AUTO_EN | SDHCI_SPRD_BIT_INNR_CLK_AUTO_EN; + /* Enable CLK_AUTO when the clock is greater than 400K. */ + if (clk > 400000) { + if (mask != (val & mask)) { + val |= mask; + sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); + } + } else { + if (val & mask) { + val &= ~mask; + sdhci_writel(host, val, SDHCI_SPRD_REG_32_BUSY_POSI); + } } } @@ -295,7 +301,7 @@ static unsigned int sdhci_sprd_get_min_clock(struct sdhci_host *host) { - return 400000; + return 100000; } static void sdhci_sprd_set_uhs_signaling(struct sdhci_host *host, @@ -379,11 +385,33 @@ return 0; } +static void sdhci_sprd_set_power(struct sdhci_host *host, unsigned char mode, + unsigned short vdd) +{ + struct mmc_host *mmc = host->mmc; + + switch (mode) { + case MMC_POWER_OFF: + mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0); + + mmc_regulator_disable_vqmmc(mmc); + break; + case MMC_POWER_ON: + mmc_regulator_enable_vqmmc(mmc); + break; + case MMC_POWER_UP: + mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd); + break; + } +} + static struct sdhci_ops sdhci_sprd_ops = { .read_l = sdhci_sprd_readl, .write_l = sdhci_sprd_writel, + .write_w = sdhci_sprd_writew, .write_b = sdhci_sprd_writeb, .set_clock = sdhci_sprd_set_clock, + .set_power = sdhci_sprd_set_power, .get_max_clock = sdhci_sprd_get_max_clock, .get_min_clock = sdhci_sprd_get_min_clock, .set_bus_width = sdhci_set_bus_width, @@ -430,7 +458,7 @@ } if (IS_ERR(sprd_host->pinctrl)) - return 0; + goto reset; switch (ios->signal_voltage) { case MMC_SIGNAL_VOLTAGE_180: @@ -458,6 +486,8 @@ /* Wait for 300 ~ 500 us for pin state stable */ usleep_range(300, 500); + +reset: sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); return 0; @@ -625,6 +655,10 @@ host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_DDR50); + ret = mmc_regulator_get_supply(host->mmc); + if (ret) + goto pm_runtime_disable; + ret = sdhci_setup_host(host); if (ret) goto pm_runtime_disable; @@ -665,14 +699,14 @@ { struct sdhci_host *host = platform_get_drvdata(pdev); struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host); - struct mmc_host *mmc = host->mmc; - mmc_remove_host(mmc); + sdhci_remove_host(host, 0); + clk_disable_unprepare(sprd_host->clk_sdio); clk_disable_unprepare(sprd_host->clk_enable); clk_disable_unprepare(sprd_host->clk_2x_enable); - mmc_free_host(mmc); + sdhci_pltfm_free(pdev); return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-tegra.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-tegra.c @@ -24,6 +24,7 @@ #include #include +#include "sdhci-cqhci.h" #include "sdhci-pltfm.h" #include "cqhci.h" @@ -100,6 +101,12 @@ #define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP BIT(8) #define NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING BIT(9) +/* + * NVQUIRK_HAS_TMCLK is for SoC's having separate timeout clock for Tegra + * SDMMC hardware data timeout. + */ +#define NVQUIRK_HAS_TMCLK BIT(10) + /* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */ #define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000 @@ -130,6 +137,7 @@ struct sdhci_tegra { const struct sdhci_tegra_soc_data *soc_data; struct gpio_desc *power_gpio; + struct clk *tmclk; bool ddr_signaling; bool pad_calib_required; bool pad_control_available; @@ -333,23 +341,6 @@ } } -static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc, - struct mmc_ios *ios) -{ - struct sdhci_host *host = mmc_priv(mmc); - u32 val; - - val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); - - if (ios->enhanced_strobe) - val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; - else - val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; - - sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); - -} - static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -357,7 +348,7 @@ const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; u32 misc_ctrl, clk_ctrl, pad_ctrl; - sdhci_reset(host, mask); + sdhci_and_cqhci_reset(host, mask); if (!(mask & SDHCI_RESET_ALL)) return; @@ -386,7 +377,7 @@ misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_DDR50; if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) misc_ctrl |= SDHCI_MISC_CTRL_ENABLE_SDR104; - if (soc_data->nvquirks & SDHCI_MISC_CTRL_ENABLE_SDR50) + if (soc_data->nvquirks & NVQUIRK_ENABLE_SDR50) clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE; } @@ -761,6 +752,32 @@ } } +static void tegra_sdhci_hs400_enhanced_strobe(struct mmc_host *mmc, + struct mmc_ios *ios) +{ + struct sdhci_host *host = mmc_priv(mmc); + u32 val; + + val = sdhci_readl(host, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); + + if (ios->enhanced_strobe) { + val |= SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; + /* + * When CMD13 is sent from mmc_select_hs400es() after + * switching to HS400ES mode, the bus is operating at + * either MMC_HIGH_26_MAX_DTR or MMC_HIGH_52_MAX_DTR. + * To meet Tegra SDHCI requirement at HS400ES mode, force SDHCI + * interface clock to MMC_HS200_MAX_DTR (200 MHz) so that host + * controller CAR clock and the interface clock are rate matched. + */ + tegra_sdhci_set_clock(host, MMC_HS200_MAX_DTR); + } else { + val &= ~SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE; + } + + sdhci_writel(host, val, SDHCI_TEGRA_VENDOR_SYS_SW_CTRL); +} + static unsigned int tegra_sdhci_get_max_clock(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -1283,7 +1300,6 @@ SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_SINGLE_POWER_WRITE | SDHCI_QUIRK_NO_HISPD_BIT | - SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | SDHCI_QUIRK2_BROKEN_HS200 | @@ -1370,7 +1386,6 @@ static const struct sdhci_pltfm_data sdhci_tegra210_pdata = { .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_SINGLE_POWER_WRITE | SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | @@ -1386,7 +1401,8 @@ NVQUIRK_HAS_PADCALIB | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | - NVQUIRK_ENABLE_SDR104, + NVQUIRK_ENABLE_SDR104 | + NVQUIRK_HAS_TMCLK, .min_tap_delay = 106, .max_tap_delay = 185, }; @@ -1407,7 +1423,6 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | SDHCI_QUIRK_SINGLE_POWER_WRITE | SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | @@ -1424,6 +1439,7 @@ NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | NVQUIRK_ENABLE_SDR104 | + NVQUIRK_HAS_TMCLK | NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING, .min_tap_delay = 84, .max_tap_delay = 136, @@ -1436,7 +1452,8 @@ NVQUIRK_HAS_PADCALIB | NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | - NVQUIRK_ENABLE_SDR104, + NVQUIRK_ENABLE_SDR104 | + NVQUIRK_HAS_TMCLK, .min_tap_delay = 96, .max_tap_delay = 139, }; @@ -1552,6 +1569,9 @@ if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) host->mmc->caps |= MMC_CAP_1_8V_DDR; + /* R1B responses is required to properly manage HW busy detection. */ + host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + tegra_sdhci_parse_dt(host); tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", @@ -1561,6 +1581,43 @@ goto err_power_req; } + /* + * Tegra210 has a separate SDMMC_LEGACY_TM clock used for host + * timeout clock and SW can choose TMCLK or SDCLK for hardware + * data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT of + * the register SDHCI_TEGRA_VENDOR_SYS_SW_CTRL. + * + * USE_TMCLK_FOR_DATA_TIMEOUT bit default is set to 1 and SDMMC uses + * 12Mhz TMCLK which is advertised in host capability register. + * With TMCLK of 12Mhz provides maximum data timeout period that can + * be achieved is 11s better than using SDCLK for data timeout. + * + * So, TMCLK is set to 12Mhz and kept enabled all the time on SoC's + * supporting separate TMCLK. + */ + + if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK) { + clk = devm_clk_get(&pdev->dev, "tmclk"); + if (IS_ERR(clk)) { + rc = PTR_ERR(clk); + if (rc == -EPROBE_DEFER) + goto err_power_req; + + dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc); + clk = NULL; + } + + clk_set_rate(clk, 12000000); + rc = clk_prepare_enable(clk); + if (rc) { + dev_err(&pdev->dev, + "failed to enable tmclk: %d\n", rc); + goto err_power_req; + } + + tegra_host->tmclk = clk; + } + clk = devm_clk_get(mmc_dev(host->mmc), NULL); if (IS_ERR(clk)) { rc = PTR_ERR(clk); @@ -1604,6 +1661,7 @@ err_rst_get: clk_disable_unprepare(pltfm_host->clk); err_clk_get: + clk_disable_unprepare(tegra_host->tmclk); err_power_req: err_parse_dt: sdhci_pltfm_free(pdev); @@ -1621,6 +1679,7 @@ reset_control_assert(tegra_host->rst); usleep_range(2000, 4000); clk_disable_unprepare(pltfm_host->clk); + clk_disable_unprepare(tegra_host->tmclk); sdhci_pltfm_free(pdev); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci-xenon.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci-xenon.c @@ -167,7 +167,12 @@ /* Disable tuning request and auto-retuning again */ xenon_retune_setup(host); - xenon_set_acg(host, true); + /* + * The ACG should be turned off at the early init time, in order + * to solve a possible issues with the 1.8V regulator stabilization. + * The feature is enabled in later stage. + */ + xenon_set_acg(host, false); xenon_set_sdclk_off_idle(host, sdhc_id, false); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci.c @@ -9,6 +9,7 @@ * - JMicron (hardware and technical support) */ +#include #include #include #include @@ -152,7 +153,7 @@ u32 present; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - !mmc_card_is_removable(host->mmc)) + !mmc_card_is_removable(host->mmc) || mmc_can_gpio_cd(host->mmc)) return; if (enable) { @@ -331,6 +332,7 @@ if (soft) { /* force clock reconfiguration */ host->clock = 0; + host->reinit_uhs = true; mmc->ops->set_ios(mmc, &mmc->ios); } } @@ -474,7 +476,7 @@ { unsigned long flags; size_t blksize, len, chunk; - u32 uninitialized_var(scratch); + u32 scratch; u8 *buf; DBG("PIO reading\n"); @@ -749,7 +751,19 @@ len -= offset; } - BUG_ON(len > 65536); + /* + * The block layer forces a minimum segment size of PAGE_SIZE, + * so 'len' can be too big here if PAGE_SIZE >= 64KiB. Write + * multiple descriptors, noting that the ADMA table is sized + * for 4KiB chunks anyway, so it will be big enough. + */ + while (len > host->max_adma) { + int n = 32 * 1024; /* 32KiB*/ + + __sdhci_adma_write_desc(host, &desc, addr, n, ADMA2_TRAN_VALID); + addr += n; + len -= n; + } /* tran, valid */ if (len) @@ -981,7 +995,7 @@ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); } -static void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable) +void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable) { if (enable) host->ier |= SDHCI_INT_DATA_TIMEOUT; @@ -990,28 +1004,31 @@ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); } +EXPORT_SYMBOL_GPL(sdhci_set_data_timeout_irq); -static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) +void __sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) { - u8 count; - - if (host->ops->set_timeout) { - host->ops->set_timeout(host, cmd); - } else { - bool too_big = false; + bool too_big = false; + u8 count = sdhci_calc_timeout(host, cmd, &too_big); - count = sdhci_calc_timeout(host, cmd, &too_big); + if (too_big && + host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT) { + sdhci_calc_sw_timeout(host, cmd); + sdhci_set_data_timeout_irq(host, false); + } else if (!(host->ier & SDHCI_INT_DATA_TIMEOUT)) { + sdhci_set_data_timeout_irq(host, true); + } - if (too_big && - host->quirks2 & SDHCI_QUIRK2_DISABLE_HW_TIMEOUT) { - sdhci_calc_sw_timeout(host, cmd); - sdhci_set_data_timeout_irq(host, false); - } else if (!(host->ier & SDHCI_INT_DATA_TIMEOUT)) { - sdhci_set_data_timeout_irq(host, true); - } + sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); +} +EXPORT_SYMBOL_GPL(__sdhci_set_timeout); - sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); - } +static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) +{ + if (host->ops->set_timeout) + host->ops->set_timeout(host, cmd); + else + __sdhci_set_timeout(host, cmd); } static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) @@ -1087,6 +1104,8 @@ } } + sdhci_config_dma(host); + if (host->flags & SDHCI_REQ_USE_DMA) { int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED); @@ -1106,8 +1125,6 @@ } } - sdhci_config_dma(host); - if (!(host->flags & SDHCI_REQ_USE_DMA)) { int flags; @@ -1159,9 +1176,11 @@ /* * In case of Version 4.10 or later, use of 'Auto CMD Auto * Select' is recommended rather than use of 'Auto CMD12 - * Enable' or 'Auto CMD23 Enable'. + * Enable' or 'Auto CMD23 Enable'. We require Version 4 Mode + * here because some controllers (e.g sdhci-of-dwmshc) expect it. */ - if (host->version >= SDHCI_SPEC_410 && (use_cmd12 || use_cmd23)) { + if (host->version >= SDHCI_SPEC_410 && host->v4_mode && + (use_cmd12 || use_cmd23)) { *mode |= SDHCI_TRNS_AUTO_SEL; ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); @@ -1506,6 +1525,10 @@ u16 preset = 0; switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED); + break; case MMC_TIMING_UHS_SDR12: preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); break; @@ -1549,10 +1572,9 @@ clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); pre_val = sdhci_get_preset_value(host); - div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK) - >> SDHCI_PRESET_SDCLK_FREQ_SHIFT; + div = FIELD_GET(SDHCI_PRESET_SDCLK_FREQ_MASK, pre_val); if (host->clk_mul && - (pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) { + (pre_val & SDHCI_PRESET_CLKGEN_SEL)) { clk = SDHCI_PROG_CLOCK_MODE; real_div = div + 1; clk_mul = host->clk_mul; @@ -1732,6 +1754,12 @@ break; case MMC_VDD_32_33: case MMC_VDD_33_34: + /* + * 3.4 ~ 3.6V are valid only for those platforms where it's + * known that the voltage range is supported by hardware. + */ + case MMC_VDD_34_35: + case MMC_VDD_35_36: pwr = SDHCI_POWER_330; break; default: @@ -1871,9 +1899,7 @@ ctrl_2 |= SDHCI_CTRL_UHS_SDR104; else if (timing == MMC_TIMING_UHS_SDR12) ctrl_2 |= SDHCI_CTRL_UHS_SDR12; - else if (timing == MMC_TIMING_SD_HS || - timing == MMC_TIMING_MMC_HS || - timing == MMC_TIMING_UHS_SDR25) + else if (timing == MMC_TIMING_UHS_SDR25) ctrl_2 |= SDHCI_CTRL_UHS_SDR25; else if (timing == MMC_TIMING_UHS_SDR50) ctrl_2 |= SDHCI_CTRL_UHS_SDR50; @@ -1886,11 +1912,46 @@ } EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); +static bool sdhci_timing_has_preset(unsigned char timing) +{ + switch (timing) { + case MMC_TIMING_UHS_SDR12: + case MMC_TIMING_UHS_SDR25: + case MMC_TIMING_UHS_SDR50: + case MMC_TIMING_UHS_SDR104: + case MMC_TIMING_UHS_DDR50: + case MMC_TIMING_MMC_DDR52: + return true; + }; + return false; +} + +static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing) +{ + return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && + sdhci_timing_has_preset(timing); +} + +static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios) +{ + /* + * Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK + * Frequency. Check if preset values need to be enabled, or the Driver + * Strength needs updating. Note, clock changes are handled separately. + */ + return !host->preset_enabled && + (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type); +} + void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct sdhci_host *host = mmc_priv(mmc); + bool reinit_uhs = host->reinit_uhs; + bool turning_on_clk = false; u8 ctrl; + host->reinit_uhs = false; + if (ios->power_mode == MMC_POWER_UNDEFINED) return; @@ -1916,6 +1977,8 @@ sdhci_enable_preset_value(host, false); if (!ios->clock || ios->clock != host->clock) { + turning_on_clk = ios->clock && !host->clock; + host->ops->set_clock(host, ios->clock); host->clock = ios->clock; @@ -1942,6 +2005,17 @@ host->ops->set_bus_width(host, ios->bus_width); + /* + * Special case to avoid multiple clock changes during voltage + * switching. + */ + if (!reinit_uhs && + turning_on_clk && + host->timing == ios->timing && + host->version >= SDHCI_SPEC_300 && + !sdhci_presetable_values_change(host, ios)) + return; + ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) { @@ -1985,6 +2059,7 @@ } sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); + host->drv_type = ios->drv_type; } else { /* * According to SDHC Spec v3.00, if the Preset Value @@ -2012,19 +2087,14 @@ host->ops->set_uhs_signaling(host, ios->timing); host->timing = ios->timing; - if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && - ((ios->timing == MMC_TIMING_UHS_SDR12) || - (ios->timing == MMC_TIMING_UHS_SDR25) || - (ios->timing == MMC_TIMING_UHS_SDR50) || - (ios->timing == MMC_TIMING_UHS_SDR104) || - (ios->timing == MMC_TIMING_UHS_DDR50) || - (ios->timing == MMC_TIMING_MMC_DDR52))) { + if (sdhci_preset_needed(host, ios->timing)) { u16 preset; sdhci_enable_preset_value(host, true); preset = sdhci_get_preset_value(host); - ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK) - >> SDHCI_PRESET_DRV_SHIFT; + ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK, + preset); + host->drv_type = ios->drv_type; } /* Re-enable SD Clock */ @@ -2071,26 +2141,29 @@ static int sdhci_check_ro(struct sdhci_host *host) { - unsigned long flags; + bool allow_invert = false; int is_readonly; - spin_lock_irqsave(&host->lock, flags); - - if (host->flags & SDHCI_DEVICE_DEAD) + if (host->flags & SDHCI_DEVICE_DEAD) { is_readonly = 0; - else if (host->ops->get_ro) + } else if (host->ops->get_ro) { is_readonly = host->ops->get_ro(host); - else if (mmc_can_gpio_ro(host->mmc)) + } else if (mmc_can_gpio_ro(host->mmc)) { is_readonly = mmc_gpio_get_ro(host->mmc); - else + /* Do not invert twice */ + allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); + } else { is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_WRITE_PROTECT); + allow_invert = true; + } - spin_unlock_irqrestore(&host->lock, flags); + if (is_readonly >= 0 && + allow_invert && + (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)) + is_readonly = !is_readonly; - /* This quirk needs to be replaced by a callback-function later */ - return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? - !is_readonly : is_readonly; + return is_readonly; } #define SAMPLE_COUNT 5 @@ -2408,8 +2481,8 @@ sdhci_send_tuning(host, opcode); if (!host->tuning_done) { - pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n", - mmc_hostname(host->mmc)); + pr_debug("%s: Tuning timeout, falling back to fixed sampling clock\n", + mmc_hostname(host->mmc)); sdhci_abort_tuning(host, opcode); return -ETIMEDOUT; } @@ -2645,6 +2718,37 @@ } /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (sdhci_needs_reset(host, mrq)) { + /* + * Do not finish until command and data lines are available for + * reset. Note there can only be one other mrq, so it cannot + * also be in mrqs_done, otherwise host->cmd and host->data_cmd + * would both be null. + */ + if (host->cmd || host->data_cmd) { + spin_unlock_irqrestore(&host->lock, flags); + return true; + } + + /* Some controllers need this kick or reset won't work here */ + if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) + /* This is to force an update */ + host->ops->set_clock(host, host->clock); + + /* + * Spec says we should do both at the same time, but Ricoh + * controllers do not like that. + */ + sdhci_do_reset(host, SDHCI_RESET_CMD); + sdhci_do_reset(host, SDHCI_RESET_DATA); + + host->pending_reset = false; + } + + /* * Always unmap the data buffers if they were mapped by * sdhci_prepare_data() whenever we finish with a request. * This avoids leaking DMA mappings on error. @@ -2696,35 +2800,6 @@ } } - /* - * The controller needs a reset of internal state machines - * upon error conditions. - */ - if (sdhci_needs_reset(host, mrq)) { - /* - * Do not finish until command and data lines are available for - * reset. Note there can only be one other mrq, so it cannot - * also be in mrqs_done, otherwise host->cmd and host->data_cmd - * would both be null. - */ - if (host->cmd || host->data_cmd) { - spin_unlock_irqrestore(&host->lock, flags); - return true; - } - - /* Some controllers need this kick or reset won't work here */ - if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) - /* This is to force an update */ - host->ops->set_clock(host, host->clock); - - /* Spec says we should do both at the same time, but Ricoh - controllers do not like that. */ - sdhci_do_reset(host, SDHCI_RESET_CMD); - sdhci_do_reset(host, SDHCI_RESET_DATA); - - host->pending_reset = false; - } - host->mrqs_done[i] = NULL; spin_unlock_irqrestore(&host->lock, flags); @@ -3300,6 +3375,7 @@ sdhci_init(host, 0); host->pwr = 0; host->clock = 0; + host->reinit_uhs = true; mmc->ops->set_ios(mmc, &mmc->ios); } else { sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); @@ -3362,6 +3438,7 @@ /* Force clock and power re-program */ host->pwr = 0; host->clock = 0; + host->reinit_uhs = true; mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios); mmc->ops->set_ios(mmc, &mmc->ios); @@ -3553,6 +3630,7 @@ * descriptor for each segment, plus 1 for a nop end descriptor. */ host->adma_table_cnt = SDHCI_MAX_SEGS * 2 + 1; + host->max_adma = 65536; return host; } @@ -3758,6 +3836,9 @@ mmc_hostname(mmc), host->version); } + if (host->quirks & SDHCI_QUIRK_BROKEN_CQE) + mmc->caps2 &= ~MMC_CAP2_CQE; + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) host->flags |= SDHCI_USE_SDMA; else if (!(host->caps & SDHCI_CAN_DO_SDMA)) @@ -3901,11 +3982,13 @@ if (host->ops->get_min_clock) mmc->f_min = host->ops->get_min_clock(host); else if (host->version >= SDHCI_SPEC_300) { - if (host->clk_mul) { - mmc->f_min = (host->max_clk * host->clk_mul) / 1024; + if (host->clk_mul) max_clk = host->max_clk * host->clk_mul; - } else - mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; + /* + * Divided Clock Mode minimum clock rate is always less than + * Programmable Clock Mode minimum clock rate. + */ + mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; } else mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; @@ -4201,10 +4284,12 @@ * be larger than 64 KiB though. */ if (host->flags & SDHCI_USE_ADMA) { - if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) + if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) { + host->max_adma = 65532; /* 32-bit alignment */ mmc->max_seg_size = 65535; - else + } else { mmc->max_seg_size = 65536; + } } else { mmc->max_seg_size = mmc->max_req_size; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci.h +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci.h @@ -9,6 +9,7 @@ #ifndef __SDHCI_HW_H #define __SDHCI_HW_H +#include #include #include #include @@ -261,18 +262,16 @@ /* 60-FB reserved */ +#define SDHCI_PRESET_FOR_HIGH_SPEED 0x64 #define SDHCI_PRESET_FOR_SDR12 0x66 #define SDHCI_PRESET_FOR_SDR25 0x68 #define SDHCI_PRESET_FOR_SDR50 0x6A #define SDHCI_PRESET_FOR_SDR104 0x6C #define SDHCI_PRESET_FOR_DDR50 0x6E #define SDHCI_PRESET_FOR_HS400 0x74 /* Non-standard */ -#define SDHCI_PRESET_DRV_MASK 0xC000 -#define SDHCI_PRESET_DRV_SHIFT 14 -#define SDHCI_PRESET_CLKGEN_SEL_MASK 0x400 -#define SDHCI_PRESET_CLKGEN_SEL_SHIFT 10 -#define SDHCI_PRESET_SDCLK_FREQ_MASK 0x3FF -#define SDHCI_PRESET_SDCLK_FREQ_SHIFT 0 +#define SDHCI_PRESET_DRV_MASK GENMASK(15, 14) +#define SDHCI_PRESET_CLKGEN_SEL BIT(10) +#define SDHCI_PRESET_SDCLK_FREQ_MASK GENMASK(9, 0) #define SDHCI_SLOT_INT_STATUS 0xFC @@ -348,7 +347,8 @@ /* * Maximum segments assuming a 512KiB maximum requisition size and a minimum - * 4KiB page size. + * 4KiB page size. Note this also allows enough for multiple descriptors in + * case of PAGE_SIZE >= 64KiB. */ #define SDHCI_MAX_SEGS 128 @@ -409,6 +409,8 @@ #define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15) /* Controller reports inverted write-protect state */ #define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16) +/* Controller has unusable command queue engine */ +#define SDHCI_QUIRK_BROKEN_CQE (1<<17) /* Controller does not like fast PIO transfers */ #define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18) /* Controller does not have a LED */ @@ -526,6 +528,8 @@ unsigned int clock; /* Current clock (MHz) */ u8 pwr; /* Current voltage */ + u8 drv_type; /* Current UHS-I driver type */ + bool reinit_uhs; /* Force UHS-related re-initialization */ bool runtime_suspended; /* Host is runtime suspended */ bool bus_on; /* Bus power prevents runtime suspend */ @@ -544,6 +548,7 @@ unsigned int blocks; /* remaining PIO blocks */ int sg_count; /* Mapped sg entries */ + int max_adma; /* Max. length in ADMA descriptor */ void *adma_table; /* ADMA descriptor table */ void *align_buffer; /* Bounce buffer */ @@ -793,5 +798,7 @@ void sdhci_reset_tuning(struct sdhci_host *host); void sdhci_send_tuning(struct sdhci_host *host, u32 opcode); void sdhci_abort_tuning(struct sdhci_host *host, u32 opcode); +void sdhci_set_data_timeout_irq(struct sdhci_host *host, bool enable); +void __sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd); #endif /* __SDHCI_HW_H */ --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci_am654.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci_am654.c @@ -227,8 +227,6 @@ */ case MMC_TIMING_SD_HS: case MMC_TIMING_MMC_HS: - case MMC_TIMING_UHS_SDR12: - case MMC_TIMING_UHS_SDR25: val &= ~SDHCI_CTRL_HISPD; } } @@ -236,6 +234,22 @@ writeb(val, host->ioaddr + reg); } +static int sdhci_am654_execute_tuning(struct mmc_host *mmc, u32 opcode) +{ + struct sdhci_host *host = mmc_priv(mmc); + int err = sdhci_execute_tuning(mmc, opcode); + + if (err) + return err; + /* + * Tuning data remains in the buffer after tuning. + * Do a command and data reset to get rid of it + */ + sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + return 0; +} + static struct sdhci_ops sdhci_am654_ops = { .get_max_clock = sdhci_pltfm_clk_get_max_clock, .get_timeout_clock = sdhci_pltfm_clk_get_max_clock, @@ -249,8 +263,7 @@ static const struct sdhci_pltfm_data sdhci_am654_pdata = { .ops = &sdhci_am654_ops, - .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | - SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, + .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }; @@ -272,8 +285,7 @@ static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { .ops = &sdhci_j721e_8bit_ops, - .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | - SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, + .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }; @@ -295,8 +307,7 @@ static const struct sdhci_pltfm_data sdhci_j721e_4bit_pdata = { .ops = &sdhci_j721e_4bit_ops, - .quirks = SDHCI_QUIRK_INVERTED_WRITE_PROTECT | - SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, + .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }; @@ -480,6 +491,8 @@ goto pm_runtime_put; } + host->mmc_host_ops.execute_tuning = sdhci_am654_execute_tuning; + ret = sdhci_am654_init(host); if (ret) goto pm_runtime_put; --- linux-oracle-5.4.0.orig/drivers/mmc/host/sdhci_f_sdh30.c +++ linux-oracle-5.4.0/drivers/mmc/host/sdhci_f_sdh30.c @@ -50,9 +50,16 @@ bool enable_cmd_dat_delay; }; +static void *sdhci_f_sdhost_priv(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + return sdhci_pltfm_priv(pltfm_host); +} + static void sdhci_f_sdh30_soft_voltage_switch(struct sdhci_host *host) { - struct f_sdhost_priv *priv = sdhci_priv(host); + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); u32 ctrl = 0; usleep_range(2500, 3000); @@ -85,7 +92,7 @@ static void sdhci_f_sdh30_reset(struct sdhci_host *host, u8 mask) { - struct f_sdhost_priv *priv = sdhci_priv(host); + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); u32 ctl; if (sdhci_readw(host, SDHCI_CLOCK_CONTROL) == 0) @@ -109,31 +116,32 @@ .set_uhs_signaling = sdhci_set_uhs_signaling, }; +static const struct sdhci_pltfm_data sdhci_f_sdh30_pltfm_data = { + .ops = &sdhci_f_sdh30_ops, + .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC + | SDHCI_QUIRK_INVERTED_WRITE_PROTECT, + .quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE + | SDHCI_QUIRK2_TUNING_WORK_AROUND, +}; + static int sdhci_f_sdh30_probe(struct platform_device *pdev) { struct sdhci_host *host; struct device *dev = &pdev->dev; - struct resource *res; - int irq, ctrl = 0, ret = 0; + int ctrl = 0, ret = 0; struct f_sdhost_priv *priv; + struct sdhci_pltfm_host *pltfm_host; u32 reg = 0; - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - host = sdhci_alloc_host(dev, sizeof(struct f_sdhost_priv)); + host = sdhci_pltfm_init(pdev, &sdhci_f_sdh30_pltfm_data, + sizeof(struct f_sdhost_priv)); if (IS_ERR(host)) return PTR_ERR(host); - priv = sdhci_priv(host); + pltfm_host = sdhci_priv(host); + priv = sdhci_pltfm_priv(pltfm_host); priv->dev = dev; - host->quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | - SDHCI_QUIRK_INVERTED_WRITE_PROTECT; - host->quirks2 = SDHCI_QUIRK2_SUPPORT_SINGLE | - SDHCI_QUIRK2_TUNING_WORK_AROUND; - priv->enable_cmd_dat_delay = device_property_read_bool(dev, "fujitsu,cmd-dat-delay-select"); @@ -141,19 +149,6 @@ if (ret) goto err; - platform_set_drvdata(pdev, host); - - host->hw_name = "f_sdh30"; - host->ops = &sdhci_f_sdh30_ops; - host->irq = irq; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - host->ioaddr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(host->ioaddr)) { - ret = PTR_ERR(host->ioaddr); - goto err; - } - if (dev_of_node(dev)) { sdhci_get_of_property(pdev); @@ -194,6 +189,9 @@ if (reg & SDHCI_CAN_DO_8BIT) priv->vendor_hs200 = F_SDH30_EMMC_HS200; + if (!(reg & SDHCI_TIMEOUT_CLK_MASK)) + host->quirks |= SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; + ret = sdhci_add_host(host); if (ret) goto err_add_host; @@ -205,23 +203,22 @@ err_clk: clk_disable_unprepare(priv->clk_iface); err: - sdhci_free_host(host); + sdhci_pltfm_free(pdev); + return ret; } static int sdhci_f_sdh30_remove(struct platform_device *pdev) { struct sdhci_host *host = platform_get_drvdata(pdev); - struct f_sdhost_priv *priv = sdhci_priv(host); - - sdhci_remove_host(host, readl(host->ioaddr + SDHCI_INT_STATUS) == - 0xffffffff); + struct f_sdhost_priv *priv = sdhci_f_sdhost_priv(host); + struct clk *clk_iface = priv->clk_iface; + struct clk *clk = priv->clk; - clk_disable_unprepare(priv->clk_iface); - clk_disable_unprepare(priv->clk); + sdhci_pltfm_unregister(pdev); - sdhci_free_host(host); - platform_set_drvdata(pdev, NULL); + clk_disable_unprepare(clk_iface); + clk_disable_unprepare(clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/sh_mmcif.c +++ linux-oracle-5.4.0/drivers/mmc/host/sh_mmcif.c @@ -1395,7 +1395,7 @@ irq[0] = platform_get_irq(pdev, 0); irq[1] = platform_get_irq_optional(pdev, 1); if (irq[0] < 0) - return -ENXIO; + return irq[0]; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(dev, res); --- linux-oracle-5.4.0.orig/drivers/mmc/host/sunxi-mmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/sunxi-mmc.c @@ -1314,8 +1314,8 @@ return ret; host->irq = platform_get_irq(pdev, 0); - if (host->irq <= 0) { - ret = -EINVAL; + if (host->irq < 0) { + ret = host->irq; goto error_disable_mmc; } @@ -1456,9 +1456,11 @@ struct sunxi_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); - pm_runtime_force_suspend(&pdev->dev); - disable_irq(host->irq); - sunxi_mmc_disable(host); + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) { + disable_irq(host->irq); + sunxi_mmc_disable(host); + } dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); mmc_free_host(mmc); --- linux-oracle-5.4.0.orig/drivers/mmc/host/tmio_mmc_core.c +++ linux-oracle-5.4.0/drivers/mmc/host/tmio_mmc_core.c @@ -217,6 +217,8 @@ else mrq->cmd->error = -ETIMEDOUT; + /* No new calls yet, but disallow concurrent tmio_mmc_done_work() */ + host->mrq = ERR_PTR(-EBUSY); host->cmd = NULL; host->data = NULL; @@ -1184,7 +1186,7 @@ if (ret == -EPROBE_DEFER) return ret; - mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities; + mmc->caps |= MMC_CAP_ERASE | MMC_CAP_4_BIT_DATA | pdata->capabilities; mmc->caps2 |= pdata->capabilities2; mmc->max_segs = pdata->max_segs ? : 32; mmc->max_blk_size = TMIO_MAX_BLK_SIZE; @@ -1285,12 +1287,14 @@ cancel_work_sync(&host->done); cancel_delayed_work_sync(&host->delayed_reset_work); tmio_mmc_release_dma(host); + tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); - pm_runtime_dont_use_autosuspend(&pdev->dev); if (host->native_hotplug) pm_runtime_put_noidle(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } EXPORT_SYMBOL_GPL(tmio_mmc_host_remove); --- linux-oracle-5.4.0.orig/drivers/mmc/host/toshsd.c +++ linux-oracle-5.4.0/drivers/mmc/host/toshsd.c @@ -651,7 +651,9 @@ if (ret) goto unmap; - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto free_irq; base = pci_resource_start(pdev, 0); dev_dbg(&pdev->dev, "MMIO %pa, IRQ %d\n", &base, pdev->irq); @@ -660,6 +662,8 @@ return 0; +free_irq: + free_irq(pdev->irq, host); unmap: pci_iounmap(pdev, host->ioaddr); release: --- linux-oracle-5.4.0.orig/drivers/mmc/host/uniphier-sd.c +++ linux-oracle-5.4.0/drivers/mmc/host/uniphier-sd.c @@ -614,11 +614,6 @@ } } - ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED, - dev_name(dev), host); - if (ret) - goto free_host; - if (priv->caps & UNIPHIER_SD_CAP_EXTENDED_IP) host->dma_ops = &uniphier_sd_internal_dma_ops; else @@ -644,10 +639,19 @@ ret = tmio_mmc_host_probe(host); if (ret) - goto free_host; + goto disable_clk; + + ret = devm_request_irq(dev, irq, tmio_mmc_irq, IRQF_SHARED, + dev_name(dev), host); + if (ret) + goto remove_host; return 0; +remove_host: + tmio_mmc_host_remove(host); +disable_clk: + uniphier_sd_clk_disable(host); free_host: tmio_mmc_host_free(host); @@ -660,6 +664,7 @@ tmio_mmc_host_remove(host); uniphier_sd_clk_disable(host); + tmio_mmc_host_free(host); return 0; } --- linux-oracle-5.4.0.orig/drivers/mmc/host/usdhi6rol0.c +++ linux-oracle-5.4.0/drivers/mmc/host/usdhi6rol0.c @@ -1743,8 +1743,10 @@ irq_cd = platform_get_irq_byname(pdev, "card detect"); irq_sd = platform_get_irq_byname(pdev, "data"); irq_sdio = platform_get_irq_byname(pdev, "SDIO"); - if (irq_sd < 0 || irq_sdio < 0) - return -ENODEV; + if (irq_sd < 0) + return irq_sd; + if (irq_sdio < 0) + return irq_sdio; mmc = mmc_alloc_host(sizeof(struct usdhi6_host), dev); if (!mmc) @@ -1803,6 +1805,7 @@ version = usdhi6_read(host, USDHI6_VERSION); if ((version & 0xfff) != 0xa0d) { + ret = -EPERM; dev_err(dev, "Version not recognized %x\n", version); goto e_clk_off; } @@ -1860,10 +1863,12 @@ ret = mmc_add_host(mmc); if (ret < 0) - goto e_clk_off; + goto e_release_dma; return 0; +e_release_dma: + usdhi6_dma_release(host); e_clk_off: clk_disable_unprepare(host->clk); e_free_mmc: --- linux-oracle-5.4.0.orig/drivers/mmc/host/via-sdmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/via-sdmmc.c @@ -319,6 +319,8 @@ /* some devices need a very long delay for power to stabilize */ #define VIA_CRDR_QUIRK_300MS_PWRDELAY 0x0001 +#define VIA_CMD_TIMEOUT_MS 1000 + static const struct pci_device_id via_ids[] = { {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_9530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, @@ -551,14 +553,17 @@ { void __iomem *addrbase; struct mmc_data *data; + unsigned int timeout_ms; u32 cmdctrl = 0; WARN_ON(host->cmd); data = cmd->data; - mod_timer(&host->timer, jiffies + HZ); host->cmd = cmd; + timeout_ms = cmd->busy_timeout ? cmd->busy_timeout : VIA_CMD_TIMEOUT_MS; + mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout_ms)); + /*Command index*/ cmdctrl = cmd->opcode << 8; @@ -852,6 +857,9 @@ { BUG_ON(intmask == 0); + if (!host->data) + return; + if (intmask & VIA_CRDR_SDSTS_DT) host->data->error = -ETIMEDOUT; else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)) @@ -1146,7 +1154,9 @@ pcidev->subsystem_device == 0x3891) sdhost->quirks = VIA_CRDR_QUIRK_300MS_PWRDELAY; - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto unmap; return 0; @@ -1254,11 +1264,14 @@ static int via_sd_suspend(struct pci_dev *pcidev, pm_message_t state) { struct via_crdr_mmc_host *host; + unsigned long flags; host = pci_get_drvdata(pcidev); + spin_lock_irqsave(&host->lock, flags); via_save_pcictrlreg(host); via_save_sdcreg(host); + spin_unlock_irqrestore(&host->lock, flags); pci_save_state(pcidev); pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0); --- linux-oracle-5.4.0.orig/drivers/mmc/host/vub300.c +++ linux-oracle-5.4.0/drivers/mmc/host/vub300.c @@ -576,7 +576,7 @@ GET_SYSTEM_PORT_STATUS, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, 0x0000, &vub300->system_port_status, - sizeof(vub300->system_port_status), HZ); + sizeof(vub300->system_port_status), 1000); if (sizeof(vub300->system_port_status) == retval) new_system_port_status(vub300); } @@ -1241,7 +1241,7 @@ SET_INTERRUPT_PSEUDOCODE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, 0x0000, - xfer_buffer, xfer_length, HZ); + xfer_buffer, xfer_length, 1000); kfree(xfer_buffer); if (retval < 0) goto copy_error_message; @@ -1284,7 +1284,7 @@ SET_TRANSFER_PSEUDOCODE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, 0x0000, - xfer_buffer, xfer_length, HZ); + xfer_buffer, xfer_length, 1000); kfree(xfer_buffer); if (retval < 0) goto copy_error_message; @@ -1715,6 +1715,9 @@ int bytes = 3 & less_cmd; int words = less_cmd >> 2; u8 *r = vub300->resp.response.command_response; + + if (!resp_len) + return; if (bytes == 3) { cmd->resp[words] = (r[1 + (words << 2)] << 24) | (r[2 + (words << 2)] << 16) @@ -1991,7 +1994,7 @@ usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_CLOCK_SPEED, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, 0x00, buf, buf_array_size, HZ); + 0x00, 0x00, buf, buf_array_size, 1000); if (retval != 8) { dev_err(&vub300->udev->dev, "SET_CLOCK_SPEED" " %dkHz failed with retval=%d\n", kHzClock, retval); @@ -2013,14 +2016,14 @@ usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_SD_POWER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, 0x0000, NULL, 0, HZ); + 0x0000, 0x0000, NULL, 0, 1000); /* must wait for the VUB300 u-proc to boot up */ msleep(600); } else if ((ios->power_mode == MMC_POWER_UP) && !vub300->card_powered) { usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_SD_POWER, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0001, 0x0000, NULL, 0, HZ); + 0x0001, 0x0000, NULL, 0, 1000); msleep(600); vub300->card_powered = 1; } else if (ios->power_mode == MMC_POWER_ON) { @@ -2049,6 +2052,7 @@ return; kref_get(&vub300->kref); if (enable) { + set_current_state(TASK_RUNNING); mutex_lock(&vub300->irq_mutex); if (vub300->irqs_queued) { vub300->irqs_queued -= 1; @@ -2064,6 +2068,7 @@ vub300_queue_poll_work(vub300, 0); } mutex_unlock(&vub300->irq_mutex); + set_current_state(TASK_INTERRUPTIBLE); } else { vub300->irq_enabled = 0; } @@ -2282,14 +2287,14 @@ GET_HC_INF0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, 0x0000, &vub300->hc_info, - sizeof(vub300->hc_info), HZ); + sizeof(vub300->hc_info), 1000); if (retval < 0) goto error5; retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), + usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_ROM_WAIT_STATES, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - firmware_rom_wait_states, 0x0000, NULL, 0, HZ); + firmware_rom_wait_states, 0x0000, NULL, 0, 1000); if (retval < 0) goto error5; dev_info(&vub300->udev->dev, @@ -2304,16 +2309,17 @@ GET_SYSTEM_PORT_STATUS, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0000, 0x0000, &vub300->system_port_status, - sizeof(vub300->system_port_status), HZ); + sizeof(vub300->system_port_status), 1000); if (retval < 0) { - goto error4; + goto error5; } else if (sizeof(vub300->system_port_status) == retval) { vub300->card_present = (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; vub300->read_only = (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; } else { - goto error4; + retval = -EINVAL; + goto error5; } usb_set_intfdata(interface, vub300); INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread); @@ -2336,8 +2342,13 @@ "USB vub300 remote SDIO host controller[%d]" "connected with no SD/SDIO card inserted\n", interface_to_InterfaceNumber(interface)); - mmc_add_host(mmc); + retval = mmc_add_host(mmc); + if (retval) + goto error6; + return 0; +error6: + del_timer_sync(&vub300->inactivity_timer); error5: mmc_free_host(mmc); /* --- linux-oracle-5.4.0.orig/drivers/mmc/host/wbsd.c +++ linux-oracle-5.4.0/drivers/mmc/host/wbsd.c @@ -1701,7 +1701,15 @@ */ wbsd_init_device(host); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) { + if (!pnp) + wbsd_chip_poweroff(host); + + wbsd_release_resources(host); + wbsd_free_mmc(dev); + return ret; + } pr_info("%s: W83L51xD", mmc_hostname(mmc)); if (host->chip_id != 0) --- linux-oracle-5.4.0.orig/drivers/mmc/host/wmt-sdmmc.c +++ linux-oracle-5.4.0/drivers/mmc/host/wmt-sdmmc.c @@ -849,7 +849,7 @@ if (IS_ERR(priv->clk_sdmmc)) { dev_err(&pdev->dev, "Error getting clock\n"); ret = PTR_ERR(priv->clk_sdmmc); - goto fail5; + goto fail5_and_a_half; } ret = clk_prepare_enable(priv->clk_sdmmc); @@ -859,13 +859,20 @@ /* configure the controller to a known 'ready' state */ wmt_reset_hardware(mmc); - mmc_add_host(mmc); + ret = mmc_add_host(mmc); + if (ret) + goto fail7; dev_info(&pdev->dev, "WMT SDHC Controller initialized\n"); return 0; +fail7: + clk_disable_unprepare(priv->clk_sdmmc); fail6: clk_put(priv->clk_sdmmc); +fail5_and_a_half: + dma_free_coherent(&pdev->dev, mmc->max_blk_count * 16, + priv->dma_desc_buffer, priv->dma_desc_device_addr); fail5: free_irq(dma_irq, priv); fail4: @@ -882,7 +889,6 @@ { struct mmc_host *mmc; struct wmt_mci_priv *priv; - struct resource *res; u32 reg_tmp; mmc = platform_get_drvdata(pdev); @@ -910,9 +916,6 @@ clk_disable_unprepare(priv->clk_sdmmc); clk_put(priv->clk_sdmmc); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - mmc_free_host(mmc); dev_info(&pdev->dev, "WMT MCI device removed\n"); --- linux-oracle-5.4.0.orig/drivers/mtd/chips/Kconfig +++ linux-oracle-5.4.0/drivers/mtd/chips/Kconfig @@ -55,12 +55,14 @@ LITTLE_ENDIAN_BYTE, if the bytes are reversed. config MTD_CFI_NOSWAP + depends on !ARCH_IXP4XX || CPU_BIG_ENDIAN bool "NO" config MTD_CFI_BE_BYTE_SWAP bool "BIG_ENDIAN_BYTE" config MTD_CFI_LE_BYTE_SWAP + depends on !ARCH_IXP4XX bool "LITTLE_ENDIAN_BYTE" endchoice --- linux-oracle-5.4.0.orig/drivers/mtd/chips/cfi_cmdset_0001.c +++ linux-oracle-5.4.0/drivers/mtd/chips/cfi_cmdset_0001.c @@ -420,8 +420,25 @@ extra_size = 0; /* Protection Register info */ - extra_size += (extp->NumProtectionFields - 1) * - sizeof(struct cfi_intelext_otpinfo); + if (extp->NumProtectionFields) { + struct cfi_intelext_otpinfo *otp = + (struct cfi_intelext_otpinfo *)&extp->extra[0]; + + extra_size += (extp->NumProtectionFields - 1) * + sizeof(struct cfi_intelext_otpinfo); + + if (extp_size >= sizeof(*extp) + extra_size) { + int i; + + /* Do some byteswapping if necessary */ + for (i = 0; i < extp->NumProtectionFields - 1; i++) { + otp->ProtRegAddr = le32_to_cpu(otp->ProtRegAddr); + otp->FactGroups = le16_to_cpu(otp->FactGroups); + otp->UserGroups = le16_to_cpu(otp->UserGroups); + otp++; + } + } + } } if (extp->MinorVersion >= '1') { @@ -695,14 +712,16 @@ */ if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3' && extp->FeatureSupport & (1 << 9)) { + int offs = 0; struct cfi_private *newcfi; struct flchip *chip; struct flchip_shared *shared; - int offs, numregions, numparts, partshift, numvirtchips, i, j; + int numregions, numparts, partshift, numvirtchips, i, j; /* Protection Register info */ - offs = (extp->NumProtectionFields - 1) * - sizeof(struct cfi_intelext_otpinfo); + if (extp->NumProtectionFields) + offs = (extp->NumProtectionFields - 1) * + sizeof(struct cfi_intelext_otpinfo); /* Burst Read info */ offs += extp->extra[offs+1]+2; --- linux-oracle-5.4.0.orig/drivers/mtd/chips/cfi_cmdset_0002.c +++ linux-oracle-5.4.0/drivers/mtd/chips/cfi_cmdset_0002.c @@ -59,6 +59,10 @@ #define CFI_SR_WBASB BIT(3) #define CFI_SR_SLSB BIT(1) +enum cfi_quirks { + CFI_QUIRK_DQ_TRUE_DATA = BIT(0), +}; + static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); #if !FORCE_WORD_WRITE @@ -119,23 +123,27 @@ struct cfi_pri_amdstd *extp = cfi->cmdset_priv; u8 poll_mask = CFI_POLL_STATUS_REG | CFI_POLL_DQ; - return extp->MinorVersion >= '5' && + return extp && extp->MinorVersion >= '5' && (extp->SoftwareFeatures & poll_mask) == CFI_POLL_STATUS_REG; } -static void cfi_check_err_status(struct map_info *map, struct flchip *chip, - unsigned long adr) +static int cfi_check_err_status(struct map_info *map, struct flchip *chip, + unsigned long adr) { struct cfi_private *cfi = map->fldrv_priv; map_word status; if (!cfi_use_status_reg(cfi)) - return; + return 0; cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); status = map_read(map, adr); + /* The error bits are invalid while the chip's busy */ + if (!map_word_bitsset(map, status, CMD(CFI_SR_DRB))) + return 0; + if (map_word_bitsset(map, status, CMD(0x3a))) { unsigned long chipstatus = MERGESTATUS(status); @@ -151,7 +159,12 @@ if (chipstatus & CFI_SR_SLSB) pr_err("%s sector write protected, status %lx\n", map->name, chipstatus); + + /* Erase/Program status bits are set on the operation failure */ + if (chipstatus & (CFI_SR_ESB | CFI_SR_PSB)) + return 1; } + return 0; } /* #define DEBUG_CFI_FEATURES */ @@ -423,6 +436,15 @@ mtd->name); } +static void fixup_quirks(struct mtd_info *mtd) +{ + struct map_info *map = mtd->priv; + struct cfi_private *cfi = map->fldrv_priv; + + if (cfi->mfr == CFI_MFR_AMD && cfi->id == 0x0c01) + cfi->quirks |= CFI_QUIRK_DQ_TRUE_DATA; +} + /* Used to fix CFI-Tables of chips without Extended Query Tables */ static struct cfi_fixup cfi_nopri_fixup_table[] = { { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ @@ -461,6 +483,7 @@ #if !FORCE_WORD_WRITE { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers }, #endif + { CFI_MFR_ANY, CFI_ID_ANY, fixup_quirks }, { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { @@ -785,26 +808,29 @@ kfree(mtd->eraseregions); kfree(mtd); kfree(cfi->cmdset_priv); - kfree(cfi->cfiq); return NULL; } /* - * Return true if the chip is ready. + * Return true if the chip is ready and has the correct value. * * Ready is one of: read mode, query mode, erase-suspend-read mode (in any * non-suspended sector) and is indicated by no toggle bits toggling. * + * Error are indicated by toggling bits or bits held with the wrong value, + * or with bits toggling. + * * Note that anything more complicated than checking if no bits are toggling * (including checking DQ5 for an error status) is tricky to get working * correctly and is therefore not done (particularly with interleaved chips * as each chip must be checked independently of the others). */ static int __xipram chip_ready(struct map_info *map, struct flchip *chip, - unsigned long addr) + unsigned long addr, map_word *expected) { struct cfi_private *cfi = map->fldrv_priv; map_word d, t; + int ret; if (cfi_use_status_reg(cfi)) { map_word ready = CMD(CFI_SR_DRB); @@ -814,61 +840,32 @@ */ cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); - d = map_read(map, addr); + t = map_read(map, addr); - return map_word_andequal(map, d, ready, ready); + return map_word_andequal(map, t, ready, ready); } d = map_read(map, addr); t = map_read(map, addr); - return map_word_equal(map, d, t); + ret = map_word_equal(map, d, t); + + if (!ret || !expected) + return ret; + + return map_word_equal(map, t, *expected); } -/* - * Return true if the chip is ready and has the correct value. - * - * Ready is one of: read mode, query mode, erase-suspend-read mode (in any - * non-suspended sector) and it is indicated by no bits toggling. - * - * Error are indicated by toggling bits or bits held with the wrong value, - * or with bits toggling. - * - * Note that anything more complicated than checking if no bits are toggling - * (including checking DQ5 for an error status) is tricky to get working - * correctly and is therefore not done (particularly with interleaved chips - * as each chip must be checked independently of the others). - * - */ static int __xipram chip_good(struct map_info *map, struct flchip *chip, - unsigned long addr, map_word expected) + unsigned long addr, map_word *expected) { struct cfi_private *cfi = map->fldrv_priv; - map_word oldd, curd; - - if (cfi_use_status_reg(cfi)) { - map_word ready = CMD(CFI_SR_DRB); - map_word err = CMD(CFI_SR_PSB | CFI_SR_ESB); - /* - * For chips that support status register, check device - * ready bit and Erase/Program status bit to know if - * operation succeeded. - */ - cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi, - cfi->device_type, NULL); - curd = map_read(map, addr); - - if (map_word_andequal(map, curd, ready, ready)) - return !map_word_bitsset(map, curd, err); - - return 0; - } + map_word *datum = expected; - oldd = map_read(map, addr); - curd = map_read(map, addr); + if (cfi->quirks & CFI_QUIRK_DQ_TRUE_DATA) + datum = NULL; - return map_word_equal(map, oldd, curd) && - map_word_equal(map, curd, expected); + return chip_ready(map, chip, addr, datum); } static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode) @@ -885,7 +882,7 @@ case FL_STATUS: for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break; if (time_after(jiffies, timeo)) { @@ -923,7 +920,7 @@ chip->state = FL_ERASE_SUSPENDING; chip->erase_suspended = 1; for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break; if (time_after(jiffies, timeo)) { @@ -1455,7 +1452,7 @@ /* wait for chip to become ready */ timeo = jiffies + msecs_to_jiffies(2); for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break; if (time_after(jiffies, timeo)) { @@ -1691,7 +1688,7 @@ * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_good(map, chip, adr, &datum)) { xip_enable(map, chip, adr); printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); xip_disable(map, chip, adr); @@ -1699,8 +1696,11 @@ break; } - if (chip_good(map, chip, adr, datum)) + if (chip_good(map, chip, adr, &datum)) { + if (cfi_check_err_status(map, chip, adr)) + ret = -EIO; break; + } /* Latency issues. Drop the lock, wait a while and retry */ UDELAY(map, chip, adr, 1); @@ -1773,7 +1773,6 @@ ret = do_write_oneword_once(map, chip, adr, datum, mode, cfi); if (ret) { /* reset on all failures. */ - cfi_check_err_status(map, chip, adr); map_write(map, CMD(0xF0), chip->start); /* FIXME - should have reset delay before continuing */ @@ -1969,13 +1968,18 @@ * "chip_good" to avoid the failure due to scheduling. */ if (time_after(jiffies, timeo) && - !chip_good(map, chip, adr, datum)) { + !chip_good(map, chip, adr, &datum)) { + pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", + __func__, adr); ret = -EIO; break; } - if (chip_good(map, chip, adr, datum)) + if (chip_good(map, chip, adr, &datum)) { + if (cfi_check_err_status(map, chip, adr)) + ret = -EIO; break; + } /* Latency issues. Drop the lock, wait a while and retry */ UDELAY(map, chip, adr, 1); @@ -2071,12 +2075,8 @@ chip->word_write_time); ret = do_write_buffer_wait(map, chip, adr, datum); - if (ret) { - cfi_check_err_status(map, chip, adr); + if (ret) do_write_buffer_reset(map, chip, cfi); - pr_err("MTD %s(): software timeout, address:0x%.8lx.\n", - __func__, adr); - } xip_enable(map, chip, adr); @@ -2184,7 +2184,7 @@ * If the driver thinks the chip is idle, and no toggle bits * are changing, then the chip is actually idle for sure. */ - if (chip->state == FL_READY && chip_ready(map, chip, adr)) + if (chip->state == FL_READY && chip_ready(map, chip, adr, NULL)) return 0; /* @@ -2201,7 +2201,7 @@ /* wait for the chip to become ready */ for (i = 0; i < jiffies_to_usecs(timeo); i++) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) return 0; udelay(1); @@ -2265,15 +2265,15 @@ map_write(map, datum, adr); for (i = 0; i < jiffies_to_usecs(uWriteTimeout); i++) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break; udelay(1); } - if (!chip_good(map, chip, adr, datum)) { + if (!chip_ready(map, chip, adr, &datum) || + cfi_check_err_status(map, chip, adr)) { /* reset on all failures. */ - cfi_check_err_status(map, chip, adr); map_write(map, CMD(0xF0), chip->start); /* FIXME - should have reset delay before continuing */ @@ -2413,6 +2413,7 @@ DECLARE_WAITQUEUE(wait, current); int ret = 0; int retry_cnt = 0; + map_word datum = map_word_ff(map); adr = cfi->addr_unlock1; @@ -2467,8 +2468,11 @@ chip->erase_suspended = 0; } - if (chip_good(map, chip, adr, map_word_ff(map))) + if (chip_ready(map, chip, adr, &datum)) { + if (cfi_check_err_status(map, chip, adr)) + ret = -EIO; break; + } if (time_after(jiffies, timeo)) { printk(KERN_WARNING "MTD %s(): software timeout\n", @@ -2483,7 +2487,6 @@ /* Did we succeed? */ if (ret) { /* reset on all failures. */ - cfi_check_err_status(map, chip, adr); map_write(map, CMD(0xF0), chip->start); /* FIXME - should have reset delay before continuing */ @@ -2510,6 +2513,7 @@ DECLARE_WAITQUEUE(wait, current); int ret = 0; int retry_cnt = 0; + map_word datum = map_word_ff(map); adr += chip->start; @@ -2564,8 +2568,11 @@ chip->erase_suspended = 0; } - if (chip_good(map, chip, adr, map_word_ff(map))) + if (chip_ready(map, chip, adr, &datum)) { + if (cfi_check_err_status(map, chip, adr)) + ret = -EIO; break; + } if (time_after(jiffies, timeo)) { printk(KERN_WARNING "MTD %s(): software timeout\n", @@ -2580,7 +2587,6 @@ /* Did we succeed? */ if (ret) { /* reset on all failures. */ - cfi_check_err_status(map, chip, adr); map_write(map, CMD(0xF0), chip->start); /* FIXME - should have reset delay before continuing */ @@ -2756,7 +2762,7 @@ */ timeo = jiffies + msecs_to_jiffies(2000); /* 2s max (un)locking */ for (;;) { - if (chip_ready(map, chip, adr)) + if (chip_ready(map, chip, adr, NULL)) break; if (time_after(jiffies, timeo)) { --- linux-oracle-5.4.0.orig/drivers/mtd/devices/docg3.c +++ linux-oracle-5.4.0/drivers/mtd/devices/docg3.c @@ -1975,9 +1975,14 @@ dev_err(dev, "No I/O memory resource defined\n"); return ret; } - base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); ret = -ENOMEM; + base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); + if (!base) { + dev_err(dev, "devm_ioremap dev failed\n"); + return ret; + } + cascade = devm_kcalloc(dev, DOC_MAX_NBFLOORS, sizeof(*cascade), GFP_KERNEL); if (!cascade) --- linux-oracle-5.4.0.orig/drivers/mtd/devices/mchp23k256.c +++ linux-oracle-5.4.0/drivers/mtd/devices/mchp23k256.c @@ -64,15 +64,17 @@ struct spi_transfer transfer[2] = {}; struct spi_message message; unsigned char command[MAX_CMD_SIZE]; - int ret; + int ret, cmd_len; spi_message_init(&message); + cmd_len = mchp23k256_cmdsz(flash); + command[0] = MCHP23K256_CMD_WRITE; mchp23k256_addr2cmd(flash, to, command); transfer[0].tx_buf = command; - transfer[0].len = mchp23k256_cmdsz(flash); + transfer[0].len = cmd_len; spi_message_add_tail(&transfer[0], &message); transfer[1].tx_buf = buf; @@ -88,8 +90,8 @@ if (ret) return ret; - if (retlen && message.actual_length > sizeof(command)) - *retlen += message.actual_length - sizeof(command); + if (retlen && message.actual_length > cmd_len) + *retlen += message.actual_length - cmd_len; return 0; } @@ -101,16 +103,18 @@ struct spi_transfer transfer[2] = {}; struct spi_message message; unsigned char command[MAX_CMD_SIZE]; - int ret; + int ret, cmd_len; spi_message_init(&message); + cmd_len = mchp23k256_cmdsz(flash); + memset(&transfer, 0, sizeof(transfer)); command[0] = MCHP23K256_CMD_READ; mchp23k256_addr2cmd(flash, from, command); transfer[0].tx_buf = command; - transfer[0].len = mchp23k256_cmdsz(flash); + transfer[0].len = cmd_len; spi_message_add_tail(&transfer[0], &message); transfer[1].rx_buf = buf; @@ -126,8 +130,8 @@ if (ret) return ret; - if (retlen && message.actual_length > sizeof(command)) - *retlen += message.actual_length - sizeof(command); + if (retlen && message.actual_length > cmd_len) + *retlen += message.actual_length - cmd_len; return 0; } --- linux-oracle-5.4.0.orig/drivers/mtd/devices/phram.c +++ linux-oracle-5.4.0/drivers/mtd/devices/phram.c @@ -243,22 +243,25 @@ ret = parse_num64(&start, token[1]); if (ret) { - kfree(name); parse_err("illegal start address\n"); + goto error; } ret = parse_num64(&len, token[2]); if (ret) { - kfree(name); parse_err("illegal device length\n"); + goto error; } ret = register_device(name, start, len); - if (!ret) - pr_info("%s device: %#llx at %#llx\n", name, len, start); - else - kfree(name); + if (ret) + goto error; + pr_info("%s device: %#llx at %#llx\n", name, len, start); + return 0; + +error: + kfree(name); return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/devices/powernv_flash.c +++ linux-oracle-5.4.0/drivers/mtd/devices/powernv_flash.c @@ -204,6 +204,9 @@ * get them */ mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node); + if (!mtd->name) + return -ENOMEM; + mtd->type = MTD_NORFLASH; mtd->flags = MTD_WRITEABLE; mtd->size = size; --- linux-oracle-5.4.0.orig/drivers/mtd/devices/slram.c +++ linux-oracle-5.4.0/drivers/mtd/devices/slram.c @@ -296,10 +296,12 @@ T("slram: devname = %s\n", devname); if ((!map) || (!(devstart = strsep(&map, ",")))) { E("slram: No devicestart specified.\n"); + break; } T("slram: devstart = %s\n", devstart); if ((!map) || (!(devlength = strsep(&map, ",")))) { E("slram: No devicelength / -end specified.\n"); + break; } T("slram: devlength = %s\n", devlength); if (parse_cmdline(devname, devstart, devlength) != 0) { --- linux-oracle-5.4.0.orig/drivers/mtd/devices/spear_smi.c +++ linux-oracle-5.4.0/drivers/mtd/devices/spear_smi.c @@ -592,6 +592,26 @@ return 0; } +/* + * The purpose of this function is to ensure a memcpy_toio() with byte writes + * only. Its structure is inspired from the ARM implementation of _memcpy_toio() + * which also does single byte writes but cannot be used here as this is just an + * implementation detail and not part of the API. Not mentioning the comment + * stating that _memcpy_toio() should be optimized. + */ +static void spear_smi_memcpy_toio_b(volatile void __iomem *dest, + const void *src, size_t len) +{ + const unsigned char *from = src; + + while (len) { + len--; + writeb(*from, dest); + from++; + dest++; + } +} + static inline int spear_smi_cpy_toio(struct spear_smi *dev, u32 bank, void __iomem *dest, const void *src, size_t len) { @@ -614,7 +634,23 @@ ctrlreg1 = readl(dev->io_base + SMI_CR1); writel((ctrlreg1 | WB_MODE) & ~SW_MODE, dev->io_base + SMI_CR1); - memcpy_toio(dest, src, len); + /* + * In Write Burst mode (WB_MODE), the specs states that writes must be: + * - incremental + * - of the same size + * The ARM implementation of memcpy_toio() will optimize the number of + * I/O by using as much 4-byte writes as possible, surrounded by + * 2-byte/1-byte access if: + * - the destination is not 4-byte aligned + * - the length is not a multiple of 4-byte. + * Avoid this alternance of write access size by using our own 'byte + * access' helper if at least one of the two conditions above is true. + */ + if (IS_ALIGNED(len, sizeof(u32)) && + IS_ALIGNED((uintptr_t)dest, sizeof(u32))) + memcpy_toio(dest, src, len); + else + spear_smi_memcpy_toio_b(dest, src, len); writel(ctrlreg1, dev->io_base + SMI_CR1); --- linux-oracle-5.4.0.orig/drivers/mtd/devices/st_spi_fsm.c +++ linux-oracle-5.4.0/drivers/mtd/devices/st_spi_fsm.c @@ -2116,10 +2116,12 @@ (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); - return mtd_device_register(&fsm->mtd, NULL, 0); - + ret = mtd_device_register(&fsm->mtd, NULL, 0); + if (ret) { err_clk_unprepare: - clk_disable_unprepare(fsm->clk); + clk_disable_unprepare(fsm->clk); + } + return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/lpddr/lpddr2_nvm.c +++ linux-oracle-5.4.0/drivers/mtd/lpddr/lpddr2_nvm.c @@ -393,6 +393,17 @@ return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_LOCK); } +static const struct mtd_info lpddr2_nvm_mtd_info = { + .type = MTD_RAM, + .writesize = 1, + .flags = (MTD_CAP_NVRAM | MTD_POWERUP_LOCK), + ._read = lpddr2_nvm_read, + ._write = lpddr2_nvm_write, + ._erase = lpddr2_nvm_erase, + ._unlock = lpddr2_nvm_unlock, + ._lock = lpddr2_nvm_lock, +}; + /* * lpddr2_nvm driver probe method */ @@ -422,6 +433,8 @@ /* lpddr2_nvm address range */ add_range = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!add_range) + return -ENODEV; /* Populate map_info data structure */ *map = (struct map_info) { @@ -433,6 +446,7 @@ .pfow_base = OW_BASE_ADDRESS, .fldrv_priv = pcm_data, }; + if (IS_ERR(map->virt)) return PTR_ERR(map->virt); @@ -444,22 +458,13 @@ return PTR_ERR(pcm_data->ctl_regs); /* Populate mtd_info data structure */ - *mtd = (struct mtd_info) { - .dev = { .parent = &pdev->dev }, - .name = pdev->dev.init_name, - .type = MTD_RAM, - .priv = map, - .size = resource_size(add_range), - .erasesize = ERASE_BLOCKSIZE * pcm_data->bus_width, - .writesize = 1, - .writebufsize = WRITE_BUFFSIZE * pcm_data->bus_width, - .flags = (MTD_CAP_NVRAM | MTD_POWERUP_LOCK), - ._read = lpddr2_nvm_read, - ._write = lpddr2_nvm_write, - ._erase = lpddr2_nvm_erase, - ._unlock = lpddr2_nvm_unlock, - ._lock = lpddr2_nvm_lock, - }; + *mtd = lpddr2_nvm_mtd_info; + mtd->dev.parent = &pdev->dev; + mtd->name = pdev->dev.init_name; + mtd->priv = map; + mtd->size = resource_size(add_range); + mtd->erasesize = ERASE_BLOCKSIZE * pcm_data->bus_width; + mtd->writebufsize = WRITE_BUFFSIZE * pcm_data->bus_width; /* Verify the presence of the device looking for PFOW string */ if (!lpddr2_nvm_pfow_present(map)) { --- linux-oracle-5.4.0.orig/drivers/mtd/lpddr/lpddr_cmds.c +++ linux-oracle-5.4.0/drivers/mtd/lpddr/lpddr_cmds.c @@ -68,7 +68,6 @@ shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), GFP_KERNEL); if (!shared) { - kfree(lpddr); kfree(mtd); return NULL; } --- linux-oracle-5.4.0.orig/drivers/mtd/maps/Kconfig +++ linux-oracle-5.4.0/drivers/mtd/maps/Kconfig @@ -303,7 +303,7 @@ config MTD_IXP4XX tristate "CFI Flash device mapped on Intel IXP4xx based systems" - depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX + depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX && MTD_CFI_ADV_OPTIONS help This enables MTD access to flash devices on platforms based on Intel's IXP4xx family of network processors such as the --- linux-oracle-5.4.0.orig/drivers/mtd/maps/physmap-core.c +++ linux-oracle-5.4.0/drivers/mtd/maps/physmap-core.c @@ -505,7 +505,7 @@ if (!info->maps[i].phys) info->maps[i].phys = res->start; - info->win_order = get_bitmask_order(resource_size(res)) - 1; + info->win_order = fls64(resource_size(res)) - 1; info->maps[i].size = BIT(info->win_order + (info->gpios ? info->gpios->ndescs : 0)); @@ -533,6 +533,17 @@ if (info->probe_type) { info->mtds[i] = do_map_probe(info->probe_type, &info->maps[i]); + + /* Fall back to mapping region as ROM */ + if (!info->mtds[i] && IS_ENABLED(CONFIG_MTD_ROM) && + strcmp(info->probe_type, "map_rom")) { + dev_warn(&dev->dev, + "map_probe() failed for type %s\n", + info->probe_type); + + info->mtds[i] = do_map_probe("map_rom", + &info->maps[i]); + } } else { int j; --- linux-oracle-5.4.0.orig/drivers/mtd/maps/physmap-versatile.c +++ linux-oracle-5.4.0/drivers/mtd/maps/physmap-versatile.c @@ -93,6 +93,7 @@ return -ENODEV; } ebi_base = of_iomap(ebi, 0); + of_node_put(ebi); if (!ebi_base) return -ENODEV; @@ -207,6 +208,7 @@ versatile_flashprot = (enum versatile_flashprot)devid->data; rmap = syscon_node_to_regmap(sysnp); + of_node_put(sysnp); if (IS_ERR(rmap)) return PTR_ERR(rmap); --- linux-oracle-5.4.0.orig/drivers/mtd/maps/pxa2xx-flash.c +++ linux-oracle-5.4.0/drivers/mtd/maps/pxa2xx-flash.c @@ -66,6 +66,7 @@ if (!info->map.virt) { printk(KERN_WARNING "Failed to ioremap %s\n", info->map.name); + kfree(info); return -ENOMEM; } info->map.cached = ioremap_cache(info->map.phys, info->map.size); @@ -87,6 +88,7 @@ iounmap((void *)info->map.virt); if (info->map.cached) iounmap(info->map.cached); + kfree(info); return -EIO; } info->mtd->dev.parent = &pdev->dev; --- linux-oracle-5.4.0.orig/drivers/mtd/mtd_blkdevs.c +++ linux-oracle-5.4.0/drivers/mtd/mtd_blkdevs.c @@ -533,7 +533,7 @@ { struct mtd_blktrans_ops *tr; - if (mtd->type == MTD_ABSENT) + if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) return; list_for_each_entry(tr, &blktrans_majors, list) @@ -576,7 +576,7 @@ list_add(&tr->list, &blktrans_majors); mtd_for_each_device(mtd) - if (mtd->type != MTD_ABSENT) + if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) tr->add_mtd(tr, mtd); mutex_unlock(&mtd_table_mutex); --- linux-oracle-5.4.0.orig/drivers/mtd/mtdblock.c +++ linux-oracle-5.4.0/drivers/mtd/mtdblock.c @@ -150,7 +150,7 @@ mtdblk->cache_state = STATE_EMPTY; ret = mtd_read(mtd, sect_start, sect_size, &retlen, mtdblk->cache_data); - if (ret) + if (ret && !mtd_is_bitflip(ret)) return ret; if (retlen != sect_size) return -EIO; @@ -185,8 +185,12 @@ pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", mtd->name, pos, len); - if (!sect_size) - return mtd_read(mtd, pos, len, &retlen, buf); + if (!sect_size) { + ret = mtd_read(mtd, pos, len, &retlen, buf); + if (ret && !mtd_is_bitflip(ret)) + return ret; + return 0; + } while (len > 0) { unsigned long sect_start = (pos/sect_size)*sect_size; @@ -206,7 +210,7 @@ memcpy (buf, mtdblk->cache_data + offset, size); } else { ret = mtd_read(mtd, pos, size, &retlen, buf); - if (ret) + if (ret && !mtd_is_bitflip(ret)) return ret; if (retlen != size) return -EIO; --- linux-oracle-5.4.0.orig/drivers/mtd/mtdchar.c +++ linux-oracle-5.4.0/drivers/mtd/mtdchar.c @@ -354,9 +354,6 @@ uint32_t retlen; int ret = 0; - if (!(file->f_mode & FMODE_WRITE)) - return -EPERM; - if (length > 4096) return -EINVAL; @@ -641,6 +638,48 @@ pr_debug("MTD_ioctl\n"); + /* + * Check the file mode to require "dangerous" commands to have write + * permissions. + */ + switch (cmd) { + /* "safe" commands */ + case MEMGETREGIONCOUNT: + case MEMGETREGIONINFO: + case MEMGETINFO: + case MEMREADOOB: + case MEMREADOOB64: + case MEMISLOCKED: + case MEMGETOOBSEL: + case MEMGETBADBLOCK: + case OTPSELECT: + case OTPGETREGIONCOUNT: + case OTPGETREGIONINFO: + case ECCGETLAYOUT: + case ECCGETSTATS: + case MTDFILEMODE: + case BLKPG: + case BLKRRPART: + break; + + /* "dangerous" commands */ + case MEMERASE: + case MEMERASE64: + case MEMLOCK: + case MEMUNLOCK: + case MEMSETBADBLOCK: + case MEMWRITEOOB: + case MEMWRITEOOB64: + case MEMWRITE: + case OTPLOCK: + if (!(file->f_mode & FMODE_WRITE)) + return -EPERM; + break; + + default: + return -ENOTTY; + } + switch (cmd) { case MEMGETREGIONCOUNT: if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) @@ -688,9 +727,6 @@ { struct erase_info *erase; - if(!(file->f_mode & FMODE_WRITE)) - return -EPERM; - erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL); if (!erase) ret = -ENOMEM; @@ -983,9 +1019,6 @@ ret = 0; break; } - - default: - ret = -ENOTTY; } return ret; @@ -1029,6 +1062,11 @@ struct mtd_oob_buf32 buf; struct mtd_oob_buf32 __user *buf_user = argp; + if (!(file->f_mode & FMODE_WRITE)) { + ret = -EPERM; + break; + } + if (copy_from_user(&buf, argp, sizeof(buf))) ret = -EFAULT; else --- linux-oracle-5.4.0.orig/drivers/mtd/mtdcore.c +++ linux-oracle-5.4.0/drivers/mtd/mtdcore.c @@ -563,7 +563,7 @@ config.id = -1; config.dev = &mtd->dev; - config.name = mtd->name; + config.name = dev_name(&mtd->dev); config.owner = THIS_MODULE; config.reg_read = mtd_nvmem_reg_read; config.size = mtd->size; @@ -673,8 +673,10 @@ dev_set_drvdata(&mtd->dev, mtd); of_node_get(mtd_get_of_node(mtd)); error = device_register(&mtd->dev); - if (error) + if (error) { + put_device(&mtd->dev); goto fail_added; + } /* Add the nvmem provider */ error = mtd_nvmem_add(mtd); @@ -727,8 +729,6 @@ mutex_lock(&mtd_table_mutex); - debugfs_remove_recursive(mtd->dbg.dfs_dir); - if (idr_find(&mtd_idr, mtd->index) != mtd) { ret = -ENODEV; goto out_error; @@ -744,6 +744,8 @@ mtd->index, mtd->name, mtd->usecount); ret = -EBUSY; } else { + debugfs_remove_recursive(mtd->dbg.dfs_dir); + /* Try to remove the NVMEM provider */ if (mtd->nvmem) nvmem_unregister(mtd->nvmem); @@ -825,6 +827,9 @@ /* Prefer parsed partitions over driver-provided fallback */ ret = parse_mtd_partitions(mtd, types, parser_data); + if (ret == -EPROBE_DEFER) + goto out; + if (ret > 0) ret = 0; else if (nr_parts) --- linux-oracle-5.4.0.orig/drivers/mtd/mtdoops.c +++ linux-oracle-5.4.0/drivers/mtd/mtdoops.c @@ -279,12 +279,13 @@ kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, record_size - MTDOOPS_HEADER_SIZE, NULL); - /* Panics must be written immediately */ - if (reason != KMSG_DUMP_OOPS) + if (reason != KMSG_DUMP_OOPS) { + /* Panics must be written immediately */ mtdoops_write(cxt, 1); - - /* For other cases, schedule work to write it "nicely" */ - schedule_work(&cxt->work_write); + } else { + /* For other cases, schedule work to write it "nicely" */ + schedule_work(&cxt->work_write); + } } static void mtdoops_notify_add(struct mtd_info *mtd) --- linux-oracle-5.4.0.orig/drivers/mtd/nand/bbt.c +++ linux-oracle-5.4.0/drivers/mtd/nand/bbt.c @@ -123,7 +123,7 @@ unsigned int rbits = bits_per_block + offs - BITS_PER_LONG; pos[1] &= ~GENMASK(rbits - 1, 0); - pos[1] |= val >> rbits; + pos[1] |= val >> (bits_per_block - rbits); } return 0; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/onenand/generic.c +++ linux-oracle-5.4.0/drivers/mtd/nand/onenand/generic.c @@ -53,7 +53,12 @@ } info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL; - info->onenand.irq = platform_get_irq(pdev, 0); + + err = platform_get_irq(pdev, 0); + if (err < 0) + goto out_iounmap; + + info->onenand.irq = err; info->mtd.dev.parent = &pdev->dev; info->mtd.priv = &info->onenand; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/onenand/omap2.c +++ linux-oracle-5.4.0/drivers/mtd/nand/onenand/omap2.c @@ -328,7 +328,8 @@ struct dma_async_tx_descriptor *tx; dma_cookie_t cookie; - tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0); + tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, + DMA_CTRL_ACK | DMA_PREP_INTERRUPT); if (!tx) { dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n"); return -EIO; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/onenand/onenand_base.c +++ linux-oracle-5.4.0/drivers/mtd/nand/onenand/onenand_base.c @@ -1248,44 +1248,44 @@ stats = mtd->ecc_stats; - /* Read-while-load method */ + /* Read-while-load method */ - /* Do first load to bufferRAM */ - if (read < len) { - if (!onenand_check_bufferram(mtd, from)) { + /* Do first load to bufferRAM */ + if (read < len) { + if (!onenand_check_bufferram(mtd, from)) { this->command(mtd, ONENAND_CMD_READ, from, writesize); - ret = this->wait(mtd, FL_READING); - onenand_update_bufferram(mtd, from, !ret); + ret = this->wait(mtd, FL_READING); + onenand_update_bufferram(mtd, from, !ret); if (mtd_is_eccerr(ret)) ret = 0; - } - } + } + } thislen = min_t(int, writesize, len - read); column = from & (writesize - 1); if (column + thislen > writesize) thislen = writesize - column; - while (!ret) { - /* If there is more to load then start next load */ - from += thislen; - if (read + thislen < len) { + while (!ret) { + /* If there is more to load then start next load */ + from += thislen; + if (read + thislen < len) { this->command(mtd, ONENAND_CMD_READ, from, writesize); - /* - * Chip boundary handling in DDP - * Now we issued chip 1 read and pointed chip 1 + /* + * Chip boundary handling in DDP + * Now we issued chip 1 read and pointed chip 1 * bufferram so we have to point chip 0 bufferram. - */ - if (ONENAND_IS_DDP(this) && - unlikely(from == (this->chipsize >> 1))) { - this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2); - boundary = 1; - } else - boundary = 0; - ONENAND_SET_PREV_BUFFERRAM(this); - } - /* While load is going, read from last bufferRAM */ - this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); + */ + if (ONENAND_IS_DDP(this) && + unlikely(from == (this->chipsize >> 1))) { + this->write_word(ONENAND_DDP_CHIP0, this->base + ONENAND_REG_START_ADDRESS2); + boundary = 1; + } else + boundary = 0; + ONENAND_SET_PREV_BUFFERRAM(this); + } + /* While load is going, read from last bufferRAM */ + this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen); /* Read oob area if needed */ if (oobbuf) { @@ -1301,24 +1301,24 @@ oobcolumn = 0; } - /* See if we are done */ - read += thislen; - if (read == len) - break; - /* Set up for next read from bufferRAM */ - if (unlikely(boundary)) - this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); - ONENAND_SET_NEXT_BUFFERRAM(this); - buf += thislen; + /* See if we are done */ + read += thislen; + if (read == len) + break; + /* Set up for next read from bufferRAM */ + if (unlikely(boundary)) + this->write_word(ONENAND_DDP_CHIP1, this->base + ONENAND_REG_START_ADDRESS2); + ONENAND_SET_NEXT_BUFFERRAM(this); + buf += thislen; thislen = min_t(int, writesize, len - read); - column = 0; - cond_resched(); - /* Now wait for load */ - ret = this->wait(mtd, FL_READING); - onenand_update_bufferram(mtd, from, !ret); + column = 0; + cond_resched(); + /* Now wait for load */ + ret = this->wait(mtd, FL_READING); + onenand_update_bufferram(mtd, from, !ret); if (mtd_is_eccerr(ret)) ret = 0; - } + } /* * Return success, if no ECC failures, else -EBADMSG @@ -2921,6 +2921,7 @@ ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); + *retlen = ops.retlen; /* Exit OTP access mode */ this->command(mtd, ONENAND_CMD_RESET, 0, 0); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/atmel/nand-controller.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -402,6 +402,7 @@ dma_async_issue_pending(nc->dmac); wait_for_completion(&finished); + dma_unmap_single(nc->dev, buf_dma, len, dir); return 0; @@ -813,10 +814,12 @@ NULL, 0, chip->ecc.strength); - if (ret >= 0) + if (ret >= 0) { + mtd->ecc_stats.corrected += ret; max_bitflips = max(ret, max_bitflips); - else + } else { mtd->ecc_stats.failed++; + } databuf += chip->ecc.size; eccbuf += chip->ecc.bytes; @@ -2002,13 +2005,15 @@ nc->mck = of_clk_get(dev->parent->of_node, 0); if (IS_ERR(nc->mck)) { dev_err(dev, "Failed to retrieve MCK clk\n"); - return PTR_ERR(nc->mck); + ret = PTR_ERR(nc->mck); + goto out_release_dma; } np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0); if (!np) { dev_err(dev, "Missing or invalid atmel,smc property\n"); - return -EINVAL; + ret = -EINVAL; + goto out_release_dma; } nc->smc = syscon_node_to_regmap(np); @@ -2016,10 +2021,16 @@ if (IS_ERR(nc->smc)) { ret = PTR_ERR(nc->smc); dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret); - return ret; + goto out_release_dma; } return 0; + +out_release_dma: + if (nc->dmac) + dma_release_channel(nc->dmac); + + return ret; } static int --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/atmel/pmecc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/atmel/pmecc.c @@ -362,7 +362,7 @@ size = ALIGN(size, sizeof(s32)); size += (req->ecc.strength + 1) * sizeof(s32) * 3; - user = kzalloc(size, GFP_KERNEL); + user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL); if (!user) return ERR_PTR(-ENOMEM); @@ -380,10 +380,8 @@ user->delta = user->dmu + req->ecc.strength + 1; gf_tables = atmel_pmecc_get_gf_tables(req); - if (IS_ERR(gf_tables)) { - kfree(user); + if (IS_ERR(gf_tables)) return ERR_CAST(gf_tables); - } user->gf_tables = gf_tables; @@ -408,12 +406,6 @@ } EXPORT_SYMBOL_GPL(atmel_pmecc_create_user); -void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user) -{ - kfree(user); -} -EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user); - static int get_strength(struct atmel_pmecc_user *user) { const int *strengths = user->pmecc->caps->strengths; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/atmel/pmecc.h +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/atmel/pmecc.h @@ -55,8 +55,6 @@ struct atmel_pmecc_user * atmel_pmecc_create_user(struct atmel_pmecc *pmecc, struct atmel_pmecc_user_req *req); -void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user); - void atmel_pmecc_reset(struct atmel_pmecc *pmecc); int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op); void atmel_pmecc_disable(struct atmel_pmecc_user *user); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -197,6 +197,7 @@ unsigned int max_page_size; const unsigned int *page_sizes; unsigned int max_oob; + u32 ecc_level_shift; u32 features; /* for low-power standby/resume only */ @@ -487,6 +488,34 @@ INTFC_CTLR_READY = BIT(31), }; +/*********************************************************************** + * NAND ACC CONTROL bitfield + * + * Some bits have remained constant throughout hardware revision, while + * others have shifted around. + ***********************************************************************/ + +/* Constant for all versions (where supported) */ +enum { + /* See BRCMNAND_HAS_CACHE_MODE */ + ACC_CONTROL_CACHE_MODE = BIT(22), + + /* See BRCMNAND_HAS_PREFETCH */ + ACC_CONTROL_PREFETCH = BIT(23), + + ACC_CONTROL_PAGE_HIT = BIT(24), + ACC_CONTROL_WR_PREEMPT = BIT(25), + ACC_CONTROL_PARTIAL_PAGE = BIT(26), + ACC_CONTROL_RD_ERASED = BIT(27), + ACC_CONTROL_FAST_PGM_RDIN = BIT(28), + ACC_CONTROL_WR_ECC = BIT(30), + ACC_CONTROL_RD_ECC = BIT(31), +}; + +#define ACC_CONTROL_ECC_SHIFT 16 +/* Only for v7.2 */ +#define ACC_CONTROL_ECC_EXT_SHIFT 13 + static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs) { return brcmnand_readl(ctrl->nand_base + offs); @@ -537,8 +566,9 @@ } else { ctrl->cs_offsets = brcmnand_cs_offsets; - /* v5.0 and earlier has a different CS0 offset layout */ - if (ctrl->nand_version <= 0x0500) + /* v3.3-5.0 have a different CS0 offset layout */ + if (ctrl->nand_version >= 0x0303 && + ctrl->nand_version <= 0x0500) ctrl->cs0_offsets = brcmnand_cs_offsets_cs0; } @@ -589,6 +619,12 @@ else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) ctrl->features |= BRCMNAND_HAS_WP; + /* v7.2 has different ecc level shift in the acc register */ + if (ctrl->nand_version == 0x0702) + ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; + else + ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; + return 0; } @@ -751,30 +787,6 @@ return 0; } -/*********************************************************************** - * NAND ACC CONTROL bitfield - * - * Some bits have remained constant throughout hardware revision, while - * others have shifted around. - ***********************************************************************/ - -/* Constant for all versions (where supported) */ -enum { - /* See BRCMNAND_HAS_CACHE_MODE */ - ACC_CONTROL_CACHE_MODE = BIT(22), - - /* See BRCMNAND_HAS_PREFETCH */ - ACC_CONTROL_PREFETCH = BIT(23), - - ACC_CONTROL_PAGE_HIT = BIT(24), - ACC_CONTROL_WR_PREEMPT = BIT(25), - ACC_CONTROL_PARTIAL_PAGE = BIT(26), - ACC_CONTROL_RD_ERASED = BIT(27), - ACC_CONTROL_FAST_PGM_RDIN = BIT(28), - ACC_CONTROL_WR_ECC = BIT(30), - ACC_CONTROL_RD_ECC = BIT(31), -}; - static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) { if (ctrl->nand_version == 0x0702) @@ -785,18 +797,15 @@ return GENMASK(5, 0); } -#define NAND_ACC_CONTROL_ECC_SHIFT 16 -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 - static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) { u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; - mask <<= NAND_ACC_CONTROL_ECC_SHIFT; + mask <<= ACC_CONTROL_ECC_SHIFT; /* v7.2 includes additional ECC levels */ - if (ctrl->nand_version >= 0x0702) - mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; + if (ctrl->nand_version == 0x0702) + mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT; return mask; } @@ -810,8 +819,8 @@ if (en) { acc_control |= ecc_flags; /* enable RD/WR ECC */ - acc_control |= host->hwcfg.ecc_level - << NAND_ACC_CONTROL_ECC_SHIFT; + acc_control &= ~brcmnand_ecc_level_mask(ctrl); + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; } else { acc_control &= ~ecc_flags; /* disable RD/WR ECC */ acc_control &= ~brcmnand_ecc_level_mask(ctrl); @@ -890,6 +899,14 @@ cpu_relax(); } while (time_after(limit, jiffies)); + /* + * do a final check after time out in case the CPU was busy and the driver + * did not get enough time to perform the polling to avoid false alarms + */ + val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); + if ((val & mask) == expected_val) + return 0; + dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n", expected_val, val & mask); @@ -1019,11 +1036,14 @@ if (!section) { /* * Small-page NAND use byte 6 for BBI while large-page - * NAND use byte 0. + * NAND use bytes 0 and 1. */ - if (cfg->page_size > 512) - oobregion->offset++; - oobregion->length--; + if (cfg->page_size > 512) { + oobregion->offset += 2; + oobregion->length -= 2; + } else { + oobregion->length--; + } } } @@ -1269,19 +1289,33 @@ const u8 *oob, int sas, int sector_1k) { int tbytes = sas << sector_1k; - int j; + int j, k = 0; + u32 last = 0xffffffff; + u8 *plast = (u8 *)&last; /* Adjust OOB values for 1K sector size */ if (sector_1k && (i & 0x01)) tbytes = max(0, tbytes - (int)ctrl->max_oob); tbytes = min_t(int, tbytes, ctrl->max_oob); - for (j = 0; j < tbytes; j += 4) + /* + * tbytes may not be multiple of words. Make sure we don't read out of + * the boundary and stop at last word. + */ + for (j = 0; (j + 3) < tbytes; j += 4) oob_reg_write(ctrl, j, (oob[j + 0] << 24) | (oob[j + 1] << 16) | (oob[j + 2] << 8) | (oob[j + 3] << 0)); + + /* handle the remaing bytes */ + while (j < tbytes) + plast[k++] = oob[j++]; + + if (tbytes & 0x3) + oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); + return tbytes; } @@ -1327,7 +1361,17 @@ dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); - BUG_ON(ctrl->cmd_pending != 0); + /* + * If we came here through _panic_write and there is a pending + * command, try to wait for it. If it times out, rather than + * hitting BUG_ON, just return so we don't crash while crashing. + */ + if (oops_in_progress) { + if (ctrl->cmd_pending && + bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0)) + return; + } else + BUG_ON(ctrl->cmd_pending != 0); ctrl->cmd_pending = cmd; ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); @@ -1752,7 +1796,7 @@ mtd->oobsize / trans, host->hwcfg.sector_size_1k); - if (!ret) { + if (ret != -EBADMSG) { *err_addr = brcmnand_get_uncorrecc_addr(ctrl); if (*err_addr) @@ -1787,28 +1831,31 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, struct nand_chip *chip, void *buf, u64 addr) { - int i, sas; - void *oob = chip->oob_poi; + struct mtd_oob_region ecc; + int i; int bitflips = 0; int page = addr >> chip->page_shift; int ret; + void *ecc_bytes; void *ecc_chunk; if (!buf) buf = nand_get_data_buf(chip); - sas = mtd->oobsize / chip->ecc.steps; - /* read without ecc for verification */ ret = chip->ecc.read_page_raw(chip, buf, true, page); if (ret) return ret; - for (i = 0; i < chip->ecc.steps; i++, oob += sas) { + for (i = 0; i < chip->ecc.steps; i++) { ecc_chunk = buf + chip->ecc.size * i; - ret = nand_check_erased_ecc_chunk(ecc_chunk, - chip->ecc.size, - oob, sas, NULL, 0, + + mtd_ooblayout_ecc(mtd, i, &ecc); + ecc_bytes = chip->oob_poi + ecc.offset; + + ret = nand_check_erased_ecc_chunk(ecc_chunk, chip->ecc.size, + ecc_bytes, ecc.length, + NULL, 0, chip->ecc.strength); if (ret < 0) return ret; @@ -2154,7 +2201,7 @@ tmp = nand_readreg(ctrl, acc_control_offs); tmp &= ~brcmnand_ecc_level_mask(ctrl); - tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; + tmp |= cfg->ecc_level << ctrl->ecc_level_shift; tmp &= ~brcmnand_spare_area_mask(ctrl); tmp |= cfg->spare_area_size; nand_writereg(ctrl, acc_control_offs, tmp); @@ -2357,6 +2404,12 @@ ret = brcmstb_choose_ecc_layout(host); + /* If OOB is written with ECC enabled it will cause ECC errors */ + if (is_hamming_ecc(host->ctrl, &host->hwcfg)) { + chip->ecc.write_oob = brcmnand_write_oob_raw; + chip->ecc.read_oob = brcmnand_read_oob_raw; + } + return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/cafe_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/cafe_nand.c @@ -757,7 +757,7 @@ "CAFE NAND", mtd); if (err) { dev_warn(&pdev->dev, "Could not register IRQ %d\n", pdev->irq); - goto out_ior; + goto out_free_rs; } /* Disable master reset, enable NAND clock */ @@ -801,6 +801,8 @@ /* Disable NAND IRQ in global IRQ mask register */ cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); free_irq(pdev->irq, mtd); + out_free_rs: + free_rs(cafe->rs); out_ior: pci_iounmap(pdev, cafe->mmio); out_free_mtd: --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/diskonchip.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/diskonchip.c @@ -53,7 +53,7 @@ 0xe8000, 0xea000, 0xec000, 0xee000, #endif #endif - 0xffffffff }; +}; static struct mtd_info *doclist = NULL; @@ -1221,7 +1221,7 @@ (i == 0) && (ip->firstUnit > 0)) { parts[0].name = " DiskOnChip IPL / Media Header partition"; parts[0].offset = 0; - parts[0].size = mtd->erasesize * ip->firstUnit; + parts[0].size = (uint64_t)mtd->erasesize * ip->firstUnit; numparts = 1; } @@ -1609,13 +1609,10 @@ numchips = doc2001_init(mtd); if ((ret = nand_scan(nand, numchips)) || (ret = doc->late_init(mtd))) { - /* DBB note: i believe nand_release is necessary here, as + /* DBB note: i believe nand_cleanup is necessary here, as buffers may have been allocated in nand_base. Check with Thomas. FIX ME! */ - /* nand_release will call mtd_device_unregister, but we - haven't yet added it. This is handled without incident by - mtd_device_unregister, as far as I can tell. */ - nand_release(nand); + nand_cleanup(nand); goto fail; } @@ -1669,7 +1666,7 @@ if (ret < 0) return ret; } else { - for (i = 0; (doc_locations[i] != 0xffffffff); i++) { + for (i = 0; i < ARRAY_SIZE(doc_locations); i++) { doc_probe(doc_locations[i]); } } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/fsl_ifc_nand.c @@ -21,7 +21,7 @@ #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ -#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait +#define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait for IFC NAND Machine */ struct fsl_ifc_ctrl; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/fsl_upm.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/fsl_upm.c @@ -62,7 +62,6 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun) { if (fun->rnb_gpio[fun->mchip_number] >= 0) { - struct mtd_info *mtd = nand_to_mtd(&fun->chip); int cnt = 1000000; while (--cnt && !fun_chip_ready(&fun->chip)) --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/fsmc_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/fsmc_nand.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -93,6 +94,14 @@ #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) +/* + * According to SPEAr300 Reference Manual (RM0082) + * TOUDEL = 7ns (Output delay from the flip-flops to the board) + * TINDEL = 5ns (Input delay from the board to the flipflop) + */ +#define TOUTDEL 7000 +#define TINDEL 5000 + struct fsmc_nand_timings { u8 tclr; u8 tar; @@ -277,7 +286,7 @@ { unsigned long hclk = clk_get_rate(host->clk); unsigned long hclkn = NSEC_PER_SEC / hclk; - u32 thiz, thold, twait, tset; + u32 thiz, thold, twait, tset, twait_min; if (sdrt->tRC_min < 30000) return -EOPNOTSUPP; @@ -309,13 +318,6 @@ else if (tims->thold > FSMC_THOLD_MASK) tims->thold = FSMC_THOLD_MASK; - twait = max(sdrt->tRP_min, sdrt->tWP_min); - tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1; - if (tims->twait == 0) - tims->twait = 1; - else if (tims->twait > FSMC_TWAIT_MASK) - tims->twait = FSMC_TWAIT_MASK; - tset = max(sdrt->tCS_min - sdrt->tWP_min, sdrt->tCEA_max - sdrt->tREA_max); tims->tset = DIV_ROUND_UP(tset / 1000, hclkn) - 1; @@ -324,6 +326,21 @@ else if (tims->tset > FSMC_TSET_MASK) tims->tset = FSMC_TSET_MASK; + /* + * According to SPEAr300 Reference Manual (RM0082) which gives more + * information related to FSMSC timings than the SPEAr600 one (RM0305), + * twait >= tCEA - (tset * TCLK) + TOUTDEL + TINDEL + */ + twait_min = sdrt->tCEA_max - ((tims->tset + 1) * hclkn * 1000) + + TOUTDEL + TINDEL; + twait = max3(sdrt->tRP_min, sdrt->tWP_min, twait_min); + + tims->twait = DIV_ROUND_UP(twait / 1000, hclkn) - 1; + if (tims->twait == 0) + tims->twait = 1; + else if (tims->twait > FSMC_TWAIT_MASK) + tims->twait = FSMC_TWAIT_MASK; + return 0; } @@ -650,6 +667,9 @@ instr->ctx.waitrdy.timeout_ms); break; } + + if (instr->delay_ns) + ndelay(instr->delay_ns); } return ret; @@ -1066,11 +1086,13 @@ host->read_dma_chan = dma_request_channel(mask, filter, NULL); if (!host->read_dma_chan) { dev_err(&pdev->dev, "Unable to get read dma channel\n"); + ret = -ENODEV; goto disable_clk; } host->write_dma_chan = dma_request_channel(mask, filter, NULL); if (!host->write_dma_chan) { dev_err(&pdev->dev, "Unable to get write dma channel\n"); + ret = -ENODEV; goto release_dma_read_chan; } } @@ -1159,9 +1181,14 @@ static int fsmc_nand_resume(struct device *dev) { struct fsmc_nand_data *host = dev_get_drvdata(dev); + int ret; if (host) { - clk_prepare_enable(host->clk); + ret = clk_prepare_enable(host->clk); + if (ret) { + dev_err(dev, "failed to enable clk\n"); + return ret; + } if (host->dev_timings) fsmc_nand_setup(host, host->dev_timings); nand_reset(&host->nand, 0); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -148,6 +148,12 @@ struct resources *r = &this->resources; int ret; + ret = pm_runtime_get_sync(this->dev); + if (ret < 0) { + pm_runtime_put_noidle(this->dev); + return ret; + } + ret = gpmi_reset_block(r->gpmi_regs, false); if (ret) goto err_out; @@ -179,8 +185,9 @@ */ writel(BM_GPMI_CTRL1_DECOUPLE_CS, r->gpmi_regs + HW_GPMI_CTRL1_SET); - return 0; err_out: + pm_runtime_mark_last_busy(this->dev); + pm_runtime_put_autosuspend(this->dev); return ret; } @@ -535,8 +542,10 @@ return ret; ret = pm_runtime_get_sync(this->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(this->dev); return ret; + } /* * Due to erratum #2847 of the MX23, the BCH cannot be soft reset on this @@ -636,14 +645,16 @@ const struct nand_sdr_timings *sdr) { struct gpmi_nfc_hardware_timing *hw = &this->hw; + struct resources *r = &this->resources; unsigned int dll_threshold_ps = this->devdata->max_chain_delay; unsigned int period_ps, reference_period_ps; unsigned int data_setup_cycles, data_hold_cycles, addr_setup_cycles; unsigned int tRP_ps; bool use_half_period; int sample_delay_ps, sample_delay_factor; - u16 busy_timeout_cycles; + unsigned int busy_timeout_cycles; u8 wrn_dly_sel; + u64 busy_timeout_ps; if (sdr->tRC_min >= 30000) { /* ONFI non-EDO modes [0-3] */ @@ -659,18 +670,21 @@ wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY; } + hw->clk_rate = clk_round_rate(r->clock[0], hw->clk_rate); + /* SDR core timings are given in picoseconds */ period_ps = div_u64((u64)NSEC_PER_SEC * 1000, hw->clk_rate); addr_setup_cycles = TO_CYCLES(sdr->tALS_min, period_ps); data_setup_cycles = TO_CYCLES(sdr->tDS_min, period_ps); data_hold_cycles = TO_CYCLES(sdr->tDH_min, period_ps); - busy_timeout_cycles = TO_CYCLES(sdr->tWB_max + sdr->tR_max, period_ps); + busy_timeout_ps = max(sdr->tBERS_max, sdr->tPROG_max); + busy_timeout_cycles = TO_CYCLES(busy_timeout_ps, period_ps); hw->timing0 = BF_GPMI_TIMING0_ADDRESS_SETUP(addr_setup_cycles) | BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles) | BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles); - hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(busy_timeout_cycles * 4096); + hw->timing1 = BF_GPMI_TIMING1_BUSY_TIMEOUT(DIV_ROUND_UP(busy_timeout_cycles, 4096)); /* * Derive NFC ideal delay from {3}: @@ -701,14 +715,32 @@ (use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0); } -static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this) +static int gpmi_nfc_apply_timings(struct gpmi_nand_data *this) { struct gpmi_nfc_hardware_timing *hw = &this->hw; struct resources *r = &this->resources; void __iomem *gpmi_regs = r->gpmi_regs; unsigned int dll_wait_time_us; + int ret; + + /* Clock dividers do NOT guarantee a clean clock signal on its output + * during the change of the divide factor on i.MX6Q/UL/SX. On i.MX7/8, + * all clock dividers provide these guarantee. + */ + if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this)) + clk_disable_unprepare(r->clock[0]); + + ret = clk_set_rate(r->clock[0], hw->clk_rate); + if (ret) { + dev_err(this->dev, "cannot set clock rate to %lu Hz: %d\n", hw->clk_rate, ret); + return ret; + } - clk_set_rate(r->clock[0], hw->clk_rate); + if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this)) { + ret = clk_prepare_enable(r->clock[0]); + if (ret) + return ret; + } writel(hw->timing0, gpmi_regs + HW_GPMI_TIMING0); writel(hw->timing1, gpmi_regs + HW_GPMI_TIMING1); @@ -727,6 +759,8 @@ /* Wait for the DLL to settle. */ udelay(dll_wait_time_us); + + return 0; } static int gpmi_setup_data_interface(struct nand_chip *chip, int chipnr, @@ -1175,15 +1209,6 @@ r->clock[i] = clk; } - if (GPMI_IS_MX6(this)) - /* - * Set the default value for the gpmi clock. - * - * If you want to use the ONFI nand which is in the - * Synchronous Mode, you should change the clock as you need. - */ - clk_set_rate(r->clock[0], 22000000); - return 0; err_clock: @@ -2399,7 +2424,7 @@ void *buf_read = NULL; const void *buf_write = NULL; bool direct = false; - struct completion *completion; + struct completion *dma_completion, *bch_completion; unsigned long to; this->ntransfers = 0; @@ -2407,8 +2432,10 @@ this->transfers[i].direction = DMA_NONE; ret = pm_runtime_get_sync(this->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(this->dev); return ret; + } /* * This driver currently supports only one NAND chip. Plus, dies share @@ -2418,7 +2445,9 @@ */ if (this->hw.must_apply_timings) { this->hw.must_apply_timings = false; - gpmi_nfc_apply_timings(this); + ret = gpmi_nfc_apply_timings(this); + if (ret) + goto out_pm; } dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs); @@ -2491,22 +2520,24 @@ this->resources.bch_regs + HW_BCH_FLASH0LAYOUT1); } + desc->callback = dma_irq_callback; + desc->callback_param = this; + dma_completion = &this->dma_done; + bch_completion = NULL; + + init_completion(dma_completion); + if (this->bch && buf_read) { writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, this->resources.bch_regs + HW_BCH_CTRL_SET); - completion = &this->bch_done; - } else { - desc->callback = dma_irq_callback; - desc->callback_param = this; - completion = &this->dma_done; + bch_completion = &this->bch_done; + init_completion(bch_completion); } - init_completion(completion); - dmaengine_submit(desc); dma_async_issue_pending(get_dma_chan(this)); - to = wait_for_completion_timeout(completion, msecs_to_jiffies(1000)); + to = wait_for_completion_timeout(dma_completion, msecs_to_jiffies(1000)); if (!to) { dev_err(this->dev, "DMA timeout, last DMA\n"); gpmi_dump_info(this); @@ -2514,6 +2545,16 @@ goto unmap; } + if (this->bch && buf_read) { + to = wait_for_completion_timeout(bch_completion, msecs_to_jiffies(1000)); + if (!to) { + dev_err(this->dev, "BCH timeout, last DMA\n"); + gpmi_dump_info(this); + ret = -ETIMEDOUT; + goto unmap; + } + } + writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, this->resources.bch_regs + HW_BCH_CTRL_CLR); gpmi_clear_bch(this); @@ -2535,6 +2576,7 @@ this->bch = false; +out_pm: pm_runtime_mark_last_busy(this->dev); pm_runtime_put_autosuspend(this->dev); @@ -2575,7 +2617,7 @@ this->bch_geometry.auxiliary_size = 128; ret = gpmi_alloc_dma_buffer(this); if (ret) - goto err_out; + return ret; nand_controller_init(&this->base); this->base.ops = &gpmi_nand_controller_ops; @@ -2722,6 +2764,10 @@ return ret; } + /* Set flag to get timing setup restored for next exec_op */ + if (this->hw.clk_rate) + this->hw.must_apply_timings = true; + /* re-init the BCH registers */ ret = bch_set_geometry(this); if (ret) { --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h @@ -36,25 +36,25 @@ void ingenic_ecc_release(struct ingenic_ecc *ecc); struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np); #else /* CONFIG_MTD_NAND_INGENIC_ECC */ -int ingenic_ecc_calculate(struct ingenic_ecc *ecc, +static inline int ingenic_ecc_calculate(struct ingenic_ecc *ecc, struct ingenic_ecc_params *params, const u8 *buf, u8 *ecc_code) { return -ENODEV; } -int ingenic_ecc_correct(struct ingenic_ecc *ecc, +static inline int ingenic_ecc_correct(struct ingenic_ecc *ecc, struct ingenic_ecc_params *params, u8 *buf, u8 *ecc_code) { return -ENODEV; } -void ingenic_ecc_release(struct ingenic_ecc *ecc) +static inline void ingenic_ecc_release(struct ingenic_ecc *ecc) { } -struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np) +static inline struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np) { return ERR_PTR(-ENODEV); } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c @@ -376,7 +376,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) { - nand_release(chip); + nand_cleanup(chip); return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/lpc32xx_mlc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/lpc32xx_mlc.c @@ -304,8 +304,9 @@ return 0; } -static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host) +static irqreturn_t lpc3xxx_nand_irq(int irq, void *data) { + struct lpc32xx_nand_host *host = data; uint8_t sr; /* Clear interrupt flag by reading status */ @@ -778,7 +779,7 @@ goto release_dma_chan; } - if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq, + if (request_irq(host->irq, &lpc3xxx_nand_irq, IRQF_TRIGGER_HIGH, DRV_NAME, host)) { dev_err(&pdev->dev, "Error requesting NAND IRQ\n"); res = -ENXIO; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/marvell_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/marvell_nand.c @@ -707,7 +707,7 @@ * In case the interrupt was not served in the required time frame, * check if the ISR was not served or if something went actually wrong. */ - if (ret && !pending) { + if (!ret && !pending) { dev_err(nfc->dev, "Timeout waiting for RB signal\n"); return -ETIMEDOUT; } @@ -1109,6 +1109,7 @@ .ndcb[2] = NDCB2_ADDR5_PAGE(page), }; unsigned int oob_bytes = lt->spare_bytes + (raw ? lt->ecc_bytes : 0); + u8 status; int ret; /* NFCv2 needs more information about the operation being executed */ @@ -1142,7 +1143,18 @@ ret = marvell_nfc_wait_op(chip, PSEC_TO_MSEC(chip->data_interface.timings.sdr.tPROG_max)); - return ret; + if (ret) + return ret; + + /* Check write status on the chip side */ + ret = nand_status_op(chip, &status); + if (ret) + return ret; + + if (status & NAND_STATUS_FAIL) + return -EIO; + + return 0; } static int marvell_nfc_hw_ecc_hmg_write_page_raw(struct nand_chip *chip, @@ -1570,6 +1582,7 @@ int data_len = lt->data_bytes; int spare_len = lt->spare_bytes; int chunk, ret; + u8 status; marvell_nfc_select_target(chip, chip->cur_cs); @@ -1607,6 +1620,14 @@ if (ret) return ret; + /* Check write status on the chip side */ + ret = nand_status_op(chip, &status); + if (ret) + return ret; + + if (status & NAND_STATUS_FAIL) + return -EIO; + return 0; } @@ -2401,6 +2422,12 @@ NDTR1_WAIT_MODE; } + /* + * Reset nfc->selected_chip so the next command will cause the timing + * registers to be updated in marvell_nfc_select_target(). + */ + nfc->selected_chip = NULL; + return 0; } @@ -2630,7 +2657,7 @@ chip->controller = &nfc->controller; nand_set_flash_node(chip, np); - if (!of_property_read_bool(np, "marvell,nand-keep-config")) + if (of_property_read_bool(np, "marvell,nand-keep-config")) chip->options |= NAND_KEEP_TIMINGS; mtd = nand_to_mtd(chip); @@ -2664,7 +2691,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "failed to register mtd device: %d\n", ret); - nand_release(chip); + nand_cleanup(chip); return ret; } @@ -2673,6 +2700,16 @@ return 0; } +static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc) +{ + struct marvell_nand_chip *entry, *temp; + + list_for_each_entry_safe(entry, temp, &nfc->chips, node) { + nand_release(&entry->chip); + list_del(&entry->node); + } +} + static int marvell_nand_chips_init(struct device *dev, struct marvell_nfc *nfc) { struct device_node *np = dev->of_node; @@ -2707,21 +2744,16 @@ ret = marvell_nand_chip_init(dev, nfc, nand_np); if (ret) { of_node_put(nand_np); - return ret; + goto cleanup_chips; } } return 0; -} -static void marvell_nand_chips_cleanup(struct marvell_nfc *nfc) -{ - struct marvell_nand_chip *entry, *temp; +cleanup_chips: + marvell_nand_chips_cleanup(nfc); - list_for_each_entry_safe(entry, temp, &nfc->chips, node) { - nand_release(&entry->chip); - list_del(&entry->node); - } + return ret; } static int marvell_nfc_init_dma(struct marvell_nfc *nfc) @@ -2823,10 +2855,6 @@ regmap_update_bits(sysctrl_base, GENCONF_CLK_GATING_CTRL, GENCONF_CLK_GATING_CTRL_ND_GATE, GENCONF_CLK_GATING_CTRL_ND_GATE); - - regmap_update_bits(sysctrl_base, GENCONF_ND_CLK_CTRL, - GENCONF_ND_CLK_CTRL_EN, - GENCONF_ND_CLK_CTRL_EN); } /* Configure the DMA if appropriate */ @@ -2975,8 +3003,10 @@ return ret; ret = clk_prepare_enable(nfc->reg_clk); - if (ret < 0) + if (ret < 0) { + clk_disable_unprepare(nfc->core_clk); return ret; + } /* * Reset nfc->selected_chip so the next command will cause the timing --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/meson_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/meson_nand.c @@ -59,7 +59,7 @@ #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \ ( \ (cmd_dir) | \ - ((ran) << 19) | \ + (ran) | \ ((bch) << 14) | \ ((short_mode) << 13) | \ (((page_size) & 0x7f) << 6) | \ @@ -72,6 +72,7 @@ #define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff)) #define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N) +#define DMA_ADDR_ALIGN 8 #define ECC_CHECK_RETURN_FF (-1) @@ -172,6 +173,7 @@ dma_addr_t daddr; dma_addr_t iaddr; + u32 info_bytes; unsigned long assigned_cs; }; @@ -275,7 +277,7 @@ if (raw) { len = mtd->writesize + mtd->oobsize; - cmd = (len & GENMASK(5, 0)) | scrambler | DMA_DIR(dir); + cmd = (len & GENMASK(13, 0)) | scrambler | DMA_DIR(dir); writel(cmd, nfc->reg_base + NFC_REG_CMD); return; } @@ -454,7 +456,7 @@ if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) { mtd->ecc_stats.corrected += ECC_ERR_CNT(*info); *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info)); - *correct_bitmap |= 1 >> i; + *correct_bitmap |= BIT_ULL(i); continue; } if ((nand->options & NAND_NEED_SCRAMBLING) && @@ -499,6 +501,7 @@ nfc->daddr, datalen, dir); return ret; } + nfc->info_bytes = infolen; cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr); writel(cmd, nfc->reg_base + NFC_REG_CMD); @@ -510,14 +513,16 @@ } static void meson_nfc_dma_buffer_release(struct nand_chip *nand, - int infolen, int datalen, + int datalen, int infolen, enum dma_data_direction dir) { struct meson_nfc *nfc = nand_get_controller_data(nand); dma_unmap_single(nfc->dev, nfc->daddr, datalen, dir); - if (infolen) + if (infolen) { dma_unmap_single(nfc->dev, nfc->iaddr, infolen, dir); + nfc->info_bytes = 0; + } } static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) @@ -536,7 +541,7 @@ if (ret) goto out; - cmd = NFC_CMD_N2M | (len & GENMASK(5, 0)); + cmd = NFC_CMD_N2M | (len & GENMASK(13, 0)); writel(cmd, nfc->reg_base + NFC_REG_CMD); meson_nfc_drain_cmd(nfc); @@ -560,7 +565,7 @@ if (ret) return ret; - cmd = NFC_CMD_M2N | (len & GENMASK(5, 0)); + cmd = NFC_CMD_M2N | (len & GENMASK(13, 0)); writel(cmd, nfc->reg_base + NFC_REG_CMD); meson_nfc_drain_cmd(nfc); @@ -706,6 +711,8 @@ usleep_range(10, 15); /* info is updated by nfc dma engine*/ smp_rmb(); + dma_sync_single_for_cpu(nfc->dev, nfc->iaddr, nfc->info_bytes, + DMA_FROM_DEVICE); ret = *info & ECC_COMPLETE; } while (!ret); } @@ -800,7 +807,7 @@ u8 *data = buf + i * ecc->size; u8 *oob = nand->oob_poi + i * (ecc->bytes + 2); - if (correct_bitmap & (1 << i)) + if (correct_bitmap & BIT_ULL(i)) continue; ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, ecc->bytes + 2, @@ -832,6 +839,9 @@ static bool meson_nfc_is_buffer_dma_safe(const void *buffer) { + if ((uintptr_t)buffer % DMA_ADDR_ALIGN) + return false; + if (virt_addr_valid(buffer) && (!object_is_on_stack(buffer))) return true; return false; @@ -1041,9 +1051,12 @@ ret = clk_set_rate(nfc->device_clk, 24000000); if (ret) - goto err_phase_rx; + goto err_disable_rx; return 0; + +err_disable_rx: + clk_disable_unprepare(nfc->phase_rx); err_phase_rx: clk_disable_unprepare(nfc->phase_tx); err_phase_tx: @@ -1164,7 +1177,6 @@ struct meson_nfc *nfc = nand_get_controller_data(nand); struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand); struct mtd_info *mtd = nand_to_mtd(nand); - int nsectors = mtd->writesize / 1024; int ret; if (!mtd->name) { @@ -1182,7 +1194,7 @@ nand->options |= NAND_NO_SUBPAGE_WRITE; ret = nand_ecc_choose_conf(nand, nfc->data->ecc_caps, - mtd->oobsize - 2 * nsectors); + mtd->oobsize - 2); if (ret) { dev_err(nfc->dev, "failed to ECC init\n"); return -EINVAL; @@ -1301,7 +1313,6 @@ if (ret) return ret; - meson_nfc_free_buffer(&meson_chip->nand); nand_cleanup(&meson_chip->nand); list_del(&meson_chip->node); } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/mpc5121_nfc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/mpc5121_nfc.c @@ -290,7 +290,6 @@ /* Control chips select signal on ADS5121 board */ static void ads5121_select_chip(struct nand_chip *nand, int chip) { - struct mtd_info *mtd = nand_to_mtd(nand); struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); u8 v; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/mtk_ecc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/mtk_ecc.c @@ -43,6 +43,7 @@ struct mtk_ecc_caps { u32 err_mask; + u32 err_shift; const u8 *ecc_strength; const u32 *ecc_regs; u8 num_ecc_strength; @@ -76,7 +77,7 @@ }; static const u8 ecc_strength_mt7622[] = { - 4, 6, 8, 10, 12, 14, 16 + 4, 6, 8, 10, 12 }; enum mtk_ecc_regs { @@ -221,7 +222,7 @@ for (i = 0; i < sectors; i++) { offset = (i >> 2) << 2; err = readl(ecc->regs + ECC_DECENUM0 + offset); - err = err >> ((i % 4) * 8); + err = err >> ((i % 4) * ecc->caps->err_shift); err &= ecc->caps->err_mask; if (err == ecc->caps->err_mask) { /* uncorrectable errors */ @@ -449,6 +450,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { .err_mask = 0x3f, + .err_shift = 8, .ecc_strength = ecc_strength_mt2701, .ecc_regs = mt2701_ecc_regs, .num_ecc_strength = 20, @@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { .err_mask = 0x7f, + .err_shift = 8, .ecc_strength = ecc_strength_mt2712, .ecc_regs = mt2712_ecc_regs, .num_ecc_strength = 23, @@ -468,10 +471,11 @@ }; static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = { - .err_mask = 0x3f, + .err_mask = 0x1f, + .err_shift = 5, .ecc_strength = ecc_strength_mt7622, .ecc_regs = mt7622_ecc_regs, - .num_ecc_strength = 7, + .num_ecc_strength = 5, .ecc_mode_shift = 4, .parity_bits = 13, .pg_irq_sel = 0, --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/mtk_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/mtk_nand.c @@ -1419,7 +1419,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "mtd parse partition error\n"); - nand_release(nand); + nand_cleanup(nand); return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_base.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_base.c @@ -292,12 +292,16 @@ struct mtd_info *mtd = nand_to_mtd(chip); int last_page = ((mtd->erasesize - mtd->writesize) >> chip->page_shift) & chip->pagemask; + unsigned int bbm_flags = NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE + | NAND_BBM_LASTPAGE; + if (page == 0 && !(chip->options & bbm_flags)) + return 0; if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE) return 0; - else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) + if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) return 1; - else if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) + if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) return last_page; return -EINVAL; @@ -355,16 +359,19 @@ * * Return: -EBUSY if the chip has been suspended, 0 otherwise */ -static int nand_get_device(struct nand_chip *chip) +static void nand_get_device(struct nand_chip *chip) { - mutex_lock(&chip->lock); - if (chip->suspended) { + /* Wait until the device is resumed. */ + while (1) { + mutex_lock(&chip->lock); + if (!chip->suspended) { + mutex_lock(&chip->controller->lock); + return; + } mutex_unlock(&chip->lock); - return -EBUSY; - } - mutex_lock(&chip->controller->lock); - return 0; + wait_event(chip->resume_wq, !chip->suspended); + } } /** @@ -589,9 +596,7 @@ nand_erase_nand(chip, &einfo, 0); /* Write bad block marker to OOB */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); ret = nand_markbad_bbm(chip, ofs); nand_release_device(chip); @@ -727,8 +732,14 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, unsigned long timeout_ms) { - /* Wait until R/B pin indicates chip is ready or timeout occurs */ - timeout_ms = jiffies + msecs_to_jiffies(timeout_ms); + + /* + * Wait until R/B pin indicates chip is ready or timeout occurs. + * +1 below is necessary because if we are now in the last fraction + * of jiffy and msecs_to_jiffies is 1 then we will wait only that + * small jiffy fraction - possibly leading to false timeout. + */ + timeout_ms = jiffies + msecs_to_jiffies(timeout_ms) + 1; do { if (gpiod_get_value_cansleep(gpiod)) return 0; @@ -3566,9 +3577,7 @@ ops->mode != MTD_OPS_RAW) return -ENOTSUPP; - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); if (!ops->datbuf) ret = nand_do_read_oob(chip, from, ops); @@ -4112,13 +4121,11 @@ struct mtd_oob_ops *ops) { struct nand_chip *chip = mtd_to_nand(mtd); - int ret; + int ret = 0; ops->retlen = 0; - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -4174,9 +4181,7 @@ return -EINVAL; /* Grab the lock and see if the device is available */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); /* Shift to get first page */ page = (int)(instr->addr >> chip->page_shift); @@ -4263,7 +4268,7 @@ pr_debug("%s: called\n", __func__); /* Grab the lock and see if the device is available */ - WARN_ON(nand_get_device(chip)); + nand_get_device(chip); /* Release it and go back */ nand_release_device(chip); } @@ -4280,9 +4285,7 @@ int ret; /* Select the NAND device */ - ret = nand_get_device(chip); - if (ret) - return ret; + nand_get_device(chip); nand_select_target(chip, chipnr); @@ -4344,6 +4347,8 @@ pr_err("%s called for a chip which is not in suspended state\n", __func__); mutex_unlock(&chip->lock); + + wake_up_all(&chip->resume_wq); } /** @@ -5004,6 +5009,7 @@ chip->cur_cs = -1; mutex_init(&chip->lock); + init_waitqueue_head(&chip->resume_wq); /* Enforce the right timings for reset/detection */ onfi_fill_data_interface(chip, NAND_SDR_IFACE, 0); @@ -5903,6 +5909,8 @@ chip->ecc.algo == NAND_ECC_BCH) nand_bch_free((struct nand_bch_control *)chip->ecc.priv); + nanddev_cleanup(&chip->base); + /* Free bad block table memory */ kfree(chip->bbt); kfree(chip->data_buf); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_ecc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_ecc.c @@ -131,7 +131,7 @@ /* rp0..rp15..rp17 are the various accumulated parities (per byte) */ uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7; uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16; - uint32_t uninitialized_var(rp17); /* to make compiler happy */ + uint32_t rp17; uint32_t par; /* the cumulative parity for all data */ uint32_t tmppar; /* the cumulative parity for this iteration; for rp12, rp14 and rp16 at the end of the --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_hynix.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_hynix.c @@ -402,7 +402,7 @@ if (ret) pr_warn("failed to initialize read-retry infrastructure"); - return 0; + return ret; } static void hynix_nand_extract_oobsize(struct nand_chip *chip, --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_micron.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_micron.c @@ -446,8 +446,10 @@ if (ret) goto err_free_manuf_data; + chip->options |= NAND_BBM_FIRSTPAGE; + if (mtd->writesize == 2048) - chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; ondie = micron_supports_on_die_ecc(chip); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_onfi.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_onfi.c @@ -173,7 +173,7 @@ } if (onfi_crc16(ONFI_CRC_BASE, (u8 *)&p[i], 254) == - le16_to_cpu(p->crc)) { + le16_to_cpu(p[i].crc)) { if (i) memcpy(p, &p[i], sizeof(*p)); break; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/nand_timings.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/nand_timings.c @@ -314,10 +314,9 @@ /* microseconds -> picoseconds */ timings->tPROG_max = 1000000ULL * ONFI_DYN_TIMING_MAX; timings->tBERS_max = 1000000ULL * ONFI_DYN_TIMING_MAX; - timings->tR_max = 1000000ULL * 200000000ULL; - /* nanoseconds -> picoseconds */ - timings->tCCS_min = 1000UL * 500000; + timings->tR_max = 200000000; + timings->tCCS_min = 500000; } return 0; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/omap_elm.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/omap_elm.c @@ -174,17 +174,17 @@ switch (info->bch_type) { case BCH8_ECC: /* syndrome fragment 0 = ecc[9-12B] */ - val = cpu_to_be32(*(u32 *) &ecc[9]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[9]); elm_write_reg(info, offset, val); /* syndrome fragment 1 = ecc[5-8B] */ offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[5]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[5]); elm_write_reg(info, offset, val); /* syndrome fragment 2 = ecc[1-4B] */ offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[1]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[1]); elm_write_reg(info, offset, val); /* syndrome fragment 3 = ecc[0B] */ @@ -194,35 +194,35 @@ break; case BCH4_ECC: /* syndrome fragment 0 = ecc[20-52b] bits */ - val = (cpu_to_be32(*(u32 *) &ecc[3]) >> 4) | + val = ((__force u32)cpu_to_be32(*(u32 *)&ecc[3]) >> 4) | ((ecc[2] & 0xf) << 28); elm_write_reg(info, offset, val); /* syndrome fragment 1 = ecc[0-20b] bits */ offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12; + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 12; elm_write_reg(info, offset, val); break; case BCH16_ECC: - val = cpu_to_be32(*(u32 *) &ecc[22]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[22]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[18]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[18]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[14]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[14]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[10]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[10]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[6]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[6]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[2]); + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[2]); elm_write_reg(info, offset, val); offset += 4; - val = cpu_to_be32(*(u32 *) &ecc[0]) >> 16; + val = (__force u32)cpu_to_be32(*(u32 *)&ecc[0]) >> 16; elm_write_reg(info, offset, val); break; default: @@ -411,6 +411,7 @@ pm_runtime_enable(&pdev->dev); if (pm_runtime_get_sync(&pdev->dev) < 0) { ret = -EINVAL; + pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); dev_err(&pdev->dev, "can't enable clock\n"); return ret; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/orion_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/orion_nand.c @@ -180,7 +180,7 @@ mtd->name = "orion_nand"; ret = mtd_device_register(mtd, board->parts, board->nr_parts); if (ret) { - nand_release(nc); + nand_cleanup(nc); goto no_dev; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/oxnas_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/oxnas_nand.c @@ -32,6 +32,7 @@ void __iomem *io_base; struct clk *clk; struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS]; + unsigned int nchips; }; static uint8_t oxnas_nand_read_byte(struct nand_chip *chip) @@ -79,9 +80,9 @@ struct nand_chip *chip; struct mtd_info *mtd; struct resource *res; - int nchips = 0; int count = 0; int err = 0; + int i; /* Allocate memory for the device structure (and zero it) */ oxnas = devm_kzalloc(&pdev->dev, sizeof(*oxnas), @@ -140,17 +141,15 @@ goto err_release_child; err = mtd_device_register(mtd, NULL, 0); - if (err) { - nand_release(chip); - goto err_release_child; - } + if (err) + goto err_cleanup_nand; - oxnas->chips[nchips] = chip; - ++nchips; + oxnas->chips[oxnas->nchips] = chip; + ++oxnas->nchips; } /* Exit if no chips found */ - if (!nchips) { + if (!oxnas->nchips) { err = -ENODEV; goto err_clk_unprepare; } @@ -159,8 +158,17 @@ return 0; +err_cleanup_nand: + nand_cleanup(chip); err_release_child: of_node_put(nand_np); + + for (i = 0; i < oxnas->nchips; i++) { + chip = oxnas->chips[i]; + WARN_ON(mtd_device_unregister(nand_to_mtd(chip))); + nand_cleanup(chip); + } + err_clk_unprepare: clk_disable_unprepare(oxnas->clk); return err; @@ -169,9 +177,13 @@ static int oxnas_nand_remove(struct platform_device *pdev) { struct oxnas_nand_ctrl *oxnas = platform_get_drvdata(pdev); + struct nand_chip *chip; + int i; - if (oxnas->chips[0]) - nand_release(oxnas->chips[0]); + for (i = 0; i < oxnas->nchips; i++) { + chip = oxnas->chips[i]; + nand_release(chip); + } clk_disable_unprepare(oxnas->clk); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/pasemi_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/pasemi_nand.c @@ -146,7 +146,7 @@ if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { dev_err(dev, "Unable to register MTD device\n"); err = -ENODEV; - goto out_lpc; + goto out_cleanup_nand; } dev_info(dev, "PA Semi NAND flash at %pR, control at I/O %x\n", &res, @@ -154,6 +154,8 @@ return 0; + out_cleanup_nand: + nand_cleanup(chip); out_lpc: release_region(lpcctl, 4); out_ior: --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/plat_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/plat_nand.c @@ -92,7 +92,7 @@ if (!err) return err; - nand_release(&data->chip); + nand_cleanup(&data->chip); out: if (pdata->ctrl.remove) pdata->ctrl.remove(pdev); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/qcom_nandc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/qcom_nandc.c @@ -2,7 +2,6 @@ /* * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ - #include #include #include @@ -459,11 +458,13 @@ * among different NAND controllers. * @ecc_modes - ecc mode for NAND * @is_bam - whether NAND controller is using BAM + * @is_qpic - whether NAND CTRL is part of qpic IP * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset */ struct qcom_nandc_props { u32 ecc_modes; bool is_bam; + bool is_qpic; u32 dev_cmd_reg_start; }; @@ -1568,6 +1569,8 @@ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); int i; + nandc_read_buffer_sync(nandc, true); + for (i = 0; i < cw_cnt; i++) { u32 flash = le32_to_cpu(nandc->reg_read_buf[i]); @@ -2751,7 +2754,8 @@ u32 nand_ctrl; /* kill onenand */ - nandc_write(nandc, SFLASHC_BURST_CFG, 0); + if (!nandc->props->is_qpic) + nandc_write(nandc, SFLASHC_BURST_CFG, 0); nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD), NAND_DEV_CMD_VLD_VAL); @@ -2845,7 +2849,7 @@ struct device *dev = nandc->dev; struct device_node *dn = dev->of_node, *child; struct qcom_nand_host *host; - int ret; + int ret = -ENODEV; for_each_available_child_of_node(dn, child) { host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); @@ -2863,10 +2867,7 @@ list_add_tail(&host->node, &nandc->host_list); } - if (list_empty(&nandc->host_list)) - return -ENODEV; - - return 0; + return ret; } /* parse custom DT properties here */ @@ -2942,10 +2943,6 @@ if (!nandc->base_dma) return -ENXIO; - ret = qcom_nandc_alloc(nandc); - if (ret) - goto err_nandc_alloc; - ret = clk_prepare_enable(nandc->core_clk); if (ret) goto err_core_clk; @@ -2954,6 +2951,10 @@ if (ret) goto err_aon_clk; + ret = qcom_nandc_alloc(nandc); + if (ret) + goto err_nandc_alloc; + ret = qcom_nandc_setup(nandc); if (ret) goto err_setup; @@ -2965,15 +2966,14 @@ return 0; err_setup: + qcom_nandc_unalloc(nandc); +err_nandc_alloc: clk_disable_unprepare(nandc->aon_clk); err_aon_clk: clk_disable_unprepare(nandc->core_clk); err_core_clk: - qcom_nandc_unalloc(nandc); -err_nandc_alloc: - dma_unmap_resource(dev, res->start, resource_size(res), + dma_unmap_resource(dev, nandc->base_dma, resource_size(res), DMA_BIDIRECTIONAL, 0); - return ret; } @@ -3007,12 +3007,14 @@ static const struct qcom_nandc_props ipq4019_nandc_props = { .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), .is_bam = true, + .is_qpic = true, .dev_cmd_reg_start = 0x0, }; static const struct qcom_nandc_props ipq8074_nandc_props = { .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT), .is_bam = true, + .is_qpic = true, .dev_cmd_reg_start = 0x7000, }; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/s3c2410.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/s3c2410.c @@ -291,7 +291,7 @@ int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; int tacls, twrph0, twrph1; unsigned long clkrate = clk_get_rate(info->clk); - unsigned long uninitialized_var(set), cfg, uninitialized_var(mask); + unsigned long set, cfg, mask; unsigned long flags; /* calculate the timing information for the controller */ --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/sh_flctl.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/sh_flctl.c @@ -384,7 +384,8 @@ dma_addr_t dma_addr; dma_cookie_t cookie; uint32_t reg; - int ret; + int ret = 0; + unsigned long time_left; if (dir == DMA_FROM_DEVICE) { chan = flctl->chan_fifo0_rx; @@ -425,13 +426,14 @@ goto out; } - ret = + time_left = wait_for_completion_timeout(&flctl->dma_complete, msecs_to_jiffies(3000)); - if (ret <= 0) { + if (time_left == 0) { dmaengine_terminate_all(chan); dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); + ret = -ETIMEDOUT; } out: @@ -441,7 +443,7 @@ dma_unmap_single(chan->device->dev, dma_addr, len, dir); - /* ret > 0 is success */ + /* ret == 0 is success */ return ret; } @@ -465,7 +467,7 @@ /* initiate DMA transfer */ if (flctl->chan_fifo0_rx && rlen >= 32 && - flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE) > 0) + !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE)) goto convert; /* DMA success */ /* do polling transfer */ @@ -524,7 +526,7 @@ /* initiate DMA transfer */ if (flctl->chan_fifo0_tx && rlen >= 32 && - flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE) > 0) + !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE)) return; /* DMA success */ /* do polling transfer */ --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/sharpsl.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/sharpsl.c @@ -183,7 +183,7 @@ return 0; err_add: - nand_release(this); + nand_cleanup(this); err_scan: iounmap(sharpsl->io); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/socrates_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/socrates_nand.c @@ -169,7 +169,7 @@ if (!res) return res; - nand_release(nand_chip); + nand_cleanup(nand_chip); out: iounmap(host->io_base); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -37,6 +37,7 @@ /* Max ECC buffer length */ #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG) +#define FMC2_TIMEOUT_US 1000 #define FMC2_TIMEOUT_MS 1000 /* Timings */ @@ -53,6 +54,8 @@ #define FMC2_PMEM 0x88 #define FMC2_PATT 0x8c #define FMC2_HECCR 0x94 +#define FMC2_ISR 0x184 +#define FMC2_ICR 0x188 #define FMC2_CSQCR 0x200 #define FMC2_CSQCFGR1 0x204 #define FMC2_CSQCFGR2 0x208 @@ -118,6 +121,12 @@ #define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) #define FMC2_PATT_DEFAULT 0x0a0a0a0a +/* Register: FMC2_ISR */ +#define FMC2_ISR_IHLF BIT(1) + +/* Register: FMC2_ICR */ +#define FMC2_ICR_CIHLF BIT(1) + /* Register: FMC2_CSQCR */ #define FMC2_CSQCR_CSQSTART BIT(0) @@ -1322,6 +1331,31 @@ stm32_fmc2_set_buswidth_16(fmc2, true); } +static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) +{ + struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + const struct nand_sdr_timings *timings; + u32 isr, sr; + + /* Check if there is no pending requests to the NAND flash */ + if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr, + sr & FMC2_SR_NWRF, 1, + FMC2_TIMEOUT_US)) + dev_warn(fmc2->dev, "Waitrdy timeout\n"); + + /* Wait tWB before R/B# signal is low */ + timings = nand_get_sdr_timings(&chip->data_interface); + ndelay(PSEC_TO_NSEC(timings->tWB_max)); + + /* R/B# signal is low, clear high level flag */ + writel_relaxed(FMC2_ICR_CIHLF, fmc2->io_base + FMC2_ICR); + + /* Wait R/B# signal is high */ + return readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_ISR, + isr, isr & FMC2_ISR_IHLF, + 5, 1000 * timeout_ms); +} + static int stm32_fmc2_exec_op(struct nand_chip *chip, const struct nand_operation *op, bool check_only) @@ -1366,8 +1400,8 @@ break; case NAND_OP_WAITRDY_INSTR: - ret = nand_soft_waitrdy(chip, - instr->ctx.waitrdy.timeout_ms); + ret = stm32_fmc2_waitrdy(chip, + instr->ctx.waitrdy.timeout_ms); break; } } @@ -1558,6 +1592,9 @@ if (IS_ERR(sdrt)) return PTR_ERR(sdrt); + if (sdrt->tRC_min < 30000) + return -EOPNOTSUPP; + if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) return 0; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/sunxi_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/sunxi_nand.c @@ -1587,7 +1587,7 @@ if (section < ecc->steps) oobregion->length = 4; else - oobregion->offset = mtd->oobsize - oobregion->offset; + oobregion->length = mtd->oobsize - oobregion->offset; return 0; } @@ -2003,7 +2003,7 @@ ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(dev, "failed to register mtd device: %d\n", ret); - nand_release(nand); + nand_cleanup(nand); return ret; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/tmio_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/tmio_nand.c @@ -448,7 +448,7 @@ if (!retval) return retval; - nand_release(nand_chip); + nand_cleanup(nand_chip); err_irq: tmio_hw_stop(dev, tmio); --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/vf610_nfc.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/vf610_nfc.c @@ -850,8 +850,10 @@ } of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev); - if (!of_id) - return -ENODEV; + if (!of_id) { + err = -ENODEV; + goto err_disable_clk; + } nfc->variant = (enum vf610_nfc_variant)of_id->data; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/raw/xway_nand.c +++ linux-oracle-5.4.0/drivers/mtd/nand/raw/xway_nand.c @@ -210,7 +210,7 @@ err = mtd_device_register(mtd, NULL, 0); if (err) - nand_release(&data->chip); + nand_cleanup(&data->chip); return err; } --- linux-oracle-5.4.0.orig/drivers/mtd/nand/spi/core.c +++ linux-oracle-5.4.0/drivers/mtd/nand/spi/core.c @@ -568,18 +568,18 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos) { struct spinand_device *spinand = nand_to_spinand(nand); + u8 marker[2] = { }; struct nand_page_io_req req = { .pos = *pos, - .ooblen = 2, + .ooblen = sizeof(marker), .ooboffs = 0, - .oobbuf.in = spinand->oobbuf, + .oobbuf.in = marker, .mode = MTD_OPS_RAW, }; - memset(spinand->oobbuf, 0, 2); spinand_select_target(spinand, pos->target); spinand_read_page(spinand, &req, false); - if (spinand->oobbuf[0] != 0xff || spinand->oobbuf[1] != 0xff) + if (marker[0] != 0xff || marker[1] != 0xff) return true; return false; @@ -603,15 +603,16 @@ static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos) { struct spinand_device *spinand = nand_to_spinand(nand); + u8 marker[2] = { }; struct nand_page_io_req req = { .pos = *pos, .ooboffs = 0, - .ooblen = 2, - .oobbuf.out = spinand->oobbuf, + .ooblen = sizeof(marker), + .oobbuf.out = marker, + .mode = MTD_OPS_RAW, }; int ret; - /* Erase block before marking it bad. */ ret = spinand_select_target(spinand, pos->target); if (ret) return ret; @@ -620,9 +621,6 @@ if (ret) return ret; - spinand_erase_op(spinand, pos); - - memset(spinand->oobbuf, 0, 2); return spinand_write_page(spinand, &req); } @@ -1051,6 +1049,10 @@ mtd->oobavail = ret; + /* Propagate ECC information to mtd_info */ + mtd->ecc_strength = nand->eccreq.strength; + mtd->ecc_step_size = nand->eccreq.step_size; + return 0; err_cleanup_nanddev: @@ -1131,12 +1133,14 @@ { .name = "spi-nand" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(spi, spinand_ids); #ifdef CONFIG_OF static const struct of_device_id spinand_of_ids[] = { { .compatible = "spi-nand" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, spinand_of_ids); #endif static struct spi_mem_driver spinand_drv = { --- linux-oracle-5.4.0.orig/drivers/mtd/nand/spi/gigadevice.c +++ linux-oracle-5.4.0/drivers/mtd/nand/spi/gigadevice.c @@ -21,7 +21,7 @@ #define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4) static SPINAND_OP_VARIANTS(read_cache_variants, - SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), @@ -29,7 +29,7 @@ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); static SPINAND_OP_VARIANTS(read_cache_variants_f, - SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0), @@ -201,7 +201,7 @@ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - 0, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F2GQ4xA", 0xF2, @@ -210,7 +210,7 @@ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - 0, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F4GQ4xA", 0xF4, @@ -219,7 +219,7 @@ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - 0, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, @@ -228,7 +228,7 @@ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, &update_cache_variants), - 0, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, gd5fxgq4uexxg_ecc_get_status)), SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148, @@ -237,7 +237,7 @@ SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f, &write_cache_variants, &update_cache_variants), - 0, + SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, gd5fxgq4ufxxg_ecc_get_status)), }; --- linux-oracle-5.4.0.orig/drivers/mtd/nand/spi/macronix.c +++ linux-oracle-5.4.0/drivers/mtd/nand/spi/macronix.c @@ -116,6 +116,121 @@ &update_cache_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX35LF2GE4AD", 0x26, + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX35LF4GE4AD", 0x37, + NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), + SPINAND_INFO("MX35LF2G14AC", 0x20, + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF4G24AD", 0xb5, + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF4GE4AD", 0xb7, + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF2G14AC", 0xa0, + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF2G24AD", 0xa4, + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF2GE4AD", 0xa6, + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF2GE4AC", 0xa2, + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF1G14AC", 0x90, + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF1G24AD", 0x94, + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF1GE4AD", 0x96, + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), + SPINAND_INFO("MX35UF1GE4AC", 0x92, + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, + mx35lf1ge4ab_ecc_get_status)), }; static int macronix_spinand_detect(struct spinand_device *spinand) --- linux-oracle-5.4.0.orig/drivers/mtd/nand/spi/micron.c +++ linux-oracle-5.4.0/drivers/mtd/nand/spi/micron.c @@ -12,7 +12,7 @@ #define SPINAND_MFR_MICRON 0x2c -#define MICRON_STATUS_ECC_MASK GENMASK(7, 4) +#define MICRON_STATUS_ECC_MASK GENMASK(6, 4) #define MICRON_STATUS_ECC_NO_BITFLIPS (0 << 4) #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4) #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) --- linux-oracle-5.4.0.orig/drivers/mtd/nand/spi/toshiba.c +++ linux-oracle-5.4.0/drivers/mtd/nand/spi/toshiba.c @@ -60,7 +60,7 @@ { struct nand_device *nand = spinand_to_nand(spinand); u8 mbf = 0; - struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, spinand->scratchbuf); switch (status & STATUS_ECC_MASK) { case STATUS_ECC_NO_BITFLIPS: @@ -79,7 +79,7 @@ if (spi_mem_exec_op(spinand->spimem, &op)) return nand->eccreq.strength; - mbf >>= 4; + mbf = *(spinand->scratchbuf) >> 4; if (WARN_ON(mbf > nand->eccreq.strength || !mbf)) return nand->eccreq.strength; --- linux-oracle-5.4.0.orig/drivers/mtd/parsers/afs.c +++ linux-oracle-5.4.0/drivers/mtd/parsers/afs.c @@ -126,8 +126,8 @@ * Static checks cannot see that we bail out if we have an error * reading the footer. */ - u_int uninitialized_var(iis_ptr); - u_int uninitialized_var(img_ptr); + u_int iis_ptr; + u_int img_ptr; u_int ptr; size_t sz; int ret; @@ -370,10 +370,8 @@ return i; out_free_parts: - while (i >= 0) { + while (--i >= 0) kfree(parts[i].name); - i--; - } kfree(parts); *pparts = NULL; return ret; --- linux-oracle-5.4.0.orig/drivers/mtd/parsers/cmdlinepart.c +++ linux-oracle-5.4.0/drivers/mtd/parsers/cmdlinepart.c @@ -218,12 +218,41 @@ struct cmdline_mtd_partition *this_mtd; struct mtd_partition *parts; int mtd_id_len, num_parts; - char *p, *mtd_id; + char *p, *mtd_id, *semicol, *open_parenth; + + /* + * Replace the first ';' by a NULL char so strrchr can work + * properly. + */ + semicol = strchr(s, ';'); + if (semicol) + *semicol = '\0'; + + /* + * make sure that part-names with ":" will not be handled as + * part of the mtd-id with an ":" + */ + open_parenth = strchr(s, '('); + if (open_parenth) + *open_parenth = '\0'; mtd_id = s; - /* fetch */ - p = strchr(s, ':'); + /* + * fetch . We use strrchr to ignore all ':' that could + * be present in the MTD name, only the last one is interpreted + * as an / separator. + */ + p = strrchr(s, ':'); + + /* Restore the '(' now. */ + if (open_parenth) + *open_parenth = '('; + + /* Restore the ';' now. */ + if (semicol) + *semicol = ';'; + if (!p) { pr_err("no mtd-id\n"); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/mtd/parsers/parser_imagetag.c +++ linux-oracle-5.4.0/drivers/mtd/parsers/parser_imagetag.c @@ -83,6 +83,7 @@ pr_err("invalid rootfs address: %*ph\n", (int)sizeof(buf->flash_image_start), buf->flash_image_start); + ret = -EINVAL; goto out; } @@ -92,6 +93,7 @@ pr_err("invalid kernel address: %*ph\n", (int)sizeof(buf->kernel_address), buf->kernel_address); + ret = -EINVAL; goto out; } @@ -100,6 +102,7 @@ pr_err("invalid kernel length: %*ph\n", (int)sizeof(buf->kernel_length), buf->kernel_length); + ret = -EINVAL; goto out; } @@ -108,6 +111,7 @@ pr_err("invalid total length: %*ph\n", (int)sizeof(buf->total_length), buf->total_length); + ret = -EINVAL; goto out; } --- linux-oracle-5.4.0.orig/drivers/mtd/parsers/redboot.c +++ linux-oracle-5.4.0/drivers/mtd/parsers/redboot.c @@ -45,6 +45,7 @@ static void parse_redboot_of(struct mtd_info *master) { struct device_node *np; + struct device_node *npart; u32 dirblock; int ret; @@ -52,7 +53,12 @@ if (!np) return; - ret = of_property_read_u32(np, "fis-index-block", &dirblock); + npart = of_get_child_by_name(np, "partitions"); + if (!npart) + return; + + ret = of_property_read_u32(npart, "fis-index-block", &dirblock); + of_node_put(npart); if (ret) return; @@ -96,7 +102,7 @@ offset -= master->erasesize; } } else { - offset = directory * master->erasesize; + offset = (unsigned long) directory * master->erasesize; while (mtd_block_isbad(master, offset)) { offset += master->erasesize; if (offset == master->size) --- linux-oracle-5.4.0.orig/drivers/mtd/parsers/sharpslpart.c +++ linux-oracle-5.4.0/drivers/mtd/parsers/sharpslpart.c @@ -165,10 +165,10 @@ static int sharpsl_nand_init_ftl(struct mtd_info *mtd, struct sharpsl_ftl *ftl) { - unsigned int block_num, log_num, phymax; + unsigned int block_num, phymax; + int i, ret, log_num; loff_t block_adr; u8 *oob; - int i, ret; oob = kzalloc(mtd->oobsize, GFP_KERNEL); if (!oob) --- linux-oracle-5.4.0.orig/drivers/mtd/sm_ftl.c +++ linux-oracle-5.4.0/drivers/mtd/sm_ftl.c @@ -1097,9 +1097,9 @@ { struct sm_ftl *ftl = dev->priv; - mutex_lock(&ftl->mutex); del_timer_sync(&ftl->timer); cancel_work_sync(&ftl->flush_work); + mutex_lock(&ftl->mutex); sm_cache_flush(ftl); mutex_unlock(&ftl->mutex); } --- linux-oracle-5.4.0.orig/drivers/mtd/spi-nor/cadence-quadspi.c +++ linux-oracle-5.4.0/drivers/mtd/spi-nor/cadence-quadspi.c @@ -34,6 +34,7 @@ /* Quirks */ #define CQSPI_NEEDS_WR_DELAY BIT(0) +#define CQSPI_DISABLE_DAC_MODE BIT(1) /* Capabilities mask */ #define CQSPI_BASE_HWCAPS_MASK \ @@ -77,9 +78,6 @@ dma_addr_t mmap_phys_base; int current_cs; - int current_page_size; - int current_erase_size; - int current_addr_width; unsigned long master_ref_clk_hz; bool is_decoded_cs; u32 fifo_depth; @@ -475,7 +473,7 @@ /* Setup dummy clock cycles */ dummy_clk = nor->read_dummy; if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) - dummy_clk = CQSPI_DUMMY_CLKS_MAX; + return -EOPNOTSUPP; if (dummy_clk / 8) { reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB); @@ -736,32 +734,6 @@ writel(reg, reg_base + CQSPI_REG_CONFIG); } -static void cqspi_configure_cs_and_sizes(struct spi_nor *nor) -{ - struct cqspi_flash_pdata *f_pdata = nor->priv; - struct cqspi_st *cqspi = f_pdata->cqspi; - void __iomem *iobase = cqspi->iobase; - unsigned int reg; - - /* configure page size and block size. */ - reg = readl(iobase + CQSPI_REG_SIZE); - reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB); - reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB); - reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; - reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB); - reg |= (ilog2(nor->mtd.erasesize) << CQSPI_REG_SIZE_BLOCK_LSB); - reg |= (nor->addr_width - 1); - writel(reg, iobase + CQSPI_REG_SIZE); - - /* configure the chip select */ - cqspi_chipselect(nor); - - /* Store the new configuration of the controller */ - cqspi->current_page_size = nor->page_size; - cqspi->current_erase_size = nor->mtd.erasesize; - cqspi->current_addr_width = nor->addr_width; -} - static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz, const unsigned int ns_val) { @@ -867,18 +839,13 @@ int switch_cs = (cqspi->current_cs != f_pdata->cs); int switch_ck = (cqspi->sclk != sclk); - if ((cqspi->current_page_size != nor->page_size) || - (cqspi->current_erase_size != nor->mtd.erasesize) || - (cqspi->current_addr_width != nor->addr_width)) - switch_cs = 1; - if (switch_cs || switch_ck) cqspi_controller_enable(cqspi, 0); /* Switch chip select. */ if (switch_cs) { cqspi->current_cs = f_pdata->cs; - cqspi_configure_cs_and_sizes(nor); + cqspi_chipselect(nor); } /* Setup baudrate divisor and delays */ @@ -1201,7 +1168,7 @@ cqspi_controller_enable(cqspi, 1); } -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi) { dma_cap_mask_t mask; @@ -1210,10 +1177,16 @@ cqspi->rx_chan = dma_request_chan_by_mask(&mask); if (IS_ERR(cqspi->rx_chan)) { - dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); + int ret = PTR_ERR(cqspi->rx_chan); + + if (ret != -EPROBE_DEFER) + dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); cqspi->rx_chan = NULL; + return ret; } init_completion(&cqspi->rx_dma_complete); + + return 0; } static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) @@ -1291,13 +1264,17 @@ f_pdata->registered = true; - if (mtd->size <= cqspi->ahb_size) { + if (mtd->size <= cqspi->ahb_size && + !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) { f_pdata->use_direct_mode = true; dev_dbg(nor->dev, "using direct mode for %s\n", mtd->name); - if (!cqspi->rx_chan) - cqspi_request_mmap_dma(cqspi); + if (!cqspi->rx_chan) { + ret = cqspi_request_mmap_dma(cqspi); + if (ret == -EPROBE_DEFER) + goto err; + } } } @@ -1464,17 +1441,30 @@ static int cqspi_suspend(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); + int ret; + ret = spi_master_suspend(master); cqspi_controller_enable(cqspi, 0); - return 0; + + clk_disable_unprepare(cqspi->clk); + + return ret; } static int cqspi_resume(struct device *dev) { struct cqspi_st *cqspi = dev_get_drvdata(dev); + struct spi_master *master = dev_get_drvdata(dev); - cqspi_controller_enable(cqspi, 1); - return 0; + clk_prepare_enable(cqspi->clk); + cqspi_wait_idle(cqspi); + cqspi_controller_init(cqspi); + + cqspi->current_cs = -1; + cqspi->sclk = 0; + + return spi_master_resume(master); } static const struct dev_pm_ops cqspi__dev_pm_ops = { @@ -1489,6 +1479,7 @@ static const struct cqspi_driver_platdata cdns_qspi = { .hwcaps_mask = CQSPI_BASE_HWCAPS_MASK, + .quirks = CQSPI_DISABLE_DAC_MODE, }; static const struct cqspi_driver_platdata k2g_qspi = { --- linux-oracle-5.4.0.orig/drivers/mtd/spi-nor/hisi-sfc.c +++ linux-oracle-5.4.0/drivers/mtd/spi-nor/hisi-sfc.c @@ -396,8 +396,10 @@ for_each_available_child_of_node(dev->of_node, np) { ret = hisi_spi_nor_register(np, host); - if (ret) + if (ret) { + of_node_put(np); goto fail; + } if (host->num_chip == HIFMC_MAX_CHIP_NUM) { dev_warn(dev, "Flash device number exceeds the maximum chipselect number\n"); @@ -472,7 +474,6 @@ hisi_spi_nor_unregister_all(host); mutex_destroy(&host->lock); - clk_disable_unprepare(host->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/mtd/spi-nor/intel-spi-pci.c +++ linux-oracle-5.4.0/drivers/mtd/spi-nor/intel-spi-pci.c @@ -61,6 +61,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x06a4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, --- linux-oracle-5.4.0.orig/drivers/mtd/spi-nor/intel-spi.c +++ linux-oracle-5.4.0/drivers/mtd/spi-nor/intel-spi.c @@ -113,7 +113,7 @@ #define ERASE_OPCODE_SHIFT 8 #define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) #define ERASE_64K_OPCODE_SHIFT 16 -#define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) +#define ERASE_64K_OPCODE_MASK (0xff << ERASE_64K_OPCODE_SHIFT) #define INTEL_SPI_TIMEOUT 5000 /* ms */ #define INTEL_SPI_FIFO_SZ 64 --- linux-oracle-5.4.0.orig/drivers/mtd/spi-nor/spi-nor.c +++ linux-oracle-5.4.0/drivers/mtd/spi-nor/spi-nor.c @@ -1010,15 +1010,18 @@ continue; erase = &map->erase_type[i]; - - /* Don't erase more than what the user has asked for. */ - if (erase->size > len) + if (!erase->size) continue; /* Alignment is not mandatory for overlaid regions */ - if (region->offset & SNOR_OVERLAID_REGION) + if (region->offset & SNOR_OVERLAID_REGION && + region->size <= len) return erase; + /* Don't erase more than what the user has asked for. */ + if (erase->size > len) + continue; + spi_nor_div_by_erase_size(erase, addr, &rem); if (rem) continue; @@ -1152,6 +1155,7 @@ goto destroy_erase_cmd_list; if (prev_erase != erase || + erase->size != cmd->size || region->offset & SNOR_OVERLAID_REGION) { cmd = spi_nor_init_erase_cmd(region, erase); if (IS_ERR(cmd)) { @@ -2267,6 +2271,10 @@ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_4B_OPCODES) + .fixups = &is25lp256_fixups }, /* Macronix */ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, @@ -2310,15 +2318,16 @@ { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "mt25qu512a", INFO6(0x20bb20, 0x104400, 64 * 1024, 1024, + SECT_4K | USE_FSR | SPI_NOR_DUAL_READ | + SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | + SPI_NOR_QUAD_READ) }, { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, { "mt25ql02g", INFO(0x20ba22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, - { "mt25qu512a (n25q512a)", INFO(0x20bb20, 0, 64 * 1024, 1024, - SECT_4K | USE_FSR | SPI_NOR_DUAL_READ | - SPI_NOR_QUAD_READ | - SPI_NOR_4B_OPCODES) }, { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, /* Micron */ @@ -2544,7 +2553,7 @@ size_t *retlen, u_char *buf) { struct spi_nor *nor = mtd_to_spi_nor(mtd); - int ret; + ssize_t ret; dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len); @@ -2865,7 +2874,7 @@ */ static int spi_nor_read_raw(struct spi_nor *nor, u32 addr, size_t len, u8 *buf) { - int ret; + ssize_t ret; while (len) { ret = spi_nor_read_data(nor, addr, len, buf); @@ -3699,7 +3708,7 @@ int i; for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { - if (!(erase_type & BIT(i))) + if (!(erase[i].size && erase_type & BIT(erase[i].idx))) continue; if (region->size & erase[i].size_mask) { spi_nor_region_mark_overlay(region); @@ -3769,6 +3778,7 @@ offset = (region[i].offset & ~SNOR_ERASE_FLAGS_MASK) + region[i].size; } + spi_nor_region_mark_end(®ion[i - 1]); save_uniform_erase_type = map->uniform_erase_type; map->uniform_erase_type = spi_nor_sort_erase_mask(map, @@ -3792,8 +3802,6 @@ if (!(regions_erase_type & BIT(erase[i].idx))) spi_nor_set_erase_type(&erase[i], 0, 0xFF); - spi_nor_region_mark_end(®ion[i - 1]); - return 0; } @@ -4443,11 +4451,10 @@ memcpy(&sfdp_params, &nor->params, sizeof(sfdp_params)); - if (spi_nor_parse_sfdp(nor, &sfdp_params)) { + if (spi_nor_parse_sfdp(nor, &nor->params)) { + memcpy(&nor->params, &sfdp_params, sizeof(nor->params)); nor->addr_width = 0; nor->flags &= ~SNOR_F_4B_OPCODES; - } else { - memcpy(&nor->params, &sfdp_params, sizeof(nor->params)); } } @@ -4544,9 +4551,7 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor) { - struct mtd_info *mtd = &nor->mtd; - - if (mtd->size <= SZ_16M) + if (nor->params.size <= SZ_16M) return; nor->flags |= SNOR_F_4B_OPCODES; --- linux-oracle-5.4.0.orig/drivers/mtd/tests/Makefile +++ linux-oracle-5.4.0/drivers/mtd/tests/Makefile @@ -1,19 +1,19 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o -obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o -obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o -obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o -obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o -obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o -obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o -obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o -obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o +obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o mtd_test.o +obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o mtd_test.o -mtd_oobtest-objs := oobtest.o mtd_test.o -mtd_pagetest-objs := pagetest.o mtd_test.o -mtd_readtest-objs := readtest.o mtd_test.o -mtd_speedtest-objs := speedtest.o mtd_test.o -mtd_stresstest-objs := stresstest.o mtd_test.o -mtd_subpagetest-objs := subpagetest.o mtd_test.o -mtd_torturetest-objs := torturetest.o mtd_test.o -mtd_nandbiterrs-objs := nandbiterrs.o mtd_test.o +mtd_oobtest-objs := oobtest.o +mtd_pagetest-objs := pagetest.o +mtd_readtest-objs := readtest.o +mtd_speedtest-objs := speedtest.o +mtd_stresstest-objs := stresstest.o +mtd_subpagetest-objs := subpagetest.o +mtd_torturetest-objs := torturetest.o +mtd_nandbiterrs-objs := nandbiterrs.o --- linux-oracle-5.4.0.orig/drivers/mtd/tests/mtd_test.c +++ linux-oracle-5.4.0/drivers/mtd/tests/mtd_test.c @@ -25,6 +25,7 @@ return 0; } +EXPORT_SYMBOL_GPL(mtdtest_erase_eraseblock); static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum) { @@ -57,6 +58,7 @@ return 0; } +EXPORT_SYMBOL_GPL(mtdtest_scan_for_bad_eraseblocks); int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt, unsigned int eb, int ebcnt) @@ -75,6 +77,7 @@ return 0; } +EXPORT_SYMBOL_GPL(mtdtest_erase_good_eraseblocks); int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf) { @@ -92,6 +95,7 @@ return err; } +EXPORT_SYMBOL_GPL(mtdtest_read); int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size, const void *buf) @@ -107,3 +111,8 @@ return err; } +EXPORT_SYMBOL_GPL(mtdtest_write); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MTD function test helpers"); +MODULE_AUTHOR("Akinobu Mita"); --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/attach.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/attach.c @@ -1447,7 +1447,7 @@ return err; } -static struct ubi_attach_info *alloc_ai(void) +static struct ubi_attach_info *alloc_ai(const char *slab_name) { struct ubi_attach_info *ai; @@ -1461,7 +1461,7 @@ INIT_LIST_HEAD(&ai->alien); INIT_LIST_HEAD(&ai->fastmap); ai->volumes = RB_ROOT; - ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", + ai->aeb_slab_cache = kmem_cache_create(slab_name, sizeof(struct ubi_ainf_peb), 0, 0, NULL); if (!ai->aeb_slab_cache) { @@ -1491,7 +1491,7 @@ err = -ENOMEM; - scan_ai = alloc_ai(); + scan_ai = alloc_ai("ubi_aeb_slab_cache_fastmap"); if (!scan_ai) goto out; @@ -1557,7 +1557,7 @@ int err; struct ubi_attach_info *ai; - ai = alloc_ai(); + ai = alloc_ai("ubi_aeb_slab_cache"); if (!ai) return -ENOMEM; @@ -1575,7 +1575,7 @@ if (err > 0 || mtd_is_eccerr(err)) { if (err != UBI_NO_FASTMAP) { destroy_ai(ai); - ai = alloc_ai(); + ai = alloc_ai("ubi_aeb_slab_cache"); if (!ai) return -ENOMEM; @@ -1614,7 +1614,7 @@ if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) { struct ubi_attach_info *scan_ai; - scan_ai = alloc_ai(); + scan_ai = alloc_ai("ubi_aeb_slab_cache_dbg_chk_fastmap"); if (!scan_ai) { err = -ENOMEM; goto out_wl; --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/build.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/build.c @@ -350,9 +350,6 @@ * we still can use 'ubi->ubi_num'. */ ubi = container_of(dev, struct ubi_device, dev); - ubi = ubi_get_device(ubi->ubi_num); - if (!ubi) - return -ENODEV; if (attr == &dev_eraseblock_size) ret = sprintf(buf, "%d\n", ubi->leb_size); @@ -381,7 +378,6 @@ else ret = -EINVAL; - ubi_put_device(ubi); return ret; } @@ -471,6 +467,7 @@ err = ubi_add_volume(ubi, ubi->volumes[i]); if (err) { ubi_err(ubi, "cannot add volume %d", i); + ubi->volumes[i] = NULL; goto out_volumes; } } @@ -664,6 +661,21 @@ ubi->vid_hdr_aloffset; } + /* + * Memory allocation for VID header is ubi->vid_hdr_alsize + * which is described in comments in io.c. + * Make sure VID header shift + UBI_VID_HDR_SIZE not exceeds + * ubi->vid_hdr_alsize, so that all vid header operations + * won't access memory out of bounds. + */ + if ((ubi->vid_hdr_shift + UBI_VID_HDR_SIZE) > ubi->vid_hdr_alsize) { + ubi_err(ubi, "Invalid VID header offset %d, VID header shift(%d)" + " + VID header size(%zu) > VID header aligned size(%d).", + ubi->vid_hdr_offset, ubi->vid_hdr_shift, + UBI_VID_HDR_SIZE, ubi->vid_hdr_alsize); + return -EINVAL; + } + /* Similar for the data offset */ ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE; ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); @@ -853,6 +865,13 @@ return -EINVAL; } + /* UBI cannot work on flashes with zero erasesize. */ + if (!mtd->erasesize) { + pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n", + mtd->index); + return -EINVAL; + } + if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) @@ -956,9 +975,6 @@ goto out_detach; } - /* Make device "available" before it becomes accessible via sysfs */ - ubi_devices[ubi_num] = ubi; - err = uif_init(ubi); if (err) goto out_detach; @@ -1003,6 +1019,7 @@ wake_up_process(ubi->bgt_thread); spin_unlock(&ubi->wl_lock); + ubi_devices[ubi_num] = ubi; ubi_notify_all(ubi, UBI_VOLUME_ADDED, NULL); return ubi_num; @@ -1011,7 +1028,6 @@ out_uif: uif_close(ubi); out_detach: - ubi_devices[ubi_num] = NULL; ubi_wl_close(ubi); ubi_free_internal_volumes(ubi); vfree(ubi->vtbl); --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/debug.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/debug.c @@ -392,9 +392,6 @@ { struct ubi_device *ubi = s->private; - if (*pos == 0) - return SEQ_START_TOKEN; - if (*pos < ubi->peb_count) return pos; @@ -408,8 +405,6 @@ { struct ubi_device *ubi = s->private; - if (v == SEQ_START_TOKEN) - return pos; (*pos)++; if (*pos < ubi->peb_count) @@ -431,11 +426,8 @@ int err; /* If this is the start, print a header */ - if (iter == SEQ_START_TOKEN) { - seq_puts(s, - "physical_block_number\terase_count\tblock_status\tread_status\n"); - return 0; - } + if (*block_number == 0) + seq_puts(s, "physical_block_number\terase_count\n"); err = ubi_io_is_bad(ubi, *block_number); if (err) --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/eba.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/eba.c @@ -599,7 +599,7 @@ int err, pnum, scrub = 0, vol_id = vol->vol_id; struct ubi_vid_io_buf *vidb; struct ubi_vid_hdr *vid_hdr; - uint32_t uninitialized_var(crc); + uint32_t crc; err = leb_read_lock(ubi, vol_id, lnum); if (err) @@ -947,7 +947,7 @@ int offset, int len) { struct ubi_device *ubi = vol->ubi; - int pnum, opnum, err, vol_id = vol->vol_id; + int pnum, opnum, err, err2, vol_id = vol->vol_id; pnum = ubi_wl_get_peb(ubi); if (pnum < 0) { @@ -982,10 +982,19 @@ out_put: up_read(&ubi->fm_eba_sem); - if (err && pnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); - else if (!err && opnum >= 0) - err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err && pnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + pnum, err2); + } + } else if (!err && opnum >= 0) { + err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0); + if (err2) { + ubi_warn(ubi, "failed to return physical eraseblock %d, error %d", + opnum, err2); + } + } return err; } @@ -1551,6 +1560,7 @@ GFP_KERNEL); if (!fm_eba[i]) { ret = -ENOMEM; + kfree(scan_eba[i]); goto out_free; } @@ -1586,7 +1596,7 @@ } out_free: - for (i = 0; i < num_volumes; i++) { + while (--i >= 0) { if (!ubi->volumes[i]) continue; --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/fastmap-wl.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/fastmap-wl.c @@ -39,6 +39,13 @@ return victim; } +static inline void return_unused_peb(struct ubi_device *ubi, + struct ubi_wl_entry *e) +{ + wl_tree_add(e, &ubi->free); + ubi->free_count++; +} + /** * return_unused_pool_pebs - returns unused PEB to the free tree. * @ubi: UBI device description object @@ -52,23 +59,10 @@ for (i = pool->used; i < pool->size; i++) { e = ubi->lookuptbl[pool->pebs[i]]; - wl_tree_add(e, &ubi->free); - ubi->free_count++; + return_unused_peb(ubi, e); } } -static int anchor_pebs_available(struct rb_root *root) -{ - struct rb_node *p; - struct ubi_wl_entry *e; - - ubi_rb_for_each_entry(p, e, root, u.rb) - if (e->pnum < UBI_FM_MAX_START) - return 1; - - return 0; -} - /** * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number. * @ubi: UBI device description object @@ -277,8 +271,26 @@ int ubi_ensure_anchor_pebs(struct ubi_device *ubi) { struct ubi_work *wrk; + struct ubi_wl_entry *anchor; spin_lock(&ubi->wl_lock); + + /* Do we already have an anchor? */ + if (ubi->fm_anchor) { + spin_unlock(&ubi->wl_lock); + return 0; + } + + /* See if we can find an anchor PEB on the list of free PEBs */ + anchor = ubi_wl_get_fm_peb(ubi, 1); + if (anchor) { + ubi->fm_anchor = anchor; + spin_unlock(&ubi->wl_lock); + return 0; + } + + /* No luck, trigger wear leveling to produce a new anchor PEB */ + ubi->fm_do_produce_anchor = 1; if (ubi->wl_scheduled) { spin_unlock(&ubi->wl_lock); return 0; @@ -294,7 +306,6 @@ return -ENOMEM; } - wrk->anchor = 1; wrk->func = &wear_leveling_worker; __schedule_ubi_work(ubi, wrk); return 0; @@ -356,6 +367,11 @@ return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); + if (ubi->fm_anchor) { + return_unused_peb(ubi, ubi->fm_anchor); + ubi->fm_anchor = NULL; + } + if (ubi->fm) { for (i = 0; i < ubi->fm->used_blocks; i++) kfree(ubi->fm->e[i]); --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/fastmap.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/fastmap.c @@ -64,7 +64,7 @@ return 0; for (pnum = 0; pnum < ubi->peb_count; pnum++) { - if (test_bit(pnum, seen) && ubi->lookuptbl[pnum]) { + if (!test_bit(pnum, seen) && ubi->lookuptbl[pnum]) { ubi_err(ubi, "self-check failed for PEB %d, fastmap didn't see it", pnum); ret = -EINVAL; } @@ -86,9 +86,10 @@ sizeof(struct ubi_fm_scan_pool) + sizeof(struct ubi_fm_scan_pool) + (ubi->peb_count * sizeof(struct ubi_fm_ec)) + - (sizeof(struct ubi_fm_eba) + - (ubi->peb_count * sizeof(__be32))) + - sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES; + ((sizeof(struct ubi_fm_eba) + + sizeof(struct ubi_fm_volhdr)) * + (UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT)) + + (ubi->peb_count * sizeof(__be32)); return roundup(size, ubi->leb_size); } @@ -468,7 +469,9 @@ if (err == UBI_IO_FF_BITFLIPS) scrub = 1; - add_aeb(ai, free, pnum, ec, scrub); + ret = add_aeb(ai, free, pnum, ec, scrub); + if (ret) + goto out; continue; } else if (err == 0 || err == UBI_IO_BITFLIPS) { dbg_bld("Found non empty PEB:%i in pool", pnum); @@ -638,8 +641,10 @@ if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 0); + ret = add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 0); + if (ret) + goto fail; } /* read EC values from used list */ @@ -649,8 +654,10 @@ if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &used, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 0); + ret = add_aeb(ai, &used, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 0); + if (ret) + goto fail; } /* read EC values from scrub list */ @@ -660,8 +667,10 @@ if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &used, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 1); + ret = add_aeb(ai, &used, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 1); + if (ret) + goto fail; } /* read EC values from erase list */ @@ -671,8 +680,10 @@ if (fm_pos >= fm_size) goto fail_bad; - add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum), - be32_to_cpu(fmec->ec), 1); + ret = add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum), + be32_to_cpu(fmec->ec), 1); + if (ret) + goto fail; } ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); @@ -1137,7 +1148,7 @@ struct rb_node *tmp_rb; int ret, i, j, free_peb_count, used_peb_count, vol_count; int scrub_peb_count, erase_peb_count; - unsigned long *seen_pebs = NULL; + unsigned long *seen_pebs; fm_raw = ubi->fm_buf; memset(ubi->fm_buf, 0, ubi->fm_size); @@ -1151,7 +1162,7 @@ dvbuf = new_fm_vbuf(ubi, UBI_FM_DATA_VOLUME_ID); if (!dvbuf) { ret = -ENOMEM; - goto out_kfree; + goto out_free_avbuf; } avhdr = ubi_get_vid_hdr(avbuf); @@ -1160,7 +1171,7 @@ seen_pebs = init_seen(ubi); if (IS_ERR(seen_pebs)) { ret = PTR_ERR(seen_pebs); - goto out_kfree; + goto out_free_dvbuf; } spin_lock(&ubi->volumes_lock); @@ -1328,7 +1339,7 @@ ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avbuf); if (ret) { ubi_err(ubi, "unable to write vid_hdr to fastmap SB!"); - goto out_kfree; + goto out_free_seen; } for (i = 0; i < new_fm->used_blocks; i++) { @@ -1350,7 +1361,7 @@ if (ret) { ubi_err(ubi, "unable to write vid_hdr to PEB %i!", new_fm->e[i]->pnum); - goto out_kfree; + goto out_free_seen; } } @@ -1360,7 +1371,7 @@ if (ret) { ubi_err(ubi, "unable to write fastmap to PEB %i!", new_fm->e[i]->pnum); - goto out_kfree; + goto out_free_seen; } } @@ -1370,10 +1381,13 @@ ret = self_check_seen(ubi, seen_pebs); dbg_bld("fastmap written!"); -out_kfree: - ubi_free_vid_buf(avbuf); - ubi_free_vid_buf(dvbuf); +out_free_seen: free_seen(seen_pebs); +out_free_dvbuf: + ubi_free_vid_buf(dvbuf); +out_free_avbuf: + ubi_free_vid_buf(avbuf); + out: return ret; } @@ -1540,14 +1554,6 @@ return 0; } - ret = ubi_ensure_anchor_pebs(ubi); - if (ret) { - up_write(&ubi->fm_eba_sem); - up_write(&ubi->work_sem); - up_write(&ubi->fm_protect); - return ret; - } - new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL); if (!new_fm) { up_write(&ubi->fm_eba_sem); @@ -1618,7 +1624,8 @@ } spin_lock(&ubi->wl_lock); - tmp_e = ubi_wl_get_fm_peb(ubi, 1); + tmp_e = ubi->fm_anchor; + ubi->fm_anchor = NULL; spin_unlock(&ubi->wl_lock); if (old_fm) { @@ -1670,6 +1677,9 @@ up_write(&ubi->work_sem); up_write(&ubi->fm_protect); kfree(old_fm); + + ubi_ensure_anchor_pebs(ubi); + return ret; err: --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/ubi.h +++ linux-oracle-5.4.0/drivers/mtd/ubi/ubi.h @@ -491,6 +491,8 @@ * @fm_work: fastmap work queue * @fm_work_scheduled: non-zero if fastmap work was scheduled * @fast_attach: non-zero if UBI was attached by fastmap + * @fm_anchor: The next anchor PEB to use for fastmap + * @fm_do_produce_anchor: If true produce an anchor PEB in wl * * @used: RB-tree of used physical eraseblocks * @erroneous: RB-tree of erroneous used physical eraseblocks @@ -599,6 +601,8 @@ struct work_struct fm_work; int fm_work_scheduled; int fast_attach; + struct ubi_wl_entry *fm_anchor; + int fm_do_produce_anchor; /* Wear-leveling sub-system's stuff */ struct rb_root used; @@ -789,7 +793,6 @@ * @vol_id: the volume ID on which this erasure is being performed * @lnum: the logical eraseblock number * @torture: if the physical eraseblock has to be tortured - * @anchor: produce a anchor PEB to by used by fastmap * * The @func pointer points to the worker function. If the @shutdown argument is * not zero, the worker has to free the resources and exit immediately as the @@ -805,7 +808,6 @@ int vol_id; int lnum; int torture; - int anchor; }; #include "debug.h" --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/vmt.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/vmt.c @@ -56,16 +56,11 @@ { int ret; struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); - struct ubi_device *ubi; - - ubi = ubi_get_device(vol->ubi->ubi_num); - if (!ubi) - return -ENODEV; + struct ubi_device *ubi = vol->ubi; spin_lock(&ubi->volumes_lock); if (!ubi->volumes[vol->vol_id]) { spin_unlock(&ubi->volumes_lock); - ubi_put_device(ubi); return -ENODEV; } /* Take a reference to prevent volume removal */ @@ -103,7 +98,6 @@ vol->ref_count -= 1; ubi_assert(vol->ref_count >= 0); spin_unlock(&ubi->volumes_lock); - ubi_put_device(ubi); return ret; } @@ -315,7 +309,6 @@ ubi->volumes[vol_id] = NULL; ubi->vol_count -= 1; spin_unlock(&ubi->volumes_lock); - ubi_eba_destroy_table(eba_tbl); out_acc: spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs -= vol->reserved_pebs; @@ -471,7 +464,7 @@ for (i = 0; i < -pebs; i++) { err = ubi_eba_unmap_leb(ubi, vol, reserved_pebs + i); if (err) - goto out_acc; + goto out_free; } spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs += pebs; @@ -519,8 +512,10 @@ ubi->avail_pebs += pebs; spin_unlock(&ubi->volumes_lock); } + return err; + out_free: - kfree(new_eba_tbl); + ubi_eba_destroy_table(new_eba_tbl); return err; } @@ -587,6 +582,7 @@ if (err) { ubi_err(ubi, "cannot add character device for volume %d, error %d", vol_id, err); + vol_release(&vol->dev); return err; } @@ -597,15 +593,14 @@ vol->dev.groups = volume_dev_groups; dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); err = device_register(&vol->dev); - if (err) - goto out_cdev; + if (err) { + cdev_del(&vol->cdev); + put_device(&vol->dev); + return err; + } self_check_volumes(ubi); return err; - -out_cdev: - cdev_del(&vol->cdev); - return err; } /** --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/vtbl.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/vtbl.c @@ -791,6 +791,12 @@ * The number of supported volumes is limited by the eraseblock size * and by the UBI_MAX_VOLUMES constant. */ + + if (ubi->leb_size < UBI_VTBL_RECORD_SIZE) { + ubi_err(ubi, "LEB size too small for a volume record"); + return -EINVAL; + } + ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE; if (ubi->vtbl_slots > UBI_MAX_VOLUMES) ubi->vtbl_slots = UBI_MAX_VOLUMES; --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/wl.c +++ linux-oracle-5.4.0/drivers/mtd/ubi/wl.c @@ -339,13 +339,6 @@ } } - /* If no fastmap has been written and this WL entry can be used - * as anchor PEB, hold it back and return the second best WL entry - * such that fastmap can use the anchor PEB later. */ - if (prev_e && !ubi->fm_disabled && - !ubi->fm && e->pnum < UBI_FM_MAX_START) - return prev_e; - return e; } @@ -583,6 +576,7 @@ * @vol_id: the volume ID that last used this PEB * @lnum: the last used logical eraseblock number for the PEB * @torture: if the physical eraseblock has to be tortured + * @nested: denotes whether the work_sem is already held * * This function returns zero in case of success and a %-ENOMEM in case of * failure. @@ -656,9 +650,6 @@ { int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0; int erase = 0, keep = 0, vol_id = -1, lnum = -1; -#ifdef CONFIG_MTD_UBI_FASTMAP - int anchor = wrk->anchor; -#endif struct ubi_wl_entry *e1, *e2; struct ubi_vid_io_buf *vidb; struct ubi_vid_hdr *vid_hdr; @@ -698,11 +689,7 @@ } #ifdef CONFIG_MTD_UBI_FASTMAP - /* Check whether we need to produce an anchor PEB */ - if (!anchor) - anchor = !anchor_pebs_available(&ubi->free); - - if (anchor) { + if (ubi->fm_do_produce_anchor) { e1 = find_anchor_wl_entry(&ubi->used); if (!e1) goto out_cancel; @@ -719,6 +706,7 @@ self_check_in_wl_tree(ubi, e1, &ubi->used); rb_erase(&e1->u.rb, &ubi->used); dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum); + ubi->fm_do_produce_anchor = 0; } else if (!ubi->scrub.rb_node) { #else if (!ubi->scrub.rb_node) { @@ -836,7 +824,14 @@ goto out_not_moved; } if (err == MOVE_RETRY) { - scrubbing = 1; + /* + * For source PEB: + * 1. The scrubbing is set for scrub type PEB, it will + * be put back into ubi->scrub list. + * 2. Non-scrub type PEB will be put back into ubi->used + * list. + */ + keep = 1; dst_leb_clean = 1; goto out_not_moved; } @@ -892,8 +887,11 @@ err = do_sync_erase(ubi, e1, vol_id, lnum, 0); if (err) { - if (e2) + if (e2) { + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e2); + spin_unlock(&ubi->wl_lock); + } goto out_ro; } @@ -975,11 +973,11 @@ spin_lock(&ubi->wl_lock); ubi->move_from = ubi->move_to = NULL; ubi->move_to_put = ubi->wl_scheduled = 0; + wl_entry_destroy(ubi, e1); + wl_entry_destroy(ubi, e2); spin_unlock(&ubi->wl_lock); ubi_free_vid_buf(vidb); - wl_entry_destroy(ubi, e1); - wl_entry_destroy(ubi, e2); out_ro: ubi_ro_mode(ubi); @@ -1051,7 +1049,6 @@ goto out_cancel; } - wrk->anchor = 0; wrk->func = &wear_leveling_worker; if (nested) __schedule_ubi_work(ubi, wrk); @@ -1071,8 +1068,6 @@ * __erase_worker - physical eraseblock erase worker function. * @ubi: UBI device description object * @wl_wrk: the work object - * @shutdown: non-zero if the worker has to free memory and exit - * because the WL sub-system is shutting down * * This function erases a physical eraseblock and perform torture testing if * needed. It also takes care about marking the physical eraseblock bad if @@ -1093,8 +1088,15 @@ err = sync_erase(ubi, e, wl_wrk->torture); if (!err) { spin_lock(&ubi->wl_lock); - wl_tree_add(e, &ubi->free); - ubi->free_count++; + + if (!ubi->fm_anchor && e->pnum < UBI_FM_MAX_START) { + ubi->fm_anchor = e; + ubi->fm_do_produce_anchor = 0; + } else { + wl_tree_add(e, &ubi->free); + ubi->free_count++; + } + spin_unlock(&ubi->wl_lock); /* @@ -1115,16 +1117,20 @@ int err1; /* Re-schedule the LEB for erasure */ - err1 = schedule_erase(ubi, e, vol_id, lnum, 0, false); + err1 = schedule_erase(ubi, e, vol_id, lnum, 0, true); if (err1) { + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e); + spin_unlock(&ubi->wl_lock); err = err1; goto out_ro; } return err; } + spin_lock(&ubi->wl_lock); wl_entry_destroy(ubi, e); + spin_unlock(&ubi->wl_lock); if (err != -EIO) /* * If this is not %-EIO, we have no idea what to do. Scheduling @@ -1240,6 +1246,18 @@ retry: spin_lock(&ubi->wl_lock); e = ubi->lookuptbl[pnum]; + if (!e) { + /* + * This wl entry has been removed for some errors by other + * process (eg. wear leveling worker), corresponding process + * (except __erase_worker, which cannot concurrent with + * ubi_wl_put_peb) will set ubi ro_mode at the same time, + * just ignore this wl entry. + */ + spin_unlock(&ubi->wl_lock); + up_read(&ubi->fm_protect); + return 0; + } if (e == ubi->move_from) { /* * User is putting the physical eraseblock which was selected to @@ -1636,6 +1654,19 @@ !ubi->thread_enabled || ubi_dbg_is_bgt_disabled(ubi)) { set_current_state(TASK_INTERRUPTIBLE); spin_unlock(&ubi->wl_lock); + + /* + * Check kthread_should_stop() after we set the task + * state to guarantee that we either see the stop bit + * and exit or the task state is reset to runnable such + * that it's not scheduled out indefinitely and detects + * the stop bit at kthread_should_stop(). + */ + if (kthread_should_stop()) { + set_current_state(TASK_RUNNING); + break; + } + schedule(); continue; } @@ -1882,6 +1913,9 @@ if (err) goto out_free; +#ifdef CONFIG_MTD_UBI_FASTMAP + ubi_ensure_anchor_pebs(ubi); +#endif return 0; out_free: --- linux-oracle-5.4.0.orig/drivers/mtd/ubi/wl.h +++ linux-oracle-5.4.0/drivers/mtd/ubi/wl.h @@ -2,7 +2,6 @@ #ifndef UBI_WL_H #define UBI_WL_H #ifdef CONFIG_MTD_UBI_FASTMAP -static int anchor_pebs_available(struct rb_root *root); static void update_fastmap_work_fn(struct work_struct *wrk); static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root); static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi); --- linux-oracle-5.4.0.orig/drivers/net/Kconfig +++ linux-oracle-5.4.0/drivers/net/Kconfig @@ -106,6 +106,7 @@ config IFB tristate "Intermediate Functional Block support" depends on NET_CLS_ACT + select NET_REDIRECT ---help--- This is an intermediate driver that allows sharing of resources. @@ -153,22 +154,22 @@ select NET_L3_MASTER_DEV config IPVLAN - tristate "IP-VLAN support" - depends on INET - depends on IPV6 || !IPV6 - ---help--- - This allows one to create virtual devices off of a main interface - and packets will be delivered based on the dest L3 (IPv6/IPv4 addr) - on packets. All interfaces (including the main interface) share L2 - making it transparent to the connected L2 switch. + tristate "IP-VLAN support" + depends on INET + depends on IPV6 || !IPV6 + ---help--- + This allows one to create virtual devices off of a main interface + and packets will be delivered based on the dest L3 (IPv6/IPv4 addr) + on packets. All interfaces (including the main interface) share L2 + making it transparent to the connected L2 switch. - Ipvlan devices can be added using the "ip" command from the - iproute2 package starting with the iproute2-3.19 release: + Ipvlan devices can be added using the "ip" command from the + iproute2 package starting with the iproute2-3.19 release: - "ip link add link [ NAME ] type ipvlan" + "ip link add link [ NAME ] type ipvlan" - To compile this driver as a module, choose M here: the module - will be called ipvlan. + To compile this driver as a module, choose M here: the module + will be called ipvlan. config IPVTAP tristate "IP-VLAN based tap driver" @@ -185,11 +186,11 @@ will be called ipvtap. config VXLAN - tristate "Virtual eXtensible Local Area Network (VXLAN)" - depends on INET - select NET_UDP_TUNNEL - select GRO_CELLS - ---help--- + tristate "Virtual eXtensible Local Area Network (VXLAN)" + depends on INET + select NET_UDP_TUNNEL + select GRO_CELLS + ---help--- This allows one to create vxlan virtual interfaces that provide Layer 2 Networks over Layer 3 Networks. VXLAN is often used to tunnel virtual network infrastructure in virtualized environments. @@ -200,12 +201,12 @@ will be called vxlan. config GENEVE - tristate "Generic Network Virtualization Encapsulation" - depends on INET - depends on IPV6 || !IPV6 - select NET_UDP_TUNNEL - select GRO_CELLS - ---help--- + tristate "Generic Network Virtualization Encapsulation" + depends on INET + depends on IPV6 || !IPV6 + select NET_UDP_TUNNEL + select GRO_CELLS + ---help--- This allows one to create geneve virtual interfaces that provide Layer 2 Networks over Layer 3 Networks. GENEVE is often used to tunnel virtual network infrastructure in virtualized environments. @@ -244,8 +245,8 @@ config NETCONSOLE tristate "Network console logging support" ---help--- - If you want to log kernel messages over the network, enable this. - See for details. + If you want to log kernel messages over the network, enable this. + See for details. config NETCONSOLE_DYNAMIC bool "Dynamic reconfiguration of logging targets" @@ -362,12 +363,12 @@ support enables VRF devices. config VSOCKMON - tristate "Virtual vsock monitoring device" - depends on VHOST_VSOCK - ---help--- - This option enables a monitoring net device for vsock sockets. It is - mostly intended for developers or support to debug vsock issues. If - unsure, say N. + tristate "Virtual vsock monitoring device" + depends on VHOST_VSOCK + ---help--- + This option enables a monitoring net device for vsock sockets. It is + mostly intended for developers or support to debug vsock issues. If + unsure, say N. endif # NET_CORE --- linux-oracle-5.4.0.orig/drivers/net/appletalk/cops.c +++ linux-oracle-5.4.0/drivers/net/appletalk/cops.c @@ -325,6 +325,8 @@ break; } + dev->base_addr = ioaddr; + /* Reserve any actual interrupt. */ if (dev->irq) { retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); @@ -332,8 +334,6 @@ goto err_out; } - dev->base_addr = ioaddr; - lp = netdev_priv(dev); spin_lock_init(&lp->lock); --- linux-oracle-5.4.0.orig/drivers/net/arcnet/arc-rimi.c +++ linux-oracle-5.4.0/drivers/net/arcnet/arc-rimi.c @@ -332,7 +332,7 @@ dev->irq = 9; if (arcrimi_probe(dev)) { - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -349,7 +349,7 @@ iounmap(lp->mem_start); release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); free_irq(dev->irq, dev); - free_netdev(dev); + free_arcdev(dev); } #ifndef MODULE --- linux-oracle-5.4.0.orig/drivers/net/arcnet/arcdevice.h +++ linux-oracle-5.4.0/drivers/net/arcnet/arcdevice.h @@ -186,6 +186,8 @@ #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */ #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit, but default is 2.5MBit. */ +#define ARC_HAS_LED 4 /* card has software controlled LEDs */ +#define ARC_HAS_ROTARY 8 /* card has rotary encoder */ /* information needed to define an encapsulation driver */ struct ArcProto { @@ -298,6 +300,10 @@ int excnak_pending; /* We just got an excesive nak interrupt */ + /* RESET flag handling */ + int reset_in_progress; + struct work_struct reset_work; + struct { uint16_t sequence; /* sequence number (incs with each packet) */ __be16 aborted_seq; @@ -350,7 +356,9 @@ void arcnet_unregister_proto(struct ArcProto *proto); irqreturn_t arcnet_interrupt(int irq, void *dev_id); + struct net_device *alloc_arcdev(const char *name); +void free_arcdev(struct net_device *dev); int arcnet_open(struct net_device *dev); int arcnet_close(struct net_device *dev); --- linux-oracle-5.4.0.orig/drivers/net/arcnet/arcnet.c +++ linux-oracle-5.4.0/drivers/net/arcnet/arcnet.c @@ -387,10 +387,44 @@ struct arcnet_local *lp = from_timer(lp, t, timer); struct net_device *dev = lp->dev; - if (!netif_carrier_ok(dev)) { + spin_lock_irq(&lp->lock); + + if (!lp->reset_in_progress && !netif_carrier_ok(dev)) { netif_carrier_on(dev); netdev_info(dev, "link up\n"); } + + spin_unlock_irq(&lp->lock); +} + +static void reset_device_work(struct work_struct *work) +{ + struct arcnet_local *lp; + struct net_device *dev; + + lp = container_of(work, struct arcnet_local, reset_work); + dev = lp->dev; + + /* Do not bring the network interface back up if an ifdown + * was already done. + */ + if (!netif_running(dev) || !lp->reset_in_progress) + return; + + rtnl_lock(); + + /* Do another check, in case of an ifdown that was triggered in + * the small race window between the exit condition above and + * acquiring RTNL. + */ + if (!netif_running(dev) || !lp->reset_in_progress) + goto out; + + dev_close(dev); + dev_open(dev, NULL); + +out: + rtnl_unlock(); } static void arcnet_reply_tasklet(unsigned long data) @@ -434,7 +468,7 @@ ret = sock_queue_err_skb(sk, ackskb); if (ret) - kfree_skb(ackskb); + dev_kfree_skb_irq(ackskb); local_irq_enable(); }; @@ -452,12 +486,25 @@ lp->dev = dev; spin_lock_init(&lp->lock); timer_setup(&lp->timer, arcnet_timer, 0); + INIT_WORK(&lp->reset_work, reset_device_work); } return dev; } EXPORT_SYMBOL(alloc_arcdev); +void free_arcdev(struct net_device *dev) +{ + struct arcnet_local *lp = netdev_priv(dev); + + /* Do not cancel this at ->ndo_close(), as the workqueue itself + * indirectly calls the ifdown path through dev_close(). + */ + cancel_work_sync(&lp->reset_work); + free_netdev(dev); +} +EXPORT_SYMBOL(free_arcdev); + /* Open/initialize the board. This is called sometime after booting when * the 'ifconfig' program is run. * @@ -587,6 +634,10 @@ /* shut down the card */ lp->hw.close(dev); + + /* reset counters */ + lp->reset_in_progress = 0; + module_put(lp->hw.owner); return 0; } @@ -820,6 +871,9 @@ spin_lock_irqsave(&lp->lock, flags); + if (lp->reset_in_progress) + goto out; + /* RESET flag was enabled - if device is not running, we must * clear it right away (but nothing else). */ @@ -852,11 +906,14 @@ if (status & RESETflag) { arc_printk(D_NORMAL, dev, "spurious reset (status=%Xh)\n", status); - arcnet_close(dev); - arcnet_open(dev); + + lp->reset_in_progress = 1; + netif_stop_queue(dev); + netif_carrier_off(dev); + schedule_work(&lp->reset_work); /* get out of the interrupt handler! */ - break; + goto out; } /* RX is inhibited - we must have received something. * Prepare to receive into the next buffer. @@ -1052,6 +1109,7 @@ udelay(1); lp->hw.intmask(dev, lp->intmask); +out: spin_unlock_irqrestore(&lp->lock, flags); return retval; } --- linux-oracle-5.4.0.orig/drivers/net/arcnet/com20020-isa.c +++ linux-oracle-5.4.0/drivers/net/arcnet/com20020-isa.c @@ -169,7 +169,7 @@ dev->irq = 9; if (com20020isa_probe(dev)) { - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -182,7 +182,7 @@ unregister_netdev(my_dev); free_irq(my_dev->irq, my_dev); release_region(my_dev->base_addr, ARCNET_TOTAL_SIZE); - free_netdev(my_dev); + free_arcdev(my_dev); } #ifndef MODULE --- linux-oracle-5.4.0.orig/drivers/net/arcnet/com20020-pci.c +++ linux-oracle-5.4.0/drivers/net/arcnet/com20020-pci.c @@ -127,6 +127,8 @@ int i, ioaddr, ret; struct resource *r; + ret = 0; + if (pci_enable_device(pdev)) return -EIO; @@ -136,9 +138,14 @@ return -ENOMEM; ci = (struct com20020_pci_card_info *)id->driver_data; + if (!ci) + return -EINVAL; + priv->ci = ci; mm = &ci->misc_map; + pci_set_drvdata(pdev, priv); + INIT_LIST_HEAD(&priv->list_dev); if (mm->size) { @@ -161,7 +168,7 @@ dev = alloc_arcdev(device); if (!dev) { ret = -ENOMEM; - goto out_port; + break; } dev->dev_port = i; @@ -178,7 +185,7 @@ pr_err("IO region %xh-%xh already allocated\n", ioaddr, ioaddr + cm->size - 1); ret = -EBUSY; - goto out_port; + goto err_free_arcdev; } /* Dummy access after Reset @@ -206,76 +213,79 @@ if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) lp->backplane = 1; - /* Get the dev_id from the PLX rotary coder */ - if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) - dev_id_mask = 0x3; - dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; - - snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); + if (ci->flags & ARC_HAS_ROTARY) { + /* Get the dev_id from the PLX rotary coder */ + if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) + dev_id_mask = 0x3; + dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; + snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); + } if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { pr_err("IO address %Xh is empty!\n", ioaddr); ret = -EIO; - goto out_port; + goto err_free_arcdev; } if (com20020_check(dev)) { ret = -EIO; - goto out_port; + goto err_free_arcdev; } + ret = com20020_found(dev, IRQF_SHARED); + if (ret) + goto err_free_arcdev; + card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), GFP_KERNEL); if (!card) { ret = -ENOMEM; - goto out_port; + goto err_free_arcdev; } card->index = i; card->pci_priv = priv; - card->tx_led.brightness_set = led_tx_set; - card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, - GFP_KERNEL, "arc%d-%d-tx", - dev->dev_id, i); - card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, - "pci:green:tx:%d-%d", - dev->dev_id, i); - - card->tx_led.dev = &dev->dev; - card->recon_led.brightness_set = led_recon_set; - card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, - GFP_KERNEL, "arc%d-%d-recon", - dev->dev_id, i); - card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, - "pci:red:recon:%d-%d", - dev->dev_id, i); - card->recon_led.dev = &dev->dev; - card->dev = dev; - - ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); - if (ret) - goto out_port; - - ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); - if (ret) - goto out_port; - dev_set_drvdata(&dev->dev, card); + if (ci->flags & ARC_HAS_LED) { + card->tx_led.brightness_set = led_tx_set; + card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "arc%d-%d-tx", + dev->dev_id, i); + card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "pci:green:tx:%d-%d", + dev->dev_id, i); + + card->tx_led.dev = &dev->dev; + card->recon_led.brightness_set = led_recon_set; + card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, + GFP_KERNEL, "arc%d-%d-recon", + dev->dev_id, i); + card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "pci:red:recon:%d-%d", + dev->dev_id, i); + card->recon_led.dev = &dev->dev; + + ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); + if (ret) + goto err_free_arcdev; + + ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); + if (ret) + goto err_free_arcdev; - ret = com20020_found(dev, IRQF_SHARED); - if (ret) - goto out_port; - - devm_arcnet_led_init(dev, dev->dev_id, i); + dev_set_drvdata(&dev->dev, card); + devm_arcnet_led_init(dev, dev->dev_id, i); + } + card->dev = dev; list_add(&card->list, &priv->list_dev); - } + continue; - pci_set_drvdata(pdev, priv); - - return 0; - -out_port: - com20020pci_remove(pdev); +err_free_arcdev: + free_arcdev(dev); + break; + } + if (ret) + com20020pci_remove(pdev); return ret; } @@ -291,7 +301,7 @@ unregister_netdev(dev); free_irq(dev->irq, dev); - free_netdev(dev); + free_arcdev(dev); } } @@ -322,7 +332,7 @@ }; static struct com20020_pci_card_info card_info_sohard = { - .name = "PLX-PCI", + .name = "SOHARD SH ARC-PCI", .devcount = 1, /* SOHARD needs PCI base addr 4 */ .chan_map_tbl = { @@ -357,7 +367,7 @@ }, }, .rotary = 0x0, - .flags = ARC_CAN_10MBIT, + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, }; static struct com20020_pci_card_info card_info_eae_ma1 = { @@ -389,7 +399,7 @@ }, }, .rotary = 0x0, - .flags = ARC_CAN_10MBIT, + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, }; static struct com20020_pci_card_info card_info_eae_fb2 = { @@ -414,7 +424,7 @@ }, }, .rotary = 0x0, - .flags = ARC_CAN_10MBIT, + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, }; static const struct pci_device_id com20020pci_id_table[] = { --- linux-oracle-5.4.0.orig/drivers/net/arcnet/com20020_cs.c +++ linux-oracle-5.4.0/drivers/net/arcnet/com20020_cs.c @@ -177,7 +177,7 @@ dev = info->dev; if (dev) { dev_dbg(&link->dev, "kfree...\n"); - free_netdev(dev); + free_arcdev(dev); } dev_dbg(&link->dev, "kfree2...\n"); kfree(info); --- linux-oracle-5.4.0.orig/drivers/net/arcnet/com90io.c +++ linux-oracle-5.4.0/drivers/net/arcnet/com90io.c @@ -396,7 +396,7 @@ err = com90io_probe(dev); if (err) { - free_netdev(dev); + free_arcdev(dev); return err; } @@ -419,7 +419,7 @@ free_irq(dev->irq, dev); release_region(dev->base_addr, ARCNET_TOTAL_SIZE); - free_netdev(dev); + free_arcdev(dev); } module_init(com90io_init) --- linux-oracle-5.4.0.orig/drivers/net/arcnet/com90xx.c +++ linux-oracle-5.4.0/drivers/net/arcnet/com90xx.c @@ -554,7 +554,7 @@ err_release_mem: release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); err_free_dev: - free_netdev(dev); + free_arcdev(dev); return -EIO; } @@ -672,7 +672,7 @@ release_region(dev->base_addr, ARCNET_TOTAL_SIZE); release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1); - free_netdev(dev); + free_arcdev(dev); } } --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_3ad.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_3ad.c @@ -233,7 +233,7 @@ if (bond == NULL) return 0; - return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; + return atomic_read(&BOND_AD_INFO(bond).agg_select_timer) ? 1 : 0; } /** @@ -1013,8 +1013,8 @@ if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { - __enable_port(port); + *update_slave_arr = true; } } break; @@ -1529,6 +1529,7 @@ slave_err(bond->dev, port->slave->dev, "Port %d did not find a suitable aggregator\n", port->actor_port_number); + return; } } /* if all aggregator's ports are READY_N == TRUE, set ready=TRUE @@ -1770,6 +1771,7 @@ port = port->next_port_in_aggregator) { __enable_port(port); } + *update_slave_arr = true; } } @@ -1984,7 +1986,7 @@ */ void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout) { - BOND_AD_INFO(bond).agg_select_timer = timeout; + atomic_set(&BOND_AD_INFO(bond).agg_select_timer, timeout); } /** @@ -1996,30 +1998,24 @@ */ void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution) { - /* check that the bond is not initialized yet */ - if (!MAC_ADDRESS_EQUAL(&(BOND_AD_INFO(bond).system.sys_mac_addr), - bond->dev->dev_addr)) { - - BOND_AD_INFO(bond).aggregator_identifier = 0; - - BOND_AD_INFO(bond).system.sys_priority = - bond->params.ad_actor_sys_prio; - if (is_zero_ether_addr(bond->params.ad_actor_system)) - BOND_AD_INFO(bond).system.sys_mac_addr = - *((struct mac_addr *)bond->dev->dev_addr); - else - BOND_AD_INFO(bond).system.sys_mac_addr = - *((struct mac_addr *)bond->params.ad_actor_system); + BOND_AD_INFO(bond).aggregator_identifier = 0; + BOND_AD_INFO(bond).system.sys_priority = + bond->params.ad_actor_sys_prio; + if (is_zero_ether_addr(bond->params.ad_actor_system)) + BOND_AD_INFO(bond).system.sys_mac_addr = + *((struct mac_addr *)bond->dev->dev_addr); + else + BOND_AD_INFO(bond).system.sys_mac_addr = + *((struct mac_addr *)bond->params.ad_actor_system); - /* initialize how many times this module is called in one - * second (should be about every 100ms) - */ - ad_ticks_per_sec = tick_resolution; + /* initialize how many times this module is called in one + * second (should be about every 100ms) + */ + ad_ticks_per_sec = tick_resolution; - bond_3ad_initiate_agg_selection(bond, - AD_AGGREGATOR_SELECTION_TIMER * - ad_ticks_per_sec); - } + bond_3ad_initiate_agg_selection(bond, + AD_AGGREGATOR_SELECTION_TIMER * + ad_ticks_per_sec); } /** @@ -2217,7 +2213,8 @@ temp_aggregator->num_of_ports--; if (__agg_active_ports(temp_aggregator) == 0) { select_new_active_agg = temp_aggregator->is_active; - ad_clear_agg(temp_aggregator); + if (temp_aggregator->num_of_ports == 0) + ad_clear_agg(temp_aggregator); if (select_new_active_agg) { slave_info(bond->dev, slave->dev, "Removing an active aggregator\n"); /* select new active aggregator */ @@ -2268,6 +2265,28 @@ } /** + * bond_agg_timer_advance - advance agg_select_timer + * @bond: bonding structure + * + * Return true when agg_select_timer reaches 0. + */ +static bool bond_agg_timer_advance(struct bonding *bond) +{ + int val, nval; + + while (1) { + val = atomic_read(&BOND_AD_INFO(bond).agg_select_timer); + if (!val) + return false; + nval = val - 1; + if (atomic_cmpxchg(&BOND_AD_INFO(bond).agg_select_timer, + val, nval) == val) + break; + } + return nval == 0; +} + +/** * bond_3ad_state_machine_handler - handle state machines timeout * @bond: bonding struct to work on * @@ -2302,9 +2321,7 @@ if (!bond_has_slaves(bond)) goto re_arm; - /* check if agg_select_timer timer after initialize is timed out */ - if (BOND_AD_INFO(bond).agg_select_timer && - !(--BOND_AD_INFO(bond).agg_select_timer)) { + if (bond_agg_timer_advance(bond)) { slave = bond_first_slave_rcu(bond); port = slave ? &(SLAVE_AD_INFO(slave)->port) : NULL; --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_alb.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_alb.c @@ -50,11 +50,6 @@ }; #pragma pack() -static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) -{ - return (struct arp_pkt *)skb_network_header(skb); -} - /* Forward declaration */ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], bool strict_match); @@ -553,10 +548,11 @@ spin_unlock(&bond->mode_lock); } -static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond) +static struct slave *rlb_choose_channel(struct sk_buff *skb, + struct bonding *bond, + const struct arp_pkt *arp) { struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); - struct arp_pkt *arp = arp_pkt(skb); struct slave *assigned_slave, *curr_active_slave; struct rlb_client_info *client_info; u32 hash_index = 0; @@ -653,18 +649,22 @@ */ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) { - struct arp_pkt *arp = arp_pkt(skb); struct slave *tx_slave = NULL; + struct arp_pkt *arp; - /* Don't modify or load balance ARPs that do not originate locally - * (e.g.,arrive via a bridge). + if (!pskb_network_may_pull(skb, sizeof(*arp))) + return NULL; + arp = (struct arp_pkt *)skb_network_header(skb); + + /* Don't modify or load balance ARPs that do not originate + * from the bond itself or a VLAN directly above the bond. */ - if (!bond_slave_has_mac_rx(bond, arp->mac_src)) + if (!bond_slave_has_mac_rcu(bond, arp->mac_src)) return NULL; if (arp->op_code == htons(ARPOP_REPLY)) { /* the arp must be sent on the selected rx channel */ - tx_slave = rlb_choose_channel(skb, bond); + tx_slave = rlb_choose_channel(skb, bond, arp); if (tx_slave) bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr, tx_slave->dev->addr_len); @@ -676,7 +676,7 @@ * When the arp reply is received the entry will be updated * with the correct unicast address of the client. */ - tx_slave = rlb_choose_channel(skb, bond); + tx_slave = rlb_choose_channel(skb, bond, arp); /* The ARP reply packets must be delayed so that * they can cancel out the influence of the ARP request. @@ -970,7 +970,8 @@ if (netif_is_macvlan(upper) && !strict_match) { tags = bond_verify_device_path(bond->dev, upper, 0); if (IS_ERR_OR_NULL(tags)) - BUG(); + return -ENOMEM; + alb_send_lp_vid(slave, upper->dev_addr, tags[0].vlan_proto, tags[0].vlan_id); kfree(tags); @@ -1276,12 +1277,12 @@ return res; if (rlb_enabled) { - bond->alb_info.rlb_enabled = 1; res = rlb_initialize(bond); if (res) { tlb_deinitialize(bond); return res; } + bond->alb_info.rlb_enabled = 1; } else { bond->alb_info.rlb_enabled = 0; } @@ -1360,7 +1361,7 @@ struct bond_up_slave *slaves; unsigned int count; - slaves = rcu_dereference(bond->slave_arr); + slaves = rcu_dereference(bond->usable_slaves); count = slaves ? READ_ONCE(slaves->count) : 0; if (likely(count)) tx_slave = slaves->arr[hash_index % @@ -1383,26 +1384,31 @@ bool do_tx_balance = true; u32 hash_index = 0; const u8 *hash_start = NULL; - struct ipv6hdr *ip6hdr; skb_reset_mac_header(skb); eth_data = eth_hdr(skb); switch (ntohs(skb->protocol)) { case ETH_P_IP: { - const struct iphdr *iph = ip_hdr(skb); + const struct iphdr *iph; if (is_broadcast_ether_addr(eth_data->h_dest) || - iph->daddr == ip_bcast || - iph->protocol == IPPROTO_IGMP) { + !pskb_network_may_pull(skb, sizeof(*iph))) { + do_tx_balance = false; + break; + } + iph = ip_hdr(skb); + if (iph->daddr == ip_bcast || iph->protocol == IPPROTO_IGMP) { do_tx_balance = false; break; } hash_start = (char *)&(iph->daddr); hash_size = sizeof(iph->daddr); - } break; - case ETH_P_IPV6: + } + case ETH_P_IPV6: { + const struct ipv6hdr *ip6hdr; + /* IPv6 doesn't really use broadcast mac address, but leave * that here just in case. */ @@ -1419,7 +1425,11 @@ break; } - /* Additianally, DAD probes should not be tx-balanced as that + if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) { + do_tx_balance = false; + break; + } + /* Additionally, DAD probes should not be tx-balanced as that * will lead to false positives for duplicate addresses and * prevent address configuration from working. */ @@ -1429,17 +1439,26 @@ break; } - hash_start = (char *)&(ipv6_hdr(skb)->daddr); - hash_size = sizeof(ipv6_hdr(skb)->daddr); + hash_start = (char *)&ip6hdr->daddr; + hash_size = sizeof(ip6hdr->daddr); break; - case ETH_P_IPX: - if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) { + } + case ETH_P_IPX: { + const struct ipxhdr *ipxhdr; + + if (pskb_network_may_pull(skb, sizeof(*ipxhdr))) { + do_tx_balance = false; + break; + } + ipxhdr = (struct ipxhdr *)skb_network_header(skb); + + if (ipxhdr->ipx_checksum != IPX_NO_CHECKSUM) { /* something is wrong with this packet */ do_tx_balance = false; break; } - if (ipx_hdr(skb)->ipx_type != IPX_TYPE_NCP) { + if (ipxhdr->ipx_type != IPX_TYPE_NCP) { /* The only protocol worth balancing in * this family since it has an "ARP" like * mechanism @@ -1448,9 +1467,11 @@ break; } + eth_data = eth_hdr(skb); hash_start = (char *)eth_data->h_dest; hash_size = ETH_ALEN; break; + } case ETH_P_ARP: do_tx_balance = false; if (bond_info->rlb_enabled) @@ -1474,7 +1495,7 @@ struct bond_up_slave *slaves; unsigned int count; - slaves = rcu_dereference(bond->slave_arr); + slaves = rcu_dereference(bond->usable_slaves); count = slaves ? READ_ONCE(slaves->count) : 0; if (likely(count)) tx_slave = slaves->arr[bond_xmit_hash(bond, skb) % @@ -1494,14 +1515,14 @@ struct slave *slave; if (!bond_has_slaves(bond)) { - bond_info->tx_rebalance_counter = 0; + atomic_set(&bond_info->tx_rebalance_counter, 0); bond_info->lp_counter = 0; goto re_arm; } rcu_read_lock(); - bond_info->tx_rebalance_counter++; + atomic_inc(&bond_info->tx_rebalance_counter); bond_info->lp_counter++; /* send learning packets */ @@ -1523,7 +1544,7 @@ } /* rebalance tx traffic */ - if (bond_info->tx_rebalance_counter >= BOND_TLB_REBALANCE_TICKS) { + if (atomic_read(&bond_info->tx_rebalance_counter) >= BOND_TLB_REBALANCE_TICKS) { bond_for_each_slave_rcu(bond, slave, iter) { tlb_clear_slave(bond, slave, 1); if (slave == rcu_access_pointer(bond->curr_active_slave)) { @@ -1533,7 +1554,7 @@ bond_info->unbalanced_load = 0; } } - bond_info->tx_rebalance_counter = 0; + atomic_set(&bond_info->tx_rebalance_counter, 0); } if (bond_info->rlb_enabled) { @@ -1603,7 +1624,8 @@ tlb_init_slave(slave); /* order a rebalance ASAP */ - bond->alb_info.tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; + atomic_set(&bond->alb_info.tx_rebalance_counter, + BOND_TLB_REBALANCE_TICKS); if (bond->alb_info.rlb_enabled) bond->alb_info.rlb_rebalance = 1; @@ -1640,7 +1662,8 @@ rlb_clear_slave(bond, slave); } else if (link == BOND_LINK_UP) { /* order a rebalance ASAP */ - bond_info->tx_rebalance_counter = BOND_TLB_REBALANCE_TICKS; + atomic_set(&bond_info->tx_rebalance_counter, + BOND_TLB_REBALANCE_TICKS); if (bond->alb_info.rlb_enabled) { bond->alb_info.rlb_rebalance = 1; /* If the updelay module parameter is smaller than the --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_debugfs.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_debugfs.c @@ -76,7 +76,7 @@ d = debugfs_rename(bonding_debug_root, bond->debug_dir, bonding_debug_root, bond->dev->name); - if (d) { + if (!IS_ERR(d)) { bond->debug_dir = d; } else { netdev_warn(bond->dev, "failed to reregister, so just unregister old one\n"); --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_main.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_main.c @@ -784,16 +784,10 @@ return bestslave; } +/* must be called in RCU critical section or with RTNL held */ static bool bond_should_notify_peers(struct bonding *bond) { - struct slave *slave; - - rcu_read_lock(); - slave = rcu_dereference(bond->curr_active_slave); - rcu_read_unlock(); - - netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", - slave ? slave->dev->name : "NULL"); + struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); if (!slave || !bond->send_peer_notif || bond->send_peer_notif % @@ -802,6 +796,9 @@ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) return false; + netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", + slave ? slave->dev->name : "NULL"); + return true; } @@ -1144,14 +1141,26 @@ static void bond_setup_by_slave(struct net_device *bond_dev, struct net_device *slave_dev) { + bool was_up = !!(bond_dev->flags & IFF_UP); + + dev_close(bond_dev); + bond_dev->header_ops = slave_dev->header_ops; bond_dev->type = slave_dev->type; bond_dev->hard_header_len = slave_dev->hard_header_len; + bond_dev->needed_headroom = slave_dev->needed_headroom; bond_dev->addr_len = slave_dev->addr_len; memcpy(bond_dev->broadcast, slave_dev->broadcast, slave_dev->addr_len); + + if (slave_dev->flags & IFF_POINTOPOINT) { + bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } + if (was_up) + dev_open(bond_dev, NULL); } /* On bonding slaves other than the currently active slave, suppress @@ -1218,7 +1227,7 @@ skb->dev = bond->dev; if (BOND_MODE(bond) == BOND_MODE_ALB && - bond->dev->priv_flags & IFF_BRIDGE_PORT && + netif_is_bridge_port(bond->dev) && skb->pkt_type == PACKET_HOST) { if (unlikely(skb_cow_head(skb, @@ -1292,7 +1301,39 @@ slave->dev->flags &= ~IFF_SLAVE; } -static struct slave *bond_alloc_slave(struct bonding *bond) +static void slave_kobj_release(struct kobject *kobj) +{ + struct slave *slave = to_slave(kobj); + struct bonding *bond = bond_get_bond_by_slave(slave); + + cancel_delayed_work_sync(&slave->notify_work); + if (BOND_MODE(bond) == BOND_MODE_8023AD) + kfree(SLAVE_AD_INFO(slave)); + + kfree(slave); +} + +static struct kobj_type slave_ktype = { + .release = slave_kobj_release, +#ifdef CONFIG_SYSFS + .sysfs_ops = &slave_sysfs_ops, +#endif +}; + +static int bond_kobj_init(struct slave *slave) +{ + int err; + + err = kobject_init_and_add(&slave->kobj, &slave_ktype, + &(slave->dev->dev.kobj), "bonding_slave"); + if (err) + kobject_put(&slave->kobj); + + return err; +} + +static struct slave *bond_alloc_slave(struct bonding *bond, + struct net_device *slave_dev) { struct slave *slave = NULL; @@ -1300,30 +1341,25 @@ if (!slave) return NULL; + slave->bond = bond; + slave->dev = slave_dev; + INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); + + if (bond_kobj_init(slave)) + return NULL; + if (BOND_MODE(bond) == BOND_MODE_8023AD) { SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info), GFP_KERNEL); if (!SLAVE_AD_INFO(slave)) { - kfree(slave); + kobject_put(&slave->kobj); return NULL; } } - INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); return slave; } -static void bond_free_slave(struct slave *slave) -{ - struct bonding *bond = bond_get_bond_by_slave(slave); - - cancel_delayed_work_sync(&slave->notify_work); - if (BOND_MODE(bond) == BOND_MODE_8023AD) - kfree(SLAVE_AD_INFO(slave)); - - kfree(slave); -} - static void bond_fill_ifbond(struct bonding *bond, struct ifbond *info) { info->bond_mode = BOND_MODE(bond); @@ -1507,14 +1543,12 @@ goto err_undo_flags; } - new_slave = bond_alloc_slave(bond); + new_slave = bond_alloc_slave(bond, slave_dev); if (!new_slave) { res = -ENOMEM; goto err_undo_flags; } - new_slave->bond = bond; - new_slave->dev = slave_dev; /* Set the new_slave's queue_id to be zero. Queue ID mapping * is set via sysfs or module option if desired. */ @@ -1836,7 +1870,7 @@ dev_set_mtu(slave_dev, new_slave->original_mtu); err_free: - bond_free_slave(new_slave); + kobject_put(&new_slave->kobj); err_undo_flags: /* Enslave of first slave has failed and we need to fix master's mac */ @@ -1900,7 +1934,6 @@ /* recompute stats just before removing the slave */ bond_get_stats(bond->dev, &bond->bond_stats); - bond_upper_dev_unlink(bond, slave); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ @@ -1909,6 +1942,8 @@ if (BOND_MODE(bond) == BOND_MODE_8023AD) bond_3ad_unbind_slave(slave); + bond_upper_dev_unlink(bond, slave); + if (bond_mode_can_use_xmit_hash(bond)) bond_update_slave_arr(bond, slave); @@ -1952,10 +1987,9 @@ bond_select_active_slave(bond); } - if (!bond_has_slaves(bond)) { - bond_set_carrier(bond); + bond_set_carrier(bond); + if (!bond_has_slaves(bond)) eth_hw_addr_random(bond_dev); - } unblock_netpoll_tx(); synchronize_rcu(); @@ -2016,7 +2050,7 @@ if (!netif_is_bond_master(slave_dev)) slave_dev->priv_flags &= ~IFF_BONDING; - bond_free_slave(slave); + kobject_put(&slave->kobj); return 0; } @@ -2037,7 +2071,8 @@ int ret; ret = __bond_release_one(bond_dev, slave_dev, false, true); - if (ret == 0 && !bond_has_slaves(bond)) { + if (ret == 0 && !bond_has_slaves(bond) && + bond_dev->reg_state != NETREG_UNREGISTERING) { bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; netdev_info(bond_dev, "Destroying bond\n"); bond_remove_proc_entry(bond); @@ -2075,12 +2110,21 @@ /* called with rcu_read_lock() */ static int bond_miimon_inspect(struct bonding *bond) { + bool ignore_updelay = false; int link_state, commit = 0; struct list_head *iter; struct slave *slave; - bool ignore_updelay; - ignore_updelay = !rcu_dereference(bond->curr_active_slave); + if (BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP) { + ignore_updelay = !rcu_dereference(bond->curr_active_slave); + } else { + struct bond_up_slave *usable_slaves; + + usable_slaves = rcu_dereference(bond->usable_slaves); + + if (usable_slaves && usable_slaves->count == 0) + ignore_updelay = true; + } bond_for_each_slave_rcu(bond, slave, iter) { bond_propose_link_state(slave, BOND_LINK_NOCHANGE); @@ -2225,9 +2269,6 @@ } else if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { /* make it immediately active */ bond_set_active_slave(slave); - } else if (slave != primary) { - /* prevent it from being the active one */ - bond_set_backup_slave(slave); } slave_info(bond->dev, slave->dev, "link status definitely up, %u Mbps %s duplex\n", @@ -2780,6 +2821,9 @@ if (bond_time_in_interval(bond, last_rx, 1)) { bond_propose_link_state(slave, BOND_LINK_UP); commit++; + } else if (slave->link == BOND_LINK_BACK) { + bond_propose_link_state(slave, BOND_LINK_FAIL); + commit++; } continue; } @@ -2888,6 +2932,19 @@ continue; + case BOND_LINK_FAIL: + bond_set_slave_link_state(slave, BOND_LINK_FAIL, + BOND_SLAVE_NOTIFY_NOW); + bond_set_slave_inactive_flags(slave, + BOND_SLAVE_NOTIFY_NOW); + + /* A slave has just been enslaved and has become + * the current active slave. + */ + if (rtnl_dereference(bond->curr_active_slave)) + RCU_INIT_POINTER(bond->current_arp_slave, NULL); + continue; + default: slave_err(bond->dev, slave->dev, "impossible: link_new_state %d on slave\n", @@ -2938,8 +2995,6 @@ return should_notify_rtnl; } - bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER); - bond_for_each_slave_rcu(bond, slave, iter) { if (!found && !before && bond_slave_is_up(slave)) before = slave; @@ -3033,9 +3088,11 @@ if (!rtnl_trylock()) return; - if (should_notify_peers) + if (should_notify_peers) { + bond->send_peer_notif--; call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, bond->dev); + } if (should_notify_rtnl) { bond_slave_state_notify(bond); bond_slave_link_notify(bond); @@ -3190,7 +3247,11 @@ unblock_netpoll_tx(); break; case NETDEV_FEAT_CHANGE: - bond_compute_features(bond); + if (!bond->notifier_ctx) { + bond->notifier_ctx = true; + bond_compute_features(bond); + bond->notifier_ctx = false; + } break; case NETDEV_RESEND_IGMP: /* Propagate to master device */ @@ -3439,6 +3500,47 @@ } } +#ifdef CONFIG_LOCKDEP +static int bond_get_lowest_level_rcu(struct net_device *dev) +{ + struct net_device *ldev, *next, *now, *dev_stack[MAX_NEST_DEV + 1]; + struct list_head *niter, *iter, *iter_stack[MAX_NEST_DEV + 1]; + int cur = 0, max = 0; + + now = dev; + iter = &dev->adj_list.lower; + + while (1) { + next = NULL; + while (1) { + ldev = netdev_next_lower_dev_rcu(now, &iter); + if (!ldev) + break; + + next = ldev; + niter = &ldev->adj_list.lower; + dev_stack[cur] = now; + iter_stack[cur++] = iter; + if (max <= cur) + max = cur; + break; + } + + if (!next) { + if (!cur) + return max; + next = dev_stack[--cur]; + niter = iter_stack[cur]; + } + + now = next; + iter = niter; + } + + return max; +} +#endif + static void bond_get_stats(struct net_device *bond_dev, struct rtnl_link_stats64 *stats) { @@ -3446,11 +3548,17 @@ struct rtnl_link_stats64 temp; struct list_head *iter; struct slave *slave; + int nest_level = 0; - spin_lock(&bond->stats_lock); - memcpy(stats, &bond->bond_stats, sizeof(*stats)); rcu_read_lock(); +#ifdef CONFIG_LOCKDEP + nest_level = bond_get_lowest_level_rcu(bond_dev); +#endif + + spin_lock_nested(&bond->stats_lock, nest_level); + memcpy(stats, &bond->bond_stats, sizeof(*stats)); + bond_for_each_slave_rcu(bond, slave, iter) { const struct rtnl_link_stats64 *new = dev_get_stats(slave->dev, &temp); @@ -3460,10 +3568,10 @@ /* save off the slave stats for the next run */ memcpy(&slave->slave_stats, new, sizeof(*new)); } - rcu_read_unlock(); memcpy(&bond->bond_stats, stats, sizeof(*stats)); spin_unlock(&bond->stats_lock); + rcu_read_unlock(); } static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) @@ -3553,6 +3661,8 @@ case BOND_RELEASE_OLD: case SIOCBONDRELEASE: res = bond_release(bond_dev, slave_dev); + if (!res) + netdev_update_lockdep_key(slave_dev); break; case BOND_SETHWADDR_OLD: case SIOCBONDSETHWADDR: @@ -3612,32 +3722,35 @@ const struct net_device_ops *slave_ops; struct neigh_parms parms; struct slave *slave; - int ret; + int ret = 0; - slave = bond_first_slave(bond); + rcu_read_lock(); + slave = bond_first_slave_rcu(bond); if (!slave) - return 0; + goto out; slave_ops = slave->dev->netdev_ops; if (!slave_ops->ndo_neigh_setup) - return 0; - - parms.neigh_setup = NULL; - parms.neigh_cleanup = NULL; - ret = slave_ops->ndo_neigh_setup(slave->dev, &parms); - if (ret) - return ret; + goto out; - /* Assign slave's neigh_cleanup to neighbour in case cleanup is called - * after the last slave has been detached. Assumes that all slaves - * utilize the same neigh_cleanup (true at this writing as only user - * is ipoib). + /* TODO: find another way [1] to implement this. + * Passing a zeroed structure is fragile, + * but at least we do not pass garbage. + * + * [1] One way would be that ndo_neigh_setup() never touch + * struct neigh_parms, but propagate the new neigh_setup() + * back to ___neigh_create() / neigh_parms_alloc() */ - n->parms->neigh_cleanup = parms.neigh_cleanup; + memset(&parms, 0, sizeof(parms)); + ret = slave_ops->ndo_neigh_setup(slave->dev, &parms); - if (!parms.neigh_setup) - return 0; + if (ret) + goto out; - return parms.neigh_setup(n); + if (parms.neigh_setup) + ret = parms.neigh_setup(n); +out: + rcu_read_unlock(); + return ret; } /* The bonding ndo_neigh_setup is called at init time beofre any @@ -3948,6 +4061,29 @@ bond_slave_arr_work_rearm(bond, 1); } +static void bond_skip_slave(struct bond_up_slave *slaves, + struct slave *skipslave) +{ + int idx; + + /* Rare situation where caller has asked to skip a specific + * slave but allocation failed (most likely!). BTW this is + * only possible when the call is initiated from + * __bond_release_one(). In this situation; overwrite the + * skipslave entry in the array with the last entry from the + * array to avoid a situation where the xmit path may choose + * this to-be-skipped slave to send a packet out. + */ + for (idx = 0; slaves && idx < slaves->count; idx++) { + if (skipslave == slaves->arr[idx]) { + slaves->arr[idx] = + slaves->arr[slaves->count - 1]; + slaves->count--; + break; + } + } +} + /* Build the usable slaves array in control path for modes that use xmit-hash * to determine the slave interface - * (a) BOND_MODE_8023AD @@ -3958,9 +4094,9 @@ */ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) { + struct bond_up_slave *usable_slaves, *old_usable_slaves; struct slave *slave; struct list_head *iter; - struct bond_up_slave *new_arr, *old_arr; int agg_id = 0; int ret = 0; @@ -3968,11 +4104,10 @@ WARN_ON(lockdep_is_held(&bond->mode_lock)); #endif - new_arr = kzalloc(offsetof(struct bond_up_slave, arr[bond->slave_cnt]), - GFP_KERNEL); - if (!new_arr) { + usable_slaves = kzalloc(struct_size(usable_slaves, arr, + bond->slave_cnt), GFP_KERNEL); + if (!usable_slaves) { ret = -ENOMEM; - pr_err("Failed to build slave-array.\n"); goto out; } if (BOND_MODE(bond) == BOND_MODE_8023AD) { @@ -3980,14 +4115,14 @@ if (bond_3ad_get_active_agg_info(bond, &ad_info)) { pr_debug("bond_3ad_get_active_agg_info failed\n"); - kfree_rcu(new_arr, rcu); + kfree_rcu(usable_slaves, rcu); /* No active aggragator means it's not safe to use * the previous array. */ - old_arr = rtnl_dereference(bond->slave_arr); - if (old_arr) { - RCU_INIT_POINTER(bond->slave_arr, NULL); - kfree_rcu(old_arr, rcu); + old_usable_slaves = rtnl_dereference(bond->usable_slaves); + if (old_usable_slaves) { + RCU_INIT_POINTER(bond->usable_slaves, NULL); + kfree_rcu(old_usable_slaves, rcu); } goto out; } @@ -4007,37 +4142,20 @@ continue; slave_dbg(bond->dev, slave->dev, "Adding slave to tx hash array[%d]\n", - new_arr->count); + usable_slaves->count); - new_arr->arr[new_arr->count++] = slave; + usable_slaves->arr[usable_slaves->count++] = slave; } - old_arr = rtnl_dereference(bond->slave_arr); - rcu_assign_pointer(bond->slave_arr, new_arr); - if (old_arr) - kfree_rcu(old_arr, rcu); + old_usable_slaves = rtnl_dereference(bond->usable_slaves); + rcu_assign_pointer(bond->usable_slaves, usable_slaves); + if (old_usable_slaves) + kfree_rcu(old_usable_slaves, rcu); out: - if (ret != 0 && skipslave) { - int idx; + if (ret != 0 && skipslave) + bond_skip_slave(rtnl_dereference(bond->usable_slaves), + skipslave); - /* Rare situation where caller has asked to skip a specific - * slave but allocation failed (most likely!). BTW this is - * only possible when the call is initiated from - * __bond_release_one(). In this situation; overwrite the - * skipslave entry in the array with the last entry from the - * array to avoid a situation where the xmit path may choose - * this to-be-skipped slave to send a packet out. - */ - old_arr = rtnl_dereference(bond->slave_arr); - for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) { - if (skipslave == old_arr->arr[idx]) { - old_arr->arr[idx] = - old_arr->arr[old_arr->count-1]; - old_arr->count--; - break; - } - } - } return ret; } @@ -4053,7 +4171,7 @@ struct bond_up_slave *slaves; unsigned int count; - slaves = rcu_dereference(bond->slave_arr); + slaves = rcu_dereference(bond->usable_slaves); count = slaves ? READ_ONCE(slaves->count) : 0; if (likely(count)) { slave = slaves->arr[bond_xmit_hash(bond, skb) % count]; @@ -4197,13 +4315,23 @@ return ret; } +static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed) +{ + if (speed == 0 || speed == SPEED_UNKNOWN) + speed = slave->speed; + else + speed = min(speed, slave->speed); + + return speed; +} + static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, struct ethtool_link_ksettings *cmd) { struct bonding *bond = netdev_priv(bond_dev); - unsigned long speed = 0; struct list_head *iter; struct slave *slave; + u32 speed = 0; cmd->base.duplex = DUPLEX_UNKNOWN; cmd->base.port = PORT_OTHER; @@ -4215,8 +4343,13 @@ */ bond_for_each_slave(bond, slave, iter) { if (bond_slave_can_tx(slave)) { - if (slave->speed != SPEED_UNKNOWN) - speed += slave->speed; + if (slave->speed != SPEED_UNKNOWN) { + if (BOND_MODE(bond) == BOND_MODE_BROADCAST) + speed = bond_mode_bcast_speed(slave, + speed); + else + speed += slave->speed; + } if (cmd->base.duplex == DUPLEX_UNKNOWN && slave->duplex != DUPLEX_UNKNOWN) cmd->base.duplex = slave->duplex; @@ -4321,7 +4454,9 @@ bond_dev->hw_features = BOND_VLAN_FEATURES | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER; + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_STAG_RX | + NETIF_F_HW_VLAN_STAG_FILTER; bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; bond_dev->features |= bond_dev->hw_features; @@ -4345,9 +4480,9 @@ __bond_release_one(bond_dev, slave->dev, true, true); netdev_info(bond_dev, "Released all slaves\n"); - arr = rtnl_dereference(bond->slave_arr); + arr = rtnl_dereference(bond->usable_slaves); if (arr) { - RCU_INIT_POINTER(bond->slave_arr, NULL); + RCU_INIT_POINTER(bond->usable_slaves, NULL); kfree_rcu(arr, rcu); } @@ -4757,6 +4892,8 @@ if (!bond->wq) return -ENOMEM; + bond->notifier_ctx = false; + spin_lock_init(&bond->stats_lock); lockdep_register_key(&bond->stats_lock_key); lockdep_set_class(&bond->stats_lock, &bond->stats_lock_key); @@ -4815,15 +4952,19 @@ bond_dev->rtnl_link_ops = &bond_link_ops; res = register_netdevice(bond_dev); + if (res < 0) { + free_netdev(bond_dev); + rtnl_unlock(); + + return res; + } netif_carrier_off(bond_dev); bond_work_init_all(bond); rtnl_unlock(); - if (res < 0) - free_netdev(bond_dev); - return res; + return 0; } static int __net_init bond_net_init(struct net *net) --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_netlink.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_netlink.c @@ -456,11 +456,10 @@ return err; err = register_netdevice(bond_dev); - - netif_carrier_off(bond_dev); if (!err) { struct bonding *bond = netdev_priv(bond_dev); + netif_carrier_off(bond_dev); bond_work_init_all(bond); } --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_options.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_options.c @@ -1084,9 +1084,9 @@ __be32 target; if (newval->string) { - if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) { - netdev_err(bond->dev, "invalid ARP target %pI4 specified\n", - &target); + if (strlen(newval->string) < 1 || + !in4_pton(newval->string + 1, -1, (u8 *)&target, -1, NULL)) { + netdev_err(bond->dev, "invalid ARP target specified\n"); return ret; } if (newval->string[0] == '+') @@ -1398,6 +1398,8 @@ case '-': slave_dbg(bond->dev, dev, "Releasing interface\n"); ret = bond_release(bond->dev, dev); + if (!ret) + netdev_update_lockdep_key(dev); break; default: @@ -1450,7 +1452,7 @@ mac = (u8 *)&newval->value; } - if (!is_valid_ether_addr(mac)) + if (is_multicast_ether_addr(mac)) goto err; netdev_dbg(bond->dev, "Setting ad_actor_system to %pM\n", mac); --- linux-oracle-5.4.0.orig/drivers/net/bonding/bond_sysfs_slave.c +++ linux-oracle-5.4.0/drivers/net/bonding/bond_sysfs_slave.c @@ -108,20 +108,19 @@ } static SLAVE_ATTR_RO(ad_partner_oper_port_state); -static const struct slave_attribute *slave_attrs[] = { - &slave_attr_state, - &slave_attr_mii_status, - &slave_attr_link_failure_count, - &slave_attr_perm_hwaddr, - &slave_attr_queue_id, - &slave_attr_ad_aggregator_id, - &slave_attr_ad_actor_oper_port_state, - &slave_attr_ad_partner_oper_port_state, +static const struct attribute *slave_attrs[] = { + &slave_attr_state.attr, + &slave_attr_mii_status.attr, + &slave_attr_link_failure_count.attr, + &slave_attr_perm_hwaddr.attr, + &slave_attr_queue_id.attr, + &slave_attr_ad_aggregator_id.attr, + &slave_attr_ad_actor_oper_port_state.attr, + &slave_attr_ad_partner_oper_port_state.attr, NULL }; #define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr) -#define to_slave(obj) container_of(obj, struct slave, kobj) static ssize_t slave_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -132,43 +131,16 @@ return slave_attr->show(slave, buf); } -static const struct sysfs_ops slave_sysfs_ops = { +const struct sysfs_ops slave_sysfs_ops = { .show = slave_show, }; -static struct kobj_type slave_ktype = { -#ifdef CONFIG_SYSFS - .sysfs_ops = &slave_sysfs_ops, -#endif -}; - int bond_sysfs_slave_add(struct slave *slave) { - const struct slave_attribute **a; - int err; - - err = kobject_init_and_add(&slave->kobj, &slave_ktype, - &(slave->dev->dev.kobj), "bonding_slave"); - if (err) - return err; - - for (a = slave_attrs; *a; ++a) { - err = sysfs_create_file(&slave->kobj, &((*a)->attr)); - if (err) { - kobject_put(&slave->kobj); - return err; - } - } - - return 0; + return sysfs_create_files(&slave->kobj, slave_attrs); } void bond_sysfs_slave_del(struct slave *slave) { - const struct slave_attribute **a; - - for (a = slave_attrs; *a; ++a) - sysfs_remove_file(&slave->kobj, &((*a)->attr)); - - kobject_put(&slave->kobj); + sysfs_remove_files(&slave->kobj, slave_attrs); } --- linux-oracle-5.4.0.orig/drivers/net/caif/Kconfig +++ linux-oracle-5.4.0/drivers/net/caif/Kconfig @@ -10,37 +10,37 @@ depends on CAIF && TTY default n ---help--- - The CAIF TTY transport driver is a Line Discipline (ldisc) - identified as N_CAIF. When this ldisc is opened from user space - it will redirect the TTY's traffic into the CAIF stack. + The CAIF TTY transport driver is a Line Discipline (ldisc) + identified as N_CAIF. When this ldisc is opened from user space + it will redirect the TTY's traffic into the CAIF stack. config CAIF_SPI_SLAVE tristate "CAIF SPI transport driver for slave interface" depends on CAIF && HAS_DMA default n ---help--- - The CAIF Link layer SPI Protocol driver for Slave SPI interface. - This driver implements a platform driver to accommodate for a - platform specific SPI device. A sample CAIF SPI Platform device is - provided in Documentation/networking/caif/spi_porting.txt + The CAIF Link layer SPI Protocol driver for Slave SPI interface. + This driver implements a platform driver to accommodate for a + platform specific SPI device. A sample CAIF SPI Platform device is + provided in . config CAIF_SPI_SYNC bool "Next command and length in start of frame" depends on CAIF_SPI_SLAVE default n ---help--- - Putting the next command and length in the start of the frame can - help to synchronize to the next transfer in case of over or under-runs. - This option also needs to be enabled on the modem. + Putting the next command and length in the start of the frame can + help to synchronize to the next transfer in case of over or under-runs. + This option also needs to be enabled on the modem. config CAIF_HSI - tristate "CAIF HSI transport driver" - depends on CAIF - default n - ---help--- - The caif low level driver for CAIF over HSI. - Be aware that if you enable this then you also need to - enable a low-level HSI driver. + tristate "CAIF HSI transport driver" + depends on CAIF + default n + ---help--- + The CAIF low level driver for CAIF over HSI. + Be aware that if you enable this then you also need to + enable a low-level HSI driver. config CAIF_VIRTIO tristate "CAIF virtio transport driver" @@ -50,7 +50,7 @@ select GENERIC_ALLOCATOR default n ---help--- - The caif driver for CAIF over Virtio. + The CAIF driver for CAIF over Virtio. if CAIF_VIRTIO source "drivers/vhost/Kconfig.vringh" --- linux-oracle-5.4.0.orig/drivers/net/caif/caif_serial.c +++ linux-oracle-5.4.0/drivers/net/caif/caif_serial.c @@ -270,7 +270,6 @@ { struct ser_device *ser; - BUG_ON(dev == NULL); ser = netdev_priv(dev); /* Send flow off once, on high water mark */ @@ -352,6 +351,7 @@ rtnl_lock(); result = register_netdevice(dev); if (result) { + tty_kref_put(tty); rtnl_unlock(); free_netdev(dev); return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/net/caif/caif_virtio.c +++ linux-oracle-5.4.0/drivers/net/caif/caif_virtio.c @@ -723,13 +723,21 @@ /* Carrier is off until netdevice is opened */ netif_carrier_off(netdev); + /* serialize netdev register + virtio_device_ready() with ndo_open() */ + rtnl_lock(); + /* register Netdev */ - err = register_netdev(netdev); + err = register_netdevice(netdev); if (err) { + rtnl_unlock(); dev_err(&vdev->dev, "Unable to register netdev (%d)\n", err); goto err; } + virtio_device_ready(vdev); + + rtnl_unlock(); + debugfs_init(cfv); return 0; @@ -738,7 +746,7 @@ if (cfv->vr_rx) vdev->vringh_config->del_vrhs(cfv->vdev); - if (cfv->vdev) + if (cfv->vq_tx) vdev->config->del_vqs(cfv->vdev); free_netdev(netdev); return err; --- linux-oracle-5.4.0.orig/drivers/net/can/Kconfig +++ linux-oracle-5.4.0/drivers/net/can/Kconfig @@ -123,6 +123,7 @@ config CAN_KVASER_PCIEFD depends on PCI tristate "Kvaser PCIe FD cards" + select CRC32 help This is a driver for the Kvaser PCI Express CAN FD family. --- linux-oracle-5.4.0.orig/drivers/net/can/Makefile +++ linux-oracle-5.4.0/drivers/net/can/Makefile @@ -7,12 +7,7 @@ obj-$(CONFIG_CAN_VXCAN) += vxcan.o obj-$(CONFIG_CAN_SLCAN) += slcan.o -obj-$(CONFIG_CAN_DEV) += can-dev.o -can-dev-y += dev.o -can-dev-y += rx-offload.o - -can-dev-$(CONFIG_CAN_LEDS) += led.o - +obj-y += dev/ obj-y += rcar/ obj-y += spi/ obj-y += usb/ --- linux-oracle-5.4.0.orig/drivers/net/can/c_can/c_can.c +++ linux-oracle-5.4.0/drivers/net/can/c_can/c_can.c @@ -212,18 +212,6 @@ .brp_inc = 1, }; -static inline void c_can_pm_runtime_enable(const struct c_can_priv *priv) -{ - if (priv->device) - pm_runtime_enable(priv->device); -} - -static inline void c_can_pm_runtime_disable(const struct c_can_priv *priv) -{ - if (priv->device) - pm_runtime_disable(priv->device); -} - static inline void c_can_pm_runtime_get_sync(const struct c_can_priv *priv) { if (priv->device) @@ -1013,7 +1001,6 @@ /* common for all type of bus errors */ priv->can.can_stats.bus_error++; - stats->rx_errors++; /* propagate the error condition to the CAN stack */ skb = alloc_can_err_skb(dev, &cf); @@ -1030,26 +1017,32 @@ case LEC_STUFF_ERROR: netdev_dbg(dev, "stuff error\n"); cf->data[2] |= CAN_ERR_PROT_STUFF; + stats->rx_errors++; break; case LEC_FORM_ERROR: netdev_dbg(dev, "form error\n"); cf->data[2] |= CAN_ERR_PROT_FORM; + stats->rx_errors++; break; case LEC_ACK_ERROR: netdev_dbg(dev, "ack error\n"); cf->data[3] = CAN_ERR_PROT_LOC_ACK; + stats->tx_errors++; break; case LEC_BIT1_ERROR: netdev_dbg(dev, "bit1 error\n"); cf->data[2] |= CAN_ERR_PROT_BIT1; + stats->tx_errors++; break; case LEC_BIT0_ERROR: netdev_dbg(dev, "bit0 error\n"); cf->data[2] |= CAN_ERR_PROT_BIT0; + stats->tx_errors++; break; case LEC_CRC_ERROR: netdev_dbg(dev, "CRC error\n"); cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ; + stats->rx_errors++; break; default: break; @@ -1334,7 +1327,6 @@ int register_c_can_dev(struct net_device *dev) { - struct c_can_priv *priv = netdev_priv(dev); int err; /* Deactivate pins to prevent DRA7 DCAN IP from being @@ -1344,28 +1336,19 @@ */ pinctrl_pm_select_sleep_state(dev->dev.parent); - c_can_pm_runtime_enable(priv); - dev->flags |= IFF_ECHO; /* we support local echo */ dev->netdev_ops = &c_can_netdev_ops; err = register_candev(dev); - if (err) - c_can_pm_runtime_disable(priv); - else + if (!err) devm_can_led_init(dev); - return err; } EXPORT_SYMBOL_GPL(register_c_can_dev); void unregister_c_can_dev(struct net_device *dev) { - struct c_can_priv *priv = netdev_priv(dev); - unregister_candev(dev); - - c_can_pm_runtime_disable(priv); } EXPORT_SYMBOL_GPL(unregister_c_can_dev); --- linux-oracle-5.4.0.orig/drivers/net/can/c_can/c_can_pci.c +++ linux-oracle-5.4.0/drivers/net/can/c_can/c_can_pci.c @@ -239,12 +239,13 @@ { struct net_device *dev = pci_get_drvdata(pdev); struct c_can_priv *priv = netdev_priv(dev); + void __iomem *addr = priv->base; unregister_c_can_dev(dev); free_c_can_dev(dev); - pci_iounmap(pdev, priv->base); + pci_iounmap(pdev, addr); pci_disable_msi(pdev); pci_clear_master(pdev); pci_release_regions(pdev); --- linux-oracle-5.4.0.orig/drivers/net/can/c_can/c_can_platform.c +++ linux-oracle-5.4.0/drivers/net/can/c_can/c_can_platform.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -385,17 +386,20 @@ platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); + pm_runtime_enable(priv->device); ret = register_c_can_dev(dev); if (ret) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", KBUILD_MODNAME, ret); - goto exit_free_device; + goto exit_pm_runtime; } dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", KBUILD_MODNAME, priv->base, dev->irq); return 0; +exit_pm_runtime: + pm_runtime_disable(priv->device); exit_free_device: free_c_can_dev(dev); exit: @@ -407,9 +411,10 @@ static int c_can_plat_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); + struct c_can_priv *priv = netdev_priv(dev); unregister_c_can_dev(dev); - + pm_runtime_disable(priv->device); free_c_can_dev(dev); return 0; --- linux-oracle-5.4.0.orig/drivers/net/can/cc770/cc770_isa.c +++ linux-oracle-5.4.0/drivers/net/can/cc770/cc770_isa.c @@ -264,22 +264,24 @@ if (err) { dev_err(&pdev->dev, "couldn't register device (err=%d)\n", err); - goto exit_unmap; + goto exit_free; } dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n", priv->reg_base, dev->irq); return 0; - exit_unmap: +exit_free: + free_cc770dev(dev); +exit_unmap: if (mem[idx]) iounmap(base); - exit_release: +exit_release: if (mem[idx]) release_mem_region(mem[idx], iosize); else release_region(port[idx], iosize); - exit: +exit: return err; } --- linux-oracle-5.4.0.orig/drivers/net/can/dev/Makefile +++ linux-oracle-5.4.0/drivers/net/can/dev/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_CAN_DEV) += can-dev.o +can-dev-y += dev.o +can-dev-y += rx-offload.o + +can-dev-$(CONFIG_CAN_LEDS) += led.o --- linux-oracle-5.4.0.orig/drivers/net/can/dev/dev.c +++ linux-oracle-5.4.0/drivers/net/can/dev/dev.c @@ -0,0 +1,1314 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix + * Copyright (C) 2006 Andrey Volkov, Varma Electronics + * Copyright (C) 2008-2009 Wolfgang Grandegger + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MOD_DESC "CAN device driver interface" + +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Wolfgang Grandegger "); + +/* CAN DLC to real data length conversion helpers */ + +static const u8 dlc2len[] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 12, 16, 20, 24, 32, 48, 64}; + +/* get data length from can_dlc with sanitized can_dlc */ +u8 can_dlc2len(u8 can_dlc) +{ + return dlc2len[can_dlc & 0x0F]; +} +EXPORT_SYMBOL_GPL(can_dlc2len); + +static const u8 len2dlc[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, /* 0 - 8 */ + 9, 9, 9, 9, /* 9 - 12 */ + 10, 10, 10, 10, /* 13 - 16 */ + 11, 11, 11, 11, /* 17 - 20 */ + 12, 12, 12, 12, /* 21 - 24 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 25 - 32 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* 33 - 40 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* 41 - 48 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 49 - 56 */ + 15, 15, 15, 15, 15, 15, 15, 15}; /* 57 - 64 */ + +/* map the sanitized data length to an appropriate data length code */ +u8 can_len2dlc(u8 len) +{ + if (unlikely(len > 64)) + return 0xF; + + return len2dlc[len]; +} +EXPORT_SYMBOL_GPL(can_len2dlc); + +#ifdef CONFIG_CAN_CALC_BITTIMING +#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ +#define CAN_CALC_SYNC_SEG 1 + +/* Bit-timing calculation derived from: + * + * Code based on LinCAN sources and H8S2638 project + * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz + * Copyright 2005 Stanislav Marek + * email: pisa@cmp.felk.cvut.cz + * + * Calculates proper bit-timing parameters for a specified bit-rate + * and sample-point, which can then be used to set the bit-timing + * registers of the CAN controller. You can find more information + * in the header file linux/can/netlink.h. + */ +static int +can_update_sample_point(const struct can_bittiming_const *btc, + unsigned int sample_point_nominal, unsigned int tseg, + unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, + unsigned int *sample_point_error_ptr) +{ + unsigned int sample_point_error, best_sample_point_error = UINT_MAX; + unsigned int sample_point, best_sample_point = 0; + unsigned int tseg1, tseg2; + int i; + + for (i = 0; i <= 1; i++) { + tseg2 = tseg + CAN_CALC_SYNC_SEG - + (sample_point_nominal * (tseg + CAN_CALC_SYNC_SEG)) / + 1000 - i; + tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); + tseg1 = tseg - tseg2; + if (tseg1 > btc->tseg1_max) { + tseg1 = btc->tseg1_max; + tseg2 = tseg - tseg1; + } + + sample_point = 1000 * (tseg + CAN_CALC_SYNC_SEG - tseg2) / + (tseg + CAN_CALC_SYNC_SEG); + sample_point_error = abs(sample_point_nominal - sample_point); + + if (sample_point <= sample_point_nominal && + sample_point_error < best_sample_point_error) { + best_sample_point = sample_point; + best_sample_point_error = sample_point_error; + *tseg1_ptr = tseg1; + *tseg2_ptr = tseg2; + } + } + + if (sample_point_error_ptr) + *sample_point_error_ptr = best_sample_point_error; + + return best_sample_point; +} + +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) +{ + struct can_priv *priv = netdev_priv(dev); + unsigned int bitrate; /* current bitrate */ + unsigned int bitrate_error; /* difference between current and nominal value */ + unsigned int best_bitrate_error = UINT_MAX; + unsigned int sample_point_error; /* difference between current and nominal value */ + unsigned int best_sample_point_error = UINT_MAX; + unsigned int sample_point_nominal; /* nominal sample point */ + unsigned int best_tseg = 0; /* current best value for tseg */ + unsigned int best_brp = 0; /* current best value for brp */ + unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; + u64 v64; + + /* Use CiA recommended sample points */ + if (bt->sample_point) { + sample_point_nominal = bt->sample_point; + } else { + if (bt->bitrate > 800000) + sample_point_nominal = 750; + else if (bt->bitrate > 500000) + sample_point_nominal = 800; + else + sample_point_nominal = 875; + } + + /* tseg even = round down, odd = round up */ + for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; + tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { + tsegall = CAN_CALC_SYNC_SEG + tseg / 2; + + /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ + brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; + + /* choose brp step which is possible in system */ + brp = (brp / btc->brp_inc) * btc->brp_inc; + if (brp < btc->brp_min || brp > btc->brp_max) + continue; + + bitrate = priv->clock.freq / (brp * tsegall); + bitrate_error = abs(bt->bitrate - bitrate); + + /* tseg brp biterror */ + if (bitrate_error > best_bitrate_error) + continue; + + /* reset sample point error if we have a better bitrate */ + if (bitrate_error < best_bitrate_error) + best_sample_point_error = UINT_MAX; + + can_update_sample_point(btc, sample_point_nominal, tseg / 2, + &tseg1, &tseg2, &sample_point_error); + if (sample_point_error > best_sample_point_error) + continue; + + best_sample_point_error = sample_point_error; + best_bitrate_error = bitrate_error; + best_tseg = tseg / 2; + best_brp = brp; + + if (bitrate_error == 0 && sample_point_error == 0) + break; + } + + if (best_bitrate_error) { + /* Error in one-tenth of a percent */ + v64 = (u64)best_bitrate_error * 1000; + do_div(v64, bt->bitrate); + bitrate_error = (u32)v64; + if (bitrate_error > CAN_CALC_MAX_ERROR) { + netdev_err(dev, + "bitrate error %d.%d%% too high\n", + bitrate_error / 10, bitrate_error % 10); + return -EDOM; + } + netdev_warn(dev, "bitrate error %d.%d%%\n", + bitrate_error / 10, bitrate_error % 10); + } + + /* real sample point */ + bt->sample_point = can_update_sample_point(btc, sample_point_nominal, + best_tseg, &tseg1, &tseg2, + NULL); + + v64 = (u64)best_brp * 1000 * 1000 * 1000; + do_div(v64, priv->clock.freq); + bt->tq = (u32)v64; + bt->prop_seg = tseg1 / 2; + bt->phase_seg1 = tseg1 - bt->prop_seg; + bt->phase_seg2 = tseg2; + + /* check for sjw user settings */ + if (!bt->sjw || !btc->sjw_max) { + bt->sjw = 1; + } else { + /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ + if (bt->sjw > btc->sjw_max) + bt->sjw = btc->sjw_max; + /* bt->sjw must not be higher than tseg2 */ + if (tseg2 < bt->sjw) + bt->sjw = tseg2; + } + + bt->brp = best_brp; + + /* real bitrate */ + bt->bitrate = priv->clock.freq / + (bt->brp * (CAN_CALC_SYNC_SEG + tseg1 + tseg2)); + + return 0; +} +#else /* !CONFIG_CAN_CALC_BITTIMING */ +static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) +{ + netdev_err(dev, "bit-timing calculation not available\n"); + return -EINVAL; +} +#endif /* CONFIG_CAN_CALC_BITTIMING */ + +/* Checks the validity of the specified bit-timing parameters prop_seg, + * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate + * prescaler value brp. You can find more information in the header + * file linux/can/netlink.h. + */ +static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc) +{ + struct can_priv *priv = netdev_priv(dev); + int tseg1, alltseg; + u64 brp64; + + tseg1 = bt->prop_seg + bt->phase_seg1; + if (!bt->sjw) + bt->sjw = 1; + if (bt->sjw > btc->sjw_max || + tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max || + bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max) + return -ERANGE; + + brp64 = (u64)priv->clock.freq * (u64)bt->tq; + if (btc->brp_inc > 1) + do_div(brp64, btc->brp_inc); + brp64 += 500000000UL - 1; + do_div(brp64, 1000000000UL); /* the practicable BRP */ + if (btc->brp_inc > 1) + brp64 *= btc->brp_inc; + bt->brp = (u32)brp64; + + if (bt->brp < btc->brp_min || bt->brp > btc->brp_max) + return -EINVAL; + + alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1; + bt->bitrate = priv->clock.freq / (bt->brp * alltseg); + bt->sample_point = ((tseg1 + 1) * 1000) / alltseg; + + return 0; +} + +/* Checks the validity of predefined bitrate settings */ +static int +can_validate_bitrate(struct net_device *dev, struct can_bittiming *bt, + const u32 *bitrate_const, + const unsigned int bitrate_const_cnt) +{ + struct can_priv *priv = netdev_priv(dev); + unsigned int i; + + for (i = 0; i < bitrate_const_cnt; i++) { + if (bt->bitrate == bitrate_const[i]) + break; + } + + if (i >= priv->bitrate_const_cnt) + return -EINVAL; + + return 0; +} + +static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, + const struct can_bittiming_const *btc, + const u32 *bitrate_const, + const unsigned int bitrate_const_cnt) +{ + int err; + + /* Depending on the given can_bittiming parameter structure the CAN + * timing parameters are calculated based on the provided bitrate OR + * alternatively the CAN timing parameters (tq, prop_seg, etc.) are + * provided directly which are then checked and fixed up. + */ + if (!bt->tq && bt->bitrate && btc) + err = can_calc_bittiming(dev, bt, btc); + else if (bt->tq && !bt->bitrate && btc) + err = can_fixup_bittiming(dev, bt, btc); + else if (!bt->tq && bt->bitrate && bitrate_const) + err = can_validate_bitrate(dev, bt, bitrate_const, + bitrate_const_cnt); + else + err = -EINVAL; + + return err; +} + +static void can_update_state_error_stats(struct net_device *dev, + enum can_state new_state) +{ + struct can_priv *priv = netdev_priv(dev); + + if (new_state <= priv->state) + return; + + switch (new_state) { + case CAN_STATE_ERROR_WARNING: + priv->can_stats.error_warning++; + break; + case CAN_STATE_ERROR_PASSIVE: + priv->can_stats.error_passive++; + break; + case CAN_STATE_BUS_OFF: + priv->can_stats.bus_off++; + break; + default: + break; + } +} + +static int can_tx_state_to_frame(struct net_device *dev, enum can_state state) +{ + switch (state) { + case CAN_STATE_ERROR_ACTIVE: + return CAN_ERR_CRTL_ACTIVE; + case CAN_STATE_ERROR_WARNING: + return CAN_ERR_CRTL_TX_WARNING; + case CAN_STATE_ERROR_PASSIVE: + return CAN_ERR_CRTL_TX_PASSIVE; + default: + return 0; + } +} + +static int can_rx_state_to_frame(struct net_device *dev, enum can_state state) +{ + switch (state) { + case CAN_STATE_ERROR_ACTIVE: + return CAN_ERR_CRTL_ACTIVE; + case CAN_STATE_ERROR_WARNING: + return CAN_ERR_CRTL_RX_WARNING; + case CAN_STATE_ERROR_PASSIVE: + return CAN_ERR_CRTL_RX_PASSIVE; + default: + return 0; + } +} + +void can_change_state(struct net_device *dev, struct can_frame *cf, + enum can_state tx_state, enum can_state rx_state) +{ + struct can_priv *priv = netdev_priv(dev); + enum can_state new_state = max(tx_state, rx_state); + + if (unlikely(new_state == priv->state)) { + netdev_warn(dev, "%s: oops, state did not change", __func__); + return; + } + + netdev_dbg(dev, "New error state: %d\n", new_state); + + can_update_state_error_stats(dev, new_state); + priv->state = new_state; + + if (!cf) + return; + + if (unlikely(new_state == CAN_STATE_BUS_OFF)) { + cf->can_id |= CAN_ERR_BUSOFF; + return; + } + + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] |= tx_state >= rx_state ? + can_tx_state_to_frame(dev, tx_state) : 0; + cf->data[1] |= tx_state <= rx_state ? + can_rx_state_to_frame(dev, rx_state) : 0; +} +EXPORT_SYMBOL_GPL(can_change_state); + +/* Local echo of CAN messages + * + * CAN network devices *should* support a local echo functionality + * (see Documentation/networking/can.rst). To test the handling of CAN + * interfaces that do not support the local echo both driver types are + * implemented. In the case that the driver does not support the echo + * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core + * to perform the echo as a fallback solution. + */ +static void can_flush_echo_skb(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + int i; + + for (i = 0; i < priv->echo_skb_max; i++) { + if (priv->echo_skb[i]) { + kfree_skb(priv->echo_skb[i]); + priv->echo_skb[i] = NULL; + stats->tx_dropped++; + stats->tx_aborted_errors++; + } + } +} + +/* Put the skb on the stack to be looped backed locally lateron + * + * The function is typically called in the start_xmit function + * of the device driver. The driver must protect access to + * priv->echo_skb, if necessary. + */ +void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, + unsigned int idx) +{ + struct can_priv *priv = netdev_priv(dev); + + BUG_ON(idx >= priv->echo_skb_max); + + /* check flag whether this packet has to be looped back */ + if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK || + (skb->protocol != htons(ETH_P_CAN) && + skb->protocol != htons(ETH_P_CANFD))) { + kfree_skb(skb); + return; + } + + if (!priv->echo_skb[idx]) { + skb = can_create_echo_skb(skb); + if (!skb) + return; + + /* make settings for echo to reduce code in irq context */ + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; + skb->dev = dev; + + /* save this skb for tx interrupt echo handling */ + priv->echo_skb[idx] = skb; + } else { + /* locking problem with netif_stop_queue() ?? */ + netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__); + kfree_skb(skb); + } +} +EXPORT_SYMBOL_GPL(can_put_echo_skb); + +struct sk_buff * +__can_get_echo_skb(struct net_device *dev, unsigned int idx, u8 *len_ptr) +{ + struct can_priv *priv = netdev_priv(dev); + + if (idx >= priv->echo_skb_max) { + netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n", + __func__, idx, priv->echo_skb_max); + return NULL; + } + + if (priv->echo_skb[idx]) { + /* Using "struct canfd_frame::len" for the frame + * length is supported on both CAN and CANFD frames. + */ + struct sk_buff *skb = priv->echo_skb[idx]; + struct canfd_frame *cf = (struct canfd_frame *)skb->data; + + /* get the real payload length for netdev statistics */ + if (cf->can_id & CAN_RTR_FLAG) + *len_ptr = 0; + else + *len_ptr = cf->len; + + priv->echo_skb[idx] = NULL; + + return skb; + } + + return NULL; +} + +/* Get the skb from the stack and loop it back locally + * + * The function is typically called when the TX done interrupt + * is handled in the device driver. The driver must protect + * access to priv->echo_skb, if necessary. + */ +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) +{ + struct sk_buff *skb; + u8 len; + + skb = __can_get_echo_skb(dev, idx, &len); + if (!skb) + return 0; + + skb_get(skb); + if (netif_rx(skb) == NET_RX_SUCCESS) + dev_consume_skb_any(skb); + else + dev_kfree_skb_any(skb); + + return len; +} +EXPORT_SYMBOL_GPL(can_get_echo_skb); + +/* Remove the skb from the stack and free it. + * + * The function is typically called when TX failed. + */ +void can_free_echo_skb(struct net_device *dev, unsigned int idx) +{ + struct can_priv *priv = netdev_priv(dev); + + BUG_ON(idx >= priv->echo_skb_max); + + if (priv->echo_skb[idx]) { + dev_kfree_skb_any(priv->echo_skb[idx]); + priv->echo_skb[idx] = NULL; + } +} +EXPORT_SYMBOL_GPL(can_free_echo_skb); + +/* CAN device restart for bus-off recovery */ +static void can_restart(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + struct can_frame *cf; + int err; + + if (netif_carrier_ok(dev)) + netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n"); + + /* No synchronization needed because the device is bus-off and + * no messages can come in or go out. + */ + can_flush_echo_skb(dev); + + /* send restart message upstream */ + skb = alloc_can_err_skb(dev, &cf); + if (!skb) { + err = -ENOMEM; + goto restart; + } + cf->can_id |= CAN_ERR_RESTARTED; + + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + + netif_rx_ni(skb); + +restart: + netdev_dbg(dev, "restarted\n"); + priv->can_stats.restarts++; + + /* Now restart the device */ + netif_carrier_on(dev); + err = priv->do_set_mode(dev, CAN_MODE_START); + if (err) { + netdev_err(dev, "Error %d during restart", err); + netif_carrier_off(dev); + } +} + +static void can_restart_work(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct can_priv *priv = container_of(dwork, struct can_priv, + restart_work); + + can_restart(priv->dev); +} + +int can_restart_now(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + /* A manual restart is only permitted if automatic restart is + * disabled and the device is in the bus-off state + */ + if (priv->restart_ms) + return -EINVAL; + if (priv->state != CAN_STATE_BUS_OFF) + return -EBUSY; + + cancel_delayed_work_sync(&priv->restart_work); + can_restart(dev); + + return 0; +} + +/* CAN bus-off + * + * This functions should be called when the device goes bus-off to + * tell the netif layer that no more packets can be sent or received. + * If enabled, a timer is started to trigger bus-off recovery. + */ +void can_bus_off(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + netdev_info(dev, "bus-off\n"); + + netif_carrier_off(dev); + + if (priv->restart_ms) + schedule_delayed_work(&priv->restart_work, + msecs_to_jiffies(priv->restart_ms)); +} +EXPORT_SYMBOL_GPL(can_bus_off); + +static void can_setup(struct net_device *dev) +{ + dev->type = ARPHRD_CAN; + dev->mtu = CAN_MTU; + dev->hard_header_len = 0; + dev->addr_len = 0; + dev->tx_queue_len = 10; + + /* New-style flags. */ + dev->flags = IFF_NOARP; + dev->features = NETIF_F_HW_CSUM; +} + +struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf) +{ + struct sk_buff *skb; + + skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + + sizeof(struct can_frame)); + if (unlikely(!skb)) + return NULL; + + skb->protocol = htons(ETH_P_CAN); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; + + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + + can_skb_reserve(skb); + can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; + + *cf = skb_put_zero(skb, sizeof(struct can_frame)); + + return skb; +} +EXPORT_SYMBOL_GPL(alloc_can_skb); + +struct sk_buff *alloc_canfd_skb(struct net_device *dev, + struct canfd_frame **cfd) +{ + struct sk_buff *skb; + + skb = netdev_alloc_skb(dev, sizeof(struct can_skb_priv) + + sizeof(struct canfd_frame)); + if (unlikely(!skb)) + return NULL; + + skb->protocol = htons(ETH_P_CANFD); + skb->pkt_type = PACKET_BROADCAST; + skb->ip_summed = CHECKSUM_UNNECESSARY; + + skb_reset_mac_header(skb); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + + can_skb_reserve(skb); + can_skb_prv(skb)->ifindex = dev->ifindex; + can_skb_prv(skb)->skbcnt = 0; + + *cfd = skb_put_zero(skb, sizeof(struct canfd_frame)); + + return skb; +} +EXPORT_SYMBOL_GPL(alloc_canfd_skb); + +struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf) +{ + struct sk_buff *skb; + + skb = alloc_can_skb(dev, cf); + if (unlikely(!skb)) + return NULL; + + (*cf)->can_id = CAN_ERR_FLAG; + (*cf)->can_dlc = CAN_ERR_DLC; + + return skb; +} +EXPORT_SYMBOL_GPL(alloc_can_err_skb); + +/* Allocate and setup space for the CAN network device */ +struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max, + unsigned int txqs, unsigned int rxqs) +{ + struct can_ml_priv *can_ml; + struct net_device *dev; + struct can_priv *priv; + int size; + + /* We put the driver's priv, the CAN mid layer priv and the + * echo skb into the netdevice's priv. The memory layout for + * the netdev_priv is like this: + * + * +-------------------------+ + * | driver's priv | + * +-------------------------+ + * | struct can_ml_priv | + * +-------------------------+ + * | array of struct sk_buff | + * +-------------------------+ + */ + + size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv); + + if (echo_skb_max) + size = ALIGN(size, sizeof(struct sk_buff *)) + + echo_skb_max * sizeof(struct sk_buff *); + + dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup, + txqs, rxqs); + if (!dev) + return NULL; + + priv = netdev_priv(dev); + priv->dev = dev; + + can_ml = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN); + can_set_ml_priv(dev, can_ml); + + if (echo_skb_max) { + priv->echo_skb_max = echo_skb_max; + priv->echo_skb = (void *)priv + + (size - echo_skb_max * sizeof(struct sk_buff *)); + } + + priv->state = CAN_STATE_STOPPED; + + INIT_DELAYED_WORK(&priv->restart_work, can_restart_work); + + return dev; +} +EXPORT_SYMBOL_GPL(alloc_candev_mqs); + +/* Free space of the CAN network device */ +void free_candev(struct net_device *dev) +{ + free_netdev(dev); +} +EXPORT_SYMBOL_GPL(free_candev); + +/* changing MTU and control mode for CAN/CANFD devices */ +int can_change_mtu(struct net_device *dev, int new_mtu) +{ + struct can_priv *priv = netdev_priv(dev); + + /* Do not allow changing the MTU while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* allow change of MTU according to the CANFD ability of the device */ + switch (new_mtu) { + case CAN_MTU: + /* 'CANFD-only' controllers can not switch to CAN_MTU */ + if (priv->ctrlmode_static & CAN_CTRLMODE_FD) + return -EINVAL; + + priv->ctrlmode &= ~CAN_CTRLMODE_FD; + break; + + case CANFD_MTU: + /* check for potential CANFD ability */ + if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) && + !(priv->ctrlmode_static & CAN_CTRLMODE_FD)) + return -EINVAL; + + priv->ctrlmode |= CAN_CTRLMODE_FD; + break; + + default: + return -EINVAL; + } + + dev->mtu = new_mtu; + return 0; +} +EXPORT_SYMBOL_GPL(can_change_mtu); + +/* Common open function when the device gets opened. + * + * This function should be called in the open function of the device + * driver. + */ +int open_candev(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + if (!priv->bittiming.bitrate) { + netdev_err(dev, "bit-timing not yet defined\n"); + return -EINVAL; + } + + /* For CAN FD the data bitrate has to be >= the arbitration bitrate */ + if ((priv->ctrlmode & CAN_CTRLMODE_FD) && + (!priv->data_bittiming.bitrate || + priv->data_bittiming.bitrate < priv->bittiming.bitrate)) { + netdev_err(dev, "incorrect/missing data bit-timing\n"); + return -EINVAL; + } + + /* Switch carrier on if device was stopped while in bus-off state */ + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(open_candev); + +#ifdef CONFIG_OF +/* Common function that can be used to understand the limitation of + * a transceiver when it provides no means to determine these limitations + * at runtime. + */ +void of_can_transceiver(struct net_device *dev) +{ + struct device_node *dn; + struct can_priv *priv = netdev_priv(dev); + struct device_node *np = dev->dev.parent->of_node; + int ret; + + dn = of_get_child_by_name(np, "can-transceiver"); + if (!dn) + return; + + ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max); + of_node_put(dn); + if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max)) + netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n"); +} +EXPORT_SYMBOL_GPL(of_can_transceiver); +#endif + +/* Common close function for cleanup before the device gets closed. + * + * This function should be called in the close function of the device + * driver. + */ +void close_candev(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + cancel_delayed_work_sync(&priv->restart_work); + can_flush_echo_skb(dev); +} +EXPORT_SYMBOL_GPL(close_candev); + +/* CAN netlink interface */ +static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { + [IFLA_CAN_STATE] = { .type = NLA_U32 }, + [IFLA_CAN_CTRLMODE] = { .len = sizeof(struct can_ctrlmode) }, + [IFLA_CAN_RESTART_MS] = { .type = NLA_U32 }, + [IFLA_CAN_RESTART] = { .type = NLA_U32 }, + [IFLA_CAN_BITTIMING] = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, + [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, + [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) }, + [IFLA_CAN_DATA_BITTIMING] + = { .len = sizeof(struct can_bittiming) }, + [IFLA_CAN_DATA_BITTIMING_CONST] + = { .len = sizeof(struct can_bittiming_const) }, + [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, +}; + +static int can_validate(struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + bool is_can_fd = false; + + /* Make sure that valid CAN FD configurations always consist of + * - nominal/arbitration bittiming + * - data bittiming + * - control mode with CAN_CTRLMODE_FD set + */ + + if (!data) + return 0; + + if (data[IFLA_CAN_CTRLMODE]) { + struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); + + is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD; + } + + if (is_can_fd) { + if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING]) + return -EOPNOTSUPP; + } + + if (data[IFLA_CAN_DATA_BITTIMING]) { + if (!is_can_fd || !data[IFLA_CAN_BITTIMING]) + return -EOPNOTSUPP; + } + + return 0; +} + +static int can_changelink(struct net_device *dev, struct nlattr *tb[], + struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + struct can_priv *priv = netdev_priv(dev); + int err; + + /* We need synchronization with dev->stop() */ + ASSERT_RTNL(); + + if (data[IFLA_CAN_BITTIMING]) { + struct can_bittiming bt; + + /* Do not allow changing bittiming while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* Calculate bittiming parameters based on + * bittiming_const if set, otherwise pass bitrate + * directly via do_set_bitrate(). Bail out if neither + * is given. + */ + if (!priv->bittiming_const && !priv->do_set_bittiming) + return -EOPNOTSUPP; + + memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt)); + err = can_get_bittiming(dev, &bt, + priv->bittiming_const, + priv->bitrate_const, + priv->bitrate_const_cnt); + if (err) + return err; + + if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) { + netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n", + priv->bitrate_max); + return -EINVAL; + } + + memcpy(&priv->bittiming, &bt, sizeof(bt)); + + if (priv->do_set_bittiming) { + /* Finally, set the bit-timing registers */ + err = priv->do_set_bittiming(dev); + if (err) + return err; + } + } + + if (data[IFLA_CAN_CTRLMODE]) { + struct can_ctrlmode *cm; + u32 ctrlstatic; + u32 maskedflags; + + /* Do not allow changing controller mode while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + cm = nla_data(data[IFLA_CAN_CTRLMODE]); + ctrlstatic = priv->ctrlmode_static; + maskedflags = cm->flags & cm->mask; + + /* check whether provided bits are allowed to be passed */ + if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic)) + return -EOPNOTSUPP; + + /* do not check for static fd-non-iso if 'fd' is disabled */ + if (!(maskedflags & CAN_CTRLMODE_FD)) + ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO; + + /* make sure static options are provided by configuration */ + if ((maskedflags & ctrlstatic) != ctrlstatic) + return -EOPNOTSUPP; + + /* clear bits to be modified and copy the flag values */ + priv->ctrlmode &= ~cm->mask; + priv->ctrlmode |= maskedflags; + + /* CAN_CTRLMODE_FD can only be set when driver supports FD */ + if (priv->ctrlmode & CAN_CTRLMODE_FD) + dev->mtu = CANFD_MTU; + else + dev->mtu = CAN_MTU; + } + + if (data[IFLA_CAN_RESTART_MS]) { + /* Do not allow changing restart delay while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]); + } + + if (data[IFLA_CAN_RESTART]) { + /* Do not allow a restart while not running */ + if (!(dev->flags & IFF_UP)) + return -EINVAL; + err = can_restart_now(dev); + if (err) + return err; + } + + if (data[IFLA_CAN_DATA_BITTIMING]) { + struct can_bittiming dbt; + + /* Do not allow changing bittiming while running */ + if (dev->flags & IFF_UP) + return -EBUSY; + + /* Calculate bittiming parameters based on + * data_bittiming_const if set, otherwise pass bitrate + * directly via do_set_bitrate(). Bail out if neither + * is given. + */ + if (!priv->data_bittiming_const && !priv->do_set_data_bittiming) + return -EOPNOTSUPP; + + memcpy(&dbt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), + sizeof(dbt)); + err = can_get_bittiming(dev, &dbt, + priv->data_bittiming_const, + priv->data_bitrate_const, + priv->data_bitrate_const_cnt); + if (err) + return err; + + if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { + netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n", + priv->bitrate_max); + return -EINVAL; + } + + memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); + + if (priv->do_set_data_bittiming) { + /* Finally, set the bit-timing registers */ + err = priv->do_set_data_bittiming(dev); + if (err) + return err; + } + } + + if (data[IFLA_CAN_TERMINATION]) { + const u16 termval = nla_get_u16(data[IFLA_CAN_TERMINATION]); + const unsigned int num_term = priv->termination_const_cnt; + unsigned int i; + + if (!priv->do_set_termination) + return -EOPNOTSUPP; + + /* check whether given value is supported by the interface */ + for (i = 0; i < num_term; i++) { + if (termval == priv->termination_const[i]) + break; + } + if (i >= num_term) + return -EINVAL; + + /* Finally, set the termination value */ + err = priv->do_set_termination(dev, termval); + if (err) + return err; + + priv->termination = termval; + } + + return 0; +} + +static size_t can_get_size(const struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + size_t size = 0; + + if (priv->bittiming.bitrate) /* IFLA_CAN_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); + if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ + size += nla_total_size(sizeof(struct can_bittiming_const)); + size += nla_total_size(sizeof(struct can_clock)); /* IFLA_CAN_CLOCK */ + size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */ + size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */ + size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ + if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */ + size += nla_total_size(sizeof(struct can_berr_counter)); + if (priv->data_bittiming.bitrate) /* IFLA_CAN_DATA_BITTIMING */ + size += nla_total_size(sizeof(struct can_bittiming)); + if (priv->data_bittiming_const) /* IFLA_CAN_DATA_BITTIMING_CONST */ + size += nla_total_size(sizeof(struct can_bittiming_const)); + if (priv->termination_const) { + size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */ + size += nla_total_size(sizeof(*priv->termination_const) * /* IFLA_CAN_TERMINATION_CONST */ + priv->termination_const_cnt); + } + if (priv->bitrate_const) /* IFLA_CAN_BITRATE_CONST */ + size += nla_total_size(sizeof(*priv->bitrate_const) * + priv->bitrate_const_cnt); + if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ + size += nla_total_size(sizeof(*priv->data_bitrate_const) * + priv->data_bitrate_const_cnt); + size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */ + + return size; +} + +static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + struct can_ctrlmode cm = {.flags = priv->ctrlmode}; + struct can_berr_counter bec = { }; + enum can_state state = priv->state; + + if (priv->do_get_state) + priv->do_get_state(dev, &state); + + if ((priv->bittiming.bitrate && + nla_put(skb, IFLA_CAN_BITTIMING, + sizeof(priv->bittiming), &priv->bittiming)) || + + (priv->bittiming_const && + nla_put(skb, IFLA_CAN_BITTIMING_CONST, + sizeof(*priv->bittiming_const), priv->bittiming_const)) || + + nla_put(skb, IFLA_CAN_CLOCK, sizeof(priv->clock), &priv->clock) || + nla_put_u32(skb, IFLA_CAN_STATE, state) || + nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) || + nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) || + + (priv->do_get_berr_counter && + !priv->do_get_berr_counter(dev, &bec) && + nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) || + + (priv->data_bittiming.bitrate && + nla_put(skb, IFLA_CAN_DATA_BITTIMING, + sizeof(priv->data_bittiming), &priv->data_bittiming)) || + + (priv->data_bittiming_const && + nla_put(skb, IFLA_CAN_DATA_BITTIMING_CONST, + sizeof(*priv->data_bittiming_const), + priv->data_bittiming_const)) || + + (priv->termination_const && + (nla_put_u16(skb, IFLA_CAN_TERMINATION, priv->termination) || + nla_put(skb, IFLA_CAN_TERMINATION_CONST, + sizeof(*priv->termination_const) * + priv->termination_const_cnt, + priv->termination_const))) || + + (priv->bitrate_const && + nla_put(skb, IFLA_CAN_BITRATE_CONST, + sizeof(*priv->bitrate_const) * + priv->bitrate_const_cnt, + priv->bitrate_const)) || + + (priv->data_bitrate_const && + nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST, + sizeof(*priv->data_bitrate_const) * + priv->data_bitrate_const_cnt, + priv->data_bitrate_const)) || + + (nla_put(skb, IFLA_CAN_BITRATE_MAX, + sizeof(priv->bitrate_max), + &priv->bitrate_max)) + ) + + return -EMSGSIZE; + + return 0; +} + +static size_t can_get_xstats_size(const struct net_device *dev) +{ + return sizeof(struct can_device_stats); +} + +static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + if (nla_put(skb, IFLA_INFO_XSTATS, + sizeof(priv->can_stats), &priv->can_stats)) + goto nla_put_failure; + return 0; + +nla_put_failure: + return -EMSGSIZE; +} + +static int can_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[], + struct netlink_ext_ack *extack) +{ + return -EOPNOTSUPP; +} + +static void can_dellink(struct net_device *dev, struct list_head *head) +{ +} + +static struct rtnl_link_ops can_link_ops __read_mostly = { + .kind = "can", + .netns_refund = true, + .maxtype = IFLA_CAN_MAX, + .policy = can_policy, + .setup = can_setup, + .validate = can_validate, + .newlink = can_newlink, + .changelink = can_changelink, + .dellink = can_dellink, + .get_size = can_get_size, + .fill_info = can_fill_info, + .get_xstats_size = can_get_xstats_size, + .fill_xstats = can_fill_xstats, +}; + +/* Register the CAN network device */ +int register_candev(struct net_device *dev) +{ + struct can_priv *priv = netdev_priv(dev); + + /* Ensure termination_const, termination_const_cnt and + * do_set_termination consistency. All must be either set or + * unset. + */ + if ((!priv->termination_const != !priv->termination_const_cnt) || + (!priv->termination_const != !priv->do_set_termination)) + return -EINVAL; + + if (!priv->bitrate_const != !priv->bitrate_const_cnt) + return -EINVAL; + + if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt) + return -EINVAL; + + dev->rtnl_link_ops = &can_link_ops; + netif_carrier_off(dev); + + return register_netdev(dev); +} +EXPORT_SYMBOL_GPL(register_candev); + +/* Unregister the CAN network device */ +void unregister_candev(struct net_device *dev) +{ + unregister_netdev(dev); +} +EXPORT_SYMBOL_GPL(unregister_candev); + +/* Test if a network device is a candev based device + * and return the can_priv* if so. + */ +struct can_priv *safe_candev_priv(struct net_device *dev) +{ + if (dev->type != ARPHRD_CAN || dev->rtnl_link_ops != &can_link_ops) + return NULL; + + return netdev_priv(dev); +} +EXPORT_SYMBOL_GPL(safe_candev_priv); + +static __init int can_dev_init(void) +{ + int err; + + can_led_notifier_init(); + + err = rtnl_link_register(&can_link_ops); + if (!err) + pr_info(MOD_DESC "\n"); + + return err; +} +module_init(can_dev_init); + +static __exit void can_dev_exit(void) +{ + rtnl_link_unregister(&can_link_ops); + + can_led_notifier_exit(); +} +module_exit(can_dev_exit); + +MODULE_ALIAS_RTNL_LINK("can"); --- linux-oracle-5.4.0.orig/drivers/net/can/dev/rx-offload.c +++ linux-oracle-5.4.0/drivers/net/can/dev/rx-offload.c @@ -0,0 +1,395 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014 David Jander, Protonic Holland + * Copyright (C) 2014-2017 Pengutronix, Marc Kleine-Budde + */ + +#include +#include + +struct can_rx_offload_cb { + u32 timestamp; +}; + +static inline struct can_rx_offload_cb *can_rx_offload_get_cb(struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct can_rx_offload_cb) > sizeof(skb->cb)); + + return (struct can_rx_offload_cb *)skb->cb; +} + +static inline bool can_rx_offload_le(struct can_rx_offload *offload, unsigned int a, unsigned int b) +{ + if (offload->inc) + return a <= b; + else + return a >= b; +} + +static inline unsigned int can_rx_offload_inc(struct can_rx_offload *offload, unsigned int *val) +{ + if (offload->inc) + return (*val)++; + else + return (*val)--; +} + +static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota) +{ + struct can_rx_offload *offload = container_of(napi, struct can_rx_offload, napi); + struct net_device *dev = offload->dev; + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + int work_done = 0; + + while ((work_done < quota) && + (skb = skb_dequeue(&offload->skb_queue))) { + struct can_frame *cf = (struct can_frame *)skb->data; + + work_done++; + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + netif_receive_skb(skb); + } + + if (work_done < quota) { + napi_complete_done(napi, work_done); + + /* Check if there was another interrupt */ + if (!skb_queue_empty(&offload->skb_queue)) + napi_reschedule(&offload->napi); + } + + can_led_event(offload->dev, CAN_LED_EVENT_RX); + + return work_done; +} + +static inline void __skb_queue_add_sort(struct sk_buff_head *head, struct sk_buff *new, + int (*compare)(struct sk_buff *a, struct sk_buff *b)) +{ + struct sk_buff *pos, *insert = NULL; + + skb_queue_reverse_walk(head, pos) { + const struct can_rx_offload_cb *cb_pos, *cb_new; + + cb_pos = can_rx_offload_get_cb(pos); + cb_new = can_rx_offload_get_cb(new); + + netdev_dbg(new->dev, + "%s: pos=0x%08x, new=0x%08x, diff=%10d, queue_len=%d\n", + __func__, + cb_pos->timestamp, cb_new->timestamp, + cb_new->timestamp - cb_pos->timestamp, + skb_queue_len(head)); + + if (compare(pos, new) < 0) + continue; + insert = pos; + break; + } + if (!insert) + __skb_queue_head(head, new); + else + __skb_queue_after(head, insert, new); +} + +static int can_rx_offload_compare(struct sk_buff *a, struct sk_buff *b) +{ + const struct can_rx_offload_cb *cb_a, *cb_b; + + cb_a = can_rx_offload_get_cb(a); + cb_b = can_rx_offload_get_cb(b); + + /* Substract two u32 and return result as int, to keep + * difference steady around the u32 overflow. + */ + return cb_b->timestamp - cb_a->timestamp; +} + +/** + * can_rx_offload_offload_one() - Read one CAN frame from HW + * @offload: pointer to rx_offload context + * @n: number of mailbox to read + * + * The task of this function is to read a CAN frame from mailbox @n + * from the device and return the mailbox's content as a struct + * sk_buff. + * + * If the struct can_rx_offload::skb_queue exceeds the maximal queue + * length (struct can_rx_offload::skb_queue_len_max) or no skb can be + * allocated, the mailbox contents is discarded by reading it into an + * overflow buffer. This way the mailbox is marked as free by the + * driver. + * + * Return: A pointer to skb containing the CAN frame on success. + * + * NULL if the mailbox @n is empty. + * + * ERR_PTR() in case of an error + */ +static struct sk_buff * +can_rx_offload_offload_one(struct can_rx_offload *offload, unsigned int n) +{ + struct sk_buff *skb = NULL, *skb_error = NULL; + struct can_rx_offload_cb *cb; + struct can_frame *cf; + int ret; + + if (likely(skb_queue_len(&offload->skb_queue) < + offload->skb_queue_len_max)) { + skb = alloc_can_skb(offload->dev, &cf); + if (unlikely(!skb)) + skb_error = ERR_PTR(-ENOMEM); /* skb alloc failed */ + } else { + skb_error = ERR_PTR(-ENOBUFS); /* skb_queue is full */ + } + + /* If queue is full or skb not available, drop by reading into + * overflow buffer. + */ + if (unlikely(skb_error)) { + struct can_frame cf_overflow; + u32 timestamp; + + ret = offload->mailbox_read(offload, &cf_overflow, + ×tamp, n); + + /* Mailbox was empty. */ + if (unlikely(!ret)) + return NULL; + + /* Mailbox has been read and we're dropping it or + * there was a problem reading the mailbox. + * + * Increment error counters in any case. + */ + offload->dev->stats.rx_dropped++; + offload->dev->stats.rx_fifo_errors++; + + /* There was a problem reading the mailbox, propagate + * error value. + */ + if (unlikely(ret < 0)) + return ERR_PTR(ret); + + return skb_error; + } + + cb = can_rx_offload_get_cb(skb); + ret = offload->mailbox_read(offload, cf, &cb->timestamp, n); + + /* Mailbox was empty. */ + if (unlikely(!ret)) { + kfree_skb(skb); + return NULL; + } + + /* There was a problem reading the mailbox, propagate error value. */ + if (unlikely(ret < 0)) { + kfree_skb(skb); + + offload->dev->stats.rx_dropped++; + offload->dev->stats.rx_fifo_errors++; + + return ERR_PTR(ret); + } + + /* Mailbox was read. */ + return skb; +} + +int can_rx_offload_irq_offload_timestamp(struct can_rx_offload *offload, u64 pending) +{ + struct sk_buff_head skb_queue; + unsigned int i; + + __skb_queue_head_init(&skb_queue); + + for (i = offload->mb_first; + can_rx_offload_le(offload, i, offload->mb_last); + can_rx_offload_inc(offload, &i)) { + struct sk_buff *skb; + + if (!(pending & BIT_ULL(i))) + continue; + + skb = can_rx_offload_offload_one(offload, i); + if (IS_ERR_OR_NULL(skb)) + continue; + + __skb_queue_add_sort(&skb_queue, skb, can_rx_offload_compare); + } + + if (!skb_queue_empty(&skb_queue)) { + unsigned long flags; + u32 queue_len; + + spin_lock_irqsave(&offload->skb_queue.lock, flags); + skb_queue_splice_tail(&skb_queue, &offload->skb_queue); + spin_unlock_irqrestore(&offload->skb_queue.lock, flags); + + if ((queue_len = skb_queue_len(&offload->skb_queue)) > + (offload->skb_queue_len_max / 8)) + netdev_dbg(offload->dev, "%s: queue_len=%d\n", + __func__, queue_len); + + can_rx_offload_schedule(offload); + } + + return skb_queue_len(&skb_queue); +} +EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_timestamp); + +int can_rx_offload_irq_offload_fifo(struct can_rx_offload *offload) +{ + struct sk_buff *skb; + int received = 0; + + while (1) { + skb = can_rx_offload_offload_one(offload, 0); + if (IS_ERR(skb)) + continue; + if (!skb) + break; + + skb_queue_tail(&offload->skb_queue, skb); + received++; + } + + if (received) + can_rx_offload_schedule(offload); + + return received; +} +EXPORT_SYMBOL_GPL(can_rx_offload_irq_offload_fifo); + +int can_rx_offload_queue_sorted(struct can_rx_offload *offload, + struct sk_buff *skb, u32 timestamp) +{ + struct can_rx_offload_cb *cb; + unsigned long flags; + + if (skb_queue_len(&offload->skb_queue) > + offload->skb_queue_len_max) { + dev_kfree_skb_any(skb); + return -ENOBUFS; + } + + cb = can_rx_offload_get_cb(skb); + cb->timestamp = timestamp; + + spin_lock_irqsave(&offload->skb_queue.lock, flags); + __skb_queue_add_sort(&offload->skb_queue, skb, can_rx_offload_compare); + spin_unlock_irqrestore(&offload->skb_queue.lock, flags); + + can_rx_offload_schedule(offload); + + return 0; +} +EXPORT_SYMBOL_GPL(can_rx_offload_queue_sorted); + +unsigned int can_rx_offload_get_echo_skb(struct can_rx_offload *offload, + unsigned int idx, u32 timestamp) +{ + struct net_device *dev = offload->dev; + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + u8 len; + int err; + + skb = __can_get_echo_skb(dev, idx, &len); + if (!skb) + return 0; + + err = can_rx_offload_queue_sorted(offload, skb, timestamp); + if (err) { + stats->rx_errors++; + stats->tx_fifo_errors++; + } + + return len; +} +EXPORT_SYMBOL_GPL(can_rx_offload_get_echo_skb); + +int can_rx_offload_queue_tail(struct can_rx_offload *offload, + struct sk_buff *skb) +{ + if (skb_queue_len(&offload->skb_queue) > + offload->skb_queue_len_max) { + dev_kfree_skb_any(skb); + return -ENOBUFS; + } + + skb_queue_tail(&offload->skb_queue, skb); + can_rx_offload_schedule(offload); + + return 0; +} +EXPORT_SYMBOL_GPL(can_rx_offload_queue_tail); + +static int can_rx_offload_init_queue(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) +{ + offload->dev = dev; + + /* Limit queue len to 4x the weight (rounted to next power of two) */ + offload->skb_queue_len_max = 2 << fls(weight); + offload->skb_queue_len_max *= 4; + skb_queue_head_init(&offload->skb_queue); + + can_rx_offload_reset(offload); + netif_napi_add(dev, &offload->napi, can_rx_offload_napi_poll, weight); + + dev_dbg(dev->dev.parent, "%s: skb_queue_len_max=%d\n", + __func__, offload->skb_queue_len_max); + + return 0; +} + +int can_rx_offload_add_timestamp(struct net_device *dev, struct can_rx_offload *offload) +{ + unsigned int weight; + + if (offload->mb_first > BITS_PER_LONG_LONG || + offload->mb_last > BITS_PER_LONG_LONG || !offload->mailbox_read) + return -EINVAL; + + if (offload->mb_first < offload->mb_last) { + offload->inc = true; + weight = offload->mb_last - offload->mb_first; + } else { + offload->inc = false; + weight = offload->mb_first - offload->mb_last; + } + + return can_rx_offload_init_queue(dev, offload, weight); +} +EXPORT_SYMBOL_GPL(can_rx_offload_add_timestamp); + +int can_rx_offload_add_fifo(struct net_device *dev, struct can_rx_offload *offload, unsigned int weight) +{ + if (!offload->mailbox_read) + return -EINVAL; + + return can_rx_offload_init_queue(dev, offload, weight); +} +EXPORT_SYMBOL_GPL(can_rx_offload_add_fifo); + +void can_rx_offload_enable(struct can_rx_offload *offload) +{ + can_rx_offload_reset(offload); + napi_enable(&offload->napi); +} +EXPORT_SYMBOL_GPL(can_rx_offload_enable); + +void can_rx_offload_del(struct can_rx_offload *offload) +{ + netif_napi_del(&offload->napi); + skb_queue_purge(&offload->skb_queue); +} +EXPORT_SYMBOL_GPL(can_rx_offload_del); + +void can_rx_offload_reset(struct can_rx_offload *offload) +{ +} +EXPORT_SYMBOL_GPL(can_rx_offload_reset); --- linux-oracle-5.4.0.orig/drivers/net/can/flexcan.c +++ linux-oracle-5.4.0/drivers/net/can/flexcan.c @@ -321,8 +321,7 @@ static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = { .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | - FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE | - FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, + FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, }; static const struct can_bittiming_const flexcan_bittiming_const = { @@ -389,6 +388,34 @@ (&priv->regs->mb[bank][priv->mb_size * mb_index]); } +static int flexcan_low_power_enter_ack(struct flexcan_priv *priv) +{ + struct flexcan_regs __iomem *regs = priv->regs; + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; + + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + udelay(10); + + if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + return -ETIMEDOUT; + + return 0; +} + +static int flexcan_low_power_exit_ack(struct flexcan_priv *priv) +{ + struct flexcan_regs __iomem *regs = priv->regs; + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; + + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) + udelay(10); + + if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) + return -ETIMEDOUT; + + return 0; +} + static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable) { struct flexcan_regs __iomem *regs = priv->regs; @@ -407,7 +434,6 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; - unsigned int ackval; u32 reg_mcr; reg_mcr = priv->read(®s->mcr); @@ -418,36 +444,24 @@ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); - /* get stop acknowledgment */ - if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr, - ackval, ackval & (1 << priv->stm.ack_bit), - 0, FLEXCAN_TIMEOUT_US)) - return -ETIMEDOUT; - - return 0; + return flexcan_low_power_enter_ack(priv); } static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; - unsigned int ackval; u32 reg_mcr; /* remove stop request */ regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, 1 << priv->stm.req_bit, 0); - /* get stop acknowledgment */ - if (regmap_read_poll_timeout(priv->stm.gpr, priv->stm.ack_gpr, - ackval, !(ackval & (1 << priv->stm.ack_bit)), - 0, FLEXCAN_TIMEOUT_US)) - return -ETIMEDOUT; reg_mcr = priv->read(®s->mcr); reg_mcr &= ~FLEXCAN_MCR_SLF_WAK; priv->write(reg_mcr, ®s->mcr); - return 0; + return flexcan_low_power_exit_ack(priv); } static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) @@ -506,49 +520,41 @@ static int flexcan_chip_enable(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; - unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; u32 reg; reg = priv->read(®s->mcr); reg &= ~FLEXCAN_MCR_MDIS; priv->write(reg, ®s->mcr); - while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) - udelay(10); - - if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) - return -ETIMEDOUT; - - return 0; + return flexcan_low_power_exit_ack(priv); } static int flexcan_chip_disable(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; - unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; u32 reg; reg = priv->read(®s->mcr); reg |= FLEXCAN_MCR_MDIS; priv->write(reg, ®s->mcr); - while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) - udelay(10); - - if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) - return -ETIMEDOUT; - - return 0; + return flexcan_low_power_enter_ack(priv); } static int flexcan_chip_freeze(struct flexcan_priv *priv) { struct flexcan_regs __iomem *regs = priv->regs; - unsigned int timeout = 1000 * 1000 * 10 / priv->can.bittiming.bitrate; + unsigned int timeout; + u32 bitrate = priv->can.bittiming.bitrate; u32 reg; + if (bitrate) + timeout = 1000 * 1000 * 10 / bitrate; + else + timeout = FLEXCAN_TIMEOUT_US / 10; + reg = priv->read(®s->mcr); - reg |= FLEXCAN_MCR_HALT; + reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT; priv->write(reg, ®s->mcr); while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_FRZ_ACK)) @@ -614,8 +620,10 @@ int err; err = pm_runtime_get_sync(priv->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_noidle(priv->dev); return err; + } err = __flexcan_get_berr_counter(dev, bec); @@ -1055,10 +1063,13 @@ flexcan_set_bittiming(dev); + /* set freeze, halt */ + err = flexcan_chip_freeze(priv); + if (err) + goto out_chip_disable; + /* MCR * - * enable freeze - * halt now * only supervisor access * enable warning int * enable individual RX masking @@ -1067,9 +1078,8 @@ */ reg_mcr = priv->read(®s->mcr); reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); - reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | - FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | FLEXCAN_MCR_IDAM_C | - FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); + reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); /* MCR * @@ -1200,14 +1210,10 @@ priv->write(reg_mecr, ®s->mecr); } - err = flexcan_transceiver_enable(priv); - if (err) - goto out_chip_disable; - /* synchronize with the can bus */ err = flexcan_chip_unfreeze(priv); if (err) - goto out_transceiver_disable; + goto out_chip_disable; priv->can.state = CAN_STATE_ERROR_ACTIVE; @@ -1224,25 +1230,28 @@ return 0; - out_transceiver_disable: - flexcan_transceiver_disable(priv); out_chip_disable: flexcan_chip_disable(priv); return err; } -/* flexcan_chip_stop +/* __flexcan_chip_stop * - * this functions is entered with clocks enabled + * this function is entered with clocks enabled */ -static void flexcan_chip_stop(struct net_device *dev) +static int __flexcan_chip_stop(struct net_device *dev, bool disable_on_error) { struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->regs; + int err; /* freeze + disable module */ - flexcan_chip_freeze(priv); - flexcan_chip_disable(priv); + err = flexcan_chip_freeze(priv); + if (err && !disable_on_error) + return err; + err = flexcan_chip_disable(priv); + if (err && !disable_on_error) + goto out_chip_unfreeze; /* Disable all interrupts */ priv->write(0, ®s->imask2); @@ -1250,8 +1259,24 @@ priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, ®s->ctrl); - flexcan_transceiver_disable(priv); priv->can.state = CAN_STATE_STOPPED; + + return 0; + + out_chip_unfreeze: + flexcan_chip_unfreeze(priv); + + return err; +} + +static inline int flexcan_chip_stop_disable_on_error(struct net_device *dev) +{ + return __flexcan_chip_stop(dev, true); +} + +static inline int flexcan_chip_stop(struct net_device *dev) +{ + return __flexcan_chip_stop(dev, false); } static int flexcan_open(struct net_device *dev) @@ -1260,17 +1285,23 @@ int err; err = pm_runtime_get_sync(priv->dev); - if (err < 0) + if (err < 0) { + pm_runtime_put_noidle(priv->dev); return err; + } err = open_candev(dev); if (err) goto out_runtime_put; - err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); + err = flexcan_transceiver_enable(priv); if (err) goto out_close; + err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); + if (err) + goto out_transceiver_disable; + priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + (sizeof(priv->regs->mb[1]) / priv->mb_size); @@ -1326,6 +1357,8 @@ can_rx_offload_del(&priv->offload); out_free_irq: free_irq(dev->irq, dev); + out_transceiver_disable: + flexcan_transceiver_disable(priv); out_close: close_candev(dev); out_runtime_put: @@ -1340,10 +1373,11 @@ netif_stop_queue(dev); can_rx_offload_disable(&priv->offload); - flexcan_chip_stop(dev); + flexcan_chip_stop_disable_on_error(dev); can_rx_offload_del(&priv->offload); free_irq(dev->irq, dev); + flexcan_transceiver_disable(priv); close_candev(dev); pm_runtime_put(priv->dev); @@ -1406,10 +1440,14 @@ if (err) goto out_chip_disable; - /* set freeze, halt and activate FIFO, restrict register access */ + /* set freeze, halt */ + err = flexcan_chip_freeze(priv); + if (err) + goto out_chip_disable; + + /* activate FIFO, restrict register access */ reg = priv->read(®s->mcr); - reg |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | - FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; + reg |= FLEXCAN_MCR_FEN | FLEXCAN_MCR_SUPV; priv->write(reg, ®s->mcr); /* Currently we only support newer versions of this core @@ -1654,6 +1692,8 @@ { struct net_device *dev = platform_get_drvdata(pdev); + device_set_wakeup_enable(&pdev->dev, false); + device_set_wakeup_capable(&pdev->dev, false); unregister_flexcandev(dev); pm_runtime_disable(&pdev->dev); free_candev(dev); @@ -1680,8 +1720,6 @@ err = flexcan_chip_disable(priv); if (err) return err; - - err = pm_runtime_force_suspend(device); } netif_stop_queue(dev); netif_device_detach(dev); @@ -1703,11 +1741,10 @@ netif_start_queue(dev); if (device_may_wakeup(device)) { disable_irq_wake(dev->irq); - } else { - err = pm_runtime_force_resume(device); + err = flexcan_exit_stop_mode(priv); if (err) return err; - + } else { err = flexcan_chip_enable(priv); } } @@ -1738,8 +1775,16 @@ struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); - if (netif_running(dev) && device_may_wakeup(device)) - flexcan_enable_wakeup_irq(priv, true); + if (netif_running(dev)) { + int err; + + if (device_may_wakeup(device)) + flexcan_enable_wakeup_irq(priv, true); + + err = pm_runtime_force_suspend(device); + if (err) + return err; + } return 0; } @@ -1748,13 +1793,16 @@ { struct net_device *dev = dev_get_drvdata(device); struct flexcan_priv *priv = netdev_priv(dev); - int err; - if (netif_running(dev) && device_may_wakeup(device)) { - flexcan_enable_wakeup_irq(priv, false); - err = flexcan_exit_stop_mode(priv); + if (netif_running(dev)) { + int err; + + err = pm_runtime_force_resume(device); if (err) return err; + + if (device_may_wakeup(device)) + flexcan_enable_wakeup_irq(priv, false); } return 0; --- linux-oracle-5.4.0.orig/drivers/net/can/grcan.c +++ linux-oracle-5.4.0/drivers/net/can/grcan.c @@ -241,13 +241,14 @@ .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \ } -#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100 +#define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100 #define GRLIB_VERSION_MASK 0xffff /* GRCAN private data structure */ struct grcan_priv { struct can_priv can; /* must be the first member */ struct net_device *dev; + struct device *ofdev_dev; struct napi_struct napi; struct grcan_registers __iomem *regs; /* ioremap'ed registers */ @@ -924,7 +925,7 @@ struct grcan_priv *priv = netdev_priv(dev); struct grcan_dma *dma = &priv->dma; - dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf, + dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf, dma->base_handle); memset(dma, 0, sizeof(*dma)); } @@ -949,7 +950,7 @@ /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */ dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT; - dma->base_buf = dma_alloc_coherent(&dev->dev, + dma->base_buf = dma_alloc_coherent(priv->ofdev_dev, dma->base_size, &dma->base_handle, GFP_KERNEL); @@ -1113,8 +1114,10 @@ priv->closing = true; if (priv->need_txbug_workaround) { + spin_unlock_irqrestore(&priv->lock, flags); del_timer_sync(&priv->hang_timer); del_timer_sync(&priv->rr_timer); + spin_lock_irqsave(&priv->lock, flags); } netif_stop_queue(dev); grcan_stop_hardware(dev); @@ -1134,7 +1137,7 @@ return 0; } -static int grcan_transmit_catch_up(struct net_device *dev, int budget) +static void grcan_transmit_catch_up(struct net_device *dev) { struct grcan_priv *priv = netdev_priv(dev); unsigned long flags; @@ -1142,7 +1145,7 @@ spin_lock_irqsave(&priv->lock, flags); - work_done = catch_up_echo_skb(dev, budget, true); + work_done = catch_up_echo_skb(dev, -1, true); if (work_done) { if (!priv->resetting && !priv->closing && !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) @@ -1156,8 +1159,6 @@ } spin_unlock_irqrestore(&priv->lock, flags); - - return work_done; } static int grcan_receive(struct net_device *dev, int budget) @@ -1239,19 +1240,13 @@ struct net_device *dev = priv->dev; struct grcan_registers __iomem *regs = priv->regs; unsigned long flags; - int tx_work_done, rx_work_done; - int rx_budget = budget / 2; - int tx_budget = budget - rx_budget; + int work_done; - /* Half of the budget for receiveing messages */ - rx_work_done = grcan_receive(dev, rx_budget); + work_done = grcan_receive(dev, budget); - /* Half of the budget for transmitting messages as that can trigger echo - * frames being received - */ - tx_work_done = grcan_transmit_catch_up(dev, tx_budget); + grcan_transmit_catch_up(dev); - if (rx_work_done < rx_budget && tx_work_done < tx_budget) { + if (work_done < budget) { napi_complete(napi); /* Guarantee no interference with a running reset that otherwise @@ -1268,7 +1263,7 @@ spin_unlock_irqrestore(&priv->lock, flags); } - return rx_work_done + tx_work_done; + return work_done; } /* Work tx bug by waiting while for the risky situation to clear. If that fails, @@ -1600,6 +1595,7 @@ memcpy(&priv->config, &grcan_module_config, sizeof(struct grcan_device_config)); priv->dev = dev; + priv->ofdev_dev = &ofdev->dev; priv->regs = base; priv->can.bittiming_const = &grcan_bittiming_const; priv->can.do_set_bittiming = grcan_set_bittiming; @@ -1652,6 +1648,7 @@ static int grcan_probe(struct platform_device *ofdev) { struct device_node *np = ofdev->dev.of_node; + struct device_node *sysid_parent; struct resource *res; u32 sysid, ambafreq; int irq, err; @@ -1661,10 +1658,14 @@ /* Compare GRLIB version number with the first that does not * have the tx bug (see start_xmit) */ - err = of_property_read_u32(np, "systemid", &sysid); - if (!err && ((sysid & GRLIB_VERSION_MASK) - >= GRCAN_TXBUG_SAFE_GRLIB_VERSION)) - txbug = false; + sysid_parent = of_find_node_by_path("/ambapp0"); + if (sysid_parent) { + err = of_property_read_u32(sysid_parent, "systemid", &sysid); + if (!err && ((sysid & GRLIB_VERSION_MASK) >= + GRCAN_TXBUG_SAFE_GRLIB_VERSION)) + txbug = false; + of_node_put(sysid_parent); + } err = of_property_read_u32(np, "freq", &ambafreq); if (err) { --- linux-oracle-5.4.0.orig/drivers/net/can/janz-ican3.c +++ linux-oracle-5.4.0/drivers/net/can/janz-ican3.c @@ -1451,7 +1451,7 @@ /* process all communication messages */ while (true) { - struct ican3_msg uninitialized_var(msg); + struct ican3_msg msg; ret = ican3_recv_msg(mod, &msg); if (ret) break; --- linux-oracle-5.4.0.orig/drivers/net/can/kvaser_pciefd.c +++ linux-oracle-5.4.0/drivers/net/can/kvaser_pciefd.c @@ -57,6 +57,7 @@ #define KVASER_PCIEFD_KCAN_STAT_REG 0x418 #define KVASER_PCIEFD_KCAN_MODE_REG 0x41c #define KVASER_PCIEFD_KCAN_BTRN_REG 0x420 +#define KVASER_PCIEFD_KCAN_BUS_LOAD_REG 0x424 #define KVASER_PCIEFD_KCAN_BTRD_REG 0x428 #define KVASER_PCIEFD_KCAN_PWM_REG 0x430 /* Loopback control register */ @@ -69,10 +70,12 @@ #define KVASER_PCIEFD_SYSID_BUILD_REG (KVASER_PCIEFD_SYSID_BASE + 0x14) /* Shared receive buffer registers */ #define KVASER_PCIEFD_SRB_BASE 0x1f200 +#define KVASER_PCIEFD_SRB_FIFO_LAST_REG (KVASER_PCIEFD_SRB_BASE + 0x1f4) #define KVASER_PCIEFD_SRB_CMD_REG (KVASER_PCIEFD_SRB_BASE + 0x200) #define KVASER_PCIEFD_SRB_IEN_REG (KVASER_PCIEFD_SRB_BASE + 0x204) #define KVASER_PCIEFD_SRB_IRQ_REG (KVASER_PCIEFD_SRB_BASE + 0x20c) #define KVASER_PCIEFD_SRB_STAT_REG (KVASER_PCIEFD_SRB_BASE + 0x210) +#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG (KVASER_PCIEFD_SRB_BASE + 0x214) #define KVASER_PCIEFD_SRB_CTRL_REG (KVASER_PCIEFD_SRB_BASE + 0x218) /* EPCS flash controller registers */ #define KVASER_PCIEFD_SPI_BASE 0x1fc00 @@ -109,6 +112,9 @@ /* DMA support */ #define KVASER_PCIEFD_SRB_STAT_DMA BIT(24) +/* SRB current packet level */ +#define KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK 0xff + /* DMA Enable */ #define KVASER_PCIEFD_SRB_CTRL_DMA_ENABLE BIT(0) @@ -247,6 +253,9 @@ #define KVASER_PCIEFD_SPACK_EWLR BIT(23) #define KVASER_PCIEFD_SPACK_EPLR BIT(24) +/* Kvaser KCAN_EPACK second word */ +#define KVASER_PCIEFD_EPACK_DIR_TX BIT(0) + struct kvaser_pciefd; struct kvaser_pciefd_can { @@ -287,12 +296,12 @@ static const struct can_bittiming_const kvaser_pciefd_bittiming_const = { .name = KVASER_PCIEFD_DRV_NAME, .tseg1_min = 1, - .tseg1_max = 255, + .tseg1_max = 512, .tseg2_min = 1, .tseg2_max = 32, .sjw_max = 16, .brp_min = 1, - .brp_max = 4096, + .brp_max = 8192, .brp_inc = 1, }; @@ -524,7 +533,7 @@ KVASER_PCIEFD_KCAN_IRQ_TOF | KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TAE | KVASER_PCIEFD_KCAN_IRQ_TAL | KVASER_PCIEFD_KCAN_IRQ_FDIC | KVASER_PCIEFD_KCAN_IRQ_BPP | - KVASER_PCIEFD_KCAN_IRQ_TAR | KVASER_PCIEFD_KCAN_IRQ_TFD; + KVASER_PCIEFD_KCAN_IRQ_TAR; iowrite32(msk, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); @@ -552,6 +561,8 @@ if (can->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) mode |= KVASER_PCIEFD_KCAN_MODE_LOM; + else + mode &= ~KVASER_PCIEFD_KCAN_MODE_LOM; mode |= KVASER_PCIEFD_KCAN_MODE_EEN; mode |= KVASER_PCIEFD_KCAN_MODE_EPEN; @@ -570,7 +581,7 @@ spin_lock_irqsave(&can->lock, irq); iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); - iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD, + iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); status = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_STAT_REG); @@ -613,7 +624,7 @@ iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); - iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | KVASER_PCIEFD_KCAN_IRQ_TFD, + iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); mode = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_MODE_REG); @@ -715,6 +726,7 @@ iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); del_timer(&can->bec_poll_timer); } + can->can.state = CAN_STATE_STOPPED; close_candev(netdev); return ret; @@ -947,6 +959,9 @@ timer_setup(&can->bec_poll_timer, kvaser_pciefd_bec_poll_timer, 0); + /* Disable Bus load reporting */ + iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_BUS_LOAD_REG); + tx_npackets = ioread32(can->reg_base + KVASER_PCIEFD_KCAN_TX_NPACKETS_REG); if (((tx_npackets >> KVASER_PCIEFD_KCAN_TX_NPACKETS_MAX_SHIFT) & @@ -994,8 +1009,7 @@ SET_NETDEV_DEV(netdev, &pcie->pci->dev); iowrite32(-1, can->reg_base + KVASER_PCIEFD_KCAN_IRQ_REG); - iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD | - KVASER_PCIEFD_KCAN_IRQ_TFD, + iowrite32(KVASER_PCIEFD_KCAN_IRQ_ABD, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); pcie->can[i] = can; @@ -1045,6 +1059,7 @@ { int i; u32 srb_status; + u32 srb_packet_count; dma_addr_t dma_addr[KVASER_PCIEFD_DMA_COUNT]; /* Disable the DMA */ @@ -1072,6 +1087,15 @@ KVASER_PCIEFD_SRB_CMD_RDB1, pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); + /* Empty Rx FIFO */ + srb_packet_count = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_RX_NR_PACKETS_REG) & + KVASER_PCIEFD_SRB_RX_NR_PACKETS_MASK; + while (srb_packet_count) { + /* Drop current packet in FIFO */ + ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_FIFO_LAST_REG); + srb_packet_count--; + } + srb_status = ioread32(pcie->reg_base + KVASER_PCIEFD_SRB_STAT_REG); if (!(srb_status & KVASER_PCIEFD_SRB_STAT_DI)) { dev_err(&pcie->pci->dev, "DMA not idle before enabling\n"); @@ -1279,7 +1303,10 @@ can->err_rep_cnt++; can->can.can_stats.bus_error++; - stats->rx_errors++; + if (p->header[1] & KVASER_PCIEFD_EPACK_DIR_TX) + stats->tx_errors++; + else + stats->rx_errors++; can->bec.txerr = bec.txerr; can->bec.rxerr = bec.rxerr; @@ -1411,9 +1438,6 @@ cmd = KVASER_PCIEFD_KCAN_CMD_AT; cmd |= ++can->cmd_seq << KVASER_PCIEFD_KCAN_CMD_SEQ_SHIFT; iowrite32(cmd, can->reg_base + KVASER_PCIEFD_KCAN_CMD_REG); - - iowrite32(KVASER_PCIEFD_KCAN_IRQ_TFD, - can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); } else if (p->header[0] & KVASER_PCIEFD_SPACK_IDET && p->header[0] & KVASER_PCIEFD_SPACK_IRM && cmdseq == (p->header[1] & KVASER_PCIEFD_PACKET_SEQ_MSK) && @@ -1702,15 +1726,6 @@ if (irq & KVASER_PCIEFD_KCAN_IRQ_TOF) netdev_err(can->can.dev, "Tx FIFO overflow\n"); - if (irq & KVASER_PCIEFD_KCAN_IRQ_TFD) { - u8 count = ioread32(can->reg_base + - KVASER_PCIEFD_KCAN_TX_NPACKETS_REG) & 0xff; - - if (count == 0) - iowrite32(KVASER_PCIEFD_KCAN_CTRL_EFLUSH, - can->reg_base + KVASER_PCIEFD_KCAN_CTRL_REG); - } - if (irq & KVASER_PCIEFD_KCAN_IRQ_BPP) netdev_err(can->can.dev, "Fail to change bittiming, when not in reset mode\n"); @@ -1812,6 +1827,11 @@ if (err) goto err_teardown_can_ctrls; + err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler, + IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie); + if (err) + goto err_teardown_can_ctrls; + iowrite32(KVASER_PCIEFD_SRB_IRQ_DPD0 | KVASER_PCIEFD_SRB_IRQ_DPD1, pcie->reg_base + KVASER_PCIEFD_SRB_IRQ_REG); @@ -1832,11 +1852,6 @@ iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1, pcie->reg_base + KVASER_PCIEFD_SRB_CMD_REG); - err = request_irq(pcie->pci->irq, kvaser_pciefd_irq_handler, - IRQF_SHARED, KVASER_PCIEFD_DRV_NAME, pcie); - if (err) - goto err_teardown_can_ctrls; - err = kvaser_pciefd_reg_candev(pcie); if (err) goto err_free_irq; @@ -1844,6 +1859,8 @@ return 0; err_free_irq: + /* Disable PCI interrupts */ + iowrite32(0, pcie->reg_base + KVASER_PCIEFD_IEN_REG); free_irq(pcie->pci->irq, pcie); err_teardown_can_ctrls: --- linux-oracle-5.4.0.orig/drivers/net/can/m_can/Kconfig +++ linux-oracle-5.4.0/drivers/net/can/m_can/Kconfig @@ -16,7 +16,8 @@ config CAN_M_CAN_TCAN4X5X depends on CAN_M_CAN - depends on REGMAP_SPI + depends on SPI + select REGMAP_SPI tristate "TCAN4X5X M_CAN device" ---help--- Say Y here if you want support for Texas Instruments TCAN4x5x --- linux-oracle-5.4.0.orig/drivers/net/can/m_can/m_can.c +++ linux-oracle-5.4.0/drivers/net/can/m_can/m_can.c @@ -206,15 +206,15 @@ /* Interrupts for version 3.0.x */ #define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE) -#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \ - IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ - IR_RF1L | IR_RF0L) +#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_BEU | IR_BEC | \ + IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ + IR_RF0L) #define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X) /* Interrupts for version >= 3.1.x */ #define IR_ERR_LEC_31X (IR_PED | IR_PEA) -#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \ - IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ - IR_RF1L | IR_RF0L) +#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_BEU | IR_BEC | \ + IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | IR_RF1L | \ + IR_RF0L) #define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X) /* Interrupt Line Select (ILS) */ @@ -379,10 +379,6 @@ cccr &= ~CCCR_CSR; if (enable) { - /* Clear the Clock stop request if it was set */ - if (cccr & CCCR_CSR) - cccr &= ~CCCR_CSR; - /* enable m_can configuration */ m_can_write(cdev, M_CAN_CCCR, cccr | CCCR_INIT); udelay(5); @@ -505,9 +501,6 @@ } while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { - if (rxfs & RXFS_RFL) - netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); - m_can_read_fifo(dev, rxfs); quota--; @@ -664,7 +657,7 @@ unsigned int ecr; switch (new_state) { - case CAN_STATE_ERROR_ACTIVE: + case CAN_STATE_ERROR_WARNING: /* error warning state */ cdev->can.can_stats.error_warning++; cdev->can.state = CAN_STATE_ERROR_WARNING; @@ -693,7 +686,7 @@ __m_can_get_berr_counter(dev, &bec); switch (new_state) { - case CAN_STATE_ERROR_ACTIVE: + case CAN_STATE_ERROR_WARNING: /* error warning state */ cf->can_id |= CAN_ERR_CRTL; cf->data[1] = (bec.txerr > bec.rxerr) ? @@ -758,8 +751,6 @@ { if (irqstatus & IR_WDI) netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); - if (irqstatus & IR_ELO) - netdev_err(dev, "Error Logging Overflow\n"); if (irqstatus & IR_BEU) netdev_err(dev, "Bit Error Uncorrected\n"); if (irqstatus & IR_BEC) @@ -846,7 +837,7 @@ { struct m_can_classdev *cdev = netdev_priv(dev); - m_can_rx_handler(dev, 1); + m_can_rx_handler(dev, M_CAN_NAPI_WEIGHT); m_can_enable_all_interrupts(cdev); @@ -913,6 +904,8 @@ struct net_device_stats *stats = &dev->stats; u32 ir; + if (pm_runtime_suspended(cdev->dev)) + return IRQ_NONE; ir = m_can_read(cdev, M_CAN_IR); if (!ir) return IRQ_NONE; @@ -988,7 +981,7 @@ .name = KBUILD_MODNAME, .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ .tseg1_max = 256, - .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ + .tseg2_min = 2, /* Time segment 2 = phase_seg2 */ .tseg2_max = 128, .sjw_max = 128, .brp_min = 1, @@ -1335,6 +1328,8 @@ &m_can_data_bittiming_const_31X; break; case 32: + case 33: + /* Support both MCAN version v3.2.x and v3.3.0 */ m_can_dev->can.bittiming_const = m_can_dev->bit_timing ? m_can_dev->bit_timing : &m_can_bittiming_const_31X; @@ -1366,6 +1361,9 @@ /* disable all interrupts */ m_can_disable_all_interrupts(cdev); + /* Set init mode to disengage from the network */ + m_can_config_endisable(cdev, true); + /* set the state as STOPPED */ cdev->can.state = CAN_STATE_STOPPED; } @@ -1418,6 +1416,8 @@ int i; int putidx; + cdev->tx_skb = NULL; + /* Generate ID field for TX buffer Element */ /* Common to all supported M_CAN versions */ if (cf->can_id & CAN_EFF_FLAG) { @@ -1443,8 +1443,6 @@ M_CAN_FIFO_DATA(i / 4), *(u32 *)(cf->data + i)); - can_put_echo_skb(skb, dev, 0); - if (cdev->can.ctrlmode & CAN_CTRLMODE_FD) { cccr = m_can_read(cdev, M_CAN_CCCR); cccr &= ~(CCCR_CMR_MASK << CCCR_CMR_SHIFT); @@ -1461,6 +1459,9 @@ m_can_write(cdev, M_CAN_CCCR, cccr); } m_can_write(cdev, M_CAN_TXBTIE, 0x1); + + can_put_echo_skb(skb, dev, 0); + m_can_write(cdev, M_CAN_TXBAR, 0x1); /* End of xmit function for version 3.0.x */ } else { @@ -1534,7 +1535,6 @@ tx_work); m_can_tx_handler(cdev); - cdev->tx_skb = NULL; } static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, @@ -1600,7 +1600,7 @@ INIT_WORK(&cdev->tx_work, m_can_tx_work_queue); err = request_threaded_irq(dev->irq, NULL, m_can_isr, - IRQF_ONESHOT | IRQF_TRIGGER_FALLING, + IRQF_ONESHOT, dev->name, dev); } else { err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, @@ -1764,6 +1764,12 @@ } EXPORT_SYMBOL_GPL(m_can_class_allocate_dev); +void m_can_class_free_dev(struct net_device *net) +{ + free_candev(net); +} +EXPORT_SYMBOL_GPL(m_can_class_free_dev); + int m_can_class_register(struct m_can_classdev *m_can_dev) { int ret; @@ -1859,8 +1865,6 @@ { unregister_candev(m_can_dev->net); - m_can_clk_stop(m_can_dev); - free_candev(m_can_dev->net); } EXPORT_SYMBOL_GPL(m_can_class_unregister); --- linux-oracle-5.4.0.orig/drivers/net/can/m_can/m_can.h +++ linux-oracle-5.4.0/drivers/net/can/m_can/m_can.h @@ -99,6 +99,7 @@ }; struct m_can_classdev *m_can_class_allocate_dev(struct device *dev); +void m_can_class_free_dev(struct net_device *net); int m_can_class_register(struct m_can_classdev *cdev); void m_can_class_unregister(struct m_can_classdev *cdev); int m_can_class_get_clocks(struct m_can_classdev *cdev); --- linux-oracle-5.4.0.orig/drivers/net/can/m_can/m_can_platform.c +++ linux-oracle-5.4.0/drivers/net/can/m_can/m_can_platform.c @@ -144,8 +144,6 @@ struct net_device *ndev = dev_get_drvdata(dev); struct m_can_classdev *mcan_class = netdev_priv(ndev); - m_can_class_suspend(dev); - clk_disable_unprepare(mcan_class->cclk); clk_disable_unprepare(mcan_class->hclk); --- linux-oracle-5.4.0.orig/drivers/net/can/m_can/tcan4x5x.c +++ linux-oracle-5.4.0/drivers/net/can/m_can/tcan4x5x.c @@ -88,7 +88,7 @@ #define TCAN4X5X_MRAM_START 0x8000 #define TCAN4X5X_MCAN_OFFSET 0x1000 -#define TCAN4X5X_MAX_REGISTER 0x8fff +#define TCAN4X5X_MAX_REGISTER 0x8ffc #define TCAN4X5X_CLEAR_ALL_INT 0xffffffff #define TCAN4X5X_SET_ALL_INT 0xffffffff @@ -126,30 +126,6 @@ int reg_offset; }; -static struct can_bittiming_const tcan4x5x_bittiming_const = { - .name = DEVICE_NAME, - .tseg1_min = 2, - .tseg1_max = 31, - .tseg2_min = 2, - .tseg2_max = 16, - .sjw_max = 16, - .brp_min = 1, - .brp_max = 32, - .brp_inc = 1, -}; - -static struct can_bittiming_const tcan4x5x_data_bittiming_const = { - .name = DEVICE_NAME, - .tseg1_min = 1, - .tseg1_max = 32, - .tseg2_min = 1, - .tseg2_max = 16, - .sjw_max = 16, - .brp_min = 1, - .brp_max = 32, - .brp_inc = 1, -}; - static void tcan4x5x_check_wake(struct tcan4x5x_priv *priv) { int wake_state = 0; @@ -164,6 +140,28 @@ } } +static int tcan4x5x_reset(struct tcan4x5x_priv *priv) +{ + int ret = 0; + + if (priv->reset_gpio) { + gpiod_set_value(priv->reset_gpio, 1); + + /* tpulse_width minimum 30us */ + usleep_range(30, 100); + gpiod_set_value(priv->reset_gpio, 0); + } else { + ret = regmap_write(priv->regmap, TCAN4X5X_CONFIG, + TCAN4X5X_SW_RESET); + if (ret) + return ret; + } + + usleep_range(700, 1000); + + return ret; +} + static int regmap_spi_gather_write(void *context, const void *reg, size_t reg_len, const void *val, size_t val_len) @@ -293,11 +291,6 @@ if (ret) return ret; - ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_MCAN_INT_REG, - TCAN4X5X_ENABLE_MCAN_INT); - if (ret) - return ret; - ret = tcan4x5x_write_tcan_reg(cdev, TCAN4X5X_INT_FLAGS, TCAN4X5X_CLEAR_ALL_INT); if (ret) @@ -327,20 +320,21 @@ if (ret) return ret; + /* Zero out the MCAN buffers */ + m_can_init_ram(cdev); + ret = regmap_update_bits(tcan4x5x->regmap, TCAN4X5X_CONFIG, TCAN4X5X_MODE_SEL_MASK, TCAN4X5X_MODE_NORMAL); if (ret) return ret; - /* Zero out the MCAN buffers */ - m_can_init_ram(cdev); - return ret; } static int tcan4x5x_parse_config(struct m_can_classdev *cdev) { struct tcan4x5x_priv *tcan4x5x = cdev->device_data; + int ret; tcan4x5x->device_wake_gpio = devm_gpiod_get(cdev->dev, "device-wake", GPIOD_OUT_HIGH); @@ -354,6 +348,10 @@ if (IS_ERR(tcan4x5x->reset_gpio)) tcan4x5x->reset_gpio = NULL; + ret = tcan4x5x_reset(tcan4x5x); + if (ret) + return ret; + tcan4x5x->device_state_gpio = devm_gpiod_get_optional(cdev->dev, "device-state", GPIOD_IN); @@ -422,8 +420,6 @@ mcan_class->dev = &spi->dev; mcan_class->ops = &tcan4x5x_ops; mcan_class->is_peripheral = true; - mcan_class->bit_timing = &tcan4x5x_bittiming_const; - mcan_class->data_timing = &tcan4x5x_data_bittiming_const; mcan_class->net->irq = spi->irq; spi_set_drvdata(spi, priv); @@ -440,9 +436,17 @@ priv->regmap = devm_regmap_init(&spi->dev, &tcan4x5x_bus, &spi->dev, &tcan4x5x_regmap); + if (IS_ERR(priv->regmap)) { + ret = PTR_ERR(priv->regmap); + goto out_clk; + } tcan4x5x_power_enable(priv->power, 1); + ret = tcan4x5x_init(mcan_class); + if (ret) + goto out_power; + ret = m_can_class_register(mcan_class); if (ret) goto out_power; @@ -466,10 +470,10 @@ { struct tcan4x5x_priv *priv = spi_get_drvdata(spi); - tcan4x5x_power_enable(priv->power, 0); - m_can_class_unregister(priv->mcan_dev); + tcan4x5x_power_enable(priv->power, 0); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/can/mscan/mpc5xxx_can.c +++ linux-oracle-5.4.0/drivers/net/can/mscan/mpc5xxx_can.c @@ -325,14 +325,14 @@ &mscan_clksrc); if (!priv->can.clock.freq) { dev_err(&ofdev->dev, "couldn't get MSCAN clock properties\n"); - goto exit_free_mscan; + goto exit_put_clock; } err = register_mscandev(dev, mscan_clksrc); if (err) { dev_err(&ofdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); - goto exit_free_mscan; + goto exit_put_clock; } dev_info(&ofdev->dev, "MSCAN at 0x%p, irq %d, clock %d Hz\n", @@ -340,7 +340,9 @@ return 0; -exit_free_mscan: +exit_put_clock: + if (data->put_clock) + data->put_clock(ofdev); free_candev(dev); exit_dispose_irq: irq_dispose_mapping(irq); --- linux-oracle-5.4.0.orig/drivers/net/can/mscan/mscan.c +++ linux-oracle-5.4.0/drivers/net/can/mscan/mscan.c @@ -381,13 +381,12 @@ struct net_device *dev = napi->dev; struct mscan_regs __iomem *regs = priv->reg_base; struct net_device_stats *stats = &dev->stats; - int npackets = 0; - int ret = 1; + int work_done = 0; struct sk_buff *skb; struct can_frame *frame; u8 canrflg; - while (npackets < quota) { + while (work_done < quota) { canrflg = in_8(®s->canrflg); if (!(canrflg & (MSCAN_RXF | MSCAN_ERR_IF))) break; @@ -408,18 +407,18 @@ stats->rx_packets++; stats->rx_bytes += frame->can_dlc; - npackets++; + work_done++; netif_receive_skb(skb); } - if (!(in_8(®s->canrflg) & (MSCAN_RXF | MSCAN_ERR_IF))) { - napi_complete(&priv->napi); - clear_bit(F_RX_PROGRESS, &priv->flags); - if (priv->can.state < CAN_STATE_BUS_OFF) - out_8(®s->canrier, priv->shadow_canrier); - ret = 0; + if (work_done < quota) { + if (likely(napi_complete_done(&priv->napi, work_done))) { + clear_bit(F_RX_PROGRESS, &priv->flags); + if (priv->can.state < CAN_STATE_BUS_OFF) + out_8(®s->canrier, priv->shadow_canrier); + } } - return ret; + return work_done; } static irqreturn_t mscan_isr(int irq, void *dev_id) --- linux-oracle-5.4.0.orig/drivers/net/can/pch_can.c +++ linux-oracle-5.4.0/drivers/net/can/pch_can.c @@ -489,6 +489,7 @@ if (!skb) return; + errc = ioread32(&priv->regs->errc); if (status & PCH_BUS_OFF) { pch_can_set_tx_all(priv, 0); pch_can_set_rx_all(priv, 0); @@ -496,9 +497,11 @@ cf->can_id |= CAN_ERR_BUSOFF; priv->can.can_stats.bus_off++; can_bus_off(ndev); + } else { + cf->data[6] = errc & PCH_TEC; + cf->data[7] = (errc & PCH_REC) >> 8; } - errc = ioread32(&priv->regs->errc); /* Warning interrupt. */ if (status & PCH_EWARN) { state = CAN_STATE_ERROR_WARNING; @@ -556,9 +559,6 @@ break; } - cf->data[6] = errc & PCH_TEC; - cf->data[7] = (errc & PCH_REC) >> 8; - priv->can.state = state; netif_receive_skb(skb); @@ -692,11 +692,11 @@ cf->data[i + 1] = data_reg >> 8; } - netif_receive_skb(skb); rcv_pkts++; stats->rx_packets++; quota--; stats->rx_bytes += cf->can_dlc; + netif_receive_skb(skb); pch_fifo_thresh(priv, obj_num); obj_num++; --- linux-oracle-5.4.0.orig/drivers/net/can/peak_canfd/peak_canfd.c +++ linux-oracle-5.4.0/drivers/net/can/peak_canfd/peak_canfd.c @@ -232,6 +232,20 @@ return pucan_write_cmd(priv); } +static int pucan_netif_rx(struct sk_buff *skb, __le32 ts_low, __le32 ts_high) +{ + struct skb_shared_hwtstamps *hwts = skb_hwtstamps(skb); + u64 ts_us; + + ts_us = (u64)le32_to_cpu(ts_high) << 32; + ts_us |= le32_to_cpu(ts_low); + + /* IP core timestamps are µs. */ + hwts->hwtstamp = ns_to_ktime(ts_us * NSEC_PER_USEC); + + return netif_rx(skb); +} + /* handle the reception of one CAN frame */ static int pucan_handle_can_rx(struct peak_canfd_priv *priv, struct pucan_rx_msg *msg) @@ -248,8 +262,7 @@ cf_len = get_can_dlc(pucan_msg_get_dlc(msg)); /* if this frame is an echo, */ - if ((rx_msg_flags & PUCAN_MSG_LOOPED_BACK) && - !(rx_msg_flags & PUCAN_MSG_SELF_RECEIVE)) { + if (rx_msg_flags & PUCAN_MSG_LOOPED_BACK) { unsigned long flags; spin_lock_irqsave(&priv->echo_lock, flags); @@ -263,7 +276,13 @@ netif_wake_queue(priv->ndev); spin_unlock_irqrestore(&priv->echo_lock, flags); - return 0; + + /* if this frame is only an echo, stop here. Otherwise, + * continue to push this application self-received frame into + * its own rx queue. + */ + if (!(rx_msg_flags & PUCAN_MSG_SELF_RECEIVE)) + return 0; } /* otherwise, it should be pushed into rx fifo */ @@ -299,7 +318,7 @@ stats->rx_bytes += cf->len; stats->rx_packets++; - netif_rx(skb); + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); return 0; } @@ -333,8 +352,8 @@ return err; } - /* start network queue (echo_skb array is empty) */ - netif_start_queue(ndev); + /* wake network queue up (echo_skb array is empty) */ + netif_wake_queue(ndev); return 0; } @@ -393,7 +412,7 @@ stats->rx_packets++; stats->rx_bytes += cf->can_dlc; - netif_rx(skb); + pucan_netif_rx(skb, msg->ts_low, msg->ts_high); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/can/rcar/rcar_can.c +++ linux-oracle-5.4.0/drivers/net/can/rcar/rcar_can.c @@ -235,11 +235,8 @@ if (eifr & (RCAR_CAN_EIFR_EWIF | RCAR_CAN_EIFR_EPIF)) { txerr = readb(&priv->regs->tecr); rxerr = readb(&priv->regs->recr); - if (skb) { + if (skb) cf->can_id |= CAN_ERR_CRTL; - cf->data[6] = txerr; - cf->data[7] = rxerr; - } } if (eifr & RCAR_CAN_EIFR_BEIF) { int rx_errors = 0, tx_errors = 0; @@ -339,6 +336,9 @@ can_bus_off(ndev); if (skb) cf->can_id |= CAN_ERR_BUSOFF; + } else if (skb) { + cf->data[6] = txerr; + cf->data[7] = rxerr; } if (eifr & RCAR_CAN_EIFR_ORIF) { netdev_dbg(priv->ndev, "Receive overrun error interrupt\n"); @@ -848,10 +848,12 @@ struct rcar_can_priv *priv = netdev_priv(ndev); u16 ctlr; - if (netif_running(ndev)) { - netif_stop_queue(ndev); - netif_device_detach(ndev); - } + if (!netif_running(ndev)) + return 0; + + netif_stop_queue(ndev); + netif_device_detach(ndev); + ctlr = readw(&priv->regs->ctlr); ctlr |= RCAR_CAN_CTLR_CANM_HALT; writew(ctlr, &priv->regs->ctlr); @@ -870,6 +872,9 @@ u16 ctlr; int err; + if (!netif_running(ndev)) + return 0; + err = clk_enable(priv->clk); if (err) { netdev_err(ndev, "clk_enable() failed, error %d\n", err); @@ -883,10 +888,9 @@ writew(ctlr, &priv->regs->ctlr); priv->can.state = CAN_STATE_ERROR_ACTIVE; - if (netif_running(ndev)) { - netif_device_attach(ndev); - netif_start_queue(ndev); - } + netif_device_attach(ndev); + netif_start_queue(ndev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/can/rcar/rcar_canfd.c +++ linux-oracle-5.4.0/drivers/net/can/rcar/rcar_canfd.c @@ -1075,7 +1075,7 @@ struct rcar_canfd_global *gpriv = dev_id; struct net_device *ndev; struct rcar_canfd_channel *priv; - u32 sts, gerfl; + u32 sts, cc, gerfl; u32 ch, ridx; /* Global error interrupts still indicate a condition specific @@ -1093,7 +1093,9 @@ /* Handle Rx interrupts */ sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(ridx)); - if (likely(sts & RCANFD_RFSTS_RFIF)) { + cc = rcar_canfd_read(priv->base, RCANFD_RFCC(ridx)); + if (likely(sts & RCANFD_RFSTS_RFIF && + cc & RCANFD_RFCC_RFIE)) { if (napi_schedule_prep(&priv->napi)) { /* Disable Rx FIFO interrupts */ rcar_canfd_clear_bit(priv->base, @@ -1598,15 +1600,15 @@ netif_napi_add(ndev, &priv->napi, rcar_canfd_rx_poll, RCANFD_NAPI_WEIGHT); + spin_lock_init(&priv->tx_lock); + devm_can_led_init(ndev); + gpriv->ch[priv->channel] = priv; err = register_candev(ndev); if (err) { dev_err(&pdev->dev, "register_candev() failed, error %d\n", err); goto fail_candev; } - spin_lock_init(&priv->tx_lock); - devm_can_led_init(ndev); - gpriv->ch[priv->channel] = priv; dev_info(&pdev->dev, "device registered (channel %u)\n", priv->channel); return 0; --- linux-oracle-5.4.0.orig/drivers/net/can/sja1000/ems_pcmcia.c +++ linux-oracle-5.4.0/drivers/net/can/sja1000/ems_pcmcia.c @@ -235,7 +235,12 @@ free_sja1000dev(dev); } - err = request_irq(dev->irq, &ems_pcmcia_interrupt, IRQF_SHARED, + if (!card->channels) { + err = -ENODEV; + goto failure_cleanup; + } + + err = request_irq(pdev->irq, &ems_pcmcia_interrupt, IRQF_SHARED, DRV_NAME, card); if (!err) return 0; --- linux-oracle-5.4.0.orig/drivers/net/can/sja1000/peak_pci.c +++ linux-oracle-5.4.0/drivers/net/can/sja1000/peak_pci.c @@ -731,16 +731,15 @@ struct net_device *prev_dev = chan->prev_dev; dev_info(&pdev->dev, "removing device %s\n", dev->name); + /* do that only for first channel */ + if (!prev_dev && chan->pciec_card) + peak_pciec_remove(chan->pciec_card); unregister_sja1000dev(dev); free_sja1000dev(dev); dev = prev_dev; - if (!dev) { - /* do that only for first channel */ - if (chan->pciec_card) - peak_pciec_remove(chan->pciec_card); + if (!dev) break; - } priv = netdev_priv(dev); chan = priv->priv; } --- linux-oracle-5.4.0.orig/drivers/net/can/sja1000/sja1000.c +++ linux-oracle-5.4.0/drivers/net/can/sja1000/sja1000.c @@ -405,9 +405,6 @@ txerr = priv->read_reg(priv, SJA1000_TXERR); rxerr = priv->read_reg(priv, SJA1000_RXERR); - cf->data[6] = txerr; - cf->data[7] = rxerr; - if (isrc & IRQ_DOI) { /* data overrun interrupt */ netdev_dbg(dev, "data overrun interrupt\n"); @@ -429,6 +426,10 @@ else state = CAN_STATE_ERROR_ACTIVE; } + if (state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + } if (isrc & IRQ_BEI) { /* bus error interrupt */ priv->can.can_stats.bus_error++; --- linux-oracle-5.4.0.orig/drivers/net/can/sja1000/sja1000_isa.c +++ linux-oracle-5.4.0/drivers/net/can/sja1000/sja1000_isa.c @@ -202,22 +202,24 @@ if (err) { dev_err(&pdev->dev, "registering %s failed (err=%d)\n", DRV_NAME, err); - goto exit_unmap; + goto exit_free; } dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n", DRV_NAME, priv->reg_base, dev->irq); return 0; - exit_unmap: +exit_free: + free_sja1000dev(dev); +exit_unmap: if (mem[idx]) iounmap(base); - exit_release: +exit_release: if (mem[idx]) release_mem_region(mem[idx], iosize); else release_region(port[idx], iosize); - exit: +exit: return err; } --- linux-oracle-5.4.0.orig/drivers/net/can/slcan.c +++ linux-oracle-5.4.0/drivers/net/can/slcan.c @@ -148,7 +148,7 @@ u32 tmpid; char *cmd = sl->rbuff; - cf.can_id = 0; + memset(&cf, 0, sizeof(cf)); switch (*cmd) { case 'r': @@ -187,8 +187,6 @@ else return; - *(u64 *) (&cf.data) = 0; /* clear payload */ - /* RTR frames may have a dlc > 0 but they never have any data bytes */ if (!(cf.can_id & CAN_RTR_FLAG)) { for (i = 0; i < cf.can_dlc; i++) { @@ -344,9 +342,16 @@ */ static void slcan_write_wakeup(struct tty_struct *tty) { - struct slcan *sl = tty->disc_data; + struct slcan *sl; + + rcu_read_lock(); + sl = rcu_dereference(tty->disc_data); + if (!sl) + goto out; schedule_work(&sl->tx_work); +out: + rcu_read_unlock(); } /* Send a can_frame to a TTY queue. */ @@ -514,6 +519,7 @@ int i; char name[IFNAMSIZ]; struct net_device *dev = NULL; + struct can_ml_priv *can_ml; struct slcan *sl; int size; @@ -536,7 +542,8 @@ dev->base_addr = i; sl = netdev_priv(dev); - dev->ml_priv = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); + can_ml = (void *)sl + ALIGN(sizeof(*sl), NETDEV_ALIGN); + can_set_ml_priv(dev, can_ml); /* Initialize channel control data */ sl->magic = SLCAN_MAGIC; @@ -617,7 +624,11 @@ sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); + slc_free_netdev(sl->dev); + /* do not call free_netdev before rtnl_unlock */ + rtnl_unlock(); free_netdev(sl->dev); + return err; err_exit: rtnl_unlock(); @@ -643,10 +654,11 @@ return; spin_lock_bh(&sl->lock); - tty->disc_data = NULL; + rcu_assign_pointer(tty->disc_data, NULL); sl->tty = NULL; spin_unlock_bh(&sl->lock); + synchronize_rcu(); flush_work(&sl->tx_work); /* Flush network side */ --- linux-oracle-5.4.0.orig/drivers/net/can/softing/softing_cs.c +++ linux-oracle-5.4.0/drivers/net/can/softing/softing_cs.c @@ -293,7 +293,7 @@ return 0; platform_failed: - kfree(dev); + platform_device_put(pdev); mem_failed: pcmcia_bad: pcmcia_failed: --- linux-oracle-5.4.0.orig/drivers/net/can/softing/softing_fw.c +++ linux-oracle-5.4.0/drivers/net/can/softing/softing_fw.c @@ -565,18 +565,19 @@ if (ret < 0) goto failed; } - /* enable_error_frame */ - /* + + /* enable_error_frame + * * Error reporting is switched off at the moment since * the receiving of them is not yet 100% verified * This should be enabled sooner or later - * - if (error_reporting) { + */ + if (0 && error_reporting) { ret = softing_fct_cmd(card, 51, "enable_error_frame"); if (ret < 0) goto failed; } - */ + /* initialize interface */ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); --- linux-oracle-5.4.0.orig/drivers/net/can/softing/softing_main.c +++ linux-oracle-5.4.0/drivers/net/can/softing/softing_main.c @@ -382,8 +382,13 @@ /* check or determine and set bittime */ ret = open_candev(ndev); - if (!ret) - ret = softing_startstop(ndev, 1); + if (ret) + return ret; + + ret = softing_startstop(ndev, 1); + if (ret < 0) + close_candev(ndev); + return ret; } --- linux-oracle-5.4.0.orig/drivers/net/can/spi/hi311x.c +++ linux-oracle-5.4.0/drivers/net/can/spi/hi311x.c @@ -218,7 +218,7 @@ return ret; } -static u8 hi3110_cmd(struct spi_device *spi, u8 command) +static int hi3110_cmd(struct spi_device *spi, u8 command) { struct hi3110_priv *priv = spi_get_drvdata(spi); @@ -670,20 +670,22 @@ txerr = hi3110_read(spi, HI3110_READ_TEC); rxerr = hi3110_read(spi, HI3110_READ_REC); - cf->data[6] = txerr; - cf->data[7] = rxerr; tx_state = txerr >= rxerr ? new_state : 0; rx_state = txerr <= rxerr ? new_state : 0; can_change_state(net, cf, tx_state, rx_state); - netif_rx_ni(skb); if (new_state == CAN_STATE_BUS_OFF) { + netif_rx_ni(skb); can_bus_off(net); if (priv->can.restart_ms == 0) { priv->force_quit = 1; hi3110_hw_sleep(spi); break; } + } else { + cf->data[6] = txerr; + cf->data[7] = rxerr; + netif_rx_ni(skb); } } --- linux-oracle-5.4.0.orig/drivers/net/can/spi/mcp251x.c +++ linux-oracle-5.4.0/drivers/net/can/spi/mcp251x.c @@ -756,9 +756,6 @@ mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); - /* mask out flags we don't care about */ - intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; - /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); @@ -768,6 +765,18 @@ if (mcp251x_is_2510(spi)) mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); + + /* check if buffer 1 is already known to be full, no need to re-read */ + if (!(intf & CANINTF_RX1IF)) { + u8 intf1, eflag1; + + /* intf needs to be read again to avoid a race condition */ + mcp251x_read_2regs(spi, CANINTF, &intf1, &eflag1); + + /* combine flags from both operations for error handling */ + intf |= intf1; + eflag |= eflag1; + } } /* receive buffer 1 */ @@ -778,6 +787,9 @@ clear_intf |= CANINTF_RX1IF; } + /* mask out flags we don't care about */ + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; + /* any error or tx interrupt we need to clear? */ if (intf & (CANINTF_ERR | CANINTF_TX)) clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); --- linux-oracle-5.4.0.orig/drivers/net/can/sun4i_can.c +++ linux-oracle-5.4.0/drivers/net/can/sun4i_can.c @@ -525,11 +525,6 @@ rxerr = (errc >> 16) & 0xFF; txerr = errc & 0xFF; - if (skb) { - cf->data[6] = txerr; - cf->data[7] = rxerr; - } - if (isrc & SUN4I_INT_DATA_OR) { /* data overrun interrupt */ netdev_dbg(dev, "data overrun interrupt\n"); @@ -560,15 +555,17 @@ else state = CAN_STATE_ERROR_ACTIVE; } + if (skb && state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + } if (isrc & SUN4I_INT_BUS_ERR) { /* bus error interrupt */ netdev_dbg(dev, "bus error interrupt\n"); priv->can.can_stats.bus_error++; - stats->rx_errors++; + ecc = readl(priv->base + SUN4I_REG_STA_ADDR); if (likely(skb)) { - ecc = readl(priv->base + SUN4I_REG_STA_ADDR); - cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; switch (ecc & SUN4I_STA_MASK_ERR) { @@ -586,9 +583,15 @@ >> 16; break; } - /* error occurred during transmission? */ - if ((ecc & SUN4I_STA_ERR_DIR) == 0) + } + + /* error occurred during transmission? */ + if ((ecc & SUN4I_STA_ERR_DIR) == 0) { + if (likely(skb)) cf->data[2] |= CAN_ERR_PROT_TX; + stats->tx_errors++; + } else { + stats->rx_errors++; } } if (isrc & SUN4I_INT_ERR_PASSIVE) { @@ -615,10 +618,10 @@ tx_state = txerr >= rxerr ? state : 0; rx_state = txerr <= rxerr ? state : 0; - if (likely(skb)) - can_change_state(dev, cf, tx_state, rx_state); - else - priv->can.state = state; + /* The skb allocation might fail, but can_change_state() + * handles cf == NULL. + */ + can_change_state(dev, cf, tx_state, rx_state); if (state == CAN_STATE_BUS_OFF) can_bus_off(dev); } --- linux-oracle-5.4.0.orig/drivers/net/can/ti_hecc.c +++ linux-oracle-5.4.0/drivers/net/can/ti_hecc.c @@ -873,7 +873,8 @@ priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) { dev_err(&pdev->dev, "hecc ioremap failed\n"); - return PTR_ERR(priv->base); + err = PTR_ERR(priv->base); + goto probe_exit_candev; } /* handle hecc-ram memory */ @@ -886,7 +887,8 @@ priv->hecc_ram = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->hecc_ram)) { dev_err(&pdev->dev, "hecc-ram ioremap failed\n"); - return PTR_ERR(priv->hecc_ram); + err = PTR_ERR(priv->hecc_ram); + goto probe_exit_candev; } /* handle mbx memory */ @@ -899,13 +901,14 @@ priv->mbx = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->mbx)) { dev_err(&pdev->dev, "mbx ioremap failed\n"); - return PTR_ERR(priv->mbx); + err = PTR_ERR(priv->mbx); + goto probe_exit_candev; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq) { dev_err(&pdev->dev, "No irq resource\n"); - goto probe_exit; + goto probe_exit_candev; } priv->ndev = ndev; @@ -936,7 +939,7 @@ err = clk_prepare_enable(priv->clk); if (err) { dev_err(&pdev->dev, "clk_prepare_enable() failed\n"); - goto probe_exit_clk; + goto probe_exit_release_clk; } priv->offload.mailbox_read = ti_hecc_mailbox_read; @@ -945,7 +948,7 @@ err = can_rx_offload_add_timestamp(ndev, &priv->offload); if (err) { dev_err(&pdev->dev, "can_rx_offload_add_timestamp() failed\n"); - goto probe_exit_clk; + goto probe_exit_disable_clk; } err = register_candev(ndev); @@ -963,11 +966,13 @@ probe_exit_offload: can_rx_offload_del(&priv->offload); -probe_exit_clk: +probe_exit_disable_clk: + clk_disable_unprepare(priv->clk); +probe_exit_release_clk: clk_put(priv->clk); probe_exit_candev: free_candev(ndev); -probe_exit: + return err; } --- linux-oracle-5.4.0.orig/drivers/net/can/usb/ems_usb.c +++ linux-oracle-5.4.0/drivers/net/can/usb/ems_usb.c @@ -194,7 +194,7 @@ __le32 ts_sec; /* timestamp in seconds */ __le32 ts_nsec; /* timestamp in nano seconds */ - union { + union __packed { u8 generic[64]; struct cpc_can_msg can_msg; struct cpc_can_params can_params; @@ -255,6 +255,8 @@ unsigned int free_slots; /* remember number of available slots */ struct ems_cpc_msg active_params; /* active controller parameters */ + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; static void ems_usb_read_interrupt_callback(struct urb *urb) @@ -587,6 +589,7 @@ for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -596,7 +599,7 @@ } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -604,6 +607,8 @@ break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), buf, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); @@ -619,6 +624,9 @@ break; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -684,6 +692,10 @@ usb_kill_anchored_urbs(&dev->rx_submitted); + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, + dev->rxbuf[i], dev->rxbuf_dma[i]); + usb_kill_anchored_urbs(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); @@ -811,7 +823,6 @@ usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); - dev_kfree_skb(skb); atomic_dec(&dev->active_tx_urbs); @@ -1053,7 +1064,6 @@ if (dev) { unregister_netdev(dev->netdev); - free_candev(dev->netdev); unlink_all_urbs(dev); @@ -1061,6 +1071,8 @@ kfree(dev->intr_in_buffer); kfree(dev->tx_msg_buffer); + + free_candev(dev->netdev); } } --- linux-oracle-5.4.0.orig/drivers/net/can/usb/esd_usb2.c +++ linux-oracle-5.4.0/drivers/net/can/usb/esd_usb2.c @@ -195,6 +195,8 @@ int net_count; u32 version; int rxinitdone; + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; struct esd_usb2_net_priv { @@ -222,8 +224,12 @@ if (id == ESD_EV_CAN_ERROR_EXT) { u8 state = msg->msg.rx.data[0]; u8 ecc = msg->msg.rx.data[1]; - u8 txerr = msg->msg.rx.data[2]; - u8 rxerr = msg->msg.rx.data[3]; + u8 rxerr = msg->msg.rx.data[2]; + u8 txerr = msg->msg.rx.data[3]; + + netdev_dbg(priv->netdev, + "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n", + msg->msg.rx.dlc, state, ecc, rxerr, txerr); skb = alloc_can_err_skb(priv->netdev, &cf); if (skb == NULL) { @@ -251,6 +257,8 @@ break; default: priv->can.state = CAN_STATE_ERROR_ACTIVE; + txerr = 0; + rxerr = 0; break; } } else { @@ -270,7 +278,6 @@ cf->data[2] |= CAN_ERR_PROT_STUFF; break; default: - cf->data[3] = ecc & SJA1000_ECC_SEG; break; } @@ -278,6 +285,9 @@ if (!(ecc & SJA1000_ECC_DIR)) cf->data[2] |= CAN_ERR_PROT_TX; + /* Bit stream position in CAN frame as the error was detected */ + cf->data[3] = ecc & SJA1000_ECC_SEG; + if (priv->can.state == CAN_STATE_ERROR_WARNING || priv->can.state == CAN_STATE_ERROR_PASSIVE) { cf->data[1] = (txerr > rxerr) ? @@ -544,6 +554,7 @@ for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -553,7 +564,7 @@ } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { dev_warn(dev->udev->dev.parent, "No memory left for USB buffer\n"); @@ -561,6 +572,8 @@ goto freeurb; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), buf, RX_BUFFER_SIZE, @@ -573,8 +586,12 @@ usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); + goto freeurb; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + freeurb: /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); @@ -662,6 +679,11 @@ int i, j; usb_kill_anchored_urbs(&dev->rx_submitted); + + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, + dev->rxbuf[i], dev->rxbuf_dma[i]); + for (i = 0; i < dev->net_count; i++) { priv = dev->nets[i]; if (priv) { --- linux-oracle-5.4.0.orig/drivers/net/can/usb/gs_usb.c +++ linux-oracle-5.4.0/drivers/net/can/usb/gs_usb.c @@ -63,21 +63,27 @@ }; /* data types passed between host and device */ + +/* The firmware on the original USB2CAN by Geschwister Schneider + * Technologie Entwicklungs- und Vertriebs UG exchanges all data + * between the host and the device in host byte order. This is done + * with the struct gs_host_config::byte_order member, which is sent + * first to indicate the desired byte order. + * + * The widely used open source firmware candleLight doesn't support + * this feature and exchanges the data in little endian byte order. + */ struct gs_host_config { - u32 byte_order; + __le32 byte_order; } __packed; -/* All data exchanged between host and device is exchanged in host byte order, - * thanks to the struct gs_host_config byte_order member, which is sent first - * to indicate the desired byte order. - */ struct gs_device_config { u8 reserved1; u8 reserved2; u8 reserved3; u8 icount; - u32 sw_version; - u32 hw_version; + __le32 sw_version; + __le32 hw_version; } __packed; #define GS_CAN_MODE_NORMAL 0 @@ -87,26 +93,26 @@ #define GS_CAN_MODE_ONE_SHOT BIT(3) struct gs_device_mode { - u32 mode; - u32 flags; + __le32 mode; + __le32 flags; } __packed; struct gs_device_state { - u32 state; - u32 rxerr; - u32 txerr; + __le32 state; + __le32 rxerr; + __le32 txerr; } __packed; struct gs_device_bittiming { - u32 prop_seg; - u32 phase_seg1; - u32 phase_seg2; - u32 sjw; - u32 brp; + __le32 prop_seg; + __le32 phase_seg1; + __le32 phase_seg2; + __le32 sjw; + __le32 brp; } __packed; struct gs_identify_mode { - u32 mode; + __le32 mode; } __packed; #define GS_CAN_FEATURE_LISTEN_ONLY BIT(0) @@ -117,23 +123,23 @@ #define GS_CAN_FEATURE_IDENTIFY BIT(5) struct gs_device_bt_const { - u32 feature; - u32 fclk_can; - u32 tseg1_min; - u32 tseg1_max; - u32 tseg2_min; - u32 tseg2_max; - u32 sjw_max; - u32 brp_min; - u32 brp_max; - u32 brp_inc; + __le32 feature; + __le32 fclk_can; + __le32 tseg1_min; + __le32 tseg1_max; + __le32 tseg2_min; + __le32 tseg2_max; + __le32 sjw_max; + __le32 brp_min; + __le32 brp_max; + __le32 brp_inc; } __packed; #define GS_CAN_FLAG_OVERFLOW 1 struct gs_host_frame { u32 echo_id; - u32 can_id; + __le32 can_id; u8 can_dlc; u8 channel; @@ -178,14 +184,16 @@ struct usb_anchor tx_submitted; atomic_t active_tx_urbs; + void *rxbuf[GS_MAX_RX_URBS]; + dma_addr_t rxbuf_dma[GS_MAX_RX_URBS]; }; /* usb interface struct */ struct gs_usb { struct gs_can *canch[GS_MAX_INTF]; struct usb_anchor rx_submitted; - atomic_t active_channels; struct usb_device *udev; + u8 active_channels; }; /* 'allocate' a tx context. @@ -314,7 +322,7 @@ /* device reports out of range channel id */ if (hf->channel >= GS_MAX_INTF) - goto resubmit_urb; + goto device_detach; dev = usbcan->canch[hf->channel]; @@ -329,13 +337,13 @@ if (!skb) return; - cf->can_id = hf->can_id; + cf->can_id = le32_to_cpu(hf->can_id); cf->can_dlc = get_can_dlc(hf->can_dlc); memcpy(cf->data, hf->data, 8); /* ERROR frames tell us information about the controller */ - if (hf->can_id & CAN_ERR_FLAG) + if (le32_to_cpu(hf->can_id) & CAN_ERR_FLAG) gs_update_state(dev, cf); netdev->stats.rx_packets++; @@ -373,6 +381,9 @@ } if (hf->flags & GS_CAN_FLAG_OVERFLOW) { + stats->rx_over_errors++; + stats->rx_errors++; + skb = alloc_can_err_skb(netdev, &cf); if (!skb) goto resubmit_urb; @@ -380,8 +391,6 @@ cf->can_id |= CAN_ERR_CRTL; cf->can_dlc = CAN_ERR_DLC; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; - stats->rx_over_errors++; - stats->rx_errors++; netif_rx(skb); } @@ -399,6 +408,7 @@ /* USB failure take down all interfaces */ if (rc == -ENODEV) { + device_detach: for (rc = 0; rc < GS_MAX_INTF; rc++) { if (usbcan->canch[rc]) netif_device_detach(usbcan->canch[rc]->netdev); @@ -418,11 +428,11 @@ if (!dbt) return -ENOMEM; - dbt->prop_seg = bt->prop_seg; - dbt->phase_seg1 = bt->phase_seg1; - dbt->phase_seg2 = bt->phase_seg2; - dbt->sjw = bt->sjw; - dbt->brp = bt->brp; + dbt->prop_seg = cpu_to_le32(bt->prop_seg); + dbt->phase_seg1 = cpu_to_le32(bt->phase_seg1); + dbt->phase_seg2 = cpu_to_le32(bt->phase_seg2); + dbt->sjw = cpu_to_le32(bt->sjw); + dbt->brp = cpu_to_le32(bt->brp); /* request bit timings */ rc = usb_control_msg(interface_to_usbdev(intf), @@ -500,10 +510,12 @@ hf->echo_id = idx; hf->channel = dev->channel; + hf->flags = 0; + hf->reserved = 0; cf = (struct can_frame *)skb->data; - hf->can_id = cf->can_id; + hf->can_id = cpu_to_le32(cf->can_id); hf->can_dlc = cf->can_dlc; memcpy(hf->data, cf->data, cf->can_dlc); @@ -573,15 +585,17 @@ int rc, i; struct gs_device_mode *dm; u32 ctrlmode; + u32 flags = 0; rc = open_candev(netdev); if (rc) return rc; - if (atomic_add_return(1, &parent->active_channels) == 1) { + if (!parent->active_channels) { for (i = 0; i < GS_MAX_RX_URBS; i++) { struct urb *urb; u8 *buf; + dma_addr_t buf_dma; /* alloc rx urb */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -592,7 +606,7 @@ buf = usb_alloc_coherent(dev->udev, sizeof(struct gs_host_frame), GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); @@ -600,6 +614,8 @@ return -ENOMEM; } + urb->transfer_dma = buf_dma; + /* fill, anchor, and submit rx urb */ usb_fill_bulk_urb(urb, dev->udev, @@ -623,10 +639,17 @@ rc); usb_unanchor_urb(urb); + usb_free_coherent(dev->udev, + sizeof(struct gs_host_frame), + buf, + buf_dma); usb_free_urb(urb); break; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + /* Drop reference, * USB core will take care of freeing it */ @@ -640,24 +663,25 @@ /* flags */ ctrlmode = dev->can.ctrlmode; - dm->flags = 0; if (ctrlmode & CAN_CTRLMODE_LOOPBACK) - dm->flags |= GS_CAN_MODE_LOOP_BACK; + flags |= GS_CAN_MODE_LOOP_BACK; else if (ctrlmode & CAN_CTRLMODE_LISTENONLY) - dm->flags |= GS_CAN_MODE_LISTEN_ONLY; + flags |= GS_CAN_MODE_LISTEN_ONLY; /* Controller is not allowed to retry TX * this mode is unavailable on atmels uc3c hardware */ if (ctrlmode & CAN_CTRLMODE_ONE_SHOT) - dm->flags |= GS_CAN_MODE_ONE_SHOT; + flags |= GS_CAN_MODE_ONE_SHOT; if (ctrlmode & CAN_CTRLMODE_3_SAMPLES) - dm->flags |= GS_CAN_MODE_TRIPLE_SAMPLE; + flags |= GS_CAN_MODE_TRIPLE_SAMPLE; /* finally start device */ - dm->mode = GS_CAN_MODE_START; + dev->can.state = CAN_STATE_ERROR_ACTIVE; + dm->mode = cpu_to_le32(GS_CAN_MODE_START); + dm->flags = cpu_to_le32(flags); rc = usb_control_msg(interface_to_usbdev(dev->iface), usb_sndctrlpipe(interface_to_usbdev(dev->iface), 0), GS_USB_BREQ_MODE, @@ -672,13 +696,13 @@ if (rc < 0) { netdev_err(netdev, "Couldn't start device (err=%d)\n", rc); kfree(dm); + dev->can.state = CAN_STATE_STOPPED; return rc; } kfree(dm); - dev->can.state = CAN_STATE_ERROR_ACTIVE; - + parent->active_channels++; if (!(dev->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) netif_start_queue(netdev); @@ -690,17 +714,27 @@ int rc; struct gs_can *dev = netdev_priv(netdev); struct gs_usb *parent = dev->parent; + unsigned int i; netif_stop_queue(netdev); /* Stop polling */ - if (atomic_dec_and_test(&parent->active_channels)) + parent->active_channels--; + if (!parent->active_channels) { usb_kill_anchored_urbs(&parent->rx_submitted); + for (i = 0; i < GS_MAX_RX_URBS; i++) + usb_free_coherent(dev->udev, + sizeof(struct gs_host_frame), + dev->rxbuf[i], + dev->rxbuf_dma[i]); + } /* Stop sending URBs */ usb_kill_anchored_urbs(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); + dev->can.state = CAN_STATE_STOPPED; + /* reset the device */ rc = gs_cmd_reset(dev); if (rc < 0) @@ -737,9 +771,9 @@ return -ENOMEM; if (do_identify) - imode->mode = GS_CAN_IDENTIFY_ON; + imode->mode = cpu_to_le32(GS_CAN_IDENTIFY_ON); else - imode->mode = GS_CAN_IDENTIFY_OFF; + imode->mode = cpu_to_le32(GS_CAN_IDENTIFY_OFF); rc = usb_control_msg(interface_to_usbdev(dev->iface), usb_sndctrlpipe(interface_to_usbdev(dev->iface), @@ -790,6 +824,7 @@ struct net_device *netdev; int rc; struct gs_device_bt_const *bt_const; + u32 feature; bt_const = kmalloc(sizeof(*bt_const), GFP_KERNEL); if (!bt_const) @@ -830,14 +865,14 @@ /* dev settup */ strcpy(dev->bt_const.name, "gs_usb"); - dev->bt_const.tseg1_min = bt_const->tseg1_min; - dev->bt_const.tseg1_max = bt_const->tseg1_max; - dev->bt_const.tseg2_min = bt_const->tseg2_min; - dev->bt_const.tseg2_max = bt_const->tseg2_max; - dev->bt_const.sjw_max = bt_const->sjw_max; - dev->bt_const.brp_min = bt_const->brp_min; - dev->bt_const.brp_max = bt_const->brp_max; - dev->bt_const.brp_inc = bt_const->brp_inc; + dev->bt_const.tseg1_min = le32_to_cpu(bt_const->tseg1_min); + dev->bt_const.tseg1_max = le32_to_cpu(bt_const->tseg1_max); + dev->bt_const.tseg2_min = le32_to_cpu(bt_const->tseg2_min); + dev->bt_const.tseg2_max = le32_to_cpu(bt_const->tseg2_max); + dev->bt_const.sjw_max = le32_to_cpu(bt_const->sjw_max); + dev->bt_const.brp_min = le32_to_cpu(bt_const->brp_min); + dev->bt_const.brp_max = le32_to_cpu(bt_const->brp_max); + dev->bt_const.brp_inc = le32_to_cpu(bt_const->brp_inc); dev->udev = interface_to_usbdev(intf); dev->iface = intf; @@ -854,28 +889,29 @@ /* can settup */ dev->can.state = CAN_STATE_STOPPED; - dev->can.clock.freq = bt_const->fclk_can; + dev->can.clock.freq = le32_to_cpu(bt_const->fclk_can); dev->can.bittiming_const = &dev->bt_const; dev->can.do_set_bittiming = gs_usb_set_bittiming; dev->can.ctrlmode_supported = 0; - if (bt_const->feature & GS_CAN_FEATURE_LISTEN_ONLY) + feature = le32_to_cpu(bt_const->feature); + if (feature & GS_CAN_FEATURE_LISTEN_ONLY) dev->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; - if (bt_const->feature & GS_CAN_FEATURE_LOOP_BACK) + if (feature & GS_CAN_FEATURE_LOOP_BACK) dev->can.ctrlmode_supported |= CAN_CTRLMODE_LOOPBACK; - if (bt_const->feature & GS_CAN_FEATURE_TRIPLE_SAMPLE) + if (feature & GS_CAN_FEATURE_TRIPLE_SAMPLE) dev->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; - if (bt_const->feature & GS_CAN_FEATURE_ONE_SHOT) + if (feature & GS_CAN_FEATURE_ONE_SHOT) dev->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT; SET_NETDEV_DEV(netdev, &intf->dev); - if (dconf->sw_version > 1) - if (bt_const->feature & GS_CAN_FEATURE_IDENTIFY) + if (le32_to_cpu(dconf->sw_version) > 1) + if (feature & GS_CAN_FEATURE_IDENTIFY) netdev->ethtool_ops = &gs_usb_ethtool_ops; kfree(bt_const); @@ -910,7 +946,7 @@ if (!hconf) return -ENOMEM; - hconf->byte_order = 0x0000beef; + hconf->byte_order = cpu_to_le32(0x0000beef); /* send host config */ rc = usb_control_msg(interface_to_usbdev(intf), @@ -918,7 +954,7 @@ GS_USB_BREQ_HOST_FORMAT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1, - intf->altsetting[0].desc.bInterfaceNumber, + intf->cur_altsetting->desc.bInterfaceNumber, hconf, sizeof(*hconf), 1000); @@ -941,7 +977,7 @@ GS_USB_BREQ_DEVICE_CONFIG, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, 1, - intf->altsetting[0].desc.bInterfaceNumber, + intf->cur_altsetting->desc.bInterfaceNumber, dconf, sizeof(*dconf), 1000); @@ -971,8 +1007,6 @@ init_usb_anchor(&dev->rx_submitted); - atomic_set(&dev->active_channels, 0); - usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); --- linux-oracle-5.4.0.orig/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ linux-oracle-5.4.0/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -35,9 +35,10 @@ #define KVASER_USB_RX_BUFFER_SIZE 3072 #define KVASER_USB_MAX_NET_DEVICES 5 -/* USB devices features */ -#define KVASER_USB_HAS_SILENT_MODE BIT(0) -#define KVASER_USB_HAS_TXRX_ERRORS BIT(1) +/* Kvaser USB device quirks */ +#define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) +#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) +#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2) /* Device capabilities */ #define KVASER_USB_CAP_BERR_CAP 0x01 @@ -65,12 +66,7 @@ struct kvaser_usb_dev_card_data { u32 ctrlmode_supported; u32 capabilities; - union { - struct { - enum kvaser_usb_leaf_family family; - } leaf; - struct kvaser_usb_dev_card_data_hydra hydra; - }; + struct kvaser_usb_dev_card_data_hydra hydra; }; /* Context for an outstanding, not yet ACKed, transmission */ @@ -80,11 +76,19 @@ int dlc; }; +struct kvaser_usb_busparams { + __le32 bitrate; + u8 tseg1; + u8 tseg2; + u8 sjw; + u8 nsamples; +} __packed; + struct kvaser_usb { struct usb_device *udev; struct usb_interface *intf; struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES]; - const struct kvaser_usb_dev_ops *ops; + const struct kvaser_usb_driver_info *driver_info; const struct kvaser_usb_dev_cfg *cfg; struct usb_endpoint_descriptor *bulk_in, *bulk_out; @@ -108,13 +112,19 @@ struct can_priv can; struct can_berr_counter bec; + /* subdriver-specific data */ + void *sub_priv; + struct kvaser_usb *dev; struct net_device *netdev; int channel; - struct completion start_comp, stop_comp, flush_comp; + struct completion start_comp, stop_comp, flush_comp, + get_busparams_comp; struct usb_anchor tx_submitted; + struct kvaser_usb_busparams busparams_nominal, busparams_data; + spinlock_t tx_contexts_lock; /* lock for active_tx_contexts */ int active_tx_contexts; struct kvaser_usb_tx_urb_context tx_contexts[]; @@ -124,11 +134,15 @@ * struct kvaser_usb_dev_ops - Device specific functions * @dev_set_mode: used for can.do_set_mode * @dev_set_bittiming: used for can.do_set_bittiming + * @dev_get_busparams: readback arbitration busparams * @dev_set_data_bittiming: used for can.do_set_data_bittiming + * @dev_get_data_busparams: readback data busparams * @dev_get_berr_counter: used for can.do_get_berr_counter * * @dev_setup_endpoints: setup USB in and out endpoints * @dev_init_card: initialize card + * @dev_init_channel: initialize channel + * @dev_remove_channel: uninitialize channel * @dev_get_software_info: get software info * @dev_get_software_details: get software details * @dev_get_card_info: get card info @@ -144,12 +158,18 @@ */ struct kvaser_usb_dev_ops { int (*dev_set_mode)(struct net_device *netdev, enum can_mode mode); - int (*dev_set_bittiming)(struct net_device *netdev); - int (*dev_set_data_bittiming)(struct net_device *netdev); + int (*dev_set_bittiming)(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams); + int (*dev_get_busparams)(struct kvaser_usb_net_priv *priv); + int (*dev_set_data_bittiming)(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams); + int (*dev_get_data_busparams)(struct kvaser_usb_net_priv *priv); int (*dev_get_berr_counter)(const struct net_device *netdev, struct can_berr_counter *bec); int (*dev_setup_endpoints)(struct kvaser_usb *dev); int (*dev_init_card)(struct kvaser_usb *dev); + int (*dev_init_channel)(struct kvaser_usb_net_priv *priv); + void (*dev_remove_channel)(struct kvaser_usb_net_priv *priv); int (*dev_get_software_info)(struct kvaser_usb *dev); int (*dev_get_software_details)(struct kvaser_usb *dev); int (*dev_get_card_info)(struct kvaser_usb *dev); @@ -166,6 +186,12 @@ int *cmd_len, u16 transid); }; +struct kvaser_usb_driver_info { + u32 quirks; + enum kvaser_usb_leaf_family family; + const struct kvaser_usb_dev_ops *ops; +}; + struct kvaser_usb_dev_cfg { const struct can_clock clock; const unsigned int timestamp_freq; @@ -176,6 +202,8 @@ extern const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops; extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops; +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv); + int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len, int *actual_len); @@ -185,4 +213,7 @@ int len); int kvaser_usb_can_rx_over_error(struct net_device *netdev); + +extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const; + #endif /* KVASER_USB_H */ --- linux-oracle-5.4.0.orig/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ linux-oracle-5.4.0/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -79,104 +79,135 @@ #define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID 269 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 270 -static inline bool kvaser_is_leaf(const struct usb_device_id *id) -{ - return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID && - id->idProduct <= USB_CAN_R_PRODUCT_ID) || - (id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID && - id->idProduct <= USB_MINI_PCIE_2HS_PRODUCT_ID); -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = { + .quirks = 0, + .ops = &kvaser_usb_hydra_dev_ops, +}; -static inline bool kvaser_is_usbcan(const struct usb_device_id *id) -{ - return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID && - id->idProduct <= USB_MEMORATOR_PRODUCT_ID; -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_HAS_SILENT_MODE, + .family = KVASER_USBCAN, + .ops = &kvaser_usb_leaf_dev_ops, +}; -static inline bool kvaser_is_hydra(const struct usb_device_id *id) -{ - return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID && - id->idProduct <= USB_HYBRID_PRO_CANLIN_PRODUCT_ID; -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { + .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; + +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; + +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_HAS_SILENT_MODE | + KVASER_USB_QUIRK_IGNORE_CLK_FREQ, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; + +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = { + .quirks = 0, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; static const struct usb_device_id kvaser_usb_table[] = { - /* Leaf USB product IDs */ - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) }, + /* Leaf M32C USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + + /* Leaf i.MX28 USB product IDs */ + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, /* USBCANII USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, /* Minihydra USB product IDs */ - { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, { } }; MODULE_DEVICE_TABLE(usb, kvaser_usb_table); @@ -235,7 +266,7 @@ } usb_free_urb(urb); - return 0; + return err; } int kvaser_usb_can_rx_over_error(struct net_device *netdev) @@ -267,6 +298,7 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) { struct kvaser_usb *dev = urb->context; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; unsigned int i; @@ -283,8 +315,8 @@ goto resubmit_urb; } - dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer, - urb->actual_length); + ops->dev_read_bulk_callback(dev, urb->transfer_buffer, + urb->actual_length); resubmit_urb: usb_fill_bulk_urb(urb, dev->udev, @@ -378,21 +410,18 @@ { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; err = open_candev(netdev); if (err) return err; - err = kvaser_usb_setup_rx_urbs(dev); + err = ops->dev_set_opt_mode(priv); if (err) goto error; - err = dev->ops->dev_set_opt_mode(priv); - if (err) - goto error; - - err = dev->ops->dev_start_chip(priv); + err = ops->dev_start_chip(priv); if (err) { netdev_warn(netdev, "Cannot start device, error %d\n", err); goto error; @@ -421,7 +450,7 @@ /* This method might sleep. Do not call it in the atomic context * of URB completions. */ -static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv) { usb_kill_anchored_urbs(&priv->tx_submitted); kvaser_usb_reset_tx_urb_contexts(priv); @@ -449,22 +478,23 @@ { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; netif_stop_queue(netdev); - err = dev->ops->dev_flush_queue(priv); + err = ops->dev_flush_queue(priv); if (err) netdev_warn(netdev, "Cannot flush queue, error %d\n", err); - if (dev->ops->dev_reset_chip) { - err = dev->ops->dev_reset_chip(dev, priv->channel); + if (ops->dev_reset_chip) { + err = ops->dev_reset_chip(dev, priv->channel); if (err) netdev_warn(netdev, "Cannot reset card, error %d\n", err); } - err = dev->ops->dev_stop_chip(priv); + err = ops->dev_stop_chip(priv); if (err) netdev_warn(netdev, "Cannot stop device, error %d\n", err); @@ -477,6 +507,93 @@ return 0; } +static int kvaser_usb_set_bittiming(struct net_device *netdev) +{ + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + struct can_bittiming *bt = &priv->can.bittiming; + + struct kvaser_usb_busparams busparams; + int tseg1 = bt->prop_seg + bt->phase_seg1; + int tseg2 = bt->phase_seg2; + int sjw = bt->sjw; + int err = -EOPNOTSUPP; + + busparams.bitrate = cpu_to_le32(bt->bitrate); + busparams.sjw = (u8)sjw; + busparams.tseg1 = (u8)tseg1; + busparams.tseg2 = (u8)tseg2; + if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) + busparams.nsamples = 3; + else + busparams.nsamples = 1; + + err = ops->dev_set_bittiming(netdev, &busparams); + if (err) + return err; + + err = kvaser_usb_setup_rx_urbs(priv->dev); + if (err) + return err; + + err = ops->dev_get_busparams(priv); + if (err) { + /* Treat EOPNOTSUPP as success */ + if (err == -EOPNOTSUPP) + err = 0; + return err; + } + + if (memcmp(&busparams, &priv->busparams_nominal, + sizeof(priv->busparams_nominal)) != 0) + err = -EINVAL; + + return err; +} + +static int kvaser_usb_set_data_bittiming(struct net_device *netdev) +{ + struct kvaser_usb_net_priv *priv = netdev_priv(netdev); + struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; + struct can_bittiming *dbt = &priv->can.data_bittiming; + + struct kvaser_usb_busparams busparams; + int tseg1 = dbt->prop_seg + dbt->phase_seg1; + int tseg2 = dbt->phase_seg2; + int sjw = dbt->sjw; + int err; + + if (!ops->dev_set_data_bittiming || + !ops->dev_get_data_busparams) + return -EOPNOTSUPP; + + busparams.bitrate = cpu_to_le32(dbt->bitrate); + busparams.sjw = (u8)sjw; + busparams.tseg1 = (u8)tseg1; + busparams.tseg2 = (u8)tseg2; + busparams.nsamples = 1; + + err = ops->dev_set_data_bittiming(netdev, &busparams); + if (err) + return err; + + err = kvaser_usb_setup_rx_urbs(priv->dev); + if (err) + return err; + + err = ops->dev_get_data_busparams(priv); + if (err) + return err; + + if (memcmp(&busparams, &priv->busparams_data, + sizeof(priv->busparams_data)) != 0) + err = -EINVAL; + + return err; +} + static void kvaser_usb_write_bulk_callback(struct urb *urb) { struct kvaser_usb_tx_urb_context *context = urb->context; @@ -503,6 +620,7 @@ { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; struct net_device_stats *stats = &netdev->stats; struct kvaser_usb_tx_urb_context *context = NULL; struct urb *urb; @@ -545,8 +663,8 @@ goto freeurb; } - buf = dev->ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len, - context->echo_index); + buf = ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len, + context->echo_index); if (!buf) { stats->tx_dropped++; dev_kfree_skb(skb); @@ -611,6 +729,7 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) { + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int i; for (i = 0; i < dev->nchannels; i++) { @@ -626,19 +745,23 @@ if (!dev->nets[i]) continue; + if (ops->dev_remove_channel) + ops->dev_remove_channel(dev->nets[i]); + free_candev(dev->nets[i]->netdev); } } -static int kvaser_usb_init_one(struct kvaser_usb *dev, - const struct usb_device_id *id, int channel) +static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) { struct net_device *netdev; struct kvaser_usb_net_priv *priv; + const struct kvaser_usb_driver_info *driver_info = dev->driver_info; + const struct kvaser_usb_dev_ops *ops = driver_info->ops; int err; - if (dev->ops->dev_reset_chip) { - err = dev->ops->dev_reset_chip(dev, channel); + if (ops->dev_reset_chip) { + err = ops->dev_reset_chip(dev, channel); if (err) return err; } @@ -655,6 +778,8 @@ init_usb_anchor(&priv->tx_submitted); init_completion(&priv->start_comp); init_completion(&priv->stop_comp); + init_completion(&priv->flush_comp); + init_completion(&priv->get_busparams_comp); priv->can.ctrlmode_supported = 0; priv->dev = dev; @@ -667,20 +792,19 @@ priv->can.state = CAN_STATE_STOPPED; priv->can.clock.freq = dev->cfg->clock.freq; priv->can.bittiming_const = dev->cfg->bittiming_const; - priv->can.do_set_bittiming = dev->ops->dev_set_bittiming; - priv->can.do_set_mode = dev->ops->dev_set_mode; - if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) || + priv->can.do_set_bittiming = kvaser_usb_set_bittiming; + priv->can.do_set_mode = ops->dev_set_mode; + if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) || (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) - priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter; - if (id->driver_info & KVASER_USB_HAS_SILENT_MODE) + priv->can.do_get_berr_counter = ops->dev_get_berr_counter; + if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE) priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported; if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; - priv->can.do_set_data_bittiming = - dev->ops->dev_set_data_bittiming; + priv->can.do_set_data_bittiming = kvaser_usb_set_data_bittiming; } netdev->flags |= IFF_ECHO; @@ -692,17 +816,26 @@ dev->nets[channel] = priv; + if (ops->dev_init_channel) { + err = ops->dev_init_channel(priv); + if (err) + goto err; + } + err = register_candev(netdev); if (err) { dev_err(&dev->intf->dev, "Failed to register CAN device\n"); - free_candev(netdev); - dev->nets[channel] = NULL; - return err; + goto err; } netdev_dbg(netdev, "device registered\n"); return 0; + +err: + free_candev(netdev); + dev->nets[channel] = NULL; + return err; } static int kvaser_usb_probe(struct usb_interface *intf, @@ -711,29 +844,22 @@ struct kvaser_usb *dev; int err; int i; + const struct kvaser_usb_driver_info *driver_info; + const struct kvaser_usb_dev_ops *ops; + + driver_info = (const struct kvaser_usb_driver_info *)id->driver_info; + if (!driver_info) + return -ENODEV; dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - if (kvaser_is_leaf(id)) { - dev->card_data.leaf.family = KVASER_LEAF; - dev->ops = &kvaser_usb_leaf_dev_ops; - } else if (kvaser_is_usbcan(id)) { - dev->card_data.leaf.family = KVASER_USBCAN; - dev->ops = &kvaser_usb_leaf_dev_ops; - } else if (kvaser_is_hydra(id)) { - dev->ops = &kvaser_usb_hydra_dev_ops; - } else { - dev_err(&intf->dev, - "Product ID (%d) is not a supported Kvaser USB device\n", - id->idProduct); - return -ENODEV; - } - dev->intf = intf; + dev->driver_info = driver_info; + ops = driver_info->ops; - err = dev->ops->dev_setup_endpoints(dev); + err = ops->dev_setup_endpoints(dev); if (err) { dev_err(&intf->dev, "Cannot get usb endpoint(s)"); return err; @@ -747,22 +873,22 @@ dev->card_data.ctrlmode_supported = 0; dev->card_data.capabilities = 0; - err = dev->ops->dev_init_card(dev); + err = ops->dev_init_card(dev); if (err) { dev_err(&intf->dev, "Failed to initialize card, error %d\n", err); return err; } - err = dev->ops->dev_get_software_info(dev); + err = ops->dev_get_software_info(dev); if (err) { dev_err(&intf->dev, "Cannot get software info, error %d\n", err); return err; } - if (dev->ops->dev_get_software_details) { - err = dev->ops->dev_get_software_details(dev); + if (ops->dev_get_software_details) { + err = ops->dev_get_software_details(dev); if (err) { dev_err(&intf->dev, "Cannot get software details, error %d\n", err); @@ -780,14 +906,14 @@ dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); - err = dev->ops->dev_get_card_info(dev); + err = ops->dev_get_card_info(dev); if (err) { dev_err(&intf->dev, "Cannot get card info, error %d\n", err); return err; } - if (dev->ops->dev_get_capabilities) { - err = dev->ops->dev_get_capabilities(dev); + if (ops->dev_get_capabilities) { + err = ops->dev_get_capabilities(dev); if (err) { dev_err(&intf->dev, "Cannot get capabilities, error %d\n", err); @@ -797,7 +923,7 @@ } for (i = 0; i < dev->nchannels; i++) { - err = kvaser_usb_init_one(dev, id, i); + err = kvaser_usb_init_one(dev, i); if (err) { kvaser_usb_remove_interfaces(dev); return err; --- linux-oracle-5.4.0.orig/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ linux-oracle-5.4.0/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -43,6 +43,8 @@ /* Minihydra command IDs */ #define CMD_SET_BUSPARAMS_REQ 16 +#define CMD_GET_BUSPARAMS_REQ 17 +#define CMD_GET_BUSPARAMS_RESP 18 #define CMD_GET_CHIP_STATE_REQ 19 #define CMD_CHIP_STATE_EVENT 20 #define CMD_SET_DRIVERMODE_REQ 21 @@ -193,21 +195,26 @@ #define KVASER_USB_HYDRA_BUS_MODE_CANFD_ISO 0x01 #define KVASER_USB_HYDRA_BUS_MODE_NONISO 0x02 struct kvaser_cmd_set_busparams { - __le32 bitrate; - u8 tseg1; - u8 tseg2; - u8 sjw; - u8 nsamples; + struct kvaser_usb_busparams busparams_nominal; u8 reserved0[4]; - __le32 bitrate_d; - u8 tseg1_d; - u8 tseg2_d; - u8 sjw_d; - u8 nsamples_d; + struct kvaser_usb_busparams busparams_data; u8 canfd_mode; u8 reserved1[7]; } __packed; +/* Busparam type */ +#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN 0x00 +#define KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD 0x01 +struct kvaser_cmd_get_busparams_req { + u8 type; + u8 reserved[27]; +} __packed; + +struct kvaser_cmd_get_busparams_res { + struct kvaser_usb_busparams busparams; + u8 reserved[20]; +} __packed; + /* Ctrl modes */ #define KVASER_USB_HYDRA_CTRLMODE_NORMAL 0x01 #define KVASER_USB_HYDRA_CTRLMODE_LISTEN 0x02 @@ -278,6 +285,8 @@ struct kvaser_cmd_error_event error_event; struct kvaser_cmd_set_busparams set_busparams_req; + struct kvaser_cmd_get_busparams_req get_busparams_req; + struct kvaser_cmd_get_busparams_res get_busparams_res; struct kvaser_cmd_chip_state_event chip_state_event; @@ -293,6 +302,7 @@ #define KVASER_USB_HYDRA_CF_FLAG_OVERRUN BIT(1) #define KVASER_USB_HYDRA_CF_FLAG_REMOTE_FRAME BIT(4) #define KVASER_USB_HYDRA_CF_FLAG_EXTENDED_ID BIT(5) +#define KVASER_USB_HYDRA_CF_FLAG_TX_ACK BIT(6) /* CAN frame flags. Used in ext_rx_can and ext_tx_can */ #define KVASER_USB_HYDRA_CF_FLAG_OSM_NACK BIT(12) #define KVASER_USB_HYDRA_CF_FLAG_ABL BIT(13) @@ -359,6 +369,10 @@ } __packed; } __packed; +struct kvaser_usb_net_hydra_priv { + int pending_get_busparams_type; +}; + static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = { .name = "kvaser_usb_kcan", .tseg1_min = 1, @@ -367,11 +381,11 @@ .tseg2_max = 32, .sjw_max = 16, .brp_min = 1, - .brp_max = 4096, + .brp_max = 8192, .brp_inc = 1, }; -static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = { +const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = { .name = "kvaser_usb_flex", .tseg1_min = 4, .tseg1_max = 16, @@ -504,6 +518,7 @@ u8 cmd_no, int channel) { struct kvaser_cmd *cmd; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -511,6 +526,7 @@ return -ENOMEM; cmd->header.cmd_no = cmd_no; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); if (channel < 0) { kvaser_usb_hydra_set_cmd_dest_he (cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL); @@ -527,7 +543,7 @@ kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -543,6 +559,7 @@ { struct kvaser_cmd *cmd; struct kvaser_usb *dev = priv->dev; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_ATOMIC); @@ -550,14 +567,14 @@ return -ENOMEM; cmd->header.cmd_no = cmd_no; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd_async(priv, cmd, - kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd_async(priv, cmd, cmd_len); if (err) kfree(cmd); @@ -701,6 +718,7 @@ { struct kvaser_usb_dev_card_data *card_data = &dev->card_data; struct kvaser_cmd *cmd; + size_t cmd_len; u32 value = 0; u32 mask = 0; u16 cap_cmd_res; @@ -712,13 +730,14 @@ return -ENOMEM; cmd->header.cmd_no = CMD_GET_CAPABILITIES_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); cmd->cap_req.cap_cmd = cpu_to_le16(cap_cmd_req); kvaser_usb_hydra_set_cmd_dest_he(cmd, card_data->hydra.sysdbg_he); kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -812,6 +831,39 @@ complete(&priv->flush_comp); } +static void kvaser_usb_hydra_get_busparams_reply(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + struct kvaser_usb_net_priv *priv; + struct kvaser_usb_net_hydra_priv *hydra; + + priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd); + if (!priv) + return; + + hydra = priv->sub_priv; + if (!hydra) + return; + + switch (hydra->pending_get_busparams_type) { + case KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN: + memcpy(&priv->busparams_nominal, &cmd->get_busparams_res.busparams, + sizeof(priv->busparams_nominal)); + break; + case KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD: + memcpy(&priv->busparams_data, &cmd->get_busparams_res.busparams, + sizeof(priv->busparams_nominal)); + break; + default: + dev_warn(&dev->intf->dev, "Unknown get_busparams_type %d\n", + hydra->pending_get_busparams_type); + break; + } + hydra->pending_get_busparams_type = -1; + + complete(&priv->get_busparams_comp); +} + static void kvaser_usb_hydra_bus_status_to_can_state(const struct kvaser_usb_net_priv *priv, u8 bus_status, @@ -890,8 +942,10 @@ new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++; - cf->data[6] = bec->txerr; - cf->data[7] = bec->rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = bec->txerr; + cf->data[7] = bec->rxerr; + } stats = &netdev->stats; stats->rx_packets++; @@ -1045,8 +1099,10 @@ shhwtstamps->hwtstamp = hwtstamp; cf->can_id |= CAN_ERR_BUSERROR; - cf->data[6] = bec.txerr; - cf->data[7] = bec.rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + } stats->rx_packets++; stats->rx_bytes += cf->can_dlc; @@ -1095,6 +1151,7 @@ struct kvaser_usb_net_priv *priv; unsigned long irq_flags; bool one_shot_fail = false; + bool is_err_frame = false; u16 transid = kvaser_usb_hydra_get_cmd_transid(cmd); priv = kvaser_usb_hydra_net_priv_from_cmd(dev, cmd); @@ -1113,10 +1170,13 @@ kvaser_usb_hydra_one_shot_fail(priv, cmd_ext); one_shot_fail = true; } + + is_err_frame = flags & KVASER_USB_HYDRA_CF_FLAG_TX_ACK && + flags & KVASER_USB_HYDRA_CF_FLAG_ERROR_FRAME; } context = &priv->tx_contexts[transid % dev->max_tx_urbs]; - if (!one_shot_fail) { + if (!one_shot_fail && !is_err_frame) { struct net_device_stats *stats = &priv->netdev->stats; stats->tx_packets++; @@ -1290,6 +1350,10 @@ kvaser_usb_hydra_state_event(dev, cmd); break; + case CMD_GET_BUSPARAMS_RESP: + kvaser_usb_hydra_get_busparams_reply(dev, cmd); + break; + case CMD_ERROR_EVENT: kvaser_usb_hydra_error_event(dev, cmd); break; @@ -1490,15 +1554,61 @@ return err; } -static int kvaser_usb_hydra_set_bittiming(struct net_device *netdev) +static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, + int busparams_type) +{ + struct kvaser_usb *dev = priv->dev; + struct kvaser_usb_net_hydra_priv *hydra = priv->sub_priv; + struct kvaser_cmd *cmd; + size_t cmd_len; + int err; + + if (!hydra) + return -EINVAL; + + cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->header.cmd_no = CMD_GET_BUSPARAMS_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); + kvaser_usb_hydra_set_cmd_dest_he + (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); + kvaser_usb_hydra_set_cmd_transid + (cmd, kvaser_usb_hydra_get_next_transid(dev)); + cmd->get_busparams_req.type = busparams_type; + hydra->pending_get_busparams_type = busparams_type; + + reinit_completion(&priv->get_busparams_comp); + + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); + if (err) + return err; + + if (!wait_for_completion_timeout(&priv->get_busparams_comp, + msecs_to_jiffies(KVASER_USB_TIMEOUT))) + return -ETIMEDOUT; + + return err; +} + +static int kvaser_usb_hydra_get_nominal_busparams(struct kvaser_usb_net_priv *priv) +{ + return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CAN); +} + +static int kvaser_usb_hydra_get_data_busparams(struct kvaser_usb_net_priv *priv) +{ + return kvaser_usb_hydra_get_busparams(priv, KVASER_USB_HYDRA_BUSPARAM_TYPE_CANFD); +} + +static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams) { struct kvaser_cmd *cmd; struct kvaser_usb_net_priv *priv = netdev_priv(netdev); - struct can_bittiming *bt = &priv->can.bittiming; struct kvaser_usb *dev = priv->dev; - int tseg1 = bt->prop_seg + bt->phase_seg1; - int tseg2 = bt->phase_seg2; - int sjw = bt->sjw; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -1506,33 +1616,29 @@ return -ENOMEM; cmd->header.cmd_no = CMD_SET_BUSPARAMS_REQ; - cmd->set_busparams_req.bitrate = cpu_to_le32(bt->bitrate); - cmd->set_busparams_req.sjw = (u8)sjw; - cmd->set_busparams_req.tseg1 = (u8)tseg1; - cmd->set_busparams_req.tseg2 = (u8)tseg2; - cmd->set_busparams_req.nsamples = 1; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); + memcpy(&cmd->set_busparams_req.busparams_nominal, busparams, + sizeof(cmd->set_busparams_req.busparams_nominal)); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); return err; } -static int kvaser_usb_hydra_set_data_bittiming(struct net_device *netdev) +static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams) { struct kvaser_cmd *cmd; struct kvaser_usb_net_priv *priv = netdev_priv(netdev); - struct can_bittiming *dbt = &priv->can.data_bittiming; struct kvaser_usb *dev = priv->dev; - int tseg1 = dbt->prop_seg + dbt->phase_seg1; - int tseg2 = dbt->phase_seg2; - int sjw = dbt->sjw; + size_t cmd_len; int err; cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); @@ -1540,11 +1646,9 @@ return -ENOMEM; cmd->header.cmd_no = CMD_SET_BUSPARAMS_FD_REQ; - cmd->set_busparams_req.bitrate_d = cpu_to_le32(dbt->bitrate); - cmd->set_busparams_req.sjw_d = (u8)sjw; - cmd->set_busparams_req.tseg1_d = (u8)tseg1; - cmd->set_busparams_req.tseg2_d = (u8)tseg2; - cmd->set_busparams_req.nsamples_d = 1; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); + memcpy(&cmd->set_busparams_req.busparams_data, busparams, + sizeof(cmd->set_busparams_req.busparams_data)); if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { if (priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO) @@ -1560,7 +1664,7 @@ kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); @@ -1590,7 +1694,7 @@ struct usb_endpoint_descriptor *ep; int i; - iface_desc = &dev->intf->altsetting[0]; + iface_desc = dev->intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { ep = &iface_desc->endpoint[i].desc; @@ -1651,6 +1755,19 @@ return 0; } +static int kvaser_usb_hydra_init_channel(struct kvaser_usb_net_priv *priv) +{ + struct kvaser_usb_net_hydra_priv *hydra; + + hydra = devm_kzalloc(&priv->dev->intf->dev, sizeof(*hydra), GFP_KERNEL); + if (!hydra) + return -ENOMEM; + + priv->sub_priv = hydra; + + return 0; +} + static int kvaser_usb_hydra_get_software_info(struct kvaser_usb *dev) { struct kvaser_cmd cmd; @@ -1675,6 +1792,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) { struct kvaser_cmd *cmd; + size_t cmd_len; int err; u32 flags; struct kvaser_usb_dev_card_data *card_data = &dev->card_data; @@ -1684,6 +1802,7 @@ return -ENOMEM; cmd->header.cmd_no = CMD_GET_SOFTWARE_DETAILS_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); cmd->sw_detail_req.use_ext_cmd = 1; kvaser_usb_hydra_set_cmd_dest_he (cmd, KVASER_USB_HYDRA_HE_ADDRESS_ILLEGAL); @@ -1691,7 +1810,7 @@ kvaser_usb_hydra_set_cmd_transid (cmd, kvaser_usb_hydra_get_next_transid(dev)); - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); if (err) goto end; @@ -1807,6 +1926,7 @@ { struct kvaser_usb *dev = priv->dev; struct kvaser_cmd *cmd; + size_t cmd_len; int err; if ((priv->can.ctrlmode & @@ -1822,6 +1942,7 @@ return -ENOMEM; cmd->header.cmd_no = CMD_SET_DRIVERMODE_REQ; + cmd_len = kvaser_usb_hydra_cmd_size(cmd); kvaser_usb_hydra_set_cmd_dest_he (cmd, dev->card_data.hydra.channel_to_he[priv->channel]); kvaser_usb_hydra_set_cmd_transid @@ -1831,7 +1952,7 @@ else cmd->set_ctrlmode.mode = KVASER_USB_HYDRA_CTRLMODE_NORMAL; - err = kvaser_usb_send_cmd(dev, cmd, kvaser_usb_hydra_cmd_size(cmd)); + err = kvaser_usb_send_cmd(dev, cmd, cmd_len); kfree(cmd); return err; @@ -1841,7 +1962,7 @@ { int err; - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ, priv->channel); @@ -1859,7 +1980,7 @@ { int err; - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); /* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT * see comment in kvaser_usb_hydra_update_state() @@ -1882,7 +2003,7 @@ { int err; - init_completion(&priv->flush_comp); + reinit_completion(&priv->flush_comp); err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_FLUSH_QUEUE, priv->channel); @@ -1993,10 +2114,13 @@ const struct kvaser_usb_dev_ops kvaser_usb_hydra_dev_ops = { .dev_set_mode = kvaser_usb_hydra_set_mode, .dev_set_bittiming = kvaser_usb_hydra_set_bittiming, + .dev_get_busparams = kvaser_usb_hydra_get_nominal_busparams, .dev_set_data_bittiming = kvaser_usb_hydra_set_data_bittiming, + .dev_get_data_busparams = kvaser_usb_hydra_get_data_busparams, .dev_get_berr_counter = kvaser_usb_hydra_get_berr_counter, .dev_setup_endpoints = kvaser_usb_hydra_setup_endpoints, .dev_init_card = kvaser_usb_hydra_init_card, + .dev_init_channel = kvaser_usb_hydra_init_channel, .dev_get_software_info = kvaser_usb_hydra_get_software_info, .dev_get_software_details = kvaser_usb_hydra_get_software_details, .dev_get_card_info = kvaser_usb_hydra_get_card_info, @@ -2024,5 +2148,5 @@ .freq = 24000000, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; --- linux-oracle-5.4.0.orig/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ linux-oracle-5.4.0/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,10 +29,6 @@ #include "kvaser_usb.h" -/* Forward declaration */ -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg; - -#define CAN_USB_CLOCK 8000000 #define MAX_USBCAN_NET_DEVICES 2 /* Command header size */ @@ -59,6 +56,9 @@ #define CMD_RX_EXT_MESSAGE 14 #define CMD_TX_EXT_MESSAGE 15 #define CMD_SET_BUS_PARAMS 16 +#define CMD_GET_BUS_PARAMS 17 +#define CMD_GET_BUS_PARAMS_REPLY 18 +#define CMD_GET_CHIP_STATE 19 #define CMD_CHIP_STATE_EVENT 20 #define CMD_SET_CTRL_MODE 21 #define CMD_RESET_CHIP 24 @@ -73,13 +73,24 @@ #define CMD_GET_CARD_INFO_REPLY 35 #define CMD_GET_SOFTWARE_INFO 38 #define CMD_GET_SOFTWARE_INFO_REPLY 39 +#define CMD_ERROR_EVENT 45 #define CMD_FLUSH_QUEUE 48 #define CMD_TX_ACKNOWLEDGE 50 #define CMD_CAN_ERROR_EVENT 51 #define CMD_FLUSH_QUEUE_REPLY 68 +#define CMD_GET_CAPABILITIES_REQ 95 +#define CMD_GET_CAPABILITIES_RESP 96 #define CMD_LEAF_LOG_MESSAGE 106 +/* Leaf frequency options */ +#define KVASER_USB_LEAF_SWOPTION_FREQ_MASK 0x60 +#define KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK 0 +#define KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK BIT(5) +#define KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK BIT(6) + +#define KVASER_USB_LEAF_SWOPTION_EXT_CAP BIT(12) + /* error factors */ #define M16C_EF_ACKE BIT(0) #define M16C_EF_CRCE BIT(1) @@ -98,16 +109,6 @@ #define USBCAN_ERROR_STATE_RX_ERROR BIT(1) #define USBCAN_ERROR_STATE_BUSERROR BIT(2) -/* bittiming parameters */ -#define KVASER_USB_TSEG1_MIN 1 -#define KVASER_USB_TSEG1_MAX 16 -#define KVASER_USB_TSEG2_MIN 1 -#define KVASER_USB_TSEG2_MAX 8 -#define KVASER_USB_SJW_MAX 4 -#define KVASER_USB_BRP_MIN 1 -#define KVASER_USB_BRP_MAX 64 -#define KVASER_USB_BRP_INC 1 - /* ctrl modes */ #define KVASER_CTRL_MODE_NORMAL 1 #define KVASER_CTRL_MODE_SILENT 2 @@ -164,11 +165,7 @@ struct kvaser_cmd_busparams { u8 tid; u8 channel; - __le32 bitrate; - u8 tseg1; - u8 tseg2; - u8 sjw; - u8 no_samp; + struct kvaser_usb_busparams busparams; } __packed; struct kvaser_cmd_tx_can { @@ -237,7 +234,7 @@ u8 tid; } __packed; -struct leaf_cmd_error_event { +struct leaf_cmd_can_error_event { u8 tid; u8 flags; __le16 time[3]; @@ -249,7 +246,7 @@ u8 error_factor; } __packed; -struct usbcan_cmd_error_event { +struct usbcan_cmd_can_error_event { u8 tid; u8 padding; u8 tx_errors_count_ch0; @@ -261,6 +258,28 @@ __le16 time; } __packed; +/* CMD_ERROR_EVENT error codes */ +#define KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL 0x8 +#define KVASER_USB_LEAF_ERROR_EVENT_PARAM 0x9 + +struct leaf_cmd_error_event { + u8 tid; + u8 error_code; + __le16 timestamp[3]; + __le16 padding; + __le16 info1; + __le16 info2; +} __packed; + +struct usbcan_cmd_error_event { + u8 tid; + u8 error_code; + __le16 info1; + __le16 info2; + __le16 timestamp; + __le16 padding; +} __packed; + struct kvaser_cmd_ctrl_mode { u8 tid; u8 channel; @@ -285,6 +304,28 @@ u8 data[8]; } __packed; +/* Sub commands for cap_req and cap_res */ +#define KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE 0x02 +#define KVASER_USB_LEAF_CAP_CMD_ERR_REPORT 0x05 +struct kvaser_cmd_cap_req { + __le16 padding0; + __le16 cap_cmd; + __le16 padding1; + __le16 channel; +} __packed; + +/* Status codes for cap_res */ +#define KVASER_USB_LEAF_CAP_STAT_OK 0x00 +#define KVASER_USB_LEAF_CAP_STAT_NOT_IMPL 0x01 +#define KVASER_USB_LEAF_CAP_STAT_UNAVAIL 0x02 +struct kvaser_cmd_cap_res { + __le16 padding; + __le16 cap_cmd; + __le16 status; + __le32 mask; + __le32 value; +} __packed; + struct kvaser_cmd { u8 len; u8 id; @@ -300,14 +341,18 @@ struct leaf_cmd_softinfo softinfo; struct leaf_cmd_rx_can rx_can; struct leaf_cmd_chip_state_event chip_state_event; - struct leaf_cmd_error_event error_event; + struct leaf_cmd_can_error_event can_error_event; struct leaf_cmd_log_message log_message; + struct leaf_cmd_error_event error_event; + struct kvaser_cmd_cap_req cap_req; + struct kvaser_cmd_cap_res cap_res; } __packed leaf; union { struct usbcan_cmd_softinfo softinfo; struct usbcan_cmd_rx_can rx_can; struct usbcan_cmd_chip_state_event chip_state_event; + struct usbcan_cmd_can_error_event can_error_event; struct usbcan_cmd_error_event error_event; } __packed usbcan; @@ -317,6 +362,42 @@ } u; } __packed; +#define CMD_SIZE_ANY 0xff +#define kvaser_fsize(field) sizeof_field(struct kvaser_cmd, field) + +static const u8 kvaser_usb_leaf_cmd_sizes_leaf[] = { + [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.leaf.softinfo), + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.leaf.rx_can), + [CMD_LEAF_LOG_MESSAGE] = kvaser_fsize(u.leaf.log_message), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.leaf.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.leaf.can_error_event), + [CMD_GET_CAPABILITIES_RESP] = kvaser_fsize(u.leaf.cap_res), + [CMD_GET_BUS_PARAMS_REPLY] = kvaser_fsize(u.busparams), + [CMD_ERROR_EVENT] = kvaser_fsize(u.leaf.error_event), + /* ignored events: */ + [CMD_FLUSH_QUEUE_REPLY] = CMD_SIZE_ANY, +}; + +static const u8 kvaser_usb_leaf_cmd_sizes_usbcan[] = { + [CMD_START_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_STOP_CHIP_REPLY] = kvaser_fsize(u.simple), + [CMD_GET_CARD_INFO_REPLY] = kvaser_fsize(u.cardinfo), + [CMD_TX_ACKNOWLEDGE] = kvaser_fsize(u.tx_acknowledge_header), + [CMD_GET_SOFTWARE_INFO_REPLY] = kvaser_fsize(u.usbcan.softinfo), + [CMD_RX_STD_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_RX_EXT_MESSAGE] = kvaser_fsize(u.usbcan.rx_can), + [CMD_CHIP_STATE_EVENT] = kvaser_fsize(u.usbcan.chip_state_event), + [CMD_CAN_ERROR_EVENT] = kvaser_fsize(u.usbcan.can_error_event), + [CMD_ERROR_EVENT] = kvaser_fsize(u.usbcan.error_event), + /* ignored events: */ + [CMD_USBCAN_CLOCK_OVERFLOW_EVENT] = CMD_SIZE_ANY, +}; + /* Summary of a kvaser error event, for a unified Leaf/Usbcan error * handling. Some discrepancies between the two families exist: * @@ -340,6 +421,113 @@ }; }; +struct kvaser_usb_net_leaf_priv { + struct kvaser_usb_net_priv *net; + + struct delayed_work chip_state_req_work; +}; + +static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = { + .name = "kvaser_usb_ucii", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 16, + .brp_inc = 1, +}; + +static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = { + .name = "kvaser_usb_leaf", + .tseg1_min = 3, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 2, + .brp_max = 128, + .brp_inc = 2, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = { + .clock = { + .freq = 8000000, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = { + .clock = { + .freq = 16000000, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = { + .clock = { + .freq = 16000000, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = { + .clock = { + .freq = 24000000, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = { + .clock = { + .freq = 32000000, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, +}; + +static int kvaser_usb_leaf_verify_size(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + /* buffer size >= cmd->len ensured by caller */ + u8 min_size = 0; + + switch (dev->driver_info->family) { + case KVASER_LEAF: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_leaf)) + min_size = kvaser_usb_leaf_cmd_sizes_leaf[cmd->id]; + break; + case KVASER_USBCAN: + if (cmd->id < ARRAY_SIZE(kvaser_usb_leaf_cmd_sizes_usbcan)) + min_size = kvaser_usb_leaf_cmd_sizes_usbcan[cmd->id]; + break; + } + + if (min_size == CMD_SIZE_ANY) + return 0; + + if (min_size) { + min_size += CMD_HEADER_LEN; + if (cmd->len >= min_size) + return 0; + + dev_err_ratelimited(&dev->intf->dev, + "Received command %u too short (size %u, needed %u)", + cmd->id, cmd->len, min_size); + return -EIO; + } + + dev_warn_ratelimited(&dev->intf->dev, + "Unhandled command (%d, size %d)\n", + cmd->id, cmd->len); + return -EINVAL; +} + static void * kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, const struct sk_buff *skb, int *frame_len, @@ -359,7 +547,7 @@ sizeof(struct kvaser_cmd_tx_can); cmd->u.tx_can.channel = priv->channel; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags; break; @@ -447,6 +635,9 @@ end: kfree(buf); + if (err == 0) + err = kvaser_usb_leaf_verify_size(dev, cmd); + return err; } @@ -471,6 +662,37 @@ return rc; } +static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, + const struct leaf_cmd_softinfo *softinfo) +{ + u32 sw_options = le32_to_cpu(softinfo->sw_options); + + dev->fw_version = le32_to_cpu(softinfo->fw_version); + dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); + + if (sw_options & KVASER_USB_LEAF_SWOPTION_EXT_CAP) + dev->card_data.capabilities |= KVASER_USB_CAP_EXT_CAP; + + if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { + /* Firmware expects bittiming parameters calculated for 16MHz + * clock, regardless of the actual clock + */ + dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg; + } else { + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz; + break; + } + } +} + static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) { struct kvaser_cmd cmd; @@ -484,16 +706,15 @@ if (err) return err; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: - dev->fw_version = le32_to_cpu(cmd.u.leaf.softinfo.fw_version); - dev->max_tx_urbs = - le16_to_cpu(cmd.u.leaf.softinfo.max_outstanding_tx); + kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); break; case KVASER_USBCAN: dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); dev->max_tx_urbs = le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); + dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg; break; } @@ -532,13 +753,123 @@ dev->nchannels = cmd.u.cardinfo.nchannels; if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES || - (dev->card_data.leaf.family == KVASER_USBCAN && + (dev->driver_info->family == KVASER_USBCAN && dev->nchannels > MAX_USBCAN_NET_DEVICES)) return -EINVAL; return 0; } +static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev, + u16 cap_cmd_req, u16 *status) +{ + struct kvaser_usb_dev_card_data *card_data = &dev->card_data; + struct kvaser_cmd *cmd; + u32 value = 0; + u32 mask = 0; + u16 cap_cmd_res; + int err; + int i; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->id = CMD_GET_CAPABILITIES_REQ; + cmd->u.leaf.cap_req.cap_cmd = cpu_to_le16(cap_cmd_req); + cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_cap_req); + + err = kvaser_usb_send_cmd(dev, cmd, cmd->len); + if (err) + goto end; + + err = kvaser_usb_leaf_wait_cmd(dev, CMD_GET_CAPABILITIES_RESP, cmd); + if (err) + goto end; + + *status = le16_to_cpu(cmd->u.leaf.cap_res.status); + + if (*status != KVASER_USB_LEAF_CAP_STAT_OK) + goto end; + + cap_cmd_res = le16_to_cpu(cmd->u.leaf.cap_res.cap_cmd); + switch (cap_cmd_res) { + case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: + case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: + value = le32_to_cpu(cmd->u.leaf.cap_res.value); + mask = le32_to_cpu(cmd->u.leaf.cap_res.mask); + break; + default: + dev_warn(&dev->intf->dev, "Unknown capability command %u\n", + cap_cmd_res); + break; + } + + for (i = 0; i < dev->nchannels; i++) { + if (BIT(i) & (value & mask)) { + switch (cap_cmd_res) { + case KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE: + card_data->ctrlmode_supported |= + CAN_CTRLMODE_LISTENONLY; + break; + case KVASER_USB_LEAF_CAP_CMD_ERR_REPORT: + card_data->capabilities |= + KVASER_USB_CAP_BERR_CAP; + break; + } + } + } + +end: + kfree(cmd); + + return err; +} + +static int kvaser_usb_leaf_get_capabilities_leaf(struct kvaser_usb *dev) +{ + int err; + u16 status; + + if (!(dev->card_data.capabilities & KVASER_USB_CAP_EXT_CAP)) { + dev_info(&dev->intf->dev, + "No extended capability support. Upgrade device firmware.\n"); + return 0; + } + + err = kvaser_usb_leaf_get_single_capability(dev, + KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE, + &status); + if (err) + return err; + if (status) + dev_info(&dev->intf->dev, + "KVASER_USB_LEAF_CAP_CMD_LISTEN_MODE failed %u\n", + status); + + err = kvaser_usb_leaf_get_single_capability(dev, + KVASER_USB_LEAF_CAP_CMD_ERR_REPORT, + &status); + if (err) + return err; + if (status) + dev_info(&dev->intf->dev, + "KVASER_USB_LEAF_CAP_CMD_ERR_REPORT failed %u\n", + status); + + return 0; +} + +static int kvaser_usb_leaf_get_capabilities(struct kvaser_usb *dev) +{ + int err = 0; + + if (dev->driver_info->family == KVASER_LEAF) + err = kvaser_usb_leaf_get_capabilities_leaf(dev); + + return err; +} + static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { @@ -567,7 +898,7 @@ context = &priv->tx_contexts[tid % dev->max_tx_urbs]; /* Sometimes the state change doesn't come after a bus-off event */ - if (priv->can.restart_ms && priv->can.state >= CAN_STATE_BUS_OFF) { + if (priv->can.restart_ms && priv->can.state == CAN_STATE_BUS_OFF) { struct sk_buff *skb; struct can_frame *cf; @@ -608,7 +939,7 @@ struct kvaser_cmd *cmd; int err; - cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); if (!cmd) return -ENOMEM; @@ -623,6 +954,16 @@ return err; } +static void kvaser_usb_leaf_chip_state_req_work(struct work_struct *work) +{ + struct kvaser_usb_net_leaf_priv *leaf = + container_of(work, struct kvaser_usb_net_leaf_priv, + chip_state_req_work.work); + struct kvaser_usb_net_priv *priv = leaf->net; + + kvaser_usb_leaf_simple_cmd_async(priv, CMD_GET_CHIP_STATE); +} + static void kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, const struct kvaser_usb_err_summary *es, @@ -641,20 +982,16 @@ new_state = CAN_STATE_BUS_OFF; } else if (es->status & M16C_STATE_BUS_PASSIVE) { new_state = CAN_STATE_ERROR_PASSIVE; - } else if (es->status & M16C_STATE_BUS_ERROR) { + } else if ((es->status & M16C_STATE_BUS_ERROR) && + cur_state >= CAN_STATE_BUS_OFF) { /* Guard against spurious error events after a busoff */ - if (cur_state < CAN_STATE_BUS_OFF) { - if (es->txerr >= 128 || es->rxerr >= 128) - new_state = CAN_STATE_ERROR_PASSIVE; - else if (es->txerr >= 96 || es->rxerr >= 96) - new_state = CAN_STATE_ERROR_WARNING; - else if (cur_state > CAN_STATE_ERROR_ACTIVE) - new_state = CAN_STATE_ERROR_ACTIVE; - } - } - - if (!es->status) + } else if (es->txerr >= 128 || es->rxerr >= 128) { + new_state = CAN_STATE_ERROR_PASSIVE; + } else if (es->txerr >= 96 || es->rxerr >= 96) { + new_state = CAN_STATE_ERROR_WARNING; + } else { new_state = CAN_STATE_ERROR_ACTIVE; + } if (new_state != cur_state) { tx_state = (es->txerr >= es->rxerr) ? new_state : 0; @@ -664,11 +1001,11 @@ } if (priv->can.restart_ms && - cur_state >= CAN_STATE_BUS_OFF && + cur_state == CAN_STATE_BUS_OFF && new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: if (es->leaf.error_factor) { priv->can.can_stats.bus_error++; @@ -698,6 +1035,7 @@ struct sk_buff *skb; struct net_device_stats *stats; struct kvaser_usb_net_priv *priv; + struct kvaser_usb_net_leaf_priv *leaf; enum can_state old_state, new_state; if (es->channel >= dev->nchannels) { @@ -707,8 +1045,13 @@ } priv = dev->nets[es->channel]; + leaf = priv->sub_priv; stats = &priv->netdev->stats; + /* Ignore e.g. state change to bus-off reported just after stopping */ + if (!netif_running(priv->netdev)) + return; + /* Update all of the CAN interface's state and error counters before * trying any memory allocation that can actually fail with -ENOMEM. * @@ -723,6 +1066,14 @@ kvaser_usb_leaf_rx_error_update_can_state(priv, es, &tmp_cf); new_state = priv->can.state; + /* If there are errors, request status updates periodically as we do + * not get automatic notifications of improved state. + */ + if (new_state < CAN_STATE_BUS_OFF && + (es->rxerr || es->txerr || new_state == CAN_STATE_ERROR_PASSIVE)) + schedule_delayed_work(&leaf->chip_state_req_work, + msecs_to_jiffies(500)); + skb = alloc_can_err_skb(priv->netdev, &cf); if (!skb) { stats->rx_dropped++; @@ -740,14 +1091,14 @@ } if (priv->can.restart_ms && - old_state >= CAN_STATE_BUS_OFF && + old_state == CAN_STATE_BUS_OFF && new_state < CAN_STATE_BUS_OFF) { cf->can_id |= CAN_ERR_RESTARTED; netif_carrier_on(priv->netdev); } } - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: if (es->leaf.error_factor) { cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; @@ -774,8 +1125,10 @@ break; } - cf->data[6] = es->txerr; - cf->data[7] = es->rxerr; + if (new_state != CAN_STATE_BUS_OFF) { + cf->data[6] = es->txerr; + cf->data[7] = es->rxerr; + } stats->rx_packets++; stats->rx_bytes += cf->can_dlc; @@ -838,11 +1191,11 @@ case CMD_CAN_ERROR_EVENT: es.channel = 0; - es.status = cmd->u.usbcan.error_event.status_ch0; - es.txerr = cmd->u.usbcan.error_event.tx_errors_count_ch0; - es.rxerr = cmd->u.usbcan.error_event.rx_errors_count_ch0; + es.status = cmd->u.usbcan.can_error_event.status_ch0; + es.txerr = cmd->u.usbcan.can_error_event.tx_errors_count_ch0; + es.rxerr = cmd->u.usbcan.can_error_event.rx_errors_count_ch0; es.usbcan.other_ch_status = - cmd->u.usbcan.error_event.status_ch1; + cmd->u.usbcan.can_error_event.status_ch1; kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); /* The USBCAN firmware supports up to 2 channels. @@ -850,13 +1203,13 @@ */ if (dev->nchannels == MAX_USBCAN_NET_DEVICES) { es.channel = 1; - es.status = cmd->u.usbcan.error_event.status_ch1; + es.status = cmd->u.usbcan.can_error_event.status_ch1; es.txerr = - cmd->u.usbcan.error_event.tx_errors_count_ch1; + cmd->u.usbcan.can_error_event.tx_errors_count_ch1; es.rxerr = - cmd->u.usbcan.error_event.rx_errors_count_ch1; + cmd->u.usbcan.can_error_event.rx_errors_count_ch1; es.usbcan.other_ch_status = - cmd->u.usbcan.error_event.status_ch0; + cmd->u.usbcan.can_error_event.status_ch0; kvaser_usb_leaf_usbcan_conditionally_rx_error(dev, &es); } break; @@ -873,11 +1226,11 @@ switch (cmd->id) { case CMD_CAN_ERROR_EVENT: - es.channel = cmd->u.leaf.error_event.channel; - es.status = cmd->u.leaf.error_event.status; - es.txerr = cmd->u.leaf.error_event.tx_errors_count; - es.rxerr = cmd->u.leaf.error_event.rx_errors_count; - es.leaf.error_factor = cmd->u.leaf.error_event.error_factor; + es.channel = cmd->u.leaf.can_error_event.channel; + es.status = cmd->u.leaf.can_error_event.status; + es.txerr = cmd->u.leaf.can_error_event.tx_errors_count; + es.rxerr = cmd->u.leaf.can_error_event.rx_errors_count; + es.leaf.error_factor = cmd->u.leaf.can_error_event.error_factor; break; case CMD_LEAF_LOG_MESSAGE: es.channel = cmd->u.leaf.log_message.channel; @@ -939,7 +1292,7 @@ stats = &priv->netdev->stats; if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) && - (dev->card_data.leaf.family == KVASER_LEAF && + (dev->driver_info->family == KVASER_LEAF && cmd->id == CMD_LEAF_LOG_MESSAGE)) { kvaser_usb_leaf_leaf_rx_error(dev, cmd); return; @@ -955,7 +1308,7 @@ return; } - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: rx_data = cmd->u.leaf.rx_can.data; break; @@ -970,7 +1323,7 @@ return; } - if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id == + if (dev->driver_info->family == KVASER_LEAF && cmd->id == CMD_LEAF_LOG_MESSAGE) { cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id); if (cf->can_id & KVASER_EXTENDED_FRAME) @@ -1009,6 +1362,74 @@ netif_rx(skb); } +static void kvaser_usb_leaf_error_event_parameter(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + u16 info1 = 0; + + switch (dev->driver_info->family) { + case KVASER_LEAF: + info1 = le16_to_cpu(cmd->u.leaf.error_event.info1); + break; + case KVASER_USBCAN: + info1 = le16_to_cpu(cmd->u.usbcan.error_event.info1); + break; + } + + /* info1 will contain the offending cmd_no */ + switch (info1) { + case CMD_SET_CTRL_MODE: + dev_warn(&dev->intf->dev, + "CMD_SET_CTRL_MODE error in parameter\n"); + break; + + case CMD_SET_BUS_PARAMS: + dev_warn(&dev->intf->dev, + "CMD_SET_BUS_PARAMS error in parameter\n"); + break; + + default: + dev_warn(&dev->intf->dev, + "Unhandled parameter error event cmd_no (%u)\n", + info1); + break; + } +} + +static void kvaser_usb_leaf_error_event(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + u8 error_code = 0; + + switch (dev->driver_info->family) { + case KVASER_LEAF: + error_code = cmd->u.leaf.error_event.error_code; + break; + case KVASER_USBCAN: + error_code = cmd->u.usbcan.error_event.error_code; + break; + } + + switch (error_code) { + case KVASER_USB_LEAF_ERROR_EVENT_TX_QUEUE_FULL: + /* Received additional CAN message, when firmware TX queue is + * already full. Something is wrong with the driver. + * This should never happen! + */ + dev_err(&dev->intf->dev, + "Received error event TX_QUEUE_FULL\n"); + break; + case KVASER_USB_LEAF_ERROR_EVENT_PARAM: + kvaser_usb_leaf_error_event_parameter(dev, cmd); + break; + + default: + dev_warn(&dev->intf->dev, + "Unhandled error event (%d)\n", error_code); + break; + } +} + static void kvaser_usb_leaf_start_chip_reply(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { @@ -1049,9 +1470,31 @@ complete(&priv->stop_comp); } +static void kvaser_usb_leaf_get_busparams_reply(const struct kvaser_usb *dev, + const struct kvaser_cmd *cmd) +{ + struct kvaser_usb_net_priv *priv; + u8 channel = cmd->u.busparams.channel; + + if (channel >= dev->nchannels) { + dev_err(&dev->intf->dev, + "Invalid channel number (%d)\n", channel); + return; + } + + priv = dev->nets[channel]; + memcpy(&priv->busparams_nominal, &cmd->u.busparams.busparams, + sizeof(priv->busparams_nominal)); + + complete(&priv->get_busparams_comp); +} + static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, const struct kvaser_cmd *cmd) { + if (kvaser_usb_leaf_verify_size(dev, cmd) < 0) + return; + switch (cmd->id) { case CMD_START_CHIP_REPLY: kvaser_usb_leaf_start_chip_reply(dev, cmd); @@ -1067,14 +1510,14 @@ break; case CMD_LEAF_LOG_MESSAGE: - if (dev->card_data.leaf.family != KVASER_LEAF) + if (dev->driver_info->family != KVASER_LEAF) goto warn; kvaser_usb_leaf_rx_can_msg(dev, cmd); break; case CMD_CHIP_STATE_EVENT: case CMD_CAN_ERROR_EVENT: - if (dev->card_data.leaf.family == KVASER_LEAF) + if (dev->driver_info->family == KVASER_LEAF) kvaser_usb_leaf_leaf_rx_error(dev, cmd); else kvaser_usb_leaf_usbcan_rx_error(dev, cmd); @@ -1084,14 +1527,22 @@ kvaser_usb_leaf_tx_acknowledge(dev, cmd); break; + case CMD_ERROR_EVENT: + kvaser_usb_leaf_error_event(dev, cmd); + break; + + case CMD_GET_BUS_PARAMS_REPLY: + kvaser_usb_leaf_get_busparams_reply(dev, cmd); + break; + /* Ignored commands */ case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: - if (dev->card_data.leaf.family != KVASER_USBCAN) + if (dev->driver_info->family != KVASER_USBCAN) goto warn; break; case CMD_FLUSH_QUEUE_REPLY: - if (dev->card_data.leaf.family != KVASER_LEAF) + if (dev->driver_info->family != KVASER_LEAF) goto warn; break; @@ -1140,7 +1591,7 @@ struct kvaser_cmd *cmd; int rc; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; @@ -1164,7 +1615,7 @@ { int err; - init_completion(&priv->start_comp); + reinit_completion(&priv->start_comp); err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP, priv->channel); @@ -1180,9 +1631,12 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv) { + struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv; int err; - init_completion(&priv->stop_comp); + reinit_completion(&priv->stop_comp); + + cancel_delayed_work(&leaf->chip_state_req_work); err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP, priv->channel); @@ -1206,7 +1660,7 @@ struct kvaser_cmd *cmd; int rc; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; @@ -1225,28 +1679,40 @@ { struct kvaser_usb_dev_card_data *card_data = &dev->card_data; - dev->cfg = &kvaser_usb_leaf_dev_cfg; card_data->ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES; return 0; } -static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { - .name = "kvaser_usb", - .tseg1_min = KVASER_USB_TSEG1_MIN, - .tseg1_max = KVASER_USB_TSEG1_MAX, - .tseg2_min = KVASER_USB_TSEG2_MIN, - .tseg2_max = KVASER_USB_TSEG2_MAX, - .sjw_max = KVASER_USB_SJW_MAX, - .brp_min = KVASER_USB_BRP_MIN, - .brp_max = KVASER_USB_BRP_MAX, - .brp_inc = KVASER_USB_BRP_INC, -}; +static int kvaser_usb_leaf_init_channel(struct kvaser_usb_net_priv *priv) +{ + struct kvaser_usb_net_leaf_priv *leaf; + + leaf = devm_kzalloc(&priv->dev->intf->dev, sizeof(*leaf), GFP_KERNEL); + if (!leaf) + return -ENOMEM; -static int kvaser_usb_leaf_set_bittiming(struct net_device *netdev) + leaf->net = priv; + INIT_DELAYED_WORK(&leaf->chip_state_req_work, + kvaser_usb_leaf_chip_state_req_work); + + priv->sub_priv = leaf; + + return 0; +} + +static void kvaser_usb_leaf_remove_channel(struct kvaser_usb_net_priv *priv) +{ + struct kvaser_usb_net_leaf_priv *leaf = priv->sub_priv; + + if (leaf) + cancel_delayed_work_sync(&leaf->chip_state_req_work); +} + +static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev, + const struct kvaser_usb_busparams *busparams) { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); - struct can_bittiming *bt = &priv->can.bittiming; struct kvaser_usb *dev = priv->dev; struct kvaser_cmd *cmd; int rc; @@ -1259,15 +1725,8 @@ cmd->len = CMD_HEADER_LEN + sizeof(struct kvaser_cmd_busparams); cmd->u.busparams.channel = priv->channel; cmd->u.busparams.tid = 0xff; - cmd->u.busparams.bitrate = cpu_to_le32(bt->bitrate); - cmd->u.busparams.sjw = bt->sjw; - cmd->u.busparams.tseg1 = bt->prop_seg + bt->phase_seg1; - cmd->u.busparams.tseg2 = bt->phase_seg2; - - if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) - cmd->u.busparams.no_samp = 3; - else - cmd->u.busparams.no_samp = 1; + memcpy(&cmd->u.busparams.busparams, busparams, + sizeof(cmd->u.busparams.busparams)); rc = kvaser_usb_send_cmd(dev, cmd, cmd->len); @@ -1275,6 +1734,27 @@ return rc; } +static int kvaser_usb_leaf_get_busparams(struct kvaser_usb_net_priv *priv) +{ + int err; + + if (priv->dev->driver_info->family == KVASER_USBCAN) + return -EOPNOTSUPP; + + reinit_completion(&priv->get_busparams_comp); + + err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_GET_BUS_PARAMS, + priv->channel); + if (err) + return err; + + if (!wait_for_completion_timeout(&priv->get_busparams_comp, + msecs_to_jiffies(KVASER_USB_TIMEOUT))) + return -ETIMEDOUT; + + return 0; +} + static int kvaser_usb_leaf_set_mode(struct net_device *netdev, enum can_mode mode) { @@ -1283,9 +1763,13 @@ switch (mode) { case CAN_MODE_START: + kvaser_usb_unlink_tx_urbs(priv); + err = kvaser_usb_leaf_simple_cmd_async(priv, CMD_START_CHIP); if (err) return err; + + priv->can.state = CAN_STATE_ERROR_ACTIVE; break; default: return -EOPNOTSUPP; @@ -1310,7 +1794,7 @@ struct usb_endpoint_descriptor *endpoint; int i; - iface_desc = &dev->intf->altsetting[0]; + iface_desc = dev->intf->cur_altsetting; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; @@ -1332,14 +1816,18 @@ const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops = { .dev_set_mode = kvaser_usb_leaf_set_mode, .dev_set_bittiming = kvaser_usb_leaf_set_bittiming, + .dev_get_busparams = kvaser_usb_leaf_get_busparams, .dev_set_data_bittiming = NULL, + .dev_get_data_busparams = NULL, .dev_get_berr_counter = kvaser_usb_leaf_get_berr_counter, .dev_setup_endpoints = kvaser_usb_leaf_setup_endpoints, .dev_init_card = kvaser_usb_leaf_init_card, + .dev_init_channel = kvaser_usb_leaf_init_channel, + .dev_remove_channel = kvaser_usb_leaf_remove_channel, .dev_get_software_info = kvaser_usb_leaf_get_software_info, .dev_get_software_details = NULL, .dev_get_card_info = kvaser_usb_leaf_get_card_info, - .dev_get_capabilities = NULL, + .dev_get_capabilities = kvaser_usb_leaf_get_capabilities, .dev_set_opt_mode = kvaser_usb_leaf_set_opt_mode, .dev_start_chip = kvaser_usb_leaf_start_chip, .dev_stop_chip = kvaser_usb_leaf_stop_chip, @@ -1348,11 +1836,3 @@ .dev_read_bulk_callback = kvaser_usb_leaf_read_bulk_callback, .dev_frame_to_cmd = kvaser_usb_leaf_frame_to_cmd, }; - -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg = { - .clock = { - .freq = CAN_USB_CLOCK, - }, - .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_leaf_bittiming_const, -}; --- linux-oracle-5.4.0.orig/drivers/net/can/usb/mcba_usb.c +++ linux-oracle-5.4.0/drivers/net/can/usb/mcba_usb.c @@ -33,10 +33,6 @@ #define MCBA_USB_RX_BUFF_SIZE 64 #define MCBA_USB_TX_BUFF_SIZE (sizeof(struct mcba_usb_msg)) -/* MCBA endpoint numbers */ -#define MCBA_USB_EP_IN 1 -#define MCBA_USB_EP_OUT 1 - /* Microchip command id */ #define MBCA_CMD_RECEIVE_MESSAGE 0xE3 #define MBCA_CMD_I_AM_ALIVE_FROM_CAN 0xF5 @@ -51,6 +47,10 @@ #define MCBA_VER_REQ_USB 1 #define MCBA_VER_REQ_CAN 2 +/* Drive the CAN_RES signal LOW "0" to activate R24 and R25 */ +#define MCBA_VER_TERMINATION_ON 0 +#define MCBA_VER_TERMINATION_OFF 1 + #define MCBA_SIDL_EXID_MASK 0x8 #define MCBA_DLC_MASK 0xf #define MCBA_DLC_RTR_MASK 0x40 @@ -82,6 +82,10 @@ bool can_ka_first_pass; bool can_speed_check; atomic_t free_ctx_cnt; + void *rxbuf[MCBA_MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS]; + int rx_pipe; + int tx_pipe; }; /* CAN frame */ @@ -270,10 +274,8 @@ memcpy(buf, usb_msg, MCBA_USB_TX_BUFF_SIZE); - usb_fill_bulk_urb(urb, priv->udev, - usb_sndbulkpipe(priv->udev, MCBA_USB_EP_OUT), buf, - MCBA_USB_TX_BUFF_SIZE, mcba_usb_write_bulk_callback, - ctx); + usb_fill_bulk_urb(urb, priv->udev, priv->tx_pipe, buf, MCBA_USB_TX_BUFF_SIZE, + mcba_usb_write_bulk_callback, ctx); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_anchor_urb(urb, &priv->tx_submitted); @@ -326,8 +328,6 @@ if (!ctx) return NETDEV_TX_BUSY; - can_put_echo_skb(skb, priv->netdev, ctx->ndx); - if (cf->can_id & CAN_EFF_FLAG) { /* SIDH | SIDL | EIDH | EIDL * 28 - 21 | 20 19 18 x x x 17 16 | 15 - 8 | 7 - 0 @@ -357,6 +357,8 @@ if (cf->can_id & CAN_RTR_FLAG) usb_msg.dlc |= MCBA_DLC_RTR_MASK; + can_put_echo_skb(skb, priv->netdev, ctx->ndx); + err = mcba_usb_xmit(priv, (struct mcba_usb_msg *)&usb_msg, ctx); if (err) goto xmit_failed; @@ -366,7 +368,6 @@ xmit_failed: can_free_echo_skb(priv->netdev, ctx->ndx); mcba_usb_free_ctx(ctx); - dev_kfree_skb(skb); stats->tx_dropped++; return NETDEV_TX_OK; @@ -472,7 +473,7 @@ priv->usb_ka_first_pass = false; } - if (msg->termination_state) + if (msg->termination_state == MCBA_VER_TERMINATION_ON) priv->can.termination = MCBA_TERMINATION_ENABLED; else priv->can.termination = MCBA_TERMINATION_DISABLED; @@ -609,7 +610,7 @@ resubmit_urb: usb_fill_bulk_urb(urb, priv->udev, - usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_OUT), + priv->rx_pipe, urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE, mcba_usb_read_bulk_callback, priv); @@ -633,6 +634,7 @@ for (i = 0; i < MCBA_MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -642,7 +644,7 @@ } buf = usb_alloc_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, - GFP_KERNEL, &urb->transfer_dma); + GFP_KERNEL, &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -650,8 +652,10 @@ break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, priv->udev, - usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), + priv->rx_pipe, buf, MCBA_USB_RX_BUFF_SIZE, mcba_usb_read_bulk_callback, priv); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -661,11 +665,14 @@ if (err) { usb_unanchor_urb(urb); usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, - buf, urb->transfer_dma); + buf, buf_dma); usb_free_urb(urb); break; } + priv->rxbuf[i] = buf; + priv->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -708,7 +715,14 @@ static void mcba_urb_unlink(struct mcba_priv *priv) { + int i; + usb_kill_anchored_urbs(&priv->rx_submitted); + + for (i = 0; i < MCBA_MAX_RX_URBS; ++i) + usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, + priv->rxbuf[i], priv->rxbuf_dma[i]); + usb_kill_anchored_urbs(&priv->tx_submitted); } @@ -779,9 +793,9 @@ }; if (term == MCBA_TERMINATION_ENABLED) - usb_msg.termination = 1; + usb_msg.termination = MCBA_VER_TERMINATION_ON; else - usb_msg.termination = 0; + usb_msg.termination = MCBA_VER_TERMINATION_OFF; mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); @@ -795,6 +809,13 @@ struct mcba_priv *priv; int err = -ENOMEM; struct usb_device *usbdev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *in, *out; + + err = usb_find_common_endpoints(intf->cur_altsetting, &in, &out, NULL, NULL); + if (err) { + dev_err(&intf->dev, "Can't find endpoints\n"); + return err; + } netdev = alloc_candev(sizeof(struct mcba_priv), MCBA_MAX_TX_URBS); if (!netdev) { @@ -840,6 +861,9 @@ goto cleanup_free_candev; } + priv->rx_pipe = usb_rcvbulkpipe(priv->udev, in->bEndpointAddress); + priv->tx_pipe = usb_sndbulkpipe(priv->udev, out->bEndpointAddress); + devm_can_led_init(netdev); /* Start USB dev only if we have successfully registered CAN device */ --- linux-oracle-5.4.0.orig/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ linux-oracle-5.4.0/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -130,14 +130,55 @@ /* protect from getting time before setting now */ if (ktime_to_ns(time_ref->tv_host)) { u64 delta_us; + s64 delta_ts = 0; - delta_us = ts - time_ref->ts_dev_2; - if (ts < time_ref->ts_dev_2) - delta_us &= (1 << time_ref->adapter->ts_used_bits) - 1; + /* General case: dev_ts_1 < dev_ts_2 < ts, with: + * + * - dev_ts_1 = previous sync timestamp + * - dev_ts_2 = last sync timestamp + * - ts = event timestamp + * - ts_period = known sync period (theoretical) + * ~ dev_ts2 - dev_ts1 + * *but*: + * + * - time counters wrap (see adapter->ts_used_bits) + * - sometimes, dev_ts_1 < ts < dev_ts2 + * + * "normal" case (sync time counters increase): + * must take into account case when ts wraps (tsw) + * + * < ts_period > < > + * | | | + * ---+--------+----+-------0-+--+--> + * ts_dev_1 | ts_dev_2 | + * ts tsw + */ + if (time_ref->ts_dev_1 < time_ref->ts_dev_2) { + /* case when event time (tsw) wraps */ + if (ts < time_ref->ts_dev_1) + delta_ts = BIT_ULL(time_ref->adapter->ts_used_bits); + + /* Otherwise, sync time counter (ts_dev_2) has wrapped: + * handle case when event time (tsn) hasn't. + * + * < ts_period > < > + * | | | + * ---+--------+--0-+---------+--+--> + * ts_dev_1 | ts_dev_2 | + * tsn ts + */ + } else if (time_ref->ts_dev_1 < ts) { + delta_ts = -BIT_ULL(time_ref->adapter->ts_used_bits); + } + + /* add delay between last sync and event timestamps */ + delta_ts += (signed int)(ts - time_ref->ts_dev_2); - delta_us += time_ref->ts_total; + /* add time from beginning to last sync */ + delta_ts += time_ref->ts_total; - delta_us *= time_ref->adapter->us_per_ts_scale; + /* convert ticks number into microseconds */ + delta_us = delta_ts * time_ref->adapter->us_per_ts_scale; delta_us >>= time_ref->adapter->us_per_ts_shift; *time = ktime_add_us(time_ref->tv_host_0, delta_us); @@ -815,7 +856,7 @@ if (dev->adapter->dev_set_bus) { err = dev->adapter->dev_set_bus(dev, 0); if (err) - goto lbl_unregister_candev; + goto adap_dev_free; } /* get device number early */ @@ -827,6 +868,10 @@ return 0; +adap_dev_free: + if (dev->adapter->dev_free) + dev->adapter->dev_free(dev); + lbl_unregister_candev: unregister_candev(netdev); --- linux-oracle-5.4.0.orig/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ linux-oracle-5.4.0/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -468,12 +468,18 @@ struct pucan_msg *rx_msg) { struct pucan_rx_msg *rm = (struct pucan_rx_msg *)rx_msg; - struct peak_usb_device *dev = usb_if->dev[pucan_msg_get_channel(rm)]; - struct net_device *netdev = dev->netdev; + struct peak_usb_device *dev; + struct net_device *netdev; struct canfd_frame *cfd; struct sk_buff *skb; const u16 rx_msg_flags = le16_to_cpu(rm->flags); + if (pucan_msg_get_channel(rm) >= ARRAY_SIZE(usb_if->dev)) + return -ENOMEM; + + dev = usb_if->dev[pucan_msg_get_channel(rm)]; + netdev = dev->netdev; + if (rx_msg_flags & PUCAN_MSG_EXT_DATA_LEN) { /* CANFD frame case */ skb = alloc_canfd_skb(netdev, &cfd); @@ -506,11 +512,11 @@ else memcpy(cfd->data, rm->d, cfd->len); - peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low)); - netdev->stats.rx_packets++; netdev->stats.rx_bytes += cfd->len; + peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(rm->ts_low)); + return 0; } @@ -519,15 +525,21 @@ struct pucan_msg *rx_msg) { struct pucan_status_msg *sm = (struct pucan_status_msg *)rx_msg; - struct peak_usb_device *dev = usb_if->dev[pucan_stmsg_get_channel(sm)]; - struct pcan_usb_fd_device *pdev = - container_of(dev, struct pcan_usb_fd_device, dev); + struct pcan_usb_fd_device *pdev; enum can_state new_state = CAN_STATE_ERROR_ACTIVE; enum can_state rx_state, tx_state; - struct net_device *netdev = dev->netdev; + struct peak_usb_device *dev; + struct net_device *netdev; struct can_frame *cf; struct sk_buff *skb; + if (pucan_stmsg_get_channel(sm) >= ARRAY_SIZE(usb_if->dev)) + return -ENOMEM; + + dev = usb_if->dev[pucan_stmsg_get_channel(sm)]; + pdev = container_of(dev, struct pcan_usb_fd_device, dev); + netdev = dev->netdev; + /* nothing should be sent while in BUS_OFF state */ if (dev->can.state == CAN_STATE_BUS_OFF) return 0; @@ -539,11 +551,10 @@ } else if (sm->channel_p_w_b & PUCAN_BUS_WARNING) { new_state = CAN_STATE_ERROR_WARNING; } else { - /* no error bit (so, no error skb, back to active state) */ - dev->can.state = CAN_STATE_ERROR_ACTIVE; + /* back to (or still in) ERROR_ACTIVE state */ + new_state = CAN_STATE_ERROR_ACTIVE; pdev->bec.txerr = 0; pdev->bec.rxerr = 0; - return 0; } /* state hasn't changed */ @@ -566,11 +577,11 @@ if (!skb) return -ENOMEM; - peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low)); - netdev->stats.rx_packets++; netdev->stats.rx_bytes += cf->can_dlc; + peak_usb_netif_rx(skb, &usb_if->time_ref, le32_to_cpu(sm->ts_low)); + return 0; } @@ -579,9 +590,14 @@ struct pucan_msg *rx_msg) { struct pucan_error_msg *er = (struct pucan_error_msg *)rx_msg; - struct peak_usb_device *dev = usb_if->dev[pucan_ermsg_get_channel(er)]; - struct pcan_usb_fd_device *pdev = - container_of(dev, struct pcan_usb_fd_device, dev); + struct pcan_usb_fd_device *pdev; + struct peak_usb_device *dev; + + if (pucan_ermsg_get_channel(er) >= ARRAY_SIZE(usb_if->dev)) + return -EINVAL; + + dev = usb_if->dev[pucan_ermsg_get_channel(er)]; + pdev = container_of(dev, struct pcan_usb_fd_device, dev); /* keep a trace of tx and rx error counters for later use */ pdev->bec.txerr = er->tx_err_cnt; @@ -595,11 +611,17 @@ struct pucan_msg *rx_msg) { struct pcan_ufd_ovr_msg *ov = (struct pcan_ufd_ovr_msg *)rx_msg; - struct peak_usb_device *dev = usb_if->dev[pufd_omsg_get_channel(ov)]; - struct net_device *netdev = dev->netdev; + struct peak_usb_device *dev; + struct net_device *netdev; struct can_frame *cf; struct sk_buff *skb; + if (pufd_omsg_get_channel(ov) >= ARRAY_SIZE(usb_if->dev)) + return -EINVAL; + + dev = usb_if->dev[pufd_omsg_get_channel(ov)]; + netdev = dev->netdev; + /* allocate an skb to store the error frame */ skb = alloc_can_err_skb(netdev, &cf); if (!skb) @@ -716,6 +738,9 @@ u16 tx_msg_size, tx_msg_flags; u8 can_dlc; + if (cfd->len > CANFD_MAX_DLEN) + return -EINVAL; + tx_msg_size = ALIGN(sizeof(struct pucan_tx_msg) + cfd->len, 4); tx_msg->size = cpu_to_le16(tx_msg_size); tx_msg->type = cpu_to_le16(PUCAN_MSG_CAN_TX); --- linux-oracle-5.4.0.orig/drivers/net/can/usb/ucan.c +++ linux-oracle-5.4.0/drivers/net/can/usb/ucan.c @@ -792,7 +792,7 @@ up); usb_anchor_urb(urb, &up->rx_urbs); - ret = usb_submit_urb(urb, GFP_KERNEL); + ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { netdev_err(up->netdev, --- linux-oracle-5.4.0.orig/drivers/net/can/usb/usb_8dev.c +++ linux-oracle-5.4.0/drivers/net/can/usb/usb_8dev.c @@ -137,7 +137,8 @@ u8 *cmd_msg_buffer; struct mutex usb_8dev_cmd_lock; - + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; /* tx frame */ @@ -441,9 +442,10 @@ if (rx_errors) stats->rx_errors++; - - cf->data[6] = txerr; - cf->data[7] = rxerr; + if (priv->can.state != CAN_STATE_BUS_OFF) { + cf->data[6] = txerr; + cf->data[7] = rxerr; + } priv->bec.txerr = txerr; priv->bec.rxerr = rxerr; @@ -669,9 +671,20 @@ atomic_inc(&priv->active_tx_urbs); err = usb_submit_urb(urb, GFP_ATOMIC); - if (unlikely(err)) - goto failed; - else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) + if (unlikely(err)) { + can_free_echo_skb(netdev, context->echo_index); + + usb_unanchor_urb(urb); + usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); + + atomic_dec(&priv->active_tx_urbs); + + if (err == -ENODEV) + netif_device_detach(netdev); + else + netdev_warn(netdev, "failed tx_urb %d\n", err); + stats->tx_dropped++; + } else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) /* Slow down tx path */ netif_stop_queue(netdev); @@ -690,19 +703,6 @@ return NETDEV_TX_BUSY; -failed: - can_free_echo_skb(netdev, context->echo_index); - - usb_unanchor_urb(urb); - usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); - - atomic_dec(&priv->active_tx_urbs); - - if (err == -ENODEV) - netif_device_detach(netdev); - else - netdev_warn(netdev, "failed tx_urb %d\n", err); - nomembuf: usb_free_urb(urb); @@ -733,6 +733,7 @@ for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -742,7 +743,7 @@ } buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -750,6 +751,8 @@ break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, priv->udev, usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX), @@ -767,6 +770,9 @@ break; } + priv->rxbuf[i] = buf; + priv->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -836,6 +842,10 @@ usb_kill_anchored_urbs(&priv->rx_submitted); + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(priv->udev, RX_BUFFER_SIZE, + priv->rxbuf[i], priv->rxbuf_dma[i]); + usb_kill_anchored_urbs(&priv->tx_submitted); atomic_set(&priv->active_tx_urbs, 0); --- linux-oracle-5.4.0.orig/drivers/net/can/vcan.c +++ linux-oracle-5.4.0/drivers/net/can/vcan.c @@ -153,7 +153,7 @@ dev->addr_len = 0; dev->tx_queue_len = 0; dev->flags = IFF_NOARP; - dev->ml_priv = netdev_priv(dev); + can_set_ml_priv(dev, netdev_priv(dev)); /* set flags according to driver capabilities */ if (echo) --- linux-oracle-5.4.0.orig/drivers/net/can/vxcan.c +++ linux-oracle-5.4.0/drivers/net/can/vxcan.c @@ -39,6 +39,7 @@ struct net_device *peer; struct canfd_frame *cfd = (struct canfd_frame *)skb->data; struct net_device_stats *peerstats, *srcstats = &dev->stats; + u8 len; if (can_dropped_invalid_skb(dev, skb)) return NETDEV_TX_OK; @@ -61,12 +62,13 @@ skb->dev = peer; skb->ip_summed = CHECKSUM_UNNECESSARY; + len = cfd->len; if (netif_rx_ni(skb) == NET_RX_SUCCESS) { srcstats->tx_packets++; - srcstats->tx_bytes += cfd->len; + srcstats->tx_bytes += len; peerstats = &peer->stats; peerstats->rx_packets++; - peerstats->rx_bytes += cfd->len; + peerstats->rx_bytes += len; } out_unlock: @@ -139,15 +141,19 @@ static void vxcan_setup(struct net_device *dev) { + struct can_ml_priv *can_ml; + dev->type = ARPHRD_CAN; dev->mtu = CANFD_MTU; dev->hard_header_len = 0; dev->addr_len = 0; dev->tx_queue_len = 0; - dev->flags = (IFF_NOARP|IFF_ECHO); + dev->flags = IFF_NOARP; dev->netdev_ops = &vxcan_netdev_ops; dev->needs_free_netdev = true; - dev->ml_priv = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); + + can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN); + can_set_ml_priv(dev, can_ml); } /* forward declaration for rtnl_create_link() */ @@ -173,12 +179,7 @@ nla_peer = data[VXCAN_INFO_PEER]; ifmp = nla_data(nla_peer); - err = rtnl_nla_parse_ifla(peer_tb, - nla_data(nla_peer) + - sizeof(struct ifinfomsg), - nla_len(nla_peer) - - sizeof(struct ifinfomsg), - NULL); + err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack); if (err < 0) return err; --- linux-oracle-5.4.0.orig/drivers/net/can/xilinx_can.c +++ linux-oracle-5.4.0/drivers/net/can/xilinx_can.c @@ -60,6 +60,8 @@ XCAN_TXMSG_BASE_OFFSET = 0x0100, /* TX Message Space */ XCAN_RXMSG_BASE_OFFSET = 0x1100, /* RX Message Space */ XCAN_RXMSG_2_BASE_OFFSET = 0x2100, /* RX Message Space */ + XCAN_AFR_2_MASK_OFFSET = 0x0A00, /* Acceptance Filter MASK */ + XCAN_AFR_2_ID_OFFSET = 0x0A04, /* Acceptance Filter ID */ }; #define XCAN_FRAME_ID_OFFSET(frame_base) ((frame_base) + 0x00) @@ -237,7 +239,7 @@ }; /* AXI CANFD Data Bittiming constants as per AXI CANFD 1.0 specs */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd = { .name = DRIVER_NAME, .tseg1_min = 1, .tseg1_max = 16, @@ -263,7 +265,7 @@ }; /* AXI CANFD 2.0 Data Bittiming constants as per AXI CANFD 2.0 spec */ -static struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { +static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { .name = DRIVER_NAME, .tseg1_min = 1, .tseg1_max = 32, @@ -1382,7 +1384,7 @@ if (ret < 0) { netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", __func__, ret); - return ret; + goto err; } ret = request_irq(ndev->irq, xcan_interrupt, priv->irq_flags, @@ -1466,6 +1468,7 @@ if (ret < 0) { netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", __func__, ret); + pm_runtime_put(priv->dev); return ret; } @@ -1750,7 +1753,12 @@ spin_lock_init(&priv->tx_lock); /* Get IRQ for the device */ - ndev->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto err_free; + + ndev->irq = ret; + ndev->flags |= IFF_ECHO; /* We support local echo */ platform_set_drvdata(pdev, ndev); @@ -1781,7 +1789,7 @@ if (ret < 0) { netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n", __func__, ret); - goto err_pmdisable; + goto err_disableclks; } if (priv->read_reg(priv, XCAN_SR_OFFSET) != XCAN_SR_CONFIG_MASK) { @@ -1803,6 +1811,11 @@ pm_runtime_put(&pdev->dev); + if (priv->devtype.flags & XCAN_FLAG_CANFD_2) { + priv->write_reg(priv, XCAN_AFR_2_ID_OFFSET, 0x00000000); + priv->write_reg(priv, XCAN_AFR_2_MASK_OFFSET, 0x00000000); + } + netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx buffers: actual %d, using %d\n", priv->reg_base, ndev->irq, priv->can.clock.freq, hw_tx_max, priv->tx_max); @@ -1811,7 +1824,6 @@ err_disableclks: pm_runtime_put(priv->dev); -err_pmdisable: pm_runtime_disable(&pdev->dev); err_free: free_candev(ndev); --- linux-oracle-5.4.0.orig/drivers/net/dsa/Kconfig +++ linux-oracle-5.4.0/drivers/net/dsa/Kconfig @@ -77,6 +77,7 @@ config NET_DSA_SMSC_LAN9303 tristate select NET_DSA_TAG_LAN9303 + select REGMAP ---help--- This enables support for the SMSC/Microchip LAN9303 3 port ethernet switch chips. --- linux-oracle-5.4.0.orig/drivers/net/dsa/b53/b53_common.c +++ linux-oracle-5.4.0/drivers/net/dsa/b53/b53_common.c @@ -347,7 +347,7 @@ * frames should be flooded or not. */ b53_read8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, &mgmt); - mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN; + mgmt |= B53_UC_FWD_EN | B53_MC_FWD_EN | B53_IPMC_FWD_EN; b53_write8(dev, B53_CTRL_PAGE, B53_IP_MULTICAST_CTRL, mgmt); } @@ -514,6 +514,19 @@ } EXPORT_SYMBOL(b53_imp_vlan_setup); +static void b53_port_set_learning(struct b53_device *dev, int port, + bool learning) +{ + u16 reg; + + b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, ®); + if (learning) + reg &= ~BIT(port); + else + reg |= BIT(port); + b53_write16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, reg); +} + int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy) { struct b53_device *dev = ds->priv; @@ -526,6 +539,9 @@ cpu_port = ds->ports[port].cpu_dp->index; + b53_br_egress_floods(ds, port, true, true); + b53_port_set_learning(dev, port, false); + if (dev->ops->irq_enable) ret = dev->ops->irq_enable(dev, port); if (ret) @@ -641,6 +657,9 @@ b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), port_ctrl); b53_brcm_hdr_setup(dev->ds, port); + + b53_br_egress_floods(dev->ds, port, true, true); + b53_port_set_learning(dev, port, false); } static void b53_enable_mib(struct b53_device *dev) @@ -676,7 +695,7 @@ b53_do_vlan_op(dev, VTA_CMD_CLEAR); } - b53_enable_vlan(dev, false, ds->vlan_filtering); + b53_enable_vlan(dev, dev->vlan_enabled, ds->vlan_filtering); b53_for_each_port(dev, i) b53_write16(dev, B53_VLAN_PAGE, @@ -977,13 +996,6 @@ b53_disable_port(ds, port); } - /* Let DSA handle the case were multiple bridges span the same switch - * device and different VLAN awareness settings are requested, which - * would be breaking filtering semantics for any of the other bridge - * devices. (not hardware supported) - */ - ds->vlan_filtering_is_global = true; - return ret; } @@ -1326,7 +1338,7 @@ if ((is5325(dev) || is5365(dev)) && vlan->vid_begin == 0) return -EOPNOTSUPP; - if (vlan->vid_end > dev->num_vlans) + if (vlan->vid_end >= dev->num_vlans) return -ERANGE; b53_enable_vlan(dev, true, ds->vlan_filtering); @@ -1349,6 +1361,9 @@ b53_get_vlan_entry(dev, vid, vl); + if (vid == 0 && vid == b53_default_pvid(dev)) + untagged = true; + vl->members |= BIT(port); if (untagged && !dsa_is_cpu_port(ds, port)) vl->untag |= BIT(port); @@ -1434,6 +1449,10 @@ reg |= ARLTBL_RW; else reg &= ~ARLTBL_RW; + if (dev->vlan_enabled) + reg &= ~ARLTBL_IVL_SVL_SELECT; + else + reg |= ARLTBL_IVL_SVL_SELECT; b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_RW_CTRL, reg); return b53_arl_op_wait(dev); @@ -1443,6 +1462,7 @@ u16 vid, struct b53_arl_entry *ent, u8 *idx, bool is_valid) { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); unsigned int i; int ret; @@ -1450,6 +1470,8 @@ if (ret) return ret; + bitmap_zero(free_bins, dev->num_arl_entries); + /* Read the bins */ for (i = 0; i < dev->num_arl_entries; i++) { u64 mac_vid; @@ -1461,13 +1483,24 @@ B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); b53_arl_to_entry(ent, mac_vid, fwd_entry); - if (!(fwd_entry & ARLTBL_VALID)) + if (!(fwd_entry & ARLTBL_VALID)) { + set_bit(i, free_bins); continue; + } if ((mac_vid & ARLTBL_MAC_MASK) != mac) continue; + if (dev->vlan_enabled && + ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid) + continue; *idx = i; + return 0; } + if (bitmap_weight(free_bins, dev->num_arl_entries) == 0) + return -ENOSPC; + + *idx = find_first_bit(free_bins, dev->num_arl_entries); + return -ENOENT; } @@ -1497,10 +1530,23 @@ if (op) return ret; - /* We could not find a matching MAC, so reset to a new entry */ - if (ret) { + switch (ret) { + case -ETIMEDOUT: + return ret; + case -ENOSPC: + dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n", + addr, vid); + return is_valid ? ret : 0; + case -ENOENT: + /* We could not find a matching MAC, so reset to a new entry */ + dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n", + addr, vid, idx); fwd_entry = 0; - idx = 1; + break; + default: + dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n", + addr, vid, idx); + break; } memset(&ent, 0, sizeof(ent)); @@ -1667,6 +1713,8 @@ b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan); dev->ports[port].vlan_ctl_mask = pvlan; + b53_port_set_learning(dev, port, true); + return 0; } EXPORT_SYMBOL(b53_br_join); @@ -1714,6 +1762,7 @@ vl->untag |= BIT(port) | BIT(cpu_port); b53_set_vlan_entry(dev, pvid, vl); } + b53_port_set_learning(dev, port, false); } EXPORT_SYMBOL(b53_br_leave); @@ -1766,19 +1815,26 @@ struct b53_device *dev = ds->priv; u16 uc, mc; - b53_read16(dev, B53_CTRL_PAGE, B53_UC_FWD_EN, &uc); + b53_read16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, &uc); if (unicast) uc |= BIT(port); else uc &= ~BIT(port); - b53_write16(dev, B53_CTRL_PAGE, B53_UC_FWD_EN, uc); + b53_write16(dev, B53_CTRL_PAGE, B53_UC_FLOOD_MASK, uc); - b53_read16(dev, B53_CTRL_PAGE, B53_MC_FWD_EN, &mc); + b53_read16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, &mc); if (multicast) mc |= BIT(port); else mc &= ~BIT(port); - b53_write16(dev, B53_CTRL_PAGE, B53_MC_FWD_EN, mc); + b53_write16(dev, B53_CTRL_PAGE, B53_MC_FLOOD_MASK, mc); + + b53_read16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, &mc); + if (multicast) + mc |= BIT(port); + else + mc &= ~BIT(port); + b53_write16(dev, B53_CTRL_PAGE, B53_IPMC_FLOOD_MASK, mc); return 0; @@ -2298,9 +2354,8 @@ dev->cpu_port = 5; } - /* cpu port is always last */ - dev->num_ports = dev->cpu_port + 1; dev->enabled_ports |= BIT(dev->cpu_port); + dev->num_ports = fls(dev->enabled_ports); /* Include non standard CPU port built-in PHYs to be probed */ if (is539x(dev) || is531x5(dev)) { @@ -2356,6 +2411,13 @@ dev->priv = priv; dev->ops = ops; ds->ops = &b53_switch_ops; + /* Let DSA handle the case were multiple bridges span the same switch + * device and different VLAN awareness settings are requested, which + * would be breaking filtering semantics for any of the other bridge + * devices. (not hardware supported) + */ + ds->vlan_filtering_is_global = true; + mutex_init(&dev->reg_mutex); mutex_init(&dev->stats_mutex); --- linux-oracle-5.4.0.orig/drivers/net/dsa/b53/b53_mmap.c +++ linux-oracle-5.4.0/drivers/net/dsa/b53/b53_mmap.c @@ -215,6 +215,18 @@ return 0; } +static int b53_mmap_phy_read16(struct b53_device *dev, int addr, int reg, + u16 *value) +{ + return -EIO; +} + +static int b53_mmap_phy_write16(struct b53_device *dev, int addr, int reg, + u16 value) +{ + return -EIO; +} + static const struct b53_io_ops b53_mmap_ops = { .read8 = b53_mmap_read8, .read16 = b53_mmap_read16, @@ -226,6 +238,8 @@ .write32 = b53_mmap_write32, .write48 = b53_mmap_write48, .write64 = b53_mmap_write64, + .phy_read16 = b53_mmap_phy_read16, + .phy_write16 = b53_mmap_phy_write16, }; static int b53_mmap_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/net/dsa/b53/b53_regs.h +++ linux-oracle-5.4.0/drivers/net/dsa/b53/b53_regs.h @@ -115,6 +115,7 @@ #define B53_UC_FLOOD_MASK 0x32 #define B53_MC_FLOOD_MASK 0x34 #define B53_IPMC_FLOOD_MASK 0x36 +#define B53_DIS_LEARNING 0x3c /* * Override Ports 0-7 State on devices with xMII interfaces (8 bit) @@ -292,6 +293,7 @@ /* ARL Table Read/Write Register (8 bit) */ #define B53_ARLTBL_RW_CTRL 0x00 #define ARLTBL_RW BIT(0) +#define ARLTBL_IVL_SVL_SELECT BIT(6) #define ARLTBL_START_DONE BIT(7) /* MAC Address Index Register (48 bit) */ @@ -304,7 +306,7 @@ * * BCM5325 and BCM5365 share most definitions below */ -#define B53_ARLTBL_MAC_VID_ENTRY(n) (0x10 * (n)) +#define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10) #define ARLTBL_MAC_MASK 0xffffffffffffULL #define ARLTBL_VID_S 48 #define ARLTBL_VID_MASK_25 0xff @@ -316,13 +318,16 @@ #define ARLTBL_VALID_25 BIT(63) /* ARL Table Data Entry N Registers (32 bit) */ -#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x08) +#define B53_ARLTBL_DATA_ENTRY(n) ((0x10 * (n)) + 0x18) #define ARLTBL_DATA_PORT_ID_MASK 0x1ff #define ARLTBL_TC(tc) ((3 & tc) << 11) #define ARLTBL_AGE BIT(14) #define ARLTBL_STATIC BIT(15) #define ARLTBL_VALID BIT(16) +/* Maximum number of bin entries in the ARL for all switches */ +#define B53_ARLTBL_MAX_BIN_ENTRIES 4 + /* ARL Search Control Register (8 bit) */ #define B53_ARL_SRCH_CTL 0x50 #define B53_ARL_SRCH_CTL_25 0x20 --- linux-oracle-5.4.0.orig/drivers/net/dsa/bcm_sf2.c +++ linux-oracle-5.4.0/drivers/net/dsa/bcm_sf2.c @@ -69,6 +69,7 @@ /* Force link status for IMP port */ reg = core_readl(priv, offset); reg |= (MII_SW_OR | LINK_STS); + reg &= ~GMII_SPEED_UP_2G; core_writel(priv, reg, offset); /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ @@ -171,11 +172,6 @@ reg &= ~P_TXQ_PSM_VDD(port); core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL); - /* Enable learning */ - reg = core_readl(priv, CORE_DIS_LEARN); - reg &= ~BIT(port); - core_writel(priv, reg, CORE_DIS_LEARN); - /* Enable Broadcom tags for that port if requested */ if (priv->brcm_tag_mask & BIT(port)) b53_brcm_hdr_setup(ds, port); @@ -420,15 +416,19 @@ /* Find our integrated MDIO bus node */ dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); priv->master_mii_bus = of_mdio_find_bus(dn); - if (!priv->master_mii_bus) + if (!priv->master_mii_bus) { + of_node_put(dn); return -EPROBE_DEFER; + } get_device(&priv->master_mii_bus->dev); priv->master_mii_dn = dn; priv->slave_mii_bus = devm_mdiobus_alloc(ds->dev); - if (!priv->slave_mii_bus) + if (!priv->slave_mii_bus) { + of_node_put(dn); return -ENOMEM; + } priv->slave_mii_bus->priv = priv; priv->slave_mii_bus->name = "sf2 slave mii"; @@ -458,7 +458,7 @@ priv->slave_mii_bus->parent = ds->dev->parent; priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask; - err = of_mdiobus_register(priv->slave_mii_bus, dn); + err = mdiobus_register(priv->slave_mii_bus); if (err && dn) of_node_put(dn); @@ -479,8 +479,10 @@ * in bits 15:8 and the patch level in bits 7:0 which is exactly what * the REG_PHY_REVISION register layout is. */ - - return priv->hw_params.gphy_rev; + if (priv->int_phy_mask & BIT(port)) + return priv->hw_params.gphy_rev; + else + return 0; } static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port, @@ -600,6 +602,11 @@ reg |= LINK_STS; if (state->duplex == DUPLEX_FULL) reg |= DUPLX_MODE; + if (state->pause & MLO_PAUSE_TXRX_MASK) { + if (state->pause & MLO_PAUSE_TX) + reg |= TXFLOW_CNTL; + reg |= RXFLOW_CNTL; + } core_writel(priv, reg, offset); } @@ -1052,6 +1059,7 @@ const struct bcm_sf2_of_data *data; struct b53_platform_data *pdata; struct dsa_switch_ops *ops; + struct device_node *ports; struct bcm_sf2_priv *priv; struct b53_device *dev; struct dsa_switch *ds; @@ -1114,7 +1122,13 @@ set_bit(0, priv->cfp.used); set_bit(0, priv->cfp.unique); - bcm_sf2_identify_ports(priv, dn->child); + /* Balance of_node_put() done by of_find_node_by_name() */ + of_node_get(dn); + ports = of_find_node_by_name(dn, "ports"); + if (ports) { + bcm_sf2_identify_ports(priv, ports); + of_node_put(ports); + } priv->irq0 = irq_of_parse_and_map(dn, 0); priv->irq1 = irq_of_parse_and_map(dn, 1); --- linux-oracle-5.4.0.orig/drivers/net/dsa/bcm_sf2_cfp.c +++ linux-oracle-5.4.0/drivers/net/dsa/bcm_sf2_cfp.c @@ -358,7 +358,7 @@ return -EINVAL; } - ip_frag = be32_to_cpu(fs->m_ext.data[0]); + ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); /* Locate the first rule available */ if (fs->location == RX_CLS_LOC_ANY) @@ -542,14 +542,14 @@ static struct cfp_rule *bcm_sf2_cfp_rule_find(struct bcm_sf2_priv *priv, int port, u32 location) { - struct cfp_rule *rule = NULL; + struct cfp_rule *rule; list_for_each_entry(rule, &priv->cfp.rules_list, next) { if (rule->port == port && rule->fs.location == location) - break; + return rule; } - return rule; + return NULL; } static int bcm_sf2_cfp_rule_cmp(struct bcm_sf2_priv *priv, int port, @@ -569,7 +569,7 @@ if (rule->fs.flow_type != fs->flow_type || rule->fs.ring_cookie != fs->ring_cookie || - rule->fs.m_ext.data[0] != fs->m_ext.data[0]) + rule->fs.h_ext.data[0] != fs->h_ext.data[0]) continue; switch (fs->flow_type & ~FLOW_EXT) { @@ -621,7 +621,7 @@ return -EINVAL; } - ip_frag = be32_to_cpu(fs->m_ext.data[0]); + ip_frag = !!(be32_to_cpu(fs->h_ext.data[0]) & 1); layout = &udf_tcpip6_layout; slice_num = bcm_sf2_get_slice_number(layout, 0); @@ -882,17 +882,14 @@ fs->m_ext.data[1])) return -EINVAL; - if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) + if (fs->location != RX_CLS_LOC_ANY && + fs->location > bcm_sf2_cfp_rule_size(priv)) return -EINVAL; if (fs->location != RX_CLS_LOC_ANY && test_bit(fs->location, priv->cfp.used)) return -EBUSY; - if (fs->location != RX_CLS_LOC_ANY && - fs->location > bcm_sf2_cfp_rule_size(priv)) - return -EINVAL; - ret = bcm_sf2_cfp_rule_cmp(priv, port, fs); if (ret == 0) return -EEXIST; @@ -973,7 +970,7 @@ struct cfp_rule *rule; int ret; - if (loc >= CFP_NUM_RULES) + if (loc > bcm_sf2_cfp_rule_size(priv)) return -EINVAL; /* Refuse deleting unused rules, and those that are not unique since --- linux-oracle-5.4.0.orig/drivers/net/dsa/dsa_loop.c +++ linux-oracle-5.4.0/drivers/net/dsa/dsa_loop.c @@ -329,6 +329,17 @@ #define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2) +static void dsa_loop_phydevs_unregister(void) +{ + unsigned int i; + + for (i = 0; i < NUM_FIXED_PHYS; i++) + if (!IS_ERR(phydevs[i])) { + fixed_phy_unregister(phydevs[i]); + phy_device_free(phydevs[i]); + } +} + static int __init dsa_loop_init(void) { struct fixed_phy_status status = { @@ -336,26 +347,27 @@ .speed = SPEED_100, .duplex = DUPLEX_FULL, }; - unsigned int i; + unsigned int i, ret; for (i = 0; i < NUM_FIXED_PHYS; i++) phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL); - return mdio_driver_register(&dsa_loop_drv); + ret = mdio_driver_register(&dsa_loop_drv); + if (ret) + dsa_loop_phydevs_unregister(); + + return ret; } module_init(dsa_loop_init); static void __exit dsa_loop_exit(void) { - unsigned int i; - mdio_driver_unregister(&dsa_loop_drv); - for (i = 0; i < NUM_FIXED_PHYS; i++) - if (!IS_ERR(phydevs[i])) - fixed_phy_unregister(phydevs[i]); + dsa_loop_phydevs_unregister(); } module_exit(dsa_loop_exit); +MODULE_SOFTDEP("pre: dsa_loop_bdinfo"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Florian Fainelli"); MODULE_DESCRIPTION("DSA loopback driver"); --- linux-oracle-5.4.0.orig/drivers/net/dsa/lan9303-core.c +++ linux-oracle-5.4.0/drivers/net/dsa/lan9303-core.c @@ -557,12 +557,12 @@ return 0; } -typedef void alr_loop_cb_t(struct lan9303 *chip, u32 dat0, u32 dat1, - int portmap, void *ctx); +typedef int alr_loop_cb_t(struct lan9303 *chip, u32 dat0, u32 dat1, + int portmap, void *ctx); -static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) +static int lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) { - int i; + int ret = 0, i; mutex_lock(&chip->alr_mutex); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, @@ -582,13 +582,17 @@ LAN9303_ALR_DAT1_PORT_BITOFFS; portmap = alrport_2_portmap[alrport]; - cb(chip, dat0, dat1, portmap, ctx); + ret = cb(chip, dat0, dat1, portmap, ctx); + if (ret) + break; lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, LAN9303_ALR_CMD_GET_NEXT); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); } mutex_unlock(&chip->alr_mutex); + + return ret; } static void alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6]) @@ -606,18 +610,20 @@ }; /* Clear learned (non-static) entry on given port */ -static void alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0, - u32 dat1, int portmap, void *ctx) +static int alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0, + u32 dat1, int portmap, void *ctx) { struct del_port_learned_ctx *del_ctx = ctx; int port = del_ctx->port; if (((BIT(port) & portmap) == 0) || (dat1 & LAN9303_ALR_DAT1_STATIC)) - return; + return 0; /* learned entries has only one port, we can just delete */ dat1 &= ~LAN9303_ALR_DAT1_VALID; /* delete entry */ lan9303_alr_make_entry_raw(chip, dat0, dat1); + + return 0; } struct port_fdb_dump_ctx { @@ -626,19 +632,19 @@ dsa_fdb_dump_cb_t *cb; }; -static void alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0, - u32 dat1, int portmap, void *ctx) +static int alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0, + u32 dat1, int portmap, void *ctx) { struct port_fdb_dump_ctx *dump_ctx = ctx; u8 mac[ETH_ALEN]; bool is_static; if ((BIT(dump_ctx->port) & portmap) == 0) - return; + return 0; alr_reg_to_mac(dat0, dat1, mac); is_static = !!(dat1 & LAN9303_ALR_DAT1_STATIC); - dump_ctx->cb(mac, 0, is_static, dump_ctx->data); + return dump_ctx->cb(mac, 0, is_static, dump_ctx->data); } /* Set a static ALR entry. Delete entry if port_map is zero */ @@ -951,7 +957,7 @@ { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", }, { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", }, { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", }, - { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", }, + { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "RxShort", }, { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", }, { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", }, { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", }, @@ -995,9 +1001,11 @@ ret = lan9303_read_switch_port( chip, port, lan9303_mib[u].offset, ®); - if (ret) + if (ret) { dev_warn(chip->dev, "Reading status port %d reg %u failed\n", port, lan9303_mib[u].offset); + reg = 0; + } data[u] = reg; } } @@ -1179,8 +1187,6 @@ struct lan9303 *chip = ds->priv; dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); - if (vid) - return -EOPNOTSUPP; return lan9303_alr_add_port(chip, addr, port, false); } @@ -1192,8 +1198,6 @@ struct lan9303 *chip = ds->priv; dev_dbg(chip->dev, "%s(%d, %pM, %d)\n", __func__, port, addr, vid); - if (vid) - return -EOPNOTSUPP; lan9303_alr_del_port(chip, addr, port); return 0; @@ -1210,9 +1214,7 @@ }; dev_dbg(chip->dev, "%s(%d)\n", __func__, port); - lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx); - - return 0; + return lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx); } static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port, @@ -1299,7 +1301,7 @@ struct device_node *np) { chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset", - GPIOD_OUT_LOW); + GPIOD_OUT_HIGH); if (IS_ERR(chip->reset_gpio)) return PTR_ERR(chip->reset_gpio); --- linux-oracle-5.4.0.orig/drivers/net/dsa/lan9303_mdio.c +++ linux-oracle-5.4.0/drivers/net/dsa/lan9303_mdio.c @@ -32,7 +32,7 @@ struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; reg <<= 2; /* reg num to offset */ - mutex_lock(&sw_dev->device->bus->mdio_lock); + mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED); lan9303_mdio_real_write(sw_dev->device, reg, val & 0xffff); lan9303_mdio_real_write(sw_dev->device, reg + 2, (val >> 16) & 0xffff); mutex_unlock(&sw_dev->device->bus->mdio_lock); @@ -50,7 +50,7 @@ struct lan9303_mdio *sw_dev = (struct lan9303_mdio *)ctx; reg <<= 2; /* reg num to offset */ - mutex_lock(&sw_dev->device->bus->mdio_lock); + mutex_lock_nested(&sw_dev->device->bus->mdio_lock, MDIO_MUTEX_NESTED); *val = lan9303_mdio_real_read(sw_dev->device, reg); *val |= (lan9303_mdio_real_read(sw_dev->device, reg + 2) << 16); mutex_unlock(&sw_dev->device->bus->mdio_lock); --- linux-oracle-5.4.0.orig/drivers/net/dsa/lantiq_gswip.c +++ linux-oracle-5.4.0/drivers/net/dsa/lantiq_gswip.c @@ -26,6 +26,7 @@ */ #include +#include #include #include #include @@ -91,11 +92,13 @@ GSWIP_MDIO_PHY_FDUP_MASK) /* GSWIP MII Registers */ -#define GSWIP_MII_CFG0 0x00 -#define GSWIP_MII_CFG1 0x02 -#define GSWIP_MII_CFG5 0x04 +#define GSWIP_MII_CFGp(p) (0x2 * (p)) +#define GSWIP_MII_CFG_RESET BIT(15) #define GSWIP_MII_CFG_EN BIT(14) +#define GSWIP_MII_CFG_ISOLATE BIT(13) #define GSWIP_MII_CFG_LDCLKDIS BIT(12) +#define GSWIP_MII_CFG_RGMII_IBS BIT(8) +#define GSWIP_MII_CFG_RMII_CLK BIT(7) #define GSWIP_MII_CFG_MODE_MIIP 0x0 #define GSWIP_MII_CFG_MODE_MIIM 0x1 #define GSWIP_MII_CFG_MODE_RMIIP 0x2 @@ -191,6 +194,23 @@ #define GSWIP_PCE_DEFPVID(p) (0x486 + ((p) * 0xA)) #define GSWIP_MAC_FLEN 0x8C5 +#define GSWIP_MAC_CTRL_0p(p) (0x903 + ((p) * 0xC)) +#define GSWIP_MAC_CTRL_0_PADEN BIT(8) +#define GSWIP_MAC_CTRL_0_FCS_EN BIT(7) +#define GSWIP_MAC_CTRL_0_FCON_MASK 0x0070 +#define GSWIP_MAC_CTRL_0_FCON_AUTO 0x0000 +#define GSWIP_MAC_CTRL_0_FCON_RX 0x0010 +#define GSWIP_MAC_CTRL_0_FCON_TX 0x0020 +#define GSWIP_MAC_CTRL_0_FCON_RXTX 0x0030 +#define GSWIP_MAC_CTRL_0_FCON_NONE 0x0040 +#define GSWIP_MAC_CTRL_0_FDUP_MASK 0x000C +#define GSWIP_MAC_CTRL_0_FDUP_AUTO 0x0000 +#define GSWIP_MAC_CTRL_0_FDUP_EN 0x0004 +#define GSWIP_MAC_CTRL_0_FDUP_DIS 0x000C +#define GSWIP_MAC_CTRL_0_GMII_MASK 0x0003 +#define GSWIP_MAC_CTRL_0_GMII_AUTO 0x0000 +#define GSWIP_MAC_CTRL_0_GMII_MII 0x0001 +#define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002 #define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC)) #define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */ @@ -209,7 +229,7 @@ #define GSWIP_SDMA_PCTRLp(p) (0xBC0 + ((p) * 0x6)) #define GSWIP_SDMA_PCTRL_EN BIT(0) /* SDMA Port Enable */ #define GSWIP_SDMA_PCTRL_FCEN BIT(1) /* Flow Control Enable */ -#define GSWIP_SDMA_PCTRL_PAUFWD BIT(1) /* Pause Frame Forwarding */ +#define GSWIP_SDMA_PCTRL_PAUFWD BIT(3) /* Pause Frame Forwarding */ #define GSWIP_TABLE_ACTIVE_VLAN 0x01 #define GSWIP_TABLE_VLAN_MAPPING 0x02 @@ -391,17 +411,9 @@ static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, int port) { - switch (port) { - case 0: - gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG0); - break; - case 1: - gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG1); - break; - case 5: - gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG5); - break; - } + /* There's no MII_CFG register for the CPU port */ + if (!dsa_is_cpu_port(priv->ds, port)) + gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port)); } static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set, @@ -662,16 +674,13 @@ GSWIP_SDMA_PCTRLp(port)); if (!dsa_is_cpu_port(ds, port)) { - u32 macconf = GSWIP_MDIO_PHY_LINK_AUTO | - GSWIP_MDIO_PHY_SPEED_AUTO | - GSWIP_MDIO_PHY_FDUP_AUTO | - GSWIP_MDIO_PHY_FCONTX_AUTO | - GSWIP_MDIO_PHY_FCONRX_AUTO | - (phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK); - - gswip_mdio_w(priv, macconf, GSWIP_MDIO_PHYp(port)); - /* Activate MDIO auto polling */ - gswip_mdio_mask(priv, 0, BIT(port), GSWIP_MDIO_MDC_CFG0); + u32 mdio_phy = 0; + + if (phydev) + mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK; + + gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy, + GSWIP_MDIO_PHYp(port)); } return 0; @@ -684,14 +693,6 @@ if (!dsa_is_user_port(ds, port)) return; - if (!dsa_is_cpu_port(ds, port)) { - gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_DOWN, - GSWIP_MDIO_PHY_LINK_MASK, - GSWIP_MDIO_PHYp(port)); - /* Deactivate MDIO auto polling */ - gswip_mdio_mask(priv, BIT(port), 0, GSWIP_MDIO_MDC_CFG0); - } - gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0, GSWIP_FDMA_PCTRLp(port)); gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0, @@ -799,15 +800,32 @@ gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP2); gswip_switch_w(priv, BIT(cpu_port), GSWIP_PCE_PMAP3); - /* disable PHY auto polling */ + /* Deactivate MDIO PHY auto polling. Some PHYs as the AR8030 have an + * interoperability problem with this auto polling mechanism because + * their status registers think that the link is in a different state + * than it actually is. For the AR8030 it has the BMSR_ESTATEN bit set + * as well as ESTATUS_1000_TFULL and ESTATUS_1000_XFULL. This makes the + * auto polling state machine consider the link being negotiated with + * 1Gbit/s. Since the PHY itself is a Fast Ethernet RMII PHY this leads + * to the switch port being completely dead (RX and TX are both not + * working). + * Also with various other PHY / port combinations (PHY11G GPHY, PHY22F + * GPHY, external RGMII PEF7071/7072) any traffic would stop. Sometimes + * it would work fine for a few minutes to hours and then stop, on + * other device it would no traffic could be sent or received at all. + * Testing shows that when PHY auto polling is disabled these problems + * go away. + */ gswip_mdio_w(priv, 0x0, GSWIP_MDIO_MDC_CFG0); + /* Configure the MDIO Clock 2.5 MHz */ gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); - /* Disable the xMII link */ - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 0); - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 1); - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 5); + /* Disable the xMII interface and clear it's isolation bit */ + for (i = 0; i < priv->hw_info->max_ports; i++) + gswip_mii_mask_cfg(priv, + GSWIP_MII_CFG_EN | GSWIP_MII_CFG_ISOLATE, + 0, i); /* enable special tag insertion on cpu port */ gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, @@ -819,7 +837,8 @@ gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN, GSWIP_MAC_CTRL_2p(cpu_port)); - gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8, GSWIP_MAC_FLEN); + gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN, + GSWIP_MAC_FLEN); gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD, GSWIP_BM_QUEUE_GCTRL); @@ -1381,11 +1400,17 @@ addr[1] = mac_bridge.key[2] & 0xff; addr[0] = (mac_bridge.key[2] >> 8) & 0xff; if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) { - if (mac_bridge.val[0] & BIT(port)) - cb(addr, 0, true, data); + if (mac_bridge.val[0] & BIT(port)) { + err = cb(addr, 0, true, data); + if (err) + return err; + } } else { - if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) - cb(addr, 0, false, data); + if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) { + err = cb(addr, 0, false, data); + if (err) + return err; + } } } return 0; @@ -1429,11 +1454,12 @@ phylink_set(mask, Pause); phylink_set(mask, Asym_Pause); - /* With the exclusion of MII and Reverse MII, we support Gigabit, - * including Half duplex + /* With the exclusion of MII, Reverse MII and Reduced MII, we + * support Gigabit, including Half duplex */ if (state->interface != PHY_INTERFACE_MODE_MII && - state->interface != PHY_INTERFACE_MODE_REVMII) { + state->interface != PHY_INTERFACE_MODE_REVMII && + state->interface != PHY_INTERFACE_MODE_RMII) { phylink_set(mask, 1000baseT_Full); phylink_set(mask, 1000baseT_Half); } @@ -1451,10 +1477,117 @@ unsupported: bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); - dev_err(ds->dev, "Unsupported interface: %d\n", state->interface); + dev_err(ds->dev, "Unsupported interface '%s' for port %d\n", + phy_modes(state->interface), port); return; } +static void gswip_port_set_link(struct gswip_priv *priv, int port, bool link) +{ + u32 mdio_phy; + + if (link) + mdio_phy = GSWIP_MDIO_PHY_LINK_UP; + else + mdio_phy = GSWIP_MDIO_PHY_LINK_DOWN; + + gswip_mdio_mask(priv, GSWIP_MDIO_PHY_LINK_MASK, mdio_phy, + GSWIP_MDIO_PHYp(port)); +} + +static void gswip_port_set_speed(struct gswip_priv *priv, int port, int speed, + phy_interface_t interface) +{ + u32 mdio_phy = 0, mii_cfg = 0, mac_ctrl_0 = 0; + + switch (speed) { + case SPEED_10: + mdio_phy = GSWIP_MDIO_PHY_SPEED_M10; + + if (interface == PHY_INTERFACE_MODE_RMII) + mii_cfg = GSWIP_MII_CFG_RATE_M50; + else + mii_cfg = GSWIP_MII_CFG_RATE_M2P5; + + mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII; + break; + + case SPEED_100: + mdio_phy = GSWIP_MDIO_PHY_SPEED_M100; + + if (interface == PHY_INTERFACE_MODE_RMII) + mii_cfg = GSWIP_MII_CFG_RATE_M50; + else + mii_cfg = GSWIP_MII_CFG_RATE_M25; + + mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_MII; + break; + + case SPEED_1000: + mdio_phy = GSWIP_MDIO_PHY_SPEED_G1; + + mii_cfg = GSWIP_MII_CFG_RATE_M125; + + mac_ctrl_0 = GSWIP_MAC_CTRL_0_GMII_RGMII; + break; + } + + gswip_mdio_mask(priv, GSWIP_MDIO_PHY_SPEED_MASK, mdio_phy, + GSWIP_MDIO_PHYp(port)); + gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_RATE_MASK, mii_cfg, port); + gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_GMII_MASK, mac_ctrl_0, + GSWIP_MAC_CTRL_0p(port)); +} + +static void gswip_port_set_duplex(struct gswip_priv *priv, int port, int duplex) +{ + u32 mac_ctrl_0, mdio_phy; + + if (duplex == DUPLEX_FULL) { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_EN; + mdio_phy = GSWIP_MDIO_PHY_FDUP_EN; + } else { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FDUP_DIS; + mdio_phy = GSWIP_MDIO_PHY_FDUP_DIS; + } + + gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FDUP_MASK, mac_ctrl_0, + GSWIP_MAC_CTRL_0p(port)); + gswip_mdio_mask(priv, GSWIP_MDIO_PHY_FDUP_MASK, mdio_phy, + GSWIP_MDIO_PHYp(port)); +} + +static void gswip_port_set_pause(struct gswip_priv *priv, int port, + bool tx_pause, bool rx_pause) +{ + u32 mac_ctrl_0, mdio_phy; + + if (tx_pause && rx_pause) { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RXTX; + mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN | + GSWIP_MDIO_PHY_FCONRX_EN; + } else if (tx_pause) { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_TX; + mdio_phy = GSWIP_MDIO_PHY_FCONTX_EN | + GSWIP_MDIO_PHY_FCONRX_DIS; + } else if (rx_pause) { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_RX; + mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS | + GSWIP_MDIO_PHY_FCONRX_EN; + } else { + mac_ctrl_0 = GSWIP_MAC_CTRL_0_FCON_NONE; + mdio_phy = GSWIP_MDIO_PHY_FCONTX_DIS | + GSWIP_MDIO_PHY_FCONRX_DIS; + } + + gswip_switch_mask(priv, GSWIP_MAC_CTRL_0_FCON_MASK, + mac_ctrl_0, GSWIP_MAC_CTRL_0p(port)); + gswip_mdio_mask(priv, + GSWIP_MDIO_PHY_FCONTX_MASK | + GSWIP_MDIO_PHY_FCONRX_MASK, + mdio_phy, GSWIP_MDIO_PHYp(port)); +} + static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, const struct phylink_link_state *state) @@ -1486,7 +1619,16 @@ "Unsupported interface: %d\n", state->interface); return; } - gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_MODE_MASK, miicfg, port); + + gswip_mii_mask_cfg(priv, + GSWIP_MII_CFG_MODE_MASK | GSWIP_MII_CFG_RMII_CLK | + GSWIP_MII_CFG_RGMII_IBS | GSWIP_MII_CFG_LDCLKDIS, + miicfg, port); + + gswip_port_set_speed(priv, port, state->speed, state->interface); + gswip_port_set_duplex(priv, port, state->duplex); + gswip_port_set_pause(priv, port, !!(state->pause & MLO_PAUSE_TX), + !!(state->pause & MLO_PAUSE_RX)); switch (state->interface) { case PHY_INTERFACE_MODE_RGMII_ID: @@ -1511,6 +1653,9 @@ struct gswip_priv *priv = ds->priv; gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, port); + + if (!dsa_is_cpu_port(ds, port)) + gswip_port_set_link(priv, port, false); } static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, @@ -1520,9 +1665,10 @@ { struct gswip_priv *priv = ds->priv; - /* Enable the xMII interface only for the external PHY */ - if (interface != PHY_INTERFACE_MODE_INTERNAL) - gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); + if (!dsa_is_cpu_port(ds, port)) + gswip_port_set_link(priv, port, true); + + gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); } static void gswip_get_strings(struct dsa_switch *ds, int port, u32 stringset, @@ -1812,11 +1958,23 @@ for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) { err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i], gphy_fw_np, i); - if (err) + if (err) { + of_node_put(gphy_fw_np); goto remove_gphy; + } i++; } + /* The standalone PHY11G requires 300ms to be fully + * initialized and ready for any MDIO communication after being + * taken out of reset. For the SoC-internal GPHY variant there + * is no (known) documentation for the minimum time after a + * reset. Use the same value as for the standalone variant as + * some users have reported internal PHYs not being detected + * without any delay. + */ + msleep(300); + return 0; remove_gphy: --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz8795.c +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz8795.c @@ -1267,6 +1267,9 @@ return -ENOMEM; } + /* set the real number of ports */ + dev->ds->num_ports = dev->port_cnt; + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz8795_spi.c +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz8795_spi.c @@ -86,12 +86,23 @@ }; MODULE_DEVICE_TABLE(of, ksz8795_dt_ids); +static const struct spi_device_id ksz8795_spi_ids[] = { + { "ksz8765" }, + { "ksz8794" }, + { "ksz8795" }, + { "ksz8863" }, + { "ksz8873" }, + { }, +}; +MODULE_DEVICE_TABLE(spi, ksz8795_spi_ids); + static struct spi_driver ksz8795_spi_driver = { .driver = { .name = "ksz8795-switch", .owner = THIS_MODULE, .of_match_table = of_match_ptr(ksz8795_dt_ids), }, + .id_table = ksz8795_spi_ids, .probe = ksz8795_spi_probe, .remove = ksz8795_spi_remove, .shutdown = ksz8795_spi_shutdown, --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz9477.c +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz9477.c @@ -206,10 +206,8 @@ SPI_AUTO_EDGE_DETECTION, 0); /* default configuration */ - ksz_read8(dev, REG_SW_LUE_CTRL_1, &data8); - data8 = SW_AGING_ENABLE | SW_LINK_AUTO_AGING | - SW_SRC_ADDR_FILTER | SW_FLUSH_STP_TABLE | SW_FLUSH_MSTP_TABLE; - ksz_write8(dev, REG_SW_LUE_CTRL_1, data8); + ksz_write8(dev, REG_SW_LUE_CTRL_1, + SW_AGING_ENABLE | SW_LINK_AUTO_AGING | SW_SRC_ADDR_FILTER); /* disable interrupts */ ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK); @@ -682,10 +680,10 @@ ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]); /* clear forwarding port */ - alu_table[2] &= ~BIT(port); + alu_table[1] &= ~BIT(port); /* if there is no port to forward, clear table */ - if ((alu_table[2] & ALU_V_PORT_MAP) == 0) { + if ((alu_table[1] & ALU_V_PORT_MAP) == 0) { alu_table[0] = 0; alu_table[1] = 0; alu_table[2] = 0; @@ -766,6 +764,9 @@ goto exit; } + if (!(ksz_data & ALU_VALID)) + continue; + /* read ALU table */ ksz9477_read_table(dev, alu_table); @@ -973,23 +974,6 @@ PORT_MIRROR_SNIFFER, false); } -static void ksz9477_phy_setup(struct ksz_device *dev, int port, - struct phy_device *phy) -{ - /* Only apply to port with PHY. */ - if (port >= dev->phy_port_cnt) - return; - - /* The MAC actually cannot run in 1000 half-duplex mode. */ - phy_remove_link_mode(phy, - ETHTOOL_LINK_MODE_1000baseT_Half_BIT); - - /* PHY does not support gigabit. */ - if (!(dev->features & GBIT_SUPPORT)) - phy_remove_link_mode(phy, - ETHTOOL_LINK_MODE_1000baseT_Full_BIT); -} - static bool ksz9477_get_gbit(struct ksz_device *dev, u8 data) { bool gbit; @@ -1537,6 +1521,7 @@ .num_statics = 16, .cpu_ports = 0x7F, /* can be configured as cpu port */ .port_cnt = 7, /* total physical port count */ + .phy_errata_9477 = true, }, }; @@ -1587,6 +1572,9 @@ return -ENOMEM; } + /* set the real number of ports */ + dev->ds->num_ports = dev->port_cnt; + return 0; } @@ -1599,7 +1587,6 @@ .get_port_addr = ksz9477_get_port_addr, .cfg_port_member = ksz9477_cfg_port_member, .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, - .phy_setup = ksz9477_phy_setup, .port_setup = ksz9477_port_setup, .r_mib_cnt = ksz9477_r_mib_cnt, .r_mib_pkt = ksz9477_r_mib_pkt, @@ -1613,7 +1600,29 @@ int ksz9477_switch_register(struct ksz_device *dev) { - return ksz_switch_register(dev, &ksz9477_dev_ops); + int ret, i; + struct phy_device *phydev; + + ret = ksz_switch_register(dev, &ksz9477_dev_ops); + if (ret) + return ret; + + for (i = 0; i < dev->phy_port_cnt; ++i) { + if (!dsa_is_user_port(dev->ds, i)) + continue; + + phydev = dsa_to_port(dev->ds, i)->slave->phydev; + + /* The MAC actually cannot run in 1000 half-duplex mode. */ + phy_remove_link_mode(phydev, + ETHTOOL_LINK_MODE_1000baseT_Half_BIT); + + /* PHY does not support gigabit. */ + if (!(dev->features & GBIT_SUPPORT)) + phy_remove_link_mode(phydev, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT); + } + return ret; } EXPORT_SYMBOL(ksz9477_switch_register); --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz9477_spi.c +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz9477_spi.c @@ -88,12 +88,24 @@ }; MODULE_DEVICE_TABLE(of, ksz9477_dt_ids); +static const struct spi_device_id ksz9477_spi_ids[] = { + { "ksz9477" }, + { "ksz9897" }, + { "ksz9893" }, + { "ksz9563" }, + { "ksz8563" }, + { "ksz9567" }, + { }, +}; +MODULE_DEVICE_TABLE(spi, ksz9477_spi_ids); + static struct spi_driver ksz9477_spi_driver = { .driver = { .name = "ksz9477-switch", .owner = THIS_MODULE, .of_match_table = of_match_ptr(ksz9477_dt_ids), }, + .id_table = ksz9477_spi_ids, .probe = ksz9477_spi_probe, .remove = ksz9477_spi_remove, .shutdown = ksz9477_spi_shutdown, @@ -101,6 +113,12 @@ module_spi_driver(ksz9477_spi_driver); +MODULE_ALIAS("spi:ksz9477"); +MODULE_ALIAS("spi:ksz9897"); +MODULE_ALIAS("spi:ksz9893"); +MODULE_ALIAS("spi:ksz9563"); +MODULE_ALIAS("spi:ksz8563"); +MODULE_ALIAS("spi:ksz9567"); MODULE_AUTHOR("Woojung Huh "); MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch SPI access Driver"); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz_common.c +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz_common.c @@ -366,8 +366,6 @@ /* setup slave port */ dev->dev_ops->port_setup(dev, port, false); - if (dev->dev_ops->phy_setup) - dev->dev_ops->phy_setup(dev, port, phy); /* port_stp_state_set() will be called after to enable the port so * there is no need to do anything. --- linux-oracle-5.4.0.orig/drivers/net/dsa/microchip/ksz_common.h +++ linux-oracle-5.4.0/drivers/net/dsa/microchip/ksz_common.h @@ -120,8 +120,6 @@ u32 (*get_port_addr)(int port, int offset); void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member); void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); - void (*phy_setup)(struct ksz_device *dev, int port, - struct phy_device *phy); void (*port_cleanup)(struct ksz_device *dev, int port); void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); @@ -217,12 +215,8 @@ int ret; ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); - if (!ret) { - /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ - value[0] = swab32(value[0]); - value[1] = swab32(value[1]); - *val = swab64((u64)*value); - } + if (!ret) + *val = (u64)value[0] << 32 | value[1]; return ret; } --- linux-oracle-5.4.0.orig/drivers/net/dsa/mt7530.c +++ linux-oracle-5.4.0/drivers/net/dsa/mt7530.c @@ -45,6 +45,7 @@ MIB_DESC(2, 0x48, "TxBytes"), MIB_DESC(1, 0x60, "RxDrop"), MIB_DESC(1, 0x64, "RxFiltering"), + MIB_DESC(1, 0x68, "RxUnicast"), MIB_DESC(1, 0x6c, "RxMulticast"), MIB_DESC(1, 0x70, "RxBroadcast"), MIB_DESC(1, 0x74, "RxAlignErr"), @@ -67,58 +68,6 @@ }; static int -mt7623_trgmii_write(struct mt7530_priv *priv, u32 reg, u32 val) -{ - int ret; - - ret = regmap_write(priv->ethernet, TRGMII_BASE(reg), val); - if (ret < 0) - dev_err(priv->dev, - "failed to priv write register\n"); - return ret; -} - -static u32 -mt7623_trgmii_read(struct mt7530_priv *priv, u32 reg) -{ - int ret; - u32 val; - - ret = regmap_read(priv->ethernet, TRGMII_BASE(reg), &val); - if (ret < 0) { - dev_err(priv->dev, - "failed to priv read register\n"); - return ret; - } - - return val; -} - -static void -mt7623_trgmii_rmw(struct mt7530_priv *priv, u32 reg, - u32 mask, u32 set) -{ - u32 val; - - val = mt7623_trgmii_read(priv, reg); - val &= ~mask; - val |= set; - mt7623_trgmii_write(priv, reg, val); -} - -static void -mt7623_trgmii_set(struct mt7530_priv *priv, u32 reg, u32 val) -{ - mt7623_trgmii_rmw(priv, reg, 0, val); -} - -static void -mt7623_trgmii_clear(struct mt7530_priv *priv, u32 reg, u32 val) -{ - mt7623_trgmii_rmw(priv, reg, val, 0); -} - -static int core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad) { struct mii_bus *bus = priv->bus; @@ -448,9 +397,9 @@ case PHY_INTERFACE_MODE_TRGMII: trgint = 1; if (priv->id == ID_MT7621) { - /* PLL frequency: 150MHz: 1.2GBit */ + /* PLL frequency: 125MHz: 1.0GBit */ if (xtal == HWTRAP_XTAL_40MHZ) - ncpo1 = 0x0780; + ncpo1 = 0x0640; if (xtal == HWTRAP_XTAL_25MHZ) ncpo1 = 0x0a00; } else { /* PLL frequency: 250MHz: 2.0Gbit */ @@ -530,27 +479,6 @@ for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mt7530_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_MASK, RD_TAP(16)); - else - if (priv->id != ID_MT7621) - mt7623_trgmii_set(priv, GSW_INTF_MODE, - INTF_MODE_TRGMII); - - return 0; -} - -static int -mt7623_pad_clk_setup(struct dsa_switch *ds) -{ - struct mt7530_priv *priv = ds->priv; - int i; - - for (i = 0 ; i < NUM_TRGMII_CTRL; i++) - mt7623_trgmii_write(priv, GSW_TRGMII_TD_ODT(i), - TD_DM_DRVP(8) | TD_DM_DRVN(8)); - - mt7623_trgmii_set(priv, GSW_TRGMII_RCK_CTRL, RX_RST | RXC_DQSISEL); - mt7623_trgmii_clear(priv, GSW_TRGMII_RCK_CTRL, RX_RST); - return 0; } @@ -566,7 +494,7 @@ static void mt7530_port_set_status(struct mt7530_priv *priv, int port, int enable) { - u32 mask = PMCR_TX_EN | PMCR_RX_EN; + u32 mask = PMCR_TX_EN | PMCR_RX_EN | PMCR_FORCE_LNK; if (enable) mt7530_set(priv, MT7530_PMCR_P(port), mask); @@ -712,14 +640,11 @@ mt7530_write(priv, MT7530_PVC_P(port), PORT_SPEC_TAG); - /* Disable auto learning on the cpu port */ - mt7530_set(priv, MT7530_PSC_P(port), SA_DIS); - - /* Unknown unicast frame fordwarding to the cpu port */ - mt7530_set(priv, MT7530_MFC, UNU_FFP(BIT(port))); + /* Unknown multicast frame forwarding to the cpu port */ + mt7530_rmw(priv, MT7530_MFC, UNM_FFP_MASK, UNM_FFP(BIT(port))); /* Set CPU port number */ - if (priv->id == ID_MT7621) + if (priv->id == ID_MT7530 || priv->id == ID_MT7621) mt7530_rmw(priv, MT7530_MFC, CPU_MASK, CPU_EN | CPU_PORT(port)); /* CPU port gets connected to all user ports of @@ -857,8 +782,9 @@ */ mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, MT7530_PORT_MATRIX_MODE); - mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, - VLAN_ATTR(MT7530_VLAN_TRANSPARENT)); + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK, + VLAN_ATTR(MT7530_VLAN_TRANSPARENT) | + PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); for (i = 0; i < MT7530_NUM_PORTS; i++) { if (dsa_is_user_port(ds, i) && @@ -874,8 +800,8 @@ if (all_user_ports_removed) { mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT), PCR_MATRIX(dsa_user_ports(priv->ds))); - mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), - PORT_SPEC_TAG); + mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG + | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); } } @@ -884,25 +810,23 @@ { struct mt7530_priv *priv = ds->priv; - /* The real fabric path would be decided on the membership in the - * entry of VLAN table. PCR_MATRIX set up here with ALL_MEMBERS - * means potential VLAN can be consisting of certain subset of all - * ports. - */ - mt7530_rmw(priv, MT7530_PCR_P(port), - PCR_MATRIX_MASK, PCR_MATRIX(MT7530_ALL_MEMBERS)); - /* Trapped into security mode allows packet forwarding through VLAN - * table lookup. + * table lookup. CPU port is set to fallback mode to let untagged + * frames pass through. */ - mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, - MT7530_PORT_SECURITY_MODE); + if (dsa_is_cpu_port(ds, port)) + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, + MT7530_PORT_FALLBACK_MODE); + else + mt7530_rmw(priv, MT7530_PCR_P(port), PCR_PORT_VLAN_MASK, + MT7530_PORT_SECURITY_MODE); /* Set the port as a user port which is to be able to recognize VID * from incoming packets before fetching entry within the VLAN table. */ - mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK, - VLAN_ATTR(MT7530_VLAN_USER)); + mt7530_rmw(priv, MT7530_PVC_P(port), VLAN_ATTR_MASK | PVC_EG_TAG_MASK, + VLAN_ATTR(MT7530_VLAN_USER) | + PVC_EG_TAG(MT7530_VLAN_EG_DISABLED)); } static void @@ -918,11 +842,8 @@ /* Remove this port from the port matrix of the other ports * in the same bridge. If the port is disabled, port matrix * is kept and not being setup until the port becomes enabled. - * And the other port's port matrix cannot be broken when the - * other port is still a VLAN-aware port. */ - if (dsa_is_user_port(ds, i) && i != port && - !dsa_port_is_vlan_filtering(&ds->ports[i])) { + if (dsa_is_user_port(ds, i) && i != port) { if (dsa_to_port(ds, i)->bridge_dev != bridge) continue; if (priv->ports[i].enable) @@ -1255,10 +1176,6 @@ dn = ds->ports[MT7530_CPU_PORT].master->dev.of_node->parent; if (priv->id == ID_MT7530) { - priv->ethernet = syscon_node_to_regmap(dn); - if (IS_ERR(priv->ethernet)) - return PTR_ERR(priv->ethernet); - regulator_set_voltage(priv->core_pwr, 1000000, 1000000); ret = regulator_enable(priv->core_pwr); if (ret < 0) { @@ -1321,8 +1238,6 @@ /* Enable and reset MIB counters */ mt7530_mib_reset(ds); - mt7530_clear(priv, MT7530_MFC, UNU_FFP_MASK); - for (i = 0; i < MT7530_NUM_PORTS; i++) { /* Disable forwarding by default on all ports */ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK, @@ -1332,6 +1247,10 @@ mt7530_cpu_port_enable(priv, i); else mt7530_port_disable(ds, i); + + /* Enable consistent egress tag */ + mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK, + PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT)); } /* Setup port 5 */ @@ -1353,6 +1272,9 @@ continue; phy_node = of_parse_phandle(mac_np, "phy-handle", 0); + if (!phy_node) + continue; + if (phy_node->parent == priv->dev->of_node->parent) { interface = of_get_phy_mode(mac_np); id = of_mdio_parse_addr(ds->dev, phy_node); @@ -1413,14 +1335,6 @@ /* Setup TX circuit incluing relevant PAD and driving */ mt7530_pad_clk_setup(ds, state->interface); - if (priv->id == ID_MT7530) { - /* Setup RX circuit, relevant PAD and driving on the - * host which must be placed after the setup on the - * device side is all finished. - */ - mt7623_pad_clk_setup(ds); - } - priv->p6_interface = state->interface; break; default: @@ -1439,7 +1353,7 @@ mcr_new &= ~(PMCR_FORCE_SPEED_1000 | PMCR_FORCE_SPEED_100 | PMCR_FORCE_FDX | PMCR_TX_FC_EN | PMCR_RX_FC_EN); mcr_new |= PMCR_IFG_XMIT(1) | PMCR_MAC_MODE | PMCR_BACKOFF_EN | - PMCR_BACKPR_EN | PMCR_FORCE_MODE | PMCR_FORCE_LNK; + PMCR_BACKPR_EN | PMCR_FORCE_MODE; /* Are we connected to external phy */ if (port == 5 && dsa_is_user_port(ds, 5)) @@ -1532,7 +1446,7 @@ phylink_set(mask, 100baseT_Full); if (state->interface != PHY_INTERFACE_MODE_MII) { - phylink_set(mask, 1000baseT_Half); + /* This switch only supports 1G full-duplex. */ phylink_set(mask, 1000baseT_Full); if (port == 5) phylink_set(mask, 1000baseX_Full); --- linux-oracle-5.4.0.orig/drivers/net/dsa/mt7530.h +++ linux-oracle-5.4.0/drivers/net/dsa/mt7530.h @@ -31,6 +31,7 @@ #define MT7530_MFC 0x10 #define BC_FFP(x) (((x) & 0xff) << 24) #define UNM_FFP(x) (((x) & 0xff) << 16) +#define UNM_FFP_MASK UNM_FFP(~0) #define UNU_FFP(x) (((x) & 0xff) << 8) #define UNU_FFP_MASK UNU_FFP(~0) #define CPU_EN BIT(7) @@ -147,6 +148,12 @@ /* Port Matrix Mode: Frames are forwarded by the PCR_MATRIX members. */ MT7530_PORT_MATRIX_MODE = PORT_VLAN(0), + /* Fallback Mode: Forward received frames with ingress ports that do + * not belong to the VLAN member. Frames whose VID is not listed on + * the VLAN table are forwarded by the PCR_MATRIX members. + */ + MT7530_PORT_FALLBACK_MODE = PORT_VLAN(1), + /* Security Mode: Discard any frame due to ingress membership * violation or VID missed on the VLAN table. */ @@ -167,9 +174,16 @@ /* Register for port vlan control */ #define MT7530_PVC_P(x) (0x2010 + ((x) * 0x100)) #define PORT_SPEC_TAG BIT(5) +#define PVC_EG_TAG(x) (((x) & 0x7) << 8) +#define PVC_EG_TAG_MASK PVC_EG_TAG(7) #define VLAN_ATTR(x) (((x) & 0x3) << 6) #define VLAN_ATTR_MASK VLAN_ATTR(3) +enum mt7530_vlan_port_eg_tag { + MT7530_VLAN_EG_DISABLED = 0, + MT7530_VLAN_EG_CONSISTENT = 1, +}; + enum mt7530_vlan_port_attr { MT7530_VLAN_USER = 0, MT7530_VLAN_TRANSPARENT = 3, @@ -268,7 +282,6 @@ /* Registers for TRGMII on the both side */ #define MT7530_TRGMII_RCK_CTRL 0x7a00 -#define GSW_TRGMII_RCK_CTRL 0x300 #define RX_RST BIT(31) #define RXC_DQSISEL BIT(30) #define DQSI1_TAP_MASK (0x7f << 8) @@ -277,31 +290,24 @@ #define DQSI0_TAP(x) ((x) & 0x7f) #define MT7530_TRGMII_RCK_RTT 0x7a04 -#define GSW_TRGMII_RCK_RTT 0x304 #define DQS1_GATE BIT(31) #define DQS0_GATE BIT(30) #define MT7530_TRGMII_RD(x) (0x7a10 + (x) * 8) -#define GSW_TRGMII_RD(x) (0x310 + (x) * 8) #define BSLIP_EN BIT(31) #define EDGE_CHK BIT(30) #define RD_TAP_MASK 0x7f #define RD_TAP(x) ((x) & 0x7f) -#define GSW_TRGMII_TXCTRL 0x340 #define MT7530_TRGMII_TXCTRL 0x7a40 #define TRAIN_TXEN BIT(31) #define TXC_INV BIT(30) #define TX_RST BIT(28) #define MT7530_TRGMII_TD_ODT(i) (0x7a54 + 8 * (i)) -#define GSW_TRGMII_TD_ODT(i) (0x354 + 8 * (i)) #define TD_DM_DRVP(x) ((x) & 0xf) #define TD_DM_DRVN(x) (((x) & 0xf) << 4) -#define GSW_INTF_MODE 0x390 -#define INTF_MODE_TRGMII BIT(1) - #define MT7530_TRGMII_TCK_CTRL 0x7a78 #define TCK_TAP(x) (((x) & 0xf) << 8) @@ -434,7 +440,6 @@ * @ds: The pointer to the dsa core structure * @bus: The bus used for the device and built-in PHY * @rstc: The pointer to reset control used by MCM - * @ethernet: The regmap used for access TRGMII-based registers * @core_pwr: The power supplied into the core * @io_pwr: The power supplied into the I/O * @reset: The descriptor for GPIO line tied to its reset pin @@ -451,7 +456,6 @@ struct dsa_switch *ds; struct mii_bus *bus; struct reset_control *rstc; - struct regmap *ethernet; struct regulator *core_pwr; struct regulator *io_pwr; struct gpio_desc *reset; --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6060.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6060.c @@ -117,6 +117,9 @@ int addr = REG_PORT(p); int ret; + if (dsa_is_unused_port(priv->ds, p)) + return 0; + /* Do not force flow control, disable Ingress and Egress * Header tagging, disable VLAN tunneling, and set the port * state to Forwarding. Additionally, if this is the CPU --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/Makefile +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/Makefile @@ -14,3 +14,7 @@ mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_PTP) += ptp.o mv88e6xxx-objs += serdes.o mv88e6xxx-objs += smi.o +mv88e6xxx-objs += trace.o + +# for tracing framework to find trace.h +CFLAGS_trace.o := -I$(src) --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/chip.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/chip.c @@ -115,8 +115,8 @@ { struct mv88e6xxx_mdio_bus *mdio_bus; - mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus, - list); + mdio_bus = list_first_entry_or_null(&chip->mdios, + struct mv88e6xxx_mdio_bus, list); if (!mdio_bus) return NULL; @@ -1517,7 +1517,11 @@ if (!entry.portvec) entry.state = 0; } else { - entry.portvec |= BIT(port); + if (state == MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC) + entry.portvec = BIT(port); + else + entry.portvec |= BIT(port); + entry.state = state; } @@ -2139,10 +2143,22 @@ /* If there is a GPIO connected to the reset pin, toggle it */ if (gpiod) { + /* If the switch has just been reset and not yet completed + * loading EEPROM, the reset may interrupt the I2C transaction + * mid-byte, causing the first EEPROM read after the reset + * from the wrong location resulting in the switch booting + * to wrong mode and inoperable. + */ + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); + gpiod_set_value_cansleep(gpiod, 1); usleep_range(10000, 20000); gpiod_set_value_cansleep(gpiod, 0); usleep_range(10000, 20000); + + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); } } @@ -2427,9 +2443,14 @@ * If this is the upstream port for this switch, enable * forwarding of unknown unicasts and multicasts. */ - reg = MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP | - MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | + reg = MV88E6185_PORT_CTL0_USE_TAG | MV88E6185_PORT_CTL0_USE_IP | MV88E6XXX_PORT_CTL0_STATE_FORWARDING; + /* Forward any IPv4 IGMP or IPv6 MLD frames received + * by a USER port to the CPU port to allow snooping. + */ + if (dsa_is_user_port(ds, port)) + reg |= MV88E6XXX_PORT_CTL0_IGMP_MLD_SNOOP; + err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg); if (err) return err; @@ -2760,10 +2781,17 @@ return err; } +/* prod_id for switch families which do not have a PHY model number */ +static const u16 family_prod_id_table[] = { + [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, + [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390, +}; + static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg) { struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv; struct mv88e6xxx_chip *chip = mdio_bus->chip; + u16 prod_id; u16 val; int err; @@ -2774,23 +2802,12 @@ err = chip->info->ops->phy_read(chip, bus, phy, reg, &val); mv88e6xxx_reg_unlock(chip); - if (reg == MII_PHYSID2) { - /* Some internal PHYs don't have a model number. */ - if (chip->info->family != MV88E6XXX_FAMILY_6165) - /* Then there is the 6165 family. It gets is - * PHYs correct. But it can also have two - * SERDES interfaces in the PHY address - * space. And these don't have a model - * number. But they are not PHYs, so we don't - * want to give them something a PHY driver - * will recognise. - * - * Use the mv88e6390 family model number - * instead, for anything which really could be - * a PHY, - */ - if (!(val & 0x3f0)) - val |= MV88E6XXX_PORT_SWITCH_ID_PROD_6390 >> 4; + /* Some internal PHYs don't have a model number. */ + if (reg == MII_PHYSID2 && !(val & 0x3f0) && + chip->info->family < ARRAY_SIZE(family_prod_id_table)) { + prod_id = family_prod_id_table[chip->info->family]; + if (prod_id) + val |= prod_id >> 4; } return err ? err : val; @@ -2908,6 +2925,7 @@ */ child = of_get_child_by_name(np, "mdio"); err = mv88e6xxx_mdio_register(chip, child, false); + of_node_put(child); if (err) return err; @@ -3060,10 +3078,10 @@ .port_set_duplex = mv88e6xxx_port_set_duplex, .port_set_speed = mv88e6185_port_set_speed, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_set_ether_type = mv88e6351_port_set_ether_type, - .port_set_jumbo_size = mv88e6165_port_set_jumbo_size, .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting, .port_pause_limit = mv88e6097_port_pause_limit, .port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit, @@ -3191,7 +3209,7 @@ .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, + .stats_set_histogram = mv88e6390_g1_stats_set_histogram, .stats_get_sset_count = mv88e6320_stats_get_sset_count, .stats_get_strings = mv88e6320_stats_get_strings, .stats_get_stats = mv88e6390_stats_get_stats, @@ -3714,6 +3732,7 @@ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, .port_set_speed = mv88e6250_port_set_speed, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_set_ether_type = mv88e6351_port_set_ether_type, @@ -3867,6 +3886,7 @@ .set_cpu_port = mv88e6095_g1_set_cpu_port, .set_egress_port = mv88e6095_g1_set_egress_port, .watchdog_ops = &mv88e6390_watchdog_ops, + .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .reset = mv88e6352_g1_reset, .vtu_getnext = mv88e6185_g1_vtu_getnext, .vtu_loadpurge = mv88e6185_g1_vtu_loadpurge, @@ -3905,7 +3925,7 @@ .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, + .stats_set_histogram = mv88e6390_g1_stats_set_histogram, .stats_get_sset_count = mv88e6320_stats_get_sset_count, .stats_get_strings = mv88e6320_stats_get_strings, .stats_get_stats = mv88e6390_stats_get_stats, @@ -3915,6 +3935,7 @@ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, + .rmu_disable = mv88e6390_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, @@ -3981,6 +4002,7 @@ .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, .port_set_speed = mv88e6185_port_set_speed, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_set_ether_type = mv88e6351_port_set_ether_type, @@ -4003,6 +4025,7 @@ .mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, + .rmu_disable = mv88e6390_g1_rmu_disable, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .avb_ops = &mv88e6352_avb_ops, @@ -4177,6 +4200,7 @@ .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6085", .num_databases = 4096, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 5, .max_vid = 4095, @@ -4199,6 +4223,7 @@ .family = MV88E6XXX_FAMILY_6095, .name = "Marvell 88E6095/88E6095F", .num_databases = 256, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 0, .max_vid = 4095, @@ -4219,6 +4244,7 @@ .family = MV88E6XXX_FAMILY_6097, .name = "Marvell 88E6097/88E6097F", .num_databases = 4096, + .num_macs = 8192, .num_ports = 11, .num_internal_phys = 8, .max_vid = 4095, @@ -4241,6 +4267,7 @@ .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6123", .num_databases = 4096, + .num_macs = 1024, .num_ports = 3, .num_internal_phys = 5, .max_vid = 4095, @@ -4263,6 +4290,7 @@ .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6131", .num_databases = 256, + .num_macs = 8192, .num_ports = 8, .num_internal_phys = 0, .max_vid = 4095, @@ -4282,7 +4310,8 @@ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6141", - .num_databases = 4096, + .num_databases = 256, + .num_macs = 2048, .num_ports = 6, .num_internal_phys = 5, .num_gpio = 11, @@ -4306,6 +4335,7 @@ .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6161", .num_databases = 4096, + .num_macs = 1024, .num_ports = 6, .num_internal_phys = 5, .max_vid = 4095, @@ -4329,6 +4359,7 @@ .family = MV88E6XXX_FAMILY_6165, .name = "Marvell 88E6165", .num_databases = 4096, + .num_macs = 8192, .num_ports = 6, .num_internal_phys = 0, .max_vid = 4095, @@ -4352,6 +4383,7 @@ .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6171", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4374,6 +4406,7 @@ .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6172", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4397,6 +4430,7 @@ .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6175", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4419,6 +4453,7 @@ .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6176", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4442,6 +4477,7 @@ .family = MV88E6XXX_FAMILY_6185, .name = "Marvell 88E6185", .num_databases = 256, + .num_macs = 8192, .num_ports = 10, .num_internal_phys = 0, .max_vid = 4095, @@ -4462,6 +4498,7 @@ .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4485,6 +4522,7 @@ .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6190X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4508,6 +4546,7 @@ .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6191", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .max_vid = 8191, @@ -4558,6 +4597,7 @@ .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6240", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4628,6 +4668,7 @@ .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6320", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4652,6 +4693,7 @@ .family = MV88E6XXX_FAMILY_6320, .name = "Marvell 88E6321", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4674,7 +4716,8 @@ .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341, .family = MV88E6XXX_FAMILY_6341, .name = "Marvell 88E6341", - .num_databases = 4096, + .num_databases = 256, + .num_macs = 2048, .num_internal_phys = 5, .num_ports = 6, .num_gpio = 11, @@ -4699,6 +4742,7 @@ .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6350", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4721,6 +4765,7 @@ .family = MV88E6XXX_FAMILY_6351, .name = "Marvell 88E6351", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .max_vid = 4095, @@ -4743,6 +4788,7 @@ .family = MV88E6XXX_FAMILY_6352, .name = "Marvell 88E6352", .num_databases = 4096, + .num_macs = 8192, .num_ports = 7, .num_internal_phys = 5, .num_gpio = 15, @@ -4766,6 +4812,7 @@ .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -4789,6 +4836,7 @@ .family = MV88E6XXX_FAMILY_6390, .name = "Marvell 88E6390X", .num_databases = 4096, + .num_macs = 16384, .num_ports = 11, /* 10 + Z80 */ .num_internal_phys = 9, .num_gpio = 16, @@ -5083,7 +5131,7 @@ goto out; } if (chip->reset) - usleep_range(1000, 2000); + usleep_range(10000, 20000); err = mv88e6xxx_detect(chip); if (err) --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/chip.h +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/chip.h @@ -94,6 +94,7 @@ u16 prod_num; const char *name; unsigned int num_databases; + unsigned int num_macs; unsigned int num_ports; unsigned int num_internal_phys; unsigned int num_gpio; @@ -609,6 +610,11 @@ return chip->info->num_databases; } +static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip) +{ + return chip->info->num_macs; +} + static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip) { return chip->info->num_ports; --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global1.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global1.c @@ -332,6 +332,11 @@ { u16 ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST; + /* Use the default high priority for management frames sent to + * the CPU. + */ + port |= MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI; + return mv88e6390_g1_monitor_write(chip, ptr, port); } --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global1.h +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global1.h @@ -210,6 +210,7 @@ #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST 0x2000 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST 0x2100 #define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST 0x3000 +#define MV88E6390_G1_MONITOR_MGMT_CTL_PTR_CPU_DEST_MGMTPRI 0x00e0 #define MV88E6390_G1_MONITOR_MGMT_CTL_DATA_MASK 0x00ff /* Offset 0x1C: Global Control 2 */ @@ -338,5 +339,6 @@ int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip); int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip); void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip); +int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid); #endif /* _MV88E6XXX_GLOBAL1_H */ --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global1_atu.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global1_atu.c @@ -12,6 +12,7 @@ #include "chip.h" #include "global1.h" +#include "trace.h" /* Offset 0x01: ATU FID Register */ @@ -82,6 +83,19 @@ return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0); } +static int mv88e6xxx_g1_read_atu_violation(struct mv88e6xxx_chip *chip) +{ + int err; + + err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_OP, + MV88E6XXX_G1_ATU_OP_BUSY | + MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); + if (err) + return err; + + return mv88e6xxx_g1_atu_op_wait(chip); +} + static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op) { u16 val; @@ -122,6 +136,46 @@ return mv88e6xxx_g1_atu_op_wait(chip); } +int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid) +{ + return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB); +} + +static int mv88e6xxx_g1_atu_fid_read(struct mv88e6xxx_chip *chip, u16 *fid) +{ + u16 val = 0, upper = 0, op = 0; + int err = -EOPNOTSUPP; + + if (mv88e6xxx_num_databases(chip) > 256) { + err = mv88e6xxx_g1_read(chip, MV88E6352_G1_ATU_FID, &val); + val &= 0xfff; + if (err) + return err; + } else { + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &op); + if (err) + return err; + if (mv88e6xxx_num_databases(chip) > 64) { + /* ATU DBNum[7:4] are located in ATU Control 15:12 */ + err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL, + &upper); + if (err) + return err; + + upper = (upper >> 8) & 0x00f0; + } else if (mv88e6xxx_num_databases(chip) > 16) { + /* ATU DBNum[5:4] are located in ATU Operation 9:8 */ + upper = (op >> 4) & 0x30; + } + + /* ATU DBNum[3:0] are located in ATU Operation 3:0 */ + val = (op & 0xf) | upper; + } + *fid = val; + + return err; +} + /* Offset 0x0C: ATU Data Register */ static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip, @@ -316,14 +370,12 @@ { struct mv88e6xxx_chip *chip = dev_id; struct mv88e6xxx_atu_entry entry; - int spid; - int err; - u16 val; + int err, spid; + u16 val, fid; mv88e6xxx_reg_lock(chip); - err = mv88e6xxx_g1_atu_op(chip, 0, - MV88E6XXX_G1_ATU_OP_GET_CLR_VIOLATION); + err = mv88e6xxx_g1_read_atu_violation(chip); if (err) goto out; @@ -331,6 +383,10 @@ if (err) goto out; + err = mv88e6xxx_g1_atu_fid_read(chip, &fid); + if (err) + goto out; + err = mv88e6xxx_g1_atu_data_read(chip, &entry); if (err) goto out; @@ -348,24 +404,25 @@ } if (val & MV88E6XXX_G1_ATU_OP_MEMBER_VIOLATION) { - dev_err_ratelimited(chip->dev, - "ATU member violation for %pM portvec %x spid %d\n", - entry.mac, entry.portvec, spid); + trace_mv88e6xxx_atu_member_violation(chip->dev, spid, + entry.portvec, entry.mac, + fid); chip->ports[spid].atu_member_violation++; } if (val & MV88E6XXX_G1_ATU_OP_MISS_VIOLATION) { - dev_err_ratelimited(chip->dev, - "ATU miss violation for %pM portvec %x spid %d\n", - entry.mac, entry.portvec, spid); + trace_mv88e6xxx_atu_miss_violation(chip->dev, spid, + entry.portvec, entry.mac, + fid); chip->ports[spid].atu_miss_violation++; } if (val & MV88E6XXX_G1_ATU_OP_FULL_VIOLATION) { - dev_err_ratelimited(chip->dev, - "ATU full violation for %pM portvec %x spid %d\n", - entry.mac, entry.portvec, spid); - chip->ports[spid].atu_full_violation++; + trace_mv88e6xxx_atu_full_violation(chip->dev, spid, + entry.portvec, entry.mac, + fid); + if (spid < ARRAY_SIZE(chip->ports)) + chip->ports[spid].atu_full_violation++; } mv88e6xxx_reg_unlock(chip); --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global1_vtu.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global1_vtu.c @@ -125,11 +125,9 @@ * Offset 0x08: VTU/STU Data Register 2 * Offset 0x09: VTU/STU Data Register 3 */ - -static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip, - struct mv88e6xxx_vtu_entry *entry) +static int mv88e6185_g1_vtu_stu_data_read(struct mv88e6xxx_chip *chip, + u16 *regs) { - u16 regs[3]; int i; /* Read all 3 VTU/STU Data registers */ @@ -142,12 +140,45 @@ return err; } - /* Extract MemberTag and PortState data */ + return 0; +} + +static int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip, + struct mv88e6xxx_vtu_entry *entry) +{ + u16 regs[3]; + int err; + int i; + + err = mv88e6185_g1_vtu_stu_data_read(chip, regs); + if (err) + return err; + + /* Extract MemberTag data */ for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { unsigned int member_offset = (i % 4) * 4; - unsigned int state_offset = member_offset + 2; entry->member[i] = (regs[i / 4] >> member_offset) & 0x3; + } + + return 0; +} + +static int mv88e6185_g1_stu_data_read(struct mv88e6xxx_chip *chip, + struct mv88e6xxx_vtu_entry *entry) +{ + u16 regs[3]; + int err; + int i; + + err = mv88e6185_g1_vtu_stu_data_read(chip, regs); + if (err) + return err; + + /* Extract PortState data */ + for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { + unsigned int state_offset = (i % 4) * 4 + 2; + entry->state[i] = (regs[i / 4] >> state_offset) & 0x3; } @@ -320,6 +351,10 @@ if (err) return err; + err = mv88e6185_g1_stu_data_read(chip, entry); + if (err) + return err; + /* VTU DBNum[3:0] are located in VTU Operation 3:0 * VTU DBNum[5:4] are located in VTU Operation 9:8 */ @@ -349,6 +384,10 @@ if (err) return err; + err = mv88e6185_g1_stu_data_read(chip, entry); + if (err) + return err; + /* VTU DBNum[3:0] are located in VTU Operation 3:0 * VTU DBNum[7:4] are located in VTU Operation 11:8 */ @@ -374,16 +413,20 @@ return err; if (entry->valid) { - /* Fetch (and mask) VLAN PortState data from the STU */ - err = mv88e6xxx_g1_vtu_stu_get(chip, entry); + err = mv88e6185_g1_vtu_data_read(chip, entry); if (err) return err; - err = mv88e6185_g1_vtu_data_read(chip, entry); + err = mv88e6xxx_g1_vtu_fid_read(chip, entry); if (err) return err; - err = mv88e6xxx_g1_vtu_fid_read(chip, entry); + /* Fetch VLAN PortState data from the STU */ + err = mv88e6xxx_g1_vtu_stu_get(chip, entry); + if (err) + return err; + + err = mv88e6185_g1_stu_data_read(chip, entry); if (err) return err; } --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global2.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global2.c @@ -280,6 +280,19 @@ return err; } +/* Offset 0x0E: ATU Statistics */ + +int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin) +{ + return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS, + kind | bin); +} + +int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats) +{ + return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats); +} + /* Offset 0x0F: Priority Override Table */ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer, @@ -310,7 +323,7 @@ * Offset 0x15: EEPROM Addr (for 8-bit data access) */ -static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) +int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) { int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); int err; @@ -1083,6 +1096,13 @@ { int err, irq, virq; + chip->g2_irq.masked = ~0; + mv88e6xxx_reg_lock(chip); + err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked); + mv88e6xxx_reg_unlock(chip); + if (err) + return err; + chip->g2_irq.domain = irq_domain_add_simple( chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip); if (!chip->g2_irq.domain) @@ -1092,7 +1112,6 @@ irq_create_mapping(chip->g2_irq.domain, irq); chip->g2_irq.chip = mv88e6xxx_g2_irq_chip; - chip->g2_irq.masked = ~0; chip->device_irq = irq_find_mapping(chip->g1_irq.domain, MV88E6XXX_G1_STS_IRQ_DEVICE); --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/global2.h +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/global2.h @@ -113,7 +113,16 @@ #define MV88E6XXX_G2_SWITCH_MAC_DATA_MASK 0x00ff /* Offset 0x0E: ATU Stats Register */ -#define MV88E6XXX_G2_ATU_STATS 0x0e +#define MV88E6XXX_G2_ATU_STATS 0x0e +#define MV88E6XXX_G2_ATU_STATS_BIN_0 (0x0 << 14) +#define MV88E6XXX_G2_ATU_STATS_BIN_1 (0x1 << 14) +#define MV88E6XXX_G2_ATU_STATS_BIN_2 (0x2 << 14) +#define MV88E6XXX_G2_ATU_STATS_BIN_3 (0x3 << 14) +#define MV88E6XXX_G2_ATU_STATS_MODE_ALL (0x0 << 12) +#define MV88E6XXX_G2_ATU_STATS_MODE_ALL_DYNAMIC (0x1 << 12) +#define MV88E6XXX_G2_ATU_STATS_MODE_FID_ALL (0x2 << 12) +#define MV88E6XXX_G2_ATU_STATS_MODE_FID_ALL_DYNAMIC (0x3 << 12) +#define MV88E6XXX_G2_ATU_STATS_MASK 0x0fff /* Offset 0x0F: Priority Override Table */ #define MV88E6XXX_G2_PRIO_OVERRIDE 0x0f @@ -340,6 +349,7 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, int port); +int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip); extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; @@ -353,6 +363,8 @@ int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip, bool external); +int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin); +int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats); #else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */ @@ -514,6 +526,18 @@ { return -EOPNOTSUPP; } + +static inline int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, + u16 kind, u16 bin) +{ + return -EOPNOTSUPP; +} + +static inline int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, + u16 *stats) +{ + return -EOPNOTSUPP; +} #endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */ --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/port.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/port.c @@ -393,7 +393,7 @@ } static int mv88e6xxx_port_set_cmode(struct mv88e6xxx_chip *chip, int port, - phy_interface_t mode) + phy_interface_t mode, bool force) { u8 lane; u16 cmode; @@ -427,8 +427,8 @@ cmode = 0; } - /* cmode doesn't change, nothing to do for us */ - if (cmode == chip->ports[port].cmode) + /* cmode doesn't change, nothing to do for us unless forced */ + if (cmode == chip->ports[port].cmode && !force) return 0; lane = mv88e6xxx_serdes_get_lane(chip, port); @@ -484,7 +484,7 @@ if (port != 9 && port != 10) return -EOPNOTSUPP; - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); } int mv88e6390_port_set_cmode(struct mv88e6xxx_chip *chip, int port, @@ -504,7 +504,7 @@ break; } - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, false); } static int mv88e6341_port_set_cmode_writable(struct mv88e6xxx_chip *chip, @@ -555,7 +555,7 @@ if (err) return err; - return mv88e6xxx_port_set_cmode(chip, port, mode); + return mv88e6xxx_port_set_cmode(chip, port, mode, true); } int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode) --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/trace.c +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/trace.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Copyright 2022 NXP + */ + +#define CREATE_TRACE_POINTS +#include "trace.h" --- linux-oracle-5.4.0.orig/drivers/net/dsa/mv88e6xxx/trace.h +++ linux-oracle-5.4.0/drivers/net/dsa/mv88e6xxx/trace.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* Copyright 2022 NXP + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mv88e6xxx + +#if !defined(_MV88E6XXX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _MV88E6XXX_TRACE_H + +#include +#include +#include + +DECLARE_EVENT_CLASS(mv88e6xxx_atu_violation, + + TP_PROTO(const struct device *dev, int spid, u16 portvec, + const unsigned char *addr, u16 fid), + + TP_ARGS(dev, spid, portvec, addr, fid), + + TP_STRUCT__entry( + __string(name, dev_name(dev)) + __field(int, spid) + __field(u16, portvec) + __array(unsigned char, addr, ETH_ALEN) + __field(u16, fid) + ), + + TP_fast_assign( + __assign_str(name, dev_name(dev)); + __entry->spid = spid; + __entry->portvec = portvec; + memcpy(__entry->addr, addr, ETH_ALEN); + __entry->fid = fid; + ), + + TP_printk("dev %s spid %d portvec 0x%x addr %pM fid %u", + __get_str(name), __entry->spid, __entry->portvec, + __entry->addr, __entry->fid) +); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_member_violation, + TP_PROTO(const struct device *dev, int spid, u16 portvec, + const unsigned char *addr, u16 fid), + TP_ARGS(dev, spid, portvec, addr, fid)); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_miss_violation, + TP_PROTO(const struct device *dev, int spid, u16 portvec, + const unsigned char *addr, u16 fid), + TP_ARGS(dev, spid, portvec, addr, fid)); + +DEFINE_EVENT(mv88e6xxx_atu_violation, mv88e6xxx_atu_full_violation, + TP_PROTO(const struct device *dev, int spid, u16 portvec, + const unsigned char *addr, u16 fid), + TP_ARGS(dev, spid, portvec, addr, fid)); + +#endif /* _MV88E6XXX_TRACE_H */ + +/* We don't want to use include/trace/events */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE trace +/* This part must be outside protection */ +#include --- linux-oracle-5.4.0.orig/drivers/net/dsa/realtek-smi-core.h +++ linux-oracle-5.4.0/drivers/net/dsa/realtek-smi-core.h @@ -25,6 +25,9 @@ const char *name; }; +/** + * struct rtl8366_vlan_mc - Virtual LAN member configuration + */ struct rtl8366_vlan_mc { u16 vid; u16 untag; @@ -119,7 +122,6 @@ int rtl8366_mc_is_used(struct realtek_smi *smi, int mc_index, int *used); int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, u32 untag, u32 fid); -int rtl8366_get_pvid(struct realtek_smi *smi, int port, int *val); int rtl8366_set_pvid(struct realtek_smi *smi, unsigned int port, unsigned int vid); int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable); --- linux-oracle-5.4.0.orig/drivers/net/dsa/rtl8366.c +++ linux-oracle-5.4.0/drivers/net/dsa/rtl8366.c @@ -36,113 +36,66 @@ } EXPORT_SYMBOL_GPL(rtl8366_mc_is_used); -int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, - u32 untag, u32 fid) +/** + * rtl8366_obtain_mc() - retrieve or allocate a VLAN member configuration + * @smi: the Realtek SMI device instance + * @vid: the VLAN ID to look up or allocate + * @vlanmc: the pointer will be assigned to a pointer to a valid member config + * if successful + * @return: index of a new member config or negative error number + */ +static int rtl8366_obtain_mc(struct realtek_smi *smi, int vid, + struct rtl8366_vlan_mc *vlanmc) { struct rtl8366_vlan_4k vlan4k; int ret; int i; - /* Update the 4K table */ - ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k); - if (ret) - return ret; - - vlan4k.member = member; - vlan4k.untag = untag; - vlan4k.fid = fid; - ret = smi->ops->set_vlan_4k(smi, &vlan4k); - if (ret) - return ret; - - /* Try to find an existing MC entry for this VID */ + /* Try to find an existing member config entry for this VID */ for (i = 0; i < smi->num_vlan_mc; i++) { - struct rtl8366_vlan_mc vlanmc; - - ret = smi->ops->get_vlan_mc(smi, i, &vlanmc); - if (ret) + ret = smi->ops->get_vlan_mc(smi, i, vlanmc); + if (ret) { + dev_err(smi->dev, "error searching for VLAN MC %d for VID %d\n", + i, vid); return ret; - - if (vid == vlanmc.vid) { - /* update the MC entry */ - vlanmc.member = member; - vlanmc.untag = untag; - vlanmc.fid = fid; - - ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); - break; } - } - - return ret; -} -EXPORT_SYMBOL_GPL(rtl8366_set_vlan); -int rtl8366_get_pvid(struct realtek_smi *smi, int port, int *val) -{ - struct rtl8366_vlan_mc vlanmc; - int ret; - int index; - - ret = smi->ops->get_mc_index(smi, port, &index); - if (ret) - return ret; - - ret = smi->ops->get_vlan_mc(smi, index, &vlanmc); - if (ret) - return ret; - - *val = vlanmc.vid; - return 0; -} -EXPORT_SYMBOL_GPL(rtl8366_get_pvid); - -int rtl8366_set_pvid(struct realtek_smi *smi, unsigned int port, - unsigned int vid) -{ - struct rtl8366_vlan_mc vlanmc; - struct rtl8366_vlan_4k vlan4k; - int ret; - int i; - - /* Try to find an existing MC entry for this VID */ - for (i = 0; i < smi->num_vlan_mc; i++) { - ret = smi->ops->get_vlan_mc(smi, i, &vlanmc); - if (ret) - return ret; - - if (vid == vlanmc.vid) { - ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); - if (ret) - return ret; - - ret = smi->ops->set_mc_index(smi, port, i); - return ret; - } + if (vid == vlanmc->vid) + return i; } /* We have no MC entry for this VID, try to find an empty one */ for (i = 0; i < smi->num_vlan_mc; i++) { - ret = smi->ops->get_vlan_mc(smi, i, &vlanmc); - if (ret) + ret = smi->ops->get_vlan_mc(smi, i, vlanmc); + if (ret) { + dev_err(smi->dev, "error searching for VLAN MC %d for VID %d\n", + i, vid); return ret; + } - if (vlanmc.vid == 0 && vlanmc.member == 0) { + if (vlanmc->vid == 0 && vlanmc->member == 0) { /* Update the entry from the 4K table */ ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k); - if (ret) + if (ret) { + dev_err(smi->dev, "error looking for 4K VLAN MC %d for VID %d\n", + i, vid); return ret; + } - vlanmc.vid = vid; - vlanmc.member = vlan4k.member; - vlanmc.untag = vlan4k.untag; - vlanmc.fid = vlan4k.fid; - ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); - if (ret) + vlanmc->vid = vid; + vlanmc->member = vlan4k.member; + vlanmc->untag = vlan4k.untag; + vlanmc->fid = vlan4k.fid; + ret = smi->ops->set_vlan_mc(smi, i, vlanmc); + if (ret) { + dev_err(smi->dev, "unable to set/update VLAN MC %d for VID %d\n", + i, vid); return ret; + } - ret = smi->ops->set_mc_index(smi, port, i); - return ret; + dev_dbg(smi->dev, "created new MC at index %d for VID %d\n", + i, vid); + return i; } } @@ -160,24 +113,110 @@ if (ret) return ret; - vlanmc.vid = vid; - vlanmc.member = vlan4k.member; - vlanmc.untag = vlan4k.untag; - vlanmc.fid = vlan4k.fid; - ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); - if (ret) + vlanmc->vid = vid; + vlanmc->member = vlan4k.member; + vlanmc->untag = vlan4k.untag; + vlanmc->fid = vlan4k.fid; + ret = smi->ops->set_vlan_mc(smi, i, vlanmc); + if (ret) { + dev_err(smi->dev, "unable to set/update VLAN MC %d for VID %d\n", + i, vid); return ret; - - ret = smi->ops->set_mc_index(smi, port, i); - return ret; + } + dev_dbg(smi->dev, "recycled MC at index %i for VID %d\n", + i, vid); + return i; } } - dev_err(smi->dev, - "all VLAN member configurations are in use\n"); - + dev_err(smi->dev, "all VLAN member configurations are in use\n"); return -ENOSPC; } + +int rtl8366_set_vlan(struct realtek_smi *smi, int vid, u32 member, + u32 untag, u32 fid) +{ + struct rtl8366_vlan_mc vlanmc; + struct rtl8366_vlan_4k vlan4k; + int mc; + int ret; + + if (!smi->ops->is_vlan_valid(smi, vid)) + return -EINVAL; + + dev_dbg(smi->dev, + "setting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n", + vid, member, untag); + + /* Update the 4K table */ + ret = smi->ops->get_vlan_4k(smi, vid, &vlan4k); + if (ret) + return ret; + + vlan4k.member |= member; + vlan4k.untag |= untag; + vlan4k.fid = fid; + ret = smi->ops->set_vlan_4k(smi, &vlan4k); + if (ret) + return ret; + + dev_dbg(smi->dev, + "resulting VLAN%d 4k members: 0x%02x, untagged: 0x%02x\n", + vid, vlan4k.member, vlan4k.untag); + + /* Find or allocate a member config for this VID */ + ret = rtl8366_obtain_mc(smi, vid, &vlanmc); + if (ret < 0) + return ret; + mc = ret; + + /* Update the MC entry */ + vlanmc.member |= member; + vlanmc.untag |= untag; + vlanmc.fid = fid; + + /* Commit updates to the MC entry */ + ret = smi->ops->set_vlan_mc(smi, mc, &vlanmc); + if (ret) + dev_err(smi->dev, "failed to commit changes to VLAN MC index %d for VID %d\n", + mc, vid); + else + dev_dbg(smi->dev, + "resulting VLAN%d MC members: 0x%02x, untagged: 0x%02x\n", + vid, vlanmc.member, vlanmc.untag); + + return ret; +} +EXPORT_SYMBOL_GPL(rtl8366_set_vlan); + +int rtl8366_set_pvid(struct realtek_smi *smi, unsigned int port, + unsigned int vid) +{ + struct rtl8366_vlan_mc vlanmc; + int mc; + int ret; + + if (!smi->ops->is_vlan_valid(smi, vid)) + return -EINVAL; + + /* Find or allocate a member config for this VID */ + ret = rtl8366_obtain_mc(smi, vid, &vlanmc); + if (ret < 0) + return ret; + mc = ret; + + ret = smi->ops->set_mc_index(smi, port, mc); + if (ret) { + dev_err(smi->dev, "set PVID: failed to set MC index %d for port %d\n", + mc, port); + return ret; + } + + dev_dbg(smi->dev, "set PVID: the PVID for port %d set to %d using existing MC index %d\n", + port, vid, mc); + + return 0; +} EXPORT_SYMBOL_GPL(rtl8366_set_pvid); int rtl8366_enable_vlan4k(struct realtek_smi *smi, bool enable) @@ -376,7 +415,8 @@ if (!smi->ops->is_vlan_valid(smi, vid)) return; - dev_info(smi->dev, "add VLAN on port %d, %s, %s\n", + dev_info(smi->dev, "add VLAN %d on port %d, %s, %s\n", + vlan->vid_begin, port, untagged ? "untagged" : "tagged", pvid ? " PVID" : "no PVID"); @@ -384,36 +424,31 @@ if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) dev_err(smi->dev, "port is DSA or CPU port\n"); - for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { - int pvid_val = 0; - - dev_info(smi->dev, "add VLAN %04x\n", vid); + for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { member |= BIT(port); if (untagged) untag |= BIT(port); - /* To ensure that we have a valid MC entry for this VLAN, - * initialize the port VLAN ID here. - */ - ret = rtl8366_get_pvid(smi, port, &pvid_val); - if (ret < 0) { - dev_err(smi->dev, "could not lookup PVID for port %d\n", - port); - return; - } - if (pvid_val == 0) { - ret = rtl8366_set_pvid(smi, port, vid); - if (ret < 0) - return; - } - } + ret = rtl8366_set_vlan(smi, vid, member, untag, 0); + if (ret) + dev_err(smi->dev, + "failed to set up VLAN %04x", + vid); - ret = rtl8366_set_vlan(smi, port, member, untag, 0); - if (ret) - dev_err(smi->dev, - "failed to set up VLAN %04x", - vid); + if (!pvid) + continue; + + ret = rtl8366_set_pvid(smi, port, vid); + if (ret) + dev_err(smi->dev, + "failed to set PVID on port %d to VLAN %04x", + port, vid); + + if (!ret) + dev_dbg(smi->dev, "VLAN add: added VLAN %d with PVID on port %d\n", + vid, port); + } } EXPORT_SYMBOL_GPL(rtl8366_vlan_add); @@ -439,13 +474,19 @@ return ret; if (vid == vlanmc.vid) { - /* clear VLAN member configurations */ - vlanmc.vid = 0; - vlanmc.priority = 0; - vlanmc.member = 0; - vlanmc.untag = 0; - vlanmc.fid = 0; - + /* Remove this port from the VLAN */ + vlanmc.member &= ~BIT(port); + vlanmc.untag &= ~BIT(port); + /* + * If no ports are members of this VLAN + * anymore then clear the whole member + * config so it can be reused. + */ + if (!vlanmc.member && vlanmc.untag) { + vlanmc.vid = 0; + vlanmc.priority = 0; + vlanmc.fid = 0; + } ret = smi->ops->set_vlan_mc(smi, i, &vlanmc); if (ret) { dev_err(smi->dev, --- linux-oracle-5.4.0.orig/drivers/net/dsa/rtl8366rb.c +++ linux-oracle-5.4.0/drivers/net/dsa/rtl8366rb.c @@ -1264,12 +1264,12 @@ static bool rtl8366rb_is_vlan_valid(struct realtek_smi *smi, unsigned int vlan) { - unsigned int max = RTL8366RB_NUM_VLANS; + unsigned int max = RTL8366RB_NUM_VLANS - 1; if (smi->vlan4k_enabled) max = RTL8366RB_NUM_VIDS - 1; - if (vlan == 0 || vlan >= max) + if (vlan == 0 || vlan > max) return false; return true; --- linux-oracle-5.4.0.orig/drivers/net/dsa/sja1105/sja1105_main.c +++ linux-oracle-5.4.0/drivers/net/dsa/sja1105/sja1105_main.c @@ -178,6 +178,7 @@ default: dev_err(dev, "Unsupported PHY mode %s!\n", phy_modes(ports[i].phy_mode)); + return -EINVAL; } mii->phy_mac[i] = ports[i].role; @@ -594,15 +595,15 @@ int i; for (i = 0; i < SJA1105_NUM_PORTS; i++) { - if (ports->role == XMII_MAC) + if (ports[i].role == XMII_MAC) continue; - if (ports->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID || - ports->phy_mode == PHY_INTERFACE_MODE_RGMII_ID) + if (ports[i].phy_mode == PHY_INTERFACE_MODE_RGMII_RXID || + ports[i].phy_mode == PHY_INTERFACE_MODE_RGMII_ID) priv->rgmii_rx_delay[i] = true; - if (ports->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID || - ports->phy_mode == PHY_INTERFACE_MODE_RGMII_ID) + if (ports[i].phy_mode == PHY_INTERFACE_MODE_RGMII_TXID || + ports[i].phy_mode == PHY_INTERFACE_MODE_RGMII_ID) priv->rgmii_tx_delay[i] = true; if ((priv->rgmii_rx_delay[i] || priv->rgmii_tx_delay[i]) && @@ -619,7 +620,7 @@ struct device *dev = &priv->spidev->dev; struct device_node *child; - for_each_child_of_node(ports_node, child) { + for_each_available_child_of_node(ports_node, child) { struct device_node *phy_node; int phy_mode; u32 index; @@ -991,10 +992,11 @@ int sja1105et_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { - struct sja1105_l2_lookup_entry l2_lookup = {0}; + struct sja1105_l2_lookup_entry l2_lookup = {0}, tmp; struct sja1105_private *priv = ds->priv; struct device *dev = ds->dev; int last_unused = -1; + int start, end, i; int bin, way, rc; bin = sja1105et_fdb_hash(priv, addr, vid); @@ -1006,7 +1008,7 @@ * mask? If yes, we need to do nothing. If not, we need * to rewrite the entry by adding this port to it. */ - if (l2_lookup.destports & BIT(port)) + if ((l2_lookup.destports & BIT(port)) && l2_lookup.lockeds) return 0; l2_lookup.destports |= BIT(port); } else { @@ -1037,6 +1039,7 @@ index, NULL, false); } } + l2_lookup.lockeds = true; l2_lookup.index = sja1105et_fdb_index(bin, way); rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, @@ -1045,6 +1048,29 @@ if (rc < 0) return rc; + /* Invalidate a dynamically learned entry if that exists */ + start = sja1105et_fdb_index(bin, 0); + end = sja1105et_fdb_index(bin, way); + + for (i = start; i < end; i++) { + rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, + i, &tmp); + if (rc == -ENOENT) + continue; + if (rc) + return rc; + + if (tmp.macaddr != ether_addr_to_u64(addr) || tmp.vlanid != vid) + continue; + + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, + i, NULL, false); + if (rc) + return rc; + + break; + } + return sja1105_static_fdb_change(priv, port, &l2_lookup, true); } @@ -1086,7 +1112,7 @@ int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { - struct sja1105_l2_lookup_entry l2_lookup = {0}; + struct sja1105_l2_lookup_entry l2_lookup = {0}, tmp; struct sja1105_private *priv = ds->priv; int rc, i; @@ -1107,10 +1133,10 @@ rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, SJA1105_SEARCH, &l2_lookup); if (rc == 0) { - /* Found and this port is already in the entry's + /* Found a static entry and this port is already in the entry's * port mask => job done */ - if (l2_lookup.destports & BIT(port)) + if ((l2_lookup.destports & BIT(port)) && l2_lookup.lockeds) return 0; /* l2_lookup.index is populated by the switch in case it * found something. @@ -1133,16 +1159,46 @@ dev_err(ds->dev, "FDB is full, cannot add entry.\n"); return -EINVAL; } - l2_lookup.lockeds = true; l2_lookup.index = i; skip_finding_an_index: + l2_lookup.lockeds = true; + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, l2_lookup.index, &l2_lookup, true); if (rc < 0) return rc; + /* The switch learns dynamic entries and looks up the FDB left to + * right. It is possible that our addition was concurrent with the + * dynamic learning of the same address, so now that the static entry + * has been installed, we are certain that address learning for this + * particular address has been turned off, so the dynamic entry either + * is in the FDB at an index smaller than the static one, or isn't (it + * can also be at a larger index, but in that case it is inactive + * because the static FDB entry will match first, and the dynamic one + * will eventually age out). Search for a dynamically learned address + * prior to our static one and invalidate it. + */ + tmp = l2_lookup; + + rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, + SJA1105_SEARCH, &tmp); + if (rc < 0) { + dev_err(ds->dev, + "port %d failed to read back entry for %pM vid %d: %pe\n", + port, addr, vid, ERR_PTR(rc)); + return rc; + } + + if (tmp.index < l2_lookup.index) { + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, + tmp.index, NULL, false); + if (rc < 0) + return rc; + } + return sja1105_static_fdb_change(priv, port, &l2_lookup, true); } @@ -1256,7 +1312,9 @@ /* We need to hide the dsa_8021q VLANs from the user. */ if (!dsa_port_is_vlan_filtering(&ds->ports[port])) l2_lookup.vlanid = 0; - cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); + rc = cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); + if (rc) + return rc; } return 0; } @@ -1389,6 +1447,8 @@ int speed_mbps[SJA1105_NUM_PORTS]; int rc, i; + mutex_lock(&priv->mgmt_lock); + mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; /* Back up the dynamic link speed changed by sja1105_adjust_port_config @@ -1420,6 +1480,8 @@ goto out; } out: + mutex_unlock(&priv->mgmt_lock); + return rc; } @@ -1556,8 +1618,8 @@ if (enabled) { /* Enable VLAN filtering. */ - tpid = ETH_P_8021AD; - tpid2 = ETH_P_8021Q; + tpid = ETH_P_8021Q; + tpid2 = ETH_P_8021AD; } else { /* Disable VLAN filtering. */ tpid = ETH_P_SJA1105; @@ -1566,9 +1628,9 @@ table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; general_params = table->entries; - /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ - general_params->tpid = tpid; /* EtherType used to identify inner tagged (C-tag) VLAN traffic */ + general_params->tpid = tpid; + /* EtherType used to identify outer tagged (S-tag) VLAN traffic */ general_params->tpid2 = tpid2; /* When VLAN filtering is on, we need to at least be able to * decode management traffic through the "backup plan". --- linux-oracle-5.4.0.orig/drivers/net/dsa/sja1105/sja1105_static_config.c +++ linux-oracle-5.4.0/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -142,6 +142,9 @@ return size; } +/* TPID and TPID2 are intentionally reversed so that semantic + * compatibility with E/T is kept. + */ static size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) @@ -166,9 +169,9 @@ sja1105_packing(buf, &entry->mirr_port, 141, 139, size, op); sja1105_packing(buf, &entry->vlmarker, 138, 107, size, op); sja1105_packing(buf, &entry->vlmask, 106, 75, size, op); - sja1105_packing(buf, &entry->tpid, 74, 59, size, op); + sja1105_packing(buf, &entry->tpid2, 74, 59, size, op); sja1105_packing(buf, &entry->ignore2stf, 58, 58, size, op); - sja1105_packing(buf, &entry->tpid2, 57, 42, size, op); + sja1105_packing(buf, &entry->tpid, 57, 42, size, op); sja1105_packing(buf, &entry->queue_ts, 41, 41, size, op); sja1105_packing(buf, &entry->egrmirrvid, 40, 29, size, op); sja1105_packing(buf, &entry->egrmirrpcp, 28, 26, size, op); --- linux-oracle-5.4.0.orig/drivers/net/dsa/vitesse-vsc73xx-core.c +++ linux-oracle-5.4.0/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -34,7 +34,7 @@ #define VSC73XX_BLOCK_ANALYZER 0x2 /* Only subblock 0 */ #define VSC73XX_BLOCK_MII 0x3 /* Subblocks 0 and 1 */ #define VSC73XX_BLOCK_MEMINIT 0x3 /* Only subblock 2 */ -#define VSC73XX_BLOCK_CAPTURE 0x4 /* Only subblock 2 */ +#define VSC73XX_BLOCK_CAPTURE 0x4 /* Subblocks 0-4, 6, 7 */ #define VSC73XX_BLOCK_ARBITER 0x5 /* Only subblock 0 */ #define VSC73XX_BLOCK_SYSTEM 0x7 /* Only subblock 0 */ @@ -360,13 +360,19 @@ break; case VSC73XX_BLOCK_MII: - case VSC73XX_BLOCK_CAPTURE: case VSC73XX_BLOCK_ARBITER: switch (subblock) { case 0 ... 1: return 1; } break; + case VSC73XX_BLOCK_CAPTURE: + switch (subblock) { + case 0 ... 4: + case 6 ... 7: + return 1; + } + break; } return 0; @@ -531,7 +537,7 @@ return 0; } - cmd = (phy << 21) | (regnum << 16); + cmd = (phy << 21) | (regnum << 16) | val; ret = vsc73xx_write(vsc, VSC73XX_BLOCK_MII, 0, 1, cmd); if (ret) return ret; @@ -1108,6 +1114,8 @@ vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x", vsc->chipid); + if (!vsc->gc.label) + return -ENOMEM; vsc->gc.ngpio = 4; vsc->gc.owner = THIS_MODULE; vsc->gc.parent = vsc->dev; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/3com/3c589_cs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/3com/3c589_cs.c @@ -196,6 +196,7 @@ { struct el3_private *lp; struct net_device *dev; + int ret; dev_dbg(&link->dev, "3c589_attach()\n"); @@ -219,7 +220,15 @@ dev->ethtool_ops = &netdev_ethtool_ops; - return tc589_config(link); + ret = tc589_config(link); + if (ret) + goto err_free_netdev; + + return 0; + +err_free_netdev: + free_netdev(dev); + return ret; } static void tc589_detach(struct pcmcia_device *link) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/8390/mcf8390.c +++ linux-oracle-5.4.0/drivers/net/ethernet/8390/mcf8390.c @@ -406,12 +406,12 @@ static int mcf8390_probe(struct platform_device *pdev) { struct net_device *dev; - struct resource *mem, *irq; + struct resource *mem; resource_size_t msize; - int ret; + int ret, irq; - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq == NULL) { + irq = platform_get_irq(pdev, 0); + if (irq < 0) { dev_err(&pdev->dev, "no IRQ specified?\n"); return -ENXIO; } @@ -434,7 +434,7 @@ SET_NETDEV_DEV(dev, &pdev->dev); platform_set_drvdata(pdev, dev); - dev->irq = irq->start; + dev->irq = irq; dev->base_addr = mem->start; ret = mcf8390_init(dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/Kconfig @@ -100,6 +100,7 @@ config KORINA tristate "Korina (IDT RC32434) Ethernet support" depends on MIKROTIK_RB532 + select CRC32 ---help--- If you have a Mikrotik RouterBoard 500 or IDT RC32434 based system say Y. Otherwise say N. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aeroflex/greth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aeroflex/greth.c @@ -258,6 +258,7 @@ if (dma_mapping_error(greth->dev, dma_addr)) { if (netif_msg_ifup(greth)) dev_err(greth->dev, "Could not create initial DMA mapping\n"); + dev_kfree_skb(skb); goto cleanup; } greth->rx_skbuff[i] = skb; @@ -483,7 +484,7 @@ if (unlikely(skb->len > MAX_FRAME_SIZE)) { dev->stats.tx_errors++; - goto out; + goto len_error; } /* Save skb pointer. */ @@ -574,6 +575,7 @@ map_error: if (net_ratelimit()) dev_warn(greth->dev, "Could not create TX DMA mapping\n"); +len_error: dev_kfree_skb(skb); out: return err; @@ -1541,10 +1543,11 @@ mdiobus_unregister(greth->mdio); unregister_netdev(ndev); - free_netdev(ndev); of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); + free_netdev(ndev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/allwinner/sun4i-emac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -432,7 +432,7 @@ /* Hardware start transmission. * Send a packet to media from the upper layer. */ -static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct emac_board_info *db = netdev_priv(dev); unsigned long channel; @@ -440,7 +440,7 @@ channel = db->tx_fifo_stat & 3; if (channel == 3) - return 1; + return NETDEV_TX_BUSY; channel = (channel == 1 ? 1 : 0); @@ -845,13 +845,13 @@ db->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(db->clk)) { ret = PTR_ERR(db->clk); - goto out_iounmap; + goto out_dispose_mapping; } ret = clk_prepare_enable(db->clk); if (ret) { dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); - goto out_iounmap; + goto out_dispose_mapping; } ret = sunxi_sram_claim(&pdev->dev); @@ -910,6 +910,8 @@ sunxi_sram_release(&pdev->dev); out_clk_disable_unprepare: clk_disable_unprepare(db->clk); +out_dispose_mapping: + irq_dispose_mapping(ndev->irq); out_iounmap: iounmap(db->membase); out: @@ -928,6 +930,7 @@ unregister_netdev(ndev); sunxi_sram_release(&pdev->dev); clk_disable_unprepare(db->clk); + irq_dispose_mapping(ndev->irq); iounmap(db->membase); free_netdev(ndev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/altera/altera_tse_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/altera/altera_tse_main.c @@ -163,7 +163,8 @@ mdio = mdiobus_alloc(); if (mdio == NULL) { netdev_err(dev, "Error allocating MDIO bus\n"); - return -ENOMEM; + ret = -ENOMEM; + goto put_node; } mdio->name = ALTERA_TSE_RESOURCE_NAME; @@ -180,6 +181,7 @@ mdio->id); goto out_free_mdio; } + of_node_put(mdio_node); if (netif_msg_drv(priv)) netdev_info(dev, "MDIO bus %s: created\n", mdio->id); @@ -189,6 +191,8 @@ out_free_mdio: mdiobus_free(mdio); mdio = NULL; +put_node: + of_node_put(mdio_node); return ret; } @@ -1431,16 +1435,19 @@ priv->rxdescmem_busaddr = dma_res->start; } else { + ret = -ENODEV; goto err_free_netdev; } - if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) + if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) { dma_set_coherent_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask)); - else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) + } else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) { dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); - else + } else { + ret = -EIO; goto err_free_netdev; + } /* MAC address space */ ret = request_and_map(pdev, "control_port", &control_port, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_admin_defs.h @@ -1,37 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef _ENA_ADMIN_H_ #define _ENA_ADMIN_H_ +#define ENA_ADMIN_RSS_KEY_PARTS 10 enum ena_admin_aq_opcode { ENA_ADMIN_CREATE_SQ = 1, @@ -55,6 +29,7 @@ ENA_ADMIN_RESOURCE_BUSY = 7, }; +/* subcommands for the set/get feature admin commands */ enum ena_admin_aq_feature_id { ENA_ADMIN_DEVICE_ATTRIBUTES = 1, ENA_ADMIN_MAX_QUEUES_NUM = 2, @@ -63,7 +38,7 @@ ENA_ADMIN_MAX_QUEUES_EXT = 7, ENA_ADMIN_RSS_HASH_FUNCTION = 10, ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, - ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12, + ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG = 12, ENA_ADMIN_MTU = 14, ENA_ADMIN_RSS_HASH_INPUT = 18, ENA_ADMIN_INTERRUPT_MODERATION = 20, @@ -117,6 +92,8 @@ enum ena_admin_get_stats_type { ENA_ADMIN_GET_STATS_TYPE_BASIC = 0, ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1, + /* extra HW stats for specific network interface */ + ENA_ADMIN_GET_STATS_TYPE_ENI = 2, }; enum ena_admin_get_stats_scope { @@ -193,7 +170,7 @@ u16 extended_status; /* indicates to the driver which AQ entry has been consumed by the - * device and could be reused + * device and could be reused */ u16 sq_head_indx; }; @@ -238,8 +215,8 @@ */ u8 sq_caps_3; - /* associated completion queue id. This CQ must be created prior to - * SQ creation + /* associated completion queue id. This CQ must be created prior to SQ + * creation */ u16 cq_idx; @@ -378,7 +355,7 @@ u16 queue_idx; /* device id, value 0xFFFF means mine. only privileged device can get - * stats of other device + * stats of other device */ u16 device_id; }; @@ -404,12 +381,49 @@ u32 rx_drops_low; u32 rx_drops_high; + + u32 tx_drops_low; + + u32 tx_drops_high; +}; + +/* ENI Statistics Command. */ +struct ena_admin_eni_stats { + /* The number of packets shaped due to inbound aggregate BW + * allowance being exceeded + */ + u64 bw_in_allowance_exceeded; + + /* The number of packets shaped due to outbound aggregate BW + * allowance being exceeded + */ + u64 bw_out_allowance_exceeded; + + /* The number of packets shaped due to PPS allowance being exceeded */ + u64 pps_allowance_exceeded; + + /* The number of packets shaped due to connection tracking + * allowance being exceeded and leading to failure in establishment + * of new connections + */ + u64 conntrack_allowance_exceeded; + + /* The number of packets shaped due to linklocal packet rate + * allowance being exceeded + */ + u64 linklocal_allowance_exceeded; }; struct ena_admin_acq_get_stats_resp { struct ena_admin_acq_common_desc acq_common_desc; - struct ena_admin_basic_stats basic_stats; + union { + u64 raw[7]; + + struct ena_admin_basic_stats basic_stats; + + struct ena_admin_eni_stats eni_stats; + } u; }; struct ena_admin_get_set_feature_common_desc { @@ -436,7 +450,9 @@ u32 device_version; - /* bitmap of ena_admin_aq_feature_id */ + /* bitmap of ena_admin_aq_feature_id, which represents supported + * subcommands for the set/get feature admin commands. + */ u32 supported_features; u32 reserved3; @@ -487,37 +503,65 @@ ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2, }; +enum ena_admin_accel_mode_feat { + ENA_ADMIN_DISABLE_META_CACHING = 0, + ENA_ADMIN_LIMIT_TX_BURST = 1, +}; + +struct ena_admin_accel_mode_get { + /* bit field of enum ena_admin_accel_mode_feat */ + u16 supported_flags; + + /* maximum burst size between two doorbells. The size is in bytes */ + u16 max_tx_burst_size; +}; + +struct ena_admin_accel_mode_set { + /* bit field of enum ena_admin_accel_mode_feat */ + u16 enabled_flags; + + u16 reserved; +}; + +struct ena_admin_accel_mode_req { + union { + u32 raw[2]; + + struct ena_admin_accel_mode_get get; + + struct ena_admin_accel_mode_set set; + } u; +}; + struct ena_admin_feature_llq_desc { u32 max_llq_num; u32 max_llq_depth; - /* specify the header locations the device supports. bitfield of - * enum ena_admin_llq_header_location. + /* specify the header locations the device supports. bitfield of enum + * ena_admin_llq_header_location. */ u16 header_location_ctrl_supported; /* the header location the driver selected to use. */ u16 header_location_ctrl_enabled; - /* if inline header is specified - this is the size of descriptor - * list entry. If header in a separate ring is specified - this is - * the size of header ring entry. bitfield of enum - * ena_admin_llq_ring_entry_size. specify the entry sizes the device - * supports + /* if inline header is specified - this is the size of descriptor list + * entry. If header in a separate ring is specified - this is the size + * of header ring entry. bitfield of enum ena_admin_llq_ring_entry_size. + * specify the entry sizes the device supports */ u16 entry_size_ctrl_supported; /* the entry size the driver selected to use. */ u16 entry_size_ctrl_enabled; - /* valid only if inline header is specified. First entry associated - * with the packet includes descriptors and header. Rest of the - * entries occupied by descriptors. This parameter defines the max - * number of descriptors precedding the header in the first entry. - * The field is bitfield of enum - * ena_admin_llq_num_descs_before_header and specify the values the - * device supports + /* valid only if inline header is specified. First entry associated with + * the packet includes descriptors and header. Rest of the entries + * occupied by descriptors. This parameter defines the max number of + * descriptors precedding the header in the first entry. The field is + * bitfield of enum ena_admin_llq_num_descs_before_header and specify + * the values the device supports */ u16 desc_num_before_header_supported; @@ -525,17 +569,20 @@ u16 desc_num_before_header_enabled; /* valid only if inline was chosen. bitfield of enum - * ena_admin_llq_stride_ctrl + * ena_admin_llq_stride_ctrl */ u16 descriptors_stride_ctrl_supported; /* the stride control the driver selected to use */ u16 descriptors_stride_ctrl_enabled; - /* Maximum size in bytes taken by llq entries in a single tx burst. - * Set to 0 when there is no such limit. + /* reserved */ + u32 reserved1; + + /* accelerated low latency queues requirement. driver needs to + * support those requirements in order to use accelerated llq */ - u32 max_tx_burst_size; + struct ena_admin_accel_mode_req accel_mode; }; struct ena_admin_queue_ext_feature_fields { @@ -557,8 +604,8 @@ u32 max_tx_header_size; - /* Maximum Descriptors number, including meta descriptor, allowed for - * a single Tx packet + /* Maximum Descriptors number, including meta descriptor, allowed for a + * single Tx packet */ u16 max_per_packet_tx_descs; @@ -581,8 +628,8 @@ u32 max_header_size; - /* Maximum Descriptors number, including meta descriptor, allowed for - * a single Tx packet + /* Maximum Descriptors number, including meta descriptor, allowed for a + * single Tx packet */ u16 max_packet_tx_descs; @@ -670,11 +717,11 @@ }; struct ena_admin_feature_rss_flow_hash_control { - u32 keys_num; + u32 key_parts; u32 reserved; - u32 key[10]; + u32 key[ENA_ADMIN_RSS_KEY_PARTS]; }; struct ena_admin_feature_rss_flow_hash_function { @@ -764,8 +811,8 @@ ENA_ADMIN_OS_DPDK = 3, ENA_ADMIN_OS_FREEBSD = 4, ENA_ADMIN_OS_IPXE = 5, - ENA_ADMIN_OS_ESXI = 6, - ENA_ADMIN_OS_GROUPS_NUM = 6, + ENA_ADMIN_OS_ESXI = 6, + ENA_ADMIN_OS_GROUPS_NUM = 6, }; struct ena_admin_host_info { @@ -809,9 +856,12 @@ u16 reserved; - /* 1 :0 : reserved + /* 0 : reserved + * 1 : rx_offset * 2 : interrupt_moderation - * 31:3 : reserved + * 3 : rx_buf_mirroring + * 4 : rss_configurable_function_key + * 31:5 : reserved */ u32 driver_supported_features; }; @@ -967,7 +1017,7 @@ struct ena_admin_aenq_common_desc { u16 group; - u16 syndrom; + u16 syndrome; /* 0 : phase * 7:1 : reserved - MBZ @@ -991,7 +1041,7 @@ ENA_ADMIN_AENQ_GROUPS_NUM = 5, }; -enum ena_admin_aenq_notification_syndrom { +enum ena_admin_aenq_notification_syndrome { ENA_ADMIN_SUSPEND = 0, ENA_ADMIN_RESUME = 1, ENA_ADMIN_UPDATE_HINTS = 2, @@ -1017,6 +1067,10 @@ u32 rx_drops_low; u32 rx_drops_high; + + u32 tx_drops_low; + + u32 tx_drops_high; }; struct ena_admin_ena_mmio_req_read_less_resp { @@ -1116,8 +1170,14 @@ #define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3) #define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 #define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8) +#define ENA_ADMIN_HOST_INFO_RX_OFFSET_SHIFT 1 +#define ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK BIT(1) #define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_SHIFT 2 #define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2) +#define ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_SHIFT 3 +#define ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_MASK BIT(3) +#define ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_SHIFT 4 +#define ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_MASK BIT(4) /* aenq_common_desc */ #define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) @@ -1125,4 +1185,4 @@ /* aenq_link_change_desc */ #define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0) -#endif /*_ENA_ADMIN_H_ */ +#endif /* _ENA_ADMIN_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_com.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_com.c @@ -1,33 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include "ena_com.h" @@ -62,7 +35,9 @@ #define ENA_REGS_ADMIN_INTR_MASK 1 -#define ENA_POLL_MS 5 +#define ENA_MIN_ADMIN_POLL_US 100 + +#define ENA_MAX_ADMIN_POLL_US 5000 /*****************************************************************************/ /*****************************************************************************/ @@ -96,7 +71,7 @@ dma_addr_t addr) { if ((addr & GENMASK_ULL(ena_dev->dma_addr_bits - 1, 0)) != addr) { - pr_err("dma address has more bits that the device supports\n"); + pr_err("DMA address has more bits that the device supports\n"); return -EINVAL; } @@ -106,16 +81,16 @@ return 0; } -static int ena_com_admin_init_sq(struct ena_com_admin_queue *queue) +static int ena_com_admin_init_sq(struct ena_com_admin_queue *admin_queue) { - struct ena_com_admin_sq *sq = &queue->sq; - u16 size = ADMIN_SQ_SIZE(queue->q_depth); + struct ena_com_admin_sq *sq = &admin_queue->sq; + u16 size = ADMIN_SQ_SIZE(admin_queue->q_depth); - sq->entries = dma_alloc_coherent(queue->q_dmadev, size, &sq->dma_addr, - GFP_KERNEL); + sq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size, + &sq->dma_addr, GFP_KERNEL); if (!sq->entries) { - pr_err("memory allocation failed\n"); + pr_err("Memory allocation failed\n"); return -ENOMEM; } @@ -128,16 +103,16 @@ return 0; } -static int ena_com_admin_init_cq(struct ena_com_admin_queue *queue) +static int ena_com_admin_init_cq(struct ena_com_admin_queue *admin_queue) { - struct ena_com_admin_cq *cq = &queue->cq; - u16 size = ADMIN_CQ_SIZE(queue->q_depth); + struct ena_com_admin_cq *cq = &admin_queue->cq; + u16 size = ADMIN_CQ_SIZE(admin_queue->q_depth); - cq->entries = dma_alloc_coherent(queue->q_dmadev, size, &cq->dma_addr, - GFP_KERNEL); + cq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size, + &cq->dma_addr, GFP_KERNEL); if (!cq->entries) { - pr_err("memory allocation failed\n"); + pr_err("Memory allocation failed\n"); return -ENOMEM; } @@ -147,20 +122,20 @@ return 0; } -static int ena_com_admin_init_aenq(struct ena_com_dev *dev, +static int ena_com_admin_init_aenq(struct ena_com_dev *ena_dev, struct ena_aenq_handlers *aenq_handlers) { - struct ena_com_aenq *aenq = &dev->aenq; + struct ena_com_aenq *aenq = &ena_dev->aenq; u32 addr_low, addr_high, aenq_caps; u16 size; - dev->aenq.q_depth = ENA_ASYNC_QUEUE_DEPTH; + ena_dev->aenq.q_depth = ENA_ASYNC_QUEUE_DEPTH; size = ADMIN_AENQ_SIZE(ENA_ASYNC_QUEUE_DEPTH); - aenq->entries = dma_alloc_coherent(dev->dmadev, size, &aenq->dma_addr, - GFP_KERNEL); + aenq->entries = dma_alloc_coherent(ena_dev->dmadev, size, + &aenq->dma_addr, GFP_KERNEL); if (!aenq->entries) { - pr_err("memory allocation failed\n"); + pr_err("Memory allocation failed\n"); return -ENOMEM; } @@ -170,18 +145,18 @@ addr_low = ENA_DMA_ADDR_TO_UINT32_LOW(aenq->dma_addr); addr_high = ENA_DMA_ADDR_TO_UINT32_HIGH(aenq->dma_addr); - writel(addr_low, dev->reg_bar + ENA_REGS_AENQ_BASE_LO_OFF); - writel(addr_high, dev->reg_bar + ENA_REGS_AENQ_BASE_HI_OFF); + writel(addr_low, ena_dev->reg_bar + ENA_REGS_AENQ_BASE_LO_OFF); + writel(addr_high, ena_dev->reg_bar + ENA_REGS_AENQ_BASE_HI_OFF); aenq_caps = 0; - aenq_caps |= dev->aenq.q_depth & ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK; + aenq_caps |= ena_dev->aenq.q_depth & ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK; aenq_caps |= (sizeof(struct ena_admin_aenq_entry) << ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT) & ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK; - writel(aenq_caps, dev->reg_bar + ENA_REGS_AENQ_CAPS_OFF); + writel(aenq_caps, ena_dev->reg_bar + ENA_REGS_AENQ_CAPS_OFF); if (unlikely(!aenq_handlers)) { - pr_err("aenq handlers pointer is NULL\n"); + pr_err("AENQ handlers pointer is NULL\n"); return -EINVAL; } @@ -197,26 +172,31 @@ atomic_dec(&queue->outstanding_cmds); } -static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *queue, +static struct ena_comp_ctx *get_comp_ctxt(struct ena_com_admin_queue *admin_queue, u16 command_id, bool capture) { - if (unlikely(command_id >= queue->q_depth)) { - pr_err("command id is larger than the queue size. cmd_id: %u queue size %d\n", - command_id, queue->q_depth); + if (unlikely(command_id >= admin_queue->q_depth)) { + pr_err("Command id is larger than the queue size. cmd_id: %u queue size %d\n", + command_id, admin_queue->q_depth); + return NULL; + } + + if (unlikely(!admin_queue->comp_ctx)) { + pr_err("Completion context is NULL\n"); return NULL; } - if (unlikely(queue->comp_ctx[command_id].occupied && capture)) { + if (unlikely(admin_queue->comp_ctx[command_id].occupied && capture)) { pr_err("Completion context is occupied\n"); return NULL; } if (capture) { - atomic_inc(&queue->outstanding_cmds); - queue->comp_ctx[command_id].occupied = true; + atomic_inc(&admin_queue->outstanding_cmds); + admin_queue->comp_ctx[command_id].occupied = true; } - return &queue->comp_ctx[command_id]; + return &admin_queue->comp_ctx[command_id]; } static struct ena_comp_ctx *__ena_com_submit_admin_cmd(struct ena_com_admin_queue *admin_queue, @@ -237,7 +217,7 @@ /* In case of queue FULL */ cnt = (u16)atomic_read(&admin_queue->outstanding_cmds); if (cnt >= admin_queue->q_depth) { - pr_debug("admin queue is full.\n"); + pr_debug("Admin queue is full.\n"); admin_queue->stats.out_of_space++; return ERR_PTR(-ENOSPC); } @@ -277,20 +257,21 @@ return comp_ctx; } -static int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue) +static int ena_com_init_comp_ctxt(struct ena_com_admin_queue *admin_queue) { - size_t size = queue->q_depth * sizeof(struct ena_comp_ctx); + size_t size = admin_queue->q_depth * sizeof(struct ena_comp_ctx); struct ena_comp_ctx *comp_ctx; u16 i; - queue->comp_ctx = devm_kzalloc(queue->q_dmadev, size, GFP_KERNEL); - if (unlikely(!queue->comp_ctx)) { - pr_err("memory allocation failed\n"); + admin_queue->comp_ctx = + devm_kzalloc(admin_queue->q_dmadev, size, GFP_KERNEL); + if (unlikely(!admin_queue->comp_ctx)) { + pr_err("Memory allocation failed\n"); return -ENOMEM; } - for (i = 0; i < queue->q_depth; i++) { - comp_ctx = get_comp_ctxt(queue, i, false); + for (i = 0; i < admin_queue->q_depth; i++) { + comp_ctx = get_comp_ctxt(admin_queue, i, false); if (comp_ctx) init_completion(&comp_ctx->wait_event); } @@ -356,7 +337,7 @@ } if (!io_sq->desc_addr.virt_addr) { - pr_err("memory allocation failed\n"); + pr_err("Memory allocation failed\n"); return -ENOMEM; } } @@ -369,8 +350,8 @@ ENA_COM_BOUNCE_BUFFER_CNTRL_CNT; io_sq->bounce_buf_ctrl.next_to_use = 0; - size = io_sq->bounce_buf_ctrl.buffer_size * - io_sq->bounce_buf_ctrl.buffers_num; + size = (size_t)io_sq->bounce_buf_ctrl.buffer_size * + io_sq->bounce_buf_ctrl.buffers_num; dev_node = dev_to_node(ena_dev->dmadev); set_dev_node(ena_dev->dmadev, ctx->numa_node); @@ -382,7 +363,7 @@ devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL); if (!io_sq->bounce_buf_ctrl.base_buffer) { - pr_err("bounce buffer memory allocation failed\n"); + pr_err("Bounce buffer memory allocation failed\n"); return -ENOMEM; } @@ -396,6 +377,8 @@ 0x0, io_sq->llq_info.desc_list_entry_size); io_sq->llq_buf_ctrl.descs_left_in_line = io_sq->llq_info.descs_num_before_header; + io_sq->disable_meta_caching = + io_sq->llq_info.disable_meta_caching; if (io_sq->llq_info.max_entries_in_tx_burst > 0) io_sq->entries_in_tx_burst_left = @@ -440,7 +423,7 @@ } if (!io_cq->cdesc_addr.virt_addr) { - pr_err("memory allocation failed\n"); + pr_err("Memory allocation failed\n"); return -ENOMEM; } @@ -516,10 +499,7 @@ static int ena_com_comp_status_to_errno(u8 comp_status) { if (unlikely(comp_status != 0)) - pr_err("admin command failed[%u]\n", comp_status); - - if (unlikely(comp_status > ENA_ADMIN_UNKNOWN_ERROR)) - return -EINVAL; + pr_err("Admin command failed[%u]\n", comp_status); switch (comp_status) { case ENA_ADMIN_SUCCESS: @@ -533,9 +513,18 @@ case ENA_ADMIN_ILLEGAL_PARAMETER: case ENA_ADMIN_UNKNOWN_ERROR: return -EINVAL; + case ENA_ADMIN_RESOURCE_BUSY: + return -EAGAIN; } - return 0; + return -EINVAL; +} + +static void ena_delay_exponential_backoff_us(u32 exp, u32 delay_us) +{ + delay_us = max_t(u32, ENA_MIN_ADMIN_POLL_US, delay_us); + delay_us = min_t(u32, delay_us * (1U << exp), ENA_MAX_ADMIN_POLL_US); + usleep_range(delay_us, 2 * delay_us); } static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx, @@ -544,6 +533,7 @@ unsigned long flags = 0; unsigned long timeout; int ret; + u32 exp = 0; timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout); @@ -567,7 +557,8 @@ goto err; } - msleep(ENA_POLL_MS); + ena_delay_exponential_backoff_us(exp++, + admin_queue->ena_dev->ena_min_poll_delay_us); } if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) { @@ -588,7 +579,7 @@ return ret; } -/** +/* * Set the LLQ configurations of the firmware * * The driver provides only the enabled feature values to the device, @@ -613,6 +604,10 @@ cmd.u.llq.desc_num_before_header_enabled = llq_info->descs_num_before_header; cmd.u.llq.descriptors_stride_ctrl_enabled = llq_info->desc_stride_ctrl; + cmd.u.llq.accel_mode.u.set.enabled_flags = + BIT(ENA_ADMIN_DISABLE_META_CACHING) | + BIT(ENA_ADMIN_LIMIT_TX_BURST); + ret = ena_com_execute_admin_command(admin_queue, (struct ena_admin_aq_entry *)&cmd, sizeof(cmd), @@ -630,6 +625,7 @@ struct ena_llq_configurations *llq_default_cfg) { struct ena_com_llq_info *llq_info = &ena_dev->llq_info; + struct ena_admin_accel_mode_get llq_accel_mode_get; u16 supported_feat; int rc; @@ -697,8 +693,7 @@ /* The desc list entry size should be whole multiply of 8 * This requirement comes from __iowrite64_copy() */ - pr_err("illegal entry size %d\n", - llq_info->desc_list_entry_size); + pr_err("Illegal entry size %d\n", llq_info->desc_list_entry_size); return -EINVAL; } @@ -730,9 +725,17 @@ llq_default_cfg->llq_num_decs_before_header, supported_feat, llq_info->descs_num_before_header); } + /* Check for accelerated queue supported */ + llq_accel_mode_get = llq_features->accel_mode.u.get; - llq_info->max_entries_in_tx_burst = - (u16)(llq_features->max_tx_burst_size / llq_default_cfg->llq_ring_entry_size_value); + llq_info->disable_meta_caching = + !!(llq_accel_mode_get.supported_flags & + BIT(ENA_ADMIN_DISABLE_META_CACHING)); + + if (llq_accel_mode_get.supported_flags & BIT(ENA_ADMIN_LIMIT_TX_BURST)) + llq_info->max_entries_in_tx_burst = + llq_accel_mode_get.max_tx_burst_size / + llq_default_cfg->llq_ring_entry_size_value; rc = ena_com_set_llq(ena_dev); if (rc) @@ -770,7 +773,7 @@ if (admin_queue->auto_polling) admin_queue->polling = true; } else { - pr_err("The ena device doesn't send a completion for the admin cmd %d status %d\n", + pr_err("The ena device didn't send a completion for the admin cmd %d status %d\n", comp_ctx->cmd_opcode, comp_ctx->status); } /* Check if shifted to polling mode. @@ -831,7 +834,7 @@ } if (unlikely(i == timeout)) { - pr_err("reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n", + pr_err("Reading reg failed for timeout. expected: req id[%hu] offset[%hu] actual: req id[%hu] offset[%hu]\n", mmio_read->seq_num, offset, read_resp->req_id, read_resp->reg_off); ret = ENA_MMIO_READ_TIMEOUT; @@ -898,7 +901,7 @@ sizeof(destroy_resp)); if (unlikely(ret && (ret != -ENODEV))) - pr_err("failed to destroy io sq error: %d\n", ret); + pr_err("Failed to destroy io sq error: %d\n", ret); return ret; } @@ -938,12 +941,13 @@ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, u16 exp_state) { - u32 val, i; + u32 val, exp = 0; + unsigned long timeout_stamp; - /* Convert timeout from resolution of 100ms to ENA_POLL_MS */ - timeout = (timeout * 100) / ENA_POLL_MS; + /* Convert timeout from resolution of 100ms to us resolution. */ + timeout_stamp = jiffies + usecs_to_jiffies(100 * 1000 * timeout); - for (i = 0; i < timeout; i++) { + while (1) { val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF); if (unlikely(val == ENA_MMIO_READ_TIMEOUT)) { @@ -955,10 +959,11 @@ exp_state) return 0; - msleep(ENA_POLL_MS); - } + if (time_is_before_jiffies(timeout_stamp)) + return -ETIME; - return -ETIME; + ena_delay_exponential_backoff_us(exp++, ena_dev->ena_min_poll_delay_us); + } } static bool ena_com_check_supported_feature_id(struct ena_com_dev *ena_dev, @@ -1005,7 +1010,7 @@ &get_cmd.control_buffer.address, control_buf_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -1041,10 +1046,31 @@ feature_ver); } +static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev) +{ + struct ena_admin_feature_rss_flow_hash_control *hash_key = + (ena_dev->rss).hash_key; + + netdev_rss_key_fill(&hash_key->key, sizeof(hash_key->key)); + /* The key buffer is stored in the device in an array of + * uint32 elements. + */ + hash_key->key_parts = ENA_ADMIN_RSS_KEY_PARTS; +} + +int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev) +{ + return ena_dev->rss.hash_func; +} + static int ena_com_hash_key_allocate(struct ena_com_dev *ena_dev) { struct ena_rss *rss = &ena_dev->rss; + if (!ena_com_check_supported_feature_id(ena_dev, + ENA_ADMIN_RSS_HASH_FUNCTION)) + return -EOPNOTSUPP; + rss->hash_key = dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key), &rss->hash_key_dma_addr, GFP_KERNEL); @@ -1098,13 +1124,13 @@ int ret; ret = ena_com_get_feature(ena_dev, &get_resp, - ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG, 0); + ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG, 0); if (unlikely(ret)) return ret; if ((get_resp.u.ind_table.min_size > log_size) || (get_resp.u.ind_table.max_size < log_size)) { - pr_err("indirect table size doesn't fit. requested size: %d while min is:%d and max %d\n", + pr_err("Indirect table size doesn't fit. requested size: %d while min is:%d and max %d\n", 1 << log_size, 1 << get_resp.u.ind_table.min_size, 1 << get_resp.u.ind_table.max_size); return -EINVAL; @@ -1197,7 +1223,7 @@ &create_cmd.sq_ba, io_sq->desc_addr.phys_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } } @@ -1226,7 +1252,7 @@ cmd_completion.llq_descriptors_offset); } - pr_debug("created sq[%u], depth[%u]\n", io_sq->idx, io_sq->q_depth); + pr_debug("Created sq[%u], depth[%u]\n", io_sq->idx, io_sq->q_depth); return ret; } @@ -1254,40 +1280,12 @@ return 0; } -static int ena_com_ind_tbl_convert_from_device(struct ena_com_dev *ena_dev) -{ - u16 dev_idx_to_host_tbl[ENA_TOTAL_NUM_QUEUES] = { (u16)-1 }; - struct ena_rss *rss = &ena_dev->rss; - u8 idx; - u16 i; - - for (i = 0; i < ENA_TOTAL_NUM_QUEUES; i++) - dev_idx_to_host_tbl[ena_dev->io_sq_queues[i].idx] = i; - - for (i = 0; i < 1 << rss->tbl_log_size; i++) { - if (rss->rss_ind_tbl[i].cq_idx > ENA_TOTAL_NUM_QUEUES) - return -EINVAL; - idx = (u8)rss->rss_ind_tbl[i].cq_idx; - - if (dev_idx_to_host_tbl[idx] > ENA_TOTAL_NUM_QUEUES) - return -EINVAL; - - rss->host_rss_ind_tbl[i] = dev_idx_to_host_tbl[idx]; - } - - return 0; -} - static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, u16 intr_delay_resolution) { - /* Initial value of intr_delay_resolution might be 0 */ - u16 prev_intr_delay_resolution = - ena_dev->intr_delay_resolution ? - ena_dev->intr_delay_resolution : - ENA_DEFAULT_INTR_DELAY_RESOLUTION; + u16 prev_intr_delay_resolution = ena_dev->intr_delay_resolution; - if (!intr_delay_resolution) { + if (unlikely(!intr_delay_resolution)) { pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n"); intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION; } @@ -1367,7 +1365,7 @@ &create_cmd.cq_ba, io_cq->cdesc_addr.phys_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -1396,7 +1394,7 @@ (u32 __iomem *)((uintptr_t)ena_dev->reg_bar + cmd_completion.numa_node_register_offset); - pr_debug("created cq[%u], depth[%u]\n", io_cq->idx, io_cq->q_depth); + pr_debug("Created cq[%u], depth[%u]\n", io_cq->idx, io_cq->q_depth); return ret; } @@ -1441,11 +1439,13 @@ { struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue; unsigned long flags = 0; + u32 exp = 0; spin_lock_irqsave(&admin_queue->q_lock, flags); while (atomic_read(&admin_queue->outstanding_cmds) != 0) { spin_unlock_irqrestore(&admin_queue->q_lock, flags); - msleep(ENA_POLL_MS); + ena_delay_exponential_backoff_us(exp++, + ena_dev->ena_min_poll_delay_us); spin_lock_irqsave(&admin_queue->q_lock, flags); } spin_unlock_irqrestore(&admin_queue->q_lock, flags); @@ -1587,12 +1587,12 @@ return -ETIME; } - pr_info("ena device version: %d.%d\n", + pr_info("ENA device version: %d.%d\n", (ver & ENA_REGS_VERSION_MAJOR_VERSION_MASK) >> ENA_REGS_VERSION_MAJOR_VERSION_SHIFT, ver & ENA_REGS_VERSION_MINOR_VERSION_MASK); - pr_info("ena controller version: %d.%d.%d implementation version %d\n", + pr_info("ENA controller version: %d.%d.%d implementation version %d\n", (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) >> ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT, (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK) >> @@ -1615,6 +1615,19 @@ return 0; } +static void +ena_com_free_ena_admin_queue_comp_ctx(struct ena_com_dev *ena_dev, + struct ena_com_admin_queue *admin_queue) + +{ + if (!admin_queue->comp_ctx) + return; + + devm_kfree(ena_dev->dmadev, admin_queue->comp_ctx); + + admin_queue->comp_ctx = NULL; +} + void ena_com_admin_destroy(struct ena_com_dev *ena_dev) { struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue; @@ -1623,9 +1636,8 @@ struct ena_com_aenq *aenq = &ena_dev->aenq; u16 size; - if (admin_queue->comp_ctx) - devm_kfree(ena_dev->dmadev, admin_queue->comp_ctx); - admin_queue->comp_ctx = NULL; + ena_com_free_ena_admin_queue_comp_ctx(ena_dev, admin_queue); + size = ADMIN_SQ_SIZE(admin_queue->q_depth); if (sq->entries) dma_free_coherent(ena_dev->dmadev, size, sq->entries, @@ -1793,6 +1805,7 @@ if (ret) goto error; + admin_queue->ena_dev = ena_dev; admin_queue->running_state = true; return 0; @@ -1902,6 +1915,7 @@ memcpy(&get_feat_ctx->dev_attr, &get_resp.u.dev_attr, sizeof(get_resp.u.dev_attr)); + ena_dev->supported_features = get_resp.u.dev_attr.supported_features; if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { @@ -1980,10 +1994,10 @@ /* ena_handle_specific_aenq_event: * return the handler that is relevant to the specific event group */ -static ena_aenq_handler ena_com_get_specific_aenq_cb(struct ena_com_dev *dev, +static ena_aenq_handler ena_com_get_specific_aenq_cb(struct ena_com_dev *ena_dev, u16 group) { - struct ena_aenq_handlers *aenq_handlers = dev->aenq.aenq_handlers; + struct ena_aenq_handlers *aenq_handlers = ena_dev->aenq.aenq_handlers; if ((group < ENA_MAX_HANDLERS) && aenq_handlers->handlers[group]) return aenq_handlers->handlers[group]; @@ -1995,12 +2009,12 @@ * handles the aenq incoming events. * pop events from the queue and apply the specific handler */ -void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data) +void ena_com_aenq_intr_handler(struct ena_com_dev *ena_dev, void *data) { struct ena_admin_aenq_entry *aenq_e; struct ena_admin_aenq_common_desc *aenq_common; - struct ena_com_aenq *aenq = &dev->aenq; - unsigned long long timestamp; + struct ena_com_aenq *aenq = &ena_dev->aenq; + u64 timestamp; ena_aenq_handler handler_cb; u16 masked_head, processed = 0; u8 phase; @@ -2018,14 +2032,14 @@ */ dma_rmb(); - timestamp = - (unsigned long long)aenq_common->timestamp_low | - ((unsigned long long)aenq_common->timestamp_high << 32); - pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n", - aenq_common->group, aenq_common->syndrom, timestamp); + timestamp = (u64)aenq_common->timestamp_low | + ((u64)aenq_common->timestamp_high << 32); + + pr_debug("AENQ! Group[%x] Syndrome[%x] timestamp: [%llus]\n", + aenq_common->group, aenq_common->syndrome, timestamp); /* Handle specific event*/ - handler_cb = ena_com_get_specific_aenq_cb(dev, + handler_cb = ena_com_get_specific_aenq_cb(ena_dev, aenq_common->group); handler_cb(data, aenq_e); /* call the actual event handler*/ @@ -2051,7 +2065,7 @@ /* write the aenq doorbell after all AENQ descriptors were read */ mb(); writel_relaxed((u32)aenq->head, - dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF); + ena_dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF); } int ena_com_dev_reset(struct ena_com_dev *ena_dev, @@ -2143,6 +2157,21 @@ return ret; } +int ena_com_get_eni_stats(struct ena_com_dev *ena_dev, + struct ena_admin_eni_stats *stats) +{ + struct ena_com_stats_ctx ctx; + int ret; + + memset(&ctx, 0x0, sizeof(ctx)); + ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_ENI); + if (likely(ret == 0)) + memcpy(stats, &ctx.get_resp.u.eni_stats, + sizeof(ctx.get_resp.u.eni_stats)); + + return ret; +} + int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev, struct ena_admin_basic_stats *stats) { @@ -2152,8 +2181,8 @@ memset(&ctx, 0x0, sizeof(ctx)); ret = ena_get_dev_stats(ena_dev, &ctx, ENA_ADMIN_GET_STATS_TYPE_BASIC); if (likely(ret == 0)) - memcpy(stats, &ctx.get_resp.basic_stats, - sizeof(ctx.get_resp.basic_stats)); + memcpy(stats, &ctx.get_resp.u.basic_stats, + sizeof(ctx.get_resp.u.basic_stats)); return ret; } @@ -2249,7 +2278,7 @@ &cmd.control_buffer.address, rss->hash_key_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -2273,12 +2302,14 @@ enum ena_admin_hash_functions func, const u8 *key, u16 key_len, u32 init_val) { - struct ena_rss *rss = &ena_dev->rss; + struct ena_admin_feature_rss_flow_hash_control *hash_key; struct ena_admin_get_feat_resp get_resp; - struct ena_admin_feature_rss_flow_hash_control *hash_key = - rss->hash_key; + enum ena_admin_hash_functions old_func; + struct ena_rss *rss = &ena_dev->rss; int rc; + hash_key = rss->hash_key; + /* Make sure size is a mult of DWs */ if (unlikely(key_len & 0x3)) return -EINVAL; @@ -2290,22 +2321,23 @@ if (unlikely(rc)) return rc; - if (!((1 << func) & get_resp.u.flow_hash_func.supported_func)) { + if (!(BIT(func) & get_resp.u.flow_hash_func.supported_func)) { pr_err("Flow hash function %d isn't supported\n", func); return -EOPNOTSUPP; } switch (func) { case ENA_ADMIN_TOEPLITZ: - if (key_len > sizeof(hash_key->key)) { - pr_err("key len (%hu) is bigger than the max supported (%zu)\n", - key_len, sizeof(hash_key->key)); - return -EINVAL; + if (key) { + if (key_len != sizeof(hash_key->key)) { + pr_err("key len (%hu) doesn't equal the supported size (%zu)\n", + key_len, sizeof(hash_key->key)); + return -EINVAL; + } + memcpy(hash_key->key, key, key_len); + rss->hash_init_val = init_val; + hash_key->key_parts = key_len / sizeof(hash_key->key[0]); } - - memcpy(hash_key->key, key, key_len); - rss->hash_init_val = init_val; - hash_key->keys_num = key_len >> 2; break; case ENA_ADMIN_CRC32: rss->hash_init_val = init_val; @@ -2315,26 +2347,27 @@ return -EINVAL; } + old_func = rss->hash_func; rss->hash_func = func; rc = ena_com_set_hash_function(ena_dev); /* Restore the old function */ if (unlikely(rc)) - ena_com_get_hash_function(ena_dev, NULL, NULL); + rss->hash_func = old_func; return rc; } int ena_com_get_hash_function(struct ena_com_dev *ena_dev, - enum ena_admin_hash_functions *func, - u8 *key) + enum ena_admin_hash_functions *func) { struct ena_rss *rss = &ena_dev->rss; struct ena_admin_get_feat_resp get_resp; - struct ena_admin_feature_rss_flow_hash_control *hash_key = - rss->hash_key; int rc; + if (unlikely(!func)) + return -EINVAL; + rc = ena_com_get_feature_ex(ena_dev, &get_resp, ENA_ADMIN_RSS_HASH_FUNCTION, rss->hash_key_dma_addr, @@ -2342,12 +2375,24 @@ if (unlikely(rc)) return rc; - rss->hash_func = get_resp.u.flow_hash_func.selected_func; - if (func) - *func = rss->hash_func; + /* ffs() returns 1 in case the lsb is set */ + rss->hash_func = ffs(get_resp.u.flow_hash_func.selected_func); + if (rss->hash_func) + rss->hash_func--; + + *func = rss->hash_func; + + return 0; +} + +int ena_com_get_hash_key(struct ena_com_dev *ena_dev, u8 *key) +{ + struct ena_admin_feature_rss_flow_hash_control *hash_key = + ena_dev->rss.hash_key; if (key) - memcpy(key, hash_key->key, (size_t)(hash_key->keys_num) << 2); + memcpy(key, hash_key->key, + (size_t)(hash_key->key_parts) * sizeof(hash_key->key[0])); return 0; } @@ -2403,7 +2448,7 @@ &cmd.control_buffer.address, rss->hash_ctrl_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } cmd.control_buffer.length = sizeof(*hash_ctrl); @@ -2464,7 +2509,7 @@ available_fields = hash_ctrl->selected_fields[i].fields & hash_ctrl->supported_fields[i].fields; if (available_fields != hash_ctrl->selected_fields[i].fields) { - pr_err("hash control doesn't support all the desire configuration. proto %x supported %x selected %x\n", + pr_err("Hash control doesn't support all the desire configuration. proto %x supported %x selected %x\n", i, hash_ctrl->supported_fields[i].fields, hash_ctrl->selected_fields[i].fields); return -EOPNOTSUPP; @@ -2502,7 +2547,7 @@ /* Make sure all the fields are supported */ supported_fields = hash_ctrl->supported_fields[proto].fields; if ((hash_fields & supported_fields) != hash_fields) { - pr_err("proto %d doesn't support the required fields %x. supports only: %x\n", + pr_err("Proto %d doesn't support the required fields %x. supports only: %x\n", proto, hash_fields, supported_fields); } @@ -2542,9 +2587,9 @@ int ret; if (!ena_com_check_supported_feature_id( - ena_dev, ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG)) { + ena_dev, ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG)) { pr_debug("Feature %d isn't supported\n", - ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG); + ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG); return -EOPNOTSUPP; } @@ -2559,7 +2604,7 @@ cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE; cmd.aq_common_descriptor.flags = ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK; - cmd.feat_common.feature_id = ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG; + cmd.feat_common.feature_id = ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG; cmd.u.ind_table.size = rss->tbl_log_size; cmd.u.ind_table.inline_index = 0xFFFFFFFF; @@ -2567,7 +2612,7 @@ &cmd.control_buffer.address, rss->rss_ind_tbl_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -2597,7 +2642,7 @@ sizeof(struct ena_admin_rss_ind_table_entry); rc = ena_com_get_feature_ex(ena_dev, &get_resp, - ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG, + ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG, rss->rss_ind_tbl_dma_addr, tbl_size, 0); if (unlikely(rc)) @@ -2606,10 +2651,6 @@ if (!ind_tbl) return 0; - rc = ena_com_ind_tbl_convert_from_device(ena_dev); - if (unlikely(rc)) - return rc; - for (i = 0; i < (1 << rss->tbl_log_size); i++) ind_tbl[i] = rss->host_rss_ind_tbl[i]; @@ -2626,8 +2667,14 @@ if (unlikely(rc)) goto err_indr_tbl; + /* The following function might return unsupported in case the + * device doesn't support setting the key / hash function. We can safely + * ignore this error and have indirection table support only. + */ rc = ena_com_hash_key_allocate(ena_dev); - if (unlikely(rc)) + if (likely(!rc)) + ena_com_hash_key_fill_default_key(ena_dev); + else if (rc != -EOPNOTSUPP) goto err_hash_key; rc = ena_com_hash_ctrl_init(ena_dev); @@ -2678,8 +2725,7 @@ host_attr->debug_area_virt_addr = dma_alloc_coherent(ena_dev->dmadev, debug_area_size, - &host_attr->debug_area_dma_addr, - GFP_KERNEL); + &host_attr->debug_area_dma_addr, GFP_KERNEL); if (unlikely(!host_attr->debug_area_virt_addr)) { host_attr->debug_area_size = 0; return -ENOMEM; @@ -2736,7 +2782,7 @@ &cmd.u.host_attr.debug_ba, host_attr->debug_area_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -2744,7 +2790,7 @@ &cmd.u.host_attr.os_info_ba, host_attr->host_info_dma_addr); if (unlikely(ret)) { - pr_err("memory address set failed\n"); + pr_err("Memory address set failed\n"); return ret; } @@ -2863,7 +2909,7 @@ (llq_info->descs_num_before_header * sizeof(struct ena_eth_io_tx_desc)); if (unlikely(ena_dev->tx_max_header_size == 0)) { - pr_err("the size of the LLQ entry is smaller than needed\n"); + pr_err("The size of the LLQ entry is smaller than needed\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_com.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_com.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef ENA_COM @@ -44,6 +17,7 @@ #include #include #include +#include #include "ena_common_defs.h" #include "ena_admin_defs.h" @@ -53,9 +27,9 @@ #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define ENA_MAX_NUM_IO_QUEUES 128U +#define ENA_MAX_NUM_IO_QUEUES 128U /* We need to queues for each IO (on for Tx and one for Rx) */ -#define ENA_TOTAL_NUM_QUEUES (2 * (ENA_MAX_NUM_IO_QUEUES)) +#define ENA_TOTAL_NUM_QUEUES (2 * (ENA_MAX_NUM_IO_QUEUES)) #define ENA_MAX_HANDLERS 256 @@ -72,13 +46,15 @@ /*****************************************************************************/ /* ENA adaptive interrupt moderation settings */ -#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196 -#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 -#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1 +#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64 +#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 +#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1 + +#define ENA_HASH_KEY_SIZE 40 -#define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF +#define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF -#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1 +#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1 struct ena_llq_configurations { enum ena_admin_llq_header_location llq_header_location; @@ -124,6 +100,7 @@ u16 descs_num_before_header; u16 descs_per_entry; u16 max_entries_in_tx_burst; + bool disable_meta_caching; }; struct ena_com_io_cq { @@ -186,6 +163,8 @@ enum queue_direction direction; enum ena_admin_placement_policy_type mem_queue_type; + bool disable_meta_caching; + u32 msix_vector; struct ena_com_tx_meta cached_tx_meta; struct ena_com_llq_info llq_info; @@ -227,15 +206,16 @@ }; struct ena_com_stats_admin { - u32 aborted_cmd; - u32 submitted_cmd; - u32 completed_cmd; - u32 out_of_space; - u32 no_completion; + u64 aborted_cmd; + u64 submitted_cmd; + u64 completed_cmd; + u64 out_of_space; + u64 no_completion; }; struct ena_com_admin_queue { void *q_dmadev; + struct ena_com_dev *ena_dev; spinlock_t q_lock; /* spinlock for the admin queue */ struct ena_comp_ctx *comp_ctx; @@ -348,6 +328,8 @@ struct ena_intr_moder_entry *intr_moder_tbl; struct ena_com_llq_info llq_info; + + u32 ena_min_poll_delay_us; }; struct ena_com_dev_get_features_ctx { @@ -392,7 +374,7 @@ */ int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev); -/* ena_com_set_mmio_read_mode - Enable/disable the mmio reg read mechanism +/* ena_com_set_mmio_read_mode - Enable/disable the indirect mmio reg read mechanism * @ena_dev: ENA communication layer struct * @readless_supported: readless mode (enable/disable) */ @@ -500,18 +482,6 @@ */ void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling); -/* ena_com_set_admin_polling_mode - Get the admin completion queue polling mode - * @ena_dev: ENA communication layer struct - * - * Get the admin completion mode. - * If polling mode is on, ena_com_execute_admin_command will perform a - * polling on the admin completion queue for the commands completion, - * otherwise it will wait on wait event. - * - * @return state - */ -bool ena_com_get_ena_admin_polling_mode(struct ena_com_dev *ena_dev); - /* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode * @ena_dev: ENA communication layer struct * @polling: Enable/Disable polling mode @@ -526,7 +496,7 @@ /* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler * @ena_dev: ENA communication layer struct * - * This method go over the admin completion queue and wake up all the pending + * This method goes over the admin completion queue and wakes up all the pending * threads that wait on the commands wait event. * * @note: Should be called after MSI-X interrupt. @@ -536,10 +506,10 @@ /* ena_com_aenq_intr_handler - AENQ interrupt handler * @ena_dev: ENA communication layer struct * - * This method go over the async event notification queue and call the proper + * This method goes over the async event notification queue and calls the proper * aenq handler. */ -void ena_com_aenq_intr_handler(struct ena_com_dev *dev, void *data); +void ena_com_aenq_intr_handler(struct ena_com_dev *ena_dev, void *data); /* ena_com_abort_admin_commands - Abort all the outstanding admin commands. * @ena_dev: ENA communication layer struct @@ -553,14 +523,14 @@ /* ena_com_wait_for_abort_completion - Wait for admin commands abort. * @ena_dev: ENA communication layer struct * - * This method wait until all the outstanding admin commands will be completed. + * This method waits until all the outstanding admin commands are completed. */ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev); /* ena_com_validate_version - Validate the device parameters * @ena_dev: ENA communication layer struct * - * This method validate the device parameters are the same as the saved + * This method verifies the device parameters are the same as the saved * parameters in ena_dev. * This method is useful after device reset, to validate the device mac address * and the device offloads are the same as before the reset. @@ -619,6 +589,15 @@ int ena_com_get_dev_basic_stats(struct ena_com_dev *ena_dev, struct ena_admin_basic_stats *stats); +/* ena_com_get_eni_stats - Get extended network interface statistics + * @ena_dev: ENA communication layer struct + * @stats: stats return value + * + * @return: 0 on Success and negative value otherwise. + */ +int ena_com_get_eni_stats(struct ena_com_dev *ena_dev, + struct ena_admin_eni_stats *stats); + /* ena_com_set_dev_mtu - Configure the device mtu. * @ena_dev: ENA communication layer struct * @mtu: mtu value @@ -655,6 +634,14 @@ */ void ena_com_rss_destroy(struct ena_com_dev *ena_dev); +/* ena_com_get_current_hash_function - Get RSS hash function + * @ena_dev: ENA communication layer struct + * + * Return the current hash function. + * @return: 0 or one of the ena_admin_hash_functions values. + */ +int ena_com_get_current_hash_function(struct ena_com_dev *ena_dev); + /* ena_com_fill_hash_function - Fill RSS hash function * @ena_dev: ENA communication layer struct * @func: The hash function (Toeplitz or crc) @@ -686,23 +673,32 @@ */ int ena_com_set_hash_function(struct ena_com_dev *ena_dev); -/* ena_com_get_hash_function - Retrieve the hash function and the hash key - * from the device. +/* ena_com_get_hash_function - Retrieve the hash function from the device. * @ena_dev: ENA communication layer struct * @func: hash function - * @key: hash key * - * Retrieve the hash function and the hash key from the device. + * Retrieve the hash function from the device. * - * @note: If the caller called ena_com_fill_hash_function but didn't flash + * @note: If the caller called ena_com_fill_hash_function but didn't flush * it to the device, the new configuration will be lost. * * @return: 0 on Success and negative value otherwise. */ int ena_com_get_hash_function(struct ena_com_dev *ena_dev, - enum ena_admin_hash_functions *func, - u8 *key); + enum ena_admin_hash_functions *func); +/* ena_com_get_hash_key - Retrieve the hash key + * @ena_dev: ENA communication layer struct + * @key: hash key + * + * Retrieve the hash key. + * + * @note: If the caller called ena_com_fill_hash_key but didn't flush + * it to the device, the new configuration will be lost. + * + * @return: 0 on Success and negative value otherwise. + */ +int ena_com_get_hash_key(struct ena_com_dev *ena_dev, u8 *key); /* ena_com_fill_hash_ctrl - Fill RSS hash control * @ena_dev: ENA communication layer struct. * @proto: The protocol to configure. @@ -737,7 +733,7 @@ * * Retrieve the hash control from the device. * - * @note, If the caller called ena_com_fill_hash_ctrl but didn't flash + * @note: If the caller called ena_com_fill_hash_ctrl but didn't flush * it to the device, the new configuration will be lost. * * @return: 0 on Success and negative value otherwise. @@ -789,7 +785,7 @@ * * Retrieve the RSS indirection table from the device. * - * @note: If the caller called ena_com_indirect_table_fill_entry but didn't flash + * @note: If the caller called ena_com_indirect_table_fill_entry but didn't flush * it to the device, the new configuration will be lost. * * @return: 0 on Success and negative value otherwise. @@ -815,14 +811,14 @@ /* ena_com_delete_debug_area - Free the debug area resources. * @ena_dev: ENA communication layer struct * - * Free the allocate debug area. + * Free the allocated debug area. */ void ena_com_delete_debug_area(struct ena_com_dev *ena_dev); /* ena_com_delete_host_info - Free the host info resources. * @ena_dev: ENA communication layer struct * - * Free the allocate host info. + * Free the allocated host info. */ void ena_com_delete_host_info(struct ena_com_dev *ena_dev); @@ -863,9 +859,9 @@ * @cmd_completion: command completion return value. * @cmd_comp_size: command completion size. - * Submit an admin command and then wait until the device will return a + * Submit an admin command and then wait until the device returns a * completion. - * The completion will be copyed into cmd_comp. + * The completion will be copied into cmd_comp. * * @return - 0 on success, negative value on failure. */ @@ -928,7 +924,7 @@ /* ena_com_config_dev_mode - Configure the placement policy of the device. * @ena_dev: ENA communication layer struct * @llq_features: LLQ feature descriptor, retrieve via - * ena_com_get_dev_attr_feat. + * ena_com_get_dev_attr_feat. * @ena_llq_config: The default driver LLQ parameters configurations */ int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, @@ -954,7 +950,7 @@ * @intr_reg: interrupt register to update. * @rx_delay_interval: Rx interval in usecs * @tx_delay_interval: Tx interval in usecs - * @unmask: unask enable/disable + * @unmask: unmask enable/disable * * Prepare interrupt update register with the supplied parameters. */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_common_defs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_common_defs.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef _ENA_COMMON_H_ #define _ENA_COMMON_H_ @@ -45,4 +18,4 @@ u16 reserved16; }; -#endif /*_ENA_COMMON_H_ */ +#endif /* _ENA_COMMON_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_eth_com.c @@ -1,33 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include "ena_eth_com.h" @@ -45,8 +18,9 @@ cdesc = (struct ena_eth_io_rx_cdesc_base *)(io_cq->cdesc_addr.virt_addr + (head_masked * io_cq->cdesc_entry_size_in_bytes)); - desc_phase = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >> - ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT; + desc_phase = (READ_ONCE(cdesc->status) & + ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >> + ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT; if (desc_phase != expected_phase) return NULL; @@ -89,7 +63,7 @@ } io_sq->entries_in_tx_burst_left--; - pr_debug("decreasing entries_in_tx_burst_left of queue %d to %d\n", + pr_debug("Decreasing entries_in_tx_burst_left of queue %d to %d\n", io_sq->qid, io_sq->entries_in_tx_burst_left); } @@ -128,12 +102,12 @@ if (unlikely((header_offset + header_len) > llq_info->desc_list_entry_size)) { - pr_err("trying to write header larger than llq entry can accommodate\n"); + pr_err("Trying to write header larger than llq entry can accommodate\n"); return -EFAULT; } if (unlikely(!bounce_buffer)) { - pr_err("bounce buffer is NULL\n"); + pr_err("Bounce buffer is NULL\n"); return -EFAULT; } @@ -151,7 +125,7 @@ bounce_buffer = pkt_ctrl->curr_bounce_buf; if (unlikely(!bounce_buffer)) { - pr_err("bounce buffer is NULL\n"); + pr_err("Bounce buffer is NULL\n"); return NULL; } @@ -262,8 +236,9 @@ ena_com_cq_inc_head(io_cq); count++; - last = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> - ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; + last = (READ_ONCE(cdesc->status) & + ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >> + ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT; } while (!last); if (last) { @@ -275,7 +250,7 @@ io_cq->cur_rx_pkt_cdesc_count = 0; io_cq->cur_rx_pkt_cdesc_start_idx = head_masked; - pr_debug("ena q_id: %d packets were completed. first desc idx %u descs# %d\n", + pr_debug("ENA q_id: %d packets were completed. first desc idx %u descs# %d\n", io_cq->qid, *first_cdesc_idx, count); } else { io_cq->cur_rx_pkt_cdesc_count += count; @@ -285,13 +260,15 @@ return count; } -static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, - struct ena_com_tx_ctx *ena_tx_ctx) +static int ena_com_create_meta(struct ena_com_io_sq *io_sq, + struct ena_com_tx_meta *ena_meta) { struct ena_eth_io_tx_meta_desc *meta_desc = NULL; - struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta; meta_desc = get_sq_desc(io_sq); + if (unlikely(!meta_desc)) + return -EFAULT; + memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc)); meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_DESC_MASK; @@ -299,7 +276,7 @@ meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK; /* bits 0-9 of the mss */ - meta_desc->word2 |= (ena_meta->mss << + meta_desc->word2 |= ((u32)ena_meta->mss << ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT) & ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK; /* bits 10-13 of the mss */ @@ -309,33 +286,57 @@ /* Extended meta desc */ meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK; - meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK; - meta_desc->len_ctrl |= (io_sq->phase << + meta_desc->len_ctrl |= ((u32)io_sq->phase << ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT) & ENA_ETH_IO_TX_META_DESC_PHASE_MASK; meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_FIRST_MASK; + meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK; + meta_desc->word2 |= ena_meta->l3_hdr_len & ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK; meta_desc->word2 |= (ena_meta->l3_hdr_offset << ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT) & ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK; - meta_desc->word2 |= (ena_meta->l4_hdr_len << + meta_desc->word2 |= ((u32)ena_meta->l4_hdr_len << ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT) & ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK; - meta_desc->len_ctrl |= ENA_ETH_IO_TX_META_DESC_META_STORE_MASK; + return ena_com_sq_update_tail(io_sq); +} - /* Cached the meta desc */ - memcpy(&io_sq->cached_tx_meta, ena_meta, - sizeof(struct ena_com_tx_meta)); +static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, + struct ena_com_tx_ctx *ena_tx_ctx, + bool *have_meta) +{ + struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta; - return ena_com_sq_update_tail(io_sq); + /* When disable meta caching is set, don't bother to save the meta and + * compare it to the stored version, just create the meta + */ + if (io_sq->disable_meta_caching) { + if (unlikely(!ena_tx_ctx->meta_valid)) + return -EINVAL; + + *have_meta = true; + return ena_com_create_meta(io_sq, ena_meta); + } + + if (ena_com_meta_desc_changed(io_sq, ena_tx_ctx)) { + *have_meta = true; + /* Cache the meta desc */ + memcpy(&io_sq->cached_tx_meta, ena_meta, + sizeof(struct ena_com_tx_meta)); + return ena_com_create_meta(io_sq, ena_meta); + } + + *have_meta = false; + return 0; } static void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx, - struct ena_eth_io_rx_cdesc_base *cdesc) + struct ena_eth_io_rx_cdesc_base *cdesc) { ena_rx_ctx->l3_proto = cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK; @@ -356,7 +357,7 @@ (cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK) >> ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT; - pr_debug("ena_rx_ctx->l3_proto %d ena_rx_ctx->l4_proto %d\nena_rx_ctx->l3_csum_err %d ena_rx_ctx->l4_csum_err %d\nhash frag %d frag: %d cdesc_status: %x\n", + pr_debug("l3_proto %d l4_proto %d l3_csum_err %d l4_csum_err %d hash %d frag %d cdesc_status %x\n", ena_rx_ctx->l3_proto, ena_rx_ctx->l4_proto, ena_rx_ctx->l3_csum_err, ena_rx_ctx->l4_csum_err, ena_rx_ctx->hash, ena_rx_ctx->frag, cdesc->status); @@ -389,7 +390,7 @@ } if (unlikely(header_len > io_sq->tx_max_header_size)) { - pr_err("header size is too large %d max header: %d\n", + pr_err("Header size is too large %d max header: %d\n", header_len, io_sq->tx_max_header_size); return -EINVAL; } @@ -402,12 +403,10 @@ if (unlikely(rc)) return rc; - have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq, - ena_tx_ctx); - if (have_meta) { - rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx); - if (unlikely(rc)) - return rc; + rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx, &have_meta); + if (unlikely(rc)) { + pr_err("Failed to create and store tx meta desc\n"); + return rc; } /* If the caller doesn't want to send packets */ @@ -426,16 +425,16 @@ if (!have_meta) desc->len_ctrl |= ENA_ETH_IO_TX_DESC_FIRST_MASK; - desc->buff_addr_hi_hdr_sz |= (header_len << + desc->buff_addr_hi_hdr_sz |= ((u32)header_len << ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT) & ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK; - desc->len_ctrl |= (io_sq->phase << ENA_ETH_IO_TX_DESC_PHASE_SHIFT) & + desc->len_ctrl |= ((u32)io_sq->phase << ENA_ETH_IO_TX_DESC_PHASE_SHIFT) & ENA_ETH_IO_TX_DESC_PHASE_MASK; desc->len_ctrl |= ENA_ETH_IO_TX_DESC_COMP_REQ_MASK; /* Bits 0-9 */ - desc->meta_ctrl |= (ena_tx_ctx->req_id << + desc->meta_ctrl |= ((u32)ena_tx_ctx->req_id << ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT) & ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK; @@ -481,7 +480,7 @@ memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc)); - desc->len_ctrl |= (io_sq->phase << + desc->len_ctrl |= ((u32)io_sq->phase << ENA_ETH_IO_TX_DESC_PHASE_SHIFT) & ENA_ETH_IO_TX_DESC_PHASE_MASK; } @@ -517,9 +516,10 @@ { struct ena_com_rx_buf_info *ena_buf = &ena_rx_ctx->ena_bufs[0]; struct ena_eth_io_rx_cdesc_base *cdesc = NULL; + u16 q_depth = io_cq->q_depth; u16 cdesc_idx = 0; u16 nb_hw_desc; - u16 i; + u16 i = 0; WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); @@ -529,7 +529,7 @@ return 0; } - pr_debug("fetch rx packet: queue %d completed desc: %d\n", io_cq->qid, + pr_debug("Fetch rx packet: queue %d completed desc: %d\n", io_cq->qid, nb_hw_desc); if (unlikely(nb_hw_desc > ena_rx_ctx->max_bufs)) { @@ -538,13 +538,21 @@ return -ENOSPC; } - for (i = 0; i < nb_hw_desc; i++) { + cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx); + ena_rx_ctx->pkt_offset = cdesc->offset; + + do { + ena_buf[i].len = cdesc->length; + ena_buf[i].req_id = cdesc->req_id; + if (unlikely(ena_buf[i].req_id >= q_depth)) + return -EIO; + + if (++i >= nb_hw_desc) + break; + cdesc = ena_com_rx_cdesc_idx_to_ptr(io_cq, cdesc_idx + i); - ena_buf->len = cdesc->length; - ena_buf->req_id = cdesc->req_id; - ena_buf++; - } + } while (1); /* Update SQ head ptr */ io_sq->next_to_comp += nb_hw_desc; @@ -578,10 +586,10 @@ desc->length = ena_buf->len; - desc->ctrl = ENA_ETH_IO_RX_DESC_FIRST_MASK; - desc->ctrl |= ENA_ETH_IO_RX_DESC_LAST_MASK; - desc->ctrl |= io_sq->phase & ENA_ETH_IO_RX_DESC_PHASE_MASK; - desc->ctrl |= ENA_ETH_IO_RX_DESC_COMP_REQ_MASK; + desc->ctrl = ENA_ETH_IO_RX_DESC_FIRST_MASK | + ENA_ETH_IO_RX_DESC_LAST_MASK | + (io_sq->phase & ENA_ETH_IO_RX_DESC_PHASE_MASK) | + ENA_ETH_IO_RX_DESC_COMP_REQ_MASK; desc->req_id = req_id; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_eth_com.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef ENA_ETH_COM_H_ @@ -73,6 +46,7 @@ u32 hash; u16 descs; int max_bufs; + u8 pkt_offset; }; int ena_com_prepare_tx(struct ena_com_io_sq *io_sq, @@ -95,7 +69,7 @@ writel(intr_reg->intr_control, io_cq->unmask_reg); } -static inline int ena_com_free_desc(struct ena_com_io_sq *io_sq) +static inline int ena_com_free_q_entries(struct ena_com_io_sq *io_sq) { u16 tail, next_to_comp, cnt; @@ -113,7 +87,7 @@ int temp; if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - return ena_com_free_desc(io_sq) >= required_buffers; + return ena_com_free_q_entries(io_sq) >= required_buffers; /* This calculation doesn't need to be 100% accurate. So to reduce * the calculation overhead just Subtract 2 lines from the free descs @@ -122,7 +96,7 @@ */ temp = required_buffers / io_sq->llq_info.descs_per_entry + 2; - return ena_com_free_desc(io_sq) > temp; + return ena_com_free_q_entries(io_sq) > temp; } static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq, @@ -156,7 +130,8 @@ llq_info = &io_sq->llq_info; num_descs = ena_tx_ctx->num_bufs; - if (unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx))) + if (llq_info->disable_meta_caching || + unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx))) ++num_descs; if (num_descs > llq_info->descs_num_before_header) { @@ -165,7 +140,7 @@ llq_info->descs_per_entry); } - pr_debug("queue: %d num_descs: %d num_entries_needed: %d\n", io_sq->qid, + pr_debug("Queue: %d num_descs: %d num_entries_needed: %d\n", io_sq->qid, num_descs, num_entries_needed); return num_entries_needed > io_sq->entries_in_tx_burst_left; @@ -176,13 +151,13 @@ u16 max_entries_in_tx_burst = io_sq->llq_info.max_entries_in_tx_burst; u16 tail = io_sq->tail; - pr_debug("write submission queue doorbell for queue: %d tail: %d\n", + pr_debug("Write submission queue doorbell for queue: %d tail: %d\n", io_sq->qid, tail); writel(tail, io_sq->db_addr); if (is_llq_max_tx_burst_exists(io_sq)) { - pr_debug("reset available entries in tx burst for queue %d to %d\n", + pr_debug("Reset available entries in tx burst for queue %d to %d\n", io_sq->qid, max_entries_in_tx_burst); io_sq->entries_in_tx_burst_left = max_entries_in_tx_burst; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef _ENA_ETH_IO_H_ #define _ENA_ETH_IO_H_ @@ -264,7 +237,9 @@ u16 sub_qid; - u16 reserved; + u8 offset; + + u8 reserved; }; /* 8-word format */ @@ -412,4 +387,4 @@ #define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31 #define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31) -#endif /*_ENA_ETH_IO_H_ */ +#endif /* _ENA_ETH_IO_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_ethtool.c @@ -1,33 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #include @@ -41,12 +14,17 @@ #define ENA_STAT_ENA_COM_ENTRY(stat) { \ .name = #stat, \ - .stat_offset = offsetof(struct ena_com_stats_admin, stat) \ + .stat_offset = offsetof(struct ena_com_stats_admin, stat) / sizeof(u64) \ } #define ENA_STAT_ENTRY(stat, stat_type) { \ .name = #stat, \ - .stat_offset = offsetof(struct ena_stats_##stat_type, stat) \ + .stat_offset = offsetof(struct ena_stats_##stat_type, stat) / sizeof(u64) \ +} + +#define ENA_STAT_HW_ENTRY(stat, stat_type) { \ + .name = #stat, \ + .stat_offset = offsetof(struct ena_admin_##stat_type, stat) / sizeof(u64) \ } #define ENA_STAT_RX_ENTRY(stat) \ @@ -58,6 +36,9 @@ #define ENA_STAT_GLOBAL_ENTRY(stat) \ ENA_STAT_ENTRY(stat, dev) +#define ENA_STAT_ENI_ENTRY(stat) \ + ENA_STAT_HW_ENTRY(stat, eni_stats) + static const struct ena_stats ena_stats_global_strings[] = { ENA_STAT_GLOBAL_ENTRY(tx_timeout), ENA_STAT_GLOBAL_ENTRY(suspend), @@ -68,6 +49,14 @@ ENA_STAT_GLOBAL_ENTRY(admin_q_pause), }; +static const struct ena_stats ena_stats_eni_strings[] = { + ENA_STAT_ENI_ENTRY(bw_in_allowance_exceeded), + ENA_STAT_ENI_ENTRY(bw_out_allowance_exceeded), + ENA_STAT_ENI_ENTRY(pps_allowance_exceeded), + ENA_STAT_ENI_ENTRY(conntrack_allowance_exceeded), + ENA_STAT_ENI_ENTRY(linklocal_allowance_exceeded), +}; + static const struct ena_stats ena_stats_tx_strings[] = { ENA_STAT_TX_ENTRY(cnt), ENA_STAT_TX_ENTRY(bytes), @@ -83,6 +72,7 @@ ENA_STAT_TX_ENTRY(bad_req_id), ENA_STAT_TX_ENTRY(llq_buffer_copy), ENA_STAT_TX_ENTRY(missed_tx), + ENA_STAT_TX_ENTRY(unmask_interrupt), }; static const struct ena_stats ena_stats_rx_strings[] = { @@ -99,6 +89,11 @@ ENA_STAT_RX_ENTRY(bad_req_id), ENA_STAT_RX_ENTRY(empty_rx_ring), ENA_STAT_RX_ENTRY(csum_unchecked), + ENA_STAT_RX_ENTRY(xdp_aborted), + ENA_STAT_RX_ENTRY(xdp_drop), + ENA_STAT_RX_ENTRY(xdp_pass), + ENA_STAT_RX_ENTRY(xdp_tx), + ENA_STAT_RX_ENTRY(xdp_invalid), }; static const struct ena_stats ena_stats_ena_com_strings[] = { @@ -109,10 +104,12 @@ ENA_STAT_ENA_COM_ENTRY(no_completion), }; -#define ENA_STATS_ARRAY_GLOBAL ARRAY_SIZE(ena_stats_global_strings) -#define ENA_STATS_ARRAY_TX ARRAY_SIZE(ena_stats_tx_strings) -#define ENA_STATS_ARRAY_RX ARRAY_SIZE(ena_stats_rx_strings) -#define ENA_STATS_ARRAY_ENA_COM ARRAY_SIZE(ena_stats_ena_com_strings) +#define ENA_STATS_ARRAY_GLOBAL ARRAY_SIZE(ena_stats_global_strings) +#define ENA_STATS_ARRAY_TX ARRAY_SIZE(ena_stats_tx_strings) +#define ENA_STATS_ARRAY_RX ARRAY_SIZE(ena_stats_rx_strings) +#define ENA_STATS_ARRAY_ENA_COM ARRAY_SIZE(ena_stats_ena_com_strings) +#define ENA_STATS_ARRAY_ENI(adapter) \ + (ARRAY_SIZE(ena_stats_eni_strings) * (adapter)->eni_stats_supported) static void ena_safe_update_stat(u64 *src, u64 *dst, struct u64_stats_sync *syncp) @@ -133,29 +130,30 @@ u64 *ptr; int i, j; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues + adapter->xdp_num_queues; i++) { /* Tx stats */ ring = &adapter->tx_ring[i]; for (j = 0; j < ENA_STATS_ARRAY_TX; j++) { ena_stats = &ena_stats_tx_strings[j]; - ptr = (u64 *)((uintptr_t)&ring->tx_stats + - (uintptr_t)ena_stats->stat_offset); + ptr = (u64 *)&ring->tx_stats + ena_stats->stat_offset; ena_safe_update_stat(ptr, (*data)++, &ring->syncp); } + /* XDP TX queues don't have a RX queue counterpart */ + if (!ENA_IS_XDP_INDEX(adapter, i)) { + /* Rx stats */ + ring = &adapter->rx_ring[i]; - /* Rx stats */ - ring = &adapter->rx_ring[i]; - - for (j = 0; j < ENA_STATS_ARRAY_RX; j++) { - ena_stats = &ena_stats_rx_strings[j]; + for (j = 0; j < ENA_STATS_ARRAY_RX; j++) { + ena_stats = &ena_stats_rx_strings[j]; - ptr = (u64 *)((uintptr_t)&ring->rx_stats + - (uintptr_t)ena_stats->stat_offset); + ptr = (u64 *)&ring->rx_stats + + ena_stats->stat_offset; - ena_safe_update_stat(ptr, (*data)++, &ring->syncp); + ena_safe_update_stat(ptr, (*data)++, &ring->syncp); + } } } } @@ -163,24 +161,23 @@ static void ena_dev_admin_queue_stats(struct ena_adapter *adapter, u64 **data) { const struct ena_stats *ena_stats; - u32 *ptr; + u64 *ptr; int i; for (i = 0; i < ENA_STATS_ARRAY_ENA_COM; i++) { ena_stats = &ena_stats_ena_com_strings[i]; - ptr = (u32 *)((uintptr_t)&adapter->ena_dev->admin_queue.stats + - (uintptr_t)ena_stats->stat_offset); + ptr = (u64 *)&adapter->ena_dev->admin_queue.stats + + ena_stats->stat_offset; *(*data)++ = *ptr; } } -static void ena_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, - u64 *data) +static void ena_get_stats(struct ena_adapter *adapter, + u64 *data, + bool eni_stats_needed) { - struct ena_adapter *adapter = netdev_priv(netdev); const struct ena_stats *ena_stats; u64 *ptr; int i; @@ -188,16 +185,48 @@ for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) { ena_stats = &ena_stats_global_strings[i]; - ptr = (u64 *)((uintptr_t)&adapter->dev_stats + - (uintptr_t)ena_stats->stat_offset); + ptr = (u64 *)&adapter->dev_stats + ena_stats->stat_offset; ena_safe_update_stat(ptr, data++, &adapter->syncp); } + if (eni_stats_needed) { + ena_update_hw_stats(adapter); + for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) { + ena_stats = &ena_stats_eni_strings[i]; + + ptr = (u64 *)&adapter->eni_stats + + ena_stats->stat_offset; + + ena_safe_update_stat(ptr, data++, &adapter->syncp); + } + } + ena_queue_stats(adapter, &data); ena_dev_admin_queue_stats(adapter, &data); } +static void ena_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, + u64 *data) +{ + struct ena_adapter *adapter = netdev_priv(netdev); + + ena_get_stats(adapter, data, adapter->eni_stats_supported); +} + +static int ena_get_sw_stats_count(struct ena_adapter *adapter) +{ + return adapter->num_io_queues * (ENA_STATS_ARRAY_TX + ENA_STATS_ARRAY_RX) + + adapter->xdp_num_queues * ENA_STATS_ARRAY_TX + + ENA_STATS_ARRAY_GLOBAL + ENA_STATS_ARRAY_ENA_COM; +} + +static int ena_get_hw_stats_count(struct ena_adapter *adapter) +{ + return ENA_STATS_ARRAY_ENI(adapter); +} + int ena_get_sset_count(struct net_device *netdev, int sset) { struct ena_adapter *adapter = netdev_priv(netdev); @@ -205,31 +234,38 @@ if (sset != ETH_SS_STATS) return -EOPNOTSUPP; - return adapter->num_queues * (ENA_STATS_ARRAY_TX + ENA_STATS_ARRAY_RX) - + ENA_STATS_ARRAY_GLOBAL + ENA_STATS_ARRAY_ENA_COM; + return ena_get_sw_stats_count(adapter) + ena_get_hw_stats_count(adapter); } static void ena_queue_strings(struct ena_adapter *adapter, u8 **data) { const struct ena_stats *ena_stats; + bool is_xdp; int i, j; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues + adapter->xdp_num_queues; i++) { + is_xdp = ENA_IS_XDP_INDEX(adapter, i); /* Tx stats */ for (j = 0; j < ENA_STATS_ARRAY_TX; j++) { ena_stats = &ena_stats_tx_strings[j]; snprintf(*data, ETH_GSTRING_LEN, - "queue_%u_tx_%s", i, ena_stats->name); - (*data) += ETH_GSTRING_LEN; + "queue_%u_%s_%s", i, + is_xdp ? "xdp_tx" : "tx", ena_stats->name); + (*data) += ETH_GSTRING_LEN; } - /* Rx stats */ - for (j = 0; j < ENA_STATS_ARRAY_RX; j++) { - ena_stats = &ena_stats_rx_strings[j]; - snprintf(*data, ETH_GSTRING_LEN, - "queue_%u_rx_%s", i, ena_stats->name); - (*data) += ETH_GSTRING_LEN; + if (!is_xdp) { + /* RX stats, in XDP there isn't a RX queue + * counterpart + */ + for (j = 0; j < ENA_STATS_ARRAY_RX; j++) { + ena_stats = &ena_stats_rx_strings[j]; + + snprintf(*data, ETH_GSTRING_LEN, + "queue_%u_rx_%s", i, ena_stats->name); + (*data) += ETH_GSTRING_LEN; + } } } } @@ -248,26 +284,43 @@ } } -static void ena_get_strings(struct net_device *netdev, u32 sset, u8 *data) +static void ena_get_strings(struct ena_adapter *adapter, + u8 *data, + bool eni_stats_needed) { - struct ena_adapter *adapter = netdev_priv(netdev); const struct ena_stats *ena_stats; int i; - if (sset != ETH_SS_STATS) - return; - for (i = 0; i < ENA_STATS_ARRAY_GLOBAL; i++) { ena_stats = &ena_stats_global_strings[i]; - memcpy(data, ena_stats->name, ETH_GSTRING_LEN); data += ETH_GSTRING_LEN; } + if (eni_stats_needed) { + for (i = 0; i < ENA_STATS_ARRAY_ENI(adapter); i++) { + ena_stats = &ena_stats_eni_strings[i]; + memcpy(data, ena_stats->name, ETH_GSTRING_LEN); + data += ETH_GSTRING_LEN; + } + } + ena_queue_strings(adapter, &data); ena_com_dev_strings(&data); } +static void ena_get_ethtool_strings(struct net_device *netdev, + u32 sset, + u8 *data) +{ + struct ena_adapter *adapter = netdev_priv(netdev); + + if (sset != ETH_SS_STATS) + return; + + ena_get_strings(adapter, data, adapter->eni_stats_supported); +} + static int ena_get_link_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *link_ksettings) { @@ -306,19 +359,16 @@ struct ena_adapter *adapter = netdev_priv(net_dev); struct ena_com_dev *ena_dev = adapter->ena_dev; - if (!ena_com_interrupt_moderation_supported(ena_dev)) { - /* the devie doesn't support interrupt moderation */ + if (!ena_com_interrupt_moderation_supported(ena_dev)) return -EOPNOTSUPP; - } coalesce->tx_coalesce_usecs = ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) * ena_dev->intr_delay_resolution; - if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) - coalesce->rx_coalesce_usecs = - ena_com_get_nonadaptive_moderation_interval_rx(ena_dev) - * ena_dev->intr_delay_resolution; + coalesce->rx_coalesce_usecs = + ena_com_get_nonadaptive_moderation_interval_rx(ena_dev) + * ena_dev->intr_delay_resolution; coalesce->use_adaptive_rx_coalesce = ena_com_get_adaptive_moderation_enabled(ena_dev); @@ -326,25 +376,25 @@ return 0; } -static void ena_update_tx_rings_intr_moderation(struct ena_adapter *adapter) +static void ena_update_tx_rings_nonadaptive_intr_moderation(struct ena_adapter *adapter) { unsigned int val; int i; val = ena_com_get_nonadaptive_moderation_interval_tx(adapter->ena_dev); - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) adapter->tx_ring[i].smoothed_interval = val; } -static void ena_update_rx_rings_intr_moderation(struct ena_adapter *adapter) +static void ena_update_rx_rings_nonadaptive_intr_moderation(struct ena_adapter *adapter) { unsigned int val; int i; val = ena_com_get_nonadaptive_moderation_interval_rx(adapter->ena_dev); - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) adapter->rx_ring[i].smoothed_interval = val; } @@ -355,35 +405,30 @@ struct ena_com_dev *ena_dev = adapter->ena_dev; int rc; - if (!ena_com_interrupt_moderation_supported(ena_dev)) { - /* the devie doesn't support interrupt moderation */ + if (!ena_com_interrupt_moderation_supported(ena_dev)) return -EOPNOTSUPP; - } rc = ena_com_update_nonadaptive_moderation_interval_tx(ena_dev, coalesce->tx_coalesce_usecs); if (rc) return rc; - ena_update_tx_rings_intr_moderation(adapter); - - if (coalesce->use_adaptive_rx_coalesce) { - if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) - ena_com_enable_adaptive_moderation(ena_dev); - return 0; - } + ena_update_tx_rings_nonadaptive_intr_moderation(adapter); rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev, coalesce->rx_coalesce_usecs); if (rc) return rc; - ena_update_rx_rings_intr_moderation(adapter); + ena_update_rx_rings_nonadaptive_intr_moderation(adapter); - if (!coalesce->use_adaptive_rx_coalesce) { - if (ena_com_get_adaptive_moderation_enabled(ena_dev)) - ena_com_disable_adaptive_moderation(ena_dev); - } + if ((coalesce->use_adaptive_rx_coalesce) && + (!ena_com_get_adaptive_moderation_enabled(ena_dev))) + ena_com_enable_adaptive_moderation(ena_dev); + + if ((!coalesce->use_adaptive_rx_coalesce) && + (ena_com_get_adaptive_moderation_enabled(ena_dev))) + ena_com_disable_adaptive_moderation(ena_dev); return 0; } @@ -408,7 +453,6 @@ struct ena_adapter *adapter = netdev_priv(dev); strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver)); - strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); strlcpy(info->bus_info, pci_name(adapter->pdev), sizeof(info->bus_info)); } @@ -612,7 +656,7 @@ switch (info->cmd) { case ETHTOOL_GRXRINGS: - info->data = adapter->num_queues; + info->data = adapter->num_io_queues; rc = 0; break; case ETHTOOL_GRXFH: @@ -640,6 +684,54 @@ return ENA_HASH_KEY_SIZE; } +static int ena_indirection_table_set(struct ena_adapter *adapter, + const u32 *indir) +{ + struct ena_com_dev *ena_dev = adapter->ena_dev; + int i, rc; + + for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) { + rc = ena_com_indirect_table_fill_entry(ena_dev, + i, + ENA_IO_RXQ_IDX(indir[i])); + if (unlikely(rc)) { + netif_err(adapter, drv, adapter->netdev, + "Cannot fill indirect table (index is too large)\n"); + return rc; + } + } + + rc = ena_com_indirect_table_set(ena_dev); + if (rc) { + netif_err(adapter, drv, adapter->netdev, + "Cannot set indirect table\n"); + return rc == -EPERM ? -EOPNOTSUPP : rc; + } + return rc; +} + +static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir) +{ + struct ena_com_dev *ena_dev = adapter->ena_dev; + int i, rc; + + if (!indir) + return 0; + + rc = ena_com_indirect_table_get(ena_dev, indir); + if (rc) + return rc; + + /* Our internal representation of the indices is: even indices + * for Tx and uneven indices for Rx. We need to convert the Rx + * indices to be consecutive + */ + for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) + indir[i] = ENA_IO_RXQ_IDX_TO_COMBINED_IDX(indir[i]); + + return rc; +} + static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) { @@ -648,11 +740,22 @@ u8 func; int rc; - rc = ena_com_indirect_table_get(adapter->ena_dev, indir); + rc = ena_indirection_table_get(adapter, indir); if (rc) return rc; - rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func, key); + /* We call this function in order to check if the device + * supports getting/setting the hash function. + */ + rc = ena_com_get_hash_function(adapter->ena_dev, &ena_func); + if (rc) { + if (rc == -EOPNOTSUPP) + rc = 0; + + return rc; + } + + rc = ena_com_get_hash_key(adapter->ena_dev, key); if (rc) return rc; @@ -661,7 +764,7 @@ func = ETH_RSS_HASH_TOP; break; case ENA_ADMIN_CRC32: - func = ETH_RSS_HASH_XOR; + func = ETH_RSS_HASH_CRC32; break; default: netif_err(adapter, drv, netdev, @@ -672,7 +775,7 @@ if (hfunc) *hfunc = func; - return rc; + return 0; } static int ena_set_rxfh(struct net_device *netdev, const u32 *indir, @@ -680,34 +783,23 @@ { struct ena_adapter *adapter = netdev_priv(netdev); struct ena_com_dev *ena_dev = adapter->ena_dev; - enum ena_admin_hash_functions func; - int rc, i; + enum ena_admin_hash_functions func = 0; + int rc; if (indir) { - for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) { - rc = ena_com_indirect_table_fill_entry(ena_dev, - i, - ENA_IO_RXQ_IDX(indir[i])); - if (unlikely(rc)) { - netif_err(adapter, drv, netdev, - "Cannot fill indirect table (index is too large)\n"); - return rc; - } - } - - rc = ena_com_indirect_table_set(ena_dev); - if (rc) { - netif_err(adapter, drv, netdev, - "Cannot set indirect table\n"); - return rc == -EPERM ? -EOPNOTSUPP : rc; - } + rc = ena_indirection_table_set(adapter, indir); + if (rc) + return rc; } switch (hfunc) { + case ETH_RSS_HASH_NO_CHANGE: + func = ena_com_get_current_hash_function(ena_dev); + break; case ETH_RSS_HASH_TOP: func = ENA_ADMIN_TOEPLITZ; break; - case ETH_RSS_HASH_XOR: + case ETH_RSS_HASH_CRC32: func = ENA_ADMIN_CRC32; break; default: @@ -716,7 +808,7 @@ return -EOPNOTSUPP; } - if (key) { + if (key || func) { rc = ena_com_fill_hash_function(ena_dev, func, key, ENA_HASH_KEY_SIZE, 0xFFFFFFFF); @@ -734,14 +826,22 @@ { struct ena_adapter *adapter = netdev_priv(netdev); - channels->max_rx = adapter->num_queues; - channels->max_tx = adapter->num_queues; - channels->max_other = 0; - channels->max_combined = 0; - channels->rx_count = adapter->num_queues; - channels->tx_count = adapter->num_queues; - channels->other_count = 0; - channels->combined_count = 0; + channels->max_combined = adapter->max_num_io_queues; + channels->combined_count = adapter->num_io_queues; +} + +static int ena_set_channels(struct net_device *netdev, + struct ethtool_channels *channels) +{ + struct ena_adapter *adapter = netdev_priv(netdev); + u32 count = channels->combined_count; + /* The check for max value is already done in ethtool */ + if (count < ENA_MIN_NUM_IO_QUEUES || + (ena_xdp_present(adapter) && + !ena_xdp_legal_queue_count(adapter, channels->combined_count))) + return -EINVAL; + + return ena_update_queue_count(adapter, count); } static int ena_get_tunable(struct net_device *netdev, @@ -798,7 +898,7 @@ .get_ringparam = ena_get_ringparam, .set_ringparam = ena_set_ringparam, .get_sset_count = ena_get_sset_count, - .get_strings = ena_get_strings, + .get_strings = ena_get_ethtool_strings, .get_ethtool_stats = ena_get_ethtool_stats, .get_rxnfc = ena_get_rxnfc, .set_rxnfc = ena_set_rxnfc, @@ -807,8 +907,10 @@ .get_rxfh = ena_get_rxfh, .set_rxfh = ena_set_rxfh, .get_channels = ena_get_channels, + .set_channels = ena_set_channels, .get_tunable = ena_get_tunable, .set_tunable = ena_set_tunable, + .get_ts_info = ethtool_op_get_ts_info, }; void ena_set_ethtool_ops(struct net_device *netdev) @@ -824,7 +926,7 @@ int strings_num; int i, rc; - strings_num = ena_get_sset_count(netdev, ETH_SS_STATS); + strings_num = ena_get_sw_stats_count(adapter); if (strings_num <= 0) { netif_err(adapter, drv, netdev, "Can't get stats num\n"); return; @@ -835,7 +937,7 @@ GFP_ATOMIC); if (!strings_buf) { netif_err(adapter, drv, netdev, - "failed to alloc strings_buf\n"); + "Failed to allocate strings_buf\n"); return; } @@ -844,13 +946,13 @@ GFP_ATOMIC); if (!data_buf) { netif_err(adapter, drv, netdev, - "failed to allocate data buf\n"); + "Failed to allocate data buf\n"); devm_kfree(&adapter->pdev->dev, strings_buf); return; } - ena_get_strings(netdev, ETH_SS_STATS, strings_buf); - ena_get_ethtool_stats(netdev, NULL, data_buf); + ena_get_strings(adapter, strings_buf, false); + ena_get_stats(adapter, data_buf, false); /* If there is a buffer, dump stats, otherwise print them to dmesg */ if (buf) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -1,33 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -36,7 +9,6 @@ #include #endif /* CONFIG_RFS_ACCEL */ #include -#include #include #include #include @@ -47,14 +19,12 @@ #include #include "ena_netdev.h" +#include #include "ena_pci_id_tbl.h" -static char version[] = DEVICE_NAME " v" DRV_MODULE_VERSION "\n"; - MODULE_AUTHOR("Amazon.com, Inc. or its affiliates"); MODULE_DESCRIPTION(DEVICE_NAME); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_MODULE_VERSION); /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (5 * HZ) @@ -78,6 +48,36 @@ static void ena_destroy_device(struct ena_adapter *adapter, bool graceful); static int ena_restore_device(struct ena_adapter *adapter); +static void ena_init_io_rings(struct ena_adapter *adapter, + int first_index, int count); +static void ena_init_napi_in_range(struct ena_adapter *adapter, int first_index, + int count); +static void ena_del_napi_in_range(struct ena_adapter *adapter, int first_index, + int count); +static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid); +static int ena_setup_tx_resources_in_range(struct ena_adapter *adapter, + int first_index, + int count); +static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid); +static void ena_free_tx_resources(struct ena_adapter *adapter, int qid); +static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget); +static void ena_destroy_all_tx_queues(struct ena_adapter *adapter); +static void ena_free_all_io_tx_resources(struct ena_adapter *adapter); +static void ena_napi_disable_in_range(struct ena_adapter *adapter, + int first_index, int count); +static void ena_napi_enable_in_range(struct ena_adapter *adapter, + int first_index, int count); +static int ena_up(struct ena_adapter *adapter); +static void ena_down(struct ena_adapter *adapter); +static void ena_unmask_interrupt(struct ena_ring *tx_ring, + struct ena_ring *rx_ring); +static void ena_update_ring_numa_node(struct ena_ring *tx_ring, + struct ena_ring *rx_ring); +static void ena_unmap_tx_buff(struct ena_ring *tx_ring, + struct ena_tx_buffer *tx_info); +static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter, + int first_index, int count); + static void ena_tx_timeout(struct net_device *dev) { struct ena_adapter *adapter = netdev_priv(dev); @@ -101,7 +101,7 @@ { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) adapter->rx_ring[i].mtu = mtu; } @@ -112,7 +112,7 @@ ret = ena_com_set_dev_mtu(adapter->ena_dev, new_mtu); if (!ret) { - netif_dbg(adapter, drv, dev, "set MTU to %d\n", new_mtu); + netif_dbg(adapter, drv, dev, "Set MTU to %d\n", new_mtu); update_rx_ring_mtu(adapter, new_mtu); dev->mtu = new_mtu; } else { @@ -123,16 +123,472 @@ return ret; } +static int ena_xmit_common(struct net_device *dev, + struct ena_ring *ring, + struct ena_tx_buffer *tx_info, + struct ena_com_tx_ctx *ena_tx_ctx, + u16 next_to_use, + u32 bytes) +{ + struct ena_adapter *adapter = netdev_priv(dev); + int rc, nb_hw_desc; + + if (unlikely(ena_com_is_doorbell_needed(ring->ena_com_io_sq, + ena_tx_ctx))) { + netif_dbg(adapter, tx_queued, dev, + "llq tx max burst size of queue %d achieved, writing doorbell to send burst\n", + ring->qid); + ena_com_write_sq_doorbell(ring->ena_com_io_sq); + } + + /* prepare the packet's descriptors to dma engine */ + rc = ena_com_prepare_tx(ring->ena_com_io_sq, ena_tx_ctx, + &nb_hw_desc); + + /* In case there isn't enough space in the queue for the packet, + * we simply drop it. All other failure reasons of + * ena_com_prepare_tx() are fatal and therefore require a device reset. + */ + if (unlikely(rc)) { + netif_err(adapter, tx_queued, dev, + "Failed to prepare tx bufs\n"); + u64_stats_update_begin(&ring->syncp); + ring->tx_stats.prepare_ctx_err++; + u64_stats_update_end(&ring->syncp); + if (rc != -ENOMEM) { + adapter->reset_reason = + ENA_REGS_RESET_DRIVER_INVALID_STATE; + set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); + } + return rc; + } + + u64_stats_update_begin(&ring->syncp); + ring->tx_stats.cnt++; + ring->tx_stats.bytes += bytes; + u64_stats_update_end(&ring->syncp); + + tx_info->tx_descs = nb_hw_desc; + tx_info->last_jiffies = jiffies; + tx_info->print_once = 0; + + ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use, + ring->ring_size); + return 0; +} + +/* This is the XDP napi callback. XDP queues use a separate napi callback + * than Rx/Tx queues. + */ +static int ena_xdp_io_poll(struct napi_struct *napi, int budget) +{ + struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi); + u32 xdp_work_done, xdp_budget; + struct ena_ring *xdp_ring; + int napi_comp_call = 0; + int ret; + + xdp_ring = ena_napi->xdp_ring; + xdp_ring->first_interrupt = ena_napi->first_interrupt; + + xdp_budget = budget; + + if (!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags) || + test_bit(ENA_FLAG_TRIGGER_RESET, &xdp_ring->adapter->flags)) { + napi_complete_done(napi, 0); + return 0; + } + + xdp_work_done = ena_clean_xdp_irq(xdp_ring, xdp_budget); + + /* If the device is about to reset or down, avoid unmask + * the interrupt and return 0 so NAPI won't reschedule + */ + if (unlikely(!test_bit(ENA_FLAG_DEV_UP, &xdp_ring->adapter->flags))) { + napi_complete_done(napi, 0); + ret = 0; + } else if (xdp_budget > xdp_work_done) { + napi_comp_call = 1; + if (napi_complete_done(napi, xdp_work_done)) + ena_unmask_interrupt(xdp_ring, NULL); + ena_update_ring_numa_node(xdp_ring, NULL); + ret = xdp_work_done; + } else { + ret = xdp_budget; + } + + u64_stats_update_begin(&xdp_ring->syncp); + xdp_ring->tx_stats.napi_comp += napi_comp_call; + xdp_ring->tx_stats.tx_poll++; + u64_stats_update_end(&xdp_ring->syncp); + + return ret; +} + +static int ena_xdp_tx_map_buff(struct ena_ring *xdp_ring, + struct ena_tx_buffer *tx_info, + struct xdp_buff *xdp, + void **push_hdr, + u32 *push_len) +{ + struct ena_adapter *adapter = xdp_ring->adapter; + struct ena_com_buf *ena_buf; + dma_addr_t dma = 0; + u32 size; + + tx_info->xdpf = convert_to_xdp_frame(xdp); + size = tx_info->xdpf->len; + ena_buf = tx_info->bufs; + + /* llq push buffer */ + *push_len = min_t(u32, size, xdp_ring->tx_max_header_size); + *push_hdr = tx_info->xdpf->data; + + if (size - *push_len > 0) { + dma = dma_map_single(xdp_ring->dev, + *push_hdr + *push_len, + size - *push_len, + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(xdp_ring->dev, dma))) + goto error_report_dma_error; + + tx_info->map_linear_data = 1; + tx_info->num_of_bufs = 1; + } + + ena_buf->paddr = dma; + ena_buf->len = size; + + return 0; + +error_report_dma_error: + u64_stats_update_begin(&xdp_ring->syncp); + xdp_ring->tx_stats.dma_mapping_err++; + u64_stats_update_end(&xdp_ring->syncp); + netif_warn(adapter, tx_queued, adapter->netdev, "Failed to map xdp buff\n"); + + xdp_return_frame_rx_napi(tx_info->xdpf); + tx_info->xdpf = NULL; + tx_info->num_of_bufs = 0; + + return -EINVAL; +} + +static int ena_xdp_xmit_buff(struct net_device *dev, + struct xdp_buff *xdp, + int qid, + struct ena_rx_buffer *rx_info) +{ + struct ena_adapter *adapter = netdev_priv(dev); + struct ena_com_tx_ctx ena_tx_ctx = {}; + struct ena_tx_buffer *tx_info; + struct ena_ring *xdp_ring; + u16 next_to_use, req_id; + int rc; + void *push_hdr; + u32 push_len; + + xdp_ring = &adapter->tx_ring[qid]; + next_to_use = xdp_ring->next_to_use; + req_id = xdp_ring->free_ids[next_to_use]; + tx_info = &xdp_ring->tx_buffer_info[req_id]; + tx_info->num_of_bufs = 0; + page_ref_inc(rx_info->page); + tx_info->xdp_rx_page = rx_info->page; + + rc = ena_xdp_tx_map_buff(xdp_ring, tx_info, xdp, &push_hdr, &push_len); + if (unlikely(rc)) + goto error_drop_packet; + + ena_tx_ctx.ena_bufs = tx_info->bufs; + ena_tx_ctx.push_header = push_hdr; + ena_tx_ctx.num_bufs = tx_info->num_of_bufs; + ena_tx_ctx.req_id = req_id; + ena_tx_ctx.header_len = push_len; + + rc = ena_xmit_common(dev, + xdp_ring, + tx_info, + &ena_tx_ctx, + next_to_use, + xdp->data_end - xdp->data); + if (rc) + goto error_unmap_dma; + /* trigger the dma engine. ena_com_write_sq_doorbell() + * has a mb + */ + ena_com_write_sq_doorbell(xdp_ring->ena_com_io_sq); + u64_stats_update_begin(&xdp_ring->syncp); + xdp_ring->tx_stats.doorbells++; + u64_stats_update_end(&xdp_ring->syncp); + + return NETDEV_TX_OK; + +error_unmap_dma: + ena_unmap_tx_buff(xdp_ring, tx_info); + tx_info->xdpf = NULL; +error_drop_packet: + __free_page(tx_info->xdp_rx_page); + return NETDEV_TX_OK; +} + +static int ena_xdp_execute(struct ena_ring *rx_ring, + struct xdp_buff *xdp, + struct ena_rx_buffer *rx_info) +{ + struct bpf_prog *xdp_prog; + u32 verdict = XDP_PASS; + u64 *xdp_stat; + + rcu_read_lock(); + xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog); + + if (!xdp_prog) + goto out; + + verdict = bpf_prog_run_xdp(xdp_prog, xdp); + + if (verdict == XDP_TX) { + ena_xdp_xmit_buff(rx_ring->netdev, + xdp, + rx_ring->qid + rx_ring->adapter->num_io_queues, + rx_info); + + xdp_stat = &rx_ring->rx_stats.xdp_tx; + } else if (unlikely(verdict == XDP_ABORTED)) { + trace_xdp_exception(rx_ring->netdev, xdp_prog, verdict); + xdp_stat = &rx_ring->rx_stats.xdp_aborted; + } else if (unlikely(verdict == XDP_DROP)) { + xdp_stat = &rx_ring->rx_stats.xdp_drop; + } else if (unlikely(verdict == XDP_PASS)) { + xdp_stat = &rx_ring->rx_stats.xdp_pass; + } else { + bpf_warn_invalid_xdp_action(verdict); + xdp_stat = &rx_ring->rx_stats.xdp_invalid; + } + + u64_stats_update_begin(&rx_ring->syncp); + (*xdp_stat)++; + u64_stats_update_end(&rx_ring->syncp); +out: + rcu_read_unlock(); + + return verdict; +} + +static void ena_init_all_xdp_queues(struct ena_adapter *adapter) +{ + adapter->xdp_first_ring = adapter->num_io_queues; + adapter->xdp_num_queues = adapter->num_io_queues; + + ena_init_io_rings(adapter, + adapter->xdp_first_ring, + adapter->xdp_num_queues); +} + +static int ena_setup_and_create_all_xdp_queues(struct ena_adapter *adapter) +{ + int rc = 0; + + rc = ena_setup_tx_resources_in_range(adapter, adapter->xdp_first_ring, + adapter->xdp_num_queues); + if (rc) + goto setup_err; + + rc = ena_create_io_tx_queues_in_range(adapter, + adapter->xdp_first_ring, + adapter->xdp_num_queues); + if (rc) + goto create_err; + + return 0; + +create_err: + ena_free_all_io_tx_resources(adapter); +setup_err: + return rc; +} + +/* Provides a way for both kernel and bpf-prog to know + * more about the RX-queue a given XDP frame arrived on. + */ +static int ena_xdp_register_rxq_info(struct ena_ring *rx_ring) +{ + int rc; + + rc = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, rx_ring->qid); + + if (rc) { + netif_err(rx_ring->adapter, ifup, rx_ring->netdev, + "Failed to register xdp rx queue info. RX queue num %d rc: %d\n", + rx_ring->qid, rc); + goto err; + } + + rc = xdp_rxq_info_reg_mem_model(&rx_ring->xdp_rxq, MEM_TYPE_PAGE_SHARED, + NULL); + + if (rc) { + netif_err(rx_ring->adapter, ifup, rx_ring->netdev, + "Failed to register xdp rx queue info memory model. RX queue num %d rc: %d\n", + rx_ring->qid, rc); + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); + } + +err: + return rc; +} + +static void ena_xdp_unregister_rxq_info(struct ena_ring *rx_ring) +{ + xdp_rxq_info_unreg_mem_model(&rx_ring->xdp_rxq); + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); +} + +static void ena_xdp_exchange_program_rx_in_range(struct ena_adapter *adapter, + struct bpf_prog *prog, + int first, int count) +{ + struct ena_ring *rx_ring; + int i = 0; + + for (i = first; i < count; i++) { + rx_ring = &adapter->rx_ring[i]; + xchg(&rx_ring->xdp_bpf_prog, prog); + if (prog) { + ena_xdp_register_rxq_info(rx_ring); + rx_ring->rx_headroom = XDP_PACKET_HEADROOM; + } else { + ena_xdp_unregister_rxq_info(rx_ring); + rx_ring->rx_headroom = 0; + } + } +} + +static void ena_xdp_exchange_program(struct ena_adapter *adapter, + struct bpf_prog *prog) +{ + struct bpf_prog *old_bpf_prog = xchg(&adapter->xdp_bpf_prog, prog); + + ena_xdp_exchange_program_rx_in_range(adapter, + prog, + 0, + adapter->num_io_queues); + + if (old_bpf_prog) + bpf_prog_put(old_bpf_prog); +} + +static int ena_destroy_and_free_all_xdp_queues(struct ena_adapter *adapter) +{ + bool was_up; + int rc; + + was_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); + + if (was_up) + ena_down(adapter); + + adapter->xdp_first_ring = 0; + adapter->xdp_num_queues = 0; + ena_xdp_exchange_program(adapter, NULL); + if (was_up) { + rc = ena_up(adapter); + if (rc) + return rc; + } + return 0; +} + +static int ena_xdp_set(struct net_device *netdev, struct netdev_bpf *bpf) +{ + struct ena_adapter *adapter = netdev_priv(netdev); + struct bpf_prog *prog = bpf->prog; + struct bpf_prog *old_bpf_prog; + int rc, prev_mtu; + bool is_up; + + is_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); + rc = ena_xdp_allowed(adapter); + if (rc == ENA_XDP_ALLOWED) { + old_bpf_prog = adapter->xdp_bpf_prog; + if (prog) { + if (!is_up) { + ena_init_all_xdp_queues(adapter); + } else if (!old_bpf_prog) { + ena_down(adapter); + ena_init_all_xdp_queues(adapter); + } + ena_xdp_exchange_program(adapter, prog); + + if (is_up && !old_bpf_prog) { + rc = ena_up(adapter); + if (rc) + return rc; + } + } else if (old_bpf_prog) { + rc = ena_destroy_and_free_all_xdp_queues(adapter); + if (rc) + return rc; + } + + prev_mtu = netdev->max_mtu; + netdev->max_mtu = prog ? ENA_XDP_MAX_MTU : adapter->max_mtu; + + if (!old_bpf_prog) + netif_info(adapter, drv, adapter->netdev, + "XDP program is set, changing the max_mtu from %d to %d", + prev_mtu, netdev->max_mtu); + + } else if (rc == ENA_XDP_CURRENT_MTU_TOO_LARGE) { + netif_err(adapter, drv, adapter->netdev, + "Failed to set xdp program, the current MTU (%d) is larger than the maximum allowed MTU (%lu) while xdp is on", + netdev->mtu, ENA_XDP_MAX_MTU); + NL_SET_ERR_MSG_MOD(bpf->extack, + "Failed to set xdp program, the current MTU is larger than the maximum allowed MTU. Check the dmesg for more info"); + return -EINVAL; + } else if (rc == ENA_XDP_NO_ENOUGH_QUEUES) { + netif_err(adapter, drv, adapter->netdev, + "Failed to set xdp program, the Rx/Tx channel count should be at most half of the maximum allowed channel count. The current queue count (%d), the maximal queue count (%d)\n", + adapter->num_io_queues, adapter->max_num_io_queues); + NL_SET_ERR_MSG_MOD(bpf->extack, + "Failed to set xdp program, there is no enough space for allocating XDP queues, Check the dmesg for more info"); + return -EINVAL; + } + + return 0; +} + +/* This is the main xdp callback, it's used by the kernel to set/unset the xdp + * program as well as to query the current xdp program id. + */ +static int ena_xdp(struct net_device *netdev, struct netdev_bpf *bpf) +{ + struct ena_adapter *adapter = netdev_priv(netdev); + + switch (bpf->command) { + case XDP_SETUP_PROG: + return ena_xdp_set(netdev, bpf); + case XDP_QUERY_PROG: + bpf->prog_id = adapter->xdp_bpf_prog ? + adapter->xdp_bpf_prog->aux->id : 0; + break; + default: + return -EINVAL; + } + return 0; +} + static int ena_init_rx_cpu_rmap(struct ena_adapter *adapter) { #ifdef CONFIG_RFS_ACCEL u32 i; int rc; - adapter->netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(adapter->num_queues); + adapter->netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(adapter->num_io_queues); if (!adapter->netdev->rx_cpu_rmap) return -ENOMEM; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { int irq_idx = ENA_IO_IRQ_IDX(i); rc = irq_cpu_rmap_add(adapter->netdev->rx_cpu_rmap, @@ -164,7 +620,8 @@ u64_stats_init(&ring->syncp); } -static void ena_init_io_rings(struct ena_adapter *adapter) +static void ena_init_io_rings(struct ena_adapter *adapter, + int first_index, int count) { struct ena_com_dev *ena_dev; struct ena_ring *txr, *rxr; @@ -172,13 +629,12 @@ ena_dev = adapter->ena_dev; - for (i = 0; i < adapter->num_queues; i++) { + for (i = first_index; i < first_index + count; i++) { txr = &adapter->tx_ring[i]; rxr = &adapter->rx_ring[i]; - /* TX/RX common ring state */ + /* TX common ring state */ ena_init_io_rings_common(adapter, txr, i); - ena_init_io_rings_common(adapter, rxr, i); /* TX specific ring state */ txr->ring_size = adapter->requested_tx_ring_size; @@ -187,15 +643,22 @@ txr->sgl_size = adapter->max_tx_sgl_size; txr->smoothed_interval = ena_com_get_nonadaptive_moderation_interval_tx(ena_dev); + txr->disable_meta_caching = adapter->disable_meta_caching; - /* RX specific ring state */ - rxr->ring_size = adapter->requested_rx_ring_size; - rxr->rx_copybreak = adapter->rx_copybreak; - rxr->sgl_size = adapter->max_rx_sgl_size; - rxr->smoothed_interval = - ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); - rxr->empty_rx_queue = 0; - adapter->ena_napi[i].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + /* Don't init RX queues for xdp queues */ + if (!ENA_IS_XDP_INDEX(adapter, i)) { + /* RX common ring state */ + ena_init_io_rings_common(adapter, rxr, i); + + /* RX specific ring state */ + rxr->ring_size = adapter->requested_rx_ring_size; + rxr->rx_copybreak = adapter->rx_copybreak; + rxr->sgl_size = adapter->max_rx_sgl_size; + rxr->smoothed_interval = + ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); + rxr->empty_rx_queue = 0; + adapter->ena_napi[i].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; + } } } @@ -285,16 +748,13 @@ tx_ring->push_buf_intermediate_buf = NULL; } -/* ena_setup_all_tx_resources - allocate I/O Tx queues resources for All queues - * @adapter: private structure - * - * Return 0 on success, negative on failure - */ -static int ena_setup_all_tx_resources(struct ena_adapter *adapter) +static int ena_setup_tx_resources_in_range(struct ena_adapter *adapter, + int first_index, + int count) { int i, rc = 0; - for (i = 0; i < adapter->num_queues; i++) { + for (i = first_index; i < first_index + count; i++) { rc = ena_setup_tx_resources(adapter, i); if (rc) goto err_setup_tx; @@ -308,40 +768,31 @@ "Tx queue %d: allocation failed\n", i); /* rewind the index freeing the rings as we go */ - while (i--) + while (first_index < i--) ena_free_tx_resources(adapter, i); return rc; } -/* ena_free_all_io_tx_resources - Free I/O Tx Resources for All Queues - * @adapter: board private structure - * - * Free all transmit software resources - */ -static void ena_free_all_io_tx_resources(struct ena_adapter *adapter) +static void ena_free_all_io_tx_resources_in_range(struct ena_adapter *adapter, + int first_index, int count) { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = first_index; i < first_index + count; i++) ena_free_tx_resources(adapter, i); } -static int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id) +/* ena_free_all_io_tx_resources - Free I/O Tx Resources for All Queues + * @adapter: board private structure + * + * Free all transmit software resources + */ +static void ena_free_all_io_tx_resources(struct ena_adapter *adapter) { - if (likely(req_id < rx_ring->ring_size)) - return 0; - - netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, - "Invalid rx req_id: %hu\n", req_id); - - u64_stats_update_begin(&rx_ring->syncp); - rx_ring->rx_stats.bad_req_id++; - u64_stats_update_end(&rx_ring->syncp); - - /* Trigger device reset */ - rx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID; - set_bit(ENA_FLAG_TRIGGER_RESET, &rx_ring->adapter->flags); - return -EFAULT; + ena_free_all_io_tx_resources_in_range(adapter, + 0, + adapter->xdp_num_queues + + adapter->num_io_queues); } /* ena_setup_rx_resources - allocate I/O Rx resources (Descriptors) @@ -428,7 +879,7 @@ { int i, rc = 0; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { rc = ena_setup_rx_resources(adapter, i); if (rc) goto err_setup_rx; @@ -456,17 +907,21 @@ { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) ena_free_rx_resources(adapter, i); } static int ena_alloc_rx_page(struct ena_ring *rx_ring, struct ena_rx_buffer *rx_info, gfp_t gfp) { + int headroom = rx_ring->rx_headroom; struct ena_com_buf *ena_buf; struct page *page; dma_addr_t dma; + /* restore page offset value in case it has been changed by device */ + rx_info->page_offset = headroom; + /* if previous allocated page is not used */ if (unlikely(rx_info->page)) return 0; @@ -479,8 +934,11 @@ return -ENOMEM; } + /* To enable NIC-side port-mirroring, AKA SPAN port, + * we make the buffer readable from the nic as well + */ dma = dma_map_page(rx_ring->dev, page, 0, ENA_PAGE_SIZE, - DMA_FROM_DEVICE); + DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(rx_ring->dev, dma))) { u64_stats_update_begin(&rx_ring->syncp); rx_ring->rx_stats.dma_mapping_err++; @@ -490,13 +948,12 @@ return -EIO; } netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, - "alloc page %p, rx_info %p\n", page, rx_info); + "Allocate page %p, rx_info %p\n", page, rx_info); rx_info->page = page; - rx_info->page_offset = 0; ena_buf = &rx_info->ena_buf; - ena_buf->paddr = dma; - ena_buf->len = ENA_PAGE_SIZE; + ena_buf->paddr = dma + headroom; + ena_buf->len = ENA_PAGE_SIZE - headroom; return 0; } @@ -513,8 +970,9 @@ return; } - dma_unmap_page(rx_ring->dev, ena_buf->paddr, ENA_PAGE_SIZE, - DMA_FROM_DEVICE); + dma_unmap_page(rx_ring->dev, ena_buf->paddr - rx_ring->rx_headroom, + ENA_PAGE_SIZE, + DMA_BIDIRECTIONAL); __free_page(page); rx_info->page = NULL; @@ -532,18 +990,14 @@ struct ena_rx_buffer *rx_info; req_id = rx_ring->free_ids[next_to_use]; - rc = validate_rx_req_id(rx_ring, req_id); - if (unlikely(rc < 0)) - break; rx_info = &rx_ring->rx_buffer_info[req_id]; - rc = ena_alloc_rx_page(rx_ring, rx_info, GFP_ATOMIC | __GFP_COMP); if (unlikely(rc < 0)) { netif_warn(rx_ring->adapter, rx_err, rx_ring->netdev, - "failed to alloc buffer for rx queue %d\n", + "Failed to allocate buffer for rx queue %d\n", rx_ring->qid); break; } @@ -552,7 +1006,7 @@ req_id); if (unlikely(rc)) { netif_warn(rx_ring->adapter, rx_status, rx_ring->netdev, - "failed to add buffer for rx queue %d\n", + "Failed to add buffer for rx queue %d\n", rx_ring->qid); break; } @@ -564,9 +1018,9 @@ u64_stats_update_begin(&rx_ring->syncp); rx_ring->rx_stats.refil_partial++; u64_stats_update_end(&rx_ring->syncp); - netdev_warn(rx_ring->netdev, - "refilled rx qid %d with only %d buffers (from %d)\n", - rx_ring->qid, i, num); + netif_warn(rx_ring->adapter, rx_err, rx_ring->netdev, + "Refilled rx qid %d with only %d buffers (from %d)\n", + rx_ring->qid, i, num); } /* ena_com_write_sq_doorbell issues a wmb() */ @@ -600,14 +1054,14 @@ struct ena_ring *rx_ring; int i, rc, bufs_num; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { rx_ring = &adapter->rx_ring[i]; bufs_num = rx_ring->ring_size - 1; rc = ena_refill_rx_bufs(rx_ring, bufs_num); if (unlikely(rc != bufs_num)) netif_warn(rx_ring->adapter, rx_status, rx_ring->netdev, - "refilling Queue %d failed. allocated %d buffers from: %d\n", + "Refilling Queue %d failed. allocated %d buffers from: %d\n", i, rc, bufs_num); } } @@ -616,12 +1070,12 @@ { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) ena_free_rx_bufs(adapter, i); } -static void ena_unmap_tx_skb(struct ena_ring *tx_ring, - struct ena_tx_buffer *tx_info) +static void ena_unmap_tx_buff(struct ena_ring *tx_ring, + struct ena_tx_buffer *tx_info) { struct ena_com_buf *ena_buf; u32 cnt; @@ -656,8 +1110,11 @@ static void ena_free_tx_bufs(struct ena_ring *tx_ring) { bool print_once = true; + bool is_xdp_ring; u32 i; + is_xdp_ring = ENA_IS_XDP_INDEX(tx_ring->adapter, tx_ring->qid); + for (i = 0; i < tx_ring->ring_size; i++) { struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i]; @@ -665,22 +1122,27 @@ continue; if (print_once) { - netdev_notice(tx_ring->netdev, - "free uncompleted tx skb qid %d idx 0x%x\n", - tx_ring->qid, i); + netif_notice(tx_ring->adapter, ifdown, tx_ring->netdev, + "Free uncompleted tx skb qid %d idx 0x%x\n", + tx_ring->qid, i); print_once = false; } else { - netdev_dbg(tx_ring->netdev, - "free uncompleted tx skb qid %d idx 0x%x\n", - tx_ring->qid, i); + netif_dbg(tx_ring->adapter, ifdown, tx_ring->netdev, + "Free uncompleted tx skb qid %d idx 0x%x\n", + tx_ring->qid, i); } - ena_unmap_tx_skb(tx_ring, tx_info); + ena_unmap_tx_buff(tx_ring, tx_info); - dev_kfree_skb_any(tx_info->skb); + if (is_xdp_ring) + xdp_return_frame(tx_info->xdpf); + else + dev_kfree_skb_any(tx_info->skb); } - netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, - tx_ring->qid)); + + if (!is_xdp_ring) + netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev, + tx_ring->qid)); } static void ena_free_all_tx_bufs(struct ena_adapter *adapter) @@ -688,7 +1150,7 @@ struct ena_ring *tx_ring; int i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues + adapter->xdp_num_queues; i++) { tx_ring = &adapter->tx_ring[i]; ena_free_tx_bufs(tx_ring); } @@ -699,7 +1161,7 @@ u16 ena_qid; int i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues + adapter->xdp_num_queues; i++) { ena_qid = ENA_IO_TXQ_IDX(i); ena_com_destroy_io_queue(adapter->ena_dev, ena_qid); } @@ -710,7 +1172,7 @@ u16 ena_qid; int i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { ena_qid = ENA_IO_RXQ_IDX(i); cancel_work_sync(&adapter->ena_napi[i].dim.work); ena_com_destroy_io_queue(adapter->ena_dev, ena_qid); @@ -723,6 +1185,32 @@ ena_destroy_all_rx_queues(adapter); } +static int handle_invalid_req_id(struct ena_ring *ring, u16 req_id, + struct ena_tx_buffer *tx_info, bool is_xdp) +{ + if (tx_info) + netif_err(ring->adapter, + tx_done, + ring->netdev, + "tx_info doesn't have valid %s", + is_xdp ? "xdp frame" : "skb"); + else + netif_err(ring->adapter, + tx_done, + ring->netdev, + "Invalid req_id: %hu\n", + req_id); + + u64_stats_update_begin(&ring->syncp); + ring->tx_stats.bad_req_id++; + u64_stats_update_end(&ring->syncp); + + /* Trigger device reset */ + ring->adapter->reset_reason = ENA_REGS_RESET_INV_TX_REQ_ID; + set_bit(ENA_FLAG_TRIGGER_RESET, &ring->adapter->flags); + return -EFAULT; +} + static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id) { struct ena_tx_buffer *tx_info = NULL; @@ -733,21 +1221,20 @@ return 0; } - if (tx_info) - netif_err(tx_ring->adapter, tx_done, tx_ring->netdev, - "tx_info doesn't have valid skb\n"); - else - netif_err(tx_ring->adapter, tx_done, tx_ring->netdev, - "Invalid req_id: %hu\n", req_id); + return handle_invalid_req_id(tx_ring, req_id, tx_info, false); +} - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->tx_stats.bad_req_id++; - u64_stats_update_end(&tx_ring->syncp); +static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id) +{ + struct ena_tx_buffer *tx_info = NULL; - /* Trigger device reset */ - tx_ring->adapter->reset_reason = ENA_REGS_RESET_INV_TX_REQ_ID; - set_bit(ENA_FLAG_TRIGGER_RESET, &tx_ring->adapter->flags); - return -EFAULT; + if (likely(req_id < xdp_ring->ring_size)) { + tx_info = &xdp_ring->tx_buffer_info[req_id]; + if (likely(tx_info->xdpf)) + return 0; + } + + return handle_invalid_req_id(xdp_ring, req_id, tx_info, true); } static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget) @@ -786,7 +1273,7 @@ tx_info->skb = NULL; tx_info->last_jiffies = 0; - ena_unmap_tx_skb(tx_ring, tx_info); + ena_unmap_tx_buff(tx_ring, tx_info); netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev, "tx_poll: q %d skb %p completed\n", tx_ring->qid, @@ -871,6 +1358,7 @@ len = ena_bufs[buf].len; req_id = ena_bufs[buf].req_id; + rx_info = &rx_ring->rx_buffer_info[req_id]; if (unlikely(!rx_info->page)) { @@ -885,7 +1373,8 @@ /* save virt address of first buffer */ va = page_address(rx_info->page) + rx_info->page_offset; - prefetch(va + NET_IP_ALIGN); + + prefetch(va); if (len <= rx_ring->rx_copybreak) { skb = ena_alloc_skb(rx_ring, false); @@ -893,7 +1382,7 @@ return NULL; netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, - "rx allocated small packet. len %d. data_len %d\n", + "RX allocated small packet. len %d. data_len %d\n", skb->len, skb->data_len); /* sync this buffer for CPU use */ @@ -922,13 +1411,13 @@ do { dma_unmap_page(rx_ring->dev, dma_unmap_addr(&rx_info->ena_buf, paddr), - ENA_PAGE_SIZE, DMA_FROM_DEVICE); + ENA_PAGE_SIZE, DMA_BIDIRECTIONAL); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page, rx_info->page_offset, len, ENA_PAGE_SIZE); netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, - "rx skb updated. len %d. data_len %d\n", + "RX skb updated. len %d. data_len %d\n", skb->len, skb->data_len); rx_info->page = NULL; @@ -943,6 +1432,7 @@ buf++; len = ena_bufs[buf].len; req_id = ena_bufs[buf].req_id; + rx_info = &rx_ring->rx_buffer_info[req_id]; } while (1); @@ -1037,6 +1527,32 @@ } } +static int ena_xdp_handle_buff(struct ena_ring *rx_ring, struct xdp_buff *xdp) +{ + struct ena_rx_buffer *rx_info; + int ret; + + rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; + xdp->data = page_address(rx_info->page) + rx_info->page_offset; + xdp_set_data_meta_invalid(xdp); + xdp->data_hard_start = page_address(rx_info->page); + xdp->data_end = xdp->data + rx_ring->ena_bufs[0].len; + /* If for some reason we received a bigger packet than + * we expect, then we simply drop it + */ + if (unlikely(rx_ring->ena_bufs[0].len > ENA_XDP_MAX_MTU)) + return XDP_DROP; + + ret = ena_xdp_execute(rx_ring, xdp, rx_info); + + /* The xdp program might expand the headers */ + if (ret == XDP_PASS) { + rx_info->page_offset = xdp->data - xdp->data_hard_start; + rx_ring->ena_bufs[0].len = xdp->data_end - xdp->data; + } + + return ret; +} /* ena_clean_rx_irq - Cleanup RX irq * @rx_ring: RX ring to clean * @napi: napi handler @@ -1048,26 +1564,32 @@ u32 budget) { u16 next_to_clean = rx_ring->next_to_clean; - u32 res_budget, work_done; - struct ena_com_rx_ctx ena_rx_ctx; + struct ena_rx_buffer *rx_info; struct ena_adapter *adapter; + u32 res_budget, work_done; + int rx_copybreak_pkt = 0; + int refill_threshold; struct sk_buff *skb; int refill_required; - int refill_threshold; - int rc = 0; + struct xdp_buff xdp; int total_len = 0; - int rx_copybreak_pkt = 0; + int xdp_verdict; + int rc = 0; int i; netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, "%s qid %d\n", __func__, rx_ring->qid); res_budget = budget; + xdp.rxq = &rx_ring->xdp_rxq; do { + xdp_verdict = XDP_PASS; + skb = NULL; ena_rx_ctx.ena_bufs = rx_ring->ena_bufs; ena_rx_ctx.max_bufs = rx_ring->sgl_size; ena_rx_ctx.descs = 0; + ena_rx_ctx.pkt_offset = 0; rc = ena_com_rx_pkt(rx_ring->ena_com_io_cq, rx_ring->ena_com_io_sq, &ena_rx_ctx); @@ -1077,17 +1599,34 @@ if (unlikely(ena_rx_ctx.descs == 0)) break; + /* First descriptor might have an offset set by the device */ + rx_info = &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]; + rx_info->page_offset += ena_rx_ctx.pkt_offset; + netif_dbg(rx_ring->adapter, rx_status, rx_ring->netdev, "rx_poll: q %d got packet from ena. descs #: %d l3 proto %d l4 proto %d hash: %x\n", rx_ring->qid, ena_rx_ctx.descs, ena_rx_ctx.l3_proto, ena_rx_ctx.l4_proto, ena_rx_ctx.hash); + if (ena_xdp_present_ring(rx_ring)) + xdp_verdict = ena_xdp_handle_buff(rx_ring, &xdp); + /* allocate skb and fill it */ - skb = ena_rx_skb(rx_ring, rx_ring->ena_bufs, ena_rx_ctx.descs, - &next_to_clean); + if (xdp_verdict == XDP_PASS) + skb = ena_rx_skb(rx_ring, + rx_ring->ena_bufs, + ena_rx_ctx.descs, + &next_to_clean); - /* exit if we failed to retrieve a buffer */ if (unlikely(!skb)) { + /* The page might not actually be freed here since the + * page reference count is incremented in + * ena_xdp_xmit_buff(), and it will be decreased only + * when send completion was received from the device + */ + if (xdp_verdict == XDP_TX) + ena_free_rx_page(rx_ring, + &rx_ring->rx_buffer_info[rx_ring->ena_bufs[0].req_id]); for (i = 0; i < ena_rx_ctx.descs; i++) { rx_ring->free_ids[next_to_clean] = rx_ring->ena_bufs[i].req_id; @@ -1095,6 +1634,10 @@ ENA_RX_RING_IDX_NEXT(next_to_clean, rx_ring->ring_size); } + if (xdp_verdict != XDP_PASS) { + res_budget--; + continue; + } break; } @@ -1126,7 +1669,7 @@ rx_ring->next_to_clean = next_to_clean; - refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq); + refill_required = ena_com_free_q_entries(rx_ring->ena_com_io_sq); refill_threshold = min_t(int, rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER, ENA_RX_REFILL_THRESH_PACKET); @@ -1142,12 +1685,18 @@ error: adapter = netdev_priv(rx_ring->netdev); - u64_stats_update_begin(&rx_ring->syncp); - rx_ring->rx_stats.bad_desc_num++; - u64_stats_update_end(&rx_ring->syncp); + if (rc == -ENOSPC) { + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->rx_stats.bad_desc_num++; + u64_stats_update_end(&rx_ring->syncp); + adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS; + } else { + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->rx_stats.bad_req_id++; + u64_stats_update_end(&rx_ring->syncp); + adapter->reset_reason = ENA_REGS_RESET_INV_RX_REQ_ID; + } - /* Too many desc from the device. Trigger reset */ - adapter->reset_reason = ENA_REGS_RESET_TOO_MANY_RX_DESCS; set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); return 0; @@ -1188,9 +1737,14 @@ struct ena_ring *rx_ring) { struct ena_eth_io_intr_reg intr_reg; - u32 rx_interval = ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev) ? - rx_ring->smoothed_interval : - ena_com_get_nonadaptive_moderation_interval_rx(rx_ring->ena_dev); + u32 rx_interval = 0; + /* Rx ring can be NULL when for XDP tx queues which don't have an + * accompanying rx_ring pair. + */ + if (rx_ring) + rx_interval = ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev) ? + rx_ring->smoothed_interval : + ena_com_get_nonadaptive_moderation_interval_rx(rx_ring->ena_dev); /* Update intr register: rx intr delay, * tx intr delay and interrupt unmask @@ -1200,11 +1754,16 @@ tx_ring->smoothed_interval, true); + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->tx_stats.unmask_interrupt++; + u64_stats_update_end(&tx_ring->syncp); + /* It is a shared MSI-X. * Tx and Rx CQ have pointer to it. * So we use one of them to reach the intr reg + * The Tx ring is used because the rx_ring is NULL for XDP queues */ - ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); + ena_com_unmask_intr(tx_ring->ena_com_io_cq, &intr_reg); } static void ena_update_ring_numa_node(struct ena_ring *tx_ring, @@ -1222,24 +1781,84 @@ if (numa_node != NUMA_NO_NODE) { ena_com_update_numa_node(tx_ring->ena_com_io_cq, numa_node); - ena_com_update_numa_node(rx_ring->ena_com_io_cq, numa_node); + if (rx_ring) + ena_com_update_numa_node(rx_ring->ena_com_io_cq, + numa_node); } tx_ring->cpu = cpu; - rx_ring->cpu = cpu; + if (rx_ring) + rx_ring->cpu = cpu; return; out: put_cpu(); } +static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget) +{ + u32 total_done = 0; + u16 next_to_clean; + u32 tx_bytes = 0; + int tx_pkts = 0; + u16 req_id; + int rc; + + if (unlikely(!xdp_ring)) + return 0; + next_to_clean = xdp_ring->next_to_clean; + + while (tx_pkts < budget) { + struct ena_tx_buffer *tx_info; + struct xdp_frame *xdpf; + + rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq, + &req_id); + if (rc) + break; + + rc = validate_xdp_req_id(xdp_ring, req_id); + if (rc) + break; + + tx_info = &xdp_ring->tx_buffer_info[req_id]; + xdpf = tx_info->xdpf; + + tx_info->xdpf = NULL; + tx_info->last_jiffies = 0; + ena_unmap_tx_buff(xdp_ring, tx_info); + + netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev, + "tx_poll: q %d skb %p completed\n", xdp_ring->qid, + xdpf); + + tx_bytes += xdpf->len; + tx_pkts++; + total_done += tx_info->tx_descs; + + __free_page(tx_info->xdp_rx_page); + xdp_ring->free_ids[next_to_clean] = req_id; + next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean, + xdp_ring->ring_size); + } + + xdp_ring->next_to_clean = next_to_clean; + ena_com_comp_ack(xdp_ring->ena_com_io_sq, total_done); + ena_com_update_dev_comp_head(xdp_ring->ena_com_io_cq); + + netif_dbg(xdp_ring->adapter, tx_done, xdp_ring->netdev, + "tx_poll: q %d done. total pkts: %d\n", + xdp_ring->qid, tx_pkts); + + return tx_pkts; +} + static int ena_io_poll(struct napi_struct *napi, int budget) { struct ena_napi *ena_napi = container_of(napi, struct ena_napi, napi); struct ena_ring *tx_ring, *rx_ring; - - u32 tx_work_done; - u32 rx_work_done; + int tx_work_done; + int rx_work_done = 0; int tx_budget; int napi_comp_call = 0; int ret; @@ -1247,6 +1866,9 @@ tx_ring = ena_napi->tx_ring; rx_ring = ena_napi->rx_ring; + tx_ring->first_interrupt = ena_napi->first_interrupt; + rx_ring->first_interrupt = ena_napi->first_interrupt; + tx_budget = tx_ring->ring_size / ENA_TX_POLL_BUDGET_DIVIDER; if (!test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags) || @@ -1256,7 +1878,11 @@ } tx_work_done = ena_clean_tx_irq(tx_ring, tx_budget); - rx_work_done = ena_clean_rx_irq(rx_ring, napi, budget); + /* On netpoll the budget is zero and the handler should only clean the + * tx completions. + */ + if (likely(budget)) + rx_work_done = ena_clean_rx_irq(rx_ring, napi, budget); /* If the device is about to reset or down, avoid unmask * the interrupt and return 0 so NAPI won't reschedule @@ -1272,7 +1898,10 @@ /* Update numa and unmask the interrupt only when schedule * from the interrupt context (vs from sk_busy_loop) */ - if (napi_complete_done(napi, rx_work_done)) { + if (napi_complete_done(napi, rx_work_done) && + READ_ONCE(ena_napi->interrupts_masked)) { + smp_rmb(); /* make sure interrupts_masked is read */ + WRITE_ONCE(ena_napi->interrupts_masked, false); /* We apply adaptive moderation on Rx path only. * Tx uses static interrupt moderation. */ @@ -1318,8 +1947,10 @@ { struct ena_napi *ena_napi = data; - ena_napi->tx_ring->first_interrupt = true; - ena_napi->rx_ring->first_interrupt = true; + ena_napi->first_interrupt = true; + + WRITE_ONCE(ena_napi->interrupts_masked, true); + smp_wmb(); /* write interrupts_masked before calling napi */ napi_schedule_irqoff(&ena_napi->napi); @@ -1331,7 +1962,7 @@ * the number of potential io queues is the minimum of what the device * supports and the number of vCPUs. */ -static int ena_enable_msix(struct ena_adapter *adapter, int num_queues) +static int ena_enable_msix(struct ena_adapter *adapter) { int msix_vecs, irq_cnt; @@ -1342,9 +1973,9 @@ } /* Reserved the max msix vectors we might need */ - msix_vecs = ENA_MAX_MSIX_VEC(num_queues); + msix_vecs = ENA_MAX_MSIX_VEC(adapter->max_num_io_queues); netif_dbg(adapter, probe, adapter->netdev, - "trying to enable MSI-X, vectors %d\n", msix_vecs); + "Trying to enable MSI-X, vectors %d\n", msix_vecs); irq_cnt = pci_alloc_irq_vectors(adapter->pdev, ENA_MIN_MSIX_VEC, msix_vecs, PCI_IRQ_MSIX); @@ -1357,9 +1988,9 @@ if (irq_cnt != msix_vecs) { netif_notice(adapter, probe, adapter->netdev, - "enable only %d MSI-X (out of %d), reduce the number of queues\n", + "Enable only %d MSI-X (out of %d), reduce the number of queues\n", irq_cnt, msix_vecs); - adapter->num_queues = irq_cnt - ENA_ADMIN_MSIX_VEC; + adapter->num_io_queues = irq_cnt - ENA_ADMIN_MSIX_VEC; } if (ena_init_rx_cpu_rmap(adapter)) @@ -1394,10 +2025,12 @@ { struct net_device *netdev; int irq_idx, i, cpu; + int io_queue_count; netdev = adapter->netdev; + io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < io_queue_count; i++) { irq_idx = ENA_IO_IRQ_IDX(i); cpu = i % num_online_cpus(); @@ -1425,12 +2058,12 @@ irq->data); if (rc) { netif_err(adapter, probe, adapter->netdev, - "failed to request admin irq\n"); + "Failed to request admin irq\n"); return rc; } netif_dbg(adapter, probe, adapter->netdev, - "set affinity hint of mgmnt irq.to 0x%lx (irq vector: %d)\n", + "Set affinity hint of mgmnt irq.to 0x%lx (irq vector: %d)\n", irq->affinity_hint_mask.bits[0], irq->vector); irq_set_affinity_hint(irq->vector, &irq->affinity_hint_mask); @@ -1440,6 +2073,7 @@ static int ena_request_io_irq(struct ena_adapter *adapter) { + u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; unsigned long flags = 0; struct ena_irq *irq; int rc = 0, i, k; @@ -1450,7 +2084,7 @@ return -EINVAL; } - for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) { + for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) { irq = &adapter->irq_tbl[i]; rc = request_irq(irq->vector, irq->handler, flags, irq->name, irq->data); @@ -1462,7 +2096,7 @@ } netif_dbg(adapter, ifup, adapter->netdev, - "set affinity hint of irq. index %d to 0x%lx (irq vector: %d)\n", + "Set affinity hint of irq. index %d to 0x%lx (irq vector: %d)\n", i, irq->affinity_hint_mask.bits[0], irq->vector); irq_set_affinity_hint(irq->vector, &irq->affinity_hint_mask); @@ -1491,6 +2125,7 @@ static void ena_free_io_irq(struct ena_adapter *adapter) { + u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; struct ena_irq *irq; int i; @@ -1501,7 +2136,7 @@ } #endif /* CONFIG_RFS_ACCEL */ - for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) { + for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) { irq = &adapter->irq_tbl[i]; irq_set_affinity_hint(irq->vector, NULL); free_irq(irq->vector, irq->data); @@ -1516,54 +2151,70 @@ static void ena_disable_io_intr_sync(struct ena_adapter *adapter) { + u32 io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; int i; if (!netif_running(adapter->netdev)) return; - for (i = ENA_IO_IRQ_FIRST_IDX; i < adapter->msix_vecs; i++) + for (i = ENA_IO_IRQ_FIRST_IDX; i < ENA_MAX_MSIX_VEC(io_queue_count); i++) synchronize_irq(adapter->irq_tbl[i].vector); } -static void ena_del_napi(struct ena_adapter *adapter) +static void ena_del_napi_in_range(struct ena_adapter *adapter, + int first_index, + int count) { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = first_index; i < first_index + count; i++) { netif_napi_del(&adapter->ena_napi[i].napi); + + WARN_ON(!ENA_IS_XDP_INDEX(adapter, i) && + adapter->ena_napi[i].xdp_ring); + } } -static void ena_init_napi(struct ena_adapter *adapter) +static void ena_init_napi_in_range(struct ena_adapter *adapter, + int first_index, int count) { - struct ena_napi *napi; int i; - for (i = 0; i < adapter->num_queues; i++) { - napi = &adapter->ena_napi[i]; + for (i = first_index; i < first_index + count; i++) { + struct ena_napi *napi = &adapter->ena_napi[i]; netif_napi_add(adapter->netdev, - &adapter->ena_napi[i].napi, - ena_io_poll, + &napi->napi, + ENA_IS_XDP_INDEX(adapter, i) ? ena_xdp_io_poll : ena_io_poll, ENA_NAPI_BUDGET); - napi->rx_ring = &adapter->rx_ring[i]; - napi->tx_ring = &adapter->tx_ring[i]; + + if (!ENA_IS_XDP_INDEX(adapter, i)) { + napi->rx_ring = &adapter->rx_ring[i]; + napi->tx_ring = &adapter->tx_ring[i]; + } else { + napi->xdp_ring = &adapter->tx_ring[i]; + } napi->qid = i; } } -static void ena_napi_disable_all(struct ena_adapter *adapter) +static void ena_napi_disable_in_range(struct ena_adapter *adapter, + int first_index, + int count) { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = first_index; i < first_index + count; i++) napi_disable(&adapter->ena_napi[i].napi); } -static void ena_napi_enable_all(struct ena_adapter *adapter) +static void ena_napi_enable_in_range(struct ena_adapter *adapter, + int first_index, + int count) { int i; - for (i = 0; i < adapter->num_queues; i++) + for (i = first_index; i < first_index + count; i++) napi_enable(&adapter->ena_napi[i].napi); } @@ -1616,7 +2267,9 @@ /* enable transmits */ netif_tx_start_all_queues(adapter->netdev); - ena_napi_enable_all(adapter); + ena_napi_enable_in_range(adapter, + 0, + adapter->xdp_num_queues + adapter->num_io_queues); return 0; } @@ -1668,12 +2321,13 @@ return rc; } -static int ena_create_all_io_tx_queues(struct ena_adapter *adapter) +static int ena_create_io_tx_queues_in_range(struct ena_adapter *adapter, + int first_index, int count) { struct ena_com_dev *ena_dev = adapter->ena_dev; int rc, i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = first_index; i < first_index + count; i++) { rc = ena_create_io_tx_queue(adapter, i); if (rc) goto create_err; @@ -1682,7 +2336,7 @@ return 0; create_err: - while (i--) + while (i-- > first_index) ena_com_destroy_io_queue(ena_dev, ENA_IO_TXQ_IDX(i)); return rc; @@ -1727,13 +2381,15 @@ netif_err(adapter, ifup, adapter->netdev, "Failed to get RX queue handlers. RX queue num %d rc: %d\n", qid, rc); - ena_com_destroy_io_queue(ena_dev, ena_qid); - return rc; + goto err; } ena_com_update_numa_node(rx_ring->ena_com_io_cq, ctx.numa_node); return rc; +err: + ena_com_destroy_io_queue(ena_dev, ena_qid); + return rc; } static int ena_create_all_io_rx_queues(struct ena_adapter *adapter) @@ -1741,7 +2397,7 @@ struct ena_com_dev *ena_dev = adapter->ena_dev; int rc, i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { rc = ena_create_io_rx_queue(adapter, i); if (rc) goto create_err; @@ -1760,11 +2416,12 @@ } static void set_io_rings_size(struct ena_adapter *adapter, - int new_tx_size, int new_rx_size) + int new_tx_size, + int new_rx_size) { int i; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { adapter->tx_ring[i].ring_size = new_tx_size; adapter->rx_ring[i].ring_size = new_rx_size; } @@ -1797,11 +2454,21 @@ adapter->requested_rx_ring_size); while (1) { - rc = ena_setup_all_tx_resources(adapter); + if (ena_xdp_present(adapter)) { + rc = ena_setup_and_create_all_xdp_queues(adapter); + + if (rc) + goto err_setup_tx; + } + rc = ena_setup_tx_resources_in_range(adapter, + 0, + adapter->num_io_queues); if (rc) goto err_setup_tx; - rc = ena_create_all_io_tx_queues(adapter); + rc = ena_create_io_tx_queues_in_range(adapter, + 0, + adapter->num_io_queues); if (rc) goto err_create_tx_queues; @@ -1867,10 +2534,11 @@ static int ena_up(struct ena_adapter *adapter) { - int rc, i; + int io_queue_count, rc, i; - netdev_dbg(adapter->netdev, "%s\n", __func__); + netif_dbg(adapter, ifup, adapter->netdev, "%s\n", __func__); + io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; ena_setup_io_intr(adapter); /* napi poll functions should be initialized before running @@ -1878,7 +2546,7 @@ * interrupt, causing the ISR to fire immediately while the poll * function wasn't set yet, causing a null dereference */ - ena_init_napi(adapter); + ena_init_napi_in_range(adapter, 0, io_queue_count); rc = ena_request_io_irq(adapter); if (rc) @@ -1902,14 +2570,14 @@ set_bit(ENA_FLAG_DEV_UP, &adapter->flags); /* Enable completion queues interrupt */ - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < adapter->num_io_queues; i++) ena_unmask_interrupt(&adapter->tx_ring[i], &adapter->rx_ring[i]); /* schedule napi in case we had pending packets * from the last time we disable napi */ - for (i = 0; i < adapter->num_queues; i++) + for (i = 0; i < io_queue_count; i++) napi_schedule(&adapter->ena_napi[i].napi); return rc; @@ -1922,13 +2590,15 @@ err_create_queues_with_backoff: ena_free_io_irq(adapter); err_req_irq: - ena_del_napi(adapter); + ena_del_napi_in_range(adapter, 0, io_queue_count); return rc; } static void ena_down(struct ena_adapter *adapter) { + int io_queue_count = adapter->num_io_queues + adapter->xdp_num_queues; + netif_info(adapter, ifdown, adapter->netdev, "%s\n", __func__); clear_bit(ENA_FLAG_DEV_UP, &adapter->flags); @@ -1941,7 +2611,7 @@ netif_tx_disable(adapter->netdev); /* After this point the napi handler won't enable the tx queue */ - ena_napi_disable_all(adapter); + ena_napi_disable_in_range(adapter, 0, io_queue_count); /* After destroy the queue there won't be any new interrupts */ @@ -1950,7 +2620,8 @@ rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); if (rc) - dev_err(&adapter->pdev->dev, "Device reset failed\n"); + netif_err(adapter, ifdown, adapter->netdev, + "Device reset failed\n"); /* stop submitting admin commands on a device that was reset */ ena_com_set_admin_running_state(adapter->ena_dev, false); } @@ -1959,7 +2630,7 @@ ena_disable_io_intr_sync(adapter); ena_free_io_irq(adapter); - ena_del_napi(adapter); + ena_del_napi_in_range(adapter, 0, io_queue_count); ena_free_all_tx_bufs(adapter); ena_free_all_rx_bufs(adapter); @@ -1984,13 +2655,13 @@ int rc; /* Notify the stack of the actual queue counts. */ - rc = netif_set_real_num_tx_queues(netdev, adapter->num_queues); + rc = netif_set_real_num_tx_queues(netdev, adapter->num_io_queues); if (rc) { netif_err(adapter, ifup, netdev, "Can't set num tx queues\n"); return rc; } - rc = netif_set_real_num_rx_queues(netdev, adapter->num_queues); + rc = netif_set_real_num_rx_queues(netdev, adapter->num_io_queues); if (rc) { netif_err(adapter, ifup, netdev, "Can't set num rx queues\n"); return rc; @@ -2043,17 +2714,59 @@ u32 new_tx_size, u32 new_rx_size) { - bool dev_up; + bool dev_was_up; - dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); + dev_was_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); ena_close(adapter->netdev); adapter->requested_tx_ring_size = new_tx_size; adapter->requested_rx_ring_size = new_rx_size; - ena_init_io_rings(adapter); - return dev_up ? ena_up(adapter) : 0; + ena_init_io_rings(adapter, + 0, + adapter->xdp_num_queues + + adapter->num_io_queues); + return dev_was_up ? ena_up(adapter) : 0; } -static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb) +int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count) +{ + struct ena_com_dev *ena_dev = adapter->ena_dev; + int prev_channel_count; + bool dev_was_up; + + dev_was_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); + ena_close(adapter->netdev); + prev_channel_count = adapter->num_io_queues; + adapter->num_io_queues = new_channel_count; + if (ena_xdp_present(adapter) && + ena_xdp_allowed(adapter) == ENA_XDP_ALLOWED) { + adapter->xdp_first_ring = new_channel_count; + adapter->xdp_num_queues = new_channel_count; + if (prev_channel_count > new_channel_count) + ena_xdp_exchange_program_rx_in_range(adapter, + NULL, + new_channel_count, + prev_channel_count); + else + ena_xdp_exchange_program_rx_in_range(adapter, + adapter->xdp_bpf_prog, + prev_channel_count, + new_channel_count); + } + + /* We need to destroy the rss table so that the indirection + * table will be reinitialized by ena_up() + */ + ena_com_rss_destroy(ena_dev); + ena_init_io_rings(adapter, + 0, + adapter->xdp_num_queues + + adapter->num_io_queues); + return dev_was_up ? ena_open(adapter->netdev) : 0; +} + +static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, + struct sk_buff *skb, + bool disable_meta_caching) { u32 mss = skb_shinfo(skb)->gso_size; struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta; @@ -2097,7 +2810,9 @@ ena_meta->l3_hdr_len = skb_network_header_len(skb); ena_meta->l3_hdr_offset = skb_network_offset(skb); ena_tx_ctx->meta_valid = 1; - + } else if (disable_meta_caching) { + memset(ena_meta, 0, sizeof(*ena_meta)); + ena_tx_ctx->meta_valid = 1; } else { ena_tx_ctx->meta_valid = 0; } @@ -2228,12 +2943,12 @@ u64_stats_update_begin(&tx_ring->syncp); tx_ring->tx_stats.dma_mapping_err++; u64_stats_update_end(&tx_ring->syncp); - netdev_warn(adapter->netdev, "failed to map skb\n"); + netif_warn(adapter, tx_queued, adapter->netdev, "Failed to map skb\n"); tx_info->skb = NULL; tx_info->num_of_bufs += i; - ena_unmap_tx_skb(tx_ring, tx_info); + ena_unmap_tx_buff(tx_ring, tx_info); return -EINVAL; } @@ -2248,7 +2963,7 @@ struct netdev_queue *txq; void *push_hdr; u16 next_to_use, req_id, header_len; - int qid, rc, nb_hw_desc; + int qid, rc; netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb); /* Determine which tx ring we will be placed on */ @@ -2281,52 +2996,19 @@ ena_tx_ctx.header_len = header_len; /* set flags and meta data */ - ena_tx_csum(&ena_tx_ctx, skb); - - if (unlikely(ena_com_is_doorbell_needed(tx_ring->ena_com_io_sq, &ena_tx_ctx))) { - netif_dbg(adapter, tx_queued, dev, - "llq tx max burst size of queue %d achieved, writing doorbell to send burst\n", - qid); - ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq); - } - - /* prepare the packet's descriptors to dma engine */ - rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx, - &nb_hw_desc); + ena_tx_csum(&ena_tx_ctx, skb, tx_ring->disable_meta_caching); - /* ena_com_prepare_tx() can't fail due to overflow of tx queue, - * since the number of free descriptors in the queue is checked - * after sending the previous packet. In case there isn't enough - * space in the queue for the next packet, it is stopped - * until there is again enough available space in the queue. - * All other failure reasons of ena_com_prepare_tx() are fatal - * and therefore require a device reset. - */ - if (unlikely(rc)) { - netif_err(adapter, tx_queued, dev, - "failed to prepare tx bufs\n"); - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->tx_stats.prepare_ctx_err++; - u64_stats_update_end(&tx_ring->syncp); - adapter->reset_reason = ENA_REGS_RESET_DRIVER_INVALID_STATE; - set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); + rc = ena_xmit_common(dev, + tx_ring, + tx_info, + &ena_tx_ctx, + next_to_use, + skb->len); + if (rc) goto error_unmap_dma; - } netdev_tx_sent_queue(txq, skb->len); - u64_stats_update_begin(&tx_ring->syncp); - tx_ring->tx_stats.cnt++; - tx_ring->tx_stats.bytes += skb->len; - u64_stats_update_end(&tx_ring->syncp); - - tx_info->tx_descs = nb_hw_desc; - tx_info->last_jiffies = jiffies; - tx_info->print_once = 0; - - tx_ring->next_to_use = ENA_TX_RING_IDX_NEXT(next_to_use, - tx_ring->ring_size); - /* stop the queue when no more space available, the packet can have up * to sgl_size + 2. one for the meta descriptor and one for header * (if the header is larger than tx_max_header_size). @@ -2373,7 +3055,7 @@ return NETDEV_TX_OK; error_unmap_dma: - ena_unmap_tx_skb(tx_ring, tx_info); + ena_unmap_tx_buff(tx_ring, tx_info); tx_info->skb = NULL; error_drop_packet: @@ -2381,32 +3063,16 @@ return NETDEV_TX_OK; } -static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb, - struct net_device *sb_dev) -{ - u16 qid; - /* we suspect that this is good for in--kernel network services that - * want to loop incoming skb rx to tx in normal user generated traffic, - * most probably we will not get to this - */ - if (skb_rx_queue_recorded(skb)) - qid = skb_get_rx_queue(skb); - else - qid = netdev_pick_tx(dev, skb, NULL); - - return qid; -} - -static void ena_config_host_info(struct ena_com_dev *ena_dev, - struct pci_dev *pdev) +static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pdev) { + struct device *dev = &pdev->dev; struct ena_admin_host_info *host_info; int rc; /* Allocate only the host info */ rc = ena_com_allocate_host_info(ena_dev); if (rc) { - pr_err("Cannot allocate host info\n"); + dev_err(dev, "Cannot allocate host info\n"); return; } @@ -2421,21 +3087,24 @@ strncpy(host_info->os_dist_str, utsname()->release, sizeof(host_info->os_dist_str) - 1); host_info->driver_version = - (DRV_MODULE_VER_MAJOR) | - (DRV_MODULE_VER_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) | - (DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT) | + (DRV_MODULE_GEN_MAJOR) | + (DRV_MODULE_GEN_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) | + (DRV_MODULE_GEN_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT) | ("K"[0] << ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT); host_info->num_cpus = num_online_cpus(); host_info->driver_supported_features = - ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK; + ENA_ADMIN_HOST_INFO_RX_OFFSET_MASK | + ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK | + ENA_ADMIN_HOST_INFO_RX_BUF_MIRRORING_MASK | + ENA_ADMIN_HOST_INFO_RSS_CONFIGURABLE_FUNCTION_KEY_MASK; rc = ena_com_set_host_attributes(ena_dev); if (rc) { if (rc == -EOPNOTSUPP) - pr_warn("Cannot set host attributes\n"); + dev_warn(dev, "Cannot set host attributes\n"); else - pr_err("Cannot set host attributes\n"); + dev_err(dev, "Cannot set host attributes\n"); goto err; } @@ -2463,7 +3132,8 @@ rc = ena_com_allocate_debug_area(adapter->ena_dev, debug_area_size); if (rc) { - pr_err("Cannot allocate debug area\n"); + netif_err(adapter, drv, adapter->netdev, + "Cannot allocate debug area\n"); return; } @@ -2483,6 +3153,19 @@ ena_com_delete_debug_area(adapter->ena_dev); } +int ena_update_hw_stats(struct ena_adapter *adapter) +{ + int rc = 0; + + rc = ena_com_get_eni_stats(adapter->ena_dev, &adapter->eni_stats); + if (rc) { + dev_info_once(&adapter->pdev->dev, "Failed to get ENI stats\n"); + return rc; + } + + return 0; +} + static void ena_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { @@ -2490,12 +3173,13 @@ struct ena_ring *rx_ring, *tx_ring; unsigned int start; u64 rx_drops; + u64 tx_drops; int i; if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) return; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { u64 bytes, packets; tx_ring = &adapter->tx_ring[i]; @@ -2524,9 +3208,11 @@ do { start = u64_stats_fetch_begin_irq(&adapter->syncp); rx_drops = adapter->dev_stats.rx_drops; + tx_drops = adapter->dev_stats.tx_drops; } while (u64_stats_fetch_retry_irq(&adapter->syncp, start)); stats->rx_dropped = rx_drops; + stats->tx_dropped = tx_drops; stats->multicast = 0; stats->collisions = 0; @@ -2546,12 +3232,12 @@ .ndo_open = ena_open, .ndo_stop = ena_close, .ndo_start_xmit = ena_start_xmit, - .ndo_select_queue = ena_select_queue, .ndo_get_stats64 = ena_get_stats64, .ndo_tx_timeout = ena_tx_timeout, .ndo_change_mtu = ena_change_mtu, .ndo_set_mac_address = NULL, .ndo_validate_addr = eth_validate_addr, + .ndo_bpf = ena_xdp, }; static int ena_device_validate_params(struct ena_adapter *adapter, @@ -2577,10 +3263,71 @@ return 0; } +static void set_default_llq_configurations(struct ena_llq_configurations *llq_config) +{ + llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER; + llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY; + llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2; + llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B; + llq_config->llq_ring_entry_size_value = 128; +} + +static int ena_set_queues_placement_policy(struct pci_dev *pdev, + struct ena_com_dev *ena_dev, + struct ena_admin_feature_llq_desc *llq, + struct ena_llq_configurations *llq_default_configurations) +{ + int rc; + u32 llq_feature_mask; + + llq_feature_mask = 1 << ENA_ADMIN_LLQ; + if (!(ena_dev->supported_features & llq_feature_mask)) { + dev_err(&pdev->dev, + "LLQ is not supported Fallback to host mode policy.\n"); + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; + return 0; + } + + rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations); + if (unlikely(rc)) { + dev_err(&pdev->dev, + "Failed to configure the device mode. Fallback to host mode policy.\n"); + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; + } + + return 0; +} + +static int ena_map_llq_mem_bar(struct pci_dev *pdev, struct ena_com_dev *ena_dev, + int bars) +{ + bool has_mem_bar = !!(bars & BIT(ENA_MEM_BAR)); + + if (!has_mem_bar) { + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { + dev_err(&pdev->dev, + "ENA device does not expose LLQ bar. Fallback to host mode policy.\n"); + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; + } + + return 0; + } + + ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, + pci_resource_start(pdev, ENA_MEM_BAR), + pci_resource_len(pdev, ENA_MEM_BAR)); + + if (!ena_dev->mem_bar) + return -EFAULT; + + return 0; +} + static int ena_device_init(struct ena_com_dev *ena_dev, struct pci_dev *pdev, struct ena_com_dev_get_features_ctx *get_feat_ctx, bool *wd_state) { + struct ena_llq_configurations llq_config; struct device *dev = &pdev->dev; bool readless_supported; u32 aenq_groups; @@ -2589,7 +3336,7 @@ rc = ena_com_mmio_reg_read_request_init(ena_dev); if (rc) { - dev_err(dev, "failed to init mmio read less\n"); + dev_err(dev, "Failed to init mmio read less\n"); return rc; } @@ -2607,7 +3354,7 @@ rc = ena_com_validate_version(ena_dev); if (rc) { - dev_err(dev, "device version is too low\n"); + dev_err(dev, "Device version is too low\n"); goto err_mmio_read_less; } @@ -2618,16 +3365,9 @@ goto err_mmio_read_less; } - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_width)); + rc = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_width)); if (rc) { - dev_err(dev, "pci_set_dma_mask failed 0x%x\n", rc); - goto err_mmio_read_less; - } - - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(dma_width)); - if (rc) { - dev_err(dev, "err_pci_set_consistent_dma_mask failed 0x%x\n", - rc); + dev_err(dev, "dma_set_mask_and_coherent failed %d\n", rc); goto err_mmio_read_less; } @@ -2671,6 +3411,15 @@ *wd_state = !!(aenq_groups & BIT(ENA_ADMIN_KEEP_ALIVE)); + set_default_llq_configurations(&llq_config); + + rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx->llq, + &llq_config); + if (rc) { + dev_err(dev, "ENA device init failed\n"); + goto err_admin_init; + } + return 0; err_admin_init: @@ -2682,14 +3431,13 @@ return rc; } -static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter, - int io_vectors) +static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter) { struct ena_com_dev *ena_dev = adapter->ena_dev; struct device *dev = &adapter->pdev->dev; int rc; - rc = ena_enable_msix(adapter, io_vectors); + rc = ena_enable_msix(adapter); if (rc) { dev_err(dev, "Can not reserve msix vectors\n"); return rc; @@ -2754,6 +3502,7 @@ ena_com_mmio_reg_read_request_destroy(ena_dev); + /* return reset reason to default value */ adapter->reset_reason = ENA_REGS_RESET_NORMAL; clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); @@ -2782,8 +3531,7 @@ goto err_device_destroy; } - rc = ena_enable_msix_and_set_admin_interrupts(adapter, - adapter->num_queues); + rc = ena_enable_msix_and_set_admin_interrupts(adapter); if (rc) { dev_err(&pdev->dev, "Enable MSI-X failed\n"); goto err_device_destroy; @@ -2804,9 +3552,10 @@ netif_carrier_on(adapter->netdev); mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); - dev_err(&pdev->dev, - "Device reset completed successfully, Driver info: %s\n", - version); + adapter->last_keep_alive_jiffies = jiffies; + dev_err(&pdev->dev, "Device reset completed successfully\n"); + + dev_err(&pdev->dev, "Device reset completed successfully\n"); return rc; err_disable_msix: @@ -2831,16 +3580,14 @@ { struct ena_adapter *adapter = container_of(work, struct ena_adapter, reset_task); - struct pci_dev *pdev = adapter->pdev; - if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { - dev_err(&pdev->dev, - "device reset schedule while reset bit is off\n"); - return; - } rtnl_lock(); - ena_destroy_device(adapter, false); - ena_restore_device(adapter); + + if (likely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { + ena_destroy_device(adapter, false); + ena_restore_device(adapter); + } + rtnl_unlock(); } @@ -2922,7 +3669,7 @@ } u64_stats_update_begin(&tx_ring->syncp); - tx_ring->tx_stats.missed_tx = missed_tx; + tx_ring->tx_stats.missed_tx += missed_tx; u64_stats_update_end(&tx_ring->syncp); return rc; @@ -2933,7 +3680,9 @@ struct ena_ring *tx_ring; struct ena_ring *rx_ring; int i, budget, rc; + int io_queue_count; + io_queue_count = adapter->xdp_num_queues + adapter->num_io_queues; /* Make sure the driver doesn't turn the device in other process */ smp_rmb(); @@ -2948,7 +3697,7 @@ budget = ENA_MONITORED_TX_QUEUES; - for (i = adapter->last_monitored_tx_qid; i < adapter->num_queues; i++) { + for (i = adapter->last_monitored_tx_qid; i < io_queue_count; i++) { tx_ring = &adapter->tx_ring[i]; rx_ring = &adapter->rx_ring[i]; @@ -2956,7 +3705,8 @@ if (unlikely(rc)) return; - rc = check_for_rx_interrupt_queue(adapter, rx_ring); + rc = !ENA_IS_XDP_INDEX(adapter, i) ? + check_for_rx_interrupt_queue(adapter, rx_ring) : 0; if (unlikely(rc)) return; @@ -2965,7 +3715,7 @@ break; } - adapter->last_monitored_tx_qid = i % adapter->num_queues; + adapter->last_monitored_tx_qid = i % io_queue_count; } /* trigger napi schedule after 2 consecutive detections */ @@ -2995,11 +3745,10 @@ if (test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags)) return; - for (i = 0; i < adapter->num_queues; i++) { + for (i = 0; i < adapter->num_io_queues; i++) { rx_ring = &adapter->rx_ring[i]; - refill_required = - ena_com_free_desc(rx_ring->ena_com_io_sq); + refill_required = ena_com_free_q_entries(rx_ring->ena_com_io_sq); if (unlikely(refill_required == (rx_ring->ring_size - 1))) { rx_ring->empty_rx_queue++; @@ -3009,7 +3758,7 @@ u64_stats_update_end(&rx_ring->syncp); netif_err(adapter, drv, adapter->netdev, - "trigger refill for ring %d\n", i); + "Trigger refill for ring %d\n", i); napi_schedule(rx_ring->napi); rx_ring->empty_rx_queue = 0; @@ -3031,8 +3780,8 @@ if (adapter->keep_alive_timeout == ENA_HW_HINTS_NO_TIMEOUT) return; - keep_alive_expired = round_jiffies(adapter->last_keep_alive_jiffies + - adapter->keep_alive_timeout); + keep_alive_expired = adapter->last_keep_alive_jiffies + + adapter->keep_alive_timeout; if (unlikely(time_is_before_jiffies(keep_alive_expired))) { netif_err(adapter, drv, adapter->netdev, "Keep alive watchdog timeout.\n"); @@ -3134,19 +3883,19 @@ } /* Reset the timer */ - mod_timer(&adapter->timer_service, jiffies + HZ); + mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); } -static int ena_calc_io_queue_num(struct pci_dev *pdev, - struct ena_com_dev *ena_dev, - struct ena_com_dev_get_features_ctx *get_feat_ctx) +static u32 ena_calc_max_io_queue_num(struct pci_dev *pdev, + struct ena_com_dev *ena_dev, + struct ena_com_dev_get_features_ctx *get_feat_ctx) { - int io_tx_sq_num, io_tx_cq_num, io_rx_num, io_queue_num; + u32 io_tx_sq_num, io_tx_cq_num, io_rx_num, max_num_io_queues; if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { struct ena_admin_queue_ext_feature_fields *max_queue_ext = &get_feat_ctx->max_queue_ext.max_queue_ext; - io_rx_num = min_t(int, max_queue_ext->max_rx_sq_num, + io_rx_num = min_t(u32, max_queue_ext->max_rx_sq_num, max_queue_ext->max_rx_cq_num); io_tx_sq_num = max_queue_ext->max_tx_sq_num; @@ -3156,73 +3905,25 @@ &get_feat_ctx->max_queues; io_tx_sq_num = max_queues->max_sq_num; io_tx_cq_num = max_queues->max_cq_num; - io_rx_num = min_t(int, io_tx_sq_num, io_tx_cq_num); + io_rx_num = min_t(u32, io_tx_sq_num, io_tx_cq_num); } /* In case of LLQ use the llq fields for the tx SQ/CQ */ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) io_tx_sq_num = get_feat_ctx->llq.max_llq_num; - io_queue_num = min_t(int, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES); - io_queue_num = min_t(int, io_queue_num, io_rx_num); - io_queue_num = min_t(int, io_queue_num, io_tx_sq_num); - io_queue_num = min_t(int, io_queue_num, io_tx_cq_num); + max_num_io_queues = min_t(u32, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES); + max_num_io_queues = min_t(u32, max_num_io_queues, io_rx_num); + max_num_io_queues = min_t(u32, max_num_io_queues, io_tx_sq_num); + max_num_io_queues = min_t(u32, max_num_io_queues, io_tx_cq_num); /* 1 IRQ for for mgmnt and 1 IRQs for each IO direction */ - io_queue_num = min_t(int, io_queue_num, pci_msix_vec_count(pdev) - 1); - if (unlikely(!io_queue_num)) { + max_num_io_queues = min_t(u32, max_num_io_queues, pci_msix_vec_count(pdev) - 1); + if (unlikely(!max_num_io_queues)) { dev_err(&pdev->dev, "The device doesn't have io queues\n"); return -EFAULT; } - return io_queue_num; -} - -static int ena_set_queues_placement_policy(struct pci_dev *pdev, - struct ena_com_dev *ena_dev, - struct ena_admin_feature_llq_desc *llq, - struct ena_llq_configurations *llq_default_configurations) -{ - bool has_mem_bar; - int rc; - u32 llq_feature_mask; - - llq_feature_mask = 1 << ENA_ADMIN_LLQ; - if (!(ena_dev->supported_features & llq_feature_mask)) { - dev_err(&pdev->dev, - "LLQ is not supported Fallback to host mode policy.\n"); - ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; - return 0; - } - - has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR); - - rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations); - if (unlikely(rc)) { - dev_err(&pdev->dev, - "Failed to configure the device mode. Fallback to host mode policy.\n"); - ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; - return 0; - } - - /* Nothing to config, exit */ - if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - return 0; - - if (!has_mem_bar) { - dev_err(&pdev->dev, - "ENA device does not expose LLQ bar. Fallback to host mode policy.\n"); - ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; - return 0; - } - - ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, - pci_resource_start(pdev, ENA_MEM_BAR), - pci_resource_len(pdev, ENA_MEM_BAR)); - - if (!ena_dev->mem_bar) - return -EFAULT; - - return 0; + return max_num_io_queues; } static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, @@ -3302,7 +4003,7 @@ } for (i = 0; i < ENA_RX_RSS_TABLE_SIZE; i++) { - val = ethtool_rxfh_indir_default(i, adapter->num_queues); + val = ethtool_rxfh_indir_default(i, adapter->num_io_queues); rc = ena_com_indirect_table_fill_entry(ena_dev, i, ENA_IO_RXQ_IDX(val)); if (unlikely(rc && (rc != -EOPNOTSUPP))) { @@ -3311,7 +4012,7 @@ } } - rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_CRC32, NULL, + rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ, NULL, ENA_HASH_KEY_SIZE, 0xFFFFFFFF); if (unlikely(rc && (rc != -EOPNOTSUPP))) { dev_err(dev, "Cannot fill hash function\n"); @@ -3340,16 +4041,8 @@ pci_release_selected_regions(pdev, release_bars); } -static void set_default_llq_configurations(struct ena_llq_configurations *llq_config) -{ - llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER; - llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B; - llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY; - llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2; - llq_config->llq_ring_entry_size_value = 128; -} -static int ena_calc_queue_size(struct ena_calc_queue_size_ctx *ctx) +static int ena_calc_io_queue_size(struct ena_calc_queue_size_ctx *ctx) { struct ena_admin_feature_llq_desc *llq = &ctx->get_feat_ctx->llq; struct ena_com_dev *ena_dev = ctx->ena_dev; @@ -3358,7 +4051,7 @@ u32 max_tx_queue_size; u32 max_rx_queue_size; - if (ctx->ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { + if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { struct ena_admin_queue_ext_feature_fields *max_queue_ext = &ctx->get_feat_ctx->max_queue_ext.max_queue_ext; max_rx_queue_size = min_t(u32, max_queue_ext->max_rx_cq_depth, @@ -3427,27 +4120,30 @@ */ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct ena_calc_queue_size_ctx calc_queue_ctx = {}; struct ena_com_dev_get_features_ctx get_feat_ctx; - struct ena_calc_queue_size_ctx calc_queue_ctx = { 0 }; - struct ena_llq_configurations llq_config; struct ena_com_dev *ena_dev = NULL; struct ena_adapter *adapter; - int io_queue_num, bars, rc; struct net_device *netdev; static int adapters_found; - char *queue_type_str; + u32 max_num_io_queues; bool wd_state; + int bars, rc; dev_dbg(&pdev->dev, "%s\n", __func__); - dev_info_once(&pdev->dev, "%s", version); - rc = pci_enable_device_mem(pdev); if (rc) { dev_err(&pdev->dev, "pci_enable_device_mem() failed!\n"); return rc; } + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(ENA_MAX_PHYS_ADDR_SIZE_BITS)); + if (rc) { + dev_err(&pdev->dev, "dma_set_mask_and_coherent failed %d\n", rc); + goto err_disable_device; + } + pci_set_master(pdev); ena_dev = vzalloc(sizeof(*ena_dev)); @@ -3468,56 +4164,48 @@ pci_resource_start(pdev, ENA_REG_BAR), pci_resource_len(pdev, ENA_REG_BAR)); if (!ena_dev->reg_bar) { - dev_err(&pdev->dev, "failed to remap regs bar\n"); + dev_err(&pdev->dev, "Failed to remap regs bar\n"); rc = -EFAULT; goto err_free_region; } + ena_dev->ena_min_poll_delay_us = ENA_ADMIN_POLL_DELAY_US; + ena_dev->dmadev = &pdev->dev; rc = ena_device_init(ena_dev, pdev, &get_feat_ctx, &wd_state); if (rc) { - dev_err(&pdev->dev, "ena device init failed\n"); + dev_err(&pdev->dev, "ENA device init failed\n"); if (rc == -ETIME) rc = -EPROBE_DEFER; goto err_free_region; } - set_default_llq_configurations(&llq_config); - - rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx.llq, - &llq_config); + rc = ena_map_llq_mem_bar(pdev, ena_dev, bars); if (rc) { - dev_err(&pdev->dev, "ena device init failed\n"); - goto err_device_destroy; + dev_err(&pdev->dev, "ENA llq bar mapping failed\n"); + goto err_free_ena_dev; } calc_queue_ctx.ena_dev = ena_dev; calc_queue_ctx.get_feat_ctx = &get_feat_ctx; calc_queue_ctx.pdev = pdev; - /* Initial Tx and RX interrupt delay. Assumes 1 usec granularity. - * Updated during device initialization with the real granularity - */ + /* Initial TX and RX interrupt delay. Assumes 1 usec granularity. + * Updated during device initialization with the real granularity + */ ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS; ena_dev->intr_moder_rx_interval = ENA_INTR_INITIAL_RX_INTERVAL_USECS; ena_dev->intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION; - io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx); - rc = ena_calc_queue_size(&calc_queue_ctx); - if (rc || io_queue_num <= 0) { + max_num_io_queues = ena_calc_max_io_queue_num(pdev, ena_dev, &get_feat_ctx); + rc = ena_calc_io_queue_size(&calc_queue_ctx); + if (rc || !max_num_io_queues) { rc = -EFAULT; goto err_device_destroy; } - dev_info(&pdev->dev, "creating %d io queues. rx queue size: %d tx queue size. %d LLQ is %s\n", - io_queue_num, - calc_queue_ctx.rx_queue_size, - calc_queue_ctx.tx_queue_size, - (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ? - "ENABLED" : "DISABLED"); - /* dev zeroed in init_etherdev */ - netdev = alloc_etherdev_mq(sizeof(struct ena_adapter), io_queue_num); + netdev = alloc_etherdev_mq(sizeof(struct ena_adapter), max_num_io_queues); if (!netdev) { dev_err(&pdev->dev, "alloc_etherdev_mq failed\n"); rc = -ENOMEM; @@ -3545,10 +4233,19 @@ adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size; adapter->max_rx_sgl_size = calc_queue_ctx.max_rx_sgl_size; - adapter->num_queues = io_queue_num; + adapter->num_io_queues = max_num_io_queues; + adapter->max_num_io_queues = max_num_io_queues; adapter->last_monitored_tx_qid = 0; + adapter->xdp_first_ring = 0; + adapter->xdp_num_queues = 0; + adapter->rx_copybreak = ENA_DEFAULT_RX_COPYBREAK; + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + adapter->disable_meta_caching = + !!(get_feat_ctx.llq.accel_mode.u.get.supported_flags & + BIT(ENA_ADMIN_DISABLE_META_CACHING)); + adapter->wd_state = wd_state; snprintf(adapter->name, ENA_NAME_MAX_LEN, "ena_%d", adapters_found); @@ -3559,7 +4256,10 @@ "Failed to query interrupt moderation feature\n"); goto err_netdev_destroy; } - ena_init_io_rings(adapter); + ena_init_io_rings(adapter, + 0, + adapter->xdp_num_queues + + adapter->num_io_queues); netdev->netdev_ops = &ena_netdev_ops; netdev->watchdog_timeo = TX_TIMEOUT; @@ -3569,7 +4269,7 @@ u64_stats_init(&adapter->syncp); - rc = ena_enable_msix_and_set_admin_interrupts(adapter, io_queue_num); + rc = ena_enable_msix_and_set_admin_interrupts(adapter); if (rc) { dev_err(&pdev->dev, "Failed to enable and set the admin interrupts\n"); @@ -3583,6 +4283,11 @@ ena_config_debug_area(adapter); + if (!ena_update_hw_stats(adapter)) + adapter->eni_stats_supported = true; + else + adapter->eni_stats_supported = false; + memcpy(adapter->netdev->perm_addr, adapter->mac_addr, netdev->addr_len); netif_carrier_off(netdev); @@ -3605,15 +4310,10 @@ timer_setup(&adapter->timer_service, ena_timer_service, 0); mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); - if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) - queue_type_str = "Regular"; - else - queue_type_str = "Low Latency"; - dev_info(&pdev->dev, - "%s found at mem %lx, mac addr %pM Queues %d, Placement policy: %s\n", + "%s found at mem %lx, mac addr %pM\n", DEVICE_NAME, (long)pci_resource_start(pdev, 0), - netdev->dev_addr, io_queue_num, queue_type_str); + netdev->dev_addr); set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); @@ -3648,13 +4348,15 @@ /*****************************************************************************/ -/* ena_remove - Device Removal Routine +/* __ena_shutoff - Helper used in both PCI remove/shutdown routines * @pdev: PCI device information struct + * @shutdown: Is it a shutdown operation? If false, means it is a removal * - * ena_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. + * __ena_shutoff is a helper routine that does the real work on shutdown and + * removal paths; the difference between those paths is with regards to whether + * dettach or unregister the netdevice. */ -static void ena_remove(struct pci_dev *pdev) +static void __ena_shutoff(struct pci_dev *pdev, bool shutdown) { struct ena_adapter *adapter = pci_get_drvdata(pdev); struct ena_com_dev *ena_dev; @@ -3669,17 +4371,25 @@ netdev->rx_cpu_rmap = NULL; } #endif /* CONFIG_RFS_ACCEL */ - del_timer_sync(&adapter->timer_service); + /* Make sure timer and reset routine won't be called after + * freeing device resources. + */ + del_timer_sync(&adapter->timer_service); cancel_work_sync(&adapter->reset_task); - rtnl_lock(); + rtnl_lock(); /* lock released inside the below if-else block */ + adapter->reset_reason = ENA_REGS_RESET_SHUTDOWN; ena_destroy_device(adapter, true); - rtnl_unlock(); - - unregister_netdev(netdev); - - free_netdev(netdev); + if (shutdown) { + netif_device_detach(netdev); + dev_close(netdev); + rtnl_unlock(); + } else { + rtnl_unlock(); + unregister_netdev(netdev); + free_netdev(netdev); + } ena_com_rss_destroy(ena_dev); @@ -3694,13 +4404,36 @@ vfree(ena_dev); } -#ifdef CONFIG_PM -/* ena_suspend - PM suspend callback +/* ena_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * ena_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. + */ + +static void ena_remove(struct pci_dev *pdev) +{ + __ena_shutoff(pdev, false); +} + +/* ena_shutdown - Device Shutdown Routine * @pdev: PCI device information struct - * @state:power state + * + * ena_shutdown is called by the PCI subsystem to alert the driver that + * a shutdown/reboot (or kexec) is happening and device must be disabled. */ -static int ena_suspend(struct pci_dev *pdev, pm_message_t state) + +static void ena_shutdown(struct pci_dev *pdev) { + __ena_shutoff(pdev, true); +} + +/* ena_suspend - PM suspend callback + * @dev_d: Device information struct + */ +static int __maybe_unused ena_suspend(struct device *dev_d) +{ + struct pci_dev *pdev = to_pci_dev(dev_d); struct ena_adapter *adapter = pci_get_drvdata(pdev); u64_stats_update_begin(&adapter->syncp); @@ -3710,7 +4443,7 @@ rtnl_lock(); if (unlikely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) { dev_err(&pdev->dev, - "ignoring device reset request as the device is being suspended\n"); + "Ignoring device reset request as the device is being suspended\n"); clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); } ena_destroy_device(adapter, true); @@ -3719,12 +4452,11 @@ } /* ena_resume - PM resume callback - * @pdev: PCI device information struct - * + * @dev_d: Device information struct */ -static int ena_resume(struct pci_dev *pdev) +static int __maybe_unused ena_resume(struct device *dev_d) { - struct ena_adapter *adapter = pci_get_drvdata(pdev); + struct ena_adapter *adapter = dev_get_drvdata(dev_d); int rc; u64_stats_update_begin(&adapter->syncp); @@ -3736,24 +4468,21 @@ rtnl_unlock(); return rc; } -#endif + +static SIMPLE_DEV_PM_OPS(ena_pm_ops, ena_suspend, ena_resume); static struct pci_driver ena_pci_driver = { .name = DRV_MODULE_NAME, .id_table = ena_pci_tbl, .probe = ena_probe, .remove = ena_remove, -#ifdef CONFIG_PM - .suspend = ena_suspend, - .resume = ena_resume, -#endif + .shutdown = ena_shutdown, + .driver.pm = &ena_pm_ops, .sriov_configure = pci_sriov_configure_simple, }; static int __init ena_init(void) { - pr_info("%s", version); - ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME); if (!ena_wq) { pr_err("Failed to create workqueue\n"); @@ -3789,7 +4518,7 @@ ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK; if (status) { - netdev_dbg(adapter->netdev, "%s\n", __func__); + netif_dbg(adapter, ifup, adapter->netdev, "%s\n", __func__); set_bit(ENA_FLAG_LINK_UP, &adapter->flags); if (!test_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags)) netif_carrier_on(adapter->netdev); @@ -3805,14 +4534,20 @@ struct ena_adapter *adapter = (struct ena_adapter *)adapter_data; struct ena_admin_aenq_keep_alive_desc *desc; u64 rx_drops; + u64 tx_drops; desc = (struct ena_admin_aenq_keep_alive_desc *)aenq_e; adapter->last_keep_alive_jiffies = jiffies; rx_drops = ((u64)desc->rx_drops_high << 32) | desc->rx_drops_low; + tx_drops = ((u64)desc->tx_drops_high << 32) | desc->tx_drops_low; u64_stats_update_begin(&adapter->syncp); + /* These stats are accumulated by the device, so the counters indicate + * all drops since last reset. + */ adapter->dev_stats.rx_drops = rx_drops; + adapter->dev_stats.tx_drops = tx_drops; u64_stats_update_end(&adapter->syncp); } @@ -3827,7 +4562,7 @@ aenq_e->aenq_common_desc.group, ENA_ADMIN_NOTIFICATION); - switch (aenq_e->aenq_common_desc.syndrom) { + switch (aenq_e->aenq_common_desc.syndrome) { case ENA_ADMIN_UPDATE_HINTS: hints = (struct ena_admin_ena_hw_hints *) (&aenq_e->inline_data_w4); @@ -3836,7 +4571,7 @@ default: netif_err(adapter, drv, adapter->netdev, "Invalid aenq notification link state %d\n", - aenq_e->aenq_common_desc.syndrom); + aenq_e->aenq_common_desc.syndrome); } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_netdev.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef ENA_H @@ -36,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -44,17 +18,11 @@ #include "ena_com.h" #include "ena_eth_com.h" -#define DRV_MODULE_VER_MAJOR 2 -#define DRV_MODULE_VER_MINOR 1 -#define DRV_MODULE_VER_SUBMINOR 0 +#define DRV_MODULE_GEN_MAJOR 2 +#define DRV_MODULE_GEN_MINOR 1 +#define DRV_MODULE_GEN_SUBMINOR 0 #define DRV_MODULE_NAME "ena" -#ifndef DRV_MODULE_VERSION -#define DRV_MODULE_VERSION \ - __stringify(DRV_MODULE_VER_MAJOR) "." \ - __stringify(DRV_MODULE_VER_MINOR) "." \ - __stringify(DRV_MODULE_VER_SUBMINOR) "K" -#endif #define DEVICE_NAME "Elastic Network Adapter (ENA)" @@ -68,7 +36,7 @@ * 16kB. */ #if PAGE_SIZE > SZ_16K -#define ENA_PAGE_SIZE SZ_16K +#define ENA_PAGE_SIZE (_AC(SZ_16K, UL)) #else #define ENA_PAGE_SIZE PAGE_SIZE #endif @@ -82,6 +50,8 @@ #define ENA_DEFAULT_RING_SIZE (1024) #define ENA_MIN_RING_SIZE (256) +#define ENA_MIN_NUM_IO_QUEUES (1) + #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2) #define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN) @@ -101,8 +71,6 @@ #define ENA_RX_RSS_TABLE_LOG_SIZE 7 #define ENA_RX_RSS_TABLE_SIZE (1 << ENA_RX_RSS_TABLE_LOG_SIZE) -#define ENA_HASH_KEY_SIZE 40 - /* The number of tx packet completions that will be handled each NAPI poll * cycle is ring_size / ENA_TX_POLL_BUDGET_DIVIDER. */ @@ -127,11 +95,15 @@ #define ENA_IO_TXQ_IDX(q) (2 * (q)) #define ENA_IO_RXQ_IDX(q) (2 * (q) + 1) +#define ENA_IO_TXQ_IDX_TO_COMBINED_IDX(q) ((q) / 2) +#define ENA_IO_RXQ_IDX_TO_COMBINED_IDX(q) (((q) - 1) / 2) #define ENA_MGMNT_IRQ_IDX 0 #define ENA_IO_IRQ_FIRST_IDX 1 #define ENA_IO_IRQ_IDX(q) (ENA_IO_IRQ_FIRST_IDX + (q)) +#define ENA_ADMIN_POLL_DELAY_US 100 + /* ENA device should send keep alive msg every 1 sec. * We wait for 6 sec just to be on the safe side. */ @@ -140,6 +112,18 @@ #define ENA_MMIO_DISABLE_REG_READ BIT(0) +/* The max MTU size is configured to be the ethernet frame size without + * the overhead of the ethernet header, which can have a VLAN header, and + * a frame check sequence (FCS). + * The buffer size we share with the device is defined to be ENA_PAGE_SIZE + */ + +#define ENA_XDP_MAX_MTU (ENA_PAGE_SIZE - ETH_HLEN - ETH_FCS_LEN - \ + VLAN_HLEN - XDP_PACKET_HEADROOM) + +#define ENA_IS_XDP_INDEX(adapter, index) (((index) >= (adapter)->xdp_first_ring) && \ + ((index) < (adapter)->xdp_first_ring + (adapter)->xdp_num_queues)) + struct ena_irq { irq_handler_t handler; void *data; @@ -153,6 +137,9 @@ struct napi_struct napi ____cacheline_aligned; struct ena_ring *tx_ring; struct ena_ring *rx_ring; + struct ena_ring *xdp_ring; + bool first_interrupt; + bool interrupts_masked; u32 qid; struct dim dim; }; @@ -161,10 +148,10 @@ struct ena_com_dev_get_features_ctx *get_feat_ctx; struct ena_com_dev *ena_dev; struct pci_dev *pdev; - u16 tx_queue_size; - u16 rx_queue_size; - u16 max_tx_queue_size; - u16 max_rx_queue_size; + u32 tx_queue_size; + u32 rx_queue_size; + u32 max_tx_queue_size; + u32 max_rx_queue_size; u16 max_tx_sgl_size; u16 max_rx_sgl_size; }; @@ -178,6 +165,17 @@ /* num of buffers used by this skb */ u32 num_of_bufs; + /* XDP buffer structure which is used for sending packets in + * the xdp queues + */ + struct xdp_frame *xdpf; + /* The rx page for the rx buffer that was received in rx and + * re transmitted on xdp tx queues as a result of XDP_TX action. + * We need to free the page once we finished cleaning the buffer in + * clean_xdp_irq() + */ + struct page *xdp_rx_page; + /* Indicate if bufs[0] map the linear data of the skb. */ u8 map_linear_data; @@ -218,6 +216,7 @@ u64 bad_req_id; u64 llq_buffer_copy; u64 missed_tx; + u64 unmask_interrupt; }; struct ena_stats_rx { @@ -234,6 +233,11 @@ u64 bad_req_id; u64 empty_rx_ring; u64 csum_unchecked; + u64 xdp_aborted; + u64 xdp_drop; + u64 xdp_pass; + u64 xdp_tx; + u64 xdp_invalid; }; struct ena_ring { @@ -256,10 +260,13 @@ struct ena_adapter *adapter; struct ena_com_io_cq *ena_com_io_cq; struct ena_com_io_sq *ena_com_io_sq; + struct bpf_prog *xdp_bpf_prog; + struct xdp_rxq_info xdp_rxq; u16 next_to_use; u16 next_to_clean; u16 rx_copybreak; + u16 rx_headroom; u16 qid; u16 mtu; u16 sgl_size; @@ -268,6 +275,7 @@ u8 tx_max_header_size; bool first_interrupt; + bool disable_meta_caching; u16 no_interrupt_event_cnt; /* cpu for TPH */ @@ -300,6 +308,7 @@ u64 interface_down; u64 admin_q_pause; u64 rx_drops; + u64 tx_drops; }; enum ena_flags_t { @@ -324,7 +333,8 @@ u32 rx_copybreak; u32 max_mtu; - int num_queues; + u32 num_io_queues; + u32 max_num_io_queues; int msix_vecs; @@ -367,15 +377,22 @@ bool wd_state; bool dev_up_before_reset; + bool disable_meta_caching; unsigned long last_keep_alive_jiffies; struct u64_stats_sync syncp; struct ena_stats_dev dev_stats; + struct ena_admin_eni_stats eni_stats; + bool eni_stats_supported; /* last queue index that was checked for uncompleted tx packets */ u32 last_monitored_tx_qid; enum ena_regs_reset_reason_types reset_reason; + + struct bpf_prog *xdp_bpf_prog; + u32 xdp_first_ring; + u32 xdp_num_queues; }; void ena_set_ethtool_ops(struct net_device *netdev); @@ -384,10 +401,53 @@ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf); +int ena_update_hw_stats(struct ena_adapter *adapter); + int ena_update_queue_sizes(struct ena_adapter *adapter, u32 new_tx_size, u32 new_rx_size); +int ena_update_queue_count(struct ena_adapter *adapter, u32 new_channel_count); + int ena_get_sset_count(struct net_device *netdev, int sset); +enum ena_xdp_errors_t { + ENA_XDP_ALLOWED = 0, + ENA_XDP_CURRENT_MTU_TOO_LARGE, + ENA_XDP_NO_ENOUGH_QUEUES, +}; + +static inline bool ena_xdp_queues_present(struct ena_adapter *adapter) +{ + return adapter->xdp_first_ring != 0; +} + +static inline bool ena_xdp_present(struct ena_adapter *adapter) +{ + return !!adapter->xdp_bpf_prog; +} + +static inline bool ena_xdp_present_ring(struct ena_ring *ring) +{ + return !!ring->xdp_bpf_prog; +} + +static inline int ena_xdp_legal_queue_count(struct ena_adapter *adapter, + u32 queues) +{ + return 2 * queues <= adapter->max_num_io_queues; +} + +static inline enum ena_xdp_errors_t ena_xdp_allowed(struct ena_adapter *adapter) +{ + enum ena_xdp_errors_t rc = ENA_XDP_ALLOWED; + + if (adapter->netdev->mtu > ENA_XDP_MAX_MTU) + rc = ENA_XDP_CURRENT_MTU_TOO_LARGE; + else if (!ena_xdp_legal_queue_count(adapter, adapter->num_io_queues)) + rc = ENA_XDP_NO_ENOUGH_QUEUES; + + return rc; +} + #endif /* !(ENA_H) */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_pci_id_tbl.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef ENA_PCI_ID_TBL_H_ @@ -53,10 +26,15 @@ #define PCI_DEV_ID_ENA_LLQ_VF 0xec21 #endif +#ifndef PCI_DEV_ID_ENA_RESRV0 +#define PCI_DEV_ID_ENA_RESRV0 0x0051 +#endif + #define ENA_PCI_ID_TABLE_ENTRY(devid) \ {PCI_DEVICE(PCI_VENDOR_ID_AMAZON, devid)}, static const struct pci_device_id ena_pci_tbl[] = { + ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_RESRV0) ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_PF) ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_LLQ_PF) ENA_PCI_ID_TABLE_ENTRY(PCI_DEV_ID_ENA_VF) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amazon/ena/ena_regs_defs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amazon/ena/ena_regs_defs.h @@ -1,33 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ /* - * Copyright 2015 - 2016 Amazon.com, Inc. or its affiliates. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the - * BSD license below: - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. + * Copyright 2015-2020 Amazon.com, Inc. or its affiliates. All rights reserved. */ #ifndef _ENA_REGS_H_ #define _ENA_REGS_H_ @@ -154,4 +127,4 @@ #define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16 #define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000 -#endif /*_ENA_REGS_H_ */ +#endif /* _ENA_REGS_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/atarilance.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/atarilance.c @@ -825,7 +825,7 @@ lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; dev->stats.tx_bytes += skb->len; - dev_kfree_skb( skb ); + dev_consume_skb_irq(skb); lp->cur_tx++; while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) { lp->cur_tx -= TX_RING_SIZE; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/lance.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/lance.c @@ -997,7 +997,7 @@ skb_copy_from_linear_data(skb, &lp->tx_bounce_buffs[entry], skb->len); lp->tx_ring[entry].base = ((u32)isa_virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000; - dev_kfree_skb(skb); + dev_consume_skb_irq(skb); } else { lp->tx_skbuff[entry] = skb; lp->tx_ring[entry].base = ((u32)isa_virt_to_bus(skb->data) & 0xffffff) | 0x83000000; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/mvme147.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/mvme147.c @@ -106,10 +106,6 @@ address = address >> 8; dev->dev_addr[3] = address&0xff; - printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", - dev->name, dev->base_addr, MVME147_LANCE_IRQ, - dev->dev_addr); - lp = netdev_priv(dev); lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ if (!lp->ram) { @@ -139,6 +135,9 @@ return ERR_PTR(err); } + netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", + dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr); + return dev; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/nmclan_cs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/nmclan_cs.c @@ -652,7 +652,7 @@ } else { pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", sig[0], sig[1]); - return -ENODEV; + goto failed; } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/pcnet32.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/pcnet32.c @@ -1548,8 +1548,7 @@ } pci_set_master(pdev); - ioaddr = pci_resource_start(pdev, 0); - if (!ioaddr) { + if (!pci_resource_len(pdev, 0)) { if (pcnet32_debug & NETIF_MSG_PROBE) pr_err("card has no PCI IO resources, aborting\n"); err = -ENODEV; @@ -1562,6 +1561,8 @@ pr_err("architecture does not support 32bit PCI busmaster DMA\n"); goto err_disable_dev; } + + ioaddr = pci_resource_start(pdev, 0); if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) { if (pcnet32_debug & NETIF_MSG_PROBE) pr_err("io address range already allocated\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -1279,10 +1279,18 @@ #define MDIO_PMA_10GBR_FECCTRL 0x00ab #endif +#ifndef MDIO_PMA_RX_CTRL1 +#define MDIO_PMA_RX_CTRL1 0x8051 +#endif + #ifndef MDIO_PCS_DIG_CTRL #define MDIO_PCS_DIG_CTRL 0x8000 #endif +#ifndef MDIO_PCS_DIGITAL_STAT +#define MDIO_PCS_DIGITAL_STAT 0x8010 +#endif + #ifndef MDIO_AN_XNP #define MDIO_AN_XNP 0x0016 #endif @@ -1323,6 +1331,10 @@ #define MDIO_VEND2_PMA_CDR_CONTROL 0x8056 #endif +#ifndef MDIO_VEND2_PMA_MISC_CTRL0 +#define MDIO_VEND2_PMA_MISC_CTRL0 0x8090 +#endif + #ifndef MDIO_CTRL1_SPEED1G #define MDIO_CTRL1_SPEED1G (MDIO_CTRL1_SPEED10G & ~BMCR_SPEED100) #endif @@ -1358,6 +1370,8 @@ #define XGBE_KR_TRAINING_ENABLE BIT(1) #define XGBE_PCS_CL37_BP BIT(12) +#define XGBE_PCS_PSEQ_STATE_MASK 0x1c +#define XGBE_PCS_PSEQ_STATE_POWER_GOOD 0x10 #define XGBE_AN_CL37_INT_CMPLT BIT(0) #define XGBE_AN_CL37_INT_MASK 0x01 @@ -1375,6 +1389,14 @@ #define XGBE_PMA_CDR_TRACK_EN_OFF 0x00 #define XGBE_PMA_CDR_TRACK_EN_ON 0x01 +#define XGBE_PMA_RX_RST_0_MASK BIT(4) +#define XGBE_PMA_RX_RST_0_RESET_ON 0x10 +#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00 + +#define XGBE_PMA_PLL_CTRL_MASK BIT(15) +#define XGBE_PMA_PLL_CTRL_ENABLE BIT(15) +#define XGBE_PMA_PLL_CTRL_DISABLE 0x0000 + /* Bit setting and getting macros * The get macro will extract the current bit field value from within * the variable --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -524,19 +524,28 @@ netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n"); } +static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata) +{ + unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; + + /* From MAC ver 30H the TFCR is per priority, instead of per queue */ + if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30) + return max_q_count; + else + return min_t(unsigned int, pdata->tx_q_count, max_q_count); +} + static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) { - unsigned int max_q_count, q_count; unsigned int reg, reg_val; - unsigned int i; + unsigned int i, q_count; /* Clear MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0); /* Clear MAC flow control */ - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + q_count = xgbe_get_fc_queue_count(pdata); reg = MAC_Q0TFCR; for (i = 0; i < q_count; i++) { reg_val = XGMAC_IOREAD(pdata, reg); @@ -553,9 +562,8 @@ { struct ieee_pfc *pfc = pdata->pfc; struct ieee_ets *ets = pdata->ets; - unsigned int max_q_count, q_count; unsigned int reg, reg_val; - unsigned int i; + unsigned int i, q_count; /* Set MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) { @@ -579,8 +587,7 @@ } /* Set MAC flow control */ - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + q_count = xgbe_get_fc_queue_count(pdata); reg = MAC_Q0TFCR; for (i = 0; i < q_count; i++) { reg_val = XGMAC_IOREAD(pdata, reg); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -514,7 +514,7 @@ xgbe_disable_rx_tx_ints(pdata); /* Turn on polling */ - __napi_schedule_irqoff(&pdata->napi); + __napi_schedule(&pdata->napi); } } else { /* Don't clear Rx/Tx status if doing per channel DMA @@ -682,10 +682,24 @@ static void xgbe_service_timer(struct timer_list *t) { struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer); + struct xgbe_channel *channel; + unsigned int i; queue_work(pdata->dev_workqueue, &pdata->service_work); mod_timer(&pdata->service_timer, jiffies + HZ); + + if (!pdata->tx_usecs) + return; + + for (i = 0; i < pdata->channel_count; i++) { + channel = pdata->channel[i]; + if (!channel->tx_ring || channel->tx_timer_active) + break; + channel->tx_timer_active = 1; + mod_timer(&channel->tx_timer, + jiffies + usecs_to_jiffies(pdata->tx_usecs)); + } } static void xgbe_init_timers(struct xgbe_prv_data *pdata) @@ -721,7 +735,9 @@ if (!channel->tx_ring) break; + /* Deactivate the Tx timer */ del_timer_sync(&channel->tx_timer); + channel->tx_timer_active = 0; } } @@ -1137,6 +1153,9 @@ devm_free_irq(pdata->dev, pdata->dev_irq, pdata); + tasklet_kill(&pdata->tasklet_dev); + tasklet_kill(&pdata->tasklet_ecc); + if (pdata->vdata->ecc_support && (pdata->dev_irq != pdata->ecc_irq)) devm_free_irq(pdata->dev, pdata->ecc_irq, pdata); @@ -1443,6 +1462,7 @@ return; netif_tx_stop_all_queues(netdev); + netif_carrier_off(pdata->netdev); xgbe_stop_timers(pdata); flush_workqueue(pdata->dev_workqueue); @@ -2764,6 +2784,14 @@ buf2_len = xgbe_rx_buf2_len(rdata, packet, len); len += buf2_len; + if (buf2_len > rdata->rx.buf.dma_len) { + /* Hardware inconsistency within the descriptors + * that has resulted in a length underflow. + */ + error = 1; + goto skip_data; + } + if (!skb) { skb = xgbe_create_skb(pdata, napi, rdata, buf1_len); @@ -2793,8 +2821,10 @@ if (!last || context_next) goto read_again; - if (!skb) + if (!skb || error) { + dev_kfree_skb(skb); goto next_packet; + } /* Be sure we don't exceed the configured MTU */ max_len = netdev->mtu + ETH_HLEN; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c @@ -314,10 +314,15 @@ cmd->base.phy_address = pdata->phy.address; - cmd->base.autoneg = pdata->phy.autoneg; - cmd->base.speed = pdata->phy.speed; - cmd->base.duplex = pdata->phy.duplex; + if (netif_carrier_ok(netdev)) { + cmd->base.speed = pdata->phy.speed; + cmd->base.duplex = pdata->phy.duplex; + } else { + cmd->base.speed = SPEED_UNKNOWN; + cmd->base.duplex = DUPLEX_UNKNOWN; + } + cmd->base.autoneg = pdata->phy.autoneg; cmd->base.port = PORT_NONE; XGBE_LM_COPY(cmd, supported, lks, supported); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-i2c.c @@ -447,8 +447,10 @@ xgbe_i2c_disable(pdata); xgbe_i2c_clear_all_interrupts(pdata); - if (pdata->dev_irq != pdata->i2c_irq) + if (pdata->dev_irq != pdata->i2c_irq) { devm_free_irq(pdata->dev, pdata->i2c_irq, pdata); + tasklet_kill(&pdata->tasklet_i2c); + } } static int xgbe_i2c_start(struct xgbe_prv_data *pdata) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -496,6 +496,7 @@ reg |= XGBE_KR_TRAINING_ENABLE; reg |= XGBE_KR_TRAINING_START; XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); + pdata->kr_start_time = jiffies; netif_dbg(pdata, link, pdata->netdev, "KR training initiated\n"); @@ -632,6 +633,8 @@ xgbe_switch_mode(pdata); + pdata->an_result = XGBE_AN_READY; + xgbe_an_restart(pdata); return XGBE_AN_INCOMPAT_LINK; @@ -1175,7 +1178,19 @@ if (pdata->phy.duplex != DUPLEX_FULL) return -EINVAL; - xgbe_set_mode(pdata, mode); + /* Force the mode change for SFI in Fixed PHY config. + * Fixed PHY configs needs PLL to be enabled while doing mode set. + * When the SFP module isn't connected during boot, driver assumes + * AN is ON and attempts autonegotiation. However, if the connected + * SFP comes up in Fixed PHY config, the link will not come up as + * PLL isn't enabled while the initial mode set command is issued. + * So, force the mode change for SFI in Fixed PHY configuration to + * fix link issues. + */ + if (mode == XGBE_MODE_SFI) + xgbe_change_mode(pdata, mode); + else + xgbe_set_mode(pdata, mode); return 0; } @@ -1275,9 +1290,30 @@ static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) { unsigned long link_timeout; + unsigned long kr_time; + int wait; link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ); if (time_after(jiffies, link_timeout)) { + if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) && + pdata->phy.autoneg == AUTONEG_ENABLE) { + /* AN restart should not happen while KR training is in progress. + * The while loop ensures no AN restart during KR training, + * waits up to 500ms and AN restart is triggered only if KR + * training is failed. + */ + wait = XGBE_KR_TRAINING_WAIT_ITER; + while (wait--) { + kr_time = pdata->kr_start_time + + msecs_to_jiffies(XGBE_AN_MS_TIMEOUT); + if (time_after(jiffies, kr_time)) + break; + /* AN restart is not required, if AN result is COMPLETE */ + if (pdata->an_result == XGBE_AN_COMPLETE) + return; + usleep_range(10000, 11000); + } + } netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n"); xgbe_phy_config_aneg(pdata); } @@ -1288,7 +1324,7 @@ return pdata->phy_if.phy_impl.an_outcome(pdata); } -static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) +static bool xgbe_phy_status_result(struct xgbe_prv_data *pdata) { struct ethtool_link_ksettings *lks = &pdata->phy.lks; enum xgbe_mode mode; @@ -1323,8 +1359,13 @@ pdata->phy.duplex = DUPLEX_FULL; - if (xgbe_set_mode(pdata, mode) && pdata->an_again) + if (!xgbe_set_mode(pdata, mode)) + return false; + + if (pdata->an_again) xgbe_phy_reconfig_aneg(pdata); + + return true; } static void xgbe_phy_status(struct xgbe_prv_data *pdata) @@ -1345,7 +1386,7 @@ &an_restart); if (an_restart) { xgbe_phy_config_aneg(pdata); - return; + goto adjust_link; } if (pdata->phy.link) { @@ -1354,7 +1395,8 @@ return; } - xgbe_phy_status_result(pdata); + if (xgbe_phy_status_result(pdata)) + return; if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) clear_bit(XGBE_LINK_INIT, &pdata->dev_state); @@ -1390,13 +1432,14 @@ /* Disable auto-negotiation */ xgbe_an_disable_all(pdata); - if (pdata->dev_irq != pdata->an_irq) + if (pdata->dev_irq != pdata->an_irq) { devm_free_irq(pdata->dev, pdata->an_irq, pdata); + tasklet_kill(&pdata->tasklet_an); + } pdata->phy_if.phy_impl.stop(pdata); pdata->phy.link = 0; - netif_carrier_off(pdata->netdev); xgbe_phy_adjust_link(pdata); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-pci.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-pci.c @@ -418,6 +418,9 @@ pci_free_irq_vectors(pdata->pcidev); + /* Disable all interrupts in the hardware */ + XP_IOWRITE(pdata, XP_INT_EN, 0x0); + xgbe_free_pdata(pdata); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -188,6 +188,7 @@ XGBE_SFP_CABLE_UNKNOWN = 0, XGBE_SFP_CABLE_ACTIVE, XGBE_SFP_CABLE_PASSIVE, + XGBE_SFP_CABLE_FIBER, }; enum xgbe_sfp_base { @@ -235,9 +236,7 @@ #define XGBE_SFP_BASE_BR 12 #define XGBE_SFP_BASE_BR_1GBE_MIN 0x0a -#define XGBE_SFP_BASE_BR_1GBE_MAX 0x0d #define XGBE_SFP_BASE_BR_10GBE_MIN 0x64 -#define XGBE_SFP_BASE_BR_10GBE_MAX 0x68 #define XGBE_SFP_BASE_CU_CABLE_LEN 18 @@ -283,6 +282,8 @@ #define XGBE_BEL_FUSE_VENDOR "BEL-FUSE " #define XGBE_BEL_FUSE_PARTNO "1GBT-SFP06 " +#define XGBE_MOLEX_VENDOR "Molex Inc. " + struct xgbe_sfp_ascii { union { char vendor[XGBE_SFP_BASE_VENDOR_NAME_LEN + 1]; @@ -822,25 +823,22 @@ static bool xgbe_phy_sfp_bit_rate(struct xgbe_sfp_eeprom *sfp_eeprom, enum xgbe_sfp_speed sfp_speed) { - u8 *sfp_base, min, max; + u8 *sfp_base, min; sfp_base = sfp_eeprom->base; switch (sfp_speed) { case XGBE_SFP_SPEED_1000: min = XGBE_SFP_BASE_BR_1GBE_MIN; - max = XGBE_SFP_BASE_BR_1GBE_MAX; break; case XGBE_SFP_SPEED_10000: min = XGBE_SFP_BASE_BR_10GBE_MIN; - max = XGBE_SFP_BASE_BR_10GBE_MAX; break; default: return false; } - return ((sfp_base[XGBE_SFP_BASE_BR] >= min) && - (sfp_base[XGBE_SFP_BASE_BR] <= max)); + return sfp_base[XGBE_SFP_BASE_BR] >= min; } static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata) @@ -857,7 +855,6 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; struct xgbe_phy_data *phy_data = pdata->phy_data; unsigned int phy_id = phy_data->phydev->phy_id; @@ -879,14 +876,7 @@ phy_write(phy_data->phydev, 0x04, 0x0d01); phy_write(phy_data->phydev, 0x00, 0x9140); - linkmode_set_bit_array(phy_10_100_features_array, - ARRAY_SIZE(phy_10_100_features_array), - supported); - linkmode_set_bit_array(phy_gbit_features_array, - ARRAY_SIZE(phy_gbit_features_array), - supported); - - linkmode_copy(phy_data->phydev->supported, supported); + linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); phy_support_asym_pause(phy_data->phydev); @@ -898,7 +888,6 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; unsigned int phy_id = phy_data->phydev->phy_id; @@ -921,6 +910,9 @@ if ((phy_id & 0xfffffff0) != 0x03625d10) return false; + /* Reset PHY - wait for self-clearing reset bit to clear */ + genphy_soft_reset(phy_data->phydev); + /* Disable RGMII mode */ phy_write(phy_data->phydev, 0x18, 0x7007); reg = phy_read(phy_data->phydev, 0x18); @@ -959,13 +951,7 @@ reg = phy_read(phy_data->phydev, 0x00); phy_write(phy_data->phydev, 0x00, reg & ~0x00800); - linkmode_set_bit_array(phy_10_100_features_array, - ARRAY_SIZE(phy_10_100_features_array), - supported); - linkmode_set_bit_array(phy_gbit_features_array, - ARRAY_SIZE(phy_gbit_features_array), - supported); - linkmode_copy(phy_data->phydev->supported, supported); + linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES); phy_support_asym_pause(phy_data->phydev); netif_dbg(pdata, drv, pdata->netdev, @@ -1138,16 +1124,21 @@ phy_data->sfp_tx_fault = xgbe_phy_check_sfp_tx_fault(phy_data); phy_data->sfp_rx_los = xgbe_phy_check_sfp_rx_los(phy_data); - /* Assume ACTIVE cable unless told it is PASSIVE */ + /* Assume FIBER cable unless told otherwise */ if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_PASSIVE) { phy_data->sfp_cable = XGBE_SFP_CABLE_PASSIVE; phy_data->sfp_cable_len = sfp_base[XGBE_SFP_BASE_CU_CABLE_LEN]; - } else { + } else if (sfp_base[XGBE_SFP_BASE_CABLE] & XGBE_SFP_BASE_CABLE_ACTIVE) { phy_data->sfp_cable = XGBE_SFP_CABLE_ACTIVE; + } else { + phy_data->sfp_cable = XGBE_SFP_CABLE_FIBER; } /* Determine the type of SFP */ - if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR) + if (phy_data->sfp_cable != XGBE_SFP_CABLE_FIBER && + xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000)) + phy_data->sfp_base = XGBE_SFP_BASE_10000_CR; + else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_SR) phy_data->sfp_base = XGBE_SFP_BASE_10000_SR; else if (sfp_base[XGBE_SFP_BASE_10GBE_CC] & XGBE_SFP_BASE_10GBE_CC_LR) phy_data->sfp_base = XGBE_SFP_BASE_10000_LR; @@ -1163,9 +1154,6 @@ phy_data->sfp_base = XGBE_SFP_BASE_1000_CX; else if (sfp_base[XGBE_SFP_BASE_1GBE_CC] & XGBE_SFP_BASE_1GBE_CC_T) phy_data->sfp_base = XGBE_SFP_BASE_1000_T; - else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) && - xgbe_phy_sfp_bit_rate(sfp_eeprom, XGBE_SFP_SPEED_10000)) - phy_data->sfp_base = XGBE_SFP_BASE_10000_CR; switch (phy_data->sfp_base) { case XGBE_SFP_BASE_1000_T: @@ -1948,16 +1936,53 @@ xgbe_phy_put_comm_ownership(pdata); } +static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) +{ + int reg; + + reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PCS, MDIO_PCS_DIGITAL_STAT, + XGBE_PCS_PSEQ_STATE_MASK); + if (reg == XGBE_PCS_PSEQ_STATE_POWER_GOOD) { + /* Mailbox command timed out, reset of RX block is required. + * This can be done by asseting the reset bit and wait for + * its compeletion. + */ + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_ON); + ndelay(20); + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_CTRL1, + XGBE_PMA_RX_RST_0_MASK, XGBE_PMA_RX_RST_0_RESET_OFF); + usleep_range(40, 50); + netif_err(pdata, link, pdata->netdev, "firmware mailbox reset performed\n"); + } +} + +static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable) +{ + XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0, + XGBE_PMA_PLL_CTRL_MASK, + enable ? XGBE_PMA_PLL_CTRL_ENABLE + : XGBE_PMA_PLL_CTRL_DISABLE); + + /* Wait for command to complete */ + usleep_range(100, 200); +} + static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, unsigned int cmd, unsigned int sub_cmd) { unsigned int s0 = 0; unsigned int wait; + /* Disable PLL re-initialization during FW command processing */ + xgbe_phy_pll_ctrl(pdata, false); + /* Log if a previous command did not complete */ - if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) + if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) { netif_dbg(pdata, link, pdata->netdev, "firmware mailbox not ready for command\n"); + xgbe_phy_rx_reset(pdata); + } /* Construct the command */ XP_SET_BITS(s0, XP_DRIVER_SCRATCH_0, COMMAND, cmd); @@ -1972,13 +1997,20 @@ wait = XGBE_RATECHANGE_COUNT; while (wait--) { if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) - return; + goto reenable_pll; usleep_range(1000, 2000); } netif_dbg(pdata, link, pdata->netdev, "firmware mailbox command did not complete\n"); + + /* Reset on error */ + xgbe_phy_rx_reset(pdata); + +reenable_pll: + /* Enable PLL re-initialization */ + xgbe_phy_pll_ctrl(pdata, true); } static void xgbe_phy_rrc(struct xgbe_prv_data *pdata) @@ -2575,6 +2607,14 @@ if (reg & MDIO_STAT1_LSTATUS) return 1; + if (pdata->phy.autoneg == AUTONEG_ENABLE && + phy_data->port_mode == XGBE_PORT_MODE_BACKPLANE) { + if (!test_bit(XGBE_LINK_INIT, &pdata->dev_state)) { + netif_carrier_off(pdata->netdev); + *an_restart = 1; + } + } + /* No link, attempt a receiver reset cycle */ if (phy_data->rrc_count++ > XGBE_RRC_FREQUENCY) { phy_data->rrc_count = 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/amd/xgbe/xgbe.h +++ linux-oracle-5.4.0/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -181,9 +181,9 @@ #define XGBE_DMA_SYS_AWCR 0x30303030 /* DMA cache settings - PCI device */ -#define XGBE_DMA_PCI_ARCR 0x00000003 -#define XGBE_DMA_PCI_AWCR 0x13131313 -#define XGBE_DMA_PCI_AWARCR 0x00000313 +#define XGBE_DMA_PCI_ARCR 0x000f0f0f +#define XGBE_DMA_PCI_AWCR 0x0f0f0f0f +#define XGBE_DMA_PCI_AWARCR 0x00000f0f /* DMA channel interrupt modes */ #define XGBE_IRQ_MODE_EDGE 0 @@ -290,6 +290,7 @@ /* Auto-negotiation */ #define XGBE_AN_MS_TIMEOUT 500 #define XGBE_LINK_TIMEOUT 5 +#define XGBE_KR_TRAINING_WAIT_ITER 50 #define XGBE_SGMII_AN_LINK_STATUS BIT(1) #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) @@ -1266,6 +1267,7 @@ unsigned int parallel_detect; unsigned int fec_ability; unsigned long an_start; + unsigned long kr_start_time; enum xgbe_an_mode an_mode; /* I2C support */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/apm/xgene-v2/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/apm/xgene-v2/main.c @@ -677,11 +677,13 @@ ret = register_netdev(ndev); if (ret) { netdev_err(ndev, "Failed to register netdev\n"); - goto err; + goto err_mdio_remove; } return 0; +err_mdio_remove: + xge_mdio_remove(ndev); err: free_netdev(ndev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -696,6 +696,12 @@ buf_pool->rx_skb[skb_index] = NULL; datalen = xgene_enet_get_data_len(le64_to_cpu(raw_desc->m1)); + + /* strip off CRC as HW isn't doing this */ + nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); + if (!nv) + datalen -= 4; + skb_put(skb, datalen); prefetch(skb->data - NET_IP_ALIGN); skb->protocol = eth_type_trans(skb, ndev); @@ -717,12 +723,8 @@ } } - nv = GET_VAL(NV, le64_to_cpu(raw_desc->m0)); - if (!nv) { - /* strip off CRC as HW isn't doing this */ - datalen -= 4; + if (!nv) goto skip_jumbo; - } slots = page_pool->slots - 1; head = page_pool->head; @@ -1002,8 +1004,10 @@ xgene_enet_napi_enable(pdata); ret = xgene_enet_register_irq(ndev); - if (ret) + if (ret) { + xgene_enet_napi_disable(pdata); return ret; + } if (ndev->phydev) { phy_start(ndev->phydev); @@ -2020,7 +2024,7 @@ int ret; ndev = alloc_etherdev_mqs(sizeof(struct xgene_enet_pdata), - XGENE_NUM_RX_RING, XGENE_NUM_TX_RING); + XGENE_NUM_TX_RING, XGENE_NUM_RX_RING); if (!ndev) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/apm/xgene/xgene_enet_main.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,6 @@ #include "xgene_enet_hw.h" #include "xgene_enet_cle.h" #include "xgene_enet_ring2.h" -#include "../../../phy/mdio-xgene.h" #define XGENE_DRV_VERSION "v1.0" #define ETHER_MIN_PACKET 64 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/apple/bmac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/apple/bmac.c @@ -1182,7 +1182,7 @@ int i; unsigned short data; - for (i = 0; i < 6; i++) + for (i = 0; i < 3; i++) { reset_and_select_srom(dev); data = read_srom(dev, i + EnetAddressOffset/2, SROMAddressBits); @@ -1511,7 +1511,7 @@ i = bp->tx_empty; ++dev->stats.tx_errors; if (i != bp->tx_fill) { - dev_kfree_skb(bp->tx_bufs[i]); + dev_kfree_skb_irq(bp->tx_bufs[i]); bp->tx_bufs[i] = NULL; if (++i >= N_TX_RING) i = 0; bp->tx_empty = i; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/apple/mace.c +++ linux-oracle-5.4.0/drivers/net/ethernet/apple/mace.c @@ -841,7 +841,7 @@ if (mp->tx_bad_runt) { mp->tx_bad_runt = 0; } else if (i != mp->tx_fill) { - dev_kfree_skb(mp->tx_bufs[i]); + dev_kfree_skb_irq(mp->tx_bufs[i]); if (++i >= N_TX_RING) i = 0; mp->tx_empty = i; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -158,7 +158,7 @@ } if ((aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) && - (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci), + (!test_bit(be16_to_cpu(fsp->h_ext.vlan_tci) & VLAN_VID_MASK, aq_nic->active_vlans))) { netdev_err(aq_nic->ndev, "ethtool: unknown vlan-id specified"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_hw.h @@ -230,7 +230,7 @@ struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self); - int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version); + u32 (*hw_get_fw_version)(struct aq_hw_s *self); int (*hw_set_offload)(struct aq_hw_s *self, struct aq_nic_cfg_s *aq_nic_cfg); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_main.c @@ -66,8 +66,10 @@ goto err_exit; err = aq_nic_start(aq_nic); - if (err < 0) + if (err < 0) { + aq_nic_stop(aq_nic); goto err_exit; + } err_exit: if (err < 0) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_nic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_nic.c @@ -467,8 +467,10 @@ dx_buff->len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) + if (unlikely(dma_mapping_error(aq_nic_get_dev(self), dx_buff->pa))) { + ret = 0; goto exit; + } first = dx_buff; dx_buff->len_pkt = skb->len; @@ -598,10 +600,6 @@ if (likely(frags)) { err = self->aq_hw_ops->hw_ring_tx_xmit(self->aq_hw, ring, frags); - if (err >= 0) { - ++ring->stats.tx.packets; - ring->stats.tx.bytes += skb->len; - } } else { err = NETDEV_TX_BUSY; } @@ -692,6 +690,9 @@ u32 *regs_buff = p; int err = 0; + if (unlikely(!self->aq_hw_ops->hw_get_regs)) + return -EOPNOTSUPP; + regs->version = 1; err = self->aq_hw_ops->hw_get_regs(self->aq_hw, @@ -706,6 +707,9 @@ int aq_nic_get_regs_count(struct aq_nic_s *self) { + if (unlikely(!self->aq_hw_ops->hw_get_regs)) + return 0; + return self->aq_nic_cfg.aq_hw_caps->mac_regs_count; } @@ -899,7 +903,6 @@ default: err = -1; goto err_exit; - break; } if (!(self->aq_nic_cfg.aq_hw_caps->link_speed_msk & rate)) { err = -1; @@ -928,11 +931,7 @@ u32 aq_nic_get_fw_version(struct aq_nic_s *self) { - u32 fw_version = 0U; - - self->aq_hw_ops->hw_get_fw_version(self->aq_hw, &fw_version); - - return fw_version; + return self->aq_hw_ops->hw_get_fw_version(self->aq_hw); } int aq_nic_stop(struct aq_nic_s *self) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -56,7 +56,7 @@ { AQ_DEVICE_ID_D108, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc108, }, { AQ_DEVICE_ID_D109, AQ_HWREV_2, &hw_atl_ops_b0, &hw_atl_b0_caps_aqc109, }, - { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, + { AQ_DEVICE_ID_AQC100, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc100, }, { AQ_DEVICE_ID_AQC107, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc107, }, { AQ_DEVICE_ID_AQC108, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc108, }, { AQ_DEVICE_ID_AQC109, AQ_HWREV_ANY, &hw_atl_ops_b1, &hw_atl_b0_caps_aqc109, }, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -92,8 +92,8 @@ return 0; } -static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic) +static int aq_ring_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic) { int err = 0; @@ -115,44 +115,29 @@ err_exit: if (err < 0) { aq_ring_free(self); - self = NULL; } - return self; + + return err; } -struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg) +int aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) { - int err = 0; - self->aq_nic = aq_nic; self->idx = idx; self->size = aq_nic_cfg->txds; self->dx_size = aq_nic_cfg->aq_hw_caps->txd_size; - self = aq_ring_alloc(self, aq_nic); - if (!self) { - err = -ENOMEM; - goto err_exit; - } - -err_exit: - if (err < 0) { - aq_ring_free(self); - self = NULL; - } - return self; + return aq_ring_alloc(self, aq_nic); } -struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg) +int aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) { - int err = 0; - self->aq_nic = aq_nic; self->idx = idx; self->size = aq_nic_cfg->rxds; @@ -163,18 +148,7 @@ if (aq_nic_cfg->rxpageorder > self->page_order) self->page_order = aq_nic_cfg->rxpageorder; - self = aq_ring_alloc(self, aq_nic); - if (!self) { - err = -ENOMEM; - goto err_exit; - } - -err_exit: - if (err < 0) { - aq_ring_free(self); - self = NULL; - } - return self; + return aq_ring_alloc(self, aq_nic); } int aq_ring_init(struct aq_ring_s *self) @@ -243,9 +217,12 @@ } } - if (unlikely(buff->is_eop)) - dev_kfree_skb_any(buff->skb); + if (unlikely(buff->is_eop)) { + ++self->stats.rx.packets; + self->stats.tx.bytes += buff->skb->len; + dev_kfree_skb_any(buff->skb); + } buff->pa = 0U; buff->eop_index = 0xffffU; self->sw_head = aq_ring_next_dx(self, self->sw_head); @@ -302,6 +279,10 @@ if (!buff->is_eop) { buff_ = buff; do { + if (buff_->next >= self->size) { + err = -EIO; + goto err_exit; + } next_ = buff_->next, buff_ = &self->buff_ring[next_]; is_rsc_completed = @@ -324,6 +305,10 @@ if (buff->is_error || buff->is_cso_err) { buff_ = buff; do { + if (buff_->next >= self->size) { + err = -EIO; + goto err_exit; + } next_ = buff_->next, buff_ = &self->buff_ring[next_]; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -153,14 +153,14 @@ self->sw_head - self->sw_tail - 1); } -struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg); -struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg); +int aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); +int aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); int aq_ring_init(struct aq_ring_s *self); void aq_ring_rx_deinit(struct aq_ring_s *self); void aq_ring_free(struct aq_ring_s *self); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -133,21 +133,18 @@ self->tx_rings, self->aq_ring_param.vec_idx); - ring = aq_ring_tx_alloc(&self->ring[i][AQ_VEC_TX_ID], aq_nic, - idx_ring, aq_nic_cfg); - if (!ring) { - err = -ENOMEM; + ring = &self->ring[i][AQ_VEC_TX_ID]; + err = aq_ring_tx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); + if (err) goto err_exit; - } ++self->tx_rings; aq_nic_set_tx_ring(aq_nic, idx_ring, ring); - ring = aq_ring_rx_alloc(&self->ring[i][AQ_VEC_RX_ID], aq_nic, - idx_ring, aq_nic_cfg); - if (!ring) { - err = -ENOMEM; + ring = &self->ring[i][AQ_VEC_RX_ID]; + err = aq_ring_rx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); + if (err) { goto err_exit; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c @@ -776,7 +776,7 @@ int err = 0; if (count > (HW_ATL_A0_MAC_MAX - HW_ATL_A0_MAC_MIN)) { - err = EBADRQC; + err = -EBADRQC; goto err_exit; } for (self->aq_nic_cfg->mc_list_count = 0U; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -674,6 +674,13 @@ err = -ENXIO; goto err_exit; } + + /* Validate that the new hw_head_ is reasonable. */ + if (hw_head_ >= ring->size) { + err = -ENXIO; + goto err_exit; + } + ring->hw_head = hw_head_; err = aq_hw_err_from_flags(self); @@ -1097,7 +1104,7 @@ return aq_hw_err_from_flags(self); } -/** +/* * @brief Set VLAN filter table * @details Configure VLAN filter table to accept (and assign the queue) traffic * for the particular vlan ids. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c @@ -1597,7 +1597,7 @@ for (i = 0; i < 4; ++i) aq_hw_write_reg(aq_hw, HW_ATL_RPF_L3_SRCA_ADR(location + i), - ipv6_src[i]); + ipv6_src[3 - i]); } void hw_atl_rpfl3l4_ipv6_dest_addr_set(struct aq_hw_s *aq_hw, u8 location, @@ -1608,7 +1608,7 @@ for (i = 0; i < 4; ++i) aq_hw_write_reg(aq_hw, HW_ATL_RPF_L3_DSTA_ADR(location + i), - ipv6_dest[i]); + ipv6_dest[3 - i]); } u32 hw_atl_sem_ram_get(struct aq_hw_s *self) @@ -1616,6 +1616,16 @@ return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM); } +u32 hw_atl_sem_reset1_get(struct aq_hw_s *self) +{ + return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RESET1); +} + +u32 hw_atl_sem_reset2_get(struct aq_hw_s *self) +{ + return hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RESET2); +} + u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp) { return aq_hw_read_reg(aq_hw, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h @@ -755,6 +755,9 @@ /* get global microprocessor ram semaphore */ u32 hw_atl_sem_ram_get(struct aq_hw_s *self); +u32 hw_atl_sem_reset1_get(struct aq_hw_s *self); +u32 hw_atl_sem_reset2_get(struct aq_hw_s *self); + /* get global microprocessor scratch pad register */ u32 hw_atl_scrpad_get(struct aq_hw_s *aq_hw, u32 scratch_scp); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h @@ -2564,7 +2564,7 @@ */ /* Register address for bitfield pif_rpf_l3_da0_i[31:0] */ -#define HW_ATL_RPF_L3_DSTA_ADR(location) (0x000053B0 + (location) * 0x4) +#define HW_ATL_RPF_L3_DSTA_ADR(filter) (0x000053D0 + (filter) * 0x4) /* Bitmask for bitfield l3_da0[1F:0] */ #define HW_ATL_RPF_L3_DSTA_MSK 0xFFFFFFFFu /* Inverted bitmask for bitfield l3_da0[1F:0] */ @@ -2576,6 +2576,10 @@ /* Default value of bitfield l3_da0[1F:0] */ #define HW_ATL_RPF_L3_DSTA_DEFAULT 0x0 +#define HW_ATL_MIF_RESET_TIMEOUT_ADR 0x00000348 + #define HW_ATL_FW_SM_RAM 0x2U +#define HW_ATL_FW_SM_RESET1 0x3U +#define HW_ATL_FW_SM_RESET2 0x4U #endif /* HW_ATL_LLH_INTERNAL_H */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c @@ -22,6 +22,7 @@ #define HW_ATL_MIF_ADDR 0x0208U #define HW_ATL_MIF_VAL 0x020CU +#define HW_ATL_MPI_RPC_ADDR 0x0334U #define HW_ATL_RPC_CONTROL_ADR 0x0338U #define HW_ATL_RPC_STATE_ADR 0x033CU @@ -44,19 +45,18 @@ #define HW_ATL_FW_VER_1X 0x01050006U #define HW_ATL_FW_VER_2X 0x02000000U #define HW_ATL_FW_VER_3X 0x03000000U +#define HW_ATL_FW_VER_4X 0x04000000U #define FORCE_FLASHLESS 0 -static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); - static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self, - enum hal_atl_utils_fw_state_e state); - + enum hal_atl_utils_fw_state_e state); static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self); static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self); static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self); static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self); static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self); +static u32 aq_fw1x_rpc_get(struct aq_hw_s *self); int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops) { @@ -67,22 +67,21 @@ return err; hw_atl_utils_hw_chip_features_init(self, - &self->chip_features); + &self->chip_features); - hw_atl_utils_get_fw_version(self, &self->fw_ver_actual); + self->fw_ver_actual = hw_atl_utils_get_fw_version(self); - if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, - self->fw_ver_actual) == 0) { + if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, self->fw_ver_actual)) { *fw_ops = &aq_fw_1x_ops; - } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, - self->fw_ver_actual) == 0) { + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X, self->fw_ver_actual)) { + *fw_ops = &aq_fw_2x_ops; + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, self->fw_ver_actual)) { *fw_ops = &aq_fw_2x_ops; - } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X, - self->fw_ver_actual) == 0) { + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, self->fw_ver_actual)) { *fw_ops = &aq_fw_2x_ops; } else { aq_pr_err("Bad FW version detected: %x\n", - self->fw_ver_actual); + self->fw_ver_actual); return -EOPNOTSUPP; } self->aq_fw_ops = *fw_ops; @@ -121,7 +120,7 @@ for (k = 0; k < 1000; k++) { u32 flb_status = aq_hw_read_reg(self, - HW_ATL_MPI_DAISY_CHAIN_STATUS); + HW_ATL_MPI_DAISY_CHAIN_STATUS); flb_status = flb_status & 0x10; if (flb_status) @@ -144,8 +143,8 @@ hw_atl_rx_rx_reg_res_dis_set(self, 0U); hw_atl_tx_tx_reg_res_dis_set(self, 0U); aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, - BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), - HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); + BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), + HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000); @@ -186,8 +185,8 @@ hw_atl_rx_rx_reg_res_dis_set(self, 0U); hw_atl_tx_tx_reg_res_dis_set(self, 0U); aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL, - BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), - HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); + BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT), + HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0); gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR); aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xFFFFBFFF) | 0x8000); @@ -238,14 +237,15 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self) { int k; + int ver = hw_atl_utils_get_fw_version(self); u32 boot_exit_code = 0; u32 val; for (k = 0; k < 1000; ++k) { u32 flb_status = aq_hw_read_reg(self, - HW_ATL_MPI_DAISY_CHAIN_STATUS); + HW_ATL_MPI_DAISY_CHAIN_STATUS); boot_exit_code = aq_hw_read_reg(self, - HW_ATL_MPI_BOOT_EXIT_CODE); + HW_ATL_MPI_BOOT_EXIT_CODE); if (flb_status != 0x06000000 || boot_exit_code != 0) break; } @@ -257,22 +257,41 @@ self->rbl_enabled = (boot_exit_code != 0); - /* FW 1.x may bootup in an invalid POWER state (WOL feature). - * We should work around this by forcing its state back to DEINIT - */ - if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, - aq_hw_read_reg(self, - HW_ATL_MPI_FW_VERSION))) { + if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, ver)) { int err = 0; + /* FW 1.x may bootup in an invalid POWER state (WOL feature). + * We should work around this by forcing its state back to DEINIT + */ hw_atl_utils_mpi_set_state(self, MPI_DEINIT); err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state, - self, val, - (val & HW_ATL_MPI_STATE_MSK) == - MPI_DEINIT, - 10, 10000U); + self, val, + (val & HW_ATL_MPI_STATE_MSK) == + MPI_DEINIT, + 10, 10000U); if (err) return err; + } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_4X, ver)) { + u64 sem_timeout = aq_hw_read_reg(self, HW_ATL_MIF_RESET_TIMEOUT_ADR); + + /* Acquire 2 semaphores before issuing reset for FW 4.x */ + if (sem_timeout > 3000) + sem_timeout = 3000; + sem_timeout = sem_timeout * 1000; + + if (sem_timeout != 0) { + int err; + + err = readx_poll_timeout_atomic(hw_atl_sem_reset1_get, self, val, + val == 1U, 1U, sem_timeout); + if (err) + aq_pr_err("reset sema1 timeout"); + + err = readx_poll_timeout_atomic(hw_atl_sem_reset2_get, self, val, + val == 1U, 1U, sem_timeout); + if (err) + aq_pr_err("reset sema2 timeout"); + } } if (self->rbl_enabled) @@ -282,14 +301,14 @@ } int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a, - u32 *p, u32 cnt) + u32 *p, u32 cnt) { int err = 0; u32 val; err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, - self, val, val == 1U, - 1U, 10000U); + self, val, val == 1U, + 1U, 10000U); if (err < 0) { bool is_locked; @@ -309,13 +328,13 @@ if (IS_CHIP_FEATURE(REVISION_B1)) err = readx_poll_timeout_atomic(hw_atl_utils_mif_addr_get, - self, val, val != a, - 1U, 1000U); + self, val, val != a, + 1U, 1000U); else err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get, - self, val, - !(val & 0x100), - 1U, 1000U); + self, val, + !(val & 0x100), + 1U, 1000U); *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL); a += 4; @@ -328,14 +347,14 @@ } static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, - u32 cnt) + u32 cnt) { u32 val; int err = 0; err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self, - val, val == 1U, - 10U, 100000U); + val, val == 1U, + 10U, 100000U); if (err < 0) goto err_exit; @@ -349,10 +368,10 @@ hw_atl_mcp_up_force_intr_set(self, 1); /* 1000 times by 10us = 10ms */ err = readx_poll_timeout_atomic(hw_atl_scrpad12_get, - self, val, - (val & 0xF0000000) != - 0x80000000, - 10U, 10000U); + self, val, + (val & 0xF0000000) != + 0x80000000, + 10U, 10000U); } } else { u32 offset = 0; @@ -364,9 +383,9 @@ aq_hw_write_reg(self, 0x200, 0xC000); err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get, - self, val, - (val & 0x100) == 0, - 1000U, 10000U); + self, val, + (val & 0x100) == 0, + 1000U, 10000U); } } @@ -376,19 +395,21 @@ return err; } -static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual) +bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual) { - int err = 0; const u32 dw_major_mask = 0xff000000U; const u32 dw_minor_mask = 0x00ffffffU; + bool ver_match; - err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0; - if (err < 0) + ver_match = (dw_major_mask & (ver_expected ^ ver_actual)) ? false : true; + if (!ver_match) goto err_exit; - err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ? - -EOPNOTSUPP : 0; + + ver_match = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ? + false : true; + err_exit: - return err; + return ver_match; } static int hw_atl_utils_init_ucp(struct aq_hw_s *self, @@ -413,6 +434,10 @@ self, self->mbox_addr, self->mbox_addr != 0U, 1000U, 10000U); + err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self, + self->rpc_addr, + self->rpc_addr != 0U, + 1000U, 100000U); return err; } @@ -469,8 +494,19 @@ self, fw.val, sw.tid == fw.tid, 1000U, 100000U); + if (err < 0) + goto err_exit; + + err = aq_hw_err_from_flags(self); + if (err < 0) + goto err_exit; if (fw.len == 0xFFFFU) { + if (sw.len > sizeof(self->rpc)) { + printk(KERN_INFO "Invalid sw len: %x\n", sw.len); + err = -EINVAL; + goto err_exit; + } err = hw_atl_utils_fw_rpc_call(self, sw.len); if (err < 0) goto err_exit; @@ -479,6 +515,11 @@ if (rpc) { if (fw.len) { + if (fw.len > sizeof(self->rpc)) { + printk(KERN_INFO "Invalid fw len: %x\n", fw.len); + err = -EINVAL; + goto err_exit; + } err = hw_atl_utils_fw_downld_dwords(self, self->rpc_addr, @@ -840,10 +881,9 @@ return 0; } -int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version) +u32 hw_atl_utils_get_fw_version(struct aq_hw_s *self) { - *fw_version = aq_hw_read_reg(self, 0x18U); - return 0; + return aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION); } static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac) @@ -950,6 +990,11 @@ return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR); } +static u32 aq_fw1x_rpc_get(struct aq_hw_s *self) +{ + return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR); +} + const struct aq_fw_ops aq_fw_1x_ops = { .init = hw_atl_utils_mpi_create, .deinit = hw_atl_fw1x_deinit, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h +++ linux-oracle-5.4.0/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h @@ -466,7 +466,7 @@ int hw_atl_utils_hw_deinit(struct aq_hw_s *self); -int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); +u32 hw_atl_utils_get_fw_version(struct aq_hw_s *self); int hw_atl_utils_update_stats(struct aq_hw_s *self); @@ -482,6 +482,8 @@ int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self, struct hw_atl_utils_fw_rpc **rpc); +bool hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual); + extern const struct aq_fw_ops aq_fw_1x_ops; extern const struct aq_fw_ops aq_fw_2x_ops; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/arc/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/arc/Kconfig @@ -21,6 +21,7 @@ depends on ARC || ARCH_ROCKCHIP || COMPILE_TEST select MII select PHYLIB + select CRC32 config ARC_EMAC tristate "ARC EMAC support" --- linux-oracle-5.4.0.orig/drivers/net/ethernet/arc/emac_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/arc/emac_mdio.c @@ -153,6 +153,7 @@ if (IS_ERR(data->reset_gpio)) { error = PTR_ERR(data->reset_gpio); dev_err(priv->dev, "Failed to request gpio: %d\n", error); + mdiobus_free(bus); return error; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/ag71xx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/ag71xx.c @@ -222,8 +222,6 @@ #define AG71XX_REG_RX_SM 0x01b0 #define AG71XX_REG_TX_SM 0x01b4 -#define ETH_SWITCH_HEADER_LEN 2 - #define AG71XX_DEFAULT_MSG_ENABLE \ (NETIF_MSG_DRV \ | NETIF_MSG_PROBE \ @@ -553,7 +551,8 @@ ag->mdio_reset = of_reset_control_get_exclusive(np, "mdio"); if (IS_ERR(ag->mdio_reset)) { netif_err(ag, probe, ndev, "Failed to get reset mdio.\n"); - return PTR_ERR(ag->mdio_reset); + err = PTR_ERR(ag->mdio_reset); + goto mdio_err_put_clk; } mii_bus->name = "ag71xx_mdio"; @@ -783,7 +782,7 @@ static unsigned int ag71xx_max_frame_len(unsigned int mtu) { - return ETH_SWITCH_HEADER_LEN + ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN; + return ETH_HLEN + VLAN_HLEN + mtu + ETH_FCS_LEN; } static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/alx/ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/alx/ethtool.c @@ -46,6 +46,8 @@ #include "reg.h" #include "hw.h" +extern const bool enable_wol; + /* The order of these strings must match the order of the fields in * struct alx_hw_stats * See hw.h @@ -281,9 +283,8 @@ spin_lock(&alx->stats_lock); alx_update_hw_stats(hw); - BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) < - ALX_NUM_STATS * sizeof(u64)); - memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64)); + BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64)); + memcpy(data, &hw->stats, sizeof(hw->stats)); spin_unlock(&alx->stats_lock); } @@ -310,11 +311,50 @@ } } +static void alx_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct alx_priv *alx = netdev_priv(netdev); + struct alx_hw *hw = &alx->hw; + + if (!enable_wol) + return; + + wol->supported = WAKE_MAGIC | WAKE_PHY; + wol->wolopts = 0; + + if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) + wol->wolopts |= WAKE_MAGIC; + if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) + wol->wolopts |= WAKE_PHY; +} + +static int alx_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct alx_priv *alx = netdev_priv(netdev); + struct alx_hw *hw = &alx->hw; + + if (!enable_wol || (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY))) + return -EOPNOTSUPP; + + hw->sleep_ctrl = 0; + + if (wol->wolopts & WAKE_MAGIC) + hw->sleep_ctrl |= ALX_SLEEP_WOL_MAGIC; + if (wol->wolopts & WAKE_PHY) + hw->sleep_ctrl |= ALX_SLEEP_WOL_PHY; + + device_set_wakeup_enable(&alx->hw.pdev->dev, hw->sleep_ctrl); + + return 0; +} + const struct ethtool_ops alx_ethtool_ops = { .get_pauseparam = alx_get_pauseparam, .set_pauseparam = alx_set_pauseparam, .get_msglevel = alx_get_msglevel, .set_msglevel = alx_set_msglevel, + .get_wol = alx_get_wol, + .set_wol = alx_set_wol, .get_link = ethtool_op_get_link, .get_strings = alx_get_strings, .get_sset_count = alx_get_sset_count, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/alx/hw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/alx/hw.c @@ -332,6 +332,16 @@ alx_write_mem32(hw, ALX_STAD1, val); } +static void alx_enable_osc(struct alx_hw *hw) +{ + u32 val; + + /* rising edge */ + val = alx_read_mem32(hw, ALX_MISC); + alx_write_mem32(hw, ALX_MISC, val & ~ALX_MISC_INTNLOSC_OPEN); + alx_write_mem32(hw, ALX_MISC, val | ALX_MISC_INTNLOSC_OPEN); +} + static void alx_reset_osc(struct alx_hw *hw, u8 rev) { u32 val, val2; @@ -774,7 +784,6 @@ return err; } - void alx_post_phy_link(struct alx_hw *hw) { u16 phy_val, len, agc; @@ -848,6 +857,65 @@ } } +/* NOTE: + * 1. phy link must be established before calling this function + * 2. wol option (pattern,magic,link,etc.) is configed before call it. + */ +int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex) +{ + u32 master, mac, phy, val; + int err = 0; + + master = alx_read_mem32(hw, ALX_MASTER); + master &= ~ALX_MASTER_PCLKSEL_SRDS; + mac = hw->rx_ctrl; + /* 10/100 half */ + ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, ALX_MAC_CTRL_SPEED_10_100); + mac &= ~(ALX_MAC_CTRL_FULLD | ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_TX_EN); + + phy = alx_read_mem32(hw, ALX_PHY_CTRL); + phy &= ~(ALX_PHY_CTRL_DSPRST_OUT | ALX_PHY_CTRL_CLS); + phy |= ALX_PHY_CTRL_RST_ANALOG | ALX_PHY_CTRL_HIB_PULSE | + ALX_PHY_CTRL_HIB_EN; + + /* without any activity */ + if (!(hw->sleep_ctrl & ALX_SLEEP_ACTIVE)) { + err = alx_write_phy_reg(hw, ALX_MII_IER, 0); + if (err) + return err; + phy |= ALX_PHY_CTRL_IDDQ | ALX_PHY_CTRL_POWER_DOWN; + } else { + if (hw->sleep_ctrl & (ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_CIFS)) + mac |= ALX_MAC_CTRL_RX_EN | ALX_MAC_CTRL_BRD_EN; + if (hw->sleep_ctrl & ALX_SLEEP_CIFS) + mac |= ALX_MAC_CTRL_TX_EN; + if (duplex == DUPLEX_FULL) + mac |= ALX_MAC_CTRL_FULLD; + if (speed == SPEED_1000) + ALX_SET_FIELD(mac, ALX_MAC_CTRL_SPEED, + ALX_MAC_CTRL_SPEED_1000); + phy |= ALX_PHY_CTRL_DSPRST_OUT; + err = alx_write_phy_ext(hw, ALX_MIIEXT_ANEG, + ALX_MIIEXT_S3DIG10, + ALX_MIIEXT_S3DIG10_SL); + if (err) + return err; + } + + alx_enable_osc(hw); + hw->rx_ctrl = mac; + alx_write_mem32(hw, ALX_MASTER, master); + alx_write_mem32(hw, ALX_MAC_CTRL, mac); + alx_write_mem32(hw, ALX_PHY_CTRL, phy); + + /* set val of PDLL D3PLLOFF */ + val = alx_read_mem32(hw, ALX_PDLL_TRNS1); + val |= ALX_PDLL_TRNS1_D3PLLOFF_EN; + alx_write_mem32(hw, ALX_PDLL_TRNS1, val); + + return 0; +} + bool alx_phy_configured(struct alx_hw *hw) { u32 cfg, hw_cfg; @@ -920,6 +988,26 @@ return alx_read_phy_reg(hw, ALX_MII_ISR, &isr); } +int alx_config_wol(struct alx_hw *hw) +{ + u32 wol = 0; + int err = 0; + + /* turn on magic packet event */ + if (hw->sleep_ctrl & ALX_SLEEP_WOL_MAGIC) + wol |= ALX_WOL0_MAGIC_EN | ALX_WOL0_PME_MAGIC_EN; + + /* turn on link up event */ + if (hw->sleep_ctrl & ALX_SLEEP_WOL_PHY) { + wol |= ALX_WOL0_LINK_EN | ALX_WOL0_PME_LINK; + /* only link up can wake up */ + err = alx_write_phy_reg(hw, ALX_MII_IER, ALX_IER_LINK_UP); + } + alx_write_mem32(hw, ALX_WOL0, wol); + + return err; +} + void alx_disable_rss(struct alx_hw *hw) { u32 ctrl = alx_read_mem32(hw, ALX_RXQ0); @@ -1044,6 +1132,70 @@ alx_post_write(hw); } +int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex) +{ + int i, err; + u16 lpa; + + err = alx_read_phy_link(hw); + if (err) + return err; + + if (hw->link_speed == SPEED_UNKNOWN) { + *speed = SPEED_UNKNOWN; + *duplex = DUPLEX_UNKNOWN; + return 0; + } + + err = alx_read_phy_reg(hw, MII_LPA, &lpa); + if (err) + return err; + + if (!(lpa & LPA_LPACK)) { + *speed = hw->link_speed; + return 0; + } + + if (lpa & LPA_10FULL) { + *speed = SPEED_10; + *duplex = DUPLEX_FULL; + } else if (lpa & LPA_10HALF) { + *speed = SPEED_10; + *duplex = DUPLEX_HALF; + } else if (lpa & LPA_100FULL) { + *speed = SPEED_100; + *duplex = DUPLEX_FULL; + } else { + *speed = SPEED_100; + *duplex = DUPLEX_HALF; + } + + if (*speed == hw->link_speed && *duplex == hw->duplex) + return 0; + err = alx_write_phy_reg(hw, ALX_MII_IER, 0); + if (err) + return err; + err = alx_setup_speed_duplex(hw, alx_speed_to_ethadv(*speed, *duplex) | + ADVERTISED_Autoneg, ALX_FC_ANEG | + ALX_FC_RX | ALX_FC_TX); + if (err) + return err; + + /* wait for linkup */ + for (i = 0; i < ALX_MAX_SETUP_LNK_CYCLE; i++) { + msleep(100); + + err = alx_read_phy_link(hw); + if (err < 0) + return err; + if (hw->link_speed != SPEED_UNKNOWN) + break; + } + if (i == ALX_MAX_SETUP_LNK_CYCLE) + return -ETIMEDOUT; + + return 0; +} bool alx_get_phy_info(struct alx_hw *hw) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/alx/hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/alx/hw.h @@ -487,6 +487,8 @@ u8 flowctrl; u32 adv_cfg; + u32 sleep_ctrl; + spinlock_t mdio_lock; struct mdio_if_info mdio; u16 phy_id[2]; @@ -549,12 +551,14 @@ void alx_enable_aspm(struct alx_hw *hw, bool l0s_en, bool l1_en); int alx_setup_speed_duplex(struct alx_hw *hw, u32 ethadv, u8 flowctrl); void alx_post_phy_link(struct alx_hw *hw); +int alx_pre_suspend(struct alx_hw *hw, int speed, u8 duplex); int alx_read_phy_reg(struct alx_hw *hw, u16 reg, u16 *phy_data); int alx_write_phy_reg(struct alx_hw *hw, u16 reg, u16 phy_data); int alx_read_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 *pdata); int alx_write_phy_ext(struct alx_hw *hw, u8 dev, u16 reg, u16 data); int alx_read_phy_link(struct alx_hw *hw); int alx_clear_phy_intr(struct alx_hw *hw); +int alx_config_wol(struct alx_hw *hw); void alx_cfg_mac_flowcontrol(struct alx_hw *hw, u8 fc); void alx_start_mac(struct alx_hw *hw); int alx_reset_mac(struct alx_hw *hw); @@ -563,6 +567,7 @@ void alx_configure_basic(struct alx_hw *hw); void alx_mask_msix(struct alx_hw *hw, int index, bool mask); void alx_disable_rss(struct alx_hw *hw); +int alx_select_powersaving_speed(struct alx_hw *hw, int *speed, u8 *duplex); bool alx_get_phy_info(struct alx_hw *hw); void alx_update_hw_stats(struct alx_hw *hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/alx/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/alx/main.c @@ -51,6 +51,11 @@ static const char alx_drv_name[] = "alx"; +/* disable WoL by default */ +bool enable_wol; +module_param(enable_wol, bool, 0644); +MODULE_PARM_DESC(enable_wol, "Enable Wake on Lan feature"); + static void alx_free_txbuf(struct alx_tx_queue *txq, int entry) { struct alx_buffer *txb = &txq->bufs[entry]; @@ -1069,6 +1074,7 @@ alx->dev->max_mtu = ALX_MAX_FRAME_LEN(ALX_MAX_FRAME_SIZE); alx->tx_ringsz = 256; alx->rx_ringsz = 512; + hw->sleep_ctrl = ALX_SLEEP_WOL_MAGIC | ALX_SLEEP_WOL_PHY; hw->imt = 200; alx->int_mask = ALX_ISR_MISC; hw->dma_chnl = hw->max_dma_chnl; @@ -1249,8 +1255,12 @@ static void __alx_stop(struct alx_priv *alx) { - alx_halt(alx); alx_free_irq(alx); + + cancel_work_sync(&alx->link_check_wk); + cancel_work_sync(&alx->reset_wk); + + alx_halt(alx); alx_free_rings(alx); alx_free_napis(alx); } @@ -1343,6 +1353,66 @@ return 0; } +static int __alx_shutdown(struct pci_dev *pdev, bool *wol_en) +{ + struct alx_priv *alx = pci_get_drvdata(pdev); + struct net_device *netdev = alx->dev; + struct alx_hw *hw = &alx->hw; + int err, speed; + u8 duplex; + + netif_device_detach(netdev); + + if (netif_running(netdev)) + __alx_stop(alx); + +#ifdef CONFIG_PM_SLEEP + err = pci_save_state(pdev); + if (err) + return err; +#endif + + err = alx_select_powersaving_speed(hw, &speed, &duplex); + if (err) + return err; + err = alx_clear_phy_intr(hw); + if (err) + return err; + err = alx_pre_suspend(hw, speed, duplex); + if (err) + return err; + err = alx_config_wol(hw); + if (err) + return err; + + *wol_en = false; + if (hw->sleep_ctrl & ALX_SLEEP_ACTIVE) { + netif_info(alx, wol, netdev, + "wol: ctrl=%X, speed=%X\n", + hw->sleep_ctrl, speed); + device_set_wakeup_enable(&pdev->dev, true); + *wol_en = true; + } + + pci_disable_device(pdev); + + return 0; +} + +static void alx_shutdown(struct pci_dev *pdev) +{ + int err; + bool wol_en; + + err = __alx_shutdown(pdev, &wol_en); + if (!err) { + pci_wake_from_d3(pdev, wol_en); + pci_set_power_state(pdev, PCI_D3hot); + } else { + dev_err(&pdev->dev, "shutdown fail %d\n", err); + } +} + static void alx_link_check(struct work_struct *work) { struct alx_priv *alx; @@ -1836,6 +1906,8 @@ goto out_unmap; } + device_set_wakeup_enable(&pdev->dev, hw->sleep_ctrl); + netdev_info(netdev, "Qualcomm Atheros AR816x/AR817x Ethernet [%pM]\n", netdev->dev_addr); @@ -1848,6 +1920,7 @@ free_netdev(netdev); out_pci_release: pci_release_mem_regions(pdev); + pci_disable_pcie_error_reporting(pdev); out_pci_disable: pci_disable_device(pdev); return err; @@ -1858,9 +1931,6 @@ struct alx_priv *alx = pci_get_drvdata(pdev); struct alx_hw *hw = &alx->hw; - cancel_work_sync(&alx->link_check_wk); - cancel_work_sync(&alx->reset_wk); - /* restore permanent mac address */ alx_set_macaddr(hw, hw->perm_addr); @@ -1877,41 +1947,95 @@ #ifdef CONFIG_PM_SLEEP static int alx_suspend(struct device *dev) { - struct alx_priv *alx = dev_get_drvdata(dev); + struct pci_dev *pdev = to_pci_dev(dev); + int err; + bool wol_en; + + err = __alx_shutdown(pdev, &wol_en); + if (err) { + dev_err(&pdev->dev, "shutdown fail in suspend %d\n", err); + return err; + } + + if (wol_en) { + pci_prepare_to_sleep(pdev); + } else { + pci_wake_from_d3(pdev, false); + pci_set_power_state(pdev, PCI_D3hot); + } - if (!netif_running(alx->dev)) - return 0; - netif_device_detach(alx->dev); - __alx_stop(alx); return 0; } static int alx_resume(struct device *dev) { - struct alx_priv *alx = dev_get_drvdata(dev); + struct pci_dev *pdev = to_pci_dev(dev); + struct alx_priv *alx = pci_get_drvdata(pdev); + struct net_device *netdev = alx->dev; struct alx_hw *hw = &alx->hw; int err; + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_save_state(pdev); + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + hw->link_speed = SPEED_UNKNOWN; + alx->int_mask = ALX_ISR_MISC; + + alx_reset_pcie(hw); alx_reset_phy(hw); - if (!netif_running(alx->dev)) - return 0; - netif_device_attach(alx->dev); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + pci_save_state(pdev); - rtnl_lock(); - err = __alx_open(alx, true); - rtnl_unlock(); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + hw->link_speed = SPEED_UNKNOWN; + alx->int_mask = ALX_ISR_MISC; + + alx_reset_pcie(hw); + alx_reset_phy(hw); + + err = alx_reset_mac(hw); + if (err) { + netif_err(alx, hw, alx->dev, + "resume:reset_mac fail %d\n", err); + return -EIO; + } + + err = alx_setup_speed_duplex(hw, hw->adv_cfg, hw->flowctrl); + if (err) { + netif_err(alx, hw, alx->dev, + "resume:setup_speed_duplex fail %d\n", err); + return -EIO; + } + + if (netif_running(netdev)) { + rtnl_lock(); + err = __alx_open(alx, true); + rtnl_unlock(); + if (err) + return err; + } + + netif_device_attach(netdev); return err; } +#endif +#ifdef CONFIG_PM_SLEEP static SIMPLE_DEV_PM_OPS(alx_pm_ops, alx_suspend, alx_resume); #define ALX_PM_OPS (&alx_pm_ops) #else #define ALX_PM_OPS NULL #endif - static pci_ers_result_t alx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { @@ -1954,6 +2078,8 @@ } pci_set_master(pdev); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); alx_reset_pcie(hw); if (!alx_reset_mac(hw)) @@ -2008,6 +2134,7 @@ .id_table = alx_pci_tbl, .probe = alx_probe, .remove = alx_remove, + .shutdown = alx_shutdown, .err_handler = &alx_err_handlers, .driver.pm = ALX_PM_OPS, }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -1989,8 +1989,11 @@ real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); if (unlikely(skb->len == hdr_len)) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -868,10 +868,13 @@ netdev_err(adapter->netdev, "offset(%d) > ring size(%d) !!\n", offset, adapter->ring_size); err = -1; - goto failed; + goto free_buffer; } return 0; +free_buffer: + kfree(tx_ring->tx_buffer); + tx_ring->tx_buffer = NULL; failed: if (adapter->ring_vir_addr != NULL) { pci_free_consistent(pdev, adapter->ring_size, @@ -1638,8 +1641,11 @@ real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb)); if (unlikely(skb->len == hdr_len)) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/Makefile +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/Makefile @@ -16,3 +16,8 @@ obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o obj-$(CONFIG_BNXT) += bnxt/ + +# FIXME: temporarily silence -Warray-bounds on non W=1+ builds +ifndef KBUILD_EXTRA_WARN +CFLAGS_tg3.o += -Wno-array-bounds +endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/b44.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/b44.c @@ -1519,8 +1519,10 @@ int ethaddr_bytes = ETH_ALEN; memset(ppattern + offset, 0xff, magicsync); - for (j = 0; j < magicsync; j++) - set_bit(len++, (unsigned long *) pmask); + for (j = 0; j < magicsync; j++) { + pmask[len >> 3] |= BIT(len & 7); + len++; + } for (j = 0; j < B44_MAX_PATTERNS; j++) { if ((B44_PATTERN_SIZE - len) >= ETH_ALEN) @@ -1532,7 +1534,8 @@ for (k = 0; k< ethaddr_bytes; k++) { ppattern[offset + magicsync + (j * ETH_ALEN) + k] = macaddr[k]; - set_bit(len++, (unsigned long *) pmask); + pmask[len >> 3] |= BIT(len & 7); + len++; } } return len - 1; @@ -2030,12 +2033,14 @@ bp->flags |= B44_FLAG_TX_PAUSE; else bp->flags &= ~B44_FLAG_TX_PAUSE; - if (bp->flags & B44_FLAG_PAUSE_AUTO) { - b44_halt(bp); - b44_init_rings(bp); - b44_init_hw(bp, B44_FULL_RESET); - } else { - __b44_set_flow_ctrl(bp, bp->flags); + if (netif_running(dev)) { + if (bp->flags & B44_FLAG_PAUSE_AUTO) { + b44_halt(bp); + b44_init_rings(bp); + b44_init_hw(bp, B44_FULL_RESET); + } else { + __b44_set_flow_ctrl(bp, bp->flags); + } } spin_unlock_irq(&bp->lock); @@ -2388,7 +2393,8 @@ goto err_out_free_dev; } - if (dma_set_mask_and_coherent(sdev->dma_dev, DMA_BIT_MASK(30))) { + err = dma_set_mask_and_coherent(sdev->dma_dev, DMA_BIT_MASK(30)); + if (err) { dev_err(sdev->dev, "Required 30BIT DMA mask unsupported by the system\n"); goto err_out_powerdown; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bcmsysport.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bcmsysport.c @@ -666,7 +666,8 @@ dma_addr_t mapping; /* Allocate a new SKB for a new packet */ - skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH); + skb = __netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH, + GFP_ATOMIC | __GFP_NOWARN); if (!skb) { priv->mib.alloc_rx_buff_failed++; netif_err(priv, rx_err, ndev, "SKB alloc failed\n"); @@ -1276,11 +1277,11 @@ struct bcm_sysport_priv *priv = netdev_priv(dev); struct device *kdev = &priv->pdev->dev; struct bcm_sysport_tx_ring *ring; + unsigned long flags, desc_flags; struct bcm_sysport_cb *cb; struct netdev_queue *txq; u32 len_status, addr_lo; unsigned int skb_len; - unsigned long flags; dma_addr_t mapping; u16 queue; int ret; @@ -1315,6 +1316,7 @@ netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", skb->data, skb_len); ret = NETDEV_TX_OK; + dev_kfree_skb_any(skb); goto out; } @@ -1338,8 +1340,10 @@ ring->desc_count--; /* Ports are latched, so write upper address first */ + spin_lock_irqsave(&priv->desc_lock, desc_flags); tdma_writel(priv, len_status, TDMA_WRITE_PORT_HI(ring->index)); tdma_writel(priv, addr_lo, TDMA_WRITE_PORT_LO(ring->index)); + spin_unlock_irqrestore(&priv->desc_lock, desc_flags); /* Check ring space and update SW control flow */ if (ring->desc_count == 0) @@ -1969,6 +1973,7 @@ } /* Initialize both hardware and software ring */ + spin_lock_init(&priv->desc_lock); for (i = 0; i < dev->num_tx_queues; i++) { ret = bcm_sysport_init_tx_ring(priv, i); if (ret) { @@ -2135,7 +2140,7 @@ return -ENOSPC; index = find_first_zero_bit(priv->filters, RXCHK_BRCM_TAG_MAX); - if (index > RXCHK_BRCM_TAG_MAX) + if (index >= RXCHK_BRCM_TAG_MAX) return -ENOSPC; /* Location is the classification ID, and index is the position @@ -2323,7 +2328,7 @@ ring->switch_queue = qp; ring->switch_port = port; ring->inspect = true; - priv->ring_map[q + port * num_tx_queues] = ring; + priv->ring_map[qp + port * num_tx_queues] = ring; qp++; } @@ -2338,7 +2343,7 @@ struct net_device *slave_dev; unsigned int num_tx_queues; struct net_device *dev; - unsigned int q, port; + unsigned int q, qp, port; priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier); if (priv->netdev != info->master) @@ -2364,7 +2369,8 @@ continue; ring->inspect = false; - priv->ring_map[q + port * num_tx_queues] = NULL; + qp = ring->switch_queue; + priv->ring_map[qp + port * num_tx_queues] = NULL; } return 0; @@ -2451,8 +2457,10 @@ priv->tx_rings = devm_kcalloc(&pdev->dev, txq, sizeof(struct bcm_sysport_tx_ring), GFP_KERNEL); - if (!priv->tx_rings) - return -ENOMEM; + if (!priv->tx_rings) { + ret = -ENOMEM; + goto err_free_netdev; + } priv->is_lite = params->is_lite; priv->num_rx_desc_words = params->num_rx_desc_words; @@ -2516,6 +2524,7 @@ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; dev->hw_features |= dev->features; dev->vlan_features |= dev->features; + dev->max_mtu = UMAC_MAX_MTU_SIZE; /* Request the WOL interrupt and advertise suspend if available */ priv->wol_irq_disabled = 1; @@ -2727,6 +2736,9 @@ umac_reset(priv); + /* Disable the UniMAC RX/TX */ + umac_enable_set(priv, CMD_RX_EN | CMD_TX_EN, 0); + /* We may have been suspended and never received a WOL event that * would turn off MPD detection, take care of that now */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bcmsysport.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bcmsysport.h @@ -742,6 +742,7 @@ int wol_irq; /* Transmit rings */ + spinlock_t desc_lock; struct bcm_sysport_tx_ring *tx_rings; /* Receive queue */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bgmac-bcma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bgmac-bcma.c @@ -228,12 +228,12 @@ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_FLW_CTRL1; bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_PHY; - if (ci->pkg == BCMA_PKG_ID_BCM47188 || - ci->pkg == BCMA_PKG_ID_BCM47186) { + if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) || + (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188)) { bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_RGMII; bgmac->feature_flags |= BGMAC_FEAT_IOST_ATTACHED; } - if (ci->pkg == BCMA_PKG_ID_BCM5358) + if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM5358) bgmac->feature_flags |= BGMAC_FEAT_SW_TYPE_EPHYRMII; break; case BCMA_CHIP_ID_BCM53573: @@ -323,7 +323,6 @@ bcma_mdio_mii_unregister(bgmac->mii_bus); bgmac_enet_remove(bgmac); bcma_set_drvdata(core, NULL); - kfree(bgmac); } static struct bcma_driver bgmac_bcma_driver = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bgmac-platform.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bgmac-platform.c @@ -171,6 +171,7 @@ static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; + struct device_node *phy_node; struct bgmac *bgmac; struct resource *regs; const u8 *mac_addr; @@ -237,7 +238,9 @@ bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = platform_bgmac_get_bus_clock; bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32; - if (of_parse_phandle(np, "phy-handle", 0)) { + phy_node = of_parse_phandle(np, "phy-handle", 0); + if (phy_node) { + of_node_put(phy_node); bgmac->phy_connect = platform_phy_connect; } else { bgmac->phy_connect = bgmac_phy_connect_direct; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bgmac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bgmac.c @@ -189,8 +189,8 @@ } slot->skb = skb; - ring->end += nr_frags + 1; netdev_sent_queue(net_dev, skb->len); + ring->end += nr_frags + 1; wmb(); @@ -890,13 +890,13 @@ if (iost & BGMAC_BCMA_IOST_ATTACHED) { flags = BGMAC_BCMA_IOCTL_SW_CLKEN; - if (!bgmac->has_robosw) + if (bgmac->in_init || !bgmac->has_robosw) flags |= BGMAC_BCMA_IOCTL_SW_RESET; } bgmac_clk_enable(bgmac, flags); } - if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw) + if (iost & BGMAC_BCMA_IOST_ATTACHED && (bgmac->in_init || !bgmac->has_robosw)) bgmac_idm_write(bgmac, BCMA_IOCTL, bgmac_idm_read(bgmac, BCMA_IOCTL) & ~BGMAC_BCMA_IOCTL_SW_RESET); @@ -1447,7 +1447,7 @@ int err; phy_dev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); - if (!phy_dev || IS_ERR(phy_dev)) { + if (IS_ERR(phy_dev)) { dev_err(bgmac->dev, "Failed to register fixed PHY device\n"); return -ENODEV; } @@ -1489,6 +1489,8 @@ struct net_device *net_dev = bgmac->net_dev; int err; + bgmac->in_init = true; + bgmac_chip_intrs_off(bgmac); net_dev->irq = bgmac->irq; @@ -1538,6 +1540,8 @@ net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features; + bgmac->in_init = false; + err = register_netdev(bgmac->net_dev); if (err) { dev_err(bgmac->dev, "Cannot register net device\n"); @@ -1564,7 +1568,6 @@ phy_disconnect(bgmac->net_dev->phydev); netif_napi_del(&bgmac->napi); bgmac_dma_free(bgmac); - free_netdev(bgmac->net_dev); } EXPORT_SYMBOL_GPL(bgmac_enet_remove); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bgmac.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bgmac.h @@ -511,6 +511,8 @@ int irq; u32 int_mask; + bool in_init; + /* Current MAC state */ int mac_speed; int mac_duplex; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2.c @@ -1461,7 +1461,7 @@ static void bnx2_enable_forced_2g5(struct bnx2 *bp) { - u32 uninitialized_var(bmcr); + u32 bmcr; int err; if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) @@ -1505,7 +1505,7 @@ static void bnx2_disable_forced_2g5(struct bnx2 *bp) { - u32 uninitialized_var(bmcr); + u32 bmcr; int err; if (!(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE)) @@ -8249,9 +8249,9 @@ BNX2_WR(bp, PCI_COMMAND, reg); } else if ((BNX2_CHIP_ID(bp) == BNX2_CHIP_ID_5706_A1) && !(bp->flags & BNX2_FLAG_PCIX)) { - dev_err(&pdev->dev, "5706 A1 can only be used in a PCIX bus, aborting\n"); + rc = -EPERM; goto err_out_unmap; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1256,7 +1256,7 @@ struct bnx2x_fw_stats_req { struct stats_query_header hdr; - struct stats_query_entry query[FP_SB_MAX_E1x+ + struct stats_query_entry query[FP_SB_MAX_E2 + BNX2X_FIRST_QUEUE_QUERY_IDX]; }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -787,6 +787,7 @@ BNX2X_ERR("skb_put is about to fail... pad %d len %d rx_buf_size %d\n", pad, len, fp->rx_buf_size); bnx2x_panic(); + bnx2x_frag_free(fp, new_data); return; } #endif @@ -2666,7 +2667,8 @@ } /* Allocated memory for FW statistics */ - if (bnx2x_alloc_fw_stats_mem(bp)) + rc = bnx2x_alloc_fw_stats_mem(bp); + if (rc) LOAD_ERROR_EXIT(bp, load_error0); /* request pf to initialize status blocks */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1004,9 +1004,6 @@ static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp, struct bnx2x_alloc_pool *pool) { - if (!pool->page) - return; - put_page(pool->page); pool->page = NULL; @@ -1017,6 +1014,9 @@ { int i; + if (!fp->page_pool.page) + return; + if (fp->mode == TPA_MODE_DISABLED) return; @@ -1109,7 +1109,7 @@ for (i = 0; i < E1H_FUNC_MAX / 2; i++) { u32 func_config = MF_CFG_RD(bp, - func_mf_config[BP_PORT(bp) + 2 * i]. + func_mf_config[BP_PATH(bp) + 2 * i]. config); func_num += ((func_config & FUNC_MF_CFG_FUNC_HIDE) ? 0 : 1); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h @@ -296,7 +296,6 @@ * possible, the driver should only write the valid vnics into the internal * ram according to the appropriate port mode. */ -#define BITS_TO_BYTES(x) ((x)/8) /* CMNG constants, as derived from system spec calculations */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -635,11 +635,13 @@ { int i, rc; struct bnx2x_ilt *ilt = BP_ILT(bp); - struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + struct ilt_client_info *ilt_cli; if (!ilt || !ilt->lines) return -1; + ilt_cli = &ilt->clients[cli_num]; + if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -9976,10 +9976,18 @@ */ static void bnx2x_parity_recover(struct bnx2x *bp) { - bool global = false; u32 error_recovered, error_unrecovered; - bool is_parity; + bool is_parity, global = false; +#ifdef CONFIG_BNX2X_SRIOV + int vf_idx; + + for (vf_idx = 0; vf_idx < bp->requested_nr_virtfn; vf_idx++) { + struct bnx2x_virtf *vf = BP_VF(bp, vf_idx); + if (vf) + vf->state = VF_LOST; + } +#endif DP(NETIF_MSG_HW, "Handling parity\n"); while (1) { switch (bp->recovery_state) { @@ -14259,10 +14267,6 @@ /* Stop Tx */ bnx2x_tx_disable(bp); - /* Delete all NAPI objects */ - bnx2x_del_all_napi(bp); - if (CNIC_LOADED(bp)) - bnx2x_del_all_napi_cnic(bp); netdev_reset_tc(bp->dev); del_timer_sync(&bp->timer); @@ -14367,6 +14371,11 @@ bnx2x_drain_tx_queues(bp); bnx2x_send_unload_req(bp, UNLOAD_RECOVERY); bnx2x_netif_stop(bp, 1); + bnx2x_del_all_napi(bp); + + if (CNIC_LOADED(bp)) + bnx2x_del_all_napi_cnic(bp); + bnx2x_free_irq(bp); /* Report UNLOAD_DONE to MCP */ @@ -14417,11 +14426,16 @@ bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK; - if (netif_running(dev)) - bnx2x_nic_load(bp, LOAD_NORMAL); + if (netif_running(dev)) { + if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + netdev_err(bp->dev, "Error during driver initialization, try unloading/reloading the driver\n"); + goto done; + } + } netif_device_attach(dev); +done: rtnl_unlock(); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -807,16 +807,20 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) { - struct pci_dev *dev; struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid); + struct pci_dev *dev; + bool pending; if (!vf) return false; dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn); - if (dev) - return bnx2x_is_pcie_pending(dev); - return false; + if (!dev) + return false; + pending = bnx2x_is_pcie_pending(dev); + pci_dev_put(dev); + + return pending; } int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) @@ -1245,8 +1249,10 @@ goto failed; /* SR-IOV capability was enabled but there are no VFs*/ - if (iov->total == 0) + if (iov->total == 0) { + err = 0; goto failed; + } iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); @@ -2397,15 +2403,21 @@ /* send the ramrod on all the queues of the PF */ for_each_eth_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; + int tx_idx; /* Set the appropriate Queue object */ q_params.q_obj = &bnx2x_sp_obj(bp, fp).q_obj; - /* Update the Queue state */ - rc = bnx2x_queue_state_change(bp, &q_params); - if (rc) { - BNX2X_ERR("Failed to configure Tx switching\n"); - return rc; + for (tx_idx = FIRST_TX_COS_INDEX; + tx_idx < fp->max_cos; tx_idx++) { + q_params.params.update.cid_index = tx_idx; + + /* Update the Queue state */ + rc = bnx2x_queue_state_change(bp, &q_params); + if (rc) { + BNX2X_ERR("Failed to configure Tx switching\n"); + return rc; + } } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h @@ -139,6 +139,7 @@ #define VF_ACQUIRED 1 /* VF acquired, but not initialized */ #define VF_ENABLED 2 /* VF Enabled */ #define VF_RESET 3 /* VF FLR'd, pending cleanup */ +#define VF_LOST 4 /* Recovery while VFs are loaded */ bool flr_clnup_stage; /* true during flr cleanup */ bool malicious; /* true if FW indicated so, until FLR */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -2107,6 +2107,18 @@ { int i; + if (vf->state == VF_LOST) { + /* Just ack the FW and return if VFs are lost + * in case of parity error. VFs are supposed to be timedout + * on waiting for PF response. + */ + DP(BNX2X_MSG_IOV, + "VF 0x%x lost, not handling the request\n", vf->abs_vfid); + + storm_memset_vf_mbx_ack(bp, vf->abs_vfid); + return; + } + /* check if tlv type is known */ if (bnx2x_tlv_supported(mbx->first_tlv.tl.type)) { /* Lock the per vf op mutex and note the locker's identity. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -125,7 +125,10 @@ NETXTREME_E_VF, NETXTREME_C_VF, NETXTREME_S_VF, + NETXTREME_C_VF_HV, + NETXTREME_E_VF_HV, NETXTREME_E_P5_VF, + NETXTREME_E_P5_VF_HV, }; /* indexed by enum above */ @@ -173,7 +176,10 @@ [NETXTREME_E_VF] = { "Broadcom NetXtreme-E Ethernet Virtual Function" }, [NETXTREME_C_VF] = { "Broadcom NetXtreme-C Ethernet Virtual Function" }, [NETXTREME_S_VF] = { "Broadcom NetXtreme-S Ethernet Virtual Function" }, + [NETXTREME_C_VF_HV] = { "Broadcom NetXtreme-C Virtual Function for Hyper-V" }, + [NETXTREME_E_VF_HV] = { "Broadcom NetXtreme-E Virtual Function for Hyper-V" }, [NETXTREME_E_P5_VF] = { "Broadcom BCM5750X NetXtreme-E Ethernet Virtual Function" }, + [NETXTREME_E_P5_VF_HV] = { "Broadcom BCM5750X NetXtreme-E Virtual Function for Hyper-V" }, }; static const struct pci_device_id bnxt_pci_tbl[] = { @@ -215,25 +221,35 @@ { PCI_VDEVICE(BROADCOM, 0x1750), .driver_data = BCM57508 }, { PCI_VDEVICE(BROADCOM, 0x1751), .driver_data = BCM57504 }, { PCI_VDEVICE(BROADCOM, 0x1752), .driver_data = BCM57502 }, - { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1800), .driver_data = BCM57502_NPAR }, { PCI_VDEVICE(BROADCOM, 0x1801), .driver_data = BCM57504_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57502_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1802), .driver_data = BCM57508_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1803), .driver_data = BCM57502_NPAR }, { PCI_VDEVICE(BROADCOM, 0x1804), .driver_data = BCM57504_NPAR }, - { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57502_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x1805), .driver_data = BCM57508_NPAR }, { PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 }, { PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 }, #ifdef CONFIG_BNXT_SRIOV { PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF }, + { PCI_VDEVICE(BROADCOM, 0x1607), .driver_data = NETXTREME_E_VF_HV }, + { PCI_VDEVICE(BROADCOM, 0x1608), .driver_data = NETXTREME_E_VF_HV }, { PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF }, + { PCI_VDEVICE(BROADCOM, 0x16bd), .driver_data = NETXTREME_E_VF_HV }, { PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF }, + { PCI_VDEVICE(BROADCOM, 0x16c2), .driver_data = NETXTREME_C_VF_HV }, + { PCI_VDEVICE(BROADCOM, 0x16c3), .driver_data = NETXTREME_C_VF_HV }, + { PCI_VDEVICE(BROADCOM, 0x16c4), .driver_data = NETXTREME_E_VF_HV }, + { PCI_VDEVICE(BROADCOM, 0x16c5), .driver_data = NETXTREME_E_VF_HV }, { PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF }, { PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF }, { PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = NETXTREME_E_VF }, { PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = NETXTREME_C_VF }, { PCI_VDEVICE(BROADCOM, 0x16e5), .driver_data = NETXTREME_C_VF }, + { PCI_VDEVICE(BROADCOM, 0x16e6), .driver_data = NETXTREME_C_VF_HV }, { PCI_VDEVICE(BROADCOM, 0x1806), .driver_data = NETXTREME_E_P5_VF }, { PCI_VDEVICE(BROADCOM, 0x1807), .driver_data = NETXTREME_E_P5_VF }, + { PCI_VDEVICE(BROADCOM, 0x1808), .driver_data = NETXTREME_E_P5_VF_HV }, + { PCI_VDEVICE(BROADCOM, 0x1809), .driver_data = NETXTREME_E_P5_VF_HV }, { PCI_VDEVICE(BROADCOM, 0xd800), .driver_data = NETXTREME_S_VF }, #endif { 0 } @@ -263,7 +279,9 @@ static bool bnxt_vf_pciid(enum board_idx idx) { return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF || - idx == NETXTREME_S_VF || idx == NETXTREME_E_P5_VF); + idx == NETXTREME_S_VF || idx == NETXTREME_C_VF_HV || + idx == NETXTREME_E_VF_HV || idx == NETXTREME_E_P5_VF || + idx == NETXTREME_E_P5_VF_HV); } #define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID) @@ -342,6 +360,26 @@ return md_dst->u.port_info.port_id; } +static bool bnxt_txr_netif_try_stop_queue(struct bnxt *bp, + struct bnxt_tx_ring_info *txr, + struct netdev_queue *txq) +{ + netif_tx_stop_queue(txq); + + /* netif_tx_stop_queue() must be done before checking + * tx index in bnxt_tx_avail() below, because in + * bnxt_tx_int(), we update tx index before checking for + * netif_tx_queue_stopped(). + */ + smp_mb(); + if (bnxt_tx_avail(bp, txr) >= bp->tx_wake_thresh) { + netif_tx_wake_queue(txq); + return false; + } + + return true; +} + static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bnxt *bp = netdev_priv(dev); @@ -369,8 +407,8 @@ free_size = bnxt_tx_avail(bp, txr); if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) { - netif_tx_stop_queue(txq); - return NETDEV_TX_BUSY; + if (bnxt_txr_netif_try_stop_queue(bp, txr, txq)) + return NETDEV_TX_BUSY; } length = skb->len; @@ -579,16 +617,7 @@ if (netdev_xmit_more() && !tx_buf->is_push) bnxt_db_write(bp, &txr->tx_db, prod); - netif_tx_stop_queue(txq); - - /* netif_tx_stop_queue() must be done before checking - * tx index in bnxt_tx_avail() below, because in - * bnxt_tx_int(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); - if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) - netif_tx_wake_queue(txq); + bnxt_txr_netif_try_stop_queue(bp, txr, txq); } return NETDEV_TX_OK; @@ -672,14 +701,9 @@ smp_mb(); if (unlikely(netif_tx_queue_stopped(txq)) && - (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh)) { - __netif_tx_lock(txq, smp_processor_id()); - if (netif_tx_queue_stopped(txq) && - bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && - txr->dev_state != BNXT_DEV_STATE_CLOSING) - netif_tx_wake_queue(txq); - __netif_tx_unlock(txq); - } + bnxt_tx_avail(bp, txr) >= bp->tx_wake_thresh && + READ_ONCE(txr->dev_state) != BNXT_DEV_STATE_CLOSING) + netif_tx_wake_queue(txq); } static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, @@ -942,6 +966,7 @@ dma_addr -= bp->rx_dma_offset; dma_unmap_page_attrs(&bp->pdev->dev, dma_addr, PAGE_SIZE, bp->rx_dir, DMA_ATTR_WEAK_ORDERING); + page_pool_release_page(rxr->page_pool, page); if (unlikely(!payload)) payload = eth_get_headlen(bp->dev, data_ptr, len); @@ -1142,6 +1167,9 @@ static void bnxt_queue_fw_reset_work(struct bnxt *bp, unsigned long delay) { + if (!(test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))) + return; + if (BNXT_PF(bp)) queue_delayed_work(bnxt_pf_wq, &bp->fw_reset_task, delay); else @@ -1156,14 +1184,6 @@ schedule_work(&bp->sp_task); } -static void bnxt_cancel_sp_work(struct bnxt *bp) -{ - if (BNXT_PF(bp)) - flush_workqueue(bnxt_pf_wq); - else - cancel_work_sync(&bp->sp_task); -} - static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) { if (!rxr->bnapi->in_reset) { @@ -1704,6 +1724,10 @@ if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons)) return -EBUSY; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); prod = rxr->rx_prod; if (cmp_type == CMP_TYPE_RX_L2_TPA_START_CMP) { @@ -1732,12 +1756,14 @@ cons = rxcmp->rx_cmp_opaque; if (unlikely(cons != rxr->rx_next_cons)) { - int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp); + int rc1 = bnxt_discard_rx(bp, cpr, &tmp_raw_cons, rxcmp); netdev_warn(bp->dev, "RX cons %x != expected cons %x\n", cons, rxr->rx_next_cons); bnxt_sched_reset(bp, rxr); - return rc1; + if (rc1) + return rc1; + goto next_rx_no_prod_no_len; } rx_buf = &rxr->rx_buf_ring[cons]; data = rx_buf->data; @@ -1767,8 +1793,12 @@ rc = -EIO; if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) { - netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); - bnxt_sched_reset(bp, rxr); + bnapi->cp_ring.rx_buf_errors++; + if (!(bp->flags & BNXT_FLAG_CHIP_P5)) { + netdev_warn(bp->dev, "RX buffer error %x\n", + rx_err); + bnxt_sched_reset(bp, rxr); + } } goto next_rx_no_len; } @@ -1892,6 +1922,10 @@ if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons)) return -EBUSY; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); cmp_type = RX_CMP_TYPE(rxcmp); if (cmp_type == CMP_TYPE_RX_L2_CMP) { rxcmp1->rx_cmp_cfa_code_errors_v2 |= @@ -1991,6 +2025,9 @@ case ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: { u32 data1 = le32_to_cpu(cmpl->event_data1); + if (!bp->fw_health) + goto async_event_process_exit; + bp->fw_reset_timestamp = jiffies; bp->fw_reset_min_dsecs = cmpl->timestamp_lo; if (!bp->fw_reset_min_dsecs) @@ -2169,7 +2206,7 @@ if (TX_CMP_TYPE(txcmp) == CMP_TYPE_TX_L2_CMP) { tx_pkts++; /* return full budget so NAPI will complete. */ - if (unlikely(tx_pkts > bp->tx_wake_thresh)) { + if (unlikely(tx_pkts >= bp->tx_wake_thresh)) { rx_pkts = budget; raw_cons = NEXT_RAW_CMP(raw_cons); if (budget) @@ -2285,6 +2322,10 @@ if (!TX_CMP_VALID(txcmp, raw_cons)) break; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); if ((TX_CMP_TYPE(txcmp) & 0x30) == 0x10) { tmp_raw_cons = NEXT_RAW_CMP(raw_cons); cp_cons = RING_CMP(tmp_raw_cons); @@ -2706,7 +2747,7 @@ static void bnxt_free_tpa_info(struct bnxt *bp) { - int i; + int i, j; for (i = 0; i < bp->rx_nr_rings; i++) { struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; @@ -2714,8 +2755,10 @@ kfree(rxr->rx_tpa_idx_map); rxr->rx_tpa_idx_map = NULL; if (rxr->rx_tpa) { - kfree(rxr->rx_tpa[0].agg_arr); - rxr->rx_tpa[0].agg_arr = NULL; + for (j = 0; j < bp->max_tpa; j++) { + kfree(rxr->rx_tpa[j].agg_arr); + rxr->rx_tpa[j].agg_arr = NULL; + } } kfree(rxr->rx_tpa); rxr->rx_tpa = NULL; @@ -2724,14 +2767,13 @@ static int bnxt_alloc_tpa_info(struct bnxt *bp) { - int i, j, total_aggs = 0; + int i, j; bp->max_tpa = MAX_TPA; if (bp->flags & BNXT_FLAG_CHIP_P5) { if (!bp->max_tpa_v2) return 0; bp->max_tpa = max_t(u16, bp->max_tpa_v2, MAX_TPA_P5); - total_aggs = bp->max_tpa * MAX_SKB_FRAGS; } for (i = 0; i < bp->rx_nr_rings; i++) { @@ -2745,12 +2787,12 @@ if (!(bp->flags & BNXT_FLAG_CHIP_P5)) continue; - agg = kcalloc(total_aggs, sizeof(*agg), GFP_KERNEL); - rxr->rx_tpa[0].agg_arr = agg; - if (!agg) - return -ENOMEM; - for (j = 1; j < bp->max_tpa; j++) - rxr->rx_tpa[j].agg_arr = agg + j * MAX_SKB_FRAGS; + for (j = 0; j < bp->max_tpa; j++) { + agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); + if (!agg) + return -ENOMEM; + rxr->rx_tpa[j].agg_arr = agg; + } rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), GFP_KERNEL); if (!rxr->rx_tpa_idx_map) @@ -3288,7 +3330,7 @@ u16 i; bp->tx_wake_thresh = max_t(int, bp->tx_ring_size / 2, - MAX_SKB_FRAGS + 1); + BNXT_MIN_TX_DESC_CNT); for (i = 0; i < bp->tx_nr_rings; i++) { struct bnxt_tx_ring_info *txr = &bp->tx_ring[i]; @@ -3415,7 +3457,7 @@ */ void bnxt_set_ring_params(struct bnxt *bp) { - u32 ring_size, rx_size, rx_space; + u32 ring_size, rx_size, rx_space, max_rx_cmpl; u32 agg_factor = 0, agg_ring_size = 0; /* 8 for CRC and VLAN */ @@ -3471,7 +3513,15 @@ bp->tx_nr_pages = bnxt_calc_nr_ring_pages(ring_size, TX_DESC_CNT); bp->tx_ring_mask = (bp->tx_nr_pages * TX_DESC_CNT) - 1; - ring_size = bp->rx_ring_size * (2 + agg_factor) + bp->tx_ring_size; + max_rx_cmpl = bp->rx_ring_size; + /* MAX TPA needs to be added because TPA_START completions are + * immediately recycled, so the TPA completions are not bound by + * the RX ring size. + */ + if (bp->flags & BNXT_FLAG_TPA) + max_rx_cmpl += bp->max_tpa; + /* RX and TPA completions are 32-byte, all others are 16-byte */ + ring_size = max_rx_cmpl * 2 + agg_ring_size + bp->tx_ring_size; bp->cp_ring_size = ring_size; bp->cp_nr_pages = bnxt_calc_nr_ring_pages(ring_size, CP_DESC_CNT); @@ -4183,7 +4233,8 @@ u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM; u16 dst = BNXT_HWRM_CHNL_CHIMP; - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) + if (BNXT_NO_FW_ACCESS(bp) && + le16_to_cpu(req->req_type) != HWRM_FUNC_RESET) return -EBUSY; if (msg_len > BNXT_HWRM_MAX_REQ_LEN) { @@ -4434,8 +4485,9 @@ FUNC_DRV_RGTR_REQ_ENABLES_VER); req.os_type = cpu_to_le16(FUNC_DRV_RGTR_REQ_OS_TYPE_LINUX); - flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE | - FUNC_DRV_RGTR_REQ_FLAGS_HOT_RESET_SUPPORT; + flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE; + if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET) + flags |= FUNC_DRV_RGTR_REQ_FLAGS_HOT_RESET_SUPPORT; if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) flags |= FUNC_DRV_RGTR_REQ_FLAGS_ERROR_RECOVERY_SUPPORT; req.flags = cpu_to_le32(flags); @@ -5517,7 +5569,7 @@ struct hwrm_ring_free_output *resp = bp->hwrm_cmd_resp_addr; u16 error_code; - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) + if (BNXT_NO_FW_ACCESS(bp)) return 0; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_RING_FREE, cmpl_ring_id, -1); @@ -6170,7 +6222,7 @@ tmr = bnxt_usec_to_coal_tmr(bp, hw_coal->coal_ticks_irq); val = clamp_t(u16, tmr, 1, coal_cap->cmpl_aggr_dma_tmr_during_int_max); - req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(tmr); + req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(val); req->enables |= cpu_to_le16(BNXT_COAL_CMPL_AGGR_TMR_DURING_INT_ENABLE); } @@ -6297,6 +6349,7 @@ static int bnxt_hwrm_stat_ctx_free(struct bnxt *bp) { int rc = 0, i; + struct hwrm_stat_ctx_clr_stats_input req0 = {0}; struct hwrm_stat_ctx_free_input req = {0}; if (!bp->bnapi) @@ -6305,6 +6358,7 @@ if (BNXT_CHIP_TYPE_NITRO_A0(bp)) return 0; + bnxt_hwrm_cmd_hdr_init(bp, &req0, HWRM_STAT_CTX_CLR_STATS, -1, -1); bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_STAT_CTX_FREE, -1, -1); mutex_lock(&bp->hwrm_cmd_lock); @@ -6314,6 +6368,11 @@ if (cpr->hw_stats_ctx_id != INVALID_STATS_CTX_ID) { req.stat_ctx_id = cpu_to_le32(cpr->hw_stats_ctx_id); + if (BNXT_FW_MAJ(bp) <= 20) { + req0.stat_ctx_id = req.stat_ctx_id; + _hwrm_send_message(bp, &req0, sizeof(req0), + HWRM_CMD_TIMEOUT); + } rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@ -6640,7 +6699,7 @@ int rc; if (!mem_size) - return 0; + return -EINVAL; ctx_pg->nr_pages = DIV_ROUND_UP(mem_size, BNXT_PAGE_SIZE); if (ctx_pg->nr_pages > MAX_CTX_TOTAL_PAGES) { @@ -6854,12 +6913,12 @@ } ena |= FUNC_BACKING_STORE_CFG_REQ_DFLT_ENABLES; rc = bnxt_hwrm_func_backing_store_cfg(bp, ena); - if (rc) + if (rc) { netdev_err(bp->dev, "Failed configuring context mem, rc = %d.\n", rc); - else - ctx->flags |= BNXT_CTX_FLAG_INITED; - + return rc; + } + ctx->flags |= BNXT_CTX_FLAG_INITED; return 0; } @@ -6951,7 +7010,8 @@ bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD; bp->tx_push_thresh = 0; - if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) + if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) && + BNXT_FW_MAJ(bp) > 217) bp->tx_push_thresh = BNXT_TX_PUSH_THRESH; hw_resc->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx); @@ -6970,7 +7030,6 @@ pf->fw_fid = le16_to_cpu(resp->fid); pf->port_id = le16_to_cpu(resp->port_id); - bp->dev->dev_port = pf->port_id; memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN); pf->first_vf_id = le16_to_cpu(resp->first_vf_id); pf->max_vfs = le16_to_cpu(resp->max_vfs); @@ -7092,14 +7151,6 @@ rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (rc) goto err_recovery_out; - if (!fw_health) { - fw_health = kzalloc(sizeof(*fw_health), GFP_KERNEL); - bp->fw_health = fw_health; - if (!fw_health) { - rc = -ENOMEM; - goto err_recovery_out; - } - } fw_health->flags = le32_to_cpu(resp->flags); if ((fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU) && !(bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL)) { @@ -7224,8 +7275,9 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) { struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr; + u16 fw_maj, fw_min, fw_bld, fw_rsv; u32 dev_caps_cfg; - int rc; + int rc, len; bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN; mutex_lock(&bp->hwrm_cmd_lock); @@ -7244,9 +7296,23 @@ resp->hwrm_intf_upd_8b); netdev_warn(bp->dev, "Please update firmware with HWRM interface 1.0.0 or newer.\n"); } - snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d", - resp->hwrm_fw_maj_8b, resp->hwrm_fw_min_8b, - resp->hwrm_fw_bld_8b, resp->hwrm_fw_rsvd_8b); + + fw_maj = le16_to_cpu(resp->hwrm_fw_major); + if (bp->hwrm_spec_code > 0x10803 && fw_maj) { + fw_min = le16_to_cpu(resp->hwrm_fw_minor); + fw_bld = le16_to_cpu(resp->hwrm_fw_build); + fw_rsv = le16_to_cpu(resp->hwrm_fw_patch); + len = FW_VER_STR_LEN; + } else { + fw_maj = resp->hwrm_fw_maj_8b; + fw_min = resp->hwrm_fw_min_8b; + fw_bld = resp->hwrm_fw_bld_8b; + fw_rsv = resp->hwrm_fw_rsvd_8b; + len = BC_HWRM_STR_LEN; + } + bp->fw_ver_code = BNXT_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv); + snprintf(bp->fw_ver_str, len, "%d.%d.%d.%d", fw_maj, fw_min, fw_bld, + fw_rsv); if (strlen(resp->active_pkg_name)) { int fw_ver_len = strlen(bp->fw_ver_str); @@ -7386,14 +7452,22 @@ pri2cos = &resp2->pri0_cos_queue_id; for (i = 0; i < 8; i++) { u8 queue_id = pri2cos[i]; + u8 queue_idx; + /* Per port queue IDs start from 0, 10, 20, etc */ + queue_idx = queue_id % 10; + if (queue_idx > BNXT_MAX_QUEUE) { + bp->pri2cos_valid = false; + goto qstats_done; + } for (j = 0; j < bp->max_q; j++) { if (bp->q_ids[j] == queue_id) - bp->pri2cos[i] = j; + bp->pri2cos_idx[i] = queue_idx; } } bp->pri2cos_valid = 1; } +qstats_done: mutex_unlock(&bp->hwrm_cmd_lock); return rc; } @@ -7432,7 +7506,7 @@ if (set_tpa) tpa_flags = bp->flags & BNXT_FLAG_TPA; - else if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) + else if (BNXT_NO_FW_ACCESS(bp)) return 0; for (i = 0; i < bp->nr_vnics; i++) { rc = bnxt_hwrm_vnic_set_tpa(bp, i, tpa_flags); @@ -7730,6 +7804,9 @@ goto err_out; } + if (BNXT_VF(bp)) + bnxt_hwrm_func_qcfg(bp); + rc = bnxt_setup_vnic(bp, 0); if (rc) goto err_out; @@ -7873,7 +7950,7 @@ int tcs, i; tcs = netdev_get_num_tc(dev); - if (tcs > 1) { + if (tcs) { int i, off, count; for (i = 0; i < tcs; i++) { @@ -7912,10 +7989,18 @@ bp->irq_tbl[0].handler = bnxt_inta; } +static int bnxt_init_int_mode(struct bnxt *bp); + static int bnxt_setup_int_mode(struct bnxt *bp) { int rc; + if (!bp->irq_tbl) { + rc = bnxt_init_int_mode(bp); + if (rc || !bp->irq_tbl) + return rc ?: -ENODEV; + } + if (bp->flags & BNXT_FLAG_USING_MSIX) bnxt_setup_msix(bp); else @@ -8100,7 +8185,7 @@ static int bnxt_init_int_mode(struct bnxt *bp) { - int rc = 0; + int rc = -ENODEV; if (bp->flags & BNXT_FLAG_MSIX_CAP) rc = bnxt_init_msix(bp); @@ -8147,10 +8232,14 @@ netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc); return rc; } - if (tcs && (bp->tx_nr_rings_per_tc * tcs != bp->tx_nr_rings)) { + if (tcs && (bp->tx_nr_rings_per_tc * tcs != + bp->tx_nr_rings - bp->tx_nr_rings_xdp)) { netdev_err(bp->dev, "tx ring reservation failure\n"); netdev_reset_tc(bp->dev); - bp->tx_nr_rings_per_tc = bp->tx_nr_rings; + if (bp->tx_nr_rings_xdp) + bp->tx_nr_rings_per_tc = bp->tx_nr_rings_xdp; + else + bp->tx_nr_rings_per_tc = bp->tx_nr_rings; return -ENOMEM; } return 0; @@ -8300,10 +8389,9 @@ for (i = 0; i < bp->cp_nr_rings; i++) { struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; + napi_disable(&bp->bnapi[i]->napi); if (bp->bnapi[i]->rx_ring) cancel_work_sync(&cpr->dim.work); - - napi_disable(&bp->bnapi[i]->napi); } } @@ -8331,12 +8419,15 @@ if (bp->tx_ring) { for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = BNXT_DEV_STATE_CLOSING; + WRITE_ONCE(txr->dev_state, BNXT_DEV_STATE_CLOSING); } } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); + /* Drop carrier first to prevent TX timeout */ + netif_carrier_off(bp->dev); /* Stop all TX queues */ netif_tx_disable(bp->dev); - netif_carrier_off(bp->dev); } void bnxt_tx_enable(struct bnxt *bp) @@ -8346,8 +8437,10 @@ for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = 0; + WRITE_ONCE(txr->dev_state, 0); } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); netif_tx_wake_all_queues(bp->dev); if (bp->link_info.link_up) netif_carrier_on(bp->dev); @@ -8362,6 +8455,11 @@ u16 fec; netif_carrier_on(bp->dev); + speed = bnxt_fw_to_ethtool_speed(bp->link_info.link_speed); + if (speed == SPEED_UNKNOWN) { + netdev_info(bp->dev, "NIC Link is Up, speed unknown\n"); + return; + } if (bp->link_info.duplex == BNXT_LINK_DUPLEX_FULL) duplex = "full"; else @@ -8374,7 +8472,6 @@ flow_ctrl = "ON - receive"; else flow_ctrl = "none"; - speed = bnxt_fw_to_ethtool_speed(bp->link_info.link_speed); netdev_info(bp->dev, "NIC Link is Up, %u Mbps %s duplex, Flow control: %s\n", speed, duplex, flow_ctrl); if (bp->flags & BNXT_FLAG_EEE_CAP) @@ -8730,7 +8827,8 @@ { struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_func_drv_if_change_input req = {0}; - bool resc_reinit = false, fw_reset = false; + bool fw_reset = !bp->irq_tbl; + bool resc_reinit = false; u32 flags = 0; int rc; @@ -8758,10 +8856,14 @@ if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && !fw_reset) { netdev_err(bp->dev, "RESET_DONE not set during FW reset.\n"); + set_bit(BNXT_STATE_ABORT_ERR, &bp->state); return -ENODEV; } if (resc_reinit || fw_reset) { if (fw_reset) { + bnxt_free_ctx_mem(bp); + kfree(bp->ctx); + bp->ctx = NULL; rc = bnxt_fw_init_one(bp); if (rc) { set_bit(BNXT_STATE_ABORT_ERR, &bp->state); @@ -8913,16 +9015,19 @@ struct hwrm_temp_monitor_query_input req = {0}; struct hwrm_temp_monitor_query_output *resp; struct bnxt *bp = dev_get_drvdata(dev); - u32 temp = 0; + u32 len = 0; + int rc; resp = bp->hwrm_cmd_resp_addr; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1); mutex_lock(&bp->hwrm_cmd_lock); - if (!_hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT)) - temp = resp->temp * 1000; /* display millidegree */ + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (!rc) + len = sprintf(buf, "%u\n", resp->temp * 1000); /* display millidegree */ mutex_unlock(&bp->hwrm_cmd_lock); - - return sprintf(buf, "%u\n", temp); + if (rc) + return rc; + return len; } static SENSOR_DEVICE_ATTR(temp1_input, 0444, bnxt_show_temp, NULL, 0); @@ -8942,7 +9047,16 @@ static void bnxt_hwmon_open(struct bnxt *bp) { + struct hwrm_temp_monitor_query_input req = {0}; struct pci_dev *pdev = bp->pdev; + int rc; + + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1); + rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + if (rc == -EACCES || rc == -EOPNOTSUPP) { + bnxt_hwmon_close(bp); + return; + } if (bp->hwmon_dev) return; @@ -9104,15 +9218,15 @@ } } - bnxt_enable_napi(bp); - bnxt_debug_dev_init(bp); - rc = bnxt_init_nic(bp, irq_re_init); if (rc) { netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); - goto open_err; + goto open_err_irq; } + bnxt_enable_napi(bp); + bnxt_debug_dev_init(bp); + if (link_re_init) { mutex_lock(&bp->link_lock); rc = bnxt_update_phy_setting(bp); @@ -9143,10 +9257,6 @@ bnxt_vf_reps_open(bp); return 0; -open_err: - bnxt_debug_dev_exit(bp); - bnxt_disable_napi(bp); - open_err_irq: bnxt_del_napi(bp); @@ -9162,7 +9272,10 @@ { int rc = 0; - rc = __bnxt_open_nic(bp, irq_re_init, link_re_init); + if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) + rc = -EIO; + if (!rc) + rc = __bnxt_open_nic(bp, irq_re_init, link_re_init); if (rc) { netdev_err(bp->dev, "nic open fail (rc: %x)\n", rc); dev_close(bp->dev); @@ -9178,6 +9291,12 @@ { int rc = 0; + if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { + netdev_err(bp->dev, "A previous firmware reset has not completed, aborting half open\n"); + rc = -ENODEV; + goto half_open_err; + } + rc = bnxt_alloc_mem(bp, false); if (rc) { netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); @@ -9270,14 +9389,10 @@ bnxt_debug_dev_exit(bp); bnxt_disable_napi(bp); del_timer_sync(&bp->timer); - if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) && - pci_is_enabled(bp->pdev)) - pci_disable_device(bp->pdev); - bnxt_free_skbs(bp); /* Save ring stats before shutdown */ - if (bp->bnapi) + if (bp->bnapi && irq_re_init) bnxt_get_ring_stats(bp, &bp->net_stats_prev); if (irq_re_init) { bnxt_free_irq(bp); @@ -9707,7 +9822,7 @@ if (bp->flags & BNXT_FLAG_CHIP_P5) return bnxt_rfs_supported(bp); - if (!(bp->flags & BNXT_FLAG_MSIX_CAP) || !bnxt_can_reserve_rings(bp)) + if (!(bp->flags & BNXT_FLAG_MSIX_CAP) || !bnxt_can_reserve_rings(bp) || !bp->rx_nr_rings) return false; vnics = 1 + bp->rx_nr_rings; @@ -9747,6 +9862,7 @@ netdev_features_t features) { struct bnxt *bp = netdev_priv(dev); + netdev_features_t vlan_features; if ((features & NETIF_F_NTUPLE) && !bnxt_rfs_capable(bp)) features &= ~NETIF_F_NTUPLE; @@ -9763,12 +9879,14 @@ /* Both CTAG and STAG VLAN accelaration on the RX side have to be * turned on or off together. */ - if ((features & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) != - (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX)) { + vlan_features = features & (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX); + if (vlan_features != (NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_STAG_RX)) { if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) features &= ~(NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX); - else + else if (vlan_features) features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX; } @@ -9927,12 +10045,15 @@ if (netif_running(bp->dev)) { int rc; - if (!silent) + if (silent) { + bnxt_close_nic(bp, false, false); + bnxt_open_nic(bp, false, false); + } else { bnxt_ulp_stop(bp); - bnxt_close_nic(bp, false, false); - rc = bnxt_open_nic(bp, false, false); - if (!silent && !rc) - bnxt_ulp_start(bp); + bnxt_close_nic(bp, true, false); + rc = bnxt_open_nic(bp, true, false); + bnxt_ulp_start(bp, rc); + } } } @@ -9950,8 +10071,7 @@ struct bnxt_fw_health *fw_health = bp->fw_health; u32 val; - if (!fw_health || !fw_health->enabled || - test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + if (!fw_health->enabled || test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) return; if (fw_health->tmr_counter) { @@ -9982,7 +10102,7 @@ struct bnxt *bp = from_timer(bp, t, timer); struct net_device *dev = bp->dev; - if (!netif_running(dev)) + if (!netif_running(dev) || !test_bit(BNXT_STATE_OPEN, &bp->state)) return; if (atomic_read(&bp->intr_sem) != 0) @@ -10050,8 +10170,15 @@ { __bnxt_close_nic(bp, true, false); bnxt_ulp_irq_stop(bp); + /* When firmware is fatal state, disable PCI device to prevent + * any potential bad DMAs before freeing kernel memory. + */ + if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) + pci_disable_device(bp->pdev); bnxt_clear_int_mode(bp); bnxt_hwrm_func_drv_unrgtr(bp); + if (pci_is_enabled(bp->pdev)) + pci_disable_device(bp->pdev); bnxt_free_ctx_mem(bp); kfree(bp->ctx); bp->ctx = NULL; @@ -10236,6 +10363,8 @@ bnxt_cfg_ntp_filters(bp); if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) bnxt_hwrm_exec_fwd_req(bp); + if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) + netdev_info(bp->dev, "Receive PF driver unload event!\n"); if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) { bnxt_hwrm_tunnel_dst_port_alloc( bp, bp->vxlan_port, @@ -10412,6 +10541,23 @@ bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; } +static void bnxt_alloc_fw_health(struct bnxt *bp) +{ + if (bp->fw_health) + return; + + if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) && + !(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) + return; + + bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL); + if (!bp->fw_health) { + netdev_warn(bp->dev, "Failed to allocate fw_health\n"); + bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET; + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; + } +} + static int bnxt_fw_init_one_p1(struct bnxt *bp) { int rc; @@ -10458,6 +10604,7 @@ netdev_warn(bp->dev, "hwrm query adv flow mgnt failure rc: %d\n", rc); + bnxt_alloc_fw_health(bp); rc = bnxt_hwrm_error_recovery_qcfg(bp); if (rc) netdev_warn(bp->dev, "hwrm query error recovery failure rc: %d\n", @@ -10526,6 +10673,8 @@ bnxt_hwrm_coal_params_qcaps(bp); } +static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt); + static int bnxt_fw_init_one(struct bnxt *bp) { int rc; @@ -10540,9 +10689,18 @@ netdev_err(bp->dev, "Firmware init phase 2 failed\n"); return rc; } + rc = bnxt_probe_phy(bp, false); + if (rc) + return rc; rc = bnxt_approve_mac(bp, bp->dev->dev_addr, false); if (rc) return rc; + + /* In case fw capabilities have changed, destroy the unneeded + * reporters and create newly capable ones. + */ + bnxt_dl_fw_reporters_destroy(bp, false); + bnxt_dl_fw_reporters_create(bp); bnxt_fw_init_one_p3(bp); return 0; } @@ -10637,6 +10795,10 @@ } bp->fw_reset_timestamp = jiffies; rtnl_lock(); + if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { + rtnl_unlock(); + goto fw_reset_abort; + } bnxt_fw_reset_close(bp); if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN; @@ -10676,8 +10838,7 @@ bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10); return; case BNXT_FW_RESET_STATE_ENABLE_DEV: - if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state) && - bp->fw_health) { + if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state)) { u32 val; val = bnxt_fw_health_readl(bp, @@ -10769,7 +10930,8 @@ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) != 0 && dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)) != 0) { dev_err(&pdev->dev, "System does not support DMA, aborting\n"); - goto init_err_disable; + rc = -EIO; + goto init_err_release; } pci_set_master(pdev); @@ -10862,13 +11024,13 @@ struct bnxt *bp = netdev_priv(dev); if (netif_running(dev)) - bnxt_close_nic(bp, false, false); + bnxt_close_nic(bp, true, false); dev->mtu = new_mtu; bnxt_set_ring_params(bp); if (netif_running(dev)) - return bnxt_open_nic(bp, false, false); + return bnxt_open_nic(bp, true, false); return 0; } @@ -10966,11 +11128,23 @@ struct flow_keys *keys1 = &f1->fkeys; struct flow_keys *keys2 = &f2->fkeys; - if (keys1->addrs.v4addrs.src == keys2->addrs.v4addrs.src && - keys1->addrs.v4addrs.dst == keys2->addrs.v4addrs.dst && - keys1->ports.ports == keys2->ports.ports && - keys1->basic.ip_proto == keys2->basic.ip_proto && - keys1->basic.n_proto == keys2->basic.n_proto && + if (keys1->basic.n_proto != keys2->basic.n_proto || + keys1->basic.ip_proto != keys2->basic.ip_proto) + return false; + + if (keys1->basic.n_proto == htons(ETH_P_IP)) { + if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src || + keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst) + return false; + } else { + if (memcmp(&keys1->addrs.v6addrs.src, &keys2->addrs.v6addrs.src, + sizeof(keys1->addrs.v6addrs.src)) || + memcmp(&keys1->addrs.v6addrs.dst, &keys2->addrs.v6addrs.dst, + sizeof(keys1->addrs.v6addrs.dst))) + return false; + } + + if (keys1->ports.ports == keys2->ports.ports && keys1->control.flags == keys2->control.flags && ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) && ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr)) @@ -11041,8 +11215,8 @@ rcu_read_lock(); hlist_for_each_entry_rcu(fltr, head, hash) { if (bnxt_fltr_match(fltr, new_fltr)) { + rc = fltr->sw_id; rcu_read_unlock(); - rc = 0; goto err_free; } } @@ -11117,8 +11291,6 @@ } } } - if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) - netdev_info(bp->dev, "Receive PF driver unload event!"); } #else @@ -11262,7 +11434,7 @@ return -EOPNOTSUPP; /* The PF and it's VF-reps only support the switchdev framework */ - if (!BNXT_PF(bp)) + if (!BNXT_PF(bp) || !(bp->flags & BNXT_FLAG_DSN_VALID)) return -EOPNOTSUPP; ppid->id_len = sizeof(bp->switch_id); @@ -11318,17 +11490,21 @@ struct net_device *dev = pci_get_drvdata(pdev); struct bnxt *bp = netdev_priv(dev); - if (BNXT_PF(bp)) { + if (BNXT_PF(bp)) bnxt_sriov_disable(bp); - bnxt_dl_unregister(bp); - } pci_disable_pcie_error_reporting(pdev); unregister_netdev(dev); - bnxt_shutdown_tc(bp); - bnxt_cancel_sp_work(bp); + clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); + /* Flush any pending tasks */ + cancel_work_sync(&bp->sp_task); + cancel_delayed_work_sync(&bp->fw_reset_task); bp->sp_event = 0; + bnxt_dl_fw_reporters_destroy(bp, true); + bnxt_dl_unregister(bp); + bnxt_shutdown_tc(bp); + bnxt_clear_int_mode(bp); bnxt_hwrm_func_drv_unrgtr(bp); bnxt_free_hwrm_resources(bp); @@ -11337,6 +11513,8 @@ bnxt_dcb_free(bp); kfree(bp->edev); bp->edev = NULL; + kfree(bp->fw_health); + bp->fw_health = NULL; bnxt_cleanup_pci(bp); bnxt_free_ctx_mem(bp); kfree(bp->ctx); @@ -11552,6 +11730,10 @@ bp->rx_nr_rings++; bp->cp_nr_rings++; } + if (rc) { + bp->tx_nr_rings = 0; + bp->rx_nr_rings = 0; + } return rc; } @@ -11574,10 +11756,9 @@ goto init_dflt_ring_err; bp->tx_nr_rings_per_tc = bp->tx_nr_rings; - if (bnxt_rfs_supported(bp) && bnxt_rfs_capable(bp)) { - bp->flags |= BNXT_FLAG_RFS; - bp->dev->features |= NETIF_F_NTUPLE; - } + + bnxt_set_dflt_rfs(bp); + init_dflt_ring_err: bnxt_ulp_irq_restart(bp, rc); return rc; @@ -11652,6 +11833,7 @@ put_unaligned_le32(dw, &dsn[0]); pci_read_config_dword(pdev, pos + 4, &dw); put_unaligned_le32(dw, &dsn[4]); + bp->flags |= BNXT_FLAG_DSN_VALID; return 0; } @@ -11668,6 +11850,14 @@ if (version_printed++ == 0) pr_info("%s", version); + /* Clear any pending DMA transactions from crash kernel + * while loading driver in capture kernel. + */ + if (is_kdump_kernel()) { + pci_clear_master(pdev); + pcie_flr(pdev); + } + max_irqs = bnxt_get_max_irq(pdev); dev = alloc_etherdev_mq(sizeof(*bp), max_irqs); if (!dev) @@ -11763,9 +11953,7 @@ if (BNXT_PF(bp)) { /* Read the adapter's DSN to use as the eswitch switch_id */ - rc = bnxt_pcie_dsn_get(bp, bp->switch_id); - if (rc) - goto init_err_pci_clean; + bnxt_pcie_dsn_get(bp, bp->switch_id); } /* MTU range: 60 - FW defined max */ @@ -11806,39 +11994,46 @@ create_singlethread_workqueue("bnxt_pf_wq"); if (!bnxt_pf_wq) { dev_err(&pdev->dev, "Unable to create workqueue.\n"); + rc = -ENOMEM; goto init_err_pci_clean; } } bnxt_init_tc(bp); } + bnxt_dl_register(bp); + rc = register_netdev(dev); if (rc) - goto init_err_cleanup_tc; + goto init_err_cleanup; if (BNXT_PF(bp)) - bnxt_dl_register(bp); + devlink_port_type_eth_set(&bp->dl_port, bp->dev); + bnxt_dl_fw_reporters_create(bp); netdev_info(dev, "%s found at mem %lx, node addr %pM\n", board_info[ent->driver_data].name, (long)pci_resource_start(pdev, 0), dev->dev_addr); pcie_print_link_status(pdev); + pci_save_state(pdev); return 0; -init_err_cleanup_tc: +init_err_cleanup: + bnxt_dl_unregister(bp); bnxt_shutdown_tc(bp); bnxt_clear_int_mode(bp); init_err_pci_clean: bnxt_free_hwrm_short_cmd_req(bp); bnxt_free_hwrm_resources(bp); - bnxt_free_ctx_mem(bp); - kfree(bp->ctx); - bp->ctx = NULL; + bnxt_ethtool_free(bp); kfree(bp->fw_health); bp->fw_health = NULL; bnxt_cleanup_pci(bp); + bnxt_free_ctx_mem(bp); + kfree(bp->ctx); + bp->ctx = NULL; init_err_free: free_netdev(dev); @@ -11862,10 +12057,10 @@ dev_close(dev); bnxt_ulp_shutdown(bp); + bnxt_clear_int_mode(bp); + pci_disable_device(pdev); if (system_state == SYSTEM_POWER_OFF) { - bnxt_clear_int_mode(bp); - pci_disable_device(pdev); pci_wake_from_d3(pdev, bp->wol); pci_set_power_state(pdev, PCI_D3hot); } @@ -11954,6 +12149,9 @@ return PCI_ERS_RESULT_DISCONNECT; } + if (state == pci_channel_io_frozen) + set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state); + if (netif_running(netdev)) bnxt_close(netdev); @@ -11977,7 +12175,7 @@ { struct net_device *netdev = pci_get_drvdata(pdev); struct bnxt *bp = netdev_priv(netdev); - int err = 0; + int err = 0, off; pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; netdev_info(bp->dev, "PCI Slot Reset\n"); @@ -11989,23 +12187,41 @@ "Cannot re-enable PCI device after reset.\n"); } else { pci_set_master(pdev); + /* Upon fatal error, our device internal logic that latches to + * BAR value is getting reset and will restore only upon + * rewritting the BARs. + * + * As pci_restore_state() does not re-write the BARs if the + * value is same as saved value earlier, driver needs to + * write the BARs to 0 to force restore, in case of fatal error. + */ + if (test_and_clear_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, + &bp->state)) { + for (off = PCI_BASE_ADDRESS_0; + off <= PCI_BASE_ADDRESS_5; off += 4) + pci_write_config_dword(bp->pdev, off, 0); + } + pci_restore_state(pdev); + pci_save_state(pdev); err = bnxt_hwrm_func_reset(bp); if (!err && netif_running(netdev)) err = bnxt_open(netdev); - if (!err) { + if (!err) result = PCI_ERS_RESULT_RECOVERED; - bnxt_ulp_start(bp); - } + bnxt_ulp_start(bp, err); } - if (result != PCI_ERS_RESULT_RECOVERED && netif_running(netdev)) - dev_close(netdev); + if (result != PCI_ERS_RESULT_RECOVERED) { + if (netif_running(netdev)) + dev_close(netdev); + pci_disable_device(pdev); + } rtnl_unlock(); - return PCI_ERS_RESULT_RECOVERED; + return result; } /** @@ -12047,8 +12263,16 @@ static int __init bnxt_init(void) { + int err; + bnxt_debug_init(); - return pci_register_driver(&bnxt_pci_driver); + err = pci_register_driver(&bnxt_pci_driver); + if (err) { + bnxt_debug_exit(); + return err; + } + + return 0; } static void __exit bnxt_exit(void) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -559,7 +559,8 @@ #define BNXT_MAX_MTU 9500 #define BNXT_MAX_PAGE_MODE_MTU \ ((unsigned int)PAGE_SIZE - VLAN_ETH_HLEN - NET_IP_ALIGN - \ - XDP_PACKET_HEADROOM) + XDP_PACKET_HEADROOM - \ + SKB_DATA_ALIGN((unsigned int)sizeof(struct skb_shared_info))) #define BNXT_MIN_PKT_SIZE 52 @@ -601,6 +602,11 @@ #define BNXT_MAX_RX_JUM_DESC_CNT (RX_DESC_CNT * MAX_RX_AGG_PAGES - 1) #define BNXT_MAX_TX_DESC_CNT (TX_DESC_CNT * MAX_TX_PAGES - 1) +/* Minimum TX BDs for a TX packet with MAX_SKB_FRAGS + 1. We need one extra + * BD because the first TX BD is always a long BD. + */ +#define BNXT_MIN_TX_DESC_CNT (MAX_SKB_FRAGS + 2) + #define RX_RING(x) (((x) & ~(RX_DESC_CNT - 1)) >> (BNXT_PAGE_SHIFT - 4)) #define RX_IDX(x) ((x) & (RX_DESC_CNT - 1)) @@ -927,6 +933,7 @@ dma_addr_t hw_stats_map; u32 hw_stats_ctx_id; u64 rx_l4_csum_errors; + u64 rx_buf_errors; u64 missed_irqs; struct bnxt_ring_struct cp_ring_struct; @@ -1057,7 +1064,6 @@ #define BNXT_VF_LINK_FORCED 0x4 #define BNXT_VF_LINK_UP 0x8 #define BNXT_VF_TRUST 0x10 - u32 func_flags; /* func cfg flags */ u32 min_tx_rate; u32 max_tx_rate; void *hwrm_cmd_req_addr; @@ -1509,6 +1515,7 @@ #define BNXT_FLAG_NO_AGG_RINGS 0x20000 #define BNXT_FLAG_RX_PAGE_MODE 0x40000 #define BNXT_FLAG_MULTI_HOST 0x100000 + #define BNXT_FLAG_DSN_VALID 0x200000 #define BNXT_FLAG_DOUBLE_DB 0x400000 #define BNXT_FLAG_CHIP_NITRO_A0 0x1000000 #define BNXT_FLAG_DIM 0x2000000 @@ -1626,6 +1633,11 @@ #define BNXT_STATE_IN_FW_RESET 4 #define BNXT_STATE_ABORT_ERR 5 #define BNXT_STATE_FW_FATAL_COND 6 +#define BNXT_STATE_PCI_CHANNEL_IO_FROZEN 8 + +#define BNXT_NO_FW_ACCESS(bp) \ + (test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) || \ + pci_channel_offline((bp)->pdev)) struct bnxt_irq *irq_tbl; int total_irqs; @@ -1657,6 +1669,7 @@ #define BNXT_FW_CAP_PCIE_STATS_SUPPORTED 0x00020000 #define BNXT_FW_CAP_EXT_STATS_SUPPORTED 0x00040000 #define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000 + #define BNXT_FW_CAP_HOT_RESET 0x00200000 #define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) u32 hwrm_spec_code; @@ -1685,7 +1698,7 @@ u16 fw_rx_stats_ext_size; u16 fw_tx_stats_ext_size; u16 hw_ring_stats_size; - u8 pri2cos[8]; + u8 pri2cos_idx[8]; u8 pri2cos_valid; u16 hwrm_max_req_len; @@ -1697,6 +1710,11 @@ #define BC_HWRM_STR_LEN 21 #define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN) char fw_ver_str[FW_VER_STR_LEN]; + u64 fw_ver_code; +#define BNXT_FW_VER_CODE(maj, min, bld, rsv) \ + ((u64)(maj) << 48 | (u64)(min) << 32 | (u64)(bld) << 16 | (rsv)) +#define BNXT_FW_MAJ(bp) ((bp)->fw_ver_code >> 48) + __be16 vxlan_port; u8 vxlan_port_cnt; __le16 vxlan_fw_dst_port_id; @@ -1902,9 +1920,6 @@ case HWRM_CFA_ENCAP_RECORD_FREE: case HWRM_CFA_DECAP_FILTER_ALLOC: case HWRM_CFA_DECAP_FILTER_FREE: - case HWRM_CFA_NTUPLE_FILTER_ALLOC: - case HWRM_CFA_NTUPLE_FILTER_FREE: - case HWRM_CFA_NTUPLE_FILTER_CFG: case HWRM_CFA_EM_FLOW_ALLOC: case HWRM_CFA_EM_FLOW_FREE: case HWRM_CFA_EM_FLOW_CFG: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c @@ -479,24 +479,26 @@ { struct bnxt *bp = netdev_priv(dev); struct ieee_ets *my_ets = bp->ieee_ets; + int rc; ets->ets_cap = bp->max_tc; if (!my_ets) { - int rc; - if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) return 0; my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); if (!my_ets) - return 0; + return -ENOMEM; rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets); if (rc) - return 0; + goto error; rc = bnxt_hwrm_queue_pri2cos_qcfg(bp, my_ets); if (rc) - return 0; + goto error; + + /* cache result */ + bp->ieee_ets = my_ets; } ets->cbs = my_ets->cbs; @@ -505,6 +507,9 @@ memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa)); memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc)); return 0; +error: + kfree(my_ets); + return rc; } static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -19,11 +19,10 @@ struct devlink_fmsg *fmsg) { struct bnxt *bp = devlink_health_reporter_priv(reporter); - struct bnxt_fw_health *health = bp->fw_health; u32 val, health_status; int rc; - if (!health || test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) + if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) return 0; val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); @@ -103,21 +102,15 @@ .recover = bnxt_fw_fatal_recover, }; -static void bnxt_dl_fw_reporters_create(struct bnxt *bp) +void bnxt_dl_fw_reporters_create(struct bnxt *bp) { struct bnxt_fw_health *health = bp->fw_health; - if (!health) + if (!bp->dl || !health) return; - health->fw_reporter = - devlink_health_reporter_create(bp->dl, &bnxt_dl_fw_reporter_ops, - 0, false, bp); - if (IS_ERR(health->fw_reporter)) { - netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n", - PTR_ERR(health->fw_reporter)); - health->fw_reporter = NULL; - } + if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) || health->fw_reset_reporter) + goto err_recovery; health->fw_reset_reporter = devlink_health_reporter_create(bp->dl, @@ -127,8 +120,30 @@ netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n", PTR_ERR(health->fw_reset_reporter)); health->fw_reset_reporter = NULL; + bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET; + } + +err_recovery: + if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) + return; + + if (!health->fw_reporter) { + health->fw_reporter = + devlink_health_reporter_create(bp->dl, + &bnxt_dl_fw_reporter_ops, + 0, false, bp); + if (IS_ERR(health->fw_reporter)) { + netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n", + PTR_ERR(health->fw_reporter)); + health->fw_reporter = NULL; + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; + return; + } } + if (health->fw_fatal_reporter) + return; + health->fw_fatal_reporter = devlink_health_reporter_create(bp->dl, &bnxt_dl_fw_fatal_reporter_ops, @@ -137,24 +152,35 @@ netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n", PTR_ERR(health->fw_fatal_reporter)); health->fw_fatal_reporter = NULL; + bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY; } } -static void bnxt_dl_fw_reporters_destroy(struct bnxt *bp) +void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all) { struct bnxt_fw_health *health = bp->fw_health; - if (!health) + if (!bp->dl || !health) return; - if (health->fw_reporter) - devlink_health_reporter_destroy(health->fw_reporter); - - if (health->fw_reset_reporter) + if ((all || !(bp->fw_cap & BNXT_FW_CAP_HOT_RESET)) && + health->fw_reset_reporter) { devlink_health_reporter_destroy(health->fw_reset_reporter); + health->fw_reset_reporter = NULL; + } - if (health->fw_fatal_reporter) + if ((bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) && !all) + return; + + if (health->fw_reporter) { + devlink_health_reporter_destroy(health->fw_reporter); + health->fw_reporter = NULL; + } + + if (health->fw_fatal_reporter) { devlink_health_reporter_destroy(health->fw_fatal_reporter); + health->fw_fatal_reporter = NULL; + } } void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event) @@ -162,9 +188,6 @@ struct bnxt_fw_health *fw_health = bp->fw_health; struct bnxt_fw_reporter_ctx fw_reporter_ctx; - if (!fw_health) - return; - fw_reporter_ctx.sp_event = event; switch (event) { case BNXT_FW_RESET_NOTIFY_SP_EVENT: @@ -203,6 +226,8 @@ #endif /* CONFIG_BNXT_SRIOV */ }; +static const struct devlink_ops bnxt_vf_dl_ops; + enum bnxt_dl_param_id { BNXT_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, BNXT_DEVLINK_PARAM_ID_GRE_VER_CHECK, @@ -311,10 +336,17 @@ } else { rc = hwrm_send_message_silent(bp, msg, msg_len, HWRM_CMD_TIMEOUT); - if (!rc) + if (!rc) { bnxt_copy_from_nvm_data(val, data, nvm_param.nvm_num_bits, nvm_param.dl_num_bytes); + } else { + struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr; + + if (resp->cmd_err == + NVM_GET_VARIABLE_CMD_ERR_CODE_VAR_NOT_EXIST) + rc = -EOPNOTSUPP; + } } dma_free_coherent(&bp->pdev->dev, sizeof(*data), data, data_dma_addr); if (rc == -EACCES) @@ -409,7 +441,10 @@ return -ENOTSUPP; } - dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); + if (BNXT_PF(bp)) + dl = devlink_alloc(&bnxt_dl_ops, sizeof(struct bnxt_dl)); + else + dl = devlink_alloc(&bnxt_vf_dl_ops, sizeof(struct bnxt_dl)); if (!dl) { netdev_warn(bp->dev, "devlink_alloc failed"); return -ENOMEM; @@ -428,6 +463,9 @@ goto err_dl_free; } + if (!BNXT_PF(bp)) + return 0; + rc = devlink_params_register(dl, bnxt_dl_params, ARRAY_SIZE(bnxt_dl_params)); if (rc) { @@ -444,7 +482,6 @@ netdev_err(bp->dev, "devlink_port_register failed"); goto err_dl_param_unreg; } - devlink_port_type_eth_set(&bp->dl_port, bp->dev); rc = devlink_port_params_register(&bp->dl_port, bnxt_dl_port_params, ARRAY_SIZE(bnxt_dl_port_params)); @@ -455,8 +492,6 @@ devlink_params_publish(dl); - bnxt_dl_fw_reporters_create(bp); - return 0; err_dl_port_unreg: @@ -479,12 +514,14 @@ if (!dl) return; - bnxt_dl_fw_reporters_destroy(bp); - devlink_port_params_unregister(&bp->dl_port, bnxt_dl_port_params, - ARRAY_SIZE(bnxt_dl_port_params)); - devlink_port_unregister(&bp->dl_port); - devlink_params_unregister(dl, bnxt_dl_params, - ARRAY_SIZE(bnxt_dl_params)); + if (BNXT_PF(bp)) { + devlink_port_params_unregister(&bp->dl_port, + bnxt_dl_port_params, + ARRAY_SIZE(bnxt_dl_port_params)); + devlink_port_unregister(&bp->dl_port); + devlink_params_unregister(dl, bnxt_dl_params, + ARRAY_SIZE(bnxt_dl_params)); + } devlink_unregister(dl); devlink_free(dl); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h @@ -39,7 +39,7 @@ #define NVM_OFF_DIS_GRE_VER_CHECK 171 #define NVM_OFF_ENABLE_SRIOV 401 -#define BNXT_MSIX_VEC_MAX 1280 +#define BNXT_MSIX_VEC_MAX 512 #define BNXT_MSIX_VEC_MIN_MAX 128 enum bnxt_nvm_dir_type { @@ -57,6 +57,8 @@ }; void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event); +void bnxt_dl_fw_reporters_create(struct bnxt *bp); +void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all); int bnxt_dl_register(struct bnxt *bp); void bnxt_dl_unregister(struct bnxt *bp); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -124,7 +124,7 @@ } reset_coalesce: - if (netif_running(dev)) { + if (test_bit(BNXT_STATE_OPEN, &bp->state)) { if (update_stats) { rc = bnxt_close_nic(bp, true, false); if (!rc) @@ -173,6 +173,7 @@ static const char * const bnxt_ring_sw_stats_str[] = { "rx_l4_csum_errors", + "rx_buf_errors", "missed_irqs", }; @@ -552,6 +553,7 @@ for (k = 0; k < stat_fields; j++, k++) buf[j] = le64_to_cpu(hw_stats[k]); buf[j++] = cpr->rx_l4_csum_errors; + buf[j++] = cpr->rx_buf_errors; buf[j++] = cpr->missed_irqs; bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter += @@ -587,25 +589,25 @@ if (bp->pri2cos_valid) { for (i = 0; i < 8; i++, j++) { long n = bnxt_rx_bytes_pri_arr[i].base_off + - bp->pri2cos[i]; + bp->pri2cos_idx[i]; buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); } for (i = 0; i < 8; i++, j++) { long n = bnxt_rx_pkts_pri_arr[i].base_off + - bp->pri2cos[i]; + bp->pri2cos_idx[i]; buf[j] = le64_to_cpu(*(rx_port_stats_ext + n)); } for (i = 0; i < 8; i++, j++) { long n = bnxt_tx_bytes_pri_arr[i].base_off + - bp->pri2cos[i]; + bp->pri2cos_idx[i]; buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); } for (i = 0; i < 8; i++, j++) { long n = bnxt_tx_pkts_pri_arr[i].base_off + - bp->pri2cos[i]; + bp->pri2cos_idx[i]; buf[j] = le64_to_cpu(*(tx_port_stats_ext + n)); } @@ -742,7 +744,7 @@ if ((ering->rx_pending > BNXT_MAX_RX_DESC_CNT) || (ering->tx_pending > BNXT_MAX_TX_DESC_CNT) || - (ering->tx_pending <= MAX_SKB_FRAGS)) + (ering->tx_pending < BNXT_MIN_TX_DESC_CNT)) return -EINVAL; if (netif_running(dev)) @@ -767,7 +769,7 @@ int max_tx_sch_inputs; /* Get the most up-to-date max_tx_sch_inputs. */ - if (BNXT_NEW_RM(bp)) + if (netif_running(dev) && BNXT_NEW_RM(bp)) bnxt_hwrm_func_resc_qcaps(bp, false); max_tx_sch_inputs = hw_resc->max_tx_sch_inputs; @@ -1663,14 +1665,15 @@ if (!BNXT_SINGLE_PF(bp)) return -EOPNOTSUPP; + mutex_lock(&bp->link_lock); if (epause->autoneg) { - if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) - return -EINVAL; + if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { + rc = -EINVAL; + goto pause_exit; + } link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; - if (bp->hwrm_spec_code >= 0x10201) - link_info->req_flow_ctrl = - PORT_PHY_CFG_REQ_AUTO_PAUSE_AUTONEG_PAUSE; + link_info->req_flow_ctrl = 0; } else { /* when transition from auto pause to force pause, * force a link change @@ -1688,6 +1691,9 @@ if (netif_running(dev)) rc = bnxt_hwrm_set_pause(bp); + +pause_exit: + mutex_unlock(&bp->link_lock); return rc; } @@ -2003,8 +2009,8 @@ struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_nvm_install_update_input install = {0}; const struct firmware *fw; - int rc, hwrm_err = 0; u32 item_len; + int rc = 0; u16 index; bnxt_hwrm_fw_set_time(bp); @@ -2048,15 +2054,14 @@ memcpy(kmem, fw->data, fw->size); modify.host_src_addr = cpu_to_le64(dma_handle); - hwrm_err = hwrm_send_message(bp, &modify, - sizeof(modify), - FLASH_PACKAGE_TIMEOUT); + rc = hwrm_send_message(bp, &modify, sizeof(modify), + FLASH_PACKAGE_TIMEOUT); dma_free_coherent(&bp->pdev->dev, fw->size, kmem, dma_handle); } } release_firmware(fw); - if (rc || hwrm_err) + if (rc) goto err_exit; if ((install_type & 0xffff) == 0) @@ -2065,20 +2070,19 @@ install.install_type = cpu_to_le32(install_type); mutex_lock(&bp->hwrm_cmd_lock); - hwrm_err = _hwrm_send_message(bp, &install, sizeof(install), - INSTALL_PACKAGE_TIMEOUT); - if (hwrm_err) { + rc = _hwrm_send_message(bp, &install, sizeof(install), + INSTALL_PACKAGE_TIMEOUT); + if (rc) { u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err; if (resp->error_code && error_code == NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { install.flags |= cpu_to_le16( NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); - hwrm_err = _hwrm_send_message(bp, &install, - sizeof(install), - INSTALL_PACKAGE_TIMEOUT); + rc = _hwrm_send_message(bp, &install, sizeof(install), + INSTALL_PACKAGE_TIMEOUT); } - if (hwrm_err) + if (rc) goto flash_pkg_exit; } @@ -2090,7 +2094,7 @@ flash_pkg_exit: mutex_unlock(&bp->hwrm_cmd_lock); err_exit: - if (hwrm_err == -EACCES) + if (rc == -EACCES) bnxt_print_admin_err(bp); return rc; } @@ -2158,6 +2162,9 @@ if (rc != 0) return rc; + if (!dir_entries || !entry_length) + return -EIO; + /* Insert 2 bytes of directory info (count and size of entries) */ if (len < 2) return -EINVAL; @@ -2391,8 +2398,7 @@ struct bnxt *bp = netdev_priv(dev); struct ethtool_eee *eee = &bp->eee; struct bnxt_link_info *link_info = &bp->link_info; - u32 advertising = - _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); + u32 advertising; int rc = 0; if (!BNXT_SINGLE_PF(bp)) @@ -2401,19 +2407,23 @@ if (!(bp->flags & BNXT_FLAG_EEE_CAP)) return -EOPNOTSUPP; + mutex_lock(&bp->link_lock); + advertising = _bnxt_fw_to_ethtool_adv_spds(link_info->advertising, 0); if (!edata->eee_enabled) goto eee_ok; if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { netdev_warn(dev, "EEE requires autoneg\n"); - return -EINVAL; + rc = -EINVAL; + goto eee_exit; } if (edata->tx_lpi_enabled) { if (bp->lpi_tmr_hi && (edata->tx_lpi_timer > bp->lpi_tmr_hi || edata->tx_lpi_timer < bp->lpi_tmr_lo)) { netdev_warn(dev, "Valid LPI timer range is %d and %d microsecs\n", bp->lpi_tmr_lo, bp->lpi_tmr_hi); - return -EINVAL; + rc = -EINVAL; + goto eee_exit; } else if (!bp->lpi_tmr_hi) { edata->tx_lpi_timer = eee->tx_lpi_timer; } @@ -2423,7 +2433,8 @@ } else if (edata->advertised & ~advertising) { netdev_warn(dev, "EEE advertised %x must be a subset of autoneg advertised speeds %x\n", edata->advertised, advertising); - return -EINVAL; + rc = -EINVAL; + goto eee_exit; } eee->advertised = edata->advertised; @@ -2435,6 +2446,8 @@ if (netif_running(dev)) rc = bnxt_hwrm_set_link_setting(bp, false, true); +eee_exit: + mutex_unlock(&bp->link_lock); return rc; } @@ -2569,7 +2582,7 @@ /* Read A2 portion of the EEPROM */ if (length) { start -= ETH_MODULE_SFF_8436_LEN; - rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A2, 1, + rc = bnxt_read_sfp_module_eeprom_info(bp, I2C_DEV_ADDR_A2, 0, start, length, data); } return rc; @@ -3062,8 +3075,15 @@ } } - if (info->dest_buf) - memcpy(info->dest_buf + off, dma_buf, len); + if (info->dest_buf) { + if ((info->seg_start + off + len) <= + BNXT_COREDUMP_BUF_LEN(info->buf_len)) { + memcpy(info->dest_buf + off, dma_buf, len); + } else { + rc = -ENOBUFS; + break; + } + } if (cmn_req->req_type == cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) @@ -3117,7 +3137,7 @@ static int bnxt_hwrm_dbg_coredump_retrieve(struct bnxt *bp, u16 component_id, u16 segment_id, u32 *seg_len, - void *buf, u32 offset) + void *buf, u32 buf_len, u32 offset) { struct hwrm_dbg_coredump_retrieve_input req = {0}; struct bnxt_hwrm_dbg_dma_info info = {NULL}; @@ -3132,8 +3152,11 @@ seq_no); info.data_len_off = offsetof(struct hwrm_dbg_coredump_retrieve_output, data_len); - if (buf) + if (buf) { info.dest_buf = buf + offset; + info.buf_len = buf_len; + info.seg_start = offset; + } rc = bnxt_hwrm_dbg_dma_data(bp, &req, sizeof(req), &info); if (!rc) @@ -3223,14 +3246,17 @@ static int bnxt_get_coredump(struct bnxt *bp, void *buf, u32 *dump_len) { u32 ver_get_resp_len = sizeof(struct hwrm_ver_get_output); + u32 offset = 0, seg_hdr_len, seg_record_len, buf_len = 0; struct coredump_segment_record *seg_record = NULL; - u32 offset = 0, seg_hdr_len, seg_record_len; struct bnxt_coredump_segment_hdr seg_hdr; struct bnxt_coredump coredump = {NULL}; time64_t start_time; u16 start_utc; int rc = 0, i; + if (buf) + buf_len = *dump_len; + start_time = ktime_get_real_seconds(); start_utc = sys_tz.tz_minuteswest * 60; seg_hdr_len = sizeof(seg_hdr); @@ -3263,6 +3289,12 @@ u32 duration = 0, seg_len = 0; unsigned long start, end; + if (buf && ((offset + seg_hdr_len) > + BNXT_COREDUMP_BUF_LEN(buf_len))) { + rc = -ENOBUFS; + goto err; + } + start = jiffies; rc = bnxt_hwrm_dbg_coredump_initiate(bp, comp_id, seg_id); @@ -3275,9 +3307,11 @@ /* Write segment data into the buffer */ rc = bnxt_hwrm_dbg_coredump_retrieve(bp, comp_id, seg_id, - &seg_len, buf, + &seg_len, buf, buf_len, offset + seg_hdr_len); - if (rc) + if (rc && rc == -ENOBUFS) + goto err; + else if (rc) netdev_err(bp->dev, "Failed to retrieve coredump for seg = %d\n", seg_record->segment_id); @@ -3307,7 +3341,8 @@ rc); kfree(coredump.data); *dump_len += sizeof(struct bnxt_coredump_record); - + if (rc == -ENOBUFS) + netdev_err(bp->dev, "Firmware returned large coredump buffer"); return rc; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h @@ -31,6 +31,8 @@ u16 total_segs; }; +#define BNXT_COREDUMP_BUF_LEN(len) ((len) - sizeof(struct bnxt_coredump_record)) + struct bnxt_hwrm_dbg_dma_info { void *dest_buf; int dest_buf_size; @@ -38,6 +40,8 @@ u16 seq_off; u16 data_len_off; u16 segs; + u32 seg_start; + u32 buf_len; }; struct hwrm_dbg_cmn_input { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -85,11 +85,10 @@ if (old_setting == setting) return 0; - func_flags = vf->func_flags; if (setting) - func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE; else - func_flags |= FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; + func_flags = FUNC_CFG_REQ_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE; /*TODO: if the driver supports VLAN filter on guest VLAN, * the spoof check should also include vlan anti-spoofing */ @@ -98,7 +97,6 @@ req.flags = cpu_to_le32(func_flags); rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); if (!rc) { - vf->func_flags = func_flags; if (setting) vf->flags |= BNXT_VF_SPOOFCHK; else @@ -230,7 +228,6 @@ memcpy(vf->mac_addr, mac, ETH_ALEN); bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); memcpy(req.dflt_mac_addr, mac, ETH_ALEN); return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@ -268,7 +265,6 @@ bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.dflt_vlan = cpu_to_le16(vlan_tag); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_VLAN); rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); @@ -307,7 +303,6 @@ return 0; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); req.enables = cpu_to_le32(FUNC_CFG_REQ_ENABLES_MAX_BW); req.max_bw = cpu_to_le32(max_tx_rate); req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_MIN_BW); @@ -403,6 +398,7 @@ } } + bp->pf.active_vfs = 0; kfree(bp->pf.vf); bp->pf.vf = NULL; } @@ -479,7 +475,6 @@ vf = &bp->pf.vf[vf_id]; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_CFG, -1, -1); req.fid = cpu_to_le16(vf->fw_fid); - req.flags = cpu_to_le32(vf->func_flags); if (is_valid_ether_addr(vf->mac_addr)) { req.enables |= cpu_to_le32(FUNC_CFG_REQ_ENABLES_DFLT_MAC_ADDR); @@ -602,7 +597,7 @@ hw_resc->max_stat_ctxs -= le16_to_cpu(req.min_stat_ctx) * n; hw_resc->max_vnics -= le16_to_cpu(req.min_vnics) * n; if (bp->flags & BNXT_FLAG_CHIP_P5) - hw_resc->max_irqs -= vf_msix * n; + hw_resc->max_nqs -= vf_msix; rc = pf->active_vfs; } @@ -839,7 +834,6 @@ bnxt_free_vf_resources(bp); - bp->pf.active_vfs = 0; /* Reclaim all resources for the PF. */ rtnl_lock(); bnxt_restore_pf_fw_resources(bp); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -113,8 +113,10 @@ { struct net_device *dev = edev->net; struct bnxt *bp = netdev_priv(dev); + struct bnxt_hw_resc *hw_resc; int max_idx, max_cp_rings; int avail_msix, idx; + int total_vecs; int rc = 0; ASSERT_RTNL(); @@ -142,7 +144,10 @@ } edev->ulp_tbl[ulp_id].msix_base = idx; edev->ulp_tbl[ulp_id].msix_requested = avail_msix; - if (bp->total_irqs < (idx + avail_msix)) { + hw_resc = &bp->hw_resc; + total_vecs = idx + avail_msix; + if (bp->total_irqs < total_vecs || + (BNXT_NEW_RM(bp) && hw_resc->resv_irqs < total_vecs)) { if (netif_running(dev)) { bnxt_close_nic(bp, true, false); rc = bnxt_open_nic(bp, true, false); @@ -156,7 +161,6 @@ } if (BNXT_NEW_RM(bp)) { - struct bnxt_hw_resc *hw_resc = &bp->hw_resc; int resv_msix; resv_msix = hw_resc->resv_irqs - bp->cp_nr_rings; @@ -182,7 +186,7 @@ edev->ulp_tbl[ulp_id].msix_requested = 0; edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED; - if (netif_running(dev)) { + if (netif_running(dev) && !(edev->flags & BNXT_EN_FLAG_ULP_STOPPED)) { bnxt_close_nic(bp, true, false); bnxt_open_nic(bp, true, false); } @@ -212,8 +216,12 @@ int bnxt_get_ulp_stat_ctxs(struct bnxt *bp) { - if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) - return BNXT_MIN_ROCE_STAT_CTXS; + if (bnxt_ulp_registered(bp->edev, BNXT_ROCE_ULP)) { + struct bnxt_en_dev *edev = bp->edev; + + if (edev->ulp_tbl[BNXT_ROCE_ULP].msix_requested) + return BNXT_MIN_ROCE_STAT_CTXS; + } return 0; } @@ -266,6 +274,7 @@ if (!edev) return; + edev->flags |= BNXT_EN_FLAG_ULP_STOPPED; for (i = 0; i < BNXT_MAX_ULP; i++) { struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; @@ -276,7 +285,7 @@ } } -void bnxt_ulp_start(struct bnxt *bp) +void bnxt_ulp_start(struct bnxt *bp, int err) { struct bnxt_en_dev *edev = bp->edev; struct bnxt_ulp_ops *ops; @@ -285,6 +294,11 @@ if (!edev) return; + edev->flags &= ~BNXT_EN_FLAG_ULP_STOPPED; + + if (err) + return; + for (i = 0; i < BNXT_MAX_ULP; i++) { struct bnxt_ulp *ulp = &edev->ulp_tbl[i]; @@ -459,13 +473,14 @@ if (!edev) return ERR_PTR(-ENOMEM); edev->en_ops = &bnxt_en_ops_tbl; - if (bp->flags & BNXT_FLAG_ROCEV1_CAP) - edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; - if (bp->flags & BNXT_FLAG_ROCEV2_CAP) - edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; edev->net = dev; edev->pdev = bp->pdev; bp->edev = edev; } + edev->flags &= ~BNXT_EN_FLAG_ROCE_CAP; + if (bp->flags & BNXT_FLAG_ROCEV1_CAP) + edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; + if (bp->flags & BNXT_FLAG_ROCEV2_CAP) + edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; return bp->edev; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.h @@ -64,6 +64,7 @@ #define BNXT_EN_FLAG_ROCE_CAP (BNXT_EN_FLAG_ROCEV1_CAP | \ BNXT_EN_FLAG_ROCEV2_CAP) #define BNXT_EN_FLAG_MSIX_REQUESTED 0x4 + #define BNXT_EN_FLAG_ULP_STOPPED 0x8 const struct bnxt_en_ops *en_ops; struct bnxt_ulp ulp_tbl[BNXT_MAX_ULP]; }; @@ -92,7 +93,7 @@ int bnxt_get_ulp_msix_base(struct bnxt *bp); int bnxt_get_ulp_stat_ctxs(struct bnxt *bp); void bnxt_ulp_stop(struct bnxt *bp); -void bnxt_ulp_start(struct bnxt *bp); +void bnxt_ulp_start(struct bnxt *bp, int err); void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs); void bnxt_ulp_shutdown(struct bnxt *bp); void bnxt_ulp_irq_stop(struct bnxt *bp); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c @@ -398,6 +398,9 @@ struct net_device *dev; int rc, i; + if (!(bp->flags & BNXT_FLAG_DSN_VALID)) + return -ENODEV; + bp->vf_reps = kcalloc(num_vfs, sizeof(vf_rep), GFP_KERNEL); if (!bp->vf_reps) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -69,6 +69,9 @@ #define GENET_RDMA_REG_OFF (priv->hw_params->rdma_offset + \ TOTAL_DESC * DMA_DESC_SIZE) +/* Forward declarations */ +static void bcmgenet_set_rx_mode(struct net_device *dev); + static inline void bcmgenet_writel(u32 value, void __iomem *offset) { /* MIPS chips strapped for BE will automagically configure the @@ -995,6 +998,8 @@ if (netif_running(dev)) bcmgenet_update_mib_counters(priv); + dev->netdev_ops->ndo_get_stats(dev); + for (i = 0; i < BCMGENET_STATS_LEN; i++) { const struct bcmgenet_stats *s; char *p; @@ -1013,7 +1018,8 @@ } } -static void bcmgenet_eee_enable_set(struct net_device *dev, bool enable) +void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, + bool tx_lpi_enabled) { struct bcmgenet_priv *priv = netdev_priv(dev); u32 off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL; @@ -1033,7 +1039,7 @@ /* Enable EEE and switch to a 27Mhz clock automatically */ reg = bcmgenet_readl(priv->base + off); - if (enable) + if (tx_lpi_enabled) reg |= TBUF_EEE_EN | TBUF_PM_EN; else reg &= ~(TBUF_EEE_EN | TBUF_PM_EN); @@ -1054,6 +1060,7 @@ priv->eee.eee_enabled = enable; priv->eee.eee_active = enable; + priv->eee.tx_lpi_enabled = tx_lpi_enabled; } static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_eee *e) @@ -1069,6 +1076,7 @@ e->eee_enabled = p->eee_enabled; e->eee_active = p->eee_active; + e->tx_lpi_enabled = p->tx_lpi_enabled; e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER); return phy_ethtool_get_eee(dev->phydev, e); @@ -1078,7 +1086,6 @@ { struct bcmgenet_priv *priv = netdev_priv(dev); struct ethtool_eee *p = &priv->eee; - int ret = 0; if (GENET_IS_V1(priv)) return -EOPNOTSUPP; @@ -1089,16 +1096,11 @@ p->eee_enabled = e->eee_enabled; if (!p->eee_enabled) { - bcmgenet_eee_enable_set(dev, false); + bcmgenet_eee_enable_set(dev, false, false); } else { - ret = phy_init_eee(dev->phydev, 0); - if (ret) { - netif_err(priv, hw, dev, "EEE initialization failed\n"); - return ret; - } - + p->eee_active = phy_init_eee(dev->phydev, false) >= 0; bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER); - bcmgenet_eee_enable_set(dev, true); + bcmgenet_eee_enable_set(dev, p->eee_active, e->tx_lpi_enabled); } return phy_ethtool_set_eee(dev->phydev, e); @@ -1182,7 +1184,8 @@ switch (mode) { case GENET_POWER_PASSIVE: - reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); + reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS | + EXT_ENERGY_DET_MASK); if (GENET_IS_V5(priv)) { reg &= ~(EXT_PWR_DOWN_PHY_EN | EXT_PWR_DOWN_PHY_RD | @@ -1541,6 +1544,11 @@ return skb; } +static void bcmgenet_hide_tsb(struct sk_buff *skb) +{ + __skb_pull(skb, sizeof(struct status_64)); +} + static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); @@ -1586,11 +1594,6 @@ goto out; } - if (skb_padto(skb, ETH_ZLEN)) { - ret = NETDEV_TX_OK; - goto out; - } - /* Retain how many bytes will be sent on the wire, without TSB inserted * by transmit checksum offload */ @@ -1639,8 +1642,13 @@ len_stat = (size << DMA_BUFLENGTH_SHIFT) | (priv->hw_params->qtag_mask << DMA_TX_QTAG_SHIFT); + /* Note: if we ever change from DMA_TX_APPEND_CRC below we + * will need to restore software padding of "runt" packets + */ + len_stat |= DMA_TX_APPEND_CRC; + if (!i) { - len_stat |= DMA_TX_APPEND_CRC | DMA_SOP; + len_stat |= DMA_SOP; if (skb->ip_summed == CHECKSUM_PARTIAL) len_stat |= DMA_TX_DO_CSUM; } @@ -1651,6 +1659,8 @@ } GENET_CB(skb)->last_cb = tx_cb_ptr; + + bcmgenet_hide_tsb(skb); skb_tx_timestamp(skb); /* Decrement total BD count and advance our write pointer */ @@ -1695,7 +1705,8 @@ dma_addr_t mapping; /* Allocate a new Rx skb */ - skb = netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT); + skb = __netdev_alloc_skb(priv->dev, priv->rx_buf_len + SKB_ALIGNMENT, + GFP_ATOMIC | __GFP_NOWARN); if (!skb) { priv->mib.alloc_rx_buff_failed++; netif_err(priv, rx_err, priv->dev, @@ -1811,6 +1822,14 @@ __func__, p_index, ring->c_index, ring->read_ptr, dma_length_status); + if (unlikely(len > RX_BUF_LENGTH)) { + netif_err(priv, rx_status, dev, "oversized packet\n"); + dev->stats.rx_length_errors++; + dev->stats.rx_errors++; + dev_kfree_skb_any(skb); + goto next; + } + if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) { netif_err(priv, rx_status, dev, "dropping fragmented packet!\n"); @@ -1971,12 +1990,18 @@ { u32 reg; + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) { + spin_unlock_bh(&priv->reg_lock); + return; + } if (enable) reg |= mask; else reg &= ~mask; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); /* UniMAC stops on a packet boundary, wait for a full-size packet * to be processed @@ -1991,11 +2016,11 @@ bcmgenet_rbuf_ctrl_set(priv, 0); udelay(10); - /* disable MAC while updating its registers */ - bcmgenet_umac_writel(priv, 0, UMAC_CMD); - - /* issue soft reset with (rg)mii loopback to ensure a stable rxclk */ - bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD); + /* issue soft reset and disable MAC while updating its registers */ + spin_lock_bh(&priv->reg_lock); + bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD); + udelay(2); + spin_unlock_bh(&priv->reg_lock); } static void bcmgenet_intr_disable(struct bcmgenet_priv *priv) @@ -2164,8 +2189,8 @@ DMA_END_ADDR); /* Initialize Tx NAPI */ - netif_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, - NAPI_POLL_WEIGHT); + netif_tx_napi_add(priv->dev, &ring->napi, bcmgenet_tx_poll, + NAPI_POLL_WEIGHT); } /* Initialize a RDMA ring */ @@ -2777,17 +2802,23 @@ } /* Returns a reusable dma control register value */ -static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) +static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx) { + unsigned int i; u32 reg; u32 dma_ctrl; /* disable DMA */ dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN; + for (i = 0; i < priv->hw_params->tx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); reg = bcmgenet_tdma_readl(priv, DMA_CTRL); reg &= ~dma_ctrl; bcmgenet_tdma_writel(priv, reg, DMA_CTRL); + dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN; + for (i = 0; i < priv->hw_params->rx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); reg = bcmgenet_rdma_readl(priv, DMA_CTRL); reg &= ~dma_ctrl; bcmgenet_rdma_writel(priv, reg, DMA_CTRL); @@ -2796,6 +2827,14 @@ udelay(10); bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH); + if (flush_rx) { + reg = bcmgenet_rbuf_ctrl_get(priv); + bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0)); + udelay(10); + bcmgenet_rbuf_ctrl_set(priv, reg); + udelay(10); + } + return dma_ctrl; } @@ -2849,6 +2888,9 @@ struct bcmgenet_priv *priv = netdev_priv(dev); /* Start the network engine */ + netif_addr_lock_bh(dev); + bcmgenet_set_rx_mode(dev); + netif_addr_unlock_bh(dev); bcmgenet_enable_rx_napi(priv); umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true); @@ -2890,14 +2932,8 @@ bcmgenet_set_hw_addr(priv, dev->dev_addr); - if (priv->internal_phy) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg |= EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } - - /* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + /* Disable RX/TX DMA and flush TX and RX queues */ + dma_ctrl = bcmgenet_dma_disable(priv, true); /* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv); @@ -2952,7 +2988,7 @@ return ret; } -static void bcmgenet_netif_stop(struct net_device *dev) +static void bcmgenet_netif_stop(struct net_device *dev, bool stop_phy) { struct bcmgenet_priv *priv = netdev_priv(dev); @@ -2967,7 +3003,8 @@ /* Disable MAC transmit. TX DMA disabled must be done before this */ umac_enable_set(priv, CMD_TX_EN, false); - phy_stop(dev->phydev); + if (stop_phy) + phy_stop(dev->phydev); bcmgenet_disable_rx_napi(priv); bcmgenet_intr_disable(priv); @@ -2993,7 +3030,7 @@ netif_dbg(priv, ifdown, dev, "bcmgenet_close\n"); - bcmgenet_netif_stop(dev); + bcmgenet_netif_stop(dev, false); /* Really kill the PHY state machine and disconnect from it */ phy_disconnect(dev->phydev); @@ -3117,16 +3154,19 @@ * 3. The number of filters needed exceeds the number filters * supported by the hardware. */ + spin_lock(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) || (nfilter > MAX_MDF_FILTER)) { reg |= CMD_PROMISC; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock(&priv->reg_lock); bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL); return; } else { reg &= ~CMD_PROMISC; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock(&priv->reg_lock); } /* update MDF filter */ @@ -3204,6 +3244,7 @@ dev->stats.rx_packets = rx_packets; dev->stats.rx_errors = rx_errors; dev->stats.rx_missed_errors = rx_errors; + dev->stats.rx_dropped = rx_dropped; return &dev->stats; } @@ -3483,6 +3524,7 @@ goto err; } + spin_lock_init(&priv->reg_lock); spin_lock_init(&priv->lock); SET_NETDEV_DEV(dev, &pdev->dev); @@ -3500,10 +3542,12 @@ /* Request the WOL interrupt and advertise suspend if available */ priv->wol_irq_disabled = true; - err = devm_request_irq(&pdev->dev, priv->wol_irq, bcmgenet_wol_isr, 0, - dev->name, priv); - if (!err) - device_set_wakeup_capable(&pdev->dev, 1); + if (priv->wol_irq > 0) { + err = devm_request_irq(&pdev->dev, priv->wol_irq, + bcmgenet_wol_isr, 0, dev->name, priv); + if (!err) + device_set_wakeup_capable(&pdev->dev, 1); + } /* Set the needed headroom to account for any possible * features enabling/disabling at runtime @@ -3578,8 +3622,10 @@ clk_disable_unprepare(priv->clk); err = register_netdev(dev); - if (err) + if (err) { + bcmgenet_mii_exit(dev); goto err; + } return err; @@ -3609,7 +3655,6 @@ struct bcmgenet_priv *priv = netdev_priv(dev); unsigned long dma_ctrl; int ret; - u32 reg; if (!netif_running(dev)) return 0; @@ -3641,17 +3686,11 @@ bcmgenet_set_hw_addr(priv, dev->dev_addr); - if (priv->internal_phy) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg |= EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } - if (priv->wolopts) bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC); /* Disable RX/TX DMA and flush TX queues */ - dma_ctrl = bcmgenet_dma_disable(priv); + dma_ctrl = bcmgenet_dma_disable(priv, false); /* Reinitialize TDMA and RDMA and SW housekeeping */ ret = bcmgenet_init_dma(priv); @@ -3666,9 +3705,6 @@ if (!device_may_wakeup(d)) phy_resume(dev->phydev); - if (priv->eee.eee_enabled) - bcmgenet_eee_enable_set(dev, true); - bcmgenet_netif_start(dev); netif_device_attach(dev); @@ -3693,7 +3729,7 @@ netif_device_detach(dev); - bcmgenet_netif_stop(dev); + bcmgenet_netif_stop(dev, true); if (!device_may_wakeup(d)) phy_suspend(dev->phydev); @@ -3733,3 +3769,4 @@ MODULE_DESCRIPTION("Broadcom GENET Ethernet controller driver"); MODULE_ALIAS("platform:bcmgenet"); MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: mdio-bcm-unimac"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -14,6 +14,7 @@ #include #include #include +#include /* total number of Buffer Descriptors, same for Rx/Tx */ #define TOTAL_DESC 256 @@ -607,6 +608,8 @@ /* device context */ struct bcmgenet_priv { void __iomem *base; + /* reg_lock: lock to serialize access to shared registers */ + spinlock_t reg_lock; enum bcmgenet_version version; struct net_device *dev; @@ -674,6 +677,7 @@ /* WOL */ struct clk *clk_wol; u32 wolopts; + u8 sopass[SOPASS_MAX]; struct bcmgenet_mib_counters mib; @@ -734,4 +738,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode); +void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, + bool tx_lpi_enabled); + #endif /* __BCMGENET_H__ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -41,18 +41,20 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct bcmgenet_priv *priv = netdev_priv(dev); - u32 reg; + struct device *kdev = &priv->pdev->dev; + + if (!device_can_wakeup(kdev)) { + wol->supported = 0; + wol->wolopts = 0; + return; + } wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE; wol->wolopts = priv->wolopts; memset(wol->sopass, 0, sizeof(wol->sopass)); - if (wol->wolopts & WAKE_MAGICSECURE) { - reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_MS); - put_unaligned_be16(reg, &wol->sopass[0]); - reg = bcmgenet_umac_readl(priv, UMAC_MPD_PW_LS); - put_unaligned_be32(reg, &wol->sopass[2]); - } + if (wol->wolopts & WAKE_MAGICSECURE) + memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass)); } /* ethtool function - set WOL (Wake on LAN) settings. @@ -62,7 +64,6 @@ { struct bcmgenet_priv *priv = netdev_priv(dev); struct device *kdev = &priv->pdev->dev; - u32 reg; if (!device_can_wakeup(kdev)) return -ENOTSUPP; @@ -70,17 +71,8 @@ if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE)) return -EINVAL; - reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - if (wol->wolopts & WAKE_MAGICSECURE) { - bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]), - UMAC_MPD_PW_MS); - bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]), - UMAC_MPD_PW_LS); - reg |= MPD_PW_EN; - } else { - reg &= ~MPD_PW_EN; - } - bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); + if (wol->wolopts & WAKE_MAGICSECURE) + memcpy(priv->sopass, wol->sopass, sizeof(priv->sopass)); /* Flag the device and relevant IRQ as wakeup capable */ if (wol->wolopts) { @@ -120,6 +112,14 @@ return retries; } +static void bcmgenet_set_mpd_password(struct bcmgenet_priv *priv) +{ + bcmgenet_umac_writel(priv, get_unaligned_be16(&priv->sopass[0]), + UMAC_MPD_PW_MS); + bcmgenet_umac_writel(priv, get_unaligned_be32(&priv->sopass[2]), + UMAC_MPD_PW_LS); +} + int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode) { @@ -132,21 +132,31 @@ return -EINVAL; } - /* disable RX */ + /* Can't suspend with WoL if MAC is still in reset */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); + if (reg & CMD_SW_RESET) + reg &= ~CMD_SW_RESET; + + /* disable RX */ reg &= ~CMD_RX_EN; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); mdelay(10); reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg |= MPD_EN; + if (priv->wolopts & WAKE_MAGICSECURE) { + bcmgenet_set_mpd_password(priv); + reg |= MPD_PW_EN; + } bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Do not leave UniMAC in MPD mode only */ retries = bcmgenet_poll_wol_status(priv); if (retries < 0) { reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); - reg &= ~MPD_EN; + reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); return retries; } @@ -155,6 +165,7 @@ retries); /* Enable CRC forward */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); priv->crc_fwd_en = 1; reg |= CMD_CRC_FWD; @@ -162,12 +173,7 @@ /* Receiver must be enabled for WOL MP detection */ reg |= CMD_RX_EN; bcmgenet_umac_writel(priv, reg, UMAC_CMD); - - if (priv->hw_params->flags & GENET_HAS_EXT) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg &= ~EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } + spin_unlock_bh(&priv->reg_lock); return 0; } @@ -185,12 +191,14 @@ reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); if (!(reg & MPD_EN)) return; /* already powered up so skip the rest */ - reg &= ~MPD_EN; + reg &= ~(MPD_EN | MPD_PW_EN); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); /* Disable CRC Forward */ + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg &= ~CMD_CRC_FWD; bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); priv->crc_fwd_en = 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -25,6 +25,7 @@ #include "bcmgenet.h" + /* setup netdev link state when PHY link status change and * update UMAC and RGMII block when link up */ @@ -90,12 +91,25 @@ reg |= RGMII_LINK; bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + spin_lock_bh(&priv->reg_lock); reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) | CMD_HD_EN | CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE); reg |= cmd_bits; + if (reg & CMD_SW_RESET) { + reg &= ~CMD_SW_RESET; + bcmgenet_umac_writel(priv, reg, UMAC_CMD); + udelay(2); + reg |= CMD_TX_EN | CMD_RX_EN; + } bcmgenet_umac_writel(priv, reg, UMAC_CMD); + spin_unlock_bh(&priv->reg_lock); + + priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0; + bcmgenet_eee_enable_set(dev, + priv->eee.eee_enabled && priv->eee.eee_active, + priv->eee.tx_lpi_enabled); } else { /* done if nothing has changed */ if (!status_changed) @@ -181,38 +195,8 @@ const char *phy_name = NULL; u32 id_mode_dis = 0; u32 port_ctrl; - int bmcr = -1; - int ret; u32 reg; - /* MAC clocking workaround during reset of umac state machines */ - reg = bcmgenet_umac_readl(priv, UMAC_CMD); - if (reg & CMD_SW_RESET) { - /* An MII PHY must be isolated to prevent TXC contention */ - if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { - ret = phy_read(phydev, MII_BMCR); - if (ret >= 0) { - bmcr = ret; - ret = phy_write(phydev, MII_BMCR, - bmcr | BMCR_ISOLATE); - } - if (ret) { - netdev_err(dev, "failed to isolate PHY\n"); - return ret; - } - } - /* Switch MAC clocking to RGMII generated clock */ - bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL); - /* Ensure 5 clks with Rx disabled - * followed by 5 clks with Reset asserted - */ - udelay(4); - reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN); - bcmgenet_umac_writel(priv, reg, UMAC_CMD); - /* Ensure 5 more clocks before Rx is enabled */ - udelay(2); - } - priv->ext_phy = !priv->internal_phy && (priv->phy_interface != PHY_INTERFACE_MODE_MOCA); @@ -244,9 +228,6 @@ phy_set_max_speed(phydev, SPEED_100); bcmgenet_sys_writel(priv, PORT_MODE_EXT_EPHY, SYS_PORT_CTRL); - /* Restore the MII PHY after isolation */ - if (bmcr >= 0) - phy_write(phydev, MII_BMCR, bmcr); break; case PHY_INTERFACE_MODE_REVMII: @@ -290,6 +271,7 @@ * block for the interface to work */ if (priv->ext_phy) { + mutex_lock(&phydev->lock); reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); reg |= id_mode_dis; if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) @@ -297,6 +279,7 @@ else reg |= RGMII_MODE_EN; bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); + mutex_unlock(&phydev->lock); } if (init) @@ -426,6 +409,10 @@ int id, ret; pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!pres) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } memset(&res, 0, sizeof(res)); memset(&ppd, 0, sizeof(ppd)); @@ -561,7 +548,7 @@ }; phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL); - if (!phydev || IS_ERR(phydev)) { + if (IS_ERR(phydev)) { dev_err(kdev, "failed to register fixed PHY device\n"); return -ENODEV; } @@ -614,5 +601,7 @@ if (of_phy_is_fixed_link(dn)) of_phy_deregister_fixed_link(dn); of_node_put(priv->phy_dn); + clk_prepare_enable(priv->clk); platform_device_unregister(priv->mii_pdev); + clk_disable_unprepare(priv->clk); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/tg3.c +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/tg3.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -230,6 +231,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FIRMWARE_TG3); +MODULE_FIRMWARE(FIRMWARE_TG357766); MODULE_FIRMWARE(FIRMWARE_TG3TSO); MODULE_FIRMWARE(FIRMWARE_TG3TSO5); @@ -6459,6 +6461,14 @@ int i; u32 *regs; + /* If it is a PCI error, all registers will be 0xffff, + * we don't dump them out, just report the error and return + */ + if (tp->pdev->error_state != pci_channel_io_normal) { + netdev_err(tp->dev, "PCI channel ERROR!\n"); + return; + } + regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC); if (!regs) return; @@ -6869,7 +6879,7 @@ desc_idx, *post_ptr); drop_it_no_recycle: /* Other statistics kept track of by card. */ - tp->rx_dropped++; + tnapi->rx_dropped++; goto next_pkt; } @@ -7227,8 +7237,8 @@ static inline void tg3_reset_task_cancel(struct tg3 *tp) { - cancel_work_sync(&tp->reset_task); - tg3_flag_clear(tp, RESET_TASK_PENDING); + if (test_and_clear_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags)) + cancel_work_sync(&tp->reset_task); tg3_flag_clear(tp, TX_RECOVERY_PENDING); } @@ -7895,8 +7905,10 @@ segs = skb_gso_segment(skb, tp->dev->features & ~(NETIF_F_TSO | NETIF_F_TSO6)); - if (IS_ERR(segs) || !segs) + if (IS_ERR(segs) || !segs) { + tnapi->tx_dropped++; goto tg3_tso_bug_end; + } do { nskb = segs; @@ -8168,7 +8180,7 @@ drop: dev_kfree_skb_any(skb); drop_nofree: - tp->tx_dropped++; + tnapi->tx_dropped++; return NETDEV_TX_OK; } @@ -9347,7 +9359,7 @@ /* tp->lock is held. */ static int tg3_halt(struct tg3 *tp, int kind, bool silent) { - int err; + int err, i; tg3_stop_fw(tp); @@ -9368,6 +9380,13 @@ /* And make sure the next sample is new data */ memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); + + for (i = 0; i < TG3_IRQ_MAX_VECS; ++i) { + struct tg3_napi *tnapi = &tp->napi[i]; + + tnapi->rx_dropped = 0; + tnapi->tx_dropped = 0; + } } return err; @@ -11195,7 +11214,8 @@ rtnl_lock(); tg3_full_lock(tp, 0); - if (!netif_running(tp->dev)) { + if (tp->pcierr_recovery || !netif_running(tp->dev) || + tp->pdev->error_state != pci_channel_io_normal) { tg3_flag_clear(tp, RESET_TASK_PENDING); tg3_full_unlock(tp); rtnl_unlock(); @@ -11219,18 +11239,27 @@ tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); err = tg3_init_hw(tp, true); - if (err) + if (err) { + tg3_full_unlock(tp); + tp->irq_sync = 0; + tg3_napi_enable(tp); + /* Clear this flag so that tg3_reset_task_cancel() will not + * call cancel_work_sync() and wait forever. + */ + tg3_flag_clear(tp, RESET_TASK_PENDING); + dev_close(tp->dev); goto out; + } tg3_netif_start(tp); -out: tg3_full_unlock(tp); if (!err) tg3_phy_start(tp); tg3_flag_clear(tp, RESET_TASK_PENDING); +out: rtnl_unlock(); } @@ -11915,6 +11944,9 @@ { struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; struct tg3_hw_stats *hw_stats = tp->hw_stats; + unsigned long rx_dropped; + unsigned long tx_dropped; + int i; stats->rx_packets = old_stats->rx_packets + get_stat64(&hw_stats->rx_ucast_packets) + @@ -11961,8 +11993,26 @@ stats->rx_missed_errors = old_stats->rx_missed_errors + get_stat64(&hw_stats->rx_discards); - stats->rx_dropped = tp->rx_dropped; - stats->tx_dropped = tp->tx_dropped; + /* Aggregate per-queue counters. The per-queue counters are updated + * by a single writer, race-free. The result computed by this loop + * might not be 100% accurate (counters can be updated in the middle of + * the loop) but the next tg3_get_nstats() will recompute the current + * value so it is acceptable. + * + * Note that these counters wrap around at 4G on 32bit machines. + */ + rx_dropped = (unsigned long)(old_stats->rx_dropped); + tx_dropped = (unsigned long)(old_stats->tx_dropped); + + for (i = 0; i < tp->irq_cnt; i++) { + struct tg3_napi *tnapi = &tp->napi[i]; + + rx_dropped += tnapi->rx_dropped; + tx_dropped += tnapi->tx_dropped; + } + + stats->rx_dropped = rx_dropped; + stats->tx_dropped = tx_dropped; } static int tg3_get_regs_len(struct net_device *dev) @@ -17766,6 +17816,9 @@ } else persist_dma_mask = dma_mask = DMA_BIT_MASK(64); + if (tg3_asic_rev(tp) == ASIC_REV_57766) + persist_dma_mask = DMA_BIT_MASK(31); + /* Configure DMA attributes. */ if (dma_mask > DMA_BIT_MASK(32)) { err = pci_set_dma_mask(pdev, dma_mask); @@ -18140,12 +18193,59 @@ static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume); +/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal + * PCIe AER event on the tg3 device if the tg3 device is not, or cannot + * be, powered down. + */ +static const struct dmi_system_id tg3_restart_aer_quirk_table[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R750"), + }, + }, + {} +}; + static void tg3_shutdown(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct tg3 *tp = netdev_priv(dev); + tg3_reset_task_cancel(tp); + rtnl_lock(); + netif_device_detach(dev); if (netif_running(dev)) @@ -18153,8 +18253,23 @@ if (system_state == SYSTEM_POWER_OFF) tg3_power_down(tp); + else if (system_state == SYSTEM_RESTART && + dmi_first_match(tg3_restart_aer_quirk_table) && + pdev->current_state != PCI_D3cold && + pdev->current_state != PCI_UNKNOWN) { + /* Disable PCIe AER on the tg3 to avoid a fatal + * error during this system restart. + */ + pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + } rtnl_unlock(); + + pci_disable_device(pdev); } /** @@ -18174,10 +18289,13 @@ netdev_info(netdev, "PCI I/O error detected\n"); + /* Want to make sure that the reset task doesn't run */ + tg3_reset_task_cancel(tp); + rtnl_lock(); - /* We probably don't have netdev yet */ - if (!netdev || !netif_running(netdev)) + /* Could be second call or maybe we don't have netdev yet */ + if (!netdev || tp->pcierr_recovery || !netif_running(netdev)) goto done; /* We needn't recover from permanent error */ @@ -18190,9 +18308,6 @@ tg3_timer_stop(tp); - /* Want to make sure that the reset task doesn't run */ - tg3_reset_task_cancel(tp); - netif_device_detach(netdev); /* Clean up software state, even if MMIO is blocked */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/broadcom/tg3.h +++ linux-oracle-5.4.0/drivers/net/ethernet/broadcom/tg3.h @@ -3018,6 +3018,7 @@ u16 *rx_rcb_prod_idx; struct tg3_rx_prodring_set prodring; struct tg3_rx_buffer_desc *rx_rcb; + unsigned long rx_dropped; u32 tx_prod ____cacheline_aligned; u32 tx_cons; @@ -3026,6 +3027,7 @@ u32 prodmbox; struct tg3_tx_buffer_desc *tx_ring; struct tg3_tx_ring_info *tx_buffers; + unsigned long tx_dropped; dma_addr_t status_mapping; dma_addr_t rx_rcb_mapping; @@ -3219,8 +3221,6 @@ /* begin "everything else" cacheline(s) section */ - unsigned long rx_dropped; - unsigned long tx_dropped; struct rtnl_link_stats64 net_stats_prev; struct tg3_ethtool_stats estats_prev; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/brocade/bna/bna_types.h +++ linux-oracle-5.4.0/drivers/net/ethernet/brocade/bna/bna_types.h @@ -410,7 +410,7 @@ /* Tx object */ /* Tx datapath control structure */ -#define BNA_Q_NAME_SIZE 16 +#define BNA_Q_NAME_SIZE (IFNAMSIZ + 6) struct bna_tcb { /* Fast path */ void **sw_qpt; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/brocade/bna/bnad.c +++ linux-oracle-5.4.0/drivers/net/ethernet/brocade/bna/bnad.c @@ -1535,8 +1535,9 @@ for (i = 0; i < num_txqs; i++) { vector_num = tx_info->tcb[i]->intr_vector; - sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name, - tx_id + tx_info->tcb[i]->id); + snprintf(tx_info->tcb[i]->name, BNA_Q_NAME_SIZE, "%s TXQ %d", + bnad->netdev->name, + tx_id + tx_info->tcb[i]->id); err = request_irq(bnad->msix_table[vector_num].vector, (irq_handler_t)bnad_msix_tx, 0, tx_info->tcb[i]->name, @@ -1586,9 +1587,9 @@ for (i = 0; i < num_rxps; i++) { vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; - sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d", - bnad->netdev->name, - rx_id + rx_info->rx_ctrl[i].ccb->id); + snprintf(rx_info->rx_ctrl[i].ccb->name, BNA_Q_NAME_SIZE, + "%s CQ %d", bnad->netdev->name, + rx_id + rx_info->rx_ctrl[i].ccb->id); err = request_irq(bnad->msix_table[vector_num].vector, (irq_handler_t)bnad_msix_rx, 0, rx_info->rx_ctrl[i].ccb->name, @@ -3282,7 +3283,7 @@ { int err, mtu; struct bnad *bnad = netdev_priv(netdev); - u32 rx_count = 0, frame, new_frame; + u32 frame, new_frame; mutex_lock(&bnad->conf_mutex); @@ -3298,12 +3299,9 @@ /* only when transition is over 4K */ if ((frame <= 4096 && new_frame > 4096) || (frame > 4096 && new_frame <= 4096)) - rx_count = bnad_reinit_rx(bnad); + bnad_reinit_rx(bnad); } - /* rx_count > 0 - new rx created - * - Linux set err = 0 and return - */ err = bnad_mtu_set(bnad, new_frame); if (err) err = -EBUSY; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -312,7 +312,7 @@ void *kern_buf; /* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); @@ -372,7 +372,7 @@ void *kern_buf; /* Copy the user space buf */ - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cadence/macb.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cadence/macb.h @@ -1177,6 +1177,8 @@ struct clk *rx_clk; struct clk *tsu_clk; struct net_device *dev; + /* Protects hw_stats and ethtool_stats */ + spinlock_t stats_lock; union { struct macb_stats macb; struct gem_stats gem; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cadence/macb_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cadence/macb_main.c @@ -73,7 +73,11 @@ /* Max length of transmit frame must be a multiple of 8 bytes */ #define MACB_TX_LEN_ALIGN 8 #define MACB_MAX_TX_LEN ((unsigned int)((1 << MACB_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1))) -#define GEM_MAX_TX_LEN ((unsigned int)((1 << GEM_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1))) +/* Limit maximum TX length as per Cadence TSO errata. This is to avoid a + * false amba_error in TX path from the DMA assuming there is not enough + * space in the SRAM (16KB) even when there is. + */ +#define GEM_MAX_TX_LEN (unsigned int)(0x3FC0) #define GEM_MTU_MIN_SIZE ETH_MIN_MTU #define MACB_NETIF_LSO NETIF_F_TSO @@ -330,8 +334,10 @@ int status; status = pm_runtime_get_sync(&bp->pdev->dev); - if (status < 0) + if (status < 0) { + pm_runtime_put_noidle(&bp->pdev->dev); goto mdio_pm_exit; + } status = macb_mdio_wait_for_idle(bp); if (status < 0) @@ -363,8 +369,10 @@ int status; status = pm_runtime_get_sync(&bp->pdev->dev); - if (status < 0) + if (status < 0) { + pm_runtime_put_noidle(&bp->pdev->dev); goto mdio_pm_exit; + } status = macb_mdio_wait_for_idle(bp); if (status < 0) @@ -711,6 +719,10 @@ } #endif addr |= MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr)); +#ifdef CONFIG_MACB_USE_HWSTAMP + if (bp->hw_dma_cap & HW_DMA_CAP_PTP) + addr &= ~GEM_BIT(DMA_RXVALID); +#endif return addr; } @@ -919,7 +931,6 @@ /* Make hw descriptor updates visible to CPU */ rmb(); - queue->rx_prepared_head++; desc = macb_rx_desc(queue, entry); if (!queue->rx_skbuff[entry]) { @@ -958,6 +969,7 @@ dma_wmb(); desc->addr &= ~MACB_BIT(RX_USED); } + queue->rx_prepared_head++; } /* Make descriptor updates visible to hardware */ @@ -1275,7 +1287,14 @@ if (work_done < budget) { napi_complete_done(napi, work_done); - /* Packets received while interrupts were disabled */ + /* RSR bits only seem to propagate to raise interrupts when + * interrupts are enabled at the time, so if bits are already + * set due to packets received while interrupts were disabled, + * they will not cause another interrupt to be generated when + * interrupts are re-enabled. + * Check for this case here. This has been seen to happen + * around 30% of the time under heavy network load. + */ status = macb_readl(bp, RSR); if (status) { if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) @@ -1283,6 +1302,22 @@ napi_reschedule(napi); } else { queue_writel(queue, IER, bp->rx_intr_mask); + + /* In rare cases, packets could have been received in + * the window between the check above and re-enabling + * interrupts. Therefore, a double-check is required + * to avoid losing a wakeup. This can potentially race + * with the interrupt handler doing the same actions + * if an interrupt is raised just after enabling them, + * but this should be harmless. + */ + status = macb_readl(bp, RSR); + if (unlikely(status)) { + queue_writel(queue, IDR, bp->rx_intr_mask); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(RCOMP)); + napi_schedule(napi); + } } } @@ -1347,6 +1382,7 @@ unsigned int head = queue->tx_head; unsigned int tail = queue->tx_tail; struct macb *bp = queue->bp; + unsigned int head_idx, tbqp; if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) queue_writel(queue, ISR, MACB_BIT(TXUBR)); @@ -1354,6 +1390,13 @@ if (head == tail) return; + tbqp = queue_readl(queue, TBQP) / macb_dma_desc_get_size(bp); + tbqp = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, tbqp)); + head_idx = macb_adj_dma_desc_idx(bp, macb_tx_ring_wrap(bp, head)); + + if (tbqp == head_idx) + return; + macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); } @@ -1440,10 +1483,12 @@ if (status & MACB_BIT(ISR_ROVR)) { /* We missed at least one packet */ + spin_lock(&bp->stats_lock); if (macb_is_gem(bp)) bp->hw_stats.gem.rx_overruns++; else bp->hw_stats.macb.rx_overruns++; + spin_unlock(&bp->stats_lock); if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) queue_writel(queue, ISR, MACB_BIT(ISR_ROVR)); @@ -1664,16 +1709,14 @@ /* Validate LSO compatibility */ - /* there is only one buffer */ - if (!skb_is_nonlinear(skb)) + /* there is only one buffer or protocol is not UDP */ + if (!skb_is_nonlinear(skb) || (ip_hdr(skb)->protocol != IPPROTO_UDP)) return features; /* length of header */ hdrlen = skb_transport_offset(skb); - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - hdrlen += tcp_hdrlen(skb); - /* For LSO: + /* For UFO only: * When software supplies two or more payload buffers all payload buffers * apart from the last must be a multiple of 8 bytes in size. */ @@ -1712,9 +1755,9 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) { - bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb); + bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) || + skb_is_nonlinear(*skb); int padlen = ETH_ZLEN - (*skb)->len; - int headroom = skb_headroom(*skb); int tailroom = skb_tailroom(*skb); struct sk_buff *nskb; u32 fcs; @@ -1728,9 +1771,6 @@ /* FCS could be appeded to tailroom. */ if (tailroom >= ETH_FCS_LEN) goto add_fcs; - /* FCS could be appeded by moving data to headroom. */ - else if (!cloned && headroom + tailroom >= ETH_FCS_LEN) - padlen = 0; /* No room for FCS, need to reallocate skb. */ else padlen = ETH_FCS_LEN; @@ -1739,10 +1779,7 @@ padlen += ETH_FCS_LEN; } - if (!cloned && headroom + tailroom >= padlen) { - (*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len); - skb_set_tail_pointer(*skb, (*skb)->len); - } else { + if (cloned || tailroom < padlen) { nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC); if (!nskb) return -ENOMEM; @@ -2529,6 +2566,10 @@ struct gem_stats *hwstat = &bp->hw_stats.gem; struct net_device_stats *nstat = &bp->dev->stats; + if (!netif_running(bp->dev)) + return nstat; + + spin_lock_irq(&bp->stats_lock); gem_update_stats(bp); nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + @@ -2558,6 +2599,7 @@ nstat->tx_aborted_errors = hwstat->tx_excessive_collisions; nstat->tx_carrier_errors = hwstat->tx_carrier_sense_errors; nstat->tx_fifo_errors = hwstat->tx_underrun; + spin_unlock_irq(&bp->stats_lock); return nstat; } @@ -2565,12 +2607,13 @@ static void gem_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { - struct macb *bp; + struct macb *bp = netdev_priv(dev); - bp = netdev_priv(dev); + spin_lock_irq(&bp->stats_lock); gem_update_stats(bp); memcpy(data, &bp->ethtool_stats, sizeof(u64) * (GEM_STATS_LEN + QUEUE_STATS_LEN * MACB_MAX_QUEUES)); + spin_unlock_irq(&bp->stats_lock); } static int gem_get_sset_count(struct net_device *dev, int sset) @@ -2620,6 +2663,7 @@ return gem_get_stats(bp); /* read stats from hardware */ + spin_lock_irq(&bp->stats_lock); macb_update_stats(bp); /* Convert HW stats into netdevice stats */ @@ -2653,6 +2697,7 @@ nstat->tx_carrier_errors = hwstat->tx_carrier_errors; nstat->tx_fifo_errors = hwstat->tx_underruns; /* Don't know about heartbeat or window errors... */ + spin_unlock_irq(&bp->stats_lock); return nstat; } @@ -2908,6 +2953,9 @@ bool cmp_b = false; bool cmp_c = false; + if (!macb_is_gem(bp)) + return; + tp4sp_v = &(fs->h_u.tcp_ip4_spec); tp4sp_m = &(fs->m_u.tcp_ip4_spec); @@ -3279,6 +3327,7 @@ { struct net_device *netdev = bp->dev; netdev_features_t features = netdev->features; + struct ethtool_rx_fs_item *item; /* TX checksum offload */ macb_set_txcsum_feature(bp, features); @@ -3287,6 +3336,9 @@ macb_set_rxcsum_feature(bp, features); /* RX Flow Filters */ + list_for_each_entry(item, &bp->rx_fs_list.list, list) + gem_prog_cmp_regs(bp, &item->fs); + macb_set_rxflow_feature(bp, features); } @@ -3576,6 +3628,7 @@ reg = gem_readl(bp, DCFG8); bp->max_tuples = min((GEM_BFEXT(SCR2CMP, reg) / 3), GEM_BFEXT(T2SCR, reg)); + INIT_LIST_HEAD(&bp->rx_fs_list.list); if (bp->max_tuples > 0) { /* also needs one ethtype match to check IPv4 */ if (GEM_BFEXT(SCR2ETH, reg) > 0) { @@ -3586,7 +3639,6 @@ /* Filtering is supported in hw but don't enable it in kernel now */ dev->hw_features |= NETIF_F_NTUPLE; /* init Rx flow definitions */ - INIT_LIST_HEAD(&bp->rx_fs_list.list); bp->rx_fs_list.count = 0; spin_lock_init(&bp->rx_fs_lock); } else @@ -3688,6 +3740,12 @@ u32 ctl; int ret; + ret = pm_runtime_get_sync(&lp->pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&lp->pdev->dev); + return ret; + } + /* Clear internal statistics */ ctl = macb_readl(lp, NCR); macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); @@ -3696,7 +3754,7 @@ ret = at91ether_start(dev); if (ret) - return ret; + goto pm_exit; /* Enable MAC interrupts */ macb_writel(lp, IER, MACB_BIT(RCOMP) | @@ -3713,6 +3771,10 @@ netif_start_queue(dev); return 0; + +pm_exit: + pm_runtime_put_sync(&lp->pdev->dev); + return ret; } /* Close the interface */ @@ -3748,7 +3810,7 @@ q->rx_buffers, q->rx_buffers_dma); q->rx_buffers = NULL; - return 0; + return pm_runtime_put(&lp->pdev->dev); } /* Transmit packet */ @@ -4027,7 +4089,7 @@ mgmt->rate = 0; mgmt->hw.init = &init; - *tx_clk = clk_register(NULL, &mgmt->hw); + *tx_clk = devm_clk_register(&pdev->dev, &mgmt->hw); if (IS_ERR(*tx_clk)) return PTR_ERR(*tx_clk); @@ -4042,15 +4104,9 @@ static int fu540_c000_init(struct platform_device *pdev) { - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res) - return -ENODEV; - - mgmt->reg = ioremap(res->start, resource_size(res)); - if (!mgmt->reg) - return -ENOMEM; + mgmt->reg = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(mgmt->reg)) + return PTR_ERR(mgmt->reg); return macb_init(pdev); } @@ -4254,16 +4310,17 @@ bp->wol = 0; if (of_get_property(np, "magic-packet", NULL)) bp->wol |= MACB_WOL_HAS_MAGIC_PACKET; - device_init_wakeup(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET); + device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET); spin_lock_init(&bp->lock); + spin_lock_init(&bp->stats_lock); /* setup capabilities */ macb_configure_caps(bp, macb_config); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT if (GEM_BFEXT(DAW64, gem_readl(bp, DCFG6))) { - dma_set_mask(&pdev->dev, DMA_BIT_MASK(44)); + dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(44)); bp->hw_dma_cap |= HW_DMA_CAP_64B; } #endif @@ -4361,7 +4418,6 @@ err_disable_clocks: clk_disable_unprepare(tx_clk); - clk_unregister(tx_clk); clk_disable_unprepare(hclk); clk_disable_unprepare(pclk); clk_disable_unprepare(rx_clk); @@ -4392,11 +4448,11 @@ mdiobus_free(bp->mii_bus); unregister_netdev(dev); + tasklet_kill(&bp->hresp_err_tasklet); pm_runtime_disable(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev); if (!pm_runtime_suspended(&pdev->dev)) { clk_disable_unprepare(bp->tx_clk); - clk_unregister(bp->tx_clk); clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); clk_disable_unprepare(bp->rx_clk); @@ -4448,7 +4504,8 @@ netif_carrier_off(netdev); if (bp->ptp_info) bp->ptp_info->ptp_remove(netdev); - pm_runtime_force_suspend(dev); + if (!device_may_wakeup(dev)) + pm_runtime_force_suspend(dev); return 0; } @@ -4463,7 +4520,8 @@ if (!netif_running(netdev)) return 0; - pm_runtime_force_resume(dev); + if (!device_may_wakeup(dev)) + pm_runtime_force_resume(dev); if (bp->wol & MACB_WOL_ENABLED) { macb_writel(bp, IDR, MACB_BIT(WOL)); @@ -4502,7 +4560,7 @@ struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); - if (!(device_may_wakeup(&bp->dev->dev))) { + if (!(device_may_wakeup(dev))) { clk_disable_unprepare(bp->tx_clk); clk_disable_unprepare(bp->hclk); clk_disable_unprepare(bp->pclk); @@ -4518,7 +4576,7 @@ struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); - if (!(device_may_wakeup(&bp->dev->dev))) { + if (!(device_may_wakeup(dev))) { clk_prepare_enable(bp->pclk); clk_prepare_enable(bp->hclk); clk_prepare_enable(bp->tx_clk); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cadence/macb_pci.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cadence/macb_pci.c @@ -112,9 +112,9 @@ struct platform_device *plat_dev = pci_get_drvdata(pdev); struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev); - platform_device_unregister(plat_dev); clk_unregister(plat_data->pclk); clk_unregister(plat_data->hclk); + platform_device_unregister(plat_dev); } static const struct pci_device_id dev_id_table[] = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cadence/macb_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cadence/macb_ptp.c @@ -275,6 +275,12 @@ if (GEM_BFEXT(DMA_RXVALID, desc->addr)) { desc_ptp = macb_ptp_desc(bp, desc); + /* Unlikely but check */ + if (!desc_ptp) { + dev_warn_ratelimited(&bp->pdev->dev, + "Timestamp not supported in BD\n"); + return; + } gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); @@ -307,8 +313,11 @@ if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0) return -ENOMEM; - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; desc_ptp = macb_ptp_desc(queue->bp, desc); + /* Unlikely but check */ + if (!desc_ptp) + return -EINVAL; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_timestamp = &queue->tx_timestamps[head]; tx_timestamp->skb = skb; /* ensure ts_1/ts_2 is loaded after ctrl (TX_USED check) */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c @@ -420,7 +420,7 @@ * bits 32:47 indicate the PVF num. */ for (q_no = 0; q_no < ern; q_no++) { - reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; + reg_val = (u64)oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; /* for VF assigned queues. */ if (q_no < oct->sriov_info.pf_srn) { @@ -1167,7 +1167,7 @@ oct->pf_num = ((fdl_bit >> CN23XX_PCIE_SRIOV_FDL_BIT_POS) & CN23XX_PCIE_SRIOV_FDL_MASK); } else { - ret = EINVAL; + ret = -EINVAL; /* Under some virtual environments, extended PCI regs are * inaccessible, in which case the above read will have failed. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_regs.h @@ -521,7 +521,7 @@ #define CN23XX_BAR1_INDEX_OFFSET 3 #define CN23XX_PEM_BAR1_INDEX_REG(port, idx) \ - (CN23XX_PEM_BAR1_INDEX_START + ((port) << CN23XX_PEM_OFFSET) + \ + (CN23XX_PEM_BAR1_INDEX_START + (((u64)port) << CN23XX_PEM_OFFSET) + \ ((idx) << CN23XX_BAR1_INDEX_OFFSET)) /*############################ DPI #########################*/ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/cn66xx_regs.h @@ -412,7 +412,7 @@ | CN6XXX_INTR_M0UNWI_ERR \ | CN6XXX_INTR_M1UPB0_ERR \ | CN6XXX_INTR_M1UPWI_ERR \ - | CN6XXX_INTR_M1UPB0_ERR \ + | CN6XXX_INTR_M1UNB0_ERR \ | CN6XXX_INTR_M1UNWI_ERR \ | CN6XXX_INTR_INSTR_DB_OF_ERR \ | CN6XXX_INTR_SLIST_DB_OF_ERR \ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -1179,7 +1179,7 @@ * @param lio per-network private data * @param start_stop whether to start or stop */ -static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) +static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) { struct octeon_soft_command *sc; union octnet_cmd *ncmd; @@ -1187,15 +1187,15 @@ int retval; if (oct->props[lio->ifidx].rx_on == start_stop) - return; + return 0; sc = (struct octeon_soft_command *) octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, 16, 0); if (!sc) { netif_info(lio, rx_err, lio->netdev, - "Failed to allocate octeon_soft_command\n"); - return; + "Failed to allocate octeon_soft_command struct\n"); + return -ENOMEM; } ncmd = (union octnet_cmd *)sc->virtdptr; @@ -1218,18 +1218,19 @@ if (retval == IQ_SEND_FAILED) { netif_info(lio, rx_err, lio->netdev, "Failed to send RX Control message\n"); octeon_free_soft_command(oct, sc); - return; } else { /* Sleep on a wait queue till the cond flag indicates that the * response arrived or timed-out. */ retval = wait_for_sc_completion_timeout(oct, sc, 0); if (retval) - return; + return retval; oct->props[lio->ifidx].rx_on = start_stop; WRITE_ONCE(sc->caller_is_done, true); } + + return retval; } /** @@ -1816,6 +1817,7 @@ struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; struct napi_struct *napi, *n; + int ret = 0; if (oct->props[lio->ifidx].napi_enabled == 0) { tasklet_disable(&oct_priv->droq_tasklet); @@ -1834,13 +1836,10 @@ ifstate_set(lio, LIO_IFSTATE_RUNNING); - if (OCTEON_CN23XX_PF(oct)) { - if (!oct->msix_on) - if (setup_tx_poll_fn(netdev)) - return -1; - } else { - if (setup_tx_poll_fn(netdev)) - return -1; + if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) { + ret = setup_tx_poll_fn(netdev); + if (ret) + goto err_poll; } netif_tx_start_all_queues(netdev); @@ -1851,7 +1850,9 @@ netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n"); /* tell Octeon to start forwarding packets to host */ - send_rx_ctrl_cmd(lio, 1); + ret = send_rx_ctrl_cmd(lio, 1); + if (ret) + goto err_rx_ctrl; /* start periodical statistics fetch */ INIT_DELAYED_WORK(&lio->stats_wk.work, lio_fetch_stats); @@ -1863,6 +1864,27 @@ netdev->name); return 0; + +err_rx_ctrl: + if (!OCTEON_CN23XX_PF(oct) || !oct->msix_on) + cleanup_tx_poll_fn(netdev); +err_poll: + if (lio->ptp_clock) { + ptp_clock_unregister(lio->ptp_clock); + lio->ptp_clock = NULL; + } + + if (oct->props[lio->ifidx].napi_enabled == 1) { + list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) + napi_disable(napi); + + oct->props[lio->ifidx].napi_enabled = 0; + + if (OCTEON_CN23XX_PF(oct)) + oct->droq[0]->ops.poll_mode = 0; + } + + return ret; } /** @@ -1876,6 +1898,7 @@ struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; struct napi_struct *napi, *n; + int ret = 0; ifstate_reset(lio, LIO_IFSTATE_RUNNING); @@ -1892,7 +1915,9 @@ lio->link_changes++; /* Tell Octeon that nic interface is down. */ - send_rx_ctrl_cmd(lio, 0); + ret = send_rx_ctrl_cmd(lio, 0); + if (ret) + return ret; if (OCTEON_CN23XX_PF(oct)) { if (!oct->msix_on) @@ -1927,7 +1952,7 @@ dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); - return 0; + return ret; } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -598,7 +598,7 @@ * @param lio per-network private data * @param start_stop whether to start or stop */ -static void send_rx_ctrl_cmd(struct lio *lio, int start_stop) +static int send_rx_ctrl_cmd(struct lio *lio, int start_stop) { struct octeon_device *oct = (struct octeon_device *)lio->oct_dev; struct octeon_soft_command *sc; @@ -606,11 +606,16 @@ int retval; if (oct->props[lio->ifidx].rx_on == start_stop) - return; + return 0; sc = (struct octeon_soft_command *) octeon_alloc_soft_command(oct, OCTNET_CMD_SIZE, 16, 0); + if (!sc) { + netif_info(lio, rx_err, lio->netdev, + "Failed to allocate octeon_soft_command struct\n"); + return -ENOMEM; + } ncmd = (union octnet_cmd *)sc->virtdptr; @@ -638,11 +643,13 @@ */ retval = wait_for_sc_completion_timeout(oct, sc, 0); if (retval) - return; + return retval; oct->props[lio->ifidx].rx_on = start_stop; WRITE_ONCE(sc->caller_is_done, true); } + + return retval; } /** @@ -909,6 +916,7 @@ struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; struct napi_struct *napi, *n; + int ret = 0; if (!oct->props[lio->ifidx].napi_enabled) { tasklet_disable(&oct_priv->droq_tasklet); @@ -935,11 +943,13 @@ (LIQUIDIO_NDEV_STATS_POLL_TIME_MS)); /* tell Octeon to start forwarding packets to host */ - send_rx_ctrl_cmd(lio, 1); + ret = send_rx_ctrl_cmd(lio, 1); + if (ret) + return ret; dev_info(&oct->pci_dev->dev, "%s interface is opened\n", netdev->name); - return 0; + return ret; } /** @@ -953,9 +963,12 @@ struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; struct napi_struct *napi, *n; + int ret = 0; /* tell Octeon to stop forwarding packets to host */ - send_rx_ctrl_cmd(lio, 0); + ret = send_rx_ctrl_cmd(lio, 0); + if (ret) + return ret; netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n"); /* Inform that netif carrier is down */ @@ -989,7 +1002,7 @@ dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); - return 0; + return ret; } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c @@ -272,13 +272,12 @@ pg_info->page_offset; memcpy(skb->data, va, MIN_SKB_SIZE); skb_put(skb, MIN_SKB_SIZE); + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, + pg_info->page, + pg_info->page_offset + MIN_SKB_SIZE, + len - MIN_SKB_SIZE, + LIO_RXBUFFER_SZ); } - - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - pg_info->page, - pg_info->page_offset + MIN_SKB_SIZE, - len - MIN_SKB_SIZE, - LIO_RXBUFFER_SZ); } else { struct octeon_skb_page_info *pg_info = ((struct octeon_skb_page_info *)(skb->cb)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/octeon/octeon_mgmt.c @@ -235,6 +235,11 @@ /* Put it in the ring. */ p->rx_ring[p->rx_next_fill] = re.d64; + /* Make sure there is no reorder of filling the ring and ringing + * the bell + */ + wmb(); + dma_sync_single_for_device(p->dev, p->rx_ring_handle, ring_size_to_bytes(OCTEON_MGMT_RX_RING_SIZE), DMA_BIDIRECTIONAL); @@ -1217,7 +1222,7 @@ */ if (netdev->phydev) { netif_carrier_off(netdev); - phy_start_aneg(netdev->phydev); + phy_start(netdev->phydev); } netif_wake_queue(netdev); @@ -1245,8 +1250,10 @@ napi_disable(&p->napi); netif_stop_queue(netdev); - if (netdev->phydev) + if (netdev->phydev) { + phy_stop(netdev->phydev); phy_disconnect(netdev->phydev); + } netif_carrier_off(netdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/thunder/nic_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/thunder/nic_main.c @@ -1193,7 +1193,7 @@ dev_err(&nic->pdev->dev, "Request for #%d msix vectors failed, returned %d\n", nic->num_vec, ret); - return 1; + return ret; } /* Register mailbox interrupt handler */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -1226,7 +1226,7 @@ if (ret < 0) { netdev_err(nic->netdev, "Req for #%d msix vectors failed\n", nic->num_vec); - return 1; + return ret; } sprintf(nic->irq_name[irq], "%s Mbox", "NICVF"); @@ -1245,7 +1245,7 @@ if (!nicvf_check_pf_ready(nic)) { nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0); nicvf_unregister_interrupts(nic); - return 1; + return -EIO; } return 0; @@ -2047,11 +2047,11 @@ /* Save message data locally to prevent them from * being overwritten by next ndo_set_rx_mode call(). */ - spin_lock(&nic->rx_mode_wq_lock); + spin_lock_bh(&nic->rx_mode_wq_lock); mode = vf_work->mode; mc = vf_work->mc; vf_work->mc = NULL; - spin_unlock(&nic->rx_mode_wq_lock); + spin_unlock_bh(&nic->rx_mode_wq_lock); __nicvf_set_rx_mode_task(mode, mc, nic); } @@ -2185,6 +2185,9 @@ nic->max_queues *= 2; nic->ptp_clock = ptp_clock; + /* Initialize mutex that serializes usage of VF's mailbox */ + mutex_init(&nic->rx_mode_mtx); + /* MAP VF's configuration registers */ nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0); if (!nic->reg_base) { @@ -2261,12 +2264,11 @@ INIT_WORK(&nic->rx_mode_work.work, nicvf_set_rx_mode_task); spin_lock_init(&nic->rx_mode_wq_lock); - mutex_init(&nic->rx_mode_mtx); err = register_netdev(netdev); if (err) { dev_err(dev, "Failed to register netdevice\n"); - goto err_unregister_interrupts; + goto err_destroy_workqueue; } nic->msg_enable = debug; @@ -2275,6 +2277,8 @@ return 0; +err_destroy_workqueue: + destroy_workqueue(nic->nicvf_rx_mode_wq); err_unregister_interrupts: nicvf_unregister_interrupts(nic); err_free_netdev: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/thunder/nicvf_queues.c @@ -776,7 +776,7 @@ mbx.rq.msg = NIC_MBOX_MSG_RQ_CFG; mbx.rq.qs_num = qs->vnic_id; mbx.rq.rq_num = qidx; - mbx.rq.cfg = (rq->caching << 26) | (rq->cq_qs << 19) | + mbx.rq.cfg = ((u64)rq->caching << 26) | (rq->cq_qs << 19) | (rq->cq_idx << 16) | (rq->cont_rbdr_qs << 9) | (rq->cont_qs_rbdr_idx << 8) | (rq->start_rbdr_qs << 1) | (rq->start_qs_rbdr_idx); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/thunder/thunder_bgx.c @@ -410,10 +410,19 @@ lmac = &bgx->lmac[lmacid]; cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG); - if (enable) + if (enable) { cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN; - else + + /* enable TX FIFO Underflow interrupt */ + bgx_reg_modify(bgx, lmacid, BGX_GMP_GMI_TXX_INT_ENA_W1S, + GMI_TXX_INT_UNDFLW); + } else { cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN); + + /* Disable TX FIFO Underflow interrupt */ + bgx_reg_modify(bgx, lmacid, BGX_GMP_GMI_TXX_INT_ENA_W1C, + GMI_TXX_INT_UNDFLW); + } bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg); if (bgx->is_rgx) @@ -1115,7 +1124,7 @@ phy_interface_mode(lmac->lmac_type))) return -ENODEV; - phy_start_aneg(lmac->phydev); + phy_start(lmac->phydev); return 0; } @@ -1429,8 +1438,10 @@ return AE_OK; } - if (strncmp(string.pointer, bgx_sel, 4)) + if (strncmp(string.pointer, bgx_sel, 4)) { + kfree(string.pointer); return AE_OK; + } acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, bgx_acpi_register_phy, NULL, bgx, NULL); @@ -1535,6 +1546,48 @@ return bgx_init_of_phy(bgx); } +static irqreturn_t bgx_intr_handler(int irq, void *data) +{ + struct bgx *bgx = (struct bgx *)data; + u64 status, val; + int lmac; + + for (lmac = 0; lmac < bgx->lmac_count; lmac++) { + status = bgx_reg_read(bgx, lmac, BGX_GMP_GMI_TXX_INT); + if (status & GMI_TXX_INT_UNDFLW) { + pci_err(bgx->pdev, "BGX%d lmac%d UNDFLW\n", + bgx->bgx_id, lmac); + val = bgx_reg_read(bgx, lmac, BGX_CMRX_CFG); + val &= ~CMR_EN; + bgx_reg_write(bgx, lmac, BGX_CMRX_CFG, val); + val |= CMR_EN; + bgx_reg_write(bgx, lmac, BGX_CMRX_CFG, val); + } + /* clear interrupts */ + bgx_reg_write(bgx, lmac, BGX_GMP_GMI_TXX_INT, status); + } + + return IRQ_HANDLED; +} + +static void bgx_register_intr(struct pci_dev *pdev) +{ + struct bgx *bgx = pci_get_drvdata(pdev); + int ret; + + ret = pci_alloc_irq_vectors(pdev, BGX_LMAC_VEC_OFFSET, + BGX_LMAC_VEC_OFFSET, PCI_IRQ_ALL_TYPES); + if (ret < 0) { + pci_err(pdev, "Req for #%d msix vectors failed\n", + BGX_LMAC_VEC_OFFSET); + return; + } + ret = pci_request_irq(pdev, GMPX_GMI_TX_INT, bgx_intr_handler, NULL, + bgx, "BGX%d", bgx->bgx_id); + if (ret) + pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); +} + static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err; @@ -1550,7 +1603,7 @@ pci_set_drvdata(pdev, bgx); - err = pci_enable_device(pdev); + err = pcim_enable_device(pdev); if (err) { dev_err(dev, "Failed to enable PCI device\n"); pci_set_drvdata(pdev, NULL); @@ -1604,6 +1657,8 @@ bgx_init_hw(bgx); + bgx_register_intr(pdev); + /* Enable all LMACs */ for (lmac = 0; lmac < bgx->lmac_count; lmac++) { err = bgx_lmac_enable(bgx, lmac); @@ -1620,6 +1675,7 @@ err_enable: bgx_vnic[bgx->bgx_id] = NULL; + pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); err_release_regions: pci_release_regions(pdev); err_disable_device: @@ -1637,6 +1693,8 @@ for (lmac = 0; lmac < bgx->lmac_count; lmac++) bgx_lmac_disable(bgx, lmac); + pci_free_irq(pdev, GMPX_GMI_TX_INT, bgx); + bgx_vnic[bgx->bgx_id] = NULL; pci_release_regions(pdev); pci_disable_device(pdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cavium/thunder/thunder_bgx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cavium/thunder/thunder_bgx.h @@ -180,6 +180,15 @@ #define BGX_GMP_GMI_TXX_BURST 0x38228 #define BGX_GMP_GMI_TXX_MIN_PKT 0x38240 #define BGX_GMP_GMI_TXX_SGMII_CTL 0x38300 +#define BGX_GMP_GMI_TXX_INT 0x38500 +#define BGX_GMP_GMI_TXX_INT_W1S 0x38508 +#define BGX_GMP_GMI_TXX_INT_ENA_W1C 0x38510 +#define BGX_GMP_GMI_TXX_INT_ENA_W1S 0x38518 +#define GMI_TXX_INT_PTP_LOST BIT_ULL(4) +#define GMI_TXX_INT_LATE_COL BIT_ULL(3) +#define GMI_TXX_INT_XSDEF BIT_ULL(2) +#define GMI_TXX_INT_XSCOL BIT_ULL(1) +#define GMI_TXX_INT_UNDFLW BIT_ULL(0) #define BGX_MSIX_VEC_0_29_ADDR 0x400000 /* +(0..29) << 4 */ #define BGX_MSIX_VEC_0_29_CTL 0x400008 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb/cxgb2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb/cxgb2.c @@ -1153,6 +1153,7 @@ if (!adapter->registered_device_map) { pr_err("%s: could not register any net devices\n", pci_name(pdev)); + err = -EINVAL; goto out_release_adapter_res; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -1303,6 +1303,7 @@ if (ret < 0) { CH_ERR(adap, "failed to bind qsets, err %d\n", ret); t3_intr_disable(adap); + quiesce_rx(adap); free_irq_resources(adap); err = ret; goto out; @@ -2448,6 +2449,8 @@ if (!is_offload(adapter)) return -EOPNOTSUPP; + if (!capable(CAP_NET_ADMIN)) + return -EPERM; if (!(adapter->flags & FULL_INIT_DONE)) return -EIO; /* need the memory controllers */ if (copy_from_user(&t, useraddr, sizeof(t))) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb3/sge.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb3/sge.c @@ -3176,6 +3176,7 @@ GFP_KERNEL | __GFP_COMP); if (!avail) { CH_ALERT(adapter, "free list queue 0 initialization failed\n"); + ret = -ENOMEM; goto err; } if (avail < q->fl[0].size) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c @@ -3677,6 +3677,8 @@ MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10); adapter->params.pci.vpd_cap_addr = pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD); + if (!adapter->params.pci.vpd_cap_addr) + return -ENODEV; ret = get_vpd_params(adapter, &adapter->params.vpd); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c @@ -1054,9 +1054,9 @@ } } -static unsigned long cudbg_mem_region_size(struct cudbg_init *pdbg_init, - struct cudbg_error *cudbg_err, - u8 mem_type) +static int cudbg_mem_region_size(struct cudbg_init *pdbg_init, + struct cudbg_error *cudbg_err, + u8 mem_type, unsigned long *region_size) { struct adapter *padap = pdbg_init->adap; struct cudbg_meminfo mem_info; @@ -1065,15 +1065,23 @@ memset(&mem_info, 0, sizeof(struct cudbg_meminfo)); rc = cudbg_fill_meminfo(padap, &mem_info); - if (rc) + if (rc) { + cudbg_err->sys_err = rc; return rc; + } cudbg_t4_fwcache(pdbg_init, cudbg_err); rc = cudbg_meminfo_get_mem_index(padap, &mem_info, mem_type, &mc_idx); - if (rc) + if (rc) { + cudbg_err->sys_err = rc; return rc; + } + + if (region_size) + *region_size = mem_info.avail[mc_idx].limit - + mem_info.avail[mc_idx].base; - return mem_info.avail[mc_idx].limit - mem_info.avail[mc_idx].base; + return 0; } static int cudbg_collect_mem_region(struct cudbg_init *pdbg_init, @@ -1081,7 +1089,12 @@ struct cudbg_error *cudbg_err, u8 mem_type) { - unsigned long size = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type); + unsigned long size = 0; + int rc; + + rc = cudbg_mem_region_size(pdbg_init, cudbg_err, mem_type, &size); + if (rc) + return rc; return cudbg_read_fw_mem(pdbg_init, dbg_buff, mem_type, size, cudbg_err); @@ -1380,11 +1393,25 @@ struct cudbg_buffer temp_buff = { 0 }; struct sge_qbase_reg_field *sge_qbase; struct ireg_buf *ch_sge_dbg; + u8 padap_running = 0; int i, rc; + u32 size; - rc = cudbg_get_buff(pdbg_init, dbg_buff, - sizeof(*ch_sge_dbg) * 2 + sizeof(*sge_qbase), - &temp_buff); + /* Accessing SGE_QBASE_MAP[0-3] and SGE_QBASE_INDEX regs can + * lead to SGE missing doorbells under heavy traffic. So, only + * collect them when adapter is idle. + */ + for_each_port(padap, i) { + padap_running = netif_running(padap->port[i]); + if (padap_running) + break; + } + + size = sizeof(*ch_sge_dbg) * 2; + if (!padap_running) + size += sizeof(*sge_qbase); + + rc = cudbg_get_buff(pdbg_init, dbg_buff, size, &temp_buff); if (rc) return rc; @@ -1406,7 +1433,8 @@ ch_sge_dbg++; } - if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5) { + if (CHELSIO_CHIP_VERSION(padap->params.chip) > CHELSIO_T5 && + !padap_running) { sge_qbase = (struct sge_qbase_reg_field *)ch_sge_dbg; /* 1 addr reg SGE_QBASE_INDEX and 4 data reg * SGE_QBASE_MAP[0-3] @@ -1967,7 +1995,6 @@ u8 mem_type[CTXT_INGRESS + 1] = { 0 }; struct cudbg_buffer temp_buff = { 0 }; struct cudbg_ch_cntxt *buff; - u64 *dst_off, *src_off; u8 *ctx_buf; u8 i, k; int rc; @@ -2036,8 +2063,11 @@ } for (j = 0; j < max_ctx_qid; j++) { + __be64 *dst_off; + u64 *src_off; + src_off = (u64 *)(ctx_buf + j * SGE_CTXT_SIZE); - dst_off = (u64 *)buff->data; + dst_off = (__be64 *)buff->data; /* The data is stored in 64-bit cpu order. Convert it * to big endian before parsing. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h @@ -503,6 +503,7 @@ enum cc_pause requested_fc; /* flow control user has requested */ enum cc_pause fc; /* actual link flow control */ + enum cc_pause advertised_fc; /* actual advertised flow control */ enum cc_fec requested_fec; /* Forward Error Correction: */ enum cc_fec fec; /* requested and actual in use */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -70,8 +70,7 @@ static void *seq_tab_next(struct seq_file *seq, void *v, loff_t *pos) { v = seq_tab_get_idx(seq->private, *pos + 1); - if (v) - ++*pos; + ++(*pos); return v; } @@ -2691,7 +2690,7 @@ seq_printf(seq, "%-12s", s); \ for (i = 0; i < n; ++i) \ seq_printf(seq, " %16" fmt_spec, v); \ - seq_putc(seq, '\n'); \ + seq_putc(seq, '\n'); \ } while (0) #define S(s, v) S3("s", s, v) #define T3(fmt_spec, s, v) S3(fmt_spec, s, tx[i].v) @@ -2996,6 +2995,9 @@ int tot_uld_entries = 0; int i; + if (!is_uld(adap)) + goto lld_only; + mutex_lock(&uld_mutex); for (i = 0; i < CXGB4_TX_MAX; i++) tot_uld_entries += sge_qinfo_uld_txq_entries(adap, i); @@ -3006,6 +3008,7 @@ } mutex_unlock(&uld_mutex); +lld_only: return DIV_ROUND_UP(adap->sge.ethqsets, 4) + tot_uld_entries + DIV_ROUND_UP(MAX_CTRL_QUEUES, 4) + 1; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c @@ -793,8 +793,8 @@ struct port_info *p = netdev_priv(dev); epause->autoneg = (p->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; - epause->rx_pause = (p->link_cfg.fc & PAUSE_RX) != 0; - epause->tx_pause = (p->link_cfg.fc & PAUSE_TX) != 0; + epause->rx_pause = (p->link_cfg.advertised_fc & PAUSE_RX) != 0; + epause->tx_pause = (p->link_cfg.advertised_fc & PAUSE_TX) != 0; } static int set_pauseparam(struct net_device *dev, @@ -1466,12 +1466,15 @@ if (ret) return ret; - if (!sff8472_comp || (sff_diag_type & 4)) { + if (!sff8472_comp || (sff_diag_type & SFP_DIAG_ADDRMODE)) { modinfo->type = ETH_MODULE_SFF_8079; modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; } else { modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + if (sff_diag_type & SFP_DIAG_IMPLEMENTED) + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; + else + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2; } break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c @@ -145,13 +145,13 @@ int err; /* do a set-tcb for smac-sel and CWR bit.. */ - err = set_tcb_tflag(adap, f, f->tid, TF_CCTRL_CWR_S, 1, 1); - if (err) - goto smac_err; - err = set_tcb_field(adap, f, f->tid, TCB_SMAC_SEL_W, TCB_SMAC_SEL_V(TCB_SMAC_SEL_M), TCB_SMAC_SEL_V(f->smt->idx), 1); + if (err) + goto smac_err; + + err = set_tcb_tflag(adap, f, f->tid, TF_CCTRL_CWR_S, 1, 1); if (!err) return 0; @@ -165,37 +165,40 @@ unsigned int tid, bool dip, bool sip, bool dp, bool sp) { + u8 *nat_lp = (u8 *)&f->fs.nat_lport; + u8 *nat_fp = (u8 *)&f->fs.nat_fport; + if (dip) { if (f->fs.type) { set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W, WORD_MASK, f->fs.nat_lip[15] | f->fs.nat_lip[14] << 8 | f->fs.nat_lip[13] << 16 | - f->fs.nat_lip[12] << 24, 1); + (u64)f->fs.nat_lip[12] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 1, WORD_MASK, f->fs.nat_lip[11] | f->fs.nat_lip[10] << 8 | f->fs.nat_lip[9] << 16 | - f->fs.nat_lip[8] << 24, 1); + (u64)f->fs.nat_lip[8] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 2, WORD_MASK, f->fs.nat_lip[7] | f->fs.nat_lip[6] << 8 | f->fs.nat_lip[5] << 16 | - f->fs.nat_lip[4] << 24, 1); + (u64)f->fs.nat_lip[4] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 3, WORD_MASK, f->fs.nat_lip[3] | f->fs.nat_lip[2] << 8 | f->fs.nat_lip[1] << 16 | - f->fs.nat_lip[0] << 24, 1); + (u64)f->fs.nat_lip[0] << 24, 1); } else { set_tcb_field(adap, f, tid, TCB_RX_FRAG3_LEN_RAW_W, WORD_MASK, f->fs.nat_lip[3] | f->fs.nat_lip[2] << 8 | f->fs.nat_lip[1] << 16 | - f->fs.nat_lip[0] << 24, 1); + (u64)f->fs.nat_lip[0] << 24, 1); } } @@ -205,25 +208,25 @@ WORD_MASK, f->fs.nat_fip[15] | f->fs.nat_fip[14] << 8 | f->fs.nat_fip[13] << 16 | - f->fs.nat_fip[12] << 24, 1); + (u64)f->fs.nat_fip[12] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 1, WORD_MASK, f->fs.nat_fip[11] | f->fs.nat_fip[10] << 8 | f->fs.nat_fip[9] << 16 | - f->fs.nat_fip[8] << 24, 1); + (u64)f->fs.nat_fip[8] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 2, WORD_MASK, f->fs.nat_fip[7] | f->fs.nat_fip[6] << 8 | f->fs.nat_fip[5] << 16 | - f->fs.nat_fip[4] << 24, 1); + (u64)f->fs.nat_fip[4] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 3, WORD_MASK, f->fs.nat_fip[3] | f->fs.nat_fip[2] << 8 | f->fs.nat_fip[1] << 16 | - f->fs.nat_fip[0] << 24, 1); + (u64)f->fs.nat_fip[0] << 24, 1); } else { set_tcb_field(adap, f, tid, @@ -231,13 +234,14 @@ WORD_MASK, f->fs.nat_fip[3] | f->fs.nat_fip[2] << 8 | f->fs.nat_fip[1] << 16 | - f->fs.nat_fip[0] << 24, 1); + (u64)f->fs.nat_fip[0] << 24, 1); } } set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK, - (dp ? f->fs.nat_lport : 0) | - (sp ? f->fs.nat_fport << 16 : 0), 1); + (dp ? (nat_lp[1] | nat_lp[0] << 8) : 0) | + (sp ? (nat_fp[1] << 16 | (u64)nat_fp[0] << 24) : 0), + 1); } /* Validate filter spec against configuration done on the card. */ @@ -608,6 +612,7 @@ FW_FILTER_WR_DIRSTEERHASH_V(f->fs.dirsteerhash) | FW_FILTER_WR_LPBK_V(f->fs.action == FILTER_SWITCH) | FW_FILTER_WR_DMAC_V(f->fs.newdmac) | + FW_FILTER_WR_SMAC_V(f->fs.newsmac) | FW_FILTER_WR_INSVLAN_V(f->fs.newvlan == VLAN_INSERT || f->fs.newvlan == VLAN_REWRITE) | FW_FILTER_WR_RMVLAN_V(f->fs.newvlan == VLAN_REMOVE || @@ -625,7 +630,8 @@ FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) | FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) | FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld)); - fwr->smac_sel = 0; + if (f->fs.newsmac) + fwr->smac_sel = f->smt->idx; fwr->rx_chan_rx_rpl_iq = htons(FW_FILTER_WR_RX_CHAN_V(0) | FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id)); @@ -656,6 +662,9 @@ fwr->fpm = htons(f->fs.mask.fport); if (adapter->params.filter2_wr_support) { + u8 *nat_lp = (u8 *)&f->fs.nat_lport; + u8 *nat_fp = (u8 *)&f->fs.nat_fport; + fwr->natmode_to_ulp_type = FW_FILTER2_WR_ULP_TYPE_V(f->fs.nat_mode ? ULP_MODE_TCPDDP : @@ -663,8 +672,8 @@ FW_FILTER2_WR_NATMODE_V(f->fs.nat_mode); memcpy(fwr->newlip, f->fs.nat_lip, sizeof(fwr->newlip)); memcpy(fwr->newfip, f->fs.nat_fip, sizeof(fwr->newfip)); - fwr->newlport = htons(f->fs.nat_lport); - fwr->newfport = htons(f->fs.nat_fport); + fwr->newlport = htons(nat_lp[1] | nat_lp[0] << 8); + fwr->newfport = htons(nat_fp[1] | nat_fp[0] << 8); } /* Mark the filter as "pending" and ship off the Filter Work Request. @@ -769,7 +778,7 @@ cxgb4_del_filter(dev, i, &f->fs); } - sb = t4_read_reg(adapter, LE_DB_SRVR_START_INDEX_A); + sb = adapter->tids.stid_base; for (i = 0; i < sb; i++) { f = (struct filter_entry *)adapter->tids.tid_tab[i]; @@ -832,16 +841,16 @@ struct in_addr *addr; addr = (struct in_addr *)ipmask; - if (addr->s_addr == 0xffffffff) + if (addr->s_addr == htonl(0xffffffff)) return true; } else if (family == AF_INET6) { struct in6_addr *addr6; addr6 = (struct in6_addr *)ipmask; - if (addr6->s6_addr32[0] == 0xffffffff && - addr6->s6_addr32[1] == 0xffffffff && - addr6->s6_addr32[2] == 0xffffffff && - addr6->s6_addr32[3] == 0xffffffff) + if (addr6->s6_addr32[0] == htonl(0xffffffff) && + addr6->s6_addr32[1] == htonl(0xffffffff) && + addr6->s6_addr32[2] == htonl(0xffffffff) && + addr6->s6_addr32[3] == htonl(0xffffffff)) return true; } return false; @@ -960,7 +969,8 @@ * in the Compressed Filter Tuple. */ if (tp->vlan_shift >= 0 && fs->mask.ivlan) - ntuple |= (FT_VLAN_VLD_F | fs->val.ivlan) << tp->vlan_shift; + ntuple |= (u64)(FT_VLAN_VLD_F | + fs->val.ivlan) << tp->vlan_shift; if (tp->port_shift >= 0 && fs->mask.iport) ntuple |= (u64)fs->val.iport << tp->port_shift; @@ -1041,11 +1051,8 @@ TX_QUEUE_V(f->fs.nat_mode) | T5_OPT_2_VALID_F | RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) | - CONG_CNTRL_V((f->fs.action == FILTER_DROP) | - (f->fs.dirsteer << 1)) | PACE_V((f->fs.maskhash) | - ((f->fs.dirsteerhash) << 1)) | - CCTRL_ECN_V(f->fs.action == FILTER_SWITCH)); + ((f->fs.dirsteerhash) << 1))); } static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb, @@ -1081,11 +1088,8 @@ TX_QUEUE_V(f->fs.nat_mode) | T5_OPT_2_VALID_F | RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) | - CONG_CNTRL_V((f->fs.action == FILTER_DROP) | - (f->fs.dirsteer << 1)) | PACE_V((f->fs.maskhash) | - ((f->fs.dirsteerhash) << 1)) | - CCTRL_ECN_V(f->fs.action == FILTER_SWITCH)); + ((f->fs.dirsteerhash) << 1))); } static int cxgb4_set_hash_filter(struct net_device *dev, @@ -1610,13 +1614,16 @@ static int configure_filter_tcb(struct adapter *adap, unsigned int tid, struct filter_entry *f) { - if (f->fs.hitcnts) + if (f->fs.hitcnts) { set_tcb_field(adap, f, tid, TCB_TIMESTAMP_W, - TCB_TIMESTAMP_V(TCB_TIMESTAMP_M) | + TCB_TIMESTAMP_V(TCB_TIMESTAMP_M), + TCB_TIMESTAMP_V(0ULL), + 1); + set_tcb_field(adap, f, tid, TCB_RTT_TS_RECENT_AGE_W, TCB_RTT_TS_RECENT_AGE_V(TCB_RTT_TS_RECENT_AGE_M), - TCB_TIMESTAMP_V(0ULL) | TCB_RTT_TS_RECENT_AGE_V(0ULL), 1); + } if (f->fs.newdmac) set_tcb_tflag(adap, f, tid, TF_CCTRL_ECE_S, 1, @@ -1738,6 +1745,20 @@ } return; } + switch (f->fs.action) { + case FILTER_PASS: + if (f->fs.dirsteer) + set_tcb_tflag(adap, f, tid, + TF_DIRECT_STEER_S, 1, 1); + break; + case FILTER_DROP: + set_tcb_tflag(adap, f, tid, TF_DROP_S, 1, 1); + break; + case FILTER_SWITCH: + set_tcb_tflag(adap, f, tid, TF_LPBK_S, 1, 1); + break; + } + break; default: @@ -1798,22 +1819,11 @@ if (ctx) ctx->result = 0; } else if (ret == FW_FILTER_WR_FLT_ADDED) { - int err = 0; - - if (f->fs.newsmac) - err = configure_filter_smac(adap, f); - - if (!err) { - f->pending = 0; /* async setup completed */ - f->valid = 1; - if (ctx) { - ctx->result = 0; - ctx->tid = idx; - } - } else { - clear_filter(adap, f); - if (ctx) - ctx->result = err; + f->pending = 0; /* async setup completed */ + f->valid = 1; + if (ctx) { + ctx->result = 0; + ctx->tid = idx; } } else { /* Something went wrong. Issue a warning about the --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2245,6 +2245,9 @@ { unsigned int i; + if (!is_uld(adap)) + return; + mutex_lock(&uld_mutex); list_del(&adap->list_node); @@ -2504,7 +2507,7 @@ /* Clear out filter specifications */ memset(&f->fs, 0, sizeof(struct ch_filter_specification)); - f->fs.val.lport = cpu_to_be16(sport); + f->fs.val.lport = be16_to_cpu(sport); f->fs.mask.lport = ~0; val = (u8 *)&sip; if ((val[0] | val[1] | val[2] | val[3]) != 0) { @@ -3032,7 +3035,6 @@ return ret; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - pi->xact_addr_filt = ret; return 0; } @@ -6153,10 +6155,13 @@ */ destroy_workqueue(adapter->workq); - if (is_uld(adapter)) { - detach_ulds(adapter); - t4_uld_clean_up(adapter); - } + detach_ulds(adapter); + + for_each_port(adapter, i) + if (adapter->port[i]->reg_state == NETREG_REGISTERED) + unregister_netdev(adapter->port[i]); + + t4_uld_clean_up(adapter); adap_free_hma_mem(adapter); @@ -6164,10 +6169,6 @@ cxgb4_free_mps_ref_entries(adapter); - for_each_port(adapter, i) - if (adapter->port[i]->reg_state == NETREG_REGISTERED) - unregister_netdev(adapter->port[i]); - debugfs_remove_recursive(adapter->debugfs_root); if (!is_t4(adapter->params.chip)) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c @@ -229,7 +229,7 @@ { struct mps_entries_ref *mps_entry, *tmp; - if (!list_empty(&adap->mps_ref)) + if (list_empty(&adap->mps_ref)) return; spin_lock(&adap->mps_ref_lock); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c @@ -246,6 +246,9 @@ FW_PTP_CMD_PORTID_V(0)); c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16)); c.u.ts.sc = FW_PTP_SC_ADJ_FTIME; + c.u.ts.sign = (delta < 0) ? 1 : 0; + if (delta < 0) + delta = -delta; c.u.ts.tm = cpu_to_be64(delta); err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), NULL); @@ -308,32 +311,17 @@ */ static int cxgb4_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { - struct adapter *adapter = (struct adapter *)container_of(ptp, - struct adapter, ptp_clock_info); - struct fw_ptp_cmd c; + struct adapter *adapter = container_of(ptp, struct adapter, + ptp_clock_info); u64 ns; - int err; - memset(&c, 0, sizeof(c)); - c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PTP_CMD) | - FW_CMD_REQUEST_F | - FW_CMD_READ_F | - FW_PTP_CMD_PORTID_V(0)); - c.retval_len16 = cpu_to_be32(FW_CMD_LEN16_V(sizeof(c) / 16)); - c.u.ts.sc = FW_PTP_SC_GET_TIME; - - err = t4_wr_mbox(adapter, adapter->mbox, &c, sizeof(c), &c); - if (err < 0) { - dev_err(adapter->pdev_dev, - "PTP: %s error %d\n", __func__, -err); - return err; - } + ns = t4_read_reg(adapter, T5_PORT_REG(0, MAC_PORT_PTP_SUM_LO_A)); + ns |= (u64)t4_read_reg(adapter, + T5_PORT_REG(0, MAC_PORT_PTP_SUM_HI_A)) << 32; /* convert to timespec*/ - ns = be64_to_cpu(c.u.ts.tm); *ts = ns_to_timespec64(ns); - - return err; + return 0; } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c @@ -58,12 +58,91 @@ PEDIT_FIELDS(IP6_, DST_63_32, 4, nat_lip, 4), PEDIT_FIELDS(IP6_, DST_95_64, 4, nat_lip, 8), PEDIT_FIELDS(IP6_, DST_127_96, 4, nat_lip, 12), - PEDIT_FIELDS(TCP_, SPORT, 2, nat_fport, 0), - PEDIT_FIELDS(TCP_, DPORT, 2, nat_lport, 0), - PEDIT_FIELDS(UDP_, SPORT, 2, nat_fport, 0), - PEDIT_FIELDS(UDP_, DPORT, 2, nat_lport, 0), }; +static const struct cxgb4_natmode_config cxgb4_natmode_config_array[] = { + /* Default supported NAT modes */ + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_NONE, + .natmode = NAT_MODE_NONE, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP, + .natmode = NAT_MODE_DIP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_DPORT, + .natmode = NAT_MODE_DIP_DP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_DPORT | + CXGB4_ACTION_NATMODE_SIP, + .natmode = NAT_MODE_DIP_DP_SIP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_DPORT | + CXGB4_ACTION_NATMODE_SPORT, + .natmode = NAT_MODE_DIP_DP_SP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_SIP | CXGB4_ACTION_NATMODE_SPORT, + .natmode = NAT_MODE_SIP_SP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_SIP | + CXGB4_ACTION_NATMODE_SPORT, + .natmode = NAT_MODE_DIP_SIP_SP, + }, + { + .chip = CHELSIO_T5, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_SIP | + CXGB4_ACTION_NATMODE_DPORT | + CXGB4_ACTION_NATMODE_SPORT, + .natmode = NAT_MODE_ALL, + }, + /* T6+ can ignore L4 ports when they're disabled. */ + { + .chip = CHELSIO_T6, + .flags = CXGB4_ACTION_NATMODE_SIP, + .natmode = NAT_MODE_SIP_SP, + }, + { + .chip = CHELSIO_T6, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_SPORT, + .natmode = NAT_MODE_DIP_DP_SP, + }, + { + .chip = CHELSIO_T6, + .flags = CXGB4_ACTION_NATMODE_DIP | CXGB4_ACTION_NATMODE_SIP, + .natmode = NAT_MODE_ALL, + }, +}; + +static void cxgb4_action_natmode_tweak(struct ch_filter_specification *fs, + u8 natmode_flags) +{ + u8 i = 0; + + /* Translate the enabled NAT 4-tuple fields to one of the + * hardware supported NAT mode configurations. This ensures + * that we pick a valid combination, where the disabled fields + * do not get overwritten to 0. + */ + for (i = 0; i < ARRAY_SIZE(cxgb4_natmode_config_array); i++) { + if (cxgb4_natmode_config_array[i].flags == natmode_flags) { + fs->nat_mode = cxgb4_natmode_config_array[i].natmode; + return; + } + } +} + static struct ch_tc_flower_entry *allocate_flower_entry(void) { struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL); @@ -156,14 +235,14 @@ struct flow_match_ports match; flow_rule_match_ports(rule, &match); - fs->val.lport = cpu_to_be16(match.key->dst); - fs->mask.lport = cpu_to_be16(match.mask->dst); - fs->val.fport = cpu_to_be16(match.key->src); - fs->mask.fport = cpu_to_be16(match.mask->src); + fs->val.lport = be16_to_cpu(match.key->dst); + fs->mask.lport = be16_to_cpu(match.mask->dst); + fs->val.fport = be16_to_cpu(match.key->src); + fs->mask.fport = be16_to_cpu(match.mask->src); /* also initialize nat_lport/fport to same values */ - fs->nat_lport = cpu_to_be16(match.key->dst); - fs->nat_fport = cpu_to_be16(match.key->src); + fs->nat_lport = fs->val.lport; + fs->nat_fport = fs->val.fport; } if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { @@ -291,7 +370,8 @@ } static void process_pedit_field(struct ch_filter_specification *fs, u32 val, - u32 mask, u32 offset, u8 htype) + u32 mask, u32 offset, u8 htype, + u8 *natmode_flags) { switch (htype) { case FLOW_ACT_MANGLE_HDR_TYPE_ETH: @@ -316,74 +396,104 @@ switch (offset) { case PEDIT_IP4_SRC: offload_pedit(fs, val, mask, IP4_SRC); + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; break; case PEDIT_IP4_DST: offload_pedit(fs, val, mask, IP4_DST); + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; } - fs->nat_mode = NAT_MODE_ALL; break; case FLOW_ACT_MANGLE_HDR_TYPE_IP6: switch (offset) { case PEDIT_IP6_SRC_31_0: offload_pedit(fs, val, mask, IP6_SRC_31_0); + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; break; case PEDIT_IP6_SRC_63_32: offload_pedit(fs, val, mask, IP6_SRC_63_32); + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; break; case PEDIT_IP6_SRC_95_64: offload_pedit(fs, val, mask, IP6_SRC_95_64); + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; break; case PEDIT_IP6_SRC_127_96: offload_pedit(fs, val, mask, IP6_SRC_127_96); + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; break; case PEDIT_IP6_DST_31_0: offload_pedit(fs, val, mask, IP6_DST_31_0); + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; break; case PEDIT_IP6_DST_63_32: offload_pedit(fs, val, mask, IP6_DST_63_32); + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; break; case PEDIT_IP6_DST_95_64: offload_pedit(fs, val, mask, IP6_DST_95_64); + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; break; case PEDIT_IP6_DST_127_96: offload_pedit(fs, val, mask, IP6_DST_127_96); + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; } - fs->nat_mode = NAT_MODE_ALL; break; case FLOW_ACT_MANGLE_HDR_TYPE_TCP: switch (offset) { case PEDIT_TCP_SPORT_DPORT: - if (~mask & PEDIT_TCP_UDP_SPORT_MASK) - offload_pedit(fs, cpu_to_be32(val) >> 16, - cpu_to_be32(mask) >> 16, - TCP_SPORT); - else - offload_pedit(fs, cpu_to_be32(val), - cpu_to_be32(mask), TCP_DPORT); + if (~mask & PEDIT_TCP_UDP_SPORT_MASK) { + fs->nat_fport = val; + *natmode_flags |= CXGB4_ACTION_NATMODE_SPORT; + } else { + fs->nat_lport = val >> 16; + *natmode_flags |= CXGB4_ACTION_NATMODE_DPORT; + } } - fs->nat_mode = NAT_MODE_ALL; break; case FLOW_ACT_MANGLE_HDR_TYPE_UDP: switch (offset) { case PEDIT_UDP_SPORT_DPORT: - if (~mask & PEDIT_TCP_UDP_SPORT_MASK) - offload_pedit(fs, cpu_to_be32(val) >> 16, - cpu_to_be32(mask) >> 16, - UDP_SPORT); - else - offload_pedit(fs, cpu_to_be32(val), - cpu_to_be32(mask), UDP_DPORT); + if (~mask & PEDIT_TCP_UDP_SPORT_MASK) { + fs->nat_fport = val; + *natmode_flags |= CXGB4_ACTION_NATMODE_SPORT; + } else { + fs->nat_lport = val >> 16; + *natmode_flags |= CXGB4_ACTION_NATMODE_DPORT; + } } - fs->nat_mode = NAT_MODE_ALL; + break; } } +static int cxgb4_action_natmode_validate(struct net_device *dev, + struct adapter *adap, u8 natmode_flags) +{ + u8 i = 0; + + /* Extract the NAT mode to enable based on what 4-tuple fields + * are enabled to be overwritten. This ensures that the + * disabled fields don't get overwritten to 0. + */ + for (i = 0; i < ARRAY_SIZE(cxgb4_natmode_config_array); i++) { + const struct cxgb4_natmode_config *c; + + c = &cxgb4_natmode_config_array[i]; + if (CHELSIO_CHIP_VERSION(adap->params.chip) >= c->chip && + natmode_flags == c->flags) + return 0; + } + netdev_err(dev, "%s: Unsupported NAT mode 4-tuple combination\n", + __func__); + return -EOPNOTSUPP; +} + static void cxgb4_process_flow_actions(struct net_device *in, struct flow_cls_offload *cls, struct ch_filter_specification *fs) { struct flow_rule *rule = flow_cls_offload_flow_rule(cls); struct flow_action_entry *act; + u8 natmode_flags = 0; int i; flow_action_for_each(i, act, &rule->action) { @@ -434,13 +544,17 @@ val = act->mangle.val; offset = act->mangle.offset; - process_pedit_field(fs, val, mask, offset, htype); + process_pedit_field(fs, val, mask, offset, htype, + &natmode_flags); } break; default: break; } } + if (natmode_flags) + cxgb4_action_natmode_tweak(fs, natmode_flags); + } static bool valid_l4_mask(u32 mask) @@ -457,7 +571,8 @@ } static bool valid_pedit_action(struct net_device *dev, - const struct flow_action_entry *act) + const struct flow_action_entry *act, + u8 *natmode_flags) { u32 mask, offset; u8 htype; @@ -482,7 +597,10 @@ case FLOW_ACT_MANGLE_HDR_TYPE_IP4: switch (offset) { case PEDIT_IP4_SRC: + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; + break; case PEDIT_IP4_DST: + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; break; default: netdev_err(dev, "%s: Unsupported pedit field\n", @@ -496,10 +614,13 @@ case PEDIT_IP6_SRC_63_32: case PEDIT_IP6_SRC_95_64: case PEDIT_IP6_SRC_127_96: + *natmode_flags |= CXGB4_ACTION_NATMODE_SIP; + break; case PEDIT_IP6_DST_31_0: case PEDIT_IP6_DST_63_32: case PEDIT_IP6_DST_95_64: case PEDIT_IP6_DST_127_96: + *natmode_flags |= CXGB4_ACTION_NATMODE_DIP; break; default: netdev_err(dev, "%s: Unsupported pedit field\n", @@ -515,6 +636,10 @@ __func__); return false; } + if (~mask & PEDIT_TCP_UDP_SPORT_MASK) + *natmode_flags |= CXGB4_ACTION_NATMODE_SPORT; + else + *natmode_flags |= CXGB4_ACTION_NATMODE_DPORT; break; default: netdev_err(dev, "%s: Unsupported pedit field\n", @@ -530,6 +655,10 @@ __func__); return false; } + if (~mask & PEDIT_TCP_UDP_SPORT_MASK) + *natmode_flags |= CXGB4_ACTION_NATMODE_SPORT; + else + *natmode_flags |= CXGB4_ACTION_NATMODE_DPORT; break; default: netdev_err(dev, "%s: Unsupported pedit field\n", @@ -548,10 +677,12 @@ struct flow_cls_offload *cls) { struct flow_rule *rule = flow_cls_offload_flow_rule(cls); + struct adapter *adap = netdev2adap(dev); struct flow_action_entry *act; bool act_redir = false; bool act_pedit = false; bool act_vlan = false; + u8 natmode_flags = 0; int i; flow_action_for_each(i, act, &rule->action) { @@ -561,7 +692,6 @@ /* Do nothing */ break; case FLOW_ACTION_REDIRECT: { - struct adapter *adap = netdev2adap(dev); struct net_device *n_dev, *target_dev; unsigned int i; bool found = false; @@ -611,7 +741,8 @@ } break; case FLOW_ACTION_MANGLE: { - bool pedit_valid = valid_pedit_action(dev, act); + bool pedit_valid = valid_pedit_action(dev, act, + &natmode_flags); if (!pedit_valid) return -EOPNOTSUPP; @@ -630,6 +761,14 @@ return -EINVAL; } + if (act_pedit) { + int ret; + + ret = cxgb4_action_natmode_validate(dev, adap, natmode_flags); + if (ret) + return ret; + } + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h @@ -108,6 +108,21 @@ #define PEDIT_TCP_SPORT_DPORT 0x0 #define PEDIT_UDP_SPORT_DPORT 0x0 +enum cxgb4_action_natmode_flags { + CXGB4_ACTION_NATMODE_NONE = 0, + CXGB4_ACTION_NATMODE_DIP = (1 << 0), + CXGB4_ACTION_NATMODE_SIP = (1 << 1), + CXGB4_ACTION_NATMODE_DPORT = (1 << 2), + CXGB4_ACTION_NATMODE_SPORT = (1 << 3), +}; + +/* TC PEDIT action to NATMODE translation entry */ +struct cxgb4_natmode_config { + enum chip_type chip; + u8 flags; + u8 natmode; +}; + int cxgb4_tc_flower_replace(struct net_device *dev, struct flow_cls_offload *cls); int cxgb4_tc_flower_destroy(struct net_device *dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c @@ -47,7 +47,7 @@ bool next_header) { unsigned int i, j; - u32 val, mask; + __be32 val, mask; int off, err; bool found; @@ -216,7 +216,7 @@ const struct cxgb4_next_header *next; bool found = false; unsigned int i, j; - u32 val, mask; + __be32 val, mask; int off; if (t->table[link_uhtid - 1].link_handle) { @@ -230,10 +230,10 @@ /* Try to find matches that allow jumps to next header. */ for (i = 0; next[i].jump; i++) { - if (next[i].offoff != cls->knode.sel->offoff || - next[i].shift != cls->knode.sel->offshift || - next[i].mask != cls->knode.sel->offmask || - next[i].offset != cls->knode.sel->off) + if (next[i].sel.offoff != cls->knode.sel->offoff || + next[i].sel.offshift != cls->knode.sel->offshift || + next[i].sel.offmask != cls->knode.sel->offmask || + next[i].sel.off != cls->knode.sel->off) continue; /* Found a possible candidate. Find a key that @@ -245,9 +245,9 @@ val = cls->knode.sel->keys[j].val; mask = cls->knode.sel->keys[j].mask; - if (next[i].match_off == off && - next[i].match_val == val && - next[i].match_mask == mask) { + if (next[i].key.off == off && + next[i].key.val == val && + next[i].key.mask == mask) { found = true; break; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32_parse.h @@ -38,12 +38,12 @@ struct cxgb4_match_field { int off; /* Offset from the beginning of the header to match */ /* Fill the value/mask pair in the spec if matched */ - int (*val)(struct ch_filter_specification *f, u32 val, u32 mask); + int (*val)(struct ch_filter_specification *f, __be32 val, __be32 mask); }; /* IPv4 match fields */ static inline int cxgb4_fill_ipv4_tos(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { f->val.tos = (ntohl(val) >> 16) & 0x000000FF; f->mask.tos = (ntohl(mask) >> 16) & 0x000000FF; @@ -52,7 +52,7 @@ } static inline int cxgb4_fill_ipv4_frag(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { u32 mask_val; u8 frag_val; @@ -74,7 +74,7 @@ } static inline int cxgb4_fill_ipv4_proto(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { f->val.proto = (ntohl(val) >> 16) & 0x000000FF; f->mask.proto = (ntohl(mask) >> 16) & 0x000000FF; @@ -83,7 +83,7 @@ } static inline int cxgb4_fill_ipv4_src_ip(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.fip[0], &val, sizeof(u32)); memcpy(&f->mask.fip[0], &mask, sizeof(u32)); @@ -92,7 +92,7 @@ } static inline int cxgb4_fill_ipv4_dst_ip(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.lip[0], &val, sizeof(u32)); memcpy(&f->mask.lip[0], &mask, sizeof(u32)); @@ -111,7 +111,7 @@ /* IPv6 match fields */ static inline int cxgb4_fill_ipv6_tos(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { f->val.tos = (ntohl(val) >> 20) & 0x000000FF; f->mask.tos = (ntohl(mask) >> 20) & 0x000000FF; @@ -120,7 +120,7 @@ } static inline int cxgb4_fill_ipv6_proto(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { f->val.proto = (ntohl(val) >> 8) & 0x000000FF; f->mask.proto = (ntohl(mask) >> 8) & 0x000000FF; @@ -129,7 +129,7 @@ } static inline int cxgb4_fill_ipv6_src_ip0(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.fip[0], &val, sizeof(u32)); memcpy(&f->mask.fip[0], &mask, sizeof(u32)); @@ -138,7 +138,7 @@ } static inline int cxgb4_fill_ipv6_src_ip1(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.fip[4], &val, sizeof(u32)); memcpy(&f->mask.fip[4], &mask, sizeof(u32)); @@ -147,7 +147,7 @@ } static inline int cxgb4_fill_ipv6_src_ip2(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.fip[8], &val, sizeof(u32)); memcpy(&f->mask.fip[8], &mask, sizeof(u32)); @@ -156,7 +156,7 @@ } static inline int cxgb4_fill_ipv6_src_ip3(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.fip[12], &val, sizeof(u32)); memcpy(&f->mask.fip[12], &mask, sizeof(u32)); @@ -165,7 +165,7 @@ } static inline int cxgb4_fill_ipv6_dst_ip0(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.lip[0], &val, sizeof(u32)); memcpy(&f->mask.lip[0], &mask, sizeof(u32)); @@ -174,7 +174,7 @@ } static inline int cxgb4_fill_ipv6_dst_ip1(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.lip[4], &val, sizeof(u32)); memcpy(&f->mask.lip[4], &mask, sizeof(u32)); @@ -183,7 +183,7 @@ } static inline int cxgb4_fill_ipv6_dst_ip2(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.lip[8], &val, sizeof(u32)); memcpy(&f->mask.lip[8], &mask, sizeof(u32)); @@ -192,7 +192,7 @@ } static inline int cxgb4_fill_ipv6_dst_ip3(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { memcpy(&f->val.lip[12], &val, sizeof(u32)); memcpy(&f->mask.lip[12], &mask, sizeof(u32)); @@ -216,7 +216,7 @@ /* TCP/UDP match */ static inline int cxgb4_fill_l4_ports(struct ch_filter_specification *f, - u32 val, u32 mask) + __be32 val, __be32 mask) { f->val.fport = ntohl(val) >> 16; f->mask.fport = ntohl(mask) >> 16; @@ -237,19 +237,13 @@ }; struct cxgb4_next_header { - unsigned int offset; /* Offset to next header */ - /* offset, shift, and mask added to offset above + /* Offset, shift, and mask added to beginning of the header * to get to next header. Useful when using a header * field's value to jump to next header such as IHL field * in IPv4 header. */ - unsigned int offoff; - u32 shift; - u32 mask; - /* match criteria to make this jump */ - unsigned int match_off; - u32 match_val; - u32 match_mask; + struct tc_u32_sel sel; + struct tc_u32_key key; /* location of jump to make */ const struct cxgb4_match_field *jump; }; @@ -258,26 +252,74 @@ * IPv4 header. */ static const struct cxgb4_next_header cxgb4_ipv4_jumps[] = { - { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF, - .match_off = 8, .match_val = 0x600, .match_mask = 0xFF00, - .jump = cxgb4_tcp_fields }, - { .offset = 0, .offoff = 0, .shift = 6, .mask = 0xF, - .match_off = 8, .match_val = 0x1100, .match_mask = 0xFF00, - .jump = cxgb4_udp_fields }, - { .jump = NULL } + { + /* TCP Jump */ + .sel = { + .off = 0, + .offoff = 0, + .offshift = 6, + .offmask = cpu_to_be16(0x0f00), + }, + .key = { + .off = 8, + .val = cpu_to_be32(0x00060000), + .mask = cpu_to_be32(0x00ff0000), + }, + .jump = cxgb4_tcp_fields, + }, + { + /* UDP Jump */ + .sel = { + .off = 0, + .offoff = 0, + .offshift = 6, + .offmask = cpu_to_be16(0x0f00), + }, + .key = { + .off = 8, + .val = cpu_to_be32(0x00110000), + .mask = cpu_to_be32(0x00ff0000), + }, + .jump = cxgb4_udp_fields, + }, + { .jump = NULL }, }; /* Accept a rule with a jump directly past the 40 Bytes of IPv6 fixed header * to get to transport layer header. */ static const struct cxgb4_next_header cxgb4_ipv6_jumps[] = { - { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0, - .match_off = 4, .match_val = 0x60000, .match_mask = 0xFF0000, - .jump = cxgb4_tcp_fields }, - { .offset = 0x28, .offoff = 0, .shift = 0, .mask = 0, - .match_off = 4, .match_val = 0x110000, .match_mask = 0xFF0000, - .jump = cxgb4_udp_fields }, - { .jump = NULL } + { + /* TCP Jump */ + .sel = { + .off = 40, + .offoff = 0, + .offshift = 0, + .offmask = 0, + }, + .key = { + .off = 4, + .val = cpu_to_be32(0x00000600), + .mask = cpu_to_be32(0x0000ff00), + }, + .jump = cxgb4_tcp_fields, + }, + { + /* UDP Jump */ + .sel = { + .off = 40, + .offoff = 0, + .offshift = 0, + .offmask = 0, + }, + .key = { + .off = 4, + .val = cpu_to_be32(0x00001100), + .mask = cpu_to_be32(0x0000ff00), + }, + .jump = cxgb4_udp_fields, + }, + { .jump = NULL }, }; struct cxgb4_link { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_thermal.c @@ -62,6 +62,7 @@ int cxgb4_thermal_init(struct adapter *adap) { struct ch_thermal *ch_thermal = &adap->ch_thermal; + char ch_tz_name[THERMAL_NAME_LENGTH]; int num_trip = CXGB4_NUM_TRIPS; u32 param, val; int ret; @@ -82,7 +83,8 @@ ch_thermal->trip_type = THERMAL_TRIP_CRITICAL; } - ch_thermal->tzdev = thermal_zone_device_register("cxgb4", num_trip, + snprintf(ch_tz_name, sizeof(ch_tz_name), "cxgb4_%s", adap->name); + ch_thermal->tzdev = thermal_zone_device_register(ch_tz_name, num_trip, 0, adap, &cxgb4_thermal_ops, NULL, 0, 0); @@ -97,7 +99,9 @@ int cxgb4_thermal_remove(struct adapter *adap) { - if (adap->ch_thermal.tzdev) + if (adap->ch_thermal.tzdev) { thermal_zone_device_unregister(adap->ch_thermal.tzdev); + adap->ch_thermal.tzdev = NULL; + } return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c @@ -638,6 +638,9 @@ { unsigned int i; + if (!is_uld(adap)) + return; + mutex_lock(&uld_mutex); for (i = 0; i < CXGB4_ULD_MAX; i++) { if (!adap->uld[i].handle) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h @@ -44,6 +44,9 @@ #define MAX_ULD_QSETS 16 +/* ulp_mem_io + ulptx_idata + payload + padding */ +#define MAX_IMM_ULPTX_WR_LEN (32 + 8 + 256 + 8) + /* CPL message priority levels */ enum { CPL_PRIORITY_DATA = 0, /* data messages */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -507,40 +507,19 @@ EXPORT_SYMBOL(cxgb4_select_ntuple); /* - * Called when address resolution fails for an L2T entry to handle packets - * on the arpq head. If a packet specifies a failure handler it is invoked, - * otherwise the packet is sent to the device. - */ -static void handle_failed_resolution(struct adapter *adap, struct l2t_entry *e) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(&e->arpq)) != NULL) { - const struct l2t_skb_cb *cb = L2T_SKB_CB(skb); - - spin_unlock(&e->lock); - if (cb->arp_err_handler) - cb->arp_err_handler(cb->handle, skb); - else - t4_ofld_send(adap, skb); - spin_lock(&e->lock); - } -} - -/* * Called when the host's neighbor layer makes a change to some entry that is * loaded into the HW L2 table. */ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) { - struct l2t_entry *e; - struct sk_buff_head *arpq = NULL; - struct l2t_data *d = adap->l2t; unsigned int addr_len = neigh->tbl->key_len; u32 *addr = (u32 *) neigh->primary_key; - int ifidx = neigh->dev->ifindex; - int hash = addr_hash(d, addr, addr_len, ifidx); + int hash, ifidx = neigh->dev->ifindex; + struct sk_buff_head *arpq = NULL; + struct l2t_data *d = adap->l2t; + struct l2t_entry *e; + hash = addr_hash(d, addr, addr_len, ifidx); read_lock_bh(&d->lock); for (e = d->l2tab[hash].first; e; e = e->next) if (!addreq(e, addr) && e->ifindex == ifidx) { @@ -573,8 +552,25 @@ write_l2e(adap, e, 0); } - if (arpq) - handle_failed_resolution(adap, e); + if (arpq) { + struct sk_buff *skb; + + /* Called when address resolution fails for an L2T + * entry to handle packets on the arpq head. If a + * packet specifies a failure handler it is invoked, + * otherwise the packet is sent to the device. + */ + while ((skb = __skb_dequeue(&e->arpq)) != NULL) { + const struct l2t_skb_cb *cb = L2T_SKB_CB(skb); + + spin_unlock(&e->lock); + if (cb->arp_err_handler) + cb->arp_err_handler(cb->handle, skb); + else + t4_ofld_send(adap, skb); + spin_lock(&e->lock); + } + } spin_unlock_bh(&e->lock); } @@ -682,8 +678,7 @@ static void *l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos) { v = l2t_get_idx(seq, *pos); - if (v) - ++*pos; + ++(*pos); return v; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/sge.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/sge.c @@ -1324,8 +1324,9 @@ int t4_sge_eth_txq_egress_update(struct adapter *adap, struct sge_eth_txq *eq, int maxreclaim) { + unsigned int reclaimed, hw_cidx; struct sge_txq *q = &eq->q; - unsigned int reclaimed; + int hw_in_use; if (!q->in_use || !__netif_tx_trylock(eq->txq)) return 0; @@ -1333,12 +1334,17 @@ /* Reclaim pending completed TX Descriptors. */ reclaimed = reclaim_completed_tx(adap, &eq->q, maxreclaim, true); + hw_cidx = ntohs(READ_ONCE(q->stat->cidx)); + hw_in_use = q->pidx - hw_cidx; + if (hw_in_use < 0) + hw_in_use += q->size; + /* If the TX Queue is currently stopped and there's now more than half * the queue available, restart it. Otherwise bail out since the rest * of what we want do here is with the possibility of shipping any * currently buffered Coalesced TX Work Request. */ - if (netif_tx_queue_stopped(eq->txq) && txq_avail(q) > (q->size / 2)) { + if (netif_tx_queue_stopped(eq->txq) && hw_in_use < (q->size / 2)) { netif_tx_wake_queue(eq->txq); eq->q.restarts++; } @@ -1469,16 +1475,7 @@ * has opened up. */ eth_txq_stop(q); - - /* If we're using the SGE Doorbell Queue Timer facility, we - * don't need to ask the Firmware to send us Egress Queue CIDX - * Updates: the Hardware will do this automatically. And - * since we send the Ingress Queue CIDX Updates to the - * corresponding Ethernet Response Queue, we'll get them very - * quickly. - */ - if (!q->dbqt) - wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; } wr = (void *)&q->q.desc[q->q.pidx]; @@ -1792,16 +1789,7 @@ * has opened up. */ eth_txq_stop(txq); - - /* If we're using the SGE Doorbell Queue Timer facility, we - * don't need to ask the Firmware to send us Egress Queue CIDX - * Updates: the Hardware will do this automatically. And - * since we send the Ingress Queue CIDX Updates to the - * corresponding Ethernet Response Queue, we'll get them very - * quickly. - */ - if (!txq->dbqt) - wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; + wr_mid |= FW_WR_EQUEQ_F | FW_WR_EQUIQ_F; } /* Start filling in our Work Request. Note that we do _not_ handle @@ -2170,17 +2158,22 @@ * @skb: the packet * * Returns true if a packet can be sent as an offload WR with immediate - * data. We currently use the same limit as for Ethernet packets. + * data. + * FW_OFLD_TX_DATA_WR limits the payload to 255 bytes due to 8-bit field. + * However, FW_ULPTX_WR commands have a 256 byte immediate only + * payload limit. */ static inline int is_ofld_imm(const struct sk_buff *skb) { struct work_request_hdr *req = (struct work_request_hdr *)skb->data; unsigned long opcode = FW_WR_OP_G(ntohl(req->wr_hi)); - if (opcode == FW_CRYPTO_LOOKASIDE_WR) + if (unlikely(opcode == FW_ULPTX_WR)) + return skb->len <= MAX_IMM_ULPTX_WR_LEN; + else if (opcode == FW_CRYPTO_LOOKASIDE_WR) return skb->len <= SGE_MAX_WR_LEN; else - return skb->len <= MAX_IMM_TX_PKT_LEN; + return skb->len <= MAX_IMM_OFLD_TX_DATA_WR_LEN; } /** @@ -2453,6 +2446,7 @@ txq_info = adap->sge.uld_txq_info[tx_uld_type]; if (unlikely(!txq_info)) { WARN_ON(true); + kfree_skb(skb); return NET_XMIT_DROP; } @@ -2828,7 +2822,7 @@ hwtstamps = skb_hwtstamps(skb); memset(hwtstamps, 0, sizeof(*hwtstamps)); - hwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(*((u64 *)data))); + hwtstamps->hwtstamp = ns_to_ktime(get_unaligned_be64(data)); return RX_PTP_PKT_SUC; } @@ -2924,26 +2918,6 @@ } txq = &s->ethtxq[pi->first_qset + rspq->idx]; - - /* We've got the Hardware Consumer Index Update in the Egress Update - * message. If we're using the SGE Doorbell Queue Timer mechanism, - * these Egress Update messages will be our sole CIDX Updates we get - * since we don't want to chew up PCIe bandwidth for both Ingress - * Messages and Status Page writes. However, The code which manages - * reclaiming successfully DMA'ed TX Work Requests uses the CIDX value - * stored in the Status Page at the end of the TX Queue. It's easiest - * to simply copy the CIDX Update value from the Egress Update message - * to the Status Page. Also note that no Endian issues need to be - * considered here since both are Big Endian and we're just copying - * bytes consistently ... - */ - if (txq->dbqt) { - struct cpl_sge_egr_update *egr; - - egr = (struct cpl_sge_egr_update *)rsp; - WRITE_ONCE(txq->q.stat->cidx, egr->cidx); - } - t4_sge_eth_txq_egress_update(adapter, txq, -1); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2093,7 +2093,8 @@ 0x1190, 0x1194, 0x11a0, 0x11a4, 0x11b0, 0x11b4, - 0x11fc, 0x1274, + 0x11fc, 0x123c, + 0x1254, 0x1274, 0x1280, 0x133c, 0x1800, 0x18fc, 0x3000, 0x302c, @@ -3499,7 +3500,7 @@ drv_fw = &fw_info->fw_hdr; /* Read the header of the firmware on the card */ - ret = -t4_read_flash(adap, FLASH_FW_START, + ret = t4_read_flash(adap, FLASH_FW_START, sizeof(*card_fw) / sizeof(uint32_t), (uint32_t *)card_fw, 1); if (ret == 0) { @@ -3528,8 +3529,8 @@ should_install_fs_fw(adap, card_fw_usable, be32_to_cpu(fs_fw->fw_ver), be32_to_cpu(card_fw->fw_ver))) { - ret = -t4_fw_upgrade(adap, adap->mbox, fw_data, - fw_size, 0); + ret = t4_fw_upgrade(adap, adap->mbox, fw_data, + fw_size, 0); if (ret != 0) { dev_err(adap->pdev_dev, "failed to install firmware: %d\n", ret); @@ -3560,7 +3561,7 @@ FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k), FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k)); - ret = EINVAL; + ret = -EINVAL; goto bye; } @@ -3748,7 +3749,7 @@ FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_VERSION)); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val); - if (ret < 0) + if (ret) return ret; *phy_fw_ver = val; return 0; @@ -3849,6 +3850,8 @@ FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD)); ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1, ¶m, &val, 30000); + if (ret) + return ret; /* If we have version number support, then check to see that the new * firmware got loaded properly. @@ -4089,7 +4092,8 @@ if (cc_pause & PAUSE_TX) fw_pause |= FW_PORT_CAP32_802_3_PAUSE; else - fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR; + fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR | + FW_PORT_CAP32_802_3_PAUSE; } else if (cc_pause & PAUSE_TX) { fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR; } @@ -8563,17 +8567,17 @@ void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl) { const struct fw_port_cmd *cmd = (const void *)rpl; - int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); - struct adapter *adapter = pi->adapter; + fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; struct link_config *lc = &pi->link_cfg; - int link_ok, linkdnrc; - enum fw_port_type port_type; + struct adapter *adapter = pi->adapter; + unsigned int speed, fc, fec, adv_fc; enum fw_port_module_type mod_type; - unsigned int speed, fc, fec; - fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; + int action, link_ok, linkdnrc; + enum fw_port_type port_type; /* Extract the various fields from the Port Information message. */ + action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); switch (action) { case FW_PORT_ACTION_GET_PORT_INFO: { u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); @@ -8611,6 +8615,7 @@ } fec = fwcap_to_cc_fec(acaps); + adv_fc = fwcap_to_cc_pause(acaps); fc = fwcap_to_cc_pause(linkattr); speed = fwcap_to_speed(linkattr); @@ -8667,7 +8672,9 @@ } if (link_ok != lc->link_ok || speed != lc->speed || - fc != lc->fc || fec != lc->fec) { /* something changed */ + fc != lc->fc || adv_fc != lc->advertised_fc || + fec != lc->fec) { + /* something changed */ if (!link_ok && lc->link_ok) { lc->link_down_rc = linkdnrc; dev_warn_ratelimited(adapter->pdev_dev, @@ -8677,6 +8684,7 @@ } lc->link_ok = link_ok; lc->speed = speed; + lc->advertised_fc = adv_fc; lc->fc = fc; lc->fec = fec; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/t4_hw.h @@ -293,6 +293,8 @@ #define I2C_PAGE_SIZE 0x100 #define SFP_DIAG_TYPE_ADDR 0x5c #define SFP_DIAG_TYPE_LEN 0x1 +#define SFP_DIAG_ADDRMODE BIT(2) +#define SFP_DIAG_IMPLEMENTED BIT(6) #define SFF_8472_COMP_ADDR 0x5e #define SFF_8472_COMP_LEN 0x1 #define SFF_REV_ADDR 0x1 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/t4_pci_id_tbl.h @@ -219,6 +219,7 @@ CH_PCI_ID_TABLE_FENTRY(0x6089), /* Custom T62100-KR */ CH_PCI_ID_TABLE_FENTRY(0x608a), /* Custom T62100-CR */ CH_PCI_ID_TABLE_FENTRY(0x608b), /* Custom T6225-CR */ + CH_PCI_ID_TABLE_FENTRY(0x6092), /* Custom T62100-CR-LOM */ CH_PCI_DEVICE_ID_TABLE_DEFINE_END; #endif /* __T4_PCI_ID_TBL_H__ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h @@ -1900,6 +1900,9 @@ #define MAC_PORT_CFG2_A 0x818 +#define MAC_PORT_PTP_SUM_LO_A 0x990 +#define MAC_PORT_PTP_SUM_HI_A 0x994 + #define MPS_CMN_CTL_A 0x9000 #define COUNTPAUSEMCRX_S 5 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_tcb.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4/t4_tcb.h @@ -50,6 +50,10 @@ #define TCB_RQ_START_M 0x3ffffffULL #define TCB_RQ_START_V(x) ((x) << TCB_RQ_START_S) +#define TF_DROP_S 22 +#define TF_DIRECT_STEER_S 23 +#define TF_LPBK_S 59 + #define TF_CCTRL_ECE_S 60 #define TF_CCTRL_CWR_S 61 #define TF_CCTRL_RFR_S 62 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -860,7 +860,7 @@ */ err = t4vf_update_port_info(pi); if (err < 0) - return err; + goto err_unwind; /* * Note that this interface is up and start everything up ... @@ -1690,8 +1690,8 @@ struct port_info *pi = netdev_priv(dev); pauseparam->autoneg = (pi->link_cfg.requested_fc & PAUSE_AUTONEG) != 0; - pauseparam->rx_pause = (pi->link_cfg.fc & PAUSE_RX) != 0; - pauseparam->tx_pause = (pi->link_cfg.fc & PAUSE_TX) != 0; + pauseparam->rx_pause = (pi->link_cfg.advertised_fc & PAUSE_RX) != 0; + pauseparam->tx_pause = (pi->link_cfg.advertised_fc & PAUSE_TX) != 0; } /* --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h @@ -135,6 +135,7 @@ enum cc_pause requested_fc; /* flow control user has requested */ enum cc_pause fc; /* actual link flow control */ + enum cc_pause advertised_fc; /* actual advertised flow control */ enum cc_fec auto_fec; /* Forward Error Correction: */ enum cc_fec requested_fec; /* "automatic" (IEEE 802.3), */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c @@ -1913,16 +1913,16 @@ static void t4vf_handle_get_port_info(struct port_info *pi, const struct fw_port_cmd *cmd) { - int action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); - struct adapter *adapter = pi->adapter; + fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; struct link_config *lc = &pi->link_cfg; - int link_ok, linkdnrc; - enum fw_port_type port_type; + struct adapter *adapter = pi->adapter; + unsigned int speed, fc, fec, adv_fc; enum fw_port_module_type mod_type; - unsigned int speed, fc, fec; - fw_port_cap32_t pcaps, acaps, lpacaps, linkattr; + int action, link_ok, linkdnrc; + enum fw_port_type port_type; /* Extract the various fields from the Port Information message. */ + action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16)); switch (action) { case FW_PORT_ACTION_GET_PORT_INFO: { u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype); @@ -1982,6 +1982,7 @@ } fec = fwcap_to_cc_fec(acaps); + adv_fc = fwcap_to_cc_pause(acaps); fc = fwcap_to_cc_pause(linkattr); speed = fwcap_to_speed(linkattr); @@ -2012,7 +2013,9 @@ } if (link_ok != lc->link_ok || speed != lc->speed || - fc != lc->fc || fec != lc->fec) { /* something changed */ + fc != lc->fc || adv_fc != lc->advertised_fc || + fec != lc->fec) { + /* something changed */ if (!link_ok && lc->link_ok) { lc->link_down_rc = linkdnrc; dev_warn_ratelimited(adapter->pdev_dev, @@ -2022,6 +2025,7 @@ } lc->link_ok = link_ok; lc->speed = speed; + lc->advertised_fc = adv_fc; lc->fc = fc; lc->fec = fec; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -99,7 +100,7 @@ rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip, peer_port, local_port, IPPROTO_TCP, - tos, 0); + tos & ~INET_ECN_MASK, 0); if (IS_ERR(rt)) return NULL; n = dst_neigh_lookup(&rt->dst, &peer_ip); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cisco/enic/enic.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cisco/enic/enic.h @@ -171,6 +171,7 @@ u16 num_vfs; #endif spinlock_t enic_api_lock; + bool enic_api_busy; struct enic_port_profile *pp; /* work queue cache line section */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cisco/enic/enic_api.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cisco/enic/enic_api.c @@ -34,6 +34,12 @@ struct vnic_dev *vdev = enic->vdev; spin_lock(&enic->enic_api_lock); + while (enic->enic_api_busy) { + spin_unlock(&enic->enic_api_lock); + cpu_relax(); + spin_lock(&enic->enic_api_lock); + } + spin_lock_bh(&enic->devcmd_lock); vnic_dev_cmd_proxy_by_index_start(vdev, vf); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cisco/enic/enic_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cisco/enic/enic_ethtool.c @@ -454,7 +454,6 @@ break; default: return -EINVAL; - break; } fsp->h_u.tcp_ip4_spec.ip4src = flow_get_u32_src(&n->keys); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cisco/enic/enic_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cisco/enic/enic_main.c @@ -803,7 +803,7 @@ return err; } -static inline void enic_queue_wq_skb(struct enic *enic, +static inline int enic_queue_wq_skb(struct enic *enic, struct vnic_wq *wq, struct sk_buff *skb) { unsigned int mss = skb_shinfo(skb)->gso_size; @@ -849,6 +849,7 @@ wq->to_use = buf->next; dev_kfree_skb(skb); } + return err; } /* netif_tx_lock held, process context with BHs disabled, or BH */ @@ -892,7 +893,8 @@ return NETDEV_TX_BUSY; } - enic_queue_wq_skb(enic, wq, skb); + if (enic_queue_wq_skb(enic, wq, skb)) + goto error; if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + ENIC_DESC_MAX_SPLITS) netif_tx_stop_queue(txq); @@ -900,6 +902,7 @@ if (!netdev_xmit_more() || netif_xmit_stopped(txq)) vnic_wq_doorbell(wq); +error: spin_unlock(&enic->wq_lock[txq_map]); return NETDEV_TX_OK; @@ -1149,18 +1152,30 @@ pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]); if (port[IFLA_PORT_PROFILE]) { + if (nla_len(port[IFLA_PORT_PROFILE]) != PORT_PROFILE_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_NAME; memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]), PORT_PROFILE_MAX); } if (port[IFLA_PORT_INSTANCE_UUID]) { + if (nla_len(port[IFLA_PORT_INSTANCE_UUID]) != PORT_UUID_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_INSTANCE; memcpy(pp->instance_uuid, nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX); } if (port[IFLA_PORT_HOST_UUID]) { + if (nla_len(port[IFLA_PORT_HOST_UUID]) != PORT_UUID_MAX) { + memcpy(pp, &prev_pp, sizeof(*pp)); + return -EINVAL; + } pp->set |= ENIC_SET_HOST; memcpy(pp->host_uuid, nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX); @@ -2013,10 +2028,10 @@ napi_disable(&enic->napi[i]); netif_carrier_off(netdev); - netif_tx_disable(netdev); if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX) for (i = 0; i < enic->wq_count; i++) napi_disable(&enic->napi[enic_cq_wq(enic, i)]); + netif_tx_disable(netdev); if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic)) enic_dev_del_station_addr(enic); @@ -2142,8 +2157,6 @@ int done; int err; - BUG_ON(in_interrupt()); - err = start(vdev, arg); if (err) return err; @@ -2331,6 +2344,13 @@ rss_hash_bits, rss_base_cpu, rss_enable); } +static void enic_set_api_busy(struct enic *enic, bool busy) +{ + spin_lock(&enic->enic_api_lock); + enic->enic_api_busy = busy; + spin_unlock(&enic->enic_api_lock); +} + static void enic_reset(struct work_struct *work) { struct enic *enic = container_of(work, struct enic, reset); @@ -2340,7 +2360,9 @@ rtnl_lock(); - spin_lock(&enic->enic_api_lock); + /* Stop any activity from infiniband */ + enic_set_api_busy(enic, true); + enic_stop(enic->netdev); enic_dev_soft_reset(enic); enic_reset_addr_lists(enic); @@ -2348,7 +2370,10 @@ enic_set_rss_nic_cfg(enic); enic_dev_set_ig_vlan_rewrite_mode(enic); enic_open(enic->netdev); - spin_unlock(&enic->enic_api_lock); + + /* Allow infiniband to fiddle with the device again */ + enic_set_api_busy(enic, false); + call_netdevice_notifiers(NETDEV_REBOOT, enic->netdev); rtnl_unlock(); @@ -2360,7 +2385,9 @@ rtnl_lock(); - spin_lock(&enic->enic_api_lock); + /* Stop any activity from infiniband */ + enic_set_api_busy(enic, true); + enic_dev_hang_notify(enic); enic_stop(enic->netdev); enic_dev_hang_reset(enic); @@ -2369,7 +2396,10 @@ enic_set_rss_nic_cfg(enic); enic_dev_set_ig_vlan_rewrite_mode(enic); enic_open(enic->netdev); - spin_unlock(&enic->enic_api_lock); + + /* Allow infiniband to fiddle with the device again */ + enic_set_api_busy(enic, false); + call_netdevice_notifiers(NETDEV_REBOOT, enic->netdev); rtnl_unlock(); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cortina/gemini.c +++ linux-oracle-5.4.0/drivers/net/ethernet/cortina/gemini.c @@ -81,8 +81,7 @@ #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT) #define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \ - NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \ - NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6) + NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM) /** * struct gmac_queue_page - page buffer per-page info @@ -304,21 +303,21 @@ switch (phydev->speed) { case 1000: status.bits.speed = GMAC_SPEED_1000; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) + if (phy_interface_mode_is_rgmii(phydev->interface)) status.bits.mii_rmii = GMAC_PHY_RGMII_1000; netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n", phydev_name(phydev)); break; case 100: status.bits.speed = GMAC_SPEED_100; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) + if (phy_interface_mode_is_rgmii(phydev->interface)) status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n", phydev_name(phydev)); break; case 10: status.bits.speed = GMAC_SPEED_10; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) + if (phy_interface_mode_is_rgmii(phydev->interface)) status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n", phydev_name(phydev)); @@ -388,6 +387,9 @@ status.bits.mii_rmii = GMAC_PHY_GMII; break; case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_TXID: + case PHY_INTERFACE_MODE_RGMII_RXID: netdev_dbg(netdev, "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n"); status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; @@ -429,8 +431,8 @@ .val = CONFIG0_MAXLEN_1536, }, { - .max_l3_len = 1542, - .val = CONFIG0_MAXLEN_1542, + .max_l3_len = 1548, + .val = CONFIG0_MAXLEN_1548, }, { .max_l3_len = 9212, @@ -576,6 +578,8 @@ if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { dev_warn(geth->dev, "TX queue base is not aligned\n"); + dma_free_coherent(geth->dev, len * sizeof(*desc_ring), + desc_ring, port->txq_dma_base); kfree(skb_tab); return -ENOMEM; } @@ -1110,10 +1114,13 @@ { struct gemini_ethernet_port *port = netdev_priv(netdev); struct gemini_ethernet *geth = port->geth; + unsigned long flags; u32 val, mask; netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); + spin_lock_irqsave(&geth->irq_lock, flags); + mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); if (en) @@ -1122,6 +1129,8 @@ val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); val = en ? val | mask : val & ~mask; writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); + + spin_unlock_irqrestore(&geth->irq_lock, flags); } static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num) @@ -1145,25 +1154,37 @@ struct gmac_txdesc *txd; skb_frag_t *skb_frag; dma_addr_t mapping; - unsigned short mtu; void *buffer; + int ret; - mtu = ETH_HLEN; - mtu += netdev->mtu; - if (skb->protocol == htons(ETH_P_8021Q)) - mtu += VLAN_HLEN; - + /* TODO: implement proper TSO using MTU in word3 */ word1 = skb->len; word3 = SOF_BIT; - if (word1 > mtu) { - word1 |= TSS_MTU_ENABLE_BIT; - word3 |= mtu; - } - - if (skb->ip_summed != CHECKSUM_NONE) { + if (skb->len >= ETH_FRAME_LEN) { + /* Hardware offloaded checksumming isn't working on frames + * bigger than 1514 bytes. A hypothesis about this is that the + * checksum buffer is only 1518 bytes, so when the frames get + * bigger they get truncated, or the last few bytes get + * overwritten by the FCS. + * + * Just use software checksumming and bypass on bigger frames. + */ + if (skb->ip_summed == CHECKSUM_PARTIAL) { + ret = skb_checksum_help(skb); + if (ret) + return ret; + } + word1 |= TSS_BYPASS_BIT; + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { int tcp = 0; + /* We do not switch off the checksumming on non TCP/UDP + * frames: as is shown from tests, the checksumming engine + * is smart enough to see that a frame is not actually TCP + * or UDP and then just pass it through without any changes + * to the frame. + */ if (skb->protocol == htons(ETH_P_IP)) { word1 |= TSS_IP_CHKSUM_BIT; tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; @@ -1405,15 +1426,19 @@ union gmac_rxdesc_3 word3; struct page *page = NULL; unsigned int page_offs; + unsigned long flags; unsigned short r, w; union dma_rwptr rw; dma_addr_t mapping; int frag_nr = 0; + spin_lock_irqsave(&geth->irq_lock, flags); rw.bits32 = readl(ptr_reg); /* Reset interrupt as all packages until here are taken into account */ writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); + spin_unlock_irqrestore(&geth->irq_lock, flags); + r = rw.bits.rptr; w = rw.bits.wptr; @@ -1716,10 +1741,9 @@ gmac_update_hw_stats(netdev); if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { + spin_lock(&geth->irq_lock); writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); - - spin_lock(&geth->irq_lock); u64_stats_update_begin(&port->ir_stats_syncp); ++port->stats.rx_fifo_errors; u64_stats_update_end(&port->ir_stats_syncp); @@ -1988,15 +2012,6 @@ return 0; } -static netdev_features_t gmac_fix_features(struct net_device *netdev, - netdev_features_t features) -{ - if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) - features &= ~GMAC_OFFLOAD_FEATURES; - - return features; -} - static int gmac_set_features(struct net_device *netdev, netdev_features_t features) { @@ -2217,7 +2232,6 @@ .ndo_set_mac_address = gmac_set_mac_address, .ndo_get_stats64 = gmac_get_stats64, .ndo_change_mtu = gmac_change_mtu, - .ndo_fix_features = gmac_fix_features, .ndo_set_features = gmac_set_features, }; @@ -2386,7 +2400,7 @@ dev_info(dev, "probe %s ID %d\n", dev_name(dev), id); - netdev = alloc_etherdev_mq(sizeof(*port), TX_QUEUE_NUM); + netdev = devm_alloc_etherdev_mqs(dev, sizeof(*port), TX_QUEUE_NUM, TX_QUEUE_NUM); if (!netdev) { dev_err(dev, "Can't allocate ethernet device #%d\n", id); return -ENOMEM; @@ -2443,7 +2457,8 @@ port->reset = devm_reset_control_get_exclusive(dev, NULL); if (IS_ERR(port->reset)) { dev_err(dev, "no reset\n"); - return PTR_ERR(port->reset); + ret = PTR_ERR(port->reset); + goto unprepare; } reset_control_reset(port->reset); usleep_range(100, 500); @@ -2470,11 +2485,12 @@ netdev->hw_features = GMAC_OFFLOAD_FEATURES; netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; - /* We can handle jumbo frames up to 10236 bytes so, let's accept - * payloads of 10236 bytes minus VLAN and ethernet header + /* We can receive jumbo frames up to 10236 bytes but only + * transmit 2047 bytes so, let's accept payloads of 2047 + * bytes minus VLAN and ethernet header */ netdev->min_mtu = ETH_MIN_MTU; - netdev->max_mtu = 10236 - VLAN_ETH_HLEN; + netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; port->freeq_refill = 0; netif_napi_add(netdev, &port->napi, gmac_napi_poll, @@ -2499,23 +2515,24 @@ port_names[port->id], port); if (ret) - return ret; + goto unprepare; ret = register_netdev(netdev); - if (!ret) { + if (ret) + goto unprepare; + + netdev_info(netdev, + "irq %d, DMA @ 0x%pap, GMAC @ 0x%pap\n", + port->irq, &dmares->start, + &gmacres->start); + ret = gmac_setup_phy(netdev); + if (ret) netdev_info(netdev, - "irq %d, DMA @ 0x%pap, GMAC @ 0x%pap\n", - port->irq, &dmares->start, - &gmacres->start); - ret = gmac_setup_phy(netdev); - if (ret) - netdev_info(netdev, - "PHY init failed, deferring to ifup time\n"); - return 0; - } + "PHY init failed, deferring to ifup time\n"); + return 0; - port->netdev = NULL; - free_netdev(netdev); +unprepare: + clk_disable_unprepare(port->pclk); return ret; } @@ -2524,7 +2541,6 @@ struct gemini_ethernet_port *port = platform_get_drvdata(pdev); gemini_port_remove(port); - free_netdev(port->netdev); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/cortina/gemini.h +++ linux-oracle-5.4.0/drivers/net/ethernet/cortina/gemini.h @@ -502,7 +502,7 @@ #define SOF_BIT 0x80000000 #define EOF_BIT 0x40000000 #define EOFIE_BIT BIT(29) -#define MTU_SIZE_BIT_MASK 0x1fff +#define MTU_SIZE_BIT_MASK 0x7ff /* Max MTU 2047 bytes */ /* GMAC Tx Descriptor */ struct gmac_txdesc { @@ -787,7 +787,7 @@ #define CONFIG0_MAXLEN_1536 0 #define CONFIG0_MAXLEN_1518 1 #define CONFIG0_MAXLEN_1522 2 -#define CONFIG0_MAXLEN_1542 3 +#define CONFIG0_MAXLEN_1548 3 #define CONFIG0_MAXLEN_9k 4 /* 9212 */ #define CONFIG0_MAXLEN_10k 5 /* 10236 */ #define CONFIG0_MAXLEN_1518__6 6 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/davicom/dm9000.c +++ linux-oracle-5.4.0/drivers/net/ethernet/davicom/dm9000.c @@ -134,6 +134,8 @@ u32 wake_state; int ip_summed; + + struct regulator *power_supply; }; /* debug code */ @@ -1405,6 +1407,8 @@ mac_addr = of_get_mac_address(np); if (!IS_ERR(mac_addr)) ether_addr_copy(pdata->dev_addr, mac_addr); + else if (PTR_ERR(mac_addr) == -EPROBE_DEFER) + return ERR_CAST(mac_addr); return pdata; } @@ -1452,7 +1456,7 @@ if (ret) { dev_err(dev, "failed to request reset gpio %d: %d\n", reset_gpios, ret); - return -ENODEV; + goto out_regulator_disable; } /* According to manual PWRST# Low Period Min 1ms */ @@ -1464,14 +1468,18 @@ if (!pdata) { pdata = dm9000_parse_dt(&pdev->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + goto out_regulator_disable; + } } /* Init network device */ ndev = alloc_etherdev(sizeof(struct board_info)); - if (!ndev) - return -ENOMEM; + if (!ndev) { + ret = -ENOMEM; + goto out_regulator_disable; + } SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1482,6 +1490,8 @@ db->dev = &pdev->dev; db->ndev = ndev; + if (!IS_ERR(power)) + db->power_supply = power; spin_lock_init(&db->lock); mutex_init(&db->addr_lock); @@ -1504,7 +1514,7 @@ goto out; } - db->irq_wake = platform_get_irq(pdev, 1); + db->irq_wake = platform_get_irq_optional(pdev, 1); if (db->irq_wake >= 0) { dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake); @@ -1706,6 +1716,10 @@ dm9000_release_board(pdev, db); free_netdev(ndev); +out_regulator_disable: + if (!IS_ERR(power)) + regulator_disable(power); + return ret; } @@ -1763,9 +1777,13 @@ dm9000_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); + struct board_info *dm = to_dm9000_board(ndev); unregister_netdev(ndev); - dm9000_release_board(pdev, netdev_priv(ndev)); + dm9000_release_board(pdev, dm); + if (dm->power_supply) + regulator_disable(dm->power_supply); + free_netdev(ndev); /* free device structure */ dev_dbg(&pdev->dev, "released and freed device\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/de2104x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/de2104x.c @@ -91,7 +91,7 @@ #define DSL CONFIG_DE2104X_DSL #endif -#define DE_RX_RING_SIZE 64 +#define DE_RX_RING_SIZE 128 #define DE_TX_RING_SIZE 64 #define DE_RING_BYTES \ ((sizeof(struct de_desc) * DE_RX_RING_SIZE) + \ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/de4x5.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/de4x5.c @@ -4708,6 +4708,10 @@ lp->ibn = 3; lp->active = *p++; if (MOTO_SROM_BUG) lp->active = 0; + /* if (MOTO_SROM_BUG) statement indicates lp->active could + * be 8 (i.e. the size of array lp->phy) */ + if (WARN_ON(lp->active >= ARRAY_SIZE(lp->phy))) + return -EINVAL; lp->phy[lp->active].gep = (*p ? p : NULL); p += (2 * (*p) + 1); lp->phy[lp->active].rst = (*p ? p : NULL); p += (2 * (*p) + 1); lp->phy[lp->active].mc = get_unaligned_le16(p); p += 2; @@ -4927,11 +4931,11 @@ u_char breg[2]; } a; int i, r2, r3, ret=0;*/ - int r2, r3; + int r2; /* Read r2 and r3 */ r2 = mii_rd(MII_ID0, phyaddr, ioaddr); - r3 = mii_rd(MII_ID1, phyaddr, ioaddr); + mii_rd(MII_ID1, phyaddr, ioaddr); /* SEEQ and Cypress way * / / * Shuffle r2 and r3 * / a.reg=0; @@ -4999,19 +5003,23 @@ } if ((j == limit) && (i < DE4X5_MAX_MII)) { for (k=0; k < DE4X5_MAX_PHY && lp->phy[k].id; k++); - lp->phy[k].addr = i; - lp->phy[k].id = id; - lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */ - lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */ - lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */ - lp->mii_cnt++; - lp->active++; - printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name); - j = de4x5_debug; - de4x5_debug |= DEBUG_MII; - de4x5_dbg_mii(dev, k); - de4x5_debug = j; - printk("\n"); + if (k < DE4X5_MAX_PHY) { + lp->phy[k].addr = i; + lp->phy[k].id = id; + lp->phy[k].spd.reg = GENERIC_REG; /* ANLPA register */ + lp->phy[k].spd.mask = GENERIC_MASK; /* 100Mb/s technologies */ + lp->phy[k].spd.value = GENERIC_VALUE; /* TX & T4, H/F Duplex */ + lp->mii_cnt++; + lp->active++; + printk("%s: Using generic MII device control. If the board doesn't operate,\nplease mail the following dump to the author:\n", dev->name); + j = de4x5_debug; + de4x5_debug |= DEBUG_MII; + de4x5_dbg_mii(dev, k); + de4x5_debug = j; + printk("\n"); + } else { + goto purgatory; + } } } purgatory: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/dmfe.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/dmfe.c @@ -2214,15 +2214,16 @@ if (cr6set) dmfe_cr6_user_set = cr6set; - switch(mode) { - case DMFE_10MHF: + switch (mode) { + case DMFE_10MHF: case DMFE_100MHF: case DMFE_10MFD: case DMFE_100MFD: case DMFE_1M_HPNA: dmfe_media_mode = mode; break; - default:dmfe_media_mode = DMFE_AUTO; + default: + dmfe_media_mode = DMFE_AUTO; break; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/media.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/media.c @@ -319,13 +319,8 @@ break; } case 5: case 6: { - u16 setup[5]; - new_csr6 = 0; /* FIXME */ - for (i = 0; i < 5; i++) - setup[i] = get_u16(&p[i*2 + 1]); - if (startup && mtable->has_reset) { struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; unsigned char *rst = rleaf->leafdata; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/tulip_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -1410,8 +1410,10 @@ /* alloc_etherdev ensures aligned and zeroed private structures */ dev = alloc_etherdev (sizeof (*tp)); - if (!dev) + if (!dev) { + pci_disable_device(pdev); return -ENOMEM; + } SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { @@ -1788,6 +1790,7 @@ err_out_free_netdev: free_netdev (dev); + pci_disable_device(pdev); return -ENODEV; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/uli526x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/uli526x.c @@ -1809,8 +1809,8 @@ if (cr6set) uli526x_cr6_user_set = cr6set; - switch (mode) { - case ULI526X_10MHF: + switch (mode) { + case ULI526X_10MHF: case ULI526X_100MHF: case ULI526X_10MFD: case ULI526X_100MFD: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dec/tulip/winbond-840.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dec/tulip/winbond-840.c @@ -367,7 +367,7 @@ int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; void __iomem *ioaddr; - i = pci_enable_device(pdev); + i = pcim_enable_device(pdev); if (i) return i; pci_set_master(pdev); @@ -389,7 +389,7 @@ ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); if (!ioaddr) - goto err_out_free_res; + goto err_out_netdev; for (i = 0; i < 3; i++) ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(eeprom_read(ioaddr, i)); @@ -468,8 +468,6 @@ err_out_cleardev: pci_iounmap(pdev, ioaddr); -err_out_free_res: - pci_release_regions(pdev); err_out_netdev: free_netdev (dev); return -ENODEV; @@ -1535,7 +1533,6 @@ if (dev) { struct netdev_private *np = netdev_priv(dev); unregister_netdev(dev); - pci_release_regions(pdev); pci_iounmap(pdev, np->base_addr); free_netdev(dev); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/dnet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/dnet.c @@ -553,11 +553,11 @@ skb_tx_timestamp(skb); + spin_unlock_irqrestore(&bp->lock, flags); + /* free the buffer */ dev_kfree_skb(skb); - spin_unlock_irqrestore(&bp->lock, flags); - return NETDEV_TX_OK; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ec_bhf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ec_bhf.c @@ -576,10 +576,12 @@ struct ec_bhf_priv *priv = netdev_priv(net_dev); unregister_netdev(net_dev); - free_netdev(net_dev); pci_iounmap(dev, priv->dma_io); pci_iounmap(dev, priv->io); + + free_netdev(net_dev); + pci_release_regions(dev); pci_clear_master(dev); pci_disable_device(dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/emulex/benet/be.h +++ linux-oracle-5.4.0/drivers/net/ethernet/emulex/benet/be.h @@ -564,7 +564,7 @@ struct be_dma_mem mbox_mem_alloced; struct be_mcc_obj mcc_obj; - struct mutex mcc_lock; /* For serializing mcc cmds to BE card */ + spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ spinlock_t mcc_cq_lock; u16 cfg_num_rx_irqs; /* configured via set-channels */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/emulex/benet/be_cmds.c +++ linux-oracle-5.4.0/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -550,7 +550,7 @@ int num = 0, status = 0; struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; - spin_lock_bh(&adapter->mcc_cq_lock); + spin_lock(&adapter->mcc_cq_lock); while ((compl = be_mcc_compl_get(adapter))) { if (compl->flags & CQE_FLAGS_ASYNC_MASK) { @@ -566,14 +566,14 @@ if (num) be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); - spin_unlock_bh(&adapter->mcc_cq_lock); + spin_unlock(&adapter->mcc_cq_lock); return status; } /* Wait till no more pending mcc requests are present */ static int be_mcc_wait_compl(struct be_adapter *adapter) { -#define mcc_timeout 12000 /* 12s timeout */ +#define mcc_timeout 120000 /* 12s timeout */ int i, status = 0; struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; @@ -581,11 +581,13 @@ if (be_check_error(adapter, BE_ERROR_ANY)) return -EIO; + local_bh_disable(); status = be_process_mcc(adapter); + local_bh_enable(); if (atomic_read(&mcc_obj->q.used) == 0) break; - usleep_range(500, 1000); + udelay(100); } if (i == mcc_timeout) { dev_err(&adapter->pdev->dev, "FW not responding\n"); @@ -863,7 +865,7 @@ static int be_cmd_lock(struct be_adapter *adapter) { if (use_mcc(adapter)) { - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); return 0; } else { return mutex_lock_interruptible(&adapter->mbox_lock); @@ -874,7 +876,7 @@ static void be_cmd_unlock(struct be_adapter *adapter) { if (use_mcc(adapter)) - return mutex_unlock(&adapter->mcc_lock); + return spin_unlock_bh(&adapter->mcc_lock); else return mutex_unlock(&adapter->mbox_lock); } @@ -1044,7 +1046,7 @@ struct be_cmd_req_mac_query *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1073,7 +1075,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1085,7 +1087,7 @@ struct be_cmd_req_pmac_add *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1110,7 +1112,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); if (base_status(status) == MCC_STATUS_UNAUTHORIZED_REQUEST) status = -EPERM; @@ -1128,7 +1130,7 @@ if (pmac_id == -1) return 0; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1148,7 +1150,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1411,7 +1413,7 @@ struct be_dma_mem *q_mem = &rxq->dma_mem; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1441,7 +1443,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1505,7 +1507,7 @@ struct be_cmd_req_q_destroy *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1522,7 +1524,7 @@ q->created = false; err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1590,7 +1592,7 @@ struct be_cmd_req_hdr *hdr; int status = 0; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1618,7 +1620,7 @@ adapter->stats_cmd_sent = true; err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1634,7 +1636,7 @@ CMD_SUBSYSTEM_ETH)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1657,7 +1659,7 @@ adapter->stats_cmd_sent = true; err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1694,7 +1696,7 @@ struct be_cmd_req_link_status *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); if (link_status) *link_status = LINK_DOWN; @@ -1733,7 +1735,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1744,7 +1746,7 @@ struct be_cmd_req_get_cntl_addnl_attribs *req; int status = 0; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1759,7 +1761,7 @@ status = be_mcc_notify(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1808,7 +1810,7 @@ if (!get_fat_cmd.va) return -ENOMEM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); while (total_size) { buf_size = min(total_size, (u32)60*1024); @@ -1846,9 +1848,9 @@ log_offset += buf_size; } err: + spin_unlock_bh(&adapter->mcc_lock); dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size, get_fat_cmd.va, get_fat_cmd.dma); - mutex_unlock(&adapter->mcc_lock); return status; } @@ -1859,7 +1861,7 @@ struct be_cmd_req_get_fw_version *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1882,7 +1884,7 @@ sizeof(adapter->fw_on_flash)); } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1896,7 +1898,7 @@ struct be_cmd_req_modify_eq_delay *req; int status = 0, i; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1919,7 +1921,7 @@ status = be_mcc_notify(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1946,7 +1948,7 @@ struct be_cmd_req_vlan_config *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -1968,7 +1970,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -1979,7 +1981,7 @@ struct be_cmd_req_rx_filter *req = mem->va; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2012,7 +2014,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2043,7 +2045,7 @@ CMD_SUBSYSTEM_COMMON)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2063,7 +2065,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED) return -EOPNOTSUPP; @@ -2082,7 +2084,7 @@ CMD_SUBSYSTEM_COMMON)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2105,7 +2107,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2186,7 +2188,7 @@ if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS)) return 0; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2211,7 +2213,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2223,7 +2225,7 @@ struct be_cmd_req_enable_disable_beacon *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2244,7 +2246,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2255,7 +2257,7 @@ struct be_cmd_req_get_beacon_state *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2279,13 +2281,13 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } /* Uses sync mcc */ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, - u8 page_num, u8 *data) + u8 page_num, u32 off, u32 len, u8 *data) { struct be_dma_mem cmd; struct be_mcc_wrb *wrb; @@ -2303,7 +2305,7 @@ return -ENOMEM; } - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2319,13 +2321,13 @@ req->port = cpu_to_le32(adapter->hba_port_num); req->page_num = cpu_to_le32(page_num); status = be_mcc_notify_wait(adapter); - if (!status) { + if (!status && len > 0) { struct be_cmd_resp_port_type *resp = cmd.va; - memcpy(data, resp->page_data, PAGE_DATA_LEN); + memcpy(data, resp->page_data + off, len); } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); return status; } @@ -2342,7 +2344,7 @@ void *ctxt = NULL; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); adapter->flash_status = 0; wrb = wrb_from_mccq(adapter); @@ -2384,7 +2386,7 @@ if (status) goto err_unlock; - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); if (!wait_for_completion_timeout(&adapter->et_cmd_compl, msecs_to_jiffies(60000))) @@ -2403,7 +2405,7 @@ return status; err_unlock: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2413,7 +2415,7 @@ int status; status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, - page_data); + 0, PAGE_DATA_LEN, page_data); if (!status) { switch (adapter->phy.interface_type) { case PHY_TYPE_QSFP: @@ -2438,7 +2440,7 @@ int status; status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, - page_data); + 0, PAGE_DATA_LEN, page_data); if (!status) { strlcpy(adapter->phy.vendor_name, page_data + SFP_VENDOR_NAME_OFFSET, SFP_VENDOR_NAME_LEN - 1); @@ -2457,7 +2459,7 @@ struct be_mcc_wrb *wrb; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2475,7 +2477,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2488,7 +2490,7 @@ struct lancer_cmd_resp_read_object *resp; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2522,7 +2524,7 @@ } err_unlock: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2534,7 +2536,7 @@ struct be_cmd_write_flashrom *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); adapter->flash_status = 0; wrb = wrb_from_mccq(adapter); @@ -2559,7 +2561,7 @@ if (status) goto err_unlock; - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); if (!wait_for_completion_timeout(&adapter->et_cmd_compl, msecs_to_jiffies(40000))) @@ -2570,7 +2572,7 @@ return status; err_unlock: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -2581,7 +2583,7 @@ struct be_mcc_wrb *wrb; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -2608,7 +2610,7 @@ memcpy(flashed_crc, req->crc, 4); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3214,7 +3216,7 @@ struct be_cmd_req_acpi_wol_magic_config *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3231,7 +3233,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3246,7 +3248,7 @@ CMD_SUBSYSTEM_LOWLEVEL)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3269,7 +3271,7 @@ if (status) goto err_unlock; - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); if (!wait_for_completion_timeout(&adapter->et_cmd_compl, msecs_to_jiffies(SET_LB_MODE_TIMEOUT))) @@ -3278,7 +3280,7 @@ return status; err_unlock: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3295,7 +3297,7 @@ CMD_SUBSYSTEM_LOWLEVEL)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3321,7 +3323,7 @@ if (status) goto err; - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); wait_for_completion(&adapter->et_cmd_compl); resp = embedded_payload(wrb); @@ -3329,7 +3331,7 @@ return status; err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3345,7 +3347,7 @@ CMD_SUBSYSTEM_LOWLEVEL)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3379,7 +3381,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3390,7 +3392,7 @@ struct be_cmd_req_seeprom_read *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3406,7 +3408,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3421,7 +3423,7 @@ CMD_SUBSYSTEM_COMMON)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3466,7 +3468,7 @@ } dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3476,7 +3478,7 @@ struct be_cmd_req_set_qos *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3496,7 +3498,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3608,7 +3610,7 @@ struct be_cmd_req_get_fn_privileges *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3640,7 +3642,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3652,7 +3654,7 @@ struct be_cmd_req_set_fn_privileges *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3672,7 +3674,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3704,7 +3706,7 @@ return -ENOMEM; } - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3768,7 +3770,7 @@ } out: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size, get_mac_list_cmd.va, get_mac_list_cmd.dma); return status; @@ -3828,7 +3830,7 @@ if (!cmd.va) return -ENOMEM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3850,7 +3852,7 @@ err: dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3886,7 +3888,7 @@ CMD_SUBSYSTEM_COMMON)) return -EPERM; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3927,7 +3929,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -3941,7 +3943,7 @@ int status; u16 vid; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -3988,7 +3990,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4187,7 +4189,7 @@ struct be_cmd_req_set_ext_fat_caps *req; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -4203,7 +4205,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4681,7 +4683,7 @@ if (iface == 0xFFFFFFFF) return -1; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -4698,7 +4700,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4732,7 +4734,7 @@ struct be_cmd_resp_get_iface_list *resp; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -4753,7 +4755,7 @@ } err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4847,7 +4849,7 @@ if (BEx_chip(adapter)) return 0; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -4865,7 +4867,7 @@ req->enable = 1; status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4938,7 +4940,7 @@ u32 link_config = 0; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -4966,7 +4968,7 @@ status = be_mcc_notify_wait(adapter); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -4997,8 +4999,7 @@ struct be_mcc_wrb *wrb; int status; - if (mutex_lock_interruptible(&adapter->mcc_lock)) - return -1; + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -5036,7 +5037,7 @@ dev_info(&adapter->pdev->dev, "Adapter does not support HW error recovery\n"); - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } @@ -5050,7 +5051,7 @@ struct be_cmd_resp_hdr *resp; int status; - mutex_lock(&adapter->mcc_lock); + spin_lock_bh(&adapter->mcc_lock); wrb = wrb_from_mccq(adapter); if (!wrb) { @@ -5073,7 +5074,7 @@ memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length); be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length); err: - mutex_unlock(&adapter->mcc_lock); + spin_unlock_bh(&adapter->mcc_lock); return status; } EXPORT_SYMBOL(be_roce_mcc_cmd); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/emulex/benet/be_cmds.h +++ linux-oracle-5.4.0/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -2427,7 +2427,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state); int be_cmd_read_port_transceiver_data(struct be_adapter *adapter, - u8 page_num, u8 *data); + u8 page_num, u32 off, u32 len, u8 *data); int be_cmd_query_cable_type(struct be_adapter *adapter); int be_cmd_query_sfp_info(struct be_adapter *adapter); int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -1339,7 +1339,7 @@ return -EOPNOTSUPP; status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, - page_data); + 0, PAGE_DATA_LEN, page_data); if (!status) { if (!page_data[SFP_PLUS_SFF_8472_COMP]) { modinfo->type = ETH_MODULE_SFF_8079; @@ -1357,25 +1357,32 @@ { struct be_adapter *adapter = netdev_priv(netdev); int status; + u32 begin, end; if (!check_privilege(adapter, MAX_PRIVILEGES)) return -EOPNOTSUPP; - status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, - data); - if (status) - goto err; - - if (eeprom->offset + eeprom->len > PAGE_DATA_LEN) { - status = be_cmd_read_port_transceiver_data(adapter, - TR_PAGE_A2, - data + - PAGE_DATA_LEN); + begin = eeprom->offset; + end = eeprom->offset + eeprom->len; + + if (begin < PAGE_DATA_LEN) { + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A0, begin, + min_t(u32, end, PAGE_DATA_LEN) - begin, + data); + if (status) + goto err; + + data += PAGE_DATA_LEN - begin; + begin = PAGE_DATA_LEN; + } + + if (end > PAGE_DATA_LEN) { + status = be_cmd_read_port_transceiver_data(adapter, TR_PAGE_A2, + begin - PAGE_DATA_LEN, + end - begin, data); if (status) goto err; } - if (eeprom->offset) - memcpy(data, data + eeprom->offset, eeprom->len); err: return be_cmd_status(status); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/emulex/benet/be_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/emulex/benet/be_main.c @@ -1137,10 +1137,11 @@ eth_hdr_len = ntohs(skb->protocol) == ETH_P_8021Q ? VLAN_ETH_HLEN : ETH_HLEN; if (skb->len <= 60 && - (lancer_chip(adapter) || skb_vlan_tag_present(skb)) && - is_ipv4_pkt(skb)) { + (lancer_chip(adapter) || BE3_chip(adapter) || + skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { ip = (struct iphdr *)ip_hdr(skb); - pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); + if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)))) + goto tx_drop; } /* If vlan tag is already inlined in the packet, skip HW VLAN @@ -1382,10 +1383,8 @@ be_get_wrb_params_from_skb(adapter, skb, &wrb_params); wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); - if (unlikely(!wrb_cnt)) { - dev_kfree_skb_any(skb); - goto drop; - } + if (unlikely(!wrb_cnt)) + goto drop_skb; /* if os2bmc is enabled and if the pkt is destined to bmc, * enqueue the pkt a 2nd time with mgmt bit set. @@ -1394,7 +1393,7 @@ BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); if (unlikely(!wrb_cnt)) - goto drop; + goto drop_skb; else skb_get(skb); } @@ -1408,6 +1407,8 @@ be_xmit_flush(adapter, txo); return NETDEV_TX_OK; +drop_skb: + dev_kfree_skb_any(skb); drop: tx_stats(txo)->tx_drv_drops++; /* Flush the already enqueued tx requests */ @@ -5631,7 +5632,9 @@ * mcc completions */ if (!netif_running(adapter->netdev)) { + local_bh_disable(); be_process_mcc(adapter); + local_bh_enable(); goto reschedule; } @@ -5800,8 +5803,8 @@ } mutex_init(&adapter->mbox_lock); - mutex_init(&adapter->mcc_lock); mutex_init(&adapter->rx_filter_lock); + spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_cq_lock); init_completion(&adapter->et_cmd_compl); @@ -6030,6 +6033,7 @@ unmap_bars: be_unmap_pci_bars(adapter); free_netdev: + pci_disable_pcie_error_reporting(pdev); free_netdev(netdev); rel_reg: pci_release_regions(pdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ethoc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ethoc.c @@ -1207,7 +1207,7 @@ ret = mdiobus_register(priv->mdio); if (ret) { dev_err(&netdev->dev, "failed to register MDIO bus\n"); - goto free2; + goto free3; } ret = ethoc_mdio_probe(netdev); @@ -1239,6 +1239,7 @@ netif_napi_del(&priv->napi); error: mdiobus_unregister(priv->mdio); +free3: mdiobus_free(priv->mdio); free2: clk_disable_unprepare(priv->clk); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ezchip/nps_enet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ezchip/nps_enet.c @@ -610,7 +610,7 @@ /* Get IRQ number */ priv->irq = platform_get_irq(pdev, 0); - if (!priv->irq) { + if (priv->irq < 0) { dev_err(dev, "failed to retrieve value from device tree\n"); err = -ENODEV; goto out_netdev; @@ -645,8 +645,8 @@ struct nps_enet_priv *priv = netdev_priv(ndev); unregister_netdev(ndev); - free_netdev(ndev); netif_napi_del(&priv->napi); + free_netdev(ndev); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/faraday/ftgmac100.c +++ linux-oracle-5.4.0/drivers/net/ethernet/faraday/ftgmac100.c @@ -567,7 +567,7 @@ (*processed)++; return true; - drop: +drop: /* Clean rxdes0 (which resets own bit) */ rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask); priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); @@ -651,6 +651,11 @@ ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat); txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); + /* Ensure the descriptor config is visible before setting the tx + * pointer. + */ + smp_wmb(); + priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer); return true; @@ -804,6 +809,11 @@ dma_wmb(); first->txdes0 = cpu_to_le32(f_ctl_stat); + /* Ensure the descriptor config is visible before setting the tx + * pointer. + */ + smp_wmb(); + /* Update next TX pointer */ priv->tx_pointer = pointer; @@ -824,7 +834,7 @@ return NETDEV_TX_OK; - dma_err: +dma_err: if (net_ratelimit()) netdev_err(netdev, "map tx fragment failed\n"); @@ -846,7 +856,7 @@ * last fragment, so we know ftgmac100_free_tx_packet() * hasn't freed the skb yet. */ - drop: +drop: /* Drop the packet */ dev_kfree_skb_any(skb); netdev->stats.tx_dropped++; @@ -1307,6 +1317,7 @@ */ if (unlikely(priv->need_mac_restart)) { ftgmac100_start_hw(priv); + priv->need_mac_restart = false; /* Re-enable "bad" interrupts */ iowrite32(FTGMAC100_INT_BAD, @@ -1417,7 +1428,7 @@ ftgmac100_init_all(priv, true); netdev_dbg(netdev, "Reset done !\n"); - bail: +bail: if (priv->mii_bus) mutex_unlock(&priv->mii_bus->mdio_lock); if (netdev->phydev) @@ -1488,15 +1499,15 @@ return 0; - err_ncsi: +err_ncsi: napi_disable(&priv->napi); netif_stop_queue(netdev); - err_alloc: +err_alloc: ftgmac100_free_buffers(priv); free_irq(netdev->irq, netdev); - err_irq: +err_irq: netif_napi_del(&priv->napi); - err_hw: +err_hw: iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); ftgmac100_free_rings(priv); return err; @@ -1733,6 +1744,19 @@ FTGMAC_100MHZ); } +static bool ftgmac100_has_child_node(struct device_node *np, const char *name) +{ + struct device_node *child_np = of_get_child_by_name(np, name); + bool ret = false; + + if (child_np) { + ret = true; + of_node_put(child_np); + } + + return ret; +} + static int ftgmac100_probe(struct platform_device *pdev) { struct resource *res; @@ -1807,6 +1831,11 @@ priv->rxdes0_edorr_mask = BIT(30); priv->txdes0_edotr_mask = BIT(30); priv->is_aspeed = true; + /* Disable ast2600 problematic HW arbitration */ + if (of_device_is_compatible(np, "aspeed,ast2600-mac")) { + iowrite32(FTGMAC100_TM_DEFAULT, + priv->base + FTGMAC100_OFFSET_TM); + } } else { priv->rxdes0_edorr_mask = BIT(15); priv->txdes0_edotr_mask = BIT(15); @@ -1815,14 +1844,17 @@ if (np && of_get_property(np, "use-ncsi", NULL)) { if (!IS_ENABLED(CONFIG_NET_NCSI)) { dev_err(&pdev->dev, "NCSI stack not enabled\n"); + err = -EINVAL; goto err_ncsi_dev; } dev_info(&pdev->dev, "Using NCSI interface\n"); priv->use_ncsi = true; priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); - if (!priv->ndev) + if (!priv->ndev) { + err = -EINVAL; goto err_ncsi_dev; + } } else if (np && of_get_property(np, "phy-handle", NULL)) { struct phy_device *phy; @@ -1830,6 +1862,7 @@ &ftgmac100_adjust_link); if (!phy) { dev_err(&pdev->dev, "Failed to connect to phy\n"); + err = -EINVAL; goto err_setup_mdio; } @@ -1840,7 +1873,7 @@ /* Display what we found */ phy_attached_info(phy); - } else if (np && !of_get_child_by_name(np, "mdio")) { + } else if (np && !ftgmac100_has_child_node(np, "mdio")) { /* Support legacy ASPEED devicetree descriptions that decribe a * MAC with an embedded MDIO controller but have no "mdio" * child node. Automatically scan the MDIO bus for available @@ -1870,6 +1903,11 @@ /* AST2400 doesn't have working HW checksum generation */ if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac"))) netdev->hw_features &= ~NETIF_F_HW_CSUM; + + /* AST2600 tx checksum with NCSI is broken */ + if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac")) + netdev->hw_features &= ~NETIF_F_HW_CSUM; + if (np && of_get_property(np, "no-hw-checksum", NULL)) netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); netdev->features |= netdev->hw_features; @@ -1886,6 +1924,8 @@ return 0; err_ncsi_dev: + if (priv->ndev) + ncsi_unregister_dev(priv->ndev); err_register_netdev: ftgmac100_destroy_mdio(netdev); err_setup_mdio: @@ -1906,6 +1946,8 @@ netdev = platform_get_drvdata(pdev); priv = netdev_priv(netdev); + if (priv->ndev) + ncsi_unregister_dev(priv->ndev); unregister_netdev(netdev); clk_disable_unprepare(priv->clk); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/faraday/ftgmac100.h +++ linux-oracle-5.4.0/drivers/net/ethernet/faraday/ftgmac100.h @@ -84,7 +84,7 @@ FTGMAC100_INT_RPKT_BUF) /* All the interrupts we care about */ -#define FTGMAC100_INT_ALL (FTGMAC100_INT_RPKT_BUF | \ +#define FTGMAC100_INT_ALL (FTGMAC100_INT_RXTX | \ FTGMAC100_INT_BAD) /* @@ -170,6 +170,14 @@ #define FTGMAC100_MACCR_SW_RST (1 << 31) /* + * test mode control register + */ +#define FTGMAC100_TM_RQ_TX_VALID_DIS (1 << 28) +#define FTGMAC100_TM_RQ_RR_IDLE_PREV (1 << 27) +#define FTGMAC100_TM_DEFAULT \ + (FTGMAC100_TM_RQ_TX_VALID_DIS | FTGMAC100_TM_RQ_RR_IDLE_PREV) + +/* * PHY control register */ #define FTGMAC100_PHYCR_MDC_CYCTHR_MASK 0x3f --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/Kconfig @@ -77,6 +77,7 @@ depends on QUICC_ENGINE select FSL_PQ_MDIO select PHYLIB + select FIXED_PHY ---help--- This driver supports the Gigabit Ethernet mode of the QUICC Engine, which is available on some Freescale SOCs. @@ -90,6 +91,7 @@ depends on HAS_DMA select FSL_PQ_MDIO select PHYLIB + select FIXED_PHY select CRC32 ---help--- This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa/Kconfig @@ -3,6 +3,7 @@ tristate "DPAA Ethernet" depends on FSL_DPAA && FSL_FMAN select PHYLIB + select FIXED_PHY select FSL_FMAN_MAC ---help--- Data Path Acceleration Architecture Ethernet driver, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -1600,13 +1600,15 @@ * Skb freeing is not handled here. * * This function may be called on error paths in the Tx function, so guard - * against cases when not all fd relevant fields were filled in. + * against cases when not all fd relevant fields were filled in. To avoid + * reading the invalid transmission timestamp for the error paths set ts to + * false. * * Return the skb backpointer, since for S/G frames the buffer containing it * gets freed here. */ static struct sk_buff *dpaa_cleanup_tx_fd(const struct dpaa_priv *priv, - const struct qm_fd *fd) + const struct qm_fd *fd, bool ts) { const enum dma_data_direction dma_dir = DMA_TO_DEVICE; struct device *dev = priv->net_dev->dev.parent; @@ -1620,18 +1622,6 @@ skbh = (struct sk_buff **)phys_to_virt(addr); skb = *skbh; - if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { - memset(&shhwtstamps, 0, sizeof(shhwtstamps)); - - if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh, - &ns)) { - shhwtstamps.hwtstamp = ns_to_ktime(ns); - skb_tstamp_tx(skb, &shhwtstamps); - } else { - dev_warn(dev, "fman_port_get_tstamp failed!\n"); - } - } - if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) { nr_frags = skb_shinfo(skb)->nr_frags; dma_unmap_single(dev, addr, @@ -1654,14 +1644,29 @@ dma_unmap_page(dev, qm_sg_addr(&sgt[i]), qm_sg_entry_get_len(&sgt[i]), dma_dir); } - - /* Free the page frag that we allocated on Tx */ - skb_free_frag(phys_to_virt(addr)); } else { dma_unmap_single(dev, addr, skb_tail_pointer(skb) - (u8 *)skbh, dma_dir); } + /* DMA unmapping is required before accessing the HW provided info */ + if (ts && priv->tx_tstamp && + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + + if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh, + &ns)) { + shhwtstamps.hwtstamp = ns_to_ktime(ns); + skb_tstamp_tx(skb, &shhwtstamps); + } else { + dev_warn(dev, "fman_port_get_tstamp failed!\n"); + } + } + + if (qm_fd_get_format(fd) == qm_fd_sg) + /* Free the page frag that we allocated on Tx */ + skb_free_frag(phys_to_virt(addr)); + return skb; } @@ -2048,12 +2053,12 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) { const int queue_mapping = skb_get_queue_mapping(skb); - bool nonlinear = skb_is_nonlinear(skb); struct rtnl_link_stats64 *percpu_stats; struct dpaa_percpu_priv *percpu_priv; struct netdev_queue *txq; struct dpaa_priv *priv; struct qm_fd fd; + bool nonlinear; int offset = 0; int err = 0; @@ -2063,6 +2068,13 @@ qm_fd_clear_fd(&fd); + /* Packet data is always read as 32-bit words, so zero out any part of + * the skb which might be sent if we have to pad the packet + */ + if (__skb_put_padto(skb, ETH_ZLEN, false)) + goto enomem; + + nonlinear = skb_is_nonlinear(skb); if (!nonlinear) { /* We're going to store the skb backpointer at the beginning * of the data buffer, so we need a privately owned skb @@ -2114,7 +2126,7 @@ if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0)) return NETDEV_TX_OK; - dpaa_cleanup_tx_fd(priv, &fd); + dpaa_cleanup_tx_fd(priv, &fd, false); skb_to_fd_failed: enomem: percpu_stats->tx_errors++; @@ -2160,7 +2172,7 @@ percpu_priv->stats.tx_errors++; - skb = dpaa_cleanup_tx_fd(priv, fd); + skb = dpaa_cleanup_tx_fd(priv, fd, false); dev_kfree_skb(skb); } @@ -2200,7 +2212,7 @@ percpu_priv->tx_confirm++; - skb = dpaa_cleanup_tx_fd(priv, fd); + skb = dpaa_cleanup_tx_fd(priv, fd, true); consume_skb(skb); } @@ -2430,7 +2442,7 @@ percpu_priv->stats.tx_fifo_errors++; count_ern(percpu_priv, msg); - skb = dpaa_cleanup_tx_fd(priv, fd); + skb = dpaa_cleanup_tx_fd(priv, fd, false); dev_kfree_skb_any(skb); } @@ -2478,6 +2490,9 @@ mac_dev->adjust_link(mac_dev); } +/* The Aquantia PHYs are capable of performing rate adaptation */ +#define PHY_VEND_AQUANTIA 0x03a1b400 + static int dpaa_phy_init(struct net_device *net_dev) { __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; @@ -2496,9 +2511,14 @@ return -ENODEV; } - /* Remove any features not supported by the controller */ - ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support); - linkmode_and(phy_dev->supported, phy_dev->supported, mask); + /* Unless the PHY is capable of rate adaptation */ + if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII || + ((phy_dev->drv->phy_id & GENMASK(31, 10)) != PHY_VEND_AQUANTIA)) { + /* remove any features not supported by the controller */ + ethtool_convert_legacy_u32_to_link_mode(mask, + mac_dev->if_support); + linkmode_and(phy_dev->supported, phy_dev->supported, mask); + } phy_support_asym_pause(phy_dev); @@ -2757,9 +2777,7 @@ headroom = (u16)(bl->priv_data_size + DPAA_PARSE_RESULTS_SIZE + DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE); - return DPAA_FD_DATA_ALIGNMENT ? ALIGN(headroom, - DPAA_FD_DATA_ALIGNMENT) : - headroom; + return ALIGN(headroom, DPAA_FD_DATA_ALIGNMENT); } static int dpaa_eth_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -506,11 +506,15 @@ info->phc_index = -1; fman_node = of_get_parent(mac_node); - if (fman_node) + if (fman_node) { ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0); + of_node_put(fman_node); + } - if (ptp_node) + if (ptp_node) { ptp_dev = of_find_device_by_node(ptp_node); + of_node_put(ptp_node); + } if (ptp_dev) ptp = platform_get_drvdata(ptp_dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -86,7 +86,7 @@ for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) { addr = dpaa2_sg_get_addr(&sgt[i]); sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); - dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, + dma_unmap_page(dev, addr, priv->rx_buf_size, DMA_BIDIRECTIONAL); free_pages((unsigned long)sg_vaddr, 0); @@ -144,7 +144,7 @@ /* Get the address and length from the S/G entry */ sg_addr = dpaa2_sg_get_addr(sge); sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, sg_addr); - dma_unmap_page(dev, sg_addr, DPAA2_ETH_RX_BUF_SIZE, + dma_unmap_page(dev, sg_addr, priv->rx_buf_size, DMA_BIDIRECTIONAL); sg_length = dpaa2_sg_get_len(sge); @@ -185,7 +185,7 @@ (page_address(page) - page_address(head_page)); skb_add_rx_frag(skb, i - 1, head_page, page_offset, - sg_length, DPAA2_ETH_RX_BUF_SIZE); + sg_length, priv->rx_buf_size); } if (dpaa2_sg_is_final(sge)) @@ -211,7 +211,7 @@ for (i = 0; i < count; i++) { vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]); - dma_unmap_page(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE, + dma_unmap_page(dev, buf_array[i], priv->rx_buf_size, DMA_BIDIRECTIONAL); free_pages((unsigned long)vaddr, 0); } @@ -331,7 +331,7 @@ break; case XDP_REDIRECT: dma_unmap_page(priv->net_dev->dev.parent, addr, - DPAA2_ETH_RX_BUF_SIZE, DMA_BIDIRECTIONAL); + priv->rx_buf_size, DMA_BIDIRECTIONAL); ch->buf_count--; xdp.data_hard_start = vaddr; err = xdp_do_redirect(priv->net_dev, &xdp, xdp_prog); @@ -370,7 +370,7 @@ trace_dpaa2_rx_fd(priv->net_dev, fd); vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr); - dma_sync_single_for_cpu(dev, addr, DPAA2_ETH_RX_BUF_SIZE, + dma_sync_single_for_cpu(dev, addr, priv->rx_buf_size, DMA_BIDIRECTIONAL); fas = dpaa2_get_fas(vaddr, false); @@ -389,13 +389,13 @@ return; } - dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, + dma_unmap_page(dev, addr, priv->rx_buf_size, DMA_BIDIRECTIONAL); skb = build_linear_skb(ch, fd, vaddr); } else if (fd_format == dpaa2_fd_sg) { WARN_ON(priv->xdp_prog); - dma_unmap_page(dev, addr, DPAA2_ETH_RX_BUF_SIZE, + dma_unmap_page(dev, addr, priv->rx_buf_size, DMA_BIDIRECTIONAL); skb = build_frag_skb(priv, ch, buf_data); free_pages((unsigned long)vaddr, 0); @@ -963,7 +963,7 @@ if (!page) goto err_alloc; - addr = dma_map_page(dev, page, 0, DPAA2_ETH_RX_BUF_SIZE, + addr = dma_map_page(dev, page, 0, priv->rx_buf_size, DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(dev, addr))) goto err_map; @@ -971,9 +971,9 @@ buf_array[i] = addr; /* tracing point */ - trace_dpaa2_eth_buf_seed(priv->net_dev, - page, DPAA2_ETH_RX_BUF_RAW_SIZE, - addr, DPAA2_ETH_RX_BUF_SIZE, + trace_dpaa2_eth_buf_seed(priv->net_dev, page_address(page), + DPAA2_ETH_RX_BUF_RAW_SIZE, + addr, priv->rx_buf_size, bpid); } @@ -1680,7 +1680,7 @@ int mfl, linear_mfl; mfl = DPAA2_ETH_L2_MAX_FRM(mtu); - linear_mfl = DPAA2_ETH_RX_BUF_SIZE - DPAA2_ETH_RX_HWA_SIZE - + linear_mfl = priv->rx_buf_size - DPAA2_ETH_RX_HWA_SIZE - dpaa2_eth_rx_head_room(priv) - XDP_PACKET_HEADROOM; if (mfl > linear_mfl) { @@ -1945,11 +1945,14 @@ static int update_xps(struct dpaa2_eth_priv *priv) { struct net_device *net_dev = priv->net_dev; - struct cpumask xps_mask; - struct dpaa2_eth_fq *fq; int i, num_queues, netdev_queues; + struct dpaa2_eth_fq *fq; + cpumask_var_t xps_mask; int err = 0; + if (!alloc_cpumask_var(&xps_mask, GFP_KERNEL)) + return -ENOMEM; + num_queues = dpaa2_eth_queue_count(priv); netdev_queues = (net_dev->num_tc ? : 1) * num_queues; @@ -1959,16 +1962,17 @@ for (i = 0; i < netdev_queues; i++) { fq = &priv->fq[i % num_queues]; - cpumask_clear(&xps_mask); - cpumask_set_cpu(fq->target_cpu, &xps_mask); + cpumask_clear(xps_mask); + cpumask_set_cpu(fq->target_cpu, xps_mask); - err = netif_set_xps_queue(net_dev, &xps_mask, i); + err = netif_set_xps_queue(net_dev, xps_mask, i); if (err) { netdev_warn_once(net_dev, "Error setting XPS queue\n"); break; } } + free_cpumask_var(xps_mask); return err; } @@ -1981,7 +1985,7 @@ int i; if (type != TC_SETUP_QDISC_MQPRIO) - return -EINVAL; + return -EOPNOTSUPP; mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS; num_queues = dpaa2_eth_queue_count(priv); @@ -1993,7 +1997,7 @@ if (num_tc > dpaa2_eth_tc_count(priv)) { netdev_err(net_dev, "Max %d traffic classes supported\n", dpaa2_eth_tc_count(priv)); - return -EINVAL; + return -EOPNOTSUPP; } if (!num_tc) { @@ -2090,7 +2094,7 @@ free: fsl_mc_object_free(dpcon); - return NULL; + return ERR_PTR(err); } static void free_dpcon(struct dpaa2_eth_priv *priv, @@ -2114,8 +2118,8 @@ return NULL; channel->dpcon = setup_dpcon(priv); - if (IS_ERR_OR_NULL(channel->dpcon)) { - err = PTR_ERR_OR_ZERO(channel->dpcon); + if (IS_ERR(channel->dpcon)) { + err = PTR_ERR(channel->dpcon); goto err_setup; } @@ -2432,6 +2436,11 @@ else rx_buf_align = DPAA2_ETH_RX_BUF_ALIGN; + /* We need to ensure that the buffer size seen by WRIOP is a multiple + * of 64 or 256 bytes depending on the WRIOP version. + */ + priv->rx_buf_size = ALIGN_DOWN(DPAA2_ETH_RX_BUF_SIZE, rx_buf_align); + /* tx buffer */ buf_layout.private_data_size = DPAA2_ETH_SWA_SIZE; buf_layout.pass_timestamp = true; @@ -2649,8 +2658,10 @@ priv->cls_rules = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) * dpaa2_eth_fs_count(priv), GFP_KERNEL); - if (!priv->cls_rules) + if (!priv->cls_rules) { + err = -ENOMEM; goto close; + } return 0; @@ -3096,7 +3107,7 @@ pools_params.num_dpbp = 1; pools_params.pools[0].dpbp_id = priv->dpbp_dev->obj_desc.id; pools_params.pools[0].backup_pool = 0; - pools_params.pools[0].buffer_size = DPAA2_ETH_RX_BUF_SIZE; + pools_params.pools[0].buffer_size = priv->rx_buf_size; err = dpni_set_pools(priv->mc_io, 0, priv->mc_token, &pools_params); if (err) { dev_err(dev, "dpni_set_pools() failed\n"); @@ -3609,10 +3620,10 @@ fsl_mc_portal_free(priv->mc_io); - free_netdev(net_dev); - dev_dbg(net_dev->dev.parent, "Removed interface %s\n", net_dev->name); + free_netdev(net_dev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h @@ -373,6 +373,7 @@ u16 tx_data_offset; struct fsl_mc_device *dpbp_dev; + u16 rx_buf_size; u16 bpid; struct iommu_domain *iommu_domain; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c @@ -216,7 +216,7 @@ if (err == -EINVAL) /* Older firmware versions don't support all pages */ memset(&dpni_stats, 0, sizeof(dpni_stats)); - else + else if (err) netdev_warn(net_dev, "dpni_get_stats(%d) failed\n", j); num_cnt = dpni_stats_page_size[j] / sizeof(u64); @@ -590,7 +590,7 @@ static int update_cls_rule(struct net_device *net_dev, struct ethtool_rx_flow_spec *new_fs, - int location) + unsigned int location) { struct dpaa2_eth_priv *priv = netdev_priv(net_dev); struct dpaa2_eth_cls_rule *rule; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c @@ -148,7 +148,7 @@ base = of_iomap(node, 0); if (!base) { err = -ENOMEM; - goto err_close; + goto err_put; } err = fsl_mc_allocate_irqs(mc_dev); @@ -160,10 +160,10 @@ irq = mc_dev->irqs[0]; ptp_qoriq->irq = irq->msi_desc->irq; - err = devm_request_threaded_irq(dev, ptp_qoriq->irq, NULL, - dpaa2_ptp_irq_handler_thread, - IRQF_NO_SUSPEND | IRQF_ONESHOT, - dev_name(dev), ptp_qoriq); + err = request_threaded_irq(ptp_qoriq->irq, NULL, + dpaa2_ptp_irq_handler_thread, + IRQF_NO_SUSPEND | IRQF_ONESHOT, + dev_name(dev), ptp_qoriq); if (err < 0) { dev_err(dev, "devm_request_threaded_irq(): %d\n", err); goto err_free_mc_irq; @@ -173,22 +173,26 @@ DPRTC_IRQ_INDEX, 1); if (err < 0) { dev_err(dev, "dprtc_set_irq_enable(): %d\n", err); - goto err_free_mc_irq; + goto err_free_threaded_irq; } err = ptp_qoriq_init(ptp_qoriq, base, &dpaa2_ptp_caps); if (err) - goto err_free_mc_irq; + goto err_free_threaded_irq; dpaa2_phc_index = ptp_qoriq->phc_index; dev_set_drvdata(dev, ptp_qoriq); return 0; +err_free_threaded_irq: + free_irq(ptp_qoriq->irq, ptp_qoriq); err_free_mc_irq: fsl_mc_free_irqs(mc_dev); err_unmap: iounmap(base); +err_put: + of_node_put(node); err_close: dprtc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); err_free_mcp: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc.c @@ -254,7 +254,7 @@ /* disable interrupts */ enetc_wr_reg(v->rbier, 0); - for_each_set_bit(i, &v->tx_rings_map, v->count_tx_rings) + for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS) enetc_wr_reg(v->tbier_base + ENETC_BDR_OFF(i), 0); napi_schedule_irqoff(&v->napi); @@ -290,7 +290,7 @@ /* enable interrupts */ enetc_wr_reg(v->rbier, ENETC_RBIER_RXTIE); - for_each_set_bit(i, &v->tx_rings_map, v->count_tx_rings) + for_each_set_bit(i, &v->tx_rings_map, ENETC_MAX_NUM_TXQS) enetc_wr_reg(v->tbier_base + ENETC_BDR_OFF(i), ENETC_TBIER_TXTIE); @@ -942,7 +942,7 @@ enetc_free_tx_ring(priv->tx_ring[i]); } -static int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) +int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr) { int size = cbdr->bd_count * sizeof(struct enetc_cbd); @@ -963,7 +963,7 @@ return 0; } -static void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) +void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr) { int size = cbdr->bd_count * sizeof(struct enetc_cbd); @@ -971,7 +971,7 @@ cbdr->bd_base = NULL; } -static void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) +void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr) { /* set CBDR cache attributes */ enetc_wr(hw, ENETC_SICAR2, @@ -991,7 +991,7 @@ cbdr->cir = hw->reg + ENETC_SICBDRCIR; } -static void enetc_clear_cbdr(struct enetc_hw *hw) +void enetc_clear_cbdr(struct enetc_hw *hw) { enetc_wr(hw, ENETC_SICBDRMR, 0); } @@ -1016,13 +1016,12 @@ return 0; } -static int enetc_configure_si(struct enetc_ndev_priv *priv) +int enetc_configure_si(struct enetc_ndev_priv *priv) { struct enetc_si *si = priv->si; struct enetc_hw *hw = &si->hw; int err; - enetc_setup_cbdr(hw, &si->cbd_ring); /* set SI cache attributes */ enetc_wr(hw, ENETC_SICAR0, ENETC_SICAR_RD_COHERENT | ENETC_SICAR_WR_COHERENT); @@ -1068,6 +1067,8 @@ if (err) return err; + enetc_setup_cbdr(&si->hw, &si->cbd_ring); + priv->cls_rules = kcalloc(si->num_fs_entries, sizeof(*priv->cls_rules), GFP_KERNEL); if (!priv->cls_rules) { @@ -1075,14 +1076,8 @@ goto err_alloc_cls; } - err = enetc_configure_si(priv); - if (err) - goto err_config_si; - return 0; -err_config_si: - kfree(priv->cls_rules); err_alloc_cls: enetc_clear_cbdr(&si->hw); enetc_free_cbdr(priv->dev, &si->cbd_ring); @@ -1151,7 +1146,12 @@ enetc_rxbdr_wr(hw, idx, ENETC_RBBSR, ENETC_RXB_DMA_SIZE); + /* Also prepare the consumer index in case page allocation never + * succeeds. In that case, hardware will never advance producer index + * to match consumer index, and will drop all frames. + */ enetc_rxbdr_wr(hw, idx, ENETC_RBPIR, 0); + enetc_rxbdr_wr(hw, idx, ENETC_RBCIR, 1); /* enable Rx ints by setting pkt thr to 1 */ enetc_rxbdr_wr(hw, idx, ENETC_RBICIR0, ENETC_RBICIR0_ICEN | 0x1); @@ -1227,7 +1227,6 @@ static int enetc_setup_irqs(struct enetc_ndev_priv *priv) { struct pci_dev *pdev = priv->si->pdev; - cpumask_t cpu_mask; int i, j, err; for (i = 0; i < priv->bdr_int_num; i++) { @@ -1254,9 +1253,7 @@ enetc_wr(hw, ENETC_SIMSITRV(idx), entry); } - cpumask_clear(&cpu_mask); - cpumask_set_cpu(i % num_online_cpus(), &cpu_mask); - irq_set_affinity_hint(irq, &cpu_mask); + irq_set_affinity_hint(irq, get_cpu_mask(i % num_online_cpus())); } return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc.h @@ -221,6 +221,7 @@ void enetc_init_si_rings_params(struct enetc_ndev_priv *priv); int enetc_alloc_si_resources(struct enetc_ndev_priv *priv); void enetc_free_si_resources(struct enetc_ndev_priv *priv); +int enetc_configure_si(struct enetc_ndev_priv *priv); int enetc_open(struct net_device *ndev); int enetc_close(struct net_device *ndev); @@ -236,6 +237,10 @@ void enetc_set_ethtool_ops(struct net_device *ndev); /* control buffer descriptor ring (CBDR) */ +int enetc_alloc_cbdr(struct device *dev, struct enetc_cbdr *cbdr); +void enetc_free_cbdr(struct device *dev, struct enetc_cbdr *cbdr); +void enetc_setup_cbdr(struct enetc_hw *hw, struct enetc_cbdr *cbdr); +void enetc_clear_cbdr(struct enetc_hw *hw); int enetc_set_mac_flt_entry(struct enetc_si *si, int index, char *mac_addr, int si_map); int enetc_clear_mac_flt_entry(struct enetc_si *si, int index); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c @@ -141,8 +141,8 @@ { ENETC_PM0_R255, "MAC rx 128-255 byte packets" }, { ENETC_PM0_R511, "MAC rx 256-511 byte packets" }, { ENETC_PM0_R1023, "MAC rx 512-1023 byte packets" }, - { ENETC_PM0_R1518, "MAC rx 1024-1518 byte packets" }, - { ENETC_PM0_R1519X, "MAC rx 1519 to max-octet packets" }, + { ENETC_PM0_R1522, "MAC rx 1024-1522 byte packets" }, + { ENETC_PM0_R1523X, "MAC rx 1523 to max-octet packets" }, { ENETC_PM0_ROVR, "MAC rx oversized packets" }, { ENETC_PM0_RJBR, "MAC rx jabber packets" }, { ENETC_PM0_RFRG, "MAC rx fragment packets" }, @@ -155,15 +155,19 @@ { ENETC_PM0_TFRM, "MAC tx frames" }, { ENETC_PM0_TFCS, "MAC tx fcs errors" }, { ENETC_PM0_TVLAN, "MAC tx VLAN frames" }, - { ENETC_PM0_TERR, "MAC tx frames" }, + { ENETC_PM0_TERR, "MAC tx frame errors" }, { ENETC_PM0_TUCA, "MAC tx unicast frames" }, { ENETC_PM0_TMCA, "MAC tx multicast frames" }, { ENETC_PM0_TBCA, "MAC tx broadcast frames" }, { ENETC_PM0_TPKT, "MAC tx packets" }, { ENETC_PM0_TUND, "MAC tx undersized packets" }, + { ENETC_PM0_T64, "MAC tx 64 byte packets" }, { ENETC_PM0_T127, "MAC tx 65-127 byte packets" }, + { ENETC_PM0_T255, "MAC tx 128-255 byte packets" }, + { ENETC_PM0_T511, "MAC tx 256-511 byte packets" }, { ENETC_PM0_T1023, "MAC tx 512-1023 byte packets" }, - { ENETC_PM0_T1518, "MAC tx 1024-1518 byte packets" }, + { ENETC_PM0_T1522, "MAC tx 1024-1522 byte packets" }, + { ENETC_PM0_T1523X, "MAC tx 1523 to max-octet packets" }, { ENETC_PM0_TCNP, "MAC tx control packets" }, { ENETC_PM0_TDFR, "MAC tx deferred packets" }, { ENETC_PM0_TMCOL, "MAC tx multiple collisions" }, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -181,6 +181,8 @@ #define ENETC_PTCCBSR0(n) (0x1110 + (n) * 8) /* n = 0 to 7*/ #define ENETC_PTCCBSR1(n) (0x1114 + (n) * 8) /* n = 0 to 7*/ #define ENETC_RSSHASH_KEY_SIZE 40 +#define ENETC_PRSSCAPR 0x1404 +#define ENETC_PRSSCAPR_GET_NUM_RSS(val) (BIT((val) & 0xf) * 32) #define ENETC_PRSSK(n) (0x1410 + (n) * 4) /* n = [0..9] */ #define ENETC_PSIVLANFMR 0x1700 #define ENETC_PSIVLANFMR_VS BIT(0) @@ -239,8 +241,8 @@ #define ENETC_PM0_R255 0x8180 #define ENETC_PM0_R511 0x8188 #define ENETC_PM0_R1023 0x8190 -#define ENETC_PM0_R1518 0x8198 -#define ENETC_PM0_R1519X 0x81A0 +#define ENETC_PM0_R1522 0x8198 +#define ENETC_PM0_R1523X 0x81A0 #define ENETC_PM0_ROVR 0x81A8 #define ENETC_PM0_RJBR 0x81B0 #define ENETC_PM0_RFRG 0x81B8 @@ -259,9 +261,13 @@ #define ENETC_PM0_TBCA 0x8250 #define ENETC_PM0_TPKT 0x8260 #define ENETC_PM0_TUND 0x8268 +#define ENETC_PM0_T64 0x8270 #define ENETC_PM0_T127 0x8278 +#define ENETC_PM0_T255 0x8280 +#define ENETC_PM0_T511 0x8288 #define ENETC_PM0_T1023 0x8290 -#define ENETC_PM0_T1518 0x8298 +#define ENETC_PM0_T1522 0x8298 +#define ENETC_PM0_T1523X 0x82A0 #define ENETC_PM0_TCNP 0x82C0 #define ENETC_PM0_TDFR 0x82D0 #define ENETC_PM0_TMCOL 0x82D8 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -809,6 +809,71 @@ of_node_put(priv->phy_node); } +/* Initialize the entire shared memory for the flow steering entries + * of this port (PF + VFs) + */ +static int enetc_init_port_rfs_memory(struct enetc_si *si) +{ + struct enetc_cmd_rfse rfse = {0}; + struct enetc_hw *hw = &si->hw; + int num_rfs, i, err = 0; + u32 val; + + val = enetc_port_rd(hw, ENETC_PRFSCAPR); + num_rfs = ENETC_PRFSCAPR_GET_NUM_RFS(val); + + for (i = 0; i < num_rfs; i++) { + err = enetc_set_fs_entry(si, &rfse, i); + if (err) + break; + } + + return err; +} + +static int enetc_init_port_rss_memory(struct enetc_si *si) +{ + struct enetc_hw *hw = &si->hw; + int num_rss, err; + int *rss_table; + u32 val; + + val = enetc_port_rd(hw, ENETC_PRSSCAPR); + num_rss = ENETC_PRSSCAPR_GET_NUM_RSS(val); + if (!num_rss) + return 0; + + rss_table = kcalloc(num_rss, sizeof(*rss_table), GFP_KERNEL); + if (!rss_table) + return -ENOMEM; + + err = enetc_set_rss_table(si, rss_table, num_rss); + + kfree(rss_table); + + return err; +} + +static void enetc_init_unused_port(struct enetc_si *si) +{ + struct device *dev = &si->pdev->dev; + struct enetc_hw *hw = &si->hw; + int err; + + si->cbd_ring.bd_count = ENETC_CBDR_DEFAULT_SIZE; + err = enetc_alloc_cbdr(dev, &si->cbd_ring); + if (err) + return; + + enetc_setup_cbdr(hw, &si->cbd_ring); + + enetc_init_port_rfs_memory(si); + enetc_init_port_rss_memory(si); + + enetc_clear_cbdr(hw); + enetc_free_cbdr(dev, &si->cbd_ring); +} + static int enetc_pf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -818,11 +883,6 @@ struct enetc_pf *pf; int err; - if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { - dev_info(&pdev->dev, "device is disabled, skipping\n"); - return -ENODEV; - } - err = enetc_pci_probe(pdev, KBUILD_MODNAME, sizeof(*pf)); if (err) { dev_err(&pdev->dev, "PCI probing failed\n"); @@ -836,6 +896,13 @@ goto err_map_pf_space; } + if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) { + enetc_init_unused_port(si); + dev_info(&pdev->dev, "device is disabled, skipping\n"); + err = -ENODEV; + goto err_device_disabled; + } + pf = enetc_si_priv(si); pf->si = si; pf->total_vfs = pci_sriov_get_totalvfs(pdev); @@ -863,6 +930,24 @@ goto err_alloc_si_res; } + err = enetc_init_port_rfs_memory(si); + if (err) { + dev_err(&pdev->dev, "Failed to initialize RFS memory\n"); + goto err_init_port_rfs; + } + + err = enetc_init_port_rss_memory(si); + if (err) { + dev_err(&pdev->dev, "Failed to initialize RSS memory\n"); + goto err_init_port_rss; + } + + err = enetc_configure_si(priv); + if (err) { + dev_err(&pdev->dev, "Failed to configure SI\n"); + goto err_config_si; + } + err = enetc_alloc_msix(priv); if (err) { dev_err(&pdev->dev, "MSIX alloc failed\n"); @@ -885,14 +970,19 @@ return 0; err_reg_netdev: + enetc_mdio_remove(pf); enetc_of_put_phy(priv); enetc_free_msix(priv); +err_config_si: +err_init_port_rss: +err_init_port_rfs: err_alloc_msix: enetc_free_si_resources(priv); err_alloc_si_res: si->ndev = NULL; free_netdev(ndev); err_alloc_netdev: +err_device_disabled: err_map_pf_space: enetc_pci_remove(pdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc_ptp.c @@ -8,7 +8,7 @@ #include "enetc.h" int enetc_phc_index = -1; -EXPORT_SYMBOL(enetc_phc_index); +EXPORT_SYMBOL_GPL(enetc_phc_index); static struct ptp_clock_info enetc_ptp_caps = { .owner = THIS_MODULE, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/enetc/enetc_vf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/enetc/enetc_vf.c @@ -94,6 +94,8 @@ if (err) return err; + eth_hw_addr_set(ndev, saddr->sa_data); + return 0; } @@ -189,6 +191,12 @@ goto err_alloc_si_res; } + err = enetc_configure_si(priv); + if (err) { + dev_err(&pdev->dev, "Failed to configure SI\n"); + goto err_config_si; + } + err = enetc_alloc_msix(priv); if (err) { dev_err(&pdev->dev, "MSIX alloc failed\n"); @@ -208,6 +216,7 @@ err_reg_netdev: enetc_free_msix(priv); +err_config_si: err_alloc_msix: enetc_free_si_resources(priv); err_alloc_si_res: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fec.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fec.h @@ -373,6 +373,9 @@ #define FEC_ENET_WAKEUP ((uint)0x00020000) /* Wakeup request */ #define FEC_ENET_TXF (FEC_ENET_TXF_0 | FEC_ENET_TXF_1 | FEC_ENET_TXF_2) #define FEC_ENET_RXF (FEC_ENET_RXF_0 | FEC_ENET_RXF_1 | FEC_ENET_RXF_2) +#define FEC_ENET_RXF_GET(X) (((X) == 0) ? FEC_ENET_RXF_0 : \ + (((X) == 1) ? FEC_ENET_RXF_1 : \ + FEC_ENET_RXF_2)) #define FEC_ENET_TS_AVAIL ((uint)0x00010000) #define FEC_ENET_TS_TIMER ((uint)0x00008000) @@ -488,6 +491,12 @@ struct sk_buff *rx_skbuff[RX_RING_SIZE]; }; +struct fec_stop_mode_gpr { + struct regmap *gpr; + u8 reg; + u8 bit; +}; + /* The FEC buffer descriptors track the ring buffers. The rx_bd_base and * tx_bd_base always point to the base of the buffer descriptors. The * cur_rx and cur_tx point to the currently available buffer. @@ -562,6 +571,7 @@ int hwts_tx_en; struct delayed_work time_keep; struct regulator *reg_phy; + struct fec_stop_mode_gpr stop_gpr; unsigned int tx_align; unsigned int rx_align; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fec_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fec_main.c @@ -62,6 +62,8 @@ #include #include #include +#include +#include #include #include @@ -84,6 +86,56 @@ #define FEC_ENET_OPD_V 0xFFF0 #define FEC_MDIO_PM_TIMEOUT 100 /* ms */ +struct fec_devinfo { + u32 quirks; + u8 stop_gpr_reg; + u8 stop_gpr_bit; +}; + +static const struct fec_devinfo fec_imx25_info = { + .quirks = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR | + FEC_QUIRK_HAS_FRREG, +}; + +static const struct fec_devinfo fec_imx27_info = { + .quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG, +}; + +static const struct fec_devinfo fec_imx28_info = { + .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | + FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC | + FEC_QUIRK_HAS_FRREG, +}; + +static const struct fec_devinfo fec_imx6q_info = { + .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | + FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 | + FEC_QUIRK_HAS_RACC, + .stop_gpr_reg = 0x34, + .stop_gpr_bit = 27, +}; + +static const struct fec_devinfo fec_mvf600_info = { + .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC, +}; + +static const struct fec_devinfo fec_imx6x_info = { + .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | + FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB | + FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE | + FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE, +}; + +static const struct fec_devinfo fec_imx6ul_info = { + .quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | + FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | + FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 | + FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC | + FEC_QUIRK_HAS_COALESCE, +}; + static struct platform_device_id fec_devtype[] = { { /* keep it for coldfire */ @@ -91,39 +143,25 @@ .driver_data = 0, }, { .name = "imx25-fec", - .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR | - FEC_QUIRK_HAS_FRREG, + .driver_data = (kernel_ulong_t)&fec_imx25_info, }, { .name = "imx27-fec", - .driver_data = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG, + .driver_data = (kernel_ulong_t)&fec_imx27_info, }, { .name = "imx28-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME | - FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC | - FEC_QUIRK_HAS_FRREG, + .driver_data = (kernel_ulong_t)&fec_imx28_info, }, { .name = "imx6q-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | - FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 | - FEC_QUIRK_HAS_RACC, + .driver_data = (kernel_ulong_t)&fec_imx6q_info, }, { .name = "mvf600-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC, + .driver_data = (kernel_ulong_t)&fec_mvf600_info, }, { .name = "imx6sx-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | - FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB | - FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE | - FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE, + .driver_data = (kernel_ulong_t)&fec_imx6x_info, }, { .name = "imx6ul-fec", - .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | - FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM | - FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 | - FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC | - FEC_QUIRK_HAS_COALESCE, + .driver_data = (kernel_ulong_t)&fec_imx6ul_info, }, { /* sentinel */ } @@ -185,8 +223,8 @@ #define PKT_MINBUF_SIZE 64 /* FEC receive acceleration */ -#define FEC_RACC_IPDIS (1 << 1) -#define FEC_RACC_PRODIS (1 << 2) +#define FEC_RACC_IPDIS BIT(1) +#define FEC_RACC_PRODIS BIT(2) #define FEC_RACC_SHIFT16 BIT(7) #define FEC_RACC_OPTIONS (FEC_RACC_IPDIS | FEC_RACC_PRODIS) @@ -218,8 +256,23 @@ #define FEC_MMFR_TA (2 << 16) #define FEC_MMFR_DATA(v) (v & 0xffff) /* FEC ECR bits definition */ -#define FEC_ECR_MAGICEN (1 << 2) -#define FEC_ECR_SLEEP (1 << 3) +#define FEC_ECR_RESET BIT(0) +#define FEC_ECR_ETHEREN BIT(1) +#define FEC_ECR_MAGICEN BIT(2) +#define FEC_ECR_SLEEP BIT(3) +#define FEC_ECR_EN1588 BIT(4) +#define FEC_ECR_BYTESWP BIT(8) +/* FEC RCR bits definition */ +#define FEC_RCR_LOOP BIT(0) +#define FEC_RCR_HALFDPX BIT(1) +#define FEC_RCR_MII BIT(2) +#define FEC_RCR_PROMISC BIT(3) +#define FEC_RCR_BC_REJ BIT(4) +#define FEC_RCR_FLOWCTL BIT(5) +#define FEC_RCR_RMII BIT(8) +#define FEC_RCR_10BASET BIT(9) +/* TX WMARK bits */ +#define FEC_TXWMRK_STRFWD BIT(8) #define FEC_MII_TIMEOUT 30000 /* us */ @@ -588,7 +641,7 @@ dev_kfree_skb_any(skb); if (net_ratelimit()) netdev_err(ndev, "Tx DMA memory map failed\n"); - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } bdp->cbd_datlen = cpu_to_fec16(size); @@ -650,7 +703,7 @@ dev_kfree_skb_any(skb); if (net_ratelimit()) netdev_err(ndev, "Tx DMA memory map failed\n"); - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } } @@ -679,6 +732,8 @@ int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); int total_len, data_left; struct bufdesc *bdp = txq->bd.cur; + struct bufdesc *tmp_bdp; + struct bufdesc_ex *ebdp; struct tso_t tso; unsigned int index = 0; int ret; @@ -752,7 +807,34 @@ return 0; err_release: - /* TODO: Release all used data descriptors for TSO */ + /* Release all used data descriptors for TSO */ + tmp_bdp = txq->bd.cur; + + while (tmp_bdp != bdp) { + /* Unmap data buffers */ + if (tmp_bdp->cbd_bufaddr && + !IS_TSO_HEADER(txq, fec32_to_cpu(tmp_bdp->cbd_bufaddr))) + dma_unmap_single(&fep->pdev->dev, + fec32_to_cpu(tmp_bdp->cbd_bufaddr), + fec16_to_cpu(tmp_bdp->cbd_datlen), + DMA_TO_DEVICE); + + /* Clear standard buffer descriptor fields */ + tmp_bdp->cbd_sc = 0; + tmp_bdp->cbd_datlen = 0; + tmp_bdp->cbd_bufaddr = 0; + + /* Handle extended descriptor if enabled */ + if (fep->bufdesc_ex) { + ebdp = (struct bufdesc_ex *)tmp_bdp; + ebdp->cbd_esc = 0; + } + + tmp_bdp = fec_enet_get_nextdesc(tmp_bdp, &txq->bd); + } + + dev_kfree_skb_any(skb); + return ret; } @@ -915,7 +997,7 @@ u32 val; u32 temp_mac[2]; u32 rcntl = OPT_FRAME_SIZE | 0x04; - u32 ecntl = 0x2; /* ETHEREN */ + u32 ecntl = FEC_ECR_ETHEREN; /* Whack a reset. We should wait for this. * For i.MX6SX SOC, enet use AXI bus, we use disable MAC @@ -991,18 +1073,18 @@ fep->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) rcntl |= (1 << 6); else if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) - rcntl |= (1 << 8); + rcntl |= FEC_RCR_RMII; else - rcntl &= ~(1 << 8); + rcntl &= ~FEC_RCR_RMII; /* 1G, 100M or 10M */ if (ndev->phydev) { if (ndev->phydev->speed == SPEED_1000) ecntl |= (1 << 5); else if (ndev->phydev->speed == SPEED_100) - rcntl &= ~(1 << 9); + rcntl &= ~FEC_RCR_10BASET; else - rcntl |= (1 << 9); + rcntl |= FEC_RCR_10BASET; } } else { #ifdef FEC_MIIGSK_ENR @@ -1061,13 +1143,13 @@ if (fep->quirks & FEC_QUIRK_ENET_MAC) { /* enable ENET endian swap */ - ecntl |= (1 << 8); + ecntl |= FEC_ECR_BYTESWP; /* enable ENET store and forward mode */ - writel(1 << 8, fep->hwp + FEC_X_WMRK); + writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK); } if (fep->bufdesc_ex) - ecntl |= (1 << 4); + ecntl |= FEC_ECR_EN1588; #ifndef CONFIG_M5272 /* Enable the MIB statistic event counters */ @@ -1092,12 +1174,29 @@ } +static void fec_enet_stop_mode(struct fec_enet_private *fep, bool enabled) +{ + struct fec_platform_data *pdata = fep->pdev->dev.platform_data; + struct fec_stop_mode_gpr *stop_gpr = &fep->stop_gpr; + + if (stop_gpr->gpr) { + if (enabled) + regmap_update_bits(stop_gpr->gpr, stop_gpr->reg, + BIT(stop_gpr->bit), + BIT(stop_gpr->bit)); + else + regmap_update_bits(stop_gpr->gpr, stop_gpr->reg, + BIT(stop_gpr->bit), 0); + } else if (pdata && pdata->sleep_mode_enable) { + pdata->sleep_mode_enable(enabled); + } +} + static void fec_stop(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - struct fec_platform_data *pdata = fep->pdev->dev.platform_data; - u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8); + u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & FEC_RCR_RMII; u32 val; /* We cannot expect a graceful transmit stop without link !!! */ @@ -1116,7 +1215,7 @@ if (fep->quirks & FEC_QUIRK_HAS_AVB) { writel(0, fep->hwp + FEC_ECNTRL); } else { - writel(1, fep->hwp + FEC_ECNTRL); + writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL); udelay(10); } writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); @@ -1125,20 +1224,23 @@ val = readl(fep->hwp + FEC_ECNTRL); val |= (FEC_ECR_MAGICEN | FEC_ECR_SLEEP); writel(val, fep->hwp + FEC_ECNTRL); - - if (pdata && pdata->sleep_mode_enable) - pdata->sleep_mode_enable(true); + fec_enet_stop_mode(fep, true); } writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); /* We have to keep ENET enabled to have MII interrupt stay working */ if (fep->quirks & FEC_QUIRK_ENET_MAC && !(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) { - writel(2, fep->hwp + FEC_ECNTRL); + writel(FEC_ECR_ETHEREN, fep->hwp + FEC_ECNTRL); writel(rmii_mode, fep->hwp + FEC_R_CNTRL); } -} + if (fep->bufdesc_ex) { + val = readl(fep->hwp + FEC_ECNTRL); + val |= FEC_ECR_EN1588; + writel(val, fep->hwp + FEC_ECNTRL); + } +} static void fec_timeout(struct net_device *ndev) @@ -1391,7 +1493,7 @@ break; pkt_received++; - writel(FEC_ENET_RXF, fep->hwp + FEC_IEVENT); + writel(FEC_ENET_RXF_GET(queue_id), fep->hwp + FEC_IEVENT); /* Check for errors. */ status ^= BD_ENET_RX_LAST; @@ -1742,6 +1844,7 @@ /* if any of the above changed restart the FEC */ if (status_change) { + netif_stop_queue(ndev); napi_disable(&fep->napi); netif_tx_lock_bh(ndev); fec_restart(ndev); @@ -1751,6 +1854,7 @@ } } else { if (fep->link) { + netif_stop_queue(ndev); napi_disable(&fep->napi); netif_tx_lock_bh(ndev); fec_stop(ndev); @@ -1892,6 +1996,27 @@ return ret; } +static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + struct phy_device *phy_dev = ndev->phydev; + + if (phy_dev) { + phy_reset_after_clk_enable(phy_dev); + } else if (fep->phy_node) { + /* + * If the PHY still is not bound to the MAC, but there is + * OF PHY node and a matching PHY device instance already, + * use the OF PHY node to obtain the PHY device instance, + * and then use that PHY device instance when triggering + * the PHY reset. + */ + phy_dev = of_phy_find_device(fep->phy_node); + phy_reset_after_clk_enable(phy_dev); + put_device(&phy_dev->mdio.dev); + } +} + static int fec_enet_clk_enable(struct net_device *ndev, bool enable) { struct fec_enet_private *fep = netdev_priv(ndev); @@ -1918,7 +2043,7 @@ if (ret) goto failed_clk_ref; - phy_reset_after_clk_enable(ndev->phydev); + fec_enet_phy_reset_after_clk_enable(ndev); } else { clk_disable_unprepare(fep->clk_enet_out); if (fep->clk_ptp) { @@ -2199,8 +2324,14 @@ { struct fec_enet_private *fep = netdev_priv(ndev); u32 __iomem *theregs = (u32 __iomem *)fep->hwp; + struct device *dev = &fep->pdev->dev; u32 *buf = (u32 *)regbuf; u32 i, off; + int ret; + + ret = pm_runtime_get_sync(dev); + if (ret < 0) + return; regs->version = fec_enet_register_version; @@ -2216,6 +2347,9 @@ off >>= 2; buf[off] = readl(&theregs[off]); } + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } static int fec_enet_get_ts_info(struct net_device *ndev, @@ -2520,15 +2654,15 @@ return -EINVAL; } - cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); + cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); if (cycle > 0xFFFF) { dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); return -EINVAL; } - cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); + cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); if (cycle > 0xFFFF) { - dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); + dev_err(dev, "Tx coalesced usec exceed hardware limitation\n"); return -EINVAL; } @@ -2920,16 +3054,16 @@ /* Init MAC prior to mii bus probe */ fec_restart(ndev); - /* Probe and connect to PHY when open the interface */ - ret = fec_enet_mii_probe(ndev); - if (ret) - goto err_enet_mii_probe; - /* Call phy_reset_after_clk_enable() again if it failed during * phy_reset_after_clk_enable() before because the PHY wasn't probed. */ if (reset_again) - phy_reset_after_clk_enable(ndev->phydev); + fec_enet_phy_reset_after_clk_enable(ndev); + + /* Probe and connect to PHY when open the interface */ + ret = fec_enet_mii_probe(ndev); + if (ret) + goto err_enet_mii_probe; if (fep->quirks & FEC_QUIRK_ERR006687) imx6q_cpuidle_fec_irqs_used(); @@ -3074,29 +3208,6 @@ return 0; } -#ifdef CONFIG_NET_POLL_CONTROLLER -/** - * fec_poll_controller - FEC Poll controller function - * @dev: The FEC network adapter - * - * Polled functionality used by netconsole and others in non interrupt mode - * - */ -static void fec_poll_controller(struct net_device *dev) -{ - int i; - struct fec_enet_private *fep = netdev_priv(dev); - - for (i = 0; i < FEC_IRQ_NUM; i++) { - if (fep->irq[i] > 0) { - disable_irq(fep->irq[i]); - fec_enet_interrupt(fep->irq[i], dev); - enable_irq(fep->irq[i]); - } - } -} -#endif - static inline void fec_enet_set_netdev_features(struct net_device *netdev, netdev_features_t features) { @@ -3145,9 +3256,6 @@ .ndo_tx_timeout = fec_timeout, .ndo_set_mac_address = fec_set_mac_address, .ndo_do_ioctl = fec_enet_ioctl, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = fec_poll_controller, -#endif .ndo_set_features = fec_set_features, }; @@ -3191,7 +3299,9 @@ return ret; } - fec_enet_alloc_queue(ndev); + ret = fec_enet_alloc_queue(ndev); + if (ret) + return ret; bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) * dsize; @@ -3199,7 +3309,8 @@ cbd_base = dmam_alloc_coherent(&fep->pdev->dev, bd_size, &bd_dma, GFP_KERNEL); if (!cbd_base) { - return -ENOMEM; + ret = -ENOMEM; + goto free_queue_mem; } /* Get the Ethernet address */ @@ -3277,6 +3388,18 @@ fec_enet_update_ethtool_stats(ndev); return 0; + +free_queue_mem: + fec_enet_free_queue(ndev); + return ret; +} + +static void fec_enet_deinit(struct net_device *ndev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + + netif_napi_del(&fep->napi); + fec_enet_free_queue(ndev); } #ifdef CONFIG_OF @@ -3389,6 +3512,37 @@ return irq_cnt; } +static int fec_enet_init_stop_mode(struct fec_enet_private *fep, + struct fec_devinfo *dev_info, + struct device_node *np) +{ + struct device_node *gpr_np; + int ret = 0; + + if (!dev_info) + return 0; + + gpr_np = of_parse_phandle(np, "gpr", 0); + if (!gpr_np) + return 0; + + fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np); + if (IS_ERR(fep->stop_gpr.gpr)) { + dev_err(&fep->pdev->dev, "could not find gpr regmap\n"); + ret = PTR_ERR(fep->stop_gpr.gpr); + fep->stop_gpr.gpr = NULL; + goto out; + } + + fep->stop_gpr.reg = dev_info->stop_gpr_reg; + fep->stop_gpr.bit = dev_info->stop_gpr_bit; + +out: + of_node_put(gpr_np); + + return ret; +} + static int fec_probe(struct platform_device *pdev) { @@ -3403,6 +3557,7 @@ int num_rx_qs; char irq_name[8]; int irq_cnt; + struct fec_devinfo *dev_info; fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs); @@ -3420,7 +3575,9 @@ of_id = of_match_device(fec_dt_ids, &pdev->dev); if (of_id) pdev->id_entry = of_id->data; - fep->quirks = pdev->id_entry->driver_data; + dev_info = (struct fec_devinfo *)pdev->id_entry->driver_data; + if (dev_info) + fep->quirks = dev_info->quirks; fep->netdev = ndev; fep->num_rx_queues = num_rx_qs; @@ -3454,6 +3611,10 @@ if (of_get_property(np, "fsl,magic-packet", NULL)) fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET; + ret = fec_enet_init_stop_mode(fep, dev_info, np); + if (ret) + goto failed_stop_mode; + phy_node = of_parse_phandle(np, "phy-handle", 0); if (!phy_node && of_phy_is_fixed_link(np)) { ret = of_phy_register_fixed_link(np); @@ -3605,13 +3766,14 @@ fec_enet_mii_remove(fep); failed_mii_init: failed_irq: + fec_enet_deinit(ndev); failed_init: fec_ptp_stop(pdev); - if (fep->reg_phy) - regulator_disable(fep->reg_phy); failed_reset: pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + if (fep->reg_phy) + regulator_disable(fep->reg_phy); failed_regulator: clk_disable_unprepare(fep->clk_ahb); failed_clk_ahb: @@ -3622,6 +3784,7 @@ if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(phy_node); +failed_stop_mode: failed_phy: dev_id--; failed_ioremap: @@ -3640,7 +3803,9 @@ ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) - return ret; + dev_err(&pdev->dev, + "Failed to resume device in remove callback (%pe)\n", + ERR_PTR(ret)); cancel_work_sync(&fep->tx_timeout_work); fec_ptp_stop(pdev); @@ -3652,13 +3817,19 @@ if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(fep->phy_node); - free_netdev(ndev); - clk_disable_unprepare(fep->clk_ahb); - clk_disable_unprepare(fep->clk_ipg); + /* After pm_runtime_get_sync() failed, the clks are still off, so skip + * disabling them again. + */ + if (ret >= 0) { + clk_disable_unprepare(fep->clk_ahb); + clk_disable_unprepare(fep->clk_ipg); + } pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + fec_enet_deinit(ndev); + free_netdev(ndev); return 0; } @@ -3699,7 +3870,6 @@ { struct net_device *ndev = dev_get_drvdata(dev); struct fec_enet_private *fep = netdev_priv(ndev); - struct fec_platform_data *pdata = fep->pdev->dev.platform_data; int ret; int val; @@ -3717,8 +3887,8 @@ goto failed_clk; } if (fep->wol_flag & FEC_WOL_FLAG_ENABLE) { - if (pdata && pdata->sleep_mode_enable) - pdata->sleep_mode_enable(false); + fec_enet_stop_mode(fep, false); + val = readl(fep->hwp + FEC_ECNTRL); val &= ~(FEC_ECR_MAGICEN | FEC_ECR_SLEEP); writel(val, fep->hwp + FEC_ECNTRL); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c @@ -92,7 +92,7 @@ goto out_free; } - snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); + snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res.start); bus->priv = priv; bus->parent = dev; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fec_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fec_ptp.c @@ -108,14 +108,13 @@ return -EINVAL; } - if (fep->pps_enable == enable) - return 0; - - fep->pps_channel = DEFAULT_PPS_CHANNEL; - fep->reload_period = PPS_OUPUT_RELOAD_PERIOD; - spin_lock_irqsave(&fep->tmreg_lock, flags); + if (fep->pps_enable == enable) { + spin_unlock_irqrestore(&fep->tmreg_lock, flags); + return 0; + } + if (enable) { /* clear capture or output compare interrupt status if have. */ @@ -141,11 +140,7 @@ * NSEC_PER_SEC - ts.tv_nsec. Add the remaining nanoseconds * to current timer would be next second. */ - tempval = readl(fep->hwp + FEC_ATIME_CTRL); - tempval |= FEC_T_CTRL_CAPTURE; - writel(tempval, fep->hwp + FEC_ATIME_CTRL); - - tempval = readl(fep->hwp + FEC_ATIME); + tempval = fep->cc.read(&fep->cc); /* Convert the ptp local counter to 1588 timestamp */ ns = timecounter_cyc2time(&fep->tc, tempval); ts = ns_to_timespec64(ns); @@ -220,15 +215,13 @@ { struct fec_enet_private *fep = container_of(cc, struct fec_enet_private, cc); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); u32 tempval; tempval = readl(fep->hwp + FEC_ATIME_CTRL); tempval |= FEC_T_CTRL_CAPTURE; writel(tempval, fep->hwp + FEC_ATIME_CTRL); - if (id_entry->driver_data & FEC_QUIRK_BUG_CAPTURE) + if (fep->quirks & FEC_QUIRK_BUG_CAPTURE) udelay(1); return readl(fep->hwp + FEC_ATIME); @@ -382,9 +375,16 @@ u64 ns; unsigned long flags; + mutex_lock(&adapter->ptp_clk_mutex); + /* Check the ptp clock */ + if (!adapter->ptp_clk_on) { + mutex_unlock(&adapter->ptp_clk_mutex); + return -EINVAL; + } spin_lock_irqsave(&adapter->tmreg_lock, flags); ns = timecounter_read(&adapter->tc); spin_unlock_irqrestore(&adapter->tmreg_lock, flags); + mutex_unlock(&adapter->ptp_clk_mutex); *ts = ns_to_timespec64(ns); @@ -445,6 +445,9 @@ int ret = 0; if (rq->type == PTP_CLK_REQ_PPS) { + fep->pps_channel = DEFAULT_PPS_CHANNEL; + fep->reload_period = PPS_OUPUT_RELOAD_PERIOD; + ret = fec_ptp_enable_pps(fep, on); return ret; @@ -592,6 +595,10 @@ fep->ptp_caps.enable = fec_ptp_enable; fep->cycle_speed = clk_get_rate(fep->clk_ptp); + if (!fep->cycle_speed) { + fep->cycle_speed = NSEC_PER_SEC; + dev_err(&fep->pdev->dev, "clk_ptp clock rate is zero\n"); + } fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; spin_lock_init(&fep->tmreg_lock); @@ -628,6 +635,9 @@ struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); + if (fep->pps_enable) + fec_ptp_enable_pps(fep, 0); + cancel_delayed_work_sync(&fep->time_keep); if (fep->ptp_clock) ptp_clock_unregister(fep->ptp_clock); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/Kconfig @@ -8,3 +8,31 @@ help Freescale Data-Path Acceleration Architecture Frame Manager (FMan) support + +config DPAA_ERRATUM_A050385 + bool + depends on ARM64 && FSL_DPAA + default y + help + DPAA FMan erratum A050385 software workaround implementation: + align buffers, data start, SG fragment length to avoid FMan DMA + splits. + FMAN DMA read or writes under heavy traffic load may cause FMAN + internal resource leak thus stopping further packet processing. + The FMAN internal queue can overflow when FMAN splits single + read or write transactions into multiple smaller transactions + such that more than 17 AXI transactions are in flight from FMAN + to interconnect. When the FMAN internal queue overflows, it can + stall further packet processing. The issue can occur with any + one of the following three conditions: + 1. FMAN AXI transaction crosses 4K address boundary (Errata + A010022) + 2. FMAN DMA address for an AXI transaction is not 16 byte + aligned, i.e. the last 4 bits of an address are non-zero + 3. Scatter Gather (SG) frames have more than one SG buffer in + the SG list and any one of the buffers, except the last + buffer in the SG list has data size that is not a multiple + of 16 bytes, i.e., other than 16, 32, 48, 64, etc. + With any one of the above three conditions present, there is + likelihood of stalled FMAN packet processing, especially under + stress with multiple ports injecting line-rate traffic. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman.c @@ -1,5 +1,6 @@ /* * Copyright 2008-2015 Freescale Semiconductor Inc. + * Copyright 2020 NXP * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -566,6 +567,10 @@ u32 qmi_def_tnums_thresh; }; +#ifdef CONFIG_DPAA_ERRATUM_A050385 +static bool fman_has_err_a050385; +#endif + static irqreturn_t fman_exceptions(struct fman *fman, enum fman_exceptions exception) { @@ -1391,8 +1396,7 @@ { struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs; u16 fm_clk_freq = fman->state->fm_clk_freq; - u32 tmp, intgr, ts_freq; - u64 frac; + u32 tmp, intgr, ts_freq, frac; ts_freq = (u32)(1 << fman->state->count1_micro_bit); /* configure timestamp so that bit 8 will count 1 microsecond @@ -2514,6 +2518,14 @@ } EXPORT_SYMBOL(fman_bind); +#ifdef CONFIG_DPAA_ERRATUM_A050385 +bool fman_has_errata_a050385(void) +{ + return fman_has_err_a050385; +} +EXPORT_SYMBOL(fman_has_errata_a050385); +#endif + static irqreturn_t fman_err_irq(int irq, void *handle) { struct fman *fman = (struct fman *)handle; @@ -2841,6 +2853,11 @@ goto fman_free; } +#ifdef CONFIG_DPAA_ERRATUM_A050385 + fman_has_err_a050385 = + of_property_read_bool(fm_node, "fsl,erratum-a050385"); +#endif + return fman; fman_node_put: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman.h @@ -1,5 +1,6 @@ /* * Copyright 2008-2015 Freescale Semiconductor Inc. + * Copyright 2020 NXP * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -398,6 +399,10 @@ int fman_get_rx_extra_headroom(void); +#ifdef CONFIG_DPAA_ERRATUM_A050385 +bool fman_has_errata_a050385(void); +#endif + struct fman *fman_bind(struct device *dev); #endif /* __FM_H */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman_dtsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman_dtsec.c @@ -1205,7 +1205,7 @@ list_for_each(pos, &dtsec->multicast_addr_hash->lsts[bucket]) { hash_entry = ETH_HASH_ENTRY_OBJ(pos); - if (hash_entry->addr == addr) { + if (hash_entry && hash_entry->addr == addr) { list_del_init(&hash_entry->node); kfree(hash_entry); break; @@ -1218,7 +1218,7 @@ list_for_each(pos, &dtsec->unicast_addr_hash->lsts[bucket]) { hash_entry = ETH_HASH_ENTRY_OBJ(pos); - if (hash_entry->addr == addr) { + if (hash_entry && hash_entry->addr == addr) { list_del_init(&hash_entry->node); kfree(hash_entry); break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman_mac.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman_mac.h @@ -252,7 +252,7 @@ struct eth_hash_t *hash; /* Allocate address hash table */ - hash = kmalloc_array(size, sizeof(struct eth_hash_t *), GFP_KERNEL); + hash = kmalloc(sizeof(*hash), GFP_KERNEL); if (!hash) return NULL; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman_memac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman_memac.c @@ -110,7 +110,7 @@ /* Interface Mode Register (IF_MODE) */ #define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */ -#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */ +#define IF_MODE_10G 0x00000000 /* 30-31 10G interface */ #define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */ #define IF_MODE_RGMII 0x00000004 #define IF_MODE_RGMII_AUTO 0x00008000 @@ -440,7 +440,7 @@ tmp = 0; switch (phy_if) { case PHY_INTERFACE_MODE_XGMII: - tmp |= IF_MODE_XGMII; + tmp |= IF_MODE_10G; break; default: tmp |= IF_MODE_GMII; @@ -856,7 +856,6 @@ tmp = ioread32be(®s->command_config); tmp &= ~CMD_CFG_PFC_MODE; - priority = 0; iowrite32be(tmp, ®s->command_config); @@ -986,7 +985,7 @@ list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) { hash_entry = ETH_HASH_ENTRY_OBJ(pos); - if (hash_entry->addr == addr) { + if (hash_entry && hash_entry->addr == addr) { list_del_init(&hash_entry->node); kfree(hash_entry); break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman_port.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman_port.c @@ -1756,6 +1756,7 @@ struct fman_port *port; struct fman *fman; struct device_node *fm_node, *port_node; + struct platform_device *fm_pdev; struct resource res; struct resource *dev_res; u32 val; @@ -1780,19 +1781,25 @@ goto return_err; } - fman = dev_get_drvdata(&of_find_device_by_node(fm_node)->dev); + fm_pdev = of_find_device_by_node(fm_node); of_node_put(fm_node); - if (!fman) { + if (!fm_pdev) { err = -EINVAL; goto return_err; } + fman = dev_get_drvdata(&fm_pdev->dev); + if (!fman) { + err = -EINVAL; + goto put_device; + } + err = of_property_read_u32(port_node, "cell-index", &val); if (err) { dev_err(port->dev, "%s: reading cell-index for %pOF failed\n", __func__, port_node); err = -EINVAL; - goto return_err; + goto put_device; } port_id = (u8)val; port->dts_params.id = port_id; @@ -1826,7 +1833,7 @@ } else { dev_err(port->dev, "%s: Illegal port type\n", __func__); err = -EINVAL; - goto return_err; + goto put_device; } port->dts_params.type = port_type; @@ -1840,7 +1847,7 @@ dev_err(port->dev, "%s: incorrect qman-channel-id\n", __func__); err = -EINVAL; - goto return_err; + goto put_device; } port->dts_params.qman_channel_id = qman_channel_id; } @@ -1850,7 +1857,7 @@ dev_err(port->dev, "%s: of_address_to_resource() failed\n", __func__); err = -ENOMEM; - goto return_err; + goto put_device; } port->dts_params.fman = fman; @@ -1875,6 +1882,8 @@ return 0; +put_device: + put_device(&fm_pdev->dev); return_err: of_node_put(port_node); free_port: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/fman_tgec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/fman_tgec.c @@ -630,7 +630,7 @@ list_for_each(pos, &tgec->multicast_addr_hash->lsts[hash]) { hash_entry = ETH_HASH_ENTRY_OBJ(pos); - if (hash_entry->addr == addr) { + if (hash_entry && hash_entry->addr == addr) { list_del_init(&hash_entry->node); kfree(hash_entry); break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fman/mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fman/mac.c @@ -94,14 +94,17 @@ __func__, ex); } -static void set_fman_mac_params(struct mac_device *mac_dev, - struct fman_mac_params *params) +static int set_fman_mac_params(struct mac_device *mac_dev, + struct fman_mac_params *params) { struct mac_priv_s *priv = mac_dev->priv; params->base_addr = (typeof(params->base_addr)) devm_ioremap(priv->dev, mac_dev->res->start, resource_size(mac_dev->res)); + if (!params->base_addr) + return -ENOMEM; + memcpy(¶ms->addr, mac_dev->addr, sizeof(mac_dev->addr)); params->max_speed = priv->max_speed; params->phy_if = mac_dev->phy_if; @@ -112,6 +115,8 @@ params->event_cb = mac_exception; params->dev_id = mac_dev; params->internal_phy_node = priv->internal_phy_node; + + return 0; } static int tgec_initialization(struct mac_device *mac_dev) @@ -123,7 +128,9 @@ priv = mac_dev->priv; - set_fman_mac_params(mac_dev, ¶ms); + err = set_fman_mac_params(mac_dev, ¶ms); + if (err) + goto _return; mac_dev->fman_mac = tgec_config(¶ms); if (!mac_dev->fman_mac) { @@ -169,7 +176,9 @@ priv = mac_dev->priv; - set_fman_mac_params(mac_dev, ¶ms); + err = set_fman_mac_params(mac_dev, ¶ms); + if (err) + goto _return; mac_dev->fman_mac = dtsec_config(¶ms); if (!mac_dev->fman_mac) { @@ -218,7 +227,9 @@ priv = mac_dev->priv; - set_fman_mac_params(mac_dev, ¶ms); + err = set_fman_mac_params(mac_dev, ¶ms); + if (err) + goto _return; if (priv->max_speed == SPEED_10000) params.phy_if = PHY_INTERFACE_MODE_XGMII; @@ -874,12 +885,21 @@ return err; } +static int mac_remove(struct platform_device *pdev) +{ + struct mac_device *mac_dev = platform_get_drvdata(pdev); + + platform_device_unregister(mac_dev->priv->eth_dev); + return 0; +} + static struct platform_driver mac_driver = { .driver = { .name = KBUILD_MODNAME, .of_match_table = mac_match, }, .probe = mac_probe, + .remove = mac_remove, }; builtin_platform_driver(mac_driver); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fs_enet/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fs_enet/Kconfig @@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only config FS_ENET - tristate "Freescale Ethernet Driver" - depends on NET_VENDOR_FREESCALE && (CPM1 || CPM2 || PPC_MPC512x) - select MII - select PHYLIB + tristate "Freescale Ethernet Driver" + depends on NET_VENDOR_FREESCALE && (CPM1 || CPM2 || PPC_MPC512x) + select MII + select PHYLIB config FS_ENET_MPC5121_FEC def_bool y if (FS_ENET && PPC_MPC512x) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fs_enet/mac-fec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fs_enet/mac-fec.c @@ -98,7 +98,7 @@ return -EINVAL; fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0); - if (!fep->fcc.fccp) + if (!fep->fec.fecp) return -EINVAL; return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -126,7 +126,7 @@ * we get is an int, and the odds of multiple bitbang mdio buses * is low enough that it's not worth going too crazy. */ - snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); + snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res.start); data = of_get_property(np, "fsl,mdio-pin", &len); if (!data || len != 4) @@ -223,3 +223,4 @@ }; module_platform_driver(fs_enet_bb_mdio_driver); +MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -224,3 +224,4 @@ }; module_platform_driver(fs_enet_fec_mdio_driver); +MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/gianfar.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/gianfar.c @@ -366,7 +366,11 @@ static int gfar_set_mac_addr(struct net_device *dev, void *p) { - eth_mac_addr(dev, p); + int ret; + + ret = eth_mac_addr(dev, p); + if (ret) + return ret; gfar_set_mac_for_addr(dev, 0, dev->dev_addr); @@ -751,8 +755,10 @@ continue; err = gfar_parse_group(child, priv, model); - if (err) + if (err) { + of_node_put(child); goto err_grp_init; + } } } else { /* SQ_SG_MODE */ err = gfar_parse_group(np, priv, model); @@ -1824,20 +1830,12 @@ fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN; /* make space for additional header when fcb is needed */ - if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) { - struct sk_buff *skb_new; - - skb_new = skb_realloc_headroom(skb, fcb_len); - if (!skb_new) { + if (fcb_len) { + if (unlikely(skb_cow_head(skb, fcb_len))) { dev->stats.tx_errors++; dev_kfree_skb_any(skb); return NETDEV_TX_OK; } - - if (skb->sk) - skb_set_owner_w(skb_new, skb->sk); - dev_consume_skb_any(skb); - skb = skb_new; } /* total number of fragments in the SKB */ @@ -2204,13 +2202,17 @@ skb_dirtytx = tx_queue->skb_dirtytx; while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) { + bool do_tstamp; + + do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && + priv->hwts_tx_en; frags = skb_shinfo(skb)->nr_frags; /* When time stamping, one additional TxBD must be freed. * Also, we need to dma_unmap_single() the TxPAL. */ - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) + if (unlikely(do_tstamp)) nr_txbds = frags + 2; else nr_txbds = frags + 1; @@ -2224,7 +2226,7 @@ (lstatus & BD_LENGTH_MASK)) break; - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { + if (unlikely(do_tstamp)) { next = next_txbd(bdp, base, tx_ring_size); buflen = be16_to_cpu(next->length) + GMAC_FCB_LEN + GMAC_TXPAL_LEN; @@ -2234,7 +2236,7 @@ dma_unmap_single(priv->dev, be32_to_cpu(bdp->bufPtr), buflen, DMA_TO_DEVICE); - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { + if (unlikely(do_tstamp)) { struct skb_shared_hwtstamps shhwtstamps; u64 *ns = (u64 *)(((uintptr_t)skb->data + 0x10) & ~0x7UL); @@ -2390,6 +2392,10 @@ if (lstatus & BD_LFLAG(RXBD_LAST)) size -= skb->len; + WARN(size < 0, "gianfar: rx fragment size underflow"); + if (size < 0) + return false; + skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, rxb->page_offset + RXBUF_ALIGNMENT, size, GFAR_RXB_TRUESIZE); @@ -2552,6 +2558,17 @@ if (lstatus & BD_LFLAG(RXBD_EMPTY)) break; + /* lost RXBD_LAST descriptor due to overrun */ + if (skb && + (lstatus & BD_LFLAG(RXBD_FIRST))) { + /* discard faulty buffer */ + dev_kfree_skb(skb); + skb = NULL; + rx_queue->stats.rx_dropped++; + + /* can continue normally */ + } + /* order rx buffer descriptor reads */ rmb(); @@ -3371,7 +3388,7 @@ if (dev->features & NETIF_F_IP_CSUM || priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) - dev->needed_headroom = GMAC_FCB_LEN; + dev->needed_headroom = GMAC_FCB_LEN + GMAC_TXPAL_LEN; /* Initializing some of the rx/tx queue level parameters */ for (i = 0; i < priv->num_tx_queues; i++) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1489,6 +1489,7 @@ ptp_node = of_find_compatible_node(NULL, NULL, "fsl,etsec-ptp"); if (ptp_node) { ptp_dev = of_find_device_by_node(ptp_node); + of_node_put(ptp_node); if (ptp_dev) ptp = platform_get_drvdata(ptp_dev); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/ucc_geth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/ucc_geth.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "ucc_geth.h" @@ -1548,11 +1549,8 @@ static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Prevent any further xmits, plus detach the device. */ - netif_device_detach(ugeth->ndev); - - /* Wait for any current xmits to finish. */ - netif_tx_disable(ugeth->ndev); + /* Prevent any further xmits */ + netif_tx_stop_all_queues(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ disable_irq(ugeth->ug_info->uf_info.irq); @@ -1565,7 +1563,10 @@ { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_device_attach(ugeth->ndev); + + /* allow to xmit again */ + netif_tx_wake_all_queues(ugeth->ndev); + __netdev_watchdog_up(ugeth->ndev); } /* Called every time the controller might need to be made @@ -3889,6 +3890,7 @@ INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work); netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64); dev->mtu = 1500; + dev->max_mtu = 1518; ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT); ugeth->phy_interface = phy_interface; @@ -3934,12 +3936,12 @@ struct device_node *np = ofdev->dev.of_node; unregister_netdev(dev); - free_netdev(dev); ucc_geth_memclean(ugeth); if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(ugeth->ug_info->tbi_node); of_node_put(ugeth->ug_info->phy_node); + free_netdev(dev); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/ucc_geth.h +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/ucc_geth.h @@ -576,7 +576,14 @@ u32 vtagtable[0x8]; /* 8 4-byte VLAN tags */ u32 tqptr; /* a base pointer to the Tx Queues Memory Region */ - u8 res2[0x80 - 0x74]; + u8 res2[0x78 - 0x74]; + u64 snums_en; + u32 l2l3baseptr; /* top byte consists of a few other bit fields */ + + u16 mtu[8]; + u8 res3[0xa8 - 0x94]; + u32 wrrtablebase; /* top byte is reserved */ + u8 res4[0xc0 - 0xac]; } __packed; /* structure representing Extended Filtering Global Parameters in PRAM */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/freescale/xgmac_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/freescale/xgmac_mdio.c @@ -49,6 +49,7 @@ struct mdio_fsl_priv { struct tgec_mdio_controller __iomem *mdio_base; bool is_little_endian; + bool has_a011043; }; static u32 xgmac_read32(void __iomem *regs, @@ -226,7 +227,8 @@ return ret; /* Return all Fs if nothing was there */ - if (xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) { + if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) && + !priv->has_a011043) { dev_err(&bus->dev, "Error while reading PHY%d reg at %d.%hhu\n", phy_id, dev_addr, regnum); @@ -274,6 +276,9 @@ priv->is_little_endian = of_property_read_bool(pdev->dev.of_node, "little-endian"); + priv->has_a011043 = of_property_read_bool(pdev->dev.of_node, + "fsl,erratum-a011043"); + ret = of_mdiobus_register(bus, np); if (ret) { dev_err(&pdev->dev, "cannot register MDIO bus\n"); @@ -296,9 +301,10 @@ static int xgmac_mdio_remove(struct platform_device *pdev) { struct mii_bus *bus = platform_get_drvdata(pdev); + struct mdio_fsl_priv *priv = bus->priv; mdiobus_unregister(bus); - iounmap(bus->priv); + iounmap(priv->mdio_base); mdiobus_free(bus); return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/fujitsu/fmvj18x_cs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/fujitsu/fmvj18x_cs.c @@ -548,8 +548,8 @@ base = ioremap(link->resource[2]->start, resource_size(link->resource[2])); if (!base) { - pcmcia_release_window(link, link->resource[2]); - return -ENOMEM; + pcmcia_release_window(link, link->resource[2]); + return -1; } pcmcia_map_mem_page(link, link->resource[2], 0); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/google/gve/gve.h +++ linux-oracle-5.4.0/drivers/net/ethernet/google/gve/gve.h @@ -391,7 +391,7 @@ gve_num_tx_qpls(priv)); /* we are out of rx qpls */ - if (id == priv->qpl_cfg.qpl_map_size) + if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv)) return NULL; set_bit(id, priv->qpl_cfg.qpl_id_map); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/google/gve/gve_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/google/gve/gve_main.c @@ -30,6 +30,7 @@ { struct gve_priv *priv = netdev_priv(dev); unsigned int start; + u64 packets, bytes; int ring; if (priv->rx) { @@ -37,10 +38,12 @@ do { start = u64_stats_fetch_begin(&priv->rx[ring].statss); - s->rx_packets += priv->rx[ring].rpackets; - s->rx_bytes += priv->rx[ring].rbytes; + packets = priv->rx[ring].rpackets; + bytes = priv->rx[ring].rbytes; } while (u64_stats_fetch_retry(&priv->rx[ring].statss, start)); + s->rx_packets += packets; + s->rx_bytes += bytes; } } if (priv->tx) { @@ -48,10 +51,12 @@ do { start = u64_stats_fetch_begin(&priv->tx[ring].statss); - s->tx_packets += priv->tx[ring].pkt_done; - s->tx_bytes += priv->tx[ring].bytes_done; + packets = priv->tx[ring].pkt_done; + bytes = priv->tx[ring].bytes_done; } while (u64_stats_fetch_retry(&priv->tx[ring].statss, start)); + s->tx_packets += packets; + s->tx_bytes += bytes; } } } @@ -121,7 +126,7 @@ /* Double check we have no extra work. * Ensure unmask synchronizes with checking for work. */ - dma_rmb(); + mb(); if (block->tx) reschedule |= gve_tx_poll(block, -1); if (block->rx) @@ -161,6 +166,7 @@ int vecs_left = new_num_ntfy_blks % 2; priv->num_ntfy_blks = new_num_ntfy_blks; + priv->mgmt_msix_idx = priv->num_ntfy_blks; priv->tx_cfg.max_queues = min_t(int, priv->tx_cfg.max_queues, vecs_per_type); priv->rx_cfg.max_queues = min_t(int, priv->rx_cfg.max_queues, @@ -241,20 +247,22 @@ { int i; - /* Free the irqs */ - for (i = 0; i < priv->num_ntfy_blks; i++) { - struct gve_notify_block *block = &priv->ntfy_blocks[i]; - int msix_idx = i; - - irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, - NULL); - free_irq(priv->msix_vectors[msix_idx].vector, block); + if (priv->msix_vectors) { + /* Free the irqs */ + for (i = 0; i < priv->num_ntfy_blks; i++) { + struct gve_notify_block *block = &priv->ntfy_blocks[i]; + int msix_idx = i; + + irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, + NULL); + free_irq(priv->msix_vectors[msix_idx].vector, block); + } + free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); } dma_free_coherent(&priv->pdev->dev, priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), priv->ntfy_blocks, priv->ntfy_block_bus); priv->ntfy_blocks = NULL; - free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); pci_disable_msix(priv->pdev); kvfree(priv->msix_vectors); priv->msix_vectors = NULL; @@ -544,7 +552,7 @@ } qpl->id = id; - qpl->num_entries = pages; + qpl->num_entries = 0; qpl->pages = kvzalloc(pages * sizeof(*qpl->pages), GFP_KERNEL); /* caller handles clean up */ if (!qpl->pages) @@ -562,6 +570,7 @@ /* caller handles clean up */ if (err) return -ENOMEM; + qpl->num_entries++; } priv->num_registered_pages += pages; @@ -1114,8 +1123,8 @@ gve_write_version(®_bar->driver_version); /* Get max queues to alloc etherdev */ - max_rx_queues = ioread32be(®_bar->max_tx_queues); - max_tx_queues = ioread32be(®_bar->max_rx_queues); + max_tx_queues = ioread32be(®_bar->max_tx_queues); + max_rx_queues = ioread32be(®_bar->max_rx_queues); /* Alloc and setup the netdev and priv */ dev = alloc_etherdev_mqs(sizeof(*priv), max_tx_queues, max_rx_queues); if (!dev) { @@ -1166,13 +1175,16 @@ err = register_netdev(dev); if (err) - goto abort_with_wq; + goto abort_with_gve_init; dev_info(&pdev->dev, "GVE version %s\n", gve_version_str); gve_clear_probe_in_progress(priv); queue_work(priv->gve_wq, &priv->service_task); return 0; +abort_with_gve_init: + gve_teardown_priv_resources(priv); + abort_with_wq: destroy_workqueue(priv->gve_wq); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/google/gve/gve_rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/google/gve/gve_rx.c @@ -418,8 +418,6 @@ rx->cnt = cnt; rx->fill_cnt += work_done; - /* restock desc ring slots */ - dma_wmb(); /* Ensure descs are visible before ringing doorbell */ gve_rx_write_doorbell(priv, rx); return gve_rx_work_pending(rx); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/google/gve/gve_tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/google/gve/gve_tx.c @@ -207,10 +207,12 @@ goto abort_with_info; tx->tx_fifo.qpl = gve_assign_tx_qpl(priv); + if (!tx->tx_fifo.qpl) + goto abort_with_desc; /* map Tx FIFO */ if (gve_tx_fifo_init(priv, &tx->tx_fifo)) - goto abort_with_desc; + goto abort_with_qpl; tx->q_resources = dma_alloc_coherent(hdev, @@ -229,6 +231,8 @@ abort_with_fifo: gve_tx_fifo_release(priv, &tx->tx_fifo); +abort_with_qpl: + gve_unassign_qpl(priv, tx->tx_fifo.qpl->id); abort_with_desc: dma_free_coherent(hdev, bytes, tx->desc, tx->bus); tx->desc = NULL; @@ -478,7 +482,7 @@ struct gve_tx_ring *tx; int nsegs; - WARN(skb_get_queue_mapping(skb) > priv->tx_cfg.num_queues, + WARN(skb_get_queue_mapping(skb) >= priv->tx_cfg.num_queues, "skb queue index out of range"); tx = &priv->tx[skb_get_queue_mapping(skb)]; if (unlikely(gve_maybe_stop_tx(tx, skb))) { @@ -487,10 +491,6 @@ * may have added descriptors without ringing the doorbell. */ - /* Ensure tx descs from a prior gve_tx are visible before - * ringing doorbell. - */ - dma_wmb(); gve_tx_put_doorbell(priv, tx->q_resources, tx->req); return NETDEV_TX_BUSY; } @@ -505,8 +505,6 @@ if (!netif_xmit_stopped(tx->netdev_txq) && netdev_xmit_more()) return NETDEV_TX_OK; - /* Ensure tx descs are visible before ringing doorbell */ - dma_wmb(); gve_tx_put_doorbell(priv, tx->q_resources, tx->req); return NETDEV_TX_OK; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hip04_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -131,7 +131,7 @@ /* buf unit size is cache_line_size, which is 64, so the shift is 6 */ #define PPE_BUF_SIZE_SHIFT 6 #define PPE_TX_BUF_HOLD BIT(31) -#define CACHE_LINE_MASK 0x3F +#define SOC_CACHE_LINE_MASK 0x3F #else #define PPE_CFG_QOS_VMID_GRP_SHIFT 8 #define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11 @@ -531,8 +531,8 @@ #if defined(CONFIG_HI13X1_GMAC) desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); - desc->data_offset = (__force u32)cpu_to_be32(phys & CACHE_LINE_MASK); - desc->send_addr = (__force u32)cpu_to_be32(phys & ~CACHE_LINE_MASK); + desc->data_offset = (__force u32)cpu_to_be32(phys & SOC_CACHE_LINE_MASK); + desc->send_addr = (__force u32)cpu_to_be32(phys & ~SOC_CACHE_LINE_MASK); #else desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); desc->send_addr = (__force u32)cpu_to_be32(phys); @@ -543,9 +543,9 @@ skb_tx_timestamp(skb); hip04_set_xmit_desc(priv, phys); - priv->tx_head = TX_NEXT(tx_head); count++; netdev_sent_queue(ndev, skb->len); + priv->tx_head = TX_NEXT(tx_head); stats->tx_bytes += skb->len; stats->tx_packets++; @@ -955,6 +955,7 @@ priv->tx_coalesce_timer.function = tx_done; priv->map = syscon_node_to_regmap(arg.np); + of_node_put(arg.np); if (IS_ERR(priv->map)) { dev_warn(d, "no syscon hisilicon,hip04-ppe\n"); ret = PTR_ERR(priv->map); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hisi_femac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hisi_femac.c @@ -283,7 +283,7 @@ skb->protocol = eth_type_trans(skb, dev); napi_gro_receive(&priv->napi, skb); dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; + dev->stats.rx_bytes += len; next: pos = (pos + 1) % rxq->num; if (rx_pkts_num >= limit) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hix5hd2_gmac.c @@ -550,7 +550,7 @@ skb->protocol = eth_type_trans(skb, dev); napi_gro_receive(&priv->napi, skb); dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; + dev->stats.rx_bytes += len; next: pos = dma_ring_incr(pos, RX_DESC_NUM); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns/hnae.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -419,8 +419,10 @@ hdev->cls_dev.release = hnae_release; (void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id); ret = device_register(&hdev->cls_dev); - if (ret) + if (ret) { + put_device(&hdev->cls_dev); return ret; + } __module_get(THIS_MODULE); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c @@ -66,6 +66,27 @@ } } +static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) +{ +#define HNS_MAC_LINK_WAIT_TIME 5 +#define HNS_MAC_LINK_WAIT_CNT 40 + + u32 link_status = 0; + int i; + + if (!mac_ctrl_drv->get_link_status) + return link_status; + + for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { + msleep(HNS_MAC_LINK_WAIT_TIME); + mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); + if (!link_status) + break; + } + + return link_status; +} + void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) { struct mac_driver *mac_ctrl_drv; @@ -83,6 +104,14 @@ &sfp_prsnt); if (!ret) *link_status = *link_status && sfp_prsnt; + + /* for FIBER port, it may have a fake link up. + * when the link status changes from down to up, we need to do + * anti-shake. the anti-shake time is base on tests. + * only FIBER port need to do this. + */ + if (*link_status && !mac_cb->link) + *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); } mac_cb->link = *link_status; @@ -904,6 +933,7 @@ mac_cb->cpld_ctrl = NULL; } else { syscon = syscon_node_to_regmap(cpld_args.np); + of_node_put(cpld_args.np); if (IS_ERR_OR_NULL(syscon)) { dev_dbg(mac_cb->dev, "no cpld-syscon found!\n"); mac_cb->cpld_ctrl = NULL; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -398,6 +398,10 @@ return; if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) { + /* DSAF_MAX_PORT_NUM is 6, but DSAF_GE_NUM is 8. + We need check to prevent array overflow */ + if (port >= DSAF_MAX_PORT_NUM) + return; reg_val_1 = 0x1 << port; port_rst_off = dsaf_dev->mac_cb[port]->port_rst_off; /* there is difference between V1 and V2 in register.*/ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -565,7 +565,6 @@ skb = *out_skb = napi_alloc_skb(&ring_data->napi, HNS_RX_HEAD_SIZE); if (unlikely(!skb)) { - netdev_err(ndev, "alloc rx skb fail\n"); ring->stats.sw_err_cnt++; return -ENOMEM; } @@ -1056,7 +1055,6 @@ container_of(napi, struct hns_nic_ring_data, napi); struct hnae_ring *ring = ring_data->ring; -try_again: clean_complete += ring_data->poll_one( ring_data, budget - clean_complete, ring_data->ex_process); @@ -1066,7 +1064,7 @@ napi_complete(napi); ring->q->handle->dev->ops->toggle_ring_irq(ring, 0); } else { - goto try_again; + return budget; } } @@ -1679,8 +1677,10 @@ for (j = 0; j < fetch_num; j++) { /* alloc one skb and init */ skb = hns_assemble_skb(ndev); - if (!skb) + if (!skb) { + ret = -ENOMEM; goto out; + } rd = &tx_ring_data(priv, skb->queue_mapping); hns_nic_net_xmit_hw(ndev, skb, rd); @@ -2298,8 +2298,10 @@ priv->enet_ver = AE_VERSION_1; else if (acpi_dev_found(hns_enet_acpi_match[1].id)) priv->enet_ver = AE_VERSION_2; - else - return -ENXIO; + else { + ret = -ENXIO; + goto out_read_prop_fail; + } /* try to find port-idx-in-ae first */ ret = acpi_node_get_property_reference(dev->fwnode, @@ -2315,7 +2317,8 @@ priv->fwnode = args.fwnode; } else { dev_err(dev, "cannot read cfg data from OF or acpi\n"); - return -ENXIO; + ret = -ENXIO; + goto out_read_prop_fail; } ret = device_property_read_u32(dev, "port-idx-in-ae", &port_id); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -415,6 +415,10 @@ /* for mutl buffer*/ new_skb = skb_copy(skb, GFP_ATOMIC); dev_kfree_skb_any(skb); + if (!new_skb) { + netdev_err(ndev, "skb alloc failed\n"); + return; + } skb = new_skb; check_ok = 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/Makefile +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/Makefile @@ -3,6 +3,8 @@ # Makefile for the HISILICON network device drivers. # +ccflags-y += -I$(srctree)/$(src) + obj-$(CONFIG_HNS3) += hns3pf/ obj-$(CONFIG_HNS3) += hns3vf/ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -45,8 +45,10 @@ HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */ HCLGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */ HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */ + HCLGE_MBX_PUSH_PROMISC_INFO, /* (PF -> VF) push vf promisc info */ + HCLGE_MBX_VF_UNINIT, /* (VF -> PF) vf is unintializing */ - HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */ + HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf flr status */ HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */ HCLGE_MBX_NCSI_ERROR, /* (M7 -> PF) receive a NCSI error */ }; @@ -71,7 +73,7 @@ }; #define HCLGE_MBX_MAX_MSG_SIZE 16 -#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8 +#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8U #define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM 3 #define HCLGE_MBX_RING_NODE_VARIABLE_NUM 3 @@ -123,7 +125,7 @@ #define hclge_mbx_ring_ptr_move_crq(crq) \ (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) #define hclge_mbx_tail_ptr_move_arq(arq) \ - (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) + (arq.tail = (arq.tail + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) #define hclge_mbx_head_ptr_move_arq(arq) \ - (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_SIZE) + (arq.head = (arq.head + 1) % HCLGE_MBX_MAX_ARQ_MSG_NUM) #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -10,6 +10,30 @@ static LIST_HEAD(hnae3_client_list); static LIST_HEAD(hnae3_ae_dev_list); +void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo) +{ + const struct pci_device_id *pci_id; + struct hnae3_ae_dev *ae_dev; + + if (!ae_algo) + return; + + list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) { + if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)) + continue; + + pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev); + if (!pci_id) + continue; + if (IS_ENABLED(CONFIG_PCI_IOV)) { + device_lock(&ae_dev->pdev->dev); + pci_disable_sriov(ae_dev->pdev); + device_unlock(&ae_dev->pdev->dev); + } + } +} +EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare); + /* we are keeping things simple and using single lock for all the * list. This is a non-critical code so other updations, if happen * in parallel, can wait. @@ -146,7 +170,7 @@ return; mutex_lock(&hnae3_common_lock); - + /* one system should only have one client for every type */ list_for_each_entry(client_tmp, &hnae3_client_list, node) { if (client_tmp->type == client->type) { existed = true; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -77,6 +77,7 @@ ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num) enum hns_desc_type { + DESC_TYPE_UNKNOWN, DESC_TYPE_SKB, DESC_TYPE_PAGE, }; @@ -130,7 +131,6 @@ HNAE3_MODULE_TYPE_CR = 0x04, HNAE3_MODULE_TYPE_KR = 0x05, HNAE3_MODULE_TYPE_TP = 0x06, - }; enum hnae3_fec_mode { @@ -165,11 +165,7 @@ HNAE3_IMP_RESET, HNAE3_UNKNOWN_RESET, HNAE3_NONE_RESET, -}; - -enum hnae3_flr_state { - HNAE3_FLR_DOWN, - HNAE3_FLR_DONE, + HNAE3_MAX_RESET, }; enum hnae3_port_base_vlan_state { @@ -366,6 +362,19 @@ * Enable/disable HW GRO * add_arfs_entry * Check the 5-tuples of flow, and create flow director rule + * get_vf_config + * Get the VF configuration setting by the host + * set_vf_link_state + * Set VF link status + * set_vf_spoofchk + * Enable/disable spoof check for specified vf + * set_vf_trust + * Enable/disable trust for specified vf, if the vf being trusted, then + * it can enable promisc mode + * set_vf_rate + * Set the max tx rate of specified vf. + * set_vf_mac + * Configure the default MAC for specified VF */ struct hnae3_ae_ops { int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev); @@ -531,6 +540,16 @@ int (*mac_connect_phy)(struct hnae3_handle *handle); void (*mac_disconnect_phy)(struct hnae3_handle *handle); void (*restore_vlan_table)(struct hnae3_handle *handle); + int (*get_vf_config)(struct hnae3_handle *handle, int vf, + struct ifla_vf_info *ivf); + int (*set_vf_link_state)(struct hnae3_handle *handle, int vf, + int link_state); + int (*set_vf_spoofchk)(struct hnae3_handle *handle, int vf, + bool enable); + int (*set_vf_trust)(struct hnae3_handle *handle, int vf, bool enable); + int (*set_vf_rate)(struct hnae3_handle *handle, int vf, + int min_tx_rate, int max_tx_rate, bool force); + int (*set_vf_mac)(struct hnae3_handle *handle, int vf, u8 *p); }; struct hnae3_dcb_ops { @@ -553,7 +572,7 @@ const struct pci_device_id *pdev_id_table; }; -#define HNAE3_INT_NAME_LEN (IFNAMSIZ + 16) +#define HNAE3_INT_NAME_LEN 32 #define HNAE3_ITR_COUNTDOWN_START 100 struct hnae3_tc_info { @@ -665,6 +684,7 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev); void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev); +void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo); void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo); void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -16,15 +16,14 @@ const char *cmd_buf) { struct hns3_nic_priv *priv = h->priv; - struct hns3_nic_ring_data *ring_data; struct hns3_enet_ring *ring; u32 base_add_l, base_add_h; u32 queue_num, queue_max; u32 value, i = 0; int cnt; - if (!priv->ring_data) { - dev_err(&h->pdev->dev, "ring_data is NULL\n"); + if (!priv->ring) { + dev_err(&h->pdev->dev, "priv->ring is NULL\n"); return -EFAULT; } @@ -44,7 +43,6 @@ return -EINVAL; } - ring_data = priv->ring_data; for (i = queue_num; i < queue_max; i++) { /* Each cycle needs to determine whether the instance is reset, * to prevent reference to invalid memory. And need to ensure @@ -54,73 +52,73 @@ test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) return -EPERM; - ring = ring_data[(u32)(i + h->kinfo.num_tqps)].ring; + ring = &priv->ring[(u32)(i + h->kinfo.num_tqps)]; base_add_h = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_BASEADDR_H_REG); base_add_l = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_BASEADDR_L_REG); - dev_info(&h->pdev->dev, "RX(%d) BASE ADD: 0x%08x%08x\n", i, + dev_info(&h->pdev->dev, "RX(%u) BASE ADD: 0x%08x%08x\n", i, base_add_h, base_add_l); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_BD_NUM_REG); - dev_info(&h->pdev->dev, "RX(%d) RING BD NUM: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING BD NUM: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_BD_LEN_REG); - dev_info(&h->pdev->dev, "RX(%d) RING BD LEN: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING BD LEN: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG); - dev_info(&h->pdev->dev, "RX(%d) RING TAIL: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING TAIL: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); - dev_info(&h->pdev->dev, "RX(%d) RING HEAD: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING HEAD: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG); - dev_info(&h->pdev->dev, "RX(%d) RING FBDNUM: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING FBDNUM: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_PKTNUM_RECORD_REG); - dev_info(&h->pdev->dev, "RX(%d) RING PKTNUM: %u\n", i, value); + dev_info(&h->pdev->dev, "RX(%u) RING PKTNUM: %u\n", i, value); - ring = ring_data[i].ring; + ring = &priv->ring[i]; base_add_h = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_BASEADDR_H_REG); base_add_l = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_BASEADDR_L_REG); - dev_info(&h->pdev->dev, "TX(%d) BASE ADD: 0x%08x%08x\n", i, + dev_info(&h->pdev->dev, "TX(%u) BASE ADD: 0x%08x%08x\n", i, base_add_h, base_add_l); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_BD_NUM_REG); - dev_info(&h->pdev->dev, "TX(%d) RING BD NUM: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING BD NUM: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_TC_REG); - dev_info(&h->pdev->dev, "TX(%d) RING TC: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING TC: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); - dev_info(&h->pdev->dev, "TX(%d) RING TAIL: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING TAIL: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_HEAD_REG); - dev_info(&h->pdev->dev, "TX(%d) RING HEAD: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING HEAD: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_FBDNUM_REG); - dev_info(&h->pdev->dev, "TX(%d) RING FBDNUM: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING FBDNUM: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_OFFSET_REG); - dev_info(&h->pdev->dev, "TX(%d) RING OFFSET: %u\n", i, value); + dev_info(&h->pdev->dev, "TX(%u) RING OFFSET: %u\n", i, value); value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_PKTNUM_RECORD_REG); - dev_info(&h->pdev->dev, "TX(%d) RING PKTNUM: %u\n\n", i, + dev_info(&h->pdev->dev, "TX(%u) RING PKTNUM: %u\n\n", i, value); } @@ -130,7 +128,6 @@ static int hns3_dbg_queue_map(struct hnae3_handle *h) { struct hns3_nic_priv *priv = h->priv; - struct hns3_nic_ring_data *ring_data; int i; if (!h->ae_algo->ops->get_global_queue_id) @@ -143,15 +140,12 @@ u16 global_qid; global_qid = h->ae_algo->ops->get_global_queue_id(h, i); - ring_data = &priv->ring_data[i]; - if (!ring_data || !ring_data->ring || - !ring_data->ring->tqp_vector) + if (!priv->ring || !priv->ring[i].tqp_vector) continue; dev_info(&h->pdev->dev, " %4d %4d %4d\n", - i, global_qid, - ring_data->ring->tqp_vector->vector_irq); + i, global_qid, priv->ring[i].tqp_vector->vector_irq); } return 0; @@ -160,7 +154,6 @@ static int hns3_dbg_bd_info(struct hnae3_handle *h, const char *cmd_buf) { struct hns3_nic_priv *priv = h->priv; - struct hns3_nic_ring_data *ring_data; struct hns3_desc *rx_desc, *tx_desc; struct device *dev = &h->pdev->dev; struct hns3_enet_ring *ring; @@ -183,8 +176,7 @@ return -EINVAL; } - ring_data = priv->ring_data; - ring = ring_data[q_num].ring; + ring = &priv->ring[q_num]; value = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); tx_index = (cnt == 1) ? value : tx_index; @@ -198,39 +190,46 @@ addr = le64_to_cpu(tx_desc->addr); dev_info(dev, "TX Queue Num: %u, BD Index: %u\n", q_num, tx_index); dev_info(dev, "(TX)addr: %pad\n", &addr); - dev_info(dev, "(TX)vlan_tag: %u\n", tx_desc->tx.vlan_tag); - dev_info(dev, "(TX)send_size: %u\n", tx_desc->tx.send_size); + dev_info(dev, "(TX)vlan_tag: %u\n", le16_to_cpu(tx_desc->tx.vlan_tag)); + dev_info(dev, "(TX)send_size: %u\n", + le16_to_cpu(tx_desc->tx.send_size)); dev_info(dev, "(TX)vlan_tso: %u\n", tx_desc->tx.type_cs_vlan_tso); dev_info(dev, "(TX)l2_len: %u\n", tx_desc->tx.l2_len); dev_info(dev, "(TX)l3_len: %u\n", tx_desc->tx.l3_len); dev_info(dev, "(TX)l4_len: %u\n", tx_desc->tx.l4_len); - dev_info(dev, "(TX)vlan_tag: %u\n", tx_desc->tx.outer_vlan_tag); - dev_info(dev, "(TX)tv: %u\n", tx_desc->tx.tv); + dev_info(dev, "(TX)vlan_tag: %u\n", + le16_to_cpu(tx_desc->tx.outer_vlan_tag)); + dev_info(dev, "(TX)tv: %u\n", le16_to_cpu(tx_desc->tx.tv)); dev_info(dev, "(TX)vlan_msec: %u\n", tx_desc->tx.ol_type_vlan_msec); dev_info(dev, "(TX)ol2_len: %u\n", tx_desc->tx.ol2_len); dev_info(dev, "(TX)ol3_len: %u\n", tx_desc->tx.ol3_len); dev_info(dev, "(TX)ol4_len: %u\n", tx_desc->tx.ol4_len); - dev_info(dev, "(TX)paylen: %u\n", tx_desc->tx.paylen); - dev_info(dev, "(TX)vld_ra_ri: %u\n", tx_desc->tx.bdtp_fe_sc_vld_ra_ri); - dev_info(dev, "(TX)mss: %u\n", tx_desc->tx.mss); + dev_info(dev, "(TX)paylen: %u\n", le32_to_cpu(tx_desc->tx.paylen)); + dev_info(dev, "(TX)vld_ra_ri: %u\n", + le16_to_cpu(tx_desc->tx.bdtp_fe_sc_vld_ra_ri)); + dev_info(dev, "(TX)mss: %u\n", le16_to_cpu(tx_desc->tx.mss)); - ring = ring_data[q_num + h->kinfo.num_tqps].ring; + ring = &priv->ring[q_num + h->kinfo.num_tqps]; value = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_TAIL_REG); rx_index = (cnt == 1) ? value : tx_index; - rx_desc = &ring->desc[rx_index]; + rx_desc = &ring->desc[rx_index]; addr = le64_to_cpu(rx_desc->addr); dev_info(dev, "RX Queue Num: %u, BD Index: %u\n", q_num, rx_index); dev_info(dev, "(RX)addr: %pad\n", &addr); - dev_info(dev, "(RX)l234_info: %u\n", rx_desc->rx.l234_info); - dev_info(dev, "(RX)pkt_len: %u\n", rx_desc->rx.pkt_len); - dev_info(dev, "(RX)size: %u\n", rx_desc->rx.size); - dev_info(dev, "(RX)rss_hash: %u\n", rx_desc->rx.rss_hash); - dev_info(dev, "(RX)fd_id: %u\n", rx_desc->rx.fd_id); - dev_info(dev, "(RX)vlan_tag: %u\n", rx_desc->rx.vlan_tag); - dev_info(dev, "(RX)o_dm_vlan_id_fb: %u\n", rx_desc->rx.o_dm_vlan_id_fb); - dev_info(dev, "(RX)ot_vlan_tag: %u\n", rx_desc->rx.ot_vlan_tag); - dev_info(dev, "(RX)bd_base_info: %u\n", rx_desc->rx.bd_base_info); + dev_info(dev, "(RX)l234_info: %u\n", + le32_to_cpu(rx_desc->rx.l234_info)); + dev_info(dev, "(RX)pkt_len: %u\n", le16_to_cpu(rx_desc->rx.pkt_len)); + dev_info(dev, "(RX)size: %u\n", le16_to_cpu(rx_desc->rx.size)); + dev_info(dev, "(RX)rss_hash: %u\n", le32_to_cpu(rx_desc->rx.rss_hash)); + dev_info(dev, "(RX)fd_id: %u\n", le16_to_cpu(rx_desc->rx.fd_id)); + dev_info(dev, "(RX)vlan_tag: %u\n", le16_to_cpu(rx_desc->rx.vlan_tag)); + dev_info(dev, "(RX)o_dm_vlan_id_fb: %u\n", + le16_to_cpu(rx_desc->rx.o_dm_vlan_id_fb)); + dev_info(dev, "(RX)ot_vlan_tag: %u\n", + le16_to_cpu(rx_desc->rx.ot_vlan_tag)); + dev_info(dev, "(RX)bd_base_info: %u\n", + le32_to_cpu(rx_desc->rx.bd_base_info)); return 0; } @@ -261,6 +260,8 @@ dev_info(&h->pdev->dev, "dump m7 info\n"); dev_info(&h->pdev->dev, "dump ncl_config (in hex)\n"); dev_info(&h->pdev->dev, "dump mac tnl status\n"); + dev_info(&h->pdev->dev, "dump loopback\n"); + dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n"); memset(printf_buf, 0, HNS3_DBG_BUF_LEN); strncat(printf_buf, "dump reg [[bios common] [ssu ]", @@ -298,8 +299,8 @@ if (!buf) return -ENOMEM; - len = snprintf(buf, HNS3_DBG_READ_LEN, "%s\n", - "Please echo help to cmd to get help information"); + len = scnprintf(buf, HNS3_DBG_READ_LEN, "%s\n", + "Please echo help to cmd to get help information"); uncopy_bytes = copy_to_user(buffer, buf, len); kfree(buf); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -21,9 +21,16 @@ #include #include #include +#include #include "hnae3.h" #include "hns3_enet.h" +/* All hns3 tracepoints are defined by the include below, which + * must be included exactly once across the whole kernel with + * CREATE_TRACE_POINTS defined + */ +#define CREATE_TRACE_POINTS +#include "hns3_trace.h" #define hns3_set_field(origin, shift, val) ((origin) |= ((val) << (shift))) #define hns3_tx_bd_count(S) DIV_ROUND_UP(S, HNS3_MAX_BD_SIZE) @@ -54,6 +61,9 @@ #define HNS3_INNER_VLAN_TAG 1 #define HNS3_OUTER_VLAN_TAG 2 +#define HNS3_MIN_TX_LEN 33U +#define HNS3_MIN_TUN_PKT_LEN 65U + /* hns3_pci_tbl - PCI Device ID Table * * Last entry must be all 0s @@ -127,18 +137,21 @@ continue; if (tqp_vectors->tx_group.ring && tqp_vectors->rx_group.ring) { - snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN - 1, - "%s-%s-%d", priv->netdev->name, "TxRx", - txrx_int_idx++); + snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN, + "%s-%s-%s-%d", hns3_driver_name, + pci_name(priv->ae_handle->pdev), + "TxRx", txrx_int_idx++); txrx_int_idx++; } else if (tqp_vectors->rx_group.ring) { - snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN - 1, - "%s-%s-%d", priv->netdev->name, "Rx", - rx_int_idx++); + snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN, + "%s-%s-%s-%d", hns3_driver_name, + pci_name(priv->ae_handle->pdev), + "Rx", rx_int_idx++); } else if (tqp_vectors->tx_group.ring) { - snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN - 1, - "%s-%s-%d", priv->netdev->name, "Tx", - tx_int_idx++); + snprintf(tqp_vectors->name, HNAE3_INT_NAME_LEN, + "%s-%s-%s-%d", hns3_driver_name, + pci_name(priv->ae_handle->pdev), + "Tx", tx_int_idx++); } else { /* Skip this unused q_vector */ continue; @@ -155,6 +168,8 @@ return ret; } + disable_irq(tqp_vectors->vector_irq); + irq_set_affinity_hint(tqp_vectors->vector_irq, &tqp_vectors->affinity_mask); @@ -173,6 +188,7 @@ static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector) { napi_enable(&tqp_vector->napi); + enable_irq(tqp_vector->vector_irq); /* enable vector */ hns3_mask_vector_irq(tqp_vector, 1); @@ -372,18 +388,6 @@ if (ret) return ret; - /* the device can work without cpu rmap, only aRFS needs it */ - ret = hns3_set_rx_cpu_rmap(netdev); - if (ret) - netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret); - - /* get irq resource for all vectors */ - ret = hns3_nic_init_irq(priv); - if (ret) { - netdev_err(netdev, "init irq failed! ret=%d\n", ret); - goto free_rmap; - } - clear_bit(HNS3_NIC_STATE_DOWN, &priv->state); /* enable the vectors */ @@ -396,22 +400,15 @@ /* start the ae_dev */ ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0; - if (ret) - goto out_start_err; - - return 0; - -out_start_err: - set_bit(HNS3_NIC_STATE_DOWN, &priv->state); - while (j--) - hns3_tqp_disable(h->kinfo.tqp[j]); + if (ret) { + set_bit(HNS3_NIC_STATE_DOWN, &priv->state); + while (j--) + hns3_tqp_disable(h->kinfo.tqp[j]); - for (j = i - 1; j >= 0; j--) - hns3_vector_disable(&priv->tqp_vector[j]); + for (j = i - 1; j >= 0; j--) + hns3_vector_disable(&priv->tqp_vector[j]); + } - hns3_nic_uninit_irq(priv); -free_rmap: - hns3_free_rx_cpu_rmap(netdev); return ret; } @@ -448,6 +445,11 @@ if (hns3_nic_resetting(netdev)) return -EBUSY; + if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) { + netdev_warn(netdev, "net open repeatedly!\n"); + return 0; + } + netif_carrier_off(netdev); ret = hns3_nic_set_real_num_queue(netdev); @@ -483,7 +485,7 @@ for (i = 0; i < h->kinfo.num_tqps; i++) { dev_queue = netdev_get_tx_queue(ndev, - priv->ring_data[i].queue_index); + priv->ring[i].queue_index); netdev_tx_reset_queue(dev_queue); } } @@ -508,11 +510,6 @@ if (ops->stop) ops->stop(priv->ae_handle); - hns3_free_rx_cpu_rmap(netdev); - - /* free irq resources */ - hns3_nic_uninit_irq(priv); - /* delay ring buffer clearing to hns3_reset_notify_uninit_enet * during reset process, because driver may not be able * to disable the ring through firmware when downing the netdev. @@ -536,8 +533,8 @@ if (h->ae_algo->ops->set_timer_task) h->ae_algo->ops->set_timer_task(priv->ae_handle, false); - netif_tx_stop_all_queues(netdev); netif_carrier_off(netdev); + netif_tx_disable(netdev); hns3_nic_net_down(netdev); @@ -681,7 +678,7 @@ return 0; ret = skb_cow_head(skb, 0); - if (unlikely(ret)) + if (unlikely(ret < 0)) return ret; l3.hdr = skb_network_header(skb); @@ -734,6 +731,8 @@ /* get MSS for TSO */ *mss = skb_shinfo(skb)->gso_size; + trace_hns3_tso(skb); + return 0; } @@ -793,7 +792,7 @@ * and it is udp packet, which has a dest port as the IANA assigned. * the hardware is expected to do the checksum offload, but the * hardware will not do the checksum offload when udp dest port is - * 4789. + * 4789, 4790 or 6081. */ static bool hns3_tunnel_csum_bug(struct sk_buff *skb) { @@ -802,11 +801,11 @@ l4.hdr = skb_transport_header(skb); if (!(!skb->encapsulation && - l4.udp->dest == htons(IANA_VXLAN_UDP_PORT))) + (l4.udp->dest == htons(IANA_VXLAN_UDP_PORT) || + l4.udp->dest == htons(GENEVE_UDP_PORT) || + l4.udp->dest == htons(4790)))) return false; - skb_checksum_help(skb); - return true; } @@ -884,8 +883,7 @@ /* the stack computes the IP header already, * driver calculate l4 checksum when not TSO. */ - skb_checksum_help(skb); - return 0; + return skb_checksum_help(skb); } hns3_set_outer_l2l3l4(skb, ol4_proto, ol_type_vlan_len_msec); @@ -929,8 +927,11 @@ l4.tcp->doff); break; case IPPROTO_UDP: - if (hns3_tunnel_csum_bug(skb)) - break; + if (hns3_tunnel_csum_bug(skb)) { + int ret = skb_put_padto(skb, HNS3_MIN_TUN_PKT_LEN); + + return ret ? ret : skb_checksum_help(skb); + } hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4CS_B, 1); hns3_set_field(*type_cs_vlan_tso, HNS3_TXD_L4T_S, @@ -955,21 +956,12 @@ /* the stack computes the IP header already, * driver calculate l4 checksum when not TSO. */ - skb_checksum_help(skb); - return 0; + return skb_checksum_help(skb); } return 0; } -static void hns3_set_txbd_baseinfo(u16 *bdtp_fe_sc_vld_ra_ri, int frag_end) -{ - /* Config bd buffer end */ - if (!!frag_end) - hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, 1U); - hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1U); -} - static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring, struct sk_buff *skb) { @@ -1062,7 +1054,7 @@ skb_reset_mac_len(skb); ret = hns3_get_l4_protocol(skb, &ol4_proto, &il4_proto); - if (unlikely(ret)) { + if (unlikely(ret < 0)) { u64_stats_update_begin(&ring->syncp); ring->stats.tx_l4_proto_err++; u64_stats_update_end(&ring->syncp); @@ -1072,7 +1064,7 @@ ret = hns3_set_l2l3l4(skb, ol4_proto, il4_proto, &type_cs_vlan_tso, &ol_type_vlan_len_msec); - if (unlikely(ret)) { + if (unlikely(ret < 0)) { u64_stats_update_begin(&ring->syncp); ring->stats.tx_l2l3l4_err++; u64_stats_update_end(&ring->syncp); @@ -1081,7 +1073,7 @@ ret = hns3_set_tso(skb, &paylen, &mss, &type_cs_vlan_tso); - if (unlikely(ret)) { + if (unlikely(ret < 0)) { u64_stats_update_begin(&ring->syncp); ring->stats.tx_tso_err++; u64_stats_update_end(&ring->syncp); @@ -1102,9 +1094,10 @@ } static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, - unsigned int size, int frag_end, - enum hns_desc_type type) + unsigned int size, enum hns_desc_type type) { +#define HNS3_LIKELY_BD_NUM 1 + struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; struct hns3_desc *desc = &ring->desc[ring->next_to_use]; struct device *dev = ring_to_dev(ring); @@ -1118,7 +1111,7 @@ int ret; ret = hns3_fill_skb_desc(ring, skb, desc); - if (unlikely(ret)) + if (unlikely(ret < 0)) return ret; dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); @@ -1137,19 +1130,17 @@ desc_cb->length = size; if (likely(size <= HNS3_MAX_BD_SIZE)) { - u16 bdtp_fe_sc_vld_ra_ri = 0; - desc_cb->priv = priv; desc_cb->dma = dma; desc_cb->type = type; desc->addr = cpu_to_le64(dma); desc->tx.send_size = cpu_to_le16(size); - hns3_set_txbd_baseinfo(&bdtp_fe_sc_vld_ra_ri, frag_end); desc->tx.bdtp_fe_sc_vld_ra_ri = - cpu_to_le16(bdtp_fe_sc_vld_ra_ri); + cpu_to_le16(BIT(HNS3_TXD_VLD_B)); + trace_hns3_tx_desc(ring, ring->next_to_use); ring_ptr_move_fw(ring, next_to_use); - return 0; + return HNS3_LIKELY_BD_NUM; } frag_buf_num = hns3_tx_bd_count(size); @@ -1158,8 +1149,6 @@ /* When frag size is bigger than hardware limit, split this frag */ for (k = 0; k < frag_buf_num; k++) { - u16 bdtp_fe_sc_vld_ra_ri = 0; - /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */ desc_cb->priv = priv; desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k; @@ -1170,12 +1159,10 @@ desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k); desc->tx.send_size = cpu_to_le16((k == frag_buf_num - 1) ? (u16)sizeoflast : (u16)HNS3_MAX_BD_SIZE); - hns3_set_txbd_baseinfo(&bdtp_fe_sc_vld_ra_ri, - frag_end && (k == frag_buf_num - 1) ? - 1 : 0); desc->tx.bdtp_fe_sc_vld_ra_ri = - cpu_to_le16(bdtp_fe_sc_vld_ra_ri); + cpu_to_le16(BIT(HNS3_TXD_VLD_B)); + trace_hns3_tx_desc(ring, ring->next_to_use); /* move ring pointer to next */ ring_ptr_move_fw(ring, next_to_use); @@ -1183,23 +1170,78 @@ desc = &ring->desc[ring->next_to_use]; } - return 0; + return frag_buf_num; } -static unsigned int hns3_nic_bd_num(struct sk_buff *skb) +static unsigned int hns3_skb_bd_num(struct sk_buff *skb, unsigned int *bd_size, + unsigned int bd_num) { - unsigned int bd_num; + unsigned int size; int i; - /* if the total len is within the max bd limit */ - if (likely(skb->len <= HNS3_MAX_BD_SIZE)) - return skb_shinfo(skb)->nr_frags + 1; + size = skb_headlen(skb); + while (size > HNS3_MAX_BD_SIZE) { + bd_size[bd_num++] = HNS3_MAX_BD_SIZE; + size -= HNS3_MAX_BD_SIZE; + + if (bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; + } - bd_num = hns3_tx_bd_count(skb_headlen(skb)); + if (size) { + bd_size[bd_num++] = size; + if (bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; + } for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - bd_num += hns3_tx_bd_count(skb_frag_size(frag)); + size = skb_frag_size(frag); + if (!size) + continue; + + while (size > HNS3_MAX_BD_SIZE) { + bd_size[bd_num++] = HNS3_MAX_BD_SIZE; + size -= HNS3_MAX_BD_SIZE; + + if (bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; + } + + bd_size[bd_num++] = size; + if (bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; + } + + return bd_num; +} + +static unsigned int hns3_tx_bd_num(struct sk_buff *skb, unsigned int *bd_size) +{ + struct sk_buff *frag_skb; + unsigned int bd_num = 0; + + /* If the total len is within the max bd limit */ + if (likely(skb->len <= HNS3_MAX_BD_SIZE && !skb_has_frag_list(skb) && + skb_shinfo(skb)->nr_frags < HNS3_MAX_NON_TSO_BD_NUM)) + return skb_shinfo(skb)->nr_frags + 1U; + + /* The below case will always be linearized, return + * HNS3_MAX_BD_NUM_TSO + 1U to make sure it is linearized. + */ + if (unlikely(skb->len > HNS3_MAX_TSO_SIZE || + (!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE))) + return HNS3_MAX_TSO_BD_NUM + 1U; + + bd_num = hns3_skb_bd_num(skb, bd_size, bd_num); + + if (!skb_has_frag_list(skb) || bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; + + skb_walk_frags(skb, frag_skb) { + bd_num = hns3_skb_bd_num(frag_skb, bd_size, bd_num); + if (bd_num > HNS3_MAX_TSO_BD_NUM) + return bd_num; } return bd_num; @@ -1218,26 +1260,26 @@ * 7 frags to to be larger than gso header len + mss, and the remaining * continuous 7 frags to be larger than MSS except the last 7 frags. */ -static bool hns3_skb_need_linearized(struct sk_buff *skb) +static bool hns3_skb_need_linearized(struct sk_buff *skb, unsigned int *bd_size, + unsigned int bd_num) { - int bd_limit = HNS3_MAX_BD_NUM_NORMAL - 1; unsigned int tot_len = 0; int i; - for (i = 0; i < bd_limit; i++) - tot_len += skb_frag_size(&skb_shinfo(skb)->frags[i]); + for (i = 0; i < HNS3_MAX_NON_TSO_BD_NUM - 1U; i++) + tot_len += bd_size[i]; - /* ensure headlen + the first 7 frags is greater than mss + header - * and the first 7 frags is greater than mss. - */ - if (((tot_len + skb_headlen(skb)) < (skb_shinfo(skb)->gso_size + - hns3_gso_hdr_len(skb))) || (tot_len < skb_shinfo(skb)->gso_size)) + /* ensure the first 8 frags is greater than mss + header */ + if (tot_len + bd_size[HNS3_MAX_NON_TSO_BD_NUM - 1U] < + skb_shinfo(skb)->gso_size + hns3_gso_hdr_len(skb)) return true; - /* ensure the remaining continuous 7 buffer is greater than mss */ - for (i = 0; i < (skb_shinfo(skb)->nr_frags - bd_limit - 1); i++) { - tot_len -= skb_frag_size(&skb_shinfo(skb)->frags[i]); - tot_len += skb_frag_size(&skb_shinfo(skb)->frags[i + bd_limit]); + /* ensure every continuous 7 buffer is greater than mss + * except the last one. + */ + for (i = 0; i < bd_num - HNS3_MAX_NON_TSO_BD_NUM; i++) { + tot_len -= bd_size[i]; + tot_len += bd_size[i + HNS3_MAX_NON_TSO_BD_NUM - 1U]; if (tot_len < skb_shinfo(skb)->gso_size) return true; @@ -1246,31 +1288,40 @@ return false; } +void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size) +{ + int i = 0; + + for (i = 0; i < MAX_SKB_FRAGS; i++) + size[i] = skb_frag_size(&shinfo->frags[i]); +} + static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring, - struct sk_buff **out_skb) + struct net_device *netdev, + struct sk_buff *skb) { - struct sk_buff *skb = *out_skb; + struct hns3_nic_priv *priv = netdev_priv(netdev); + unsigned int bd_size[HNS3_MAX_TSO_BD_NUM + 1U]; unsigned int bd_num; - bd_num = hns3_nic_bd_num(skb); - if (unlikely(bd_num > HNS3_MAX_BD_NUM_NORMAL)) { - struct sk_buff *new_skb; - - if (skb_is_gso(skb) && bd_num <= HNS3_MAX_BD_NUM_TSO && - !hns3_skb_need_linearized(skb)) + bd_num = hns3_tx_bd_num(skb, bd_size); + if (unlikely(bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { + if (bd_num <= HNS3_MAX_TSO_BD_NUM && skb_is_gso(skb) && + !hns3_skb_need_linearized(skb, bd_size, bd_num)) { + trace_hns3_over_8bd(skb); goto out; + } - /* manual split the send packet */ - new_skb = skb_copy(skb, GFP_ATOMIC); - if (!new_skb) + if (__skb_linearize(skb)) return -ENOMEM; - dev_kfree_skb_any(skb); - *out_skb = new_skb; - bd_num = hns3_nic_bd_num(new_skb); - if ((skb_is_gso(new_skb) && bd_num > HNS3_MAX_BD_NUM_TSO) || - (!skb_is_gso(new_skb) && bd_num > HNS3_MAX_BD_NUM_NORMAL)) + bd_num = hns3_tx_bd_count(skb->len); + if ((skb_is_gso(skb) && bd_num > HNS3_MAX_TSO_BD_NUM) || + (!skb_is_gso(skb) && + bd_num > HNS3_MAX_NON_TSO_BD_NUM)) { + trace_hns3_over_8bd(skb); return -ENOMEM; + } u64_stats_update_begin(&ring->syncp); ring->stats.tx_copy++; @@ -1278,10 +1329,23 @@ } out: - if (unlikely(ring_space(ring) < bd_num)) - return -EBUSY; + if (likely(ring_space(ring) >= bd_num)) + return bd_num; - return bd_num; + netif_stop_subqueue(netdev, ring->queue_index); + smp_mb(); /* Memory barrier before checking ring_space */ + + /* Start queue in case hns3_clean_tx_ring has just made room + * available and has not seen the queue stopped state performed + * by netif_stop_subqueue above. + */ + if (ring_space(ring) >= bd_num && netif_carrier_ok(netdev) && + !test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) { + netif_start_subqueue(netdev, ring->queue_index); + return bd_num; + } + + return -EBUSY; } static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) @@ -1290,6 +1354,10 @@ unsigned int i; for (i = 0; i < ring->desc_num; i++) { + struct hns3_desc *desc = &ring->desc[ring->next_to_use]; + + memset(desc, 0, sizeof(*desc)); + /* check if this is where we started */ if (ring->next_to_use == next_to_use_orig) break; @@ -1297,6 +1365,9 @@ /* rollback one */ ring_ptr_move_bw(ring, next_to_use); + if (!ring->desc_cb[ring->next_to_use].dma) + continue; + /* unmap the descriptor dma address */ if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB) dma_unmap_single(dev, @@ -1311,76 +1382,107 @@ ring->desc_cb[ring->next_to_use].length = 0; ring->desc_cb[ring->next_to_use].dma = 0; + ring->desc_cb[ring->next_to_use].type = DESC_TYPE_UNKNOWN; } } +static int hns3_fill_skb_to_desc(struct hns3_enet_ring *ring, + struct sk_buff *skb, enum hns_desc_type type) +{ + unsigned int size = skb_headlen(skb); + int i, ret, bd_num = 0; + + if (size) { + ret = hns3_fill_desc(ring, skb, size, type); + if (unlikely(ret < 0)) + return ret; + + bd_num += ret; + } + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + size = skb_frag_size(frag); + if (!size) + continue; + + ret = hns3_fill_desc(ring, frag, size, DESC_TYPE_PAGE); + if (unlikely(ret < 0)) + return ret; + + bd_num += ret; + } + + return bd_num; +} + netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) { struct hns3_nic_priv *priv = netdev_priv(netdev); - struct hns3_nic_ring_data *ring_data = - &tx_ring_data(priv, skb->queue_mapping); - struct hns3_enet_ring *ring = ring_data->ring; + struct hns3_enet_ring *ring = &priv->ring[skb->queue_mapping]; struct netdev_queue *dev_queue; - skb_frag_t *frag; - int next_to_use_head; - int buf_num; - int seg_num; - int size; + int pre_ntu, next_to_use_head; + struct sk_buff *frag_skb; + int bd_num = 0; int ret; - int i; + + /* Hardware can only handle short frames above 32 bytes */ + if (skb_put_padto(skb, HNS3_MIN_TX_LEN)) + return NETDEV_TX_OK; /* Prefetch the data used later */ prefetch(skb->data); - buf_num = hns3_nic_maybe_stop_tx(ring, &skb); - if (unlikely(buf_num <= 0)) { - if (buf_num == -EBUSY) { + ret = hns3_nic_maybe_stop_tx(ring, netdev, skb); + if (unlikely(ret <= 0)) { + if (ret == -EBUSY) { u64_stats_update_begin(&ring->syncp); ring->stats.tx_busy++; u64_stats_update_end(&ring->syncp); - goto out_net_tx_busy; - } else if (buf_num == -ENOMEM) { + return NETDEV_TX_BUSY; + } else if (ret == -ENOMEM) { u64_stats_update_begin(&ring->syncp); ring->stats.sw_err_cnt++; u64_stats_update_end(&ring->syncp); } - hns3_rl_err(netdev, "xmit error: %d!\n", buf_num); + hns3_rl_err(netdev, "xmit error: %d!\n", ret); goto out_err_tx_ok; } - /* No. of segments (plus a header) */ - seg_num = skb_shinfo(skb)->nr_frags + 1; - /* Fill the first part */ - size = skb_headlen(skb); - next_to_use_head = ring->next_to_use; - ret = hns3_fill_desc(ring, skb, size, seg_num == 1 ? 1 : 0, - DESC_TYPE_SKB); - if (unlikely(ret)) + ret = hns3_fill_skb_to_desc(ring, skb, DESC_TYPE_SKB); + if (unlikely(ret < 0)) goto fill_err; - /* Fill the fragments */ - for (i = 1; i < seg_num; i++) { - frag = &skb_shinfo(skb)->frags[i - 1]; - size = skb_frag_size(frag); + bd_num += ret; - ret = hns3_fill_desc(ring, frag, size, - seg_num - 1 == i ? 1 : 0, - DESC_TYPE_PAGE); + if (!skb_has_frag_list(skb)) + goto out; - if (unlikely(ret)) + skb_walk_frags(skb, frag_skb) { + ret = hns3_fill_skb_to_desc(ring, frag_skb, DESC_TYPE_PAGE); + if (unlikely(ret < 0)) goto fill_err; + + bd_num += ret; } +out: + pre_ntu = ring->next_to_use ? (ring->next_to_use - 1) : + (ring->desc_num - 1); + ring->desc[pre_ntu].tx.bdtp_fe_sc_vld_ra_ri |= + cpu_to_le16(BIT(HNS3_TXD_FE_B)); + trace_hns3_tx_desc(ring, pre_ntu); /* Complete translate all packets */ - dev_queue = netdev_get_tx_queue(netdev, ring_data->queue_index); + dev_queue = netdev_get_tx_queue(netdev, ring->queue_index); netdev_tx_sent_queue(dev_queue, skb->len); wmb(); /* Commit all data before submit */ - hnae3_queue_xmit(ring->tqp, buf_num); + hnae3_queue_xmit(ring->tqp, bd_num); return NETDEV_TX_OK; @@ -1390,12 +1492,6 @@ out_err_tx_ok: dev_kfree_skb_any(skb); return NETDEV_TX_OK; - -out_net_tx_busy: - netif_stop_subqueue(netdev, ring_data->queue_index); - smp_mb(); /* Commit all data before submit */ - - return NETDEV_TX_BUSY; } static int hns3_nic_net_set_mac_address(struct net_device *netdev, void *p) @@ -1413,6 +1509,16 @@ return 0; } + /* For VF device, if there is a perm_addr, then the user will not + * be allowed to change the address. + */ + if (!hns3_is_phys_func(h->pdev) && + !is_zero_ether_addr(netdev->perm_addr)) { + netdev_err(netdev, "has permanent MAC %pM, user MAC %pM not allow\n", + netdev->perm_addr, mac_addr->sa_data); + return -EPERM; + } + ret = h->ae_algo->ops->set_mac_addr(h, mac_addr->sa_data, false); if (ret) { netdev_err(netdev, "set_mac_address fail, ret=%d!\n", ret); @@ -1477,6 +1583,37 @@ return 0; } +static netdev_features_t hns3_features_check(struct sk_buff *skb, + struct net_device *dev, + netdev_features_t features) +{ +#define HNS3_MAX_HDR_LEN 480U +#define HNS3_MAX_L4_HDR_LEN 60U + + size_t len; + + if (skb->ip_summed != CHECKSUM_PARTIAL) + return features; + + if (skb->encapsulation) + len = skb_inner_transport_header(skb) - skb->data; + else + len = skb_transport_header(skb) - skb->data; + + /* Assume L4 is 60 byte as TCP is the only protocol with a + * a flexible value, and it's max len is 60 bytes. + */ + len += HNS3_MAX_L4_HDR_LEN; + + /* Hardware only supports checksum on the skb with a max header + * len of 480 bytes. + */ + if (len > HNS3_MAX_HDR_LEN) + features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + + return features; +} + static void hns3_nic_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) { @@ -1505,7 +1642,7 @@ for (idx = 0; idx < queue_num; idx++) { /* fetch the tx stats */ - ring = priv->ring_data[idx].ring; + ring = &priv->ring[idx]; do { start = u64_stats_fetch_begin_irq(&ring->syncp); tx_bytes += ring->stats.tx_bytes; @@ -1523,7 +1660,7 @@ } while (u64_stats_fetch_retry_irq(&ring->syncp, start)); /* fetch the rx stats */ - ring = priv->ring_data[idx + queue_num].ring; + ring = &priv->ring[idx + queue_num]; do { start = u64_stats_fetch_begin_irq(&ring->syncp); rx_bytes += ring->stats.rx_bytes; @@ -1590,7 +1727,7 @@ netif_dbg(h, drv, netdev, "setup tc: num_tc=%u\n", tc); return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ? - kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP; + kinfo->dcb_ops->setup_tc(h, tc ? tc : 1, prio_tc) : -EOPNOTSUPP; } static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type, @@ -1633,8 +1770,8 @@ int ret = -EIO; netif_dbg(h, drv, netdev, - "set vf vlan: vf=%d, vlan=%u, qos=%u, vlan_proto=%u\n", - vf, vlan, qos, vlan_proto); + "set vf vlan: vf=%d, vlan=%u, qos=%u, vlan_proto=0x%x\n", + vf, vlan, qos, ntohs(vlan_proto)); if (h->ae_algo->ops->set_vf_vlan_filter) ret = h->ae_algo->ops->set_vf_vlan_filter(h, vf, vlan, @@ -1643,6 +1780,29 @@ return ret; } +static int hns3_set_vf_spoofchk(struct net_device *netdev, int vf, bool enable) +{ + struct hnae3_handle *handle = hns3_get_handle(netdev); + + if (hns3_nic_resetting(netdev)) + return -EBUSY; + + if (!handle->ae_algo->ops->set_vf_spoofchk) + return -EOPNOTSUPP; + + return handle->ae_algo->ops->set_vf_spoofchk(handle, vf, enable); +} + +static int hns3_set_vf_trust(struct net_device *netdev, int vf, bool enable) +{ + struct hnae3_handle *handle = hns3_get_handle(netdev); + + if (!handle->ae_algo->ops->set_vf_trust) + return -EOPNOTSUPP; + + return handle->ae_algo->ops->set_vf_trust(handle, vf, enable); +} + static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu) { struct hnae3_handle *h = hns3_get_handle(netdev); @@ -1671,7 +1831,7 @@ { struct hns3_nic_priv *priv = netdev_priv(ndev); struct hnae3_handle *h = hns3_get_handle(ndev); - struct hns3_enet_ring *tx_ring = NULL; + struct hns3_enet_ring *tx_ring; struct napi_struct *napi; int timeout_queue = 0; int hw_head, hw_tail; @@ -1692,6 +1852,9 @@ time_after(jiffies, (trans_start + ndev->watchdog_timeo))) { timeout_queue = i; + netdev_info(ndev, "queue state: 0x%lx, delta msecs: %u\n", + q->state, + jiffies_to_msecs(jiffies - trans_start)); break; } } @@ -1705,7 +1868,7 @@ priv->tx_timeout_count++; - tx_ring = priv->ring_data[timeout_queue].ring; + tx_ring = &priv->ring[timeout_queue]; napi = &tx_ring->tqp_vector->napi; netdev_info(ndev, @@ -1805,6 +1968,57 @@ } #endif +static int hns3_nic_get_vf_config(struct net_device *ndev, int vf, + struct ifla_vf_info *ivf) +{ + struct hnae3_handle *h = hns3_get_handle(ndev); + + if (!h->ae_algo->ops->get_vf_config) + return -EOPNOTSUPP; + + return h->ae_algo->ops->get_vf_config(h, vf, ivf); +} + +static int hns3_nic_set_vf_link_state(struct net_device *ndev, int vf, + int link_state) +{ + struct hnae3_handle *h = hns3_get_handle(ndev); + + if (!h->ae_algo->ops->set_vf_link_state) + return -EOPNOTSUPP; + + return h->ae_algo->ops->set_vf_link_state(h, vf, link_state); +} + +static int hns3_nic_set_vf_rate(struct net_device *ndev, int vf, + int min_tx_rate, int max_tx_rate) +{ + struct hnae3_handle *h = hns3_get_handle(ndev); + + if (!h->ae_algo->ops->set_vf_rate) + return -EOPNOTSUPP; + + return h->ae_algo->ops->set_vf_rate(h, vf, min_tx_rate, max_tx_rate, + false); +} + +static int hns3_nic_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac) +{ + struct hnae3_handle *h = hns3_get_handle(netdev); + + if (!h->ae_algo->ops->set_vf_mac) + return -EOPNOTSUPP; + + if (is_multicast_ether_addr(mac)) { + netdev_err(netdev, + "Invalid MAC:%pM specified. Could not set MAC\n", + mac); + return -EINVAL; + } + + return h->ae_algo->ops->set_vf_mac(h, vf_id, mac); +} + static const struct net_device_ops hns3_nic_netdev_ops = { .ndo_open = hns3_nic_net_open, .ndo_stop = hns3_nic_net_stop, @@ -1814,16 +2028,22 @@ .ndo_do_ioctl = hns3_nic_do_ioctl, .ndo_change_mtu = hns3_nic_change_mtu, .ndo_set_features = hns3_nic_set_features, + .ndo_features_check = hns3_features_check, .ndo_get_stats64 = hns3_nic_get_stats64, .ndo_setup_tc = hns3_nic_setup_tc, .ndo_set_rx_mode = hns3_nic_set_rx_mode, .ndo_vlan_rx_add_vid = hns3_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = hns3_vlan_rx_kill_vid, .ndo_set_vf_vlan = hns3_ndo_set_vf_vlan, + .ndo_set_vf_spoofchk = hns3_set_vf_spoofchk, + .ndo_set_vf_trust = hns3_set_vf_trust, #ifdef CONFIG_RFS_ACCEL .ndo_rx_flow_steer = hns3_rx_flow_steer, #endif - + .ndo_get_vf_config = hns3_nic_get_vf_config, + .ndo_set_vf_link_state = hns3_nic_set_vf_link_state, + .ndo_set_vf_rate = hns3_nic_set_vf_rate, + .ndo_set_vf_mac = hns3_nic_set_vf_mac, }; bool hns3_is_phys_func(struct pci_dev *pdev) @@ -1843,7 +2063,7 @@ case HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF: return false; default: - dev_warn(&pdev->dev, "un-recognized pci device-id %d", + dev_warn(&pdev->dev, "un-recognized pci device-id %u", dev_id); } @@ -2026,7 +2246,7 @@ { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); - dev_info(&pdev->dev, "hns3 flr prepare\n"); + dev_info(&pdev->dev, "FLR prepare\n"); if (ae_dev && ae_dev->ops && ae_dev->ops->flr_prepare) ae_dev->ops->flr_prepare(ae_dev); } @@ -2035,7 +2255,7 @@ { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); - dev_info(&pdev->dev, "hns3 flr done\n"); + dev_info(&pdev->dev, "FLR done\n"); if (ae_dev && ae_dev->ops && ae_dev->ops->flr_done) ae_dev->ops->flr_done(ae_dev); } @@ -2069,9 +2289,8 @@ NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC; - - netdev->hw_enc_features |= NETIF_F_TSO_MANGLEID; + NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC | + NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST; netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; @@ -2081,21 +2300,24 @@ NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC; + NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC | + NETIF_F_FRAGLIST; netdev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC; + NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC | + NETIF_F_FRAGLIST; netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC; + NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_SCTP_CRC | + NETIF_F_FRAGLIST; if (pdev->revision >= 0x21) { netdev->hw_features |= NETIF_F_GRO_HW; @@ -2320,21 +2542,22 @@ void hns3_clean_tx_ring(struct hns3_enet_ring *ring) { - struct net_device *netdev = ring->tqp->handle->kinfo.netdev; + struct net_device *netdev = ring_to_netdev(ring); struct hns3_nic_priv *priv = netdev_priv(netdev); struct netdev_queue *dev_queue; int bytes, pkts; int head; head = readl_relaxed(ring->tqp->io_base + HNS3_RING_TX_RING_HEAD_REG); - rmb(); /* Make sure head is ready before touch any data */ if (is_ring_empty(ring) || head == ring->next_to_clean) return; /* no data to poll */ + rmb(); /* Make sure head is ready before touch any data */ + if (unlikely(!is_valid_clean_head(ring, head))) { - netdev_err(netdev, "wrong head (%d, %d-%d)\n", head, - ring->next_to_use, ring->next_to_clean); + hns3_rl_err(netdev, "wrong head (%d, %d-%d)\n", head, + ring->next_to_use, ring->next_to_clean); u64_stats_update_begin(&ring->syncp); ring->stats.io_err_cnt++; @@ -2357,8 +2580,8 @@ dev_queue = netdev_get_tx_queue(netdev, ring->tqp->tqp_index); netdev_tx_completed_queue(dev_queue, pkts, bytes); - if (unlikely(pkts && netif_carrier_ok(netdev) && - (ring_space(ring) > HNS3_MAX_BD_PER_PKT))) { + if (unlikely(netif_carrier_ok(netdev) && + ring_space(ring) > HNS3_MAX_TSO_BD_NUM)) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ @@ -2401,7 +2624,7 @@ ring->stats.sw_err_cnt++; u64_stats_update_end(&ring->syncp); - hns3_rl_err(ring->tqp_vector->napi.dev, + hns3_rl_err(ring_to_netdev(ring), "alloc rx buffer failed: %d\n", ret); break; @@ -2420,6 +2643,12 @@ writel_relaxed(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG); } +static bool hns3_page_is_reusable(struct page *page) +{ + return page_to_nid(page) == numa_mem_id() && + !page_is_pfmemalloc(page); +} + static void hns3_nic_reuse_page(struct sk_buff *skb, int i, struct hns3_enet_ring *ring, int pull_len, struct hns3_desc_cb *desc_cb) @@ -2434,7 +2663,7 @@ /* Avoid re-using remote pages, or the stack is still using the page * when page_offset rollback to zero, flag default unreuse */ - if (unlikely(page_to_nid(desc_cb->priv) != numa_mem_id()) || + if (unlikely(!hns3_page_is_reusable(desc_cb->priv)) || (!desc_cb->page_offset && page_count(desc_cb->priv) > 1)) return; @@ -2504,13 +2733,16 @@ skb->csum_start = (unsigned char *)th - skb->head; skb->csum_offset = offsetof(struct tcphdr, check); skb->ip_summed = CHECKSUM_PARTIAL; + + trace_hns3_gro(skb); + return 0; } static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb, u32 l234info, u32 bd_base_info, u32 ol_info) { - struct net_device *netdev = ring->tqp->handle->kinfo.netdev; + struct net_device *netdev = ring_to_netdev(ring); int l3_type, l4_type; int ol4_type; @@ -2624,9 +2856,8 @@ static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length, unsigned char *va) { -#define HNS3_NEED_ADD_FRAG 1 struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_clean]; - struct net_device *netdev = ring->tqp->handle->kinfo.netdev; + struct net_device *netdev = ring_to_netdev(ring); struct sk_buff *skb; ring->skb = napi_alloc_skb(&ring->tqp_vector->napi, HNS3_RX_HEAD_SIZE); @@ -2641,6 +2872,7 @@ return -ENOMEM; } + trace_hns3_rx_desc(ring); prefetchw(skb->data); ring->pending_buf = 1; @@ -2650,7 +2882,7 @@ memcpy(__skb_put(skb, length), va, ALIGN(length, sizeof(long))); /* We can reuse buffer as-is, just make sure it is local */ - if (likely(page_to_nid(desc_cb->priv) == numa_mem_id())) + if (likely(hns3_page_is_reusable(desc_cb->priv))) desc_cb->reuse_flag = 1; else /* This page cannot be reused so discard it */ put_page(desc_cb->priv); @@ -2668,33 +2900,19 @@ desc_cb); ring_ptr_move_fw(ring, next_to_clean); - return HNS3_NEED_ADD_FRAG; + return 0; } -static int hns3_add_frag(struct hns3_enet_ring *ring, struct hns3_desc *desc, - struct sk_buff **out_skb, bool pending) +static int hns3_add_frag(struct hns3_enet_ring *ring) { - struct sk_buff *skb = *out_skb; - struct sk_buff *head_skb = *out_skb; + struct sk_buff *skb = ring->skb; + struct sk_buff *head_skb = skb; struct sk_buff *new_skb; struct hns3_desc_cb *desc_cb; - struct hns3_desc *pre_desc; + struct hns3_desc *desc; u32 bd_base_info; - int pre_bd; - - /* if there is pending bd, the SW param next_to_clean has moved - * to next and the next is NULL - */ - if (pending) { - pre_bd = (ring->next_to_clean - 1 + ring->desc_num) % - ring->desc_num; - pre_desc = &ring->desc[pre_bd]; - bd_base_info = le32_to_cpu(pre_desc->rx.bd_base_info); - } else { - bd_base_info = le32_to_cpu(desc->rx.bd_base_info); - } - while (!(bd_base_info & BIT(HNS3_RXD_FE_B))) { + do { desc = &ring->desc[ring->next_to_clean]; desc_cb = &ring->desc_cb[ring->next_to_clean]; bd_base_info = le32_to_cpu(desc->rx.bd_base_info); @@ -2704,10 +2922,9 @@ return -ENXIO; if (unlikely(ring->frag_num >= MAX_SKB_FRAGS)) { - new_skb = napi_alloc_skb(&ring->tqp_vector->napi, - HNS3_RX_HEAD_SIZE); + new_skb = napi_alloc_skb(&ring->tqp_vector->napi, 0); if (unlikely(!new_skb)) { - hns3_rl_err(ring->tqp_vector->napi.dev, + hns3_rl_err(ring_to_netdev(ring), "alloc rx fraglist skb fail\n"); return -ENXIO; } @@ -2730,9 +2947,10 @@ } hns3_nic_reuse_page(skb, ring->frag_num++, ring, 0, desc_cb); + trace_hns3_rx_desc(ring); ring_ptr_move_fw(ring, next_to_clean); ring->pending_buf++; - } + } while (!(bd_base_info & BIT(HNS3_RXD_FE_B))); return 0; } @@ -2783,7 +3001,7 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb) { - struct net_device *netdev = ring->tqp->handle->kinfo.netdev; + struct net_device *netdev = ring_to_netdev(ring); enum hns3_pkt_l2t_type l2_frame_type; u32 bd_base_info, l234info, ol_info; struct hns3_desc *desc; @@ -2858,8 +3076,7 @@ return 0; } -static int hns3_handle_rx_bd(struct hns3_enet_ring *ring, - struct sk_buff **out_skb) +static int hns3_handle_rx_bd(struct hns3_enet_ring *ring) { struct sk_buff *skb = ring->skb; struct hns3_desc_cb *desc_cb; @@ -2897,32 +3114,27 @@ if (!skb) { ret = hns3_alloc_skb(ring, length, ring->va); - *out_skb = skb = ring->skb; + skb = ring->skb; if (ret < 0) /* alloc buffer fail */ return ret; - if (ret > 0) { /* need add frag */ - ret = hns3_add_frag(ring, desc, &skb, false); + if (!(bd_base_info & BIT(HNS3_RXD_FE_B))) { /* need add frag */ + ret = hns3_add_frag(ring); if (ret) return ret; - - /* As the head data may be changed when GRO enable, copy - * the head data in after other data rx completed - */ - memcpy(skb->data, ring->va, - ALIGN(ring->pull_len, sizeof(long))); } } else { - ret = hns3_add_frag(ring, desc, &skb, true); + ret = hns3_add_frag(ring); if (ret) return ret; + } - /* As the head data may be changed when GRO enable, copy - * the head data in after other data rx completed - */ + /* As the head data may be changed when GRO enable, copy + * the head data in after other data rx completed + */ + if (skb->len > HNS3_RX_HEAD_SIZE) memcpy(skb->data, ring->va, ALIGN(ring->pull_len, sizeof(long))); - } ret = hns3_handle_bdinfo(ring, skb); if (unlikely(ret)) { @@ -2931,8 +3143,6 @@ } skb_record_rx_queue(skb, ring->tqp->tqp_index); - *out_skb = skb; - return 0; } @@ -2941,17 +3151,19 @@ { #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16 int unused_count = hns3_desc_unused(ring); - struct sk_buff *skb = ring->skb; int recv_pkts = 0; int recv_bds = 0; int err, num; num = readl_relaxed(ring->tqp->io_base + HNS3_RING_RX_RING_FBDNUM_REG); - rmb(); /* Make sure num taken effect before the other data is touched */ - num -= unused_count; unused_count -= ring->pending_buf; + if (num <= 0) + goto out; + + rmb(); /* Make sure num taken effect before the other data is touched */ + while (recv_pkts < budget && recv_bds < num) { /* Reuse or realloc buffers */ if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) { @@ -2961,27 +3173,19 @@ } /* Poll one pkt */ - err = hns3_handle_rx_bd(ring, &skb); - if (unlikely(!skb)) /* This fault cannot be repaired */ - goto out; - - if (err == -ENXIO) { /* Do not get FE for the packet */ + err = hns3_handle_rx_bd(ring); + /* Do not get FE for the packet or failed to alloc skb */ + if (unlikely(!ring->skb || err == -ENXIO)) { goto out; - } else if (unlikely(err)) { /* Do jump the err */ - recv_bds += ring->pending_buf; - unused_count += ring->pending_buf; - ring->skb = NULL; - ring->pending_buf = 0; - continue; + } else if (likely(!err)) { + rx_fn(ring, ring->skb); + recv_pkts++; } - rx_fn(ring, skb); recv_bds += ring->pending_buf; unused_count += ring->pending_buf; ring->skb = NULL; ring->pending_buf = 0; - - recv_pkts++; } out: @@ -3303,7 +3507,6 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv) { - struct hnae3_ring_chain_node vector_ring_chain; struct hnae3_handle *h = priv->ae_handle; struct hns3_enet_tqp_vector *tqp_vector; int ret = 0; @@ -3324,17 +3527,19 @@ tqp_vector = &priv->tqp_vector[vector_i]; hns3_add_ring_to_group(&tqp_vector->tx_group, - priv->ring_data[i].ring); + &priv->ring[i]); hns3_add_ring_to_group(&tqp_vector->rx_group, - priv->ring_data[i + tqp_num].ring); + &priv->ring[i + tqp_num]); - priv->ring_data[i].ring->tqp_vector = tqp_vector; - priv->ring_data[i + tqp_num].ring->tqp_vector = tqp_vector; + priv->ring[i].tqp_vector = tqp_vector; + priv->ring[i + tqp_num].tqp_vector = tqp_vector; tqp_vector->num_tqps++; } for (i = 0; i < priv->vector_num; i++) { + struct hnae3_ring_chain_node vector_ring_chain; + tqp_vector = &priv->tqp_vector[i]; tqp_vector->rx_group.total_bytes = 0; @@ -3436,26 +3641,25 @@ if (!tqp_vector->rx_group.ring && !tqp_vector->tx_group.ring) continue; - hns3_get_vector_ring_chain(tqp_vector, &vector_ring_chain); + /* Since the mapping can be overwritten, when fail to get the + * chain between vector and ring, we should go on to deal with + * the remaining options. + */ + if (hns3_get_vector_ring_chain(tqp_vector, &vector_ring_chain)) + dev_warn(priv->dev, "failed to get ring chain\n"); h->ae_algo->ops->unmap_ring_from_vector(h, tqp_vector->vector_irq, &vector_ring_chain); hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain); - if (tqp_vector->irq_init_flag == HNS3_VECTOR_INITED) { - irq_set_affinity_hint(tqp_vector->vector_irq, NULL); - free_irq(tqp_vector->vector_irq, tqp_vector); - tqp_vector->irq_init_flag = HNS3_VECTOR_NOT_INITED; - } - hns3_clear_ring_group(&tqp_vector->rx_group); hns3_clear_ring_group(&tqp_vector->tx_group); netif_napi_del(&priv->tqp_vector[i].napi); } } -static int hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) +static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) { struct hnae3_handle *h = priv->ae_handle; struct pci_dev *pdev = h->pdev; @@ -3467,35 +3671,28 @@ tqp_vector = &priv->tqp_vector[i]; ret = h->ae_algo->ops->put_vector(h, tqp_vector->vector_irq); if (ret) - return ret; + return; } devm_kfree(&pdev->dev, priv->tqp_vector); - return 0; } -static int hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, - unsigned int ring_type) +static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, + unsigned int ring_type) { - struct hns3_nic_ring_data *ring_data = priv->ring_data; int queue_num = priv->ae_handle->kinfo.num_tqps; - struct pci_dev *pdev = priv->ae_handle->pdev; struct hns3_enet_ring *ring; int desc_num; - ring = devm_kzalloc(&pdev->dev, sizeof(*ring), GFP_KERNEL); - if (!ring) - return -ENOMEM; - if (ring_type == HNAE3_RING_TYPE_TX) { + ring = &priv->ring[q->tqp_index]; desc_num = priv->ae_handle->kinfo.num_tx_desc; - ring_data[q->tqp_index].ring = ring; - ring_data[q->tqp_index].queue_index = q->tqp_index; + ring->queue_index = q->tqp_index; ring->io_base = (u8 __iomem *)q->io_base + HNS3_TX_REG_OFFSET; } else { + ring = &priv->ring[q->tqp_index + queue_num]; desc_num = priv->ae_handle->kinfo.num_rx_desc; - ring_data[q->tqp_index + queue_num].ring = ring; - ring_data[q->tqp_index + queue_num].queue_index = q->tqp_index; + ring->queue_index = q->tqp_index; ring->io_base = q->io_base; } @@ -3510,76 +3707,41 @@ ring->desc_num = desc_num; ring->next_to_use = 0; ring->next_to_clean = 0; - - return 0; } -static int hns3_queue_to_ring(struct hnae3_queue *tqp, - struct hns3_nic_priv *priv) +static void hns3_queue_to_ring(struct hnae3_queue *tqp, + struct hns3_nic_priv *priv) { - int ret; - - ret = hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_TX); - if (ret) - return ret; - - ret = hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_RX); - if (ret) { - devm_kfree(priv->dev, priv->ring_data[tqp->tqp_index].ring); - return ret; - } - - return 0; + hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_TX); + hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_RX); } static int hns3_get_ring_config(struct hns3_nic_priv *priv) { struct hnae3_handle *h = priv->ae_handle; struct pci_dev *pdev = h->pdev; - int i, ret; + int i; - priv->ring_data = devm_kzalloc(&pdev->dev, - array3_size(h->kinfo.num_tqps, - sizeof(*priv->ring_data), - 2), - GFP_KERNEL); - if (!priv->ring_data) + priv->ring = devm_kzalloc(&pdev->dev, + array3_size(h->kinfo.num_tqps, + sizeof(*priv->ring), 2), + GFP_KERNEL); + if (!priv->ring) return -ENOMEM; - for (i = 0; i < h->kinfo.num_tqps; i++) { - ret = hns3_queue_to_ring(h->kinfo.tqp[i], priv); - if (ret) - goto err; - } + for (i = 0; i < h->kinfo.num_tqps; i++) + hns3_queue_to_ring(h->kinfo.tqp[i], priv); return 0; -err: - while (i--) { - devm_kfree(priv->dev, priv->ring_data[i].ring); - devm_kfree(priv->dev, - priv->ring_data[i + h->kinfo.num_tqps].ring); - } - - devm_kfree(&pdev->dev, priv->ring_data); - priv->ring_data = NULL; - return ret; } static void hns3_put_ring_config(struct hns3_nic_priv *priv) { - struct hnae3_handle *h = priv->ae_handle; - int i; - - if (!priv->ring_data) + if (!priv->ring) return; - for (i = 0; i < h->kinfo.num_tqps; i++) { - devm_kfree(priv->dev, priv->ring_data[i].ring); - devm_kfree(priv->dev, - priv->ring_data[i + h->kinfo.num_tqps].ring); - } - devm_kfree(priv->dev, priv->ring_data); - priv->ring_data = NULL; + devm_kfree(priv->dev, priv->ring); + priv->ring = NULL; } static int hns3_alloc_ring_memory(struct hns3_enet_ring *ring) @@ -3696,7 +3858,7 @@ for (j = 0; j < tc_info->tqp_count; j++) { struct hnae3_queue *q; - q = priv->ring_data[tc_info->tqp_offset + j].ring->tqp; + q = priv->ring[tc_info->tqp_offset + j].tqp; hns3_write_dev(q, HNS3_RING_TX_RING_TC_REG, tc_info->tc); } @@ -3711,21 +3873,21 @@ int ret; for (i = 0; i < ring_num; i++) { - ret = hns3_alloc_ring_memory(priv->ring_data[i].ring); + ret = hns3_alloc_ring_memory(&priv->ring[i]); if (ret) { dev_err(priv->dev, "Alloc ring memory fail! ret=%d\n", ret); goto out_when_alloc_ring_memory; } - u64_stats_init(&priv->ring_data[i].ring->syncp); + u64_stats_init(&priv->ring[i].syncp); } return 0; out_when_alloc_ring_memory: for (j = i - 1; j >= 0; j--) - hns3_fini_ring(priv->ring_data[j].ring); + hns3_fini_ring(&priv->ring[j]); return -ENOMEM; } @@ -3736,30 +3898,31 @@ int i; for (i = 0; i < h->kinfo.num_tqps; i++) { - hns3_fini_ring(priv->ring_data[i].ring); - hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring); + hns3_fini_ring(&priv->ring[i]); + hns3_fini_ring(&priv->ring[i + h->kinfo.num_tqps]); } return 0; } /* Set mac addr if it is configured. or leave it to the AE driver */ -static int hns3_init_mac_addr(struct net_device *netdev, bool init) +static int hns3_init_mac_addr(struct net_device *netdev) { struct hns3_nic_priv *priv = netdev_priv(netdev); struct hnae3_handle *h = priv->ae_handle; - u8 mac_addr_temp[ETH_ALEN]; + u8 mac_addr_temp[ETH_ALEN] = {0}; int ret = 0; - if (h->ae_algo->ops->get_mac_addr && init) { + if (h->ae_algo->ops->get_mac_addr) h->ae_algo->ops->get_mac_addr(h, mac_addr_temp); - ether_addr_copy(netdev->dev_addr, mac_addr_temp); - } /* Check if the MAC address is valid, if not get a random one */ - if (!is_valid_ether_addr(netdev->dev_addr)) { + if (!is_valid_ether_addr(mac_addr_temp)) { eth_hw_addr_random(netdev); dev_warn(priv->dev, "using random MAC address %pM\n", netdev->dev_addr); + } else { + ether_addr_copy(netdev->dev_addr, mac_addr_temp); + ether_addr_copy(netdev->perm_addr, mac_addr_temp); } if (h->ae_algo->ops->set_mac_addr) @@ -3827,14 +3990,14 @@ struct hnae3_knic_private_info *kinfo = &priv->ae_handle->kinfo; dev_info(priv->dev, "MAC address: %pM\n", priv->netdev->dev_addr); - dev_info(priv->dev, "Task queue pairs numbers: %d\n", kinfo->num_tqps); - dev_info(priv->dev, "RSS size: %d\n", kinfo->rss_size); - dev_info(priv->dev, "Allocated RSS size: %d\n", kinfo->req_rss_size); - dev_info(priv->dev, "RX buffer length: %d\n", kinfo->rx_buf_len); - dev_info(priv->dev, "Desc num per TX queue: %d\n", kinfo->num_tx_desc); - dev_info(priv->dev, "Desc num per RX queue: %d\n", kinfo->num_rx_desc); - dev_info(priv->dev, "Total number of enabled TCs: %d\n", kinfo->num_tc); - dev_info(priv->dev, "Max mtu size: %d\n", priv->netdev->max_mtu); + dev_info(priv->dev, "Task queue pairs numbers: %u\n", kinfo->num_tqps); + dev_info(priv->dev, "RSS size: %u\n", kinfo->rss_size); + dev_info(priv->dev, "Allocated RSS size: %u\n", kinfo->req_rss_size); + dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len); + dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc); + dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc); + dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc); + dev_info(priv->dev, "Max mtu size: %u\n", priv->netdev->max_mtu); } static int hns3_client_init(struct hnae3_handle *handle) @@ -3863,7 +4026,7 @@ handle->kinfo.netdev = netdev; handle->priv = (void *)priv; - hns3_init_mac_addr(netdev, true); + hns3_init_mac_addr(netdev); hns3_set_default_feature(netdev); @@ -3897,7 +4060,7 @@ ret = hns3_init_all_ring(priv); if (ret) { ret = -ENOMEM; - goto out_init_ring_data; + goto out_init_ring; } ret = hns3_init_phy(netdev); @@ -3910,6 +4073,18 @@ goto out_reg_netdev_fail; } + /* the device can work without cpu rmap, only aRFS needs it */ + ret = hns3_set_rx_cpu_rmap(netdev); + if (ret) + dev_warn(priv->dev, "set rx cpu rmap fail, ret=%d\n", ret); + + ret = hns3_nic_init_irq(priv); + if (ret) { + dev_err(priv->dev, "init irq failed! ret=%d\n", ret); + hns3_free_rx_cpu_rmap(netdev); + goto out_init_irq_fail; + } + ret = hns3_client_start(handle); if (ret) { dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret); @@ -3931,17 +4106,20 @@ return ret; out_client_start: + hns3_free_rx_cpu_rmap(netdev); + hns3_nic_uninit_irq(priv); +out_init_irq_fail: unregister_netdev(netdev); out_reg_netdev_fail: hns3_uninit_phy(netdev); out_init_phy: hns3_uninit_all_ring(priv); -out_init_ring_data: +out_init_ring: hns3_nic_uninit_vector_data(priv); out_init_vector_data: hns3_nic_dealloc_vector_data(priv); out_alloc_vector_data: - priv->ring_data = NULL; + priv->ring = NULL; out_get_ring_cfg: priv->ae_handle = NULL; free_netdev(netdev); @@ -3968,15 +4146,17 @@ goto out_netdev_free; } + hns3_free_rx_cpu_rmap(netdev); + + hns3_nic_uninit_irq(priv); + hns3_del_all_fd_rules(netdev, true); hns3_clear_all_ring(handle, true); hns3_nic_uninit_vector_data(priv); - ret = hns3_nic_dealloc_vector_data(priv); - if (ret) - netdev_err(netdev, "dealloc vector error\n"); + hns3_nic_dealloc_vector_data(priv); ret = hns3_uninit_all_ring(priv); if (ret) @@ -3984,9 +4164,8 @@ hns3_put_ring_config(priv); - hns3_dbg_uninit(handle); - out_netdev_free: + hns3_dbg_uninit(handle); free_netdev(netdev); } @@ -3998,8 +4177,8 @@ return; if (linkup) { - netif_carrier_on(netdev); netif_tx_wake_all_queues(netdev); + netif_carrier_on(netdev); if (netif_msg_link(handle)) netdev_info(netdev, "link up\n"); } else { @@ -4102,7 +4281,7 @@ /* if alloc new buffer fail, exit directly * and reclear in up flow. */ - netdev_warn(ring->tqp->handle->kinfo.netdev, + netdev_warn(ring_to_netdev(ring), "reserve buffer map failed, ret = %d\n", ret); return ret; @@ -4148,10 +4327,10 @@ for (i = 0; i < h->kinfo.num_tqps; i++) { struct hns3_enet_ring *ring; - ring = priv->ring_data[i].ring; + ring = &priv->ring[i]; hns3_clear_tx_ring(ring); - ring = priv->ring_data[i + h->kinfo.num_tqps].ring; + ring = &priv->ring[i + h->kinfo.num_tqps]; /* Continue to clear other rings even if clearing some * rings failed. */ @@ -4175,16 +4354,16 @@ if (ret) return ret; - hns3_init_ring_hw(priv->ring_data[i].ring); + hns3_init_ring_hw(&priv->ring[i]); /* We need to clear tx ring here because self test will * use the ring and will not run down before up */ - hns3_clear_tx_ring(priv->ring_data[i].ring); - priv->ring_data[i].ring->next_to_clean = 0; - priv->ring_data[i].ring->next_to_use = 0; + hns3_clear_tx_ring(&priv->ring[i]); + priv->ring[i].next_to_clean = 0; + priv->ring[i].next_to_use = 0; - rx_ring = priv->ring_data[i + h->kinfo.num_tqps].ring; + rx_ring = &priv->ring[i + h->kinfo.num_tqps]; hns3_init_ring_hw(rx_ring); ret = hns3_clear_rx_ring(rx_ring); if (ret) @@ -4261,6 +4440,11 @@ struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev); int ret = 0; + if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state)) { + netdev_err(kinfo->netdev, "device is not initialized yet\n"); + return -EFAULT; + } + clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state); if (netif_running(kinfo->netdev)) { @@ -4303,17 +4487,32 @@ if (ret) goto err_uninit_vector; + /* the device can work without cpu rmap, only aRFS needs it */ + ret = hns3_set_rx_cpu_rmap(netdev); + if (ret) + dev_warn(priv->dev, "set rx cpu rmap fail, ret=%d\n", ret); + + ret = hns3_nic_init_irq(priv); + if (ret) { + dev_err(priv->dev, "init irq failed! ret=%d\n", ret); + hns3_free_rx_cpu_rmap(netdev); + goto err_init_irq_fail; + } + ret = hns3_client_start(handle); if (ret) { dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret); - goto err_uninit_ring; + goto err_client_start_fail; } set_bit(HNS3_NIC_STATE_INITED, &priv->state); return ret; -err_uninit_ring: +err_client_start_fail: + hns3_free_rx_cpu_rmap(netdev); + hns3_nic_uninit_irq(priv); +err_init_irq_fail: hns3_uninit_all_ring(priv); err_uninit_vector: hns3_nic_uninit_vector_data(priv); @@ -4331,7 +4530,7 @@ bool vlan_filter_enable; int ret; - ret = hns3_init_mac_addr(netdev, false); + ret = hns3_init_mac_addr(netdev); if (ret) return ret; @@ -4358,11 +4557,16 @@ struct hns3_nic_priv *priv = netdev_priv(netdev); int ret; + if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state)) + hns3_nic_net_stop(netdev); + if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) { netdev_warn(netdev, "already uninitialized\n"); return 0; } + hns3_free_rx_cpu_rmap(netdev); + hns3_nic_uninit_irq(priv); hns3_clear_all_ring(handle, true); hns3_reset_tx_queue(priv->ae_handle); @@ -4370,9 +4574,7 @@ hns3_store_coal(priv); - ret = hns3_nic_dealloc_vector_data(priv); - if (ret) - netdev_err(netdev, "dealloc vector error\n"); + hns3_nic_dealloc_vector_data(priv); ret = hns3_uninit_all_ring(priv); if (ret) @@ -4454,7 +4656,7 @@ if (new_tqp_num > hns3_get_max_available_channels(h) || new_tqp_num < 1) { dev_err(&netdev->dev, - "Change tqps fail, the tqp range is from 1 to %d", + "Change tqps fail, the tqp range is from 1 to %u", hns3_get_max_available_channels(h)); return -EINVAL; } @@ -4538,7 +4740,7 @@ pr_info("%s: %s\n", hns3_driver_name, hns3_copyright); client.type = HNAE3_CLIENT_KNIC; - snprintf(client.name, HNAE3_CLIENT_NAME_LENGTH - 1, "%s", + snprintf(client.name, HNAE3_CLIENT_NAME_LENGTH, "%s", hns3_driver_name); client.ops = &client_ops; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -76,7 +76,7 @@ #define HNS3_RING_NAME_LEN 16 #define HNS3_BUFFER_SIZE_2048 2048 #define HNS3_RING_MAX_PENDING 32760 -#define HNS3_RING_MIN_PENDING 24 +#define HNS3_RING_MIN_PENDING 72 #define HNS3_RING_BD_MULTIPLE 8 /* max frame size of mac */ #define HNS3_MAC_MAX_FRAME 9728 @@ -186,7 +186,7 @@ #define HNS3_TXD_MSS_S 0 #define HNS3_TXD_MSS_M (0x3fff << HNS3_TXD_MSS_S) -#define HNS3_TX_LAST_SIZE_M 0xffff +#define HNS3_TX_LAST_SIZE_M 0xffff #define HNS3_VECTOR_TX_IRQ BIT_ULL(0) #define HNS3_VECTOR_RX_IRQ BIT_ULL(1) @@ -195,9 +195,13 @@ #define HNS3_VECTOR_INITED 1 #define HNS3_MAX_BD_SIZE 65535 -#define HNS3_MAX_BD_NUM_NORMAL 8 -#define HNS3_MAX_BD_NUM_TSO 63 -#define HNS3_MAX_BD_PER_PKT MAX_SKB_FRAGS +#define HNS3_MAX_NON_TSO_BD_NUM 8U +#define HNS3_MAX_TSO_BD_NUM 63U +#define HNS3_MAX_TSO_SIZE \ + (HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM) + +#define HNS3_MAX_NON_TSO_SIZE \ + (HNS3_MAX_BD_SIZE * HNS3_MAX_NON_TSO_BD_NUM) #define HNS3_VECTOR_GL0_OFFSET 0x100 #define HNS3_VECTOR_GL1_OFFSET 0x200 @@ -309,7 +313,7 @@ u16 reuse_flag; - /* desc type, used by the ring user to mark the type of the priv data */ + /* desc type, used by the ring user to mark the type of the priv data */ u16 type; }; @@ -405,6 +409,7 @@ struct hns3_enet_ring *next; struct hns3_enet_tqp_vector *tqp_vector; struct hnae3_queue *tqp; + int queue_index; struct device *dev; /* will be used for DMA mapping of descriptors */ /* statistic */ @@ -430,18 +435,7 @@ int pending_buf; struct sk_buff *skb; struct sk_buff *tail_skb; -}; - -struct hns_queue; - -struct hns3_nic_ring_data { - struct hns3_enet_ring *ring; - struct napi_struct napi; - int queue_index; - int (*poll_one)(struct hns3_nic_ring_data *, int, void *); - void (*ex_process)(struct hns3_nic_ring_data *, struct sk_buff *); - void (*fini_process)(struct hns3_nic_ring_data *); -}; +} ____cacheline_internodealigned_in_smp; enum hns3_flow_level_range { HNS3_FLOW_LOW = 0, @@ -518,7 +512,7 @@ * the cb for nic to manage the ring buffer, the first half of the * array is for tx_ring and vice versa for the second half */ - struct hns3_nic_ring_data *ring_data; + struct hns3_enet_ring *ring; struct hns3_enet_tqp_vector *tqp_vector; u16 vector_num; @@ -613,11 +607,11 @@ #define ring_to_dev(ring) ((ring)->dev) +#define ring_to_netdev(ring) ((ring)->tqp_vector->napi.dev) + #define ring_to_dma_dir(ring) (HNAE3_IS_TX_RING(ring) ? \ DMA_TO_DEVICE : DMA_FROM_DEVICE) -#define tx_ring_data(priv, idx) ((priv)->ring_data[idx]) - #define hns3_buf_size(_ring) ((_ring)->buf_size) static inline unsigned int hns3_page_order(struct hns3_enet_ring *ring) @@ -679,4 +673,5 @@ void hns3_dbg_uninit(struct hnae3_handle *handle); void hns3_dbg_register_debugfs(const char *debugfs_dir_name); void hns3_dbg_unregister_debugfs(void); +void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size); #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -174,18 +174,21 @@ { struct hns3_enet_tqp_vector *tqp_vector = ring->tqp_vector; unsigned char *packet = skb->data; + u32 len = skb_headlen(skb); u32 i; - for (i = 0; i < skb->len; i++) + len = min_t(u32, len, HNS3_NIC_LB_TEST_PACKET_SIZE); + + for (i = 0; i < len; i++) if (packet[i] != (unsigned char)(i & 0xff)) break; /* The packet is correctly received */ - if (i == skb->len) + if (i == HNS3_NIC_LB_TEST_PACKET_SIZE) tqp_vector->rx_group.total_packets++; else print_hex_dump(KERN_ERR, "selftest:", DUMP_PREFIX_OFFSET, 16, 1, - skb->data, skb->len, true); + skb->data, len, true); dev_kfree_skb_any(skb); } @@ -198,7 +201,7 @@ kinfo = &h->kinfo; for (i = kinfo->num_tqps; i < kinfo->num_tqps * 2; i++) { - struct hns3_enet_ring *ring = priv->ring_data[i].ring; + struct hns3_enet_ring *ring = &priv->ring[i]; struct hns3_enet_ring_group *rx_group; u64 pre_rx_pkt; @@ -221,7 +224,7 @@ u32 i; for (i = start_ringid; i <= end_ringid; i++) { - struct hns3_enet_ring *ring = priv->ring_data[i].ring; + struct hns3_enet_ring *ring = &priv->ring[i]; hns3_clean_tx_ring(ring); } @@ -423,9 +426,8 @@ data[ETH_GSTRING_LEN - 1] = '\0'; /* first, prepend the prefix string */ - n1 = snprintf(data, MAX_PREFIX_SIZE, "%s%d_", - prefix, i); - n1 = min_t(uint, n1, MAX_PREFIX_SIZE - 1); + n1 = scnprintf(data, MAX_PREFIX_SIZE, "%s%d_", + prefix, i); size_left = (ETH_GSTRING_LEN - 1) - n1; /* now, concatenate the stats string to it */ @@ -486,7 +488,7 @@ /* get stats for Tx */ for (i = 0; i < kinfo->num_tqps; i++) { - ring = nic_priv->ring_data[i].ring; + ring = &nic_priv->ring[i]; for (j = 0; j < HNS3_TXQ_STATS_COUNT; j++) { stat = (u8 *)ring + hns3_txq_stats[j].stats_offset; *data++ = *(u64 *)stat; @@ -495,7 +497,7 @@ /* get stats for Rx */ for (i = 0; i < kinfo->num_tqps; i++) { - ring = nic_priv->ring_data[i + kinfo->num_tqps].ring; + ring = &nic_priv->ring[i + kinfo->num_tqps]; for (j = 0; j < HNS3_RXQ_STATS_COUNT; j++) { stat = (u8 *)ring + hns3_rxq_stats[j].stats_offset; *data++ = *(u64 *)stat; @@ -598,8 +600,8 @@ param->tx_max_pending = HNS3_RING_MAX_PENDING; param->rx_max_pending = HNS3_RING_MAX_PENDING; - param->tx_pending = priv->ring_data[0].ring->desc_num; - param->rx_pending = priv->ring_data[queue_num].ring->desc_num; + param->tx_pending = priv->ring[0].desc_num; + param->rx_pending = priv->ring[queue_num].desc_num; } static void hns3_get_pauseparam(struct net_device *netdev, @@ -673,7 +675,9 @@ hns3_get_ksettings(h, cmd); break; case HNAE3_MEDIA_TYPE_FIBER: - if (module_type == HNAE3_MODULE_TYPE_CR) + if (module_type == HNAE3_MODULE_TYPE_UNKNOWN) + cmd->base.port = PORT_OTHER; + else if (module_type == HNAE3_MODULE_TYPE_CR) cmd->base.port = PORT_DA; else cmd->base.port = PORT_FIBRE; @@ -737,7 +741,7 @@ if (ops->get_media_type) ops->get_media_type(handle, &media_type, &module_type); - if (cmd->base.duplex != DUPLEX_FULL && + if (cmd->base.duplex == DUPLEX_HALF && media_type != HNAE3_MEDIA_TYPE_COPPER) { netdev_err(netdev, "only copper port supports half duplex!"); @@ -901,9 +905,8 @@ h->kinfo.num_rx_desc = rx_desc_num; for (i = 0; i < h->kinfo.num_tqps; i++) { - priv->ring_data[i].ring->desc_num = tx_desc_num; - priv->ring_data[i + h->kinfo.num_tqps].ring->desc_num = - rx_desc_num; + priv->ring[i].desc_num = tx_desc_num; + priv->ring[i + h->kinfo.num_tqps].desc_num = rx_desc_num; } } @@ -919,7 +922,7 @@ return NULL; for (i = 0; i < handle->kinfo.num_tqps * 2; i++) { - memcpy(&tmp_rings[i], priv->ring_data[i].ring, + memcpy(&tmp_rings[i], &priv->ring[i], sizeof(struct hns3_enet_ring)); tmp_rings[i].skb = NULL; } @@ -967,8 +970,8 @@ /* Hardware requires that its descriptors must be multiple of eight */ new_tx_desc_num = ALIGN(param->tx_pending, HNS3_RING_BD_MULTIPLE); new_rx_desc_num = ALIGN(param->rx_pending, HNS3_RING_BD_MULTIPLE); - old_tx_desc_num = priv->ring_data[0].ring->desc_num; - old_rx_desc_num = priv->ring_data[queue_num].ring->desc_num; + old_tx_desc_num = priv->ring[0].desc_num; + old_rx_desc_num = priv->ring[queue_num].desc_num; if (old_tx_desc_num == new_tx_desc_num && old_rx_desc_num == new_rx_desc_num) return 0; @@ -981,7 +984,7 @@ } netdev_info(ndev, - "Changing Tx/Rx ring depth from %d/%d to %d/%d\n", + "Changing Tx/Rx ring depth from %u/%u to %u/%u\n", old_tx_desc_num, old_rx_desc_num, new_tx_desc_num, new_rx_desc_num); @@ -997,7 +1000,7 @@ hns3_change_all_ring_bd_num(priv, old_tx_desc_num, old_rx_desc_num); for (i = 0; i < h->kinfo.num_tqps * 2; i++) - memcpy(priv->ring_data[i].ring, &tmp_rings[i], + memcpy(&priv->ring[i], &tmp_rings[i], sizeof(struct hns3_enet_ring)); } else { for (i = 0; i < h->kinfo.num_tqps * 2; i++) @@ -1093,13 +1096,13 @@ if (queue >= queue_num) { netdev_err(netdev, - "Invalid queue value %d! Queue max id=%d\n", + "Invalid queue value %u! Queue max id=%u\n", queue, queue_num - 1); return -EINVAL; } - tx_vector = priv->ring_data[queue].ring->tqp_vector; - rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector; + tx_vector = priv->ring[queue].tqp_vector; + rx_vector = priv->ring[queue_num + queue].tqp_vector; cmd->use_adaptive_tx_coalesce = tx_vector->tx_group.coal.gl_adapt_enable; @@ -1143,14 +1146,14 @@ rx_gl = hns3_gl_round_down(cmd->rx_coalesce_usecs); if (rx_gl != cmd->rx_coalesce_usecs) { netdev_info(netdev, - "rx_usecs(%d) rounded down to %d, because it must be multiple of 2.\n", + "rx_usecs(%u) rounded down to %u, because it must be multiple of 2.\n", cmd->rx_coalesce_usecs, rx_gl); } tx_gl = hns3_gl_round_down(cmd->tx_coalesce_usecs); if (tx_gl != cmd->tx_coalesce_usecs) { netdev_info(netdev, - "tx_usecs(%d) rounded down to %d, because it must be multiple of 2.\n", + "tx_usecs(%u) rounded down to %u, because it must be multiple of 2.\n", cmd->tx_coalesce_usecs, tx_gl); } @@ -1178,7 +1181,7 @@ rl = hns3_rl_round_down(cmd->rx_coalesce_usecs_high); if (rl != cmd->rx_coalesce_usecs_high) { netdev_info(netdev, - "usecs_high(%d) rounded down to %d, because it must be multiple of 4.\n", + "usecs_high(%u) rounded down to %u, because it must be multiple of 4.\n", cmd->rx_coalesce_usecs_high, rl); } @@ -1207,7 +1210,7 @@ if (cmd->use_adaptive_tx_coalesce == 1 || cmd->use_adaptive_rx_coalesce == 1) { netdev_info(netdev, - "adaptive-tx=%d and adaptive-rx=%d, tx_usecs or rx_usecs will changed dynamically.\n", + "adaptive-tx=%u and adaptive-rx=%u, tx_usecs or rx_usecs will changed dynamically.\n", cmd->use_adaptive_tx_coalesce, cmd->use_adaptive_rx_coalesce); } @@ -1224,8 +1227,8 @@ struct hnae3_handle *h = priv->ae_handle; int queue_num = h->kinfo.num_tqps; - tx_vector = priv->ring_data[queue].ring->tqp_vector; - rx_vector = priv->ring_data[queue_num + queue].ring->tqp_vector; + tx_vector = priv->ring[queue].tqp_vector; + rx_vector = priv->ring[queue_num + queue].tqp_vector; tx_vector->tx_group.coal.gl_adapt_enable = cmd->use_adaptive_tx_coalesce; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3_trace.h @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2018-2019 Hisilicon Limited. */ + +/* This must be outside ifdef _HNS3_TRACE_H */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM hns3 + +#if !defined(_HNS3_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _HNS3_TRACE_H_ + +#include + +#define DESC_NR (sizeof(struct hns3_desc) / sizeof(u32)) + +DECLARE_EVENT_CLASS(hns3_skb_template, + TP_PROTO(struct sk_buff *skb), + TP_ARGS(skb), + + TP_STRUCT__entry( + __field(unsigned int, headlen) + __field(unsigned int, len) + __field(__u8, nr_frags) + __field(__u8, ip_summed) + __field(unsigned int, hdr_len) + __field(unsigned short, gso_size) + __field(unsigned short, gso_segs) + __field(unsigned int, gso_type) + __field(bool, fraglist) + __array(__u32, size, MAX_SKB_FRAGS) + ), + + TP_fast_assign( + __entry->headlen = skb_headlen(skb); + __entry->len = skb->len; + __entry->nr_frags = skb_shinfo(skb)->nr_frags; + __entry->gso_size = skb_shinfo(skb)->gso_size; + __entry->gso_segs = skb_shinfo(skb)->gso_segs; + __entry->gso_type = skb_shinfo(skb)->gso_type; + __entry->hdr_len = skb->encapsulation ? + skb_inner_transport_offset(skb) + inner_tcp_hdrlen(skb) : + skb_transport_offset(skb) + tcp_hdrlen(skb); + __entry->ip_summed = skb->ip_summed; + __entry->fraglist = skb_has_frag_list(skb); + hns3_shinfo_pack(skb_shinfo(skb), __entry->size); + ), + + TP_printk( + "len: %u, %u, %u, cs: %u, gso: %u, %u, %x, frag(%d %u): %s", + __entry->headlen, __entry->len, __entry->hdr_len, + __entry->ip_summed, __entry->gso_size, __entry->gso_segs, + __entry->gso_type, __entry->fraglist, __entry->nr_frags, + __print_array(__entry->size, MAX_SKB_FRAGS, sizeof(__u32)) + ) +); + +DEFINE_EVENT(hns3_skb_template, hns3_over_8bd, + TP_PROTO(struct sk_buff *skb), + TP_ARGS(skb)); + +DEFINE_EVENT(hns3_skb_template, hns3_gro, + TP_PROTO(struct sk_buff *skb), + TP_ARGS(skb)); + +DEFINE_EVENT(hns3_skb_template, hns3_tso, + TP_PROTO(struct sk_buff *skb), + TP_ARGS(skb)); + +TRACE_EVENT(hns3_tx_desc, + TP_PROTO(struct hns3_enet_ring *ring, int cur_ntu), + TP_ARGS(ring, cur_ntu), + + TP_STRUCT__entry( + __field(int, index) + __field(int, ntu) + __field(int, ntc) + __field(dma_addr_t, desc_dma) + __array(u32, desc, DESC_NR) + __string(devname, ring->tqp->handle->kinfo.netdev->name) + ), + + TP_fast_assign( + __entry->index = ring->tqp->tqp_index; + __entry->ntu = ring->next_to_use; + __entry->ntc = ring->next_to_clean; + __entry->desc_dma = ring->desc_dma_addr, + memcpy(__entry->desc, &ring->desc[cur_ntu], + sizeof(struct hns3_desc)); + __assign_str(devname, ring->tqp->handle->kinfo.netdev->name); + ), + + TP_printk( + "%s-%d-%d/%d desc(%pad): %s", + __get_str(devname), __entry->index, __entry->ntu, + __entry->ntc, &__entry->desc_dma, + __print_array(__entry->desc, DESC_NR, sizeof(u32)) + ) +); + +TRACE_EVENT(hns3_rx_desc, + TP_PROTO(struct hns3_enet_ring *ring), + TP_ARGS(ring), + + TP_STRUCT__entry( + __field(int, index) + __field(int, ntu) + __field(int, ntc) + __field(dma_addr_t, desc_dma) + __field(dma_addr_t, buf_dma) + __array(u32, desc, DESC_NR) + __string(devname, ring->tqp->handle->kinfo.netdev->name) + ), + + TP_fast_assign( + __entry->index = ring->tqp->tqp_index; + __entry->ntu = ring->next_to_use; + __entry->ntc = ring->next_to_clean; + __entry->desc_dma = ring->desc_dma_addr; + __entry->buf_dma = ring->desc_cb[ring->next_to_clean].dma; + memcpy(__entry->desc, &ring->desc[ring->next_to_clean], + sizeof(struct hns3_desc)); + __assign_str(devname, ring->tqp->handle->kinfo.netdev->name); + ), + + TP_printk( + "%s-%d-%d/%d desc(%pad) buf(%pad): %s", + __get_str(devname), __entry->index, __entry->ntu, + __entry->ntc, &__entry->desc_dma, &__entry->buf_dma, + __print_array(__entry->desc, DESC_NR, sizeof(u32)) + ) +); + +#endif /* _HNS3_TRACE_H_ */ + +/* This must be outside ifdef _HNS3_TRACE_H */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE hns3_trace +#include --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -145,7 +145,7 @@ rmb(); /* Make sure head is ready before touch any data */ if (!is_valid_csq_clean_head(csq, head)) { - dev_warn(&hdev->pdev->dev, "wrong cmd head (%d, %d-%d)\n", head, + dev_warn(&hdev->pdev->dev, "wrong cmd head (%u, %d-%d)\n", head, csq->next_to_use, csq->next_to_clean); dev_warn(&hdev->pdev->dev, "Disabling any further commands to IMP firmware\n"); @@ -314,11 +314,10 @@ } while (timeout < hw->cmq.tx_timeout); } - if (!complete) { + if (!complete) retval = -EBADE; - } else { + else retval = hclge_cmd_check_retval(hw, desc, num, ntc); - } /* Clean the command send queue */ handle = hclge_cmd_csq_clean(hw); @@ -480,19 +479,6 @@ hclge_write_dev(hw, HCLGE_NIC_CRQ_TAIL_REG, 0); } -static void hclge_destroy_queue(struct hclge_cmq_ring *ring) -{ - spin_lock(&ring->lock); - hclge_free_cmd_desc(ring); - spin_unlock(&ring->lock); -} - -static void hclge_destroy_cmd_queue(struct hclge_hw *hw) -{ - hclge_destroy_queue(&hw->cmq.csq); - hclge_destroy_queue(&hw->cmq.crq); -} - void hclge_cmd_uninit(struct hclge_dev *hdev) { spin_lock_bh(&hdev->hw.cmq.csq.lock); @@ -502,5 +488,6 @@ spin_unlock(&hdev->hw.cmq.crq.lock); spin_unlock_bh(&hdev->hw.cmq.csq.lock); - hclge_destroy_cmd_queue(&hdev->hw); + hclge_free_cmd_desc(&hdev->hw.cmq.csq); + hclge_free_cmd_desc(&hdev->hw.cmq.crq); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -5,8 +5,11 @@ #define __HCLGE_CMD_H #include #include +#include +#include "hnae3.h" #define HCLGE_CMDQ_TX_TIMEOUT 30000 +#define HCLGE_DESC_DATA_LEN 6 struct hclge_dev; struct hclge_desc { @@ -18,7 +21,7 @@ __le16 flag; __le16 retval; __le16 rsv; - __le32 data[6]; + __le32 data[HCLGE_DESC_DATA_LEN]; }; struct hclge_cmq_ring { @@ -61,6 +64,7 @@ struct hclge_misc_vector { u8 __iomem *addr; int vector_irq; + char name[HNAE3_INT_NAME_LEN]; }; struct hclge_cmq { @@ -244,7 +248,7 @@ /* QCN commands */ HCLGE_OPC_QCN_MOD_CFG = 0x1A01, HCLGE_OPC_QCN_GRP_TMPLT_CFG = 0x1A02, - HCLGE_OPC_QCN_SHAPPING_IR_CFG = 0x1A03, + HCLGE_OPC_QCN_SHAPPING_CFG = 0x1A03, HCLGE_OPC_QCN_SHAPPING_BS_CFG = 0x1A04, HCLGE_OPC_QCN_QSET_LINK_CFG = 0x1A05, HCLGE_OPC_QCN_RP_STATUS_GET = 0x1A06, @@ -257,8 +261,12 @@ /* Led command */ HCLGE_OPC_LED_STATUS_CFG = 0xB000, + /* clear hardware resource command */ + HCLGE_OPC_CLEAR_HW_RESOURCE = 0x700B, + /* NCL config command */ HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011, + /* M7 stats command */ HCLGE_OPC_M7_STATS_BD = 0x7012, HCLGE_OPC_M7_STATS_INFO = 0x7013, @@ -428,8 +436,10 @@ #define HCLGE_PF_MAC_NUM_MASK 0x3 #define HCLGE_PF_STATE_MAIN BIT(HCLGE_PF_STATE_MAIN_B) #define HCLGE_PF_STATE_DONE BIT(HCLGE_PF_STATE_DONE_B) +#define HCLGE_VF_RST_STATUS_CMD 4 + struct hclge_func_status_cmd { - __le32 vf_rst_state[4]; + __le32 vf_rst_state[HCLGE_VF_RST_STATUS_CMD]; u8 pf_state; u8 mac_id; u8 rsv1; @@ -485,10 +495,12 @@ #define HCLGE_CFG_UMV_TBL_SPACE_S 16 #define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16) +#define HCLGE_CFG_CMD_CNT 4 + struct hclge_cfg_param_cmd { __le32 offset; __le32 rsv; - __le32 param[4]; + __le32 param[HCLGE_CFG_CMD_CNT]; }; #define HCLGE_MAC_MODE 0x0 @@ -712,8 +724,7 @@ u8 flags; u8 resp_code; __le16 vlan_tag; - __le32 mac_addr_hi32; - __le16 mac_addr_lo16; + u8 mac_addr[ETH_ALEN]; __le16 rsv1; __le16 ethter_type; __le16 egress_port; @@ -758,20 +769,27 @@ u8 rsv2[19]; }; +#define HCLGE_VLAN_ID_OFFSET_STEP 160 +#define HCLGE_VLAN_BYTE_SIZE 8 +#define HCLGE_VLAN_OFFSET_BITMAP \ + (HCLGE_VLAN_ID_OFFSET_STEP / HCLGE_VLAN_BYTE_SIZE) + struct hclge_vlan_filter_pf_cfg_cmd { u8 vlan_offset; u8 vlan_cfg; u8 rsv[2]; - u8 vlan_offset_bitmap[20]; + u8 vlan_offset_bitmap[HCLGE_VLAN_OFFSET_BITMAP]; }; +#define HCLGE_MAX_VF_BYTES 16 + struct hclge_vlan_filter_vf_cfg_cmd { __le16 vlan_id; u8 resp_code; u8 rsv; u8 vlan_cfg; u8 rsv1[3]; - u8 vf_bitmap[16]; + u8 vf_bitmap[HCLGE_MAX_VF_BYTES]; }; #define HCLGE_SWITCH_ANTI_SPOOF_B 0U @@ -806,6 +824,7 @@ #define HCLGE_CFG_NIC_ROCE_SEL_B 4 #define HCLGE_ACCEPT_TAG2_B 5 #define HCLGE_ACCEPT_UNTAG2_B 6 +#define HCLGE_VF_NUM_PER_BYTE 8 struct hclge_vport_vtag_tx_cfg_cmd { u8 vport_vlan_cfg; @@ -813,7 +832,7 @@ u8 rsv1[2]; __le16 def_vlan_tag1; __le16 def_vlan_tag2; - u8 vf_bitmap[8]; + u8 vf_bitmap[HCLGE_VF_NUM_PER_BYTE]; u8 rsv2[8]; }; @@ -825,7 +844,7 @@ u8 vport_vlan_cfg; u8 vf_offset; u8 rsv1[6]; - u8 vf_bitmap[8]; + u8 vf_bitmap[HCLGE_VF_NUM_PER_BYTE]; u8 rsv2[8]; }; @@ -864,7 +883,7 @@ u8 flags; u8 resp_code; __le16 vlan_tag; - u8 mac_addr[6]; + u8 mac_addr[ETH_ALEN]; __le16 index; __le16 ethter_type; __le16 egress_port; @@ -1018,16 +1037,16 @@ #define HCLGE_FD_AD_DROP_B 0 #define HCLGE_FD_AD_DIRECT_QID_B 1 #define HCLGE_FD_AD_QID_S 2 -#define HCLGE_FD_AD_QID_M GENMASK(12, 2) +#define HCLGE_FD_AD_QID_M GENMASK(11, 2) #define HCLGE_FD_AD_USE_COUNTER_B 12 #define HCLGE_FD_AD_COUNTER_NUM_S 13 #define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(20, 13) #define HCLGE_FD_AD_NXT_STEP_B 20 #define HCLGE_FD_AD_NXT_KEY_S 21 -#define HCLGE_FD_AD_NXT_KEY_M GENMASK(26, 21) +#define HCLGE_FD_AD_NXT_KEY_M GENMASK(25, 21) #define HCLGE_FD_AD_WR_RULE_ID_B 0 #define HCLGE_FD_AD_RULE_ID_S 1 -#define HCLGE_FD_AD_RULE_ID_M GENMASK(13, 1) +#define HCLGE_FD_AD_RULE_ID_M GENMASK(12, 1) struct hclge_fd_ad_config_cmd { u8 stage; @@ -1090,9 +1109,6 @@ enum hclge_opcode_type opcode, bool is_read); void hclge_cmd_reuse_desc(struct hclge_desc *desc, bool is_read); -int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, - struct hclge_promisc_param *param); - enum hclge_cmd_status hclge_cmd_mdio_write(struct hclge_hw *hw, struct hclge_desc *desc); enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw *hw, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -87,7 +87,7 @@ for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { if (prio_tc[i] >= num_tc) { dev_err(&hdev->pdev->dev, - "prio_tc[%u] checking failed, %u >= num_tc(%u)\n", + "prio_tc[%d] checking failed, %u >= num_tc(%u)\n", i, prio_tc[i], num_tc); return -EINVAL; } @@ -124,7 +124,7 @@ if (ret) return ret; - for (i = 0; i < hdev->tc_max; i++) { + for (i = 0; i < HNAE3_MAX_TC; i++) { switch (ets->tc_tsa[i]) { case IEEE_8021QAZ_TSA_STRICT: if (hdev->tm_info.tc_info[i].tc_sch_mode != @@ -132,6 +132,15 @@ *changed = true; break; case IEEE_8021QAZ_TSA_ETS: + /* The hardware will switch to sp mode if bandwidth is + * 0, so limit ets bandwidth must be greater than 0. + */ + if (!ets->tc_tx_bw[i]) { + dev_err(&hdev->pdev->dev, + "tc%u ets bw cannot be 0\n", i); + return -EINVAL; + } + if (hdev->tm_info.tc_info[i].tc_sch_mode != HCLGE_SCH_MODE_DWRR) *changed = true; @@ -281,21 +290,12 @@ u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC]; struct hclge_vport *vport = hclge_get_vport(h); struct hclge_dev *hdev = vport->back; - u8 i, j, pfc_map, *prio_tc; int ret; + u8 i; memset(pfc, 0, sizeof(*pfc)); pfc->pfc_cap = hdev->pfc_max; - prio_tc = hdev->tm_info.prio_tc; - pfc_map = hdev->tm_info.hw_pfc_map; - - /* Pfc setting is based on TC */ - for (i = 0; i < hdev->tm_info.num_tc; i++) { - for (j = 0; j < HNAE3_MAX_USER_PRIO; j++) { - if ((prio_tc[j] == i) && (pfc_map & BIT(i))) - pfc->pfc_en |= BIT(j); - } - } + pfc->pfc_en = hdev->tm_info.pfc_en; ret = hclge_pfc_tx_stats_get(hdev, requests); if (ret) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -73,8 +73,6 @@ static int hclge_dbg_get_dfx_bd_num(struct hclge_dev *hdev, int offset) { -#define HCLGE_GET_DFX_REG_TYPE_CNT 4 - struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT]; int entries_per_desc; int index; @@ -89,7 +87,7 @@ entries_per_desc = ARRAY_SIZE(desc[0].data); index = offset % entries_per_desc; - return (int)desc[offset / entries_per_desc].data[index]; + return le32_to_cpu(desc[offset / entries_per_desc].data[index]); } static int hclge_dbg_cmd_send(struct hclge_dev *hdev, @@ -145,15 +143,13 @@ return; } - buf_len = sizeof(struct hclge_desc) * bd_num; + buf_len = sizeof(struct hclge_desc) * bd_num; desc_src = kzalloc(buf_len, GFP_KERNEL); - if (!desc_src) { - dev_err(&hdev->pdev->dev, "call kzalloc failed\n"); + if (!desc_src) return; - } desc = desc_src; - ret = hclge_dbg_cmd_send(hdev, desc, index, bd_num, reg_msg->cmd); + ret = hclge_dbg_cmd_send(hdev, desc, index, bd_num, reg_msg->cmd); if (ret) { kfree(desc_src); return; @@ -169,7 +165,7 @@ if (dfx_message->flag) dev_info(&hdev->pdev->dev, "%s: 0x%x\n", dfx_message->message, - desc->data[i % entries_per_desc]); + le32_to_cpu(desc->data[i % entries_per_desc])); dfx_message++; } @@ -181,6 +177,7 @@ { struct device *dev = &hdev->pdev->dev; struct hclge_dbg_bitmap_cmd *bitmap; + enum hclge_opcode_type cmd; int rq_id, pri_id, qset_id; int port_id, nq_id, pg_id; struct hclge_desc desc[2]; @@ -195,10 +192,10 @@ return; } - ret = hclge_dbg_cmd_send(hdev, desc, qset_id, 1, - HCLGE_OPC_QSET_DFX_STS); + cmd = HCLGE_OPC_QSET_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, qset_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "roce_qset_mask: 0x%x\n", bitmap->bit0); @@ -206,75 +203,90 @@ dev_info(dev, "qs_shaping_pass: 0x%x\n", bitmap->bit2); dev_info(dev, "qs_bp_sts: 0x%x\n", bitmap->bit3); - ret = hclge_dbg_cmd_send(hdev, desc, pri_id, 1, HCLGE_OPC_PRI_DFX_STS); + cmd = HCLGE_OPC_PRI_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, pri_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "pri_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "pri_cshaping_pass: 0x%x\n", bitmap->bit1); dev_info(dev, "pri_pshaping_pass: 0x%x\n", bitmap->bit2); - ret = hclge_dbg_cmd_send(hdev, desc, pg_id, 1, HCLGE_OPC_PG_DFX_STS); + cmd = HCLGE_OPC_PG_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, pg_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "pg_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "pg_cshaping_pass: 0x%x\n", bitmap->bit1); dev_info(dev, "pg_pshaping_pass: 0x%x\n", bitmap->bit2); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_PORT_DFX_STS); + cmd = HCLGE_OPC_PORT_DFX_STS; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; bitmap = (struct hclge_dbg_bitmap_cmd *)&desc[0].data[1]; dev_info(dev, "port_mask: 0x%x\n", bitmap->bit0); dev_info(dev, "port_shaping_pass: 0x%x\n", bitmap->bit1); - ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_NQ_CNT); + cmd = HCLGE_OPC_SCH_NQ_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; - dev_info(dev, "sch_nq_cnt: 0x%x\n", desc[0].data[1]); + dev_info(dev, "sch_nq_cnt: 0x%x\n", le32_to_cpu(desc[0].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, HCLGE_OPC_SCH_RQ_CNT); + cmd = HCLGE_OPC_SCH_RQ_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, nq_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; - dev_info(dev, "sch_rq_cnt: 0x%x\n", desc[0].data[1]); + dev_info(dev, "sch_rq_cnt: 0x%x\n", le32_to_cpu(desc[0].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, 0, 2, HCLGE_OPC_TM_INTERNAL_STS); + cmd = HCLGE_OPC_TM_INTERNAL_STS; + ret = hclge_dbg_cmd_send(hdev, desc, 0, 2, cmd); if (ret) - return; + goto err_dcb_cmd_send; - dev_info(dev, "pri_bp: 0x%x\n", desc[0].data[1]); - dev_info(dev, "fifo_dfx_info: 0x%x\n", desc[0].data[2]); - dev_info(dev, "sch_roce_fifo_afull_gap: 0x%x\n", desc[0].data[3]); - dev_info(dev, "tx_private_waterline: 0x%x\n", desc[0].data[4]); - dev_info(dev, "tm_bypass_en: 0x%x\n", desc[0].data[5]); - dev_info(dev, "SSU_TM_BYPASS_EN: 0x%x\n", desc[1].data[0]); - dev_info(dev, "SSU_RESERVE_CFG: 0x%x\n", desc[1].data[1]); + dev_info(dev, "pri_bp: 0x%x\n", le32_to_cpu(desc[0].data[1])); + dev_info(dev, "fifo_dfx_info: 0x%x\n", le32_to_cpu(desc[0].data[2])); + dev_info(dev, "sch_roce_fifo_afull_gap: 0x%x\n", + le32_to_cpu(desc[0].data[3])); + dev_info(dev, "tx_private_waterline: 0x%x\n", + le32_to_cpu(desc[0].data[4])); + dev_info(dev, "tm_bypass_en: 0x%x\n", le32_to_cpu(desc[0].data[5])); + dev_info(dev, "SSU_TM_BYPASS_EN: 0x%x\n", le32_to_cpu(desc[1].data[0])); + dev_info(dev, "SSU_RESERVE_CFG: 0x%x\n", le32_to_cpu(desc[1].data[1])); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_TM_INTERNAL_CNT); + cmd = HCLGE_OPC_TM_INTERNAL_CNT; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; - dev_info(dev, "SCH_NIC_NUM: 0x%x\n", desc[0].data[1]); - dev_info(dev, "SCH_ROCE_NUM: 0x%x\n", desc[0].data[2]); + dev_info(dev, "SCH_NIC_NUM: 0x%x\n", le32_to_cpu(desc[0].data[1])); + dev_info(dev, "SCH_ROCE_NUM: 0x%x\n", le32_to_cpu(desc[0].data[2])); - ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, - HCLGE_OPC_TM_INTERNAL_STS_1); + cmd = HCLGE_OPC_TM_INTERNAL_STS_1; + ret = hclge_dbg_cmd_send(hdev, desc, port_id, 1, cmd); if (ret) - return; + goto err_dcb_cmd_send; + + dev_info(dev, "TC_MAP_SEL: 0x%x\n", le32_to_cpu(desc[0].data[1])); + dev_info(dev, "IGU_PFC_PRI_EN: 0x%x\n", le32_to_cpu(desc[0].data[2])); + dev_info(dev, "MAC_PFC_PRI_EN: 0x%x\n", le32_to_cpu(desc[0].data[3])); + dev_info(dev, "IGU_PRI_MAP_TC_CFG: 0x%x\n", + le32_to_cpu(desc[0].data[4])); + dev_info(dev, "IGU_TX_PRI_MAP_TC_CFG: 0x%x\n", + le32_to_cpu(desc[0].data[5])); + return; - dev_info(dev, "TC_MAP_SEL: 0x%x\n", desc[0].data[1]); - dev_info(dev, "IGU_PFC_PRI_EN: 0x%x\n", desc[0].data[2]); - dev_info(dev, "MAC_PFC_PRI_EN: 0x%x\n", desc[0].data[3]); - dev_info(dev, "IGU_PRI_MAP_TC_CFG: 0x%x\n", desc[0].data[4]); - dev_info(dev, "IGU_TX_PRI_MAP_TC_CFG: 0x%x\n", desc[0].data[5]); +err_dcb_cmd_send: + dev_err(&hdev->pdev->dev, + "failed to dump dcb dfx, cmd = %#x, ret = %d\n", + cmd, ret); } static void hclge_dbg_dump_reg_cmd(struct hclge_dev *hdev, const char *cmd_buf) @@ -308,8 +320,9 @@ char *false_buf) { if (flag) - dev_info(&hdev->pdev->dev, "%s(%d): %s\n", title_buf, index, - true_buf); + dev_info(&hdev->pdev->dev, "%s(%d): %s weight: %u\n", + title_buf, index, true_buf, + hdev->tm_info.pg_info[0].tc_dwrr[index]); else dev_info(&hdev->pdev->dev, "%s(%d): %s\n", title_buf, index, false_buf); @@ -337,7 +350,8 @@ ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data; - dev_info(&hdev->pdev->dev, "dump tc\n"); + dev_info(&hdev->pdev->dev, "dump tc: %u tc enabled\n", + hdev->tm_info.num_tc); dev_info(&hdev->pdev->dev, "weight_offset: %u\n", ets_weight->weight_offset); @@ -364,7 +378,7 @@ pg_shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PG_C pg_id: %u\n", pg_shap_cfg_cmd->pg_id); dev_info(&hdev->pdev->dev, "PG_C pg_shapping: 0x%x\n", - pg_shap_cfg_cmd->pg_shapping_para); + le32_to_cpu(pg_shap_cfg_cmd->pg_shapping_para)); cmd = HCLGE_OPC_TM_PG_P_SHAPPING; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -375,7 +389,7 @@ pg_shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PG_P pg_id: %u\n", pg_shap_cfg_cmd->pg_id); dev_info(&hdev->pdev->dev, "PG_P pg_shapping: 0x%x\n", - pg_shap_cfg_cmd->pg_shapping_para); + le32_to_cpu(pg_shap_cfg_cmd->pg_shapping_para)); cmd = HCLGE_OPC_TM_PORT_SHAPPING; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -385,7 +399,7 @@ port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PORT port_shapping: 0x%x\n", - port_shap_cfg_cmd->port_shapping_para); + le32_to_cpu(port_shap_cfg_cmd->port_shapping_para)); cmd = HCLGE_OPC_TM_PG_SCH_MODE_CFG; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -393,7 +407,8 @@ if (ret) goto err_tm_pg_cmd_send; - dev_info(&hdev->pdev->dev, "PG_SCH pg_id: %u\n", desc.data[0]); + dev_info(&hdev->pdev->dev, "PG_SCH pg_id: %u\n", + le32_to_cpu(desc.data[0])); cmd = HCLGE_OPC_TM_PRI_SCH_MODE_CFG; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -401,7 +416,8 @@ if (ret) goto err_tm_pg_cmd_send; - dev_info(&hdev->pdev->dev, "PRI_SCH pri_id: %u\n", desc.data[0]); + dev_info(&hdev->pdev->dev, "PRI_SCH pri_id: %u\n", + le32_to_cpu(desc.data[0])); cmd = HCLGE_OPC_TM_QS_SCH_MODE_CFG; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -409,7 +425,8 @@ if (ret) goto err_tm_pg_cmd_send; - dev_info(&hdev->pdev->dev, "QS_SCH qs_id: %u\n", desc.data[0]); + dev_info(&hdev->pdev->dev, "QS_SCH qs_id: %u\n", + le32_to_cpu(desc.data[0])); if (!hnae3_dev_dcb_supported(hdev)) { dev_info(&hdev->pdev->dev, @@ -429,7 +446,7 @@ dev_info(&hdev->pdev->dev, "BP_TO_QSET qs_group_id: 0x%x\n", bp_to_qs_map_cmd->qs_group_id); dev_info(&hdev->pdev->dev, "BP_TO_QSET qs_bit_map: 0x%x\n", - bp_to_qs_map_cmd->qs_bit_map); + le32_to_cpu(bp_to_qs_map_cmd->qs_bit_map)); return; err_tm_pg_cmd_send: @@ -471,7 +488,7 @@ qs_to_pri_map = (struct hclge_qs_to_pri_link_cmd *)desc.data; dev_info(&hdev->pdev->dev, "QS_TO_PRI qs_id: %u\n", - qs_to_pri_map->qs_id); + le16_to_cpu(qs_to_pri_map->qs_id)); dev_info(&hdev->pdev->dev, "QS_TO_PRI priority: %u\n", qs_to_pri_map->priority); dev_info(&hdev->pdev->dev, "QS_TO_PRI link_vld: %u\n", @@ -484,9 +501,10 @@ goto err_tm_cmd_send; nq_to_qs_map = (struct hclge_nq_to_qs_link_cmd *)desc.data; - dev_info(&hdev->pdev->dev, "NQ_TO_QS nq_id: %u\n", nq_to_qs_map->nq_id); + dev_info(&hdev->pdev->dev, "NQ_TO_QS nq_id: %u\n", + le16_to_cpu(nq_to_qs_map->nq_id)); dev_info(&hdev->pdev->dev, "NQ_TO_QS qset_id: 0x%x\n", - nq_to_qs_map->qset_id); + le16_to_cpu(nq_to_qs_map->qset_id)); cmd = HCLGE_OPC_TM_PG_WEIGHT; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -505,7 +523,8 @@ goto err_tm_cmd_send; qs_weight = (struct hclge_qs_weight_cmd *)desc.data; - dev_info(&hdev->pdev->dev, "QS qs_id: %u\n", qs_weight->qs_id); + dev_info(&hdev->pdev->dev, "QS qs_id: %u\n", + le16_to_cpu(qs_weight->qs_id)); dev_info(&hdev->pdev->dev, "QS dwrr: %u\n", qs_weight->dwrr); cmd = HCLGE_OPC_TM_PRI_WEIGHT; @@ -527,7 +546,7 @@ shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PRI_C pri_id: %u\n", shap_cfg_cmd->pri_id); dev_info(&hdev->pdev->dev, "PRI_C pri_shapping: 0x%x\n", - shap_cfg_cmd->pri_shapping_para); + le32_to_cpu(shap_cfg_cmd->pri_shapping_para)); cmd = HCLGE_OPC_TM_PRI_P_SHAPPING; hclge_cmd_setup_basic_desc(&desc, cmd, true); @@ -538,7 +557,7 @@ shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; dev_info(&hdev->pdev->dev, "PRI_P pri_id: %u\n", shap_cfg_cmd->pri_id); dev_info(&hdev->pdev->dev, "PRI_P pri_shapping: 0x%x\n", - shap_cfg_cmd->pri_shapping_para); + le32_to_cpu(shap_cfg_cmd->pri_shapping_para)); hclge_dbg_dump_tm_pg(hdev); @@ -574,7 +593,7 @@ ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) goto err_tm_map_cmd_send; - qset_id = nq_to_qs_map->qset_id & 0x3FF; + qset_id = le16_to_cpu(nq_to_qs_map->qset_id) & 0x3FF; cmd = HCLGE_OPC_TM_QS_TO_PRI_LINK; map = (struct hclge_qs_to_pri_link_cmd *)desc.data; @@ -614,7 +633,8 @@ if (ret) goto err_tm_map_cmd_send; - qset_maping[group_id] = bp_to_qs_map_cmd->qs_bit_map; + qset_maping[group_id] = + le32_to_cpu(bp_to_qs_map_cmd->qs_bit_map); } dev_info(&hdev->pdev->dev, "index | tm bp qset maping:\n"); @@ -658,7 +678,7 @@ dev_info(&hdev->pdev->dev, "pause_trans_gap: 0x%x\n", pause_param->pause_trans_gap); dev_info(&hdev->pdev->dev, "pause_trans_time: 0x%x\n", - pause_param->pause_trans_time); + le16_to_cpu(pause_param->pause_trans_time)); } static void hclge_dbg_dump_qos_pri_map(struct hclge_dev *hdev) @@ -712,7 +732,7 @@ tx_buf_cmd = (struct hclge_tx_buff_alloc_cmd *)desc[0].data; for (i = 0; i < HCLGE_MAX_TC_NUM; i++) dev_info(&hdev->pdev->dev, "tx_packet_buf_tc_%d: 0x%x\n", i, - tx_buf_cmd->tx_pkt_buff[i]); + le16_to_cpu(tx_buf_cmd->tx_pkt_buff[i])); cmd = HCLGE_OPC_RX_PRIV_BUFF_ALLOC; hclge_cmd_setup_basic_desc(desc, cmd, true); @@ -724,10 +744,10 @@ rx_buf_cmd = (struct hclge_rx_priv_buff_cmd *)desc[0].data; for (i = 0; i < HCLGE_MAX_TC_NUM; i++) dev_info(&hdev->pdev->dev, "rx_packet_buf_tc_%d: 0x%x\n", i, - rx_buf_cmd->buf_num[i]); + le16_to_cpu(rx_buf_cmd->buf_num[i])); dev_info(&hdev->pdev->dev, "rx_share_buf: 0x%x\n", - rx_buf_cmd->shared_buf); + le16_to_cpu(rx_buf_cmd->shared_buf)); cmd = HCLGE_OPC_RX_COM_WL_ALLOC; hclge_cmd_setup_basic_desc(desc, cmd, true); @@ -738,7 +758,8 @@ rx_com_wl = (struct hclge_rx_com_wl *)desc[0].data; dev_info(&hdev->pdev->dev, "\n"); dev_info(&hdev->pdev->dev, "rx_com_wl: high: 0x%x, low: 0x%x\n", - rx_com_wl->com_wl.high, rx_com_wl->com_wl.low); + le16_to_cpu(rx_com_wl->com_wl.high), + le16_to_cpu(rx_com_wl->com_wl.low)); cmd = HCLGE_OPC_RX_GBL_PKT_CNT; hclge_cmd_setup_basic_desc(desc, cmd, true); @@ -749,7 +770,8 @@ rx_packet_cnt = (struct hclge_rx_com_wl *)desc[0].data; dev_info(&hdev->pdev->dev, "rx_global_packet_cnt: high: 0x%x, low: 0x%x\n", - rx_packet_cnt->com_wl.high, rx_packet_cnt->com_wl.low); + le16_to_cpu(rx_packet_cnt->com_wl.high), + le16_to_cpu(rx_packet_cnt->com_wl.low)); dev_info(&hdev->pdev->dev, "\n"); if (!hnae3_dev_dcb_supported(hdev)) { @@ -769,14 +791,16 @@ for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++) dev_info(&hdev->pdev->dev, "rx_priv_wl_tc_%d: high: 0x%x, low: 0x%x\n", i, - rx_priv_wl->tc_wl[i].high, rx_priv_wl->tc_wl[i].low); + le16_to_cpu(rx_priv_wl->tc_wl[i].high), + le16_to_cpu(rx_priv_wl->tc_wl[i].low)); rx_priv_wl = (struct hclge_rx_priv_wl_buf *)desc[1].data; for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++) dev_info(&hdev->pdev->dev, "rx_priv_wl_tc_%d: high: 0x%x, low: 0x%x\n", i + HCLGE_TC_NUM_ONE_DESC, - rx_priv_wl->tc_wl[i].high, rx_priv_wl->tc_wl[i].low); + le16_to_cpu(rx_priv_wl->tc_wl[i].high), + le16_to_cpu(rx_priv_wl->tc_wl[i].low)); cmd = HCLGE_OPC_RX_COM_THRD_ALLOC; hclge_cmd_setup_basic_desc(&desc[0], cmd, true); @@ -791,16 +815,16 @@ for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++) dev_info(&hdev->pdev->dev, "rx_com_thrd_tc_%d: high: 0x%x, low: 0x%x\n", i, - rx_com_thrd->com_thrd[i].high, - rx_com_thrd->com_thrd[i].low); + le16_to_cpu(rx_com_thrd->com_thrd[i].high), + le16_to_cpu(rx_com_thrd->com_thrd[i].low)); rx_com_thrd = (struct hclge_rx_com_thrd *)desc[1].data; for (i = 0; i < HCLGE_TC_NUM_ONE_DESC; i++) dev_info(&hdev->pdev->dev, "rx_com_thrd_tc_%d: high: 0x%x, low: 0x%x\n", i + HCLGE_TC_NUM_ONE_DESC, - rx_com_thrd->com_thrd[i].high, - rx_com_thrd->com_thrd[i].low); + le16_to_cpu(rx_com_thrd->com_thrd[i].high), + le16_to_cpu(rx_com_thrd->com_thrd[i].low)); return; err_qos_cmd_send: @@ -813,6 +837,7 @@ struct hclge_mac_ethertype_idx_rd_cmd *req0; char printf_buf[HCLGE_DBG_BUF_LEN]; struct hclge_desc desc; + u32 msg_egress_port; int ret, i; dev_info(&hdev->pdev->dev, "mng tab:\n"); @@ -845,7 +870,8 @@ memset(printf_buf, 0, HCLGE_DBG_BUF_LEN); snprintf(printf_buf, HCLGE_DBG_BUF_LEN, "%02u |%02x:%02x:%02x:%02x:%02x:%02x|", - req0->index, req0->mac_addr[0], req0->mac_addr[1], + le16_to_cpu(req0->index), + req0->mac_addr[0], req0->mac_addr[1], req0->mac_addr[2], req0->mac_addr[3], req0->mac_addr[4], req0->mac_addr[5]); @@ -853,27 +879,28 @@ HCLGE_DBG_BUF_LEN - strlen(printf_buf), "%x |%04x |%x |%04x|%x |%02x |%02x |", !!(req0->flags & HCLGE_DBG_MNG_MAC_MASK_B), - req0->ethter_type, + le16_to_cpu(req0->ethter_type), !!(req0->flags & HCLGE_DBG_MNG_ETHER_MASK_B), - req0->vlan_tag & HCLGE_DBG_MNG_VLAN_TAG, + le16_to_cpu(req0->vlan_tag) & HCLGE_DBG_MNG_VLAN_TAG, !!(req0->flags & HCLGE_DBG_MNG_VLAN_MASK_B), req0->i_port_bitmap, req0->i_port_direction); + msg_egress_port = le16_to_cpu(req0->egress_port); snprintf(printf_buf + strlen(printf_buf), HCLGE_DBG_BUF_LEN - strlen(printf_buf), - "%d |%d |%02d |%04d|%x\n", - !!(req0->egress_port & HCLGE_DBG_MNG_E_TYPE_B), - req0->egress_port & HCLGE_DBG_MNG_PF_ID, - (req0->egress_port >> 3) & HCLGE_DBG_MNG_VF_ID, - req0->egress_queue, - !!(req0->egress_port & HCLGE_DBG_MNG_DROP_B)); + "%x |%x |%02x |%04x|%x\n", + !!(msg_egress_port & HCLGE_DBG_MNG_E_TYPE_B), + msg_egress_port & HCLGE_DBG_MNG_PF_ID, + (msg_egress_port >> 3) & HCLGE_DBG_MNG_VF_ID, + le16_to_cpu(req0->egress_queue), + !!(msg_egress_port & HCLGE_DBG_MNG_DROP_B)); dev_info(&hdev->pdev->dev, "%s", printf_buf); } } -static void hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, u8 stage, - bool sel_x, u32 loc) +static int hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, u8 stage, + bool sel_x, u32 loc) { struct hclge_fd_tcam_config_1_cmd *req1; struct hclge_fd_tcam_config_2_cmd *req2; @@ -898,7 +925,7 @@ ret = hclge_cmd_send(&hdev->hw, desc, 3); if (ret) - return; + return ret; dev_info(&hdev->pdev->dev, " read result tcam key %s(%u):\n", sel_x ? "x" : "y", loc); @@ -917,19 +944,79 @@ req = (u32 *)req3->tcam_data; for (i = 0; i < 5; i++) dev_info(&hdev->pdev->dev, "%08x\n", *req++); + + return ret; +} + +static int hclge_dbg_get_rules_location(struct hclge_dev *hdev, u16 *rule_locs) +{ + struct hclge_fd_rule *rule; + struct hlist_node *node; + int cnt = 0; + + spin_lock_bh(&hdev->fd_rule_lock); + hlist_for_each_entry_safe(rule, node, &hdev->fd_rule_list, rule_node) { + rule_locs[cnt] = rule->location; + cnt++; + } + spin_unlock_bh(&hdev->fd_rule_lock); + + if (cnt != hdev->hclge_fd_rule_num) + return -EINVAL; + + return cnt; } static void hclge_dbg_fd_tcam(struct hclge_dev *hdev) { - u32 i; + int i, ret, rule_cnt; + u16 *rule_locs; + + if (!hnae3_dev_fd_supported(hdev)) { + dev_err(&hdev->pdev->dev, + "Only FD-supported dev supports dump fd tcam\n"); + return; + } + + if (!hdev->hclge_fd_rule_num || + !hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]) + return; + + rule_locs = kcalloc(hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1], + sizeof(u16), GFP_KERNEL); + if (!rule_locs) + return; + + rule_cnt = hclge_dbg_get_rules_location(hdev, rule_locs); + if (rule_cnt <= 0) { + dev_err(&hdev->pdev->dev, + "failed to get rule number, ret = %d\n", rule_cnt); + kfree(rule_locs); + return; + } + + for (i = 0; i < rule_cnt; i++) { + ret = hclge_dbg_fd_tcam_read(hdev, 0, true, rule_locs[i]); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get fd tcam key x, ret = %d\n", ret); + kfree(rule_locs); + return; + } - for (i = 0; i < hdev->fd_cfg.rule_num[0]; i++) { - hclge_dbg_fd_tcam_read(hdev, 0, true, i); - hclge_dbg_fd_tcam_read(hdev, 0, false, i); + ret = hclge_dbg_fd_tcam_read(hdev, 0, false, rule_locs[i]); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get fd tcam key y, ret = %d\n", ret); + kfree(rule_locs); + return; + } } + + kfree(rule_locs); } -static void hclge_dbg_dump_rst_info(struct hclge_dev *hdev) +void hclge_dbg_dump_rst_info(struct hclge_dev *hdev) { dev_info(&hdev->pdev->dev, "PF reset count: %u\n", hdev->rst_stats.pf_rst_cnt); @@ -945,8 +1032,6 @@ hdev->rst_stats.hw_reset_done_cnt); dev_info(&hdev->pdev->dev, "reset count: %u\n", hdev->rst_stats.reset_cnt); - dev_info(&hdev->pdev->dev, "reset count: %u\n", - hdev->rst_stats.reset_cnt); dev_info(&hdev->pdev->dev, "reset fail count: %u\n", hdev->rst_stats.reset_fail_cnt); dev_info(&hdev->pdev->dev, "vector0 interrupt enable status: 0x%x\n", @@ -961,6 +1046,15 @@ hclge_read_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG)); dev_info(&hdev->pdev->dev, "function reset status: 0x%x\n", hclge_read_dev(&hdev->hw, HCLGE_FUN_RST_ING)); + dev_info(&hdev->pdev->dev, "hdev state: 0x%lx\n", hdev->state); +} + +static void hclge_dbg_dump_serv_info(struct hclge_dev *hdev) +{ + dev_info(&hdev->pdev->dev, "last_serv_processed: %lu\n", + hdev->last_serv_processed); + dev_info(&hdev->pdev->dev, "last_serv_cnt: %lu\n", + hdev->serv_processed_cnt); } static void hclge_dbg_get_m7_stats_info(struct hclge_dev *hdev) @@ -986,11 +1080,8 @@ buf_len = sizeof(struct hclge_desc) * bd_num; desc_src = kzalloc(buf_len, GFP_KERNEL); - if (!desc_src) { - dev_err(&hdev->pdev->dev, - "allocate desc for get_m7_stats failed\n"); + if (!desc_src) return; - } desc_tmp = desc_src; ret = hclge_dbg_cmd_send(hdev, desc_tmp, 0, bd_num, @@ -1053,7 +1144,7 @@ const char *cmd_buf) { #define HCLGE_MAX_NCL_CONFIG_OFFSET 4096 -#define HCLGE_MAX_NCL_CONFIG_LENGTH (20 + 24 * 4) +#define HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD (20 + 24 * 4) struct hclge_desc desc[HCLGE_CMD_NCL_CONFIG_BD_NUM]; int bd_num = HCLGE_CMD_NCL_CONFIG_BD_NUM; @@ -1077,8 +1168,8 @@ while (length > 0) { data0 = offset; - if (length >= HCLGE_MAX_NCL_CONFIG_LENGTH) - data0 |= HCLGE_MAX_NCL_CONFIG_LENGTH << 16; + if (length >= HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD) + data0 |= HCLGE_NCL_CONFIG_LENGTH_IN_EACH_CMD << 16; else data0 |= length << 16; ret = hclge_dbg_cmd_send(hdev, desc, data0, bd_num, @@ -1090,6 +1181,57 @@ } } +static void hclge_dbg_dump_loopback(struct hclge_dev *hdev, + const char *cmd_buf) +{ + struct phy_device *phydev = hdev->hw.mac.phydev; + struct hclge_config_mac_mode_cmd *req_app; + struct hclge_serdes_lb_cmd *req_serdes; + struct hclge_desc desc; + u8 loopback_en; + int ret; + + req_app = (struct hclge_config_mac_mode_cmd *)desc.data; + req_serdes = (struct hclge_serdes_lb_cmd *)desc.data; + + dev_info(&hdev->pdev->dev, "mac id: %u\n", hdev->hw.mac.mac_id); + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to dump app loopback status, ret = %d\n", ret); + return; + } + + loopback_en = hnae3_get_bit(le32_to_cpu(req_app->txrx_pad_fcs_loop_en), + HCLGE_MAC_APP_LP_B); + dev_info(&hdev->pdev->dev, "app loopback: %s\n", + loopback_en ? "on" : "off"); + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, true); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to dump serdes loopback status, ret = %d\n", + ret); + return; + } + + loopback_en = req_serdes->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B; + dev_info(&hdev->pdev->dev, "serdes serial loopback: %s\n", + loopback_en ? "on" : "off"); + + loopback_en = req_serdes->enable & + HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B; + dev_info(&hdev->pdev->dev, "serdes parallel loopback: %s\n", + loopback_en ? "on" : "off"); + + if (phydev) + dev_info(&hdev->pdev->dev, "phy loopback: %s\n", + phydev->loopback_enabled ? "on" : "off"); +} + /* hclge_dbg_dump_mac_tnl_status: print message about mac tnl interrupt * @hdev: pointer to struct hclge_dev */ @@ -1110,10 +1252,87 @@ } } +static void hclge_dbg_dump_qs_shaper_single(struct hclge_dev *hdev, u16 qsid) +{ + struct hclge_qs_shapping_cmd *shap_cfg_cmd; + u8 ir_u, ir_b, ir_s, bs_b, bs_s; + struct hclge_desc desc; + u32 shapping_para; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, true); + + shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data; + shap_cfg_cmd->qs_id = cpu_to_le16(qsid); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "qs%u failed to get tx_rate, ret=%d\n", + qsid, ret); + return; + } + + shapping_para = le32_to_cpu(shap_cfg_cmd->qs_shapping_para); + ir_b = hclge_tm_get_field(shapping_para, IR_B); + ir_u = hclge_tm_get_field(shapping_para, IR_U); + ir_s = hclge_tm_get_field(shapping_para, IR_S); + bs_b = hclge_tm_get_field(shapping_para, BS_B); + bs_s = hclge_tm_get_field(shapping_para, BS_S); + + dev_info(&hdev->pdev->dev, + "qs%u ir_b:%u, ir_u:%u, ir_s:%u, bs_b:%u, bs_s:%u\n", + qsid, ir_b, ir_u, ir_s, bs_b, bs_s); +} + +static void hclge_dbg_dump_qs_shaper_all(struct hclge_dev *hdev) +{ + struct hnae3_knic_private_info *kinfo; + struct hclge_vport *vport; + int vport_id, i; + + for (vport_id = 0; vport_id <= pci_num_vf(hdev->pdev); vport_id++) { + vport = &hdev->vport[vport_id]; + kinfo = &vport->nic.kinfo; + + dev_info(&hdev->pdev->dev, "qs cfg of vport%d:\n", vport_id); + + for (i = 0; i < kinfo->num_tc; i++) { + u16 qsid = vport->qs_offset + i; + + hclge_dbg_dump_qs_shaper_single(hdev, qsid); + } + } +} + +static void hclge_dbg_dump_qs_shaper(struct hclge_dev *hdev, + const char *cmd_buf) +{ +#define HCLGE_MAX_QSET_NUM 1024 + + u16 qsid; + int ret; + + ret = kstrtou16(cmd_buf, 0, &qsid); + if (ret) { + hclge_dbg_dump_qs_shaper_all(hdev); + return; + } + + if (qsid >= HCLGE_MAX_QSET_NUM) { + dev_err(&hdev->pdev->dev, "qsid(%u) out of range[0-1023]\n", + qsid); + return; + } + + hclge_dbg_dump_qs_shaper_single(hdev, qsid); +} + int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf) { #define DUMP_REG "dump reg" #define DUMP_TM_MAP "dump tm map" +#define DUMP_LOOPBACK "dump loopback" struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -1138,6 +1357,8 @@ hclge_dbg_dump_reg_cmd(hdev, &cmd_buf[sizeof(DUMP_REG)]); } else if (strncmp(cmd_buf, "dump reset info", 15) == 0) { hclge_dbg_dump_rst_info(hdev); + } else if (strncmp(cmd_buf, "dump serv info", 14) == 0) { + hclge_dbg_dump_serv_info(hdev); } else if (strncmp(cmd_buf, "dump m7 info", 12) == 0) { hclge_dbg_get_m7_stats_info(hdev); } else if (strncmp(cmd_buf, "dump ncl_config", 15) == 0) { @@ -1145,6 +1366,12 @@ &cmd_buf[sizeof("dump ncl_config")]); } else if (strncmp(cmd_buf, "dump mac tnl status", 19) == 0) { hclge_dbg_dump_mac_tnl_status(hdev); + } else if (strncmp(cmd_buf, DUMP_LOOPBACK, + strlen(DUMP_LOOPBACK)) == 0) { + hclge_dbg_dump_loopback(hdev, &cmd_buf[sizeof(DUMP_LOOPBACK)]); + } else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) { + hclge_dbg_dump_qs_shaper(hdev, + &cmd_buf[sizeof("dump qs shaper")]); } else { dev_info(&hdev->pdev->dev, "unknown command\n"); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.h @@ -35,8 +35,6 @@ #define HCLGE_DBG_DFX_SSU_2_OFFSET 12 -#pragma pack(1) - struct hclge_qos_pri_map_cmd { u8 pri0_tc : 4, pri1_tc : 4; @@ -85,8 +83,6 @@ struct hclge_dbg_reg_common_msg reg_msg; }; -#pragma pack() - static struct hclge_dbg_dfx_message hclge_dbg_bios_common_reg[] = { {false, "Reserved"}, {true, "BP_CPU_STATE"}, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c @@ -505,7 +505,7 @@ static const struct hclge_hw_error hclge_ssu_port_based_err_int[] = { { .int_msk = BIT(0), .msg = "roc_pkt_without_key_port", - .reset_level = HNAE3_GLOBAL_RESET }, + .reset_level = HNAE3_FUNC_RESET }, { .int_msk = BIT(1), .msg = "tpu_pkt_without_key_port", .reset_level = HNAE3_GLOBAL_RESET }, { .int_msk = BIT(2), .msg = "igu_pkt_without_key_port", @@ -599,7 +599,7 @@ static const struct hclge_hw_error hclge_ssu_port_based_pf_int[] = { { .int_msk = BIT(0), .msg = "roc_pkt_without_key_port", - .reset_level = HNAE3_GLOBAL_RESET }, + .reset_level = HNAE3_FUNC_RESET }, { .int_msk = BIT(9), .msg = "low_water_line_err_port", .reset_level = HNAE3_NONE_RESET }, { .int_msk = BIT(10), .msg = "hi_water_line_err_port", @@ -753,8 +753,9 @@ /* configure IGU,EGU error interrupts */ hclge_cmd_setup_basic_desc(&desc, HCLGE_IGU_COMMON_INT_EN, false); + desc.data[0] = cpu_to_le32(HCLGE_IGU_ERR_INT_TYPE); if (en) - desc.data[0] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN); + desc.data[0] |= cpu_to_le32(HCLGE_IGU_ERR_INT_EN); desc.data[1] = cpu_to_le32(HCLGE_IGU_ERR_INT_EN_MASK); @@ -1667,9 +1668,6 @@ hclge_handle_rocee_ras_error(ae_dev); } - if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) - goto out; - if (ae_dev->hw_err_reset_req) return PCI_ERS_RESULT_NEED_RESET; @@ -1747,7 +1745,7 @@ if (vf_id) { if (vf_id >= hdev->num_alloc_vport) { - dev_err(dev, "invalid vf id(%d)\n", vf_id); + dev_err(dev, "invalid vf id(%u)\n", vf_id); return; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.h @@ -33,7 +33,8 @@ #define HCLGE_TQP_ECC_ERR_INT_EN_MASK 0x0FFF #define HCLGE_MSIX_SRAM_ECC_ERR_INT_EN_MASK 0x0F000000 #define HCLGE_MSIX_SRAM_ECC_ERR_INT_EN 0x0F000000 -#define HCLGE_IGU_ERR_INT_EN 0x0000066F +#define HCLGE_IGU_ERR_INT_EN 0x0000000F +#define HCLGE_IGU_ERR_INT_TYPE 0x00000660 #define HCLGE_IGU_ERR_INT_EN_MASK 0x000F #define HCLGE_IGU_TNL_ERR_INT_EN 0x0002AABF #define HCLGE_IGU_TNL_ERR_INT_EN_MASK 0x003F --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -55,6 +55,8 @@ #define HCLGE_LINK_STATUS_MS 10 +#define HCLGE_VF_VPORT_START_NUM 1 + static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps); static int hclge_init_vlan_config(struct hclge_dev *hdev); static void hclge_sync_vlan_filter(struct hclge_dev *hdev); @@ -70,6 +72,8 @@ static struct hnae3_ae_algo ae_algo; +static struct workqueue_struct *hclge_wq; + static const struct pci_device_id ae_algo_pci_tbl[] = { {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_GE), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE), 0}, @@ -323,8 +327,7 @@ { .flags = HCLGE_MAC_MGR_MASK_VLAN_B, .ethter_type = cpu_to_le16(ETH_P_LLDP), - .mac_addr_hi32 = cpu_to_le32(htonl(0x0180C200)), - .mac_addr_lo16 = cpu_to_le16(htons(0x000E)), + .mac_addr = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e}, .i_port_bitmap = 0x1, }, }; @@ -415,7 +418,7 @@ { #define HCLGE_MAC_CMD_NUM 21 - u64 *data = (u64 *)(&hdev->hw_stats.mac_stats); + u64 *data = (u64 *)(&hdev->mac_stats); struct hclge_desc desc[HCLGE_MAC_CMD_NUM]; __le64 *desc_data; int i, k, n; @@ -452,7 +455,7 @@ static int hclge_mac_update_stats_complete(struct hclge_dev *hdev, u32 desc_num) { - u64 *data = (u64 *)(&hdev->hw_stats.mac_stats); + u64 *data = (u64 *)(&hdev->mac_stats); struct hclge_desc *desc; __le64 *desc_data; u16 i, k, n; @@ -746,7 +749,8 @@ handle->flags |= HNAE3_SUPPORT_SERDES_SERIAL_LOOPBACK; handle->flags |= HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK; - if (hdev->hw.mac.phydev) { + if (hdev->hw.mac.phydev && hdev->hw.mac.phydev->drv && + hdev->hw.mac.phydev->drv->set_loopback) { count += 1; handle->flags |= HNAE3_SUPPORT_PHY_LOOPBACK; } @@ -801,7 +805,7 @@ struct hclge_dev *hdev = vport->back; u64 *p; - p = hclge_comm_get_stats(&hdev->hw_stats.mac_stats, g_mac_stats_string, + p = hclge_comm_get_stats(&hdev->mac_stats, g_mac_stats_string, ARRAY_SIZE(g_mac_stats_string), data); p = hclge_tqps_get_stats(handle, p); } @@ -814,13 +818,15 @@ hclge_update_stats(handle, NULL); - mac_stats->tx_pause_cnt = hdev->hw_stats.mac_stats.mac_tx_mac_pause_num; - mac_stats->rx_pause_cnt = hdev->hw_stats.mac_stats.mac_rx_mac_pause_num; + mac_stats->tx_pause_cnt = hdev->mac_stats.mac_tx_mac_pause_num; + mac_stats->rx_pause_cnt = hdev->mac_stats.mac_rx_mac_pause_num; } static int hclge_parse_func_status(struct hclge_dev *hdev, struct hclge_func_status_cmd *status) { +#define HCLGE_MAC_ID_MASK 0xF + if (!(status->pf_state & HCLGE_PF_STATE_DONE)) return -EINVAL; @@ -830,6 +836,7 @@ else hdev->flag &= ~HCLGE_FLAG_MAIN; + hdev->hw.mac.mac_id = status->mac_id & HCLGE_MAC_ID_MASK; return 0; } @@ -1194,6 +1201,35 @@ hclge_parse_backplane_link_mode(hdev, speed_ability); } +static u32 hclge_get_max_speed(u8 speed_ability) +{ + if (speed_ability & HCLGE_SUPPORT_100G_BIT) + return HCLGE_MAC_SPEED_100G; + + if (speed_ability & HCLGE_SUPPORT_50G_BIT) + return HCLGE_MAC_SPEED_50G; + + if (speed_ability & HCLGE_SUPPORT_40G_BIT) + return HCLGE_MAC_SPEED_40G; + + if (speed_ability & HCLGE_SUPPORT_25G_BIT) + return HCLGE_MAC_SPEED_25G; + + if (speed_ability & HCLGE_SUPPORT_10G_BIT) + return HCLGE_MAC_SPEED_10G; + + if (speed_ability & HCLGE_SUPPORT_1G_BIT) + return HCLGE_MAC_SPEED_1G; + + if (speed_ability & HCLGE_SUPPORT_100M_BIT) + return HCLGE_MAC_SPEED_100M; + + if (speed_ability & HCLGE_SUPPORT_10M_BIT) + return HCLGE_MAC_SPEED_10M; + + return HCLGE_MAC_SPEED_1G; +} + static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) { struct hclge_cfg_param_cmd *req; @@ -1327,9 +1363,10 @@ static int hclge_configure(struct hclge_dev *hdev) { + const struct cpumask *cpumask = cpu_online_mask; struct hclge_cfg cfg; unsigned int i; - int ret; + int node, ret; ret = hclge_get_cfg(hdev, &cfg); if (ret) { @@ -1364,9 +1401,11 @@ hclge_parse_link_mode(hdev, cfg.speed_ability); + hdev->hw.mac.max_speed = hclge_get_max_speed(cfg.speed_ability); + if ((hdev->tc_max > HNAE3_MAX_TC) || (hdev->tc_max < 1)) { - dev_warn(&hdev->pdev->dev, "TC num = %d.\n", + dev_warn(&hdev->pdev->dev, "TC num = %u.\n", hdev->tc_max); hdev->tc_max = 1; } @@ -1389,11 +1428,12 @@ hclge_init_kdump_kernel_config(hdev); - /* Set the init affinity based on pci func number */ - i = cpumask_weight(cpumask_of_node(dev_to_node(&hdev->pdev->dev))); - i = i ? PCI_FUNC(hdev->pdev->devfn) % i : 0; - cpumask_set_cpu(cpumask_local_spread(i, dev_to_node(&hdev->pdev->dev)), - &hdev->affinity_mask); + /* Set the affinity based on numa node */ + node = dev_to_node(&hdev->pdev->dev); + if (node != NUMA_NO_NODE) + cpumask = cpumask_of_node(node); + + cpumask_copy(&hdev->affinity_mask, cpumask); return ret; } @@ -1626,7 +1666,7 @@ num_vport = hdev->num_vmdq_vport + hdev->num_req_vfs + 1; if (hdev->num_tqps < num_vport) { - dev_err(&hdev->pdev->dev, "tqps(%d) is less than vports(%d)", + dev_err(&hdev->pdev->dev, "tqps(%u) is less than vports(%d)", hdev->num_tqps, num_vport); return -EINVAL; } @@ -1649,6 +1689,7 @@ for (i = 0; i < num_vport; i++) { vport->back = hdev; vport->vport_id = i; + vport->vf_info.link_state = IFLA_VF_LINK_STATE_AUTO; vport->mps = HCLGE_MAC_DEFAULT_FRAME; vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE; vport->rxvlan_cfg.rx_vlan_offload_en = true; @@ -2312,7 +2353,7 @@ } if (vectors < hdev->num_msi) dev_warn(&hdev->pdev->dev, - "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", + "requested %u MSI/MSI-X, but allocated %d MSI/MSI-X\n", hdev->num_msi, vectors); hdev->num_msi = vectors; @@ -2417,10 +2458,12 @@ int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) { + struct hclge_mac *mac = &hdev->hw.mac; int ret; duplex = hclge_check_speed_dup(duplex, speed); - if (hdev->hw.mac.speed == speed && hdev->hw.mac.duplex == duplex) + if (!mac->support_autoneg && mac->speed == speed && + mac->duplex == duplex) return 0; ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex); @@ -2583,7 +2626,10 @@ int ret; hdev->support_sfp_query = true; - hdev->hw.mac.duplex = HCLGE_MAC_FULL; + + if (!test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) + hdev->hw.mac.duplex = HCLGE_MAC_FULL; + ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, hdev->hw.mac.duplex); if (ret) { @@ -2632,31 +2678,27 @@ static void hclge_mbx_task_schedule(struct hclge_dev *hdev) { - if (!test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) && + if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && !test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state)) - queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq, - &hdev->mbx_service_task); + mod_delayed_work_on(cpumask_first(&hdev->affinity_mask), + hclge_wq, &hdev->service_task, 0); } static void hclge_reset_task_schedule(struct hclge_dev *hdev) { if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && !test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) - queue_work_on(cpumask_first(&hdev->affinity_mask), system_wq, - &hdev->rst_service_task); + mod_delayed_work_on(cpumask_first(&hdev->affinity_mask), + hclge_wq, &hdev->service_task, 0); } void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time) { - if (!test_bit(HCLGE_STATE_DOWN, &hdev->state) && - !test_bit(HCLGE_STATE_REMOVING, &hdev->state) && - !test_and_set_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state)) { - hdev->hw_stats.stats_timer++; - hdev->fd_arfs_expire_timer++; + if (!test_bit(HCLGE_STATE_REMOVING, &hdev->state) && + !test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) mod_delayed_work_on(cpumask_first(&hdev->affinity_mask), - system_wq, &hdev->service_task, + hclge_wq, &hdev->service_task, delay_time); - } } static int hclge_get_mac_link_status(struct hclge_dev *hdev) @@ -2715,6 +2757,10 @@ if (!client) return; + + if (test_and_set_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state)) + return; + state = hclge_get_mac_phy_link(hdev); if (state != hdev->hw.mac.link) { for (i = 0; i < hdev->num_vmdq_vport + 1; i++) { @@ -2728,6 +2774,8 @@ } hdev->hw.mac.link = state; } + + clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state); } static void hclge_update_port_capability(struct hclge_mac *mac) @@ -2744,7 +2792,7 @@ else if (mac->media_type == HNAE3_MEDIA_TYPE_COPPER) mac->module_type = HNAE3_MODULE_TYPE_TP; - if (mac->support_autoneg == true) { + if (mac->support_autoneg) { linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mac->supported); linkmode_copy(mac->advertising, mac->supported); } else { @@ -2798,6 +2846,12 @@ return ret; } + /* In some case, mac speed get from IMP may be 0, it shouldn't be + * set to mac->speed. + */ + if (!le32_to_cpu(resp->speed)) + return 0; + mac->speed = le32_to_cpu(resp->speed); /* if resp->speed_ability is 0, it means it's an old version * firmware, do not update these params @@ -2871,6 +2925,65 @@ return hdev->hw.mac.link; } +static struct hclge_vport *hclge_get_vf_vport(struct hclge_dev *hdev, int vf) +{ + if (pci_num_vf(hdev->pdev) == 0) { + dev_err(&hdev->pdev->dev, + "SRIOV is disabled, can not get vport(%d) info.\n", vf); + return NULL; + } + + if (vf < 0 || vf >= pci_num_vf(hdev->pdev)) { + dev_err(&hdev->pdev->dev, + "vf id(%d) is out of range(0 <= vfid < %d)\n", + vf, pci_num_vf(hdev->pdev)); + return NULL; + } + + /* VF start from 1 in vport */ + vf += HCLGE_VF_VPORT_START_NUM; + return &hdev->vport[vf]; +} + +static int hclge_get_vf_config(struct hnae3_handle *handle, int vf, + struct ifla_vf_info *ivf) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + ivf->vf = vf; + ivf->linkstate = vport->vf_info.link_state; + ivf->spoofchk = vport->vf_info.spoofchk; + ivf->trusted = vport->vf_info.trusted; + ivf->min_tx_rate = 0; + ivf->max_tx_rate = vport->vf_info.max_tx_rate; + ivf->vlan = vport->port_base_vlan_cfg.vlan_info.vlan_tag; + ivf->vlan_proto = htons(vport->port_base_vlan_cfg.vlan_info.vlan_proto); + ivf->qos = vport->port_base_vlan_cfg.vlan_info.qos; + ether_addr_copy(ivf->mac, vport->vf_info.mac); + + return 0; +} + +static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, + int link_state) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + vport->vf_info.link_state = link_state; + + return 0; +} + static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) { u32 rst_src_reg, cmdq_src_reg, msix_src_reg; @@ -2909,8 +3022,6 @@ /* check for vector0 msix event source */ if (msix_src_reg & HCLGE_VECTOR0_REG_MSIX_MASK) { - dev_info(&hdev->pdev->dev, "received event 0x%x\n", - msix_src_reg); *clearval = msix_src_reg; return HCLGE_VECTOR0_EVENT_ERR; } @@ -2934,8 +3045,13 @@ static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, u32 regclr) { +#define HCLGE_IMP_RESET_DELAY 5 + switch (event_type) { case HCLGE_VECTOR0_EVENT_RST: + if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) + mdelay(HCLGE_IMP_RESET_DELAY); + hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); break; case HCLGE_VECTOR0_EVENT_MBX: @@ -3083,8 +3199,10 @@ hclge_get_misc_vector(hdev); /* this would be explicitly freed in the end */ + snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", + HCLGE_NAME, pci_name(hdev->pdev)); ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, - 0, "hclge_misc", hdev); + 0, hdev->misc_vector.name, hdev); if (ret) { hclge_free_vector(hdev, 0); dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", @@ -3158,7 +3276,8 @@ static int hclge_reset_wait(struct hclge_dev *hdev) { #define HCLGE_RESET_WATI_MS 100 -#define HCLGE_RESET_WAIT_CNT 200 +#define HCLGE_RESET_WAIT_CNT 350 + u32 val, reg, reg_bit; u32 cnt = 0; @@ -3175,8 +3294,6 @@ reg = HCLGE_FUN_RST_ING; reg_bit = HCLGE_FUN_RST_ING_B; break; - case HNAE3_FLR_RESET: - break; default: dev_err(&hdev->pdev->dev, "Wait for unsupported reset type: %d\n", @@ -3184,20 +3301,6 @@ return -EINVAL; } - if (hdev->reset_type == HNAE3_FLR_RESET) { - while (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state) && - cnt++ < HCLGE_RESET_WAIT_CNT) - msleep(HCLGE_RESET_WATI_MS); - - if (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state)) { - dev_err(&hdev->pdev->dev, - "flr wait timeout: %d\n", cnt); - return -EBUSY; - } - - return 0; - } - val = hclge_read_dev(&hdev->hw, reg); while (hnae3_get_bit(val, reg_bit) && cnt < HCLGE_RESET_WAIT_CNT) { msleep(HCLGE_RESET_WATI_MS); @@ -3241,7 +3344,7 @@ ret = hclge_set_vf_rst(hdev, vport->vport_id, reset); if (ret) { dev_err(&hdev->pdev->dev, - "set vf(%d) rst failed %d!\n", + "set vf(%u) rst failed %d!\n", vport->vport_id, ret); return ret; } @@ -3256,14 +3359,26 @@ ret = hclge_inform_reset_assert_to_vf(vport); if (ret) dev_warn(&hdev->pdev->dev, - "inform reset to vf(%d) failed %d!\n", + "inform reset to vf(%u) failed %d!\n", vport->vport_id, ret); } return 0; } -static int hclge_func_reset_sync_vf(struct hclge_dev *hdev) +static void hclge_mailbox_service_task(struct hclge_dev *hdev) +{ + if (!test_and_clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state) || + test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state) || + test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state)) + return; + + hclge_mbx_handler(hdev); + + clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); +} + +static void hclge_func_reset_sync_vf(struct hclge_dev *hdev) { struct hclge_pf_rst_sync_cmd *req; struct hclge_desc desc; @@ -3274,26 +3389,28 @@ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_VF_RST_RDY, true); do { + /* vf need to down netdev by mbx during PF or FLR reset */ + hclge_mailbox_service_task(hdev); + ret = hclge_cmd_send(&hdev->hw, &desc, 1); /* for compatible with old firmware, wait * 100 ms for VF to stop IO */ if (ret == -EOPNOTSUPP) { msleep(HCLGE_RESET_SYNC_TIME); - return 0; + return; } else if (ret) { - dev_err(&hdev->pdev->dev, "sync with VF fail %d!\n", - ret); - return ret; + dev_warn(&hdev->pdev->dev, "sync with VF fail %d!\n", + ret); + return; } else if (req->all_vf_ready) { - return 0; + return; } msleep(HCLGE_PF_RESET_SYNC_TIME); hclge_cmd_reuse_desc(&desc, true); } while (cnt++ < HCLGE_PF_RESET_SYNC_CNT); - dev_err(&hdev->pdev->dev, "sync with VF timeout!\n"); - return -ETIME; + dev_warn(&hdev->pdev->dev, "sync with VF timeout!\n"); } void hclge_report_hw_error(struct hclge_dev *hdev, @@ -3353,7 +3470,7 @@ u32 val; if (hclge_get_hw_reset_stat(handle)) { - dev_info(&pdev->dev, "Hardware reset not finish\n"); + dev_info(&pdev->dev, "hardware reset not finish\n"); dev_info(&pdev->dev, "func_rst_reg:0x%x, global_rst_reg:0x%x\n", hclge_read_dev(&hdev->hw, HCLGE_FUN_RST_ING), hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG)); @@ -3362,26 +3479,20 @@ switch (hdev->reset_type) { case HNAE3_GLOBAL_RESET: + dev_info(&pdev->dev, "global reset requested\n"); val = hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG); hnae3_set_bit(val, HCLGE_GLOBAL_RESET_BIT, 1); hclge_write_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG, val); - dev_info(&pdev->dev, "Global Reset requested\n"); break; case HNAE3_FUNC_RESET: - dev_info(&pdev->dev, "PF Reset requested\n"); + dev_info(&pdev->dev, "PF reset requested\n"); /* schedule again to check later */ set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); hclge_reset_task_schedule(hdev); break; - case HNAE3_FLR_RESET: - dev_info(&pdev->dev, "FLR requested\n"); - /* schedule again to check later */ - set_bit(HNAE3_FLR_RESET, &hdev->reset_pending); - hclge_reset_task_schedule(hdev); - break; default: dev_warn(&pdev->dev, - "Unsupported reset type: %d\n", hdev->reset_type); + "unsupported reset type: %d\n", hdev->reset_type); break; } } @@ -3394,10 +3505,15 @@ /* first, resolve any unknown reset type to the known type(s) */ if (test_bit(HNAE3_UNKNOWN_RESET, addr)) { + u32 msix_sts_reg = hclge_read_dev(&hdev->hw, + HCLGE_VECTOR0_PF_OTHER_INT_STS_REG); /* we will intentionally ignore any errors from this function * as we will end up in *some* reset request in any case */ - hclge_handle_hw_msix_error(hdev, addr); + if (hclge_handle_hw_msix_error(hdev, addr)) + dev_info(&hdev->pdev->dev, "received msix interrupt 0x%x\n", + msix_sts_reg); + clear_bit(HNAE3_UNKNOWN_RESET, addr); /* We defered the clearing of the error event which caused * interrupt since it was not posssible to do that in @@ -3462,23 +3578,6 @@ hclge_enable_vector(&hdev->misc_vector, true); } -static int hclge_reset_prepare_down(struct hclge_dev *hdev) -{ - int ret = 0; - - switch (hdev->reset_type) { - case HNAE3_FUNC_RESET: - /* fall through */ - case HNAE3_FLR_RESET: - ret = hclge_set_all_vf_rst(hdev, true); - break; - default: - break; - } - - return ret; -} - static void hclge_reset_handshake(struct hclge_dev *hdev, bool enable) { u32 reg_val; @@ -3492,6 +3591,19 @@ hclge_write_dev(&hdev->hw, HCLGE_NIC_CSQ_DEPTH_REG, reg_val); } +static int hclge_func_reset_notify_vf(struct hclge_dev *hdev) +{ + int ret; + + ret = hclge_set_all_vf_rst(hdev, true); + if (ret) + return ret; + + hclge_func_reset_sync_vf(hdev); + + return 0; +} + static int hclge_reset_prepare_wait(struct hclge_dev *hdev) { u32 reg_val; @@ -3499,10 +3611,7 @@ switch (hdev->reset_type) { case HNAE3_FUNC_RESET: - /* to confirm whether all running VF is ready - * before request PF reset - */ - ret = hclge_func_reset_sync_vf(hdev); + ret = hclge_func_reset_notify_vf(hdev); if (ret) return ret; @@ -3522,16 +3631,9 @@ hdev->rst_stats.pf_rst_cnt++; break; case HNAE3_FLR_RESET: - /* to confirm whether all running VF is ready - * before request PF reset - */ - ret = hclge_func_reset_sync_vf(hdev); + ret = hclge_func_reset_notify_vf(hdev); if (ret) return ret; - - set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state); - set_bit(HNAE3_FLR_DOWN, &hdev->flr_state); - hdev->rst_stats.flr_rst_cnt++; break; case HNAE3_IMP_RESET: hclge_handle_imp_error(hdev); @@ -3569,7 +3671,7 @@ hdev->rst_stats.reset_fail_cnt++; set_bit(hdev->reset_type, &hdev->reset_pending); dev_info(&hdev->pdev->dev, - "re-schedule reset task(%d)\n", + "re-schedule reset task(%u)\n", hdev->rst_stats.reset_fail_cnt); return true; } @@ -3580,6 +3682,11 @@ hclge_reset_handshake(hdev, true); dev_err(&hdev->pdev->dev, "Reset fail!\n"); + + hclge_dbg_dump_rst_info(hdev); + + set_bit(HCLGE_STATE_RST_FAIL, &hdev->state); + return false; } @@ -3655,10 +3762,9 @@ return hclge_notify_client(hdev, HNAE3_RESTORE_CLIENT); } -static void hclge_reset(struct hclge_dev *hdev) +static int hclge_reset_prepare(struct hclge_dev *hdev) { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); - enum hnae3_reset_type reset_level; int ret; /* Initialize ae_dev reset status as well, in case enet layer wants to @@ -3669,45 +3775,41 @@ /* perform reset of the stack & ae device for a client */ ret = hclge_notify_roce_client(hdev, HNAE3_DOWN_CLIENT); if (ret) - goto err_reset; - - ret = hclge_reset_prepare_down(hdev); - if (ret) - goto err_reset; + return ret; rtnl_lock(); ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT); - if (ret) - goto err_reset_lock; - rtnl_unlock(); - - ret = hclge_reset_prepare_wait(hdev); if (ret) - goto err_reset; + return ret; - if (hclge_reset_wait(hdev)) - goto err_reset; + return hclge_reset_prepare_wait(hdev); +} + +static int hclge_reset_rebuild(struct hclge_dev *hdev) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + enum hnae3_reset_type reset_level; + int ret; hdev->rst_stats.hw_reset_done_cnt++; ret = hclge_notify_roce_client(hdev, HNAE3_UNINIT_CLIENT); if (ret) - goto err_reset; + return ret; rtnl_lock(); - ret = hclge_reset_stack(hdev); + rtnl_unlock(); if (ret) - goto err_reset_lock; + return ret; hclge_clear_reset_cause(hdev); ret = hclge_reset_prepare_up(hdev); if (ret) - goto err_reset_lock; + return ret; - rtnl_unlock(); ret = hclge_notify_roce_client(hdev, HNAE3_INIT_CLIENT); /* ignore RoCE notify error if it fails HCLGE_RESET_MAX_FAIL_CNT - 1 @@ -3715,24 +3817,23 @@ */ if (ret && hdev->rst_stats.reset_fail_cnt < HCLGE_RESET_MAX_FAIL_CNT - 1) - goto err_reset; + return ret; rtnl_lock(); - ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT); - if (ret) - goto err_reset_lock; - rtnl_unlock(); + if (ret) + return ret; ret = hclge_notify_roce_client(hdev, HNAE3_UP_CLIENT); if (ret) - goto err_reset; + return ret; hdev->last_reset_time = jiffies; hdev->rst_stats.reset_fail_cnt = 0; hdev->rst_stats.reset_done_cnt++; ae_dev->reset_type = HNAE3_NONE_RESET; + clear_bit(HCLGE_STATE_RST_FAIL, &hdev->state); /* if default_reset_request has a higher level reset request, * it should be handled as soon as possible. since some errors @@ -3743,10 +3844,22 @@ if (reset_level != HNAE3_NONE_RESET) set_bit(reset_level, &hdev->reset_request); + return 0; +} + +static void hclge_reset(struct hclge_dev *hdev) +{ + if (hclge_reset_prepare(hdev)) + goto err_reset; + + if (hclge_reset_wait(hdev)) + goto err_reset; + + if (hclge_reset_rebuild(hdev)) + goto err_reset; + return; -err_reset_lock: - rtnl_unlock(); err_reset: if (hclge_reset_err_handle(hdev)) hclge_reset_task_schedule(hdev); @@ -3779,12 +3892,13 @@ HCLGE_RESET_INTERVAL))) { mod_timer(&hdev->reset_timer, jiffies + HCLGE_RESET_INTERVAL); return; - } else if (hdev->default_reset_request) + } else if (hdev->default_reset_request) { hdev->reset_level = hclge_get_reset_level(ae_dev, &hdev->default_reset_request); - else if (time_after(jiffies, (hdev->last_reset_time + 4 * 5 * HZ))) + } else if (time_after(jiffies, (hdev->last_reset_time + 4 * 5 * HZ))) { hdev->reset_level = HNAE3_FUNC_RESET; + } dev_info(&hdev->pdev->dev, "received reset event, reset type is %d\n", hdev->reset_level); @@ -3846,34 +3960,18 @@ hdev->reset_type = HNAE3_NONE_RESET; } -static void hclge_reset_service_task(struct work_struct *work) +static void hclge_reset_service_task(struct hclge_dev *hdev) { - struct hclge_dev *hdev = - container_of(work, struct hclge_dev, rst_service_task); - - if (test_and_set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) + if (!test_and_clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) return; - clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state); + down(&hdev->reset_sem); + set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); hclge_reset_subtask(hdev); clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); -} - -static void hclge_mailbox_service_task(struct work_struct *work) -{ - struct hclge_dev *hdev = - container_of(work, struct hclge_dev, mbx_service_task); - - if (test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state)) - return; - - clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state); - - hclge_mbx_handler(hdev); - - clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); + up(&hdev->reset_sem); } static void hclge_update_vport_alive(struct hclge_dev *hdev) @@ -3893,28 +3991,62 @@ } } -static void hclge_service_task(struct work_struct *work) +static void hclge_periodic_service_task(struct hclge_dev *hdev) { - struct hclge_dev *hdev = - container_of(work, struct hclge_dev, service_task.work); + unsigned long delta = round_jiffies_relative(HZ); - clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state); + /* Always handle the link updating to make sure link state is + * updated when it is triggered by mbx. + */ + hclge_update_link_status(hdev); - if (hdev->hw_stats.stats_timer >= HCLGE_STATS_TIMER_INTERVAL) { - hclge_update_stats_for_all(hdev); - hdev->hw_stats.stats_timer = 0; + if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { + delta = jiffies - hdev->last_serv_processed; + + if (delta < round_jiffies_relative(HZ)) { + delta = round_jiffies_relative(HZ) - delta; + goto out; + } } - hclge_update_port_info(hdev); - hclge_update_link_status(hdev); + hdev->serv_processed_cnt++; hclge_update_vport_alive(hdev); + + if (test_bit(HCLGE_STATE_DOWN, &hdev->state)) { + hdev->last_serv_processed = jiffies; + goto out; + } + + if (!(hdev->serv_processed_cnt % HCLGE_STATS_TIMER_INTERVAL)) + hclge_update_stats_for_all(hdev); + + hclge_update_port_info(hdev); hclge_sync_vlan_filter(hdev); - if (hdev->fd_arfs_expire_timer >= HCLGE_FD_ARFS_EXPIRE_TIMER_INTERVAL) { + + if (!(hdev->serv_processed_cnt % HCLGE_ARFS_EXPIRE_INTERVAL)) hclge_rfs_filter_expire(hdev); - hdev->fd_arfs_expire_timer = 0; - } - hclge_task_schedule(hdev, round_jiffies_relative(HZ)); + hdev->last_serv_processed = jiffies; + +out: + hclge_task_schedule(hdev, delta); +} + +static void hclge_service_task(struct work_struct *work) +{ + struct hclge_dev *hdev = + container_of(work, struct hclge_dev, service_task.work); + + hclge_reset_service_task(hdev); + hclge_mailbox_service_task(hdev); + hclge_periodic_service_task(hdev); + + /* Handle reset and mbx again in case periodical task delays the + * handling by calling hclge_task_schedule() in + * hclge_periodic_service_task(). + */ + hclge_reset_service_task(hdev); + hclge_mailbox_service_task(hdev); } struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle) @@ -3985,7 +4117,7 @@ vector_id = hclge_get_vector_index(hdev, vector); if (vector_id < 0) { dev_err(&hdev->pdev->dev, - "Get vector index fail. vector_id =%d\n", vector_id); + "Get vector index fail. vector = %d\n", vector); return vector_id; } @@ -4415,7 +4547,7 @@ */ if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) { dev_err(&hdev->pdev->dev, - "Configure rss tc size failed, invalid TC_SIZE = %d\n", + "Configure rss tc size failed, invalid TC_SIZE = %u\n", rss_size); return -EINVAL; } @@ -4560,7 +4692,7 @@ vector_id = hclge_get_vector_index(hdev, vector); if (vector_id < 0) { dev_err(&hdev->pdev->dev, - "Get vector index fail. vector_id =%d\n", vector_id); + "failed to get vector index. vector=%d\n", vector); return vector_id; } @@ -4593,8 +4725,8 @@ return ret; } -int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, - struct hclge_promisc_param *param) +static int hclge_cmd_set_promisc_mode(struct hclge_dev *hdev, + struct hclge_promisc_param *param) { struct hclge_promisc_cfg_cmd *req; struct hclge_desc desc; @@ -4621,8 +4753,9 @@ return ret; } -void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, - bool en_mc, bool en_bc, int vport_id) +static void hclge_promisc_param_init(struct hclge_promisc_param *param, + bool en_uc, bool en_mc, bool en_bc, + int vport_id) { if (!param) return; @@ -4637,12 +4770,21 @@ param->vf_id = vport_id; } +int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc, + bool en_mc_pmc, bool en_bc_pmc) +{ + struct hclge_dev *hdev = vport->back; + struct hclge_promisc_param param; + + hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, en_bc_pmc, + vport->vport_id); + return hclge_cmd_set_promisc_mode(hdev, ¶m); +} + static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, bool en_mc_pmc) { struct hclge_vport *vport = hclge_get_vport(handle); - struct hclge_dev *hdev = vport->back; - struct hclge_promisc_param param; bool en_bc_pmc = true; /* For revision 0x20, if broadcast promisc enabled, vlan filter is @@ -4652,9 +4794,8 @@ if (handle->pdev->revision == 0x20) en_bc_pmc = handle->netdev_flags & HNAE3_BPE ? true : false; - hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, en_bc_pmc, - vport->vport_id); - return hclge_cmd_set_promisc_mode(hdev, ¶m); + return hclge_set_vport_promisc_mode(vport, en_uc_pmc, en_mc_pmc, + en_bc_pmc); } static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode) @@ -4756,7 +4897,7 @@ break; default: dev_err(&hdev->pdev->dev, - "Unsupported flow director mode %d\n", + "Unsupported flow director mode %u\n", hdev->fd_cfg.fd_mode); return -EOPNOTSUPP; } @@ -4905,9 +5046,9 @@ case BIT(INNER_SRC_MAC): for (i = 0; i < ETH_ALEN; i++) { calc_x(key_x[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], - rule->tuples.src_mac[i]); + rule->tuples_mask.src_mac[i]); calc_y(key_y[ETH_ALEN - 1 - i], rule->tuples.src_mac[i], - rule->tuples.src_mac[i]); + rule->tuples_mask.src_mac[i]); } return true; @@ -5086,7 +5227,7 @@ true); if (ret) { dev_err(&hdev->pdev->dev, - "fd key_y config fail, loc=%d, ret=%d\n", + "fd key_y config fail, loc=%u, ret=%d\n", rule->queue_id, ret); return ret; } @@ -5095,7 +5236,7 @@ true); if (ret) dev_err(&hdev->pdev->dev, - "fd key_x config fail, loc=%d, ret=%d\n", + "fd key_x config fail, loc=%u, ret=%d\n", rule->queue_id, ret); return ret; } @@ -5344,7 +5485,7 @@ } } else if (!is_add) { dev_err(&hdev->pdev->dev, - "delete fail, rule %d is inexistent\n", + "delete fail, rule %u is inexistent\n", location); return -EINVAL; } @@ -5584,7 +5725,7 @@ if (vf > hdev->num_req_vfs) { dev_err(&hdev->pdev->dev, - "Error: vf id (%d) > max vf num (%d)\n", + "Error: vf id (%u) > max vf num (%u)\n", vf, hdev->num_req_vfs); return -EINVAL; } @@ -5594,7 +5735,7 @@ if (ring >= tqps) { dev_err(&hdev->pdev->dev, - "Error: queue id (%d) > max tqp num (%d)\n", + "Error: queue id (%u) > max tqp num (%u)\n", ring, tqps - 1); return -EINVAL; } @@ -5625,9 +5766,9 @@ /* to avoid rule conflict, when user configure rule by ethtool, * we need to clear all arfs rules */ + spin_lock_bh(&hdev->fd_rule_lock); hclge_clear_arfs_rules(handle); - spin_lock_bh(&hdev->fd_rule_lock); ret = hclge_fd_config_rule(hdev, rule); spin_unlock_bh(&hdev->fd_rule_lock); @@ -5653,7 +5794,7 @@ if (!hclge_fd_rule_exist(hdev, fs->location)) { dev_err(&hdev->pdev->dev, - "Delete fail, rule %d is inexistent\n", fs->location); + "Delete fail, rule %u is inexistent\n", fs->location); return -ENOENT; } @@ -5670,6 +5811,7 @@ return ret; } +/* make sure being called after lock up with fd_rule_lock */ static void hclge_del_all_fd_entries(struct hnae3_handle *handle, bool clear_list) { @@ -5682,7 +5824,6 @@ if (!hnae3_dev_fd_supported(hdev)) return; - spin_lock_bh(&hdev->fd_rule_lock); for_each_set_bit(location, hdev->fd_bmap, hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]) hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, location, @@ -5699,8 +5840,6 @@ bitmap_zero(hdev->fd_bmap, hdev->fd_cfg.rule_num[HCLGE_FD_STAGE_1]); } - - spin_unlock_bh(&hdev->fd_rule_lock); } static int hclge_restore_fd_entries(struct hnae3_handle *handle) @@ -5730,7 +5869,7 @@ if (ret) { dev_warn(&hdev->pdev->dev, - "Restore rule %d failed, remove it\n", + "Restore rule %u failed, remove it\n", rule->location); clear_bit(rule->location, hdev->fd_bmap); hlist_del(&rule->rule_node); @@ -5938,8 +6077,7 @@ fs->h_ext.vlan_tci = cpu_to_be16(rule->tuples.vlan_tag1); fs->m_ext.vlan_tci = rule->unused_tuple & BIT(INNER_VLAN_TAG_FST) ? - cpu_to_be16(VLAN_VID_MASK) : - cpu_to_be16(rule->tuples_mask.vlan_tag1); + 0 : cpu_to_be16(rule->tuples_mask.vlan_tag1); } if (fs->flow_type & FLOW_MAC_EXT) { @@ -6003,6 +6141,9 @@ static void hclge_fd_get_flow_tuples(const struct flow_keys *fkeys, struct hclge_fd_rule_tuples *tuples) { +#define flow_ip6_src fkeys->addrs.v6addrs.src.in6_u.u6_addr32 +#define flow_ip6_dst fkeys->addrs.v6addrs.dst.in6_u.u6_addr32 + tuples->ether_proto = be16_to_cpu(fkeys->basic.n_proto); tuples->ip_proto = fkeys->basic.ip_proto; tuples->dst_port = be16_to_cpu(fkeys->ports.dst); @@ -6011,12 +6152,12 @@ tuples->src_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.src); tuples->dst_ip[3] = be32_to_cpu(fkeys->addrs.v4addrs.dst); } else { - memcpy(tuples->src_ip, - fkeys->addrs.v6addrs.src.in6_u.u6_addr32, - sizeof(tuples->src_ip)); - memcpy(tuples->dst_ip, - fkeys->addrs.v6addrs.dst.in6_u.u6_addr32, - sizeof(tuples->dst_ip)); + int i; + + for (i = 0; i < IPV6_SIZE; i++) { + tuples->src_ip[i] = be32_to_cpu(flow_ip6_src[i]); + tuples->dst_ip[i] = be32_to_cpu(flow_ip6_dst[i]); + } } } @@ -6064,7 +6205,7 @@ u16 flow_id, struct flow_keys *fkeys) { struct hclge_vport *vport = hclge_get_vport(handle); - struct hclge_fd_rule_tuples new_tuples; + struct hclge_fd_rule_tuples new_tuples = {}; struct hclge_dev *hdev = vport->back; struct hclge_fd_rule *rule; u16 tmp_queue_id; @@ -6074,20 +6215,18 @@ if (!hnae3_dev_fd_supported(hdev)) return -EOPNOTSUPP; - memset(&new_tuples, 0, sizeof(new_tuples)); - hclge_fd_get_flow_tuples(fkeys, &new_tuples); - - spin_lock_bh(&hdev->fd_rule_lock); - /* when there is already fd rule existed add by user, * arfs should not work */ + spin_lock_bh(&hdev->fd_rule_lock); if (hdev->fd_active_type == HCLGE_FD_EP_ACTIVE) { spin_unlock_bh(&hdev->fd_rule_lock); return -EOPNOTSUPP; } + hclge_fd_get_flow_tuples(fkeys, &new_tuples); + /* check is there flow director filter existed for this flow, * if not, create a new filter for it; * if filter exist with different queue id, modify the filter; @@ -6172,6 +6311,7 @@ #endif } +/* make sure being called after lock up with fd_rule_lock */ static void hclge_clear_arfs_rules(struct hnae3_handle *handle) { #ifdef CONFIG_RFS_ACCEL @@ -6216,10 +6356,14 @@ hdev->fd_en = enable; clear = hdev->fd_active_type == HCLGE_FD_ARFS_ACTIVE; - if (!enable) + + if (!enable) { + spin_lock_bh(&hdev->fd_rule_lock); hclge_del_all_fd_entries(handle, clear); - else + spin_unlock_bh(&hdev->fd_rule_lock); + } else { hclge_restore_fd_entries(handle); + } } static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable) @@ -6631,6 +6775,19 @@ } } +static void hclge_flush_link_update(struct hclge_dev *hdev) +{ +#define HCLGE_FLUSH_LINK_TIMEOUT 100000 + + unsigned long last = hdev->serv_processed_cnt; + int i = 0; + + while (test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state) && + i++ < HCLGE_FLUSH_LINK_TIMEOUT && + last == hdev->serv_processed_cnt) + usleep_range(1, 1); +} + static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable) { struct hclge_vport *vport = hclge_get_vport(handle); @@ -6639,12 +6796,12 @@ if (enable) { hclge_task_schedule(hdev, round_jiffies_relative(HZ)); } else { - /* Set the DOWN flag here to disable the service to be - * scheduled again - */ + /* Set the DOWN flag here to disable link updating */ set_bit(HCLGE_STATE_DOWN, &hdev->state); - cancel_delayed_work_sync(&hdev->service_task); - clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state); + + /* flush memory to make sure DOWN is seen by service task */ + smp_mb__before_atomic(); + hclge_flush_link_update(hdev); } } @@ -6673,17 +6830,22 @@ int i; set_bit(HCLGE_STATE_DOWN, &hdev->state); - + spin_lock_bh(&hdev->fd_rule_lock); hclge_clear_arfs_rules(handle); + spin_unlock_bh(&hdev->fd_rule_lock); - /* If it is not PF reset, the firmware will disable the MAC, + /* If it is not PF reset or FLR, the firmware will disable the MAC, * so it only need to stop phy here. */ - if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) && - hdev->reset_type != HNAE3_FUNC_RESET) { - hclge_mac_stop_phy(hdev); - hclge_update_link_status(hdev); - return; + if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state)) { + hclge_pfc_pause_en_cfg(hdev, HCLGE_PFC_TX_RX_DISABLE, + HCLGE_PFC_DISABLE); + if (hdev->reset_type != HNAE3_FUNC_RESET && + hdev->reset_type != HNAE3_FLR_RESET) { + hclge_mac_stop_phy(hdev); + hclge_update_link_status(hdev); + return; + } } for (i = 0; i < handle->kinfo.num_tqps; i++) @@ -6735,7 +6897,7 @@ if (cmdq_resp) { dev_err(&hdev->pdev->dev, - "cmdq execute failed for get_mac_vlan_cmd_status,status=%d.\n", + "cmdq execute failed for get_mac_vlan_cmd_status,status=%u.\n", cmdq_resp); return -EIO; } @@ -6987,7 +7149,7 @@ if (allocated_size < hdev->wanted_umv_size) dev_warn(&hdev->pdev->dev, - "Alloc umv space failed, want %d, get %d\n", + "Alloc umv space failed, want %u, get %u\n", hdev->wanted_umv_size, allocated_size); mutex_init(&hdev->umv_mutex); @@ -7155,7 +7317,7 @@ /* check if we just hit the duplicate */ if (!ret) { - dev_warn(&hdev->pdev->dev, "VF %d mac(%pM) exists\n", + dev_warn(&hdev->pdev->dev, "VF %u mac(%pM) exists\n", vport->vport_id, addr); return 0; } @@ -7225,7 +7387,6 @@ return -EINVAL; } memset(&req, 0, sizeof(req)); - hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hclge_prepare_mac_addr(&req, addr, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); if (status) { @@ -7270,7 +7431,6 @@ } memset(&req, 0, sizeof(req)); - hnae3_set_bit(req.entry_type, HCLGE_MAC_VLAN_BIT0_EN_B, 0); hclge_prepare_mac_addr(&req, addr, true); status = hclge_lookup_mac_vlan_tbl(vport, &req, desc, true); if (!status) { @@ -7336,7 +7496,7 @@ mc_flag = is_write_tbl && mac_type == HCLGE_MAC_ADDR_MC; list_for_each_entry_safe(mac_cfg, tmp, list, node) { - if (strncmp(mac_cfg->mac_addr, mac_addr, ETH_ALEN) == 0) { + if (ether_addr_equal(mac_cfg->mac_addr, mac_addr)) { if (uc_flag && mac_cfg->hd_tbl_status) hclge_rm_uc_addr_common(vport, mac_addr); @@ -7380,7 +7540,6 @@ struct hclge_vport *vport; int i; - mutex_lock(&hdev->vport_cfg_mutex); for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; list_for_each_entry_safe(mac, tmp, &vport->uc_mac_list, node) { @@ -7393,7 +7552,6 @@ kfree(mac); } } - mutex_unlock(&hdev->vport_cfg_mutex); } static int hclge_get_mac_ethertype_cmd_status(struct hclge_dev *hdev, @@ -7408,7 +7566,7 @@ if (cmdq_resp) { dev_err(&hdev->pdev->dev, - "cmdq execute failed for get_mac_ethertype_cmd_status, status=%d.\n", + "cmdq execute failed for get_mac_ethertype_cmd_status, status=%u.\n", cmdq_resp); return -EIO; } @@ -7430,7 +7588,7 @@ break; default: dev_err(&hdev->pdev->dev, - "add mac ethertype failed for undefined, code=%d.\n", + "add mac ethertype failed for undefined, code=%u.\n", resp_code); return_status = -EIO; } @@ -7438,6 +7596,73 @@ return return_status; } +static bool hclge_check_vf_mac_exist(struct hclge_vport *vport, int vf_idx, + u8 *mac_addr) +{ + struct hclge_mac_vlan_tbl_entry_cmd req; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + u16 egress_port = 0; + int i; + + if (is_zero_ether_addr(mac_addr)) + return false; + + memset(&req, 0, sizeof(req)); + hnae3_set_field(egress_port, HCLGE_MAC_EPORT_VFID_M, + HCLGE_MAC_EPORT_VFID_S, vport->vport_id); + req.egress_port = cpu_to_le16(egress_port); + hclge_prepare_mac_addr(&req, mac_addr, false); + + if (hclge_lookup_mac_vlan_tbl(vport, &req, &desc, false) != -ENOENT) + return true; + + vf_idx += HCLGE_VF_VPORT_START_NUM; + for (i = hdev->num_vmdq_vport + 1; i < hdev->num_alloc_vport; i++) + if (i != vf_idx && + ether_addr_equal(mac_addr, hdev->vport[i].vf_info.mac)) + return true; + + return false; +} + +static int hclge_set_vf_mac(struct hnae3_handle *handle, int vf, + u8 *mac_addr) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + if (ether_addr_equal(mac_addr, vport->vf_info.mac)) { + dev_info(&hdev->pdev->dev, + "Specified MAC(=%pM) is same as before, no change committed!\n", + mac_addr); + return 0; + } + + if (hclge_check_vf_mac_exist(vport, vf, mac_addr)) { + dev_err(&hdev->pdev->dev, "Specified MAC(=%pM) exists!\n", + mac_addr); + return -EEXIST; + } + + ether_addr_copy(vport->vf_info.mac, mac_addr); + + if (test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { + dev_info(&hdev->pdev->dev, + "MAC of VF %d has been set to %pM, and it will be reinitialized!\n", + vf, mac_addr); + return hclge_inform_reset_assert_to_vf(vport); + } + + dev_info(&hdev->pdev->dev, "MAC of VF %d has been set to %pM\n", + vf, mac_addr); + return 0; +} + static int hclge_add_mgr_tbl(struct hclge_dev *hdev, const struct hclge_mac_mgr_tbl_entry_cmd *req) { @@ -7558,16 +7783,27 @@ struct hclge_desc desc; int ret; - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, false); - + /* read current vlan filter parameter */ + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, true); req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data; req->vlan_type = vlan_type; - req->vlan_fe = filter_en ? fe_type : 0; req->vf_id = vf_id; ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to get vlan filter config, ret = %d.\n", ret); + return ret; + } + + /* modify and write new config parameter */ + hclge_cmd_reuse_desc(&desc, false); + req->vlan_fe = filter_en ? + (req->vlan_fe | fe_type) : (req->vlan_fe & ~fe_type); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); if (ret) - dev_err(&hdev->pdev->dev, "set vlan filter fail, ret =%d.\n", + dev_err(&hdev->pdev->dev, "failed to set vlan filter, ret = %d.\n", ret); return ret; @@ -7610,7 +7846,7 @@ bool is_kill, u16 vlan, __be16 proto) { -#define HCLGE_MAX_VF_BYTES 16 + struct hclge_vport *vport = &hdev->vport[vfid]; struct hclge_vlan_filter_vf_cfg_cmd *req0; struct hclge_vlan_filter_vf_cfg_cmd *req1; struct hclge_desc desc[2]; @@ -7619,10 +7855,18 @@ int ret; /* if vf vlan table is full, firmware will close vf vlan filter, it - * is unable and unnecessary to add new vlan id to vf vlan filter + * is unable and unnecessary to add new vlan id to vf vlan filter. + * If spoof check is enable, and vf vlan is full, it shouldn't add + * new vlan, because tx packets with these vlan id will be dropped. */ - if (test_bit(vfid, hdev->vf_vlan_full) && !is_kill) + if (test_bit(vfid, hdev->vf_vlan_full) && !is_kill) { + if (vport->vf_info.spoofchk && vlan) { + dev_err(&hdev->pdev->dev, + "Can't add vlan due to spoof check is on and vf vlan table is full\n"); + return -EPERM; + } return 0; + } hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_VLAN_FILTER_VF_CFG, false); @@ -7666,7 +7910,7 @@ } dev_err(&hdev->pdev->dev, - "Add vf vlan filter fail, ret =%d.\n", + "Add vf vlan filter fail, ret =%u.\n", req0->resp_code); } else { #define HCLGE_VF_VLAN_DEL_NO_FOUND 1 @@ -7682,7 +7926,7 @@ return 0; dev_err(&hdev->pdev->dev, - "Kill vf vlan filter fail, ret =%d.\n", + "Kill vf vlan filter fail, ret =%u.\n", req0->resp_code); } @@ -7701,9 +7945,10 @@ hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_PF_CFG, false); - vlan_offset_160 = vlan_id / 160; - vlan_offset_byte = (vlan_id % 160) / 8; - vlan_offset_byte_val = 1 << (vlan_id % 8); + vlan_offset_160 = vlan_id / HCLGE_VLAN_ID_OFFSET_STEP; + vlan_offset_byte = (vlan_id % HCLGE_VLAN_ID_OFFSET_STEP) / + HCLGE_VLAN_BYTE_SIZE; + vlan_offset_byte_val = 1 << (vlan_id % HCLGE_VLAN_BYTE_SIZE); req = (struct hclge_vlan_filter_pf_cfg_cmd *)desc.data; req->vlan_offset = vlan_offset_160; @@ -7731,7 +7976,7 @@ proto); if (ret) { dev_err(&hdev->pdev->dev, - "Set %d vport vlan filter config fail, ret =%d.\n", + "Set %u vport vlan filter config fail, ret =%d.\n", vport_id, ret); return ret; } @@ -7743,7 +7988,7 @@ if (!is_kill && test_and_set_bit(vport_id, hdev->vlan_table[vlan_id])) { dev_err(&hdev->pdev->dev, - "Add port vlan failed, vport %d is already in vlan %d\n", + "Add port vlan failed, vport %u is already in vlan %u\n", vport_id, vlan_id); return -EINVAL; } @@ -7751,7 +7996,7 @@ if (is_kill && !test_and_clear_bit(vport_id, hdev->vlan_table[vlan_id])) { dev_err(&hdev->pdev->dev, - "Delete port vlan failed, vport %d is not in vlan %d\n", + "Delete port vlan failed, vport %u is not in vlan %u\n", vport_id, vlan_id); return -EINVAL; } @@ -7999,7 +8244,11 @@ static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, bool writen_to_tbl) { - struct hclge_vport_vlan_cfg *vlan; + struct hclge_vport_vlan_cfg *vlan, *tmp; + + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) + if (vlan->vlan_id == vlan_id) + return; vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); if (!vlan) @@ -8076,6 +8325,7 @@ kfree(vlan); } } + clear_bit(vport->vport_id, hdev->vf_vlan_full); } void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev) @@ -8084,7 +8334,6 @@ struct hclge_vport *vport; int i; - mutex_lock(&hdev->vport_cfg_mutex); for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { @@ -8092,7 +8341,6 @@ kfree(vlan); } } - mutex_unlock(&hdev->vport_cfg_mutex); } static void hclge_restore_vlan_table(struct hnae3_handle *handle) @@ -8104,7 +8352,6 @@ u16 state, vlan_id; int i; - mutex_lock(&hdev->vport_cfg_mutex); for (i = 0; i < hdev->num_alloc_vport; i++) { vport = &hdev->vport[i]; vlan_proto = vport->port_base_vlan_cfg.vlan_info.vlan_proto; @@ -8119,16 +8366,17 @@ } list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { - if (vlan->hd_tbl_status) - hclge_set_vlan_filter_hw(hdev, - htons(ETH_P_8021Q), - vport->vport_id, - vlan->vlan_id, - false); + int ret; + + if (!vlan->hd_tbl_status) + continue; + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), + vport->vport_id, + vlan->vlan_id, false); + if (ret) + break; } } - - mutex_unlock(&hdev->vport_cfg_mutex); } int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) @@ -8262,13 +8510,16 @@ if (hdev->pdev->revision == 0x20) return -EOPNOTSUPP; + vport = hclge_get_vf_vport(hdev, vfid); + if (!vport) + return -EINVAL; + /* qos is a 3 bits value, so can not be bigger than 7 */ - if (vfid >= hdev->num_alloc_vfs || vlan > VLAN_N_VID - 1 || qos > 7) + if (vlan > VLAN_N_VID - 1 || qos > 7) return -EINVAL; if (proto != htons(ETH_P_8021Q)) return -EPROTONOSUPPORT; - vport = &hdev->vport[vfid]; state = hclge_get_port_base_vlan_state(vport, vport->port_base_vlan_cfg.state, vlan); @@ -8279,27 +8530,40 @@ vlan_info.qos = qos; vlan_info.vlan_proto = ntohs(proto); - /* update port based VLAN for PF */ - if (!vfid) { - hclge_notify_client(hdev, HNAE3_DOWN_CLIENT); - ret = hclge_update_port_base_vlan_cfg(vport, state, &vlan_info); - hclge_notify_client(hdev, HNAE3_UP_CLIENT); - - return ret; - } - if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) { return hclge_update_port_base_vlan_cfg(vport, state, &vlan_info); } else { ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0], - (u8)vfid, state, + vport->vport_id, state, vlan, qos, ntohs(proto)); return ret; } } +static void hclge_clear_vf_vlan(struct hclge_dev *hdev) +{ + struct hclge_vlan_info *vlan_info; + struct hclge_vport *vport; + int ret; + int vf; + + /* clear port base vlan for all vf */ + for (vf = HCLGE_VF_VPORT_START_NUM; vf < hdev->num_alloc_vport; vf++) { + vport = &hdev->vport[vf]; + vlan_info = &vport->port_base_vlan_cfg.vlan_info; + + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), + vport->vport_id, + vlan_info->vlan_tag, true); + if (ret) + dev_err(&hdev->pdev->dev, + "failed to clear vf vlan for vf%d, ret = %d\n", + vf - HCLGE_VF_VPORT_START_NUM, ret); + } +} + int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, u16 vlan_id, bool is_kill) { @@ -8330,11 +8594,11 @@ } if (!ret) { - if (is_kill) - hclge_rm_vport_vlan_table(vport, vlan_id, false); - else + if (!is_kill) hclge_add_vport_vlan_table(vport, vlan_id, writen_to_tbl); + else if (is_kill && vlan_id != 0) + hclge_rm_vport_vlan_table(vport, vlan_id, false); } else if (is_kill) { /* when remove hw vlan filter failed, record the vlan id, * and try to remove it from hw later, to be consistence @@ -8404,6 +8668,7 @@ struct hclge_dev *hdev = vport->back; int i, max_frm_size, ret; + /* HW supprt 2 layer vlan */ max_frm_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + 2 * VLAN_HLEN; if (max_frm_size < HCLGE_MAC_MIN_FRAME || max_frm_size > HCLGE_MAC_MAX_FRAME) @@ -8555,12 +8820,19 @@ void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id) { + struct hnae3_handle *handle = &vport->nic; struct hclge_dev *hdev = vport->back; int reset_try_times = 0; int reset_status; u16 queue_gid; int ret; + if (queue_id >= handle->kinfo.num_tqps) { + dev_warn(&hdev->pdev->dev, "Invalid vf queue id(%u)\n", + queue_id); + return; + } + queue_gid = hclge_covert_handle_qid_global(&vport->nic, queue_id); ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true); @@ -8819,16 +9091,16 @@ dev_info(dev, "PF info begin:\n"); - dev_info(dev, "Task queue pairs numbers: %d\n", hdev->num_tqps); - dev_info(dev, "Desc num per TX queue: %d\n", hdev->num_tx_desc); - dev_info(dev, "Desc num per RX queue: %d\n", hdev->num_rx_desc); - dev_info(dev, "Numbers of vports: %d\n", hdev->num_alloc_vport); - dev_info(dev, "Numbers of vmdp vports: %d\n", hdev->num_vmdq_vport); - dev_info(dev, "Numbers of VF for this PF: %d\n", hdev->num_req_vfs); - dev_info(dev, "HW tc map: %d\n", hdev->hw_tc_map); - dev_info(dev, "Total buffer size for TX/RX: %d\n", hdev->pkt_buf_size); - dev_info(dev, "TX buffer size for each TC: %d\n", hdev->tx_buf_size); - dev_info(dev, "DV buffer size for each TC: %d\n", hdev->dv_buf_size); + dev_info(dev, "Task queue pairs numbers: %u\n", hdev->num_tqps); + dev_info(dev, "Desc num per TX queue: %u\n", hdev->num_tx_desc); + dev_info(dev, "Desc num per RX queue: %u\n", hdev->num_rx_desc); + dev_info(dev, "Numbers of vports: %u\n", hdev->num_alloc_vport); + dev_info(dev, "Numbers of vmdp vports: %u\n", hdev->num_vmdq_vport); + dev_info(dev, "Numbers of VF for this PF: %u\n", hdev->num_req_vfs); + dev_info(dev, "HW tc map: 0x%x\n", hdev->hw_tc_map); + dev_info(dev, "Total buffer size for TX/RX: %u\n", hdev->pkt_buf_size); + dev_info(dev, "TX buffer size for each TC: %u\n", hdev->tx_buf_size); + dev_info(dev, "DV buffer size for each TC: %u\n", hdev->dv_buf_size); dev_info(dev, "This is %s PF\n", hdev->flag & HCLGE_FLAG_MAIN ? "main" : "not main"); dev_info(dev, "DCB %s\n", @@ -8844,10 +9116,9 @@ { struct hnae3_client *client = vport->nic.client; struct hclge_dev *hdev = ae_dev->priv; - int rst_cnt; + int rst_cnt = hdev->rst_stats.reset_cnt; int ret; - rst_cnt = hdev->rst_stats.reset_cnt; ret = client->ops->init_instance(&vport->nic); if (ret) return ret; @@ -8947,7 +9218,6 @@ switch (client->type) { case HNAE3_CLIENT_KNIC: - hdev->nic_client = client; vport->nic.client = client; ret = hclge_init_nic_client_instance(ae_dev, vport); @@ -9087,6 +9357,7 @@ set_bit(HCLGE_STATE_DOWN, &hdev->state); clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state); clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); + clear_bit(HCLGE_STATE_RST_FAIL, &hdev->state); clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state); clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); } @@ -9100,38 +9371,57 @@ del_timer_sync(&hdev->reset_timer); if (hdev->service_task.work.func) cancel_delayed_work_sync(&hdev->service_task); - if (hdev->rst_service_task.func) - cancel_work_sync(&hdev->rst_service_task); - if (hdev->mbx_service_task.func) - cancel_work_sync(&hdev->mbx_service_task); } static void hclge_flr_prepare(struct hnae3_ae_dev *ae_dev) { -#define HCLGE_FLR_WAIT_MS 100 -#define HCLGE_FLR_WAIT_CNT 50 - struct hclge_dev *hdev = ae_dev->priv; - int cnt = 0; +#define HCLGE_FLR_RETRY_WAIT_MS 500 +#define HCLGE_FLR_RETRY_CNT 5 - clear_bit(HNAE3_FLR_DOWN, &hdev->flr_state); - clear_bit(HNAE3_FLR_DONE, &hdev->flr_state); - set_bit(HNAE3_FLR_RESET, &hdev->default_reset_request); - hclge_reset_event(hdev->pdev, NULL); + struct hclge_dev *hdev = ae_dev->priv; + int retry_cnt = 0; + int ret; - while (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state) && - cnt++ < HCLGE_FLR_WAIT_CNT) - msleep(HCLGE_FLR_WAIT_MS); +retry: + down(&hdev->reset_sem); + set_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); + hdev->reset_type = HNAE3_FLR_RESET; + ret = hclge_reset_prepare(hdev); + if (ret) { + dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n", + ret); + if (hdev->reset_pending || + retry_cnt++ < HCLGE_FLR_RETRY_CNT) { + dev_err(&hdev->pdev->dev, + "reset_pending:0x%lx, retry_cnt:%d\n", + hdev->reset_pending, retry_cnt); + clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); + up(&hdev->reset_sem); + msleep(HCLGE_FLR_RETRY_WAIT_MS); + goto retry; + } + } - if (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state)) - dev_err(&hdev->pdev->dev, - "flr wait down timeout: %d\n", cnt); + /* disable misc vector before FLR done */ + hclge_enable_vector(&hdev->misc_vector, false); + set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state); + hdev->rst_stats.flr_rst_cnt++; } static void hclge_flr_done(struct hnae3_ae_dev *ae_dev) { struct hclge_dev *hdev = ae_dev->priv; + int ret; - set_bit(HNAE3_FLR_DONE, &hdev->flr_state); + hclge_enable_vector(&hdev->misc_vector, true); + + ret = hclge_reset_rebuild(hdev); + if (ret) + dev_err(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", ret); + + hdev->reset_type = HNAE3_NONE_RESET; + clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); + up(&hdev->reset_sem); } static void hclge_clear_resetting_state(struct hclge_dev *hdev) @@ -9146,11 +9436,33 @@ ret = hclge_set_vf_rst(hdev, vport->vport_id, false); if (ret) dev_warn(&hdev->pdev->dev, - "clear vf(%d) rst failed %d!\n", + "clear vf(%u) rst failed %d!\n", vport->vport_id, ret); } } +static int hclge_clear_hw_resource(struct hclge_dev *hdev) +{ + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CLEAR_HW_RESOURCE, false); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + /* This new command is only supported by new firmware, it will + * fail with older firmware. Error value -EOPNOSUPP can only be + * returned by older firmware running this command, to keep code + * backward compatible we will override this value and return + * success. + */ + if (ret && ret != -EOPNOTSUPP) { + dev_err(&hdev->pdev->dev, + "failed to clear hw resource, ret = %d\n", ret); + return ret; + } + return 0; +} + static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) { struct pci_dev *pdev = ae_dev->pdev; @@ -9168,11 +9480,13 @@ hdev->reset_type = HNAE3_NONE_RESET; hdev->reset_level = HNAE3_FUNC_RESET; ae_dev->priv = hdev; + + /* HW supprt 2 layer vlan */ hdev->mps = ETH_FRAME_LEN + ETH_FCS_LEN + 2 * VLAN_HLEN; mutex_init(&hdev->vport_lock); - mutex_init(&hdev->vport_cfg_mutex); spin_lock_init(&hdev->fd_rule_lock); + sema_init(&hdev->reset_sem, 1); ret = hclge_pci_init(hdev); if (ret) { @@ -9192,6 +9506,10 @@ if (ret) goto err_cmd_uninit; + ret = hclge_clear_hw_resource(hdev); + if (ret) + goto err_cmd_uninit; + ret = hclge_get_cap(hdev); if (ret) { dev_err(&pdev->dev, "get hw capability error, ret = %d.\n", @@ -9306,8 +9624,6 @@ timer_setup(&hdev->reset_timer, hclge_reset_timer, 0); INIT_DELAYED_WORK(&hdev->service_task, hclge_service_task); - INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task); - INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task); /* Setup affinity after service timer setup because add_timer_on * is called in affinity notify. @@ -9341,6 +9657,8 @@ dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", HCLGE_DRIVER_NAME); + hclge_task_schedule(hdev, round_jiffies_relative(HZ)); + return 0; err_mdiobus_unreg: @@ -9363,7 +9681,220 @@ static void hclge_stats_clear(struct hclge_dev *hdev) { - memset(&hdev->hw_stats, 0, sizeof(hdev->hw_stats)); + memset(&hdev->mac_stats, 0, sizeof(hdev->mac_stats)); +} + +static int hclge_set_mac_spoofchk(struct hclge_dev *hdev, int vf, bool enable) +{ + return hclge_config_switch_param(hdev, vf, enable, + HCLGE_SWITCH_ANTI_SPOOF_MASK); +} + +static int hclge_set_vlan_spoofchk(struct hclge_dev *hdev, int vf, bool enable) +{ + return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, + HCLGE_FILTER_FE_NIC_INGRESS_B, + enable, vf); +} + +static int hclge_set_vf_spoofchk_hw(struct hclge_dev *hdev, int vf, bool enable) +{ + int ret; + + ret = hclge_set_mac_spoofchk(hdev, vf, enable); + if (ret) { + dev_err(&hdev->pdev->dev, + "Set vf %d mac spoof check %s failed, ret=%d\n", + vf, enable ? "on" : "off", ret); + return ret; + } + + ret = hclge_set_vlan_spoofchk(hdev, vf, enable); + if (ret) + dev_err(&hdev->pdev->dev, + "Set vf %d vlan spoof check %s failed, ret=%d\n", + vf, enable ? "on" : "off", ret); + + return ret; +} + +static int hclge_set_vf_spoofchk(struct hnae3_handle *handle, int vf, + bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + u32 new_spoofchk = enable ? 1 : 0; + int ret; + + if (hdev->pdev->revision == 0x20) + return -EOPNOTSUPP; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + if (vport->vf_info.spoofchk == new_spoofchk) + return 0; + + if (enable && test_bit(vport->vport_id, hdev->vf_vlan_full)) + dev_warn(&hdev->pdev->dev, + "vf %d vlan table is full, enable spoof check may cause its packet send fail\n", + vf); + else if (enable && hclge_is_umv_space_full(vport)) + dev_warn(&hdev->pdev->dev, + "vf %d mac table is full, enable spoof check may cause its packet send fail\n", + vf); + + ret = hclge_set_vf_spoofchk_hw(hdev, vport->vport_id, enable); + if (ret) + return ret; + + vport->vf_info.spoofchk = new_spoofchk; + return 0; +} + +static int hclge_reset_vport_spoofchk(struct hclge_dev *hdev) +{ + struct hclge_vport *vport = hdev->vport; + int ret; + int i; + + if (hdev->pdev->revision == 0x20) + return 0; + + /* resume the vf spoof check state after reset */ + for (i = 0; i < hdev->num_alloc_vport; i++) { + ret = hclge_set_vf_spoofchk_hw(hdev, vport->vport_id, + vport->vf_info.spoofchk); + if (ret) + return ret; + + vport++; + } + + return 0; +} + +static int hclge_set_vf_trust(struct hnae3_handle *handle, int vf, bool enable) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + u32 new_trusted = enable ? 1 : 0; + bool en_bc_pmc; + int ret; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + if (vport->vf_info.trusted == new_trusted) + return 0; + + /* Disable promisc mode for VF if it is not trusted any more. */ + if (!enable && vport->vf_info.promisc_enable) { + en_bc_pmc = hdev->pdev->revision != 0x20; + ret = hclge_set_vport_promisc_mode(vport, false, false, + en_bc_pmc); + if (ret) + return ret; + vport->vf_info.promisc_enable = 0; + hclge_inform_vf_promisc_info(vport); + } + + vport->vf_info.trusted = new_trusted; + + return 0; +} + +static void hclge_reset_vf_rate(struct hclge_dev *hdev) +{ + int ret; + int vf; + + /* reset vf rate to default value */ + for (vf = HCLGE_VF_VPORT_START_NUM; vf < hdev->num_alloc_vport; vf++) { + struct hclge_vport *vport = &hdev->vport[vf]; + + vport->vf_info.max_tx_rate = 0; + ret = hclge_tm_qs_shaper_cfg(vport, vport->vf_info.max_tx_rate); + if (ret) + dev_err(&hdev->pdev->dev, + "vf%d failed to reset to default, ret=%d\n", + vf - HCLGE_VF_VPORT_START_NUM, ret); + } +} + +static int hclge_vf_rate_param_check(struct hclge_dev *hdev, int vf, + int min_tx_rate, int max_tx_rate) +{ + if (min_tx_rate != 0 || + max_tx_rate < 0 || max_tx_rate > hdev->hw.mac.max_speed) { + dev_err(&hdev->pdev->dev, + "min_tx_rate:%d [0], max_tx_rate:%d [0, %u]\n", + min_tx_rate, max_tx_rate, hdev->hw.mac.max_speed); + return -EINVAL; + } + + return 0; +} + +static int hclge_set_vf_rate(struct hnae3_handle *handle, int vf, + int min_tx_rate, int max_tx_rate, bool force) +{ + struct hclge_vport *vport = hclge_get_vport(handle); + struct hclge_dev *hdev = vport->back; + int ret; + + ret = hclge_vf_rate_param_check(hdev, vf, min_tx_rate, max_tx_rate); + if (ret) + return ret; + + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + if (!force && max_tx_rate == vport->vf_info.max_tx_rate) + return 0; + + ret = hclge_tm_qs_shaper_cfg(vport, max_tx_rate); + if (ret) + return ret; + + vport->vf_info.max_tx_rate = max_tx_rate; + + return 0; +} + +static int hclge_resume_vf_rate(struct hclge_dev *hdev) +{ + struct hnae3_handle *handle = &hdev->vport->nic; + struct hclge_vport *vport; + int ret; + int vf; + + /* resume the vf max_tx_rate after reset */ + for (vf = 0; vf < pci_num_vf(hdev->pdev); vf++) { + vport = hclge_get_vf_vport(hdev, vf); + if (!vport) + return -EINVAL; + + /* zero means max rate, after reset, firmware already set it to + * max rate, so just continue. + */ + if (!vport->vf_info.max_tx_rate) + continue; + + ret = hclge_set_vf_rate(handle, vf, 0, + vport->vf_info.max_tx_rate, true); + if (ret) { + dev_err(&hdev->pdev->dev, + "vf%d failed to resume tx_rate:%u, ret=%d\n", + vf, vport->vf_info.max_tx_rate, ret); + return ret; + } + } + + return 0; } static void hclge_reset_vport_state(struct hclge_dev *hdev) @@ -9437,12 +9968,22 @@ return ret; } + ret = init_mgr_tbl(hdev); + if (ret) { + dev_err(&pdev->dev, + "failed to reinit manager table, ret = %d\n", ret); + return ret; + } + ret = hclge_init_fd_config(hdev); if (ret) { dev_err(&pdev->dev, "fd table init fail, ret=%d\n", ret); return ret; } + /* Log and clear the hw errors those already occurred */ + hclge_handle_all_hns_hw_errors(ae_dev); + /* Re-enable the hw error interrupts because * the interrupts get disabled on global reset. */ @@ -9465,6 +10006,13 @@ } hclge_reset_vport_state(hdev); + ret = hclge_reset_vport_spoofchk(hdev); + if (ret) + return ret; + + ret = hclge_resume_vf_rate(hdev); + if (ret) + return ret; dev_info(&pdev->dev, "Reset done, %s driver initialization finished.\n", HCLGE_DRIVER_NAME); @@ -9477,6 +10025,8 @@ struct hclge_dev *hdev = ae_dev->priv; struct hclge_mac *mac = &hdev->hw.mac; + hclge_reset_vf_rate(hdev); + hclge_clear_vf_vlan(hdev); hclge_misc_affinity_teardown(hdev); hclge_state_uninit(hdev); @@ -9500,7 +10050,6 @@ mutex_destroy(&hdev->vport_lock); hclge_uninit_vport_mac_table(hdev); hclge_uninit_vport_vlan_table(hdev); - mutex_destroy(&hdev->vport_cfg_mutex); ae_dev->priv = NULL; } @@ -9541,8 +10090,8 @@ u16 tc_offset[HCLGE_MAX_TC_NUM] = {0}; struct hclge_dev *hdev = vport->back; u16 tc_size[HCLGE_MAX_TC_NUM] = {0}; - int cur_rss_size = kinfo->rss_size; - int cur_tqps = kinfo->num_tqps; + u16 cur_rss_size = kinfo->rss_size; + u16 cur_tqps = kinfo->num_tqps; u16 tc_valid[HCLGE_MAX_TC_NUM]; u16 roundup_size; u32 *rss_indir; @@ -9596,7 +10145,7 @@ out: if (!ret) dev_info(&hdev->pdev->dev, - "Channels changed, rss_size from %d to %d, tqps from %d to %d", + "Channels changed, rss_size from %u to %u, tqps from %u to %u", cur_rss_size, kinfo->rss_size, cur_tqps, kinfo->rss_size * kinfo->num_tc); @@ -9762,10 +10311,8 @@ int *bd_num_list, u32 type_num) { -#define HCLGE_DFX_REG_BD_NUM 4 - u32 entries_per_desc, desc_index, index, offset, i; - struct hclge_desc desc[HCLGE_DFX_REG_BD_NUM]; + struct hclge_desc desc[HCLGE_GET_DFX_REG_TYPE_CNT]; int ret; ret = hclge_query_bd_num_cmd_send(hdev, desc); @@ -9834,8 +10381,9 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len) { u32 dfx_reg_type_num = ARRAY_SIZE(hclge_dfx_bd_offset_list); - int data_len_per_desc, data_len, bd_num, i; + int data_len_per_desc, bd_num, i; int bd_num_list[BD_LIST_MAX_NUM]; + u32 data_len; int ret; ret = hclge_get_dfx_reg_bd_num(hdev, bd_num_list, dfx_reg_type_num); @@ -9878,10 +10426,8 @@ buf_len = sizeof(*desc_src) * bd_num_max; desc_src = kzalloc(buf_len, GFP_KERNEL); - if (!desc_src) { - dev_err(&hdev->pdev->dev, "%s kzalloc failed\n", __func__); + if (!desc_src) return -ENOMEM; - } for (i = 0; i < dfx_reg_type_num; i++) { bd_num = bd_num_list[i]; @@ -10199,6 +10745,12 @@ .mac_connect_phy = hclge_mac_connect_phy, .mac_disconnect_phy = hclge_mac_disconnect_phy, .restore_vlan_table = hclge_restore_vlan_table, + .get_vf_config = hclge_get_vf_config, + .set_vf_link_state = hclge_set_vf_link_state, + .set_vf_spoofchk = hclge_set_vf_spoofchk, + .set_vf_trust = hclge_set_vf_trust, + .set_vf_rate = hclge_set_vf_rate, + .set_vf_mac = hclge_set_vf_mac, }; static struct hnae3_ae_algo ae_algo = { @@ -10210,6 +10762,12 @@ { pr_info("%s is initializing\n", HCLGE_NAME); + hclge_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGE_NAME); + if (!hclge_wq) { + pr_err("%s: failed to create workqueue\n", HCLGE_NAME); + return -ENOMEM; + } + hnae3_register_ae_algo(&ae_algo); return 0; @@ -10217,7 +10775,9 @@ static void hclge_exit(void) { + hnae3_unregister_ae_algo_prepare(&ae_algo); hnae3_unregister_ae_algo(&ae_algo); + destroy_workqueue(hclge_wq); } module_init(hclge_init); module_exit(hclge_exit); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -139,9 +139,10 @@ #define HCLGE_PHY_MDIX_STATUS_B 6 #define HCLGE_PHY_SPEED_DUP_RESOLVE_B 11 +#define HCLGE_GET_DFX_REG_TYPE_CNT 4 + /* Factor used to calculate offset and bitmap of VF num */ #define HCLGE_VF_NUM_PER_CMD 64 -#define HCLGE_VF_NUM_PER_BYTE 8 enum HLCGE_PORT_TYPE { HOST_PORT, @@ -209,13 +210,14 @@ HCLGE_STATE_NIC_REGISTERED, HCLGE_STATE_ROCE_REGISTERED, HCLGE_STATE_SERVICE_INITED, - HCLGE_STATE_SERVICE_SCHED, HCLGE_STATE_RST_SERVICE_SCHED, HCLGE_STATE_RST_HANDLING, HCLGE_STATE_MBX_SERVICE_SCHED, HCLGE_STATE_MBX_HANDLING, HCLGE_STATE_STATISTICS_UPDATING, HCLGE_STATE_CMD_DISABLE, + HCLGE_STATE_LINK_UPDATING, + HCLGE_STATE_RST_FAIL, HCLGE_STATE_MAX }; @@ -226,8 +228,6 @@ HCLGE_VECTOR0_EVENT_OTHER, }; -#define HCLGE_MPF_ENBALE 1 - enum HCLGE_MAC_SPEED { HCLGE_MAC_SPEED_UNKNOWN = 0, /* unknown */ HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */ @@ -249,6 +249,7 @@ #define QUERY_ACTIVE_SPEED 1 struct hclge_mac { + u8 mac_id; u8 phy_addr; u8 flag; u8 media_type; /* port media type, e.g. fibre/copper/backplane */ @@ -258,6 +259,7 @@ u8 support_autoneg; u8 speed_type; /* 0: sfp speed, 1: active speed */ u32 speed; + u32 max_speed; u32 speed_ability; /* speed ability supported by current media */ u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */ u32 fec_mode; /* active fec mode */ @@ -456,11 +458,7 @@ u64 mac_rx_ctrl_pkt_num; }; -#define HCLGE_STATS_TIMER_INTERVAL (60 * 5) -struct hclge_hw_stats { - struct hclge_mac_stats mac_stats; - u32 stats_timer; -}; +#define HCLGE_STATS_TIMER_INTERVAL 300UL struct hclge_vlan_type_cfg { u16 rx_ot_fst_vlan_type; @@ -551,7 +549,7 @@ /* assigned by firmware, the real filter number for each pf may be less */ #define MAX_FD_FILTER_NUM 4096 -#define HCLGE_FD_ARFS_EXPIRE_TIMER_INTERVAL 5 +#define HCLGE_ARFS_EXPIRE_INTERVAL 5UL enum HCLGE_FD_ACTIVE_RULE_TYPE { HCLGE_FD_RULE_NONE, @@ -655,7 +653,6 @@ u32 hw_reset_done_cnt; /* the number of HW reset has completed */ u32 pf_rst_cnt; /* the number of PF reset */ u32 flr_rst_cnt; /* the number of FLR */ - u32 core_rst_cnt; /* the number of CORE reset */ u32 global_rst_cnt; /* the number of GLOBAL */ u32 imp_rst_cnt; /* the number of IMP reset */ u32 reset_cnt; /* the number of reset */ @@ -715,7 +712,7 @@ struct hnae3_ae_dev *ae_dev; struct hclge_hw hw; struct hclge_misc_vector misc_vector; - struct hclge_hw_stats hw_stats; + struct hclge_mac_stats mac_stats; unsigned long state; unsigned long flr_state; unsigned long last_reset_time; @@ -726,6 +723,7 @@ unsigned long reset_request; /* reset has been requested */ unsigned long reset_pending; /* client rst is pending to be served */ struct hclge_rst_stats rst_stats; + struct semaphore reset_sem; /* protect reset process */ u32 fw_version; u16 num_vmdq_vport; /* Num vmdq vport this PF has set up */ u16 num_tqps; /* Num task queue pairs of this PF */ @@ -777,8 +775,6 @@ unsigned long service_timer_previous; struct timer_list reset_timer; struct delayed_work service_task; - struct work_struct rst_service_task; - struct work_struct mbx_service_task; bool cur_promisc; int num_alloc_vfs; /* Actual number of VFs allocated */ @@ -814,7 +810,8 @@ struct hlist_head fd_rule_list; spinlock_t fd_rule_lock; /* protect fd_rule_list and fd_bmap */ u16 hclge_fd_rule_num; - u16 fd_arfs_expire_timer; + unsigned long serv_processed_cnt; + unsigned long last_serv_processed; unsigned long fd_bmap[BITS_TO_LONGS(MAX_FD_FILTER_NUM)]; enum HCLGE_FD_ACTIVE_RULE_TYPE fd_active_type; u8 fd_en; @@ -828,8 +825,6 @@ u16 share_umv_size; struct mutex umv_mutex; /* protect share_umv_size */ - struct mutex vport_cfg_mutex; /* Protect stored vf table */ - DECLARE_KFIFO(mac_tnl_log, struct hclge_mac_tnl_stats, HCLGE_MAC_TNL_LOG_SIZE); @@ -886,6 +881,15 @@ struct hclge_vlan_info vlan_info; }; +struct hclge_vf_info { + int link_state; + u8 mac[ETH_ALEN]; + u32 spoofchk; + u32 max_tx_rate; + u32 trusted; + u16 promisc_enable; +}; + struct hclge_vport { u16 alloc_tqps; /* Allocated Tx/Rx queues */ @@ -917,15 +921,15 @@ unsigned long state; unsigned long last_active_jiffies; u32 mps; /* Max packet size */ + struct hclge_vf_info vf_info; struct list_head uc_mac_list; /* Store VF unicast table */ struct list_head mc_mac_list; /* Store VF multicast table */ struct list_head vlan_list; /* Store VF vlan table */ }; -void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc, - bool en_mc, bool en_bc, int vport_id); - +int hclge_set_vport_promisc_mode(struct hclge_vport *vport, bool en_uc_pmc, + bool en_mc_pmc, bool en_bc_pmc); int hclge_add_uc_addr_common(struct hclge_vport *vport, const unsigned char *addr); int hclge_rm_uc_addr_common(struct hclge_vport *vport, @@ -994,4 +998,6 @@ struct hclge_desc *desc); void hclge_report_hw_error(struct hclge_dev *hdev, enum hnae3_hw_error_type type); +void hclge_inform_vf_promisc_info(struct hclge_vport *vport); +void hclge_dbg_dump_rst_info(struct hclge_dev *hdev); #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -26,7 +26,7 @@ if (resp_data_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { dev_err(&hdev->pdev->dev, - "PF fail to gen resp to VF len %d exceeds max len %d\n", + "PF fail to gen resp to VF len %u exceeds max len %u\n", resp_data_len, HCLGE_MBX_MAX_RESP_DATA_SIZE); /* If resp_data_len is too long, set the value to max length @@ -64,6 +64,13 @@ enum hclge_cmd_status status; struct hclge_desc desc; + if (msg_len > HCLGE_MBX_MAX_MSG_SIZE) { + dev_err(&hdev->pdev->dev, + "msg data length(=%u) exceeds maximum(=%u)\n", + msg_len, HCLGE_MBX_MAX_MSG_SIZE); + return -EMSGSIZE; + } + resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); @@ -86,10 +93,12 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) { struct hclge_dev *hdev = vport->back; - enum hnae3_reset_type reset_type; + u16 reset_type; u8 msg_data[2]; u8 dest_vfid; + BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX); + dest_vfid = (u8)vport->vport_id; if (hdev->reset_type == HNAE3_FUNC_RESET) @@ -205,12 +214,38 @@ static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *req) { - bool en_bc = req->msg[1] ? true : false; - struct hclge_promisc_param param; +#define HCLGE_MBX_BC_INDEX 1 +#define HCLGE_MBX_UC_INDEX 2 +#define HCLGE_MBX_MC_INDEX 3 + + bool en_bc = req->msg[HCLGE_MBX_BC_INDEX] ? true : false; + bool en_uc = req->msg[HCLGE_MBX_UC_INDEX] ? true : false; + bool en_mc = req->msg[HCLGE_MBX_MC_INDEX] ? true : false; + int ret; + + if (!vport->vf_info.trusted) { + en_uc = false; + en_mc = false; + } + + ret = hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc); + if (req->mbx_need_resp) + hclge_gen_resp_to_vf(vport, req, ret, NULL, 0); + + vport->vf_info.promisc_enable = (en_uc || en_mc) ? 1 : 0; + + return ret; +} + +void hclge_inform_vf_promisc_info(struct hclge_vport *vport) +{ + u8 dest_vfid = (u8)vport->vport_id; + u8 msg_data[2]; - /* vf is not allowed to enable unicast/multicast broadcast */ - hclge_promisc_param_init(¶m, false, false, en_bc, vport->vport_id); - return hclge_cmd_set_promisc_mode(vport->back, ¶m); + memcpy(&msg_data[0], &vport->vf_info.promisc_enable, sizeof(u16)); + + hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), + HCLGE_MBX_PUSH_PROMISC_INFO, dest_vfid); } static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, @@ -223,6 +258,20 @@ if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]); + /* If VF MAC has been configured by the host then it + * cannot be overridden by the MAC specified by the VM. + */ + if (!is_zero_ether_addr(vport->vf_info.mac) && + !ether_addr_equal(mac_addr, vport->vf_info.mac)) { + status = -EPERM; + goto out; + } + + if (!is_valid_ether_addr(mac_addr)) { + status = -EINVAL; + goto out; + } + hclge_rm_uc_addr_common(vport, old_addr); status = hclge_add_uc_addr_common(vport, mac_addr); if (status) { @@ -245,11 +294,12 @@ false, HCLGE_MAC_ADDR_UC); } else { dev_err(&hdev->pdev->dev, - "failed to set unicast mac addr, unknown subcode %d\n", + "failed to set unicast mac addr, unknown subcode %u\n", mbx_req->msg[1]); return -EIO; } +out: if (mbx_req->mbx_need_resp & HCLGE_MBX_NEED_RESP_BIT) hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); @@ -278,7 +328,7 @@ false, HCLGE_MAC_ADDR_MC); } else { dev_err(&hdev->pdev->dev, - "failed to set mcast mac addr, unknown subcode %d\n", + "failed to set mcast mac addr, unknown subcode %u\n", mbx_req->msg[1]); return -EIO; } @@ -324,6 +374,9 @@ proto = msg_cmd->proto; status = hclge_set_vlan_filter(handle, cpu_to_be16(proto), vlan, is_kill); + if (mbx_req->mbx_need_resp) + return hclge_gen_resp_to_vf(vport, mbx_req, status, + NULL, 0); } else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) { struct hnae3_handle *handle = &vport->nic; bool en = msg_cmd->is_kill ? true : false; @@ -398,6 +451,13 @@ HCLGE_TQPS_RSS_INFO_LEN); } +static int hclge_get_vf_mac_addr(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req) +{ + return hclge_gen_resp_to_vf(vport, mbx_req, 0, vport->vf_info.mac, + ETH_ALEN); +} + static int hclge_get_vf_queue_depth(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *mbx_req, bool gen_resp) @@ -428,6 +488,9 @@ static int hclge_get_link_info(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *mbx_req) { +#define HCLGE_VF_LINK_STATE_UP 1U +#define HCLGE_VF_LINK_STATE_DOWN 0U + struct hclge_dev *hdev = vport->back; u16 link_status; u8 msg_data[8]; @@ -435,7 +498,19 @@ u16 duplex; /* mac.link can only be 0 or 1 */ - link_status = (u16)hdev->hw.mac.link; + switch (vport->vf_info.link_state) { + case IFLA_VF_LINK_STATE_ENABLE: + link_status = HCLGE_VF_LINK_STATE_UP; + break; + case IFLA_VF_LINK_STATE_DISABLE: + link_status = HCLGE_VF_LINK_STATE_DOWN; + break; + case IFLA_VF_LINK_STATE_AUTO: + default: + link_status = (u16)hdev->hw.mac.link; + break; + } + duplex = hdev->hw.mac.duplex; memcpy(&msg_data[0], &link_status, sizeof(u16)); memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32)); @@ -455,7 +530,7 @@ unsigned long advertising; unsigned long supported; unsigned long send_data; - u8 msg_data[10]; + u8 msg_data[10] = {}; u8 dest_vfid; advertising = hdev->hw.mac.advertising[0]; @@ -489,7 +564,7 @@ struct hclge_dev *hdev = vport->back; int ret; - dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %d!", + dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %u!", vport->vport_id); ret = hclge_func_reset_cmd(hdev, vport->vport_id); @@ -524,7 +599,8 @@ qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); memcpy(resp_data, &qid_in_pf, sizeof(qid_in_pf)); - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, 2); + return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, + sizeof(resp_data)); } static int hclge_get_rss_key(struct hclge_vport *vport, @@ -568,7 +644,6 @@ #define LINK_STATUS_OFFSET 1 #define LINK_FAIL_CODE_OFFSET 2 - clear_bit(HCLGE_STATE_SERVICE_SCHED, &hdev->state); hclge_task_schedule(hdev, 0); if (!req->msg[LINK_STATUS_OFFSET]) @@ -614,7 +689,7 @@ flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) { dev_warn(&hdev->pdev->dev, - "dropped invalid mailbox message, code = %d\n", + "dropped invalid mailbox message, code = %u\n", req->msg[0]); /* dropping/not processing this invalid message */ @@ -731,13 +806,12 @@ hclge_get_link_mode(vport, req); break; case HCLGE_MBX_GET_VF_FLR_STATUS: - mutex_lock(&hdev->vport_cfg_mutex); + case HCLGE_MBX_VF_UNINIT: hclge_rm_vport_all_mac_table(vport, true, HCLGE_MAC_ADDR_UC); hclge_rm_vport_all_mac_table(vport, true, HCLGE_MAC_ADDR_MC); hclge_rm_vport_all_vlan_table(vport, true); - mutex_unlock(&hdev->vport_cfg_mutex); break; case HCLGE_MBX_GET_MEDIA_TYPE: ret = hclge_get_vf_media_type(vport, req); @@ -749,12 +823,19 @@ case HCLGE_MBX_PUSH_LINK_STATUS: hclge_handle_link_change_event(hdev, req); break; + case HCLGE_MBX_GET_MAC_ADDR: + ret = hclge_get_vf_mac_addr(vport, req); + if (ret) + dev_err(&hdev->pdev->dev, + "PF failed(%d) to get MAC for VF\n", + ret); + break; case HCLGE_MBX_NCSI_ERROR: hclge_handle_ncsi_error(hdev); break; default: dev_err(&hdev->pdev->dev, - "un-supported mailbox message, code = %d\n", + "un-supported mailbox message, code = %u\n", req->msg[0]); break; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c @@ -134,7 +134,7 @@ "no phy device is connected to mdio bus\n"); return 0; } else if (hdev->hw.mac.phy_addr >= PHY_MAX_ADDR) { - dev_err(&hdev->pdev->dev, "phy_addr(%d) is too large.\n", + dev_err(&hdev->pdev->dev, "phy_addr(%u) is too large.\n", hdev->hw.mac.phy_addr); return -EINVAL; } @@ -255,6 +255,8 @@ if (!phydev) return; + phy_loopback(phydev, false); + phy_start(phydev); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -46,7 +46,7 @@ #define DIVISOR_CLK (1000 * 8) #define DIVISOR_IR_B_126 (126 * DIVISOR_CLK) - const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = { + static const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = { 6 * 256, /* Prioriy level */ 6 * 32, /* Prioriy group level */ 6 * 8, /* Port level */ @@ -170,8 +170,8 @@ return hclge_cmd_send(&hdev->hw, &desc, 1); } -static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, - u8 pfc_bitmap) +int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, + u8 pfc_bitmap) { struct hclge_desc desc; struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data; @@ -511,6 +511,49 @@ return hclge_cmd_send(&hdev->hw, &desc, 1); } +int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate) +{ + struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; + struct hclge_qs_shapping_cmd *shap_cfg_cmd; + struct hclge_dev *hdev = vport->back; + struct hclge_desc desc; + u8 ir_b, ir_u, ir_s; + u32 shaper_para; + int ret, i; + + if (!max_tx_rate) + max_tx_rate = HCLGE_ETHER_MAX_RATE; + + ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET, + &ir_b, &ir_u, &ir_s); + if (ret) + return ret; + + shaper_para = hclge_tm_get_shapping_para(ir_b, ir_u, ir_s, + HCLGE_SHAPER_BS_U_DEF, + HCLGE_SHAPER_BS_S_DEF); + + for (i = 0; i < kinfo->num_tc; i++) { + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, + false); + + shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data; + shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i); + shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "vf%u, qs%u failed to set tx_rate:%d, ret=%d\n", + vport->vport_id, shap_cfg_cmd->qs_id, + max_tx_rate, ret); + return ret; + } + } + + return 0; +} + static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) { struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; @@ -523,7 +566,7 @@ */ kinfo->num_tc = vport->vport_id ? 1 : min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); - vport->qs_offset = (vport->vport_id ? hdev->tm_info.num_tc : 0) + + vport->qs_offset = (vport->vport_id ? HNAE3_MAX_TC : 0) + (vport->vport_id ? (vport->vport_id - 1) : 0); max_rss_size = min_t(u16, hdev->rss_size_max, @@ -532,7 +575,7 @@ /* Set to user value, no larger than max_rss_size. */ if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size && kinfo->req_rss_size <= max_rss_size) { - dev_info(&hdev->pdev->dev, "rss changes from %d to %d\n", + dev_info(&hdev->pdev->dev, "rss changes from %u to %u\n", kinfo->rss_size, kinfo->req_rss_size); kinfo->rss_size = kinfo->req_rss_size; } else if (kinfo->rss_size > max_rss_size || @@ -633,6 +676,8 @@ hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map; for (k = 0; k < hdev->tm_info.num_tc; k++) hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT; + for (; k < HNAE3_MAX_TC; k++) + hdev->tm_info.pg_info[i].tc_dwrr[k] = 0; } } @@ -972,7 +1017,6 @@ static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) { -#define DEFAULT_TC_WEIGHT 1 #define DEFAULT_TC_OFFSET 14 struct hclge_ets_tc_weight_cmd *ets_weight; @@ -985,13 +1029,7 @@ for (i = 0; i < HNAE3_MAX_TC; i++) { struct hclge_pg_info *pg_info; - ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT; - - if (!(hdev->hw_tc_map & BIT(i))) - continue; - - pg_info = - &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; + pg_info = &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; ets_weight->tc_weight[i] = pg_info->tc_dwrr[i]; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -96,6 +96,12 @@ __le32 pg_shapping_para; }; +struct hclge_qs_shapping_cmd { + __le16 qs_id; + u8 rsvd[2]; + __le32 qs_shapping_para; +}; + #define HCLGE_BP_GRP_NUM 32 #define HCLGE_BP_SUB_GRP_ID_S 0 #define HCLGE_BP_SUB_GRP_ID_M GENMASK(4, 0) @@ -109,6 +115,9 @@ u32 rsvd1; }; +#define HCLGE_PFC_DISABLE 0 +#define HCLGE_PFC_TX_RX_DISABLE 0 + struct hclge_pfc_en_cmd { u8 tx_rx_en_bitmap; u8 pri_en_bitmap; @@ -150,8 +159,12 @@ void hclge_tm_pfc_info_update(struct hclge_dev *hdev); int hclge_tm_dwrr_cfg(struct hclge_dev *hdev); int hclge_tm_init_hw(struct hclge_dev *hdev, bool init); +int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, + u8 pfc_bitmap); int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); +int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); + #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c @@ -50,7 +50,7 @@ rmb(); /* Make sure head is ready before touch any data */ if (!hclgevf_is_valid_csq_clean_head(csq, head)) { - dev_warn(&hdev->pdev->dev, "wrong cmd head (%d, %d-%d)\n", head, + dev_warn(&hdev->pdev->dev, "wrong cmd head (%u, %d-%d)\n", head, csq->next_to_use, csq->next_to_clean); dev_warn(&hdev->pdev->dev, "Disabling any further commands to IMP firmware\n"); @@ -92,9 +92,9 @@ u32 reg_val; if (ring->flag == HCLGEVF_TYPE_CSQ) { - reg_val = (u32)ring->desc_dma_addr; + reg_val = lower_32_bits(ring->desc_dma_addr); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_L_REG, reg_val); - reg_val = (u32)((ring->desc_dma_addr >> 31) >> 1); + reg_val = upper_32_bits(ring->desc_dma_addr); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_BASEADDR_H_REG, reg_val); reg_val = hclgevf_read_dev(hw, HCLGEVF_NIC_CSQ_DEPTH_REG); @@ -105,9 +105,9 @@ hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG, 0); hclgevf_write_dev(hw, HCLGEVF_NIC_CSQ_TAIL_REG, 0); } else { - reg_val = (u32)ring->desc_dma_addr; + reg_val = lower_32_bits(ring->desc_dma_addr); hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_BASEADDR_L_REG, reg_val); - reg_val = (u32)((ring->desc_dma_addr >> 31) >> 1); + reg_val = upper_32_bits(ring->desc_dma_addr); hclgevf_write_dev(hw, HCLGEVF_NIC_CRQ_BASEADDR_H_REG, reg_val); reg_val = (ring->desc_num >> HCLGEVF_NIC_CMQ_DESC_NUM_S); @@ -443,7 +443,7 @@ { spin_lock_bh(&hdev->hw.cmq.csq.lock); spin_lock(&hdev->hw.cmq.crq.lock); - clear_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); + set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); hclgevf_cmd_uninit_regs(&hdev->hw); spin_unlock(&hdev->hw.cmq.crq.lock); spin_unlock_bh(&hdev->hw.cmq.csq.lock); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -16,6 +16,8 @@ static int hclgevf_reset_hdev(struct hclgevf_dev *hdev); static struct hnae3_ae_algo ae_algovf; +static struct workqueue_struct *hclgevf_wq; + static const struct pci_device_id ae_algovf_pci_tbl[] = { {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), 0}, @@ -440,6 +442,9 @@ struct hnae3_client *rclient; struct hnae3_client *client; + if (test_and_set_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state)) + return; + client = handle->client; rclient = hdev->roce_client; @@ -452,6 +457,8 @@ rclient->ops->link_status_change(rhandle, !!link_state); hdev->hw.mac.link = link_state; } + + clear_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state); } static void hclgevf_update_link_mode(struct hclgevf_dev *hdev) @@ -644,9 +651,9 @@ roundup_size = ilog2(roundup_size); for (i = 0; i < HCLGEVF_MAX_TC_NUM; i++) { - tc_valid[i] = !!(hdev->hw_tc_map & BIT(i)); + tc_valid[i] = 1; tc_size[i] = roundup_size; - tc_offset[i] = rss_size * i; + tc_offset[i] = (hdev->hw_tc_map & BIT(i)) ? rss_size * i : 0; } hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_RSS_TC_MODE, false); @@ -1113,6 +1120,7 @@ } static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev, + bool en_uc_pmc, bool en_mc_pmc, bool en_bc_pmc) { struct hclge_mbx_vf_to_pf_cmd *req; @@ -1120,10 +1128,11 @@ int ret; req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; - hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); req->msg[0] = HCLGE_MBX_SET_PROMISC_MODE; req->msg[1] = en_bc_pmc ? 1 : 0; + req->msg[2] = en_uc_pmc ? 1 : 0; + req->msg[3] = en_mc_pmc ? 1 : 0; ret = hclgevf_cmd_send(&hdev->hw, &desc, 1); if (ret) @@ -1133,9 +1142,17 @@ return ret; } -static int hclgevf_set_promisc_mode(struct hclgevf_dev *hdev, bool en_bc_pmc) +static int hclgevf_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc, + bool en_mc_pmc) { - return hclgevf_cmd_set_promisc_mode(hdev, en_bc_pmc); + struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + struct pci_dev *pdev = hdev->pdev; + bool en_bc_pmc; + + en_bc_pmc = pdev->revision != 0x20; + + return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc, + en_bc_pmc); } static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, unsigned int tqp_id, @@ -1174,11 +1191,37 @@ } } +static int hclgevf_get_host_mac_addr(struct hclgevf_dev *hdev, u8 *p) +{ + u8 host_mac[ETH_ALEN]; + int status; + + status = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_MAC_ADDR, 0, NULL, 0, + true, host_mac, ETH_ALEN); + if (status) { + dev_err(&hdev->pdev->dev, + "fail to get VF MAC from host %d", status); + return status; + } + + ether_addr_copy(p, host_mac); + + return 0; +} + static void hclgevf_get_mac_addr(struct hnae3_handle *handle, u8 *p) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + u8 host_mac_addr[ETH_ALEN]; + + if (hclgevf_get_host_mac_addr(hdev, host_mac_addr)) + return; - ether_addr_copy(p, hdev->hw.mac.mac_addr); + hdev->has_pf_mac = !is_zero_ether_addr(host_mac_addr); + if (hdev->has_pf_mac) + ether_addr_copy(p, host_mac_addr); + else + ether_addr_copy(p, hdev->hw.mac.mac_addr); } static int hclgevf_set_mac_addr(struct hnae3_handle *handle, void *p, @@ -1273,14 +1316,13 @@ msg_data[0] = is_kill; memcpy(&msg_data[1], &vlan_id, sizeof(vlan_id)); memcpy(&msg_data[3], &proto, sizeof(proto)); - ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, - HCLGE_MBX_VLAN_FILTER, msg_data, - HCLGEVF_VLAN_MBX_MSG_LEN, false, NULL, 0); - /* when remove hw vlan filter failed, record the vlan id, * and try to remove it from hw later, to be consistence * with stack. */ + ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN, + HCLGE_MBX_VLAN_FILTER, msg_data, + HCLGEVF_VLAN_MBX_MSG_LEN, true, NULL, 0); if (is_kill && ret) set_bit(vlan_id, hdev->vlan_del_fail_bmap); @@ -1368,32 +1410,6 @@ return ret; } -static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev) -{ - struct hclgevf_dev *hdev = ae_dev->priv; - - set_bit(HNAE3_FLR_DONE, &hdev->flr_state); -} - -static int hclgevf_flr_poll_timeout(struct hclgevf_dev *hdev, - unsigned long delay_us, - unsigned long wait_cnt) -{ - unsigned long cnt = 0; - - while (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state) && - cnt++ < wait_cnt) - usleep_range(delay_us, delay_us * 2); - - if (!test_bit(HNAE3_FLR_DONE, &hdev->flr_state)) { - dev_err(&hdev->pdev->dev, - "flr wait timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - static int hclgevf_reset_wait(struct hclgevf_dev *hdev) { #define HCLGEVF_RESET_WAIT_US 20000 @@ -1404,11 +1420,7 @@ u32 val; int ret; - if (hdev->reset_type == HNAE3_FLR_RESET) - return hclgevf_flr_poll_timeout(hdev, - HCLGEVF_RESET_WAIT_US, - HCLGEVF_RESET_WAIT_CNT); - else if (hdev->reset_type == HNAE3_VF_RESET) + if (hdev->reset_type == HNAE3_VF_RESET) ret = readl_poll_timeout(hdev->hw.io_base + HCLGEVF_VF_RST_ING, val, !(val & HCLGEVF_VF_RST_ING_BIT), @@ -1432,7 +1444,10 @@ * might happen in case reset assertion was made by PF. Yes, this also * means we might end up waiting bit more even for VF reset. */ - msleep(5000); + if (hdev->reset_type == HNAE3_VF_FULL_RESET) + msleep(5000); + else + msleep(500); return 0; } @@ -1480,7 +1495,8 @@ /* clear handshake status with IMP */ hclgevf_reset_handshake(hdev, false); - return 0; + /* bring up the nic to enable TX/RX again */ + return hclgevf_notify_client(hdev, HNAE3_UP_CLIENT); } static int hclgevf_reset_prepare_wait(struct hclgevf_dev *hdev) @@ -1489,18 +1505,10 @@ int ret = 0; - switch (hdev->reset_type) { - case HNAE3_VF_FUNC_RESET: + if (hdev->reset_type == HNAE3_VF_FUNC_RESET) { ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_RESET, 0, NULL, 0, true, NULL, sizeof(u8)); hdev->rst_stats.vf_func_rst_cnt++; - break; - case HNAE3_FLR_RESET: - set_bit(HNAE3_FLR_DOWN, &hdev->flr_state); - hdev->rst_stats.flr_rst_cnt++; - break; - default: - break; } set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); @@ -1513,12 +1521,39 @@ return ret; } +static void hclgevf_dump_rst_info(struct hclgevf_dev *hdev) +{ + dev_info(&hdev->pdev->dev, "VF function reset count: %u\n", + hdev->rst_stats.vf_func_rst_cnt); + dev_info(&hdev->pdev->dev, "FLR reset count: %u\n", + hdev->rst_stats.flr_rst_cnt); + dev_info(&hdev->pdev->dev, "VF reset count: %u\n", + hdev->rst_stats.vf_rst_cnt); + dev_info(&hdev->pdev->dev, "reset done count: %u\n", + hdev->rst_stats.rst_done_cnt); + dev_info(&hdev->pdev->dev, "HW reset done count: %u\n", + hdev->rst_stats.hw_rst_done_cnt); + dev_info(&hdev->pdev->dev, "reset count: %u\n", + hdev->rst_stats.rst_cnt); + dev_info(&hdev->pdev->dev, "reset fail count: %u\n", + hdev->rst_stats.rst_fail_cnt); + dev_info(&hdev->pdev->dev, "vector0 interrupt enable status: 0x%x\n", + hclgevf_read_dev(&hdev->hw, HCLGEVF_MISC_VECTOR_REG_BASE)); + dev_info(&hdev->pdev->dev, "vector0 interrupt status: 0x%x\n", + hclgevf_read_dev(&hdev->hw, HCLGEVF_VECTOR0_CMDQ_STAT_REG)); + dev_info(&hdev->pdev->dev, "handshake status: 0x%x\n", + hclgevf_read_dev(&hdev->hw, HCLGEVF_CMDQ_TX_DEPTH_REG)); + dev_info(&hdev->pdev->dev, "function reset status: 0x%x\n", + hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING)); + dev_info(&hdev->pdev->dev, "hdev state: 0x%lx\n", hdev->state); +} + static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) { /* recover handshake status with IMP when reset fail */ hclgevf_reset_handshake(hdev, true); hdev->rst_stats.rst_fail_cnt++; - dev_err(&hdev->pdev->dev, "failed to reset VF(%d)\n", + dev_err(&hdev->pdev->dev, "failed to reset VF(%u)\n", hdev->rst_stats.rst_fail_cnt); if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) @@ -1527,10 +1562,13 @@ if (hclgevf_is_reset_pending(hdev)) { set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); hclgevf_reset_task_schedule(hdev); + } else { + set_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); + hclgevf_dump_rst_info(hdev); } } -static int hclgevf_reset(struct hclgevf_dev *hdev) +static int hclgevf_reset_prepare(struct hclgevf_dev *hdev) { struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); int ret; @@ -1540,61 +1578,64 @@ */ ae_dev->reset_type = hdev->reset_type; hdev->rst_stats.rst_cnt++; - rtnl_lock(); + rtnl_lock(); /* bring down the nic to stop any ongoing TX/RX */ ret = hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT); - if (ret) - goto err_reset_lock; - rtnl_unlock(); - - ret = hclgevf_reset_prepare_wait(hdev); if (ret) - goto err_reset; + return ret; - /* check if VF could successfully fetch the hardware reset completion - * status from the hardware - */ - ret = hclgevf_reset_wait(hdev); - if (ret) { - /* can't do much in this situation, will disable VF */ - dev_err(&hdev->pdev->dev, - "VF failed(=%d) to fetch H/W reset completion status\n", - ret); - goto err_reset; - } + return hclgevf_reset_prepare_wait(hdev); +} + +static int hclgevf_reset_rebuild(struct hclgevf_dev *hdev) +{ + struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev); + int ret; hdev->rst_stats.hw_rst_done_cnt++; rtnl_lock(); - /* now, re-initialize the nic client and ae device */ ret = hclgevf_reset_stack(hdev); + rtnl_unlock(); if (ret) { dev_err(&hdev->pdev->dev, "failed to reset VF stack\n"); - goto err_reset_lock; + return ret; } - /* bring up the nic to enable TX/RX again */ - ret = hclgevf_notify_client(hdev, HNAE3_UP_CLIENT); - if (ret) - goto err_reset_lock; - - rtnl_unlock(); - hdev->last_reset_time = jiffies; ae_dev->reset_type = HNAE3_NONE_RESET; hdev->rst_stats.rst_done_cnt++; hdev->rst_stats.rst_fail_cnt = 0; + clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); + + return 0; +} + +static void hclgevf_reset(struct hclgevf_dev *hdev) +{ + if (hclgevf_reset_prepare(hdev)) + goto err_reset; + + /* check if VF could successfully fetch the hardware reset completion + * status from the hardware + */ + if (hclgevf_reset_wait(hdev)) { + /* can't do much in this situation, will disable VF */ + dev_err(&hdev->pdev->dev, + "failed to fetch H/W reset completion status\n"); + goto err_reset; + } + + if (hclgevf_reset_rebuild(hdev)) + goto err_reset; + + return; - return ret; -err_reset_lock: - rtnl_unlock(); err_reset: hclgevf_reset_err_handle(hdev); - - return ret; } static enum hnae3_reset_type hclgevf_get_reset_level(struct hclgevf_dev *hdev, @@ -1657,25 +1698,60 @@ set_bit(rst_type, &hdev->default_reset_request); } +static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en) +{ + writel(en ? 1 : 0, vector->addr); +} + static void hclgevf_flr_prepare(struct hnae3_ae_dev *ae_dev) { -#define HCLGEVF_FLR_WAIT_MS 100 -#define HCLGEVF_FLR_WAIT_CNT 50 +#define HCLGEVF_FLR_RETRY_WAIT_MS 500 +#define HCLGEVF_FLR_RETRY_CNT 5 + struct hclgevf_dev *hdev = ae_dev->priv; - int cnt = 0; + int retry_cnt = 0; + int ret; - clear_bit(HNAE3_FLR_DOWN, &hdev->flr_state); - clear_bit(HNAE3_FLR_DONE, &hdev->flr_state); - set_bit(HNAE3_FLR_RESET, &hdev->default_reset_request); - hclgevf_reset_event(hdev->pdev, NULL); +retry: + down(&hdev->reset_sem); + set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); + hdev->reset_type = HNAE3_FLR_RESET; + ret = hclgevf_reset_prepare(hdev); + if (ret) { + dev_err(&hdev->pdev->dev, "fail to prepare FLR, ret=%d\n", + ret); + if (hdev->reset_pending || + retry_cnt++ < HCLGEVF_FLR_RETRY_CNT) { + dev_err(&hdev->pdev->dev, + "reset_pending:0x%lx, retry_cnt:%d\n", + hdev->reset_pending, retry_cnt); + clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); + up(&hdev->reset_sem); + msleep(HCLGEVF_FLR_RETRY_WAIT_MS); + goto retry; + } + } - while (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state) && - cnt++ < HCLGEVF_FLR_WAIT_CNT) - msleep(HCLGEVF_FLR_WAIT_MS); + /* disable misc vector before FLR done */ + hclgevf_enable_vector(&hdev->misc_vector, false); + hdev->rst_stats.flr_rst_cnt++; +} - if (!test_bit(HNAE3_FLR_DOWN, &hdev->flr_state)) - dev_err(&hdev->pdev->dev, - "flr wait down timeout: %d\n", cnt); +static void hclgevf_flr_done(struct hnae3_ae_dev *ae_dev) +{ + struct hclgevf_dev *hdev = ae_dev->priv; + int ret; + + hclgevf_enable_vector(&hdev->misc_vector, true); + + ret = hclgevf_reset_rebuild(hdev); + if (ret) + dev_warn(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", + ret); + + hdev->reset_type = HNAE3_NONE_RESET; + clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); + up(&hdev->reset_sem); } static u32 hclgevf_get_fw_version(struct hnae3_handle *handle) @@ -1702,60 +1778,37 @@ void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev) { - if (!test_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state) && - !test_bit(HCLGEVF_STATE_REMOVING, &hdev->state)) { - set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); - schedule_work(&hdev->rst_service_task); - } + if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && + !test_and_set_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, + &hdev->state)) + mod_delayed_work(hclgevf_wq, &hdev->service_task, 0); } void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev) { - if (!test_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state) && - !test_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) { - set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); - schedule_work(&hdev->mbx_service_task); - } -} - -static void hclgevf_task_schedule(struct hclgevf_dev *hdev) -{ - if (!test_bit(HCLGEVF_STATE_DOWN, &hdev->state) && - !test_and_set_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state)) - schedule_work(&hdev->service_task); -} - -static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev) -{ - /* if we have any pending mailbox event then schedule the mbx task */ - if (hdev->mbx_event_pending) - hclgevf_mbx_task_schedule(hdev); - - if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state)) - hclgevf_reset_task_schedule(hdev); + if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && + !test_and_set_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, + &hdev->state)) + mod_delayed_work(hclgevf_wq, &hdev->service_task, 0); } -static void hclgevf_service_timer(struct timer_list *t) +static void hclgevf_task_schedule(struct hclgevf_dev *hdev, + unsigned long delay) { - struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); - - mod_timer(&hdev->service_timer, jiffies + - HCLGEVF_GENERAL_TASK_INTERVAL * HZ); - - hdev->stats_timer++; - hclgevf_task_schedule(hdev); + if (!test_bit(HCLGEVF_STATE_REMOVING, &hdev->state) && + !test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) + mod_delayed_work(hclgevf_wq, &hdev->service_task, delay); } -static void hclgevf_reset_service_task(struct work_struct *work) +static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) { - struct hclgevf_dev *hdev = - container_of(work, struct hclgevf_dev, rst_service_task); - int ret; +#define HCLGEVF_MAX_RESET_ATTEMPTS_CNT 3 - if (test_and_set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state)) + if (!test_and_clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state)) return; - clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); + down(&hdev->reset_sem); + set_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); if (test_and_clear_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state)) { @@ -1769,12 +1822,8 @@ hdev->last_reset_time = jiffies; while ((hdev->reset_type = hclgevf_get_reset_level(hdev, &hdev->reset_pending)) - != HNAE3_NONE_RESET) { - ret = hclgevf_reset(hdev); - if (ret) - dev_err(&hdev->pdev->dev, - "VF stack reset failed %d.\n", ret); - } + != HNAE3_NONE_RESET) + hclgevf_reset(hdev); } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state)) { /* we could be here when either of below happens: @@ -1800,7 +1849,7 @@ * We cannot do much for 2. but to check first we can try reset * our PCIe + stack and see if it alleviates the problem. */ - if (hdev->reset_attempts > 3) { + if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { /* prepare for full reset of stack + pcie interface */ set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending); @@ -1815,42 +1864,29 @@ hclgevf_reset_task_schedule(hdev); } + hdev->reset_type = HNAE3_NONE_RESET; clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); + up(&hdev->reset_sem); } -static void hclgevf_mailbox_service_task(struct work_struct *work) +static void hclgevf_mailbox_service_task(struct hclgevf_dev *hdev) { - struct hclgevf_dev *hdev; - - hdev = container_of(work, struct hclgevf_dev, mbx_service_task); + if (!test_and_clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state)) + return; if (test_and_set_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state)) return; - clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); - hclgevf_mbx_async_handler(hdev); clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); } -static void hclgevf_keep_alive_timer(struct timer_list *t) +static void hclgevf_keep_alive(struct hclgevf_dev *hdev) { - struct hclgevf_dev *hdev = from_timer(hdev, t, keep_alive_timer); - - schedule_work(&hdev->keep_alive_task); - mod_timer(&hdev->keep_alive_timer, jiffies + - HCLGEVF_KEEP_ALIVE_TASK_INTERVAL * HZ); -} - -static void hclgevf_keep_alive_task(struct work_struct *work) -{ - struct hclgevf_dev *hdev; u8 respmsg; int ret; - hdev = container_of(work, struct hclgevf_dev, keep_alive_task); - if (test_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state)) return; @@ -1861,19 +1897,32 @@ "VF sends keep alive cmd failed(=%d)\n", ret); } -static void hclgevf_service_task(struct work_struct *work) +static void hclgevf_periodic_service_task(struct hclgevf_dev *hdev) { - struct hnae3_handle *handle; - struct hclgevf_dev *hdev; + unsigned long delta = round_jiffies_relative(HZ); + struct hnae3_handle *handle = &hdev->nic; - hdev = container_of(work, struct hclgevf_dev, service_task); - handle = &hdev->nic; + if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { + delta = jiffies - hdev->last_serv_processed; - if (hdev->stats_timer >= HCLGEVF_STATS_TIMER_INTERVAL) { - hclgevf_tqps_update_stats(handle); - hdev->stats_timer = 0; + if (delta < round_jiffies_relative(HZ)) { + delta = round_jiffies_relative(HZ) - delta; + goto out; + } + } + + hdev->serv_processed_cnt++; + if (!(hdev->serv_processed_cnt % HCLGEVF_KEEP_ALIVE_TASK_INTERVAL)) + hclgevf_keep_alive(hdev); + + if (test_bit(HCLGEVF_STATE_DOWN, &hdev->state)) { + hdev->last_serv_processed = jiffies; + goto out; } + if (!(hdev->serv_processed_cnt % HCLGEVF_STATS_TIMER_INTERVAL)) + hclgevf_tqps_update_stats(handle); + /* request the link status from the PF. PF would be able to tell VF * about such updates in future so we might remove this later */ @@ -1883,9 +1932,27 @@ hclgevf_sync_vlan_filter(hdev); - hclgevf_deferred_task_schedule(hdev); + hdev->last_serv_processed = jiffies; - clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); +out: + hclgevf_task_schedule(hdev, delta); +} + +static void hclgevf_service_task(struct work_struct *work) +{ + struct hclgevf_dev *hdev = container_of(work, struct hclgevf_dev, + service_task.work); + + hclgevf_reset_service_task(hdev); + hclgevf_mailbox_service_task(hdev); + hclgevf_periodic_service_task(hdev); + + /* Handle reset and mbx again in case periodical task delays the + * handling by calling hclgevf_task_schedule() in + * hclgevf_periodic_service_task() + */ + hclgevf_reset_service_task(hdev); + hclgevf_mailbox_service_task(hdev); } static void hclgevf_clear_event_cause(struct hclgevf_dev *hdev, u32 regclr) @@ -1938,16 +2005,14 @@ return HCLGEVF_VECTOR0_EVENT_MBX; } - dev_dbg(&hdev->pdev->dev, "vector 0 interrupt from unknown source\n"); + /* print other vector0 event source */ + dev_info(&hdev->pdev->dev, + "vector 0 interrupt from unknown source, cmdq_src = %#x\n", + cmdq_stat_reg); return HCLGEVF_VECTOR0_EVENT_OTHER; } -static void hclgevf_enable_vector(struct hclgevf_misc_vector *vector, bool en) -{ - writel(en ? 1 : 0, vector->addr); -} - static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) { enum hclgevf_evt_cause event_cause; @@ -1956,6 +2021,8 @@ hclgevf_enable_vector(&hdev->misc_vector, false); event_cause = hclgevf_check_evt_cause(hdev, &clearval); + if (event_cause != HCLGEVF_VECTOR0_EVENT_OTHER) + hclgevf_clear_event_cause(hdev, clearval); switch (event_cause) { case HCLGEVF_VECTOR0_EVENT_RST: @@ -1968,10 +2035,7 @@ break; } - if (event_cause != HCLGEVF_VECTOR0_EVENT_OTHER) { - hclgevf_clear_event_cause(hdev, clearval); - hclgevf_enable_vector(&hdev->misc_vector, true); - } + hclgevf_enable_vector(&hdev->misc_vector, true); return IRQ_HANDLED; } @@ -2103,7 +2167,6 @@ ret = hclgevf_set_rss_input_tuple(hdev, rss_cfg); if (ret) return ret; - } /* Initialize RSS indirect table */ @@ -2119,20 +2182,45 @@ static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) { + struct hnae3_handle *nic = &hdev->nic; + int ret; + + ret = hclgevf_en_hw_strip_rxvtag(nic, true); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to enable rx vlan offload, ret = %d\n", ret); + return ret; + } + return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, false); } +static void hclgevf_flush_link_update(struct hclgevf_dev *hdev) +{ +#define HCLGEVF_FLUSH_LINK_TIMEOUT 100000 + + unsigned long last = hdev->serv_processed_cnt; + int i = 0; + + while (test_bit(HCLGEVF_STATE_LINK_UPDATING, &hdev->state) && + i++ < HCLGEVF_FLUSH_LINK_TIMEOUT && + last == hdev->serv_processed_cnt) + usleep_range(1, 1); +} + static void hclgevf_set_timer_task(struct hnae3_handle *handle, bool enable) { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); if (enable) { - mod_timer(&hdev->service_timer, jiffies + HZ); + hclgevf_task_schedule(hdev, 0); } else { - del_timer_sync(&hdev->service_timer); - cancel_work_sync(&hdev->service_task); - clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); + set_bit(HCLGEVF_STATE_DOWN, &hdev->state); + + /* flush memory to make sure DOWN is seen by service task */ + smp_mb__before_atomic(); + hclgevf_flush_link_update(hdev); } } @@ -2140,14 +2228,14 @@ { struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); + clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); + hclgevf_reset_tqp_stats(handle); hclgevf_request_link_info(hdev); hclgevf_update_link_mode(hdev); - clear_bit(HCLGEVF_STATE_DOWN, &hdev->state); - return 0; } @@ -2179,16 +2267,12 @@ static int hclgevf_client_start(struct hnae3_handle *handle) { - struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); int ret; ret = hclgevf_set_alive(handle, true); if (ret) return ret; - mod_timer(&hdev->keep_alive_timer, jiffies + - HCLGEVF_KEEP_ALIVE_TASK_INTERVAL * HZ); - return 0; } @@ -2201,27 +2285,18 @@ if (ret) dev_warn(&hdev->pdev->dev, "%s failed %d\n", __func__, ret); - - del_timer_sync(&hdev->keep_alive_timer); - cancel_work_sync(&hdev->keep_alive_task); } static void hclgevf_state_init(struct hclgevf_dev *hdev) { - /* setup tasks for the MBX */ - INIT_WORK(&hdev->mbx_service_task, hclgevf_mailbox_service_task); clear_bit(HCLGEVF_STATE_MBX_SERVICE_SCHED, &hdev->state); clear_bit(HCLGEVF_STATE_MBX_HANDLING, &hdev->state); + clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); - /* setup tasks for service timer */ - timer_setup(&hdev->service_timer, hclgevf_service_timer, 0); - - INIT_WORK(&hdev->service_task, hclgevf_service_task); - clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); - - INIT_WORK(&hdev->rst_service_task, hclgevf_reset_service_task); + INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); mutex_init(&hdev->mbx_resp.mbx_mutex); + sema_init(&hdev->reset_sem, 1); /* bring the device down */ set_bit(HCLGEVF_STATE_DOWN, &hdev->state); @@ -2232,18 +2307,8 @@ set_bit(HCLGEVF_STATE_DOWN, &hdev->state); set_bit(HCLGEVF_STATE_REMOVING, &hdev->state); - if (hdev->keep_alive_timer.function) - del_timer_sync(&hdev->keep_alive_timer); - if (hdev->keep_alive_task.func) - cancel_work_sync(&hdev->keep_alive_task); - if (hdev->service_timer.function) - del_timer_sync(&hdev->service_timer); - if (hdev->service_task.func) - cancel_work_sync(&hdev->service_task); - if (hdev->mbx_service_task.func) - cancel_work_sync(&hdev->mbx_service_task); - if (hdev->rst_service_task.func) - cancel_work_sync(&hdev->rst_service_task); + if (hdev->service_task.work.func) + cancel_delayed_work_sync(&hdev->service_task); mutex_destroy(&hdev->mbx_resp.mbx_mutex); } @@ -2272,7 +2337,7 @@ } if (vectors < hdev->num_msi) dev_warn(&hdev->pdev->dev, - "requested %d MSI/MSI-X, but allocated %d MSI/MSI-X\n", + "requested %u MSI/MSI-X, but allocated %d MSI/MSI-X\n", hdev->num_msi, vectors); hdev->num_msi = vectors; @@ -2317,8 +2382,10 @@ hclgevf_get_misc_vector(hdev); + snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", + HCLGEVF_NAME, pci_name(hdev->pdev)); ret = request_irq(hdev->misc_vector.vector_irq, hclgevf_misc_irq_handle, - 0, "hclgevf_cmd", hdev); + 0, hdev->misc_vector.name, hdev); if (ret) { dev_err(&hdev->pdev->dev, "VF failed to request misc irq(%d)\n", hdev->misc_vector.vector_irq); @@ -2348,12 +2415,12 @@ dev_info(dev, "VF info begin:\n"); - dev_info(dev, "Task queue pairs numbers: %d\n", hdev->num_tqps); - dev_info(dev, "Desc num per TX queue: %d\n", hdev->num_tx_desc); - dev_info(dev, "Desc num per RX queue: %d\n", hdev->num_rx_desc); - dev_info(dev, "Numbers of vports: %d\n", hdev->num_alloc_vport); - dev_info(dev, "HW tc map: %d\n", hdev->hw_tc_map); - dev_info(dev, "PF media type of this VF: %d\n", + dev_info(dev, "Task queue pairs numbers: %u\n", hdev->num_tqps); + dev_info(dev, "Desc num per TX queue: %u\n", hdev->num_tx_desc); + dev_info(dev, "Desc num per RX queue: %u\n", hdev->num_rx_desc); + dev_info(dev, "Numbers of vports: %u\n", hdev->num_alloc_vport); + dev_info(dev, "HW tc map: 0x%x\n", hdev->hw_tc_map); + dev_info(dev, "PF media type of this VF: %u\n", hdev->hw.mac.media_type); dev_info(dev, "VF info end.\n"); @@ -2583,7 +2650,8 @@ struct pci_dev *pdev = hdev->pdev; int ret = 0; - if (hdev->reset_type == HNAE3_VF_FULL_RESET && + if ((hdev->reset_type == HNAE3_VF_FULL_RESET || + hdev->reset_type == HNAE3_FLR_RESET) && test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { hclgevf_misc_irq_uninit(hdev); hclgevf_uninit_msi(hdev); @@ -2648,12 +2716,6 @@ return ret; } - if (pdev->revision >= 0x21) { - ret = hclgevf_set_promisc_mode(hdev, true); - if (ret) - return ret; - } - dev_info(&hdev->pdev->dev, "Reset done\n"); return 0; @@ -2696,6 +2758,7 @@ hclgevf_state_init(hdev); hdev->reset_level = HNAE3_VF_FUNC_RESET; + hdev->reset_type = HNAE3_NONE_RESET; ret = hclgevf_misc_irq_init(hdev); if (ret) { @@ -2728,17 +2791,6 @@ if (ret) goto err_config; - /* vf is not allowed to enable unicast/multicast promisc mode. - * For revision 0x20, default to disable broadcast promisc mode, - * firmware makes sure broadcast packets can be accepted. - * For revision 0x21, default to enable broadcast promisc mode. - */ - if (pdev->revision >= 0x21) { - ret = hclgevf_set_promisc_mode(hdev, true); - if (ret) - goto err_config; - } - /* Initialize RSS for this VF */ ret = hclgevf_rss_init_hw(hdev); if (ret) { @@ -2758,6 +2810,8 @@ dev_info(&hdev->pdev->dev, "finished initializing %s driver\n", HCLGEVF_DRIVER_NAME); + hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); + return 0; err_config: @@ -2777,19 +2831,21 @@ { hclgevf_state_uninit(hdev); + hclgevf_send_mbx_msg(hdev, HCLGE_MBX_VF_UNINIT, 0, NULL, 0, + false, NULL, 0); + if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { hclgevf_misc_irq_uninit(hdev); hclgevf_uninit_msi(hdev); } - hclgevf_pci_uninit(hdev); hclgevf_cmd_uninit(hdev); + hclgevf_pci_uninit(hdev); } static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) { struct pci_dev *pdev = ae_dev->pdev; - struct hclgevf_dev *hdev; int ret; ret = hclgevf_alloc_hdev(ae_dev); @@ -2804,10 +2860,6 @@ return ret; } - hdev = ae_dev->priv; - timer_setup(&hdev->keep_alive_timer, hclgevf_keep_alive_timer, 0); - INIT_WORK(&hdev->keep_alive_task, hclgevf_keep_alive_task); - return 0; } @@ -3152,6 +3204,7 @@ .get_global_queue_id = hclgevf_get_qid_global, .set_timer_task = hclgevf_set_timer_task, .get_link_mode = hclgevf_get_link_mode, + .set_promisc_mode = hclgevf_set_promisc_mode, }; static struct hnae3_ae_algo ae_algovf = { @@ -3163,6 +3216,12 @@ { pr_info("%s is initializing\n", HCLGEVF_NAME); + hclgevf_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGEVF_NAME); + if (!hclgevf_wq) { + pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME); + return -ENOMEM; + } + hnae3_register_ae_algo(&ae_algovf); return 0; @@ -3171,6 +3230,7 @@ static void hclgevf_exit(void) { hnae3_unregister_ae_algo(&ae_algovf); + destroy_workqueue(hclgevf_wq); } module_init(hclgevf_init); module_exit(hclgevf_exit); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h @@ -142,16 +142,15 @@ HCLGEVF_STATE_REMOVING, HCLGEVF_STATE_NIC_REGISTERED, /* task states */ - HCLGEVF_STATE_SERVICE_SCHED, HCLGEVF_STATE_RST_SERVICE_SCHED, HCLGEVF_STATE_RST_HANDLING, HCLGEVF_STATE_MBX_SERVICE_SCHED, HCLGEVF_STATE_MBX_HANDLING, HCLGEVF_STATE_CMD_DISABLE, + HCLGEVF_STATE_LINK_UPDATING, + HCLGEVF_STATE_RST_FAIL, }; -#define HCLGEVF_MPF_ENBALE 1 - struct hclgevf_mac { u8 media_type; u8 module_type; @@ -222,6 +221,7 @@ struct hclgevf_misc_vector { u8 __iomem *addr; int vector_irq; + char name[HNAE3_INT_NAME_LEN]; }; struct hclgevf_rst_stats { @@ -253,6 +253,7 @@ unsigned long reset_state; /* requested, pending */ struct hclgevf_rst_stats rst_stats; u32 reset_attempts; + struct semaphore reset_sem; /* protect reset process */ u32 fw_version; u16 num_tqps; /* num task queue pairs of this PF */ @@ -266,6 +267,7 @@ u16 num_tx_desc; /* desc num of per tx queue */ u16 num_rx_desc; /* desc num of per rx queue */ u8 hw_tc_map; + u8 has_pf_mac; u16 num_msi; u16 num_msi_left; @@ -284,12 +286,7 @@ struct hclgevf_mbx_resp_status mbx_resp; /* mailbox response */ struct hclgevf_mbx_arq_ring arq; /* mailbox async rx queue */ - struct timer_list service_timer; - struct timer_list keep_alive_timer; - struct work_struct service_task; - struct work_struct keep_alive_task; - struct work_struct rst_service_task; - struct work_struct mbx_service_task; + struct delayed_work service_task; struct hclgevf_tqp *htqp; @@ -299,7 +296,8 @@ struct hnae3_client *nic_client; struct hnae3_client *roce_client; u32 flag; - u32 stats_timer; + unsigned long serv_processed_cnt; + unsigned long last_serv_processed; }; static inline bool hclgevf_is_reset_pending(struct hclgevf_dev *hdev) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c @@ -33,7 +33,7 @@ if (resp_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { dev_err(&hdev->pdev->dev, - "VF mbx response len(=%d) exceeds maximum(=%d)\n", + "VF mbx response len(=%u) exceeds maximum(=%u)\n", resp_len, HCLGE_MBX_MAX_RESP_DATA_SIZE); return -EINVAL; @@ -49,7 +49,7 @@ if (i >= HCLGEVF_MAX_TRY_TIMES) { dev_err(&hdev->pdev->dev, - "VF could not get mbx(%d,%d) resp(=%d) from PF in %d tries\n", + "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n", code0, code1, hdev->mbx_resp.received_resp, i); return -EIO; } @@ -68,10 +68,10 @@ if (!(r_code0 == code0 && r_code1 == code1 && !mbx_resp->resp_status)) { dev_err(&hdev->pdev->dev, - "VF could not match resp code(code0=%d,code1=%d), %d\n", + "VF could not match resp code(code0=%u,code1=%u), %d\n", code0, code1, mbx_resp->resp_status); dev_err(&hdev->pdev->dev, - "VF could not match resp r_code(r_code0=%d,r_code1=%d)\n", + "VF could not match resp r_code(r_code0=%u,r_code1=%u)\n", r_code0, r_code1); return -EIO; } @@ -168,7 +168,7 @@ flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); if (unlikely(!hnae3_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) { dev_warn(&hdev->pdev->dev, - "dropped invalid mailbox message, code = %d\n", + "dropped invalid mailbox message, code = %u\n", req->msg[0]); /* dropping/not processing this invalid message */ @@ -187,7 +187,7 @@ case HCLGE_MBX_PF_VF_RESP: if (resp->received_resp) dev_warn(&hdev->pdev->dev, - "VF mbx resp flag not clear(%d)\n", + "VF mbx resp flag not clear(%u)\n", req->msg[1]); resp->received_resp = true; @@ -205,6 +205,7 @@ case HCLGE_MBX_ASSERTING_RESET: case HCLGE_MBX_LINK_STAT_MODE: case HCLGE_MBX_PUSH_VLAN_INFO: + case HCLGE_MBX_PUSH_PROMISC_INFO: /* set this mbx event as pending. This is required as we * might loose interrupt event when mbx task is busy * handling. This shall be cleared when mbx task just @@ -218,7 +219,7 @@ if (atomic_read(&hdev->arq.count) >= HCLGE_MBX_MAX_ARQ_MSG_NUM) { dev_warn(&hdev->pdev->dev, - "Async Q full, dropping msg(%d)\n", + "Async Q full, dropping msg(%u)\n", req->msg[1]); break; } @@ -235,7 +236,7 @@ break; default: dev_err(&hdev->pdev->dev, - "VF received unsupported(%d) mbx msg from PF\n", + "VF received unsupported(%u) mbx msg from PF\n", req->msg[0]); break; } @@ -248,6 +249,14 @@ crq->next_to_use); } +static void hclgevf_parse_promisc_info(struct hclgevf_dev *hdev, + u16 promisc_info) +{ + if (!promisc_info) + dev_info(&hdev->pdev->dev, + "Promisc mode is closed by host for being untrusted.\n"); +} + void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev) { enum hnae3_reset_type reset_type; @@ -313,9 +322,12 @@ hclgevf_update_port_base_vlan_info(hdev, state, (u8 *)vlan_info, 8); break; + case HCLGE_MBX_PUSH_PROMISC_INFO: + hclgevf_parse_promisc_info(hdev, msg_q[1]); + break; default: dev_err(&hdev->pdev->dev, - "fetched unsupported(%d) message from arq\n", + "fetched unsupported(%u) message from arq\n", msg_q[0]); break; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/hisilicon/hns_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/hisilicon/hns_mdio.c @@ -498,6 +498,7 @@ MDIO_SC_RESET_ST; } } + of_node_put(reg_args.np); } else { dev_warn(&pdev->dev, "find syscon ret = %#x\n", ret); mdio_dev->subctrl_vbase = NULL; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c @@ -389,7 +389,8 @@ spin_unlock_bh(&cmdq->cmdq_lock); - if (!wait_for_completion_timeout(&done, CMDQ_TIMEOUT)) { + if (!wait_for_completion_timeout(&done, + msecs_to_jiffies(CMDQ_TIMEOUT))) { spin_lock_bh(&cmdq->cmdq_lock); if (cmdq->errcode[curr_prod_idx] == &errcode) @@ -623,6 +624,8 @@ if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info))) return -EBUSY; + dma_rmb(); + errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL); cmdq_sync_cmd_handler(cmdq, ci, errcode); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c @@ -297,6 +297,7 @@ } hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); + hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; hw_ioctxt.cmdq_depth = 0; @@ -359,50 +360,6 @@ return -EFAULT; } -static int wait_for_io_stopped(struct hinic_hwdev *hwdev) -{ - struct hinic_cmd_io_status cmd_io_status; - struct hinic_hwif *hwif = hwdev->hwif; - struct pci_dev *pdev = hwif->pdev; - struct hinic_pfhwdev *pfhwdev; - unsigned long end; - u16 out_size; - int err; - - if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) { - dev_err(&pdev->dev, "Unsupported PCI Function type\n"); - return -EINVAL; - } - - pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); - - cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif); - - end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT); - do { - err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM, - HINIC_COMM_CMD_IO_STATUS_GET, - &cmd_io_status, sizeof(cmd_io_status), - &cmd_io_status, &out_size, - HINIC_MGMT_MSG_SYNC); - if ((err) || (out_size != sizeof(cmd_io_status))) { - dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n", - err); - return err; - } - - if (cmd_io_status.status == IO_STOPPED) { - dev_info(&pdev->dev, "IO stopped\n"); - return 0; - } - - msleep(20); - } while (time_before(jiffies, end)); - - dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n"); - return -ETIMEDOUT; -} - /** * clear_io_resource - set the IO resources as not active in the NIC * @hwdev: the NIC HW device @@ -422,11 +379,8 @@ return -EINVAL; } - err = wait_for_io_stopped(hwdev); - if (err) { - dev_err(&pdev->dev, "IO has not stopped yet\n"); - return err; - } + /* sleep 100ms to wait for firmware stopping I/O */ + msleep(100); cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h @@ -151,8 +151,8 @@ u8 lro_en; u8 rsvd3; + u8 ppf_idx; u8 rsvd4; - u8 rsvd5; u16 rq_depth; u16 rx_buf_sz_idx; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c @@ -188,7 +188,7 @@ * eq_update_ci - update the HW cons idx of event queue * @eq: the event queue to update the cons idx for **/ -static void eq_update_ci(struct hinic_eq *eq) +static void eq_update_ci(struct hinic_eq *eq, u32 arm_state) { u32 val, addr = EQ_CONS_IDX_REG_ADDR(eq); @@ -202,7 +202,7 @@ val |= HINIC_EQ_CI_SET(eq->cons_idx, IDX) | HINIC_EQ_CI_SET(eq->wrapped, WRAPPED) | - HINIC_EQ_CI_SET(EQ_ARMED, INT_ARMED); + HINIC_EQ_CI_SET(arm_state, INT_ARMED); val |= HINIC_EQ_CI_SET(eq_cons_idx_checksum_set(val), XOR_CHKSUM); @@ -235,6 +235,8 @@ if (HINIC_EQ_ELEM_DESC_GET(aeqe_desc, WRAPPED) == eq->wrapped) break; + dma_rmb(); + event = HINIC_EQ_ELEM_DESC_GET(aeqe_desc, TYPE); if (event >= HINIC_MAX_AEQ_EVENTS) { dev_err(&pdev->dev, "Unknown AEQ Event %d\n", event); @@ -347,7 +349,7 @@ else if (eq->type == HINIC_CEQ) ceq_irq_handler(eq); - eq_update_ci(eq); + eq_update_ci(eq, EQ_ARMED); } /** @@ -702,7 +704,7 @@ } set_eq_ctrls(eq); - eq_update_ci(eq); + eq_update_ci(eq, EQ_ARMED); err = alloc_eq_pages(eq); if (err) { @@ -752,18 +754,28 @@ **/ static void remove_eq(struct hinic_eq *eq) { - struct msix_entry *entry = &eq->msix_entry; - - free_irq(entry->vector, eq); + hinic_set_msix_state(eq->hwif, eq->msix_entry.entry, + HINIC_MSIX_DISABLE); + free_irq(eq->msix_entry.vector, eq); if (eq->type == HINIC_AEQ) { struct hinic_eq_work *aeq_work = &eq->aeq_work; cancel_work_sync(&aeq_work->work); + /* clear aeq_len to avoid hw access host memory */ + hinic_hwif_write_reg(eq->hwif, + HINIC_CSR_AEQ_CTRL_1_ADDR(eq->q_id), 0); } else if (eq->type == HINIC_CEQ) { tasklet_kill(&eq->ceq_tasklet); + /* clear ceq_len to avoid hw access host memory */ + hinic_hwif_write_reg(eq->hwif, + HINIC_CSR_CEQ_CTRL_1_ADDR(eq->q_id), 0); } + /* update cons_idx to avoid invalid interrupt */ + eq->cons_idx = hinic_hwif_read_reg(eq->hwif, EQ_PROD_IDX_REG_ADDR(eq)); + eq_update_ci(eq, EQ_NOT_ARMED); + free_eq_pages(eq); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_if.h @@ -137,6 +137,7 @@ #define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx) #define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx) #define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx) +#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx) #define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type) #define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c @@ -43,7 +43,9 @@ #define MSG_NOT_RESP 0xFFFF -#define MGMT_MSG_TIMEOUT 1000 +#define MGMT_MSG_TIMEOUT 5000 + +#define SET_FUNC_PORT_MGMT_TIMEOUT 25000 #define mgmt_to_pfhwdev(pf_mgmt) \ container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt) @@ -238,12 +240,13 @@ u8 *buf_in, u16 in_size, u8 *buf_out, u16 *out_size, enum mgmt_direction_type direction, - u16 resp_msg_id) + u16 resp_msg_id, u32 timeout) { struct hinic_hwif *hwif = pf_to_mgmt->hwif; struct pci_dev *pdev = hwif->pdev; struct hinic_recv_msg *recv_msg; struct completion *recv_done; + unsigned long timeo; u16 msg_id; int err; @@ -267,7 +270,9 @@ goto unlock_sync_msg; } - if (!wait_for_completion_timeout(recv_done, MGMT_MSG_TIMEOUT)) { + timeo = msecs_to_jiffies(timeout ? timeout : MGMT_MSG_TIMEOUT); + + if (!wait_for_completion_timeout(recv_done, timeo)) { dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id); err = -ETIMEDOUT; goto unlock_sync_msg; @@ -341,6 +346,7 @@ { struct hinic_hwif *hwif = pf_to_mgmt->hwif; struct pci_dev *pdev = hwif->pdev; + u32 timeout = 0; if (sync != HINIC_MGMT_MSG_SYNC) { dev_err(&pdev->dev, "Invalid MGMT msg type\n"); @@ -352,9 +358,12 @@ return -EINVAL; } + if (cmd == HINIC_PORT_CMD_SET_FUNC_STATE) + timeout = SET_FUNC_PORT_MGMT_TIMEOUT; + return msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size, buf_out, out_size, MGMT_DIRECT_SEND, - MSG_NOT_RESP); + MSG_NOT_RESP, timeout); } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h @@ -94,6 +94,7 @@ struct hinic_wq *wq; + struct cpumask affinity_mask; u32 irq; u16 msix_entry; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -161,6 +161,7 @@ hinic_clean_txq(&nic_dev->txqs[j]); devm_kfree(&netdev->dev, nic_dev->txqs); + nic_dev->txqs = NULL; return err; } @@ -221,6 +222,7 @@ hinic_clean_rxq(&nic_dev->rxqs[j]); devm_kfree(&netdev->dev, nic_dev->rxqs); + nic_dev->rxqs = NULL; return err; } @@ -356,7 +358,8 @@ if (!num_cpus) num_cpus = num_online_cpus(); - nic_dev->num_qps = min_t(u16, nic_dev->max_qps, num_cpus); + nic_dev->num_qps = hinic_hwdev_num_qps(hwdev); + nic_dev->num_qps = min_t(u16, nic_dev->num_qps, num_cpus); nic_dev->rss_limit = nic_dev->num_qps; nic_dev->num_rss = nic_dev->num_qps; @@ -482,7 +485,6 @@ { struct hinic_dev *nic_dev = netdev_priv(netdev); unsigned int flags; - int err; down(&nic_dev->mgmt_lock); @@ -496,20 +498,9 @@ up(&nic_dev->mgmt_lock); - err = hinic_port_set_func_state(nic_dev, HINIC_FUNC_PORT_DISABLE); - if (err) { - netif_err(nic_dev, drv, netdev, - "Failed to set func port state\n"); - nic_dev->flags |= (flags & HINIC_INTF_UP); - return err; - } + hinic_port_set_state(nic_dev, HINIC_PORT_DISABLE); - err = hinic_port_set_state(nic_dev, HINIC_PORT_DISABLE); - if (err) { - netif_err(nic_dev, drv, netdev, "Failed to set port state\n"); - nic_dev->flags |= (flags & HINIC_INTF_UP); - return err; - } + hinic_port_set_func_state(nic_dev, HINIC_FUNC_PORT_DISABLE); if (nic_dev->flags & HINIC_RSS_ENABLE) { hinic_rss_deinit(nic_dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_rx.c @@ -350,6 +350,9 @@ if (!rq_wqe) break; + /* make sure we read rx_done before packet length */ + dma_rmb(); + cqe = rq->cqe[ci]; status = be32_to_cpu(cqe->status); hinic_rq_get_sge(rxq->rq, rq_wqe, ci, &sge); @@ -475,7 +478,6 @@ struct hinic_hwdev *hwdev = nic_dev->hwdev; struct hinic_rq *rq = rxq->rq; struct hinic_qp *qp; - struct cpumask mask; int err; rx_add_napi(rxq); @@ -492,8 +494,8 @@ } qp = container_of(rq, struct hinic_qp, rq); - cpumask_set_cpu(qp->q_id % num_online_cpus(), &mask); - return irq_set_affinity_hint(rq->irq, &mask); + cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask); + return irq_set_affinity_hint(rq->irq, &rq->affinity_mask); } static void rx_free_irq(struct hinic_rxq *rxq) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/huawei/hinic/hinic_tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/huawei/hinic/hinic_tx.c @@ -45,7 +45,7 @@ #define HW_CONS_IDX(sq) be16_to_cpu(*(u16 *)((sq)->hw_ci_addr)) -#define MIN_SKB_LEN 17 +#define MIN_SKB_LEN 32 #define MAX_PAYLOAD_OFFSET 221 #define TRANSPORT_OFFSET(l4_hdr, skb) ((u32)((l4_hdr) - (skb)->data)) @@ -622,6 +622,8 @@ do { hw_ci = HW_CONS_IDX(sq) & wq->mask; + dma_rmb(); + /* Reading a WQEBB to get real WQE size and consumer index. */ sq_wqe = hinic_sq_read_wqebb(sq, &skb, &wqe_size, &sw_ci); if ((!sq_wqe) || --- linux-oracle-5.4.0.orig/drivers/net/ethernet/i825xx/82596.c +++ linux-oracle-5.4.0/drivers/net/ethernet/i825xx/82596.c @@ -1155,7 +1155,7 @@ err = -ENODEV; goto out; } - memcpy(eth_addr, (void *) 0xfffc1f2c, ETH_ALEN); /* YUCK! Get addr from NOVRAM */ + memcpy(eth_addr, absolute_pointer(0xfffc1f2c), ETH_ALEN); /* YUCK! Get addr from NOVRAM */ dev->base_addr = MVME_I596_BASE; dev->irq = (unsigned) MVME16x_IRQ_I596; goto found; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/i825xx/sni_82596.c +++ linux-oracle-5.4.0/drivers/net/ethernet/i825xx/sni_82596.c @@ -123,9 +123,10 @@ netdevice->dev_addr[5] = readb(eth_addr + 0x06); iounmap(eth_addr); - if (!netdevice->irq) { + if (netdevice->irq < 0) { printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", __FILE__, netdevice->base_addr); + retval = netdevice->irq; goto probe_failed; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/i825xx/sun3_82586.c +++ linux-oracle-5.4.0/drivers/net/ethernet/i825xx/sun3_82586.c @@ -990,7 +990,7 @@ { #ifdef DEBUG printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus); - printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status)); + printk("%s: command-stats: %04x\n", dev->name, swab16(p->xmit_cmds[0]->cmd_status)); printk("%s: check, whether you set the right interrupt number!\n",dev->name); #endif sun3_82586_close(dev); @@ -1015,6 +1015,7 @@ if(skb->len > XMIT_BUFF_SIZE) { printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len); + dev_kfree_skb(skb); return NETDEV_TX_OK; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2617,10 +2617,8 @@ u16 dummy16 = 0; cb0 = (void *)get_zeroed_page(GFP_KERNEL); - if (!cb0) { - ret = -ENOMEM; - goto out; - } + if (!cb0) + return -ENOMEM; for (i = 0; i < (port->num_def_qps); i++) { struct ehea_port_res *pr = &port->port_res[i]; @@ -2640,6 +2638,7 @@ cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2652,6 +2651,7 @@ &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { netdev_err(dev, "modify_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2660,6 +2660,7 @@ cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (2)\n"); + ret = -EFAULT; goto out; } @@ -2896,6 +2897,7 @@ ret = of_device_register(&port->ofdev); if (ret) { pr_err("failed to register device. ret=%d\n", ret); + put_device(&port->ofdev.dev); goto out; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ibm/emac/mal.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ibm/emac/mal.c @@ -576,7 +576,7 @@ printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", ofdev->dev.of_node); err = -ENODEV; - goto fail; + goto fail_unmap; #endif } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ibm/ibmveth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ibm/ibmveth.c @@ -196,7 +196,7 @@ unsigned long offset; for (offset = 0; offset < length; offset += SMP_CACHE_BYTES) - asm("dcbfl %0,%1" :: "b" (addr), "r" (offset)); + asm("dcbf %0,%1,1" :: "b" (addr), "r" (offset)); } /* replenish the buffers for a pool. note that we don't need to @@ -1317,6 +1317,7 @@ int offset = ibmveth_rxq_frame_offset(adapter); int csum_good = ibmveth_rxq_csum_good(adapter); int lrg_pkt = ibmveth_rxq_large_packet(adapter); + __sum16 iph_check = 0; skb = ibmveth_rxq_get_buffer(adapter); @@ -1353,16 +1354,26 @@ skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); - if (csum_good) { - skb->ip_summed = CHECKSUM_UNNECESSARY; - ibmveth_rx_csum_helper(skb, adapter); + /* PHYP without PLSO support places a -1 in the ip + * checksum for large send frames. + */ + if (skb->protocol == cpu_to_be16(ETH_P_IP)) { + struct iphdr *iph = (struct iphdr *)skb->data; + + iph_check = iph->check; } - if (length > netdev->mtu + ETH_HLEN) { + if ((length > netdev->mtu + ETH_HLEN) || + lrg_pkt || iph_check == 0xffff) { ibmveth_rx_mss_helper(skb, mss, lrg_pkt); adapter->rx_large_packets++; } + if (csum_good) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + ibmveth_rx_csum_helper(skb, adapter); + } + napi_gro_receive(napi, skb); /* send it up */ netdev->stats.rx_packets++; @@ -1682,7 +1693,7 @@ } netdev->min_mtu = IBMVETH_MIN_MTU; - netdev->max_mtu = ETH_MAX_MTU; + netdev->max_mtu = ETH_MAX_MTU - IBMVETH_BUFF_OH; memcpy(netdev->dev_addr, mac_addr_p, ETH_ALEN); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ibm/ibmvnic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ibm/ibmvnic.c @@ -176,7 +176,7 @@ ltb->map_id = adapter->map_id; adapter->map_id++; - init_completion(&adapter->fw_done); + reinit_completion(&adapter->fw_done); rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); if (rc) { @@ -202,8 +202,13 @@ if (!ltb->buff) return; + /* VIOS automatically unmaps the long term buffer at remote + * end for the following resets: + * FAILOVER, MOBILITY, TIMEOUT. + */ if (adapter->reset_reason != VNIC_RESET_FAILOVER && - adapter->reset_reason != VNIC_RESET_MOBILITY) + adapter->reset_reason != VNIC_RESET_MOBILITY && + adapter->reset_reason != VNIC_RESET_TIMEOUT) send_request_unmap(adapter, ltb->map_id); dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); } @@ -215,7 +220,7 @@ memset(ltb->buff, 0, ltb->size); - init_completion(&adapter->fw_done); + reinit_completion(&adapter->fw_done); rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); if (rc) return rc; @@ -416,6 +421,9 @@ int i, j, rc; u64 *size_array; + if (!adapter->rx_pool) + return -1; + size_array = (u64 *)((u8 *)(adapter->login_rsp_buf) + be32_to_cpu(adapter->login_rsp_buf->off_rxadd_buff_size)); @@ -586,6 +594,9 @@ int tx_scrqs; int i, rc; + if (!adapter->tx_pool) + return -1; + tx_scrqs = be32_to_cpu(adapter->login_rsp_buf->num_txsubm_subcrqs); for (i = 0; i < tx_scrqs; i++) { rc = reset_one_tx_pool(adapter, &adapter->tso_pool[i]); @@ -683,8 +694,11 @@ adapter->tso_pool = kcalloc(tx_subcrqs, sizeof(struct ibmvnic_tx_pool), GFP_KERNEL); - if (!adapter->tso_pool) + if (!adapter->tso_pool) { + kfree(adapter->tx_pool); + adapter->tx_pool = NULL; return -1; + } adapter->num_active_tx_pools = tx_subcrqs; @@ -779,12 +793,13 @@ struct ibmvnic_adapter *adapter = netdev_priv(netdev); unsigned long timeout = msecs_to_jiffies(30000); int retry_count = 0; + int retries = 10; bool retry; int rc; do { retry = false; - if (retry_count > IBMVNIC_MAX_QUEUES) { + if (retry_count > retries) { netdev_warn(netdev, "Login attempts exceeded\n"); return -1; } @@ -799,11 +814,23 @@ if (!wait_for_completion_timeout(&adapter->init_done, timeout)) { - netdev_warn(netdev, "Login timed out\n"); - return -1; + netdev_warn(netdev, "Login timed out, retrying...\n"); + retry = true; + adapter->init_done_rc = 0; + retry_count++; + continue; } - if (adapter->init_done_rc == PARTIALSUCCESS) { + if (adapter->init_done_rc == ABORTED) { + netdev_warn(netdev, "Login aborted, retrying...\n"); + retry = true; + adapter->init_done_rc = 0; + retry_count++; + /* FW or device may be busy, so + * wait a bit before retrying login + */ + msleep(500); + } else if (adapter->init_done_rc == PARTIALSUCCESS) { retry_count++; release_sub_crqs(adapter, 1); @@ -846,12 +873,22 @@ static void release_login_buffer(struct ibmvnic_adapter *adapter) { + if (!adapter->login_buf) + return; + + dma_unmap_single(&adapter->vdev->dev, adapter->login_buf_token, + adapter->login_buf_sz, DMA_TO_DEVICE); kfree(adapter->login_buf); adapter->login_buf = NULL; } static void release_login_rsp_buffer(struct ibmvnic_adapter *adapter) { + if (!adapter->login_rsp_buf) + return; + + dma_unmap_single(&adapter->vdev->dev, adapter->login_rsp_buf_token, + adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); kfree(adapter->login_rsp_buf); adapter->login_rsp_buf = NULL; } @@ -943,7 +980,7 @@ if (adapter->vpd->buff) len = adapter->vpd->len; - init_completion(&adapter->fw_done); + reinit_completion(&adapter->fw_done); crq.get_vpd_size.first = IBMVNIC_CRQ_CMD; crq.get_vpd_size.cmd = GET_VPD_SIZE; rc = ibmvnic_send_crq(adapter, &crq); @@ -1057,8 +1094,7 @@ rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP); if (rc) { - for (i = 0; i < adapter->req_rx_queues; i++) - napi_disable(&adapter->napi[i]); + ibmvnic_napi_disable(adapter); release_resources(adapter); return rc; } @@ -1090,18 +1126,27 @@ if (adapter->state != VNIC_CLOSED) { rc = ibmvnic_login(netdev); if (rc) - return rc; + goto out; rc = init_resources(adapter); if (rc) { netdev_err(netdev, "failed to initialize resources\n"); release_resources(adapter); - return rc; + goto out; } } rc = __ibmvnic_open(netdev); +out: + /* + * If open fails due to a pending failover, set device state and + * return. Device operation will be handled by reset routine. + */ + if (rc && adapter->failover_pending) { + adapter->state = VNIC_OPEN; + rc = 0; + } return rc; } @@ -1226,10 +1271,8 @@ adapter->state = VNIC_CLOSING; rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_DN); - if (rc) - return rc; adapter->state = VNIC_CLOSED; - return 0; + return rc; } static int ibmvnic_close(struct net_device *netdev) @@ -1429,8 +1472,6 @@ netdev_tx_t ret = NETDEV_TX_OK; if (test_bit(0, &adapter->resetting)) { - if (!netif_subqueue_stopped(netdev, skb)) - netif_stop_subqueue(netdev, queue_num); dev_kfree_skb_any(skb); tx_send_failed++; @@ -1492,10 +1533,25 @@ skb_copy_from_linear_data(skb, dst, skb->len); } + /* post changes to long_term_buff *dst before VIOS accessing it */ + dma_wmb(); + tx_pool->consumer_index = (tx_pool->consumer_index + 1) % tx_pool->num_buffers; tx_buff = &tx_pool->tx_buff[index]; + + /* Sanity checks on our free map to make sure it points to an index + * that is not being occupied by another skb. If skb memory is + * not freed then we see congestion control kick in and halt tx. + */ + if (unlikely(tx_buff->skb)) { + dev_warn_ratelimited(dev, "TX free map points to untracked skb (%s %d idx=%d)\n", + skb_is_gso(skb) ? "tso_pool" : "tx_pool", + queue_num, index); + dev_kfree_skb_any(tx_buff->skb); + } + tx_buff->skb = skb; tx_buff->data_dma[0] = data_dma_addr; tx_buff->data_len[0] = skb->len; @@ -1689,7 +1745,7 @@ crq.change_mac_addr.cmd = CHANGE_MAC_ADDR; ether_addr_copy(&crq.change_mac_addr.mac_addr[0], dev_addr); - init_completion(&adapter->fw_done); + reinit_completion(&adapter->fw_done); rc = ibmvnic_send_crq(adapter, &crq); if (rc) { rc = -EIO; @@ -1716,6 +1772,9 @@ int rc; rc = 0; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + ether_addr_copy(adapter->mac_addr, addr->sa_data); if (adapter->state != VNIC_PROBED) rc = __ibmvnic_set_mac(netdev, addr->sa_data); @@ -1813,12 +1872,19 @@ u64 old_num_rx_queues, old_num_tx_queues; u64 old_num_rx_slots, old_num_tx_slots; struct net_device *netdev = adapter->netdev; - int i, rc; + int rc; netdev_dbg(adapter->netdev, "Re-setting driver (%d)\n", rwi->reset_reason); rtnl_lock(); + /* + * Now that we have the rtnl lock, clear any pending failover. + * This will ensure ibmvnic_open() has either completed or will + * block until failover is complete. + */ + if (rwi->reset_reason == VNIC_RESET_FAILOVER) + adapter->failover_pending = false; netif_carrier_off(netdev); adapter->reset_reason = rwi->reset_reason; @@ -1865,13 +1931,18 @@ release_sub_crqs(adapter, 1); } else { rc = ibmvnic_reset_crq(adapter); - if (!rc) + if (rc == H_CLOSED || rc == H_SUCCESS) { rc = vio_enable_interrupts(adapter->vdev); + if (rc) + netdev_err(adapter->netdev, + "Reset failed to enable interrupts. rc=%d\n", + rc); + } } if (rc) { netdev_err(adapter->netdev, - "Couldn't initialize crq. rc=%d\n", rc); + "Reset couldn't initialize crq. rc=%d\n", rc); goto out; } @@ -1900,7 +1971,10 @@ adapter->req_rx_add_entries_per_subcrq != old_num_rx_slots || adapter->req_tx_entries_per_subcrq != - old_num_tx_slots) { + old_num_tx_slots || + !adapter->rx_pool || + !adapter->tso_pool || + !adapter->tx_pool) { release_rx_pools(adapter); release_tx_pools(adapter); release_napi(adapter); @@ -1912,12 +1986,18 @@ } else { rc = reset_tx_pools(adapter); - if (rc) + if (rc) { + netdev_dbg(adapter->netdev, "reset tx pools failed (%d)\n", + rc); goto out; + } rc = reset_rx_pools(adapter); - if (rc) + if (rc) { + netdev_dbg(adapter->netdev, "reset rx pools failed (%d)\n", + rc); goto out; + } } ibmvnic_disable_irqs(adapter); } @@ -1937,12 +2017,11 @@ /* refresh device's multicast list */ ibmvnic_set_multi(netdev); - /* kick napi */ - for (i = 0; i < adapter->req_rx_queues; i++) - napi_schedule(&adapter->napi[i]); - - if (adapter->reset_reason != VNIC_RESET_FAILOVER) + if (adapter->reset_reason == VNIC_RESET_FAILOVER || + adapter->reset_reason == VNIC_RESET_MOBILITY) { call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); + call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); + } rc = 0; @@ -2012,6 +2091,9 @@ if (rc) return IBMVNIC_OPEN_FAILED; + call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev); + call_netdevice_notifiers(NETDEV_RESEND_IGMP, netdev); + return 0; } @@ -2075,6 +2157,13 @@ /* CHANGE_PARAM requestor holds rtnl_lock */ rc = do_change_param_reset(adapter, rwi, reset_state); } else if (adapter->force_reset_recovery) { + /* + * Since we are doing a hard reset now, clear the + * failover_pending flag so we don't ignore any + * future MOBILITY or other resets. + */ + adapter->failover_pending = false; + /* Transport event occurred during previous reset */ if (adapter->wait_for_reset) { /* Previous was CHANGE_PARAM; caller locked */ @@ -2138,9 +2227,15 @@ unsigned long flags; int ret; + /* + * If failover is pending don't schedule any other reset. + * Instead let the failover complete. If there is already a + * a failover reset scheduled, we will detect and drop the + * duplicate reset when walking the ->rwi_list below. + */ if (adapter->state == VNIC_REMOVING || adapter->state == VNIC_REMOVED || - adapter->failover_pending) { + (adapter->failover_pending && reason != VNIC_RESET_FAILOVER)) { ret = EBUSY; netdev_dbg(netdev, "Adapter removing or pending failover, skipping reset\n"); goto err; @@ -2175,8 +2270,10 @@ * flush reset queue and process this reset */ if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) { - list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) + list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) { list_del(entry); + kfree(list_entry(entry, struct ibmvnic_rwi, list)); + } } rwi->reset_reason = reason; list_add_tail(&rwi->list, &adapter->rwi_list); @@ -2193,6 +2290,12 @@ { struct ibmvnic_adapter *adapter = netdev_priv(dev); + if (test_bit(0, &adapter->resetting)) { + netdev_err(adapter->netdev, + "Adapter is resetting, skip timeout reset\n"); + return; + } + ibmvnic_reset(adapter, VNIC_RESET_TIMEOUT); } @@ -2234,6 +2337,12 @@ if (!pending_scrq(adapter, adapter->rx_scrq[scrq_num])) break; + /* The queue entry at the current index is peeked at above + * to determine that there is a valid descriptor awaiting + * processing. We want to be sure that the current slot + * holds a valid descriptor before reading its contents. + */ + dma_rmb(); next = ibmvnic_next_scrq(adapter, adapter->rx_scrq[scrq_num]); rx_buff = (struct ibmvnic_rx_buff *)be64_to_cpu(next-> @@ -2258,6 +2367,8 @@ offset = be16_to_cpu(next->rx_comp.off_frame_data); flags = next->rx_comp.flags; skb = rx_buff->skb; + /* load long_term_buff before copying to skb */ + dma_rmb(); skb_copy_to_linear_data(skb, rx_buff->data + offset, length); @@ -2316,7 +2427,7 @@ adapter->fallback.rx_entries = adapter->req_rx_add_entries_per_subcrq; adapter->fallback.tx_entries = adapter->req_tx_entries_per_subcrq; - init_completion(&adapter->reset_done); + reinit_completion(&adapter->reset_done); adapter->wait_for_reset = true; rc = ibmvnic_reset(adapter, VNIC_RESET_CHANGE_PARAM); if (rc) @@ -2332,7 +2443,7 @@ adapter->desired.rx_entries = adapter->fallback.rx_entries; adapter->desired.tx_entries = adapter->fallback.tx_entries; - init_completion(&adapter->reset_done); + reinit_completion(&adapter->reset_done); adapter->wait_for_reset = true; rc = ibmvnic_reset(adapter, VNIC_RESET_CHANGE_PARAM); if (rc) @@ -2603,7 +2714,7 @@ cpu_to_be32(sizeof(struct ibmvnic_statistics)); /* Wait for data to be written */ - init_completion(&adapter->stats_done); + reinit_completion(&adapter->stats_done); rc = ibmvnic_send_crq(adapter, &crq); if (rc) return; @@ -2694,6 +2805,9 @@ { int i, rc; + if (!adapter->tx_scrq || !adapter->rx_scrq) + return -EINVAL; + for (i = 0; i < adapter->req_tx_queues; i++) { netdev_dbg(adapter->netdev, "Re-setting tx_scrq[%d]\n", i); rc = reset_one_sub_crq_queue(adapter, adapter->tx_scrq[i]); @@ -2912,13 +3026,18 @@ unsigned int pool = scrq->pool_index; int num_entries = 0; + /* The queue entry at the current index is peeked at above + * to determine that there is a valid descriptor awaiting + * processing. We want to be sure that the current slot + * holds a valid descriptor before reading its contents. + */ + dma_rmb(); + next = ibmvnic_next_scrq(adapter, scrq); for (i = 0; i < next->tx_comp.num_comps; i++) { - if (next->tx_comp.rcs[i]) { + if (next->tx_comp.rcs[i]) dev_err(dev, "tx error %x\n", next->tx_comp.rcs[i]); - continue; - } index = be32_to_cpu(next->tx_comp.correlators[i]); if (index & IBMVNIC_TSO_POOL_MASK) { tx_pool = &adapter->tso_pool[pool]; @@ -3067,7 +3186,7 @@ req_tx_irq_failed: for (j = 0; j < i; j++) { free_irq(adapter->tx_scrq[j]->irq, adapter->tx_scrq[j]); - irq_dispose_mapping(adapter->rx_scrq[j]->irq); + irq_dispose_mapping(adapter->tx_scrq[j]->irq); } release_sub_crqs(adapter, 1); return rc; @@ -3163,11 +3282,25 @@ struct device *dev = &adapter->vdev->dev; union ibmvnic_crq crq; int max_entries; + int cap_reqs; + + /* We send out 6 or 7 REQUEST_CAPABILITY CRQs below (depending on + * the PROMISC flag). Initialize this count upfront. When the tasklet + * receives a response to all of these, it will send the next protocol + * message (QUERY_IP_OFFLOAD). + */ + if (!(adapter->netdev->flags & IFF_PROMISC) || + adapter->promisc_supported) + cap_reqs = 7; + else + cap_reqs = 6; if (!retry) { /* Sub-CRQ entries are 32 byte long */ int entries_page = 4 * PAGE_SIZE / (sizeof(u64) * 4); + atomic_set(&adapter->running_cap_crqs, cap_reqs); + if (adapter->min_tx_entries_per_subcrq > entries_page || adapter->min_rx_add_entries_per_subcrq > entries_page) { dev_err(dev, "Fatal, invalid entries per sub-crq\n"); @@ -3228,44 +3361,45 @@ adapter->opt_rx_comp_queues; adapter->req_rx_add_queues = adapter->max_rx_add_queues; + } else { + atomic_add(cap_reqs, &adapter->running_cap_crqs); } - memset(&crq, 0, sizeof(crq)); crq.request_capability.first = IBMVNIC_CRQ_CMD; crq.request_capability.cmd = REQUEST_CAPABILITY; crq.request_capability.capability = cpu_to_be16(REQ_TX_QUEUES); crq.request_capability.number = cpu_to_be64(adapter->req_tx_queues); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); crq.request_capability.capability = cpu_to_be16(REQ_RX_QUEUES); crq.request_capability.number = cpu_to_be64(adapter->req_rx_queues); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_QUEUES); crq.request_capability.number = cpu_to_be64(adapter->req_rx_add_queues); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); crq.request_capability.capability = cpu_to_be16(REQ_TX_ENTRIES_PER_SUBCRQ); crq.request_capability.number = cpu_to_be64(adapter->req_tx_entries_per_subcrq); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); crq.request_capability.capability = cpu_to_be16(REQ_RX_ADD_ENTRIES_PER_SUBCRQ); crq.request_capability.number = cpu_to_be64(adapter->req_rx_add_entries_per_subcrq); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); crq.request_capability.capability = cpu_to_be16(REQ_MTU); crq.request_capability.number = cpu_to_be64(adapter->req_mtu); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); if (adapter->netdev->flags & IFF_PROMISC) { @@ -3273,16 +3407,21 @@ crq.request_capability.capability = cpu_to_be16(PROMISC_REQUESTED); crq.request_capability.number = cpu_to_be64(1); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); } } else { crq.request_capability.capability = cpu_to_be16(PROMISC_REQUESTED); crq.request_capability.number = cpu_to_be64(0); - atomic_inc(&adapter->running_cap_crqs); + cap_reqs--; ibmvnic_send_crq(adapter, &crq); } + + /* Keep at end to catch any discrepancy between expected and actual + * CRQs sent. + */ + WARN_ON(cap_reqs != 0); } static int pending_scrq(struct ibmvnic_adapter *adapter, @@ -3312,6 +3451,11 @@ } spin_unlock_irqrestore(&scrq->lock, flags); + /* Ensure that the entire buffer descriptor has been + * loaded before reading its contents + */ + dma_rmb(); + return entry; } @@ -3682,118 +3826,132 @@ static void send_cap_queries(struct ibmvnic_adapter *adapter) { union ibmvnic_crq crq; + int cap_reqs; + + /* We send out 25 QUERY_CAPABILITY CRQs below. Initialize this count + * upfront. When the tasklet receives a response to all of these, it + * can send out the next protocol messaage (REQUEST_CAPABILITY). + */ + cap_reqs = 25; + + atomic_set(&adapter->running_cap_crqs, cap_reqs); - atomic_set(&adapter->running_cap_crqs, 0); memset(&crq, 0, sizeof(crq)); crq.query_capability.first = IBMVNIC_CRQ_CMD; crq.query_capability.cmd = QUERY_CAPABILITY; crq.query_capability.capability = cpu_to_be16(MIN_TX_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MIN_RX_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_TX_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_RX_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MIN_TX_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MIN_RX_ADD_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_TX_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_RX_ADD_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(TCP_IP_OFFLOAD); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(PROMISC_SUPPORTED); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MIN_MTU); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_MTU); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_MULTICAST_FILTERS); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(VLAN_HEADER_INSERTION); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(RX_VLAN_HEADER_INSERTION); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(MAX_TX_SG_ENTRIES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(RX_SG_SUPPORTED); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(OPT_TX_COMP_SUB_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(OPT_RX_COMP_QUEUES); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(OPT_RX_BUFADD_Q_PER_RX_COMP_Q); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(OPT_TX_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(OPT_RXBA_ENTRIES_PER_SUBCRQ); - atomic_inc(&adapter->running_cap_crqs); ibmvnic_send_crq(adapter, &crq); + cap_reqs--; crq.query_capability.capability = cpu_to_be16(TX_RX_DESC_REQ); - atomic_inc(&adapter->running_cap_crqs); + ibmvnic_send_crq(adapter, &crq); + cap_reqs--; + + /* Keep at end to catch any discrepancy between expected and actual + * CRQs sent. + */ + WARN_ON(cap_reqs != 0); } static void handle_vpd_size_rsp(union ibmvnic_crq *crq, @@ -4040,8 +4198,13 @@ dev_err(dev, "Error %ld in CHANGE_MAC_ADDR_RSP\n", rc); goto out; } + /* crq->change_mac_addr.mac_addr is the requested one + * crq->change_mac_addr_rsp.mac_addr is the returned valid one. + */ ether_addr_copy(netdev->dev_addr, &crq->change_mac_addr_rsp.mac_addr[0]); + ether_addr_copy(adapter->mac_addr, + &crq->change_mac_addr_rsp.mac_addr[0]); out: complete(&adapter->fw_done); return rc; @@ -4055,6 +4218,8 @@ char *name; atomic_dec(&adapter->running_cap_crqs); + netdev_dbg(adapter->netdev, "Outstanding request-caps: %d\n", + atomic_read(&adapter->running_cap_crqs)); switch (be16_to_cpu(crq->request_capability_rsp.capability)) { case REQ_TX_QUEUES: req_value = &adapter->req_tx_queues; @@ -4155,11 +4320,6 @@ struct ibmvnic_login_buffer *login = adapter->login_buf; int i; - dma_unmap_single(dev, adapter->login_buf_token, adapter->login_buf_sz, - DMA_TO_DEVICE); - dma_unmap_single(dev, adapter->login_rsp_buf_token, - adapter->login_rsp_buf_sz, DMA_FROM_DEVICE); - /* If the number of queues requested can't be allocated by the * server, the login response will return with code 1. We will need * to resend the login buffer with fewer queues requested. @@ -4170,6 +4330,14 @@ return 0; } + if (adapter->failover_pending) { + adapter->init_done_rc = -EAGAIN; + netdev_dbg(netdev, "Failover pending, ignoring login response\n"); + complete(&adapter->init_done); + /* login response buffer will be released on reset */ + return 0; + } + netdev->mtu = adapter->req_mtu - ETH_HLEN; netdev_dbg(adapter->netdev, "Login Response Buffer:\n"); @@ -4408,7 +4576,7 @@ memset(&crq, 0, sizeof(crq)); crq.query_phys_parms.first = IBMVNIC_CRQ_CMD; crq.query_phys_parms.cmd = QUERY_PHYS_PARMS; - init_completion(&adapter->fw_done); + reinit_completion(&adapter->fw_done); rc = ibmvnic_send_crq(adapter, &crq); if (rc) return rc; @@ -4438,7 +4606,7 @@ case IBMVNIC_1GBPS: adapter->speed = SPEED_1000; break; - case IBMVNIC_10GBP: + case IBMVNIC_10GBPS: adapter->speed = SPEED_10000; break; case IBMVNIC_25GBPS: @@ -4453,6 +4621,9 @@ case IBMVNIC_100GBPS: adapter->speed = SPEED_100000; break; + case IBMVNIC_200GBPS: + adapter->speed = SPEED_200000; + break; default: if (netif_carrier_ok(netdev)) netdev_warn(netdev, "Unknown speed 0x%08x\n", rspeed); @@ -4486,12 +4657,26 @@ case IBMVNIC_CRQ_INIT: dev_info(dev, "Partner initialized\n"); adapter->from_passive_init = true; - adapter->failover_pending = false; if (!completion_done(&adapter->init_done)) { complete(&adapter->init_done); adapter->init_done_rc = -EIO; } - ibmvnic_reset(adapter, VNIC_RESET_FAILOVER); + rc = ibmvnic_reset(adapter, VNIC_RESET_FAILOVER); + if (rc && rc != -EBUSY) { + /* We were unable to schedule the failover + * reset either because the adapter was still + * probing (eg: during kexec) or we could not + * allocate memory. Clear the failover_pending + * flag since no one else will. We ignore + * EBUSY because it means either FAILOVER reset + * is already scheduled or the adapter is + * being removed. + */ + netdev_err(netdev, + "Error %ld scheduling failover reset\n", + rc); + adapter->failover_pending = false; + } break; case IBMVNIC_CRQ_INIT_COMPLETE: dev_info(dev, "Partner initialization complete\n"); @@ -4535,12 +4720,10 @@ dev_err(dev, "Error %ld in VERSION_EXCHG_RSP\n", rc); break; } - dev_info(dev, "Partner protocol version is %d\n", - crq->version_exchange_rsp.version); - if (be16_to_cpu(crq->version_exchange_rsp.version) < - ibmvnic_version) - ibmvnic_version = + ibmvnic_version = be16_to_cpu(crq->version_exchange_rsp.version); + dev_info(dev, "Partner protocol version is %d\n", + ibmvnic_version); send_cap_queries(adapter); break; case QUERY_CAPABILITY_RSP: @@ -4650,15 +4833,15 @@ while (!done) { /* Pull all the valid messages off the CRQ */ while ((crq = ibmvnic_next_crq(adapter)) != NULL) { + /* This barrier makes sure ibmvnic_next_crq()'s + * crq->generic.first & IBMVNIC_CRQ_CMD_RSP is loaded + * before ibmvnic_handle_crq()'s + * switch(gen_crq->first) and switch(gen_crq->cmd). + */ + dma_rmb(); ibmvnic_handle_crq(crq, adapter); crq->generic.first = 0; } - - /* remain in tasklet until all - * capabilities responses are received - */ - if (!adapter->wait_capability) - done = true; } /* if capabilities CRQ's were sent in this tasklet, the following * tasklet must wait until all responses are received @@ -4696,6 +4879,9 @@ } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); /* Clean out the queue */ + if (!crq->msgs) + return -EINVAL; + memset(crq->msgs, 0, PAGE_SIZE); crq->cur = 0; crq->active = false; @@ -4797,6 +4983,9 @@ crq->cur = 0; spin_lock_init(&crq->lock); + /* process any CRQs that were queued before we enabled interrupts */ + tasklet_schedule(&adapter->tasklet); + return retrc; req_irq_failed: @@ -4850,6 +5039,15 @@ release_sub_crqs(adapter, 0); rc = init_sub_crqs(adapter); } else { + /* no need to reinitialize completely, but we do + * need to clean up transmits that were in flight + * when we processed the reset. Failure to do so + * will confound the upper layer, usually TCP, by + * creating the illusion of transmits that are + * awaiting completion. + */ + clean_tx_pools(adapter); + rc = reset_sub_crq_queues(adapter); } } else { @@ -4960,6 +5158,9 @@ INIT_LIST_HEAD(&adapter->rwi_list); spin_lock_init(&adapter->rwi_lock); init_completion(&adapter->init_done); + init_completion(&adapter->fw_done); + init_completion(&adapter->reset_done); + init_completion(&adapter->stats_done); clear_bit(0, &adapter->resetting); do { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ibm/ibmvnic.h +++ linux-oracle-5.4.0/drivers/net/ethernet/ibm/ibmvnic.h @@ -373,7 +373,7 @@ #define IBMVNIC_10MBPS 0x40000000 #define IBMVNIC_100MBPS 0x20000000 #define IBMVNIC_1GBPS 0x10000000 -#define IBMVNIC_10GBP 0x08000000 +#define IBMVNIC_10GBPS 0x08000000 #define IBMVNIC_40GBPS 0x04000000 #define IBMVNIC_100GBPS 0x02000000 #define IBMVNIC_25GBPS 0x01000000 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e100.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e100.c @@ -1398,7 +1398,7 @@ u8 phy_type; int without_mii; - phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; + phy_type = (le16_to_cpu(nic->eeprom[eeprom_phy_iface]) >> 8) & 0x0f; switch (phy_type) { case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ @@ -1518,7 +1518,7 @@ mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && - (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { + (le16_to_cpu(nic->eeprom[eeprom_cnfg_mdix]) & eeprom_mdix_enabled))) { /* enable/disable MDI/MDI-X auto-switching. */ mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); @@ -2266,9 +2266,9 @@ { /* ASF can be enabled from eeprom */ return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && - (nic->eeprom[eeprom_config_asf] & eeprom_asf) && - !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && - ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE); + (le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_asf) && + !(le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_gcl) && + ((le16_to_cpu(nic->eeprom[eeprom_smbus_addr]) & 0xFF) != 0xFE); } static int e100_up(struct nic *nic) @@ -2435,11 +2435,15 @@ sizeof(info->bus_info)); } -#define E100_PHY_REGS 0x1C +#define E100_PHY_REGS 0x1D static int e100_get_regs_len(struct net_device *netdev) { struct nic *nic = netdev_priv(netdev); - return 1 + E100_PHY_REGS + sizeof(nic->mem->dump_buf); + + /* We know the number of registers, and the size of the dump buffer. + * Calculate the total size in bytes. + */ + return (1 + E100_PHY_REGS) * sizeof(u32) + sizeof(nic->mem->dump_buf); } static void e100_get_regs(struct net_device *netdev, @@ -2453,14 +2457,18 @@ buff[0] = ioread8(&nic->csr->scb.cmd_hi) << 24 | ioread8(&nic->csr->scb.cmd_lo) << 16 | ioread16(&nic->csr->scb.status); - for (i = E100_PHY_REGS; i >= 0; i--) - buff[1 + E100_PHY_REGS - i] = - mdio_read(netdev, nic->mii.phy_id, i); + for (i = 0; i < E100_PHY_REGS; i++) + /* Note that we read the registers in reverse order. This + * ordering is the ABI apparently used by ethtool and other + * applications. + */ + buff[1 + i] = mdio_read(netdev, nic->mii.phy_id, + E100_PHY_REGS - 1 - i); memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf)); e100_exec_cb(nic, NULL, e100_dump); msleep(10); - memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf, - sizeof(nic->mem->dump_buf)); + memcpy(&buff[1 + E100_PHY_REGS], nic->mem->dump_buf, + sizeof(nic->mem->dump_buf)); } static void e100_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) @@ -2924,7 +2932,7 @@ /* Wol magic packet can be enabled from eeprom */ if ((nic->mac >= mac_82558_D101_A4) && - (nic->eeprom[eeprom_id] & eeprom_id_wol)) { + (le16_to_cpu(nic->eeprom[eeprom_id]) & eeprom_id_wol)) { nic->flags |= wol_magic; device_set_wakeup_enable(&pdev->dev, true); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000/e1000_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -542,8 +542,13 @@ WARN_ON(in_interrupt()); while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) msleep(1); - e1000_down(adapter); - e1000_up(adapter); + + /* only run the task if not already down */ + if (!test_bit(__E1000_DOWN, &adapter->flags)) { + e1000_down(adapter); + e1000_up(adapter); + } + clear_bit(__E1000_RESETTING, &adapter->flags); } @@ -1433,10 +1438,15 @@ struct e1000_hw *hw = &adapter->hw; int count = E1000_CHECK_RESET_COUNT; - while (test_bit(__E1000_RESETTING, &adapter->flags) && count--) + while (test_and_set_bit(__E1000_RESETTING, &adapter->flags) && count--) usleep_range(10000, 20000); - WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); + WARN_ON(count < 0); + + /* signal that we're down so that the reset task will no longer run */ + set_bit(__E1000_DOWN, &adapter->flags); + clear_bit(__E1000_RESETTING, &adapter->flags); + e1000_down(adapter); e1000_power_down_phy(adapter); e1000_free_irq(adapter); @@ -3140,8 +3150,9 @@ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); if (skb->data_len && hdr_len == len) { switch (hw->mac_type) { + case e1000_82544: { unsigned int pull_size; - case e1000_82544: + /* Make sure we have room to chop off 4 bytes, * and that the end alignment will work out to * this hardware's requirements @@ -3162,6 +3173,7 @@ } len = skb_headlen(skb); break; + } default: /* do nothing */ break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/82571.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/82571.c @@ -899,6 +899,8 @@ } else { data &= ~IGP02E1000_PM_D0_LPLU; ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); + if (ret_val) + return ret_val; /* LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most * important. During driver activity we should enable --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/e1000.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/e1000.h @@ -185,13 +185,12 @@ /* board specific private data structure */ struct e1000_adapter { + struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct timer_list blink_timer; struct work_struct reset_task; - struct delayed_work watchdog_task; - - struct workqueue_struct *e1000_workqueue; + struct work_struct watchdog_task; const struct e1000_info *ei; @@ -577,7 +576,6 @@ #define er32(reg) __er32(hw, E1000_##reg) -s32 __ew32_prepare(struct e1000_hw *hw); void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val); #define ew32(reg, val) __ew32(hw, E1000_##reg, (val)) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/hw.h @@ -86,6 +86,12 @@ #define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0 #define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1 #define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2 +#define E1000_DEV_ID_PCH_CMP_I219_LM10 0x0D4E +#define E1000_DEV_ID_PCH_CMP_I219_V10 0x0D4F +#define E1000_DEV_ID_PCH_CMP_I219_LM11 0x0D4C +#define E1000_DEV_ID_PCH_CMP_I219_V11 0x0D4D +#define E1000_DEV_ID_PCH_CMP_I219_LM12 0x0D53 +#define E1000_DEV_ID_PCH_CMP_I219_V12 0x0D55 #define E1000_REVISION_4 4 @@ -662,6 +668,7 @@ bool kmrn_lock_loss_workaround_enabled; struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; bool nvm_k1_enabled; + bool disable_k1_off; bool eee_disable; u16 eee_lp_ability; enum e1000_ulp_state ulp_state; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -995,6 +995,8 @@ { u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) | link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND; + u32 max_ltr_enc_d = 0; /* maximum LTR decoded by platform */ + u32 lat_enc_d = 0; /* latency decoded */ u16 lat_enc = 0; /* latency encoded */ if (link) { @@ -1048,7 +1050,17 @@ E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop); max_ltr_enc = max_t(u16, max_snoop, max_nosnoop); - if (lat_enc > max_ltr_enc) + lat_enc_d = (lat_enc & E1000_LTRV_VALUE_MASK) * + (1U << (E1000_LTRV_SCALE_FACTOR * + ((lat_enc & E1000_LTRV_SCALE_MASK) + >> E1000_LTRV_SCALE_SHIFT))); + + max_ltr_enc_d = (max_ltr_enc & E1000_LTRV_VALUE_MASK) * + (1U << (E1000_LTRV_SCALE_FACTOR * + ((max_ltr_enc & E1000_LTRV_SCALE_MASK) + >> E1000_LTRV_SCALE_SHIFT))); + + if (lat_enc_d > max_ltr_enc_d) lat_enc = max_ltr_enc; } @@ -1237,9 +1249,9 @@ ew32(H2ME, mac_reg); } - /* Poll up to 300msec for ME to clear ULP_CFG_DONE. */ + /* Poll up to 2.5sec for ME to clear ULP_CFG_DONE. */ while (er32(FWSM) & E1000_FWSM_ULP_CFG_DONE) { - if (i++ == 30) { + if (i++ == 250) { ret_val = -E1000_ERR_PHY; goto out; } @@ -1538,6 +1550,9 @@ fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; } + if (hw->dev_spec.ich8lan.disable_k1_off == true) + fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE; + ew32(FEXTNVM6, fextnvm6); } @@ -4084,13 +4099,17 @@ return ret_val; if (!(data & valid_csum_mask)) { - data |= valid_csum_mask; - ret_val = e1000_write_nvm(hw, word, 1, &data); - if (ret_val) - return ret_val; - ret_val = e1000e_update_nvm_checksum(hw); - if (ret_val) - return ret_val; + e_dbg("NVM Checksum Invalid\n"); + + if (hw->mac.type < e1000_pch_cnp) { + data |= valid_csum_mask; + ret_val = e1000_write_nvm(hw, word, 1, &data); + if (ret_val) + return ret_val; + ret_val = e1000e_update_nvm_checksum(hw); + if (ret_val) + return ret_val; + } } return e1000e_validate_nvm_checksum_generic(hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -274,8 +274,11 @@ /* Latency Tolerance Reporting */ #define E1000_LTRV 0x000F8 +#define E1000_LTRV_VALUE_MASK 0x000003FF #define E1000_LTRV_SCALE_MAX 5 #define E1000_LTRV_SCALE_FACTOR 5 +#define E1000_LTRV_SCALE_SHIFT 10 +#define E1000_LTRV_SCALE_MASK 0x00001C00 #define E1000_LTRV_REQ_SHIFT 15 #define E1000_LTRV_NOSNOOP_SHIFT 16 #define E1000_LTRV_SEND (1 << 30) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/netdev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/netdev.c @@ -119,14 +119,12 @@ * has bit 24 set while ME is accessing MAC CSR registers, wait if it is set * and try again a number of times. **/ -s32 __ew32_prepare(struct e1000_hw *hw) +static void __ew32_prepare(struct e1000_hw *hw) { s32 i = E1000_ICH_FWSM_PCIM2PCI_COUNT; while ((er32(FWSM) & E1000_ICH_FWSM_PCIM2PCI) && --i) udelay(50); - - return i; } void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val) @@ -607,11 +605,11 @@ { struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - s32 ret_val = __ew32_prepare(hw); + __ew32_prepare(hw); writel(i, rx_ring->tail); - if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) { + if (unlikely(i != readl(rx_ring->tail))) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); @@ -624,11 +622,11 @@ { struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - s32 ret_val = __ew32_prepare(hw); + __ew32_prepare(hw); writel(i, tx_ring->tail); - if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) { + if (unlikely(i != readl(tx_ring->tail))) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); @@ -1780,8 +1778,7 @@ } /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->state)) - mod_delayed_work(adapter->e1000_workqueue, - &adapter->watchdog_task, HZ); + mod_timer(&adapter->watchdog_timer, jiffies + 1); } /* Reset on uncorrectable ECC error */ @@ -1861,8 +1858,7 @@ } /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->state)) - mod_delayed_work(adapter->e1000_workqueue, - &adapter->watchdog_task, HZ); + mod_timer(&adapter->watchdog_timer, jiffies + 1); } /* Reset on uncorrectable ECC error */ @@ -1907,8 +1903,7 @@ hw->mac.get_link_status = true; /* guard against interrupt when we're going down */ if (!test_bit(__E1000_DOWN, &adapter->state)) - mod_delayed_work(adapter->e1000_workqueue, - &adapter->watchdog_task, HZ); + mod_timer(&adapter->watchdog_timer, jiffies + 1); } if (!test_bit(__E1000_DOWN, &adapter->state)) @@ -4281,6 +4276,7 @@ napi_synchronize(&adapter->napi); + del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); spin_lock(&adapter->stats64_lock); @@ -4715,12 +4711,12 @@ pm_runtime_get_sync(&pdev->dev); - if (!test_bit(__E1000_DOWN, &adapter->state)) { + if (netif_device_present(netdev)) { e1000e_down(adapter, true); e1000_free_irq(adapter); /* Link status message must follow this format */ - pr_info("%s NIC Link is Down\n", adapter->netdev->name); + pr_info("%s NIC Link is Down\n", netdev->name); } napi_disable(&adapter->napi); @@ -5152,11 +5148,25 @@ } } +/** + * e1000_watchdog - Timer Call-back + * @data: pointer to adapter cast into an unsigned long + **/ +static void e1000_watchdog(struct timer_list *t) +{ + struct e1000_adapter *adapter = from_timer(adapter, t, watchdog_timer); + + /* Do the rest outside of interrupt context */ + schedule_work(&adapter->watchdog_task); + + /* TODO: make this use queue_delayed_work() */ +} + static void e1000_watchdog_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, - watchdog_task.work); + watchdog_task); struct net_device *netdev = adapter->netdev; struct e1000_mac_info *mac = &adapter->hw.mac; struct e1000_phy_info *phy = &adapter->hw.phy; @@ -5189,18 +5199,20 @@ pm_runtime_resume(netdev->dev.parent); /* Checking if MAC is in DMoff state*/ - pcim_state = er32(STATUS); - while (pcim_state & E1000_STATUS_PCIM_STATE) { - if (tries++ == dmoff_exit_timeout) { - e_dbg("Error in exiting dmoff\n"); - break; - } - usleep_range(10000, 20000); + if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { pcim_state = er32(STATUS); - - /* Checking if MAC exited DMoff state */ - if (!(pcim_state & E1000_STATUS_PCIM_STATE)) - e1000_phy_hw_reset(&adapter->hw); + while (pcim_state & E1000_STATUS_PCIM_STATE) { + if (tries++ == dmoff_exit_timeout) { + e_dbg("Error in exiting dmoff\n"); + break; + } + usleep_range(10000, 20000); + pcim_state = er32(STATUS); + + /* Checking if MAC exited DMoff state */ + if (!(pcim_state & E1000_STATUS_PCIM_STATE)) + e1000_phy_hw_reset(&adapter->hw); + } } /* update snapshot of PHY registers on LSC */ @@ -5258,27 +5270,6 @@ ew32(TARC(0), tarc0); } - /* disable TSO for pcie and 10/100 speeds, to avoid - * some hardware issues - */ - if (!(adapter->flags & FLAG_TSO_FORCE)) { - switch (adapter->link_speed) { - case SPEED_10: - case SPEED_100: - e_info("10/100 speed: disabling TSO\n"); - netdev->features &= ~NETIF_F_TSO; - netdev->features &= ~NETIF_F_TSO6; - break; - case SPEED_1000: - netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - break; - default: - /* oops */ - break; - } - } - /* enable transmits in the hardware, need to do this * after setting TARC(0) */ @@ -5404,9 +5395,8 @@ /* Reset the timer */ if (!test_bit(__E1000_DOWN, &adapter->state)) - queue_delayed_work(adapter->e1000_workqueue, - &adapter->watchdog_task, - round_jiffies(2 * HZ)); + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + 2 * HZ)); } #define E1000_TX_FLAGS_CSUM 0x00000001 @@ -5901,9 +5891,9 @@ e1000_tx_queue(tx_ring, tx_flags, count); /* Make sure there is space in the ring for the next send. */ e1000_maybe_stop_tx(tx_ring, - (MAX_SKB_FRAGS * + ((MAX_SKB_FRAGS + 1) * DIV_ROUND_UP(PAGE_SIZE, - adapter->tx_fifo_limit) + 2)); + adapter->tx_fifo_limit) + 4)); if (!netdev_xmit_more() || netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) { @@ -5940,15 +5930,19 @@ struct e1000_adapter *adapter; adapter = container_of(work, struct e1000_adapter, reset_task); + rtnl_lock(); /* don't run the task if already down */ - if (test_bit(__E1000_DOWN, &adapter->state)) + if (test_bit(__E1000_DOWN, &adapter->state)) { + rtnl_unlock(); return; + } if (!(adapter->flags & FLAG_RESTART_NOW)) { e1000e_dump(adapter); e_err("Reset adapter unexpectedly\n"); } e1000e_reinit_locked(adapter); + rtnl_unlock(); } /** @@ -6294,14 +6288,186 @@ pm_runtime_put_sync(netdev->dev.parent); } +/* S0ix implementation */ +static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mac_data; + u16 phy_data; + + /* Disable the periodic inband message, + * don't request PCIe clock in K1 page770_17[10:9] = 10b + */ + e1e_rphy(hw, HV_PM_CTRL, &phy_data); + phy_data &= ~HV_PM_CTRL_K1_CLK_REQ; + phy_data |= BIT(10); + e1e_wphy(hw, HV_PM_CTRL, phy_data); + + /* Make sure we don't exit K1 every time a new packet arrives + * 772_29[5] = 1 CS_Mode_Stay_In_K1 + */ + e1e_rphy(hw, I217_CGFREG, &phy_data); + phy_data |= BIT(5); + e1e_wphy(hw, I217_CGFREG, phy_data); + + /* Change the MAC/PHY interface to SMBus + * Force the SMBus in PHY page769_23[0] = 1 + * Force the SMBus in MAC CTRL_EXT[11] = 1 + */ + e1e_rphy(hw, CV_SMB_CTRL, &phy_data); + phy_data |= CV_SMB_CTRL_FORCE_SMBUS; + e1e_wphy(hw, CV_SMB_CTRL, phy_data); + mac_data = er32(CTRL_EXT); + mac_data |= E1000_CTRL_EXT_FORCE_SMBUS; + ew32(CTRL_EXT, mac_data); + + /* DFT control: PHY bit: page769_20[0] = 1 + * Gate PPW via EXTCNF_CTRL - set 0x0F00[7] = 1 + */ + e1e_rphy(hw, I82579_DFT_CTRL, &phy_data); + phy_data |= BIT(0); + e1e_wphy(hw, I82579_DFT_CTRL, phy_data); + + mac_data = er32(EXTCNF_CTRL); + mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG; + ew32(EXTCNF_CTRL, mac_data); + + /* Check MAC Tx/Rx packet buffer pointers. + * Reset MAC Tx/Rx packet buffer pointers to suppress any + * pending traffic indication that would prevent power gating. + */ + mac_data = er32(TDFH); + if (mac_data) + ew32(TDFH, 0); + mac_data = er32(TDFT); + if (mac_data) + ew32(TDFT, 0); + mac_data = er32(TDFHS); + if (mac_data) + ew32(TDFHS, 0); + mac_data = er32(TDFTS); + if (mac_data) + ew32(TDFTS, 0); + mac_data = er32(TDFPC); + if (mac_data) + ew32(TDFPC, 0); + mac_data = er32(RDFH); + if (mac_data) + ew32(RDFH, 0); + mac_data = er32(RDFT); + if (mac_data) + ew32(RDFT, 0); + mac_data = er32(RDFHS); + if (mac_data) + ew32(RDFHS, 0); + mac_data = er32(RDFTS); + if (mac_data) + ew32(RDFTS, 0); + mac_data = er32(RDFPC); + if (mac_data) + ew32(RDFPC, 0); + + /* Enable the Dynamic Power Gating in the MAC */ + mac_data = er32(FEXTNVM7); + mac_data |= BIT(22); + ew32(FEXTNVM7, mac_data); + + /* Disable the time synchronization clock */ + mac_data = er32(FEXTNVM7); + mac_data |= BIT(31); + mac_data &= ~BIT(0); + ew32(FEXTNVM7, mac_data); + + /* Dynamic Power Gating Enable */ + mac_data = er32(CTRL_EXT); + mac_data |= BIT(3); + ew32(CTRL_EXT, mac_data); + + /* Enable the Dynamic Clock Gating in the DMA and MAC */ + mac_data = er32(CTRL_EXT); + mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN; + ew32(CTRL_EXT, mac_data); + + /* No MAC DPG gating SLP_S0 in modern standby + * Switch the logic of the lanphypc to use PMC counter + */ + mac_data = er32(FEXTNVM5); + mac_data |= BIT(7); + ew32(FEXTNVM5, mac_data); +} + +static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mac_data; + u16 phy_data; + + /* Disable the Dynamic Power Gating in the MAC */ + mac_data = er32(FEXTNVM7); + mac_data &= 0xFFBFFFFF; + ew32(FEXTNVM7, mac_data); + + /* Enable the time synchronization clock */ + mac_data = er32(FEXTNVM7); + mac_data |= BIT(0); + ew32(FEXTNVM7, mac_data); + + /* Disable Dynamic Power Gating */ + mac_data = er32(CTRL_EXT); + mac_data &= 0xFFFFFFF7; + ew32(CTRL_EXT, mac_data); + + /* Disable the Dynamic Clock Gating in the DMA and MAC */ + mac_data = er32(CTRL_EXT); + mac_data &= 0xFFF7FFFF; + ew32(CTRL_EXT, mac_data); + + /* Revert the lanphypc logic to use the internal Gbe counter + * and not the PMC counter + */ + mac_data = er32(FEXTNVM5); + mac_data &= 0xFFFFFF7F; + ew32(FEXTNVM5, mac_data); + + /* Enable the periodic inband message, + * Request PCIe clock in K1 page770_17[10:9] =01b + */ + e1e_rphy(hw, HV_PM_CTRL, &phy_data); + phy_data &= 0xFBFF; + phy_data |= HV_PM_CTRL_K1_CLK_REQ; + e1e_wphy(hw, HV_PM_CTRL, phy_data); + + /* Return back configuration + * 772_29[5] = 0 CS_Mode_Stay_In_K1 + */ + e1e_rphy(hw, I217_CGFREG, &phy_data); + phy_data &= 0xFFDF; + e1e_wphy(hw, I217_CGFREG, phy_data); + + /* Change the MAC/PHY interface to Kumeran + * Unforce the SMBus in PHY page769_23[0] = 0 + * Unforce the SMBus in MAC CTRL_EXT[11] = 0 + */ + e1e_rphy(hw, CV_SMB_CTRL, &phy_data); + phy_data &= ~CV_SMB_CTRL_FORCE_SMBUS; + e1e_wphy(hw, CV_SMB_CTRL, phy_data); + mac_data = er32(CTRL_EXT); + mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS; + ew32(CTRL_EXT, mac_data); +} + static int e1000e_pm_freeze(struct device *dev) { struct net_device *netdev = dev_get_drvdata(dev); struct e1000_adapter *adapter = netdev_priv(netdev); + bool present; + + rtnl_lock(); + present = netif_device_present(netdev); netif_device_detach(netdev); - if (netif_running(netdev)) { + if (present && netif_running(netdev)) { int count = E1000_CHECK_RESET_COUNT; while (test_bit(__E1000_RESETTING, &adapter->state) && count--) @@ -6313,6 +6479,8 @@ e1000e_down(adapter, false); e1000_free_irq(adapter); } + rtnl_unlock(); + e1000e_reset_interrupt_capability(adapter); /* Allow time for pending master requests to run */ @@ -6326,11 +6494,17 @@ struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - u32 ctrl, ctrl_ext, rctl, status; - /* Runtime suspend should only enable wakeup for link changes */ - u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol; + u32 ctrl, ctrl_ext, rctl, status, wufc; int retval = 0; + /* Runtime suspend should only enable wakeup for link changes */ + if (runtime) + wufc = E1000_WUFC_LNKC; + else if (device_may_wakeup(&pdev->dev)) + wufc = adapter->wol; + else + wufc = 0; + status = er32(STATUS); if (status & E1000_STATUS_LU) wufc &= ~E1000_WUFC_LNKC; @@ -6387,7 +6561,7 @@ if (adapter->hw.phy.type == e1000_phy_igp_3) { e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); } else if (hw->mac.type >= e1000_pch_lpt) { - if (!(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) + if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) /* ULP does not support wake from unicast, multicast * or broadcast. */ @@ -6560,6 +6734,30 @@ __e1000e_disable_aspm(pdev, state, 1); } +static int e1000e_pm_thaw(struct device *dev) +{ + struct net_device *netdev = dev_get_drvdata(dev); + struct e1000_adapter *adapter = netdev_priv(netdev); + int rc = 0; + + e1000e_set_interrupt_capability(adapter); + + rtnl_lock(); + if (netif_running(netdev)) { + rc = e1000_request_irq(adapter); + if (rc) + goto err_irq; + + e1000e_up(adapter); + } + + netif_device_attach(netdev); +err_irq: + rtnl_unlock(); + + return rc; +} + #ifdef CONFIG_PM static int __e1000_resume(struct pci_dev *pdev) { @@ -6627,29 +6825,12 @@ } #ifdef CONFIG_PM_SLEEP -static int e1000e_pm_thaw(struct device *dev) -{ - struct net_device *netdev = dev_get_drvdata(dev); - struct e1000_adapter *adapter = netdev_priv(netdev); - - e1000e_set_interrupt_capability(adapter); - if (netif_running(netdev)) { - u32 err = e1000_request_irq(adapter); - - if (err) - return err; - - e1000e_up(adapter); - } - - netif_device_attach(netdev); - - return 0; -} - static int e1000e_pm_suspend(struct device *dev) { + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); + struct e1000_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev = to_pci_dev(dev); + struct e1000_hw *hw = &adapter->hw; int rc; e1000e_flush_lpic(pdev); @@ -6660,14 +6841,25 @@ if (rc) e1000e_pm_thaw(dev); + /* Introduce S0ix implementation */ + if (hw->mac.type >= e1000_pch_cnp) + e1000e_s0ix_entry_flow(adapter); + return rc; } static int e1000e_pm_resume(struct device *dev) { + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); + struct e1000_adapter *adapter = netdev_priv(netdev); struct pci_dev *pdev = to_pci_dev(dev); + struct e1000_hw *hw = &adapter->hw; int rc; + /* Introduce S0ix implementation */ + if (hw->mac.type >= e1000_pch_cnp) + e1000e_s0ix_exit_flow(adapter); + rc = __e1000_resume(pdev); if (rc) return rc; @@ -6818,16 +7010,11 @@ static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { - struct net_device *netdev = pci_get_drvdata(pdev); - struct e1000_adapter *adapter = netdev_priv(netdev); - - netif_device_detach(netdev); + e1000e_pm_freeze(&pdev->dev); if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - if (netif_running(netdev)) - e1000e_down(adapter, true); pci_disable_device(pdev); /* Request a slot slot reset. */ @@ -6893,10 +7080,7 @@ e1000_init_manageability_pt(adapter); - if (netif_running(netdev)) - e1000e_up(adapter); - - netif_device_attach(netdev); + e1000e_pm_thaw(&pdev->dev); /* If the controller has AMT, do not set DRV_LOAD until the interface * is up. For all other cases, let the f/w know that the h/w is now @@ -7196,6 +7380,32 @@ NETIF_F_RXCSUM | NETIF_F_HW_CSUM); + /* disable TSO for pcie and 10/100 speeds to avoid + * some hardware issues and for i219 to fix transfer + * speed being capped at 60% + */ + if (!(adapter->flags & FLAG_TSO_FORCE)) { + switch (adapter->link_speed) { + case SPEED_10: + case SPEED_100: + e_info("10/100 speed: disabling TSO\n"); + netdev->features &= ~NETIF_F_TSO; + netdev->features &= ~NETIF_F_TSO6; + break; + case SPEED_1000: + netdev->features |= NETIF_F_TSO; + netdev->features |= NETIF_F_TSO6; + break; + default: + /* oops */ + break; + } + if (hw->mac.type == e1000_pch_spt) { + netdev->features &= ~NETIF_F_TSO; + netdev->features &= ~NETIF_F_TSO6; + } + } + /* Set user-changeable features (subset of all device features) */ netdev->hw_features = netdev->features; netdev->hw_features |= NETIF_F_RXFCS; @@ -7259,21 +7469,11 @@ goto err_eeprom; } - adapter->e1000_workqueue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, - e1000e_driver_name); - - if (!adapter->e1000_workqueue) { - err = -ENOMEM; - goto err_workqueue; - } - - INIT_DELAYED_WORK(&adapter->watchdog_task, e1000_watchdog_task); - queue_delayed_work(adapter->e1000_workqueue, &adapter->watchdog_task, - 0); - + timer_setup(&adapter->watchdog_timer, e1000_watchdog, 0); timer_setup(&adapter->phy_info_timer, e1000_update_phy_info, 0); INIT_WORK(&adapter->reset_task, e1000_reset_task); + INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang); @@ -7367,9 +7567,6 @@ return 0; err_register: - flush_workqueue(adapter->e1000_workqueue); - destroy_workqueue(adapter->e1000_workqueue); -err_workqueue: if (!(adapter->flags & FLAG_HAS_AMT)) e1000e_release_hw_control(adapter); err_eeprom: @@ -7387,6 +7584,7 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: @@ -7407,26 +7605,22 @@ { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - bool down = test_bit(__E1000_DOWN, &adapter->state); e1000e_ptp_remove(adapter); /* The timers may be rescheduled, so explicitly disable them * from being rescheduled. */ - if (!down) - set_bit(__E1000_DOWN, &adapter->state); + set_bit(__E1000_DOWN, &adapter->state); + del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); cancel_work_sync(&adapter->reset_task); + cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->downshift_task); cancel_work_sync(&adapter->update_phy_task); cancel_work_sync(&adapter->print_hang_task); - cancel_delayed_work(&adapter->watchdog_task); - flush_workqueue(adapter->e1000_workqueue); - destroy_workqueue(adapter->e1000_workqueue); - if (adapter->flags & FLAG_HAS_HW_TIMESTAMP) { cancel_work_sync(&adapter->tx_hwtstamp_work); if (adapter->tx_hwtstamp_skb) { @@ -7435,9 +7629,6 @@ } } - /* Don't lie to e1000_close() down the road. */ - if (!down) - clear_bit(__E1000_DOWN, &adapter->state); unregister_netdev(netdev); if (pci_dev_run_wake(pdev)) @@ -7567,6 +7758,12 @@ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V8), board_pch_cnp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_LM9), board_pch_cnp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V9), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM10), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V10), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM11), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V11), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM12), board_pch_spt }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V12), board_pch_spt }, { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/phy.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/phy.c @@ -203,7 +203,7 @@ * Increasing the time out as testing showed failures with * the lower time out */ - for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { + for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 10); i++) { udelay(50); mdic = er32(MDIC); if (mdic & E1000_MDIC_READY) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/e1000e/regs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/e1000e/regs.h @@ -18,6 +18,7 @@ #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ +#define E1000_FEXTNVM5 0x00014 /* Future Extended NVM 5 - RW */ #define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */ #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */ #define E1000_FEXTNVM9 0x5BB4 /* Future Extended NVM 9 - RW */ @@ -234,4 +235,7 @@ #define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */ #define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ +/* PHY registers */ +#define I82579_DFT_CTRL PHY_REG(769, 20) + #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -2230,6 +2230,7 @@ err_ioremap: free_netdev(netdev); err_alloc_netdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e.h @@ -129,6 +129,7 @@ __I40E_RESET_INTR_RECEIVED, __I40E_REINIT_REQUESTED, __I40E_PF_RESET_REQUESTED, + __I40E_PF_RESET_AND_REBUILD_REQUESTED, __I40E_CORE_RESET_REQUESTED, __I40E_GLOBAL_RESET_REQUESTED, __I40E_EMP_RESET_INTR_RECEIVED, @@ -150,11 +151,15 @@ __I40E_CLIENT_RESET, __I40E_VIRTCHNL_OP_PENDING, __I40E_RECOVERY_MODE, + __I40E_VF_RESETS_DISABLED, /* disable resets during i40e_remove */ + __I40E_VFS_RELEASING, /* This must be last as it determines the size of the BITMAP */ __I40E_STATE_SIZE__, }; #define I40E_PF_RESET_FLAG BIT_ULL(__I40E_PF_RESET_REQUESTED) +#define I40E_PF_RESET_AND_REBUILD_FLAG \ + BIT_ULL(__I40E_PF_RESET_AND_REBUILD_REQUESTED) /* VSI state flags */ enum i40e_vsi_state_t { @@ -164,6 +169,7 @@ __I40E_VSI_OVERFLOW_PROMISC, __I40E_VSI_REINIT_REQUESTED, __I40E_VSI_DOWN_REQUESTED, + __I40E_VSI_RELEASING, /* This must be last as it determines the size of the BITMAP */ __I40E_VSI_STATE_SIZE__, }; @@ -176,7 +182,6 @@ struct i40e_lump_tracking { u16 num_entries; - u16 search_hint; u16 list[0]; #define I40E_PILE_VALID_BIT 0x8000 #define I40E_IWARP_IRQ_PILE_ID (I40E_PILE_VALID_BIT - 2) @@ -751,12 +756,12 @@ struct rtnl_link_stats64 net_stats_offsets; struct i40e_eth_stats eth_stats; struct i40e_eth_stats eth_stats_offsets; - u32 tx_restart; - u32 tx_busy; + u64 tx_restart; + u64 tx_busy; u64 tx_linearize; u64 tx_force_wb; - u32 rx_buf_failed; - u32 rx_page_failed; + u64 rx_buf_failed; + u64 rx_page_failed; /* These are containers of ring pointers, allocated at run-time */ struct i40e_ring **rx_rings; @@ -1118,6 +1123,7 @@ const u8 *macaddr); int i40e_del_mac_filter(struct i40e_vsi *vsi, const u8 *macaddr); bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi); +int i40e_count_filters(struct i40e_vsi *vsi); struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, const u8 *macaddr); void i40e_vlan_stripping_enable(struct i40e_vsi *vsi); #ifdef CONFIG_I40E_DCB @@ -1141,6 +1147,7 @@ void i40e_ptp_restore_hw_time(struct i40e_pf *pf); void i40e_ptp_init(struct i40e_pf *pf); void i40e_ptp_stop(struct i40e_pf *pf); +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset); int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi); i40e_status i40e_get_partition_bw_setting(struct i40e_pf *pf); i40e_status i40e_set_partition_bw_setting(struct i40e_pf *pf); @@ -1151,7 +1158,7 @@ static inline bool i40e_enabled_xdp_vsi(struct i40e_vsi *vsi) { - return !!vsi->xdp_prog; + return !!READ_ONCE(vsi->xdp_prog); } int i40e_create_queue_channel(struct i40e_vsi *vsi, struct i40e_channel *ch); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -1211,7 +1211,7 @@ #define I40E_AQC_SET_VSI_PROMISC_BROADCAST 0x04 #define I40E_AQC_SET_VSI_DEFAULT 0x08 #define I40E_AQC_SET_VSI_PROMISC_VLAN 0x10 -#define I40E_AQC_SET_VSI_PROMISC_TX 0x8000 +#define I40E_AQC_SET_VSI_PROMISC_RX_ONLY 0x8000 __le16 seid; #define I40E_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF __le16 vlan_tag; @@ -1893,8 +1893,10 @@ I40E_PHY_TYPE_25GBASE_LR = 0x22, I40E_PHY_TYPE_25GBASE_AOC = 0x23, I40E_PHY_TYPE_25GBASE_ACC = 0x24, - I40E_PHY_TYPE_2_5GBASE_T = 0x30, - I40E_PHY_TYPE_5GBASE_T = 0x31, + I40E_PHY_TYPE_2_5GBASE_T = 0x26, + I40E_PHY_TYPE_5GBASE_T = 0x27, + I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS = 0x30, + I40E_PHY_TYPE_5GBASE_T_LINK_STATUS = 0x31, I40E_PHY_TYPE_MAX, I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD, I40E_PHY_TYPE_EMPTY = 0xFE, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_alloc.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_alloc.h @@ -20,16 +20,11 @@ }; /* prototype for functions used for dynamic memory allocation */ -i40e_status i40e_allocate_dma_mem(struct i40e_hw *hw, - struct i40e_dma_mem *mem, - enum i40e_memory_type type, - u64 size, u32 alignment); -i40e_status i40e_free_dma_mem(struct i40e_hw *hw, - struct i40e_dma_mem *mem); -i40e_status i40e_allocate_virt_mem(struct i40e_hw *hw, - struct i40e_virt_mem *mem, - u32 size); -i40e_status i40e_free_virt_mem(struct i40e_hw *hw, - struct i40e_virt_mem *mem); +int i40e_allocate_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem, + enum i40e_memory_type type, u64 size, u32 alignment); +int i40e_free_dma_mem(struct i40e_hw *hw, struct i40e_dma_mem *mem); +int i40e_allocate_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem, + u32 size); +int i40e_free_virt_mem(struct i40e_hw *hw, struct i40e_virt_mem *mem); #endif /* _I40E_ALLOC_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_client.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_client.c @@ -178,6 +178,10 @@ "Cannot locate client instance close routine\n"); return; } + if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { + dev_dbg(&pf->pdev->dev, "Client is not open, abort close\n"); + return; + } cdev->client->ops->close(&cdev->lan_info, cdev->client, reset); clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); i40e_client_release_qvlist(&cdev->lan_info); @@ -376,7 +380,7 @@ /* Remove failed client instance */ clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); - i40e_client_del_instance(pf); + return; } } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -29,6 +29,7 @@ case I40E_DEV_ID_QSFP_C: case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: + case I40E_DEV_ID_10G_BASE_T_BC: case I40E_DEV_ID_10G_B: case I40E_DEV_ID_10G_SFP: case I40E_DEV_ID_20G_KR2: @@ -1156,8 +1157,8 @@ break; case I40E_PHY_TYPE_100BASE_TX: case I40E_PHY_TYPE_1000BASE_T: - case I40E_PHY_TYPE_2_5GBASE_T: - case I40E_PHY_TYPE_5GBASE_T: + case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS: + case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS: case I40E_PHY_TYPE_10GBASE_T: media = I40E_MEDIA_TYPE_BASET; break; @@ -1341,7 +1342,7 @@ I40E_PFLAN_QALLOC_FIRSTQ_SHIFT; j = (val & I40E_PFLAN_QALLOC_LASTQ_MASK) >> I40E_PFLAN_QALLOC_LASTQ_SHIFT; - if (val & I40E_PFLAN_QALLOC_VALID_MASK) + if (val & I40E_PFLAN_QALLOC_VALID_MASK && j >= base_queue) num_queues = (j - base_queue) + 1; else num_queues = 0; @@ -1351,7 +1352,7 @@ I40E_PF_VT_PFALLOC_FIRSTVF_SHIFT; j = (val & I40E_PF_VT_PFALLOC_LASTVF_MASK) >> I40E_PF_VT_PFALLOC_LASTVF_SHIFT; - if (val & I40E_PF_VT_PFALLOC_VALID_MASK) + if (val & I40E_PF_VT_PFALLOC_VALID_MASK && j >= i) num_vfs = (j - i) + 1; else num_vfs = 0; @@ -1441,9 +1442,9 @@ u32 gpio_val = 0; u32 port; - if (!hw->func_caps.led[idx]) + if (!I40E_IS_X710TL_DEVICE(hw->device_id) && + !hw->func_caps.led[idx]) return 0; - gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx)); port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >> I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT; @@ -1462,8 +1463,15 @@ #define I40E_FILTER_ACTIVITY 0xE #define I40E_LINK_ACTIVITY 0xC #define I40E_MAC_ACTIVITY 0xD +#define I40E_FW_LED BIT(4) +#define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \ + I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) + #define I40E_LED0 22 +#define I40E_PIN_FUNC_SDP 0x0 +#define I40E_PIN_FUNC_LED 0x1 + /** * i40e_led_get - return current on/off mode * @hw: pointer to the hw struct @@ -1508,8 +1516,10 @@ { int i; - if (mode & 0xfffffff0) + if (mode & ~I40E_LED_MODE_VALID) { hw_dbg(hw, "invalid mode passed in %X\n", mode); + return; + } /* as per the documentation GPIO 22-29 are the LED * GPIO pins named LED0..LED7 @@ -1519,6 +1529,20 @@ if (!gpio_val) continue; + + if (I40E_IS_X710TL_DEVICE(hw->device_id)) { + u32 pin_func = 0; + + if (mode & I40E_FW_LED) + pin_func = I40E_PIN_FUNC_SDP; + else + pin_func = I40E_PIN_FUNC_LED; + + gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK; + gpio_val |= ((pin_func << + I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) & + I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK); + } gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK; /* this & is a bit of paranoia, but serves as a range check */ gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) & @@ -1950,6 +1974,21 @@ } /** + * i40e_is_aq_api_ver_ge + * @aq: pointer to AdminQ info containing HW API version to compare + * @maj: API major value + * @min: API minor value + * + * Assert whether current HW API version is greater/equal than provided. + **/ +static bool i40e_is_aq_api_ver_ge(struct i40e_adminq_info *aq, u16 maj, + u16 min) +{ + return (aq->api_maj_ver > maj || + (aq->api_maj_ver == maj && aq->api_min_ver >= min)); +} + +/** * i40e_aq_add_vsi * @hw: pointer to the hw struct * @vsi_ctx: pointer to a vsi context struct @@ -2074,18 +2113,16 @@ if (set) { flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST; - if (rx_only_promisc && - (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) || - (hw->aq.api_maj_ver > 1))) - flags |= I40E_AQC_SET_VSI_PROMISC_TX; + if (rx_only_promisc && i40e_is_aq_api_ver_ge(&hw->aq, 1, 5)) + flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY; } cmd->promiscuous_flags = cpu_to_le16(flags); cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST); - if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) || - (hw->aq.api_maj_ver > 1)) - cmd->valid_flags |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_TX); + if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5)) + cmd->valid_flags |= + cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY); cmd->seid = cpu_to_le16(seid); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); @@ -2182,11 +2219,17 @@ i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_vsi_promiscuous_modes); - if (enable) + if (enable) { flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST; + if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5)) + flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY; + } cmd->promiscuous_flags = cpu_to_le16(flags); cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST); + if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5)) + cmd->valid_flags |= + cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY); cmd->seid = cpu_to_le16(seid); cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID); @@ -2571,9 +2614,16 @@ if (status) return status; - hw->phy.link_info.req_fec_info = - abilities.fec_cfg_curr_mod_ext_info & - (I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS); + if (abilities.fec_cfg_curr_mod_ext_info & + I40E_AQ_ENABLE_FEC_AUTO) + hw->phy.link_info.req_fec_info = + (I40E_AQ_REQUEST_FEC_KR | + I40E_AQ_REQUEST_FEC_RS); + else + hw->phy.link_info.req_fec_info = + abilities.fec_cfg_curr_mod_ext_info & + (I40E_AQ_REQUEST_FEC_KR | + I40E_AQ_REQUEST_FEC_RS); memcpy(hw->phy.link_info.module_type, &abilities.module_type, sizeof(hw->phy.link_info.module_type)); @@ -4885,6 +4935,7 @@ break; case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: + case I40E_DEV_ID_10G_BASE_T_BC: case I40E_DEV_ID_10G_BASE_T_X722: case I40E_DEV_ID_25G_B: case I40E_DEV_ID_25G_SFP28: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_dcb.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_dcb.c @@ -889,7 +889,9 @@ ret = i40e_read_nvm_module_data(hw, I40E_SR_EMP_SR_SETTINGS_PTR, - offset, 1, + offset, + I40E_LLDP_CURRENT_STATUS_OFFSET, + I40E_LLDP_CURRENT_STATUS_SIZE, &lldp_cfg.adminstatus); } else { ret = i40e_read_lldp_cfg(hw, &lldp_cfg); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_dcb.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_dcb.h @@ -32,6 +32,9 @@ #define I40E_CEE_MAX_FEAT_TYPE 3 #define I40E_LLDP_CURRENT_STATUS_XL710_OFFSET 0x2B #define I40E_LLDP_CURRENT_STATUS_X722_OFFSET 0x31 +#define I40E_LLDP_CURRENT_STATUS_OFFSET 1 +#define I40E_LLDP_CURRENT_STATUS_SIZE 1 + /* Defines for LLDP TLV header */ #define I40E_LLDP_TLV_LEN_SHIFT 0 #define I40E_LLDP_TLV_LEN_MASK (0x01FF << I40E_LLDP_TLV_LEN_SHIFT) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -234,7 +234,7 @@ (unsigned long int)vsi->net_stats_offsets.rx_compressed, (unsigned long int)vsi->net_stats_offsets.tx_compressed); dev_info(&pf->pdev->dev, - " tx_restart = %d, tx_busy = %d, rx_buf_failed = %d, rx_page_failed = %d\n", + " tx_restart = %llu, tx_busy = %llu, rx_buf_failed = %llu, rx_page_failed = %llu\n", vsi->tx_restart, vsi->tx_busy, vsi->rx_buf_failed, vsi->rx_page_failed); rcu_read_lock(); @@ -505,6 +505,14 @@ dev_info(&pf->pdev->dev, "vsi %d not found\n", vsi_seid); return; } + if (vsi->type != I40E_VSI_MAIN && + vsi->type != I40E_VSI_FDIR && + vsi->type != I40E_VSI_VMDQ2) { + dev_info(&pf->pdev->dev, + "vsi %d type %d descriptor rings not available\n", + vsi_seid, vsi->type); + return; + } if (ring_id >= vsi->num_queue_pairs || ring_id < 0) { dev_info(&pf->pdev->dev, "ring %d not found\n", ring_id); return; @@ -1755,7 +1763,7 @@ void i40e_dbg_init(void) { i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); - if (!i40e_dbg_root) + if (IS_ERR(i40e_dbg_root)) pr_info("init of debugfs failed\n"); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_devids.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_devids.h @@ -23,6 +23,8 @@ #define I40E_DEV_ID_10G_BASE_T_BC 0x15FF #define I40E_DEV_ID_10G_B 0x104F #define I40E_DEV_ID_10G_SFP 0x104E +#define I40E_IS_X710TL_DEVICE(d) \ + ((d) == I40E_DEV_ID_10G_BASE_T_BC) #define I40E_DEV_ID_KX_X722 0x37CE #define I40E_DEV_ID_QSFP_X722 0x37CF #define I40E_DEV_ID_SFP_X722 0x37D0 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_diag.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_diag.c @@ -44,7 +44,7 @@ return 0; } -struct i40e_diag_reg_test_info i40e_reg_list[] = { +const struct i40e_diag_reg_test_info i40e_reg_list[] = { /* offset mask elements stride */ {I40E_QTX_CTL(0), 0x0000FFBF, 1, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)}, @@ -78,27 +78,28 @@ { i40e_status ret_code = 0; u32 reg, mask; + u32 elements; u32 i, j; for (i = 0; i40e_reg_list[i].offset != 0 && !ret_code; i++) { + elements = i40e_reg_list[i].elements; /* set actual reg range for dynamically allocated resources */ if (i40e_reg_list[i].offset == I40E_QTX_CTL(0) && hw->func_caps.num_tx_qp != 0) - i40e_reg_list[i].elements = hw->func_caps.num_tx_qp; + elements = hw->func_caps.num_tx_qp; if ((i40e_reg_list[i].offset == I40E_PFINT_ITRN(0, 0) || i40e_reg_list[i].offset == I40E_PFINT_ITRN(1, 0) || i40e_reg_list[i].offset == I40E_PFINT_ITRN(2, 0) || i40e_reg_list[i].offset == I40E_QINT_TQCTL(0) || i40e_reg_list[i].offset == I40E_QINT_RQCTL(0)) && hw->func_caps.num_msix_vectors != 0) - i40e_reg_list[i].elements = - hw->func_caps.num_msix_vectors - 1; + elements = hw->func_caps.num_msix_vectors - 1; /* test register access */ mask = i40e_reg_list[i].mask; - for (j = 0; j < i40e_reg_list[i].elements && !ret_code; j++) { + for (j = 0; j < elements && !ret_code; j++) { reg = i40e_reg_list[i].offset + (j * i40e_reg_list[i].stride); ret_code = i40e_diag_reg_pattern_test(hw, reg, mask); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_diag.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_diag.h @@ -20,7 +20,7 @@ u32 stride; /* bytes between each element */ }; -extern struct i40e_diag_reg_test_info i40e_reg_list[]; +extern const struct i40e_diag_reg_test_info i40e_reg_list[]; i40e_status i40e_diag_reg_test(struct i40e_hw *hw); i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -232,6 +232,8 @@ I40E_STAT(struct i40e_vsi, _name, _stat) #define I40E_VEB_STAT(_name, _stat) \ I40E_STAT(struct i40e_veb, _name, _stat) +#define I40E_VEB_TC_STAT(_name, _stat) \ + I40E_STAT(struct i40e_cp_veb_tc_stats, _name, _stat) #define I40E_PFC_STAT(_name, _stat) \ I40E_STAT(struct i40e_pfc_stats, _name, _stat) #define I40E_QUEUE_STAT(_name, _stat) \ @@ -266,11 +268,18 @@ I40E_VEB_STAT("veb.rx_unknown_protocol", stats.rx_unknown_protocol), }; +struct i40e_cp_veb_tc_stats { + u64 tc_rx_packets; + u64 tc_rx_bytes; + u64 tc_tx_packets; + u64 tc_tx_bytes; +}; + static const struct i40e_stats i40e_gstrings_veb_tc_stats[] = { - I40E_VEB_STAT("veb.tc_%u_tx_packets", tc_stats.tc_tx_packets), - I40E_VEB_STAT("veb.tc_%u_tx_bytes", tc_stats.tc_tx_bytes), - I40E_VEB_STAT("veb.tc_%u_rx_packets", tc_stats.tc_rx_packets), - I40E_VEB_STAT("veb.tc_%u_rx_bytes", tc_stats.tc_rx_bytes), + I40E_VEB_TC_STAT("veb.tc_%u_tx_packets", tc_tx_packets), + I40E_VEB_TC_STAT("veb.tc_%u_tx_bytes", tc_tx_bytes), + I40E_VEB_TC_STAT("veb.tc_%u_rx_packets", tc_rx_packets), + I40E_VEB_TC_STAT("veb.tc_%u_rx_bytes", tc_rx_bytes), }; static const struct i40e_stats i40e_gstrings_misc_stats[] = { @@ -722,7 +731,14 @@ ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS); ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER); - if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) { + if ((I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) && + (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info)) { + ethtool_link_ksettings_add_link_mode(ks, advertising, + FEC_NONE); + ethtool_link_ksettings_add_link_mode(ks, advertising, + FEC_BASER); + ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS); + } else if (I40E_AQ_SET_FEC_REQUEST_RS & req_fec_info) { ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS); } else if (I40E_AQ_SET_FEC_REQUEST_KR & req_fec_info) { ethtool_link_ksettings_add_link_mode(ks, advertising, @@ -730,12 +746,6 @@ } else { ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_NONE); - if (I40E_AQ_SET_FEC_AUTO & req_fec_info) { - ethtool_link_ksettings_add_link_mode(ks, advertising, - FEC_RS); - ethtool_link_ksettings_add_link_mode(ks, advertising, - FEC_BASER); - } } } @@ -829,8 +839,8 @@ 10000baseT_Full); break; case I40E_PHY_TYPE_10GBASE_T: - case I40E_PHY_TYPE_5GBASE_T: - case I40E_PHY_TYPE_2_5GBASE_T: + case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS: + case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS: case I40E_PHY_TYPE_1000BASE_T: case I40E_PHY_TYPE_100BASE_TX: ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg); @@ -967,7 +977,7 @@ default: /* if we got here and link is up something bad is afoot */ netdev_info(netdev, - "WARNING: Link is up but PHY type 0x%x is not recognized.\n", + "WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n", hw_link_info->phy_type); } @@ -1097,6 +1107,7 @@ /* Set flow control settings */ ethtool_link_ksettings_add_link_mode(ks, supported, Pause); + ethtool_link_ksettings_add_link_mode(ks, supported, Asym_Pause); switch (hw->fc.requested_mode) { case I40E_FC_FULL: @@ -1248,8 +1259,7 @@ if (ethtool_link_ksettings_test_link_mode(&safe_ks, supported, Autoneg) && - hw->phy.link_info.phy_type != - I40E_PHY_TYPE_10GBASE_T) { + hw->phy.media_type != I40E_MEDIA_TYPE_BASET) { netdev_info(netdev, "Autoneg cannot be disabled on this phy\n"); err = -EINVAL; goto done; @@ -1395,7 +1405,8 @@ memset(&config, 0, sizeof(config)); config.phy_type = abilities.phy_type; - config.abilities = abilities.abilities; + config.abilities = abilities.abilities | + I40E_AQ_PHY_ENABLE_ATOMIC_LINK; config.phy_type_ext = abilities.phy_type_ext; config.link_speed = abilities.link_speed; config.eee_capability = abilities.eee_capability; @@ -1437,6 +1448,7 @@ struct i40e_hw *hw = &pf->hw; i40e_status status = 0; int err = 0; + u8 fec_cfg; /* Get the current phy config */ memset(&abilities, 0, sizeof(abilities)); @@ -1448,18 +1460,16 @@ } fecparam->fec = 0; - if (abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_AUTO) + fec_cfg = abilities.fec_cfg_curr_mod_ext_info; + if (fec_cfg & I40E_AQ_SET_FEC_AUTO) fecparam->fec |= ETHTOOL_FEC_AUTO; - if ((abilities.fec_cfg_curr_mod_ext_info & - I40E_AQ_SET_FEC_REQUEST_RS) || - (abilities.fec_cfg_curr_mod_ext_info & - I40E_AQ_SET_FEC_ABILITY_RS)) + else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_RS | + I40E_AQ_SET_FEC_ABILITY_RS)) fecparam->fec |= ETHTOOL_FEC_RS; - if ((abilities.fec_cfg_curr_mod_ext_info & - I40E_AQ_SET_FEC_REQUEST_KR) || - (abilities.fec_cfg_curr_mod_ext_info & I40E_AQ_SET_FEC_ABILITY_KR)) + else if (fec_cfg & (I40E_AQ_SET_FEC_REQUEST_KR | + I40E_AQ_SET_FEC_ABILITY_KR)) fecparam->fec |= ETHTOOL_FEC_BASER; - if (abilities.fec_cfg_curr_mod_ext_info == 0) + if (fec_cfg == 0) fecparam->fec |= ETHTOOL_FEC_OFF; if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_KR_ENA) @@ -2213,6 +2223,29 @@ } /** + * i40e_get_veb_tc_stats - copy VEB TC statistics to formatted structure + * @tc: the TC statistics in VEB structure (veb->tc_stats) + * @i: the index of traffic class in (veb->tc_stats) structure to copy + * + * Copy VEB TC statistics from structure of arrays (veb->tc_stats) to + * one dimensional structure i40e_cp_veb_tc_stats. + * Produce formatted i40e_cp_veb_tc_stats structure of the VEB TC + * statistics for the given TC. + **/ +static struct i40e_cp_veb_tc_stats +i40e_get_veb_tc_stats(struct i40e_veb_tc_stats *tc, unsigned int i) +{ + struct i40e_cp_veb_tc_stats veb_tc = { + .tc_rx_packets = tc->tc_rx_packets[i], + .tc_rx_bytes = tc->tc_rx_bytes[i], + .tc_tx_packets = tc->tc_tx_packets[i], + .tc_tx_bytes = tc->tc_tx_bytes[i], + }; + + return veb_tc; +} + +/** * i40e_get_pfc_stats - copy HW PFC statistics to formatted structure * @pf: the PF device structure * @i: the priority value to copy @@ -2296,8 +2329,16 @@ i40e_gstrings_veb_stats); for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) - i40e_add_ethtool_stats(&data, veb_stats ? veb : NULL, - i40e_gstrings_veb_tc_stats); + if (veb_stats) { + struct i40e_cp_veb_tc_stats veb_tc = + i40e_get_veb_tc_stats(&veb->tc_stats, i); + + i40e_add_ethtool_stats(&data, &veb_tc, + i40e_gstrings_veb_tc_stats); + } else { + i40e_add_ethtool_stats(&data, NULL, + i40e_gstrings_veb_tc_stats); + } i40e_add_ethtool_stats(&data, pf, i40e_gstrings_stats); @@ -2537,15 +2578,16 @@ set_bit(__I40E_TESTING, pf->state); + if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || + test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) { + dev_warn(&pf->pdev->dev, + "Cannot start offline testing when PF is in reset state.\n"); + goto skip_ol_tests; + } + if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) { dev_warn(&pf->pdev->dev, "Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n"); - data[I40E_ETH_TEST_REG] = 1; - data[I40E_ETH_TEST_EEPROM] = 1; - data[I40E_ETH_TEST_INTR] = 1; - data[I40E_ETH_TEST_LINK] = 1; - eth_test->flags |= ETH_TEST_FL_FAILED; - clear_bit(__I40E_TESTING, pf->state); goto skip_ol_tests; } @@ -2592,9 +2634,17 @@ data[I40E_ETH_TEST_INTR] = 0; } -skip_ol_tests: - netif_info(pf, drv, netdev, "testing finished\n"); + return; + +skip_ol_tests: + data[I40E_ETH_TEST_REG] = 1; + data[I40E_ETH_TEST_EEPROM] = 1; + data[I40E_ETH_TEST_INTR] = 1; + data[I40E_ETH_TEST_LINK] = 1; + eth_test->flags |= ETH_TEST_FL_FAILED; + clear_bit(__I40E_TESTING, pf->state); + netif_info(pf, drv, netdev, "testing failed\n"); } static void i40e_get_wol(struct net_device *netdev, @@ -3032,10 +3082,17 @@ if (cmd->flow_type == TCP_V4_FLOW || cmd->flow_type == UDP_V4_FLOW) { - if (i_set & I40E_L3_SRC_MASK) - cmd->data |= RXH_IP_SRC; - if (i_set & I40E_L3_DST_MASK) - cmd->data |= RXH_IP_DST; + if (hw->mac.type == I40E_MAC_X722) { + if (i_set & I40E_X722_L3_SRC_MASK) + cmd->data |= RXH_IP_SRC; + if (i_set & I40E_X722_L3_DST_MASK) + cmd->data |= RXH_IP_DST; + } else { + if (i_set & I40E_L3_SRC_MASK) + cmd->data |= RXH_IP_SRC; + if (i_set & I40E_L3_DST_MASK) + cmd->data |= RXH_IP_DST; + } } else if (cmd->flow_type == TCP_V6_FLOW || cmd->flow_type == UDP_V6_FLOW) { if (i_set & I40E_L3_V6_SRC_MASK) @@ -3342,12 +3399,15 @@ /** * i40e_get_rss_hash_bits - Read RSS Hash bits from register + * @hw: hw structure * @nfc: pointer to user request * @i_setc: bits currently set * * Returns value of bits to be set per user request **/ -static u64 i40e_get_rss_hash_bits(struct ethtool_rxnfc *nfc, u64 i_setc) +static u64 i40e_get_rss_hash_bits(struct i40e_hw *hw, + struct ethtool_rxnfc *nfc, + u64 i_setc) { u64 i_set = i_setc; u64 src_l3 = 0, dst_l3 = 0; @@ -3366,8 +3426,13 @@ dst_l3 = I40E_L3_V6_DST_MASK; } else if (nfc->flow_type == TCP_V4_FLOW || nfc->flow_type == UDP_V4_FLOW) { - src_l3 = I40E_L3_SRC_MASK; - dst_l3 = I40E_L3_DST_MASK; + if (hw->mac.type == I40E_MAC_X722) { + src_l3 = I40E_X722_L3_SRC_MASK; + dst_l3 = I40E_X722_L3_DST_MASK; + } else { + src_l3 = I40E_L3_SRC_MASK; + dst_l3 = I40E_L3_DST_MASK; + } } else { /* Any other flow type are not supported here */ return i_set; @@ -3385,6 +3450,7 @@ return i_set; } +#define FLOW_PCTYPES_SIZE 64 /** * i40e_set_rss_hash_opt - Enable/Disable flow types for RSS hash * @pf: pointer to the physical function struct @@ -3397,9 +3463,11 @@ struct i40e_hw *hw = &pf->hw; u64 hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) | ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32); - u8 flow_pctype = 0; + DECLARE_BITMAP(flow_pctypes, FLOW_PCTYPES_SIZE); u64 i_set, i_setc; + bitmap_zero(flow_pctypes, FLOW_PCTYPES_SIZE); + if (pf->flags & I40E_FLAG_MFP_ENABLED) { dev_err(&pf->pdev->dev, "Change of RSS hash input set is not supported when MFP mode is enabled\n"); @@ -3415,36 +3483,35 @@ switch (nfc->flow_type) { case TCP_V4_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_TCP; + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, flow_pctypes); if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK); + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK, + flow_pctypes); break; case TCP_V6_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_TCP; + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, flow_pctypes); if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK); - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK); + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK, + flow_pctypes); break; case UDP_V4_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV4_UDP; - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | - BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP); - + set_bit(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, flow_pctypes); + if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) { + set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP, + flow_pctypes); + set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP, + flow_pctypes); + } hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV4); break; case UDP_V6_FLOW: - flow_pctype = I40E_FILTER_PCTYPE_NONF_IPV6_UDP; - if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) - hena |= - BIT_ULL(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | - BIT_ULL(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP); - + set_bit(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, flow_pctypes); + if (pf->hw_features & I40E_HW_MULTIPLE_TCP_UDP_RSS_PCTYPE) { + set_bit(I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP, + flow_pctypes); + set_bit(I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP, + flow_pctypes); + } hena |= BIT_ULL(I40E_FILTER_PCTYPE_FRAG_IPV6); break; case AH_ESP_V4_FLOW: @@ -3477,17 +3544,20 @@ return -EINVAL; } - if (flow_pctype) { - i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, - flow_pctype)) | - ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, - flow_pctype)) << 32); - i_set = i40e_get_rss_hash_bits(nfc, i_setc); - i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_pctype), - (u32)i_set); - i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_pctype), - (u32)(i_set >> 32)); - hena |= BIT_ULL(flow_pctype); + if (bitmap_weight(flow_pctypes, FLOW_PCTYPES_SIZE)) { + u8 flow_id; + + for_each_set_bit(flow_id, flow_pctypes, FLOW_PCTYPES_SIZE) { + i_setc = (u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id)) | + ((u64)i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id)) << 32); + i_set = i40e_get_rss_hash_bits(&pf->hw, nfc, i_setc); + + i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, flow_id), + (u32)i_set); + i40e_write_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, flow_id), + (u32)(i_set >> 32)); + hena |= BIT_ULL(flow_id); + } } i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena); @@ -4163,11 +4233,7 @@ return -EOPNOTSUPP; /* First 4 bytes of L4 header */ - if (usr_ip4_spec->l4_4_bytes == htonl(0xFFFFFFFF)) - new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK; - else if (!usr_ip4_spec->l4_4_bytes) - new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK); - else + if (usr_ip4_spec->l4_4_bytes) return -EOPNOTSUPP; /* Filtering on Type of Service is not supported. */ @@ -4874,7 +4940,7 @@ enum i40e_admin_queue_err adq_err; struct i40e_vsi *vsi = np->vsi; struct i40e_pf *pf = vsi->back; - bool is_reset_needed; + u32 reset_needed = 0; i40e_status status; u32 i, j; @@ -4919,9 +4985,11 @@ flags_complete: changed_flags = orig_flags ^ new_flags; - is_reset_needed = !!(changed_flags & (I40E_FLAG_VEB_STATS_ENABLED | - I40E_FLAG_LEGACY_RX | I40E_FLAG_SOURCE_PRUNING_DISABLED | - I40E_FLAG_DISABLE_FW_LLDP)); + if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) + reset_needed = I40E_PF_RESET_AND_REBUILD_FLAG; + if (changed_flags & (I40E_FLAG_VEB_STATS_ENABLED | + I40E_FLAG_LEGACY_RX | I40E_FLAG_SOURCE_PRUNING_DISABLED)) + reset_needed = BIT(__I40E_PF_RESET_REQUESTED); /* Before we finalize any flag changes, we need to perform some * checks to ensure that the changes are supported and safe. @@ -5038,12 +5106,16 @@ case I40E_AQ_RC_EEXIST: dev_warn(&pf->pdev->dev, "FW LLDP agent is already running\n"); - is_reset_needed = false; + reset_needed = 0; break; case I40E_AQ_RC_EPERM: dev_warn(&pf->pdev->dev, "Device configuration forbids SW from starting the LLDP agent.\n"); return -EINVAL; + case I40E_AQ_RC_EAGAIN: + dev_warn(&pf->pdev->dev, + "Stop FW LLDP agent command is still being processed, please try again in a second.\n"); + return -EBUSY; default: dev_warn(&pf->pdev->dev, "Starting FW LLDP agent failed: error: %s, %s\n", @@ -5067,8 +5139,8 @@ /* Issue reset to cause things to take effect, as additional bits * are added we will need to create a mask of bits requiring reset */ - if (is_reset_needed) - i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true); + if (reset_needed) + i40e_do_reset(pf, reset_needed, true); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -44,6 +44,8 @@ static void i40e_determine_queue_usage(struct i40e_pf *pf); static int i40e_setup_pf_filter_control(struct i40e_pf *pf); static void i40e_prep_for_reset(struct i40e_pf *pf, bool lock_acquired); +static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit, + bool lock_acquired); static int i40e_reset(struct i40e_pf *pf); static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired); static int i40e_setup_misc_vector_for_recovery_mode(struct i40e_pf *pf); @@ -105,6 +107,30 @@ static struct workqueue_struct *i40e_wq; +static void netdev_hw_addr_refcnt(struct i40e_mac_filter *f, + struct net_device *netdev, int delta) +{ + struct netdev_hw_addr_list *ha_list; + struct netdev_hw_addr *ha; + + if (!f || !netdev) + return; + + if (is_unicast_ether_addr(f->macaddr) || is_link_local_ether_addr(f->macaddr)) + ha_list = &netdev->uc; + else + ha_list = &netdev->mc; + + netdev_hw_addr_list_for_each(ha, ha_list) { + if (ether_addr_equal(ha->addr, f->macaddr)) { + ha->refcount += delta; + if (ha->refcount <= 0) + ha->refcount = 1; + break; + } + } +} + /** * i40e_allocate_dma_mem_d - OS specific memory alloc for shared code * @hw: pointer to the HW structure @@ -184,10 +210,6 @@ * @id: an owner id to stick on the items assigned * * Returns the base item index of the lump, or negative for error - * - * The search_hint trick and lack of advanced fit-finding only work - * because we're highly likely to have all the same size lump requests. - * Linear search time and any fragmentation should be minimal. **/ static int i40e_get_lump(struct i40e_pf *pf, struct i40e_lump_tracking *pile, u16 needed, u16 id) @@ -202,8 +224,21 @@ return -EINVAL; } - /* start the linear search with an imperfect hint */ - i = pile->search_hint; + /* Allocate last queue in the pile for FDIR VSI queue + * so it doesn't fragment the qp_pile + */ + if (pile == pf->qp_pile && pf->vsi[id]->type == I40E_VSI_FDIR) { + if (pile->list[pile->num_entries - 1] & I40E_PILE_VALID_BIT) { + dev_err(&pf->pdev->dev, + "Cannot allocate queue %d for I40E_VSI_FDIR\n", + pile->num_entries - 1); + return -ENOMEM; + } + pile->list[pile->num_entries - 1] = id | I40E_PILE_VALID_BIT; + return pile->num_entries - 1; + } + + i = 0; while (i < pile->num_entries) { /* skip already allocated entries */ if (pile->list[i] & I40E_PILE_VALID_BIT) { @@ -222,7 +257,6 @@ for (j = 0; j < needed; j++) pile->list[i+j] = id | I40E_PILE_VALID_BIT; ret = i; - pile->search_hint = i + j; break; } @@ -245,7 +279,7 @@ { int valid_id = (id | I40E_PILE_VALID_BIT); int count = 0; - int i; + u16 i; if (!pile || index >= pile->num_entries) return -EINVAL; @@ -257,8 +291,6 @@ count++; } - if (count && index < pile->search_hint) - pile->search_hint = index; return count; } @@ -383,7 +415,9 @@ set_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state); break; default: - netdev_err(netdev, "tx_timeout recovery unsuccessful\n"); + netdev_err(netdev, "tx_timeout recovery unsuccessful, device is in non-recoverable state.\n"); + set_bit(__I40E_DOWN_REQUESTED, pf->state); + set_bit(__I40E_VSI_DOWN_REQUESTED, vsi->state); break; } @@ -458,11 +492,15 @@ i40e_get_netdev_stats_struct_tx(ring, stats); if (i40e_enabled_xdp_vsi(vsi)) { - ring++; + ring = READ_ONCE(vsi->xdp_rings[i]); + if (!ring) + continue; i40e_get_netdev_stats_struct_tx(ring, stats); } - ring++; + ring = READ_ONCE(vsi->rx_rings[i]); + if (!ring) + continue; do { start = u64_stats_fetch_begin_irq(&ring->syncp); packets = ring->stats.packets; @@ -774,9 +812,9 @@ struct rtnl_link_stats64 *ns; /* netdev stats */ struct i40e_eth_stats *oes; struct i40e_eth_stats *es; /* device's eth stats */ - u32 tx_restart, tx_busy; + u64 tx_restart, tx_busy; struct i40e_ring *p; - u32 rx_page, rx_buf; + u64 rx_page, rx_buf; u64 bytes, packets; unsigned int start; u64 tx_linearize; @@ -806,6 +844,8 @@ for (q = 0; q < vsi->num_queue_pairs; q++) { /* locate Tx ring */ p = READ_ONCE(vsi->tx_rings[q]); + if (!p) + continue; do { start = u64_stats_fetch_begin_irq(&p->syncp); @@ -819,8 +859,11 @@ tx_linearize += p->tx_stats.tx_linearize; tx_force_wb += p->tx_stats.tx_force_wb; - /* Rx queue is part of the same block as Tx queue */ - p = &p[1]; + /* locate Rx ring */ + p = READ_ONCE(vsi->rx_rings[q]); + if (!p) + continue; + do { start = u64_stats_fetch_begin_irq(&p->syncp); packets = p->stats.packets; @@ -1110,6 +1153,25 @@ } /** + * i40e_count_filters - counts VSI mac filters + * @vsi: the VSI to be searched + * + * Returns count of mac filters + **/ +int i40e_count_filters(struct i40e_vsi *vsi) +{ + struct i40e_mac_filter *f; + struct hlist_node *h; + int bkt; + int cnt = 0; + + hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) + ++cnt; + + return cnt; +} + +/** * i40e_find_filter - Search VSI filter list for specific mac/vlan filter * @vsi: the VSI to be searched * @macaddr: the MAC address @@ -1765,6 +1827,7 @@ bool is_add) { struct i40e_pf *pf = vsi->back; + u16 num_tc_qps = 0; u16 sections = 0; u8 netdev_tc = 0; u16 numtc = 1; @@ -1772,13 +1835,37 @@ u8 offset; u16 qmap; int i; - u16 num_tc_qps = 0; sections = I40E_AQ_VSI_PROP_QUEUE_MAP_VALID; offset = 0; + /* zero out queue mapping, it will get updated on the end of the function */ + memset(ctxt->info.queue_mapping, 0, sizeof(ctxt->info.queue_mapping)); + + if (vsi->type == I40E_VSI_MAIN) { + /* This code helps add more queue to the VSI if we have + * more cores than RSS can support, the higher cores will + * be served by ATR or other filters. Furthermore, the + * non-zero req_queue_pairs says that user requested a new + * queue count via ethtool's set_channels, so use this + * value for queues distribution across traffic classes + * We need at least one queue pair for the interface + * to be usable as we see in else statement. + */ + if (vsi->req_queue_pairs > 0) + vsi->num_queue_pairs = vsi->req_queue_pairs; + else if (pf->flags & I40E_FLAG_MSIX_ENABLED) + vsi->num_queue_pairs = pf->num_lan_msix; + else + vsi->num_queue_pairs = 1; + } /* Number of queues per enabled TC */ - num_tc_qps = vsi->alloc_queue_pairs; + if (vsi->type == I40E_VSI_MAIN || + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs != 0)) + num_tc_qps = vsi->num_queue_pairs; + else + num_tc_qps = vsi->alloc_queue_pairs; + if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) { /* Find numtc from enabled TC bitmap */ for (i = 0, numtc = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { @@ -1856,15 +1943,11 @@ } ctxt->info.tc_mapping[i] = cpu_to_le16(qmap); } - - /* Set actual Tx/Rx queue pairs */ - vsi->num_queue_pairs = offset; - if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) { - if (vsi->req_queue_pairs > 0) - vsi->num_queue_pairs = vsi->req_queue_pairs; - else if (pf->flags & I40E_FLAG_MSIX_ENABLED) - vsi->num_queue_pairs = pf->num_lan_msix; - } + /* Do not change previously set num_queue_pairs for PFs and VFs*/ + if ((vsi->type == I40E_VSI_MAIN && numtc != 1) || + (vsi->type == I40E_VSI_SRIOV && vsi->num_queue_pairs == 0) || + (vsi->type != I40E_VSI_MAIN && vsi->type != I40E_VSI_SRIOV)) + vsi->num_queue_pairs = offset; /* Scheduler section valid can only be set for ADD VSI */ if (is_add) { @@ -1994,6 +2077,7 @@ hlist_for_each_entry_safe(new, h, from, hlist) { /* We can simply free the wrapper structure */ hlist_del(&new->hlist); + netdev_hw_addr_refcnt(new->f, vsi->netdev, -1); kfree(new); } } @@ -2341,6 +2425,10 @@ &tmp_add_list, &tmp_del_list, vlan_filters); + + hlist_for_each_entry(new, &tmp_add_list, hlist) + netdev_hw_addr_refcnt(new->f, vsi->netdev, 1); + if (retval) goto err_no_memory_locked; @@ -2473,6 +2561,7 @@ if (new->f->state == I40E_FILTER_NEW) new->f->state = new->state; hlist_del(&new->hlist); + netdev_hw_addr_refcnt(new->f, vsi->netdev, -1); kfree(new); } spin_unlock_bh(&vsi->mac_filter_hash_lock); @@ -2536,8 +2625,7 @@ i40e_stat_str(hw, aq_ret), i40e_aq_str(hw, hw->aq.asq_last_status)); } else { - dev_info(&pf->pdev->dev, "%s is %s allmulti mode.\n", - vsi->netdev->name, + dev_info(&pf->pdev->dev, "%s allmulti mode.\n", cur_multipromisc ? "entering" : "leaving"); } } @@ -2592,14 +2680,15 @@ return; if (!test_and_clear_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state)) return; - if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) { + if (test_bit(__I40E_VF_DISABLE, pf->state)) { set_bit(__I40E_MACVLAN_SYNC_PENDING, pf->state); return; } for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v] && - (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED)) { + (pf->vsi[v]->flags & I40E_VSI_FLAG_FILTER_CHANGED) && + !test_bit(__I40E_VSI_RELEASING, pf->vsi[v]->state)) { int ret = i40e_sync_vsi_filters(pf->vsi[v]); if (ret) { @@ -2610,7 +2699,6 @@ } } } - clear_bit(__I40E_VF_DISABLE, pf->state); } /** @@ -2639,7 +2727,7 @@ struct i40e_pf *pf = vsi->back; if (i40e_enabled_xdp_vsi(vsi)) { - int frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN; + int frame_size = new_mtu + I40E_PACKET_HDR_PAD; if (frame_size > i40e_max_xdp_frame_size(vsi)) return -EINVAL; @@ -3534,14 +3622,14 @@ q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[i]->itr_setting); wr32(hw, I40E_PFINT_ITRN(I40E_RX_ITR, vector - 1), - q_vector->rx.target_itr); + q_vector->rx.target_itr >> 1); q_vector->rx.current_itr = q_vector->rx.target_itr; q_vector->tx.next_update = jiffies + 1; q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[i]->itr_setting); wr32(hw, I40E_PFINT_ITRN(I40E_TX_ITR, vector - 1), - q_vector->tx.target_itr); + q_vector->tx.target_itr >> 1); q_vector->tx.current_itr = q_vector->tx.target_itr; wr32(hw, I40E_PFINT_RATEN(vector - 1), @@ -3646,11 +3734,11 @@ /* set the ITR configuration */ q_vector->rx.next_update = jiffies + 1; q_vector->rx.target_itr = ITR_TO_REG(vsi->rx_rings[0]->itr_setting); - wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr); + wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), q_vector->rx.target_itr >> 1); q_vector->rx.current_itr = q_vector->rx.target_itr; q_vector->tx.next_update = jiffies + 1; q_vector->tx.target_itr = ITR_TO_REG(vsi->tx_rings[0]->itr_setting); - wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr); + wr32(hw, I40E_PFINT_ITR0(I40E_TX_ITR), q_vector->tx.target_itr >> 1); q_vector->tx.current_itr = q_vector->tx.target_itr; i40e_enable_misc_int_causes(pf); @@ -3979,8 +4067,16 @@ } if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) { - ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; - set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); + /* disable any further VFLR event notifications */ + if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) { + u32 reg = rd32(hw, I40E_PFINT_ICR0_ENA); + + reg &= ~I40E_PFINT_ICR0_VFLR_MASK; + wr32(hw, I40E_PFINT_ICR0_ENA, reg); + } else { + ena_mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; + set_bit(__I40E_VFLR_EVENT_PENDING, pf->state); + } } if (icr0 & I40E_PFINT_ICR0_GRST_MASK) { @@ -4386,11 +4482,10 @@ } /** - * i40e_vsi_control_tx - Start or stop a VSI's rings + * i40e_vsi_enable_tx - Start a VSI's rings * @vsi: the VSI being configured - * @enable: start or stop the rings **/ -static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) +static int i40e_vsi_enable_tx(struct i40e_vsi *vsi) { struct i40e_pf *pf = vsi->back; int i, pf_q, ret = 0; @@ -4399,7 +4494,7 @@ for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { ret = i40e_control_wait_tx_q(vsi->seid, pf, pf_q, - false /*is xdp*/, enable); + false /*is xdp*/, true); if (ret) break; @@ -4408,7 +4503,7 @@ ret = i40e_control_wait_tx_q(vsi->seid, pf, pf_q + vsi->alloc_queue_pairs, - true /*is xdp*/, enable); + true /*is xdp*/, true); if (ret) break; } @@ -4506,32 +4601,25 @@ } /** - * i40e_vsi_control_rx - Start or stop a VSI's rings + * i40e_vsi_enable_rx - Start a VSI's rings * @vsi: the VSI being configured - * @enable: start or stop the rings **/ -static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) +static int i40e_vsi_enable_rx(struct i40e_vsi *vsi) { struct i40e_pf *pf = vsi->back; int i, pf_q, ret = 0; pf_q = vsi->base_queue; for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - ret = i40e_control_wait_rx_q(pf, pf_q, enable); + ret = i40e_control_wait_rx_q(pf, pf_q, true); if (ret) { dev_info(&pf->pdev->dev, - "VSI seid %d Rx ring %d %sable timeout\n", - vsi->seid, pf_q, (enable ? "en" : "dis")); + "VSI seid %d Rx ring %d enable timeout\n", + vsi->seid, pf_q); break; } } - /* Due to HW errata, on Rx disable only, the register can indicate done - * before it really is. Needs 50ms to be sure - */ - if (!enable) - mdelay(50); - return ret; } @@ -4544,29 +4632,47 @@ int ret = 0; /* do rx first for enable and last for disable */ - ret = i40e_vsi_control_rx(vsi, true); + ret = i40e_vsi_enable_rx(vsi); if (ret) return ret; - ret = i40e_vsi_control_tx(vsi, true); + ret = i40e_vsi_enable_tx(vsi); return ret; } +#define I40E_DISABLE_TX_GAP_MSEC 50 + /** * i40e_vsi_stop_rings - Stop a VSI's rings * @vsi: the VSI being configured **/ void i40e_vsi_stop_rings(struct i40e_vsi *vsi) { + struct i40e_pf *pf = vsi->back; + int pf_q, err, q_end; + /* When port TX is suspended, don't wait */ if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state)) return i40e_vsi_stop_rings_no_wait(vsi); - /* do rx first for enable and last for disable - * Ignore return value, we need to shutdown whatever we can - */ - i40e_vsi_control_tx(vsi, false); - i40e_vsi_control_rx(vsi, false); + q_end = vsi->base_queue + vsi->num_queue_pairs; + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) + i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false); + + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) { + err = i40e_control_wait_rx_q(pf, pf_q, false); + if (err) + dev_info(&pf->pdev->dev, + "VSI seid %d Rx ring %d dissable timeout\n", + vsi->seid, pf_q); + } + + msleep(I40E_DISABLE_TX_GAP_MSEC); + pf_q = vsi->base_queue; + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) + wr32(&pf->hw, I40E_QTX_ENA(pf_q), 0); + + i40e_vsi_wait_queues_disabled(vsi); } /** @@ -4790,7 +4896,8 @@ { int i; - i40e_free_misc_vector(pf); + if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) + i40e_free_misc_vector(pf); i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, I40E_IWARP_IRQ_PILE_ID); @@ -4977,7 +5084,7 @@ { int v, ret = 0; - for (v = 0; v < pf->hw.func_caps.num_vsis; v++) { + for (v = 0; v < pf->num_alloc_vsi; v++) { if (pf->vsi[v]) { ret = i40e_vsi_wait_queues_disabled(pf->vsi[v]); if (ret) @@ -5344,6 +5451,58 @@ } /** + * i40e_update_adq_vsi_queues - update queue mapping for ADq VSI + * @vsi: the VSI being reconfigured + * @vsi_offset: offset from main VF VSI + */ +int i40e_update_adq_vsi_queues(struct i40e_vsi *vsi, int vsi_offset) +{ + struct i40e_vsi_context ctxt = {}; + struct i40e_pf *pf; + struct i40e_hw *hw; + int ret; + + if (!vsi) + return I40E_ERR_PARAM; + pf = vsi->back; + hw = &pf->hw; + + ctxt.seid = vsi->seid; + ctxt.pf_num = hw->pf_id; + ctxt.vf_num = vsi->vf_id + hw->func_caps.vf_base_id + vsi_offset; + ctxt.uplink_seid = vsi->uplink_seid; + ctxt.connection_type = I40E_AQ_VSI_CONN_TYPE_NORMAL; + ctxt.flags = I40E_AQ_VSI_TYPE_VF; + ctxt.info = vsi->info; + + i40e_vsi_setup_queue_map(vsi, &ctxt, vsi->tc_config.enabled_tc, + false); + if (vsi->reconfig_rss) { + vsi->rss_size = min_t(int, pf->alloc_rss_size, + vsi->num_queue_pairs); + ret = i40e_vsi_config_rss(vsi); + if (ret) { + dev_info(&pf->pdev->dev, "Failed to reconfig rss for num_queues\n"); + return ret; + } + vsi->reconfig_rss = false; + } + + ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); + if (ret) { + dev_info(&pf->pdev->dev, "Update vsi config failed, err %s aq_err %s\n", + i40e_stat_str(hw, ret), + i40e_aq_str(hw, hw->aq.asq_last_status)); + return ret; + } + /* update the local VSI info with updated queue map */ + i40e_vsi_update_queue_map(vsi, &ctxt); + vsi->info.valid_sections = 0; + + return ret; +} + +/** * i40e_vsi_config_tc - Configure VSI Tx Scheduler for given TC map * @vsi: VSI to be configured * @enabled_tc: TC bitmap @@ -5505,6 +5664,26 @@ } /** + * i40e_bw_bytes_to_mbits - Convert max_tx_rate from bytes to mbits + * @vsi: Pointer to vsi structure + * @max_tx_rate: max TX rate in bytes to be converted into Mbits + * + * Helper function to convert units before send to set BW limit + **/ +static u64 i40e_bw_bytes_to_mbits(struct i40e_vsi *vsi, u64 max_tx_rate) +{ + if (max_tx_rate < I40E_BW_MBPS_DIVISOR) { + dev_warn(&vsi->back->pdev->dev, + "Setting max tx rate to minimum usable value of 50Mbps.\n"); + max_tx_rate = I40E_BW_CREDIT_DIVISOR; + } else { + do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); + } + + return max_tx_rate; +} + +/** * i40e_set_bw_limit - setup BW limit for Tx traffic based on max_tx_rate * @vsi: VSI to be configured * @seid: seid of the channel/VSI @@ -5526,10 +5705,10 @@ max_tx_rate, seid); return -EINVAL; } - if (max_tx_rate && max_tx_rate < 50) { + if (max_tx_rate && max_tx_rate < I40E_BW_CREDIT_DIVISOR) { dev_warn(&pf->pdev->dev, "Setting max tx rate to minimum usable value of 50Mbps.\n"); - max_tx_rate = 50; + max_tx_rate = I40E_BW_CREDIT_DIVISOR; } /* Tx rate credits are in values of 50Mbps, 0 is disabled */ @@ -5634,24 +5813,6 @@ } /** - * i40e_is_any_channel - channel exist or not - * @vsi: ptr to VSI to which channels are associated with - * - * Returns true or false if channel(s) exist for associated VSI or not - **/ -static bool i40e_is_any_channel(struct i40e_vsi *vsi) -{ - struct i40e_channel *ch, *ch_tmp; - - list_for_each_entry_safe(ch, ch_tmp, &vsi->ch_list, list) { - if (ch->initialized) - return true; - } - - return false; -} - -/** * i40e_get_max_queues_for_channel * @vsi: ptr to VSI to which channels are associated with * @@ -6158,26 +6319,15 @@ /* By default we are in VEPA mode, if this is the first VF/VMDq * VSI to be added switch to VEB mode. */ - if ((!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) || - (!i40e_is_any_channel(vsi))) { - if (!is_power_of_2(vsi->tc_config.tc_info[0].qcount)) { - dev_dbg(&pf->pdev->dev, - "Failed to create channel. Override queues (%u) not power of 2\n", - vsi->tc_config.tc_info[0].qcount); - return -EINVAL; - } - if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { - pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; + if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { + pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; - if (vsi->type == I40E_VSI_MAIN) { - if (pf->flags & I40E_FLAG_TC_MQPRIO) - i40e_do_reset(pf, I40E_PF_RESET_FLAG, - true); - else - i40e_do_reset_safe(pf, - I40E_PF_RESET_FLAG); - } + if (vsi->type == I40E_VSI_MAIN) { + if (pf->flags & I40E_FLAG_TC_MQPRIO) + i40e_do_reset(pf, I40E_PF_RESET_FLAG, true); + else + i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); } /* now onwards for main VSI, number of queues will be value * of TC0's queue count @@ -6804,8 +6954,8 @@ for (i = 0; i < vsi->num_queue_pairs; i++) { i40e_clean_tx_ring(vsi->tx_rings[i]); if (i40e_enabled_xdp_vsi(vsi)) { - /* Make sure that in-progress ndo_xdp_xmit - * calls are completed. + /* Make sure that in-progress ndo_xdp_xmit and + * ndo_xsk_wakeup calls are completed. */ synchronize_rcu(); i40e_clean_tx_ring(vsi->xdp_rings[i]); @@ -6851,6 +7001,8 @@ } if (vsi->num_queue_pairs < (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) { + dev_err(&vsi->back->pdev->dev, + "Failed to create traffic channel, insufficient number of queues.\n"); return -EINVAL; } if (sum_max_rate > i40e_get_link_speed(vsi)) { @@ -7019,42 +7171,43 @@ static int i40e_fwd_ring_up(struct i40e_vsi *vsi, struct net_device *vdev, struct i40e_fwd_adapter *fwd) { + struct i40e_channel *ch = NULL, *ch_tmp, *iter; int ret = 0, num_tc = 1, i, aq_err; - struct i40e_channel *ch, *ch_tmp; struct i40e_pf *pf = vsi->back; struct i40e_hw *hw = &pf->hw; - if (list_empty(&vsi->macvlan_list)) - return -EINVAL; - /* Go through the list and find an available channel */ - list_for_each_entry_safe(ch, ch_tmp, &vsi->macvlan_list, list) { - if (!i40e_is_channel_macvlan(ch)) { - ch->fwd = fwd; + list_for_each_entry_safe(iter, ch_tmp, &vsi->macvlan_list, list) { + if (!i40e_is_channel_macvlan(iter)) { + iter->fwd = fwd; /* record configuration for macvlan interface in vdev */ for (i = 0; i < num_tc; i++) netdev_bind_sb_channel_queue(vsi->netdev, vdev, i, - ch->num_queue_pairs, - ch->base_queue); - for (i = 0; i < ch->num_queue_pairs; i++) { + iter->num_queue_pairs, + iter->base_queue); + for (i = 0; i < iter->num_queue_pairs; i++) { struct i40e_ring *tx_ring, *rx_ring; u16 pf_q; - pf_q = ch->base_queue + i; + pf_q = iter->base_queue + i; /* Get to TX ring ptr */ tx_ring = vsi->tx_rings[pf_q]; - tx_ring->ch = ch; + tx_ring->ch = iter; /* Get the RX ring ptr */ rx_ring = vsi->rx_rings[pf_q]; - rx_ring->ch = ch; + rx_ring->ch = iter; } + ch = iter; break; } } + if (!ch) + return -EINVAL; + /* Guarantee all rings are updated before we update the * MAC address filter. */ @@ -7168,6 +7321,7 @@ ch->num_queue_pairs = qcnt; if (!i40e_setup_channel(pf, vsi, ch)) { ret = -EINVAL; + kfree(ch); goto err_free; } ch->parent_vsi = vsi; @@ -7466,17 +7620,25 @@ vsi->seid); need_reset = true; goto exit; - } else { - dev_info(&vsi->back->pdev->dev, - "Setup channel (id:%u) utilizing num_queues %d\n", - vsi->seid, vsi->tc_config.tc_info[0].qcount); + } else if (enabled_tc && + (!is_power_of_2(vsi->tc_config.tc_info[0].qcount))) { + netdev_info(netdev, + "Failed to create channel. Override queues (%u) not power of 2\n", + vsi->tc_config.tc_info[0].qcount); + ret = -EINVAL; + need_reset = true; + goto exit; } + dev_info(&vsi->back->pdev->dev, + "Setup channel (id:%u) utilizing num_queues %d\n", + vsi->seid, vsi->tc_config.tc_info[0].qcount); + if (pf->flags & I40E_FLAG_TC_MQPRIO) { if (vsi->mqprio_qopt.max_rate[0]) { - u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; + u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, + vsi->mqprio_qopt.max_rate[0]); - do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); if (!ret) { u64 credits = max_tx_rate; @@ -7592,6 +7754,8 @@ if (filter->flags >= ARRAY_SIZE(flag_table)) return I40E_ERR_CONFIG; + memset(&cld_filter, 0, sizeof(cld_filter)); + /* copy element needed to add cloud filter from filter */ i40e_set_cld_element(filter, &cld_filter); @@ -7655,10 +7819,13 @@ return -EOPNOTSUPP; /* adding filter using src_port/src_ip is not supported at this stage */ - if (filter->src_port || filter->src_ipv4 || + if (filter->src_port || + (filter->src_ipv4 && filter->n_proto != ETH_P_IPV6) || !ipv6_addr_any(&filter->ip.v6.src_ip6)) return -EOPNOTSUPP; + memset(&cld_filter, 0, sizeof(cld_filter)); + /* copy element needed to add cloud filter from filter */ i40e_set_cld_element(filter, &cld_filter.element); @@ -7682,7 +7849,7 @@ cpu_to_le16(I40E_AQC_ADD_CLOUD_FILTER_MAC_VLAN_PORT); } - } else if (filter->dst_ipv4 || + } else if ((filter->dst_ipv4 && filter->n_proto != ETH_P_IPV6) || !ipv6_addr_any(&filter->ip.v6.dst_ip6)) { cld_filter.element.flags = cpu_to_le16(I40E_AQC_ADD_CLOUD_FILTER_IP_PORT); @@ -7992,6 +8159,11 @@ return -EOPNOTSUPP; } + if (!tc) { + dev_err(&pf->pdev->dev, "Unable to add filter because of invalid destination"); + return -EINVAL; + } + if (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state) || test_bit(__I40E_RESET_INTR_RECEIVED, pf->state)) return -EBUSY; @@ -8031,9 +8203,8 @@ err = i40e_add_del_cloud_filter(vsi, filter, true); if (err) { - dev_err(&pf->pdev->dev, - "Failed to add cloud filter, err %s\n", - i40e_stat_str(&pf->hw, err)); + dev_err(&pf->pdev->dev, "Failed to add cloud filter, err %d\n", + err); goto err; } @@ -8219,6 +8390,27 @@ } /** + * i40e_netif_set_realnum_tx_rx_queues - Update number of tx/rx queues + * @vsi: vsi structure + * + * This updates netdev's number of tx/rx queues + * + * Returns status of setting tx/rx queues + **/ +static int i40e_netif_set_realnum_tx_rx_queues(struct i40e_vsi *vsi) +{ + int ret; + + ret = netif_set_real_num_rx_queues(vsi->netdev, + vsi->num_queue_pairs); + if (ret) + return ret; + + return netif_set_real_num_tx_queues(vsi->netdev, + vsi->num_queue_pairs); +} + +/** * i40e_vsi_open - * @vsi: the VSI to open * @@ -8254,13 +8446,7 @@ goto err_setup_rx; /* Notify the stack of the actual queue counts. */ - err = netif_set_real_num_tx_queues(vsi->netdev, - vsi->num_queue_pairs); - if (err) - goto err_set_queues; - - err = netif_set_real_num_rx_queues(vsi->netdev, - vsi->num_queue_pairs); + err = i40e_netif_set_realnum_tx_rx_queues(vsi); if (err) goto err_set_queues; @@ -8269,6 +8455,8 @@ dev_driver_string(&pf->pdev->dev), dev_name(&pf->pdev->dev)); err = i40e_vsi_request_irq(vsi, int_name); + if (err) + goto err_setup_rx; } else { err = -EINVAL; @@ -8461,6 +8649,13 @@ dev_dbg(&pf->pdev->dev, "PFR requested\n"); i40e_handle_reset_warning(pf, lock_acquired); + } else if (reset_flags & I40E_PF_RESET_AND_REBUILD_FLAG) { + /* Request a PF Reset + * + * Resets PF and reinitializes PFs VSI. + */ + i40e_prep_for_reset(pf, lock_acquired); + i40e_reset_and_rebuild(pf, true, lock_acquired); dev_info(&pf->pdev->dev, pf->flags & I40E_FLAG_DISABLE_FW_LLDP ? "FW LLDP is disabled\n" : @@ -9572,7 +9767,7 @@ if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { /* retry with a larger buffer */ buf_len = data_size; - } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) { + } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { dev_info(&pf->pdev->dev, "capability discovery failed, err %s aq_err %s\n", i40e_stat_str(&pf->hw, err), @@ -9784,6 +9979,21 @@ } /** + * i40e_clean_xps_state - clean xps state for every tx_ring + * @vsi: ptr to the VSI + **/ +static void i40e_clean_xps_state(struct i40e_vsi *vsi) +{ + int i; + + if (vsi->tx_rings) + for (i = 0; i < vsi->num_queue_pairs; i++) + if (vsi->tx_rings[i]) + clear_bit(__I40E_TX_XPS_INIT_DONE, + vsi->tx_rings[i]->state); +} + +/** * i40e_prep_for_reset - prep for the core to reset * @pf: board private structure * @lock_acquired: indicates whether or not the lock has been acquired @@ -9814,8 +10024,10 @@ rtnl_unlock(); for (v = 0; v < pf->num_alloc_vsi; v++) { - if (pf->vsi[v]) + if (pf->vsi[v]) { + i40e_clean_xps_state(pf->vsi[v]); pf->vsi[v]->seid = 0; + } } i40e_shutdown_adminq(&pf->hw); @@ -9924,22 +10136,19 @@ **/ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) { - int old_recovery_mode_bit = test_bit(__I40E_RECOVERY_MODE, pf->state); + const bool is_recovery_mode_reported = i40e_check_recovery_mode(pf); struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; struct i40e_hw *hw = &pf->hw; - u8 set_fc_aq_fail = 0; i40e_status ret; u32 val; int v; if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) && - i40e_check_recovery_mode(pf)) { + is_recovery_mode_reported) i40e_set_ethtool_ops(pf->vsi[pf->lan_vsi]->netdev); - } if (test_bit(__I40E_DOWN, pf->state) && - !test_bit(__I40E_RECOVERY_MODE, pf->state) && - !old_recovery_mode_bit) + !test_bit(__I40E_RECOVERY_MODE, pf->state)) goto clear_recovery; dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n"); @@ -9953,15 +10162,9 @@ } i40e_get_oem_version(&pf->hw); - if (test_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state) && - ((hw->aq.fw_maj_ver == 4 && hw->aq.fw_min_ver <= 33) || - hw->aq.fw_maj_ver < 4) && hw->mac.type == I40E_MAC_XL710) { - /* The following delay is necessary for 4.33 firmware and older - * to recover after EMP reset. 200 ms should suffice but we - * put here 300 ms to be sure that FW is ready to operate - * after reset. - */ - mdelay(300); + if (test_and_clear_bit(__I40E_EMP_RESET_INTR_RECEIVED, pf->state)) { + /* The following delay is necessary for firmware update. */ + mdelay(1000); } /* re-verify the eeprom if we just had an EMP reset */ @@ -9972,13 +10175,12 @@ * accordingly with regard to resources initialization * and deinitialization */ - if (test_bit(__I40E_RECOVERY_MODE, pf->state) || - old_recovery_mode_bit) { + if (test_bit(__I40E_RECOVERY_MODE, pf->state)) { if (i40e_get_capabilities(pf, i40e_aqc_opc_list_func_capabilities)) goto end_unlock; - if (test_bit(__I40E_RECOVERY_MODE, pf->state)) { + if (is_recovery_mode_reported) { /* we're staying in recovery mode so we'll reinitialize * misc vector here */ @@ -10053,13 +10255,6 @@ i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - /* make sure our flow control settings are restored */ - ret = i40e_set_fc(&pf->hw, &set_fc_aq_fail, true); - if (ret) - dev_dbg(&pf->pdev->dev, "setting flow control: ret = %s last_status = %s\n", - i40e_stat_str(&pf->hw, ret), - i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - /* Rebuild the VSIs and VEBs that existed before reset. * They are still in our local switch element arrays, so only * need to rebuild the switch model in the HW. @@ -10114,10 +10309,10 @@ } if (vsi->mqprio_qopt.max_rate[0]) { - u64 max_tx_rate = vsi->mqprio_qopt.max_rate[0]; + u64 max_tx_rate = i40e_bw_bytes_to_mbits(vsi, + vsi->mqprio_qopt.max_rate[0]); u64 credits = 0; - do_div(max_tx_rate, I40E_BW_MBPS_DIVISOR); ret = i40e_set_bw_limit(vsi, vsi->seid, max_tx_rate); if (ret) goto end_unlock; @@ -10166,8 +10361,11 @@ pf->hw.aq.asq_last_status)); } /* reinit the misc interrupt */ - if (pf->flags & I40E_FLAG_MSIX_ENABLED) + if (pf->flags & I40E_FLAG_MSIX_ENABLED) { ret = i40e_setup_misc_vector(pf); + if (ret) + goto end_unlock; + } /* Add a filter to drop all Flow control frames from any VSI from being * transmitted. By doing so we stop a malicious VF from sending out @@ -10815,10 +11013,10 @@ if (vsi->tx_rings && vsi->tx_rings[0]) { for (i = 0; i < vsi->alloc_queue_pairs; i++) { kfree_rcu(vsi->tx_rings[i], rcu); - vsi->tx_rings[i] = NULL; - vsi->rx_rings[i] = NULL; + WRITE_ONCE(vsi->tx_rings[i], NULL); + WRITE_ONCE(vsi->rx_rings[i], NULL); if (vsi->xdp_rings) - vsi->xdp_rings[i] = NULL; + WRITE_ONCE(vsi->xdp_rings[i], NULL); } } } @@ -10852,7 +11050,7 @@ if (vsi->back->hw_features & I40E_HW_WB_ON_ITR_CAPABLE) ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; ring->itr_setting = pf->tx_itr_default; - vsi->tx_rings[i] = ring++; + WRITE_ONCE(vsi->tx_rings[i], ring++); if (!i40e_enabled_xdp_vsi(vsi)) goto setup_rx; @@ -10870,7 +11068,7 @@ ring->flags = I40E_TXR_FLAGS_WB_ON_ITR; set_ring_xdp(ring); ring->itr_setting = pf->tx_itr_default; - vsi->xdp_rings[i] = ring++; + WRITE_ONCE(vsi->xdp_rings[i], ring++); setup_rx: ring->queue_index = i; @@ -10883,7 +11081,7 @@ ring->size = 0; ring->dcb_tc = 0; ring->itr_setting = pf->rx_itr_default; - vsi->rx_rings[i] = ring; + WRITE_ONCE(vsi->rx_rings[i], ring); } return 0; @@ -11264,7 +11462,6 @@ return -ENOMEM; pf->irq_pile->num_entries = vectors; - pf->irq_pile->search_hint = 0; /* track first vector for misc interrupts, ignore return */ (void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1); @@ -11396,7 +11593,7 @@ /* associate no queues to the misc vector */ wr32(hw, I40E_PFINT_LNKLST0, I40E_QUEUE_END_OF_LIST); - wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), I40E_ITR_8K); + wr32(hw, I40E_PFINT_ITR0(I40E_RX_ITR), I40E_ITR_8K >> 1); i40e_flush(hw); @@ -11742,6 +11939,8 @@ struct i40e_aqc_configure_partition_bw_data bw_data; i40e_status status; + memset(&bw_data, 0, sizeof(bw_data)); + /* Set the valid bit for this PF */ bw_data.pf_valid_bits = cpu_to_le16(BIT(pf->hw.pf_id)); bw_data.max_bw[pf->hw.pf_id] = pf->max_bw & I40E_ALT_BW_VALUE_MASK; @@ -11848,6 +12047,7 @@ { int err = 0; int size; + u16 pow; /* Set default capability flags */ pf->flags = I40E_FLAG_RX_CSUM_ENABLED | @@ -11866,6 +12066,11 @@ pf->rss_table_size = pf->hw.func_caps.rss_table_size; pf->rss_size_max = min_t(int, pf->rss_size_max, pf->hw.func_caps.num_tx_qp); + + /* find the next higher power-of-2 of num cpus */ + pow = roundup_pow_of_two(num_online_cpus()); + pf->rss_size_max = min_t(int, pf->rss_size_max, pow); + if (pf->hw.func_caps.rss) { pf->flags |= I40E_FLAG_RSS_ENABLED; pf->alloc_rss_size = min_t(int, pf->rss_size_max, @@ -12007,7 +12212,6 @@ goto sw_init_done; } pf->qp_pile->num_entries = pf->hw.func_caps.num_tx_qp; - pf->qp_pile->search_hint = 0; pf->tx_timeout_recovery_level = 1; @@ -12359,6 +12563,8 @@ } br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + if (!br_spec) + return -EINVAL; nla_for_each_nested(attr, br_spec, rem) { __u16 mode; @@ -12526,8 +12732,12 @@ old_prog = xchg(&vsi->xdp_prog, prog); - if (need_reset) + if (need_reset) { + if (!prog) + /* Wait until ndo_xsk_wakeup completes. */ + synchronize_rcu(); i40e_reset_and_rebuild(pf, true, true); + } for (i = 0; i < vsi->num_queue_pairs; i++) WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog); @@ -12847,6 +13057,7 @@ .ndo_poll_controller = i40e_netpoll, #endif .ndo_setup_tc = __i40e_setup_tc, + .ndo_select_queue = i40e_lan_select_queue, .ndo_set_features = i40e_set_features, .ndo_set_vf_mac = i40e_ndo_set_vf_mac, .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, @@ -13280,15 +13491,15 @@ vsi->id = ctxt.vsi_number; } - vsi->active_filters = 0; - clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); spin_lock_bh(&vsi->mac_filter_hash_lock); + vsi->active_filters = 0; /* If macvlan filters already exist, force them to get loaded */ hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) { f->state = I40E_FILTER_NEW; f_count++; } spin_unlock_bh(&vsi->mac_filter_hash_lock); + clear_bit(__I40E_VSI_OVERFLOW_PROMISC, vsi->state); if (f_count) { vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED; @@ -13338,7 +13549,7 @@ dev_info(&pf->pdev->dev, "Can't remove PF VSI\n"); return -ENODEV; } - + set_bit(__I40E_VSI_RELEASING, vsi->state); uplink_seid = vsi->uplink_seid; if (vsi->type != I40E_VSI_SRIOV) { if (vsi->netdev_registered) { @@ -13670,6 +13881,9 @@ ret = i40e_config_netdev(vsi); if (ret) goto err_netdev; + ret = i40e_netif_set_realnum_tx_rx_queues(vsi); + if (ret) + goto err_netdev; ret = register_netdev(vsi->netdev); if (ret) goto err_netdev; @@ -14637,6 +14851,7 @@ int err; int v_idx; + pci_set_drvdata(pf->pdev, pf); pci_save_state(pf->pdev); /* set up periodic task facility */ @@ -14672,12 +14887,16 @@ * in order to register the netdev */ v_idx = i40e_vsi_mem_alloc(pf, I40E_VSI_MAIN); - if (v_idx < 0) + if (v_idx < 0) { + err = v_idx; goto err_switch_setup; + } pf->lan_vsi = v_idx; vsi = pf->vsi[v_idx]; - if (!vsi) + if (!vsi) { + err = -EFAULT; goto err_switch_setup; + } vsi->alloc_queue_pairs = 1; err = i40e_config_netdev(vsi); if (err) @@ -14736,7 +14955,6 @@ int err; u32 val; u32 i; - u8 set_fc_aq_fail; err = pci_enable_device_mem(pdev); if (err) @@ -14911,8 +15129,8 @@ if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && hw->aq.api_min_ver > I40E_FW_MINOR_VERSION(hw)) - dev_info(&pdev->dev, - "The driver for the device detected a newer version of the NVM image v%u.%u than expected v%u.%u. Please install the most recent version of the network driver.\n", + dev_dbg(&pdev->dev, + "The driver for the device detected a newer version of the NVM image v%u.%u than v%u.%u.\n", hw->aq.api_maj_ver, hw->aq.api_min_ver, I40E_FW_API_VERSION_MAJOR, @@ -15058,24 +15276,6 @@ } INIT_LIST_HEAD(&pf->vsi[pf->lan_vsi]->ch_list); - /* Make sure flow control is set according to current settings */ - err = i40e_set_fc(hw, &set_fc_aq_fail, true); - if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_GET) - dev_dbg(&pf->pdev->dev, - "Set fc with err %s aq_err %s on get_phy_cap\n", - i40e_stat_str(hw, err), - i40e_aq_str(hw, hw->aq.asq_last_status)); - if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_SET) - dev_dbg(&pf->pdev->dev, - "Set fc with err %s aq_err %s on set_phy_config\n", - i40e_stat_str(hw, err), - i40e_aq_str(hw, hw->aq.asq_last_status)); - if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_UPDATE) - dev_dbg(&pf->pdev->dev, - "Set fc with err %s aq_err %s on get_link_info\n", - i40e_stat_str(hw, err), - i40e_aq_str(hw, hw->aq.asq_last_status)); - /* if FDIR VSI was set up, start it now */ for (i = 0; i < pf->num_alloc_vsi; i++) { if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) { @@ -15132,6 +15332,8 @@ if (err) { dev_info(&pdev->dev, "setup of misc vector failed: %d\n", err); + i40e_cloud_filter_exit(pf); + i40e_fdir_teardown(pf); goto err_vsis; } } @@ -15328,6 +15530,14 @@ i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0); i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0); + while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state)) + usleep_range(1000, 2000); + + if (pf->flags & I40E_FLAG_SRIOV_ENABLED) { + set_bit(__I40E_VF_RESETS_DISABLED, pf->state); + i40e_free_vfs(pf); + pf->flags &= ~I40E_FLAG_SRIOV_ENABLED; + } /* no more scheduling of any task */ set_bit(__I40E_SUSPENDED, pf->state); set_bit(__I40E_DOWN, pf->state); @@ -15354,11 +15564,6 @@ */ i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false); - if (pf->flags & I40E_FLAG_SRIOV_ENABLED) { - i40e_free_vfs(pf); - pf->flags &= ~I40E_FLAG_SRIOV_ENABLED; - } - i40e_fdir_teardown(pf); /* If there is a switch structure or any orphans, remove them. @@ -15373,11 +15578,15 @@ i40e_switch_branch_release(pf->veb[i]); } - /* Now we can shutdown the PF's VSI, just before we kill + /* Now we can shutdown the PF's VSIs, just before we kill * adminq and hmc. */ - if (pf->vsi[pf->lan_vsi]) - i40e_vsi_release(pf->vsi[pf->lan_vsi]); + for (i = pf->num_alloc_vsi; i--;) + if (pf->vsi[i]) { + i40e_vsi_close(pf->vsi[i]); + i40e_vsi_release(pf->vsi[i]); + pf->vsi[i] = NULL; + } i40e_cloud_filter_exit(pf); @@ -15526,6 +15735,9 @@ struct i40e_pf *pf = pci_get_drvdata(pdev); i40e_reset_and_rebuild(pf, false, false); +#ifdef CONFIG_PCI_IOV + i40e_restore_all_vfs_msi_state(pdev); +#endif /* CONFIG_PCI_IOV */ } /** @@ -15778,7 +15990,7 @@ * since we need to be able to guarantee forward progress even under * memory pressure. */ - i40e_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, i40e_driver_name); + i40e_wq = alloc_workqueue("%s", 0, 0, i40e_driver_name); if (!i40e_wq) { pr_err("%s: Failed to create workqueue\n", i40e_driver_name); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -210,11 +210,11 @@ * @hw: pointer to the HW structure. * @module_pointer: module pointer location in words from the NVM beginning * @offset: offset in words from module start - * @words: number of words to write - * @data: buffer with words to write to the Shadow RAM + * @words: number of words to read + * @data: buffer with words to read to the Shadow RAM * @last_command: tells the AdminQ that this is the last command * - * Writes a 16 bit words buffer to the Shadow RAM using the admin command. + * Reads a 16 bit words buffer to the Shadow RAM using the admin command. **/ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer, u32 offset, @@ -234,18 +234,18 @@ */ if ((offset + words) > hw->nvm.sr_size) i40e_debug(hw, I40E_DEBUG_NVM, - "NVM write error: offset %d beyond Shadow RAM limit %d\n", + "NVM read error: offset %d beyond Shadow RAM limit %d\n", (offset + words), hw->nvm.sr_size); else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS) - /* We can write only up to 4KB (one sector), in one AQ write */ + /* We can read only up to 4KB (one sector), in one AQ write */ i40e_debug(hw, I40E_DEBUG_NVM, - "NVM write fail error: tried to write %d words, limit is %d.\n", + "NVM read fail error: tried to read %d words, limit is %d.\n", words, I40E_SR_SECTOR_SIZE_IN_WORDS); else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS) != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS)) - /* A single write cannot spread over two sectors */ + /* A single read cannot spread over two sectors */ i40e_debug(hw, I40E_DEBUG_NVM, - "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n", + "NVM read error: cannot spread over two sectors in a single read offset=%d words=%d\n", offset, words); else ret_code = i40e_aq_read_nvm(hw, module_pointer, @@ -323,20 +323,24 @@ /** * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location - * @hw: pointer to the HW structure + * @hw: Pointer to the HW structure * @module_ptr: Pointer to module in words with respect to NVM beginning - * @offset: offset in words from module start + * @module_offset: Offset in words from module start + * @data_offset: Offset in words from reading data area start * @words_data_size: Words to read from NVM * @data_ptr: Pointer to memory location where resulting buffer will be stored **/ -i40e_status i40e_read_nvm_module_data(struct i40e_hw *hw, - u8 module_ptr, u16 offset, - u16 words_data_size, - u16 *data_ptr) +enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw, + u8 module_ptr, + u16 module_offset, + u16 data_offset, + u16 words_data_size, + u16 *data_ptr) { i40e_status status; + u16 specific_ptr = 0; u16 ptr_value = 0; - u32 flat_offset; + u32 offset = 0; if (module_ptr != 0) { status = i40e_read_nvm_word(hw, module_ptr, &ptr_value); @@ -352,36 +356,35 @@ /* Pointer not initialized */ if (ptr_value == I40E_NVM_INVALID_PTR_VAL || - ptr_value == I40E_NVM_INVALID_VAL) + ptr_value == I40E_NVM_INVALID_VAL) { + i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n"); return I40E_ERR_BAD_PTR; + } /* Check whether the module is in SR mapped area or outside */ if (ptr_value & I40E_PTR_TYPE) { /* Pointer points outside of the Shared RAM mapped area */ - ptr_value &= ~I40E_PTR_TYPE; + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n"); - /* PtrValue in 4kB units, need to convert to words */ - ptr_value /= 2; - flat_offset = ((u32)ptr_value * 0x1000) + (u32)offset; - status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ); - if (!status) { - status = i40e_aq_read_nvm(hw, 0, 2 * flat_offset, - 2 * words_data_size, - data_ptr, true, NULL); - i40e_release_nvm(hw); - if (status) { - i40e_debug(hw, I40E_DEBUG_ALL, - "Reading nvm aq failed.Error code: %d.\n", - status); - return I40E_ERR_NVM; - } - } else { - return I40E_ERR_NVM; - } + return I40E_ERR_PARAM; } else { /* Read from the Shadow RAM */ - status = i40e_read_nvm_buffer(hw, ptr_value + offset, - &words_data_size, data_ptr); + + status = i40e_read_nvm_word(hw, ptr_value + module_offset, + &specific_ptr); + if (status) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm word failed.Error code: %d.\n", + status); + return I40E_ERR_NVM; + } + + offset = ptr_value + module_offset + specific_ptr + + data_offset; + + status = i40e_read_nvm_buffer(hw, offset, &words_data_size, + data_ptr); if (status) { i40e_debug(hw, I40E_DEBUG_ALL, "Reading nvm buffer failed.Error code: %d.\n", --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_prototype.h @@ -315,10 +315,12 @@ void i40e_release_nvm(struct i40e_hw *hw); i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, u16 *data); -i40e_status i40e_read_nvm_module_data(struct i40e_hw *hw, - u8 module_ptr, u16 offset, - u16 words_data_size, - u16 *data_ptr); +enum i40e_status_code i40e_read_nvm_module_data(struct i40e_hw *hw, + u8 module_ptr, + u16 module_offset, + u16 data_offset, + u16 words_data_size, + u16 *data_ptr); i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data); i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1195,6 +1195,11 @@ rc->total_packets = 0; } +static struct i40e_rx_buffer *i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx) +{ + return &rx_ring->rx_bi[idx]; +} + /** * i40e_reuse_rx_page - page flip buffer and store it back on the ring * @rx_ring: rx descriptor ring to store buffers on @@ -1208,7 +1213,7 @@ struct i40e_rx_buffer *new_buff; u16 nta = rx_ring->next_to_alloc; - new_buff = &rx_ring->rx_bi[nta]; + new_buff = i40e_rx_bi(rx_ring, nta); /* update, and store next to alloc */ nta++; @@ -1272,7 +1277,7 @@ ntc = rx_ring->next_to_clean; /* fetch, update, and store next to clean */ - rx_buffer = &rx_ring->rx_bi[ntc++]; + rx_buffer = i40e_rx_bi(rx_ring, ntc++); ntc = (ntc < rx_ring->count) ? ntc : 0; rx_ring->next_to_clean = ntc; @@ -1361,7 +1366,7 @@ /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { - struct i40e_rx_buffer *rx_bi = &rx_ring->rx_bi[i]; + struct i40e_rx_buffer *rx_bi = i40e_rx_bi(rx_ring, i); if (!rx_bi->page) continue; @@ -1576,7 +1581,7 @@ return false; rx_desc = I40E_RX_DESC(rx_ring, ntu); - bi = &rx_ring->rx_bi[ntu]; + bi = i40e_rx_bi(rx_ring, ntu); do { if (!i40e_alloc_mapped_page(rx_ring, bi)) @@ -1598,7 +1603,7 @@ ntu++; if (unlikely(ntu == rx_ring->count)) { rx_desc = I40E_RX_DESC(rx_ring, 0); - bi = rx_ring->rx_bi; + bi = i40e_rx_bi(rx_ring, 0); ntu = 0; } @@ -1864,6 +1869,7 @@ * the adapter for another receive * * @rx_buffer: buffer containing the page + * @rx_buffer_pgcnt: buffer page refcount pre xdp_do_redirect() call * * If page is reusable, rx_buffer->page_offset is adjusted to point to * an unused region in the page. @@ -1886,7 +1892,8 @@ * * In either case, if the page is reusable its refcount is increased. **/ -static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer) +static bool i40e_can_reuse_rx_page(struct i40e_rx_buffer *rx_buffer, + int rx_buffer_pgcnt) { unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; struct page *page = rx_buffer->page; @@ -1897,7 +1904,7 @@ #if (PAGE_SIZE < 8192) /* if we are only owner of page we can reuse it */ - if (unlikely((page_count(page) - pagecnt_bias) > 1)) + if (unlikely((rx_buffer_pgcnt - pagecnt_bias) > 1)) return false; #else #define I40E_LAST_OFFSET \ @@ -1956,17 +1963,25 @@ * i40e_get_rx_buffer - Fetch Rx buffer and synchronize data for use * @rx_ring: rx descriptor ring to transact packets on * @size: size of buffer to add to skb + * @rx_buffer_pgcnt: buffer page refcount * * This function will pull an Rx buffer from the ring and synchronize it * for use by the CPU. */ static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring, - const unsigned int size) + const unsigned int size, + int *rx_buffer_pgcnt) { struct i40e_rx_buffer *rx_buffer; - rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; - prefetchw(rx_buffer->page); + rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); + *rx_buffer_pgcnt = +#if (PAGE_SIZE < 8192) + page_count(rx_buffer->page); +#else + 0; +#endif + prefetch_page_address(rx_buffer->page); /* we are reusing so sync this buffer for CPU use */ dma_sync_single_range_for_cpu(rx_ring->dev, @@ -2120,14 +2135,16 @@ * i40e_put_rx_buffer - Clean up used buffer and either recycle or free * @rx_ring: rx descriptor ring to transact packets on * @rx_buffer: rx buffer to pull data from + * @rx_buffer_pgcnt: rx buffer page refcount pre xdp_do_redirect() call * * This function will clean up the contents of the rx_buffer. It will * either recycle the buffer or unmap it and free the associated resources. */ static void i40e_put_rx_buffer(struct i40e_ring *rx_ring, - struct i40e_rx_buffer *rx_buffer) + struct i40e_rx_buffer *rx_buffer, + int rx_buffer_pgcnt) { - if (i40e_can_reuse_rx_page(rx_buffer)) { + if (i40e_can_reuse_rx_page(rx_buffer, rx_buffer_pgcnt)) { /* hand second half of page back to the ring */ i40e_reuse_rx_page(rx_ring, rx_buffer); } else { @@ -2216,15 +2233,20 @@ case XDP_TX: xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); + if (result == I40E_XDP_CONSUMED) + goto out_failure; break; case XDP_REDIRECT: err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); - result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; + if (err) + goto out_failure; + result = I40E_XDP_REDIR; break; default: bpf_warn_invalid_xdp_action(act); /* fall through */ case XDP_ABORTED: +out_failure: trace_xdp_exception(rx_ring->netdev, xdp_prog, act); /* fall through -- handle aborts by dropping packet */ case XDP_DROP: @@ -2340,6 +2362,7 @@ while (likely(total_rx_packets < (unsigned int)budget)) { struct i40e_rx_buffer *rx_buffer; union i40e_rx_desc *rx_desc; + int rx_buffer_pgcnt; unsigned int size; u64 qword; @@ -2379,7 +2402,7 @@ break; i40e_trace(clean_rx_irq, rx_ring, rx_desc, skb); - rx_buffer = i40e_get_rx_buffer(rx_ring, size); + rx_buffer = i40e_get_rx_buffer(rx_ring, size, &rx_buffer_pgcnt); /* retrieve a buffer from the ring */ if (!skb) { @@ -2419,7 +2442,7 @@ break; } - i40e_put_rx_buffer(rx_ring, rx_buffer); + i40e_put_rx_buffer(rx_ring, rx_buffer, rx_buffer_pgcnt); cleaned_count++; if (i40e_is_non_eop(rx_ring, rx_desc, skb)) @@ -2646,7 +2669,7 @@ return budget; } - if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR) + if (q_vector->tx.ring[0].flags & I40E_TXR_FLAGS_WB_ON_ITR) q_vector->arm_wb_state = false; /* Exit the polling mode, but don't re-enable interrupts if stack might @@ -3075,13 +3098,16 @@ l4_proto = ip.v4->protocol; } else if (*tx_flags & I40E_TX_FLAGS_IPV6) { + int ret; + tunnel |= I40E_TX_CTX_EXT_IP_IPV6; exthdr = ip.hdr + sizeof(*ip.v6); l4_proto = ip.v6->nexthdr; - if (l4.hdr != exthdr) - ipv6_skip_exthdr(skb, exthdr - skb->data, - &l4_proto, &frag_off); + ret = ipv6_skip_exthdr(skb, exthdr - skb->data, + &l4_proto, &frag_off); + if (ret < 0) + return -1; } /* define outer transport */ @@ -3495,6 +3521,55 @@ return -1; } +static u16 i40e_swdcb_skb_tx_hash(struct net_device *dev, + const struct sk_buff *skb, + u16 num_tx_queues) +{ + u32 jhash_initval_salt = 0xd631614b; + u32 hash; + + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else + hash = (__force u16)skb->protocol ^ skb->hash; + + hash = jhash_1word(hash, jhash_initval_salt); + + return (u16)(((u64)hash * num_tx_queues) >> 32); +} + +u16 i40e_lan_select_queue(struct net_device *netdev, + struct sk_buff *skb, + struct net_device __always_unused *sb_dev) +{ + struct i40e_netdev_priv *np = netdev_priv(netdev); + struct i40e_vsi *vsi = np->vsi; + struct i40e_hw *hw; + u16 qoffset; + u16 qcount; + u8 tclass; + u16 hash; + u8 prio; + + /* is DCB enabled at all? */ + if (vsi->tc_config.numtc == 1) + return netdev_pick_tx(netdev, skb, sb_dev); + + prio = skb->priority; + hw = &vsi->back->hw; + tclass = hw->local_dcbx_config.etscfg.prioritytable[prio]; + /* sanity check */ + if (unlikely(!(vsi->tc_config.enabled_tc & BIT(tclass)))) + tclass = 0; + + /* select a queue assigned for the given TC */ + qcount = vsi->tc_config.tc_info[tclass].qcount; + hash = i40e_swdcb_skb_tx_hash(netdev, skb, qcount); + + qoffset = vsi->tc_config.tc_info[tclass].qoffset; + return qoffset + hash; +} + /** * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring * @xdp: data to transmit --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -481,6 +481,8 @@ bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count); netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev); +u16 i40e_lan_select_queue(struct net_device *netdev, struct sk_buff *skb, + struct net_device *sb_dev); void i40e_clean_tx_ring(struct i40e_ring *tx_ring); void i40e_clean_rx_ring(struct i40e_ring *rx_ring); int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_type.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -253,11 +253,8 @@ #define I40E_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC + \ I40E_PHY_TYPE_OFFSET) /* Offset for 2.5G/5G PHY Types value to bit number conversion */ -#define I40E_PHY_TYPE_OFFSET2 (-10) -#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T + \ - I40E_PHY_TYPE_OFFSET2) -#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T + \ - I40E_PHY_TYPE_OFFSET2) +#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T) +#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T) #define I40E_HW_CAP_MAX_GPIO 30 /* Capabilities of a PF or a VF or the whole device */ struct i40e_hw_capabilities { @@ -1473,6 +1470,10 @@ #define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000 /* INPUT SET MASK for RSS, flow director, and flexible payload */ +#define I40E_X722_L3_SRC_SHIFT 49 +#define I40E_X722_L3_SRC_MASK (0x3ULL << I40E_X722_L3_SRC_SHIFT) +#define I40E_X722_L3_DST_SHIFT 41 +#define I40E_X722_L3_DST_MASK (0x3ULL << I40E_X722_L3_DST_SHIFT) #define I40E_L3_SRC_SHIFT 47 #define I40E_L3_SRC_MASK (0x3ULL << I40E_L3_SRC_SHIFT) #define I40E_L3_V6_SRC_SHIFT 43 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -55,12 +55,7 @@ pfe.event = VIRTCHNL_EVENT_LINK_CHANGE; pfe.severity = PF_EVENT_SEVERITY_INFO; - - /* Always report link is down if the VF queues aren't enabled */ - if (!vf->queues_enabled) { - pfe.event_data.link_event.link_status = false; - pfe.event_data.link_event.link_speed = 0; - } else if (vf->link_forced) { + if (vf->link_forced) { pfe.event_data.link_event.link_status = vf->link_up; pfe.event_data.link_event.link_speed = (vf->link_up ? VIRTCHNL_LINK_SPEED_40GB : 0); @@ -70,7 +65,6 @@ pfe.event_data.link_event.link_speed = i40e_virtchnl_link_speed(ls->link_speed); } - i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT, 0, (u8 *)&pfe, sizeof(pfe), NULL); } @@ -105,6 +99,32 @@ (u8 *)&pfe, sizeof(struct virtchnl_pf_event)); } +#ifdef CONFIG_PCI_IOV +void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev) +{ + u16 vf_id; + u16 pos; + + /* Continue only if this is a PF */ + if (!pdev->is_physfn) + return; + + if (!pci_num_vf(pdev)) + return; + + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (pos) { + struct pci_dev *vf_dev = NULL; + + pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id); + while ((vf_dev = pci_get_device(pdev->vendor, vf_id, vf_dev))) { + if (vf_dev->is_virtfn && vf_dev->physfn == pdev) + pci_restore_msi_state(vf_dev); + } + } +} +#endif /* CONFIG_PCI_IOV */ + /** * i40e_vc_notify_vf_reset * @vf: pointer to the VF structure @@ -136,16 +156,18 @@ /***********************misc routines*****************************/ /** - * i40e_vc_disable_vf + * i40e_vc_reset_vf * @vf: pointer to the VF info - * - * Disable the VF through a SW reset. + * @notify_vf: notify vf about reset or not + * Reset VF handler. **/ -static inline void i40e_vc_disable_vf(struct i40e_vf *vf) +static void i40e_vc_reset_vf(struct i40e_vf *vf, bool notify_vf) { + struct i40e_pf *pf = vf->pf; int i; - i40e_vc_notify_vf_reset(vf); + if (notify_vf) + i40e_vc_notify_vf_reset(vf); /* We want to ensure that an actual reset occurs initiated after this * function was called. However, we do not want to wait forever, so @@ -153,14 +175,24 @@ * ensure a reset. */ for (i = 0; i < 20; i++) { + /* If PF is in VFs releasing state reset VF is impossible, + * so leave it. + */ + if (test_bit(__I40E_VFS_RELEASING, pf->state)) + return; if (i40e_reset_vf(vf, false)) return; usleep_range(10000, 20000); } - dev_warn(&vf->pf->pdev->dev, - "Failed to initiate reset for VF %d after 200 milliseconds\n", - vf->vf_id); + if (notify_vf) + dev_warn(&vf->pf->pdev->dev, + "Failed to initiate reset for VF %d after 200 milliseconds\n", + vf->vf_id); + else + dev_dbg(&vf->pf->pdev->dev, + "Failed to initiate reset for VF %d after 200 milliseconds\n", + vf->vf_id); } /** @@ -621,14 +653,13 @@ u16 vsi_queue_id, struct virtchnl_rxq_info *info) { + u16 pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx]; struct i40e_hw *hw = &pf->hw; struct i40e_hmc_obj_rxq rx_ctx; - u16 pf_queue_id; int ret = 0; - pf_queue_id = i40e_vc_get_pf_queue_id(vf, vsi_id, vsi_queue_id); - /* clear the context structure first */ memset(&rx_ctx, 0, sizeof(struct i40e_hmc_obj_rxq)); @@ -666,6 +697,10 @@ } rx_ctx.rxmax = info->max_pkt_size; + /* if port VLAN is configured increase the max packet size */ + if (vsi->info.pvid) + rx_ctx.rxmax += VLAN_HLEN; + /* enable 32bytes desc always */ rx_ctx.dsize = 1; @@ -955,7 +990,6 @@ i40e_vsi_release(pf->vsi[vf->lan_vsi_idx]); vf->lan_vsi_idx = 0; vf->lan_vsi_id = 0; - vf->num_mac = 0; } /* do the accounting and remove additional ADq VSI's */ @@ -1107,39 +1141,98 @@ return -EIO; } -static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi); +/** + * __i40e_getnum_vf_vsi_vlan_filters + * @vsi: pointer to the vsi + * + * called to get the number of VLANs offloaded on this VF + **/ +static int __i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) +{ + struct i40e_mac_filter *f; + u16 num_vlans = 0, bkt; + + hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { + if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID) + num_vlans++; + } + + return num_vlans; +} /** - * i40e_config_vf_promiscuous_mode - * @vf: pointer to the VF info - * @vsi_id: VSI id - * @allmulti: set MAC L2 layer multicast promiscuous enable/disable - * @alluni: set MAC L2 layer unicast promiscuous enable/disable + * i40e_getnum_vf_vsi_vlan_filters + * @vsi: pointer to the vsi * - * Called from the VF to configure the promiscuous mode of - * VF vsis and from the VF reset path to reset promiscuous mode. + * wrapper for __i40e_getnum_vf_vsi_vlan_filters() with spinlock held **/ -static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, - u16 vsi_id, - bool allmulti, - bool alluni) +static int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) +{ + int num_vlans; + + spin_lock_bh(&vsi->mac_filter_hash_lock); + num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi); + spin_unlock_bh(&vsi->mac_filter_hash_lock); + + return num_vlans; +} + +/** + * i40e_get_vlan_list_sync + * @vsi: pointer to the VSI + * @num_vlans: number of VLANs in mac_filter_hash, returned to caller + * @vlan_list: list of VLANs present in mac_filter_hash, returned to caller. + * This array is allocated here, but has to be freed in caller. + * + * Called to get number of VLANs and VLAN list present in mac_filter_hash. + **/ +static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans, + s16 **vlan_list) { - struct i40e_pf *pf = vf->pf; - struct i40e_hw *hw = &pf->hw; struct i40e_mac_filter *f; - i40e_status aq_ret = 0; - struct i40e_vsi *vsi; + int i = 0; int bkt; - vsi = i40e_find_vsi_from_id(pf, vsi_id); - if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi) - return I40E_ERR_PARAM; + spin_lock_bh(&vsi->mac_filter_hash_lock); + *num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi); + *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC); + if (!(*vlan_list)) + goto err; - if (vf->port_vlan_id) { - aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, vsi->seid, - allmulti, - vf->port_vlan_id, - NULL); + hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { + if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID) + continue; + (*vlan_list)[i++] = f->vlan; + } +err: + spin_unlock_bh(&vsi->mac_filter_hash_lock); +} + +/** + * i40e_set_vsi_promisc + * @vf: pointer to the VF struct + * @seid: VSI number + * @multi_enable: set MAC L2 layer multicast promiscuous enable/disable + * for a given VLAN + * @unicast_enable: set MAC L2 layer unicast promiscuous enable/disable + * for a given VLAN + * @vl: List of VLANs - apply filter for given VLANs + * @num_vlans: Number of elements in @vl + **/ +static i40e_status +i40e_set_vsi_promisc(struct i40e_vf *vf, u16 seid, bool multi_enable, + bool unicast_enable, s16 *vl, u16 num_vlans) +{ + i40e_status aq_ret, aq_tmp = 0; + struct i40e_pf *pf = vf->pf; + struct i40e_hw *hw = &pf->hw; + int i; + + /* No VLAN to set promisc on, set on VSI */ + if (!num_vlans || !vl) { + aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, seid, + multi_enable, + NULL); if (aq_ret) { int aq_err = pf->hw.aq.asq_last_status; @@ -1148,13 +1241,14 @@ vf->vf_id, i40e_stat_str(&pf->hw, aq_ret), i40e_aq_str(&pf->hw, aq_err)); + return aq_ret; } - aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, vsi->seid, - alluni, - vf->port_vlan_id, - NULL); + aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, seid, + unicast_enable, + NULL, true); + if (aq_ret) { int aq_err = pf->hw.aq.asq_last_status; @@ -1164,68 +1258,94 @@ i40e_stat_str(&pf->hw, aq_ret), i40e_aq_str(&pf->hw, aq_err)); } + return aq_ret; - } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) { - hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { - if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID) - continue; - aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, - vsi->seid, - allmulti, - f->vlan, - NULL); - if (aq_ret) { - int aq_err = pf->hw.aq.asq_last_status; + } - dev_err(&pf->pdev->dev, - "Could not add VLAN %d to multicast promiscuous domain err %s aq_err %s\n", - f->vlan, - i40e_stat_str(&pf->hw, aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - } + for (i = 0; i < num_vlans; i++) { + aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw, seid, + multi_enable, + vl[i], NULL); + if (aq_ret) { + int aq_err = pf->hw.aq.asq_last_status; - aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, - vsi->seid, - alluni, - f->vlan, - NULL); - if (aq_ret) { - int aq_err = pf->hw.aq.asq_last_status; + dev_err(&pf->pdev->dev, + "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n", + vf->vf_id, + i40e_stat_str(&pf->hw, aq_ret), + i40e_aq_str(&pf->hw, aq_err)); - dev_err(&pf->pdev->dev, - "Could not add VLAN %d to Unicast promiscuous domain err %s aq_err %s\n", - f->vlan, - i40e_stat_str(&pf->hw, aq_ret), - i40e_aq_str(&pf->hw, aq_err)); - } + if (!aq_tmp) + aq_tmp = aq_ret; + } + + aq_ret = i40e_aq_set_vsi_uc_promisc_on_vlan(hw, seid, + unicast_enable, + vl[i], NULL); + if (aq_ret) { + int aq_err = pf->hw.aq.asq_last_status; + + dev_err(&pf->pdev->dev, + "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n", + vf->vf_id, + i40e_stat_str(&pf->hw, aq_ret), + i40e_aq_str(&pf->hw, aq_err)); + + if (!aq_tmp) + aq_tmp = aq_ret; } - return aq_ret; } - aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti, - NULL); - if (aq_ret) { - int aq_err = pf->hw.aq.asq_last_status; - dev_err(&pf->pdev->dev, - "VF %d failed to set multicast promiscuous mode err %s aq_err %s\n", - vf->vf_id, - i40e_stat_str(&pf->hw, aq_ret), - i40e_aq_str(&pf->hw, aq_err)); + if (aq_tmp) + aq_ret = aq_tmp; + + return aq_ret; +} + +/** + * i40e_config_vf_promiscuous_mode + * @vf: pointer to the VF info + * @vsi_id: VSI id + * @allmulti: set MAC L2 layer multicast promiscuous enable/disable + * @alluni: set MAC L2 layer unicast promiscuous enable/disable + * + * Called from the VF to configure the promiscuous mode of + * VF vsis and from the VF reset path to reset promiscuous mode. + **/ +static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf, + u16 vsi_id, + bool allmulti, + bool alluni) +{ + i40e_status aq_ret = I40E_SUCCESS; + struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi; + u16 num_vlans; + s16 *vl; + + vsi = i40e_find_vsi_from_id(pf, vsi_id); + if (!i40e_vc_isvalid_vsi_id(vf, vsi_id) || !vsi) + return I40E_ERR_PARAM; + + if (vf->port_vlan_id) { + aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, + alluni, &vf->port_vlan_id, 1); return aq_ret; - } + } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) { + i40e_get_vlan_list_sync(vsi, &num_vlans, &vl); - aq_ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, alluni, - NULL, true); - if (aq_ret) { - int aq_err = pf->hw.aq.asq_last_status; + if (!vl) + return I40E_ERR_NO_MEMORY; - dev_err(&pf->pdev->dev, - "VF %d failed to set unicast promiscuous mode err %s aq_err %s\n", - vf->vf_id, - i40e_stat_str(&pf->hw, aq_ret), - i40e_aq_str(&pf->hw, aq_err)); + aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni, + vl, num_vlans); + kfree(vl); + return aq_ret; } + /* no VLANs to set on, set on VSI */ + aq_ret = i40e_set_vsi_promisc(vf, vsi->seid, allmulti, alluni, + NULL, 0); return aq_ret; } @@ -1335,7 +1455,8 @@ * @vf: pointer to the VF structure * @flr: VFLR was issued or not * - * Returns true if the VF is reset, false otherwise. + * Returns true if the VF is in reset, resets successfully, or resets + * are disabled and false otherwise. **/ bool i40e_reset_vf(struct i40e_vf *vf, bool flr) { @@ -1345,11 +1466,16 @@ u32 reg; int i; - /* If the VFs have been disabled, this means something else is - * resetting the VF, so we shouldn't continue. - */ - if (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) - return false; + if (test_bit(__I40E_VF_RESETS_DISABLED, pf->state)) + return true; + + /* Bail out if VFs are disabled. */ + if (test_bit(__I40E_VF_DISABLE, pf->state)) + return true; + + /* If VF is being reset already we don't need to continue. */ + if (test_and_set_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + return true; i40e_trigger_vf_reset(vf, flr); @@ -1385,7 +1511,8 @@ i40e_cleanup_reset_vf(vf); i40e_flush(hw); - clear_bit(__I40E_VF_DISABLE, pf->state); + usleep_range(20000, 40000); + clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states); return true; } @@ -1406,8 +1533,8 @@ { struct i40e_hw *hw = &pf->hw; struct i40e_vf *vf; - int i, v; u32 reg; + int i; /* If we don't have any VFs, then there is nothing to reset */ if (!pf->num_alloc_vfs) @@ -1418,8 +1545,11 @@ return false; /* Begin reset on all VFs at once */ - for (v = 0; v < pf->num_alloc_vfs; v++) - i40e_trigger_vf_reset(&pf->vf[v], flr); + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) { + /* If VF is being reset no need to trigger reset again */ + if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + i40e_trigger_vf_reset(vf, flr); + } /* HW requires some time to make sure it can flush the FIFO for a VF * when it resets it. Poll the VPGEN_VFRSTAT register for each VF in @@ -1427,22 +1557,23 @@ * the VFs using a simple iterator that increments once that VF has * finished resetting. */ - for (i = 0, v = 0; i < 10 && v < pf->num_alloc_vfs; i++) { + for (i = 0, vf = &pf->vf[0]; i < 10 && vf < &pf->vf[pf->num_alloc_vfs]; ++i) { usleep_range(10000, 20000); /* Check each VF in sequence, beginning with the VF to fail * the previous check. */ - while (v < pf->num_alloc_vfs) { - vf = &pf->vf[v]; - reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id)); - if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK)) - break; + while (vf < &pf->vf[pf->num_alloc_vfs]) { + if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) { + reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id)); + if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK)) + break; + } /* If the current VF has finished resetting, move on * to the next VF in sequence. */ - v++; + ++vf; } } @@ -1452,31 +1583,39 @@ /* Display a warning if at least one VF didn't manage to reset in * time, but continue on with the operation. */ - if (v < pf->num_alloc_vfs) + if (vf < &pf->vf[pf->num_alloc_vfs]) dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n", - pf->vf[v].vf_id); + vf->vf_id); usleep_range(10000, 20000); /* Begin disabling all the rings associated with VFs, but do not wait * between each VF. */ - for (v = 0; v < pf->num_alloc_vfs; v++) { + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) { /* On initial reset, we don't have any queues to disable */ - if (pf->vf[v].lan_vsi_idx == 0) + if (vf->lan_vsi_idx == 0) continue; - i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]); + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + continue; + + i40e_vsi_stop_rings_no_wait(pf->vsi[vf->lan_vsi_idx]); } /* Now that we've notified HW to disable all of the VF rings, wait * until they finish. */ - for (v = 0; v < pf->num_alloc_vfs; v++) { + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) { /* On initial reset, we don't have any queues to disable */ - if (pf->vf[v].lan_vsi_idx == 0) + if (vf->lan_vsi_idx == 0) + continue; + + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) continue; - i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]); + i40e_vsi_wait_queues_disabled(pf->vsi[vf->lan_vsi_idx]); } /* Hw may need up to 50ms to finish disabling the RX queues. We @@ -1485,10 +1624,16 @@ mdelay(50); /* Finish the reset on each VF */ - for (v = 0; v < pf->num_alloc_vfs; v++) - i40e_cleanup_reset_vf(&pf->vf[v]); + for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) { + /* If VF is reset in another thread just continue */ + if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) + continue; + + i40e_cleanup_reset_vf(vf); + } i40e_flush(hw); + usleep_range(20000, 40000); clear_bit(__I40E_VF_DISABLE, pf->state); return true; @@ -1508,11 +1653,22 @@ if (!pf->vf) return; + + set_bit(__I40E_VFS_RELEASING, pf->state); while (test_and_set_bit(__I40E_VF_DISABLE, pf->state)) usleep_range(1000, 2000); i40e_notify_client_of_vf_enable(pf, 0); + /* Disable IOV before freeing resources. This lets any VF drivers + * running in the host get themselves cleaned up before we yank + * the carpet out from underneath their feet. + */ + if (!pci_vfs_assigned(pf->pdev)) + pci_disable_sriov(pf->pdev); + else + dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n"); + /* Amortize wait time by stopping all VFs at the same time */ for (i = 0; i < pf->num_alloc_vfs; i++) { if (test_bit(I40E_VF_STATE_INIT, &pf->vf[i].vf_states)) @@ -1528,15 +1684,6 @@ i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[i].lan_vsi_idx]); } - /* Disable IOV before freeing resources. This lets any VF drivers - * running in the host get themselves cleaned up before we yank - * the carpet out from underneath their feet. - */ - if (!pci_vfs_assigned(pf->pdev)) - pci_disable_sriov(pf->pdev); - else - dev_warn(&pf->pdev->dev, "VFs are assigned - not disabling SR-IOV\n"); - /* free up VF resources */ tmp = pf->num_alloc_vfs; pf->num_alloc_vfs = 0; @@ -1565,6 +1712,7 @@ } } clear_bit(__I40E_VF_DISABLE, pf->state); + clear_bit(__I40E_VFS_RELEASING, pf->state); } #ifdef CONFIG_PCI_IOV @@ -1700,7 +1848,7 @@ if (num_vfs) { if (!(pf->flags & I40E_FLAG_VEB_MODE_ENABLED)) { pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; - i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); + i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); } ret = i40e_pci_sriov_enable(pdev, num_vfs); goto sriov_configure_out; @@ -1709,7 +1857,7 @@ if (!pci_vfs_assigned(pf->pdev)) { i40e_free_vfs(pf); pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED; - i40e_do_reset_safe(pf, I40E_PF_RESET_FLAG); + i40e_do_reset_safe(pf, I40E_PF_RESET_AND_REBUILD_FLAG); } else { dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n"); ret = -EINVAL; @@ -1795,6 +1943,32 @@ } /** + * i40e_sync_vf_state + * @vf: pointer to the VF info + * @state: VF state + * + * Called from a VF message to synchronize the service with a potential + * VF reset state + **/ +static bool i40e_sync_vf_state(struct i40e_vf *vf, enum i40e_vf_states state) +{ + int i; + + /* When handling some messages, it needs VF state to be set. + * It is possible that this flag is cleared during VF reset, + * so there is a need to wait until the end of the reset to + * handle the request message correctly. + */ + for (i = 0; i < I40E_VF_STATE_WAIT_COUNT; i++) { + if (test_bit(state, &vf->vf_states)) + return true; + usleep_range(10000, 20000); + } + + return test_bit(state, &vf->vf_states); +} + +/** * i40e_vc_get_version_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer @@ -1838,6 +2012,25 @@ } /** + * i40e_vc_get_max_frame_size + * @vf: pointer to the VF + * + * Max frame size is determined based on the current port's max frame size and + * whether a port VLAN is configured on this VF. The VF is not aware whether + * it's in a port VLAN so the PF needs to account for this in max frame size + * checks and sending the max frame size to the VF. + **/ +static u16 i40e_vc_get_max_frame_size(struct i40e_vf *vf) +{ + u16 max_frame_size = vf->pf->hw.phy.link_info.max_frame_size; + + if (vf->port_vlan_id) + max_frame_size -= VLAN_HLEN; + + return max_frame_size; +} + +/** * i40e_vc_get_vf_resources_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer @@ -1854,7 +2047,7 @@ size_t len = 0; int ret; - if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_INIT)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -1937,6 +2130,7 @@ vfres->max_vectors = pf->hw.func_caps.num_msix_vectors_vf; vfres->rss_key_size = I40E_HKEY_ARRAY_SIZE; vfres->rss_lut_size = I40E_VF_HLUT_ARRAY_SIZE; + vfres->max_mtu = i40e_vc_get_max_frame_size(vf); if (vf->lan_vsi_idx) { vfres->vsi_res[0].vsi_id = vf->lan_vsi_id; @@ -1960,39 +2154,6 @@ } /** - * i40e_vc_reset_vf_msg - * @vf: pointer to the VF info - * - * called from the VF to reset itself, - * unlike other virtchnl messages, PF driver - * doesn't send the response back to the VF - **/ -static void i40e_vc_reset_vf_msg(struct i40e_vf *vf) -{ - if (test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) - i40e_reset_vf(vf, false); -} - -/** - * i40e_getnum_vf_vsi_vlan_filters - * @vsi: pointer to the vsi - * - * called to get the number of VLANs offloaded on this VF - **/ -static inline int i40e_getnum_vf_vsi_vlan_filters(struct i40e_vsi *vsi) -{ - struct i40e_mac_filter *f; - int num_vlans = 0, bkt; - - hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) { - if (f->vlan >= 0 && f->vlan <= I40E_MAX_VLANID) - num_vlans++; - } - - return num_vlans; -} - -/** * i40e_vc_config_promiscuous_mode_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer @@ -2009,7 +2170,7 @@ bool allmulti = false; bool alluni = false; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err_out; } @@ -2090,13 +2251,14 @@ struct virtchnl_vsi_queue_config_info *qci = (struct virtchnl_vsi_queue_config_info *)msg; struct virtchnl_queue_pair_info *qpi; - struct i40e_pf *pf = vf->pf; u16 vsi_id, vsi_queue_id = 0; - u16 num_qps_all = 0; + struct i40e_pf *pf = vf->pf; i40e_status aq_ret = 0; int i, j = 0, idx = 0; + struct i40e_vsi *vsi; + u16 num_qps_all = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2112,7 +2274,7 @@ } if (vf->adq_enabled) { - for (i = 0; i < I40E_MAX_VF_VSI; i++) + for (i = 0; i < vf->num_tc; i++) num_qps_all += vf->ch[i].num_qps; if (num_qps_all != qci->num_queue_pairs) { aq_ret = I40E_ERR_PARAM; @@ -2183,9 +2345,15 @@ pf->vsi[vf->lan_vsi_idx]->num_queue_pairs = qci->num_queue_pairs; } else { - for (i = 0; i < vf->num_tc; i++) - pf->vsi[vf->ch[i].vsi_idx]->num_queue_pairs = - vf->ch[i].num_qps; + for (i = 0; i < vf->num_tc; i++) { + vsi = pf->vsi[vf->ch[i].vsi_idx]; + vsi->num_queue_pairs = vf->ch[i].num_qps; + + if (i40e_update_adq_vsi_queues(vsi, i)) { + aq_ret = I40E_ERR_CONFIG; + goto error_param; + } + } } error_param: @@ -2238,7 +2406,7 @@ i40e_status aq_ret = 0; int i; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2323,6 +2491,22 @@ } /** + * i40e_vc_validate_vqs_bitmaps - validate Rx/Tx queue bitmaps from VIRTHCHNL + * @vqs: virtchnl_queue_select structure containing bitmaps to validate + * + * Returns true if validation was successful, else false. + */ +static bool i40e_vc_validate_vqs_bitmaps(struct virtchnl_queue_select *vqs) +{ + if ((!vqs->rx_queues && !vqs->tx_queues) || + vqs->rx_queues >= BIT(I40E_MAX_VF_QUEUES) || + vqs->tx_queues >= BIT(I40E_MAX_VF_QUEUES)) + return false; + + return true; +} + +/** * i40e_vc_enable_queues_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer @@ -2347,7 +2531,7 @@ goto error_param; } - if ((0 == vqs->rx_queues) && (0 == vqs->tx_queues)) { + if (!i40e_vc_validate_vqs_bitmaps(vqs)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2373,8 +2557,6 @@ } } - vf->queues_enabled = true; - error_param: /* send the response to the VF */ return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ENABLE_QUEUES, @@ -2396,10 +2578,7 @@ struct i40e_pf *pf = vf->pf; i40e_status aq_ret = 0; - /* Immediately mark queues as disabled */ - vf->queues_enabled = false; - - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2409,9 +2588,7 @@ goto error_param; } - if ((vqs->rx_queues == 0 && vqs->tx_queues == 0) || - vqs->rx_queues > I40E_MAX_VF_QUEUES || - vqs->tx_queues > I40E_MAX_VF_QUEUES) { + if (!i40e_vc_validate_vqs_bitmaps(vqs)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2434,6 +2611,59 @@ } /** + * i40e_check_enough_queue - find big enough queue number + * @vf: pointer to the VF info + * @needed: the number of items needed + * + * Returns the base item index of the queue, or negative for error + **/ +static int i40e_check_enough_queue(struct i40e_vf *vf, u16 needed) +{ + unsigned int i, cur_queues, more, pool_size; + struct i40e_lump_tracking *pile; + struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi; + + vsi = pf->vsi[vf->lan_vsi_idx]; + cur_queues = vsi->alloc_queue_pairs; + + /* if current allocated queues are enough for need */ + if (cur_queues >= needed) + return vsi->base_queue; + + pile = pf->qp_pile; + if (cur_queues > 0) { + /* if the allocated queues are not zero + * just check if there are enough queues for more + * behind the allocated queues. + */ + more = needed - cur_queues; + for (i = vsi->base_queue + cur_queues; + i < pile->num_entries; i++) { + if (pile->list[i] & I40E_PILE_VALID_BIT) + break; + + if (more-- == 1) + /* there is enough */ + return vsi->base_queue; + } + } + + pool_size = 0; + for (i = 0; i < pile->num_entries; i++) { + if (pile->list[i] & I40E_PILE_VALID_BIT) { + pool_size = 0; + continue; + } + if (needed <= ++pool_size) + /* there is enough */ + return i; + } + + return -ENOMEM; +} + +/** * i40e_vc_request_queues_msg * @vf: pointer to the VF info * @msg: pointer to the msg buffer @@ -2451,7 +2681,7 @@ u8 cur_pairs = vf->num_queue_pairs; struct i40e_pf *pf = vf->pf; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) return -EINVAL; if (req_pairs > I40E_MAX_VF_QUEUES) { @@ -2467,11 +2697,16 @@ req_pairs - cur_pairs, pf->queues_left); vfres->num_queue_pairs = pf->queues_left + cur_pairs; + } else if (i40e_check_enough_queue(vf, req_pairs) < 0) { + dev_warn(&pf->pdev->dev, + "VF %d requested %d more queues, but there is not enough for it.\n", + vf->vf_id, + req_pairs - cur_pairs); + vfres->num_queue_pairs = cur_pairs; } else { /* successful request */ vf->num_req_queues = req_pairs; - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true); return 0; } @@ -2497,7 +2732,7 @@ memset(&stats, 0, sizeof(struct i40e_eth_stats)); - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2521,6 +2756,24 @@ (u8 *)&stats, sizeof(stats)); } +/** + * i40e_can_vf_change_mac + * @vf: pointer to the VF info + * + * Return true if the VF is allowed to change its MAC filters, false otherwise + */ +static bool i40e_can_vf_change_mac(struct i40e_vf *vf) +{ + /* If the VF MAC address has been set administratively (via the + * ndo_set_vf_mac command), then deny permission to the VF to + * add/delete unicast MAC addresses, unless the VF is trusted + */ + if (vf->pf_set_mac && !vf->trusted) + return false; + + return true; +} + /* If the VF is not trusted restrict the number of MAC/VLAN it can program * MAC filters: 16 for multicast, 1 for MAC, 1 for broadcast */ @@ -2548,20 +2801,12 @@ struct virtchnl_ether_addr_list *al) { struct i40e_pf *pf = vf->pf; + struct i40e_vsi *vsi = pf->vsi[vf->lan_vsi_idx]; + int mac2add_cnt = 0; int i; - /* If this VF is not privileged, then we can't add more than a limited - * number of addresses. Check to make sure that the additions do not - * push us over the limit. - */ - if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) && - (vf->num_mac + al->num_elements) > I40E_VC_MAX_MAC_ADDR_PER_VF) { - dev_err(&pf->pdev->dev, - "Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n"); - return -EPERM; - } - for (i = 0; i < al->num_elements; i++) { + struct i40e_mac_filter *f; u8 *addr = al->list[i].addr; if (is_broadcast_ether_addr(addr) || @@ -2578,15 +2823,31 @@ * The VF may request to set the MAC address filter already * assigned to it so do not return an error in that case. */ - if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) && - !is_multicast_ether_addr(addr) && vf->pf_set_mac && + if (!i40e_can_vf_change_mac(vf) && + !is_multicast_ether_addr(addr) && !ether_addr_equal(addr, vf->default_lan_addr.addr)) { dev_err(&pf->pdev->dev, "VF attempting to override administratively set MAC address, bring down and up the VF interface to resume normal operation\n"); return -EPERM; } + + /*count filters that really will be added*/ + f = i40e_find_mac(vsi, addr); + if (!f) + ++mac2add_cnt; } + /* If this VF is not privileged, then we can't add more than a limited + * number of addresses. Check to make sure that the additions do not + * push us over the limit. + */ + if (!test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps) && + (i40e_count_filters(vsi) + mac2add_cnt) > + I40E_VC_MAX_MAC_ADDR_PER_VF) { + dev_err(&pf->pdev->dev, + "Cannot add more MAC addresses, VF is not trusted, switch the VF to trusted to add more functionality\n"); + return -EPERM; + } return 0; } @@ -2606,7 +2867,7 @@ i40e_status ret = 0; int i; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { ret = I40E_ERR_PARAM; goto error_param; @@ -2640,9 +2901,11 @@ ret = I40E_ERR_PARAM; spin_unlock_bh(&vsi->mac_filter_hash_lock); goto error_param; - } else { - vf->num_mac++; } + if (is_valid_ether_addr(al->list[i].addr) && + is_zero_ether_addr(vf->default_lan_addr.addr)) + ether_addr_copy(vf->default_lan_addr.addr, + al->list[i].addr); } } spin_unlock_bh(&vsi->mac_filter_hash_lock); @@ -2670,12 +2933,13 @@ { struct virtchnl_ether_addr_list *al = (struct virtchnl_ether_addr_list *)msg; + bool was_unimac_deleted = false; struct i40e_pf *pf = vf->pf; struct i40e_vsi *vsi = NULL; i40e_status ret = 0; int i; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || !i40e_vc_isvalid_vsi_id(vf, al->vsi_id)) { ret = I40E_ERR_PARAM; goto error_param; @@ -2689,29 +2953,29 @@ ret = I40E_ERR_INVALID_MAC_ADDR; goto error_param; } - - if (vf->pf_set_mac && - ether_addr_equal(al->list[i].addr, - vf->default_lan_addr.addr)) { - dev_err(&pf->pdev->dev, - "MAC addr %pM has been set by PF, cannot delete it for VF %d, reset VF to change MAC addr\n", - vf->default_lan_addr.addr, vf->vf_id); - ret = I40E_ERR_PARAM; - goto error_param; - } } vsi = pf->vsi[vf->lan_vsi_idx]; spin_lock_bh(&vsi->mac_filter_hash_lock); /* delete addresses from the list */ - for (i = 0; i < al->num_elements; i++) + for (i = 0; i < al->num_elements; i++) { + const u8 *addr = al->list[i].addr; + + /* Allow to delete VF primary MAC only if it was not set + * administratively by PF or if VF is trusted. + */ + if (ether_addr_equal(addr, vf->default_lan_addr.addr) && + i40e_can_vf_change_mac(vf)) + was_unimac_deleted = true; + else + continue; + if (i40e_del_mac_filter(vsi, al->list[i].addr)) { ret = I40E_ERR_INVALID_MAC_ADDR; spin_unlock_bh(&vsi->mac_filter_hash_lock); goto error_param; - } else { - vf->num_mac--; } + } spin_unlock_bh(&vsi->mac_filter_hash_lock); @@ -2721,10 +2985,25 @@ dev_err(&pf->pdev->dev, "Unable to program VF %d MAC filters, error %d\n", vf->vf_id, ret); + if (vf->trusted && was_unimac_deleted) { + struct i40e_mac_filter *f; + struct hlist_node *h; + u8 *macaddr = NULL; + int bkt; + + /* set last unicast mac address as default */ + spin_lock_bh(&vsi->mac_filter_hash_lock); + hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) { + if (is_valid_ether_addr(f->macaddr)) + macaddr = f->macaddr; + } + if (macaddr) + ether_addr_copy(vf->default_lan_addr.addr, macaddr); + spin_unlock_bh(&vsi->mac_filter_hash_lock); + } error_param: /* send the response to the VF */ - return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_DEL_ETH_ADDR, - ret); + return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_DEL_ETH_ADDR, ret); } /** @@ -2814,7 +3093,7 @@ i40e_status aq_ret = 0; int i; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || !i40e_vc_isvalid_vsi_id(vf, vfl->vsi_id)) { aq_ret = I40E_ERR_PARAM; goto error_param; @@ -2934,9 +3213,9 @@ struct i40e_vsi *vsi = NULL; i40e_status aq_ret = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || !i40e_vc_isvalid_vsi_id(vf, vrk->vsi_id) || - (vrk->key_len != I40E_HKEY_ARRAY_SIZE)) { + vrk->key_len != I40E_HKEY_ARRAY_SIZE) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -2965,9 +3244,9 @@ i40e_status aq_ret = 0; u16 i; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE) || !i40e_vc_isvalid_vsi_id(vf, vrl->vsi_id) || - (vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE)) { + vrl->lut_entries != I40E_VF_HLUT_ARRAY_SIZE) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3000,7 +3279,7 @@ i40e_status aq_ret = 0; int len = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3036,7 +3315,7 @@ struct i40e_hw *hw = &pf->hw; i40e_status aq_ret = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3061,7 +3340,7 @@ i40e_status aq_ret = 0; struct i40e_vsi *vsi; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3087,7 +3366,7 @@ i40e_status aq_ret = 0; struct i40e_vsi *vsi; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3120,16 +3399,16 @@ bool found = false; int bkt; - if (!tc_filter->action) { + if (tc_filter->action != VIRTCHNL_ACTION_TC_REDIRECT) { dev_info(&pf->pdev->dev, - "VF %d: Currently ADq doesn't support Drop Action\n", - vf->vf_id); + "VF %d: ADQ doesn't support this action (%d)\n", + vf->vf_id, tc_filter->action); goto err; } /* action_meta is TC number here to which the filter is applied */ if (!tc_filter->action_meta || - tc_filter->action_meta > I40E_MAX_VF_VSI) { + tc_filter->action_meta > vf->num_tc) { dev_info(&pf->pdev->dev, "VF %d: Invalid TC number %u\n", vf->vf_id, tc_filter->action_meta); goto err; @@ -3314,7 +3593,7 @@ i40e_status aq_ret = 0; int i, ret; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3445,7 +3724,7 @@ i40e_status aq_ret = 0; int i, ret; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err_out; } @@ -3554,7 +3833,7 @@ i40e_status aq_ret = 0; u64 speed = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3661,15 +3940,9 @@ /* set this flag only after making sure all inputs are sane */ vf->adq_enabled = true; - /* num_req_queues is set when user changes number of queues via ethtool - * and this causes issue for default VSI(which depends on this variable) - * when ADq is enabled, hence reset it. - */ - vf->num_req_queues = 0; /* reset the VF in order to allocate resources */ - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true); return I40E_SUCCESS; @@ -3689,7 +3962,7 @@ struct i40e_pf *pf = vf->pf; i40e_status aq_ret = 0; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { + if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { aq_ret = I40E_ERR_PARAM; goto err; } @@ -3709,8 +3982,7 @@ } /* reset the VF in order to allocate resources */ - i40e_vc_notify_vf_reset(vf); - i40e_reset_vf(vf, false); + i40e_vc_reset_vf(vf, true); return I40E_SUCCESS; @@ -3772,7 +4044,7 @@ i40e_vc_notify_vf_link_state(vf); break; case VIRTCHNL_OP_RESET_VF: - i40e_vc_reset_vf_msg(vf); + i40e_vc_reset_vf(vf, false); ret = 0; break; case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: @@ -3962,20 +4234,16 @@ goto error_param; vf = &pf->vf[vf_id]; - vsi = pf->vsi[vf->lan_vsi_idx]; /* When the VF is resetting wait until it is done. * It can take up to 200 milliseconds, * but wait for up to 300 milliseconds to be safe. - * If the VF is indeed in reset, the vsi pointer has - * to show on the newly loaded vsi under pf->vsi[id]. + * Acquire the VSI pointer only after the VF has been + * properly initialized. */ for (i = 0; i < 15; i++) { - if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { - if (i > 0) - vsi = pf->vsi[vf->lan_vsi_idx]; + if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) break; - } msleep(20); } if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { @@ -3984,6 +4252,7 @@ ret = -EAGAIN; goto error_param; } + vsi = pf->vsi[vf->lan_vsi_idx]; if (is_multicast_ether_addr(mac)) { dev_err(&pf->pdev->dev, @@ -4029,7 +4298,7 @@ /* Force the VF interface down so it has to bring up with new MAC * address */ - i40e_vc_disable_vf(vf); + i40e_vc_reset_vf(vf, true); dev_info(&pf->pdev->dev, "Bring down and up the VF interface to make this change effective.\n"); error_param: @@ -4038,34 +4307,6 @@ } /** - * i40e_vsi_has_vlans - True if VSI has configured VLANs - * @vsi: pointer to the vsi - * - * Check if a VSI has configured any VLANs. False if we have a port VLAN or if - * we have no configured VLANs. Do not call while holding the - * mac_filter_hash_lock. - */ -static bool i40e_vsi_has_vlans(struct i40e_vsi *vsi) -{ - bool have_vlans; - - /* If we have a port VLAN, then the VSI cannot have any VLANs - * configured, as all MAC/VLAN filters will be assigned to the PVID. - */ - if (vsi->info.pvid) - return false; - - /* Since we don't have a PVID, we know that if the device is in VLAN - * mode it must be because of a VLAN filter configured on this VSI. - */ - spin_lock_bh(&vsi->mac_filter_hash_lock); - have_vlans = i40e_is_vsi_in_vlan(vsi); - spin_unlock_bh(&vsi->mac_filter_hash_lock); - - return have_vlans; -} - -/** * i40e_ndo_set_vf_port_vlan * @netdev: network interface device structure * @vf_id: VF identifier @@ -4121,19 +4362,6 @@ /* duplicate request, so just return success */ goto error_pvid; - if (i40e_vsi_has_vlans(vsi)) { - dev_err(&pf->pdev->dev, - "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", - vf_id); - /* Administrator Error - knock the VF offline until he does - * the right thing by reconfiguring his network correctly - * and then reloading the VF driver. - */ - i40e_vc_disable_vf(vf); - /* During reset the VF got a new VSI, so refresh the pointer. */ - vsi = pf->vsi[vf->lan_vsi_idx]; - } - /* Locked once because multiple functions below iterate list */ spin_lock_bh(&vsi->mac_filter_hash_lock); @@ -4219,6 +4447,10 @@ */ vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); + i40e_vc_reset_vf(vf, true); + /* During reset the VF got a new VSI, so refresh a pointer. */ + vsi = pf->vsi[vf->lan_vsi_idx]; + ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); if (ret) { dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); @@ -4514,7 +4746,7 @@ goto out; vf->trusted = setting; - i40e_vc_disable_vf(vf); + i40e_vc_reset_vf(vf, true); dev_info(&pf->pdev->dev, "VF %u is now %strusted\n", vf_id, setting ? "" : "un"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -19,6 +19,8 @@ #define I40E_MAX_VF_PROMISC_FLAGS 3 +#define I40E_VF_STATE_WAIT_COUNT 20 + /* Various queue ctrls */ enum i40e_queue_ctrl { I40E_QUEUE_CTRL_UNKNOWN = 0, @@ -39,6 +41,7 @@ I40E_VF_STATE_MC_PROMISC, I40E_VF_STATE_UC_PROMISC, I40E_VF_STATE_PRE_ENABLE, + I40E_VF_STATE_RESETTING }; /* VF capabilities */ @@ -99,9 +102,7 @@ unsigned int tx_rate; /* Tx bandwidth limit in Mbps */ bool link_forced; bool link_up; /* only valid if VF link is forced */ - bool queues_enabled; /* true if the VF queues are enabled */ bool spoofchk; - u16 num_mac; u16 num_vlan; /* ADq related variables */ @@ -139,5 +140,8 @@ void i40e_vc_notify_link_state(struct i40e_pf *pf); void i40e_vc_notify_reset(struct i40e_pf *pf); +#ifdef CONFIG_PCI_IOV +void i40e_restore_all_vfs_msi_state(struct pci_dev *pdev); +#endif /* CONFIG_PCI_IOV */ #endif /* _I40E_VIRTCHNL_PF_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/i40e/i40e_xsk.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/i40e/i40e_xsk.c @@ -9,6 +9,11 @@ #include "i40e_txrx_common.h" #include "i40e_xsk.h" +static struct i40e_rx_buffer *i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx) +{ + return &rx_ring->rx_bi[idx]; +} + /** * i40e_xsk_umem_dma_map - DMA maps all UMEM memory for the netdev * @vsi: Current VSI @@ -207,21 +212,28 @@ xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); + if (likely(act == XDP_REDIRECT)) { + err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); + if (err) + goto out_failure; + rcu_read_unlock(); + return I40E_XDP_REDIR; + } + switch (act) { case XDP_PASS: break; case XDP_TX: xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index]; result = i40e_xmit_xdp_tx_ring(xdp, xdp_ring); - break; - case XDP_REDIRECT: - err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); - result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED; + if (result == I40E_XDP_CONSUMED) + goto out_failure; break; default: bpf_warn_invalid_xdp_action(act); /* fall through */ case XDP_ABORTED: +out_failure: trace_xdp_exception(rx_ring->netdev, xdp_prog, act); /* fallthrough -- handle aborts by dropping packet */ case XDP_DROP: @@ -321,7 +333,7 @@ bool ok = true; rx_desc = I40E_RX_DESC(rx_ring, ntu); - bi = &rx_ring->rx_bi[ntu]; + bi = i40e_rx_bi(rx_ring, ntu); do { if (!alloc(rx_ring, bi)) { ok = false; @@ -340,7 +352,7 @@ if (unlikely(ntu == rx_ring->count)) { rx_desc = I40E_RX_DESC(rx_ring, 0); - bi = rx_ring->rx_bi; + bi = i40e_rx_bi(rx_ring, 0); ntu = 0; } @@ -402,7 +414,7 @@ { struct i40e_rx_buffer *bi; - bi = &rx_ring->rx_bi[rx_ring->next_to_clean]; + bi = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); /* we are reusing so sync this buffer for CPU use */ dma_sync_single_range_for_cpu(rx_ring->dev, @@ -424,7 +436,8 @@ static void i40e_reuse_rx_buffer_zc(struct i40e_ring *rx_ring, struct i40e_rx_buffer *old_bi) { - struct i40e_rx_buffer *new_bi = &rx_ring->rx_bi[rx_ring->next_to_alloc]; + struct i40e_rx_buffer *new_bi = i40e_rx_bi(rx_ring, + rx_ring->next_to_alloc); u16 nta = rx_ring->next_to_alloc; /* update, and store next to alloc */ @@ -456,7 +469,7 @@ mask = rx_ring->xsk_umem->chunk_mask; nta = rx_ring->next_to_alloc; - bi = &rx_ring->rx_bi[nta]; + bi = i40e_rx_bi(rx_ring, nta); nta++; rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; @@ -492,13 +505,11 @@ struct sk_buff *skb; /* allocate a skb to store the frags */ - skb = __napi_alloc_skb(&rx_ring->q_vector->napi, - xdp->data_end - xdp->data_hard_start, + skb = __napi_alloc_skb(&rx_ring->q_vector->napi, datasize, GFP_ATOMIC | __GFP_NOWARN); if (unlikely(!skb)) return NULL; - skb_reserve(skb, xdp->data - xdp->data_hard_start); memcpy(__skb_put(skb, datasize), xdp->data, datasize); if (metasize) skb_metadata_set(skb, metasize); @@ -787,8 +798,12 @@ { struct i40e_netdev_priv *np = netdev_priv(dev); struct i40e_vsi *vsi = np->vsi; + struct i40e_pf *pf = vsi->back; struct i40e_ring *ring; + if (test_bit(__I40E_CONFIG_BUSY, pf->state)) + return -EAGAIN; + if (test_bit(__I40E_VSI_DOWN, vsi->state)) return -ENETDOWN; @@ -820,7 +835,7 @@ u16 i; for (i = 0; i < rx_ring->count; i++) { - struct i40e_rx_buffer *rx_bi = &rx_ring->rx_bi[i]; + struct i40e_rx_buffer *rx_bi = i40e_rx_bi(rx_ring, i); if (!rx_bi->addr) continue; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf.h @@ -86,6 +86,11 @@ #define IAVF_HKEY_ARRAY_SIZE ((IAVF_VFQF_HKEY_MAX_INDEX + 1) * 4) #define IAVF_HLUT_ARRAY_SIZE ((IAVF_VFQF_HLUT_MAX_INDEX + 1) * 4) #define IAVF_MBPS_DIVISOR 125000 /* divisor to convert to Mbps */ +#define IAVF_MBPS_QUANTA 50 + +#define IAVF_VIRTCHNL_VF_RESOURCE_SIZE (sizeof(struct virtchnl_vf_resource) + \ + (IAVF_MAX_VF_VSI * \ + sizeof(struct virtchnl_vsi_resource))) /* MAX_MSIX_Q_VECTORS of these are allocated, * but we only use one per queue-specific vector. @@ -130,6 +135,7 @@ struct iavf_mac_filter { struct list_head list; u8 macaddr[ETH_ALEN]; + bool is_new_mac; /* filter is new, wait for PF decision */ bool remove; /* filter needs to be removed */ bool add; /* filter needs to be added */ }; @@ -306,6 +312,14 @@ bool netdev_registered; bool link_up; enum virtchnl_link_speed link_speed; + /* This is only populated if the VIRTCHNL_VF_CAP_ADV_LINK_SPEED is set + * in vf_res->vf_cap_flags. Use ADV_LINK_SUPPORT macro to determine if + * this field is valid. This field should be used going forward and the + * enum virtchnl_link_speed above should be considered the legacy way of + * storing/communicating link speeds. + */ + u32 link_speed_mbps; + enum virtchnl_ops current_op; #define CLIENT_ALLOWED(_a) ((_a)->vf_res ? \ (_a)->vf_res->vf_cap_flags & \ @@ -322,6 +336,8 @@ VIRTCHNL_VF_OFFLOAD_RSS_PF))) #define VLAN_ALLOWED(_a) ((_a)->vf_res->vf_cap_flags & \ VIRTCHNL_VF_OFFLOAD_VLAN) +#define ADV_LINK_SUPPORT(_a) ((_a)->vf_res->vf_cap_flags & \ + VIRTCHNL_VF_CAP_ADV_LINK_SPEED) struct virtchnl_vf_resource *vf_res; /* incl. all VSIs */ struct virtchnl_vsi_resource *vsi_res; /* our LAN VSI */ struct virtchnl_version_info pf_version; @@ -369,7 +385,7 @@ void iavf_update_stats(struct iavf_adapter *adapter); void iavf_reset_interrupt_capability(struct iavf_adapter *adapter); int iavf_init_interrupt_scheme(struct iavf_adapter *adapter); -void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask); +void iavf_irq_enable_queues(struct iavf_adapter *adapter); void iavf_free_all_tx_resources(struct iavf_adapter *adapter); void iavf_free_all_rx_resources(struct iavf_adapter *adapter); @@ -415,4 +431,6 @@ void iavf_disable_channels(struct iavf_adapter *adapter); void iavf_add_cloud_filter(struct iavf_adapter *adapter); void iavf_del_cloud_filter(struct iavf_adapter *adapter); +struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, + const u8 *macaddr); #endif /* _IAVF_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_adminq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_adminq.c @@ -324,6 +324,7 @@ static enum iavf_status iavf_init_asq(struct iavf_hw *hw) { enum iavf_status ret_code = 0; + int i; if (hw->aq.asq.count > 0) { /* queue already initialized */ @@ -354,12 +355,17 @@ /* initialize base registers */ ret_code = iavf_config_asq_regs(hw); if (ret_code) - goto init_adminq_free_rings; + goto init_free_asq_bufs; /* success! */ hw->aq.asq.count = hw->aq.num_asq_entries; goto init_adminq_exit; +init_free_asq_bufs: + for (i = 0; i < hw->aq.num_asq_entries; i++) + iavf_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]); + iavf_free_virt_mem(hw, &hw->aq.asq.dma_head); + init_adminq_free_rings: iavf_free_adminq_asq(hw); @@ -383,6 +389,7 @@ static enum iavf_status iavf_init_arq(struct iavf_hw *hw) { enum iavf_status ret_code = 0; + int i; if (hw->aq.arq.count > 0) { /* queue already initialized */ @@ -413,12 +420,16 @@ /* initialize base registers */ ret_code = iavf_config_arq_regs(hw); if (ret_code) - goto init_adminq_free_rings; + goto init_free_arq_bufs; /* success! */ hw->aq.arq.count = hw->aq.num_arq_entries; goto init_adminq_exit; +init_free_arq_bufs: + for (i = 0; i < hw->aq.num_arq_entries; i++) + iavf_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]); + iavf_free_virt_mem(hw, &hw->aq.arq.dma_head); init_adminq_free_rings: iavf_free_adminq_arq(hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_common.c @@ -662,7 +662,7 @@ /* Non Tunneled IPv6 */ IAVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), IAVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), - IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3), + IAVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), IAVF_PTT_UNUSED_ENTRY(91), IAVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), IAVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -278,7 +278,18 @@ ethtool_link_ksettings_zero_link_mode(cmd, supported); cmd->base.autoneg = AUTONEG_DISABLE; cmd->base.port = PORT_NONE; - /* Set speed and duplex */ + cmd->base.duplex = DUPLEX_FULL; + + if (ADV_LINK_SUPPORT(adapter)) { + if (adapter->link_speed_mbps && + adapter->link_speed_mbps < U32_MAX) + cmd->base.speed = adapter->link_speed_mbps; + else + cmd->base.speed = SPEED_UNKNOWN; + + return 0; + } + switch (adapter->link_speed) { case IAVF_LINK_SPEED_40GB: cmd->base.speed = SPEED_40000; @@ -306,7 +317,6 @@ default: break; } - cmd->base.duplex = DUPLEX_FULL; return 0; } @@ -602,23 +612,44 @@ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - new_tx_count = clamp_t(u32, ring->tx_pending, - IAVF_MIN_TXD, - IAVF_MAX_TXD); - new_tx_count = ALIGN(new_tx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); - - new_rx_count = clamp_t(u32, ring->rx_pending, - IAVF_MIN_RXD, - IAVF_MAX_RXD); - new_rx_count = ALIGN(new_rx_count, IAVF_REQ_DESCRIPTOR_MULTIPLE); + if (ring->tx_pending > IAVF_MAX_TXD || + ring->tx_pending < IAVF_MIN_TXD || + ring->rx_pending > IAVF_MAX_RXD || + ring->rx_pending < IAVF_MIN_RXD) { + netdev_err(netdev, "Descriptors requested (Tx: %d / Rx: %d) out of range [%d-%d] (increment %d)\n", + ring->tx_pending, ring->rx_pending, IAVF_MIN_TXD, + IAVF_MAX_RXD, IAVF_REQ_DESCRIPTOR_MULTIPLE); + return -EINVAL; + } + + new_tx_count = ALIGN(ring->tx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE); + if (new_tx_count != ring->tx_pending) + netdev_info(netdev, "Requested Tx descriptor count rounded up to %d\n", + new_tx_count); + + new_rx_count = ALIGN(ring->rx_pending, IAVF_REQ_DESCRIPTOR_MULTIPLE); + if (new_rx_count != ring->rx_pending) + netdev_info(netdev, "Requested Rx descriptor count rounded up to %d\n", + new_rx_count); /* if nothing to do return success */ if ((new_tx_count == adapter->tx_desc_count) && - (new_rx_count == adapter->rx_desc_count)) + (new_rx_count == adapter->rx_desc_count)) { + netdev_dbg(netdev, "Nothing to change, descriptor count is same as requested\n"); return 0; + } + + if (new_tx_count != adapter->tx_desc_count) { + netdev_dbg(netdev, "Changing Tx descriptor count from %d to %d\n", + adapter->tx_desc_count, new_tx_count); + adapter->tx_desc_count = new_tx_count; + } - adapter->tx_desc_count = new_tx_count; - adapter->rx_desc_count = new_rx_count; + if (new_rx_count != adapter->rx_desc_count) { + netdev_dbg(netdev, "Changing Rx descriptor count from %d to %d\n", + adapter->rx_desc_count, new_rx_count); + adapter->rx_desc_count = new_rx_count; + } if (netif_running(netdev)) { adapter->flags |= IAVF_FLAG_RESET_NEEDED; @@ -709,12 +740,31 @@ * * Change the ITR settings for a specific queue. **/ -static void iavf_set_itr_per_queue(struct iavf_adapter *adapter, - struct ethtool_coalesce *ec, int queue) +static int iavf_set_itr_per_queue(struct iavf_adapter *adapter, + struct ethtool_coalesce *ec, int queue) { struct iavf_ring *rx_ring = &adapter->rx_rings[queue]; struct iavf_ring *tx_ring = &adapter->tx_rings[queue]; struct iavf_q_vector *q_vector; + u16 itr_setting; + + itr_setting = rx_ring->itr_setting & ~IAVF_ITR_DYNAMIC; + + if (ec->rx_coalesce_usecs != itr_setting && + ec->use_adaptive_rx_coalesce) { + netif_info(adapter, drv, adapter->netdev, + "Rx interrupt throttling cannot be changed if adaptive-rx is enabled\n"); + return -EINVAL; + } + + itr_setting = tx_ring->itr_setting & ~IAVF_ITR_DYNAMIC; + + if (ec->tx_coalesce_usecs != itr_setting && + ec->use_adaptive_tx_coalesce) { + netif_info(adapter, drv, adapter->netdev, + "Tx interrupt throttling cannot be changed if adaptive-tx is enabled\n"); + return -EINVAL; + } rx_ring->itr_setting = ITR_REG_ALIGN(ec->rx_coalesce_usecs); tx_ring->itr_setting = ITR_REG_ALIGN(ec->tx_coalesce_usecs); @@ -737,6 +787,7 @@ * the Tx and Rx ITR values based on the values we have entered * into the q_vector, no need to write the values now. */ + return 0; } /** @@ -778,9 +829,11 @@ */ if (queue < 0) { for (i = 0; i < adapter->num_active_queues; i++) - iavf_set_itr_per_queue(adapter, ec, i); + if (iavf_set_itr_per_queue(adapter, ec, i)) + return -EINVAL; } else if (queue < adapter->num_active_queues) { - iavf_set_itr_per_queue(adapter, ec, queue); + if (iavf_set_itr_per_queue(adapter, ec, queue)) + return -EINVAL; } else { netif_info(adapter, drv, netdev, "Invalid queue value, queue range is 0 - %d\n", adapter->num_active_queues - 1); @@ -952,14 +1005,13 @@ if (hfunc) *hfunc = ETH_RSS_HASH_TOP; - if (!indir) - return 0; - - memcpy(key, adapter->rss_key, adapter->rss_key_size); + if (key) + memcpy(key, adapter->rss_key, adapter->rss_key_size); - /* Each 32 bits pointed by 'indir' is stored with a lut entry */ - for (i = 0; i < adapter->rss_lut_size; i++) - indir[i] = (u32)adapter->rss_lut[i]; + if (indir) + /* Each 32 bits pointed by 'indir' is stored with a lut entry */ + for (i = 0; i < adapter->rss_lut_size; i++) + indir[i] = (u32)adapter->rss_lut[i]; return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -143,6 +143,30 @@ } /** + * iavf_lock_timeout - try to set bit but give up after timeout + * @adapter: board private structure + * @bit: bit to set + * @msecs: timeout in msecs + * + * Returns 0 on success, negative on failure + **/ +static int iavf_lock_timeout(struct iavf_adapter *adapter, + enum iavf_critical_section_t bit, + unsigned int msecs) +{ + unsigned int wait, delay = 10; + + for (wait = 0; wait < msecs; wait += delay) { + if (!test_and_set_bit(bit, &adapter->crit_section)) + return 0; + + msleep(delay); + } + + return -1; +} + +/** * iavf_schedule_reset - Set the flags and schedule a reset event * @adapter: board private structure **/ @@ -220,21 +244,18 @@ } /** - * iavf_irq_enable_queues - Enable interrupt for specified queues + * iavf_irq_enable_queues - Enable interrupt for all queues * @adapter: board private structure - * @mask: bitmap of queues to enable **/ -void iavf_irq_enable_queues(struct iavf_adapter *adapter, u32 mask) +void iavf_irq_enable_queues(struct iavf_adapter *adapter) { struct iavf_hw *hw = &adapter->hw; int i; for (i = 1; i < adapter->num_msix_vectors; i++) { - if (mask & BIT(i - 1)) { - wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1), - IAVF_VFINT_DYN_CTLN1_INTENA_MASK | - IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK); - } + wr32(hw, IAVF_VFINT_DYN_CTLN1(i - 1), + IAVF_VFINT_DYN_CTLN1_INTENA_MASK | + IAVF_VFINT_DYN_CTLN1_ITR_INDX_MASK); } } @@ -248,7 +269,7 @@ struct iavf_hw *hw = &adapter->hw; iavf_misc_irq_enable(adapter); - iavf_irq_enable_queues(adapter, ~0); + iavf_irq_enable_queues(adapter); if (flush) iavf_flush(hw); @@ -743,9 +764,8 @@ * * Returns ptr to the filter object or NULL when no memory available. **/ -static struct -iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, - const u8 *macaddr) +struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, + const u8 *macaddr) { struct iavf_mac_filter *f; @@ -762,6 +782,7 @@ list_add_tail(&f->list, &adapter->mac_filter_list); f->add = true; + f->is_new_mac = true; adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; } else { f->remove = false; @@ -1368,19 +1389,16 @@ static void iavf_free_q_vectors(struct iavf_adapter *adapter) { int q_idx, num_q_vectors; - int napi_vectors; if (!adapter->q_vectors) return; num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; - napi_vectors = adapter->num_active_queues; for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { struct iavf_q_vector *q_vector = &adapter->q_vectors[q_idx]; - if (q_idx < napi_vectors) - netif_napi_del(&q_vector->napi); + netif_napi_del(&q_vector->napi); } kfree(adapter->q_vectors); adapter->q_vectors = NULL; @@ -1500,11 +1518,6 @@ set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); iavf_map_rings_to_vectors(adapter); - - if (RSS_AQ(adapter)) - adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS; - else - err = iavf_init_rss(adapter); err: return err; } @@ -1607,8 +1620,7 @@ iavf_set_promiscuous(adapter, FLAG_VF_MULTICAST_PROMISC); return 0; } - - if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) && + if ((adapter->aq_required & IAVF_FLAG_AQ_RELEASE_PROMISC) || (adapter->aq_required & IAVF_FLAG_AQ_RELEASE_ALLMULTI)) { iavf_set_promiscuous(adapter, 0); return 0; @@ -1757,17 +1769,17 @@ struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct iavf_hw *hw = &adapter->hw; - int err = 0, bufsz; + int err; WARN_ON(adapter->state != __IAVF_INIT_GET_RESOURCES); /* aq msg sent, awaiting reply */ if (!adapter->vf_res) { - bufsz = sizeof(struct virtchnl_vf_resource) + - (IAVF_MAX_VF_VSI * - sizeof(struct virtchnl_vsi_resource)); - adapter->vf_res = kzalloc(bufsz, GFP_KERNEL); - if (!adapter->vf_res) + adapter->vf_res = kzalloc(IAVF_VIRTCHNL_VF_RESOURCE_SIZE, + GFP_KERNEL); + if (!adapter->vf_res) { + err = -ENOMEM; goto err; + } } err = iavf_get_vf_config(adapter); if (err == IAVF_ERR_ADMIN_QUEUE_NO_WORK) { @@ -1787,7 +1799,8 @@ goto err_alloc; } - if (iavf_process_config(adapter)) + err = iavf_process_config(adapter); + if (err) goto err_alloc; adapter->current_op = VIRTCHNL_OP_UNKNOWN; @@ -1845,11 +1858,9 @@ netif_tx_stop_all_queues(netdev); if (CLIENT_ALLOWED(adapter)) { err = iavf_lan_add_device(adapter); - if (err) { - rtnl_unlock(); + if (err) dev_info(&pdev->dev, "Failed to add VF to client API service list: %d\n", err); - } } dev_info(&pdev->dev, "MAC address: %pM\n", adapter->hw.mac.addr); if (netdev->features & NETIF_F_GRO) @@ -1864,8 +1875,10 @@ adapter->rss_key = kzalloc(adapter->rss_key_size, GFP_KERNEL); adapter->rss_lut = kzalloc(adapter->rss_lut_size, GFP_KERNEL); - if (!adapter->rss_key || !adapter->rss_lut) + if (!adapter->rss_key || !adapter->rss_lut) { + err = -ENOMEM; goto err_mem; + } if (RSS_AQ(adapter)) adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS; else @@ -1947,7 +1960,10 @@ iavf_send_api_ver(adapter); } } else { - if (!iavf_process_aq_command(adapter) && + /* An error will be returned if no commands were + * processed; use this opportunity to update stats + */ + if (iavf_process_aq_command(adapter) && adapter->state == __IAVF_RUNNING) iavf_request_stats(adapter); } @@ -1962,7 +1978,6 @@ /* check for hw reset */ reg_val = rd32(hw, IAVF_VF_ARQLEN1) & IAVF_VF_ARQLEN1_ARQENABLE_MASK; if (!reg_val) { - adapter->state = __IAVF_RESETTING; adapter->flags |= IAVF_FLAG_RESET_PENDING; adapter->aq_required = 0; adapter->current_op = VIRTCHNL_OP_UNKNOWN; @@ -2035,9 +2050,9 @@ iavf_free_misc_irq(adapter); iavf_reset_interrupt_capability(adapter); - iavf_free_queues(adapter); iavf_free_q_vectors(adapter); - kfree(adapter->vf_res); + iavf_free_queues(adapter); + memset(adapter->vf_res, 0, IAVF_VIRTCHNL_VF_RESOURCE_SIZE); iavf_shutdown_adminq(&adapter->hw); adapter->netdev->flags &= ~IFF_UP; clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); @@ -2065,9 +2080,9 @@ struct virtchnl_vf_resource *vfres = adapter->vf_res; struct net_device *netdev = adapter->netdev; struct iavf_hw *hw = &adapter->hw; + struct iavf_mac_filter *f, *ftmp; struct iavf_vlan_filter *vlf; struct iavf_cloud_filter *cf; - struct iavf_mac_filter *f; u32 reg_val; int i = 0, err; bool running; @@ -2078,6 +2093,10 @@ if (test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) return; + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) { + schedule_work(&adapter->reset_task); + return; + } while (test_and_set_bit(__IAVF_IN_CLIENT_TASK, &adapter->crit_section)) usleep_range(500, 1000); @@ -2126,6 +2145,7 @@ } pci_set_master(adapter->pdev); + pci_restore_msi_state(adapter->pdev); if (i == IAVF_RESET_WAIT_COUNT) { dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", @@ -2176,11 +2196,29 @@ goto reset_err; } + if (RSS_AQ(adapter)) { + adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS; + } else { + err = iavf_init_rss(adapter); + if (err) + goto reset_err; + } + adapter->aq_required |= IAVF_FLAG_AQ_GET_CONFIG; adapter->aq_required |= IAVF_FLAG_AQ_MAP_VECTORS; spin_lock_bh(&adapter->mac_vlan_list_lock); + /* Delete filter for the current MAC address, it could have + * been changed by the PF via administratively set MAC. + * Will be re-added via VIRTCHNL_OP_GET_VF_RESOURCES. + */ + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { + if (ether_addr_equal(f->macaddr, adapter->hw.mac.addr)) { + list_del(&f->list); + kfree(f); + } + } /* re-add all MAC filters */ list_for_each_entry(f, &adapter->mac_filter_list, list) { f->add = true; @@ -2274,6 +2312,8 @@ if (!event.msg_buf) goto out; + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 200)) + goto freedom; do { ret = iavf_clean_arq_element(hw, &event, &pending); v_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high); @@ -2287,6 +2327,7 @@ if (pending != 0) memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE); } while (pending); + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); if ((adapter->flags & (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) || @@ -2295,7 +2336,7 @@ /* check for error indications */ val = rd32(hw, hw->aq.arq.len); - if (val == 0xdeadbeef) /* indicates device in reset */ + if (val == 0xdeadbeef || val == 0xffffffff) /* device in reset */ goto freedom; oldval = val; if (val & IAVF_VF_ARQLEN1_ARQVFE_MASK) { @@ -2478,6 +2519,16 @@ { int speed = 0, ret = 0; + if (ADV_LINK_SUPPORT(adapter)) { + if (adapter->link_speed_mbps < U32_MAX) { + speed = adapter->link_speed_mbps; + goto validate_bw; + } else { + dev_err(&adapter->pdev->dev, "Unknown link speed\n"); + return -EINVAL; + } + } + switch (adapter->link_speed) { case IAVF_LINK_SPEED_40GB: speed = 40000; @@ -2501,6 +2552,7 @@ break; } +validate_bw: if (max_tx_rate > speed) { dev_err(&adapter->pdev->dev, "Invalid tx rate specified\n"); @@ -2523,6 +2575,7 @@ struct tc_mqprio_qopt_offload *mqprio_qopt) { u64 total_max_rate = 0; + u32 tx_rate_rem = 0; int i, num_qps = 0; u64 tx_rate = 0; int ret = 0; @@ -2537,17 +2590,40 @@ return -EINVAL; if (mqprio_qopt->min_rate[i]) { dev_err(&adapter->pdev->dev, - "Invalid min tx rate (greater than 0) specified\n"); + "Invalid min tx rate (greater than 0) specified for TC%d\n", + i); return -EINVAL; } - /*convert to Mbps */ + + /* convert to Mbps */ tx_rate = div_u64(mqprio_qopt->max_rate[i], IAVF_MBPS_DIVISOR); + + if (mqprio_qopt->max_rate[i] && + tx_rate < IAVF_MBPS_QUANTA) { + dev_err(&adapter->pdev->dev, + "Invalid max tx rate for TC%d, minimum %dMbps\n", + i, IAVF_MBPS_QUANTA); + return -EINVAL; + } + + (void)div_u64_rem(tx_rate, IAVF_MBPS_QUANTA, &tx_rate_rem); + + if (tx_rate_rem != 0) { + dev_err(&adapter->pdev->dev, + "Invalid max tx rate for TC%d, not divisible by %d\n", + i, IAVF_MBPS_QUANTA); + return -EINVAL; + } + total_max_rate += tx_rate; num_qps += mqprio_qopt->qopt.count[i]; } - if (num_qps > IAVF_MAX_REQ_QUEUES) + if (num_qps > adapter->num_active_queues) { + dev_err(&adapter->pdev->dev, + "Cannot support requested number of queues\n"); return -EINVAL; + } ret = iavf_validate_tx_bandwidth(adapter, total_max_rate); return ret; @@ -2572,6 +2648,34 @@ } /** + * iavf_is_tc_config_same - Compare the mqprio TC config with the + * TC config already configured on this adapter. + * @adapter: board private structure + * @mqprio_qopt: TC config received from kernel. + * + * This function compares the TC config received from the kernel + * with the config already configured on the adapter. + * + * Return: True if configuration is same, false otherwise. + **/ +static bool iavf_is_tc_config_same(struct iavf_adapter *adapter, + struct tc_mqprio_qopt *mqprio_qopt) +{ + struct virtchnl_channel_info *ch = &adapter->ch_config.ch_info[0]; + int i; + + if (adapter->num_tc != mqprio_qopt->num_tc) + return false; + + for (i = 0; i < adapter->num_tc; i++) { + if (ch[i].count != mqprio_qopt->count[i] || + ch[i].offset != mqprio_qopt->offset[i]) + return false; + } + return true; +} + +/** * __iavf_setup_tc - configure multiple traffic classes * @netdev: network interface device structure * @type_date: tc offload data @@ -2627,7 +2731,7 @@ if (ret) return ret; /* Return if same TC config is requested */ - if (adapter->num_tc == num_tc) + if (iavf_is_tc_config_same(adapter, &mqprio_qopt->qopt)) return 0; adapter->num_tc = num_tc; @@ -2976,11 +3080,11 @@ /* start out with flow type and eth type IPv4 to begin with */ filter->f.flow_type = VIRTCHNL_TCP_V4_FLOW; err = iavf_parse_cls_flower(adapter, cls_flower, filter); - if (err < 0) + if (err) goto err; err = iavf_handle_tclass(adapter, tc, filter); - if (err < 0) + if (err) goto err; /* add filter to the list */ @@ -3052,9 +3156,6 @@ static int iavf_setup_tc_cls_flower(struct iavf_adapter *adapter, struct flow_cls_offload *cls_flower) { - if (cls_flower->common.chain_index) - return -EOPNOTSUPP; - switch (cls_flower->command) { case FLOW_CLS_REPLACE: return iavf_configure_clsflower(adapter, cls_flower); @@ -3078,6 +3179,11 @@ static int iavf_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) { + struct iavf_adapter *adapter = cb_priv; + + if (!tc_cls_can_offload_and_chain0(adapter->netdev, type_data)) + return -EOPNOTSUPP; + switch (type) { case TC_SETUP_CLSFLOWER: return iavf_setup_tc_cls_flower(cb_priv, type_data); @@ -3260,8 +3366,11 @@ iavf_notify_client_l2_params(&adapter->vsi); adapter->flags |= IAVF_FLAG_SERVICE_CLIENT_REQUESTED; } - adapter->flags |= IAVF_FLAG_RESET_NEEDED; - queue_work(iavf_wq, &adapter->reset_task); + + if (netif_running(netdev)) { + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + queue_work(iavf_wq, &adapter->reset_task); + } return 0; } @@ -3365,7 +3474,8 @@ { struct iavf_adapter *adapter = netdev_priv(netdev); - if (!(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) + if (adapter->vf_res && + !(adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)) features &= ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER); @@ -3570,6 +3680,10 @@ init_task.work); struct iavf_hw *hw = &adapter->hw; + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) { + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + return; + } switch (adapter->state) { case __IAVF_STARTUP: if (iavf_startup(adapter) < 0) @@ -3582,14 +3696,14 @@ case __IAVF_INIT_GET_RESOURCES: if (iavf_init_get_resources(adapter) < 0) goto init_failed; - return; + goto out; default: goto init_failed; } queue_delayed_work(iavf_wq, &adapter->init_task, msecs_to_jiffies(30)); - return; + goto out; init_failed: if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) { dev_err(&adapter->pdev->dev, @@ -3598,9 +3712,11 @@ iavf_shutdown_adminq(hw); adapter->state = __IAVF_STARTUP; queue_delayed_work(iavf_wq, &adapter->init_task, HZ * 5); - return; + goto out; } queue_delayed_work(iavf_wq, &adapter->init_task, HZ); +out: + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); } /** @@ -3617,9 +3733,12 @@ if (netif_running(netdev)) iavf_close(netdev); + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); /* Prevent the watchdog from running. */ adapter->state = __IAVF_REMOVE; adapter->aq_required = 0; + clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); #ifdef CONFIG_PM pci_save_state(pdev); @@ -3739,6 +3858,7 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_pci_reg: err_dma: @@ -3746,7 +3866,6 @@ return err; } -#ifdef CONFIG_PM /** * iavf_suspend - Power management suspend routine * @pdev: PCI device information struct @@ -3754,11 +3873,10 @@ * * Called when the system (VM) is entering sleep/suspend. **/ -static int iavf_suspend(struct pci_dev *pdev, pm_message_t state) +static int __maybe_unused iavf_suspend(struct device *dev_d) { - struct net_device *netdev = pci_get_drvdata(pdev); + struct net_device *netdev = dev_get_drvdata(dev_d); struct iavf_adapter *adapter = netdev_priv(netdev); - int retval = 0; netif_device_detach(netdev); @@ -3776,12 +3894,6 @@ clear_bit(__IAVF_IN_CRITICAL_TASK, &adapter->crit_section); - retval = pci_save_state(pdev); - if (retval) - return retval; - - pci_disable_device(pdev); - return 0; } @@ -3791,24 +3903,13 @@ * * Called when the system (VM) is resumed from sleep/suspend. **/ -static int iavf_resume(struct pci_dev *pdev) +static int __maybe_unused iavf_resume(struct device *dev_d) { - struct iavf_adapter *adapter = pci_get_drvdata(pdev); - struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = to_pci_dev(dev_d); + struct net_device *netdev = pci_get_drvdata(pdev); + struct iavf_adapter *adapter = netdev_priv(netdev); u32 err; - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - /* pci_restore_state clears dev->state_saved so call - * pci_save_state to restore it. - */ - pci_save_state(pdev); - - err = pci_enable_device_mem(pdev); - if (err) { - dev_err(&pdev->dev, "Cannot enable PCI device from suspend.\n"); - return err; - } pci_set_master(pdev); rtnl_lock(); @@ -3832,7 +3933,6 @@ return err; } -#endif /* CONFIG_PM */ /** * iavf_remove - Device Removal Routine * @pdev: PCI device information struct @@ -3867,10 +3967,6 @@ err); } - /* Shut down all the garbage mashers on the detention level */ - adapter->state = __IAVF_REMOVE; - adapter->aq_required = 0; - adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; iavf_request_reset(adapter); msleep(50); /* If the FW isn't responding, kick it once, but only once. */ @@ -3878,6 +3974,13 @@ iavf_request_reset(adapter); msleep(50); } + if (iavf_lock_timeout(adapter, __IAVF_IN_CRITICAL_TASK, 5000)) + dev_warn(&adapter->pdev->dev, "failed to set __IAVF_IN_CRITICAL_TASK in %s\n", __FUNCTION__); + + /* Shut down all the garbage mashers on the detention level */ + adapter->state = __IAVF_REMOVE; + adapter->aq_required = 0; + adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; iavf_free_all_tx_resources(adapter); iavf_free_all_rx_resources(adapter); iavf_misc_irq_disable(adapter); @@ -3900,8 +4003,6 @@ iounmap(hw->hw_addr); pci_release_regions(pdev); - iavf_free_all_tx_resources(adapter); - iavf_free_all_rx_resources(adapter); iavf_free_queues(adapter); kfree(adapter->vf_res); spin_lock_bh(&adapter->mac_vlan_list_lock); @@ -3934,16 +4035,15 @@ pci_disable_device(pdev); } +static SIMPLE_DEV_PM_OPS(iavf_pm_ops, iavf_suspend, iavf_resume); + static struct pci_driver iavf_driver = { - .name = iavf_driver_name, - .id_table = iavf_pci_tbl, - .probe = iavf_probe, - .remove = iavf_remove, -#ifdef CONFIG_PM - .suspend = iavf_suspend, - .resume = iavf_resume, -#endif - .shutdown = iavf_shutdown, + .name = iavf_driver_name, + .id_table = iavf_pci_tbl, + .probe = iavf_probe, + .remove = iavf_remove, + .driver.pm = &iavf_pm_ops, + .shutdown = iavf_shutdown, }; /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_register.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_register.h @@ -40,7 +40,7 @@ #define IAVF_VFINT_DYN_CTL01_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTL01_INTENA_SHIFT) #define IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT 3 #define IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK IAVF_MASK(0x3, IAVF_VFINT_DYN_CTL01_ITR_INDX_SHIFT) -#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */ +#define IAVF_VFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...63 */ /* Reset: VFR */ #define IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT 0 #define IAVF_VFINT_DYN_CTLN1_INTENA_MASK IAVF_MASK(0x1, IAVF_VFINT_DYN_CTLN1_INTENA_SHIFT) #define IAVF_VFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_txrx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_txrx.c @@ -114,8 +114,11 @@ { u32 head, tail; + /* underlying hardware might not allow access and/or always return + * 0 for the head/tail registers so just use the cached values + */ head = ring->next_to_clean; - tail = readl(ring->tail); + tail = ring->next_to_use; if (head != tail) return (head < tail) ? @@ -1058,7 +1061,7 @@ cpu_to_le64((u64)IAVF_RX_DESC_FLTSTAT_RSS_HASH << IAVF_RX_DESC_STATUS_FLTSTAT_SHIFT); - if (ring->netdev->features & NETIF_F_RXHASH) + if (!(ring->netdev->features & NETIF_F_RXHASH)) return; if ((rx_desc->wb.qword1.status_error_len & rss_mask) == rss_mask) { @@ -1263,11 +1266,10 @@ { struct iavf_rx_buffer *rx_buffer; - if (!size) - return NULL; - rx_buffer = &rx_ring->rx_bi[rx_ring->next_to_clean]; prefetchw(rx_buffer->page); + if (!size) + return rx_buffer; /* we are reusing so sync this buffer for CPU use */ dma_sync_single_range_for_cpu(rx_ring->dev, @@ -1372,7 +1374,7 @@ #endif struct sk_buff *skb; - if (!rx_buffer) + if (!rx_buffer || !size) return NULL; /* prefetch first cache line of first page */ va = page_address(rx_buffer->page) + rx_buffer->page_offset; @@ -1532,7 +1534,7 @@ /* exit if we failed to retrieve a buffer */ if (!skb) { rx_ring->rx_stats.alloc_buff_failed++; - if (rx_buffer) + if (rx_buffer && size) rx_buffer->pagecnt_bias++; break; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -139,7 +139,8 @@ VIRTCHNL_VF_OFFLOAD_ENCAP | VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM | VIRTCHNL_VF_OFFLOAD_REQ_QUEUES | - VIRTCHNL_VF_OFFLOAD_ADQ; + VIRTCHNL_VF_OFFLOAD_ADQ | + VIRTCHNL_VF_CAP_ADV_LINK_SPEED; adapter->current_op = VIRTCHNL_OP_GET_VF_RESOURCES; adapter->aq_required &= ~IAVF_FLAG_AQ_GET_CONFIG; @@ -240,11 +241,14 @@ void iavf_configure_queues(struct iavf_adapter *adapter) { struct virtchnl_vsi_queue_config_info *vqci; - struct virtchnl_queue_pair_info *vqpi; + int i, max_frame = adapter->vf_res->max_mtu; int pairs = adapter->num_active_queues; - int i, max_frame = IAVF_MAX_RXBUFFER; + struct virtchnl_queue_pair_info *vqpi; size_t len; + if (max_frame > IAVF_MAX_RXBUFFER || !max_frame) + max_frame = IAVF_MAX_RXBUFFER; + if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) { /* bail because we already have a command pending */ dev_err(&adapter->pdev->dev, "Cannot configure queues, command %d pending\n", @@ -564,6 +568,47 @@ } /** + * iavf_mac_add_ok + * @adapter: adapter structure + * + * Submit list of filters based on PF response. + **/ +static void iavf_mac_add_ok(struct iavf_adapter *adapter) +{ + struct iavf_mac_filter *f, *ftmp; + + spin_lock_bh(&adapter->mac_vlan_list_lock); + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { + f->is_new_mac = false; + } + spin_unlock_bh(&adapter->mac_vlan_list_lock); +} + +/** + * iavf_mac_add_reject + * @adapter: adapter structure + * + * Remove filters from list based on PF response. + **/ +static void iavf_mac_add_reject(struct iavf_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct iavf_mac_filter *f, *ftmp; + + spin_lock_bh(&adapter->mac_vlan_list_lock); + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { + if (f->remove && ether_addr_equal(f->macaddr, netdev->dev_addr)) + f->remove = false; + + if (f->is_new_mac) { + list_del(&f->list); + kfree(f); + } + } + spin_unlock_bh(&adapter->mac_vlan_list_lock); +} + +/** * iavf_add_vlans * @adapter: adapter structure * @@ -918,6 +963,8 @@ iavf_send_pf_msg(adapter, VIRTCHNL_OP_DISABLE_VLAN_STRIPPING, NULL, 0); } +#define IAVF_MAX_SPEED_STRLEN 13 + /** * iavf_print_link_message - print link up or down * @adapter: adapter structure @@ -927,37 +974,99 @@ static void iavf_print_link_message(struct iavf_adapter *adapter) { struct net_device *netdev = adapter->netdev; - char *speed = "Unknown "; + int link_speed_mbps; + char *speed; if (!adapter->link_up) { netdev_info(netdev, "NIC Link is Down\n"); return; } + speed = kcalloc(1, IAVF_MAX_SPEED_STRLEN, GFP_KERNEL); + if (!speed) + return; + + if (ADV_LINK_SUPPORT(adapter)) { + link_speed_mbps = adapter->link_speed_mbps; + goto print_link_msg; + } + switch (adapter->link_speed) { case IAVF_LINK_SPEED_40GB: - speed = "40 G"; + link_speed_mbps = SPEED_40000; break; case IAVF_LINK_SPEED_25GB: - speed = "25 G"; + link_speed_mbps = SPEED_25000; break; case IAVF_LINK_SPEED_20GB: - speed = "20 G"; + link_speed_mbps = SPEED_20000; break; case IAVF_LINK_SPEED_10GB: - speed = "10 G"; + link_speed_mbps = SPEED_10000; break; case IAVF_LINK_SPEED_1GB: - speed = "1000 M"; + link_speed_mbps = SPEED_1000; break; case IAVF_LINK_SPEED_100MB: - speed = "100 M"; + link_speed_mbps = SPEED_100; break; default: + link_speed_mbps = SPEED_UNKNOWN; break; } - netdev_info(netdev, "NIC Link is Up %sbps Full Duplex\n", speed); +print_link_msg: + if (link_speed_mbps > SPEED_1000) { + if (link_speed_mbps == SPEED_2500) + snprintf(speed, IAVF_MAX_SPEED_STRLEN, "2.5 Gbps"); + else + /* convert to Gbps inline */ + snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%d %s", + link_speed_mbps / 1000, "Gbps"); + } else if (link_speed_mbps == SPEED_UNKNOWN) { + snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%s", "Unknown Mbps"); + } else { + snprintf(speed, IAVF_MAX_SPEED_STRLEN, "%u %s", + link_speed_mbps, "Mbps"); + } + + netdev_info(netdev, "NIC Link is Up Speed is %s Full Duplex\n", speed); + kfree(speed); +} + +/** + * iavf_get_vpe_link_status + * @adapter: adapter structure + * @vpe: virtchnl_pf_event structure + * + * Helper function for determining the link status + **/ +static bool +iavf_get_vpe_link_status(struct iavf_adapter *adapter, + struct virtchnl_pf_event *vpe) +{ + if (ADV_LINK_SUPPORT(adapter)) + return vpe->event_data.link_event_adv.link_status; + else + return vpe->event_data.link_event.link_status; +} + +/** + * iavf_set_adapter_link_speed_from_vpe + * @adapter: adapter structure for which we are setting the link speed + * @vpe: virtchnl_pf_event structure that contains the link speed we are setting + * + * Helper function for setting iavf_adapter link speed + **/ +static void +iavf_set_adapter_link_speed_from_vpe(struct iavf_adapter *adapter, + struct virtchnl_pf_event *vpe) +{ + if (ADV_LINK_SUPPORT(adapter)) + adapter->link_speed_mbps = + vpe->event_data.link_event_adv.link_speed; + else + adapter->link_speed = vpe->event_data.link_event.link_speed; } /** @@ -1187,12 +1296,11 @@ if (v_opcode == VIRTCHNL_OP_EVENT) { struct virtchnl_pf_event *vpe = (struct virtchnl_pf_event *)msg; - bool link_up = vpe->event_data.link_event.link_status; + bool link_up = iavf_get_vpe_link_status(adapter, vpe); switch (vpe->event) { case VIRTCHNL_EVENT_LINK_CHANGE: - adapter->link_speed = - vpe->event_data.link_event.link_speed; + iavf_set_adapter_link_speed_from_vpe(adapter, vpe); /* we've already got the right link status, bail */ if (adapter->link_up == link_up) @@ -1252,6 +1360,7 @@ case VIRTCHNL_OP_ADD_ETH_ADDR: dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n", iavf_stat_str(&adapter->hw, v_retval)); + iavf_mac_add_reject(adapter); /* restore administratively set MAC address */ ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr); break; @@ -1321,10 +1430,11 @@ } } switch (v_opcode) { - case VIRTCHNL_OP_ADD_ETH_ADDR: { + case VIRTCHNL_OP_ADD_ETH_ADDR: + if (!v_retval) + iavf_mac_add_ok(adapter); if (!ether_addr_equal(netdev->dev_addr, adapter->hw.mac.addr)) ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr); - } break; case VIRTCHNL_OP_GET_STATS: { struct iavf_eth_stats *stats = @@ -1359,6 +1469,9 @@ ether_addr_copy(netdev->perm_addr, adapter->hw.mac.addr); } + spin_lock_bh(&adapter->mac_vlan_list_lock); + iavf_add_filter(adapter, adapter->hw.mac.addr); + spin_unlock_bh(&adapter->mac_vlan_list_lock); iavf_process_config(adapter); } break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_common.c @@ -436,6 +436,7 @@ static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) { struct ice_switch_info *sw; + enum ice_status status; hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*hw->switch_info), GFP_KERNEL); @@ -446,7 +447,12 @@ INIT_LIST_HEAD(&sw->vsi_list_map_head); - return ice_init_def_sw_recp(hw); + status = ice_init_def_sw_recp(hw); + if (status) { + devm_kfree(ice_hw_to_dev(hw), hw->switch_info); + return status; + } + return 0; } /** @@ -934,7 +940,7 @@ */ enum ice_status ice_check_reset(struct ice_hw *hw) { - u32 cnt, reg = 0, grst_delay; + u32 cnt, reg = 0, grst_delay, uld_mask; /* Poll for Device Active state in case a recent CORER, GLOBR, * or EMPR has occurred. The grst delay value is in 100ms units. @@ -956,13 +962,20 @@ return ICE_ERR_RESET_FAILED; } -#define ICE_RESET_DONE_MASK (GLNVM_ULD_CORER_DONE_M | \ - GLNVM_ULD_GLOBR_DONE_M) +#define ICE_RESET_DONE_MASK (GLNVM_ULD_PCIER_DONE_M |\ + GLNVM_ULD_PCIER_DONE_1_M |\ + GLNVM_ULD_CORER_DONE_M |\ + GLNVM_ULD_GLOBR_DONE_M |\ + GLNVM_ULD_POR_DONE_M |\ + GLNVM_ULD_POR_DONE_1_M |\ + GLNVM_ULD_PCIER_DONE_2_M) + + uld_mask = ICE_RESET_DONE_MASK; /* Device is Active; check Global Reset processes are done */ for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { - reg = rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK; - if (reg == ICE_RESET_DONE_MASK) { + reg = rd32(hw, GLNVM_ULD) & uld_mask; + if (reg == uld_mask) { ice_debug(hw, ICE_DBG_INIT, "Global reset processes done. %d\n", cnt); break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_controlq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_controlq.c @@ -199,7 +199,9 @@ cq->rq.r.rq_bi[i].pa = 0; cq->rq.r.rq_bi[i].size = 0; } + cq->rq.r.rq_bi = NULL; devm_kfree(ice_hw_to_dev(hw), cq->rq.dma_head); + cq->rq.dma_head = NULL; return ICE_ERR_NO_MEMORY; } @@ -245,7 +247,9 @@ cq->sq.r.sq_bi[i].pa = 0; cq->sq.r.sq_bi[i].size = 0; } + cq->sq.r.sq_bi = NULL; devm_kfree(ice_hw_to_dev(hw), cq->sq.dma_head); + cq->sq.dma_head = NULL; return ICE_ERR_NO_MEMORY; } @@ -304,6 +308,28 @@ return 0; } +#define ICE_FREE_CQ_BUFS(hw, qi, ring) \ +do { \ + int i; \ + /* free descriptors */ \ + if ((qi)->ring.r.ring##_bi) \ + for (i = 0; i < (qi)->num_##ring##_entries; i++) \ + if ((qi)->ring.r.ring##_bi[i].pa) { \ + dmam_free_coherent(ice_hw_to_dev(hw), \ + (qi)->ring.r.ring##_bi[i].size, \ + (qi)->ring.r.ring##_bi[i].va, \ + (qi)->ring.r.ring##_bi[i].pa); \ + (qi)->ring.r.ring##_bi[i].va = NULL;\ + (qi)->ring.r.ring##_bi[i].pa = 0;\ + (qi)->ring.r.ring##_bi[i].size = 0;\ + } \ + /* free the buffer info list */ \ + if ((qi)->ring.cmd_buf) \ + devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf); \ + /* free DMA head */ \ + devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head); \ +} while (0) + /** * ice_init_sq - main initialization routine for Control ATQ * @hw: pointer to the hardware structure @@ -357,6 +383,7 @@ goto init_ctrlq_exit; init_ctrlq_free_rings: + ICE_FREE_CQ_BUFS(hw, cq, sq); ice_free_cq_ring(hw, &cq->sq); init_ctrlq_exit: @@ -416,33 +443,13 @@ goto init_ctrlq_exit; init_ctrlq_free_rings: + ICE_FREE_CQ_BUFS(hw, cq, rq); ice_free_cq_ring(hw, &cq->rq); init_ctrlq_exit: return ret_code; } -#define ICE_FREE_CQ_BUFS(hw, qi, ring) \ -do { \ - int i; \ - /* free descriptors */ \ - for (i = 0; i < (qi)->num_##ring##_entries; i++) \ - if ((qi)->ring.r.ring##_bi[i].pa) { \ - dmam_free_coherent(ice_hw_to_dev(hw), \ - (qi)->ring.r.ring##_bi[i].size,\ - (qi)->ring.r.ring##_bi[i].va,\ - (qi)->ring.r.ring##_bi[i].pa);\ - (qi)->ring.r.ring##_bi[i].va = NULL; \ - (qi)->ring.r.ring##_bi[i].pa = 0; \ - (qi)->ring.r.ring##_bi[i].size = 0; \ - } \ - /* free the buffer info list */ \ - if ((qi)->ring.cmd_buf) \ - devm_kfree(ice_hw_to_dev(hw), (qi)->ring.cmd_buf); \ - /* free DMA head */ \ - devm_kfree(ice_hw_to_dev(hw), (qi)->ring.dma_head); \ -} while (0) - /** * ice_shutdown_sq - shutdown the Control ATQ * @hw: pointer to the hardware structure @@ -948,7 +955,7 @@ if (ice_sq_done(hw, cq)) break; - mdelay(1); + udelay(ICE_CTL_Q_SQ_CMD_USEC); total_delay++; } while (total_delay < cq->sq_cmd_timeout); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_controlq.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_controlq.h @@ -31,8 +31,9 @@ ICE_CTL_Q_MAILBOX, }; -/* Control Queue default settings */ -#define ICE_CTL_Q_SQ_CMD_TIMEOUT 250 /* msecs */ +/* Control Queue timeout settings - max delay 1s */ +#define ICE_CTL_Q_SQ_CMD_TIMEOUT 10000 /* Count 10000 times */ +#define ICE_CTL_Q_SQ_CMD_USEC 100 /* Check every 100usec */ struct ice_ctl_q_ring { void *dma_head; /* Virtual address to DMA head */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_devids.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_devids.h @@ -5,11 +5,50 @@ #define _ICE_DEVIDS_H_ /* Device IDs */ +/* Intel(R) Ethernet Connection E823-L for backplane */ +#define ICE_DEV_ID_E823L_BACKPLANE 0x124C +/* Intel(R) Ethernet Connection E823-L for SFP */ +#define ICE_DEV_ID_E823L_SFP 0x124D +/* Intel(R) Ethernet Connection E823-L/X557-AT 10GBASE-T */ +#define ICE_DEV_ID_E823L_10G_BASE_T 0x124E +/* Intel(R) Ethernet Connection E823-L 1GbE */ +#define ICE_DEV_ID_E823L_1GBE 0x124F +/* Intel(R) Ethernet Connection E823-L for QSFP */ +#define ICE_DEV_ID_E823L_QSFP 0x151D /* Intel(R) Ethernet Controller E810-C for backplane */ #define ICE_DEV_ID_E810C_BACKPLANE 0x1591 /* Intel(R) Ethernet Controller E810-C for QSFP */ #define ICE_DEV_ID_E810C_QSFP 0x1592 /* Intel(R) Ethernet Controller E810-C for SFP */ #define ICE_DEV_ID_E810C_SFP 0x1593 - +/* Intel(R) Ethernet Controller E810-XXV for SFP */ +#define ICE_DEV_ID_E810_XXV_SFP 0x159B +/* Intel(R) Ethernet Connection E823-C for backplane */ +#define ICE_DEV_ID_E823C_BACKPLANE 0x188A +/* Intel(R) Ethernet Connection E823-C for QSFP */ +#define ICE_DEV_ID_E823C_QSFP 0x188B +/* Intel(R) Ethernet Connection E823-C for SFP */ +#define ICE_DEV_ID_E823C_SFP 0x188C +/* Intel(R) Ethernet Connection E823-C/X557-AT 10GBASE-T */ +#define ICE_DEV_ID_E823C_10G_BASE_T 0x188D +/* Intel(R) Ethernet Connection E823-C 1GbE */ +#define ICE_DEV_ID_E823C_SGMII 0x188E +/* Intel(R) Ethernet Connection E822-C for backplane */ +#define ICE_DEV_ID_E822C_BACKPLANE 0x1890 +/* Intel(R) Ethernet Connection E822-C for QSFP */ +#define ICE_DEV_ID_E822C_QSFP 0x1891 +/* Intel(R) Ethernet Connection E822-C for SFP */ +#define ICE_DEV_ID_E822C_SFP 0x1892 +/* Intel(R) Ethernet Connection E822-C/X557-AT 10GBASE-T */ +#define ICE_DEV_ID_E822C_10G_BASE_T 0x1893 +/* Intel(R) Ethernet Connection E822-C 1GbE */ +#define ICE_DEV_ID_E822C_SGMII 0x1894 +/* Intel(R) Ethernet Connection E822-X for backplane */ +#define ICE_DEV_ID_E822X_BACKPLANE 0x1897 +/* Intel(R) Ethernet Connection E822-L for SFP */ +#define ICE_DEV_ID_E822L_SFP 0x1898 +/* Intel(R) Ethernet Connection E822-L/X557-AT 10GBASE-T */ +#define ICE_DEV_ID_E822L_10G_BASE_T 0x1899 +/* Intel(R) Ethernet Connection E822-L 1GbE */ +#define ICE_DEV_ID_E822L_SGMII 0x189A #endif /* _ICE_DEVIDS_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -138,9 +138,6 @@ QINT_RQCTL(0), PFINT_OICR_ENA, QRX_ITR(0), - PF0INT_ITR_0(0), - PF0INT_ITR_1(0), - PF0INT_ITR_2(0), }; struct ice_priv_flag { @@ -619,7 +616,8 @@ rx_desc = ICE_RX_DESC(rx_ring, i); if (!(rx_desc->wb.status_error0 & - cpu_to_le16(ICE_TX_DESC_CMD_EOP | ICE_TX_DESC_CMD_RS))) + (cpu_to_le16(BIT(ICE_RX_FLEX_DESC_STATUS0_DD_S)) | + cpu_to_le16(BIT(ICE_RX_FLEX_DESC_STATUS0_EOF_S))))) continue; rx_buf = &rx_ring->rx_buf[i]; @@ -2338,6 +2336,42 @@ } /** + * ice_set_phy_type_from_speed - set phy_types based on speeds + * and advertised modes + * @ks: ethtool link ksettings struct + * @phy_type_low: pointer to the lower part of phy_type + * @phy_type_high: pointer to the higher part of phy_type + * @adv_link_speed: targeted link speeds bitmap + */ +static void +ice_set_phy_type_from_speed(const struct ethtool_link_ksettings *ks, + u64 *phy_type_low, u64 *phy_type_high, + u16 adv_link_speed) +{ + /* Handle 1000M speed in a special way because ice_update_phy_type + * enables all link modes, but having mixed copper and optical + * standards is not supported. + */ + adv_link_speed &= ~ICE_AQ_LINK_SPEED_1000MB; + + if (ethtool_link_ksettings_test_link_mode(ks, advertising, + 1000baseT_Full)) + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_T | + ICE_PHY_TYPE_LOW_1G_SGMII; + + if (ethtool_link_ksettings_test_link_mode(ks, advertising, + 1000baseKX_Full)) + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_KX; + + if (ethtool_link_ksettings_test_link_mode(ks, advertising, + 1000baseX_Full)) + *phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_SX | + ICE_PHY_TYPE_LOW_1000BASE_LX; + + ice_update_phy_type(phy_type_low, phy_type_high, adv_link_speed); +} + +/** * ice_set_link_ksettings - Set Speed and Duplex * @netdev: network interface device structure * @ks: ethtool ksettings @@ -2472,7 +2506,8 @@ adv_link_speed = curr_link_speed; /* Convert the advertise link speeds to their corresponded PHY_TYPE */ - ice_update_phy_type(&phy_type_low, &phy_type_high, adv_link_speed); + ice_set_phy_type_from_speed(ks, &phy_type_low, &phy_type_high, + adv_link_speed); if (!autoneg_changed && adv_link_speed == curr_link_speed) { netdev_info(netdev, "Nothing changed, exiting without setting anything.\n"); @@ -2635,14 +2670,14 @@ netdev_info(netdev, "Changing Tx descriptor count from %d to %d\n", vsi->tx_rings[0]->count, new_tx_cnt); - tx_rings = devm_kcalloc(&pf->pdev->dev, vsi->alloc_txq, + tx_rings = devm_kcalloc(&pf->pdev->dev, vsi->num_txq, sizeof(*tx_rings), GFP_KERNEL); if (!tx_rings) { err = -ENOMEM; goto done; } - for (i = 0; i < vsi->alloc_txq; i++) { + ice_for_each_txq(vsi, i) { /* clone ring and setup updated count */ tx_rings[i] = *vsi->tx_rings[i]; tx_rings[i].count = new_tx_cnt; @@ -2667,14 +2702,14 @@ netdev_info(netdev, "Changing Rx descriptor count from %d to %d\n", vsi->rx_rings[0]->count, new_rx_cnt); - rx_rings = devm_kcalloc(&pf->pdev->dev, vsi->alloc_rxq, + rx_rings = devm_kcalloc(&pf->pdev->dev, vsi->num_rxq, sizeof(*rx_rings), GFP_KERNEL); if (!rx_rings) { err = -ENOMEM; goto done; } - for (i = 0; i < vsi->alloc_rxq; i++) { + ice_for_each_rxq(vsi, i) { /* clone ring and setup updated count */ rx_rings[i] = *vsi->rx_rings[i]; rx_rings[i].count = new_rx_cnt; @@ -2712,7 +2747,7 @@ ice_down(vsi); if (tx_rings) { - for (i = 0; i < vsi->alloc_txq; i++) { + ice_for_each_txq(vsi, i) { ice_free_tx_ring(vsi->tx_rings[i]); *vsi->tx_rings[i] = tx_rings[i]; } @@ -2720,7 +2755,7 @@ } if (rx_rings) { - for (i = 0; i < vsi->alloc_rxq; i++) { + ice_for_each_rxq(vsi, i) { ice_free_rx_ring(vsi->rx_rings[i]); /* copy the real tail offset */ rx_rings[i].tail = vsi->rx_rings[i]->tail; @@ -2744,7 +2779,7 @@ free_tx: /* error cleanup if the Rx allocations failed after getting Tx */ if (tx_rings) { - for (i = 0; i < vsi->alloc_txq; i++) + ice_for_each_txq(vsi, i) ice_free_tx_ring(&tx_rings[i]); devm_kfree(&pf->pdev->dev, tx_rings); } @@ -2916,13 +2951,6 @@ else return -EINVAL; - /* Tell the OS link is going down, the link will go back up when fw - * says it is ready asynchronously - */ - ice_print_link_msg(vsi, false); - netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); - /* Set the FC mode and only restart AN if link is up */ status = ice_set_fc(pi, &aq_failures, link_up); @@ -3368,10 +3396,17 @@ struct ice_vsi *vsi = np->vsi; if (q_num < 0) { - int i; + int v_idx; + + ice_for_each_q_vector(vsi, v_idx) { + /* In some cases if DCB is configured the num_[rx|tx]q + * can be less than vsi->num_q_vectors. This check + * accounts for that so we don't report a false failure + */ + if (v_idx >= vsi->num_rxq && v_idx >= vsi->num_txq) + goto set_complete; - ice_for_each_q_vector(vsi, i) { - if (ice_set_q_coalesce(vsi, ec, i)) + if (ice_set_q_coalesce(vsi, ec, v_idx)) return -EINVAL; } goto set_complete; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_flex_pipe.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_flex_pipe.c @@ -1535,10 +1535,12 @@ es->ref_count = devm_kcalloc(ice_hw_to_dev(hw), es->count, sizeof(*es->ref_count), GFP_KERNEL); + if (!es->ref_count) + goto err; es->written = devm_kcalloc(ice_hw_to_dev(hw), es->count, sizeof(*es->written), GFP_KERNEL); - if (!es->ref_count) + if (!es->written) goto err; } return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_hw_autogen.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_hw_autogen.h @@ -6,9 +6,6 @@ #ifndef _ICE_HW_AUTOGEN_H_ #define _ICE_HW_AUTOGEN_H_ -#define PF0INT_ITR_0(_i) (0x03000004 + ((_i) * 4096)) -#define PF0INT_ITR_1(_i) (0x03000008 + ((_i) * 4096)) -#define PF0INT_ITR_2(_i) (0x0300000C + ((_i) * 4096)) #define QTX_COMM_DBELL(_DBQM) (0x002C0000 + ((_DBQM) * 4)) #define QTX_COMM_HEAD(_DBQM) (0x000E0000 + ((_DBQM) * 4)) #define QTX_COMM_HEAD_HEAD_S 0 @@ -34,6 +31,7 @@ #define PF_FW_ATQLEN_ATQOVFL_M BIT(29) #define PF_FW_ATQLEN_ATQCRIT_M BIT(30) #define VF_MBX_ARQLEN(_VF) (0x0022BC00 + ((_VF) * 4)) +#define VF_MBX_ATQLEN(_VF) (0x0022A800 + ((_VF) * 4)) #define PF_FW_ATQLEN_ATQENABLE_M BIT(31) #define PF_FW_ATQT 0x00080400 #define PF_MBX_ARQBAH 0x0022E400 @@ -273,8 +271,14 @@ #define GLNVM_GENS_SR_SIZE_S 5 #define GLNVM_GENS_SR_SIZE_M ICE_M(0x7, 5) #define GLNVM_ULD 0x000B6008 +#define GLNVM_ULD_PCIER_DONE_M BIT(0) +#define GLNVM_ULD_PCIER_DONE_1_M BIT(1) #define GLNVM_ULD_CORER_DONE_M BIT(3) #define GLNVM_ULD_GLOBR_DONE_M BIT(4) +#define GLNVM_ULD_POR_DONE_M BIT(5) +#define GLNVM_ULD_POR_DONE_1_M BIT(8) +#define GLNVM_ULD_PCIER_DONE_2_M BIT(9) +#define GLNVM_ULD_PE_DONE_M BIT(10) #define GLPCI_CNF2 0x000BE004 #define GLPCI_CNF2_CACHELINE_SIZE_M BIT(1) #define PF_FUNC_RID 0x0009E880 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_lib.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1015,8 +1015,7 @@ ctxt->info.q_opt_rss = ((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | - ((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) & - ICE_AQ_VSI_Q_OPT_RSS_HASH_M); + (hash_type & ICE_AQ_VSI_Q_OPT_RSS_HASH_M); } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_main.c @@ -2900,7 +2900,7 @@ if (err) { dev_err(dev, "ice_init_interrupt_scheme failed: %d\n", err); err = -EIO; - goto err_init_interrupt_unroll; + goto err_init_vsi_unroll; } /* Driver is mostly up */ @@ -2986,6 +2986,7 @@ ice_free_irq_msix_misc(pf); err_init_interrupt_unroll: ice_clear_interrupt_scheme(pf); +err_init_vsi_unroll: devm_kfree(dev, pf->vsi); err_init_pf_unroll: ice_deinit_pf(pf); @@ -3004,9 +3005,6 @@ struct ice_pf *pf = pci_get_drvdata(pdev); int i; - if (!pf) - return; - for (i = 0; i < ICE_MAX_RESET_WAIT; i++) { if (!ice_is_reset_in_progress(pf->state)) break; @@ -3178,6 +3176,26 @@ { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_BACKPLANE), 0 }, { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_QSFP), 0 }, { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810_XXV_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823C_BACKPLANE), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823C_QSFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823C_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823C_10G_BASE_T), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823C_SGMII), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822C_BACKPLANE), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822C_QSFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822C_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822C_10G_BASE_T), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822C_SGMII), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822X_BACKPLANE), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822L_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822L_10G_BASE_T), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E822L_SGMII), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823L_BACKPLANE), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823L_SFP), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823L_10G_BASE_T), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823L_1GBE), 0 }, + { PCI_VDEVICE(INTEL, ICE_DEV_ID_E823L_QSFP), 0 }, /* required last entry */ { 0, } }; @@ -3213,7 +3231,7 @@ pr_info("%s - version %s\n", ice_driver_string, ice_drv_ver); pr_info("%s\n", ice_copyright); - ice_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, KBUILD_MODNAME); + ice_wq = alloc_workqueue("%s", 0, 0, KBUILD_MODNAME); if (!ice_wq) { pr_err("Failed to create workqueue\n"); return -ENOMEM; @@ -3494,11 +3512,10 @@ { int err; - if (vsi->netdev) { + if (vsi->netdev && vsi->type == ICE_VSI_PF) { ice_set_rx_mode(vsi->netdev); err = ice_vsi_vlan_setup(vsi); - if (err) return err; } @@ -3557,13 +3574,19 @@ if (vsi->port_info && (vsi->port_info->phy.link_info.link_info & ICE_AQ_LINK_UP) && - vsi->netdev) { + vsi->netdev && vsi->type == ICE_VSI_PF) { ice_print_link_msg(vsi, true); netif_tx_start_all_queues(vsi->netdev); netif_carrier_on(vsi->netdev); } - ice_service_task_schedule(pf); + /* Perform an initial read of the statistics registers now to + * set the baseline so counters are ready when interface is up + */ + ice_update_eth_stats(vsi); + + if (vsi->type == ICE_VSI_PF) + ice_service_task_schedule(pf); return 0; } @@ -3970,8 +3993,13 @@ } ice_for_each_txq(vsi, i) { - vsi->tx_rings[i]->netdev = vsi->netdev; - err = ice_setup_tx_ring(vsi->tx_rings[i]); + struct ice_ring *ring = vsi->tx_rings[i]; + + if (!ring) + return -EINVAL; + + ring->netdev = vsi->netdev; + err = ice_setup_tx_ring(ring); if (err) break; } @@ -3996,8 +4024,13 @@ } ice_for_each_rxq(vsi, i) { - vsi->rx_rings[i]->netdev = vsi->netdev; - err = ice_setup_rx_ring(vsi->rx_rings[i]); + struct ice_ring *ring = vsi->rx_rings[i]; + + if (!ring) + return -EINVAL; + + ring->netdev = vsi->netdev; + err = ice_setup_rx_ring(ring); if (err) break; } @@ -4581,6 +4614,8 @@ pf_sw = pf->first_sw; /* find the attribute in the netlink message */ br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); + if (!br_spec) + return -EINVAL; nla_for_each_nested(attr, br_spec, rem) { __u16 mode; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_nvm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_nvm.c @@ -289,6 +289,32 @@ hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo; + switch (hw->device_id) { + /* the following devices do not have boot_cfg_tlv yet */ + case ICE_DEV_ID_E823C_BACKPLANE: + case ICE_DEV_ID_E823C_QSFP: + case ICE_DEV_ID_E823C_SFP: + case ICE_DEV_ID_E823C_10G_BASE_T: + case ICE_DEV_ID_E823C_SGMII: + case ICE_DEV_ID_E822C_BACKPLANE: + case ICE_DEV_ID_E822C_QSFP: + case ICE_DEV_ID_E822C_10G_BASE_T: + case ICE_DEV_ID_E822C_SGMII: + case ICE_DEV_ID_E822C_SFP: + case ICE_DEV_ID_E822X_BACKPLANE: + case ICE_DEV_ID_E822L_SFP: + case ICE_DEV_ID_E822L_10G_BASE_T: + case ICE_DEV_ID_E822L_SGMII: + case ICE_DEV_ID_E823L_BACKPLANE: + case ICE_DEV_ID_E823L_SFP: + case ICE_DEV_ID_E823L_10G_BASE_T: + case ICE_DEV_ID_E823L_1GBE: + case ICE_DEV_ID_E823L_QSFP: + return status; + default: + break; + } + return status; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_sched.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_sched.c @@ -27,9 +27,8 @@ if (!root) return ICE_ERR_NO_MEMORY; - /* coverity[suspicious_sizeof] */ root->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[0], - sizeof(*root), GFP_KERNEL); + sizeof(*root->children), GFP_KERNEL); if (!root->children) { devm_kfree(ice_hw_to_dev(hw), root); return ICE_ERR_NO_MEMORY; @@ -181,10 +180,9 @@ if (!node) return ICE_ERR_NO_MEMORY; if (hw->max_children[layer]) { - /* coverity[suspicious_sizeof] */ node->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[layer], - sizeof(*node), GFP_KERNEL); + sizeof(*node->children), GFP_KERNEL); if (!node->children) { devm_kfree(ice_hw_to_dev(hw), node); return ICE_ERR_NO_MEMORY; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_switch.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_switch.c @@ -1279,6 +1279,9 @@ ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, vsi_list_id); + if (!m_entry->vsi_list_info) + return ICE_ERR_NO_MEMORY; + /* If this entry was large action then the large action needs * to be updated to point to FWD to VSI list */ @@ -1296,7 +1299,7 @@ /* A rule already exists with the new VSI being added */ if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) - return 0; + return -EEXIST; /* Update the previously created VSI list set with * the new VSI ID passed in @@ -2266,6 +2269,7 @@ return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && fm_entry->fltr_info.vsi_handle == vsi_handle) || (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && + fm_entry->vsi_list_info && (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); } @@ -2338,14 +2342,12 @@ return ICE_ERR_PARAM; list_for_each_entry(fm_entry, lkup_list_head, list_entry) { - struct ice_fltr_info *fi; - - fi = &fm_entry->fltr_info; - if (!fi || !ice_vsi_uses_fltr(fm_entry, vsi_handle)) + if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) continue; status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, - vsi_list_head, fi); + vsi_list_head, + &fm_entry->fltr_info); if (status) return status; } @@ -2625,7 +2627,7 @@ else status = ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vlan_id); - if (status) + if (status && status != -EEXIST) break; } @@ -2663,7 +2665,7 @@ &remove_list_head); mutex_unlock(rule_lock); if (status) - return; + goto free_fltr_list; switch (lkup) { case ICE_SW_LKUP_MAC: @@ -2686,6 +2688,7 @@ break; } +free_fltr_list: list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { list_del(&fm_entry->list_entry); devm_kfree(ice_hw_to_dev(hw), fm_entry); @@ -2748,8 +2751,6 @@ if (!itr->vsi_list_info || !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) continue; - /* Clearing it so that the logic can add it back */ - clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); f_entry.fltr_info.vsi_handle = vsi_handle; f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; /* update the src in case it is VSI num */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_txrx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -2109,6 +2109,7 @@ struct ice_tx_offload_params offload = { 0 }; struct ice_vsi *vsi = tx_ring->vsi; struct ice_tx_buf *first; + struct ethhdr *eth; unsigned int count; int tso, csum; @@ -2156,7 +2157,9 @@ goto out_drop; /* allow CONTROL frames egress from main VSI if FW LLDP disabled */ - if (unlikely(skb->priority == TC_PRIO_CONTROL && + eth = (struct ethhdr *)skb_mac_header(skb); + if (unlikely((skb->priority == TC_PRIO_CONTROL || + eth->h_proto == htons(ETH_P_LLDP)) && vsi->type == ICE_VSI_PF && vsi->port_info->is_sw_lldp)) offload.cd_qw1 |= (u64)(ICE_TX_DESC_DTYPE_CTX | --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_type.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_type.h @@ -48,7 +48,7 @@ /* FW update timeout definitions are in milliseconds */ #define ICE_NVM_TIMEOUT 180000 #define ICE_CHANGE_LOCK_TIMEOUT 1000 -#define ICE_GLOBAL_CFG_LOCK_TIMEOUT 3000 +#define ICE_GLOBAL_CFG_LOCK_TIMEOUT 5000 enum ice_aq_res_access_type { ICE_RES_READ = 1, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c @@ -317,8 +317,9 @@ pf->num_alloc_vfs = 0; for (i = 0; i < tmp; i++) { if (test_bit(ICE_VF_STATE_INIT, pf->vf[i].vf_states)) { - /* disable VF qp mappings */ + /* disable VF qp mappings and set VF disable state */ ice_dis_vf_mappings(&pf->vf[i]); + set_bit(ICE_VF_STATE_DIS, pf->vf[i].vf_states); ice_free_vf_res(&pf->vf[i]); } } @@ -383,13 +384,15 @@ */ clear_bit(ICE_VF_STATE_INIT, vf->vf_states); - /* VF_MBX_ARQLEN is cleared by PFR, so the driver needs to clear it - * in the case of VFR. If this is done for PFR, it can mess up VF - * resets because the VF driver may already have started cleanup - * by the time we get here. - */ - if (!is_pfr) - wr32(hw, VF_MBX_ARQLEN(vf_abs_id), 0); + /* VF_MBX_ARQLEN and VF_MBX_ATQLEN are cleared by PFR, so the driver + * needs to clear them in the case of VFR/VFLR. If this is done for + * PFR, it can mess up VF resets because the VF driver may already + * have started cleanup by the time we get here. + */ + if (!is_pfr) { + wr32(hw, VF_MBX_ARQLEN(vf->vf_id), 0); + wr32(hw, VF_MBX_ATQLEN(vf->vf_id), 0); + } /* In the case of a VFLR, the HW has already reset the VF and we * just need to clean up, so don't hit the VFRTRIG register. @@ -1287,9 +1290,12 @@ if (!vf || vf->vf_id >= vf->pf->num_alloc_vfs) return; - /* verify if the VF is in either init or active before proceeding */ - if (!test_bit(ICE_VF_STATE_INIT, vf->vf_states) && - !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) + /* Bail out if VF is in disabled state, neither initialized, nor active + * state - otherwise proceed with notifications + */ + if ((!test_bit(ICE_VF_STATE_INIT, vf->vf_states) && + !test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) || + test_bit(ICE_VF_STATE_DIS, vf->vf_states)) return; pfe.event = VIRTCHNL_EVENT_RESET_IMPENDING; @@ -1869,8 +1875,8 @@ enum virtchnl_status_code v_ret = VIRTCHNL_STATUS_SUCCESS; struct virtchnl_queue_select *vqs = (struct virtchnl_queue_select *)msg; + struct ice_eth_stats stats = { 0 }; struct ice_pf *pf = vf->pf; - struct ice_eth_stats stats; struct ice_vsi *vsi; if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { @@ -1889,7 +1895,6 @@ goto error_param; } - memset(&stats, 0, sizeof(struct ice_eth_stats)); ice_update_eth_stats(vsi); stats = vsi->eth_stats; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/e1000_82575.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -530,7 +530,7 @@ dev_spec->module_plugged = true; if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) { hw->phy.media_type = e1000_media_type_internal_serdes; - } else if (eth_flags->e100_base_fx) { + } else if (eth_flags->e100_base_fx || eth_flags->e100_base_lx) { dev_spec->sgmii_active = true; hw->phy.media_type = e1000_media_type_internal_serdes; } else if (eth_flags->e1000_base_t) { @@ -657,14 +657,10 @@ break; } - /* do not change link mode for 100BaseFX */ - if (dev_spec->eth_flags.e100_base_fx) - break; - /* change current link mode setting */ ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK; - if (hw->phy.media_type == e1000_media_type_copper) + if (dev_spec->sgmii_active) ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII; else ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/e1000_mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -425,7 +425,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) { u32 hash_value, hash_mask; - u8 bit_shift = 0; + u8 bit_shift = 1; /* Register count multiplied by bits per register */ hash_mask = (hw->mac.mta_reg_count * 32) - 1; @@ -433,7 +433,7 @@ /* For a mc_filter_type of 0, bit_shift is the number of left-shifts * where 0xFF would still fall within the hash mask. */ - while (hash_mask >> bit_shift != 0xFF) + while (hash_mask >> bit_shift != 0xFF && bit_shift < 4) bit_shift++; /* The portion of the address that is used for the hash table --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/igb.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/igb.h @@ -32,11 +32,11 @@ /* TX/RX descriptor defines */ #define IGB_DEFAULT_TXD 256 #define IGB_DEFAULT_TX_WORK 128 -#define IGB_MIN_TXD 80 +#define IGB_MIN_TXD 64 #define IGB_MAX_TXD 4096 #define IGB_DEFAULT_RXD 256 -#define IGB_MIN_RXD 80 +#define IGB_MIN_RXD 64 #define IGB_MAX_RXD 4096 #define IGB_DEFAULT_ITR 3 /* dynamic */ @@ -594,6 +594,8 @@ struct igb_mac_addr *mac_table; struct vf_mac_filter vf_macs; struct vf_mac_filter *vf_mac_list; + /* lock for VF resources */ + spinlock_t vfs_lock; }; /* flags controlling PTP/1588 function */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -143,7 +143,8 @@ u32 speed; u32 supported, advertising; - status = rd32(E1000_STATUS); + status = pm_runtime_suspended(&adapter->pdev->dev) ? + 0 : rd32(E1000_STATUS); if (hw->phy.media_type == e1000_media_type_copper) { supported = (SUPPORTED_10baseT_Half | @@ -181,7 +182,7 @@ advertising &= ~ADVERTISED_1000baseKX_Full; } } - if (eth_flags->e100_base_fx) { + if (eth_flags->e100_base_fx || eth_flags->e100_base_lx) { supported |= SUPPORTED_100baseT_Full; advertising |= ADVERTISED_100baseT_Full; } @@ -813,6 +814,8 @@ */ ret_val = hw->nvm.ops.read(hw, last_word, 1, &eeprom_buff[last_word - first_word]); + if (ret_val) + goto out; } /* Device's eeprom is always little-endian, word addressable */ @@ -832,6 +835,7 @@ hw->nvm.ops.update(hw); igb_set_fw_version(adapter); +out: kfree(eeprom_buff); return ret_val; } @@ -1401,6 +1405,8 @@ *data = 1; return -1; } + wr32(E1000_IVAR_MISC, E1000_IVAR_VALID << 8); + wr32(E1000_EIMS, BIT(0)); } else if (adapter->flags & IGB_FLAG_HAS_MSI) { shared_int = false; if (request_irq(irq, @@ -2991,11 +2997,15 @@ if (err) goto err_out_w_lock; - igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx); + err = igb_update_ethtool_nfc_entry(adapter, input, input->sw_idx); + if (err) + goto err_out_input_filter; spin_unlock(&adapter->nfc_lock); return 0; +err_out_input_filter: + igb_erase_filter(adapter, input); err_out_w_lock: spin_unlock(&adapter->nfc_lock); err_out: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/igb_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/igb_main.c @@ -674,6 +674,10 @@ dca_register_notify(&dca_notifier); #endif ret = pci_register_driver(&igb_driver); +#ifdef CONFIG_IGB_DCA + if (ret) + dca_unregister_notify(&dca_notifier); +#endif return ret; } @@ -940,6 +944,7 @@ **/ static int igb_request_msix(struct igb_adapter *adapter) { + unsigned int num_q_vectors = adapter->num_q_vectors; struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; @@ -948,7 +953,13 @@ if (err) goto err_out; - for (i = 0; i < adapter->num_q_vectors; i++) { + if (num_q_vectors > MAX_Q_VECTORS) { + num_q_vectors = MAX_Q_VECTORS; + dev_warn(&adapter->pdev->dev, + "The number of queue vectors (%d) is higher than max allowed (%d)\n", + adapter->num_q_vectors, MAX_Q_VECTORS); + } + for (i = 0; i < num_q_vectors; i++) { struct igb_q_vector *q_vector = adapter->q_vector[i]; vector++; @@ -1206,8 +1217,12 @@ if (!q_vector) { q_vector = kzalloc(size, GFP_KERNEL); } else if (size > ksize(q_vector)) { - kfree_rcu(q_vector, rcu); - q_vector = kzalloc(size, GFP_KERNEL); + struct igb_q_vector *new_q_vector; + + new_q_vector = kzalloc(size, GFP_KERNEL); + if (new_q_vector) + kfree_rcu(q_vector, rcu); + q_vector = new_q_vector; } else { memset(q_vector, 0, size); } @@ -1687,14 +1702,15 @@ **/ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) { - struct igb_ring *ring = adapter->tx_ring[queue]; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; + struct igb_ring *ring; u32 tqavcc, tqavctrl; u16 value; WARN_ON(hw->mac.type != e1000_i210); WARN_ON(queue < 0 || queue > 1); + ring = adapter->tx_ring[queue]; /* If any of the Qav features is enabled, configure queues as SR and * with HIGH PRIO. If none is, then configure them with LOW PRIO and @@ -2651,7 +2667,8 @@ } input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI; - input->filter.vlan_tci = match.key->vlan_priority; + input->filter.vlan_tci = + (__force __be16)match.key->vlan_priority; } } @@ -3468,6 +3485,7 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: @@ -3481,6 +3499,7 @@ struct net_device *netdev = pci_get_drvdata(pdev); struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + unsigned long flags; /* reclaim resources allocated to VFs */ if (adapter->vf_data) { @@ -3493,12 +3512,13 @@ pci_disable_sriov(pdev); msleep(500); } - + spin_lock_irqsave(&adapter->vfs_lock, flags); kfree(adapter->vf_mac_list); adapter->vf_mac_list = NULL; kfree(adapter->vf_data); adapter->vf_data = NULL; adapter->vfs_allocated_count = 0; + spin_unlock_irqrestore(&adapter->vfs_lock, flags); wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); wrfl(); msleep(100); @@ -3694,8 +3714,9 @@ struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; - /* Virtualization features not supported on i210 family. */ - if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) + /* Virtualization features not supported on i210 and 82580 family. */ + if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211) || + (hw->mac.type == e1000_82580)) return; /* Of the below we really only want the effect of getting @@ -3819,6 +3840,9 @@ spin_lock_init(&adapter->nfc_lock); spin_lock_init(&adapter->stats64_lock); + + /* init spinlock to avoid concurrency of VF resources */ + spin_lock_init(&adapter->vfs_lock); #ifdef CONFIG_PCI_IOV switch (hw->mac.type) { case e1000_82576: @@ -4326,8 +4350,7 @@ else mrqc |= E1000_MRQC_ENABLE_VMDQ; } else { - if (hw->mac.type != e1000_i211) - mrqc |= E1000_MRQC_ENABLE_RSS_MQ; + mrqc |= E1000_MRQC_ENABLE_RSS_MQ; } igb_vmm_control(adapter); @@ -4534,6 +4557,10 @@ static void igb_set_rx_buffer_len(struct igb_adapter *adapter, struct igb_ring *rx_ring) { +#if (PAGE_SIZE < 8192) + struct e1000_hw *hw = &adapter->hw; +#endif + /* set build_skb and buffer size flags */ clear_ring_build_skb_enabled(rx_ring); clear_ring_uses_large_buffer(rx_ring); @@ -4544,10 +4571,9 @@ set_ring_build_skb_enabled(rx_ring); #if (PAGE_SIZE < 8192) - if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB) - return; - - set_ring_uses_large_buffer(rx_ring); + if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB || + rd32(E1000_RCTL) & E1000_RCTL_SBP) + set_ring_uses_large_buffer(rx_ring); #endif } @@ -4657,6 +4683,8 @@ DMA_TO_DEVICE); } + tx_buffer->next_to_watch = NULL; + /* move us one more past the eop_desc for start of next pkt */ tx_buffer++; i++; @@ -5307,7 +5335,8 @@ break; } - if (adapter->link_speed != SPEED_1000) + if (adapter->link_speed != SPEED_1000 || + !hw->phy.ops.read_reg) goto no_wait; /* wait for Remote receiver status OK */ @@ -6194,9 +6223,18 @@ struct igb_adapter *adapter; adapter = container_of(work, struct igb_adapter, reset_task); + rtnl_lock(); + /* If we're already down or resetting, just bail */ + if (test_bit(__IGB_DOWN, &adapter->state) || + test_bit(__IGB_RESETTING, &adapter->state)) { + rtnl_unlock(); + return; + } + igb_dump(adapter); netdev_err(adapter->netdev, "Reset adapter\n"); igb_reinit_locked(adapter); + rtnl_unlock(); } /** @@ -6445,77 +6483,85 @@ } } +static void igb_perout(struct igb_adapter *adapter, int tsintr_tt) +{ + int pin = ptp_find_pin(adapter->ptp_clock, PTP_PF_PEROUT, tsintr_tt); + struct e1000_hw *hw = &adapter->hw; + struct timespec64 ts; + u32 tsauxc; + + if (pin < 0 || pin >= IGB_N_PEROUT) + return; + + spin_lock(&adapter->tmreg_lock); + ts = timespec64_add(adapter->perout[pin].start, + adapter->perout[pin].period); + /* u32 conversion of tv_sec is safe until y2106 */ + wr32((tsintr_tt == 1) ? E1000_TRGTTIML1 : E1000_TRGTTIML0, ts.tv_nsec); + wr32((tsintr_tt == 1) ? E1000_TRGTTIMH1 : E1000_TRGTTIMH0, (u32)ts.tv_sec); + tsauxc = rd32(E1000_TSAUXC); + tsauxc |= TSAUXC_EN_TT0; + wr32(E1000_TSAUXC, tsauxc); + adapter->perout[pin].start = ts; + spin_unlock(&adapter->tmreg_lock); +} + +static void igb_extts(struct igb_adapter *adapter, int tsintr_tt) +{ + int pin = ptp_find_pin(adapter->ptp_clock, PTP_PF_EXTTS, tsintr_tt); + struct e1000_hw *hw = &adapter->hw; + struct ptp_clock_event event; + u32 sec, nsec; + + if (pin < 0 || pin >= IGB_N_EXTTS) + return; + + nsec = rd32((tsintr_tt == 1) ? E1000_AUXSTMPL1 : E1000_AUXSTMPL0); + sec = rd32((tsintr_tt == 1) ? E1000_AUXSTMPH1 : E1000_AUXSTMPH0); + event.type = PTP_CLOCK_EXTTS; + event.index = tsintr_tt; + event.timestamp = sec * 1000000000ULL + nsec; + ptp_clock_event(adapter->ptp_clock, &event); +} + static void igb_tsync_interrupt(struct igb_adapter *adapter) { + const u32 mask = (TSINTR_SYS_WRAP | E1000_TSICR_TXTS | + TSINTR_TT0 | TSINTR_TT1 | + TSINTR_AUTT0 | TSINTR_AUTT1); struct e1000_hw *hw = &adapter->hw; + u32 tsicr = rd32(E1000_TSICR); struct ptp_clock_event event; - struct timespec64 ts; - u32 ack = 0, tsauxc, sec, nsec, tsicr = rd32(E1000_TSICR); + + if (hw->mac.type == e1000_82580) { + /* 82580 has a hardware bug that requires an explicit + * write to clear the TimeSync interrupt cause. + */ + wr32(E1000_TSICR, tsicr & mask); + } if (tsicr & TSINTR_SYS_WRAP) { event.type = PTP_CLOCK_PPS; if (adapter->ptp_caps.pps) ptp_clock_event(adapter->ptp_clock, &event); - ack |= TSINTR_SYS_WRAP; } if (tsicr & E1000_TSICR_TXTS) { /* retrieve hardware timestamp */ schedule_work(&adapter->ptp_tx_work); - ack |= E1000_TSICR_TXTS; } - if (tsicr & TSINTR_TT0) { - spin_lock(&adapter->tmreg_lock); - ts = timespec64_add(adapter->perout[0].start, - adapter->perout[0].period); - /* u32 conversion of tv_sec is safe until y2106 */ - wr32(E1000_TRGTTIML0, ts.tv_nsec); - wr32(E1000_TRGTTIMH0, (u32)ts.tv_sec); - tsauxc = rd32(E1000_TSAUXC); - tsauxc |= TSAUXC_EN_TT0; - wr32(E1000_TSAUXC, tsauxc); - adapter->perout[0].start = ts; - spin_unlock(&adapter->tmreg_lock); - ack |= TSINTR_TT0; - } - - if (tsicr & TSINTR_TT1) { - spin_lock(&adapter->tmreg_lock); - ts = timespec64_add(adapter->perout[1].start, - adapter->perout[1].period); - wr32(E1000_TRGTTIML1, ts.tv_nsec); - wr32(E1000_TRGTTIMH1, (u32)ts.tv_sec); - tsauxc = rd32(E1000_TSAUXC); - tsauxc |= TSAUXC_EN_TT1; - wr32(E1000_TSAUXC, tsauxc); - adapter->perout[1].start = ts; - spin_unlock(&adapter->tmreg_lock); - ack |= TSINTR_TT1; - } - - if (tsicr & TSINTR_AUTT0) { - nsec = rd32(E1000_AUXSTMPL0); - sec = rd32(E1000_AUXSTMPH0); - event.type = PTP_CLOCK_EXTTS; - event.index = 0; - event.timestamp = sec * 1000000000ULL + nsec; - ptp_clock_event(adapter->ptp_clock, &event); - ack |= TSINTR_AUTT0; - } - - if (tsicr & TSINTR_AUTT1) { - nsec = rd32(E1000_AUXSTMPL1); - sec = rd32(E1000_AUXSTMPH1); - event.type = PTP_CLOCK_EXTTS; - event.index = 1; - event.timestamp = sec * 1000000000ULL + nsec; - ptp_clock_event(adapter->ptp_clock, &event); - ack |= TSINTR_AUTT1; - } + if (tsicr & TSINTR_TT0) + igb_perout(adapter, 0); - /* acknowledge the interrupts */ - wr32(E1000_TSICR, ack); + if (tsicr & TSINTR_TT1) + igb_perout(adapter, 1); + + if (tsicr & TSINTR_AUTT0) + igb_extts(adapter, 0); + + if (tsicr & TSINTR_AUTT1) + igb_extts(adapter, 1); } static irqreturn_t igb_msix_other(int irq, void *data) @@ -7105,7 +7151,7 @@ { struct e1000_hw *hw = &adapter->hw; unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; - u32 reg, msgbuf[3]; + u32 reg, msgbuf[3] = {}; u8 *addr = (u8 *)(&msgbuf[1]); /* process all the same items cleared in a function level reset */ @@ -7354,6 +7400,20 @@ struct vf_mac_filter *entry = NULL; int ret = 0; + if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) && + !vf_data->trusted) { + dev_warn(&pdev->dev, + "VF %d requested MAC filter but is administratively denied\n", + vf); + return -EINVAL; + } + if (!is_valid_ether_addr(addr)) { + dev_warn(&pdev->dev, + "VF %d attempted to set invalid MAC filter\n", + vf); + return -EINVAL; + } + switch (info) { case E1000_VF_MAC_FILTER_CLR: /* remove all unicast MAC filters related to the current VF */ @@ -7367,20 +7427,6 @@ } break; case E1000_VF_MAC_FILTER_ADD: - if ((vf_data->flags & IGB_VF_FLAG_PF_SET_MAC) && - !vf_data->trusted) { - dev_warn(&pdev->dev, - "VF %d requested MAC filter but is administratively denied\n", - vf); - return -EINVAL; - } - if (!is_valid_ether_addr(addr)) { - dev_warn(&pdev->dev, - "VF %d attempted to set invalid MAC filter\n", - vf); - return -EINVAL; - } - /* try to find empty slot in the list */ list_for_each(pos, &adapter->vf_macs.l) { entry = list_entry(pos, struct vf_mac_filter, l); @@ -7548,8 +7594,10 @@ static void igb_msg_task(struct igb_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; + unsigned long flags; u32 vf; + spin_lock_irqsave(&adapter->vfs_lock, flags); for (vf = 0; vf < adapter->vfs_allocated_count; vf++) { /* process any reset requests */ if (!igb_check_for_rst(hw, vf)) @@ -7563,6 +7611,7 @@ if (!igb_check_for_ack(hw, vf)) igb_rcv_ack_from_vf(adapter, vf); } + spin_unlock_irqrestore(&adapter->vfs_lock, flags); } /** @@ -7732,7 +7781,7 @@ if (likely(napi_complete_done(napi, work_done))) igb_ring_irq_enable(q_vector); - return min(work_done, budget - 1); + return work_done; } /** @@ -8247,7 +8296,7 @@ if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) && test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags)) - vid = be16_to_cpu(rx_desc->wb.upper.vlan); + vid = be16_to_cpu((__force __be16)rx_desc->wb.upper.vlan); else vid = le16_to_cpu(rx_desc->wb.upper.vlan); @@ -8995,6 +9044,11 @@ struct net_device *netdev = pci_get_drvdata(pdev); struct igb_adapter *adapter = netdev_priv(netdev); + if (state == pci_channel_io_normal) { + dev_warn(&pdev->dev, "Non-correctable non-fatal error reported.\n"); + return PCI_ERS_RESULT_CAN_RECOVER; + } + netif_device_detach(netdev); if (state == pci_channel_io_perm_failure) @@ -9061,6 +9115,10 @@ struct igb_adapter *adapter = netdev_priv(netdev); if (netif_running(netdev)) { + if (!test_bit(__IGB_DOWN, &adapter->state)) { + dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n"); + return; + } if (igb_up(adapter)) { dev_err(&pdev->dev, "igb_up failed after reset\n"); return; @@ -9383,11 +9441,10 @@ struct e1000_hw *hw = &adapter->hw; u32 dmac_thr; u16 hwm; + u32 reg; if (hw->mac.type > e1000_82580) { if (adapter->flags & IGB_FLAG_DMAC) { - u32 reg; - /* force threshold to 0. */ wr32(E1000_DMCTXTH, 0); @@ -9420,7 +9477,6 @@ /* Disable BMC-to-OS Watchdog Enable */ if (hw->mac.type != e1000_i354) reg &= ~E1000_DMACR_DC_BMC2OSW_EN; - wr32(E1000_DMACR, reg); /* no lower threshold to disable @@ -9437,12 +9493,12 @@ */ wr32(E1000_DMCTXTH, (IGB_MIN_TXPBSIZE - (IGB_TX_BUF_4096 + adapter->max_frame_size)) >> 6); + } - /* make low power state decision controlled - * by DMA coal - */ + if (hw->mac.type >= e1000_i210 || + (adapter->flags & IGB_FLAG_DMAC)) { reg = rd32(E1000_PCIEMISC); - reg &= ~E1000_PCIEMISC_LX_DECISION; + reg |= E1000_PCIEMISC_LX_DECISION; wr32(E1000_PCIEMISC, reg); } /* endif adapter->dmac is not disabled */ } else if (hw->mac.type == e1000_82580) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igb/igb_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igb/igb_ptp.c @@ -1245,18 +1245,6 @@ return; } - spin_lock_init(&adapter->tmreg_lock); - INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work); - - if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) - INIT_DELAYED_WORK(&adapter->ptp_overflow_work, - igb_ptp_overflow_check); - - adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; - adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; - - igb_ptp_reset(adapter); - adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps, &adapter->pdev->dev); if (IS_ERR(adapter->ptp_clock)) { @@ -1266,6 +1254,18 @@ dev_info(&adapter->pdev->dev, "added PHC on %s\n", adapter->netdev->name); adapter->ptp_flags |= IGB_PTP_ENABLED; + + spin_lock_init(&adapter->tmreg_lock); + INIT_WORK(&adapter->ptp_tx_work, igb_ptp_tx_work); + + if (adapter->ptp_flags & IGB_PTP_OVERFLOW_CHECK) + INIT_DELAYED_WORK(&adapter->ptp_overflow_work, + igb_ptp_overflow_check); + + adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; + adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF; + + igb_ptp_reset(adapter); } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igbvf/igbvf.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igbvf/igbvf.h @@ -39,11 +39,11 @@ /* Tx/Rx descriptor defines */ #define IGBVF_DEFAULT_TXD 256 #define IGBVF_MAX_TXD 4096 -#define IGBVF_MIN_TXD 80 +#define IGBVF_MIN_TXD 64 #define IGBVF_DEFAULT_RXD 256 #define IGBVF_MAX_RXD 4096 -#define IGBVF_MIN_RXD 80 +#define IGBVF_MIN_RXD 64 #define IGBVF_MIN_ITR_USECS 10 /* 100000 irq/sec */ #define IGBVF_MAX_ITR_USECS 10000 /* 100 irq/sec */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igbvf/netdev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igbvf/netdev.c @@ -83,14 +83,14 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, struct net_device *netdev, struct sk_buff *skb, - u32 status, u16 vlan) + u32 status, __le16 vlan) { u16 vid; if (status & E1000_RXD_STAT_VP) { if ((adapter->flags & IGBVF_FLAG_RX_LB_VLAN_BSWAP) && (status & E1000_RXDEXT_STATERR_LB)) - vid = be16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + vid = be16_to_cpu((__force __be16)vlan) & E1000_RXD_SPC_VLAN_MASK; else vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; if (test_bit(vid, adapter->active_vlans)) @@ -1070,7 +1070,7 @@ igbvf_intr_msix_rx, 0, adapter->rx_ring->name, netdev); if (err) - goto out; + goto free_irq_tx; adapter->rx_ring->itr_register = E1000_EITR(vector); adapter->rx_ring->itr_val = adapter->current_itr; @@ -1079,10 +1079,14 @@ err = request_irq(adapter->msix_entries[vector].vector, igbvf_msix_other, 0, netdev->name, netdev); if (err) - goto out; + goto free_irq_rx; igbvf_configure_msix(adapter); return 0; +free_irq_rx: + free_irq(adapter->msix_entries[--vector].vector, netdev); +free_irq_tx: + free_irq(adapter->msix_entries[--vector].vector, netdev); out: return err; } @@ -2887,6 +2891,7 @@ return 0; err_hw_init: + netif_napi_del(&adapter->rx_ring->napi); kfree(adapter->tx_ring); kfree(adapter->rx_ring); err_sw_init: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igbvf/vf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igbvf/vf.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright(c) 2009 - 2018 Intel Corporation. */ +#include + #include "vf.h" static s32 e1000_check_for_link_vf(struct e1000_hw *hw); @@ -131,11 +133,16 @@ /* set our "perm_addr" based on info provided by PF */ ret_val = mbx->ops.read_posted(hw, msgbuf, 3); if (!ret_val) { - if (msgbuf[0] == (E1000_VF_RESET | - E1000_VT_MSGTYPE_ACK)) + switch (msgbuf[0]) { + case E1000_VF_RESET | E1000_VT_MSGTYPE_ACK: memcpy(hw->mac.perm_addr, addr, ETH_ALEN); - else + break; + case E1000_VF_RESET | E1000_VT_MSGTYPE_NACK: + eth_zero_addr(hw->mac.perm_addr); + break; + default: ret_val = -E1000_ERR_MAC_INIT; + } } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc.h @@ -78,11 +78,11 @@ /* TX/RX descriptor defines */ #define IGC_DEFAULT_TXD 256 #define IGC_DEFAULT_TX_WORK 128 -#define IGC_MIN_TXD 80 +#define IGC_MIN_TXD 64 #define IGC_MAX_TXD 4096 #define IGC_DEFAULT_RXD 256 -#define IGC_MIN_RXD 80 +#define IGC_MIN_RXD 64 #define IGC_MAX_RXD 4096 /* Transmit and receive queues */ @@ -504,7 +504,7 @@ if (hw->phy.ops.read_reg) return hw->phy.ops.read_reg(hw, offset, data); - return 0; + return -EOPNOTSUPP; } /* forward declaration */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_base.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_base.c @@ -187,15 +187,7 @@ igc_check_for_copper_link(hw); - /* Verify phy id and set remaining function pointers */ - switch (phy->id) { - case I225_I_PHY_ID: - phy->type = igc_phy_i225; - break; - default: - ret_val = -IGC_ERR_PHY; - goto out; - } + phy->type = igc_phy_i225; out: return ret_val; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_defines.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_defines.h @@ -360,6 +360,7 @@ /* PHY Status Register */ #define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ #define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define IGC_PHY_RST_COMP 0x0100 /* Internal PHY reset completion */ /* PHY 1000 MII Register/Bit Definitions */ /* PHY Registers defined by IEEE */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1668,14 +1668,22 @@ /* twisted pair */ cmd->base.port = PORT_TP; cmd->base.phy_address = hw->phy.addr; + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); /* advertising link modes */ - ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full); - ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); + if (hw->phy.autoneg_advertised & ADVERTISE_10_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_100_HALF) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half); + if (hw->phy.autoneg_advertised & ADVERTISE_100_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_1000_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full); + if (hw->phy.autoneg_advertised & ADVERTISE_2500_FULL) + ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full); /* set autoneg settings */ if (hw->mac.autoneg == 1) { @@ -1684,6 +1692,9 @@ Autoneg); } + /* Set pause flow control settings */ + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); + switch (hw->fc.requested_mode) { case igc_fc_full: ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); @@ -1698,12 +1709,11 @@ Asym_Pause); break; default: - ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); - ethtool_link_ksettings_add_link_mode(cmd, advertising, - Asym_Pause); + break; } - status = rd32(IGC_STATUS); + status = pm_runtime_suspended(&adapter->pdev->dev) ? + 0 : rd32(IGC_STATUS); if (status & IGC_STATUS_LU) { if (status & IGC_STATUS_SPEED_1000) { @@ -1758,7 +1768,7 @@ { struct igc_adapter *adapter = netdev_priv(netdev); struct igc_hw *hw = &adapter->hw; - u32 advertising; + u16 advertised = 0; /* When adapter in resetting mode, autoneg/speed/duplex * cannot be changed @@ -1784,12 +1794,33 @@ while (test_and_set_bit(__IGC_RESETTING, &adapter->state)) usleep_range(1000, 2000); - ethtool_convert_link_mode_to_legacy_u32(&advertising, - cmd->link_modes.advertising); + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 2500baseT_Full)) + advertised |= ADVERTISE_2500_FULL; + + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 1000baseT_Full)) + advertised |= ADVERTISE_1000_FULL; + + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 100baseT_Full)) + advertised |= ADVERTISE_100_FULL; + + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 100baseT_Half)) + advertised |= ADVERTISE_100_HALF; + + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 10baseT_Full)) + advertised |= ADVERTISE_10_FULL; + + if (ethtool_link_ksettings_test_link_mode(cmd, advertising, + 10baseT_Half)) + advertised |= ADVERTISE_10_HALF; if (cmd->base.autoneg == AUTONEG_ENABLE) { hw->mac.autoneg = 1; - hw->phy.autoneg_advertised = advertising; + hw->phy.autoneg_advertised = advertised; if (adapter->fc_autoneg) hw->fc.requested_mode = igc_fc_default; } else { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_i225.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_i225.c @@ -156,8 +156,15 @@ { u32 swfw_sync; - while (igc_get_hw_semaphore_i225(hw)) - ; /* Empty */ + /* Releasing the resource requires first getting the HW semaphore. + * If we fail to get the semaphore, there is nothing we can do, + * except log an error and quit. We are not allowed to hang here + * indefinitely, as it may cause denial of service or system crash. + */ + if (igc_get_hw_semaphore_i225(hw)) { + hw_dbg("Failed to release SW_FW_SYNC.\n"); + return; + } swfw_sync = rd32(IGC_SW_FW_SYNC); swfw_sync &= ~mask; @@ -219,9 +226,9 @@ u16 *data) { struct igc_nvm_info *nvm = &hw->nvm; + s32 ret_val = -IGC_ERR_NVM; u32 attempts = 100000; u32 i, k, eewr = 0; - s32 ret_val = 0; /* A check for invalid values: offset too large, too many words, * too many words for the offset, and not enough words. @@ -229,7 +236,6 @@ if (offset >= nvm->word_size || (words > (nvm->word_size - offset)) || words == 0) { hw_dbg("nvm parameter(s) out of bounds\n"); - ret_val = -IGC_ERR_NVM; goto out; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_mac.c @@ -647,7 +647,7 @@ } out: - return 0; + return ret_val; } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_main.c @@ -256,6 +256,8 @@ DMA_TO_DEVICE); } + tx_buffer->next_to_watch = NULL; + /* move us one more past the eop_desc for start of next pkt */ tx_buffer++; i++; @@ -608,7 +610,6 @@ /* disable the queue */ wr32(IGC_TXDCTL(reg_idx), 0); wrfl(); - mdelay(10); wr32(IGC_TDLEN(reg_idx), ring->count * sizeof(union igc_adv_tx_desc)); @@ -2222,21 +2223,23 @@ } /** - * igc_get_stats - Get System Network Statistics + * igc_get_stats64 - Get System Network Statistics * @netdev: network interface device structure + * @stats: rtnl_link_stats64 pointer * * Returns the address of the device statistics structure. * The statistics are updated here and also from the timer callback. */ -static struct net_device_stats *igc_get_stats(struct net_device *netdev) +static void igc_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { struct igc_adapter *adapter = netdev_priv(netdev); + spin_lock(&adapter->stats64_lock); if (!test_bit(__IGC_RESETTING, &adapter->state)) igc_update_stats(adapter); - - /* only return the current stats */ - return &netdev->stats; + memcpy(stats, &adapter->stats64, sizeof(*stats)); + spin_unlock(&adapter->stats64_lock); } static netdev_features_t igc_fix_features(struct net_device *netdev, @@ -2689,6 +2692,7 @@ */ static int igc_request_msix(struct igc_adapter *adapter) { + unsigned int num_q_vectors = adapter->num_q_vectors; int i = 0, err = 0, vector = 0, free_vector = 0; struct net_device *netdev = adapter->netdev; @@ -2697,7 +2701,13 @@ if (err) goto err_out; - for (i = 0; i < adapter->num_q_vectors; i++) { + if (num_q_vectors > MAX_Q_VECTORS) { + num_q_vectors = MAX_Q_VECTORS; + dev_warn(&adapter->pdev->dev, + "The number of queue vectors (%d) is higher than max allowed (%d)\n", + adapter->num_q_vectors, MAX_Q_VECTORS); + } + for (i = 0; i < num_q_vectors; i++) { struct igc_q_vector *q_vector = adapter->q_vector[i]; vector++; @@ -2873,8 +2883,7 @@ break; } - if (hw->mac.type == igc_i225 && - hw->phy.id == I225_I_PHY_ID) { + if (hw->mac.type == igc_i225) { if (!netif_carrier_ok(adapter->netdev)) { adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE; } else if (!(adapter->flags & IGC_FLAG_NEED_LINK_UPDATE)) { @@ -3984,7 +3993,7 @@ .ndo_start_xmit = igc_xmit_frame, .ndo_set_mac_address = igc_set_mac, .ndo_change_mtu = igc_change_mtu, - .ndo_get_stats = igc_get_stats, + .ndo_get_stats64 = igc_get_stats64, .ndo_fix_features = igc_fix_features, .ndo_set_features = igc_set_features, .ndo_features_check = igc_features_check, @@ -4308,8 +4317,8 @@ err_ioremap: free_netdev(netdev); err_alloc_etherdev: - pci_release_selected_regions(pdev, - pci_select_bars(pdev, IORESOURCE_MEM)); + pci_disable_pcie_error_reporting(pdev); + pci_release_mem_regions(pdev); err_pci_reg: err_dma: pci_disable_device(pdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_phy.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_phy.c @@ -173,6 +173,7 @@ s32 igc_phy_hw_reset(struct igc_hw *hw) { struct igc_phy_info *phy = &hw->phy; + u32 phpm = 0, timeout = 10000; s32 ret_val; u32 ctrl; @@ -186,6 +187,8 @@ if (ret_val) goto out; + phpm = rd32(IGC_I225_PHPM); + ctrl = rd32(IGC_CTRL); wr32(IGC_CTRL, ctrl | IGC_CTRL_PHY_RST); wrfl(); @@ -195,7 +198,18 @@ wr32(IGC_CTRL, ctrl); wrfl(); - usleep_range(1500, 2000); + /* SW should guarantee 100us for the completion of the PHY reset */ + usleep_range(100, 150); + do { + phpm = rd32(IGC_I225_PHPM); + timeout--; + udelay(1); + } while (!(phpm & IGC_PHY_RST_COMP) && timeout); + + if (!timeout) + hw_dbg("Timeout is expired after a phy reset\n"); + + usleep_range(100, 150); phy->ops.release(hw); @@ -235,8 +249,7 @@ return ret_val; } - if ((phy->autoneg_mask & ADVERTISE_2500_FULL) && - hw->phy.id == I225_I_PHY_ID) { + if (phy->autoneg_mask & ADVERTISE_2500_FULL) { /* Read the MULTI GBT AN Control Register - reg 7.32 */ ret_val = phy->ops.read_reg(hw, (STANDARD_AN_REG_MASK << MMD_DEVADDR_SHIFT) | @@ -376,8 +389,7 @@ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); - if ((phy->autoneg_mask & ADVERTISE_2500_FULL) && - hw->phy.id == I225_I_PHY_ID) + if (phy->autoneg_mask & ADVERTISE_2500_FULL) ret_val = phy->ops.write_reg(hw, (STANDARD_AN_REG_MASK << MMD_DEVADDR_SHIFT) | @@ -569,7 +581,7 @@ * the lower time out */ for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) { - usleep_range(500, 1000); + udelay(50); mdic = rd32(IGC_MDIC); if (mdic & IGC_MDIC_READY) break; @@ -626,7 +638,7 @@ * the lower time out */ for (i = 0; i < IGC_GEN_POLL_TIMEOUT; i++) { - usleep_range(500, 1000); + udelay(50); mdic = rd32(IGC_MDIC); if (mdic & IGC_MDIC_READY) break; @@ -734,8 +746,6 @@ if (ret_val) return ret_val; ret_val = igc_write_phy_reg_mdic(hw, offset, data); - if (ret_val) - return ret_val; hw->phy.ops.release(hw); } else { ret_val = igc_write_xmdio_reg(hw, (u16)offset, dev_addr, @@ -767,8 +777,6 @@ if (ret_val) return ret_val; ret_val = igc_read_phy_reg_mdic(hw, offset, data); - if (ret_val) - return ret_val; hw->phy.ops.release(hw); } else { ret_val = igc_read_xmdio_reg(hw, (u16)offset, dev_addr, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/igc/igc_regs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/igc/igc_regs.h @@ -12,6 +12,7 @@ #define IGC_MDIC 0x00020 /* MDI Control - RW */ #define IGC_MDICNFG 0x00E04 /* MDC/MDIO Configuration - RW */ #define IGC_CONNSW 0x00034 /* Copper/Fiber switch control - RW */ +#define IGC_I225_PHPM 0x00E14 /* I225 PHY Power Management */ /* Internal Packet Buffer Size Registers */ #define IGC_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ @@ -236,4 +237,6 @@ #define array_rd32(reg, offset) (igc_rd32(hw, (reg) + ((offset) << 2))) +#define IGC_REMOVED(h) unlikely(!(h)) + #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -67,6 +67,8 @@ #define IXGBE_RXBUFFER_4K 4096 #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ +#define IXGBE_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2)) + /* Attempt to maximize the headroom available for incoming frames. We * use a 2K buffer for receives and need 1536/1534 to store the data for * the frame. This leaves us with 512 bytes of room. From that we need @@ -177,11 +179,14 @@ u16 pf_vlan; /* When set, guest VLAN config not allowed. */ u16 pf_qos; u16 tx_rate; + int link_enable; + int link_state; u8 spoofchk_enabled; bool rss_query_enabled; u8 trusted; int xcast_mode; unsigned int vf_api; + u8 primary_abort_count; }; enum ixgbevf_xcast_modes { @@ -553,6 +558,8 @@ #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ) #define IXGBE_SFP_POLL_JIFFIES (2 * HZ) /* SFP poll every 2 seconds */ +#define IXGBE_PRIMARY_ABORT_LIMIT 5 + /* board specific private data structure */ struct ixgbe_adapter { unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; @@ -614,6 +621,7 @@ #define IXGBE_FLAG2_RX_LEGACY BIT(16) #define IXGBE_FLAG2_IPSEC_ENABLED BIT(17) #define IXGBE_FLAG2_VF_IPSEC_ENABLED BIT(18) +#define IXGBE_FLAG2_AUTO_DISABLE_VF BIT(19) /* Tx fast path data */ int num_tx_queues; @@ -773,6 +781,7 @@ #ifdef CONFIG_IXGBE_IPSEC struct ixgbe_ipsec *ipsec; #endif /* CONFIG_IXGBE_IPSEC */ + spinlock_t vfs_lock; }; static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c @@ -123,14 +123,14 @@ if (ret_val) return ret_val; if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; /* Check to see if SFP+ module is supported */ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, &data_offset); if (ret_val) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; break; default: break; @@ -213,7 +213,7 @@ break; default: - return IXGBE_ERR_LINK_SETUP; + return -EIO; } return 0; @@ -283,7 +283,7 @@ /* Validate the water mark configuration */ if (!hw->fc.pause_time) - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; /* Low water mark of zero causes XOFF floods */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { @@ -292,7 +292,7 @@ if (!hw->fc.low_water[i] || hw->fc.low_water[i] >= hw->fc.high_water[i]) { hw_dbg(hw, "Invalid water mark configuration\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } } } @@ -369,7 +369,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Set 802.3x based flow control settings. */ @@ -438,7 +438,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autonegotiation did not complete.\n"); } } @@ -478,7 +478,7 @@ if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { hw_dbg(hw, "Link was indicated but link is down\n"); - return IXGBE_ERR_LINK_SETUP; + return -EIO; } return 0; @@ -594,7 +594,7 @@ speed &= link_capabilities; if (speed == IXGBE_LINK_SPEED_UNKNOWN) - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; /* Set KX4/KX support according to speed requested */ else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || @@ -701,9 +701,9 @@ /* Init PHY and function pointers, perform SFP setup */ phy_status = hw->phy.ops.init(hw); - if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (phy_status == -EOPNOTSUPP) return phy_status; - if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) + if (phy_status == -ENOENT) goto mac_reset_top; hw->phy.ops.reset(hw); @@ -727,7 +727,7 @@ udelay(1); } if (ctrl & IXGBE_CTRL_RST) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -789,7 +789,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); @@ -814,7 +814,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); @@ -845,7 +845,7 @@ u32 vftabyte; if (vlan > 4095) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Determine 32-bit word position in array */ regindex = (vlan >> 5) & 0x7F; /* upper seven bits */ @@ -964,7 +964,7 @@ gssr = IXGBE_GSSR_PHY0_SM; if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; if (hw->phy.type == ixgbe_phy_nl) { /* @@ -993,7 +993,7 @@ if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { hw_dbg(hw, "EEPROM read did not pass.\n"); - status = IXGBE_ERR_SFP_NOT_PRESENT; + status = -ENOENT; goto out; } @@ -1003,7 +1003,7 @@ *eeprom_data = (u8)(sfp_data >> 8); } else { - status = IXGBE_ERR_PHY; + status = -EIO; } out: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -117,7 +117,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; if (hw->eeprom.ops.read(hw, ++data_offset, &data_value)) goto setup_sfp_err; @@ -144,7 +144,7 @@ if (ret_val) { hw_dbg(hw, " sfp module setup not complete\n"); - return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + return -EIO; } } @@ -159,7 +159,7 @@ usleep_range(hw->eeprom.semaphore_delay * 1000, hw->eeprom.semaphore_delay * 2000); hw_err(hw, "eeprom read at offset %d failed\n", data_offset); - return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + return -EIO; } /** @@ -184,7 +184,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; *locked = true; } @@ -219,7 +219,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; locked = true; } @@ -400,7 +400,7 @@ break; default: - return IXGBE_ERR_LINK_SETUP; + return -EIO; } if (hw->phy.multispeed_fiber) { @@ -541,7 +541,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autoneg did not complete.\n"); } } @@ -794,7 +794,7 @@ speed &= link_capabilities; if (speed == IXGBE_LINK_SPEED_UNKNOWN) - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ if (hw->mac.orig_link_settings_stored) @@ -861,8 +861,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = - IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autoneg did not complete.\n"); } } @@ -927,7 +926,7 @@ /* Identify PHY and related function pointers */ status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Setup SFP module if there is one present. */ @@ -936,7 +935,7 @@ hw->phy.sfp_setup_needed = false; } - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Reset PHY */ @@ -974,7 +973,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -1093,7 +1092,7 @@ udelay(10); } - return IXGBE_ERR_FDIR_CMD_INCOMPLETE; + return -EIO; } /** @@ -1155,7 +1154,7 @@ } if (i >= IXGBE_FDIR_INIT_DONE_POLL) { hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); - return IXGBE_ERR_FDIR_REINIT_FAILED; + return -EIO; } /* Clear FDIR statistics registers (read to clear) */ @@ -1387,7 +1386,7 @@ break; default: hw_dbg(hw, " Error on flow type input\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* configure FDIRCMD register */ @@ -1546,7 +1545,7 @@ break; default: hw_dbg(hw, " Error on vm pool mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) { @@ -1555,13 +1554,13 @@ if (input_mask->formatted.dst_port || input_mask->formatted.src_port) { hw_dbg(hw, " Error on src/dst port mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } case IXGBE_ATR_L4TYPE_MASK: break; default: hw_dbg(hw, " Error on flow type mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (ntohs(input_mask->formatted.vlan_id) & 0xEFFF) { @@ -1582,7 +1581,7 @@ break; default: hw_dbg(hw, " Error on VLAN mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch ((__force u16)input_mask->formatted.flex_bytes & 0xFFFF) { @@ -1594,7 +1593,7 @@ break; default: hw_dbg(hw, " Error on flexible byte mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ @@ -1823,7 +1822,7 @@ /* Return error if SFP module has been detected but is not supported */ if (hw->phy.type == ixgbe_phy_sfp_unsupported) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; return status; } @@ -1862,13 +1861,13 @@ * Verifies that installed the firmware version is 0.6 or higher * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. * - * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or - * if the FW version is not supported. + * Return: -EACCES if the FW is not present or if the FW version is + * not supported. **/ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) { - s32 status = IXGBE_ERR_EEPROM_VERSION; u16 fw_offset, fw_ptp_cfg_offset; + s32 status = -EACCES; u16 offset; u16 fw_version = 0; @@ -1882,7 +1881,7 @@ goto fw_version_err; if (fw_offset == 0 || fw_offset == 0xFFFF) - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; /* get the offset to the Pass Through Patch Configuration block */ offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR; @@ -1890,7 +1889,7 @@ goto fw_version_err; if (fw_ptp_cfg_offset == 0 || fw_ptp_cfg_offset == 0xFFFF) - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; /* get the firmware version */ offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4; @@ -1904,7 +1903,7 @@ fw_version_err: hw_err(hw, "eeprom read at offset %d failed\n", offset); - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; } /** @@ -2037,7 +2036,7 @@ if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) { hw_dbg(hw, "auto negotiation not completed\n"); - ret_val = IXGBE_ERR_RESET_FAILED; + ret_val = -EIO; goto reset_pipeline_out; } @@ -2086,7 +2085,7 @@ if (!timeout) { hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; goto release_i2c_access; } } @@ -2140,7 +2139,7 @@ if (!timeout) { hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; goto release_i2c_access; } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -30,7 +30,7 @@ u16 words, u16 *data); static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, u16 offset); -static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); +static s32 ixgbe_disable_pcie_primary(struct ixgbe_hw *hw); /* Base table for registers values that change by MAC */ const u32 ixgbe_mvals_8259X[IXGBE_MVALS_IDX_LIMIT] = { @@ -124,7 +124,7 @@ */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } /* @@ -215,7 +215,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } if (hw->mac.type != ixgbe_mac_X540) { @@ -500,7 +500,7 @@ if (pba_num == NULL) { hw_dbg(hw, "PBA string buffer was null\n"); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); @@ -526,7 +526,7 @@ /* we will need 11 characters to store the PBA */ if (pba_num_size < 11) { hw_dbg(hw, "PBA string buffer too small\n"); - return IXGBE_ERR_NO_SPACE; + return -ENOSPC; } /* extract hex string from data and pba_ptr */ @@ -563,13 +563,13 @@ if (length == 0xFFFF || length == 0) { hw_dbg(hw, "NVM PBA number section invalid length\n"); - return IXGBE_ERR_PBA_SECTION; + return -EIO; } /* check if pba_num buffer is big enough */ if (pba_num_size < (((u32)length * 2) - 1)) { hw_dbg(hw, "PBA string buffer too small\n"); - return IXGBE_ERR_NO_SPACE; + return -ENOSPC; } /* trim pba length from start of string */ @@ -746,10 +746,10 @@ usleep_range(1000, 2000); /* - * Prevent the PCI-E bus from from hanging by disabling PCI-E master + * Prevent the PCI-E bus from hanging by disabling PCI-E primary * access and verify no pending requests */ - return ixgbe_disable_pcie_master(hw); + return ixgbe_disable_pcie_primary(hw); } /** @@ -805,7 +805,7 @@ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); @@ -826,7 +826,7 @@ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn off the LED, set mode to OFF. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); @@ -904,11 +904,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset + words > hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || (offset + words > hw->eeprom.word_size)) + return -EINVAL; /* * The EEPROM page size cannot be queried from the chip. We do lazy @@ -962,7 +959,7 @@ if (ixgbe_ready_eeprom(hw) != 0) { ixgbe_release_eeprom(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } for (i = 0; i < words; i++) { @@ -1028,7 +1025,7 @@ hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + return -EINVAL; return ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data); } @@ -1050,11 +1047,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset + words > hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || (offset + words > hw->eeprom.word_size)) + return -EINVAL; /* * We cannot hold synchronization semaphores for too long @@ -1099,7 +1093,7 @@ if (ixgbe_ready_eeprom(hw) != 0) { ixgbe_release_eeprom(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } for (i = 0; i < words; i++) { @@ -1142,7 +1136,7 @@ hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + return -EINVAL; return ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); } @@ -1165,11 +1159,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || offset >= hw->eeprom.word_size) + return -EINVAL; for (i = 0; i < words; i++) { eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | @@ -1262,11 +1253,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || offset >= hw->eeprom.word_size) + return -EINVAL; for (i = 0; i < words; i++) { eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | @@ -1328,7 +1316,7 @@ } udelay(5); } - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -1344,7 +1332,7 @@ u32 i; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw)); @@ -1366,7 +1354,7 @@ hw_dbg(hw, "Could not acquire EEPROM grant\n"); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); - return IXGBE_ERR_EEPROM; + return -EIO; } /* Setup EEPROM for Read/Write */ @@ -1419,7 +1407,7 @@ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM(hw)); if (swsm & IXGBE_SWSM_SMBI) { hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } } @@ -1447,7 +1435,7 @@ if (i >= timeout) { hw_dbg(hw, "SWESMBI Software EEPROM semaphore not granted.\n"); ixgbe_release_eeprom_semaphore(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } return 0; @@ -1503,7 +1491,7 @@ */ if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { hw_dbg(hw, "SPI EEPROM Status error\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } return 0; @@ -1715,7 +1703,7 @@ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { if (hw->eeprom.ops.read(hw, i, &pointer)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } /* If the pointer seems invalid */ @@ -1724,7 +1712,7 @@ if (hw->eeprom.ops.read(hw, pointer, &length)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } if (length == 0xFFFF || length == 0) @@ -1733,7 +1721,7 @@ for (j = pointer + 1; j <= pointer + length; j++) { if (hw->eeprom.ops.read(hw, j, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -1786,7 +1774,7 @@ * calculated checksum */ if (read_checksum != checksum) - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; /* If the user cares, return the calculated checksum */ if (checksum_val) @@ -1845,7 +1833,7 @@ /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } /* setup VMDq pool selection before this RAR gets enabled */ @@ -1897,7 +1885,7 @@ /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } /* @@ -2146,7 +2134,7 @@ /* Validate the water mark configuration. */ if (!hw->fc.pause_time) - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; /* Low water mark of zero causes XOFF floods */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { @@ -2155,7 +2143,7 @@ if (!hw->fc.low_water[i] || hw->fc.low_water[i] >= hw->fc.high_water[i]) { hw_dbg(hw, "Invalid water mark configuration\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } } } @@ -2212,7 +2200,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Set 802.3x based flow control settings. */ @@ -2243,7 +2231,7 @@ } /* Configure pause time (2 TCs per register) */ - reg = hw->fc.pause_time * 0x00010001; + reg = hw->fc.pause_time * 0x00010001U; for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++) IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg); @@ -2269,7 +2257,7 @@ u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) { if ((!(adv_reg)) || (!(lp_reg))) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EINVAL; if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { /* @@ -2321,7 +2309,7 @@ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); @@ -2353,12 +2341,12 @@ */ links = IXGBE_READ_REG(hw, IXGBE_LINKS); if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; if (hw->mac.type == ixgbe_mac_82599EB) { links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; } /* * Read the 10g AN autoc and LP ability registers and resolve @@ -2407,8 +2395,8 @@ **/ void ixgbe_fc_autoneg(struct ixgbe_hw *hw) { - s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; + s32 ret_val = -EIO; bool link_up; /* @@ -2506,15 +2494,15 @@ } /** - * ixgbe_disable_pcie_master - Disable PCI-express master access + * ixgbe_disable_pcie_primary - Disable PCI-express primary access * @hw: pointer to hardware structure * - * Disables PCI-Express master access and verifies there are no pending - * requests. IXGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable - * bit hasn't caused the master requests to be disabled, else 0 - * is returned signifying master requests disabled. + * Disables PCI-Express primary access and verifies there are no pending + * requests. -EALREADY is returned if primary disable + * bit hasn't caused the primary requests to be disabled, else 0 + * is returned signifying primary requests disabled. **/ -static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) +static s32 ixgbe_disable_pcie_primary(struct ixgbe_hw *hw) { u32 i, poll; u16 value; @@ -2523,23 +2511,23 @@ IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); /* Poll for bit to read as set */ - for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { + for (i = 0; i < IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT; i++) { if (IXGBE_READ_REG(hw, IXGBE_CTRL) & IXGBE_CTRL_GIO_DIS) break; usleep_range(100, 120); } - if (i >= IXGBE_PCI_MASTER_DISABLE_TIMEOUT) { + if (i >= IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT) { hw_dbg(hw, "GIO disable did not set - requesting resets\n"); goto gio_disable_fail; } - /* Exit if master requests are blocked */ + /* Exit if primary requests are blocked */ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) || ixgbe_removed(hw->hw_addr)) return 0; - /* Poll for master request bit to clear */ - for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { + /* Poll for primary request bit to clear */ + for (i = 0; i < IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT; i++) { udelay(100); if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) return 0; @@ -2547,13 +2535,13 @@ /* * Two consecutive resets are required via CTRL.RST per datasheet - * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine - * of this need. The first reset prevents new master requests from + * 5.2.5.3.2 Primary Disable. We set a flag to inform the reset routine + * of this need. The first reset prevents new primary requests from * being issued by our device. We then must wait 1usec or more for any * remaining completions from the PCIe bus to trickle in, and then reset * again to clear out any effects they may have had on our device. */ - hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n"); + hw_dbg(hw, "GIO Primary Disable bit didn't clear - requesting resets\n"); gio_disable_fail: hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; @@ -2575,7 +2563,7 @@ } hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n"); - return IXGBE_ERR_MASTER_REQUESTS_PENDING; + return -EALREADY; } /** @@ -2600,7 +2588,7 @@ * SW_FW_SYNC bits (not just NVM) */ if (ixgbe_get_eeprom_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); if (!(gssr & (fwmask | swmask))) { @@ -2620,7 +2608,7 @@ ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); usleep_range(5000, 10000); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } /** @@ -2757,7 +2745,7 @@ s32 ret_val; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* * Link must be up to auto-blink the LEDs; @@ -2803,7 +2791,7 @@ s32 ret_val; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); if (ret_val) @@ -2963,7 +2951,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); @@ -3014,7 +3002,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } if (vmdq < 32) { @@ -3091,7 +3079,7 @@ * will simply bypass the VLVF if there are no entries present in the * VLVF that contain our VLAN */ - first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; + first_empty_slot = vlvf_bypass ? -ENOSPC : 0; /* add VLAN enable bit for comparison */ vlan |= IXGBE_VLVF_VIEN; @@ -3115,7 +3103,7 @@ if (!first_empty_slot) hw_dbg(hw, "No space in VLVF.\n"); - return first_empty_slot ? : IXGBE_ERR_NO_SPACE; + return first_empty_slot ? : -ENOSPC; } /** @@ -3135,7 +3123,7 @@ s32 vlvf_index; if ((vlan > 4095) || (vind > 63)) - return IXGBE_ERR_PARAM; + return -EINVAL; /* * this is a 2 part operation - first the VFTA, then the @@ -3596,7 +3584,8 @@ * * Communicates with the manageability block. On success return 0 * else returns semaphore error when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * semaphore, -EINVAL when incorrect parameters passed or -EIO when + * command fails. * * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held * by the caller. @@ -3609,7 +3598,7 @@ if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EINVAL; } /* Set bit 9 of FWSTS clearing FW reset indication */ @@ -3620,13 +3609,13 @@ hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if (!(hicr & IXGBE_HICR_EN)) { hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; } /* Calculate length in DWORDs. We must be DWORD aligned */ if (length % sizeof(u32)) { hw_dbg(hw, "Buffer length failure, not aligned to dword"); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } dword_len = length >> 2; @@ -3651,7 +3640,7 @@ /* Check command successful completion. */ if ((timeout && i == timeout) || !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; return 0; } @@ -3671,7 +3660,7 @@ * in these cases. * * Communicates with the manageability block. On success return 0 - * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. + * else return -EIO or -EINVAL. **/ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, u32 length, u32 timeout, @@ -3688,7 +3677,7 @@ if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EINVAL; } /* Take management host interface semaphore */ status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); @@ -3718,7 +3707,7 @@ if (length < round_up(buf_len, 4) + hdr_size) { hw_dbg(hw, "Buffer not large enough for reply message.\n"); - status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = -EIO; goto rel_out; } @@ -3749,8 +3738,8 @@ * * Sends driver version number to firmware through the manageability * block. On success return 0 - * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * else returns -EBUSY when encountering an error acquiring + * semaphore or -EIO when command fails. **/ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, u8 sub, __always_unused u16 len, @@ -3786,7 +3775,7 @@ FW_CEM_RESP_STATUS_SUCCESS) ret_val = 0; else - ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + ret_val = -EIO; break; } @@ -3884,14 +3873,14 @@ return status; if ((*ets_offset == 0x0000) || (*ets_offset == 0xFFFF)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = hw->eeprom.ops.read(hw, *ets_offset, ets_cfg); if (status) return status; if ((*ets_cfg & IXGBE_ETS_TYPE_MASK) != IXGBE_ETS_TYPE_EMC_SHIFTED) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; return 0; } @@ -3914,7 +3903,7 @@ /* Only support thermal sensors attached to physical port 0 */ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); if (status) @@ -3974,7 +3963,7 @@ /* Only support thermal sensors attached to physical port 0 */ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); if (status) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -138,6 +138,8 @@ "legacy-rx", #define IXGBE_PRIV_FLAGS_VF_IPSEC_EN BIT(1) "vf-ipsec", +#define IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF BIT(2) + "mdd-disable-vf", }; #define IXGBE_PRIV_FLAGS_STR_LEN ARRAY_SIZE(ixgbe_priv_flags_strings) @@ -2542,6 +2544,14 @@ return 0; } +static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) +{ + if (adapter->hw.mac.type < ixgbe_mac_X550) + return 16; + else + return 64; +} + static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, u32 *rule_locs) { @@ -2550,7 +2560,8 @@ switch (cmd->cmd) { case ETHTOOL_GRXRINGS: - cmd->data = adapter->num_rx_queues; + cmd->data = min_t(int, adapter->num_rx_queues, + ixgbe_rss_indir_tbl_max(adapter)); ret = 0; break; case ETHTOOL_GRXCLSRLCNT: @@ -2952,14 +2963,6 @@ return ret; } -static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter) -{ - if (adapter->hw.mac.type < ixgbe_mac_X550) - return 16; - else - return 64; -} - static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev) { return IXGBE_RSS_KEY_SIZE; @@ -3008,8 +3011,8 @@ int i; u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter); - if (hfunc) - return -EINVAL; + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; /* Fill out the redirection table */ if (indir) { @@ -3246,7 +3249,7 @@ { struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_hw *hw = &adapter->hw; - s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + s32 status = -EFAULT; u8 databyte = 0xFF; int i = 0; @@ -3416,6 +3419,9 @@ if (adapter->flags2 & IXGBE_FLAG2_VF_IPSEC_ENABLED) priv_flags |= IXGBE_PRIV_FLAGS_VF_IPSEC_EN; + if (adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) + priv_flags |= IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF; + return priv_flags; } @@ -3423,6 +3429,7 @@ { struct ixgbe_adapter *adapter = netdev_priv(netdev); unsigned int flags2 = adapter->flags2; + unsigned int i; flags2 &= ~IXGBE_FLAG2_RX_LEGACY; if (priv_flags & IXGBE_PRIV_FLAGS_LEGACY_RX) @@ -3432,6 +3439,21 @@ if (priv_flags & IXGBE_PRIV_FLAGS_VF_IPSEC_EN) flags2 |= IXGBE_FLAG2_VF_IPSEC_ENABLED; + flags2 &= ~IXGBE_FLAG2_AUTO_DISABLE_VF; + if (priv_flags & IXGBE_PRIV_FLAGS_AUTO_DISABLE_VF) { + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + /* Reset primary abort counter */ + for (i = 0; i < adapter->num_vfs; i++) + adapter->vfinfo[i].primary_abort_count = 0; + + flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF; + } else { + e_info(probe, + "Cannot set private flags: Operation not supported\n"); + return -EOPNOTSUPP; + } + } + if (flags2 != adapter->flags2) { adapter->flags2 = flags2; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -192,7 +192,7 @@ } /* alloc the udl from per cpu ddp pool */ - ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_KERNEL, &ddp->udp); + ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp); if (!ddp->udl) { e_err(drv, "failed allocated ddp context\n"); goto out_noddp_unmap; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -575,6 +575,11 @@ return -EINVAL; } + if (xs->props.mode != XFRM_MODE_TRANSPORT) { + netdev_err(dev, "Unsupported mode for ipsec offload\n"); + return -EINVAL; + } + if (ixgbe_ipsec_check_mgmt_ip(xs)) { netdev_err(dev, "IPsec IP addr clash with mgmt filters\n"); return -EINVAL; @@ -898,12 +903,19 @@ /* Tx IPsec offload doesn't seem to work on this * device, so block these requests for now. */ - if (!(sam->flags & XFRM_OFFLOAD_INBOUND)) { + sam->flags = sam->flags & ~XFRM_OFFLOAD_IPV6; + if (sam->flags != XFRM_OFFLOAD_INBOUND) { err = -EOPNOTSUPP; goto err_out; } - xs = kzalloc(sizeof(*xs), GFP_KERNEL); + algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1); + if (unlikely(!algo)) { + err = -ENOENT; + goto err_out; + } + + xs = kzalloc(sizeof(*xs), GFP_ATOMIC); if (unlikely(!xs)) { err = -ENOMEM; goto err_out; @@ -919,14 +931,8 @@ memcpy(&xs->id.daddr.a4, sam->addr, sizeof(xs->id.daddr.a4)); xs->xso.dev = adapter->netdev; - algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1); - if (unlikely(!algo)) { - err = -ENOENT; - goto err_xs; - } - aead_len = sizeof(*xs->aead) + IXGBE_IPSEC_KEY_BITS / 8; - xs->aead = kzalloc(aead_len, GFP_KERNEL); + xs->aead = kzalloc(aead_len, GFP_ATOMIC); if (unlikely(!xs->aead)) { err = -ENOMEM; goto err_xs; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -923,7 +923,7 @@ ring->queue_index = txr_idx; /* assign ring to adapter */ - adapter->tx_ring[txr_idx] = ring; + WRITE_ONCE(adapter->tx_ring[txr_idx], ring); /* update count and index */ txr_count--; @@ -950,7 +950,7 @@ set_ring_xdp(ring); /* assign ring to adapter */ - adapter->xdp_ring[xdp_idx] = ring; + WRITE_ONCE(adapter->xdp_ring[xdp_idx], ring); /* update count and index */ xdp_count--; @@ -993,7 +993,7 @@ ring->queue_index = rxr_idx; /* assign ring to adapter */ - adapter->rx_ring[rxr_idx] = ring; + WRITE_ONCE(adapter->rx_ring[rxr_idx], ring); /* update count and index */ rxr_count--; @@ -1022,13 +1022,13 @@ ixgbe_for_each_ring(ring, q_vector->tx) { if (ring_is_xdp(ring)) - adapter->xdp_ring[ring->queue_index] = NULL; + WRITE_ONCE(adapter->xdp_ring[ring->queue_index], NULL); else - adapter->tx_ring[ring->queue_index] = NULL; + WRITE_ONCE(adapter->tx_ring[ring->queue_index], NULL); } ixgbe_for_each_ring(ring, q_vector->rx) - adapter->rx_ring[ring->queue_index] = NULL; + WRITE_ONCE(adapter->rx_ring[ring->queue_index], NULL); adapter->q_vector[v_idx] = NULL; napi_hash_del(&q_vector->napi); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1827,7 +1827,8 @@ struct sk_buff *skb) { if (ring_uses_build_skb(rx_ring)) { - unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK; + unsigned long mask = (unsigned long)ixgbe_rx_pg_size(rx_ring) - 1; + unsigned long offset = (unsigned long)(skb->data) & mask; dma_sync_single_range_for_cpu(rx_ring->dev, IXGBE_CB(skb)->dma, @@ -1947,7 +1948,8 @@ return (page_to_nid(page) != numa_mem_id()) || page_is_pfmemalloc(page); } -static bool ixgbe_can_reuse_rx_page(struct ixgbe_rx_buffer *rx_buffer) +static bool ixgbe_can_reuse_rx_page(struct ixgbe_rx_buffer *rx_buffer, + int rx_buffer_pgcnt) { unsigned int pagecnt_bias = rx_buffer->pagecnt_bias; struct page *page = rx_buffer->page; @@ -1958,7 +1960,7 @@ #if (PAGE_SIZE < 8192) /* if we are only owner of page we can reuse it */ - if (unlikely((page_ref_count(page) - pagecnt_bias) > 1)) + if (unlikely((rx_buffer_pgcnt - pagecnt_bias) > 1)) return false; #else /* The last offset is a bit aggressive in that we assume the @@ -2023,11 +2025,18 @@ static struct ixgbe_rx_buffer *ixgbe_get_rx_buffer(struct ixgbe_ring *rx_ring, union ixgbe_adv_rx_desc *rx_desc, struct sk_buff **skb, - const unsigned int size) + const unsigned int size, + int *rx_buffer_pgcnt) { struct ixgbe_rx_buffer *rx_buffer; rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; + *rx_buffer_pgcnt = +#if (PAGE_SIZE < 8192) + page_count(rx_buffer->page); +#else + 0; +#endif prefetchw(rx_buffer->page); *skb = rx_buffer->skb; @@ -2057,9 +2066,10 @@ static void ixgbe_put_rx_buffer(struct ixgbe_ring *rx_ring, struct ixgbe_rx_buffer *rx_buffer, - struct sk_buff *skb) + struct sk_buff *skb, + int rx_buffer_pgcnt) { - if (ixgbe_can_reuse_rx_page(rx_buffer)) { + if (ixgbe_can_reuse_rx_page(rx_buffer, rx_buffer_pgcnt)) { /* hand second half of page back to the ring */ ixgbe_reuse_rx_page(rx_ring, rx_buffer); } else { @@ -2254,7 +2264,8 @@ rx_buffer->page_offset ^= truesize; #else unsigned int truesize = ring_uses_build_skb(rx_ring) ? - SKB_DATA_ALIGN(IXGBE_SKB_PAD + size) : + SKB_DATA_ALIGN(IXGBE_SKB_PAD + size) + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) : SKB_DATA_ALIGN(size); rx_buffer->page_offset += truesize; @@ -2294,6 +2305,7 @@ union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *rx_buffer; struct sk_buff *skb; + int rx_buffer_pgcnt; unsigned int size; /* return some buffers to hardware, one at a time is too slow */ @@ -2313,7 +2325,7 @@ */ dma_rmb(); - rx_buffer = ixgbe_get_rx_buffer(rx_ring, rx_desc, &skb, size); + rx_buffer = ixgbe_get_rx_buffer(rx_ring, rx_desc, &skb, size, &rx_buffer_pgcnt); /* retrieve a buffer from the ring */ if (!skb) { @@ -2355,7 +2367,7 @@ break; } - ixgbe_put_rx_buffer(rx_ring, rx_buffer, skb); + ixgbe_put_rx_buffer(rx_ring, rx_buffer, skb, rx_buffer_pgcnt); cleaned_count++; /* place incomplete frames back on ring for completion */ @@ -2743,7 +2755,6 @@ { struct ixgbe_hw *hw = &adapter->hw; u32 eicr = adapter->interrupt_event; - s32 rc; if (test_bit(__IXGBE_DOWN, &adapter->state)) return; @@ -2777,14 +2788,13 @@ } /* Check if this is not due to overtemp */ - if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP) + if (!hw->phy.ops.check_overtemp(hw)) return; break; case IXGBE_DEV_ID_X550EM_A_1G_T: case IXGBE_DEV_ID_X550EM_A_1G_T_L: - rc = hw->phy.ops.check_overtemp(hw); - if (rc != IXGBE_ERR_OVERTEMP) + if (!hw->phy.ops.check_overtemp(hw)) return; break; default: @@ -2928,8 +2938,8 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, u64 qmask) { - u32 mask; struct ixgbe_hw *hw = &adapter->hw; + u32 mask; switch (hw->mac.type) { case ixgbe_mac_82598EB: @@ -5239,7 +5249,7 @@ struct ixgbe_hw *hw = &adapter->hw; struct hlist_node *node2; struct ixgbe_fdir_filter *filter; - u64 action; + u8 queue; spin_lock(&adapter->fdir_perfect_lock); @@ -5248,17 +5258,34 @@ hlist_for_each_entry_safe(filter, node2, &adapter->fdir_filter_list, fdir_node) { - action = filter->action; - if (action != IXGBE_FDIR_DROP_QUEUE && action != 0) - action = - (action >> ETHTOOL_RX_FLOW_SPEC_RING_VF_OFF) - 1; + if (filter->action == IXGBE_FDIR_DROP_QUEUE) { + queue = IXGBE_FDIR_DROP_QUEUE; + } else { + u32 ring = ethtool_get_flow_spec_ring(filter->action); + u8 vf = ethtool_get_flow_spec_ring_vf(filter->action); + + if (!vf && (ring >= adapter->num_rx_queues)) { + e_err(drv, "FDIR restore failed without VF, ring: %u\n", + ring); + continue; + } else if (vf && + ((vf > adapter->num_vfs) || + ring >= adapter->num_rx_queues_per_pool)) { + e_err(drv, "FDIR restore failed with VF, vf: %hhu, ring: %u\n", + vf, ring); + continue; + } + + /* Map the ring onto the absolute queue index */ + if (!vf) + queue = adapter->rx_ring[ring]->reg_idx; + else + queue = ((vf - 1) * + adapter->num_rx_queues_per_pool) + ring; + } ixgbe_fdir_write_perfect_filter_82599(hw, - &filter->filter, - filter->sw_idx, - (action == IXGBE_FDIR_DROP_QUEUE) ? - IXGBE_FDIR_DROP_QUEUE : - adapter->rx_ring[action]->reg_idx); + &filter->filter, filter->sw_idx, queue); } spin_unlock(&adapter->fdir_perfect_lock); @@ -5490,7 +5517,7 @@ { u32 speed; bool autoneg, link_up = false; - int ret = IXGBE_ERR_LINK_SETUP; + int ret = -EIO; if (hw->mac.ops.check_link) ret = hw->mac.ops.check_link(hw, &speed, &link_up, false); @@ -5650,6 +5677,9 @@ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + + /* update setting rx tx for all active vfs */ + ixgbe_set_all_vfs(adapter); } void ixgbe_reinit_locked(struct ixgbe_adapter *adapter) @@ -5909,13 +5939,13 @@ err = hw->mac.ops.init_hw(hw); switch (err) { case 0: - case IXGBE_ERR_SFP_NOT_PRESENT: - case IXGBE_ERR_SFP_NOT_SUPPORTED: + case -ENOENT: + case -EOPNOTSUPP: break; - case IXGBE_ERR_MASTER_REQUESTS_PENDING: - e_dev_err("master disable timed out\n"); + case -EALREADY: + e_dev_err("primary disable timed out\n"); break; - case IXGBE_ERR_EEPROM_VERSION: + case -EACCES: /* We are running on a pre-production device, log a warning */ e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated with " @@ -6108,11 +6138,8 @@ for (i = 0 ; i < adapter->num_vfs; i++) adapter->vfinfo[i].clear_to_send = false; - /* ping all the active vfs to let them know we are going down */ - ixgbe_ping_all_vfs(adapter); - - /* Disable all VFTE/VFRE TX/RX */ - ixgbe_disable_tx_rx(adapter); + /* update setting rx tx for all active vfs */ + ixgbe_set_all_vfs(adapter); } /* disable transmits in the hardware now that interrupts are off */ @@ -6367,6 +6394,9 @@ /* n-tuple support exists, always init our spinlock */ spin_lock_init(&adapter->fdir_perfect_lock); + /* init spinlock to avoid concurrency of VF resources */ + spin_lock_init(&adapter->vfs_lock); + #ifdef CONFIG_IXGBE_DCB ixgbe_init_dcb(adapter); #endif @@ -6690,6 +6720,18 @@ } /** + * ixgbe_max_xdp_frame_size - returns the maximum allowed frame size for XDP + * @adapter: device handle, pointer to adapter + */ +static int ixgbe_max_xdp_frame_size(struct ixgbe_adapter *adapter) +{ + if (PAGE_SIZE >= 8192 || adapter->flags2 & IXGBE_FLAG2_RX_LEGACY) + return IXGBE_RXBUFFER_2K; + else + return IXGBE_RXBUFFER_3K; +} + +/** * ixgbe_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure * @new_mtu: new value for maximum frame size @@ -6700,18 +6742,12 @@ { struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (adapter->xdp_prog) { - int new_frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + - VLAN_HLEN; - int i; - - for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *ring = adapter->rx_ring[i]; + if (ixgbe_enabled_xdp_adapter(adapter)) { + int new_frame_size = new_mtu + IXGBE_PKT_HDR_PAD; - if (new_frame_size > ixgbe_rx_bufsz(ring)) { - e_warn(probe, "Requested MTU size is not supported with XDP\n"); - return -EINVAL; - } + if (new_frame_size > ixgbe_max_xdp_frame_size(adapter)) { + e_warn(probe, "Requested MTU size is not supported with XDP\n"); + return -EINVAL; } } @@ -7046,7 +7082,10 @@ } for (i = 0; i < adapter->num_rx_queues; i++) { - struct ixgbe_ring *rx_ring = adapter->rx_ring[i]; + struct ixgbe_ring *rx_ring = READ_ONCE(adapter->rx_ring[i]); + + if (!rx_ring) + continue; non_eop_descs += rx_ring->rx_stats.non_eop_descs; alloc_rx_page += rx_ring->rx_stats.alloc_rx_page; alloc_rx_page_failed += rx_ring->rx_stats.alloc_rx_page_failed; @@ -7067,15 +7106,20 @@ packets = 0; /* gather some stats to the adapter struct that are per queue */ for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *tx_ring = adapter->tx_ring[i]; + struct ixgbe_ring *tx_ring = READ_ONCE(adapter->tx_ring[i]); + + if (!tx_ring) + continue; restart_queue += tx_ring->tx_stats.restart_queue; tx_busy += tx_ring->tx_stats.tx_busy; bytes += tx_ring->stats.bytes; packets += tx_ring->stats.packets; } for (i = 0; i < adapter->num_xdp_queues; i++) { - struct ixgbe_ring *xdp_ring = adapter->xdp_ring[i]; + struct ixgbe_ring *xdp_ring = READ_ONCE(adapter->xdp_ring[i]); + if (!xdp_ring) + continue; restart_queue += xdp_ring->tx_stats.restart_queue; tx_busy += xdp_ring->tx_stats.tx_busy; bytes += xdp_ring->stats.bytes; @@ -7588,6 +7632,27 @@ } #ifdef CONFIG_PCI_IOV +static void ixgbe_bad_vf_abort(struct ixgbe_adapter *adapter, u32 vf) +{ + struct ixgbe_hw *hw = &adapter->hw; + + if (adapter->hw.mac.type == ixgbe_mac_82599EB && + adapter->flags2 & IXGBE_FLAG2_AUTO_DISABLE_VF) { + adapter->vfinfo[vf].primary_abort_count++; + if (adapter->vfinfo[vf].primary_abort_count == + IXGBE_PRIMARY_ABORT_LIMIT) { + ixgbe_set_vf_link_state(adapter, vf, + IFLA_VF_LINK_STATE_DISABLE); + adapter->vfinfo[vf].primary_abort_count = 0; + + e_info(drv, + "Malicious Driver Detection event detected on PF %d VF %d MAC: %pM mdd-disable-vf=on", + hw->bus.func, vf, + adapter->vfinfo[vf].vf_mac_addresses); + } + } +} + static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; @@ -7619,8 +7684,10 @@ continue; pci_read_config_word(vfdev, PCI_STATUS, &status_reg); if (status_reg != IXGBE_FAILED_READ_CFG_WORD && - status_reg & PCI_STATUS_REC_MASTER_ABORT) + status_reg & PCI_STATUS_REC_MASTER_ABORT) { + ixgbe_bad_vf_abort(adapter, vf); pcie_flr(vfdev); + } } } @@ -7707,10 +7774,10 @@ adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1; err = hw->phy.ops.identify_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (err == -EOPNOTSUPP) goto sfp_out; - if (err == IXGBE_ERR_SFP_NOT_PRESENT) { + if (err == -ENOENT) { /* If no cable is present, then we need to reset * the next time we find a good cable. */ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; @@ -7736,7 +7803,7 @@ else err = hw->mac.ops.setup_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (err == -EOPNOTSUPP) goto sfp_out; adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; @@ -7745,8 +7812,8 @@ sfp_out: clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); - if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) && - (adapter->netdev->reg_state == NETREG_REGISTERED)) { + if (err == -EOPNOTSUPP && + adapter->netdev->reg_state == NETREG_REGISTERED) { e_dev_err("failed to initialize because an unsupported " "SFP+ module type was detected.\n"); e_dev_err("Reload the driver after installing a " @@ -7816,7 +7883,7 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 status; + bool overtemp; if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT)) return; @@ -7826,11 +7893,9 @@ if (!hw->phy.ops.handle_lasi) return; - status = hw->phy.ops.handle_lasi(&adapter->hw); - if (status != IXGBE_ERR_OVERTEMP) - return; - - e_crit(drv, "%s\n", ixgbe_overheat_msg); + hw->phy.ops.handle_lasi(&adapter->hw, &overtemp); + if (overtemp) + e_crit(drv, "%s\n", ixgbe_overheat_msg); } static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) @@ -8377,7 +8442,7 @@ struct ixgbe_adapter *adapter = q_vector->adapter; if (unlikely(skb_tail_pointer(skb) < hdr.network + - VXLAN_HEADROOM)) + vxlan_headroom(0))) return; /* verify the port is recognized as VXLAN */ @@ -8639,7 +8704,8 @@ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && adapter->ptp_clock) { - if (!test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, + if (adapter->tstamp_config.tx_type == HWTSTAMP_TX_ON && + !test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state)) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IXGBE_TX_FLAGS_TSTAMP; @@ -9558,8 +9624,10 @@ ixgbe_atr_compute_perfect_hash_82599(&input->filter, mask); err = ixgbe_fdir_write_perfect_filter_82599(hw, &input->filter, input->sw_idx, queue); - if (!err) - ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); + if (err) + goto err_out_w_lock; + + ixgbe_update_ethtool_fdir_entry(adapter, input, input->sw_idx); spin_unlock(&adapter->fdir_perfect_lock); if ((uhtid != 0x800) && (adapter->jump_tables[uhtid])) @@ -10247,7 +10315,12 @@ /* If transitioning XDP modes reconfigure rings */ if (need_reset) { - int err = ixgbe_setup_tc(dev, adapter->hw_tcs); + int err; + + if (!prog) + /* Wait until ndo_xsk_wakeup completes. */ + synchronize_rcu(); + err = ixgbe_setup_tc(dev, adapter->hw_tcs); if (err) { rcu_assign_pointer(adapter->xdp_prog, old_prog); @@ -10361,6 +10434,7 @@ .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, .ndo_set_vf_rate = ixgbe_ndo_set_vf_bw, .ndo_set_vf_spoofchk = ixgbe_ndo_set_vf_spoofchk, + .ndo_set_vf_link_state = ixgbe_ndo_set_vf_link_state, .ndo_set_vf_rss_query_en = ixgbe_ndo_set_vf_rss_query_en, .ndo_set_vf_trust = ixgbe_ndo_set_vf_trust, .ndo_get_vf_config = ixgbe_ndo_get_vf_config, @@ -10479,6 +10553,44 @@ } /** + * ixgbe_irq_disable_single - Disable single IRQ vector + * @adapter: adapter structure + * @ring: ring index + **/ +static void ixgbe_irq_disable_single(struct ixgbe_adapter *adapter, u32 ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 qmask = BIT_ULL(ring); + u32 mask; + + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + mask = qmask & IXGBE_EIMC_RTX_QUEUE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask); + break; + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: + case ixgbe_mac_X550: + case ixgbe_mac_X550EM_x: + case ixgbe_mac_x550em_a: + mask = (qmask & 0xFFFFFFFF); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask); + mask = (qmask >> 32); + if (mask) + IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask); + break; + default: + break; + } + IXGBE_WRITE_FLUSH(&adapter->hw); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) + synchronize_irq(adapter->msix_entries[ring].vector); + else + synchronize_irq(adapter->pdev->irq); +} + +/** * ixgbe_txrx_ring_disable - Disable Rx/Tx/XDP Tx rings * @adapter: adapter structure * @ring: ring index @@ -10494,6 +10606,11 @@ tx_ring = adapter->tx_ring[ring]; xdp_ring = adapter->xdp_ring[ring]; + ixgbe_irq_disable_single(adapter, ring); + + /* Rx/Tx/XDP Tx share the same napi context. */ + napi_disable(&rx_ring->q_vector->napi); + ixgbe_disable_txr(adapter, tx_ring); if (xdp_ring) ixgbe_disable_txr(adapter, xdp_ring); @@ -10502,9 +10619,6 @@ if (xdp_ring) synchronize_rcu(); - /* Rx/Tx/XDP Tx share the same napi context. */ - napi_disable(&rx_ring->q_vector->napi); - ixgbe_clean_tx_ring(tx_ring); if (xdp_ring) ixgbe_clean_tx_ring(xdp_ring); @@ -10532,9 +10646,6 @@ tx_ring = adapter->tx_ring[ring]; xdp_ring = adapter->xdp_ring[ring]; - /* Rx/Tx/XDP Tx share the same napi context. */ - napi_enable(&rx_ring->q_vector->napi); - ixgbe_configure_tx_ring(adapter, tx_ring); if (xdp_ring) ixgbe_configure_tx_ring(adapter, xdp_ring); @@ -10543,6 +10654,11 @@ clear_bit(__IXGBE_TX_DISABLED, &tx_ring->state); if (xdp_ring) clear_bit(__IXGBE_TX_DISABLED, &xdp_ring->state); + + /* Rx/Tx/XDP Tx share the same napi context. */ + napi_enable(&rx_ring->q_vector->napi); + ixgbe_irq_enable_queues(adapter, BIT_ULL(ring)); + IXGBE_WRITE_FLUSH(&adapter->hw); } /** @@ -10829,6 +10945,9 @@ if (err) goto err_sw_init; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + adapter->flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF; + /* Make sure the SWFW semaphore is in a valid state */ if (hw->mac.ops.init_swfw_sync) hw->mac.ops.init_swfw_sync(hw); @@ -10864,9 +10983,9 @@ err = hw->mac.ops.reset_hw(hw); hw->phy.reset_if_overtemp = false; ixgbe_set_eee_capable(adapter); - if (err == IXGBE_ERR_SFP_NOT_PRESENT) { + if (err == -ENOENT) { err = 0; - } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + } else if (err == -EOPNOTSUPP) { e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n"); e_dev_err("Reload the driver after installing a supported module.\n"); goto err_sw_init; @@ -11083,7 +11202,7 @@ /* reset the hardware with the new settings */ err = hw->mac.ops.start_hw(hw); - if (err == IXGBE_ERR_EEPROM_VERSION) { + if (err == -EACCES) { /* We are running on a pre-production device, log a warning */ e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated " @@ -11163,6 +11282,7 @@ disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c @@ -24,7 +24,7 @@ size = mbx->size; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->read(hw, msg, size, mbx_id); } @@ -43,10 +43,10 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (size > mbx->size) - return IXGBE_ERR_MBX; + return -EINVAL; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->write(hw, msg, size, mbx_id); } @@ -63,7 +63,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_msg(hw, mbx_id); } @@ -80,7 +80,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_ack(hw, mbx_id); } @@ -97,7 +97,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_rst(hw, mbx_id); } @@ -115,12 +115,12 @@ int countdown = mbx->timeout; if (!countdown || !mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; while (mbx->ops->check_for_msg(hw, mbx_id)) { countdown--; if (!countdown) - return IXGBE_ERR_MBX; + return -EIO; udelay(mbx->usec_delay); } @@ -140,12 +140,12 @@ int countdown = mbx->timeout; if (!countdown || !mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; while (mbx->ops->check_for_ack(hw, mbx_id)) { countdown--; if (!countdown) - return IXGBE_ERR_MBX; + return -EIO; udelay(mbx->usec_delay); } @@ -169,7 +169,7 @@ s32 ret_val; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; ret_val = ixgbe_poll_for_msg(hw, mbx_id); if (ret_val) @@ -197,7 +197,7 @@ /* exit if either we can't write or there isn't a defined timeout */ if (!mbx->ops || !mbx->timeout) - return IXGBE_ERR_MBX; + return -EIO; /* send msg */ ret_val = mbx->ops->write(hw, msg, size, mbx_id); @@ -217,7 +217,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -238,7 +238,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -259,7 +259,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -295,7 +295,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -317,7 +317,7 @@ if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) return 0; - return IXGBE_ERR_MBX; + return -EIO; } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h @@ -7,7 +7,6 @@ #include "ixgbe_type.h" #define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ -#define IXGBE_ERR_MBX -100 #define IXGBE_VFMAILBOX 0x002FC #define IXGBE_VFMBMEM 0x00200 @@ -85,6 +84,8 @@ #define IXGBE_VF_IPSEC_ADD 0x0d #define IXGBE_VF_IPSEC_DEL 0x0e +#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */ + /* length of permanent address message returned from PF */ #define IXGBE_VF_PERMADDR_MSG_LEN 4 /* word in permanent address message with the current multicast type */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -102,7 +102,7 @@ csum = ~csum; do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); /* Device Address and write indication */ if (ixgbe_out_i2c_byte_ack(hw, addr)) @@ -150,7 +150,7 @@ hw_dbg(hw, "I2C byte read combined error.\n"); } while (retry < max_retry); - return IXGBE_ERR_I2C; + return -EIO; } /** @@ -179,7 +179,7 @@ csum = ~csum; do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); /* Device Address and write indication */ if (ixgbe_out_i2c_byte_ack(hw, addr)) @@ -215,7 +215,7 @@ hw_dbg(hw, "I2C byte write combined error.\n"); } while (retry < max_retry); - return IXGBE_ERR_I2C; + return -EIO; } /** @@ -262,8 +262,8 @@ **/ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { + u32 status = -EFAULT; u32 phy_addr; - u32 status = IXGBE_ERR_PHY_ADDR_INVALID; if (!hw->phy.phy_semaphore_mask) { if (hw->bus.lan_id) @@ -282,7 +282,7 @@ if (ixgbe_probe_phy(hw, phy_addr)) return 0; else - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; } for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { @@ -405,8 +405,7 @@ return status; /* Don't reset PHY if it's shut down due to overtemp. */ - if (!hw->phy.reset_if_overtemp && - (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) + if (!hw->phy.reset_if_overtemp && hw->phy.ops.check_overtemp(hw)) return 0; /* Blocked by MNG FW so bail */ @@ -454,7 +453,7 @@ if (ctrl & MDIO_CTRL1_RESET) { hw_dbg(hw, "PHY reset polling failed to complete.\n"); - return IXGBE_ERR_RESET_FAILED; + return -EIO; } return 0; @@ -496,7 +495,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY address command did not complete.\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Address cycle complete, setup and write the read @@ -523,7 +522,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY read command didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Read operation is complete. Get the data @@ -555,7 +554,7 @@ phy_data); hw->mac.ops.release_swfw_sync(hw, gssr); } else { - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } return status; @@ -600,7 +599,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY address cmd didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* @@ -628,7 +627,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY write cmd didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -653,7 +652,7 @@ phy_data); hw->mac.ops.release_swfw_sync(hw, gssr); } else { - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } return status; @@ -851,9 +850,11 @@ rp_pdev = pci_get_domain_bus_and_slot(0, 0, devfn); if (rp_pdev && rp_pdev->subordinate) { bus = rp_pdev->subordinate->number; + pci_dev_put(rp_pdev); return pci_get_domain_bus_and_slot(0, bus, 0); } + pci_dev_put(rp_pdev); return NULL; } @@ -870,6 +871,7 @@ struct ixgbe_adapter *adapter = hw->back; struct pci_dev *pdev = adapter->pdev; struct pci_dev *func0_pdev; + bool has_mii = false; /* For the C3000 family of SoCs (x550em_a) the internal ixgbe devices * are always downstream of root ports @ 0000:00:16.0 & 0000:00:17.0 @@ -880,15 +882,16 @@ func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x16, 0)); if (func0_pdev) { if (func0_pdev == pdev) - return true; - else - return false; + has_mii = true; + goto out; } func0_pdev = ixgbe_get_first_secondary_devfn(PCI_DEVFN(0x17, 0)); if (func0_pdev == pdev) - return true; + has_mii = true; - return false; +out: + pci_dev_put(func0_pdev); + return has_mii; } /** @@ -1298,7 +1301,7 @@ if ((phy_data & MDIO_CTRL1_RESET) != 0) { hw_dbg(hw, "PHY reset did not complete.\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Get init offsets */ @@ -1355,12 +1358,12 @@ hw_dbg(hw, "SOL\n"); } else { hw_dbg(hw, "Bad control value\n"); - return IXGBE_ERR_PHY; + return -EIO; } break; default: hw_dbg(hw, "Bad control type\n"); - return IXGBE_ERR_PHY; + return -EIO; } } @@ -1368,7 +1371,7 @@ err_eeprom: hw_err(hw, "eeprom read at offset %d failed\n", data_offset); - return IXGBE_ERR_PHY; + return -EIO; } /** @@ -1386,10 +1389,10 @@ return ixgbe_identify_qsfp_module_generic(hw); default: hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1414,7 +1417,7 @@ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /* LAN ID is needed for sfp_type determination */ @@ -1429,7 +1432,7 @@ if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES, @@ -1620,7 +1623,7 @@ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } /* Anything else 82598-based is supported */ @@ -1644,7 +1647,7 @@ } hw_dbg(hw, "SFP+ module not supported\n"); hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; @@ -1654,7 +1657,7 @@ hw->phy.id = 0; hw->phy.type = ixgbe_phy_unknown; } - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1681,7 +1684,7 @@ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) { hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /* LAN ID is needed for sfp_type determination */ @@ -1695,7 +1698,7 @@ if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } hw->phy.id = identifier; @@ -1763,7 +1766,7 @@ } else { /* unsupported module type */ hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } } @@ -1823,7 +1826,7 @@ } hw_dbg(hw, "QSFP module not supported\n"); hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; } @@ -1834,7 +1837,7 @@ hw->phy.id = 0; hw->phy.type = ixgbe_phy_unknown; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1854,14 +1857,14 @@ u16 sfp_type = hw->phy.sfp_type; if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) && (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; /* * Limiting active cables and 1G Phys must be initialized as @@ -1882,11 +1885,11 @@ if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) { hw_err(hw, "eeprom read at %d failed\n", IXGBE_PHY_INIT_OFFSET_NL); - return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + return -EIO; } if ((!*list_offset) || (*list_offset == 0xFFFF)) - return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + return -EIO; /* Shift offset to first ID word */ (*list_offset)++; @@ -1905,7 +1908,7 @@ goto err_phy; if ((!*data_offset) || (*data_offset == 0xFFFF)) { hw_dbg(hw, "SFP+ module not supported\n"); - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } else { break; } @@ -1918,14 +1921,14 @@ if (sfp_id == IXGBE_PHY_INIT_END_NL) { hw_dbg(hw, "No matching SFP+ module found\n"); - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; err_phy: hw_err(hw, "eeprom read at offset %d failed\n", *list_offset); - return IXGBE_ERR_PHY; + return -EIO; } /** @@ -2020,7 +2023,7 @@ do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); @@ -2136,7 +2139,7 @@ u32 swfw_mask = hw->phy.phy_semaphore_mask; if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; do { ixgbe_i2c_start(hw); @@ -2378,7 +2381,7 @@ if (ack == 1) { hw_dbg(hw, "I2C ack was not received.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; } ixgbe_lower_i2c_clk(hw, &i2cctl); @@ -2450,7 +2453,7 @@ udelay(IXGBE_I2C_T_LOW); } else { hw_dbg(hw, "I2C data was not set to %X\n", data); - return IXGBE_ERR_I2C; + return -EIO; } return 0; @@ -2546,7 +2549,7 @@ *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw)); if (data != ixgbe_get_i2c_data(hw, i2cctl)) { hw_dbg(hw, "Error - I2C data was not set to %X.\n", data); - return IXGBE_ERR_I2C; + return -EIO; } return 0; @@ -2616,22 +2619,24 @@ * @hw: pointer to hardware structure * * Checks if the LASI temp alarm status was triggered due to overtemp + * + * Return true when an overtemp event detected, otherwise false. **/ -s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) { u16 phy_data = 0; + u32 status; if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) - return 0; + return false; /* Check that the LASI temp alarm status was triggered */ - hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, - MDIO_MMD_PMAPMD, &phy_data); - - if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) - return 0; + status = hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + MDIO_MMD_PMAPMD, &phy_data); + if (status) + return false; - return IXGBE_ERR_OVERTEMP; + return !!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM); } /** ixgbe_set_copper_phy_power - Control power for copper phy --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -155,7 +155,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); -s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); +bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -989,6 +989,7 @@ u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; u32 tsync_rx_mtrl = PTP_EV_PORT << 16; + u32 aflags = adapter->flags; bool is_l2 = false; u32 regval; @@ -1009,20 +1010,20 @@ case HWTSTAMP_FILTER_NONE: tsync_rx_ctl = 0; tsync_rx_mtrl = 0; - adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: @@ -1036,8 +1037,8 @@ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; is_l2 = true; config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_NTP_ALL: @@ -1048,7 +1049,7 @@ if (hw->mac.type >= ixgbe_mac_X550) { tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; config->rx_filter = HWTSTAMP_FILTER_ALL; - adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; break; } /* fall through */ @@ -1059,8 +1060,6 @@ * Delay_Req messages and hardware does not support * timestamping all packets => return error */ - adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); config->rx_filter = HWTSTAMP_FILTER_NONE; return -ERANGE; } @@ -1092,8 +1091,8 @@ IXGBE_TSYNCRXCTL_TYPE_ALL | IXGBE_TSYNCRXCTL_TSIP_UT_EN; config->rx_filter = HWTSTAMP_FILTER_ALL; - adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; - adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; is_l2 = true; break; default: @@ -1126,6 +1125,9 @@ IXGBE_WRITE_FLUSH(hw); + /* configure adapter flags only when HW is actually configured */ + adapter->flags = aflags; + /* clear TX/RX time stamp registers, just to be sure */ ixgbe_ptp_clear_tx_timestamp(adapter); IXGBE_READ_REG(hw, IXGBE_RXSTMPH); @@ -1211,7 +1213,6 @@ struct cyclecounter cc; unsigned long flags; u32 incval = 0; - u32 tsauxc = 0; u32 fuse0 = 0; /* For some of the boards below this mask is technically incorrect. @@ -1246,18 +1247,6 @@ case ixgbe_mac_x550em_a: case ixgbe_mac_X550: cc.read = ixgbe_ptp_read_X550; - - /* enable SYSTIME counter */ - IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); - IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); - IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); - tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); - IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, - tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); - IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); - IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); - - IXGBE_WRITE_FLUSH(hw); break; case ixgbe_mac_X540: cc.read = ixgbe_ptp_read_82599; @@ -1290,6 +1279,50 @@ } /** + * ixgbe_ptp_init_systime - Initialize SYSTIME registers + * @adapter: the ixgbe private board structure + * + * Initialize and start the SYSTIME registers. + */ +static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 tsauxc; + + switch (hw->mac.type) { + case ixgbe_mac_X550EM_x: + case ixgbe_mac_x550em_a: + case ixgbe_mac_X550: + tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC); + + /* Reset SYSTIME registers to 0 */ + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); + + /* Reset interrupt settings */ + IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS); + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC); + + /* Activate the SYSTIME counter */ + IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, + tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME); + break; + case ixgbe_mac_X540: + case ixgbe_mac_82599EB: + /* Reset SYSTIME registers to 0 */ + IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0); + IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0); + break; + default: + /* Other devices aren't supported */ + return; + }; + + IXGBE_WRITE_FLUSH(hw); +} + +/** * ixgbe_ptp_reset * @adapter: the ixgbe private board structure * @@ -1315,6 +1348,8 @@ ixgbe_ptp_start_cyclecounter(adapter); + ixgbe_ptp_init_systime(adapter); + spin_lock_irqsave(&adapter->tmreg_lock, flags); timecounter_init(&adapter->hw_tc, &adapter->hw_cc, ktime_to_ns(ktime_get_real())); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -28,6 +28,9 @@ struct vf_macvlans *mv_list; int num_vf_macvlans, i; + /* Initialize list of VF macvlans */ + INIT_LIST_HEAD(&adapter->vf_mvs.l); + num_vf_macvlans = hw->mac.num_rar_entries - (IXGBE_MAX_PF_MACVLANS + 1 + num_vfs); if (!num_vf_macvlans) @@ -36,8 +39,6 @@ mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), GFP_KERNEL); if (mv_list) { - /* Initialize list of VF macvlans */ - INIT_LIST_HEAD(&adapter->vf_mvs.l); for (i = 0; i < num_vf_macvlans; i++) { mv_list[i].vf = -1; mv_list[i].free = true; @@ -96,6 +97,7 @@ for (i = 0; i < num_vfs; i++) { /* enable spoof checking for all VFs */ adapter->vfinfo[i].spoofchk_enabled = true; + adapter->vfinfo[i].link_enable = true; /* We support VF RSS querying only for 82599 and x540 * devices at the moment. These devices share RSS @@ -204,10 +206,13 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) { unsigned int num_vfs = adapter->num_vfs, vf; + unsigned long flags; int rss; + spin_lock_irqsave(&adapter->vfs_lock, flags); /* set num VFs to 0 to prevent access to vfinfo */ adapter->num_vfs = 0; + spin_unlock_irqrestore(&adapter->vfs_lock, flags); /* put the reference to all of the vf devices */ for (vf = 0; vf < num_vfs; ++vf) { @@ -467,12 +472,16 @@ return err; } -static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) +static int ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 max_frame, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; - int max_frame = msgbuf[1]; u32 max_frs; + if (max_frame < ETH_MIN_MTU || max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE) { + e_err(drv, "VF max_frame %d out of range\n", max_frame); + return -EINVAL; + } + /* * For 82599EB we have to keep all PFs and VFs operating with * the same max_frame value in order to avoid sending an oversize @@ -533,12 +542,6 @@ } } - /* MTU < 68 is an error and causes problems on some kernels */ - if (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE) { - e_err(drv, "VF max_frame %d out of range\n", max_frame); - return -EINVAL; - } - /* pull current max frame size from hardware */ max_frs = IXGBE_READ_REG(hw, IXGBE_MAXFRS); max_frs &= IXGBE_MHADD_MFS_MASK; @@ -822,6 +825,57 @@ } } +/** + * ixgbe_set_vf_rx_tx - Set VF rx tx + * @adapter: Pointer to adapter struct + * @vf: VF identifier + * + * Set or reset correct transmit and receive for vf + **/ +static void ixgbe_set_vf_rx_tx(struct ixgbe_adapter *adapter, int vf) +{ + u32 reg_cur_tx, reg_cur_rx, reg_req_tx, reg_req_rx; + struct ixgbe_hw *hw = &adapter->hw; + u32 reg_offset, vf_shift; + + vf_shift = vf % 32; + reg_offset = vf / 32; + + reg_cur_tx = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); + reg_cur_rx = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); + + if (adapter->vfinfo[vf].link_enable) { + reg_req_tx = reg_cur_tx | 1 << vf_shift; + reg_req_rx = reg_cur_rx | 1 << vf_shift; + } else { + reg_req_tx = reg_cur_tx & ~(1 << vf_shift); + reg_req_rx = reg_cur_rx & ~(1 << vf_shift); + } + + /* The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs. + * For more info take a look at ixgbe_set_vf_lpe + */ + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + struct net_device *dev = adapter->netdev; + int pf_max_frame = dev->mtu + ETH_HLEN; + +#if IS_ENABLED(CONFIG_FCOE) + if (dev->features & NETIF_F_FCOE_MTU) + pf_max_frame = max_t(int, pf_max_frame, + IXGBE_FCOE_JUMBO_FRAME_SIZE); +#endif /* CONFIG_FCOE */ + + if (pf_max_frame > ETH_FRAME_LEN) + reg_req_rx = reg_cur_rx & ~(1 << vf_shift); + } + + /* Enable/Disable particular VF */ + if (reg_cur_tx != reg_req_tx) + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg_req_tx); + if (reg_cur_rx != reg_req_rx) + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg_req_rx); +} + static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ]; @@ -847,11 +901,6 @@ vf_shift = vf % 32; reg_offset = vf / 32; - /* enable transmit for vf */ - reg = IXGBE_READ_REG(hw, IXGBE_VFTE(reg_offset)); - reg |= BIT(vf_shift); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg); - /* force drop enable for all VF Rx queues */ reg = IXGBE_QDE_ENABLE; if (adapter->vfinfo[vf].pf_vlan) @@ -859,27 +908,7 @@ ixgbe_write_qde(adapter, vf, reg); - /* enable receive for vf */ - reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset)); - reg |= BIT(vf_shift); - /* - * The 82599 cannot support a mix of jumbo and non-jumbo PF/VFs. - * For more info take a look at ixgbe_set_vf_lpe - */ - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - struct net_device *dev = adapter->netdev; - int pf_max_frame = dev->mtu + ETH_HLEN; - -#ifdef CONFIG_FCOE - if (dev->features & NETIF_F_FCOE_MTU) - pf_max_frame = max_t(int, pf_max_frame, - IXGBE_FCOE_JUMBO_FRAME_SIZE); - -#endif /* CONFIG_FCOE */ - if (pf_max_frame > ETH_FRAME_LEN) - reg &= ~BIT(vf_shift); - } - IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); + ixgbe_set_vf_rx_tx(adapter, vf); /* enable VF mailbox for further messages */ adapter->vfinfo[vf].clear_to_send = true; @@ -1159,9 +1188,9 @@ switch (xcast_mode) { case IXGBEVF_XCAST_MODE_NONE: - disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | + disable = IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; - enable = 0; + enable = IXGBE_VMOLR_BAM; break; case IXGBEVF_XCAST_MODE_MULTI: disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; @@ -1183,9 +1212,9 @@ return -EPERM; } - disable = 0; + disable = IXGBE_VMOLR_VPE; enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE | - IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE; + IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE; break; default: return -EOPNOTSUPP; @@ -1204,6 +1233,26 @@ return 0; } +static int ixgbe_get_vf_link_state(struct ixgbe_adapter *adapter, + u32 *msgbuf, u32 vf) +{ + u32 *link_state = &msgbuf[1]; + + /* verify the PF is supporting the correct API */ + switch (adapter->vfinfo[vf].vf_api) { + case ixgbe_mbox_api_12: + case ixgbe_mbox_api_13: + case ixgbe_mbox_api_14: + break; + default: + return -EOPNOTSUPP; + } + + *link_state = adapter->vfinfo[vf].link_enable; + + return 0; +} + static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) { u32 mbx_size = IXGBE_VFMAILBOX_SIZE; @@ -1249,7 +1298,7 @@ retval = ixgbe_set_vf_vlan_msg(adapter, msgbuf, vf); break; case IXGBE_VF_SET_LPE: - retval = ixgbe_set_vf_lpe(adapter, msgbuf, vf); + retval = ixgbe_set_vf_lpe(adapter, msgbuf[1], vf); break; case IXGBE_VF_SET_MACVLAN: retval = ixgbe_set_vf_macvlan_msg(adapter, msgbuf, vf); @@ -1269,6 +1318,9 @@ case IXGBE_VF_UPDATE_XCAST_MODE: retval = ixgbe_update_vf_xcast_mode(adapter, msgbuf, vf); break; + case IXGBE_VF_GET_LINK_STATE: + retval = ixgbe_get_vf_link_state(adapter, msgbuf, vf); + break; case IXGBE_VF_IPSEC_ADD: retval = ixgbe_ipsec_vf_add_sa(adapter, msgbuf, vf); break; @@ -1277,7 +1329,7 @@ break; default: e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); - retval = IXGBE_ERR_MBX; + retval = -EIO; break; } @@ -1307,8 +1359,10 @@ void ixgbe_msg_task(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; + unsigned long flags; u32 vf; + spin_lock_irqsave(&adapter->vfs_lock, flags); for (vf = 0; vf < adapter->num_vfs; vf++) { /* process any reset requests */ if (!ixgbe_check_for_rst(hw, vf)) @@ -1322,18 +1376,7 @@ if (!ixgbe_check_for_ack(hw, vf)) ixgbe_rcv_ack_from_vf(adapter, vf); } -} - -void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - - /* disable transmit and receive for all vfs */ - IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0); - - IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0); + spin_unlock_irqrestore(&adapter->vfs_lock, flags); } static inline void ixgbe_ping_vf(struct ixgbe_adapter *adapter, int vf) @@ -1361,6 +1404,21 @@ } } +/** + * ixgbe_set_all_vfs - update vfs queues + * @adapter: Pointer to adapter struct + * + * Update setting transmit and receive queues for all vfs + **/ +void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter) +{ + int i; + + for (i = 0 ; i < adapter->num_vfs; i++) + ixgbe_set_vf_link_state(adapter, i, + adapter->vfinfo[i].link_state); +} + int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -1658,6 +1716,84 @@ return 0; } +/** + * ixgbe_set_vf_link_state - Set link state + * @adapter: Pointer to adapter struct + * @vf: VF identifier + * @state: required link state + * + * Set a link force state on/off a single vf + **/ +void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state) +{ + adapter->vfinfo[vf].link_state = state; + + switch (state) { + case IFLA_VF_LINK_STATE_AUTO: + if (test_bit(__IXGBE_DOWN, &adapter->state)) + adapter->vfinfo[vf].link_enable = false; + else + adapter->vfinfo[vf].link_enable = true; + break; + case IFLA_VF_LINK_STATE_ENABLE: + adapter->vfinfo[vf].link_enable = true; + break; + case IFLA_VF_LINK_STATE_DISABLE: + adapter->vfinfo[vf].link_enable = false; + break; + } + + ixgbe_set_vf_rx_tx(adapter, vf); + + /* restart the VF */ + adapter->vfinfo[vf].clear_to_send = false; + ixgbe_ping_vf(adapter, vf); +} + +/** + * ixgbe_ndo_set_vf_link_state - Set link state + * @netdev: network interface device structure + * @vf: VF identifier + * @state: required link state + * + * Set the link state of a specified VF, regardless of physical link state + **/ +int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int ret = 0; + + if (vf < 0 || vf >= adapter->num_vfs) { + dev_err(&adapter->pdev->dev, + "NDO set VF link - invalid VF identifier %d\n", vf); + return -EINVAL; + } + + switch (state) { + case IFLA_VF_LINK_STATE_ENABLE: + dev_info(&adapter->pdev->dev, + "NDO set VF %d link state %d - not supported\n", + vf, state); + break; + case IFLA_VF_LINK_STATE_DISABLE: + dev_info(&adapter->pdev->dev, + "NDO set VF %d link state disable\n", vf); + ixgbe_set_vf_link_state(adapter, vf, state); + break; + case IFLA_VF_LINK_STATE_AUTO: + dev_info(&adapter->pdev->dev, + "NDO set VF %d link state auto\n", vf); + ixgbe_set_vf_link_state(adapter, vf, state); + break; + default: + dev_err(&adapter->pdev->dev, + "NDO set VF %d - invalid link state %d\n", vf, state); + ret = -EINVAL; + } + + return ret; +} + int ixgbe_ndo_set_vf_rss_query_en(struct net_device *netdev, int vf, bool setting) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h @@ -17,8 +17,8 @@ #endif void ixgbe_msg_task(struct ixgbe_adapter *adapter); int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); -void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); +void ixgbe_set_all_vfs(struct ixgbe_adapter *adapter); int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, u8 qos, __be16 vlan_proto); @@ -31,7 +31,9 @@ int ixgbe_ndo_set_vf_trust(struct net_device *netdev, int vf, bool setting); int ixgbe_ndo_get_vf_config(struct net_device *netdev, int vf, struct ifla_vf_info *ivi); +int ixgbe_ndo_set_vf_link_state(struct net_device *netdev, int vf, int state); void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); +void ixgbe_set_vf_link_state(struct ixgbe_adapter *adapter, int vf, int state); int ixgbe_disable_sriov(struct ixgbe_adapter *adapter); #ifdef CONFIG_PCI_IOV void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, unsigned int max_vfs); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -1247,7 +1247,7 @@ #define IXGBE_PSRTYPE_RQPL_SHIFT 29 /* CTRL Bit Masks */ -#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Master Disable bit */ +#define IXGBE_CTRL_GIO_DIS 0x00000004 /* Global IO Primary Disable bit */ #define IXGBE_CTRL_LNK_RST 0x00000008 /* Link Reset. Resets everything. */ #define IXGBE_CTRL_RST 0x04000000 /* Reset (SW) */ #define IXGBE_CTRL_RST_MASK (IXGBE_CTRL_LNK_RST | IXGBE_CTRL_RST) @@ -1810,7 +1810,7 @@ /* STATUS Bit Masks */ #define IXGBE_STATUS_LAN_ID 0x0000000C /* LAN ID */ #define IXGBE_STATUS_LAN_ID_SHIFT 2 /* LAN ID Shift*/ -#define IXGBE_STATUS_GIO 0x00080000 /* GIO Master Enable Status */ +#define IXGBE_STATUS_GIO 0x00080000 /* GIO Primary Enable Status */ #define IXGBE_STATUS_LAN_ID_0 0x00000000 /* LAN ID 0 */ #define IXGBE_STATUS_LAN_ID_1 0x00000004 /* LAN ID 1 */ @@ -2192,8 +2192,8 @@ #define IXGBE_PCIDEVCTRL2_4_8s 0xd #define IXGBE_PCIDEVCTRL2_17_34s 0xe -/* Number of 100 microseconds we wait for PCI Express master disable */ -#define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800 +/* Number of 100 microseconds we wait for PCI Express primary disable */ +#define IXGBE_PCI_PRIMARY_DISABLE_TIMEOUT 800 /* RAH */ #define IXGBE_RAH_VIND_MASK 0x003C0000 @@ -3505,10 +3505,10 @@ s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *); s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); - s32 (*check_overtemp)(struct ixgbe_hw *); + bool (*check_overtemp)(struct ixgbe_hw *); s32 (*set_phy_power)(struct ixgbe_hw *, bool on); s32 (*enter_lplu)(struct ixgbe_hw *); - s32 (*handle_lasi)(struct ixgbe_hw *hw); + s32 (*handle_lasi)(struct ixgbe_hw *hw, bool *); s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, u8 *value); s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, @@ -3661,45 +3661,6 @@ const u32 *mvals; }; - -/* Error Codes */ -#define IXGBE_ERR_EEPROM -1 -#define IXGBE_ERR_EEPROM_CHECKSUM -2 -#define IXGBE_ERR_PHY -3 -#define IXGBE_ERR_CONFIG -4 -#define IXGBE_ERR_PARAM -5 -#define IXGBE_ERR_MAC_TYPE -6 -#define IXGBE_ERR_UNKNOWN_PHY -7 -#define IXGBE_ERR_LINK_SETUP -8 -#define IXGBE_ERR_ADAPTER_STOPPED -9 -#define IXGBE_ERR_INVALID_MAC_ADDR -10 -#define IXGBE_ERR_DEVICE_NOT_SUPPORTED -11 -#define IXGBE_ERR_MASTER_REQUESTS_PENDING -12 -#define IXGBE_ERR_INVALID_LINK_SETTINGS -13 -#define IXGBE_ERR_AUTONEG_NOT_COMPLETE -14 -#define IXGBE_ERR_RESET_FAILED -15 -#define IXGBE_ERR_SWFW_SYNC -16 -#define IXGBE_ERR_PHY_ADDR_INVALID -17 -#define IXGBE_ERR_I2C -18 -#define IXGBE_ERR_SFP_NOT_SUPPORTED -19 -#define IXGBE_ERR_SFP_NOT_PRESENT -20 -#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 -#define IXGBE_ERR_NO_SAN_ADDR_PTR -22 -#define IXGBE_ERR_FDIR_REINIT_FAILED -23 -#define IXGBE_ERR_EEPROM_VERSION -24 -#define IXGBE_ERR_NO_SPACE -25 -#define IXGBE_ERR_OVERTEMP -26 -#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 -#define IXGBE_ERR_FC_NOT_SUPPORTED -28 -#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 -#define IXGBE_ERR_PBA_SECTION -31 -#define IXGBE_ERR_INVALID_ARGUMENT -32 -#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 -#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 -#define IXGBE_ERR_FW_RESP_INVALID -39 -#define IXGBE_ERR_TOKEN_RETRY -40 -#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF - #define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) #define IXGBE_FUSES0_300MHZ BIT(5) #define IXGBE_FUSES0_REV_MASK (3u << 6) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c @@ -84,7 +84,7 @@ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); if (status) { hw_dbg(hw, "semaphore failed with %d", status); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ctrl = IXGBE_CTRL_RST; @@ -103,7 +103,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } msleep(100); @@ -220,7 +220,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_read_eerd_generic(hw, offset, data); @@ -243,7 +243,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data); @@ -264,7 +264,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_eewr_generic(hw, offset, data); @@ -287,7 +287,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data); @@ -324,7 +324,7 @@ for (i = 0; i < checksum_last_word; i++) { if (ixgbe_read_eerd_generic(hw, i, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -349,8 +349,7 @@ if (ixgbe_read_eerd_generic(hw, pointer, &length)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; - break; + return -EIO; } /* Skip pointer section if length is invalid. */ @@ -361,7 +360,7 @@ for (j = pointer + 1; j <= pointer + length; j++) { if (ixgbe_read_eerd_generic(hw, j, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -398,7 +397,7 @@ } if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->eeprom.ops.calc_checksum(hw); if (status < 0) @@ -419,7 +418,7 @@ */ if (read_checksum != checksum) { hw_dbg(hw, "Invalid EEPROM checksum"); - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; } /* If the user cares, return the calculated checksum */ @@ -456,7 +455,7 @@ } if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->eeprom.ops.calc_checksum(hw); if (status < 0) @@ -491,7 +490,7 @@ s32 status; status = ixgbe_poll_flash_update_done_X540(hw); - if (status == IXGBE_ERR_EEPROM) { + if (status == -EIO) { hw_dbg(hw, "Flash update time out\n"); return status; } @@ -541,7 +540,7 @@ return 0; udelay(5); } - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -576,7 +575,7 @@ * SW_FW_SYNC bits (not just NVM) */ if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); if (!(swfw_sync & (fwmask | swmask | hwmask))) { @@ -600,7 +599,7 @@ * bits in the SW_FW_SYNC register. */ if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); if (swfw_sync & (fwmask | hwmask)) { swfw_sync |= swmask; @@ -623,11 +622,11 @@ rmask |= IXGBE_GSSR_I2C_MASK; ixgbe_release_swfw_sync_X540(hw, rmask); ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } /** @@ -681,7 +680,7 @@ if (i == timeout) { hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } /* Now get the semaphore between SW/FW through the REGSMP bit */ @@ -698,7 +697,7 @@ */ hw_dbg(hw, "REGSMP Software NVM semaphore not granted\n"); ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -769,7 +768,7 @@ bool link_up; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Link should be up in order for the blink bit in the LED control * register to work. Force link and speed in the MAC if link is down. @@ -805,7 +804,7 @@ u32 ledctl_reg; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Restore the LED to its default value. */ ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c @@ -206,13 +206,13 @@ } if (retry == IXGBE_CS4227_RETRIES) { hw_err(hw, "CS4227 reset did not complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value); if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) { hw_err(hw, "CS4227 EEPROM did not load successfully\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -350,13 +350,13 @@ static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data) { - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; } static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data) { - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; } /** @@ -463,7 +463,7 @@ --retries; } while (retries > 0); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; } static const struct { @@ -511,7 +511,7 @@ hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; hw->phy.autoneg_advertised = hw->phy.speeds_supported; hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | @@ -568,7 +568,7 @@ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } switch (hw->fc.requested_mode) { @@ -600,8 +600,10 @@ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); if (rc) return rc; + if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) - return IXGBE_ERR_OVERTEMP; + return -EIO; + return 0; } @@ -675,7 +677,7 @@ *ctrl = command; if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { hw_dbg(hw, "IOSF wait timed out\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -715,7 +717,8 @@ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; hw_dbg(hw, "Failed to read, error %x\n", error); - return IXGBE_ERR_PHY; + ret = -EIO; + goto out; } if (!ret) @@ -750,9 +753,9 @@ if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) return 0; if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) - return IXGBE_ERR_FW_RESP_INVALID; + return -EIO; - return IXGBE_ERR_TOKEN_RETRY; + return -EAGAIN; } /** @@ -778,7 +781,7 @@ return status; if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) return 0; - return IXGBE_ERR_FW_RESP_INVALID; + return -EIO; } /** @@ -942,7 +945,7 @@ local_buffer = buf; } else { if (buffer_size < ptr) - return IXGBE_ERR_PARAM; + return -EINVAL; local_buffer = &buffer[ptr]; } @@ -960,7 +963,7 @@ } if (buffer && ((u32)start + (u32)length > buffer_size)) - return IXGBE_ERR_PARAM; + return -EINVAL; for (i = start; length; i++, length--) { if (i == bufsz && !buffer) { @@ -1012,7 +1015,7 @@ local_buffer = eeprom_ptrs; } else { if (buffer_size < IXGBE_EEPROM_LAST_WORD) - return IXGBE_ERR_PARAM; + return -EINVAL; local_buffer = buffer; } @@ -1148,7 +1151,7 @@ * calculated checksum */ if (read_checksum != checksum) { - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; hw_dbg(hw, "Invalid EEPROM checksum"); } @@ -1203,7 +1206,7 @@ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); } else { hw_dbg(hw, "write ee hostif failed to get semaphore"); - status = IXGBE_ERR_SWFW_SYNC; + status = -EBUSY; } return status; @@ -1415,7 +1418,7 @@ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; hw_dbg(hw, "Failed to write, error %x\n", error); - return IXGBE_ERR_PHY; + return -EIO; } out: @@ -1558,7 +1561,7 @@ /* iXFI is only supported with X552 */ if (mac->type != ixgbe_mac_X550EM_x) - return IXGBE_ERR_LINK_SETUP; + return -EIO; /* Disable AN and force speed to 10G Serial. */ status = ixgbe_read_iosf_sb_reg_x550(hw, @@ -1580,7 +1583,7 @@ break; default: /* Other link speeds are not supported by internal KR PHY. */ - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; } status = ixgbe_write_iosf_sb_reg_x550(hw, @@ -1611,7 +1614,7 @@ { switch (hw->phy.sfp_type) { case ixgbe_sfp_type_not_present: - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; case ixgbe_sfp_type_da_cu_core0: case ixgbe_sfp_type_da_cu_core1: *linear = true; @@ -1630,7 +1633,7 @@ case ixgbe_sfp_type_1g_cu_core0: case ixgbe_sfp_type_1g_cu_core1: default: - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; @@ -1660,7 +1663,7 @@ * there is no reason to configure CS4227 and SFP not present error is * not accepted in the setup MAC link flow. */ - if (status == IXGBE_ERR_SFP_NOT_PRESENT) + if (status == -ENOENT) return 0; if (status) @@ -1718,7 +1721,7 @@ break; default: /* Other link speeds are not supported by internal PHY. */ - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; } status = mac->ops.write_iosf_sb_reg(hw, @@ -1753,7 +1756,7 @@ /* If no SFP module present, then return success. Return success since * SFP not present error is not excepted in the setup MAC link flow. */ - if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + if (ret_val == -ENOENT) return 0; if (ret_val) @@ -1803,7 +1806,7 @@ /* If no SFP module present, then return success. Return success since * SFP not present error is not excepted in the setup MAC link flow. */ - if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + if (ret_val == -ENOENT) return 0; if (ret_val) @@ -1813,7 +1816,7 @@ ixgbe_setup_kr_speed_x550em(hw, speed); if (hw->phy.mdio.prtad == MDIO_PRTAD_NONE) - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; /* Get external PHY SKU id */ ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, @@ -1912,7 +1915,7 @@ u16 i, autoneg_status; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) - return IXGBE_ERR_CONFIG; + return -EIO; status = ixgbe_check_mac_link_generic(hw, speed, link_up, link_up_wait_to_complete); @@ -2095,9 +2098,9 @@ */ static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) { - s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; ixgbe_link_speed speed; + s32 status = -EIO; bool link_up; /* AN should have completed when the cable was plugged in. @@ -2115,7 +2118,7 @@ /* Check if auto-negotiation has completed */ status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); if (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { - status = IXGBE_ERR_FC_NOT_NEGOTIATED; + status = -EIO; goto out; } @@ -2319,18 +2322,18 @@ * @hw: pointer to hardware structure * @lsc: pointer to boolean flag which indicates whether external Base T * PHY interrupt is lsc + * @is_overtemp: indicate whether an overtemp event encountered * * Determime if external Base T PHY interrupt cause is high temperature * failure alarm or link status change. - * - * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature - * failure alarm, else return PHY access status. **/ -static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) +static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc, + bool *is_overtemp) { u32 status; u16 reg; + *is_overtemp = false; *lsc = false; /* Vendor alarm triggered */ @@ -2362,7 +2365,8 @@ if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) { /* power down the PHY in case the PHY FW didn't already */ ixgbe_set_copper_phy_power(hw, false); - return IXGBE_ERR_OVERTEMP; + *is_overtemp = true; + return -EIO; } if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { /* device fault alarm triggered */ @@ -2376,7 +2380,8 @@ if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) { /* power down the PHY in case the PHY FW didn't */ ixgbe_set_copper_phy_power(hw, false); - return IXGBE_ERR_OVERTEMP; + *is_overtemp = true; + return -EIO; } } @@ -2412,12 +2417,12 @@ **/ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) { + bool lsc, overtemp; u32 status; u16 reg; - bool lsc; /* Clear interrupt flags */ - status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, &overtemp); /* Enable link status change alarm */ @@ -2496,21 +2501,20 @@ /** * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt * @hw: pointer to hardware structure + * @is_overtemp: indicate whether an overtemp event encountered * * Handle external Base T PHY interrupt. If high temperature * failure alarm then return error, else if link status change * then setup internal/external PHY link - * - * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature - * failure alarm, else return PHY access status. **/ -static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw) +static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw, + bool *is_overtemp) { struct ixgbe_phy_info *phy = &hw->phy; bool lsc; u32 status; - status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, is_overtemp); if (status) return status; @@ -2642,7 +2646,7 @@ u16 speed; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) - return IXGBE_ERR_CONFIG; + return -EIO; if (!(hw->mac.type == ixgbe_mac_X550EM_x && !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))) { @@ -2685,7 +2689,7 @@ break; default: /* Internal PHY does not support anything else */ - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } return ixgbe_setup_ixfi_x550em(hw, &force_speed); @@ -2717,7 +2721,7 @@ u16 phy_data; if (led_idx >= IXGBE_X557_MAX_LED_INDEX) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, @@ -2739,7 +2743,7 @@ u16 phy_data; if (led_idx >= IXGBE_X557_MAX_LED_INDEX) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, @@ -2763,8 +2767,9 @@ * * Sends driver version number to firmware through the manageability * block. On success return 0 - * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * else returns -EBUSY when encountering an error acquiring + * semaphore, -EIO when command fails or -ENIVAL when incorrect + * params passed. **/ static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, u8 sub, u16 len, @@ -2775,7 +2780,7 @@ int i; if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string))) - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; @@ -2800,7 +2805,7 @@ if (fw_cmd.hdr.cmd_or_resp.ret_status != FW_CEM_RESP_STATUS_SUCCESS) - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; return 0; } @@ -2857,7 +2862,7 @@ /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } /* 10gig parts do not have a word in the EEPROM to determine the @@ -2892,7 +2897,7 @@ break; default: hw_err(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (hw->device_id) { @@ -2936,8 +2941,8 @@ static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) { u32 link_s1, lp_an_page_low, an_cntl_1; - s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; + s32 status = -EIO; bool link_up; /* AN should have completed when the cable was plugged in. @@ -2963,7 +2968,7 @@ if (status || (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { hw_dbg(hw, "Auto-Negotiation did not complete\n"); - status = IXGBE_ERR_FC_NOT_NEGOTIATED; + status = -EIO; goto out; } @@ -3137,21 +3142,23 @@ /** * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp * @hw: pointer to hardware structure + * + * Return true when an overtemp event detected, otherwise false. */ -static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) +static bool ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) { u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; s32 rc; rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); if (rc) - return rc; + return false; if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { ixgbe_shutdown_fw_phy(hw); - return IXGBE_ERR_OVERTEMP; + return true; } - return 0; + return false; } /** @@ -3201,8 +3208,7 @@ /* Identify the PHY or SFP module */ ret_val = phy->ops.identify(hw); - if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || - ret_val == IXGBE_ERR_PHY_ADDR_INVALID) + if (ret_val == -EOPNOTSUPP || ret_val == -EFAULT) return ret_val; /* Setup function pointers based on detected hardware */ @@ -3405,10 +3411,12 @@ /* flush pending Tx transactions */ ixgbe_clear_tx_pending(hw); + /* set MDIO speed before talking to the PHY in case it's the 1st time */ + ixgbe_set_mdio_speed(hw); + /* PHY ops must be identified and initialized prior to reset */ status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || - status == IXGBE_ERR_PHY_ADDR_INVALID) + if (status == -EOPNOTSUPP || status == -EFAULT) return status; /* start the external PHY */ @@ -3424,7 +3432,7 @@ hw->phy.sfp_setup_needed = false; } - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Reset PHY */ @@ -3448,7 +3456,7 @@ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); if (status) { hw_dbg(hw, "semaphore failed with %d", status); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); @@ -3466,7 +3474,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -3562,7 +3570,7 @@ /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } if (hw->fc.requested_mode == ixgbe_fc_default) @@ -3619,7 +3627,7 @@ break; default: hw_err(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } status = hw->mac.ops.write_iosf_sb_reg(hw, @@ -3715,7 +3723,7 @@ return 0; if (hmask) ixgbe_release_swfw_sync_X540(hw, hmask); - if (status != IXGBE_ERR_TOKEN_RETRY) + if (status != -EAGAIN) return status; msleep(FW_PHY_TOKEN_DELAY); } @@ -3759,7 +3767,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -3785,7 +3793,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); hw->mac.ops.release_swfw_sync(hw, mask); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c @@ -583,12 +583,14 @@ u32 cmd_type; while (budget-- > 0) { - if (unlikely(!ixgbe_desc_unused(xdp_ring)) || - !netif_carrier_ok(xdp_ring->netdev)) { + if (unlikely(!ixgbe_desc_unused(xdp_ring))) { work_done = false; break; } + if (!netif_carrier_ok(xdp_ring->netdev)) + break; + if (!xsk_umem_consume_tx(xdp_ring->xsk_umem, &desc)) break; @@ -709,10 +711,14 @@ if (qid >= adapter->num_xdp_queues) return -ENXIO; - if (!adapter->xdp_ring[qid]->xsk_umem) + ring = adapter->xdp_ring[qid]; + + if (test_bit(__IXGBE_TX_DISABLED, &ring->state)) + return -ENETDOWN; + + if (!ring->xsk_umem) return -ENXIO; - ring = adapter->xdp_ring[qid]; if (!napi_if_scheduled_mark_missed(&ring->q_vector->napi)) { u64 eics = BIT_ULL(ring->q_vector->v_idx); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -272,6 +272,11 @@ return -EINVAL; } + if (xs->props.mode != XFRM_MODE_TRANSPORT) { + netdev_err(dev, "Unsupported mode for ipsec offload\n"); + return -EINVAL; + } + if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { struct rx_sa rsa; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -387,6 +387,8 @@ u32 *rss_key; u8 rss_indir_tbl[IXGBEVF_X550_VFRETA_SIZE]; u32 flags; + bool link_state; + #define IXGBEVF_FLAGS_LEGACY_RX BIT(1) #ifdef CONFIG_XFRM --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1079,11 +1079,14 @@ case XDP_TX: xdp_ring = adapter->xdp_ring[rx_ring->queue_index]; result = ixgbevf_xmit_xdp_ring(xdp_ring, xdp); + if (result == IXGBEVF_XDP_CONSUMED) + goto out_failure; break; default: bpf_warn_invalid_xdp_action(act); /* fallthrough */ case XDP_ABORTED: +out_failure: trace_xdp_exception(rx_ring->netdev, xdp_prog, act); /* fallthrough -- handle aborts by dropping packet */ case XDP_DROP: @@ -1976,14 +1979,15 @@ if (adapter->flags & IXGBEVF_FLAGS_LEGACY_RX) return; - set_ring_build_skb_enabled(rx_ring); + if (PAGE_SIZE < 8192) + if (max_frame > IXGBEVF_MAX_FRAME_BUILD_SKB) + set_ring_uses_large_buffer(rx_ring); - if (PAGE_SIZE < 8192) { - if (max_frame <= IXGBEVF_MAX_FRAME_BUILD_SKB) - return; + /* 82599 can't rely on RXDCTL.RLPML to restrict the size of the frame */ + if (adapter->hw.mac.type == ixgbe_mac_82599_vf && !ring_uses_large_buffer(rx_ring)) + return; - set_ring_uses_large_buffer(rx_ring); - } + set_ring_build_skb_enabled(rx_ring); } /** @@ -2081,11 +2085,6 @@ struct ixgbe_hw *hw = &adapter->hw; int count = 0; - if ((netdev_uc_count(netdev)) > 10) { - pr_err("Too many unicast filters - No Space\n"); - return -ENOSPC; - } - if (!netdev_uc_empty(netdev)) { struct netdev_hw_addr *ha; @@ -2287,7 +2286,9 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; struct ixgbe_hw *hw = &adapter->hw; + bool state; ixgbevf_configure_msix(adapter); @@ -2300,6 +2301,11 @@ spin_unlock_bh(&adapter->mbx_lock); + state = adapter->link_state; + hw->mac.ops.get_link_state(hw, &adapter->link_state); + if (state && state != adapter->link_state) + dev_info(&pdev->dev, "VF is administratively disabled\n"); + smp_mb__before_atomic(); clear_bit(__IXGBEVF_DOWN, &adapter->state); ixgbevf_napi_enable_all(adapter); @@ -3070,6 +3076,8 @@ adapter->tx_ring_count = IXGBEVF_DEFAULT_TXD; adapter->rx_ring_count = IXGBEVF_DEFAULT_RXD; + adapter->link_state = true; + set_bit(__IXGBEVF_DOWN, &adapter->state); return 0; @@ -3302,7 +3310,7 @@ ixgbevf_watchdog_update_link(adapter); - if (adapter->link_up) + if (adapter->link_up && adapter->link_state) ixgbevf_watchdog_link_is_up(adapter); else ixgbevf_watchdog_link_is_down(adapter); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/mbx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/mbx.h @@ -51,6 +51,16 @@ /* bits 23:16 are used for exra info for certain messages */ #define IXGBE_VT_MSGINFO_MASK (0xFF << IXGBE_VT_MSGINFO_SHIFT) +/* IXGBE_VT_MSGTYPE_NACK and IXGBE_VT_MSGTYPE_ACK were renamed to + * IXGBE_VT_MSGTYPE_FAILURE and IXGBE_VT_MSGTYPE_SUCCESS respectively + * with commit 0edbecd57057 upstream. + * + * One of the backported fixes use them with their new names. These + * aliases enable them to work with both older and newer names. + */ +#define IXGBE_VT_MSGTYPE_SUCCESS IXGBE_VT_MSGTYPE_ACK +#define IXGBE_VT_MSGTYPE_FAILURE IXGBE_VT_MSGTYPE_NACK + /* definitions to support mailbox API version negotiation */ /* each element denotes a version of the API; existing numbers may not @@ -97,6 +107,8 @@ #define IXGBE_VF_IPSEC_ADD 0x0d #define IXGBE_VF_IPSEC_DEL 0x0e +#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */ + /* length of permanent address message returned from PF */ #define IXGBE_VF_PERMADDR_MSG_LEN 4 /* word in permanent address message with the current multicast type */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/vf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -574,6 +574,46 @@ } /** + * ixgbevf_get_link_state_vf - Get VF link state from PF + * @hw: pointer to the HW structure + * @link_state: link state storage + * + * Returns state of the operation error or success. + */ +static s32 ixgbevf_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state) +{ + u32 msgbuf[2]; + s32 ret_val; + s32 err; + + msgbuf[0] = IXGBE_VF_GET_LINK_STATE; + msgbuf[1] = 0x0; + + err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2); + + if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) { + ret_val = IXGBE_ERR_MBX; + } else { + ret_val = 0; + *link_state = msgbuf[1]; + } + + return ret_val; +} + +/** + * ixgbevf_hv_get_link_state_vf - * Hyper-V variant - just a stub. + * @hw: unused + * @link_state: unused + * + * Hyper-V variant; there is no mailbox communication. + */ +static s32 ixgbevf_hv_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state) +{ + return -EOPNOTSUPP; +} + +/** * ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address * @hw: pointer to the HW structure * @vlan: 12 bit VLAN ID @@ -950,6 +990,7 @@ .set_rar = ixgbevf_set_rar_vf, .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, .update_xcast_mode = ixgbevf_update_xcast_mode, + .get_link_state = ixgbevf_get_link_state_vf, .set_uc_addr = ixgbevf_set_uc_addr_vf, .set_vfta = ixgbevf_set_vfta_vf, .set_rlpml = ixgbevf_set_rlpml_vf, @@ -967,6 +1008,7 @@ .set_rar = ixgbevf_hv_set_rar_vf, .update_mc_addr_list = ixgbevf_hv_update_mc_addr_list_vf, .update_xcast_mode = ixgbevf_hv_update_xcast_mode, + .get_link_state = ixgbevf_hv_get_link_state_vf, .set_uc_addr = ixgbevf_hv_set_uc_addr_vf, .set_vfta = ixgbevf_hv_set_vfta_vf, .set_rlpml = ixgbevf_hv_set_rlpml_vf, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/intel/ixgbevf/vf.h +++ linux-oracle-5.4.0/drivers/net/ethernet/intel/ixgbevf/vf.h @@ -42,6 +42,7 @@ s32 (*init_rx_addrs)(struct ixgbe_hw *); s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*update_xcast_mode)(struct ixgbe_hw *, int); + s32 (*get_link_state)(struct ixgbe_hw *hw, bool *link_state); s32 (*enable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/jme.c +++ linux-oracle-5.4.0/drivers/net/ethernet/jme.c @@ -947,15 +947,13 @@ if (skb->protocol != htons(ETH_P_IP)) return csum; skb_set_network_header(skb, ETH_HLEN); - if ((ip_hdr(skb)->protocol != IPPROTO_UDP) || - (skb->len < (ETH_HLEN + - (ip_hdr(skb)->ihl << 2) + - sizeof(struct udphdr)))) { + + if (ip_hdr(skb)->protocol != IPPROTO_UDP || + skb->len < (ETH_HLEN + ip_hdrlen(skb) + sizeof(struct udphdr))) { skb_reset_network_header(skb); return csum; } - skb_set_transport_header(skb, - ETH_HLEN + (ip_hdr(skb)->ihl << 2)); + skb_set_transport_header(skb, ETH_HLEN + ip_hdrlen(skb)); csum = udp_hdr(skb)->check; skb_reset_transport_header(skb); skb_reset_network_header(skb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/korina.c +++ linux-oracle-5.4.0/drivers/net/ethernet/korina.c @@ -219,7 +219,7 @@ dev_kfree_skb_any(skb); spin_unlock_irqrestore(&lp->lock, flags); - return NETDEV_TX_BUSY; + return NETDEV_TX_OK; } } @@ -1113,7 +1113,7 @@ return rc; probe_err_register: - kfree(lp->td_ring); + kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring)); probe_err_td_ring: iounmap(lp->tx_dma_regs); probe_err_dma_tx: @@ -1133,6 +1133,7 @@ iounmap(lp->eth_regs); iounmap(lp->rx_dma_regs); iounmap(lp->tx_dma_regs); + kfree((struct dma_desc *)KSEG0ADDR(lp->td_ring)); unregister_netdev(bif->dev); free_netdev(bif->dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/lantiq_etop.c +++ linux-oracle-5.4.0/drivers/net/ethernet/lantiq_etop.c @@ -213,8 +213,9 @@ if (ch->dma.irq) free_irq(ch->dma.irq, priv); if (IS_RX(ch->idx)) { - int desc; - for (desc = 0; desc < LTQ_DESC_NUM; desc++) + struct ltq_dma_channel *dma = &ch->dma; + + for (dma->desc = 0; dma->desc < LTQ_DESC_NUM; dma->desc++) dev_kfree_skb_any(ch->skb[ch->dma.desc]); } } @@ -463,10 +464,11 @@ unsigned long flags; u32 byte_offset; - len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; + if (skb_put_padto(skb, ETH_ZLEN)) + return NETDEV_TX_OK; + len = skb->len; if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { - dev_kfree_skb_any(skb); netdev_err(dev, "tx ring full\n"); netif_tx_stop_queue(txq); return NETDEV_TX_BUSY; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/lantiq_xrx200.c +++ linux-oracle-5.4.0/drivers/net/ethernet/lantiq_xrx200.c @@ -154,6 +154,8 @@ static int xrx200_alloc_skb(struct xrx200_chan *ch) { + struct sk_buff *skb = ch->skb[ch->dma.desc]; + dma_addr_t mapping; int ret = 0; ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev, @@ -163,16 +165,18 @@ goto skip; } - ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(ch->priv->dev, - ch->skb[ch->dma.desc]->data, XRX200_DMA_DATA_LEN, - DMA_FROM_DEVICE); - if (unlikely(dma_mapping_error(ch->priv->dev, - ch->dma.desc_base[ch->dma.desc].addr))) { + mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data, + XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) { dev_kfree_skb_any(ch->skb[ch->dma.desc]); + ch->skb[ch->dma.desc] = skb; ret = -ENOMEM; goto skip; } + ch->dma.desc_base[ch->dma.desc].addr = mapping; + /* Make sure the address is written before we give it to HW */ + wmb(); skip: ch->dma.desc_base[ch->dma.desc].ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | @@ -196,6 +200,7 @@ ch->dma.desc %= LTQ_DESC_NUM; if (ret) { + net_dev->stats.rx_dropped++; netdev_err(net_dev, "failed to allocate new rx buffer\n"); return ret; } @@ -204,7 +209,7 @@ skb->protocol = eth_type_trans(skb, net_dev); netif_receive_skb(skb); net_dev->stats.rx_packets++; - net_dev->stats.rx_bytes += len - ETH_FCS_LEN; + net_dev->stats.rx_bytes += len; return 0; } @@ -230,8 +235,8 @@ } if (rx < budget) { - napi_complete(&ch->napi); - ltq_dma_enable_irq(&ch->dma); + if (napi_complete_done(&ch->napi, rx)) + ltq_dma_enable_irq(&ch->dma); } return rx; @@ -245,6 +250,7 @@ int pkts = 0; int bytes = 0; + netif_tx_lock(net_dev); while (pkts < budget) { struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->tx_free]; @@ -268,9 +274,13 @@ net_dev->stats.tx_bytes += bytes; netdev_completed_queue(ch->priv->net_dev, pkts, bytes); + netif_tx_unlock(net_dev); + if (netif_queue_stopped(net_dev)) + netif_wake_queue(net_dev); + if (pkts < budget) { - napi_complete(&ch->napi); - ltq_dma_enable_irq(&ch->dma); + if (napi_complete_done(&ch->napi, pkts)) + ltq_dma_enable_irq(&ch->dma); } return pkts; @@ -341,10 +351,12 @@ { struct xrx200_chan *ch = ptr; - ltq_dma_disable_irq(&ch->dma); - ltq_dma_ack_irq(&ch->dma); + if (napi_schedule_prep(&ch->napi)) { + ltq_dma_disable_irq(&ch->dma); + __napi_schedule(&ch->napi); + } - napi_schedule(&ch->napi); + ltq_dma_ack_irq(&ch->dma); return IRQ_HANDLED; } @@ -498,7 +510,7 @@ /* setup NAPI */ netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx, 32); - netif_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping, 32); + netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping, 32); platform_set_drvdata(pdev, priv); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mv643xx_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -2476,6 +2476,7 @@ for (i = 0; i < mp->rxq_count; i++) rxq_deinit(mp->rxq + i); out: + napi_disable(&mp->napi); free_irq(dev->irq, dev); return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvneta.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvneta.c @@ -101,12 +101,14 @@ #define MVNETA_DESC_SWAP BIT(6) #define MVNETA_TX_BRST_SZ_MASK(burst) ((burst) << 22) #define MVNETA_PORT_STATUS 0x2444 -#define MVNETA_TX_IN_PRGRS BIT(1) +#define MVNETA_TX_IN_PRGRS BIT(0) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c +/* Only exists on Armada XP and Armada 370 */ #define MVNETA_SERDES_CFG 0x24A0 #define MVNETA_SGMII_SERDES_PROTO 0x0cc7 #define MVNETA_QSGMII_SERDES_PROTO 0x0667 +#define MVNETA_HSGMII_SERDES_PROTO 0x1107 #define MVNETA_TYPE_PRIO 0x24bc #define MVNETA_FORCE_UNI BIT(21) #define MVNETA_TXQ_CMD_1 0x24e4 @@ -388,6 +390,8 @@ struct u64_stats_sync syncp; u64 rx_packets; u64 rx_bytes; + u64 rx_dropped; + u64 rx_errors; u64 tx_packets; u64 tx_bytes; }; @@ -545,6 +549,20 @@ }; #endif +enum mvneta_tx_buf_type { + MVNETA_TYPE_SKB, + MVNETA_TYPE_XDP_TX, + MVNETA_TYPE_XDP_NDO, +}; + +struct mvneta_tx_buf { + enum mvneta_tx_buf_type type; + union { + struct xdp_frame *xdpf; + struct sk_buff *skb; + }; +}; + struct mvneta_tx_queue { /* Number of this TX queue, in the range 0-7 */ u8 id; @@ -560,8 +578,8 @@ int tx_stop_threshold; int tx_wake_threshold; - /* Array of transmitted skb */ - struct sk_buff **tx_skb; + /* Array of transmitted buffers */ + struct mvneta_tx_buf *buf; /* Index of last TX DMA descriptor that was inserted */ int txq_put_index; @@ -706,6 +724,8 @@ struct mvneta_pcpu_stats *cpu_stats; u64 rx_packets; u64 rx_bytes; + u64 rx_dropped; + u64 rx_errors; u64 tx_packets; u64 tx_bytes; @@ -714,19 +734,20 @@ start = u64_stats_fetch_begin_irq(&cpu_stats->syncp); rx_packets = cpu_stats->rx_packets; rx_bytes = cpu_stats->rx_bytes; + rx_dropped = cpu_stats->rx_dropped; + rx_errors = cpu_stats->rx_errors; tx_packets = cpu_stats->tx_packets; tx_bytes = cpu_stats->tx_bytes; } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start)); stats->rx_packets += rx_packets; stats->rx_bytes += rx_bytes; + stats->rx_dropped += rx_dropped; + stats->rx_errors += rx_errors; stats->tx_packets += tx_packets; stats->tx_bytes += tx_bytes; } - stats->rx_errors = dev->stats.rx_errors; - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; } @@ -1401,7 +1422,7 @@ */ if (txq_number == 1) txq_map = (cpu == pp->rxq_def) ? - MVNETA_CPU_TXQ_ACCESS(1) : 0; + MVNETA_CPU_TXQ_ACCESS(0) : 0; } else { txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; @@ -1703,8 +1724,14 @@ static void mvneta_rx_error(struct mvneta_port *pp, struct mvneta_rx_desc *rx_desc) { + struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats); u32 status = rx_desc->status; + /* update per-cpu counter */ + u64_stats_update_begin(&stats->syncp); + stats->rx_errors++; + u64_stats_update_end(&stats->syncp); + switch (status & MVNETA_RXD_ERR_CODE_MASK) { case MVNETA_RXD_ERR_CRC: netdev_err(pp->dev, "bad rx status %08x (crc error), size=%d\n", @@ -1761,14 +1788,9 @@ int i; for (i = 0; i < num; i++) { + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_get_index]; struct mvneta_tx_desc *tx_desc = txq->descs + txq->txq_get_index; - struct sk_buff *skb = txq->tx_skb[txq->txq_get_index]; - - if (skb) { - bytes_compl += skb->len; - pkts_compl++; - } mvneta_txq_inc_get(txq); @@ -1776,9 +1798,12 @@ dma_unmap_single(pp->dev->dev.parent, tx_desc->buf_phys_addr, tx_desc->data_size, DMA_TO_DEVICE); - if (!skb) + if (!buf->skb) continue; - dev_kfree_skb_any(skb); + + bytes_compl += buf->skb->len; + pkts_compl++; + dev_kfree_skb_any(buf->skb); } netdev_tx_completed_queue(nq, pkts_compl, bytes_compl); @@ -1965,7 +1990,6 @@ /* Check errors only for FIRST descriptor */ if (rx_status & MVNETA_RXD_ERR_SUMMARY) { mvneta_rx_error(pp, rx_desc); - dev->stats.rx_errors++; /* leave the descriptor untouched */ continue; } @@ -1976,11 +2000,17 @@ skb_size = max(rx_copybreak, rx_header_size); rxq->skb = netdev_alloc_skb_ip_align(dev, skb_size); if (unlikely(!rxq->skb)) { + struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats); + netdev_err(dev, "Can't allocate skb on queue %d\n", rxq->id); - dev->stats.rx_dropped++; + rxq->skb_alloc_err++; + + u64_stats_update_begin(&stats->syncp); + stats->rx_dropped++; + u64_stats_update_end(&stats->syncp); continue; } copy_size = min(skb_size, rx_bytes); @@ -2137,7 +2167,6 @@ mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool, rx_desc->buf_phys_addr); err_drop_frame: - dev->stats.rx_errors++; mvneta_rx_error(pp, rx_desc); /* leave the descriptor untouched */ continue; @@ -2225,16 +2254,19 @@ mvneta_tso_put_hdr(struct sk_buff *skb, struct mvneta_port *pp, struct mvneta_tx_queue *txq) { - struct mvneta_tx_desc *tx_desc; int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; + struct mvneta_tx_desc *tx_desc; - txq->tx_skb[txq->txq_put_index] = NULL; tx_desc = mvneta_txq_next_desc_get(txq); tx_desc->data_size = hdr_len; tx_desc->command = mvneta_skb_tx_csum(pp, skb); tx_desc->command |= MVNETA_TXD_F_DESC; tx_desc->buf_phys_addr = txq->tso_hdrs_phys + txq->txq_put_index * TSO_HEADER_SIZE; + buf->type = MVNETA_TYPE_SKB; + buf->skb = NULL; + mvneta_txq_inc_put(txq); } @@ -2243,6 +2275,7 @@ struct sk_buff *skb, char *data, int size, bool last_tcp, bool is_last) { + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; struct mvneta_tx_desc *tx_desc; tx_desc = mvneta_txq_next_desc_get(txq); @@ -2256,7 +2289,8 @@ } tx_desc->command = 0; - txq->tx_skb[txq->txq_put_index] = NULL; + buf->type = MVNETA_TYPE_SKB; + buf->skb = NULL; if (last_tcp) { /* last descriptor in the TCP packet */ @@ -2264,7 +2298,7 @@ /* last descriptor in SKB */ if (is_last) - txq->tx_skb[txq->txq_put_index] = skb; + buf->skb = skb; } mvneta_txq_inc_put(txq); return 0; @@ -2349,6 +2383,7 @@ int i, nr_frags = skb_shinfo(skb)->nr_frags; for (i = 0; i < nr_frags; i++) { + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; void *addr = skb_frag_address(frag); @@ -2368,12 +2403,13 @@ if (i == nr_frags - 1) { /* Last descriptor */ tx_desc->command = MVNETA_TXD_L_DESC | MVNETA_TXD_Z_PAD; - txq->tx_skb[txq->txq_put_index] = skb; + buf->skb = skb; } else { /* Descriptor in the middle: Not First, Not Last */ tx_desc->command = 0; - txq->tx_skb[txq->txq_put_index] = NULL; + buf->skb = NULL; } + buf->type = MVNETA_TYPE_SKB; mvneta_txq_inc_put(txq); } @@ -2401,6 +2437,7 @@ struct mvneta_port *pp = netdev_priv(dev); u16 txq_id = skb_get_queue_mapping(skb); struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_buf *buf = &txq->buf[txq->txq_put_index]; struct mvneta_tx_desc *tx_desc; int len = skb->len; int frags = 0; @@ -2433,16 +2470,17 @@ goto out; } + buf->type = MVNETA_TYPE_SKB; if (frags == 1) { /* First and Last descriptor */ tx_cmd |= MVNETA_TXD_FLZ_DESC; tx_desc->command = tx_cmd; - txq->tx_skb[txq->txq_put_index] = skb; + buf->skb = skb; mvneta_txq_inc_put(txq); } else { /* First but not Last */ tx_cmd |= MVNETA_TXD_F_DESC; - txq->tx_skb[txq->txq_put_index] = NULL; + buf->skb = NULL; mvneta_txq_inc_put(txq); tx_desc->command = tx_cmd; /* Continue with other skb fragments */ @@ -2789,11 +2827,10 @@ /* For the case where the last mvneta_poll did not process all * RX packets */ - rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); - cause_rx_tx |= pp->neta_armada3700 ? pp->cause_rx_tx : port->cause_rx_tx; + rx_queue = fls(((cause_rx_tx >> 8) & 0xff)); if (rx_queue) { rx_queue = rx_queue - 1; if (pp->bm_priv) @@ -2989,9 +3026,8 @@ txq->last_desc = txq->size - 1; - txq->tx_skb = kmalloc_array(txq->size, sizeof(*txq->tx_skb), - GFP_KERNEL); - if (!txq->tx_skb) { + txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL); + if (!txq->buf) { dma_free_coherent(pp->dev->dev.parent, txq->size * MVNETA_DESC_ALIGNED_SIZE, txq->descs, txq->descs_phys); @@ -3003,7 +3039,7 @@ txq->size * TSO_HEADER_SIZE, &txq->tso_hdrs_phys, GFP_KERNEL); if (!txq->tso_hdrs) { - kfree(txq->tx_skb); + kfree(txq->buf); dma_free_coherent(pp->dev->dev.parent, txq->size * MVNETA_DESC_ALIGNED_SIZE, txq->descs, txq->descs_phys); @@ -3011,7 +3047,9 @@ } /* Setup XPS mapping */ - if (txq_number > 1) + if (pp->neta_armada3700) + cpu = 0; + else if (txq_number > 1) cpu = txq->id % num_present_cpus(); else cpu = pp->rxq_def % num_present_cpus(); @@ -3056,7 +3094,7 @@ { struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id); - kfree(txq->tx_skb); + kfree(txq->buf); if (txq->tso_hdrs) dma_free_coherent(pp->dev->dev.parent, @@ -3150,26 +3188,60 @@ return 0; } -static int mvneta_comphy_init(struct mvneta_port *pp) +static int mvneta_comphy_init(struct mvneta_port *pp, phy_interface_t interface) { int ret; - if (!pp->comphy) - return 0; - - ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, - pp->phy_interface); + ret = phy_set_mode_ext(pp->comphy, PHY_MODE_ETHERNET, interface); if (ret) return ret; return phy_power_on(pp->comphy); } +static int mvneta_config_interface(struct mvneta_port *pp, + phy_interface_t interface) +{ + int ret = 0; + + if (pp->comphy) { + if (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_1000BASEX || + interface == PHY_INTERFACE_MODE_2500BASEX) { + ret = mvneta_comphy_init(pp, interface); + } + } else { + switch (interface) { + case PHY_INTERFACE_MODE_QSGMII: + mvreg_write(pp, MVNETA_SERDES_CFG, + MVNETA_QSGMII_SERDES_PROTO); + break; + + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + mvreg_write(pp, MVNETA_SERDES_CFG, + MVNETA_SGMII_SERDES_PROTO); + break; + + case PHY_INTERFACE_MODE_2500BASEX: + mvreg_write(pp, MVNETA_SERDES_CFG, + MVNETA_HSGMII_SERDES_PROTO); + break; + default: + break; + } + } + + pp->phy_interface = interface; + + return ret; +} + static void mvneta_start_dev(struct mvneta_port *pp) { int cpu; - WARN_ON(mvneta_comphy_init(pp)); + WARN_ON(mvneta_config_interface(pp, pp->phy_interface)); mvneta_max_rx_size_set(pp, pp->pkt_size); mvneta_txq_max_tx_size_set(pp, pp->pkt_size); @@ -3544,17 +3616,13 @@ /* When at 2.5G, the link partner can send frames with shortened * preambles. */ - if (state->speed == SPEED_2500) + if (state->interface == PHY_INTERFACE_MODE_2500BASEX) new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; - if (pp->comphy && pp->phy_interface != state->interface && - (state->interface == PHY_INTERFACE_MODE_SGMII || - state->interface == PHY_INTERFACE_MODE_1000BASEX || - state->interface == PHY_INTERFACE_MODE_2500BASEX)) { - pp->phy_interface = state->interface; - - WARN_ON(phy_power_off(pp->comphy)); - WARN_ON(mvneta_comphy_init(pp)); + if (pp->phy_interface != state->interface) { + if (pp->comphy) + WARN_ON(phy_power_off(pp->comphy)); + WARN_ON(mvneta_config_interface(pp, state->interface)); } if (new_ctrl0 != gmac_ctrl0) @@ -3669,7 +3737,7 @@ /* Use the cpu associated to the rxq when it is online, in all * the other cases, use the cpu 0 which can't be offline. */ - if (cpu_online(pp->rxq_def)) + if (pp->rxq_def < nr_cpu_ids && cpu_online(pp->rxq_def)) elected_cpu = pp->rxq_def; max_cpu = num_present_cpus(); @@ -3694,7 +3762,7 @@ */ if (txq_number == 1) txq_map = (cpu == elected_cpu) ? - MVNETA_CPU_TXQ_ACCESS(1) : 0; + MVNETA_CPU_TXQ_ACCESS(0) : 0; else txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & MVNETA_CPU_TXQ_ACCESS_ALL_MASK; @@ -3718,6 +3786,11 @@ node_online); struct mvneta_pcpu_port *port = per_cpu_ptr(pp->ports, cpu); + /* Armada 3700's per-cpu interrupt for mvneta is broken, all interrupts + * are routed to CPU 0, so we don't need all the cpu-hotplug support + */ + if (pp->neta_armada3700) + return 0; spin_lock(&pp->lock); /* @@ -4455,12 +4528,10 @@ /* MAC Cause register should be cleared */ mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); - if (phy_mode == PHY_INTERFACE_MODE_QSGMII) - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); - else if (phy_mode == PHY_INTERFACE_MODE_SGMII || - phy_interface_mode_is_8023z(phy_mode)) - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); - else if (!phy_interface_mode_is_rgmii(phy_mode)) + if (phy_mode != PHY_INTERFACE_MODE_QSGMII && + phy_mode != PHY_INTERFACE_MODE_SGMII && + !phy_interface_mode_is_8023z(phy_mode) && + !phy_interface_mode_is_rgmii(phy_mode)) return -EINVAL; return 0; @@ -4647,7 +4718,7 @@ if (err < 0) goto err_netdev; - err = mvneta_port_power_up(pp, phy_mode); + err = mvneta_port_power_up(pp, pp->phy_interface); if (err < 0) { dev_err(&pdev->dev, "can't power up port\n"); goto err_netdev; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -809,7 +809,7 @@ unsigned int max_port_rxqs; /* Workqueue to gather hardware statistics */ - char queue_name[30]; + char queue_name[31]; struct workqueue_struct *stats_queue; /* Debugfs root entry */ @@ -1202,5 +1202,6 @@ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name); void mvpp2_dbgfs_cleanup(struct mvpp2 *priv); +void mvpp2_dbgfs_exit(void); #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -318,7 +318,7 @@ MVPP2_PRS_RI_VLAN_MASK), /* Non IP flow, with vlan tag */ MVPP2_DEF_FLOW(MVPP22_FLOW_ETHERNET, MVPP2_FL_NON_IP_TAG, - MVPP22_CLS_HEK_OPT_VLAN, + MVPP22_CLS_HEK_TAGGED, 0, 0), }; @@ -1070,7 +1070,7 @@ (port->first_rxq >> MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS)); val = mvpp2_read(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG); - val |= MVPP2_CLS_SWFWD_PCTRL_MASK(port->id); + val &= ~MVPP2_CLS_SWFWD_PCTRL_MASK(port->id); mvpp2_write(port->priv, MVPP2_CLS_SWFWD_PCTRL_REG, val); } @@ -1422,6 +1422,9 @@ struct mvpp2_ethtool_fs *efs; int ret; + if (info->fs.location >= MVPP2_N_RFS_ENTRIES_PER_FLOW) + return -EINVAL; + efs = port->rfs_rules[info->fs.location]; if (!efs) return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c @@ -691,6 +691,13 @@ return 0; } +static struct dentry *mvpp2_root; + +void mvpp2_dbgfs_exit(void) +{ + debugfs_remove(mvpp2_root); +} + void mvpp2_dbgfs_cleanup(struct mvpp2 *priv) { debugfs_remove_recursive(priv->dbgfs_dir); @@ -700,10 +707,9 @@ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name) { - struct dentry *mvpp2_dir, *mvpp2_root; + struct dentry *mvpp2_dir; int ret, i; - mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL); if (!mvpp2_root) mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1073,7 +1073,7 @@ u32 val; /* If the thread isn't used, don't do anything */ - if (smp_processor_id() > port->priv->nthreads) + if (smp_processor_id() >= port->priv->nthreads) return; val = MVPP2_CAUSE_MISC_SUM_MASK | @@ -1129,7 +1129,7 @@ regmap_read(priv->sysctrl_base, GENCONF_CTRL0, &val); if (port->gop_id == 2) - val |= GENCONF_CTRL0_PORT0_RGMII | GENCONF_CTRL0_PORT1_RGMII; + val |= GENCONF_CTRL0_PORT0_RGMII; else if (port->gop_id == 3) val |= GENCONF_CTRL0_PORT1_RGMII_MII; regmap_write(priv->sysctrl_base, GENCONF_CTRL0, val); @@ -1541,7 +1541,7 @@ for (q = 0; q < port->ntxqs; q++) for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) *pstats++ += mvpp2_read_index(port->priv, - MVPP22_CTRS_TX_CTR(port->id, i), + MVPP22_CTRS_TX_CTR(port->id, q), mvpp2_ethtool_txq_regs[i].offset); /* Rxqs are numbered from 0 from the user standpoint, but not from the @@ -1550,7 +1550,7 @@ for (q = 0; q < port->nrxqs; q++) for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) *pstats++ += mvpp2_read_index(port->priv, - port->first_rxq + i, + port->first_rxq + q, mvpp2_ethtool_rxq_regs[i].offset); } @@ -2078,7 +2078,7 @@ int queue; /* If the thread isn't used, don't do anything */ - if (smp_processor_id() > port->priv->nthreads) + if (smp_processor_id() >= port->priv->nthreads) return; for (queue = 0; queue < port->ntxqs; queue++) { @@ -2161,17 +2161,18 @@ static void mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_tx_queue *txq) { - unsigned int thread = mvpp2_cpu_to_thread(port->priv, get_cpu()); + unsigned int thread; u32 val; if (txq->done_pkts_coal > MVPP2_TXQ_THRESH_MASK) txq->done_pkts_coal = MVPP2_TXQ_THRESH_MASK; val = (txq->done_pkts_coal << MVPP2_TXQ_THRESH_OFFSET); - mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); - mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); - - put_cpu(); + /* PKT-coalescing registers are per-queue + per-thread */ + for (thread = 0; thread < MVPP2_MAX_THREADS; thread++) { + mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_NUM_REG, txq->id); + mvpp2_thread_write(port->priv, thread, MVPP2_TXQ_THRESH_REG, val); + } } static u32 mvpp2_usec_to_cycles(u32 usec, unsigned long clk_hz) @@ -3674,7 +3675,7 @@ valid = true; } - if (priv->hw_version == MVPP22 && port->link_irq && !port->phylink) { + if (priv->hw_version == MVPP22 && port->link_irq) { err = request_irq(port->link_irq, mvpp2_link_status_isr, 0, dev->name, port); if (err) { @@ -3696,6 +3697,7 @@ if (!valid) { netdev_err(port->dev, "invalid configuration: no dt or link IRQ"); + err = -ENOENT; goto err_free_irq; } @@ -4231,6 +4233,11 @@ break; case ETHTOOL_GRXCLSRLALL: for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { + if (loc == info->rule_cnt) { + ret = -EMSGSIZE; + break; + } + if (port->rfs_rules[i]) rules[loc++] = i; } @@ -4319,6 +4326,8 @@ if (!mvpp22_rss_is_supported()) return -EOPNOTSUPP; + if (rss_context >= MVPP22_N_RSS_TABLES) + return -EINVAL; if (hfunc) *hfunc = ETH_RSS_HASH_CRC32; @@ -4742,12 +4751,16 @@ eth_hw_addr_random(dev); } +static struct mvpp2_port *mvpp2_phylink_to_port(struct phylink_config *config) +{ + return container_of(config, struct mvpp2_port, phylink_config); +} + static void mvpp2_phylink_validate(struct phylink_config *config, unsigned long *supported, struct phylink_link_state *state) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; /* Invalid combinations */ @@ -4770,8 +4783,6 @@ phylink_set(mask, Autoneg); phylink_set_port_modes(mask); - phylink_set(mask, Pause); - phylink_set(mask, Asym_Pause); switch (state->interface) { case PHY_INTERFACE_MODE_10GKR: @@ -4874,8 +4885,7 @@ static int mvpp2_phylink_mac_link_state(struct phylink_config *config, struct phylink_link_state *state) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); if (port->priv->hw_version == MVPP22 && port->gop_id == 0) { u32 mode = readl(port->base + MVPP22_XLG_CTRL3_REG); @@ -4893,8 +4903,7 @@ static void mvpp2_mac_an_restart(struct phylink_config *config) { - struct mvpp2_port *port = container_of(config, struct mvpp2_port, - phylink_config); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); u32 val = readl(port->base + MVPP2_GMAC_AUTONEG_CONFIG); writel(val | MVPP2_GMAC_IN_BAND_RESTART_AN, @@ -5082,13 +5091,12 @@ static void mvpp2_mac_config(struct phylink_config *config, unsigned int mode, const struct phylink_link_state *state) { - struct net_device *dev = to_net_dev(config->dev); - struct mvpp2_port *port = netdev_priv(dev); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); bool change_interface = port->phy_interface != state->interface; /* Check for invalid configuration */ if (mvpp2_is_xlg(state->interface) && port->gop_id != 0) { - netdev_err(dev, "Invalid mode on %s\n", dev->name); + netdev_err(port->dev, "Invalid mode on %s\n", port->dev->name); return; } @@ -5125,8 +5133,7 @@ static void mvpp2_mac_link_up(struct phylink_config *config, unsigned int mode, phy_interface_t interface, struct phy_device *phy) { - struct net_device *dev = to_net_dev(config->dev); - struct mvpp2_port *port = netdev_priv(dev); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); u32 val; if (!phylink_autoneg_inband(mode)) { @@ -5147,14 +5154,13 @@ mvpp2_egress_enable(port); mvpp2_ingress_enable(port); - netif_tx_wake_all_queues(dev); + netif_tx_wake_all_queues(port->dev); } static void mvpp2_mac_link_down(struct phylink_config *config, unsigned int mode, phy_interface_t interface) { - struct net_device *dev = to_net_dev(config->dev); - struct mvpp2_port *port = netdev_priv(dev); + struct mvpp2_port *port = mvpp2_phylink_to_port(config); u32 val; if (!phylink_autoneg_inband(mode)) { @@ -5171,7 +5177,7 @@ } } - netif_tx_stop_all_queues(dev); + netif_tx_stop_all_queues(port->dev); mvpp2_egress_disable(port); mvpp2_ingress_disable(port); @@ -5727,6 +5733,10 @@ return PTR_ERR(priv->lms_base); } else { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } if (has_acpi_companion(&pdev->dev)) { /* In case the MDIO memory region is declared in * the ACPI, it can already appear as 'in-use' @@ -5768,7 +5778,7 @@ shared = num_present_cpus() - priv->nthreads; if (shared > 0) - bitmap_fill(&priv->lock_map, + bitmap_set(&priv->lock_map, 0, min_t(int, shared, MVPP2_MAX_THREADS)); for (i = 0; i < MVPP2_MAX_THREADS; i++) { @@ -5897,6 +5907,8 @@ return 0; err_port_probe: + fwnode_handle_put(port_fwnode); + i = 0; fwnode_for_each_available_child_node(fwnode, port_fwnode) { if (priv->port_list[i]) @@ -5923,8 +5935,8 @@ { struct mvpp2 *priv = platform_get_drvdata(pdev); struct fwnode_handle *fwnode = pdev->dev.fwnode; + int i = 0, poolnum = MVPP2_BM_POOLS_NUM; struct fwnode_handle *port_fwnode; - int i = 0; mvpp2_dbgfs_cleanup(priv); @@ -5938,7 +5950,10 @@ destroy_workqueue(priv->stats_queue); - for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { + if (priv->percpu_pools) + poolnum = mvpp2_get_nrxqs(priv) * 2; + + for (i = 0; i < poolnum; i++) { struct mvpp2_bm_pool *bm_pool = &priv->bm_pools[i]; mvpp2_bm_pool_destroy(&pdev->dev, priv, bm_pool); @@ -5994,7 +6009,18 @@ }, }; -module_platform_driver(mvpp2_driver); +static int __init mvpp2_driver_init(void) +{ + return platform_driver_register(&mvpp2_driver); +} +module_init(mvpp2_driver_init); + +static void __exit mvpp2_driver_exit(void) +{ + platform_driver_unregister(&mvpp2_driver); + mvpp2_dbgfs_exit(); +} +module_exit(mvpp2_driver_exit); MODULE_DESCRIPTION("Marvell PPv2 Ethernet Driver - www.marvell.com"); MODULE_AUTHOR("Marcin Wojtas "); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c @@ -29,16 +29,16 @@ /* Clear entry invalidation bit */ pe->tcam[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK; - /* Write tcam index - indirect access */ - mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index); - for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) - mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]); - /* Write sram index - indirect access */ mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index); for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram[i]); + /* Write tcam index - indirect access */ + mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index); + for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) + mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]); + return 0; } @@ -405,6 +405,38 @@ return -EINVAL; } +/* Drop flow control pause frames */ +static void mvpp2_prs_drop_fc(struct mvpp2 *priv) +{ + unsigned char da[ETH_ALEN] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 }; + struct mvpp2_prs_entry pe; + unsigned int len; + + memset(&pe, 0, sizeof(pe)); + + /* For all ports - drop flow control frames */ + pe.index = MVPP2_PE_FC_DROP; + mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); + + /* Set match on DA */ + len = ETH_ALEN; + while (len--) + mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff); + + mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK, + MVPP2_PRS_RI_DROP_MASK); + + mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); + mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); + + /* Mask all ports */ + mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); + + /* Update shadow table and hw entry */ + mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC); + mvpp2_prs_hw_write(priv, &pe); +} + /* Enable/disable dropping all mac da's */ static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add) { @@ -1162,6 +1194,7 @@ mvpp2_prs_hw_write(priv, &pe); /* Create dummy entries for drop all and promiscuous modes */ + mvpp2_prs_drop_fc(priv); mvpp2_prs_mac_drop_all_set(priv, 0, false); mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false); mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false); @@ -1647,8 +1680,9 @@ mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, MVPP2_PRS_RI_L3_PROTO_MASK); - /* Skip eth_type + 4 bytes of IPv6 header */ - mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, + /* Jump to DIP of IPV6 header */ + mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 + + MVPP2_MAX_L3_ADDR_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); /* Set L3 offset */ mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.h @@ -129,7 +129,7 @@ #define MVPP2_PE_VID_EDSA_FLTR_DEFAULT (MVPP2_PRS_TCAM_SRAM_SIZE - 7) #define MVPP2_PE_VLAN_DBL (MVPP2_PRS_TCAM_SRAM_SIZE - 6) #define MVPP2_PE_VLAN_NONE (MVPP2_PRS_TCAM_SRAM_SIZE - 5) -/* reserved */ +#define MVPP2_PE_FC_DROP (MVPP2_PRS_TCAM_SRAM_SIZE - 4) #define MVPP2_PE_MAC_MC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 3) #define MVPP2_PE_MAC_UC_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 2) #define MVPP2_PE_MAC_NON_PROMISCUOUS (MVPP2_PRS_TCAM_SRAM_SIZE - 1) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/cgx.c @@ -582,7 +582,7 @@ /* Release thread waiting for completion */ lmac->cmd_pend = false; - wake_up_interruptible(&lmac->wq_cmd_cmplt); + wake_up(&lmac->wq_cmd_cmplt); break; case CGX_EVT_ASYNC: if (cgx_event_is_linkevent(event)) @@ -725,8 +725,10 @@ if (!lmac) return -ENOMEM; lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); - if (!lmac->name) - return -ENOMEM; + if (!lmac->name) { + err = -ENOMEM; + goto err_lmac_free; + } sprintf(lmac->name, "cgx_fwi_%d_%d", cgx->cgx_id, i); lmac->lmac_id = i; lmac->cgx = cgx; @@ -737,7 +739,7 @@ CGX_LMAC_FWI + i * 9), cgx_fwi_event_handler, 0, lmac->name, lmac); if (err) - return err; + goto err_irq; /* Enable interrupt */ cgx_write(cgx, lmac->lmac_id, CGXX_CMRX_INT_ENA_W1S, @@ -748,6 +750,12 @@ } return cgx_lmac_verify_fwi_version(cgx); + +err_irq: + kfree(lmac->name); +err_lmac_free: + kfree(lmac); + return err; } static int cgx_lmac_exit(struct cgx *cgx) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/common.h +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/common.h @@ -43,7 +43,7 @@ void *base; dma_addr_t iova; int alloc_sz; - u8 entry_sz; + u16 entry_sz; u8 align; u32 qsize; }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/npc.h +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/npc.h @@ -38,14 +38,18 @@ NPC_LT_LB_ITAG, }; +/* Don't modify ltypes up to IP6_EXT, otherwise length and checksum of IP + * headers may not be checked correctly. IPv4 ltypes and IPv6 ltypes must + * differ only at bit 0 so mask 0xE can be used to detect extended headers. + */ enum npc_kpu_lc_ltype { - NPC_LT_LC_IP = 1, + NPC_LT_LC_PTP = 1, + NPC_LT_LC_IP, NPC_LT_LC_IP6, NPC_LT_LC_ARP, NPC_LT_LC_RARP, NPC_LT_LC_MPLS, NPC_LT_LC_NSH, - NPC_LT_LC_PTP, NPC_LT_LC_FCOE, }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1124,7 +1124,7 @@ if (req->ssow > block->lf.max) { dev_err(&rvu->pdev->dev, "Func 0x%x: Invalid SSOW req, %d > max %d\n", - pcifunc, req->sso, block->lf.max); + pcifunc, req->ssow, block->lf.max); return -EINVAL; } mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->type); @@ -1708,10 +1708,9 @@ } } -static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq) +static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq) { struct rvu *rvu = (struct rvu *)rvu_irq; - int vfs = rvu->vfs; u64 intr; intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT); @@ -1723,6 +1722,18 @@ rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr); + return IRQ_HANDLED; +} + +static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq) +{ + struct rvu *rvu = (struct rvu *)rvu_irq; + int vfs = rvu->vfs; + u64 intr; + + /* Sync with mbox memory region */ + rmb(); + /* Handle VF interrupts */ if (vfs > 64) { intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1)); @@ -1980,8 +1991,10 @@ INTR_MASK(rvu->hw->total_pfs) & ~1ULL); for (irq = 0; irq < rvu->num_vec; irq++) { - if (rvu->irq_allocated[irq]) + if (rvu->irq_allocated[irq]) { free_irq(pci_irq_vector(rvu->pdev, irq), rvu); + rvu->irq_allocated[irq] = false; + } } pci_free_irq_vectors(rvu->pdev); @@ -2033,7 +2046,7 @@ /* Register mailbox interrupt handler */ sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox"); ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX), - rvu_mbox_intr_handler, 0, + rvu_mbox_pf_intr_handler, 0, &rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu); if (ret) { dev_err(rvu->dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -2430,9 +2430,10 @@ if (link < 0) return NIX_AF_ERR_RX_LINK_INVALID; - nix_find_link_frs(rvu, req, pcifunc); linkcfg: + nix_find_link_frs(rvu, req, pcifunc); + cfg = rvu_read64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link)); cfg = (cfg & ~(0xFFFFULL << 16)) | ((u64)req->maxlen << 16); if (req->update_minlen) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -1967,10 +1967,10 @@ index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); if (index >= mcam->bmap_entries) break; + entry = index + 1; if (mcam->entry2cntr_map[index] != req->cntr) continue; - entry = index + 1; npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index, req->cntr); } @@ -2013,10 +2013,11 @@ index = find_next_bit(mcam->bmap, mcam->bmap_entries, entry); if (index >= mcam->bmap_entries) break; + entry = index + 1; + if (mcam->entry2cntr_map[index] != req->cntr) continue; - entry = index + 1; npc_unmap_mcam_entry_and_cntr(rvu, mcam, blkaddr, index, req->cntr); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/pxa168_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1407,18 +1407,15 @@ printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n"); - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n"); + dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n"); return -ENODEV; } - clk_prepare_enable(clk); dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); - if (!dev) { - err = -ENOMEM; - goto err_clk; - } + if (!dev) + return -ENOMEM; platform_set_drvdata(pdev, dev); pep = netdev_priv(dev); @@ -1531,8 +1528,6 @@ mdiobus_free(pep->smi_bus); err_netdev: free_netdev(dev); -err_clk: - clk_disable_unprepare(clk); return err; } @@ -1554,8 +1549,8 @@ mdiobus_unregister(pep->smi_bus); mdiobus_free(pep->smi_bus); - unregister_netdev(dev); cancel_work_sync(&pep->tx_timeout_task); + unregister_netdev(dev); free_netdev(dev); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/sky2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/sky2.c @@ -130,6 +130,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */ + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4373) }, /* 88E8075 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4382) }, /* 88E8079 */ @@ -203,7 +204,7 @@ static inline u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) { - u16 v; + u16 v = 0; __gm_phy_read(hw, port, reg, &v); return v; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/marvell/sky2.h +++ linux-oracle-5.4.0/drivers/net/ethernet/marvell/sky2.h @@ -2201,7 +2201,7 @@ struct sk_buff *skb; dma_addr_t data_addr; DEFINE_DMA_UNMAP_LEN(data_size); - dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; + dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT ?: 1]; }; enum flow_control { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -65,6 +65,17 @@ return __raw_readl(eth->base + reg); } +u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg) +{ + u32 val; + + val = mtk_r32(eth, reg); + val &= ~mask; + val |= set; + mtk_w32(eth, val, reg); + return reg; +} + static int mtk_mdio_busy_wait(struct mtk_eth *eth) { unsigned long t_start = jiffies; @@ -160,11 +171,21 @@ return 0; } -static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, int speed) +static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth, + phy_interface_t interface, int speed) { u32 val; int ret; + if (interface == PHY_INTERFACE_MODE_TRGMII) { + mtk_w32(eth, TRGMII_MODE, INTF_MODE); + val = 500000000; + ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val); + if (ret) + dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret); + return; + } + val = (speed == SPEED_1000) ? INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100; mtk_w32(eth, val, INTF_MODE); @@ -193,8 +214,8 @@ struct mtk_mac *mac = container_of(config, struct mtk_mac, phylink_config); struct mtk_eth *eth = mac->hw; - u32 mcr_cur, mcr_new, sid; - int val, ge_mode, err; + u32 mcr_cur, mcr_new, sid, i; + int val, ge_mode, err = 0; /* MT76x8 has no hardware settings between for the MAC */ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && @@ -251,10 +272,20 @@ state->interface)) goto err_phy; } else { - if (state->interface != - PHY_INTERFACE_MODE_TRGMII) - mtk_gmac0_rgmii_adjust(mac->hw, - state->speed); + mtk_gmac0_rgmii_adjust(mac->hw, + state->interface, + state->speed); + + /* mt7623_pad_clk_setup */ + for (i = 0 ; i < NUM_TRGMII_CTRL; i++) + mtk_w32(mac->hw, + TD_DM_DRVP(8) | TD_DM_DRVN(8), + TRGMII_TD_ODT(i)); + + /* Assert/release MT7623 RXC reset */ + mtk_m32(mac->hw, 0, RXC_RST | RXC_DQSISEL, + TRGMII_RCK_CTRL); + mtk_m32(mac->hw, RXC_RST, 0, TRGMII_RCK_CTRL); } } @@ -644,32 +675,53 @@ void mtk_stats_update_mac(struct mtk_mac *mac) { struct mtk_hw_stats *hw_stats = mac->hw_stats; - unsigned int base = MTK_GDM1_TX_GBCNT; - u64 stats; - - base += hw_stats->reg_offset; + struct mtk_eth *eth = mac->hw; u64_stats_update_begin(&hw_stats->syncp); - hw_stats->rx_bytes += mtk_r32(mac->hw, base); - stats = mtk_r32(mac->hw, base + 0x04); - if (stats) - hw_stats->rx_bytes += (stats << 32); - hw_stats->rx_packets += mtk_r32(mac->hw, base + 0x08); - hw_stats->rx_overflow += mtk_r32(mac->hw, base + 0x10); - hw_stats->rx_fcs_errors += mtk_r32(mac->hw, base + 0x14); - hw_stats->rx_short_errors += mtk_r32(mac->hw, base + 0x18); - hw_stats->rx_long_errors += mtk_r32(mac->hw, base + 0x1c); - hw_stats->rx_checksum_errors += mtk_r32(mac->hw, base + 0x20); - hw_stats->rx_flow_control_packets += - mtk_r32(mac->hw, base + 0x24); - hw_stats->tx_skip += mtk_r32(mac->hw, base + 0x28); - hw_stats->tx_collisions += mtk_r32(mac->hw, base + 0x2c); - hw_stats->tx_bytes += mtk_r32(mac->hw, base + 0x30); - stats = mtk_r32(mac->hw, base + 0x34); - if (stats) - hw_stats->tx_bytes += (stats << 32); - hw_stats->tx_packets += mtk_r32(mac->hw, base + 0x38); + if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { + hw_stats->tx_packets += mtk_r32(mac->hw, MT7628_SDM_TPCNT); + hw_stats->tx_bytes += mtk_r32(mac->hw, MT7628_SDM_TBCNT); + hw_stats->rx_packets += mtk_r32(mac->hw, MT7628_SDM_RPCNT); + hw_stats->rx_bytes += mtk_r32(mac->hw, MT7628_SDM_RBCNT); + hw_stats->rx_checksum_errors += + mtk_r32(mac->hw, MT7628_SDM_CS_ERR); + } else { + unsigned int offs = hw_stats->reg_offset; + u64 stats; + + hw_stats->rx_bytes += mtk_r32(mac->hw, + MTK_GDM1_RX_GBCNT_L + offs); + stats = mtk_r32(mac->hw, MTK_GDM1_RX_GBCNT_H + offs); + if (stats) + hw_stats->rx_bytes += (stats << 32); + hw_stats->rx_packets += + mtk_r32(mac->hw, MTK_GDM1_RX_GPCNT + offs); + hw_stats->rx_overflow += + mtk_r32(mac->hw, MTK_GDM1_RX_OERCNT + offs); + hw_stats->rx_fcs_errors += + mtk_r32(mac->hw, MTK_GDM1_RX_FERCNT + offs); + hw_stats->rx_short_errors += + mtk_r32(mac->hw, MTK_GDM1_RX_SERCNT + offs); + hw_stats->rx_long_errors += + mtk_r32(mac->hw, MTK_GDM1_RX_LENCNT + offs); + hw_stats->rx_checksum_errors += + mtk_r32(mac->hw, MTK_GDM1_RX_CERCNT + offs); + hw_stats->rx_flow_control_packets += + mtk_r32(mac->hw, MTK_GDM1_RX_FCCNT + offs); + hw_stats->tx_skip += + mtk_r32(mac->hw, MTK_GDM1_TX_SKIPCNT + offs); + hw_stats->tx_collisions += + mtk_r32(mac->hw, MTK_GDM1_TX_COLCNT + offs); + hw_stats->tx_bytes += + mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_L + offs); + stats = mtk_r32(mac->hw, MTK_GDM1_TX_GBCNT_H + offs); + if (stats) + hw_stats->tx_bytes += (stats << 32); + hw_stats->tx_packets += + mtk_r32(mac->hw, MTK_GDM1_TX_GPCNT + offs); + } + u64_stats_update_end(&hw_stats->syncp); } @@ -750,6 +802,17 @@ rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); } +static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask) +{ + unsigned int size = mtk_max_frag_size(MTK_MAX_LRO_RX_LENGTH); + unsigned long data; + + data = __get_free_pages(gfp_mask | __GFP_COMP | __GFP_NOWARN, + get_order(size)); + + return (void *)data; +} + /* the qdma core needs scratch memory to be setup */ static int mtk_init_fq_dma(struct mtk_eth *eth) { @@ -1247,7 +1310,10 @@ goto release_desc; /* alloc new buffer */ - new_data = napi_alloc_frag(ring->frag_size); + if (ring->frag_size <= PAGE_SIZE) + new_data = napi_alloc_frag(ring->frag_size); + else + new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC); if (unlikely(!new_data)) { netdev->stats.rx_dropped++; goto release_desc; @@ -1284,7 +1350,7 @@ skb->protocol = eth_type_trans(skb, netdev); if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && - RX_DMA_VID(trxd.rxd3)) + (trxd.rxd2 & RX_DMA_VTAG)) __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), RX_DMA_VID(trxd.rxd3)); skb_record_rx_queue(skb, 0); @@ -1644,7 +1710,10 @@ return -ENOMEM; for (i = 0; i < rx_dma_size; i++) { - ring->data[i] = netdev_alloc_frag(ring->frag_size); + if (ring->frag_size <= PAGE_SIZE) + ring->data[i] = netdev_alloc_frag(ring->frag_size); + else + ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL); if (!ring->data[i]) return -ENOMEM; } @@ -1910,6 +1979,9 @@ struct ethtool_rx_flow_spec *fsp = (struct ethtool_rx_flow_spec *)&cmd->fs; + if (fsp->location >= ARRAY_SIZE(mac->hwlro_ip)) + return -EINVAL; + /* only tcp dst ipv4 is meaningful, others are meaningless */ fsp->flow_type = TCP_V4_FLOW; fsp->h_u.tcp_ip4_spec.ip4dst = ntohl(mac->hwlro_ip[fsp->location]); @@ -1936,6 +2008,9 @@ int i; for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { + if (cnt == cmd->rule_cnt) + return -EMSGSIZE; + if (mac->hwlro_ip[i]) { rule_locs[cnt] = i; cnt++; @@ -2847,6 +2922,8 @@ eth->netdev[id]->irq = eth->irq[0]; eth->netdev[id]->dev.of_node = np; + eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH - MTK_RX_ETH_HLEN; + return 0; free_netdev: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -264,8 +264,21 @@ /* QDMA FQ Free Page Buffer Length Register */ #define MTK_QDMA_FQ_BLEN 0x1B2C -/* GMA1 Received Good Byte Count Register */ -#define MTK_GDM1_TX_GBCNT 0x2400 +/* GMA1 counter / statics register */ +#define MTK_GDM1_RX_GBCNT_L 0x2400 +#define MTK_GDM1_RX_GBCNT_H 0x2404 +#define MTK_GDM1_RX_GPCNT 0x2408 +#define MTK_GDM1_RX_OERCNT 0x2410 +#define MTK_GDM1_RX_FERCNT 0x2414 +#define MTK_GDM1_RX_SERCNT 0x2418 +#define MTK_GDM1_RX_LENCNT 0x241c +#define MTK_GDM1_RX_CERCNT 0x2420 +#define MTK_GDM1_RX_FCCNT 0x2424 +#define MTK_GDM1_TX_SKIPCNT 0x2428 +#define MTK_GDM1_TX_COLCNT 0x242c +#define MTK_GDM1_TX_GBCNT_L 0x2430 +#define MTK_GDM1_TX_GBCNT_H 0x2434 +#define MTK_GDM1_TX_GPCNT 0x2438 #define MTK_STAT_OFFSET 0x40 /* QDMA descriptor txd4 */ @@ -293,6 +306,7 @@ #define RX_DMA_LSO BIT(30) #define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) #define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff) +#define RX_DMA_VTAG BIT(15) /* QDMA descriptor rxd3 */ #define RX_DMA_VID(_x) ((_x) & 0xfff) @@ -350,10 +364,13 @@ #define DQSI0(x) ((x << 0) & GENMASK(6, 0)) #define DQSI1(x) ((x << 8) & GENMASK(14, 8)) #define RXCTL_DMWTLAT(x) ((x << 16) & GENMASK(18, 16)) +#define RXC_RST BIT(31) #define RXC_DQSISEL BIT(30) #define RCK_CTRL_RGMII_1000 (RXC_DQSISEL | RXCTL_DMWTLAT(2) | DQSI1(16)) #define RCK_CTRL_RGMII_10_100 RXCTL_DMWTLAT(2) +#define NUM_TRGMII_CTRL 5 + /* TRGMII RXC control register */ #define TRGMII_TCK_CTRL 0x10340 #define TXCTL_DMWTLAT(x) ((x << 16) & GENMASK(18, 16)) @@ -361,6 +378,11 @@ #define TCK_CTRL_RGMII_1000 TXCTL_DMWTLAT(2) #define TCK_CTRL_RGMII_10_100 (TXC_INV | TXCTL_DMWTLAT(2)) +/* TRGMII TX Drive Strength */ +#define TRGMII_TD_ODT(i) (0x10354 + 8 * (i)) +#define TD_DM_DRVP(x) ((x) & 0xf) +#define TD_DM_DRVN(x) (((x) & 0xf) << 4) + /* TRGMII Interface mode register */ #define INTF_MODE 0x10390 #define TRGMII_INTF_DIS BIT(0) @@ -467,6 +489,13 @@ #define MT7628_SDM_MAC_ADRL (MT7628_SDM_OFFSET + 0x0c) #define MT7628_SDM_MAC_ADRH (MT7628_SDM_OFFSET + 0x10) +/* Counter / stat register */ +#define MT7628_SDM_TPCNT (MT7628_SDM_OFFSET + 0x100) +#define MT7628_SDM_TBCNT (MT7628_SDM_OFFSET + 0x104) +#define MT7628_SDM_RPCNT (MT7628_SDM_OFFSET + 0x108) +#define MT7628_SDM_RBCNT (MT7628_SDM_OFFSET + 0x10c) +#define MT7628_SDM_CS_ERR (MT7628_SDM_OFFSET + 0x110) + struct mtk_rx_dma { unsigned int rxd1; unsigned int rxd2; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mediatek/mtk_sgmii.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mediatek/mtk_sgmii.c @@ -26,6 +26,7 @@ break; ss->regmap[i] = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(ss->regmap[i])) return PTR_ERR(ss->regmap[i]); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -47,7 +47,7 @@ #define EN_ETHTOOL_SHORT_MASK cpu_to_be16(0xffff) #define EN_ETHTOOL_WORD_MASK cpu_to_be32(0xffffffff) -static int mlx4_en_moderation_update(struct mlx4_en_priv *priv) +int mlx4_en_moderation_update(struct mlx4_en_priv *priv) { int i, t; int err = 0; @@ -663,7 +663,7 @@ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_T, SPEED_1000, ETHTOOL_LINK_MODE_1000baseT_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_CX_SGMII, SPEED_1000, - ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); + ETHTOOL_LINK_MODE_1000baseX_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_1000BASE_KX, SPEED_1000, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_T, SPEED_10000, @@ -675,9 +675,9 @@ MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_KR, SPEED_10000, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_CR, SPEED_10000, - ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_10GBASE_SR, SPEED_10000, - ETHTOOL_LINK_MODE_10000baseKR_Full_BIT); + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT); MLX4_BUILD_PTYS2ETHTOOL_CONFIG(MLX4_20GBASE_KR2, SPEED_20000, ETHTOOL_LINK_MODE_20000baseMLD2_Full_BIT, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT); @@ -2011,8 +2011,6 @@ return ret; } -#define MLX4_EEPROM_PAGE_LEN 256 - static int mlx4_en_get_module_info(struct net_device *dev, struct ethtool_modinfo *modinfo) { @@ -2047,7 +2045,7 @@ break; case MLX4_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = MLX4_EEPROM_PAGE_LEN; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; break; default: return -EINVAL; @@ -2085,7 +2083,7 @@ en_err(priv, "mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n", i, offset, ee->len - i, ret); - return 0; + return ret; } i += ret; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -371,6 +371,9 @@ int nhoff = skb_network_offset(skb); int ret = 0; + if (skb->encapsulation) + return -EPROTONOSUPPORT; + if (skb->protocol != htons(ETH_P_IP)) return -EPROTONOSUPPORT; @@ -1383,8 +1386,10 @@ } priv->port_stats.tx_timeout++; - en_dbg(DRV, priv, "Scheduling watchdog\n"); - queue_work(mdev->workqueue, &priv->watchdog_task); + if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state)) { + en_dbg(DRV, priv, "Scheduling port restart\n"); + queue_work(mdev->workqueue, &priv->restart_task); + } } @@ -1738,6 +1743,7 @@ mlx4_en_deactivate_cq(priv, cq); goto tx_err; } + clear_bit(MLX4_EN_TX_RING_STATE_RECOVERING, &tx_ring->state); if (t != TX_XDP) { tx_ring->tx_queue = netdev_get_tx_queue(dev, i); tx_ring->recycle_ring = NULL; @@ -1834,6 +1840,7 @@ local_bh_enable(); } + clear_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state); netif_tx_start_all_queues(dev); netif_device_attach(dev); @@ -2004,7 +2011,7 @@ static void mlx4_en_restart(struct work_struct *work) { struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, - watchdog_task); + restart_task); struct mlx4_en_dev *mdev = priv->mdev; struct net_device *dev = priv->dev; @@ -2274,9 +2281,14 @@ bool carry_xdp_prog) { struct bpf_prog *xdp_prog; - int i, t; + int i, t, ret; - mlx4_en_copy_priv(tmp, priv, prof); + ret = mlx4_en_copy_priv(tmp, priv, prof); + if (ret) { + en_warn(priv, "%s: mlx4_en_copy_priv() failed, return\n", + __func__); + return ret; + } if (mlx4_en_alloc_resources(tmp)) { en_warn(priv, @@ -2386,7 +2398,7 @@ if (netif_running(dev)) { mutex_lock(&mdev->state_lock); if (!mdev->device_up) { - /* NIC is probably restarting - let watchdog task reset + /* NIC is probably restarting - let restart task reset * the port */ en_dbg(DRV, priv, "Change MTU called with card down!?\n"); } else { @@ -2395,7 +2407,9 @@ if (err) { en_err(priv, "Failed restarting port:%d\n", priv->port); - queue_work(mdev->workqueue, &priv->watchdog_task); + if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, + &priv->state)) + queue_work(mdev->workqueue, &priv->restart_task); } } mutex_unlock(&mdev->state_lock); @@ -2865,7 +2879,8 @@ if (err) { en_err(priv, "Failed starting port %d for XDP change\n", priv->port); - queue_work(mdev->workqueue, &priv->watchdog_task); + if (!test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state)) + queue_work(mdev->workqueue, &priv->restart_task); } } @@ -3263,7 +3278,7 @@ priv->counter_index = MLX4_SINK_COUNTER_INDEX(mdev->dev); spin_lock_init(&priv->stats_lock); INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); - INIT_WORK(&priv->watchdog_task, mlx4_en_restart); + INIT_WORK(&priv->restart_task, mlx4_en_restart); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); INIT_DELAYED_WORK(&priv->service_task, mlx4_en_service_task); @@ -3650,6 +3665,8 @@ en_err(priv, "Failed starting port\n"); } + if (!err) + err = mlx4_en_moderation_update(priv); out: mutex_unlock(&mdev->state_lock); kfree(tmp); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -942,6 +942,9 @@ bool clean_complete = true; int done; + if (!budget) + return 0; + if (priv->tx_ring_num[TX_XDP]) { xdp_tx_cq = priv->tx_cq[TX_XDP][cq->ring]; if (xdp_tx_cq->xdp_busy) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "mlx4_en.h" @@ -261,6 +262,10 @@ } } +INDIRECT_CALLABLE_DECLARE(u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, + struct mlx4_en_tx_ring *ring, + int index, u64 timestamp, + int napi_mode)); u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring, @@ -329,6 +334,11 @@ return tx_info->nr_txbb; } +INDIRECT_CALLABLE_DECLARE(u32 mlx4_en_recycle_tx_desc(struct mlx4_en_priv *priv, + struct mlx4_en_tx_ring *ring, + int index, u64 timestamp, + int napi_mode)); + u32 mlx4_en_recycle_tx_desc(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring, int index, u64 timestamp, @@ -340,7 +350,7 @@ .dma = tx_info->map0_dma, }; - if (!mlx4_en_rx_recycle(ring->recycle_ring, &frame)) { + if (!napi_mode || !mlx4_en_rx_recycle(ring->recycle_ring, &frame)) { dma_unmap_page(priv->ddev, tx_info->map0_dma, PAGE_SIZE, priv->dma_dir); put_page(tx_info->page); @@ -382,6 +392,35 @@ return cnt; } +static void mlx4_en_handle_err_cqe(struct mlx4_en_priv *priv, struct mlx4_err_cqe *err_cqe, + u16 cqe_index, struct mlx4_en_tx_ring *ring) +{ + struct mlx4_en_dev *mdev = priv->mdev; + struct mlx4_en_tx_info *tx_info; + struct mlx4_en_tx_desc *tx_desc; + u16 wqe_index; + int desc_size; + + en_err(priv, "CQE error - cqn 0x%x, ci 0x%x, vendor syndrome: 0x%x syndrome: 0x%x\n", + ring->sp_cqn, cqe_index, err_cqe->vendor_err_syndrome, err_cqe->syndrome); + print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, err_cqe, sizeof(*err_cqe), + false); + + wqe_index = be16_to_cpu(err_cqe->wqe_index) & ring->size_mask; + tx_info = &ring->tx_info[wqe_index]; + desc_size = tx_info->nr_txbb << LOG_TXBB_SIZE; + en_err(priv, "Related WQE - qpn 0x%x, wqe index 0x%x, wqe size 0x%x\n", ring->qpn, + wqe_index, desc_size); + tx_desc = ring->buf + (wqe_index << LOG_TXBB_SIZE); + print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1, tx_desc, desc_size, false); + + if (test_and_set_bit(MLX4_EN_STATE_FLAG_RESTARTING, &priv->state)) + return; + + en_err(priv, "Scheduling port restart\n"); + queue_work(mdev->workqueue, &priv->restart_task); +} + bool mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int napi_budget) { @@ -428,13 +467,10 @@ dma_rmb(); if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) == - MLX4_CQE_OPCODE_ERROR)) { - struct mlx4_err_cqe *cqe_err = (struct mlx4_err_cqe *)cqe; - - en_err(priv, "CQE error - vendor syndrome: 0x%x syndrome: 0x%x\n", - cqe_err->vendor_err_syndrome, - cqe_err->syndrome); - } + MLX4_CQE_OPCODE_ERROR)) + if (!test_and_set_bit(MLX4_EN_TX_RING_STATE_RECOVERING, &ring->state)) + mlx4_en_handle_err_cqe(priv, (struct mlx4_err_cqe *)cqe, index, + ring); /* Skip over last polled CQE */ new_index = be16_to_cpu(cqe->wqe_index) & size_mask; @@ -449,7 +485,9 @@ timestamp = mlx4_en_get_cqe_ts(cqe); /* free next descriptor */ - last_nr_txbb = ring->free_tx_desc( + last_nr_txbb = INDIRECT_CALL_2(ring->free_tx_desc, + mlx4_en_free_tx_desc, + mlx4_en_recycle_tx_desc, priv, ring, ring_index, timestamp, napi_budget); @@ -830,6 +868,7 @@ struct mlx4_en_tx_desc *tx_desc; struct mlx4_wqe_data_seg *data; struct mlx4_en_tx_info *tx_info; + u32 __maybe_unused ring_cons; int tx_ind; int nr_txbb; int desc_size; @@ -843,7 +882,6 @@ bool stop_queue; bool inline_ok; u8 data_offset; - u32 ring_cons; bool bf_ok; tx_ind = skb_get_queue_mapping(skb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/fw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -823,6 +823,7 @@ #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac +#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1 #define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc #define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0 #define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2 @@ -841,6 +842,8 @@ if (mlx4_is_mfunc(dev)) disable_unsupported_roce_caps(outbox); + MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER); + dev_cap->map_clock_to_user = field & 0x80; MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET); dev_cap->reserved_qps = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET); @@ -1864,8 +1867,8 @@ #define INIT_HCA_LOG_RD_OFFSET (INIT_HCA_QPC_OFFSET + 0x77) #define INIT_HCA_MCAST_OFFSET 0x0c0 #define INIT_HCA_MC_BASE_OFFSET (INIT_HCA_MCAST_OFFSET + 0x00) -#define INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x12) -#define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x16) +#define INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x13) +#define INIT_HCA_LOG_MC_HASH_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x17) #define INIT_HCA_UC_STEERING_OFFSET (INIT_HCA_MCAST_OFFSET + 0x18) #define INIT_HCA_LOG_MC_TABLE_SZ_OFFSET (INIT_HCA_MCAST_OFFSET + 0x1b) #define INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN 0x6 @@ -1873,7 +1876,7 @@ #define INIT_HCA_DRIVER_VERSION_SZ 0x40 #define INIT_HCA_FS_PARAM_OFFSET 0x1d0 #define INIT_HCA_FS_BASE_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x00) -#define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x12) +#define INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x13) #define INIT_HCA_FS_A0_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x18) #define INIT_HCA_FS_LOG_TABLE_SZ_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x1b) #define INIT_HCA_FS_ETH_BITS_OFFSET (INIT_HCA_FS_PARAM_OFFSET + 0x21) @@ -2734,7 +2737,7 @@ if (err) { mlx4_err(dev, "Failed to retrieve required operation: %d\n", err); - return; + goto out; } MLX4_GET(modifier, outbox, GET_OP_REQ_MODIFIER_OFFSET); MLX4_GET(token, outbox, GET_OP_REQ_TOKEN_OFFSET); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/fw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -131,6 +131,7 @@ u32 health_buffer_addrs; struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; bool wol_port[MLX4_MAX_PORTS + 1]; + bool map_clock_to_user; }; struct mlx4_func_cap { @@ -182,8 +183,8 @@ u64 cmpt_base; u64 mtt_base; u64 global_caps; - u16 log_mc_entry_sz; - u16 log_mc_hash_sz; + u8 log_mc_entry_sz; + u8 log_mc_hash_sz; u16 hca_core_clock; /* Internal Clock Frequency (in MHz) */ u8 log_num_qps; u8 log_num_srqs; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/main.c @@ -498,6 +498,7 @@ } } + dev->caps.map_clock_to_user = dev_cap->map_clock_to_user; dev->caps.uar_page_size = PAGE_SIZE; dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; @@ -1948,6 +1949,11 @@ if (mlx4_is_slave(dev)) return -EOPNOTSUPP; + if (!dev->caps.map_clock_to_user) { + mlx4_dbg(dev, "Map clock to user is not supported.\n"); + return -EOPNOTSUPP; + } + if (!params) return -EINVAL; @@ -2550,6 +2556,7 @@ if (!err || err == -ENOSPC) { priv->def_counter[port] = idx; + err = 0; } else if (err == -ENOENT) { err = 0; continue; @@ -2600,7 +2607,8 @@ MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED); if (!err) *idx = get_param_l(&out_param); - + if (WARN_ON(err == -ENOSPC)) + err = -EINVAL; return err; } return __mlx4_counter_alloc(dev, idx); @@ -3518,6 +3526,7 @@ if (!SRIOV_VALID_STATE(dev->flags)) { mlx4_err(dev, "Invalid SRIOV state\n"); + err = -EINVAL; goto err_close; } } @@ -4352,12 +4361,14 @@ static void mlx4_shutdown(struct pci_dev *pdev) { struct mlx4_dev_persistent *persist = pci_get_drvdata(pdev); + struct mlx4_dev *dev = persist->dev; mlx4_info(persist->dev, "mlx4_shutdown was called\n"); mutex_lock(&persist->interface_state_mutex); if (persist->interface_state & MLX4_INTERFACE_STATE_UP) mlx4_unload_one(pdev); mutex_unlock(&persist->interface_state_mutex); + mlx4_pci_disable_device(dev); } static const struct pci_error_handlers mlx4_err_handler = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -271,6 +271,10 @@ } buf[MLX4_EN_CACHE_SIZE]; }; +enum { + MLX4_EN_TX_RING_STATE_RECOVERING, +}; + struct mlx4_en_priv; struct mlx4_en_tx_ring { @@ -317,6 +321,7 @@ * Only queue_stopped might be used if BQL is not properly working. */ unsigned long queue_stopped; + unsigned long state; struct mlx4_hwq_resources sp_wqres; struct mlx4_qp sp_qp; struct mlx4_qp_context sp_context; @@ -530,6 +535,10 @@ struct mutex mutex; /* for mutual access to stats bitmap */ }; +enum { + MLX4_EN_STATE_FLAG_RESTARTING, +}; + struct mlx4_en_priv { struct mlx4_en_dev *mdev; struct mlx4_en_port_profile *prof; @@ -595,7 +604,7 @@ struct mlx4_en_cq *rx_cq[MAX_RX_RINGS]; struct mlx4_qp drop_qp; struct work_struct rx_mode_task; - struct work_struct watchdog_task; + struct work_struct restart_task; struct work_struct linkstate_task; struct delayed_work stats_task; struct delayed_work service_task; @@ -643,6 +652,7 @@ u32 pflags; u8 rss_key[MLX4_EN_RSS_KEY_SIZE]; u8 rss_hash_fn; + unsigned long state; }; enum mlx4_en_wol { @@ -787,6 +797,7 @@ #define DEV_FEATURE_CHANGED(dev, new_features, feature) \ ((dev->features & feature) ^ (new_features & feature)) +int mlx4_en_moderation_update(struct mlx4_en_priv *priv); int mlx4_en_reset_config(struct net_device *dev, struct hwtstamp_config ts_config, netdev_features_t new_features); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/mr.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -114,7 +114,7 @@ goto err_out; for (i = 0; i <= buddy->max_order; ++i) { - s = BITS_TO_LONGS(1 << (buddy->max_order - i)); + s = BITS_TO_LONGS(1UL << (buddy->max_order - i)); buddy->bits[i] = kvmalloc_array(s, sizeof(long), GFP_KERNEL | __GFP_ZERO); if (!buddy->bits[i]) goto err_out_free; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/port.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/port.c @@ -1973,6 +1973,7 @@ #define I2C_ADDR_LOW 0x50 #define I2C_ADDR_HIGH 0x51 #define I2C_PAGE_SIZE 256 +#define I2C_HIGH_PAGE_SIZE 128 /* Module Info Data */ struct mlx4_cable_info { @@ -2026,6 +2027,88 @@ return "Unknown Error"; } +static int mlx4_get_module_id(struct mlx4_dev *dev, u8 port, u8 *module_id) +{ + struct mlx4_cmd_mailbox *inbox, *outbox; + struct mlx4_mad_ifc *inmad, *outmad; + struct mlx4_cable_info *cable_info; + int ret; + + inbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(inbox)) + return PTR_ERR(inbox); + + outbox = mlx4_alloc_cmd_mailbox(dev); + if (IS_ERR(outbox)) { + mlx4_free_cmd_mailbox(dev, inbox); + return PTR_ERR(outbox); + } + + inmad = (struct mlx4_mad_ifc *)(inbox->buf); + outmad = (struct mlx4_mad_ifc *)(outbox->buf); + + inmad->method = 0x1; /* Get */ + inmad->class_version = 0x1; + inmad->mgmt_class = 0x1; + inmad->base_version = 0x1; + inmad->attr_id = cpu_to_be16(0xFF60); /* Module Info */ + + cable_info = (struct mlx4_cable_info *)inmad->data; + cable_info->dev_mem_address = 0; + cable_info->page_num = 0; + cable_info->i2c_addr = I2C_ADDR_LOW; + cable_info->size = cpu_to_be16(1); + + ret = mlx4_cmd_box(dev, inbox->dma, outbox->dma, port, 3, + MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C, + MLX4_CMD_NATIVE); + if (ret) + goto out; + + if (be16_to_cpu(outmad->status)) { + /* Mad returned with bad status */ + ret = be16_to_cpu(outmad->status); + mlx4_warn(dev, + "MLX4_CMD_MAD_IFC Get Module ID attr(%x) port(%d) i2c_addr(%x) offset(%d) size(%d): Response Mad Status(%x) - %s\n", + 0xFF60, port, I2C_ADDR_LOW, 0, 1, ret, + cable_info_mad_err_str(ret)); + ret = -ret; + goto out; + } + cable_info = (struct mlx4_cable_info *)outmad->data; + *module_id = cable_info->data[0]; +out: + mlx4_free_cmd_mailbox(dev, inbox); + mlx4_free_cmd_mailbox(dev, outbox); + return ret; +} + +static void mlx4_sfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + *i2c_addr = I2C_ADDR_LOW; + *page_num = 0; + + if (*offset < I2C_PAGE_SIZE) + return; + + *i2c_addr = I2C_ADDR_HIGH; + *offset -= I2C_PAGE_SIZE; +} + +static void mlx4_qsfp_eeprom_params_set(u8 *i2c_addr, u8 *page_num, u16 *offset) +{ + /* Offsets 0-255 belong to page 0. + * Offsets 256-639 belong to pages 01, 02, 03. + * For example, offset 400 is page 02: 1 + (400 - 256) / 128 = 2 + */ + if (*offset < I2C_PAGE_SIZE) + *page_num = 0; + else + *page_num = 1 + (*offset - I2C_PAGE_SIZE) / I2C_HIGH_PAGE_SIZE; + *i2c_addr = I2C_ADDR_LOW; + *offset -= *page_num * I2C_HIGH_PAGE_SIZE; +} + /** * mlx4_get_module_info - Read cable module eeprom data * @dev: mlx4_dev. @@ -2045,12 +2128,30 @@ struct mlx4_cmd_mailbox *inbox, *outbox; struct mlx4_mad_ifc *inmad, *outmad; struct mlx4_cable_info *cable_info; - u16 i2c_addr; + u8 module_id, i2c_addr, page_num; int ret; if (size > MODULE_INFO_MAX_READ) size = MODULE_INFO_MAX_READ; + ret = mlx4_get_module_id(dev, port, &module_id); + if (ret) + return ret; + + switch (module_id) { + case MLX4_MODULE_ID_SFP: + mlx4_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + case MLX4_MODULE_ID_QSFP: + case MLX4_MODULE_ID_QSFP_PLUS: + case MLX4_MODULE_ID_QSFP28: + mlx4_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + default: + mlx4_err(dev, "Module ID not recognized: %#x\n", module_id); + return -EINVAL; + } + inbox = mlx4_alloc_cmd_mailbox(dev); if (IS_ERR(inbox)) return PTR_ERR(inbox); @@ -2076,11 +2177,9 @@ */ size -= offset + size - I2C_PAGE_SIZE; - i2c_addr = I2C_ADDR_LOW; - cable_info = (struct mlx4_cable_info *)inmad->data; cable_info->dev_mem_address = cpu_to_be16(offset); - cable_info->page_num = 0; + cable_info->page_num = page_num; cable_info->i2c_addr = i2c_addr; cable_info->size = cpu_to_be16(size); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/qp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -697,7 +697,8 @@ err = mlx4_bitmap_init(*bitmap + k, 1, MLX4_QP_TABLE_RAW_ETH_SIZE - 1, 0, 0); - mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0); + if (!err) + mlx4_bitmap_alloc_range(*bitmap + k, 1, 1, 0); } if (err) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -4986,6 +4986,7 @@ if (!fs_rule->mirr_mbox) { mlx4_err(dev, "rule mirroring mailbox is null\n"); + mlx4_free_cmd_mailbox(dev, mailbox); return -EINVAL; } memcpy(mailbox->buf, fs_rule->mirr_mbox, fs_rule->mirr_mbox_size); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h @@ -45,7 +45,7 @@ static inline bool mlx5_accel_is_ktls_device(struct mlx5_core_dev *mdev) { - if (!MLX5_CAP_GEN(mdev, tls)) + if (!MLX5_CAP_GEN(mdev, tls_tx)) return false; if (!MLX5_CAP_GEN(mdev, log_max_dek)) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -69,12 +69,10 @@ MLX5_CMD_DELIVERY_STAT_CMD_DESCR_ERR = 0x10, }; -static struct mlx5_cmd_work_ent *alloc_cmd(struct mlx5_cmd *cmd, - struct mlx5_cmd_msg *in, - struct mlx5_cmd_msg *out, - void *uout, int uout_size, - mlx5_cmd_cbk_t cbk, - void *context, int page_queue) +static struct mlx5_cmd_work_ent * +cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in, + struct mlx5_cmd_msg *out, void *uout, int uout_size, + mlx5_cmd_cbk_t cbk, void *context, int page_queue) { gfp_t alloc_flags = cbk ? GFP_ATOMIC : GFP_KERNEL; struct mlx5_cmd_work_ent *ent; @@ -83,6 +81,7 @@ if (!ent) return ERR_PTR(-ENOMEM); + ent->idx = -EINVAL; ent->in = in; ent->out = out; ent->uout = uout; @@ -91,10 +90,16 @@ ent->context = context; ent->cmd = cmd; ent->page_queue = page_queue; + refcount_set(&ent->refcnt, 1); return ent; } +static void cmd_free_ent(struct mlx5_cmd_work_ent *ent) +{ + kfree(ent); +} + static u8 alloc_token(struct mlx5_cmd *cmd) { u8 token; @@ -109,26 +114,50 @@ return token; } -static int alloc_ent(struct mlx5_cmd *cmd) +static int cmd_alloc_index(struct mlx5_cmd *cmd, struct mlx5_cmd_work_ent *ent) { unsigned long flags; int ret; spin_lock_irqsave(&cmd->alloc_lock, flags); ret = find_first_bit(&cmd->bitmask, cmd->max_reg_cmds); - if (ret < cmd->max_reg_cmds) + if (ret < cmd->max_reg_cmds) { clear_bit(ret, &cmd->bitmask); + ent->idx = ret; + cmd->ent_arr[ent->idx] = ent; + } spin_unlock_irqrestore(&cmd->alloc_lock, flags); return ret < cmd->max_reg_cmds ? ret : -ENOMEM; } -static void free_ent(struct mlx5_cmd *cmd, int idx) +static void cmd_free_index(struct mlx5_cmd *cmd, int idx) +{ + lockdep_assert_held(&cmd->alloc_lock); + set_bit(idx, &cmd->bitmask); +} + +static void cmd_ent_get(struct mlx5_cmd_work_ent *ent) +{ + refcount_inc(&ent->refcnt); +} + +static void cmd_ent_put(struct mlx5_cmd_work_ent *ent) { + struct mlx5_cmd *cmd = ent->cmd; unsigned long flags; spin_lock_irqsave(&cmd->alloc_lock, flags); - set_bit(idx, &cmd->bitmask); + if (!refcount_dec_and_test(&ent->refcnt)) + goto out; + + if (ent->idx >= 0) { + cmd_free_index(cmd, ent->idx); + up(ent->page_queue ? &cmd->pages_sem : &cmd->sem); + } + + cmd_free_ent(ent); +out: spin_unlock_irqrestore(&cmd->alloc_lock, flags); } @@ -219,11 +248,6 @@ ent->ret = -ETIMEDOUT; } -static void free_cmd(struct mlx5_cmd_work_ent *ent) -{ - kfree(ent); -} - static int verify_signature(struct mlx5_cmd_work_ent *ent) { struct mlx5_cmd_mailbox *next = ent->out->next; @@ -317,6 +341,8 @@ case MLX5_CMD_OP_DEALLOC_MEMIC: case MLX5_CMD_OP_PAGE_FAULT_RESUME: case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS: + case MLX5_CMD_OP_DESTROY_UCTX: + case MLX5_CMD_OP_DESTROY_UMEM: return MLX5_CMD_STAT_OK; case MLX5_CMD_OP_QUERY_HCA_CAP: @@ -442,9 +468,7 @@ case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: case MLX5_CMD_OP_CREATE_UCTX: - case MLX5_CMD_OP_DESTROY_UCTX: case MLX5_CMD_OP_CREATE_UMEM: - case MLX5_CMD_OP_DESTROY_UMEM: case MLX5_CMD_OP_ALLOC_MEMIC: case MLX5_CMD_OP_MODIFY_XRQ: case MLX5_CMD_OP_RELEASE_XRQ_ERROR: @@ -837,17 +861,43 @@ struct mlx5_core_dev *dev = container_of(ent->cmd, struct mlx5_core_dev, cmd); + mlx5_cmd_eq_recover(dev); + + /* Maybe got handled by eq recover ? */ + if (!test_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state)) { + mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, recovered after timeout\n", ent->idx, + mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + goto out; /* phew, already handled */ + } + ent->ret = -ETIMEDOUT; - mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", - mlx5_command_str(msg_to_opcode(ent->in)), - msg_to_opcode(ent->in)); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) Async, timeout. Will cause a leak of a command resource\n", + ent->idx, mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); + +out: + cmd_ent_put(ent); /* for the cmd_ent_get() took on schedule delayed work */ } static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg); static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg); +static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode) +{ + if (cmd->allowed_opcode == CMD_ALLOWED_OPCODE_ALL) + return true; + + return cmd->allowed_opcode == opcode; +} + +bool mlx5_cmd_is_down(struct mlx5_core_dev *dev) +{ + return pci_channel_offline(dev->pdev) || + dev->cmd.state != MLX5_CMDIF_STATE_UP || + dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR; +} + static void cmd_work_handler(struct work_struct *work) { struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work); @@ -861,17 +911,18 @@ int alloc_ret; int cmd_mode; + complete(&ent->handling); sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; down(sem); if (!ent->page_queue) { - alloc_ret = alloc_ent(cmd); + alloc_ret = cmd_alloc_index(cmd, ent); if (alloc_ret < 0) { mlx5_core_err(dev, "failed to allocate command entry\n"); if (ent->callback) { ent->callback(-EAGAIN, ent->context); mlx5_free_cmd_msg(dev, ent->out); free_msg(dev, ent->in); - free_cmd(ent); + cmd_ent_put(ent); } else { ent->ret = -EAGAIN; complete(&ent->done); @@ -879,16 +930,14 @@ up(sem); return; } - ent->idx = alloc_ret; } else { ent->idx = cmd->max_reg_cmds; spin_lock_irqsave(&cmd->alloc_lock, flags); clear_bit(ent->idx, &cmd->bitmask); + cmd->ent_arr[ent->idx] = ent; spin_unlock_irqrestore(&cmd->alloc_lock, flags); } - cmd->ent_arr[ent->idx] = ent; - set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); lay = get_inst(cmd, ent->idx); ent->lay = lay; memset(lay, 0, sizeof(*lay)); @@ -908,12 +957,13 @@ ent->ts1 = ktime_get_ns(); cmd_mode = cmd->mode; - if (ent->callback) - schedule_delayed_work(&ent->cb_timeout_work, cb_timeout); + if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, cb_timeout)) + cmd_ent_get(ent); + set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); + cmd_ent_get(ent); /* for the _real_ FW event on completion */ /* Skip sending command to fw if internal error */ - if (pci_channel_offline(dev->pdev) || - dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { + if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, ent->op)) { u8 status = 0; u32 drv_synd; @@ -921,7 +971,7 @@ MLX5_SET(mbox_out, ent->out, status, status); MLX5_SET(mbox_out, ent->out, syndrome, drv_synd); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); return; } @@ -934,7 +984,7 @@ poll_timeout(ent); /* make sure we read the descriptor after ownership is SW */ rmb(); - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, (ent->ret == -ETIMEDOUT)); + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, (ent->ret == -ETIMEDOUT)); } } @@ -968,25 +1018,62 @@ } } +enum { + MLX5_CMD_TIMEOUT_RECOVER_MSEC = 5 * 1000, +}; + +static void wait_func_handle_exec_timeout(struct mlx5_core_dev *dev, + struct mlx5_cmd_work_ent *ent) +{ + unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_RECOVER_MSEC); + + mlx5_cmd_eq_recover(dev); + + /* Re-wait on the ent->done after executing the recovery flow. If the + * recovery flow (or any other recovery flow running simultaneously) + * has recovered an EQE, it should cause the entry to be completed by + * the command interface. + */ + if (wait_for_completion_timeout(&ent->done, timeout)) { + mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) recovered after timeout\n", ent->idx, + mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + return; + } + + mlx5_core_warn(dev, "cmd[%d]: %s(0x%x) No done completion\n", ent->idx, + mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + + ent->ret = -ETIMEDOUT; + mlx5_cmd_comp_handler(dev, 1ULL << ent->idx, true); +} + static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent) { unsigned long timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC); struct mlx5_cmd *cmd = &dev->cmd; int err; - if (cmd->mode == CMD_MODE_POLLING || ent->polling) { - wait_for_completion(&ent->done); - } else if (!wait_for_completion_timeout(&ent->done, timeout)) { - ent->ret = -ETIMEDOUT; - mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); + if (!wait_for_completion_timeout(&ent->handling, timeout) && + cancel_work_sync(&ent->work)) { + ent->ret = -ECANCELED; + goto out_err; } + if (cmd->mode == CMD_MODE_POLLING || ent->polling) + wait_for_completion(&ent->done); + else if (!wait_for_completion_timeout(&ent->done, timeout)) + wait_func_handle_exec_timeout(dev, ent); +out_err: err = ent->ret; if (err == -ETIMEDOUT) { mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n", mlx5_command_str(msg_to_opcode(ent->in)), msg_to_opcode(ent->in)); + } else if (err == -ECANCELED) { + mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n", + mlx5_command_str(msg_to_opcode(ent->in)), + msg_to_opcode(ent->in)); } mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", err, deliv_status_to_str(ent->status), ent->status); @@ -1014,14 +1101,20 @@ if (callback && page_queue) return -EINVAL; - ent = alloc_cmd(cmd, in, out, uout, uout_size, callback, context, - page_queue); + ent = cmd_alloc_ent(cmd, in, out, uout, uout_size, + callback, context, page_queue); if (IS_ERR(ent)) return PTR_ERR(ent); + /* put for this ent is when consumed, depending on the use case + * 1) (!callback) blocking flow: by caller after wait_func completes + * 2) (callback) flow: by mlx5_cmd_comp_handler() when ent is handled + */ + ent->token = token; ent->polling = force_polling; + init_completion(&ent->handling); if (!callback) init_completion(&ent->done); @@ -1036,11 +1129,11 @@ } if (callback) - goto out; + goto out; /* mlx5_cmd_comp_handler() will put(ent) */ err = wait_func(dev, ent); - if (err == -ETIMEDOUT) - goto out; + if (err == -ETIMEDOUT || err == -ECANCELED) + goto out_free; ds = ent->ts2 - ent->ts1; op = MLX5_GET(mbox_in, in->first.data, opcode); @@ -1057,7 +1150,7 @@ *status = ent->status; out_free: - free_cmd(ent); + cmd_ent_put(ent); out: return err; } @@ -1331,8 +1424,8 @@ return -EFAULT; err = sscanf(outlen_str, "%d", &outlen); - if (err < 0) - return err; + if (err != 1) + return -EINVAL; ptr = kzalloc(outlen, GFP_KERNEL); if (!ptr) @@ -1387,6 +1480,22 @@ mlx5_cmdif_debugfs_init(dev); } +void mlx5_cmd_allowed_opcode(struct mlx5_core_dev *dev, u16 opcode) +{ + struct mlx5_cmd *cmd = &dev->cmd; + int i; + + for (i = 0; i < cmd->max_reg_cmds; i++) + down(&cmd->sem); + down(&cmd->pages_sem); + + cmd->allowed_opcode = opcode; + + up(&cmd->pages_sem); + for (i = 0; i < cmd->max_reg_cmds; i++) + up(&cmd->sem); +} + static void mlx5_cmd_change_mod(struct mlx5_core_dev *dev, int mode) { struct mlx5_cmd *cmd = &dev->cmd; @@ -1461,8 +1570,6 @@ vector = vec & 0xffffffff; for (i = 0; i < (1 << cmd->log_sz); i++) { if (test_bit(i, &vector)) { - struct semaphore *sem; - ent = cmd->ent_arr[i]; /* if we already completed the command, ignore it */ @@ -1472,18 +1579,19 @@ if (!forced) { mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n", ent->idx); - free_ent(cmd, ent->idx); - free_cmd(ent); + cmd_ent_put(ent); } continue; } - if (ent->callback) - cancel_delayed_work(&ent->cb_timeout_work); - if (ent->page_queue) - sem = &cmd->pages_sem; - else - sem = &cmd->sem; + if (ent->callback && cancel_delayed_work(&ent->cb_timeout_work)) + cmd_ent_put(ent); /* timeout work was canceled */ + + if (!forced || /* Real FW completion */ + mlx5_cmd_is_down(dev) || /* No real FW completion is expected */ + !opcode_allowed(cmd, ent->op)) + cmd_ent_put(ent); + ent->ts2 = ktime_get_ns(); memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out)); dump_command(dev, ent, 0); @@ -1501,10 +1609,6 @@ ent->ret, deliv_status_to_str(ent->status), ent->status); } - /* only real completion will free the entry slot */ - if (!forced) - free_ent(cmd, ent->idx); - if (ent->callback) { ds = ent->ts2 - ent->ts1; if (ent->op < ARRAY_SIZE(cmd->stats)) { @@ -1532,21 +1636,26 @@ free_msg(dev, ent->in); err = err ? err : ent->status; - if (!forced) - free_cmd(ent); + /* final consumer is done, release ent */ + cmd_ent_put(ent); callback(err, context); } else { + /* release wait_func() so mlx5_cmd_invoke() + * can make the final ent_put() + */ complete(&ent->done); } - up(sem); } } } void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) { + struct mlx5_cmd *cmd = &dev->cmd; + unsigned long bitmask; unsigned long flags; u64 vector; + int i; /* wait for pending handlers to complete */ mlx5_eq_synchronize_cmd_irq(dev); @@ -1555,11 +1664,20 @@ if (!vector) goto no_trig; + bitmask = vector; + /* we must increment the allocated entries refcount before triggering the completions + * to guarantee pending commands will not get freed in the meanwhile. + * For that reason, it also has to be done inside the alloc_lock. + */ + for_each_set_bit(i, &bitmask, (1 << cmd->log_sz)) + cmd_ent_get(cmd->ent_arr[i]); vector |= MLX5_TRIGGERED_CMD_COMP; spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags); mlx5_core_dbg(dev, "vector 0x%llx\n", vector); mlx5_cmd_comp_handler(dev, vector, true); + for_each_set_bit(i, &bitmask, (1 << cmd->log_sz)) + cmd_ent_put(cmd->ent_arr[i]); return; no_trig: @@ -1571,12 +1689,17 @@ struct mlx5_cmd *cmd = &dev->cmd; int i; - for (i = 0; i < cmd->max_reg_cmds; i++) - while (down_trylock(&cmd->sem)) + for (i = 0; i < cmd->max_reg_cmds; i++) { + while (down_trylock(&cmd->sem)) { mlx5_cmd_trigger_completions(dev); + cond_resched(); + } + } - while (down_trylock(&cmd->pages_sem)) + while (down_trylock(&cmd->pages_sem)) { mlx5_cmd_trigger_completions(dev); + cond_resched(); + } /* Unlock cmdif */ up(&cmd->pages_sem); @@ -1663,12 +1786,11 @@ int err; u8 status = 0; u32 drv_synd; + u16 opcode; u8 token; - if (pci_channel_offline(dev->pdev) || - dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) { - u16 opcode = MLX5_GET(mbox_in, in, opcode); - + opcode = MLX5_GET(mbox_in, in, opcode); + if (mlx5_cmd_is_down(dev) || !opcode_allowed(&dev->cmd, opcode)) { err = mlx5_internal_err_ret_value(dev, opcode, &drv_synd, &status); MLX5_SET(mbox_out, out, status, status); MLX5_SET(mbox_out, out, syndrome, drv_synd); @@ -1738,7 +1860,7 @@ ctx->dev = dev; /* Starts at 1 to avoid doing wake_up if we are not cleaning up */ atomic_set(&ctx->num_inflight, 1); - init_waitqueue_head(&ctx->wait); + init_completion(&ctx->inflight_done); } EXPORT_SYMBOL(mlx5_cmd_init_async_ctx); @@ -1752,8 +1874,8 @@ */ void mlx5_cmd_cleanup_async_ctx(struct mlx5_async_ctx *ctx) { - atomic_dec(&ctx->num_inflight); - wait_event(ctx->wait, atomic_read(&ctx->num_inflight) == 0); + if (!atomic_dec_and_test(&ctx->num_inflight)) + wait_for_completion(&ctx->inflight_done); } EXPORT_SYMBOL(mlx5_cmd_cleanup_async_ctx); @@ -1764,7 +1886,7 @@ work->user_callback(status, work); if (atomic_dec_and_test(&ctx->num_inflight)) - wake_up(&ctx->wait); + complete(&ctx->inflight_done); } int mlx5_cmd_exec_cb(struct mlx5_async_ctx *ctx, void *in, int in_size, @@ -1780,7 +1902,7 @@ ret = cmd_exec(ctx->dev, in, in_size, out, out_size, mlx5_cmd_exec_cb_handler, work, false); if (ret && atomic_dec_and_test(&ctx->num_inflight)) - wake_up(&ctx->wait); + complete(&ctx->inflight_done); return ret; } @@ -1933,6 +2055,7 @@ goto err_free_page; } + cmd->state = MLX5_CMDIF_STATE_DOWN; cmd->checksum_disabled = 1; cmd->max_reg_cmds = (1 << cmd->log_sz) - 1; cmd->bitmask = (1UL << cmd->max_reg_cmds) - 1; @@ -1970,6 +2093,7 @@ mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma)); cmd->mode = CMD_MODE_POLLING; + cmd->allowed_opcode = CMD_ALLOWED_OPCODE_ALL; create_msg_cache(dev); @@ -2009,3 +2133,10 @@ dma_pool_destroy(cmd->pool); } EXPORT_SYMBOL(mlx5_cmd_cleanup); + +void mlx5_cmd_set_state(struct mlx5_core_dev *dev, + enum mlx5_cmdif_state cmdif_state) +{ + dev->cmd.state = cmdif_state; +} +EXPORT_SYMBOL(mlx5_cmd_set_state); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -23,7 +23,10 @@ if (err) return err; - return mlx5_firmware_flash(dev, fw, extack); + err = mlx5_firmware_flash(dev, fw, extack); + release_firmware(fw); + + return err; } static u8 mlx5_fw_ver_major(u32 version) @@ -52,7 +55,7 @@ u32 running_fw, stored_fw; int err; - err = devlink_info_driver_name_put(req, DRIVER_NAME); + err = devlink_info_driver_name_put(req, KBUILD_MODNAME); if (err) return err; @@ -85,6 +88,22 @@ return 0; } +static int mlx5_devlink_reload_down(struct devlink *devlink, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + + return mlx5_unload_one(dev, false); +} + +static int mlx5_devlink_reload_up(struct devlink *devlink, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + + return mlx5_load_one(dev, false); +} + static const struct devlink_ops mlx5_devlink_ops = { #ifdef CONFIG_MLX5_ESWITCH .eswitch_mode_set = mlx5_devlink_eswitch_mode_set, @@ -96,6 +115,8 @@ #endif .flash_update = mlx5_devlink_flash_update, .info_get = mlx5_devlink_info_get, + .reload_down = mlx5_devlink_reload_down, + .reload_up = mlx5_devlink_reload_up, }; struct devlink *mlx5_devlink_alloc(void) @@ -177,12 +198,29 @@ MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE, }; +static int mlx5_devlink_enable_roce_validate(struct devlink *devlink, u32 id, + union devlink_param_value val, + struct netlink_ext_ack *extack) +{ + struct mlx5_core_dev *dev = devlink_priv(devlink); + bool new_state = val.vbool; + + if (new_state && !MLX5_CAP_GEN(dev, roce)) { + NL_SET_ERR_MSG_MOD(extack, "Device doesn't support RoCE"); + return -EOPNOTSUPP; + } + + return 0; +} + static const struct devlink_param mlx5_devlink_params[] = { DEVLINK_PARAM_DRIVER(MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE, "flow_steering_mode", DEVLINK_PARAM_TYPE_STRING, BIT(DEVLINK_PARAM_CMODE_RUNTIME), mlx5_devlink_fs_mode_get, mlx5_devlink_fs_mode_set, mlx5_devlink_fs_mode_validate), + DEVLINK_PARAM_GENERIC(ENABLE_ROCE, BIT(DEVLINK_PARAM_CMODE_DRIVERINIT), + NULL, NULL, mlx5_devlink_enable_roce_validate), }; static void mlx5_devlink_set_params_init_values(struct devlink *devlink) @@ -197,6 +235,11 @@ devlink_param_driverinit_value_set(devlink, MLX5_DEVLINK_PARAM_FLOW_STEERING_MODE, value); + + value.vbool = MLX5_CAP_GEN(dev, roce); + devlink_param_driverinit_value_set(devlink, + DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE, + value); } int mlx5_devlink_register(struct devlink *devlink, struct device *dev) @@ -213,6 +256,7 @@ goto params_reg_err; mlx5_devlink_set_params_init_values(devlink); devlink_params_publish(devlink); + devlink_reload_enable(devlink); return 0; params_reg_err: @@ -222,6 +266,7 @@ void mlx5_devlink_unregister(struct devlink *devlink) { + devlink_reload_disable(devlink); devlink_params_unregister(devlink, mlx5_devlink_params, ARRAY_SIZE(mlx5_devlink_params)); devlink_unregister(devlink); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -480,7 +480,7 @@ (u64)timestamp_low; break; default: - if (tracer_event->event_id >= tracer->str_db.first_string_trace || + if (tracer_event->event_id >= tracer->str_db.first_string_trace && tracer_event->event_id <= tracer->str_db.first_string_trace + tracer->str_db.num_string_trace) { tracer_event->type = TRACER_EVENT_TYPE_STRING; @@ -600,7 +600,7 @@ } else { cur_string = mlx5_tracer_message_get(tracer, tracer_event); if (!cur_string) { - pr_debug("%s Got string event for unknown string tdsm: %d\n", + pr_debug("%s Got string event for unknown string tmsn: %d\n", __func__, tracer_event->string_event.tmsn); return -1; } @@ -636,7 +636,7 @@ trace_timestamp = (timestamp_event.timestamp & MASK_52_7) | (str_frmt->timestamp & MASK_6_0); else - trace_timestamp = ((timestamp_event.timestamp & MASK_52_7) - 1) | + trace_timestamp = ((timestamp_event.timestamp - 1) & MASK_52_7) | (str_frmt->timestamp & MASK_6_0); mlx5_tracer_print_trace(str_frmt, dev, trace_timestamp); @@ -673,6 +673,9 @@ if (!tracer->owner) return; + if (unlikely(!tracer->str_db.loaded)) + goto arm; + block_count = tracer->buff.size / TRACER_BLOCK_SIZE_BYTE; start_offset = tracer->buff.consumer_index * TRACER_BLOCK_SIZE_BYTE; @@ -684,8 +687,8 @@ get_block_timestamp(tracer, &tmp_trace_block[TRACES_PER_BLOCK - 1]); while (block_timestamp > tracer->last_timestamp) { - /* Check block override if its not the first block */ - if (!tracer->last_timestamp) { + /* Check block override if it's not the first block */ + if (tracer->last_timestamp) { u64 *ts_event; /* To avoid block override be the HW in case of buffer * wraparound, the time stamp of the previous block @@ -730,6 +733,7 @@ &tmp_trace_block[TRACES_PER_BLOCK - 1]); } +arm: mlx5_fw_tracer_arm(dev); } @@ -935,7 +939,7 @@ return NULL; } - tracer = kzalloc(sizeof(*tracer), GFP_KERNEL); + tracer = kvzalloc(sizeof(*tracer), GFP_KERNEL); if (!tracer) return ERR_PTR(-ENOMEM); @@ -982,7 +986,7 @@ tracer->dev = NULL; destroy_workqueue(tracer->work_queue); free_tracer: - kfree(tracer); + kvfree(tracer); return ERR_PTR(err); } @@ -1005,7 +1009,7 @@ err = mlx5_core_alloc_pd(dev, &tracer->buff.pdn); if (err) { mlx5_core_warn(dev, "FWTracer: Failed to allocate PD %d\n", err); - return err; + goto err_cancel_work; } err = mlx5_fw_tracer_create_mkey(tracer); @@ -1017,12 +1021,20 @@ MLX5_NB_INIT(&tracer->nb, fw_tracer_event, DEVICE_TRACER); mlx5_eq_notifier_register(dev, &tracer->nb); - mlx5_fw_tracer_start(tracer); - + err = mlx5_fw_tracer_start(tracer); + if (err) { + mlx5_core_warn(dev, "FWTracer: Failed to start tracer %d\n", err); + goto err_notifier_unregister; + } return 0; +err_notifier_unregister: + mlx5_eq_notifier_unregister(dev, &tracer->nb); + mlx5_core_destroy_mkey(dev, &tracer->buff.mkey); err_dealloc_pd: mlx5_core_dealloc_pd(dev, tracer->buff.pdn); +err_cancel_work: + cancel_work_sync(&tracer->read_fw_strings_work); return err; } @@ -1061,7 +1073,7 @@ mlx5_fw_tracer_destroy_log_buf(tracer); flush_workqueue(tracer->work_queue); destroy_workqueue(tracer->work_queue); - kfree(tracer); + kvfree(tracer); } static int fw_tracer_event(struct notifier_block *nb, unsigned long action, void *data) @@ -1076,8 +1088,7 @@ queue_work(tracer->work_queue, &tracer->ownership_change_work); break; case MLX5_TRACER_SUBTYPE_TRACES_AVAILABLE: - if (likely(tracer->str_db.loaded)) - queue_work(tracer->work_queue, &tracer->handle_traces_work); + queue_work(tracer->work_queue, &tracer->handle_traces_work); break; default: mlx5_core_dbg(dev, "FWTracer: Event with unrecognized subtype: sub_type %d\n", --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -92,11 +92,16 @@ #define MLX5_MPWRQ_PAGES_PER_WQE BIT(MLX5_MPWRQ_WQE_PAGE_ORDER) #define MLX5_MTT_OCTW(npages) (ALIGN(npages, 8) / 2) -#define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE, 8)) +/* Add another page to MLX5E_REQUIRED_WQE_MTTS as a buffer between + * WQEs, This page will absorb write overflow by the hardware, when + * receiving packets larger than MTU. These oversize packets are + * dropped by the driver at a later stage. + */ +#define MLX5E_REQUIRED_WQE_MTTS (ALIGN(MLX5_MPWRQ_PAGES_PER_WQE + 1, 8)) #define MLX5E_LOG_ALIGNED_MPWQE_PPW (ilog2(MLX5E_REQUIRED_WQE_MTTS)) #define MLX5E_REQUIRED_MTTS(wqes) (wqes * MLX5E_REQUIRED_WQE_MTTS) #define MLX5E_MAX_RQ_NUM_MTTS \ - ((1 << 16) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ + (ALIGN_DOWN(U16_MAX, 4) * 2) /* So that MLX5_MTT_OCTW(num_mtts) fits into u16 */ #define MLX5E_ORDER2_MAX_PACKET_MTU (order_base_2(10 * 1024)) #define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW \ (ilog2(MLX5E_MAX_RQ_NUM_MTTS / MLX5E_REQUIRED_WQE_MTTS)) @@ -367,10 +372,12 @@ MLX5E_SQ_STATE_AM, MLX5E_SQ_STATE_TLS, MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE, + MLX5E_SQ_STATE_PENDING_XSK_TX, }; struct mlx5e_sq_wqe_info { u8 opcode; + u8 num_wqebbs; /* Auxiliary data for different opcodes. */ union { @@ -692,6 +699,7 @@ u32 rqn; struct mlx5_core_dev *mdev; struct mlx5_core_mkey umr_mkey; + struct mlx5e_dma_info wqe_overflow; /* XDP read-mostly */ struct xdp_rxq_info xdp_rxq; @@ -760,7 +768,7 @@ MLX5E_STATE_OPENED, MLX5E_STATE_DESTROYING, MLX5E_STATE_XDP_TX_ENABLED, - MLX5E_STATE_XDP_OPEN, + MLX5E_STATE_XDP_ACTIVE, }; struct mlx5e_rqt { @@ -816,7 +824,7 @@ struct mlx5e_priv { /* priv data path fields - start */ struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC]; - int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC]; + int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC]; #ifdef CONFIG_MLX5_CORE_EN_DCB struct mlx5e_dcbx_dp dcbx_dp; #endif @@ -947,7 +955,7 @@ void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe); bool mlx5e_post_rx_wqes(struct mlx5e_rq *rq); -void mlx5e_poll_ico_cq(struct mlx5e_cq *cq); +int mlx5e_poll_ico_cq(struct mlx5e_cq *cq); bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq); void mlx5e_dealloc_rx_wqe(struct mlx5e_rq *rq, u16 ix); void mlx5e_dealloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix); @@ -1034,14 +1042,15 @@ struct mlx5e_channels *chs); void mlx5e_close_channels(struct mlx5e_channels *chs); -/* Function pointer to be used to modify WH settings while +/* Function pointer to be used to modify HW or kernel settings while * switching channels */ -typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv); +typedef int (*mlx5e_fp_preactivate)(struct mlx5e_priv *priv); int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv); int mlx5e_safe_switch_channels(struct mlx5e_priv *priv, struct mlx5e_channels *new_chs, - mlx5e_fp_hw_modify hw_modify); + mlx5e_fp_preactivate preactivate); +int mlx5e_num_channels_changed(struct mlx5e_priv *priv); void mlx5e_activate_priv_channels(struct mlx5e_priv *priv); void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv); @@ -1058,6 +1067,7 @@ void mlx5e_activate_rq(struct mlx5e_rq *rq); void mlx5e_deactivate_rq(struct mlx5e_rq *rq); void mlx5e_free_rx_descs(struct mlx5e_rq *rq); +void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq); void mlx5e_activate_icosq(struct mlx5e_icosq *icosq); void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq); @@ -1099,7 +1109,7 @@ int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv); int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc); -void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc); +void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv); int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs); void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h @@ -122,6 +122,22 @@ #endif }; +#define MLX5E_TTC_NUM_GROUPS 3 +#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT) +#define MLX5E_TTC_GROUP2_SIZE BIT(1) +#define MLX5E_TTC_GROUP3_SIZE BIT(0) +#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ + MLX5E_TTC_GROUP2_SIZE +\ + MLX5E_TTC_GROUP3_SIZE) + +#define MLX5E_INNER_TTC_NUM_GROUPS 3 +#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3) +#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1) +#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0) +#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\ + MLX5E_INNER_TTC_GROUP2_SIZE +\ + MLX5E_INNER_TTC_GROUP3_SIZE) + #ifdef CONFIG_MLX5_EN_RXNFC struct mlx5e_ethtool_table { @@ -218,18 +234,12 @@ void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv, struct ttc_params *ttc_params); void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params); -void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params); int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, struct mlx5e_ttc_table *ttc); void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv, struct mlx5e_ttc_table *ttc); -int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, - struct mlx5e_ttc_table *ttc); -void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, - struct mlx5e_ttc_table *ttc); - void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft); void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/health.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/health.c @@ -197,9 +197,10 @@ struct devlink_health_reporter *reporter, char *err_str, struct mlx5e_err_ctx *err_ctx) { - if (!reporter) { - netdev_err(priv->netdev, err_str); - return err_ctx->recover(&err_ctx->ctx); - } + netdev_err(priv->netdev, err_str); + + if (!reporter) + return err_ctx->recover(err_ctx->ctx); + return devlink_health_report(reporter, err_str, err_ctx); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/health.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/health.h @@ -10,8 +10,7 @@ static inline bool cqe_syndrome_needs_recover(u8 syndrome) { - return syndrome == MLX5_CQE_SYNDROME_LOCAL_LENGTH_ERR || - syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || + return syndrome == MLX5_CQE_SYNDROME_LOCAL_QP_OP_ERR || syndrome == MLX5_CQE_SYNDROME_LOCAL_PROT_ERR || syndrome == MLX5_CQE_SYNDROME_WR_FLUSH_ERR; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/port.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/port.c @@ -73,15 +73,31 @@ [MLX5E_50GAUI_2_LAUI_2_50GBASE_CR2_KR2] = 50000, [MLX5E_50GAUI_1_LAUI_1_50GBASE_CR_KR] = 50000, [MLX5E_CAUI_4_100GBASE_CR4_KR4] = 100000, + [MLX5E_100GAUI_2_100GBASE_CR2_KR2] = 100000, [MLX5E_200GAUI_4_200GBASE_CR4_KR4] = 200000, [MLX5E_400GAUI_8] = 400000, }; +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev) +{ + struct mlx5e_port_eth_proto eproto; + int err; + + if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet)) + return true; + + err = mlx5_port_query_eth_proto(mdev, 1, true, &eproto); + if (err) + return false; + + return !!eproto.cap; +} + static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev, const u32 **arr, u32 *size, bool force_legacy) { - bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + bool ext = force_legacy ? false : mlx5e_ptys_ext_supported(mdev); *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) : ARRAY_SIZE(mlx5e_link_speed); @@ -176,7 +192,7 @@ bool ext; int err; - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + ext = mlx5e_ptys_ext_supported(mdev); err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); if (err) goto out; @@ -204,7 +220,7 @@ int err; int i; - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + ext = mlx5e_ptys_ext_supported(mdev); err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/port.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/port.h @@ -54,7 +54,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, bool force_legacy); - +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev); int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out); int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in); int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c @@ -155,8 +155,11 @@ } if (port_buffer->buffer[i].size < - (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) + (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) { + pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n", + i, port_buffer->buffer[i].size); return -ENOMEM; + } port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff; port_buffer->buffer[i].xon = @@ -232,6 +235,26 @@ return 0; } +static int fill_pfc_en(struct mlx5_core_dev *mdev, u8 *pfc_en) +{ + u32 g_rx_pause, g_tx_pause; + int err; + + err = mlx5_query_port_pause(mdev, &g_rx_pause, &g_tx_pause); + if (err) + return err; + + /* If global pause enabled, set all active buffers to lossless. + * Otherwise, check PFC setting. + */ + if (g_rx_pause || g_tx_pause) + *pfc_en = 0xff; + else + err = mlx5_query_port_pfc(mdev, pfc_en, NULL); + + return err; +} + #define MINIMUM_MAX_MTU 9216 int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, u32 change, unsigned int mtu, @@ -277,7 +300,7 @@ if (change & MLX5E_PORT_BUFFER_PRIO2BUFFER) { update_prio2buffer = true; - err = mlx5_query_port_pfc(priv->mdev, &curr_pfc_en, NULL); + err = fill_pfc_en(priv->mdev, &curr_pfc_en); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c @@ -90,7 +90,7 @@ goto out; mlx5e_reset_icosq_cc_pc(icosq); - mlx5e_free_rx_descs(rq); + mlx5e_free_rx_in_progress_descs(rq); clear_bit(MLX5E_SQ_STATE_RECOVERING, &icosq->state); mlx5e_activate_icosq(icosq); mlx5e_activate_rq(rq); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c @@ -144,10 +144,10 @@ #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) int ret; - ret = ipv6_stub->ipv6_dst_lookup(dev_net(mirred_dev), NULL, &dst, - fl6); - if (ret < 0) - return ret; + dst = ipv6_stub->ipv6_dst_lookup_flow(dev_net(mirred_dev), NULL, fl6, + NULL); + if (IS_ERR(dst)) + return PTR_ERR(dst); if (!(*out_ttl)) *out_ttl = ip6_dst_hoplimit(dst); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_geneve.c @@ -227,6 +227,10 @@ option_key = (struct geneve_opt *)&enc_opts.key->data[0]; option_mask = (struct geneve_opt *)&enc_opts.mask->data[0]; + if (option_mask->opt_class == 0 && option_mask->type == 0 && + !memchr_inv(option_mask->opt_data, 0, option_mask->length * 4)) + return 0; + if (option_key->length > max_tlv_option_data_len) { NL_SET_ERR_MSG_MOD(extack, "Matching on GENEVE options: unsupported option len"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h @@ -27,6 +27,11 @@ #define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start)) +static inline bool mlx5e_skb_is_multicast(struct sk_buff *skb) +{ + return skb->pkt_type == PACKET_MULTICAST || skb->pkt_type == PACKET_BROADCAST; +} + static inline bool mlx5e_wqc_has_room_for(struct mlx5_wq_cyc *wq, u16 cc, u16 pc, u16 n) { @@ -179,6 +184,16 @@ } } +static inline void mlx5e_rqwq_reset(struct mlx5e_rq *rq) +{ + if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { + mlx5_wq_ll_reset(&rq->mpwqe.wq); + rq->mpwqe.actual_wq_head = 0; + } else { + mlx5_wq_cyc_reset(&rq->wqe.wq); + } +} + /* SW parser related functions */ struct mlx5e_swp_spec { @@ -189,6 +204,15 @@ u8 tun_l4_proto; }; +static inline void mlx5e_eseg_swp_offsets_add_vlan(struct mlx5_wqe_eth_seg *eseg) +{ + /* SWP offsets are in 2-bytes words */ + eseg->swp_outer_l3_offset += VLAN_HLEN / 2; + eseg->swp_outer_l4_offset += VLAN_HLEN / 2; + eseg->swp_inner_l3_offset += VLAN_HLEN / 2; + eseg->swp_inner_l4_offset += VLAN_HLEN / 2; +} + static inline void mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, struct mlx5e_swp_spec *swp_spec) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h @@ -75,12 +75,18 @@ static inline void mlx5e_xdp_tx_enable(struct mlx5e_priv *priv) { set_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); + + if (priv->channels.params.xdp_prog) + set_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); } static inline void mlx5e_xdp_tx_disable(struct mlx5e_priv *priv) { + if (priv->channels.params.xdp_prog) + clear_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); + clear_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); - /* let other device's napi(s) see our new state */ + /* Let other device's napi(s) and XSK wakeups see our new state. */ synchronize_rcu(); } @@ -89,19 +95,9 @@ return test_bit(MLX5E_STATE_XDP_TX_ENABLED, &priv->state); } -static inline void mlx5e_xdp_set_open(struct mlx5e_priv *priv) -{ - set_bit(MLX5E_STATE_XDP_OPEN, &priv->state); -} - -static inline void mlx5e_xdp_set_closed(struct mlx5e_priv *priv) -{ - clear_bit(MLX5E_STATE_XDP_OPEN, &priv->state); -} - -static inline bool mlx5e_xdp_is_open(struct mlx5e_priv *priv) +static inline bool mlx5e_xdp_is_active(struct mlx5e_priv *priv) { - return test_bit(MLX5E_STATE_XDP_OPEN, &priv->state); + return test_bit(MLX5E_STATE_XDP_ACTIVE, &priv->state); } static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_xdpsq *sq) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c @@ -144,6 +144,7 @@ { clear_bit(MLX5E_CHANNEL_STATE_XSK, c->state); napi_synchronize(&c->napi); + synchronize_rcu(); /* Sync with the XSK wakeup. */ mlx5e_close_rq(&c->xskrq); mlx5e_close_cq(&c->xskrq.cq); @@ -151,6 +152,10 @@ mlx5e_close_cq(&c->xskicosq.cq); mlx5e_close_xdpsq(&c->xsksq); mlx5e_close_cq(&c->xsksq.cq); + + memset(&c->xskrq, 0, sizeof(c->xskrq)); + memset(&c->xsksq, 0, sizeof(c->xsksq)); + memset(&c->xskicosq, 0, sizeof(c->xskicosq)); } void mlx5e_activate_xsk(struct mlx5e_channel *c) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c @@ -14,7 +14,7 @@ struct mlx5e_channel *c; u16 ix; - if (unlikely(!mlx5e_xdp_is_open(priv))) + if (unlikely(!mlx5e_xdp_is_active(priv))) return -ENETDOWN; if (unlikely(!mlx5e_qid_get_ch_if_in_group(params, qid, MLX5E_RQ_GROUP_XSK, &ix))) @@ -33,6 +33,9 @@ if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->xskicosq.state))) return 0; + if (test_and_set_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state)) + return 0; + spin_lock(&c->xskicosq_lock); mlx5e_trigger_irq(&c->xskicosq); spin_unlock(&c->xskicosq_lock); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h @@ -48,7 +48,7 @@ } static inline void -mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg) +mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ihs) { struct mlx5e_swp_spec swp_spec = {}; unsigned int offset = 0; @@ -82,6 +82,8 @@ } mlx5e_set_eseg_swp(skb, eseg, &swp_spec); + if (skb_vlan_tag_present(skb) && ihs) + mlx5e_eseg_swp_offsets_add_vlan(eseg); } #else --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -117,7 +117,6 @@ struct xfrm_replay_state_esn *replay_esn; u32 seq_bottom; u8 overlap; - u32 *esn; if (!(sa_entry->x->props.flags & XFRM_STATE_ESN)) { sa_entry->esn_state.trigger = 0; @@ -130,11 +129,9 @@ sa_entry->esn_state.esn = xfrm_replay_seqhi(sa_entry->x, htonl(seq_bottom)); - esn = &sa_entry->esn_state.esn; sa_entry->esn_state.trigger = 1; if (unlikely(overlap && seq_bottom < MLX5E_IPSEC_ESN_SCOPE_MID)) { - ++(*esn); sa_entry->esn_state.overlap = 0; return true; } else if (unlikely(!overlap && @@ -515,9 +512,6 @@ struct mlx5_core_dev *mdev = priv->mdev; struct net_device *netdev = priv->netdev; - if (!priv->ipsec) - return; - if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) || !MLX5_CAP_ETH(mdev, swp)) { mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c @@ -121,7 +121,9 @@ trailer_len = alen + plen + 2; - pskb_trim(skb, skb->len - trailer_len); + ret = pskb_trim(skb, skb->len - trailer_len); + if (unlikely(ret)) + return ret; if (skb->protocol == htons(ETH_P_IP)) { ipv4hdr->tot_len = htons(ntohs(ipv4hdr->tot_len) - trailer_len); ip_send_check(ipv4hdr); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c @@ -69,8 +69,8 @@ struct mlx5e_ktls_offload_context_tx *tx_priv = mlx5e_get_ktls_tx_priv_ctx(tls_ctx); - mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id); mlx5e_destroy_tis(priv->mdev, tx_priv->tisn); + mlx5_ktls_destroy_key(priv->mdev, tx_priv->key_id); kvfree(tx_priv); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h @@ -38,8 +38,8 @@ enum { MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START = 0, - MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 1, - MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 2, + MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_TRACKING = 1, + MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_SEARCHING = 2, }; struct mlx5e_ktls_offload_context_tx { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -180,7 +180,7 @@ struct tx_sync_info { u64 rcd_sn; - s32 sync_len; + u32 sync_len; int nr_frags; skb_frag_t frags[MAX_SKB_FRAGS]; }; @@ -193,13 +193,14 @@ static enum mlx5e_ktls_sync_retval tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, - u32 tcp_seq, struct tx_sync_info *info) + u32 tcp_seq, int datalen, struct tx_sync_info *info) { struct tls_offload_context_tx *tx_ctx = priv_tx->tx_ctx; enum mlx5e_ktls_sync_retval ret = MLX5E_KTLS_SYNC_DONE; struct tls_record_info *record; int remaining, i = 0; unsigned long flags; + bool ends_before; spin_lock_irqsave(&tx_ctx->lock, flags); record = tls_get_record(tx_ctx, tcp_seq, &info->rcd_sn); @@ -209,9 +210,21 @@ goto out; } - if (unlikely(tcp_seq < tls_record_start_seq(record))) { - ret = tls_record_is_start_marker(record) ? - MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; + /* There are the following cases: + * 1. packet ends before start marker: bypass offload. + * 2. packet starts before start marker and ends after it: drop, + * not supported, breaks contract with kernel. + * 3. packet ends before tls record info starts: drop, + * this packet was already acknowledged and its record info + * was released. + */ + ends_before = before(tcp_seq + datalen - 1, tls_record_start_seq(record)); + + if (unlikely(tls_record_is_start_marker(record))) { + ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; + goto out; + } else if (ends_before) { + ret = MLX5E_KTLS_SYNC_FAIL; goto out; } @@ -220,7 +233,7 @@ while (remaining > 0) { skb_frag_t *frag = &record->frags[i]; - get_page(skb_frag_page(frag)); + page_ref_inc(skb_frag_page(frag)); remaining -= skb_frag_size(frag); info->frags[i++] = *frag; } @@ -308,7 +321,7 @@ stats = sq->stats; mlx5e_tx_dma_unmap(sq->pdev, dma); - put_page(wi->resync_dump_frag_page); + page_ref_dec(wi->resync_dump_frag_page); stats->tls_dump_packets++; stats->tls_dump_bytes += wi->num_bytes; } @@ -337,7 +350,7 @@ u8 num_wqebbs; int i = 0; - ret = tx_sync_info_get(priv_tx, seq, &info); + ret = tx_sync_info_get(priv_tx, seq, datalen, &info); if (unlikely(ret != MLX5E_KTLS_SYNC_DONE)) { if (ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA) { stats->tls_skip_no_sync_data++; @@ -351,14 +364,6 @@ goto err_out; } - if (unlikely(info.sync_len < 0)) { - if (likely(datalen <= -info.sync_len)) - return MLX5E_KTLS_SYNC_DONE; - - stats->tls_drop_bypass_req++; - goto err_out; - } - stats->tls_ooo++; tx_post_resync_params(sq, priv_tx, info.rcd_sn); @@ -378,8 +383,6 @@ if (unlikely(contig_wqebbs_room < num_wqebbs)) mlx5e_fill_sq_frag_edge(sq, wq, pi, contig_wqebbs_room); - tx_post_resync_params(sq, priv_tx, info.rcd_sn); - for (; i < info.nr_frags; i++) { unsigned int orig_fsz, frag_offset = 0, n = 0; skb_frag_t *f = &info.frags[i]; @@ -409,12 +412,12 @@ err_out: for (; i < info.nr_frags; i++) - /* The put_page() here undoes the page ref obtained in tx_sync_info_get(). + /* The page_ref_dec() here undoes the page ref obtained in tx_sync_info_get(). * Page refs obtained for the DUMP WQEs above (by page_ref_add) will be * released only upon their completions (or in mlx5e_free_txqsq_descs, * if channel closes). */ - put_page(skb_frag_page(&info.frags[i])); + page_ref_dec(skb_frag_page(&info.frags[i])); return MLX5E_KTLS_SYNC_FAIL; } @@ -455,12 +458,18 @@ enum mlx5e_ktls_sync_retval ret = mlx5e_ktls_tx_handle_ooo(priv_tx, sq, datalen, seq); - if (likely(ret == MLX5E_KTLS_SYNC_DONE)) + switch (ret) { + case MLX5E_KTLS_SYNC_DONE: *wqe = mlx5e_sq_fetch_wqe(sq, sizeof(**wqe), pi); - else if (ret == MLX5E_KTLS_SYNC_FAIL) + break; + case MLX5E_KTLS_SYNC_SKIP_NO_DATA: + if (likely(!skb->decrypted)) + goto out; + WARN_ON_ONCE(1); + /* fall-through */ + default: /* MLX5E_KTLS_SYNC_FAIL */ goto err_out; - else /* ret == MLX5E_KTLS_SYNC_SKIP_NO_DATA */ - goto out; + } } priv_tx->expected_seq = seq + datalen; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c @@ -269,7 +269,7 @@ int datalen; u32 skb_seq; - if (MLX5_CAP_GEN(sq->channel->mdev, tls)) { + if (MLX5_CAP_GEN(sq->channel->mdev, tls_tx)) { skb = mlx5e_ktls_handle_tx_skb(netdev, sq, skb, wqe, pi); goto out; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_stats.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_stats.c @@ -35,7 +35,6 @@ #include #include "en.h" -#include "accel/tls.h" #include "fpga/sdk.h" #include "en_accel/tls.h" @@ -51,9 +50,14 @@ #define NUM_TLS_SW_COUNTERS ARRAY_SIZE(mlx5e_tls_sw_stats_desc) +static bool is_tls_atomic_stats(struct mlx5e_priv *priv) +{ + return priv->tls && !mlx5_accel_is_ktls_device(priv->mdev); +} + int mlx5e_tls_get_count(struct mlx5e_priv *priv) { - if (!priv->tls) + if (!is_tls_atomic_stats(priv)) return 0; return NUM_TLS_SW_COUNTERS; @@ -63,7 +67,7 @@ { unsigned int i, idx = 0; - if (!priv->tls) + if (!is_tls_atomic_stats(priv)) return 0; for (i = 0; i < NUM_TLS_SW_COUNTERS; i++) @@ -77,7 +81,7 @@ { int i, idx = 0; - if (!priv->tls) + if (!is_tls_atomic_stats(priv)) return 0; for (i = 0; i < NUM_TLS_SW_COUNTERS; i++) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c @@ -227,11 +227,13 @@ ft->g = kcalloc(MLX5E_ARFS_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); - in = kvzalloc(inlen, GFP_KERNEL); - if (!in || !ft->g) { - kvfree(ft->g); - kvfree(in); + if (!ft->g) return -ENOMEM; + + in = kvzalloc(inlen, GFP_KERNEL); + if (!in) { + err = -ENOMEM; + goto err_free_g; } mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); @@ -251,7 +253,7 @@ break; default: err = -EINVAL; - goto out; + goto err_free_in; } switch (type) { @@ -273,7 +275,7 @@ break; default: err = -EINVAL; - goto out; + goto err_free_in; } MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); @@ -282,7 +284,7 @@ MLX5_SET_CFG(in, end_flow_index, ix - 1); ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); if (IS_ERR(ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++; memset(in, 0, inlen); @@ -291,18 +293,20 @@ MLX5_SET_CFG(in, end_flow_index, ix - 1); ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); if (IS_ERR(ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++; kvfree(in); return 0; -err: +err_clean_group: err = PTR_ERR(ft->g[ft->num_groups]); ft->g[ft->num_groups] = NULL; -out: +err_free_in: kvfree(in); - +err_free_g: + kfree(ft->g); + ft->g = NULL; return err; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c @@ -109,12 +109,14 @@ if (!MLX5_CAP_GEN(priv->mdev, ets)) return -EOPNOTSUPP; - ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; - for (i = 0; i < ets->ets_cap; i++) { + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]); if (err) return err; + } + ets->ets_cap = mlx5_max_tc(priv->mdev) + 1; + for (i = 0; i < ets->ets_cap; i++) { err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -40,9 +40,7 @@ { struct mlx5_core_dev *mdev = priv->mdev; - strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver)); - strlcpy(drvinfo->version, DRIVER_VERSION, - sizeof(drvinfo->version)); + strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), @@ -129,6 +127,10 @@ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT); MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, legacy, ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT); + MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100BASE_TX, legacy, + ETHTOOL_LINK_MODE_100baseT_Full_BIT); + MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_T, legacy, + ETHTOOL_LINK_MODE_1000baseT_Full_BIT); MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, legacy, ETHTOOL_LINK_MODE_10000baseT_Full_BIT); MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, legacy, @@ -200,7 +202,7 @@ struct ptys2ethtool_config **arr, u32 *size) { - bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + bool ext = mlx5e_ptys_ext_supported(mdev); *arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table; *size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) : @@ -445,9 +447,7 @@ if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) { *cur_params = new_channels.params; - if (!netif_is_rxfh_configured(priv->netdev)) - mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt, - MLX5E_INDIR_RQT_SIZE, count); + mlx5e_num_channels_changed(priv); goto out; } @@ -455,12 +455,8 @@ if (arfs_enabled) mlx5e_arfs_disable(priv); - if (!netif_is_rxfh_configured(priv->netdev)) - mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt, - MLX5E_INDIR_RQT_SIZE, count); - /* Switch to new channels, set new parameters and close old ones */ - err = mlx5e_safe_switch_channels(priv, &new_channels, NULL); + err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_num_channels_changed); if (arfs_enabled) { int err2 = mlx5e_arfs_enable(priv); @@ -706,11 +702,11 @@ return 0; } -static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings, - u32 eth_proto_cap, - u8 connector_type, bool ext) +static void ptys2ethtool_supported_advertised_port(struct mlx5_core_dev *mdev, + struct ethtool_link_ksettings *link_ksettings, + u32 eth_proto_cap, u8 connector_type) { - if ((!connector_type && !ext) || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) { + if (!MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) { if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR) | MLX5E_PROT_MASK(MLX5E_10GBASE_SR) | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4) @@ -842,9 +838,9 @@ [MLX5E_PORT_OTHER] = PORT_OTHER, }; -static u8 get_connector_port(u32 eth_proto, u8 connector_type, bool ext) +static u8 get_connector_port(struct mlx5_core_dev *mdev, u32 eth_proto, u8 connector_type) { - if ((connector_type || ext) && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER) + if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_connector_type)) return ptys2connector_type[connector_type]; if (eth_proto & @@ -877,7 +873,7 @@ struct ethtool_link_ksettings *link_ksettings) { unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising; - bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + bool ext = mlx5e_ptys_ext_supported(mdev); ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext); } @@ -906,7 +902,7 @@ __func__, err); goto err_query_regs; } - ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability); eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_capability); eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, @@ -943,11 +939,11 @@ link_ksettings); eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; - - link_ksettings->base.port = get_connector_port(eth_proto_oper, - connector_type, ext); - ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin, - connector_type, ext); + connector_type = connector_type < MLX5E_CONNECTOR_TYPE_NUMBER ? + connector_type : MLX5E_PORT_UNKNOWN; + link_ksettings->base.port = get_connector_port(mdev, eth_proto_oper, connector_type); + ptys2ethtool_supported_advertised_port(mdev, link_ksettings, eth_proto_admin, + connector_type); get_lp_advertising(mdev, eth_proto_lp, link_ksettings); if (an_status == MLX5_AN_COMPLETE) @@ -982,6 +978,22 @@ return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings); } +static int mlx5e_speed_validate(struct net_device *netdev, bool ext, + const unsigned long link_modes, u8 autoneg) +{ + /* Extended link-mode has no speed limitations. */ + if (ext) + return 0; + + if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && + autoneg != AUTONEG_ENABLE) { + netdev_err(netdev, "%s: 56G link speed requires autoneg enabled\n", + __func__); + return -EINVAL; + } + return 0; +} + static u32 mlx5e_ethtool2ptys_adver_link(const unsigned long *link_modes) { u32 i, ptys_modes = 0; @@ -1027,18 +1039,11 @@ return bitmap_intersects(modes, adver, __ETHTOOL_LINK_MODE_MASK_NBITS); } -static bool ext_speed_requested(u32 speed) -{ -#define MLX5E_MAX_PTYS_LEGACY_SPEED 100000 - return !!(speed > MLX5E_MAX_PTYS_LEGACY_SPEED); -} - -static bool ext_requested(u8 autoneg, const unsigned long *adver, u32 speed) +static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_supported) { bool ext_link_mode = ext_link_mode_requested(adver); - bool ext_speed = ext_speed_requested(speed); - return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_speed; + return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported; } int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, @@ -1065,8 +1070,8 @@ autoneg = link_ksettings->base.autoneg; speed = link_ksettings->base.speed; - ext = ext_requested(autoneg, adver, speed), - ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); + ext_supported = mlx5e_ptys_ext_supported(mdev); + ext = ext_requested(autoneg, adver, ext_supported); if (!ext_supported && ext) return -EOPNOTSUPP; @@ -1081,13 +1086,9 @@ link_modes = autoneg == AUTONEG_ENABLE ? ethtool2ptys_adver_func(adver) : mlx5e_port_speed2linkmodes(mdev, speed, !ext); - if ((link_modes & MLX5E_PROT_MASK(MLX5E_56GBASE_R4)) && - autoneg != AUTONEG_ENABLE) { - netdev_err(priv->netdev, "%s: 56G link speed requires autoneg enabled\n", - __func__); - err = -EINVAL; + err = mlx5e_speed_validate(priv->netdev, ext, link_modes, autoneg); + if (err) goto out; - } link_modes = link_modes & eproto.cap; if (!link_modes) { @@ -1107,7 +1108,12 @@ if (!an_changes && link_modes == eproto.admin) goto out; - mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); + err = mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext); + if (err) { + netdev_err(priv->netdev, "%s: failed to set ptys reg: %d\n", __func__, err); + goto out; + } + mlx5_toggle_port_link(mdev); out: @@ -1561,6 +1567,10 @@ int mode; int err; + if (bitmap_weight((unsigned long *)&fecparam->fec, + ETHTOOL_FEC_BASER_BIT + 1) > 1) + return -EOPNOTSUPP; + for (mode = 0; mode < ARRAY_SIZE(pplm_fec_2_ethtool); mode++) { if (!(pplm_fec_2_ethtool[mode] & fecparam->fec)) continue; @@ -1643,7 +1653,7 @@ break; case MLX5_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; - modinfo->eeprom_len = MLX5_EEPROM_PAGE_LENGTH; + modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; break; default: netdev_err(priv->netdev, "%s: cable type not recognized:0x%x\n", @@ -1680,7 +1690,7 @@ if (size_read < 0) { netdev_err(priv->netdev, "%s: mlx5_query_eeprom failed:0x%x\n", __func__, size_read); - return 0; + return size_read; } i += size_read; @@ -1808,6 +1818,7 @@ { struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5_core_dev *mdev = priv->mdev; + int err; if (!MLX5_CAP_GEN(mdev, cqe_compression)) return -EOPNOTSUPP; @@ -1817,7 +1828,10 @@ return -EINVAL; } - mlx5e_modify_rx_cqe_compression_locked(priv, enable); + err = mlx5e_modify_rx_cqe_compression_locked(priv, enable); + if (err) + return err; + priv->channels.params.rx_cqe_compress_def = enable; return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -217,6 +217,9 @@ break; } + if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type)) + return 0; + *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); if (IS_ERR(*rule_p)) { @@ -397,8 +400,7 @@ for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID) mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i); - if (priv->fs.vlan.cvlan_filter_disabled && - !(priv->netdev->flags & IFF_PROMISC)) + if (priv->fs.vlan.cvlan_filter_disabled) mlx5e_add_any_vid_rules(priv); } @@ -415,8 +417,12 @@ for_each_set_bit(i, priv->fs.vlan.active_svlans, VLAN_N_VID) mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i); - if (priv->fs.vlan.cvlan_filter_disabled && - !(priv->netdev->flags & IFF_PROMISC)) + WARN_ON_ONCE(!(test_bit(MLX5E_STATE_DESTROYING, &priv->state))); + + /* must be called after DESTROY bit is set and + * set_rx_mode is called and flushed + */ + if (priv->fs.vlan.cvlan_filter_disabled) mlx5e_del_any_vid_rules(priv); } @@ -904,22 +910,6 @@ return err; } -#define MLX5E_TTC_NUM_GROUPS 3 -#define MLX5E_TTC_GROUP1_SIZE (BIT(3) + MLX5E_NUM_TUNNEL_TT) -#define MLX5E_TTC_GROUP2_SIZE BIT(1) -#define MLX5E_TTC_GROUP3_SIZE BIT(0) -#define MLX5E_TTC_TABLE_SIZE (MLX5E_TTC_GROUP1_SIZE +\ - MLX5E_TTC_GROUP2_SIZE +\ - MLX5E_TTC_GROUP3_SIZE) - -#define MLX5E_INNER_TTC_NUM_GROUPS 3 -#define MLX5E_INNER_TTC_GROUP1_SIZE BIT(3) -#define MLX5E_INNER_TTC_GROUP2_SIZE BIT(1) -#define MLX5E_INNER_TTC_GROUP3_SIZE BIT(0) -#define MLX5E_INNER_TTC_TABLE_SIZE (MLX5E_INNER_TTC_GROUP1_SIZE +\ - MLX5E_INNER_TTC_GROUP2_SIZE +\ - MLX5E_INNER_TTC_GROUP3_SIZE) - static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc, bool use_ipv) { @@ -937,6 +927,7 @@ in = kvzalloc(inlen, GFP_KERNEL); if (!in) { kfree(ft->g); + ft->g = NULL; return -ENOMEM; } @@ -1077,6 +1068,7 @@ in = kvzalloc(inlen, GFP_KERNEL); if (!in) { kfree(ft->g); + ft->g = NULL; return -ENOMEM; } @@ -1131,7 +1123,7 @@ ttc_params->inner_ttc = &priv->fs.inner_ttc; } -void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) +static void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params) { struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; @@ -1150,8 +1142,8 @@ ft_attr->prio = MLX5E_NIC_PRIO; } -int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, - struct mlx5e_ttc_table *ttc) +static int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params, + struct mlx5e_ttc_table *ttc) { struct mlx5e_flow_table *ft = &ttc->ft; int err; @@ -1181,8 +1173,8 @@ return err; } -void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, - struct mlx5e_ttc_table *ttc) +static void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv, + struct mlx5e_ttc_table *ttc) { if (!mlx5e_tunnel_inner_ft_supported(priv->mdev)) return; @@ -1356,6 +1348,7 @@ ft->g[ft->num_groups] = NULL; mlx5e_destroy_groups(ft); kvfree(in); + kfree(ft->g); return err; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c @@ -676,7 +676,7 @@ if (num_tuples <= 0) { netdev_warn(priv->netdev, "%s: flow is not valid %d\n", __func__, num_tuples); - return num_tuples; + return num_tuples < 0 ? num_tuples : -EINVAL; } eth_ft = get_flow_table(priv, fs, num_tuples); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -266,12 +266,17 @@ static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev, u64 npages, u8 page_shift, - struct mlx5_core_mkey *umr_mkey) + struct mlx5_core_mkey *umr_mkey, + dma_addr_t filler_addr) { - int inlen = MLX5_ST_SZ_BYTES(create_mkey_in); + struct mlx5_mtt *mtt; + int inlen; void *mkc; u32 *in; int err; + int i; + + inlen = MLX5_ST_SZ_BYTES(create_mkey_in) + sizeof(*mtt) * npages; in = kvzalloc(inlen, GFP_KERNEL); if (!in) @@ -291,6 +296,18 @@ MLX5_SET(mkc, mkc, translations_octword_size, MLX5_MTT_OCTW(npages)); MLX5_SET(mkc, mkc, log_page_size, page_shift); + MLX5_SET(create_mkey_in, in, translations_octword_actual_size, + MLX5_MTT_OCTW(npages)); + + /* Initialize the mkey with all MTTs pointing to a default + * page (filler_addr). When the channels are activated, UMR + * WQEs will redirect the RX WQEs to the actual memory from + * the RQ's pool, while the gaps (wqe_overflow) remain mapped + * to the default page. + */ + mtt = MLX5_ADDR_OF(create_mkey_in, in, klm_pas_mtt); + for (i = 0 ; i < npages ; i++) + mtt[i].ptag = cpu_to_be64(filler_addr); err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen); @@ -302,7 +319,8 @@ { u64 num_mtts = MLX5E_REQUIRED_MTTS(mlx5_wq_ll_get_size(&rq->mpwqe.wq)); - return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey); + return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey, + rq->wqe_overflow.addr); } static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix) @@ -370,6 +388,28 @@ mlx5e_reporter_rq_cqe_err(rq); } +static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq) +{ + rq->wqe_overflow.page = alloc_page(GFP_KERNEL); + if (!rq->wqe_overflow.page) + return -ENOMEM; + + rq->wqe_overflow.addr = dma_map_page(rq->pdev, rq->wqe_overflow.page, 0, + PAGE_SIZE, rq->buff.map_dir); + if (dma_mapping_error(rq->pdev, rq->wqe_overflow.addr)) { + __free_page(rq->wqe_overflow.page); + return -ENOMEM; + } + return 0; +} + +static void mlx5e_free_mpwqe_rq_drop_page(struct mlx5e_rq *rq) +{ + dma_unmap_page(rq->pdev, rq->wqe_overflow.addr, PAGE_SIZE, + rq->buff.map_dir); + __free_page(rq->wqe_overflow.page); +} + static int mlx5e_alloc_rq(struct mlx5e_channel *c, struct mlx5e_params *params, struct mlx5e_xsk_param *xsk, @@ -432,7 +472,11 @@ err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->mpwqe.wq, &rq->wq_ctrl); if (err) - return err; + goto err_rq_wq_destroy; + + err = mlx5e_alloc_mpwqe_rq_drop_page(rq); + if (err) + goto err_rq_wq_destroy; rq->mpwqe.wq.db = &rq->mpwqe.wq.db[MLX5_RCV_DBR]; @@ -474,7 +518,7 @@ err = mlx5e_create_rq_umr_mkey(mdev, rq); if (err) - goto err_rq_wq_destroy; + goto err_rq_drop_page; rq->mkey_be = cpu_to_be32(rq->umr_mkey.key); err = mlx5e_rq_alloc_mpwqe_info(rq, c); @@ -485,7 +529,7 @@ err = mlx5_wq_cyc_create(mdev, &rqp->wq, rqc_wq, &rq->wqe.wq, &rq->wq_ctrl); if (err) - return err; + goto err_rq_wq_destroy; rq->wqe.wq.db = &rq->wqe.wq.db[MLX5_RCV_DBR]; @@ -622,6 +666,8 @@ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: kvfree(rq->mpwqe.info); mlx5_core_destroy_mkey(mdev, &rq->umr_mkey); +err_rq_drop_page: + mlx5e_free_mpwqe_rq_drop_page(rq); break; default: /* MLX5_WQ_TYPE_CYCLIC */ kvfree(rq->wqe.frags); @@ -649,6 +695,7 @@ case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: kvfree(rq->mpwqe.info); mlx5_core_destroy_mkey(rq->mdev, &rq->umr_mkey); + mlx5e_free_mpwqe_rq_drop_page(rq); break; default: /* MLX5_WQ_TYPE_CYCLIC */ kvfree(rq->wqe.frags); @@ -723,6 +770,9 @@ if (!in) return -ENOMEM; + if (curr_state == MLX5_RQC_STATE_RST && next_state == MLX5_RQC_STATE_RDY) + mlx5e_rqwq_reset(rq); + rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); MLX5_SET(modify_rq_in, in, rq_state, curr_state); @@ -821,6 +871,29 @@ return -ETIMEDOUT; } +void mlx5e_free_rx_in_progress_descs(struct mlx5e_rq *rq) +{ + struct mlx5_wq_ll *wq; + u16 head; + int i; + + if (rq->wq_type != MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) + return; + + wq = &rq->mpwqe.wq; + head = wq->head; + + /* Outstanding UMR WQEs (in progress) start at wq->head */ + for (i = 0; i < rq->mpwqe.umr_in_progress; i++) { + rq->dealloc_wqe(rq, head); + head = mlx5_wq_ll_get_wqe_next_ix(wq, head); + } + + rq->mpwqe.actual_wq_head = wq->head; + rq->mpwqe.umr_in_progress = 0; + rq->mpwqe.umr_completed = 0; +} + void mlx5e_free_rx_descs(struct mlx5e_rq *rq) { __be16 wqe_ix_be; @@ -828,14 +901,8 @@ if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) { struct mlx5_wq_ll *wq = &rq->mpwqe.wq; - u16 head = wq->head; - int i; - /* Outstanding UMR WQEs (in progress) start at wq->head */ - for (i = 0; i < rq->mpwqe.umr_in_progress; i++) { - rq->dealloc_wqe(rq, head); - head = mlx5_wq_ll_get_wqe_next_ix(wq, head); - } + mlx5e_free_rx_in_progress_descs(rq); while (!mlx5_wq_ll_is_empty(wq)) { struct mlx5e_rx_wqe_ll *wqe; @@ -1693,11 +1760,10 @@ struct mlx5e_params *params, struct mlx5e_channel_param *cparam) { - struct mlx5e_priv *priv = c->priv; int err, tc; for (tc = 0; tc < params->num_tc; tc++) { - int txq_ix = c->ix + tc * priv->max_nch; + int txq_ix = c->ix + tc * params->num_channels; err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix, params, &cparam->sq, &c->sq[tc], tc); @@ -2299,8 +2365,9 @@ { switch (params->rq_wq_type) { case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ: - return order_base_2(MLX5E_UMR_WQEBBS) + - mlx5e_get_rq_log_wq_sz(rqp->rqc); + return max_t(u8, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE, + order_base_2(MLX5E_UMR_WQEBBS) + + mlx5e_get_rq_log_wq_sz(rqp->rqc)); default: /* MLX5_WQ_TYPE_CYCLIC */ return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE; } @@ -2739,7 +2806,8 @@ mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen); } - if (!mlx5e_tunnel_inner_ft_supported(priv->mdev)) + /* Verify inner tirs resources allocated */ + if (!priv->inner_indir_tir[0].tirn) return; for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { @@ -2878,41 +2946,52 @@ netdev_set_tc_queue(netdev, tc, nch, 0); } -static void mlx5e_build_tc2txq_maps(struct mlx5e_priv *priv) +static void mlx5e_update_netdev_queues(struct mlx5e_priv *priv) { - int i, tc; + int num_txqs = priv->channels.num * priv->channels.params.num_tc; + int num_rxqs = priv->channels.num * priv->profile->rq_groups; + struct net_device *netdev = priv->netdev; - for (i = 0; i < priv->max_nch; i++) - for (tc = 0; tc < priv->profile->max_tc; tc++) - priv->channel_tc2txq[i][tc] = i + tc * priv->max_nch; + mlx5e_netdev_set_tcs(netdev); + netif_set_real_num_tx_queues(netdev, num_txqs); + netif_set_real_num_rx_queues(netdev, num_rxqs); } -static void mlx5e_build_tx2sq_maps(struct mlx5e_priv *priv) +int mlx5e_num_channels_changed(struct mlx5e_priv *priv) { - struct mlx5e_channel *c; - struct mlx5e_txqsq *sq; - int i, tc; + u16 count = priv->channels.params.num_channels; + + if (!netif_is_rxfh_configured(priv->netdev)) + mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt, + MLX5E_INDIR_RQT_SIZE, count); + + return 0; +} + +static void mlx5e_build_txq_maps(struct mlx5e_priv *priv) +{ + int i, ch; + + ch = priv->channels.num; + + for (i = 0; i < ch; i++) { + int tc; + + for (tc = 0; tc < priv->channels.params.num_tc; tc++) { + struct mlx5e_channel *c = priv->channels.c[i]; + struct mlx5e_txqsq *sq = &c->sq[tc]; - for (i = 0; i < priv->channels.num; i++) { - c = priv->channels.c[i]; - for (tc = 0; tc < c->num_tc; tc++) { - sq = &c->sq[tc]; priv->txq2sq[sq->txq_ix] = sq; + priv->channel_tc2realtxq[i][tc] = i + tc * ch; } } } void mlx5e_activate_priv_channels(struct mlx5e_priv *priv) { - int num_txqs = priv->channels.num * priv->channels.params.num_tc; - int num_rxqs = priv->channels.num * priv->profile->rq_groups; - struct net_device *netdev = priv->netdev; - - mlx5e_netdev_set_tcs(netdev); - netif_set_real_num_tx_queues(netdev, num_txqs); - netif_set_real_num_rx_queues(netdev, num_rxqs); + mlx5e_update_netdev_queues(priv); - mlx5e_build_tx2sq_maps(priv); + mlx5e_build_txq_maps(priv); mlx5e_activate_channels(&priv->channels); mlx5e_xdp_tx_enable(priv); netif_tx_start_all_queues(priv->netdev); @@ -2946,7 +3025,7 @@ static void mlx5e_switch_priv_channels(struct mlx5e_priv *priv, struct mlx5e_channels *new_chs, - mlx5e_fp_hw_modify hw_modify) + mlx5e_fp_preactivate preactivate) { struct net_device *netdev = priv->netdev; int new_num_txqs; @@ -2965,9 +3044,11 @@ priv->channels = *new_chs; - /* New channels are ready to roll, modify HW settings if needed */ - if (hw_modify) - hw_modify(priv); + /* New channels are ready to roll, call the preactivate hook if needed + * to modify HW settings or update kernel parameters. + */ + if (preactivate) + preactivate(priv); priv->profile->update_rx(priv); mlx5e_activate_priv_channels(priv); @@ -2979,7 +3060,7 @@ int mlx5e_safe_switch_channels(struct mlx5e_priv *priv, struct mlx5e_channels *new_chs, - mlx5e_fp_hw_modify hw_modify) + mlx5e_fp_preactivate preactivate) { int err; @@ -2987,7 +3068,7 @@ if (err) return err; - mlx5e_switch_priv_channels(priv, new_chs, hw_modify); + mlx5e_switch_priv_channels(priv, new_chs, preactivate); return 0; } @@ -3005,15 +3086,32 @@ priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE; } +static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev, + enum mlx5_port_status state) +{ + struct mlx5_eswitch *esw = mdev->priv.eswitch; + int vport_admin_state; + + mlx5_set_port_admin_status(mdev, state); + + if (!MLX5_ESWITCH_MANAGER(mdev) || mlx5_eswitch_mode(esw) == MLX5_ESWITCH_OFFLOADS || + !MLX5_CAP_GEN(mdev, uplink_follow)) + return; + + if (state == MLX5_PORT_UP) + vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO; + else + vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN; + + mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state); +} + int mlx5e_open_locked(struct net_device *netdev) { struct mlx5e_priv *priv = netdev_priv(netdev); - bool is_xdp = priv->channels.params.xdp_prog; int err; set_bit(MLX5E_STATE_OPENED, &priv->state); - if (is_xdp) - mlx5e_xdp_set_open(priv); err = mlx5e_open_channels(priv, &priv->channels); if (err) @@ -3028,8 +3126,6 @@ return 0; err_clear_state_opened_flag: - if (is_xdp) - mlx5e_xdp_set_closed(priv); clear_bit(MLX5E_STATE_OPENED, &priv->state); return err; } @@ -3042,7 +3138,7 @@ mutex_lock(&priv->state_lock); err = mlx5e_open_locked(netdev); if (!err) - mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP); + mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_UP); mutex_unlock(&priv->state_lock); if (mlx5_vxlan_allowed(priv->mdev->vxlan)) @@ -3061,8 +3157,6 @@ if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) return 0; - if (priv->channels.params.xdp_prog) - mlx5e_xdp_set_closed(priv); clear_bit(MLX5E_STATE_OPENED, &priv->state); netif_carrier_off(priv->netdev); @@ -3081,7 +3175,7 @@ return -ENODEV; mutex_lock(&priv->state_lock); - mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN); + mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_DOWN); err = mlx5e_close_locked(netdev); mutex_unlock(&priv->state_lock); @@ -3380,14 +3474,15 @@ return err; } -void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc) +void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv) { int i; for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]); - if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev)) + /* Verify inner tirs resources allocated */ + if (!priv->inner_indir_tir[0].tirn) return; for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) @@ -3536,6 +3631,7 @@ s->rx_packets += rq_stats->packets + xskrq_stats->packets; s->rx_bytes += rq_stats->bytes + xskrq_stats->bytes; + s->multicast += rq_stats->mcast_packets + xskrq_stats->mcast_packets; for (j = 0; j < priv->max_opened_tc; j++) { struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j]; @@ -3551,10 +3647,14 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) { struct mlx5e_priv *priv = netdev_priv(dev); - struct mlx5e_vport_stats *vstats = &priv->stats.vport; struct mlx5e_pport_stats *pstats = &priv->stats.pport; - if (!mlx5e_monitor_counter_supported(priv)) { + /* In switchdev mode, monitor counters doesn't monitor + * rx/tx stats of 802_3. The update stats mechanism + * should keep the 802_3 layout counters updated + */ + if (!mlx5e_monitor_counter_supported(priv) || + mlx5e_is_uplink_rep(priv)) { /* update HW stats in background for next time */ mlx5e_queue_update_stats(priv); } @@ -3568,7 +3668,7 @@ mlx5e_fold_sw_stats64(priv, stats); } - stats->rx_dropped = priv->stats.qcnt.rx_out_of_buffer; + stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer; stats->rx_length_errors = PPORT_802_3_GET(pstats, a_in_range_length_errors) + @@ -3581,12 +3681,6 @@ stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors + stats->rx_frame_errors; stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors; - - /* vport multicast also counts packets that are dropped due to steering - * or rx out of buffer - */ - stats->multicast = - VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); } static void mlx5e_set_rx_mode(struct net_device *dev) @@ -3706,20 +3800,67 @@ return mlx5_set_port_fcs(mdev, !enable); } +static int mlx5e_set_rx_port_ts(struct mlx5_core_dev *mdev, bool enable) +{ + u32 in[MLX5_ST_SZ_DW(pcmr_reg)] = {}; + bool supported, curr_state; + int err; + + if (!MLX5_CAP_GEN(mdev, ports_check)) + return 0; + + err = mlx5_query_ports_check(mdev, in, sizeof(in)); + if (err) + return err; + + supported = MLX5_GET(pcmr_reg, in, rx_ts_over_crc_cap); + curr_state = MLX5_GET(pcmr_reg, in, rx_ts_over_crc); + + if (!supported || enable == curr_state) + return 0; + + MLX5_SET(pcmr_reg, in, local_port, 1); + MLX5_SET(pcmr_reg, in, rx_ts_over_crc, enable); + + return mlx5_set_ports_check(mdev, in, sizeof(in)); +} + static int set_feature_rx_fcs(struct net_device *netdev, bool enable) { struct mlx5e_priv *priv = netdev_priv(netdev); + struct mlx5e_channels *chs = &priv->channels; + struct mlx5_core_dev *mdev = priv->mdev; int err; mutex_lock(&priv->state_lock); - priv->channels.params.scatter_fcs_en = enable; - err = mlx5e_modify_channels_scatter_fcs(&priv->channels, enable); - if (err) - priv->channels.params.scatter_fcs_en = !enable; + if (enable) { + err = mlx5e_set_rx_port_ts(mdev, false); + if (err) + goto out; - mutex_unlock(&priv->state_lock); + chs->params.scatter_fcs_en = true; + err = mlx5e_modify_channels_scatter_fcs(chs, true); + if (err) { + chs->params.scatter_fcs_en = false; + mlx5e_set_rx_port_ts(mdev, true); + } + } else { + chs->params.scatter_fcs_en = false; + err = mlx5e_modify_channels_scatter_fcs(chs, false); + if (err) { + chs->params.scatter_fcs_en = true; + goto out; + } + err = mlx5e_set_rx_port_ts(mdev, true); + if (err) { + mlx5_core_warn(mdev, "Failed to set RX port timestamp %d\n", err); + err = 0; + } + } +out: + mutex_unlock(&priv->state_lock); return err; } @@ -3761,12 +3902,11 @@ static int mlx5e_handle_feature(struct net_device *netdev, netdev_features_t *features, - netdev_features_t wanted_features, netdev_features_t feature, mlx5e_feature_handler feature_handler) { - netdev_features_t changes = wanted_features ^ netdev->features; - bool enable = !!(wanted_features & feature); + netdev_features_t changes = *features ^ netdev->features; + bool enable = !!(*features & feature); int err; if (!(changes & feature)) @@ -3774,22 +3914,22 @@ err = feature_handler(netdev, enable); if (err) { + MLX5E_SET_FEATURE(features, feature, !enable); netdev_err(netdev, "%s feature %pNF failed, err %d\n", enable ? "Enable" : "Disable", &feature, err); return err; } - MLX5E_SET_FEATURE(features, feature, enable); return 0; } int mlx5e_set_features(struct net_device *netdev, netdev_features_t features) { - netdev_features_t oper_features = netdev->features; + netdev_features_t oper_features = features; int err = 0; #define MLX5E_HANDLE_FEATURE(feature, handler) \ - mlx5e_handle_feature(netdev, &oper_features, features, feature, handler) + mlx5e_handle_feature(netdev, &oper_features, feature, handler) err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro); err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER, @@ -3835,6 +3975,13 @@ } } + if (params->xdp_prog) { + if (features & NETIF_F_LRO) { + netdev_warn(netdev, "LRO is incompatible with XDP\n"); + features &= ~NETIF_F_LRO; + } + } + if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) { features &= ~NETIF_F_RXHASH; if (netdev->features & NETIF_F_RXHASH) @@ -4230,6 +4377,21 @@ mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0); } +static bool mlx5e_gre_tunnel_inner_proto_offload_supported(struct mlx5_core_dev *mdev, + struct sk_buff *skb) +{ + switch (skb->inner_protocol) { + case htons(ETH_P_IP): + case htons(ETH_P_IPV6): + case htons(ETH_P_TEB): + return true; + case htons(ETH_P_MPLS_UC): + case htons(ETH_P_MPLS_MC): + return MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_gre); + } + return false; +} + static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv, struct sk_buff *skb, netdev_features_t features) @@ -4252,7 +4414,9 @@ switch (proto) { case IPPROTO_GRE: - return features; + if (mlx5e_gre_tunnel_inner_proto_offload_supported(priv->mdev, skb)) + return features; + break; case IPPROTO_IPIP: case IPPROTO_IPV6: if (mlx5e_tunnel_proto_supported(priv->mdev, IPPROTO_IPIP)) @@ -4264,7 +4428,7 @@ /* Verify if UDP port is being offloaded by HW */ if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port)) - return features; + return vxlan_features_check(skb, features); #if IS_ENABLED(CONFIG_GENEVE) /* Support Geneve offload for default UDP port */ @@ -4285,7 +4449,6 @@ struct mlx5e_priv *priv = netdev_priv(netdev); features = vlan_features_check(skb, features); - features = vxlan_features_check(skb, features); #ifdef CONFIG_MLX5_EN_IPSEC if (mlx5e_ipsec_feature_check(skb, netdev, features)) @@ -4379,16 +4542,6 @@ return 0; } -static int mlx5e_xdp_update_state(struct mlx5e_priv *priv) -{ - if (priv->channels.params.xdp_prog) - mlx5e_xdp_set_open(priv); - else - mlx5e_xdp_set_closed(priv); - - return 0; -} - static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog) { struct mlx5e_priv *priv = netdev_priv(netdev); @@ -4428,7 +4581,7 @@ mlx5e_set_rq_type(priv->mdev, &new_channels.params); old_prog = priv->channels.params.xdp_prog; - err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_xdp_update_state); + err = mlx5e_safe_switch_channels(priv, &new_channels, NULL); if (err) goto unlock; } else { @@ -4479,6 +4632,11 @@ unlock: mutex_unlock(&priv->state_lock); + + /* Need to fix some features. */ + if (!err) + netdev_update_features(netdev); + return err; } @@ -4906,6 +5064,8 @@ netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM; netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL | + NETIF_F_GSO_UDP_TUNNEL_CSUM; } if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) { @@ -5028,7 +5188,6 @@ if (err) mlx5_core_err(mdev, "TLS initialization failed, %d\n", err); mlx5e_build_nic_netdev(netdev); - mlx5e_build_tc2txq_maps(priv); mlx5e_health_create_reporters(priv); return 0; @@ -5100,7 +5259,7 @@ err_destroy_direct_tirs: mlx5e_destroy_direct_tirs(priv, priv->direct_tir); err_destroy_indirect_tirs: - mlx5e_destroy_indirect_tirs(priv, true); + mlx5e_destroy_indirect_tirs(priv); err_destroy_direct_rqts: mlx5e_destroy_direct_rqts(priv, priv->direct_tir); err_destroy_indirect_rqts: @@ -5119,7 +5278,7 @@ mlx5e_destroy_direct_tirs(priv, priv->xsk_tir); mlx5e_destroy_direct_rqts(priv, priv->xsk_tir); mlx5e_destroy_direct_tirs(priv, priv->direct_tir); - mlx5e_destroy_indirect_tirs(priv, true); + mlx5e_destroy_indirect_tirs(priv); mlx5e_destroy_direct_rqts(priv, priv->direct_tir); mlx5e_destroy_rqt(priv, &priv->indir_rqt); mlx5e_close_drop_rq(&priv->drop_rq); @@ -5151,7 +5310,7 @@ /* Marking the link as currently not needed by the Driver */ if (!netif_running(netdev)) - mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN); + mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN); mlx5e_set_netdev_mtu_boundaries(priv); mlx5e_set_dev_port_mtu(priv); @@ -5312,9 +5471,10 @@ max_nch = mlx5e_get_max_num_channels(priv->mdev); if (priv->channels.params.num_channels > max_nch) { mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); + /* Reducing the number of channels - RXFH has to be reset. */ + priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; priv->channels.params.num_channels = max_nch; - mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt, - MLX5E_INDIR_RQT_SIZE, max_nch); + mlx5e_num_channels_changed(priv); } err = profile->init_tx(priv); @@ -5334,6 +5494,8 @@ profile->cleanup_tx(priv); out: + set_bit(MLX5E_STATE_DESTROYING, &priv->state); + cancel_work_sync(&priv->update_stats_work); return err; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -71,14 +71,17 @@ { struct mlx5e_priv *priv = netdev_priv(dev); struct mlx5_core_dev *mdev = priv->mdev; + int count; strlcpy(drvinfo->driver, mlx5e_rep_driver_name, sizeof(drvinfo->driver)); - strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version)); - snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), - "%d.%d.%04d (%.16s)", - fw_rev_maj(mdev), fw_rev_min(mdev), - fw_rev_sub(mdev), mdev->board_id); + count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), + fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); + if (count >= sizeof(drvinfo->fw_version)) + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), + "%d.%d.%04d", fw_rev_maj(mdev), + fw_rev_min(mdev), fw_rev_sub(mdev)); } static void mlx5e_uplink_rep_get_drvinfo(struct net_device *dev, @@ -1434,6 +1437,8 @@ params->num_tc = 1; params->tunneled_offload_en = false; + if (rep->vport != MLX5_VPORT_UPLINK) + params->vlan_strip_disable = true; mlx5_query_min_inline(mdev, ¶ms->tx_min_inline_mode); @@ -1597,7 +1602,7 @@ err_destroy_direct_tirs: mlx5e_destroy_direct_tirs(priv, priv->direct_tir); err_destroy_indirect_tirs: - mlx5e_destroy_indirect_tirs(priv, false); + mlx5e_destroy_indirect_tirs(priv); err_destroy_direct_rqts: mlx5e_destroy_direct_rqts(priv, priv->direct_tir); err_destroy_indirect_rqts: @@ -1614,7 +1619,7 @@ mlx5_del_flow_rules(rpriv->vport_rx_rule); mlx5e_destroy_ttc_table(priv, &priv->fs.ttc); mlx5e_destroy_direct_tirs(priv, priv->direct_tir); - mlx5e_destroy_indirect_tirs(priv, false); + mlx5e_destroy_indirect_tirs(priv); mlx5e_destroy_direct_rqts(priv, priv->direct_tir); mlx5e_destroy_rqt(priv, &priv->indir_rqt); mlx5e_close_drop_rq(&priv->drop_rq); @@ -1736,6 +1741,9 @@ INIT_WORK(&rpriv->uplink_priv.reoffload_flows_work, mlx5e_tc_reoffload_flows_work); + if (MLX5_CAP_GEN(mdev, uplink_follow)) + mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK, + 0, 0, MLX5_VPORT_ADMIN_STATE_AUTO); mlx5_lag_add(mdev, netdev); priv->events_nb.notifier_call = uplink_rep_async_event; mlx5_notifier_register(mdev, &priv->events_nb); @@ -1814,29 +1822,30 @@ struct mlx5_eswitch_rep *rep = rpriv->rep; struct netdev_phys_item_id ppid = {}; unsigned int dl_port_index = 0; + u16 pfnum; if (!is_devlink_port_supported(dev, rpriv)) return 0; mlx5e_rep_get_port_parent_id(rpriv->netdev, &ppid); + pfnum = PCI_FUNC(dev->pdev->devfn); if (rep->vport == MLX5_VPORT_UPLINK) { devlink_port_attrs_set(&rpriv->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL, - PCI_FUNC(dev->pdev->devfn), false, 0, + pfnum, false, 0, &ppid.id[0], ppid.id_len); dl_port_index = vport_to_devlink_port_index(dev, rep->vport); } else if (rep->vport == MLX5_VPORT_PF) { devlink_port_attrs_pci_pf_set(&rpriv->dl_port, &ppid.id[0], ppid.id_len, - dev->pdev->devfn); + pfnum); dl_port_index = rep->vport; } else if (mlx5_eswitch_is_vf_vport(dev->priv.eswitch, rpriv->rep->vport)) { devlink_port_attrs_pci_vf_set(&rpriv->dl_port, &ppid.id[0], ppid.id_len, - dev->pdev->devfn, - rep->vport - 1); + pfnum, rep->vport - 1); dl_port_index = vport_to_devlink_port_index(dev, rep->vport); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -49,6 +49,7 @@ #include "en/xdp.h" #include "en/xsk/rx.h" #include "en/health.h" +#include "en/txrx.h" static inline bool mlx5e_rx_hw_stamp(struct hwtstamp_config *config) { @@ -247,8 +248,8 @@ if (unlikely(!dma_info->page)) return -ENOMEM; - dma_info->addr = dma_map_page(rq->pdev, dma_info->page, 0, - PAGE_SIZE, rq->buff.map_dir); + dma_info->addr = dma_map_page_attrs(rq->pdev, dma_info->page, 0, PAGE_SIZE, + rq->buff.map_dir, DMA_ATTR_SKIP_CPU_SYNC); if (unlikely(dma_mapping_error(rq->pdev, dma_info->addr))) { page_pool_recycle_direct(rq->page_pool, dma_info->page); dma_info->page = NULL; @@ -269,7 +270,8 @@ void mlx5e_page_dma_unmap(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info) { - dma_unmap_page(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir); + dma_unmap_page_attrs(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir, + DMA_ATTR_SKIP_CPU_SYNC); } void mlx5e_page_release_dynamic(struct mlx5e_rq *rq, @@ -477,6 +479,7 @@ /* fill sq frag edge with nops to avoid wqe wrapping two pages */ for (; wi < edge_wi; wi++) { wi->opcode = MLX5_OPCODE_NOP; + wi->num_wqebbs = 1; mlx5e_post_nop(wq, sq->sqn, &sq->pc); } } @@ -525,6 +528,7 @@ umr_wqe->uctrl.xlt_offset = cpu_to_be16(xlt_offset); sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_UMR; + sq->db.ico_wqe[pi].num_wqebbs = MLX5E_UMR_WQEBBS; sq->db.ico_wqe[pi].umr.rq = rq; sq->pc += MLX5E_UMR_WQEBBS; @@ -585,7 +589,7 @@ return !!err; } -void mlx5e_poll_ico_cq(struct mlx5e_cq *cq) +int mlx5e_poll_ico_cq(struct mlx5e_cq *cq) { struct mlx5e_icosq *sq = container_of(cq, struct mlx5e_icosq, cq); struct mlx5_cqe64 *cqe; @@ -593,11 +597,11 @@ int i; if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state))) - return; + return 0; cqe = mlx5_cqwq_get_cqe(&cq->wq); if (likely(!cqe)) - return; + return 0; /* sq->cc must be updated only after mlx5_cqwq_update_db_record(), * otherwise a cq overrun may occur @@ -628,17 +632,14 @@ ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc); wi = &sq->db.ico_wqe[ci]; + sqcc += wi->num_wqebbs; - if (likely(wi->opcode == MLX5_OPCODE_UMR)) { - sqcc += MLX5E_UMR_WQEBBS; + if (likely(wi->opcode == MLX5_OPCODE_UMR)) wi->umr.rq->mpwqe.umr_completed++; - } else if (likely(wi->opcode == MLX5_OPCODE_NOP)) { - sqcc++; - } else { + else if (unlikely(wi->opcode != MLX5_OPCODE_NOP)) netdev_WARN_ONCE(cq->channel->netdev, "Bad OPCODE in ICOSQ WQE info: 0x%x\n", wi->opcode); - } } while (!last_wqe); @@ -647,6 +648,8 @@ sq->cc = sqcc; mlx5_cqwq_update_db_record(&cq->wq); + + return i; } bool mlx5e_post_rx_mpwqes(struct mlx5e_rq *rq) @@ -1021,6 +1024,9 @@ mlx5e_enable_ecn(rq, skb); skb->protocol = eth_type_trans(skb, netdev); + + if (unlikely(mlx5e_skb_is_multicast(skb))) + stats->mcast_packets++; } static inline void mlx5e_complete_rx_cqe(struct mlx5e_rq *rq, @@ -1427,6 +1433,7 @@ #ifdef CONFIG_MLX5_CORE_IPOIB +#define MLX5_IB_GRH_SGID_OFFSET 8 #define MLX5_IB_GRH_DGID_OFFSET 24 #define MLX5_GID_SIZE 16 @@ -1440,6 +1447,7 @@ struct net_device *netdev; struct mlx5e_priv *priv; char *pseudo_header; + u32 flags_rqpn; u32 qpn; u8 *dgid; u8 g; @@ -1461,7 +1469,8 @@ tstamp = &priv->tstamp; stats = &priv->channel_stats[rq->ix].rq; - g = (be32_to_cpu(cqe->flags_rqpn) >> 28) & 3; + flags_rqpn = be32_to_cpu(cqe->flags_rqpn); + g = (flags_rqpn >> 28) & 3; dgid = skb->data + MLX5_IB_GRH_DGID_OFFSET; if ((!g) || dgid[0] != 0xff) skb->pkt_type = PACKET_HOST; @@ -1470,9 +1479,15 @@ else skb->pkt_type = PACKET_MULTICAST; - /* TODO: IB/ipoib: Allow mcast packets from other VFs - * 68996a6e760e5c74654723eeb57bf65628ae87f4 + /* Drop packets that this interface sent, ie multicast packets + * that the HCA has replicated. */ + if (g && (qpn == (flags_rqpn & 0xffffff)) && + (memcmp(netdev->dev_addr + 4, skb->data + MLX5_IB_GRH_SGID_OFFSET, + MLX5_GID_SIZE) == 0)) { + skb->dev = NULL; + return; + } skb_pull(skb, MLX5_IB_GRH_BYTES); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c @@ -297,6 +297,9 @@ s->tx_tls_drop_bypass_req += sq_stats->tls_drop_bypass_req; #endif s->tx_cqes += sq_stats->cqes; + + /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92657 */ + barrier(); } } } @@ -1601,7 +1604,7 @@ for (j = 0; j < NUM_SQ_STATS; j++) sprintf(data + (idx++) * ETH_GSTRING_LEN, sq_stats_desc[j].format, - priv->channel_tc2txq[i][tc]); + i + tc * max_nch); for (i = 0; i < max_nch; i++) { for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h @@ -68,6 +68,7 @@ u64 tx_nop; u64 rx_lro_packets; u64 rx_lro_bytes; + u64 rx_mcast_packets; u64 rx_ecn_mark; u64 rx_removed_vlan_packets; u64 rx_csum_unnecessary; @@ -235,6 +236,7 @@ u64 csum_none; u64 lro_packets; u64 lro_bytes; + u64 mcast_packets; u64 ecn_mark; u64 removed_vlan_packets; u64 xdp_drop; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -57,6 +57,7 @@ #include "lib/devcom.h" #include "lib/geneve.h" #include "diag/en_tc_tracepoint.h" +#include struct mlx5_nic_flow_attr { u32 action; @@ -443,12 +444,32 @@ static struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) { + struct mlx5_core_dev *mdev; struct net_device *netdev; struct mlx5e_priv *priv; - netdev = __dev_get_by_index(net, ifindex); + netdev = dev_get_by_index(net, ifindex); + if (!netdev) + return ERR_PTR(-ENODEV); + priv = netdev_priv(netdev); - return priv->mdev; + mdev = priv->mdev; + dev_put(netdev); + + /* Mirred tc action holds a refcount on the ifindex net_device (see + * net/sched/act_mirred.c:tcf_mirred_get_dev). So, it's okay to continue using mdev + * after dev_put(netdev), while we're in the context of adding a tc flow. + * + * The mdev pointer corresponds to the peer/out net_device of a hairpin. It is then + * stored in a hairpin object, which exists until all flows, that refer to it, get + * removed. + * + * On the other hand, after a hairpin object has been created, the peer net_device may + * be removed/unbound while there are still some hairpin flows that are using it. This + * case is handled by mlx5e_tc_hairpin_update_dead_peer, which is hooked to + * NETDEV_UNREGISTER event of the peer net_device. + */ + return mdev; } static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) @@ -586,7 +607,7 @@ for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) ttc_params->indir_tirn[tt] = hp->indir_tirn[tt]; - ft_attr->max_fte = MLX5E_NUM_TT; + ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE; ft_attr->level = MLX5E_TC_TTC_FT_LEVEL; ft_attr->prio = MLX5E_TC_PRIO; } @@ -647,6 +668,10 @@ func_mdev = priv->mdev; peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); + if (IS_ERR(peer_mdev)) { + err = PTR_ERR(peer_mdev); + goto create_pair_err; + } pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); if (IS_ERR(pair)) { @@ -785,6 +810,11 @@ int err; peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); + if (IS_ERR(peer_mdev)) { + NL_SET_ERR_MSG_MOD(extack, "invalid ifindex of mirred device"); + return PTR_ERR(peer_mdev); + } + if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); return -EOPNOTSUPP; @@ -1615,8 +1645,11 @@ flow_flag_clear(flow, DUP); - mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow); - kvfree(flow->peer_flow); + if (refcount_dec_and_test(&flow->peer_flow->refcnt)) { + mlx5e_tc_del_fdb_flow(flow->peer_flow->priv, flow->peer_flow); + kfree(flow->peer_flow); + } + flow->peer_flow = NULL; } @@ -1834,8 +1867,8 @@ BIT(FLOW_DISSECTOR_KEY_ENC_IP) | BIT(FLOW_DISSECTOR_KEY_ENC_OPTS))) { NL_SET_ERR_MSG_MOD(extack, "Unsupported key"); - netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n", - dissector->used_keys); + netdev_dbg(priv->netdev, "Unsupported key used: 0x%x\n", + dissector->used_keys); return -EOPNOTSUPP; } @@ -2421,10 +2454,11 @@ field_bsize = f->size * BITS_PER_BYTE; if (field_bsize == 32) { - mask_be32 = *(__be32 *)&mask; + mask_be32 = (__be32)mask; mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); } else if (field_bsize == 16) { - mask_be16 = *(__be16 *)&mask; + mask_be32 = (__be32)mask; + mask_be16 = *(__be16 *)&mask_be32; mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); } @@ -3166,8 +3200,12 @@ if (err) return err; - *out_dev = dev_get_by_index_rcu(dev_net(vlan_dev), - dev_get_iflink(vlan_dev)); + rcu_read_lock(); + *out_dev = dev_get_by_index_rcu(dev_net(vlan_dev), dev_get_iflink(vlan_dev)); + rcu_read_unlock(); + if (!*out_dev) + return -ENODEV; + if (is_vlan_dev(*out_dev)) err = add_vlan_push_action(priv, attr, out_dev, action); @@ -3178,12 +3216,13 @@ struct mlx5_esw_flow_attr *attr, u32 *action) { - int nest_level = attr->parse_attr->filter_dev->lower_level; struct flow_action_entry vlan_act = { .id = FLOW_ACTION_VLAN_POP, }; - int err = 0; + int nest_level, err = 0; + nest_level = attr->parse_attr->filter_dev->lower_level - + priv->netdev->lower_level; while (nest_level--) { err = parse_tc_vlan_action(priv, &vlan_act, attr, action); if (err) @@ -3443,6 +3482,12 @@ attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; } + if (!(attr->action & + (MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | MLX5_FLOW_CONTEXT_ACTION_DROP))) { + NL_SET_ERR_MSG(extack, "Rule must have at least one forward/drop action"); + return -EOPNOTSUPP; + } + if (attr->split_count > 0 && !mlx5_esw_has_fwd_fdb(priv->mdev)) { NL_SET_ERR_MSG_MOD(extack, "current firmware doesn't support split rule for port mirroring"); @@ -3933,15 +3978,22 @@ return err; } -static int apply_police_params(struct mlx5e_priv *priv, u32 rate, +static int apply_police_params(struct mlx5e_priv *priv, u64 rate, struct netlink_ext_ack *extack) { struct mlx5e_rep_priv *rpriv = priv->ppriv; struct mlx5_eswitch *esw; + u32 rate_mbps = 0; u16 vport_num; - u32 rate_mbps; int err; + vport_num = rpriv->rep->vport; + if (vport_num >= MLX5_VPORT_ECPF) { + NL_SET_ERR_MSG_MOD(extack, + "Ingress rate limit is supported only for Eswitch ports connected to VFs"); + return -EOPNOTSUPP; + } + esw = priv->mdev->priv.eswitch; /* rate is given in bytes/sec. * First convert to bits/sec and then round to the nearest mbit/secs. @@ -3949,8 +4001,10 @@ * Moreover, if rate is non zero we choose to configure to a minimum of * 1 mbit/sec. */ - rate_mbps = rate ? max_t(u32, (rate * 8 + 500000) / 1000000, 1) : 0; - vport_num = rpriv->rep->vport; + if (rate) { + rate = (rate * BITS_PER_BYTE) + 500000; + rate_mbps = max_t(u32, do_div(rate, 1000000), 1); + } err = mlx5_esw_modify_vport_rate(esw, vport_num, rate_mbps); if (err) @@ -4055,7 +4109,7 @@ list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) { wait_for_completion(&hpe->res_ready); if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id) - hpe->hp->pair->peer_gone = true; + mlx5_core_hairpin_clear_dead_peer(hpe->hp->pair); mlx5e_hairpin_put(priv, hpe); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c @@ -93,7 +93,7 @@ if (txq_ix >= num_channels) txq_ix = priv->txq2sq[txq_ix]->ch_ix; - return priv->channel_tc2txq[txq_ix][up]; + return priv->channel_tc2realtxq[txq_ix][up]; } static inline int mlx5e_skb_l2_header_offset(struct sk_buff *skb) @@ -341,8 +341,8 @@ dseg = wqe->data; #if IS_ENABLED(CONFIG_GENEVE) - if (skb->encapsulation) - mlx5e_tx_tunnel_accel(skb, eseg); + if (skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) + mlx5e_tx_tunnel_accel(skb, eseg, ihs); #endif mlx5e_txwqe_build_eseg_csum(sq, skb, eseg); @@ -537,10 +537,9 @@ void mlx5e_free_txqsq_descs(struct mlx5e_txqsq *sq) { struct mlx5e_tx_wqe_info *wi; + u32 dma_fifo_cc, nbytes = 0; + u16 ci, sqcc, npkts = 0; struct sk_buff *skb; - u32 dma_fifo_cc; - u16 sqcc; - u16 ci; int i; sqcc = sq->cc; @@ -565,11 +564,15 @@ } dev_kfree_skb_any(skb); + npkts++; + nbytes += wi->num_bytes; sqcc += wi->num_wqebbs; } sq->dma_fifo_cc = dma_fifo_cc; sq->cc = sqcc; + + netdev_tx_completed_queue(sq->txq, npkts, nbytes); } #ifdef CONFIG_MLX5_CORE_IPOIB --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c @@ -78,6 +78,7 @@ u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc); sq->db.ico_wqe[pi].opcode = MLX5_OPCODE_NOP; + sq->db.ico_wqe[pi].num_wqebbs = 1; nopwqe = mlx5e_post_nop(wq, sq->sqn, &sq->pc); mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nopwqe->ctrl); } @@ -144,7 +145,11 @@ busy |= rq->post_wqes(rq); if (xsk_open) { - mlx5e_poll_ico_cq(&c->xskicosq.cq); + if (mlx5e_poll_ico_cq(&c->xskicosq.cq)) + /* Don't clear the flag if nothing was polled to prevent + * queueing more WQEs and overflowing XSKICOSQ. + */ + clear_bit(MLX5E_SQ_STATE_PENDING_XSK_TX, &c->xskicosq.state); busy |= mlx5e_poll_xdpsq_cq(&xsksq->cq); busy_xsk |= mlx5e_napi_xsk_post(xsksq, xskrq); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -190,6 +190,29 @@ return count_eqe; } +static void mlx5_eq_async_int_lock(struct mlx5_eq_async *eq, unsigned long *flags) + __acquires(&eq->lock) +{ + if (in_irq()) + spin_lock(&eq->lock); + else + spin_lock_irqsave(&eq->lock, *flags); +} + +static void mlx5_eq_async_int_unlock(struct mlx5_eq_async *eq, unsigned long *flags) + __releases(&eq->lock) +{ + if (in_irq()) + spin_unlock(&eq->lock); + else + spin_unlock_irqrestore(&eq->lock, *flags); +} + +enum async_eq_nb_action { + ASYNC_EQ_IRQ_HANDLER = 0, + ASYNC_EQ_RECOVER = 1, +}; + static int mlx5_eq_async_int(struct notifier_block *nb, unsigned long action, void *data) { @@ -199,11 +222,14 @@ struct mlx5_eq_table *eqt; struct mlx5_core_dev *dev; struct mlx5_eqe *eqe; + unsigned long flags; int num_eqes = 0; dev = eq->dev; eqt = dev->priv.eq_table; + mlx5_eq_async_int_lock(eq_async, &flags); + eqe = next_eqe_sw(eq); if (!eqe) goto out; @@ -224,8 +250,19 @@ out: eq_update_ci(eq, 1); + mlx5_eq_async_int_unlock(eq_async, &flags); - return 0; + return unlikely(action == ASYNC_EQ_RECOVER) ? num_eqes : 0; +} + +void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev) +{ + struct mlx5_eq_async *eq = &dev->priv.eq_table->cmd_eq; + int eqes; + + eqes = mlx5_eq_async_int(&eq->irq_nb, ASYNC_EQ_RECOVER, NULL); + if (eqes) + mlx5_core_warn(dev, "Recovered %d EQEs on cmd_eq\n", eqes); } static void init_eq_buf(struct mlx5_eq *eq) @@ -563,6 +600,40 @@ gather_user_async_events(dev, mask); } +static int +setup_async_eq(struct mlx5_core_dev *dev, struct mlx5_eq_async *eq, + struct mlx5_eq_param *param, const char *name) +{ + int err; + + eq->irq_nb.notifier_call = mlx5_eq_async_int; + spin_lock_init(&eq->lock); + + err = create_async_eq(dev, &eq->core, param); + if (err) { + mlx5_core_warn(dev, "failed to create %s EQ %d\n", name, err); + return err; + } + err = mlx5_eq_enable(dev, &eq->core, &eq->irq_nb); + if (err) { + mlx5_core_warn(dev, "failed to enable %s EQ %d\n", name, err); + destroy_async_eq(dev, &eq->core); + } + return err; +} + +static void cleanup_async_eq(struct mlx5_core_dev *dev, + struct mlx5_eq_async *eq, const char *name) +{ + int err; + + mlx5_eq_disable(dev, &eq->core, &eq->irq_nb); + err = destroy_async_eq(dev, &eq->core); + if (err) + mlx5_core_err(dev, "failed to destroy %s eq, err(%d)\n", + name, err); +} + static int create_async_eqs(struct mlx5_core_dev *dev) { struct mlx5_eq_table *table = dev->priv.eq_table; @@ -572,77 +643,48 @@ MLX5_NB_INIT(&table->cq_err_nb, cq_err_event_notifier, CQ_ERROR); mlx5_eq_notifier_register(dev, &table->cq_err_nb); - table->cmd_eq.irq_nb.notifier_call = mlx5_eq_async_int; param = (struct mlx5_eq_param) { .irq_index = 0, .nent = MLX5_NUM_CMD_EQE, + .mask[0] = 1ull << MLX5_EVENT_TYPE_CMD, }; - - param.mask[0] = 1ull << MLX5_EVENT_TYPE_CMD; - err = create_async_eq(dev, &table->cmd_eq.core, ¶m); - if (err) { - mlx5_core_warn(dev, "failed to create cmd EQ %d\n", err); - goto err0; - } - err = mlx5_eq_enable(dev, &table->cmd_eq.core, &table->cmd_eq.irq_nb); - if (err) { - mlx5_core_warn(dev, "failed to enable cmd EQ %d\n", err); + mlx5_cmd_allowed_opcode(dev, MLX5_CMD_OP_CREATE_EQ); + err = setup_async_eq(dev, &table->cmd_eq, ¶m, "cmd"); + if (err) goto err1; - } + mlx5_cmd_use_events(dev); + mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL); - table->async_eq.irq_nb.notifier_call = mlx5_eq_async_int; param = (struct mlx5_eq_param) { .irq_index = 0, .nent = MLX5_NUM_ASYNC_EQE, }; gather_async_events_mask(dev, param.mask); - err = create_async_eq(dev, &table->async_eq.core, ¶m); - if (err) { - mlx5_core_warn(dev, "failed to create async EQ %d\n", err); + err = setup_async_eq(dev, &table->async_eq, ¶m, "async"); + if (err) goto err2; - } - err = mlx5_eq_enable(dev, &table->async_eq.core, - &table->async_eq.irq_nb); - if (err) { - mlx5_core_warn(dev, "failed to enable async EQ %d\n", err); - goto err3; - } - table->pages_eq.irq_nb.notifier_call = mlx5_eq_async_int; param = (struct mlx5_eq_param) { .irq_index = 0, .nent = /* TODO: sriov max_vf + */ 1, + .mask[0] = 1ull << MLX5_EVENT_TYPE_PAGE_REQUEST, }; - param.mask[0] = 1ull << MLX5_EVENT_TYPE_PAGE_REQUEST; - err = create_async_eq(dev, &table->pages_eq.core, ¶m); - if (err) { - mlx5_core_warn(dev, "failed to create pages EQ %d\n", err); - goto err4; - } - err = mlx5_eq_enable(dev, &table->pages_eq.core, - &table->pages_eq.irq_nb); - if (err) { - mlx5_core_warn(dev, "failed to enable pages EQ %d\n", err); - goto err5; - } + err = setup_async_eq(dev, &table->pages_eq, ¶m, "pages"); + if (err) + goto err3; - return err; + return 0; -err5: - destroy_async_eq(dev, &table->pages_eq.core); -err4: - mlx5_eq_disable(dev, &table->async_eq.core, &table->async_eq.irq_nb); err3: - destroy_async_eq(dev, &table->async_eq.core); + cleanup_async_eq(dev, &table->async_eq, "async"); err2: mlx5_cmd_use_polling(dev); - mlx5_eq_disable(dev, &table->cmd_eq.core, &table->cmd_eq.irq_nb); + cleanup_async_eq(dev, &table->cmd_eq, "cmd"); err1: - destroy_async_eq(dev, &table->cmd_eq.core); -err0: + mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL); mlx5_eq_notifier_unregister(dev, &table->cq_err_nb); return err; } @@ -650,28 +692,13 @@ static void destroy_async_eqs(struct mlx5_core_dev *dev) { struct mlx5_eq_table *table = dev->priv.eq_table; - int err; - - mlx5_eq_disable(dev, &table->pages_eq.core, &table->pages_eq.irq_nb); - err = destroy_async_eq(dev, &table->pages_eq.core); - if (err) - mlx5_core_err(dev, "failed to destroy pages eq, err(%d)\n", - err); - - mlx5_eq_disable(dev, &table->async_eq.core, &table->async_eq.irq_nb); - err = destroy_async_eq(dev, &table->async_eq.core); - if (err) - mlx5_core_err(dev, "failed to destroy async eq, err(%d)\n", - err); + cleanup_async_eq(dev, &table->pages_eq, "pages"); + cleanup_async_eq(dev, &table->async_eq, "async"); + mlx5_cmd_allowed_opcode(dev, MLX5_CMD_OP_DESTROY_EQ); mlx5_cmd_use_polling(dev); - - mlx5_eq_disable(dev, &table->cmd_eq.core, &table->cmd_eq.irq_nb); - err = destroy_async_eq(dev, &table->cmd_eq.core); - if (err) - mlx5_core_err(dev, "failed to destroy command eq, err(%d)\n", - err); - + cleanup_async_eq(dev, &table->cmd_eq, "cmd"); + mlx5_cmd_allowed_opcode(dev, CMD_ALLOWED_OPCODE_ALL); mlx5_eq_notifier_unregister(dev, &table->cq_err_nb); } @@ -901,13 +928,24 @@ mutex_unlock(&table->lock); } +#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING +#define MLX5_MAX_ASYNC_EQS 4 +#else +#define MLX5_MAX_ASYNC_EQS 3 +#endif + int mlx5_eq_table_create(struct mlx5_core_dev *dev) { struct mlx5_eq_table *eq_table = dev->priv.eq_table; + int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ? + MLX5_CAP_GEN(dev, max_num_eqs) : + 1 << MLX5_CAP_GEN(dev, log_max_eq); int err; eq_table->num_comp_eqs = - mlx5_irq_get_num_comp(eq_table->irq_table); + min_t(int, + mlx5_irq_get_num_comp(eq_table->irq_table), + num_eqs - MLX5_MAX_ASYNC_EQS); err = create_async_eqs(dev); if (err) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1592,6 +1592,10 @@ struct mlx5_vport *vport; vport = mlx5_eswitch_get_vport(esw, vport_num); + + if (!vport->qos.enabled) + return -EOPNOTSUPP; + MLX5_SET(scheduling_context, ctx, max_average_bw, rate_mbps); return mlx5_modify_scheduling_element_cmd(esw->dev, @@ -1919,7 +1923,7 @@ mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB); mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_ETH); } - + esw_destroy_tsar(esw); return err; } @@ -2094,6 +2098,8 @@ u16 vport, int link_state) { struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); + int opmod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT; + int other_vport = 1; int err = 0; if (!ESW_ALLOWED(esw)) @@ -2101,15 +2107,17 @@ if (IS_ERR(evport)) return PTR_ERR(evport); + if (vport == MLX5_VPORT_UPLINK) { + opmod = MLX5_VPORT_STATE_OP_MOD_UPLINK; + other_vport = 0; + vport = 0; + } mutex_lock(&esw->state_lock); - err = mlx5_modify_vport_admin_state(esw->dev, - MLX5_VPORT_STATE_OP_MOD_ESW_VPORT, - vport, 1, link_state); + err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state); if (err) { - mlx5_core_warn(esw->dev, - "Failed to set vport %d link state, err = %d", - vport, err); + mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d", + vport, opmod, err); goto unlock; } @@ -2151,8 +2159,6 @@ struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); int err = 0; - if (!ESW_ALLOWED(esw)) - return -EPERM; if (IS_ERR(evport)) return PTR_ERR(evport); if (vlan > 4095 || qos > 7) @@ -2180,6 +2186,9 @@ u8 set_flags = 0; int err; + if (!ESW_ALLOWED(esw)) + return vlan ? -EPERM : 0; + if (vlan || qos) set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT; @@ -2319,25 +2328,17 @@ int mlx5_eswitch_get_vepa(struct mlx5_eswitch *esw, u8 *setting) { - int err = 0; - if (!esw) return -EOPNOTSUPP; if (!ESW_ALLOWED(esw)) return -EPERM; - mutex_lock(&esw->state_lock); - if (esw->mode != MLX5_ESWITCH_LEGACY) { - err = -EOPNOTSUPP; - goto out; - } + if (esw->mode != MLX5_ESWITCH_LEGACY) + return -EOPNOTSUPP; *setting = esw->fdb_table.legacy.vepa_uplink_rule ? 1 : 0; - -out: - mutex_unlock(&esw->state_lock); - return err; + return 0; } int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, @@ -2372,12 +2373,15 @@ max_guarantee = evport->info.min_rate; } - return max_t(u32, max_guarantee / fw_max_bw_share, 1); + if (max_guarantee) + return max_t(u32, max_guarantee / fw_max_bw_share, 1); + return 0; } -static int normalize_vports_min_rate(struct mlx5_eswitch *esw, u32 divider) +static int normalize_vports_min_rate(struct mlx5_eswitch *esw) { u32 fw_max_bw_share = MLX5_CAP_QOS(esw->dev, max_tsar_bw_share); + u32 divider = calculate_vports_min_rate_divider(esw); struct mlx5_vport *evport; u32 vport_max_rate; u32 vport_min_rate; @@ -2390,9 +2394,9 @@ continue; vport_min_rate = evport->info.min_rate; vport_max_rate = evport->info.max_rate; - bw_share = MLX5_MIN_BW_SHARE; + bw_share = 0; - if (vport_min_rate) + if (divider) bw_share = MLX5_RATE_TO_BW_SHARE(vport_min_rate, divider, fw_max_bw_share); @@ -2417,7 +2421,6 @@ struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport); u32 fw_max_bw_share; u32 previous_min_rate; - u32 divider; bool min_rate_supported; bool max_rate_supported; int err = 0; @@ -2442,8 +2445,7 @@ previous_min_rate = evport->info.min_rate; evport->info.min_rate = min_rate; - divider = calculate_vports_min_rate_divider(esw); - err = normalize_vports_min_rate(esw, divider); + err = normalize_vports_min_rate(esw); if (err) { evport->info.min_rate = previous_min_rate; goto unlock; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -606,6 +606,8 @@ static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw) {} static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; } static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; } +static inline +int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; } static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev) { return ERR_PTR(-EOPNOTSUPP); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -858,7 +858,7 @@ */ #define ESW_SIZE (16 * 1024 * 1024) const unsigned int ESW_POOLS[4] = { 4 * 1024 * 1024, 1 * 1024 * 1024, - 64 * 1024, 4 * 1024 }; + 64 * 1024, 128 }; static int get_sz_from_pool(struct mlx5_eswitch *esw) @@ -1143,35 +1143,37 @@ } esw->fdb_table.offloads.send_to_vport_grp = g; - /* create peer esw miss group */ - memset(flow_group_in, 0, inlen); - - esw_set_flow_group_source_port(esw, flow_group_in); + if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) { + /* create peer esw miss group */ + memset(flow_group_in, 0, inlen); + + esw_set_flow_group_source_port(esw, flow_group_in); + + if (!mlx5_eswitch_vport_match_metadata_enabled(esw)) { + match_criteria = MLX5_ADDR_OF(create_flow_group_in, + flow_group_in, + match_criteria); - if (!mlx5_eswitch_vport_match_metadata_enabled(esw)) { - match_criteria = MLX5_ADDR_OF(create_flow_group_in, - flow_group_in, - match_criteria); - - MLX5_SET_TO_ONES(fte_match_param, match_criteria, - misc_parameters.source_eswitch_owner_vhca_id); + MLX5_SET_TO_ONES(fte_match_param, match_criteria, + misc_parameters.source_eswitch_owner_vhca_id); - MLX5_SET(create_flow_group_in, flow_group_in, - source_eswitch_owner_vhca_id_valid, 1); - } - - MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ix); - MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, - ix + esw->total_vports - 1); - ix += esw->total_vports; + MLX5_SET(create_flow_group_in, flow_group_in, + source_eswitch_owner_vhca_id_valid, 1); + } - g = mlx5_create_flow_group(fdb, flow_group_in); - if (IS_ERR(g)) { - err = PTR_ERR(g); - esw_warn(dev, "Failed to create peer miss flow group err(%d)\n", err); - goto peer_miss_err; + MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, ix); + MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, + ix + esw->total_vports - 1); + ix += esw->total_vports; + + g = mlx5_create_flow_group(fdb, flow_group_in); + if (IS_ERR(g)) { + err = PTR_ERR(g); + esw_warn(dev, "Failed to create peer miss flow group err(%d)\n", err); + goto peer_miss_err; + } + esw->fdb_table.offloads.peer_miss_grp = g; } - esw->fdb_table.offloads.peer_miss_grp = g; /* create miss group */ memset(flow_group_in, 0, inlen); @@ -1206,7 +1208,8 @@ miss_rule_err: mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp); miss_err: - mlx5_destroy_flow_group(esw->fdb_table.offloads.peer_miss_grp); + if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) + mlx5_destroy_flow_group(esw->fdb_table.offloads.peer_miss_grp); peer_miss_err: mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp); send_vport_err: @@ -1229,7 +1232,8 @@ mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule_multi); mlx5_del_flow_rules(esw->fdb_table.offloads.miss_rule_uni); mlx5_destroy_flow_group(esw->fdb_table.offloads.send_to_vport_grp); - mlx5_destroy_flow_group(esw->fdb_table.offloads.peer_miss_grp); + if (MLX5_CAP_ESW(esw->dev, merged_eswitch)) + mlx5_destroy_flow_group(esw->fdb_table.offloads.peer_miss_grp); mlx5_destroy_flow_group(esw->fdb_table.offloads.miss_grp); mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb); @@ -1973,10 +1977,6 @@ if (!MLX5_CAP_ESW_FLOWTABLE(esw->dev, flow_source)) return false; - if (mlx5_core_is_ecpf_esw_manager(esw->dev) || - mlx5_ecpf_vport_exists(esw->dev)) - return false; - return true; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c @@ -267,6 +267,8 @@ for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) { struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl; + attr->dests[curr_dest].termtbl = NULL; + /* search for the destination associated with the * current term table */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/events.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/events.c @@ -346,8 +346,10 @@ events->dev = dev; dev->priv.events = events; events->wq = create_singlethread_workqueue("mlx5_events"); - if (!events->wq) + if (!events->wq) { + kfree(events); return -ENOMEM; + } INIT_WORK(&events->pcie_core_work, mlx5_pcie_event); return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c @@ -850,6 +850,7 @@ mutex_lock(&fpga_xfrm->lock); if (!--fpga_xfrm->num_rules) { mlx5_fpga_ipsec_release_sa_ctx(fpga_xfrm->sa_ctx); + kfree(fpga_xfrm->sa_ctx); fpga_xfrm->sa_ctx = NULL; } mutex_unlock(&fpga_xfrm->lock); @@ -1478,7 +1479,7 @@ if (!memcmp(&xfrm->attrs, attrs, sizeof(xfrm->attrs))) return 0; - if (!mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) { + if (mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) { mlx5_core_warn(mdev, "Tried to create an esp with unsupported attrs\n"); return -EOPNOTSUPP; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -496,6 +496,13 @@ goto out; } + if (rule->dest_attr.type == MLX5_FLOW_DESTINATION_TYPE_PORT && + --fte->dests_size) { + fte->modify_mask |= BIT(MLX5_SET_FTE_MODIFY_ENABLE_MASK_ACTION); + fte->action.action &= ~MLX5_FLOW_CONTEXT_ACTION_ALLOW; + goto out; + } + if ((fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && --fte->dests_size) { fte->modify_mask |= @@ -629,7 +636,7 @@ fte->action = *flow_act; fte->flow_context = spec->flow_context; - tree_init_node(&fte->node, NULL, del_sw_fte); + tree_init_node(&fte->node, del_hw_fte, del_sw_fte); return fte; } @@ -809,18 +816,15 @@ { struct mlx5_flow_root_namespace *root = find_root(&prio->node); struct mlx5_flow_table *iter; - int i = 0; int err; fs_for_each_ft(iter, prio) { - i++; err = root->cmds->modify_flow_table(root, iter, ft); if (err) { - mlx5_core_warn(dev, "Failed to modify flow table %d\n", - iter->id); + mlx5_core_err(dev, + "Failed to modify flow table id %d, type %d, err %d\n", + iter->id, iter->type, err); /* The driver is out of sync with the FW */ - if (i > 1) - WARN_ON(true); return err; } } @@ -964,17 +968,19 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, struct fs_prio *prio) { - struct mlx5_flow_table *next_ft; + struct mlx5_flow_table *next_ft, *first_ft; int err = 0; /* Connect_prev_fts and update_root_ft_create are mutually exclusive */ - if (list_empty(&prio->node.children)) { + first_ft = list_first_entry_or_null(&prio->node.children, + struct mlx5_flow_table, node.list); + if (!first_ft || first_ft->level > ft->level) { err = connect_prev_fts(dev, ft, prio); if (err) return err; - next_ft = find_next_chained_ft(prio); + next_ft = first_ft ? first_ft : find_next_chained_ft(prio); err = connect_fwd_rules(dev, ft, next_ft); if (err) return err; @@ -1064,6 +1070,7 @@ destroy_ft: root->cmds->destroy_flow_table(root, ft); free_ft: + rhltable_destroy(&ft->fgs_hash); kfree(ft); unlock_root: mutex_unlock(&root->chain_lock); @@ -1443,9 +1450,22 @@ return NULL; } -static bool check_conflicting_actions(u32 action1, u32 action2) +static bool check_conflicting_actions_vlan(const struct mlx5_fs_vlan *vlan0, + const struct mlx5_fs_vlan *vlan1) { - u32 xored_actions = action1 ^ action2; + return vlan0->ethtype != vlan1->ethtype || + vlan0->vid != vlan1->vid || + vlan0->prio != vlan1->prio; +} + +static bool check_conflicting_actions(const struct mlx5_flow_act *act1, + const struct mlx5_flow_act *act2) +{ + u32 action1 = act1->action; + u32 action2 = act2->action; + u32 xored_actions; + + xored_actions = action1 ^ action2; /* if one rule only wants to count, it's ok */ if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT || @@ -1462,6 +1482,22 @@ MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2)) return true; + if (action1 & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT && + act1->pkt_reformat != act2->pkt_reformat) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR && + act1->modify_hdr != act2->modify_hdr) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH && + check_conflicting_actions_vlan(&act1->vlan[0], &act2->vlan[0])) + return true; + + if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 && + check_conflicting_actions_vlan(&act1->vlan[1], &act2->vlan[1])) + return true; + return false; } @@ -1469,7 +1505,7 @@ const struct mlx5_flow_context *flow_context, const struct mlx5_flow_act *flow_act) { - if (check_conflicting_actions(flow_act->action, fte->action.action)) { + if (check_conflicting_actions(flow_act, &fte->action)) { mlx5_core_warn(get_dev(&fte->node), "Found two FTEs with conflicting actions\n"); return -EEXIST; @@ -1513,8 +1549,9 @@ } trace_mlx5_fs_set_fte(fte, false); + /* Link newly added rules into the tree. */ for (i = 0; i < handle->num_rules; i++) { - if (refcount_read(&handle->rule[i]->node.refcount) == 1) { + if (!handle->rule[i]->node.parent) { tree_add_node(&handle->rule[i]->node, &fte->node); trace_mlx5_fs_add_rule(handle->rule[i]); } @@ -1555,16 +1592,16 @@ struct match_list first; }; -static void free_match_list(struct match_list_head *head) +static void free_match_list(struct match_list_head *head, bool ft_locked) { if (!list_empty(&head->list)) { struct match_list *iter, *match_tmp; list_del(&head->first.list); - tree_put_node(&head->first.g->node, false); + tree_put_node(&head->first.g->node, ft_locked); list_for_each_entry_safe(iter, match_tmp, &head->list, list) { - tree_put_node(&iter->g->node, false); + tree_put_node(&iter->g->node, ft_locked); list_del(&iter->list); kfree(iter); } @@ -1573,7 +1610,8 @@ static int build_match_list(struct match_list_head *match_head, struct mlx5_flow_table *ft, - const struct mlx5_flow_spec *spec) + const struct mlx5_flow_spec *spec, + bool ft_locked) { struct rhlist_head *tmp, *list; struct mlx5_flow_group *g; @@ -1598,9 +1636,9 @@ curr_match = kmalloc(sizeof(*curr_match), GFP_ATOMIC); if (!curr_match) { - free_match_list(match_head); - err = -ENOMEM; - goto out; + rcu_read_unlock(); + free_match_list(match_head, ft_locked); + return -ENOMEM; } if (!tree_get_node(&g->node)) { kfree(curr_match); @@ -1609,7 +1647,6 @@ curr_match->g = g; list_add_tail(&curr_match->list, &match_head->list); } -out: rcu_read_unlock(); return err; } @@ -1641,13 +1678,22 @@ fte_tmp = NULL; goto out; } + + nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); + if (!fte_tmp->node.active) { + up_write_ref_node(&fte_tmp->node, false); + + if (take_write) + up_write_ref_node(&g->node, false); + else + up_read_ref_node(&g->node); + tree_put_node(&fte_tmp->node, false); - fte_tmp = NULL; - goto out; + + return NULL; } - nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD); out: if (take_write) up_write_ref_node(&g->node, false); @@ -1691,6 +1737,7 @@ if (!fte_tmp) continue; rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte_tmp); + /* No error check needed here, because insert_fte() is not called */ up_write_ref_node(&fte_tmp->node, false); tree_put_node(&fte_tmp->node, false); kmem_cache_free(steering->ftes_cache, fte); @@ -1739,7 +1786,8 @@ up_write_ref_node(&g->node, false); rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte); up_write_ref_node(&fte->node, false); - tree_put_node(&fte->node, false); + if (IS_ERR(rule)) + tree_put_node(&fte->node, false); return rule; } rule = ERR_PTR(-ENOENT); @@ -1778,7 +1826,7 @@ version = atomic_read(&ft->node.version); /* Collect all fgs which has a matching match_criteria */ - err = build_match_list(&match_head, ft, spec); + err = build_match_list(&match_head, ft, spec, take_write); if (err) { if (take_write) up_write_ref_node(&ft->node, false); @@ -1792,7 +1840,7 @@ rule = try_add_to_existing_fg(ft, &match_head.list, spec, flow_act, dest, dest_num, version); - free_match_list(&match_head); + free_match_list(&match_head, take_write); if (!IS_ERR(rule) || (PTR_ERR(rule) != -ENOENT && PTR_ERR(rule) != -EAGAIN)) { if (take_write) @@ -1839,7 +1887,8 @@ up_write_ref_node(&g->node, false); rule = add_rule_fg(g, spec, flow_act, dest, dest_num, fte); up_write_ref_node(&fte->node, false); - tree_put_node(&fte->node, false); + if (IS_ERR(rule)) + tree_put_node(&fte->node, false); tree_put_node(&g->node, false); return rule; @@ -1927,13 +1976,18 @@ down_write_ref_node(&fte->node, false); for (i = handle->num_rules - 1; i >= 0; i--) tree_remove_node(&handle->rule[i]->node, true); - if (fte->modify_mask && fte->dests_size) { - modify_fte(fte); - up_write_ref_node(&fte->node, false); - } else { + if (list_empty(&fte->node.children)) { del_hw_fte(&fte->node); - up_write(&fte->node.lock); + /* Avoid double call to del_hw_fte */ + fte->node.del_hw_func = NULL; + up_write_ref_node(&fte->node, false); tree_put_node(&fte->node, false); + } else if (fte->dests_size) { + if (fte->modify_mask) + modify_fte(fte); + up_write_ref_node(&fte->node, false); + } else { + up_write_ref_node(&fte->node, false); } kfree(handle); } @@ -2014,7 +2068,7 @@ node.list) == ft)) return 0; - next_ft = find_next_chained_ft(prio); + next_ft = find_next_ft(ft); err = connect_fwd_rules(dev, next_ft, ft); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/fw.c @@ -239,7 +239,7 @@ return err; } - if (MLX5_CAP_GEN(dev, tls)) { + if (MLX5_CAP_GEN(dev, tls_tx)) { err = mlx5_core_get_caps(dev, MLX5_CAP_TLS); if (err) return err; @@ -337,6 +337,10 @@ do { if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) break; + if (pci_channel_offline(dev->pdev)) { + mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n"); + return -EACCES; + } cond_resched(); } while (!time_after(jiffies, end)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -193,15 +193,23 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force) { + bool err_detected = false; + + /* Mark the device as fatal in order to abort FW commands */ + if ((check_fatal_sensors(dev) || force) && + dev->state == MLX5_DEVICE_STATE_UP) { + dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; + err_detected = true; + } mutex_lock(&dev->intf_state_mutex); - if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) - goto unlock; + if (!err_detected && dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) + goto unlock;/* a previous error is still being handled */ if (dev->state == MLX5_DEVICE_STATE_UNINITIALIZED) { dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; goto unlock; } - if (check_fatal_sensors(dev) || force) { + if (check_fatal_sensors(dev) || force) { /* protected state setting */ dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; mlx5_cmd_flush(dev); } @@ -242,8 +250,12 @@ do { if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED) break; + if (pci_channel_offline(dev->pdev)) { + mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n"); + goto unlock; + } - cond_resched(); + msleep(20); } while (!time_after(jiffies, end)); if (mlx5_get_nic_state(dev) != MLX5_NIC_IFC_DISABLED) { @@ -314,6 +326,10 @@ "health recovery flow aborted, PCI reads still not working\n"); return -EIO; } + if (pci_channel_offline(dev->pdev)) { + mlx5_core_err(dev, "PCI channel offline, stop waiting for PCI\n"); + return -EACCES; + } msleep(100); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c @@ -39,7 +39,7 @@ struct mlx5e_priv *priv = mlx5i_epriv(dev); mlx5e_ethtool_get_drvinfo(priv, drvinfo); - strlcpy(drvinfo->driver, DRIVER_NAME "[ib_ipoib]", + strlcpy(drvinfo->driver, KBUILD_MODNAME "[ib_ipoib]", sizeof(drvinfo->driver)); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c @@ -319,17 +319,6 @@ } mlx5e_set_ttc_basic_params(priv, &ttc_params); - mlx5e_set_inner_ttc_ft_params(&ttc_params); - for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) - ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn; - - err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc); - if (err) { - netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n", - err); - goto err_destroy_arfs_tables; - } - mlx5e_set_ttc_ft_params(&ttc_params); for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn; @@ -338,13 +327,11 @@ if (err) { netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n", err); - goto err_destroy_inner_ttc_table; + goto err_destroy_arfs_tables; } return 0; -err_destroy_inner_ttc_table: - mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc); err_destroy_arfs_tables: mlx5e_arfs_destroy_tables(priv); @@ -354,7 +341,6 @@ static void mlx5i_destroy_flow_steering(struct mlx5e_priv *priv) { mlx5e_destroy_ttc_table(priv, &priv->fs.ttc); - mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc); mlx5e_arfs_destroy_tables(priv); } @@ -379,7 +365,7 @@ if (err) goto err_destroy_indirect_rqts; - err = mlx5e_create_indirect_tirs(priv, true); + err = mlx5e_create_indirect_tirs(priv, false); if (err) goto err_destroy_direct_rqts; @@ -396,7 +382,7 @@ err_destroy_direct_tirs: mlx5e_destroy_direct_tirs(priv, priv->direct_tir); err_destroy_indirect_tirs: - mlx5e_destroy_indirect_tirs(priv, true); + mlx5e_destroy_indirect_tirs(priv); err_destroy_direct_rqts: mlx5e_destroy_direct_rqts(priv, priv->direct_tir); err_destroy_indirect_rqts: @@ -412,7 +398,7 @@ { mlx5i_destroy_flow_steering(priv); mlx5e_destroy_direct_tirs(priv, priv->direct_tir); - mlx5e_destroy_indirect_tirs(priv, true); + mlx5e_destroy_indirect_tirs(priv); mlx5e_destroy_direct_rqts(priv, priv->direct_tir); mlx5e_destroy_rqt(priv, &priv->indir_rqt); mlx5e_close_drop_rq(&priv->drop_rq); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c @@ -265,10 +265,8 @@ fen_info = container_of(info, struct fib_entry_notifier_info, info); fi = fen_info->fi; - if (fi->nh) { - NL_SET_ERR_MSG_MOD(info->extack, "IPv4 route with nexthop objects is not supported"); - return notifier_from_errno(-EINVAL); - } + if (fi->nh) + return NOTIFY_DONE; fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev; if (fib_dev != ldev->pf[0].netdev && fib_dev != ldev->pf[1].netdev) { @@ -307,6 +305,11 @@ struct lag_mp *mp = &ldev->lag_mp; int err; + /* always clear mfi, as it might become stale when a route delete event + * has been missed + */ + mp->mfi = NULL; + if (mp->fib_nb.notifier_call) return 0; @@ -328,4 +331,5 @@ unregister_fib_notifier(&mp->fib_nb); mp->fib_nb.notifier_call = NULL; + mp->mfi = NULL; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -388,16 +388,37 @@ return 0; } +enum { + MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_IN = BIT(0), + MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_OUT = BIT(1), +}; + static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, enum ptp_pin_function func, unsigned int chan) { - return (func == PTP_PF_PHYSYNC) ? -EOPNOTSUPP : 0; + struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, + ptp_info); + + switch (func) { + case PTP_PF_NONE: + return 0; + case PTP_PF_EXTTS: + return !(clock->pps_info.pin_caps[pin] & + MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_IN); + case PTP_PF_PEROUT: + return !(clock->pps_info.pin_caps[pin] & + MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_OUT); + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; } static const struct ptp_clock_info mlx5_ptp_clock_info = { .owner = THIS_MODULE, - .name = "mlx5_p2p", - .max_adj = 100000000, + .name = "mlx5_ptp", + .max_adj = 50000000, .n_alarm = 0, .n_ext_ts = 0, .n_per_out = 0, @@ -477,8 +498,9 @@ switch (clock->ptp_info.pin_config[pin].func) { case PTP_PF_EXTTS: ptp_event.index = pin; - ptp_event.timestamp = timecounter_cyc2time(&clock->tc, - be64_to_cpu(eqe->data.pps.time_stamp)); + ptp_event.timestamp = + mlx5_timecounter_cyc2time(clock, + be64_to_cpu(eqe->data.pps.time_stamp)); if (clock->pps_info.enabled) { ptp_event.type = PTP_CLOCK_PPSUSR; ptp_event.pps_times.ts_real = --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c @@ -3,6 +3,7 @@ #include #include "lib/devcom.h" +#include "mlx5_core.h" static LIST_HEAD(devcom_list); @@ -14,7 +15,7 @@ struct mlx5_devcom_component { struct { void *data; - } device[MLX5_MAX_PORTS]; + } device[MLX5_DEVCOM_PORTS_SUPPORTED]; mlx5_devcom_event_handler_t handler; struct rw_semaphore sem; @@ -25,7 +26,7 @@ struct list_head list; struct mlx5_devcom_component components[MLX5_DEVCOM_NUM_COMPONENTS]; - struct mlx5_core_dev *devs[MLX5_MAX_PORTS]; + struct mlx5_core_dev *devs[MLX5_DEVCOM_PORTS_SUPPORTED]; }; struct mlx5_devcom { @@ -74,13 +75,16 @@ if (!mlx5_core_is_pf(dev)) return NULL; + if (MLX5_CAP_GEN(dev, num_lag_ports) != MLX5_DEVCOM_PORTS_SUPPORTED) + return NULL; + mlx5_dev_list_lock(); sguid0 = mlx5_query_nic_system_image_guid(dev); list_for_each_entry(iter, &devcom_list, list) { struct mlx5_core_dev *tmp_dev = NULL; idx = -1; - for (i = 0; i < MLX5_MAX_PORTS; i++) { + for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) { if (iter->devs[i]) tmp_dev = iter->devs[i]; else @@ -100,8 +104,10 @@ if (!priv) { priv = mlx5_devcom_list_alloc(); - if (!priv) - return ERR_PTR(-ENOMEM); + if (!priv) { + devcom = ERR_PTR(-ENOMEM); + goto out; + } idx = 0; new_priv = true; @@ -110,13 +116,16 @@ priv->devs[idx] = dev; devcom = mlx5_devcom_alloc(priv, idx); if (!devcom) { - kfree(priv); - return ERR_PTR(-ENOMEM); + if (new_priv) + kfree(priv); + devcom = ERR_PTR(-ENOMEM); + goto out; } if (new_priv) list_add(&priv->list, &devcom_list); - +out: + mlx5_dev_list_unlock(); return devcom; } @@ -129,20 +138,23 @@ if (IS_ERR_OR_NULL(devcom)) return; + mlx5_dev_list_lock(); priv = devcom->priv; priv->devs[devcom->idx] = NULL; kfree(devcom); - for (i = 0; i < MLX5_MAX_PORTS; i++) + for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) if (priv->devs[i]) break; - if (i != MLX5_MAX_PORTS) - return; + if (i != MLX5_DEVCOM_PORTS_SUPPORTED) + goto out; list_del(&priv->list); kfree(priv); +out: + mlx5_dev_list_unlock(); } void mlx5_devcom_register_component(struct mlx5_devcom *devcom, @@ -191,7 +203,7 @@ comp = &devcom->priv->components[id]; down_write(&comp->sem); - for (i = 0; i < MLX5_MAX_PORTS; i++) + for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) if (i != devcom->idx && comp->device[i].data) { err = comp->handler(event, comp->device[i].data, event_data); @@ -239,7 +251,7 @@ return NULL; } - for (i = 0; i < MLX5_MAX_PORTS; i++) + for (i = 0; i < MLX5_DEVCOM_PORTS_SUPPORTED; i++) if (i != devcom->idx) break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h @@ -6,6 +6,8 @@ #include +#define MLX5_DEVCOM_PORTS_SUPPORTED 2 + enum mlx5_devcom_components { MLX5_DEVCOM_ESW_OFFLOADS, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h @@ -38,6 +38,7 @@ struct mlx5_eq_async { struct mlx5_eq core; struct notifier_block irq_nb; + spinlock_t lock; /* To avoid irq EQ handle races with resiliency flows */ }; struct mlx5_eq_comp { @@ -82,6 +83,7 @@ struct cpumask *mlx5_eq_comp_cpumask(struct mlx5_core_dev *dev, int ix); u32 mlx5_eq_poll_irq_disabled(struct mlx5_eq_comp *eq); +void mlx5_cmd_eq_recover(struct mlx5_core_dev *dev); void mlx5_eq_synchronize_async_irq(struct mlx5_core_dev *dev); void mlx5_eq_synchronize_cmd_irq(struct mlx5_core_dev *dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c @@ -105,6 +105,7 @@ geneve->opt_type = opt->type; geneve->obj_id = res; geneve->refcount++; + res = 0; } unlock: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c @@ -24,6 +24,11 @@ pci_write_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val)) #define VSC_MAX_RETRIES 2048 +/* Reading VSC registers can take relatively long time. + * Yield the cpu every 128 registers read. + */ +#define VSC_GW_READ_BLOCK_COUNT 128 + enum { VSC_CTRL_OFFSET = 0x4, VSC_COUNTER_OFFSET = 0x8, @@ -74,6 +79,10 @@ ret = -EBUSY; goto pci_unlock; } + if (pci_channel_offline(dev->pdev)) { + ret = -EACCES; + goto pci_unlock; + } /* Check if semaphore is already locked */ ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val); @@ -269,6 +278,7 @@ { unsigned int next_read_addr = 0; unsigned int read_addr = 0; + unsigned int count = 0; while (read_addr < length) { if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr, @@ -276,6 +286,10 @@ return read_addr; read_addr = next_read_addr; + if (++count == VSC_GW_READ_BLOCK_COUNT) { + cond_resched(); + count = 0; + } } return length; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -50,6 +50,7 @@ #ifdef CONFIG_RFS_ACCEL #include #endif +#include #include #include "mlx5_core.h" #include "lib/eq.h" @@ -74,7 +75,6 @@ MODULE_AUTHOR("Eli Cohen "); MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION(DRIVER_VERSION); unsigned int mlx5_core_debug_mask; module_param_named(debug_mask, mlx5_core_debug_mask, uint, 0644); @@ -221,13 +221,16 @@ strncat(string, ",", remaining_size); remaining_size = max_t(int, 0, driver_ver_sz - strlen(string)); - strncat(string, DRIVER_NAME, remaining_size); + strncat(string, KBUILD_MODNAME, remaining_size); remaining_size = max_t(int, 0, driver_ver_sz - strlen(string)); strncat(string, ",", remaining_size); remaining_size = max_t(int, 0, driver_ver_sz - strlen(string)); - strncat(string, DRIVER_VERSION, remaining_size); + + snprintf(string + strlen(string), remaining_size, "%u.%u.%u", + (u8)((LINUX_VERSION_CODE >> 16) & 0xff), (u8)((LINUX_VERSION_CODE >> 8) & 0xff), + (u16)(LINUX_VERSION_CODE & 0xffff)); /*Send the command*/ MLX5_SET(set_driver_version_in, in, opcode, @@ -303,7 +306,7 @@ return -ENODEV; } - err = pci_request_regions(pdev, DRIVER_NAME); + err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) dev_err(&pdev->dev, "Couldn't get PCI resources, aborting\n"); @@ -794,6 +797,11 @@ static void mlx5_pci_close(struct mlx5_core_dev *dev) { + /* health work might still be active, and it needs pci bar in + * order to know the NIC state. Therefore, drain the health WQ + * before removing the pci bars + */ + mlx5_drain_health_wq(dev); iounmap(dev->iseg); pci_clear_master(dev->pdev); release_bar(dev->pdev); @@ -878,7 +886,7 @@ dev->dm = mlx5_dm_create(dev); if (IS_ERR(dev->dm)) - mlx5_core_warn(dev, "Failed to init device memory%d\n", err); + mlx5_core_warn(dev, "Failed to init device memory %ld\n", PTR_ERR(dev->dm)); dev->tracer = mlx5_fw_tracer_create(dev); dev->hv_vhca = mlx5_hv_vhca_create(dev); @@ -966,6 +974,8 @@ goto err_cmd_cleanup; } + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_UP); + err = mlx5_core_enable_hca(dev, 0); if (err) { mlx5_core_err(dev, "enable hca failed\n"); @@ -1027,6 +1037,7 @@ err_disable_hca: mlx5_core_disable_hca(dev, 0); err_cmd_cleanup: + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); mlx5_cmd_cleanup(dev); return err; @@ -1044,6 +1055,7 @@ } mlx5_reclaim_startup_pages(dev); mlx5_core_disable_hca(dev, 0); + mlx5_cmd_set_state(dev, MLX5_CMDIF_STATE_DOWN); mlx5_cmd_cleanup(dev); return 0; @@ -1168,7 +1180,7 @@ mlx5_put_uars_page(dev, dev->priv.uar); } -static int mlx5_load_one(struct mlx5_core_dev *dev, bool boot) +int mlx5_load_one(struct mlx5_core_dev *dev, bool boot) { int err = 0; @@ -1183,7 +1195,7 @@ err = mlx5_function_setup(dev, boot); if (err) - goto out; + goto err_function; if (boot) { err = mlx5_init_once(dev); @@ -1197,6 +1209,12 @@ if (err) goto err_load; + if (boot) { + err = mlx5_devlink_register(priv_to_devlink(dev), dev->device); + if (err) + goto err_devlink_reg; + } + if (mlx5_device_registered(dev)) { mlx5_attach_device(dev); } else { @@ -1214,22 +1232,24 @@ return err; err_reg_dev: + if (boot) + mlx5_devlink_unregister(priv_to_devlink(dev)); +err_devlink_reg: mlx5_unload(dev); err_load: if (boot) mlx5_cleanup_once(dev); function_teardown: mlx5_function_teardown(dev, boot); +err_function: dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; mutex_unlock(&dev->intf_state_mutex); return err; } -static int mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup) +int mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup) { - int err = 0; - if (cleanup) { mlx5_unregister_device(dev); mlx5_drain_health_wq(dev); @@ -1257,7 +1277,7 @@ mlx5_function_teardown(dev, cleanup); out: mutex_unlock(&dev->intf_state_mutex); - return err; + return 0; } static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx) @@ -1353,10 +1373,6 @@ request_module_nowait(MLX5_IB_MOD); - err = mlx5_devlink_register(devlink, &pdev->dev); - if (err) - goto clean_load; - err = mlx5_crdump_enable(dev); if (err) dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err); @@ -1364,9 +1380,6 @@ pci_save_state(pdev); return 0; -clean_load: - mlx5_unload_one(dev, true); - err_load_one: mlx5_pci_close(dev); pci_init_err: @@ -1551,6 +1564,22 @@ mlx5_pci_disable_device(dev); } +static int mlx5_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); + + mlx5_unload_one(dev, false); + + return 0; +} + +static int mlx5_resume(struct pci_dev *pdev) +{ + struct mlx5_core_dev *dev = pci_get_drvdata(pdev); + + return mlx5_load_one(dev, false); +} + static const struct pci_device_id mlx5_core_pci_table[] = { { PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_CONNECTIB) }, { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF}, /* Connect-IB VF */ @@ -1567,6 +1596,7 @@ { PCI_VDEVICE(MELLANOX, 0x101d) }, /* ConnectX-6 Dx */ { PCI_VDEVICE(MELLANOX, 0x101e), MLX5_PCI_DEV_IS_VF}, /* ConnectX Family mlx5Gen Virtual Function */ { PCI_VDEVICE(MELLANOX, 0x101f) }, /* ConnectX-6 LX */ + { PCI_VDEVICE(MELLANOX, 0x1021) }, /* ConnectX-7 */ { PCI_VDEVICE(MELLANOX, 0xa2d2) }, /* BlueField integrated ConnectX-5 network controller */ { PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF}, /* BlueField integrated ConnectX-5 network controller VF */ { PCI_VDEVICE(MELLANOX, 0xa2d6) }, /* BlueField-2 integrated ConnectX-6 Dx network controller */ @@ -1589,10 +1619,12 @@ } static struct pci_driver mlx5_core_driver = { - .name = DRIVER_NAME, + .name = KBUILD_MODNAME, .id_table = mlx5_core_pci_table, .probe = init_one, .remove = remove_one, + .suspend = mlx5_suspend, + .resume = mlx5_resume, .shutdown = shutdown, .err_handler = &mlx5_err_handler, .sriov_configure = mlx5_core_sriov_configure, @@ -1609,10 +1641,13 @@ } } -static int __init init(void) +static int __init mlx5_init(void) { int err; + WARN_ONCE(strcmp(MLX5_ADEV_NAME, KBUILD_MODNAME), + "mlx5_core name not in sync with kernel module name"); + get_random_bytes(&sw_owner_id, sizeof(sw_owner_id)); mlx5_core_verify_params(); @@ -1634,7 +1669,7 @@ return err; } -static void __exit cleanup(void) +static void __exit mlx5_cleanup(void) { #ifdef CONFIG_MLX5_CORE_EN mlx5e_cleanup(); @@ -1643,5 +1678,5 @@ mlx5_unregister_debugfs(); } -module_init(init); -module_exit(cleanup); +module_init(mlx5_init); +module_exit(mlx5_cleanup); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h @@ -43,9 +43,6 @@ #include #include -#define DRIVER_NAME "mlx5_core" -#define DRIVER_VERSION "5.0-0" - extern uint mlx5_core_debug_mask; #define mlx5_core_dbg(__dev, format, ...) \ @@ -243,4 +240,7 @@ u8 mlx5_get_nic_state(struct mlx5_core_dev *dev); void mlx5_set_nic_state(struct mlx5_core_dev *dev, u8 state); + +int mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup); +int mlx5_load_one(struct mlx5_core_dev *dev, bool boot); #endif /* __MLX5_CORE_H__ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -167,7 +167,8 @@ fp = list_entry(dev->priv.free_list.next, struct fw_page, list); n = find_first_bit(&fp->bitmask, 8 * sizeof(fp->bitmask)); if (n >= MLX5_NUM_4K_IN_PAGE) { - mlx5_core_warn(dev, "alloc 4k bug\n"); + mlx5_core_warn(dev, "alloc 4k bug: fw page = 0x%llx, n = %u, bitmask: %lu, max num of 4K pages: %d\n", + fp->addr, n, fp->bitmask, MLX5_NUM_4K_IN_PAGE); return -ENOENT; } clear_bit(n, &fp->bitmask); @@ -339,6 +340,24 @@ return err; } +static u32 fwp_fill_manage_pages_out(struct fw_page *fwp, u32 *out, u32 index, + u32 npages) +{ + u32 pages_set = 0; + unsigned int n; + + for_each_clear_bit(n, &fwp->bitmask, MLX5_NUM_4K_IN_PAGE) { + MLX5_ARRAY_SET64(manage_pages_out, out, pas, index + pages_set, + fwp->addr + (n * MLX5_ADAPTER_PAGE_SIZE)); + pages_set++; + + if (!--npages) + break; + } + + return pages_set; +} + static int reclaim_pages_cmd(struct mlx5_core_dev *dev, u32 *in, int in_size, u32 *out, int out_size) { @@ -348,7 +367,7 @@ u32 npages; u32 i = 0; - if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) + if (!mlx5_cmd_is_down(dev)) return mlx5_cmd_exec(dev, in, in_size, out, out_size); /* No hard feelings, we want our pages back! */ @@ -362,8 +381,7 @@ if (fwp->func_id != func_id) continue; - MLX5_ARRAY_SET64(manage_pages_out, out, pas, i, fwp->addr); - i++; + i += fwp_fill_manage_pages_out(fwp, out, i, npages - i); } MLX5_SET(manage_pages_out, out, output_num_entries, i); @@ -486,8 +504,8 @@ int mlx5_satisfy_startup_pages(struct mlx5_core_dev *dev, int boot) { - u16 uninitialized_var(func_id); - s32 uninitialized_var(npages); + u16 func_id; + s32 npages; int err; err = mlx5_cmd_query_pages(dev, &func_id, &npages, boot); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -115,7 +115,7 @@ return 0; err_request_irq: - for (; i >= 0; i--) { + while (i--) { struct mlx5_irq *irq = mlx5_irq_get(dev, i); int irqn = pci_irq_vector(dev->pdev, i); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -293,7 +293,40 @@ return 0; } -static int mlx5_eeprom_page(int offset) +static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, + u8 *module_id) +{ + u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; + u32 out[MLX5_ST_SZ_DW(mcia_reg)]; + int err, status; + u8 *ptr; + + MLX5_SET(mcia_reg, in, i2c_device_address, MLX5_I2C_ADDR_LOW); + MLX5_SET(mcia_reg, in, module, module_num); + MLX5_SET(mcia_reg, in, device_address, 0); + MLX5_SET(mcia_reg, in, page_number, 0); + MLX5_SET(mcia_reg, in, size, 1); + MLX5_SET(mcia_reg, in, l, 0); + + err = mlx5_core_access_reg(dev, in, sizeof(in), out, + sizeof(out), MLX5_REG_MCIA, 0, 0); + if (err) + return err; + + status = MLX5_GET(mcia_reg, out, status); + if (status) { + mlx5_core_err(dev, "query_mcia_reg failed: status: 0x%x\n", + status); + return -EIO; + } + ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + + *module_id = ptr[0]; + + return 0; +} + +static int mlx5_qsfp_eeprom_page(u16 offset) { if (offset < MLX5_EEPROM_PAGE_LENGTH) /* Addresses between 0-255 - page 00 */ @@ -307,7 +340,7 @@ MLX5_EEPROM_HIGH_PAGE_LENGTH); } -static int mlx5_eeprom_high_page_offset(int page_num) +static int mlx5_qsfp_eeprom_high_page_offset(int page_num) { if (!page_num) /* Page 0 always start from low page */ return 0; @@ -316,35 +349,62 @@ return page_num * MLX5_EEPROM_HIGH_PAGE_LENGTH; } +static void mlx5_qsfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) +{ + *i2c_addr = MLX5_I2C_ADDR_LOW; + *page_num = mlx5_qsfp_eeprom_page(*offset); + *offset -= mlx5_qsfp_eeprom_high_page_offset(*page_num); +} + +static void mlx5_sfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) +{ + *i2c_addr = MLX5_I2C_ADDR_LOW; + *page_num = 0; + + if (*offset < MLX5_EEPROM_PAGE_LENGTH) + return; + + *i2c_addr = MLX5_I2C_ADDR_HIGH; + *offset -= MLX5_EEPROM_PAGE_LENGTH; +} + int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, u16 offset, u16 size, u8 *data) { - int module_num, page_num, status, err; + int module_num, status, err, page_num = 0; + u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; u32 out[MLX5_ST_SZ_DW(mcia_reg)]; - u32 in[MLX5_ST_SZ_DW(mcia_reg)]; - u16 i2c_addr; - void *ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); + u16 i2c_addr = 0; + u8 module_id; + void *ptr; err = mlx5_query_module_num(dev, &module_num); if (err) return err; - memset(in, 0, sizeof(in)); - size = min_t(int, size, MLX5_EEPROM_MAX_BYTES); - - /* Get the page number related to the given offset */ - page_num = mlx5_eeprom_page(offset); + err = mlx5_query_module_id(dev, module_num, &module_id); + if (err) + return err; - /* Set the right offset according to the page number, - * For page_num > 0, relative offset is always >= 128 (high page). - */ - offset -= mlx5_eeprom_high_page_offset(page_num); + switch (module_id) { + case MLX5_MODULE_ID_SFP: + mlx5_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + case MLX5_MODULE_ID_QSFP: + case MLX5_MODULE_ID_QSFP_PLUS: + case MLX5_MODULE_ID_QSFP28: + mlx5_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; + default: + mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id); + return -EINVAL; + } if (offset + size > MLX5_EEPROM_PAGE_LENGTH) /* Cross pages read, read until offset 256 in low page */ size -= offset + size - MLX5_EEPROM_PAGE_LENGTH; - i2c_addr = MLX5_I2C_ADDR_LOW; + size = min_t(int, size, MLX5_EEPROM_MAX_BYTES); MLX5_SET(mcia_reg, in, l, 0); MLX5_SET(mcia_reg, in, module, module_num); @@ -365,6 +425,7 @@ return -EIO; } + ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); memcpy(data, ptr, size); return size; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/rdma.c @@ -116,7 +116,7 @@ static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev) { mlx5_core_roce_gid_set(dev, 0, 0, 0, - NULL, NULL, false, 0, 0); + NULL, NULL, false, 0, 1); } static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid) @@ -156,6 +156,9 @@ { int err; + if (!MLX5_CAP_GEN(dev, roce)) + return; + err = mlx5_nic_vport_enable_roce(dev); if (err) { mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/sriov.c @@ -211,8 +211,7 @@ host_total_vfs = MLX5_GET(query_esw_functions_out, out, host_params_context.host_total_vfs); kvfree(out); - if (host_total_vfs) - return host_total_vfs; + return host_total_vfs; } done: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c @@ -667,6 +667,7 @@ switch (action_type) { case DR_ACTION_TYP_DROP: attr.final_icm_addr = nic_dmn->drop_icm_addr; + attr.hit_gvmi = nic_dmn->drop_icm_addr >> 48; break; case DR_ACTION_TYP_FT: dest_action = action; @@ -930,7 +931,6 @@ action->rewrite.data = (void *)ops; action->rewrite.num_of_actions = i; - action->rewrite.chunk->byte_size = i * sizeof(*ops); ret = mlx5dr_send_postsend_action(dmn, action); if (ret) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c @@ -92,6 +92,7 @@ caps->eswitch_manager = MLX5_CAP_GEN(mdev, eswitch_manager); caps->gvmi = MLX5_CAP_GEN(mdev, vhca_id); caps->flex_protocols = MLX5_CAP_GEN(mdev, flex_parser_protocols); + caps->sw_format_ver = MLX5_CAP_GEN(mdev, steering_format_version); if (mlx5dr_matcher_supp_flex_parser_icmp_v4(caps)) { caps->flex_parser_id_icmp_dw0 = MLX5_CAP_GEN(mdev, flex_parser_id_icmp_dw0); @@ -422,11 +423,12 @@ err = mlx5_cmd_exec(mdev, in, inlen, out, sizeof(out)); if (err) - return err; + goto err_free_in; *reformat_id = MLX5_GET(alloc_packet_reformat_context_out, out, packet_reformat_id); - kvfree(in); +err_free_in: + kvfree(in); return err; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c @@ -2,6 +2,7 @@ /* Copyright (c) 2019 Mellanox Technologies. */ #include +#include #include "dr_types.h" static int dr_domain_init_cache(struct mlx5dr_domain *dmn) @@ -64,9 +65,9 @@ } dmn->uar = mlx5_get_uars_page(dmn->mdev); - if (!dmn->uar) { + if (IS_ERR(dmn->uar)) { mlx5dr_err(dmn, "Couldn't allocate UAR\n"); - ret = -ENOMEM; + ret = PTR_ERR(dmn->uar); goto clean_pd; } @@ -223,6 +224,11 @@ if (ret) return ret; + if (dmn->info.caps.sw_format_ver != MLX5_STEERING_FORMAT_CONNECTX_5) { + mlx5dr_err(dmn, "SW steering is not supported on this device\n"); + return -EOPNOTSUPP; + } + ret = dr_domain_query_fdb_caps(mdev, dmn); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c @@ -209,7 +209,7 @@ /* We need to copy the refcount since this ste * may have been traversed several times */ - refcount_set(&new_ste->refcount, refcount_read(&cur_ste->refcount)); + new_ste->refcount = cur_ste->refcount; /* Link old STEs rule_mem list to the new ste */ mlx5dr_rule_update_rule_member(cur_ste, new_ste); @@ -638,6 +638,9 @@ if (!rule_mem) return -ENOMEM; + INIT_LIST_HEAD(&rule_mem->list); + INIT_LIST_HEAD(&rule_mem->use_ste_list); + rule_mem->ste = ste; list_add_tail(&rule_mem->list, &nic_rule->rule_members_list); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB /* Copyright (c) 2019 Mellanox Technologies. */ +#include #include "dr_types.h" #define QUEUE_SIZE 128 @@ -180,7 +181,7 @@ in, pas)); err = mlx5_core_create_qp(mdev, &dr_qp->mqp, in, inlen); - kfree(in); + kvfree(in); if (err) { mlx5_core_warn(mdev, " Can't create QP\n"); @@ -557,7 +558,8 @@ int ret; send_info.write.addr = (uintptr_t)action->rewrite.data; - send_info.write.length = action->rewrite.chunk->byte_size; + send_info.write.length = action->rewrite.num_of_actions * + DR_MODIFY_ACTION_SIZE; send_info.write.lkey = 0; send_info.remote_addr = action->rewrite.chunk->mr_addr; send_info.rkey = action->rewrite.chunk->rkey; @@ -601,6 +603,7 @@ MLX5_SET(qpc, qpc, log_ack_req_freq, 0); MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); MLX5_SET(qpc, qpc, rnr_retry, attr->rnr_retry); + MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 0x8); /* ~1ms */ return mlx5_core_qp_modify(mdev, MLX5_CMD_OP_RTR2RTS_QP, 0, qpc, &dr_qp->mqp); @@ -687,6 +690,12 @@ pr_info("CQ event %u on CQ #%u\n", event, mcq->cqn); } +static void dr_cq_complete(struct mlx5_core_cq *mcq, + struct mlx5_eqe *eqe) +{ + pr_err("CQ completion CQ: #%u\n", mcq->cqn); +} + static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, struct mlx5_uars_page *uar, size_t ncqe) @@ -729,7 +738,7 @@ if (!in) goto err_cqwq; - vector = smp_processor_id() % mlx5_comp_vectors_count(mdev); + vector = raw_smp_processor_id() % mlx5_comp_vectors_count(mdev); err = mlx5_vector2eqn(mdev, vector, &eqn, &irqn); if (err) { kvfree(in); @@ -748,6 +757,7 @@ mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, pas); cq->mcq.event = dr_cq_event; + cq->mcq.comp = dr_cq_complete; err = mlx5_core_create_cq(mdev, &cq->mcq, in, inlen, out, sizeof(out)); kvfree(in); @@ -759,7 +769,12 @@ cq->mcq.set_ci_db = cq->wq_ctrl.db.db; cq->mcq.arm_db = cq->wq_ctrl.db.db + 1; *cq->mcq.set_ci_db = 0; - *cq->mcq.arm_db = 0; + + /* set no-zero value, in order to avoid the HW to run db-recovery on + * CQ that used in polling mode. + */ + *cq->mcq.arm_db = cpu_to_be32(2 << 28); + cq->mcq.vector = 0; cq->mcq.irqn = irqn; cq->mcq.uar = uar; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c @@ -340,7 +340,7 @@ if (dst->next_htbl) dst->next_htbl->pointing_ste = dst; - refcount_set(&dst->refcount, refcount_read(&src->refcount)); + dst->refcount = src->refcount; INIT_LIST_HEAD(&dst->rule_list); list_splice_tail_init(&src->rule_list, &dst->rule_list); @@ -557,7 +557,7 @@ bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste) { - return !refcount_read(&ste->refcount); + return !ste->refcount; } /* Init one ste as a pattern for ste data array */ @@ -681,14 +681,14 @@ htbl->ste_arr = chunk->ste_arr; htbl->hw_ste_arr = chunk->hw_ste_arr; htbl->miss_list = chunk->miss_list; - refcount_set(&htbl->refcount, 0); + htbl->refcount = 0; for (i = 0; i < chunk->num_of_entries; i++) { struct mlx5dr_ste *ste = &htbl->ste_arr[i]; ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED; ste->htbl = htbl; - refcount_set(&ste->refcount, 0); + ste->refcount = 0; INIT_LIST_HEAD(&ste->miss_list_node); INIT_LIST_HEAD(&htbl->miss_list[i]); INIT_LIST_HEAD(&ste->rule_list); @@ -705,7 +705,7 @@ int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl) { - if (refcount_read(&htbl->refcount)) + if (htbl->refcount) return -EBUSY; mlx5dr_icm_free_chunk(htbl->chunk); @@ -2257,7 +2257,9 @@ struct mlx5dr_cmd_vport_cap *vport_cap; struct mlx5dr_domain *dmn = sb->dmn; struct mlx5dr_cmd_caps *caps; + u8 *bit_mask = sb->bit_mask; u8 *tag = hw_ste->tag; + bool source_gvmi_set; DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); @@ -2278,7 +2280,8 @@ if (!vport_cap) return -EINVAL; - if (vport_cap->vport_gvmi) + source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); + if (vport_cap->vport_gvmi && source_gvmi_set) MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); misc->source_eswitch_owner_vhca_id = 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_table.c @@ -9,7 +9,7 @@ struct mlx5dr_matcher *last_matcher = NULL; struct mlx5dr_htbl_connect_info info; struct mlx5dr_ste_htbl *last_htbl; - int ret; + int ret = -EOPNOTSUPP; if (action && action->action_type != DR_ACTION_TYP_FT) return -EOPNOTSUPP; @@ -68,6 +68,9 @@ } } + if (ret) + goto out; + /* Release old action */ if (tbl->miss_action) refcount_dec(&tbl->miss_action->refcount); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h @@ -117,7 +117,7 @@ struct mlx5dr_ste { u8 *hw_ste; /* refcount: indicates the num of rules that using this ste */ - refcount_t refcount; + u32 refcount; /* attached to the miss_list head at each htbl entry */ struct list_head miss_list_node; @@ -149,7 +149,7 @@ struct mlx5dr_ste_htbl { u8 lu_type; u16 byte_mask; - refcount_t refcount; + u32 refcount; struct mlx5dr_icm_chunk *chunk; struct mlx5dr_ste *ste_arr; u8 *hw_ste_arr; @@ -200,13 +200,14 @@ static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl) { - if (refcount_dec_and_test(&htbl->refcount)) + htbl->refcount--; + if (!htbl->refcount) mlx5dr_ste_htbl_free(htbl); } static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl) { - refcount_inc(&htbl->refcount); + htbl->refcount++; } /* STE utils */ @@ -248,14 +249,15 @@ struct mlx5dr_matcher *matcher, struct mlx5dr_matcher_rx_tx *nic_matcher) { - if (refcount_dec_and_test(&ste->refcount)) + ste->refcount--; + if (!ste->refcount) mlx5dr_ste_free(ste, matcher, nic_matcher); } /* initial as 0, increased only when ste appears in a new rule */ static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste) { - refcount_inc(&ste->refcount); + ste->refcount++; } void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste, @@ -611,6 +613,7 @@ u8 max_ft_level; u16 roce_min_src_udp; u8 num_esw_ports; + u8 sw_format_ver; bool eswitch_manager; bool rx_sw_owner; bool tx_sw_owner; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/steering/fs_dr.c @@ -43,11 +43,10 @@ err = mlx5dr_table_set_miss_action(ft->fs_dr_table.dr_table, action); if (err && action) { err = mlx5dr_action_destroy(action); - if (err) { - action = NULL; - mlx5_core_err(ns->dev, "Failed to destroy action (%d)\n", - err); - } + if (err) + mlx5_core_err(ns->dev, + "Failed to destroy action (%d)\n", err); + action = NULL; } ft->fs_dr_table.miss_action = action; if (old_miss_action) { @@ -247,29 +246,9 @@ /* The order of the actions are must to be keep, only the following * order is supported by SW steering: - * TX: push vlan -> modify header -> encap + * TX: modify header -> push vlan -> encap * RX: decap -> pop vlan -> modify header */ - if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) { - tmp_action = create_action_push_vlan(domain, &fte->action.vlan[0]); - if (!tmp_action) { - err = -ENOMEM; - goto free_actions; - } - fs_dr_actions[fs_dr_num_actions++] = tmp_action; - actions[num_actions++] = tmp_action; - } - - if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) { - tmp_action = create_action_push_vlan(domain, &fte->action.vlan[1]); - if (!tmp_action) { - err = -ENOMEM; - goto free_actions; - } - fs_dr_actions[fs_dr_num_actions++] = tmp_action; - actions[num_actions++] = tmp_action; - } - if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_DECAP) { enum mlx5dr_action_reformat_type decap_type = DR_ACTION_REFORMAT_TYP_TNL_L2_TO_L2; @@ -322,6 +301,26 @@ actions[num_actions++] = fte->action.modify_hdr->action.dr_action; + if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) { + tmp_action = create_action_push_vlan(domain, &fte->action.vlan[0]); + if (!tmp_action) { + err = -ENOMEM; + goto free_actions; + } + fs_dr_actions[fs_dr_num_actions++] = tmp_action; + actions[num_actions++] = tmp_action; + } + + if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) { + tmp_action = create_action_push_vlan(domain, &fte->action.vlan[1]); + if (!tmp_action) { + err = -ENOMEM; + goto free_actions; + } + fs_dr_actions[fs_dr_num_actions++] = tmp_action; + actions[num_actions++] = tmp_action; + } + if (delay_encap_set) actions[num_actions++] = fte->action.pkt_reformat->action.dr_action; @@ -352,26 +351,16 @@ if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) { list_for_each_entry(dst, &fte->node.children, node.list) { enum mlx5_flow_destination_type type = dst->dest_attr.type; - u32 id; if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { err = -ENOSPC; goto free_actions; } - switch (type) { - case MLX5_FLOW_DESTINATION_TYPE_COUNTER: - id = dst->dest_attr.counter_id; + if (type == MLX5_FLOW_DESTINATION_TYPE_COUNTER) + continue; - tmp_action = - mlx5dr_action_create_flow_counter(id); - if (!tmp_action) { - err = -ENOMEM; - goto free_actions; - } - fs_dr_actions[fs_dr_num_actions++] = tmp_action; - actions[num_actions++] = tmp_action; - break; + switch (type) { case MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE: tmp_action = create_ft_action(dev, dst); if (!tmp_action) { @@ -397,6 +386,32 @@ } } + if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) { + list_for_each_entry(dst, &fte->node.children, node.list) { + u32 id; + + if (dst->dest_attr.type != + MLX5_FLOW_DESTINATION_TYPE_COUNTER) + continue; + + if (num_actions == MLX5_FLOW_CONTEXT_ACTION_MAX) { + err = -ENOSPC; + goto free_actions; + } + + id = dst->dest_attr.counter_id; + tmp_action = + mlx5dr_action_create_flow_counter(id); + if (!tmp_action) { + err = -ENOMEM; + goto free_actions; + } + + fs_dr_actions[fs_dr_num_actions++] = tmp_action; + actions[num_actions++] = tmp_action; + } + } + params.match_sz = match_sz; params.match_buf = (u64 *)fte->val; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/transobj.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/transobj.c @@ -457,6 +457,15 @@ return err; } +static void mlx5_hairpin_unpair_peer_sq(struct mlx5_hairpin *hp) +{ + int i; + + for (i = 0; i < hp->num_channels; i++) + mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, + MLX5_SQC_STATE_RST, 0, 0); +} + static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp) { int i; @@ -465,13 +474,9 @@ for (i = 0; i < hp->num_channels; i++) mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_RST, 0, 0); - /* unset peer SQs */ - if (hp->peer_gone) - return; - for (i = 0; i < hp->num_channels; i++) - mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, - MLX5_SQC_STATE_RST, 0, 0); + if (!hp->peer_gone) + mlx5_hairpin_unpair_peer_sq(hp); } struct mlx5_hairpin * @@ -518,3 +523,16 @@ mlx5_hairpin_destroy_queues(hp); kfree(hp); } + +void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp) +{ + int i; + + mlx5_hairpin_unpair_peer_sq(hp); + + /* destroy peer SQ */ + for (i = 0; i < hp->num_channels; i++) + mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]); + + hp->peer_gone = true; +} --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/wq.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/wq.c @@ -96,6 +96,13 @@ return err; } +void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq) +{ + wq->wqe_ctr = 0; + wq->cur_sz = 0; + mlx5_wq_cyc_update_db_record(wq); +} + int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, void *qpc, struct mlx5_wq_qp *wq, struct mlx5_wq_ctrl *wq_ctrl) @@ -194,6 +201,19 @@ return err; } +static void mlx5_wq_ll_init_list(struct mlx5_wq_ll *wq) +{ + struct mlx5_wqe_srq_next_seg *next_seg; + int i; + + for (i = 0; i < wq->fbc.sz_m1; i++) { + next_seg = mlx5_wq_ll_get_wqe(wq, i); + next_seg->next_wqe_index = cpu_to_be16(i + 1); + } + next_seg = mlx5_wq_ll_get_wqe(wq, i); + wq->tail_next = &next_seg->next_wqe_index; +} + int mlx5_wq_ll_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, void *wqc, struct mlx5_wq_ll *wq, struct mlx5_wq_ctrl *wq_ctrl) @@ -201,9 +221,7 @@ u8 log_wq_stride = MLX5_GET(wq, wqc, log_wq_stride); u8 log_wq_sz = MLX5_GET(wq, wqc, log_wq_sz); struct mlx5_frag_buf_ctrl *fbc = &wq->fbc; - struct mlx5_wqe_srq_next_seg *next_seg; int err; - int i; err = mlx5_db_alloc_node(mdev, &wq_ctrl->db, param->db_numa_node); if (err) { @@ -222,13 +240,7 @@ mlx5_init_fbc(wq_ctrl->buf.frags, log_wq_stride, log_wq_sz, fbc); - for (i = 0; i < fbc->sz_m1; i++) { - next_seg = mlx5_wq_ll_get_wqe(wq, i); - next_seg->next_wqe_index = cpu_to_be16(i + 1); - } - next_seg = mlx5_wq_ll_get_wqe(wq, i); - wq->tail_next = &next_seg->next_wqe_index; - + mlx5_wq_ll_init_list(wq); wq_ctrl->mdev = mdev; return 0; @@ -239,6 +251,15 @@ return err; } +void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq) +{ + wq->head = 0; + wq->wqe_ctr = 0; + wq->cur_sz = 0; + mlx5_wq_ll_init_list(wq); + mlx5_wq_ll_update_db_record(wq); +} + void mlx5_wq_destroy(struct mlx5_wq_ctrl *wq_ctrl) { mlx5_frag_buf_free(wq_ctrl->mdev, &wq_ctrl->buf); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlx5/core/wq.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlx5/core/wq.h @@ -80,10 +80,12 @@ void *wqc, struct mlx5_wq_cyc *wq, struct mlx5_wq_ctrl *wq_ctrl); u32 mlx5_wq_cyc_get_size(struct mlx5_wq_cyc *wq); +void mlx5_wq_cyc_reset(struct mlx5_wq_cyc *wq); int mlx5_wq_qp_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, void *qpc, struct mlx5_wq_qp *wq, struct mlx5_wq_ctrl *wq_ctrl); +void mlx5_wq_ll_reset(struct mlx5_wq_ll *wq); int mlx5_cqwq_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param, void *cqc, struct mlx5_cqwq *wq, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c @@ -14,7 +14,6 @@ #define MLXFW_FSM_STATE_WAIT_TIMEOUT_MS 30000 #define MLXFW_FSM_STATE_WAIT_ROUNDS \ (MLXFW_FSM_STATE_WAIT_TIMEOUT_MS / MLXFW_FSM_STATE_WAIT_CYCLE_MS) -#define MLXFW_FSM_MAX_COMPONENT_SIZE (10 * (1 << 20)) static const char * const mlxfw_fsm_state_err_str[] = { [MLXFW_FSM_STATE_ERR_ERROR] = @@ -111,7 +110,6 @@ if (err) return err; - comp_max_size = min_t(u32, comp_max_size, MLXFW_FSM_MAX_COMPONENT_SIZE); if (comp->data_size > comp_max_size) { pr_err("Component %d is of size %d which is bigger than limit %d\n", comp->index, comp->data_size, comp_max_size); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "mlxfw_mfa2.h" #include "mlxfw_mfa2_file.h" @@ -548,7 +549,7 @@ comp_size = be32_to_cpu(comp->size); comp_buf_size = comp_size + mlxfw_mfa2_comp_magic_len; - comp_data = kmalloc(sizeof(*comp_data) + comp_buf_size, GFP_KERNEL); + comp_data = vzalloc(sizeof(*comp_data) + comp_buf_size); if (!comp_data) return ERR_PTR(-ENOMEM); comp_data->comp.data_size = comp_size; @@ -570,7 +571,7 @@ comp_data->comp.data = comp_data->buff + mlxfw_mfa2_comp_magic_len; return &comp_data->comp; err_out: - kfree(comp_data); + vfree(comp_data); return ERR_PTR(err); } @@ -579,7 +580,7 @@ const struct mlxfw_mfa2_comp_data *comp_data; comp_data = container_of(comp, struct mlxfw_mfa2_comp_data, comp); - kfree(comp_data); + vfree(comp_data); } void mlxfw_mfa2_file_fini(struct mlxfw_mfa2_file *mfa2_file) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2_tlv_multi.c @@ -31,6 +31,8 @@ if (tlv->type == MLXFW_MFA2_TLV_MULTI_PART) { multi = mlxfw_mfa2_tlv_multi_get(mfa2_file, tlv); + if (!multi) + return NULL; tlv_len = NLA_ALIGN(tlv_len + be16_to_cpu(multi->total_len)); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -444,7 +444,8 @@ if (trans->core->fw_flash_in_progress) timeout = msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_DURING_FW_FLASH_MS); - queue_delayed_work(trans->core->emad_wq, &trans->timeout_dw, timeout); + queue_delayed_work(trans->core->emad_wq, &trans->timeout_dw, + timeout << trans->retries); } static int mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core, @@ -493,6 +494,9 @@ err = mlxsw_emad_transmit(trans->core, trans); if (err == 0) return; + + if (!atomic_dec_and_test(&trans->active)) + return; } else { err = -EIO; } @@ -562,7 +566,7 @@ static const struct mlxsw_listener mlxsw_emad_rx_listener = MLXSW_RXL(mlxsw_emad_rx_listener_func, ETHEMAD, TRAP_TO_CPU, false, - EMAD, DISCARD); + EMAD, FORWARD); static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) { @@ -592,7 +596,7 @@ err = mlxsw_core_trap_register(mlxsw_core, &mlxsw_emad_rx_listener, mlxsw_core); if (err) - return err; + goto err_trap_register; err = mlxsw_core->driver->basic_trap_groups_set(mlxsw_core); if (err) @@ -604,6 +608,7 @@ err_emad_trap_set: mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, mlxsw_core); +err_trap_register: destroy_workqueue(mlxsw_core->emad_wq); return err; } @@ -1280,6 +1285,8 @@ if (!reload) devlink_resources_unregister(devlink, NULL); mlxsw_core->bus->fini(mlxsw_core->bus_priv); + if (!reload) + devlink_free(devlink); return; @@ -1576,7 +1583,7 @@ err = mlxsw_emad_reg_access(mlxsw_core, reg, payload, type, trans, bulk_list, cb, cb_priv, tid); if (err) { - kfree(trans); + kfree_rcu(trans, rcu); return err; } return 0; @@ -1801,11 +1808,13 @@ break; } } - rcu_read_unlock(); - if (!found) + if (!found) { + rcu_read_unlock(); goto drop; + } rxl->func(skb, local_port, rxl_item->priv); + rcu_read_unlock(); return; drop: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c @@ -316,7 +316,7 @@ block = kzalloc(sizeof(*block), GFP_KERNEL); if (!block) - return NULL; + return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&block->resource_list); block->afa = mlxsw_afa; @@ -344,7 +344,7 @@ mlxsw_afa_set_destroy(block->first_set); err_first_set_create: kfree(block); - return NULL; + return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL(mlxsw_afa_block_create); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c @@ -19,22 +19,14 @@ #define MLXSW_THERMAL_ASIC_TEMP_NORM 75000 /* 75C */ #define MLXSW_THERMAL_ASIC_TEMP_HIGH 85000 /* 85C */ #define MLXSW_THERMAL_ASIC_TEMP_HOT 105000 /* 105C */ -#define MLXSW_THERMAL_ASIC_TEMP_CRIT 110000 /* 110C */ +#define MLXSW_THERMAL_ASIC_TEMP_CRIT 140000 /* 140C */ #define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */ #define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2) #define MLXSW_THERMAL_ZONE_MAX_NAME 16 #define MLXSW_THERMAL_TEMP_SCORE_MAX GENMASK(31, 0) #define MLXSW_THERMAL_MAX_STATE 10 +#define MLXSW_THERMAL_MIN_STATE 2 #define MLXSW_THERMAL_MAX_DUTY 255 -/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values - * MLXSW_THERMAL_MAX_STATE + x, where x is between 2 and 10 are used for - * setting fan speed dynamic minimum. For example, if value is set to 14 (40%) - * cooling levels vector will be set to 4, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10 to - * introduce PWM speed in percent: 40, 40, 40, 40, 40, 50, 60. 70, 80, 90, 100. - */ -#define MLXSW_THERMAL_SPEED_MIN (MLXSW_THERMAL_MAX_STATE + 2) -#define MLXSW_THERMAL_SPEED_MAX (MLXSW_THERMAL_MAX_STATE * 2) -#define MLXSW_THERMAL_SPEED_MIN_LEVEL 2 /* 20% */ /* External cooling devices, allowed for binding to mlxsw thermal zones. */ static char * const mlxsw_thermal_external_allowed_cdev[] = { @@ -177,6 +169,12 @@ if (err) return err; + if (crit_temp > emerg_temp) { + dev_warn(dev, "%s : Critical threshold %d is above emergency threshold %d\n", + tz->tzdev->type, crit_temp, emerg_temp); + return 0; + } + /* According to the system thermal requirements, the thermal zones are * defined with four trip points. The critical and emergency * temperature thresholds, provided by QSFP module are set as "active" @@ -191,11 +189,8 @@ tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp = crit_temp; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp = crit_temp; tz->trips[MLXSW_THERMAL_TEMP_TRIP_HOT].temp = emerg_temp; - if (emerg_temp > crit_temp) - tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + + tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp + MLXSW_THERMAL_MODULE_TEMP_SHIFT; - else - tz->trips[MLXSW_THERMAL_TEMP_TRIP_CRIT].temp = emerg_temp; return 0; } @@ -390,8 +385,7 @@ static int mlxsw_thermal_trend_get(struct thermal_zone_device *tzdev, int trip, enum thermal_trend *trend) { - struct mlxsw_thermal_module *tz = tzdev->devdata; - struct mlxsw_thermal *thermal = tz->parent; + struct mlxsw_thermal *thermal = tzdev->devdata; if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS) return -EINVAL; @@ -592,6 +586,22 @@ return 0; } +static int mlxsw_thermal_module_trend_get(struct thermal_zone_device *tzdev, + int trip, enum thermal_trend *trend) +{ + struct mlxsw_thermal_module *tz = tzdev->devdata; + struct mlxsw_thermal *thermal = tz->parent; + + if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS) + return -EINVAL; + + if (tzdev == thermal->tz_highest_dev) + return 1; + + *trend = THERMAL_TREND_STABLE; + return 0; +} + static struct thermal_zone_device_ops mlxsw_thermal_module_ops = { .bind = mlxsw_thermal_module_bind, .unbind = mlxsw_thermal_module_unbind, @@ -603,7 +613,7 @@ .set_trip_temp = mlxsw_thermal_module_trip_temp_set, .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get, .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set, - .get_trend = mlxsw_thermal_trend_get, + .get_trend = mlxsw_thermal_module_trend_get, }; static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev, @@ -642,7 +652,7 @@ .set_trip_temp = mlxsw_thermal_module_trip_temp_set, .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get, .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set, - .get_trend = mlxsw_thermal_trend_get, + .get_trend = mlxsw_thermal_module_trend_get, }; static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev, @@ -685,49 +695,16 @@ struct mlxsw_thermal *thermal = cdev->devdata; struct device *dev = thermal->bus_info->dev; char mfsc_pl[MLXSW_REG_MFSC_LEN]; - unsigned long cur_state, i; int idx; - u8 duty; int err; + if (state > MLXSW_THERMAL_MAX_STATE) + return -EINVAL; + idx = mlxsw_get_cooling_device_idx(thermal, cdev); if (idx < 0) return idx; - /* Verify if this request is for changing allowed fan dynamical - * minimum. If it is - update cooling levels accordingly and update - * state, if current state is below the newly requested minimum state. - * For example, if current state is 5, and minimal state is to be - * changed from 4 to 6, thermal->cooling_levels[0 to 5] will be changed - * all from 4 to 6. And state 5 (thermal->cooling_levels[4]) should be - * overwritten. - */ - if (state >= MLXSW_THERMAL_SPEED_MIN && - state <= MLXSW_THERMAL_SPEED_MAX) { - state -= MLXSW_THERMAL_MAX_STATE; - for (i = 0; i <= MLXSW_THERMAL_MAX_STATE; i++) - thermal->cooling_levels[i] = max(state, i); - - mlxsw_reg_mfsc_pack(mfsc_pl, idx, 0); - err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsc), mfsc_pl); - if (err) - return err; - - duty = mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl); - cur_state = mlxsw_duty_to_state(duty); - - /* If current fan state is lower than requested dynamical - * minimum, increase fan speed up to dynamical minimum. - */ - if (state < cur_state) - return 0; - - state = cur_state; - } - - if (state > MLXSW_THERMAL_MAX_STATE) - return -EINVAL; - /* Normalize the state to the valid speed range. */ state = thermal->cooling_levels[state]; mlxsw_reg_mfsc_pack(mfsc_pl, idx, mlxsw_state_to_duty(state)); @@ -1022,8 +999,7 @@ /* Initialize cooling levels per PWM state. */ for (i = 0; i < MLXSW_THERMAL_MAX_STATE; i++) - thermal->cooling_levels[i] = max(MLXSW_THERMAL_SPEED_MIN_LEVEL, - i); + thermal->cooling_levels[i] = max(MLXSW_THERMAL_MIN_STATE, i); thermal->polling_delay = bus_info->low_frequency ? MLXSW_THERMAL_SLOW_POLL_INT : --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/i2c.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/i2c.c @@ -47,6 +47,7 @@ #define MLXSW_I2C_MBOX_SIZE_BITS 12 #define MLXSW_I2C_ADDR_BUF_SIZE 4 #define MLXSW_I2C_BLK_DEF 32 +#define MLXSW_I2C_BLK_MAX 100 #define MLXSW_I2C_RETRY 5 #define MLXSW_I2C_TIMEOUT_MSECS 5000 #define MLXSW_I2C_MAX_DATA_SIZE 256 @@ -427,7 +428,7 @@ } else { /* No input mailbox is case of initialization query command. */ reg_size = MLXSW_I2C_MAX_DATA_SIZE; - num = reg_size / mlxsw_i2c->block_size; + num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size); if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) { dev_err(&client->dev, "Could not acquire lock"); @@ -575,7 +576,7 @@ return -EOPNOTSUPP; } - mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF, + mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX, min_t(u16, quirks->max_read_len, quirks->max_write_len)); } else { @@ -649,6 +650,7 @@ return 0; errout: + mutex_destroy(&mlxsw_i2c->cmd.lock); i2c_set_clientdata(client, NULL); return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/minimal.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/minimal.c @@ -204,8 +204,8 @@ err_register_netdev: mlxsw_m->ports[local_port] = NULL; - free_netdev(dev); err_dev_addr_get: + free_netdev(dev); err_alloc_etherdev: mlxsw_core_port_fini(mlxsw_m->core, local_port); return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -1318,36 +1318,64 @@ mbox->mapaddr); } -static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, - const struct pci_device_id *id) +static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci, + const struct pci_device_id *id, + u32 *p_sys_status) { unsigned long end; - char mrsr_pl[MLXSW_REG_MRSR_LEN]; - int err; + u32 val; - mlxsw_reg_mrsr_pack(mrsr_pl); - err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl); - if (err) - return err; if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) { msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); return 0; } - /* We must wait for the HW to become responsive once again. */ + /* We must wait for the HW to become responsive. */ msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS); end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); do { - u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); - + val = mlxsw_pci_read32(mlxsw_pci, FW_READY); if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC) return 0; cond_resched(); } while (time_before(jiffies, end)); + + *p_sys_status = val & MLXSW_PCI_FW_READY_MASK; + return -EBUSY; } +static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci, + const struct pci_device_id *id) +{ + struct pci_dev *pdev = mlxsw_pci->pdev; + char mrsr_pl[MLXSW_REG_MRSR_LEN]; + u32 sys_status; + int err; + + err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status); + if (err) { + dev_err(&pdev->dev, "Failed to reach system ready status before reset. Status is 0x%x\n", + sys_status); + return err; + } + + mlxsw_reg_mrsr_pack(mrsr_pl); + err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl); + if (err) + return err; + + err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status); + if (err) { + dev_err(&pdev->dev, "Failed to reach system ready status after reset. Status is 0x%x\n", + sys_status); + return err; + } + + return 0; +} + static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci) { int err; @@ -1373,23 +1401,12 @@ u16 num_pages; int err; - mutex_init(&mlxsw_pci->cmd.lock); - init_waitqueue_head(&mlxsw_pci->cmd.wait); - mlxsw_pci->core = mlxsw_core; mbox = mlxsw_cmd_mbox_alloc(); if (!mbox) return -ENOMEM; - err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); - if (err) - goto mbox_put; - - err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.out_mbox); - if (err) - goto err_out_mbox_alloc; - err = mlxsw_pci_sw_reset(mlxsw_pci, mlxsw_pci->id); if (err) goto err_sw_reset; @@ -1496,9 +1513,6 @@ mlxsw_pci_free_irq_vectors(mlxsw_pci); err_alloc_irq: err_sw_reset: - mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox); -err_out_mbox_alloc: - mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); mbox_put: mlxsw_cmd_mbox_free(mbox); return err; @@ -1512,8 +1526,6 @@ mlxsw_pci_aqs_fini(mlxsw_pci); mlxsw_pci_fw_area_fini(mlxsw_pci); mlxsw_pci_free_irq_vectors(mlxsw_pci); - mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox); - mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); } static struct mlxsw_pci_queue * @@ -1727,6 +1739,37 @@ .features = MLXSW_BUS_F_TXRX | MLXSW_BUS_F_RESET, }; +static int mlxsw_pci_cmd_init(struct mlxsw_pci *mlxsw_pci) +{ + int err; + + mutex_init(&mlxsw_pci->cmd.lock); + init_waitqueue_head(&mlxsw_pci->cmd.wait); + + err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); + if (err) + goto err_in_mbox_alloc; + + err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.out_mbox); + if (err) + goto err_out_mbox_alloc; + + return 0; + +err_out_mbox_alloc: + mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); +err_in_mbox_alloc: + mutex_destroy(&mlxsw_pci->cmd.lock); + return err; +} + +static void mlxsw_pci_cmd_fini(struct mlxsw_pci *mlxsw_pci) +{ + mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox); + mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox); + mutex_destroy(&mlxsw_pci->cmd.lock); +} + static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { const char *driver_name = pdev->driver->name; @@ -1782,6 +1825,10 @@ mlxsw_pci->pdev = pdev; pci_set_drvdata(pdev, mlxsw_pci); + err = mlxsw_pci_cmd_init(mlxsw_pci); + if (err) + goto err_pci_cmd_init; + mlxsw_pci->bus_info.device_kind = driver_name; mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev); mlxsw_pci->bus_info.dev = &pdev->dev; @@ -1799,6 +1846,8 @@ return 0; err_bus_device_register: + mlxsw_pci_cmd_fini(mlxsw_pci); +err_pci_cmd_init: iounmap(mlxsw_pci->hw_addr); err_ioremap: err_pci_resource_len_check: @@ -1816,6 +1865,7 @@ struct mlxsw_pci *mlxsw_pci = pci_get_drvdata(pdev); mlxsw_core_bus_device_unregister(mlxsw_pci->core, false); + mlxsw_pci_cmd_fini(mlxsw_pci); iounmap(mlxsw_pci->hw_addr); pci_release_regions(mlxsw_pci->pdev); pci_disable_device(mlxsw_pci->pdev); @@ -1826,6 +1876,7 @@ { pci_driver->probe = mlxsw_pci_probe; pci_driver->remove = mlxsw_pci_remove; + pci_driver->shutdown = mlxsw_pci_remove; return pci_register_driver(pci_driver); } EXPORT_SYMBOL(mlxsw_pci_driver_register); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -5421,6 +5421,7 @@ MLXSW_REG_HTGT_TRAP_GROUP_SP_LBERROR, MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0, MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP1, + MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP, __MLXSW_REG_HTGT_TRAP_GROUP_MAX, MLXSW_REG_HTGT_TRAP_GROUP_MAX = __MLXSW_REG_HTGT_TRAP_GROUP_MAX - 1 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -812,23 +812,17 @@ u64 len; int err; + if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { + this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb)); if (mlxsw_core_skb_transmit_busy(mlxsw_sp->core, &tx_info)) return NETDEV_TX_BUSY; - if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) { - struct sk_buff *skb_orig = skb; - - skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN); - if (!skb) { - this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); - dev_kfree_skb_any(skb_orig); - return NETDEV_TX_OK; - } - dev_consume_skb_any(skb_orig); - } - if (eth_skb_pad(skb)) { this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); return NETDEV_TX_OK; @@ -1167,6 +1161,9 @@ periodic_hw_stats.update_dw.work); if (!netif_carrier_ok(mlxsw_sp_port->dev)) + /* Note: mlxsw_sp_port_down_wipe_counters() clears the cache as + * necessary when port goes down. + */ goto out; mlxsw_sp_port_get_hw_stats(mlxsw_sp_port->dev, @@ -3935,6 +3932,7 @@ mlxsw_sp_cpu_port_remove(mlxsw_sp); kfree(mlxsw_sp->port_to_module); kfree(mlxsw_sp->ports); + mlxsw_sp->ports = NULL; } static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp) @@ -3989,6 +3987,7 @@ kfree(mlxsw_sp->port_to_module); err_port_to_module_alloc: kfree(mlxsw_sp->ports); + mlxsw_sp->ports = NULL; return err; } @@ -4043,6 +4042,14 @@ } } +static struct mlxsw_sp_port * +mlxsw_sp_port_get_by_local_port(struct mlxsw_sp *mlxsw_sp, u8 local_port) +{ + if (mlxsw_sp->ports && mlxsw_sp->ports[local_port]) + return mlxsw_sp->ports[local_port]; + return NULL; +} + static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, unsigned int count, struct netlink_ext_ack *extack) @@ -4061,7 +4068,7 @@ local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X); local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X); - mlxsw_sp_port = mlxsw_sp->ports[local_port]; + mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port); if (!mlxsw_sp_port) { dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", local_port); @@ -4139,7 +4146,7 @@ local_ports_in_1x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_1X); local_ports_in_2x = MLXSW_CORE_RES_GET(mlxsw_core, LOCAL_PORTS_IN_2X); - mlxsw_sp_port = mlxsw_sp->ports[local_port]; + mlxsw_sp_port = mlxsw_sp_port_get_by_local_port(mlxsw_sp, local_port); if (!mlxsw_sp_port) { dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", local_port); @@ -4176,6 +4183,15 @@ return 0; } +static void +mlxsw_sp_port_down_wipe_counters(struct mlxsw_sp_port *mlxsw_sp_port) +{ + int i; + + for (i = 0; i < TC_MAX_QUEUE; i++) + mlxsw_sp_port->periodic_hw_stats.xstats.backlog[i] = 0; +} + static void mlxsw_sp_pude_event_func(const struct mlxsw_reg_info *reg, char *pude_pl, void *priv) { @@ -4197,6 +4213,7 @@ } else { netdev_info(mlxsw_sp_port->dev, "link down\n"); netif_carrier_off(mlxsw_sp_port->dev); + mlxsw_sp_port_down_wipe_counters(mlxsw_sp_port); } } @@ -4398,8 +4415,8 @@ MLXSW_SP_RXL_MARK(ROUTER_ALERT_IPV6, TRAP_TO_CPU, ROUTER_EXP, false), MLXSW_SP_RXL_MARK(IPIP_DECAP_ERROR, TRAP_TO_CPU, ROUTER_EXP, false), MLXSW_SP_RXL_MARK(DECAP_ECN0, TRAP_TO_CPU, ROUTER_EXP, false), - MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, ROUTER_EXP, false), - MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, ROUTER_EXP, false), + MLXSW_SP_RXL_MARK(IPV4_VRRP, TRAP_TO_CPU, VRRP, false), + MLXSW_SP_RXL_MARK(IPV6_VRRP, TRAP_TO_CPU, VRRP, false), /* PKT Sample trap */ MLXSW_RXL(mlxsw_sp_rx_listener_sample_func, PKT_SAMPLE, MIRROR_TO_CPU, false, SP_IP2ME, DISCARD), @@ -4483,6 +4500,10 @@ rate = 19 * 1024; burst_size = 12; break; + case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: + rate = 360; + burst_size = 7; + break; default: continue; } @@ -4522,6 +4543,7 @@ case MLXSW_REG_HTGT_TRAP_GROUP_SP_OSPF: case MLXSW_REG_HTGT_TRAP_GROUP_SP_PIM: case MLXSW_REG_HTGT_TRAP_GROUP_SP_PTP0: + case MLXSW_REG_HTGT_TRAP_GROUP_SP_VRRP: priority = 5; tc = 5; break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c @@ -88,8 +88,8 @@ * to be written using PEFA register to all indexes for all regions. */ afa_block = mlxsw_afa_block_create(mlxsw_sp->afa); - if (!afa_block) { - err = -ENOMEM; + if (IS_ERR(afa_block)) { + err = PTR_ERR(afa_block); goto err_afa_block; } err = mlxsw_afa_block_continue(afa_block); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,7 @@ struct mlxsw_sp_fid *dummy_fid; struct rhashtable ruleset_ht; struct list_head rules; + struct mutex rules_lock; /* Protects rules list */ struct { struct delayed_work dw; unsigned long interval; /* ms */ @@ -442,7 +444,7 @@ rulei = kzalloc(sizeof(*rulei), GFP_KERNEL); if (!rulei) - return NULL; + return ERR_PTR(-ENOMEM); if (afa_block) { rulei->act_block = afa_block; @@ -701,7 +703,9 @@ goto err_ruleset_block_bind; } + mutex_lock(&mlxsw_sp->acl->rules_lock); list_add_tail(&rule->list, &mlxsw_sp->acl->rules); + mutex_unlock(&mlxsw_sp->acl->rules_lock); block->rule_count++; block->egress_blocker_rule_count += rule->rulei->egress_bind_blocker; return 0; @@ -723,7 +727,9 @@ block->egress_blocker_rule_count -= rule->rulei->egress_bind_blocker; ruleset->ht_key.block->rule_count--; + mutex_lock(&mlxsw_sp->acl->rules_lock); list_del(&rule->list); + mutex_unlock(&mlxsw_sp->acl->rules_lock); if (!ruleset->ht_key.chain_index && mlxsw_sp_acl_ruleset_is_singular(ruleset)) mlxsw_sp_acl_ruleset_block_unbind(mlxsw_sp, ruleset, @@ -783,19 +789,18 @@ struct mlxsw_sp_acl_rule *rule; int err; - /* Protect internal structures from changes */ - rtnl_lock(); + mutex_lock(&acl->rules_lock); list_for_each_entry(rule, &acl->rules, list) { err = mlxsw_sp_acl_rule_activity_update(acl->mlxsw_sp, rule); if (err) goto err_rule_update; } - rtnl_unlock(); + mutex_unlock(&acl->rules_lock); return 0; err_rule_update: - rtnl_unlock(); + mutex_unlock(&acl->rules_lock); return err; } @@ -880,6 +885,7 @@ acl->dummy_fid = fid; INIT_LIST_HEAD(&acl->rules); + mutex_init(&acl->rules_lock); err = mlxsw_sp_acl_tcam_init(mlxsw_sp, &acl->tcam); if (err) goto err_acl_ops_init; @@ -892,6 +898,7 @@ return 0; err_acl_ops_init: + mutex_destroy(&acl->rules_lock); mlxsw_sp_fid_put(fid); err_fid_get: rhashtable_destroy(&acl->ruleset_ht); @@ -908,6 +915,7 @@ cancel_delayed_work_sync(&mlxsw_sp->acl->rule_activity_update.dw); mlxsw_sp_acl_tcam_fini(mlxsw_sp, &acl->tcam); + mutex_destroy(&acl->rules_lock); WARN_ON(!list_empty(&acl->rules)); mlxsw_sp_fid_put(acl->dummy_fid); rhashtable_destroy(&acl->ruleset_ht); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -301,6 +301,7 @@ unsigned long *p_index) { unsigned int num_rows, entry_size; + unsigned long index; /* We only allow allocations of entire rows */ if (num_erps % erp_core->num_erp_banks != 0) @@ -309,10 +310,11 @@ entry_size = erp_core->erpt_entries_size[region_type]; num_rows = num_erps / erp_core->num_erp_banks; - *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); - if (*p_index == 0) + index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); + if (!index) return -ENOBUFS; - *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; + + *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; return 0; } @@ -1215,18 +1217,6 @@ return err ? false : true; } -static int mlxsw_sp_acl_erp_hints_obj_cmp(const void *obj1, const void *obj2) -{ - const struct mlxsw_sp_acl_erp_key *key1 = obj1; - const struct mlxsw_sp_acl_erp_key *key2 = obj2; - - /* For hints purposes, two objects are considered equal - * in case the masks are the same. Does not matter what - * the "ctcam" value is. - */ - return memcmp(key1->mask, key2->mask, sizeof(key1->mask)); -} - static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj, void *obj) { @@ -1306,7 +1296,6 @@ static const struct objagg_ops mlxsw_sp_acl_erp_objagg_ops = { .obj_size = sizeof(struct mlxsw_sp_acl_erp_key), .delta_check = mlxsw_sp_acl_erp_delta_check, - .hints_obj_cmp = mlxsw_sp_acl_erp_hints_obj_cmp, .delta_create = mlxsw_sp_acl_erp_delta_create, .delta_destroy = mlxsw_sp_acl_erp_delta_destroy, .root_create = mlxsw_sp_acl_erp_root_create, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -68,6 +68,8 @@ tcam->max_groups = max_groups; tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUP_SIZE); + tcam->max_group_size = min_t(unsigned int, tcam->max_group_size, + MLXSW_REG_PAGT_ACL_MAX_NUM); err = ops->init(mlxsw_sp, tcam->priv, tcam); if (err) @@ -290,13 +292,14 @@ int err; group->tcam = tcam; - mutex_init(&group->lock); INIT_LIST_HEAD(&group->region_list); err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id); if (err) return err; + mutex_init(&group->lock); + return 0; } @@ -755,7 +758,9 @@ rehash.dw.work); int credits = MLXSW_SP_ACL_TCAM_VREGION_REHASH_CREDITS; + mutex_lock(&vregion->lock); mlxsw_sp_acl_tcam_vregion_rehash(vregion->mlxsw_sp, vregion, &credits); + mutex_unlock(&vregion->lock); if (credits < 0) /* Rehash gone out of credits so it was interrupted. * Schedule the work as soon as possible to continue. @@ -766,6 +771,17 @@ } static void +mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(struct mlxsw_sp_acl_tcam_rehash_ctx *ctx) +{ + /* The entry markers are relative to the current chunk and therefore + * needs to be reset together with the chunk marker. + */ + ctx->current_vchunk = NULL; + ctx->start_ventry = NULL; + ctx->stop_ventry = NULL; +} + +static void mlxsw_sp_acl_tcam_rehash_ctx_vchunk_changed(struct mlxsw_sp_acl_tcam_vchunk *vchunk) { struct mlxsw_sp_acl_tcam_vregion *vregion = vchunk->vregion; @@ -787,7 +803,7 @@ * the current chunk pointer to make sure all chunks * are properly migrated. */ - vregion->rehash.ctx.current_vchunk = NULL; + mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(&vregion->rehash.ctx); } static struct mlxsw_sp_acl_tcam_vregion * @@ -860,10 +876,14 @@ struct mlxsw_sp_acl_tcam *tcam = vregion->tcam; if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) { + struct mlxsw_sp_acl_tcam_rehash_ctx *ctx = &vregion->rehash.ctx; + mutex_lock(&tcam->lock); list_del(&vregion->tlist); mutex_unlock(&tcam->lock); - cancel_delayed_work_sync(&vregion->rehash.dw); + if (cancel_delayed_work_sync(&vregion->rehash.dw) && + ctx->hints_priv) + ops->region_rehash_hints_put(ctx->hints_priv); } mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion); if (vregion->region2) @@ -986,8 +1006,9 @@ unsigned int priority, struct mlxsw_afk_element_usage *elusage) { + struct mlxsw_sp_acl_tcam_vchunk *vchunk, *vchunk2; struct mlxsw_sp_acl_tcam_vregion *vregion; - struct mlxsw_sp_acl_tcam_vchunk *vchunk; + struct list_head *pos; int err; if (priority == MLXSW_SP_ACL_TCAM_CATCHALL_PRIO) @@ -1025,7 +1046,14 @@ } mlxsw_sp_acl_tcam_rehash_ctx_vregion_changed(vregion); - list_add_tail(&vchunk->list, &vregion->vchunk_list); + + /* Position the vchunk inside the list according to priority */ + list_for_each(pos, &vregion->vchunk_list) { + vchunk2 = list_entry(pos, typeof(*vchunk2), list); + if (vchunk2->priority > priority) + break; + } + list_add_tail(&vchunk->list, pos); mutex_unlock(&vregion->lock); return vchunk; @@ -1219,8 +1247,14 @@ struct mlxsw_sp_acl_tcam_ventry *ventry, bool *activity) { - return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, - ventry->entry, activity); + struct mlxsw_sp_acl_tcam_vregion *vregion = ventry->vchunk->vregion; + int err; + + mutex_lock(&vregion->lock); + err = mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, ventry->entry, + activity); + mutex_unlock(&vregion->lock); + return err; } static int @@ -1254,6 +1288,8 @@ { struct mlxsw_sp_acl_tcam_chunk *new_chunk; + WARN_ON(vchunk->chunk2); + new_chunk = mlxsw_sp_acl_tcam_chunk_create(mlxsw_sp, vchunk, region); if (IS_ERR(new_chunk)) return PTR_ERR(new_chunk); @@ -1272,7 +1308,7 @@ { mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk2); vchunk->chunk2 = NULL; - ctx->current_vchunk = NULL; + mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx); } static int @@ -1295,6 +1331,9 @@ return 0; } + if (list_empty(&vchunk->ventry_list)) + goto out; + /* If the migration got interrupted, we have the ventry to start from * stored in context. */ @@ -1304,6 +1343,8 @@ ventry = list_first_entry(&vchunk->ventry_list, typeof(*ventry), list); + WARN_ON(ventry->vchunk != vchunk); + list_for_each_entry_from(ventry, &vchunk->ventry_list, list) { /* During rollback, once we reach the ventry that failed * to migrate, we are done. @@ -1344,6 +1385,7 @@ } } +out: mlxsw_sp_acl_tcam_vchunk_migrate_end(mlxsw_sp, vchunk, ctx); return 0; } @@ -1357,6 +1399,9 @@ struct mlxsw_sp_acl_tcam_vchunk *vchunk; int err; + if (list_empty(&vregion->vchunk_list)) + return 0; + /* If the migration got interrupted, we have the vchunk * we are working on stored in context. */ @@ -1385,16 +1430,17 @@ int err, err2; trace_mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion); - mutex_lock(&vregion->lock); err = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion, ctx, credits); if (err) { + if (ctx->this_is_rollback) + return err; /* In case migration was not successful, we need to swap * so the original region pointer is assigned again * to vregion->region. */ swap(vregion->region, vregion->region2); - ctx->current_vchunk = NULL; + mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx); ctx->this_is_rollback = true; err2 = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion, ctx, credits); @@ -1405,7 +1451,6 @@ /* Let the rollback to be continued later on. */ } } - mutex_unlock(&vregion->lock); trace_mlxsw_sp_acl_tcam_vregion_migrate_end(mlxsw_sp, vregion); return err; } @@ -1454,6 +1499,7 @@ ctx->hints_priv = hints_priv; ctx->this_is_rollback = false; + mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx); return 0; @@ -1506,7 +1552,8 @@ err = mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion, ctx, credits); if (err) { - dev_err(mlxsw_sp->bus_info->dev, "Failed to migrate vregion\n"); + dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to migrate vregion\n"); + return; } if (*credits >= 0) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h @@ -7,8 +7,8 @@ #include "spectrum.h" enum mlxsw_sp_counter_sub_pool_id { - MLXSW_SP_COUNTER_SUB_POOL_FLOW, MLXSW_SP_COUNTER_SUB_POOL_RIF, + MLXSW_SP_COUNTER_SUB_POOL_FLOW, }; int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c @@ -227,8 +227,6 @@ static int mlxsw_sp_dcbnl_app_validate(struct net_device *dev, struct dcb_app *app) { - int prio; - if (app->priority >= IEEE_8021QAZ_MAX_TCS) { netdev_err(dev, "APP entry with priority value %u is invalid\n", app->priority); @@ -242,17 +240,6 @@ app->protocol); return -EINVAL; } - - /* Warn about any DSCP APP entries with the same PID. */ - prio = fls(dcb_ieee_getapp_mask(dev, app)); - if (prio--) { - if (prio < app->priority) - netdev_warn(dev, "Choosing priority %d for DSCP %d in favor of previously-active value of %d\n", - app->priority, app->protocol, prio); - else if (prio > app->priority) - netdev_warn(dev, "Ignoring new priority %d for DSCP %d in favor of current value of %d\n", - app->priority, app->protocol, prio); - } break; case IEEE_8021QAZ_APP_SEL_ETHERTYPE: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c @@ -215,7 +215,7 @@ start_again: err = devlink_dpipe_entry_ctx_prepare(dump_ctx); if (err) - return err; + goto err_ctx_prepare; j = 0; for (; i < rif_count; i++) { struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i); @@ -247,6 +247,7 @@ return 0; err_entry_append: err_entry_get: +err_ctx_prepare: rtnl_unlock(); devlink_dpipe_entry_clear(&entry); return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -123,9 +123,12 @@ u8 prio = act->vlan.prio; u16 vid = act->vlan.vid; - return mlxsw_sp_acl_rulei_act_vlan(mlxsw_sp, rulei, - act->id, vid, - proto, prio, extack); + err = mlxsw_sp_acl_rulei_act_vlan(mlxsw_sp, rulei, + act->id, vid, + proto, prio, extack); + if (err) + return err; + break; } default: NL_SET_ERR_MSG_MOD(extack, "Unsupported action"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -524,6 +524,16 @@ u16 erif_index = 0; int err; + /* Add the eRIF */ + if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { + erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); + err = mr->mr_ops->route_erif_add(mlxsw_sp, + rve->mr_route->route_priv, + erif_index); + if (err) + return err; + } + /* Update the route action, as the new eVIF can be a tunnel or a pimreg * device which will require updating the action. */ @@ -533,17 +543,7 @@ rve->mr_route->route_priv, route_action); if (err) - return err; - } - - /* Add the eRIF */ - if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) { - erif_index = mlxsw_sp_rif_index(rve->mr_vif->rif); - err = mr->mr_ops->route_erif_add(mlxsw_sp, - rve->mr_route->route_priv, - erif_index); - if (err) - goto err_route_erif_add; + goto err_route_action_update; } /* Update the minimum MTU */ @@ -561,14 +561,14 @@ return 0; err_route_min_mtu_update: - if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) - mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, - erif_index); -err_route_erif_add: if (route_action != rve->mr_route->route_action) mr->mr_ops->route_action_update(mlxsw_sp, rve->mr_route->route_priv, rve->mr_route->route_action); +err_route_action_update: + if (mlxsw_sp_mr_vif_valid(rve->mr_vif)) + mr->mr_ops->route_erif_del(mlxsw_sp, rve->mr_route->route_priv, + erif_index); return err; } @@ -637,12 +637,12 @@ return 0; err_erif_unresolve: - list_for_each_entry_from_reverse(erve, &mr_vif->route_evif_list, - vif_node) + list_for_each_entry_continue_reverse(erve, &mr_vif->route_evif_list, + vif_node) mlxsw_sp_mr_route_evif_unresolve(mr_table, erve); err_irif_unresolve: - list_for_each_entry_from_reverse(irve, &mr_vif->route_ivif_list, - vif_node) + list_for_each_entry_continue_reverse(irve, &mr_vif->route_ivif_list, + vif_node) mlxsw_sp_mr_route_ivif_unresolve(mr_table, irve); mr_vif->rif = NULL; return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c @@ -199,8 +199,8 @@ int err; afa_block = mlxsw_afa_block_create(mlxsw_sp->afa); - if (!afa_block) - return ERR_PTR(-ENOMEM); + if (IS_ERR(afa_block)) + return afa_block; err = mlxsw_afa_block_append_allocated_counter(afa_block, counter_index); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c @@ -294,8 +294,8 @@ .fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload, }; -static bool mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp, - bool learning_en) +static int mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp, + bool learning_en) { char tnpc_pl[MLXSW_REG_TNPC_LEN]; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c @@ -195,6 +195,20 @@ return -EOPNOTSUPP; } +static u64 +mlxsw_sp_xstats_backlog(struct mlxsw_sp_port_xstats *xstats, int tclass_num) +{ + return xstats->backlog[tclass_num] + + xstats->backlog[tclass_num + 8]; +} + +static u64 +mlxsw_sp_xstats_tail_drop(struct mlxsw_sp_port_xstats *xstats, int tclass_num) +{ + return xstats->tail_drop[tclass_num] + + xstats->tail_drop[tclass_num + 8]; +} + static void mlxsw_sp_qdisc_bstats_per_priority_get(struct mlxsw_sp_port_xstats *xstats, u8 prio_bitmap, u64 *tx_packets, @@ -269,7 +283,7 @@ &stats_base->tx_bytes); red_base->prob_mark = xstats->ecn; red_base->prob_drop = xstats->wred_drop[tclass_num]; - red_base->pdrop = xstats->tail_drop[tclass_num]; + red_base->pdrop = mlxsw_sp_xstats_tail_drop(xstats, tclass_num); stats_base->overlimits = red_base->prob_drop + red_base->prob_mark; stats_base->drops = red_base->prob_drop + red_base->pdrop; @@ -369,7 +383,8 @@ early_drops = xstats->wred_drop[tclass_num] - xstats_base->prob_drop; marks = xstats->ecn - xstats_base->prob_mark; - pdrops = xstats->tail_drop[tclass_num] - xstats_base->pdrop; + pdrops = mlxsw_sp_xstats_tail_drop(xstats, tclass_num) - + xstats_base->pdrop; res->pdrop += pdrops; res->prob_drop += early_drops; @@ -402,9 +417,10 @@ overlimits = xstats->wred_drop[tclass_num] + xstats->ecn - stats_base->overlimits; - drops = xstats->wred_drop[tclass_num] + xstats->tail_drop[tclass_num] - + drops = xstats->wred_drop[tclass_num] + + mlxsw_sp_xstats_tail_drop(xstats, tclass_num) - stats_base->drops; - backlog = xstats->backlog[tclass_num]; + backlog = mlxsw_sp_xstats_backlog(xstats, tclass_num); _bstats_update(stats_ptr->bstats, tx_bytes, tx_packets); stats_ptr->qstats->overlimits += overlimits; @@ -575,9 +591,9 @@ tx_packets = stats->tx_packets - stats_base->tx_packets; for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { - drops += xstats->tail_drop[i]; + drops += mlxsw_sp_xstats_tail_drop(xstats, i); drops += xstats->wred_drop[i]; - backlog += xstats->backlog[i]; + backlog += mlxsw_sp_xstats_backlog(xstats, i); } drops = drops - stats_base->drops; @@ -613,7 +629,7 @@ stats_base->drops = 0; for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { - stats_base->drops += xstats->tail_drop[i]; + stats_base->drops += mlxsw_sp_xstats_tail_drop(xstats, i); stats_base->drops += xstats->wred_drop[i]; } @@ -650,6 +666,13 @@ mlxsw_sp_port->tclass_qdiscs[tclass_num].handle == p->child_handle) return 0; + if (!p->child_handle) { + /* This is an invisible FIFO replacing the original Qdisc. + * Ignore it--the original Qdisc's destroy will follow. + */ + return 0; + } + /* See if the grafted qdisc is already offloaded on any tclass. If so, * unoffload it. */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -3871,7 +3871,7 @@ { const struct fib_nh *nh = fib_info_nh(fi, 0); - return nh->fib_nh_scope == RT_SCOPE_LINK || + return nh->fib_nh_gw_family || mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, nh, NULL); } @@ -5637,8 +5637,13 @@ if (mlxsw_sp_fib6_rt_should_ignore(rt)) return; + /* Multipath routes are first added to the FIB trie and only then + * notified. If we vetoed the addition, we will get a delete + * notification for a route we do not have. Therefore, do not warn if + * route was not found. + */ fib6_entry = mlxsw_sp_fib6_entry_lookup(mlxsw_sp, rt); - if (WARN_ON(!fib6_entry)) + if (!fib6_entry) return; /* If not all the nexthops are deleted, then only reduce the nexthop @@ -6282,7 +6287,7 @@ } fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); - if (WARN_ON(!fib_work)) + if (!fib_work) return NOTIFY_BAD; fib_work->mlxsw_sp = router->mlxsw_sp; @@ -6980,6 +6985,9 @@ for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) { rif = mlxsw_sp->router->rifs[i]; + if (rif && rif->ops && + rif->ops->type == MLXSW_SP_RIF_TYPE_IPIP_LB) + continue; if (rif && rif->dev && rif->dev != dev && !ether_addr_equal_masked(rif->dev->dev_addr, dev_addr, mlxsw_sp->mac_mask)) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mellanox/mlxsw/switchx2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mellanox/mlxsw/switchx2.c @@ -299,22 +299,17 @@ u64 len; int err; + if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { + this_cpu_inc(mlxsw_sx_port->pcpu_stats->tx_dropped); + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + memset(skb->cb, 0, sizeof(struct mlxsw_skb_cb)); if (mlxsw_core_skb_transmit_busy(mlxsw_sx->core, &tx_info)) return NETDEV_TX_BUSY; - if (unlikely(skb_headroom(skb) < MLXSW_TXHDR_LEN)) { - struct sk_buff *skb_orig = skb; - - skb = skb_realloc_headroom(skb, MLXSW_TXHDR_LEN); - if (!skb) { - this_cpu_inc(mlxsw_sx_port->pcpu_stats->tx_dropped); - dev_kfree_skb_any(skb_orig); - return NETDEV_TX_OK; - } - dev_consume_skb_any(skb_orig); - } mlxsw_sx_txhdr_construct(skb, &tx_info); /* TX header is consumed by HW on the way so we shouldn't count its * bytes as being sent. @@ -1263,6 +1258,7 @@ if (mlxsw_sx_port_created(mlxsw_sx, i)) mlxsw_sx_port_remove(mlxsw_sx, i); kfree(mlxsw_sx->ports); + mlxsw_sx->ports = NULL; } static int mlxsw_sx_ports_create(struct mlxsw_sx *mlxsw_sx) @@ -1297,6 +1293,7 @@ if (mlxsw_sx_port_created(mlxsw_sx, i)) mlxsw_sx_port_remove(mlxsw_sx, i); kfree(mlxsw_sx->ports); + mlxsw_sx->ports = NULL; return err; } @@ -1380,6 +1377,12 @@ u8 module, width; int err; + if (!mlxsw_sx->ports || !mlxsw_sx->ports[local_port]) { + dev_err(mlxsw_sx->bus_info->dev, "Port number \"%d\" does not exist\n", + local_port); + return -EINVAL; + } + if (new_type == DEVLINK_PORT_TYPE_AUTO) return -EOPNOTSUPP; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/micrel/ks8842.c +++ linux-oracle-5.4.0/drivers/net/ethernet/micrel/ks8842.c @@ -1136,6 +1136,10 @@ unsigned i; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) goto err_mem_region; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/micrel/ks8851_mll.c +++ linux-oracle-5.4.0/drivers/net/ethernet/micrel/ks8851_mll.c @@ -157,21 +157,47 @@ */ /** - * ks_rdreg8 - read 8 bit register from device + * ks_check_endian - Check whether endianness of the bus is correct * @ks : The chip information - * @offset: The register address * - * Read a 8bit register from the chip, returning the result + * The KS8851-16MLL EESK pin allows selecting the endianness of the 16bit + * bus. To maintain optimum performance, the bus endianness should be set + * such that it matches the endianness of the CPU. */ -static u8 ks_rdreg8(struct ks_net *ks, int offset) + +static int ks_check_endian(struct ks_net *ks) { - u16 data; - u8 shift_bit = offset & 0x03; - u8 shift_data = (offset & 1) << 3; - ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit); - iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); - data = ioread16(ks->hw_addr); - return (u8)(data >> shift_data); + u16 cider; + + /* + * Read CIDER register first, however read it the "wrong" way around. + * If the endian strap on the KS8851-16MLL in incorrect and the chip + * is operating in different endianness than the CPU, then the meaning + * of BE[3:0] byte-enable bits is also swapped such that: + * BE[3,2,1,0] becomes BE[1,0,3,2] + * + * Luckily for us, the byte-enable bits are the top four MSbits of + * the address register and the CIDER register is at offset 0xc0. + * Hence, by reading address 0xc0c0, which is not impacted by endian + * swapping, we assert either BE[3:2] or BE[1:0] while reading the + * CIDER register. + * + * If the bus configuration is correct, reading 0xc0c0 asserts + * BE[3:2] and this read returns 0x0000, because to read register + * with bottom two LSbits of address set to 0, BE[1:0] must be + * asserted. + * + * If the bus configuration is NOT correct, reading 0xc0c0 asserts + * BE[1:0] and this read returns non-zero 0x8872 value. + */ + iowrite16(BE3 | BE2 | KS_CIDER, ks->hw_addr_cmd); + cider = ioread16(ks->hw_addr); + if (!cider) + return 0; + + netdev_err(ks->netdev, "incorrect EESK endian strap setting\n"); + + return -EINVAL; } /** @@ -190,22 +216,6 @@ } /** - * ks_wrreg8 - write 8bit register value to chip - * @ks: The chip information - * @offset: The register address - * @value: The value to write - * - */ -static void ks_wrreg8(struct ks_net *ks, int offset, u8 value) -{ - u8 shift_bit = (offset & 0x03); - u16 value_write = (u16)(value << ((offset & 1) << 3)); - ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit); - iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd); - iowrite16(value_write, ks->hw_addr); -} - -/** * ks_wrreg16 - write 16bit register value to chip * @ks: The chip information * @offset: The register address @@ -324,8 +334,7 @@ u16 reg_data = 0; /* Regardless of bus width, 8 bit read should always work.*/ - reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF; - reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8; + reg_data = ks_rdreg16(ks, KS_CCR); /* addr/data bus are multiplexed */ ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED; @@ -429,7 +438,7 @@ /* 1. set sudo DMA mode */ ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI); - ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); + ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); /* 2. read prepend data */ /** @@ -446,7 +455,7 @@ ks_inblk(ks, buf, ALIGN(len, 4)); /* 4. reset sudo DMA Mode */ - ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); + ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); } /** @@ -548,14 +557,17 @@ { struct net_device *netdev = pw; struct ks_net *ks = netdev_priv(netdev); + unsigned long flags; u16 status; + spin_lock_irqsave(&ks->statelock, flags); /*this should be the first in IRQ handler */ ks_save_cmd_reg(ks); status = ks_rdreg16(ks, KS_ISR); if (unlikely(!status)) { ks_restore_cmd_reg(ks); + spin_unlock_irqrestore(&ks->statelock, flags); return IRQ_NONE; } @@ -581,6 +593,7 @@ ks->netdev->stats.rx_over_errors++; /* this should be the last in IRQ handler*/ ks_restore_cmd_reg(ks); + spin_unlock_irqrestore(&ks->statelock, flags); return IRQ_HANDLED; } @@ -650,6 +663,7 @@ /* shutdown RX/TX QMU */ ks_disable_qmu(ks); + ks_disable_int(ks); /* set powermode to soft power down to save power */ ks_set_powermode(ks, PMECR_PM_SOFTDOWN); @@ -679,13 +693,13 @@ ks->txh.txw[1] = cpu_to_le16(len); /* 1. set sudo-DMA mode */ - ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff); + ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); /* 2. write status/lenth info */ ks_outblk(ks, ks->txh.txw, 4); /* 3. write pkt data */ ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4)); /* 4. reset sudo-DMA mode */ - ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr); + ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */ ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE); /* 6. wait until TXQCR_METFE is auto-cleared */ @@ -706,10 +720,9 @@ { netdev_tx_t retv = NETDEV_TX_OK; struct ks_net *ks = netdev_priv(netdev); + unsigned long flags; - disable_irq(netdev->irq); - ks_disable_int(ks); - spin_lock(&ks->statelock); + spin_lock_irqsave(&ks->statelock, flags); /* Extra space are required: * 4 byte for alignment, 4 for status/length, 4 for CRC @@ -723,9 +736,7 @@ dev_kfree_skb(skb); } else retv = NETDEV_TX_BUSY; - spin_unlock(&ks->statelock); - ks_enable_int(ks); - enable_irq(netdev->irq); + spin_unlock_irqrestore(&ks->statelock, flags); return retv; } @@ -1251,6 +1262,10 @@ goto err_free; } + err = ks_check_endian(ks); + if (err) + goto err_free; + netdev->irq = platform_get_irq(pdev, 0); if ((int)netdev->irq < 0) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/micrel/ksz884x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/micrel/ksz884x.c @@ -1649,8 +1649,7 @@ #define HW_DELAY(hw, reg) \ do { \ - u16 dummy; \ - dummy = readw(hw->io + reg); \ + readw(hw->io + reg); \ } while (0) /** @@ -5694,7 +5693,7 @@ * from the bridge. */ if ((hw->features & STP_SUPPORT) && !promiscuous && - (dev->priv_flags & IFF_BRIDGE_PORT)) { + netif_is_bridge_port(dev)) { struct ksz_switch *sw = hw->ksz_switch; int port = priv->port.first_port; @@ -6929,7 +6928,7 @@ char banner[sizeof(version)]; struct ksz_switch *sw = NULL; - result = pci_enable_device(pdev); + result = pcim_enable_device(pdev); if (result) return result; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/encx24j600-regmap.c +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/encx24j600-regmap.c @@ -364,7 +364,7 @@ goto err_out; usleep_range(26, 100); - while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) && + while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) && (mistat & BUSY)) cpu_relax(); @@ -402,7 +402,7 @@ goto err_out; usleep_range(26, 100); - while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) && + while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) && (mistat & BUSY)) cpu_relax(); @@ -502,13 +502,19 @@ .reg_read = regmap_encx24j600_phy_reg_read, }; -void devm_regmap_init_encx24j600(struct device *dev, - struct encx24j600_context *ctx) +int devm_regmap_init_encx24j600(struct device *dev, + struct encx24j600_context *ctx) { mutex_init(&ctx->mutex); regcfg.lock_arg = ctx; ctx->regmap = devm_regmap_init(dev, ®map_encx24j600, ctx, ®cfg); + if (IS_ERR(ctx->regmap)) + return PTR_ERR(ctx->regmap); ctx->phymap = devm_regmap_init(dev, &phymap_encx24j600, ctx, &phycfg); + if (IS_ERR(ctx->phymap)) + return PTR_ERR(ctx->phymap); + + return 0; } EXPORT_SYMBOL_GPL(devm_regmap_init_encx24j600); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/encx24j600.c +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/encx24j600.c @@ -1027,10 +1027,13 @@ priv->speed = SPEED_100; priv->ctx.spi = spi; - devm_regmap_init_encx24j600(&spi->dev, &priv->ctx); ndev->irq = spi->irq; ndev->netdev_ops = &encx24j600_netdev_ops; + ret = devm_regmap_init_encx24j600(&spi->dev, &priv->ctx); + if (ret) + goto out_free; + mutex_init(&priv->lock); /* Reset device and check if it is connected */ @@ -1070,7 +1073,7 @@ if (unlikely(ret)) { netif_err(priv, probe, ndev, "Error %d initializing card encx24j600 card\n", ret); - goto out_free; + goto out_stop; } eidled = encx24j600_read_reg(priv, EIDLED); @@ -1088,6 +1091,8 @@ out_unregister: unregister_netdev(priv->ndev); +out_stop: + kthread_stop(priv->kworker_task); out_free: free_netdev(ndev); @@ -1100,6 +1105,7 @@ struct encx24j600_priv *priv = dev_get_drvdata(&spi->dev); unregister_netdev(priv->ndev); + kthread_stop(priv->kworker_task); free_netdev(priv->ndev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/encx24j600_hw.h +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/encx24j600_hw.h @@ -15,8 +15,8 @@ int bank; }; -void devm_regmap_init_encx24j600(struct device *dev, - struct encx24j600_context *ctx); +int devm_regmap_init_encx24j600(struct device *dev, + struct encx24j600_context *ctx); /* Single-byte instructions */ #define BANK_SELECT(bank) (0xC0 | ((bank & (BANK_MASK >> BANK_SHIFT)) << 1)) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/lan743x_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/lan743x_ethtool.c @@ -780,7 +780,9 @@ wol->supported = 0; wol->wolopts = 0; - phy_ethtool_get_wol(netdev->phydev, wol); + + if (netdev->phydev) + phy_ethtool_get_wol(netdev->phydev, wol); wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | WAKE_MAGIC | WAKE_PHY | WAKE_ARP; @@ -809,9 +811,8 @@ device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts); - phy_ethtool_set_wol(netdev->phydev, wol); - - return 0; + return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol) + : -ENETDOWN; } #endif /* CONFIG_PM */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/lan743x_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/lan743x_main.c @@ -80,6 +80,18 @@ !(data & HW_CFG_LRST_), 100000, 10000000); } +static int lan743x_csr_wait_for_bit_atomic(struct lan743x_adapter *adapter, + int offset, u32 bit_mask, + int target_value, int udelay_min, + int udelay_max, int count) +{ + u32 data; + + return readx_poll_timeout_atomic(LAN743X_CSR_READ_OP, offset, data, + target_value == !!(data & bit_mask), + udelay_max, udelay_min * count); +} + static int lan743x_csr_wait_for_bit(struct lan743x_adapter *adapter, int offset, u32 bit_mask, int target_value, int usleep_min, @@ -145,7 +157,8 @@ int_sts = lan743x_csr_read(adapter, INT_STS); if (int_sts & INT_BIT_SW_GP_) { - lan743x_csr_write(adapter, INT_STS, INT_BIT_SW_GP_); + /* disable the interrupt to prevent repeated re-triggering */ + lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_SW_GP_); intr->software_isr_flag = 1; } } @@ -155,9 +168,8 @@ struct lan743x_tx *tx = context; struct lan743x_adapter *adapter = tx->adapter; bool enable_flag = true; - u32 int_en = 0; - int_en = lan743x_csr_read(adapter, INT_EN_SET); + lan743x_csr_read(adapter, INT_EN_SET); if (flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CLEAR) { lan743x_csr_write(adapter, INT_EN_CLR, INT_BIT_DMA_TX_(tx->channel_number)); @@ -672,14 +684,12 @@ static int lan743x_dp_write(struct lan743x_adapter *adapter, u32 select, u32 addr, u32 length, u32 *buf) { - int ret = -EIO; u32 dp_sel; int i; - mutex_lock(&adapter->dp_lock); - if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, - 1, 40, 100, 100)) - goto unlock; + if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, DP_SEL_DPRDY_, + 1, 40, 100, 100)) + return -EIO; dp_sel = lan743x_csr_read(adapter, DP_SEL); dp_sel &= ~DP_SEL_MASK_; dp_sel |= select; @@ -689,15 +699,13 @@ lan743x_csr_write(adapter, DP_ADDR, addr + i); lan743x_csr_write(adapter, DP_DATA_0, buf[i]); lan743x_csr_write(adapter, DP_CMD, DP_CMD_WRITE_); - if (lan743x_csr_wait_for_bit(adapter, DP_SEL, DP_SEL_DPRDY_, - 1, 40, 100, 100)) - goto unlock; + if (lan743x_csr_wait_for_bit_atomic(adapter, DP_SEL, + DP_SEL_DPRDY_, + 1, 40, 100, 100)) + return -EIO; } - ret = 0; -unlock: - mutex_unlock(&adapter->dp_lock); - return ret; + return 0; } static u32 lan743x_mac_mii_access(u16 id, u16 index, int read) @@ -921,8 +929,7 @@ } static void lan743x_phy_update_flowcontrol(struct lan743x_adapter *adapter, - u8 duplex, u16 local_adv, - u16 remote_adv) + u16 local_adv, u16 remote_adv) { struct lan743x_phy *phy = &adapter->phy; u8 cap; @@ -949,22 +956,17 @@ phy_print_status(phydev); if (phydev->state == PHY_RUNNING) { - struct ethtool_link_ksettings ksettings; int remote_advertisement = 0; int local_advertisement = 0; - memset(&ksettings, 0, sizeof(ksettings)); - phy_ethtool_get_link_ksettings(netdev, &ksettings); local_advertisement = linkmode_adv_to_mii_adv_t(phydev->advertising); remote_advertisement = linkmode_adv_to_mii_adv_t(phydev->lp_advertising); - lan743x_phy_update_flowcontrol(adapter, - ksettings.base.duplex, - local_advertisement, + lan743x_phy_update_flowcontrol(adapter, local_advertisement, remote_advertisement); - lan743x_ptp_update_latency(adapter, ksettings.base.speed); + lan743x_ptp_update_latency(adapter, phydev->speed); } } @@ -1247,13 +1249,13 @@ goto clear_active; if (!(buffer_info->flags & TX_BUFFER_INFO_FLAG_TIMESTAMP_REQUESTED)) { - dev_kfree_skb(buffer_info->skb); + dev_kfree_skb_any(buffer_info->skb); goto clear_skb; } if (cleanup) { lan743x_ptp_unrequest_tx_timestamp(tx->adapter); - dev_kfree_skb(buffer_info->skb); + dev_kfree_skb_any(buffer_info->skb); } else { ignore_sync = (buffer_info->flags & TX_BUFFER_INFO_FLAG_IGNORE_SYNC) != 0; @@ -1563,7 +1565,7 @@ if (required_number_of_descriptors > lan743x_tx_get_avail_desc(tx)) { if (required_number_of_descriptors > (tx->ring_size - 1)) { - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); } else { /* save to overflow buffer */ tx->overflow_skb = skb; @@ -1596,7 +1598,7 @@ start_frame_length, do_timestamp, skb->ip_summed == CHECKSUM_PARTIAL)) { - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); goto unlock; } @@ -1615,7 +1617,7 @@ * frame assembler clean up was performed inside * lan743x_tx_frame_add_fragment */ - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); goto unlock; } } @@ -1635,10 +1637,9 @@ bool start_transmitter = false; unsigned long irq_flags = 0; u32 ioc_bit = 0; - u32 int_sts = 0; ioc_bit = DMAC_INT_BIT_TX_IOC_(tx->channel_number); - int_sts = lan743x_csr_read(adapter, DMAC_INT_STS); + lan743x_csr_read(adapter, DMAC_INT_STS); if (tx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C) lan743x_csr_write(adapter, DMAC_INT_STS, ioc_bit); spin_lock_irqsave(&tx->ring_lock, irq_flags); @@ -1712,6 +1713,16 @@ ret = -EINVAL; goto cleanup; } + if (dma_set_mask_and_coherent(&tx->adapter->pdev->dev, + DMA_BIT_MASK(64))) { + if (dma_set_mask_and_coherent(&tx->adapter->pdev->dev, + DMA_BIT_MASK(32))) { + dev_warn(&tx->adapter->pdev->dev, + "lan743x_: No suitable DMA available\n"); + ret = -ENOMEM; + goto cleanup; + } + } ring_allocation_size = ALIGN(tx->ring_size * sizeof(struct lan743x_tx_descriptor), PAGE_SIZE); @@ -1894,13 +1905,21 @@ return ((++index) % rx->ring_size); } -static struct sk_buff *lan743x_rx_allocate_skb(struct lan743x_rx *rx) +static struct sk_buff *lan743x_rx_allocate_skb(struct lan743x_rx *rx, gfp_t gfp) { int length = 0; length = (LAN743X_MAX_FRAME_SIZE + ETH_HLEN + 4 + RX_HEAD_PADDING); return __netdev_alloc_skb(rx->adapter->netdev, - length, GFP_ATOMIC | GFP_DMA); + length, gfp); +} + +static void lan743x_rx_update_tail(struct lan743x_rx *rx, int index) +{ + /* update the tail once per 8 descriptors */ + if ((index & 7) == 7) + lan743x_csr_write(rx->adapter, RX_TAIL(rx->channel_number), + index); } static int lan743x_rx_init_ring_element(struct lan743x_rx *rx, int index, @@ -1933,6 +1952,7 @@ descriptor->data0 = (RX_DESC_DATA0_OWN_ | (length & RX_DESC_DATA0_BUF_LENGTH_MASK_)); skb_reserve(buffer_info->skb, RX_HEAD_PADDING); + lan743x_rx_update_tail(rx, index); return 0; } @@ -1951,6 +1971,7 @@ descriptor->data0 = (RX_DESC_DATA0_OWN_ | ((buffer_info->buffer_length) & RX_DESC_DATA0_BUF_LENGTH_MASK_)); + lan743x_rx_update_tail(rx, index); } static void lan743x_rx_release_ring_element(struct lan743x_rx *rx, int index) @@ -2063,7 +2084,8 @@ struct sk_buff *new_skb = NULL; int packet_length; - new_skb = lan743x_rx_allocate_skb(rx); + new_skb = lan743x_rx_allocate_skb(rx, + GFP_ATOMIC | GFP_DMA); if (!new_skb) { /* failed to allocate next skb. * Memory is very low. @@ -2162,6 +2184,7 @@ { struct lan743x_rx *rx = container_of(napi, struct lan743x_rx, napi); struct lan743x_adapter *adapter = rx->adapter; + int result = RX_PROCESS_RESULT_NOTHING_TO_DO; u32 rx_tail_flags = 0; int count; @@ -2170,27 +2193,19 @@ lan743x_csr_write(adapter, DMAC_INT_STS, DMAC_INT_BIT_RXFRM_(rx->channel_number)); } - count = 0; - while (count < weight) { - int rx_process_result = lan743x_rx_process_packet(rx); - - if (rx_process_result == RX_PROCESS_RESULT_PACKET_RECEIVED) { - count++; - } else if (rx_process_result == - RX_PROCESS_RESULT_NOTHING_TO_DO) { + for (count = 0; count < weight; count++) { + result = lan743x_rx_process_packet(rx); + if (result == RX_PROCESS_RESULT_NOTHING_TO_DO) break; - } else if (rx_process_result == - RX_PROCESS_RESULT_PACKET_DROPPED) { - continue; - } } rx->frame_count += count; - if (count == weight) - goto done; + if (count == weight || result == RX_PROCESS_RESULT_PACKET_RECEIVED) + return weight; if (!napi_complete_done(napi, count)) - goto done; + return count; + /* re-arm interrupts, must write to rx tail on some chip variants */ if (rx->vector_flags & LAN743X_VECTOR_FLAG_VECTOR_ENABLE_AUTO_SET) rx_tail_flags |= RX_TAIL_SET_TOP_INT_VEC_EN_; if (rx->vector_flags & LAN743X_VECTOR_FLAG_SOURCE_ENABLE_AUTO_SET) { @@ -2200,10 +2215,10 @@ INT_BIT_DMA_RX_(rx->channel_number)); } - /* update RX_TAIL */ - lan743x_csr_write(adapter, RX_TAIL(rx->channel_number), - rx_tail_flags | rx->last_tail); -done: + if (rx_tail_flags) + lan743x_csr_write(adapter, RX_TAIL(rx->channel_number), + rx_tail_flags | rx->last_tail); + return count; } @@ -2259,6 +2274,16 @@ ret = -EINVAL; goto cleanup; } + if (dma_set_mask_and_coherent(&rx->adapter->pdev->dev, + DMA_BIT_MASK(64))) { + if (dma_set_mask_and_coherent(&rx->adapter->pdev->dev, + DMA_BIT_MASK(32))) { + dev_warn(&rx->adapter->pdev->dev, + "lan743x_: No suitable DMA available\n"); + ret = -ENOMEM; + goto cleanup; + } + } ring_allocation_size = ALIGN(rx->ring_size * sizeof(struct lan743x_rx_descriptor), PAGE_SIZE); @@ -2297,7 +2322,8 @@ rx->last_head = 0; for (index = 0; index < rx->ring_size; index++) { - struct sk_buff *new_skb = lan743x_rx_allocate_skb(rx); + struct sk_buff *new_skb = lan743x_rx_allocate_skb(rx, + GFP_KERNEL); ret = lan743x_rx_init_ring_element(rx, index, new_skb); if (ret) @@ -2348,7 +2374,7 @@ netif_napi_add(adapter->netdev, &rx->napi, lan743x_rx_napi_poll, - rx->ring_size - 1); + NAPI_POLL_WEIGHT); lan743x_csr_write(adapter, DMAC_CMD, DMAC_CMD_RX_SWR_(rx->channel_number)); @@ -2674,7 +2700,6 @@ adapter->intr.irq = adapter->pdev->irq; lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF); - mutex_init(&adapter->dp_lock); ret = lan743x_gpio_init(adapter); if (ret) @@ -3005,6 +3030,8 @@ if (ret) { netif_err(adapter, probe, adapter->netdev, "lan743x_hardware_init returned %d\n", ret); + lan743x_pci_cleanup(adapter); + return ret; } /* open netdev when netdev is at running state while resume. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/microchip/lan743x_main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/microchip/lan743x_main.h @@ -706,9 +706,6 @@ struct lan743x_csr csr; struct lan743x_intr intr; - /* lock, used to prevent concurrent access to data port */ - struct mutex dp_lock; - struct lan743x_gpio gpio; struct lan743x_ptp ptp; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/moxa/moxart_ether.c +++ linux-oracle-5.4.0/drivers/net/ethernet/moxa/moxart_ether.c @@ -74,11 +74,6 @@ static void moxart_mac_free_memory(struct net_device *ndev) { struct moxart_mac_priv_t *priv = netdev_priv(ndev); - int i; - - for (i = 0; i < RX_DESC_NUM; i++) - dma_unmap_single(&ndev->dev, priv->rx_mapping[i], - priv->rx_buf_size, DMA_FROM_DEVICE); if (priv->tx_desc_base) dma_free_coherent(&priv->pdev->dev, @@ -147,11 +142,11 @@ desc + RX_REG_OFFSET_DESC1); priv->rx_buf[i] = priv->rx_buf_base + priv->rx_buf_size * i; - priv->rx_mapping[i] = dma_map_single(&ndev->dev, + priv->rx_mapping[i] = dma_map_single(&priv->pdev->dev, priv->rx_buf[i], priv->rx_buf_size, DMA_FROM_DEVICE); - if (dma_mapping_error(&ndev->dev, priv->rx_mapping[i])) + if (dma_mapping_error(&priv->pdev->dev, priv->rx_mapping[i])) netdev_err(ndev, "DMA mapping error\n"); moxart_desc_write(priv->rx_mapping[i], @@ -193,6 +188,7 @@ static int moxart_mac_stop(struct net_device *ndev) { struct moxart_mac_priv_t *priv = netdev_priv(ndev); + int i; napi_disable(&priv->napi); @@ -204,6 +200,11 @@ /* disable all functions */ writel(0, priv->base + REG_MAC_CTRL); + /* unmap areas mapped in moxart_mac_setup_desc_ring() */ + for (i = 0; i < RX_DESC_NUM; i++) + dma_unmap_single(&priv->pdev->dev, priv->rx_mapping[i], + priv->rx_buf_size, DMA_FROM_DEVICE); + return 0; } @@ -240,7 +241,7 @@ if (len > RX_BUF_SIZE) len = RX_BUF_SIZE; - dma_sync_single_for_cpu(&ndev->dev, + dma_sync_single_for_cpu(&priv->pdev->dev, priv->rx_mapping[rx_head], priv->rx_buf_size, DMA_FROM_DEVICE); skb = netdev_alloc_skb_ip_align(ndev, len); @@ -294,7 +295,7 @@ unsigned int tx_tail = priv->tx_tail; while (tx_tail != tx_head) { - dma_unmap_single(&ndev->dev, priv->tx_mapping[tx_tail], + dma_unmap_single(&priv->pdev->dev, priv->tx_mapping[tx_tail], priv->tx_len[tx_tail], DMA_TO_DEVICE); ndev->stats.tx_packets++; @@ -357,9 +358,9 @@ len = skb->len > TX_BUF_SIZE ? TX_BUF_SIZE : skb->len; - priv->tx_mapping[tx_head] = dma_map_single(&ndev->dev, skb->data, + priv->tx_mapping[tx_head] = dma_map_single(&priv->pdev->dev, skb->data, len, DMA_TO_DEVICE); - if (dma_mapping_error(&ndev->dev, priv->tx_mapping[tx_head])) { + if (dma_mapping_error(&priv->pdev->dev, priv->tx_mapping[tx_head])) { netdev_err(ndev, "DMA mapping error\n"); goto out_unlock; } @@ -378,7 +379,7 @@ len = ETH_ZLEN; } - dma_sync_single_for_device(&ndev->dev, priv->tx_mapping[tx_head], + dma_sync_single_for_device(&priv->pdev->dev, priv->tx_mapping[tx_head], priv->tx_buf_size, DMA_TO_DEVICE); txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK); @@ -481,6 +482,10 @@ priv->pdev = pdev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -EINVAL; + goto init_fail; + } ndev->base_addr = res->start; priv->base = devm_ioremap_resource(p_dev, res); if (IS_ERR(priv->base)) { @@ -494,7 +499,7 @@ priv->tx_buf_size = TX_BUF_SIZE; priv->rx_buf_size = RX_BUF_SIZE; - priv->tx_desc_base = dma_alloc_coherent(&pdev->dev, TX_REG_DESC_SIZE * + priv->tx_desc_base = dma_alloc_coherent(p_dev, TX_REG_DESC_SIZE * TX_DESC_NUM, &priv->tx_base, GFP_DMA | GFP_KERNEL); if (!priv->tx_desc_base) { @@ -502,7 +507,7 @@ goto init_fail; } - priv->rx_desc_base = dma_alloc_coherent(&pdev->dev, RX_REG_DESC_SIZE * + priv->rx_desc_base = dma_alloc_coherent(p_dev, RX_REG_DESC_SIZE * RX_DESC_NUM, &priv->rx_base, GFP_DMA | GFP_KERNEL); if (!priv->rx_desc_base) { @@ -541,10 +546,8 @@ SET_NETDEV_DEV(ndev, &pdev->dev); ret = register_netdev(ndev); - if (ret) { - free_netdev(ndev); + if (ret) goto init_fail; - } netdev_dbg(ndev, "%s: IRQ=%d address=%pM\n", __func__, ndev->irq, ndev->dev_addr); @@ -564,7 +567,7 @@ struct net_device *ndev = platform_get_drvdata(pdev); unregister_netdev(ndev); - free_irq(ndev->irq, ndev); + devm_free_irq(&pdev->dev, ndev->irq, ndev); moxart_mac_free_memory(ndev); free_netdev(ndev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mscc/ocelot.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mscc/ocelot.c @@ -1024,12 +1024,6 @@ switch (cfg.rx_filter) { case HWTSTAMP_FILTER_NONE: break; - case HWTSTAMP_FILTER_ALL: - case HWTSTAMP_FILTER_SOME: - case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: - case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: - case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: - case HWTSTAMP_FILTER_NTP_ALL: case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: @@ -1189,7 +1183,10 @@ SOF_TIMESTAMPING_RAW_HARDWARE; info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) | BIT(HWTSTAMP_TX_ONESTEP_SYNC); - info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT); return 0; } @@ -1716,10 +1713,8 @@ struct net_device *dev = netdev_notifier_info_to_dev(ptr); int ret = 0; - if (!ocelot_netdevice_dev_check(dev)) - return 0; - if (event == NETDEV_PRECHANGEUPPER && + ocelot_netdevice_dev_check(dev) && netif_is_lag_master(info->upper_dev)) { struct netdev_lag_upper_info *lag_upper_info = info->upper_info; struct netlink_ext_ack *extack; @@ -1979,14 +1974,18 @@ static int ocelot_init_timestamp(struct ocelot *ocelot) { + struct ptp_clock *ptp_clock; + ocelot->ptp_info = ocelot_ptp_clock_info; - ocelot->ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); - if (IS_ERR(ocelot->ptp_clock)) - return PTR_ERR(ocelot->ptp_clock); + ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev); + if (IS_ERR(ptp_clock)) + return PTR_ERR(ptp_clock); /* Check if PHC support is missing at the configuration level */ - if (!ocelot->ptp_clock) + if (!ptp_clock) return 0; + ocelot->ptp_clock = ptp_clock; + ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG); ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW); ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH); @@ -2154,8 +2153,12 @@ ocelot_write_rix(ocelot, ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)), ANA_PGID_PGID, PGID_MC); - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV4); - ocelot_write_rix(ocelot, 0, ANA_PGID_PGID, PGID_MCIPV6); + ocelot_write_rix(ocelot, + ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)), + ANA_PGID_PGID, PGID_MCIPV4); + ocelot_write_rix(ocelot, + ANA_PGID_PGID_PGID(GENMASK(ocelot->num_phys_ports, 0)), + ANA_PGID_PGID, PGID_MCIPV6); /* CPU port Injection/Extraction configuration */ ocelot_write_rix(ocelot, QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE | @@ -2213,6 +2216,8 @@ destroy_workqueue(ocelot->stats_queue); mutex_destroy(&ocelot->stats_lock); ocelot_ace_deinit(); + if (ocelot->ptp_clock) + ptp_clock_unregister(ocelot->ptp_clock); for (i = 0; i < ocelot->num_phys_ports; i++) { port = ocelot->ports[i]; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/mscc/ocelot_board.c +++ linux-oracle-5.4.0/drivers/net/ethernet/mscc/ocelot_board.c @@ -112,6 +112,14 @@ if (err != 4) break; + /* At this point the IFH was read correctly, so it is safe to + * presume that there is no error. The err needs to be reset + * otherwise a frame could come in CPU queue between the while + * condition and the check for error later on. And in that case + * the new frame is just removed and not processed. + */ + err = 0; + ocelot_parse_ifh(ifh, &info); dev = ocelot->ports[info.port]->dev; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ linux-oracle-5.4.0/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3849,6 +3849,7 @@ dev_err(&pdev->dev, "invalid sram_size %dB or board span %ldB\n", mgp->sram_size, mgp->board_span); + status = -EINVAL; goto abort_with_ioremap; } memcpy_fromio(mgp->eeprom_strings, @@ -3955,6 +3956,7 @@ myri10ge_free_slices(mgp); abort_with_firmware: + kfree(mgp->msix_vectors); myri10ge_dummy_rdma(mgp, 0); abort_with_ioremap: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/jazzsonic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/jazzsonic.c @@ -235,11 +235,13 @@ err = register_netdev(dev); if (err) - goto out1; + goto undo_probe1; return 0; -out1: +undo_probe1: + dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), + lp->descriptors, lp->descriptors_laddr); release_mem_region(dev->base_addr, SONIC_MEM_SIZE); out: free_netdev(dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/macsonic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/macsonic.c @@ -540,10 +540,14 @@ err = register_netdev(dev); if (err) - goto out; + goto undo_probe; return 0; +undo_probe: + dma_free_coherent(lp->device, + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), + lp->descriptors, lp->descriptors_laddr); out: free_netdev(dev); @@ -618,12 +622,16 @@ err = register_netdev(ndev); if (err) - goto out; + goto undo_probe; nubus_set_drvdata(board, ndev); return 0; +undo_probe: + dma_free_coherent(lp->device, + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), + lp->descriptors, lp->descriptors_laddr); out: free_netdev(ndev); return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/natsemi.c +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/natsemi.c @@ -819,7 +819,7 @@ printk(version); #endif - i = pci_enable_device(pdev); + i = pcim_enable_device(pdev); if (i) return i; /* natsemi has a non-standard PM control register @@ -852,7 +852,7 @@ ioaddr = ioremap(iostart, iosize); if (!ioaddr) { i = -ENOMEM; - goto err_ioremap; + goto err_pci_request_regions; } /* Work around the dropped serial bit. */ @@ -974,9 +974,6 @@ err_register_netdev: iounmap(ioaddr); - err_ioremap: - pci_release_regions(pdev); - err_pci_request_regions: free_netdev(dev); return i; @@ -3242,7 +3239,6 @@ NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); unregister_netdev (dev); - pci_release_regions (pdev); iounmap(ioaddr); free_netdev (dev); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/sonic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/sonic.c @@ -64,6 +64,8 @@ netif_dbg(lp, ifup, dev, "%s: initializing sonic driver\n", __func__); + spin_lock_init(&lp->lock); + for (i = 0; i < SONIC_NUM_RRS; i++) { struct sk_buff *skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); if (skb == NULL) { @@ -114,6 +116,24 @@ return 0; } +/* Wait for the SONIC to become idle. */ +static void sonic_quiesce(struct net_device *dev, u16 mask) +{ + struct sonic_local * __maybe_unused lp = netdev_priv(dev); + int i; + u16 bits; + + for (i = 0; i < 1000; ++i) { + bits = SONIC_READ(SONIC_CMD) & mask; + if (!bits) + return; + if (irqs_disabled() || in_interrupt()) + udelay(20); + else + usleep_range(100, 200); + } + WARN_ONCE(1, "command deadline expired! 0x%04x\n", bits); +} /* * Close the SONIC device @@ -130,6 +150,9 @@ /* * stop the SONIC, disable interrupts */ + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS); + sonic_quiesce(dev, SONIC_CR_ALL); + SONIC_WRITE(SONIC_IMR, 0); SONIC_WRITE(SONIC_ISR, 0x7fff); SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); @@ -169,6 +192,9 @@ * put the Sonic into software-reset mode and * disable all interrupts before releasing DMA buffers */ + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS); + sonic_quiesce(dev, SONIC_CR_ALL); + SONIC_WRITE(SONIC_IMR, 0); SONIC_WRITE(SONIC_ISR, 0x7fff); SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); @@ -206,8 +232,6 @@ * wake the tx queue * Concurrently with all of this, the SONIC is potentially writing to * the status flags of the TDs. - * Until some mutual exclusion is added, this code will not work with SMP. However, - * MIPS Jazz machines and m68k Macs were all uni-processor machines. */ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) @@ -215,7 +239,8 @@ struct sonic_local *lp = netdev_priv(dev); dma_addr_t laddr; int length; - int entry = lp->next_tx; + int entry; + unsigned long flags; netif_dbg(lp, tx_queued, dev, "%s: skb=%p\n", __func__, skb); @@ -231,12 +256,16 @@ */ laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE); - if (!laddr) { + if (dma_mapping_error(lp->device, laddr)) { pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name); dev_kfree_skb_any(skb); return NETDEV_TX_OK; } + spin_lock_irqsave(&lp->lock, flags); + + entry = lp->next_tx; + sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ sonic_tda_put(dev, entry, SONIC_TD_FRAG_COUNT, 1); /* single fragment */ sonic_tda_put(dev, entry, SONIC_TD_PKTSIZE, length); /* length of packet */ @@ -246,10 +275,6 @@ sonic_tda_put(dev, entry, SONIC_TD_LINK, sonic_tda_get(dev, entry, SONIC_TD_LINK) | SONIC_EOL); - /* - * Must set tx_skb[entry] only after clearing status, and - * before clearing EOL and before stopping queue - */ wmb(); lp->tx_len[entry] = length; lp->tx_laddr[entry] = laddr; @@ -272,6 +297,8 @@ SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); + spin_unlock_irqrestore(&lp->lock, flags); + return NETDEV_TX_OK; } @@ -284,15 +311,28 @@ struct net_device *dev = dev_id; struct sonic_local *lp = netdev_priv(dev); int status; + unsigned long flags; + + /* The lock has two purposes. Firstly, it synchronizes sonic_interrupt() + * with sonic_send_packet() so that the two functions can share state. + * Secondly, it makes sonic_interrupt() re-entrant, as that is required + * by macsonic which must use two IRQs with different priority levels. + */ + spin_lock_irqsave(&lp->lock, flags); + + status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT; + if (!status) { + spin_unlock_irqrestore(&lp->lock, flags); - if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)) return IRQ_NONE; + } do { + SONIC_WRITE(SONIC_ISR, status); /* clear the interrupt(s) */ + if (status & SONIC_INT_PKTRX) { netif_dbg(lp, intr, dev, "%s: packet rx\n", __func__); sonic_rx(dev); /* got packet(s) */ - SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ } if (status & SONIC_INT_TXDN) { @@ -300,11 +340,12 @@ int td_status; int freed_some = 0; - /* At this point, cur_tx is the index of a TD that is one of: - * unallocated/freed (status set & tx_skb[entry] clear) - * allocated and sent (status set & tx_skb[entry] set ) - * allocated and not yet sent (status clear & tx_skb[entry] set ) - * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear) + /* The state of a Transmit Descriptor may be inferred + * from { tx_skb[entry], td_status } as follows. + * { clear, clear } => the TD has never been used + * { set, clear } => the TD was handed to SONIC + * { set, set } => the TD was handed back + * { clear, set } => the TD is available for re-use */ netif_dbg(lp, intr, dev, "%s: tx done\n", __func__); @@ -313,18 +354,19 @@ if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0) break; - if (td_status & 0x0001) { + if (td_status & SONIC_TCR_PTX) { lp->stats.tx_packets++; lp->stats.tx_bytes += sonic_tda_get(dev, entry, SONIC_TD_PKTSIZE); } else { - lp->stats.tx_errors++; - if (td_status & 0x0642) + if (td_status & (SONIC_TCR_EXD | + SONIC_TCR_EXC | SONIC_TCR_BCM)) lp->stats.tx_aborted_errors++; - if (td_status & 0x0180) + if (td_status & + (SONIC_TCR_NCRS | SONIC_TCR_CRLS)) lp->stats.tx_carrier_errors++; - if (td_status & 0x0020) + if (td_status & SONIC_TCR_OWC) lp->stats.tx_window_errors++; - if (td_status & 0x0004) + if (td_status & SONIC_TCR_FU) lp->stats.tx_fifo_errors++; } @@ -346,7 +388,6 @@ if (freed_some || lp->tx_skb[entry] == NULL) netif_wake_queue(dev); /* The ring is no longer full */ lp->cur_tx = entry; - SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */ } /* @@ -355,42 +396,37 @@ if (status & SONIC_INT_RFO) { netif_dbg(lp, rx_err, dev, "%s: rx fifo overrun\n", __func__); - lp->stats.rx_fifo_errors++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ } if (status & SONIC_INT_RDE) { netif_dbg(lp, rx_err, dev, "%s: rx descriptors exhausted\n", __func__); - lp->stats.rx_dropped++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ } if (status & SONIC_INT_RBAE) { netif_dbg(lp, rx_err, dev, "%s: rx buffer area exceeded\n", __func__); - lp->stats.rx_dropped++; - SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ } /* counter overruns; all counters are 16bit wide */ - if (status & SONIC_INT_FAE) { + if (status & SONIC_INT_FAE) lp->stats.rx_frame_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_FAE); /* clear the interrupt */ - } - if (status & SONIC_INT_CRC) { + if (status & SONIC_INT_CRC) lp->stats.rx_crc_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_CRC); /* clear the interrupt */ - } - if (status & SONIC_INT_MP) { + if (status & SONIC_INT_MP) lp->stats.rx_missed_errors += 65536; - SONIC_WRITE(SONIC_ISR, SONIC_INT_MP); /* clear the interrupt */ - } /* transmit error */ if (status & SONIC_INT_TXER) { - if (SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) - netif_dbg(lp, tx_err, dev, "%s: tx fifo underrun\n", - __func__); - SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ + u16 tcr = SONIC_READ(SONIC_TCR); + + netif_dbg(lp, tx_err, dev, "%s: TXER intr, TCR %04x\n", + __func__, tcr); + + if (tcr & (SONIC_TCR_EXD | SONIC_TCR_EXC | + SONIC_TCR_FU | SONIC_TCR_BCM)) { + /* Aborted transmission. Try again. */ + netif_stop_queue(dev); + SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); + } } /* bus retry */ @@ -400,107 +436,164 @@ /* ... to help debug DMA problems causing endless interrupts. */ /* Bounce the eth interface to turn on the interrupt again. */ SONIC_WRITE(SONIC_IMR, 0); - SONIC_WRITE(SONIC_ISR, SONIC_INT_BR); /* clear the interrupt */ } - /* load CAM done */ - if (status & SONIC_INT_LCD) - SONIC_WRITE(SONIC_ISR, SONIC_INT_LCD); /* clear the interrupt */ - } while((status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)); + status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT; + } while (status); + + spin_unlock_irqrestore(&lp->lock, flags); + return IRQ_HANDLED; } +/* Return the array index corresponding to a given Receive Buffer pointer. */ +static int index_from_addr(struct sonic_local *lp, dma_addr_t addr, + unsigned int last) +{ + unsigned int i = last; + + do { + i = (i + 1) & SONIC_RRS_MASK; + if (addr == lp->rx_laddr[i]) + return i; + } while (i != last); + + return -ENOENT; +} + +/* Allocate and map a new skb to be used as a receive buffer. */ +static bool sonic_alloc_rb(struct net_device *dev, struct sonic_local *lp, + struct sk_buff **new_skb, dma_addr_t *new_addr) +{ + *new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); + if (!*new_skb) + return false; + + if (SONIC_BUS_SCALE(lp->dma_bitmode) == 2) + skb_reserve(*new_skb, 2); + + *new_addr = dma_map_single(lp->device, skb_put(*new_skb, SONIC_RBSIZE), + SONIC_RBSIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(lp->device, *new_addr)) { + dev_kfree_skb(*new_skb); + *new_skb = NULL; + return false; + } + + return true; +} + +/* Place a new receive resource in the Receive Resource Area and update RWP. */ +static void sonic_update_rra(struct net_device *dev, struct sonic_local *lp, + dma_addr_t old_addr, dma_addr_t new_addr) +{ + unsigned int entry = sonic_rr_entry(dev, SONIC_READ(SONIC_RWP)); + unsigned int end = sonic_rr_entry(dev, SONIC_READ(SONIC_RRP)); + u32 buf; + + /* The resources in the range [RRP, RWP) belong to the SONIC. This loop + * scans the other resources in the RRA, those in the range [RWP, RRP). + */ + do { + buf = (sonic_rra_get(dev, entry, SONIC_RR_BUFADR_H) << 16) | + sonic_rra_get(dev, entry, SONIC_RR_BUFADR_L); + + if (buf == old_addr) + break; + + entry = (entry + 1) & SONIC_RRS_MASK; + } while (entry != end); + + WARN_ONCE(buf != old_addr, "failed to find resource!\n"); + + sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, new_addr >> 16); + sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, new_addr & 0xffff); + + entry = (entry + 1) & SONIC_RRS_MASK; + + SONIC_WRITE(SONIC_RWP, sonic_rr_addr(dev, entry)); +} + /* * We have a good packet(s), pass it/them up the network stack. */ static void sonic_rx(struct net_device *dev) { struct sonic_local *lp = netdev_priv(dev); - int status; int entry = lp->cur_rx; + int prev_entry = lp->eol_rx; + bool rbe = false; while (sonic_rda_get(dev, entry, SONIC_RD_IN_USE) == 0) { - struct sk_buff *used_skb; - struct sk_buff *new_skb; - dma_addr_t new_laddr; - u16 bufadr_l; - u16 bufadr_h; - int pkt_len; - - status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); - if (status & SONIC_RCR_PRX) { - /* Malloc up new buffer. */ - new_skb = netdev_alloc_skb(dev, SONIC_RBSIZE + 2); - if (new_skb == NULL) { - lp->stats.rx_dropped++; + u16 status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); + + /* If the RD has LPKT set, the chip has finished with the RB */ + if ((status & SONIC_RCR_PRX) && (status & SONIC_RCR_LPKT)) { + struct sk_buff *new_skb; + dma_addr_t new_laddr; + u32 addr = (sonic_rda_get(dev, entry, + SONIC_RD_PKTPTR_H) << 16) | + sonic_rda_get(dev, entry, SONIC_RD_PKTPTR_L); + int i = index_from_addr(lp, addr, entry); + + if (i < 0) { + WARN_ONCE(1, "failed to find buffer!\n"); break; } - /* provide 16 byte IP header alignment unless DMA requires otherwise */ - if(SONIC_BUS_SCALE(lp->dma_bitmode) == 2) - skb_reserve(new_skb, 2); - - new_laddr = dma_map_single(lp->device, skb_put(new_skb, SONIC_RBSIZE), - SONIC_RBSIZE, DMA_FROM_DEVICE); - if (!new_laddr) { - dev_kfree_skb(new_skb); - printk(KERN_ERR "%s: Failed to map rx buffer, dropping packet.\n", dev->name); + + if (sonic_alloc_rb(dev, lp, &new_skb, &new_laddr)) { + struct sk_buff *used_skb = lp->rx_skb[i]; + int pkt_len; + + /* Pass the used buffer up the stack */ + dma_unmap_single(lp->device, addr, SONIC_RBSIZE, + DMA_FROM_DEVICE); + + pkt_len = sonic_rda_get(dev, entry, + SONIC_RD_PKTLEN); + skb_trim(used_skb, pkt_len); + used_skb->protocol = eth_type_trans(used_skb, + dev); + netif_rx(used_skb); + lp->stats.rx_packets++; + lp->stats.rx_bytes += pkt_len; + + lp->rx_skb[i] = new_skb; + lp->rx_laddr[i] = new_laddr; + } else { + /* Failed to obtain a new buffer so re-use it */ + new_laddr = addr; lp->stats.rx_dropped++; - break; } - - /* now we have a new skb to replace it, pass the used one up the stack */ - dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE); - used_skb = lp->rx_skb[entry]; - pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN); - skb_trim(used_skb, pkt_len); - used_skb->protocol = eth_type_trans(used_skb, dev); - netif_rx(used_skb); - lp->stats.rx_packets++; - lp->stats.rx_bytes += pkt_len; - - /* and insert the new skb */ - lp->rx_laddr[entry] = new_laddr; - lp->rx_skb[entry] = new_skb; - - bufadr_l = (unsigned long)new_laddr & 0xffff; - bufadr_h = (unsigned long)new_laddr >> 16; - sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l); - sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h); - } else { - /* This should only happen, if we enable accepting broken packets. */ - lp->stats.rx_errors++; - if (status & SONIC_RCR_FAER) - lp->stats.rx_frame_errors++; - if (status & SONIC_RCR_CRCR) - lp->stats.rx_crc_errors++; - } - if (status & SONIC_RCR_LPKT) { - /* - * this was the last packet out of the current receive buffer - * give the buffer back to the SONIC + /* If RBE is already asserted when RWP advances then + * it's safe to clear RBE after processing this packet. */ - lp->cur_rwp += SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode); - if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff; - SONIC_WRITE(SONIC_RWP, lp->cur_rwp); - if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) { - netif_dbg(lp, rx_err, dev, "%s: rx buffer exhausted\n", - __func__); - SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */ - } - } else - printk(KERN_ERR "%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", - dev->name); + rbe = rbe || SONIC_READ(SONIC_ISR) & SONIC_INT_RBE; + sonic_update_rra(dev, lp, addr, new_laddr); + } /* * give back the descriptor */ - sonic_rda_put(dev, entry, SONIC_RD_LINK, - sonic_rda_get(dev, entry, SONIC_RD_LINK) | SONIC_EOL); + sonic_rda_put(dev, entry, SONIC_RD_STATUS, 0); sonic_rda_put(dev, entry, SONIC_RD_IN_USE, 1); - sonic_rda_put(dev, lp->eol_rx, SONIC_RD_LINK, - sonic_rda_get(dev, lp->eol_rx, SONIC_RD_LINK) & ~SONIC_EOL); - lp->eol_rx = entry; - lp->cur_rx = entry = (entry + 1) & SONIC_RDS_MASK; + + prev_entry = entry; + entry = (entry + 1) & SONIC_RDS_MASK; + } + + lp->cur_rx = entry; + + if (prev_entry != lp->eol_rx) { + /* Advance the EOL flag to put descriptors back into service */ + sonic_rda_put(dev, prev_entry, SONIC_RD_LINK, SONIC_EOL | + sonic_rda_get(dev, prev_entry, SONIC_RD_LINK)); + sonic_rda_put(dev, lp->eol_rx, SONIC_RD_LINK, ~SONIC_EOL & + sonic_rda_get(dev, lp->eol_rx, SONIC_RD_LINK)); + lp->eol_rx = prev_entry; } + + if (rbe) + SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* * If any worth-while packets have been received, netif_rx() * has done a mark_bh(NET_BH) for us and will work on them @@ -550,6 +643,8 @@ (netdev_mc_count(dev) > 15)) { rcr |= SONIC_RCR_AMC; } else { + unsigned long flags; + netif_dbg(lp, ifup, dev, "%s: mc_count %d\n", __func__, netdev_mc_count(dev)); sonic_set_cam_enable(dev, 1); /* always enable our own address */ @@ -563,9 +658,14 @@ i++; } SONIC_WRITE(SONIC_CDC, 16); - /* issue Load CAM command */ SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff); + + /* LCAM and TXP commands can't be used simultaneously */ + spin_lock_irqsave(&lp->lock, flags); + sonic_quiesce(dev, SONIC_CR_TXP); SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); + sonic_quiesce(dev, SONIC_CR_LCAM); + spin_unlock_irqrestore(&lp->lock, flags); } } @@ -580,7 +680,6 @@ */ static int sonic_init(struct net_device *dev) { - unsigned int cmd; struct sonic_local *lp = netdev_priv(dev); int i; @@ -592,12 +691,16 @@ SONIC_WRITE(SONIC_ISR, 0x7fff); SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); + /* While in reset mode, clear CAM Enable register */ + SONIC_WRITE(SONIC_CE, 0); + /* * clear software reset flag, disable receiver, clear and * enable interrupts, then completely initialize the SONIC */ SONIC_WRITE(SONIC_CMD, 0); - SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS); + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXDIS | SONIC_CR_STP); + sonic_quiesce(dev, SONIC_CR_ALL); /* * initialize the receive resource area @@ -615,15 +718,10 @@ } /* initialize all RRA registers */ - lp->rra_end = (lp->rra_laddr + SONIC_NUM_RRS * SIZEOF_SONIC_RR * - SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; - lp->cur_rwp = (lp->rra_laddr + (SONIC_NUM_RRS - 1) * SIZEOF_SONIC_RR * - SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; - - SONIC_WRITE(SONIC_RSA, lp->rra_laddr & 0xffff); - SONIC_WRITE(SONIC_REA, lp->rra_end); - SONIC_WRITE(SONIC_RRP, lp->rra_laddr & 0xffff); - SONIC_WRITE(SONIC_RWP, lp->cur_rwp); + SONIC_WRITE(SONIC_RSA, sonic_rr_addr(dev, 0)); + SONIC_WRITE(SONIC_REA, sonic_rr_addr(dev, SONIC_NUM_RRS)); + SONIC_WRITE(SONIC_RRP, sonic_rr_addr(dev, 0)); + SONIC_WRITE(SONIC_RWP, sonic_rr_addr(dev, SONIC_NUM_RRS - 1)); SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1)); @@ -631,14 +729,7 @@ netif_dbg(lp, ifup, dev, "%s: issuing RRRA command\n", __func__); SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); - i = 0; - while (i++ < 100) { - if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA) - break; - } - - netif_dbg(lp, ifup, dev, "%s: status=%x, i=%d\n", __func__, - SONIC_READ(SONIC_CMD), i); + sonic_quiesce(dev, SONIC_CR_RRRA); /* * Initialize the receive descriptors so that they @@ -713,28 +804,17 @@ * load the CAM */ SONIC_WRITE(SONIC_CMD, SONIC_CR_LCAM); - - i = 0; - while (i++ < 100) { - if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD) - break; - } - netif_dbg(lp, ifup, dev, "%s: CMD=%x, ISR=%x, i=%d\n", __func__, - SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i); + sonic_quiesce(dev, SONIC_CR_LCAM); /* * enable receiver, disable loopback * and enable all interrupts */ - SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN | SONIC_CR_STP); SONIC_WRITE(SONIC_RCR, SONIC_RCR_DEFAULT); SONIC_WRITE(SONIC_TCR, SONIC_TCR_DEFAULT); SONIC_WRITE(SONIC_ISR, 0x7fff); SONIC_WRITE(SONIC_IMR, SONIC_IMR_DEFAULT); - - cmd = SONIC_READ(SONIC_CMD); - if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) - printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd); + SONIC_WRITE(SONIC_CMD, SONIC_CR_RXEN); netif_dbg(lp, ifup, dev, "%s: new status=%x\n", __func__, SONIC_READ(SONIC_CMD)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/sonic.h +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/sonic.h @@ -110,6 +110,9 @@ #define SONIC_CR_TXP 0x0002 #define SONIC_CR_HTX 0x0001 +#define SONIC_CR_ALL (SONIC_CR_LCAM | SONIC_CR_RRRA | \ + SONIC_CR_RXEN | SONIC_CR_TXP) + /* * SONIC data configuration bits */ @@ -175,6 +178,7 @@ #define SONIC_TCR_NCRS 0x0100 #define SONIC_TCR_CRLS 0x0080 #define SONIC_TCR_EXC 0x0040 +#define SONIC_TCR_OWC 0x0020 #define SONIC_TCR_PMB 0x0008 #define SONIC_TCR_FU 0x0004 #define SONIC_TCR_BCM 0x0002 @@ -274,8 +278,9 @@ #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ -#define SONIC_RDS_MASK (SONIC_NUM_RDS-1) -#define SONIC_TDS_MASK (SONIC_NUM_TDS-1) +#define SONIC_RRS_MASK (SONIC_NUM_RRS - 1) +#define SONIC_RDS_MASK (SONIC_NUM_RDS - 1) +#define SONIC_TDS_MASK (SONIC_NUM_TDS - 1) #define SONIC_RBSIZE 1520 /* size of one resource buffer */ @@ -312,8 +317,6 @@ u32 rda_laddr; /* logical DMA address of RDA */ dma_addr_t rx_laddr[SONIC_NUM_RRS]; /* logical DMA addresses of rx skbuffs */ dma_addr_t tx_laddr[SONIC_NUM_TDS]; /* logical DMA addresses of tx skbuffs */ - unsigned int rra_end; - unsigned int cur_rwp; unsigned int cur_rx; unsigned int cur_tx; /* first unacked transmit packet */ unsigned int eol_rx; @@ -322,6 +325,7 @@ int msg_enable; struct device *device; /* generic device */ struct net_device_stats stats; + spinlock_t lock; }; #define TX_TIMEOUT (3 * HZ) @@ -344,30 +348,30 @@ as far as we can tell. */ /* OpenBSD calls this "SWO". I'd like to think that sonic_buf_put() is a much better name. */ -static inline void sonic_buf_put(void* base, int bitmode, +static inline void sonic_buf_put(u16 *base, int bitmode, int offset, __u16 val) { if (bitmode) #ifdef __BIG_ENDIAN - ((__u16 *) base + (offset*2))[1] = val; + __raw_writew(val, base + (offset * 2) + 1); #else - ((__u16 *) base + (offset*2))[0] = val; + __raw_writew(val, base + (offset * 2) + 0); #endif else - ((__u16 *) base)[offset] = val; + __raw_writew(val, base + (offset * 1) + 0); } -static inline __u16 sonic_buf_get(void* base, int bitmode, +static inline __u16 sonic_buf_get(u16 *base, int bitmode, int offset) { if (bitmode) #ifdef __BIG_ENDIAN - return ((volatile __u16 *) base + (offset*2))[1]; + return __raw_readw(base + (offset * 2) + 1); #else - return ((volatile __u16 *) base + (offset*2))[0]; + return __raw_readw(base + (offset * 2) + 0); #endif else - return ((volatile __u16 *) base)[offset]; + return __raw_readw(base + (offset * 1) + 0); } /* Inlines that you should actually use for reading/writing DMA buffers */ @@ -447,6 +451,22 @@ (entry * SIZEOF_SONIC_RR) + offset); } +static inline u16 sonic_rr_addr(struct net_device *dev, int entry) +{ + struct sonic_local *lp = netdev_priv(dev); + + return lp->rra_laddr + + entry * SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode); +} + +static inline u16 sonic_rr_entry(struct net_device *dev, u16 addr) +{ + struct sonic_local *lp = netdev_priv(dev); + + return (addr - (u16)lp->rra_laddr) / (SIZEOF_SONIC_RR * + SONIC_BUS_SCALE(lp->dma_bitmode)); +} + static const char version[] = "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/natsemi/xtsonic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/natsemi/xtsonic.c @@ -120,7 +120,7 @@ .ndo_set_mac_address = eth_mac_addr, }; -static int __init sonic_probe1(struct net_device *dev) +static int sonic_probe1(struct net_device *dev) { unsigned int silicon_revision; struct sonic_local *lp = netdev_priv(dev); @@ -265,11 +265,14 @@ sonic_msg_init(dev); if ((err = register_netdev(dev))) - goto out1; + goto undo_probe1; return 0; -out1: +undo_probe1: + dma_free_coherent(lp->device, + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), + lp->descriptors, lp->descriptors_laddr); release_region(dev->base_addr, SONIC_MEM_SIZE); out: free_netdev(dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/neterion/s2io.c +++ linux-oracle-5.4.0/drivers/net/ethernet/neterion/s2io.c @@ -2375,7 +2375,7 @@ skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); if (skb) { swstats->mem_freed += skb->truesize; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); cnt++; } } @@ -7122,9 +7122,8 @@ if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENOMEM; + ret = -ENOMEM; + goto err_fill_buff; } DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i, ring->rx_bufs_left); @@ -7162,18 +7161,16 @@ /* Enable Rx Traffic and interrupts on the NIC */ if (start_nic(sp)) { DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENODEV; + ret = -ENODEV; + goto err_out; } /* Add interrupt service routine */ if (s2io_add_isr(sp) != 0) { if (sp->config.intr_type == MSI_X) s2io_rem_isr(sp); - s2io_reset(sp); - free_rx_buffers(sp); - return -ENODEV; + ret = -ENODEV; + goto err_out; } timer_setup(&sp->alarm_timer, s2io_alarm_handle, 0); @@ -7193,6 +7190,20 @@ } return 0; + +err_out: + if (config->napi) { + if (config->intr_type == MSI_X) { + for (i = 0; i < sp->config.rx_ring_num; i++) + napi_disable(&sp->mac_control.rings[i].napi); + } else { + napi_disable(&sp->napi); + } + } +err_fill_buff: + s2io_reset(sp); + free_rx_buffers(sp); + return ret; } /** @@ -7276,7 +7287,7 @@ int ring_no = ring_data->ring_no; u16 l3_csum, l4_csum; unsigned long long err = rxdp->Control_1 & RXD_T_CODE; - struct lro *uninitialized_var(lro); + struct lro *lro; u8 err_mask; struct swStat *swstats = &sp->mac_control.stats_info->sw_stat; @@ -8565,7 +8576,7 @@ return; } - if (s2io_set_mac_addr(netdev, netdev->dev_addr) == FAILURE) { + if (do_s2io_prog_unicast(netdev, netdev->dev_addr) == FAILURE) { s2io_card_down(sp); pr_err("Can't restore mac addr after reset.\n"); return; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/neterion/vxge/vxge-config.h +++ linux-oracle-5.4.0/drivers/net/ethernet/neterion/vxge/vxge-config.h @@ -2045,7 +2045,7 @@ if ((level >= VXGE_ERR && VXGE_COMPONENT_LL & VXGE_DEBUG_ERR_MASK) || \ (level >= VXGE_TRACE && VXGE_COMPONENT_LL & VXGE_DEBUG_TRACE_MASK))\ if ((mask & VXGE_DEBUG_MASK) == mask) \ - printk(fmt "\n", __VA_ARGS__); \ + printk(fmt "\n", ##__VA_ARGS__); \ } while (0) #else #define vxge_debug_ll(level, mask, fmt, ...) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -3524,13 +3524,13 @@ kfree(vdev->vpaths); - /* we are safe to free it now */ - free_netdev(dev); - vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", buf); vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, __func__, __LINE__); + + /* we are safe to free it now */ + free_netdev(dev); } /* @@ -4197,6 +4197,9 @@ return ret; } +#define VXGE_PXE_FIRMWARE "vxge/X3fw-pxe.ncf" +#define VXGE_FIRMWARE "vxge/X3fw.ncf" + static int vxge_probe_fw_update(struct vxgedev *vdev) { u32 maj, min, bld; @@ -4239,9 +4242,9 @@ } } if (gpxe) - fw_name = "vxge/X3fw-pxe.ncf"; + fw_name = VXGE_PXE_FIRMWARE; else - fw_name = "vxge/X3fw.ncf"; + fw_name = VXGE_FIRMWARE; ret = vxge_fw_upgrade(vdev, fw_name, 0); /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on @@ -4846,3 +4849,5 @@ } module_init(vxge_starter); module_exit(vxge_closer); +MODULE_FIRMWARE(VXGE_PXE_FIRMWARE); +MODULE_FIRMWARE(VXGE_FIRMWARE); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/neterion/vxge/vxge-main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/neterion/vxge/vxge-main.h @@ -452,49 +452,49 @@ #if (VXGE_DEBUG_LL_CONFIG & VXGE_DEBUG_MASK) #define vxge_debug_ll_config(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_LL_CONFIG, fmt, ##__VA_ARGS__) #else #define vxge_debug_ll_config(level, fmt, ...) #endif #if (VXGE_DEBUG_INIT & VXGE_DEBUG_MASK) #define vxge_debug_init(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_INIT, fmt, ##__VA_ARGS__) #else #define vxge_debug_init(level, fmt, ...) #endif #if (VXGE_DEBUG_TX & VXGE_DEBUG_MASK) #define vxge_debug_tx(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_TX, fmt, ##__VA_ARGS__) #else #define vxge_debug_tx(level, fmt, ...) #endif #if (VXGE_DEBUG_RX & VXGE_DEBUG_MASK) #define vxge_debug_rx(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_RX, fmt, ##__VA_ARGS__) #else #define vxge_debug_rx(level, fmt, ...) #endif #if (VXGE_DEBUG_MEM & VXGE_DEBUG_MASK) #define vxge_debug_mem(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_MEM, fmt, ##__VA_ARGS__) #else #define vxge_debug_mem(level, fmt, ...) #endif #if (VXGE_DEBUG_ENTRYEXIT & VXGE_DEBUG_MASK) #define vxge_debug_entryexit(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_ENTRYEXIT, fmt, ##__VA_ARGS__) #else #define vxge_debug_entryexit(level, fmt, ...) #endif #if (VXGE_DEBUG_INTR & VXGE_DEBUG_MASK) #define vxge_debug_intr(level, fmt, ...) \ - vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, __VA_ARGS__) + vxge_debug_ll(level, VXGE_DEBUG_INTR, fmt, ##__VA_ARGS__) #else #define vxge_debug_intr(level, fmt, ...) #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/neterion/vxge/vxge-traffic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/neterion/vxge/vxge-traffic.c @@ -30,8 +30,6 @@ */ enum vxge_hw_status vxge_hw_vpath_intr_enable(struct __vxge_hw_vpath_handle *vp) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; struct vxge_hw_vpath_reg __iomem *vp_reg; enum vxge_hw_status status = VXGE_HW_OK; @@ -84,7 +82,7 @@ __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL, &vp_reg->xgmac_vp_int_status); - val64 = readq(&vp_reg->vpath_general_int_status); + readq(&vp_reg->vpath_general_int_status); /* Mask unwanted interrupts */ @@ -157,8 +155,6 @@ enum vxge_hw_status vxge_hw_vpath_intr_disable( struct __vxge_hw_vpath_handle *vp) { - u64 val64; - struct __vxge_hw_virtualpath *vpath; enum vxge_hw_status status = VXGE_HW_OK; struct vxge_hw_vpath_reg __iomem *vp_reg; @@ -179,8 +175,6 @@ (u32)VXGE_HW_INTR_MASK_ALL, &vp_reg->vpath_general_int_mask); - val64 = VXGE_HW_TIM_CLR_INT_EN_VP(1 << (16 - vpath->vp_id)); - writeq(VXGE_HW_INTR_MASK_ALL, &vp_reg->kdfcctl_errors_mask); __vxge_hw_pio_mem_write32_upper((u32)VXGE_HW_INTR_MASK_ALL, @@ -487,9 +481,7 @@ */ void vxge_hw_device_flush_io(struct __vxge_hw_device *hldev) { - u32 val32; - - val32 = readl(&hldev->common_reg->titan_general_int_status); + readl(&hldev->common_reg->titan_general_int_status); } /** @@ -1716,8 +1708,8 @@ enum vxge_hw_status vxge_hw_vpath_mac_addr_add( struct __vxge_hw_vpath_handle *vp, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN], + u8 *macaddr, + u8 *macaddr_mask, enum vxge_hw_vpath_mac_addr_add_mode duplicate_mode) { u32 i; @@ -1779,8 +1771,8 @@ enum vxge_hw_status vxge_hw_vpath_mac_addr_get( struct __vxge_hw_vpath_handle *vp, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]) + u8 *macaddr, + u8 *macaddr_mask) { u32 i; u64 data1 = 0ULL; @@ -1831,8 +1823,8 @@ enum vxge_hw_status vxge_hw_vpath_mac_addr_get_next( struct __vxge_hw_vpath_handle *vp, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]) + u8 *macaddr, + u8 *macaddr_mask) { u32 i; u64 data1 = 0ULL; @@ -1884,8 +1876,8 @@ enum vxge_hw_status vxge_hw_vpath_mac_addr_delete( struct __vxge_hw_vpath_handle *vp, - u8 (macaddr)[ETH_ALEN], - u8 (macaddr_mask)[ETH_ALEN]) + u8 *macaddr, + u8 *macaddr_mask) { u32 i; u64 data1 = 0ULL; @@ -2375,7 +2367,6 @@ u8 t_code; enum vxge_hw_status status = VXGE_HW_OK; void *first_rxdh; - u64 val64 = 0; int new_count = 0; ring->cmpl_cnt = 0; @@ -2403,8 +2394,7 @@ } writeq(VXGE_HW_PRC_RXD_DOORBELL_NEW_QW_CNT(new_count), &ring->vp_reg->prc_rxd_doorbell); - val64 = - readl(&ring->common_reg->titan_general_int_status); + readl(&ring->common_reg->titan_general_int_status); ring->doorbell_cnt = 0; } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/abm/cls.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/abm/cls.c @@ -176,10 +176,8 @@ u8 mask, val; int err; - if (!nfp_abm_u32_check_knode(alink->abm, knode, proto, extack)) { - err = -EOPNOTSUPP; + if (!nfp_abm_u32_check_knode(alink->abm, knode, proto, extack)) goto err_delete; - } tos_off = proto == htons(ETH_P_IP) ? 16 : 20; @@ -200,18 +198,14 @@ if ((iter->val & cmask) == (val & cmask) && iter->band != knode->res->classid) { NL_SET_ERR_MSG_MOD(extack, "conflict with already offloaded filter"); - err = -EOPNOTSUPP; goto err_delete; } } if (!match) { match = kzalloc(sizeof(*match), GFP_KERNEL); - if (!match) { - err = -ENOMEM; - goto err_delete; - } - + if (!match) + return -ENOMEM; list_add(&match->list, &alink->dscp_map); } match->handle = knode->handle; @@ -227,7 +221,7 @@ err_delete: nfp_abm_u32_knode_delete(alink, knode); - return err; + return -EOPNOTSUPP; } static int nfp_abm_setup_tc_block_cb(enum tc_setup_type type, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/abm/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/abm/main.c @@ -283,6 +283,7 @@ if (!nfp_nsp_has_hwinfo_lookup(nsp)) { nfp_warn(pf->cpp, "NSP doesn't support PF MAC generation\n"); eth_hw_addr_random(nn->dp.netdev); + nfp_nsp_close(nsp); return; } @@ -332,8 +333,10 @@ goto err_free_alink; alink->prio_map = kzalloc(abm->prio_map_len, GFP_KERNEL); - if (!alink->prio_map) + if (!alink->prio_map) { + err = -ENOMEM; goto err_free_alink; + } /* This is a multi-host app, make sure MAC/PHY is up, but don't * make the MAC/PHY state follow the state of any of the ports. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/bpf/cmsg.c @@ -20,6 +20,8 @@ struct sk_buff *skb; skb = nfp_app_ctrl_msg_alloc(bpf->app, size, GFP_KERNEL); + if (!skb) + return NULL; skb_put(skb, size); return skb; @@ -454,6 +456,7 @@ dev_consume_skb_any(skb); else dev_kfree_skb_any(skb); + return; } nfp_ccm_rx(&bpf->ccm, skb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -182,15 +182,21 @@ nfp_bpf_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu) { struct nfp_net *nn = netdev_priv(netdev); - unsigned int max_mtu; + struct nfp_bpf_vnic *bv; + struct bpf_prog *prog; if (~nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF) return 0; - max_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32; - if (new_mtu > max_mtu) { - nn_info(nn, "BPF offload active, MTU over %u not supported\n", - max_mtu); + if (nn->xdp_hw.prog) { + prog = nn->xdp_hw.prog; + } else { + bv = nn->app_priv; + prog = bv->tc_prog; + } + + if (nfp_bpf_offload_check_mtu(nn, prog, new_mtu)) { + nn_info(nn, "BPF offload active, potential packet access beyond hardware packet boundary"); return -EBUSY; } return 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -560,6 +560,8 @@ void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog); int nfp_bpf_jit(struct nfp_prog *prog); bool nfp_bpf_supported_opcode(u8 code); +bool nfp_bpf_offload_check_mtu(struct nfp_net *nn, struct bpf_prog *prog, + unsigned int mtu); int nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn_idx); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/bpf/offload.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/bpf/offload.c @@ -454,7 +454,8 @@ map_id_full = be64_to_cpu(cbe->map_ptr); map_id = map_id_full; - if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) + if (size_add(pkt_size, data_size) > INT_MAX || + len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) return -EINVAL; if (cbe->hdr.ver != NFP_CCM_ABI_VERSION) return -EINVAL; @@ -477,19 +478,28 @@ return 0; } +bool nfp_bpf_offload_check_mtu(struct nfp_net *nn, struct bpf_prog *prog, + unsigned int mtu) +{ + unsigned int fw_mtu, pkt_off; + + fw_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32; + pkt_off = min(prog->aux->max_pkt_offset, mtu); + + return fw_mtu < pkt_off; +} + static int nfp_net_bpf_load(struct nfp_net *nn, struct bpf_prog *prog, struct netlink_ext_ack *extack) { struct nfp_prog *nfp_prog = prog->aux->offload->dev_priv; - unsigned int fw_mtu, pkt_off, max_stack, max_prog_len; + unsigned int max_stack, max_prog_len; dma_addr_t dma_addr; void *img; int err; - fw_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32; - pkt_off = min(prog->aux->max_pkt_offset, nn->dp.netdev->mtu); - if (fw_mtu < pkt_off) { + if (nfp_bpf_offload_check_mtu(nn, prog, nn->dp.netdev->mtu)) { NL_SET_ERR_MSG_MOD(extack, "BPF offload not supported with potential packet access beyond HW packet split boundary"); return -EOPNOTSUPP; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c @@ -308,6 +308,11 @@ acti_netdevs = kmalloc_array(entry->slave_cnt, sizeof(*acti_netdevs), GFP_KERNEL); + if (!acti_netdevs) { + schedule_delayed_work(&lag->work, + NFP_FL_LAG_DELAY); + continue; + } /* Include sanity check in the loop. It may be that a bond has * changed between processing the last notification and the --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/flower/main.h +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/flower/main.h @@ -164,6 +164,7 @@ * @qos_rate_limiters: Current active qos rate limiters * @qos_stats_lock: Lock on qos stats updates * @pre_tun_rule_cnt: Number of pre-tunnel rules offloaded + * @merge_table: Hash table to store merged flows */ struct nfp_flower_priv { struct nfp_app *app; @@ -196,6 +197,7 @@ unsigned int qos_rate_limiters; spinlock_t qos_stats_lock; /* Protect the qos stats */ int pre_tun_rule_cnt; + struct rhashtable merge_table; }; /** @@ -310,6 +312,12 @@ }; extern const struct rhashtable_params nfp_flower_table_params; +extern const struct rhashtable_params merge_table_params; + +struct nfp_merge_info { + u64 parent_ctx; + struct rhash_head ht_node; +}; struct nfp_fl_stats_frame { __be32 stats_con_id; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -65,17 +65,17 @@ freed_stats_id = priv->stats_ring_size; /* Check for unallocated entries first. */ if (priv->stats_ids.init_unalloc > 0) { - if (priv->active_mem_unit == priv->total_mem_units) { - priv->stats_ids.init_unalloc--; - priv->active_mem_unit = 0; - } - *stats_context_id = FIELD_PREP(NFP_FL_STAT_ID_STAT, priv->stats_ids.init_unalloc - 1) | FIELD_PREP(NFP_FL_STAT_ID_MU_NUM, priv->active_mem_unit); - priv->active_mem_unit++; + + if (++priv->active_mem_unit == priv->total_mem_units) { + priv->stats_ids.init_unalloc--; + priv->active_mem_unit = 0; + } + return 0; } @@ -327,8 +327,14 @@ goto err_free_ctx_entry; } + /* Do net allocate a mask-id for pre_tun_rules. These flows are used to + * configure the pre_tun table and are never actually send to the + * firmware as an add-flow message. This causes the mask-id allocation + * on the firmware to get out of sync if allocated here. + */ new_mask_id = 0; - if (!nfp_check_mask_add(app, nfp_flow->mask_data, + if (!nfp_flow->pre_tun_rule.dev && + !nfp_check_mask_add(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, &nfp_flow->meta.flags, &new_mask_id)) { NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot allocate a new mask id"); @@ -359,7 +365,8 @@ goto err_remove_mask; } - if (!nfp_check_mask_remove(app, nfp_flow->mask_data, + if (!nfp_flow->pre_tun_rule.dev && + !nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, NULL, &new_mask_id)) { NL_SET_ERR_MSG_MOD(extack, "invalid entry: cannot release mask id"); @@ -374,8 +381,10 @@ return 0; err_remove_mask: - nfp_check_mask_remove(app, nfp_flow->mask_data, nfp_flow->meta.mask_len, - NULL, &new_mask_id); + if (!nfp_flow->pre_tun_rule.dev) + nfp_check_mask_remove(app, nfp_flow->mask_data, + nfp_flow->meta.mask_len, + NULL, &new_mask_id); err_remove_rhash: WARN_ON_ONCE(rhashtable_remove_fast(&priv->stats_ctx_table, &ctx_entry->ht_node, @@ -406,9 +415,10 @@ __nfp_modify_flow_metadata(priv, nfp_flow); - nfp_check_mask_remove(app, nfp_flow->mask_data, - nfp_flow->meta.mask_len, &nfp_flow->meta.flags, - &new_mask_id); + if (!nfp_flow->pre_tun_rule.dev) + nfp_check_mask_remove(app, nfp_flow->mask_data, + nfp_flow->meta.mask_len, &nfp_flow->meta.flags, + &new_mask_id); /* Update flow payload with mask ids. */ nfp_flow->unmasked_data[NFP_FL_MASK_ID_LOCATION] = new_mask_id; @@ -480,6 +490,12 @@ .automatic_shrinking = true, }; +const struct rhashtable_params merge_table_params = { + .key_offset = offsetof(struct nfp_merge_info, parent_ctx), + .head_offset = offsetof(struct nfp_merge_info, ht_node), + .key_len = sizeof(u64), +}; + int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, unsigned int host_num_mems) { @@ -496,6 +512,10 @@ if (err) goto err_free_flow_table; + err = rhashtable_init(&priv->merge_table, &merge_table_params); + if (err) + goto err_free_stats_ctx_table; + get_random_bytes(&priv->mask_id_seed, sizeof(priv->mask_id_seed)); /* Init ring buffer and unallocated mask_ids. */ @@ -503,7 +523,7 @@ kmalloc_array(NFP_FLOWER_MASK_ENTRY_RS, NFP_FLOWER_MASK_ELEMENT_RS, GFP_KERNEL); if (!priv->mask_ids.mask_id_free_list.buf) - goto err_free_stats_ctx_table; + goto err_free_merge_table; priv->mask_ids.init_unallocated = NFP_FLOWER_MASK_ENTRY_RS - 1; @@ -540,6 +560,8 @@ kfree(priv->mask_ids.last_used); err_free_mask_id: kfree(priv->mask_ids.mask_id_free_list.buf); +err_free_merge_table: + rhashtable_destroy(&priv->merge_table); err_free_stats_ctx_table: rhashtable_destroy(&priv->stats_ctx_table); err_free_flow_table: @@ -558,6 +580,8 @@ nfp_check_rhashtable_empty, NULL); rhashtable_free_and_destroy(&priv->stats_ctx_table, nfp_check_rhashtable_empty, NULL); + rhashtable_free_and_destroy(&priv->merge_table, + nfp_check_rhashtable_empty, NULL); kvfree(priv->stats); kfree(priv->mask_ids.mask_id_free_list.buf); kfree(priv->mask_ids.last_used); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -923,6 +923,8 @@ struct netlink_ext_ack *extack = NULL; struct nfp_fl_payload *merge_flow; struct nfp_fl_key_ls merge_key_ls; + struct nfp_merge_info *merge_info; + u64 parent_ctx = 0; int err; ASSERT_RTNL(); @@ -933,6 +935,15 @@ nfp_flower_is_merge_flow(sub_flow2)) return -EINVAL; + /* check if the two flows are already merged */ + parent_ctx = (u64)(be32_to_cpu(sub_flow1->meta.host_ctx_id)) << 32; + parent_ctx |= (u64)(be32_to_cpu(sub_flow2->meta.host_ctx_id)); + if (rhashtable_lookup_fast(&priv->merge_table, + &parent_ctx, merge_table_params)) { + nfp_flower_cmsg_warn(app, "The two flows are already merged.\n"); + return 0; + } + err = nfp_flower_can_merge(sub_flow1, sub_flow2); if (err) return err; @@ -974,16 +985,33 @@ if (err) goto err_release_metadata; + merge_info = kmalloc(sizeof(*merge_info), GFP_KERNEL); + if (!merge_info) { + err = -ENOMEM; + goto err_remove_rhash; + } + merge_info->parent_ctx = parent_ctx; + err = rhashtable_insert_fast(&priv->merge_table, &merge_info->ht_node, + merge_table_params); + if (err) + goto err_destroy_merge_info; + err = nfp_flower_xmit_flow(app, merge_flow, NFP_FLOWER_CMSG_TYPE_FLOW_MOD); if (err) - goto err_remove_rhash; + goto err_remove_merge_info; merge_flow->in_hw = true; sub_flow1->in_hw = false; return 0; +err_remove_merge_info: + WARN_ON_ONCE(rhashtable_remove_fast(&priv->merge_table, + &merge_info->ht_node, + merge_table_params)); +err_destroy_merge_info: + kfree(merge_info); err_remove_rhash: WARN_ON_ONCE(rhashtable_remove_fast(&priv->flow_table, &merge_flow->fl_node, @@ -1211,7 +1239,9 @@ { struct nfp_flower_priv *priv = app->priv; struct nfp_fl_payload_link *link, *temp; + struct nfp_merge_info *merge_info; struct nfp_fl_payload *origin; + u64 parent_ctx = 0; bool mod = false; int err; @@ -1248,8 +1278,22 @@ err_free_links: /* Clean any links connected with the merged flow. */ list_for_each_entry_safe(link, temp, &merge_flow->linked_flows, - merge_flow.list) + merge_flow.list) { + u32 ctx_id = be32_to_cpu(link->sub_flow.flow->meta.host_ctx_id); + + parent_ctx = (parent_ctx << 32) | (u64)(ctx_id); nfp_flower_unlink_flow(link); + } + + merge_info = rhashtable_lookup_fast(&priv->merge_table, + &parent_ctx, + merge_table_params); + if (merge_info) { + WARN_ON_ONCE(rhashtable_remove_fast(&priv->merge_table, + &merge_info->ht_node, + merge_table_params)); + kfree(merge_info); + } kfree(merge_flow->action_data); kfree(merge_flow->mask_data); @@ -1368,7 +1412,8 @@ ctx_id = be32_to_cpu(sub_flow->meta.host_ctx_id); priv->stats[ctx_id].pkts += pkts; priv->stats[ctx_id].bytes += bytes; - max_t(u64, priv->stats[ctx_id].used, used); + priv->stats[ctx_id].used = max_t(u64, used, + priv->stats[ctx_id].used); } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -588,12 +588,12 @@ int port, bool mod) { struct nfp_flower_priv *priv = app->priv; - int ida_idx = NFP_MAX_MAC_INDEX, err; struct nfp_tun_offloaded_mac *entry; + int ida_idx = -1, err; u16 nfp_mac_idx = 0; entry = nfp_tunnel_lookup_offloaded_macs(app, netdev->dev_addr); - if (entry && nfp_tunnel_is_mac_idx_global(entry->index)) { + if (entry && (nfp_tunnel_is_mac_idx_global(entry->index) || netif_is_lag_port(netdev))) { if (entry->bridge_count || !nfp_flower_is_supported_bridge(netdev)) { nfp_tunnel_offloaded_macs_inc_ref_and_link(entry, @@ -663,7 +663,7 @@ err_free_entry: kfree(entry); err_free_ida: - if (ida_idx != NFP_MAX_MAC_INDEX) + if (ida_idx != -1) ida_simple_remove(&priv->tun.mac_off_ids, ida_idx); return err; @@ -677,6 +677,7 @@ struct nfp_flower_repr_priv *repr_priv; struct nfp_tun_offloaded_mac *entry; struct nfp_repr *repr; + u16 nfp_mac_idx; int ida_idx; entry = nfp_tunnel_lookup_offloaded_macs(app, mac); @@ -695,8 +696,6 @@ entry->bridge_count--; if (!entry->bridge_count && entry->ref_count) { - u16 nfp_mac_idx; - nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT; if (__nfp_tunnel_offload_mac(app, mac, nfp_mac_idx, false)) { @@ -712,7 +711,6 @@ /* If MAC is now used by 1 repr set the offloaded MAC index to port. */ if (entry->ref_count == 1 && list_is_singular(&entry->repr_list)) { - u16 nfp_mac_idx; int port, err; repr_priv = list_first_entry(&entry->repr_list, @@ -740,8 +738,14 @@ WARN_ON_ONCE(rhashtable_remove_fast(&priv->tun.offloaded_macs, &entry->ht_node, offloaded_macs_params)); + + if (nfp_flower_is_supported_bridge(netdev)) + nfp_mac_idx = entry->index & ~NFP_TUN_PRE_TUN_IDX_BIT; + else + nfp_mac_idx = entry->index; + /* If MAC has global ID then extract and free the ida entry. */ - if (nfp_tunnel_is_mac_idx_global(entry->index)) { + if (nfp_tunnel_is_mac_idx_global(nfp_mac_idx)) { ida_idx = nfp_tunnel_get_ida_from_global_mac_idx(entry->index); ida_simple_remove(&priv->tun.mac_off_ids, ida_idx); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfp_asm.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfp_asm.c @@ -196,7 +196,7 @@ } reg->dst_lmextn = swreg_lmextn(dst); - reg->src_lmextn = swreg_lmextn(lreg) | swreg_lmextn(rreg); + reg->src_lmextn = swreg_lmextn(lreg) || swreg_lmextn(rreg); return 0; } @@ -277,7 +277,7 @@ } reg->dst_lmextn = swreg_lmextn(dst); - reg->src_lmextn = swreg_lmextn(lreg) | swreg_lmextn(rreg); + reg->src_lmextn = swreg_lmextn(lreg) || swreg_lmextn(rreg); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfp_net.h +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfp_net.h @@ -557,7 +557,6 @@ * @exn_name: Name for Exception interrupt * @shared_handler: Handler for shared interrupts * @shared_name: Name for shared interrupt - * @me_freq_mhz: ME clock_freq (MHz) * @reconfig_lock: Protects @reconfig_posted, @reconfig_timer_active, * @reconfig_sync_present and HW reconfiguration request * regs/machinery from async requests (sync must take @@ -639,8 +638,6 @@ irq_handler_t shared_handler; char shared_name[IFNAMSIZ + 8]; - u32 me_freq_mhz; - bool link_up; spinlock_t link_status_lock; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -2626,8 +2626,8 @@ snprintf(r_vec->name, sizeof(r_vec->name), "%s-rxtx-%d", nfp_net_name(nn), idx); - err = request_irq(r_vec->irq_vector, r_vec->handler, 0, r_vec->name, - r_vec); + err = request_irq(r_vec->irq_vector, r_vec->handler, IRQF_NO_AUTOEN, + r_vec->name, r_vec); if (err) { if (nn->dp.netdev) netif_napi_del(&r_vec->napi); @@ -2637,7 +2637,6 @@ nn_err(nn, "Error requesting IRQ %d\n", r_vec->irq_vector); return err; } - disable_irq(r_vec->irq_vector); irq_set_affinity_hint(r_vec->irq_vector, &r_vec->affinity_mask); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -273,6 +273,8 @@ port = nfp_port_from_netdev(netdev); eth_port = nfp_port_get_eth_port(port); if (eth_port) { + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); cmd->base.autoneg = eth_port->aneg != NFP_ANEG_DISABLED ? AUTONEG_ENABLE : AUTONEG_DISABLE; nfp_net_set_fec_link_mode(eth_port, cmd); @@ -731,8 +733,8 @@ struct nfp_eth_table_port *eth_port; struct nfp_port *port; - param->active_fec = ETHTOOL_FEC_NONE_BIT; - param->fec = ETHTOOL_FEC_NONE_BIT; + param->active_fec = ETHTOOL_FEC_NONE; + param->fec = ETHTOOL_FEC_NONE; port = nfp_port_from_netdev(netdev); eth_port = nfp_port_get_eth_port(port); @@ -1125,6 +1127,11 @@ u8 data; port = nfp_port_from_netdev(netdev); + if (!port) + return -EOPNOTSUPP; + + /* update port state to get latest interface */ + set_bit(NFP_PORT_CHANGED, &port->flags); eth_port = nfp_port_get_eth_port(port); if (!eth_port) return -EOPNOTSUPP; @@ -1267,7 +1274,7 @@ * ME timestamp ticks. There are 16 ME clock cycles for each timestamp * count. */ - factor = nn->me_freq_mhz / 16; + factor = nn->tlv_caps.me_freq_mhz / 16; /* Each pair of (usecs, max_frames) fields specifies that interrupts * should be coalesced until --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c @@ -542,11 +542,13 @@ const u32 barcfg_msix_general = NFP_PCIE_BAR_PCIE2CPP_MapType( NFP_PCIE_BAR_PCIE2CPP_MapType_GENERAL) | - NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT; + NFP_PCIE_BAR_PCIE2CPP_LengthSelect( + NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT); const u32 barcfg_msix_xpb = NFP_PCIE_BAR_PCIE2CPP_MapType( NFP_PCIE_BAR_PCIE2CPP_MapType_BULK) | - NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT | + NFP_PCIE_BAR_PCIE2CPP_LengthSelect( + NFP_PCIE_BAR_PCIE2CPP_LengthSelect_32BIT) | NFP_PCIE_BAR_PCIE2CPP_Target_BaseAddress( NFP_CPP_TARGET_ISLAND_XPB); const u32 barcfg_explicit[4] = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ linux-oracle-5.4.0/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -803,8 +803,10 @@ return -ENOMEM; cache = kzalloc(sizeof(*cache), GFP_KERNEL); - if (!cache) + if (!cache) { + nfp_cpp_area_free(area); return -ENOMEM; + } cache->id = 0; cache->addr = 0; @@ -872,7 +874,6 @@ } /* Adjust the start address to be cache size aligned */ - cache->id = id; cache->addr = addr & ~(u64)(cache->size - 1); /* Re-init to the new ID and address */ @@ -892,6 +893,8 @@ return NULL; } + cache->id = id; + exit: /* Adjust offset */ *offset = addr - cache->addr; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ni/nixge.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ni/nixge.c @@ -249,25 +249,26 @@ struct sk_buff *skb; int i; - for (i = 0; i < RX_BD_NUM; i++) { - phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], - phys); - - dma_unmap_single(ndev->dev.parent, phys_addr, - NIXGE_MAX_JUMBO_FRAME_SIZE, - DMA_FROM_DEVICE); - - skb = (struct sk_buff *)(uintptr_t) - nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], - sw_id_offset); - dev_kfree_skb(skb); - } + if (priv->rx_bd_v) { + for (i = 0; i < RX_BD_NUM; i++) { + phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], + phys); + + dma_unmap_single(ndev->dev.parent, phys_addr, + NIXGE_MAX_JUMBO_FRAME_SIZE, + DMA_FROM_DEVICE); + + skb = (struct sk_buff *)(uintptr_t) + nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], + sw_id_offset); + dev_kfree_skb(skb); + } - if (priv->rx_bd_v) dma_free_coherent(ndev->dev.parent, sizeof(*priv->rx_bd_v) * RX_BD_NUM, priv->rx_bd_v, priv->rx_bd_p); + } if (priv->tx_skb) devm_kfree(ndev->dev.parent, priv->tx_skb); @@ -899,6 +900,7 @@ err_rx_irq: free_irq(priv->tx_irq, ndev); err_tx_irq: + napi_disable(&priv->napi); phy_stop(phy); phy_disconnect(phy); tasklet_kill(&priv->dma_err_tasklet); @@ -1318,19 +1320,21 @@ netif_napi_add(ndev, &priv->napi, nixge_poll, NAPI_POLL_WEIGHT); err = nixge_of_get_resources(pdev); if (err) - return err; + goto free_netdev; __nixge_hw_set_mac_address(ndev); priv->tx_irq = platform_get_irq_byname(pdev, "tx"); if (priv->tx_irq < 0) { netdev_err(ndev, "could not find 'tx' irq"); - return priv->tx_irq; + err = priv->tx_irq; + goto free_netdev; } priv->rx_irq = platform_get_irq_byname(pdev, "rx"); if (priv->rx_irq < 0) { netdev_err(ndev, "could not find 'rx' irq"); - return priv->rx_irq; + err = priv->rx_irq; + goto free_netdev; } priv->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/nvidia/forcedeth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/nvidia/forcedeth.c @@ -6099,6 +6099,7 @@ return 0; out_error: + nv_mgmt_release_sema(dev); if (phystate_orig) writel(phystate|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); out_freering: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/nxp/lpc_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/nxp/lpc_eth.c @@ -815,7 +815,8 @@ if (mdiobus_register(pldat->mii_bus)) goto err_out_unregister_bus; - if (lpc_mii_probe(pldat->ndev) != 0) + err = lpc_mii_probe(pldat->ndev); + if (err) goto err_out_unregister_bus; return 0; @@ -1006,9 +1007,6 @@ napi_disable(&pldat->napi); netif_stop_queue(ndev); - if (ndev->phydev) - phy_stop(ndev->phydev); - spin_lock_irqsave(&pldat->lock, flags); __lpc_eth_reset(pldat); netif_carrier_off(ndev); @@ -1016,6 +1014,8 @@ writel(0, LPC_ENET_MAC2(pldat->net_base)); spin_unlock_irqrestore(&pldat->lock, flags); + if (ndev->phydev) + phy_stop(ndev->phydev); clk_disable_unprepare(pldat->clk); return 0; @@ -1470,6 +1470,7 @@ { struct net_device *ndev = platform_get_drvdata(pdev); struct netdata_local *pldat; + int ret; if (device_may_wakeup(&pdev->dev)) disable_irq_wake(ndev->irq); @@ -1479,7 +1480,9 @@ pldat = netdev_priv(ndev); /* Enable interface clock */ - clk_enable(pldat->clk); + ret = clk_enable(pldat->clk); + if (ret) + return ret; /* Reset and initialize */ __lpc_eth_reset(pldat); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -107,7 +107,7 @@ { u8 *data = skb->data; unsigned int offset; - u16 *hi, *id; + u16 hi, id; u32 lo; if (ptp_classify_raw(skb) == PTP_CLASS_NONE) @@ -118,14 +118,11 @@ if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid)) return 0; - hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID); - id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); + hi = get_unaligned_be16(data + offset + OFF_PTP_SOURCE_UUID + 0); + lo = get_unaligned_be32(data + offset + OFF_PTP_SOURCE_UUID + 2); + id = get_unaligned_be16(data + offset + OFF_PTP_SEQUENCE_ID); - memcpy(&lo, &hi[1], sizeof(lo)); - - return (uid_hi == *hi && - uid_lo == lo && - seqid == *id); + return (uid_hi == hi && uid_lo == lo && seqid == id); } static void @@ -135,7 +132,6 @@ struct pci_dev *pdev; u64 ns; u32 hi, lo, val; - u16 uid, seq; if (!adapter->hwts_rx_en) return; @@ -151,10 +147,7 @@ lo = pch_src_uuid_lo_read(pdev); hi = pch_src_uuid_hi_read(pdev); - uid = hi & 0xffff; - seq = (hi >> 16) & 0xffff; - - if (!pch_ptp_match(skb, htons(uid), htonl(lo), htons(seq))) + if (!pch_ptp_match(skb, hi, lo, hi >> 16)) goto out; ns = pch_rx_snap_read(pdev); @@ -1173,6 +1166,7 @@ buffer_info->dma = 0; buffer_info->time_stamp = 0; tx_ring->next_to_use = ring_num; + dev_kfree_skb_any(skb); return; } buffer_info->mapped = true; @@ -2487,6 +2481,7 @@ unregister_netdev(netdev); pch_gbe_phy_hw_reset(&adapter->hw); + pci_dev_put(adapter->ptp_pdev); free_netdev(netdev); } @@ -2535,9 +2530,13 @@ adapter->pdev = pdev; adapter->hw.back = adapter; adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR]; + adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data; - if (adapter->pdata && adapter->pdata->platform_init) - adapter->pdata->platform_init(pdev); + if (adapter->pdata && adapter->pdata->platform_init) { + ret = adapter->pdata->platform_init(pdev); + if (ret) + goto err_free_netdev; + } adapter->ptp_pdev = pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus), @@ -2564,7 +2563,7 @@ /* setup the private structure */ ret = pch_gbe_sw_init(adapter); if (ret) - goto err_free_netdev; + goto err_put_dev; /* Initialize PHY */ ret = pch_gbe_init_phy(adapter); @@ -2622,6 +2621,8 @@ err_free_adapter: pch_gbe_phy_hw_reset(&adapter->hw); +err_put_dev: + pci_dev_put(adapter->ptp_pdev); err_free_netdev: free_netdev(netdev); return ret; @@ -2632,7 +2633,7 @@ */ static int pch_gbe_minnow_platform_init(struct pci_dev *pdev) { - unsigned long flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH | GPIOF_EXPORT; + unsigned long flags = GPIOF_OUT_INIT_HIGH; unsigned gpio = MINNOW_PHY_RESET_GPIO; int ret; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pasemi/pasemi_mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1078,16 +1078,20 @@ mac->tx = pasemi_mac_setup_tx_resources(dev); - if (!mac->tx) + if (!mac->tx) { + ret = -ENOMEM; goto out_tx_ring; + } /* We might already have allocated rings in case mtu was changed * before interface was brought up. */ if (dev->mtu > 1500 && !mac->num_cs) { pasemi_mac_setup_csrings(mac); - if (!mac->num_cs) + if (!mac->num_cs) { + ret = -ENOMEM; goto out_tx_ring; + } } /* Zero out rmon counters */ @@ -1419,7 +1423,7 @@ write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), 2); } -static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) { struct pasemi_mac * const mac = netdev_priv(dev); struct pasemi_mac_txring * const txring = tx_ring(mac); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -102,15 +102,18 @@ void *p) { struct ionic_lif *lif = netdev_priv(netdev); + unsigned int offset; unsigned int size; regs->version = IONIC_DEV_CMD_REG_VERSION; + offset = 0; size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32); - memcpy_fromio(p, lif->ionic->idev.dev_info_regs->words, size); + memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size); + offset += size; size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32); - memcpy_fromio(p, lif->ionic->idev.dev_cmd_regs->words, size); + memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size); } static int ionic_get_link_ksettings(struct net_device *netdev, @@ -122,6 +125,11 @@ ethtool_link_ksettings_zero_link_mode(ks, supported); + if (!idev->port_info) { + netdev_err(netdev, "port_info not initialized\n"); + return -EOPNOTSUPP; + } + /* The port_info data is found in a DMA space that the NIC keeps * up-to-date, so there's no need to request the data from the * NIC, we already have it in our memory space. @@ -565,7 +573,7 @@ info->data = lif->nxqs; break; default: - netdev_err(netdev, "Command parameter %d is not supported\n", + netdev_dbg(netdev, "Command parameter %d is not supported\n", info->cmd); err = -EOPNOTSUPP; } @@ -703,8 +711,8 @@ len = min_t(u32, sizeof(xcvr->sprom), ee->len); do { - memcpy(data, xcvr->sprom, len); - memcpy(tbuf, xcvr->sprom, len); + memcpy(data, &xcvr->sprom[ee->offset], len); + memcpy(tbuf, &xcvr->sprom[ee->offset], len); /* Let's make sure we got a consistent copy */ if (!memcmp(data, tbuf, len)) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pensando/ionic/ionic_if.h +++ linux-oracle-5.4.0/drivers/net/ethernet/pensando/ionic/ionic_if.h @@ -862,7 +862,7 @@ #define IONIC_RXQ_COMP_CSUM_F_VLAN 0x40 #define IONIC_RXQ_COMP_CSUM_F_CALC 0x80 u8 pkt_type_color; -#define IONIC_RXQ_COMP_PKT_TYPE_MASK 0x0f +#define IONIC_RXQ_COMP_PKT_TYPE_MASK 0x7f }; enum ionic_pkt_type { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ linux-oracle-5.4.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -143,7 +143,7 @@ name = dev_name(dev); snprintf(intr->name, sizeof(intr->name), - "%s-%s-%s", IONIC_DRV_NAME, name, q->name); + "%.5s-%.16s-%.8s", IONIC_DRV_NAME, name, q->name); return devm_request_irq(dev, intr->vector, ionic_isr, 0, intr->name, &qcq->napi); @@ -167,10 +167,10 @@ return 0; } -static void ionic_intr_free(struct ionic_lif *lif, int index) +static void ionic_intr_free(struct ionic *ionic, int index) { - if (index != INTR_INDEX_NOT_ASSIGNED && index < lif->ionic->nintrs) - clear_bit(index, lif->ionic->intrs); + if (index != INTR_INDEX_NOT_ASSIGNED && index < ionic->nintrs) + clear_bit(index, ionic->intrs); } static int ionic_qcq_enable(struct ionic_qcq *qcq) @@ -190,6 +190,7 @@ .oper = IONIC_Q_ENABLE, }, }; + int ret; idev = &lif->ionic->idev; dev = lif->ionic->dev; @@ -197,16 +198,22 @@ dev_dbg(dev, "q_enable.index %d q_enable.qtype %d\n", ctx.cmd.q_control.index, ctx.cmd.q_control.type); + if (qcq->flags & IONIC_QCQ_F_INTR) + ionic_intr_clean(idev->intr_ctrl, qcq->intr.index); + + ret = ionic_adminq_post_wait(lif, &ctx); + if (ret) + return ret; + if (qcq->flags & IONIC_QCQ_F_INTR) { + napi_enable(&qcq->napi); irq_set_affinity_hint(qcq->intr.vector, &qcq->intr.affinity_mask); - napi_enable(&qcq->napi); - ionic_intr_clean(idev->intr_ctrl, qcq->intr.index); ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, IONIC_INTR_MASK_CLEAR); } - return ionic_adminq_post_wait(lif, &ctx); + return 0; } static int ionic_qcq_disable(struct ionic_qcq *qcq) @@ -247,7 +254,6 @@ static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq) { struct ionic_dev *idev = &lif->ionic->idev; - struct device *dev = lif->ionic->dev; if (!qcq) return; @@ -260,7 +266,6 @@ if (qcq->flags & IONIC_QCQ_F_INTR) { ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, IONIC_INTR_MASK_SET); - devm_free_irq(dev, qcq->intr.vector, &qcq->napi); netif_napi_del(&qcq->napi); } @@ -278,8 +283,12 @@ qcq->base = NULL; qcq->base_pa = 0; - if (qcq->flags & IONIC_QCQ_F_INTR) - ionic_intr_free(lif, qcq->intr.index); + if (qcq->flags & IONIC_QCQ_F_INTR) { + irq_set_affinity_hint(qcq->intr.vector, NULL); + devm_free_irq(dev, qcq->intr.vector, &qcq->napi); + qcq->intr.vector = 0; + ionic_intr_free(lif->ionic, qcq->intr.index); + } devm_kfree(dev, qcq->cq.info); qcq->cq.info = NULL; @@ -321,11 +330,6 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq, struct ionic_qcq *n_qcq) { - if (WARN_ON(n_qcq->flags & IONIC_QCQ_F_INTR)) { - ionic_intr_free(n_qcq->cq.lif, n_qcq->intr.index); - n_qcq->flags &= ~IONIC_QCQ_F_INTR; - } - n_qcq->intr.vector = src_qcq->intr.vector; n_qcq->intr.index = src_qcq->intr.index; } @@ -409,8 +413,15 @@ ionic_intr_mask_assert(idev->intr_ctrl, new->intr.index, IONIC_INTR_MASK_SET); - new->intr.cpu = new->intr.index % num_online_cpus(); - if (cpu_online(new->intr.cpu)) + err = ionic_request_irq(lif, new); + if (err) { + netdev_warn(lif->netdev, "irq request failed %d\n", err); + goto err_out_free_intr; + } + + new->intr.cpu = cpumask_local_spread(new->intr.index, + dev_to_node(dev)); + if (new->intr.cpu != -1) cpumask_set_cpu(new->intr.cpu, &new->intr.affinity_mask); } else { @@ -422,13 +433,13 @@ if (!new->cq.info) { netdev_err(lif->netdev, "Cannot allocate completion queue info\n"); err = -ENOMEM; - goto err_out_free_intr; + goto err_out_free_irq; } err = ionic_cq_init(lif, &new->cq, &new->intr, num_descs, cq_desc_size); if (err) { netdev_err(lif->netdev, "Cannot initialize completion queue\n"); - goto err_out_free_intr; + goto err_out_free_irq; } new->base = dma_alloc_coherent(dev, total_size, &new->base_pa, @@ -436,7 +447,7 @@ if (!new->base) { netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n"); err = -ENOMEM; - goto err_out_free_intr; + goto err_out_free_irq; } new->total_size = total_size; @@ -462,8 +473,12 @@ return 0; +err_out_free_irq: + if (flags & IONIC_QCQ_F_INTR) + devm_free_irq(dev, new->intr.vector, &new->napi); err_out_free_intr: - ionic_intr_free(lif, new->intr.index); + if (flags & IONIC_QCQ_F_INTR) + ionic_intr_free(lif->ionic, new->intr.index); err_out: dev_err(dev, "qcq alloc of %s%d failed %d\n", name, index, err); return err; @@ -638,12 +653,6 @@ netif_napi_add(lif->netdev, &qcq->napi, ionic_rx_napi, NAPI_POLL_WEIGHT); - err = ionic_request_irq(lif, qcq); - if (err) { - netif_napi_del(&qcq->napi); - return err; - } - qcq->flags |= IONIC_QCQ_F_INITED; ionic_debugfs_add_qcq(lif, qcq); @@ -666,7 +675,7 @@ eid = le64_to_cpu(comp->event.eid); /* Have we run out of new completions to process? */ - if (eid <= lif->last_eid) + if ((s64)(eid - lif->last_eid) <= 0) return false; lif->last_eid = eid; @@ -809,8 +818,7 @@ if (f) return 0; - netdev_dbg(lif->netdev, "rx_filter add ADDR %pM (id %d)\n", addr, - ctx.comp.rx_filter_add.filter_id); + netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr); memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN); err = ionic_adminq_post_wait(lif, &ctx); @@ -839,6 +847,9 @@ return -ENOENT; } + netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", + addr, f->filter_id); + ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); ionic_rx_filter_free(lif, f); spin_unlock_bh(&lif->rx_filters.lock); @@ -847,9 +858,6 @@ if (err) return err; - netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", addr, - ctx.cmd.rx_filter_del.filter_id); - return 0; } @@ -913,6 +921,10 @@ static int ionic_addr_del(struct net_device *netdev, const u8 *addr) { + /* Don't delete our own address from the uc list */ + if (ether_addr_equal(addr, netdev->dev_addr)) + return 0; + return ionic_lif_addr(netdev_priv(netdev), addr, false); } @@ -1187,6 +1199,7 @@ netdev->hw_features |= netdev->hw_enc_features; netdev->features |= netdev->hw_features; + netdev->vlan_features |= netdev->features & ~NETIF_F_VLAN_FEATURES; netdev->priv_flags |= IFF_UNICAST_FLT; @@ -1290,13 +1303,11 @@ }; int err; + netdev_dbg(netdev, "rx_filter add VLAN %d\n", vid); err = ionic_adminq_post_wait(lif, &ctx); if (err) return err; - netdev_dbg(netdev, "rx_filter add VLAN %d (id %d)\n", vid, - ctx.comp.rx_filter_add.filter_id); - return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx); } @@ -1321,8 +1332,8 @@ return -ENOENT; } - netdev_dbg(netdev, "rx_filter del VLAN %d (id %d)\n", vid, - le32_to_cpu(ctx.cmd.rx_filter_del.filter_id)); + netdev_dbg(netdev, "rx_filter del VLAN %d (id %d)\n", + vid, f->filter_id); ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id); ionic_rx_filter_free(lif, f); @@ -1364,12 +1375,9 @@ static int ionic_lif_rss_init(struct ionic_lif *lif) { - u8 rss_key[IONIC_RSS_HASH_KEY_SIZE]; unsigned int tbl_sz; unsigned int i; - netdev_rss_key_fill(rss_key, IONIC_RSS_HASH_KEY_SIZE); - lif->rss_types = IONIC_RSS_TYPE_IPV4 | IONIC_RSS_TYPE_IPV4_TCP | IONIC_RSS_TYPE_IPV4_UDP | @@ -1382,12 +1390,18 @@ for (i = 0; i < tbl_sz; i++) lif->rss_ind_tbl[i] = ethtool_rxfh_indir_default(i, lif->nxqs); - return ionic_lif_rss_config(lif, lif->rss_types, rss_key, NULL); + return ionic_lif_rss_config(lif, lif->rss_types, NULL, NULL); } -static int ionic_lif_rss_deinit(struct ionic_lif *lif) +static void ionic_lif_rss_deinit(struct ionic_lif *lif) { - return ionic_lif_rss_config(lif, 0x0, NULL, NULL); + int tbl_sz; + + tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz); + memset(lif->rss_ind_tbl, 0, tbl_sz); + memset(lif->rss_hash_key, 0, IONIC_RSS_HASH_KEY_SIZE); + + ionic_lif_rss_config(lif, 0x0, NULL, NULL); } static void ionic_txrx_disable(struct ionic_lif *lif) @@ -1710,6 +1724,7 @@ dev_err(dev, "Failed to allocate rss indirection table, aborting\n"); goto err_out_free_qcqs; } + netdev_rss_key_fill(lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE); list_add_tail(&lif->list, &ionic->lifs); @@ -1855,18 +1870,14 @@ netif_napi_add(lif->netdev, &qcq->napi, ionic_adminq_napi, NAPI_POLL_WEIGHT); - err = ionic_request_irq(lif, qcq); - if (err) { - netdev_warn(lif->netdev, "adminq irq request failed %d\n", err); - netif_napi_del(&qcq->napi); - return err; - } - napi_enable(&qcq->napi); - if (qcq->flags & IONIC_QCQ_F_INTR) + if (qcq->flags & IONIC_QCQ_F_INTR) { + irq_set_affinity_hint(qcq->intr.vector, + &qcq->intr.affinity_mask); ionic_intr_mask(idev->intr_ctrl, qcq->intr.index, IONIC_INTR_MASK_CLEAR); + } qcq->flags |= IONIC_QCQ_F_INITED; @@ -1989,7 +2000,7 @@ return -EINVAL; } - lif->dbid_inuse = bitmap_alloc(lif->dbid_count, GFP_KERNEL); + lif->dbid_inuse = bitmap_zalloc(lif->dbid_count, GFP_KERNEL); if (!lif->dbid_inuse) { dev_err(dev, "Failed alloc doorbell id bitmap, aborting\n"); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c +++ linux-oracle-5.4.0/drivers/net/ethernet/pensando/ionic/ionic_rx_filter.c @@ -36,10 +36,12 @@ spin_lock_init(&lif->rx_filters.lock); + spin_lock_bh(&lif->rx_filters.lock); for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { INIT_HLIST_HEAD(&lif->rx_filters.by_hash[i]); INIT_HLIST_HEAD(&lif->rx_filters.by_id[i]); } + spin_unlock_bh(&lif->rx_filters.lock); return 0; } @@ -51,11 +53,13 @@ struct hlist_node *tmp; unsigned int i; + spin_lock_bh(&lif->rx_filters.lock); for (i = 0; i < IONIC_RX_FILTER_HLISTS; i++) { head = &lif->rx_filters.by_id[i]; hlist_for_each_entry_safe(f, tmp, head, by_id) ionic_rx_filter_free(lif, f); } + spin_unlock_bh(&lif->rx_filters.lock); } int ionic_rx_filter_save(struct ionic_lif *lif, u32 flow_id, u16 rxq_index, @@ -91,6 +95,7 @@ f->filter_id = le32_to_cpu(ctx->comp.rx_filter_add.filter_id); f->rxq_index = rxq_index; memcpy(&f->cmd, ac, sizeof(f->cmd)); + netdev_dbg(lif->netdev, "rx_filter add filter_id %d\n", f->filter_id); INIT_HLIST_NODE(&f->by_hash); INIT_HLIST_NODE(&f->by_id); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -257,7 +257,7 @@ unsigned int len; unsigned int i; - len = netdev->mtu + ETH_HLEN; + len = netdev->mtu + ETH_HLEN + VLAN_HLEN; for (i = ionic_q_space_avail(q); i; i--) { skb = ionic_rx_skb_alloc(q, len, &dma_addr); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/Kconfig @@ -78,6 +78,7 @@ depends on PCI select ZLIB_INFLATE select CRC8 + select CRC32 select NET_DEVLINK ---help--- This enables the support for ... --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -564,11 +564,6 @@ .ndo_set_features = netxen_set_features, }; -static inline bool netxen_function_zero(struct pci_dev *pdev) -{ - return (PCI_FUNC(pdev->devfn) == 0) ? true : false; -} - static inline void netxen_set_interrupt_mode(struct netxen_adapter *adapter, u32 mode) { @@ -664,7 +659,7 @@ netxen_initialize_interrupt_registers(adapter); netxen_set_msix_bit(pdev, 0); - if (netxen_function_zero(pdev)) { + if (adapter->portnum == 0) { if (!netxen_setup_msi_interrupts(adapter, num_msix)) netxen_set_interrupt_mode(adapter, NETXEN_MSI_MODE); else @@ -1607,6 +1602,8 @@ free_netdev(netdev); err_out_free_res: + if (NX_IS_REVISION_P3(pdev->revision)) + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_cxt.c @@ -396,7 +396,7 @@ vf_tids += segs[NUM_TASK_PF_SEGMENTS].count; } - iids->vf_cids += vf_cids * p_mngr->vf_count; + iids->vf_cids = vf_cids; iids->tids += vf_tids * p_mngr->vf_count; DP_VERBOSE(p_hwfn, QED_MSG_ILT, @@ -1023,6 +1023,7 @@ p_dma->p_virt = NULL; } kfree(p_mngr->ilt_shadow); + p_mngr->ilt_shadow = NULL; } static int qed_ilt_blk_alloc(struct qed_hwfn *p_hwfn, @@ -2073,8 +2074,8 @@ num_srqs = min_t(u32, QED_RDMA_MAX_SRQS, p_params->num_srqs); if (p_hwfn->mcp_info->func_info.protocol == QED_PCI_ETH_RDMA) { - DP_NOTICE(p_hwfn, - "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n"); + DP_VERBOSE(p_hwfn, QED_MSG_SP, + "Current day drivers don't support RoCE & iWARP simultaneously on the same PF. Default to RoCE-only\n"); p_hwfn->hw_info.personality = QED_PCI_ETH_ROCE; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -1293,9 +1293,11 @@ p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC; p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; + BUILD_BUG_ON(sizeof(dcbx_info->operational.params) != + sizeof(p_hwfn->p_dcbx_info->set.config.params)); memcpy(&p_hwfn->p_dcbx_info->set.config.params, &dcbx_info->operational.params, - sizeof(struct qed_dcbx_admin_params)); + sizeof(p_hwfn->p_dcbx_info->set.config.params)); p_hwfn->p_dcbx_info->set.config.valid = true; memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_debug.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_debug.c @@ -8197,6 +8197,10 @@ DP_ERR(cdev, "qed_dbg_mcp_trace failed. rc = %d\n", rc); } + /* Re-populate nvm attribute info */ + qed_mcp_nvm_info_free(p_hwfn); + qed_mcp_nvm_info_populate(p_hwfn); + /* nvm cfg1 */ rc = qed_dbg_nvm_image(cdev, (u8 *)buffer + offset + REGDUMP_HEADER_SIZE, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -1368,6 +1368,8 @@ void qed_resc_free(struct qed_dev *cdev) { + struct qed_rdma_info *rdma_info; + struct qed_hwfn *p_hwfn; int i; if (IS_VF(cdev)) { @@ -1385,7 +1387,8 @@ qed_llh_free(cdev); for_each_hwfn(cdev, i) { - struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; + p_hwfn = cdev->hwfns + i; + rdma_info = p_hwfn->p_rdma_info; qed_cxt_mngr_free(p_hwfn); qed_qm_info_free(p_hwfn); @@ -1404,8 +1407,10 @@ qed_ooo_free(p_hwfn); } - if (QED_IS_RDMA_PERSONALITY(p_hwfn)) + if (QED_IS_RDMA_PERSONALITY(p_hwfn) && rdma_info) { + qed_spq_unregister_async_cb(p_hwfn, rdma_info->proto); qed_rdma_info_free(p_hwfn); + } qed_iov_free(p_hwfn); qed_l2_free(p_hwfn); @@ -3087,7 +3092,7 @@ } /* Log and clear previous pglue_b errors if such exist */ - qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt); + qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_main_ptt, true); /* Enable the PF's internal FID_enable in the PXP */ rc = qed_pglueb_set_pfid_enable(p_hwfn, p_hwfn->p_main_ptt, @@ -4137,7 +4142,8 @@ cdev->mf_bits = BIT(QED_MF_LLH_MAC_CLSS) | BIT(QED_MF_LLH_PROTO_CLSS) | BIT(QED_MF_LL2_NON_UNICAST) | - BIT(QED_MF_INTER_PF_SWITCH); + BIT(QED_MF_INTER_PF_SWITCH) | + BIT(QED_MF_DISABLE_ARFS); break; case NVM_CFG1_GLOB_MF_MODE_DEFAULT: cdev->mf_bits = BIT(QED_MF_LLH_MAC_CLSS) | @@ -4150,6 +4156,14 @@ DP_INFO(p_hwfn, "Multi function mode is 0x%lx\n", cdev->mf_bits); + + /* In CMT the PF is unknown when the GFS block processes the + * packet. Therefore cannot use searcher as it has a per PF + * database, and thus ARFS must be disabled. + * + */ + if (QED_IS_CMT(cdev)) + cdev->mf_bits |= BIT(QED_MF_DISABLE_ARFS); } DP_INFO(p_hwfn, "Multi function mode is 0x%lx\n", @@ -4418,12 +4432,6 @@ return 0; } -static void qed_nvm_info_free(struct qed_hwfn *p_hwfn) -{ - kfree(p_hwfn->nvm_info.image_att); - p_hwfn->nvm_info.image_att = NULL; -} - static int qed_hw_prepare_single(struct qed_hwfn *p_hwfn, void __iomem *p_regview, void __iomem *p_doorbells, @@ -4508,7 +4516,7 @@ return rc; err3: if (IS_LEAD_HWFN(p_hwfn)) - qed_nvm_info_free(p_hwfn); + qed_mcp_nvm_info_free(p_hwfn); err2: if (IS_LEAD_HWFN(p_hwfn)) qed_iov_free_hw_info(p_hwfn->cdev); @@ -4569,7 +4577,7 @@ if (rc) { if (IS_PF(cdev)) { qed_init_free(p_hwfn); - qed_nvm_info_free(p_hwfn); + qed_mcp_nvm_info_free(p_hwfn); qed_mcp_free(p_hwfn); qed_hw_hwfn_free(p_hwfn); } @@ -4603,7 +4611,7 @@ qed_iov_free_hw_info(cdev); - qed_nvm_info_free(p_hwfn); + qed_mcp_nvm_info_free(p_hwfn); } static void qed_chain_free_next_ptr(struct qed_dev *cdev, @@ -4648,26 +4656,20 @@ static void qed_chain_free_pbl(struct qed_dev *cdev, struct qed_chain *p_chain) { - void **pp_virt_addr_tbl = p_chain->pbl.pp_virt_addr_tbl; + struct addr_tbl_entry *pp_addr_tbl = p_chain->pbl.pp_addr_tbl; u32 page_cnt = p_chain->page_cnt, i, pbl_size; - u8 *p_pbl_virt = p_chain->pbl_sp.p_virt_table; - if (!pp_virt_addr_tbl) + if (!pp_addr_tbl) return; - if (!p_pbl_virt) - goto out; - for (i = 0; i < page_cnt; i++) { - if (!pp_virt_addr_tbl[i]) + if (!pp_addr_tbl[i].virt_addr || !pp_addr_tbl[i].dma_map) break; dma_free_coherent(&cdev->pdev->dev, QED_CHAIN_PAGE_SIZE, - pp_virt_addr_tbl[i], - *(dma_addr_t *)p_pbl_virt); - - p_pbl_virt += QED_CHAIN_PBL_ENTRY_SIZE; + pp_addr_tbl[i].virt_addr, + pp_addr_tbl[i].dma_map); } pbl_size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE; @@ -4677,9 +4679,9 @@ pbl_size, p_chain->pbl_sp.p_virt_table, p_chain->pbl_sp.p_phys_table); -out: - vfree(p_chain->pbl.pp_virt_addr_tbl); - p_chain->pbl.pp_virt_addr_tbl = NULL; + + vfree(p_chain->pbl.pp_addr_tbl); + p_chain->pbl.pp_addr_tbl = NULL; } void qed_chain_free(struct qed_dev *cdev, struct qed_chain *p_chain) @@ -4780,19 +4782,19 @@ { u32 page_cnt = p_chain->page_cnt, size, i; dma_addr_t p_phys = 0, p_pbl_phys = 0; - void **pp_virt_addr_tbl = NULL; + struct addr_tbl_entry *pp_addr_tbl; u8 *p_pbl_virt = NULL; void *p_virt = NULL; - size = page_cnt * sizeof(*pp_virt_addr_tbl); - pp_virt_addr_tbl = vzalloc(size); - if (!pp_virt_addr_tbl) + size = page_cnt * sizeof(*pp_addr_tbl); + pp_addr_tbl = vzalloc(size); + if (!pp_addr_tbl) return -ENOMEM; /* The allocation of the PBL table is done with its full size, since it * is expected to be successive. * qed_chain_init_pbl_mem() is called even in a case of an allocation - * failure, since pp_virt_addr_tbl was previously allocated, and it + * failure, since tbl was previously allocated, and it * should be saved to allow its freeing during the error flow. */ size = page_cnt * QED_CHAIN_PBL_ENTRY_SIZE; @@ -4806,8 +4808,7 @@ p_chain->b_external_pbl = true; } - qed_chain_init_pbl_mem(p_chain, p_pbl_virt, p_pbl_phys, - pp_virt_addr_tbl); + qed_chain_init_pbl_mem(p_chain, p_pbl_virt, p_pbl_phys, pp_addr_tbl); if (!p_pbl_virt) return -ENOMEM; @@ -4826,7 +4827,8 @@ /* Fill the PBL table with the physical address of the page */ *(dma_addr_t *)p_pbl_virt = p_phys; /* Keep the virtual address of the page */ - p_chain->pbl.pp_virt_addr_tbl[i] = p_virt; + p_chain->pbl.pp_addr_tbl[i].virt_addr = p_virt; + p_chain->pbl.pp_addr_tbl[i].dma_map = p_phys; p_pbl_virt += QED_CHAIN_PBL_ENTRY_SIZE; } @@ -5137,6 +5139,11 @@ num_vports = p_hwfn->qm_info.num_vports; + if (num_vports < 2) { + DP_NOTICE(p_hwfn, "Unexpected num_vports: %d\n", num_vports); + return -EINVAL; + } + /* Accounting for the vports which are configured for WFQ explicitly */ for (i = 0; i < num_vports; i++) { u32 tmp_speed; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_int.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -256,9 +256,10 @@ #define PGLUE_ATTENTION_ZLR_VALID (1 << 25) #define PGLUE_ATTENTION_ILT_VALID (1 << 23) -int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt) +int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, + bool hw_init) { + char msg[256]; u32 tmp; tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2); @@ -272,22 +273,23 @@ details = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS); - DP_NOTICE(p_hwfn, - "Illegal write by chip to [%08x:%08x] blocked.\n" - "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" - "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n", - addr_hi, addr_lo, details, - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), - (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), - GET_FIELD(details, - PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0, - tmp, - GET_FIELD(tmp, - PGLUE_ATTENTION_DETAILS2_WAS_ERR) ? 1 : 0, - GET_FIELD(tmp, - PGLUE_ATTENTION_DETAILS2_BME) ? 1 : 0, - GET_FIELD(tmp, - PGLUE_ATTENTION_DETAILS2_FID_EN) ? 1 : 0); + snprintf(msg, sizeof(msg), + "Illegal write by chip to [%08x:%08x] blocked.\n" + "Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x]\n" + "Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]", + addr_hi, addr_lo, details, + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_PFID), + (u8)GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VFID), + !!GET_FIELD(details, PGLUE_ATTENTION_DETAILS_VF_VALID), + tmp, + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_WAS_ERR), + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_BME), + !!GET_FIELD(tmp, PGLUE_ATTENTION_DETAILS2_FID_EN)); + + if (hw_init) + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); + else + DP_NOTICE(p_hwfn, "%s\n", msg); } tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2); @@ -320,8 +322,14 @@ } tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL); - if (tmp & PGLUE_ATTENTION_ICPL_VALID) - DP_NOTICE(p_hwfn, "ICPL error - %08x\n", tmp); + if (tmp & PGLUE_ATTENTION_ICPL_VALID) { + snprintf(msg, sizeof(msg), "ICPL error - %08x", tmp); + + if (hw_init) + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "%s\n", msg); + else + DP_NOTICE(p_hwfn, "%s\n", msg); + } tmp = qed_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS); if (tmp & PGLUE_ATTENTION_ZLR_VALID) { @@ -360,7 +368,7 @@ static int qed_pglueb_rbc_attn_cb(struct qed_hwfn *p_hwfn) { - return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt); + return qed_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt, false); } #define QED_DORQ_ATTENTION_REASON_MASK (0xfffff) @@ -1172,7 +1180,8 @@ index, attn_bits, attn_acks, asserted_bits, deasserted_bits, p_sb_attn_sw->known_attn); } else if (asserted_bits == 0x100) { - DP_INFO(p_hwfn, "MFW indication via attention\n"); + DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, + "MFW indication via attention\n"); } else { DP_VERBOSE(p_hwfn, NETIF_MSG_INTR, "MFW indication [deassertion]\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_int.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_int.h @@ -431,7 +431,7 @@ #define QED_MAPPING_MEMORY_SIZE(dev) (NUM_OF_SBS(dev)) -int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, - struct qed_ptt *p_ptt); +int qed_pglueb_rbc_attn_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, + bool hw_init); #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_iwarp.c @@ -1307,6 +1307,14 @@ prev_weight = weight; while (weight) { + /* If the HW device is during recovery, all resources are + * immediately reset without receiving a per-cid indication + * from HW. In this case we don't expect the cid_map to be + * cleared. + */ + if (p_hwfn->cdev->recov_in_prog) + return 0; + msleep(QED_IWARP_MAX_CID_CLEAN_TIME); weight = bitmap_weight(bmap->bitmap, bmap->max_count); @@ -2742,14 +2750,18 @@ iwarp_info->partial_fpdus = kcalloc((u16)p_hwfn->p_rdma_info->num_qps, sizeof(*iwarp_info->partial_fpdus), GFP_KERNEL); - if (!iwarp_info->partial_fpdus) + if (!iwarp_info->partial_fpdus) { + rc = -ENOMEM; goto err; + } iwarp_info->max_num_partial_fpdus = (u16)p_hwfn->p_rdma_info->num_qps; iwarp_info->mpa_intermediate_buf = kzalloc(buff_size, GFP_KERNEL); - if (!iwarp_info->mpa_intermediate_buf) + if (!iwarp_info->mpa_intermediate_buf) { + rc = -ENOMEM; goto err; + } /* The mpa_bufs array serves for pending RX packets received on the * mpa ll2 that don't have place on the tx ring and require later @@ -2759,8 +2771,10 @@ iwarp_info->mpa_bufs = kcalloc(data.input.rx_num_desc, sizeof(*iwarp_info->mpa_bufs), GFP_KERNEL); - if (!iwarp_info->mpa_bufs) + if (!iwarp_info->mpa_bufs) { + rc = -ENOMEM; goto err; + } INIT_LIST_HEAD(&iwarp_info->mpa_buf_pending_list); INIT_LIST_HEAD(&iwarp_info->mpa_buf_list); @@ -2832,8 +2846,6 @@ if (rc) return rc; - qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_IWARP); - return qed_iwarp_ll2_stop(p_hwfn); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_l2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_l2.c @@ -2001,6 +2001,9 @@ struct qed_ptt *p_ptt, struct qed_arfs_config_params *p_cfg_params) { + if (test_bit(QED_MF_DISABLE_ARFS, &p_hwfn->cdev->mf_bits)) + return; + if (p_cfg_params->mode != QED_FILTER_CONFIG_MODE_DISABLE) { qed_gft_config(p_hwfn, p_ptt, p_hwfn->rel_pf_id, p_cfg_params->tcp, @@ -2778,25 +2781,6 @@ return qed_filter_mcast_cmd(cdev, &mcast, QED_SPQ_MODE_CB, NULL); } -static int qed_configure_filter(struct qed_dev *cdev, - struct qed_filter_params *params) -{ - enum qed_filter_rx_mode_type accept_flags; - - switch (params->type) { - case QED_FILTER_TYPE_UCAST: - return qed_configure_filter_ucast(cdev, ¶ms->filter.ucast); - case QED_FILTER_TYPE_MCAST: - return qed_configure_filter_mcast(cdev, ¶ms->filter.mcast); - case QED_FILTER_TYPE_RX_MODE: - accept_flags = params->filter.accept_flags; - return qed_configure_filter_rx_mode(cdev, accept_flags); - default: - DP_NOTICE(cdev, "Unknown filter type %d\n", (int)params->type); - return -EINVAL; - } -} - static int qed_configure_arfs_searcher(struct qed_dev *cdev, enum qed_filter_config_mode mode) { @@ -2929,7 +2913,9 @@ .q_rx_stop = &qed_stop_rxq, .q_tx_start = &qed_start_txq, .q_tx_stop = &qed_stop_txq, - .filter_config = &qed_configure_filter, + .filter_config_rx_mode = &qed_configure_filter_rx_mode, + .filter_config_ucast = &qed_configure_filter_ucast, + .filter_config_mcast = &qed_configure_filter_mcast, .fastpath_stop = &qed_fastpath_stop, .eth_cqe_completion = &qed_fp_cqe_completion, .get_vport_stats = &qed_get_vport_stats, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -113,7 +113,10 @@ static int qed_ll2_alloc_buffer(struct qed_dev *cdev, u8 **data, dma_addr_t *phys_addr) { - *data = kmalloc(cdev->ll2->rx_size, GFP_ATOMIC); + size_t size = cdev->ll2->rx_size + NET_SKB_PAD + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + + *data = kmalloc(size, GFP_ATOMIC); if (!(*data)) { DP_INFO(cdev, "Failed to allocate LL2 buffer data\n"); return -ENOMEM; @@ -353,6 +356,9 @@ unsigned long flags; int rc = -EINVAL; + if (!p_ll2_conn) + return rc; + spin_lock_irqsave(&p_tx->lock, flags); if (p_tx->b_completing_packet) { rc = -EBUSY; @@ -526,7 +532,16 @@ unsigned long flags = 0; int rc = 0; + if (!p_ll2_conn) + return rc; + spin_lock_irqsave(&p_rx->lock, flags); + + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) { + spin_unlock_irqrestore(&p_rx->lock, flags); + return 0; + } + cq_new_idx = le16_to_cpu(*p_rx->p_fw_cons); cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain); @@ -847,6 +862,9 @@ struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie; int rc; + if (!p_ll2_conn) + return 0; + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) return 0; @@ -870,6 +888,9 @@ u16 new_idx = 0, num_bds = 0; int rc; + if (!p_ll2_conn) + return 0; + if (!QED_LL2_TX_REGISTERED(p_ll2_conn)) return 0; @@ -1642,6 +1663,8 @@ if (!p_ll2_conn) return -EINVAL; p_rx = &p_ll2_conn->rx_queue; + if (!p_rx->set_prod_addr) + return -EIO; spin_lock_irqsave(&p_rx->lock, flags); if (!list_empty(&p_rx->free_descq)) @@ -2429,7 +2452,7 @@ INIT_LIST_HEAD(&cdev->ll2->list); spin_lock_init(&cdev->ll2->lock); - cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN + + cdev->ll2->rx_size = PRM_DMA_PAD_BYTES_NUM + ETH_HLEN + L1_CACHE_BYTES + params->mtu; /* Allocate memory for LL2. --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_ll2.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_ll2.h @@ -123,9 +123,9 @@ enum core_tx_dest tx_dest; u8 tx_stats_en; bool main_func_queue; + struct qed_ll2_cbs cbs; struct qed_ll2_rx_queue rx_queue; struct qed_ll2_tx_queue tx_queue; - struct qed_ll2_cbs cbs; }; /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -280,6 +280,8 @@ dev_info->fw_eng = FW_ENGINEERING_VERSION; dev_info->b_inter_pf_switch = test_bit(QED_MF_INTER_PF_SWITCH, &cdev->mf_bits); + if (!test_bit(QED_MF_DISABLE_ARFS, &cdev->mf_bits)) + dev_info->b_arfs_capable = true; dev_info->tx_switching = true; if (hw_info->b_wol_support == QED_WOL_SUPPORT_PME) @@ -557,7 +559,12 @@ rc = cnt; } - if (rc > 0) { + /* For VFs, we should return with an error in case we didn't get the + * exact number of msix vectors as we requested. + * Not doing that will lead to a crash when starting queues for + * this VF. + */ + if ((IS_PF(cdev) && rc > 0) || (IS_VF(cdev) && rc == cnt)) { /* MSI-x configuration was achieved */ int_params->out.int_mode = QED_INT_MODE_MSIX; int_params->out.num_vectors = rc; @@ -1087,9 +1094,6 @@ #define QED_PERIODIC_DB_REC_INTERVAL_MS 100 #define QED_PERIODIC_DB_REC_INTERVAL \ msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS) -#define QED_PERIODIC_DB_REC_WAIT_COUNT 10 -#define QED_PERIODIC_DB_REC_WAIT_INTERVAL \ - (QED_PERIODIC_DB_REC_INTERVAL_MS / QED_PERIODIC_DB_REC_WAIT_COUNT) static int qed_slowpath_delayed_work(struct qed_hwfn *hwfn, enum qed_slowpath_wq_flag wq_flag, @@ -1123,7 +1127,7 @@ static void qed_slowpath_wq_stop(struct qed_dev *cdev) { - int i, sleep_count = QED_PERIODIC_DB_REC_WAIT_COUNT; + int i; if (IS_VF(cdev)) return; @@ -1135,13 +1139,7 @@ /* Stop queuing new delayed works */ cdev->hwfns[i].slowpath_wq_active = false; - /* Wait until the last periodic doorbell recovery is executed */ - while (test_bit(QED_SLOWPATH_PERIODIC_DB_REC, - &cdev->hwfns[i].slowpath_task_flags) && - sleep_count--) - msleep(QED_PERIODIC_DB_REC_WAIT_INTERVAL); - - flush_workqueue(cdev->hwfns[i].slowpath_wq); + cancel_delayed_work(&cdev->hwfns[i].slowpath_task); destroy_workqueue(cdev->hwfns[i].slowpath_wq); } } @@ -1179,7 +1177,6 @@ static int qed_slowpath_wq_start(struct qed_dev *cdev) { struct qed_hwfn *hwfn; - char name[NAME_SIZE]; int i; if (IS_VF(cdev)) @@ -1188,11 +1185,11 @@ for_each_hwfn(cdev, i) { hwfn = &cdev->hwfns[i]; - snprintf(name, NAME_SIZE, "slowpath-%02x:%02x.%02x", - cdev->pdev->bus->number, - PCI_SLOT(cdev->pdev->devfn), hwfn->abs_pf_id); + hwfn->slowpath_wq = alloc_workqueue("slowpath-%02x:%02x.%02x", + 0, 0, cdev->pdev->bus->number, + PCI_SLOT(cdev->pdev->devfn), + hwfn->abs_pf_id); - hwfn->slowpath_wq = alloc_workqueue(name, 0, 0); if (!hwfn->slowpath_wq) { DP_NOTICE(hwfn, "Cannot create slowpath workqueue\n"); return -ENOMEM; @@ -1240,6 +1237,7 @@ } else { DP_NOTICE(cdev, "Failed to acquire PTT for aRFS\n"); + rc = -EINVAL; goto err; } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -498,14 +498,18 @@ spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); - if (!qed_mcp_has_pending_cmd(p_hwfn)) + if (!qed_mcp_has_pending_cmd(p_hwfn)) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; + } rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt); - if (!rc) + if (!rc) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; - else if (rc != -EAGAIN) + } else if (rc != -EAGAIN) { goto err; + } spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); @@ -522,6 +526,8 @@ return -EAGAIN; } + spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); + /* Send the mailbox command */ qed_mcp_reread_offsets(p_hwfn, p_ptt); seq_num = ++p_hwfn->mcp_info->drv_mb_seq; @@ -548,14 +554,18 @@ spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); - if (p_cmd_elem->b_is_completed) + if (p_cmd_elem->b_is_completed) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; + } rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt); - if (!rc) + if (!rc) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; - else if (rc != -EAGAIN) + } else if (rc != -EAGAIN) { goto err; + } spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); } while (++cnt < max_retries); @@ -576,6 +586,7 @@ return -EAGAIN; } + spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); qed_mcp_cmd_del_elem(p_hwfn, p_cmd_elem); spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); @@ -3048,7 +3059,9 @@ if (rc) return rc; - if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) + if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED)) + rc = -EOPNOTSUPP; + else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK)) rc = -EINVAL; return rc; @@ -3149,12 +3162,20 @@ return rc; } +void qed_mcp_nvm_info_free(struct qed_hwfn *p_hwfn) +{ + kfree(p_hwfn->nvm_info.image_att); + p_hwfn->nvm_info.image_att = NULL; + p_hwfn->nvm_info.valid = false; +} + int qed_mcp_get_nvm_image_att(struct qed_hwfn *p_hwfn, enum qed_nvm_images image_id, struct qed_nvm_image_att *p_image_att) { enum nvm_image_type type; + int rc; u32 i; /* Translate image_id into MFW definitions */ @@ -3180,7 +3201,10 @@ return -EINVAL; } - qed_mcp_nvm_info_populate(p_hwfn); + rc = qed_mcp_nvm_info_populate(p_hwfn); + if (rc) + return rc; + for (i = 0; i < p_hwfn->nvm_info.num_images; i++) if (type == p_hwfn->nvm_info.image_att[i].image_type) break; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -1193,6 +1193,13 @@ int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn); /** + * @brief Delete nvm info shadow in the given hardware function + * + * @param p_hwfn + */ +void qed_mcp_nvm_info_free(struct qed_hwfn *p_hwfn); + +/** * @brief Get the engine affinity configuration. * * @param p_hwfn --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_ptp.c @@ -44,8 +44,8 @@ /* Add/subtract the Adjustment_Value when making a Drift adjustment */ #define QED_DRIFT_CNTR_DIRECTION_SHIFT 31 #define QED_TIMESTAMP_MASK BIT(16) -/* Param mask for Hardware to detect/timestamp the unicast PTP packets */ -#define QED_PTP_UCAST_PARAM_MASK 0xF +/* Param mask for Hardware to detect/timestamp the L2/L4 unicast PTP packets */ +#define QED_PTP_UCAST_PARAM_MASK 0x70F static enum qed_resc_lock qed_ptcdev_to_resc(struct qed_hwfn *p_hwfn) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_rdma.c @@ -1245,8 +1245,7 @@ if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info->active) { - DP_ERR(p_hwfn->cdev, - "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", + pr_err("qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", rdma_cxt, in_params, out_params); return NULL; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_roce.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_roce.c @@ -107,13 +107,20 @@ * Beyond the added delay we clear the bitmap anyway. */ while (bitmap_weight(rcid_map->bitmap, rcid_map->max_count)) { + /* If the HW device is during recovery, all resources are + * immediately reset without receiving a per-cid indication + * from HW. In this case we don't expect the cid bitmap to be + * cleared. + */ + if (p_hwfn->cdev->recov_in_prog) + return; + msleep(100); if (wait_count++ > 20) { DP_NOTICE(p_hwfn, "cid bitmap wait timed out\n"); break; } } - qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_ROCE); } static void qed_rdma_copy_gids(struct qed_rdma_qp *qp, __le32 *src_gid, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -96,6 +96,7 @@ p_ramrod->personality = PERSONALITY_ETH; break; case QED_PCI_ETH_ROCE: + case QED_PCI_ETH_IWARP: p_ramrod->personality = PERSONALITY_RDMA_AND_ETH; break; default: @@ -3002,12 +3003,16 @@ u8 mask = QED_ACCEPT_UCAST_UNMATCHED | QED_ACCEPT_MCAST_UNMATCHED; struct qed_filter_accept_flags *flags = ¶ms->accept_flags; struct qed_public_vf_info *vf_info; + u16 tlv_mask; + + tlv_mask = BIT(QED_IOV_VP_UPDATE_ACCEPT_PARAM) | + BIT(QED_IOV_VP_UPDATE_ACCEPT_ANY_VLAN); /* Untrusted VFs can't even be trusted to know that fact. * Simply indicate everything is configured fine, and trace * configuration 'behind their back'. */ - if (!(*tlvs & BIT(QED_IOV_VP_UPDATE_ACCEPT_PARAM))) + if (!(*tlvs & tlv_mask)) return 0; vf_info = qed_iov_get_public_vf_info(hwfn, vfid, true); @@ -3024,6 +3029,13 @@ flags->tx_accept_filter &= ~mask; } + if (params->update_accept_any_vlan_flg) { + vf_info->accept_any_vlan = params->accept_any_vlan; + + if (vf_info->forced_vlan && !vf_info->is_trusted_configured) + params->accept_any_vlan = false; + } + return 0; } @@ -3800,11 +3812,11 @@ return found; } -static void qed_iov_get_link(struct qed_hwfn *p_hwfn, - u16 vfid, - struct qed_mcp_link_params *p_params, - struct qed_mcp_link_state *p_link, - struct qed_mcp_link_capabilities *p_caps) +static int qed_iov_get_link(struct qed_hwfn *p_hwfn, + u16 vfid, + struct qed_mcp_link_params *p_params, + struct qed_mcp_link_state *p_link, + struct qed_mcp_link_capabilities *p_caps) { struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn, vfid, @@ -3812,7 +3824,7 @@ struct qed_bulletin_content *p_bulletin; if (!p_vf) - return; + return -EINVAL; p_bulletin = p_vf->bulletin.p_virt; @@ -3822,6 +3834,7 @@ __qed_vf_get_link_state(p_hwfn, p_link, p_bulletin); if (p_caps) __qed_vf_get_link_caps(p_hwfn, p_caps, p_bulletin); + return 0; } static int @@ -4391,6 +4404,9 @@ } vf = qed_iov_get_vf_info(QED_LEADING_HWFN(cdev), (u16)vfid, true); + if (!vf) + return -EINVAL; + vport_id = vf->vport_id; return qed_configure_vport_wfq(cdev, vport_id, rate); @@ -4683,6 +4699,7 @@ struct qed_public_vf_info *vf_info; struct qed_mcp_link_state link; u32 tx_rate; + int ret; /* Sanitize request */ if (IS_VF(cdev)) @@ -4696,7 +4713,9 @@ vf_info = qed_iov_get_public_vf_info(hwfn, vf_id, true); - qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL); + ret = qed_iov_get_link(hwfn, vf_id, NULL, &link, NULL); + if (ret) + return ret; /* Fill information about VF */ ivi->vf = vf_id; @@ -4712,6 +4731,7 @@ tx_rate = vf_info->tx_rate; ivi->max_tx_rate = tx_rate ? tx_rate : link.speed; ivi->min_tx_rate = qed_iov_get_vf_min_rate(hwfn, vf_id); + ivi->trusted = vf_info->is_trusted_request; return 0; } @@ -5133,7 +5153,7 @@ /* Validate that the VF has a configured vport */ vf = qed_iov_get_vf_info(hwfn, i, true); - if (!vf->vport_instance) + if (!vf || !vf->vport_instance) continue; memset(¶ms, 0, sizeof(params)); @@ -5142,6 +5162,12 @@ params.update_ctl_frame_check = 1; params.mac_chk_en = !vf_info->is_trusted_configured; + params.update_accept_any_vlan_flg = 0; + + if (vf_info->accept_any_vlan && vf_info->forced_vlan) { + params.update_accept_any_vlan_flg = 1; + params.accept_any_vlan = vf_info->accept_any_vlan; + } if (vf_info->rx_accept_mode & mask) { flags->update_rx_mode_config = 1; @@ -5157,13 +5183,20 @@ if (!vf_info->is_trusted_configured) { flags->rx_accept_filter &= ~mask; flags->tx_accept_filter &= ~mask; + params.accept_any_vlan = false; } if (flags->update_rx_mode_config || flags->update_tx_mode_config || - params.update_ctl_frame_check) + params.update_ctl_frame_check || + params.update_accept_any_vlan_flg) { + DP_VERBOSE(hwfn, QED_MSG_IOV, + "vport update config for %s VF[abs 0x%x rel 0x%x]\n", + vf_info->is_trusted_configured ? "trusted" : "untrusted", + vf->abs_vf_id, vf->relative_vf_id); qed_sp_vport_update(hwfn, ¶ms, QED_SPQ_MODE_EBLOCK, NULL); + } } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_sriov.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_sriov.h @@ -88,6 +88,7 @@ bool is_trusted_request; u8 rx_accept_mode; u8 tx_accept_mode; + bool accept_any_vlan; }; struct qed_iov_vf_init_params { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qed/qed_vf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qed/qed_vf.c @@ -81,12 +81,17 @@ mutex_unlock(&(p_hwfn->vf_iov_info->mutex)); } +#define QED_VF_CHANNEL_USLEEP_ITERATIONS 90 +#define QED_VF_CHANNEL_USLEEP_DELAY 100 +#define QED_VF_CHANNEL_MSLEEP_ITERATIONS 10 +#define QED_VF_CHANNEL_MSLEEP_DELAY 25 + static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size) { union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request; struct ustorm_trigger_vf_zone trigger; struct ustorm_vf_zone *zone_data; - int rc = 0, time = 100; + int iter, rc = 0; zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B; @@ -126,11 +131,19 @@ REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger)); /* When PF would be done with the response, it would write back to the - * `done' address. Poll until then. + * `done' address from a coherent DMA zone. Poll until then. */ - while ((!*done) && time) { - msleep(25); - time--; + + iter = QED_VF_CHANNEL_USLEEP_ITERATIONS; + while (!*done && iter--) { + udelay(QED_VF_CHANNEL_USLEEP_DELAY); + dma_rmb(); + } + + iter = QED_VF_CHANNEL_MSLEEP_ITERATIONS; + while (!*done && iter--) { + msleep(QED_VF_CHANNEL_MSLEEP_DELAY); + dma_rmb(); } if (!*done) { @@ -526,6 +539,9 @@ p_iov->bulletin.size, &p_iov->bulletin.phys, GFP_KERNEL); + if (!p_iov->bulletin.p_virt) + goto free_pf2vf_reply; + DP_VERBOSE(p_hwfn, QED_MSG_IOV, "VF's bulletin Board [%p virt 0x%llx phys 0x%08x bytes]\n", p_iov->bulletin.p_virt, @@ -565,6 +581,10 @@ return rc; +free_pf2vf_reply: + dma_free_coherent(&p_hwfn->cdev->pdev->dev, + sizeof(union pfvf_tlvs), + p_iov->pf2vf_reply, p_iov->pf2vf_reply_phys); free_vf2pf_request: dma_free_coherent(&p_hwfn->cdev->pdev->dev, sizeof(union vfpf_tlvs), --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede.h @@ -163,6 +163,8 @@ struct list_head entry; struct list_head rdma_event_list; struct workqueue_struct *rdma_wq; + struct kref refcnt; + struct completion event_comp; bool exp_recovery; }; @@ -572,12 +574,14 @@ #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) #define NUM_RX_BDS_MAX (RX_RING_SIZE - 1) #define NUM_RX_BDS_MIN 128 +#define NUM_RX_BDS_KDUMP_MIN 63 #define NUM_RX_BDS_DEF ((u16)BIT(10) - 1) #define TX_RING_SIZE_POW 13 #define TX_RING_SIZE ((u16)BIT(TX_RING_SIZE_POW)) #define NUM_TX_BDS_MAX (TX_RING_SIZE - 1) #define NUM_TX_BDS_MIN 128 +#define NUM_TX_BDS_KDUMP_MIN 63 #define NUM_TX_BDS_DEF NUM_TX_BDS_MAX #define QEDE_MIN_PKT_LEN 64 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -336,6 +336,9 @@ { int i; + if (!edev->dev_info.common.b_arfs_capable) + return -EINVAL; + edev->arfs = vzalloc(sizeof(*edev->arfs)); if (!edev->arfs) return -ENOMEM; @@ -641,30 +644,28 @@ enum qed_filter_xcast_params_type opcode, unsigned char mac[ETH_ALEN]) { - struct qed_filter_params filter_cmd; + struct qed_filter_ucast_params ucast; - memset(&filter_cmd, 0, sizeof(filter_cmd)); - filter_cmd.type = QED_FILTER_TYPE_UCAST; - filter_cmd.filter.ucast.type = opcode; - filter_cmd.filter.ucast.mac_valid = 1; - ether_addr_copy(filter_cmd.filter.ucast.mac, mac); + memset(&ucast, 0, sizeof(ucast)); + ucast.type = opcode; + ucast.mac_valid = 1; + ether_addr_copy(ucast.mac, mac); - return edev->ops->filter_config(edev->cdev, &filter_cmd); + return edev->ops->filter_config_ucast(edev->cdev, &ucast); } static int qede_set_ucast_rx_vlan(struct qede_dev *edev, enum qed_filter_xcast_params_type opcode, u16 vid) { - struct qed_filter_params filter_cmd; + struct qed_filter_ucast_params ucast; - memset(&filter_cmd, 0, sizeof(filter_cmd)); - filter_cmd.type = QED_FILTER_TYPE_UCAST; - filter_cmd.filter.ucast.type = opcode; - filter_cmd.filter.ucast.vlan_valid = 1; - filter_cmd.filter.ucast.vlan = vid; + memset(&ucast, 0, sizeof(ucast)); + ucast.type = opcode; + ucast.vlan_valid = 1; + ucast.vlan = vid; - return edev->ops->filter_config(edev->cdev, &filter_cmd); + return edev->ops->filter_config_ucast(edev->cdev, &ucast); } static int qede_config_accept_any_vlan(struct qede_dev *edev, bool action) @@ -1130,18 +1131,17 @@ enum qed_filter_xcast_params_type opcode, unsigned char *mac, int num_macs) { - struct qed_filter_params filter_cmd; + struct qed_filter_mcast_params mcast; int i; - memset(&filter_cmd, 0, sizeof(filter_cmd)); - filter_cmd.type = QED_FILTER_TYPE_MCAST; - filter_cmd.filter.mcast.type = opcode; - filter_cmd.filter.mcast.num = num_macs; + memset(&mcast, 0, sizeof(mcast)); + mcast.type = opcode; + mcast.num = num_macs; for (i = 0; i < num_macs; i++, mac += ETH_ALEN) - ether_addr_copy(filter_cmd.filter.mcast.mac[i], mac); + ether_addr_copy(mcast.mac[i], mac); - return edev->ops->filter_config(edev->cdev, &filter_cmd); + return edev->ops->filter_config_mcast(edev->cdev, &mcast); } int qede_set_mac_addr(struct net_device *ndev, void *p) @@ -1230,7 +1230,7 @@ netif_addr_lock_bh(ndev); mc_count = netdev_mc_count(ndev); - if (mc_count < 64) { + if (mc_count <= 64) { netdev_for_each_mc_addr(ha, ndev) { ether_addr_copy(temp, ha->addr); temp += ETH_ALEN; @@ -1267,7 +1267,6 @@ { enum qed_filter_rx_mode_type accept_flags; struct qede_dev *edev = netdev_priv(ndev); - struct qed_filter_params rx_mode; unsigned char *uc_macs, *temp; struct netdev_hw_addr *ha; int rc, uc_count; @@ -1293,10 +1292,6 @@ netif_addr_unlock_bh(ndev); - /* Configure the struct for the Rx mode */ - memset(&rx_mode, 0, sizeof(struct qed_filter_params)); - rx_mode.type = QED_FILTER_TYPE_RX_MODE; - /* Remove all previous unicast secondary macs and multicast macs * (configrue / leave the primary mac) */ @@ -1344,8 +1339,7 @@ qede_config_accept_any_vlan(edev, false); } - rx_mode.filter.accept_flags = accept_flags; - edev->ops->filter_config(edev->cdev, &rx_mode); + edev->ops->filter_config_rx_mode(edev->cdev, accept_flags); out: kfree(uc_macs); } @@ -1946,8 +1940,8 @@ struct flow_cls_offload *f) { struct qede_arfs_fltr_node *n; - int min_hlen, rc = -EINVAL; struct qede_arfs_tuple t; + int min_hlen, rc; __qede_lock(edev); @@ -1957,7 +1951,8 @@ } /* parse flower attribute and prepare filter */ - if (qede_parse_flow_attr(edev, proto, f->rule, &t)) + rc = qede_parse_flow_attr(edev, proto, f->rule, &t); + if (rc) goto unlock; /* Validate profile mode and number of filters */ @@ -1966,12 +1961,15 @@ DP_NOTICE(edev, "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n", t.mode, edev->arfs->mode, edev->arfs->filter_count); + rc = -EINVAL; goto unlock; } /* parse tc actions and get the vf_id */ - if (qede_parse_actions(edev, &f->rule->action)) + if (qede_parse_actions(edev, &f->rule->action)) { + rc = -EINVAL; goto unlock; + } if (qede_flow_find_fltr(edev, &t)) { rc = -EEXIST; @@ -2076,10 +2074,9 @@ if (IS_ERR(flow)) return PTR_ERR(flow); - if (qede_parse_flow_attr(edev, proto, flow->rule, t)) { - err = -EINVAL; + err = qede_parse_flow_attr(edev, proto, flow->rule, t); + if (err) goto err_out; - } /* Make sure location is valid and filter isn't already set */ err = qede_flow_spec_validate(edev, &flow->rule->action, t, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -723,6 +723,9 @@ buf = page_address(bd->data) + bd->page_offset; skb = build_skb(buf, rxq->rx_buf_seg_size); + if (unlikely(!skb)) + return NULL; + skb_reserve(skb, pad); skb_put(skb, len); @@ -1597,6 +1600,13 @@ data_split = true; } } else { + if (unlikely(skb->len > ETH_TX_MAX_NON_LSO_PKT_LEN)) { + DP_ERR(edev, "Unexpected non LSO skb length = 0x%x\n", skb->len); + qede_free_failed_tx_pkt(txq, first_bd, 0, false); + qede_update_tx_producer(txq); + return NETDEV_TX_OK; + } + val |= ((skb->len & ETH_TX_DATA_1ST_BD_PKT_LEN_MASK) << ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT); } @@ -1737,6 +1747,11 @@ ntohs(udp_hdr(skb)->dest) != gnv_port)) return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + } else if (l4_proto == IPPROTO_IPIP) { + /* IPIP tunnels are unknown to the device or at least unsupported natively, + * offloads for them can't be done trivially, so disable them for such skb. + */ + return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); } } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -29,6 +29,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#include #include #include #include @@ -707,8 +708,14 @@ edev->dp_module = dp_module; edev->dp_level = dp_level; edev->ops = qed_ops; - edev->q_num_rx_buffers = NUM_RX_BDS_DEF; - edev->q_num_tx_buffers = NUM_TX_BDS_DEF; + + if (is_kdump_kernel()) { + edev->q_num_rx_buffers = NUM_RX_BDS_KDUMP_MIN; + edev->q_num_tx_buffers = NUM_TX_BDS_KDUMP_MIN; + } else { + edev->q_num_rx_buffers = NUM_RX_BDS_DEF; + edev->q_num_tx_buffers = NUM_TX_BDS_DEF; + } DP_INFO(edev, "Allocated netdev with %d tx queues and %d rx queues\n", info->num_queues, info->num_queues); @@ -763,7 +770,7 @@ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_TC; - if (!IS_VF(edev) && edev->dev_info.common.num_hwfns == 1) + if (edev->dev_info.common.b_arfs_capable) hw_features |= NETIF_F_NTUPLE; if (edev->dev_info.common.vxlan_enable || @@ -1151,7 +1158,7 @@ /* PTP not supported on VFs */ if (!is_vf) - qede_ptp_enable(edev, (mode == QEDE_PROBE_NORMAL)); + qede_ptp_enable(edev); edev->ops->register_ops(cdev, &qede_ll_ops, edev); @@ -1240,6 +1247,7 @@ if (system_state == SYSTEM_POWER_OFF) return; qed_ops->common->remove(cdev); + edev->cdev = NULL; /* Since this can happen out-of-sync with other flows, * don't release the netdevice until after slowpath stop @@ -1406,6 +1414,7 @@ rxq->rx_buf_seg_size = roundup_pow_of_two(size); } else { rxq->rx_buf_seg_size = PAGE_SIZE; + edev->ndev->features &= ~NETIF_F_GRO_HW; } /* Allocate the parallel driver ring for Rx buffers */ @@ -1450,6 +1459,7 @@ } } + edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW); if (!edev->gro_disable) qede_set_tpa_param(rxq); err: @@ -1702,8 +1712,6 @@ snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", edev->ndev->name, queue_id); } - - edev->gro_disable = !(edev->ndev->features & NETIF_F_GRO_HW); } static int qede_set_real_num_queues(struct qede_dev *edev) @@ -1765,6 +1773,7 @@ } edev->int_info.used_cnt = 0; + edev->int_info.msix_cnt = 0; } static int qede_req_msix_irqs(struct qede_dev *edev) @@ -2203,7 +2212,7 @@ qede_vlan_mark_nonconfigured(edev); edev->ops->fastpath_stop(edev->cdev); - if (!IS_VF(edev) && edev->dev_info.common.num_hwfns == 1) { + if (edev->dev_info.common.b_arfs_capable) { qede_poll_for_freeing_arfs_filters(edev); qede_free_arfs(edev); } @@ -2270,10 +2279,9 @@ if (rc) goto err2; - if (!IS_VF(edev) && edev->dev_info.common.num_hwfns == 1) { - rc = qede_alloc_arfs(edev); - if (rc) - DP_NOTICE(edev, "aRFS memory allocation failed\n"); + if (qede_alloc_arfs(edev)) { + edev->ndev->features &= ~NETIF_F_NTUPLE; + edev->dev_info.common.b_arfs_capable = false; } qede_napi_add_enable(edev); @@ -2310,7 +2318,6 @@ goto out; err4: qede_sync_free_irqs(edev); - memset(&edev->int_info.msix_cnt, 0, sizeof(struct qed_int_info)); err3: qede_napi_disable_remove(edev); err2: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -411,6 +411,7 @@ if (ptp->tx_skb) { dev_kfree_skb_any(ptp->tx_skb); ptp->tx_skb = NULL; + clear_bit_unlock(QEDE_FLAGS_PTP_TX_IN_PRORGESS, &edev->flags); } /* Disable PTP in HW */ @@ -422,7 +423,7 @@ edev->ptp = NULL; } -static int qede_ptp_init(struct qede_dev *edev, bool init_tc) +static int qede_ptp_init(struct qede_dev *edev) { struct qede_ptp *ptp; int rc; @@ -443,25 +444,19 @@ /* Init work queue for Tx timestamping */ INIT_WORK(&ptp->work, qede_ptp_task); - /* Init cyclecounter and timecounter. This is done only in the first - * load. If done in every load, PTP application will fail when doing - * unload / load (e.g. MTU change) while it is running. - */ - if (init_tc) { - memset(&ptp->cc, 0, sizeof(ptp->cc)); - ptp->cc.read = qede_ptp_read_cc; - ptp->cc.mask = CYCLECOUNTER_MASK(64); - ptp->cc.shift = 0; - ptp->cc.mult = 1; + /* Init cyclecounter and timecounter */ + memset(&ptp->cc, 0, sizeof(ptp->cc)); + ptp->cc.read = qede_ptp_read_cc; + ptp->cc.mask = CYCLECOUNTER_MASK(64); + ptp->cc.shift = 0; + ptp->cc.mult = 1; - timecounter_init(&ptp->tc, &ptp->cc, - ktime_to_ns(ktime_get_real())); - } + timecounter_init(&ptp->tc, &ptp->cc, ktime_to_ns(ktime_get_real())); - return rc; + return 0; } -int qede_ptp_enable(struct qede_dev *edev, bool init_tc) +int qede_ptp_enable(struct qede_dev *edev) { struct qede_ptp *ptp; int rc; @@ -482,7 +477,7 @@ edev->ptp = ptp; - rc = qede_ptp_init(edev, init_tc); + rc = qede_ptp_init(edev); if (rc) goto err1; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_ptp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_ptp.h @@ -41,7 +41,7 @@ void qede_ptp_tx_ts(struct qede_dev *edev, struct sk_buff *skb); int qede_ptp_hw_ts(struct qede_dev *edev, struct ifreq *req); void qede_ptp_disable(struct qede_dev *edev); -int qede_ptp_enable(struct qede_dev *edev, bool init_tc); +int qede_ptp_enable(struct qede_dev *edev); int qede_ptp_get_ts_info(struct qede_dev *edev, struct ethtool_ts_info *ts); static inline void qede_ptp_record_rx_ts(struct qede_dev *edev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qede/qede_rdma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qede/qede_rdma.c @@ -59,6 +59,9 @@ static int qede_rdma_create_wq(struct qede_dev *edev) { INIT_LIST_HEAD(&edev->rdma_info.rdma_event_list); + kref_init(&edev->rdma_info.refcnt); + init_completion(&edev->rdma_info.event_comp); + edev->rdma_info.rdma_wq = create_singlethread_workqueue("rdma_wq"); if (!edev->rdma_info.rdma_wq) { DP_NOTICE(edev, "qedr: Could not create workqueue\n"); @@ -83,10 +86,26 @@ } } +static void qede_rdma_complete_event(struct kref *ref) +{ + struct qede_rdma_dev *rdma_dev = + container_of(ref, struct qede_rdma_dev, refcnt); + + /* no more events will be added after this */ + complete(&rdma_dev->event_comp); +} + static void qede_rdma_destroy_wq(struct qede_dev *edev) { + /* Avoid race with add_event flow, make sure it finishes before + * we start accessing the list and cleaning up the work + */ + kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); + wait_for_completion(&edev->rdma_info.event_comp); + qede_rdma_cleanup_event(edev); destroy_workqueue(edev->rdma_info.rdma_wq); + edev->rdma_info.rdma_wq = NULL; } int qede_rdma_dev_add(struct qede_dev *edev, bool recovery) @@ -307,18 +326,27 @@ if (edev->rdma_info.exp_recovery) return; - if (!edev->rdma_info.qedr_dev) + if (!edev->rdma_info.qedr_dev || !edev->rdma_info.rdma_wq) return; + /* We don't want the cleanup flow to start while we're allocating and + * scheduling the work + */ + if (!kref_get_unless_zero(&edev->rdma_info.refcnt)) + return; /* already being destroyed */ + event_node = qede_rdma_get_free_event_node(edev); if (!event_node) - return; + goto out; event_node->event = event; event_node->ptr = edev; INIT_WORK(&event_node->work, qede_rdma_handle_event); queue_work(edev->rdma_info.rdma_wq, &event_node->work); + +out: + kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); } void qede_rdma_dev_event_open(struct qede_dev *edev) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qla3xxx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qla3xxx.c @@ -115,7 +115,7 @@ value = readl(&port_regs->CommonRegs.semaphoreReg); if ((value & (sem_mask >> 16)) == sem_bits) return 0; - ssleep(1); + mdelay(1000); } while (--seconds); return -1; } @@ -155,7 +155,7 @@ "driver lock acquired\n"); return 1; } - ssleep(1); + mdelay(1000); } while (++i < 10); netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); @@ -316,12 +316,11 @@ * buffer */ skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, + map = dma_map_single(&qdev->pdev->dev, lrg_buf_cb->skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + qdev->lrg_buffer_len - QL_HEADER_SPACE, + DMA_FROM_DEVICE); + err = dma_mapping_error(&qdev->pdev->dev, map); if (err) { netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", @@ -1803,13 +1802,12 @@ * first buffer */ skb_reserve(lrg_buf_cb->skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, + map = dma_map_single(&qdev->pdev->dev, lrg_buf_cb->skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); + qdev->lrg_buffer_len - QL_HEADER_SPACE, + DMA_FROM_DEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = dma_mapping_error(&qdev->pdev->dev, map); if (err) { netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", @@ -1944,18 +1942,16 @@ goto invalid_seg_count; } - pci_unmap_single(qdev->pdev, + dma_unmap_single(&qdev->pdev->dev, dma_unmap_addr(&tx_cb->map[0], mapaddr), - dma_unmap_len(&tx_cb->map[0], maplen), - PCI_DMA_TODEVICE); + dma_unmap_len(&tx_cb->map[0], maplen), DMA_TO_DEVICE); tx_cb->seg_count--; if (tx_cb->seg_count) { for (i = 1; i < tx_cb->seg_count; i++) { - pci_unmap_page(qdev->pdev, - dma_unmap_addr(&tx_cb->map[i], - mapaddr), + dma_unmap_page(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[i], mapaddr), dma_unmap_len(&tx_cb->map[i], maplen), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); } } qdev->ndev->stats.tx_packets++; @@ -2022,10 +2018,9 @@ qdev->ndev->stats.rx_bytes += length; skb_put(skb, length); - pci_unmap_single(qdev->pdev, + dma_unmap_single(&qdev->pdev->dev, dma_unmap_addr(lrg_buf_cb2, mapaddr), - dma_unmap_len(lrg_buf_cb2, maplen), - PCI_DMA_FROMDEVICE); + dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE); prefetch(skb->data); skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, qdev->ndev); @@ -2068,10 +2063,9 @@ skb2 = lrg_buf_cb2->skb; skb_put(skb2, length); /* Just the second buffer length here. */ - pci_unmap_single(qdev->pdev, + dma_unmap_single(&qdev->pdev->dev, dma_unmap_addr(lrg_buf_cb2, mapaddr), - dma_unmap_len(lrg_buf_cb2, maplen), - PCI_DMA_FROMDEVICE); + dma_unmap_len(lrg_buf_cb2, maplen), DMA_FROM_DEVICE); prefetch(skb2->data); skb_checksum_none_assert(skb2); @@ -2320,9 +2314,9 @@ /* * Map the skb buffer first. */ - map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); + map = dma_map_single(&qdev->pdev->dev, skb->data, len, DMA_TO_DEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = dma_mapping_error(&qdev->pdev->dev, map); if (err) { netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", err); @@ -2358,11 +2352,11 @@ (seg == 7 && seg_cnt > 8) || (seg == 12 && seg_cnt > 13) || (seg == 17 && seg_cnt > 18)) { - map = pci_map_single(qdev->pdev, oal, + map = dma_map_single(&qdev->pdev->dev, oal, sizeof(struct oal), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = dma_mapping_error(&qdev->pdev->dev, map); if (err) { netdev_err(qdev->ndev, "PCI mapping outbound address list with error: %d\n", @@ -2424,24 +2418,24 @@ (seg == 7 && seg_cnt > 8) || (seg == 12 && seg_cnt > 13) || (seg == 17 && seg_cnt > 18)) { - pci_unmap_single(qdev->pdev, - dma_unmap_addr(&tx_cb->map[seg], mapaddr), - dma_unmap_len(&tx_cb->map[seg], maplen), - PCI_DMA_TODEVICE); + dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[seg], mapaddr), + dma_unmap_len(&tx_cb->map[seg], maplen), + DMA_TO_DEVICE); oal++; seg++; } - pci_unmap_page(qdev->pdev, + dma_unmap_page(&qdev->pdev->dev, dma_unmap_addr(&tx_cb->map[seg], mapaddr), dma_unmap_len(&tx_cb->map[seg], maplen), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); } - pci_unmap_single(qdev->pdev, + dma_unmap_single(&qdev->pdev->dev, dma_unmap_addr(&tx_cb->map[0], mapaddr), dma_unmap_addr(&tx_cb->map[0], maplen), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); return NETDEV_TX_BUSY; @@ -2476,6 +2470,7 @@ skb_shinfo(skb)->nr_frags); if (tx_cb->seg_count == -1) { netdev_err(ndev, "%s: invalid segment count!\n", __func__); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -2526,9 +2521,8 @@ wmb(); qdev->req_q_virt_addr = - pci_alloc_consistent(qdev->pdev, - (size_t) qdev->req_q_size, - &qdev->req_q_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size, + &qdev->req_q_phy_addr, GFP_KERNEL); if ((qdev->req_q_virt_addr == NULL) || LS_64BITS(qdev->req_q_phy_addr) & (qdev->req_q_size - 1)) { @@ -2537,16 +2531,14 @@ } qdev->rsp_q_virt_addr = - pci_alloc_consistent(qdev->pdev, - (size_t) qdev->rsp_q_size, - &qdev->rsp_q_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, (size_t)qdev->rsp_q_size, + &qdev->rsp_q_phy_addr, GFP_KERNEL); if ((qdev->rsp_q_virt_addr == NULL) || LS_64BITS(qdev->rsp_q_phy_addr) & (qdev->rsp_q_size - 1)) { netdev_err(qdev->ndev, "rspQ allocation failed\n"); - pci_free_consistent(qdev->pdev, (size_t) qdev->req_q_size, - qdev->req_q_virt_addr, - qdev->req_q_phy_addr); + dma_free_coherent(&qdev->pdev->dev, (size_t)qdev->req_q_size, + qdev->req_q_virt_addr, qdev->req_q_phy_addr); return -ENOMEM; } @@ -2562,15 +2554,13 @@ return; } - pci_free_consistent(qdev->pdev, - qdev->req_q_size, - qdev->req_q_virt_addr, qdev->req_q_phy_addr); + dma_free_coherent(&qdev->pdev->dev, qdev->req_q_size, + qdev->req_q_virt_addr, qdev->req_q_phy_addr); qdev->req_q_virt_addr = NULL; - pci_free_consistent(qdev->pdev, - qdev->rsp_q_size, - qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr); + dma_free_coherent(&qdev->pdev->dev, qdev->rsp_q_size, + qdev->rsp_q_virt_addr, qdev->rsp_q_phy_addr); qdev->rsp_q_virt_addr = NULL; @@ -2594,12 +2584,13 @@ return -ENOMEM; qdev->lrg_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->lrg_buf_q_alloc_size, - &qdev->lrg_buf_q_alloc_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, + qdev->lrg_buf_q_alloc_size, + &qdev->lrg_buf_q_alloc_phy_addr, GFP_KERNEL); if (qdev->lrg_buf_q_alloc_virt_addr == NULL) { netdev_err(qdev->ndev, "lBufQ failed\n"); + kfree(qdev->lrg_buf); return -ENOMEM; } qdev->lrg_buf_q_virt_addr = qdev->lrg_buf_q_alloc_virt_addr; @@ -2614,15 +2605,17 @@ qdev->small_buf_q_alloc_size = qdev->small_buf_q_size * 2; qdev->small_buf_q_alloc_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_q_alloc_size, - &qdev->small_buf_q_alloc_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, + qdev->small_buf_q_alloc_size, + &qdev->small_buf_q_alloc_phy_addr, GFP_KERNEL); if (qdev->small_buf_q_alloc_virt_addr == NULL) { netdev_err(qdev->ndev, "Small Buffer Queue allocation failed\n"); - pci_free_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, - qdev->lrg_buf_q_alloc_virt_addr, - qdev->lrg_buf_q_alloc_phy_addr); + dma_free_coherent(&qdev->pdev->dev, + qdev->lrg_buf_q_alloc_size, + qdev->lrg_buf_q_alloc_virt_addr, + qdev->lrg_buf_q_alloc_phy_addr); + kfree(qdev->lrg_buf); return -ENOMEM; } @@ -2639,17 +2632,15 @@ return; } kfree(qdev->lrg_buf); - pci_free_consistent(qdev->pdev, - qdev->lrg_buf_q_alloc_size, - qdev->lrg_buf_q_alloc_virt_addr, - qdev->lrg_buf_q_alloc_phy_addr); + dma_free_coherent(&qdev->pdev->dev, qdev->lrg_buf_q_alloc_size, + qdev->lrg_buf_q_alloc_virt_addr, + qdev->lrg_buf_q_alloc_phy_addr); qdev->lrg_buf_q_virt_addr = NULL; - pci_free_consistent(qdev->pdev, - qdev->small_buf_q_alloc_size, - qdev->small_buf_q_alloc_virt_addr, - qdev->small_buf_q_alloc_phy_addr); + dma_free_coherent(&qdev->pdev->dev, qdev->small_buf_q_alloc_size, + qdev->small_buf_q_alloc_virt_addr, + qdev->small_buf_q_alloc_phy_addr); qdev->small_buf_q_virt_addr = NULL; @@ -2667,9 +2658,9 @@ QL_SMALL_BUFFER_SIZE); qdev->small_buf_virt_addr = - pci_alloc_consistent(qdev->pdev, - qdev->small_buf_total_size, - &qdev->small_buf_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, + qdev->small_buf_total_size, + &qdev->small_buf_phy_addr, GFP_KERNEL); if (qdev->small_buf_virt_addr == NULL) { netdev_err(qdev->ndev, "Failed to get small buffer memory\n"); @@ -2702,10 +2693,10 @@ return; } if (qdev->small_buf_virt_addr != NULL) { - pci_free_consistent(qdev->pdev, - qdev->small_buf_total_size, - qdev->small_buf_virt_addr, - qdev->small_buf_phy_addr); + dma_free_coherent(&qdev->pdev->dev, + qdev->small_buf_total_size, + qdev->small_buf_virt_addr, + qdev->small_buf_phy_addr); qdev->small_buf_virt_addr = NULL; } @@ -2720,10 +2711,10 @@ lrg_buf_cb = &qdev->lrg_buf[i]; if (lrg_buf_cb->skb) { dev_kfree_skb(lrg_buf_cb->skb); - pci_unmap_single(qdev->pdev, + dma_unmap_single(&qdev->pdev->dev, dma_unmap_addr(lrg_buf_cb, mapaddr), dma_unmap_len(lrg_buf_cb, maplen), - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); } else { break; @@ -2756,6 +2747,9 @@ int err; for (i = 0; i < qdev->num_large_buffers; i++) { + lrg_buf_cb = &qdev->lrg_buf[i]; + memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); + skb = netdev_alloc_skb(qdev->ndev, qdev->lrg_buffer_len); if (unlikely(!skb)) { @@ -2766,23 +2760,17 @@ ql_free_large_buffers(qdev); return -ENOMEM; } else { - - lrg_buf_cb = &qdev->lrg_buf[i]; - memset(lrg_buf_cb, 0, sizeof(struct ql_rcv_buf_cb)); lrg_buf_cb->index = i; - lrg_buf_cb->skb = skb; /* * We save some space to copy the ethhdr from first * buffer */ skb_reserve(skb, QL_HEADER_SPACE); - map = pci_map_single(qdev->pdev, - skb->data, - qdev->lrg_buffer_len - - QL_HEADER_SPACE, - PCI_DMA_FROMDEVICE); + map = dma_map_single(&qdev->pdev->dev, skb->data, + qdev->lrg_buffer_len - QL_HEADER_SPACE, + DMA_FROM_DEVICE); - err = pci_dma_mapping_error(qdev->pdev, map); + err = dma_mapping_error(&qdev->pdev->dev, map); if (err) { netdev_err(qdev->ndev, "PCI mapping failed with error: %d\n", @@ -2792,6 +2780,7 @@ return -ENOMEM; } + lrg_buf_cb->skb = skb; dma_unmap_addr_set(lrg_buf_cb, mapaddr, map); dma_unmap_len_set(lrg_buf_cb, maplen, qdev->lrg_buffer_len - @@ -2866,8 +2855,8 @@ * Network Completion Queue Producer Index Register */ qdev->shadow_reg_virt_addr = - pci_alloc_consistent(qdev->pdev, - PAGE_SIZE, &qdev->shadow_reg_phy_addr); + dma_alloc_coherent(&qdev->pdev->dev, PAGE_SIZE, + &qdev->shadow_reg_phy_addr, GFP_KERNEL); if (qdev->shadow_reg_virt_addr != NULL) { qdev->preq_consumer_index = qdev->shadow_reg_virt_addr; @@ -2922,10 +2911,9 @@ err_buffer_queues: ql_free_net_req_rsp_queues(qdev); err_req_rsp: - pci_free_consistent(qdev->pdev, - PAGE_SIZE, - qdev->shadow_reg_virt_addr, - qdev->shadow_reg_phy_addr); + dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE, + qdev->shadow_reg_virt_addr, + qdev->shadow_reg_phy_addr); return -ENOMEM; } @@ -2938,10 +2926,9 @@ ql_free_buffer_queues(qdev); ql_free_net_req_rsp_queues(qdev); if (qdev->shadow_reg_virt_addr != NULL) { - pci_free_consistent(qdev->pdev, - PAGE_SIZE, - qdev->shadow_reg_virt_addr, - qdev->shadow_reg_phy_addr); + dma_free_coherent(&qdev->pdev->dev, PAGE_SIZE, + qdev->shadow_reg_virt_addr, + qdev->shadow_reg_phy_addr); qdev->shadow_reg_virt_addr = NULL; } } @@ -3291,7 +3278,7 @@ if ((value & ISP_CONTROL_SR) == 0) break; - ssleep(1); + mdelay(1000); } while ((--max_wait_time)); /* @@ -3327,7 +3314,7 @@ ispControlStatus); if ((value & ISP_CONTROL_FSR) == 0) break; - ssleep(1); + mdelay(1000); } while ((--max_wait_time)); } if (max_wait_time == 0) @@ -3495,20 +3482,19 @@ spin_lock_irqsave(&qdev->hw_lock, hw_flags); - err = ql_wait_for_drvr_lock(qdev); - if (err) { - err = ql_adapter_initialize(qdev); - if (err) { - netdev_err(ndev, "Unable to initialize adapter\n"); - goto err_init; - } - netdev_err(ndev, "Releasing driver lock\n"); - ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); - } else { + if (!ql_wait_for_drvr_lock(qdev)) { netdev_err(ndev, "Could not acquire driver lock\n"); + err = -ENODEV; goto err_lock; } + err = ql_adapter_initialize(qdev); + if (err) { + netdev_err(ndev, "Unable to initialize adapter\n"); + goto err_init; + } + ql_sem_unlock(qdev, QL_DRVR_SEM_MASK); + spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); set_bit(QL_ADAPTER_UP, &qdev->flags); @@ -3630,7 +3616,8 @@ qdev->mem_map_registers; unsigned long hw_flags; - if (test_bit((QL_RESET_PER_SCSI | QL_RESET_START), &qdev->flags)) { + if (test_bit(QL_RESET_PER_SCSI, &qdev->flags) || + test_bit(QL_RESET_START, &qdev->flags)) { clear_bit(QL_LINK_MASTER, &qdev->flags); /* @@ -3642,18 +3629,15 @@ if (tx_cb->skb) { netdev_printk(KERN_DEBUG, ndev, "Freeing lost SKB\n"); - pci_unmap_single(qdev->pdev, - dma_unmap_addr(&tx_cb->map[0], - mapaddr), - dma_unmap_len(&tx_cb->map[0], maplen), - PCI_DMA_TODEVICE); + dma_unmap_single(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[0], mapaddr), + dma_unmap_len(&tx_cb->map[0], maplen), + DMA_TO_DEVICE); for (j = 1; j < tx_cb->seg_count; j++) { - pci_unmap_page(qdev->pdev, - dma_unmap_addr(&tx_cb->map[j], - mapaddr), - dma_unmap_len(&tx_cb->map[j], - maplen), - PCI_DMA_TODEVICE); + dma_unmap_page(&qdev->pdev->dev, + dma_unmap_addr(&tx_cb->map[j], mapaddr), + dma_unmap_len(&tx_cb->map[j], maplen), + DMA_TO_DEVICE); } dev_kfree_skb(tx_cb->skb); tx_cb->skb = NULL; @@ -3769,7 +3753,7 @@ struct net_device *ndev = NULL; struct ql3_adapter *qdev = NULL; static int cards_found; - int uninitialized_var(pci_using_dac), err; + int pci_using_dac, err; err = pci_enable_device(pdev); if (err) { @@ -3785,13 +3769,10 @@ pci_set_master(pdev); - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) pci_using_dac = 1; - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); - } else if (!(err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { + else if (!(err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))) pci_using_dac = 0; - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); - } if (err) { pr_err("%s no usable DMA configuration\n", pci_name(pdev)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -1079,8 +1079,14 @@ sds_mbx_size = sizeof(struct qlcnic_sds_mbx); context_id = recv_ctx->context_id; num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS; - ahw->hw_ops->alloc_mbx_args(&cmd, adapter, - QLCNIC_CMD_ADD_RCV_RINGS); + err = ahw->hw_ops->alloc_mbx_args(&cmd, adapter, + QLCNIC_CMD_ADD_RCV_RINGS); + if (err) { + dev_err(&adapter->pdev->dev, + "Failed to alloc mbx args %d\n", err); + return err; + } + cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16); /* set up status rings, mbx 2-81 */ @@ -2987,7 +2993,7 @@ QLCWRX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK, val); dev_info(&adapter->pdev->dev, "%s: lock recovery initiated\n", __func__); - msleep(QLC_83XX_DRV_LOCK_RECOVERY_DELAY); + mdelay(QLC_83XX_DRV_LOCK_RECOVERY_DELAY); val = QLCRDX(adapter->ahw, QLC_83XX_RECOVER_DRV_LOCK); id = ((val >> 2) & 0xF); if (id == adapter->portnum) { @@ -3023,7 +3029,7 @@ if (status) break; - msleep(QLC_83XX_DRV_LOCK_WAIT_DELAY); + mdelay(QLC_83XX_DRV_LOCK_WAIT_DELAY); i++; if (i == 1) @@ -3158,8 +3164,10 @@ indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr); ret = QLCRD32(adapter, indirect_addr, &err); - if (err == -EIO) + if (err == -EIO) { + qlcnic_83xx_unlock_flash(adapter); return err; + } word = ret; *(u32 *)p_data = word; @@ -3651,7 +3659,7 @@ ahw->diag_cnt = 0; ret = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_INTRPT_TEST); if (ret) - goto fail_diag_irq; + goto fail_mbx_args; if (adapter->flags & QLCNIC_MSIX_ENABLED) intrpt_id = ahw->intr_tbl[0].id; @@ -3681,6 +3689,8 @@ done: qlcnic_free_mbx_args(&cmd); + +fail_mbx_args: qlcnic_83xx_diag_free_res(netdev, drv_sds_rings); fail_diag_irq: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -1720,7 +1720,7 @@ ahw->reset.seq_error = 0; ahw->reset.buff = kzalloc(QLC_83XX_RESTART_TEMPLATE_SIZE, GFP_KERNEL); - if (p_dev->ahw->reset.buff == NULL) + if (ahw->reset.buff == NULL) return -ENOMEM; p_buff = p_dev->ahw->reset.buff; @@ -2043,6 +2043,7 @@ break; } entry += p_hdr->size; + cond_resched(); } p_dev->ahw->reset.seq_index = index; } @@ -2250,7 +2251,8 @@ /* Boot either flash image or firmware image from host file system */ if (qlcnic_load_fw_file == 1) { - if (qlcnic_83xx_load_fw_image_from_host(adapter)) + err = qlcnic_83xx_load_fw_image_from_host(adapter); + if (err) return err; } else { QLC_SHARED_REG_WR32(adapter, QLCNIC_FW_IMG_VALID, @@ -2523,7 +2525,13 @@ goto disable_mbx_intr; qlcnic_83xx_clear_function_resources(adapter); - qlcnic_dcb_enable(adapter->dcb); + + err = qlcnic_dcb_enable(adapter->dcb); + if (err) { + qlcnic_dcb_free(adapter->dcb); + goto disable_mbx_intr; + } + qlcnic_83xx_initialize_nic(adapter, 1); qlcnic_dcb_get_info(adapter->dcb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -629,7 +629,13 @@ int i, err, ring; if (dev->flags & QLCNIC_NEED_FLR) { - pci_reset_function(dev->pdev); + err = pci_reset_function(dev->pdev); + if (err) { + dev_err(&dev->pdev->dev, + "Adapter reset failed (%d). Please reboot\n", + err); + return err; + } dev->flags &= ~QLCNIC_NEED_FLR; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.h @@ -42,17 +42,12 @@ unsigned long state; }; -static inline void qlcnic_clear_dcb_ops(struct qlcnic_dcb *dcb) -{ - kfree(dcb); -} - static inline int qlcnic_dcb_get_hw_capability(struct qlcnic_dcb *dcb) { if (dcb && dcb->ops->get_hw_capability) return dcb->ops->get_hw_capability(dcb); - return 0; + return -EOPNOTSUPP; } static inline void qlcnic_dcb_free(struct qlcnic_dcb *dcb) @@ -66,7 +61,7 @@ if (dcb && dcb->ops->attach) return dcb->ops->attach(dcb); - return 0; + return -EOPNOTSUPP; } static inline int @@ -75,7 +70,7 @@ if (dcb && dcb->ops->query_hw_capability) return dcb->ops->query_hw_capability(dcb, buf); - return 0; + return -EOPNOTSUPP; } static inline void qlcnic_dcb_get_info(struct qlcnic_dcb *dcb) @@ -90,7 +85,7 @@ if (dcb && dcb->ops->query_cee_param) return dcb->ops->query_cee_param(dcb, buf, type); - return 0; + return -EOPNOTSUPP; } static inline int qlcnic_dcb_get_cee_cfg(struct qlcnic_dcb *dcb) @@ -98,7 +93,7 @@ if (dcb && dcb->ops->get_cee_cfg) return dcb->ops->get_cee_cfg(dcb); - return 0; + return -EOPNOTSUPP; } static inline void qlcnic_dcb_aen_handler(struct qlcnic_dcb *dcb, void *msg) @@ -113,9 +108,8 @@ dcb->ops->init_dcbnl_ops(dcb); } -static inline void qlcnic_dcb_enable(struct qlcnic_dcb *dcb) +static inline int qlcnic_dcb_enable(struct qlcnic_dcb *dcb) { - if (dcb && qlcnic_dcb_attach(dcb)) - qlcnic_clear_dcb_ops(dcb); + return dcb ? qlcnic_dcb_attach(dcb) : 0; } #endif --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1049,7 +1049,7 @@ for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) { skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE); if (!skb) - break; + goto error; qlcnic_create_loopback_buff(skb->data, adapter->mac_addr); skb_put(skb, QLCNIC_ILB_PKT_SIZE); adapter->ahw->diag_cnt = 0; @@ -1073,6 +1073,7 @@ cnt++; } if (cnt != i) { +error: dev_err(&adapter->pdev->dev, "LB Test: failed, TX[%d], RX[%d]\n", i, cnt); if (mode != QLCNIC_ILB_MODE) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -440,7 +440,6 @@ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x3c, 1); msleep(20); - qlcnic_rom_unlock(adapter); /* big hammer don't reset CAM block on reset */ QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2509,6 +2509,7 @@ qlcnic_sriov_vf_register_map(ahw); break; default: + err = -EINVAL; goto err_out_free_hw_res; } @@ -2638,7 +2639,13 @@ "Device does not support MSI interrupts\n"); if (qlcnic_82xx_check(adapter)) { - qlcnic_dcb_enable(adapter->dcb); + err = qlcnic_dcb_enable(adapter->dcb); + if (err) { + qlcnic_dcb_free(adapter->dcb); + dev_err(&pdev->dev, "Failed to enable DCB\n"); + goto err_out_free_hw; + } + qlcnic_dcb_get_info(adapter->dcb); err = qlcnic_setup_intr(adapter); @@ -2708,6 +2715,7 @@ kfree(ahw); err_out_free_res: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c @@ -703,6 +703,7 @@ addr += 16; reg_read -= 16; ret += 16; + cond_resched(); } out: mutex_unlock(&adapter->ahw->mem_lock); @@ -1383,6 +1384,7 @@ buf_offset += entry->hdr.cap_size; entry_offset += entry->hdr.offset; buffer = fw_dump->data + buf_offset; + cond_resched(); } fw_dump->clr = 1; @@ -1424,6 +1426,7 @@ if (fw_dump->tmpl_hdr == NULL || current_version > prev_version) { vfree(fw_dump->tmpl_hdr); + fw_dump->tmpl_hdr = NULL; if (qlcnic_83xx_md_check_extended_dump_capability(adapter)) extended = !qlcnic_83xx_extend_md_capab(adapter); @@ -1442,6 +1445,8 @@ struct qlcnic_83xx_dump_template_hdr *hdr; hdr = fw_dump->tmpl_hdr; + if (!hdr) + return; hdr->drv_cap_mask = 0x1f; fw_dump->cap_mask = 0x1f; dev_info(&pdev->dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h @@ -202,7 +202,7 @@ struct qlcnic_info *, u16); int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8); void qlcnic_sriov_free_vlans(struct qlcnic_adapter *); -void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *); +int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *); bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *); void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *, struct qlcnic_vf_info *, u16); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -222,6 +222,8 @@ return 0; qlcnic_destroy_async_wq: + while (i--) + kfree(sriov->vf_info[i].vp); destroy_workqueue(bc->bc_async_wq); qlcnic_destroy_trans_wq: @@ -433,7 +435,7 @@ struct qlcnic_cmd_args *cmd) { struct qlcnic_sriov *sriov = adapter->ahw->sriov; - int i, num_vlans; + int i, num_vlans, ret; u16 *vlans; if (sriov->allowed_vlans) @@ -444,7 +446,9 @@ dev_info(&adapter->pdev->dev, "Number of allowed Guest VLANs = %d\n", sriov->num_allowed_vlans); - qlcnic_sriov_alloc_vlans(adapter); + ret = qlcnic_sriov_alloc_vlans(adapter); + if (ret) + return ret; if (!sriov->any_vlan) return 0; @@ -2160,7 +2164,7 @@ return err; } -void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter) +int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter) { struct qlcnic_sriov *sriov = adapter->ahw->sriov; struct qlcnic_vf_info *vf; @@ -2170,7 +2174,11 @@ vf = &sriov->vf_info[i]; vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans, sizeof(*vf->sriov_vlans), GFP_KERNEL); + if (!vf->sriov_vlans) + return -ENOMEM; } + + return 0; } void qlcnic_sriov_free_vlans(struct qlcnic_adapter *adapter) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -598,7 +598,9 @@ if (err) goto del_flr_queue; - qlcnic_sriov_alloc_vlans(adapter); + err = qlcnic_sriov_alloc_vlans(adapter); + if (err) + goto del_flr_queue; return err; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/emac/emac-mac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/emac/emac-mac.c @@ -1439,6 +1439,7 @@ { struct emac_tpd tpd; u32 prod_idx; + int len; memset(&tpd, 0, sizeof(tpd)); @@ -1458,9 +1459,10 @@ if (skb_network_offset(skb) != ETH_HLEN) TPD_TYP_SET(&tpd, 1); + len = skb->len; emac_tx_fill_tpd(adpt, tx_q, skb, &tpd); - netdev_sent_queue(adpt->netdev, skb->len); + netdev_sent_queue(adpt->netdev, len); /* Make sure the are enough free descriptors to hold one * maximum-sized SKB. We need one desc for each fragment, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/emac/emac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/emac/emac.c @@ -485,13 +485,24 @@ ret = clk_prepare_enable(adpt->clk[EMAC_CLK_CFG_AHB]); if (ret) - return ret; + goto disable_clk_axi; ret = clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 19200000); if (ret) - return ret; + goto disable_clk_cfg_ahb; + + ret = clk_prepare_enable(adpt->clk[EMAC_CLK_HIGH_SPEED]); + if (ret) + goto disable_clk_cfg_ahb; + + return 0; + +disable_clk_cfg_ahb: + clk_disable_unprepare(adpt->clk[EMAC_CLK_CFG_AHB]); +disable_clk_axi: + clk_disable_unprepare(adpt->clk[EMAC_CLK_AXI]); - return clk_prepare_enable(adpt->clk[EMAC_CLK_HIGH_SPEED]); + return ret; } /* Enable clocks; needs emac_clks_phase1_init to be called before */ @@ -727,19 +738,26 @@ struct net_device *netdev = dev_get_drvdata(&pdev->dev); struct emac_adapter *adpt = netdev_priv(netdev); + netif_carrier_off(netdev); + netif_tx_disable(netdev); + unregister_netdev(netdev); netif_napi_del(&adpt->rx_q.napi); + free_irq(adpt->irq.irq, &adpt->irq); + cancel_work_sync(&adpt->work_thread); + emac_clks_teardown(adpt); put_device(&adpt->phydev->mdio.dev); mdiobus_unregister(adpt->mii_bus); - free_netdev(netdev); if (adpt->phy.digital) iounmap(adpt->phy.digital); iounmap(adpt->phy.base); + free_netdev(netdev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/qca_debug.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/qca_debug.c @@ -30,6 +30,8 @@ #define QCASPI_MAX_REGS 0x20 +#define QCASPI_RX_MAX_FRAMES 4 + static const u16 qcaspi_spi_regs[] = { SPI_REG_BFR_SIZE, SPI_REG_WRBUF_SPC_AVA, @@ -249,31 +251,30 @@ { struct qcaspi *qca = netdev_priv(dev); - ring->rx_max_pending = 4; + ring->rx_max_pending = QCASPI_RX_MAX_FRAMES; ring->tx_max_pending = TX_RING_MAX_LEN; - ring->rx_pending = 4; + ring->rx_pending = QCASPI_RX_MAX_FRAMES; ring->tx_pending = qca->txr.count; } static int qcaspi_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) { - const struct net_device_ops *ops = dev->netdev_ops; struct qcaspi *qca = netdev_priv(dev); - if ((ring->rx_pending) || + if (ring->rx_pending != QCASPI_RX_MAX_FRAMES || (ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - if (netif_running(dev)) - ops->ndo_stop(dev); + if (qca->spi_thread) + kthread_park(qca->spi_thread); qca->txr.count = max_t(u32, ring->tx_pending, TX_RING_MIN_LEN); qca->txr.count = min_t(u16, qca->txr.count, TX_RING_MAX_LEN); - if (netif_running(dev)) - ops->ndo_open(dev); + if (qca->spi_thread) + kthread_unpark(qca->spi_thread); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/qca_spi.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/qca_spi.c @@ -65,7 +65,7 @@ #define QCASPI_PLUGGABLE_MIN 0 #define QCASPI_PLUGGABLE_MAX 1 -static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN; +static int qcaspi_pluggable = QCASPI_PLUGGABLE_MAX; module_param(qcaspi_pluggable, int, 0); MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no)."); @@ -434,7 +434,7 @@ skb_put(qca->rx_skb, retcode); qca->rx_skb->protocol = eth_type_trans( qca->rx_skb, qca->rx_skb->dev); - qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_checksum_none_assert(qca->rx_skb); netif_rx_ni(qca->rx_skb); qca->rx_skb = netdev_alloc_skb_ip_align(net_dev, net_dev->mtu + VLAN_ETH_HLEN); @@ -573,9 +573,20 @@ netdev_info(qca->net_dev, "SPI thread created\n"); while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_park()) { + netif_tx_disable(qca->net_dev); + netif_carrier_off(qca->net_dev); + qcaspi_flush_tx_ring(qca); + kthread_parkme(); + if (qca->sync == QCASPI_SYNC_READY) { + netif_carrier_on(qca->net_dev); + netif_wake_queue(qca->net_dev); + } + continue; + } + if ((qca->intr_req == qca->intr_svc) && - (qca->txr.skb[qca->txr.head] == NULL) && - (qca->sync == QCASPI_SYNC_READY)) + !qca->txr.skb[qca->txr.head]) schedule(); set_current_state(TASK_RUNNING); @@ -602,11 +613,17 @@ if (intr_cause & SPI_INT_CPU_ON) { qcaspi_qca7k_sync(qca, QCASPI_EVENT_CPUON); + /* Frame decoding in progress */ + if (qca->frm_handle.state != qca->frm_handle.init) + qca->net_dev->stats.rx_dropped++; + + qcafrm_fsm_init_spi(&qca->frm_handle); + qca->stats.device_reset++; + /* not synced. */ if (qca->sync != QCASPI_SYNC_READY) continue; - qca->stats.device_reset++; netif_wake_queue(qca->net_dev); netif_carrier_on(qca->net_dev); } @@ -806,7 +823,6 @@ dev->mtu = QCAFRM_MAX_MTU; dev->type = ARPHRD_ETHER; - qca->clkspeed = qcaspi_clkspeed; qca->burst_len = qcaspi_burst_len; qca->spi_thread = NULL; qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN + @@ -895,17 +911,15 @@ legacy_mode = of_property_read_bool(spi->dev.of_node, "qca,legacy-mode"); - if (qcaspi_clkspeed == 0) { - if (spi->max_speed_hz) - qcaspi_clkspeed = spi->max_speed_hz; - else - qcaspi_clkspeed = QCASPI_CLK_SPEED; - } - - if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) || - (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) { - dev_err(&spi->dev, "Invalid clkspeed: %d\n", - qcaspi_clkspeed); + if (qcaspi_clkspeed) + spi->max_speed_hz = qcaspi_clkspeed; + else if (!spi->max_speed_hz) + spi->max_speed_hz = QCASPI_CLK_SPEED; + + if (spi->max_speed_hz < QCASPI_CLK_SPEED_MIN || + spi->max_speed_hz > QCASPI_CLK_SPEED_MAX) { + dev_err(&spi->dev, "Invalid clkspeed: %u\n", + spi->max_speed_hz); return -EINVAL; } @@ -930,14 +944,13 @@ return -EINVAL; } - dev_info(&spi->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n", + dev_info(&spi->dev, "ver=%s, clkspeed=%u, burst_len=%d, pluggable=%d\n", QCASPI_DRV_VERSION, - qcaspi_clkspeed, + spi->max_speed_hz, qcaspi_burst_len, qcaspi_pluggable); spi->mode = SPI_MODE_3; - spi->max_speed_hz = qcaspi_clkspeed; if (spi_setup(spi) < 0) { dev_err(&spi->dev, "Unable to setup SPI device\n"); return -EFAULT; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/qca_spi.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/qca_spi.h @@ -101,7 +101,6 @@ #endif /* user configurable options */ - u32 clkspeed; u8 legacy_mode; u16 burst_len; }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/qca_uart.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/qca_uart.c @@ -107,7 +107,7 @@ skb_put(qca->rx_skb, retcode); qca->rx_skb->protocol = eth_type_trans( qca->rx_skb, qca->rx_skb->dev); - qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + skb_checksum_none_assert(qca->rx_skb); netif_rx_ni(qca->rx_skb); qca->rx_skb = netdev_alloc_skb_ip_align(netdev, netdev->mtu + --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -13,25 +13,6 @@ #include "rmnet_vnd.h" #include "rmnet_private.h" -/* Locking scheme - - * The shared resource which needs to be protected is realdev->rx_handler_data. - * For the writer path, this is using rtnl_lock(). The writer paths are - * rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These - * paths are already called with rtnl_lock() acquired in. There is also an - * ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For - * dereference here, we will need to use rtnl_dereference(). Dev list writing - * needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link(). - * For the reader path, the real_dev->rx_handler_data is called in the TX / RX - * path. We only need rcu_read_lock() for these scenarios. In these cases, - * the rcu_read_lock() is held in __dev_queue_xmit() and - * netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl() - * to get the relevant information. For dev list reading, we again acquire - * rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu(). - * We also use unregister_netdevice_many() to free all rmnet devices in - * rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in - * same context. - */ - /* Local Definitions and Declarations */ static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = { @@ -51,9 +32,10 @@ return rtnl_dereference(real_dev->rx_handler_data); } -static int rmnet_unregister_real_device(struct net_device *real_dev, - struct rmnet_port *port) +static int rmnet_unregister_real_device(struct net_device *real_dev) { + struct rmnet_port *port = rmnet_get_port_rtnl(real_dev); + if (port->nr_rmnet_devs) return -EINVAL; @@ -61,22 +43,27 @@ kfree(port); - /* release reference on real_dev */ - dev_put(real_dev); - netdev_dbg(real_dev, "Removed from rmnet\n"); return 0; } -static int rmnet_register_real_device(struct net_device *real_dev) +static int rmnet_register_real_device(struct net_device *real_dev, + struct netlink_ext_ack *extack) { struct rmnet_port *port; int rc, entry; ASSERT_RTNL(); - if (rmnet_is_real_dev_registered(real_dev)) + if (rmnet_is_real_dev_registered(real_dev)) { + port = rmnet_get_port_rtnl(real_dev); + if (port->rmnet_mode != RMNET_EPMODE_VND) { + NL_SET_ERR_MSG_MOD(extack, "bridge device already exists"); + return -EINVAL; + } + return 0; + } port = kzalloc(sizeof(*port), GFP_ATOMIC); if (!port) @@ -89,9 +76,6 @@ return -EBUSY; } - /* hold on to real dev for MAP data */ - dev_hold(real_dev); - for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++) INIT_HLIST_HEAD(&port->muxed_ep[entry]); @@ -99,28 +83,33 @@ return 0; } -static void rmnet_unregister_bridge(struct net_device *dev, - struct rmnet_port *port) +static void rmnet_unregister_bridge(struct rmnet_port *port) { - struct rmnet_port *bridge_port; - struct net_device *bridge_dev; + struct net_device *bridge_dev, *real_dev, *rmnet_dev; + struct rmnet_port *real_port; if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) return; - /* bridge slave handling */ + rmnet_dev = port->rmnet_dev; if (!port->nr_rmnet_devs) { - bridge_dev = port->bridge_ep; - - bridge_port = rmnet_get_port_rtnl(bridge_dev); - bridge_port->bridge_ep = NULL; - bridge_port->rmnet_mode = RMNET_EPMODE_VND; + /* bridge device */ + real_dev = port->bridge_ep; + bridge_dev = port->dev; + + real_port = rmnet_get_port_rtnl(real_dev); + real_port->bridge_ep = NULL; + real_port->rmnet_mode = RMNET_EPMODE_VND; } else { + /* real device */ bridge_dev = port->bridge_ep; - bridge_port = rmnet_get_port_rtnl(bridge_dev); - rmnet_unregister_real_device(bridge_dev, bridge_port); + port->bridge_ep = NULL; + port->rmnet_mode = RMNET_EPMODE_VND; } + + netdev_upper_dev_unlink(bridge_dev, rmnet_dev); + rmnet_unregister_real_device(bridge_dev); } static int rmnet_newlink(struct net *src_net, struct net_device *dev, @@ -135,6 +124,11 @@ int err = 0; u16 mux_id; + if (!tb[IFLA_LINK]) { + NL_SET_ERR_MSG_MOD(extack, "link not specified"); + return -EINVAL; + } + real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); if (!real_dev || !dev) return -ENODEV; @@ -148,7 +142,7 @@ mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); - err = rmnet_register_real_device(real_dev); + err = rmnet_register_real_device(real_dev, extack); if (err) goto err0; @@ -157,7 +151,12 @@ if (err) goto err1; + err = netdev_upper_dev_link(real_dev, dev, extack); + if (err < 0) + goto err2; + port->rmnet_mode = mode; + port->rmnet_dev = dev; hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); @@ -173,8 +172,11 @@ return 0; +err2: + unregister_netdevice(dev); + rmnet_vnd_dellink(mux_id, port, ep); err1: - rmnet_unregister_real_device(real_dev, port); + rmnet_unregister_real_device(real_dev); err0: kfree(ep); return err; @@ -183,77 +185,74 @@ static void rmnet_dellink(struct net_device *dev, struct list_head *head) { struct rmnet_priv *priv = netdev_priv(dev); - struct net_device *real_dev; + struct net_device *real_dev, *bridge_dev; + struct rmnet_port *real_port, *bridge_port; struct rmnet_endpoint *ep; - struct rmnet_port *port; - u8 mux_id; + u8 mux_id = priv->mux_id; real_dev = priv->real_dev; - if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) + if (!rmnet_is_real_dev_registered(real_dev)) return; - port = rmnet_get_port_rtnl(real_dev); - - mux_id = rmnet_vnd_get_mux(dev); + real_port = rmnet_get_port_rtnl(real_dev); + bridge_dev = real_port->bridge_ep; + if (bridge_dev) { + bridge_port = rmnet_get_port_rtnl(bridge_dev); + rmnet_unregister_bridge(bridge_port); + } - ep = rmnet_get_endpoint(port, mux_id); + ep = rmnet_get_endpoint(real_port, mux_id); if (ep) { hlist_del_init_rcu(&ep->hlnode); - rmnet_unregister_bridge(dev, port); - rmnet_vnd_dellink(mux_id, port, ep); + rmnet_vnd_dellink(mux_id, real_port, ep); kfree(ep); } - rmnet_unregister_real_device(real_dev, port); + netdev_upper_dev_unlink(real_dev, dev); + rmnet_unregister_real_device(real_dev); unregister_netdevice_queue(dev, head); } -static void rmnet_force_unassociate_device(struct net_device *dev) +static void rmnet_force_unassociate_device(struct net_device *real_dev) { - struct net_device *real_dev = dev; struct hlist_node *tmp_ep; struct rmnet_endpoint *ep; struct rmnet_port *port; unsigned long bkt_ep; LIST_HEAD(list); - if (!rmnet_is_real_dev_registered(real_dev)) - return; - - ASSERT_RTNL(); - - port = rmnet_get_port_rtnl(dev); - - rcu_read_lock(); - rmnet_unregister_bridge(dev, port); - - hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { - unregister_netdevice_queue(ep->egress_dev, &list); - rmnet_vnd_dellink(ep->mux_id, port, ep); + port = rmnet_get_port_rtnl(real_dev); - hlist_del_init_rcu(&ep->hlnode); - kfree(ep); + if (port->nr_rmnet_devs) { + /* real device */ + rmnet_unregister_bridge(port); + hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { + unregister_netdevice_queue(ep->egress_dev, &list); + netdev_upper_dev_unlink(real_dev, ep->egress_dev); + rmnet_vnd_dellink(ep->mux_id, port, ep); + hlist_del_init_rcu(&ep->hlnode); + kfree(ep); + } + rmnet_unregister_real_device(real_dev); + unregister_netdevice_many(&list); + } else { + rmnet_unregister_bridge(port); } - - rcu_read_unlock(); - unregister_netdevice_many(&list); - - rmnet_unregister_real_device(real_dev, port); } static int rmnet_config_notify_cb(struct notifier_block *nb, unsigned long event, void *data) { - struct net_device *dev = netdev_notifier_info_to_dev(data); + struct net_device *real_dev = netdev_notifier_info_to_dev(data); - if (!dev) + if (!rmnet_is_real_dev_registered(real_dev)) return NOTIFY_DONE; switch (event) { case NETDEV_UNREGISTER: - netdev_dbg(dev, "Kernel unregister\n"); - rmnet_force_unassociate_device(dev); + netdev_dbg(real_dev, "Kernel unregister\n"); + rmnet_force_unassociate_device(real_dev); break; default: @@ -288,32 +287,41 @@ { struct rmnet_priv *priv = netdev_priv(dev); struct net_device *real_dev; - struct rmnet_endpoint *ep; struct rmnet_port *port; u16 mux_id; if (!dev) return -ENODEV; - real_dev = __dev_get_by_index(dev_net(dev), - nla_get_u32(tb[IFLA_LINK])); - - if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) + real_dev = priv->real_dev; + if (!rmnet_is_real_dev_registered(real_dev)) return -ENODEV; port = rmnet_get_port_rtnl(real_dev); if (data[IFLA_RMNET_MUX_ID]) { mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); - ep = rmnet_get_endpoint(port, priv->mux_id); - if (!ep) - return -ENODEV; - hlist_del_init_rcu(&ep->hlnode); - hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); + if (mux_id != priv->mux_id) { + struct rmnet_endpoint *ep; - ep->mux_id = mux_id; - priv->mux_id = mux_id; + ep = rmnet_get_endpoint(port, priv->mux_id); + if (!ep) + return -ENODEV; + + if (rmnet_get_endpoint(port, mux_id)) { + NL_SET_ERR_MSG_MOD(extack, + "MUX ID already exists"); + return -EINVAL; + } + + hlist_del_init_rcu(&ep->hlnode); + hlist_add_head_rcu(&ep->hlnode, + &port->muxed_ep[mux_id]); + + ep->mux_id = mux_id; + priv->mux_id = mux_id; + } } if (data[IFLA_RMNET_FLAGS]) { @@ -367,7 +375,7 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = { .kind = "rmnet", - .maxtype = __IFLA_RMNET_MAX, + .maxtype = IFLA_RMNET_MAX, .priv_size = sizeof(struct rmnet_priv), .setup = rmnet_vnd_setup, .validate = rmnet_rtnl_validate, @@ -379,11 +387,10 @@ .fill_info = rmnet_fill_info, }; -/* Needs either rcu_read_lock() or rtnl lock */ -struct rmnet_port *rmnet_get_port(struct net_device *real_dev) +struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev) { if (rmnet_is_real_dev_registered(real_dev)) - return rcu_dereference_rtnl(real_dev->rx_handler_data); + return rcu_dereference_bh(real_dev->rx_handler_data); else return NULL; } @@ -409,7 +416,7 @@ struct rmnet_port *port, *slave_port; int err; - port = rmnet_get_port(real_dev); + port = rmnet_get_port_rtnl(real_dev); /* If there is more than one rmnet dev attached, its probably being * used for muxing. Skip the briding in that case @@ -420,13 +427,21 @@ if (rmnet_is_real_dev_registered(slave_dev)) return -EBUSY; - err = rmnet_register_real_device(slave_dev); + err = rmnet_register_real_device(slave_dev, extack); if (err) return -EBUSY; - slave_port = rmnet_get_port(slave_dev); + err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL, + extack); + if (err) { + rmnet_unregister_real_device(slave_dev); + return err; + } + + slave_port = rmnet_get_port_rtnl(slave_dev); slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; slave_port->bridge_ep = real_dev; + slave_port->rmnet_dev = rmnet_dev; port->rmnet_mode = RMNET_EPMODE_BRIDGE; port->bridge_ep = slave_dev; @@ -438,16 +453,9 @@ int rmnet_del_bridge(struct net_device *rmnet_dev, struct net_device *slave_dev) { - struct rmnet_priv *priv = netdev_priv(rmnet_dev); - struct net_device *real_dev = priv->real_dev; - struct rmnet_port *port, *slave_port; + struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev); - port = rmnet_get_port(real_dev); - port->rmnet_mode = RMNET_EPMODE_VND; - port->bridge_ep = NULL; - - slave_port = rmnet_get_port(slave_dev); - rmnet_unregister_real_device(slave_dev, slave_port); + rmnet_unregister_bridge(port); netdev_dbg(slave_dev, "removed from rmnet as slave\n"); return 0; @@ -473,8 +481,8 @@ static void __exit rmnet_exit(void) { - unregister_netdevice_notifier(&rmnet_dev_notifier); rtnl_link_unregister(&rmnet_link_ops); + unregister_netdevice_notifier(&rmnet_dev_notifier); } module_init(rmnet_init) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -28,6 +28,7 @@ u8 rmnet_mode; struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP]; struct net_device *bridge_ep; + struct net_device *rmnet_dev; }; extern struct rtnl_link_ops rmnet_link_ops; @@ -65,7 +66,7 @@ struct rmnet_priv_stats stats; }; -struct rmnet_port *rmnet_get_port(struct net_device *real_dev); +struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev); struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id); int rmnet_add_bridge(struct net_device *rmnet_dev, struct net_device *slave_dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/rmnet/rmnet_handlers.c @@ -159,6 +159,9 @@ static void rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev) { + if (skb_mac_header_was_set(skb)) + skb_push(skb, skb->mac_len); + if (bridge_dev) { skb->dev = bridge_dev; dev_queue_xmit(skb); @@ -184,7 +187,12 @@ return RX_HANDLER_PASS; dev = skb->dev; - port = rmnet_get_port(dev); + port = rmnet_get_port_rcu(dev); + if (unlikely(!port)) { + atomic_long_inc(&skb->dev->rx_nohandler); + kfree_skb(skb); + goto done; + } switch (port->rmnet_mode) { case RMNET_EPMODE_VND: @@ -217,7 +225,7 @@ skb->dev = priv->real_dev; mux_id = priv->mux_id; - port = rmnet_get_port(skb->dev); + port = rmnet_get_port_rcu(skb->dev); if (!port) goto drop; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -266,14 +266,6 @@ return 0; } -u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev) -{ - struct rmnet_priv *priv; - - priv = netdev_priv(rmnet_dev); - return priv->mux_id; -} - int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) { netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +++ linux-oracle-5.4.0/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h @@ -16,6 +16,5 @@ struct rmnet_endpoint *ep); void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev); void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev); -u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); void rmnet_vnd_setup(struct net_device *dev); #endif /* _RMNET_VND_H_ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/rdc/r6040.c +++ linux-oracle-5.4.0/drivers/net/ethernet/rdc/r6040.c @@ -119,6 +119,8 @@ #define PHY_ST 0x8A /* PHY status register */ #define MAC_SM 0xAC /* MAC status machine */ #define MAC_SM_RST 0x0002 /* MAC status machine reset */ +#define MD_CSC 0xb6 /* MDC speed control register */ +#define MD_CSC_DEFAULT 0x0030 #define MAC_ID 0xBE /* Identifier register */ #define TX_DCNT 0x80 /* TX descriptor count */ @@ -354,8 +356,9 @@ { void __iomem *ioaddr = lp->base; int limit = MAC_DEF_TIMEOUT; - u16 cmd; + u16 cmd, md_csc; + md_csc = ioread16(ioaddr + MD_CSC); iowrite16(MAC_RST, ioaddr + MCR1); while (limit--) { cmd = ioread16(ioaddr + MCR1); @@ -367,6 +370,10 @@ iowrite16(MAC_SM_RST, ioaddr + MAC_SM); iowrite16(0, ioaddr + MAC_SM); mdelay(5); + + /* Restore MDIO clock frequency */ + if (md_csc != MD_CSC_DEFAULT) + iowrite16(md_csc, ioaddr + MD_CSC); } static void r6040_init_mac_regs(struct net_device *dev) @@ -1155,10 +1162,12 @@ err = register_netdev(dev); if (err) { dev_err(&pdev->dev, "Failed to register net device\n"); - goto err_out_mdio_unregister; + goto err_out_phy_disconnect; } return 0; +err_out_phy_disconnect: + phy_disconnect(dev->phydev); err_out_mdio_unregister: mdiobus_unregister(lp->mii_bus); err_out_mdio: @@ -1182,6 +1191,7 @@ struct r6040_private *lp = netdev_priv(dev); unregister_netdev(dev); + phy_disconnect(dev->phydev); mdiobus_unregister(lp->mii_bus); mdiobus_free(lp->mii_bus); netif_napi_del(&lp->napi); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/realtek/r8169_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/realtek/r8169_main.c @@ -52,6 +52,7 @@ #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" #define FIRMWARE_8168H_1 "rtl_nic/rtl8168h-1.fw" #define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw" +#define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw" #define FIRMWARE_8107E_1 "rtl_nic/rtl8107e-1.fw" #define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw" #define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw" @@ -135,6 +136,7 @@ RTL_GIGA_MAC_VER_49, RTL_GIGA_MAC_VER_50, RTL_GIGA_MAC_VER_51, + RTL_GIGA_MAC_VER_52, RTL_GIGA_MAC_VER_60, RTL_GIGA_MAC_VER_61, RTL_GIGA_MAC_NONE @@ -202,6 +204,7 @@ [RTL_GIGA_MAC_VER_49] = {"RTL8168ep/8111ep" }, [RTL_GIGA_MAC_VER_50] = {"RTL8168ep/8111ep" }, [RTL_GIGA_MAC_VER_51] = {"RTL8168ep/8111ep" }, + [RTL_GIGA_MAC_VER_52] = {"RTL8168fp/RTL8117", FIRMWARE_8168FP_3}, [RTL_GIGA_MAC_VER_60] = {"RTL8125" }, [RTL_GIGA_MAC_VER_61] = {"RTL8125", FIRMWARE_8125A_3}, }; @@ -212,6 +215,7 @@ { PCI_VDEVICE(REALTEK, 0x8129) }, { PCI_VDEVICE(REALTEK, 0x8136), RTL_CFG_NO_GBIT }, { PCI_VDEVICE(REALTEK, 0x8161) }, + { PCI_VDEVICE(REALTEK, 0x8162) }, { PCI_VDEVICE(REALTEK, 0x8167) }, { PCI_VDEVICE(REALTEK, 0x8168) }, { PCI_VDEVICE(NCUBE, 0x8168) }, @@ -622,7 +626,34 @@ __le64 rx_broadcast; __le32 rx_multicast; __le16 tx_aborted; - __le16 tx_underun; + __le16 tx_underrun; + /* new since RTL8125 */ + __le64 tx_octets; + __le64 rx_octets; + __le64 rx_multicast64; + __le64 tx_unicast64; + __le64 tx_broadcast64; + __le64 tx_multicast64; + __le32 tx_pause_on; + __le32 tx_pause_off; + __le32 tx_pause_all; + __le32 tx_deferred; + __le32 tx_late_collision; + __le32 tx_all_collision; + __le32 tx_aborted32; + __le32 align_errors32; + __le32 rx_frame_too_long; + __le32 rx_runt; + __le32 rx_pause_on; + __le32 rx_pause_off; + __le32 rx_pause_all; + __le32 rx_unknown_opcode; + __le32 rx_mac_error; + __le32 tx_underrun32; + __le32 rx_mac_missed; + __le32 rx_tcam_dropped; + __le32 tdu; + __le32 rdu; }; struct rtl8169_tc_offsets { @@ -680,6 +711,7 @@ struct rtl8169_counters *counters; struct rtl8169_tc_offsets tc_offset; u32 saved_wolopts; + int eee_adv; const char *fw_name; struct rtl_fw *rtl_fw; @@ -712,6 +744,7 @@ MODULE_FIRMWARE(FIRMWARE_8168G_3); MODULE_FIRMWARE(FIRMWARE_8168H_1); MODULE_FIRMWARE(FIRMWARE_8168H_2); +MODULE_FIRMWARE(FIRMWARE_8168FP_3); MODULE_FIRMWARE(FIRMWARE_8107E_1); MODULE_FIRMWARE(FIRMWARE_8107E_2); MODULE_FIRMWARE(FIRMWARE_8125A_3); @@ -741,12 +774,6 @@ RTL_W8(tp, Cfg9346, Cfg9346_Unlock); } -static void rtl_tx_performance_tweak(struct rtl8169_private *tp, u16 force) -{ - pcie_capability_clear_and_set_word(tp->pci_dev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_READRQ, force); -} - static bool rtl_is_8125(struct rtl8169_private *tp) { return tp->mac_version >= RTL_GIGA_MAC_VER_60; @@ -756,7 +783,7 @@ { return tp->mac_version >= RTL_GIGA_MAC_VER_34 && tp->mac_version != RTL_GIGA_MAC_VER_39 && - tp->mac_version <= RTL_GIGA_MAC_VER_51; + tp->mac_version <= RTL_GIGA_MAC_VER_52; } static bool rtl_supports_eee(struct rtl8169_private *tp) @@ -1092,6 +1119,17 @@ rtl_writephy(tp, reg_addr, (val & ~m) | p); } +static void r8168g_phy_param(struct phy_device *phydev, u16 parm, + u16 mask, u16 val) +{ + int oldpage = phy_select_page(phydev, 0x0a43); + + __phy_write(phydev, 0x13, parm); + __phy_modify(phydev, 0x14, mask, val); + + phy_restore_page(phydev, oldpage, 0); +} + DECLARE_RTL_COND(rtl_ephyar_cond) { return RTL_R32(tp, EPHYAR) & EPHYAR_FLAG; @@ -1115,6 +1153,13 @@ RTL_R32(tp, EPHYAR) & EPHYAR_DATA_MASK : ~0; } +static void r8168fp_adjust_ocp_cmd(struct rtl8169_private *tp, u32 *cmd, int type) +{ + /* based on RTL8168FP_OOBMAC_BASE in vendor driver */ + if (tp->mac_version == RTL_GIGA_MAC_VER_52 && type == ERIAR_OOB) + *cmd |= 0x7f0 << 18; +} + DECLARE_RTL_COND(rtl_eriar_cond) { return RTL_R32(tp, ERIAR) & ERIAR_FLAG; @@ -1123,9 +1168,12 @@ static void _rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, u32 val, int type) { + u32 cmd = ERIAR_WRITE_CMD | type | mask | addr; + BUG_ON((addr & 3) || (mask == 0)); RTL_W32(tp, ERIDR, val); - RTL_W32(tp, ERIAR, ERIAR_WRITE_CMD | type | mask | addr); + r8168fp_adjust_ocp_cmd(tp, &cmd, type); + RTL_W32(tp, ERIAR, cmd); rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); } @@ -1138,7 +1186,10 @@ static u32 _rtl_eri_read(struct rtl8169_private *tp, int addr, int type) { - RTL_W32(tp, ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); + u32 cmd = ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr; + + r8168fp_adjust_ocp_cmd(tp, &cmd, type); + RTL_W32(tp, ERIAR, cmd); return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? RTL_R32(tp, ERIDR) : ~0; @@ -1262,9 +1313,7 @@ case RTL_GIGA_MAC_VER_31: rtl8168dp_driver_start(tp); break; - case RTL_GIGA_MAC_VER_49: - case RTL_GIGA_MAC_VER_50: - case RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: rtl8168ep_driver_start(tp); break; default: @@ -1296,9 +1345,7 @@ case RTL_GIGA_MAC_VER_31: rtl8168dp_driver_stop(tp); break; - case RTL_GIGA_MAC_VER_49: - case RTL_GIGA_MAC_VER_50: - case RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: rtl8168ep_driver_stop(tp); break; default: @@ -1326,9 +1373,7 @@ case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: return r8168dp_check_dash(tp); - case RTL_GIGA_MAC_VER_49: - case RTL_GIGA_MAC_VER_50: - case RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: return r8168ep_check_dash(tp); default: return false; @@ -1503,7 +1548,7 @@ break; case RTL_GIGA_MAC_VER_34: case RTL_GIGA_MAC_VER_37: - case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_39 ... RTL_GIGA_MAC_VER_52: options = RTL_R8(tp, Config2) & ~PME_SIGNAL; if (wolopts) options |= PME_SIGNAL; @@ -1516,6 +1561,7 @@ rtl_lock_config_regs(tp); device_set_wakeup_enable(tp_to_dev(tp), wolopts); + tp->dev->wol_enabled = wolopts ? 1 : 0; } static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) @@ -1798,14 +1844,14 @@ data[9] = le64_to_cpu(counters->rx_broadcast); data[10] = le32_to_cpu(counters->rx_multicast); data[11] = le16_to_cpu(counters->tx_aborted); - data[12] = le16_to_cpu(counters->tx_underun); + data[12] = le16_to_cpu(counters->tx_underrun); } static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) { switch(stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); + memcpy(data, rtl8169_gstrings, sizeof(rtl8169_gstrings)); break; } } @@ -2074,6 +2120,10 @@ } ret = phy_ethtool_set_eee(tp->phydev, data); + + if (!ret) + tp->eee_adv = phy_read_mmd(dev->phydev, MDIO_MMD_AN, + MDIO_AN_EEE_ADV); out: pm_runtime_put_noidle(d); return ret; @@ -2104,10 +2154,16 @@ static void rtl_enable_eee(struct rtl8169_private *tp) { struct phy_device *phydev = tp->phydev; - int supported = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); + int adv; + + /* respect EEE advertisement the user may have set */ + if (tp->eee_adv >= 0) + adv = tp->eee_adv; + else + adv = phy_read_mmd(phydev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE); - if (supported > 0) - phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, supported); + if (adv >= 0) + phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, adv); } static void rtl8169_get_mac_version(struct rtl8169_private *tp) @@ -2132,6 +2188,9 @@ { 0x7cf, 0x608, RTL_GIGA_MAC_VER_60 }, { 0x7c8, 0x608, RTL_GIGA_MAC_VER_61 }, + /* RTL8117 */ + { 0x7cf, 0x54a, RTL_GIGA_MAC_VER_52 }, + /* 8168EP family. */ { 0x7cf, 0x502, RTL_GIGA_MAC_VER_51 }, { 0x7cf, 0x501, RTL_GIGA_MAC_VER_50 }, @@ -2190,6 +2249,8 @@ { 0x7cf, 0x348, RTL_GIGA_MAC_VER_07 }, { 0x7cf, 0x248, RTL_GIGA_MAC_VER_07 }, { 0x7cf, 0x340, RTL_GIGA_MAC_VER_13 }, + /* RTL8401, reportedly works if treated as RTL8101e */ + { 0x7cf, 0x240, RTL_GIGA_MAC_VER_13 }, { 0x7cf, 0x343, RTL_GIGA_MAC_VER_10 }, { 0x7cf, 0x342, RTL_GIGA_MAC_VER_16 }, { 0x7c8, 0x348, RTL_GIGA_MAC_VER_09 }, @@ -2256,8 +2317,11 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) { /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ - if (tp->rtl_fw) + if (tp->rtl_fw) { rtl_fw_write_firmware(tp, tp->rtl_fw); + /* At least one firmware doesn't reset tp->ocp_base. */ + tp->ocp_base = OCP_STD_PHY_BASE; + } } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -3228,12 +3292,8 @@ phy_modify_paged(phydev, 0x0bcc, 0x14, BIT(8), 0); phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(7) | BIT(6)); - phy_write(phydev, 0x1f, 0x0a43); - phy_write(phydev, 0x13, 0x8084); - phy_clear_bits(phydev, 0x14, BIT(14) | BIT(13)); - phy_set_bits(phydev, 0x10, BIT(12) | BIT(1) | BIT(0)); - - phy_write(phydev, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x8084, 0x6000, 0x0000); + phy_modify_paged(phydev, 0x0a43, 0x10, 0x0000, 0x1003); } static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) @@ -3263,9 +3323,7 @@ phy_modify_paged(tp->phydev, 0x0a4b, 0x11, 0, BIT(2)); /* Enable UC LPF tune function */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x8012); - rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000); + r8168g_phy_param(tp->phydev, 0x8012, 0x0000, 0x8000); phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14)); @@ -3295,73 +3353,48 @@ static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp) { + struct phy_device *phydev = tp->phydev; u16 dout_tapbin; u32 data; rtl_apply_firmware(tp); /* CHN EST parameters adjust - giga master */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x809b); - rtl_w0w1_phy(tp, 0x14, 0x8000, 0xf800); - rtl_writephy(tp, 0x13, 0x80a2); - rtl_w0w1_phy(tp, 0x14, 0x8000, 0xff00); - rtl_writephy(tp, 0x13, 0x80a4); - rtl_w0w1_phy(tp, 0x14, 0x8500, 0xff00); - rtl_writephy(tp, 0x13, 0x809c); - rtl_w0w1_phy(tp, 0x14, 0xbd00, 0xff00); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x809b, 0xf800, 0x8000); + r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x8000); + r8168g_phy_param(phydev, 0x80a4, 0xff00, 0x8500); + r8168g_phy_param(phydev, 0x809c, 0xff00, 0xbd00); /* CHN EST parameters adjust - giga slave */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x80ad); - rtl_w0w1_phy(tp, 0x14, 0x7000, 0xf800); - rtl_writephy(tp, 0x13, 0x80b4); - rtl_w0w1_phy(tp, 0x14, 0x5000, 0xff00); - rtl_writephy(tp, 0x13, 0x80ac); - rtl_w0w1_phy(tp, 0x14, 0x4000, 0xff00); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x7000); + r8168g_phy_param(phydev, 0x80b4, 0xff00, 0x5000); + r8168g_phy_param(phydev, 0x80ac, 0xff00, 0x4000); /* CHN EST parameters adjust - fnet */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x808e); - rtl_w0w1_phy(tp, 0x14, 0x1200, 0xff00); - rtl_writephy(tp, 0x13, 0x8090); - rtl_w0w1_phy(tp, 0x14, 0xe500, 0xff00); - rtl_writephy(tp, 0x13, 0x8092); - rtl_w0w1_phy(tp, 0x14, 0x9f00, 0xff00); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x808e, 0xff00, 0x1200); + r8168g_phy_param(phydev, 0x8090, 0xff00, 0xe500); + r8168g_phy_param(phydev, 0x8092, 0xff00, 0x9f00); /* enable R-tune & PGA-retune function */ dout_tapbin = 0; - rtl_writephy(tp, 0x1f, 0x0a46); - data = rtl_readphy(tp, 0x13); + data = phy_read_paged(phydev, 0x0a46, 0x13); data &= 3; data <<= 2; dout_tapbin |= data; - data = rtl_readphy(tp, 0x12); + data = phy_read_paged(phydev, 0x0a46, 0x12); data &= 0xc000; data >>= 14; dout_tapbin |= data; dout_tapbin = ~(dout_tapbin^0x08); dout_tapbin <<= 12; dout_tapbin &= 0xf000; - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x827a); - rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000); - rtl_writephy(tp, 0x13, 0x827b); - rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000); - rtl_writephy(tp, 0x13, 0x827c); - rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000); - rtl_writephy(tp, 0x13, 0x827d); - rtl_w0w1_phy(tp, 0x14, dout_tapbin, 0xf000); - - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x0811); - rtl_w0w1_phy(tp, 0x14, 0x0800, 0x0000); - rtl_writephy(tp, 0x1f, 0x0a42); - rtl_w0w1_phy(tp, 0x16, 0x0002, 0x0000); - rtl_writephy(tp, 0x1f, 0x0000); + + r8168g_phy_param(phydev, 0x827a, 0xf000, dout_tapbin); + r8168g_phy_param(phydev, 0x827b, 0xf000, dout_tapbin); + r8168g_phy_param(phydev, 0x827c, 0xf000, dout_tapbin); + r8168g_phy_param(phydev, 0x827d, 0xf000, dout_tapbin); + r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800); + phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002); /* enable GPHY 10M */ phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11)); @@ -3369,22 +3402,13 @@ /* SAR ADC performance */ phy_modify_paged(tp->phydev, 0x0bca, 0x17, BIT(12) | BIT(13), BIT(14)); - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x803f); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x8047); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x804f); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x8057); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x805f); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x8067); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x13, 0x806f); - rtl_w0w1_phy(tp, 0x14, 0x0000, 0x3000); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x803f, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x8047, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x804f, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x8057, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x805f, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x8067, 0x3000, 0x0000); + r8168g_phy_param(phydev, 0x806f, 0x3000, 0x0000); /* disable phy pfm mode */ phy_modify_paged(tp->phydev, 0x0a44, 0x11, BIT(7), 0); @@ -3397,24 +3421,18 @@ static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp) { u16 ioffset_p3, ioffset_p2, ioffset_p1, ioffset_p0; + struct phy_device *phydev = tp->phydev; u16 rlen; u32 data; rtl_apply_firmware(tp); /* CHIN EST parameter update */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x808a); - rtl_w0w1_phy(tp, 0x14, 0x000a, 0x003f); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x808a, 0x003f, 0x000a); /* enable R-tune & PGA-retune function */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x0811); - rtl_w0w1_phy(tp, 0x14, 0x0800, 0x0000); - rtl_writephy(tp, 0x1f, 0x0a42); - rtl_w0w1_phy(tp, 0x16, 0x0002, 0x0000); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x0811, 0x0000, 0x0800); + phy_modify_paged(phydev, 0x0a42, 0x16, 0x0000, 0x0002); /* enable GPHY 10M */ phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11)); @@ -3434,26 +3452,20 @@ data = (ioffset_p3<<12)|(ioffset_p2<<8)|(ioffset_p1<<4)|(ioffset_p0); if ((ioffset_p3 != 0x0f) || (ioffset_p2 != 0x0f) || - (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f)) { - rtl_writephy(tp, 0x1f, 0x0bcf); - rtl_writephy(tp, 0x16, data); - rtl_writephy(tp, 0x1f, 0x0000); - } + (ioffset_p1 != 0x0f) || (ioffset_p0 != 0x0f)) + phy_write_paged(phydev, 0x0bcf, 0x16, data); /* Modify rlen (TX LPF corner frequency) level */ - rtl_writephy(tp, 0x1f, 0x0bcd); - data = rtl_readphy(tp, 0x16); + data = phy_read_paged(phydev, 0x0bcd, 0x16); data &= 0x000f; rlen = 0; if (data > 3) rlen = data - 3; data = rlen | (rlen<<4) | (rlen<<8) | (rlen<<12); - rtl_writephy(tp, 0x17, data); - rtl_writephy(tp, 0x1f, 0x0bcd); - rtl_writephy(tp, 0x1f, 0x0000); + phy_write_paged(phydev, 0x0bcd, 0x17, data); /* disable phy pfm mode */ - phy_modify_paged(tp->phydev, 0x0a44, 0x11, BIT(7), 0); + phy_modify_paged(phydev, 0x0a44, 0x11, BIT(7), 0); rtl8168g_disable_aldps(tp); rtl8168g_config_eee_phy(tp); @@ -3462,22 +3474,21 @@ static void rtl8168ep_1_hw_phy_config(struct rtl8169_private *tp) { + struct phy_device *phydev = tp->phydev; + /* Enable PHY auto speed down */ - phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2)); + phy_modify_paged(phydev, 0x0a44, 0x11, 0, BIT(3) | BIT(2)); rtl8168g_phy_adjust_10m_aldps(tp); /* Enable EEE auto-fallback function */ - phy_modify_paged(tp->phydev, 0x0a4b, 0x11, 0, BIT(2)); + phy_modify_paged(phydev, 0x0a4b, 0x11, 0, BIT(2)); /* Enable UC LPF tune function */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x8012); - rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000); /* set rg_sel_sdm_rate */ - phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14)); + phy_modify_paged(phydev, 0x0c42, 0x11, BIT(13), BIT(14)); rtl8168g_disable_aldps(tp); rtl8168g_config_eee_phy(tp); @@ -3486,63 +3497,38 @@ static void rtl8168ep_2_hw_phy_config(struct rtl8169_private *tp) { + struct phy_device *phydev = tp->phydev; + rtl8168g_phy_adjust_10m_aldps(tp); /* Enable UC LPF tune function */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x8012); - rtl_w0w1_phy(tp, 0x14, 0x8000, 0x0000); - rtl_writephy(tp, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x8012, 0x0000, 0x8000); /* Set rg_sel_sdm_rate */ phy_modify_paged(tp->phydev, 0x0c42, 0x11, BIT(13), BIT(14)); /* Channel estimation parameters */ - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x80f3); - rtl_w0w1_phy(tp, 0x14, 0x8b00, ~0x8bff); - rtl_writephy(tp, 0x13, 0x80f0); - rtl_w0w1_phy(tp, 0x14, 0x3a00, ~0x3aff); - rtl_writephy(tp, 0x13, 0x80ef); - rtl_w0w1_phy(tp, 0x14, 0x0500, ~0x05ff); - rtl_writephy(tp, 0x13, 0x80f6); - rtl_w0w1_phy(tp, 0x14, 0x6e00, ~0x6eff); - rtl_writephy(tp, 0x13, 0x80ec); - rtl_w0w1_phy(tp, 0x14, 0x6800, ~0x68ff); - rtl_writephy(tp, 0x13, 0x80ed); - rtl_w0w1_phy(tp, 0x14, 0x7c00, ~0x7cff); - rtl_writephy(tp, 0x13, 0x80f2); - rtl_w0w1_phy(tp, 0x14, 0xf400, ~0xf4ff); - rtl_writephy(tp, 0x13, 0x80f4); - rtl_w0w1_phy(tp, 0x14, 0x8500, ~0x85ff); - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x8110); - rtl_w0w1_phy(tp, 0x14, 0xa800, ~0xa8ff); - rtl_writephy(tp, 0x13, 0x810f); - rtl_w0w1_phy(tp, 0x14, 0x1d00, ~0x1dff); - rtl_writephy(tp, 0x13, 0x8111); - rtl_w0w1_phy(tp, 0x14, 0xf500, ~0xf5ff); - rtl_writephy(tp, 0x13, 0x8113); - rtl_w0w1_phy(tp, 0x14, 0x6100, ~0x61ff); - rtl_writephy(tp, 0x13, 0x8115); - rtl_w0w1_phy(tp, 0x14, 0x9200, ~0x92ff); - rtl_writephy(tp, 0x13, 0x810e); - rtl_w0w1_phy(tp, 0x14, 0x0400, ~0x04ff); - rtl_writephy(tp, 0x13, 0x810c); - rtl_w0w1_phy(tp, 0x14, 0x7c00, ~0x7cff); - rtl_writephy(tp, 0x13, 0x810b); - rtl_w0w1_phy(tp, 0x14, 0x5a00, ~0x5aff); - rtl_writephy(tp, 0x1f, 0x0a43); - rtl_writephy(tp, 0x13, 0x80d1); - rtl_w0w1_phy(tp, 0x14, 0xff00, ~0xffff); - rtl_writephy(tp, 0x13, 0x80cd); - rtl_w0w1_phy(tp, 0x14, 0x9e00, ~0x9eff); - rtl_writephy(tp, 0x13, 0x80d3); - rtl_w0w1_phy(tp, 0x14, 0x0e00, ~0x0eff); - rtl_writephy(tp, 0x13, 0x80d5); - rtl_w0w1_phy(tp, 0x14, 0xca00, ~0xcaff); - rtl_writephy(tp, 0x13, 0x80d7); - rtl_w0w1_phy(tp, 0x14, 0x8400, ~0x84ff); + r8168g_phy_param(phydev, 0x80f3, 0xff00, 0x8b00); + r8168g_phy_param(phydev, 0x80f0, 0xff00, 0x3a00); + r8168g_phy_param(phydev, 0x80ef, 0xff00, 0x0500); + r8168g_phy_param(phydev, 0x80f6, 0xff00, 0x6e00); + r8168g_phy_param(phydev, 0x80ec, 0xff00, 0x6800); + r8168g_phy_param(phydev, 0x80ed, 0xff00, 0x7c00); + r8168g_phy_param(phydev, 0x80f2, 0xff00, 0xf400); + r8168g_phy_param(phydev, 0x80f4, 0xff00, 0x8500); + r8168g_phy_param(phydev, 0x8110, 0xff00, 0xa800); + r8168g_phy_param(phydev, 0x810f, 0xff00, 0x1d00); + r8168g_phy_param(phydev, 0x8111, 0xff00, 0xf500); + r8168g_phy_param(phydev, 0x8113, 0xff00, 0x6100); + r8168g_phy_param(phydev, 0x8115, 0xff00, 0x9200); + r8168g_phy_param(phydev, 0x810e, 0xff00, 0x0400); + r8168g_phy_param(phydev, 0x810c, 0xff00, 0x7c00); + r8168g_phy_param(phydev, 0x810b, 0xff00, 0x5a00); + r8168g_phy_param(phydev, 0x80d1, 0xff00, 0xff00); + r8168g_phy_param(phydev, 0x80cd, 0xff00, 0x9e00); + r8168g_phy_param(phydev, 0x80d3, 0xff00, 0x0e00); + r8168g_phy_param(phydev, 0x80d5, 0xff00, 0xca00); + r8168g_phy_param(phydev, 0x80d7, 0xff00, 0x8400); /* Force PWM-mode */ rtl_writephy(tp, 0x1f, 0x0bcd); @@ -3561,6 +3547,46 @@ rtl_enable_eee(tp); } +static void rtl8117_hw_phy_config(struct rtl8169_private *tp) +{ + struct phy_device *phydev = tp->phydev; + + /* CHN EST parameters adjust - fnet */ + r8168g_phy_param(phydev, 0x808e, 0xff00, 0x4800); + r8168g_phy_param(phydev, 0x8090, 0xff00, 0xcc00); + r8168g_phy_param(phydev, 0x8092, 0xff00, 0xb000); + + r8168g_phy_param(phydev, 0x8088, 0xff00, 0x6000); + r8168g_phy_param(phydev, 0x808b, 0x3f00, 0x0b00); + r8168g_phy_param(phydev, 0x808d, 0x1f00, 0x0600); + r8168g_phy_param(phydev, 0x808c, 0xff00, 0xb000); + r8168g_phy_param(phydev, 0x80a0, 0xff00, 0x2800); + r8168g_phy_param(phydev, 0x80a2, 0xff00, 0x5000); + r8168g_phy_param(phydev, 0x809b, 0xf800, 0xb000); + r8168g_phy_param(phydev, 0x809a, 0xff00, 0x4b00); + r8168g_phy_param(phydev, 0x809d, 0x3f00, 0x0800); + r8168g_phy_param(phydev, 0x80a1, 0xff00, 0x7000); + r8168g_phy_param(phydev, 0x809f, 0x1f00, 0x0300); + r8168g_phy_param(phydev, 0x809e, 0xff00, 0x8800); + r8168g_phy_param(phydev, 0x80b2, 0xff00, 0x2200); + r8168g_phy_param(phydev, 0x80ad, 0xf800, 0x9800); + r8168g_phy_param(phydev, 0x80af, 0x3f00, 0x0800); + r8168g_phy_param(phydev, 0x80b3, 0xff00, 0x6f00); + r8168g_phy_param(phydev, 0x80b1, 0x1f00, 0x0300); + r8168g_phy_param(phydev, 0x80b0, 0xff00, 0x9300); + + r8168g_phy_param(phydev, 0x8011, 0x0000, 0x0800); + + /* enable GPHY 10M */ + phy_modify_paged(tp->phydev, 0x0a44, 0x11, 0, BIT(11)); + + r8168g_phy_param(phydev, 0x8016, 0x0000, 0x0400); + + rtl8168g_disable_aldps(tp); + rtl8168h_config_eee_phy(tp); + rtl_enable_eee(tp); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3657,38 +3683,22 @@ phy_modify_paged(phydev, 0xad1, 0x15, 0x0000, 0x03ff); phy_modify_paged(phydev, 0xad1, 0x16, 0x0000, 0x03ff); - phy_write(phydev, 0x1f, 0x0a43); - phy_write(phydev, 0x13, 0x80ea); - phy_modify(phydev, 0x14, 0xff00, 0xc400); - phy_write(phydev, 0x13, 0x80eb); - phy_modify(phydev, 0x14, 0x0700, 0x0300); - phy_write(phydev, 0x13, 0x80f8); - phy_modify(phydev, 0x14, 0xff00, 0x1c00); - phy_write(phydev, 0x13, 0x80f1); - phy_modify(phydev, 0x14, 0xff00, 0x3000); - phy_write(phydev, 0x13, 0x80fe); - phy_modify(phydev, 0x14, 0xff00, 0xa500); - phy_write(phydev, 0x13, 0x8102); - phy_modify(phydev, 0x14, 0xff00, 0x5000); - phy_write(phydev, 0x13, 0x8105); - phy_modify(phydev, 0x14, 0xff00, 0x3300); - phy_write(phydev, 0x13, 0x8100); - phy_modify(phydev, 0x14, 0xff00, 0x7000); - phy_write(phydev, 0x13, 0x8104); - phy_modify(phydev, 0x14, 0xff00, 0xf000); - phy_write(phydev, 0x13, 0x8106); - phy_modify(phydev, 0x14, 0xff00, 0x6500); - phy_write(phydev, 0x13, 0x80dc); - phy_modify(phydev, 0x14, 0xff00, 0xed00); - phy_write(phydev, 0x13, 0x80df); - phy_set_bits(phydev, 0x14, BIT(8)); - phy_write(phydev, 0x13, 0x80e1); - phy_clear_bits(phydev, 0x14, BIT(8)); - phy_write(phydev, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x80ea, 0xff00, 0xc400); + r8168g_phy_param(phydev, 0x80eb, 0x0700, 0x0300); + r8168g_phy_param(phydev, 0x80f8, 0xff00, 0x1c00); + r8168g_phy_param(phydev, 0x80f1, 0xff00, 0x3000); + r8168g_phy_param(phydev, 0x80fe, 0xff00, 0xa500); + r8168g_phy_param(phydev, 0x8102, 0xff00, 0x5000); + r8168g_phy_param(phydev, 0x8105, 0xff00, 0x3300); + r8168g_phy_param(phydev, 0x8100, 0xff00, 0x7000); + r8168g_phy_param(phydev, 0x8104, 0xff00, 0xf000); + r8168g_phy_param(phydev, 0x8106, 0xff00, 0x6500); + r8168g_phy_param(phydev, 0x80dc, 0xff00, 0xed00); + r8168g_phy_param(phydev, 0x80df, 0x0000, 0x0100); + r8168g_phy_param(phydev, 0x80e1, 0x0100, 0x0000); phy_modify_paged(phydev, 0xbf0, 0x13, 0x003f, 0x0038); - phy_write_paged(phydev, 0xa43, 0x13, 0x819f); - phy_write_paged(phydev, 0xa43, 0x14, 0xd0b6); + r8168g_phy_param(phydev, 0x819f, 0xffff, 0xd0b6); phy_write_paged(phydev, 0xbc3, 0x12, 0x5555); phy_modify_paged(phydev, 0xbf0, 0x15, 0x0e00, 0x0a00); @@ -3743,22 +3753,16 @@ phy_write(phydev, 0x14, 0x0002); for (i = 0; i < 25; i++) phy_write(phydev, 0x14, 0x0000); - - phy_write(phydev, 0x13, 0x8257); - phy_write(phydev, 0x14, 0x020F); - - phy_write(phydev, 0x13, 0x80EA); - phy_write(phydev, 0x14, 0x7843); phy_write(phydev, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x8257, 0xffff, 0x020F); + r8168g_phy_param(phydev, 0x80ea, 0xffff, 0x7843); + rtl_apply_firmware(tp); phy_modify_paged(phydev, 0xd06, 0x14, 0x0000, 0x2000); - phy_write(phydev, 0x1f, 0x0a43); - phy_write(phydev, 0x13, 0x81a2); - phy_set_bits(phydev, 0x14, BIT(8)); - phy_write(phydev, 0x1f, 0x0000); + r8168g_phy_param(phydev, 0x81a2, 0x0000, 0x0100); phy_modify_paged(phydev, 0xb54, 0x16, 0xff00, 0xdb00); phy_modify_paged(phydev, 0xa45, 0x12, 0x0001, 0x0000); @@ -3826,6 +3830,7 @@ [RTL_GIGA_MAC_VER_49] = rtl8168ep_1_hw_phy_config, [RTL_GIGA_MAC_VER_50] = rtl8168ep_2_hw_phy_config, [RTL_GIGA_MAC_VER_51] = rtl8168ep_2_hw_phy_config, + [RTL_GIGA_MAC_VER_52] = rtl8117_hw_phy_config, [RTL_GIGA_MAC_VER_60] = rtl8125_1_hw_phy_config, [RTL_GIGA_MAC_VER_61] = rtl8125_2_hw_phy_config, }; @@ -3919,7 +3924,7 @@ case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: case RTL_GIGA_MAC_VER_34: - case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_37 ... RTL_GIGA_MAC_VER_61: RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -3944,7 +3949,9 @@ } switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_39: case RTL_GIGA_MAC_VER_43: @@ -3955,6 +3962,7 @@ case RTL_GIGA_MAC_VER_48: case RTL_GIGA_MAC_VER_50: case RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_52: case RTL_GIGA_MAC_VER_60: case RTL_GIGA_MAC_VER_61: RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~0x80); @@ -3973,7 +3981,9 @@ static void rtl_pll_power_up(struct rtl8169_private *tp) { switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_25 ... RTL_GIGA_MAC_VER_26: + case RTL_GIGA_MAC_VER_29 ... RTL_GIGA_MAC_VER_30: + case RTL_GIGA_MAC_VER_32 ... RTL_GIGA_MAC_VER_33: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_39: case RTL_GIGA_MAC_VER_43: @@ -3986,6 +3996,7 @@ case RTL_GIGA_MAC_VER_48: case RTL_GIGA_MAC_VER_50: case RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_52: case RTL_GIGA_MAC_VER_60: case RTL_GIGA_MAC_VER_61: RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | 0xc0); @@ -4017,7 +4028,7 @@ case RTL_GIGA_MAC_VER_38: RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); break; case RTL_GIGA_MAC_VER_60 ... RTL_GIGA_MAC_VER_61: @@ -4039,14 +4050,12 @@ { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B); } static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); } static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp) @@ -4061,104 +4070,80 @@ static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) { - RTL_W8(tp, MaxTxPacketSize, 0x3f); + RTL_W8(tp, MaxTxPacketSize, 0x24); RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B); } static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) { - RTL_W8(tp, MaxTxPacketSize, 0x0c); + RTL_W8(tp, MaxTxPacketSize, 0x3f); RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); -} - -static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) -{ - rtl_tx_performance_tweak(tp, - PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN); -} - -static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp) -{ - rtl_tx_performance_tweak(tp, - PCI_EXP_DEVCTL_READRQ_4096B | PCI_EXP_DEVCTL_NOSNOOP_EN); } static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp) { - r8168b_0_hw_jumbo_enable(tp); - RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0)); } static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp) { - r8168b_0_hw_jumbo_disable(tp); - RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0)); } -static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) +static void rtl_jumbo_config(struct rtl8169_private *tp) { - rtl_unlock_config_regs(tp); - switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_11: - r8168b_0_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_12: - case RTL_GIGA_MAC_VER_17: - r8168b_1_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: - r8168c_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: - r8168dp_hw_jumbo_enable(tp); - break; - case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_34: - r8168e_hw_jumbo_enable(tp); - break; - default: - break; - } - rtl_lock_config_regs(tp); -} + bool jumbo = tp->dev->mtu > ETH_DATA_LEN; + int readrq = 4096; -static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) -{ rtl_unlock_config_regs(tp); switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_11: - r8168b_0_hw_jumbo_disable(tp); - break; case RTL_GIGA_MAC_VER_12: case RTL_GIGA_MAC_VER_17: - r8168b_1_hw_jumbo_disable(tp); + if (jumbo) { + readrq = 512; + r8168b_1_hw_jumbo_enable(tp); + } else { + r8168b_1_hw_jumbo_disable(tp); + } break; case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26: - r8168c_hw_jumbo_disable(tp); + if (jumbo) { + readrq = 512; + r8168c_hw_jumbo_enable(tp); + } else { + r8168c_hw_jumbo_disable(tp); + } break; case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28: - r8168dp_hw_jumbo_disable(tp); + if (jumbo) + r8168dp_hw_jumbo_enable(tp); + else + r8168dp_hw_jumbo_disable(tp); break; - case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_34: - r8168e_hw_jumbo_disable(tp); + case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33: + if (jumbo) { + pcie_set_readrq(tp->pci_dev, 512); + r8168e_hw_jumbo_enable(tp); + } else { + r8168e_hw_jumbo_disable(tp); + } break; default: break; } rtl_lock_config_regs(tp); -} -static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu) -{ - if (mtu > ETH_DATA_LEN) - rtl_hw_jumbo_enable(tp); - else - rtl_hw_jumbo_disable(tp); + if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii) + pcie_set_readrq(tp->pci_dev, readrq); + + /* Chip doesn't support pause in jumbo mode */ + linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, + tp->phydev->advertising, !jumbo); + linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, + tp->phydev->advertising, !jumbo); + phy_start_aneg(tp->phydev); } DECLARE_RTL_COND(rtl_chipcmd_cond) @@ -4229,7 +4214,7 @@ rtl_udelay_loop_wait_low(tp, &rtl_npq_cond, 20, 42*42); break; case RTL_GIGA_MAC_VER_34 ... RTL_GIGA_MAC_VER_38: - case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_52: RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); break; @@ -4301,6 +4286,8 @@ /* Unconditionally log net taps. */ netif_notice(tp, link, dev, "Promiscuous mode enabled\n"); rx_mode |= AcceptAllPhys; + } else if (!(dev->flags & IFF_MULTICAST)) { + rx_mode &= ~AcceptMulticast; } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || dev->flags & IFF_ALLMULTI || tp->mac_version == RTL_GIGA_MAC_VER_35) { @@ -4557,18 +4544,12 @@ rtl_set_def_aspm_entry_latency(tp); rtl_disable_clock_request(tp); - - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); } static void rtl_hw_start_8168dp(struct rtl8169_private *tp) { rtl_set_def_aspm_entry_latency(tp); - if (tp->dev->mtu <= ETH_DATA_LEN) - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_disable_clock_request(tp); } @@ -4583,8 +4564,6 @@ rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_ephy_init(tp, e_info_8168d_4); rtl_enable_clock_request(tp); @@ -4659,8 +4638,6 @@ { rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); @@ -4687,7 +4664,7 @@ { 0x08, 0x0001, 0x0002 }, { 0x09, 0x0000, 0x0080 }, { 0x19, 0x0000, 0x0224 }, - { 0x00, 0x0000, 0x0004 }, + { 0x00, 0x0000, 0x0008 }, { 0x0c, 0x3df0, 0x0200 }, }; @@ -4704,7 +4681,7 @@ { 0x06, 0x00c0, 0x0020 }, { 0x0f, 0xffff, 0x5200 }, { 0x19, 0x0000, 0x0224 }, - { 0x00, 0x0000, 0x0004 }, + { 0x00, 0x0000, 0x0008 }, { 0x0c, 0x3df0, 0x0200 }, }; @@ -4723,8 +4700,6 @@ rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_reset_packet_filter(tp); rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f); @@ -4739,6 +4714,7 @@ rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); rtl_pcie_state_l2l3_disable(tp); + rtl_hw_aspm_clkreq_enable(tp, true); } static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) @@ -4961,8 +4937,6 @@ rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_reset_packet_filter(tp); rtl_eri_set_bits(tp, 0xdc, ERIAR_MASK_1111, BIT(4)); @@ -5020,8 +4994,6 @@ rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_reset_packet_filter(tp); rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f80); @@ -5106,6 +5078,71 @@ rtl_hw_aspm_clkreq_enable(tp, true); } +static void rtl_hw_start_8117(struct rtl8169_private *tp) +{ + static const struct ephy_info e_info_8117[] = { + { 0x19, 0x0040, 0x1100 }, + { 0x59, 0x0040, 0x1100 }, + }; + int rg_saw_cnt; + + rtl8168ep_stop_cmac(tp); + + /* disable aspm and clock request before access ephy */ + rtl_hw_aspm_clkreq_enable(tp, false); + rtl_ephy_init(tp, e_info_8117); + + rtl_set_fifo_size(tp, 0x08, 0x10, 0x02, 0x06); + rtl8168g_set_pause_thresholds(tp, 0x2f, 0x5f); + + rtl_set_def_aspm_entry_latency(tp); + + rtl_reset_packet_filter(tp); + + rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f90); + + rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87); + + RTL_W32(tp, MISC, RTL_R32(tp, MISC) & ~RXDV_GATED_EN); + + rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); + rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); + + rtl8168_config_eee_mac(tp); + + RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); + RTL_W8(tp, MISC_1, RTL_R8(tp, MISC_1) & ~PFM_D3COLD_EN); + + RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~TX_10M_PS_EN); + + rtl_eri_clear_bits(tp, 0x1b0, ERIAR_MASK_0011, BIT(12)); + + rtl_pcie_state_l2l3_disable(tp); + + rg_saw_cnt = phy_read_paged(tp->phydev, 0x0c42, 0x13) & 0x3fff; + if (rg_saw_cnt > 0) { + u16 sw_cnt_1ms_ini; + + sw_cnt_1ms_ini = (16000000 / rg_saw_cnt) & 0x0fff; + r8168_mac_ocp_modify(tp, 0xd412, 0x0fff, sw_cnt_1ms_ini); + } + + r8168_mac_ocp_modify(tp, 0xe056, 0x00f0, 0x0070); + r8168_mac_ocp_write(tp, 0xea80, 0x0003); + r8168_mac_ocp_modify(tp, 0xe052, 0x0000, 0x0009); + r8168_mac_ocp_modify(tp, 0xd420, 0x0fff, 0x047f); + + r8168_mac_ocp_write(tp, 0xe63e, 0x0001); + r8168_mac_ocp_write(tp, 0xe63e, 0x0000); + r8168_mac_ocp_write(tp, 0xc094, 0x0000); + r8168_mac_ocp_write(tp, 0xc09e, 0x0000); + + /* firmware is for MAC only */ + rtl_apply_firmware(tp); + + rtl_hw_aspm_clkreq_enable(tp, true); +} + static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) { static const struct ephy_info e_info_8102e_1[] = { @@ -5124,8 +5161,6 @@ RTL_W8(tp, DBG_REG, FIX_NAK_1); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - RTL_W8(tp, Config1, LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); @@ -5141,8 +5176,6 @@ { rtl_set_def_aspm_entry_latency(tp); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable); RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); } @@ -5203,8 +5236,6 @@ rtl_ephy_init(tp, e_info_8402); - rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); - rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06); rtl_reset_packet_filter(tp); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); @@ -5226,7 +5257,6 @@ RTL_W8(tp, DLLPR, RTL_R8(tp, DLLPR) & ~PFM_EN); rtl_pcie_state_l2l3_disable(tp); - rtl_hw_aspm_clkreq_enable(tp, true); } DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond) @@ -5399,6 +5429,7 @@ [RTL_GIGA_MAC_VER_49] = rtl_hw_start_8168ep_1, [RTL_GIGA_MAC_VER_50] = rtl_hw_start_8168ep_2, [RTL_GIGA_MAC_VER_51] = rtl_hw_start_8168ep_3, + [RTL_GIGA_MAC_VER_52] = rtl_hw_start_8117, [RTL_GIGA_MAC_VER_60] = rtl_hw_start_8125_1, [RTL_GIGA_MAC_VER_61] = rtl_hw_start_8125_2, }; @@ -5420,10 +5451,18 @@ static void rtl_hw_start_8168(struct rtl8169_private *tp) { - if (tp->mac_version == RTL_GIGA_MAC_VER_13 || - tp->mac_version == RTL_GIGA_MAC_VER_16) + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_11: + case RTL_GIGA_MAC_VER_12: + case RTL_GIGA_MAC_VER_13: + case RTL_GIGA_MAC_VER_16: + case RTL_GIGA_MAC_VER_17: pcie_capability_set_word(tp->pci_dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_NOSNOOP_EN); + break; + default: + break; + } if (rtl_is_8168evl_up(tp)) RTL_W8(tp, MaxTxPacketSize, EarlySize); @@ -5480,7 +5519,7 @@ rtl_set_rx_tx_desc_registers(tp); rtl_lock_config_regs(tp); - rtl_jumbo_config(tp, tp->dev->mtu); + rtl_jumbo_config(tp); /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ RTL_R16(tp, CPlusCmd); @@ -5495,10 +5534,13 @@ { struct rtl8169_private *tp = netdev_priv(dev); - rtl_jumbo_config(tp, new_mtu); - dev->mtu = new_mtu; netdev_update_features(dev); + rtl_jumbo_config(tp); + + /* Reportedly at least Asus X453MA truncates packets otherwise */ + if (tp->mac_version == RTL_GIGA_MAC_VER_37) + rtl_init_rxcfg(tp); return 0; } @@ -5828,7 +5870,8 @@ opts[1] |= transport_offset << TCPHO_SHIFT; } else { if (unlikely(rtl_test_hw_pad_bug(tp, skb))) - return !eth_skb_pad(skb); + /* eth_skb_pad would free the skb on error */ + return !__skb_put_padto(skb, ETH_ZLEN, false); } return true; @@ -6054,7 +6097,7 @@ struct ring_info *tx_skb = tp->tx_skb + entry; u32 status; - status = le32_to_cpu(tp->TxDescArray[entry].opts1); + status = le32_to_cpu(READ_ONCE(tp->TxDescArray[entry].opts1)); if (status & DescOwn) break; @@ -6137,7 +6180,7 @@ struct RxDesc *desc = tp->RxDescArray + entry; u32 status; - status = le32_to_cpu(desc->opts1); + status = le32_to_cpu(READ_ONCE(desc->opts1)); if (status & DescOwn) break; @@ -6231,7 +6274,9 @@ !(status & tp->irq_mask)) return IRQ_NONE; - if (unlikely(status & SYSErr)) { + /* At least RTL8168fp may unexpectedly set the SYSErr bit */ + if (unlikely(status & SYSErr && + tp->mac_version <= RTL_GIGA_MAC_VER_06)) { rtl8169_pcierr_interrupt(tp->dev); goto out; } @@ -6242,12 +6287,11 @@ if (unlikely(status & RxFIFOOver && tp->mac_version == RTL_GIGA_MAC_VER_11)) { netif_stop_queue(tp->dev); - /* XXX - Hack alert. See rtl_task(). */ - set_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } rtl_irq_disable(tp); - napi_schedule_irqoff(&tp->napi); + napi_schedule(&tp->napi); out: rtl_ack_events(tp, status); @@ -6317,12 +6361,17 @@ static void r8169_phylink_handler(struct net_device *ndev) { struct rtl8169_private *tp = netdev_priv(ndev); + struct device *d = tp_to_dev(tp); if (netif_carrier_ok(ndev)) { rtl_link_chg_patch(tp); - pm_request_resume(&tp->pci_dev->dev); + pm_request_resume(d); + netif_wake_queue(tp->dev); } else { - pm_runtime_idle(&tp->pci_dev->dev); + /* In few cases rx is broken after link-down otherwise */ + if (rtl_is_8125(tp)) + rtl_reset_work(tp); + pm_runtime_idle(d); } if (net_ratelimit()) @@ -6346,8 +6395,6 @@ if (!tp->supports_gmii) phy_set_max_speed(phydev, SPEED_100); - phy_support_asym_pause(phydev); - phy_attached_info(phydev); return 0; @@ -6399,9 +6446,9 @@ cancel_work_sync(&tp->wk.work); - phy_disconnect(tp->phydev); + free_irq(pci_irq_vector(pdev, 0), tp); - pci_free_irq(pdev, 0, tp); + phy_disconnect(tp->phydev); dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, tp->RxPhyAddr); @@ -6452,8 +6499,8 @@ rtl_request_firmware(tp); - retval = pci_request_irq(pdev, 0, rtl8169_interrupt, NULL, tp, - dev->name); + retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt, + IRQF_SHARED, dev->name, tp); if (retval < 0) goto err_release_fw_2; @@ -6486,7 +6533,7 @@ return retval; err_free_irq: - pci_free_irq(pdev, 0, tp); + free_irq(pci_irq_vector(pdev, 0), tp); err_release_fw_2: rtl_release_firmware(tp); rtl8169_rx_clear(tp); @@ -6800,7 +6847,7 @@ RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~MSIEnable); rtl_lock_config_regs(tp); /* fall through */ - case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_07 ... RTL_GIGA_MAC_VER_17: flags = PCI_IRQ_LEGACY; break; default: @@ -6870,6 +6917,15 @@ struct mii_bus *new_bus; int ret; + /* On some boards with this chip version the BIOS is buggy and misses + * to reset the PHY page selector. This results in the PHY ID read + * accessing registers on a different page, returning a more or + * less random value. Fix this by resetting the page selector first. + */ + if (tp->mac_version == RTL_GIGA_MAC_VER_25 || + tp->mac_version == RTL_GIGA_MAC_VER_26) + r8169_mdio_write(tp, 0x1f, 0); + new_bus = devm_mdiobus_alloc(&pdev->dev); if (!new_bus) return -ENOMEM; @@ -6878,7 +6934,8 @@ new_bus->priv = tp; new_bus->parent = &pdev->dev; new_bus->irq[0] = PHY_IGNORE_INTERRUPT; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x-%x", + pci_domain_nr(pdev->bus), pci_dev_id(pdev)); new_bus->read = r8169_mdio_read_reg; new_bus->write = r8169_mdio_write_reg; @@ -6891,6 +6948,13 @@ if (!tp->phydev) { mdiobus_unregister(new_bus); return -ENODEV; + } else if (!tp->phydev->drv) { + /* Most chip versions fail with the genphy driver. + * Therefore ensure that the dedicated PHY driver is loaded. + */ + dev_err(&pdev->dev, "realtek.ko not loaded, maybe it needs to be added to initramfs?\n"); + mdiobus_unregister(new_bus); + return -EUNATCH; } /* PHY will be woken up in rtl_open() */ @@ -6953,7 +7017,7 @@ static void rtl_hw_initialize(struct rtl8169_private *tp) { switch (tp->mac_version) { - case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_51: + case RTL_GIGA_MAC_VER_49 ... RTL_GIGA_MAC_VER_52: rtl8168ep_stop_cmac(tp); /* fall through */ case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_48: @@ -7063,6 +7127,7 @@ tp->pci_dev = pdev; tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); tp->supports_gmii = ent->driver_data == RTL_CFG_NO_GBIT ? 0 : 1; + tp->eee_adv = -1; /* Get the *optional* external "ether_clk" used on some boards */ rc = rtl_get_ether_clk(tp); @@ -7072,8 +7137,7 @@ /* Disable ASPM completely as that cause random device stop working * problems as well as full system hangs for some PCIe devices users. */ - rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | - PCIE_LINK_STATE_L1); + rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_1); tp->aspm_manageable = !rc; /* enable device (incl. PCI PM wakeup and hotplug setup) */ @@ -7147,12 +7211,10 @@ netif_napi_add(dev, &tp->napi, rtl8169_poll, NAPI_POLL_WEIGHT); - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; - dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | - NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; + dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX; dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | NETIF_F_HIGHDMA; dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; @@ -7170,25 +7232,25 @@ dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_RX; if (rtl_chip_supports_csum_v2(tp)) { - dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; - dev->features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + dev->hw_features |= NETIF_F_IPV6_CSUM; + dev->features |= NETIF_F_IPV6_CSUM; + } + + /* There has been a number of reports that using SG/TSO results in + * tx timeouts. However for a lot of people SG/TSO works fine. + * Therefore disable both features by default, but allow users to + * enable them. Use at own risk! + */ + if (rtl_chip_supports_csum_v2(tp)) { + dev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6; dev->gso_max_size = RTL_GSO_MAX_SIZE_V2; dev->gso_max_segs = RTL_GSO_MAX_SEGS_V2; } else { + dev->hw_features |= NETIF_F_SG | NETIF_F_TSO; dev->gso_max_size = RTL_GSO_MAX_SIZE_V1; dev->gso_max_segs = RTL_GSO_MAX_SEGS_V1; } - /* RTL8168e-vl and one RTL8168c variant are known to have a - * HW issue with TSO. - */ - if (tp->mac_version == RTL_GIGA_MAC_VER_34 || - tp->mac_version == RTL_GIGA_MAC_VER_22) { - dev->vlan_features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); - dev->hw_features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); - dev->features &= ~(NETIF_F_ALL_TSO | NETIF_F_SG); - } - dev->hw_features |= NETIF_F_RXALL; dev->hw_features |= NETIF_F_RXFCS; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/renesas/ravb_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/renesas/ravb_main.c @@ -736,14 +736,14 @@ ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS); if (eis & EIS_QFS) { ris2 = ravb_read(ndev, RIS2); - ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED), + ravb_write(ndev, ~(RIS2_QFF0 | RIS2_QFF1 | RIS2_RFFF | RIS2_RESERVED), RIS2); /* Receive Descriptor Empty int */ if (ris2 & RIS2_QFF0) priv->stats[RAVB_BE].rx_over_errors++; - /* Receive Descriptor Empty int */ + /* Receive Descriptor Empty int */ if (ris2 & RIS2_QFF1) priv->stats[RAVB_NC].rx_over_errors++; @@ -911,31 +911,23 @@ int q = napi - priv->napi; int mask = BIT(q); int quota = budget; - u32 ris0, tis; + bool unmask; - for (;;) { - tis = ravb_read(ndev, TIS); - ris0 = ravb_read(ndev, RIS0); - if (!((ris0 & mask) || (tis & mask))) - break; - - /* Processing RX Descriptor Ring */ - if (ris0 & mask) { - /* Clear RX interrupt */ - ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0); - if (ravb_rx(ndev, "a, q)) - goto out; - } - /* Processing TX Descriptor Ring */ - if (tis & mask) { - spin_lock_irqsave(&priv->lock, flags); - /* Clear TX interrupt */ - ravb_write(ndev, ~(mask | TIS_RESERVED), TIS); - ravb_tx_free(ndev, q, true); - netif_wake_subqueue(ndev, q); - spin_unlock_irqrestore(&priv->lock, flags); - } - } + /* Processing RX Descriptor Ring */ + /* Clear RX interrupt */ + ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0); + unmask = !ravb_rx(ndev, "a, q); + + /* Processing RX Descriptor Ring */ + spin_lock_irqsave(&priv->lock, flags); + /* Clear TX interrupt */ + ravb_write(ndev, ~(mask | TIS_RESERVED), TIS); + ravb_tx_free(ndev, q, true); + netif_wake_subqueue(ndev, q); + spin_unlock_irqrestore(&priv->lock, flags); + + if (!unmask) + goto out; napi_complete(napi); @@ -1391,13 +1383,13 @@ if (priv->chip_id == RCAR_GEN2) ravb_ptp_init(ndev, priv->pdev); - netif_tx_start_all_queues(ndev); - /* PHY control start */ error = ravb_phy_start(ndev); if (error) goto out_ptp_stop; + netif_tx_start_all_queues(ndev); + return 0; out_ptp_stop: @@ -1444,6 +1436,13 @@ struct ravb_private *priv = container_of(work, struct ravb_private, work); struct net_device *ndev = priv->ndev; + int error; + + if (!rtnl_trylock()) { + usleep_range(1000, 2000); + schedule_work(&priv->work); + return; + } netif_tx_stop_all_queues(ndev); @@ -1452,20 +1451,44 @@ ravb_ptp_stop(ndev); /* Wait for DMA stopping */ - ravb_stop_dma(ndev); + if (ravb_stop_dma(ndev)) { + /* If ravb_stop_dma() fails, the hardware is still operating + * for TX and/or RX. So, this should not call the following + * functions because ravb_dmac_init() is possible to fail too. + * Also, this should not retry ravb_stop_dma() again and again + * here because it's possible to wait forever. So, this just + * re-enables the TX and RX and skip the following + * re-initialization procedure. + */ + ravb_rcv_snd_enable(ndev); + goto out; + } ravb_ring_free(ndev, RAVB_BE); ravb_ring_free(ndev, RAVB_NC); /* Device init */ - ravb_dmac_init(ndev); + error = ravb_dmac_init(ndev); + if (error) { + /* If ravb_dmac_init() fails, descriptors are freed. So, this + * should return here to avoid re-enabling the TX and RX in + * ravb_emac_init(). + */ + netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n", + __func__, error); + goto out_unlock; + } ravb_emac_init(ndev); +out: /* Initialise PTP Clock driver */ if (priv->chip_id == RCAR_GEN2) ravb_ptp_init(ndev, priv->pdev); netif_tx_start_all_queues(ndev); + +out_unlock: + rtnl_unlock(); } /* Packet transmit function for Ethernet AVB */ @@ -1477,7 +1500,7 @@ struct ravb_tstamp_skb *ts_skb; struct ravb_tx_desc *desc; unsigned long flags; - u32 dma_addr; + dma_addr_t dma_addr; void *buffer; u32 entry; u32 len; @@ -1692,6 +1715,8 @@ of_phy_deregister_fixed_link(np); } + cancel_work_sync(&priv->work); + if (priv->chip_id != RCAR_GEN2) { free_irq(priv->tx_irqs[RAVB_NC], ndev); free_irq(priv->rx_irqs[RAVB_NC], ndev); @@ -1719,12 +1744,16 @@ config.flags = 0; config.tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_V2_L2_EVENT) + switch (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE) { + case RAVB_RXTSTAMP_TYPE_V2_L2_EVENT: config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; - else if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_ALL) + break; + case RAVB_RXTSTAMP_TYPE_ALL: config.rx_filter = HWTSTAMP_FILTER_ALL; - else + break; + default: config.rx_filter = HWTSTAMP_FILTER_NONE; + } return copy_to_user(req->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; @@ -2013,7 +2042,9 @@ ndev->hw_features = NETIF_F_RXCSUM; pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); + error = pm_runtime_resume_and_get(&pdev->dev); + if (error < 0) + goto out_rpm_disable; /* The Ether-specific entries in the device structure. */ ndev->base_addr = res->start; @@ -2184,6 +2215,7 @@ free_netdev(ndev); pm_runtime_put(&pdev->dev); +out_rpm_disable: pm_runtime_disable(&pdev->dev); return error; } @@ -2197,15 +2229,15 @@ if (priv->chip_id != RCAR_GEN2) ravb_ptp_stop(ndev); - dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, - priv->desc_bat_dma); /* Set reset mode */ ravb_write(ndev, CCC_OPC_RESET, CCC); - pm_runtime_put_sync(&pdev->dev); unregister_netdev(ndev); netif_napi_del(&priv->napi[RAVB_NC]); netif_napi_del(&priv->napi[RAVB_BE]); ravb_mdio_release(priv); + dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, + priv->desc_bat_dma); + pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); free_netdev(ndev); platform_set_drvdata(pdev, NULL); @@ -2312,6 +2344,7 @@ ret = ravb_open(ndev); if (ret < 0) return ret; + ravb_set_rx_mode(ndev); netif_device_attach(ndev); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/renesas/sh_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/renesas/sh_eth.c @@ -610,6 +610,8 @@ EESR_TDE, .fdr_value = 0x0000070f, + .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5, + .no_psr = 1, .apr = 1, .mpr = 1, @@ -828,6 +830,8 @@ .fdr_value = 0x0000070f, + .trscer_err_mask = DESC_I_RINT8 | DESC_I_RINT5, + .apr = 1, .mpr = 1, .tpauser = 1, @@ -1131,6 +1135,9 @@ EESIPR_CEEFIP | EESIPR_CELFIP | EESIPR_RRFIP | EESIPR_RTLFIP | EESIPR_RTSFIP | EESIPR_PREIP | EESIPR_CERFIP, + + .trscer_err_mask = DESC_I_RINT8, + .tsu = 1, .dual_port = 1, }; @@ -2204,24 +2211,28 @@ if (cd->tsu) { add_tsu_reg(ARSTR); add_tsu_reg(TSU_CTRST); - add_tsu_reg(TSU_FWEN0); - add_tsu_reg(TSU_FWEN1); - add_tsu_reg(TSU_FCM); - add_tsu_reg(TSU_BSYSL0); - add_tsu_reg(TSU_BSYSL1); - add_tsu_reg(TSU_PRISL0); - add_tsu_reg(TSU_PRISL1); - add_tsu_reg(TSU_FWSL0); - add_tsu_reg(TSU_FWSL1); + if (cd->dual_port) { + add_tsu_reg(TSU_FWEN0); + add_tsu_reg(TSU_FWEN1); + add_tsu_reg(TSU_FCM); + add_tsu_reg(TSU_BSYSL0); + add_tsu_reg(TSU_BSYSL1); + add_tsu_reg(TSU_PRISL0); + add_tsu_reg(TSU_PRISL1); + add_tsu_reg(TSU_FWSL0); + add_tsu_reg(TSU_FWSL1); + } add_tsu_reg(TSU_FWSLC); - add_tsu_reg(TSU_QTAGM0); - add_tsu_reg(TSU_QTAGM1); - add_tsu_reg(TSU_FWSR); - add_tsu_reg(TSU_FWINMK); - add_tsu_reg(TSU_ADQT0); - add_tsu_reg(TSU_ADQT1); - add_tsu_reg(TSU_VTAG0); - add_tsu_reg(TSU_VTAG1); + if (cd->dual_port) { + add_tsu_reg(TSU_QTAGM0); + add_tsu_reg(TSU_QTAGM1); + add_tsu_reg(TSU_FWSR); + add_tsu_reg(TSU_FWINMK); + add_tsu_reg(TSU_ADQT0); + add_tsu_reg(TSU_ADQT1); + add_tsu_reg(TSU_VTAG0); + add_tsu_reg(TSU_VTAG1); + } add_tsu_reg(TSU_ADSBSY); add_tsu_reg(TSU_TEN); add_tsu_reg(TSU_POST1); @@ -2311,7 +2322,7 @@ { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *sh_eth_gstrings_stats, + memcpy(data, sh_eth_gstrings_stats, sizeof(sh_eth_gstrings_stats)); break; } @@ -2556,6 +2567,7 @@ else txdesc->status |= cpu_to_le32(TD_TACT); + wmb(); /* cur_tx must be incremented after TACT bit was set */ mdp->cur_tx++; if (!(sh_eth_read(ndev, EDTRR) & mdp->cd->edtrr_trns)) @@ -2636,10 +2648,10 @@ /* Free all the skbuffs in the Rx queue and the DMA buffer. */ sh_eth_ring_free(ndev); - pm_runtime_put_sync(&mdp->pdev->dev); - mdp->is_opened = 0; + pm_runtime_put(&mdp->pdev->dev); + return 0; } @@ -3484,10 +3496,12 @@ netif_device_detach(ndev); + rtnl_lock(); if (mdp->wol_enabled) ret = sh_eth_wol_setup(ndev); else ret = sh_eth_close(ndev); + rtnl_unlock(); return ret; } @@ -3501,10 +3515,12 @@ if (!netif_running(ndev)) return 0; + rtnl_lock(); if (mdp->wol_enabled) ret = sh_eth_wol_restore(ndev); else ret = sh_eth_open(ndev); + rtnl_unlock(); if (ret < 0) return ret; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/rocker/rocker_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/rocker/rocker_main.c @@ -647,10 +647,10 @@ err_dma_event_ring_bufs_alloc: rocker_dma_ring_destroy(rocker, &rocker->event_ring); err_dma_event_ring_create: + rocker_dma_cmd_ring_waits_free(rocker); +err_dma_cmd_ring_waits_alloc: rocker_dma_ring_bufs_free(rocker, &rocker->cmd_ring, PCI_DMA_BIDIRECTIONAL); -err_dma_cmd_ring_waits_alloc: - rocker_dma_cmd_ring_waits_free(rocker); err_dma_cmd_ring_bufs_alloc: rocker_dma_ring_destroy(rocker, &rocker->cmd_ring); return err; @@ -2542,7 +2542,7 @@ u64 link_status = rocker_read64(rocker, PORT_PHYS_LINK_STATUS); bool link_up; - link_up = link_status & (1 << rocker_port->pport); + link_up = link_status & (1ULL << rocker_port->pport); if (link_up) netif_carrier_on(rocker_port->dev); else --- linux-oracle-5.4.0.orig/drivers/net/ethernet/rocker/rocker_ofdpa.c +++ linux-oracle-5.4.0/drivers/net/ethernet/rocker/rocker_ofdpa.c @@ -1273,7 +1273,7 @@ bool removing; int err = 0; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -2795,7 +2795,8 @@ if (!ofdpa_port) continue; nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; - ofdpa_flow_tbl_del(ofdpa_port, OFDPA_OP_FLAG_REMOVE, + ofdpa_flow_tbl_del(ofdpa_port, + OFDPA_OP_FLAG_REMOVE | OFDPA_OP_FLAG_NOWAIT, flow_entry); } spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, flags); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -2277,18 +2277,18 @@ char *opt; if (!str || !*str) - return -EINVAL; + return 1; while ((opt = strsep(&str, ",")) != NULL) { - if (!strncmp(opt, "eee_timer:", 6)) { + if (!strncmp(opt, "eee_timer:", 10)) { if (kstrtoint(opt + 10, 0, &eee_timer)) goto err; } } - return 0; + return 1; err: pr_err("%s: ERROR broken module parameter conversion\n", __func__); - return -EINVAL; + return 1; } __setup("sxgbeeth=", sxgbe_cmdline_opt); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/seeq/ether3.c +++ linux-oracle-5.4.0/drivers/net/ethernet/seeq/ether3.c @@ -848,9 +848,11 @@ { struct net_device *dev = ecard_get_drvdata(ec); + ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); ecard_set_drvdata(ec, NULL); unregister_netdev(dev); + del_timer_sync(&priv(dev)->timer); free_netdev(dev); ecard_release_resources(ec); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/ef10.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/ef10.c @@ -2056,7 +2056,10 @@ efx_update_sw_stats(efx, stats); out: + /* releasing a DMA coherent buffer with BH disabled can panic */ + spin_unlock_bh(&efx->stats_lock); efx_nic_free_buffer(efx, &stats_buf); + spin_lock_bh(&efx->stats_lock); return rc; } @@ -6160,6 +6163,11 @@ n_parts++; } + if (!n_parts) { + kfree(parts); + return 0; + } + rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts)); fail: if (rc) @@ -6593,6 +6601,30 @@ return rc; } +static unsigned int efx_ef10_recycle_ring_size(const struct efx_nic *efx) +{ + unsigned int ret = EFX_RECYCLE_RING_SIZE_10G; + + /* There is no difference between PFs and VFs. The side is based on + * the maximum link speed of a given NIC. + */ + switch (efx->pci_dev->device & 0xfff) { + case 0x0903: /* Farmingdale can do up to 10G */ + break; + case 0x0923: /* Greenport can do up to 40G */ + case 0x0a03: /* Medford can do up to 40G */ + ret *= 4; + break; + default: /* Medford2 can do up to 100G */ + ret *= 10; + } + + if (IS_ENABLED(CONFIG_PPC64)) + ret *= 4; + + return ret; +} + #define EF10_OFFLOAD_FEATURES \ (NETIF_F_IP_CSUM | \ NETIF_F_HW_VLAN_CTAG_FILTER | \ @@ -6705,6 +6737,7 @@ .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL, .rx_hash_key_size = 40, + .rx_recycle_ring_size = efx_ef10_recycle_ring_size, }; const struct efx_nic_type efx_hunt_a0_nic_type = { @@ -6840,4 +6873,5 @@ .hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE | 1 << HWTSTAMP_FILTER_ALL, .rx_hash_key_size = 40, + .rx_recycle_ring_size = efx_ef10_recycle_ring_size, }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/ef10_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/ef10_sriov.c @@ -403,12 +403,18 @@ return rc; } +/* Disable SRIOV and remove VFs + * If some VFs are attached to a guest (using Xen, only) nothing is + * done if force=false, and vports are freed if force=true (for the non + * attachedc ones, only) but SRIOV is not disabled and VFs are not + * removed in either case. + */ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force) { struct pci_dev *dev = efx->pci_dev; - unsigned int vfs_assigned = 0; - - vfs_assigned = pci_vfs_assigned(dev); + struct efx_ef10_nic_data *nic_data = efx->nic_data; + unsigned int vfs_assigned = pci_vfs_assigned(dev); + int i, rc = 0; if (vfs_assigned && !force) { netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; " @@ -416,12 +422,17 @@ return -EBUSY; } - if (!vfs_assigned) + if (!vfs_assigned) { + for (i = 0; i < efx->vf_count; i++) + nic_data->vf[i].pci_dev = NULL; pci_disable_sriov(dev); + } else { + rc = -EBUSY; + } efx_ef10_sriov_free_vf_vswitching(efx); efx->vf_count = 0; - return 0; + return rc; } int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs) @@ -440,7 +451,6 @@ void efx_ef10_sriov_fini(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data; - unsigned int i; int rc; if (!nic_data->vf) { @@ -450,14 +460,7 @@ return; } - /* Remove any VFs in the host */ - for (i = 0; i < efx->vf_count; ++i) { - struct efx_nic *vf_efx = nic_data->vf[i].efx; - - if (vf_efx) - vf_efx->pci_dev->driver->remove(vf_efx->pci_dev); - } - + /* Disable SRIOV and remove any VFs in the host */ rc = efx_ef10_pci_sriov_disable(efx, true); if (rc) netif_dbg(efx, drv, efx->net_dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/efx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/efx.c @@ -519,6 +519,7 @@ if (tx_queue->channel) tx_queue->channel = channel; tx_queue->buffer = NULL; + tx_queue->cb_page = NULL; memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/efx.h +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/efx.h @@ -57,6 +57,12 @@ #define EFX_MAX_EVQ_SIZE 16384UL #define EFX_MIN_EVQ_SIZE 512UL +/* Number of RX buffers to recycle pages for. When creating the RX page recycle + * ring, this number is divided by the number of buffers per page to calculate + * the number of pages to store in the RX page recycle ring. + */ +#define EFX_RECYCLE_RING_SIZE_10G 256 + /* Maximum number of TCP segments we support for soft-TSO */ #define EFX_TSO_MAX_SEGS 100 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/ethtool.c @@ -128,20 +128,14 @@ { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; - u32 supported; mutex_lock(&efx->mac_lock); efx->phy_op->get_link_ksettings(efx, cmd); mutex_unlock(&efx->mac_lock); /* Both MACs support pause frames (bidirectional and respond-only) */ - ethtool_convert_link_mode_to_legacy_u32(&supported, - cmd->link_modes.supported); - - supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; - - ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, - supported); + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); + ethtool_link_ksettings_add_link_mode(cmd, supported, Asym_Pause); if (LOOPBACK_INTERNAL(efx)) { cmd->base.speed = link_state->speed; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/falcon/farch.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/falcon/farch.c @@ -870,17 +870,12 @@ { struct ef4_channel *channel = ef4_rx_queue_channel(rx_queue); struct ef4_nic *efx = rx_queue->efx; - bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; + bool __maybe_unused rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; bool rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc; - bool rx_ev_other_err, rx_ev_pause_frm; - bool rx_ev_hdr_type, rx_ev_mcast_pkt; - unsigned rx_ev_pkt_type; + bool rx_ev_pause_frm; - rx_ev_hdr_type = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_HDR_TYPE); - rx_ev_mcast_pkt = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_MCAST_PKT); rx_ev_tobe_disc = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_TOBE_DISC); - rx_ev_pkt_type = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_PKT_TYPE); rx_ev_buf_owner_id_err = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_BUF_OWNER_ID_ERR); rx_ev_ip_hdr_chksum_err = EF4_QWORD_FIELD(*event, @@ -893,10 +888,6 @@ 0 : EF4_QWORD_FIELD(*event, FSF_AA_RX_EV_DRIB_NIB)); rx_ev_pause_frm = EF4_QWORD_FIELD(*event, FSF_AZ_RX_EV_PAUSE_FRM_ERR); - /* Every error apart from tobe_disc and pause_frm */ - rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | - rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | - rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); /* Count errors that are not in MAC stats. Ignore expected * checksum errors during self-test. */ @@ -916,6 +907,13 @@ * to a FIFO overflow. */ #ifdef DEBUG + { + /* Every error apart from tobe_disc and pause_frm */ + + bool rx_ev_other_err = (rx_ev_drib_nib | rx_ev_tcp_udp_chksum_err | + rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | + rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); + if (rx_ev_other_err && net_ratelimit()) { netif_dbg(efx, rx_err, efx->net_dev, " RX queue %d unexpected RX event " @@ -932,6 +930,7 @@ rx_ev_tobe_disc ? " [TOBE_DISC]" : "", rx_ev_pause_frm ? " [PAUSE]" : ""); } + } #endif /* The frame must be discarded if any of these are true. */ @@ -1643,15 +1642,11 @@ */ void ef4_farch_dimension_resources(struct ef4_nic *efx, unsigned sram_lim_qw) { - unsigned vi_count, buftbl_min; + unsigned vi_count; /* Account for the buffer table entries backing the datapath channels * and the descriptor caches for those channels. */ - buftbl_min = ((efx->n_rx_channels * EF4_MAX_DMAQ_SIZE + - efx->n_tx_channels * EF4_TXQ_TYPES * EF4_MAX_DMAQ_SIZE + - efx->n_channels * EF4_MAX_EVQ_SIZE) - * sizeof(ef4_qword_t) / EF4_BUF_SIZE); vi_count = max(efx->n_channels, efx->n_tx_channels * EF4_TXQ_TYPES); efx->tx_dc_base = sram_lim_qw - vi_count * TX_DC_ENTRIES; @@ -2532,7 +2527,6 @@ enum ef4_farch_filter_table_id table_id; struct ef4_farch_filter_table *table; unsigned int filter_idx; - struct ef4_farch_filter_spec *spec; int rc; table_id = ef4_farch_filter_id_table_id(filter_id); @@ -2543,7 +2537,6 @@ filter_idx = ef4_farch_filter_id_index(filter_id); if (filter_idx >= table->size) return -ENOENT; - spec = &table->spec[filter_idx]; spin_lock_bh(&efx->filter_lock); rc = ef4_farch_filter_remove(efx, table, filter_idx, priority); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/falcon/rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/falcon/rx.c @@ -726,7 +726,10 @@ efx->rx_bufs_per_page); rx_queue->page_ring = kcalloc(page_ring_size, sizeof(*rx_queue->page_ring), GFP_KERNEL); - rx_queue->page_ptr_mask = page_ring_size - 1; + if (!rx_queue->page_ring) + rx_queue->page_ptr_mask = 0; + else + rx_queue->page_ptr_mask = page_ring_size - 1; } void ef4_init_rx_queue(struct ef4_rx_queue *rx_queue) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/mcdi.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/mcdi.c @@ -163,9 +163,9 @@ /* Serialise with efx_mcdi_ev_cpl() and efx_mcdi_ev_death() */ spin_lock_bh(&mcdi->iface_lock); ++mcdi->seqno; + seqno = mcdi->seqno & SEQ_MASK; spin_unlock_bh(&mcdi->iface_lock); - seqno = mcdi->seqno & SEQ_MASK; xflags = 0; if (mcdi->mode == MCDI_MODE_EVENTS) xflags |= MCDI_HEADER_XFLAGS_EVREQ; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/net_driver.h +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/net_driver.h @@ -1243,6 +1243,7 @@ * @udp_tnl_add_port: Add a UDP tunnel port * @udp_tnl_has_port: Check if a port has been added as UDP tunnel * @udp_tnl_del_port: Remove a UDP tunnel port + * @rx_recycle_ring_size: Size of the RX recycle ring * @revision: Hardware architecture revision * @txd_ptr_tbl_base: TX descriptor ring base address * @rxd_ptr_tbl_base: RX descriptor ring base address @@ -1413,6 +1414,7 @@ int (*udp_tnl_add_port)(struct efx_nic *efx, struct efx_udp_tunnel tnl); bool (*udp_tnl_has_port)(struct efx_nic *efx, __be16 port); int (*udp_tnl_del_port)(struct efx_nic *efx, struct efx_udp_tunnel tnl); + unsigned int (*rx_recycle_ring_size)(const struct efx_nic *efx); int revision; unsigned int txd_ptr_tbl_base; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/nic.h +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/nic.h @@ -607,6 +607,11 @@ bool efx_nic_event_present(struct efx_channel *channel); +static inline unsigned int efx_rx_recycle_ring_size(const struct efx_nic *efx) +{ + return efx->type->rx_recycle_ring_size(efx); +} + /* Some statistics are computed as A - B where A and B each increase * linearly with some hardware counter(s) and the counters are read * asynchronously. If the counters contributing to B are always read --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/ptp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/ptp.c @@ -560,13 +560,45 @@ u32 nic_major, u32 nic_minor, s32 correction) { + u32 sync_timestamp; ktime_t kt = { 0 }; + s16 delta; if (!(nic_major & 0x80000000)) { WARN_ON_ONCE(nic_major >> 16); - /* Use the top bits from the latest sync event. */ - nic_major &= 0xffff; - nic_major |= (last_sync_timestamp_major(efx) & 0xffff0000); + + /* Medford provides 48 bits of timestamp, so we must get the top + * 16 bits from the timesync event state. + * + * We only have the lower 16 bits of the time now, but we do + * have a full resolution timestamp at some point in past. As + * long as the difference between the (real) now and the sync + * is less than 2^15, then we can reconstruct the difference + * between those two numbers using only the lower 16 bits of + * each. + * + * Put another way + * + * a - b = ((a mod k) - b) mod k + * + * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know + * (a mod k) and b, so can calculate the delta, a - b. + * + */ + sync_timestamp = last_sync_timestamp_major(efx); + + /* Because delta is s16 this does an implicit mask down to + * 16 bits which is what we need, assuming + * MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that + * we can deal with the (unlikely) case of sync timestamps + * arriving from the future. + */ + delta = nic_major - sync_timestamp; + + /* Recover the fully specified time now, by applying the offset + * to the (fully specified) sync time. + */ + nic_major = sync_timestamp + delta; kt = ptp->nic_to_kernel_time(nic_major, nic_minor, correction); @@ -616,7 +648,7 @@ } else if (rc == -EINVAL) { fmt = MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS; } else if (rc == -EPERM) { - netif_info(efx, probe, efx->net_dev, "no PTP support\n"); + pci_info(efx->pci_dev, "no PTP support\n"); return rc; } else { efx_mcdi_display_error(efx, MC_CMD_PTP, sizeof(inbuf), @@ -792,7 +824,7 @@ * should only have been called during probe. */ if (rc == -ENOSYS || rc == -EPERM) - netif_info(efx, probe, efx->net_dev, "no PTP support\n"); + pci_info(efx->pci_dev, "no PTP support\n"); else if (rc) efx_mcdi_display_error(efx, MC_CMD_PTP, MC_CMD_PTP_IN_DISABLE_LEN, @@ -1061,7 +1093,29 @@ tx_queue = &ptp_data->channel->tx_queue[type]; if (tx_queue && tx_queue->timestamping) { + /* This code invokes normal driver TX code which is always + * protected from softirqs when called from generic TX code, + * which in turn disables preemption. Look at __dev_queue_xmit + * which uses rcu_read_lock_bh disabling preemption for RCU + * plus disabling softirqs. We do not need RCU reader + * protection here. + * + * Although it is theoretically safe for current PTP TX/RX code + * running without disabling softirqs, there are three good + * reasond for doing so: + * + * 1) The code invoked is mainly implemented for non-PTP + * packets and it is always executed with softirqs + * disabled. + * 2) This being a single PTP packet, better to not + * interrupt its processing by softirqs which can lead + * to high latencies. + * 3) netdev_xmit_more checks preemption is disabled and + * triggers a BUG_ON if not. + */ + local_bh_disable(); efx_enqueue_skb(tx_queue, skb); + local_bh_enable(); } else { WARN_ONCE(1, "PTP channel has no timestamped tx queue\n"); dev_kfree_skb_any(skb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/rx.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/rx.c @@ -27,13 +27,6 @@ /* Preferred number of descriptors to fill at once */ #define EFX_RX_PREFERRED_BATCH 8U -/* Number of RX buffers to recycle pages for. When creating the RX page recycle - * ring, this number is divided by the number of buffers per page to calculate - * the number of pages to store in the RX page recycle ring. - */ -#define EFX_RECYCLE_RING_SIZE_IOMMU 4096 -#define EFX_RECYCLE_RING_SIZE_NOIOMMU (2 * EFX_RX_PREFERRED_BATCH) - /* Size of buffer allocated for skb header area. */ #define EFX_SKB_HEADERS 128u @@ -710,16 +703,7 @@ { unsigned int bufs_in_recycle_ring, page_ring_size; - /* Set the RX recycle ring size */ -#ifdef CONFIG_PPC64 - bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU; -#else - if (iommu_present(&pci_bus_type)) - bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_IOMMU; - else - bufs_in_recycle_ring = EFX_RECYCLE_RING_SIZE_NOIOMMU; -#endif /* CONFIG_PPC64 */ - + bufs_in_recycle_ring = efx_rx_recycle_ring_size(efx); page_ring_size = roundup_pow_of_two(bufs_in_recycle_ring / efx->rx_bufs_per_page); rx_queue->page_ring = kcalloc(page_ring_size, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/siena.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/siena.c @@ -946,6 +946,12 @@ #endif /* CONFIG_SFC_MTD */ +static unsigned int efx_siena_recycle_ring_size(const struct efx_nic *efx) +{ + /* Maximum link speed is 10G */ + return EFX_RECYCLE_RING_SIZE_10G; +} + /************************************************************************** * * Revision-dependent attributes used by efx.c and nic.c @@ -1084,4 +1090,5 @@ 1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT | 1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT), .rx_hash_key_size = 16, + .rx_recycle_ring_size = efx_siena_recycle_ring_size, }; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sfc/siena_sriov.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sfc/siena_sriov.c @@ -1056,7 +1056,7 @@ return; if (efx_siena_sriov_cmd(efx, false, &efx->vi_scale, &count)) { - netif_info(efx, probe, efx->net_dev, "no SR-IOV VFs probed\n"); + pci_info(efx->pci_dev, "no SR-IOV VFs probed\n"); return; } if (count > 0 && count > max_vfs) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sis/sis900.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sis/sis900.c @@ -443,7 +443,7 @@ #endif /* setup various bits in PCI command register */ - ret = pci_enable_device(pci_dev); + ret = pcim_enable_device(pci_dev); if(ret) return ret; i = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); @@ -469,7 +469,7 @@ ioaddr = pci_iomap(pci_dev, 0, 0); if (!ioaddr) { ret = -ENOMEM; - goto err_out_cleardev; + goto err_out; } sis_priv = netdev_priv(net_dev); @@ -579,8 +579,6 @@ sis_priv->tx_ring_dma); err_out_unmap: pci_iounmap(pci_dev, ioaddr); -err_out_cleardev: - pci_release_regions(pci_dev); err_out: free_netdev(net_dev); return ret; @@ -787,10 +785,9 @@ static void sis900_set_capability(struct net_device *net_dev, struct mii_phy *phy) { u16 cap; - u16 status; - status = mdio_read(net_dev, phy->phy_addr, MII_STATUS); - status = mdio_read(net_dev, phy->phy_addr, MII_STATUS); + mdio_read(net_dev, phy->phy_addr, MII_STATUS); + mdio_read(net_dev, phy->phy_addr, MII_STATUS); cap = MII_NWAY_CSMA_CD | ((phy->status & MII_STAT_CAN_TX_FDX)? MII_NWAY_TX_FDX:0) | @@ -2490,7 +2487,6 @@ sis_priv->tx_ring_dma); pci_iounmap(pci_dev, sis_priv->ioaddr); free_netdev(net_dev); - pci_release_regions(pci_dev); } #ifdef CONFIG_PM --- linux-oracle-5.4.0.orig/drivers/net/ethernet/smsc/smc911x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/smsc/smc911x.c @@ -936,7 +936,7 @@ if (lp->ctl_rspeed != 100) my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF); - if (!lp->ctl_rfduplx) + if (!lp->ctl_rfduplx) my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); /* Update our Auto-Neg Advertisement Register */ @@ -2069,6 +2069,11 @@ ndev->dma = (unsigned char)-1; ndev->irq = platform_get_irq(pdev, 0); + if (ndev->irq < 0) { + ret = ndev->irq; + goto release_both; + } + lp = netdev_priv(ndev); lp->netdev = ndev; #ifdef SMC_DYNAMIC_BUS_CONFIG --- linux-oracle-5.4.0.orig/drivers/net/ethernet/smsc/smc91x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/smsc/smc91x.c @@ -2274,7 +2274,7 @@ ret = try_toggle_control_gpio(&pdev->dev, &lp->power_gpio, "power", 0, 0, 100); if (ret) - return ret; + goto out_free_netdev; /* * Optional reset GPIO configured? Minimum 100 ns reset needed @@ -2283,7 +2283,7 @@ ret = try_toggle_control_gpio(&pdev->dev, &lp->reset_gpio, "reset", 0, 0, 100); if (ret) - return ret; + goto out_free_netdev; /* * Need to wait for optional EEPROM to load, max 750 us according --- linux-oracle-5.4.0.orig/drivers/net/ethernet/smsc/smc91x.h +++ linux-oracle-5.4.0/drivers/net/ethernet/smsc/smc91x.h @@ -175,8 +175,8 @@ writew(*wp++, a); } -#define SMC_inw(a, r) _swapw(readw((a) + (r))) -#define SMC_outw(lp, v, a, r) writew(_swapw(v), (a) + (r)) +#define SMC_inw(a, r) ioread16be((a) + (r)) +#define SMC_outw(lp, v, a, r) iowrite16be(v, (a) + (r)) #define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l) #define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/smsc/smsc911x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/smsc/smsc911x.c @@ -2433,7 +2433,7 @@ if (irq == -EPROBE_DEFER) { retval = -EPROBE_DEFER; goto out_0; - } else if (irq <= 0) { + } else if (irq < 0) { pr_warn("Could not allocate irq resource\n"); retval = -ENODEV; goto out_0; @@ -2502,20 +2502,20 @@ retval = smsc911x_init(dev); if (retval < 0) - goto out_disable_resources; + goto out_init_fail; netif_carrier_off(dev); retval = smsc911x_mii_init(pdev, dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i initialising mii", retval); - goto out_disable_resources; + goto out_init_fail; } retval = register_netdev(dev); if (retval) { SMSC_WARN(pdata, probe, "Error %i registering device", retval); - goto out_disable_resources; + goto out_init_fail; } else { SMSC_TRACE(pdata, probe, "Network interface: \"%s\"", dev->name); @@ -2556,9 +2556,10 @@ return 0; -out_disable_resources: +out_init_fail: pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); +out_disable_resources: (void)smsc911x_disable_resources(pdev); out_enable_resources_fail: smsc911x_free_resources(pdev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/socionext/netsec.c +++ linux-oracle-5.4.0/drivers/net/ethernet/socionext/netsec.c @@ -847,8 +847,8 @@ enum dma_data_direction dma_dir = page_pool_get_dma_dir(rx_ring->page_pool); - dma_handle = page_pool_get_dma_addr(page) + - NETSEC_RXBUF_HEADROOM; + dma_handle = page_pool_get_dma_addr(page) + xdpf->headroom + + sizeof(*xdpf); dma_sync_single_for_device(priv->dev, dma_handle, xdpf->len, dma_dir); tx_desc.buf_type = TYPE_NETSEC_XDP_TX; @@ -928,7 +928,6 @@ struct netsec_rx_pkt_info rx_info; enum dma_data_direction dma_dir; struct bpf_prog *xdp_prog; - struct sk_buff *skb = NULL; u16 xdp_xmit = 0; u32 xdp_act = 0; int done = 0; @@ -942,7 +941,8 @@ struct netsec_de *de = dring->vaddr + (DESC_SZ * idx); struct netsec_desc *desc = &dring->desc[idx]; struct page *page = virt_to_page(desc->addr); - u32 xdp_result = XDP_PASS; + u32 xdp_result = NETSEC_XDP_PASS; + struct sk_buff *skb = NULL; u16 pkt_len, desc_len; dma_addr_t dma_handle; struct xdp_buff xdp; @@ -1693,14 +1693,17 @@ goto err1; /* set phy power down */ - data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR) | - BMCR_PDOWN; - netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); + data = netsec_phy_read(priv->mii_bus, priv->phy_addr, MII_BMCR); + netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, + data | BMCR_PDOWN); ret = netsec_reset_hardware(priv, true); if (ret) goto err2; + /* Restore phy power state */ + netsec_phy_write(priv->mii_bus, priv->phy_addr, MII_BMCR, data); + spin_lock_init(&priv->desc_ring[NETSEC_RING_TX].lock); spin_lock_init(&priv->desc_ring[NETSEC_RING_RX].lock); @@ -1933,11 +1936,13 @@ ret = PTR_ERR(priv->phydev); dev_err(priv->dev, "get_phy_device err(%d)\n", ret); priv->phydev = NULL; + mdiobus_unregister(bus); return -ENODEV; } ret = phy_device_register(priv->phydev); if (ret) { + phy_device_free(priv->phydev); mdiobus_unregister(bus); dev_err(priv->dev, "phy_device_register err(%d)\n", ret); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/socionext/sni_ave.c +++ linux-oracle-5.4.0/drivers/net/ethernet/socionext/sni_ave.c @@ -424,16 +424,22 @@ phy_ethtool_get_wol(ndev->phydev, wol); } -static int ave_ethtool_set_wol(struct net_device *ndev, - struct ethtool_wolinfo *wol) +static int __ave_ethtool_set_wol(struct net_device *ndev, + struct ethtool_wolinfo *wol) { - int ret; - if (!ndev->phydev || (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))) return -EOPNOTSUPP; - ret = phy_ethtool_set_wol(ndev->phydev, wol); + return phy_ethtool_set_wol(ndev->phydev, wol); +} + +static int ave_ethtool_set_wol(struct net_device *ndev, + struct ethtool_wolinfo *wol) +{ + int ret; + + ret = __ave_ethtool_set_wol(ndev, wol); if (!ret) device_set_wakeup_enable(&ndev->dev, !!wol->wolopts); @@ -1185,7 +1191,7 @@ ret = regmap_update_bits(priv->regmap, SG_ETPINMODE, priv->pinmode_mask, priv->pinmode_val); if (ret) - return ret; + goto out_reset_assert; ave_global_reset(ndev); @@ -1216,7 +1222,7 @@ /* set wol initial state disabled */ wol.wolopts = 0; - ave_ethtool_set_wol(ndev, &wol); + __ave_ethtool_set_wol(ndev, &wol); if (!phy_interface_is_rgmii(phydev)) phy_set_max_speed(phydev, SPEED_100); @@ -1768,7 +1774,7 @@ ave_ethtool_get_wol(ndev, &wol); wol.wolopts = priv->wolopts; - ave_ethtool_set_wol(ndev, &wol); + __ave_ethtool_set_wol(ndev, &wol); if (ndev->phydev) { ret = phy_resume(ndev->phydev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c @@ -57,10 +57,6 @@ #define TSE_PCS_USE_SGMII_ENA BIT(0) #define TSE_PCS_IF_USE_SGMII 0x03 -#define SGMII_ADAPTER_CTRL_REG 0x00 -#define SGMII_ADAPTER_DISABLE 0x0001 -#define SGMII_ADAPTER_ENABLE 0x0000 - #define AUTONEGO_LINK_TIMER 20 static int tse_pcs_reset(void __iomem *base, struct tse_pcs *pcs) @@ -202,12 +198,8 @@ unsigned int speed) { void __iomem *tse_pcs_base = pcs->tse_pcs_base; - void __iomem *sgmii_adapter_base = pcs->sgmii_adapter_base; u32 val; - writew(SGMII_ADAPTER_ENABLE, - sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); - pcs->autoneg = phy_dev->autoneg; if (phy_dev->autoneg == AUTONEG_ENABLE) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.h @@ -10,6 +10,10 @@ #include #include +#define SGMII_ADAPTER_CTRL_REG 0x00 +#define SGMII_ADAPTER_ENABLE 0x0000 +#define SGMII_ADAPTER_DISABLE 0x0001 + struct tse_pcs { struct device *dev; void __iomem *tse_pcs_base; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/common.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/common.h @@ -176,6 +176,7 @@ unsigned long mac_errors[32]; unsigned long mtl_errors[32]; unsigned long dma_errors[32]; + unsigned long dma_dpp_errors[32]; }; /* Number of fields in Safety Stats */ @@ -364,9 +365,8 @@ unsigned int arpoffsel; }; -/* GMAC TX FIFO is 8K, Rx FIFO is 16K */ -#define BUF_SIZE_16KiB 16384 -/* RX Buffer size must be < 8191 and multiple of 4/8/16 bytes */ +/* RX Buffer size must be multiple of 4/8/16 bytes */ +#define BUF_SIZE_16KiB 16368 #define BUF_SIZE_8KiB 8188 #define BUF_SIZE_4KiB 4096 #define BUF_SIZE_2KiB 2048 --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -357,6 +357,7 @@ data->fix_mac_speed = tegra_eqos_fix_speed; data->init = tegra_eqos_init; data->bsp_priv = eqos; + data->sph_disable = 1; err = tegra_eqos_init(pdev, eqos); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c @@ -71,6 +71,7 @@ static const struct of_device_id dwmac_generic_match[] = { { .compatible = "st,spear600-gmac"}, + { .compatible = "snps,dwmac-3.40a"}, { .compatible = "snps,dwmac-3.50a"}, { .compatible = "snps,dwmac-3.610"}, { .compatible = "snps,dwmac-3.70a"}, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c @@ -288,10 +288,7 @@ val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL; break; default: - dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n", - phy_modes(gmac->phy_mode)); - err = -EINVAL; - goto err_remove_config_dt; + goto err_unsupported_phy; } regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val); @@ -308,16 +305,25 @@ NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id); break; default: - dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n", - phy_modes(gmac->phy_mode)); - err = -EINVAL; - goto err_remove_config_dt; + goto err_unsupported_phy; } regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val); /* Enable PTP clock */ regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val); val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id); + switch (gmac->phy_mode) { + case PHY_INTERFACE_MODE_RGMII: + val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) | + NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id); + break; + case PHY_INTERFACE_MODE_SGMII: + val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) | + NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id); + break; + default: + goto err_unsupported_phy; + } regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val); if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) { @@ -337,6 +343,9 @@ plat_dat->has_gmac = true; plat_dat->bsp_priv = gmac; plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed; + plat_dat->multicast_filter_bins = 0; + plat_dat->tx_fifo_size = 8192; + plat_dat->rx_fifo_size = 8192; err = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (err) @@ -344,6 +353,11 @@ return 0; +err_unsupported_phy: + dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n", + phy_modes(gmac->phy_mode)); + err = -EINVAL; + err_remove_config_dt: stmmac_remove_config_dt(pdev, plat_dat); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c @@ -29,7 +29,6 @@ #define PRG_ETH0_EXT_RMII_MODE 4 /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */ -#define PRG_ETH0_CLK_M250_SEL_SHIFT 4 #define PRG_ETH0_CLK_M250_SEL_MASK GENMASK(4, 4) #define PRG_ETH0_TXDLY_SHIFT 5 @@ -112,6 +111,15 @@ struct device *dev = dwmac->dev; const char *parent_name, *mux_parent_names[MUX_CLK_NUM_PARENTS]; struct meson8b_dwmac_clk_configs *clk_configs; + static const struct clk_div_table div_table[] = { + { .div = 2, .val = 2, }, + { .div = 3, .val = 3, }, + { .div = 4, .val = 4, }, + { .div = 5, .val = 5, }, + { .div = 6, .val = 6, }, + { .div = 7, .val = 7, }, + { /* end of array */ } + }; clk_configs = devm_kzalloc(dev, sizeof(*clk_configs), GFP_KERNEL); if (!clk_configs) @@ -134,8 +142,9 @@ } clk_configs->m250_mux.reg = dwmac->regs + PRG_ETH0; - clk_configs->m250_mux.shift = PRG_ETH0_CLK_M250_SEL_SHIFT; - clk_configs->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK; + clk_configs->m250_mux.shift = __ffs(PRG_ETH0_CLK_M250_SEL_MASK); + clk_configs->m250_mux.mask = PRG_ETH0_CLK_M250_SEL_MASK >> + clk_configs->m250_mux.shift; clk = meson8b_dwmac_register_clk(dwmac, "m250_sel", mux_parent_names, MUX_CLK_NUM_PARENTS, &clk_mux_ops, &clk_configs->m250_mux.hw); @@ -146,9 +155,9 @@ clk_configs->m250_div.reg = dwmac->regs + PRG_ETH0; clk_configs->m250_div.shift = PRG_ETH0_CLK_M250_DIV_SHIFT; clk_configs->m250_div.width = PRG_ETH0_CLK_M250_DIV_WIDTH; - clk_configs->m250_div.flags = CLK_DIVIDER_ONE_BASED | - CLK_DIVIDER_ALLOW_ZERO | - CLK_DIVIDER_ROUND_CLOSEST; + clk_configs->m250_div.table = div_table; + clk_configs->m250_div.flags = CLK_DIVIDER_ALLOW_ZERO | + CLK_DIVIDER_ROUND_CLOSEST; clk = meson8b_dwmac_register_clk(dwmac, "m250_div", &parent_name, 1, &clk_divider_ops, &clk_configs->m250_div.hw); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -75,6 +75,11 @@ unsigned int value; }; +struct ethqos_emac_driver_data { + const struct ethqos_emac_por *por; + unsigned int num_por; +}; + struct qcom_ethqos { struct platform_device *pdev; void __iomem *rgmii_base; @@ -171,6 +176,11 @@ { .offset = RGMII_IO_MACRO_CONFIG2, .value = 0x00002060 }, }; +static const struct ethqos_emac_driver_data emac_v2_3_0_data = { + .por = emac_v2_3_0_por, + .num_por = ARRAY_SIZE(emac_v2_3_0_por), +}; + static int ethqos_dll_configure(struct qcom_ethqos *ethqos) { unsigned int val; @@ -413,6 +423,7 @@ dll_lock = rgmii_readl(ethqos, SDC4_STATUS); if (dll_lock & SDC4_STATUS_DLL_LOCK) break; + retry--; } while (retry > 0); if (!retry) dev_err(ðqos->pdev->dev, @@ -441,6 +452,7 @@ struct device_node *np = pdev->dev.of_node; struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; + const struct ethqos_emac_driver_data *data; struct qcom_ethqos *ethqos; struct resource *res; int ret; @@ -470,7 +482,9 @@ goto err_mem; } - ethqos->por = of_device_get_match_data(&pdev->dev); + data = of_device_get_match_data(&pdev->dev); + ethqos->por = data->por; + ethqos->num_por = data->num_por; ethqos->rgmii_clk = devm_clk_get(&pdev->dev, "rgmii"); if (IS_ERR(ethqos->rgmii_clk)) { @@ -491,6 +505,8 @@ plat_dat->has_gmac4 = 1; plat_dat->pmt = 1; plat_dat->tso_en = of_property_read_bool(np, "snps,tso"); + if (of_device_is_compatible(np, "qcom,qcs404-ethqos")) + plat_dat->rx_clk_runs_in_lpi = 1; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) @@ -525,7 +541,7 @@ } static const struct of_device_id qcom_ethqos_match[] = { - { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_por}, + { .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data}, { } }; MODULE_DEVICE_TABLE(of, qcom_ethqos_match); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -1411,7 +1411,7 @@ ret = rk_gmac_clk_init(plat_dat); if (ret) - return ret; + goto err_remove_config_dt; ret = rk_gmac_powerup(plat_dat->bsp_priv); if (ret) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -18,9 +18,6 @@ #include "altr_tse_pcs.h" -#define SGMII_ADAPTER_CTRL_REG 0x00 -#define SGMII_ADAPTER_DISABLE 0x0001 - #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1 #define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2 @@ -62,14 +59,13 @@ { struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv; void __iomem *splitter_base = dwmac->splitter_base; - void __iomem *tse_pcs_base = dwmac->pcs.tse_pcs_base; void __iomem *sgmii_adapter_base = dwmac->pcs.sgmii_adapter_base; struct device *dev = dwmac->dev; struct net_device *ndev = dev_get_drvdata(dev); struct phy_device *phy_dev = ndev->phydev; u32 val; - if ((tse_pcs_base) && (sgmii_adapter_base)) + if (sgmii_adapter_base) writew(SGMII_ADAPTER_DISABLE, sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); @@ -93,8 +89,11 @@ writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); } - if (tse_pcs_base && sgmii_adapter_base) + if (phy_dev && sgmii_adapter_base) { + writew(SGMII_ADAPTER_ENABLE, + sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); + } } static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) @@ -241,6 +240,8 @@ switch (phymode) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: *val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII; break; case PHY_INTERFACE_MODE_MII: @@ -289,16 +290,19 @@ phymode == PHY_INTERFACE_MODE_MII || phymode == PHY_INTERFACE_MODE_GMII || phymode == PHY_INTERFACE_MODE_SGMII) { - ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2); regmap_read(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, &module); module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift / 2)); regmap_write(sys_mgr_base_addr, SYSMGR_FPGAGRP_MODULE_REG, module); - } else { - ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2)); } + if (dwmac->f2h_ptp_ref_clk) + ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << (reg_shift / 2); + else + ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK << + (reg_shift / 2)); + regmap_write(sys_mgr_base_addr, reg_offset, ctrl); /* Deassert reset for the phy configuration to be sampled by @@ -422,6 +426,8 @@ plat_dat->bsp_priv = dwmac; plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; + plat_dat->riwt_off = 1; + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) goto err_remove_config_dt; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -111,6 +111,7 @@ int (*parse_data)(struct stm32_dwmac *dwmac, struct device *dev); u32 syscfg_eth_mask; + bool clk_rx_enable_in_suspend; }; static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) @@ -128,7 +129,8 @@ if (ret) return ret; - if (!dwmac->dev->power.is_suspended) { + if (!dwmac->ops->clk_rx_enable_in_suspend || + !dwmac->dev->power.is_suspended) { ret = clk_prepare_enable(dwmac->clk_rx); if (ret) { clk_disable_unprepare(dwmac->clk_tx); @@ -508,7 +510,8 @@ .suspend = stm32mp1_suspend, .resume = stm32mp1_resume, .parse_data = stm32mp1_parse_data, - .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK + .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, + .clk_rx_enable_in_suspend = true }; static const struct of_device_id stm32_dwmac_match[] = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c @@ -64,6 +64,7 @@ * @variant: reference to the current board variant * @regmap: regmap for using the syscon * @internal_phy_powered: Does the internal PHY is enabled + * @use_internal_phy: Is the internal PHY selected for use * @mux_handle: Internal pointer used by mdio-mux lib */ struct sunxi_priv_data { @@ -74,6 +75,7 @@ const struct emac_variant *variant; struct regmap_field *regmap_field; bool internal_phy_powered; + bool use_internal_phy; void *mux_handle; }; @@ -523,8 +525,11 @@ .dma_interrupt = sun8i_dwmac_dma_interrupt, }; +static int sun8i_dwmac_power_internal_phy(struct stmmac_priv *priv); + static int sun8i_dwmac_init(struct platform_device *pdev, void *priv) { + struct net_device *ndev = platform_get_drvdata(pdev); struct sunxi_priv_data *gmac = priv; int ret; @@ -538,13 +543,25 @@ ret = clk_prepare_enable(gmac->tx_clk); if (ret) { - if (gmac->regulator) - regulator_disable(gmac->regulator); dev_err(&pdev->dev, "Could not enable AHB clock\n"); - return ret; + goto err_disable_regulator; + } + + if (gmac->use_internal_phy) { + ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev)); + if (ret) + goto err_disable_clk; } return 0; + +err_disable_clk: + clk_disable_unprepare(gmac->tx_clk); +err_disable_regulator: + if (gmac->regulator) + regulator_disable(gmac->regulator); + + return ret; } static void sun8i_dwmac_core_init(struct mac_device_info *hw, @@ -701,7 +718,7 @@ if (err) { dev_err(priv->device, "EMAC reset timeout\n"); - return -EFAULT; + return err; } return 0; } @@ -815,7 +832,6 @@ struct sunxi_priv_data *gmac = priv->plat->bsp_priv; u32 reg, val; int ret = 0; - bool need_power_ephy = false; if (current_child ^ desired_child) { regmap_field_read(gmac->regmap_field, ®); @@ -823,13 +839,12 @@ case DWMAC_SUN8I_MDIO_MUX_INTERNAL_ID: dev_info(priv->device, "Switch mux to internal PHY"); val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SELECT; - - need_power_ephy = true; + gmac->use_internal_phy = true; break; case DWMAC_SUN8I_MDIO_MUX_EXTERNAL_ID: dev_info(priv->device, "Switch mux to external PHY"); val = (reg & ~H3_EPHY_MUX_MASK) | H3_EPHY_SHUTDOWN; - need_power_ephy = false; + gmac->use_internal_phy = false; break; default: dev_err(priv->device, "Invalid child ID %x\n", @@ -837,7 +852,7 @@ return -EINVAL; } regmap_field_write(gmac->regmap_field, val); - if (need_power_ephy) { + if (gmac->use_internal_phy) { ret = sun8i_dwmac_power_internal_phy(priv); if (ret) return ret; @@ -864,6 +879,7 @@ ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, &gmac->mux_handle, priv, priv->mii); + of_node_put(mdio_mux); return ret; } @@ -957,6 +973,9 @@ /* default */ break; case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; break; case PHY_INTERFACE_MODE_RMII: @@ -985,17 +1004,12 @@ struct sunxi_priv_data *gmac = priv; if (gmac->variant->soc_has_internal_phy) { - /* sun8i_dwmac_exit could be called with mdiomux uninit */ - if (gmac->mux_handle) - mdio_mux_uninit(gmac->mux_handle); if (gmac->internal_phy_powered) sun8i_dwmac_unpower_internal_phy(gmac); } sun8i_dwmac_unset_syscon(gmac); - reset_control_put(gmac->rst_ephy); - clk_disable_unprepare(gmac->tx_clk); if (gmac->regulator) @@ -1193,6 +1207,8 @@ plat_dat->init = sun8i_dwmac_init; plat_dat->exit = sun8i_dwmac_exit; plat_dat->setup = sun8i_dwmac_setup; + plat_dat->tx_fifo_size = 4096; + plat_dat->rx_fifo_size = 16384; ret = sun8i_dwmac_init(pdev, plat_dat->bsp_priv); if (ret) @@ -1224,12 +1240,32 @@ return ret; dwmac_mux: + reset_control_put(gmac->rst_ephy); + clk_put(gmac->ephy_clk); sun8i_dwmac_unset_syscon(gmac); dwmac_exit: stmmac_pltfr_remove(pdev); return ret; } +static int sun8i_dwmac_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(ndev); + struct sunxi_priv_data *gmac = priv->plat->bsp_priv; + + if (gmac->variant->soc_has_internal_phy) { + mdio_mux_uninit(gmac->mux_handle); + sun8i_dwmac_unpower_internal_phy(gmac); + reset_control_put(gmac->rst_ephy); + clk_put(gmac->ephy_clk); + } + + stmmac_pltfr_remove(pdev); + + return 0; +} + static const struct of_device_id sun8i_dwmac_match[] = { { .compatible = "allwinner,sun8i-h3-emac", .data = &emac_variant_h3 }, @@ -1249,7 +1285,7 @@ static struct platform_driver sun8i_dwmac_driver = { .probe = sun8i_dwmac_probe, - .remove = stmmac_pltfr_remove, + .remove = sun8i_dwmac_remove, .driver = { .name = "dwmac-sun8i", .pm = &stmmac_pltfr_pm_ops, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac-sunxi.c @@ -30,7 +30,7 @@ static int sun7i_gmac_init(struct platform_device *pdev, void *priv) { struct sunxi_priv_data *gmac = priv; - int ret; + int ret = 0; if (gmac->regulator) { ret = regulator_enable(gmac->regulator); @@ -44,18 +44,18 @@ * rate, which then uses the auto-reparenting feature of the * clock driver, and enabling/disabling the clock. */ - if (gmac->interface == PHY_INTERFACE_MODE_RGMII) { + if (phy_interface_mode_is_rgmii(gmac->interface)) { clk_set_rate(gmac->tx_clk, SUN7I_GMAC_GMII_RGMII_RATE); clk_prepare_enable(gmac->tx_clk); gmac->clk_enabled = 1; } else { clk_set_rate(gmac->tx_clk, SUN7I_GMAC_MII_RATE); ret = clk_prepare(gmac->tx_clk); - if (ret) - return ret; + if (ret && gmac->regulator) + regulator_disable(gmac->regulator); } - return 0; + return ret; } static void sun7i_gmac_exit(struct platform_device *pdev, void *priv) @@ -146,6 +146,8 @@ plat_dat->init = sun7i_gmac_init; plat_dat->exit = sun7i_gmac_exit; plat_dat->fix_mac_speed = sun7i_fix_speed; + plat_dat->tx_fifo_size = 4096; + plat_dat->rx_fifo_size = 16384; ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv); if (ret) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -76,10 +76,10 @@ #define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ - (reg * 8)) -#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ - (reg * 8)) +#define GMAC_ADDR_HIGH(reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \ + 0x00000040 + (reg * 8)) +#define GMAC_ADDR_LOW(reg) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 : \ + 0x00000044 + (reg * 8)) #define GMAC_MAX_PERFECT_ADDRESSES 1 #define GMAC_PCS_BASE 0x000000c0 /* PCS register base */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -24,6 +24,7 @@ static void dwmac1000_core_init(struct mac_device_info *hw, struct net_device *dev) { + struct stmmac_priv *priv = netdev_priv(dev); void __iomem *ioaddr = hw->pcsr; u32 value = readl(ioaddr + GMAC_CONTROL); int mtu = dev->mtu; @@ -35,7 +36,7 @@ * Broadcom tags can look like invalid LLC/SNAP packets and cause the * hardware to truncate packets on reception. */ - if (netdev_uses_dsa(dev)) + if (netdev_uses_dsa(dev) || !priv->plat->enh_desc) value &= ~GMAC_CONTROL_ACS; if (mtu > 1500) @@ -165,6 +166,9 @@ value = GMAC_FRAME_FILTER_PR | GMAC_FRAME_FILTER_PCF; } else if (dev->flags & IFF_ALLMULTI) { value = GMAC_FRAME_FILTER_PM; /* pass all multi */ + } else if (!netdev_mc_empty(dev) && (mcbitslog2 == 0)) { + /* Fall back to all multicast if we've no filter */ + value = GMAC_FRAME_FILTER_PM; } else if (!netdev_mc_empty(dev)) { struct netdev_hw_addr *ha; @@ -208,7 +212,7 @@ reg++; } - while (reg <= perfect_addr_number) { + while (reg < perfect_addr_number) { writel(0, ioaddr + GMAC_ADDR_HIGH(reg)); writel(0, ioaddr + GMAC_ADDR_LOW(reg)); reg++; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -218,11 +218,18 @@ readl(ioaddr + DMA_BUS_MODE + i * 4); } -static void dwmac1000_get_hw_feature(void __iomem *ioaddr, - struct dma_features *dma_cap) +static int dwmac1000_get_hw_feature(void __iomem *ioaddr, + struct dma_features *dma_cap) { u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE); + if (!hw_cap) { + /* 0x00000000 is the value read on old hardware that does not + * implement this register + */ + return -EOPNOTSUPP; + } + dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL); dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1; dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2; @@ -252,6 +259,8 @@ dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22; /* Alternate (enhanced) DESC mode */ dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; + + return 0; } static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -75,19 +75,41 @@ u32 prio, u32 queue) { void __iomem *ioaddr = hw->pcsr; - u32 base_register; - u32 value; + u32 clear_mask = 0; + u32 ctrl2, ctrl3; + int i; + + ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2); + ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3); + + /* The software must ensure that the same priority + * is not mapped to multiple Rx queues + */ + for (i = 0; i < 4; i++) + clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) & + GMAC_RXQCTRL_PSRQX_MASK(i)); + + ctrl2 &= ~clear_mask; + ctrl3 &= ~clear_mask; + + /* First assign new priorities to a queue, then + * clear them from others queues + */ + if (queue < 4) { + ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) & + GMAC_RXQCTRL_PSRQX_MASK(queue); - base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3; - if (queue >= 4) + writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2); + writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3); + } else { queue -= 4; - value = readl(ioaddr + base_register); - - value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue); - value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) & + ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) & GMAC_RXQCTRL_PSRQX_MASK(queue); - writel(value, ioaddr + base_register); + + writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3); + writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2); + } } static void dwmac4_tx_queue_priority(struct mac_device_info *hw, @@ -215,6 +237,9 @@ if (queue == 0 || queue == 4) { value &= ~MTL_RXQ_DMA_Q04MDMACH_MASK; value |= MTL_RXQ_DMA_Q04MDMACH(chan); + } else if (queue > 4) { + value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue - 4); + value |= MTL_RXQ_DMA_QXMDMACH(chan, queue - 4); } else { value &= ~MTL_RXQ_DMA_QXMDMACH_MASK(queue); value |= MTL_RXQ_DMA_QXMDMACH(chan, queue); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -116,6 +116,23 @@ ioaddr + DMA_CHAN_INTR_ENA(chan)); } +static void dwmac410_dma_init_channel(void __iomem *ioaddr, + struct stmmac_dma_cfg *dma_cfg, u32 chan) +{ + u32 value; + + /* common channel control register config */ + value = readl(ioaddr + DMA_CHAN_CONTROL(chan)); + if (dma_cfg->pblx8) + value = value | DMA_BUS_MODE_PBL; + + writel(value, ioaddr + DMA_CHAN_CONTROL(chan)); + + /* Mask interrupts by writing to CSR7 */ + writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10, + ioaddr + DMA_CHAN_INTR_ENA(chan)); +} + static void dwmac4_dma_init(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, int atds) { @@ -194,7 +211,7 @@ u32 channel, int fifosz, u8 qmode) { unsigned int rqs = fifosz / 256 - 1; - u32 mtl_rx_op, mtl_rx_int; + u32 mtl_rx_op; mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(channel)); @@ -265,11 +282,6 @@ } writel(mtl_rx_op, ioaddr + MTL_CHAN_RX_OP_MODE(channel)); - - /* Enable MTL RX overflow */ - mtl_rx_int = readl(ioaddr + MTL_CHAN_INT_CTRL(channel)); - writel(mtl_rx_int | MTL_RX_OVERFLOW_INT_EN, - ioaddr + MTL_CHAN_INT_CTRL(channel)); } static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode, @@ -324,8 +336,8 @@ writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(channel)); } -static void dwmac4_get_hw_feature(void __iomem *ioaddr, - struct dma_features *dma_cap) +static int dwmac4_get_hw_feature(void __iomem *ioaddr, + struct dma_features *dma_cap) { u32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0); @@ -388,6 +400,8 @@ dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11; dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10; dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5; + + return 0; } /* Enable/disable TSO feature and set MSS */ @@ -462,7 +476,7 @@ const struct stmmac_dma_ops dwmac410_dma_ops = { .reset = dwmac4_dma_reset, .init = dwmac4_dma_init, - .init_chan = dwmac4_dma_init_channel, + .init_chan = dwmac410_dma_init_channel, .init_rx_chan = dwmac4_dma_init_rx_chan, .init_tx_chan = dwmac4_dma_init_tx_chan, .axi = dwmac4_dma_axi, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c @@ -60,10 +60,6 @@ value &= ~DMA_CONTROL_ST; writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan)); - - value = readl(ioaddr + GMAC_CONFIG); - value &= ~GMAC_CONFIG_TE; - writel(value, ioaddr + GMAC_CONFIG); } void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -520,9 +520,9 @@ return 0; } - val |= PPSCMDx(index, 0x2); val |= TRGTMODSELx(index, 0x2); val |= PPSEN0; + writel(val, ioaddr + MAC_PPS_CONTROL); writel(cfg->start.tv_sec, ioaddr + MAC_PPSx_TARGET_TIME_SEC(index)); @@ -547,6 +547,7 @@ writel(period - 1, ioaddr + MAC_PPSx_WIDTH(index)); /* Finally, activate it */ + val |= PPSCMDx(index, 0x2); writel(val, ioaddr + MAC_PPS_CONTROL); return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h @@ -128,6 +128,7 @@ #define NUM_DWMAC100_DMA_REGS 9 #define NUM_DWMAC1000_DMA_REGS 23 +#define NUM_DWMAC4_DMA_REGS 27 void dwmac_enable_dma_transmission(void __iomem *ioaddr); void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h @@ -212,7 +212,7 @@ ((val) << XGMAC_PPS_MINIDX(x)) #define XGMAC_PPSCMD_START 0x2 #define XGMAC_PPSCMD_STOP 0x5 -#define XGMAC_PPSEN0 BIT(4) +#define XGMAC_PPSENx(x) BIT(4 + (x) * 8) #define XGMAC_PPSx_TARGET_TIME_SEC(x) (0x00000d80 + (x) * 0x10) #define XGMAC_PPSx_TARGET_TIME_NSEC(x) (0x00000d84 + (x) * 0x10) #define XGMAC_TRGTBUSY0 BIT(31) @@ -256,6 +256,8 @@ #define XGMAC_RXCEIE BIT(4) #define XGMAC_TXCEIE BIT(0) #define XGMAC_MTL_ECC_INT_STATUS 0x000010cc +#define XGMAC_MTL_DPP_CONTROL 0x000010e0 +#define XGMAC_DPP_DISABLE BIT(0) #define XGMAC_MTL_TXQ_OPMODE(x) (0x00001100 + (0x80 * (x))) #define XGMAC_TQS GENMASK(25, 16) #define XGMAC_TQS_SHIFT 16 @@ -331,6 +333,7 @@ #define XGMAC_DCEIE BIT(1) #define XGMAC_TCEIE BIT(0) #define XGMAC_DMA_ECC_INT_STATUS 0x0000306c +#define XGMAC_DMA_DPP_INT_STATUS 0x00003074 #define XGMAC_DMA_CH_CONTROL(x) (0x00003100 + (0x80 * (x))) #define XGMAC_SPH BIT(24) #define XGMAC_PBLx8 BIT(16) @@ -343,6 +346,8 @@ #define XGMAC_DMA_CH_RX_CONTROL(x) (0x00003108 + (0x80 * (x))) #define XGMAC_RxPBL GENMASK(21, 16) #define XGMAC_RxPBL_SHIFT 16 +#define XGMAC_RBSZ GENMASK(14, 1) +#define XGMAC_RBSZ_SHIFT 1 #define XGMAC_RXST BIT(0) #define XGMAC_DMA_CH_TxDESC_HADDR(x) (0x00003110 + (0x80 * (x))) #define XGMAC_DMA_CH_TxDESC_LADDR(x) (0x00003114 + (0x80 * (x))) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -96,17 +96,41 @@ u32 queue) { void __iomem *ioaddr = hw->pcsr; - u32 value, reg; + u32 clear_mask = 0; + u32 ctrl2, ctrl3; + int i; - reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3; - if (queue >= 4) + ctrl2 = readl(ioaddr + XGMAC_RXQ_CTRL2); + ctrl3 = readl(ioaddr + XGMAC_RXQ_CTRL3); + + /* The software must ensure that the same priority + * is not mapped to multiple Rx queues + */ + for (i = 0; i < 4; i++) + clear_mask |= ((prio << XGMAC_PSRQ_SHIFT(i)) & + XGMAC_PSRQ(i)); + + ctrl2 &= ~clear_mask; + ctrl3 &= ~clear_mask; + + /* First assign new priorities to a queue, then + * clear them from others queues + */ + if (queue < 4) { + ctrl2 |= (prio << XGMAC_PSRQ_SHIFT(queue)) & + XGMAC_PSRQ(queue); + + writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2); + writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3); + } else { queue -= 4; - value = readl(ioaddr + reg); - value &= ~XGMAC_PSRQ(queue); - value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue); + ctrl3 |= (prio << XGMAC_PSRQ_SHIFT(queue)) & + XGMAC_PSRQ(queue); - writel(value, ioaddr + reg); + writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3); + writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2); + } } static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio, @@ -757,6 +781,44 @@ { false, "UNKNOWN", "Unknown Error" }, /* 31 */ }; +#define DPP_RX_ERR "Read Rx Descriptor Parity checker Error" +#define DPP_TX_ERR "Read Tx Descriptor Parity checker Error" + +static const struct dwxgmac3_error_desc dwxgmac3_dma_dpp_errors[32] = { + { true, "TDPES0", DPP_TX_ERR }, + { true, "TDPES1", DPP_TX_ERR }, + { true, "TDPES2", DPP_TX_ERR }, + { true, "TDPES3", DPP_TX_ERR }, + { true, "TDPES4", DPP_TX_ERR }, + { true, "TDPES5", DPP_TX_ERR }, + { true, "TDPES6", DPP_TX_ERR }, + { true, "TDPES7", DPP_TX_ERR }, + { true, "TDPES8", DPP_TX_ERR }, + { true, "TDPES9", DPP_TX_ERR }, + { true, "TDPES10", DPP_TX_ERR }, + { true, "TDPES11", DPP_TX_ERR }, + { true, "TDPES12", DPP_TX_ERR }, + { true, "TDPES13", DPP_TX_ERR }, + { true, "TDPES14", DPP_TX_ERR }, + { true, "TDPES15", DPP_TX_ERR }, + { true, "RDPES0", DPP_RX_ERR }, + { true, "RDPES1", DPP_RX_ERR }, + { true, "RDPES2", DPP_RX_ERR }, + { true, "RDPES3", DPP_RX_ERR }, + { true, "RDPES4", DPP_RX_ERR }, + { true, "RDPES5", DPP_RX_ERR }, + { true, "RDPES6", DPP_RX_ERR }, + { true, "RDPES7", DPP_RX_ERR }, + { true, "RDPES8", DPP_RX_ERR }, + { true, "RDPES9", DPP_RX_ERR }, + { true, "RDPES10", DPP_RX_ERR }, + { true, "RDPES11", DPP_RX_ERR }, + { true, "RDPES12", DPP_RX_ERR }, + { true, "RDPES13", DPP_RX_ERR }, + { true, "RDPES14", DPP_RX_ERR }, + { true, "RDPES15", DPP_RX_ERR }, +}; + static void dwxgmac3_handle_dma_err(struct net_device *ndev, void __iomem *ioaddr, bool correctable, struct stmmac_safety_stats *stats) @@ -768,6 +830,13 @@ dwxgmac3_log_error(ndev, value, correctable, "DMA", dwxgmac3_dma_errors, STAT_OFF(dma_errors), stats); + + value = readl(ioaddr + XGMAC_DMA_DPP_INT_STATUS); + writel(value, ioaddr + XGMAC_DMA_DPP_INT_STATUS); + + dwxgmac3_log_error(ndev, value, false, "DMA_DPP", + dwxgmac3_dma_dpp_errors, + STAT_OFF(dma_dpp_errors), stats); } static int dwxgmac3_safety_feat_config(void __iomem *ioaddr, unsigned int asp) @@ -804,6 +873,12 @@ value |= XGMAC_TMOUTEN; /* FSM Timeout Feature */ writel(value, ioaddr + XGMAC_MAC_FSM_CONTROL); + /* 5. Enable Data Path Parity Protection */ + value = readl(ioaddr + XGMAC_MTL_DPP_CONTROL); + /* already enabled by default, explicit enable it again */ + value &= ~XGMAC_DPP_DISABLE; + writel(value, ioaddr + XGMAC_MTL_DPP_CONTROL); + return 0; } @@ -837,7 +912,11 @@ ret |= !corr; } - err = dma & (XGMAC_DEUIS | XGMAC_DECIS); + /* DMA_DPP_Interrupt_Status is indicated by MCSIS bit in + * DMA_Safety_Interrupt_Status, so we handle DMA Data Path + * Parity Errors here + */ + err = dma & (XGMAC_DEUIS | XGMAC_DECIS | XGMAC_MCSIS); corr = dma & XGMAC_DECIS; if (err) { dwxgmac3_handle_dma_err(ndev, ioaddr, corr, stats); @@ -853,6 +932,7 @@ { dwxgmac3_mac_errors }, { dwxgmac3_mtl_errors }, { dwxgmac3_dma_errors }, + { dwxgmac3_dma_dpp_errors }, }; static int dwxgmac3_safety_feat_dump(struct stmmac_safety_stats *stats, @@ -1101,7 +1181,19 @@ val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_START); val |= XGMAC_TRGTMODSELx(index, XGMAC_PPSCMD_START); - val |= XGMAC_PPSEN0; + + /* XGMAC Core has 4 PPS outputs at most. + * + * Prior XGMAC Core 3.20, Fixed mode or Flexible mode are selectable for + * PPS0 only via PPSEN0. PPS{1,2,3} are in Flexible mode by default, + * and can not be switched to Fixed mode, since PPSEN{1,2,3} are + * read-only reserved to 0. + * But we always set PPSEN{1,2,3} do not make things worse ;-) + * + * From XGMAC Core 3.20 and later, PPSEN{0,1,2,3} are writable and must + * be set, or the PPS outputs stay in Fixed PPS mode by default. + */ + val |= XGMAC_PPSENx(index); writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index)); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c @@ -356,8 +356,8 @@ return ret; } -static void dwxgmac2_get_hw_feature(void __iomem *ioaddr, - struct dma_features *dma_cap) +static int dwxgmac2_get_hw_feature(void __iomem *ioaddr, + struct dma_features *dma_cap) { u32 hw_cap; @@ -425,6 +425,8 @@ dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11; dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9; dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3; + + return 0; } static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 nchan) @@ -489,7 +491,8 @@ u32 value; value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); - value |= bfsize << 1; + value &= ~XGMAC_RBSZ; + value |= bfsize << XGMAC_RBSZ_SHIFT; writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan)); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -196,8 +196,8 @@ int (*dma_interrupt) (void __iomem *ioaddr, struct stmmac_extra_stats *x, u32 chan); /* If supported then get the optional core features */ - void (*get_hw_feature)(void __iomem *ioaddr, - struct dma_features *dma_cap); + int (*get_hw_feature)(void __iomem *ioaddr, + struct dma_features *dma_cap); /* Program the HW RX Watchdog */ void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan); void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan); @@ -247,7 +247,7 @@ #define stmmac_dma_interrupt_status(__priv, __args...) \ stmmac_do_callback(__priv, dma, dma_interrupt, __args) #define stmmac_get_hw_feature(__priv, __args...) \ - stmmac_do_void_callback(__priv, dma, get_hw_feature, __args) + stmmac_do_callback(__priv, dma, get_hw_feature, __args) #define stmmac_rx_watchdog(__priv, __args...) \ stmmac_do_void_callback(__priv, dma, rx_watchdog, __args) #define stmmac_set_tx_ring_len(__priv, __args...) \ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/mmc_core.c @@ -170,8 +170,10 @@ #define MMC_XGMAC_RX_DISCARD_OCT_GB 0x1b4 #define MMC_XGMAC_RX_ALIGN_ERR_PKT 0x1bc +#define MMC_XGMAC_TX_FPE_INTR_MASK 0x204 #define MMC_XGMAC_TX_FPE_FRAG 0x208 #define MMC_XGMAC_TX_HOLD_REQ 0x20c +#define MMC_XGMAC_RX_FPE_INTR_MASK 0x224 #define MMC_XGMAC_RX_PKT_ASSEMBLY_ERR 0x228 #define MMC_XGMAC_RX_PKT_SMD_ERR 0x22c #define MMC_XGMAC_RX_PKT_ASSEMBLY_OK 0x230 @@ -336,6 +338,8 @@ { writel(0x0, mmcaddr + MMC_RX_INTR_MASK); writel(0x0, mmcaddr + MMC_TX_INTR_MASK); + writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_TX_FPE_INTR_MASK); + writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_FPE_INTR_MASK); writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_IPC_INTR_MASK); } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -191,6 +191,7 @@ u32 msg_enable; int wolopts; int wol_irq; + bool wol_irq_disabled; int clk_csr; struct timer_list eee_ctrl_timer; int lpi_irq; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -21,10 +21,18 @@ #include "dwxgmac2.h" #define REG_SPACE_SIZE 0x1060 +#define GMAC4_REG_SPACE_SIZE 0x116C #define MAC100_ETHTOOL_NAME "st_mac100" #define GMAC_ETHTOOL_NAME "st_gmac" #define XGMAC_ETHTOOL_NAME "st_xgmac" +/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h + * + * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the + * same time due to the conflicting macro names. + */ +#define GMAC4_DMA_CHAN_BASE_ADDR 0x00001100 + #define ETHTOOL_DMA_OFFSET 55 struct stmmac_stats { @@ -413,6 +421,8 @@ if (priv->plat->has_xgmac) return XGMAC_REGSIZE * 4; + else if (priv->plat->has_gmac4) + return GMAC4_REG_SPACE_SIZE; return REG_SPACE_SIZE; } @@ -425,8 +435,13 @@ stmmac_dump_mac_regs(priv, priv->hw, reg_space); stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space); - if (!priv->plat->has_xgmac) { - /* Copy DMA registers to where ethtool expects them */ + /* Copy DMA registers to where ethtool expects them */ + if (priv->plat->has_gmac4) { + /* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */ + memcpy(®_space[ETHTOOL_DMA_OFFSET], + ®_space[GMAC4_DMA_CHAN_BASE_ADDR / 4], + NUM_DWMAC4_DMA_REGS * 4); + } else if (!priv->plat->has_xgmac) { memcpy(®_space[ETHTOOL_DMA_OFFSET], ®_space[DMA_BUS_MODE / 4], NUM_DWMAC1000_DMA_REGS * 4); @@ -628,10 +643,16 @@ if (wol->wolopts) { pr_info("stmmac: wakeup enable\n"); device_set_wakeup_enable(priv->device, 1); - enable_irq_wake(priv->wol_irq); + /* Avoid unbalanced enable_irq_wake calls */ + if (priv->wol_irq_disabled) + enable_irq_wake(priv->wol_irq); + priv->wol_irq_disabled = false; } else { device_set_wakeup_enable(priv->device, 0); - disable_irq_wake(priv->wol_irq); + /* Avoid unbalanced disable_irq_wake calls */ + if (!priv->wol_irq_disabled) + disable_irq_wake(priv->wol_irq); + priv->wol_irq_disabled = true; } mutex_lock(&priv->lock); @@ -662,23 +683,16 @@ struct stmmac_priv *priv = netdev_priv(dev); int ret; - if (!edata->eee_enabled) { + if (!priv->dma_cap.eee) + return -EOPNOTSUPP; + + if (!edata->eee_enabled) stmmac_disable_eee_mode(priv); - } else { - /* We are asking for enabling the EEE but it is safe - * to verify all by invoking the eee_init function. - * In case of failure it will return an error. - */ - edata->eee_enabled = stmmac_eee_init(priv); - if (!edata->eee_enabled) - return -EOPNOTSUPP; - } ret = phylink_ethtool_set_eee(priv->phylink, edata); if (ret) return ret; - priv->eee_enabled = edata->eee_enabled; priv->tx_lpi_timer = edata->tx_lpi_timer; return 0; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -26,12 +26,16 @@ unsigned long data; u32 reg_value; - /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second - * formula = (1/ptp_clock) * 1000000000 - * where ptp_clock is 50MHz if fine method is used to update system + /* For GMAC3.x, 4.x versions, in "fine adjustement mode" set sub-second + * increment to twice the number of nanoseconds of a clock cycle. + * The calculation of the default_addend value by the caller will set it + * to mid-range = 2^31 when the remainder of this division is zero, + * which will make the accumulator overflow once every 2 ptp_clock + * cycles, adding twice the number of nanoseconds of a clock cycle : + * 2000000000ULL / ptp_clock. */ if (value & PTP_TCR_TSCFUPDT) - data = (1000000000ULL / 50000000); + data = (2000000000ULL / ptp_clock); else data = (1000000000ULL / ptp_clock); @@ -39,7 +43,8 @@ if (!(value & PTP_TCR_TSCTRLSSR)) data = (data * 1000) / 465; - data &= PTP_SSIR_SSINC_MASK; + if (data > PTP_SSIR_SSINC_MAX) + data = PTP_SSIR_SSINC_MAX; reg_value = data; if (gmac4) @@ -145,15 +150,20 @@ static void get_systime(void __iomem *ioaddr, u64 *systime) { - u64 ns; + u64 ns, sec0, sec1; - /* Get the TSSS value */ - ns = readl(ioaddr + PTP_STNSR); - /* Get the TSS and convert sec time value to nanosecond */ - ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; + /* Get the TSS value */ + sec1 = readl_relaxed(ioaddr + PTP_STSR); + do { + sec0 = sec1; + /* Get the TSSS value */ + ns = readl_relaxed(ioaddr + PTP_STNSR); + /* Get the TSS value */ + sec1 = readl_relaxed(ioaddr + PTP_STSR); + } while (sec0 != sec1); if (systime) - *systime = ns; + *systime = ns + (sec1 * 1000000000ULL); } const struct stmmac_hwtimestamp stmmac_ptp = { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -45,7 +45,7 @@ #include "dwxgmac2.h" #include "hwif.h" -#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES) +#define STMMAC_ALIGN(x) ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16) #define TSO_MAX_BUFF_SIZE (SZ_16K - 1) /* Module parameters */ @@ -105,6 +105,7 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id); #ifdef CONFIG_DEBUG_FS +static const struct net_device_ops stmmac_netdev_ops; static void stmmac_init_fs(struct net_device *dev); static void stmmac_exit_fs(struct net_device *dev); #endif @@ -174,32 +175,6 @@ } } -/** - * stmmac_stop_all_queues - Stop all queues - * @priv: driver private structure - */ -static void stmmac_stop_all_queues(struct stmmac_priv *priv) -{ - u32 tx_queues_cnt = priv->plat->tx_queues_to_use; - u32 queue; - - for (queue = 0; queue < tx_queues_cnt; queue++) - netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); -} - -/** - * stmmac_start_all_queues - Start all queues - * @priv: driver private structure - */ -static void stmmac_start_all_queues(struct stmmac_priv *priv) -{ - u32 tx_queues_cnt = priv->plat->tx_queues_to_use; - u32 queue; - - for (queue = 0; queue < tx_queues_cnt; queue++) - netif_tx_start_queue(netdev_get_tx_queue(priv->dev, queue)); -} - static void stmmac_service_event_schedule(struct stmmac_priv *priv) { if (!test_bit(STMMAC_DOWN, &priv->state) && @@ -250,7 +225,7 @@ priv->clk_csr = STMMAC_CSR_100_150M; else if ((clk_rate >= CSR_F_150M) && (clk_rate < CSR_F_250M)) priv->clk_csr = STMMAC_CSR_150_250M; - else if ((clk_rate >= CSR_F_250M) && (clk_rate < CSR_F_300M)) + else if ((clk_rate >= CSR_F_250M) && (clk_rate <= CSR_F_300M)) priv->clk_csr = STMMAC_CSR_250_300M; } @@ -629,7 +604,8 @@ config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; ptp_v2 = PTP_TCR_TSVER2ENA; snap_type_sel = PTP_TCR_SNAPTYPSEL_1; - ts_event_en = PTP_TCR_TSEVNTENA; + if (priv->synopsys_id < DWMAC_CORE_4_10) + ts_event_en = PTP_TCR_TSEVNTENA; ptp_over_ipv4_udp = PTP_TCR_TSIPV4ENA; ptp_over_ipv6_udp = PTP_TCR_TSIPV6ENA; ptp_over_ethernet = PTP_TCR_TSIPENA; @@ -956,7 +932,8 @@ stmmac_mac_set(priv, priv->ioaddr, true); if (phy && priv->dma_cap.eee) { - priv->eee_active = phy_init_eee(phy, 1) >= 0; + priv->eee_active = + phy_init_eee(phy, !priv->plat->rx_clk_runs_in_lpi) >= 0; priv->eee_enabled = stmmac_eee_init(priv); stmmac_set_eee_pls(priv, priv->hw, true); } @@ -1022,6 +999,11 @@ int addr = priv->plat->phy_addr; struct phy_device *phydev; + if (addr < 0) { + netdev_err(priv->dev, "no phy found\n"); + return -ENODEV; + } + phydev = mdiobus_get_phy(priv->mii, addr); if (!phydev) { netdev_err(priv->dev, "no phy at addr %d\n", addr); @@ -1108,7 +1090,9 @@ { int ret = bufsize; - if (mtu >= BUF_SIZE_4KiB) + if (mtu >= BUF_SIZE_8KiB) + ret = BUF_SIZE_16KiB; + else if (mtu >= BUF_SIZE_4KiB) ret = BUF_SIZE_8KiB; else if (mtu >= BUF_SIZE_2KiB) ret = BUF_SIZE_4KiB; @@ -1292,19 +1276,9 @@ struct stmmac_priv *priv = netdev_priv(dev); u32 rx_count = priv->plat->rx_queues_to_use; int ret = -ENOMEM; - int bfsize = 0; int queue; int i; - bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu); - if (bfsize < 0) - bfsize = 0; - - if (bfsize < BUF_SIZE_16KiB) - bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); - - priv->dma_buf_sz = bfsize; - /* RX INITIALIZATION */ netif_dbg(priv, probe, priv->dev, "SKB addresses:\nskb\t\tskb data\tdma data\n"); @@ -1346,8 +1320,6 @@ } } - buf_sz = bfsize; - return 0; err_init_rx_buffers: @@ -1476,6 +1448,19 @@ } /** + * stmmac_free_tx_skbufs - free TX skb buffers + * @priv: private structure + */ +static void stmmac_free_tx_skbufs(struct stmmac_priv *priv) +{ + u32 tx_queue_cnt = priv->plat->tx_queues_to_use; + u32 queue; + + for (queue = 0; queue < tx_queue_cnt; queue++) + dma_free_tx_skbufs(priv, queue); +} + +/** * free_dma_rx_desc_resources - free RX dma desc resources * @priv: private structure */ @@ -1502,10 +1487,8 @@ rx_q->dma_erx, rx_q->dma_rx_phy); kfree(rx_q->buf_pool); - if (rx_q->page_pool) { - page_pool_request_shutdown(rx_q->page_pool); + if (rx_q->page_pool) page_pool_destroy(rx_q->page_pool); - } } } @@ -2010,6 +1993,8 @@ tx_q->cur_tx = 0; tx_q->mss = 0; netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, chan)); + stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg, + tx_q->dma_tx_phy, chan); stmmac_start_tx_dma(priv, chan); priv->dev->stats.tx_errors++; @@ -2656,6 +2641,7 @@ static int stmmac_open(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); + int bfsize = 0; u32 chan; int ret; @@ -2675,7 +2661,16 @@ memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); priv->xstats.threshold = tc; - priv->dma_buf_sz = STMMAC_ALIGN(buf_sz); + bfsize = stmmac_set_16kib_bfsize(priv, dev->mtu); + if (bfsize < 0) + bfsize = 0; + + if (bfsize < BUF_SIZE_16KiB) + bfsize = stmmac_set_bfsize(dev->mtu, priv->dma_buf_sz); + + priv->dma_buf_sz = bfsize; + buf_sz = bfsize; + priv->rx_copybreak = STMMAC_RX_COPYBREAK; ret = alloc_dma_desc_resources(priv); @@ -2712,6 +2707,7 @@ goto irq_error; } + priv->wol_irq_disabled = true; /* Request the Wake IRQ in case of another line is used for WoL */ if (priv->wol_irq != dev->irq) { ret = request_irq(priv->wol_irq, stmmac_interrupt, @@ -2737,7 +2733,7 @@ } stmmac_enable_all_queues(priv); - stmmac_start_all_queues(priv); + netif_tx_start_all_queues(priv->dev); return 0; @@ -2771,15 +2767,10 @@ struct stmmac_priv *priv = netdev_priv(dev); u32 chan; - if (priv->eee_enabled) - del_timer_sync(&priv->eee_ctrl_timer); - /* Stop and disconnect the PHY */ phylink_stop(priv->phylink); phylink_disconnect_phy(priv->phylink); - stmmac_stop_all_queues(priv); - stmmac_disable_all_queues(priv); for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) @@ -2792,6 +2783,11 @@ if (priv->lpi_irq > 0) free_irq(priv->lpi_irq, dev); + if (priv->eee_enabled) { + priv->tx_path_in_lpi_mode = false; + del_timer_sync(&priv->eee_ctrl_timer); + } + /* Stop TX/RX DMA and clear the descriptors */ stmmac_stop_all_dma(priv); @@ -3105,6 +3101,7 @@ tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc)); stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue); + stmmac_tx_timer_arm(priv, queue); return NETDEV_TX_OK; @@ -3332,6 +3329,7 @@ tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc)); stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue); + stmmac_tx_timer_arm(priv, queue); return NETDEV_TX_OK; @@ -3443,6 +3441,55 @@ stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue); } +static unsigned int stmmac_rx_buf1_len(struct stmmac_priv *priv, + struct dma_desc *p, + int status, unsigned int len) +{ + int ret, coe = priv->hw->rx_csum; + unsigned int plen = 0, hlen = 0; + + /* Not first descriptor, buffer is always zero */ + if (priv->sph && len) + return 0; + + /* First descriptor, get split header length */ + ret = stmmac_get_rx_header_len(priv, p, &hlen); + if (priv->sph && hlen) { + priv->xstats.rx_split_hdr_pkt_n++; + return hlen; + } + + /* First descriptor, not last descriptor and not split header */ + if (status & rx_not_ls) + return priv->dma_buf_sz; + + plen = stmmac_get_rx_frame_len(priv, p, coe); + + /* First descriptor and last descriptor and not split header */ + return min_t(unsigned int, priv->dma_buf_sz, plen); +} + +static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, + struct dma_desc *p, + int status, unsigned int len) +{ + int coe = priv->hw->rx_csum; + unsigned int plen = 0; + + /* Not split header, buffer is not available */ + if (!priv->sph) + return 0; + + /* Not last descriptor */ + if (status & rx_not_ls) + return priv->dma_buf_sz; + + plen = stmmac_get_rx_frame_len(priv, p, coe); + + /* Last descriptor */ + return plen - len; +} + /** * stmmac_rx - manage the receive process * @priv: driver private structure @@ -3472,11 +3519,10 @@ stmmac_display_ring(priv, rx_head, DMA_RX_SIZE, true); } while (count < limit) { - unsigned int hlen = 0, prev_len = 0; + unsigned int buf1_len = 0, buf2_len = 0; enum pkt_hash_types hash_type; struct stmmac_rx_buffer *buf; struct dma_desc *np, *p; - unsigned int sec_len; int entry; u32 hash; @@ -3491,11 +3537,12 @@ len = 0; } +read_again: if (count >= limit) break; -read_again: - sec_len = 0; + buf1_len = 0; + buf2_len = 0; entry = next_entry; buf = &rx_q->buf_pool[entry]; @@ -3520,7 +3567,6 @@ np = rx_q->dma_rx + next_entry; prefetch(np); - prefetch(page_address(buf->page)); if (priv->extend_desc) stmmac_rx_extended_status(priv, &priv->dev->stats, @@ -3537,69 +3583,61 @@ goto read_again; if (unlikely(error)) { dev_kfree_skb(skb); + skb = NULL; count++; continue; } /* Buffer is good. Go on. */ - if (likely(status & rx_not_ls)) { - len += priv->dma_buf_sz; - } else { - prev_len = len; - len = stmmac_get_rx_frame_len(priv, p, coe); + prefetch(page_address(buf->page)); + if (buf->sec_page) + prefetch(page_address(buf->sec_page)); - /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 - * Type frames (LLC/LLC-SNAP) - * - * llc_snap is never checked in GMAC >= 4, so this ACS - * feature is always disabled and packets need to be - * stripped manually. - */ - if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || - unlikely(status != llc_snap)) - len -= ETH_FCS_LEN; + buf1_len = stmmac_rx_buf1_len(priv, p, status, len); + len += buf1_len; + buf2_len = stmmac_rx_buf2_len(priv, p, status, len); + len += buf2_len; + + /* ACS is set; GMAC core strips PAD/FCS for IEEE 802.3 + * Type frames (LLC/LLC-SNAP) + * + * llc_snap is never checked in GMAC >= 4, so this ACS + * feature is always disabled and packets need to be + * stripped manually. + */ + if (unlikely(priv->synopsys_id >= DWMAC_CORE_4_00) || + unlikely(status != llc_snap)) { + if (buf2_len) + buf2_len -= ETH_FCS_LEN; + else + buf1_len -= ETH_FCS_LEN; + + len -= ETH_FCS_LEN; } if (!skb) { - int ret = stmmac_get_rx_header_len(priv, p, &hlen); - - if (priv->sph && !ret && (hlen > 0)) { - sec_len = len; - if (!(status & rx_not_ls)) - sec_len = sec_len - hlen; - len = hlen; - - prefetch(page_address(buf->sec_page)); - priv->xstats.rx_split_hdr_pkt_n++; - } - - skb = napi_alloc_skb(&ch->rx_napi, len); + skb = napi_alloc_skb(&ch->rx_napi, buf1_len); if (!skb) { priv->dev->stats.rx_dropped++; count++; - continue; + goto drain_data; } - dma_sync_single_for_cpu(priv->device, buf->addr, len, - DMA_FROM_DEVICE); + dma_sync_single_for_cpu(priv->device, buf->addr, + buf1_len, DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, page_address(buf->page), - len); - skb_put(skb, len); + buf1_len); + skb_put(skb, buf1_len); /* Data payload copied into SKB, page ready for recycle */ page_pool_recycle_direct(rx_q->page_pool, buf->page); buf->page = NULL; - } else { - unsigned int buf_len = len - prev_len; - - if (likely(status & rx_not_ls)) - buf_len = priv->dma_buf_sz; - + } else if (buf1_len) { dma_sync_single_for_cpu(priv->device, buf->addr, - buf_len, DMA_FROM_DEVICE); + buf1_len, DMA_FROM_DEVICE); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->page, 0, buf_len, + buf->page, 0, buf1_len, priv->dma_buf_sz); /* Data payload appended into SKB */ @@ -3607,22 +3645,23 @@ buf->page = NULL; } - if (sec_len > 0) { + if (buf2_len) { dma_sync_single_for_cpu(priv->device, buf->sec_addr, - sec_len, DMA_FROM_DEVICE); + buf2_len, DMA_FROM_DEVICE); skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, - buf->sec_page, 0, sec_len, + buf->sec_page, 0, buf2_len, priv->dma_buf_sz); - len += sec_len; - /* Data payload appended into SKB */ page_pool_release_page(rx_q->page_pool, buf->sec_page); buf->sec_page = NULL; } +drain_data: if (likely(status & rx_not_ls)) goto read_again; + if (!skb) + continue; /* Got entire packet into SKB. Finish it. */ @@ -3640,13 +3679,14 @@ skb_record_rx_queue(skb, queue); napi_gro_receive(&ch->rx_napi, skb); + skb = NULL; priv->dev->stats.rx_packets++; priv->dev->stats.rx_bytes += len; count++; } - if (status & rx_not_ls) { + if (status & rx_not_ls || skb) { rx_q->state_saved = true; rx_q->state.skb = skb; rx_q->state.error = error; @@ -3749,13 +3789,26 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) { struct stmmac_priv *priv = netdev_priv(dev); + int txfifosz = priv->plat->tx_fifo_size; + const int mtu = new_mtu; + + if (txfifosz == 0) + txfifosz = priv->dma_cap.tx_fifo_size; + + txfifosz /= priv->plat->tx_queues_to_use; if (netif_running(dev)) { netdev_err(priv->dev, "must be stopped to change its MTU\n"); return -EBUSY; } - dev->mtu = new_mtu; + new_mtu = STMMAC_ALIGN(new_mtu); + + /* If condition true, FIFO is too small or MTU too large */ + if ((txfifosz < new_mtu) || (new_mtu > BUF_SIZE_16KiB)) + return -EINVAL; + + dev->mtu = mtu; netdev_update_features(dev); @@ -3819,7 +3872,7 @@ /** * stmmac_interrupt - main ISR * @irq: interrupt number. - * @dev_id: to pass the net device pointer. + * @dev_id: to pass the net device pointer (must be valid). * Description: this is the main driver interrupt service routine. * It can call: * o DMA service routine (to manage incoming frame reception and transmission @@ -3843,11 +3896,6 @@ if (priv->irq_wake) pm_wakeup_event(priv->device, 0); - if (unlikely(!dev)) { - netdev_err(priv->dev, "%s: invalid dev pointer\n", __func__); - return IRQ_NONE; - } - /* Check if adapter is up */ if (test_bit(STMMAC_DOWN, &priv->state)) return IRQ_HANDLED; @@ -3858,7 +3906,6 @@ /* To handle GMAC own interrupts */ if ((priv->plat->has_gmac) || xmac) { int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats); - int mtl_status; if (unlikely(status)) { /* For LPI we need to save the tx status */ @@ -3869,17 +3916,8 @@ } for (queue = 0; queue < queues_count; queue++) { - struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue]; - - mtl_status = stmmac_host_mtl_irq_status(priv, priv->hw, - queue); - if (mtl_status != -EINVAL) - status |= mtl_status; - - if (status & CORE_IRQ_MTL_RX_OVERFLOW) - stmmac_set_rx_tail_ptr(priv, priv->ioaddr, - rx_q->rx_tail_addr, - queue); + status = stmmac_host_mtl_irq_status(priv, priv->hw, + queue); } /* PCS link status */ @@ -4163,10 +4201,40 @@ } DEFINE_SHOW_ATTRIBUTE(stmmac_dma_cap); +/* Use network device events to rename debugfs file entries. + */ +static int stmmac_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct stmmac_priv *priv = netdev_priv(dev); + + if (dev->netdev_ops != &stmmac_netdev_ops) + goto done; + + switch (event) { + case NETDEV_CHANGENAME: + if (priv->dbgfs_dir) + priv->dbgfs_dir = debugfs_rename(stmmac_fs_dir, + priv->dbgfs_dir, + stmmac_fs_dir, + dev->name); + break; + } +done: + return NOTIFY_DONE; +} + +static struct notifier_block stmmac_notifier = { + .notifier_call = stmmac_device_event, +}; + static void stmmac_init_fs(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); + rtnl_lock(); + /* Create per netdev entries */ priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir); @@ -4177,6 +4245,8 @@ /* Entry to report the DMA HW features */ debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, &stmmac_dma_cap_fops); + + rtnl_unlock(); } static void stmmac_exit_fs(struct net_device *dev) @@ -4510,7 +4580,7 @@ dev_info(priv->device, "TSO feature enabled\n"); } - if (priv->dma_cap.sphen) { + if (priv->dma_cap.sphen && !priv->plat->sph_disable) { ndev->hw_features |= NETIF_F_GRO; priv->sph = true; dev_info(priv->device, "SPH feature enabled\n"); @@ -4622,9 +4692,9 @@ /* MDIO bus Registration */ ret = stmmac_mdio_register(ndev); if (ret < 0) { - dev_err(priv->device, - "%s: MDIO bus (id: %d) registration failed", - __func__, priv->plat->bus_id); + dev_err_probe(priv->device, ret, + "%s: MDIO bus (id: %d) registration failed\n", + __func__, priv->plat->bus_id); goto error_mdio_register; } } @@ -4684,14 +4754,14 @@ netdev_info(priv->dev, "%s: removing driver", __func__); -#ifdef CONFIG_DEBUG_FS - stmmac_exit_fs(ndev); -#endif stmmac_stop_all_dma(priv); stmmac_mac_set(priv, priv->ioaddr, false); netif_carrier_off(ndev); unregister_netdev(ndev); +#ifdef CONFIG_DEBUG_FS + stmmac_exit_fs(ndev); +#endif phylink_destroy(priv->phylink); if (priv->plat->stmmac_rst) reset_control_assert(priv->plat->stmmac_rst); @@ -4719,6 +4789,7 @@ { struct net_device *ndev = dev_get_drvdata(dev); struct stmmac_priv *priv = netdev_priv(ndev); + u32 chan; if (!ndev || !netif_running(ndev)) return 0; @@ -4728,10 +4799,17 @@ mutex_lock(&priv->lock); netif_device_detach(ndev); - stmmac_stop_all_queues(priv); stmmac_disable_all_queues(priv); + for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++) + del_timer_sync(&priv->tx_queue[chan].txtimer); + + if (priv->eee_enabled) { + priv->tx_path_in_lpi_mode = false; + del_timer_sync(&priv->eee_ctrl_timer); + } + /* Stop TX/RX DMA */ stmmac_stop_all_dma(priv); @@ -4784,6 +4862,8 @@ tx_q->cur_tx = 0; tx_q->dirty_tx = 0; tx_q->mss = 0; + + netdev_tx_reset_queue(netdev_get_tx_queue(priv->dev, queue)); } } @@ -4824,12 +4904,11 @@ stmmac_mdio_reset(priv->mii); } - netif_device_attach(ndev); - mutex_lock(&priv->lock); stmmac_reset_queues_param(priv); + stmmac_free_tx_skbufs(priv); stmmac_clear_descriptors(priv); stmmac_hw_setup(ndev, false); @@ -4838,8 +4917,6 @@ stmmac_enable_all_queues(priv); - stmmac_start_all_queues(priv); - mutex_unlock(&priv->lock); if (!device_may_wakeup(priv->device)) { @@ -4850,6 +4927,8 @@ phylink_mac_change(priv->phylink, true); + netif_device_attach(ndev); + return 0; } EXPORT_SYMBOL_GPL(stmmac_resume); @@ -4860,7 +4939,7 @@ char *opt; if (!str || !*str) - return -EINVAL; + return 1; while ((opt = strsep(&str, ",")) != NULL) { if (!strncmp(opt, "debug:", 6)) { if (kstrtoint(opt + 6, 0, &debug)) @@ -4891,11 +4970,11 @@ goto err; } } - return 0; + return 1; err: pr_err("%s: ERROR broken module parameter conversion", __func__); - return -EINVAL; + return 1; } __setup("stmmaceth=", stmmac_cmdline_opt); @@ -4907,6 +4986,7 @@ /* Create debugfs main directory if it doesn't exist yet */ if (!stmmac_fs_dir) stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); + register_netdevice_notifier(&stmmac_notifier); #endif return 0; @@ -4915,6 +4995,7 @@ static void __exit stmmac_exit(void) { #ifdef CONFIG_DEBUG_FS + unregister_netdevice_notifier(&stmmac_notifier); debugfs_remove_recursive(stmmac_fs_dir); #endif } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -358,8 +358,12 @@ new_bus->parent = priv->device; err = of_mdiobus_register(new_bus, mdio_node); - if (err != 0) { - dev_err(dev, "Cannot register the MDIO bus\n"); + if (err == -ENODEV) { + err = 0; + dev_info(dev, "MDIO bus is disabled\n"); + goto bus_register_fail; + } else if (err) { + dev_err_probe(dev, err, "Cannot register the MDIO bus\n"); goto bus_register_fail; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -119,6 +119,7 @@ plat->has_gmac4 = 1; plat->force_sf_dma_mode = 0; plat->tso_en = 1; + plat->sph_disable = 1; plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; @@ -481,7 +482,7 @@ return -ENOMEM; /* Enable pci device */ - ret = pci_enable_device(pdev); + ret = pcim_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", __func__); @@ -538,8 +539,6 @@ pcim_iounmap_regions(pdev, BIT(i)); break; } - - pci_disable_device(pdev); } static int __maybe_unused stmmac_pci_suspend(struct device *dev) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -107,10 +107,10 @@ axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en"); axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm"); - axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe"); - axi->axi_fb = of_property_read_bool(np, "snps,axi_fb"); - axi->axi_mb = of_property_read_bool(np, "snps,axi_mb"); - axi->axi_rb = of_property_read_bool(np, "snps,axi_rb"); + axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe"); + axi->axi_fb = of_property_read_bool(np, "snps,fb"); + axi->axi_mb = of_property_read_bool(np, "snps,mb"); + axi->axi_rb = of_property_read_bool(np, "snps,rb"); if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt)) axi->axi_wr_osr_lmt = 1; @@ -320,7 +320,7 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, struct device_node *np, struct device *dev) { - bool mdio = true; + bool mdio = !of_phy_is_fixed_link(np); static const struct of_device_id need_mdio_ids[] = { { .compatible = "snps,dwc-qos-ethernet-4.10" }, {}, @@ -428,8 +428,7 @@ plat->phylink_node = np; /* Get max speed of operation from device tree */ - if (of_property_read_u32(np, "max-speed", &plat->max_speed)) - plat->max_speed = -1; + of_property_read_u32(np, "max-speed", &plat->max_speed); plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) @@ -505,6 +504,14 @@ plat->pmt = 1; } + if (of_device_is_compatible(np, "snps,dwmac-3.40a")) { + plat->has_gmac = 1; + plat->enh_desc = 1; + plat->tx_coe = 1; + plat->bugged_jumbo = 1; + plat->pmt = 1; + } + if (of_device_is_compatible(np, "snps,dwmac-4.00") || of_device_is_compatible(np, "snps,dwmac-4.10a") || of_device_is_compatible(np, "snps,dwmac-4.20a")) { @@ -547,7 +554,7 @@ dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); - if (plat->force_thresh_dma_mode) { + if (plat->force_thresh_dma_mode && plat->force_sf_dma_mode) { plat->force_sf_dma_mode = 0; dev_warn(&pdev->dev, "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n"); @@ -624,6 +631,8 @@ void stmmac_remove_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat) { + clk_disable_unprepare(plat->stmmac_clk); + clk_disable_unprepare(plat->pclk); of_node_put(plat->phy_node); of_node_put(plat->mdio_node); } @@ -663,16 +672,22 @@ * In case the wake up interrupt is not passed from the platform * so the driver will continue to use the mac irq (ndev->irq) */ - stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq"); + stmmac_res->wol_irq = + platform_get_irq_byname_optional(pdev, "eth_wake_irq"); if (stmmac_res->wol_irq < 0) { if (stmmac_res->wol_irq == -EPROBE_DEFER) return -EPROBE_DEFER; + dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n"); stmmac_res->wol_irq = stmmac_res->irq; } - stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi"); - if (stmmac_res->lpi_irq == -EPROBE_DEFER) - return -EPROBE_DEFER; + stmmac_res->lpi_irq = + platform_get_irq_byname_optional(pdev, "eth_lpi"); + if (stmmac_res->lpi_irq < 0) { + if (stmmac_res->lpi_irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + dev_info(&pdev->dev, "IRQ eth_lpi not found\n"); + } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h @@ -61,7 +61,7 @@ #define PTP_TCR_TSENMACADDR BIT(18) /* SSIR defines */ -#define PTP_SSIR_SSINC_MASK 0xff +#define PTP_SSIR_SSINC_MAX 0xff #define GMAC4_PTP_SSIR_SSINC_SHIFT 16 #endif /* __STMMAC_PTP_H__ */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c @@ -80,7 +80,7 @@ if (attr->max_size && (attr->max_size > size)) size = attr->max_size; - skb = netdev_alloc_skb_ip_align(priv->dev, size); + skb = netdev_alloc_skb(priv->dev, size); if (!skb) return NULL; @@ -244,6 +244,8 @@ struct net_device *orig_ndev) { struct stmmac_test_priv *tpriv = pt->af_packet_priv; + unsigned char *src = tpriv->packet->src; + unsigned char *dst = tpriv->packet->dst; struct stmmachdr *shdr; struct ethhdr *ehdr; struct udphdr *uhdr; @@ -260,15 +262,15 @@ goto out; ehdr = (struct ethhdr *)skb_mac_header(skb); - if (tpriv->packet->dst) { - if (!ether_addr_equal(ehdr->h_dest, tpriv->packet->dst)) + if (dst) { + if (!ether_addr_equal_unaligned(ehdr->h_dest, dst)) goto out; } if (tpriv->packet->sarc) { - if (!ether_addr_equal(ehdr->h_source, ehdr->h_dest)) + if (!ether_addr_equal_unaligned(ehdr->h_source, ehdr->h_dest)) goto out; - } else if (tpriv->packet->src) { - if (!ether_addr_equal(ehdr->h_source, tpriv->packet->src)) + } else if (src) { + if (!ether_addr_equal_unaligned(ehdr->h_source, src)) goto out; } @@ -624,6 +626,8 @@ return -EOPNOTSUPP; if (netdev_uc_count(priv->dev) >= priv->hw->unicast_filter_entries) return -EOPNOTSUPP; + if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins) + return -EOPNOTSUPP; while (--tries) { /* We only need to check the mc_addr for collisions */ @@ -666,6 +670,8 @@ if (stmmac_filter_check(priv)) return -EOPNOTSUPP; + if (netdev_uc_count(priv->dev) >= priv->hw->unicast_filter_entries) + return -EOPNOTSUPP; if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins) return -EOPNOTSUPP; @@ -710,7 +716,7 @@ struct ethhdr *ehdr; ehdr = (struct ethhdr *)skb_mac_header(skb); - if (!ether_addr_equal(ehdr->h_source, orig_ndev->dev_addr)) + if (!ether_addr_equal_unaligned(ehdr->h_source, orig_ndev->dev_addr)) goto out; if (ehdr->h_proto != htons(ETH_P_PAUSE)) goto out; @@ -847,12 +853,16 @@ if (tpriv->vlan_id) { if (skb->vlan_proto != htons(proto)) goto out; - if (skb->vlan_tci != tpriv->vlan_id) + if (skb->vlan_tci != tpriv->vlan_id) { + /* Means filter did not work. */ + tpriv->ok = false; + complete(&tpriv->comp); goto out; + } } ehdr = (struct ethhdr *)skb_mac_header(skb); - if (!ether_addr_equal(ehdr->h_dest, tpriv->packet->dst)) + if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->dst)) goto out; ihdr = ip_hdr(skb); @@ -1287,16 +1297,19 @@ struct stmmac_packet_attrs attr = { }; struct flow_dissector *dissector; struct flow_cls_offload *cls; + int ret, old_enable = 0; struct flow_rule *rule; - int ret; if (!tc_can_offload(priv->dev)) return -EOPNOTSUPP; if (!priv->dma_cap.l3l4fnum) return -EOPNOTSUPP; - if (priv->rss.enable) + if (priv->rss.enable) { + old_enable = priv->rss.enable; + priv->rss.enable = false; stmmac_rss_configure(priv, priv->hw, NULL, priv->plat->rx_queues_to_use); + } dissector = kzalloc(sizeof(*dissector), GFP_KERNEL); if (!dissector) { @@ -1363,7 +1376,8 @@ cleanup_dissector: kfree(dissector); cleanup_rss: - if (priv->rss.enable) { + if (old_enable) { + priv->rss.enable = old_enable; stmmac_rss_configure(priv, priv->hw, &priv->rss, priv->plat->rx_queues_to_use); } @@ -1408,16 +1422,19 @@ struct stmmac_packet_attrs attr = { }; struct flow_dissector *dissector; struct flow_cls_offload *cls; + int ret, old_enable = 0; struct flow_rule *rule; - int ret; if (!tc_can_offload(priv->dev)) return -EOPNOTSUPP; if (!priv->dma_cap.l3l4fnum) return -EOPNOTSUPP; - if (priv->rss.enable) + if (priv->rss.enable) { + old_enable = priv->rss.enable; + priv->rss.enable = false; stmmac_rss_configure(priv, priv->hw, NULL, priv->plat->rx_queues_to_use); + } dissector = kzalloc(sizeof(*dissector), GFP_KERNEL); if (!dissector) { @@ -1489,7 +1506,8 @@ cleanup_dissector: kfree(dissector); cleanup_rss: - if (priv->rss.enable) { + if (old_enable) { + priv->rss.enable = old_enable; stmmac_rss_configure(priv, priv->hw, &priv->rss, priv->plat->rx_queues_to_use); } @@ -1542,7 +1560,7 @@ struct arphdr *ahdr; ehdr = (struct ethhdr *)skb_mac_header(skb); - if (!ether_addr_equal(ehdr->h_dest, tpriv->packet->src)) + if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->src)) goto out; ahdr = arp_hdr(skb); @@ -1596,12 +1614,16 @@ } ret = stmmac_set_arp_offload(priv, priv->hw, true, ip_addr); - if (ret) + if (ret) { + kfree_skb(skb); goto cleanup; + } ret = dev_set_promiscuity(priv->dev, 1); - if (ret) + if (ret) { + kfree_skb(skb); goto cleanup; + } skb_set_queue_mapping(skb, 0); ret = dev_queue_xmit(skb); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ linux-oracle-5.4.0/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -332,7 +332,12 @@ priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB; } else if (!qopt->enable) { - return stmmac_dma_qmode(priv, priv->ioaddr, queue, MTL_QUEUE_DCB); + ret = stmmac_dma_qmode(priv, priv->ioaddr, queue, + MTL_QUEUE_DCB); + if (ret) + return ret; + + priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB; } /* Port Transmit Rate and Speed Divider */ @@ -579,6 +584,10 @@ { int ret = 0; + /* When RSS is enabled, the filtering will be bypassed */ + if (priv->rss.enable) + return -EBUSY; + switch (cls->command) { case FLOW_CLS_REPLACE: ret = tc_add_flow(priv, cls); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/Kconfig @@ -73,6 +73,7 @@ config SUNVNET_COMMON tristate "Common routines to support Sun Virtual Networking" depends on SUN_LDOMS + depends on INET default m config SUNVNET --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/cassini.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/cassini.c @@ -1337,7 +1337,7 @@ writel(val, cp->regs + REG_RX_PAGE_SIZE); /* enable the header parser if desired */ - if (CAS_HP_FIRMWARE == cas_prog_null) + if (&CAS_HP_FIRMWARE[0] == &cas_prog_null[0]) return; val = CAS_BASE(HP_CFG_NUM_CPU, CAS_NCPUS > 63 ? 0 : CAS_NCPUS); @@ -2291,7 +2291,7 @@ drops = 0; while (1) { struct cas_rx_comp *rxc = rxcs + entry; - struct sk_buff *uninitialized_var(skb); + struct sk_buff *skb; int type, len; u64 words[4]; int i, dring; @@ -3807,7 +3807,7 @@ /* program header parser */ if ((cp->cas_flags & CAS_FLAG_TARGET_ABORT) || - (CAS_HP_ALT_FIRMWARE == cas_prog_null)) { + (&CAS_HP_ALT_FIRMWARE[0] == &cas_prog_null[0])) { cas_load_firmware(cp, CAS_HP_FIRMWARE); } else { cas_load_firmware(cp, CAS_HP_ALT_FIRMWARE); @@ -4971,7 +4971,7 @@ cas_cacheline_size)) { dev_err(&pdev->dev, "Could not set PCI cache " "line size\n"); - goto err_write_cacheline; + goto err_out_free_res; } } #endif @@ -5138,13 +5138,14 @@ cas_shutdown(cp); mutex_unlock(&cp->pm_mutex); + vfree(cp->fw_data); + pci_iounmap(pdev, cp->regs); err_out_free_res: pci_release_regions(pdev); -err_write_cacheline: /* Try to restore it in case the error occurred after we * set it. */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/ldmvsw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/ldmvsw.c @@ -290,6 +290,9 @@ hp = mdesc_grab(); + if (!hp) + return -ENODEV; + rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); err = -ENODEV; if (!rmac) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/niu.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/niu.c @@ -429,7 +429,7 @@ struct niu_link_config *lp = &np->link_config; u16 pll_cfg, pll_sts; int max_retry = 100; - u64 uninitialized_var(sig), mask, val; + u64 sig, mask, val; u32 tx_cfg, rx_cfg; unsigned long i; int err; @@ -526,7 +526,7 @@ struct niu_link_config *lp = &np->link_config; u32 tx_cfg, rx_cfg, pll_cfg, pll_sts; int max_retry = 100; - u64 uninitialized_var(sig), mask, val; + u64 sig, mask, val; unsigned long i; int err; @@ -714,7 +714,7 @@ static int esr_reset(struct niu *np) { - u32 uninitialized_var(reset); + u32 reset; int err; err = mdio_write(np, np->port, NIU_ESR_DEV_ADDR, @@ -3931,8 +3931,6 @@ mp->rx_mcasts += RXMAC_MC_FRM_CNT_COUNT; if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; - if (val & XRXMAC_STATUS_RXBCAST_CNT_EXP) - mp->rx_bcasts += RXMAC_BC_FRM_CNT_COUNT; if (val & XRXMAC_STATUS_RXHIST1_CNT_EXP) mp->rx_hist_cnt1 += RXMAC_HIST_CNT1_COUNT; if (val & XRXMAC_STATUS_RXHIST2_CNT_EXP) @@ -4505,7 +4503,7 @@ err = niu_rbr_fill(np, rp, GFP_KERNEL); if (err) - return err; + goto out_err; } tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), @@ -8146,10 +8144,10 @@ "VPD_SCAN: Reading in property [%s] len[%d]\n", namebuf, prop_len); for (i = 0; i < prop_len; i++) { - err = niu_pci_eeprom_read(np, off + i); - if (err >= 0) - *prop_buf = err; - ++prop_buf; + err = niu_pci_eeprom_read(np, off + i); + if (err < 0) + return err; + *prop_buf++ = err; } } @@ -8160,14 +8158,14 @@ } /* ESPC_PIO_EN_ENABLE must be set */ -static void niu_pci_vpd_fetch(struct niu *np, u32 start) +static int niu_pci_vpd_fetch(struct niu *np, u32 start) { u32 offset; int err; err = niu_pci_eeprom_read16_swp(np, start + 1); if (err < 0) - return; + return err; offset = err + 3; @@ -8176,12 +8174,14 @@ u32 end; err = niu_pci_eeprom_read(np, here); + if (err < 0) + return err; if (err != 0x90) - return; + return -EINVAL; err = niu_pci_eeprom_read16_swp(np, here + 1); if (err < 0) - return; + return err; here = start + offset + 3; end = start + offset + err; @@ -8189,9 +8189,13 @@ offset += err; err = niu_pci_vpd_scan_props(np, here, end); - if (err < 0 || err == 1) - return; + if (err < 0) + return err; + /* ret == 1 is not an error */ + if (err == 1) + return 0; } + return 0; } /* ESPC_PIO_EN_ENABLE must be set */ @@ -9282,8 +9286,11 @@ offset = niu_pci_vpd_offset(np); netif_printk(np, probe, KERN_DEBUG, np->dev, "%s() VPD offset [%08x]\n", __func__, offset); - if (offset) - niu_pci_vpd_fetch(np, offset); + if (offset) { + err = niu_pci_vpd_fetch(np, offset); + if (err < 0) + return err; + } nw64(ESPC_PIO_EN, 0); if (np->flags & NIU_FLAGS_VPD_VALID) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/sungem.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/sungem.c @@ -959,17 +959,6 @@ return IRQ_HANDLED; } -#ifdef CONFIG_NET_POLL_CONTROLLER -static void gem_poll_controller(struct net_device *dev) -{ - struct gem *gp = netdev_priv(dev); - - disable_irq(gp->pdev->irq); - gem_interrupt(gp->pdev->irq, dev); - enable_irq(gp->pdev->irq); -} -#endif - static void gem_tx_timeout(struct net_device *dev) { struct gem *gp = netdev_priv(dev); @@ -2835,9 +2824,6 @@ .ndo_change_mtu = gem_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = gem_set_mac_address, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = gem_poll_controller, -#endif }; static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/sunhme.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/sunhme.c @@ -2064,9 +2064,9 @@ skb_reserve(copy_skb, 2); skb_put(copy_skb, len); - dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE); skb_copy_from_linear_data(skb, copy_skb->data, len); - dma_sync_single_for_device(hp->dma_dev, dma_addr, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(hp->dma_dev, dma_addr, len + 2, DMA_FROM_DEVICE); /* Reuse original ring buffer. */ hme_write_rxd(hp, this, (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)), @@ -3164,7 +3164,7 @@ if (err) { printk(KERN_ERR "happymeal(PCI): Cannot register net device, " "aborting.\n"); - goto err_out_iounmap; + goto err_out_free_coherent; } pci_set_drvdata(pdev, hp); @@ -3197,6 +3197,10 @@ return 0; +err_out_free_coherent: + dma_free_coherent(hp->dma_dev, PAGE_SIZE, + hp->happy_block, hp->hblock_dvma); + err_out_iounmap: iounmap(hp->gregs); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/sunvnet.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/sunvnet.c @@ -431,6 +431,9 @@ hp = mdesc_grab(); + if (!hp) + return -ENODEV; + vp = vnet_find_parent(hp, vdev->mp, vdev); if (IS_ERR(vp)) { pr_err("Cannot find port parent vnet\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/sun/sunvnet_common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/sun/sunvnet_common.c @@ -1353,27 +1353,12 @@ if (vio_version_after_eq(&port->vio, 1, 3)) localmtu -= VLAN_HLEN; - if (skb->protocol == htons(ETH_P_IP)) { - struct flowi4 fl4; - struct rtable *rt = NULL; - - memset(&fl4, 0, sizeof(fl4)); - fl4.flowi4_oif = dev->ifindex; - fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos); - fl4.daddr = ip_hdr(skb)->daddr; - fl4.saddr = ip_hdr(skb)->saddr; - - rt = ip_route_output_key(dev_net(dev), &fl4); - if (!IS_ERR(rt)) { - skb_dst_set(skb, &rt->dst); - icmp_send(skb, ICMP_DEST_UNREACH, - ICMP_FRAG_NEEDED, - htonl(localmtu)); - } - } + if (skb->protocol == htons(ETH_P_IP)) + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(localmtu)); #if IS_ENABLED(CONFIG_IPV6) else if (skb->protocol == htons(ETH_P_IPV6)) - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu); + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, localmtu); #endif goto out_dropped; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c +++ linux-oracle-5.4.0/drivers/net/ethernet/synopsys/dwc-xlgmac-common.c @@ -513,7 +513,7 @@ void xlgmac_print_all_hw_features(struct xlgmac_pdata *pdata) { - char *str = NULL; + char __maybe_unused *str = NULL; XLGMAC_PR("\n"); XLGMAC_PR("=====================================================\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/tehuti/tehuti.c +++ linux-oracle-5.4.0/drivers/net/ethernet/tehuti/tehuti.c @@ -2052,6 +2052,7 @@ /*bdx_hw_reset(priv); */ if (bdx_read_mac(priv)) { pr_err("load MAC address failed\n"); + err = -EFAULT; goto err_out_iomap; } SET_NETDEV_DEV(ndev, &pdev->dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/Kconfig +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/Kconfig @@ -22,6 +22,7 @@ depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) || COMPILE_TEST select TI_DAVINCI_MDIO select PHYLIB + select GENERIC_ALLOCATOR ---help--- This driver supports TI's DaVinci Ethernet . --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/cpsw.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/cpsw.c @@ -890,8 +890,8 @@ { struct cpsw_common *cpsw = dev_id; - cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); writel(0, &cpsw->wr_regs->rx_en); + cpdma_ctlr_eoi(cpsw->dma, CPDMA_EOI_RX); if (cpsw->quirk_irq) { disable_irq_nosync(cpsw->irqs_table[0]); @@ -1753,6 +1753,8 @@ err_cleanup: if (!cpsw->usage_count) { + napi_disable(&cpsw->napi_rx); + napi_disable(&cpsw->napi_tx); cpdma_ctlr_stop(cpsw->dma); cpsw_destroy_xdp_rxqs(cpsw); } @@ -2209,7 +2211,7 @@ HOST_PORT_NUM, ALE_VLAN, vid); ret |= cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast, 0, ALE_VLAN, vid); - ret |= cpsw_ale_flush_multicast(cpsw->ale, 0, vid); + ret |= cpsw_ale_flush_multicast(cpsw->ale, ALE_PORT_HOST, vid); err: pm_runtime_put(cpsw->dev); return ret; @@ -2876,6 +2878,7 @@ CPSW_MAX_QUEUES, CPSW_MAX_QUEUES); if (!ndev) { dev_err(dev, "error allocating net_device\n"); + ret = -ENOMEM; goto clean_cpts; } @@ -2999,11 +3002,15 @@ struct cpsw_common *cpsw = dev_get_drvdata(dev); int i; + rtnl_lock(); + for (i = 0; i < cpsw->data.slaves; i++) if (cpsw->slaves[i].ndev) if (netif_running(cpsw->slaves[i].ndev)) cpsw_ndo_stop(cpsw->slaves[i].ndev); + rtnl_unlock(); + /* Select sleep pin state */ pinctrl_pm_select_sleep_state(dev); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/cpsw_ale.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/cpsw_ale.c @@ -60,23 +60,37 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) { - int idx; + int idx, idx2, index; + u32 hi_val = 0; idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be fetched exceed a word */ + if (idx != idx2) { + index = 2 - idx2; /* flip */ + hi_val = ale_entry[index] << ((idx2 * 32) - start); + } start -= idx * 32; idx = 2 - idx; /* flip */ - return (ale_entry[idx] >> start) & BITMASK(bits); + return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits); } static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, u32 value) { - int idx; + int idx, idx2, index; value &= BITMASK(bits); - idx = start / 32; + idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be set exceed a word */ + if (idx != idx2) { + index = 2 - idx2; /* flip */ + ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32))); + ale_entry[index] |= (value >> ((idx2 * 32) - start)); + } start -= idx * 32; - idx = 2 - idx; /* flip */ + idx = 2 - idx; /* flip */ ale_entry[idx] &= ~(BITMASK(bits) << start); ale_entry[idx] |= (value << start); } @@ -779,6 +793,7 @@ void cpsw_ale_stop(struct cpsw_ale *ale) { del_timer_sync(&ale->timer); + cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); } @@ -862,6 +877,7 @@ ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS; } + cpsw_ale_control_set(ale, 0, ALE_CLEAR, 1); return ale; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/cpts.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/cpts.c @@ -454,7 +454,9 @@ for (i = 0; i < CPTS_MAX_EVENTS; i++) list_add(&cpts->pool_data[i].list, &cpts->pool); - clk_enable(cpts->refclk); + err = clk_enable(cpts->refclk); + if (err) + return err; cpts_write32(cpts, CPTS_EN, control); cpts_write32(cpts, TS_PEND_EN, int_enable); @@ -485,6 +487,7 @@ ptp_clock_unregister(cpts->clock); cpts->clock = NULL; + cpts->phc_index = -1; cpts_write32(cpts, 0, int_enable); cpts_write32(cpts, 0, control); @@ -667,6 +670,7 @@ cpts->cc.read = cpts_systim_read; cpts->cc.mask = CLOCKSOURCE_MASK(32); cpts->info = cpts_info; + cpts->phc_index = -1; cpts_calc_mult_shift(cpts); /* save cc.mult original value as it can be modified --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/davinci_cpdma.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/davinci_cpdma.c @@ -1018,7 +1018,6 @@ struct cpdma_chan *chan = si->chan; struct cpdma_ctlr *ctlr = chan->ctlr; int len = si->len; - int swlen = len; struct cpdma_desc __iomem *desc; dma_addr_t buffer; u32 mode; @@ -1046,7 +1045,6 @@ if (si->data_dma) { buffer = si->data_dma; dma_sync_single_for_device(ctlr->dev, buffer, len, chan->dir); - swlen |= CPDMA_DMA_EXT_MAP; } else { buffer = dma_map_single(ctlr->dev, si->data_virt, len, chan->dir); ret = dma_mapping_error(ctlr->dev, buffer); @@ -1065,7 +1063,8 @@ writel_relaxed(mode | len, &desc->hw_mode); writel_relaxed((uintptr_t)si->token, &desc->sw_token); writel_relaxed(buffer, &desc->sw_buffer); - writel_relaxed(swlen, &desc->sw_len); + writel_relaxed(si->data_dma ? len | CPDMA_DMA_EXT_MAP : len, + &desc->sw_len); desc_read(desc, sw_len); __cpdma_chan_submit(chan, desc); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/davinci_emac.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/davinci_emac.c @@ -169,11 +169,11 @@ /* EMAC mac_status register */ #define EMAC_MACSTATUS_TXERRCODE_MASK (0xF00000) #define EMAC_MACSTATUS_TXERRCODE_SHIFT (20) -#define EMAC_MACSTATUS_TXERRCH_MASK (0x7) +#define EMAC_MACSTATUS_TXERRCH_MASK (0x70000) #define EMAC_MACSTATUS_TXERRCH_SHIFT (16) #define EMAC_MACSTATUS_RXERRCODE_MASK (0xF000) #define EMAC_MACSTATUS_RXERRCODE_SHIFT (12) -#define EMAC_MACSTATUS_RXERRCH_MASK (0x7) +#define EMAC_MACSTATUS_RXERRCH_MASK (0x700) #define EMAC_MACSTATUS_RXERRCH_SHIFT (8) /* EMAC RX register masks */ @@ -412,8 +412,20 @@ u32 int_ctrl, num_interrupts = 0; u32 prescale = 0, addnl_dvdr = 1, coal_intvl = 0; - if (!coal->rx_coalesce_usecs) - return -EINVAL; + if (!coal->rx_coalesce_usecs) { + priv->coal_intvl = 0; + + switch (priv->version) { + case EMAC_VERSION_2: + emac_ctrl_write(EMAC_DM646X_CMINTCTRL, 0); + break; + default: + emac_ctrl_write(EMAC_CTRL_EWINTTCNT, 0); + break; + } + + return 0; + } coal_intvl = coal->rx_coalesce_usecs; @@ -1226,7 +1238,7 @@ struct net_device *ndev = priv->ndev; struct device *emac_dev = &ndev->dev; u32 status = 0; - u32 num_tx_pkts = 0, num_rx_pkts = 0; + u32 num_rx_pkts = 0; /* Check interrupt vectors and call packet processing */ status = emac_read(EMAC_MACINVECTOR); @@ -1237,8 +1249,7 @@ mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC; if (status & mask) { - num_tx_pkts = cpdma_chan_process(priv->txchan, - EMAC_DEF_TX_MAX_SERVICE); + cpdma_chan_process(priv->txchan, EMAC_DEF_TX_MAX_SERVICE); } /* TX processing */ mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/davinci_mdio.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/davinci_mdio.c @@ -397,6 +397,8 @@ data->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; data->regs = devm_ioremap(dev, res->start, resource_size(res)); if (!data->regs) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/netcp_core.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/netcp_core.c @@ -1262,7 +1262,7 @@ } /* Submit the packet */ -static int netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) +static netdev_tx_t netcp_ndo_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct netcp_intf *netcp = netdev_priv(ndev); struct netcp_stats *tx_stats = &netcp->stats; @@ -1350,9 +1350,9 @@ tx_pipe->dma_queue = knav_queue_open(name, tx_pipe->dma_queue_id, KNAV_QUEUE_SHARED); if (IS_ERR(tx_pipe->dma_queue)) { + ret = PTR_ERR(tx_pipe->dma_queue); dev_err(dev, "Could not open DMA queue for channel \"%s\": %d\n", name, ret); - ret = PTR_ERR(tx_pipe->dma_queue); goto err; } --- linux-oracle-5.4.0.orig/drivers/net/ethernet/ti/tlan.c +++ linux-oracle-5.4.0/drivers/net/ethernet/ti/tlan.c @@ -314,9 +314,8 @@ pci_release_regions(pdev); #endif - free_netdev(dev); - cancel_work_sync(&priv->tlan_tqueue); + free_netdev(dev); } static void tlan_start(struct net_device *dev) @@ -673,7 +672,6 @@ static void __init tlan_eisa_probe(void) { long ioaddr; - int rc = -ENODEV; int irq; u16 device_id; @@ -738,8 +736,7 @@ /* Setup the newly found eisa adapter */ - rc = tlan_probe1(NULL, ioaddr, irq, - 12, NULL); + tlan_probe1(NULL, ioaddr, irq, 12, NULL); continue; out: --- linux-oracle-5.4.0.orig/drivers/net/ethernet/toshiba/ps3_gelic_net.c +++ linux-oracle-5.4.0/drivers/net/ethernet/toshiba/ps3_gelic_net.c @@ -317,15 +317,17 @@ /* set up the hardware pointers in each descriptor */ for (i = 0; i < no; i++, descr++) { + dma_addr_t cpu_addr; + gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE); - descr->bus_addr = - dma_map_single(ctodev(card), descr, - GELIC_DESCR_SIZE, - DMA_BIDIRECTIONAL); - if (!descr->bus_addr) + cpu_addr = dma_map_single(ctodev(card), descr, + GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL); + + if (dma_mapping_error(ctodev(card), cpu_addr)) goto iommu_error; + descr->bus_addr = cpu_to_be32(cpu_addr); descr->next = descr + 1; descr->prev = descr - 1; } @@ -365,28 +367,30 @@ * * allocates a new rx skb, iommu-maps it and attaches it to the descriptor. * Activate the descriptor state-wise + * + * Gelic RX sk_buffs must be aligned to GELIC_NET_RXBUF_ALIGN and the length + * must be a multiple of GELIC_NET_RXBUF_ALIGN. */ static int gelic_descr_prepare_rx(struct gelic_card *card, struct gelic_descr *descr) { + static const unsigned int rx_skb_size = + ALIGN(GELIC_NET_MAX_FRAME, GELIC_NET_RXBUF_ALIGN) + + GELIC_NET_RXBUF_ALIGN - 1; + dma_addr_t cpu_addr; int offset; - unsigned int bufsize; if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE) dev_info(ctodev(card), "%s: ERROR status\n", __func__); - /* we need to round up the buffer size to a multiple of 128 */ - bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN); - /* and we need to have it 128 byte aligned, therefore we allocate a - * bit more */ - descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1); + descr->skb = netdev_alloc_skb(*card->netdev, rx_skb_size); if (!descr->skb) { descr->buf_addr = 0; /* tell DMAC don't touch memory */ dev_info(ctodev(card), "%s:allocate skb failed !!\n", __func__); return -ENOMEM; } - descr->buf_size = cpu_to_be32(bufsize); + descr->buf_size = cpu_to_be32(rx_skb_size); descr->dmac_cmd_status = 0; descr->result_size = 0; descr->valid_size = 0; @@ -397,11 +401,10 @@ if (offset) skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ - descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card), - descr->skb->data, - GELIC_NET_MAX_MTU, - DMA_FROM_DEVICE)); - if (!descr->buf_addr) { + cpu_addr = dma_map_single(ctodev(card), descr->skb->data, + GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE); + descr->buf_addr = cpu_to_be32(cpu_addr); + if (dma_mapping_error(ctodev(card), cpu_addr)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; dev_info(ctodev(card), @@ -781,7 +784,7 @@ buf = dma_map_single(ctodev(card), skb->data, skb->len, DMA_TO_DEVICE); - if (!buf) { + if (dma_mapping_error(ctodev(card), buf)) { dev_err(ctodev(card), "dma map 2 failed (%p, %i). Dropping packet\n", skb->data, skb->len); @@ -917,7 +920,7 @@ data_error = be32_to_cpu(descr->data_error); /* unmap skb buffer */ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), - GELIC_NET_MAX_MTU, + GELIC_NET_MAX_FRAME, DMA_FROM_DEVICE); skb_put(skb, be32_to_cpu(descr->valid_size)? --- linux-oracle-5.4.0.orig/drivers/net/ethernet/toshiba/ps3_gelic_net.h +++ linux-oracle-5.4.0/drivers/net/ethernet/toshiba/ps3_gelic_net.h @@ -19,8 +19,9 @@ #define GELIC_NET_RX_DESCRIPTORS 128 /* num of descriptors */ #define GELIC_NET_TX_DESCRIPTORS 128 /* num of descriptors */ -#define GELIC_NET_MAX_MTU VLAN_ETH_FRAME_LEN -#define GELIC_NET_MIN_MTU VLAN_ETH_ZLEN +#define GELIC_NET_MAX_FRAME 2312 +#define GELIC_NET_MAX_MTU 2294 +#define GELIC_NET_MIN_MTU 64 #define GELIC_NET_RXBUF_ALIGN 128 #define GELIC_CARD_RX_CSUM_DEFAULT 1 /* hw chksum */ #define GELIC_NET_WATCHDOG_TIMEOUT 5*HZ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ linux-oracle-5.4.0/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1217,7 +1217,7 @@ key_index = wl->current_key; if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { - /* reques to change default key index */ + /* request to change default key index */ pr_debug("%s: request to change default key to %d\n", __func__, key_index); wl->current_key = key_index; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/toshiba/spider_net.c +++ linux-oracle-5.4.0/drivers/net/ethernet/toshiba/spider_net.c @@ -283,8 +283,8 @@ descr = descr->next; } while (descr != chain->ring); - dma_free_coherent(&card->pdev->dev, chain->num_desc, - chain->hwring, chain->dma_addr); + dma_free_coherent(&card->pdev->dev, chain->num_desc * sizeof(struct spider_net_hw_descr), + chain->hwring, chain->dma_addr); } /** --- linux-oracle-5.4.0.orig/drivers/net/ethernet/toshiba/tc35815.c +++ linux-oracle-5.4.0/drivers/net/ethernet/toshiba/tc35815.c @@ -644,7 +644,7 @@ linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask); linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); } - linkmode_and(phydev->supported, phydev->supported, mask); + linkmode_andnot(phydev->supported, phydev->supported, mask); linkmode_copy(phydev->advertising, phydev->supported); lp->link = 0; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/tundra/tsi108_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1302,12 +1302,15 @@ data->rxring = dma_alloc_coherent(&data->pdev->dev, rxring_size, &data->rxdma, GFP_KERNEL); - if (!data->rxring) + if (!data->rxring) { + free_irq(data->irq_num, dev); return -ENOMEM; + } data->txring = dma_alloc_coherent(&data->pdev->dev, txring_size, &data->txdma, GFP_KERNEL); if (!data->txring) { + free_irq(data->irq_num, dev); dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring, data->rxdma); return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/via/via-velocity.c +++ linux-oracle-5.4.0/drivers/net/ethernet/via/via-velocity.c @@ -865,26 +865,13 @@ */ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) { - u32 curr_status; struct mac_regs __iomem *regs = vptr->mac_regs; vptr->mii_status = mii_check_media_mode(vptr->mac_regs); - curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL); /* Set mii link status */ set_mii_flow_control(vptr); - /* - Check if new status is consistent with current status - if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) || - (mii_status==curr_status)) { - vptr->mii_status=mii_check_media_mode(vptr->mac_regs); - vptr->mii_status=check_connection_type(vptr->mac_regs); - VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n"); - return 0; - } - */ - if (PHYID_GET_PHY_ID(vptr->phy_id) == PHYID_CICADA_CS8201) MII_REG_BITS_ON(AUXCR_MDPPS, MII_NCONFIG, vptr->mac_regs); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/wiznet/w5100.c +++ linux-oracle-5.4.0/drivers/net/ethernet/wiznet/w5100.c @@ -1052,6 +1052,8 @@ mac_addr = data->mac_addr; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; if (resource_size(mem) < W5100_BUS_DIRECT_SIZE) ops = &w5100_mmio_indirect_ops; else --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xilinx/ll_temac.h +++ linux-oracle-5.4.0/drivers/net/ethernet/xilinx/ll_temac.h @@ -375,10 +375,14 @@ int tx_bd_next; int tx_bd_tail; int rx_bd_ci; + int rx_bd_tail; /* DMA channel control setup */ u32 tx_chnl_ctrl; u32 rx_chnl_ctrl; + u8 coalesce_count_rx; + + struct delayed_work restart_work; }; /* Wrappers for temac_ior()/temac_iow() function pointers above */ --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xilinx/ll_temac_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -102,7 +103,7 @@ */ #define HARD_ACS_RDY_POLL_NS (20 * NSEC_PER_MSEC) -/** +/* * temac_indirect_busywait - Wait for current indirect register access * to complete. */ @@ -117,7 +118,7 @@ return 0; } -/** +/* * temac_indirect_in32 - Indirect register read access. This function * must be called without lp->indirect_lock being held. */ @@ -132,7 +133,7 @@ return val; } -/** +/* * temac_indirect_in32_locked - Indirect register read access. This * function must be called with lp->indirect_lock being held. Use * this together with spin_lock_irqsave/spin_lock_irqrestore to avoid @@ -160,7 +161,7 @@ return temac_ior(lp, XTE_LSW0_OFFSET); } -/** +/* * temac_indirect_out32 - Indirect register write access. This function * must be called without lp->indirect_lock being held. */ @@ -173,7 +174,7 @@ spin_unlock_irqrestore(lp->indirect_lock, flags); } -/** +/* * temac_indirect_out32_locked - Indirect register write access. This * function must be called with lp->indirect_lock being held. Use * this together with spin_lock_irqsave/spin_lock_irqrestore to avoid @@ -198,7 +199,7 @@ WARN_ON(temac_indirect_busywait(lp)); } -/** +/* * temac_dma_in32_* - Memory mapped DMA read, these function expects a * register input that is based on DCR word addresses which are then * converted to memory mapped byte addresses. To be assigned to @@ -214,7 +215,7 @@ return ioread32(lp->sdma_regs + (reg << 2)); } -/** +/* * temac_dma_out32_* - Memory mapped DMA read, these function expects * a register input that is based on DCR word addresses which are then * converted to memory mapped byte addresses. To be assigned to @@ -236,7 +237,7 @@ */ #ifdef CONFIG_PPC_DCR -/** +/* * temac_dma_dcr_in32 - DCR based DMA read */ static u32 temac_dma_dcr_in(struct temac_local *lp, int reg) @@ -244,7 +245,7 @@ return dcr_read(lp->sdma_dcrs, reg); } -/** +/* * temac_dma_dcr_out32 - DCR based DMA write */ static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value) @@ -252,7 +253,7 @@ dcr_write(lp->sdma_dcrs, reg, value); } -/** +/* * temac_dcr_setup - If the DMA is DCR based, then setup the address and * I/O functions */ @@ -289,7 +290,7 @@ #endif -/** +/* * temac_dma_bd_release - Release buffer descriptor rings */ static void temac_dma_bd_release(struct net_device *ndev) @@ -319,7 +320,7 @@ lp->tx_bd_v, lp->tx_bd_p); } -/** +/* * temac_dma_bd_init - Setup buffer descriptor rings */ static int temac_dma_bd_init(struct net_device *ndev) @@ -367,6 +368,8 @@ skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) + goto out; lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr); lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); @@ -387,12 +390,13 @@ lp->tx_bd_next = 0; lp->tx_bd_tail = 0; lp->rx_bd_ci = 0; + lp->rx_bd_tail = RX_BD_NUM - 1; /* Enable RX DMA transfers */ wmb(); lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); lp->dma_out(lp, RX_TAILDESC_PTR, - lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * lp->rx_bd_tail)); /* Prepare for TX DMA transfer */ lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); @@ -585,7 +589,7 @@ {} }; -/** +/* * temac_setoptions */ static u32 temac_setoptions(struct net_device *ndev, u32 options) @@ -766,12 +770,15 @@ stat = be32_to_cpu(cur_p->app0); while (stat & STS_CTRL_APP0_CMPLT) { + /* Make sure that the other fields are read after bd is + * released by dma + */ + rmb(); dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), be32_to_cpu(cur_p->len), DMA_TO_DEVICE); skb = (struct sk_buff *)ptr_from_txbd(cur_p); if (skb) dev_consume_skb_irq(skb); - cur_p->app0 = 0; cur_p->app1 = 0; cur_p->app2 = 0; cur_p->app3 = 0; @@ -780,6 +787,12 @@ ndev->stats.tx_packets++; ndev->stats.tx_bytes += be32_to_cpu(cur_p->len); + /* app0 must be visible last, as it is used to flag + * availability of the bd + */ + smp_mb(); + cur_p->app0 = 0; + lp->tx_bd_ci++; if (lp->tx_bd_ci >= TX_BD_NUM) lp->tx_bd_ci = 0; @@ -788,6 +801,9 @@ stat = be32_to_cpu(cur_p->app0); } + /* Matches barrier in temac_start_xmit */ + smp_mb(); + netif_wake_queue(ndev); } @@ -803,6 +819,9 @@ if (cur_p->app0) return NETDEV_TX_BUSY; + /* Make sure to read next bd app0 after this one */ + rmb(); + tail++; if (tail >= TX_BD_NUM) tail = 0; @@ -830,9 +849,19 @@ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; if (temac_check_tx_bd_space(lp, num_frag + 1)) { - if (!netif_queue_stopped(ndev)) - netif_stop_queue(ndev); - return NETDEV_TX_BUSY; + if (netif_queue_stopped(ndev)) + return NETDEV_TX_BUSY; + + netif_stop_queue(ndev); + + /* Matches barrier in temac_start_xmit_done */ + smp_mb(); + + /* Space might have just been freed - check again */ + if (temac_check_tx_bd_space(lp, num_frag + 1)) + return NETDEV_TX_BUSY; + + netif_wake_queue(ndev); } cur_p->app0 = 0; @@ -850,12 +879,15 @@ skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, skb_headlen(skb), DMA_TO_DEVICE); cur_p->len = cpu_to_be32(skb_headlen(skb)); + if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, skb_dma_addr))) { + dev_kfree_skb_any(skb); + ndev->stats.tx_dropped++; + return NETDEV_TX_OK; + } cur_p->phys = cpu_to_be32(skb_dma_addr); - ptr_to_txbd((void *)skb, cur_p); for (ii = 0; ii < num_frag; ii++) { - lp->tx_bd_tail++; - if (lp->tx_bd_tail >= TX_BD_NUM) + if (++lp->tx_bd_tail >= TX_BD_NUM) lp->tx_bd_tail = 0; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; @@ -863,6 +895,27 @@ skb_frag_address(frag), skb_frag_size(frag), DMA_TO_DEVICE); + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) { + if (--lp->tx_bd_tail < 0) + lp->tx_bd_tail = TX_BD_NUM - 1; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + while (--ii >= 0) { + --frag; + dma_unmap_single(ndev->dev.parent, + be32_to_cpu(cur_p->phys), + skb_frag_size(frag), + DMA_TO_DEVICE); + if (--lp->tx_bd_tail < 0) + lp->tx_bd_tail = TX_BD_NUM - 1; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + } + dma_unmap_single(ndev->dev.parent, + be32_to_cpu(cur_p->phys), + skb_headlen(skb), DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + ndev->stats.tx_dropped++; + return NETDEV_TX_OK; + } cur_p->phys = cpu_to_be32(skb_dma_addr); cur_p->len = cpu_to_be32(skb_frag_size(frag)); cur_p->app0 = 0; @@ -870,6 +923,11 @@ } cur_p->app0 |= cpu_to_be32(STS_CTRL_APP0_EOP); + /* Mark last fragment with skb address, so it can be consumed + * in temac_start_xmit_done() + */ + ptr_to_txbd((void *)skb, cur_p); + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; lp->tx_bd_tail++; if (lp->tx_bd_tail >= TX_BD_NUM) @@ -881,34 +939,62 @@ wmb(); lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + if (temac_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) + netif_stop_queue(ndev); + return NETDEV_TX_OK; } +static int ll_temac_recv_buffers_available(struct temac_local *lp) +{ + int available; + + if (!lp->rx_skb[lp->rx_bd_ci]) + return 0; + available = 1 + lp->rx_bd_tail - lp->rx_bd_ci; + if (available <= 0) + available += RX_BD_NUM; + return available; +} static void ll_temac_recv(struct net_device *ndev) { struct temac_local *lp = netdev_priv(ndev); - struct sk_buff *skb, *new_skb; - unsigned int bdstat; - struct cdmac_bd *cur_p; - dma_addr_t tail_p, skb_dma_addr; - int length; unsigned long flags; + int rx_bd; + bool update_tail = false; spin_lock_irqsave(&lp->rx_lock, flags); - tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; - cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; - - bdstat = be32_to_cpu(cur_p->app0); - while ((bdstat & STS_CTRL_APP0_CMPLT)) { + /* Process all received buffers, passing them on network + * stack. After this, the buffer descriptors will be in an + * un-allocated stage, where no skb is allocated for it, and + * they are therefore not available for TEMAC/DMA. + */ + do { + struct cdmac_bd *bd = &lp->rx_bd_v[lp->rx_bd_ci]; + struct sk_buff *skb = lp->rx_skb[lp->rx_bd_ci]; + unsigned int bdstat = be32_to_cpu(bd->app0); + int length; + + /* While this should not normally happen, we can end + * here when GFP_ATOMIC allocations fail, and we + * therefore have un-allocated buffers. + */ + if (!skb) + break; - skb = lp->rx_skb[lp->rx_bd_ci]; - length = be32_to_cpu(cur_p->app4) & 0x3FFF; + /* Loop over all completed buffer descriptors */ + if (!(bdstat & STS_CTRL_APP0_CMPLT)) + break; - dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), + dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys), XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); + /* The buffer is not valid for DMA anymore */ + bd->phys = 0; + bd->len = 0; + length = be32_to_cpu(bd->app4) & 0x3FFF; skb_put(skb, length); skb->protocol = eth_type_trans(skb, ndev); skb_checksum_none_assert(skb); @@ -923,43 +1009,102 @@ * (back) for proper IP checksum byte order * (be16). */ - skb->csum = htons(be32_to_cpu(cur_p->app3) & 0xFFFF); + skb->csum = htons(be32_to_cpu(bd->app3) & 0xFFFF); skb->ip_summed = CHECKSUM_COMPLETE; } if (!skb_defer_rx_timestamp(skb)) netif_rx(skb); + /* The skb buffer is now owned by network stack above */ + lp->rx_skb[lp->rx_bd_ci] = NULL; ndev->stats.rx_packets++; ndev->stats.rx_bytes += length; - new_skb = netdev_alloc_skb_ip_align(ndev, - XTE_MAX_JUMBO_FRAME_SIZE); - if (!new_skb) { - spin_unlock_irqrestore(&lp->rx_lock, flags); - return; + rx_bd = lp->rx_bd_ci; + if (++lp->rx_bd_ci >= RX_BD_NUM) + lp->rx_bd_ci = 0; + } while (rx_bd != lp->rx_bd_tail); + + /* DMA operations will halt when the last buffer descriptor is + * processed (ie. the one pointed to by RX_TAILDESC_PTR). + * When that happens, no more interrupt events will be + * generated. No IRQ_COAL or IRQ_DLY, and not even an + * IRQ_ERR. To avoid stalling, we schedule a delayed work + * when there is a potential risk of that happening. The work + * will call this function, and thus re-schedule itself until + * enough buffers are available again. + */ + if (ll_temac_recv_buffers_available(lp) < lp->coalesce_count_rx) + schedule_delayed_work(&lp->restart_work, HZ / 1000); + + /* Allocate new buffers for those buffer descriptors that were + * passed to network stack. Note that GFP_ATOMIC allocations + * can fail (e.g. when a larger burst of GFP_ATOMIC + * allocations occurs), so while we try to allocate all + * buffers in the same interrupt where they were processed, we + * continue with what we could get in case of allocation + * failure. Allocation of remaining buffers will be retried + * in following calls. + */ + while (1) { + struct sk_buff *skb; + struct cdmac_bd *bd; + dma_addr_t skb_dma_addr; + + rx_bd = lp->rx_bd_tail + 1; + if (rx_bd >= RX_BD_NUM) + rx_bd = 0; + bd = &lp->rx_bd_v[rx_bd]; + + if (bd->phys) + break; /* All skb's allocated */ + + skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); + if (!skb) { + dev_warn(&ndev->dev, "skb alloc failed\n"); + break; } - cur_p->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); - skb_dma_addr = dma_map_single(ndev->dev.parent, new_skb->data, + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); - cur_p->phys = cpu_to_be32(skb_dma_addr); - cur_p->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); - lp->rx_skb[lp->rx_bd_ci] = new_skb; + if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, + skb_dma_addr))) { + dev_kfree_skb_any(skb); + break; + } - lp->rx_bd_ci++; - if (lp->rx_bd_ci >= RX_BD_NUM) - lp->rx_bd_ci = 0; + bd->phys = cpu_to_be32(skb_dma_addr); + bd->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); + bd->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); + lp->rx_skb[rx_bd] = skb; + + lp->rx_bd_tail = rx_bd; + update_tail = true; + } - cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; - bdstat = be32_to_cpu(cur_p->app0); + /* Move tail pointer when buffers have been allocated */ + if (update_tail) { + lp->dma_out(lp, RX_TAILDESC_PTR, + lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_tail); } - lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); spin_unlock_irqrestore(&lp->rx_lock, flags); } +/* Function scheduled to ensure a restart in case of DMA halt + * condition caused by running out of buffer descriptors. + */ +static void ll_temac_restart_work_func(struct work_struct *work) +{ + struct temac_local *lp = container_of(work, struct temac_local, + restart_work.work); + struct net_device *ndev = lp->ndev; + + ll_temac_recv(ndev); +} + static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) { struct net_device *ndev = _ndev; @@ -1052,6 +1197,8 @@ dev_dbg(&ndev->dev, "temac_close()\n"); + cancel_delayed_work_sync(&lp->restart_work); + free_irq(lp->tx_irq, ndev); free_irq(lp->rx_irq, ndev); @@ -1184,6 +1331,7 @@ lp->dev = &pdev->dev; lp->options = XTE_OPTION_DEFAULTS; spin_lock_init(&lp->rx_lock); + INIT_DELAYED_WORK(&lp->restart_work, ll_temac_restart_work_func); /* Setup mutex for synchronization of indirect register access */ if (pdata) { @@ -1197,6 +1345,8 @@ lp->indirect_lock = devm_kmalloc(&pdev->dev, sizeof(*lp->indirect_lock), GFP_KERNEL); + if (!lp->indirect_lock) + return -ENOMEM; spin_lock_init(lp->indirect_lock); } @@ -1290,14 +1440,13 @@ */ lp->tx_chnl_ctrl = 0x10220000; lp->rx_chnl_ctrl = 0xff070000; + lp->coalesce_count_rx = 0x07; /* Finished with the DMA node; drop the reference */ of_node_put(dma_np); } else if (pdata) { /* 2nd memory resource specifies DMA registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - lp->sdma_regs = devm_ioremap_nocache(&pdev->dev, res->start, - resource_size(res)); + lp->sdma_regs = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(lp->sdma_regs)) { dev_err(&pdev->dev, "could not map DMA registers\n"); @@ -1321,23 +1470,26 @@ (pdata->tx_irq_count << 16); else lp->tx_chnl_ctrl = 0x10220000; - if (pdata->rx_irq_timeout || pdata->rx_irq_count) + if (pdata->rx_irq_timeout || pdata->rx_irq_count) { lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) | (pdata->rx_irq_count << 16); - else + lp->coalesce_count_rx = pdata->rx_irq_count; + } else { lp->rx_chnl_ctrl = 0xff070000; + lp->coalesce_count_rx = 0x07; + } } /* Error handle returned DMA RX and TX interrupts */ - if (lp->rx_irq < 0) { - if (lp->rx_irq != -EPROBE_DEFER) - dev_err(&pdev->dev, "could not get DMA RX irq\n"); - return lp->rx_irq; - } - if (lp->tx_irq < 0) { - if (lp->tx_irq != -EPROBE_DEFER) - dev_err(&pdev->dev, "could not get DMA TX irq\n"); - return lp->tx_irq; + if (lp->rx_irq <= 0) { + rc = lp->rx_irq ?: -EINVAL; + return dev_err_probe(&pdev->dev, rc, + "could not get DMA RX irq\n"); + } + if (lp->tx_irq <= 0) { + rc = lp->tx_irq ?: -EINVAL; + return dev_err_probe(&pdev->dev, rc, + "could not get DMA TX irq\n"); } if (temac_np) { --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ linux-oracle-5.4.0/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -159,22 +159,17 @@ #define XAE_RCW1_OFFSET 0x00000404 /* Rx Configuration Word 1 */ #define XAE_TC_OFFSET 0x00000408 /* Tx Configuration */ #define XAE_FCC_OFFSET 0x0000040C /* Flow Control Configuration */ -#define XAE_EMMC_OFFSET 0x00000410 /* EMAC mode configuration */ -#define XAE_PHYC_OFFSET 0x00000414 /* RGMII/SGMII configuration */ -#define XAE_MDIO_MC_OFFSET 0x00000500 /* MII Management Config */ -#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MII Management Control */ -#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MII Management Write Data */ -#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MII Management Read Data */ -#define XAE_MDIO_MIS_OFFSET 0x00000600 /* MII Management Interrupt Status */ -/* MII Mgmt Interrupt Pending register offset */ -#define XAE_MDIO_MIP_OFFSET 0x00000620 -/* MII Management Interrupt Enable register offset */ -#define XAE_MDIO_MIE_OFFSET 0x00000640 -/* MII Management Interrupt Clear register offset. */ -#define XAE_MDIO_MIC_OFFSET 0x00000660 +#define XAE_EMMC_OFFSET 0x00000410 /* MAC speed configuration */ +#define XAE_PHYC_OFFSET 0x00000414 /* RX Max Frame Configuration */ +#define XAE_ID_OFFSET 0x000004F8 /* Identification register */ +#define XAE_MDIO_MC_OFFSET 0x00000500 /* MDIO Setup */ +#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MDIO Control */ +#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MDIO Write Data */ +#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MDIO Read Data */ #define XAE_UAW0_OFFSET 0x00000700 /* Unicast address word 0 */ #define XAE_UAW1_OFFSET 0x00000704 /* Unicast address word 1 */ -#define XAE_FMI_OFFSET 0x00000708 /* Filter Mask Index */ +#define XAE_FMI_OFFSET 0x00000708 /* Frame Filter Control */ +#define XAE_FFE_OFFSET 0x0000070C /* Frame Filter Enable */ #define XAE_AF0_OFFSET 0x00000710 /* Address Filter 0 */ #define XAE_AF1_OFFSET 0x00000714 /* Address Filter 1 */ @@ -313,7 +308,7 @@ */ #define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF -/* Bit masks for Axi Ethernet FMI register */ +/* Bit masks for Axi Ethernet FMC register */ #define XAE_FMI_PM_MASK 0x80000000 /* Promis. mode enable */ #define XAE_FMI_IND_MASK 0x00000003 /* Index Mask */ @@ -335,6 +330,7 @@ #define XAE_FEATURE_PARTIAL_TX_CSUM (1 << 1) #define XAE_FEATURE_FULL_RX_CSUM (1 << 2) #define XAE_FEATURE_FULL_TX_CSUM (1 << 3) +#define XAE_FEATURE_DMA_64BIT (1 << 4) #define XAE_NO_CSUM_OFFLOAD 0 @@ -347,9 +343,9 @@ /** * struct axidma_bd - Axi Dma buffer descriptor layout * @next: MM2S/S2MM Next Descriptor Pointer - * @reserved1: Reserved and not used + * @next_msb: MM2S/S2MM Next Descriptor Pointer (high 32 bits) * @phys: MM2S/S2MM Buffer Address - * @reserved2: Reserved and not used + * @phys_msb: MM2S/S2MM Buffer Address (high 32 bits) * @reserved3: Reserved and not used * @reserved4: Reserved and not used * @cntrl: MM2S/S2MM Control value @@ -362,9 +358,9 @@ */ struct axidma_bd { u32 next; /* Physical address of next buffer descriptor */ - u32 reserved1; + u32 next_msb; /* high 32 bits for IP >= v7.1, reserved on older IP */ u32 phys; - u32 reserved2; + u32 phys_msb; /* for IP >= v7.1, reserved for older IP */ u32 reserved3; u32 reserved4; u32 cntrl; @@ -435,7 +431,7 @@ void __iomem *regs; void __iomem *dma_regs; - struct tasklet_struct dma_err_tasklet; + struct work_struct dma_err_task; int tx_irq; int rx_irq; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ linux-oracle-5.4.0/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -41,8 +41,9 @@ #include "xilinx_axienet.h" /* Descriptors defines for Tx and Rx DMA */ -#define TX_BD_NUM_DEFAULT 64 +#define TX_BD_NUM_DEFAULT 128 #define RX_BD_NUM_DEFAULT 1024 +#define TX_BD_NUM_MIN (MAX_SKB_FRAGS + 1) #define TX_BD_NUM_MAX 4096 #define RX_BD_NUM_MAX 4096 @@ -147,6 +148,34 @@ iowrite32(value, lp->dma_regs + reg); } +static void axienet_dma_out_addr(struct axienet_local *lp, off_t reg, + dma_addr_t addr) +{ + axienet_dma_out32(lp, reg, lower_32_bits(addr)); + + if (lp->features & XAE_FEATURE_DMA_64BIT) + axienet_dma_out32(lp, reg + 4, upper_32_bits(addr)); +} + +static void desc_set_phys_addr(struct axienet_local *lp, dma_addr_t addr, + struct axidma_bd *desc) +{ + desc->phys = lower_32_bits(addr); + if (lp->features & XAE_FEATURE_DMA_64BIT) + desc->phys_msb = upper_32_bits(addr); +} + +static dma_addr_t desc_get_phys_addr(struct axienet_local *lp, + struct axidma_bd *desc) +{ + dma_addr_t ret = desc->phys; + + if (lp->features & XAE_FEATURE_DMA_64BIT) + ret |= ((dma_addr_t)desc->phys_msb << 16) << 16; + + return ret; +} + /** * axienet_dma_bd_release - Release buffer descriptor rings * @ndev: Pointer to the net_device structure @@ -160,24 +189,41 @@ int i; struct axienet_local *lp = netdev_priv(ndev); + /* If we end up here, tx_bd_v must have been DMA allocated. */ + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * lp->tx_bd_num, + lp->tx_bd_v, + lp->tx_bd_p); + + if (!lp->rx_bd_v) + return; + for (i = 0; i < lp->rx_bd_num; i++) { - dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, - lp->max_frm_size, DMA_FROM_DEVICE); + dma_addr_t phys; + + /* A NULL skb means this descriptor has not been initialised + * at all. + */ + if (!lp->rx_bd_v[i].skb) + break; + dev_kfree_skb(lp->rx_bd_v[i].skb); - } - if (lp->rx_bd_v) { - dma_free_coherent(ndev->dev.parent, - sizeof(*lp->rx_bd_v) * lp->rx_bd_num, - lp->rx_bd_v, - lp->rx_bd_p); - } - if (lp->tx_bd_v) { - dma_free_coherent(ndev->dev.parent, - sizeof(*lp->tx_bd_v) * lp->tx_bd_num, - lp->tx_bd_v, - lp->tx_bd_p); + /* For each descriptor, we programmed cntrl with the (non-zero) + * descriptor size, after it had been successfully allocated. + * So a non-zero value in there means we need to unmap it. + */ + if (lp->rx_bd_v[i].cntrl) { + phys = desc_get_phys_addr(lp, &lp->rx_bd_v[i]); + dma_unmap_single(ndev->dev.parent, phys, + lp->max_frm_size, DMA_FROM_DEVICE); + } } + + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * lp->rx_bd_num, + lp->rx_bd_v, + lp->rx_bd_p); } /** @@ -207,7 +253,7 @@ sizeof(*lp->tx_bd_v) * lp->tx_bd_num, &lp->tx_bd_p, GFP_KERNEL); if (!lp->tx_bd_v) - goto out; + return -ENOMEM; lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->rx_bd_v) * lp->rx_bd_num, @@ -216,25 +262,37 @@ goto out; for (i = 0; i < lp->tx_bd_num; i++) { - lp->tx_bd_v[i].next = lp->tx_bd_p + - sizeof(*lp->tx_bd_v) * - ((i + 1) % lp->tx_bd_num); + dma_addr_t addr = lp->tx_bd_p + + sizeof(*lp->tx_bd_v) * + ((i + 1) % lp->tx_bd_num); + + lp->tx_bd_v[i].next = lower_32_bits(addr); + if (lp->features & XAE_FEATURE_DMA_64BIT) + lp->tx_bd_v[i].next_msb = upper_32_bits(addr); } for (i = 0; i < lp->rx_bd_num; i++) { - lp->rx_bd_v[i].next = lp->rx_bd_p + - sizeof(*lp->rx_bd_v) * - ((i + 1) % lp->rx_bd_num); + dma_addr_t addr; + + addr = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * + ((i + 1) % lp->rx_bd_num); + lp->rx_bd_v[i].next = lower_32_bits(addr); + if (lp->features & XAE_FEATURE_DMA_64BIT) + lp->rx_bd_v[i].next_msb = upper_32_bits(addr); skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); if (!skb) goto out; lp->rx_bd_v[i].skb = skb; - lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, - skb->data, - lp->max_frm_size, - DMA_FROM_DEVICE); + addr = dma_map_single(ndev->dev.parent, skb->data, + lp->max_frm_size, DMA_FROM_DEVICE); + if (dma_mapping_error(ndev->dev.parent, addr)) { + netdev_err(ndev, "DMA mapping error\n"); + goto out; + } + desc_set_phys_addr(lp, addr, &lp->rx_bd_v[i]); + lp->rx_bd_v[i].cntrl = lp->max_frm_size; } @@ -267,18 +325,18 @@ /* Populate the tail pointer and bring the Rx Axi DMA engine out of * halted state. This will make the Rx side ready for reception. */ - axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr | XAXIDMA_CR_RUNSTOP_MASK); - axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + - (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1))); + axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1))); /* Write to the RS (Run-stop) bit in the Tx channel control register. * Tx channel is now ready to run. But only after we write to the * tail pointer register that the Tx channel will start transmitting. */ - axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr | XAXIDMA_CR_RUNSTOP_MASK); @@ -351,7 +409,7 @@ */ static void axienet_set_multicast_list(struct net_device *ndev) { - int i; + int i = 0; u32 reg, af0reg, af1reg; struct axienet_local *lp = netdev_priv(ndev); @@ -369,7 +427,10 @@ } else if (!netdev_mc_empty(ndev)) { struct netdev_hw_addr *ha; - i = 0; + reg = axienet_ior(lp, XAE_FMI_OFFSET); + reg &= ~XAE_FMI_PM_MASK; + axienet_iow(lp, XAE_FMI_OFFSET, reg); + netdev_for_each_mc_addr(ha, ndev) { if (i >= XAE_MULTICAST_CAM_TABLE_NUM) break; @@ -388,6 +449,7 @@ axienet_iow(lp, XAE_FMI_OFFSET, reg); axienet_iow(lp, XAE_AF0_OFFSET, af0reg); axienet_iow(lp, XAE_AF1_OFFSET, af1reg); + axienet_iow(lp, XAE_FFE_OFFSET, 1); i++; } } else { @@ -395,18 +457,15 @@ reg &= ~XAE_FMI_PM_MASK; axienet_iow(lp, XAE_FMI_OFFSET, reg); - - for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { - reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; - reg |= i; - - axienet_iow(lp, XAE_FMI_OFFSET, reg); - axienet_iow(lp, XAE_AF0_OFFSET, 0); - axienet_iow(lp, XAE_AF1_OFFSET, 0); - } - dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); } + + for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { + reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; + reg |= i; + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_FFE_OFFSET, 0); + } } /** @@ -437,9 +496,10 @@ lp->options |= options; } -static void __axienet_device_reset(struct axienet_local *lp) +static int __axienet_device_reset(struct axienet_local *lp) { u32 timeout; + /* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset * process of Axi DMA takes a while to complete as all pending * commands/transfers will be flushed or completed during this @@ -455,9 +515,11 @@ if (--timeout == 0) { netdev_err(lp->ndev, "%s: DMA reset timeout!\n", __func__); - break; + return -ETIMEDOUT; } } + + return 0; } /** @@ -470,13 +532,17 @@ * areconnected to Axi Ethernet reset lines, this in turn resets the Axi * Ethernet core. No separate hardware reset is done for the Axi Ethernet * core. + * Returns 0 on success or a negative error number otherwise. */ -static void axienet_device_reset(struct net_device *ndev) +static int axienet_device_reset(struct net_device *ndev) { u32 axienet_status; struct axienet_local *lp = netdev_priv(ndev); + int ret; - __axienet_device_reset(lp); + ret = __axienet_device_reset(lp); + if (ret) + return ret; lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE; lp->options |= XAE_OPTION_VLAN; @@ -491,9 +557,11 @@ lp->options |= XAE_OPTION_JUMBO; } - if (axienet_dma_bd_init(ndev)) { + ret = axienet_dma_bd_init(ndev); + if (ret) { netdev_err(ndev, "%s: descriptor allocation failed\n", __func__); + return ret; } axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET); @@ -518,36 +586,54 @@ axienet_setoptions(ndev, lp->options); netif_trans_update(ndev); + + return 0; } /** - * axienet_start_xmit_done - Invoked once a transmit is completed by the - * Axi DMA Tx channel. + * axienet_free_tx_chain - Clean up a series of linked TX descriptors. * @ndev: Pointer to the net_device structure - * - * This function is invoked from the Axi DMA Tx isr to notify the completion - * of transmit operation. It clears fields in the corresponding Tx BDs and - * unmaps the corresponding buffer so that CPU can regain ownership of the - * buffer. It finally invokes "netif_wake_queue" to restart transmission if - * required. + * @first_bd: Index of first descriptor to clean up + * @nr_bds: Number of descriptors to clean up, can be -1 if unknown. + * @sizep: Pointer to a u32 filled with the total sum of all bytes + * in all cleaned-up descriptors. Ignored if NULL. + * + * Would either be called after a successful transmit operation, or after + * there was an error when setting up the chain. + * Returns the number of descriptors handled. */ -static void axienet_start_xmit_done(struct net_device *ndev) +static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd, + int nr_bds, u32 *sizep) { - u32 size = 0; - u32 packets = 0; struct axienet_local *lp = netdev_priv(ndev); struct axidma_bd *cur_p; - unsigned int status = 0; + int max_bds = nr_bds; + unsigned int status; + dma_addr_t phys; + int i; - cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; - status = cur_p->status; - while (status & XAXIDMA_BD_STS_COMPLETE_MASK) { - dma_unmap_single(ndev->dev.parent, cur_p->phys, - (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), - DMA_TO_DEVICE); - if (cur_p->skb) + if (max_bds == -1) + max_bds = lp->tx_bd_num; + + for (i = 0; i < max_bds; i++) { + cur_p = &lp->tx_bd_v[(first_bd + i) % lp->tx_bd_num]; + status = cur_p->status; + + /* If no number is given, clean up *all* descriptors that have + * been completed by the MAC. + */ + if (nr_bds == -1 && !(status & XAXIDMA_BD_STS_COMPLETE_MASK)) + break; + + phys = desc_get_phys_addr(lp, cur_p); + dma_unmap_single(ndev->dev.parent, phys, + (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), + DMA_TO_DEVICE); + + if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK)) dev_consume_skb_irq(cur_p->skb); - /*cur_p->phys = 0;*/ + + cur_p->cntrl = 0; cur_p->app0 = 0; cur_p->app1 = 0; cur_p->app2 = 0; @@ -555,15 +641,36 @@ cur_p->status = 0; cur_p->skb = NULL; - size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; - packets++; - - if (++lp->tx_bd_ci >= lp->tx_bd_num) - lp->tx_bd_ci = 0; - cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; - status = cur_p->status; + if (sizep) + *sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; } + return i; +} + +/** + * axienet_start_xmit_done - Invoked once a transmit is completed by the + * Axi DMA Tx channel. + * @ndev: Pointer to the net_device structure + * + * This function is invoked from the Axi DMA Tx isr to notify the completion + * of transmit operation. It clears fields in the corresponding Tx BDs and + * unmaps the corresponding buffer so that CPU can regain ownership of the + * buffer. It finally invokes "netif_wake_queue" to restart transmission if + * required. + */ +static void axienet_start_xmit_done(struct net_device *ndev) +{ + struct axienet_local *lp = netdev_priv(ndev); + u32 packets = 0; + u32 size = 0; + + packets = axienet_free_tx_chain(ndev, lp->tx_bd_ci, -1, &size); + + lp->tx_bd_ci += packets; + if (lp->tx_bd_ci >= lp->tx_bd_num) + lp->tx_bd_ci -= lp->tx_bd_num; + ndev->stats.tx_packets += packets; ndev->stats.tx_bytes += size; @@ -617,14 +724,15 @@ u32 csum_start_off; u32 csum_index_off; skb_frag_t *frag; - dma_addr_t tail_p; + dma_addr_t tail_p, phys; struct axienet_local *lp = netdev_priv(ndev); struct axidma_bd *cur_p; + u32 orig_tail_ptr = lp->tx_bd_tail; num_frag = skb_shinfo(skb)->nr_frags; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; - if (axienet_check_tx_bd_space(lp, num_frag)) { + if (axienet_check_tx_bd_space(lp, num_frag + 1)) { if (netif_queue_stopped(ndev)) return NETDEV_TX_BUSY; @@ -634,7 +742,7 @@ smp_mb(); /* Space might have just been freed - check again */ - if (axienet_check_tx_bd_space(lp, num_frag)) + if (axienet_check_tx_bd_space(lp, num_frag + 1)) return NETDEV_TX_BUSY; netif_wake_queue(ndev); @@ -644,7 +752,7 @@ if (lp->features & XAE_FEATURE_FULL_TX_CSUM) { /* Tx Full Checksum Offload Enabled */ cur_p->app0 |= 2; - } else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) { + } else if (lp->features & XAE_FEATURE_PARTIAL_TX_CSUM) { csum_start_off = skb_transport_offset(skb); csum_index_off = csum_start_off + skb->csum_offset; /* Tx Partial Checksum Offload Enabled */ @@ -655,19 +763,37 @@ cur_p->app0 |= 2; /* Tx Full Checksum Offload Enabled */ } + phys = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) { + if (net_ratelimit()) + netdev_err(ndev, "TX DMA mapping error\n"); + ndev->stats.tx_dropped++; + return NETDEV_TX_OK; + } + desc_set_phys_addr(lp, phys, cur_p); cur_p->cntrl = skb_headlen(skb) | XAXIDMA_BD_CTRL_TXSOF_MASK; - cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, - skb_headlen(skb), DMA_TO_DEVICE); for (ii = 0; ii < num_frag; ii++) { if (++lp->tx_bd_tail >= lp->tx_bd_num) lp->tx_bd_tail = 0; cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; frag = &skb_shinfo(skb)->frags[ii]; - cur_p->phys = dma_map_single(ndev->dev.parent, - skb_frag_address(frag), - skb_frag_size(frag), - DMA_TO_DEVICE); + phys = dma_map_single(ndev->dev.parent, + skb_frag_address(frag), + skb_frag_size(frag), + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) { + if (net_ratelimit()) + netdev_err(ndev, "TX DMA mapping error\n"); + ndev->stats.tx_dropped++; + axienet_free_tx_chain(ndev, orig_tail_ptr, ii + 1, + NULL); + lp->tx_bd_tail = orig_tail_ptr; + + return NETDEV_TX_OK; + } + desc_set_phys_addr(lp, phys, cur_p); cur_p->cntrl = skb_frag_size(frag); } @@ -676,7 +802,7 @@ tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; /* Start the transfer */ - axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); + axienet_dma_out_addr(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); if (++lp->tx_bd_tail >= lp->tx_bd_num) lp->tx_bd_tail = 0; @@ -706,10 +832,12 @@ cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) { + dma_addr_t phys; + tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; - dma_unmap_single(ndev->dev.parent, cur_p->phys, - lp->max_frm_size, + phys = desc_get_phys_addr(lp, cur_p); + dma_unmap_single(ndev->dev.parent, phys, lp->max_frm_size, DMA_FROM_DEVICE); skb = cur_p->skb; @@ -745,9 +873,17 @@ if (!new_skb) return; - cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, - lp->max_frm_size, - DMA_FROM_DEVICE); + phys = dma_map_single(ndev->dev.parent, new_skb->data, + lp->max_frm_size, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(ndev->dev.parent, phys))) { + if (net_ratelimit()) + netdev_err(ndev, "RX DMA mapping error\n"); + dev_kfree_skb(new_skb); + return; + } + desc_set_phys_addr(lp, phys, cur_p); + cur_p->cntrl = lp->max_frm_size; cur_p->status = 0; cur_p->skb = new_skb; @@ -761,7 +897,7 @@ ndev->stats.rx_bytes += size; if (tail_p) - axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p); + axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p); } /** @@ -791,7 +927,8 @@ return IRQ_NONE; if (status & XAXIDMA_IRQ_ERROR_MASK) { dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status); - dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + dev_err(&ndev->dev, "Current BD is at: 0x%x%08x\n", + (lp->tx_bd_v[lp->tx_bd_ci]).phys_msb, (lp->tx_bd_v[lp->tx_bd_ci]).phys); cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); @@ -806,7 +943,7 @@ /* Write to the Rx channel control register */ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); - tasklet_schedule(&lp->dma_err_tasklet); + schedule_work(&lp->dma_err_task); axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status); } out: @@ -840,7 +977,8 @@ return IRQ_NONE; if (status & XAXIDMA_IRQ_ERROR_MASK) { dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status); - dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + dev_err(&ndev->dev, "Current BD is at: 0x%x%08x\n", + (lp->rx_bd_v[lp->rx_bd_ci]).phys_msb, (lp->rx_bd_v[lp->rx_bd_ci]).phys); cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); @@ -855,7 +993,7 @@ /* write to the Rx channel control register */ axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); - tasklet_schedule(&lp->dma_err_tasklet); + schedule_work(&lp->dma_err_task); axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status); } out: @@ -891,7 +1029,7 @@ return IRQ_HANDLED; } -static void axienet_dma_err_handler(unsigned long data); +static void axienet_dma_err_handler(struct work_struct *work); /** * axienet_open - Driver open routine. @@ -921,8 +1059,9 @@ */ mutex_lock(&lp->mii_bus->mdio_lock); axienet_mdio_disable(lp); - axienet_device_reset(ndev); - ret = axienet_mdio_enable(lp); + ret = axienet_device_reset(ndev); + if (ret == 0) + ret = axienet_mdio_enable(lp); mutex_unlock(&lp->mii_bus->mdio_lock); if (ret < 0) return ret; @@ -935,9 +1074,8 @@ phylink_start(lp->phylink); - /* Enable tasklets for Axi DMA error handling */ - tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, - (unsigned long) lp); + /* Enable worker thread for Axi DMA error handling */ + INIT_WORK(&lp->dma_err_task, axienet_dma_err_handler); /* Enable interrupts for Axi DMA Tx */ ret = request_irq(lp->tx_irq, axienet_tx_irq, IRQF_SHARED, @@ -966,7 +1104,7 @@ err_tx_irq: phylink_stop(lp->phylink); phylink_disconnect_phy(lp->phylink); - tasklet_kill(&lp->dma_err_tasklet); + cancel_work_sync(&lp->dma_err_task); dev_err(lp->dev, "request_irq() failed\n"); return ret; } @@ -1025,7 +1163,7 @@ axienet_mdio_enable(lp); mutex_unlock(&lp->mii_bus->mdio_lock); - tasklet_kill(&lp->dma_err_tasklet); + cancel_work_sync(&lp->dma_err_task); if (lp->eth_irq > 0) free_irq(lp->eth_irq, ndev); @@ -1170,10 +1308,6 @@ data[20] = axienet_ior(lp, XAE_MDIO_MCR_OFFSET); data[21] = axienet_ior(lp, XAE_MDIO_MWD_OFFSET); data[22] = axienet_ior(lp, XAE_MDIO_MRD_OFFSET); - data[23] = axienet_ior(lp, XAE_MDIO_MIS_OFFSET); - data[24] = axienet_ior(lp, XAE_MDIO_MIP_OFFSET); - data[25] = axienet_ior(lp, XAE_MDIO_MIE_OFFSET); - data[26] = axienet_ior(lp, XAE_MDIO_MIC_OFFSET); data[27] = axienet_ior(lp, XAE_UAW0_OFFSET); data[28] = axienet_ior(lp, XAE_UAW1_OFFSET); data[29] = axienet_ior(lp, XAE_FMI_OFFSET); @@ -1212,7 +1346,8 @@ if (ering->rx_pending > RX_BD_NUM_MAX || ering->rx_mini_pending || ering->rx_jumbo_pending || - ering->rx_pending > TX_BD_NUM_MAX) + ering->tx_pending < TX_BD_NUM_MIN || + ering->tx_pending > TX_BD_NUM_MAX) return -EINVAL; if (netif_running(ndev)) @@ -1505,17 +1640,18 @@ }; /** - * axienet_dma_err_handler - Tasklet handler for Axi DMA Error - * @data: Data passed + * axienet_dma_err_handler - Work queue task for Axi DMA Error + * @work: pointer to work_struct * * Resets the Axi DMA and Axi Ethernet devices, and reconfigures the * Tx/Rx BDs. */ -static void axienet_dma_err_handler(unsigned long data) +static void axienet_dma_err_handler(struct work_struct *work) { u32 axienet_status; u32 cr, i; - struct axienet_local *lp = (struct axienet_local *) data; + struct axienet_local *lp = container_of(work, struct axienet_local, + dma_err_task); struct net_device *ndev = lp->ndev; struct axidma_bd *cur_p; @@ -1535,14 +1671,18 @@ for (i = 0; i < lp->tx_bd_num; i++) { cur_p = &lp->tx_bd_v[i]; - if (cur_p->phys) - dma_unmap_single(ndev->dev.parent, cur_p->phys, + if (cur_p->cntrl) { + dma_addr_t addr = desc_get_phys_addr(lp, cur_p); + + dma_unmap_single(ndev->dev.parent, addr, (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), DMA_TO_DEVICE); + } if (cur_p->skb) dev_kfree_skb_irq(cur_p->skb); cur_p->phys = 0; + cur_p->phys_msb = 0; cur_p->cntrl = 0; cur_p->status = 0; cur_p->app0 = 0; @@ -1596,18 +1736,18 @@ /* Populate the tail pointer and bring the Rx Axi DMA engine out of * halted state. This will make the Rx side ready for reception. */ - axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + axienet_dma_out_addr(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr | XAXIDMA_CR_RUNSTOP_MASK); - axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + - (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1))); + axienet_dma_out_addr(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (lp->rx_bd_num - 1))); /* Write to the RS (Run-stop) bit in the Tx channel control register. * Tx channel is now ready to run. But only after we write to the * tail pointer register that the Tx channel will start transmitting */ - axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + axienet_dma_out_addr(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr | XAXIDMA_CR_RUNSTOP_MASK); @@ -1677,6 +1817,18 @@ lp->options = XAE_OPTION_DEFAULTS; lp->rx_bd_num = RX_BD_NUM_DEFAULT; lp->tx_bd_num = TX_BD_NUM_DEFAULT; + + lp->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(lp->clk)) { + ret = PTR_ERR(lp->clk); + goto free_netdev; + } + ret = clk_prepare_enable(lp->clk); + if (ret) { + dev_err(&pdev->dev, "Unable to enable clock: %d\n", ret); + goto free_netdev; + } + /* Map device registers */ ethres = platform_get_resource(pdev, IORESOURCE_MEM, 0); lp->regs = devm_ioremap_resource(&pdev->dev, ethres); @@ -1790,10 +1942,6 @@ /* Check for these resources directly on the Ethernet node. */ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!res) { - dev_err(&pdev->dev, "unable to get DMA memory resource\n"); - goto free_netdev; - } lp->dma_regs = devm_ioremap_resource(&pdev->dev, res); lp->rx_irq = platform_get_irq(pdev, 1); lp->tx_irq = platform_get_irq(pdev, 0); @@ -1810,6 +1958,29 @@ goto free_netdev; } + /* Autodetect the need for 64-bit DMA pointers. + * When the IP is configured for a bus width bigger than 32 bits, + * writing the MSB registers is mandatory, even if they are all 0. + * We can detect this case by writing all 1's to one such register + * and see if that sticks: when the IP is configured for 32 bits + * only, those registers are RES0. + * Those MSB registers were introduced in IP v7.1, which we check first. + */ + if ((axienet_ior(lp, XAE_ID_OFFSET) >> 24) >= 0x9) { + void __iomem *desc = lp->dma_regs + XAXIDMA_TX_CDESC_OFFSET + 4; + + iowrite32(0x0, desc); + if (ioread32(desc) == 0) { /* sanity check */ + iowrite32(0xffffffff, desc); + if (ioread32(desc) > 0) { + lp->features |= XAE_FEATURE_DMA_64BIT; + dev_info(&pdev->dev, + "autodetected 64-bit DMA range\n"); + } + iowrite32(0x0, desc); + } + } + /* Check for Ethernet core IRQ (optional) */ if (lp->eth_irq <= 0) dev_info(&pdev->dev, "Ethernet core IRQ not defined\n"); @@ -1828,20 +1999,6 @@ lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); if (lp->phy_node) { - lp->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(lp->clk)) { - dev_warn(&pdev->dev, "Failed to get clock: %ld\n", - PTR_ERR(lp->clk)); - lp->clk = NULL; - } else { - ret = clk_prepare_enable(lp->clk); - if (ret) { - dev_err(&pdev->dev, "Unable to enable clock: %d\n", - ret); - goto free_netdev; - } - } - ret = axienet_mdio_setup(lp); if (ret) dev_warn(&pdev->dev, --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ linux-oracle-5.4.0/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -541,7 +541,7 @@ xemaclite_enable_interrupts(lp); if (lp->deferred_skb) { - dev_kfree_skb(lp->deferred_skb); + dev_kfree_skb_irq(lp->deferred_skb); lp->deferred_skb = NULL; dev->stats.tx_errors++; } @@ -820,10 +820,10 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) { struct mii_bus *bus; - int rc; struct resource res; struct device_node *np = of_get_parent(lp->phy_node); struct device_node *npp; + int rc, ret; /* Don't register the MDIO bus if the phy_node or its parent node * can't be found. @@ -833,8 +833,14 @@ return -ENODEV; } npp = of_get_parent(np); - - of_address_to_resource(npp, 0, &res); + ret = of_address_to_resource(npp, 0, &res); + of_node_put(npp); + if (ret) { + dev_err(dev, "%s resource error!\n", + dev->of_node->full_name); + of_node_put(np); + return ret; + } if (lp->ndev->mem_start != res.start) { struct phy_device *phydev; phydev = of_phy_find_device(lp->phy_node); @@ -843,6 +849,7 @@ "MDIO of the phy is not registered yet\n"); else put_device(&phydev->mdio.dev); + of_node_put(np); return 0; } @@ -855,6 +862,7 @@ bus = mdiobus_alloc(); if (!bus) { dev_err(dev, "Failed to allocate mdiobus\n"); + of_node_put(np); return -ENOMEM; } @@ -867,6 +875,7 @@ bus->parent = dev; rc = of_mdiobus_register(bus, np); + of_node_put(np); if (rc) { dev_err(dev, "Failed to register mdio bus.\n"); goto err_register; @@ -923,8 +932,6 @@ xemaclite_disable_interrupts(lp); if (lp->phy_node) { - u32 bmcr; - lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, xemaclite_adjust_link, 0, PHY_INTERFACE_MODE_MII); @@ -935,19 +942,6 @@ /* EmacLite doesn't support giga-bit speeds */ phy_set_max_speed(lp->phy_dev, SPEED_100); - - /* Don't advertise 1000BASE-T Full/Half duplex speeds */ - phy_write(lp->phy_dev, MII_CTRL1000, 0); - - /* Advertise only 10 and 100mbps full/half duplex speeds */ - phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL | - ADVERTISE_CSMA); - - /* Restart auto negotiation */ - bmcr = phy_read(lp->phy_dev, MII_BMCR); - bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); - phy_write(lp->phy_dev, MII_BMCR, bmcr); - phy_start(lp->phy_dev); } @@ -1187,15 +1181,16 @@ if (rc) { dev_err(dev, "Cannot register network device, aborting\n"); - goto error; + goto put_node; } dev_info(dev, - "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n", - (unsigned int __force)ndev->mem_start, - (unsigned int __force)lp->base_addr, ndev->irq); + "Xilinx EmacLite at 0x%08X mapped to 0x%p, irq=%d\n", + (unsigned int __force)ndev->mem_start, lp->base_addr, ndev->irq); return 0; +put_node: + of_node_put(lp->phy_node); error: free_netdev(ndev); return rc; --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xircom/xirc2ps_cs.c +++ linux-oracle-5.4.0/drivers/net/ethernet/xircom/xirc2ps_cs.c @@ -503,6 +503,11 @@ xirc2ps_detach(struct pcmcia_device *link) { struct net_device *dev = link->priv; + struct local_info *local = netdev_priv(dev); + + netif_carrier_off(dev); + netif_tx_disable(dev); + cancel_work_sync(&local->tx_timeout_task); dev_dbg(&link->dev, "detach\n"); --- linux-oracle-5.4.0.orig/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ linux-oracle-5.4.0/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -517,25 +517,14 @@ return ret; } -static int ixp4xx_mdio_register(void) +static int ixp4xx_mdio_register(struct eth_regs __iomem *regs) { int err; if (!(mdio_bus = mdiobus_alloc())) return -ENOMEM; - if (cpu_is_ixp43x()) { - /* IXP43x lacks NPE-B and uses NPE-C for MII PHY access */ - if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEC_ETH)) - return -ENODEV; - mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; - } else { - /* All MII PHY accesses use NPE-B Ethernet registers */ - if (!(ixp4xx_read_feature_bits() & IXP4XX_FEATURE_NPEB_ETH0)) - return -ENODEV; - mdio_regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; - } - + mdio_regs = regs; __raw_writel(DEFAULT_CORE_CNTRL, &mdio_regs->core_control); spin_lock_init(&mdio_lock); mdio_bus->name = "IXP4xx MII Bus"; @@ -1374,7 +1363,7 @@ .ndo_validate_addr = eth_validate_addr, }; -static int eth_init_one(struct platform_device *pdev) +static int ixp4xx_eth_probe(struct platform_device *pdev) { struct port *port; struct net_device *dev; @@ -1384,7 +1373,7 @@ char phy_id[MII_BUS_ID_SIZE + 3]; int err; - if (!(dev = alloc_etherdev(sizeof(struct port)))) + if (!(dev = devm_alloc_etherdev(&pdev->dev, sizeof(struct port)))) return -ENOMEM; SET_NETDEV_DEV(dev, &pdev->dev); @@ -1394,20 +1383,51 @@ switch (port->id) { case IXP4XX_ETH_NPEA: + /* If the MDIO bus is not up yet, defer probe */ + if (!mdio_bus) + return -EPROBE_DEFER; port->regs = (struct eth_regs __iomem *)IXP4XX_EthA_BASE_VIRT; regs_phys = IXP4XX_EthA_BASE_PHYS; break; case IXP4XX_ETH_NPEB: + /* + * On all except IXP43x, NPE-B is used for the MDIO bus. + * If there is no NPE-B in the feature set, bail out, else + * register the MDIO bus. + */ + if (!cpu_is_ixp43x()) { + if (!(ixp4xx_read_feature_bits() & + IXP4XX_FEATURE_NPEB_ETH0)) + return -ENODEV; + /* Else register the MDIO bus on NPE-B */ + if ((err = ixp4xx_mdio_register(IXP4XX_EthC_BASE_VIRT))) + return err; + } + if (!mdio_bus) + return -EPROBE_DEFER; port->regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT; regs_phys = IXP4XX_EthB_BASE_PHYS; break; case IXP4XX_ETH_NPEC: + /* + * IXP43x lacks NPE-B and uses NPE-C for the MDIO bus access, + * of there is no NPE-C, no bus, nothing works, so bail out. + */ + if (cpu_is_ixp43x()) { + if (!(ixp4xx_read_feature_bits() & + IXP4XX_FEATURE_NPEC_ETH)) + return -ENODEV; + /* Else register the MDIO bus on NPE-C */ + if ((err = ixp4xx_mdio_register(IXP4XX_EthC_BASE_VIRT))) + return err; + } + if (!mdio_bus) + return -EPROBE_DEFER; port->regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT; regs_phys = IXP4XX_EthC_BASE_PHYS; break; default: - err = -ENODEV; - goto err_free; + return -ENODEV; } dev->netdev_ops = &ixp4xx_netdev_ops; @@ -1416,10 +1436,8 @@ netif_napi_add(dev, &port->napi, eth_poll, NAPI_WEIGHT); - if (!(port->npe = npe_request(NPE_ID(port->id)))) { - err = -EIO; - goto err_free; - } + if (!(port->npe = npe_request(NPE_ID(port->id)))) + return -EIO; port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name); if (!port->mem_res) { @@ -1465,12 +1483,10 @@ release_resource(port->mem_res); err_npe_rel: npe_release(port->npe); -err_free: - free_netdev(dev); return err; } -static int eth_remove_one(struct platform_device *pdev) +static int ixp4xx_eth_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct phy_device *phydev = dev->phydev; @@ -1478,45 +1494,21 @@ unregister_netdev(dev); phy_disconnect(phydev); + ixp4xx_mdio_remove(); npe_port_tab[NPE_ID(port->id)] = NULL; npe_release(port->npe); release_resource(port->mem_res); - free_netdev(dev); return 0; } static struct platform_driver ixp4xx_eth_driver = { .driver.name = DRV_NAME, - .probe = eth_init_one, - .remove = eth_remove_one, + .probe = ixp4xx_eth_probe, + .remove = ixp4xx_eth_remove, }; - -static int __init eth_init_module(void) -{ - int err; - - /* - * FIXME: we bail out on device tree boot but this really needs - * to be fixed in a nicer way: this registers the MDIO bus before - * even matching the driver infrastructure, we should only probe - * detected hardware. - */ - if (of_have_populated_dt()) - return -ENODEV; - if ((err = ixp4xx_mdio_register())) - return err; - return platform_driver_register(&ixp4xx_eth_driver); -} - -static void __exit eth_cleanup_module(void) -{ - platform_driver_unregister(&ixp4xx_eth_driver); - ixp4xx_mdio_remove(); -} +module_platform_driver(ixp4xx_eth_driver); MODULE_AUTHOR("Krzysztof Halasa"); MODULE_DESCRIPTION("Intel IXP4xx Ethernet driver"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:ixp4xx_eth"); -module_init(eth_init_module); -module_exit(eth_cleanup_module); --- linux-oracle-5.4.0.orig/drivers/net/fddi/Kconfig +++ linux-oracle-5.4.0/drivers/net/fddi/Kconfig @@ -40,17 +40,20 @@ config DEFXX_MMIO bool - prompt "Use MMIO instead of PIO" if PCI || EISA + prompt "Use MMIO instead of IOP" if PCI || EISA depends on DEFXX - default n if PCI || EISA + default n if EISA default y ---help--- This instructs the driver to use EISA or PCI memory-mapped I/O - (MMIO) as appropriate instead of programmed I/O ports (PIO). + (MMIO) as appropriate instead of programmed I/O ports (IOP). Enabling this gives an improvement in processing time in parts - of the driver, but it may cause problems with EISA (DEFEA) - adapters. TURBOchannel does not have the concept of I/O ports, - so MMIO is always used for these (DEFTA) adapters. + of the driver, but it requires a memory window to be configured + for EISA (DEFEA) adapters that may not always be available. + Conversely some PCIe host bridges do not support IOP, so MMIO + may be required to access PCI (DEFPA) adapters on downstream PCI + buses with some systems. TURBOchannel does not have the concept + of I/O ports, so MMIO is always used for these (DEFTA) adapters. If unsure, say N. --- linux-oracle-5.4.0.orig/drivers/net/fddi/defxx.c +++ linux-oracle-5.4.0/drivers/net/fddi/defxx.c @@ -495,6 +495,25 @@ .ndo_set_mac_address = dfx_ctl_set_mac_address, }; +static void dfx_register_res_alloc_err(const char *print_name, bool mmio, + bool eisa) +{ + pr_err("%s: Cannot use %s, no address set, aborting\n", + print_name, mmio ? "MMIO" : "I/O"); + pr_err("%s: Recompile driver with \"CONFIG_DEFXX_MMIO=%c\"\n", + print_name, mmio ? 'n' : 'y'); + if (eisa && mmio) + pr_err("%s: Or run ECU and set adapter's MMIO location\n", + print_name); +} + +static void dfx_register_res_err(const char *print_name, bool mmio, + unsigned long start, unsigned long len) +{ + pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, aborting\n", + print_name, mmio ? "MMIO" : "I/O", len, start); +} + /* * ================ * = dfx_register = @@ -568,15 +587,12 @@ dev_set_drvdata(bdev, dev); dfx_get_bars(bdev, bar_start, bar_len); - if (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0) { - pr_err("%s: Cannot use MMIO, no address set, aborting\n", - print_name); - pr_err("%s: Run ECU and set adapter's MMIO location\n", - print_name); - pr_err("%s: Or recompile driver with \"CONFIG_DEFXX_MMIO=n\"" - "\n", print_name); + if (bar_len[0] == 0 || + (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0)) { + dfx_register_res_alloc_err(print_name, dfx_use_mmio, + dfx_bus_eisa); err = -ENXIO; - goto err_out; + goto err_out_disable; } if (dfx_use_mmio) @@ -585,18 +601,16 @@ else region = request_region(bar_start[0], bar_len[0], print_name); if (!region) { - pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, " - "aborting\n", dfx_use_mmio ? "MMIO" : "I/O", print_name, - (long)bar_len[0], (long)bar_start[0]); + dfx_register_res_err(print_name, dfx_use_mmio, + bar_start[0], bar_len[0]); err = -EBUSY; goto err_out_disable; } if (bar_start[1] != 0) { region = request_region(bar_start[1], bar_len[1], print_name); if (!region) { - pr_err("%s: Cannot reserve I/O resource " - "0x%lx @ 0x%lx, aborting\n", print_name, - (long)bar_len[1], (long)bar_start[1]); + dfx_register_res_err(print_name, 0, + bar_start[1], bar_len[1]); err = -EBUSY; goto err_out_csr_region; } @@ -604,9 +618,8 @@ if (bar_start[2] != 0) { region = request_region(bar_start[2], bar_len[2], print_name); if (!region) { - pr_err("%s: Cannot reserve I/O resource " - "0x%lx @ 0x%lx, aborting\n", print_name, - (long)bar_len[2], (long)bar_start[2]); + dfx_register_res_err(print_name, 0, + bar_start[2], bar_len[2]); err = -EBUSY; goto err_out_bh_region; } @@ -3831,10 +3844,24 @@ int status; status = pci_register_driver(&dfx_pci_driver); - if (!status) - status = eisa_driver_register(&dfx_eisa_driver); - if (!status) - status = tc_register_driver(&dfx_tc_driver); + if (status) + goto err_pci_register; + + status = eisa_driver_register(&dfx_eisa_driver); + if (status) + goto err_eisa_register; + + status = tc_register_driver(&dfx_tc_driver); + if (status) + goto err_tc_register; + + return 0; + +err_tc_register: + eisa_driver_unregister(&dfx_eisa_driver); +err_eisa_register: + pci_unregister_driver(&dfx_pci_driver); +err_pci_register: return status; } --- linux-oracle-5.4.0.orig/drivers/net/fddi/defza.c +++ linux-oracle-5.4.0/drivers/net/fddi/defza.c @@ -1504,9 +1504,8 @@ release_mem_region(start, len); err_out_kfree: - free_netdev(dev); - pr_err("%s: initialization failure, aborting!\n", fp->name); + free_netdev(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/net/fjes/fjes_hw.c +++ linux-oracle-5.4.0/drivers/net/fjes/fjes_hw.c @@ -220,21 +220,25 @@ mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid); hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL); - if (!(hw->hw_info.req_buf)) - return -ENOMEM; + if (!(hw->hw_info.req_buf)) { + result = -ENOMEM; + goto free_ep_info; + } hw->hw_info.req_buf_size = mem_size; mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid); hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL); - if (!(hw->hw_info.res_buf)) - return -ENOMEM; + if (!(hw->hw_info.res_buf)) { + result = -ENOMEM; + goto free_req_buf; + } hw->hw_info.res_buf_size = mem_size; result = fjes_hw_alloc_shared_status_region(hw); if (result) - return result; + goto free_res_buf; hw->hw_info.buffer_share_bit = 0; hw->hw_info.buffer_unshare_reserve_bit = 0; @@ -245,11 +249,11 @@ result = fjes_hw_alloc_epbuf(&buf_pair->tx); if (result) - return result; + goto free_epbuf; result = fjes_hw_alloc_epbuf(&buf_pair->rx); if (result) - return result; + goto free_epbuf; spin_lock_irqsave(&hw->rx_status_lock, flags); fjes_hw_setup_epbuf(&buf_pair->tx, mac, @@ -272,6 +276,25 @@ fjes_hw_init_command_registers(hw, ¶m); return 0; + +free_epbuf: + for (epidx = 0; epidx < hw->max_epid ; epidx++) { + if (epidx == hw->my_epid) + continue; + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx); + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx); + } + fjes_hw_free_shared_status_region(hw); +free_res_buf: + kfree(hw->hw_info.res_buf); + hw->hw_info.res_buf = NULL; +free_req_buf: + kfree(hw->hw_info.req_buf); + hw->hw_info.req_buf = NULL; +free_ep_info: + kfree(hw->ep_shm_info); + hw->ep_shm_info = NULL; + return result; } static void fjes_hw_cleanup(struct fjes_hw *hw) --- linux-oracle-5.4.0.orig/drivers/net/fjes/fjes_main.c +++ linux-oracle-5.4.0/drivers/net/fjes/fjes_main.c @@ -166,6 +166,9 @@ /* create platform_device */ plat_dev = platform_device_register_simple(DRV_NAME, 0, fjes_resource, ARRAY_SIZE(fjes_resource)); + if (IS_ERR(plat_dev)) + return PTR_ERR(plat_dev); + device->driver_data = plat_dev; return 0; @@ -1259,9 +1262,18 @@ adapter->interrupt_watch_enable = false; res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; + goto err_free_control_wq; + } hw->hw_res.start = res->start; hw->hw_res.size = resource_size(res); hw->hw_res.irq = platform_get_irq(plat_dev, 0); + if (hw->hw_res.irq < 0) { + err = hw->hw_res.irq; + goto err_free_control_wq; + } + err = fjes_hw_init(&adapter->hw); if (err) goto err_free_control_wq; --- linux-oracle-5.4.0.orig/drivers/net/geneve.c +++ linux-oracle-5.4.0/drivers/net/geneve.c @@ -215,14 +215,13 @@ struct metadata_dst *tun_dst = NULL; struct pcpu_sw_netstats *stats; unsigned int len; - int err = 0; + int nh, err = 0; void *oiph; if (ip_tunnel_collect_metadata() || gs->collect_md) { __be16 flags; - flags = TUNNEL_KEY | TUNNEL_GENEVE_OPT | - (gnvh->oam ? TUNNEL_OAM : 0) | + flags = TUNNEL_KEY | (gnvh->oam ? TUNNEL_OAM : 0) | (gnvh->critical ? TUNNEL_CRIT_OPT : 0); tun_dst = udp_tun_rx_dst(skb, geneve_get_sk_family(gs), flags, @@ -260,9 +259,23 @@ goto drop; } - oiph = skb_network_header(skb); + /* Save offset of outer header relative to skb->head, + * because we are going to reset the network header to the inner header + * and might change skb->head. + */ + nh = skb_network_header(skb) - skb->head; + skb_reset_network_header(skb); + if (!pskb_inet_may_pull(skb)) { + DEV_STATS_INC(geneve->dev, rx_length_errors); + DEV_STATS_INC(geneve->dev, rx_errors); + goto drop; + } + + /* Get the outer header. */ + oiph = skb->head + nh; + if (geneve_get_sk_family(gs) == AF_INET) err = IP_ECN_decapsulate(oiph, skb); #if IS_ENABLED(CONFIG_IPV6) @@ -773,7 +786,8 @@ struct net_device *dev, struct geneve_sock *gs4, struct flowi4 *fl4, - const struct ip_tunnel_info *info) + const struct ip_tunnel_info *info, + __be16 dport, __be16 sport) { bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct geneve_dev *geneve = netdev_priv(dev); @@ -789,6 +803,8 @@ fl4->flowi4_proto = IPPROTO_UDP; fl4->daddr = info->key.u.ipv4.dst; fl4->saddr = info->key.u.ipv4.src; + fl4->fl4_dport = dport; + fl4->fl4_sport = sport; tos = info->key.tos; if ((tos == 1) && !geneve->collect_md) { @@ -823,7 +839,8 @@ struct net_device *dev, struct geneve_sock *gs6, struct flowi6 *fl6, - const struct ip_tunnel_info *info) + const struct ip_tunnel_info *info, + __be16 dport, __be16 sport) { bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct geneve_dev *geneve = netdev_priv(dev); @@ -839,21 +856,25 @@ fl6->flowi6_proto = IPPROTO_UDP; fl6->daddr = info->key.u.ipv6.dst; fl6->saddr = info->key.u.ipv6.src; + fl6->fl6_dport = dport; + fl6->fl6_sport = sport; + prio = info->key.tos; if ((prio == 1) && !geneve->collect_md) { prio = ip_tunnel_get_dsfield(ip_hdr(skb), skb); use_cache = false; } - fl6->flowlabel = ip6_make_flowinfo(RT_TOS(prio), - info->key.label); + fl6->flowlabel = ip6_make_flowinfo(prio, info->key.label); dst_cache = (struct dst_cache *)&info->dst_cache; if (use_cache) { dst = dst_cache_get_ip6(dst_cache, &fl6->saddr); if (dst) return dst; } - if (ipv6_stub->ipv6_dst_lookup(geneve->net, gs6->sock->sk, &dst, fl6)) { + dst = ipv6_stub->ipv6_dst_lookup_flow(geneve->net, gs6->sock->sk, fl6, + NULL); + if (IS_ERR(dst)) { netdev_dbg(dev, "no route to %pI6\n", &fl6->daddr); return ERR_PTR(-ENETUNREACH); } @@ -883,14 +904,18 @@ __be16 sport; int err; - rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info); + if (!skb_vlan_inet_prepare(skb)) + return -EINVAL; + + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info, + geneve->info.key.tp_dst, sport); if (IS_ERR(rt)) return PTR_ERR(rt); skb_tunnel_check_pmtu(skb, &rt->dst, GENEVE_IPV4_HLEN + info->options_len); - sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); if (geneve->collect_md) { tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); ttl = key->ttl; @@ -945,13 +970,17 @@ __be16 sport; int err; - dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info); + if (!skb_vlan_inet_prepare(skb)) + return -EINVAL; + + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info, + geneve->info.key.tp_dst, sport); if (IS_ERR(dst)) return PTR_ERR(dst); skb_tunnel_check_pmtu(skb, dst, GENEVE_IPV6_HLEN + info->options_len); - sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); if (geneve->collect_md) { prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); ttl = key->ttl; @@ -985,9 +1014,10 @@ if (geneve->collect_md) { info = skb_tunnel_info(skb); if (unlikely(!info || !(info->mode & IP_TUNNEL_INFO_TX))) { - err = -EINVAL; netdev_dbg(dev, "no tunnel metadata\n"); - goto tx_error; + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; } } else { info = &geneve->info; @@ -1004,7 +1034,7 @@ if (likely(!err)) return NETDEV_TX_OK; -tx_error: + dev_kfree_skb(skb); if (err == -ELOOP) @@ -1031,13 +1061,18 @@ { struct ip_tunnel_info *info = skb_tunnel_info(skb); struct geneve_dev *geneve = netdev_priv(dev); + __be16 sport; if (ip_tunnel_info_af(info) == AF_INET) { struct rtable *rt; struct flowi4 fl4; + struct geneve_sock *gs4 = rcu_dereference(geneve->sock4); + sport = udp_flow_src_port(geneve->net, skb, + 1, USHRT_MAX, true); - rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info); + rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info, + geneve->info.key.tp_dst, sport); if (IS_ERR(rt)) return PTR_ERR(rt); @@ -1047,9 +1082,13 @@ } else if (ip_tunnel_info_af(info) == AF_INET6) { struct dst_entry *dst; struct flowi6 fl6; + struct geneve_sock *gs6 = rcu_dereference(geneve->sock6); + sport = udp_flow_src_port(geneve->net, skb, + 1, USHRT_MAX, true); - dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info); + dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info, + geneve->info.key.tp_dst, sport); if (IS_ERR(dst)) return PTR_ERR(dst); @@ -1060,8 +1099,7 @@ return -EINVAL; } - info->key.tp_src = udp_flow_src_port(geneve->net, skb, - 1, USHRT_MAX, true); + info->key.tp_src = sport; info->key.tp_dst = geneve->info.key.tp_dst; return 0; } @@ -1205,7 +1243,7 @@ enum ifla_geneve_df df = nla_get_u8(data[IFLA_GENEVE_DF]); if (df < 0 || df > GENEVE_DF_MAX) { - NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_GENEVE_DF], + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_DF], "Invalid DF attribute"); return -EINVAL; } @@ -1612,11 +1650,11 @@ struct netlink_ext_ack *extack) { struct geneve_dev *geneve = netdev_priv(dev); + enum ifla_geneve_df df = geneve->df; struct geneve_sock *gs4, *gs6; struct ip_tunnel_info info; bool metadata; bool use_udp6_rx_checksums; - enum ifla_geneve_df df; bool ttl_inherit; int err; @@ -1646,6 +1684,7 @@ geneve->collect_md = metadata; geneve->use_udp6_rx_checksums = use_udp6_rx_checksums; geneve->ttl_inherit = ttl_inherit; + geneve->df = df; geneve_unquiesce(geneve, gs4, gs6); return 0; @@ -1828,23 +1867,9 @@ { struct geneve_net *gn = net_generic(net, geneve_net_id); struct geneve_dev *geneve, *next; - struct net_device *dev, *aux; - /* gather any geneve devices that were moved into this ns */ - for_each_netdev_safe(net, dev, aux) - if (dev->rtnl_link_ops == &geneve_link_ops) - unregister_netdevice_queue(dev, head); - - /* now gather any other geneve devices that were created in this ns */ - list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) { - /* If geneve->dev is in the same netns, it was already added - * to the list by the previous loop. - */ - if (!net_eq(dev_net(geneve->dev), net)) - unregister_netdevice_queue(geneve->dev, head); - } - - WARN_ON_ONCE(!list_empty(&gn->sock_list)); + list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) + geneve_dellink(geneve->dev, head); } static void __net_exit geneve_exit_batch_net(struct list_head *net_list) @@ -1859,6 +1884,12 @@ /* unregister the devices gathered above */ unregister_netdevice_many(&list); rtnl_unlock(); + + list_for_each_entry(net, net_list, exit_list) { + const struct geneve_net *gn = net_generic(net, geneve_net_id); + + WARN_ON_ONCE(!list_empty(&gn->sock_list)); + } } static struct pernet_operations geneve_net_ops = { --- linux-oracle-5.4.0.orig/drivers/net/gtp.c +++ linux-oracle-5.4.0/drivers/net/gtp.c @@ -38,7 +38,6 @@ struct hlist_node hlist_addr; union { - u64 tid; struct { u64 tid; u16 flow; @@ -298,7 +297,9 @@ gtp->sk1u = NULL; udp_sk(sk)->encap_type = 0; rcu_assign_sk_user_data(sk, NULL); + release_sock(sk); sock_put(sk); + return; } release_sock(sk); } @@ -541,14 +542,14 @@ mtu = dst_mtu(&rt->dst); } - rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu); + rt->dst.ops->update_pmtu(&rt->dst, NULL, skb, mtu, false); - if (!skb_is_gso(skb) && (iph->frag_off & htons(IP_DF)) && - mtu < ntohs(iph->tot_len)) { + if (iph->frag_off & htons(IP_DF) && + ((!skb_is_gso(skb) && skb->len > mtu) || + (skb_is_gso(skb) && !skb_gso_validate_network_len(skb, mtu)))) { netdev_dbg(dev, "packet too big, fragmentation needed\n"); - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, - htonl(mtu)); + icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, + htonl(mtu)); goto err_rt; } @@ -572,6 +573,9 @@ if (skb_cow_head(skb, dev->needed_headroom)) goto tx_err; + if (!pskb_inet_may_pull(skb)) + goto tx_err; + skb_reset_inner_headers(skb); /* PDP context lookups in gtp_build_skb_*() need rcu read-side lock. */ @@ -641,9 +645,16 @@ } static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize); -static void gtp_hashtable_free(struct gtp_dev *gtp); static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]); +static void gtp_destructor(struct net_device *dev) +{ + struct gtp_dev *gtp = netdev_priv(dev); + + kfree(gtp->addr_hash); + kfree(gtp->tid_hash); +} + static int gtp_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) @@ -657,45 +668,56 @@ gtp = netdev_priv(dev); - err = gtp_encap_enable(gtp, data); - if (err < 0) - return err; - - if (!data[IFLA_GTP_PDP_HASHSIZE]) + if (!data[IFLA_GTP_PDP_HASHSIZE]) { hashsize = 1024; - else + } else { hashsize = nla_get_u32(data[IFLA_GTP_PDP_HASHSIZE]); + if (!hashsize) + hashsize = 1024; + } err = gtp_hashtable_new(gtp, hashsize); if (err < 0) - goto out_encap; + return err; + + err = gtp_encap_enable(gtp, data); + if (err < 0) + goto out_hashtable; err = register_netdevice(dev); if (err < 0) { netdev_dbg(dev, "failed to register new netdev %d\n", err); - goto out_hashtable; + goto out_encap; } - gn = net_generic(dev_net(dev), gtp_net_id); - list_add_rcu(>p->list, &gn->gtp_dev_list); + gn = net_generic(src_net, gtp_net_id); + list_add(>p->list, &gn->gtp_dev_list); + dev->priv_destructor = gtp_destructor; netdev_dbg(dev, "registered new GTP interface\n"); return 0; -out_hashtable: - gtp_hashtable_free(gtp); out_encap: gtp_encap_disable(gtp); +out_hashtable: + kfree(gtp->addr_hash); + kfree(gtp->tid_hash); return err; } static void gtp_dellink(struct net_device *dev, struct list_head *head) { struct gtp_dev *gtp = netdev_priv(dev); + struct hlist_node *next; + struct pdp_ctx *pctx; + int i; + + for (i = 0; i < gtp->hash_size; i++) + hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid) + pdp_context_delete(pctx); - gtp_hashtable_free(gtp); - list_del_rcu(>p->list); + list_del(>p->list); unregister_netdevice_queue(dev, head); } @@ -751,12 +773,12 @@ int i; gtp->addr_hash = kmalloc_array(hsize, sizeof(struct hlist_head), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (gtp->addr_hash == NULL) return -ENOMEM; gtp->tid_hash = kmalloc_array(hsize, sizeof(struct hlist_head), - GFP_KERNEL); + GFP_KERNEL | __GFP_NOWARN); if (gtp->tid_hash == NULL) goto err1; @@ -772,20 +794,6 @@ return -ENOMEM; } -static void gtp_hashtable_free(struct gtp_dev *gtp) -{ - struct pdp_ctx *pctx; - int i; - - for (i = 0; i < gtp->hash_size; i++) - hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) - pdp_context_delete(pctx); - - synchronize_rcu(); - kfree(gtp->addr_hash); - kfree(gtp->tid_hash); -} - static struct sock *gtp_encap_enable_socket(int fd, int type, struct gtp_dev *gtp) { @@ -799,22 +807,24 @@ sock = sockfd_lookup(fd, &err); if (!sock) { pr_debug("gtp socket fd=%d not found\n", fd); - return NULL; + return ERR_PTR(err); } - if (sock->sk->sk_protocol != IPPROTO_UDP) { + sk = sock->sk; + if (sk->sk_protocol != IPPROTO_UDP || + sk->sk_type != SOCK_DGRAM || + (sk->sk_family != AF_INET && sk->sk_family != AF_INET6)) { pr_debug("socket fd=%d not UDP\n", fd); sk = ERR_PTR(-EINVAL); goto out_sock; } - lock_sock(sock->sk); - if (sock->sk->sk_user_data) { + lock_sock(sk); + if (sk->sk_user_data) { sk = ERR_PTR(-EBUSY); - goto out_sock; + goto out_rel_sock; } - sk = sock->sk; sock_hold(sk); tuncfg.sk_user_data = gtp; @@ -824,8 +834,9 @@ setup_udp_tunnel_sock(sock_net(sock->sk), sock, &tuncfg); -out_sock: +out_rel_sock: release_sock(sock->sk); +out_sock: sockfd_put(sock); return sk; } @@ -837,31 +848,32 @@ unsigned int role = GTP_ROLE_GGSN; if (data[IFLA_GTP_FD0]) { - u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]); + int fd0 = nla_get_u32(data[IFLA_GTP_FD0]); - sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp); - if (IS_ERR(sk0)) - return PTR_ERR(sk0); + if (fd0 >= 0) { + sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp); + if (IS_ERR(sk0)) + return PTR_ERR(sk0); + } } if (data[IFLA_GTP_FD1]) { - u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]); + int fd1 = nla_get_u32(data[IFLA_GTP_FD1]); - sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp); - if (IS_ERR(sk1u)) { - if (sk0) + if (fd1 >= 0) { + sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp); + if (IS_ERR(sk1u)) { gtp_encap_disable_sock(sk0); - return PTR_ERR(sk1u); + return PTR_ERR(sk1u); + } } } if (data[IFLA_GTP_ROLE]) { role = nla_get_u32(data[IFLA_GTP_ROLE]); if (role > GTP_ROLE_SGSN) { - if (sk0) - gtp_encap_disable_sock(sk0); - if (sk1u) - gtp_encap_disable_sock(sk1u); + gtp_encap_disable_sock(sk0); + gtp_encap_disable_sock(sk1u); return -EINVAL; } } @@ -926,24 +938,31 @@ } } -static int ipv4_pdp_add(struct gtp_dev *gtp, struct sock *sk, - struct genl_info *info) +static int gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk, + struct genl_info *info) { + struct pdp_ctx *pctx, *pctx_tid = NULL; struct net_device *dev = gtp->dev; u32 hash_ms, hash_tid = 0; - struct pdp_ctx *pctx; + unsigned int version; bool found = false; __be32 ms_addr; ms_addr = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]); hash_ms = ipv4_hashfn(ms_addr) % gtp->hash_size; + version = nla_get_u32(info->attrs[GTPA_VERSION]); - hlist_for_each_entry_rcu(pctx, >p->addr_hash[hash_ms], hlist_addr) { - if (pctx->ms_addr_ip4.s_addr == ms_addr) { - found = true; - break; - } - } + pctx = ipv4_pdp_find(gtp, ms_addr); + if (pctx) + found = true; + if (version == GTP_V0) + pctx_tid = gtp0_pdp_find(gtp, + nla_get_u64(info->attrs[GTPA_TID])); + else if (version == GTP_V1) + pctx_tid = gtp1_pdp_find(gtp, + nla_get_u32(info->attrs[GTPA_I_TEI])); + if (pctx_tid) + found = true; if (found) { if (info->nlhdr->nlmsg_flags & NLM_F_EXCL) @@ -951,6 +970,11 @@ if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE) return -EOPNOTSUPP; + if (pctx && pctx_tid) + return -EEXIST; + if (!pctx) + pctx = pctx_tid; + ipv4_pdp_fill(pctx, info); if (pctx->gtp_version == GTP_V0) @@ -1074,7 +1098,7 @@ goto out_unlock; } - err = ipv4_pdp_add(gtp, sk, info); + err = gtp_pdp_add(gtp, sk, info); out_unlock: rcu_read_unlock(); @@ -1155,16 +1179,17 @@ static struct genl_family gtp_genl_family; static int gtp_genl_fill_info(struct sk_buff *skb, u32 snd_portid, u32 snd_seq, - u32 type, struct pdp_ctx *pctx) + int flags, u32 type, struct pdp_ctx *pctx) { void *genlh; - genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, 0, + genlh = genlmsg_put(skb, snd_portid, snd_seq, >p_genl_family, flags, type); if (genlh == NULL) goto nlmsg_failure; if (nla_put_u32(skb, GTPA_VERSION, pctx->gtp_version) || + nla_put_u32(skb, GTPA_LINK, pctx->dev->ifindex) || nla_put_be32(skb, GTPA_PEER_ADDRESS, pctx->peer_addr_ip4.s_addr) || nla_put_be32(skb, GTPA_MS_ADDRESS, pctx->ms_addr_ip4.s_addr)) goto nla_put_failure; @@ -1213,8 +1238,8 @@ goto err_unlock; } - err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, - info->snd_seq, info->nlhdr->nlmsg_type, pctx); + err = gtp_genl_fill_info(skb2, NETLINK_CB(skb).portid, info->snd_seq, + 0, info->nlhdr->nlmsg_type, pctx); if (err < 0) goto err_unlock_free; @@ -1232,43 +1257,50 @@ struct netlink_callback *cb) { struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; + int i, j, bucket = cb->args[0], skip = cb->args[1]; struct net *net = sock_net(skb->sk); - struct gtp_net *gn = net_generic(net, gtp_net_id); - unsigned long tid = cb->args[1]; - int i, k = cb->args[0], ret; + struct net_device *dev; struct pdp_ctx *pctx; if (cb->args[4]) return 0; - list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { + rcu_read_lock(); + for_each_netdev_rcu(net, dev) { + if (dev->rtnl_link_ops != >p_link_ops) + continue; + + gtp = netdev_priv(dev); + if (last_gtp && last_gtp != gtp) continue; else last_gtp = NULL; - for (i = k; i < gtp->hash_size; i++) { - hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], hlist_tid) { - if (tid && tid != pctx->u.tid) - continue; - else - tid = 0; - - ret = gtp_genl_fill_info(skb, - NETLINK_CB(cb->skb).portid, - cb->nlh->nlmsg_seq, - cb->nlh->nlmsg_type, pctx); - if (ret < 0) { + for (i = bucket; i < gtp->hash_size; i++) { + j = 0; + hlist_for_each_entry_rcu(pctx, >p->tid_hash[i], + hlist_tid) { + if (j >= skip && + gtp_genl_fill_info(skb, + NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + NLM_F_MULTI, + cb->nlh->nlmsg_type, pctx)) { cb->args[0] = i; - cb->args[1] = pctx->u.tid; + cb->args[1] = j; cb->args[2] = (unsigned long)gtp; goto out; } + j++; } + skip = 0; } + bucket = 0; } cb->args[4] = 1; out: + rcu_read_unlock(); return skb->len; } @@ -1326,23 +1358,23 @@ return 0; } -static void __net_exit gtp_net_exit(struct net *net) +static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + struct list_head *dev_to_kill) { - struct gtp_net *gn = net_generic(net, gtp_net_id); - struct gtp_dev *gtp; - LIST_HEAD(list); + struct net *net; - rtnl_lock(); - list_for_each_entry(gtp, &gn->gtp_dev_list, list) - gtp_dellink(gtp->dev, &list); + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp, *gtp_next; - unregister_netdevice_many(&list); - rtnl_unlock(); + list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); + } } static struct pernet_operations gtp_net_ops = { .init = gtp_net_init, - .exit = gtp_net_exit, + .exit_batch_rtnl = gtp_net_exit_batch_rtnl, .id = >p_net_id, .size = sizeof(struct gtp_net), }; @@ -1353,26 +1385,26 @@ get_random_bytes(>p_h_initval, sizeof(gtp_h_initval)); - err = rtnl_link_register(>p_link_ops); + err = register_pernet_subsys(>p_net_ops); if (err < 0) goto error_out; - err = genl_register_family(>p_genl_family); + err = rtnl_link_register(>p_link_ops); if (err < 0) - goto unreg_rtnl_link; + goto unreg_pernet_subsys; - err = register_pernet_subsys(>p_net_ops); + err = genl_register_family(>p_genl_family); if (err < 0) - goto unreg_genl_family; + goto unreg_rtnl_link; pr_info("GTP module loaded (pdp ctx size %zd bytes)\n", sizeof(struct pdp_ctx)); return 0; -unreg_genl_family: - genl_unregister_family(>p_genl_family); unreg_rtnl_link: rtnl_link_unregister(>p_link_ops); +unreg_pernet_subsys: + unregister_pernet_subsys(>p_net_ops); error_out: pr_err("error loading GTP module loaded\n"); return err; --- linux-oracle-5.4.0.orig/drivers/net/hamradio/6pack.c +++ linux-oracle-5.4.0/drivers/net/hamradio/6pack.c @@ -68,9 +68,9 @@ #define SIXP_DAMA_OFF 0 /* default level 2 parameters */ -#define SIXP_TXDELAY (HZ/4) /* in 1 s */ +#define SIXP_TXDELAY 25 /* 250 ms */ #define SIXP_PERSIST 50 /* in 256ths */ -#define SIXP_SLOTTIME (HZ/10) /* in 1 s */ +#define SIXP_SLOTTIME 10 /* 100 ms */ #define SIXP_INIT_RESYNC_TIMEOUT (3*HZ/2) /* in 1 s */ #define SIXP_RESYNC_TIMEOUT 5*HZ /* in 1 s */ @@ -311,7 +311,6 @@ { /* Finish setting up the DEVICE info. */ dev->netdev_ops = &sp_netdev_ops; - dev->needs_free_netdev = true; dev->mtu = SIXP_MTU; dev->hard_header_len = AX25_MAX_HEADER_LEN; dev->header_ops = &ax25_header_ops; @@ -654,10 +653,10 @@ { struct sixpack *sp; - write_lock_bh(&disc_data_lock); + write_lock_irq(&disc_data_lock); sp = tty->disc_data; tty->disc_data = NULL; - write_unlock_bh(&disc_data_lock); + write_unlock_irq(&disc_data_lock); if (!sp) return; @@ -674,14 +673,16 @@ */ netif_stop_queue(sp->dev); + unregister_netdev(sp->dev); + del_timer_sync(&sp->tx_t); del_timer_sync(&sp->resync_t); - /* Free all 6pack frame buffers. */ + /* Free all 6pack frame buffers after unreg. */ kfree(sp->rbuff); kfree(sp->xbuff); - unregister_netdev(sp->dev); + free_netdev(sp->dev); } /* Perform I/O control on an active 6pack channel. */ @@ -839,6 +840,12 @@ return; } + if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) { + pr_err("6pack: cooked buffer overrun, data loss\n"); + sp->rx_count = 0; + return; + } + buf = sp->raw_buf; sp->cooked_buf[sp->rx_count_cooked++] = buf[0] | ((buf[1] << 2) & 0xc0); --- linux-oracle-5.4.0.orig/drivers/net/hamradio/baycom_epp.c +++ linux-oracle-5.4.0/drivers/net/hamradio/baycom_epp.c @@ -758,7 +758,7 @@ * ===================== network driver interface ========================= */ -static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t baycom_send_packet(struct sk_buff *skb, struct net_device *dev) { struct baycom_state *bc = netdev_priv(dev); --- linux-oracle-5.4.0.orig/drivers/net/hamradio/bpqether.c +++ linux-oracle-5.4.0/drivers/net/hamradio/bpqether.c @@ -127,7 +127,8 @@ { struct bpqdev *bpq; - list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) { + list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list, + lockdep_rtnl_is_held()) { if (bpq->ethdev == dev) return bpq->axdev; } @@ -510,7 +511,7 @@ if (!net_eq(dev_net(dev), &init_net)) return NOTIFY_DONE; - if (!dev_is_ethdev(dev)) + if (!dev_is_ethdev(dev) && !bpq_get_ax25_dev(dev)) return NOTIFY_DONE; switch (event) { --- linux-oracle-5.4.0.orig/drivers/net/hamradio/mkiss.c +++ linux-oracle-5.4.0/drivers/net/hamradio/mkiss.c @@ -31,6 +31,8 @@ #define AX_MTU 236 +/* some arch define END as assembly function ending, just undef it */ +#undef END /* SLIP/KISS protocol characters. */ #define END 0300 /* indicates end of frame */ #define ESC 0333 /* indicates byte stuffing */ @@ -773,10 +775,10 @@ { struct mkiss *ax; - write_lock_bh(&disc_data_lock); + write_lock_irq(&disc_data_lock); ax = tty->disc_data; tty->disc_data = NULL; - write_unlock_bh(&disc_data_lock); + write_unlock_irq(&disc_data_lock); if (!ax) return; @@ -793,13 +795,15 @@ */ netif_stop_queue(ax->dev); - /* Free all AX25 frame buffers. */ + unregister_netdev(ax->dev); + + /* Free all AX25 frame buffers after unreg. */ kfree(ax->rbuff); kfree(ax->xbuff); ax->tty = NULL; - unregister_netdev(ax->dev); + free_netdev(ax->dev); } /* Perform I/O control on an active ax25 channel. */ --- linux-oracle-5.4.0.orig/drivers/net/hamradio/scc.c +++ linux-oracle-5.4.0/drivers/net/hamradio/scc.c @@ -300,12 +300,12 @@ spin_lock_irqsave(&scc->lock, flags); if (scc->tx_buff != NULL) { - dev_kfree_skb(scc->tx_buff); + dev_kfree_skb_irq(scc->tx_buff); scc->tx_buff = NULL; } while (!skb_queue_empty(&scc->tx_queue)) - dev_kfree_skb(skb_dequeue(&scc->tx_queue)); + dev_kfree_skb_irq(skb_dequeue(&scc->tx_queue)); spin_unlock_irqrestore(&scc->lock, flags); } @@ -1667,7 +1667,7 @@ if (skb_queue_len(&scc->tx_queue) > scc->dev->tx_queue_len) { struct sk_buff *skb_del; skb_del = skb_dequeue(&scc->tx_queue); - dev_kfree_skb(skb_del); + dev_kfree_skb_irq(skb_del); } skb_queue_tail(&scc->tx_queue, skb); netif_trans_update(dev); --- linux-oracle-5.4.0.orig/drivers/net/hamradio/yam.c +++ linux-oracle-5.4.0/drivers/net/hamradio/yam.c @@ -951,9 +951,7 @@ sizeof(struct yamdrv_ioctl_mcs)); if (IS_ERR(ym)) return PTR_ERR(ym); - if (ym->cmd != SIOCYAMSMCS) - return -EINVAL; - if (ym->bitrate > YAM_MAXBITRATE) { + if (ym->cmd != SIOCYAMSMCS || ym->bitrate > YAM_MAXBITRATE) { kfree(ym); return -EINVAL; } @@ -1133,6 +1131,7 @@ err = register_netdev(dev); if (err) { printk(KERN_WARNING "yam: cannot register net device %s\n", dev->name); + free_netdev(dev); goto error; } yam_devs[i] = dev; --- linux-oracle-5.4.0.orig/drivers/net/hippi/rrunner.c +++ linux-oracle-5.4.0/drivers/net/hippi/rrunner.c @@ -1242,7 +1242,7 @@ rrpriv->info = NULL; } if (rrpriv->rx_ctrl) { - pci_free_consistent(pdev, sizeof(struct ring_ctrl), + pci_free_consistent(pdev, 256 * sizeof(struct ring_ctrl), rrpriv->rx_ctrl, rrpriv->rx_ctrl_dma); rrpriv->rx_ctrl = NULL; } @@ -1346,7 +1346,9 @@ rrpriv->fw_running = 0; + spin_unlock_irqrestore(&rrpriv->lock, flags); del_timer_sync(&rrpriv->timer); + spin_lock_irqsave(&rrpriv->lock, flags); writel(0, ®s->TxPi); writel(0, ®s->IpRxPi); --- linux-oracle-5.4.0.orig/drivers/net/hyperv/Kconfig +++ linux-oracle-5.4.0/drivers/net/hyperv/Kconfig @@ -3,5 +3,6 @@ tristate "Microsoft Hyper-V virtual network driver" depends on HYPERV select UCS2_STRING + select NLS help Select this option to enable the Hyper-V virtual network driver. --- linux-oracle-5.4.0.orig/drivers/net/hyperv/hyperv_net.h +++ linux-oracle-5.4.0/drivers/net/hyperv/hyperv_net.h @@ -169,7 +169,6 @@ u8 hw_mac_adr[ETH_ALEN]; u8 rss_key[NETVSC_HASH_KEYLEN]; - u16 rx_table[ITAB_NUM]; }; @@ -880,6 +879,7 @@ unsigned long rx_no_memory; unsigned long stop_queue; unsigned long wake_queue; + unsigned long vlan_error; }; struct netvsc_ethtool_pcpu_stats { @@ -938,6 +938,8 @@ u32 tx_table[VRSS_SEND_TAB_SIZE]; + u16 rx_table[ITAB_NUM]; + /* Ethtool settings */ u8 duplex; u32 speed; @@ -953,6 +955,9 @@ u32 vf_alloc; /* Serial number of the VF to team with */ u32 vf_serial; + + /* completion variable to confirm vf association */ + struct completion vf_add; }; /* Per channel data */ --- linux-oracle-5.4.0.orig/drivers/net/hyperv/netvsc.c +++ linux-oracle-5.4.0/drivers/net/hyperv/netvsc.c @@ -99,7 +99,7 @@ init_waitqueue_head(&net_device->wait_drain); net_device->destroy = false; - net_device->tx_disable = false; + net_device->tx_disable = true; net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; @@ -1223,6 +1223,10 @@ net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated; net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial; + + if (net_device_ctx->vf_alloc) + complete(&net_device_ctx->vf_add); + netdev_info(ndev, "VF slot %u %s\n", net_device_ctx->vf_serial, net_device_ctx->vf_alloc ? "added" : "removed"); --- linux-oracle-5.4.0.orig/drivers/net/hyperv/netvsc_drv.c +++ linux-oracle-5.4.0/drivers/net/hyperv/netvsc_drv.c @@ -43,6 +43,10 @@ #define LINKCHANGE_INT (2 * HZ) #define VF_TAKEOVER_INT (HZ / 10) +/* Macros to define the context of vf registration */ +#define VF_REG_IN_PROBE 1 +#define VF_REG_IN_NOTIFIER 2 + static unsigned int ring_size __ro_after_init = 128; module_param(ring_size, uint, 0444); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); @@ -285,9 +289,9 @@ else if (flow.basic.n_proto == htons(ETH_P_IPV6)) hash = jhash2((u32 *)&flow.addrs.v6addrs, 8, hashrnd); else - hash = 0; + return 0; - skb_set_hash(skb, hash, PKT_HASH_TYPE_L3); + __skb_set_sw_hash(skb, hash, false); } return hash; @@ -366,7 +370,7 @@ } rcu_read_unlock(); - while (unlikely(txq >= ndev->real_num_tx_queues)) + while (txq >= ndev->real_num_tx_queues) txq -= ndev->real_num_tx_queues; return txq; @@ -501,7 +505,7 @@ int rc; skb->dev = vf_netdev; - skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; + skb_record_rx_queue(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); rc = dev_queue_xmit(skb); if (likely(rc == NET_XMIT_SUCCESS || rc == NET_XMIT_CN)) { @@ -531,12 +535,13 @@ u32 hash; struct hv_page_buffer pb[MAX_PAGE_BUFFER_COUNT]; - /* if VF is present and up then redirect packets - * already called with rcu_read_lock_bh + /* If VF is present and up then redirect packets to it. + * Skip the VF if it is marked down or has no carrier. + * If netpoll is in uses, then VF can not be used either. */ vf_netdev = rcu_dereference_bh(net_device_ctx->vf_netdev); if (vf_netdev && netif_running(vf_netdev) && - !netpoll_tx_running(net)) + netif_carrier_ok(vf_netdev) && !netpoll_tx_running(net)) return netvsc_vf_xmit(net, vf_netdev, skb); /* We will atmost need two pages to describe the rndis @@ -604,6 +609,29 @@ *hash_info = hash; } + /* When using AF_PACKET we need to drop VLAN header from + * the frame and update the SKB to allow the HOST OS + * to transmit the 802.1Q packet + */ + if (skb->protocol == htons(ETH_P_8021Q)) { + u16 vlan_tci; + + skb_reset_mac_header(skb); + if (eth_type_vlan(eth_hdr(skb)->h_proto)) { + if (unlikely(__skb_vlan_pop(skb, &vlan_tci) != 0)) { + ++net_device_ctx->eth_stats.vlan_error; + goto drop; + } + + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); + /* Update the NDIS header pkt lengths */ + packet->total_data_buflen -= VLAN_HLEN; + packet->total_bytes -= VLAN_HLEN; + rndis_msg->msg_len = packet->total_data_buflen; + rndis_msg->msg.pkt.data_len = packet->total_data_buflen; + } + } + if (skb_vlan_tag_present(skb)) { struct ndis_pkt_8021q_info *vlan; @@ -795,8 +823,7 @@ skb->protocol == htons(ETH_P_IP)) netvsc_comp_ipcsum(skb); - /* Do L4 checksum offload if enabled and present. - */ + /* Do L4 checksum offload if enabled and present. */ if (csum_info && (net->features & NETIF_F_RXCSUM)) { if (csum_info->receive.tcp_checksum_succeeded || csum_info->receive.udp_checksum_succeeded) @@ -974,6 +1001,7 @@ } /* In any case device is now ready */ + nvdev->tx_disable = false; netif_device_attach(ndev); /* Note: enable and attach happen when sub-channels setup */ @@ -1344,6 +1372,7 @@ { "rx_no_memory", offsetof(struct netvsc_ethtool_stats, rx_no_memory) }, { "stop_queue", offsetof(struct netvsc_ethtool_stats, stop_queue) }, { "wake_queue", offsetof(struct netvsc_ethtool_stats, wake_queue) }, + { "vlan_error", offsetof(struct netvsc_ethtool_stats, vlan_error) }, }, pcpu_stats[] = { { "cpu%u_rx_packets", offsetof(struct netvsc_ethtool_pcpu_stats, rx_packets) }, @@ -1444,6 +1473,9 @@ pcpu_sum = kvmalloc_array(num_possible_cpus(), sizeof(struct netvsc_ethtool_pcpu_stats), GFP_KERNEL); + if (!pcpu_sum) + return; + netvsc_get_pcpu_stats(dev, pcpu_sum); for_each_present_cpu(cpu) { struct netvsc_ethtool_pcpu_stats *this_sum = &pcpu_sum[cpu]; @@ -1659,7 +1691,7 @@ rndis_dev = ndev->extension; if (indir) { for (i = 0; i < ITAB_NUM; i++) - indir[i] = rndis_dev->rx_table[i]; + indir[i] = ndc->rx_table[i]; } if (key) @@ -1689,7 +1721,7 @@ return -EINVAL; for (i = 0; i < ITAB_NUM; i++) - rndis_dev->rx_table[i] = indir[i]; + ndc->rx_table[i] = indir[i]; } if (!key) { @@ -2033,7 +2065,7 @@ } static int netvsc_vf_join(struct net_device *vf_netdev, - struct net_device *ndev) + struct net_device *ndev, int context) { struct net_device_context *ndev_ctx = netdev_priv(ndev); int ret; @@ -2056,10 +2088,11 @@ goto upper_link_failed; } - /* set slave flag before open to prevent IPv6 addrconf */ - vf_netdev->flags |= IFF_SLAVE; - - schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); + /* If this registration is called from probe context vf_takeover + * is taken care of later in probe itself. + */ + if (context == VF_REG_IN_NOTIFIER) + schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); @@ -2129,6 +2162,7 @@ { struct device *parent = vf_netdev->dev.parent; struct net_device_context *ndev_ctx; + struct net_device *ndev; struct pci_dev *pdev; u32 serial; @@ -2151,8 +2185,31 @@ if (!ndev_ctx->vf_alloc) continue; - if (ndev_ctx->vf_serial == serial) - return hv_get_drvdata(ndev_ctx->device_ctx); + if (ndev_ctx->vf_serial != serial) + continue; + + ndev = hv_get_drvdata(ndev_ctx->device_ctx); + if (ndev->addr_len != vf_netdev->addr_len || + memcmp(ndev->perm_addr, vf_netdev->perm_addr, + ndev->addr_len) != 0) + continue; + + return ndev; + + } + + /* Fallback path to check synthetic vf with help of mac addr. + * Because this function can be called before vf_netdev is + * initialized (NETDEV_POST_INIT) when its perm_addr has not been copied + * from dev_addr, also try to match to its dev_addr. + * Note: On Hyper-V and Azure, it's not possible to set a MAC address + * on a VF that matches to the MAC of a unrelated NETVSC device. + */ + list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { + ndev = hv_get_drvdata(ndev_ctx->device_ctx); + if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr) || + ether_addr_equal(vf_netdev->dev_addr, ndev->perm_addr)) + return ndev; } netdev_notice(vf_netdev, @@ -2160,7 +2217,20 @@ return NULL; } -static int netvsc_register_vf(struct net_device *vf_netdev) +static int netvsc_prepare_bonding(struct net_device *vf_netdev) +{ + struct net_device *ndev; + + ndev = get_netvsc_byslot(vf_netdev); + if (!ndev) + return NOTIFY_DONE; + + /* set slave flag before open to prevent IPv6 addrconf */ + vf_netdev->flags |= IFF_SLAVE; + return NOTIFY_DONE; +} + +static int netvsc_register_vf(struct net_device *vf_netdev, int context) { struct net_device_context *net_device_ctx; struct netvsc_device *netvsc_dev; @@ -2199,7 +2269,7 @@ netdev_info(ndev, "VF registering: %s\n", vf_netdev->name); - if (netvsc_vf_join(vf_netdev, ndev) != 0) + if (netvsc_vf_join(vf_netdev, ndev, context) != 0) return NOTIFY_DONE; dev_hold(vf_netdev); @@ -2228,6 +2298,11 @@ if (!netvsc_dev) return NOTIFY_DONE; + if (vf_is_up && !net_device_ctx->vf_alloc) { + netdev_info(ndev, "Waiting for the VF association from host\n"); + wait_for_completion(&net_device_ctx->vf_add); + } + netvsc_switch_datapath(ndev, vf_is_up); netdev_info(ndev, "Data path switched %s VF: %s\n", vf_is_up ? "to" : "from", vf_netdev->name); @@ -2249,6 +2324,7 @@ netdev_info(ndev, "VF unregistering: %s\n", vf_netdev->name); + reinit_completion(&net_device_ctx->vf_add); netdev_rx_handler_unregister(vf_netdev); netdev_upper_dev_unlink(vf_netdev, ndev); RCU_INIT_POINTER(net_device_ctx->vf_netdev, NULL); @@ -2257,10 +2333,31 @@ return NOTIFY_OK; } +static int check_dev_is_matching_vf(struct net_device *event_ndev) +{ + /* Skip NetVSC interfaces */ + if (event_ndev->netdev_ops == &device_ops) + return -ENODEV; + + /* Avoid non-Ethernet type devices */ + if (event_ndev->type != ARPHRD_ETHER) + return -ENODEV; + + /* Avoid Vlan dev with same MAC registering as VF */ + if (is_vlan_dev(event_ndev)) + return -ENODEV; + + /* Avoid Bonding master dev with same MAC registering as VF */ + if (netif_is_bond_master(event_ndev)) + return -ENODEV; + + return 0; +} + static int netvsc_probe(struct hv_device *dev, const struct hv_vmbus_device_id *dev_id) { - struct net_device *net = NULL; + struct net_device *net = NULL, *vf_netdev; struct net_device_context *net_device_ctx; struct netvsc_device_info *device_info = NULL; struct netvsc_device *nvdev; @@ -2286,6 +2383,7 @@ INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_link_change); + init_completion(&net_device_ctx->vf_add); spin_lock_init(&net_device_ctx->lock); INIT_LIST_HEAD(&net_device_ctx->reconfig_events); INIT_DELAYED_WORK(&net_device_ctx->vf_takeover, netvsc_vf_setup); @@ -2351,6 +2449,8 @@ else net->max_mtu = ETH_DATA_LEN; + nvdev->tx_disable = false; + ret = register_netdevice(net); if (ret != 0) { pr_err("Unable to register netdev.\n"); @@ -2358,6 +2458,30 @@ } list_add(&net_device_ctx->list, &netvsc_dev_list); + + /* When the hv_netvsc driver is unloaded and reloaded, the + * NET_DEVICE_REGISTER for the vf device is replayed before probe + * is complete. This is because register_netdevice_notifier() gets + * registered before vmbus_driver_register() so that callback func + * is set before probe and we don't miss events like NETDEV_POST_INIT + * So, in this section we try to register the matching vf device that + * is present as a netdevice, knowing that its register call is not + * processed in the netvsc_netdev_notifier(as probing is progress and + * get_netvsc_byslot fails). + */ + for_each_netdev(dev_net(net), vf_netdev) { + ret = check_dev_is_matching_vf(vf_netdev); + if (ret != 0) + continue; + + if (net != get_netvsc_byslot(vf_netdev)) + continue; + + netvsc_prepare_bonding(vf_netdev); + netvsc_register_vf(vf_netdev, VF_REG_IN_PROBE); + __netvsc_vf_setup(net, vf_netdev); + break; + } rtnl_unlock(); kfree(device_info); @@ -2440,6 +2564,31 @@ }, }; +/* Set VF's namespace same as the synthetic NIC */ +static void netvsc_event_set_vf_ns(struct net_device *ndev) +{ + struct net_device_context *ndev_ctx = netdev_priv(ndev); + struct net_device *vf_netdev; + int ret; + + vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); + if (!vf_netdev) + return; + + if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) { + ret = dev_change_net_namespace(vf_netdev, dev_net(ndev), + "eth%d"); + if (ret) + netdev_err(vf_netdev, + "Cannot move to same namespace as %s: %d\n", + ndev->name, ret); + else + netdev_info(vf_netdev, + "Moved VF to namespace with: %s\n", + ndev->name); + } +} + /* * On Hyper-V, every VF interface is matched with a corresponding * synthetic interface. The synthetic interface is presented first @@ -2450,27 +2599,22 @@ unsigned long event, void *ptr) { struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); + int ret = 0; - /* Skip our own events */ - if (event_dev->netdev_ops == &device_ops) - return NOTIFY_DONE; - - /* Avoid non-Ethernet type devices */ - if (event_dev->type != ARPHRD_ETHER) - return NOTIFY_DONE; - - /* Avoid Vlan dev with same MAC registering as VF */ - if (is_vlan_dev(event_dev)) + if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) { + netvsc_event_set_vf_ns(event_dev); return NOTIFY_DONE; + } - /* Avoid Bonding master dev with same MAC registering as VF */ - if ((event_dev->priv_flags & IFF_BONDING) && - (event_dev->flags & IFF_MASTER)) + ret = check_dev_is_matching_vf(event_dev); + if (ret != 0) return NOTIFY_DONE; switch (event) { + case NETDEV_POST_INIT: + return netvsc_prepare_bonding(event_dev); case NETDEV_REGISTER: - return netvsc_register_vf(event_dev); + return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER); case NETDEV_UNREGISTER: return netvsc_unregister_vf(event_dev); case NETDEV_UP: @@ -2502,12 +2646,17 @@ } netvsc_ring_bytes = ring_size * PAGE_SIZE; + register_netdevice_notifier(&netvsc_netdev_notifier); + ret = vmbus_driver_register(&netvsc_drv); if (ret) - return ret; + goto err_vmbus_reg; - register_netdevice_notifier(&netvsc_netdev_notifier); return 0; + +err_vmbus_reg: + unregister_netdevice_notifier(&netvsc_netdev_notifier); + return ret; } MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/net/hyperv/rndis_filter.c +++ linux-oracle-5.4.0/drivers/net/hyperv/rndis_filter.c @@ -767,6 +767,7 @@ const u8 *rss_key, u16 flag) { struct net_device *ndev = rdev->ndev; + struct net_device_context *ndc = netdev_priv(ndev); struct rndis_request *request; struct rndis_set_request *set; struct rndis_set_complete *set_complete; @@ -806,7 +807,7 @@ /* Set indirection table entries */ itab = (u32 *)(rssp + 1); for (i = 0; i < ITAB_NUM; i++) - itab[i] = rdev->rx_table[i]; + itab[i] = ndc->rx_table[i]; /* Set hask key values */ keyp = (u8 *)((unsigned long)rssp + rssp->hashkey_offset); @@ -1165,6 +1166,9 @@ wait_event(nvdev->subchan_open, atomic_read(&nvdev->open_chn) == nvdev->num_chn); + for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) + ndev_ctx->tx_table[i] = i % nvdev->num_chn; + /* ignore failures from setting rss parameters, still have channels */ if (dev_info) rndis_filter_set_rss_param(rdev, dev_info->rss_key); @@ -1174,9 +1178,6 @@ netif_set_real_num_tx_queues(ndev, nvdev->num_chn); netif_set_real_num_rx_queues(ndev, nvdev->num_chn); - for (i = 0; i < VRSS_SEND_TAB_SIZE; i++) - ndev_ctx->tx_table[i] = i % nvdev->num_chn; - return 0; } @@ -1305,6 +1306,7 @@ struct netvsc_device_info *device_info) { struct net_device *net = hv_get_drvdata(dev); + struct net_device_context *ndc = netdev_priv(net); struct netvsc_device *net_device; struct rndis_device *rndis_device; struct ndis_recv_scale_cap rsscap; @@ -1391,9 +1393,11 @@ /* We will use the given number of channels if available. */ net_device->num_chn = min(net_device->max_chn, device_info->num_chn); - for (i = 0; i < ITAB_NUM; i++) - rndis_device->rx_table[i] = ethtool_rxfh_indir_default( + if (!netif_is_rxfh_configured(net)) { + for (i = 0; i < ITAB_NUM; i++) + ndc->rx_table[i] = ethtool_rxfh_indir_default( i, net_device->num_chn); + } atomic_set(&net_device->open_chn, 1); vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open); @@ -1432,8 +1436,6 @@ /* Halt and release the rndis device */ rndis_filter_halt_device(net_dev, rndis_dev); - net_dev->extension = NULL; - netvsc_device_remove(dev); } --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/Kconfig +++ linux-oracle-5.4.0/drivers/net/ieee802154/Kconfig @@ -74,9 +74,9 @@ The module will be called 'atusb'. config IEEE802154_ADF7242 - tristate "ADF7242 transceiver driver" - depends on IEEE802154_DRIVERS && MAC802154 - depends on SPI + tristate "ADF7242 transceiver driver" + depends on IEEE802154_DRIVERS && MAC802154 + depends on SPI ---help--- Say Y here to enable the ADF7242 SPI 802.15.4 wireless controller. @@ -107,9 +107,10 @@ management entities. config IEEE802154_MCR20A - tristate "MCR20A transceiver driver" - depends on IEEE802154_DRIVERS && MAC802154 - depends on SPI + tristate "MCR20A transceiver driver" + select REGMAP_SPI + depends on IEEE802154_DRIVERS && MAC802154 + depends on SPI ---help--- Say Y here to enable the MCR20A SPI 802.15.4 wireless controller. --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/adf7242.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/adf7242.c @@ -882,7 +882,9 @@ int ret; u8 lqi, len_u8, *data; - adf7242_read_reg(lp, 0, &len_u8); + ret = adf7242_read_reg(lp, 0, &len_u8); + if (ret) + return ret; len = len_u8; @@ -1160,9 +1162,10 @@ static void adf7242_debugfs_init(struct adf7242_local *lp) { - char debugfs_dir_name[DNAME_INLINE_LEN + 1] = "adf7242-"; + char debugfs_dir_name[DNAME_INLINE_LEN + 1]; - strncat(debugfs_dir_name, dev_name(&lp->spi->dev), DNAME_INLINE_LEN); + snprintf(debugfs_dir_name, sizeof(debugfs_dir_name), + "adf7242-%s", dev_name(&lp->spi->dev)); lp->debugfs_root = debugfs_create_dir(debugfs_dir_name, NULL); @@ -1262,7 +1265,7 @@ WQ_MEM_RECLAIM); if (unlikely(!lp->wqueue)) { ret = -ENOMEM; - goto err_hw_init; + goto err_alloc_wq; } ret = adf7242_hw_init(lp); @@ -1294,6 +1297,8 @@ return ret; err_hw_init: + destroy_workqueue(lp->wqueue); +err_alloc_wq: mutex_destroy(&lp->bmux); ieee802154_free_hw(lp->hw); @@ -1306,10 +1311,11 @@ debugfs_remove_recursive(lp->debugfs_root); + ieee802154_unregister_hw(lp->hw); + cancel_delayed_work_sync(&lp->work); destroy_workqueue(lp->wqueue); - ieee802154_unregister_hw(lp->hw); mutex_destroy(&lp->bmux); ieee802154_free_hw(lp->hw); --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/at86rf230.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/at86rf230.c @@ -100,6 +100,7 @@ unsigned long cal_timeout; bool is_tx; bool is_tx_from_off; + bool was_tx; u8 tx_retry; struct sk_buff *tx_skb; struct at86rf230_state_change tx; @@ -343,7 +344,11 @@ if (ctx->free) kfree(ctx); - ieee802154_wake_queue(lp->hw); + if (lp->was_tx) { + lp->was_tx = 0; + dev_kfree_skb_any(lp->tx_skb); + ieee802154_wake_queue(lp->hw); + } } static void @@ -352,7 +357,11 @@ struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - lp->is_tx = 0; + if (lp->is_tx) { + lp->was_tx = 1; + lp->is_tx = 0; + } + at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, at86rf230_async_error_recover_complete); } --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/atusb.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/atusb.c @@ -93,7 +93,9 @@ ret = usb_control_msg(usb_dev, pipe, request, requesttype, value, index, data, size, timeout); - if (ret < 0) { + if (ret < size) { + ret = ret < 0 ? ret : -ENODATA; + atusb->err = ret; dev_err(&usb_dev->dev, "%s: req 0x%02x val 0x%x idx 0x%x, error %d\n", @@ -365,6 +367,7 @@ return -ENOMEM; } usb_anchor_urb(urb, &atusb->idle_urbs); + usb_free_urb(urb); n--; } return 0; @@ -860,9 +863,9 @@ if (!build) return -ENOMEM; - ret = atusb_control_msg(atusb, usb_rcvctrlpipe(usb_dev, 0), - ATUSB_BUILD, ATUSB_REQ_FROM_DEV, 0, 0, - build, ATUSB_BUILD_SIZE, 1000); + /* We cannot call atusb_control_msg() here, since this request may read various length data */ + ret = usb_control_msg(atusb->usb_dev, usb_rcvctrlpipe(usb_dev, 0), ATUSB_BUILD, + ATUSB_REQ_FROM_DEV, 0, 0, build, ATUSB_BUILD_SIZE, 1000); if (ret >= 0) { build[ret] = 0; dev_info(&usb_dev->dev, "Firmware: build %s\n", build); --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/ca8210.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/ca8210.c @@ -926,7 +926,7 @@ dev_dbg(&spi->dev, "%s called\n", __func__); - cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC); + cas_ctl = kzalloc(sizeof(*cas_ctl), GFP_ATOMIC); if (!cas_ctl) return -ENOMEM; @@ -1770,6 +1770,7 @@ status ); if (status != MAC_TRANSACTION_OVERFLOW) { + dev_kfree_skb_any(priv->tx_skb); ieee802154_wake_queue(priv->hw); return 0; } @@ -1943,10 +1944,9 @@ struct ca8210_priv *priv ) { - int status; struct ieee802154_hdr header = { }; struct secspec secspec; - unsigned int mac_len; + int mac_len, status; dev_dbg(&priv->spi->dev, "%s called\n", __func__); @@ -1954,6 +1954,8 @@ * packet */ mac_len = ieee802154_hdr_peek_addrs(skb, &header); + if (mac_len < 0) + return mac_len; secspec.security_level = header.sec.level; secspec.key_id_mode = header.sec.key_id_mode; @@ -2780,7 +2782,6 @@ struct device_node *np = spi->dev.of_node; struct ca8210_priv *priv = spi_get_drvdata(spi); struct ca8210_platform_data *pdata = spi->dev.platform_data; - int ret = 0; if (!np) return -EFAULT; @@ -2797,18 +2798,8 @@ dev_crit(&spi->dev, "Failed to register external clk\n"); return PTR_ERR(priv->clk); } - ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk); - if (ret) { - clk_unregister(priv->clk); - dev_crit( - &spi->dev, - "Failed to register external clock as clock provider\n" - ); - } else { - dev_info(&spi->dev, "External clock set as clock provider\n"); - } - return ret; + return of_clk_add_provider(np, of_clk_src_simple_get, priv->clk); } /** @@ -2820,8 +2811,8 @@ { struct ca8210_priv *priv = spi_get_drvdata(spi); - if (!priv->clk) - return + if (IS_ERR_OR_NULL(priv->clk)) + return; of_clk_del_provider(spi->dev.of_node); clk_unregister(priv->clk); @@ -2924,6 +2915,7 @@ ); if (!priv->irq_workqueue) { dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n"); + destroy_workqueue(priv->mlme_workqueue); return -ENOMEM; } @@ -2974,8 +2966,8 @@ ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND; ca8210_hw->phy->cca_ed_level = -9800; ca8210_hw->phy->symbol_duration = 16; - ca8210_hw->phy->lifs_period = 40; - ca8210_hw->phy->sifs_period = 12; + ca8210_hw->phy->lifs_period = 40 * ca8210_hw->phy->symbol_duration; + ca8210_hw->phy->sifs_period = 12 * ca8210_hw->phy->symbol_duration; ca8210_hw->flags = IEEE802154_HW_AFILT | IEEE802154_HW_OMIT_CKSUM | @@ -3132,7 +3124,11 @@ spi_set_drvdata(priv->spi, priv); if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) { cascoda_api_upstream = ca8210_test_int_driver_write; - ca8210_test_interface_init(priv); + ret = ca8210_test_interface_init(priv); + if (ret) { + dev_crit(&spi_device->dev, "ca8210_test_interface_init failed\n"); + goto error; + } } else { cascoda_api_upstream = NULL; } --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/cc2520.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/cc2520.c @@ -507,6 +507,7 @@ goto err_tx; if (status & CC2520_STATUS_TX_UNDERFLOW) { + rc = -EINVAL; dev_err(&priv->spi->dev, "cc2520 tx underflow exception\n"); goto err_tx; } @@ -972,7 +973,7 @@ if (timeout-- <= 0) { dev_err(&priv->spi->dev, "oscillator start failed!\n"); - return ret; + return -ETIMEDOUT; } udelay(1); } while (!(status & CC2520_STATUS_XOSC32M_STABLE)); --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/mac802154_hwsim.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/mac802154_hwsim.c @@ -418,7 +418,7 @@ struct hwsim_edge *e; u32 v0, v1; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; @@ -480,7 +480,7 @@ struct hwsim_edge *e; u32 v0, v1; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; @@ -522,20 +522,20 @@ static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info) { struct nlattr *edge_attrs[MAC802154_HWSIM_EDGE_ATTR_MAX + 1]; - struct hwsim_edge_info *einfo; + struct hwsim_edge_info *einfo, *einfo_old; struct hwsim_phy *phy_v0; struct hwsim_edge *e; u32 v0, v1; u8 lqi; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE], hwsim_edge_policy, NULL)) return -EINVAL; - if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] && + if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] || !edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI]) return -EINVAL; @@ -560,8 +560,10 @@ list_for_each_entry_rcu(e, &phy_v0->edges, list) { if (e->endpoint->idx == v1) { einfo->lqi = lqi; - rcu_assign_pointer(e->info, einfo); + einfo_old = rcu_replace_pointer(e->info, einfo, + lockdep_is_held(&hwsim_phys_lock)); rcu_read_unlock(); + kfree_rcu(einfo_old, rcu); mutex_unlock(&hwsim_phys_lock); return 0; } @@ -715,6 +717,8 @@ return 0; +sub_fail: + hwsim_edge_unsubscribe_me(phy); me_fail: rcu_read_lock(); list_for_each_entry_rcu(e, &phy->edges, list) { @@ -722,8 +726,6 @@ hwsim_free_edge(e); } rcu_read_unlock(); -sub_fail: - hwsim_edge_unsubscribe_me(phy); return -ENOMEM; } @@ -786,6 +788,7 @@ goto err_pib; } + pib->channel = 13; rcu_assign_pointer(phy->pib, pib); phy->idx = idx; INIT_LIST_HEAD(&phy->edges); @@ -824,12 +827,17 @@ static void hwsim_del(struct hwsim_phy *phy) { struct hwsim_pib *pib; + struct hwsim_edge *e; hwsim_edge_unsubscribe_me(phy); list_del(&phy->list); rcu_read_lock(); + list_for_each_entry_rcu(e, &phy->edges, list) { + list_del_rcu(&e->list); + hwsim_free_edge(e); + } pib = rcu_dereference(phy->pib); rcu_read_unlock(); --- linux-oracle-5.4.0.orig/drivers/net/ieee802154/mcr20a.c +++ linux-oracle-5.4.0/drivers/net/ieee802154/mcr20a.c @@ -976,8 +976,8 @@ dev_dbg(printdev(lp), "%s\n", __func__); phy->symbol_duration = 16; - phy->lifs_period = 40; - phy->sifs_period = 12; + phy->lifs_period = 40 * phy->symbol_duration; + phy->sifs_period = 12 * phy->symbol_duration; hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | @@ -1311,16 +1311,13 @@ irq_type = IRQF_TRIGGER_FALLING; ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr, - irq_type, dev_name(&spi->dev), lp); + irq_type | IRQF_NO_AUTOEN, dev_name(&spi->dev), lp); if (ret) { dev_err(&spi->dev, "could not request_irq for mcr20a\n"); ret = -ENODEV; goto free_dev; } - /* disable_irq by default and wait for starting hardware */ - disable_irq(spi->irq); - ret = ieee802154_register_hw(hw); if (ret) { dev_crit(&spi->dev, "ieee802154_register_hw failed\n"); --- linux-oracle-5.4.0.orig/drivers/net/ifb.c +++ linux-oracle-5.4.0/drivers/net/ifb.c @@ -75,7 +75,7 @@ } while ((skb = __skb_dequeue(&txp->tq)) != NULL) { - skb->tc_redirected = 0; + skb->redirected = 0; skb->tc_skip_classify = 1; u64_stats_update_begin(&txp->tsync); @@ -96,7 +96,7 @@ rcu_read_unlock(); skb->skb_iif = txp->dev->ifindex; - if (!skb->tc_from_ingress) { + if (!skb->from_ingress) { dev_queue_xmit(skb); } else { skb_pull_rcsum(skb, skb->mac_len); @@ -243,7 +243,7 @@ txp->rx_bytes += skb->len; u64_stats_update_end(&txp->rsync); - if (!skb->tc_redirected || !skb->skb_iif) { + if (!skb->redirected || !skb->skb_iif) { dev_kfree_skb(skb); dev->stats.rx_dropped++; return NETDEV_TX_OK; --- linux-oracle-5.4.0.orig/drivers/net/ipvlan/ipvlan_core.c +++ linux-oracle-5.4.0/drivers/net/ipvlan/ipvlan_core.c @@ -293,6 +293,7 @@ } if (dev) dev_put(dev); + cond_resched(); } } @@ -411,7 +412,7 @@ return addr; } -static int ipvlan_process_v4_outbound(struct sk_buff *skb) +static noinline_for_stack int ipvlan_process_v4_outbound(struct sk_buff *skb) { const struct iphdr *ip4h = ip_hdr(skb); struct net_device *dev = skb->dev; @@ -436,27 +437,28 @@ goto err; } skb_dst_set(skb, &rt->dst); - err = ip_local_out(net, skb->sk, skb); + + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); + + err = ip_local_out(net, NULL, skb); if (unlikely(net_xmit_eval(err))) - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); else ret = NET_XMIT_SUCCESS; goto out; err: - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); kfree_skb(skb); out: return ret; } #if IS_ENABLED(CONFIG_IPV6) -static int ipvlan_process_v6_outbound(struct sk_buff *skb) + +static noinline_for_stack int +ipvlan_route_v6_outbound(struct net_device *dev, struct sk_buff *skb) { const struct ipv6hdr *ip6h = ipv6_hdr(skb); - struct net_device *dev = skb->dev; - struct net *net = dev_net(dev); - struct dst_entry *dst; - int err, ret = NET_XMIT_DROP; struct flowi6 fl6 = { .flowi6_oif = dev->ifindex, .daddr = ip6h->daddr, @@ -466,24 +468,38 @@ .flowi6_mark = skb->mark, .flowi6_proto = ip6h->nexthdr, }; + struct dst_entry *dst; + int err; - dst = ip6_route_output(net, NULL, &fl6); - if (dst->error) { - ret = dst->error; + dst = ip6_route_output(dev_net(dev), NULL, &fl6); + err = dst->error; + if (err) { dst_release(dst); - goto err; + return err; } skb_dst_set(skb, dst); - err = ip6_local_out(net, skb->sk, skb); + return 0; +} + +static int ipvlan_process_v6_outbound(struct sk_buff *skb) +{ + struct net_device *dev = skb->dev; + int err, ret = NET_XMIT_DROP; + + err = ipvlan_route_v6_outbound(dev, skb); + if (unlikely(err)) { + DEV_STATS_INC(dev, tx_errors); + kfree_skb(skb); + return err; + } + + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); + + err = ip6_local_out(dev_net(dev), NULL, skb); if (unlikely(net_xmit_eval(err))) - dev->stats.tx_errors++; + DEV_STATS_INC(dev, tx_errors); else ret = NET_XMIT_SUCCESS; - goto out; -err: - dev->stats.tx_errors++; - kfree_skb(skb); -out: return ret; } #else @@ -495,22 +511,25 @@ static int ipvlan_process_outbound(struct sk_buff *skb) { - struct ethhdr *ethh = eth_hdr(skb); int ret = NET_XMIT_DROP; - /* In this mode we dont care about multicast and broadcast traffic */ - if (is_multicast_ether_addr(ethh->h_dest)) { - pr_debug_ratelimited("Dropped {multi|broad}cast of type=[%x]\n", - ntohs(skb->protocol)); - kfree_skb(skb); - goto out; - } - /* The ipvlan is a pseudo-L2 device, so the packets that we receive * will have L2; which need to discarded and processed further * in the net-ns of the main-device. */ if (skb_mac_header_was_set(skb)) { + /* In this mode we dont care about + * multicast and broadcast traffic */ + struct ethhdr *ethh = eth_hdr(skb); + + if (is_multicast_ether_addr(ethh->h_dest)) { + pr_debug_ratelimited( + "Dropped {multi|broad}cast of type=[%x]\n", + ntohs(skb->protocol)); + kfree_skb(skb); + goto out; + } + skb_pull(skb, sizeof(*ethh)); skb->mac_header = (typeof(skb->mac_header))~0U; skb_reset_network_header(skb); @@ -576,7 +595,8 @@ consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } out: @@ -587,7 +607,7 @@ static int ipvlan_xmit_mode_l2(struct sk_buff *skb, struct net_device *dev) { const struct ipvl_dev *ipvlan = netdev_priv(dev); - struct ethhdr *eth = eth_hdr(skb); + struct ethhdr *eth = skb_eth_hdr(skb); struct ipvl_addr *addr; void *lyr3h; int addr_type; @@ -602,7 +622,8 @@ consume_skb(skb); return NET_XMIT_DROP; } - return ipvlan_rcv_frame(addr, &skb, true); + ipvlan_rcv_frame(addr, &skb, true); + return NET_XMIT_SUCCESS; } } skb = skb_share_check(skb, GFP_ATOMIC); @@ -614,9 +635,11 @@ * the skb for the main-dev. At the RX side we just return * RX_PASS for it to be processed further on the stack. */ - return dev_forward_skb(ipvlan->phy_dev, skb); + dev_forward_skb(ipvlan->phy_dev, skb); + return NET_XMIT_SUCCESS; } else if (is_multicast_ether_addr(eth->h_dest)) { + skb_reset_mac_header(skb); ipvlan_skb_crossing_ns(skb, NULL); ipvlan_multicast_enqueue(ipvlan->port, skb, true); return NET_XMIT_SUCCESS; --- linux-oracle-5.4.0.orig/drivers/net/ipvlan/ipvlan_l3s.c +++ linux-oracle-5.4.0/drivers/net/ipvlan/ipvlan_l3s.c @@ -101,6 +101,11 @@ goto out; skb->dev = addr->master->dev; + skb->skb_iif = skb->dev->ifindex; +#if IS_ENABLED(CONFIG_IPV6) + if (addr->atype == IPVL_IPV6) + IP6CB(skb)->iif = skb->dev->ifindex; +#endif len = skb->len + ETH_HLEN; ipvlan_count_rx(addr->master, len, true, false); out: --- linux-oracle-5.4.0.orig/drivers/net/ipvlan/ipvlan_main.c +++ linux-oracle-5.4.0/drivers/net/ipvlan/ipvlan_main.c @@ -106,12 +106,21 @@ kfree(port); } +#define IPVLAN_ALWAYS_ON_OFLOADS \ + (NETIF_F_SG | NETIF_F_HW_CSUM | \ + NETIF_F_GSO_ROBUST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL) + +#define IPVLAN_ALWAYS_ON \ + (IPVLAN_ALWAYS_ON_OFLOADS | NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED) + #define IPVLAN_FEATURES \ - (NETIF_F_SG | NETIF_F_CSUM_MASK | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ + (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \ NETIF_F_GSO | NETIF_F_TSO | NETIF_F_GSO_ROBUST | \ NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \ NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER) + /* NETIF_F_GSO_ENCAP_ALL NETIF_F_GSO_SOFTWARE Newly added */ + #define IPVLAN_STATE_MASK \ ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) @@ -125,7 +134,9 @@ dev->state = (dev->state & ~IPVLAN_STATE_MASK) | (phy_dev->state & IPVLAN_STATE_MASK); dev->features = phy_dev->features & IPVLAN_FEATURES; - dev->features |= NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED; + dev->features |= IPVLAN_ALWAYS_ON; + dev->vlan_features = phy_dev->vlan_features & IPVLAN_FEATURES; + dev->vlan_features |= IPVLAN_ALWAYS_ON_OFLOADS; dev->hw_enc_features |= dev->features; dev->gso_max_size = phy_dev->gso_max_size; dev->gso_max_segs = phy_dev->gso_max_segs; @@ -164,7 +175,6 @@ static int ipvlan_open(struct net_device *dev) { struct ipvl_dev *ipvlan = netdev_priv(dev); - struct net_device *phy_dev = ipvlan->phy_dev; struct ipvl_addr *addr; if (ipvlan->port->mode == IPVLAN_MODE_L3 || @@ -178,7 +188,7 @@ ipvlan_ht_addr_add(ipvlan, addr); rcu_read_unlock(); - return dev_uc_add(phy_dev, phy_dev->dev_addr); + return 0; } static int ipvlan_stop(struct net_device *dev) @@ -190,8 +200,6 @@ dev_uc_unsync(phy_dev, dev); dev_mc_unsync(phy_dev, dev); - dev_uc_del(phy_dev, phy_dev->dev_addr); - rcu_read_lock(); list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) ipvlan_ht_addr_del(addr); @@ -228,7 +236,14 @@ { struct ipvl_dev *ipvlan = netdev_priv(dev); - return features & (ipvlan->sfeatures | ~IPVLAN_FEATURES); + features |= NETIF_F_ALL_FOR_ALL; + features &= (ipvlan->sfeatures | ~IPVLAN_FEATURES); + features = netdev_increment_features(ipvlan->phy_dev->features, + features, features); + features |= IPVLAN_ALWAYS_ON; + features &= (IPVLAN_FEATURES | IPVLAN_ALWAYS_ON); + + return features; } static void ipvlan_change_rx_flags(struct net_device *dev, int change) @@ -305,6 +320,7 @@ s->rx_dropped = rx_errs; s->tx_dropped = tx_drps; } + s->tx_errors = DEV_STATS_READ(dev, tx_errors); } static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) @@ -720,7 +736,8 @@ write_pnet(&port->pnet, newnet); - ipvlan_migrate_l3s_hook(oldnet, newnet); + if (port->mode == IPVLAN_MODE_L3S) + ipvlan_migrate_l3s_hook(oldnet, newnet); break; } case NETDEV_UNREGISTER: @@ -735,10 +752,9 @@ case NETDEV_FEAT_CHANGE: list_for_each_entry(ipvlan, &port->ipvlans, pnode) { - ipvlan->dev->features = dev->features & IPVLAN_FEATURES; ipvlan->dev->gso_max_size = dev->gso_max_size; ipvlan->dev->gso_max_segs = dev->gso_max_segs; - netdev_features_change(ipvlan->dev); + netdev_update_features(ipvlan->dev); } break; --- linux-oracle-5.4.0.orig/drivers/net/ipvlan/ipvtap.c +++ linux-oracle-5.4.0/drivers/net/ipvlan/ipvtap.c @@ -194,7 +194,7 @@ .notifier_call = ipvtap_device_event, }; -static int ipvtap_init(void) +static int __init ipvtap_init(void) { int err; @@ -228,7 +228,7 @@ } module_init(ipvtap_init); -static void ipvtap_exit(void) +static void __exit ipvtap_exit(void) { rtnl_link_unregister(&ipvtap_link_ops); unregister_netdevice_notifier(&ipvtap_notifier_block); --- linux-oracle-5.4.0.orig/drivers/net/loopback.c +++ linux-oracle-5.4.0/drivers/net/loopback.c @@ -206,7 +206,7 @@ int err; err = -ENOMEM; - dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup); + dev = alloc_netdev(0, "lo", NET_NAME_PREDICTABLE, loopback_setup); if (!dev) goto out; @@ -241,8 +241,22 @@ return NETDEV_TX_OK; } +static int blackhole_neigh_output(struct neighbour *n, struct sk_buff *skb) +{ + kfree_skb(skb); + return 0; +} + +static int blackhole_neigh_construct(struct net_device *dev, + struct neighbour *n) +{ + n->output = blackhole_neigh_output; + return 0; +} + static const struct net_device_ops blackhole_netdev_ops = { .ndo_start_xmit = blackhole_netdev_xmit, + .ndo_neigh_construct = blackhole_neigh_construct, }; /* This is a dst-dummy device used specifically for invalidated --- linux-oracle-5.4.0.orig/drivers/net/macsec.c +++ linux-oracle-5.4.0/drivers/net/macsec.c @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -560,18 +561,28 @@ skb->protocol = eth_hdr(skb)->h_proto; } +static unsigned int macsec_msdu_len(struct sk_buff *skb) +{ + struct macsec_dev *macsec = macsec_priv(skb->dev); + struct macsec_secy *secy = &macsec->secy; + bool sci_present = macsec_skb_cb(skb)->has_sci; + + return skb->len - macsec_hdr_len(sci_present) - secy->icv_len; +} + static void macsec_count_tx(struct sk_buff *skb, struct macsec_tx_sc *tx_sc, struct macsec_tx_sa *tx_sa) { + unsigned int msdu_len = macsec_msdu_len(skb); struct pcpu_tx_sc_stats *txsc_stats = this_cpu_ptr(tx_sc->stats); u64_stats_update_begin(&txsc_stats->syncp); if (tx_sc->encrypt) { - txsc_stats->stats.OutOctetsEncrypted += skb->len; + txsc_stats->stats.OutOctetsEncrypted += msdu_len; txsc_stats->stats.OutPktsEncrypted++; this_cpu_inc(tx_sa->stats->OutPktsEncrypted); } else { - txsc_stats->stats.OutOctetsProtected += skb->len; + txsc_stats->stats.OutOctetsProtected += msdu_len; txsc_stats->stats.OutPktsProtected++; this_cpu_inc(tx_sa->stats->OutPktsProtected); } @@ -601,9 +612,10 @@ aead_request_free(macsec_skb_cb(skb)->req); rcu_read_lock_bh(); - macsec_encrypt_finish(skb, dev); macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa); - len = skb->len; + /* packet is encrypted/protected so tx_bytes must be calculated */ + len = macsec_msdu_len(skb) + 2 * ETH_ALEN; + macsec_encrypt_finish(skb, dev); ret = dev_queue_xmit(skb); count_tx(dev, ret, len); rcu_read_unlock_bh(); @@ -759,6 +771,7 @@ macsec_skb_cb(skb)->req = req; macsec_skb_cb(skb)->tx_sa = tx_sa; + macsec_skb_cb(skb)->has_sci = sci_present; aead_request_set_callback(req, 0, macsec_encrypt_done, skb); dev_hold(skb->dev); @@ -799,15 +812,17 @@ u64_stats_update_begin(&rxsc_stats->syncp); rxsc_stats->stats.InPktsLate++; u64_stats_update_end(&rxsc_stats->syncp); + DEV_STATS_INC(secy->netdev, rx_dropped); return false; } if (secy->validate_frames != MACSEC_VALIDATE_DISABLED) { + unsigned int msdu_len = macsec_msdu_len(skb); u64_stats_update_begin(&rxsc_stats->syncp); if (hdr->tci_an & MACSEC_TCI_E) - rxsc_stats->stats.InOctetsDecrypted += skb->len; + rxsc_stats->stats.InOctetsDecrypted += msdu_len; else - rxsc_stats->stats.InOctetsValidated += skb->len; + rxsc_stats->stats.InOctetsValidated += msdu_len; u64_stats_update_end(&rxsc_stats->syncp); } @@ -820,6 +835,8 @@ u64_stats_update_begin(&rxsc_stats->syncp); rxsc_stats->stats.InPktsNotValid++; u64_stats_update_end(&rxsc_stats->syncp); + this_cpu_inc(rx_sa->stats->InPktsNotValid); + DEV_STATS_INC(secy->netdev, rx_errors); return false; } @@ -905,9 +922,9 @@ macsec_finalize_skb(skb, macsec->secy.icv_len, macsec_extra_len(macsec_skb_cb(skb)->has_sci)); + len = skb->len; macsec_reset_skb(skb, macsec->secy.netdev); - len = skb->len; if (gro_cells_receive(&macsec->gro_cells, skb) == NET_RX_SUCCESS) count_rx(dev, len); @@ -1049,6 +1066,7 @@ u64_stats_update_begin(&secy_stats->syncp); secy_stats->stats.InPktsNoTag++; u64_stats_update_end(&secy_stats->syncp); + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); continue; } @@ -1079,6 +1097,7 @@ struct macsec_rx_sa *rx_sa; struct macsec_rxh_data *rxd; struct macsec_dev *macsec; + unsigned int len; sci_t sci; u32 pn; bool cbit; @@ -1159,6 +1178,7 @@ u64_stats_update_begin(&secy_stats->syncp); secy_stats->stats.InPktsBadTag++; u64_stats_update_end(&secy_stats->syncp); + DEV_STATS_INC(secy->netdev, rx_errors); goto drop_nosa; } @@ -1174,6 +1194,7 @@ u64_stats_update_begin(&rxsc_stats->syncp); rxsc_stats->stats.InPktsNotUsingSA++; u64_stats_update_end(&rxsc_stats->syncp); + DEV_STATS_INC(secy->netdev, rx_errors); goto drop_nosa; } @@ -1200,6 +1221,7 @@ u64_stats_update_begin(&rxsc_stats->syncp); rxsc_stats->stats.InPktsLate++; u64_stats_update_end(&rxsc_stats->syncp); + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); goto drop; } } @@ -1228,6 +1250,7 @@ deliver: macsec_finalize_skb(skb, secy->icv_len, macsec_extra_len(macsec_skb_cb(skb)->has_sci)); + len = skb->len; macsec_reset_skb(skb, secy->netdev); if (rx_sa) @@ -1237,9 +1260,9 @@ skb_orphan(skb); ret = gro_cells_receive(&macsec->gro_cells, skb); if (ret == NET_RX_SUCCESS) - count_rx(dev, skb->len); + count_rx(dev, len); else - macsec->secy.netdev->stats.rx_dropped++; + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); rcu_read_unlock(); @@ -1276,6 +1299,7 @@ u64_stats_update_begin(&secy_stats->syncp); secy_stats->stats.InPktsNoSCI++; u64_stats_update_end(&secy_stats->syncp); + DEV_STATS_INC(macsec->secy.netdev, rx_errors); continue; } @@ -1294,7 +1318,7 @@ secy_stats->stats.InPktsUnknownSCI++; u64_stats_update_end(&secy_stats->syncp); } else { - macsec->secy.netdev->stats.rx_dropped++; + DEV_STATS_INC(macsec->secy.netdev, rx_dropped); } } @@ -2727,21 +2751,21 @@ if (!secy->operational) { kfree_skb(skb); - dev->stats.tx_dropped++; + DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } + len = skb->len; skb = macsec_encrypt(skb, dev); if (IS_ERR(skb)) { if (PTR_ERR(skb) != -EINPROGRESS) - dev->stats.tx_dropped++; + DEV_STATS_INC(dev, tx_dropped); return NETDEV_TX_OK; } macsec_count_tx(skb, &macsec->secy.tx_sc, macsec_skb_cb(skb)->tx_sa); macsec_encrypt_finish(skb, dev); - len = skb->len; ret = dev_queue_xmit(skb); count_tx(dev, ret, len); return ret; @@ -2882,6 +2906,11 @@ dev_uc_sync(real_dev, dev); } +static sci_t dev_to_sci(struct net_device *dev, __be16 port) +{ + return make_sci(dev->dev_addr, port); +} + static int macsec_set_mac_address(struct net_device *dev, void *p) { struct macsec_dev *macsec = macsec_priv(dev); @@ -2903,6 +2932,7 @@ out: ether_addr_copy(dev->dev_addr, addr->sa_data); + macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); return 0; } @@ -2947,8 +2977,9 @@ s->tx_bytes += tmp.tx_bytes; } - s->rx_dropped = dev->stats.rx_dropped; - s->tx_dropped = dev->stats.tx_dropped; + s->rx_dropped = DEV_STATS_READ(dev, rx_dropped); + s->tx_dropped = DEV_STATS_READ(dev, tx_dropped); + s->rx_errors = DEV_STATS_READ(dev, rx_errors); } static int macsec_get_iflink(const struct net_device *dev) @@ -2977,6 +3008,7 @@ static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, + [IFLA_MACSEC_PORT] = { .type = NLA_U16 }, [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, @@ -3176,11 +3208,6 @@ return false; } -static sci_t dev_to_sci(struct net_device *dev, __be16 port) -{ - return make_sci(dev->dev_addr, port); -} - static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) { struct macsec_dev *macsec = macsec_priv(dev); @@ -3223,25 +3250,40 @@ struct netlink_ext_ack *extack) { struct macsec_dev *macsec = macsec_priv(dev); + rx_handler_func_t *rx_handler; + u8 icv_len = DEFAULT_ICV_LEN; struct net_device *real_dev; - int err; + int err, mtu; sci_t sci; - u8 icv_len = DEFAULT_ICV_LEN; - rx_handler_func_t *rx_handler; if (!tb[IFLA_LINK]) return -EINVAL; real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); if (!real_dev) return -ENODEV; + if (real_dev->type != ARPHRD_ETHER) + return -EINVAL; dev->priv_flags |= IFF_MACSEC; macsec->real_dev = real_dev; + /* send_sci must be set to true when transmit sci explicitly is set */ + if ((data && data[IFLA_MACSEC_SCI]) && + (data && data[IFLA_MACSEC_INC_SCI])) { + u8 send_sci = !!nla_get_u8(data[IFLA_MACSEC_INC_SCI]); + + if (!send_sci) + return -EINVAL; + } + if (data && data[IFLA_MACSEC_ICV_LEN]) icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); - dev->mtu = real_dev->mtu - icv_len - macsec_extra_len(true); + mtu = real_dev->mtu - icv_len - macsec_extra_len(true); + if (mtu < 0) + dev->mtu = 0; + else + dev->mtu = mtu; rx_handler = rtnl_dereference(real_dev->rx_handler); if (rx_handler && rx_handler != macsec_handle_frame) --- linux-oracle-5.4.0.orig/drivers/net/macvlan.c +++ linux-oracle-5.4.0/drivers/net/macvlan.c @@ -138,7 +138,7 @@ u32 idx = macvlan_eth_hash(addr); struct hlist_head *h = &vlan->port->vlan_source_hash[idx]; - hlist_for_each_entry_rcu(entry, h, hlist) { + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { if (ether_addr_equal_64bits(entry->addr, addr) && entry->vlan == vlan) return entry; @@ -334,6 +334,8 @@ if (src) dev_put(src->dev); consume_skb(skb); + + cond_resched(); } } @@ -359,10 +361,11 @@ } spin_unlock(&port->bc_queue.lock); + schedule_work(&port->bc_work); + if (err) goto free_nskb; - schedule_work(&port->bc_work); return; free_nskb: @@ -444,6 +447,10 @@ int ret; rx_handler_result_t handle_res; + /* Packets from dev_loopback_xmit() do not have L2 header, bail out */ + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) + return RX_HANDLER_PASS; + port = macvlan_port_get_rcu(skb->dev); if (is_multicast_ether_addr(eth->h_dest)) { unsigned int hash; @@ -512,10 +519,11 @@ const struct macvlan_dev *dest; if (vlan->mode == MACVLAN_MODE_BRIDGE) { - const struct ethhdr *eth = (void *)skb->data; + const struct ethhdr *eth = skb_eth_hdr(skb); /* send to other bridge ports directly */ if (is_multicast_ether_addr(eth->h_dest)) { + skb_reset_mac_header(skb); macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); goto xmit_world; } @@ -757,7 +765,7 @@ if (dev->flags & IFF_UP) { if (change & IFF_ALLMULTI) dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); - if (change & IFF_PROMISC) + if (!macvlan_passthru(vlan->port) && change & IFF_PROMISC) dev_set_promiscuity(lowerdev, dev->flags & IFF_PROMISC ? 1 : -1); @@ -1158,7 +1166,7 @@ { ether_setup(dev); - dev->min_mtu = 0; + /* ether_setup() has set dev->min_mtu to ETH_MIN_MTU. */ dev->max_mtu = ETH_MAX_MTU; dev->priv_flags &= ~IFF_TX_SKB_SHARING; netif_keep_dst(dev); @@ -1251,6 +1259,9 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[], struct netlink_ext_ack *extack) { + struct nlattr *nla, *head; + int rem, len; + if (tb[IFLA_ADDRESS]) { if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) return -EINVAL; @@ -1298,6 +1309,20 @@ return -EADDRNOTAVAIL; } + if (data[IFLA_MACVLAN_MACADDR_DATA]) { + head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]); + len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]); + + nla_for_each_attr(nla, head, len, rem) { + if (nla_type(nla) != IFLA_MACVLAN_MACADDR || + nla_len(nla) != ETH_ALEN) + return -EINVAL; + + if (!is_valid_ether_addr(nla_data(nla))) + return -EADDRNOTAVAIL; + } + } + if (data[IFLA_MACVLAN_MACADDR_COUNT]) return -EINVAL; @@ -1354,10 +1379,6 @@ len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]); nla_for_each_attr(nla, head, len, rem) { - if (nla_type(nla) != IFLA_MACVLAN_MACADDR || - nla_len(nla) != ETH_ALEN) - continue; - addr = nla_data(nla); ret = macvlan_hash_add_source(vlan, addr); if (ret) @@ -1478,8 +1499,10 @@ /* the macvlan port may be freed by macvlan_uninit when fail to register. * so we destroy the macvlan port only when it's valid. */ - if (create && macvlan_port_get_rtnl(lowerdev)) + if (create && macvlan_port_get_rtnl(lowerdev)) { + macvlan_flush_sources(port, vlan); macvlan_port_destroy(port->dev); + } return err; } EXPORT_SYMBOL_GPL(macvlan_common_newlink); @@ -1581,7 +1604,7 @@ struct hlist_head *h = &vlan->port->vlan_source_hash[i]; struct macvlan_source_entry *entry; - hlist_for_each_entry_rcu(entry, h, hlist) { + hlist_for_each_entry_rcu(entry, h, hlist, lockdep_rtnl_is_held()) { if (entry->vlan != vlan) continue; if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr)) @@ -1700,7 +1723,7 @@ struct macvlan_dev, list); - if (macvlan_sync_address(vlan->dev, dev->dev_addr)) + if (vlan && macvlan_sync_address(vlan->dev, dev->dev_addr)) return NOTIFY_BAD; break; --- linux-oracle-5.4.0.orig/drivers/net/macvtap.c +++ linux-oracle-5.4.0/drivers/net/macvtap.c @@ -133,11 +133,17 @@ dev->tx_queue_len = TUN_READQ_SIZE; } +static struct net *macvtap_link_net(const struct net_device *dev) +{ + return dev_net(macvlan_dev_real_dev(dev)); +} + static struct rtnl_link_ops macvtap_link_ops __read_mostly = { .kind = "macvtap", .setup = macvtap_setup, .newlink = macvtap_newlink, .dellink = macvtap_dellink, + .get_link_net = macvtap_link_net, .priv_size = sizeof(struct macvtap_dev), }; --- linux-oracle-5.4.0.orig/drivers/net/net_failover.c +++ linux-oracle-5.4.0/drivers/net/net_failover.c @@ -61,7 +61,8 @@ return 0; err_standby_open: - dev_close(primary_dev); + if (primary_dev) + dev_close(primary_dev); err_primary_open: netif_tx_disable(dev); return err; @@ -129,14 +130,10 @@ txq = ops->ndo_select_queue(primary_dev, skb, sb_dev); else txq = netdev_pick_tx(primary_dev, skb, NULL); - - qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; - - return txq; + } else { + txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; } - txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0; - /* Save the original txq to restore before passing to the driver */ qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping; --- linux-oracle-5.4.0.orig/drivers/net/netconsole.c +++ linux-oracle-5.4.0/drivers/net/netconsole.c @@ -715,6 +715,7 @@ /* rtnl_lock already held * we might sleep in __netpoll_cleanup() */ + nt->enabled = false; spin_unlock_irqrestore(&target_list_lock, flags); __netpoll_cleanup(&nt->np); @@ -722,7 +723,6 @@ spin_lock_irqsave(&target_list_lock, flags); dev_put(nt->np.dev); nt->np.dev = NULL; - nt->enabled = false; stopped = true; netconsole_target_put(nt); goto restart; --- linux-oracle-5.4.0.orig/drivers/net/netdevsim/bpf.c +++ linux-oracle-5.4.0/drivers/net/netdevsim/bpf.c @@ -347,10 +347,12 @@ { struct nsim_bpf_bound_map *nmap = offmap->dev_priv; - nmap->entry[idx].key = kmalloc(offmap->map.key_size, GFP_USER); + nmap->entry[idx].key = kmalloc(offmap->map.key_size, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!nmap->entry[idx].key) return -ENOMEM; - nmap->entry[idx].value = kmalloc(offmap->map.value_size, GFP_USER); + nmap->entry[idx].value = kmalloc(offmap->map.value_size, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!nmap->entry[idx].value) { kfree(nmap->entry[idx].key); nmap->entry[idx].key = NULL; @@ -492,7 +494,7 @@ if (offmap->map.map_flags) return -EINVAL; - nmap = kzalloc(sizeof(*nmap), GFP_USER); + nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT); if (!nmap) return -ENOMEM; @@ -510,6 +512,7 @@ goto err_free; key = nmap->entry[i].key; *key = i; + memset(nmap->entry[i].value, 0, offmap->map.value_size); } } --- linux-oracle-5.4.0.orig/drivers/net/netdevsim/dev.c +++ linux-oracle-5.4.0/drivers/net/netdevsim/dev.c @@ -73,7 +73,7 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev) { - char dev_ddir_name[16]; + char dev_ddir_name[sizeof(DRV_NAME) + 10]; sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id); nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir); --- linux-oracle-5.4.0.orig/drivers/net/netdevsim/netdev.c +++ linux-oracle-5.4.0/drivers/net/netdevsim/netdev.c @@ -292,6 +292,7 @@ ns = netdev_priv(dev); ns->netdev = dev; + u64_stats_init(&ns->syncp); ns->nsim_dev = nsim_dev; ns->nsim_dev_port = nsim_dev_port; ns->nsim_bus_dev = nsim_dev->nsim_bus_dev; @@ -301,7 +302,7 @@ rtnl_lock(); err = nsim_bpf_init(ns); if (err) - goto err_free_netdev; + goto err_rtnl_unlock; nsim_ipsec_init(ns); @@ -315,8 +316,8 @@ err_ipsec_teardown: nsim_ipsec_teardown(ns); nsim_bpf_uninit(ns); +err_rtnl_unlock: rtnl_unlock(); -err_free_netdev: free_netdev(dev); return ERR_PTR(err); } --- linux-oracle-5.4.0.orig/drivers/net/ntb_netdev.c +++ linux-oracle-5.4.0/drivers/net/ntb_netdev.c @@ -137,7 +137,7 @@ enqueue_again: rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN); if (rc) { - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); ndev->stats.rx_errors++; ndev->stats.rx_fifo_errors++; } @@ -192,7 +192,7 @@ ndev->stats.tx_aborted_errors++; } - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); if (ntb_transport_tx_free_entry(dev->qp) >= tx_start) { /* Make sure anybody stopping the queue after this sees the new @@ -484,7 +484,14 @@ rc = ntb_transport_register_client_dev(KBUILD_MODNAME); if (rc) return rc; - return ntb_transport_register_client(&ntb_netdev_client); + + rc = ntb_transport_register_client(&ntb_netdev_client); + if (rc) { + ntb_transport_unregister_client_dev(KBUILD_MODNAME); + return rc; + } + + return 0; } module_init(ntb_netdev_init_module); --- linux-oracle-5.4.0.orig/drivers/net/phy/Kconfig +++ linux-oracle-5.4.0/drivers/net/phy/Kconfig @@ -193,6 +193,7 @@ depends on 64BIT depends on PCI select MDIO_CAVIUM + select MDIO_DEVRES help This driver supports the MDIO interfaces found on Cavium ThunderX SoCs when the MDIO bus device appears as a PCI --- linux-oracle-5.4.0.orig/drivers/net/phy/aquantia_main.c +++ linux-oracle-5.4.0/drivers/net/phy/aquantia_main.c @@ -34,6 +34,8 @@ #define MDIO_AN_VEND_PROV 0xc400 #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) +#define MDIO_AN_VEND_PROV_5000BASET_FULL BIT(11) +#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10) #define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4) #define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0) #define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT 4 @@ -230,9 +232,20 @@ phydev->advertising)) reg |= MDIO_AN_VEND_PROV_1000BASET_HALF; + /* Handle the case when the 2.5G and 5G speeds are not advertised */ + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + phydev->advertising)) + reg |= MDIO_AN_VEND_PROV_2500BASET_FULL; + + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + phydev->advertising)) + reg |= MDIO_AN_VEND_PROV_5000BASET_FULL; + ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV, MDIO_AN_VEND_PROV_1000BASET_HALF | - MDIO_AN_VEND_PROV_1000BASET_FULL, reg); + MDIO_AN_VEND_PROV_1000BASET_FULL | + MDIO_AN_VEND_PROV_2500BASET_FULL | + MDIO_AN_VEND_PROV_5000BASET_FULL, reg); if (ret < 0) return ret; if (ret > 0) @@ -627,6 +640,8 @@ .config_intr = aqr_config_intr, .ack_interrupt = aqr_ack_interrupt, .read_status = aqr_read_status, + .suspend = aqr107_suspend, + .resume = aqr107_resume, }, { PHY_ID_MATCH_MODEL(PHY_ID_AQR106), --- linux-oracle-5.4.0.orig/drivers/net/phy/bcm-phy-lib.c +++ linux-oracle-5.4.0/drivers/net/phy/bcm-phy-lib.c @@ -190,7 +190,7 @@ int bcm_phy_set_eee(struct phy_device *phydev, bool enable) { - int val; + int val, mask = 0; /* Enable EEE at PHY level */ val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL); @@ -209,10 +209,17 @@ if (val < 0) return val; + if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + phydev->supported)) + mask |= MDIO_EEE_1000T; + if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, + phydev->supported)) + mask |= MDIO_EEE_100TX; + if (enable) - val |= (MDIO_EEE_100TX | MDIO_EEE_1000T); + val |= mask; else - val &= ~(MDIO_EEE_100TX | MDIO_EEE_1000T); + val &= ~mask; phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val); --- linux-oracle-5.4.0.orig/drivers/net/phy/bcm63xx.c +++ linux-oracle-5.4.0/drivers/net/phy/bcm63xx.c @@ -73,6 +73,7 @@ /* same phy as above, with just a different OUI */ .phy_id = 0x002bdc00, .phy_id_mask = 0xfffffc00, + .name = "Broadcom BCM63XX (2)", /* PHY_BASIC_FEATURES */ .flags = PHY_IS_INTERNAL, .config_init = bcm63xx_config_init, --- linux-oracle-5.4.0.orig/drivers/net/phy/bcm7xxx.c +++ linux-oracle-5.4.0/drivers/net/phy/bcm7xxx.c @@ -26,7 +26,12 @@ #define MII_BCM7XXX_SHD_2_ADDR_CTRL 0xe #define MII_BCM7XXX_SHD_2_CTRL_STAT 0xf #define MII_BCM7XXX_SHD_2_BIAS_TRIM 0x1a +#define MII_BCM7XXX_SHD_3_PCS_CTRL 0x0 +#define MII_BCM7XXX_SHD_3_PCS_STATUS 0x1 +#define MII_BCM7XXX_SHD_3_EEE_CAP 0x2 #define MII_BCM7XXX_SHD_3_AN_EEE_ADV 0x3 +#define MII_BCM7XXX_SHD_3_EEE_LP 0x4 +#define MII_BCM7XXX_SHD_3_EEE_WK_ERR 0x5 #define MII_BCM7XXX_SHD_3_PCS_CTRL_2 0x6 #define MII_BCM7XXX_PCS_CTRL_2_DEF 0x4400 #define MII_BCM7XXX_SHD_3_AN_STAT 0xb @@ -210,25 +215,37 @@ return genphy_config_aneg(phydev); } -static int phy_set_clr_bits(struct phy_device *dev, int location, - int set_mask, int clr_mask) +static int __phy_set_clr_bits(struct phy_device *dev, int location, + int set_mask, int clr_mask) { int v, ret; - v = phy_read(dev, location); + v = __phy_read(dev, location); if (v < 0) return v; v &= ~clr_mask; v |= set_mask; - ret = phy_write(dev, location, v); + ret = __phy_write(dev, location, v); if (ret < 0) return ret; return v; } +static int phy_set_clr_bits(struct phy_device *dev, int location, + int set_mask, int clr_mask) +{ + int ret; + + mutex_lock(&dev->mdio.bus->mdio_lock); + ret = __phy_set_clr_bits(dev, location, set_mask, clr_mask); + mutex_unlock(&dev->mdio.bus->mdio_lock); + + return ret; +} + static int bcm7xxx_28nm_ephy_01_afe_config_init(struct phy_device *phydev) { int ret; @@ -392,6 +409,93 @@ return bcm7xxx_28nm_ephy_apd_enable(phydev); } +#define MII_BCM7XXX_REG_INVALID 0xff + +static u8 bcm7xxx_28nm_ephy_regnum_to_shd(u16 regnum) +{ + switch (regnum) { + case MDIO_CTRL1: + return MII_BCM7XXX_SHD_3_PCS_CTRL; + case MDIO_STAT1: + return MII_BCM7XXX_SHD_3_PCS_STATUS; + case MDIO_PCS_EEE_ABLE: + return MII_BCM7XXX_SHD_3_EEE_CAP; + case MDIO_AN_EEE_ADV: + return MII_BCM7XXX_SHD_3_AN_EEE_ADV; + case MDIO_AN_EEE_LPABLE: + return MII_BCM7XXX_SHD_3_EEE_LP; + case MDIO_PCS_EEE_WK_ERR: + return MII_BCM7XXX_SHD_3_EEE_WK_ERR; + default: + return MII_BCM7XXX_REG_INVALID; + } +} + +static bool bcm7xxx_28nm_ephy_dev_valid(int devnum) +{ + return devnum == MDIO_MMD_AN || devnum == MDIO_MMD_PCS; +} + +static int bcm7xxx_28nm_ephy_read_mmd(struct phy_device *phydev, + int devnum, u16 regnum) +{ + u8 shd = bcm7xxx_28nm_ephy_regnum_to_shd(regnum); + int ret; + + if (!bcm7xxx_28nm_ephy_dev_valid(devnum) || + shd == MII_BCM7XXX_REG_INVALID) + return -EOPNOTSUPP; + + /* set shadow mode 2 */ + ret = __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, + MII_BCM7XXX_SHD_MODE_2, 0); + if (ret < 0) + return ret; + + /* Access the desired shadow register address */ + ret = __phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd); + if (ret < 0) + goto reset_shadow_mode; + + ret = __phy_read(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT); + +reset_shadow_mode: + /* reset shadow mode 2 */ + __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, + MII_BCM7XXX_SHD_MODE_2); + return ret; +} + +static int bcm7xxx_28nm_ephy_write_mmd(struct phy_device *phydev, + int devnum, u16 regnum, u16 val) +{ + u8 shd = bcm7xxx_28nm_ephy_regnum_to_shd(regnum); + int ret; + + if (!bcm7xxx_28nm_ephy_dev_valid(devnum) || + shd == MII_BCM7XXX_REG_INVALID) + return -EOPNOTSUPP; + + /* set shadow mode 2 */ + ret = __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, + MII_BCM7XXX_SHD_MODE_2, 0); + if (ret < 0) + return ret; + + /* Access the desired shadow register address */ + ret = __phy_write(phydev, MII_BCM7XXX_SHD_2_ADDR_CTRL, shd); + if (ret < 0) + goto reset_shadow_mode; + + /* Write the desired value in the shadow register */ + __phy_write(phydev, MII_BCM7XXX_SHD_2_CTRL_STAT, val); + +reset_shadow_mode: + /* reset shadow mode 2 */ + return __phy_set_clr_bits(phydev, MII_BCM7XXX_TEST, 0, + MII_BCM7XXX_SHD_MODE_2); +} + static int bcm7xxx_28nm_ephy_resume(struct phy_device *phydev) { int ret; @@ -563,6 +667,8 @@ .get_strings = bcm_phy_get_strings, \ .get_stats = bcm7xxx_28nm_get_phy_stats, \ .probe = bcm7xxx_28nm_probe, \ + .read_mmd = bcm7xxx_28nm_ephy_read_mmd, \ + .write_mmd = bcm7xxx_28nm_ephy_write_mmd, \ } #define BCM7XXX_40NM_EPHY(_oui, _name) \ --- linux-oracle-5.4.0.orig/drivers/net/phy/broadcom.c +++ linux-oracle-5.4.0/drivers/net/phy/broadcom.c @@ -11,6 +11,7 @@ */ #include "bcm-phy-lib.h" +#include #include #include #include @@ -26,18 +27,13 @@ MODULE_AUTHOR("Maciej W. Rozycki"); MODULE_LICENSE("GPL"); +static int bcm54xx_config_clock_delay(struct phy_device *phydev); + static int bcm54210e_config_init(struct phy_device *phydev) { int val; - val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC); - val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN; - val |= MII_BCM54XX_AUXCTL_MISC_WREN; - bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val); - - val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL); - val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; - bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); + bcm54xx_config_clock_delay(phydev); if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) { val = phy_read(phydev, MII_CTRL1000); @@ -429,6 +425,17 @@ return err; } +static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum) +{ + return -EOPNOTSUPP; +} + +static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum, + u16 val) +{ + return -EOPNOTSUPP; +} + static int bcm5481_config_aneg(struct phy_device *phydev) { struct device_node *np = phydev->mdio.dev.of_node; @@ -484,6 +491,26 @@ if (err < 0) return err; + /* The datasheet indicates the PHY needs up to 1us to complete a reset, + * build some slack here. + */ + usleep_range(1000, 2000); + + /* The PHY requires 65 MDC clock cycles to complete a write operation + * and turnaround the line properly. + * + * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac) + * may flag the lack of turn-around as a read failure. This is + * particularly true with this combination since the MDIO controller + * only used 64 MDC cycles. This is not a critical failure in this + * specific case and it has no functional impact otherwise, so we let + * that one go through. If there is a genuine bus error, the next read + * of MII_BRCM_FET_INTREG will error out. + */ + err = phy_read(phydev, MII_BMCR); + if (err < 0 && err != -EIO) + return err; + reg = phy_read(phydev, MII_BRCM_FET_INTREG); if (reg < 0) return reg; @@ -651,6 +678,7 @@ .phy_id_mask = 0xfffffff0, .name = "Broadcom BCM54616S", /* PHY_GBIT_FEATURES */ + .soft_reset = genphy_soft_reset, .config_init = bcm54xx_config_init, .config_aneg = bcm54616s_config_aneg, .ack_interrupt = bcm_phy_ack_intr, @@ -679,6 +707,8 @@ .phy_id_mask = 0xfffffff0, .name = "Broadcom BCM54810", /* PHY_GBIT_FEATURES */ + .read_mmd = bcm54810_read_mmd, + .write_mmd = bcm54810_write_mmd, .config_init = bcm54xx_config_init, .config_aneg = bcm5481_config_aneg, .ack_interrupt = bcm_phy_ack_intr, --- linux-oracle-5.4.0.orig/drivers/net/phy/dp83640.c +++ linux-oracle-5.4.0/drivers/net/phy/dp83640.c @@ -1119,7 +1119,7 @@ goto out; } dp83640_clock_init(clock, bus); - list_add_tail(&phyter_clocks, &clock->list); + list_add_tail(&clock->list, &phyter_clocks); out: mutex_unlock(&phyter_clocks_lock); @@ -1348,6 +1348,7 @@ dp83640->hwts_rx_en = 1; dp83640->layer = PTP_CLASS_L4; dp83640->version = PTP_CLASS_V1; + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: @@ -1355,6 +1356,7 @@ dp83640->hwts_rx_en = 1; dp83640->layer = PTP_CLASS_L4; dp83640->version = PTP_CLASS_V2; + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: @@ -1362,6 +1364,7 @@ dp83640->hwts_rx_en = 1; dp83640->layer = PTP_CLASS_L2; dp83640->version = PTP_CLASS_V2; + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_SYNC: @@ -1369,6 +1372,7 @@ dp83640->hwts_rx_en = 1; dp83640->layer = PTP_CLASS_L4 | PTP_CLASS_L2; dp83640->version = PTP_CLASS_V2; + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; break; default: return -ERANGE; --- linux-oracle-5.4.0.orig/drivers/net/phy/dp83640_reg.h +++ linux-oracle-5.4.0/drivers/net/phy/dp83640_reg.h @@ -5,7 +5,7 @@ #ifndef HAVE_DP83640_REGISTERS #define HAVE_DP83640_REGISTERS -#define PAGE0 0x0000 +/* #define PAGE0 0x0000 */ #define PHYCR2 0x001c /* PHY Control Register 2 */ #define PAGE4 0x0004 --- linux-oracle-5.4.0.orig/drivers/net/phy/dp83822.c +++ linux-oracle-5.4.0/drivers/net/phy/dp83822.c @@ -197,9 +197,7 @@ if (misr_status < 0) return misr_status; - misr_status |= (DP83822_RX_ERR_HF_INT_EN | - DP83822_FALSE_CARRIER_HF_INT_EN | - DP83822_ANEG_COMPLETE_INT_EN | + misr_status |= (DP83822_ANEG_COMPLETE_INT_EN | DP83822_DUP_MODE_CHANGE_INT_EN | DP83822_SPEED_CHANGED_INT_EN | DP83822_LINK_STAT_INT_EN | @@ -238,7 +236,7 @@ if (err < 0) return err; - err = phy_write(phydev, MII_DP83822_MISR1, 0); + err = phy_write(phydev, MII_DP83822_MISR2, 0); if (err < 0) return err; --- linux-oracle-5.4.0.orig/drivers/net/phy/dp83867.c +++ linux-oracle-5.4.0/drivers/net/phy/dp83867.c @@ -25,7 +25,8 @@ #define DP83867_CFG3 0x1e /* Extended Registers */ -#define DP83867_CFG4 0x0031 +#define DP83867_FLD_THR_CFG 0x002e +#define DP83867_CFG4 0x0031 #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6)) #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5) #define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5) @@ -74,12 +75,14 @@ #define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK GENMASK(2, 0) #define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT 0 #define DP83867_STRAP_STS2_CLK_SKEW_NONE BIT(2) +#define DP83867_STRAP_STS2_STRAP_FLD BIT(10) /* PHY CTRL bits */ #define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14 #define DP83867_PHYCR_FIFO_DEPTH_MAX 0x03 #define DP83867_PHYCR_FIFO_DEPTH_MASK GENMASK(15, 14) #define DP83867_PHYCR_RESERVED_MASK BIT(11) +#define DP83867_PHYCR_FORCE_LINK_GOOD BIT(10) /* RGMIIDCTL bits */ #define DP83867_RGMII_TX_CLK_DELAY_MAX 0xf @@ -95,9 +98,16 @@ #define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK (0x1f << 8) #define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT 8 +/* CFG3 bits */ +#define DP83867_CFG3_INT_OE BIT(7) +#define DP83867_CFG3_ROBUST_AUTO_MDIX BIT(9) + /* CFG4 bits */ #define DP83867_CFG4_PORT_MIRROR_EN BIT(0) +/* FLD_THR_CFG */ +#define DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK 0x7 + enum { DP83867_PORT_MIRROING_KEEP, DP83867_PORT_MIRROING_EN, @@ -313,6 +323,20 @@ phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, BIT(7)); + bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2); + if (bs & DP83867_STRAP_STS2_STRAP_FLD) { + /* When using strap to enable FLD, the ENERGY_LOST_FLD_THR will + * be set to 0x2. This may causes the PHY link to be unstable - + * the default value 0x1 need to be restored. + */ + ret = phy_modify_mmd(phydev, DP83867_DEVADDR, + DP83867_FLD_THR_CFG, + DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK, + 0x1); + if (ret) + return ret; + } + if (phy_interface_is_rgmii(phydev)) { val = phy_read(phydev, MII_DP83867_PHYCTRL); if (val < 0) @@ -408,14 +432,23 @@ else val &= ~DP83867_SGMII_TYPE; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val); + + /* This is a SW workaround for link instability if RX_CTRL is + * not strapped to mode 3 or 4 in HW. This is required for SGMII + * in addition to clearing bit 7, handled above. + */ + if (dp83867->rxctrl_strap_quirk) + phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, + BIT(8)); } + val = phy_read(phydev, DP83867_CFG3); /* Enable Interrupt output INT_OE in CFG3 register */ - if (phy_interrupt_is_valid(phydev)) { - val = phy_read(phydev, DP83867_CFG3); - val |= BIT(7); - phy_write(phydev, DP83867_CFG3, val); - } + if (phy_interrupt_is_valid(phydev)) + val |= DP83867_CFG3_INT_OE; + + val |= DP83867_CFG3_ROBUST_AUTO_MDIX; + phy_write(phydev, DP83867_CFG3, val); if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) dp83867_config_port_mirroring(phydev); @@ -449,7 +482,8 @@ usleep_range(10, 20); - return 0; + return phy_modify(phydev, MII_DP83867_PHYCTRL, + DP83867_PHYCR_FORCE_LINK_GOOD, 0); } static struct phy_driver dp83867_driver[] = { --- linux-oracle-5.4.0.orig/drivers/net/phy/fixed_phy.c +++ linux-oracle-5.4.0/drivers/net/phy/fixed_phy.c @@ -212,16 +212,13 @@ */ gpiod = gpiod_get_from_of_node(fixed_link_node, "link-gpios", 0, GPIOD_IN, "mdio"); - of_node_put(fixed_link_node); - if (IS_ERR(gpiod)) { - if (PTR_ERR(gpiod) == -EPROBE_DEFER) - return gpiod; - + if (IS_ERR(gpiod) && PTR_ERR(gpiod) != -EPROBE_DEFER) { if (PTR_ERR(gpiod) != -ENOENT) pr_err("error getting GPIO for fixed link %pOF, proceed without\n", fixed_link_node); gpiod = NULL; } + of_node_put(fixed_link_node); return gpiod; } --- linux-oracle-5.4.0.orig/drivers/net/phy/intel-xway.c +++ linux-oracle-5.4.0/drivers/net/phy/intel-xway.c @@ -11,6 +11,18 @@ #define XWAY_MDIO_IMASK 0x19 /* interrupt mask */ #define XWAY_MDIO_ISTAT 0x1A /* interrupt status */ +#define XWAY_MDIO_LED 0x1B /* led control */ + +/* bit 15:12 are reserved */ +#define XWAY_MDIO_LED_LED3_EN BIT(11) /* Enable the integrated function of LED3 */ +#define XWAY_MDIO_LED_LED2_EN BIT(10) /* Enable the integrated function of LED2 */ +#define XWAY_MDIO_LED_LED1_EN BIT(9) /* Enable the integrated function of LED1 */ +#define XWAY_MDIO_LED_LED0_EN BIT(8) /* Enable the integrated function of LED0 */ +/* bit 7:4 are reserved */ +#define XWAY_MDIO_LED_LED3_DA BIT(3) /* Direct Access to LED3 */ +#define XWAY_MDIO_LED_LED2_DA BIT(2) /* Direct Access to LED2 */ +#define XWAY_MDIO_LED_LED1_DA BIT(1) /* Direct Access to LED1 */ +#define XWAY_MDIO_LED_LED0_DA BIT(0) /* Direct Access to LED0 */ #define XWAY_MDIO_INIT_WOL BIT(15) /* Wake-On-LAN */ #define XWAY_MDIO_INIT_MSRE BIT(14) @@ -159,6 +171,15 @@ /* Clear all pending interrupts */ phy_read(phydev, XWAY_MDIO_ISTAT); + /* Ensure that integrated led function is enabled for all leds */ + err = phy_write(phydev, XWAY_MDIO_LED, + XWAY_MDIO_LED_LED0_EN | + XWAY_MDIO_LED_LED1_EN | + XWAY_MDIO_LED_LED2_EN | + XWAY_MDIO_LED_LED3_EN); + if (err) + return err; + phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH, XWAY_MMD_LEDCH_NACS_NONE | XWAY_MMD_LEDCH_SBF_F02HZ | --- linux-oracle-5.4.0.orig/drivers/net/phy/marvell.c +++ linux-oracle-5.4.0/drivers/net/phy/marvell.c @@ -358,7 +358,7 @@ return marvell_config_aneg(phydev); } -#ifdef CONFIG_OF_MDIO +#if IS_ENABLED(CONFIG_OF_MDIO) /* Set and/or override some configuration registers based on the * marvell,reg-init property stored in the of_node for the phydev. * @@ -444,9 +444,9 @@ else mscr = 0; - return phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, - MII_88E1121_PHY_MSCR_REG, - MII_88E1121_PHY_MSCR_DELAY_MASK, mscr); + return phy_modify_paged_changed(phydev, MII_MARVELL_MSCR_PAGE, + MII_88E1121_PHY_MSCR_REG, + MII_88E1121_PHY_MSCR_DELAY_MASK, mscr); } static int m88e1121_config_aneg(struct phy_device *phydev) @@ -460,11 +460,13 @@ return err; } + changed = err; + err = marvell_set_polarity(phydev, phydev->mdix_ctrl); if (err < 0) return err; - changed = err; + changed |= err; err = genphy_config_aneg(phydev); if (err < 0) @@ -886,16 +888,15 @@ { int err; - err = genphy_soft_reset(phydev); + err = marvell_set_polarity(phydev, phydev->mdix_ctrl); if (err < 0) return err; - err = marvell_set_polarity(phydev, phydev->mdix_ctrl); + err = genphy_config_aneg(phydev); if (err < 0) return err; - err = genphy_config_aneg(phydev); - return 0; + return genphy_soft_reset(phydev); } static int m88e1118_config_init(struct phy_device *phydev) @@ -917,6 +918,12 @@ if (err < 0) return err; + if (phy_interface_is_rgmii(phydev)) { + err = m88e1121_config_aneg_rgmii_delays(phydev); + if (err < 0) + return err; + } + /* Adjust LED Control */ if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) err = phy_write(phydev, 0x10, 0x1100); @@ -1401,8 +1408,8 @@ int err; /* Suspend the fiber mode first */ - if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, - phydev->supported)) { + if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, + phydev->supported)) { err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); if (err < 0) goto error; @@ -1436,8 +1443,8 @@ int err; /* Resume the fiber mode first */ - if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, - phydev->supported)) { + if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, + phydev->supported)) { err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); if (err < 0) goto error; @@ -2401,9 +2408,31 @@ .get_stats = marvell_get_stats, }, { - .phy_id = MARVELL_PHY_ID_88E6390, + .phy_id = MARVELL_PHY_ID_88E6341_FAMILY, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E6341 Family", + /* PHY_GBIT_FEATURES */ + .probe = m88e1510_probe, + .config_init = &marvell_config_init, + .config_aneg = &m88e6390_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, + .did_interrupt = &m88e1121_did_interrupt, + .resume = &genphy_resume, + .suspend = &genphy_suspend, + .read_page = marvell_read_page, + .write_page = marvell_write_page, + .get_sset_count = marvell_get_sset_count, + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + .get_tunable = m88e1540_get_tunable, + .set_tunable = m88e1540_set_tunable, + }, + { + .phy_id = MARVELL_PHY_ID_88E6390_FAMILY, .phy_id_mask = MARVELL_PHY_ID_MASK, - .name = "Marvell 88E6390", + .name = "Marvell 88E6390 Family", /* PHY_GBIT_FEATURES */ .probe = m88e6390_probe, .config_init = &marvell_config_init, @@ -2441,7 +2470,8 @@ { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK }, { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK }, - { MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK }, { } }; --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-aspeed.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-aspeed.c @@ -61,6 +61,13 @@ iowrite32(ctrl, ctx->base + ASPEED_MDIO_CTRL); + rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_CTRL, ctrl, + !(ctrl & ASPEED_MDIO_CTRL_FIRE), + ASPEED_MDIO_INTERVAL_US, + ASPEED_MDIO_TIMEOUT_US); + if (rc < 0) + return rc; + rc = readl_poll_timeout(ctx->base + ASPEED_MDIO_DATA, data, data & ASPEED_MDIO_DATA_IDLE, ASPEED_MDIO_INTERVAL_US, @@ -141,6 +148,7 @@ { .compatible = "aspeed,ast2600-mdio", }, { }, }; +MODULE_DEVICE_TABLE(of, aspeed_mdio_of_match); static struct platform_driver aspeed_mdio_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-bcm-iproc.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-bcm-iproc.c @@ -178,6 +178,23 @@ return 0; } +#ifdef CONFIG_PM_SLEEP +int iproc_mdio_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct iproc_mdio_priv *priv = platform_get_drvdata(pdev); + + /* restore the mii clock configuration */ + iproc_mdio_config_clk(priv->base); + + return 0; +} + +static const struct dev_pm_ops iproc_mdio_pm_ops = { + .resume = iproc_mdio_resume +}; +#endif /* CONFIG_PM_SLEEP */ + static const struct of_device_id iproc_mdio_of_match[] = { { .compatible = "brcm,iproc-mdio", }, { /* sentinel */ }, @@ -188,6 +205,9 @@ .driver = { .name = "iproc-mdio", .of_match_table = iproc_mdio_of_match, +#ifdef CONFIG_PM_SLEEP + .pm = &iproc_mdio_pm_ops, +#endif }, .probe = iproc_mdio_probe, .remove = iproc_mdio_remove, --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-bcm-unimac.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-bcm-unimac.c @@ -242,11 +242,9 @@ return -ENOMEM; } - priv->clk = devm_clk_get(&pdev->dev, NULL); - if (PTR_ERR(priv->clk) == -EPROBE_DEFER) + priv->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); - else - priv->clk = NULL; ret = clk_prepare_enable(priv->clk); if (ret) --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-i2c.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-i2c.c @@ -10,10 +10,9 @@ * of their settings. */ #include +#include #include -#include "mdio-i2c.h" - /* * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is * specified to be present in SFP modules. These correspond with PHY --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-mux-bcm-iproc.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-mux-bcm-iproc.c @@ -288,8 +288,13 @@ static int mdio_mux_iproc_resume(struct device *dev) { struct iproc_mdiomux_desc *md = dev_get_drvdata(dev); + int rc; - clk_prepare_enable(md->core_clk); + rc = clk_prepare_enable(md->core_clk); + if (rc) { + dev_err(md->dev, "failed to enable core clk\n"); + return rc; + } mdio_mux_iproc_config(md); return 0; --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-mux-meson-g12a.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-mux-meson-g12a.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -148,6 +149,7 @@ static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv) { + u32 value; int ret; /* Enable the phy clock */ @@ -161,18 +163,25 @@ /* Initialize ephy control */ writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0); - writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | - FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | - FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | - PHY_CNTL1_CLK_EN | - PHY_CNTL1_CLKFREQ | - PHY_CNTL1_PHY_ENB, - priv->regs + ETH_PHY_CNTL1); + + /* Make sure we get a 0 -> 1 transition on the enable bit */ + value = FIELD_PREP(PHY_CNTL1_ST_MODE, 3) | + FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) | + FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) | + PHY_CNTL1_CLK_EN | + PHY_CNTL1_CLKFREQ; + writel(value, priv->regs + ETH_PHY_CNTL1); writel(PHY_CNTL2_USE_INTERNAL | PHY_CNTL2_SMI_SRC_MAC | PHY_CNTL2_RX_CLK_EPHY, priv->regs + ETH_PHY_CNTL2); + value |= PHY_CNTL1_PHY_ENB; + writel(value, priv->regs + ETH_PHY_CNTL1); + + /* The phy needs a bit of time to power up */ + mdelay(10); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-mux.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-mux.c @@ -82,6 +82,17 @@ static int parent_count; +static void mdio_mux_uninit_children(struct mdio_mux_parent_bus *pb) +{ + struct mdio_mux_child_bus *cb = pb->children; + + while (cb) { + mdiobus_unregister(cb->mii_bus); + mdiobus_free(cb->mii_bus); + cb = cb->next; + } +} + int mdio_mux_init(struct device *dev, struct device_node *mux_node, int (*switch_fn)(int cur, int desired, void *data), @@ -144,7 +155,7 @@ cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); if (!cb) { ret_val = -ENOMEM; - continue; + goto err_loop; } cb->bus_number = v; cb->parent = pb; @@ -152,8 +163,7 @@ cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { ret_val = -ENOMEM; - devm_kfree(dev, cb); - continue; + goto err_loop; } cb->mii_bus->priv = cb; @@ -165,11 +175,15 @@ cb->mii_bus->write = mdio_mux_write; r = of_mdiobus_register(cb->mii_bus, child_bus_node); if (r) { + mdiobus_free(cb->mii_bus); + if (r == -EPROBE_DEFER) { + ret_val = r; + goto err_loop; + } + devm_kfree(dev, cb); dev_err(dev, "Error: Failed to register MDIO bus for child %pOF\n", child_bus_node); - mdiobus_free(cb->mii_bus); - devm_kfree(dev, cb); } else { cb->next = pb->children; pb->children = cb; @@ -182,6 +196,10 @@ dev_err(dev, "Error: No acceptable child buses found\n"); devm_kfree(dev, pb); + +err_loop: + mdio_mux_uninit_children(pb); + of_node_put(child_bus_node); err_pb_kz: put_device(&parent_bus->dev); err_parent_bus: @@ -193,14 +211,8 @@ void mdio_mux_uninit(void *mux_handle) { struct mdio_mux_parent_bus *pb = mux_handle; - struct mdio_mux_child_bus *cb = pb->children; - - while (cb) { - mdiobus_unregister(cb->mii_bus); - mdiobus_free(cb->mii_bus); - cb = cb->next; - } + mdio_mux_uninit_children(pb); put_device(&pb->mii_bus->dev); } EXPORT_SYMBOL_GPL(mdio_mux_uninit); --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-octeon.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-octeon.c @@ -72,7 +72,6 @@ return 0; fail_register: - mdiobus_free(bus->mii_bus); smi_en.u64 = 0; oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); return err; @@ -86,7 +85,6 @@ bus = platform_get_drvdata(pdev); mdiobus_unregister(bus->mii_bus); - mdiobus_free(bus->mii_bus); smi_en.u64 = 0; oct_mdio_writeq(smi_en.u64, bus->register_base + SMI_EN); return 0; --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-thunder.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-thunder.c @@ -104,6 +104,7 @@ if (i >= ARRAY_SIZE(nexus->buses)) break; } + fwnode_handle_put(fwn); return 0; err_release_regions: @@ -126,7 +127,6 @@ continue; mdiobus_unregister(bus->mii_bus); - mdiobus_free(bus->mii_bus); oct_mdio_writeq(0, bus->register_base + SMI_EN); } pci_set_drvdata(pdev, NULL); --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio-xgene.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio-xgene.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,6 @@ #include #include #include -#include "mdio-xgene.h" static bool xgene_mdio_status; --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio_bus.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio_bus.c @@ -62,8 +62,8 @@ struct reset_control *reset = NULL; if (mdiodev->dev.of_node) - reset = devm_reset_control_get_exclusive(&mdiodev->dev, - "phy"); + reset = of_reset_control_get_exclusive(mdiodev->dev.of_node, + "phy"); if (IS_ERR(reset)) { if (PTR_ERR(reset) == -ENOENT || PTR_ERR(reset) == -ENOTSUPP) reset = NULL; @@ -107,6 +107,8 @@ if (mdiodev->bus->mdio_map[mdiodev->addr] != mdiodev) return -EINVAL; + reset_control_put(mdiodev->reset_ctrl); + mdiodev->bus->mdio_map[mdiodev->addr] = NULL; return 0; @@ -115,7 +117,12 @@ struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr) { - struct mdio_device *mdiodev = bus->mdio_map[addr]; + struct mdio_device *mdiodev; + + if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map)) + return NULL; + + mdiodev = bus->mdio_map[addr]; if (!mdiodev) return NULL; @@ -383,6 +390,13 @@ bus->dev.groups = NULL; dev_set_name(&bus->dev, "%s", bus->id); + /* We need to set state to MDIOBUS_UNREGISTERED to correctly release + * the device in mdiobus_free() + * + * State will be updated later in this function in case of success + */ + bus->state = MDIOBUS_UNREGISTERED; + err = device_register(&bus->dev); if (err) { pr_err("mii_bus %s failed to register\n", bus->id); @@ -410,7 +424,7 @@ bus->reset(bus); for (i = 0; i < PHY_MAX_ADDR; i++) { - if ((bus->phy_mask & (1 << i)) == 0) { + if ((bus->phy_mask & BIT(i)) == 0) { struct phy_device *phydev; phydev = mdiobus_scan(bus, i); @@ -424,7 +438,7 @@ mdiobus_setup_mdiodev_from_board_info(bus, mdiobus_create_device); bus->state = MDIOBUS_REGISTERED; - pr_info("%s: probed\n", bus->name); + dev_dbg(&bus->dev, "probed\n"); return 0; error: @@ -451,7 +465,8 @@ struct mdio_device *mdiodev; int i; - BUG_ON(bus->state != MDIOBUS_REGISTERED); + if (WARN_ON_ONCE(bus->state != MDIOBUS_REGISTERED)) + return; bus->state = MDIOBUS_UNREGISTERED; for (i = 0; i < PHY_MAX_ADDR; i++) { @@ -743,7 +758,6 @@ return ret; } -EXPORT_SYMBOL_GPL(mdio_bus_init); #if IS_ENABLED(CONFIG_PHYLIB) void mdio_bus_exit(void) --- linux-oracle-5.4.0.orig/drivers/net/phy/mdio_device.c +++ linux-oracle-5.4.0/drivers/net/phy/mdio_device.c @@ -180,6 +180,16 @@ return 0; } +static void mdio_shutdown(struct device *dev) +{ + struct mdio_device *mdiodev = to_mdio_device(dev); + struct device_driver *drv = mdiodev->dev.driver; + struct mdio_driver *mdiodrv = to_mdio_driver(drv); + + if (mdiodrv->shutdown) + mdiodrv->shutdown(mdiodev); +} + /** * mdio_driver_register - register an mdio_driver with the MDIO layer * @new_driver: new mdio_driver to register @@ -194,6 +204,7 @@ mdiodrv->driver.bus = &mdio_bus_type; mdiodrv->driver.probe = mdio_probe; mdiodrv->driver.remove = mdio_remove; + mdiodrv->driver.shutdown = mdio_shutdown; retval = driver_register(&mdiodrv->driver); if (retval) { --- linux-oracle-5.4.0.orig/drivers/net/phy/meson-gxl.c +++ linux-oracle-5.4.0/drivers/net/phy/meson-gxl.c @@ -235,6 +235,8 @@ .config_intr = meson_gxl_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, }, { PHY_ID_MATCH_EXACT(0x01803301), .name = "Meson G12A Internal PHY", @@ -245,6 +247,8 @@ .config_intr = meson_gxl_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, }, }; --- linux-oracle-5.4.0.orig/drivers/net/phy/micrel.c +++ linux-oracle-5.4.0/drivers/net/phy/micrel.c @@ -25,6 +25,7 @@ #include #include #include +#include /* Operation Mode Strap Override */ #define MII_KSZPHY_OMSO 0x16 @@ -281,7 +282,7 @@ } } - if (priv->led_mode >= 0) + if (priv->type && priv->led_mode >= 0) kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode); return 0; @@ -297,10 +298,10 @@ type = priv->type; - if (type->has_broadcast_disable) + if (type && type->has_broadcast_disable) kszphy_broadcast_disable(phydev); - if (type->has_nand_tree_disable) + if (type && type->has_nand_tree_disable) kszphy_nand_tree_disable(phydev); return kszphy_config_reset(phydev); @@ -342,11 +343,11 @@ } static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, - const u32 ksz_phy_id) + const bool ksz_8051) { int ret; - if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id) + if ((phydev->phy_id & MICREL_PHY_ID_MASK) != PHY_ID_KSZ8051) return 0; ret = phy_read(phydev, MII_BMSR); @@ -359,7 +360,7 @@ * the switch does not. */ ret &= BMSR_ERCAP; - if (ksz_phy_id == PHY_ID_KSZ8051) + if (ksz_8051) return ret; else return !ret; @@ -367,7 +368,7 @@ static int ksz8051_match_phy_device(struct phy_device *phydev) { - return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8051); + return ksz8051_ksz8795_match_phy_device(phydev, true); } static int ksz8081_config_init(struct phy_device *phydev) @@ -395,7 +396,7 @@ static int ksz8795_match_phy_device(struct phy_device *phydev) { - return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ87XX); + return ksz8051_ksz8795_match_phy_device(phydev, false); } static int ksz9021_load_values_from_of(struct phy_device *phydev, @@ -902,6 +903,12 @@ genphy_resume(phydev); + /* After switching from power-down to normal mode, an internal global + * reset is automatically generated. Wait a minimum of 1 ms before + * read/write access to the PHY registers. + */ + usleep_range(1000, 2000); + ret = kszphy_config_reset(phydev); if (ret) return ret; @@ -932,7 +939,7 @@ priv->type = type; - if (type->led_mode_reg) { + if (type && type->led_mode_reg) { ret = of_property_read_u32(np, "micrel,led-mode", &priv->led_mode); if (ret) @@ -953,7 +960,8 @@ unsigned long rate = clk_get_rate(clk); bool rmii_ref_clk_sel_25_mhz; - priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; + if (type) + priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; rmii_ref_clk_sel_25_mhz = of_property_read_bool(np, "micrel,rmii-reference-clock-select-25-mhz"); @@ -1033,8 +1041,9 @@ .get_sset_count = kszphy_get_sset_count, .get_strings = kszphy_get_strings, .get_stats = kszphy_get_stats, - .suspend = genphy_suspend, - .resume = genphy_resume, + /* No suspend/resume callbacks because of errata DS80000700A, + * receiver error following software power down. + */ }, { .phy_id = PHY_ID_KSZ8041RNLI, .phy_id_mask = MICREL_PHY_ID_MASK, @@ -1088,6 +1097,7 @@ .probe = kszphy_probe, .config_init = ksz8081_config_init, .ack_interrupt = kszphy_ack_interrupt, + .soft_reset = genphy_soft_reset, .config_intr = kszphy_config_intr, .get_sset_count = kszphy_get_sset_count, .get_strings = kszphy_get_strings, @@ -1140,14 +1150,28 @@ .suspend = genphy_suspend, .resume = kszphy_resume, }, { + .phy_id = PHY_ID_LAN8814, + .phy_id_mask = MICREL_PHY_ID_MASK, + .name = "Microchip INDY Gigabit Quad PHY", + .driver_data = &ksz9021_type, + .probe = kszphy_probe, + .soft_reset = genphy_soft_reset, + .read_status = ksz9031_read_status, + .get_sset_count = kszphy_get_sset_count, + .get_strings = kszphy_get_strings, + .get_stats = kszphy_get_stats, + .suspend = genphy_suspend, + .resume = kszphy_resume, +}, { .phy_id = PHY_ID_KSZ9131, .phy_id_mask = MICREL_PHY_ID_MASK, .name = "Microchip KSZ9131 Gigabit PHY", /* PHY_GBIT_FEATURES */ .driver_data = &ksz9021_type, .probe = kszphy_probe, + .soft_reset = genphy_soft_reset, .config_init = ksz9131_config_init, - .read_status = ksz9031_read_status, + .read_status = genphy_read_status, .ack_interrupt = kszphy_ack_interrupt, .config_intr = kszphy_config_intr, .get_sset_count = kszphy_get_sset_count, @@ -1177,8 +1201,6 @@ .name = "Micrel KSZ87XX Switch", /* PHY_BASIC_FEATURES */ .config_init = kszphy_config_init, - .config_aneg = ksz8873mll_config_aneg, - .read_status = ksz8873mll_read_status, .match_phy_device = ksz8795_match_phy_device, .suspend = genphy_suspend, .resume = genphy_resume, @@ -1212,6 +1234,8 @@ { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK }, { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK }, { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK }, + { PHY_ID_KSZ9477, MICREL_PHY_ID_MASK }, + { PHY_ID_LAN8814, MICREL_PHY_ID_MASK }, { } }; --- linux-oracle-5.4.0.orig/drivers/net/phy/microchip.c +++ linux-oracle-5.4.0/drivers/net/phy/microchip.c @@ -326,6 +326,37 @@ return genphy_config_aneg(phydev); } +static void lan88xx_link_change_notify(struct phy_device *phydev) +{ + int temp; + + /* At forced 100 F/H mode, chip may fail to set mode correctly + * when cable is switched between long(~50+m) and short one. + * As workaround, set to 10 before setting to 100 + * at forced 100 F/H mode. + */ + if (!phydev->autoneg && phydev->speed == 100) { + /* disable phy interrupt */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + + temp = phy_read(phydev, MII_BMCR); + temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); + phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ + temp |= BMCR_SPEED100; + phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ + + /* clear pending interrupt generated while workaround */ + temp = phy_read(phydev, LAN88XX_INT_STS); + + /* enable phy interrupt back */ + temp = phy_read(phydev, LAN88XX_INT_MASK); + temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; + phy_write(phydev, LAN88XX_INT_MASK, temp); + } +} + static struct phy_driver microchip_phy_driver[] = { { .phy_id = 0x0007c130, @@ -339,6 +370,7 @@ .config_init = lan88xx_config_init, .config_aneg = lan88xx_config_aneg, + .link_change_notify = lan88xx_link_change_notify, .ack_interrupt = lan88xx_phy_ack_interrupt, .config_intr = lan88xx_phy_config_intr, --- linux-oracle-5.4.0.orig/drivers/net/phy/microchip_t1.c +++ linux-oracle-5.4.0/drivers/net/phy/microchip_t1.c @@ -3,9 +3,21 @@ #include #include +#include #include #include +/* External Register Control Register */ +#define LAN87XX_EXT_REG_CTL (0x14) +#define LAN87XX_EXT_REG_CTL_RD_CTL (0x1000) +#define LAN87XX_EXT_REG_CTL_WR_CTL (0x0800) + +/* External Register Read Data Register */ +#define LAN87XX_EXT_REG_RD_DATA (0x15) + +/* External Register Write Data Register */ +#define LAN87XX_EXT_REG_WR_DATA (0x16) + /* Interrupt Source Register */ #define LAN87XX_INTERRUPT_SOURCE (0x18) @@ -14,9 +26,160 @@ #define LAN87XX_MASK_LINK_UP (0x0004) #define LAN87XX_MASK_LINK_DOWN (0x0002) +/* phyaccess nested types */ +#define PHYACC_ATTR_MODE_READ 0 +#define PHYACC_ATTR_MODE_WRITE 1 +#define PHYACC_ATTR_MODE_MODIFY 2 + +#define PHYACC_ATTR_BANK_SMI 0 +#define PHYACC_ATTR_BANK_MISC 1 +#define PHYACC_ATTR_BANK_PCS 2 +#define PHYACC_ATTR_BANK_AFE 3 +#define PHYACC_ATTR_BANK_MAX 7 + #define DRIVER_AUTHOR "Nisar Sayed " #define DRIVER_DESC "Microchip LAN87XX T1 PHY driver" +struct access_ereg_val { + u8 mode; + u8 bank; + u8 offset; + u16 val; + u16 mask; +}; + +static int access_ereg(struct phy_device *phydev, u8 mode, u8 bank, + u8 offset, u16 val) +{ + u16 ereg = 0; + int rc = 0; + + if (mode > PHYACC_ATTR_MODE_WRITE || bank > PHYACC_ATTR_BANK_MAX) + return -EINVAL; + + if (bank == PHYACC_ATTR_BANK_SMI) { + if (mode == PHYACC_ATTR_MODE_WRITE) + rc = phy_write(phydev, offset, val); + else + rc = phy_read(phydev, offset); + return rc; + } + + if (mode == PHYACC_ATTR_MODE_WRITE) { + ereg = LAN87XX_EXT_REG_CTL_WR_CTL; + rc = phy_write(phydev, LAN87XX_EXT_REG_WR_DATA, val); + if (rc < 0) + return rc; + } else { + ereg = LAN87XX_EXT_REG_CTL_RD_CTL; + } + + ereg |= (bank << 8) | offset; + + rc = phy_write(phydev, LAN87XX_EXT_REG_CTL, ereg); + if (rc < 0) + return rc; + + if (mode == PHYACC_ATTR_MODE_READ) + rc = phy_read(phydev, LAN87XX_EXT_REG_RD_DATA); + + return rc; +} + +static int access_ereg_modify_changed(struct phy_device *phydev, + u8 bank, u8 offset, u16 val, u16 mask) +{ + int new = 0, rc = 0; + + if (bank > PHYACC_ATTR_BANK_MAX) + return -EINVAL; + + rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, bank, offset, val); + if (rc < 0) + return rc; + + new = val | (rc & (mask ^ 0xFFFF)); + rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE, bank, offset, new); + + return rc; +} + +static int lan87xx_phy_init(struct phy_device *phydev) +{ + static const struct access_ereg_val init[] = { + /* TX Amplitude = 5 */ + {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_AFE, 0x0B, + 0x000A, 0x001E}, + /* Clear SMI interrupts */ + {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 0x18, + 0, 0}, + /* Clear MISC interrupts */ + {PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 0x08, + 0, 0}, + /* Turn on TC10 Ring Oscillator (ROSC) */ + {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_MISC, 0x20, + 0x0020, 0x0020}, + /* WUR Detect Length to 1.2uS, LPC Detect Length to 1.09uS */ + {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_PCS, 0x20, + 0x283C, 0}, + /* Wake_In Debounce Length to 39uS, Wake_Out Length to 79uS */ + {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x21, + 0x274F, 0}, + /* Enable Auto Wake Forward to Wake_Out, ROSC on, Sleep, + * and Wake_In to wake PHY + */ + {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x20, + 0x80A7, 0}, + /* Enable WUP Auto Fwd, Enable Wake on MDI, Wakeup Debouncer + * to 128 uS + */ + {PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x24, + 0xF110, 0}, + /* Enable HW Init */ + {PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_SMI, 0x1A, + 0x0100, 0x0100}, + }; + int rc, i; + + /* Start manual initialization procedures in Managed Mode */ + rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI, + 0x1a, 0x0000, 0x0100); + if (rc < 0) + return rc; + + /* Soft Reset the SMI block */ + rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI, + 0x00, 0x8000, 0x8000); + if (rc < 0) + return rc; + + /* Check to see if the self-clearing bit is cleared */ + usleep_range(1000, 2000); + rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ, + PHYACC_ATTR_BANK_SMI, 0x00, 0); + if (rc < 0) + return rc; + if ((rc & 0x8000) != 0) + return -ETIMEDOUT; + + /* PHY Initialization */ + for (i = 0; i < ARRAY_SIZE(init); i++) { + if (init[i].mode == PHYACC_ATTR_MODE_MODIFY) { + rc = access_ereg_modify_changed(phydev, init[i].bank, + init[i].offset, + init[i].val, + init[i].mask); + } else { + rc = access_ereg(phydev, init[i].mode, init[i].bank, + init[i].offset, init[i].val); + } + if (rc < 0) + return rc; + } + + return 0; +} + static int lan87xx_phy_config_intr(struct phy_device *phydev) { int rc, val = 0; @@ -40,6 +203,13 @@ return rc < 0 ? rc : 0; } +static int lan87xx_config_init(struct phy_device *phydev) +{ + int rc = lan87xx_phy_init(phydev); + + return rc < 0 ? rc : 0; +} + static struct phy_driver microchip_t1_phy_driver[] = { { .phy_id = 0x0007c150, @@ -48,6 +218,7 @@ .features = PHY_BASIC_T1_FEATURES, + .config_init = lan87xx_config_init, .config_aneg = genphy_config_aneg, .ack_interrupt = lan87xx_phy_ack_interrupt, --- linux-oracle-5.4.0.orig/drivers/net/phy/mscc.c +++ linux-oracle-5.4.0/drivers/net/phy/mscc.c @@ -302,11 +302,11 @@ BIT(VSC8531_FORCE_LED_OFF) | \ BIT(VSC8531_FORCE_LED_ON)) -#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin" +#define MSCC_VSC8584_REVB_INT8051_FW "microchip/mscc_vsc8584_revb_int8051_fb48.bin" #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800 #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 -#define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin" +#define MSCC_VSC8574_REVB_INT8051_FW "microchip/mscc_vsc8574_revb_int8051_29e8.bin" #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000 #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8 --- linux-oracle-5.4.0.orig/drivers/net/phy/phy-c45.c +++ linux-oracle-5.4.0/drivers/net/phy/phy-c45.c @@ -239,9 +239,10 @@ /* The link state is latched low so that momentary link * drops can be detected. Do not double-read the status - * in polling mode to detect such short link drops. + * in polling mode to detect such short link drops except + * the link was already down. */ - if (!phy_polling_mode(phydev)) { + if (!phy_polling_mode(phydev) || !phydev->link) { val = phy_read_mmd(phydev, devad, MDIO_STAT1); if (val < 0) return val; --- linux-oracle-5.4.0.orig/drivers/net/phy/phy-core.c +++ linux-oracle-5.4.0/drivers/net/phy/phy-core.c @@ -128,11 +128,11 @@ PHY_SETTING( 2500, FULL, 2500baseT_Full ), PHY_SETTING( 2500, FULL, 2500baseX_Full ), /* 1G */ - PHY_SETTING( 1000, FULL, 1000baseKX_Full ), PHY_SETTING( 1000, FULL, 1000baseT_Full ), PHY_SETTING( 1000, HALF, 1000baseT_Half ), PHY_SETTING( 1000, FULL, 1000baseT1_Full ), PHY_SETTING( 1000, FULL, 1000baseX_Full ), + PHY_SETTING( 1000, FULL, 1000baseKX_Full ), /* 100M */ PHY_SETTING( 100, FULL, 100baseT_Full ), PHY_SETTING( 100, FULL, 100baseT1_Full ), --- linux-oracle-5.4.0.orig/drivers/net/phy/phy.c +++ linux-oracle-5.4.0/drivers/net/phy/phy.c @@ -116,10 +116,15 @@ */ static int phy_clear_interrupt(struct phy_device *phydev) { - if (phydev->drv->ack_interrupt) - return phydev->drv->ack_interrupt(phydev); + int ret = 0; - return 0; + if (phydev->drv->ack_interrupt) { + mutex_lock(&phydev->lock); + ret = phydev->drv->ack_interrupt(phydev); + mutex_unlock(&phydev->lock); + } + + return ret; } /** @@ -345,15 +350,16 @@ phydev->autoneg = autoneg; - phydev->speed = speed; + if (autoneg == AUTONEG_DISABLE) { + phydev->speed = speed; + phydev->duplex = duplex; + } linkmode_copy(phydev->advertising, advertising); linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising, autoneg == AUTONEG_ENABLE); - phydev->duplex = duplex; - phydev->mdix_ctrl = cmd->base.eth_tp_mdix_ctrl; /* Restart the PHY */ @@ -366,6 +372,7 @@ void phy_ethtool_ksettings_get(struct phy_device *phydev, struct ethtool_link_ksettings *cmd) { + mutex_lock(&phydev->lock); linkmode_copy(cmd->link_modes.supported, phydev->supported); linkmode_copy(cmd->link_modes.advertising, phydev->advertising); linkmode_copy(cmd->link_modes.lp_advertising, phydev->lp_advertising); @@ -382,6 +389,7 @@ cmd->base.autoneg = phydev->autoneg; cmd->base.eth_tp_mdix_ctrl = phydev->mdix_ctrl; cmd->base.eth_tp_mdix = phydev->mdix; + mutex_unlock(&phydev->lock); } EXPORT_SYMBOL(phy_ethtool_ksettings_get); @@ -552,7 +560,7 @@ } /** - * phy_start_aneg - start auto-negotiation for this PHY device + * _phy_start_aneg - start auto-negotiation for this PHY device * @phydev: the phy_device struct * * Description: Sanitizes the settings (if we're not autonegotiating @@ -560,25 +568,43 @@ * If the PHYCONTROL Layer is operating, we change the state to * reflect the beginning of Auto-negotiation or forcing. */ -int phy_start_aneg(struct phy_device *phydev) +static int _phy_start_aneg(struct phy_device *phydev) { int err; + lockdep_assert_held(&phydev->lock); + if (!phydev->drv) return -EIO; - mutex_lock(&phydev->lock); - if (AUTONEG_DISABLE == phydev->autoneg) phy_sanitize_settings(phydev); err = phy_config_aneg(phydev); if (err < 0) - goto out_unlock; + return err; if (phy_is_started(phydev)) err = phy_check_link_status(phydev); -out_unlock: + + return err; +} + +/** + * phy_start_aneg - start auto-negotiation for this PHY device + * @phydev: the phy_device struct + * + * Description: Sanitizes the settings (if we're not autonegotiating + * them), and then calls the driver's config_aneg function. + * If the PHYCONTROL Layer is operating, we change the state to + * reflect the beginning of Auto-negotiation or forcing. + */ +int phy_start_aneg(struct phy_device *phydev) +{ + int err; + + mutex_lock(&phydev->lock); + err = _phy_start_aneg(phydev); mutex_unlock(&phydev->lock); return err; @@ -740,6 +766,36 @@ } /** + * phy_did_interrupt - Checks if the PHY generated an interrupt + * @phydev: target phy_device struct + */ +static int phy_did_interrupt(struct phy_device *phydev) +{ + int ret; + + mutex_lock(&phydev->lock); + ret = phydev->drv->did_interrupt(phydev); + mutex_unlock(&phydev->lock); + + return ret; +} + +/** + * phy_handle_interrupt - PHY specific interrupt handler + * @phydev: target phy_device struct + */ +static int phy_handle_interrupt(struct phy_device *phydev) +{ + int ret; + + mutex_lock(&phydev->lock); + ret = phydev->drv->handle_interrupt(phydev); + mutex_unlock(&phydev->lock); + + return ret; +} + +/** * phy_interrupt - PHY interrupt handler * @irq: interrupt line * @phy_dat: phy_device pointer @@ -750,18 +806,19 @@ { struct phy_device *phydev = phy_dat; - if (phydev->drv->did_interrupt && !phydev->drv->did_interrupt(phydev)) + if (phydev->drv->did_interrupt && !phy_did_interrupt(phydev)) return IRQ_NONE; if (phydev->drv->handle_interrupt) { - if (phydev->drv->handle_interrupt(phydev)) + if (phy_handle_interrupt(phydev)) goto phy_err; } else { /* reschedule state queue work to run as soon as possible */ phy_trigger_machine(phydev); } - if (phy_clear_interrupt(phydev)) + /* did_interrupt() may have cleared the interrupt already */ + if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev)) goto phy_err; return IRQ_HANDLED; @@ -833,7 +890,7 @@ */ void phy_stop(struct phy_device *phydev) { - if (!phy_is_started(phydev)) { + if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) { WARN(1, "called from state %s\n", phy_state_to_str(phydev->state)); return; @@ -1159,9 +1216,11 @@ /* Restart autonegotiation so the new modes get sent to the * link partner. */ - ret = phy_restart_aneg(phydev); - if (ret < 0) - return ret; + if (phydev->autoneg == AUTONEG_ENABLE) { + ret = phy_restart_aneg(phydev); + if (ret < 0) + return ret; + } } return 0; --- linux-oracle-5.4.0.orig/drivers/net/phy/phy_device.c +++ linux-oracle-5.4.0/drivers/net/phy/phy_device.c @@ -246,7 +246,7 @@ * MDIO bus driver and clock gated at this point. */ if (!netdev) - return !phydev->suspended; + goto out; if (netdev->wol_enabled) return false; @@ -266,7 +266,8 @@ if (device_may_wakeup(&netdev->dev)) return false; - return true; +out: + return !phydev->suspended; } static int mdio_bus_phy_suspend(struct device *dev) @@ -284,6 +285,8 @@ if (!mdio_bus_phy_may_suspend(phydev)) return 0; + phydev->suspended_by_mdio_bus = 1; + return phy_suspend(phydev); } @@ -292,9 +295,11 @@ struct phy_device *phydev = to_phy_device(dev); int ret; - if (!mdio_bus_phy_may_suspend(phydev)) + if (!phydev->suspended_by_mdio_bus) goto no_resume; + phydev->suspended_by_mdio_bus = 0; + ret = phy_resume(phydev); if (ret < 0) return ret; @@ -488,7 +493,7 @@ if (phydev->is_c45) { for (i = 1; i < num_ids; i++) { - if (!(phydev->c45_ids.devices_in_package & (1 << i))) + if (phydev->c45_ids.device_ids[i] == 0xffffffff) continue; if ((phydrv->phy_id & phydrv->phy_id_mask) == @@ -552,7 +557,7 @@ .pm = MDIO_BUS_PHY_PM_OPS, }; -static int phy_request_driver_module(struct phy_device *dev, int phy_id) +static int phy_request_driver_module(struct phy_device *dev, u32 phy_id) { int ret; @@ -564,15 +569,15 @@ * then modprobe isn't available. */ if (IS_ENABLED(CONFIG_MODULES) && ret < 0 && ret != -ENOENT) { - phydev_err(dev, "error %d loading PHY driver module for ID 0x%08x\n", - ret, phy_id); + phydev_err(dev, "error %d loading PHY driver module for ID 0x%08lx\n", + ret, (unsigned long)phy_id); return ret; } return 0; } -struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, +struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id, bool is_c45, struct phy_c45_device_ids *c45_ids) { @@ -596,8 +601,8 @@ mdiodev->device_free = phy_mdio_device_free; mdiodev->device_remove = phy_mdio_device_remove; - dev->speed = 0; - dev->duplex = -1; + dev->speed = SPEED_UNKNOWN; + dev->duplex = DUPLEX_UNKNOWN; dev->pause = 0; dev->asym_pause = 0; dev->link = 0; @@ -610,7 +615,9 @@ if (c45_ids) dev->c45_ids = *c45_ids; dev->irq = bus->irq[addr]; + dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr); + device_initialize(&mdiodev->dev); dev->state = PHY_DOWN; @@ -632,7 +639,7 @@ int i; for (i = 1; i < num_ids; i++) { - if (!(c45_ids->devices_in_package & (1 << i))) + if (c45_ids->device_ids[i] == 0xffffffff) continue; ret = phy_request_driver_module(dev, @@ -644,10 +651,8 @@ ret = phy_request_driver_module(dev, phy_id); } - if (!ret) { - device_initialize(&mdiodev->dev); - } else { - kfree(dev); + if (ret) { + put_device(&mdiodev->dev); dev = ERR_PTR(ret); } @@ -792,8 +797,10 @@ /* Grab the bits from PHYIR2, and put them in the lower half */ phy_reg = mdiobus_read(bus, addr, MII_PHYSID2); - if (phy_reg < 0) - return -EIO; + if (phy_reg < 0) { + /* returning -ENODEV doesn't stop bus scanning */ + return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO; + } *phy_id |= phy_reg; @@ -812,10 +819,13 @@ */ struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45) { - struct phy_c45_device_ids c45_ids = {0}; + struct phy_c45_device_ids c45_ids; u32 phy_id = 0; int r; + c45_ids.devices_in_package = 0; + memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids)); + r = get_phy_id(bus, addr, &phy_id, is_c45, &c45_ids); if (r) return ERR_PTR(r); @@ -1302,6 +1312,7 @@ error_module_put: module_put(d->driver->owner); + d->driver = NULL; error_put_device: put_device(d); if (ndev_owner != bus->owner) @@ -1411,7 +1422,8 @@ phy_led_triggers_unregister(phydev); - module_put(phydev->mdio.dev.driver->owner); + if (phydev->mdio.dev.driver) + module_put(phydev->mdio.dev.driver->owner); /* If the device had no specific driver before (i.e. - it * was using the generic driver), we unbind the device @@ -1422,6 +1434,9 @@ phy_driver_is_genphy_10g(phydev)) device_release_driver(&phydev->mdio.dev); + /* Assert the reset signal */ + phy_device_reset(phydev, 1); + /* * The phydev might go away on the put_device() below, so avoid * a use-after-free bug by reading the underlying bus first. @@ -1433,9 +1448,6 @@ ndev_owner = dev->dev.parent->driver->owner; if (ndev_owner != bus->owner) module_put(bus->owner); - - /* Assert the reset signal */ - phy_device_reset(phydev, 1); } EXPORT_SYMBOL(phy_detach); @@ -1755,9 +1767,10 @@ /* The link state is latched low so that momentary link * drops can be detected. Do not double-read the status - * in polling mode to detect such short link drops. + * in polling mode to detect such short link drops except + * the link was already down. */ - if (!phy_polling_mode(phydev)) { + if (!phy_polling_mode(phydev) || !phydev->link) { status = phy_read(phydev, MII_BMSR); if (status < 0) return status; --- linux-oracle-5.4.0.orig/drivers/net/phy/phylink.c +++ linux-oracle-5.4.0/drivers/net/phy/phylink.c @@ -444,8 +444,7 @@ pl->cur_interface = link_state.interface; pl->ops->mac_link_up(pl->config, pl->link_an_mode, - pl->phy_state.interface, - pl->phydev); + pl->cur_interface, pl->phydev); if (ndev) netif_carrier_on(ndev); @@ -583,6 +582,11 @@ return ret; } + if (!fwnode_device_is_available(ref.fwnode)) { + fwnode_handle_put(ref.fwnode); + return 0; + } + pl->sfp_bus = sfp_register_upstream(ref.fwnode, pl, &sfp_phylink_ops); if (!pl->sfp_bus) return -ENOMEM; @@ -1332,7 +1336,7 @@ return -EOPNOTSUPP; if (!phylink_test(pl->supported, Asym_Pause) && - !pause->autoneg && pause->rx_pause != pause->tx_pause) + pause->rx_pause != pause->tx_pause) return -EINVAL; config->pause &= ~(MLO_PAUSE_AN | MLO_PAUSE_TXRX_MASK); --- linux-oracle-5.4.0.orig/drivers/net/phy/realtek.c +++ linux-oracle-5.4.0/drivers/net/phy/realtek.c @@ -171,7 +171,9 @@ static int rtl8211f_config_init(struct phy_device *phydev) { + struct device *dev = &phydev->mdio.dev; u16 val; + int ret; /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin. @@ -189,7 +191,22 @@ return 0; } - return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val); + ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, + val); + if (ret < 0) { + dev_err(dev, "Failed to update the TX delay register\n"); + return ret; + } else if (ret) { + dev_dbg(dev, + "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", + val ? "Enabling" : "Disabling"); + } else { + dev_dbg(dev, + "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", + val ? "enabled" : "disabled"); + } + + return 0; } static int rtl8211e_config_init(struct phy_device *phydev) @@ -438,6 +455,15 @@ .suspend = genphy_suspend, .resume = genphy_resume, .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, + }, { + PHY_ID_MATCH_MODEL(0x001cc880), + .name = "RTL8208 Fast Ethernet", + .read_mmd = genphy_read_mmd_unsupported, + .write_mmd = genphy_write_mmd_unsupported, + .suspend = genphy_suspend, + .resume = genphy_resume, + .read_page = rtl821x_read_page, .write_page = rtl821x_write_page, }, { PHY_ID_MATCH_EXACT(0x001cc910), --- linux-oracle-5.4.0.orig/drivers/net/phy/sfp-bus.c +++ linux-oracle-5.4.0/drivers/net/phy/sfp-bus.c @@ -9,6 +9,12 @@ #include "sfp.h" +struct sfp_quirk { + const char *vendor; + const char *part; + void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes); +}; + /** * struct sfp_bus - internal representation of a sfp bus */ @@ -21,6 +27,7 @@ const struct sfp_socket_ops *socket_ops; struct device *sfp_dev; struct sfp *sfp; + const struct sfp_quirk *sfp_quirk; const struct sfp_upstream_ops *upstream_ops; void *upstream; @@ -30,6 +37,71 @@ bool started; }; +static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, + unsigned long *modes) +{ + phylink_set(modes, 2500baseX_Full); +} + +static const struct sfp_quirk sfp_quirks[] = { + { + // Alcatel Lucent G-010S-P can operate at 2500base-X, but + // incorrectly report 2500MBd NRZ in their EEPROM + .vendor = "ALCATELLUCENT", + .part = "G010SP", + .modes = sfp_quirk_2500basex, + }, { + // Alcatel Lucent G-010S-A can operate at 2500base-X, but + // report 3.2GBd NRZ in their EEPROM + .vendor = "ALCATELLUCENT", + .part = "3FE46541AA", + .modes = sfp_quirk_2500basex, + }, { + // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd + // NRZ in their EEPROM + .vendor = "HUAWEI", + .part = "MA5671A", + .modes = sfp_quirk_2500basex, + }, +}; + +static size_t sfp_strlen(const char *str, size_t maxlen) +{ + size_t size, i; + + /* Trailing characters should be filled with space chars */ + for (i = 0, size = 0; i < maxlen; i++) + if (str[i] != ' ') + size = i + 1; + + return size; +} + +static bool sfp_match(const char *qs, const char *str, size_t len) +{ + if (!qs) + return true; + if (strlen(qs) != len) + return false; + return !strncmp(qs, str, len); +} + +static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id) +{ + const struct sfp_quirk *q; + unsigned int i; + size_t vs, ps; + + vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name)); + ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn)); + + for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++) + if (sfp_match(q->vendor, id->base.vendor_name, vs) && + sfp_match(q->part, id->base.vendor_pn, ps)) + return q; + + return NULL; +} /** * sfp_parse_port() - Parse the EEPROM base ID, setting the port type * @bus: a pointer to the &struct sfp_bus structure for the sfp module @@ -233,6 +305,9 @@ phylink_set(modes, 1000baseX_Full); } + if (bus->sfp_quirk) + bus->sfp_quirk->modes(id, modes); + bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS); phylink_set(support, Autoneg); @@ -553,6 +628,8 @@ const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus); int ret = 0; + bus->sfp_quirk = sfp_lookup_quirk(id); + if (ops && ops->module_insert) ret = ops->module_insert(bus->upstream, id); @@ -566,6 +643,8 @@ if (ops && ops->module_remove) ops->module_remove(bus->upstream); + + bus->sfp_quirk = NULL; } EXPORT_SYMBOL_GPL(sfp_module_remove); --- linux-oracle-5.4.0.orig/drivers/net/phy/sfp.c +++ linux-oracle-5.4.0/drivers/net/phy/sfp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include -#include "mdio-i2c.h" #include "sfp.h" #include "swphy.h" @@ -115,7 +115,7 @@ [SFP_S_LINK_UP] = "link_up", [SFP_S_TX_FAULT] = "tx_fault", [SFP_S_REINIT] = "reinit", - [SFP_S_TX_DISABLE] = "rx_disable", + [SFP_S_TX_DISABLE] = "tx_disable", }; static const char *sm_state_to_str(unsigned short sm_state) @@ -1878,7 +1878,7 @@ platform_set_drvdata(pdev, sfp); - err = devm_add_action(sfp->dev, sfp_cleanup, sfp); + err = devm_add_action_or_reset(sfp->dev, sfp_cleanup, sfp); if (err < 0) return err; @@ -1970,7 +1970,8 @@ continue; sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]); - if (!sfp->gpio_irq[i]) { + if (sfp->gpio_irq[i] < 0) { + sfp->gpio_irq[i] = 0; poll = true; continue; } --- linux-oracle-5.4.0.orig/drivers/net/phy/smsc.c +++ linux-oracle-5.4.0/drivers/net/phy/smsc.c @@ -108,8 +108,11 @@ static int lan87xx_read_status(struct phy_device *phydev) { struct smsc_phy_priv *priv = phydev->priv; + int err; - int err = genphy_read_status(phydev); + err = genphy_read_status(phydev); + if (err) + return err; if (!phydev->link && priv->energy_enable) { int i; --- linux-oracle-5.4.0.orig/drivers/net/phy/vitesse.c +++ linux-oracle-5.4.0/drivers/net/phy/vitesse.c @@ -232,16 +232,6 @@ return 0; } -static int vsc73xx_config_aneg(struct phy_device *phydev) -{ - /* The VSC73xx switches does not like to be instructed to - * do autonegotiation in any way, it prefers that you just go - * with the power-on/reset defaults. Writing some registers will - * just make autonegotiation permanently fail. - */ - return 0; -} - /* This adds a skew for both TX and RX clocks, so the skew should only be * applied to "rgmii-id" interfaces. It may not work as expected * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces. */ @@ -424,7 +414,6 @@ .phy_id_mask = 0x000ffff0, /* PHY_GBIT_FEATURES */ .config_init = vsc738x_config_init, - .config_aneg = vsc73xx_config_aneg, .read_page = vsc73xx_read_page, .write_page = vsc73xx_write_page, }, { @@ -433,7 +422,6 @@ .phy_id_mask = 0x000ffff0, /* PHY_GBIT_FEATURES */ .config_init = vsc738x_config_init, - .config_aneg = vsc73xx_config_aneg, .read_page = vsc73xx_read_page, .write_page = vsc73xx_write_page, }, { @@ -442,7 +430,6 @@ .phy_id_mask = 0x000ffff0, /* PHY_GBIT_FEATURES */ .config_init = vsc739x_config_init, - .config_aneg = vsc73xx_config_aneg, .read_page = vsc73xx_read_page, .write_page = vsc73xx_write_page, }, { @@ -451,7 +438,6 @@ .phy_id_mask = 0x000ffff0, /* PHY_GBIT_FEATURES */ .config_init = vsc739x_config_init, - .config_aneg = vsc73xx_config_aneg, .read_page = vsc73xx_read_page, .write_page = vsc73xx_write_page, }, { --- linux-oracle-5.4.0.orig/drivers/net/phy/xilinx_gmii2rgmii.c +++ linux-oracle-5.4.0/drivers/net/phy/xilinx_gmii2rgmii.c @@ -82,6 +82,7 @@ if (!priv->phy_dev->drv) { dev_info(dev, "Attached phy not ready\n"); + put_device(&priv->phy_dev->mdio.dev); return -EPROBE_DEFER; } --- linux-oracle-5.4.0.orig/drivers/net/plip/plip.c +++ linux-oracle-5.4.0/drivers/net/plip/plip.c @@ -444,12 +444,12 @@ } rcv->state = PLIP_PK_DONE; if (rcv->skb) { - kfree_skb(rcv->skb); + dev_kfree_skb_irq(rcv->skb); rcv->skb = NULL; } snd->state = PLIP_PK_DONE; if (snd->skb) { - dev_kfree_skb(snd->skb); + dev_consume_skb_irq(snd->skb); snd->skb = NULL; } spin_unlock_irq(&nl->lock); @@ -1103,7 +1103,7 @@ /* Any address will do - we take the first. We already have the first two bytes filled with 0xfc, from plip_init_dev(). */ - const struct in_ifaddr *ifa = rcu_dereference(in_dev->ifa_list); + const struct in_ifaddr *ifa = rtnl_dereference(in_dev->ifa_list); if (ifa != NULL) { memcpy(dev->dev_addr+2, &ifa->ifa_local, 4); } --- linux-oracle-5.4.0.orig/drivers/net/ppp/ppp_async.c +++ linux-oracle-5.4.0/drivers/net/ppp/ppp_async.c @@ -470,6 +470,10 @@ case PPPIOCSMRU: if (get_user(val, p)) break; + if (val > U16_MAX) { + err = -EINVAL; + break; + } if (val < PPP_MRU) val = PPP_MRU; ap->mru = val; @@ -547,7 +551,7 @@ * and 7 (code-reject) must be sent as though no options * had been negotiated. */ - islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; + islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7; if (i == 0) { if (islcp) @@ -874,15 +878,15 @@ skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); if (!skb) goto nomem; - ap->rpkt = skb; - } - if (skb->len == 0) { - /* Try to get the payload 4-byte aligned. - * This should match the - * PPP_ALLSTATIONS/PPP_UI/compressed tests in - * process_input_packet, but we do not have - * enough chars here to test buf[1] and buf[2]. - */ + ap->rpkt = skb; + } + if (skb->len == 0) { + /* Try to get the payload 4-byte aligned. + * This should match the + * PPP_ALLSTATIONS/PPP_UI/compressed tests in + * process_input_packet, but we do not have + * enough chars here to test buf[1] and buf[2]. + */ if (buf[0] != PPP_ALLSTATIONS) skb_reserve(skb, 2 + (buf[0] & 1)); } --- linux-oracle-5.4.0.orig/drivers/net/ppp/ppp_generic.c +++ linux-oracle-5.4.0/drivers/net/ppp/ppp_generic.c @@ -69,6 +69,20 @@ #define MPHDRLEN 6 /* multilink protocol header length */ #define MPHDRLEN_SSN 4 /* ditto with short sequence numbers */ +#define PPP_PROTO_LEN 2 +#define PPP_LCP_HDRLEN 4 + +/* The filter instructions generated by libpcap are constructed + * assuming a four-byte PPP header on each packet, where the last + * 2 bytes are the protocol field defined in the RFC and the first + * byte of the first 2 bytes indicates the direction. + * The second byte is currently unused, but we still need to initialize + * it to prevent crafted BPF programs from reading them which would + * cause reading of uninitialized data. + */ +#define PPP_FILTER_OUTBOUND_TAG 0x0100 +#define PPP_FILTER_INBOUND_TAG 0x0000 + /* * An instance of /dev/ppp can be associated with either a ppp * interface unit or a ppp channel. In both cases, file->private_data @@ -283,7 +297,7 @@ static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); -static int unit_get(struct idr *p, void *ptr); +static int unit_get(struct idr *p, void *ptr, int min); static int unit_set(struct idr *p, void *ptr, int n); static void unit_put(struct idr *p, int n); static void *unit_find(struct idr *p, int n); @@ -489,6 +503,15 @@ return ret; } +static bool ppp_check_packet(struct sk_buff *skb, size_t count) +{ + /* LCP packets must include LCP header which 4 bytes long: + * 1-byte code, 1-byte identifier, and 2-byte length. + */ + return get_unaligned_be16(skb->data) != PPP_LCP || + count >= PPP_PROTO_LEN + PPP_LCP_HDRLEN; +} + static ssize_t ppp_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -498,6 +521,9 @@ if (!pf) return -ENXIO; + /* All PPP packets should start with the 2-byte protocol */ + if (count < PPP_PROTO_LEN) + return -EINVAL; ret = -ENOMEM; skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL); if (!skb) @@ -508,6 +534,11 @@ kfree_skb(skb); goto out; } + ret = -EINVAL; + if (unlikely(!ppp_check_packet(skb, count))) { + kfree_skb(skb); + goto out; + } switch (pf->kind) { case INTERFACE: @@ -959,9 +990,20 @@ mutex_lock(&pn->all_ppp_mutex); if (unit < 0) { - ret = unit_get(&pn->units_idr, ppp); + ret = unit_get(&pn->units_idr, ppp, 0); if (ret < 0) goto err; + if (!ifname_is_set) { + while (1) { + snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ret); + if (!__dev_get_by_name(ppp->ppp_net, ppp->dev->name)) + break; + unit_put(&pn->units_idr, ret); + ret = unit_get(&pn->units_idr, ppp, ret + 1); + if (ret < 0) + goto err; + } + } } else { /* Caller asked for a specific unit number. Fail with -EEXIST * if unavailable. For backward compatibility, return -EEXIST @@ -1110,7 +1152,7 @@ * the PPP unit identifer as suffix (i.e. ppp). This allows * userspace to infer the device name using to the PPPIOCGUNIT ioctl. */ - if (!tb[IFLA_IFNAME]) + if (!tb[IFLA_IFNAME] || !nla_len(tb[IFLA_IFNAME]) || !*(char *)nla_data(tb[IFLA_IFNAME])) conf.ifname_is_set = false; err = ppp_dev_configure(src_net, dev, &conf); @@ -1506,12 +1548,14 @@ int len; unsigned char *cp; + skb->dev = ppp->dev; + if (proto < 0x8000) { #ifdef CONFIG_PPP_FILTER - /* check if we should pass this packet */ - /* the filter instructions are constructed assuming - a four-byte PPP header on each packet */ - *(u8 *)skb_push(skb, 2) = 1; + /* check if the packet passes the pass and active filters. + * See comment for PPP_FILTER_OUTBOUND_TAG above. + */ + *(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_OUTBOUND_TAG); if (ppp->pass_filter && BPF_PROG_RUN(ppp->pass_filter, skb) == 0) { if (ppp->debug & 1) @@ -1533,7 +1577,7 @@ } ++ppp->stats64.tx_packets; - ppp->stats64.tx_bytes += skb->len - 2; + ppp->stats64.tx_bytes += skb->len - PPP_PROTO_LEN; switch (proto) { case PPP_IP: @@ -2190,14 +2234,13 @@ /* network protocol frame - give it to the kernel */ #ifdef CONFIG_PPP_FILTER - /* check if the packet passes the pass and active filters */ - /* the filter instructions are constructed assuming - a four-byte PPP header on each packet */ if (ppp->pass_filter || ppp->active_filter) { if (skb_unclone(skb, GFP_ATOMIC)) goto err; - - *(u8 *)skb_push(skb, 2) = 0; + /* Check if the packet passes the pass and active filters. + * See comment for PPP_FILTER_INBOUND_TAG above. + */ + *(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG); if (ppp->pass_filter && BPF_PROG_RUN(ppp->pass_filter, skb) == 0) { if (ppp->debug & 1) @@ -3294,9 +3337,9 @@ } /* get new free unit number and associate pointer with it */ -static int unit_get(struct idr *p, void *ptr) +static int unit_get(struct idr *p, void *ptr, int min) { - return idr_alloc(p, ptr, 0, 0, GFP_KERNEL); + return idr_alloc(p, ptr, min, 0, GFP_KERNEL); } /* put unit number back to a pool */ --- linux-oracle-5.4.0.orig/drivers/net/ppp/ppp_synctty.c +++ linux-oracle-5.4.0/drivers/net/ppp/ppp_synctty.c @@ -463,6 +463,10 @@ case PPPIOCSMRU: if (get_user(val, (int __user *) argp)) break; + if (val > U16_MAX) { + err = -EINVAL; + break; + } if (val < PPP_MRU) val = PPP_MRU; ap->mru = val; @@ -698,7 +702,7 @@ /* strip address/control field if present */ p = skb->data; - if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { + if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { /* chop off address/control */ if (skb->len < 3) goto err; --- linux-oracle-5.4.0.orig/drivers/net/ppp/pppoe.c +++ linux-oracle-5.4.0/drivers/net/ppp/pppoe.c @@ -492,6 +492,9 @@ if (!skb) goto out; + if (skb->pkt_type != PACKET_HOST) + goto abort; + if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) goto abort; --- linux-oracle-5.4.0.orig/drivers/net/slip/slhc.c +++ linux-oracle-5.4.0/drivers/net/slip/slhc.c @@ -232,7 +232,7 @@ struct cstate *cs = lcs->next; unsigned long deltaS, deltaA; short changes = 0; - int hlen; + int nlen, hlen; unsigned char new_seq[16]; unsigned char *cp = new_seq; struct iphdr *ip; @@ -248,6 +248,8 @@ return isize; ip = (struct iphdr *) icp; + if (ip->version != 4 || ip->ihl < 5) + return isize; /* Bail if this packet isn't TCP, or is an IP fragment */ if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { @@ -258,10 +260,14 @@ comp->sls_o_tcp++; return isize; } - /* Extract TCP header */ + nlen = ip->ihl * 4; + if (isize < nlen + sizeof(*th)) + return isize; - th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); - hlen = ip->ihl*4 + th->doff*4; + th = (struct tcphdr *)(icp + nlen); + if (th->doff < sizeof(struct tcphdr) / 4) + return isize; + hlen = nlen + th->doff * 4; /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or * some other control bit is set). Also uncompressible if @@ -637,46 +643,57 @@ int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) { - struct cstate *cs; - unsigned ihl; - + const struct tcphdr *th; unsigned char index; + struct iphdr *iph; + struct cstate *cs; + unsigned int ihl; - if(isize < 20) { - /* The packet is shorter than a legal IP header */ + /* The packet is shorter than a legal IP header. + * Also make sure isize is positive. + */ + if (isize < (int)sizeof(struct iphdr)) { +runt: comp->sls_i_runt++; - return slhc_toss( comp ); + return slhc_toss(comp); } + iph = (struct iphdr *)icp; /* Peek at the IP header's IHL field to find its length */ - ihl = icp[0] & 0xf; - if(ihl < 20 / 4){ - /* The IP header length field is too small */ - comp->sls_i_runt++; - return slhc_toss( comp ); - } - index = icp[9]; - icp[9] = IPPROTO_TCP; + ihl = iph->ihl; + /* The IP header length field is too small, + * or packet is shorter than the IP header followed + * by minimal tcp header. + */ + if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr)) + goto runt; + + index = iph->protocol; + iph->protocol = IPPROTO_TCP; if (ip_fast_csum(icp, ihl)) { /* Bad IP header checksum; discard */ comp->sls_i_badcheck++; - return slhc_toss( comp ); + return slhc_toss(comp); } - if(index > comp->rslot_limit) { + if (index > comp->rslot_limit) { comp->sls_i_error++; return slhc_toss(comp); } - + th = (struct tcphdr *)(icp + ihl * 4); + if (th->doff < sizeof(struct tcphdr) / 4) + goto runt; + if (isize < ihl * 4 + th->doff * 4) + goto runt; /* Update local state */ cs = &comp->rstate[comp->recv_current = index]; comp->flags &=~ SLF_TOSS; - memcpy(&cs->cs_ip,icp,20); - memcpy(&cs->cs_tcp,icp + ihl*4,20); + memcpy(&cs->cs_ip, iph, sizeof(*iph)); + memcpy(&cs->cs_tcp, th, sizeof(*th)); if (ihl > 5) - memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); - if (cs->cs_tcp.doff > 5) - memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); - cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; + memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4); + if (th->doff > 5) + memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4); + cs->cs_hsize = ihl*2 + th->doff*2; cs->initialized = true; /* Put headers back on packet * Neither header checksum is recalculated --- linux-oracle-5.4.0.orig/drivers/net/slip/slip.c +++ linux-oracle-5.4.0/drivers/net/slip/slip.c @@ -452,9 +452,16 @@ */ static void slip_write_wakeup(struct tty_struct *tty) { - struct slip *sl = tty->disc_data; + struct slip *sl; + + rcu_read_lock(); + sl = rcu_dereference(tty->disc_data); + if (!sl) + goto out; schedule_work(&sl->tx_work); +out: + rcu_read_unlock(); } static void sl_tx_timeout(struct net_device *dev) @@ -464,7 +471,7 @@ spin_lock(&sl->lock); if (netif_queue_stopped(dev)) { - if (!netif_running(dev)) + if (!netif_running(dev) || !sl->tty) goto out; /* May be we must check transmitter timeout here ? @@ -855,7 +862,11 @@ sl->tty = NULL; tty->disc_data = NULL; clear_bit(SLF_INUSE, &sl->flags); + sl_free_netdev(sl->dev); + /* do not call free_netdev before rtnl_unlock */ + rtnl_unlock(); free_netdev(sl->dev); + return err; err_exit: rtnl_unlock(); @@ -881,10 +892,11 @@ return; spin_lock_bh(&sl->lock); - tty->disc_data = NULL; + rcu_assign_pointer(tty->disc_data, NULL); sl->tty = NULL; spin_unlock_bh(&sl->lock); + synchronize_rcu(); flush_work(&sl->tx_work); /* VSV = very important to remove timers */ --- linux-oracle-5.4.0.orig/drivers/net/sungem_phy.c +++ linux-oracle-5.4.0/drivers/net/sungem_phy.c @@ -454,6 +454,7 @@ int can_low_power = 1; if (np == NULL || of_get_property(np, "no-autolowpower", NULL)) can_low_power = 0; + of_node_put(np); if (can_low_power) { /* Enable automatic low-power */ sungem_phy_write(phy, 0x1c, 0x9002); --- linux-oracle-5.4.0.orig/drivers/net/tap.c +++ linux-oracle-5.4.0/drivers/net/tap.c @@ -525,7 +525,7 @@ q->sock.state = SS_CONNECTED; q->sock.file = file; q->sock.ops = &tap_socket_ops; - sock_init_data(&q->sock, &q->sk); + sock_init_data_uid(&q->sock, &q->sk, current_fsuid()); q->sk.sk_write_space = tap_sock_write_space; q->sk.sk_destruct = tap_sock_destruct; q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; @@ -715,9 +715,8 @@ skb_probe_transport_header(skb); /* Move network header to the right position for VLAN tagged packets */ - if ((skb->protocol == htons(ETH_P_8021Q) || - skb->protocol == htons(ETH_P_8021AD)) && - __vlan_get_protocol(skb, skb->protocol, &depth) != 0) + if (eth_type_vlan(skb->protocol) && + vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0) skb_set_network_header(skb, depth); rcu_read_lock(); @@ -1095,10 +1094,9 @@ return -ENOLINK; } ret = 0; - u = tap->dev->type; + dev_get_mac_address(&sa, dev_net(tap->dev), tap->dev->name); if (copy_to_user(&ifr->ifr_name, tap->dev->name, IFNAMSIZ) || - copy_to_user(&ifr->ifr_hwaddr.sa_data, tap->dev->dev_addr, ETH_ALEN) || - put_user(u, &ifr->ifr_hwaddr.sa_family)) + copy_to_user(&ifr->ifr_hwaddr, &sa, sizeof(sa))) ret = -EFAULT; tap_put_tap_dev(tap); rtnl_unlock(); @@ -1113,7 +1111,7 @@ rtnl_unlock(); return -ENOLINK; } - ret = dev_set_mac_address(tap->dev, &sa, NULL); + ret = dev_set_mac_address_user(tap->dev, &sa, NULL); tap_put_tap_dev(tap); rtnl_unlock(); return ret; @@ -1155,6 +1153,11 @@ struct sk_buff *skb; int err, depth; + if (unlikely(xdp->data_end - xdp->data < ETH_HLEN)) { + err = -EINVAL; + goto err; + } + if (q->flags & IFF_VNET_HDR) vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz); @@ -1178,9 +1181,8 @@ } /* Move network header to the right position for VLAN tagged packets */ - if ((skb->protocol == htons(ETH_P_8021Q) || - skb->protocol == htons(ETH_P_8021AD)) && - __vlan_get_protocol(skb, skb->protocol, &depth) != 0) + if (eth_type_vlan(skb->protocol) && + vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0) skb_set_network_header(skb, depth); rcu_read_lock(); @@ -1215,7 +1217,8 @@ struct xdp_buff *xdp; int i; - if (ctl && (ctl->type == TUN_MSG_PTR)) { + if (m->msg_controllen == sizeof(struct tun_msg_ctl) && + ctl && ctl->type == TUN_MSG_PTR) { for (i = 0; i < ctl->num; i++) { xdp = &((struct xdp_buff *)ctl->ptr)[i]; tap_get_user_xdp(q, xdp); --- linux-oracle-5.4.0.orig/drivers/net/team/team.c +++ linux-oracle-5.4.0/drivers/net/team/team.c @@ -284,10 +284,12 @@ return 0; inst_rollback: - for (i--; i >= 0; i--) + for (i--; i >= 0; i--) { __team_option_inst_del_option(team, dst_opts[i]); + list_del(&dst_opts[i]->list); + } - i = option_count - 1; + i = option_count; alloc_rollback: for (i--; i >= 0; i--) kfree(dst_opts[i]); @@ -468,6 +470,9 @@ struct team_mode_item *mitem; const struct team_mode *mode = NULL; + if (!try_module_get(THIS_MODULE)) + return NULL; + spin_lock(&mode_list_lock); mitem = __find_mode(kind); if (!mitem) { @@ -483,6 +488,7 @@ } spin_unlock(&mode_list_lock); + module_put(THIS_MODULE); return mode; } @@ -987,7 +993,8 @@ unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; - list_for_each_entry(port, &team->port_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(port, &team->port_list, list) { vlan_features = netdev_increment_features(vlan_features, port->dev->vlan_features, TEAM_VLAN_FEATURES); @@ -1001,6 +1008,7 @@ if (port->dev->hard_header_len > max_hard_header_len) max_hard_header_len = port->dev->hard_header_len; } + rcu_read_unlock(); team->dev->vlan_features = vlan_features; team->dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | @@ -1016,9 +1024,7 @@ static void team_compute_features(struct team *team) { - mutex_lock(&team->lock); __team_compute_features(team); - mutex_unlock(&team->lock); netdev_change_features(team->dev); } @@ -1159,6 +1165,13 @@ return -EBUSY; } + if (netdev_has_upper_dev(port_dev, dev)) { + NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface"); + netdev_err(dev, "Device %s is already a lower device of the team interface\n", + portname); + return -EBUSY; + } + if (port_dev->features & NETIF_F_VLAN_CHALLENGED && vlan_uses_dev(dev)) { NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up"); @@ -1266,10 +1279,12 @@ } } - netif_addr_lock_bh(dev); - dev_uc_sync_multiple(port_dev, dev); - dev_mc_sync_multiple(port_dev, dev); - netif_addr_unlock_bh(dev); + if (dev->flags & IFF_UP) { + netif_addr_lock_bh(dev); + dev_uc_sync_multiple(port_dev, dev); + dev_mc_sync_multiple(port_dev, dev); + netif_addr_unlock_bh(dev); + } port->index = -1; list_add_tail_rcu(&port->list, &team->port_list); @@ -1340,8 +1355,10 @@ netdev_rx_handler_unregister(port_dev); team_port_disable_netpoll(port); vlan_vids_del_by_dev(port_dev, dev); - dev_uc_unsync(port_dev, dev); - dev_mc_unsync(port_dev, dev); + if (dev->flags & IFF_UP) { + dev_uc_unsync(port_dev, dev); + dev_mc_unsync(port_dev, dev); + } dev_close(port_dev); team_port_leave(team, port); @@ -1616,6 +1633,7 @@ team->dev = dev; team_set_no_mode(team); + team->notifier_ctx = false; team->pcpu_stats = netdev_alloc_pcpu_stats(struct team_pcpu_stats); if (!team->pcpu_stats) @@ -1690,6 +1708,14 @@ static int team_close(struct net_device *dev) { + struct team *team = netdev_priv(dev); + struct team_port *port; + + list_for_each_entry(port, &team->port_list, list) { + dev_uc_unsync(port->dev, dev); + dev_mc_unsync(port->dev, dev); + } + return 0; } @@ -2074,7 +2100,8 @@ cmd->base.duplex = DUPLEX_UNKNOWN; cmd->base.port = PORT_OTHER; - list_for_each_entry(port, &team->port_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(port, &team->port_list, list) { if (team_port_txable(port)) { if (port->state.speed != SPEED_UNKNOWN) speed += port->state.speed; @@ -2083,6 +2110,8 @@ cmd->base.duplex = port->state.duplex; } } + rcu_read_unlock(); + cmd->base.speed = speed ? : SPEED_UNKNOWN; return 0; @@ -2101,13 +2130,28 @@ static void team_setup_by_port(struct net_device *dev, struct net_device *port_dev) { - dev->header_ops = port_dev->header_ops; + struct team *team = netdev_priv(dev); + + if (port_dev->type == ARPHRD_ETHER) + dev->header_ops = team->header_ops_cache; + else + dev->header_ops = port_dev->header_ops; dev->type = port_dev->type; dev->hard_header_len = port_dev->hard_header_len; + dev->needed_headroom = port_dev->needed_headroom; dev->addr_len = port_dev->addr_len; dev->mtu = port_dev->mtu; memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); eth_hw_addr_inherit(dev, port_dev); + + if (port_dev->flags & IFF_POINTOPOINT) { + dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == + (IFF_BROADCAST | IFF_MULTICAST)) { + dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); + dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); + } } static int team_dev_type_check_change(struct net_device *dev, @@ -2138,8 +2182,11 @@ static void team_setup(struct net_device *dev) { + struct team *team = netdev_priv(dev); + ether_setup(dev); dev->max_mtu = ETH_MAX_MTU; + team->header_ops_cache = dev->header_ops; dev->netdev_ops = &team_netdev_ops; dev->ethtool_ops = &team_ethtool_ops; @@ -2164,7 +2211,9 @@ dev->hw_features = TEAM_VLAN_FEATURES | NETIF_F_HW_VLAN_CTAG_RX | - NETIF_F_HW_VLAN_CTAG_FILTER; + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_STAG_RX | + NETIF_F_HW_VLAN_STAG_FILTER; dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4; dev->features |= dev->hw_features; @@ -2237,6 +2286,8 @@ [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, + [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, + [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, }; static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) @@ -2612,7 +2663,9 @@ ctx.data.u32_val = nla_get_u32(attr_data); break; case TEAM_OPTION_TYPE_STRING: - if (nla_len(attr_data) > TEAM_STRING_MAX_LEN) { + if (nla_len(attr_data) > TEAM_STRING_MAX_LEN || + !memchr(nla_data(attr_data), '\0', + nla_len(attr_data))) { err = -EINVAL; goto team_put; } @@ -2993,7 +3046,11 @@ team_del_slave(port->team->dev, dev); break; case NETDEV_FEAT_CHANGE: - team_compute_features(port->team); + if (!port->team->notifier_ctx) { + port->team->notifier_ctx = true; + team_compute_features(port->team); + port->team->notifier_ctx = false; + } break; case NETDEV_PRECHANGEMTU: /* Forbid to change mtu of underlaying device */ --- linux-oracle-5.4.0.orig/drivers/net/thunderbolt.c +++ linux-oracle-5.4.0/drivers/net/thunderbolt.c @@ -958,12 +958,11 @@ *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 0, ip_hdr(skb)->protocol, 0); - } else if (skb_is_gso_v6(skb)) { + } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); - return false; } else if (protocol == htons(ETH_P_IPV6)) { tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, @@ -1339,12 +1338,21 @@ TBNET_MATCH_FRAGS_ID); ret = tb_register_property_dir("network", tbnet_dir); - if (ret) { - tb_property_free_dir(tbnet_dir); - return ret; - } + if (ret) + goto err_free_dir; + + ret = tb_register_service_driver(&tbnet_driver); + if (ret) + goto err_unregister; + + return 0; + +err_unregister: + tb_unregister_property_dir("network", tbnet_dir); +err_free_dir: + tb_property_free_dir(tbnet_dir); - return tb_register_service_driver(&tbnet_driver); + return ret; } module_init(tbnet_init); --- linux-oracle-5.4.0.orig/drivers/net/tun.c +++ linux-oracle-5.4.0/drivers/net/tun.c @@ -68,6 +68,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -242,6 +250,9 @@ struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; struct ethtool_link_ksettings link_ksettings; + /* init args */ + struct file *file; + struct ifreq *ifr; }; struct veth { @@ -267,6 +278,9 @@ } EXPORT_SYMBOL(tun_ptr_to_xdp); +static void tun_flow_init(struct tun_struct *tun); +static void tun_flow_uninit(struct tun_struct *tun); + static int tun_napi_receive(struct napi_struct *napi, int budget) { struct tun_file *tfile = container_of(napi, struct tun_file, napi); @@ -313,12 +327,18 @@ tfile->napi_enabled = napi_en; tfile->napi_frags_enabled = napi_en && napi_frags; if (napi_en) { - netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll, - NAPI_POLL_WEIGHT); + netif_tx_napi_add(tun->dev, &tfile->napi, tun_napi_poll, + NAPI_POLL_WEIGHT); napi_enable(&tfile->napi); } } +static void tun_napi_enable(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + napi_enable(&tfile->napi); +} + static void tun_napi_disable(struct tun_file *tfile) { if (tfile->napi_enabled) @@ -622,7 +642,7 @@ struct net *net = dev_net(tun->dev); return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) || - (gid_valid(tun->group) && !in_egroup_p(tun->group))) && + (gid_valid(tun->group) && !in_egroup_p(tun->group))) && !ns_capable(net->user_ns, CAP_NET_ADMIN); } @@ -682,7 +702,8 @@ tun = rtnl_dereference(tfile->tun); if (tun && clean) { - tun_napi_disable(tfile); + if (!tfile->detached) + tun_napi_disable(tfile); tun_napi_del(tfile); } @@ -694,6 +715,7 @@ tun->tfiles[tun->numqueues - 1]); ntfile = rtnl_dereference(tun->tfiles[index]); ntfile->queue_index = index; + ntfile->xdp_rxq.queue_index = index; rcu_assign_pointer(tun->tfiles[tun->numqueues - 1], NULL); @@ -701,8 +723,10 @@ if (clean) { RCU_INIT_POINTER(tfile->tun, NULL); sock_put(&tfile->sk); - } else + } else { tun_disable_queue(tun, tfile); + tun_napi_disable(tfile); + } synchronize_net(); tun_flow_delete_by_queue(tun, tun->numqueues + 1); @@ -725,7 +749,6 @@ if (tun) xdp_rxq_info_unreg(&tfile->xdp_rxq); ptr_ring_cleanup(&tfile->tx_ring, tun_ptr_free); - sock_put(&tfile->sk); } } @@ -741,6 +764,9 @@ if (dev) netdev_state_change(dev); rtnl_unlock(); + + if (clean) + sock_put(&tfile->sk); } static void tun_detach_all(struct net_device *dev) @@ -775,6 +801,7 @@ sock_put(&tfile->sk); } list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { + tun_napi_del(tfile); tun_enable_queue(tfile); tun_queue_purge(tfile); xdp_rxq_info_unreg(&tfile->xdp_rxq); @@ -855,6 +882,7 @@ if (tfile->detached) { tun_enable_queue(tfile); + tun_napi_enable(tfile); } else { sock_hold(&tfile->sk); tun_napi_init(tun, tfile, napi, napi_frags); @@ -1006,6 +1034,49 @@ static const struct ethtool_ops tun_ethtool_ops; +static int tun_net_init(struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + struct ifreq *ifr = tun->ifr; + int err; + + tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); + if (!tun->pcpu_stats) + return -ENOMEM; + + spin_lock_init(&tun->lock); + + err = security_tun_dev_alloc_security(&tun->security); + if (err < 0) { + free_percpu(tun->pcpu_stats); + return err; + } + + tun_flow_init(tun); + + dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | + TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX; + dev->features = dev->hw_features | NETIF_F_LLTX; + dev->vlan_features = dev->features & + ~(NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_HW_VLAN_STAG_TX); + + tun->flags = (tun->flags & ~TUN_FEATURES) | + (ifr->ifr_flags & TUN_FEATURES); + + INIT_LIST_HEAD(&tun->disabled); + err = tun_attach(tun, tun->file, false, ifr->ifr_flags & IFF_NAPI, + ifr->ifr_flags & IFF_NAPI_FRAGS, false); + if (err < 0) { + tun_flow_uninit(tun); + security_tun_dev_free_security(tun->security); + free_percpu(tun->pcpu_stats); + return err; + } + return 0; +} + /* Net device detach from fd. */ static void tun_net_uninit(struct net_device *dev) { @@ -1063,6 +1134,7 @@ { struct tun_struct *tun = netdev_priv(dev); int txq = skb->queue_mapping; + struct netdev_queue *queue; struct tun_file *tfile; int len = skb->len; @@ -1109,6 +1181,10 @@ if (ptr_ring_produce(&tfile->tx_ring, skb)) goto drop; + /* NETIF_F_LLTX requires to do our own update of trans_start */ + queue = netdev_get_tx_queue(dev, txq); + queue->trans_start = jiffies; + /* Notify and wake up reader process */ if (tfile->flags & TUN_FASYNC) kill_fasync(&tfile->fasync, SIGIO, POLL_IN); @@ -1259,6 +1335,7 @@ } static const struct net_device_ops tun_netdev_ops = { + .ndo_init = tun_net_init, .ndo_uninit = tun_net_uninit, .ndo_open = tun_net_open, .ndo_stop = tun_net_close, @@ -1339,6 +1416,7 @@ } static const struct net_device_ops tap_netdev_ops = { + .ndo_init = tun_net_init, .ndo_uninit = tun_net_uninit, .ndo_open = tun_net_open, .ndo_stop = tun_net_close, @@ -1379,7 +1457,7 @@ #define MAX_MTU 65535 /* Initialize net device. */ -static void tun_net_init(struct net_device *dev) +static void tun_net_initialize(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); @@ -1468,8 +1546,9 @@ int err; int i; - if (it->nr_segs > MAX_SKB_FRAGS + 1) - return ERR_PTR(-ENOMEM); + if (it->nr_segs > MAX_SKB_FRAGS + 1 || + len > (ETH_MAX_MTU - NET_SKB_PAD - NET_IP_ALIGN)) + return ERR_PTR(-EMSGSIZE); local_bh_disable(); skb = napi_get_frags(&tfile->napi); @@ -1594,7 +1673,7 @@ if (zerocopy) return false; - if (SKB_DATA_ALIGN(len + TUN_RX_PAD) + + if (SKB_DATA_ALIGN(len + TUN_RX_PAD + XDP_PACKET_HEADROOM) + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) > PAGE_SIZE) return false; @@ -1715,8 +1794,12 @@ alloc_frag->offset += buflen; } err = tun_xdp_act(tun, xdp_prog, &xdp, act); - if (err < 0) - goto err_xdp; + if (err < 0) { + if (act == XDP_REDIRECT || act == XDP_TX) + put_page(alloc_frag->page); + goto out; + } + if (err == XDP_REDIRECT) xdp_do_flush_map(); if (err != XDP_PASS) @@ -1730,8 +1813,6 @@ return __tun_build_skb(tfile, alloc_frag, buf, buflen, len, pad); -err_xdp: - put_page(alloc_frag->page); out: rcu_read_unlock(); local_bh_enable(); @@ -1906,8 +1987,11 @@ skb->dev = tun->dev; break; case IFF_TAP: - if (!frags) - skb->protocol = eth_type_trans(skb, tun->dev); + if (frags && !pskb_may_pull(skb, ETH_HLEN)) { + err = -ENOMEM; + goto drop; + } + skb->protocol = eth_type_trans(skb, tun->dev); break; } @@ -1923,6 +2007,7 @@ skb_reset_network_header(skb); skb_probe_transport_header(skb); + skb_record_rx_queue(skb, tfile->queue_index); if (skb_xdp) { struct bpf_prog *xdp_prog; @@ -1936,6 +2021,10 @@ if (ret != XDP_PASS) { rcu_read_unlock(); local_bh_enable(); + if (frags) { + tfile->napi.skb = NULL; + mutex_unlock(&tfile->napi_mutex); + } return total_len; } } @@ -1959,22 +2048,33 @@ } if (frags) { + u32 headlen; + /* Exercise flow dissector code path. */ - u32 headlen = eth_get_headlen(tun->dev, skb->data, - skb_headlen(skb)); + skb_push(skb, ETH_HLEN); + headlen = eth_get_headlen(tun->dev, skb->data, + skb_headlen(skb)); if (unlikely(headlen > skb_headlen(skb))) { + WARN_ON_ONCE(1); + err = -ENOMEM; this_cpu_inc(tun->pcpu_stats->rx_dropped); +napi_busy: napi_free_frags(&tfile->napi); rcu_read_unlock(); mutex_unlock(&tfile->napi_mutex); - WARN_ON(1); - return -ENOMEM; + return err; } - local_bh_disable(); - napi_gro_frags(&tfile->napi); - local_bh_enable(); + if (likely(napi_schedule_prep(&tfile->napi))) { + local_bh_disable(); + napi_gro_frags(&tfile->napi); + napi_complete(&tfile->napi); + local_bh_enable(); + } else { + err = -EBUSY; + goto napi_busy; + } mutex_unlock(&tfile->napi_mutex); } else if (tfile->napi_enabled) { struct sk_buff_head *queue = &tfile->sk.sk_write_queue; @@ -2015,12 +2115,15 @@ struct tun_file *tfile = file->private_data; struct tun_struct *tun = tun_get(tfile); ssize_t result; + int noblock = 0; if (!tun) return -EBADFD; - result = tun_get_user(tun, tfile, NULL, from, - file->f_flags & O_NONBLOCK, false); + if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) + noblock = 1; + + result = tun_get_user(tun, tfile, NULL, from, noblock, false); tun_put(tun); return result; @@ -2105,14 +2208,16 @@ tun_is_little_endian(tun), true, vlan_hlen)) { struct skb_shared_info *sinfo = skb_shinfo(skb); - pr_err("unexpected GSO type: " - "0x%x, gso_size %d, hdr_len %d\n", - sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size), - tun16_to_cpu(tun, gso.hdr_len)); - print_hex_dump(KERN_ERR, "tun: ", - DUMP_PREFIX_NONE, - 16, 1, skb->head, - min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true); + + if (net_ratelimit()) { + netdev_err(tun->dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len %d\n", + sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size), + tun16_to_cpu(tun, gso.hdr_len)); + print_hex_dump(KERN_ERR, "tun: ", + DUMP_PREFIX_NONE, + 16, 1, skb->head, + min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true); + } WARN_ON_ONCE(1); return -EINVAL; } @@ -2241,10 +2346,15 @@ struct tun_file *tfile = file->private_data; struct tun_struct *tun = tun_get(tfile); ssize_t len = iov_iter_count(to), ret; + int noblock = 0; if (!tun) return -EBADFD; - ret = tun_do_read(tun, tfile, to, file->f_flags & O_NONBLOCK, NULL); + + if ((file->f_flags & O_NONBLOCK) || (iocb->ki_flags & IOCB_NOWAIT)) + noblock = 1; + + ret = tun_do_read(tun, tfile, to, noblock, NULL); ret = min_t(ssize_t, ret, len); if (ret > 0) iocb->ki_pos = ret; @@ -2429,6 +2539,9 @@ bool skb_xdp = false; struct page *page; + if (unlikely(datasize < ETH_HLEN)) + return -EINVAL; + xdp_prog = rcu_dereference(tun->xdp_prog); if (xdp_prog) { if (gso->gso_type) { @@ -2486,6 +2599,7 @@ skb->protocol = eth_type_trans(skb, tun->dev); skb_reset_network_header(skb); skb_probe_transport_header(skb); + skb_record_rx_queue(skb, tfile->queue_index); if (skb_xdp) { err = do_xdp_generic(xdp_prog, skb); @@ -2497,7 +2611,6 @@ !tfile->detached) rxhash = __skb_get_hash_symmetric(skb); - skb_record_rx_queue(skb, tfile->queue_index); netif_receive_skb(skb); /* No need for get_cpu_ptr() here since this function is @@ -2527,7 +2640,8 @@ if (!tun) return -EBADFD; - if (ctl && (ctl->type == TUN_MSG_PTR)) { + if (m->msg_controllen == sizeof(struct tun_msg_ctl) && + ctl && ctl->type == TUN_MSG_PTR) { struct tun_page tpage; int n = ctl->num; int flush = 0; @@ -2782,9 +2896,6 @@ if (!dev) return -ENOMEM; - err = dev_get_valid_name(net, dev, name); - if (err < 0) - goto err_free_dev; dev_net_set(dev, net); dev->rtnl_link_ops = &tun_link_ops; @@ -2803,41 +2914,16 @@ tun->rx_batched = 0; RCU_INIT_POINTER(tun->steering_prog, NULL); - tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); - if (!tun->pcpu_stats) { - err = -ENOMEM; - goto err_free_dev; - } - - spin_lock_init(&tun->lock); - - err = security_tun_dev_alloc_security(&tun->security); - if (err < 0) - goto err_free_stat; - - tun_net_init(dev); - tun_flow_init(tun); + tun->ifr = ifr; + tun->file = file; - dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | - TUN_USER_FEATURES | NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_STAG_TX; - dev->features = dev->hw_features | NETIF_F_LLTX; - dev->vlan_features = dev->features & - ~(NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_STAG_TX); - - tun->flags = (tun->flags & ~TUN_FEATURES) | - (ifr->ifr_flags & TUN_FEATURES); - - INIT_LIST_HEAD(&tun->disabled); - err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI, - ifr->ifr_flags & IFF_NAPI_FRAGS, false); - if (err < 0) - goto err_free_flow; + tun_net_initialize(dev); err = register_netdevice(tun->dev); - if (err < 0) - goto err_detach; + if (err < 0) { + free_netdev(dev); + return err; + } /* free_netdev() won't check refcnt, to aovid race * with dev_put() we need publish tun after registration. */ @@ -2856,20 +2942,6 @@ strcpy(ifr->ifr_name, tun->dev->name); return 0; - -err_detach: - tun_detach_all(dev); - /* register_netdevice() already called tun_free_netdev() */ - goto err_free_dev; - -err_free_flow: - tun_flow_uninit(tun); - security_tun_dev_free_security(tun->security); -err_free_stat: - free_percpu(tun->pcpu_stats); -err_free_dev: - free_netdev(dev); - return err; } static void tun_get_iff(struct tun_struct *tun, struct ifreq *ifr) @@ -3022,6 +3094,45 @@ return __tun_set_ebpf(tun, prog_p, prog); } +/* Return correct value for tun->dev->addr_len based on tun->dev->type. */ +static unsigned char tun_get_addr_len(unsigned short type) +{ + switch (type) { + case ARPHRD_IP6GRE: + case ARPHRD_TUNNEL6: + return sizeof(struct in6_addr); + case ARPHRD_IPGRE: + case ARPHRD_TUNNEL: + case ARPHRD_SIT: + return 4; + case ARPHRD_ETHER: + return ETH_ALEN; + case ARPHRD_IEEE802154: + case ARPHRD_IEEE802154_MONITOR: + return IEEE802154_EXTENDED_ADDR_LEN; + case ARPHRD_PHONET_PIPE: + case ARPHRD_PPP: + case ARPHRD_NONE: + return 0; + case ARPHRD_6LOWPAN: + return EUI64_ADDR_LEN; + case ARPHRD_FDDI: + return FDDI_K_ALEN; + case ARPHRD_HIPPI: + return HIPPI_ALEN; + case ARPHRD_IEEE802: + return FC_ALEN; + case ARPHRD_ROSE: + return ROSE_ADDR_LEN; + case ARPHRD_NETROM: + return AX25_ADDR_LEN; + case ARPHRD_LOCALTLK: + return LTALK_ALEN; + default: + return 0; + } +} + static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg, int ifreq_len) { @@ -3029,10 +3140,11 @@ struct net *net = sock_net(&tfile->sk); struct tun_struct *tun; void __user* argp = (void __user*)arg; - unsigned int ifindex, carrier; + unsigned int carrier; struct ifreq ifr; kuid_t owner; kgid_t group; + int ifindex; int sndbuf; int vnet_hdr_sz; int le; @@ -3089,7 +3201,9 @@ ret = -EFAULT; if (copy_from_user(&ifindex, argp, sizeof(ifindex))) goto unlock; - + ret = -EINVAL; + if (ifindex < 0) + goto unlock; ret = 0; tfile->ifindex = ifindex; goto unlock; @@ -3177,6 +3291,7 @@ ret = -EBUSY; } else { tun->dev->type = (int) arg; + tun->dev->addr_len = tun_get_addr_len(tun->dev->type); tun_debug(KERN_INFO, tun, "linktype set to %d\n", tun->dev->type); ret = 0; @@ -3203,7 +3318,7 @@ case SIOCGIFHWADDR: /* Get hw address */ memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); - ifr.ifr_hwaddr.sa_family = tun->dev->type; + dev_get_mac_address(&ifr.ifr_hwaddr, net, tun->dev->name); if (copy_to_user(argp, &ifr, ifreq_len)) ret = -EFAULT; break; @@ -3213,7 +3328,7 @@ tun_debug(KERN_DEBUG, tun, "set hw address: %pM\n", ifr.ifr_hwaddr.sa_data); - ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr, NULL); + ret = dev_set_mac_address_user(tun->dev, &ifr.ifr_hwaddr, NULL); break; case TUNGETSNDBUF: @@ -3428,7 +3543,7 @@ tfile->socket.file = file; tfile->socket.ops = &tun_socket_ops; - sock_init_data(&tfile->socket, &tfile->sk); + sock_init_data_uid(&tfile->socket, &tfile->sk, current_fsuid()); tfile->sk.sk_write_space = tun_sock_write_space; tfile->sk.sk_sndbuf = INT_MAX; --- linux-oracle-5.4.0.orig/drivers/net/usb/Kconfig +++ linux-oracle-5.4.0/drivers/net/usb/Kconfig @@ -99,6 +99,10 @@ config USB_RTL8152 tristate "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" select MII + select CRC32 + select CRYPTO + select CRYPTO_HASH + select CRYPTO_SHA256 help This option adds support for Realtek RTL8152 based USB 2.0 10/100 Ethernet adapters and RTL8153 based USB 3.0 10/100/1000 @@ -113,6 +117,7 @@ select PHYLIB select MICROCHIP_PHY select FIXED_PHY + select CRC32 help This option adds support for Microchip LAN78XX based USB 2 & USB 3 10/100/1000 Ethernet adapters. --- linux-oracle-5.4.0.orig/drivers/net/usb/aqc111.c +++ linux-oracle-5.4.0/drivers/net/usb/aqc111.c @@ -1079,17 +1079,17 @@ u16 pkt_count = 0; u64 desc_hdr = 0; u16 vlan_tag = 0; - u32 skb_len = 0; + u32 skb_len; if (!skb) goto err; - if (skb->len == 0) + skb_len = skb->len; + if (skb_len < sizeof(desc_hdr)) goto err; - skb_len = skb->len; /* RX Descriptor Header */ - skb_trim(skb, skb->len - sizeof(desc_hdr)); + skb_trim(skb, skb_len - sizeof(desc_hdr)); desc_hdr = le64_to_cpup((u64 *)skb_tail_pointer(skb)); /* Check these packets */ @@ -1102,10 +1102,15 @@ if (start_of_descs != desc_offset) goto err; - /* self check desc_offset from header*/ - if (desc_offset >= skb_len) + /* self check desc_offset from header and make sure that the + * bounds of the metadata array are inside the SKB + */ + if (pkt_count * 2 + desc_offset >= skb_len) goto err; + /* Packets must not overlap the metadata array */ + skb_trim(skb, desc_offset); + if (pkt_count == 0) goto err; @@ -1136,17 +1141,15 @@ continue; } - /* Clone SKB */ - new_skb = skb_clone(skb, GFP_ATOMIC); + new_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len); if (!new_skb) goto err; - new_skb->len = pkt_len; + skb_put(new_skb, pkt_len); + memcpy(new_skb->data, skb->data, pkt_len); skb_pull(new_skb, AQ_RX_HW_PAD); - skb_set_tail_pointer(new_skb, new_skb->len); - new_skb->truesize = SKB_TRUESIZE(new_skb->len); if (aqc111_data->rx_checksum) aqc111_rx_checksum(new_skb, pkt_desc); --- linux-oracle-5.4.0.orig/drivers/net/usb/asix_common.c +++ linux-oracle-5.4.0/drivers/net/usb/asix_common.c @@ -9,6 +9,8 @@ #include "asix.h" +#define AX_HOST_EN_RETRIES 30 + int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, u16 size, void *data, int in_pm) { @@ -63,6 +65,29 @@ value, index, data, size); } +static int asix_check_host_enable(struct usbnet *dev, int in_pm) +{ + int i, ret; + u8 smsr; + + for (i = 0; i < AX_HOST_EN_RETRIES; ++i) { + ret = asix_set_sw_mii(dev, in_pm); + if (ret == -ENODEV || ret == -ETIMEDOUT) + break; + usleep_range(1000, 1100); + ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, + 0, 0, 1, &smsr, in_pm); + if (ret == -ENODEV) + break; + else if (ret < sizeof(smsr)) + continue; + else if (smsr & AX_HOST_EN) + break; + } + + return i >= AX_HOST_EN_RETRIES ? -ETIMEDOUT : ret; +} + static void reset_asix_rx_fixup_info(struct asix_rx_fixup_info *rx) { /* Reset the variables that have a lifetime outside of @@ -296,7 +321,7 @@ netdev_dbg(dev->net, "asix_get_phy_addr()\n"); - if (ret < 0) { + if (ret < 2) { netdev_err(dev->net, "Error reading PHYID register: %02x\n", ret); goto out; } @@ -445,19 +470,11 @@ { struct usbnet *dev = netdev_priv(netdev); __le16 res; - u8 smsr; - int i = 0; int ret; mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 0); - if (ret == -ENODEV || ret == -ETIMEDOUT) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 0); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 0); if (ret == -ENODEV || ret == -ETIMEDOUT) { mutex_unlock(&dev->phy_mutex); return ret; @@ -478,22 +495,14 @@ { struct usbnet *dev = netdev_priv(netdev); __le16 res = cpu_to_le16(val); - u8 smsr; - int i = 0; int ret; netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 0); - if (ret == -ENODEV) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 0); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 0); if (ret == -ENODEV) { mutex_unlock(&dev->phy_mutex); return; @@ -509,19 +518,11 @@ { struct usbnet *dev = netdev_priv(netdev); __le16 res; - u8 smsr; - int i = 0; int ret; mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 1); - if (ret == -ENODEV || ret == -ETIMEDOUT) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 1); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 1); if (ret == -ENODEV || ret == -ETIMEDOUT) { mutex_unlock(&dev->phy_mutex); return ret; @@ -543,22 +544,14 @@ { struct usbnet *dev = netdev_priv(netdev); __le16 res = cpu_to_le16(val); - u8 smsr; - int i = 0; int ret; netdev_dbg(dev->net, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", phy_id, loc, val); mutex_lock(&dev->phy_mutex); - do { - ret = asix_set_sw_mii(dev, 1); - if (ret == -ENODEV) - break; - usleep_range(1000, 1100); - ret = asix_read_cmd(dev, AX_CMD_STATMNGSTS_REG, - 0, 0, 1, &smsr, 1); - } while (!(smsr & AX_HOST_EN) && (i++ < 30) && (ret != -ENODEV)); + + ret = asix_check_host_enable(dev, 1); if (ret == -ENODEV) { mutex_unlock(&dev->phy_mutex); return; --- linux-oracle-5.4.0.orig/drivers/net/usb/ax88172a.c +++ linux-oracle-5.4.0/drivers/net/usb/ax88172a.c @@ -186,7 +186,9 @@ u8 buf[ETH_ALEN]; struct ax88172a_private *priv; - usbnet_get_endpoints(dev, intf); + ret = usbnet_get_endpoints(dev, intf); + if (ret) + return ret; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) @@ -198,6 +200,7 @@ ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0); if (ret < ETH_ALEN) { netdev_err(dev->net, "Failed to read MAC address: %d\n", ret); + ret = -EIO; goto free; } memcpy(dev->net->dev_addr, buf, ETH_ALEN); --- linux-oracle-5.4.0.orig/drivers/net/usb/ax88179_178a.c +++ linux-oracle-5.4.0/drivers/net/usb/ax88179_178a.c @@ -295,12 +295,12 @@ int ret; if (2 == size) { - u16 buf; + u16 buf = 0; ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); le16_to_cpus(&buf); *((u16 *)data) = buf; } else if (4 == size) { - u32 buf; + u32 buf = 0; ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); le32_to_cpus(&buf); *((u32 *)data) = buf; @@ -345,7 +345,8 @@ if (netif_carrier_ok(dev->net) != link) { usbnet_link_change(dev, link, 1); - netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); + if (!link) + netdev_info(dev->net, "ax88179 - Link status is: 0\n"); } } @@ -1361,57 +1362,114 @@ u16 hdr_off; u32 *pkt_hdr; - /* This check is no longer done by usbnet */ - if (skb->len < dev->net->hard_header_len) - return 0; + /* At the end of the SKB, there's a header telling us how many packets + * are bundled into this buffer and where we can find an array of + * per-packet metadata (which contains elements encoded into u16). + */ + + /* SKB contents for current firmware: + * + * ... + * + * + * ... + * + * + * + * where: + * contains pkt_len bytes: + * 2 bytes of IP alignment pseudo header + * packet received + * contains 4 bytes: + * pkt_len and fields AX_RXHDR_* + * 0-7 bytes to terminate at + * 8 bytes boundary (64-bit). + * 4 bytes to make rx_hdr terminate at + * 8 bytes boundary (64-bit) + * contains 4 bytes: + * pkt_len=0 and AX_RXHDR_DROP_ERR + * contains 4 bytes: + * pkt_cnt and hdr_off (offset of + * ) + * + * pkt_cnt is number of entrys in the per-packet metadata. + * In current firmware there is 2 entrys per packet. + * The first points to the packet and the + * second is a dummy header. + * This was done probably to align fields in 64-bit and + * maintain compatibility with old firmware. + * This code assumes that and are + * optional. + */ + if (skb->len < 4) + return 0; skb_trim(skb, skb->len - 4); rx_hdr = get_unaligned_le32(skb_tail_pointer(skb)); - pkt_cnt = (u16)rx_hdr; hdr_off = (u16)(rx_hdr >> 16); + + if (pkt_cnt == 0) + return 0; + + /* Make sure that the bounds of the metadata array are inside the SKB + * (and in front of the counter at the end). + */ + if (pkt_cnt * 4 + hdr_off > skb->len) + return 0; pkt_hdr = (u32 *)(skb->data + hdr_off); - while (pkt_cnt--) { + /* Packets must not overlap the metadata array */ + skb_trim(skb, hdr_off); + + for (; pkt_cnt > 0; pkt_cnt--, pkt_hdr++) { + u16 pkt_len_plus_padd; u16 pkt_len; le32_to_cpus(pkt_hdr); pkt_len = (*pkt_hdr >> 16) & 0x1fff; + pkt_len_plus_padd = (pkt_len + 7) & 0xfff8; + + /* Skip dummy header used for alignment + */ + if (pkt_len == 0) + continue; + + if (pkt_len_plus_padd > skb->len) + return 0; /* Check CRC or runt packet */ - if ((*pkt_hdr & AX_RXHDR_CRC_ERR) || - (*pkt_hdr & AX_RXHDR_DROP_ERR)) { - skb_pull(skb, (pkt_len + 7) & 0xFFF8); - pkt_hdr++; + if ((*pkt_hdr & (AX_RXHDR_CRC_ERR | AX_RXHDR_DROP_ERR)) || + pkt_len < 2 + ETH_HLEN) { + dev->net->stats.rx_errors++; + skb_pull(skb, pkt_len_plus_padd); continue; } - if (pkt_cnt == 0) { - /* Skip IP alignment psudo header */ + /* last packet */ + if (pkt_len_plus_padd == skb->len) { + skb_trim(skb, pkt_len); + + /* Skip IP alignment pseudo header */ skb_pull(skb, 2); - skb->len = pkt_len; - skb_set_tail_pointer(skb, pkt_len); - skb->truesize = pkt_len + sizeof(struct sk_buff); + ax88179_rx_checksum(skb, pkt_hdr); return 1; } - ax_skb = skb_clone(skb, GFP_ATOMIC); - if (ax_skb) { - ax_skb->len = pkt_len; - ax_skb->data = skb->data + 2; - skb_set_tail_pointer(ax_skb, pkt_len); - ax_skb->truesize = pkt_len + sizeof(struct sk_buff); - ax88179_rx_checksum(ax_skb, pkt_hdr); - usbnet_skb_return(dev, ax_skb); - } else { + ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len); + if (!ax_skb) return 0; - } + skb_put(ax_skb, pkt_len); + memcpy(ax_skb->data, skb->data + 2, pkt_len); + + ax88179_rx_checksum(ax_skb, pkt_hdr); + usbnet_skb_return(dev, ax_skb); - skb_pull(skb, (pkt_len + 7) & 0xFFF8); - pkt_hdr++; + skb_pull(skb, pkt_len_plus_padd); } - return 1; + + return 0; } static struct sk_buff * @@ -1475,6 +1533,7 @@ GMII_PHY_PHYSR, 2, &tmp16); if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { + netdev_info(dev->net, "ax88179 - Link status is: 0\n"); return 0; } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; @@ -1512,6 +1571,8 @@ netif_carrier_on(dev->net); + netdev_info(dev->net, "ax88179 - Link status is: 1\n"); + return 0; } @@ -1532,11 +1593,11 @@ *tmp16 = AX_PHYPWR_RSTCTL_IPRL; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); - msleep(200); + msleep(500); *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); - msleep(100); + msleep(200); /* Ethernet PHY Auto Detach*/ ax88179_auto_detach(dev, 0); @@ -1718,6 +1779,7 @@ .status = ax88179_status, .link_reset = ax88179_link_reset, .reset = ax88179_reset, + .stop = ax88179_stop, .flags = FLAG_ETHER | FLAG_FRAMING_AX, .rx_fixup = ax88179_rx_fixup, .tx_fixup = ax88179_tx_fixup, --- linux-oracle-5.4.0.orig/drivers/net/usb/cdc-phonet.c +++ linux-oracle-5.4.0/drivers/net/usb/cdc-phonet.c @@ -387,6 +387,8 @@ err = register_netdev(dev); if (err) { + /* Set disconnected flag so that disconnect() returns early. */ + pnd->disconnected = 1; usb_driver_release_interface(&usbpn_driver, data_intf); goto out; } --- linux-oracle-5.4.0.orig/drivers/net/usb/cdc_eem.c +++ linux-oracle-5.4.0/drivers/net/usb/cdc_eem.c @@ -123,10 +123,10 @@ } skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); + dev_kfree_skb_any(skb); if (!skb2) return NULL; - dev_kfree_skb_any(skb); skb = skb2; done: --- linux-oracle-5.4.0.orig/drivers/net/usb/cdc_ether.c +++ linux-oracle-5.4.0/drivers/net/usb/cdc_ether.c @@ -571,6 +571,11 @@ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ .bInterfaceProtocol = USB_CDC_PROTO_NONE +#define ZAURUS_FAKE_INTERFACE \ + .bInterfaceClass = USB_CLASS_COMM, \ + .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ + .bInterfaceProtocol = USB_CDC_PROTO_NONE + /* SA-1100 based Sharp Zaurus ("collie"), or compatible; * wire-incompatible with true CDC Ethernet implementations. * (And, it seems, needlessly so...) @@ -600,6 +605,13 @@ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct = 0x8005, /* A-300 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = 0, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, .idProduct = 0x8006, /* B-500/SL-5600 */ ZAURUS_MASTER_INTERFACE, .driver_info = 0, @@ -607,11 +619,25 @@ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = 0, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, .idProduct = 0x8007, /* C-700 */ ZAURUS_MASTER_INTERFACE, .driver_info = 0, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct = 0x8007, /* C-700 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = 0, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x9031, /* C-750 C-760 */ @@ -628,6 +654,13 @@ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct = 0x9032, /* SL-6000 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = 0, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, /* reported with some C860 units */ .idProduct = 0x9050, /* C-860 */ ZAURUS_MASTER_INTERFACE, @@ -752,6 +785,13 @@ }, #endif +/* Lenovo ThinkPad OneLink+ Dock (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3054, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* ThinkPad USB-C Dock (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM, @@ -766,6 +806,13 @@ .driver_info = 0, }, +/* ThinkPad Thunderbolt 3 Dock Gen 2 (based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3082, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM, @@ -787,6 +834,13 @@ .driver_info = 0, }, +/* Lenovo Powered USB-C Travel Hub (4X90S92381, based on Realtek RTL8153) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x721e, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* ThinkPad USB-C Dock Gen 2 (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0xa387, USB_CLASS_COMM, @@ -808,14 +862,21 @@ .driver_info = 0, }, -/* Microsoft Surface 3 dock (based on Realtek RTL8153) */ +/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x07c6, USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = 0, }, - /* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ +/* Microsoft Surface Ethernet Adapter (based on Realtek RTL8153B) */ +{ + USB_DEVICE_AND_INTERFACE_INFO(MICROSOFT_VENDOR_ID, 0x0927, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + +/* TP-LINK UE300 USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */ { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, 0x0601, USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), --- linux-oracle-5.4.0.orig/drivers/net/usb/cdc_mbim.c +++ linux-oracle-5.4.0/drivers/net/usb/cdc_mbim.c @@ -653,6 +653,21 @@ .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, }, + /* Telit LN920 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1061, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, + }, + + /* Telit FN990 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1071, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, + }, + + /* Telit FE990 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1081, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle, + }, + /* default entry */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long)&cdc_mbim_info_zlp, --- linux-oracle-5.4.0.orig/drivers/net/usb/cdc_ncm.c +++ linux-oracle-5.4.0/drivers/net/usb/cdc_ncm.c @@ -175,8 +175,17 @@ u32 val, max, min; /* clamp new_tx to sane values */ - min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16); - max = min_t(u32, CDC_NCM_NTB_MAX_SIZE_TX, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)); + if (ctx->is_ndp16) + min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth16); + else + min = ctx->max_datagram_size + ctx->max_ndp_size + sizeof(struct usb_cdc_ncm_nth32); + + if (le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize) == 0) + max = CDC_NCM_NTB_MAX_SIZE_TX; /* dwNtbOutMaxSize not set */ + else + max = clamp_t(u32, le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize), + USB_CDC_NCM_NTB_MIN_OUT_SIZE, + CDC_NCM_NTB_MAX_SIZE_TX); /* some devices set dwNtbOutMaxSize too low for the above default */ min = min(min, max); @@ -307,10 +316,17 @@ if (enable == (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) return len; - if (enable && !ctx->delayed_ndp16) { - ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); - if (!ctx->delayed_ndp16) - return -ENOMEM; + if (enable) { + if (ctx->is_ndp16 && !ctx->delayed_ndp16) { + ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); + if (!ctx->delayed_ndp16) + return -ENOMEM; + } + if (!ctx->is_ndp16 && !ctx->delayed_ndp32) { + ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); + if (!ctx->delayed_ndp32) + return -ENOMEM; + } } /* flush pending data before changing flag */ @@ -512,6 +528,9 @@ dev_err(&dev->intf->dev, "SET_CRC_MODE failed\n"); } + /* use ndp16 by default */ + ctx->is_ndp16 = 1; + /* set NTB format, if both formats are supported. * * "The host shall only send this command while the NCM Data @@ -519,14 +538,27 @@ */ if (le16_to_cpu(ctx->ncm_parm.bmNtbFormatsSupported) & USB_CDC_NCM_NTB32_SUPPORTED) { - dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit\n"); - err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - USB_CDC_NCM_NTB16_FORMAT, - iface_no, NULL, 0); - if (err < 0) + if (ctx->drvflags & CDC_NCM_FLAG_PREFER_NTB32) { + ctx->is_ndp16 = 0; + dev_dbg(&dev->intf->dev, "Setting NTB format to 32-bit\n"); + err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, + USB_TYPE_CLASS | USB_DIR_OUT + | USB_RECIP_INTERFACE, + USB_CDC_NCM_NTB32_FORMAT, + iface_no, NULL, 0); + } else { + ctx->is_ndp16 = 1; + dev_dbg(&dev->intf->dev, "Setting NTB format to 16-bit\n"); + err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, + USB_TYPE_CLASS | USB_DIR_OUT + | USB_RECIP_INTERFACE, + USB_CDC_NCM_NTB16_FORMAT, + iface_no, NULL, 0); + } + if (err < 0) { + ctx->is_ndp16 = 1; dev_err(&dev->intf->dev, "SET_NTB_FORMAT failed\n"); + } } /* set initial device values */ @@ -549,7 +581,10 @@ ctx->tx_max_datagrams = CDC_NCM_DPT_DATAGRAMS_MAX; /* set up maximum NDP size */ - ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe16); + if (ctx->is_ndp16) + ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp16) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe16); + else + ctx->max_ndp_size = sizeof(struct usb_cdc_ncm_ndp32) + (ctx->tx_max_datagrams + 1) * sizeof(struct usb_cdc_ncm_dpe32); /* initial coalescing timer interval */ ctx->timer_interval = CDC_NCM_TIMER_INTERVAL_USEC * NSEC_PER_USEC; @@ -734,7 +769,10 @@ ctx->tx_curr_skb = NULL; } - kfree(ctx->delayed_ndp16); + if (ctx->is_ndp16) + kfree(ctx->delayed_ndp16); + else + kfree(ctx->delayed_ndp32); kfree(ctx); } @@ -772,10 +810,8 @@ u8 *buf; int len; int temp; - int err; u8 iface_no; struct usb_cdc_parsed_header hdr; - __le16 curr_ntb_format; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -879,32 +915,6 @@ goto error2; } - /* - * Some Huawei devices have been observed to come out of reset in NDP32 mode. - * Let's check if this is the case, and set the device to NDP16 mode again if - * needed. - */ - if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) { - err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT, - USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, - 0, iface_no, &curr_ntb_format, 2); - if (err < 0) { - goto error2; - } - - if (curr_ntb_format == cpu_to_le16(USB_CDC_NCM_NTB32_FORMAT)) { - dev_info(&intf->dev, "resetting NTB format to 16-bit"); - err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - USB_CDC_NCM_NTB16_FORMAT, - iface_no, NULL, 0); - - if (err < 0) - goto error2; - } - } - cdc_ncm_find_endpoints(dev, ctx->data); cdc_ncm_find_endpoints(dev, ctx->control); if (!dev->in || !dev->out || !dev->status) { @@ -929,9 +939,15 @@ /* Allocate the delayed NDP if needed. */ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { - ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); - if (!ctx->delayed_ndp16) - goto error2; + if (ctx->is_ndp16) { + ctx->delayed_ndp16 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); + if (!ctx->delayed_ndp16) + goto error2; + } else { + ctx->delayed_ndp32 = kzalloc(ctx->max_ndp_size, GFP_KERNEL); + if (!ctx->delayed_ndp32) + goto error2; + } dev_info(&intf->dev, "NDP will be placed at end of frame for this device."); } @@ -1055,7 +1071,7 @@ /* return a pointer to a valid struct usb_cdc_ncm_ndp16 of type sign, possibly * allocating a new one within skb */ -static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) +static struct usb_cdc_ncm_ndp16 *cdc_ncm_ndp16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) { struct usb_cdc_ncm_ndp16 *ndp16 = NULL; struct usb_cdc_ncm_nth16 *nth16 = (void *)skb->data; @@ -1110,12 +1126,73 @@ return ndp16; } +static struct usb_cdc_ncm_ndp32 *cdc_ncm_ndp32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign, size_t reserve) +{ + struct usb_cdc_ncm_ndp32 *ndp32 = NULL; + struct usb_cdc_ncm_nth32 *nth32 = (void *)skb->data; + size_t ndpoffset = le32_to_cpu(nth32->dwNdpIndex); + + /* If NDP should be moved to the end of the NCM package, we can't follow the + * NTH32 header as we would normally do. NDP isn't written to the SKB yet, and + * the wNdpIndex field in the header is actually not consistent with reality. It will be later. + */ + if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { + if (ctx->delayed_ndp32->dwSignature == sign) + return ctx->delayed_ndp32; + + /* We can only push a single NDP to the end. Return + * NULL to send what we've already got and queue this + * skb for later. + */ + else if (ctx->delayed_ndp32->dwSignature) + return NULL; + } + + /* follow the chain of NDPs, looking for a match */ + while (ndpoffset) { + ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb->data + ndpoffset); + if (ndp32->dwSignature == sign) + return ndp32; + ndpoffset = le32_to_cpu(ndp32->dwNextNdpIndex); + } + + /* align new NDP */ + if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) + cdc_ncm_align_tail(skb, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size); + + /* verify that there is room for the NDP and the datagram (reserve) */ + if ((ctx->tx_curr_size - skb->len - reserve) < ctx->max_ndp_size) + return NULL; + + /* link to it */ + if (ndp32) + ndp32->dwNextNdpIndex = cpu_to_le32(skb->len); + else + nth32->dwNdpIndex = cpu_to_le32(skb->len); + + /* push a new empty NDP */ + if (!(ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END)) + ndp32 = skb_put_zero(skb, ctx->max_ndp_size); + else + ndp32 = ctx->delayed_ndp32; + + ndp32->dwSignature = sign; + ndp32->wLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_ndp32) + sizeof(struct usb_cdc_ncm_dpe32)); + return ndp32; +} + struct sk_buff * cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) { struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; - struct usb_cdc_ncm_nth16 *nth16; - struct usb_cdc_ncm_ndp16 *ndp16; + union { + struct usb_cdc_ncm_nth16 *nth16; + struct usb_cdc_ncm_nth32 *nth32; + } nth; + union { + struct usb_cdc_ncm_ndp16 *ndp16; + struct usb_cdc_ncm_ndp32 *ndp32; + } ndp; struct sk_buff *skb_out; u16 n = 0, index, ndplen; u8 ready2send = 0; @@ -1126,7 +1203,10 @@ * accordingly. Otherwise, we should check here. */ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) - delayed_ndp_size = ALIGN(ctx->max_ndp_size, ctx->tx_ndp_modulus); + delayed_ndp_size = ctx->max_ndp_size + + max_t(u32, + ctx->tx_ndp_modulus, + ctx->tx_modulus + ctx->tx_remainder) - 1; else delayed_ndp_size = 0; @@ -1152,6 +1232,9 @@ * further. */ if (skb_out == NULL) { + /* If even the smallest allocation fails, abort. */ + if (ctx->tx_curr_size == USB_CDC_NCM_NTB_MIN_OUT_SIZE) + goto alloc_failed; ctx->tx_low_mem_max_cnt = min(ctx->tx_low_mem_max_cnt + 1, (unsigned)CDC_NCM_LOW_MEM_MAX_CNT); ctx->tx_low_mem_val = ctx->tx_low_mem_max_cnt; @@ -1170,20 +1253,23 @@ skb_out = alloc_skb(ctx->tx_curr_size, GFP_ATOMIC); /* No allocation possible so we will abort */ - if (skb_out == NULL) { - if (skb != NULL) { - dev_kfree_skb_any(skb); - dev->net->stats.tx_dropped++; - } - goto exit_no_skb; - } + if (!skb_out) + goto alloc_failed; ctx->tx_low_mem_val--; } - /* fill out the initial 16-bit NTB header */ - nth16 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth16)); - nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); - nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); - nth16->wSequence = cpu_to_le16(ctx->tx_seq++); + if (ctx->is_ndp16) { + /* fill out the initial 16-bit NTB header */ + nth.nth16 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth16)); + nth.nth16->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH16_SIGN); + nth.nth16->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)); + nth.nth16->wSequence = cpu_to_le16(ctx->tx_seq++); + } else { + /* fill out the initial 32-bit NTB header */ + nth.nth32 = skb_put_zero(skb_out, sizeof(struct usb_cdc_ncm_nth32)); + nth.nth32->dwSignature = cpu_to_le32(USB_CDC_NCM_NTH32_SIGN); + nth.nth32->wHeaderLength = cpu_to_le16(sizeof(struct usb_cdc_ncm_nth32)); + nth.nth32->wSequence = cpu_to_le16(ctx->tx_seq++); + } /* count total number of frames in this NTB */ ctx->tx_curr_frame_num = 0; @@ -1205,13 +1291,17 @@ } /* get the appropriate NDP for this skb */ - ndp16 = cdc_ncm_ndp(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); + if (ctx->is_ndp16) + ndp.ndp16 = cdc_ncm_ndp16(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); + else + ndp.ndp32 = cdc_ncm_ndp32(ctx, skb_out, sign, skb->len + ctx->tx_modulus + ctx->tx_remainder); /* align beginning of next frame */ cdc_ncm_align_tail(skb_out, ctx->tx_modulus, ctx->tx_remainder, ctx->tx_curr_size); /* check if we had enough room left for both NDP and frame */ - if (!ndp16 || skb_out->len + skb->len + delayed_ndp_size > ctx->tx_curr_size) { + if ((ctx->is_ndp16 && !ndp.ndp16) || (!ctx->is_ndp16 && !ndp.ndp32) || + skb_out->len + skb->len + delayed_ndp_size > ctx->tx_curr_size) { if (n == 0) { /* won't fit, MTU problem? */ dev_kfree_skb_any(skb); @@ -1233,13 +1323,22 @@ } /* calculate frame number withing this NDP */ - ndplen = le16_to_cpu(ndp16->wLength); - index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; + if (ctx->is_ndp16) { + ndplen = le16_to_cpu(ndp.ndp16->wLength); + index = (ndplen - sizeof(struct usb_cdc_ncm_ndp16)) / sizeof(struct usb_cdc_ncm_dpe16) - 1; + + /* OK, add this skb */ + ndp.ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); + ndp.ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); + ndp.ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); + } else { + ndplen = le16_to_cpu(ndp.ndp32->wLength); + index = (ndplen - sizeof(struct usb_cdc_ncm_ndp32)) / sizeof(struct usb_cdc_ncm_dpe32) - 1; - /* OK, add this skb */ - ndp16->dpe16[index].wDatagramLength = cpu_to_le16(skb->len); - ndp16->dpe16[index].wDatagramIndex = cpu_to_le16(skb_out->len); - ndp16->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe16)); + ndp.ndp32->dpe32[index].dwDatagramLength = cpu_to_le32(skb->len); + ndp.ndp32->dpe32[index].dwDatagramIndex = cpu_to_le32(skb_out->len); + ndp.ndp32->wLength = cpu_to_le16(ndplen + sizeof(struct usb_cdc_ncm_dpe32)); + } skb_put_data(skb_out, skb->data, skb->len); ctx->tx_curr_frame_payload += skb->len; /* count real tx payload data */ dev_kfree_skb_any(skb); @@ -1286,13 +1385,22 @@ /* If requested, put NDP at end of frame. */ if (ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END) { - nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; - cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); - nth16->wNdpIndex = cpu_to_le16(skb_out->len); - skb_put_data(skb_out, ctx->delayed_ndp16, ctx->max_ndp_size); + if (ctx->is_ndp16) { + nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; + cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); + nth.nth16->wNdpIndex = cpu_to_le16(skb_out->len); + skb_put_data(skb_out, ctx->delayed_ndp16, ctx->max_ndp_size); + + /* Zero out delayed NDP - signature checking will naturally fail. */ + ndp.ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); + } else { + nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; + cdc_ncm_align_tail(skb_out, ctx->tx_ndp_modulus, 0, ctx->tx_curr_size - ctx->max_ndp_size); + nth.nth32->dwNdpIndex = cpu_to_le32(skb_out->len); + skb_put_data(skb_out, ctx->delayed_ndp32, ctx->max_ndp_size); - /* Zero out delayed NDP - signature checking will naturally fail. */ - ndp16 = memset(ctx->delayed_ndp16, 0, ctx->max_ndp_size); + ndp.ndp32 = memset(ctx->delayed_ndp32, 0, ctx->max_ndp_size); + } } /* If collected data size is less or equal ctx->min_tx_pkt @@ -1307,15 +1415,21 @@ if (!(dev->driver_info->flags & FLAG_SEND_ZLP) && skb_out->len > ctx->min_tx_pkt) { padding_count = ctx->tx_curr_size - skb_out->len; - skb_put_zero(skb_out, padding_count); + if (!WARN_ON(padding_count > ctx->tx_curr_size)) + skb_put_zero(skb_out, padding_count); } else if (skb_out->len < ctx->tx_curr_size && (skb_out->len % dev->maxpacket) == 0) { skb_put_u8(skb_out, 0); /* force short packet */ } /* set final frame length */ - nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; - nth16->wBlockLength = cpu_to_le16(skb_out->len); + if (ctx->is_ndp16) { + nth.nth16 = (struct usb_cdc_ncm_nth16 *)skb_out->data; + nth.nth16->wBlockLength = cpu_to_le16(skb_out->len); + } else { + nth.nth32 = (struct usb_cdc_ncm_nth32 *)skb_out->data; + nth.nth32->dwBlockLength = cpu_to_le32(skb_out->len); + } /* return skb */ ctx->tx_curr_skb = NULL; @@ -1333,6 +1447,11 @@ return skb_out; +alloc_failed: + if (skb) { + dev_kfree_skb_any(skb); + dev->net->stats.tx_dropped++; + } exit_no_skb: /* Start timer, if there is a remaining non-empty skb */ if (ctx->tx_curr_skb != NULL && n > 0) @@ -1398,7 +1517,12 @@ goto error; spin_lock_bh(&ctx->mtx); - skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)); + + if (ctx->is_ndp16) + skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)); + else + skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN)); + spin_unlock_bh(&ctx->mtx); return skb_out; @@ -1459,6 +1583,54 @@ } EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_nth16); +int cdc_ncm_rx_verify_nth32(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in) +{ + struct usbnet *dev = netdev_priv(skb_in->dev); + struct usb_cdc_ncm_nth32 *nth32; + int len; + int ret = -EINVAL; + + if (ctx == NULL) + goto error; + + if (skb_in->len < (sizeof(struct usb_cdc_ncm_nth32) + + sizeof(struct usb_cdc_ncm_ndp32))) { + netif_dbg(dev, rx_err, dev->net, "frame too short\n"); + goto error; + } + + nth32 = (struct usb_cdc_ncm_nth32 *)skb_in->data; + + if (nth32->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH32_SIGN)) { + netif_dbg(dev, rx_err, dev->net, + "invalid NTH32 signature <%#010x>\n", + le32_to_cpu(nth32->dwSignature)); + goto error; + } + + len = le32_to_cpu(nth32->dwBlockLength); + if (len > ctx->rx_max) { + netif_dbg(dev, rx_err, dev->net, + "unsupported NTB block length %u/%u\n", len, + ctx->rx_max); + goto error; + } + + if ((ctx->rx_seq + 1) != le16_to_cpu(nth32->wSequence) && + (ctx->rx_seq || le16_to_cpu(nth32->wSequence)) && + !((ctx->rx_seq == 0xffff) && !le16_to_cpu(nth32->wSequence))) { + netif_dbg(dev, rx_err, dev->net, + "sequence number glitch prev=%d curr=%d\n", + ctx->rx_seq, le16_to_cpu(nth32->wSequence)); + } + ctx->rx_seq = le16_to_cpu(nth32->wSequence); + + ret = le32_to_cpu(nth32->dwNdpIndex); +error: + return ret; +} +EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_nth32); + /* verify NDP header and return number of datagrams, or negative error */ int cdc_ncm_rx_verify_ndp16(struct sk_buff *skb_in, int ndpoffset) { @@ -1495,42 +1667,110 @@ } EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp16); +/* verify NDP header and return number of datagrams, or negative error */ +int cdc_ncm_rx_verify_ndp32(struct sk_buff *skb_in, int ndpoffset) +{ + struct usbnet *dev = netdev_priv(skb_in->dev); + struct usb_cdc_ncm_ndp32 *ndp32; + int ret = -EINVAL; + + if ((ndpoffset + sizeof(struct usb_cdc_ncm_ndp32)) > skb_in->len) { + netif_dbg(dev, rx_err, dev->net, "invalid NDP offset <%u>\n", + ndpoffset); + goto error; + } + ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); + + if (le16_to_cpu(ndp32->wLength) < USB_CDC_NCM_NDP32_LENGTH_MIN) { + netif_dbg(dev, rx_err, dev->net, "invalid DPT32 length <%u>\n", + le16_to_cpu(ndp32->wLength)); + goto error; + } + + ret = ((le16_to_cpu(ndp32->wLength) - + sizeof(struct usb_cdc_ncm_ndp32)) / + sizeof(struct usb_cdc_ncm_dpe32)); + ret--; /* we process NDP entries except for the last one */ + + if ((sizeof(struct usb_cdc_ncm_ndp32) + + ret * (sizeof(struct usb_cdc_ncm_dpe32))) > skb_in->len) { + netif_dbg(dev, rx_err, dev->net, "Invalid nframes = %d\n", ret); + ret = -EINVAL; + } + +error: + return ret; +} +EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp32); + int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) { struct sk_buff *skb; struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; - int len; + unsigned int len; int nframes; int x; - int offset; - struct usb_cdc_ncm_ndp16 *ndp16; - struct usb_cdc_ncm_dpe16 *dpe16; + unsigned int offset; + union { + struct usb_cdc_ncm_ndp16 *ndp16; + struct usb_cdc_ncm_ndp32 *ndp32; + } ndp; + union { + struct usb_cdc_ncm_dpe16 *dpe16; + struct usb_cdc_ncm_dpe32 *dpe32; + } dpe; + int ndpoffset; int loopcount = 50; /* arbitrary max preventing infinite loop */ u32 payload = 0; - ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); + if (ctx->is_ndp16) + ndpoffset = cdc_ncm_rx_verify_nth16(ctx, skb_in); + else + ndpoffset = cdc_ncm_rx_verify_nth32(ctx, skb_in); + if (ndpoffset < 0) goto error; next_ndp: - nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); - if (nframes < 0) - goto error; + if (ctx->is_ndp16) { + nframes = cdc_ncm_rx_verify_ndp16(skb_in, ndpoffset); + if (nframes < 0) + goto error; - ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); + ndp.ndp16 = (struct usb_cdc_ncm_ndp16 *)(skb_in->data + ndpoffset); - if (ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { - netif_dbg(dev, rx_err, dev->net, - "invalid DPT16 signature <%#010x>\n", - le32_to_cpu(ndp16->dwSignature)); - goto err_ndp; - } - dpe16 = ndp16->dpe16; - - for (x = 0; x < nframes; x++, dpe16++) { - offset = le16_to_cpu(dpe16->wDatagramIndex); - len = le16_to_cpu(dpe16->wDatagramLength); + if (ndp.ndp16->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN)) { + netif_dbg(dev, rx_err, dev->net, + "invalid DPT16 signature <%#010x>\n", + le32_to_cpu(ndp.ndp16->dwSignature)); + goto err_ndp; + } + dpe.dpe16 = ndp.ndp16->dpe16; + } else { + nframes = cdc_ncm_rx_verify_ndp32(skb_in, ndpoffset); + if (nframes < 0) + goto error; + + ndp.ndp32 = (struct usb_cdc_ncm_ndp32 *)(skb_in->data + ndpoffset); + + if (ndp.ndp32->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN)) { + netif_dbg(dev, rx_err, dev->net, + "invalid DPT32 signature <%#010x>\n", + le32_to_cpu(ndp.ndp32->dwSignature)); + goto err_ndp; + } + dpe.dpe32 = ndp.ndp32->dpe32; + } + + for (x = 0; x < nframes; x++) { + if (ctx->is_ndp16) { + offset = le16_to_cpu(dpe.dpe16->wDatagramIndex); + len = le16_to_cpu(dpe.dpe16->wDatagramLength); + } else { + offset = le32_to_cpu(dpe.dpe32->dwDatagramIndex); + len = le32_to_cpu(dpe.dpe32->dwDatagramLength); + } /* * CDC NCM ch. 3.7 @@ -1542,8 +1782,8 @@ break; } - /* sanity checking */ - if (((offset + len) > skb_in->len) || + /* sanity checking - watch out for integer wrap*/ + if ((offset > skb_in->len) || (len > skb_in->len - offset) || (len > ctx->rx_max) || (len < ETH_HLEN)) { netif_dbg(dev, rx_err, dev->net, "invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n", @@ -1561,10 +1801,19 @@ usbnet_skb_return(dev, skb); payload += len; /* count payload bytes in this NTB */ } + + if (ctx->is_ndp16) + dpe.dpe16++; + else + dpe.dpe32++; } err_ndp: /* are there more NDPs to process? */ - ndpoffset = le16_to_cpu(ndp16->wNextNdpIndex); + if (ctx->is_ndp16) + ndpoffset = le16_to_cpu(ndp.ndp16->wNextNdpIndex); + else + ndpoffset = le32_to_cpu(ndp.ndp32->dwNextNdpIndex); + if (ndpoffset && loopcount--) goto next_ndp; @@ -1585,6 +1834,15 @@ uint32_t rx_speed = le32_to_cpu(data->DLBitRRate); uint32_t tx_speed = le32_to_cpu(data->ULBitRate); + /* if the speed hasn't changed, don't report it. + * RTL8156 shipped before 2021 sends notification about every 32ms. + */ + if (dev->rx_speed == rx_speed && dev->tx_speed == tx_speed) + return; + + dev->rx_speed = rx_speed; + dev->tx_speed = tx_speed; + /* * Currently the USB-NET API does not support reporting the actual * device speed. Do print it instead. @@ -1625,10 +1883,8 @@ * USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be * sent by device after USB_CDC_NOTIFY_SPEED_CHANGE. */ - netif_info(dev, link, dev->net, - "network connection: %sconnected\n", - !!event->wValue ? "" : "dis"); - usbnet_link_change(dev, !!event->wValue, 0); + if (netif_carrier_ok(dev->net) != !!event->wValue) + usbnet_link_change(dev, !!event->wValue, 0); break; case USB_CDC_NOTIFY_SPEED_CHANGE: @@ -1651,7 +1907,7 @@ static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET - | FLAG_LINK_INTR, + | FLAG_LINK_INTR | FLAG_ETHER, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, --- linux-oracle-5.4.0.orig/drivers/net/usb/ch9200.c +++ linux-oracle-5.4.0/drivers/net/usb/ch9200.c @@ -338,6 +338,7 @@ { int retval = 0; unsigned char data[2]; + u8 addr[ETH_ALEN]; retval = usbnet_get_endpoints(dev, intf); if (retval) @@ -385,7 +386,8 @@ retval = control_write(dev, REQUEST_WRITE, 0, MAC_REG_CTRL, data, 0x02, CONTROL_TIMEOUT_MS); - retval = get_mac_address(dev, dev->net->dev_addr); + retval = get_mac_address(dev, addr); + eth_hw_addr_set(dev->net, addr); return retval; } --- linux-oracle-5.4.0.orig/drivers/net/usb/cx82310_eth.c +++ linux-oracle-5.4.0/drivers/net/usb/cx82310_eth.c @@ -40,6 +40,11 @@ #define CX82310_MTU 1514 #define CMD_EP 0x01 +struct cx82310_priv { + struct work_struct reenable_work; + struct usbnet *dev; +}; + /* * execute control command * - optionally send some data (command parameters) @@ -115,6 +120,23 @@ return ret; } +static int cx82310_enable_ethernet(struct usbnet *dev) +{ + int ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0); + + if (ret) + netdev_err(dev->net, "unable to enable ethernet mode: %d\n", + ret); + return ret; +} + +static void cx82310_reenable_work(struct work_struct *work) +{ + struct cx82310_priv *priv = container_of(work, struct cx82310_priv, + reenable_work); + cx82310_enable_ethernet(priv->dev); +} + #define partial_len data[0] /* length of partial packet data */ #define partial_rem data[1] /* remaining (missing) data length */ #define partial_data data[2] /* partial packet data */ @@ -126,6 +148,8 @@ struct usb_device *udev = dev->udev; u8 link[3]; int timeout = 50; + struct cx82310_priv *priv; + u8 addr[ETH_ALEN]; /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0 @@ -152,6 +176,15 @@ if (!dev->partial_data) return -ENOMEM; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto err_partial; + } + dev->driver_priv = priv; + INIT_WORK(&priv->reenable_work, cx82310_reenable_work); + priv->dev = dev; + /* wait for firmware to become ready (indicated by the link being up) */ while (--timeout) { ret = cx82310_cmd(dev, CMD_GET_LINK_STATUS, true, NULL, 0, @@ -168,20 +201,17 @@ } /* enable ethernet mode (?) */ - ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0); - if (ret) { - dev_err(&udev->dev, "unable to enable ethernet mode: %d\n", - ret); + ret = cx82310_enable_ethernet(dev); + if (ret) goto err; - } /* get the MAC address */ - ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0, - dev->net->dev_addr, ETH_ALEN); + ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0, addr, ETH_ALEN); if (ret) { dev_err(&udev->dev, "unable to read MAC address: %d\n", ret); goto err; } + eth_hw_addr_set(dev->net, addr); /* start (does not seem to have any effect?) */ ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0); @@ -190,13 +220,19 @@ return 0; err: + kfree(dev->driver_priv); +err_partial: kfree((void *)dev->partial_data); return ret; } static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf) { + struct cx82310_priv *priv = dev->driver_priv; + kfree((void *)dev->partial_data); + cancel_work_sync(&priv->reenable_work); + kfree(dev->driver_priv); } /* @@ -211,6 +247,7 @@ { int len; struct sk_buff *skb2; + struct cx82310_priv *priv = dev->driver_priv; /* * If the last skb ended with an incomplete packet, this skb contains @@ -245,7 +282,10 @@ break; } - if (len > CX82310_MTU) { + if (len == 0xffff) { + netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode"); + schedule_work(&priv->reenable_work); + } else if (len > CX82310_MTU) { dev_err(&dev->udev->dev, "RX packet too long: %d B\n", len); return 0; --- linux-oracle-5.4.0.orig/drivers/net/usb/dm9601.c +++ linux-oracle-5.4.0/drivers/net/usb/dm9601.c @@ -221,13 +221,18 @@ struct usbnet *dev = netdev_priv(netdev); __le16 res; + int err; if (phy_id) { netdev_dbg(dev->net, "Only internal phy supported\n"); return 0; } - dm_read_shared_word(dev, 1, loc, &res); + err = dm_read_shared_word(dev, 1, loc, &res); + if (err < 0) { + netdev_err(dev->net, "MDIO read error: %d\n", err); + return 0; + } netdev_dbg(dev->net, "dm9601_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", @@ -625,6 +630,10 @@ USB_DEVICE(0x0a46, 0x1269), /* DM9621A USB to Fast Ethernet Adapter */ .driver_info = (unsigned long)&dm9601_info, }, + { + USB_DEVICE(0x0586, 0x3427), /* ZyXEL Keenetic Plus DSL xDSL modem */ + .driver_info = (unsigned long)&dm9601_info, + }, {}, // END }; --- linux-oracle-5.4.0.orig/drivers/net/usb/gl620a.c +++ linux-oracle-5.4.0/drivers/net/usb/gl620a.c @@ -179,9 +179,7 @@ { dev->hard_mtu = GL_RCV_BUF_SIZE; dev->net->hard_header_len += 4; - dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in); - dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out); - return 0; + return usbnet_get_endpoints(dev, intf); } static const struct driver_info genelink_info = { --- linux-oracle-5.4.0.orig/drivers/net/usb/hso.c +++ linux-oracle-5.4.0/drivers/net/usb/hso.c @@ -611,7 +611,7 @@ return serial; } -static int get_free_serial_index(void) +static int obtain_minor(struct hso_serial *serial) { int index; unsigned long flags; @@ -619,8 +619,10 @@ spin_lock_irqsave(&serial_table_lock, flags); for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) { if (serial_table[index] == NULL) { + serial_table[index] = serial->parent; + serial->minor = index; spin_unlock_irqrestore(&serial_table_lock, flags); - return index; + return 0; } } spin_unlock_irqrestore(&serial_table_lock, flags); @@ -629,15 +631,12 @@ return -1; } -static void set_serial_by_index(unsigned index, struct hso_serial *serial) +static void release_minor(struct hso_serial *serial) { unsigned long flags; spin_lock_irqsave(&serial_table_lock, flags); - if (serial) - serial_table[index] = serial->parent; - else - serial_table[index] = NULL; + serial_table[serial->minor] = NULL; spin_unlock_irqrestore(&serial_table_lock, flags); } @@ -1389,8 +1388,9 @@ unsigned long flags; if (old) - hso_dbg(0x16, "Termios called with: cflags new[%d] - old[%d]\n", - tty->termios.c_cflag, old->c_cflag); + hso_dbg(0x16, "Termios called with: cflags new[%u] - old[%u]\n", + (unsigned int)tty->termios.c_cflag, + (unsigned int)old->c_cflag); /* the actual setup */ spin_lock_irqsave(&serial->serial_lock, flags); @@ -1689,7 +1689,7 @@ spin_unlock_irqrestore(&serial->serial_lock, flags); return usb_control_msg(serial->parent->usb, - usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, + usb_sndctrlpipe(serial->parent->usb, 0), 0x22, 0x21, val, if_num, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -2229,6 +2229,7 @@ static void hso_serial_tty_unregister(struct hso_serial *serial) { tty_unregister_device(tty_drv, serial->minor); + release_minor(serial); } static void hso_serial_common_free(struct hso_serial *serial) @@ -2252,22 +2253,22 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, int rx_size, int tx_size) { - int minor; int i; tty_port_init(&serial->port); - minor = get_free_serial_index(); - if (minor < 0) - goto exit; + if (obtain_minor(serial)) + goto exit2; /* register our minor number */ serial->parent->dev = tty_port_register_device_attr(&serial->port, - tty_drv, minor, &serial->parent->interface->dev, + tty_drv, serial->minor, &serial->parent->interface->dev, serial->parent, hso_serial_dev_groups); + if (IS_ERR(serial->parent->dev)) { + release_minor(serial); + goto exit2; + } - /* fill in specific data for later use */ - serial->minor = minor; serial->magic = HSO_SERIAL_MAGIC; spin_lock_init(&serial->serial_lock); serial->num_rx_urbs = num_urbs; @@ -2309,6 +2310,7 @@ return 0; exit: hso_serial_tty_unregister(serial); +exit2: hso_serial_common_free(serial); return -1; } @@ -2434,7 +2436,7 @@ if (hso_dev->usb_gone) rv = 0; else - rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), + rv = usb_control_msg(hso_dev->usb, usb_sndctrlpipe(hso_dev->usb, 0), enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); mutex_unlock(&hso_dev->mutex); @@ -2495,7 +2497,7 @@ hso_net_init); if (!net) { dev_err(&interface->dev, "Unable to create ethernet device\n"); - goto exit; + goto err_hso_dev; } hso_net = netdev_priv(net); @@ -2508,13 +2510,13 @@ USB_DIR_IN); if (!hso_net->in_endp) { dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); - goto exit; + goto err_net; } hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT); if (!hso_net->out_endp) { dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); - goto exit; + goto err_net; } SET_NETDEV_DEV(net, &interface->dev); SET_NETDEV_DEVTYPE(net, &hso_type); @@ -2523,18 +2525,18 @@ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); if (!hso_net->mux_bulk_rx_urb_pool[i]) - goto exit; + goto err_mux_bulk_rx; hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_rx_buf_pool[i]) - goto exit; + goto err_mux_bulk_rx; } hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!hso_net->mux_bulk_tx_urb) - goto exit; + goto err_mux_bulk_rx; hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_tx_buf) - goto exit; + goto err_free_tx_urb; add_net_device(hso_dev); @@ -2542,7 +2544,7 @@ result = register_netdev(net); if (result) { dev_err(&interface->dev, "Failed to register device\n"); - goto exit; + goto err_free_tx_buf; } hso_log_port(hso_dev); @@ -2550,8 +2552,21 @@ hso_create_rfkill(hso_dev, interface); return hso_dev; -exit: - hso_free_net_device(hso_dev); + +err_free_tx_buf: + remove_net_device(hso_dev); + kfree(hso_net->mux_bulk_tx_buf); +err_free_tx_urb: + usb_free_urb(hso_net->mux_bulk_tx_urb); +err_mux_bulk_rx: + for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { + usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); + kfree(hso_net->mux_bulk_rx_buf_pool[i]); + } +err_net: + free_netdev(net); +err_hso_dev: + kfree(hso_dev); return NULL; } @@ -2617,32 +2632,31 @@ num_urbs = 2; serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), GFP_KERNEL); + if (!serial->tiocmget) + goto exit; serial->tiocmget->serial_state_notification = kzalloc(sizeof(struct hso_serial_state_notification), GFP_KERNEL); - /* it isn't going to break our heart if serial->tiocmget - * allocation fails don't bother checking this. - */ - if (serial->tiocmget && serial->tiocmget->serial_state_notification) { - tiocmget = serial->tiocmget; - tiocmget->endp = hso_get_ep(interface, - USB_ENDPOINT_XFER_INT, - USB_DIR_IN); - if (!tiocmget->endp) { - dev_err(&interface->dev, "Failed to find INT IN ep\n"); - goto exit; - } - - tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); - if (tiocmget->urb) { - mutex_init(&tiocmget->mutex); - init_waitqueue_head(&tiocmget->waitq); - } else - hso_free_tiomget(serial); + if (!serial->tiocmget->serial_state_notification) + goto exit; + tiocmget = serial->tiocmget; + tiocmget->endp = hso_get_ep(interface, + USB_ENDPOINT_XFER_INT, + USB_DIR_IN); + if (!tiocmget->endp) { + dev_err(&interface->dev, "Failed to find INT IN ep\n"); + goto exit; } - } - else + + tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL); + if (!tiocmget->urb) + goto exit; + + mutex_init(&tiocmget->mutex); + init_waitqueue_head(&tiocmget->waitq); + } else { num_urbs = 1; + } if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE, BULK_URB_TX_SIZE)) @@ -2664,9 +2678,6 @@ serial->write_data = hso_std_serial_write_data; - /* and record this serial */ - set_serial_by_index(serial->minor, serial); - /* setup the proc dirs and files if needed */ hso_log_port(hso_dev); @@ -2706,14 +2717,14 @@ serial = kzalloc(sizeof(*serial), GFP_KERNEL); if (!serial) - goto exit; + goto err_free_dev; hso_dev->port_data.dev_serial = serial; serial->parent = hso_dev; if (hso_serial_common_create (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE)) - goto exit; + goto err_free_serial; serial->tx_data_length--; serial->write_data = hso_mux_serial_write_data; @@ -2723,20 +2734,15 @@ serial->shared_int->ref_count++; mutex_unlock(&serial->shared_int->shared_int_lock); - /* and record this serial */ - set_serial_by_index(serial->minor, serial); - /* setup the proc dirs and files if needed */ hso_log_port(hso_dev); /* done, return it */ return hso_dev; -exit: - if (serial) { - tty_unregister_device(tty_drv, serial->minor); - kfree(serial); - } +err_free_serial: + kfree(serial); +err_free_dev: kfree(hso_dev); return NULL; @@ -3109,8 +3115,7 @@ cancel_work_sync(&serial_table[i]->async_put_intf); cancel_work_sync(&serial_table[i]->async_get_intf); hso_serial_tty_unregister(serial); - kref_put(&serial_table[i]->ref, hso_serial_ref_free); - set_serial_by_index(i, NULL); + kref_put(&serial->parent->ref, hso_serial_ref_free); } } --- linux-oracle-5.4.0.orig/drivers/net/usb/huawei_cdc_ncm.c +++ linux-oracle-5.4.0/drivers/net/usb/huawei_cdc_ncm.c @@ -77,11 +77,11 @@ */ drvflags |= CDC_NCM_FLAG_NDP_TO_END; - /* Additionally, it has been reported that some Huawei E3372H devices, with - * firmware version 21.318.01.00.541, come out of reset in NTB32 format mode, hence - * needing to be set to the NTB16 one again. + /* For many Huawei devices the NTB32 mode is the default and the best mode + * they work with. Huawei E5785 and E5885 devices refuse to work in NTB16 mode at all. */ - drvflags |= CDC_NCM_FLAG_RESET_NTB16; + drvflags |= CDC_NCM_FLAG_PREFER_NTB32; + ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags); if (ret) goto err; --- linux-oracle-5.4.0.orig/drivers/net/usb/ipheth.c +++ linux-oracle-5.4.0/drivers/net/usb/ipheth.c @@ -59,7 +59,7 @@ #define IPHETH_USBINTF_SUBCLASS 253 #define IPHETH_USBINTF_PROTO 1 -#define IPHETH_BUF_SIZE 1516 +#define IPHETH_BUF_SIZE 1514 #define IPHETH_IP_ALIGN 2 /* padding at front of URB */ #define IPHETH_TX_TIMEOUT (5 * HZ) @@ -121,7 +121,7 @@ if (tx_buf == NULL) goto free_rx_urb; - rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE, + rx_buf = usb_alloc_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, GFP_KERNEL, &rx_urb->transfer_dma); if (rx_buf == NULL) goto free_tx_buf; @@ -146,7 +146,7 @@ static void ipheth_free_urbs(struct ipheth_device *iphone) { - usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->rx_buf, + usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, iphone->rx_buf, iphone->rx_urb->transfer_dma); usb_free_coherent(iphone->udev, IPHETH_BUF_SIZE, iphone->tx_buf, iphone->tx_urb->transfer_dma); @@ -253,13 +253,14 @@ 0x02, /* index */ dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE, IPHETH_CTRL_TIMEOUT); - if (retval < 0) { + if (retval <= 0) { dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n", __func__, retval); return retval; } - if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) { + if ((retval == 1 && dev->ctrl_buf[0] == IPHETH_CARRIER_ON) || + (retval >= 2 && dev->ctrl_buf[1] == IPHETH_CARRIER_ON)) { netif_carrier_on(dev->net); if (dev->tx_urb->status != -EINPROGRESS) netif_wake_queue(dev->net); @@ -317,7 +318,7 @@ usb_fill_bulk_urb(dev->rx_urb, udev, usb_rcvbulkpipe(udev, dev->bulk_in), - dev->rx_buf, IPHETH_BUF_SIZE, + dev->rx_buf, IPHETH_BUF_SIZE + IPHETH_IP_ALIGN, ipheth_rcvbulk_callback, dev); dev->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -353,8 +354,8 @@ { struct ipheth_device *dev = netdev_priv(net); - cancel_delayed_work_sync(&dev->carrier_work); netif_stop_queue(net); + cancel_delayed_work_sync(&dev->carrier_work); return 0; } @@ -443,7 +444,7 @@ netdev->netdev_ops = &ipheth_netdev_ops; netdev->watchdog_timeo = IPHETH_TX_TIMEOUT; - strcpy(netdev->name, "eth%d"); + strscpy(netdev->name, "eth%d", sizeof(netdev->name)); dev = netdev_priv(netdev); dev->udev = udev; --- linux-oracle-5.4.0.orig/drivers/net/usb/kalmia.c +++ linux-oracle-5.4.0/drivers/net/usb/kalmia.c @@ -65,8 +65,8 @@ init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT); if (status != 0) { netdev_err(dev->net, - "Error sending init packet. Status %i, length %i\n", - status, act_len); + "Error sending init packet. Status %i\n", + status); return status; } else if (act_len != init_msg_len) { @@ -83,8 +83,8 @@ if (status != 0) netdev_err(dev->net, - "Error receiving init result. Status %i, length %i\n", - status, act_len); + "Error receiving init result. Status %i\n", + status); else if (act_len != expected_len) netdev_err(dev->net, "Unexpected init result length: %i\n", act_len); --- linux-oracle-5.4.0.orig/drivers/net/usb/kaweth.c +++ linux-oracle-5.4.0/drivers/net/usb/kaweth.c @@ -1127,8 +1127,7 @@ goto err_all_but_rxbuf; memcpy(netdev->broadcast, &bcast_addr, sizeof(bcast_addr)); - memcpy(netdev->dev_addr, &kaweth->configuration.hw_addr, - sizeof(kaweth->configuration.hw_addr)); + eth_hw_addr_set(netdev, (u8 *)&kaweth->configuration.hw_addr); netdev->netdev_ops = &kaweth_netdev_ops; netdev->watchdog_timeo = KAWETH_TX_TIMEOUT; --- linux-oracle-5.4.0.orig/drivers/net/usb/lan78xx.c +++ linux-oracle-5.4.0/drivers/net/usb/lan78xx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,8 @@ #define LAN7801_USB_PRODUCT_ID (0x7801) #define LAN78XX_EEPROM_MAGIC (0x78A5) #define LAN78XX_OTP_MAGIC (0x78F3) +#define AT29M2AF_USB_VENDOR_ID (0x07C9) +#define AT29M2AF_USB_PRODUCT_ID (0x0012) #define MII_READ 1 #define MII_WRITE 0 @@ -87,6 +90,12 @@ /* statistic update interval (mSec) */ #define STAT_UPDATE_TIMER (1 * 1000) +/* time to wait for MAC or FCT to stop (jiffies) */ +#define HW_DISABLE_TIMEOUT (HZ / 10) + +/* time to wait between polling MAC or FCT state (ms) */ +#define HW_DISABLE_DELAY_MS 1 + /* defines interrupts from interrupt EP */ #define MAX_INT_EP (32) #define INT_EP_INTEP (31) @@ -376,17 +385,14 @@ struct tasklet_struct bh; struct delayed_work wq; - struct usb_host_endpoint *ep_blkin; - struct usb_host_endpoint *ep_blkout; - struct usb_host_endpoint *ep_intr; - int msg_enable; struct urb *urb_intr; struct usb_anchor deferred; + struct mutex dev_mutex; /* serialise open/stop wrt suspend/resume */ struct mutex phy_mutex; /* for phy access */ - unsigned pipe_in, pipe_out, pipe_intr; + unsigned int pipe_in, pipe_out, pipe_intr; u32 hard_mtu; /* count any extra framing */ size_t rx_urb_size; /* size for rx urbs */ @@ -396,7 +402,7 @@ wait_queue_head_t *wait; unsigned char suspend_count; - unsigned maxpacket; + unsigned int maxpacket; struct timer_list delay; struct timer_list stat_monitor; @@ -480,6 +486,26 @@ return ret; } +static int lan78xx_update_reg(struct lan78xx_net *dev, u32 reg, u32 mask, + u32 data) +{ + int ret; + u32 buf; + + ret = lan78xx_read_reg(dev, reg, &buf); + if (ret < 0) + return ret; + + buf &= ~mask; + buf |= (mask & data); + + ret = lan78xx_write_reg(dev, reg, buf); + if (ret < 0) + return ret; + + return 0; +} + static int lan78xx_read_stats(struct lan78xx_net *dev, struct lan78xx_statstage *data) { @@ -505,13 +531,13 @@ if (likely(ret >= 0)) { src = (u32 *)stats; dst = (u32 *)data; - for (i = 0; i < sizeof(*stats)/sizeof(u32); i++) { + for (i = 0; i < sizeof(*stats) / sizeof(u32); i++) { le32_to_cpus(&src[i]); dst[i] = src[i]; } } else { netdev_warn(dev->net, - "Failed to read stat ret = 0x%x", ret); + "Failed to read stat ret = %d", ret); } kfree(stats); @@ -519,10 +545,11 @@ return ret; } -#define check_counter_rollover(struct1, dev_stats, member) { \ - if (struct1->member < dev_stats.saved.member) \ - dev_stats.rollover_count.member++; \ - } +#define check_counter_rollover(struct1, dev_stats, member) \ + do { \ + if ((struct1)->member < (dev_stats).saved.member) \ + (dev_stats).rollover_count.member++; \ + } while (0) static void lan78xx_check_stat_rollover(struct lan78xx_net *dev, struct lan78xx_statstage *stats) @@ -825,20 +852,19 @@ u32 length, u8 *data) { int i; - int ret; u32 buf; unsigned long timeout; - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (buf & OTP_PWR_DN_PWRDN_N_) { /* clear it and wait to be cleared */ - ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); + lan78xx_write_reg(dev, OTP_PWR_DN, 0); timeout = jiffies + HZ; do { usleep_range(1, 10); - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_PWR_DN"); @@ -848,18 +874,18 @@ } for (i = 0; i < length; i++) { - ret = lan78xx_write_reg(dev, OTP_ADDR1, - ((offset + i) >> 8) & OTP_ADDR1_15_11); - ret = lan78xx_write_reg(dev, OTP_ADDR2, - ((offset + i) & OTP_ADDR2_10_3)); + lan78xx_write_reg(dev, OTP_ADDR1, + ((offset + i) >> 8) & OTP_ADDR1_15_11); + lan78xx_write_reg(dev, OTP_ADDR2, + ((offset + i) & OTP_ADDR2_10_3)); - ret = lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); - ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + lan78xx_write_reg(dev, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); + lan78xx_read_reg(dev, OTP_STATUS, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_STATUS"); @@ -867,7 +893,7 @@ } } while (buf & OTP_STATUS_BUSY_); - ret = lan78xx_read_reg(dev, OTP_RD_DATA, &buf); + lan78xx_read_reg(dev, OTP_RD_DATA, &buf); data[i] = (u8)(buf & 0xFF); } @@ -879,20 +905,19 @@ u32 length, u8 *data) { int i; - int ret; u32 buf; unsigned long timeout; - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (buf & OTP_PWR_DN_PWRDN_N_) { /* clear it and wait to be cleared */ - ret = lan78xx_write_reg(dev, OTP_PWR_DN, 0); + lan78xx_write_reg(dev, OTP_PWR_DN, 0); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_PWR_DN, &buf); + lan78xx_read_reg(dev, OTP_PWR_DN, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on OTP_PWR_DN completion"); @@ -902,21 +927,21 @@ } /* set to BYTE program mode */ - ret = lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); + lan78xx_write_reg(dev, OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_); for (i = 0; i < length; i++) { - ret = lan78xx_write_reg(dev, OTP_ADDR1, - ((offset + i) >> 8) & OTP_ADDR1_15_11); - ret = lan78xx_write_reg(dev, OTP_ADDR2, - ((offset + i) & OTP_ADDR2_10_3)); - ret = lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); - ret = lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); - ret = lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); + lan78xx_write_reg(dev, OTP_ADDR1, + ((offset + i) >> 8) & OTP_ADDR1_15_11); + lan78xx_write_reg(dev, OTP_ADDR2, + ((offset + i) & OTP_ADDR2_10_3)); + lan78xx_write_reg(dev, OTP_PRGM_DATA, data[i]); + lan78xx_write_reg(dev, OTP_TST_CMD, OTP_TST_CMD_PRGVRFY_); + lan78xx_write_reg(dev, OTP_CMD_GO, OTP_CMD_GO_GO_); timeout = jiffies + HZ; do { udelay(1); - ret = lan78xx_read_reg(dev, OTP_STATUS, &buf); + lan78xx_read_reg(dev, OTP_STATUS, &buf); if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "Timeout on OTP_STATUS completion"); @@ -965,7 +990,7 @@ usleep_range(40, 100); } - netdev_warn(dev->net, "lan78xx_dataport_wait_not_busy timed out"); + netdev_warn(dev->net, "%s timed out", __func__); return -EIO; } @@ -978,7 +1003,7 @@ int i, ret; if (usb_autopm_get_interface(dev->intf) < 0) - return 0; + return 0; mutex_lock(&pdata->dataport_mutex); @@ -1041,7 +1066,6 @@ container_of(param, struct lan78xx_priv, set_multicast); struct lan78xx_net *dev = pdata->dev; int i; - int ret; netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x\n", pdata->rfe_ctl); @@ -1050,14 +1074,14 @@ DP_SEL_VHF_HASH_LEN, pdata->mchash_table); for (i = 1; i < NUM_OF_MAF; i++) { - ret = lan78xx_write_reg(dev, MAF_HI(i), 0); - ret = lan78xx_write_reg(dev, MAF_LO(i), - pdata->pfilter_table[i][1]); - ret = lan78xx_write_reg(dev, MAF_HI(i), - pdata->pfilter_table[i][0]); + lan78xx_write_reg(dev, MAF_HI(i), 0); + lan78xx_write_reg(dev, MAF_LO(i), + pdata->pfilter_table[i][1]); + lan78xx_write_reg(dev, MAF_HI(i), + pdata->pfilter_table[i][0]); } - ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); } static void lan78xx_set_multicast(struct net_device *netdev) @@ -1073,11 +1097,12 @@ RFE_CTL_DA_PERFECT_ | RFE_CTL_MCAST_HASH_); for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++) - pdata->mchash_table[i] = 0; + pdata->mchash_table[i] = 0; + /* pfilter_table[0] has own HW address */ for (i = 1; i < NUM_OF_MAF; i++) { - pdata->pfilter_table[i][0] = - pdata->pfilter_table[i][1] = 0; + pdata->pfilter_table[i][0] = 0; + pdata->pfilter_table[i][1] = 0; } pdata->rfe_ctl |= RFE_CTL_BCAST_EN_; @@ -1127,7 +1152,6 @@ u16 lcladv, u16 rmtadv) { u32 flow = 0, fct_flow = 0; - int ret; u8 cap; if (dev->fc_autoneg) @@ -1150,10 +1174,10 @@ (cap & FLOW_CTRL_RX ? "enabled" : "disabled"), (cap & FLOW_CTRL_TX ? "enabled" : "disabled")); - ret = lan78xx_write_reg(dev, FCT_FLOW, fct_flow); + lan78xx_write_reg(dev, FCT_FLOW, fct_flow); /* threshold value should be set before enabling flow */ - ret = lan78xx_write_reg(dev, FLOW, flow); + lan78xx_write_reg(dev, FLOW, flow); return 0; } @@ -1162,30 +1186,33 @@ { struct phy_device *phydev = dev->net->phydev; struct ethtool_link_ksettings ecmd; - int ladv, radv, ret; + int ladv, radv, ret, link; u32 buf; /* clear LAN78xx interrupt status */ ret = lan78xx_write_reg(dev, INT_STS, INT_STS_PHY_INT_); if (unlikely(ret < 0)) - return -EIO; + return ret; + mutex_lock(&phydev->lock); phy_read_status(phydev); + link = phydev->link; + mutex_unlock(&phydev->lock); - if (!phydev->link && dev->link_on) { + if (!link && dev->link_on) { dev->link_on = false; /* reset MAC */ ret = lan78xx_read_reg(dev, MAC_CR, &buf); if (unlikely(ret < 0)) - return -EIO; + return ret; buf |= MAC_CR_RST_; ret = lan78xx_write_reg(dev, MAC_CR, buf); if (unlikely(ret < 0)) - return -EIO; + return ret; del_timer(&dev->stat_monitor); - } else if (phydev->link && !dev->link_on) { + } else if (link && !dev->link_on) { dev->link_on = true; phy_ethtool_ksettings_get(phydev, &ecmd); @@ -1194,18 +1221,30 @@ if (ecmd.base.speed == 1000) { /* disable U2 */ ret = lan78xx_read_reg(dev, USB_CFG1, &buf); + if (ret < 0) + return ret; buf &= ~USB_CFG1_DEV_U2_INIT_EN_; ret = lan78xx_write_reg(dev, USB_CFG1, buf); + if (ret < 0) + return ret; /* enable U1 */ ret = lan78xx_read_reg(dev, USB_CFG1, &buf); + if (ret < 0) + return ret; buf |= USB_CFG1_DEV_U1_INIT_EN_; ret = lan78xx_write_reg(dev, USB_CFG1, buf); + if (ret < 0) + return ret; } else { /* enable U1 & U2 */ ret = lan78xx_read_reg(dev, USB_CFG1, &buf); + if (ret < 0) + return ret; buf |= USB_CFG1_DEV_U2_INIT_EN_; buf |= USB_CFG1_DEV_U1_INIT_EN_; ret = lan78xx_write_reg(dev, USB_CFG1, buf); + if (ret < 0) + return ret; } } @@ -1223,6 +1262,8 @@ ret = lan78xx_update_flowcontrol(dev, ecmd.base.duplex, ladv, radv); + if (ret < 0) + return ret; if (!timer_pending(&dev->stat_monitor)) { dev->delta = 1; @@ -1233,7 +1274,7 @@ tasklet_schedule(&dev->bh); } - return ret; + return 0; } /* some work can't be done in tasklets, so we use keventd @@ -1269,9 +1310,10 @@ generic_handle_irq(dev->domain_data.phyirq); local_irq_enable(); } - } else + } else { netdev_warn(dev->net, "unexpected interrupt: 0x%08x\n", intdata); + } } static int lan78xx_ethtool_get_eeprom_len(struct net_device *netdev) @@ -1360,7 +1402,7 @@ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); if (usb_autopm_get_interface(dev->intf) < 0) - return; + return; ret = lan78xx_read_reg(dev, USB_CFG0, &buf); if (unlikely(ret < 0)) { @@ -1386,13 +1428,13 @@ struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); int ret; + if (wol->wolopts & ~WAKE_ALL) + return -EINVAL; + ret = usb_autopm_get_interface(dev->intf); if (ret < 0) return ret; - if (wol->wolopts & ~WAKE_ALL) - return -EINVAL; - pdata->wol = wol->wolopts; device_set_wakeup_enable(&dev->udev->dev, (bool)wol->wolopts); @@ -1474,9 +1516,14 @@ static u32 lan78xx_get_link(struct net_device *net) { + u32 link; + + mutex_lock(&net->phydev->lock); phy_read_status(net->phydev); + link = net->phydev->link; + mutex_unlock(&net->phydev->lock); - return net->phydev->link; + return link; } static void lan78xx_get_drvinfo(struct net_device *net, @@ -1674,11 +1721,10 @@ static void lan78xx_init_mac_address(struct lan78xx_net *dev) { u32 addr_lo, addr_hi; - int ret; u8 addr[6]; - ret = lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); - ret = lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); + lan78xx_read_reg(dev, RX_ADDRL, &addr_lo); + lan78xx_read_reg(dev, RX_ADDRH, &addr_hi); addr[0] = addr_lo & 0xFF; addr[1] = (addr_lo >> 8) & 0xFF; @@ -1711,12 +1757,12 @@ (addr[2] << 16) | (addr[3] << 24); addr_hi = addr[4] | (addr[5] << 8); - ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); - ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + lan78xx_write_reg(dev, RX_ADDRL, addr_lo); + lan78xx_write_reg(dev, RX_ADDRH, addr_hi); } - ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); - ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); ether_addr_copy(dev->net->dev_addr, addr); } @@ -1808,6 +1854,7 @@ dev->mdiobus->read = lan78xx_mdiobus_read; dev->mdiobus->write = lan78xx_mdiobus_write; dev->mdiobus->name = "lan78xx-mdiobus"; + dev->mdiobus->parent = &dev->udev->dev; snprintf(dev->mdiobus->id, MII_BUS_ID_SIZE, "usb-%03d:%03d", dev->udev->bus->busnum, dev->udev->devnum); @@ -1848,33 +1895,8 @@ static void lan78xx_link_status_change(struct net_device *net) { struct phy_device *phydev = net->phydev; - int ret, temp; - - /* At forced 100 F/H mode, chip may fail to set mode correctly - * when cable is switched between long(~50+m) and short one. - * As workaround, set to 10 before setting to 100 - * at forced 100 F/H mode. - */ - if (!phydev->autoneg && (phydev->speed == 100)) { - /* disable phy interrupt */ - temp = phy_read(phydev, LAN88XX_INT_MASK); - temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_; - ret = phy_write(phydev, LAN88XX_INT_MASK, temp); - temp = phy_read(phydev, MII_BMCR); - temp &= ~(BMCR_SPEED100 | BMCR_SPEED1000); - phy_write(phydev, MII_BMCR, temp); /* set to 10 first */ - temp |= BMCR_SPEED100; - phy_write(phydev, MII_BMCR, temp); /* set to 100 later */ - - /* clear pending interrupt generated while workaround */ - temp = phy_read(phydev, LAN88XX_INT_STS); - - /* enable phy interrupt back */ - temp = phy_read(phydev, LAN88XX_INT_MASK); - temp |= LAN88XX_INT_MASK_MDINTPIN_EN_; - ret = phy_write(phydev, LAN88XX_INT_MASK, temp); - } + phy_print_status(phydev); } static int irq_map(struct irq_domain *d, unsigned int irq, @@ -1927,14 +1949,13 @@ struct lan78xx_net *dev = container_of(data, struct lan78xx_net, domain_data); u32 buf; - int ret; /* call register access here because irq_bus_lock & irq_bus_sync_unlock * are only two callbacks executed in non-atomic contex. */ - ret = lan78xx_read_reg(dev, INT_EP_CTL, &buf); + lan78xx_read_reg(dev, INT_EP_CTL, &buf); if (buf != data->irqenable) - ret = lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); + lan78xx_write_reg(dev, INT_EP_CTL, data->irqenable); mutex_unlock(&data->irq_lock); } @@ -2001,7 +2022,6 @@ static int lan8835_fixup(struct phy_device *phydev) { int buf; - int ret; struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); /* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */ @@ -2011,11 +2031,11 @@ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8010, buf); /* RGMII MAC TXC Delay Enable */ - ret = lan78xx_write_reg(dev, MAC_RGMII_ID, - MAC_RGMII_ID_TXC_DELAY_EN_); + lan78xx_write_reg(dev, MAC_RGMII_ID, + MAC_RGMII_ID_TXC_DELAY_EN_); /* RGMII TX DLL Tune Adjust */ - ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); + lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); dev->interface = PHY_INTERFACE_MODE_RGMII_TXID; @@ -2130,7 +2150,7 @@ if (dev->domain_data.phyirq > 0) phydev->irq = dev->domain_data.phyirq; else - phydev->irq = 0; + phydev->irq = PHY_POLL; netdev_dbg(dev->net, "phydev->irq = %d\n", phydev->irq); /* set to AUTOMDIX */ @@ -2145,6 +2165,7 @@ if (dev->chipid == ID_REV_CHIP_ID_7801_) { if (phy_is_pseudo_fixed_link(phydev)) { fixed_phy_unregister(phydev); + phy_device_free(phydev); } else { phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); @@ -2199,28 +2220,27 @@ static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) { - int ret = 0; u32 buf; bool rxenabled; - ret = lan78xx_read_reg(dev, MAC_RX, &buf); + lan78xx_read_reg(dev, MAC_RX, &buf); rxenabled = ((buf & MAC_RX_RXEN_) != 0); if (rxenabled) { buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); } /* add 4 to size for FCS */ buf &= ~MAC_RX_MAX_SIZE_MASK_; buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT_) & MAC_RX_MAX_SIZE_MASK_); - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); if (rxenabled) { buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + lan78xx_write_reg(dev, MAC_RX, buf); } return 0; @@ -2283,7 +2303,11 @@ if ((ll_mtu % dev->maxpacket) == 0) return -EDOM; - ret = lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); + ret = usb_autopm_get_interface(dev->intf); + if (ret < 0) + return ret; + + lan78xx_set_rx_max_frame_length(dev, new_mtu + VLAN_ETH_HLEN); netdev->mtu = new_mtu; @@ -2298,6 +2322,8 @@ } } + usb_autopm_put_interface(dev->intf); + return 0; } @@ -2306,7 +2332,6 @@ struct lan78xx_net *dev = netdev_priv(netdev); struct sockaddr *addr = p; u32 addr_lo, addr_hi; - int ret; if (netif_running(netdev)) return -EBUSY; @@ -2323,12 +2348,12 @@ addr_hi = netdev->dev_addr[4] | netdev->dev_addr[5] << 8; - ret = lan78xx_write_reg(dev, RX_ADDRL, addr_lo); - ret = lan78xx_write_reg(dev, RX_ADDRH, addr_hi); + lan78xx_write_reg(dev, RX_ADDRL, addr_lo); + lan78xx_write_reg(dev, RX_ADDRH, addr_hi); /* Added to support MAC address changes */ - ret = lan78xx_write_reg(dev, MAF_LO(0), addr_lo); - ret = lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); + lan78xx_write_reg(dev, MAF_LO(0), addr_lo); + lan78xx_write_reg(dev, MAF_HI(0), addr_hi | MAF_HI_VALID_); return 0; } @@ -2340,7 +2365,6 @@ struct lan78xx_net *dev = netdev_priv(netdev); struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); unsigned long flags; - int ret; spin_lock_irqsave(&pdata->rfe_ctl_lock, flags); @@ -2364,7 +2388,7 @@ spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags); - ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); return 0; } @@ -2456,26 +2480,186 @@ lan78xx_write_reg(dev, LTM_INACTIVE1, regs[5]); } +static int lan78xx_start_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enable) +{ + return lan78xx_update_reg(dev, reg, hw_enable, hw_enable); +} + +static int lan78xx_stop_hw(struct lan78xx_net *dev, u32 reg, u32 hw_enabled, + u32 hw_disabled) +{ + unsigned long timeout; + bool stopped = true; + int ret; + u32 buf; + + /* Stop the h/w block (if not already stopped) */ + + ret = lan78xx_read_reg(dev, reg, &buf); + if (ret < 0) + return ret; + + if (buf & hw_enabled) { + buf &= ~hw_enabled; + + ret = lan78xx_write_reg(dev, reg, buf); + if (ret < 0) + return ret; + + stopped = false; + timeout = jiffies + HW_DISABLE_TIMEOUT; + do { + ret = lan78xx_read_reg(dev, reg, &buf); + if (ret < 0) + return ret; + + if (buf & hw_disabled) + stopped = true; + else + msleep(HW_DISABLE_DELAY_MS); + } while (!stopped && !time_after(jiffies, timeout)); + } + + ret = stopped ? 0 : -ETIME; + + return ret; +} + +static int lan78xx_flush_fifo(struct lan78xx_net *dev, u32 reg, u32 fifo_flush) +{ + return lan78xx_update_reg(dev, reg, fifo_flush, fifo_flush); +} + +static int lan78xx_start_tx_path(struct lan78xx_net *dev) +{ + int ret; + + netif_dbg(dev, drv, dev->net, "start tx path"); + + /* Start the MAC transmitter */ + + ret = lan78xx_start_hw(dev, MAC_TX, MAC_TX_TXEN_); + if (ret < 0) + return ret; + + /* Start the Tx FIFO */ + + ret = lan78xx_start_hw(dev, FCT_TX_CTL, FCT_TX_CTL_EN_); + if (ret < 0) + return ret; + + return 0; +} + +static int lan78xx_stop_tx_path(struct lan78xx_net *dev) +{ + int ret; + + netif_dbg(dev, drv, dev->net, "stop tx path"); + + /* Stop the Tx FIFO */ + + ret = lan78xx_stop_hw(dev, FCT_TX_CTL, FCT_TX_CTL_EN_, FCT_TX_CTL_DIS_); + if (ret < 0) + return ret; + + /* Stop the MAC transmitter */ + + ret = lan78xx_stop_hw(dev, MAC_TX, MAC_TX_TXEN_, MAC_TX_TXD_); + if (ret < 0) + return ret; + + return 0; +} + +/* The caller must ensure the Tx path is stopped before calling + * lan78xx_flush_tx_fifo(). + */ +static int lan78xx_flush_tx_fifo(struct lan78xx_net *dev) +{ + return lan78xx_flush_fifo(dev, FCT_TX_CTL, FCT_TX_CTL_RST_); +} + +static int lan78xx_start_rx_path(struct lan78xx_net *dev) +{ + int ret; + + netif_dbg(dev, drv, dev->net, "start rx path"); + + /* Start the Rx FIFO */ + + ret = lan78xx_start_hw(dev, FCT_RX_CTL, FCT_RX_CTL_EN_); + if (ret < 0) + return ret; + + /* Start the MAC receiver*/ + + ret = lan78xx_start_hw(dev, MAC_RX, MAC_RX_RXEN_); + if (ret < 0) + return ret; + + return 0; +} + +static int lan78xx_stop_rx_path(struct lan78xx_net *dev) +{ + int ret; + + netif_dbg(dev, drv, dev->net, "stop rx path"); + + /* Stop the MAC receiver */ + + ret = lan78xx_stop_hw(dev, MAC_RX, MAC_RX_RXEN_, MAC_RX_RXD_); + if (ret < 0) + return ret; + + /* Stop the Rx FIFO */ + + ret = lan78xx_stop_hw(dev, FCT_RX_CTL, FCT_RX_CTL_EN_, FCT_RX_CTL_DIS_); + if (ret < 0) + return ret; + + return 0; +} + +/* The caller must ensure the Rx path is stopped before calling + * lan78xx_flush_rx_fifo(). + */ +static int lan78xx_flush_rx_fifo(struct lan78xx_net *dev) +{ + return lan78xx_flush_fifo(dev, FCT_RX_CTL, FCT_RX_CTL_RST_); +} + static int lan78xx_reset(struct lan78xx_net *dev) { struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); - u32 buf; - int ret = 0; unsigned long timeout; + int ret; + u32 buf; u8 sig; ret = lan78xx_read_reg(dev, HW_CFG, &buf); + if (ret < 0) + return ret; + buf |= HW_CFG_LRST_; + ret = lan78xx_write_reg(dev, HW_CFG, buf); + if (ret < 0) + return ret; timeout = jiffies + HZ; do { mdelay(1); ret = lan78xx_read_reg(dev, HW_CFG, &buf); + if (ret < 0) + return ret; + if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout on completion of LiteReset"); - return -EIO; + ret = -ETIMEDOUT; + return ret; } } while (buf & HW_CFG_LRST_); @@ -2483,13 +2667,22 @@ /* save DEVID for later usage */ ret = lan78xx_read_reg(dev, ID_REV, &buf); + if (ret < 0) + return ret; + dev->chipid = (buf & ID_REV_CHIP_ID_MASK_) >> 16; dev->chiprev = buf & ID_REV_CHIP_REV_MASK_; /* Respond to the IN token with a NAK */ ret = lan78xx_read_reg(dev, USB_CFG0, &buf); + if (ret < 0) + return ret; + buf |= USB_CFG_BIR_; + ret = lan78xx_write_reg(dev, USB_CFG0, buf); + if (ret < 0) + return ret; /* Init LTM */ lan78xx_init_ltm(dev); @@ -2512,58 +2705,111 @@ } ret = lan78xx_write_reg(dev, BURST_CAP, buf); + if (ret < 0) + return ret; + ret = lan78xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY); + if (ret < 0) + return ret; ret = lan78xx_read_reg(dev, HW_CFG, &buf); + if (ret < 0) + return ret; + buf |= HW_CFG_MEF_; + ret = lan78xx_write_reg(dev, HW_CFG, buf); + if (ret < 0) + return ret; ret = lan78xx_read_reg(dev, USB_CFG0, &buf); + if (ret < 0) + return ret; + buf |= USB_CFG_BCE_; + ret = lan78xx_write_reg(dev, USB_CFG0, buf); + if (ret < 0) + return ret; /* set FIFO sizes */ buf = (MAX_RX_FIFO_SIZE - 512) / 512; + ret = lan78xx_write_reg(dev, FCT_RX_FIFO_END, buf); + if (ret < 0) + return ret; buf = (MAX_TX_FIFO_SIZE - 512) / 512; + ret = lan78xx_write_reg(dev, FCT_TX_FIFO_END, buf); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_); + if (ret < 0) + return ret; + ret = lan78xx_write_reg(dev, FLOW, 0); + if (ret < 0) + return ret; + ret = lan78xx_write_reg(dev, FCT_FLOW, 0); + if (ret < 0) + return ret; /* Don't need rfe_ctl_lock during initialisation */ ret = lan78xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl); + if (ret < 0) + return ret; + pdata->rfe_ctl |= RFE_CTL_BCAST_EN_ | RFE_CTL_DA_PERFECT_; + ret = lan78xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl); + if (ret < 0) + return ret; /* Enable or disable checksum offload engines */ - lan78xx_set_features(dev->net, dev->net->features); + ret = lan78xx_set_features(dev->net, dev->net->features); + if (ret < 0) + return ret; lan78xx_set_multicast(dev->net); /* reset PHY */ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + return ret; + buf |= PMT_CTL_PHY_RST_; + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + return ret; timeout = jiffies + HZ; do { mdelay(1); ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + return ret; + if (time_after(jiffies, timeout)) { netdev_warn(dev->net, "timeout waiting for PHY Reset"); - return -EIO; + ret = -ETIMEDOUT; + return ret; } } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_)); ret = lan78xx_read_reg(dev, MAC_CR, &buf); + if (ret < 0) + return ret; + /* LAN7801 only has RGMII mode */ if (dev->chipid == ID_REV_CHIP_ID_7801_) buf &= ~MAC_CR_GMII_EN_; - if (dev->chipid == ID_REV_CHIP_ID_7800_) { + if (dev->chipid == ID_REV_CHIP_ID_7800_ || + dev->chipid == ID_REV_CHIP_ID_7850_) { ret = lan78xx_read_raw_eeprom(dev, 0, 1, &sig); if (!ret && sig != EEPROM_INDICATOR) { /* Implies there is no external eeprom. Set mac speed */ @@ -2572,27 +2818,13 @@ } } ret = lan78xx_write_reg(dev, MAC_CR, buf); - - ret = lan78xx_read_reg(dev, MAC_TX, &buf); - buf |= MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); - - ret = lan78xx_read_reg(dev, FCT_TX_CTL, &buf); - buf |= FCT_TX_CTL_EN_; - ret = lan78xx_write_reg(dev, FCT_TX_CTL, buf); + if (ret < 0) + return ret; ret = lan78xx_set_rx_max_frame_length(dev, dev->net->mtu + VLAN_ETH_HLEN); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); - - ret = lan78xx_read_reg(dev, FCT_RX_CTL, &buf); - buf |= FCT_RX_CTL_EN_; - ret = lan78xx_write_reg(dev, FCT_RX_CTL, buf); - - return 0; + return ret; } static void lan78xx_init_stats(struct lan78xx_net *dev) @@ -2626,9 +2858,13 @@ struct lan78xx_net *dev = netdev_priv(net); int ret; + netif_dbg(dev, ifup, dev->net, "open device"); + ret = usb_autopm_get_interface(dev->intf); if (ret < 0) - goto out; + return ret; + + mutex_lock(&dev->dev_mutex); phy_start(net->phydev); @@ -2644,6 +2880,20 @@ } } + ret = lan78xx_flush_rx_fifo(dev); + if (ret < 0) + goto done; + ret = lan78xx_flush_tx_fifo(dev); + if (ret < 0) + goto done; + + ret = lan78xx_start_tx_path(dev); + if (ret < 0) + goto done; + ret = lan78xx_start_rx_path(dev); + if (ret < 0) + goto done; + lan78xx_init_stats(dev); set_bit(EVENT_DEV_OPEN, &dev->flags); @@ -2654,9 +2904,11 @@ lan78xx_defer_kevent(dev, EVENT_LINK_RESET); done: - usb_autopm_put_interface(dev->intf); + mutex_unlock(&dev->dev_mutex); + + if (ret < 0) + usb_autopm_put_interface(dev->intf); -out: return ret; } @@ -2673,38 +2925,56 @@ temp = unlink_urbs(dev, &dev->txq) + unlink_urbs(dev, &dev->rxq); /* maybe wait for deletions to finish. */ - while (!skb_queue_empty(&dev->rxq) && - !skb_queue_empty(&dev->txq) && - !skb_queue_empty(&dev->done)) { + while (!skb_queue_empty(&dev->rxq) || + !skb_queue_empty(&dev->txq)) { schedule_timeout(msecs_to_jiffies(UNLINK_TIMEOUT_MS)); set_current_state(TASK_UNINTERRUPTIBLE); netif_dbg(dev, ifdown, dev->net, - "waited for %d urb completions\n", temp); + "waited for %d urb completions", temp); } set_current_state(TASK_RUNNING); dev->wait = NULL; remove_wait_queue(&unlink_wakeup, &wait); + + while (!skb_queue_empty(&dev->done)) { + struct skb_data *entry; + struct sk_buff *skb; + + skb = skb_dequeue(&dev->done); + entry = (struct skb_data *)(skb->cb); + usb_free_urb(entry->urb); + dev_kfree_skb(skb); + } } static int lan78xx_stop(struct net_device *net) { struct lan78xx_net *dev = netdev_priv(net); + netif_dbg(dev, ifup, dev->net, "stop device"); + + mutex_lock(&dev->dev_mutex); + if (timer_pending(&dev->stat_monitor)) del_timer_sync(&dev->stat_monitor); - if (net->phydev) - phy_stop(net->phydev); - clear_bit(EVENT_DEV_OPEN, &dev->flags); netif_stop_queue(net); + tasklet_kill(&dev->bh); + + lan78xx_terminate_urbs(dev); netif_info(dev, ifdown, dev->net, "stop stats: rx/tx %lu/%lu, errs %lu/%lu\n", net->stats.rx_packets, net->stats.tx_packets, net->stats.rx_errors, net->stats.tx_errors); - lan78xx_terminate_urbs(dev); + /* ignore errors that occur stopping the Tx and Rx data paths */ + lan78xx_stop_tx_path(dev); + lan78xx_stop_rx_path(dev); + + if (net->phydev) + phy_stop(net->phydev); usb_kill_urb(dev->urb_intr); @@ -2714,18 +2984,18 @@ * can't flush_scheduled_work() until we drop rtnl (later), * else workers could deadlock; so make workers a NOP. */ - dev->flags = 0; + clear_bit(EVENT_TX_HALT, &dev->flags); + clear_bit(EVENT_RX_HALT, &dev->flags); + clear_bit(EVENT_LINK_RESET, &dev->flags); + clear_bit(EVENT_STAT_UPDATE, &dev->flags); + cancel_delayed_work_sync(&dev->wq); - tasklet_kill(&dev->bh); usb_autopm_put_interface(dev->intf); - return 0; -} + mutex_unlock(&dev->dev_mutex); -static int lan78xx_linearize(struct sk_buff *skb) -{ - return skb_linearize(skb); + return 0; } static struct sk_buff *lan78xx_tx_prep(struct lan78xx_net *dev, @@ -2739,8 +3009,10 @@ return NULL; } - if (lan78xx_linearize(skb) < 0) + if (skb_linearize(skb)) { + dev_kfree_skb_any(skb); return NULL; + } tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN_MASK_) | TX_CMD_A_FCS_; @@ -2845,6 +3117,9 @@ struct lan78xx_net *dev = netdev_priv(net); struct sk_buff *skb2 = NULL; + if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) + schedule_delayed_work(&dev->wq, 0); + if (skb) { skb_tx_timestamp(skb); skb2 = lan78xx_tx_prep(dev, skb, GFP_ATOMIC); @@ -2869,78 +3144,12 @@ return NETDEV_TX_OK; } -static int -lan78xx_get_endpoints(struct lan78xx_net *dev, struct usb_interface *intf) -{ - int tmp; - struct usb_host_interface *alt = NULL; - struct usb_host_endpoint *in = NULL, *out = NULL; - struct usb_host_endpoint *status = NULL; - - for (tmp = 0; tmp < intf->num_altsetting; tmp++) { - unsigned ep; - - in = NULL; - out = NULL; - status = NULL; - alt = intf->altsetting + tmp; - - for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { - struct usb_host_endpoint *e; - int intr = 0; - - e = alt->endpoint + ep; - switch (e->desc.bmAttributes) { - case USB_ENDPOINT_XFER_INT: - if (!usb_endpoint_dir_in(&e->desc)) - continue; - intr = 1; - /* FALLTHROUGH */ - case USB_ENDPOINT_XFER_BULK: - break; - default: - continue; - } - if (usb_endpoint_dir_in(&e->desc)) { - if (!intr && !in) - in = e; - else if (intr && !status) - status = e; - } else { - if (!out) - out = e; - } - } - if (in && out) - break; - } - if (!alt || !in || !out) - return -EINVAL; - - dev->pipe_in = usb_rcvbulkpipe(dev->udev, - in->desc.bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK); - dev->pipe_out = usb_sndbulkpipe(dev->udev, - out->desc.bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK); - dev->ep_intr = status; - - return 0; -} - static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) { struct lan78xx_priv *pdata = NULL; int ret; int i; - ret = lan78xx_get_endpoints(dev, intf); - if (ret) { - netdev_warn(dev->net, "lan78xx_get_endpoints failed: %d\n", - ret); - return ret; - } - dev->data[0] = (unsigned long)kzalloc(sizeof(*pdata), GFP_KERNEL); pdata = (struct lan78xx_priv *)(dev->data[0]); @@ -3438,9 +3647,10 @@ if (skb) dev_kfree_skb_any(skb); usb_free_urb(urb); - } else + } else { netif_dbg(dev, tx_queued, dev->net, "> tx, len %d, type 0x%x\n", length, skb->protocol); + } } static void lan78xx_rx_bh(struct lan78xx_net *dev) @@ -3516,18 +3726,17 @@ dev = container_of(work, struct lan78xx_net, wq.work); + if (usb_autopm_get_interface(dev->intf) < 0) + return; + if (test_bit(EVENT_TX_HALT, &dev->flags)) { unlink_urbs(dev, &dev->txq); - status = usb_autopm_get_interface(dev->intf); - if (status < 0) - goto fail_pipe; + status = usb_clear_halt(dev->udev, dev->pipe_out); - usb_autopm_put_interface(dev->intf); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_tx_err(dev)) -fail_pipe: netdev_err(dev->net, "can't clear tx halt, status %d\n", status); @@ -3537,18 +3746,14 @@ netif_wake_queue(dev->net); } } + if (test_bit(EVENT_RX_HALT, &dev->flags)) { unlink_urbs(dev, &dev->rxq); - status = usb_autopm_get_interface(dev->intf); - if (status < 0) - goto fail_halt; status = usb_clear_halt(dev->udev, dev->pipe_in); - usb_autopm_put_interface(dev->intf); if (status < 0 && status != -EPIPE && status != -ESHUTDOWN) { if (netif_msg_rx_err(dev)) -fail_halt: netdev_err(dev->net, "can't clear rx halt, status %d\n", status); @@ -3562,16 +3767,9 @@ int ret = 0; clear_bit(EVENT_LINK_RESET, &dev->flags); - status = usb_autopm_get_interface(dev->intf); - if (status < 0) - goto skip_reset; if (lan78xx_link_reset(dev) < 0) { - usb_autopm_put_interface(dev->intf); -skip_reset: netdev_info(dev->net, "link reset failed (%d)\n", ret); - } else { - usb_autopm_put_interface(dev->intf); } } @@ -3585,6 +3783,8 @@ dev->delta = min((dev->delta * 2), 50); } + + usb_autopm_put_interface(dev->intf); } static void intr_complete(struct urb *urb) @@ -3644,8 +3844,10 @@ phy_disconnect(net->phydev); - if (phy_is_pseudo_fixed_link(phydev)) + if (phy_is_pseudo_fixed_link(phydev)) { fixed_phy_unregister(phydev); + phy_device_free(phydev); + } unregister_netdev(net); @@ -3670,6 +3872,19 @@ tasklet_schedule(&dev->bh); } +static netdev_features_t lan78xx_features_check(struct sk_buff *skb, + struct net_device *netdev, + netdev_features_t features) +{ + if (skb->len + TX_OVERHEAD > MAX_SINGLE_PACKET_SIZE) + features &= ~NETIF_F_GSO_MASK; + + features = vlan_features_check(skb, features); + features = vxlan_features_check(skb, features); + + return features; +} + static const struct net_device_ops lan78xx_netdev_ops = { .ndo_open = lan78xx_open, .ndo_stop = lan78xx_stop, @@ -3683,6 +3898,7 @@ .ndo_set_features = lan78xx_set_features, .ndo_vlan_rx_add_vid = lan78xx_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = lan78xx_vlan_rx_kill_vid, + .ndo_features_check = lan78xx_features_check, }; static void lan78xx_stat_monitor(struct timer_list *t) @@ -3695,12 +3911,13 @@ static int lan78xx_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_host_endpoint *ep_blkin, *ep_blkout, *ep_intr; struct lan78xx_net *dev; struct net_device *netdev; struct usb_device *udev; int ret; - unsigned maxp; - unsigned period; + unsigned int maxp; + unsigned int period; u8 *buf = NULL; udev = interface_to_usbdev(intf); @@ -3729,6 +3946,7 @@ skb_queue_head_init(&dev->rxq_pause); skb_queue_head_init(&dev->txq_pend); mutex_init(&dev->phy_mutex); + mutex_init(&dev->dev_mutex); tasklet_init(&dev->bh, lan78xx_bh, (unsigned long)dev); INIT_DELAYED_WORK(&dev->wq, lan78xx_delayedwork); @@ -3743,6 +3961,34 @@ mutex_init(&dev->stats.access_lock); + if (intf->cur_altsetting->desc.bNumEndpoints < 3) { + ret = -ENODEV; + goto out2; + } + + dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE); + ep_blkin = usb_pipe_endpoint(udev, dev->pipe_in); + if (!ep_blkin || !usb_endpoint_is_bulk_in(&ep_blkin->desc)) { + ret = -ENODEV; + goto out2; + } + + dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE); + ep_blkout = usb_pipe_endpoint(udev, dev->pipe_out); + if (!ep_blkout || !usb_endpoint_is_bulk_out(&ep_blkout->desc)) { + ret = -ENODEV; + goto out2; + } + + ep_intr = &intf->cur_altsetting->endpoint[2]; + if (!usb_endpoint_is_int_in(&ep_intr->desc)) { + ret = -ENODEV; + goto out2; + } + + dev->pipe_intr = usb_rcvintpipe(dev->udev, + usb_endpoint_num(&ep_intr->desc)); + ret = lan78xx_bind(dev, intf); if (ret < 0) goto out2; @@ -3752,19 +3998,9 @@ /* MTU range: 68 - 9000 */ netdev->max_mtu = MAX_SINGLE_PACKET_SIZE; + netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER); - dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0; - dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1; - dev->ep_intr = (intf->cur_altsetting)->endpoint + 2; - - dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE); - dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE); - - dev->pipe_intr = usb_rcvintpipe(dev->udev, - dev->ep_intr->desc.bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK); - period = dev->ep_intr->desc.bInterval; - + period = ep_intr->desc.bInterval; maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0); buf = kmalloc(maxp, GFP_KERNEL); if (buf) { @@ -3777,11 +4013,18 @@ usb_fill_int_urb(dev->urb_intr, dev->udev, dev->pipe_intr, buf, maxp, intr_complete, dev, period); + dev->urb_intr->transfer_flags |= URB_FREE_BUFFER; } } dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1); + /* Reject broken descriptors. */ + if (dev->maxpacket == 0) { + ret = -ENODEV; + goto out4; + } + /* driver requires remote-wakeup capability during autosuspend. */ intf->needs_remote_wakeup = 1; @@ -3846,38 +4089,119 @@ return crc; } -static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) +static int lan78xx_set_auto_suspend(struct lan78xx_net *dev) { u32 buf; int ret; - int mask_index; - u16 crc; - u32 temp_wucsr; - u32 temp_pmt_ctl; + + ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + return ret; + + ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + return ret; + + /* auto suspend (selective suspend) */ + + ret = lan78xx_write_reg(dev, WUCSR, 0); + if (ret < 0) + return ret; + ret = lan78xx_write_reg(dev, WUCSR2, 0); + if (ret < 0) + return ret; + ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + if (ret < 0) + return ret; + + /* set goodframe wakeup */ + + ret = lan78xx_read_reg(dev, WUCSR, &buf); + if (ret < 0) + return ret; + + buf |= WUCSR_RFE_WAKE_EN_; + buf |= WUCSR_STORE_WAKE_; + + ret = lan78xx_write_reg(dev, WUCSR, buf); + if (ret < 0) + return ret; + + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + return ret; + + buf &= ~PMT_CTL_RES_CLR_WKP_EN_; + buf |= PMT_CTL_RES_CLR_WKP_STS_; + buf |= PMT_CTL_PHY_WAKE_EN_; + buf |= PMT_CTL_WOL_EN_; + buf &= ~PMT_CTL_SUS_MODE_MASK_; + buf |= PMT_CTL_SUS_MODE_3_; + + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + return ret; + + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + return ret; + + buf |= PMT_CTL_WUPS_MASK_; + + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + return ret; + + ret = lan78xx_start_rx_path(dev); + + return ret; +} + +static int lan78xx_set_suspend(struct lan78xx_net *dev, u32 wol) +{ const u8 ipv4_multicast[3] = { 0x01, 0x00, 0x5E }; const u8 ipv6_multicast[3] = { 0x33, 0x33 }; const u8 arp_type[2] = { 0x08, 0x06 }; + u32 temp_pmt_ctl; + int mask_index; + u32 temp_wucsr; + u32 buf; + u16 crc; + int ret; - ret = lan78xx_read_reg(dev, MAC_TX, &buf); - buf &= ~MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + return ret; + ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUCSR, 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUCSR2, 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + if (ret < 0) + return ret; temp_wucsr = 0; temp_pmt_ctl = 0; + ret = lan78xx_read_reg(dev, PMT_CTL, &temp_pmt_ctl); + if (ret < 0) + return ret; + temp_pmt_ctl &= ~PMT_CTL_RES_CLR_WKP_EN_; temp_pmt_ctl |= PMT_CTL_RES_CLR_WKP_STS_; - for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) + for (mask_index = 0; mask_index < NUM_OF_WUF_CFG; mask_index++) { ret = lan78xx_write_reg(dev, WUF_CFG(mask_index), 0); + if (ret < 0) + return ret; + } mask_index = 0; if (wol & WAKE_PHY) { @@ -3911,11 +4235,22 @@ WUF_CFGX_TYPE_MCAST_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 7); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + if (ret < 0) + return ret; + mask_index++; /* for IPv6 Multicast */ @@ -3925,11 +4260,22 @@ WUF_CFGX_TYPE_MCAST_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 3); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + if (ret < 0) + return ret; + mask_index++; temp_pmt_ctl |= PMT_CTL_WOL_EN_; @@ -3955,11 +4301,22 @@ WUF_CFGX_TYPE_ALL_ | (0 << WUF_CFGX_OFFSET_SHIFT_) | (crc & WUF_CFGX_CRC16_MASK_)); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK0(mask_index), 0x3000); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK1(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK2(mask_index), 0); + if (ret < 0) + return ret; ret = lan78xx_write_reg(dev, WUF_MASK3(mask_index), 0); + if (ret < 0) + return ret; + mask_index++; temp_pmt_ctl |= PMT_CTL_WOL_EN_; @@ -3968,6 +4325,8 @@ } ret = lan78xx_write_reg(dev, WUCSR, temp_wucsr); + if (ret < 0) + return ret; /* when multiple WOL bits are set */ if (hweight_long((unsigned long)wol) > 1) { @@ -3976,35 +4335,47 @@ temp_pmt_ctl |= PMT_CTL_SUS_MODE_0_; } ret = lan78xx_write_reg(dev, PMT_CTL, temp_pmt_ctl); + if (ret < 0) + return ret; /* clear WUPS */ ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + return ret; + buf |= PMT_CTL_WUPS_MASK_; + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + return ret; - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + ret = lan78xx_start_rx_path(dev); - return 0; + return ret; } static int lan78xx_suspend(struct usb_interface *intf, pm_message_t message) { struct lan78xx_net *dev = usb_get_intfdata(intf); - struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]); - u32 buf; + bool dev_open; int ret; int event; event = message.event; - if (!dev->suspend_count++) { + mutex_lock(&dev->dev_mutex); + + netif_dbg(dev, ifdown, dev->net, + "suspending: pm event %#x", message.event); + + dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags); + + if (dev_open) { spin_lock_irq(&dev->txq.lock); /* don't autosuspend while transmitting */ if ((skb_queue_len(&dev->txq) || skb_queue_len(&dev->txq_pend)) && - PMSG_IS_AUTO(message)) { + PMSG_IS_AUTO(message)) { spin_unlock_irq(&dev->txq.lock); ret = -EBUSY; goto out; @@ -4013,129 +4384,207 @@ spin_unlock_irq(&dev->txq.lock); } - /* stop TX & RX */ - ret = lan78xx_read_reg(dev, MAC_TX, &buf); - buf &= ~MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + /* stop RX */ + ret = lan78xx_stop_rx_path(dev); + if (ret < 0) + goto out; - /* empty out the rx and queues */ + ret = lan78xx_flush_rx_fifo(dev); + if (ret < 0) + goto out; + + /* stop Tx */ + ret = lan78xx_stop_tx_path(dev); + if (ret < 0) + goto out; + + /* empty out the Rx and Tx queues */ netif_device_detach(dev->net); lan78xx_terminate_urbs(dev); usb_kill_urb(dev->urb_intr); /* reattach */ netif_device_attach(dev->net); - } - if (test_bit(EVENT_DEV_ASLEEP, &dev->flags)) { del_timer(&dev->stat_monitor); if (PMSG_IS_AUTO(message)) { - /* auto suspend (selective suspend) */ - ret = lan78xx_read_reg(dev, MAC_TX, &buf); - buf &= ~MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf &= ~MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + ret = lan78xx_set_auto_suspend(dev); + if (ret < 0) + goto out; + } else { + struct lan78xx_priv *pdata; - ret = lan78xx_write_reg(dev, WUCSR, 0); - ret = lan78xx_write_reg(dev, WUCSR2, 0); - ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + pdata = (struct lan78xx_priv *)(dev->data[0]); + netif_carrier_off(dev->net); + ret = lan78xx_set_suspend(dev, pdata->wol); + if (ret < 0) + goto out; + } + } else { + /* Interface is down; don't allow WOL and PHY + * events to wake up the host + */ + u32 buf; - /* set goodframe wakeup */ - ret = lan78xx_read_reg(dev, WUCSR, &buf); + set_bit(EVENT_DEV_ASLEEP, &dev->flags); - buf |= WUCSR_RFE_WAKE_EN_; - buf |= WUCSR_STORE_WAKE_; + ret = lan78xx_write_reg(dev, WUCSR, 0); + if (ret < 0) + goto out; + ret = lan78xx_write_reg(dev, WUCSR2, 0); + if (ret < 0) + goto out; - ret = lan78xx_write_reg(dev, WUCSR, buf); + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + goto out; - ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + buf &= ~PMT_CTL_RES_CLR_WKP_EN_; + buf |= PMT_CTL_RES_CLR_WKP_STS_; + buf &= ~PMT_CTL_SUS_MODE_MASK_; + buf |= PMT_CTL_SUS_MODE_3_; - buf &= ~PMT_CTL_RES_CLR_WKP_EN_; - buf |= PMT_CTL_RES_CLR_WKP_STS_; + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + goto out; - buf |= PMT_CTL_PHY_WAKE_EN_; - buf |= PMT_CTL_WOL_EN_; - buf &= ~PMT_CTL_SUS_MODE_MASK_; - buf |= PMT_CTL_SUS_MODE_3_; + ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + if (ret < 0) + goto out; - ret = lan78xx_write_reg(dev, PMT_CTL, buf); + buf |= PMT_CTL_WUPS_MASK_; - ret = lan78xx_read_reg(dev, PMT_CTL, &buf); + ret = lan78xx_write_reg(dev, PMT_CTL, buf); + if (ret < 0) + goto out; + } + + ret = 0; +out: + mutex_unlock(&dev->dev_mutex); - buf |= PMT_CTL_WUPS_MASK_; + return ret; +} - ret = lan78xx_write_reg(dev, PMT_CTL, buf); +static bool lan78xx_submit_deferred_urbs(struct lan78xx_net *dev) +{ + bool pipe_halted = false; + struct urb *urb; - ret = lan78xx_read_reg(dev, MAC_RX, &buf); - buf |= MAC_RX_RXEN_; - ret = lan78xx_write_reg(dev, MAC_RX, buf); + while ((urb = usb_get_from_anchor(&dev->deferred))) { + struct sk_buff *skb = urb->context; + int ret; + + if (!netif_device_present(dev->net) || + !netif_carrier_ok(dev->net) || + pipe_halted) { + usb_free_urb(urb); + dev_kfree_skb(skb); + continue; + } + + ret = usb_submit_urb(urb, GFP_ATOMIC); + + if (ret == 0) { + netif_trans_update(dev->net); + lan78xx_queue_skb(&dev->txq, skb, tx_start); } else { - lan78xx_set_suspend(dev, pdata->wol); + usb_free_urb(urb); + dev_kfree_skb(skb); + + if (ret == -EPIPE) { + netif_stop_queue(dev->net); + pipe_halted = true; + } else if (ret == -ENODEV) { + netif_device_detach(dev->net); + } } } - ret = 0; -out: - return ret; + return pipe_halted; } static int lan78xx_resume(struct usb_interface *intf) { struct lan78xx_net *dev = usb_get_intfdata(intf); - struct sk_buff *skb; - struct urb *res; + bool dev_open; int ret; - u32 buf; - if (!timer_pending(&dev->stat_monitor)) { - dev->delta = 1; - mod_timer(&dev->stat_monitor, - jiffies + STAT_UPDATE_TIMER); - } + mutex_lock(&dev->dev_mutex); - if (!--dev->suspend_count) { - /* resume interrupt URBs */ - if (dev->urb_intr && test_bit(EVENT_DEV_OPEN, &dev->flags)) - usb_submit_urb(dev->urb_intr, GFP_NOIO); + netif_dbg(dev, ifup, dev->net, "resuming device"); + + dev_open = test_bit(EVENT_DEV_OPEN, &dev->flags); + + if (dev_open) { + bool pipe_halted = false; + + ret = lan78xx_flush_tx_fifo(dev); + if (ret < 0) + goto out; + + if (dev->urb_intr) { + int ret = usb_submit_urb(dev->urb_intr, GFP_KERNEL); - spin_lock_irq(&dev->txq.lock); - while ((res = usb_get_from_anchor(&dev->deferred))) { - skb = (struct sk_buff *)res->context; - ret = usb_submit_urb(res, GFP_ATOMIC); if (ret < 0) { - dev_kfree_skb_any(skb); - usb_free_urb(res); - usb_autopm_put_interface_async(dev->intf); - } else { - netif_trans_update(dev->net); - lan78xx_queue_skb(&dev->txq, skb, tx_start); + if (ret == -ENODEV) + netif_device_detach(dev->net); + + netdev_warn(dev->net, "Failed to submit intr URB"); } } + spin_lock_irq(&dev->txq.lock); + + if (netif_device_present(dev->net)) { + pipe_halted = lan78xx_submit_deferred_urbs(dev); + + if (pipe_halted) + lan78xx_defer_kevent(dev, EVENT_TX_HALT); + } + clear_bit(EVENT_DEV_ASLEEP, &dev->flags); + spin_unlock_irq(&dev->txq.lock); - if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { - if (!(skb_queue_len(&dev->txq) >= dev->tx_qlen)) - netif_start_queue(dev->net); - tasklet_schedule(&dev->bh); + if (!pipe_halted && + netif_device_present(dev->net) && + (skb_queue_len(&dev->txq) < dev->tx_qlen)) + netif_start_queue(dev->net); + + ret = lan78xx_start_tx_path(dev); + if (ret < 0) + goto out; + + tasklet_schedule(&dev->bh); + + if (!timer_pending(&dev->stat_monitor)) { + dev->delta = 1; + mod_timer(&dev->stat_monitor, + jiffies + STAT_UPDATE_TIMER); } + + } else { + clear_bit(EVENT_DEV_ASLEEP, &dev->flags); } ret = lan78xx_write_reg(dev, WUCSR2, 0); + if (ret < 0) + goto out; ret = lan78xx_write_reg(dev, WUCSR, 0); + if (ret < 0) + goto out; ret = lan78xx_write_reg(dev, WK_SRC, 0xFFF1FF1FUL); + if (ret < 0) + goto out; ret = lan78xx_write_reg(dev, WUCSR2, WUCSR2_NS_RCD_ | WUCSR2_ARP_RCD_ | WUCSR2_IPV6_TCPSYN_RCD_ | WUCSR2_IPV4_TCPSYN_RCD_); + if (ret < 0) + goto out; ret = lan78xx_write_reg(dev, WUCSR, WUCSR_EEE_TX_WAKE_ | WUCSR_EEE_RX_WAKE_ | @@ -4144,23 +4593,32 @@ WUCSR_WUFR_ | WUCSR_MPR_ | WUCSR_BCST_FR_); + if (ret < 0) + goto out; - ret = lan78xx_read_reg(dev, MAC_TX, &buf); - buf |= MAC_TX_TXEN_; - ret = lan78xx_write_reg(dev, MAC_TX, buf); + ret = 0; +out: + mutex_unlock(&dev->dev_mutex); - return 0; + return ret; } static int lan78xx_reset_resume(struct usb_interface *intf) { struct lan78xx_net *dev = usb_get_intfdata(intf); + int ret; - lan78xx_reset(dev); + netif_dbg(dev, ifup, dev->net, "(reset) resuming device"); + + ret = lan78xx_reset(dev); + if (ret < 0) + return ret; phy_start(dev->net->phydev); - return lan78xx_resume(intf); + ret = lan78xx_resume(intf); + + return ret; } static const struct usb_device_id products[] = { @@ -4176,6 +4634,10 @@ /* LAN7801 USB Gigabit Ethernet Device */ USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID), }, + { + /* ATM2-AF USB Gigabit Ethernet Device */ + USB_DEVICE(AT29M2AF_USB_VENDOR_ID, AT29M2AF_USB_PRODUCT_ID), + }, {}, }; MODULE_DEVICE_TABLE(usb, products); --- linux-oracle-5.4.0.orig/drivers/net/usb/mcs7830.c +++ linux-oracle-5.4.0/drivers/net/usb/mcs7830.c @@ -108,8 +108,16 @@ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) { - return usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, - 0x0000, index, data, size); + int ret; + + ret = usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, + 0x0000, index, data, size); + if (ret < 0) + return ret; + else if (ret < size) + return -ENODATA; + + return ret; } static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) @@ -472,17 +480,19 @@ static int mcs7830_bind(struct usbnet *dev, struct usb_interface *udev) { struct net_device *net = dev->net; + u8 addr[ETH_ALEN]; int ret; int retry; /* Initial startup: Gather MAC address setting from EEPROM */ ret = -EINVAL; for (retry = 0; retry < 5 && ret; retry++) - ret = mcs7830_hif_get_mac_address(dev, net->dev_addr); + ret = mcs7830_hif_get_mac_address(dev, addr); if (ret) { dev_warn(&dev->udev->dev, "Cannot read MAC address\n"); goto out; } + eth_hw_addr_set(net, addr); mcs7830_data_set_multicast(net); --- linux-oracle-5.4.0.orig/drivers/net/usb/pegasus.c +++ linux-oracle-5.4.0/drivers/net/usb/pegasus.c @@ -495,11 +495,11 @@ goto goon; rx_status = buf[count - 2]; - if (rx_status & 0x1e) { + if (rx_status & 0x1c) { netif_dbg(pegasus, rx_err, net, "RX packet error %x\n", rx_status); net->stats.rx_errors++; - if (rx_status & 0x06) /* long or runt */ + if (rx_status & 0x04) /* runt */ net->stats.rx_length_errors++; if (rx_status & 0x08) net->stats.rx_crc_errors++; @@ -747,12 +747,16 @@ set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp); } -static inline void get_interrupt_interval(pegasus_t *pegasus) +static inline int get_interrupt_interval(pegasus_t *pegasus) { u16 data; u8 interval; + int ret; + + ret = read_eprom_word(pegasus, 4, &data); + if (ret < 0) + return ret; - read_eprom_word(pegasus, 4, &data); interval = data >> 8; if (pegasus->usb->speed != USB_SPEED_HIGH) { if (interval < 0x80) { @@ -767,6 +771,8 @@ } } pegasus->intr_interval = interval; + + return 0; } static void set_carrier(struct net_device *net) @@ -1186,7 +1192,9 @@ | NETIF_MSG_PROBE | NETIF_MSG_LINK); pegasus->features = usb_dev_id[dev_index].private; - get_interrupt_interval(pegasus); + res = get_interrupt_interval(pegasus); + if (res) + goto out2; if (reset_mac(pegasus)) { dev_err(&intf->dev, "can't reset MAC\n"); res = -EIO; --- linux-oracle-5.4.0.orig/drivers/net/usb/plusb.c +++ linux-oracle-5.4.0/drivers/net/usb/plusb.c @@ -57,9 +57,7 @@ static inline int pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index) { - return usbnet_read_cmd(dev, req, - USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, + return usbnet_write_cmd(dev, req, USB_TYPE_VENDOR | USB_RECIP_DEVICE, val, index, NULL, 0); } --- linux-oracle-5.4.0.orig/drivers/net/usb/qmi_wwan.c +++ linux-oracle-5.4.0/drivers/net/usb/qmi_wwan.c @@ -61,7 +61,6 @@ enum qmi_wwan_quirks { QMI_WWAN_QUIRK_DTR = 1 << 0, /* needs "set DTR" request */ - QMI_WWAN_QUIRK_QUECTEL_DYNCFG = 1 << 1, /* check num. endpoints */ }; struct qmimux_hdr { @@ -239,6 +238,7 @@ break; default: /* not ip - do not know what to do */ + kfree_skb(skbn); goto skip; } @@ -338,6 +338,9 @@ netdev_dbg(net, "mode: raw IP\n"); } else if (!net->header_ops) { /* don't bother if already set */ ether_setup(net); + /* Restoring min/max mtu values set originally by usbnet */ + net->min_mtu = 0; + net->max_mtu = ETH_MAX_MTU; clear_bit(EVENT_NO_IP_ALIGN, &dev->flags); netdev_dbg(net, "mode: Ethernet\n"); } @@ -439,13 +442,6 @@ goto err; } - /* we don't want to modify a running netdev */ - if (netif_running(dev->net)) { - netdev_err(dev->net, "Cannot change a running device\n"); - ret = -EBUSY; - goto err; - } - ret = qmimux_register_device(dev->net, mux_id); if (!ret) { info->flags |= QMI_WWAN_FLAG_MUX; @@ -475,13 +471,6 @@ if (!rtnl_trylock()) return restart_syscall(); - /* we don't want to modify a running netdev */ - if (netif_running(dev->net)) { - netdev_err(dev->net, "Cannot change a running device\n"); - ret = -EBUSY; - goto err; - } - del_dev = qmimux_find_dev(dev, mux_id); if (!del_dev) { netdev_err(dev->net, "mux_id not present\n"); @@ -916,16 +905,6 @@ .data = QMI_WWAN_QUIRK_DTR, }; -static const struct driver_info qmi_wwan_info_quirk_quectel_dyncfg = { - .description = "WWAN/QMI device", - .flags = FLAG_WWAN | FLAG_SEND_ZLP, - .bind = qmi_wwan_bind, - .unbind = qmi_wwan_unbind, - .manage_power = qmi_wwan_manage_power, - .rx_fixup = qmi_wwan_rx_fixup, - .data = QMI_WWAN_QUIRK_DTR | QMI_WWAN_QUIRK_QUECTEL_DYNCFG, -}; - #define HUAWEI_VENDOR_ID 0x12D1 /* map QMI/wwan function by a fixed interface number */ @@ -946,14 +925,18 @@ #define QMI_GOBI_DEVICE(vend, prod) \ QMI_FIXED_INTF(vend, prod, 0) -/* Quectel does not use fixed interface numbers on at least some of their - * devices. We need to check the number of endpoints to ensure that we bind to - * the correct interface. +/* Many devices have QMI and DIAG functions which are distinguishable + * from other vendor specific functions by class, subclass and + * protocol all being 0xff. The DIAG function has exactly 2 endpoints + * and is silently rejected when probed. + * + * This makes it possible to match dynamically numbered QMI functions + * as seen on e.g. many Quectel modems. */ -#define QMI_QUIRK_QUECTEL_DYNCFG(vend, prod) \ +#define QMI_MATCH_FF_FF_FF(vend, prod) \ USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_VENDOR_SPEC, \ USB_SUBCLASS_VENDOR_SPEC, 0xff), \ - .driver_info = (unsigned long)&qmi_wwan_info_quirk_quectel_dyncfg + .driver_info = (unsigned long)&qmi_wwan_info_quirk_dtr static const struct usb_device_id products[] = { /* 1. CDC ECM like devices match on the control interface */ @@ -1059,9 +1042,13 @@ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), .driver_info = (unsigned long)&qmi_wwan_info, }, - {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ - {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ - {QMI_QUIRK_QUECTEL_DYNCFG(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0620)}, /* Quectel EM160R-GL */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0800)}, /* Quectel RM500Q-GL */ + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0801)}, /* Quectel RM520N */ /* 3. Combined interface devices matching on interface number */ {QMI_FIXED_INTF(0x0408, 0xea42, 4)}, /* Yota / Megafon M100-1 */ @@ -1095,7 +1082,7 @@ {QMI_FIXED_INTF(0x05c6, 0x9011, 4)}, {QMI_FIXED_INTF(0x05c6, 0x9021, 1)}, {QMI_FIXED_INTF(0x05c6, 0x9022, 2)}, - {QMI_FIXED_INTF(0x05c6, 0x9025, 4)}, /* Alcatel-sbell ASB TL131 TDD LTE (China Mobile) */ + {QMI_QUIRK_SET_DTR(0x05c6, 0x9025, 4)}, /* Alcatel-sbell ASB TL131 TDD LTE (China Mobile) */ {QMI_FIXED_INTF(0x05c6, 0x9026, 3)}, {QMI_FIXED_INTF(0x05c6, 0x902e, 5)}, {QMI_FIXED_INTF(0x05c6, 0x9031, 5)}, @@ -1193,7 +1180,9 @@ {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, + {QMI_QUIRK_SET_DTR(0x05c6, 0x9091, 2)}, /* Compal RXM-G1 */ {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ + {QMI_QUIRK_SET_DTR(0x05c6, 0x90db, 2)}, /* Compal RXM-G1 */ {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, {QMI_QUIRK_SET_DTR(0x05c6, 0x9625, 4)}, /* YUGA CLM920-NC5 */ @@ -1213,6 +1202,7 @@ {QMI_FIXED_INTF(0x1435, 0xd182, 5)}, /* Wistron NeWeb D18 */ {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ + {QMI_FIXED_INTF(0x1690, 0x7588, 4)}, /* ASKEY WWHC050 */ {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ @@ -1259,6 +1249,7 @@ {QMI_FIXED_INTF(0x19d2, 0x0168, 4)}, {QMI_FIXED_INTF(0x19d2, 0x0176, 3)}, {QMI_FIXED_INTF(0x19d2, 0x0178, 3)}, + {QMI_FIXED_INTF(0x19d2, 0x0189, 4)}, /* ZTE MF290 */ {QMI_FIXED_INTF(0x19d2, 0x0191, 4)}, /* ZTE EuFi890 */ {QMI_FIXED_INTF(0x19d2, 0x0199, 1)}, /* ZTE MF820S */ {QMI_FIXED_INTF(0x19d2, 0x0200, 1)}, @@ -1281,6 +1272,7 @@ {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ + {QMI_FIXED_INTF(0x19d2, 0x1275, 3)}, /* ZTE P685M */ {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, @@ -1295,7 +1287,7 @@ {QMI_FIXED_INTF(0x2001, 0x7e3d, 4)}, /* D-Link DWM-222 A2 */ {QMI_FIXED_INTF(0x2020, 0x2031, 4)}, /* Olicard 600 */ {QMI_FIXED_INTF(0x2020, 0x2033, 4)}, /* BroadMobi BM806U */ - {QMI_FIXED_INTF(0x2020, 0x2060, 4)}, /* BroadMobi BM818 */ + {QMI_QUIRK_SET_DTR(0x2020, 0x2060, 4)}, /* BroadMobi BM818 */ {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ @@ -1326,15 +1318,29 @@ {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1031, 3)}, /* Telit LE910C1-EUX */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x103a, 0)}, /* Telit LE910C4-WWX */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)}, /* Telit LN920 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)}, /* Telit FN990 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */ {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1230, 2)}, /* Telit LE910Cx */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1260, 2)}, /* Telit LE910Cx */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1261, 2)}, /* Telit LE910Cx */ {QMI_QUIRK_SET_DTR(0x1bc7, 0x1900, 1)}, /* Telit LN940 series */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x3000, 0)}, /* Telit FN912 series */ + {QMI_QUIRK_SET_DTR(0x1bc7, 0x3001, 0)}, /* Telit FN912 series */ {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)}, /* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)}, /* Telewell TW-3G HSPA+ */ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ @@ -1346,12 +1352,14 @@ {QMI_FIXED_INTF(0x0b3c, 0xc00a, 6)}, /* Olivetti Olicard 160 */ {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */ {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ + {QMI_QUIRK_SET_DTR(0x1e2d, 0x006f, 8)}, /* Cinterion PLS83/PLS63 */ {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ {QMI_FIXED_INTF(0x1e2d, 0x0063, 10)}, /* Cinterion ALASxx (1 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0082, 4)}, /* Cinterion PHxx,PXxx (2 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0082, 5)}, /* Cinterion PHxx,PXxx (2 RmNet) */ {QMI_FIXED_INTF(0x1e2d, 0x0083, 4)}, /* Cinterion PHxx,PXxx (1 RmNet + USB Audio)*/ {QMI_QUIRK_SET_DTR(0x1e2d, 0x00b0, 4)}, /* Cinterion CLS8 */ + {QMI_FIXED_INTF(0x1e2d, 0x00b7, 0)}, /* Cinterion MV31 RmNet */ {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ @@ -1361,18 +1369,30 @@ {QMI_FIXED_INTF(0x413c, 0x81b3, 8)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */ {QMI_FIXED_INTF(0x413c, 0x81b6, 8)}, /* Dell Wireless 5811e */ {QMI_FIXED_INTF(0x413c, 0x81b6, 10)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81c2, 8)}, /* Dell Wireless 5811e */ + {QMI_FIXED_INTF(0x413c, 0x81cc, 8)}, /* Dell Wireless 5816e */ {QMI_FIXED_INTF(0x413c, 0x81d7, 0)}, /* Dell Wireless 5821e */ + {QMI_FIXED_INTF(0x413c, 0x81d7, 1)}, /* Dell Wireless 5821e preproduction config */ {QMI_FIXED_INTF(0x413c, 0x81e0, 0)}, /* Dell Wireless 5821e with eSIM support*/ + {QMI_FIXED_INTF(0x413c, 0x81e4, 0)}, /* Dell Wireless 5829e with eSIM support*/ + {QMI_FIXED_INTF(0x413c, 0x81e6, 0)}, /* Dell Wireless 5829e */ {QMI_FIXED_INTF(0x03f0, 0x4e1d, 8)}, /* HP lt4111 LTE/EV-DO/HSPA+ Gobi 4G Module */ {QMI_FIXED_INTF(0x03f0, 0x9d1d, 1)}, /* HP lt4120 Snapdragon X5 LTE */ {QMI_FIXED_INTF(0x22de, 0x9061, 3)}, /* WeTelecom WPD-600N */ {QMI_QUIRK_SET_DTR(0x1e0e, 0x9001, 5)}, /* SIMCom 7100E, 7230E, 7600E ++ */ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0121, 4)}, /* Quectel EC21 Mini PCIe */ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ + {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */ {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ + {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ + {QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */ + {QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */ + {QMI_FIXED_INTF(0x2dee, 0x4d22, 5)}, /* MeiG Smart SRM825L */ /* 4. Gobi 1000 devices */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ @@ -1453,7 +1473,6 @@ { struct usb_device_id *id = (struct usb_device_id *)prod; struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; - const struct driver_info *info; /* Workaround to enable dynamic IDs. This disables usbnet * blacklisting functionality. Which, if required, can be @@ -1489,12 +1508,8 @@ * different. Ignore the current interface if the number of endpoints * equals the number for the diag interface (two). */ - info = (void *)id->driver_info; - - if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) { - if (desc->bNumEndpoints == 2) - return -ENODEV; - } + if (desc->bNumEndpoints == 2) + return -ENODEV; return usbnet_probe(intf, id); } --- linux-oracle-5.4.0.orig/drivers/net/usb/r8152.c +++ linux-oracle-5.4.0/drivers/net/usb/r8152.c @@ -29,7 +29,7 @@ #define NETNEXT_VERSION "10" /* Information for net */ -#define NET_VERSION "10" +#define NET_VERSION "11" #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers " @@ -63,6 +63,7 @@ #define PLA_LED_FEATURE 0xdd92 #define PLA_PHYAR 0xde00 #define PLA_BOOT_CTRL 0xe004 +#define PLA_LWAKE_CTRL_REG 0xe007 #define PLA_GPHY_INTR_IMR 0xe022 #define PLA_EEE_CR 0xe040 #define PLA_EEEP_CR 0xe080 @@ -90,6 +91,7 @@ #define PLA_TALLYCNT 0xe890 #define PLA_SFF_STS_7 0xe8de #define PLA_PHYSTATUS 0xe908 +#define PLA_CONFIG6 0xe90a /* CONFIG6 */ #define PLA_BP_BA 0xfc26 #define PLA_BP_0 0xfc28 #define PLA_BP_1 0xfc2a @@ -102,6 +104,7 @@ #define PLA_BP_EN 0xfc38 #define USB_USB2PHY 0xb41e +#define USB_SSPHYLINK1 0xb426 #define USB_SSPHYLINK2 0xb428 #define USB_U2P3_CTRL 0xb460 #define USB_CSR_DUMMY1 0xb464 @@ -286,6 +289,9 @@ #define LINK_ON_WAKE_EN 0x0010 #define LINK_OFF_WAKE_EN 0x0008 +/* PLA_CONFIG6 */ +#define LANWAKE_CLR_EN BIT(0) + /* PLA_CONFIG5 */ #define BWF_EN 0x0040 #define MWF_EN 0x0020 @@ -298,6 +304,7 @@ /* PLA_PHY_PWR */ #define TX_10M_IDLE_EN 0x0080 #define PFM_PWM_SWITCH 0x0040 +#define TEST_IO_OFF BIT(4) /* PLA_MAC_PWR_CTRL */ #define D3_CLK_GATED_EN 0x00004000 @@ -310,6 +317,7 @@ #define MAC_CLK_SPDWN_EN BIT(15) /* PLA_MAC_PWR_CTRL3 */ +#define PLA_MCU_SPDWN_EN BIT(14) #define PKT_AVAIL_SPDWN_EN 0x0100 #define SUSPEND_SPDWN_EN 0x0004 #define U1U2_SPDWN_EN 0x0002 @@ -340,6 +348,9 @@ /* PLA_BOOT_CTRL */ #define AUTOLOAD_DONE 0x0002 +/* PLA_LWAKE_CTRL_REG */ +#define LANWAKE_PIN BIT(7) + /* PLA_SUSPEND_FLAG */ #define LINK_CHG_EVENT BIT(0) @@ -353,6 +364,9 @@ #define USB2PHY_SUSPEND 0x0001 #define USB2PHY_L1 0x0002 +/* USB_SSPHYLINK1 */ +#define DELAY_PHY_PWR_CHG BIT(1) + /* USB_SSPHYLINK2 */ #define pwd_dn_scale_mask 0x3ffe #define pwd_dn_scale(x) ((x) << 1) @@ -622,6 +636,7 @@ SCHEDULE_TASKLET, GREEN_ETHERNET, DELL_TB_RX_AGG_BUG, + LENOVO_MACPASSTHRU, }; /* Define these values to match your device */ @@ -836,7 +851,7 @@ ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, tmp, size, 500); + value, index, tmp, size, USB_CTRL_GET_TIMEOUT); if (ret < 0) memset(data, 0xff, size); else @@ -859,7 +874,7 @@ ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, tmp, size, 500); + value, index, tmp, size, USB_CTRL_SET_TIMEOUT); kfree(tmp); @@ -1222,38 +1237,52 @@ int ret = -EINVAL; u32 ocp_data; unsigned char buf[6]; - - /* test for -AD variant of RTL8153 */ - ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); - if ((ocp_data & AD_MASK) == 0x1000) { - /* test for MAC address pass-through bit */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); - if ((ocp_data & PASS_THRU_MASK) != 1) { - netif_dbg(tp, probe, tp->netdev, - "No efuse for RTL8153-AD MAC pass through\n"); - return -ENODEV; - } + char *mac_obj_name; + acpi_object_type mac_obj_type; + int mac_strlen; + + if (test_bit(LENOVO_MACPASSTHRU, &tp->flags)) { + mac_obj_name = "\\MACA"; + mac_obj_type = ACPI_TYPE_STRING; + mac_strlen = 0x16; } else { - /* test for RTL8153-BND and RTL8153-BD */ - ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); - if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { - netif_dbg(tp, probe, tp->netdev, - "Invalid variant for MAC pass through\n"); - return -ENODEV; + /* test for -AD variant of RTL8153 */ + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0); + if ((ocp_data & AD_MASK) == 0x1000) { + /* test for MAC address pass-through bit */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, EFUSE); + if ((ocp_data & PASS_THRU_MASK) != 1) { + netif_dbg(tp, probe, tp->netdev, + "No efuse for RTL8153-AD MAC pass through\n"); + return -ENODEV; + } + } else { + /* test for RTL8153-BND and RTL8153-BD */ + ocp_data = ocp_read_byte(tp, MCU_TYPE_USB, USB_MISC_1); + if ((ocp_data & BND_MASK) == 0 && (ocp_data & BD_MASK) == 0) { + netif_dbg(tp, probe, tp->netdev, + "Invalid variant for MAC pass through\n"); + return -ENODEV; + } } + + mac_obj_name = "\\_SB.AMAC"; + mac_obj_type = ACPI_TYPE_BUFFER; + mac_strlen = 0x17; } /* returns _AUXMAC_#AABBCCDDEEFF# */ - status = acpi_evaluate_object(NULL, "\\_SB.AMAC", NULL, &buffer); + status = acpi_evaluate_object(NULL, mac_obj_name, NULL, &buffer); obj = (union acpi_object *)buffer.pointer; if (!ACPI_SUCCESS(status)) return -ENODEV; - if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { + if (obj->type != mac_obj_type || obj->string.length != mac_strlen) { netif_warn(tp, probe, tp->netdev, "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", obj->type, obj->string.length); goto amacout; } + if (strncmp(obj->string.pointer, "_AUXMAC_#", 9) != 0 || strncmp(obj->string.pointer + 0x15, "#", 1) != 0) { netif_warn(tp, probe, tp->netdev, @@ -1465,7 +1494,9 @@ "Stop submitting intr, status %d\n", status); return; case -EOVERFLOW: - netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); + if (net_ratelimit()) + netif_info(tp, intr, tp->netdev, + "intr status -EOVERFLOW\n"); goto resubmit; /* -EPIPE: should clear the halt */ default: @@ -2237,6 +2268,9 @@ struct r8152 *tp = container_of(napi, struct r8152, napi); int work_done; + if (!budget) + return 0; + work_done = rx_bottom(tp, budget); if (work_done < budget) { @@ -2822,29 +2856,6 @@ device_set_wakeup_enable(&tp->udev->dev, false); } -static void r8153_mac_clk_spd(struct r8152 *tp, bool enable) -{ - /* MAC clock speed down */ - if (enable) { - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, - ALDPS_SPDWN_RATIO); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, - EEE_SPDWN_RATIO); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, - PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN | - U1U2_SPDWN_EN | L1_SPDWN_EN); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, - PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN | - TP100_SPDWN_EN | TP500_SPDWN_EN | EEE_SPDWN_EN | - TP1000_SPDWN_EN); - } else { - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); - ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); - } -} - static void r8153_u1u2en(struct r8152 *tp, bool enable) { u8 u1u2[8]; @@ -2992,6 +3003,8 @@ } msleep(20); + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + break; } return data; @@ -3142,11 +3155,9 @@ if (enable) { r8153_u1u2en(tp, false); r8153_u2p3en(tp, false); - r8153_mac_clk_spd(tp, true); rtl_runtime_suspend_enable(tp, true); } else { rtl_runtime_suspend_enable(tp, false); - r8153_mac_clk_spd(tp, false); switch (tp->version) { case RTL_VER_03: @@ -3175,7 +3186,6 @@ r8153b_ups_en(tp, false); r8153_queue_wake(tp, false); rtl_runtime_suspend_enable(tp, false); - r8153_u2p3en(tp, true); r8153b_u1u2en(tp, true); } } @@ -3377,11 +3387,23 @@ set_bit(PHY_RESET, &tp->flags); } -static void r8152b_exit_oob(struct r8152 *tp) +static void wait_oob_link_list_ready(struct r8152 *tp) { u32 ocp_data; int i; + for (i = 0; i < 1000; i++) { + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); + if (ocp_data & LINK_LIST_READY) + break; + usleep_range(1000, 2000); + } +} + +static void r8152b_exit_oob(struct r8152 *tp) +{ + u32 ocp_data; + ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); ocp_data &= ~RCR_ACPT_ALL; ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); @@ -3399,23 +3421,13 @@ ocp_data &= ~MCU_BORW_EN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ocp_data |= RE_INIT_LL; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); rtl8152_nic_reset(tp); @@ -3457,7 +3469,6 @@ static void r8152b_enter_oob(struct r8152 *tp) { u32 ocp_data; - int i; ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ocp_data &= ~NOW_IS_OOB; @@ -3469,23 +3480,13 @@ rtl_disable(tp); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ocp_data |= RE_INIT_LL; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS); @@ -3703,7 +3704,6 @@ r8153_aldps_en(tp, true); r8152b_enable_fc(tp); - r8153_u2p3en(tp, true); set_bit(PHY_RESET, &tp->flags); } @@ -3711,9 +3711,7 @@ static void r8153_first_init(struct r8152 *tp) { u32 ocp_data; - int i; - r8153_mac_clk_spd(tp, false); rxdy_gated_en(tp, true); r8153_teredo_off(tp); @@ -3732,23 +3730,13 @@ ocp_data &= ~MCU_BORW_EN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ocp_data |= RE_INIT_LL; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); @@ -3773,9 +3761,6 @@ static void r8153_enter_oob(struct r8152 *tp) { u32 ocp_data; - int i; - - r8153_mac_clk_spd(tp, true); ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); ocp_data &= ~NOW_IS_OOB; @@ -3784,23 +3769,13 @@ rtl_disable(tp); rtl_reset_bmu(tp); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7); ocp_data |= RE_INIT_LL; ocp_write_word(tp, MCU_TYPE_PLA, PLA_SFF_STS_7, ocp_data); - for (i = 0; i < 1000; i++) { - ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL); - if (ocp_data & LINK_LIST_READY) - break; - usleep_range(1000, 2000); - } + wait_oob_link_list_ready(tp); ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); @@ -4004,6 +3979,8 @@ static void rtl8153_up(struct r8152 *tp) { + u32 ocp_data; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; @@ -4011,6 +3988,19 @@ r8153_u2p3en(tp, false); r8153_aldps_en(tp, false); r8153_first_init(tp); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); + ocp_data |= LANWAKE_CLR_EN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); + ocp_data &= ~LANWAKE_PIN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); + + ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1); + ocp_data &= ~DELAY_PHY_PWR_CHG; + ocp_write_word(tp, MCU_TYPE_USB, USB_SSPHYLINK1, ocp_data); + r8153_aldps_en(tp, true); switch (tp->version) { @@ -4029,11 +4019,17 @@ static void rtl8153_down(struct r8152 *tp) { + u32 ocp_data; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) { rtl_drop_queued_tx(tp); return; } + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); + ocp_data &= ~LANWAKE_CLR_EN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + r8153_u1u2en(tp, false); r8153_u2p3en(tp, false); r8153_power_cut_en(tp, false); @@ -4044,6 +4040,8 @@ static void rtl8153b_up(struct r8152 *tp) { + u32 ocp_data; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; @@ -4054,18 +4052,27 @@ r8153_first_init(tp); ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH, RX_THR_B); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); + ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + r8153_aldps_en(tp, true); - r8153_u2p3en(tp, true); r8153b_u1u2en(tp, true); } static void rtl8153b_down(struct r8152 *tp) { + u32 ocp_data; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) { rtl_drop_queued_tx(tp); return; } + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); + ocp_data |= PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + r8153b_u1u2en(tp, false); r8153_u2p3en(tp, false); r8153b_power_cut_en(tp, false); @@ -4299,9 +4306,10 @@ tp->rtl_ops.down(tp); mutex_unlock(&tp->control); + } + if (!res) usb_autopm_put_interface(tp->intf); - } free_all_mem(tp); @@ -4375,7 +4383,10 @@ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & AUTOLOAD_DONE) break; + msleep(20); + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + break; } data = r8153_phy_status(tp, 0); @@ -4449,11 +4460,24 @@ ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001); + /* MAC clock speed down */ + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); + r8153_power_cut_en(tp, false); r8153_u1u2en(tp, true); - r8153_mac_clk_spd(tp, false); usb_enable_lpm(tp->udev); + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6); + ocp_data |= LANWAKE_CLR_EN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6, ocp_data); + + ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG); + ocp_data &= ~LANWAKE_PIN; + ocp_write_byte(tp, MCU_TYPE_PLA, PLA_LWAKE_CTRL_REG, ocp_data); + /* rx aggregation */ ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL); ocp_data &= ~(RX_AGG_DISABLE | RX_ZERO_EN); @@ -4493,7 +4517,10 @@ if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & AUTOLOAD_DONE) break; + msleep(20); + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + break; } data = r8153_phy_status(tp, 0); @@ -4526,6 +4553,19 @@ ocp_data |= MAC_CLK_SPDWN_EN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, ocp_data); + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3); + ocp_data &= ~PLA_MCU_SPDWN_EN; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, ocp_data); + + if (tp->version == RTL_VER_09) { + /* Disable Test IO for 32QFN */ + if (ocp_read_byte(tp, MCU_TYPE_PLA, 0xdc00) & BIT(5)) { + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR); + ocp_data |= TEST_IO_OFF; + ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data); + } + } + set_bit(GREEN_ETHERNET, &tp->flags); /* rx aggregation */ @@ -5015,7 +5055,7 @@ { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); + memcpy(data, rtl8152_gstrings, sizeof(rtl8152_gstrings)); break; } } @@ -5479,7 +5519,10 @@ ops->in_nway = rtl8153_in_nway; ops->hw_phy_cfg = r8153_hw_phy_cfg; ops->autosuspend_en = rtl8153_runtime_enable; - tp->rx_buf_sz = 32 * 1024; + if (tp->udev->speed < USB_SPEED_SUPER) + tp->rx_buf_sz = 16 * 1024; + else + tp->rx_buf_sz = 32 * 1024; tp->eee_en = true; tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX; break; @@ -5525,7 +5568,8 @@ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); + PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), + USB_CTRL_GET_TIMEOUT); if (ret > 0) ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; @@ -5587,6 +5631,9 @@ return -ENODEV; } + if (intf->cur_altsetting->desc.bNumEndpoints < 3) + return -ENODEV; + usb_reset_device(udev); netdev = alloc_etherdev(sizeof(struct r8152)); if (!netdev) { @@ -5644,6 +5691,10 @@ netdev->hw_features &= ~NETIF_F_RXCSUM; } + if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO && + le16_to_cpu(udev->descriptor.idProduct) == 0x3082) + set_bit(LENOVO_MACPASSTHRU, &tp->flags); + if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial && (!strcmp(udev->serial, "000001000000") || !strcmp(udev->serial, "000002000000"))) { dev_info(&udev->dev, "Dell TB16 Dock, disable RX aggregation"); @@ -5687,6 +5738,11 @@ intf->needs_remote_wakeup = 1; + if (!rtl_can_wakeup(tp)) + __rtl_set_wol(tp, 0); + else + tp->saved_wolopts = __rtl_get_wol(tp); + tp->rtl_ops.init(tp); queue_delayed_work(system_long_wq, &tp->hw_phy_work, 0); set_ethernet_addr(tp); @@ -5700,10 +5756,6 @@ goto out1; } - if (!rtl_can_wakeup(tp)) - __rtl_set_wol(tp, 0); - - tp->saved_wolopts = __rtl_get_wol(tp); if (tp->saved_wolopts) device_set_wakeup_enable(&udev->dev, true); else @@ -5715,6 +5767,9 @@ out1: tasklet_kill(&tp->tx_tl); + cancel_delayed_work_sync(&tp->hw_phy_work); + if (tp->rtl_ops.unload) + tp->rtl_ops.unload(tp); usb_set_intfdata(intf, NULL); out: free_netdev(netdev); @@ -5760,13 +5815,17 @@ {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)}, {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)}, {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07c6)}, + {REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x0927)}, {REALTEK_USB_DEVICE(VENDOR_ID_SAMSUNG, 0xa101)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x304f)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3054)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3062)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3069)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x3082)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7205)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x720c)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x7214)}, + {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0x721e)}, {REALTEK_USB_DEVICE(VENDOR_ID_LENOVO, 0xa387)}, {REALTEK_USB_DEVICE(VENDOR_ID_LINKSYS, 0x0041)}, {REALTEK_USB_DEVICE(VENDOR_ID_NVIDIA, 0x09ff)}, --- linux-oracle-5.4.0.orig/drivers/net/usb/rndis_host.c +++ linux-oracle-5.4.0/drivers/net/usb/rndis_host.c @@ -201,7 +201,7 @@ dev_dbg(&info->control->dev, "rndis response error, code %d\n", retval); } - msleep(20); + msleep(40); } dev_dbg(&info->control->dev, "rndis response timeout\n"); return -ETIMEDOUT; @@ -255,7 +255,8 @@ off = le32_to_cpu(u.get_c->offset); len = le32_to_cpu(u.get_c->len); - if (unlikely((8 + off + len) > CONTROL_BUFFER_SIZE)) + if (unlikely((off > CONTROL_BUFFER_SIZE - 8) || + (len > CONTROL_BUFFER_SIZE - 8 - off))) goto response_error; if (*reply_len != -1 && len != *reply_len) @@ -387,7 +388,7 @@ reply_len = sizeof *phym; retval = rndis_query(dev, intf, u.buf, RNDIS_OID_GEN_PHYSICAL_MEDIUM, - 0, (void **) &phym, &reply_len); + reply_len, (void **)&phym, &reply_len); if (retval != 0 || !phym) { /* OID is optional so don't fail here. */ phym_unspec = cpu_to_le32(RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED); @@ -609,6 +610,11 @@ USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_poll_status_info, }, { + /* Hytera Communications DMR radios' "Radio to PC Network" */ + USB_VENDOR_AND_INTERFACE_INFO(0x238b, + USB_CLASS_COMM, 2 /* ACM */, 0x0ff), + .driver_info = (unsigned long)&rndis_info, +}, { /* RNDIS is MSFT's un-official variant of CDC ACM */ USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), .driver_info = (unsigned long) &rndis_info, --- linux-oracle-5.4.0.orig/drivers/net/usb/rtl8150.c +++ linux-oracle-5.4.0/drivers/net/usb/rtl8150.c @@ -71,6 +71,14 @@ #define MSR_SPEED (1<<3) #define MSR_LINK (1<<2) +/* USB endpoints */ +enum rtl8150_usb_ep { + RTL8150_USB_EP_CONTROL = 0, + RTL8150_USB_EP_BULK_IN = 1, + RTL8150_USB_EP_BULK_OUT = 2, + RTL8150_USB_EP_INT_IN = 3, +}; + /* Interrupt pipe data */ #define INT_TSR 0x00 #define INT_RSR 0x01 @@ -274,12 +282,20 @@ return 1; } -static inline void set_ethernet_addr(rtl8150_t * dev) +static void set_ethernet_addr(rtl8150_t *dev) { - u8 node_id[6]; + u8 node_id[ETH_ALEN]; + int ret; + + ret = get_registers(dev, IDR, sizeof(node_id), node_id); - get_registers(dev, IDR, sizeof(node_id), node_id); - memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id)); + if (ret == sizeof(node_id)) { + ether_addr_copy(dev->netdev->dev_addr, node_id); + } else { + eth_hw_addr_random(dev->netdev); + netdev_notice(dev->netdev, "Assigned a random MAC address: %pM\n", + dev->netdev->dev_addr); + } } static int rtl8150_set_mac_address(struct net_device *netdev, void *p) @@ -589,9 +605,9 @@ dev_kfree_skb(dev->rx_skb_pool[i]); } -static void rx_fixup(unsigned long data) +static void rx_fixup(struct tasklet_struct *t) { - struct rtl8150 *dev = (struct rtl8150 *)data; + struct rtl8150 *dev = from_tasklet(dev, t, tl); struct sk_buff *skb; int status; @@ -790,7 +806,8 @@ struct ethtool_link_ksettings *ecmd) { rtl8150_t *dev = netdev_priv(netdev); - short lpa, bmcr; + short lpa = 0; + short bmcr = 0; u32 supported; supported = (SUPPORTED_10baseT_Half | @@ -877,6 +894,13 @@ struct usb_device *udev = interface_to_usbdev(intf); rtl8150_t *dev; struct net_device *netdev; + static const u8 bulk_ep_addr[] = { + RTL8150_USB_EP_BULK_IN | USB_DIR_IN, + RTL8150_USB_EP_BULK_OUT | USB_DIR_OUT, + 0}; + static const u8 int_ep_addr[] = { + RTL8150_USB_EP_INT_IN | USB_DIR_IN, + 0}; netdev = alloc_etherdev(sizeof(rtl8150_t)); if (!netdev) @@ -890,7 +914,14 @@ return -ENOMEM; } - tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev); + /* Verify that all required endpoints are present */ + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) { + dev_err(&intf->dev, "couldn't find required endpoints\n"); + goto out; + } + + tasklet_setup(&dev->tl, rx_fixup); spin_lock_init(&dev->rx_pool_lock); dev->udev = udev; --- linux-oracle-5.4.0.orig/drivers/net/usb/sierra_net.c +++ linux-oracle-5.4.0/drivers/net/usb/sierra_net.c @@ -674,6 +674,7 @@ 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00}; static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = { 0x00, 0x00, SIERRA_NET_HIP_SHUTD_ID, 0x00}; + u8 mod[2]; dev_dbg(&dev->udev->dev, "%s", __func__); @@ -703,8 +704,9 @@ dev->net->netdev_ops = &sierra_net_device_ops; /* change MAC addr to include, ifacenum, and to be unique */ - dev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter); - dev->net->dev_addr[ETH_ALEN-1] = ifacenum; + mod[0] = atomic_inc_return(&iface_counter); + mod[1] = ifacenum; + dev_addr_mod(dev->net, ETH_ALEN - 2, mod, 2); /* prepare shutdown message template */ memcpy(priv->shdwn_msg, shdwn_tmplate, sizeof(priv->shdwn_msg)); --- linux-oracle-5.4.0.orig/drivers/net/usb/smsc75xx.c +++ linux-oracle-5.4.0/drivers/net/usb/smsc75xx.c @@ -90,7 +90,9 @@ ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, &buf, 4); - if (unlikely(ret < 0)) { + if (unlikely(ret < 4)) { + ret = ret < 0 ? ret : -ENODATA; + netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", index, ret); return ret; @@ -1482,7 +1484,7 @@ ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) { netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); - return ret; + goto free_pdata; } smsc75xx_init_mac_address(dev); @@ -1491,7 +1493,7 @@ ret = smsc75xx_reset(dev); if (ret < 0) { netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); - return ret; + goto cancel_work; } dev->net->netdev_ops = &smsc75xx_netdev_ops; @@ -1501,6 +1503,13 @@ dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; dev->net->max_mtu = MAX_SINGLE_PACKET_SIZE; return 0; + +cancel_work: + cancel_work_sync(&pdata->set_multicast); +free_pdata: + kfree(pdata); + dev->data[0] = 0; + return ret; } static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) @@ -1510,7 +1519,6 @@ cancel_work_sync(&pdata->set_multicast); netif_dbg(dev, ifdown, dev->net, "free pdata\n"); kfree(pdata); - pdata = NULL; dev->data[0] = 0; } } @@ -2192,6 +2200,13 @@ size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING; align_count = (4 - ((size + RXW_PADDING) % 4)) % 4; + if (unlikely(size > skb->len)) { + netif_dbg(dev, rx_err, dev->net, + "size err rx_cmd_a=0x%08x\n", + rx_cmd_a); + return 0; + } + if (unlikely(rx_cmd_a & RX_CMD_A_RED)) { netif_dbg(dev, rx_err, dev->net, "Error rx_cmd_a=0x%08x\n", rx_cmd_a); --- linux-oracle-5.4.0.orig/drivers/net/usb/smsc95xx.c +++ linux-oracle-5.4.0/drivers/net/usb/smsc95xx.c @@ -261,16 +261,18 @@ mutex_unlock(&dev->phy_mutex); } -static int smsc95xx_mdio_read_nopm(struct net_device *netdev, int phy_id, - int idx) +static int smsc95xx_mdio_read_nopm(struct usbnet *dev, int idx) { - return __smsc95xx_mdio_read(netdev, phy_id, idx, 1); + struct mii_if_info *mii = &dev->mii; + + return __smsc95xx_mdio_read(dev->net, mii->phy_id, idx, 1); } -static void smsc95xx_mdio_write_nopm(struct net_device *netdev, int phy_id, - int idx, int regval) +static void smsc95xx_mdio_write_nopm(struct usbnet *dev, int idx, int regval) { - __smsc95xx_mdio_write(netdev, phy_id, idx, regval, 1); + struct mii_if_info *mii = &dev->mii; + + __smsc95xx_mdio_write(dev->net, mii->phy_id, idx, regval, 1); } static int smsc95xx_mdio_read(struct net_device *netdev, int phy_id, int idx) @@ -455,7 +457,7 @@ static void smsc95xx_set_multicast(struct net_device *netdev) { struct usbnet *dev = netdev_priv(netdev); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; int ret; @@ -550,7 +552,7 @@ static int smsc95xx_link_reset(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; struct mii_if_info *mii = &dev->mii; struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET }; unsigned long flags; @@ -618,7 +620,7 @@ static void set_carrier(struct usbnet *dev, bool link) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; if (pdata->link_ok == link) return; @@ -747,7 +749,7 @@ struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; wolinfo->supported = SUPPORTED_WAKE; wolinfo->wolopts = pdata->wolopts; @@ -757,7 +759,7 @@ struct ethtool_wolinfo *wolinfo) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int ret; if (wolinfo->wolopts & ~SUPPORTED_WAKE) @@ -796,7 +798,7 @@ static void set_mdix_status(struct net_device *net, __u8 mdix_ctrl) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int buf; if ((pdata->chip_id == ID_REV_CHIP_ID_9500A_) || @@ -845,7 +847,7 @@ struct ethtool_link_ksettings *cmd) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int retval; retval = usbnet_get_link_ksettings(net, cmd); @@ -860,7 +862,7 @@ const struct ethtool_link_ksettings *cmd) { struct usbnet *dev = netdev_priv(net); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int retval; if (pdata->mdix_ctrl != cmd->base.eth_tp_mdix_ctrl) @@ -942,7 +944,7 @@ /* starts the TX path */ static int smsc95xx_start_tx_path(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; int ret; @@ -962,7 +964,7 @@ /* Starts the Receive path */ static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; unsigned long flags; spin_lock_irqsave(&pdata->mac_cr_lock, flags); @@ -1019,8 +1021,8 @@ static int smsc95xx_reset(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - u32 read_buf, write_buf, burst_cap; + struct smsc95xx_priv *pdata = dev->driver_priv; + u32 read_buf, burst_cap; int ret = 0, timeout; netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n"); @@ -1040,7 +1042,7 @@ if (timeout >= 100) { netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n"); - return ret; + return -ETIMEDOUT; } ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_); @@ -1162,10 +1164,13 @@ return ret; netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf); + ret = smsc95xx_read_reg(dev, LED_GPIO_CFG, &read_buf); + if (ret < 0) + return ret; /* Configure GPIO pins as LED outputs */ - write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | - LED_GPIO_CFG_FDX_LED; - ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf); + read_buf |= LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED | + LED_GPIO_CFG_FDX_LED; + ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, read_buf); if (ret < 0) return ret; @@ -1247,7 +1252,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) { - struct smsc95xx_priv *pdata = NULL; + struct smsc95xx_priv *pdata; u32 val; int ret; @@ -1259,13 +1264,12 @@ return ret; } - dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc95xx_priv), - GFP_KERNEL); - - pdata = (struct smsc95xx_priv *)(dev->data[0]); + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; + dev->driver_priv = pdata; + spin_lock_init(&pdata->mac_cr_lock); /* LAN95xx devices do not alter the computed checksum of 0 to 0xffff. @@ -1287,11 +1291,14 @@ /* Init all registers */ ret = smsc95xx_reset(dev); + if (ret) + goto free_pdata; /* detect device revision as different features may be available */ ret = smsc95xx_read_reg(dev, ID_REV, &val); if (ret < 0) - return ret; + goto free_pdata; + val >>= 16; pdata->chip_id = val; pdata->mdix_ctrl = get_mdix_status(dev->net); @@ -1317,19 +1324,19 @@ schedule_delayed_work(&pdata->carrier_check, CARRIER_CHECK_DELAY); return 0; + +free_pdata: + kfree(pdata); + return ret; } static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; - if (pdata) { - cancel_delayed_work(&pdata->carrier_check); - netif_dbg(dev, ifdown, dev->net, "free pdata\n"); - kfree(pdata); - pdata = NULL; - dev->data[0] = 0; - } + cancel_delayed_work_sync(&pdata->carrier_check); + netif_dbg(dev, ifdown, dev->net, "free pdata\n"); + kfree(pdata); } static u32 smsc_crc(const u8 *buffer, size_t len, int filter) @@ -1340,39 +1347,37 @@ static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) { - struct mii_if_info *mii = &dev->mii; int ret; netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); /* read to clear */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_SRC); + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC); if (ret < 0) return ret; /* enable interrupt source */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_INT_MASK); + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK); if (ret < 0) return ret; ret |= mask; - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_INT_MASK, ret); + smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret); return 0; } static int smsc95xx_link_ok_nopm(struct usbnet *dev) { - struct mii_if_info *mii = &dev->mii; int ret; /* first, a dummy read, needed to latch some MII phys */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); + ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR); if (ret < 0) return ret; - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, MII_BMSR); + ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR); if (ret < 0) return ret; @@ -1381,7 +1386,7 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1420,8 +1425,7 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); - struct mii_if_info *mii = &dev->mii; + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1429,17 +1433,17 @@ * compatibility with non-standard link partners */ if (pdata->features & FEATURE_PHY_NLP_CROSSOVER) - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_EDPD_CONFIG, - PHY_EDPD_CONFIG_DEFAULT); + smsc95xx_mdio_write_nopm(dev, PHY_EDPD_CONFIG, + PHY_EDPD_CONFIG_DEFAULT); /* enable energy detect power-down mode */ - ret = smsc95xx_mdio_read_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS); + ret = smsc95xx_mdio_read_nopm(dev, PHY_MODE_CTRL_STS); if (ret < 0) return ret; ret |= MODE_CTRL_STS_EDPWRDOWN_; - smsc95xx_mdio_write_nopm(dev->net, mii->phy_id, PHY_MODE_CTRL_STS, ret); + smsc95xx_mdio_write_nopm(dev, PHY_MODE_CTRL_STS, ret); /* enter SUSPEND1 mode */ ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val); @@ -1468,7 +1472,7 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1490,7 +1494,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val; int ret; @@ -1529,7 +1533,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; int ret; if (!netif_running(dev->net)) { @@ -1577,7 +1581,7 @@ static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; u32 val, link_up; int ret; @@ -1848,7 +1852,7 @@ u32 val; BUG_ON(!dev); - pdata = (struct smsc95xx_priv *)(dev->data[0]); + pdata = dev->driver_priv; suspend_flags = pdata->suspend_flags; netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags); @@ -1903,9 +1907,11 @@ static void smsc95xx_rx_csum_offload(struct sk_buff *skb) { - skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2); + u16 *csum_ptr = (u16 *)(skb_tail_pointer(skb) - 2); + + skb->csum = (__force __wsum)get_unaligned(csum_ptr); skb->ip_summed = CHECKSUM_COMPLETE; - skb_trim(skb, skb->len - 2); + skb_trim(skb, skb->len - 2); /* remove csum */ } static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) @@ -1928,6 +1934,12 @@ size = (u16)((header & RX_STS_FL_) >> 16); align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; + if (unlikely(size > skb->len)) { + netif_dbg(dev, rx_err, dev->net, + "size err header=0x%08x\n", header); + return 0; + } + if (unlikely(header & RX_STS_ES_)) { netif_dbg(dev, rx_err, dev->net, "Error header=0x%08x\n", header); @@ -1957,25 +1969,22 @@ if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(skb); skb_trim(skb, skb->len - 4); /* remove fcs */ - skb->truesize = size + sizeof(struct sk_buff); return 1; } - ax_skb = skb_clone(skb, GFP_ATOMIC); + ax_skb = netdev_alloc_skb_ip_align(dev->net, size); if (unlikely(!ax_skb)) { netdev_warn(dev->net, "Error allocating skb\n"); return 0; } - ax_skb->len = size; - ax_skb->data = packet; - skb_set_tail_pointer(ax_skb, size); + skb_put(ax_skb, size); + memcpy(ax_skb->data, packet, size); if (dev->net->features & NETIF_F_RXCSUM) smsc95xx_rx_csum_offload(ax_skb); skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */ - ax_skb->truesize = size + sizeof(struct sk_buff); usbnet_skb_return(dev, ax_skb); } @@ -2068,7 +2077,7 @@ static int smsc95xx_manage_power(struct usbnet *dev, int on) { - struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); + struct smsc95xx_priv *pdata = dev->driver_priv; dev->intf->needs_remote_wakeup = on; --- linux-oracle-5.4.0.orig/drivers/net/usb/sr9700.c +++ linux-oracle-5.4.0/drivers/net/usb/sr9700.c @@ -178,6 +178,7 @@ struct usbnet *dev = netdev_priv(netdev); __le16 res; int rc = 0; + int err; if (phy_id) { netdev_dbg(netdev, "Only internal phy supported\n"); @@ -188,11 +189,17 @@ if (loc == MII_BMSR) { u8 value; - sr_read_reg(dev, SR_NSR, &value); + err = sr_read_reg(dev, SR_NSR, &value); + if (err < 0) + return err; + if (value & NSR_LINKST) rc = 1; } - sr_share_read_word(dev, 1, loc, &res); + err = sr_share_read_word(dev, 1, loc, &res); + if (err < 0) + return err; + if (rc == 1) res = le16_to_cpu(res) | BMSR_LSTATUS; else @@ -319,6 +326,7 @@ { struct net_device *netdev; struct mii_if_info *mii; + u8 addr[ETH_ALEN]; int ret; ret = usbnet_get_endpoints(dev, intf); @@ -349,11 +357,12 @@ * EEPROM automatically to PAR. In case there is no EEPROM externally, * a default MAC address is stored in PAR for making chip work properly. */ - if (sr_read(dev, SR_PAR, ETH_ALEN, netdev->dev_addr) < 0) { + if (sr_read(dev, SR_PAR, ETH_ALEN, addr) < 0) { netdev_err(netdev, "Error reading MAC address\n"); ret = -ENODEV; goto out; } + eth_hw_addr_set(netdev, addr); /* power up and reset phy */ sr_write_reg(dev, SR_PRR, PRR_PHY_RST); @@ -410,7 +419,7 @@ /* ignore the CRC length */ len = (skb->data[1] | (skb->data[2] << 8)) - 4; - if (len > ETH_FRAME_LEN) + if (len > ETH_FRAME_LEN || len > skb->len || len < 0) return 0; /* the last packet of current skb */ @@ -418,19 +427,15 @@ skb_pull(skb, 3); skb->len = len; skb_set_tail_pointer(skb, len); - skb->truesize = len + sizeof(struct sk_buff); return 2; } - /* skb_clone is used for address align */ - sr_skb = skb_clone(skb, GFP_ATOMIC); + sr_skb = netdev_alloc_skb_ip_align(dev->net, len); if (!sr_skb) return 0; - sr_skb->len = len; - sr_skb->data = skb->data + 3; - skb_set_tail_pointer(sr_skb, len); - sr_skb->truesize = len + sizeof(struct sk_buff); + skb_put(sr_skb, len); + memcpy(sr_skb->data, skb->data + 3, len); usbnet_skb_return(dev, sr_skb); skb_pull(skb, len + SR_RX_OVERHEAD); --- linux-oracle-5.4.0.orig/drivers/net/usb/sr9800.c +++ linux-oracle-5.4.0/drivers/net/usb/sr9800.c @@ -731,12 +731,15 @@ struct sr_data *data = (struct sr_data *)&dev->data; u16 led01_mux, led23_mux; int ret, embd_phy; + u8 addr[ETH_ALEN]; u32 phyid; u16 rx_ctl; data->eeprom_len = SR9800_EEPROM_LEN; - usbnet_get_endpoints(dev, intf); + ret = usbnet_get_endpoints(dev, intf); + if (ret) + goto out; /* LED Setting Rule : * AABB:CCDD @@ -754,12 +757,12 @@ } /* Get the MAC address */ - ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, - dev->net->dev_addr); + ret = sr_read_cmd(dev, SR_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, addr); if (ret < 0) { netdev_dbg(dev->net, "Failed to read MAC address: %d\n", ret); return ret; } + eth_hw_addr_set(dev->net, addr); netdev_dbg(dev->net, "mac addr : %pM\n", dev->net->dev_addr); /* Initialize MII structure */ --- linux-oracle-5.4.0.orig/drivers/net/usb/usbnet.c +++ linux-oracle-5.4.0/drivers/net/usb/usbnet.c @@ -67,9 +67,6 @@ /*-------------------------------------------------------------------------*/ -// randomly generated ethernet address -static u8 node_id [ETH_ALEN]; - /* use ethtool to change the level for any given device */ static int msg_level = -1; module_param (msg_level, int, 0); @@ -151,12 +148,13 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress) { + u8 addr[ETH_ALEN]; int tmp = -1, ret; unsigned char buf [13]; ret = usb_string(dev->udev, iMACAddress, buf, sizeof buf); if (ret == 12) - tmp = hex2bin(dev->net->dev_addr, buf, 6); + tmp = hex2bin(addr, buf, 6); if (tmp < 0) { dev_dbg(&dev->udev->dev, "bad MAC string %d fetch, %d\n", iMACAddress, tmp); @@ -164,6 +162,7 @@ ret = -EINVAL; return ret; } + eth_hw_addr_set(dev->net, addr); return 0; } EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr); @@ -833,13 +832,11 @@ mpn = !test_and_clear_bit(EVENT_NO_RUNTIME_PM, &dev->flags); - /* deferred work (task, timer, softirq) must also stop. - * can't flush_scheduled_work() until we drop rtnl (later), - * else workers could deadlock; so make workers a NOP. - */ + /* deferred work (timer, softirq, task) must also stop */ dev->flags = 0; del_timer_sync (&dev->delay); tasklet_kill (&dev->bh); + cancel_work_sync(&dev->kevent); if (!pm) usb_autopm_put_interface(dev->intf); @@ -1587,6 +1584,7 @@ struct usbnet *dev; struct usb_device *xdev; struct net_device *net; + struct urb *urb; dev = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); @@ -1603,9 +1601,11 @@ net = dev->net; unregister_netdev (net); - cancel_work_sync(&dev->kevent); - - usb_scuttle_anchored_urbs(&dev->deferred); + while ((urb = usb_get_from_anchor(&dev->deferred))) { + dev_kfree_skb(urb->context); + kfree(urb->sg); + usb_free_urb(urb); + } if (dev->driver_info->unbind) dev->driver_info->unbind (dev, intf); @@ -1710,8 +1710,7 @@ dev->interrupt_count = 0; dev->net = net; - strcpy (net->name, "usb%d"); - memcpy (net->dev_addr, node_id, sizeof node_id); + strscpy(net->name, "usb%d", sizeof(net->name)); /* rx and tx sides can use different message sizes; * bind() should set rx_urb_size in that case. @@ -1736,14 +1735,15 @@ // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || - (net->dev_addr [0] & 0x02) == 0)) - strcpy (net->name, "eth%d"); + /* somebody touched it*/ + !is_zero_ether_addr(net->dev_addr))) + strscpy(net->name, "eth%d", sizeof(net->name)); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) - strcpy(net->name, "wlan%d"); + strscpy(net->name, "wlan%d", sizeof(net->name)); /* WWAN devices should always be named "wwan%d" */ if ((dev->driver_info->flags & FLAG_WWAN) != 0) - strcpy(net->name, "wwan%d"); + strscpy(net->name, "wwan%d", sizeof(net->name)); /* devices that cannot do ARP */ if ((dev->driver_info->flags & FLAG_NOARP) != 0) @@ -1755,6 +1755,10 @@ } else if (!info->in || !info->out) status = usbnet_get_endpoints (dev, udev); else { + u8 ep_addrs[3] = { + info->in + USB_DIR_IN, info->out + USB_DIR_OUT, 0 + }; + dev->in = usb_rcvbulkpipe (xdev, info->in); dev->out = usb_sndbulkpipe (xdev, info->out); if (!(info->flags & FLAG_NO_SETINT)) @@ -1764,6 +1768,8 @@ else status = 0; + if (status == 0 && !usb_check_bulk_endpoints(udev, ep_addrs)) + status = -EINVAL; } if (status >= 0 && dev->status) status = init_status (dev, udev); @@ -1773,10 +1779,15 @@ if (!dev->rx_urb_size) dev->rx_urb_size = dev->hard_mtu; dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); + if (dev->maxpacket == 0) { + /* that is a broken device */ + status = -ENODEV; + goto out4; + } - /* let userspace know we have a random address */ - if (ether_addr_equal(net->dev_addr, node_id)) - net->addr_assign_type = NET_ADDR_RANDOM; + /* this flags the device for user space */ + if (!is_valid_ether_addr(net->dev_addr)) + eth_hw_addr_random(net); if ((dev->driver_info->flags & FLAG_WLAN) != 0) SET_NETDEV_DEVTYPE(net, &wlan_type); @@ -1982,7 +1993,7 @@ cmd, reqtype, value, index, size); if (size) { - buf = kmalloc(size, GFP_KERNEL); + buf = kmalloc(size, GFP_NOIO); if (!buf) goto out; } @@ -2014,7 +2025,7 @@ cmd, reqtype, value, index, size); if (data) { - buf = kmemdup(data, size, GFP_KERNEL); + buf = kmemdup(data, size, GFP_NOIO); if (!buf) goto out; } else { @@ -2115,7 +2126,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, u16 value, u16 index, const void *data, u16 size) { - struct usb_ctrlrequest *req = NULL; + struct usb_ctrlrequest *req; struct urb *urb; int err = -ENOMEM; void *buf = NULL; @@ -2133,7 +2144,7 @@ if (!buf) { netdev_err(dev->net, "Error allocating buffer" " in %s!\n", __func__); - goto fail_free; + goto fail_free_urb; } } @@ -2157,14 +2168,21 @@ if (err < 0) { netdev_err(dev->net, "Error submitting the control" " message: status=%d\n", err); - goto fail_free; + goto fail_free_all; } return 0; +fail_free_all: + kfree(req); fail_free_buf: kfree(buf); -fail_free: - kfree(req); + /* + * avoid a double free + * needed because the flag can be set only + * after filling the URB + */ + urb->transfer_flags = 0; +fail_free_urb: usb_free_urb(urb); fail: return err; @@ -2179,7 +2197,6 @@ BUILD_BUG_ON( FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data)); - eth_random_addr(node_id); return 0; } module_init(usbnet_init); --- linux-oracle-5.4.0.orig/drivers/net/usb/zaurus.c +++ linux-oracle-5.4.0/drivers/net/usb/zaurus.c @@ -256,6 +256,11 @@ .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \ .bInterfaceProtocol = USB_CDC_PROTO_NONE +#define ZAURUS_FAKE_INTERFACE \ + .bInterfaceClass = USB_CLASS_COMM, \ + .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \ + .bInterfaceProtocol = USB_CDC_PROTO_NONE + /* SA-1100 based Sharp Zaurus ("collie"), or compatible. */ { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO @@ -284,11 +289,25 @@ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, + .idProduct = 0x8005, /* A-300 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, .idProduct = 0x8006, /* B-500/SL-5600 */ ZAURUS_MASTER_INTERFACE, .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct = 0x8006, /* B-500/SL-5600 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x8007, /* C-700 */ @@ -296,6 +315,13 @@ .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct = 0x8007, /* C-700 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, .idProduct = 0x9031, /* C-750 C-760 */ @@ -315,6 +341,13 @@ .driver_info = ZAURUS_PXA_INFO, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + .idProduct = 0x9032, /* SL-6000 */ + ZAURUS_FAKE_INTERFACE, + .driver_info = (unsigned long)&bogus_mdlm_info, +}, { + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, .idVendor = 0x04DD, /* reported with some C860 units */ --- linux-oracle-5.4.0.orig/drivers/net/veth.c +++ linux-oracle-5.4.0/drivers/net/veth.c @@ -209,9 +209,10 @@ { /* Write ptr_ring before reading rx_notify_masked */ smp_mb(); - if (!rq->rx_notify_masked) { - rq->rx_notify_masked = true; - napi_schedule(&rq->xdp_napi); + if (!READ_ONCE(rq->rx_notify_masked) && + napi_schedule_prep(&rq->xdp_napi)) { + WRITE_ONCE(rq->rx_notify_masked, true); + __napi_schedule(&rq->xdp_napi); } } @@ -237,6 +238,7 @@ { struct veth_priv *rcv_priv, *priv = netdev_priv(dev); struct veth_rq *rq = NULL; + int ret = NETDEV_TX_OK; struct net_device *rcv; int length = skb->len; bool rcv_xdp = false; @@ -244,7 +246,7 @@ rcu_read_lock(); rcv = rcu_dereference(priv->peer); - if (unlikely(!rcv)) { + if (unlikely(!rcv) || !pskb_may_pull(skb, ETH_HLEN)) { kfree_skb(skb); goto drop; } @@ -254,8 +256,6 @@ if (rxq < rcv->real_num_rx_queues) { rq = &rcv_priv->rq[rxq]; rcv_xdp = rcu_access_pointer(rq->xdp_prog); - if (rcv_xdp) - skb_record_rx_queue(skb, rxq); } skb_tx_timestamp(skb); @@ -271,6 +271,7 @@ } else { drop: atomic64_inc(&priv->dropped); + ret = NET_XMIT_DROP; } if (rcv_xdp) @@ -278,7 +279,7 @@ rcu_read_unlock(); - return NETDEV_TX_OK; + return ret; } static u64 veth_stats_tx(struct pcpu_lstats *result, struct net_device *dev) @@ -510,13 +511,15 @@ struct veth_xdp_tx_bq *bq) { void *hard_start = frame->data - frame->headroom; - void *head = hard_start - sizeof(struct xdp_frame); int len = frame->len, delta = 0; struct xdp_frame orig_frame; struct bpf_prog *xdp_prog; unsigned int headroom; struct sk_buff *skb; + /* bpf_xdp_adjust_head() assures BPF cannot access xdp_frame area */ + hard_start -= sizeof(struct xdp_frame); + rcu_read_lock(); xdp_prog = rcu_dereference(rq->xdp_prog); if (likely(xdp_prog)) { @@ -538,7 +541,6 @@ break; case XDP_TX: orig_frame = *frame; - xdp.data_hard_start = head; xdp.rxq->mem = frame->mem; if (unlikely(veth_xdp_tx(rq->dev, &xdp, bq) < 0)) { trace_xdp_exception(rq->dev, xdp_prog, act); @@ -550,7 +552,6 @@ goto xdp_xmit; case XDP_REDIRECT: orig_frame = *frame; - xdp.data_hard_start = head; xdp.rxq->mem = frame->mem; if (xdp_do_redirect(rq->dev, &xdp, xdp_prog)) { frame = &orig_frame; @@ -572,7 +573,7 @@ rcu_read_unlock(); headroom = sizeof(struct xdp_frame) + frame->headroom - delta; - skb = veth_build_skb(head, headroom, len, 0); + skb = veth_build_skb(hard_start, headroom, len, 0); if (!skb) { xdp_return_frame(frame); goto err; @@ -782,8 +783,10 @@ /* Write rx_notify_masked before reading ptr_ring */ smp_store_mb(rq->rx_notify_masked, false); if (unlikely(!__ptr_ring_empty(&rq->xdp_ring))) { - rq->rx_notify_masked = true; - napi_schedule(&rq->xdp_napi); + if (napi_schedule_prep(&rq->xdp_napi)) { + WRITE_ONCE(rq->rx_notify_masked, true); + __napi_schedule(&rq->xdp_napi); + } } } @@ -1254,10 +1257,7 @@ nla_peer = data[VETH_INFO_PEER]; ifmp = nla_data(nla_peer); - err = rtnl_nla_parse_ifla(peer_tb, - nla_data(nla_peer) + sizeof(struct ifinfomsg), - nla_len(nla_peer) - sizeof(struct ifinfomsg), - NULL); + err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack); if (err < 0) return err; --- linux-oracle-5.4.0.orig/drivers/net/virtio_net.c +++ linux-oracle-5.4.0/drivers/net/virtio_net.c @@ -63,6 +63,11 @@ VIRTIO_NET_F_GUEST_CSUM }; +#define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ + (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ + (1ULL << VIRTIO_NET_F_GUEST_ECN) | \ + (1ULL << VIRTIO_NET_F_GUEST_UFO)) + struct virtnet_stat_desc { char desc[ETH_GSTRING_LEN]; size_t offset; @@ -190,6 +195,9 @@ /* # of XDP queue pairs currently used by the driver */ u16 xdp_queue_pairs; + /* xdp_queue_pairs may be 0, when xdp is already loaded. So add this. */ + bool xdp_enabled; + /* I like... big packets and I cannot lie! */ bool big_packets; @@ -205,9 +213,15 @@ /* Packet virtio header size */ u8 hdr_len; - /* Work struct for refilling if we run low on memory. */ + /* Work struct for delayed refilling if we run low on memory. */ struct delayed_work refill; + /* Is delayed refill enabled? */ + bool refill_enabled; + + /* The lock to synchronize the access to refill_enabled */ + spinlock_t refill_lock; + /* Work struct for config space updates */ struct work_struct config_work; @@ -311,6 +325,20 @@ return p; } +static void enable_delayed_refill(struct virtnet_info *vi) +{ + spin_lock_bh(&vi->refill_lock); + vi->refill_enabled = true; + spin_unlock_bh(&vi->refill_lock); +} + +static void disable_delayed_refill(struct virtnet_info *vi) +{ + spin_lock_bh(&vi->refill_lock); + vi->refill_enabled = false; + spin_unlock_bh(&vi->refill_lock); +} + static void virtqueue_napi_schedule(struct napi_struct *napi, struct virtqueue *vq) { @@ -371,7 +399,7 @@ struct receive_queue *rq, struct page *page, unsigned int offset, unsigned int len, unsigned int truesize, - bool hdr_valid) + bool hdr_valid, unsigned int metasize) { struct sk_buff *skb; struct virtio_net_hdr_mrg_rxbuf *hdr; @@ -393,6 +421,7 @@ else hdr_padded_len = sizeof(struct padded_vnet_hdr); + /* hdr_valid means no XDP, so we can copy the vnet header */ if (hdr_valid) memcpy(hdr, p, hdr_len); @@ -400,11 +429,20 @@ offset += hdr_padded_len; p += hdr_padded_len; - copy = len; - if (copy > skb_tailroom(skb)) - copy = skb_tailroom(skb); + /* Copy all frame if it fits skb->head, otherwise + * we let virtio_net_hdr_to_skb() and GRO pull headers as needed. + */ + if (len <= skb_tailroom(skb)) + copy = len; + else + copy = ETH_HLEN + metasize; skb_put_data(skb, p, copy); + if (metasize) { + __skb_pull(skb, metasize); + skb_metadata_set(skb, metasize); + } + len -= copy; offset += copy; @@ -450,10 +488,6 @@ struct virtio_net_hdr_mrg_rxbuf *hdr; int err; - /* virtqueue want to use data area in-front of packet */ - if (unlikely(xdpf->metasize > 0)) - return -EOPNOTSUPP; - if (unlikely(xdpf->headroom < vi->hdr_len)) return -EOVERFLOW; @@ -474,12 +508,41 @@ return 0; } -static struct send_queue *virtnet_xdp_sq(struct virtnet_info *vi) -{ - unsigned int qp; - - qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id(); - return &vi->sq[qp]; +/* when vi->curr_queue_pairs > nr_cpu_ids, the txq/sq is only used for xdp tx on + * the current cpu, so it does not need to be locked. + * + * Here we use marco instead of inline functions because we have to deal with + * three issues at the same time: 1. the choice of sq. 2. judge and execute the + * lock/unlock of txq 3. make sparse happy. It is difficult for two inline + * functions to perfectly solve these three problems at the same time. + */ +#define virtnet_xdp_get_sq(vi) ({ \ + struct netdev_queue *txq; \ + typeof(vi) v = (vi); \ + unsigned int qp; \ + \ + if (v->curr_queue_pairs > nr_cpu_ids) { \ + qp = v->curr_queue_pairs - v->xdp_queue_pairs; \ + qp += smp_processor_id(); \ + txq = netdev_get_tx_queue(v->dev, qp); \ + __netif_tx_acquire(txq); \ + } else { \ + qp = smp_processor_id() % v->curr_queue_pairs; \ + txq = netdev_get_tx_queue(v->dev, qp); \ + __netif_tx_lock(txq, raw_smp_processor_id()); \ + } \ + v->sq + qp; \ +}) + +#define virtnet_xdp_put_sq(vi, q) { \ + struct netdev_queue *txq; \ + typeof(vi) v = (vi); \ + \ + txq = netdev_get_tx_queue(v->dev, (q) - v->sq); \ + if (v->curr_queue_pairs > nr_cpu_ids) \ + __netif_tx_release(txq); \ + else \ + __netif_tx_unlock(txq); \ } static int virtnet_xdp_xmit(struct net_device *dev, @@ -505,7 +568,7 @@ if (!xdp_prog) return -ENXIO; - sq = virtnet_xdp_sq(vi); + sq = virtnet_xdp_get_sq(vi); if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) { ret = -EINVAL; @@ -553,12 +616,13 @@ sq->stats.kicks += kicks; u64_stats_update_end(&sq->stats.syncp); + virtnet_xdp_put_sq(vi, sq); return ret; } static unsigned int virtnet_get_headroom(struct virtnet_info *vi) { - return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0; + return vi->xdp_enabled ? VIRTIO_XDP_HEADROOM : 0; } /* We copy the packet for XDP in the following cases: @@ -582,8 +646,13 @@ int page_off, unsigned int *len) { - struct page *page = alloc_page(GFP_ATOMIC); + int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + struct page *page; + if (page_off + *len + tailroom > PAGE_SIZE) + return NULL; + + page = alloc_page(GFP_ATOMIC); if (!page) return NULL; @@ -591,7 +660,6 @@ page_off += *len; while (--*num_buf) { - int tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); unsigned int buflen; void *buf; int off; @@ -644,6 +712,7 @@ unsigned int delta = 0; struct page *xdp_page; int err; + unsigned int metasize = 0; len -= vi->hdr_len; stats->bytes += len; @@ -683,8 +752,8 @@ xdp.data_hard_start = buf + VIRTNET_RX_PAD + vi->hdr_len; xdp.data = xdp.data_hard_start + xdp_headroom; - xdp_set_data_meta_invalid(&xdp); xdp.data_end = xdp.data + len; + xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; orig_data = xdp.data; act = bpf_prog_run_xdp(xdp_prog, &xdp); @@ -695,6 +764,7 @@ /* Recalculate length in case bpf program changed it */ delta = orig_data - xdp.data; len = xdp.data_end - xdp.data; + metasize = xdp.data - xdp.data_meta; break; case XDP_TX: stats->xdp_tx++; @@ -740,6 +810,9 @@ memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len); } /* keep zeroed vnet hdr since packet was changed by bpf */ + if (metasize) + skb_metadata_set(skb, metasize); + err: return skb; @@ -760,8 +833,8 @@ struct virtnet_rq_stats *stats) { struct page *page = buf; - struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, - PAGE_SIZE, true); + struct sk_buff *skb = + page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, true, 0); stats->bytes += len - vi->hdr_len; if (unlikely(!skb)) @@ -793,6 +866,7 @@ unsigned int truesize; unsigned int headroom = mergeable_ctx_to_headroom(ctx); int err; + unsigned int metasize = 0; head_skb = NULL; stats->bytes += len - vi->hdr_len; @@ -839,8 +913,8 @@ data = page_address(xdp_page) + offset; xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM + vi->hdr_len; xdp.data = data + vi->hdr_len; - xdp_set_data_meta_invalid(&xdp); xdp.data_end = xdp.data + (len - vi->hdr_len); + xdp.data_meta = xdp.data; xdp.rxq = &rq->xdp_rxq; act = bpf_prog_run_xdp(xdp_prog, &xdp); @@ -848,24 +922,27 @@ switch (act) { case XDP_PASS: + metasize = xdp.data - xdp.data_meta; + /* recalculate offset to account for any header - * adjustments. Note other cases do not build an - * skb and avoid using offset + * adjustments and minus the metasize to copy the + * metadata in page_to_skb(). Note other cases do not + * build an skb and avoid using offset */ - offset = xdp.data - - page_address(xdp_page) - vi->hdr_len; + offset = xdp.data - page_address(xdp_page) - + vi->hdr_len - metasize; - /* recalculate len if xdp.data or xdp.data_end were - * adjusted + /* recalculate len if xdp.data, xdp.data_end or + * xdp.data_meta were adjusted */ - len = xdp.data_end - xdp.data + vi->hdr_len; + len = xdp.data_end - xdp.data + vi->hdr_len + metasize; /* We can only create skb based on xdp_page. */ if (unlikely(xdp_page != page)) { rcu_read_unlock(); put_page(page); - head_skb = page_to_skb(vi, rq, xdp_page, - offset, len, - PAGE_SIZE, false); + head_skb = page_to_skb(vi, rq, xdp_page, offset, + len, PAGE_SIZE, false, + metasize); return head_skb; } break; @@ -921,7 +998,8 @@ goto err_skb; } - head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog); + head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog, + metasize); curr_skb = head_skb; if (unlikely(!curr_skb)) @@ -1231,9 +1309,11 @@ break; } while (rq->vq->num_free); if (virtqueue_kick_prepare(rq->vq) && virtqueue_notify(rq->vq)) { - u64_stats_update_begin(&rq->stats.syncp); + unsigned long flags; + + flags = u64_stats_update_begin_irqsave(&rq->stats.syncp); rq->stats.kicks++; - u64_stats_update_end(&rq->stats.syncp); + u64_stats_update_end_irqrestore(&rq->stats.syncp, flags); } return !oom; @@ -1332,8 +1412,12 @@ } if (rq->vq->num_free > min((unsigned int)budget, virtqueue_get_vring_size(rq->vq)) / 2) { - if (!try_fill_recv(vi, rq, GFP_ATOMIC)) - schedule_delayed_work(&vi->refill, 0); + if (!try_fill_recv(vi, rq, GFP_ATOMIC)) { + spin_lock(&vi->refill_lock); + if (vi->refill_enabled) + schedule_delayed_work(&vi->refill, 0); + spin_unlock(&vi->refill_lock); + } } u64_stats_update_begin(&rq->stats.syncp); @@ -1395,7 +1479,7 @@ return false; } -static void virtnet_poll_cleantx(struct receive_queue *rq) +static void virtnet_poll_cleantx(struct receive_queue *rq, int budget) { struct virtnet_info *vi = rq->vq->vdev->priv; unsigned int index = vq2rxq(rq->vq); @@ -1406,7 +1490,7 @@ return; if (__netif_tx_trylock(txq)) { - free_old_xmit_skbs(sq, true); + free_old_xmit_skbs(sq, !!budget); __netif_tx_unlock(txq); } @@ -1423,7 +1507,7 @@ unsigned int received; unsigned int xdp_xmit = 0; - virtnet_poll_cleantx(rq); + virtnet_poll_cleantx(rq, budget); received = virtnet_receive(rq, budget, &xdp_xmit); @@ -1435,12 +1519,13 @@ xdp_do_flush_map(); if (xdp_xmit & VIRTIO_XDP_TX) { - sq = virtnet_xdp_sq(vi); + sq = virtnet_xdp_get_sq(vi); if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { u64_stats_update_begin(&sq->stats.syncp); sq->stats.kicks++; u64_stats_update_end(&sq->stats.syncp); } + virtnet_xdp_put_sq(vi, sq); } return received; @@ -1451,6 +1536,8 @@ struct virtnet_info *vi = netdev_priv(dev); int i, err; + enable_delayed_refill(vi); + for (i = 0; i < vi->max_queue_pairs; i++) { if (i < vi->curr_queue_pairs) /* Make sure we have some buffers: if oom use wq. */ @@ -1481,6 +1568,8 @@ struct virtnet_info *vi = sq->vq->vdev->priv; unsigned int index = vq2txq(sq->vq); struct netdev_queue *txq; + int opaque; + bool done; if (unlikely(is_xdp_raw_buffer_queue(vi, index))) { /* We don't need to enable cb for XDP */ @@ -1490,10 +1579,28 @@ txq = netdev_get_tx_queue(vi->dev, index); __netif_tx_lock(txq, raw_smp_processor_id()); - free_old_xmit_skbs(sq, true); + virtqueue_disable_cb(sq->vq); + free_old_xmit_skbs(sq, !!budget); + + opaque = virtqueue_enable_cb_prepare(sq->vq); + + done = napi_complete_done(napi, 0); + + if (!done) + virtqueue_disable_cb(sq->vq); + __netif_tx_unlock(txq); - virtqueue_napi_complete(napi, sq->vq, 0); + if (done) { + if (unlikely(virtqueue_poll(sq->vq, opaque))) { + if (napi_schedule_prep(napi)) { + __netif_tx_lock(txq, raw_smp_processor_id()); + virtqueue_disable_cb(sq->vq); + __netif_tx_unlock(txq); + __napi_schedule(napi); + } + } + } if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) netif_tx_wake_queue(txq); @@ -1525,7 +1632,7 @@ if (virtio_net_hdr_from_skb(skb, &hdr->hdr, virtio_is_little_endian(vi->vdev), false, 0)) - BUG(); + return -EPROTO; if (vi->mergeable_rx_bufs) hdr->num_buffers = 0; @@ -1801,12 +1908,14 @@ struct virtnet_info *vi = netdev_priv(dev); int i; + /* Make sure NAPI doesn't schedule refill work */ + disable_delayed_refill(vi); /* Make sure refill_work doesn't re-enable napi! */ cancel_delayed_work_sync(&vi->refill); for (i = 0; i < vi->max_queue_pairs; i++) { - xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); napi_disable(&vi->rq[i].napi); + xdp_rxq_info_unreg(&vi->rq[i].xdp_rxq); virtnet_napi_tx_disable(&vi->sq[i].napi); } @@ -2065,14 +2174,16 @@ get_online_cpus(); err = _virtnet_set_queues(vi, queue_pairs); - if (!err) { - netif_set_real_num_tx_queues(dev, queue_pairs); - netif_set_real_num_rx_queues(dev, queue_pairs); - - virtnet_set_affinity(vi); + if (err) { + put_online_cpus(); + goto err; } + virtnet_set_affinity(vi); put_online_cpus(); + netif_set_real_num_tx_queues(dev, queue_pairs); + netif_set_real_num_rx_queues(dev, queue_pairs); + err: return err; } @@ -2314,7 +2425,6 @@ static void virtnet_freeze_down(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; - int i; /* Make sure no work handler is accessing the device */ flush_work(&vi->config_work); @@ -2322,14 +2432,8 @@ netif_tx_lock_bh(vi->dev); netif_device_detach(vi->dev); netif_tx_unlock_bh(vi->dev); - cancel_delayed_work_sync(&vi->refill); - - if (netif_running(vi->dev)) { - for (i = 0; i < vi->max_queue_pairs; i++) { - napi_disable(&vi->rq[i].napi); - virtnet_napi_tx_disable(&vi->sq[i].napi); - } - } + if (netif_running(vi->dev)) + virtnet_close(vi->dev); } static int init_vqs(struct virtnet_info *vi); @@ -2337,7 +2441,7 @@ static int virtnet_restore_up(struct virtio_device *vdev) { struct virtnet_info *vi = vdev->priv; - int err, i; + int err; err = init_vqs(vi); if (err) @@ -2345,16 +2449,12 @@ virtio_device_ready(vdev); - if (netif_running(vi->dev)) { - for (i = 0; i < vi->curr_queue_pairs; i++) - if (!try_fill_recv(vi, &vi->rq[i], GFP_KERNEL)) - schedule_delayed_work(&vi->refill, 0); + enable_delayed_refill(vi); - for (i = 0; i < vi->max_queue_pairs; i++) { - virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); - virtnet_napi_tx_enable(vi, vi->sq[i].vq, - &vi->sq[i].napi); - } + if (netif_running(vi->dev)) { + err = virtnet_open(vi->dev); + if (err) + return err; } netif_tx_lock_bh(vi->dev); @@ -2414,7 +2514,7 @@ virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { - NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); + NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first"); return -EOPNOTSUPP; } @@ -2435,10 +2535,9 @@ /* XDP requires extra queues for XDP_TX */ if (curr_qp + xdp_qp > vi->max_queue_pairs) { - NL_SET_ERR_MSG_MOD(extack, "Too few free TX rings available"); - netdev_warn(dev, "request %i queues but max is %i\n", + netdev_warn(dev, "XDP request %i queues but max is %i. XDP_TX and XDP_REDIRECT will operate in a slower locked tx mode.\n", curr_qp + xdp_qp, vi->max_queue_pairs); - return -ENOMEM; + xdp_qp = 0; } old_prog = rtnl_dereference(vi->rq[0].xdp_prog); @@ -2475,11 +2574,14 @@ vi->xdp_queue_pairs = xdp_qp; if (prog) { + vi->xdp_enabled = true; for (i = 0; i < vi->max_queue_pairs; i++) { rcu_assign_pointer(vi->rq[i].xdp_prog, prog); if (i == 0 && !old_prog) virtnet_clear_guest_offloads(vi); } + } else { + vi->xdp_enabled = false; } for (i = 0; i < vi->max_queue_pairs; i++) { @@ -2563,14 +2665,15 @@ u64 offloads; int err; - if ((dev->features ^ features) & NETIF_F_LRO) { - if (vi->xdp_queue_pairs) + if ((dev->features ^ features) & NETIF_F_GRO_HW) { + if (vi->xdp_enabled) return -EBUSY; - if (features & NETIF_F_LRO) + if (features & NETIF_F_GRO_HW) offloads = vi->guest_offloads_capable; else - offloads = 0; + offloads = vi->guest_offloads_capable & + ~GUEST_OFFLOAD_GRO_HW_MASK; err = virtnet_set_guest_offloads(vi, offloads); if (err) @@ -2689,6 +2792,27 @@ put_page(vi->rq[i].alloc_frag.page); } +static void virtnet_sq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + if (!is_xdp_frame(buf)) + dev_kfree_skb(buf); + else + xdp_return_frame(ptr_to_xdp(buf)); +} + +static void virtnet_rq_free_unused_buf(struct virtqueue *vq, void *buf) +{ + struct virtnet_info *vi = vq->vdev->priv; + int i = vq2rxq(vq); + + if (vi->mergeable_rx_bufs) + put_page(virt_to_head_page(buf)); + else if (vi->big_packets) + give_pages(&vi->rq[i], buf); + else + put_page(virt_to_head_page(buf)); +} + static void free_unused_bufs(struct virtnet_info *vi) { void *buf; @@ -2696,26 +2820,16 @@ for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->sq[i].vq; - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (!is_xdp_frame(buf)) - dev_kfree_skb(buf); - else - xdp_return_frame(ptr_to_xdp(buf)); - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_sq_free_unused_buf(vq, buf); + cond_resched(); } for (i = 0; i < vi->max_queue_pairs; i++) { struct virtqueue *vq = vi->rq[i].vq; - - while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) { - if (vi->mergeable_rx_bufs) { - put_page(virt_to_head_page(buf)); - } else if (vi->big_packets) { - give_pages(&vi->rq[i], buf); - } else { - put_page(virt_to_head_page(buf)); - } - } + while ((buf = virtqueue_detach_unused_buf(vq)) != NULL) + virtnet_rq_free_unused_buf(vq, buf); + cond_resched(); } } @@ -2750,10 +2864,11 @@ { vq_callback_t **callbacks; struct virtqueue **vqs; - int ret = -ENOMEM; - int i, total_vqs; const char **names; + int ret = -ENOMEM; + int total_vqs; bool *ctx; + u16 i; /* We expect 1 RX virtqueue followed by 1 TX virtqueue, followed by * possible N-1 RX/TX queue pairs used in multiqueue mode, followed by @@ -2790,8 +2905,8 @@ for (i = 0; i < vi->max_queue_pairs; i++) { callbacks[rxq2vq(i)] = skb_recv_done; callbacks[txq2vq(i)] = skb_xmit_done; - sprintf(vi->rq[i].name, "input.%d", i); - sprintf(vi->sq[i].name, "output.%d", i); + sprintf(vi->rq[i].name, "input.%u", i); + sprintf(vi->sq[i].name, "output.%u", i); names[rxq2vq(i)] = vi->rq[i].name; names[txq2vq(i)] = vi->sq[i].name; if (ctx) @@ -3042,13 +3157,21 @@ dev->features |= dev->hw_features & NETIF_F_ALL_TSO; /* (!csum && gso) case will be fixed by register_netdev() */ } - if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM)) - dev->features |= NETIF_F_RXCSUM; + + /* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't + * need to calculate checksums for partially checksummed packets, + * as they're considered valid by the upper layer. + * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only + * receives fully checksummed packets. The device may assist in + * validating these packets' checksums, so the driver won't have to. + */ + dev->features |= NETIF_F_RXCSUM; + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_GRO_HW; if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) - dev->hw_features |= NETIF_F_LRO; + dev->hw_features |= NETIF_F_GRO_HW; dev->vlan_features = dev->features; @@ -3071,6 +3194,7 @@ vdev->priv = vi; INIT_WORK(&vi->config_work, virtnet_config_changed_work); + spin_lock_init(&vi->refill_lock); /* If we can receive ANY GSO packets, we must allocate large ones. */ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || @@ -3106,6 +3230,7 @@ dev_err(&vdev->dev, "device MTU appears to have changed it is now %d < %d", mtu, dev->min_mtu); + err = -EINVAL; goto free; } @@ -3149,22 +3274,28 @@ } } - err = register_netdev(dev); + /* serialize netdev register + virtio_device_ready() with ndo_open() */ + rtnl_lock(); + + err = register_netdevice(dev); if (err) { pr_debug("virtio_net: registering device failed\n"); + rtnl_unlock(); goto free_failover; } virtio_device_ready(vdev); + _virtnet_set_queues(vi, vi->curr_queue_pairs); + + rtnl_unlock(); + err = virtnet_cpu_notif_add(vi); if (err) { pr_debug("virtio_net: registering cpu notifier failed\n"); goto free_unregister_netdev; } - virtnet_set_queues(vi, vi->curr_queue_pairs); - /* Assume link up if device can't report link status, otherwise get link status from config. */ netif_carrier_off(dev); @@ -3255,8 +3386,11 @@ virtnet_set_queues(vi, vi->curr_queue_pairs); err = virtnet_cpu_notif_add(vi); - if (err) + if (err) { + virtnet_freeze_down(vdev); + remove_vq_common(vi); return err; + } return 0; } --- linux-oracle-5.4.0.orig/drivers/net/vmxnet3/vmxnet3_drv.c +++ linux-oracle-5.4.0/drivers/net/vmxnet3/vmxnet3_drv.c @@ -595,6 +595,7 @@ if (dma_mapping_error(&adapter->pdev->dev, rbi->dma_addr)) { dev_kfree_skb_any(rbi->skb); + rbi->skb = NULL; rq->stats.rx_buf_alloc_failure++; break; } @@ -619,6 +620,7 @@ if (dma_mapping_error(&adapter->pdev->dev, rbi->dma_addr)) { put_page(rbi->page); + rbi->page = NULL; rq->stats.rx_buf_alloc_failure++; break; } @@ -861,7 +863,8 @@ switch (protocol) { case IPPROTO_TCP: - ctx->l4_hdr_size = tcp_hdrlen(skb); + ctx->l4_hdr_size = skb->encapsulation ? inner_tcp_hdrlen(skb) : + tcp_hdrlen(skb); break; case IPPROTO_UDP: ctx->l4_hdr_size = sizeof(struct udphdr); @@ -1583,6 +1586,10 @@ u32 i, ring_idx; struct Vmxnet3_RxDesc *rxd; + /* ring has already been cleaned up */ + if (!rq->rx_ring[0].base) + return; + for (ring_idx = 0; ring_idx < 2; ring_idx++) { for (i = 0; i < rq->rx_ring[ring_idx].size; i++) { #ifdef __BIG_ENDIAN_BITFIELD @@ -3633,7 +3640,6 @@ vmxnet3_free_intr_resources(adapter); netif_device_detach(netdev); - netif_tx_stop_all_queues(netdev); /* Create wake-up filters. */ pmConf = adapter->pm_conf; --- linux-oracle-5.4.0.orig/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ linux-oracle-5.4.0/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -702,6 +702,8 @@ *hfunc = ETH_RSS_HASH_TOP; if (!p) return 0; + if (n > UPT1_RSS_MAX_IND_TABLE_SIZE) + return 0; while (n--) p[n] = rssConf->indTable[n]; return 0; --- linux-oracle-5.4.0.orig/drivers/net/vrf.c +++ linux-oracle-5.4.0/drivers/net/vrf.c @@ -33,6 +33,7 @@ #include #include #include +#include #define DRV_NAME "vrf" #define DRV_VERSION "1.0" @@ -147,12 +148,26 @@ return NETDEV_TX_OK; } +static void vrf_nf_set_untracked(struct sk_buff *skb) +{ + if (skb_get_nfct(skb) == 0) + nf_ct_set(skb, NULL, IP_CT_UNTRACKED); +} + +static void vrf_nf_reset_ct(struct sk_buff *skb) +{ + if (skb_get_nfct(skb) == IP_CT_UNTRACKED) + nf_reset_ct(skb); +} + #if IS_ENABLED(CONFIG_IPV6) static int vrf_ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) { int err; + vrf_nf_reset_ct(skb); + err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, skb, NULL, skb_dst(skb)->dev, dst_output); @@ -188,8 +203,8 @@ fl6.flowi6_proto = iph->nexthdr; fl6.flowi6_flags = FLOWI_FLAG_SKIP_NH_OIF; - dst = ip6_route_output(net, NULL, &fl6); - if (dst == dst_null) + dst = ip6_dst_lookup_flow(net, NULL, &fl6, NULL); + if (IS_ERR(dst) || dst == dst_null) goto err; skb_dst_drop(skb); @@ -206,6 +221,7 @@ /* strip the ethernet header added for pass through VRF device */ __skb_pull(skb, skb_network_offset(skb)); + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); ret = vrf_ip6_local_out(net, skb->sk, skb); if (unlikely(net_xmit_eval(ret))) dev->stats.tx_errors++; @@ -232,6 +248,8 @@ { int err; + vrf_nf_reset_ct(skb); + err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, skb, NULL, skb_dst(skb)->dev, dst_output); if (likely(err == 1)) @@ -287,6 +305,7 @@ RT_SCOPE_LINK); } + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); ret = vrf_ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb); if (unlikely(net_xmit_eval(ret))) vrf_dev->stats.tx_errors++; @@ -332,8 +351,7 @@ return ret; } -static int vrf_finish_direct(struct net *net, struct sock *sk, - struct sk_buff *skb) +static void vrf_finish_direct(struct sk_buff *skb) { struct net_device *vrf_dev = skb->dev; @@ -352,7 +370,7 @@ skb_pull(skb, ETH_HLEN); } - return 1; + vrf_nf_reset_ct(skb); } #if IS_ENABLED(CONFIG_IPV6) @@ -366,7 +384,7 @@ struct neighbour *neigh; int ret; - nf_reset_ct(skb); + vrf_nf_reset_ct(skb); skb->protocol = htons(ETH_P_IPV6); skb->dev = dev; @@ -431,15 +449,41 @@ return skb; } +static int vrf_output6_direct_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) +{ + vrf_finish_direct(skb); + + return vrf_ip6_local_out(net, sk, skb); +} + static int vrf_output6_direct(struct net *net, struct sock *sk, struct sk_buff *skb) { + int err = 1; + skb->protocol = htons(ETH_P_IPV6); - return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, - net, sk, skb, NULL, skb->dev, - vrf_finish_direct, - !(IPCB(skb)->flags & IPSKB_REROUTED)); + if (!(IPCB(skb)->flags & IPSKB_REROUTED)) + err = nf_hook(NFPROTO_IPV6, NF_INET_POST_ROUTING, net, sk, skb, + NULL, skb->dev, vrf_output6_direct_finish); + + if (likely(err == 1)) + vrf_finish_direct(skb); + + return err; +} + +static int vrf_ip6_out_direct_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) +{ + int err; + + err = vrf_output6_direct(net, sk, skb); + if (likely(err == 1)) + err = vrf_ip6_local_out(net, sk, skb); + + return err; } static struct sk_buff *vrf_ip6_out_direct(struct net_device *vrf_dev, @@ -452,18 +496,15 @@ skb->dev = vrf_dev; err = nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, sk, - skb, NULL, vrf_dev, vrf_output6_direct); + skb, NULL, vrf_dev, vrf_ip6_out_direct_finish); if (likely(err == 1)) err = vrf_output6_direct(net, sk, skb); - /* reset skb device */ if (likely(err == 1)) - nf_reset_ct(skb); - else - skb = NULL; + return skb; - return skb; + return NULL; } static struct sk_buff *vrf_ip6_out(struct net_device *vrf_dev, @@ -474,7 +515,10 @@ if (rt6_need_strict(&ipv6_hdr(skb)->daddr)) return skb; - if (qdisc_tx_is_default(vrf_dev)) + vrf_nf_set_untracked(skb); + + if (qdisc_tx_is_default(vrf_dev) || + IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) return vrf_ip6_out_direct(vrf_dev, sk, skb); return vrf_ip6_out_redirect(vrf_dev, skb); @@ -560,7 +604,7 @@ bool is_v6gw = false; int ret = -EINVAL; - nf_reset_ct(skb); + vrf_nf_reset_ct(skb); /* Be paranoid, rather than too clever. */ if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { @@ -642,15 +686,41 @@ return skb; } +static int vrf_output_direct_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) +{ + vrf_finish_direct(skb); + + return vrf_ip_local_out(net, sk, skb); +} + static int vrf_output_direct(struct net *net, struct sock *sk, struct sk_buff *skb) { + int err = 1; + skb->protocol = htons(ETH_P_IP); - return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, - net, sk, skb, NULL, skb->dev, - vrf_finish_direct, - !(IPCB(skb)->flags & IPSKB_REROUTED)); + if (!(IPCB(skb)->flags & IPSKB_REROUTED)) + err = nf_hook(NFPROTO_IPV4, NF_INET_POST_ROUTING, net, sk, skb, + NULL, skb->dev, vrf_output_direct_finish); + + if (likely(err == 1)) + vrf_finish_direct(skb); + + return err; +} + +static int vrf_ip_out_direct_finish(struct net *net, struct sock *sk, + struct sk_buff *skb) +{ + int err; + + err = vrf_output_direct(net, sk, skb); + if (likely(err == 1)) + err = vrf_ip_local_out(net, sk, skb); + + return err; } static struct sk_buff *vrf_ip_out_direct(struct net_device *vrf_dev, @@ -663,18 +733,15 @@ skb->dev = vrf_dev; err = nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, sk, - skb, NULL, vrf_dev, vrf_output_direct); + skb, NULL, vrf_dev, vrf_ip_out_direct_finish); if (likely(err == 1)) err = vrf_output_direct(net, sk, skb); - /* reset skb device */ if (likely(err == 1)) - nf_reset_ct(skb); - else - skb = NULL; + return skb; - return skb; + return NULL; } static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev, @@ -686,7 +753,10 @@ ipv4_is_lbcast(ip_hdr(skb)->daddr)) return skb; - if (qdisc_tx_is_default(vrf_dev)) + vrf_nf_set_untracked(skb); + + if (qdisc_tx_is_default(vrf_dev) || + IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) return vrf_ip_out_direct(vrf_dev, sk, skb); return vrf_ip_out_redirect(vrf_dev, skb); @@ -860,9 +930,6 @@ dev->flags = IFF_MASTER | IFF_NOARP; - /* MTU is irrelevant for VRF device; set to 64k similar to lo */ - dev->mtu = 64 * 1024; - /* similarly, oper state is irrelevant; set to up to avoid confusion */ dev->operstate = IF_OPER_UP; return 0; @@ -992,14 +1059,20 @@ bool is_ndisc = ipv6_ndisc_frame(skb); /* loopback, multicast & non-ND link-local traffic; do not push through - * packet taps again. Reset pkt_type for upper layers to process skb + * packet taps again. Reset pkt_type for upper layers to process skb. + * For strict packets with a source LLA, determine the dst using the + * original ifindex. */ if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) { skb->dev = vrf_dev; skb->skb_iif = vrf_dev->ifindex; IP6CB(skb)->flags |= IP6SKB_L3SLAVE; + if (skb->pkt_type == PACKET_LOOPBACK) skb->pkt_type = PACKET_HOST; + else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) + vrf_ip6_input_dst(skb, vrf_dev, orig_iif); + goto out; } @@ -1289,7 +1362,8 @@ * which breaks networking. */ dev->min_mtu = IPV6_MIN_MTU; - dev->max_mtu = ETH_MAX_MTU; + dev->max_mtu = IP6_MAX_MTU; + dev->mtu = dev->max_mtu; } static int vrf_validate(struct nlattr *tb[], struct nlattr *data[], --- linux-oracle-5.4.0.orig/drivers/net/vxlan.c +++ linux-oracle-5.4.0/drivers/net/vxlan.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,167 @@ ip_tunnel_collect_metadata(); } +static struct ip_fan_map *vxlan_fan_find_map(struct vxlan_dev *vxlan, __be32 daddr) +{ + struct ip_fan_map *fan_map; + + rcu_read_lock(); + list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) { + if (fan_map->overlay == + (daddr & inet_make_mask(fan_map->overlay_prefix))) { + rcu_read_unlock(); + return fan_map; + } + } + rcu_read_unlock(); + + return NULL; +} + +static void vxlan_fan_flush_map(struct vxlan_dev *vxlan) +{ + struct ip_fan_map *fan_map; + + list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) { + list_del_rcu(&fan_map->list); + kfree_rcu(fan_map, rcu); + } +} + +static int vxlan_fan_del_map(struct vxlan_dev *vxlan, __be32 overlay) +{ + struct ip_fan_map *fan_map; + + fan_map = vxlan_fan_find_map(vxlan, overlay); + if (!fan_map) + return -ENOENT; + + list_del_rcu(&fan_map->list); + kfree_rcu(fan_map, rcu); + + return 0; +} + +static int vxlan_fan_add_map(struct vxlan_dev *vxlan, struct ifla_fan_map *map) +{ + __be32 overlay_mask, underlay_mask; + struct ip_fan_map *fan_map; + + overlay_mask = inet_make_mask(map->overlay_prefix); + underlay_mask = inet_make_mask(map->underlay_prefix); + + netdev_dbg(vxlan->dev, "vfam: map: o %x/%d u %x/%d om %x um %x\n", + map->overlay, map->overlay_prefix, + map->underlay, map->underlay_prefix, + overlay_mask, underlay_mask); + + if ((map->overlay & ~overlay_mask) || (map->underlay & ~underlay_mask)) + return -EINVAL; + + if (!(map->overlay & overlay_mask) && (map->underlay & underlay_mask)) + return -EINVAL; + + /* Special case: overlay 0 and underlay 0: flush all mappings */ + if (!map->overlay && !map->underlay) { + vxlan_fan_flush_map(vxlan); + return 0; + } + + /* Special case: overlay set and underlay 0: clear map for overlay */ + if (!map->underlay) + return vxlan_fan_del_map(vxlan, map->overlay); + + if (vxlan_fan_find_map(vxlan, map->overlay)) + return -EEXIST; + + fan_map = kmalloc(sizeof(*fan_map), GFP_KERNEL); + fan_map->underlay = map->underlay; + fan_map->overlay = map->overlay; + fan_map->underlay_prefix = map->underlay_prefix; + fan_map->overlay_mask = ntohl(overlay_mask); + fan_map->overlay_prefix = map->overlay_prefix; + + list_add_tail_rcu(&fan_map->list, &vxlan->fan.fan_maps); + + return 0; +} + +static int vxlan_parse_fan_map(struct nlattr *data[], struct vxlan_dev *vxlan) +{ + struct ifla_fan_map *map; + struct nlattr *attr; + int rem, rv; + + nla_for_each_nested(attr, data[IFLA_IPTUN_FAN_MAP], rem) { + map = nla_data(attr); + rv = vxlan_fan_add_map(vxlan, map); + if (rv) + return rv; + } + + return 0; +} + +static int vxlan_fan_build_rdst(struct vxlan_dev *vxlan, struct sk_buff *skb, + struct vxlan_rdst *fan_rdst) +{ + struct ip_fan_map *f_map; + union vxlan_addr *va; + u32 daddr, underlay; + struct arphdr *arp; + void *arp_ptr; + struct ethhdr *eth; + struct iphdr *iph; + + eth = eth_hdr(skb); + switch (eth->h_proto) { + case htons(ETH_P_IP): + iph = ip_hdr(skb); + if (!iph) + return -EINVAL; + daddr = iph->daddr; + break; + case htons(ETH_P_ARP): + arp = arp_hdr(skb); + if (!arp) + return -EINVAL; + arp_ptr = arp + 1; + netdev_dbg(vxlan->dev, + "vfbr: arp sha %pM sip %pI4 tha %pM tip %pI4\n", + arp_ptr, arp_ptr + skb->dev->addr_len, + arp_ptr + skb->dev->addr_len + 4, + arp_ptr + (skb->dev->addr_len * 2) + 4); + arp_ptr += (skb->dev->addr_len * 2) + 4; + memcpy(&daddr, arp_ptr, 4); + break; + default: + netdev_dbg(vxlan->dev, "vfbr: unknown eth p %x\n", eth->h_proto); + return -EINVAL; + } + + f_map = vxlan_fan_find_map(vxlan, daddr); + if (!f_map) + return -EINVAL; + + daddr = ntohl(daddr); + underlay = ntohl(f_map->underlay); + if (!underlay) + return -EINVAL; + + memset(fan_rdst, 0, sizeof(*fan_rdst)); + va = &fan_rdst->remote_ip; + va->sa.sa_family = AF_INET; + fan_rdst->remote_vni = vxlan->default_dst.remote_vni; + va->sin.sin_addr.s_addr = htonl(underlay | + ((daddr & ~f_map->overlay_mask) >> + (32 - f_map->overlay_prefix - + (32 - f_map->underlay_prefix)))); + netdev_dbg(vxlan->dev, "vfbr: daddr %x ul %x dst %x\n", + daddr, underlay, va->sin.sin_addr.s_addr); + + return 0; +} + #if IS_ENABLED(CONFIG_IPV6) static inline bool vxlan_addr_equal(const union vxlan_addr *a, const union vxlan_addr *b) @@ -679,11 +841,11 @@ rd = kmalloc(sizeof(*rd), GFP_ATOMIC); if (rd == NULL) - return -ENOBUFS; + return -ENOMEM; if (dst_cache_init(&rd->dst_cache, GFP_ATOMIC)) { kfree(rd); - return -ENOBUFS; + return -ENOMEM; } rd->remote_ip = *ip; @@ -698,6 +860,32 @@ return 1; } +static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol) +{ + struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr; + + /* Need to have Next Protocol set for interfaces in GPE mode. */ + if (!gpe->np_applied) + return false; + /* "The initial version is 0. If a receiver does not support the + * version indicated it MUST drop the packet. + */ + if (gpe->version != 0) + return false; + /* "When the O bit is set to 1, the packet is an OAM packet and OAM + * processing MUST occur." However, we don't implement OAM + * processing, thus drop the packet. + */ + if (gpe->oam_flag) + return false; + + *protocol = tun_p_to_eth_p(gpe->next_protocol); + if (!*protocol) + return false; + + return true; +} + static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, unsigned int off, struct vxlanhdr *vh, size_t hdrlen, @@ -1225,6 +1413,7 @@ for (h = 0; h < FDB_HASH_SIZE; ++h) { struct vxlan_fdb *f; + rcu_read_lock(); hlist_for_each_entry_rcu(f, &vxlan->fdb_head[h], hlist) { struct vxlan_rdst *rd; @@ -1237,12 +1426,15 @@ cb->nlh->nlmsg_seq, RTM_NEWNEIGH, NLM_F_MULTI, rd); - if (err < 0) + if (err < 0) { + rcu_read_unlock(); goto out; + } skip: *idx += 1; } } + rcu_read_unlock(); } out: return err; @@ -1293,6 +1485,10 @@ struct vxlan_fdb *f; u32 ifindex = 0; + /* Ignore packets from invalid src-address */ + if (!is_valid_ether_addr(src_mac)) + return true; + #if IS_ENABLED(CONFIG_IPV6) if (src_ip->sa.sa_family == AF_INET6 && (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL)) @@ -1560,35 +1756,6 @@ unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS; } -static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed, - __be16 *protocol, - struct sk_buff *skb, u32 vxflags) -{ - struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed; - - /* Need to have Next Protocol set for interfaces in GPE mode. */ - if (!gpe->np_applied) - return false; - /* "The initial version is 0. If a receiver does not support the - * version indicated it MUST drop the packet. - */ - if (gpe->version != 0) - return false; - /* "When the O bit is set to 1, the packet is an OAM packet and OAM - * processing MUST occur." However, we don't implement OAM - * processing, thus drop the packet. - */ - if (gpe->oam_flag) - return false; - - *protocol = tun_p_to_eth_p(gpe->next_protocol); - if (!*protocol) - return false; - - unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS; - return true; -} - static bool vxlan_set_mac(struct vxlan_dev *vxlan, struct vxlan_sock *vs, struct sk_buff *skb, __be32 vni) @@ -1690,8 +1857,9 @@ * used by VXLAN extensions if explicitly requested. */ if (vs->flags & VXLAN_F_GPE) { - if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags)) + if (!vxlan_parse_gpe_proto(&unparsed, &protocol)) goto drop; + unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS; raw_proto = true; } @@ -1924,6 +2092,10 @@ ns_olen = request->len - skb_network_offset(request) - sizeof(struct ipv6hdr) - sizeof(*ns); for (i = 0; i < ns_olen-1; i += (ns->opt[i+1]<<3)) { + if (!ns->opt[i + 1]) { + kfree_skb(reply); + return NULL; + } if (ns->opt[i] == ND_OPT_SOURCE_LL_ADDR) { daddr = ns->opt + i + sizeof(struct nd_opt_hdr); break; @@ -1987,6 +2159,7 @@ struct neighbour *n; struct nd_msg *msg; + rcu_read_lock(); in6_dev = __in6_dev_get(dev); if (!in6_dev) goto out; @@ -2038,6 +2211,7 @@ } out: + rcu_read_unlock(); consume_skb(skb); return NETDEV_TX_OK; } @@ -2276,7 +2450,6 @@ bool use_cache = ip_tunnel_dst_cache_usable(skb, info); struct dst_entry *ndst; struct flowi6 fl6; - int err; if (!sock6) return ERR_PTR(-EIO); @@ -2299,10 +2472,9 @@ fl6.fl6_dport = dport; fl6.fl6_sport = sport; - err = ipv6_stub->ipv6_dst_lookup(vxlan->net, - sock6->sock->sk, - &ndst, &fl6); - if (unlikely(err < 0)) { + ndst = ipv6_stub->ipv6_dst_lookup_flow(vxlan->net, sock6->sock->sk, + &fl6, NULL); + if (unlikely(IS_ERR(ndst))) { netdev_dbg(dev, "no route to %pI6\n", daddr); return ERR_PTR(-ENETUNREACH); } @@ -2519,6 +2691,13 @@ goto tx_error; } + if (fan_has_map(&vxlan->fan) && rt->rt_flags & RTCF_LOCAL) { + netdev_dbg(dev, "discard fan to localhost %pI4\n", + &dst->sin.sin_addr.s_addr); + ip_rt_put(rt); + goto tx_free; + } + if (!info) { /* Bypass encapsulation if the destination is local */ err = encap_bypass_if_local(skb, dev, vxlan, dst, @@ -2542,7 +2721,7 @@ } ndst = &rt->dst; - skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM); + skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE)); tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); @@ -2582,7 +2761,7 @@ goto out_unlock; } - skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM); + skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6)); tos = ip_tunnel_ecn_encap(tos, old_iph, skb); ttl = ttl ? : ip6_dst_hoplimit(ndst); @@ -2615,6 +2794,7 @@ dev->stats.tx_carrier_errors++; dst_release(ndst); dev->stats.tx_errors++; +tx_free: kfree_skb(skb); } @@ -2669,6 +2849,20 @@ #endif } + if (fan_has_map(&vxlan->fan)) { + struct vxlan_rdst fan_rdst; + + netdev_dbg(vxlan->dev, "vxlan_xmit p %x d %pM\n", + eth->h_proto, eth->h_dest); + if (vxlan_fan_build_rdst(vxlan, skb, &fan_rdst)) { + dev->stats.tx_dropped++; + kfree_skb(skb); + return NETDEV_TX_OK; + } + vxlan_xmit_one(skb, dev, vni, &fan_rdst, 0); + return NETDEV_TX_OK; + } + eth = eth_hdr(skb); f = vxlan_find_mac(vxlan, eth->h_dest, vni); did_rsc = false; @@ -2781,10 +2975,19 @@ /* Setup stats when device is created */ static int vxlan_init(struct net_device *dev) { + struct vxlan_dev *vxlan = netdev_priv(dev); + int err; + dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); if (!dev->tstats) return -ENOMEM; + err = gro_cells_init(&vxlan->gro_cells, dev); + if (err) { + free_percpu(dev->tstats); + return err; + } + return 0; } @@ -2852,8 +3055,10 @@ if (!do_all && (f->state & (NUD_PERMANENT | NUD_NOARP))) continue; /* the all_zeros_mac entry is deleted at vxlan_uninit */ - if (!is_zero_ether_addr(f->eth_addr)) - vxlan_fdb_destroy(vxlan, f, true, true); + if (is_zero_ether_addr(f->eth_addr) && + f->vni == vxlan->cfg.vni) + continue; + vxlan_fdb_destroy(vxlan, f, true, true); } spin_unlock_bh(&vxlan->hash_lock[h]); } @@ -2889,14 +3094,12 @@ struct vxlan_rdst *dst = &vxlan->default_dst; struct net_device *lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex); - bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6); /* This check is different than dev->max_mtu, because it looks at * the lowerdev->mtu, rather than the static dev->max_mtu */ if (lowerdev) { - int max_mtu = lowerdev->mtu - - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); + int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags); if (new_mtu > max_mtu) return -EINVAL; } @@ -3045,12 +3248,12 @@ vxlan->dev = dev; - gro_cells_init(&vxlan->gro_cells, dev); - for (h = 0; h < FDB_HASH_SIZE; ++h) { spin_lock_init(&vxlan->hash_lock[h]); INIT_HLIST_HEAD(&vxlan->fdb_head[h]); } + + INIT_LIST_HEAD(&vxlan->fan.fan_maps); } static void vxlan_ether_setup(struct net_device *dev) @@ -3139,7 +3342,7 @@ u32 id = nla_get_u32(data[IFLA_VXLAN_ID]); if (id >= VXLAN_N_VID) { - NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_ID], + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_ID], "VXLAN ID must be lower than 16777216"); return -ERANGE; } @@ -3150,7 +3353,7 @@ = nla_data(data[IFLA_VXLAN_PORT_RANGE]); if (ntohs(p->high) < ntohs(p->low)) { - NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_PORT_RANGE], + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_PORT_RANGE], "Invalid source port range"); return -EINVAL; } @@ -3160,7 +3363,7 @@ enum ifla_vxlan_df df = nla_get_u8(data[IFLA_VXLAN_DF]); if (df < 0 || df > VXLAN_DF_MAX) { - NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_DF], + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_VXLAN_DF], "Invalid DF attribute"); return -EINVAL; } @@ -3497,11 +3700,11 @@ struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_rdst *dst = &vxlan->default_dst; unsigned short needed_headroom = ETH_HLEN; - bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6); int max_mtu = ETH_MAX_MTU; + u32 flags = conf->flags; if (!changelink) { - if (conf->flags & VXLAN_F_GPE) + if (flags & VXLAN_F_GPE) vxlan_raw_setup(dev); else vxlan_ether_setup(dev); @@ -3523,9 +3726,11 @@ dev->gso_max_segs = lowerdev->gso_max_segs; needed_headroom = lowerdev->hard_header_len; + needed_headroom += lowerdev->needed_headroom; + + dev->needed_tailroom = lowerdev->needed_tailroom; - max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : - VXLAN_HEADROOM); + max_mtu = lowerdev->mtu - vxlan_headroom(flags); if (max_mtu < ETH_MIN_MTU) max_mtu = ETH_MIN_MTU; @@ -3536,10 +3741,9 @@ if (dev->mtu > max_mtu) dev->mtu = max_mtu; - if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) - needed_headroom += VXLAN6_HEADROOM; - else - needed_headroom += VXLAN_HEADROOM; + if (flags & VXLAN_F_COLLECT_METADATA) + flags |= VXLAN_F_IPV6; + needed_headroom += vxlan_headroom(flags); dev->needed_headroom = needed_headroom; memcpy(&vxlan->cfg, conf, sizeof(*conf)); @@ -3602,8 +3806,10 @@ if (dst->remote_ifindex) { remote_dev = __dev_get_by_index(net, dst->remote_ifindex); - if (!remote_dev) + if (!remote_dev) { + err = -ENODEV; goto errout; + } err = netdev_upper_dev_link(remote_dev, dev, extack); if (err) @@ -3722,6 +3928,12 @@ conf->remote_ip.sa.sa_family = AF_INET6; } + if (data[IFLA_VXLAN_FAN_MAP]) { + err = vxlan_parse_fan_map(data, vxlan); + if (err) + return err; + } + if (data[IFLA_VXLAN_LOCAL]) { if (changelink && (conf->saddr.sa.sa_family != AF_INET)) { NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL], "New local address family does not match old"); @@ -4058,6 +4270,7 @@ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_ZERO_CSUM6_RX */ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_TX */ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */ + nla_total_size(sizeof(struct ip_fan_map) * 256) + 0; } @@ -4104,6 +4317,26 @@ } } + if (fan_has_map(&vxlan->fan)) { + struct nlattr *fan_nest; + struct ip_fan_map *fan_map; + + fan_nest = nla_nest_start(skb, IFLA_VXLAN_FAN_MAP); + if (!fan_nest) + goto nla_put_failure; + list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) { + struct ifla_fan_map map; + + map.underlay = fan_map->underlay; + map.underlay_prefix = fan_map->underlay_prefix; + map.overlay = fan_map->overlay; + map.overlay_prefix = fan_map->overlay_prefix; + if (nla_put(skb, IFLA_FAN_MAPPING, sizeof(map), &map)) + goto nla_put_failure; + } + nla_nest_end(skb, fan_nest); + } + if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->cfg.ttl) || nla_put_u8(skb, IFLA_VXLAN_TTL_INHERIT, !!(vxlan->cfg.flags & VXLAN_F_TTL_INHERIT)) || @@ -4399,12 +4632,27 @@ return 0; } +#ifdef CONFIG_SYSCTL +static struct ctl_table_header *vxlan_fan_header; +static unsigned int vxlan_fan_version = 4; + +static struct ctl_table vxlan_fan_sysctls[] = { + { + .procname = "vxlan", + .data = &vxlan_fan_version, + .maxlen = sizeof(vxlan_fan_version), + .mode = 0444, + .proc_handler = proc_dointvec, + }, + {}, +}; +#endif /* CONFIG_SYSCTL */ + static void vxlan_destroy_tunnels(struct net *net, struct list_head *head) { struct vxlan_net *vn = net_generic(net, vxlan_net_id); struct vxlan_dev *vxlan, *next; struct net_device *dev, *aux; - unsigned int h; for_each_netdev_safe(net, dev, aux) if (dev->rtnl_link_ops == &vxlan_link_ops) @@ -4418,14 +4666,13 @@ unregister_netdevice_queue(vxlan->dev, head); } - for (h = 0; h < PORT_HASH_SIZE; ++h) - WARN_ON_ONCE(!hlist_empty(&vn->sock_list[h])); } static void __net_exit vxlan_exit_batch_net(struct list_head *net_list) { struct net *net; LIST_HEAD(list); + unsigned int h; rtnl_lock(); list_for_each_entry(net, net_list, exit_list) @@ -4433,6 +4680,13 @@ unregister_netdevice_many(&list); rtnl_unlock(); + + list_for_each_entry(net, net_list, exit_list) { + struct vxlan_net *vn = net_generic(net, vxlan_net_id); + + for (h = 0; h < PORT_HASH_SIZE; ++h) + WARN_ON_ONCE(!hlist_empty(&vn->sock_list[h])); + } } static struct pernet_operations vxlan_net_ops = { @@ -4464,7 +4718,20 @@ if (rc) goto out4; +#ifdef CONFIG_SYSCTL + vxlan_fan_header = register_net_sysctl(&init_net, "net/fan", + vxlan_fan_sysctls); + if (!vxlan_fan_header) { + rc = -ENOMEM; + goto sysctl_failed; + } +#endif /* CONFIG_SYSCTL */ + return 0; +#ifdef CONFIG_SYSCTL +sysctl_failed: + rtnl_link_unregister(&vxlan_link_ops); +#endif /* CONFIG_SYSCTL */ out4: unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); out3: @@ -4478,6 +4745,9 @@ static void __exit vxlan_cleanup_module(void) { +#ifdef CONFIG_SYSCTL + unregister_net_sysctl_table(vxlan_fan_header); +#endif /* CONFIG_SYSCTL */ rtnl_link_unregister(&vxlan_link_ops); unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); unregister_netdevice_notifier(&vxlan_notifier_block); --- linux-oracle-5.4.0.orig/drivers/net/wan/Kconfig +++ linux-oracle-5.4.0/drivers/net/wan/Kconfig @@ -200,7 +200,7 @@ depends on WANXL && !PREVENT_FIRMWARE_BUILD help Allows you to rebuild firmware run by the QUICC processor. - It requires as68k, ld68k and hexdump programs. + It requires m68k toolchains and hexdump programs. You should never need this option, say N. @@ -282,6 +282,7 @@ tristate "Slic Maxim ds26522 card support" depends on SPI depends on FSL_SOC || ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST + select BITREVERSE help This module initializes and configures the slic maxim card in T1 or E1 mode. --- linux-oracle-5.4.0.orig/drivers/net/wan/Makefile +++ linux-oracle-5.4.0/drivers/net/wan/Makefile @@ -40,17 +40,17 @@ ifeq ($(CONFIG_WANXL_BUILD_FIRMWARE),y) ifeq ($(ARCH),m68k) - AS68K = $(AS) - LD68K = $(LD) + M68KCC = $(CC) + M68KLD = $(LD) else - AS68K = as68k - LD68K = ld68k + M68KCC = $(CROSS_COMPILE_M68K)gcc + M68KLD = $(CROSS_COMPILE_M68K)ld endif quiet_cmd_build_wanxlfw = BLD FW $@ cmd_build_wanxlfw = \ - $(CPP) -D__ASSEMBLY__ -Wp,-MD,$(depfile) -I$(srctree)/include/uapi $< | $(AS68K) -m68360 -o $(obj)/wanxlfw.o; \ - $(LD68K) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ + $(M68KCC) -D__ASSEMBLY__ -Wp,-MD,$(depfile) -I$(srctree)/include/uapi -c -o $(obj)/wanxlfw.o $<; \ + $(M68KLD) --oformat binary -Ttext 0x1000 $(obj)/wanxlfw.o -o $(obj)/wanxlfw.bin; \ hexdump -ve '"\n" 16/1 "0x%02X,"' $(obj)/wanxlfw.bin | sed 's/0x ,//g;1s/^/static const u8 firmware[]={/;$$s/,$$/\n};\n/' >$(obj)/wanxlfw.inc; \ rm -f $(obj)/wanxlfw.bin $(obj)/wanxlfw.o --- linux-oracle-5.4.0.orig/drivers/net/wan/cosa.c +++ linux-oracle-5.4.0/drivers/net/wan/cosa.c @@ -889,6 +889,7 @@ chan->tx_status = 1; spin_unlock_irqrestore(&cosa->lock, flags); up(&chan->wsem); + kfree(kbuf); return -ERESTARTSYS; } } --- linux-oracle-5.4.0.orig/drivers/net/wan/farsync.c +++ linux-oracle-5.4.0/drivers/net/wan/farsync.c @@ -569,8 +569,8 @@ static void fst_process_tx_work_q(unsigned long work_q); static void fst_process_int_work_q(unsigned long work_q); -static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0); -static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0); +static DECLARE_TASKLET_OLD(fst_tx_task, fst_process_tx_work_q); +static DECLARE_TASKLET_OLD(fst_int_task, fst_process_int_work_q); static struct fst_card_info *fst_card_array[FST_MAX_CARDS]; static spinlock_t fst_work_q_lock; @@ -2613,6 +2613,7 @@ for (i = 0; i < card->nports; i++) { struct net_device *dev = port_to_dev(&card->ports[i]); unregister_hdlc_device(dev); + free_netdev(dev); } fst_disable_intr(card); @@ -2633,6 +2634,7 @@ card->tx_dma_handle_card); } fst_card_array[card->card_no] = NULL; + kfree(card); } static struct pci_driver fst_driver = { --- linux-oracle-5.4.0.orig/drivers/net/wan/fsl_ucc_hdlc.c +++ linux-oracle-5.4.0/drivers/net/wan/fsl_ucc_hdlc.c @@ -34,6 +34,8 @@ #define TDM_PPPOHT_SLIC_MAXIN #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) +static int uhdlc_close(struct net_device *dev); + static struct ucc_tdm_info utdm_primary_info = { .uf_info = { .tsa = 0, @@ -73,7 +75,7 @@ }, }; -static struct ucc_tdm_info utdm_info[MAX_HDLC_NUM]; +static struct ucc_tdm_info utdm_info[UCC_MAX_NUM]; static int uhdlc_init(struct ucc_hdlc_private *priv) { @@ -204,14 +206,18 @@ priv->rx_skbuff = kcalloc(priv->rx_ring_size, sizeof(*priv->rx_skbuff), GFP_KERNEL); - if (!priv->rx_skbuff) + if (!priv->rx_skbuff) { + ret = -ENOMEM; goto free_ucc_pram; + } priv->tx_skbuff = kcalloc(priv->tx_ring_size, sizeof(*priv->tx_skbuff), GFP_KERNEL); - if (!priv->tx_skbuff) + if (!priv->tx_skbuff) { + ret = -ENOMEM; goto free_rx_skbuff; + } priv->skb_curtx = 0; priv->skb_dirtytx = 0; @@ -245,6 +251,11 @@ ret = -ENOMEM; goto free_riptr; } + if (riptr != (u16)riptr || tiptr != (u16)tiptr) { + dev_err(priv->dev, "MURAM allocation out of addressable range\n"); + ret = -ENOMEM; + goto free_tiptr; + } /* Set RIPTR, TIPTR */ iowrite16be(riptr, &priv->ucc_pram->riptr); @@ -701,6 +712,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); struct ucc_hdlc_private *priv = hdlc->priv; struct ucc_tdm *utdm = priv->utdm; + int rc = 0; if (priv->hdlc_busy != 1) { if (request_irq(priv->ut_info->uf_info.irq, @@ -724,10 +736,13 @@ napi_enable(&priv->napi); netdev_reset_queue(dev); netif_start_queue(dev); - hdlc_open(dev); + + rc = hdlc_open(dev); + if (rc) + uhdlc_close(dev); } - return 0; + return rc; } static void uhdlc_memclean(struct ucc_hdlc_private *priv) @@ -817,6 +832,8 @@ netdev_reset_queue(dev); priv->hdlc_busy = 0; + hdlc_close(dev); + return 0; } @@ -1240,9 +1257,11 @@ free_dev: free_netdev(dev); undo_uhdlc_init: - iounmap(utdm->siram); + if (utdm) + iounmap(utdm->siram); unmap_si_regs: - iounmap(utdm->si_regs); + if (utdm) + iounmap(utdm->si_regs); free_utdm: if (uhdlc_priv->tsa) kfree(utdm); --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc.c @@ -46,7 +46,15 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev) { - struct hdlc_device *hdlc = dev_to_hdlc(dev); + struct hdlc_device *hdlc; + + /* First make sure "dev" is an HDLC device */ + if (!(dev->priv_flags & IFF_WAN_HDLC)) { + kfree_skb(skb); + return NET_RX_SUCCESS; + } + + hdlc = dev_to_hdlc(dev); if (!net_eq(dev_net(dev), &init_net)) { kfree_skb(skb); --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc_cisco.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc_cisco.c @@ -118,6 +118,7 @@ skb_put(skb, sizeof(struct cisco_packet)); skb->priority = TC_PRIO_CONTROL; skb->dev = dev; + skb->protocol = htons(ETH_P_HDLC); skb_reset_network_header(skb); dev_queue_xmit(skb); @@ -370,6 +371,7 @@ memcpy(&state(hdlc)->settings, &new_settings, size); spin_lock_init(&state(hdlc)->lock); dev->header_ops = &cisco_header_ops; + dev->hard_header_len = sizeof(struct hdlc_header); dev->type = ARPHRD_CISCO; call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev); netif_dormant_on(dev); --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc_fr.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc_fr.c @@ -273,63 +273,69 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci) { - u16 head_len; struct sk_buff *skb = *skb_p; - switch (skb->protocol) { - case cpu_to_be16(NLPID_CCITT_ANSI_LMI): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_CCITT_ANSI_LMI; - break; - - case cpu_to_be16(NLPID_CISCO_LMI): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_CISCO_LMI; - break; - - case cpu_to_be16(ETH_P_IP): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_IP; - break; - - case cpu_to_be16(ETH_P_IPV6): - head_len = 4; - skb_push(skb, head_len); - skb->data[3] = NLPID_IPV6; - break; - - case cpu_to_be16(ETH_P_802_3): - head_len = 10; - if (skb_headroom(skb) < head_len) { - struct sk_buff *skb2 = skb_realloc_headroom(skb, - head_len); + if (!skb->dev) { /* Control packets */ + switch (dlci) { + case LMI_CCITT_ANSI_DLCI: + skb_push(skb, 4); + skb->data[3] = NLPID_CCITT_ANSI_LMI; + break; + + case LMI_CISCO_DLCI: + skb_push(skb, 4); + skb->data[3] = NLPID_CISCO_LMI; + break; + + default: + return -EINVAL; + } + + } else if (skb->dev->type == ARPHRD_DLCI) { + switch (skb->protocol) { + case htons(ETH_P_IP): + skb_push(skb, 4); + skb->data[3] = NLPID_IP; + break; + + case htons(ETH_P_IPV6): + skb_push(skb, 4); + skb->data[3] = NLPID_IPV6; + break; + + default: + skb_push(skb, 10); + skb->data[3] = FR_PAD; + skb->data[4] = NLPID_SNAP; + /* OUI 00-00-00 indicates an Ethertype follows */ + skb->data[5] = 0x00; + skb->data[6] = 0x00; + skb->data[7] = 0x00; + /* This should be an Ethertype: */ + *(__be16 *)(skb->data + 8) = skb->protocol; + } + + } else if (skb->dev->type == ARPHRD_ETHER) { + if (skb_headroom(skb) < 10) { + struct sk_buff *skb2 = skb_realloc_headroom(skb, 10); if (!skb2) return -ENOBUFS; dev_kfree_skb(skb); skb = *skb_p = skb2; } - skb_push(skb, head_len); + skb_push(skb, 10); skb->data[3] = FR_PAD; skb->data[4] = NLPID_SNAP; - skb->data[5] = FR_PAD; + /* OUI 00-80-C2 stands for the 802.1 organization */ + skb->data[5] = 0x00; skb->data[6] = 0x80; skb->data[7] = 0xC2; + /* PID 00-07 stands for Ethernet frames without FCS */ skb->data[8] = 0x00; - skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */ - break; + skb->data[9] = 0x07; - default: - head_len = 10; - skb_push(skb, head_len); - skb->data[3] = FR_PAD; - skb->data[4] = NLPID_SNAP; - skb->data[5] = FR_PAD; - skb->data[6] = FR_PAD; - skb->data[7] = FR_PAD; - *(__be16*)(skb->data + 8) = skb->protocol; + } else { + return -EINVAL; } dlci_to_q922(skb->data, dlci); @@ -425,14 +431,16 @@ skb_put(skb, pad); memset(skb->data + len, 0, pad); } - skb->protocol = cpu_to_be16(ETH_P_802_3); } + skb->dev = dev; if (!fr_hard_header(&skb, pvc->dlci)) { dev->stats.tx_bytes += skb->len; dev->stats.tx_packets++; if (pvc->state.fecn) /* TX Congestion counter */ dev->stats.tx_compressed++; skb->dev = pvc->frad; + skb->protocol = htons(ETH_P_HDLC); + skb_reset_network_header(skb); dev_queue_xmit(skb); return NETDEV_TX_OK; } @@ -492,10 +500,8 @@ memset(skb->data, 0, len); skb_reserve(skb, 4); if (lmi == LMI_CISCO) { - skb->protocol = cpu_to_be16(NLPID_CISCO_LMI); fr_hard_header(&skb, LMI_CISCO_DLCI); } else { - skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI); fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI); } data = skb_tail_pointer(skb); @@ -555,6 +561,7 @@ skb_put(skb, i); skb->priority = TC_PRIO_CONTROL; skb->dev = dev; + skb->protocol = htons(ETH_P_HDLC); skb_reset_network_header(skb); dev_queue_xmit(skb); @@ -1041,7 +1048,7 @@ { dev->type = ARPHRD_DLCI; dev->flags = IFF_POINTOPOINT; - dev->hard_header_len = 10; + dev->hard_header_len = 0; dev->addr_len = 2; netif_keep_dst(dev); } @@ -1093,6 +1100,7 @@ dev->mtu = HDLC_MAX_MTU; dev->min_mtu = 68; dev->max_mtu = HDLC_MAX_MTU; + dev->needed_headroom = 10; dev->priv_flags |= IFF_NO_QUEUE; dev->ml_priv = pvc; --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc_ppp.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc_ppp.c @@ -251,6 +251,7 @@ skb->priority = TC_PRIO_CONTROL; skb->dev = dev; + skb->protocol = htons(ETH_P_HDLC); skb_reset_network_header(skb); skb_queue_tail(&tx_queue, skb); } @@ -383,11 +384,8 @@ } for (opt = data; len; len -= opt[1], opt += opt[1]) { - if (len < 2 || len < opt[1]) { - dev->stats.rx_errors++; - kfree(out); - return; /* bad packet, drop silently */ - } + if (len < 2 || opt[1] < 2 || len < opt[1]) + goto err_out; if (pid == PID_LCP) switch (opt[0]) { @@ -395,6 +393,8 @@ continue; /* MRU always OK and > 1500 bytes? */ case LCP_OPTION_ACCM: /* async control character map */ + if (opt[1] < sizeof(valid_accm)) + goto err_out; if (!memcmp(opt, valid_accm, sizeof(valid_accm))) continue; @@ -406,6 +406,8 @@ } break; case LCP_OPTION_MAGIC: + if (len < 6) + goto err_out; if (opt[1] != 6 || (!opt[2] && !opt[3] && !opt[4] && !opt[5])) break; /* reject invalid magic number */ @@ -424,6 +426,11 @@ ppp_cp_event(dev, pid, RCR_GOOD, CP_CONF_ACK, id, req_len, data); kfree(out); + return; + +err_out: + dev->stats.rx_errors++; + kfree(out); } static int ppp_rx(struct sk_buff *skb) @@ -562,6 +569,13 @@ unsigned long flags; spin_lock_irqsave(&ppp->lock, flags); + /* mod_timer could be called after we entered this function but + * before we got the lock. + */ + if (timer_pending(&proto->timer)) { + spin_unlock_irqrestore(&ppp->lock, flags); + return; + } switch (proto->state) { case STOPPING: case REQ_SENT: --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc_raw_eth.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc_raw_eth.c @@ -99,6 +99,7 @@ old_qlen = dev->tx_queue_len; ether_setup(dev); dev->tx_queue_len = old_qlen; + dev->priv_flags &= ~IFF_TX_SKB_SHARING; eth_hw_addr_random(dev); call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev); netif_dormant_off(dev); --- linux-oracle-5.4.0.orig/drivers/net/wan/hdlc_x25.c +++ linux-oracle-5.4.0/drivers/net/wan/hdlc_x25.c @@ -62,10 +62,13 @@ { unsigned char *ptr; - skb_push(skb, 1); - - if (skb_cow(skb, 1)) + if (skb_cow(skb, 1)) { + kfree_skb(skb); return NET_RX_DROP; + } + + skb_push(skb, 1); + skb_reset_network_header(skb); ptr = skb->data; *ptr = X25_IFACE_DATA; @@ -79,6 +82,13 @@ static void x25_data_transmit(struct net_device *dev, struct sk_buff *skb) { hdlc_device *hdlc = dev_to_hdlc(dev); + + skb_reset_network_header(skb); + skb->protocol = hdlc_type_trans(skb, dev); + + if (dev_nit_active(dev)) + dev_queue_xmit_nit(skb, dev); + hdlc->xmit(skb, dev); /* Ignore return value :-( */ } @@ -93,6 +103,7 @@ switch (skb->data[0]) { case X25_IFACE_DATA: /* Data to be transmitted */ skb_pull(skb, 1); + skb_reset_network_header(skb); if ((result = lapb_data_request(dev, skb)) != LAPB_OK) dev_kfree_skb(skb); return NETDEV_TX_OK; --- linux-oracle-5.4.0.orig/drivers/net/wan/ixp4xx_hss.c +++ linux-oracle-5.4.0/drivers/net/wan/ixp4xx_hss.c @@ -258,7 +258,7 @@ struct hss_plat_info *plat; buffer_t *rx_buff_tab[RX_DESCS], *tx_buff_tab[TX_DESCS]; struct desc *desc_tab; /* coherent */ - u32 desc_tab_phys; + dma_addr_t desc_tab_phys; unsigned int id; unsigned int clock_type, clock_rate, loopback; unsigned int initialized, carrier; @@ -858,7 +858,7 @@ dev->stats.tx_dropped++; return NETDEV_TX_OK; } - memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4); + memcpy_swab32(mem, (u32 *)((uintptr_t)skb->data & ~3), bytes / 4); dev_kfree_skb(skb); #endif --- linux-oracle-5.4.0.orig/drivers/net/wan/lapbether.c +++ linux-oracle-5.4.0/drivers/net/wan/lapbether.c @@ -51,6 +51,8 @@ struct list_head node; struct net_device *ethdev; /* link to ethernet device */ struct net_device *axdev; /* lapbeth device (lapb#) */ + bool up; + spinlock_t up_lock; /* Protects "up" */ }; static LIST_HEAD(lapbeth_devices); @@ -98,8 +100,9 @@ rcu_read_lock(); lapbeth = lapbeth_get_x25_dev(dev); if (!lapbeth) - goto drop_unlock; - if (!netif_running(lapbeth->axdev)) + goto drop_unlock_rcu; + spin_lock_bh(&lapbeth->up_lock); + if (!lapbeth->up) goto drop_unlock; len = skb->data[0] + skb->data[1] * 256; @@ -114,11 +117,14 @@ goto drop_unlock; } out: + spin_unlock_bh(&lapbeth->up_lock); rcu_read_unlock(); return 0; drop_unlock: kfree_skb(skb); goto out; +drop_unlock_rcu: + rcu_read_unlock(); drop: kfree_skb(skb); return 0; @@ -128,10 +134,12 @@ { unsigned char *ptr; - skb_push(skb, 1); - - if (skb_cow(skb, 1)) + if (skb_cow(skb, 1)) { + kfree_skb(skb); return NET_RX_DROP; + } + + skb_push(skb, 1); ptr = skb->data; *ptr = X25_IFACE_DATA; @@ -146,13 +154,17 @@ static netdev_tx_t lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) { + struct lapbethdev *lapbeth = netdev_priv(dev); int err; - /* - * Just to be *really* sure not to send anything if the interface - * is down, the ethernet device may have gone. + spin_lock_bh(&lapbeth->up_lock); + if (!lapbeth->up) + goto drop; + + /* There should be a pseudo header of 1 byte added by upper layers. + * Check to make sure it is there before reading it. */ - if (!netif_running(dev)) + if (skb->len < 1) goto drop; switch (skb->data[0]) { @@ -177,6 +189,7 @@ goto drop; } out: + spin_unlock_bh(&lapbeth->up_lock); return NETDEV_TX_OK; drop: kfree_skb(skb); @@ -190,8 +203,6 @@ struct net_device *dev; int size = skb->len; - skb->protocol = htons(ETH_P_X25); - ptr = skb_push(skb, 2); *ptr++ = size % 256; @@ -202,6 +213,10 @@ skb->dev = dev = lapbeth->ethdev; + skb->protocol = htons(ETH_P_DEC); + + skb_reset_network_header(skb); + dev_hard_header(skb, dev, ETH_P_DEC, bcast_addr, NULL, 0); dev_queue_xmit(skb); @@ -266,6 +281,7 @@ */ static int lapbeth_open(struct net_device *dev) { + struct lapbethdev *lapbeth = netdev_priv(dev); int err; if ((err = lapb_register(dev, &lapbeth_callbacks)) != LAPB_OK) { @@ -273,15 +289,21 @@ return -ENODEV; } - netif_start_queue(dev); + spin_lock_bh(&lapbeth->up_lock); + lapbeth->up = true; + spin_unlock_bh(&lapbeth->up_lock); + return 0; } static int lapbeth_close(struct net_device *dev) { + struct lapbethdev *lapbeth = netdev_priv(dev); int err; - netif_stop_queue(dev); + spin_lock_bh(&lapbeth->up_lock); + lapbeth->up = false; + spin_unlock_bh(&lapbeth->up_lock); if ((err = lapb_unregister(dev)) != LAPB_OK) pr_err("lapb_unregister error: %d\n", err); @@ -303,7 +325,7 @@ dev->netdev_ops = &lapbeth_netdev_ops; dev->needs_free_netdev = true; dev->type = ARPHRD_X25; - dev->hard_header_len = 3; + dev->hard_header_len = 0; dev->mtu = 1000; dev->addr_len = 0; } @@ -319,17 +341,33 @@ ASSERT_RTNL(); + if (dev->type != ARPHRD_ETHER) + return -EINVAL; + ndev = alloc_netdev(sizeof(*lapbeth), "lapb%d", NET_NAME_UNKNOWN, lapbeth_setup); if (!ndev) goto out; + /* When transmitting data: + * first this driver removes a pseudo header of 1 byte, + * then the lapb module prepends an LAPB header of at most 3 bytes, + * then this driver prepends a length field of 2 bytes, + * then the underlying Ethernet device prepends its own header. + */ + ndev->needed_headroom = -1 + 3 + 2 + dev->hard_header_len + + dev->needed_headroom; + ndev->needed_tailroom = dev->needed_tailroom; + lapbeth = netdev_priv(ndev); lapbeth->axdev = ndev; dev_hold(dev); lapbeth->ethdev = dev; + lapbeth->up = false; + spin_lock_init(&lapbeth->up_lock); + rc = -EIO; if (register_netdevice(ndev)) goto fail; @@ -368,7 +406,7 @@ if (dev_net(dev) != &init_net) return NOTIFY_DONE; - if (!dev_is_ethdev(dev)) + if (!dev_is_ethdev(dev) && !lapbeth_get_x25_dev(dev)) return NOTIFY_DONE; switch (event) { --- linux-oracle-5.4.0.orig/drivers/net/wan/lmc/lmc_main.c +++ linux-oracle-5.4.0/drivers/net/wan/lmc/lmc_main.c @@ -912,6 +912,8 @@ break; default: printk(KERN_WARNING "%s: LMC UNKNOWN CARD!\n", dev->name); + unregister_hdlc_device(dev); + return -EIO; break; } --- linux-oracle-5.4.0.orig/drivers/net/wan/lmc/lmc_proto.c +++ linux-oracle-5.4.0/drivers/net/wan/lmc/lmc_proto.c @@ -101,17 +101,13 @@ switch(sc->if_type){ case LMC_PPP: return hdlc_type_trans(skb, sc->lmc_device); - break; case LMC_NET: return htons(ETH_P_802_2); - break; case LMC_RAW: /* Packet type for skbuff kind of useless */ return htons(ETH_P_802_2); - break; default: printk(KERN_WARNING "%s: No protocol set for this interface, assuming 802.2 (which is wrong!!)\n", sc->name); return htons(ETH_P_802_2); - break; } lmc_trace(sc->lmc_device, "lmc_proto_tye out"); --- linux-oracle-5.4.0.orig/drivers/net/wan/sdla.c +++ linux-oracle-5.4.0/drivers/net/wan/sdla.c @@ -708,7 +708,7 @@ spin_lock_irqsave(&sdla_lock, flags); SDLA_WINDOW(dev, addr); - pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK)); + pbuf = (void *)(dev->mem_start + (addr & SDLA_ADDR_MASK)); __sdla_write(dev, pbuf->buf_addr, skb->data, skb->len); SDLA_WINDOW(dev, addr); pbuf->opp_flag = 1; --- linux-oracle-5.4.0.orig/drivers/net/wan/x25_asy.c +++ linux-oracle-5.4.0/drivers/net/wan/x25_asy.c @@ -183,7 +183,7 @@ netif_wake_queue(sl->dev); } -/* Send one completely decapsulated IP datagram to the IP layer. */ +/* Send an LAPB frame to the LAPB module to process. */ static void x25_asy_bump(struct x25_asy *sl) { @@ -195,13 +195,12 @@ count = sl->rcount; dev->stats.rx_bytes += count; - skb = dev_alloc_skb(count+1); + skb = dev_alloc_skb(count); if (skb == NULL) { netdev_warn(sl->dev, "memory squeeze, dropping packet\n"); dev->stats.rx_dropped++; return; } - skb_push(skb, 1); /* LAPB internal control */ skb_put_data(skb, sl->rbuff, count); skb->protocol = x25_type_trans(skb, sl->dev); err = lapb_data_received(skb->dev, skb); @@ -209,7 +208,6 @@ kfree_skb(skb); printk(KERN_DEBUG "x25_asy: data received err - %d\n", err); } else { - netif_rx(skb); dev->stats.rx_packets++; } } @@ -356,12 +354,21 @@ */ /* - * Called when I frame data arrives. We did the work above - throw it - * at the net layer. + * Called when I frame data arrive. We add a pseudo header for upper + * layers and pass it to upper layers. */ static int x25_asy_data_indication(struct net_device *dev, struct sk_buff *skb) { + if (skb_cow(skb, 1)) { + kfree_skb(skb); + return NET_RX_DROP; + } + skb_push(skb, 1); + skb->data[0] = X25_IFACE_DATA; + + skb->protocol = x25_type_trans(skb, dev); + return netif_rx(skb); } @@ -657,7 +664,7 @@ switch (s) { case X25_END: if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && - sl->rcount > 2) + sl->rcount >= 2) x25_asy_bump(sl); clear_bit(SLF_ESCAPE, &sl->flags); sl->rcount = 0; --- linux-oracle-5.4.0.orig/drivers/net/wan/z85230.c +++ linux-oracle-5.4.0/drivers/net/wan/z85230.c @@ -702,7 +702,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id) { struct z8530_dev *dev=dev_id; - u8 uninitialized_var(intr); + u8 intr; static volatile int locker=0; int work=0; struct z8530_irqhandler *irqs; --- linux-oracle-5.4.0.orig/drivers/net/wimax/i2400m/op-rfkill.c +++ linux-oracle-5.4.0/drivers/net/wimax/i2400m/op-rfkill.c @@ -86,7 +86,7 @@ if (cmd == NULL) goto error_alloc; cmd->hdr.type = cpu_to_le16(I2400M_MT_CMD_RF_CONTROL); - cmd->hdr.length = sizeof(cmd->sw_rf); + cmd->hdr.length = cpu_to_le16(sizeof(cmd->sw_rf)); cmd->hdr.version = cpu_to_le16(I2400M_L3L4_VERSION); cmd->sw_rf.hdr.type = cpu_to_le16(I2400M_TLV_RF_OPERATION); cmd->sw_rf.hdr.length = cpu_to_le16(sizeof(cmd->sw_rf.status)); --- linux-oracle-5.4.0.orig/drivers/net/wimax/i2400m/usb-fw.c +++ linux-oracle-5.4.0/drivers/net/wimax/i2400m/usb-fw.c @@ -354,6 +354,7 @@ usb_autopm_put_interface(i2400mu->usb_iface); d_fnend(8, dev, "(i2400m %p ack %p size %zu) = %ld\n", i2400m, ack, ack_size, (long) result); + usb_put_urb(¬if_urb); return result; error_exceeded: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/Kconfig @@ -30,12 +30,12 @@ Right now only ath9k makes use of this. config ATH_TRACEPOINTS - bool "Atheros wireless tracing" - depends on ATH_DEBUG - depends on EVENT_TRACING - ---help--- - This option enables tracepoints for atheros wireless drivers. - Currently, ath9k makes use of this facility. + bool "Atheros wireless tracing" + depends on ATH_DEBUG + depends on EVENT_TRACING + ---help--- + This option enables tracepoints for atheros wireless drivers. + Currently, ath9k makes use of this facility. config ATH_REG_DYNAMIC_USER_REG_HINTS bool "Atheros dynamic user regulatory hints" --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ar5523/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ar5523/Kconfig @@ -1,9 +1,9 @@ # SPDX-License-Identifier: ISC config AR5523 - tristate "Atheros AR5523 wireless driver support" - depends on MAC80211 && USB - select ATH_COMMON - select FW_LOADER - ---help--- - This module add support for AR5523 based USB dongles such as D-Link - DWL-G132, Netgear WPN111 and many more. + tristate "Atheros AR5523 wireless driver support" + depends on MAC80211 && USB + select ATH_COMMON + select FW_LOADER + ---help--- + This module add support for AR5523 based USB dongles such as D-Link + DWL-G132, Netgear WPN111 and many more. --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ar5523/ar5523.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ar5523/ar5523.c @@ -153,6 +153,10 @@ ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); return; } + if (!cmd->odata) { + ar5523_err(ar, "Unexpected WDCMSG_TARGET_START reply"); + return; + } memcpy(cmd->odata, hdr + 1, sizeof(u32)); cmd->olen = sizeof(u32); cmd->res = 0; @@ -237,6 +241,11 @@ } } +static void ar5523_cancel_tx_cmd(struct ar5523 *ar) +{ + usb_kill_urb(ar->tx_cmd.urb_tx); +} + static int ar5523_cmd(struct ar5523 *ar, u32 code, const void *idata, int ilen, void *odata, int olen, int flags) { @@ -255,7 +264,8 @@ if (flags & AR5523_CMD_FLAG_MAGIC) hdr->magic = cpu_to_be32(1 << 24); - memcpy(hdr + 1, idata, ilen); + if (ilen) + memcpy(hdr + 1, idata, ilen); cmd->odata = odata; cmd->olen = olen; @@ -275,6 +285,7 @@ } if (!wait_for_completion_timeout(&cmd->done, 2 * HZ)) { + ar5523_cancel_tx_cmd(ar); cmd->odata = NULL; ar5523_err(ar, "timeout waiting for command %02x reply\n", code); @@ -1579,6 +1590,20 @@ struct ar5523 *ar; int error = -ENOMEM; + static const u8 bulk_ep_addr[] = { + AR5523_CMD_TX_PIPE | USB_DIR_OUT, + AR5523_DATA_TX_PIPE | USB_DIR_OUT, + AR5523_CMD_RX_PIPE | USB_DIR_IN, + AR5523_DATA_RX_PIPE | USB_DIR_IN, + 0}; + + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr)) { + dev_err(&dev->dev, + "Could not find all expected endpoints\n"); + error = -ENODEV; + goto out; + } + /* * Load firmware if the device requires it. This will return * -ENXIO on success and we'll get called back afer the usb @@ -1769,6 +1794,8 @@ AR5523_DEVICE_UX(0x0846, 0x4300), /* Netgear / WG111U */ AR5523_DEVICE_UG(0x0846, 0x4250), /* Netgear / WG111T */ AR5523_DEVICE_UG(0x0846, 0x5f00), /* Netgear / WPN111 */ + AR5523_DEVICE_UG(0x083a, 0x4506), /* SMC / EZ Connect + SMCWUSBT-G2 */ AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / AR5523_1 */ AR5523_DEVICE_UX(0x157e, 0x3205), /* Umedia / AR5523_2 */ AR5523_DEVICE_UG(0x157e, 0x3006), /* Umedia / TEW444UBEU */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath.h @@ -197,12 +197,13 @@ bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr); void ath_hw_setbssidmask(struct ath_common *common); -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +void ath_key_delete(struct ath_common *common, u8 hw_key_idx); int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); bool ath_hw_keyreset(struct ath_common *common, u16 entry); +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/ce.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/ce.c @@ -1299,29 +1299,24 @@ struct ath10k_hw_ce_host_wm_regs *wm_regs = ar->hw_ce_regs->wm_regs; u32 ctrl_addr = ce_state->ctrl_addr; - spin_lock_bh(&ce->ce_lock); - - /* Clear the copy-complete interrupts that will be handled here. */ + /* + * Clear before handling + * + * Misc CE interrupts are not being handled, but still need + * to be cleared. + * + * NOTE: When the last copy engine interrupt is cleared the + * hardware will go to sleep. Once this happens any access to + * the CE registers can cause a hardware fault. + */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, - wm_regs->cc_mask); - - spin_unlock_bh(&ce->ce_lock); + wm_regs->cc_mask | wm_regs->wm_mask); if (ce_state->recv_cb) ce_state->recv_cb(ce_state); if (ce_state->send_cb) ce_state->send_cb(ce_state); - - spin_lock_bh(&ce->ce_lock); - - /* - * Misc CE interrupts are not being handled, but still need - * to be cleared. - */ - ath10k_ce_engine_int_status_clear(ar, ctrl_addr, wm_regs->wm_mask); - - spin_unlock_bh(&ce->ce_lock); } EXPORT_SYMBOL(ath10k_ce_per_engine_service); @@ -1372,45 +1367,55 @@ ath10k_ce_watermark_intr_disable(ar, ctrl_addr); } -int ath10k_ce_disable_interrupts(struct ath10k *ar) +void ath10k_ce_disable_interrupt(struct ath10k *ar, int ce_id) { struct ath10k_ce *ce = ath10k_ce_priv(ar); struct ath10k_ce_pipe *ce_state; u32 ctrl_addr; - int ce_id; - for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { - ce_state = &ce->ce_states[ce_id]; - if (ce_state->attr_flags & CE_ATTR_POLL) - continue; + ce_state = &ce->ce_states[ce_id]; + if (ce_state->attr_flags & CE_ATTR_POLL) + return; - ctrl_addr = ath10k_ce_base_address(ar, ce_id); + ctrl_addr = ath10k_ce_base_address(ar, ce_id); - ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); - ath10k_ce_error_intr_disable(ar, ctrl_addr); - ath10k_ce_watermark_intr_disable(ar, ctrl_addr); - } + ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); + ath10k_ce_error_intr_disable(ar, ctrl_addr); + ath10k_ce_watermark_intr_disable(ar, ctrl_addr); +} +EXPORT_SYMBOL(ath10k_ce_disable_interrupt); - return 0; +void ath10k_ce_disable_interrupts(struct ath10k *ar) +{ + int ce_id; + + for (ce_id = 0; ce_id < CE_COUNT; ce_id++) + ath10k_ce_disable_interrupt(ar, ce_id); } EXPORT_SYMBOL(ath10k_ce_disable_interrupts); -void ath10k_ce_enable_interrupts(struct ath10k *ar) +void ath10k_ce_enable_interrupt(struct ath10k *ar, int ce_id) { struct ath10k_ce *ce = ath10k_ce_priv(ar); - int ce_id; struct ath10k_ce_pipe *ce_state; + ce_state = &ce->ce_states[ce_id]; + if (ce_state->attr_flags & CE_ATTR_POLL) + return; + + ath10k_ce_per_engine_handler_adjust(ce_state); +} +EXPORT_SYMBOL(ath10k_ce_enable_interrupt); + +void ath10k_ce_enable_interrupts(struct ath10k *ar) +{ + int ce_id; + /* Enable interrupts for copy engine that * are not using polling mode. */ - for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { - ce_state = &ce->ce_states[ce_id]; - if (ce_state->attr_flags & CE_ATTR_POLL) - continue; - - ath10k_ce_per_engine_handler_adjust(ce_state); - } + for (ce_id = 0; ce_id < CE_COUNT; ce_id++) + ath10k_ce_enable_interrupt(ar, ce_id); } EXPORT_SYMBOL(ath10k_ce_enable_interrupts); @@ -1555,7 +1560,7 @@ ret = ath10k_ce_alloc_shadow_base(ar, src_ring, nentries); if (ret) { dma_free_coherent(ar->dev, - (nentries * sizeof(struct ce_desc_64) + + (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), src_ring->base_addr_owner_space_unaligned, base_addr); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/ce.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/ce.h @@ -255,10 +255,13 @@ /*==================CE Interrupt Handlers====================*/ void ath10k_ce_per_engine_service_any(struct ath10k *ar); void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); -int ath10k_ce_disable_interrupts(struct ath10k *ar); +void ath10k_ce_disable_interrupt(struct ath10k *ar, int ce_id); +void ath10k_ce_disable_interrupts(struct ath10k *ar); +void ath10k_ce_enable_interrupt(struct ath10k *ar, int ce_id); void ath10k_ce_enable_interrupts(struct ath10k *ar); void ath10k_ce_dump_registers(struct ath10k *ar, struct ath10k_fw_crash_data *crash_data); + void ath10k_ce_alloc_rri(struct ath10k *ar); void ath10k_ce_free_rri(struct ath10k *ar); @@ -369,18 +372,14 @@ (((x) & CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK) >> \ CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB) #define CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS 0x0000 -#define CE_INTERRUPT_SUMMARY (GENMASK(CE_COUNT_MAX - 1, 0)) static inline u32 ath10k_ce_interrupt_summary(struct ath10k *ar) { struct ath10k_ce *ce = ath10k_ce_priv(ar); - if (!ar->hw_params.per_ce_irq) - return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( - ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS + - CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)); - else - return CE_INTERRUPT_SUMMARY; + return CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET( + ce->bus_ops->read32((ar), CE_WRAPPER_BASE_ADDRESS + + CE_WRAPPER_INTERRUPT_SUMMARY_ADDRESS)); } /* Host software's Copy Engine configuration. */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/core.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/core.c @@ -118,7 +118,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -154,7 +153,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -217,7 +215,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -252,7 +249,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -287,7 +283,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -325,7 +320,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -366,7 +360,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -414,7 +407,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -459,7 +451,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -494,7 +485,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -531,7 +521,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -573,7 +562,6 @@ .num_wds_entries = 0x20, .target_64bit = false, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL, - .per_ce_irq = false, .shadow_reg_support = false, .rri_on_ddr = false, .hw_filter_reset_required = true, @@ -591,6 +579,9 @@ .max_spatial_stream = 4, .fw = { .dir = WCN3990_HW_1_0_FW_DIR, + .board = WCN3990_HW_1_0_BOARD_DATA_FILE, + .board_size = WCN3990_BOARD_DATA_SZ, + .board_ext_size = WCN3990_BOARD_EXT_DATA_SZ, }, .sw_decrypt_mcast_mgmt = true, .hw_ops = &wcn3990_ops, @@ -601,7 +592,6 @@ .num_wds_entries = TARGET_HL_TLV_NUM_WDS_ENTRIES, .target_64bit = true, .rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC, - .per_ce_irq = true, .shadow_reg_support = true, .rri_on_ddr = true, .hw_filter_reset_required = false, @@ -2157,7 +2147,7 @@ static int ath10k_init_hw_params(struct ath10k *ar) { - const struct ath10k_hw_params *uninitialized_var(hw_params); + const struct ath10k_hw_params *hw_params; int i; for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/core.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/core.h @@ -969,6 +969,11 @@ u32 low_5ghz_chan; u32 high_5ghz_chan; bool ani_enabled; + u32 sys_cap_info; + + /* protected by data_lock */ + bool hw_rfkill_on; + /* protected by conf_mutex */ u8 ps_state_enable; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/coredump.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/coredump.c @@ -1208,9 +1208,11 @@ dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_RAM_DATA); dump_tlv->tlv_len = cpu_to_le32(crash_data->ramdump_buf_len); - memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf, - crash_data->ramdump_buf_len); - sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len; + if (crash_data->ramdump_buf_len) { + memcpy(dump_tlv->tlv_data, crash_data->ramdump_buf, + crash_data->ramdump_buf_len); + sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len; + } } mutex_unlock(&ar->dump_mutex); @@ -1257,6 +1259,9 @@ if (test_bit(ATH10K_FW_CRASH_DUMP_RAM_DATA, &ath10k_coredump_mask)) { crash_data->ramdump_buf_len = ath10k_coredump_get_ramdump_size(ar); + if (!crash_data->ramdump_buf_len) + return 0; + crash_data->ramdump_buf = vzalloc(crash_data->ramdump_buf_len); if (!crash_data->ramdump_buf) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/debug.c @@ -1138,7 +1138,7 @@ u32 sset, u8 *data) { if (sset == ETH_SS_STATS) - memcpy(data, *ath10k_gstrings_stats, + memcpy(data, ath10k_gstrings_stats, sizeof(ath10k_gstrings_stats)); } @@ -1516,7 +1516,7 @@ *len += scnprintf(buf + *len, buf_len - *len, "No. Preamble Rate_code "); - for (i = 0; i < WMI_TPC_TX_N_CHAIN; i++) + for (i = 0; i < tpc_stats->num_tx_chain; i++) *len += scnprintf(buf + *len, buf_len - *len, "tpc_value%d ", i); @@ -2532,6 +2532,7 @@ ath10k_debug_fw_stats_reset(ar); kfree(ar->debug.tpc_stats); + kfree(ar->debug.tpc_stats_final); } int ath10k_debug_register(struct ath10k *ar) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/debugfs_sta.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/debugfs_sta.c @@ -438,7 +438,7 @@ } out: mutex_unlock(&ar->conf_mutex); - return count; + return ret ?: count; } static const struct file_operations fops_peer_debug_trigger = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/htt.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/htt.h @@ -835,6 +835,7 @@ #define ATH10K_HTT_TXRX_PEER_SECURITY_MAX 2 #define ATH10K_TXRX_NUM_EXT_TIDS 19 +#define ATH10K_TXRX_NON_QOS_TID 16 enum htt_security_flags { #define HTT_SECURITY_TYPE_MASK 0x7F @@ -2033,6 +2034,7 @@ int (*htt_h2t_aggr_cfg_msg)(struct ath10k_htt *htt, u8 max_subfrms_ampdu, u8 max_subfrms_amsdu); + void (*htt_flush_tx)(struct ath10k_htt *htt); }; static inline int ath10k_htt_send_rx_ring_cfg(struct ath10k_htt *htt) @@ -2072,6 +2074,12 @@ return htt->tx_ops->htt_tx(htt, txmode, msdu); } +static inline void ath10k_htt_flush_tx(struct ath10k_htt *htt) +{ + if (htt->tx_ops->htt_flush_tx) + htt->tx_ops->htt_flush_tx(htt); +} + static inline int ath10k_htt_alloc_txbuff(struct ath10k_htt *htt) { if (!htt->tx_ops->htt_alloc_txbuff) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/htt_rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -142,6 +142,14 @@ BUILD_BUG_ON(HTT_RX_RING_FILL_LEVEL >= HTT_RX_RING_SIZE / 2); idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr); + + if (idx < 0 || idx >= htt->rx_ring.size) { + ath10k_err(htt->ar, "rx ring index is not valid, firmware malfunctioning?\n"); + idx &= htt->rx_ring.size_mask; + ret = -ENOMEM; + goto fail; + } + while (num > 0) { skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN); if (!skb) { @@ -941,6 +949,7 @@ u8 preamble = 0; u8 group_id; u32 info1, info2, info3; + u32 stbc, nsts_su; info1 = __le32_to_cpu(rxd->ppdu_start.info1); info2 = __le32_to_cpu(rxd->ppdu_start.info2); @@ -985,11 +994,16 @@ */ bw = info2 & 3; sgi = info3 & 1; + stbc = (info2 >> 3) & 1; group_id = (info2 >> 4) & 0x3F; if (GROUP_ID_IS_SU_MIMO(group_id)) { mcs = (info3 >> 4) & 0x0F; - nss = ((info2 >> 10) & 0x07) + 1; + nsts_su = ((info2 >> 10) & 0x07); + if (stbc) + nss = (nsts_su >> 2) + 1; + else + nss = (nsts_su + 1); } else { /* Hardware doesn't decode VHT-SIG-B into Rx descriptor * so it's impossible to decode MCS. Also since @@ -1725,16 +1739,97 @@ msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); } +static u64 ath10k_htt_rx_h_get_pn(struct ath10k *ar, struct sk_buff *skb, + u16 offset, + enum htt_rx_mpdu_encrypt_type enctype) +{ + struct ieee80211_hdr *hdr; + u64 pn = 0; + u8 *ehdr; + + hdr = (struct ieee80211_hdr *)(skb->data + offset); + ehdr = skb->data + offset + ieee80211_hdrlen(hdr->frame_control); + + if (enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) { + pn = ehdr[0]; + pn |= (u64)ehdr[1] << 8; + pn |= (u64)ehdr[4] << 16; + pn |= (u64)ehdr[5] << 24; + pn |= (u64)ehdr[6] << 32; + pn |= (u64)ehdr[7] << 40; + } + return pn; +} + +static bool ath10k_htt_rx_h_frag_multicast_check(struct ath10k *ar, + struct sk_buff *skb, + u16 offset) +{ + struct ieee80211_hdr *hdr; + + hdr = (struct ieee80211_hdr *)(skb->data + offset); + return !is_multicast_ether_addr(hdr->addr1); +} + +static bool ath10k_htt_rx_h_frag_pn_check(struct ath10k *ar, + struct sk_buff *skb, + u16 peer_id, + u16 offset, + enum htt_rx_mpdu_encrypt_type enctype) +{ + struct ath10k_peer *peer; + union htt_rx_pn_t *last_pn, new_pn = {0}; + struct ieee80211_hdr *hdr; + bool more_frags; + u8 tid, frag_number; + u32 seq; + + peer = ath10k_peer_find_by_id(ar, peer_id); + if (!peer) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid peer for frag pn check\n"); + return false; + } + + hdr = (struct ieee80211_hdr *)(skb->data + offset); + if (ieee80211_is_data_qos(hdr->frame_control)) + tid = ieee80211_get_tid(hdr); + else + tid = ATH10K_TXRX_NON_QOS_TID; + + last_pn = &peer->frag_tids_last_pn[tid]; + new_pn.pn48 = ath10k_htt_rx_h_get_pn(ar, skb, offset, enctype); + more_frags = ieee80211_has_morefrags(hdr->frame_control); + frag_number = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; + seq = (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; + + if (frag_number == 0) { + last_pn->pn48 = new_pn.pn48; + peer->frag_tids_seq[tid] = seq; + } else { + if (seq != peer->frag_tids_seq[tid]) + return false; + + if (new_pn.pn48 != last_pn->pn48 + 1) + return false; + + last_pn->pn48 = new_pn.pn48; + } + + return true; +} + static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, struct sk_buff_head *amsdu, struct ieee80211_rx_status *status, bool fill_crypt_header, u8 *rx_hdr, - enum ath10k_pkt_rx_err *err) + enum ath10k_pkt_rx_err *err, + u16 peer_id, + bool frag) { struct sk_buff *first; struct sk_buff *last; - struct sk_buff *msdu; + struct sk_buff *msdu, *temp; struct htt_rx_desc *rxd; struct ieee80211_hdr *hdr; enum htt_rx_mpdu_encrypt_type enctype; @@ -1747,6 +1842,7 @@ bool is_decrypted; bool is_mgmt; u32 attention; + bool frag_pn_check = true, multicast_check = true; if (skb_queue_empty(amsdu)) return; @@ -1845,7 +1941,37 @@ } skb_queue_walk(amsdu, msdu) { + if (frag && !fill_crypt_header && is_decrypted && + enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2) + frag_pn_check = ath10k_htt_rx_h_frag_pn_check(ar, + msdu, + peer_id, + 0, + enctype); + + if (frag) + multicast_check = ath10k_htt_rx_h_frag_multicast_check(ar, + msdu, + 0); + + if (!frag_pn_check || !multicast_check) { + /* Discard the fragment with invalid PN or multicast DA + */ + temp = msdu->prev; + __skb_unlink(msdu, amsdu); + dev_kfree_skb_any(msdu); + msdu = temp; + frag_pn_check = true; + multicast_check = true; + continue; + } + ath10k_htt_rx_h_csum_offload(msdu); + + if (frag && !fill_crypt_header && + enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) + status->flag &= ~RX_FLAG_MMIC_STRIPPED; + ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, is_decrypted); @@ -1863,6 +1989,11 @@ hdr = (void *)msdu->data; hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); + + if (frag && !fill_crypt_header && + enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) + status->flag &= ~RX_FLAG_IV_STRIPPED & + ~RX_FLAG_MMIC_STRIPPED; } } @@ -1970,14 +2101,62 @@ ath10k_unchain_msdu(amsdu, unchain_cnt); } +static bool ath10k_htt_rx_validate_amsdu(struct ath10k *ar, + struct sk_buff_head *amsdu) +{ + u8 *subframe_hdr; + struct sk_buff *first; + bool is_first, is_last; + struct htt_rx_desc *rxd; + struct ieee80211_hdr *hdr; + size_t hdr_len, crypto_len; + enum htt_rx_mpdu_encrypt_type enctype; + int bytes_aligned = ar->hw_params.decap_align_bytes; + + first = skb_peek(amsdu); + + rxd = (void *)first->data - sizeof(*rxd); + hdr = (void *)rxd->rx_hdr_status; + + is_first = !!(rxd->msdu_end.common.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); + is_last = !!(rxd->msdu_end.common.info0 & + __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); + + /* Return in case of non-aggregated msdu */ + if (is_first && is_last) + return true; + + /* First msdu flag is not set for the first msdu of the list */ + if (!is_first) + return false; + + enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), + RX_MPDU_START_INFO0_ENCRYPT_TYPE); + + hdr_len = ieee80211_hdrlen(hdr->frame_control); + crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); + + subframe_hdr = (u8 *)hdr + round_up(hdr_len, bytes_aligned) + + crypto_len; + + /* Validate if the amsdu has a proper first subframe. + * There are chances a single msdu can be received as amsdu when + * the unauthenticated amsdu flag of a QoS header + * gets flipped in non-SPP AMSDU's, in such cases the first + * subframe has llc/snap header in place of a valid da. + * return false if the da matches rfc1042 pattern + */ + if (ether_addr_equal(subframe_hdr, rfc1042_header)) + return false; + + return true; +} + static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, struct sk_buff_head *amsdu, struct ieee80211_rx_status *rx_status) { - /* FIXME: It might be a good idea to do some fuzzy-testing to drop - * invalid/dangerous frames. - */ - if (!rx_status->freq) { ath10k_dbg(ar, ATH10K_DBG_HTT, "no channel configured; ignoring frame(s)!\n"); return false; @@ -1988,6 +2167,11 @@ return false; } + if (!ath10k_htt_rx_validate_amsdu(ar, amsdu)) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "invalid amsdu received\n"); + return false; + } + return true; } @@ -2050,7 +2234,8 @@ ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt); ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter); - ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err); + ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err, 0, + false); msdus_to_queue = skb_queue_len(&amsdu); ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); @@ -2183,6 +2368,11 @@ fw_desc = &rx->fw_desc; rx_desc_len = fw_desc->len; + if (fw_desc->u.bits.discard) { + ath10k_dbg(ar, ATH10K_DBG_HTT, "htt discard mpdu\n"); + goto err; + } + /* I have not yet seen any case where num_mpdu_ranges > 1. * qcacld does not seem handle that case either, so we introduce the * same limitiation here as well. @@ -2483,6 +2673,13 @@ rx_desc = (struct htt_hl_rx_desc *)(skb->data + tot_hdr_len); rx_desc_info = __le32_to_cpu(rx_desc->info); + hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); + + if (is_multicast_ether_addr(hdr->addr1)) { + /* Discard the fragment with multicast DA */ + goto err; + } + if (!MS(rx_desc_info, HTT_RX_DESC_HL_INFO_ENCRYPTED)) { spin_unlock_bh(&ar->data_lock); return ath10k_htt_rx_proc_rx_ind_hl(htt, &resp->rx_ind_hl, skb, @@ -2490,8 +2687,6 @@ HTT_RX_NON_TKIP_MIC); } - hdr = (struct ieee80211_hdr *)((u8 *)rx_desc + rx_hl->fw_desc.len); - if (ieee80211_has_retry(hdr->frame_control)) goto err; @@ -2726,7 +2921,7 @@ spin_lock_bh(&ar->data_lock); peer = ath10k_peer_find_by_id(ar, peer_id); - if (!peer) { + if (!peer || !peer->sta) { spin_unlock_bh(&ar->data_lock); rcu_read_unlock(); continue; @@ -3000,7 +3195,7 @@ ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL); ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL, - NULL); + NULL, peer_id, frag); ath10k_htt_rx_h_enqueue(ar, &amsdu, status); break; case -EAGAIN: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/htt_tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -147,6 +147,9 @@ htt->num_pending_tx--; if (htt->num_pending_tx == htt->max_num_pending_tx - 1) ath10k_mac_tx_unlock(htt->ar, ATH10K_TX_PAUSE_Q_FULL); + + if (htt->num_pending_tx == 0) + wake_up(&htt->empty_tx_wq); } int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt) @@ -529,9 +532,14 @@ htt->tx_mem_allocated = false; } -void ath10k_htt_tx_stop(struct ath10k_htt *htt) +static void ath10k_htt_flush_tx_queue(struct ath10k_htt *htt) { idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); +} + +void ath10k_htt_tx_stop(struct ath10k_htt *htt) +{ + ath10k_htt_flush_tx_queue(htt); idr_destroy(&htt->pending_tx); } @@ -1535,7 +1543,9 @@ err_unmap_msdu: dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); err_free_msdu_id: + spin_lock_bh(&htt->tx_lock); ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); err: return res; } @@ -1742,7 +1752,9 @@ err_unmap_msdu: dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); err_free_msdu_id: + spin_lock_bh(&htt->tx_lock); ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); err: return res; } @@ -1774,6 +1786,7 @@ .htt_send_frag_desc_bank_cfg = ath10k_htt_send_frag_desc_bank_cfg_32, .htt_tx = ath10k_htt_tx_hl, .htt_h2t_aggr_cfg_msg = ath10k_htt_h2t_aggr_cfg_msg_32, + .htt_flush_tx = ath10k_htt_flush_tx_queue, }; void ath10k_htt_set_tx_ops(struct ath10k_htt *htt) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/hw.c @@ -155,6 +155,9 @@ .num_target_ce_config_wlan = 7, .ce_desc_meta_data_mask = 0xFFFC, .ce_desc_meta_data_lsb = 2, + .rfkill_pin = 16, + .rfkill_cfg = 0, + .rfkill_on_level = 1, }; const struct ath10k_hw_values qca99x0_values = { @@ -1145,6 +1148,7 @@ const struct ath10k_hw_ops qca99x0_ops = { .rx_desc_get_l3_pad_bytes = ath10k_qca99x0_rx_desc_get_l3_pad_bytes, .rx_desc_get_msdu_limit_error = ath10k_qca99x0_rx_desc_msdu_limit_error, + .is_rssi_enable = ath10k_htt_tx_rssi_enable, }; const struct ath10k_hw_ops qca6174_ops = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/hw.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/hw.h @@ -132,6 +132,7 @@ /* WCN3990 1.0 definitions */ #define WCN3990_HW_1_0_DEV_VERSION ATH10K_HW_WCN3990 #define WCN3990_HW_1_0_FW_DIR ATH10K_FW_DIR "/WCN3990/hw1.0" +#define WCN3990_HW_1_0_BOARD_DATA_FILE "board.bin" #define ATH10K_FW_FILE_BASE "firmware" #define ATH10K_FW_API_MAX 6 @@ -379,6 +380,9 @@ u8 num_target_ce_config_wlan; u16 ce_desc_meta_data_mask; u8 ce_desc_meta_data_lsb; + u32 rfkill_pin; + u32 rfkill_cfg; + bool rfkill_on_level; }; extern const struct ath10k_hw_values qca988x_values; @@ -590,9 +594,6 @@ /* Target rx ring fill level */ u32 rx_ring_fill_level; - /* target supporting per ce IRQ */ - bool per_ce_irq; - /* target supporting shadow register for ce write */ bool shadow_reg_support; @@ -810,7 +811,7 @@ #define TARGET_10_4_TX_DBG_LOG_SIZE 1024 #define TARGET_10_4_NUM_WDS_ENTRIES 32 -#define TARGET_10_4_DMA_BURST_SIZE 0 +#define TARGET_10_4_DMA_BURST_SIZE 1 #define TARGET_10_4_MAC_AGGR_DELIM 0 #define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1 #define TARGET_10_4_VOW_CONFIG 0 --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/mac.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "hif.h" #include "core.h" @@ -856,11 +857,36 @@ return 0; } +static void ath10k_peer_map_cleanup(struct ath10k *ar, struct ath10k_peer *peer) +{ + int peer_id, i; + + lockdep_assert_held(&ar->conf_mutex); + + for_each_set_bit(peer_id, peer->peer_ids, + ATH10K_MAX_NUM_PEER_IDS) { + ar->peer_map[peer_id] = NULL; + } + + /* Double check that peer is properly un-referenced from + * the peer_map + */ + for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { + if (ar->peer_map[i] == peer) { + ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", + peer->addr, peer, i); + ar->peer_map[i] = NULL; + } + } + + list_del(&peer->list); + kfree(peer); + ar->num_peers--; +} + static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id) { struct ath10k_peer *peer, *tmp; - int peer_id; - int i; lockdep_assert_held(&ar->conf_mutex); @@ -872,25 +898,7 @@ ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n", peer->addr, vdev_id); - for_each_set_bit(peer_id, peer->peer_ids, - ATH10K_MAX_NUM_PEER_IDS) { - ar->peer_map[peer_id] = NULL; - } - - /* Double check that peer is properly un-referenced from - * the peer_map - */ - for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { - if (ar->peer_map[i] == peer) { - ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %pK idx %d)\n", - peer->addr, peer, i); - ar->peer_map[i] = NULL; - } - } - - list_del(&peer->list); - kfree(peer); - ar->num_peers--; + ath10k_peer_map_cleanup(ar, peer); } spin_unlock_bh(&ar->data_lock); } @@ -985,8 +993,12 @@ ath10k_mac_vif_beacon_free(arvif); if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; } } @@ -1040,7 +1052,7 @@ arg.channel.min_power = 0; arg.channel.max_power = channel->max_power * 2; arg.channel.max_reg_power = channel->max_reg_power * 2; - arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; + arg.channel.max_antenna_gain = channel->max_antenna_gain; reinit_completion(&ar->vdev_setup_done); reinit_completion(&ar->vdev_delete_done); @@ -1486,7 +1498,7 @@ arg.channel.min_power = 0; arg.channel.max_power = chandef->chan->max_power * 2; arg.channel.max_reg_power = chandef->chan->max_reg_power * 2; - arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2; + arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain; if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; @@ -3145,7 +3157,7 @@ ch->min_power = 0; ch->max_power = channel->max_power * 2; ch->max_reg_power = channel->max_reg_power * 2; - ch->max_antenna_gain = channel->max_antenna_gain * 2; + ch->max_antenna_gain = channel->max_antenna_gain; ch->reg_class_id = 0; /* FIXME */ /* FIXME: why use only legacy modes, why not any @@ -3624,23 +3636,16 @@ static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb) { struct sk_buff_head *q = &ar->wmi_mgmt_tx_queue; - int ret = 0; - spin_lock_bh(&ar->data_lock); - - if (skb_queue_len(q) == ATH10K_MAX_NUM_MGMT_PENDING) { + if (skb_queue_len_lockless(q) >= ATH10K_MAX_NUM_MGMT_PENDING) { ath10k_warn(ar, "wmi mgmt tx queue is full\n"); - ret = -ENOSPC; - goto unlock; + return -ENOSPC; } - __skb_queue_tail(q, skb); + skb_queue_tail(q, skb); ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work); -unlock: - spin_unlock_bh(&ar->data_lock); - - return ret; + return 0; } static enum ath10k_mac_tx_path @@ -3708,7 +3713,7 @@ struct ieee80211_vif *vif, enum ath10k_hw_txrx_mode txmode, enum ath10k_mac_tx_path txpath, - struct sk_buff *skb) + struct sk_buff *skb, bool noque_offchan) { struct ieee80211_hw *hw = ar->hw; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -3738,10 +3743,10 @@ } } - if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { + if (!noque_offchan && info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { if (!ath10k_mac_tx_frm_has_freq(ar)) { - ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %pK\n", - skb); + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac queued offchannel skb %pK len %d\n", + skb, skb->len); skb_queue_tail(&ar->offchan_tx_queue, skb); ieee80211_queue_work(hw, &ar->offchan_tx_work); @@ -3803,8 +3808,8 @@ mutex_lock(&ar->conf_mutex); - ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK\n", - skb); + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %pK len %d\n", + skb, skb->len); hdr = (struct ieee80211_hdr *)skb->data; peer_addr = ieee80211_get_DA(hdr); @@ -3850,7 +3855,7 @@ txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb); txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode); - ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb); + ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, true); if (ret) { ath10k_warn(ar, "failed to transmit offchannel frame: %d\n", ret); @@ -3860,8 +3865,8 @@ time_left = wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ); if (time_left == 0) - ath10k_warn(ar, "timed out waiting for offchannel skb %pK\n", - skb); + ath10k_warn(ar, "timed out waiting for offchannel skb %pK, len: %d\n", + skb, skb->len); if (!peer && tmp_peer_created) { ret = ath10k_peer_delete(ar, vdev_id, peer_addr); @@ -3903,12 +3908,17 @@ ar->running_fw->fw_file.fw_features)) { paddr = dma_map_single(ar->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (!paddr) + if (dma_mapping_error(ar->dev, paddr)) { + ieee80211_free_txskb(ar->hw, skb); continue; + } ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr); if (ret) { ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n", ret); + /* remove this msdu from idr tracking */ + ath10k_wmi_cleanup_mgmt_tx_send(ar, skb); + dma_unmap_single(ar->dev, paddr, skb->len, DMA_TO_DEVICE); ieee80211_free_txskb(ar->hw, skb); @@ -4097,7 +4107,7 @@ spin_unlock_bh(&ar->htt.tx_lock); } - ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb); + ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false); if (unlikely(ret)) { ath10k_warn(ar, "failed to push frame: %d\n", ret); @@ -4378,7 +4388,7 @@ spin_unlock_bh(&ar->htt.tx_lock); } - ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb); + ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb, false); if (ret) { ath10k_warn(ar, "failed to transmit frame: %d\n", ret); if (is_htt) { @@ -4754,6 +4764,63 @@ return 0; } +static int ath10k_mac_rfkill_config(struct ath10k *ar) +{ + u32 param; + int ret; + + if (ar->hw_values->rfkill_pin == 0) { + ath10k_warn(ar, "ath10k does not support hardware rfkill with this device\n"); + return -EOPNOTSUPP; + } + + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac rfkill_pin %d rfkill_cfg %d rfkill_on_level %d", + ar->hw_values->rfkill_pin, ar->hw_values->rfkill_cfg, + ar->hw_values->rfkill_on_level); + + param = FIELD_PREP(WMI_TLV_RFKILL_CFG_RADIO_LEVEL, + ar->hw_values->rfkill_on_level) | + FIELD_PREP(WMI_TLV_RFKILL_CFG_GPIO_PIN_NUM, + ar->hw_values->rfkill_pin) | + FIELD_PREP(WMI_TLV_RFKILL_CFG_PIN_AS_GPIO, + ar->hw_values->rfkill_cfg); + + ret = ath10k_wmi_pdev_set_param(ar, + ar->wmi.pdev_param->rfkill_config, + param); + if (ret) { + ath10k_warn(ar, + "failed to set rfkill config 0x%x: %d\n", + param, ret); + return ret; + } + return 0; +} + +int ath10k_mac_rfkill_enable_radio(struct ath10k *ar, bool enable) +{ + enum wmi_tlv_rfkill_enable_radio param; + int ret; + + if (enable) + param = WMI_TLV_RFKILL_ENABLE_RADIO_ON; + else + param = WMI_TLV_RFKILL_ENABLE_RADIO_OFF; + + ath10k_dbg(ar, ATH10K_DBG_MAC, "mac rfkill enable %d", param); + + ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rfkill_enable, + param); + if (ret) { + ath10k_warn(ar, "failed to set rfkill enable param %d: %d\n", + param, ret); + return ret; + } + + return 0; +} + static int ath10k_start(struct ieee80211_hw *hw) { struct ath10k *ar = hw->priv; @@ -4788,6 +4855,16 @@ goto err; } + spin_lock_bh(&ar->data_lock); + + if (ar->hw_rfkill_on) { + ar->hw_rfkill_on = false; + spin_unlock_bh(&ar->data_lock); + goto err; + } + + spin_unlock_bh(&ar->data_lock); + ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL); if (ret) { ath10k_err(ar, "Could not init hif: %d\n", ret); @@ -4801,6 +4878,14 @@ goto err_power_down; } + if (ar->sys_cap_info & WMI_TLV_SYS_CAP_INFO_RFKILL) { + ret = ath10k_mac_rfkill_config(ar); + if (ret && ret != -EOPNOTSUPP) { + ath10k_warn(ar, "failed to configure rfkill: %d", ret); + goto err_core_stop; + } + } + param = ar->wmi.pdev_param->pmf_qos; ret = ath10k_wmi_pdev_set_param(ar, param, 1); if (ret) { @@ -4960,7 +5045,8 @@ mutex_lock(&ar->conf_mutex); if (ar->state != ATH10K_STATE_OFF) { - ath10k_halt(ar); + if (!ar->hw_rfkill_on) + ath10k_halt(ar); ar->state = ATH10K_STATE_OFF; } mutex_unlock(&ar->conf_mutex); @@ -5253,10 +5339,25 @@ if (vif->type == NL80211_IFTYPE_ADHOC || vif->type == NL80211_IFTYPE_MESH_POINT || vif->type == NL80211_IFTYPE_AP) { - arvif->beacon_buf = dma_alloc_coherent(ar->dev, - IEEE80211_MAX_FRAME_LEN, - &arvif->beacon_paddr, - GFP_ATOMIC); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) { + arvif->beacon_buf = kmalloc(IEEE80211_MAX_FRAME_LEN, + GFP_KERNEL); + + /* Using a kernel pointer in place of a dma_addr_t + * token can lead to undefined behavior if that + * makes it into cache management functions. Use a + * known-invalid address token instead, which + * avoids the warning and makes it easier to catch + * bugs if it does end up getting used. + */ + arvif->beacon_paddr = DMA_MAPPING_ERROR; + } else { + arvif->beacon_buf = + dma_alloc_coherent(ar->dev, + IEEE80211_MAX_FRAME_LEN, + &arvif->beacon_paddr, + GFP_ATOMIC); + } if (!arvif->beacon_buf) { ret = -ENOMEM; ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", @@ -5269,6 +5370,7 @@ if (arvif->nohwcrypt && !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { + ret = -EINVAL; ath10k_warn(ar, "cryptmode module param needed for sw crypto\n"); goto err; } @@ -5470,8 +5572,12 @@ err: if (arvif->beacon_buf) { - dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, - arvif->beacon_buf, arvif->beacon_paddr); + if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) + kfree(arvif->beacon_buf); + else + dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, + arvif->beacon_buf, + arvif->beacon_paddr); arvif->beacon_buf = NULL; } @@ -6619,10 +6725,7 @@ /* Clean up the peer object as well since we * must have failed to do this above. */ - list_del(&peer->list); - ar->peer_map[i] = NULL; - kfree(peer); - ar->num_peers--; + ath10k_peer_map_cleanup(ar, peer); } } spin_unlock_bh(&ar->data_lock); @@ -7080,6 +7183,7 @@ ath10k_wmi_peer_flush(ar, arvif->vdev_id, arvif->bssid, bitmap); } + ath10k_htt_flush_tx(&ar->htt); } return; } @@ -7125,7 +7229,7 @@ struct ieee80211_channel *channel) { int ret; - enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR; + enum wmi_bss_survey_req_type type = WMI_BSS_SURVEY_REQ_TYPE_READ; lockdep_assert_held(&ar->conf_mutex); @@ -8809,7 +8913,6 @@ ar->hw->wiphy->max_scan_ie_len = WLAN_SCAN_PARAMS_MAX_IE_LEN; if (test_bit(WMI_SERVICE_NLO, ar->wmi.svc_map)) { - ar->hw->wiphy->max_sched_scan_reqs = 1; ar->hw->wiphy->max_sched_scan_ssids = WMI_PNO_MAX_SUPP_NETWORKS; ar->hw->wiphy->max_match_sets = WMI_PNO_MAX_SUPP_NETWORKS; ar->hw->wiphy->max_sched_scan_ie_len = WMI_PNO_MAX_IE_LENGTH; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/mac.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/mac.h @@ -72,6 +72,7 @@ u8 tid); int ath10k_mac_ext_resource_config(struct ath10k *ar, u32 val); void ath10k_mac_wait_tx_complete(struct ath10k *ar); +int ath10k_mac_rfkill_enable_radio(struct ath10k *ar, bool enable); static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif, struct sk_buff *skb) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/pci.c @@ -1604,11 +1604,22 @@ { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); u32 i; + int ret; + + mutex_lock(&ar->conf_mutex); + if (ar->state != ATH10K_STATE_ON) { + ath10k_warn(ar, "Skipping pci_dump_memory_reg invalid state\n"); + ret = -EIO; + goto done; + } for (i = 0; i < region->len; i += 4) *(u32 *)(buf + i) = ioread32(ar_pci->mem + region->start + i); - return region->len; + ret = region->len; +done: + mutex_unlock(&ar->conf_mutex); + return ret; } /* if an error happened returns < 0, otherwise the length */ @@ -1704,7 +1715,11 @@ count = ath10k_pci_dump_memory_sram(ar, current_region, buf); break; case ATH10K_MEM_REGION_TYPE_IOREG: - count = ath10k_pci_dump_memory_reg(ar, current_region, buf); + ret = ath10k_pci_dump_memory_reg(ar, current_region, buf); + if (ret < 0) + break; + + count = ret; break; default: ret = ath10k_pci_dump_memory_generic(ar, current_region, buf); @@ -1945,8 +1960,9 @@ ath10k_pci_irq_enable(ar); ath10k_pci_rx_post(ar); - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, - ar_pci->link_ctl); + pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC, + ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC); return 0; } @@ -2059,6 +2075,7 @@ ath10k_pci_irq_sync(ar); napi_synchronize(&ar->napi); napi_disable(&ar->napi); + cancel_work_sync(&ar_pci->dump_work); /* Most likely the device has HTT Rx ring configured. The only way to * prevent the device from accessing (and possible corrupting) host @@ -2802,8 +2819,8 @@ pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL, &ar_pci->link_ctl); - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, - ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); + pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC); /* * Bring the target up cleanly. @@ -3490,7 +3507,7 @@ struct ath10k_pci *ar_pci; enum ath10k_hw_rev hw_rev; struct ath10k_bus_params bus_params = {}; - bool pci_ps; + bool pci_ps, is_qca988x = false; int (*pci_soft_reset)(struct ath10k *ar); int (*pci_hard_reset)(struct ath10k *ar); u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); @@ -3500,6 +3517,7 @@ case QCA988X_2_0_DEVICE_ID: hw_rev = ATH10K_HW_QCA988X; pci_ps = false; + is_qca988x = true; pci_soft_reset = ath10k_pci_warm_reset; pci_hard_reset = ath10k_pci_qca988x_chip_reset; targ_cpu_to_ce_addr = ath10k_pci_qca988x_targ_cpu_to_ce_addr; @@ -3619,24 +3637,39 @@ goto err_deinit_irq; } + bus_params.dev_type = ATH10K_DEV_TYPE_LL; + bus_params.link_can_suspend = true; + /* Read CHIP_ID before reset to catch QCA9880-AR1A v1 devices that + * fall off the bus during chip_reset. These chips have the same pci + * device id as the QCA9880 BR4A or 2R4E. So that's why the check. + */ + if (is_qca988x) { + bus_params.chip_id = + ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); + if (bus_params.chip_id != 0xffffffff) { + if (!ath10k_pci_chip_is_supported(pdev->device, + bus_params.chip_id)) { + ret = -ENODEV; + goto err_unsupported; + } + } + } + ret = ath10k_pci_chip_reset(ar); if (ret) { ath10k_err(ar, "failed to reset chip: %d\n", ret); goto err_free_irq; } - bus_params.dev_type = ATH10K_DEV_TYPE_LL; - bus_params.link_can_suspend = true; bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); if (bus_params.chip_id == 0xffffffff) { - ath10k_err(ar, "failed to get chip id\n"); - goto err_free_irq; + ret = -ENODEV; + goto err_unsupported; } if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) { - ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", - pdev->device, bus_params.chip_id); - goto err_free_irq; + ret = -ENODEV; + goto err_unsupported; } ret = ath10k_core_register(ar, &bus_params); @@ -3647,6 +3680,10 @@ return 0; +err_unsupported: + ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", + pdev->device, bus_params.chip_id); + err_free_irq: ath10k_pci_free_irq(ar); ath10k_pci_rx_retry_sync(ar); @@ -3733,18 +3770,22 @@ static int __init ath10k_pci_init(void) { - int ret; + int ret1, ret2; - ret = pci_register_driver(&ath10k_pci_driver); - if (ret) + ret1 = pci_register_driver(&ath10k_pci_driver); + if (ret1) printk(KERN_ERR "failed to register ath10k pci driver: %d\n", - ret); + ret1); - ret = ath10k_ahb_init(); - if (ret) - printk(KERN_ERR "ahb init failed: %d\n", ret); + ret2 = ath10k_ahb_init(); + if (ret2) + printk(KERN_ERR "ahb init failed: %d\n", ret2); - return ret; + if (ret1 && ret2) + return ret1; + + /* registered to at least one bus */ + return 0; } module_init(ath10k_pci_init); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/qmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/qmi.c @@ -581,22 +581,29 @@ { struct wlfw_host_cap_resp_msg_v01 resp = {}; struct wlfw_host_cap_req_msg_v01 req = {}; + struct qmi_elem_info *req_ei; struct ath10k *ar = qmi->ar; + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); struct qmi_txn txn; int ret; req.daemon_support_valid = 1; req.daemon_support = 0; - ret = qmi_txn_init(&qmi->qmi_hdl, &txn, - wlfw_host_cap_resp_msg_v01_ei, &resp); + ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_host_cap_resp_msg_v01_ei, + &resp); if (ret < 0) goto out; + if (test_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags)) + req_ei = wlfw_host_cap_8bit_req_msg_v01_ei; + else + req_ei = wlfw_host_cap_req_msg_v01_ei; + ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, QMI_WLFW_HOST_CAP_REQ_V01, WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN, - wlfw_host_cap_req_msg_v01_ei, &req); + req_ei, &req); if (ret < 0) { qmi_txn_cancel(&txn); ath10k_err(ar, "failed to send host capability request: %d\n", ret); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.c @@ -1988,6 +1988,28 @@ {} }; +struct qmi_elem_info wlfw_host_cap_8bit_req_msg_v01_ei[] = { + { + .data_type = QMI_OPT_FLAG, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + daemon_support_valid), + }, + { + .data_type = QMI_UNSIGNED_1_BYTE, + .elem_len = 1, + .elem_size = sizeof(u8), + .array_type = NO_ARRAY, + .tlv_type = 0x10, + .offset = offsetof(struct wlfw_host_cap_req_msg_v01, + daemon_support), + }, + {} +}; + struct qmi_elem_info wlfw_host_cap_resp_msg_v01_ei[] = { { .data_type = QMI_STRUCT, --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/qmi_wlfw_v01.h @@ -575,6 +575,7 @@ #define WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN 189 extern struct qmi_elem_info wlfw_host_cap_req_msg_v01_ei[]; +extern struct qmi_elem_info wlfw_host_cap_8bit_req_msg_v01_ei[]; struct wlfw_host_cap_resp_msg_v01 { struct qmi_response_type_v01 resp; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/rx_desc.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/rx_desc.h @@ -1282,7 +1282,19 @@ #define FW_RX_DESC_UDP (1 << 6) struct fw_rx_desc_hl { - u8 info0; + union { + struct { + u8 discard:1, + forward:1, + any_err:1, + dup_err:1, + reserved:1, + inspect:1, + extension:2; + } bits; + u8 info0; + } u; + u8 version; u8 len; u8 flags; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/sdio.c @@ -3,6 +3,7 @@ * Copyright (c) 2004-2011 Atheros Communications Inc. * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. * Copyright (c) 2016-2017 Erik Stromdahl + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -550,6 +551,10 @@ le16_to_cpu(htc_hdr->len), ATH10K_HTC_MBOX_MAX_PAYLOAD_LENGTH); ret = -ENOMEM; + + queue_work(ar->workqueue, &ar->restart_work); + ath10k_warn(ar, "exceeds length, start recovery\n"); + goto err; } @@ -1582,23 +1587,33 @@ size_t buf_len) { int ret; + void *mem; + + mem = kzalloc(buf_len, GFP_KERNEL); + if (!mem) + return -ENOMEM; /* set window register to start read cycle */ ret = ath10k_sdio_write32(ar, MBOX_WINDOW_READ_ADDR_ADDRESS, address); if (ret) { ath10k_warn(ar, "failed to set mbox window read address: %d", ret); - return ret; + goto out; } /* read the data */ - ret = ath10k_sdio_read(ar, MBOX_WINDOW_DATA_ADDRESS, buf, buf_len); + ret = ath10k_sdio_read(ar, MBOX_WINDOW_DATA_ADDRESS, mem, buf_len); if (ret) { ath10k_warn(ar, "failed to read from mbox window data address: %d\n", ret); - return ret; + goto out; } - return 0; + memcpy(buf, mem, buf_len); + +out: + kfree(mem); + + return ret; } static int ath10k_sdio_hif_diag_read32(struct ath10k *ar, u32 address, @@ -2109,10 +2124,11 @@ func->num, func->vendor, func->device); ath10k_core_unregister(ar); - ath10k_core_destroy(ar); flush_workqueue(ar_sdio->workqueue); destroy_workqueue(ar_sdio->workqueue); + + ath10k_core_destroy(ar); } static const struct sdio_device_id ath10k_sdio_devices[] = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/snoc.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/snoc.c @@ -3,6 +3,7 @@ * Copyright (c) 2018 The Linux Foundation. All rights reserved. */ +#include #include #include #include @@ -821,12 +822,20 @@ static inline void ath10k_snoc_irq_disable(struct ath10k *ar) { - ath10k_ce_disable_interrupts(ar); + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + int id; + + for (id = 0; id < CE_COUNT_MAX; id++) + disable_irq(ar_snoc->ce_irqs[id].irq_line); } static inline void ath10k_snoc_irq_enable(struct ath10k *ar) { - ath10k_ce_enable_interrupts(ar); + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + int id; + + for (id = 0; id < CE_COUNT_MAX; id++) + enable_irq(ar_snoc->ce_irqs[id].irq_line); } static void ath10k_snoc_rx_pipe_cleanup(struct ath10k_snoc_pipe *snoc_pipe) @@ -919,6 +928,7 @@ { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + bitmap_clear(ar_snoc->pending_ce_irqs, 0, CE_COUNT_MAX); napi_enable(&ar->napi); ath10k_snoc_irq_enable(ar); ath10k_snoc_rx_post(ar); @@ -1039,12 +1049,15 @@ ret = ath10k_snoc_init_pipes(ar); if (ret) { ath10k_err(ar, "failed to initialize CE: %d\n", ret); - goto err_wlan_enable; + goto err_free_rri; } + ath10k_ce_enable_interrupts(ar); + return 0; -err_wlan_enable: +err_free_rri: + ath10k_ce_free_rri(ar); ath10k_snoc_wlan_disable(ar); return ret; @@ -1155,7 +1168,9 @@ return IRQ_HANDLED; } - ath10k_snoc_irq_disable(ar); + ath10k_ce_disable_interrupt(ar, ce_id); + set_bit(ce_id, ar_snoc->pending_ce_irqs); + napi_schedule(&ar->napi); return IRQ_HANDLED; @@ -1164,20 +1179,25 @@ static int ath10k_snoc_napi_poll(struct napi_struct *ctx, int budget) { struct ath10k *ar = container_of(ctx, struct ath10k, napi); + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); int done = 0; + int ce_id; if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) { napi_complete(ctx); return done; } - ath10k_ce_per_engine_service_any(ar); + for (ce_id = 0; ce_id < CE_COUNT; ce_id++) + if (test_and_clear_bit(ce_id, ar_snoc->pending_ce_irqs)) { + ath10k_ce_per_engine_service(ar, ce_id); + ath10k_ce_enable_interrupt(ar, ce_id); + } + done = ath10k_htt_txrx_compl_task(ar, budget); - if (done < budget) { + if (done < budget) napi_complete(ctx); - ath10k_snoc_irq_enable(ar); - } return done; } @@ -1191,13 +1211,12 @@ static int ath10k_snoc_request_irq(struct ath10k *ar) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); - int irqflags = IRQF_TRIGGER_RISING; int ret, id; for (id = 0; id < CE_COUNT_MAX; id++) { ret = request_irq(ar_snoc->ce_irqs[id].irq_line, ath10k_snoc_per_engine_handler, - irqflags, ce_name[id], ar); + IRQF_NO_AUTOEN, ce_name[id], ar); if (ret) { ath10k_err(ar, "failed to register IRQ handler for CE %d: %d", @@ -1261,6 +1280,15 @@ return ret; } +static void ath10k_snoc_quirks_init(struct ath10k *ar) +{ + struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + struct device *dev = &ar_snoc->dev->dev; + + if (of_property_read_bool(dev->of_node, "qcom,snoc-host-cap-8bit-quirk")) + set_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags); +} + int ath10k_snoc_fw_indication(struct ath10k *ar, u64 type) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); @@ -1678,6 +1706,8 @@ ar->ce_priv = &ar_snoc->ce; msa_size = drv_data->msa_size; + ath10k_snoc_quirks_init(ar); + ret = ath10k_snoc_resource_init(ar); if (ret) { ath10k_warn(ar, "failed to initialize resource: %d\n", ret); @@ -1718,13 +1748,16 @@ ret = ath10k_qmi_init(ar, msa_size); if (ret) { ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret); - goto err_core_destroy; + goto err_power_off; } ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc probe\n"); return 0; +err_power_off: + ath10k_hw_power_off(ar); + err_free_irq: ath10k_snoc_free_irq(ar); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/snoc.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/snoc.h @@ -63,6 +63,7 @@ ATH10K_SNOC_FLAG_REGISTERED, ATH10K_SNOC_FLAG_UNREGISTERING, ATH10K_SNOC_FLAG_RECOVERY, + ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, }; struct ath10k_snoc { @@ -80,6 +81,7 @@ struct ath10k_clk_info *clk; struct ath10k_qmi *qmi; unsigned long flags; + DECLARE_BITMAP(pending_ce_irqs, CE_COUNT_MAX); }; static inline struct ath10k_snoc *ath10k_snoc_priv(struct ath10k *ar) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/targaddrs.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/targaddrs.h @@ -480,4 +480,7 @@ #define QCA4019_BOARD_DATA_SZ 12064 #define QCA4019_BOARD_EXT_DATA_SZ 0 +#define WCN3990_BOARD_DATA_SZ 26328 +#define WCN3990_BOARD_EXT_DATA_SZ 0 + #endif /* __TARGADDRS_H__ */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/txrx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/txrx.c @@ -80,13 +80,13 @@ ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); ath10k_htt_tx_dec_pending(htt); - if (htt->num_pending_tx == 0) - wake_up(&htt->empty_tx_wq); spin_unlock_bh(&htt->tx_lock); + rcu_read_lock(); if (txq && txq->sta && skb_cb->airtime_est) ieee80211_sta_register_airtime(txq->sta, txq->tid, skb_cb->airtime_est, 0); + rcu_read_unlock(); if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); @@ -95,6 +95,8 @@ info = IEEE80211_SKB_CB(msdu); memset(&info->status, 0, sizeof(info->status)); + info->status.rates[0].idx = -1; + trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/usb.c @@ -38,6 +38,10 @@ struct ath10k_urb_context *urb_context = NULL; unsigned long flags; + /* bail if this pipe is not initialized */ + if (!pipe->ar_usb) + return NULL; + spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags); if (!list_empty(&pipe->urb_list_head)) { urb_context = list_first_entry(&pipe->urb_list_head, @@ -55,6 +59,10 @@ { unsigned long flags; + /* bail if this pipe is not initialized */ + if (!pipe->ar_usb) + return; + spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags); pipe->urb_cnt++; @@ -435,6 +443,7 @@ ath10k_dbg(ar, ATH10K_DBG_USB_BULK, "usb bulk transmit failed: %d\n", ret); usb_unanchor_urb(urb); + usb_free_urb(urb); ret = -EINVAL; goto err_free_urb_to_pipe; } @@ -516,7 +525,7 @@ req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000); if (ret < 0) { ath10k_warn(ar, "Failed to read usb control message: %d\n", @@ -856,6 +865,11 @@ le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0; pipe_num = @@ -1000,6 +1014,8 @@ ar_usb = ath10k_usb_priv(ar); ret = ath10k_usb_create(ar, interface); + if (ret) + goto err; ar_usb->ar = ar; ar->dev_id = product_id; @@ -1012,7 +1028,7 @@ ret = ath10k_core_register(ar, &bus_params); if (ret) { ath10k_warn(ar, "failed to register driver core: %d\n", ret); - goto err; + goto err_usb_destroy; } /* TODO: remove this once USB support is fully implemented */ @@ -1020,6 +1036,9 @@ return 0; +err_usb_destroy: + ath10k_usb_destroy(ar); + err: ath10k_core_destroy(ar); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wmi-ops.h @@ -133,6 +133,7 @@ struct sk_buff *(*gen_mgmt_tx_send)(struct ath10k *ar, struct sk_buff *skb, dma_addr_t paddr); + int (*cleanup_mgmt_tx_send)(struct ath10k *ar, struct sk_buff *msdu); struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable, u32 log_level); struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); @@ -442,6 +443,15 @@ } static inline int +ath10k_wmi_cleanup_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu) +{ + if (!ar->wmi.ops->cleanup_mgmt_tx_send) + return -EOPNOTSUPP; + + return ar->wmi.ops->cleanup_mgmt_tx_send(ar, msdu); +} + +static inline int ath10k_wmi_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu, dma_addr_t paddr) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -409,6 +409,49 @@ return 0; } +static void ath10k_wmi_tlv_event_rfkill_state_change(struct ath10k *ar, + struct sk_buff *skb) +{ + const struct wmi_tlv_rfkill_state_change_ev *ev; + const void **tb; + bool radio; + int ret; + + tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); + if (IS_ERR(tb)) { + ret = PTR_ERR(tb); + ath10k_warn(ar, + "failed to parse rfkill state change event: %d\n", + ret); + return; + } + + ev = tb[WMI_TLV_TAG_STRUCT_RFKILL_EVENT]; + if (!ev) { + kfree(tb); + return; + } + + ath10k_dbg(ar, ATH10K_DBG_MAC, + "wmi tlv rfkill state change gpio %d type %d radio_state %d\n", + __le32_to_cpu(ev->gpio_pin_num), + __le32_to_cpu(ev->int_type), + __le32_to_cpu(ev->radio_state)); + + radio = (__le32_to_cpu(ev->radio_state) == WMI_TLV_RFKILL_RADIO_STATE_ON); + + spin_lock_bh(&ar->data_lock); + + if (!radio) + ar->hw_rfkill_on = true; + + spin_unlock_bh(&ar->data_lock); + + /* notify cfg80211 radio state change */ + ath10k_mac_rfkill_enable_radio(ar, radio); + wiphy_rfkill_set_hw_state(ar->hw->wiphy, !radio); +} + static int ath10k_wmi_tlv_event_temperature(struct ath10k *ar, struct sk_buff *skb) { @@ -445,13 +488,13 @@ case WMI_TDLS_TEARDOWN_REASON_TX: case WMI_TDLS_TEARDOWN_REASON_RSSI: case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT: + rcu_read_lock(); station = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); if (!station) { ath10k_warn(ar, "did not find station from tdls peer event"); - kfree(tb); - return; + goto exit; } arvif = ath10k_get_arvif(ar, __le32_to_cpu(ev->vdev_id)); ieee80211_tdls_oper_request( @@ -461,7 +504,13 @@ GFP_ATOMIC ); break; + default: + kfree(tb); + return; } + +exit: + rcu_read_unlock(); kfree(tb); } @@ -629,6 +678,9 @@ case WMI_TLV_TX_PAUSE_EVENTID: ath10k_wmi_tlv_event_tx_pause(ar, skb); break; + case WMI_TLV_RFKILL_STATE_CHANGE_EVENTID: + ath10k_wmi_tlv_event_rfkill_state_change(ar, skb); + break; case WMI_TLV_PDEV_TEMPERATURE_EVENTID: ath10k_wmi_tlv_event_temperature(ar, skb); break; @@ -701,6 +753,10 @@ } ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT]; + if (!ev) { + kfree(tb); + return -EPROTO; + } arg->desc_id = ev->desc_id; arg->status = ev->status; @@ -1212,6 +1268,7 @@ arg->num_mem_reqs = ev->num_mem_reqs; arg->service_map = svc_bmap; arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap); + arg->sys_cap_info = ev->sys_cap_info; ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs), ath10k_wmi_tlv_parse_mem_reqs, arg); @@ -1260,13 +1317,15 @@ switch (tag) { case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT: + arg->service_map_ext_valid = true; arg->service_map_ext_len = *(__le32 *)ptr; arg->service_map_ext = ptr + sizeof(__le32); return 0; default: break; } - return -EPROTO; + + return 0; } static int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar, @@ -2838,6 +2897,23 @@ } static int +ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, + struct sk_buff *msdu) +{ + struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); + struct ath10k_mgmt_tx_pkt_addr *pkt_addr; + struct ath10k_wmi *wmi = &ar->wmi; + + spin_lock_bh(&ar->data_lock); + pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); + spin_unlock_bh(&ar->data_lock); + + kfree(pkt_addr); + + return 0; +} + +static int ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb, dma_addr_t paddr) { @@ -2911,6 +2987,8 @@ if (desc_id < 0) goto err_free_skb; + cb->msdu_id = desc_id; + ptr = (void *)skb->data; tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_MGMT_TX_CMD); @@ -3650,6 +3728,7 @@ struct wmi_tlv *tlv; struct sk_buff *skb; __le32 *channel_list; + u16 tlv_len; size_t len; void *ptr; u32 i; @@ -3707,10 +3786,12 @@ /* nlo_configured_parameters(nlo_list) */ cmd->no_of_ssids = __cpu_to_le32(min_t(u8, pno->uc_networks_count, WMI_NLO_MAX_SSIDS)); + tlv_len = __le32_to_cpu(cmd->no_of_ssids) * + sizeof(struct nlo_configured_parameters); tlv = ptr; tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); - tlv->len = __cpu_to_le16(len); + tlv->len = __cpu_to_le16(tlv_len); ptr += sizeof(*tlv); nlo_list = ptr; @@ -4204,6 +4285,8 @@ .wapi_mbssid_offset = WMI_PDEV_PARAM_UNSUPPORTED, .arp_srcaddr = WMI_PDEV_PARAM_UNSUPPORTED, .arp_dstaddr = WMI_PDEV_PARAM_UNSUPPORTED, + .rfkill_config = WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG, + .rfkill_enable = WMI_TLV_PDEV_PARAM_RFKILL_ENABLE, }; static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { @@ -4336,6 +4419,7 @@ .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, /* .gen_mgmt_tx = not implemented; HTT is used */ .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send, + .cleanup_mgmt_tx_send = ath10k_wmi_tlv_op_cleanup_mgmt_tx_send, .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wmi-tlv.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wmi-tlv.h @@ -7,6 +7,8 @@ #ifndef _WMI_TLV_H #define _WMI_TLV_H +#include + #define WMI_TLV_CMD(grp_id) (((grp_id) << 12) | 0x1) #define WMI_TLV_EV(grp_id) (((grp_id) << 12) | 0x1) #define WMI_TLV_CMD_UNSUPPORTED 0 @@ -2235,6 +2237,31 @@ __le32 vdev_id; } __packed; +enum wmi_tlv_sys_cap_info_flags { + WMI_TLV_SYS_CAP_INFO_RXTX_LED = BIT(0), + WMI_TLV_SYS_CAP_INFO_RFKILL = BIT(1), +}; + +#define WMI_TLV_RFKILL_CFG_GPIO_PIN_NUM GENMASK(5, 0) +#define WMI_TLV_RFKILL_CFG_RADIO_LEVEL BIT(6) +#define WMI_TLV_RFKILL_CFG_PIN_AS_GPIO GENMASK(10, 7) + +enum wmi_tlv_rfkill_enable_radio { + WMI_TLV_RFKILL_ENABLE_RADIO_ON = 0, + WMI_TLV_RFKILL_ENABLE_RADIO_OFF = 1, +}; + +enum wmi_tlv_rfkill_radio_state { + WMI_TLV_RFKILL_RADIO_STATE_OFF = 1, + WMI_TLV_RFKILL_RADIO_STATE_ON = 2, +}; + +struct wmi_tlv_rfkill_state_change_ev { + __le32 gpio_pin_num; + __le32 int_type; + __le32 radio_state; +}; + void ath10k_wmi_tlv_attach(struct ath10k *ar); enum wmi_nlo_auth_algorithm { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wmi.c @@ -1720,12 +1720,32 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { - unsigned long time_left; + unsigned long time_left, i; time_left = wait_for_completion_timeout(&ar->wmi.service_ready, WMI_SERVICE_READY_TIMEOUT_HZ); - if (!time_left) - return -ETIMEDOUT; + if (!time_left) { + /* Sometimes the PCI HIF doesn't receive interrupt + * for the service ready message even if the buffer + * was completed. PCIe sniffer shows that it's + * because the corresponding CE ring doesn't fires + * it. Workaround here by polling CE rings once. + */ + ath10k_warn(ar, "failed to receive service ready completion, polling..\n"); + + for (i = 0; i < CE_COUNT; i++) + ath10k_hif_send_complete_check(ar, i, 1); + + time_left = wait_for_completion_timeout(&ar->wmi.service_ready, + WMI_SERVICE_READY_TIMEOUT_HZ); + if (!time_left) { + ath10k_warn(ar, "polling timed out\n"); + return -ETIMEDOUT; + } + + ath10k_warn(ar, "service ready completion received, continuing normally\n"); + } + return 0; } @@ -2365,6 +2385,7 @@ dma_unmap_single(ar->dev, pkt_addr->paddr, msdu->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(msdu); + kfree(pkt_addr); if (param->status) { info->flags &= ~IEEE80211_TX_STAT_ACK; @@ -2541,6 +2562,10 @@ if (ieee80211_is_beacon(hdr->frame_control)) ath10k_mac_handle_beacon(ar, skb); + if (ieee80211_is_beacon(hdr->frame_control) || + ieee80211_is_probe_resp(hdr->frame_control)) + status->boottime_ns = ktime_get_boottime_ns(); + ath10k_dbg(ar, ATH10K_DBG_MGMT, "event mgmt rx skb %pK len %d ftype %02x stype %02x\n", skb, skb->len, @@ -4668,16 +4693,13 @@ } pream_idx = 0; - for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) { + for (i = 0; i < tpc_stats->rate_max; i++) { memset(tpc_value, 0, sizeof(tpc_value)); memset(buff, 0, sizeof(buff)); if (i == pream_table[pream_idx]) pream_idx++; - for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) { - if (j >= __le32_to_cpu(ev->num_tx_chain)) - break; - + for (j = 0; j < tpc_stats->num_tx_chain; j++) { tpc[j] = ath10k_tpc_config_get_rate(ar, ev, i, j + 1, rate_code[i], type); @@ -4790,7 +4812,7 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) { - u32 num_tx_chain; + u32 num_tx_chain, rate_max; u8 rate_code[WMI_TPC_RATE_MAX]; u16 pream_table[WMI_TPC_PREAM_TABLE_MAX]; struct wmi_pdev_tpc_config_event *ev; @@ -4806,6 +4828,13 @@ return; } + rate_max = __le32_to_cpu(ev->rate_max); + if (rate_max > WMI_TPC_RATE_MAX) { + ath10k_warn(ar, "number of rate is %d greater than TPC configured rate %d\n", + rate_max, WMI_TPC_RATE_MAX); + rate_max = WMI_TPC_RATE_MAX; + } + tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); if (!tpc_stats) return; @@ -4822,8 +4851,8 @@ __le32_to_cpu(ev->twice_antenna_reduction); tpc_stats->power_limit = __le32_to_cpu(ev->power_limit); tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power); - tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain); - tpc_stats->rate_max = __le32_to_cpu(ev->rate_max); + tpc_stats->num_tx_chain = num_tx_chain; + tpc_stats->rate_max = rate_max; ath10k_tpc_config_disp_tables(ar, ev, tpc_stats, rate_code, pream_table, @@ -5018,16 +5047,13 @@ } pream_idx = 0; - for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) { + for (i = 0; i < tpc_stats->rate_max; i++) { memset(tpc_value, 0, sizeof(tpc_value)); memset(buff, 0, sizeof(buff)); if (i == pream_table[pream_idx]) pream_idx++; - for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) { - if (j >= __le32_to_cpu(ev->num_tx_chain)) - break; - + for (j = 0; j < tpc_stats->num_tx_chain; j++) { tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1, rate_code[i], type, pream_idx); @@ -5043,7 +5069,7 @@ void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb) { - u32 num_tx_chain; + u32 num_tx_chain, rate_max; u8 rate_code[WMI_TPC_FINAL_RATE_MAX]; u16 pream_table[WMI_TPC_PREAM_TABLE_MAX]; struct wmi_pdev_tpc_final_table_event *ev; @@ -5051,12 +5077,24 @@ ev = (struct wmi_pdev_tpc_final_table_event *)skb->data; + num_tx_chain = __le32_to_cpu(ev->num_tx_chain); + if (num_tx_chain > WMI_TPC_TX_N_CHAIN) { + ath10k_warn(ar, "number of tx chain is %d greater than TPC final configured tx chain %d\n", + num_tx_chain, WMI_TPC_TX_N_CHAIN); + return; + } + + rate_max = __le32_to_cpu(ev->rate_max); + if (rate_max > WMI_TPC_FINAL_RATE_MAX) { + ath10k_warn(ar, "number of rate is %d greater than TPC final configured rate %d\n", + rate_max, WMI_TPC_FINAL_RATE_MAX); + rate_max = WMI_TPC_FINAL_RATE_MAX; + } + tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); if (!tpc_stats) return; - num_tx_chain = __le32_to_cpu(ev->num_tx_chain); - ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table, num_tx_chain); @@ -5069,8 +5107,8 @@ __le32_to_cpu(ev->twice_antenna_reduction); tpc_stats->power_limit = __le32_to_cpu(ev->power_limit); tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power); - tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain); - tpc_stats->rate_max = __le32_to_cpu(ev->rate_max); + tpc_stats->num_tx_chain = num_tx_chain; + tpc_stats->rate_max = rate_max; ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats, rate_code, pream_table, @@ -5393,6 +5431,12 @@ arg->service_map = ev->wmi_service_bitmap; arg->service_map_len = sizeof(ev->wmi_service_bitmap); + /* Deliberately skipping ev->sys_cap_info as WMI and WMI-TLV have + * different values. We would need a translation to handle that, + * but as we don't currently need anything from sys_cap_info from + * WMI interface (only from WMI-TLV) safest it to skip it. + */ + n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), ARRAY_SIZE(arg->mem_reqs)); for (i = 0; i < n; i++) @@ -5443,9 +5487,12 @@ ar->hw_eeprom_rd = __le32_to_cpu(arg.eeprom_rd); ar->low_5ghz_chan = __le32_to_cpu(arg.low_5ghz_chan); ar->high_5ghz_chan = __le32_to_cpu(arg.high_5ghz_chan); + ar->sys_cap_info = __le32_to_cpu(arg.sys_cap_info); ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", arg.service_map, arg.service_map_len); + ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi sys_cap_info 0x%x\n", + ar->sys_cap_info); if (ar->num_rf_chains > ar->max_spatial_stream) { ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", @@ -5646,8 +5693,13 @@ ret); } - ath10k_wmi_map_svc_ext(ar, arg.service_map_ext, ar->wmi.svc_map, - __le32_to_cpu(arg.service_map_ext_len)); + /* + * Initialization of "arg.service_map_ext_valid" to ZERO is necessary + * for the below logic to work. + */ + if (arg.service_map_ext_valid) + ath10k_wmi_map_svc_ext(ar, arg.service_map_ext, ar->wmi.svc_map, + __le32_to_cpu(arg.service_map_ext_len)); } static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb) @@ -9422,8 +9474,9 @@ msdu = pkt_addr->vaddr; dma_unmap_single(ar->dev, pkt_addr->paddr, - msdu->len, DMA_FROM_DEVICE); + msdu->len, DMA_TO_DEVICE); ieee80211_free_txskb(ar->hw, msdu); + kfree(pkt_addr); return 0; } @@ -9440,7 +9493,5 @@ } cancel_work_sync(&ar->svc_rdy_work); - - if (ar->svc_rdy_skb) - dev_kfree_skb(ar->svc_rdy_skb); + dev_kfree_skb(ar->svc_rdy_skb); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wmi.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wmi.h @@ -2045,7 +2045,9 @@ union { __le32 reginfo1; struct { + /* note: power unit is 1 dBm */ u8 antenna_max; + /* note: power unit is 0.5 dBm */ u8 max_tx_power; } __packed; } __packed; @@ -2065,6 +2067,7 @@ u32 min_power; u32 max_power; u32 max_reg_power; + /* note: power unit is 1 dBm */ u32 max_antenna_gain; u32 reg_class_id; enum wmi_phy_mode mode; @@ -3786,6 +3789,8 @@ u32 arp_srcaddr; u32 arp_dstaddr; u32 enable_btcoex; + u32 rfkill_config; + u32 rfkill_enable; }; #define WMI_PDEV_PARAM_UNSUPPORTED 0 @@ -6851,12 +6856,14 @@ __le32 num_mem_reqs; __le32 low_5ghz_chan; __le32 high_5ghz_chan; + __le32 sys_cap_info; const __le32 *service_map; size_t service_map_len; const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; }; struct wmi_svc_avail_ev_arg { + bool service_map_ext_valid; __le32 service_map_ext_len; const __le32 *service_map_ext; }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath10k/wow.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath10k/wow.c @@ -337,14 +337,15 @@ if (patterns[i].mask[j / 8] & BIT(j % 8)) bitmask[j] = 0xff; old_pattern.mask = bitmask; - new_pattern = old_pattern; if (ar->wmi.rx_decap_mode == ATH10K_HW_TXRX_NATIVE_WIFI) { - if (patterns[i].pkt_offset < ETH_HLEN) + if (patterns[i].pkt_offset < ETH_HLEN) { ath10k_wow_convert_8023_to_80211(&new_pattern, &old_pattern); - else + } else { + new_pattern = old_pattern; new_pattern.pkt_offset += WOW_HDR_LEN - ETH_HLEN; + } } if (WARN_ON(new_pattern.pattern_len > WOW_MAX_PATTERN_SIZE)) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath5k/eeprom.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath5k/eeprom.c @@ -529,7 +529,7 @@ ee->ee_n_piers[mode]++; freq2 = (val >> 8) & 0xff; - if (!freq2) + if (!freq2 || i >= max) break; pc[i++].freq = ath5k_eeprom_bin2freq(ee, @@ -746,6 +746,9 @@ } } + if (idx == AR5K_EEPROM_N_PD_CURVES) + goto err_out; + ee->ee_pd_gains[mode] = 1; pd = &chinfo[pier].pd_curves[idx]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -521,7 +521,7 @@ } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath5k/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath5k/pci.c @@ -46,6 +46,8 @@ { PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */ { PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */ { PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */ + { PCI_VDEVICE(ATHEROS, 0xff16) }, /* Gigaset SX76[23] AR241[34]A */ + { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* Arcadyan ARV45XX AR2417 */ { PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */ { 0 } }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/bmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/bmi.c @@ -246,7 +246,7 @@ return -EACCES; } - size = sizeof(cid) + sizeof(addr) + sizeof(param); + size = sizeof(cid) + sizeof(addr) + sizeof(*param); if (size > ar->bmi.max_cmd_size) { WARN_ON(1); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/debug.c @@ -1027,14 +1027,17 @@ { struct ath6kl *ar = file->private_data; unsigned long lrssi_roam_threshold; + int ret; if (kstrtoul_from_user(user_buf, count, 0, &lrssi_roam_threshold)) return -EINVAL; ar->lrssi_roam_threshold = lrssi_roam_threshold; - ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold); + ret = ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold); + if (ret) + return ret; return count; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -960,8 +960,8 @@ * Thus the possibility of ar->htc_target being NULL * via ath6kl_recv_complete -> ath6kl_usb_io_comp_work. */ - if (WARN_ON_ONCE(!target)) { - ath6kl_err("Target not yet initialized\n"); + if (!target) { + ath6kl_dbg(ATH6KL_DBG_HTC, "Target not yet initialized\n"); status = -EINVAL; goto free_skb; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/init.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/init.c @@ -1575,7 +1575,7 @@ int ath6kl_init_hw_params(struct ath6kl *ar) { - const struct ath6kl_hw *uninitialized_var(hw); + const struct ath6kl_hw *hw; int i; for (i = 0; i < ARRAY_SIZE(hw_list); i++) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/main.c @@ -430,6 +430,9 @@ ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid); + if (aid < 1 || aid > AP_MAX_NUM_STA) + return; + if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) assoc_info; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/usb.c @@ -340,6 +340,11 @@ le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval); } + + /* Ignore broken descriptors. */ + if (usb_endpoint_maxp(endpoint) == 0) + continue; + urbcount = 0; pipe_num = @@ -907,7 +912,7 @@ req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, buf, - size, 2 * HZ); + size, 2000); if (ret < 0) { ath6kl_warn("Failed to read usb control message: %d\n", ret); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath6kl/wmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2510,8 +2510,10 @@ goto free_data_skb; for (index = 0; index < num_pri_streams; index++) { - if (WARN_ON(!data_sync_bufs[index].skb)) + if (WARN_ON(!data_sync_bufs[index].skb)) { + ret = -ENOMEM; goto free_data_skb; + } ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, data_sync_bufs[index]. @@ -2645,6 +2647,11 @@ return -EINVAL; } + if (tsid >= 16) { + ath6kl_err("invalid tsid: %d\n", tsid); + return -EINVAL; + } + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); if (!skb) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/Kconfig @@ -144,13 +144,13 @@ a platform that can toggle the RF-Kill GPIO. config ATH9K_CHANNEL_CONTEXT - bool "Channel Context support" - depends on ATH9K - default n - ---help--- - This option enables channel context support in ath9k, which is needed - for multi-channel concurrency. Enable this if P2P PowerSave support - is required. + bool "Channel Context support" + depends on ATH9K + default n + ---help--- + This option enables channel context support in ath9k, which is needed + for multi-channel concurrency. Enable this if P2P PowerSave support + is required. config ATH9K_PCOEM bool "Atheros ath9k support for PC OEM cards" if EXPERT @@ -162,32 +162,32 @@ depends on ATH9K_PCI default n help - This separate driver provides a loader in order to support the - AR500X to AR92XX-generation of ath9k PCI(e) WiFi chips, which have - their initialization data (which contains the real PCI Device ID - that ath9k will need) stored together with the calibration data out - of reach for the ath9k chip. + This separate driver provides a loader in order to support the + AR500X to AR92XX-generation of ath9k PCI(e) WiFi chips, which have + their initialization data (which contains the real PCI Device ID + that ath9k will need) stored together with the calibration data out + of reach for the ath9k chip. - These devices are usually various network appliances, routers or - access Points and such. + These devices are usually various network appliances, routers or + access Points and such. - If unsure say N. + If unsure say N. config ATH9K_HTC - tristate "Atheros HTC based wireless cards support" - depends on USB && MAC80211 - select ATH9K_HW - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS - select ATH9K_COMMON - ---help--- - Support for Atheros HTC based cards. - Chipsets supported: AR9271 + tristate "Atheros HTC based wireless cards support" + depends on USB && MAC80211 + select ATH9K_HW + select MAC80211_LEDS + select LEDS_CLASS + select NEW_LEDS + select ATH9K_COMMON + ---help--- + Support for Atheros HTC based cards. + Chipsets supported: AR9271 - For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc + For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc - The built module will be ath9k_htc. + The built module will be ath9k_htc. config ATH9K_HTC_DEBUGFS bool "Atheros ath9k_htc debugging" --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ahb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ahb.c @@ -136,8 +136,8 @@ ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)mem, irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, mem, irq); return 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/antenna.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/antenna.c @@ -643,7 +643,7 @@ conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; } else if (antcomb->rssi_sub > - antcomb->rssi_lna1) { + antcomb->rssi_lna2) { /* set to A-B */ conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -3351,7 +3351,8 @@ "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", cptr, code, reference, length, major, minor); if ((!AR_SREV_9485(ah) && length >= 1024) || - (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) { + (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485) || + (length > cptr)) { ath_dbg(common, EEPROM, "Skipping bad header\n"); cptr -= COMP_HDR_LEN; continue; @@ -4183,7 +4184,7 @@ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah) { - u32 data, ko, kg; + u32 data = 0, ko, kg; if (!AR_SREV_9462_20_OR_LATER(ah)) return; @@ -5614,7 +5615,7 @@ static u8 ar9003_get_eepmisc(struct ath_hw *ah) { - return ah->eeprom.map4k.baseEepHeader.eepMisc; + return ah->eeprom.ar9300_eep.baseEepHeader.opCapFlags.eepMisc; } const struct eeprom_ops eep_ar9300_ops = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -1099,17 +1099,22 @@ { u32 dma_dbg_chain, dma_dbg_complete; u8 dcu_chain_state, dcu_complete_state; + unsigned int dbg_reg, reg_offset; int i; - for (i = 0; i < NUM_STATUS_READS; i++) { - if (queue < 6) - dma_dbg_chain = REG_READ(ah, AR_DMADBG_4); - else - dma_dbg_chain = REG_READ(ah, AR_DMADBG_5); + if (queue < 6) { + dbg_reg = AR_DMADBG_4; + reg_offset = queue * 5; + } else { + dbg_reg = AR_DMADBG_5; + reg_offset = (queue - 6) * 5; + } + for (i = 0; i < NUM_STATUS_READS; i++) { + dma_dbg_chain = REG_READ(ah, dbg_reg); dma_dbg_complete = REG_READ(ah, AR_DMADBG_6); - dcu_chain_state = (dma_dbg_chain >> (5 * queue)) & 0x1f; + dcu_chain_state = (dma_dbg_chain >> reg_offset) & 0x1f; dcu_complete_state = dma_dbg_complete & 0x3; if ((dcu_chain_state != 0x6) || (dcu_complete_state != 0x1)) @@ -1128,6 +1133,7 @@ u8 dcu_chain_state, dcu_complete_state; bool dcu_wait_frdone = false; unsigned long chk_dcu = 0; + unsigned int reg_offset; unsigned int i = 0; dma_dbg_4 = REG_READ(ah, AR_DMADBG_4); @@ -1139,12 +1145,15 @@ goto exit; for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (i < 6) + if (i < 6) { chk_dbg = dma_dbg_4; - else + reg_offset = i * 5; + } else { chk_dbg = dma_dbg_5; + reg_offset = (i - 6) * 5; + } - dcu_chain_state = (chk_dbg >> (5 * i)) & 0x1f; + dcu_chain_state = (chk_dbg >> reg_offset) & 0x1f; if (dcu_chain_state == 0x6) { dcu_wait_frdone = true; chk_dcu |= BIT(i); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -720,7 +720,7 @@ #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL (AR_SREV_9561(ah) ? 0x1e00 : 0xf000) -#define AR_CH0_TOP2_XPABIASLVL_S 12 +#define AR_CH0_TOP2_XPABIASLVL_S (AR_SREV_9561(ah) ? 9 : 12) #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : \ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ath9k.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ath9k.h @@ -177,7 +177,8 @@ s8 txq; u8 keyix; u8 rtscts_rate; - u8 retries : 7; + u8 retries : 6; + u8 dyn_smps : 1; u8 baw_tracked : 1; u8 tx_power; enum ath9k_key_type keytype:2; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c @@ -84,7 +84,7 @@ val = swahb32(val); } - __raw_writel(val, mem + reg); + iowrite32(val, mem + reg); usleep_range(100, 120); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/debug.c @@ -1223,8 +1223,11 @@ ah->nf_override = val; - if (ah->curchan) + if (ah->curchan) { + ath9k_ps_wakeup(sc); ath9k_hw_loadnf(ah, ah->curchan); + ath9k_ps_restore(sc); + } return count; } @@ -1281,7 +1284,7 @@ u32 sset, u8 *data) { if (sset == ETH_SS_STATS) - memcpy(data, *ath9k_gstrings_stats, + memcpy(data, ath9k_gstrings_stats, sizeof(ath9k_gstrings_stats)); } @@ -1313,11 +1316,11 @@ struct ath_softc *sc = hw->priv; int i = 0; - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + + data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all); - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + + data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all + sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all); @@ -1368,8 +1371,6 @@ sc->debug.debugfs_phy = debugfs_create_dir("ath9k", sc->hw->wiphy->debugfsdir); - if (!sc->debug.debugfs_phy) - return -ENOMEM; #ifdef CONFIG_ATH_DEBUG debugfs_create_file("debug", 0600, sc->debug.debugfs_phy, --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/hif_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -244,11 +244,11 @@ ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, txok); if (txok) { - TX_STAT_INC(skb_success); - TX_STAT_ADD(skb_success_bytes, ln); + TX_STAT_INC(hif_dev, skb_success); + TX_STAT_ADD(hif_dev, skb_success_bytes, ln); } else - TX_STAT_INC(skb_failed); + TX_STAT_INC(hif_dev, skb_failed); } } @@ -302,7 +302,7 @@ hif_dev->tx.tx_buf_cnt++; if (!(hif_dev->tx.flags & HIF_USB_TX_STOP)) __hif_usb_tx(hif_dev); /* Check for pending SKBs */ - TX_STAT_INC(buf_completed); + TX_STAT_INC(hif_dev, buf_completed); spin_unlock(&hif_dev->tx.tx_lock); } @@ -353,7 +353,7 @@ tx_buf->len += tx_buf->offset; __skb_queue_tail(&tx_buf->skb_queue, nskb); - TX_STAT_INC(skb_queued); + TX_STAT_INC(hif_dev, skb_queued); } usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev, @@ -368,11 +368,10 @@ __skb_queue_head_init(&tx_buf->skb_queue); list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); hif_dev->tx.tx_buf_cnt++; + } else { + TX_STAT_INC(hif_dev, buf_queued); } - if (!ret) - TX_STAT_INC(buf_queued); - return ret; } @@ -449,10 +448,19 @@ spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); /* The pending URBs have to be canceled. */ + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_pending, list) { + usb_get_urb(tx_buf->urb); + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); usb_kill_urb(tx_buf->urb); + list_del(&tx_buf->list); + usb_free_urb(tx_buf->urb); + kfree(tx_buf->buf); + kfree(tx_buf); + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); } + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } @@ -506,7 +514,7 @@ ath9k_htc_txcompletion_cb(hif_dev->htc_handle, skb, false); hif_dev->tx.tx_skb_cnt--; - TX_STAT_INC(skb_failed); + TX_STAT_INC(hif_dev, skb_failed); } } @@ -526,6 +534,24 @@ .send = hif_usb_send, }; +/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream + * in case ath9k_hif_usb_rx_stream wasn't called next time to + * process the buffer and subsequently free it. + */ +static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev) +{ + unsigned long flags; + + spin_lock_irqsave(&hif_dev->rx_lock, flags); + if (hif_dev->remain_skb) { + dev_kfree_skb_any(hif_dev->remain_skb); + hif_dev->remain_skb = NULL; + hif_dev->rx_remain_len = 0; + RX_STAT_INC(hif_dev, skb_dropped); + } + spin_unlock_irqrestore(&hif_dev->rx_lock, flags); +} + static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, struct sk_buff *skb) { @@ -553,11 +579,11 @@ memcpy(ptr, skb->data, rx_remain_len); rx_pkt_len += rx_remain_len; - hif_dev->rx_remain_len = 0; skb_put(remain_skb, rx_pkt_len); skb_pool[pool_index++] = remain_skb; - + hif_dev->remain_skb = NULL; + hif_dev->rx_remain_len = 0; } else { index = rx_remain_len; } @@ -576,9 +602,21 @@ pkt_len = get_unaligned_le16(ptr + index); pkt_tag = get_unaligned_le16(ptr + index + 2); + /* It is supposed that if we have an invalid pkt_tag or + * pkt_len then the whole input SKB is considered invalid + * and dropped; the associated packets already in skb_pool + * are dropped, too. + */ if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) { - RX_STAT_INC(skb_dropped); - return; + RX_STAT_INC(hif_dev, skb_dropped); + goto invalid_pkt; + } + + if (pkt_len > 2 * MAX_RX_BUF_SIZE) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: invalid pkt_len (%x)\n", pkt_len); + RX_STAT_INC(hif_dev, skb_dropped); + goto invalid_pkt; } pad_len = 4 - (pkt_len & 0x3); @@ -590,11 +628,6 @@ if (index > MAX_RX_BUF_SIZE) { spin_lock(&hif_dev->rx_lock); - hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; - hif_dev->rx_transfer_len = - MAX_RX_BUF_SIZE - chk_idx - 4; - hif_dev->rx_pad_len = pad_len; - nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); if (!nskb) { dev_err(&hif_dev->udev->dev, @@ -602,8 +635,14 @@ spin_unlock(&hif_dev->rx_lock); goto err; } + + hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; + hif_dev->rx_transfer_len = + MAX_RX_BUF_SIZE - chk_idx - 4; + hif_dev->rx_pad_len = pad_len; + skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); + RX_STAT_INC(hif_dev, skb_allocated); memcpy(nskb->data, &(skb->data[chk_idx+4]), hif_dev->rx_transfer_len); @@ -612,6 +651,11 @@ hif_dev->remain_skb = nskb; spin_unlock(&hif_dev->rx_lock); } else { + if (pool_index == MAX_PKT_NUM_IN_TRANSFER) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: over RX MAX_PKT_NUM\n"); + goto err; + } nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); if (!nskb) { dev_err(&hif_dev->udev->dev, @@ -619,7 +663,7 @@ goto err; } skb_reserve(nskb, 32); - RX_STAT_INC(skb_allocated); + RX_STAT_INC(hif_dev, skb_allocated); memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len); skb_put(nskb, pkt_len); @@ -629,18 +673,25 @@ err: for (i = 0; i < pool_index; i++) { - RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len); + RX_STAT_ADD(hif_dev, skb_completed_bytes, skb_pool[i]->len); ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], skb_pool[i]->len, USB_WLAN_RX_PIPE); - RX_STAT_INC(skb_completed); + RX_STAT_INC(hif_dev, skb_completed); } + return; +invalid_pkt: + for (i = 0; i < pool_index; i++) { + dev_kfree_skb_any(skb_pool[i]); + RX_STAT_INC(hif_dev, skb_dropped); + } + return; } static void ath9k_hif_usb_rx_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct rx_buf *rx_buf = (struct rx_buf *)urb->context; + struct hif_device_usb *hif_dev = rx_buf->hif_dev; + struct sk_buff *skb = rx_buf->skb; int ret; if (!skb) @@ -667,8 +718,7 @@ } resubmit: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); + __skb_set_length(skb, 0); usb_anchor_urb(urb, &hif_dev->rx_submitted); ret = usb_submit_urb(urb, GFP_ATOMIC); @@ -680,21 +730,21 @@ return; free: kfree_skb(skb); + kfree(rx_buf); } static void ath9k_hif_usb_reg_in_cb(struct urb *urb) { - struct sk_buff *skb = (struct sk_buff *) urb->context; - struct sk_buff *nskb; - struct hif_device_usb *hif_dev = - usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + struct rx_buf *rx_buf = (struct rx_buf *)urb->context; + struct hif_device_usb *hif_dev = rx_buf->hif_dev; + struct sk_buff *skb = rx_buf->skb; int ret; if (!skb) return; if (!hif_dev) - goto free; + goto free_skb; switch (urb->status) { case 0: @@ -703,10 +753,9 @@ case -ECONNRESET: case -ENODEV: case -ESHUTDOWN: - goto free; + goto free_skb; default: - skb_reset_tail_pointer(skb); - skb_trim(skb, 0); + __skb_set_length(skb, 0); goto resubmit; } @@ -714,24 +763,28 @@ if (likely(urb->actual_length != 0)) { skb_put(skb, urb->actual_length); - /* Process the command first */ + /* + * Process the command first. + * skb is either freed here or passed to be + * managed to another callback function. + */ ath9k_htc_rx_msg(hif_dev->htc_handle, skb, skb->len, USB_REG_IN_PIPE); - - nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); - if (!nskb) { + skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); + if (!skb) { dev_err(&hif_dev->udev->dev, "ath9k_htc: REG_IN memory allocation failure\n"); - urb->context = NULL; - return; + goto free_rx_buf; } + rx_buf->skb = skb; + usb_fill_int_urb(urb, hif_dev->udev, usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), - nskb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, nskb, 1); + skb->data, MAX_REG_IN_BUF_SIZE, + ath9k_hif_usb_reg_in_cb, rx_buf, 1); } resubmit: @@ -739,12 +792,14 @@ ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) { usb_unanchor_urb(urb); - goto free; + goto free_skb; } return; -free: +free_skb: kfree_skb(skb); +free_rx_buf: + kfree(rx_buf); urb->context = NULL; } @@ -753,27 +808,33 @@ struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; unsigned long flags; + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) { - usb_kill_urb(tx_buf->urb); list_del(&tx_buf->list); usb_free_urb(tx_buf->urb); kfree(tx_buf->buf); kfree(tx_buf); } + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); hif_dev->tx.flags |= HIF_USB_TX_FLUSH; spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_pending, list) { + usb_get_urb(tx_buf->urb); + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); usb_kill_urb(tx_buf->urb); list_del(&tx_buf->list); usb_free_urb(tx_buf->urb); kfree(tx_buf->buf); kfree(tx_buf); + spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); } + spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); usb_kill_anchored_urbs(&hif_dev->mgmt_submitted); } @@ -790,7 +851,7 @@ init_usb_anchor(&hif_dev->mgmt_submitted); for (i = 0; i < MAX_TX_URB_NUM; i++) { - tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); + tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL); if (!tx_buf) goto err; @@ -823,12 +884,14 @@ static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->rx_submitted); + ath9k_hif_usb_free_rx_remain_skb(hif_dev); } static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) { - struct urb *urb = NULL; + struct rx_buf *rx_buf = NULL; struct sk_buff *skb = NULL; + struct urb *urb = NULL; int i, ret; init_usb_anchor(&hif_dev->rx_submitted); @@ -836,6 +899,12 @@ for (i = 0; i < MAX_RX_URB_NUM; i++) { + rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } + /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { @@ -850,11 +919,14 @@ goto err_skb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + usb_fill_bulk_urb(urb, hif_dev->udev, usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE), skb->data, MAX_RX_BUF_SIZE, - ath9k_hif_usb_rx_cb, skb); + ath9k_hif_usb_rx_cb, rx_buf); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->rx_submitted); @@ -880,6 +952,8 @@ err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_rx_urbs(hif_dev); return ret; } @@ -891,14 +965,21 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) { - struct urb *urb = NULL; + struct rx_buf *rx_buf = NULL; struct sk_buff *skb = NULL; + struct urb *urb = NULL; int i, ret; init_usb_anchor(&hif_dev->reg_in_submitted); for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { + rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + if (!rx_buf) { + ret = -ENOMEM; + goto err_rxb; + } + /* Allocate URB */ urb = usb_alloc_urb(0, GFP_KERNEL); if (urb == NULL) { @@ -913,11 +994,14 @@ goto err_skb; } + rx_buf->hif_dev = hif_dev; + rx_buf->skb = skb; + usb_fill_int_urb(urb, hif_dev->udev, usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, - ath9k_hif_usb_reg_in_cb, skb, 1); + ath9k_hif_usb_reg_in_cb, rx_buf, 1); /* Anchor URB */ usb_anchor_urb(urb, &hif_dev->reg_in_submitted); @@ -943,6 +1027,8 @@ err_skb: usb_free_urb(urb); err_urb: + kfree(rx_buf); +err_rxb: ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); return ret; } @@ -973,7 +1059,7 @@ return -ENOMEM; } -static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) +void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) { usb_kill_anchored_urbs(&hif_dev->regout_submitted); ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev); @@ -1216,7 +1302,7 @@ static int send_eject_command(struct usb_interface *interface) { struct usb_device *udev = interface_to_usbdev(interface); - struct usb_host_interface *iface_desc = &interface->altsetting[0]; + struct usb_host_interface *iface_desc = interface->cur_altsetting; struct usb_endpoint_descriptor *endpoint; unsigned char *cmd; u8 bulk_out_ep; @@ -1271,10 +1357,24 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { + struct usb_endpoint_descriptor *bulk_in, *bulk_out, *int_in, *int_out; struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *alt; struct hif_device_usb *hif_dev; int ret = 0; + /* Verify the expected endpoints are present */ + alt = interface->cur_altsetting; + if (usb_find_common_endpoints(alt, &bulk_in, &bulk_out, &int_in, &int_out) < 0 || + usb_endpoint_num(bulk_in) != USB_WLAN_RX_PIPE || + usb_endpoint_num(bulk_out) != USB_WLAN_TX_PIPE || + usb_endpoint_num(int_in) != USB_REG_IN_PIPE || + usb_endpoint_num(int_out) != USB_REG_OUT_PIPE) { + dev_err(&udev->dev, + "ath9k_htc: Device endpoint numbers are not the expected ones\n"); + return -ENODEV; + } + if (id->driver_info == STORAGE_DEVICE) return send_eject_command(interface); @@ -1341,8 +1441,9 @@ if (hif_dev->flags & HIF_USB_READY) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); + ath9k_destoy_wmi(hif_dev->htc_handle->drv_priv); + ath9k_htc_hw_free(hif_dev->htc_handle); } usb_set_intfdata(interface, NULL); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/hif_usb.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -86,6 +86,11 @@ struct list_head list; }; +struct rx_buf { + struct sk_buff *skb; + struct hif_device_usb *hif_dev; +}; + #define HIF_USB_TX_STOP BIT(0) #define HIF_USB_TX_FLUSH BIT(1) @@ -133,5 +138,6 @@ int ath9k_hif_usb_init(void); void ath9k_hif_usb_exit(void); +void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev); #endif /* HTC_USB_H */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc.h @@ -325,14 +325,18 @@ } #ifdef CONFIG_ATH9K_HTC_DEBUGFS - -#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) -#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) -#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++) -#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a) -#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ - -#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) +#define __STAT_SAFE(hif_dev, expr) do { ((hif_dev)->htc_handle->drv_priv ? (expr) : 0); } while (0) +#define CAB_STAT_INC(priv) do { ((priv)->debug.tx_stats.cab_queued++); } while (0) +#define TX_QSTAT_INC(priv, q) do { ((priv)->debug.tx_stats.queue_stats[q]++); } while (0) + +#define TX_STAT_INC(hif_dev, c) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c++) +#define TX_STAT_ADD(hif_dev, c, a) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.tx_stats.c += a) +#define RX_STAT_INC(hif_dev, c) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c++) +#define RX_STAT_ADD(hif_dev, c, a) \ + __STAT_SAFE((hif_dev), (hif_dev)->htc_handle->drv_priv->debug.skbrx_stats.c += a) void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, struct ath_rx_status *rs); @@ -372,13 +376,13 @@ struct ethtool_stats *stats, u64 *data); #else -#define TX_STAT_INC(c) do { } while (0) -#define TX_STAT_ADD(c, a) do { } while (0) -#define RX_STAT_INC(c) do { } while (0) -#define RX_STAT_ADD(c, a) do { } while (0) -#define CAB_STAT_INC do { } while (0) +#define TX_STAT_INC(hif_dev, c) do { } while (0) +#define TX_STAT_ADD(hif_dev, c, a) do { } while (0) +#define RX_STAT_INC(hif_dev, c) do { } while (0) +#define RX_STAT_ADD(hif_dev, c, a) do { } while (0) -#define TX_QSTAT_INC(c) do { } while (0) +#define CAB_STAT_INC(priv) +#define TX_QSTAT_INC(priv, c) static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, struct ath_rx_status *rs) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -428,7 +428,7 @@ u32 sset, u8 *data) { if (sset == ETH_SS_STATS) - memcpy(data, *ath9k_htc_gstrings_stats, + memcpy(data, ath9k_htc_gstrings_stats, sizeof(ath9k_htc_gstrings_stats)); } @@ -491,8 +491,6 @@ priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, priv->hw->wiphy->debugfsdir); - if (!priv->debug.debugfs_phy) - return -ENOMEM; ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -246,7 +246,7 @@ if (unlikely(r)) { ath_dbg(common, WMI, "REGISTER READ FAILED: (0x%04x, %d)\n", reg_offset, r); - return -EIO; + return -1; } return be32_to_cpu(val); @@ -931,8 +931,9 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, u16 devid, char *product, u32 drv_info) { - struct ieee80211_hw *hw; + struct hif_device_usb *hif_dev; struct ath9k_htc_priv *priv; + struct ieee80211_hw *hw; int ret; hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops); @@ -943,7 +944,6 @@ priv->hw = hw; priv->htc = htc_handle; priv->dev = dev; - htc_handle->drv_priv = priv; SET_IEEE80211_DEV(hw, priv->dev); ret = ath9k_htc_wait_for_target(priv); @@ -964,10 +964,15 @@ if (ret) goto err_init; + htc_handle->drv_priv = priv; + return 0; err_init: - ath9k_deinit_wmi(priv); + ath9k_stop_wmi(priv); + hif_dev = (struct hif_device_usb *)htc_handle->hif_dev; + ath9k_hif_usb_dealloc_urbs(hif_dev); + ath9k_destoy_wmi(priv); err_free: ieee80211_free_hw(hw); return ret; @@ -982,7 +987,7 @@ htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED; ath9k_deinit_device(htc_handle->drv_priv); - ath9k_deinit_wmi(htc_handle->drv_priv); + ath9k_stop_wmi(htc_handle->drv_priv); ieee80211_free_hw(htc_handle->drv_priv->hw); } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1460,7 +1460,7 @@ } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; @@ -1674,7 +1674,7 @@ case IEEE80211_AMPDU_TX_START: ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid); if (!ret) - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -106,20 +106,20 @@ switch (qnum) { case 0: - TX_QSTAT_INC(IEEE80211_AC_VO); + TX_QSTAT_INC(priv, IEEE80211_AC_VO); epid = priv->data_vo_ep; break; case 1: - TX_QSTAT_INC(IEEE80211_AC_VI); + TX_QSTAT_INC(priv, IEEE80211_AC_VI); epid = priv->data_vi_ep; break; case 2: - TX_QSTAT_INC(IEEE80211_AC_BE); + TX_QSTAT_INC(priv, IEEE80211_AC_BE); epid = priv->data_be_ep; break; case 3: default: - TX_QSTAT_INC(IEEE80211_AC_BK); + TX_QSTAT_INC(priv, IEEE80211_AC_BK); epid = priv->data_bk_ep; break; } @@ -323,7 +323,7 @@ memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); if (is_cab) { - CAB_STAT_INC; + CAB_STAT_INC(priv); tx_ctl->epid = priv->cab_ep; return; } @@ -647,9 +647,10 @@ struct ath9k_htc_tx_event *tx_pend; int i; - for (i = 0; i < txs->cnt; i++) { - WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); + if (WARN_ON_ONCE(txs->cnt > HTC_MAX_TX_STATUS)) + return; + for (i = 0; i < txs->cnt; i++) { __txs = &txs->txstatus[i]; skb = ath9k_htc_tx_get_packet(priv, __txs); @@ -973,6 +974,8 @@ struct ath_htc_rx_status *rxstatus; struct ath_rx_status rx_stats; bool decrypt_error = false; + u16 rs_datalen; + bool is_phyerr; if (skb->len < HTC_RX_FRAME_HEADER_SIZE) { ath_err(common, "Corrupted RX frame, dropping (len: %d)\n", @@ -982,11 +985,32 @@ rxstatus = (struct ath_htc_rx_status *)skb->data; - if (be16_to_cpu(rxstatus->rs_datalen) - - (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) { + rs_datalen = be16_to_cpu(rxstatus->rs_datalen); + if (unlikely(rs_datalen - + (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0)) { ath_err(common, "Corrupted RX data len, dropping (dlen: %d, skblen: %d)\n", - rxstatus->rs_datalen, skb->len); + rs_datalen, skb->len); + goto rx_next; + } + + is_phyerr = rxstatus->rs_status & ATH9K_RXERR_PHY; + /* + * Discard zero-length packets and packets smaller than an ACK + * which are not PHY_ERROR (short radar pulses have a length of 3) + */ + if (unlikely(!rs_datalen || (rs_datalen < 10 && !is_phyerr))) { + ath_dbg(common, ANY, + "Short RX data len, dropping (dlen: %d)\n", + rs_datalen); + goto rx_next; + } + + if (rxstatus->rs_keyix >= ATH_KEYMAX && + rxstatus->rs_keyix != ATH9K_RXKEYIX_INVALID) { + ath_dbg(common, ANY, + "Invalid keyix, dropping (keyix: %d)\n", + rxstatus->rs_keyix); goto rx_next; } @@ -1011,7 +1035,7 @@ * Process PHY errors and return so that the packet * can be dropped. */ - if (rx_stats.rs_status & ATH9K_RXERR_PHY) { + if (unlikely(is_phyerr)) { /* TODO: Not using DFS processing now. */ if (ath_cmn_process_fft(&priv->spec_priv, hdr, &rx_stats, rx_status->mactime)) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/htc_hst.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -30,6 +30,7 @@ hdr->endpoint_id = epid; hdr->flags = flags; hdr->payload_len = cpu_to_be16(len); + memset(hdr->control, 0, sizeof(hdr->control)); status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb); @@ -113,6 +114,15 @@ if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { epid = svc_rspmsg->endpoint_id; + + /* Check that the received epid for the endpoint to attach + * a new service is valid. ENDPOINT0 can't be used here as it + * is already reserved for HTC_CTRL_RSVD_SVC service and thus + * should not be modified. + */ + if (epid <= ENDPOINT0 || epid >= ENDPOINT_MAX) + return; + service_id = be16_to_cpu(svc_rspmsg->service_id); max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len); endpoint = &target->endpoint[epid]; @@ -170,7 +180,6 @@ time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); if (!time_left) { dev_err(target->dev, "HTC credit config timeout\n"); - kfree_skb(skb); return -ETIMEDOUT; } @@ -206,7 +215,6 @@ time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); if (!time_left) { dev_err(target->dev, "HTC start timeout\n"); - kfree_skb(skb); return -ETIMEDOUT; } @@ -271,6 +279,10 @@ conn_msg->dl_pipeid = endpoint->dl_pipeid; conn_msg->ul_pipeid = endpoint->ul_pipeid; + /* To prevent infoleak */ + conn_msg->svc_meta_len = 0; + conn_msg->pad = 0; + ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0); if (ret) goto err; @@ -279,10 +291,12 @@ if (!time_left) { dev_err(target->dev, "Service connection timeout for: %d\n", service_connreq->service_id); - kfree_skb(skb); return -ETIMEDOUT; } + if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX) + return -EINVAL; + *conn_rsp_epid = target->conn_rsp_epid; return 0; err: @@ -339,6 +353,8 @@ if (skb) { htc_hdr = (struct htc_frame_hdr *) skb->data; + if (htc_hdr->endpoint_id >= ARRAY_SIZE(htc_handle->endpoint)) + goto ret; endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id]; skb_pull(skb, sizeof(struct htc_frame_hdr)); @@ -357,40 +373,34 @@ } static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, - struct sk_buff *skb) + struct sk_buff *skb, u32 len) { uint32_t *pattern = (uint32_t *)skb->data; - switch (*pattern) { - case 0x33221199: - { + if (*pattern == 0x33221199 && len >= sizeof(struct htc_panic_bad_vaddr)) { struct htc_panic_bad_vaddr *htc_panic; htc_panic = (struct htc_panic_bad_vaddr *) skb->data; dev_err(htc_handle->dev, "ath: firmware panic! " "exccause: 0x%08x; pc: 0x%08x; badvaddr: 0x%08x.\n", htc_panic->exccause, htc_panic->pc, htc_panic->badvaddr); - break; - } - case 0x33221299: - { + return; + } + if (*pattern == 0x33221299) { struct htc_panic_bad_epid *htc_panic; htc_panic = (struct htc_panic_bad_epid *) skb->data; dev_err(htc_handle->dev, "ath: firmware panic! " "bad epid: 0x%08x\n", htc_panic->epid); - break; - } - default: - dev_err(htc_handle->dev, "ath: unknown panic pattern!\n"); - break; + return; } + dev_err(htc_handle->dev, "ath: unknown panic pattern!\n"); } /* * HTC Messages are handled directly here and the obtained SKB * is freed. * - * Service messages (Data, WMI) passed to the corresponding + * Service messages (Data, WMI) are passed to the corresponding * endpoint RX handlers, which have to free the SKB. */ void ath9k_htc_rx_msg(struct htc_target *htc_handle, @@ -404,16 +414,26 @@ if (!htc_handle || !skb) return; + /* A valid message requires len >= 8. + * + * sizeof(struct htc_frame_hdr) == 8 + * sizeof(struct htc_ready_msg) == 8 + * sizeof(struct htc_panic_bad_vaddr) == 16 + * sizeof(struct htc_panic_bad_epid) == 8 + */ + if (unlikely(len < sizeof(struct htc_frame_hdr))) + goto invalid; htc_hdr = (struct htc_frame_hdr *) skb->data; epid = htc_hdr->endpoint_id; if (epid == 0x99) { - ath9k_htc_fw_panic_report(htc_handle, skb); + ath9k_htc_fw_panic_report(htc_handle, skb, len); kfree_skb(skb); return; } if (epid < 0 || epid >= ENDPOINT_MAX) { +invalid: if (pipe_id != USB_REG_IN_PIPE) dev_kfree_skb_any(skb); else @@ -425,21 +445,30 @@ /* Handle trailer */ if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) { - if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) + if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) { /* Move past the Watchdog pattern */ htc_hdr = (struct htc_frame_hdr *)(skb->data + 4); + len -= 4; + } } /* Get the message ID */ + if (unlikely(len < sizeof(struct htc_frame_hdr) + sizeof(__be16))) + goto invalid; msg_id = (__be16 *) ((void *) htc_hdr + sizeof(struct htc_frame_hdr)); /* Now process HTC messages */ switch (be16_to_cpu(*msg_id)) { case HTC_MSG_READY_ID: + if (unlikely(len < sizeof(struct htc_ready_msg))) + goto invalid; htc_process_target_rdy(htc_handle, htc_hdr); break; case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID: + if (unlikely(len < sizeof(struct htc_frame_hdr) + + sizeof(struct htc_conn_svc_rspmsg))) + goto invalid; htc_process_conn_rsp(htc_handle, htc_hdr); break; default: @@ -458,6 +487,8 @@ if (endpoint->ep_callbacks.rx) endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv, skb, epid); + else + goto invalid; } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/hw.c @@ -287,7 +287,7 @@ srev = REG_READ(ah, AR_SREV); - if (srev == -EIO) { + if (srev == -1) { ath_err(ath9k_hw_common(ah), "Failed to read SREV register"); return false; @@ -1622,7 +1622,6 @@ ath9k_hw_gpio_request_out(ah, i, NULL, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i))); - ath9k_hw_gpio_free(ah, i); } } @@ -2730,14 +2729,17 @@ static void ath9k_hw_gpio_cfg_soc(struct ath_hw *ah, u32 gpio, bool out, const char *label) { + int err; + if (ah->caps.gpio_requested & BIT(gpio)) return; - /* may be requested by BSP, free anyway */ - gpio_free(gpio); - - if (gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label)) + err = gpio_request_one(gpio, out ? GPIOF_OUT_INIT_LOW : GPIOF_IN, label); + if (err) { + ath_err(ath9k_hw_common(ah), "request GPIO%d failed:%d\n", + gpio, err); return; + } ah->caps.gpio_requested |= BIT(gpio); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/hw.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/hw.h @@ -819,6 +819,7 @@ struct ath9k_pacal_info pacal_info; struct ar5416Stats stats; struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; + DECLARE_BITMAP(pending_del_keymap, ATH_KEYMAX); enum ath9k_int imask; u32 imrs2_reg; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/init.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/init.c @@ -230,7 +230,7 @@ struct ath_hw *ah = hw_priv; struct ath_common *common = ath9k_hw_common(ah); struct ath_softc *sc = (struct ath_softc *) common->priv; - unsigned long uninitialized_var(flags); + unsigned long flags; u32 val; if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/main.c @@ -200,7 +200,7 @@ void ath_restart_work(struct ath_softc *sc) { ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah)) ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, @@ -304,6 +304,11 @@ hchan = ah->curchan; } + if (!hchan) { + fastcc = false; + hchan = ath9k_cmn_get_channel(sc->hw, ah, &sc->cur_chan->chandef); + } + if (!ath_prepare_reset(sc)) fastcc = false; @@ -525,8 +530,10 @@ ath9k_debug_sync_cause(sc, sync_cause); status &= ah->imask; /* discard unasked-for bits */ - if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) + if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) { + ath9k_hw_kill_interrupts(sc->sc_ah); return IRQ_HANDLED; + } /* * If there are no status bits set, then this interrupt was not @@ -818,12 +825,81 @@ ieee80211_free_txskb(hw, skb); } +static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) +{ + struct ath_buf *bf; + struct ieee80211_tx_info *txinfo; + struct ath_frame_info *fi; + + list_for_each_entry(bf, txq_list, list) { + if (bf->bf_state.stale || !bf->bf_mpdu) + continue; + + txinfo = IEEE80211_SKB_CB(bf->bf_mpdu); + fi = (struct ath_frame_info *)&txinfo->status.status_driver_data[0]; + if (fi->keyix == keyix) + return true; + } + + return false; +} + +static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + int i, j; + struct ath_txq *txq; + bool key_in_use = false; + + for (i = 0; !key_in_use && i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + txq = &sc->tx.txq[i]; + if (!txq->axq_depth) + continue; + if (!ath9k_hw_numtxpending(ah, txq->axq_qnum)) + continue; + + ath_txq_lock(sc, txq); + key_in_use = ath9k_txq_list_has_key(&txq->axq_q, keyix); + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + int idx = txq->txq_tailidx; + + for (j = 0; !key_in_use && + !list_empty(&txq->txq_fifo[idx]) && + j < ATH_TXFIFO_DEPTH; j++) { + key_in_use = ath9k_txq_list_has_key( + &txq->txq_fifo[idx], keyix); + INCR(idx, ATH_TXFIFO_DEPTH); + } + } + ath_txq_unlock(sc, txq); + } + + return key_in_use; +} + +static void ath9k_pending_key_del(struct ath_softc *sc, u8 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + + if (!test_bit(keyix, ah->pending_del_keymap) || + ath9k_txq_has_key(sc, keyix)) + return; + + /* No more TXQ frames point to this key cache entry, so delete it. */ + clear_bit(keyix, ah->pending_del_keymap); + ath_key_delete(common, keyix); +} + static void ath9k_stop(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); bool prev_idle; + int i; ath9k_deinit_channel_context(sc); @@ -891,6 +967,14 @@ spin_unlock_bh(&sc->sc_pcu_lock); + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + + /* Clear key cache entries explicitly to get rid of any potentially + * remaining keys. + */ + ath9k_cmn_init_crypto(sc->sc_ah); + ath9k_ps_restore(sc); sc->ps_idle = prev_idle; @@ -1457,6 +1541,9 @@ ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); } + if (changed & IEEE80211_CONF_CHANGE_POWER) + ath9k_set_txpower(sc, NULL); + mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); @@ -1533,12 +1620,11 @@ { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_node *an = (struct ath_node *) sta->drv_priv; - struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; if (!an->ps_key) return; - ath_key_delete(common, &ps_key); + ath_key_delete(common, an->ps_key); an->ps_key = 0; an->key_idx[0] = 0; } @@ -1700,6 +1786,12 @@ if (sta) an = (struct ath_node *)sta->drv_priv; + /* Delete pending key cache entries if no more frames are pointing to + * them in TXQs. + */ + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + switch (cmd) { case SET_KEY: if (sta) @@ -1729,7 +1821,15 @@ } break; case DISABLE_KEY: - ath_key_delete(common, key); + if (ath9k_txq_has_key(sc, key->hw_key_idx)) { + /* Delay key cache entry deletion until there are no + * remaining TXQ frames pointing to this entry. + */ + set_bit(key->hw_key_idx, sc->sc_ah->pending_del_keymap); + ath_hw_keysetmac(common, key->hw_key_idx, NULL); + } else { + ath_key_delete(common, key->hw_key_idx); + } if (an) { for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) { if (an->key_idx[i] != key->hw_key_idx) @@ -1921,7 +2021,7 @@ ath9k_ps_wakeup(sc); ret = ath_tx_aggr_start(sc, sta, tid, ssn); if (!ret) - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: @@ -2128,7 +2228,7 @@ } ieee80211_queue_delayed_work(hw, &sc->hw_check_work, - ATH_HW_CHECK_POLL_INT); + msecs_to_jiffies(ATH_HW_CHECK_POLL_INT)); } static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/pci.c @@ -993,8 +993,8 @@ sc->sc_ah->msi_reg = 0; ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)sc->mem, pdev->irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, sc->mem, pdev->irq); return 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/wmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/wmi.c @@ -112,14 +112,17 @@ return wmi; } -void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) +void ath9k_stop_wmi(struct ath9k_htc_priv *priv) { struct wmi *wmi = priv->wmi; mutex_lock(&wmi->op_mutex); wmi->stopped = true; mutex_unlock(&wmi->op_mutex); +} +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv) +{ kfree(priv->wmi); } @@ -215,6 +218,10 @@ if (unlikely(wmi->stopped)) goto free_skb; + /* Validate the obtained SKB. */ + if (unlikely(skb->len < sizeof(struct wmi_cmd_hdr))) + goto free_skb; + hdr = (struct wmi_cmd_hdr *) skb->data; cmd_id = be16_to_cpu(hdr->command_id); @@ -232,10 +239,10 @@ spin_unlock_irqrestore(&wmi->wmi_lock, flags); goto free_skb; } - spin_unlock_irqrestore(&wmi->wmi_lock, flags); /* WMI command response */ ath9k_wmi_rsp_callback(wmi, skb); + spin_unlock_irqrestore(&wmi->wmi_lock, flags); free_skb: kfree_skb(skb); @@ -273,7 +280,8 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, struct sk_buff *skb, - enum wmi_cmd_id cmd, u16 len) + enum wmi_cmd_id cmd, u16 len, + u8 *rsp_buf, u32 rsp_len) { struct wmi_cmd_hdr *hdr; unsigned long flags; @@ -283,6 +291,11 @@ hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); spin_lock_irqsave(&wmi->wmi_lock, flags); + + /* record the rsp buffer and length */ + wmi->cmd_rsp_buf = rsp_buf; + wmi->cmd_rsp_len = rsp_len; + wmi->last_seq_id = wmi->tx_seq_id; spin_unlock_irqrestore(&wmi->wmi_lock, flags); @@ -298,8 +311,8 @@ struct ath_common *common = ath9k_hw_common(ah); u16 headroom = sizeof(struct htc_frame_hdr) + sizeof(struct wmi_cmd_hdr); + unsigned long time_left, flags; struct sk_buff *skb; - unsigned long time_left; int ret = 0; if (ah->ah_flags & AH_UNPLUGGED) @@ -323,11 +336,7 @@ goto out; } - /* record the rsp buffer and length */ - wmi->cmd_rsp_buf = rsp_buf; - wmi->cmd_rsp_len = rsp_len; - - ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); + ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len); if (ret) goto out; @@ -335,8 +344,10 @@ if (!time_left) { ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", wmi_cmd_to_name(cmd_id)); + spin_lock_irqsave(&wmi->wmi_lock, flags); + wmi->last_seq_id = 0; + spin_unlock_irqrestore(&wmi->wmi_lock, flags); mutex_unlock(&wmi->op_mutex); - kfree_skb(skb); return -ETIMEDOUT; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/wmi.h +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/wmi.h @@ -179,7 +179,6 @@ }; struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); -void ath9k_deinit_wmi(struct ath9k_htc_priv *priv); int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, enum htc_endpoint_id *wmi_ctrl_epid); int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, @@ -189,6 +188,8 @@ void ath9k_wmi_event_tasklet(unsigned long data); void ath9k_fatal_work(struct work_struct *work); void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv); +void ath9k_stop_wmi(struct ath9k_htc_priv *priv); +void ath9k_destoy_wmi(struct ath9k_htc_priv *priv); #define WMI_CMD(_wmi_cmd) \ do { \ --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/ath9k/xmit.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/ath9k/xmit.c @@ -141,8 +141,8 @@ { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); BUILD_BUG_ON(sizeof(struct ath_frame_info) > - sizeof(tx_info->rate_driver_data)); - return (struct ath_frame_info *) &tx_info->rate_driver_data[0]; + sizeof(tx_info->status.status_driver_data)); + return (struct ath_frame_info *) &tx_info->status.status_driver_data[0]; } static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno) @@ -1271,6 +1271,11 @@ is_40, is_sgi, is_sp); if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; + if (rix >= 8 && fi->dyn_smps) { + info->rates[i].RateFlags |= + ATH9K_RATESERIES_RTS_CTS; + info->flags |= ATH9K_TXDESC_CTSENA; + } info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, is_40, false); @@ -2111,6 +2116,7 @@ fi->keyix = an->ps_key; else fi->keyix = ATH9K_TXKEYIX_INVALID; + fi->dyn_smps = sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC; fi->keytype = keytype; fi->framelen = framelen; fi->tx_power = txpower; @@ -2492,6 +2498,16 @@ spin_unlock_irqrestore(&sc->tx.txbuflock, flags); } +static void ath_clear_tx_status(struct ieee80211_tx_info *tx_info) +{ + void *ptr = &tx_info->status; + + memset(ptr + sizeof(tx_info->status.rates), 0, + sizeof(tx_info->status) - + sizeof(tx_info->status.rates) - + sizeof(tx_info->status.status_driver_data)); +} + static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int nframes, int nbad, int txok) @@ -2503,6 +2519,8 @@ struct ath_hw *ah = sc->sc_ah; u8 i, tx_rateindex; + ath_clear_tx_status(tx_info); + if (txok) tx_info->status.ack_signal = ts->ts_rssi; @@ -2517,6 +2535,13 @@ tx_info->status.ampdu_len = nframes; tx_info->status.ampdu_ack_len = nframes - nbad; + tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; + + for (i = tx_rateindex + 1; i < hw->max_rates; i++) { + tx_info->status.rates[i].count = 0; + tx_info->status.rates[i].idx = -1; + } + if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) { /* @@ -2538,16 +2563,6 @@ tx_info->status.rates[tx_rateindex].count = hw->max_rate_tries; } - - for (i = tx_rateindex + 1; i < hw->max_rates; i++) { - tx_info->status.rates[i].count = 0; - tx_info->status.rates[i].idx = -1; - } - - tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; - - /* we report airtime in ath_tx_count_airtime(), don't report twice */ - tx_info->status.tx_time = 0; } static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/carl9170/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/carl9170/Kconfig @@ -16,13 +16,11 @@ config CARL9170_LEDS bool "SoftLED Support" - depends on CARL9170 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS default y + depends on CARL9170 + depends on MAC80211_LEDS help - This option is necessary, if you want your device' LEDs to blink + This option is necessary, if you want your device's LEDs to blink. Say Y, unless you need the LEDs for firmware debugging. --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/carl9170/fw.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/carl9170/fw.c @@ -338,9 +338,7 @@ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (SUPP(CARL9170FW_WLANTX_CAB)) { - if_comb_types |= - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO); + if_comb_types |= BIT(NL80211_IFTYPE_AP); #ifdef CONFIG_MAC80211_MESH if_comb_types |= --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/carl9170/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/carl9170/main.c @@ -582,11 +582,10 @@ ar->disable_offload |= ((vif->type != NL80211_IFTYPE_STATION) && (vif->type != NL80211_IFTYPE_AP)); - /* While the driver supports HW offload in a single - * P2P client configuration, it doesn't support HW - * offload in the favourit, concurrent P2P GO+CLIENT - * configuration. Hence, HW offload will always be - * disabled for P2P. + /* The driver used to have P2P GO+CLIENT support, + * but since this was dropped and we don't know if + * there are any gremlins lurking in the shadows, + * so best we keep HW offload disabled for P2P. */ ar->disable_offload |= vif->p2p; @@ -639,18 +638,6 @@ if (vif->type == NL80211_IFTYPE_STATION) break; - /* P2P GO [master] use-case - * Because the P2P GO station is selected dynamically - * by all participating peers of a WIFI Direct network, - * the driver has be able to change the main interface - * operating mode on the fly. - */ - if (main_vif->p2p && vif->p2p && - vif->type == NL80211_IFTYPE_AP) { - old_main = main_vif; - break; - } - err = -EBUSY; rcu_read_unlock(); @@ -1449,8 +1436,7 @@ rcu_assign_pointer(sta_info->agg[tid], tid_info); spin_unlock_bh(&ar->tx_ampdu_list_lock); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: @@ -1930,7 +1916,7 @@ WARN_ON(!(tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)); - tx_params = (tx_streams - 1) << + tx_params |= (tx_streams - 1) << IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/carl9170/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/carl9170/tx.c @@ -1557,6 +1557,9 @@ goto out; } } while (ar->beacon_enabled && i--); + + /* no entry found in list */ + return NULL; } out: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/carl9170/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/carl9170/usb.c @@ -1069,6 +1069,38 @@ ar->usb_ep_cmd_is_bulk = true; } + /* Verify that all expected endpoints are present */ + if (ar->usb_ep_cmd_is_bulk) { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } else { + u8 bulk_ep_addr[] = { + AR9170_USB_EP_RX | USB_DIR_IN, + AR9170_USB_EP_TX | USB_DIR_OUT, + 0}; + u8 int_ep_addr[] = { + AR9170_USB_EP_IRQ | USB_DIR_IN, + AR9170_USB_EP_CMD | USB_DIR_OUT, + 0}; + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) + err = -ENODEV; + } + + if (err) { + carl9170_free(ar); + return err; + } + usb_set_intfdata(intf, ar); SET_IEEE80211_DEV(ar->hw, &intf->dev); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/dfs_pattern_detector.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/dfs_pattern_detector.c @@ -182,10 +182,12 @@ if (cd == NULL) return; list_del(&cd->head); - for (i = 0; i < dpd->num_radar_types; i++) { - struct pri_detector *de = cd->detectors[i]; - if (de != NULL) - de->exit(de); + if (cd->detectors) { + for (i = 0; i < dpd->num_radar_types; i++) { + struct pri_detector *de = cd->detectors[i]; + if (de != NULL) + de->exit(de); + } } kfree(cd->detectors); kfree(cd); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/key.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/key.c @@ -84,8 +84,7 @@ } EXPORT_SYMBOL(ath_hw_keyreset); -static bool ath_hw_keysetmac(struct ath_common *common, - u16 entry, const u8 *mac) +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) { u32 macHi, macLo; u32 unicast_flag = AR_KEYTABLE_VALID; @@ -125,6 +124,7 @@ return true; } +EXPORT_SYMBOL(ath_hw_keysetmac); static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, const struct ath_keyval *k, @@ -581,29 +581,38 @@ /* * Delete Key. */ -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) +void ath_key_delete(struct ath_common *common, u8 hw_key_idx) { - ath_hw_keyreset(common, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) + /* Leave CCMP and TKIP (main key) configured to avoid disabling + * encryption for potentially pending frames already in a TXQ with the + * keyix pointing to this key entry. Instead, only clear the MAC address + * to prevent RX processing from using this key cache entry. + */ + if (test_bit(hw_key_idx, common->ccmp_keymap) || + test_bit(hw_key_idx, common->tkip_keymap)) + ath_hw_keysetmac(common, hw_key_idx, NULL); + else + ath_hw_keyreset(common, hw_key_idx); + if (hw_key_idx < IEEE80211_WEP_NKID) return; - clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); - if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + clear_bit(hw_key_idx, common->keymap); + clear_bit(hw_key_idx, common->ccmp_keymap); + if (!test_bit(hw_key_idx, common->tkip_keymap)) return; - clear_bit(key->hw_key_idx + 64, common->keymap); + clear_bit(hw_key_idx + 64, common->keymap); - clear_bit(key->hw_key_idx, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + clear_bit(hw_key_idx, common->tkip_keymap); + clear_bit(hw_key_idx + 64, common->tkip_keymap); if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - ath_hw_keyreset(common, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + ath_hw_keyreset(common, hw_key_idx + 32); + clear_bit(hw_key_idx + 32, common->keymap); + clear_bit(hw_key_idx + 64 + 32, common->keymap); - clear_bit(key->hw_key_idx + 32, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap); } } EXPORT_SYMBOL(ath_key_delete); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wcn36xx/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wcn36xx/Kconfig @@ -17,3 +17,12 @@ Enabled debugfs support If unsure, say Y to make it easier to debug problems. + +config WCN36XX_SNAPDRAGON_HACKS + bool "Dragonboard 410c WCN36XX MAC address generation hacks" + default n + depends on WCN36XX + ---help--- + Upon probe, WCN36XX will try to read its MAC address from + a file located at /lib/firmware/wlan/macaddr0. If the file + is not present, it will randomly generate a new MAC address. --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wcn36xx/dxe.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -563,6 +563,10 @@ dxe = ctl->desc; while (!(READ_ONCE(dxe->ctrl) & WCN36xx_DXE_CTRL_VLD)) { + /* do not read until we own DMA descriptor */ + dma_rmb(); + + /* read/modify DMA descriptor */ skb = ctl->skb; dma_addr = dxe->dst_addr_l; ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl, GFP_ATOMIC); @@ -573,9 +577,15 @@ dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE, DMA_FROM_DEVICE); wcn36xx_rx_skb(wcn, skb); - } /* else keep old skb not submitted and use it for rx DMA */ + } + /* else keep old skb not submitted and reuse it for rx DMA + * (dropping the packet that it contained) + */ + /* flush descriptor changes before re-marking as valid */ + dma_wmb(); dxe->ctrl = ctrl; + ctl = ctl->next; dxe = ctl->desc; } @@ -942,4 +952,9 @@ wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_l_ch); wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_h_ch); + + wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_l_ch); + wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_h_ch); + wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_l_ch); + wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_h_ch); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wcn36xx/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wcn36xx/main.c @@ -134,7 +134,9 @@ .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_DSSSCCK40 | - IEEE80211_HT_CAP_LSIG_TXOP_PROT, + IEEE80211_HT_CAP_LSIG_TXOP_PROT | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_SUP_WIDTH_20_40, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, @@ -163,7 +165,7 @@ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .mcs = { .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(72), + .rx_highest = cpu_to_le16(150), .tx_params = IEEE80211_HT_MCS_TX_DEFINED, } } @@ -293,23 +295,16 @@ goto out_free_dxe_pool; } - wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); - if (!wcn->hal_buf) { - wcn36xx_err("Failed to allocate smd buf\n"); - ret = -ENOMEM; - goto out_free_dxe_ctl; - } - ret = wcn36xx_smd_load_nv(wcn); if (ret) { wcn36xx_err("Failed to push NV to chip\n"); - goto out_free_smd_buf; + goto out_free_dxe_ctl; } ret = wcn36xx_smd_start(wcn); if (ret) { wcn36xx_err("Failed to start chip\n"); - goto out_free_smd_buf; + goto out_free_dxe_ctl; } if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { @@ -336,8 +331,6 @@ out_smd_stop: wcn36xx_smd_stop(wcn); -out_free_smd_buf: - kfree(wcn->hal_buf); out_free_dxe_ctl: wcn36xx_dxe_free_ctl_blks(wcn); out_free_dxe_pool: @@ -374,8 +367,6 @@ wcn36xx_dxe_free_mem_pools(wcn); wcn36xx_dxe_free_ctl_blks(wcn); - - kfree(wcn->hal_buf); } static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) @@ -1084,6 +1075,7 @@ enum ieee80211_ampdu_mlme_action action = params->action; u16 tid = params->tid; u16 *ssn = ¶ms->ssn; + int ret = 0; wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", action, tid); @@ -1106,7 +1098,7 @@ sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START; spin_unlock_bh(&sta_priv->ampdu_lock); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_OPERATIONAL: spin_lock_bh(&sta_priv->ampdu_lock); @@ -1131,7 +1123,7 @@ mutex_unlock(&wcn->conf_mutex); - return 0; + return ret; } static const struct ieee80211_ops wcn36xx_ops = { @@ -1302,6 +1294,14 @@ void *wcnss; int ret; const u8 *addr; +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS + int status; + const struct firmware *addr_file = NULL; + u8 tmp[18], _addr[ETH_ALEN]; + static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5}; + static const char *files = {"wlan/macaddr0"}; +#endif + wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); @@ -1322,6 +1322,12 @@ mutex_init(&wcn->hal_mutex); mutex_init(&wcn->scan_lock); + wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); + if (!wcn->hal_buf) { + ret = -ENOMEM; + goto out_wq; + } + ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); if (ret < 0) { wcn36xx_err("failed to set DMA mask: %d\n", ret); @@ -1341,15 +1347,43 @@ if (addr && ret != ETH_ALEN) { wcn36xx_err("invalid local-mac-address\n"); ret = -EINVAL; - goto out_wq; - } else if (addr) { + goto out_destroy_ept; + } +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS + else if (addr == NULL) { + addr = _addr; + status = request_firmware(&addr_file, files, &pdev->dev); + + if (status < 0) { + /* Assign a random mac with Qualcomm oui */ + dev_err(&pdev->dev, "Failed (%d) to read macaddress" + "file %s, using a random address instead", status, files); + memcpy(addr, qcom_oui, 3); + get_random_bytes(addr + 3, 3); + } else { + memset(tmp, 0, sizeof(tmp)); + memcpy(tmp, addr_file->data, sizeof(tmp) - 1); + sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &addr[0], + &addr[1], + &addr[2], + &addr[3], + &addr[4], + &addr[5]); + + release_firmware(addr_file); + } + } +#endif + + if (addr) { wcn36xx_info("mac address: %pM\n", addr); SET_IEEE80211_PERM_ADDR(wcn->hw, addr); } ret = wcn36xx_platform_get_resources(wcn, pdev); if (ret) - goto out_wq; + goto out_destroy_ept; wcn36xx_init_ieee80211(wcn); ret = ieee80211_register_hw(wcn->hw); @@ -1361,6 +1395,8 @@ out_unmap: iounmap(wcn->ccu_base); iounmap(wcn->dxe_base); +out_destroy_ept: + rpmsg_destroy_ept(wcn->smd_channel); out_wq: ieee80211_free_hw(hw); out_err: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wcn36xx/smd.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wcn36xx/smd.c @@ -2311,7 +2311,7 @@ wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", tmp->bss_index); vif = wcn36xx_priv_to_vif(tmp); - ieee80211_connection_loss(vif); + ieee80211_beacon_loss(vif); } return 0; } @@ -2326,7 +2326,7 @@ wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", rsp->bss_index); vif = wcn36xx_priv_to_vif(tmp); - ieee80211_connection_loss(vif); + ieee80211_beacon_loss(vif); return 0; } } @@ -2340,30 +2340,52 @@ size_t len) { struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; - struct wcn36xx_vif *tmp; + struct wcn36xx_vif *vif_priv; + struct ieee80211_vif *vif; + struct ieee80211_bss_conf *bss_conf; struct ieee80211_sta *sta; + bool found = false; if (len != sizeof(*rsp)) { wcn36xx_warn("Corrupted delete sta indication\n"); return -EIO; } - wcn36xx_dbg(WCN36XX_DBG_HAL, "delete station indication %pM index %d\n", - rsp->addr2, rsp->sta_id); + wcn36xx_dbg(WCN36XX_DBG_HAL, + "delete station indication %pM index %d reason %d\n", + rsp->addr2, rsp->sta_id, rsp->reason_code); - list_for_each_entry(tmp, &wcn->vif_list, list) { + list_for_each_entry(vif_priv, &wcn->vif_list, list) { rcu_read_lock(); - sta = ieee80211_find_sta(wcn36xx_priv_to_vif(tmp), rsp->addr2); - if (sta) - ieee80211_report_low_ack(sta, 0); + vif = wcn36xx_priv_to_vif(vif_priv); + + if (vif->type == NL80211_IFTYPE_STATION) { + /* We could call ieee80211_find_sta too, but checking + * bss_conf is clearer. + */ + bss_conf = &vif->bss_conf; + if (vif_priv->sta_assoc && + !memcmp(bss_conf->bssid, rsp->addr2, ETH_ALEN)) { + found = true; + wcn36xx_dbg(WCN36XX_DBG_HAL, + "connection loss bss_index %d\n", + vif_priv->bss_index); + ieee80211_connection_loss(vif); + } + } else { + sta = ieee80211_find_sta(vif, rsp->addr2); + if (sta) { + found = true; + ieee80211_report_low_ack(sta, 0); + } + } + rcu_read_unlock(); - if (sta) + if (found) return 0; } - wcn36xx_warn("STA with addr %pM and index %d not found\n", - rsp->addr2, - rsp->sta_id); + wcn36xx_warn("BSS or STA with addr %pM not found\n", rsp->addr2); return -ENOENT; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wil6210/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wil6210/Kconfig @@ -2,6 +2,7 @@ config WIL6210 tristate "Wilocity 60g WiFi card wil6210 support" select WANT_DEV_COREDUMP + select CRC32 depends on CFG80211 depends on PCI default n --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wil6210/debugfs.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1021,20 +1021,14 @@ void *cmd; int cmdlen = len - sizeof(struct wmi_cmd_hdr); u16 cmdid; - int rc, rc1; + int rc1; - if (cmdlen < 0) + if (cmdlen < 0 || *ppos != 0) return -EINVAL; - wmi = kmalloc(len, GFP_KERNEL); - if (!wmi) - return -ENOMEM; - - rc = simple_write_to_buffer(wmi, len, ppos, buf, len); - if (rc < 0) { - kfree(wmi); - return rc; - } + wmi = memdup_user(buf, len); + if (IS_ERR(wmi)) + return PTR_ERR(wmi); cmd = (cmdlen > 0) ? &wmi[1] : NULL; cmdid = le16_to_cpu(wmi->command_id); @@ -1044,7 +1038,7 @@ wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1); - return rc; + return len; } static const struct file_operations fops_wmi = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -880,6 +880,7 @@ u8 data_offset; struct wil_rx_status_extended *s; u16 sring_idx = sring - wil->srings; + int invalid_buff_id_retry; BUILD_BUG_ON(sizeof(struct wil_rx_status_extended) > sizeof(skb->cb)); @@ -893,9 +894,9 @@ /* Extract the buffer ID from the status message */ buff_id = le16_to_cpu(wil_rx_status_get_buff_id(msg)); + invalid_buff_id_retry = 0; while (!buff_id) { struct wil_rx_status_extended *s; - int invalid_buff_id_retry = 0; wil_dbg_txrx(wil, "buff_id is not updated yet by HW, (swhead 0x%x)\n", --- linux-oracle-5.4.0.orig/drivers/net/wireless/ath/wil6210/wmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/ath/wil6210/wmi.c @@ -2505,7 +2505,8 @@ cmd->mgmt_frm_type = type; /* BUG: FW API define ieLen as u8. Will fix FW */ cmd->ie_len = cpu_to_le16(ie_len); - memcpy(cmd->ie_info, ie, ie_len); + if (ie_len) + memcpy(cmd->ie_info, ie, ie_len); rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len); kfree(cmd); out: @@ -2541,7 +2542,8 @@ } cmd->ie_len = cpu_to_le16(ie_len); - memcpy(cmd->ie_info, ie, ie_len); + if (ie_len) + memcpy(cmd->ie_info, ie, ie_len); rc = wmi_send(wil, WMI_UPDATE_FT_IES_CMDID, vif->mid, cmd, len); kfree(cmd); --- linux-oracle-5.4.0.orig/drivers/net/wireless/atmel/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/atmel/Kconfig @@ -13,29 +13,29 @@ if WLAN_VENDOR_ATMEL config ATMEL - tristate "Atmel at76c50x chipset 802.11b support" - depends on CFG80211 && (PCI || PCMCIA) - select WIRELESS_EXT - select WEXT_PRIV - select FW_LOADER - select CRC32 - ---help--- - A driver 802.11b wireless cards based on the Atmel fast-vnet - chips. This driver supports standard Linux wireless extensions. + tristate "Atmel at76c50x chipset 802.11b support" + depends on CFG80211 && (PCI || PCMCIA) + select WIRELESS_EXT + select WEXT_PRIV + select FW_LOADER + select CRC32 + ---help--- + A driver 802.11b wireless cards based on the Atmel fast-vnet + chips. This driver supports standard Linux wireless extensions. - Many cards based on this chipset do not have flash memory - and need their firmware loaded at start-up. If yours is - one of these, you will need to provide a firmware image - to be loaded into the card by the driver. The Atmel - firmware package can be downloaded from - + Many cards based on this chipset do not have flash memory + and need their firmware loaded at start-up. If yours is + one of these, you will need to provide a firmware image + to be loaded into the card by the driver. The Atmel + firmware package can be downloaded from + config PCI_ATMEL - tristate "Atmel at76c506 PCI cards" - depends on ATMEL && PCI - ---help--- - Enable support for PCI and mini-PCI cards containing the - Atmel at76c506 chip. + tristate "Atmel at76c506 PCI cards" + depends on ATMEL && PCI + ---help--- + Enable support for PCI and mini-PCI cards containing the + Atmel at76c506 chip. config PCMCIA_ATMEL tristate "Atmel at76c502/at76c504 PCMCIA cards" --- linux-oracle-5.4.0.orig/drivers/net/wireless/atmel/atmel_cs.c +++ linux-oracle-5.4.0/drivers/net/wireless/atmel/atmel_cs.c @@ -73,6 +73,7 @@ static int atmel_probe(struct pcmcia_device *p_dev) { struct local_info *local; + int ret; dev_dbg(&p_dev->dev, "atmel_attach()\n"); @@ -83,8 +84,16 @@ p_dev->priv = local; - return atmel_config(p_dev); -} /* atmel_attach */ + ret = atmel_config(p_dev); + if (ret) + goto err_free_priv; + + return 0; + +err_free_priv: + kfree(p_dev->priv); + return ret; +} static void atmel_detach(struct pcmcia_device *link) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/b43.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/b43.h @@ -651,7 +651,7 @@ union { __be16 d16; __be32 d32; - } data __packed; + } __packed data; } __packed; @@ -1082,6 +1082,22 @@ return dev->__using_pio_transfers; } +static inline void b43_wake_queue(struct b43_wldev *dev, int queue_prio) +{ + if (dev->qos_enabled) + ieee80211_wake_queue(dev->wl->hw, queue_prio); + else + ieee80211_wake_queue(dev->wl->hw, 0); +} + +static inline void b43_stop_queue(struct b43_wldev *dev, int queue_prio) +{ + if (dev->qos_enabled) + ieee80211_stop_queue(dev->wl->hw, queue_prio); + else + ieee80211_stop_queue(dev->wl->hw, 0); +} + /* Message printing */ __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/debugfs.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/debugfs.c @@ -493,7 +493,7 @@ struct b43_wldev *dev; struct b43_debugfs_fops *dfops; struct b43_dfs_file *dfile; - ssize_t uninitialized_var(ret); + ssize_t ret; char *buf; const size_t bufsize = 1024 * 16; /* 16 kiB buffer */ const size_t buforder = get_order(bufsize); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/dma.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/dma.c @@ -37,7 +37,7 @@ static u32 b43_dma_address(struct b43_dma *dma, dma_addr_t dmaaddr, enum b43_addrtype addrtype) { - u32 uninitialized_var(addr); + u32 addr; switch (addrtype) { case B43_DMA_ADDR_LOW: @@ -1399,8 +1399,8 @@ should_inject_overflow(ring)) { /* This TX ring is full. */ unsigned int skb_mapping = skb_get_queue_mapping(skb); - ieee80211_stop_queue(dev->wl->hw, skb_mapping); - dev->wl->tx_queue_stopped[skb_mapping] = 1; + b43_stop_queue(dev, skb_mapping); + dev->wl->tx_queue_stopped[skb_mapping] = true; ring->stopped = true; if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { b43dbg(dev->wl, "Stopped TX ring %d\n", ring->index); @@ -1566,11 +1566,11 @@ } if (dev->wl->tx_queue_stopped[ring->queue_prio]) { - dev->wl->tx_queue_stopped[ring->queue_prio] = 0; + dev->wl->tx_queue_stopped[ring->queue_prio] = false; } else { /* If the driver queue is running wake the corresponding * mac80211 queue. */ - ieee80211_wake_queue(dev->wl->hw, ring->queue_prio); + b43_wake_queue(dev, ring->queue_prio); if (b43_debug(dev, B43_DBG_DMAVERBOSE)) { b43dbg(dev->wl, "Woke up TX ring %d\n", ring->index); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/lo.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/lo.c @@ -729,7 +729,7 @@ }; int max_rx_gain; struct b43_lo_calib *cal; - struct lo_g_saved_values uninitialized_var(saved_regs); + struct lo_g_saved_values saved_regs; /* Values from the "TXCTL Register and Value Table" */ u16 txctl_reg; u16 txctl_value; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/main.c @@ -2585,7 +2585,8 @@ start_ieee80211: wl->hw->queues = B43_QOS_QUEUE_NUM; - if (!modparam_qos || dev->fw.opensource) + if (!modparam_qos || dev->fw.opensource || + dev->dev->chip_id == BCMA_CHIP_ID_BCM4331) wl->hw->queues = 1; err = ieee80211_register_hw(wl->hw); @@ -3600,8 +3601,8 @@ else err = b43_dma_tx(dev, skb); if (err == -ENOSPC) { - wl->tx_queue_stopped[queue_num] = 1; - ieee80211_stop_queue(wl->hw, queue_num); + wl->tx_queue_stopped[queue_num] = true; + b43_stop_queue(dev, queue_num); skb_queue_head(&wl->tx_queue[queue_num], skb); break; } @@ -3611,7 +3612,7 @@ } if (!err) - wl->tx_queue_stopped[queue_num] = 0; + wl->tx_queue_stopped[queue_num] = false; } #if B43_DEBUG @@ -3625,6 +3626,7 @@ struct sk_buff *skb) { struct b43_wl *wl = hw_to_b43_wl(hw); + u16 skb_queue_mapping; if (unlikely(skb->len < 2 + 2 + 6)) { /* Too short, this can't be a valid frame. */ @@ -3633,12 +3635,12 @@ } B43_WARN_ON(skb_shinfo(skb)->nr_frags); - skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb); - if (!wl->tx_queue_stopped[skb->queue_mapping]) { + skb_queue_mapping = skb_get_queue_mapping(skb); + skb_queue_tail(&wl->tx_queue[skb_queue_mapping], skb); + if (!wl->tx_queue_stopped[skb_queue_mapping]) ieee80211_queue_work(wl->hw, &wl->tx_work); - } else { - ieee80211_stop_queue(wl->hw, skb->queue_mapping); - } + else + b43_stop_queue(wl->current_dev, skb_queue_mapping); } static void b43_qos_params_upload(struct b43_wldev *dev, @@ -5569,7 +5571,7 @@ /* fill hw info */ ieee80211_hw_set(hw, RX_INCLUDES_FCS); ieee80211_hw_set(hw, SIGNAL_DBM); - + ieee80211_hw_set(hw, MFP_CAPABLE); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | @@ -5603,7 +5605,7 @@ /* Initialize queues and flags. */ for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) { skb_queue_head_init(&wl->tx_queue[queue_num]); - wl->tx_queue_stopped[queue_num] = 0; + wl->tx_queue_stopped[queue_num] = false; } snprintf(chip_name, ARRAY_SIZE(chip_name), --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/phy_g.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/phy_g.c @@ -2297,7 +2297,7 @@ b43_phy_mask(dev, B43_PHY_G_CRS, 0x7FFF); b43_set_all_gains(dev, 3, 8, 1); - start = (channel - 5 > 0) ? channel - 5 : 1; + start = (channel > 5) ? channel - 5 : 1; end = (channel + 5 < 14) ? channel + 5 : 13; for (i = start; i <= end; i++) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/phy_n.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/phy_n.c @@ -582,7 +582,7 @@ u16 data[4]; s16 gain[2]; u16 minmax[2]; - static const u16 lna_gain[4] = { -2, 10, 19, 25 }; + static const s16 lna_gain[4] = { -2, 10, 19, 25 }; if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 1); @@ -5308,7 +5308,7 @@ for (i = 0; i < 4; i++) { if (dev->phy.rev >= 3) - table[i] = coef[i]; + coef[i] = table[i]; else coef[i] = 0; } @@ -5643,7 +5643,7 @@ u8 rfctl[2]; u8 afectl_core; u16 tmp[6]; - u16 uninitialized_var(cur_hpf1), uninitialized_var(cur_hpf2), cur_lna; + u16 cur_hpf1, cur_hpf2, cur_lna; u32 real, imag; enum nl80211_band band; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/pio.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/pio.c @@ -525,7 +525,7 @@ if (total_len > (q->buffer_size - q->buffer_used)) { /* Not enough memory on the queue. */ err = -EBUSY; - ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); + b43_stop_queue(dev, skb_get_queue_mapping(skb)); q->stopped = true; goto out; } @@ -552,7 +552,7 @@ if (((q->buffer_size - q->buffer_used) < roundup(2 + 2 + 6, 4)) || (q->free_packet_slots == 0)) { /* The queue is full. */ - ieee80211_stop_queue(dev->wl->hw, skb_get_queue_mapping(skb)); + b43_stop_queue(dev, skb_get_queue_mapping(skb)); q->stopped = true; } @@ -587,7 +587,7 @@ list_add(&pack->list, &q->packets_list); if (q->stopped) { - ieee80211_wake_queue(dev->wl->hw, q->queue_prio); + b43_wake_queue(dev, q->queue_prio); q->stopped = false; } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43/xmit.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43/xmit.c @@ -422,10 +422,10 @@ if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) { unsigned int len; - struct ieee80211_hdr *uninitialized_var(hdr); + struct ieee80211_hdr *hdr; int rts_rate, rts_rate_fb; int rts_rate_ofdm, rts_rate_fb_ofdm; - struct b43_plcp_hdr6 *uninitialized_var(plcp); + struct b43_plcp_hdr6 *plcp; struct ieee80211_rate *rts_cts_rate; rts_cts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info); @@ -436,7 +436,7 @@ rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { - struct ieee80211_cts *uninitialized_var(cts); + struct ieee80211_cts *cts; switch (dev->fw.hdr_format) { case B43_FW_HDR_598: @@ -458,7 +458,7 @@ mac_ctl |= B43_TXH_MAC_SENDCTS; len = sizeof(struct ieee80211_cts); } else { - struct ieee80211_rts *uninitialized_var(rts); + struct ieee80211_rts *rts; switch (dev->fw.hdr_format) { case B43_FW_HDR_598: @@ -650,8 +650,8 @@ const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; __le16 fctl; u16 phystat0, phystat3; - u16 uninitialized_var(chanstat), uninitialized_var(mactime); - u32 uninitialized_var(macstat); + u16 chanstat, mactime; + u32 macstat; u16 chanid; int padding, rate_idx; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/b43legacy.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/b43legacy.h @@ -379,7 +379,7 @@ union { __be16 d16; __be32 d32; - } data __packed; + } __packed data; } __packed; #define B43legacy_PHYMODE(phytype) (1 << (phytype)) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/debugfs.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/debugfs.c @@ -190,7 +190,7 @@ struct b43legacy_wldev *dev; struct b43legacy_debugfs_fops *dfops; struct b43legacy_dfs_file *dfile; - ssize_t uninitialized_var(ret); + ssize_t ret; char *buf; const size_t bufsize = 1024 * 16; /* 16 KiB buffer */ const size_t buforder = get_order(bufsize); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/main.c @@ -1275,8 +1275,9 @@ } /* Interrupt handler bottom-half */ -static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) +static void b43legacy_interrupt_tasklet(unsigned long data) { + struct b43legacy_wldev *dev = (struct b43legacy_wldev *)data; u32 reason; u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; u32 merged_dma_reason = 0; @@ -2579,7 +2580,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, unsigned int new_mode) { - struct b43legacy_wldev *uninitialized_var(up_dev); + struct b43legacy_wldev *up_dev; struct b43legacy_wldev *down_dev; int err; bool gmode = false; @@ -3741,7 +3742,7 @@ b43legacy_set_status(wldev, B43legacy_STAT_UNINIT); wldev->bad_frames_preempt = modparam_bad_frames_preempt; tasklet_init(&wldev->isr_tasklet, - (void (*)(unsigned long))b43legacy_interrupt_tasklet, + b43legacy_interrupt_tasklet, (unsigned long)wldev); if (modparam_pio) wldev->__using_pio = true; @@ -3800,6 +3801,7 @@ /* fill hw info */ ieee80211_hw_set(hw, RX_INCLUDES_FCS); ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, MFP_CAPABLE); /* Allow WPA3 in software */ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/phy.c @@ -1123,7 +1123,7 @@ struct b43legacy_phy *phy = &dev->phy; u16 regstack[12] = { 0 }; u16 mls; - u16 fval; + s16 fval; int i; int j; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/radio.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/radio.c @@ -283,7 +283,7 @@ & 0x7FFF); b43legacy_set_all_gains(dev, 3, 8, 1); - start = (channel - 5 > 0) ? channel - 5 : 1; + start = (channel > 5) ? channel - 5 : 1; end = (channel + 5 < 14) ? channel + 5 : 13; for (i = start; i <= end; i++) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/b43legacy/xmit.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/b43legacy/xmit.c @@ -558,6 +558,7 @@ default: b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", chanstat); + goto drop; } memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -770,7 +770,7 @@ nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, sdiodev->settings->bus.sdio.txglomsz); - nents += (nents >> 4) + 1; + nents *= 2; WARN_ON(nents > sdiodev->max_segment_count); @@ -1168,13 +1168,9 @@ }, }; -void brcmf_sdio_register(void) +int brcmf_sdio_register(void) { - int ret; - - ret = sdio_register_driver(&brcmf_sdmmc_driver); - if (ret) - brcmf_err("sdio_register_driver failed: %d\n", ret); + return sdio_register_driver(&brcmf_sdmmc_driver); } void brcmf_sdio_exit(void) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h @@ -274,11 +274,26 @@ #ifdef CONFIG_BRCMFMAC_SDIO void brcmf_sdio_exit(void); -void brcmf_sdio_register(void); +int brcmf_sdio_register(void); +#else +static inline void brcmf_sdio_exit(void) { } +static inline int brcmf_sdio_register(void) { return 0; } #endif + #ifdef CONFIG_BRCMFMAC_USB void brcmf_usb_exit(void); -void brcmf_usb_register(void); +int brcmf_usb_register(void); +#else +static inline void brcmf_usb_exit(void) { } +static inline int brcmf_usb_register(void) { return 0; } +#endif + +#ifdef CONFIG_BRCMFMAC_PCIE +void brcmf_pcie_exit(void); +int brcmf_pcie_register(void); +#else +static inline void brcmf_pcie_exit(void) { } +static inline int brcmf_pcie_register(void) { return 0; } #endif #endif /* BRCMFMAC_BUS_H */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -82,9 +82,14 @@ #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000) +#define BRCMF_PS_MAX_TIMEOUT_MS 2000 + #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) +#define BRCMF_MAX_CHANSPEC_LIST \ + (BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1) + static bool check_vif_up(struct brcmf_cfg80211_vif *vif) { if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) { @@ -705,8 +710,7 @@ scan_request = cfg->scan_request; cfg->scan_request = NULL; - if (timer_pending(&cfg->escan_timeout)) - del_timer_sync(&cfg->escan_timeout); + del_timer_sync(&cfg->escan_timeout); if (fw_abort) { /* Do a scan abort to stop the driver's scan engine */ @@ -1264,13 +1268,14 @@ { struct brcmf_pub *drvr = ifp->drvr; struct brcmf_wsec_pmk_le pmk; - int i, err; + int err; + + memset(&pmk, 0, sizeof(pmk)); - /* convert to firmware key format */ - pmk.key_len = cpu_to_le16(pmk_len << 1); - pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE); - for (i = 0; i < pmk_len; i++) - snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]); + /* pass pmk directly */ + pmk.key_len = cpu_to_le16(pmk_len); + pmk.flags = cpu_to_le16(0); + memcpy(pmk.key, pmk_data, pmk_len); /* store psk in firmware */ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, @@ -2610,8 +2615,9 @@ struct brcmf_sta_info_le sta_info_le; u32 sta_flags; u32 is_tdls_peer; - s32 total_rssi; - s32 count_rssi; + s32 total_rssi_avg = 0; + s32 total_rssi = 0; + s32 count_rssi = 0; int rssi; u32 i; @@ -2677,25 +2683,27 @@ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); } - total_rssi = 0; - count_rssi = 0; for (i = 0; i < BRCMF_ANT_MAX; i++) { - if (sta_info_le.rssi[i]) { - sinfo->chain_signal_avg[count_rssi] = - sta_info_le.rssi[i]; - sinfo->chain_signal[count_rssi] = - sta_info_le.rssi[i]; - total_rssi += sta_info_le.rssi[i]; - count_rssi++; - } + if (sta_info_le.rssi[i] == 0 || + sta_info_le.rx_lastpkt_rssi[i] == 0) + continue; + sinfo->chains |= BIT(count_rssi); + sinfo->chain_signal[count_rssi] = + sta_info_le.rx_lastpkt_rssi[i]; + sinfo->chain_signal_avg[count_rssi] = + sta_info_le.rssi[i]; + total_rssi += sta_info_le.rx_lastpkt_rssi[i]; + total_rssi_avg += sta_info_le.rssi[i]; + count_rssi++; } if (count_rssi) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); - sinfo->chains = count_rssi; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); - total_rssi /= count_rssi; - sinfo->signal = total_rssi; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); + sinfo->filled |= + BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); + sinfo->signal = total_rssi / count_rssi; + sinfo->signal_avg = total_rssi_avg / count_rssi; } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) { memset(&scb_val, 0, sizeof(scb_val)); @@ -2789,6 +2797,12 @@ else bphy_err(drvr, "error (%d)\n", err); } + + err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret", + min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS)); + if (err) + bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err); + done: brcmf_dbg(TRACE, "Exit\n"); return err; @@ -5374,7 +5388,8 @@ return false; } -static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) +static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif, + const struct brcmf_event_msg *e) { u32 event = e->event_code; u16 flags = e->flags; @@ -5383,6 +5398,8 @@ (event == BRCMF_E_DISASSOC_IND) || ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) { brcmf_dbg(CONN, "Processing link down\n"); + clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state); + clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state); return true; } return false; @@ -5449,6 +5466,11 @@ (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf; req_len = le32_to_cpu(assoc_info->req_len); resp_len = le32_to_cpu(assoc_info->resp_len); + if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) { + bphy_err(drvr, "invalid lengths in assoc info: req %u resp %u\n", + req_len, resp_len); + return -EINVAL; + } if (req_len) { err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies", cfg->extra_buf, @@ -5675,7 +5697,7 @@ } else brcmf_bss_connect_done(cfg, ndev, e, true); brcmf_net_setcarrier(ifp, true); - } else if (brcmf_is_linkdown(e)) { + } else if (brcmf_is_linkdown(ifp->vif, e)) { brcmf_dbg(CONN, "Linkdown\n"); if (!brcmf_is_ibssmode(ifp->vif)) { brcmf_bss_connect_done(cfg, ndev, e, false); @@ -6053,6 +6075,13 @@ band->channels[i].flags = IEEE80211_CHAN_DISABLED; total = le32_to_cpu(list->count); + if (total > BRCMF_MAX_CHANSPEC_LIST) { + bphy_err(drvr, "Invalid count of channel Spec. (%u)\n", + total); + err = -EINVAL; + goto fail_pbuf; + } + for (i = 0; i < total; i++) { ch.chspec = (u16)le32_to_cpu(list->element[i]); cfg->d11inf.decchspec(&ch); @@ -6198,6 +6227,13 @@ band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ]; list = (struct brcmf_chanspec_list *)pbuf; num_chan = le32_to_cpu(list->count); + if (num_chan > BRCMF_MAX_CHANSPEC_LIST) { + bphy_err(drvr, "Invalid count of channel Spec. (%u)\n", + num_chan); + kfree(pbuf); + return -EINVAL; + } + for (i = 0; i < num_chan; i++) { ch.chspec = (u16)le32_to_cpu(list->element[i]); cfg->d11inf.decchspec(&ch); @@ -7203,6 +7239,7 @@ brcmf_btcoex_detach(cfg); wiphy_unregister(cfg->wiphy); wl_deinit_priv(cfg); + cancel_work_sync(&cfg->escan_timeout_work); brcmf_free_wiphy(cfg->wiphy); kfree(cfg); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -264,6 +264,7 @@ err); goto done; } + buf[sizeof(buf) - 1] = '\0'; ptr = (char *)buf; strsep(&ptr, "\n"); @@ -280,15 +281,17 @@ if (err) { brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err); } else { + buf[sizeof(buf) - 1] = '\0'; clmver = (char *)buf; - /* store CLM version for adding it to revinfo debugfs file */ - memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); /* Replace all newline/linefeed characters with space * character */ strreplace(clmver, '\n', ' '); + /* store CLM version for adding it to revinfo debugfs file */ + memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver)); + brcmf_dbg(INFO, "CLM version = %s\n", clmver); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -290,6 +290,7 @@ struct brcmf_pub *drvr = ifp->drvr; struct ethhdr *eh; int head_delta; + unsigned int tx_bytes = skb->len; brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); @@ -332,6 +333,7 @@ bphy_err(drvr, "%s: failed to expand headroom\n", brcmf_ifname(ifp)); atomic_inc(&drvr->bus_if->stats.pktcow_failed); + dev_kfree_skb(skb); goto done; } } @@ -361,7 +363,7 @@ ndev->stats.tx_dropped++; } else { ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; + ndev->stats.tx_bytes += tx_bytes; } /* Return ok: we always eat the packet */ @@ -483,7 +485,7 @@ ret = brcmf_proto_hdrpull(drvr, true, skb, ifp); if (ret || !(*ifp) || !(*ifp)->ndev) { - if (ret != -ENODATA && *ifp) + if (ret != -ENODATA && *ifp && (*ifp)->ndev) (*ifp)->ndev->stats.rx_errors++; brcmu_pkt_buf_free_skb(skb); return -ENODATA; @@ -536,6 +538,11 @@ struct ethhdr *eh; u16 type; + if (!ifp) { + brcmu_pkt_buf_free_skb(txp); + return; + } + eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); @@ -1350,6 +1357,11 @@ brcmf_fweh_detach(drvr); brcmf_proto_detach(drvr); + if (drvr->mon_if) { + brcmf_net_detach(drvr->mon_if->ndev, false); + drvr->mon_if = NULL; + } + /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { if (drvr->iflist[i]) @@ -1433,40 +1445,34 @@ } } -static void brcmf_driver_register(struct work_struct *work) -{ -#ifdef CONFIG_BRCMFMAC_SDIO - brcmf_sdio_register(); -#endif -#ifdef CONFIG_BRCMFMAC_USB - brcmf_usb_register(); -#endif -#ifdef CONFIG_BRCMFMAC_PCIE - brcmf_pcie_register(); -#endif -} -static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); - int __init brcmf_core_init(void) { - if (!schedule_work(&brcmf_driver_work)) - return -EBUSY; + int err; + err = brcmf_sdio_register(); + if (err) + return err; + + err = brcmf_usb_register(); + if (err) + goto error_usb_register; + + err = brcmf_pcie_register(); + if (err) + goto error_pcie_register; return 0; + +error_pcie_register: + brcmf_usb_exit(); +error_usb_register: + brcmf_sdio_exit(); + return err; } void __exit brcmf_core_exit(void) { - cancel_work_sync(&brcmf_driver_work); - -#ifdef CONFIG_BRCMFMAC_SDIO brcmf_sdio_exit(); -#endif -#ifdef CONFIG_BRCMFMAC_USB brcmf_usb_exit(); -#endif -#ifdef CONFIG_BRCMFMAC_PCIE brcmf_pcie_exit(); -#endif } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c @@ -40,6 +40,18 @@ BRCM_CC_43340_CHIP_ID, 2, "pov-tab-p1006w-data" }; +static const struct brcmf_dmi_data predia_basic_data = { + BRCM_CC_43341_CHIP_ID, 2, "predia-basic" +}; + +/* Note the Voyo winpad A15 tablet uses the same Ampak AP6330 module, with the + * exact same nvram file as the Prowise-PT301 tablet. Since the nvram for the + * Prowise-PT301 is already in linux-firmware we just point to that here. + */ +static const struct brcmf_dmi_data voyo_winpad_a15_data = { + BRCM_CC_4330_CHIP_ID, 4, "Prowise-PT301" +}; + static const struct dmi_system_id dmi_platform_data[] = { { /* ACEPC T8 Cherry Trail Z8350 mini PC */ @@ -64,6 +76,16 @@ .driver_data = (void *)&acepc_t8_data, }, { + /* Cyberbook T116 rugged tablet */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "20170531"), + }, + /* The factory image nvram file is identical to the ACEPC T8 one */ + .driver_data = (void *)&acepc_t8_data, + }, + { /* Match for the GPDwin which unfortunately uses somewhat * generic dmi strings, which is why we test for 4 strings. * Comparing against 23 other byt/cht boards, board_vendor @@ -111,6 +133,26 @@ }, .driver_data = (void *)&pov_tab_p1006w_data, }, + { + /* Predia Basic tablet (+ with keyboard dock) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"), + /* Mx.WT107.KUBNGEA02 with the version-nr dropped */ + DMI_MATCH(DMI_BIOS_VERSION, "Mx.WT107.KUBNGEA"), + }, + .driver_data = (void *)&predia_basic_data, + }, + { + /* Voyo winpad A15 tablet */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"), + }, + .driver_data = (void *)&voyo_winpad_a15_data, + }, {} }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -283,13 +283,14 @@ if (!err) ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_RANDOM_MAC); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa"); + if (drvr->settings->feature_disable) { brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n", ifp->drvr->feat_flags, drvr->settings->feature_disable); ifp->drvr->feat_flags &= ~drvr->settings->feature_disable; } - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa"); brcmf_feat_firmware_overrides(drvr); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -207,6 +207,8 @@ size = BRCMF_FW_MAX_NVRAM_SIZE; else size = data_len; + /* Add space for properties we may add */ + size += strlen(BRCMF_FW_DEFAULT_BOARDREV) + 1; /* Alloc for extra 0 byte + roundup by 4 + length field */ size += 1 + 3 + sizeof(u32); nvp->nvram = kzalloc(size, GFP_KERNEL); @@ -701,6 +703,11 @@ u32 i, j; char end = '\0'; + if (chiprev >= BITS_PER_TYPE(u32)) { + brcmf_err("Invalid chip revision %u\n", chiprev); + return NULL; + } + for (i = 0; i < table_size; i++) { if (mapping_table[i].chipid == chip && mapping_table[i].revmask & BIT(chiprev)) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c @@ -228,6 +228,10 @@ brcmf_fweh_event_name(event->code), event->code, event->emsg.ifidx, event->emsg.bsscfgidx, event->emsg.addr); + if (event->emsg.bsscfgidx >= BRCMF_MAX_IFS) { + bphy_err(drvr, "invalid bsscfg index: %u\n", event->emsg.bsscfgidx); + goto event_free; + } /* convert event message */ emsg_be = &event->emsg; @@ -304,10 +308,12 @@ { struct brcmf_fweh_info *fweh = &drvr->fweh; - /* cancel the worker */ - cancel_work_sync(&fweh->event_work); - WARN_ON(!list_empty(&fweh->event_q)); - memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); + /* cancel the worker if initialized */ + if (fweh->event_work.func) { + cancel_work_sync(&fweh->event_work); + WARN_ON(!list_empty(&fweh->event_q)); + memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); + } } /** --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -19,7 +19,7 @@ #define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ -#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 +#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0004 #define BRCMF_STA_BRCM 0x00000001 /* Running a Broadcom driver */ #define BRCMF_STA_WME 0x00000002 /* WMM association */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -643,6 +643,7 @@ static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, int ifidx) { + struct brcmf_fws_hanger_item *hi; bool (*matchfn)(struct sk_buff *, void *) = NULL; struct sk_buff *skb; int prec; @@ -654,6 +655,9 @@ skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); while (skb) { hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); + hi = &fws->hanger.items[hslot]; + WARN_ON(skb != hi->pkt); + hi->state = BRCMF_FWS_HANGER_ITEM_STATE_FREE; brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true); brcmu_pkt_buf_free_skb(skb); @@ -2145,8 +2149,7 @@ brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); brcmf_fws_schedule_deq(fws); } else { - bphy_err(drvr, "drop skb: no hanger slot\n"); - brcmf_txfinalize(ifp, skb, false); + bphy_err(drvr, "no hanger slot available\n"); rc = -ENOMEM; } brcmf_fws_unlock(fws); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -345,8 +345,11 @@ count++; } while (count < pktids->array_size); - if (count == pktids->array_size) + if (count == pktids->array_size) { + dma_unmap_single(dev, *physaddr, skb->len - data_offset, + pktids->direction); return -ENOMEM; + } array[*idx].data_offset = data_offset; array[*idx].physaddr = *physaddr; @@ -1619,6 +1622,8 @@ BRCMF_TX_IOCTL_MAX_MSG_SIZE, msgbuf->ioctbuf, msgbuf->ioctbuf_handle); + if (msgbuf->txflow_wq) + destroy_workqueue(msgbuf->txflow_wq); kfree(msgbuf); } return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c @@ -2092,7 +2092,8 @@ /* firmware requires unique mac address for p2pdev interface */ if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) { bphy_err(drvr, "discovery vif must be different from primary interface\n"); - return ERR_PTR(-EINVAL); + err = -EINVAL; + goto fail; } brcmf_p2p_generate_bss_mac(p2p, addr); --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -445,47 +446,6 @@ static void -brcmf_pcie_copy_mem_todev(struct brcmf_pciedev_info *devinfo, u32 mem_offset, - void *srcaddr, u32 len) -{ - void __iomem *address = devinfo->tcm + mem_offset; - __le32 *src32; - __le16 *src16; - u8 *src8; - - if (((ulong)address & 4) || ((ulong)srcaddr & 4) || (len & 4)) { - if (((ulong)address & 2) || ((ulong)srcaddr & 2) || (len & 2)) { - src8 = (u8 *)srcaddr; - while (len) { - iowrite8(*src8, address); - address++; - src8++; - len--; - } - } else { - len = len / 2; - src16 = (__le16 *)srcaddr; - while (len) { - iowrite16(le16_to_cpu(*src16), address); - address += 2; - src16++; - len--; - } - } - } else { - len = len / 4; - src32 = (__le32 *)srcaddr; - while (len) { - iowrite32(le32_to_cpu(*src32), address); - address += 4; - src32++; - len--; - } - } -} - - -static void brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset, void *dstaddr, u32 len) { @@ -656,7 +616,7 @@ } if (!brcmf_chip_set_active(devinfo->ci, resetintr)) - return -EINVAL; + return -EIO; return 0; } @@ -1149,6 +1109,10 @@ BRCMF_NROF_H2D_COMMON_MSGRINGS; max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; } + if (max_flowrings > 512) { + brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings); + return -EIO; + } if (devinfo->dma_idx_sz != 0) { bufsz = (max_submissionrings + max_completionrings) * @@ -1346,6 +1310,18 @@ { } +static int brcmf_pcie_preinit(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; + + brcmf_dbg(PCIE, "Enter\n"); + + brcmf_pcie_intr_enable(buspub->devinfo); + brcmf_pcie_hostready(buspub->devinfo); + + return 0; +} static int brcmf_pcie_tx(struct device *dev, struct sk_buff *skb) { @@ -1427,6 +1403,8 @@ struct brcmf_fw_request *fwreq; int err; + brcmf_pcie_intr_disable(devinfo); + brcmf_pcie_bus_console_read(devinfo, true); brcmf_detach(dev); @@ -1452,6 +1430,7 @@ } static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { + .preinit = brcmf_pcie_preinit, .txdata = brcmf_pcie_tx, .stop = brcmf_pcie_down, .txctl = brcmf_pcie_tx_ctlpkt, @@ -1559,8 +1538,8 @@ return err; brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); - brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase, - (void *)fw->data, fw->size); + memcpy_toio(devinfo->tcm + devinfo->ci->rambase, + (void *)fw->data, fw->size); resetintr = get_unaligned_le32(fw->data); release_firmware(fw); @@ -1574,7 +1553,7 @@ brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); address = devinfo->ci->rambase + devinfo->ci->ramsize - nvram_len; - brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); + memcpy_toio(devinfo->tcm + address, nvram, nvram_len); brcmf_fw_nvram_free(nvram); } else { brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", @@ -1773,6 +1752,8 @@ ret = brcmf_chip_get_raminfo(devinfo->ci); if (ret) { brcmf_err(bus, "Failed to get RAM info\n"); + release_firmware(fw); + brcmf_fw_nvram_free(nvram); goto fail; } @@ -1822,9 +1803,6 @@ init_waitqueue_head(&devinfo->mbdata_resp_wait); - brcmf_pcie_intr_enable(devinfo); - brcmf_pcie_hostready(devinfo); - ret = brcmf_attach(&devinfo->pdev->dev); if (ret) goto fail; @@ -1934,16 +1912,18 @@ fwreq = brcmf_pcie_prepare_fw_request(devinfo); if (!fwreq) { ret = -ENOMEM; - goto fail_bus; + goto fail_brcmf; } ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup); if (ret < 0) { kfree(fwreq); - goto fail_bus; + goto fail_brcmf; } return 0; +fail_brcmf: + brcmf_free(&devinfo->pdev->dev); fail_bus: kfree(bus->msgbuf); kfree(bus); @@ -2069,7 +2049,7 @@ err = brcmf_pcie_probe(pdev, NULL); if (err) - brcmf_err(bus, "probe after resume failed, err=%d\n", err); + __brcmf_err(NULL, __func__, "probe after resume failed, err=%d\n", err); return err; } @@ -2133,15 +2113,10 @@ }; -void brcmf_pcie_register(void) +int brcmf_pcie_register(void) { - int err; - brcmf_dbg(PCIE, "Enter\n"); - err = pci_register_driver(&brcmf_pciedrvr); - if (err) - brcmf_err(NULL, "PCIE driver registration failed, err=%d\n", - err); + return pci_register_driver(&brcmf_pciedrvr); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.h @@ -11,9 +11,4 @@ struct brcmf_pciedev_info *devinfo; }; - -void brcmf_pcie_exit(void); -void brcmf_pcie_register(void); - - #endif /* BRCMFMAC_PCIE_H */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c @@ -154,12 +154,12 @@ struct brcmf_pno_macaddr_le pfn_mac; u8 *mac_addr = NULL; u8 *mac_mask = NULL; - int err, i; + int err, i, ri; - for (i = 0; i < pi->n_reqs; i++) - if (pi->reqs[i]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { - mac_addr = pi->reqs[i]->mac_addr; - mac_mask = pi->reqs[i]->mac_addr_mask; + for (ri = 0; ri < pi->n_reqs; ri++) + if (pi->reqs[ri]->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { + mac_addr = pi->reqs[ri]->mac_addr; + mac_mask = pi->reqs[ri]->mac_addr_mask; break; } @@ -181,7 +181,7 @@ pfn_mac.mac[0] |= 0x02; brcmf_dbg(SCAN, "enabling random mac: reqid=%llu mac=%pM\n", - pi->reqs[i]->reqid, pfn_mac.mac); + pi->reqs[ri]->reqid, pfn_mac.mac); err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, sizeof(pfn_mac)); if (err) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -550,7 +550,7 @@ BRCMF_SDIO_FT_SUB, }; -#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) +#define SDIOD_DRVSTR_KEY(chip, pmu) (((unsigned int)(chip) << 16) | (pmu)) /* SDIO Pad drive strength to select value mappings */ struct sdiod_drive_str { @@ -1934,7 +1934,10 @@ if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new, BRCMF_SDIO_FT_NORMAL)) { rd->len = 0; + brcmf_sdio_rxfail(bus, true, true); + sdio_release_host(bus->sdiodev->func1); brcmu_pkt_buf_free_skb(pkt); + continue; } bus->sdcnt.rx_readahead_cnt++; if (rd->len != roundup(rd_new.len, 16)) { @@ -3364,6 +3367,7 @@ /* Take arm out of reset */ if (!brcmf_chip_set_active(bus->ci, rstvec)) { brcmf_err("error getting out of ARM core reset\n"); + bcmerror = -EIO; goto err; } @@ -3682,7 +3686,11 @@ if (bus->idlecount > bus->idletime) { brcmf_dbg(SDIO, "idle\n"); sdio_claim_host(bus->sdiodev->func1); - brcmf_sdio_wd_timer(bus, false); +#ifdef DEBUG + if (!BRCMF_FWCON_ON() || + bus->console_interval == 0) +#endif + brcmf_sdio_wd_timer(bus, false); bus->idlecount = 0; brcmf_sdio_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func1); @@ -4225,6 +4233,12 @@ } if (err == 0) { + /* Assign bus interface call back */ + sdiod->bus_if->dev = sdiod->dev; + sdiod->bus_if->ops = &brcmf_sdio_bus_ops; + sdiod->bus_if->chip = bus->ci->chip; + sdiod->bus_if->chiprev = bus->ci->chiprev; + /* Allow full data communication using DPC from now on. */ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); @@ -4241,12 +4255,6 @@ sdio_release_host(sdiod->func1); - /* Assign bus interface call back */ - sdiod->bus_if->dev = sdiod->dev; - sdiod->bus_if->ops = &brcmf_sdio_bus_ops; - sdiod->bus_if->chip = bus->ci->chip; - sdiod->bus_if->chiprev = bus->ci->chiprev; - err = brcmf_alloc(sdiod->dev, sdiod->settings); if (err) { brcmf_err("brcmf_alloc failed\n"); @@ -4426,6 +4434,7 @@ brcmf_sdiod_intr_unregister(bus->sdiodev); brcmf_detach(bus->sdiodev->dev); + brcmf_free(bus->sdiodev->dev); cancel_work_sync(&bus->datawork); if (bus->brcmf_wq) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -430,6 +430,7 @@ usb_free_urb(req->urb); list_del(q->next); } + kfree(reqs); return NULL; } @@ -1348,7 +1349,7 @@ goto fail; } - desc = &intf->altsetting[0].desc; + desc = &intf->cur_altsetting->desc; if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || (desc->bInterfaceSubClass != 2) || (desc->bInterfaceProtocol != 0xff)) { @@ -1361,7 +1362,7 @@ num_of_eps = desc->bNumEndpoints; for (ep = 0; ep < num_of_eps; ep++) { - endpoint = &intf->altsetting[0].endpoint[ep].desc; + endpoint = &intf->cur_altsetting->endpoint[ep].desc; endpoint_num = usb_endpoint_num(endpoint); if (!usb_endpoint_xfer_bulk(endpoint)) continue; @@ -1557,12 +1558,8 @@ usb_deregister(&brcmf_usbdrvr); } -void brcmf_usb_register(void) +int brcmf_usb_register(void) { - int ret; - brcmf_dbg(USB, "Enter\n"); - ret = usb_register(&brcmf_usbdrvr); - if (ret) - brcmf_err("usb_register failed %d\n", ret); + return usb_register(&brcmf_usbdrvr); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -850,8 +850,7 @@ "START: tid %d is not agg\'able\n", tid); return -EINVAL; } - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: @@ -1091,6 +1090,7 @@ ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(hw, SIGNAL_DBM); ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, MFP_CAPABLE); hw->extra_tx_headroom = brcms_c_get_header_len(); hw->queues = N_TX_QUEUES; @@ -1223,6 +1223,7 @@ { struct brcms_info *wl; struct ieee80211_hw *hw; + int ret; dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, @@ -1247,11 +1248,16 @@ wl = brcms_attach(pdev); if (!wl) { pr_err("%s: brcms_attach failed!\n", __func__); - return -ENODEV; + ret = -ENODEV; + goto err_free_ieee80211; } brcms_led_register(wl); return 0; + +err_free_ieee80211: + ieee80211_free_hw(hw); + return ret; } static int brcms_suspend(struct bcma_device *pdev) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c @@ -383,8 +383,9 @@ return sh; } -static void wlc_phy_timercb_phycal(struct brcms_phy *pi) +static void wlc_phy_timercb_phycal(void *ptr) { + struct brcms_phy *pi = ptr; uint delay = 5; if (PHY_PERICAL_MPHASE_PENDING(pi)) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c @@ -2625,7 +2625,6 @@ struct lcnphy_txgains cal_gains, temp_gains; u16 hash; - u8 band_idx; int j; u16 ncorr_override[5]; u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, @@ -2657,6 +2656,9 @@ u16 *values_to_save; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + if (WARN_ON(CHSPEC_IS5G(pi->radio_chanspec))) + return; + values_to_save = kmalloc_array(20, sizeof(u16), GFP_ATOMIC); if (NULL == values_to_save) return; @@ -2720,20 +2722,18 @@ hash = (target_gains->gm_gain << 8) | (target_gains->pga_gain << 4) | (target_gains->pad_gain); - band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); - cal_gains = *target_gains; memset(ncorr_override, 0, sizeof(ncorr_override)); - for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { - if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { + for (j = 0; j < iqcal_gainparams_numgains_lcnphy[0]; j++) { + if (hash == tbl_iqcal_gainparams_lcnphy[0][j][0]) { cal_gains.gm_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; + tbl_iqcal_gainparams_lcnphy[0][j][1]; cal_gains.pga_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; + tbl_iqcal_gainparams_lcnphy[0][j][2]; cal_gains.pad_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; + tbl_iqcal_gainparams_lcnphy[0][j][3]; memcpy(ncorr_override, - &tbl_iqcal_gainparams_lcnphy[band_idx][j][3], + &tbl_iqcal_gainparams_lcnphy[0][j][3], sizeof(ncorr_override)); break; } @@ -5065,8 +5065,10 @@ pi->pi_fptr.radioloftget = wlc_lcnphy_get_radio_loft; pi->pi_fptr.detach = wlc_phy_detach_lcnphy; - if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) + if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) { + kfree(pi->u.pi_lcnphy); return false; + } if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { if (pi_lcn->lcnphy_tempsense_option == 3) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -23445,6 +23445,9 @@ } } + if (WARN_ON(k == NPHY_IQCAL_NUMGAINS)) + return; + params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1]; params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2]; params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c @@ -57,12 +57,11 @@ } struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn)(struct brcms_phy *pi), + void (*fn)(void *pi), void *arg, const char *name) { return (struct wlapi_timer *) - brcms_init_timer(physhim->wl, (void (*)(void *))fn, - arg, name); + brcms_init_timer(physhim->wl, fn, arg, name); } void wlapi_free_timer(struct wlapi_timer *t) --- linux-oracle-5.4.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h +++ linux-oracle-5.4.0/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.h @@ -131,7 +131,7 @@ /* PHY to WL utility functions */ struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn)(struct brcms_phy *pi), + void (*fn)(void *pi), void *arg, const char *name); void wlapi_free_timer(struct wlapi_timer *t); void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); --- linux-oracle-5.4.0.orig/drivers/net/wireless/cisco/airo.c +++ linux-oracle-5.4.0/drivers/net/wireless/cisco/airo.c @@ -1925,6 +1925,10 @@ airo_print_err(dev->name, "%s: skb == NULL!",__func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } npacks = skb_queue_len (&ai->txq); if (npacks >= MAXTXQ - 1) { @@ -2127,6 +2131,10 @@ airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = 0; i < MAX_FIDS / 2 && (fids[i] & 0xffff0000); i++ ); @@ -2201,6 +2209,10 @@ airo_print_err(dev->name, "%s: skb == NULL!", __func__); return NETDEV_TX_OK; } + if (skb_padto(skb, ETH_ZLEN)) { + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + } /* Find a vacant FID */ for( i = MAX_FIDS / 2; i < MAX_FIDS && (fids[i] & 0xffff0000); i++ ); @@ -6092,8 +6104,11 @@ { struct airo_info *local = dev->ml_priv; StatusRid status_rid; /* Card status info */ + int ret; - readStatusRid(local, &status_rid, 1); + ret = readStatusRid(local, &status_rid, 1); + if (ret) + return -EBUSY; vwrq->value = le16_to_cpu(status_rid.currentXmitRate) * 500000; /* If more than one rate, set auto */ @@ -7790,16 +7805,8 @@ case AIROGVLIST: ridcode = RID_APLIST; break; case AIROGDRVNAM: ridcode = RID_DRVNAME; break; case AIROGEHTENC: ridcode = RID_ETHERENCAP; break; - case AIROGWEPKTMP: ridcode = RID_WEP_TEMP; - /* Only super-user can read WEP keys */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - break; - case AIROGWEPKNV: ridcode = RID_WEP_PERM; - /* Only super-user can read WEP keys */ - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - break; + case AIROGWEPKTMP: ridcode = RID_WEP_TEMP; break; + case AIROGWEPKNV: ridcode = RID_WEP_PERM; break; case AIROGSTAT: ridcode = RID_STATUS; break; case AIROGSTATSD32: ridcode = RID_STATSDELTA; break; case AIROGSTATSC32: ridcode = RID_STATS; break; @@ -7813,7 +7820,13 @@ return -EINVAL; } - if ((iobuf = kmalloc(RIDSIZE, GFP_KERNEL)) == NULL) + if (ridcode == RID_WEP_TEMP || ridcode == RID_WEP_PERM) { + /* Only super-user can read WEP keys */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + } + + if ((iobuf = kzalloc(RIDSIZE, GFP_KERNEL)) == NULL) return -ENOMEM; PC4500_readrid(ai,ridcode,iobuf,RIDSIZE, 1); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -2294,10 +2294,11 @@ return -ENOMEM; packet->rxp = (struct ipw2100_rx *)packet->skb->data; - packet->dma_addr = pci_map_single(priv->pci_dev, packet->skb->data, + packet->dma_addr = dma_map_single(&priv->pci_dev->dev, + packet->skb->data, sizeof(struct ipw2100_rx), - PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(priv->pci_dev, packet->dma_addr)) { + DMA_FROM_DEVICE); + if (dma_mapping_error(&priv->pci_dev->dev, packet->dma_addr)) { dev_kfree_skb(packet->skb); return -ENOMEM; } @@ -2478,9 +2479,8 @@ return; } - pci_unmap_single(priv->pci_dev, - packet->dma_addr, - sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE); + dma_unmap_single(&priv->pci_dev->dev, packet->dma_addr, + sizeof(struct ipw2100_rx), DMA_FROM_DEVICE); skb_put(packet->skb, status->frame_size); @@ -2562,8 +2562,8 @@ return; } - pci_unmap_single(priv->pci_dev, packet->dma_addr, - sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE); + dma_unmap_single(&priv->pci_dev->dev, packet->dma_addr, + sizeof(struct ipw2100_rx), DMA_FROM_DEVICE); memmove(packet->skb->data + sizeof(struct ipw_rt_hdr), packet->skb->data, status->frame_size); @@ -2688,9 +2688,9 @@ /* Sync the DMA for the RX buffer so CPU is sure to get * the correct values */ - pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr, - sizeof(struct ipw2100_rx), - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&priv->pci_dev->dev, packet->dma_addr, + sizeof(struct ipw2100_rx), + DMA_FROM_DEVICE); if (unlikely(ipw2100_corruption_check(priv, i))) { ipw2100_corruption_detected(priv, i); @@ -2922,9 +2922,8 @@ (packet->index + 1 + i) % txq->entries, tbd->host_addr, tbd->buf_length); - pci_unmap_single(priv->pci_dev, - tbd->host_addr, - tbd->buf_length, PCI_DMA_TODEVICE); + dma_unmap_single(&priv->pci_dev->dev, tbd->host_addr, + tbd->buf_length, DMA_TO_DEVICE); } libipw_txb_free(packet->info.d_struct.txb); @@ -3164,15 +3163,13 @@ tbd->buf_length = packet->info.d_struct.txb-> fragments[i]->len - LIBIPW_3ADDR_LEN; - tbd->host_addr = pci_map_single(priv->pci_dev, + tbd->host_addr = dma_map_single(&priv->pci_dev->dev, packet->info.d_struct. - txb->fragments[i]-> - data + + txb->fragments[i]->data + LIBIPW_3ADDR_LEN, tbd->buf_length, - PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(priv->pci_dev, - tbd->host_addr)) { + DMA_TO_DEVICE); + if (dma_mapping_error(&priv->pci_dev->dev, tbd->host_addr)) { IPW_DEBUG_TX("dma mapping error\n"); break; } @@ -3181,10 +3178,10 @@ txq->next, tbd->host_addr, tbd->buf_length); - pci_dma_sync_single_for_device(priv->pci_dev, - tbd->host_addr, - tbd->buf_length, - PCI_DMA_TODEVICE); + dma_sync_single_for_device(&priv->pci_dev->dev, + tbd->host_addr, + tbd->buf_length, + DMA_TO_DEVICE); txq->next++; txq->next %= txq->entries; @@ -3206,8 +3203,9 @@ } } -static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) +static void ipw2100_irq_tasklet(unsigned long data) { + struct ipw2100_priv *priv = (struct ipw2100_priv *)data; struct net_device *dev = priv->net_dev; unsigned long flags; u32 inta, tmp; @@ -3438,9 +3436,9 @@ return -ENOMEM; for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { - v = pci_zalloc_consistent(priv->pci_dev, - sizeof(struct ipw2100_cmd_header), - &p); + v = dma_alloc_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_cmd_header), &p, + GFP_KERNEL); if (!v) { printk(KERN_ERR DRV_NAME ": " "%s: PCI alloc failed for msg " @@ -3459,11 +3457,10 @@ return 0; for (j = 0; j < i; j++) { - pci_free_consistent(priv->pci_dev, - sizeof(struct ipw2100_cmd_header), - priv->msg_buffers[j].info.c_struct.cmd, - priv->msg_buffers[j].info.c_struct. - cmd_phys); + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_cmd_header), + priv->msg_buffers[j].info.c_struct.cmd, + priv->msg_buffers[j].info.c_struct.cmd_phys); } kfree(priv->msg_buffers); @@ -3494,11 +3491,10 @@ return; for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { - pci_free_consistent(priv->pci_dev, - sizeof(struct ipw2100_cmd_header), - priv->msg_buffers[i].info.c_struct.cmd, - priv->msg_buffers[i].info.c_struct. - cmd_phys); + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_cmd_header), + priv->msg_buffers[i].info.c_struct.cmd, + priv->msg_buffers[i].info.c_struct.cmd_phys); } kfree(priv->msg_buffers); @@ -4321,7 +4317,8 @@ IPW_DEBUG_INFO("enter\n"); q->size = entries * sizeof(struct ipw2100_status); - q->drv = pci_zalloc_consistent(priv->pci_dev, q->size, &q->nic); + q->drv = dma_alloc_coherent(&priv->pci_dev->dev, q->size, &q->nic, + GFP_KERNEL); if (!q->drv) { IPW_DEBUG_WARNING("Can not allocate status queue.\n"); return -ENOMEM; @@ -4337,9 +4334,10 @@ IPW_DEBUG_INFO("enter\n"); if (priv->status_queue.drv) { - pci_free_consistent(priv->pci_dev, priv->status_queue.size, - priv->status_queue.drv, - priv->status_queue.nic); + dma_free_coherent(&priv->pci_dev->dev, + priv->status_queue.size, + priv->status_queue.drv, + priv->status_queue.nic); priv->status_queue.drv = NULL; } @@ -4355,7 +4353,8 @@ q->entries = entries; q->size = entries * sizeof(struct ipw2100_bd); - q->drv = pci_zalloc_consistent(priv->pci_dev, q->size, &q->nic); + q->drv = dma_alloc_coherent(&priv->pci_dev->dev, q->size, &q->nic, + GFP_KERNEL); if (!q->drv) { IPW_DEBUG_INFO ("can't allocate shared memory for buffer descriptors\n"); @@ -4375,7 +4374,8 @@ return; if (q->drv) { - pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic); + dma_free_coherent(&priv->pci_dev->dev, q->size, q->drv, + q->nic); q->drv = NULL; } @@ -4435,9 +4435,9 @@ } for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { - v = pci_alloc_consistent(priv->pci_dev, - sizeof(struct ipw2100_data_header), - &p); + v = dma_alloc_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_data_header), &p, + GFP_KERNEL); if (!v) { printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx " "buffers.\n", @@ -4457,11 +4457,10 @@ return 0; for (j = 0; j < i; j++) { - pci_free_consistent(priv->pci_dev, - sizeof(struct ipw2100_data_header), - priv->tx_buffers[j].info.d_struct.data, - priv->tx_buffers[j].info.d_struct. - data_phys); + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_data_header), + priv->tx_buffers[j].info.d_struct.data, + priv->tx_buffers[j].info.d_struct.data_phys); } kfree(priv->tx_buffers); @@ -4538,12 +4537,10 @@ priv->tx_buffers[i].info.d_struct.txb = NULL; } if (priv->tx_buffers[i].info.d_struct.data) - pci_free_consistent(priv->pci_dev, - sizeof(struct ipw2100_data_header), - priv->tx_buffers[i].info.d_struct. - data, - priv->tx_buffers[i].info.d_struct. - data_phys); + dma_free_coherent(&priv->pci_dev->dev, + sizeof(struct ipw2100_data_header), + priv->tx_buffers[i].info.d_struct.data, + priv->tx_buffers[i].info.d_struct.data_phys); } kfree(priv->tx_buffers); @@ -4606,9 +4603,10 @@ return 0; for (j = 0; j < i; j++) { - pci_unmap_single(priv->pci_dev, priv->rx_buffers[j].dma_addr, + dma_unmap_single(&priv->pci_dev->dev, + priv->rx_buffers[j].dma_addr, sizeof(struct ipw2100_rx_packet), - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb(priv->rx_buffers[j].skb); } @@ -4660,10 +4658,10 @@ for (i = 0; i < RX_QUEUE_LENGTH; i++) { if (priv->rx_buffers[i].rxp) { - pci_unmap_single(priv->pci_dev, + dma_unmap_single(&priv->pci_dev->dev, priv->rx_buffers[i].dma_addr, sizeof(struct ipw2100_rx), - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb(priv->rx_buffers[i].skb); } } @@ -6007,7 +6005,7 @@ spin_unlock_irqrestore(&priv->low_lock, flags); } -static void ipw2100_irq_tasklet(struct ipw2100_priv *priv); +static void ipw2100_irq_tasklet(unsigned long data); static const struct net_device_ops ipw2100_netdev_ops = { .ndo_open = ipw2100_open, @@ -6137,7 +6135,7 @@ INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); INIT_DELAYED_WORK(&priv->scan_event, ipw2100_scan_event); - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + tasklet_init(&priv->irq_tasklet, ipw2100_irq_tasklet, (unsigned long)priv); /* NOTE: We do not start the deferred work for status checks yet */ @@ -6195,7 +6193,7 @@ pci_set_master(pci_dev); pci_set_drvdata(pci_dev, priv); - err = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); if (err) { printk(KERN_WARNING DRV_NAME "Error calling pci_set_dma_mask.\n"); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -1945,8 +1945,9 @@ wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); } -static void ipw_irq_tasklet(struct ipw_priv *priv) +static void ipw_irq_tasklet(unsigned long data) { + struct ipw_priv *priv = (struct ipw_priv *)data; u32 inta, inta_mask, handled = 0; unsigned long flags; int rc = 0; @@ -3441,9 +3442,10 @@ /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].skb != NULL) { - pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, - IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - dev_kfree_skb(rxq->pool[i].skb); + dma_unmap_single(&priv->pci_dev->dev, + rxq->pool[i].dma_addr, + IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); + dev_kfree_skb_irq(rxq->pool[i].skb); rxq->pool[i].skb = NULL; } list_add_tail(&rxq->pool[i].list, &rxq->rx_used); @@ -3775,7 +3777,8 @@ } q->bd = - pci_alloc_consistent(dev, sizeof(q->bd[0]) * count, &q->q.dma_addr); + dma_alloc_coherent(&dev->dev, sizeof(q->bd[0]) * count, + &q->q.dma_addr, GFP_KERNEL); if (!q->bd) { IPW_ERROR("pci_alloc_consistent(%zd) failed\n", sizeof(q->bd[0]) * count); @@ -3817,9 +3820,10 @@ /* unmap chunks if any */ for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) { - pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]), + dma_unmap_single(&dev->dev, + le32_to_cpu(bd->u.data.chunk_ptr[i]), le16_to_cpu(bd->u.data.chunk_len[i]), - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); if (txq->txb[txq->q.last_used]) { libipw_txb_free(txq->txb[txq->q.last_used]); txq->txb[txq->q.last_used] = NULL; @@ -3851,8 +3855,8 @@ } /* free buffers belonging to queue itself */ - pci_free_consistent(dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd, - q->dma_addr); + dma_free_coherent(&dev->dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd, + q->dma_addr); kfree(txq->txb); /* 0 fill whole structure */ @@ -5197,8 +5201,8 @@ list_del(element); rxb->dma_addr = - pci_map_single(priv->pci_dev, rxb->skb->data, - IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + dma_map_single(&priv->pci_dev->dev, rxb->skb->data, + IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; @@ -5231,8 +5235,9 @@ for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { if (rxq->pool[i].skb != NULL) { - pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, - IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + dma_unmap_single(&priv->pci_dev->dev, + rxq->pool[i].dma_addr, + IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); dev_kfree_skb(rxq->pool[i].skb); } } @@ -8270,9 +8275,8 @@ } priv->rxq->queue[i] = NULL; - pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, - IPW_RX_BUF_SIZE, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&priv->pci_dev->dev, rxb->dma_addr, + IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); pkt = (struct ipw_rx_packet *)rxb->skb->data; IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n", @@ -8424,8 +8428,8 @@ rxb->skb = NULL; } - pci_unmap_single(priv->pci_dev, rxb->dma_addr, - IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + dma_unmap_single(&priv->pci_dev->dev, rxb->dma_addr, + IPW_RX_BUF_SIZE, DMA_FROM_DEVICE); list_add_tail(&rxb->list, &priv->rxq->rx_used); i = (i + 1) % RX_QUEUE_SIZE; @@ -10224,11 +10228,10 @@ txb->fragments[i]->len - hdr_len); tfd->u.data.chunk_ptr[i] = - cpu_to_le32(pci_map_single - (priv->pci_dev, - txb->fragments[i]->data + hdr_len, - txb->fragments[i]->len - hdr_len, - PCI_DMA_TODEVICE)); + cpu_to_le32(dma_map_single(&priv->pci_dev->dev, + txb->fragments[i]->data + hdr_len, + txb->fragments[i]->len - hdr_len, + DMA_TO_DEVICE)); tfd->u.data.chunk_len[i] = cpu_to_le16(txb->fragments[i]->len - hdr_len); } @@ -10258,10 +10261,10 @@ dev_kfree_skb_any(txb->fragments[i]); txb->fragments[i] = skb; tfd->u.data.chunk_ptr[i] = - cpu_to_le32(pci_map_single - (priv->pci_dev, skb->data, - remaining_bytes, - PCI_DMA_TODEVICE)); + cpu_to_le32(dma_map_single(&priv->pci_dev->dev, + skb->data, + remaining_bytes, + DMA_TO_DEVICE)); le32_add_cpu(&tfd->u.data.num_chunks, 1); } @@ -10680,7 +10683,7 @@ INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate); #endif /* CONFIG_IPW2200_QOS */ - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + tasklet_init(&priv->irq_tasklet, ipw_irq_tasklet, (unsigned long)priv); return ret; @@ -11411,9 +11414,14 @@ set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); /* With that information in place, we can now register the wiphy... */ - if (wiphy_register(wdev->wiphy)) - rc = -EIO; + rc = wiphy_register(wdev->wiphy); + if (rc) + goto out; + + return 0; out: + kfree(priv->ieee->a_band.channels); + kfree(priv->ieee->bg_band.channels); return rc; } @@ -11631,9 +11639,9 @@ pci_set_master(pdev); - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (err) { printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n"); goto out_pci_disable_device; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/ipw2x00/libipw_rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/ipw2x00/libipw_rx.c @@ -870,8 +870,8 @@ switch (ieee->iw_mode) { case IW_MODE_ADHOC: /* our BSS and not from/to DS */ - if (ether_addr_equal(hdr->addr3, ieee->bssid)) - if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) { + if (ether_addr_equal(hdr->addr3, ieee->bssid) && + ((fc & (IEEE80211_FCTL_TODS + IEEE80211_FCTL_FROMDS)) == 0)) { /* promisc: get all */ if (ieee->dev->flags & IFF_PROMISC) is_packet_for_us = 1; @@ -885,8 +885,8 @@ break; case IW_MODE_INFRA: /* our BSS (== from our AP) and from DS */ - if (ether_addr_equal(hdr->addr2, ieee->bssid)) - if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) { + if (ether_addr_equal(hdr->addr2, ieee->bssid) && + ((fc & (IEEE80211_FCTL_TODS + IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS)) { /* promisc: get all */ if (ieee->dev->flags & IFF_PROMISC) is_packet_for_us = 1; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/ipw2x00/libipw_tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/ipw2x00/libipw_tx.c @@ -383,7 +383,7 @@ /* Each fragment may need to have room for encryption * pre/postfix */ - if (host_encrypt) + if (host_encrypt && crypt && crypt->ops) bytes_per_frag -= crypt->ops->extra_mpdu_prefix_len + crypt->ops->extra_mpdu_postfix_len; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/ipw2x00/libipw_wx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/ipw2x00/libipw_wx.c @@ -633,8 +633,10 @@ } if (ext->alg != IW_ENCODE_ALG_NONE) { - memcpy(sec.keys[idx], ext->key, ext->key_len); - sec.key_sizes[idx] = ext->key_len; + int key_len = clamp_val(ext->key_len, 0, SCM_KEY_LEN); + + memcpy(sec.keys[idx], ext->key, key_len); + sec.key_sizes[idx] = key_len; sec.flags |= (1 << idx); if (ext->alg == IW_ENCODE_ALG_WEP) { sec.encode_alg[idx] = SEC_ALG_WEP; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/3945-mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/3945-mac.c @@ -1376,8 +1376,9 @@ } static void -il3945_irq_tasklet(struct il_priv *il) +il3945_irq_tasklet(unsigned long data) { + struct il_priv *il = (struct il_priv *)data; u32 inta, handled = 0; u32 inta_fh; unsigned long flags; @@ -2301,9 +2302,7 @@ il3945_hw_txq_ctx_free(il); exit: memset(&il->card_alive, 0, sizeof(struct il_alive_resp)); - - if (il->beacon_skb) - dev_kfree_skb(il->beacon_skb); + dev_kfree_skb(il->beacon_skb); il->beacon_skb = NULL; /* clear out any free frames */ @@ -3383,10 +3382,12 @@ * *****************************************************************************/ -static void +static int il3945_setup_deferred_work(struct il_priv *il) { il->workqueue = create_singlethread_workqueue(DRV_NAME); + if (!il->workqueue) + return -ENOMEM; init_waitqueue_head(&il->wait_command_queue); @@ -3403,8 +3404,10 @@ timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_init(&il->irq_tasklet, - (void (*)(unsigned long))il3945_irq_tasklet, + il3945_irq_tasklet, (unsigned long)il); + + return 0; } static void @@ -3726,7 +3729,10 @@ } il_set_rxon_channel(il, &il->bands[NL80211_BAND_2GHZ].channels[5]); - il3945_setup_deferred_work(il); + err = il3945_setup_deferred_work(il); + if (err) + goto out_remove_sysfs; + il3945_setup_handlers(il); il_power_initialize(il); @@ -3738,7 +3744,7 @@ err = il3945_setup_mac(il); if (err) - goto out_remove_sysfs; + goto out_destroy_workqueue; il_dbgfs_register(il, DRV_NAME); @@ -3747,9 +3753,10 @@ return 0; -out_remove_sysfs: +out_destroy_workqueue: destroy_workqueue(il->workqueue); il->workqueue = NULL; +out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &il3945_attribute_group); out_release_irq: free_irq(il->pci_dev->irq, il); @@ -3846,9 +3853,7 @@ il_free_channel_map(il); il_free_geos(il); kfree(il->scan_cmd); - if (il->beacon_skb) - dev_kfree_skb(il->beacon_skb); - + dev_kfree_skb(il->beacon_skb); ieee80211_free_hw(il->hw); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/3945-rs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/3945-rs.c @@ -374,7 +374,7 @@ } static void * -il3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +il3945_rs_alloc(struct ieee80211_hw *hw) { return hw->priv; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/3945.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/3945.c @@ -2100,7 +2100,7 @@ /* set tx power value for all OFDM rates */ for (rate_idx = 0; rate_idx < IL_OFDM_RATES; rate_idx++) { - s32 uninitialized_var(power_idx); + s32 power_idx; int rc; /* use channel group's clip-power table, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -2265,7 +2265,7 @@ if (tid_data->tfds_in_queue == 0) { D_HT("HW queue is empty\n"); tid_data->agg.state = IL_AGG_ON; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; } else { D_HT("HW queue is NOT empty: %d packets in HW queue\n", tid_data->tfds_in_queue); @@ -2768,7 +2768,7 @@ struct ieee80211_tx_info *info; struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le32_to_cpu(tx_resp->u.status); - int uninitialized_var(tid); + int tid; int sta_id; int freed; u8 *qc = NULL; @@ -4344,8 +4344,9 @@ } static void -il4965_irq_tasklet(struct il_priv *il) +il4965_irq_tasklet(unsigned long data) { + struct il_priv *il = (struct il_priv *)data; u32 inta, handled = 0; u32 inta_fh; unsigned long flags; @@ -6216,10 +6217,12 @@ mutex_unlock(&il->mutex); } -static void +static int il4965_setup_deferred_work(struct il_priv *il) { il->workqueue = create_singlethread_workqueue(DRV_NAME); + if (!il->workqueue) + return -ENOMEM; init_waitqueue_head(&il->wait_command_queue); @@ -6238,8 +6241,10 @@ timer_setup(&il->watchdog, il_bg_watchdog, 0); tasklet_init(&il->irq_tasklet, - (void (*)(unsigned long))il4965_irq_tasklet, + il4965_irq_tasklet, (unsigned long)il); + + return 0; } static void @@ -6629,7 +6634,10 @@ goto out_disable_msi; } - il4965_setup_deferred_work(il); + err = il4965_setup_deferred_work(il); + if (err) + goto out_free_irq; + il4965_setup_handlers(il); /********************************************* @@ -6667,6 +6675,7 @@ out_destroy_workqueue: destroy_workqueue(il->workqueue); il->workqueue = NULL; +out_free_irq: free_irq(il->pci_dev->irq, il); out_disable_msi: pci_disable_msi(il->pci_dev); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/4965-rs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/4965-rs.c @@ -2403,7 +2403,7 @@ /* Repeat initial/next rate. * For legacy IL_NUMBER_TRY == 1, this loop will not execute. * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */ - while (repeat_rate > 0 && idx < LINK_QUAL_MAX_RETRY_NUM) { + while (repeat_rate > 0 && idx < (LINK_QUAL_MAX_RETRY_NUM - 1)) { if (is_legacy(tbl_type.lq_type)) { if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) ant_toggle_cnt++; @@ -2474,7 +2474,7 @@ } static void * -il4965_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +il4965_rs_alloc(struct ieee80211_hw *hw) { return hw->priv; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlegacy/common.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlegacy/common.c @@ -699,7 +699,7 @@ u32 gp = _il_rd(il, CSR_EEPROM_GP); int sz; int ret; - u16 addr; + int addr; /* allocate eeprom */ sz = il->cfg->eeprom_size; @@ -4286,8 +4286,8 @@ * power savings, even without L1. */ if (il->cfg->set_l0s) { - pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); - if (lctl & PCI_EXP_LNKCTL_ASPM_L1) { + ret = pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl); + if (!ret && (lctl & PCI_EXP_LNKCTL_ASPM_L1)) { /* L1-ASPM enabled; disable(!) L0S */ il_set_bit(il, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); @@ -4969,6 +4969,8 @@ */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + _il_wr(il, CSR_INT, 0xffffffff); + _il_wr(il, CSR_FH_INT_STATUS, 0xffffffff); il_enable_interrupts(il); if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) @@ -5182,8 +5184,7 @@ memset(&il->current_ht_config, 0, sizeof(struct il_ht_config)); /* new association get rid of ibss beacon skb */ - if (il->beacon_skb) - dev_kfree_skb(il->beacon_skb); + dev_consume_skb_irq(il->beacon_skb); il->beacon_skb = NULL; il->timestamp = 0; @@ -5302,10 +5303,7 @@ } spin_lock_irqsave(&il->lock, flags); - - if (il->beacon_skb) - dev_kfree_skb(il->beacon_skb); - + dev_consume_skb_irq(il->beacon_skb); il->beacon_skb = skb; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/cfg/22000.c @@ -137,7 +137,7 @@ .pcie_l1_allowed = true, }; -static const struct iwl_base_params iwl_22560_base_params = { +static const struct iwl_base_params iwl_ax210_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, .num_of_queues = 512, .max_tfd_queue_size = 65536, @@ -195,40 +195,26 @@ .trans.csr = &iwl_csr_v1, \ .gp2_reg_addr = 0xa02c68 -#define IWL_DEVICE_22560 \ - IWL_DEVICE_22000_COMMON, \ - .trans.device_family = IWL_DEVICE_FAMILY_22560, \ - .trans.base_params = &iwl_22560_base_params, \ - .trans.csr = &iwl_csr_v2 - #define IWL_DEVICE_AX210 \ IWL_DEVICE_22000_COMMON, \ .trans.umac_prph_offset = 0x300000, \ .trans.device_family = IWL_DEVICE_FAMILY_AX210, \ - .trans.base_params = &iwl_22560_base_params, \ + .trans.base_params = &iwl_ax210_base_params, \ .trans.csr = &iwl_csr_v1, \ .min_txq_size = 128, \ .gp2_reg_addr = 0xd02c68, \ .min_256_ba_txq_size = 512 -const struct iwl_cfg iwl22000_2ac_cfg_hr = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_HR_FW_PRE, - IWL_DEVICE_22500, -}; - -const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_HR_CDB_FW_PRE, - IWL_DEVICE_22500, - .cdb = true, -}; - -const struct iwl_cfg iwl22000_2ac_cfg_jf = { - .name = "Intel(R) Dual Band Wireless AC 22000", - .fw_name_pre = IWL_22000_JF_FW_PRE, - IWL_DEVICE_22500, -}; +/* + * If the device doesn't support HE, no need to have that many buffers. + * 22000 devices can split multiple frames into a single RB, so fewer are + * needed; AX210 cannot (but use smaller RBs by default) - these sizes + * were picked according to 8 MSDUs inside 256 A-MSDUs in an A-MPDU, with + * additional overhead to account for processing time. + */ +#define IWL_NUM_RBDS_NON_HE 512 +#define IWL_NUM_RBDS_22000_HE 2048 +#define IWL_NUM_RBDS_AX210_HE 4096 const struct iwl_cfg iwl_ax101_cfg_qu_hr = { .name = "Intel(R) Wi-Fi 6 AX101", @@ -241,6 +227,7 @@ */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .tx_with_siso_diversity = true, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_qu_hr = { @@ -253,6 +240,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0 = { @@ -265,6 +253,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_qu_c0_hr_b0 = { @@ -277,6 +266,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax101_cfg_quz_hr = { @@ -289,42 +279,46 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax201_cfg_quz_hr = { - .name = "Intel(R) Wi-Fi 6 AX201 160MHz", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* + .name = "Intel(R) Wi-Fi 6 AX201 160MHz", + .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* * This device doesn't support receiving BlockAck with a large bitmap * so we need to restrict the size of transmitted aggregation to the * HT size; mac80211 would otherwise pick the HE max (256) by default. */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax1650s_cfg_quz_hr = { - .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* + .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)", + .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* * This device doesn't support receiving BlockAck with a large bitmap * so we need to restrict the size of transmitted aggregation to the * HT size; mac80211 would otherwise pick the HE max (256) by default. */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax1650i_cfg_quz_hr = { - .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", - .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, - IWL_DEVICE_22500, - /* + .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)", + .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE, + IWL_DEVICE_22500, + /* * This device doesn't support receiving BlockAck with a large bitmap * so we need to restrict the size of transmitted aggregation to the * HT size; mac80211 would otherwise pick the HE max (256) by default. */ - .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl_ax200_cfg_cc = { @@ -338,6 +332,7 @@ */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650x_2ax_cfg = { @@ -351,6 +346,7 @@ */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650w_2ax_cfg = { @@ -364,6 +360,7 @@ */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .trans.bisr_workaround = 1, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; /* @@ -375,48 +372,56 @@ .name = "Intel(R) Wireless-AC 9461", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9462", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9461_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9461", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9462", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_qu_c0_jf_b0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_QU_C_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = { @@ -429,6 +434,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_cfg_quz_a0_jf_b0_soc = { @@ -443,6 +449,7 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc = { @@ -457,6 +464,7 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9461_2ac_cfg_quz_a0_jf_b0_soc = { @@ -471,6 +479,7 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9462_2ac_cfg_quz_a0_jf_b0_soc = { @@ -485,6 +494,7 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc = { @@ -499,6 +509,7 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc = { @@ -513,18 +524,21 @@ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, .integrated = true, .soc_latency = 5000, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1550s_2ac_cfg_qu_b0_jf_b0 = { .name = "Killer (R) Wireless-AC 1550s Wireless Network Adapter (9560NGW)", .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, IWL_DEVICE_22500, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0 = { @@ -537,6 +551,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = { @@ -549,6 +564,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = { @@ -561,6 +577,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = { @@ -573,6 +590,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_jf = { @@ -585,6 +603,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0 = { @@ -597,6 +616,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = { @@ -609,6 +629,7 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { @@ -621,18 +642,21 @@ * HT size; mac80211 would otherwise pick the HE max (256) by default. */ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, + .num_rbds = IWL_NUM_RBDS_22000_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = { .name = "Intel(R) Wireless-AC 9560 160MHz", .fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_NON_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = { .name = "Intel(R) Wi-Fi 7 AX210 160MHz", .fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax211_2ax_cfg_so_gf_a0 = { @@ -640,6 +664,7 @@ .fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE, .uhb_supported = true, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = { @@ -647,12 +672,14 @@ .fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE, .uhb_supported = true, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; const struct iwl_cfg iwlax411_2ax_cfg_so_gf4_a0 = { .name = "Intel(R) Wi-Fi 7 AX411 160MHz", .fw_name_pre = IWL_22000_SO_A_GF4_A_FW_PRE, IWL_DEVICE_AX210, + .num_rbds = IWL_NUM_RBDS_AX210_HE, }; MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/cfg/9000.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/cfg/9000.c @@ -137,6 +137,7 @@ .thermal_params = &iwl9000_tt_params, \ .apmg_not_supported = true, \ .trans.mq_rx_supported = true, \ + .num_rbds = 512, \ .vht_mu_mimo_supported = true, \ .mac_addr_from_csr = true, \ .trans.rf_id = true, \ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/dvm/led.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/dvm/led.c @@ -171,6 +171,9 @@ priv->led.name = kasprintf(GFP_KERNEL, "%s-led", wiphy_name(priv->hw->wiphy)); + if (!priv->led.name) + return; + priv->led.brightness_set = iwl_led_brightness_set; priv->led.blink_set = iwl_led_blink_set; priv->led.max_brightness = 1; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -303,7 +303,7 @@ priv->is_open = 1; IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; + return ret; } static void iwlagn_mac_stop(struct ieee80211_hw *hw) --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -3019,7 +3019,7 @@ cpu_to_le16(priv->lib->bt_params->agg_time_limit); } -static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +static void *rs_alloc(struct ieee80211_hw *hw) { return hw->priv; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -1086,6 +1086,7 @@ { __le16 key_flags; struct iwl_addsta_cmd sta_cmd; + size_t to_copy; int i; spin_lock_bh(&priv->sta_lock); @@ -1105,7 +1106,9 @@ sta_cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; for (i = 0; i < 5; i++) sta_cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); - memcpy(sta_cmd.key.key, keyconf->key, keyconf->keylen); + /* keyconf may contain MIC rx/tx keys which iwl does not use */ + to_copy = min_t(size_t, sizeof(sta_cmd.key.key), keyconf->keylen); + memcpy(sta_cmd.key.key, keyconf->key, to_copy); break; case WLAN_CIPHER_SUITE_WEP104: key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/dvm/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/dvm/tx.c @@ -267,7 +267,7 @@ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_station_priv *sta_priv = NULL; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - struct iwl_device_cmd *dev_cmd; + struct iwl_device_tx_cmd *dev_cmd; struct iwl_tx_cmd *tx_cmd; __le16 fc; u8 hdr_len; @@ -348,7 +348,6 @@ if (unlikely(!dev_cmd)) goto drop_unlock_priv; - memset(dev_cmd, 0, sizeof(*dev_cmd)); dev_cmd->hdr.cmd = REPLY_TX; tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; @@ -621,7 +620,7 @@ IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", tid_data->agg.ssn); tid_data->agg.state = IWL_AGG_STARTING; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; } else { IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " "next_reclaimed = %d\n", --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h @@ -7,7 +7,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -29,7 +29,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -323,7 +323,7 @@ } __packed; /* TX_CMD_API_S_VER_7 */ /** - * struct iwl_tx_cmd_gen3 - TX command struct to FW for 22560 devices + * struct iwl_tx_cmd_gen3 - TX command struct to FW for AX210+ devices * ( TX_CMD = 0x1c ) * @len: in bytes of the payload, see below for details * @flags: combination of &enum iwl_tx_cmd_flags --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/fw/api/txq.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/fw/api/txq.h @@ -8,7 +8,7 @@ * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2019 Intel Corporation + * Copyright(c) 2019 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2019 Intel Corporation + * Copyright(c) 2019 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ IWL_MVM_DQA_MAX_MGMT_QUEUE = 8, IWL_MVM_DQA_AP_PROBE_RESP_QUEUE = 9, IWL_MVM_DQA_MIN_DATA_QUEUE = 10, - IWL_MVM_DQA_MAX_DATA_QUEUE = 31, + IWL_MVM_DQA_MAX_DATA_QUEUE = 30, }; enum iwl_mvm_tx_fifo { --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -8,7 +8,7 @@ * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1373,11 +1373,7 @@ goto out; } - /* - * region register have absolute value so apply rxf offset after - * reading the registers - */ - offs += rxf_data.offset; + offs = rxf_data.offset; /* Lock fence */ iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1); @@ -2315,10 +2311,7 @@ goto out; } - if (iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true)) { - IWL_ERR(fwrt, "Failed to stop DBGC recording, aborting dump\n"); - goto out; - } + iwl_fw_dbg_stop_restart_recording(fwrt, ¶ms, true); IWL_DEBUG_FW_INFO(fwrt, "WRT: Data collection start\n"); if (iwl_trans_dbg_ini_valid(fwrt->trans)) @@ -2484,19 +2477,14 @@ return 0; } -int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, - struct iwl_fw_dbg_params *params, - bool stop) +void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params, + bool stop) { int ret = 0; - /* if the FW crashed or not debug monitor cfg was given, there is - * no point in changing the recording state - */ - if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status) || - (!fwrt->trans->dbg.dest_tlv && - fwrt->trans->dbg.ini_dest == IWL_FW_INI_LOCATION_INVALID)) - return 0; + if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) + return; if (fw_has_capa(&fwrt->fw->ucode_capa, IWL_UCODE_TLV_CAPA_DBG_SUSPEND_RESUME_CMD_SUPP)) @@ -2513,7 +2501,5 @@ iwl_fw_set_dbg_rec_on(fwrt); } #endif - - return ret; } IWL_EXPORT_SYMBOL(iwl_fw_dbg_stop_restart_recording); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/fw/dbg.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/fw/dbg.h @@ -263,9 +263,9 @@ _iwl_fw_dbg_trigger_simple_stop((fwrt), (wdev), \ iwl_fw_dbg_get_trigger((fwrt)->fw,\ (trig))) -int iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, - struct iwl_fw_dbg_params *params, - bool stop); +void iwl_fw_dbg_stop_restart_recording(struct iwl_fw_runtime *fwrt, + struct iwl_fw_dbg_params *params, + bool stop); #ifdef CONFIG_IWLWIFI_DEBUGFS static inline void iwl_fw_set_dbg_rec_on(struct iwl_fw_runtime *fwrt) --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -332,9 +332,9 @@ struct iwl_fw_ini_error_dump_range { __le32 range_data_size; union { - __le32 internal_base_addr; - __le64 dram_base_addr; - __le32 page_num; + __le32 internal_base_addr __packed; + __le64 dram_base_addr __packed; + __le32 page_num __packed; struct iwl_fw_ini_fifo_hdr fifo_hdr; }; __le32 data[]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-config.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-config.h @@ -88,7 +88,6 @@ IWL_DEVICE_FAMILY_8000, IWL_DEVICE_FAMILY_9000, IWL_DEVICE_FAMILY_22000, - IWL_DEVICE_FAMILY_22560, IWL_DEVICE_FAMILY_AX210, }; @@ -411,6 +410,8 @@ * @uhb_supported: ultra high band channels supported * @min_256_ba_txq_size: minimum number of slots required in a TX queue which * supports 256 BA aggregation + * @num_rbds: number of receive buffer descriptors to use + * (only used for multi-queue capable devices) * * We enable the driver to be backward compatible wrt. hardware features. * API differences in uCode shouldn't be handled here but through TLVs @@ -466,6 +467,7 @@ u8 max_vht_ampdu_exponent; u8 ucode_api_max; u8 ucode_api_min; + u16 num_rbds; u32 min_umac_error_event_table; u32 extra_phy_cfg_flags; u32 d3_debug_data_base_addr; @@ -578,9 +580,6 @@ extern const struct iwl_cfg iwl9560_2ac_160_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_2ac_cfg_shared_clk; extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk; -extern const struct iwl_cfg iwl22000_2ac_cfg_hr; -extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; -extern const struct iwl_cfg iwl22000_2ac_cfg_jf; extern const struct iwl_cfg iwl_ax101_cfg_qu_hr; extern const struct iwl_cfg iwl_ax101_cfg_qu_c0_hr_b0; extern const struct iwl_cfg iwl_ax101_cfg_quz_hr; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-context-info.h @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -20,7 +20,7 @@ * BSD LICENSE * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,12 +64,12 @@ * the init done for driver command that configures several system modes * @IWL_CTXT_INFO_EARLY_DEBUG: enable early debug * @IWL_CTXT_INFO_ENABLE_CDMP: enable core dump - * @IWL_CTXT_INFO_RB_CB_SIZE_POS: position of the RBD Cyclic Buffer Size + * @IWL_CTXT_INFO_RB_CB_SIZE: mask of the RBD Cyclic Buffer Size * exponent, the actual size is 2**value, valid sizes are 8-2048. * The value is four bits long. Maximum valid exponent is 12 * @IWL_CTXT_INFO_TFD_FORMAT_LONG: use long TFD Format (the * default is short format - not supported by the driver) - * @IWL_CTXT_INFO_RB_SIZE_POS: RB size position + * @IWL_CTXT_INFO_RB_SIZE: RB size mask * (values are IWL_CTXT_INFO_RB_SIZE_*K) * @IWL_CTXT_INFO_RB_SIZE_1K: Value for 1K RB size * @IWL_CTXT_INFO_RB_SIZE_2K: Value for 2K RB size @@ -83,12 +83,12 @@ * @IWL_CTXT_INFO_RB_SIZE_32K: Value for 32K RB size */ enum iwl_context_info_flags { - IWL_CTXT_INFO_AUTO_FUNC_INIT = BIT(0), - IWL_CTXT_INFO_EARLY_DEBUG = BIT(1), - IWL_CTXT_INFO_ENABLE_CDMP = BIT(2), - IWL_CTXT_INFO_RB_CB_SIZE_POS = 4, - IWL_CTXT_INFO_TFD_FORMAT_LONG = BIT(8), - IWL_CTXT_INFO_RB_SIZE_POS = 9, + IWL_CTXT_INFO_AUTO_FUNC_INIT = 0x0001, + IWL_CTXT_INFO_EARLY_DEBUG = 0x0002, + IWL_CTXT_INFO_ENABLE_CDMP = 0x0004, + IWL_CTXT_INFO_RB_CB_SIZE = 0x00f0, + IWL_CTXT_INFO_TFD_FORMAT_LONG = 0x0100, + IWL_CTXT_INFO_RB_SIZE = 0x1e00, IWL_CTXT_INFO_RB_SIZE_1K = 0x1, IWL_CTXT_INFO_RB_SIZE_2K = 0x2, IWL_CTXT_INFO_RB_SIZE_4K = 0x4, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-csr.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-csr.h @@ -147,6 +147,16 @@ #define CSR_MAC_SHADOW_REG_CTL2 (CSR_BASE + 0x0AC) #define CSR_MAC_SHADOW_REG_CTL2_RX_WAKE 0xFFFF +/* LTR control (since IWL_DEVICE_FAMILY_22000) */ +#define CSR_LTR_LONG_VAL_AD (CSR_BASE + 0x0D4) +#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ 0x80000000 +#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE 0x1c000000 +#define CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL 0x03ff0000 +#define CSR_LTR_LONG_VAL_AD_SNOOP_REQ 0x00008000 +#define CSR_LTR_LONG_VAL_AD_SNOOP_SCALE 0x00001c00 +#define CSR_LTR_LONG_VAL_AD_SNOOP_VAL 0x000003ff +#define CSR_LTR_LONG_VAL_AD_SCALE_USEC 2 + /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) @@ -603,9 +613,7 @@ enum msix_hw_int_causes { MSIX_HW_INT_CAUSES_REG_ALIVE = BIT(0), MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1), - MSIX_HW_INT_CAUSES_REG_IPC = BIT(1), MSIX_HW_INT_CAUSES_REG_IML = BIT(2), - MSIX_HW_INT_CAUSES_REG_SW_ERR_V2 = BIT(5), MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6), MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7), MSIX_HW_INT_CAUSES_REG_PERIODIC = BIT(8), --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -183,6 +183,9 @@ for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) iwl_free_fw_img(drv, drv->fw.img + i); + + /* clear the data for the aborted load case */ + memset(&drv->fw, 0, sizeof(drv->fw)); } static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, @@ -1110,7 +1113,7 @@ if (tlv_len != sizeof(*fseq_ver)) goto invalid_tlv_len; - IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n", + IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n", fseq_ver->version); } break; @@ -1276,23 +1279,31 @@ const struct iwl_op_mode_ops *ops = op->ops; struct dentry *dbgfs_dir = NULL; struct iwl_op_mode *op_mode = NULL; + int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; + + for (retry = 0; retry <= max_retry; retry++) { #ifdef CONFIG_IWLWIFI_DEBUGFS - drv->dbgfs_op_mode = debugfs_create_dir(op->name, - drv->dbgfs_drv); - dbgfs_dir = drv->dbgfs_op_mode; + drv->dbgfs_op_mode = debugfs_create_dir(op->name, + drv->dbgfs_drv); + dbgfs_dir = drv->dbgfs_op_mode; #endif - op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir); + op_mode = ops->start(drv->trans, drv->trans->cfg, + &drv->fw, dbgfs_dir); + + if (op_mode) + return op_mode; + + IWL_ERR(drv, "retry init count %d\n", retry); #ifdef CONFIG_IWLWIFI_DEBUGFS - if (!op_mode) { debugfs_remove_recursive(drv->dbgfs_op_mode); drv->dbgfs_op_mode = NULL; - } #endif + } - return op_mode; + return NULL; } static void _iwl_op_mode_stop(struct iwl_drv *drv) @@ -1330,6 +1341,7 @@ int i; bool load_module = false; bool usniffer_images = false; + bool failure = true; fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; fw->ucode_capa.standard_phy_calibration_size = @@ -1587,15 +1599,9 @@ * else from proceeding if the module fails to load * or hangs loading. */ - if (load_module) { + if (load_module) request_module("%s", op->name); -#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR - if (err) - IWL_ERR(drv, - "failed to load module %s (error %d), is dynamic loading enabled?\n", - op->name, err); -#endif - } + failure = false; goto free; try_again: @@ -1610,7 +1616,12 @@ out_unbind: complete(&drv->request_firmware_complete); device_release_driver(drv->trans->dev); + /* drv has just been freed by the release */ + failure = false; free: + if (failure) + iwl_dealloc_ucode(drv); + if (pieces) { for (i = 0; i < ARRAY_SIZE(pieces->img); i++) kfree(pieces->img[i].sec); @@ -1658,8 +1669,8 @@ err_fw: #ifdef CONFIG_IWLWIFI_DEBUGFS debugfs_remove_recursive(drv->dbgfs_drv); - iwl_dbg_tlv_free(drv->trans); #endif + iwl_dbg_tlv_free(drv->trans); kfree(drv); err: return ERR_PTR(ret); @@ -1804,7 +1815,7 @@ "disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX"); module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size, int, 0444); MODULE_PARM_DESC(amsdu_size, - "amsdu size 0: 12K for multi Rx queue devices, 2K for 22560 devices, " + "amsdu size 0: 12K for multi Rx queue devices, 2K for AX210 devices, " "4K for other devices 1:4K 2:8K 3:12K 4: 2K (default 0)"); module_param_named(fw_restart, iwlwifi_mod_params.fw_restart, bool, 0444); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-drv.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-drv.h @@ -145,4 +145,7 @@ #define IWL_EXPORT_SYMBOL(sym) #endif +/* max retry for init flow */ +#define IWL_MAX_INIT_RETRY 2 + #endif /* __iwl_drv_h__ */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-fh.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-fh.h @@ -611,10 +611,7 @@ */ #define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002) -#define MQ_RX_TABLE_SIZE 512 -#define MQ_RX_TABLE_MASK (MQ_RX_TABLE_SIZE - 1) -#define MQ_RX_NUM_RBDS (MQ_RX_TABLE_SIZE - 1) -#define RX_POOL_SIZE (MQ_RX_NUM_RBDS + \ +#define RX_POOL_SIZE(rbds) ((rbds) - 1 + \ IWL_MAX_RX_HW_QUEUES * \ (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC)) /* cb size is the exponent */ @@ -768,7 +765,7 @@ /** * struct iwl_gen3_bc_tbl scheduler byte count table gen3 - * For 22560 and on: + * For AX210 and on: * @tfd_offset: 0-12 - tx command byte count * 12-13 - number of 64 byte chunks * 14-16 - reserved --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -225,6 +225,34 @@ NVM_CHANNEL_DC_HIGH = BIT(12), }; +/** + * enum iwl_reg_capa_flags - global flags applied for the whole regulatory + * domain. + * @REG_CAPA_BF_CCD_LOW_BAND: Beam-forming or Cyclic Delay Diversity in the + * 2.4Ghz band is allowed. + * @REG_CAPA_BF_CCD_HIGH_BAND: Beam-forming or Cyclic Delay Diversity in the + * 5Ghz band is allowed. + * @REG_CAPA_160MHZ_ALLOWED: 11ac channel with a width of 160Mhz is allowed + * for this regulatory domain (valid only in 5Ghz). + * @REG_CAPA_80MHZ_ALLOWED: 11ac channel with a width of 80Mhz is allowed + * for this regulatory domain (valid only in 5Ghz). + * @REG_CAPA_MCS_8_ALLOWED: 11ac with MCS 8 is allowed. + * @REG_CAPA_MCS_9_ALLOWED: 11ac with MCS 9 is allowed. + * @REG_CAPA_40MHZ_FORBIDDEN: 11n channel with a width of 40Mhz is forbidden + * for this regulatory domain (valid only in 5Ghz). + * @REG_CAPA_DC_HIGH_ENABLED: DC HIGH allowed. + */ +enum iwl_reg_capa_flags { + REG_CAPA_BF_CCD_LOW_BAND = BIT(0), + REG_CAPA_BF_CCD_HIGH_BAND = BIT(1), + REG_CAPA_160MHZ_ALLOWED = BIT(2), + REG_CAPA_80MHZ_ALLOWED = BIT(3), + REG_CAPA_MCS_8_ALLOWED = BIT(4), + REG_CAPA_MCS_9_ALLOWED = BIT(5), + REG_CAPA_40MHZ_FORBIDDEN = BIT(7), + REG_CAPA_DC_HIGH_ENABLED = BIT(9), +}; + static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, int chan, u32 flags) { @@ -491,14 +519,12 @@ .has_he = true, .he_cap_elem = { .mac_cap_info[0] = - IEEE80211_HE_MAC_CAP0_HTC_HE | - IEEE80211_HE_MAC_CAP0_TWT_REQ, + IEEE80211_HE_MAC_CAP0_HTC_HE, .mac_cap_info[1] = IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US | IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8, .mac_cap_info[2] = - IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP | - IEEE80211_HE_MAC_CAP2_ACK_EN, + IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP, .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL | IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, @@ -582,8 +608,7 @@ IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US | IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_8, .mac_cap_info[2] = - IEEE80211_HE_MAC_CAP2_BSR | - IEEE80211_HE_MAC_CAP2_ACK_EN, + IEEE80211_HE_MAC_CAP2_BSR, .mac_cap_info[3] = IEEE80211_HE_MAC_CAP3_OMI_CONTROL | IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2, @@ -1031,6 +1056,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan, int ch_idx, u16 nvm_flags, + u16 cap_flags, const struct iwl_cfg *cfg) { u32 flags = NL80211_RRF_NO_HT40; @@ -1069,13 +1095,27 @@ (flags & NL80211_RRF_NO_IR)) flags |= NL80211_RRF_GO_CONCURRENT; + /* + * cap_flags is per regulatory domain so apply it for every channel + */ + if (ch_idx >= NUM_2GHZ_CHANNELS) { + if (cap_flags & REG_CAPA_40MHZ_FORBIDDEN) + flags |= NL80211_RRF_NO_HT40; + + if (!(cap_flags & REG_CAPA_80MHZ_ALLOWED)) + flags |= NL80211_RRF_NO_80MHZ; + + if (!(cap_flags & REG_CAPA_160MHZ_ALLOWED)) + flags |= NL80211_RRF_NO_160MHZ; + } + return flags; } struct ieee80211_regdomain * iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, int num_of_ch, __le32 *channels, u16 fw_mcc, - u16 geo_info) + u16 geo_info, u16 cap) { int ch_idx; u16 ch_flags; @@ -1133,7 +1173,8 @@ } reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx, - ch_flags, cfg); + ch_flags, cap, + cfg); /* we can't continue the same rule */ if (ch_idx == 0 || prev_reg_rule_flags != reg_rule_flags || --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h @@ -7,7 +7,7 @@ * * Copyright(c) 2008 - 2015 Intel Corporation. All rights reserved. * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -29,7 +29,7 @@ * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 Intel Corporation + * Copyright(c) 2018 - 2019 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -103,7 +103,7 @@ struct ieee80211_regdomain * iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg, int num_of_ch, __le32 *channels, u16 fw_mcc, - u16 geo_info); + u16 geo_info, u16 cap); /** * struct iwl_nvm_section - describes an NVM section in memory. --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -66,7 +66,9 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_trans_ops *ops) + const struct iwl_trans_ops *ops, + unsigned int cmd_pool_size, + unsigned int cmd_pool_align) { struct iwl_trans *trans; #ifdef CONFIG_LOCKDEP @@ -90,10 +92,8 @@ "iwl_cmd_pool:%s", dev_name(trans->dev)); trans->dev_cmd_pool = kmem_cache_create(trans->dev_cmd_pool_name, - sizeof(struct iwl_device_cmd), - sizeof(void *), - SLAB_HWCACHE_ALIGN, - NULL); + cmd_pool_size, cmd_pool_align, + SLAB_HWCACHE_ALIGN, NULL); if (!trans->dev_cmd_pool) return NULL; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-trans.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/iwl-trans.h @@ -193,6 +193,18 @@ }; } __packed; +/** + * struct iwl_device_tx_cmd - buffer for TX command + * @hdr: the header + * @payload: the payload placeholder + * + * The actual structure is sized dynamically according to need. + */ +struct iwl_device_tx_cmd { + struct iwl_cmd_header hdr; + u8 payload[]; +} __packed; + #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) /* @@ -302,6 +314,7 @@ #define IWL_MGMT_TID 15 #define IWL_FRAME_LIMIT 64 #define IWL_MAX_RX_HW_QUEUES 16 +#define IWL_9000_MAX_RX_HW_QUEUES 6 /** * enum iwl_wowlan_status - WoWLAN image/device status @@ -544,7 +557,7 @@ int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd); int (*tx)(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int queue); + struct iwl_device_tx_cmd *dev_cmd, int queue); void (*reclaim)(struct iwl_trans *trans, int queue, int ssn, struct sk_buff_head *skbs); @@ -921,22 +934,22 @@ return trans->ops->dump_data(trans, dump_mask); } -static inline struct iwl_device_cmd * +static inline struct iwl_device_tx_cmd * iwl_trans_alloc_tx_cmd(struct iwl_trans *trans) { - return kmem_cache_alloc(trans->dev_cmd_pool, GFP_ATOMIC); + return kmem_cache_zalloc(trans->dev_cmd_pool, GFP_ATOMIC); } int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, - struct iwl_device_cmd *dev_cmd) + struct iwl_device_tx_cmd *dev_cmd) { kmem_cache_free(trans->dev_cmd_pool, dev_cmd); } static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int queue) + struct iwl_device_tx_cmd *dev_cmd, int queue) { if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status))) return -EIO; @@ -1239,7 +1252,9 @@ *****************************************************/ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size, struct device *dev, - const struct iwl_trans_ops *ops); + const struct iwl_trans_ops *ops, + unsigned int cmd_pool_size, + unsigned int cmd_pool_align); void iwl_trans_free(struct iwl_trans *trans); /***************************************************** --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/constants.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/constants.h @@ -154,5 +154,6 @@ #define IWL_MVM_D3_DEBUG false #define IWL_MVM_USE_TWT false #define IWL_MVM_AMPDU_CONSEC_DROPS_DELBA 10 +#define IWL_MVM_USE_NSSN_SYNC 0 #endif /* __MVM_CONSTANTS_H */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c @@ -514,7 +514,10 @@ const size_t bufsz = sizeof(buf); int pos = 0; + mutex_lock(&mvm->mutex); iwl_mvm_get_sync_time(mvm, &curr_gp2, &curr_os); + mutex_unlock(&mvm->mutex); + do_div(curr_os, NSEC_PER_USEC); diff = curr_os - curr_gp2; pos += scnprintf(buf + pos, bufsz - pos, "diff=%lld\n", diff); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -5,10 +5,9 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -28,10 +27,9 @@ * * BSD LICENSE * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -478,6 +476,11 @@ if (kstrtou16(buf, 0, &amsdu_len)) return -EINVAL; + /* only change from debug set <-> debug unset */ + if ((amsdu_len && mvmsta->orig_amsdu_len) || + (!!amsdu_len && mvmsta->orig_amsdu_len)) + return -EBUSY; + if (amsdu_len) { mvmsta->orig_amsdu_len = sta->max_amsdu_len; sta->max_amsdu_len = amsdu_len; @@ -1174,7 +1177,7 @@ int bin_len = count / 2; int ret = -EINVAL; size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) ? + IWL_DEVICE_FAMILY_AX210) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; @@ -1874,6 +1877,11 @@ if (ret < 0) return ret; + if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO; @@ -1951,6 +1959,11 @@ if (ret < 0) return ret; + if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { + ret = -EIO; + goto out; + } + rsp = (void *)hcmd.resp_pkt->data; if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) { ret = -ENXIO; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -8,6 +8,7 @@ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * Copyright (C) 2018 Intel Corporation * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,6 +31,7 @@ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH * Copyright (C) 2018 Intel Corporation * Copyright (C) 2019 Intel Corporation + * Copyright (C) 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -389,6 +391,8 @@ if (req != mvm->ftm_initiator.req) return; + iwl_mvm_ftm_reset(mvm); + if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD, LOCATION_GROUP, 0), 0, sizeof(cmd), &cmd)) @@ -502,7 +506,6 @@ lockdep_assert_held(&mvm->mutex); if (!mvm->ftm_initiator.req) { - IWL_ERR(mvm, "Got FTM response but have no request?\n"); return; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -134,7 +134,14 @@ .dataflags[0] = IWL_HCMD_DFL_NOCOPY, }; - /* Do not configure default queue, it is configured via context info */ + /* + * The default queue is configured via context info, so if we + * have a single queue, there's nothing to do here. + */ + if (mvm->trans->num_rx_queues == 1) + return 0; + + /* skip the default queue */ num_queues = mvm->trans->num_rx_queues - 1; size = struct_size(cmd, data, num_queues); @@ -190,20 +197,10 @@ { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_mfu_assert_dump_notif *mfu_dump_notif = (void *)pkt->data; - __le32 *dump_data = mfu_dump_notif->data; - int n_words = le32_to_cpu(mfu_dump_notif->data_size) / sizeof(__le32); - int i; if (mfu_dump_notif->index_num == 0) IWL_INFO(mvm, "MFUART assert id 0x%x occurred\n", le32_to_cpu(mfu_dump_notif->assert_id)); - - for (i = 0; i < n_words; i++) - IWL_DEBUG_INFO(mvm, - "MFUART assert dump, dword %u: 0x%08x\n", - le16_to_cpu(mfu_dump_notif->index_num) * - n_words + i, - le32_to_cpu(dump_data[i])); } static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait, @@ -514,6 +511,18 @@ struct iwl_phy_cfg_cmd phy_cfg_cmd; enum iwl_ucode_type ucode_type = mvm->fwrt.cur_fw_img; + if (iwl_mvm_has_unified_ucode(mvm) && + !mvm->trans->cfg->tx_with_siso_diversity) { + return 0; + } else if (mvm->trans->cfg->tx_with_siso_diversity) { + /* + * TODO: currently we don't set the antenna but letting the NIC + * to decide which antenna to use. This should come from BIOS. + */ + phy_cfg_cmd.phy_cfg = + cpu_to_le32(FW_PHY_CFG_CHAIN_SAD_ENABLED); + } + /* Set parameters */ phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm)); @@ -644,7 +653,7 @@ mvm->nvm_data->bands[0].n_channels = 1; mvm->nvm_data->bands[0].n_bitrates = 1; mvm->nvm_data->bands[0].bitrates = - (void *)mvm->nvm_data->channels + 1; + (void *)(mvm->nvm_data->channels + 1); mvm->nvm_data->bands[0].bitrates->hw_value = 10; } @@ -1169,15 +1178,22 @@ static int iwl_mvm_ppag_init(struct iwl_mvm *mvm) { - return -ENOENT; + return 0; } #endif /* CONFIG_ACPI */ +static void iwl_mvm_disconnect_iterator(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + if (vif->type == NL80211_IFTYPE_STATION) + ieee80211_hw_restart_disconnect(vif); +} + void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) { u32 error_log_size = mvm->fw->ucode_capa.error_log_size; + u32 status = 0; int ret; - u32 resp; struct iwl_fw_error_recovery_cmd recovery_cmd = { .flags = cpu_to_le32(flags), @@ -1185,7 +1201,6 @@ }; struct iwl_host_cmd host_cmd = { .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), - .flags = CMD_WANT_SKB, .data = {&recovery_cmd, }, .len = {sizeof(recovery_cmd), }, }; @@ -1205,7 +1220,7 @@ recovery_cmd.buf_size = cpu_to_le32(error_log_size); } - ret = iwl_mvm_send_cmd(mvm, &host_cmd); + ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status); kfree(mvm->error_recovery_buf); mvm->error_recovery_buf = NULL; @@ -1216,11 +1231,15 @@ /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ if (flags & ERROR_RECOVERY_UPDATE_DB) { - resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data); - if (resp) + if (status) { IWL_ERR(mvm, "Failed to send recovery cmd blob was invalid %d\n", - resp); + status); + + ieee80211_iterate_interfaces(mvm->hw, 0, + iwl_mvm_disconnect_iterator, + mvm); + } } } @@ -1344,12 +1363,12 @@ ret = iwl_send_phy_db_data(mvm->phy_db); if (ret) goto error; - - ret = iwl_send_phy_cfg_cmd(mvm); - if (ret) - goto error; } + ret = iwl_send_phy_cfg_cmd(mvm); + if (ret) + goto error; + ret = iwl_mvm_send_bt_init_conf(mvm); if (ret) goto error; @@ -1398,8 +1417,10 @@ while (!sband && i < NUM_NL80211_BANDS) sband = mvm->hw->wiphy->bands[i++]; - if (WARN_ON_ONCE(!sband)) + if (WARN_ON_ONCE(!sband)) { + ret = -ENODEV; goto error; + } chan = &sband->channels[0]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/led.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/led.c @@ -129,6 +129,9 @@ mvm->led.name = kasprintf(GFP_KERNEL, "%s-led", wiphy_name(mvm->hw->wiphy)); + if (!mvm->led.name) + return -ENOMEM; + mvm->led.brightness_set = iwl_led_brightness_set; mvm->led.max_brightness = 1; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1043,8 +1043,10 @@ return -ENOMEM; #ifdef CONFIG_IWLWIFI_DEBUGFS - if (mvm->beacon_inject_active) + if (mvm->beacon_inject_active) { + dev_kfree_skb(beacon); return -EBUSY; + } #endif ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -5,10 +5,9 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -28,10 +27,9 @@ * * BSD LICENSE * - * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -73,6 +71,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-op-mode.h" #include "iwl-io.h" #include "mvm.h" @@ -256,7 +255,8 @@ __le32_to_cpu(resp->n_channels), resp->channels, __le16_to_cpu(resp->mcc), - __le16_to_cpu(resp->geo_info)); + __le16_to_cpu(resp->geo_info), + __le16_to_cpu(resp->cap)); /* Store the return source id */ src_id = resp->source_id; kfree(resp); @@ -343,7 +343,6 @@ [0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING, [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, - [9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT, }; const static struct wiphy_iftype_ext_capab he_iftypes_ext_capa[] = { @@ -742,6 +741,20 @@ return ret; } +static void iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_sta *sta) +{ + if (likely(sta)) { + if (likely(iwl_mvm_tx_skb_sta(mvm, skb, sta) == 0)) + return; + } else { + if (likely(iwl_mvm_tx_skb_non_sta(mvm, skb) == 0)) + return; + } + + ieee80211_free_txskb(mvm->hw, skb); +} + static void iwl_mvm_mac_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) @@ -785,14 +798,7 @@ } } - if (sta) { - if (iwl_mvm_tx_skb(mvm, skb, sta)) - goto drop; - return; - } - - if (iwl_mvm_tx_skb_non_sta(mvm, skb)) - goto drop; + iwl_mvm_tx_skb(mvm, skb, sta); return; drop: ieee80211_free_txskb(hw, skb); @@ -842,10 +848,7 @@ break; } - if (!txq->sta) - iwl_mvm_tx_skb_non_sta(mvm, skb); - else - iwl_mvm_tx_skb(mvm, skb, txq->sta); + iwl_mvm_tx_skb(mvm, skb, txq->sta); } } while (atomic_dec_return(&mvmtxq->tx_request)); rcu_read_unlock(); @@ -1126,9 +1129,30 @@ { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); int ret; + int retry, max_retry = 0; mutex_lock(&mvm->mutex); - ret = __iwl_mvm_mac_start(mvm); + + /* we are starting the mac not in error flow, and restart is enabled */ + if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && + iwlwifi_mod_params.fw_restart) { + max_retry = IWL_MAX_INIT_RETRY; + /* + * This will prevent mac80211 recovery flows to trigger during + * init failures + */ + set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); + } + + for (retry = 0; retry <= max_retry; retry++) { + ret = __iwl_mvm_mac_start(mvm); + if (!ret) + break; + + IWL_ERR(mvm, "mac start retry %d\n", retry); + } + clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); + mutex_unlock(&mvm->mutex); return ret; @@ -1190,14 +1214,13 @@ */ flush_work(&mvm->roc_done_wk); + iwl_mvm_rm_aux_sta(mvm); + iwl_mvm_stop_device(mvm); iwl_mvm_async_handlers_purge(mvm); /* async_handlers_list is empty and will stay empty: HW is stopped */ - /* the fw is stopped, the aux sta is dead: clean up driver state */ - iwl_mvm_del_aux_sta(mvm); - /* * Clear IN_HW_RESTART and HW_RESTART_REQUESTED flag when stopping the * hw (as restart_complete() won't be called in this case) and mac80211 @@ -1672,6 +1695,7 @@ struct iwl_mvm_mc_iter_data iter_data = { .mvm = mvm, }; + int ret; lockdep_assert_held(&mvm->mutex); @@ -1681,6 +1705,22 @@ ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_mc_iface_iterator, &iter_data); + + /* + * Send a (synchronous) ech command so that we wait for the + * multiple asynchronous MCAST_FILTER_CMD commands sent by + * the interface iterator. Otherwise, we might get here over + * and over again (by userspace just sending a lot of these) + * and the CPU can send them faster than the firmware can + * process them. + * Note that the CPU is still faster - but with this we'll + * actually send fewer commands overall because the CPU will + * not schedule the work in mac80211 as frequently if it's + * still running when rescheduled (possibly multiple times). + */ + ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL); + if (ret) + IWL_ERR(mvm, "Failed to synchronize multicast groups update\n"); } static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw, @@ -2020,7 +2060,7 @@ rcu_read_lock(); sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]); - if (IS_ERR(sta)) { + if (IS_ERR_OR_NULL(sta)) { rcu_read_unlock(); WARN(1, "Can't find STA to configure HE\n"); return; @@ -2968,16 +3008,20 @@ void *_data) { struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data; + const struct cfg80211_bss_ies *ies; const struct element *elem; - elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data, - bss->ies->len); + rcu_read_lock(); + ies = rcu_dereference(bss->ies); + elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, ies->data, + ies->len); if (!elem || elem->datalen < 10 || !(elem->data[10] & WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) { data->tolerated = false; } + rcu_read_unlock(); } static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw, @@ -3020,7 +3064,7 @@ /* this would be a mac80211 bug ... but don't crash */ if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) - return -EINVAL; + return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ? 0 : -EINVAL; /* * If we are in a STA removal flow and in DQA mode: @@ -3067,6 +3111,9 @@ goto out_unlock; } + if (vif->type == NL80211_IFTYPE_STATION) + vif->bss_conf.he_support = sta->he_cap.has_he; + if (sta->tdls && (vif->p2p || iwl_mvm_tdls_sta_count(mvm, NULL) == @@ -3648,9 +3695,12 @@ tail->apply_time_max_delay = cpu_to_le32(delay); IWL_DEBUG_TE(mvm, - "ROC: Requesting to remain on channel %u for %ums (requested = %ums, max_delay = %ums, dtim_interval = %ums)\n", - channel->hw_value, req_dur, duration, delay, - dtim_interval); + "ROC: Requesting to remain on channel %u for %ums\n", + channel->hw_value, req_dur); + IWL_DEBUG_TE(mvm, + "\t(requested = %ums, max_delay = %ums, dtim_interval = %ums)\n", + duration, delay, dtim_interval); + /* Set the node address */ memcpy(tail->node_addr, vif->addr, ETH_ALEN); @@ -3717,6 +3767,7 @@ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct cfg80211_chan_def chandef; struct iwl_mvm_phy_ctxt *phy_ctxt; + bool band_change_removal; int ret, i; IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, @@ -3786,19 +3837,30 @@ cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); /* - * Change the PHY context configuration as it is currently referenced - * only by the P2P Device MAC + * Check if the remain-on-channel is on a different band and that + * requires context removal, see iwl_mvm_phy_ctxt_changed(). If + * so, we'll need to release and then re-configure here, since we + * must not remove a PHY context that's part of a binding. */ - if (mvmvif->phy_ctxt->ref == 1) { + band_change_removal = + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && + mvmvif->phy_ctxt->channel->band != chandef.chan->band; + + if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) { + /* + * Change the PHY context configuration as it is currently + * referenced only by the P2P Device MAC (and we can modify it) + */ ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt, &chandef, 1, 1); if (ret) goto out_unlock; } else { /* - * The PHY context is shared with other MACs. Need to remove the - * P2P Device from the binding, allocate an new PHY context and - * create a new binding + * The PHY context is shared with other MACs (or we're trying to + * switch bands), so remove the P2P Device from the binding, + * allocate an new PHY context and create a new binding. */ phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); if (!phy_ctxt) { @@ -4161,6 +4223,9 @@ iwl_mvm_binding_remove_vif(mvm, vif); out: + if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD) && + switching_chanctx) + return; mvmvif->phy_ctxt = NULL; iwl_mvm_power_update_mac(mvm); } @@ -4601,6 +4666,10 @@ int i; if (!iwl_mvm_has_new_tx_api(mvm)) { + /* we can't ask the firmware anything if it is dead */ + if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, + &mvm->status)) + return; if (drop) { mutex_lock(&mvm->mutex); iwl_mvm_flush_tx_path(mvm, @@ -4682,8 +4751,11 @@ /* this can take a while, and we may need/want other operations * to succeed while doing this, so do it without the mutex held + * If the firmware is dead, this can't work... */ - if (!drop && !iwl_mvm_has_new_tx_api(mvm)) + if (!drop && !iwl_mvm_has_new_tx_api(mvm) && + !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, + &mvm->status)) iwl_trans_wait_tx_queues_empty(mvm->trans, msk); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1167,6 +1167,8 @@ * @IWL_MVM_STATUS_ROC_AUX_RUNNING: AUX remain-on-channel is running * @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running * @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA + * @IWL_MVM_STATUS_STARTING: starting mac, + * used to disable restart flow while in STARTING state */ enum iwl_mvm_status { IWL_MVM_STATUS_HW_RFKILL, @@ -1177,6 +1179,7 @@ IWL_MVM_STATUS_ROC_AUX_RUNNING, IWL_MVM_STATUS_FIRMWARE_RUNNING, IWL_MVM_STATUS_NEED_FLUSH_P2P, + IWL_MVM_STATUS_STARTING, }; /* Keep track of completed init configuration */ @@ -1508,8 +1511,8 @@ int __must_check iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len, const void *data, u32 *status); -int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, - struct ieee80211_sta *sta); +int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_sta *sta); int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb); void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, struct iwl_tx_cmd *tx_cmd, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c @@ -281,7 +281,7 @@ int regulatory_type; /* Checking for required sections */ - if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) { + if (mvm->trans->cfg->nvm_type == IWL_NVM) { if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n"); @@ -309,7 +309,8 @@ } /* PHY_SKU section is mandatory in B0 */ - if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { + if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT && + !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { IWL_ERR(mvm, "Can't parse phy_sku in B0, empty sections\n"); return NULL; @@ -507,6 +508,11 @@ struct iwl_mcc_update_resp *mcc_resp = (void *)pkt->data; n_channels = __le32_to_cpu(mcc_resp->n_channels); + if (iwl_rx_packet_payload_len(pkt) != + struct_size(mcc_resp, channels, n_channels)) { + resp_cp = ERR_PTR(-EINVAL); + goto exit; + } resp_len = sizeof(struct iwl_mcc_update_resp) + n_channels * sizeof(__le32); resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL); @@ -518,6 +524,11 @@ struct iwl_mcc_update_resp_v3 *mcc_resp_v3 = (void *)pkt->data; n_channels = __le32_to_cpu(mcc_resp_v3->n_channels); + if (iwl_rx_packet_payload_len(pkt) != + struct_size(mcc_resp_v3, channels, n_channels)) { + resp_cp = ERR_PTR(-EINVAL); + goto exit; + } resp_len = sizeof(struct iwl_mcc_update_resp) + n_channels * sizeof(__le32); resp_cp = kzalloc(resp_len, GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -316,6 +316,12 @@ iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC), RX_HANDLER_GRP(DATA_PATH_GROUP, STA_PM_NOTIF, iwl_mvm_sta_pm_notif, RX_HANDLER_SYNC), + RX_HANDLER_GRP(MAC_CONF_GROUP, PROBE_RESPONSE_DATA_NOTIF, + iwl_mvm_probe_resp_data_notif, + RX_HANDLER_ASYNC_LOCKED), + RX_HANDLER_GRP(MAC_CONF_GROUP, CHANNEL_SWITCH_NOA_NOTIF, + iwl_mvm_channel_switch_noa_notif, + RX_HANDLER_SYNC), }; #undef RX_HANDLER #undef RX_HANDLER_GRP @@ -667,7 +673,7 @@ op_mode->ops = &iwl_mvm_ops_mq; trans->rx_mpdu_cmd_hdr_size = (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) ? + IWL_DEVICE_FAMILY_AX210) ? sizeof(struct iwl_rx_mpdu_desc) : IWL_RX_DESC_SIZE_V1; } else { @@ -681,10 +687,26 @@ mvm->fw_restart = iwlwifi_mod_params.fw_restart ? -1 : 0; - mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; - mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE; - mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE; - mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE; + if (iwl_mvm_has_new_tx_api(mvm)) { + /* + * If we have the new TX/queue allocation API initialize them + * all to invalid numbers. We'll rewrite the ones that we need + * later, but that doesn't happen for all of them all of the + * time (e.g. P2P Device is optional), and if a dynamic queue + * ends up getting number 2 (IWL_MVM_DQA_P2P_DEVICE_QUEUE) then + * iwl_mvm_is_static_queue() erroneously returns true, and we + * might have things getting stuck. + */ + mvm->aux_queue = IWL_MVM_INVALID_QUEUE; + mvm->snif_queue = IWL_MVM_INVALID_QUEUE; + mvm->probe_queue = IWL_MVM_INVALID_QUEUE; + mvm->p2p_dev_queue = IWL_MVM_INVALID_QUEUE; + } else { + mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; + mvm->snif_queue = IWL_MVM_DQA_INJECT_MONITOR_QUEUE; + mvm->probe_queue = IWL_MVM_DQA_AP_PROBE_RESP_QUEUE; + mvm->p2p_dev_queue = IWL_MVM_DQA_P2P_DEVICE_QUEUE; + } mvm->sf_state = SF_UNINIT; if (iwl_mvm_has_unified_ucode(mvm)) @@ -730,7 +752,7 @@ trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) rb_size_default = IWL_AMSDU_2K; else rb_size_default = IWL_AMSDU_4K; @@ -756,7 +778,7 @@ trans->wide_cmd_header = true; trans_cfg.bc_table_dword = - mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560; + mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210; trans_cfg.command_groups = iwl_mvm_groups; trans_cfg.command_groups_size = ARRAY_SIZE(iwl_mvm_groups); @@ -832,6 +854,10 @@ if (!mvm->scan_cmd) goto out_free; + /* invalidate ids to prevent accidental removal of sta_id 0 */ + mvm->aux_sta.sta_id = IWL_MVM_INVALID_STA; + mvm->snif_sta.sta_id = IWL_MVM_INVALID_STA; + /* Set EBS as successful as long as not stated otherwise by the FW. */ mvm->last_ebs_successful = true; @@ -1141,8 +1167,11 @@ mvmtxq = iwl_mvm_txq_from_mac80211(txq); mvmtxq->stopped = !start; - if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) + if (start && mvmsta->sta_state != IEEE80211_STA_NOTEXIST) { + local_bh_disable(); iwl_mvm_mac_itxq_xmit(mvm->hw, txq); + local_bh_enable(); + } } out: @@ -1232,6 +1261,7 @@ reprobe = container_of(wk, struct iwl_mvm_reprobe, work); if (device_reprobe(reprobe->dev)) dev_err(reprobe->dev, "reprobe failed!\n"); + put_device(reprobe->dev); kfree(reprobe); module_put(THIS_MODULE); } @@ -1261,6 +1291,9 @@ */ if (!mvm->fw_restart && fw_error) { iwl_fw_error_collect(&mvm->fwrt); + } else if (test_bit(IWL_MVM_STATUS_STARTING, + &mvm->status)) { + IWL_ERR(mvm, "Starting mac, retry will be triggered anyway\n"); } else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { struct iwl_mvm_reprobe *reprobe; @@ -1282,7 +1315,7 @@ module_put(THIS_MODULE); return; } - reprobe->dev = mvm->trans->dev; + reprobe->dev = get_device(mvm->trans->dev); INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); schedule_work(&reprobe->work); } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/power.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/power.c @@ -626,6 +626,9 @@ struct iwl_power_vifs *power_iterator = _data; bool active = mvmvif->phy_ctxt && mvmvif->phy_ctxt->id < NUM_PHY_CTX; + if (!mvmvif->uploaded) + return; + switch (ieee80211_vif_type_p2p(vif)) { case NL80211_IFTYPE_P2P_DEVICE: break; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -27,7 +27,7 @@ * BSD LICENSE * * Copyright(c) 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -147,7 +147,11 @@ (vht_ena && (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)))) flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; - /* consider our LDPC support in case of HE */ + /* consider LDPC support in case of HE */ + if (he_cap->has_he && (he_cap->he_cap_elem.phy_cap_info[1] & + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) + flags |= IWL_TLC_MNG_CFG_FLAGS_LDPC_MSK; + if (sband->iftype_data && sband->iftype_data->he_cap.has_he && !(sband->iftype_data->he_cap.he_cap_elem.phy_cap_info[1] & IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)) @@ -191,11 +195,13 @@ { u16 supp; int i, highest_mcs; + u8 nss = sta->rx_nss; - for (i = 0; i < sta->rx_nss; i++) { - if (i == IWL_TLC_NSS_MAX) - break; + /* the station support only a single receive chain */ + if (sta->smps_mode == IEEE80211_SMPS_STATIC) + nss = 1; + for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { highest_mcs = rs_fw_vht_highest_rx_mcs_index(vht_cap, i + 1); if (!highest_mcs) continue; @@ -241,8 +247,13 @@ u16 tx_mcs_160 = le16_to_cpu(sband->iftype_data->he_cap.he_mcs_nss_supp.tx_mcs_160); int i; + u8 nss = sta->rx_nss; + + /* the station support only a single receive chain */ + if (sta->smps_mode == IEEE80211_SMPS_STATIC) + nss = 1; - for (i = 0; i < sta->rx_nss && i < IWL_TLC_NSS_MAX; i++) { + for (i = 0; i < nss && i < IWL_TLC_NSS_MAX; i++) { u16 _mcs_160 = (mcs_160 >> (2 * i)) & 0x3; u16 _mcs_80 = (mcs_80 >> (2 * i)) & 0x3; u16 _tx_mcs_160 = (tx_mcs_160 >> (2 * i)) & 0x3; @@ -303,8 +314,14 @@ cmd->mode = IWL_TLC_MNG_MODE_HT; cmd->ht_rates[IWL_TLC_NSS_1][IWL_TLC_HT_BW_NONE_160] = cpu_to_le16(ht_cap->mcs.rx_mask[0]); - cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = - cpu_to_le16(ht_cap->mcs.rx_mask[1]); + + /* the station support only a single receive chain */ + if (sta->smps_mode == IEEE80211_SMPS_STATIC) + cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = + 0; + else + cmd->ht_rates[IWL_TLC_NSS_2][IWL_TLC_HT_BW_NONE_160] = + cpu_to_le16(ht_cap->mcs.rx_mask[1]); } } @@ -350,8 +367,15 @@ u16 size = le32_to_cpu(notif->amsdu_size); int i; - if (WARN_ON(sta->max_amsdu_len < size)) + if (sta->max_amsdu_len < size) { + /* + * In debug sta->max_amsdu_len < size + * so also check with orig_amsdu_len which holds the + * original data before debugfs changed the value + */ + WARN_ON(mvmsta->orig_amsdu_len < size); goto out; + } mvmsta->amsdu_enabled = le32_to_cpu(notif->amsdu_enabled); mvmsta->max_amsdu_len = size; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -3663,7 +3663,7 @@ cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta)); } -static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +static void *rs_alloc(struct ieee80211_hw *hw) { return hw->priv; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/rs.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/rs.h @@ -133,13 +133,8 @@ #define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) #define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) -/* - * FIXME - various places in firmware API still use u8, - * e.g. LQ command and SCD config command. - * This should be 256 instead. - */ -#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (255) -#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (255) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_DEF (64) +#define LINK_QUAL_AGG_FRAME_LIMIT_GEN2_MAX (64) #define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * Copyright(c) 2016 - 2017 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,6 +60,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include #include #include #include "iwl-trans.h" @@ -357,7 +358,7 @@ rx_res = (struct iwl_rx_mpdu_res_start *)pkt->data; hdr = (struct ieee80211_hdr *)(pkt->data + sizeof(*rx_res)); len = le16_to_cpu(rx_res->byte_count); - rx_pkt_status = le32_to_cpup((__le32 *) + rx_pkt_status = get_unaligned_le32((__le32 *) (pkt->data + sizeof(*rx_res) + len)); /* Dont use dev_alloc_skb(), we'll have enough headroom once @@ -565,6 +566,7 @@ struct iwl_mvm_stat_data { struct iwl_mvm *mvm; + __le32 flags; __le32 mac_id; u8 beacon_filter_average_energy; void *general; @@ -605,6 +607,13 @@ -general->beacon_average_energy[vif_id]; } + /* make sure that beacon statistics don't go backwards with TCM + * request to clear statistics + */ + if (le32_to_cpu(data->flags) & IWL_STATISTICS_REPLY_FLG_CLEAR) + mvmvif->beacon_stats.accu_num_beacons += + mvmvif->beacon_stats.num_beacons; + if (mvmvif->id != id) return; @@ -762,6 +771,7 @@ flags = stats->flag; } + data.flags = flags; iwl_mvm_rx_stats_check_trigger(mvm, pkt); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c @@ -177,12 +177,39 @@ struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; unsigned int headlen, fraglen, pad_len = 0; unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); + u8 mic_crc_len = u8_get_bits(desc->mac_flags1, + IWL_RX_MPDU_MFLG1_MIC_CRC_LEN_MASK) << 1; if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) { len -= 2; pad_len = 2; } + /* + * For non monitor interface strip the bytes the RADA might not have + * removed. As monitor interface cannot exist with other interfaces + * this removal is safe. + */ + if (mic_crc_len && !ieee80211_hw_check(mvm->hw, RX_INCLUDES_FCS)) { + u32 pkt_flags = le32_to_cpu(pkt->len_n_flags); + + /* + * If RADA was not enabled then decryption was not performed so + * the MIC cannot be removed. + */ + if (!(pkt_flags & FH_RSCSR_RADA_EN)) { + if (WARN_ON(crypt_len > mic_crc_len)) + return -EINVAL; + + mic_crc_len -= crypt_len; + } + + if (WARN_ON(mic_crc_len > len)) + return -EINVAL; + + len -= mic_crc_len; + } + /* If frame is small enough to fit in skb->head, pull it completely. * If not, only pull ieee80211_hdr (including crypto if present, and * an additional 8 bytes for SNAP/ethertype, see below) so that @@ -514,14 +541,17 @@ static void iwl_mvm_sync_nssn(struct iwl_mvm *mvm, u8 baid, u16 nssn) { - struct iwl_mvm_rss_sync_notif notif = { - .metadata.type = IWL_MVM_RXQ_NSSN_SYNC, - .metadata.sync = 0, - .nssn_sync.baid = baid, - .nssn_sync.nssn = nssn, - }; + if (IWL_MVM_USE_NSSN_SYNC) { + struct iwl_mvm_rss_sync_notif notif = { + .metadata.type = IWL_MVM_RXQ_NSSN_SYNC, + .metadata.sync = 0, + .nssn_sync.baid = baid, + .nssn_sync.nssn = nssn, + }; - iwl_mvm_sync_rx_queues_internal(mvm, (void *)¬if, sizeof(notif)); + iwl_mvm_sync_rx_queues_internal(mvm, (void *)¬if, + sizeof(notif)); + } } #define RX_REORDER_BUF_TIMEOUT_MQ (HZ / 10) @@ -1565,7 +1595,7 @@ if (unlikely(test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))) return; - if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (mvm->trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { rate_n_flags = le32_to_cpu(desc->v3.rate_n_flags); channel = desc->v3.channel; gp2_on_air_rise = le32_to_cpu(desc->v3.gp2_on_air_rise); @@ -1667,7 +1697,7 @@ u64 tsf_on_air_rise; if (mvm->trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) + IWL_DEVICE_FAMILY_AX210) tsf_on_air_rise = le64_to_cpu(desc->v3.tsf_on_air_rise); else tsf_on_air_rise = le64_to_cpu(desc->v1.tsf_on_air_rise); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -93,6 +93,8 @@ /* adaptive dwell default APs number in social channels (1, 6, 11) */ #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10 +#define WFA_TPC_IE_LEN 9 + struct iwl_mvm_scan_timing_params { u32 suspend_time; u32 max_out_time; @@ -378,8 +380,8 @@ max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE; - /* we create the 802.11 header and SSID element */ - max_probe_len -= 24 + 2; + /* we create the 802.11 header SSID element and WFA TPC element */ + max_probe_len -= 24 + 2 + WFA_TPC_IE_LEN; /* DS parameter set element is added on 2.4GHZ band if required */ if (iwl_mvm_rrm_scan_needed(mvm)) @@ -776,8 +778,6 @@ return newpos; } -#define WFA_TPC_IE_LEN 9 - static void iwl_mvm_add_tpc_report_ie(u8 *pos) { pos[0] = WLAN_EID_VENDOR_SPECIFIC; @@ -1220,7 +1220,7 @@ cmd_size = sizeof(struct iwl_scan_config_v2); else cmd_size = sizeof(struct iwl_scan_config_v1); - cmd_size += num_channels; + cmd_size += mvm->fw->ucode_capa.n_scan_channels; cfg = kzalloc(cmd_size, GFP_KERNEL); if (!cfg) @@ -1339,7 +1339,7 @@ if (IWL_MVM_ADWELL_MAX_BUDGET) cmd->v7.adwell_max_budget = cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET); - else if (params->ssids && params->ssids[0].ssid_len) + else if (params->n_ssids && params->ssids[0].ssid_len) cmd->v7.adwell_max_budget = cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN); else @@ -1700,7 +1700,7 @@ return -EIO; } -#define SCAN_TIMEOUT 20000 +#define SCAN_TIMEOUT 30000 void iwl_mvm_scan_timeout_wk(struct work_struct *work) { @@ -2140,7 +2140,7 @@ if (!(mvm->scan_status & type)) return 0; - if (iwl_mvm_is_radio_killed(mvm)) { + if (!test_bit(STATUS_DEVICE_ENABLED, &mvm->trans->status)) { ret = 0; goto out; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -346,8 +346,9 @@ } static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - int queue, u8 tid, u8 flags) + u16 *queueptr, u8 tid, u8 flags) { + int queue = *queueptr; struct iwl_scd_txq_cfg_cmd cmd = { .scd_queue = queue, .action = SCD_CFG_DISABLE_QUEUE, @@ -356,6 +357,7 @@ if (iwl_mvm_has_new_tx_api(mvm)) { iwl_trans_txq_free(mvm->trans, queue); + *queueptr = IWL_MVM_INVALID_QUEUE; return 0; } @@ -517,6 +519,7 @@ u8 sta_id, tid; unsigned long disable_agg_tids = 0; bool same_sta; + u16 queue_tmp = queue; int ret; lockdep_assert_held(&mvm->mutex); @@ -539,7 +542,7 @@ iwl_mvm_invalidate_sta_queue(mvm, queue, disable_agg_tids, false); - ret = iwl_mvm_disable_txq(mvm, old_sta, queue, tid, 0); + ret = iwl_mvm_disable_txq(mvm, old_sta, &queue_tmp, tid, 0); if (ret) { IWL_ERR(mvm, "Failed to free inactive queue %d (ret=%d)\n", @@ -722,6 +725,11 @@ lockdep_assert_held(&mvm->mutex); + if (WARN(maxq >= mvm->trans->trans_cfg->base_params->num_of_queues, + "max queue %d >= num_of_queues (%d)", maxq, + mvm->trans->trans_cfg->base_params->num_of_queues)) + maxq = mvm->trans->trans_cfg->base_params->num_of_queues - 1; + /* This should not be hit with new TX path */ if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) return -ENOSPC; @@ -1164,9 +1172,9 @@ inactive_tid_bitmap, &unshare_queues, &changetid_queues); - if (ret >= 0 && free_queue < 0) { + if (ret && free_queue < 0) { queue_owner = sta; - free_queue = ret; + free_queue = i; } /* only unlock sta lock - we still need the queue info lock */ spin_unlock_bh(&mvmsta->lock); @@ -1179,17 +1187,15 @@ for_each_set_bit(i, &changetid_queues, IWL_MAX_HW_QUEUES) iwl_mvm_change_queue_tid(mvm, i); + rcu_read_unlock(); + if (free_queue >= 0 && alloc_for_sta != IWL_MVM_INVALID_STA) { ret = iwl_mvm_free_inactive_queue(mvm, free_queue, queue_owner, alloc_for_sta); - if (ret) { - rcu_read_unlock(); + if (ret) return ret; - } } - rcu_read_unlock(); - return free_queue; } @@ -1206,6 +1212,7 @@ unsigned int wdg_timeout = iwl_mvm_get_wd_timeout(mvm, mvmsta->vif, false, false); int queue = -1; + u16 queue_tmp; unsigned long disable_agg_tids = 0; enum iwl_mvm_agg_state queue_state; bool shared_queue = false, inc_ssn; @@ -1354,7 +1361,8 @@ return 0; out_err: - iwl_mvm_disable_txq(mvm, sta, queue, tid, 0); + queue_tmp = queue; + iwl_mvm_disable_txq(mvm, sta, &queue_tmp, tid, 0); return ret; } @@ -1792,7 +1800,7 @@ if (mvm_sta->tid_data[i].txq_id == IWL_MVM_INVALID_QUEUE) continue; - iwl_mvm_disable_txq(mvm, sta, mvm_sta->tid_data[i].txq_id, i, + iwl_mvm_disable_txq(mvm, sta, &mvm_sta->tid_data[i].txq_id, i, 0); mvm_sta->tid_data[i].txq_id = IWL_MVM_INVALID_QUEUE; } @@ -1802,6 +1810,7 @@ iwl_mvm_txq_from_mac80211(sta->txq[i]); mvmtxq->txq_id = IWL_MVM_INVALID_QUEUE; + list_del_init(&mvmtxq->list); } } @@ -2002,7 +2011,7 @@ ret = iwl_mvm_add_int_sta_common(mvm, sta, NULL, macidx, maccolor); if (ret) { if (!iwl_mvm_has_new_tx_api(mvm)) - iwl_mvm_disable_txq(mvm, NULL, *queue, + iwl_mvm_disable_txq(mvm, NULL, queue, IWL_MAX_TID_COUNT, 0); return ret; } @@ -2067,7 +2076,10 @@ lockdep_assert_held(&mvm->mutex); - iwl_mvm_disable_txq(mvm, NULL, mvm->snif_queue, IWL_MAX_TID_COUNT, 0); + if (WARN_ON_ONCE(mvm->snif_sta.sta_id == IWL_MVM_INVALID_STA)) + return -EINVAL; + + iwl_mvm_disable_txq(mvm, NULL, &mvm->snif_queue, IWL_MAX_TID_COUNT, 0); ret = iwl_mvm_rm_sta_common(mvm, mvm->snif_sta.sta_id); if (ret) IWL_WARN(mvm, "Failed sending remove station\n"); @@ -2075,16 +2087,27 @@ return ret; } -void iwl_mvm_dealloc_snif_sta(struct iwl_mvm *mvm) +int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm) { - iwl_mvm_dealloc_int_sta(mvm, &mvm->snif_sta); -} + int ret; -void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm) -{ lockdep_assert_held(&mvm->mutex); + if (WARN_ON_ONCE(mvm->aux_sta.sta_id == IWL_MVM_INVALID_STA)) + return -EINVAL; + + iwl_mvm_disable_txq(mvm, NULL, &mvm->aux_queue, IWL_MAX_TID_COUNT, 0); + ret = iwl_mvm_rm_sta_common(mvm, mvm->aux_sta.sta_id); + if (ret) + IWL_WARN(mvm, "Failed sending remove station\n"); iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta); + + return ret; +} + +void iwl_mvm_dealloc_snif_sta(struct iwl_mvm *mvm) +{ + iwl_mvm_dealloc_int_sta(mvm, &mvm->snif_sta); } /* @@ -2169,7 +2192,7 @@ struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - int queue; + u16 *queueptr, queue; lockdep_assert_held(&mvm->mutex); @@ -2178,10 +2201,10 @@ switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: - queue = mvm->probe_queue; + queueptr = &mvm->probe_queue; break; case NL80211_IFTYPE_P2P_DEVICE: - queue = mvm->p2p_dev_queue; + queueptr = &mvm->p2p_dev_queue; break; default: WARN(1, "Can't free bcast queue on vif type %d\n", @@ -2189,7 +2212,8 @@ return; } - iwl_mvm_disable_txq(mvm, NULL, queue, IWL_MAX_TID_COUNT, 0); + queue = *queueptr; + iwl_mvm_disable_txq(mvm, NULL, queueptr, IWL_MAX_TID_COUNT, 0); if (iwl_mvm_has_new_tx_api(mvm)) return; @@ -2424,7 +2448,7 @@ iwl_mvm_flush_sta(mvm, &mvmvif->mcast_sta, true, 0); - iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0); + iwl_mvm_disable_txq(mvm, NULL, &mvmvif->cab_queue, 0, 0); ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); if (ret) @@ -2533,7 +2557,7 @@ } if (iwl_mvm_has_new_rx_api(mvm) && start) { - u16 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); + u32 reorder_buf_size = buf_size * sizeof(baid_data->entries[0]); /* sparse doesn't like the __align() so don't check */ #ifndef __CHECKER__ @@ -2844,13 +2868,12 @@ if (normalized_ssn == tid_data->next_reclaimed) { tid_data->state = IWL_AGG_STARTING; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; } else { tid_data->state = IWL_EMPTYING_HW_QUEUE_ADDBA; + ret = 0; } - ret = 0; - out: spin_unlock_bh(&mvmsta->lock); @@ -3321,6 +3344,10 @@ igtk_cmd.sta_id = cpu_to_le32(sta_id); if (remove_key) { + /* This is a valid situation for IGTK */ + if (sta_id == IWL_MVM_INVALID_STA) + return 0; + igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID); } else { struct ieee80211_key_seq seq; @@ -3575,9 +3602,9 @@ IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n", keyconf->keyidx, sta_id); - if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || - keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || - keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)) + if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC || + keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 || + keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256) return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true); if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/sta.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/sta.h @@ -8,7 +8,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -31,7 +31,7 @@ * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * Copyright(c) 2015 - 2016 Intel Deutschland GmbH - * Copyright(c) 2018 - 2019 Intel Corporation + * Copyright(c) 2018 - 2020 Intel Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -541,7 +541,7 @@ int tid, u8 queue, bool start); int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); -void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm); +int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm); int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/tt.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/tt.c @@ -731,7 +731,8 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm) { int i; - char name[] = "iwlwifi"; + char name[16]; + static atomic_t counter = ATOMIC_INIT(0); if (!iwl_mvm_is_tt_in_fw(mvm)) { mvm->tz_device.tzone = NULL; @@ -741,6 +742,7 @@ BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH); + sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF); mvm->tz_device.tzone = thermal_zone_device_register(name, IWL_MAX_DTS_TRIPS, IWL_WRITABLE_TRIPS_MSK, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -487,13 +487,13 @@ /* * Allocates and sets the Tx cmd the driver data pointers in the skb */ -static struct iwl_device_cmd * +static struct iwl_device_tx_cmd * iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, struct ieee80211_tx_info *info, int hdrlen, struct ieee80211_sta *sta, u8 sta_id) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_device_cmd *dev_cmd; + struct iwl_device_tx_cmd *dev_cmd; struct iwl_tx_cmd *tx_cmd; dev_cmd = iwl_trans_alloc_tx_cmd(mvm->trans); @@ -501,11 +501,6 @@ if (unlikely(!dev_cmd)) return NULL; - /* Make sure we zero enough of dev_cmd */ - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen2) > sizeof(*tx_cmd)); - BUILD_BUG_ON(sizeof(struct iwl_tx_cmd_gen3) > sizeof(*tx_cmd)); - - memset(dev_cmd, 0, sizeof(dev_cmd->hdr) + sizeof(*tx_cmd)); dev_cmd->hdr.cmd = TX_CMD; if (iwl_mvm_has_new_tx_api(mvm)) { @@ -534,20 +529,24 @@ flags |= IWL_TX_FLAGS_ENCRYPT_DIS; /* - * For data packets rate info comes from the fw. Only - * set rate/antenna during connection establishment or in case - * no station is given. + * For data and mgmt packets rate info comes from the fw. Only + * set rate/antenna for injected frames with fixed rate, or + * when no sta is given. */ - if (!sta || !ieee80211_is_data(hdr->frame_control) || - mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { + if (unlikely(!sta || + info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) { flags |= IWL_TX_FLAGS_CMD_RATE; rate_n_flags = iwl_mvm_get_tx_rate_n_flags(mvm, info, sta, hdr->frame_control); + } else if (!ieee80211_is_data(hdr->frame_control) || + mvmsta->sta_state < IEEE80211_STA_AUTHORIZED) { + /* These are important frames */ + flags |= IWL_TX_FLAGS_HIGH_PRI; } if (mvm->trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) { + IWL_DEVICE_FAMILY_AX210) { struct iwl_tx_cmd_gen3 *cmd = (void *)dev_cmd->payload; cmd->offload_assist |= cpu_to_le32(offload_assist); @@ -594,7 +593,7 @@ } static void iwl_mvm_skb_prepare_status(struct sk_buff *skb, - struct iwl_device_cmd *cmd) + struct iwl_device_tx_cmd *cmd) { struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); @@ -713,7 +712,7 @@ { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info info; - struct iwl_device_cmd *dev_cmd; + struct iwl_device_tx_cmd *dev_cmd; u8 sta_id; int hdrlen = ieee80211_hdrlen(hdr->frame_control); __le16 fc = hdr->frame_control; @@ -935,7 +934,12 @@ !(mvmsta->amsdu_enabled & BIT(tid))) return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb); - max_amsdu_len = iwl_mvm_max_amsdu_size(mvm, sta, tid); + /* + * Take the min of ieee80211 station and mvm station + */ + max_amsdu_len = + min_t(unsigned int, sta->max_amsdu_len, + iwl_mvm_max_amsdu_size(mvm, sta, tid)); /* * Limit A-MSDU in A-MPDU to 4095 bytes when VHT is not @@ -1070,7 +1074,7 @@ { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl_mvm_sta *mvmsta; - struct iwl_device_cmd *dev_cmd; + struct iwl_device_tx_cmd *dev_cmd; __le16 fc; u16 seq_number = 0; u8 tid = IWL_MAX_TID_COUNT; @@ -1091,6 +1095,9 @@ if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) return -1; + if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->he_cap.has_he) + return -1; + if (unlikely(ieee80211_is_probe_resp(fc))) iwl_mvm_probe_resp_set_noa(mvm, skb); @@ -1146,7 +1153,7 @@ if (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) { iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); spin_unlock(&mvmsta->lock); - return 0; + return -1; } if (!iwl_mvm_has_new_tx_api(mvm)) { @@ -1198,14 +1205,15 @@ return -1; } -int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, - struct ieee80211_sta *sta) +int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_sta *sta) { struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); struct ieee80211_tx_info info; struct sk_buff_head mpdus_skbs; unsigned int payload_len; int ret; + struct sk_buff *orig_skb = skb; if (WARN_ON_ONCE(!mvmsta)) return -1; @@ -1238,8 +1246,17 @@ ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta); if (ret) { + /* Free skbs created as part of TSO logic that have not yet been dequeued */ __skb_queue_purge(&mpdus_skbs); - return ret; + /* skb here is not necessarily same as skb that entered this method, + * so free it explicitly. + */ + if (skb == orig_skb) + ieee80211_free_txskb(mvm->hw, skb); + else + kfree_skb(skb); + /* there was error, but we consumed skb one way or another, so return 0 */ + return 0; } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -758,6 +758,9 @@ lockdep_assert_held(&mvm->mutex); + if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) + return false; + if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1) return false; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -63,7 +63,6 @@ struct iwl_prph_scratch *prph_scratch; struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl; struct iwl_prph_info *prph_info; - void *iml_img; u32 control_flags = 0; int ret; int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE, @@ -155,19 +154,22 @@ ctxt_info_gen3->mtr_size = cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size)); ctxt_info_gen3->mcr_size = - cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE)); + cpu_to_le16(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds)); trans_pcie->ctxt_info_gen3 = ctxt_info_gen3; trans_pcie->prph_info = prph_info; trans_pcie->prph_scratch = prph_scratch; /* Allocate IML */ - iml_img = dma_alloc_coherent(trans->dev, trans->iml_len, - &trans_pcie->iml_dma_addr, GFP_KERNEL); - if (!iml_img) - return -ENOMEM; + trans_pcie->iml = dma_alloc_coherent(trans->dev, trans->iml_len, + &trans_pcie->iml_dma_addr, + GFP_KERNEL); + if (!trans_pcie->iml) { + ret = -ENOMEM; + goto err_free_ctxt_info; + } - memcpy(iml_img, trans->iml, trans->iml_len); + memcpy(trans_pcie->iml, trans->iml, trans->iml_len); iwl_enable_fw_load_int_ctx_info(trans); @@ -180,6 +182,26 @@ iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); + + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) { + /* + * The firmware initializes this again later (to a smaller + * value), but for the boot process initialize the LTR to + * ~250 usec. + */ + u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, + CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) | + u32_encode_bits(250, + CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) | + CSR_LTR_LONG_VAL_AD_SNOOP_REQ | + u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC, + CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) | + u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL); + + iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val); + } + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1); else @@ -187,6 +209,11 @@ return 0; +err_free_ctxt_info: + dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3), + trans_pcie->ctxt_info_gen3, + trans_pcie->ctxt_info_dma_addr); + trans_pcie->ctxt_info_gen3 = NULL; err_free_prph_info: dma_free_coherent(trans->dev, sizeof(*prph_info), @@ -215,6 +242,11 @@ trans_pcie->ctxt_info_dma_addr = 0; trans_pcie->ctxt_info_gen3 = NULL; + dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml, + trans_pcie->iml_dma_addr); + trans_pcie->iml_dma_addr = 0; + trans_pcie->iml = NULL; + iwl_pcie_ctxt_info_free_fw_img(trans); dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch), --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -193,11 +193,12 @@ rb_size = IWL_CTXT_INFO_RB_SIZE_4K; } - BUILD_BUG_ON(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) > 0xF); - control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG | - (RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE) << - IWL_CTXT_INFO_RB_CB_SIZE_POS) | - (rb_size << IWL_CTXT_INFO_RB_SIZE_POS); + WARN_ON(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds) > 12); + control_flags = IWL_CTXT_INFO_TFD_FORMAT_LONG; + control_flags |= + u32_encode_bits(RX_QUEUE_CB_SIZE(trans->cfg->num_rbds), + IWL_CTXT_INFO_RB_CB_SIZE); + control_flags |= u32_encode_bits(rb_size, IWL_CTXT_INFO_RB_SIZE); ctxt_info->control.control_flags = cpu_to_le32(control_flags); /* initialize RX default queue */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/drv.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/drv.c @@ -258,6 +258,7 @@ {IWL_PCI_DEVICE(0x088E, 0x446A, iwl6035_2agn_sff_cfg)}, {IWL_PCI_DEVICE(0x088E, 0x4860, iwl6035_2agn_cfg)}, {IWL_PCI_DEVICE(0x088F, 0x5260, iwl6035_2agn_cfg)}, + {IWL_PCI_DEVICE(0x088F, 0x526A, iwl6035_2agn_cfg)}, /* 105 Series */ {IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, @@ -910,7 +911,6 @@ {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax201_cfg_qu_hr)}, - {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0310, iwl_ax201_cfg_qu_hr)}, {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl_ax201_cfg_qu_hr)}, @@ -968,6 +968,7 @@ {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0)}, + {IWL_PCI_DEVICE(0x2725, 0x0024, iwlax210_2ax_cfg_ty_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_ty_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0510, iwlax210_2ax_cfg_ty_gf_a0)}, {IWL_PCI_DEVICE(0x2725, 0x0A10, iwlax210_2ax_cfg_ty_gf_a0)}, @@ -992,18 +993,32 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + const struct iwl_cfg_trans_params *trans = + (struct iwl_cfg_trans_params *)(ent->driver_data); const struct iwl_cfg *cfg_7265d __maybe_unused = NULL; struct iwl_trans *iwl_trans; + struct iwl_trans_pcie *trans_pcie; unsigned long flags; int ret; + /* + * This is needed for backwards compatibility with the old + * tables, so we don't need to change all the config structs + * at the same time. The cfg is used to compare with the old + * full cfg structs. + */ + const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); + + /* make sure trans is the first element in iwl_cfg */ + BUILD_BUG_ON(offsetof(struct iwl_cfg, trans)); - iwl_trans = iwl_trans_pcie_alloc(pdev, ent, &cfg->trans); + iwl_trans = iwl_trans_pcie_alloc(pdev, ent, trans); if (IS_ERR(iwl_trans)) return PTR_ERR(iwl_trans); + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); + /* the trans_cfg should never change, so set it now */ - iwl_trans->trans_cfg = &cfg->trans; + iwl_trans->trans_cfg = trans; if (WARN_ONCE(!iwl_trans->trans_cfg->csr, "CSR addresses aren't configured\n")) { @@ -1027,22 +1042,22 @@ cfg_7265d = &iwl7265d_n_cfg; if (cfg_7265d && (iwl_trans->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_7265D) - cfg = cfg_7265d; + iwl_trans->cfg = cfg_7265d; iwl_trans->hw_rf_id = iwl_read32(iwl_trans, CSR_HW_RF_ID); if (cfg == &iwlax210_2ax_cfg_so_hr_a0) { if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_TY) { - cfg = &iwlax210_2ax_cfg_ty_gf_a0; + iwl_trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - cfg = &iwlax210_2ax_cfg_so_jf_a0; + iwl_trans->cfg = &iwlax210_2ax_cfg_so_jf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) { - cfg = &iwlax211_2ax_cfg_so_gf_a0; + iwl_trans->cfg = &iwlax211_2ax_cfg_so_gf_a0; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF4)) { - cfg = &iwlax411_2ax_cfg_so_gf4_a0; + iwl_trans->cfg = &iwlax411_2ax_cfg_so_gf4_a0; } } else if (cfg == &iwl_ax101_cfg_qu_hr) { if ((CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == @@ -1050,13 +1065,17 @@ iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) || (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR1))) { - cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && + iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { + iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { - cfg = &iwl_ax101_cfg_qu_hr; + iwl_trans->cfg = &iwl_ax101_cfg_qu_hr; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { - cfg = &iwl22000_2ax_cfg_jf; + iwl_trans->cfg = &iwl22000_2ax_cfg_jf; } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(iwl_trans->hw_rf_id) == CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HRCDB)) { IWL_ERR(iwl_trans, "RF ID HRCDB is not supported\n"); @@ -1073,19 +1092,11 @@ hw_status = iwl_read_prph(iwl_trans, UMAG_GEN_HW_STATUS); if (CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_B_STEP) - /* - * b step fw is the same for physical card and fpga - */ - cfg = &iwl22000_2ax_cfg_qnj_hr_b0; + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0; else if ((hw_status & UMAG_GEN_HW_IS_FPGA) && - CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == SILICON_A_STEP) { - cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; - } else { - /* - * a step no FPGA - */ - cfg = &iwl22000_2ac_cfg_hr; - } + CSR_HW_RF_STEP(iwl_trans->hw_rf_id) == + SILICON_A_STEP) + iwl_trans->cfg = &iwl22000_2ax_cfg_qnj_hr_a0_f0; } /* @@ -1096,38 +1107,60 @@ */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QU_C0) { if (cfg == &iwl_ax101_cfg_qu_hr) - cfg = &iwl_ax101_cfg_qu_c0_hr_b0; + iwl_trans->cfg = &iwl_ax101_cfg_qu_c0_hr_b0; else if (cfg == &iwl_ax201_cfg_qu_hr) - cfg = &iwl_ax201_cfg_qu_c0_hr_b0; + iwl_trans->cfg = &iwl_ax201_cfg_qu_c0_hr_b0; else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9461_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9462_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0; else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) - cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; + iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0; + else if (cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0; + else if (cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0; } /* same thing for QuZ... */ if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) { - if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr) + if (cfg == &iwl_ax101_cfg_qu_hr) iwl_trans->cfg = &iwl_ax101_cfg_quz_hr; - else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr) + else if (cfg == &iwl_ax201_cfg_qu_hr) iwl_trans->cfg = &iwl_ax201_cfg_quz_hr; - else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc; - else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) + else if (cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0) iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc; + else if (cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &iwl_ax1650s_cfg_quz_hr; + else if (cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0) + iwl_trans->cfg = &iwl_ax1650i_cfg_quz_hr; } #endif - /* now set the real cfg we decided to use */ - iwl_trans->cfg = cfg; + /* + * If we didn't set the cfg yet, assume the trans is actually + * a full cfg from the old tables. + */ + if (!iwl_trans->cfg) + iwl_trans->cfg = cfg; + + if (iwl_trans->trans_cfg->mq_rx_supported) { + if (WARN_ON(!iwl_trans->cfg->num_rbds)) { + ret = -EINVAL; + goto out_free_trans; + } + trans_pcie->num_rx_bufs = iwl_trans->cfg->num_rbds; + } else { + trans_pcie->num_rx_bufs = RX_QUEUE_SIZE; + } if (iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_8000 && iwl_trans_grab_nic_access(iwl_trans, &flags)) { @@ -1172,6 +1205,9 @@ { struct iwl_trans *trans = pci_get_drvdata(pdev); + if (!trans) + return; + iwl_drv_stop(trans->drv); iwl_trans_pcie_free(trans); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -166,7 +166,7 @@ * @id: queue index * @bd: driver's pointer to buffer of receive buffer descriptors (rbd). * Address size is 32 bit in pre-9000 devices and 64 bit in 9000 devices. - * In 22560 devices it is a pointer to a list of iwl_rx_transfer_desc's + * In AX210 devices it is a pointer to a list of iwl_rx_transfer_desc's * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) * @ubd: driver's pointer to buffer of used receive buffer descriptors (rbd) * @ubd_dma: physical address of buffer of used receive buffer descriptors (rbd) @@ -264,7 +264,7 @@ static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, struct iwl_rxq *rxq) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { __le16 *rb_stts = rxq->rb_stts; return READ_ONCE(*rb_stts); @@ -305,7 +305,7 @@ #define IWL_FIRST_TB_SIZE_ALIGN ALIGN(IWL_FIRST_TB_SIZE, 64) struct iwl_pcie_txq_entry { - struct iwl_device_cmd *cmd; + void *cmd; struct sk_buff *skb; /* buffer to free after command completes */ const void *free_buf; @@ -475,6 +475,8 @@ * Context information addresses will be taken from here. * This is driver's local copy for keeping track of size and * count for allocating and freeing the memory. + * @iml: image loader image virtual address + * @iml_dma_addr: image loader image DMA address * @trans: pointer to the generic transport area * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler @@ -513,8 +515,8 @@ */ struct iwl_trans_pcie { struct iwl_rxq *rxq; - struct iwl_rx_mem_buffer rx_pool[RX_POOL_SIZE]; - struct iwl_rx_mem_buffer *global_table[RX_POOL_SIZE]; + struct iwl_rx_mem_buffer *rx_pool; + struct iwl_rx_mem_buffer **global_table; struct iwl_rb_allocator rba; union { struct iwl_context_info *ctxt_info; @@ -522,6 +524,7 @@ }; struct iwl_prph_info *prph_info; struct iwl_prph_scratch *prph_scratch; + void *iml; dma_addr_t ctxt_info_dma_addr; dma_addr_t prph_info_dma_addr; dma_addr_t prph_scratch_dma_addr; @@ -573,6 +576,7 @@ u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; u8 max_tbs; u16 tfd_size; + u16 num_rx_bufs; enum iwl_amsdu_size rx_buf_size; bool bc_table_dword; @@ -690,7 +694,7 @@ void iwl_trans_pcie_log_scd_error(struct iwl_trans *trans, struct iwl_txq *txq); int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id); + struct iwl_device_tx_cmd *dev_cmd, int txq_id); void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx); @@ -1111,7 +1115,7 @@ unsigned int timeout); void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue); int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id); + struct iwl_device_tx_cmd *dev_cmd, int txq_id); int iwl_trans_pcie_gen2_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -200,8 +200,8 @@ */ int iwl_pcie_rx_stop(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - /* TODO: remove this for 22560 once fw does it */ + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + /* TODO: remove this once fw does it */ iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3, RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); @@ -247,11 +247,7 @@ } rxq->write_actual = round_down(rxq->write, 8); - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560) - iwl_write32(trans, HBUS_TARG_WRPTR, - (rxq->write_actual | - ((FIRST_RX_QUEUE + rxq->id) << 16))); - else if (trans->trans_cfg->mq_rx_supported) + if (trans->trans_cfg->mq_rx_supported) iwl_write32(trans, RFH_Q_FRBDCB_WIDX_TRG(rxq->id), rxq->write_actual); else @@ -279,7 +275,7 @@ struct iwl_rxq *rxq, struct iwl_rx_mem_buffer *rxb) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { struct iwl_rx_transfer_desc *bd = rxq->bd; BUILD_BUG_ON(sizeof(*bd) != 2 * sizeof(u64)); @@ -326,7 +322,7 @@ WARN_ON(rxb->page_dma & DMA_BIT_MASK(12)); /* Point to Rx buffer via next RBD in circular buffer */ iwl_pcie_restock_bd(trans, rxq, rxb); - rxq->write = (rxq->write + 1) & MQ_RX_TABLE_MASK; + rxq->write = (rxq->write + 1) & (rxq->queue_size - 1); rxq->free_count--; } spin_unlock(&rxq->lock); @@ -514,7 +510,7 @@ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int i; - for (i = 0; i < RX_POOL_SIZE; i++) { + for (i = 0; i < RX_POOL_SIZE(trans_pcie->num_rx_bufs); i++) { if (!trans_pcie->rx_pool[i].page) continue; dma_unmap_page(trans->dev, trans_pcie->rx_pool[i].page_dma, @@ -691,7 +687,7 @@ { struct device *dev = trans->dev; bool use_rx_td = (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560); + IWL_DEVICE_FAMILY_AX210); int free_size = iwl_pcie_free_bd_size(trans, use_rx_td); if (rxq->bd) @@ -712,7 +708,7 @@ rxq->used_bd_dma = 0; rxq->used_bd = NULL; - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) return; if (rxq->tr_tail) @@ -736,13 +732,13 @@ int i; int free_size; bool use_rx_td = (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560); + IWL_DEVICE_FAMILY_AX210); size_t rb_stts_size = use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status); spin_lock_init(&rxq->lock); if (trans->trans_cfg->mq_rx_supported) - rxq->queue_size = MQ_RX_TABLE_SIZE; + rxq->queue_size = trans->cfg->num_rbds; else rxq->queue_size = RX_QUEUE_SIZE; @@ -784,11 +780,6 @@ &rxq->cr_tail_dma, GFP_KERNEL); if (!rxq->cr_tail) goto err; - /* - * W/A 22560 device step Z0 must be non zero bug - * TODO: remove this when stop supporting Z0 - */ - *rxq->cr_tail = cpu_to_le16(500); return 0; @@ -808,7 +799,7 @@ struct iwl_rb_allocator *rba = &trans_pcie->rba; int i, ret; size_t rb_stts_size = trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560 ? + IWL_DEVICE_FAMILY_AX210 ? sizeof(__le16) : sizeof(struct iwl_rb_status); if (WARN_ON(trans_pcie->rxq)) @@ -816,8 +807,18 @@ trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq), GFP_KERNEL); - if (!trans_pcie->rxq) - return -ENOMEM; + trans_pcie->rx_pool = kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), + sizeof(trans_pcie->rx_pool[0]), + GFP_KERNEL); + trans_pcie->global_table = + kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), + sizeof(trans_pcie->global_table[0]), + GFP_KERNEL); + if (!trans_pcie->rxq || !trans_pcie->rx_pool || + !trans_pcie->global_table) { + ret = -ENOMEM; + goto err; + } spin_lock_init(&rba->lock); @@ -854,6 +855,8 @@ trans_pcie->base_rb_stts = NULL; trans_pcie->base_rb_stts_dma = 0; } + kfree(trans_pcie->rx_pool); + kfree(trans_pcie->global_table); kfree(trans_pcie->rxq); return ret; @@ -1074,8 +1077,9 @@ rxq->read = 0; rxq->write = 0; rxq->write_actual = 0; - memset(rxq->rb_stts, 0, (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) ? + memset(rxq->rb_stts, 0, + (trans->trans_cfg->device_family >= + IWL_DEVICE_FAMILY_AX210) ? sizeof(__le16) : sizeof(struct iwl_rb_status)); iwl_pcie_rx_init_rxb_lists(rxq); @@ -1089,12 +1093,11 @@ /* move the pool to the default queue and allocator ownerships */ queue_size = trans->trans_cfg->mq_rx_supported ? - MQ_RX_NUM_RBDS : RX_QUEUE_SIZE; + trans_pcie->num_rx_bufs - 1 : RX_QUEUE_SIZE; allocator_pool_size = trans->num_rx_queues * (RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC); num_alloc = queue_size + allocator_pool_size; - BUILD_BUG_ON(ARRAY_SIZE(trans_pcie->global_table) != - ARRAY_SIZE(trans_pcie->rx_pool)); + for (i = 0; i < num_alloc; i++) { struct iwl_rx_mem_buffer *rxb = &trans_pcie->rx_pool[i]; @@ -1152,7 +1155,7 @@ struct iwl_rb_allocator *rba = &trans_pcie->rba; int i; size_t rb_stts_size = trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560 ? + IWL_DEVICE_FAMILY_AX210 ? sizeof(__le16) : sizeof(struct iwl_rb_status); /* @@ -1185,6 +1188,8 @@ if (rxq->napi.poll) netif_napi_del(&rxq->napi); } + kfree(trans_pcie->rx_pool); + kfree(trans_pcie->global_table); kfree(trans_pcie->rxq); } @@ -1347,7 +1352,7 @@ } page_stolen |= rxcb._page_stolen; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) break; offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN); } @@ -1398,13 +1403,12 @@ return rxb; } - /* used_bd is a 32/16 bit but only 12 are used to retrieve the vid */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) - vid = le16_to_cpu(rxq->cd[i].rbid) & 0x0FFF; + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) + vid = le16_to_cpu(rxq->cd[i].rbid); else - vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; + vid = le32_to_cpu(rxq->bd_32[i]) & 0x0FFF; /* 12-bit VID */ - if (!vid || vid > ARRAY_SIZE(trans_pcie->global_table)) + if (!vid || vid > RX_POOL_SIZE(trans_pcie->num_rx_bufs)) goto out_err; rxb = trans_pcie->global_table[vid - 1]; @@ -1429,6 +1433,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct napi_struct *napi; struct iwl_rxq *rxq; u32 r, i, count = 0; bool emergency = false; @@ -1515,7 +1520,7 @@ /* Backtrack one entry */ rxq->read = i; /* update cr tail with the rxq read pointer */ - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) *rxq->cr_tail = cpu_to_le16(r); spin_unlock(&rxq->lock); @@ -1534,8 +1539,16 @@ if (unlikely(emergency && count)) iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC, rxq); - if (rxq->napi.poll) - napi_gro_flush(&rxq->napi, false); + napi = &rxq->napi; + if (napi->poll) { + napi_gro_flush(napi, false); + + if (napi->rx_count) { + netif_receive_skb_list(&napi->rx_list); + INIT_LIST_HEAD(&napi->rx_list); + napi->rx_count = 0; + } + } iwl_pcie_rxq_restock(trans, rxq); } @@ -2152,8 +2165,7 @@ /* Error detected by uCode */ if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) || - (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) || - (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR_V2)) { + (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR)) { IWL_ERR(trans, "Microcode SW error detected. Restarting 0x%X.\n", inta_fh); @@ -2185,17 +2197,7 @@ } } - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22560 && - inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) { - /* Reflect IML transfer status */ - int res = iwl_read32(trans, CSR_IML_RESP_ADDR); - - IWL_DEBUG_ISR(trans, "IML transfer status: %d\n", res); - if (res == IWL_IMAGE_RESP_FAIL) { - isr_stats->sw++; - iwl_pcie_irq_handle_error(trans); - } - } else if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) { + if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) { u32 sleep_notif = le32_to_cpu(trans_pcie->prph_info->sleep_notif); if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND || --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -57,24 +57,6 @@ #include "internal.h" #include "fw/dbg.h" -static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) -{ - iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, - HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); - udelay(20); - iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, - HPM_HIPM_GEN_CFG_CR_PG_EN | - HPM_HIPM_GEN_CFG_CR_SLP_EN); - udelay(20); - iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG, - HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); - - iwl_trans_sw_reset(trans); - iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - - return 0; -} - /* * Start up NIC's basic functionality after it has been reset * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) @@ -110,13 +92,6 @@ iwl_pcie_apm_config(trans); - if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && - trans->cfg->integrated) { - ret = iwl_pcie_gen2_force_power_gating(trans); - if (ret) - return ret; - } - ret = iwl_finish_nic_init(trans, trans->trans_cfg); if (ret) return ret; @@ -193,7 +168,7 @@ } iwl_pcie_ctxt_info_free_paging(trans); - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) iwl_pcie_ctxt_info_gen3_free(trans); else iwl_pcie_ctxt_info_free(trans); @@ -294,7 +269,8 @@ /* now that we got alive we can free the fw image & the context info. * paging memory cannot be freed included since FW will still use it */ - iwl_pcie_ctxt_info_free(trans); + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + iwl_pcie_ctxt_info_free(trans); /* * Re-enable all the interrupts, including the RF-Kill one, now that @@ -316,8 +292,7 @@ /* This may fail if AMT took ownership of the device */ if (iwl_pcie_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); - ret = -EIO; - goto out; + return -EIO; } iwl_enable_rfkill_int(trans); @@ -365,7 +340,7 @@ goto out; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); else ret = iwl_pcie_ctxt_info_init(trans, fw); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -79,6 +79,7 @@ #include "iwl-agn-hw.h" #include "fw/error-dump.h" #include "fw/dbg.h" +#include "fw/api/tx.h" #include "internal.h" #include "iwl-fh.h" @@ -629,7 +630,6 @@ int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) { int ret; - int t = 0; int iter; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); @@ -644,6 +644,8 @@ usleep_range(1000, 2000); for (iter = 0; iter < 10; iter++) { + int t = 0; + /* If HW is not ready, prepare the conditions to check again */ iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); @@ -1112,30 +1114,12 @@ {MSIX_HW_INT_CAUSES_REG_HAP, CSR_MSIX_HW_INT_MASK_AD, 0x2E}, }; -static struct iwl_causes_list causes_list_v2[] = { - {MSIX_FH_INT_CAUSES_D2S_CH0_NUM, CSR_MSIX_FH_INT_MASK_AD, 0}, - {MSIX_FH_INT_CAUSES_D2S_CH1_NUM, CSR_MSIX_FH_INT_MASK_AD, 0x1}, - {MSIX_FH_INT_CAUSES_S2D, CSR_MSIX_FH_INT_MASK_AD, 0x3}, - {MSIX_FH_INT_CAUSES_FH_ERR, CSR_MSIX_FH_INT_MASK_AD, 0x5}, - {MSIX_HW_INT_CAUSES_REG_ALIVE, CSR_MSIX_HW_INT_MASK_AD, 0x10}, - {MSIX_HW_INT_CAUSES_REG_IPC, CSR_MSIX_HW_INT_MASK_AD, 0x11}, - {MSIX_HW_INT_CAUSES_REG_SW_ERR_V2, CSR_MSIX_HW_INT_MASK_AD, 0x15}, - {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16}, - {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17}, - {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18}, - {MSIX_HW_INT_CAUSES_REG_SCD, CSR_MSIX_HW_INT_MASK_AD, 0x2A}, - {MSIX_HW_INT_CAUSES_REG_FH_TX, CSR_MSIX_HW_INT_MASK_AD, 0x2B}, - {MSIX_HW_INT_CAUSES_REG_HW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x2D}, - {MSIX_HW_INT_CAUSES_REG_HAP, CSR_MSIX_HW_INT_MASK_AD, 0x2E}, -}; - static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; - int i, arr_size = - (trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22560) ? - ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2); + int i, arr_size = ARRAY_SIZE(causes_list); + struct iwl_causes_list *causes = causes_list; /* * Access all non RX causes and map them to the default irq. @@ -1143,11 +1127,6 @@ * the first interrupt vector will serve non-RX and FBQ causes. */ for (i = 0; i < arr_size; i++) { - struct iwl_causes_list *causes = - (trans->trans_cfg->device_family != - IWL_DEVICE_FAMILY_22560) ? - causes_list : causes_list_v2; - iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); iwl_clear_bit(trans, causes[i].mask_reg, causes[i].cause_num); @@ -1334,8 +1313,7 @@ /* This may fail if AMT took ownership of the device */ if (iwl_pcie_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); - ret = -EIO; - goto out; + return -EIO; } iwl_enable_rfkill_int(trans); @@ -1634,11 +1612,15 @@ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int max_irqs, num_irqs, i, ret; u16 pci_cmd; + u32 max_rx_queues = IWL_MAX_RX_HW_QUEUES; if (!cfg_trans->mq_rx_supported) goto enable_msi; - max_irqs = min_t(u32, num_online_cpus() + 2, IWL_MAX_RX_HW_QUEUES); + if (cfg_trans->device_family <= IWL_DEVICE_FAMILY_9000) + max_rx_queues = IWL_9000_MAX_RX_HW_QUEUES; + + max_irqs = min_t(u32, num_online_cpus() + 2, max_rx_queues); for (i = 0; i < max_irqs; i++) trans_pcie->msix_entries[i].entry = i; @@ -1783,6 +1765,29 @@ return 0; } +static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans) +{ + int ret; + + ret = iwl_finish_nic_init(trans, trans->trans_cfg); + if (ret < 0) + return ret; + + iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); + udelay(20); + iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_PG_EN | + HPM_HIPM_GEN_CFG_CR_SLP_EN); + udelay(20); + iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG, + HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE); + + iwl_trans_pcie_sw_reset(trans); + + return 0; +} + static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1802,6 +1807,13 @@ iwl_trans_pcie_sw_reset(trans); + if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 && + trans->cfg->integrated) { + err = iwl_pcie_gen2_force_power_gating(trans); + if (err) + return err; + } + err = iwl_pcie_apm_init(trans); if (err) return err; @@ -1871,7 +1883,7 @@ static u32 iwl_trans_pcie_prph_msk(struct iwl_trans *trans) { - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) return 0x00FFFFFF; else return 0x000FFFFF; @@ -2147,18 +2159,38 @@ void *buf, int dwords) { unsigned long flags; - int offs, ret = 0; + int offs = 0; u32 *vals = buf; - if (iwl_trans_grab_nic_access(trans, &flags)) { - iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); - for (offs = 0; offs < dwords; offs++) - vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - iwl_trans_release_nic_access(trans, &flags); - } else { - ret = -EBUSY; + while (offs < dwords) { + /* limit the time we spin here under lock to 1/2s */ + unsigned long end = jiffies + HZ / 2; + bool resched = false; + + if (iwl_trans_grab_nic_access(trans, &flags)) { + iwl_write32(trans, HBUS_TARG_MEM_RADDR, + addr + 4 * offs); + + while (offs < dwords) { + vals[offs] = iwl_read32(trans, + HBUS_TARG_MEM_RDAT); + offs++; + + if (time_after(jiffies, end)) { + resched = true; + break; + } + } + iwl_trans_release_nic_access(trans, &flags); + + if (resched) + cond_resched(); + } else { + return -EBUSY; + } } - return ret; + + return 0; } static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr, @@ -2781,7 +2813,7 @@ void *buf, ssize_t *size, ssize_t *bytes_copied) { - int buf_size_left = count - *bytes_copied; + ssize_t buf_size_left = count - *bytes_copied; buf_size_left = buf_size_left - (buf_size_left % sizeof(u32)); if (*size > buf_size_left) @@ -3432,19 +3464,34 @@ { struct iwl_trans_pcie *trans_pcie; struct iwl_trans *trans; - int ret, addr_size; + int ret, addr_size, txcmd_size, txcmd_align; + const struct iwl_trans_ops *ops = &trans_ops_pcie_gen2; + + if (!cfg_trans->gen2) { + ops = &trans_ops_pcie; + txcmd_size = sizeof(struct iwl_tx_cmd); + txcmd_align = sizeof(void *); + } else if (cfg_trans->device_family < IWL_DEVICE_FAMILY_AX210) { + txcmd_size = sizeof(struct iwl_tx_cmd_gen2); + txcmd_align = 64; + } else { + txcmd_size = sizeof(struct iwl_tx_cmd_gen3); + txcmd_align = 128; + } + + txcmd_size += sizeof(struct iwl_cmd_header); + txcmd_size += 36; /* biggest possible 802.11 header */ + + /* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */ + if (WARN_ON(cfg_trans->gen2 && txcmd_size >= txcmd_align)) + return ERR_PTR(-EINVAL); ret = pcim_enable_device(pdev); if (ret) return ERR_PTR(ret); - if (cfg_trans->gen2) - trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), - &pdev->dev, &trans_ops_pcie_gen2); - else - trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), - &pdev->dev, &trans_ops_pcie); - + trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), &pdev->dev, ops, + txcmd_size, txcmd_align); if (!trans) return ERR_PTR(-ENOMEM); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c @@ -113,14 +113,14 @@ */ num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1; - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { - /* Starting from 22560, the HW expects bytes */ + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { + /* Starting from AX210, the HW expects bytes */ WARN_ON(trans_pcie->bc_table_dword); WARN_ON(len > 0x3FFF); bc_ent = cpu_to_le16(len | (num_fetch_chunks << 14)); scd_bc_tbl_gen3->tfd_offset[idx] = bc_ent; } else { - /* Until 22560, the HW expects DW */ + /* Before AX210, the HW expects DW */ WARN_ON(!trans_pcie->bc_table_dword); len = DIV_ROUND_UP(len, 4); WARN_ON(len > 0xFFF); @@ -243,7 +243,8 @@ static int iwl_pcie_gen2_build_amsdu(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_tfh_tfd *tfd, int start_len, - u8 hdr_len, struct iwl_device_cmd *dev_cmd) + u8 hdr_len, + struct iwl_device_tx_cmd *dev_cmd) { #ifdef CONFIG_INET struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -371,7 +372,7 @@ static struct iwl_tfh_tfd *iwl_pcie_gen2_build_tx_amsdu(struct iwl_trans *trans, struct iwl_txq *txq, - struct iwl_device_cmd *dev_cmd, + struct iwl_device_tx_cmd *dev_cmd, struct sk_buff *skb, struct iwl_cmd_meta *out_meta, int hdr_len, @@ -403,6 +404,10 @@ tb_phys = dma_map_single(trans->dev, tb1_addr, len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(trans->dev, tb_phys))) goto out_err; + /* + * No need for _with_wa(), we ensure (via alignment) that the data + * here can never cross or end at a page boundary. + */ iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, len); if (iwl_pcie_gen2_build_amsdu(trans, skb, tfd, @@ -456,7 +461,7 @@ static struct iwl_tfh_tfd *iwl_pcie_gen2_build_tx(struct iwl_trans *trans, struct iwl_txq *txq, - struct iwl_device_cmd *dev_cmd, + struct iwl_device_tx_cmd *dev_cmd, struct sk_buff *skb, struct iwl_cmd_meta *out_meta, int hdr_len, @@ -468,6 +473,7 @@ dma_addr_t tb_phys; int len, tb1_len, tb2_len; void *tb1_addr; + struct sk_buff *frag; tb_phys = iwl_pcie_get_first_tb_dma(txq, idx); @@ -495,6 +501,10 @@ tb_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(trans->dev, tb_phys))) goto out_err; + /* + * No need for _with_wa(), we ensure (via alignment) that the data + * here can never cross or end at a page boundary. + */ iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, tb1_len); trace_iwlwifi_dev_tx(trans->dev, skb, tfd, sizeof(*tfd), &dev_cmd->hdr, IWL_FIRST_TB_SIZE + tb1_len, hdr_len); @@ -516,6 +526,19 @@ if (iwl_pcie_gen2_tx_add_frags(trans, skb, tfd, out_meta)) goto out_err; + skb_walk_frags(skb, frag) { + tb_phys = dma_map_single(trans->dev, frag->data, + skb_headlen(frag), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb_phys))) + goto out_err; + iwl_pcie_gen2_set_tb(trans, tfd, tb_phys, skb_headlen(frag)); + trace_iwlwifi_dev_tx_tb(trans->dev, skb, + frag->data, + skb_headlen(frag)); + if (iwl_pcie_gen2_tx_add_frags(trans, frag, tfd, out_meta)) + goto out_err; + } + return tfd; out_err: @@ -526,7 +549,7 @@ static struct iwl_tfh_tfd *iwl_pcie_gen2_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq, - struct iwl_device_cmd *dev_cmd, + struct iwl_device_tx_cmd *dev_cmd, struct sk_buff *skb, struct iwl_cmd_meta *out_meta) { @@ -541,7 +564,7 @@ memset(tfd, 0, sizeof(*tfd)); - if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_22560) + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) len = sizeof(struct iwl_tx_cmd_gen2); else len = sizeof(struct iwl_tx_cmd_gen3); @@ -566,7 +589,7 @@ } int iwl_trans_pcie_gen2_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id) + struct iwl_device_tx_cmd *dev_cmd, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_cmd_meta *out_meta; @@ -591,7 +614,7 @@ /* don't put the packet on the ring, if there is no room */ if (unlikely(iwl_queue_space(trans, txq) < 3)) { - struct iwl_device_cmd **dev_cmd_ptr; + struct iwl_device_tx_cmd **dev_cmd_ptr; dev_cmd_ptr = (void *)((u8 *)skb->cb + trans_pcie->dev_cmd_offs); @@ -623,7 +646,7 @@ return -1; } - if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_22560) { + if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { struct iwl_tx_cmd_gen3 *tx_cmd_gen3 = (void *)dev_cmd->payload; @@ -682,6 +705,7 @@ const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; struct iwl_tfh_tfd *tfd; + unsigned long flags2; copy_size = sizeof(struct iwl_cmd_header_wide); cmd_size = sizeof(struct iwl_cmd_header_wide); @@ -750,14 +774,14 @@ goto free_dup_buf; } - spin_lock_bh(&txq->lock); + spin_lock_irqsave(&txq->lock, flags2); idx = iwl_pcie_get_cmd_index(txq, txq->write_ptr); tfd = iwl_pcie_get_tfd(trans, txq, txq->write_ptr); memset(tfd, 0, sizeof(*tfd)); if (iwl_queue_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { - spin_unlock_bh(&txq->lock); + spin_unlock_irqrestore(&txq->lock, flags2); IWL_ERR(trans, "No space in command queue\n"); iwl_op_mode_cmd_queue_full(trans->op_mode); @@ -892,7 +916,7 @@ spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); out: - spin_unlock_bh(&txq->lock); + spin_unlock_irqrestore(&txq->lock, flags2); free_dup_buf: if (idx < 0) kfree(dup_buf); @@ -1124,7 +1148,7 @@ return -ENOMEM; ret = iwl_pcie_alloc_dma_ptr(trans, &txq->bc_tbl, (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) ? + IWL_DEVICE_FAMILY_AX210) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl)); if (ret) { @@ -1260,6 +1284,9 @@ iwl_pcie_gen2_txq_unmap(trans, queue); + iwl_pcie_gen2_txq_free_memory(trans, trans_pcie->txq[queue]); + trans_pcie->txq[queue] = NULL; + IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", queue); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intel/iwlwifi/pcie/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/intel/iwlwifi/pcie/tx.c @@ -213,8 +213,8 @@ u8 sec_ctl = 0; u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; __le16 bc_ent; - struct iwl_tx_cmd *tx_cmd = - (void *)txq->entries[txq->write_ptr].cmd->payload; + struct iwl_device_tx_cmd *dev_cmd = txq->entries[txq->write_ptr].cmd; + struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; u8 sta_id = tx_cmd->sta_id; scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; @@ -257,8 +257,8 @@ int read_ptr = txq->read_ptr; u8 sta_id = 0; __le16 bc_ent; - struct iwl_tx_cmd *tx_cmd = - (void *)txq->entries[read_ptr].cmd->payload; + struct iwl_device_tx_cmd *dev_cmd = txq->entries[read_ptr].cmd; + struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); @@ -657,6 +657,11 @@ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = trans_pcie->txq[txq_id]; + if (!txq) { + IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n"); + return; + } + spin_lock_bh(&txq->lock); while (txq->write_ptr != txq->read_ptr) { IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", @@ -949,7 +954,7 @@ u16 bc_tbls_size = trans->trans_cfg->base_params->num_of_queues; bc_tbls_size *= (trans->trans_cfg->device_family >= - IWL_DEVICE_FAMILY_22560) ? + IWL_DEVICE_FAMILY_AX210) ? sizeof(struct iwl_gen3_bc_tbl) : sizeof(struct iwlagn_scd_bc_tbl); @@ -1196,7 +1201,7 @@ while (!skb_queue_empty(&overflow_skbs)) { struct sk_buff *skb = __skb_dequeue(&overflow_skbs); - struct iwl_device_cmd *dev_cmd_ptr; + struct iwl_device_tx_cmd *dev_cmd_ptr; dev_cmd_ptr = *(void **)((u8 *)skb->cb + trans_pcie->dev_cmd_offs); @@ -1539,6 +1544,7 @@ u32 cmd_pos; const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; + unsigned long flags2; if (WARN(!trans->wide_cmd_header && group_id > IWL_ALWAYS_LONG_GROUP, @@ -1622,10 +1628,10 @@ goto free_dup_buf; } - spin_lock_bh(&txq->lock); + spin_lock_irqsave(&txq->lock, flags2); if (iwl_queue_space(trans, txq) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { - spin_unlock_bh(&txq->lock); + spin_unlock_irqrestore(&txq->lock, flags2); IWL_ERR(trans, "No space in command queue\n"); iwl_op_mode_cmd_queue_full(trans->op_mode); @@ -1786,7 +1792,7 @@ spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); out: - spin_unlock_bh(&txq->lock); + spin_unlock_irqrestore(&txq->lock, flags2); free_dup_buf: if (idx < 0) kfree(dup_buf); @@ -2099,7 +2105,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_txq *txq, u8 hdr_len, struct iwl_cmd_meta *out_meta, - struct iwl_device_cmd *dev_cmd, u16 tb1_len) + struct iwl_device_tx_cmd *dev_cmd, + u16 tb1_len) { struct iwl_tx_cmd *tx_cmd = (void *)dev_cmd->payload; struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; @@ -2281,7 +2288,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_txq *txq, u8 hdr_len, struct iwl_cmd_meta *out_meta, - struct iwl_device_cmd *dev_cmd, u16 tb1_len) + struct iwl_device_tx_cmd *dev_cmd, + u16 tb1_len) { /* No A-MSDU without CONFIG_INET */ WARN_ON(1); @@ -2291,7 +2299,7 @@ #endif /* CONFIG_INET */ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id) + struct iwl_device_tx_cmd *dev_cmd, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct ieee80211_hdr *hdr; @@ -2348,7 +2356,7 @@ /* don't put the packet on the ring, if there is no room */ if (unlikely(iwl_queue_space(trans, txq) < 3)) { - struct iwl_device_cmd **dev_cmd_ptr; + struct iwl_device_tx_cmd **dev_cmd_ptr; dev_cmd_ptr = (void *)((u8 *)skb->cb + trans_pcie->dev_cmd_offs); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/hostap/hostap_ap.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/hostap/hostap_ap.c @@ -2508,7 +2508,7 @@ sta->supported_rates[0] = 2; if (sta->tx_supp_rates & WLAN_RATE_2M) sta->supported_rates[1] = 4; - if (sta->tx_supp_rates & WLAN_RATE_5M5) + if (sta->tx_supp_rates & WLAN_RATE_5M5) sta->supported_rates[2] = 11; if (sta->tx_supp_rates & WLAN_RATE_11M) sta->supported_rates[3] = 22; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/orinoco/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/orinoco/hw.c @@ -931,6 +931,8 @@ err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFAUTHENTICATION_AGERE, auth_flag); + if (err) + return err; } err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFWEPENABLED_AGERE, --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/orinoco/orinoco_cs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/orinoco/orinoco_cs.c @@ -96,6 +96,7 @@ { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret; priv = alloc_orinocodev(sizeof(*card), &link->dev, orinoco_cs_hard_reset, NULL); @@ -107,8 +108,16 @@ card->p_dev = link; link->priv = priv; - return orinoco_cs_config(link); -} /* orinoco_cs_attach */ + ret = orinoco_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +} static void orinoco_cs_detach(struct pcmcia_device *link) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/orinoco/orinoco_usb.c @@ -1234,13 +1234,6 @@ if (skb->len < ETH_HLEN) goto drop; - ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0); - if (!ctx) - goto busy; - - memset(ctx->buf, 0, BULK_BUF_SIZE); - buf = ctx->buf->data; - tx_control = 0; err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control, @@ -1248,6 +1241,13 @@ if (err) goto drop; + ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0); + if (!ctx) + goto drop; + + memset(ctx->buf, 0, BULK_BUF_SIZE); + buf = ctx->buf->data; + { __le16 *tx_cntl = (__le16 *)buf; *tx_cntl = cpu_to_le16(tx_control); @@ -1361,7 +1361,8 @@ int retval; BUG_ON(in_interrupt()); - BUG_ON(!upriv); + if (!upriv) + return -EINVAL; upriv->reply_count = 0; /* Write the MAGIC number on the simulated registers to keep @@ -1608,9 +1609,9 @@ /* set up the endpoint information */ /* check out the endpoints */ - iface_desc = &interface->altsetting[0].desc; + iface_desc = &interface->cur_altsetting->desc; for (i = 0; i < iface_desc->bNumEndpoints; ++i) { - ep = &interface->altsetting[0].endpoint[i].desc; + ep = &interface->cur_altsetting->endpoint[i].desc; if (usb_endpoint_is_bulk_in(ep)) { /* we found a bulk in endpoint */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/orinoco/spectrum_cs.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/orinoco/spectrum_cs.c @@ -157,6 +157,7 @@ { struct orinoco_private *priv; struct orinoco_pccard *card; + int ret; priv = alloc_orinocodev(sizeof(*card), &link->dev, spectrum_cs_hard_reset, @@ -169,8 +170,16 @@ card->p_dev = link; link->priv = priv; - return spectrum_cs_config(link); -} /* spectrum_cs_attach */ + ret = spectrum_cs_config(link); + if (ret) + goto err_free_orinocodev; + + return 0; + +err_free_orinocodev: + free_orinocodev(priv); + return ret; +} static void spectrum_cs_detach(struct pcmcia_device *link) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/p54/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/p54/main.c @@ -682,7 +682,7 @@ * queues have already been stopped and no new frames can sneak * up from behind. */ - while ((total = p54_flush_count(priv) && i--)) { + while ((total = p54_flush_count(priv)) && i--) { /* waste time */ msleep(20); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/p54/p54pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/p54/p54pci.c @@ -329,10 +329,12 @@ struct p54p_desc *desc; dma_addr_t mapping; u32 idx, i; + __le32 device_addr; spin_lock_irqsave(&priv->lock, flags); idx = le32_to_cpu(ring_control->host_idx[1]); i = idx % ARRAY_SIZE(ring_control->tx_data); + device_addr = ((struct p54_hdr *)skb->data)->req_id; mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); @@ -346,7 +348,7 @@ desc = &ring_control->tx_data[i]; desc->host_addr = cpu_to_le32(mapping); - desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; + desc->device_addr = device_addr; desc->len = cpu_to_le16(skb->len); desc->flags = 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/p54/p54spi.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/p54/p54spi.c @@ -164,7 +164,7 @@ ret = p54_parse_firmware(dev, priv->firmware); if (ret) { - release_firmware(priv->firmware); + /* the firmware is released by the caller */ return ret; } @@ -623,7 +623,7 @@ gpio_direction_input(p54spi_gpio_irq); ret = request_irq(gpio_to_irq(p54spi_gpio_irq), - p54spi_interrupt, 0, "p54spi", + p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi", priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); @@ -632,8 +632,6 @@ irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); - disable_irq(gpio_to_irq(p54spi_gpio_irq)); - INIT_WORK(&priv->work, p54spi_work); init_completion(&priv->fw_comp); INIT_LIST_HEAD(&priv->tx_pending); @@ -659,6 +657,7 @@ return 0; err_free_common: + release_firmware(priv->firmware); free_irq(gpio_to_irq(p54spi_gpio_irq), spi); err_free_gpio_irq: gpio_free(p54spi_gpio_irq); --- linux-oracle-5.4.0.orig/drivers/net/wireless/intersil/p54/p54usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/intersil/p54/p54usb.c @@ -61,6 +61,7 @@ {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x124a, 0x4026)}, /* AirVasT USB wireless device */ {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */ {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/mac80211_hwsim.c +++ linux-oracle-5.4.0/drivers/net/wireless/mac80211_hwsim.c @@ -527,7 +527,7 @@ bool ps_poll_pending; struct dentry *debugfs; - uintptr_t pending_cookie; + atomic_t pending_cookie; struct sk_buff_head pending; /* packets pending */ /* * Only radios in the same group can communicate together (the @@ -663,6 +663,7 @@ struct hwsim_vif_priv *vp = (void *)vif->drv_priv; struct sk_buff *skb; struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *cb; if (!vp->assoc) return; @@ -684,6 +685,10 @@ memcpy(hdr->addr2, mac, ETH_ALEN); memcpy(hdr->addr3, vp->bssid, ETH_ALEN); + cb = IEEE80211_SKB_CB(skb); + cb->control.rates[0].count = 1; + cb->control.rates[1].idx = -1; + rcu_read_lock(); mac80211_hwsim_tx_frame(data->hw, skb, rcu_dereference(vif->chanctx_conf)->def.chan); @@ -1113,8 +1118,7 @@ goto nla_put_failure; /* We create a cookie to identify this skb */ - data->pending_cookie++; - cookie = data->pending_cookie; + cookie = atomic_inc_return(&data->pending_cookie); info->rate_driver_data[0] = (void *)cookie; if (nla_put_u64_64bit(skb, HWSIM_ATTR_COOKIE, cookie, HWSIM_ATTR_PAD)) goto nla_put_failure; @@ -1458,8 +1462,13 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *data = hw->priv; + data->started = false; hrtimer_cancel(&data->beacon_timer); + + while (!skb_queue_empty(&data->pending)) + ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); + wiphy_dbg(hw->wiphy, "%s\n", __func__); } @@ -1598,8 +1607,8 @@ bcn_int -= data->bcn_delta; data->bcn_delta = 0; } - hrtimer_forward(&data->beacon_timer, hrtimer_get_expires(timer), - ns_to_ktime(bcn_int * NSEC_PER_USEC)); + hrtimer_forward_now(&data->beacon_timer, + ns_to_ktime(bcn_int * NSEC_PER_USEC)); return HRTIMER_RESTART; } @@ -1979,8 +1988,7 @@ switch (action) { case IEEE80211_AMPDU_TX_START: - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: @@ -2057,9 +2065,21 @@ if (req->ie_len) skb_put_data(probe, req->ie, req->ie_len); + rcu_read_lock(); + if (!ieee80211_tx_prepare_skb(hwsim->hw, + hwsim->hw_scan_vif, + probe, + hwsim->tmp_chan->band, + NULL)) { + rcu_read_unlock(); + kfree_skb(probe); + continue; + } + local_bh_disable(); mac80211_hwsim_tx_frame(hwsim->hw, probe, hwsim->tmp_chan); + rcu_read_unlock(); local_bh_enable(); } } @@ -2302,7 +2322,7 @@ u32 sset, u8 *data) { if (sset == ETH_SS_STATS) - memcpy(data, *mac80211_hwsim_gstrings_stats, + memcpy(data, mac80211_hwsim_gstrings_stats, sizeof(mac80211_hwsim_gstrings_stats)); } @@ -3243,6 +3263,7 @@ const u8 *src; unsigned int hwsim_flags; int i; + unsigned long flags; bool found = false; if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || @@ -3267,18 +3288,20 @@ goto out; /* look for the skb matching the cookie passed back from user */ + spin_lock_irqsave(&data2->pending.lock, flags); skb_queue_walk_safe(&data2->pending, skb, tmp) { - u64 skb_cookie; + uintptr_t skb_cookie; txi = IEEE80211_SKB_CB(skb); - skb_cookie = (u64)(uintptr_t)txi->rate_driver_data[0]; + skb_cookie = (uintptr_t)txi->rate_driver_data[0]; if (skb_cookie == ret_skb_cookie) { - skb_unlink(skb, &data2->pending); + __skb_unlink(skb, &data2->pending); found = true; break; } } + spin_unlock_irqrestore(&data2->pending.lock, flags); /* not found */ if (!found) @@ -3311,6 +3334,10 @@ } txi->flags |= IEEE80211_TX_STAT_ACK; } + + if (hwsim_flags & HWSIM_TX_CTL_NO_ACK) + txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; + ieee80211_tx_status_irqsafe(data2->hw, skb); return 0; out: @@ -3339,14 +3366,15 @@ frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); + if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) || + frame_data_len > IEEE80211_MAX_DATA_LEN) + goto err; + /* Allocate new skb here */ skb = alloc_skb(frame_data_len, GFP_KERNEL); if (skb == NULL) goto err; - if (frame_data_len > IEEE80211_MAX_DATA_LEN) - goto err; - /* Copy the data */ skb_put_data(skb, frame_data, frame_data_len); @@ -3388,6 +3416,8 @@ rx_status.band = data2->channel->band; rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); + if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates) + goto out; rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); hdr = (void *)skb->data; @@ -3575,9 +3605,9 @@ } if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { - hwname = kasprintf(GFP_KERNEL, "%.*s", - nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), - (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); + hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]), + nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), + GFP_KERNEL); if (!hwname) return -ENOMEM; param.hwname = hwname; @@ -3597,9 +3627,9 @@ if (info->attrs[HWSIM_ATTR_RADIO_ID]) { idx = nla_get_u32(info->attrs[HWSIM_ATTR_RADIO_ID]); } else if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { - hwname = kasprintf(GFP_KERNEL, "%.*s", - nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), - (char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME])); + hwname = kstrndup((char *)nla_data(info->attrs[HWSIM_ATTR_RADIO_NAME]), + nla_len(info->attrs[HWSIM_ATTR_RADIO_NAME]), + GFP_KERNEL); if (!hwname) return -ENOMEM; } else --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/Kconfig @@ -2,8 +2,6 @@ config LIBERTAS tristate "Marvell 8xxx Libertas WLAN driver support" depends on CFG80211 - select WIRELESS_EXT - select WEXT_SPY select LIB80211 select FW_LOADER ---help--- --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/cfg.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/cfg.c @@ -273,6 +273,10 @@ int hw, ap, ap_max = ie[1]; u8 hw_rate; + if (ap_max > MAX_RATES) { + lbs_deb_assoc("invalid rates\n"); + return tlv; + } /* Advance past IE header */ ie += 2; @@ -1777,6 +1781,12 @@ } else { int hw, i; u8 rates_max = rates_eid[1]; + if (rates_max > MAX_RATES) { + lbs_deb_join("invalid rates"); + rcu_read_unlock(); + ret = -EINVAL; + goto out; + } u8 *rates = cmd.bss.rates; for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) { u8 hw_rate = lbs_rates[hw].bitrate / 5; --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/cmd.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/cmd.c @@ -1133,7 +1133,7 @@ if (!cmdarray[i].cmdbuf) { lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n"); ret = -1; - goto done; + goto free_cmd_array; } } @@ -1141,8 +1141,17 @@ init_waitqueue_head(&cmdarray[i].cmdwait_q); lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]); } - ret = 0; + return 0; +free_cmd_array: + for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) { + if (cmdarray[i].cmdbuf) { + kfree(cmdarray[i].cmdbuf); + cmdarray[i].cmdbuf = NULL; + } + } + kfree(priv->cmd_array); + priv->cmd_array = NULL; done: return ret; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/cmdresp.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/cmdresp.c @@ -48,7 +48,7 @@ /* Free Tx and Rx packets */ spin_lock_irqsave(&priv->driver_lock, flags); - kfree_skb(priv->currenttxskb); + dev_kfree_skb_irq(priv->currenttxskb); priv->currenttxskb = NULL; priv->tx_pending_len = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/if_sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/if_sdio.c @@ -1179,6 +1179,10 @@ spin_lock_init(&card->lock); card->workqueue = alloc_workqueue("libertas_sdio", WQ_MEM_RECLAIM, 0); + if (unlikely(!card->workqueue)) { + ret = -ENOMEM; + goto err_queue; + } INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); init_waitqueue_head(&card->pwron_waitq); @@ -1230,6 +1234,7 @@ lbs_remove_card(priv); free: destroy_workqueue(card->workqueue); +err_queue: while (card->packets) { packet = card->packets; card->packets = card->packets->next; --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/if_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/if_usb.c @@ -287,11 +287,13 @@ return 0; err_get_fw: + usb_put_dev(udev); lbs_remove_card(priv); err_add_card: if_usb_reset_device(cardp); dealloc: if_usb_free(cardp); + kfree(cardp); error: return r; @@ -316,6 +318,7 @@ /* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); @@ -634,7 +637,7 @@ priv->resp_len[i] = (recvlength - MESSAGE_HEADER_LEN); memcpy(priv->resp_buf[i], recvbuff + MESSAGE_HEADER_LEN, priv->resp_len[i]); - kfree_skb(skb); + dev_kfree_skb_irq(skb); lbs_notify_command_response(priv, i); spin_unlock_irqrestore(&priv->driver_lock, flags); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/main.c @@ -217,7 +217,7 @@ spin_lock_irqsave(&priv->driver_lock, flags); priv->iface_running = false; - kfree_skb(priv->currenttxskb); + dev_kfree_skb_irq(priv->currenttxskb); priv->currenttxskb = NULL; priv->tx_pending_len = 0; spin_unlock_irqrestore(&priv->driver_lock, flags); @@ -870,6 +870,7 @@ ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); if (ret) { pr_err("Out of memory allocating event FIFO buffer\n"); + lbs_free_cmd_buffer(priv); goto out; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas/mesh.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas/mesh.c @@ -801,24 +801,6 @@ .attrs = mesh_ie_attrs, }; -static void lbs_persist_config_init(struct net_device *dev) -{ - int ret; - ret = sysfs_create_group(&(dev->dev.kobj), &boot_opts_group); - if (ret) - pr_err("failed to create boot_opts_group.\n"); - - ret = sysfs_create_group(&(dev->dev.kobj), &mesh_ie_group); - if (ret) - pr_err("failed to create mesh_ie_group.\n"); -} - -static void lbs_persist_config_remove(struct net_device *dev) -{ - sysfs_remove_group(&(dev->dev.kobj), &boot_opts_group); - sysfs_remove_group(&(dev->dev.kobj), &mesh_ie_group); -} - /*************************************************************************** * Initializing and starting, stopping mesh @@ -1019,6 +1001,10 @@ SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent); mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST; + mesh_dev->sysfs_groups[0] = &lbs_mesh_attr_group; + mesh_dev->sysfs_groups[1] = &boot_opts_group; + mesh_dev->sysfs_groups[2] = &mesh_ie_group; + /* Register virtual mesh interface */ ret = register_netdev(mesh_dev); if (ret) { @@ -1026,19 +1012,10 @@ goto err_free_netdev; } - ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); - if (ret) - goto err_unregister; - - lbs_persist_config_init(mesh_dev); - /* Everything successful */ ret = 0; goto done; -err_unregister: - unregister_netdev(mesh_dev); - err_free_netdev: free_netdev(mesh_dev); @@ -1059,8 +1036,6 @@ netif_stop_queue(mesh_dev); netif_carrier_off(mesh_dev); - sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); - lbs_persist_config_remove(mesh_dev); unregister_netdev(mesh_dev); priv->mesh_dev = NULL; kfree(mesh_dev->ieee80211_ptr); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -230,6 +230,7 @@ dealloc: if_usb_free(cardp); + kfree(cardp); error: lbtf_deb_leave(LBTF_DEB_MAIN); return -ENOMEM; @@ -247,13 +248,14 @@ lbtf_deb_enter(LBTF_DEB_MAIN); - if_usb_reset_device(priv); - - if (priv) + if (priv) { + if_usb_reset_device(priv); lbtf_remove_card(priv); + } /* Unlink and free urb */ if_usb_free(cardp); + kfree(cardp); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); @@ -611,7 +613,7 @@ spin_lock_irqsave(&priv->driver_lock, flags); memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN, recvlength - MESSAGE_HEADER_LEN); - kfree_skb(skb); + dev_kfree_skb_irq(skb); lbtf_cmd_response_rx(priv); spin_unlock_irqrestore(&priv->driver_lock, flags); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/11h.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/11h.c @@ -303,5 +303,7 @@ mwifiex_dbg(priv->adapter, MSG, "indicating channel switch completion to kernel\n"); + mutex_lock(&priv->wdev.mtx); cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef); + mutex_unlock(&priv->wdev.mtx); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/11n.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/11n.c @@ -657,14 +657,15 @@ uint16_t del_ba_param_set; memset(&delba, 0, sizeof(delba)); - delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS); - del_ba_param_set = le16_to_cpu(delba.del_ba_param_set); + del_ba_param_set = tid << DELBA_TID_POS; + if (initiator) del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK; else del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK; + delba.del_ba_param_set = cpu_to_le16(del_ba_param_set); memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); /* We don't wait for the response of this command */ @@ -889,7 +890,7 @@ */ void mwifiex_update_ampdu_txwinsize(struct mwifiex_adapter *adapter) { - u8 i; + u8 i, j; u32 tx_win_size; struct mwifiex_private *priv; @@ -920,8 +921,8 @@ if (tx_win_size != priv->add_ba_param.tx_win_size) { if (!priv->media_connected) continue; - for (i = 0; i < MAX_NUM_TID; i++) - mwifiex_send_delba_txbastream_tbl(priv, i); + for (j = 0; j < MAX_NUM_TID; j++) + mwifiex_send_delba_txbastream_tbl(priv, j); } } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -977,8 +977,8 @@ } } - tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len); - tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba); + tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len); + tmp = (u8 *)tlv_rxba + sizeof(tlv_rxba->header) + tlv_len; tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -912,16 +912,20 @@ switch (type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: - priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_type = MWIFIEX_BSS_TYPE_STA; break; case NL80211_IFTYPE_P2P_CLIENT: - priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_role = MWIFIEX_BSS_ROLE_STA; + priv->bss_type = MWIFIEX_BSS_TYPE_P2P; break; case NL80211_IFTYPE_P2P_GO: - priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_type = MWIFIEX_BSS_TYPE_P2P; break; case NL80211_IFTYPE_AP: priv->bss_role = MWIFIEX_BSS_ROLE_UAP; + priv->bss_type = MWIFIEX_BSS_TYPE_UAP; break; default: mwifiex_dbg(adapter, ERROR, @@ -930,6 +934,8 @@ return -EOPNOTSUPP; } + priv->bss_num = mwifiex_get_unused_bss_num(adapter, priv->bss_type); + spin_lock_irqsave(&adapter->main_proc_lock, flags); adapter->main_locked = false; spin_unlock_irqrestore(&adapter->main_proc_lock, flags); @@ -1233,29 +1239,15 @@ break; case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: + if (mwifiex_cfg80211_deinit_p2p(priv)) + return -EFAULT; + switch (type) { - case NL80211_IFTYPE_STATION: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; - priv->adapter->curr_iface_comb.p2p_intf--; - priv->adapter->curr_iface_comb.sta_intf++; - dev->ieee80211_ptr->iftype = type; - if (mwifiex_deinit_priv_params(priv)) - return -1; - if (mwifiex_init_new_priv_params(priv, dev, type)) - return -1; - if (mwifiex_sta_init_cmd(priv, false, false)) - return -1; - break; case NL80211_IFTYPE_ADHOC: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; + case NL80211_IFTYPE_STATION: return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype, type, params); - break; case NL80211_IFTYPE_AP: - if (mwifiex_cfg80211_deinit_p2p(priv)) - return -EFAULT; return mwifiex_change_vif_to_ap(dev, curr_iftype, type, params); case NL80211_IFTYPE_UNSPECIFIED: @@ -1496,7 +1488,8 @@ int idx, u8 *mac, struct station_info *sinfo) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - static struct mwifiex_sta_node *node; + struct mwifiex_sta_node *node; + int i; if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && priv->media_connected && idx == 0) { @@ -1506,13 +1499,10 @@ mwifiex_send_cmd(priv, HOST_CMD_APCMD_STA_LIST, HostCmd_ACT_GEN_GET, 0, NULL, true); - if (node && (&node->list == &priv->sta_list)) { - node = NULL; - return -ENOENT; - } - - node = list_prepare_entry(node, &priv->sta_list, list); - list_for_each_entry_continue(node, &priv->sta_list, list) { + i = 0; + list_for_each_entry(node, &priv->sta_list, list) { + if (i++ != idx) + continue; ether_addr_copy(mac, node->mac_addr); return mwifiex_dump_station_info(priv, node, sinfo); } @@ -1996,6 +1986,8 @@ mwifiex_set_sys_config_invalid_data(bss_cfg); + memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN); + if (params->beacon_interval) bss_cfg->beacon_period = params->beacon_interval; if (params->dtim_period) @@ -4327,11 +4319,27 @@ if (ISSUPP_ADHOC_ENABLED(adapter->fw_cap_info)) wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); - wiphy->bands[NL80211_BAND_2GHZ] = &mwifiex_band_2ghz; - if (adapter->config_bands & BAND_A) - wiphy->bands[NL80211_BAND_5GHZ] = &mwifiex_band_5ghz; - else + wiphy->bands[NL80211_BAND_2GHZ] = devm_kmemdup(adapter->dev, + &mwifiex_band_2ghz, + sizeof(mwifiex_band_2ghz), + GFP_KERNEL); + if (!wiphy->bands[NL80211_BAND_2GHZ]) { + ret = -ENOMEM; + goto err; + } + + if (adapter->config_bands & BAND_A) { + wiphy->bands[NL80211_BAND_5GHZ] = devm_kmemdup(adapter->dev, + &mwifiex_band_5ghz, + sizeof(mwifiex_band_5ghz), + GFP_KERNEL); + if (!wiphy->bands[NL80211_BAND_5GHZ]) { + ret = -ENOMEM; + goto err; + } + } else { wiphy->bands[NL80211_BAND_5GHZ] = NULL; + } if (adapter->drcs_enabled && ISSUPP_DRCS_ENABLED(adapter->fw_cap_info)) wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta_drcs; @@ -4419,8 +4427,7 @@ if (ret < 0) { mwifiex_dbg(adapter, ERROR, "%s: wiphy_register failed: %d\n", __func__, ret); - wiphy_free(wiphy); - return ret; + goto err; } if (!adapter->regd) { @@ -4462,4 +4469,9 @@ adapter->wiphy = wiphy; return ret; + +err: + wiphy_free(wiphy); + + return ret; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -322,9 +322,9 @@ adapter->seq_num++; sleep_cfm_buf->seq_num = - cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO + cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO (adapter->seq_num, priv->bss_num, - priv->bss_type))); + priv->bss_type)); mwifiex_dbg(adapter, CMD, "cmd: DNLD_CMD: %#x, act %#x, len %d, seqno %#x\n", --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/debugfs.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/debugfs.c @@ -265,8 +265,11 @@ if (!p) return -ENOMEM; - if (!priv || !priv->hist_data) - return -EFAULT; + if (!priv || !priv->hist_data) { + ret = -EFAULT; + goto free_and_exit; + } + phist_data = priv->hist_data; p += sprintf(p, "\n" @@ -321,6 +324,8 @@ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page, (unsigned long)p - page); +free_and_exit: + free_page(page); return ret; } @@ -971,9 +976,6 @@ priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name, mwifiex_dfs_dir); - if (!priv->dfs_dev_dir) - return; - MWIFIEX_DFS_ADD_FILE(info); MWIFIEX_DFS_ADD_FILE(debug); MWIFIEX_DFS_ADD_FILE(getlog); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/fw.h +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/fw.h @@ -177,6 +177,7 @@ #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) +#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) @@ -217,6 +218,7 @@ #define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) #define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202) #define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203) +#define TLV_TYPE_LED_CONTROL (PROPRIETARY_TLV_BASE_ID + 205) #define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206) #define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236) #define TLV_TYPE_CHAN_ATTR_CFG (PROPRIETARY_TLV_BASE_ID + 237) @@ -363,6 +365,7 @@ #define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c #define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040 #define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D +#define HostCmd_CMD_802_11_LED_CONTROL 0X004E #define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b #define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e #define HostCmd_CMD_802_11_BG_SCAN_CONFIG 0x006b @@ -512,10 +515,10 @@ #define RF_ANTENNA_AUTO 0xFFFF -#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) { \ - (((seq) & 0x00ff) | \ - (((num) & 0x000f) << 8)) | \ - (((type) & 0x000f) << 12); } +#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) \ + ((((seq) & 0x00ff) | \ + (((num) & 0x000f) << 8)) | \ + (((type) & 0x000f) << 12)) #define HostCmd_GET_SEQ_NO(seq) \ ((seq) & HostCmd_SEQ_NUM_MASK) @@ -852,7 +855,7 @@ struct mwifiex_ie_types_wildcard_ssid_params { struct mwifiex_ie_types_header header; u8 max_ssid_length; - u8 ssid[1]; + u8 ssid[]; } __packed; #define TSF_DATA_SIZE 8 @@ -953,7 +956,7 @@ struct mwifiex_aes_param { u8 pn[WPA_PN_SIZE]; __le16 key_len; - u8 key[WLAN_KEY_LEN_CCMP]; + u8 key[WLAN_KEY_LEN_CCMP_256]; } __packed; struct mwifiex_wapi_param { @@ -1193,6 +1196,16 @@ u8 oper_mode; } __packed; +struct mwifiex_led_param { + __le16 mode; + __le16 on; +} __packed; + +struct mwifiex_ie_types_led_param { + struct mwifiex_ie_types_header header; + struct mwifiex_led_param led_cfg; +} __packed; + struct host_cmd_ds_802_11_ad_hoc_start { u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 bss_mode; @@ -1316,6 +1329,11 @@ } params; } __packed; +struct host_cmd_ds_802_11_led_control { + __le16 action; + __le16 num_led; +} __packed; + enum SNMP_MIB_INDEX { OP_RATE_SET_I = 1, DTIM_PERIOD_I = 3, @@ -1589,7 +1607,7 @@ struct host_cmd_ds_802_11_scan_ext { u32 reserved; - u8 tlv_buffer[1]; + u8 tlv_buffer[]; } __packed; struct mwifiex_ie_types_bss_mode { @@ -2370,6 +2388,7 @@ struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; struct host_cmd_ds_multi_chan_policy mc_policy; struct host_cmd_ds_robust_coex coex; + struct host_cmd_ds_802_11_led_control led_cfg; struct host_cmd_ds_wakeup_reason hs_wakeup_reason; struct host_cmd_ds_gtk_rekey_params rekey; struct host_cmd_ds_chan_region_cfg reg_cfg; --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/ioctl.h +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/ioctl.h @@ -119,6 +119,7 @@ u8 qos_info; u8 power_constraint; struct mwifiex_types_wmm_info wmm_info; + u8 mac_addr[ETH_ALEN]; }; enum { --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/join.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/join.c @@ -877,6 +877,8 @@ memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN); + if (req_ssid->ssid_len > IEEE80211_MAX_SSID_LEN) + req_ssid->ssid_len = IEEE80211_MAX_SSID_LEN; memcpy(adhoc_start->ssid, req_ssid->ssid, req_ssid->ssid_len); mwifiex_dbg(adapter, INFO, "info: ADHOC_S_CMD: SSID = %s\n", --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/main.c @@ -631,6 +631,7 @@ mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); mwifiex_dbg(adapter, MSG, "driver_version = %s\n", fmt); + adapter->is_up = true; goto done; err_add_intf: @@ -727,8 +728,10 @@ static int mwifiex_open(struct net_device *dev) { - netif_carrier_off(dev); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + netif_carrier_off(dev); + mwifiex_set_led(priv->adapter, MWIFIEX_LED_ON); return 0; } @@ -759,6 +762,7 @@ cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); } + mwifiex_set_led(priv->adapter, MWIFIEX_LED_OFF); return 0; } @@ -1468,7 +1472,10 @@ priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); mwifiex_deauthenticate(priv, NULL); + mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); + mwifiex_uninit_sw(adapter); + adapter->is_up = false; if (adapter->if_ops.down_dev) adapter->if_ops.down_dev(adapter); @@ -1596,7 +1603,8 @@ } ret = devm_request_irq(dev, adapter->irq_wakeup, - mwifiex_irq_wakeup_handler, IRQF_TRIGGER_LOW, + mwifiex_irq_wakeup_handler, + IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN, "wifi_wake", adapter); if (ret) { dev_err(dev, "Failed to request irq_wakeup %d (%d)\n", @@ -1604,7 +1612,6 @@ goto err_exit; } - disable_irq(adapter->irq_wakeup); if (device_init_wakeup(dev, true)) { dev_err(dev, "fail to init wakeup for mwifiex\n"); goto err_exit; @@ -1730,7 +1737,8 @@ if (!adapter) return 0; - mwifiex_uninit_sw(adapter); + if (adapter->is_up) + mwifiex_uninit_sw(adapter); if (adapter->irq_wakeup >= 0) device_init_wakeup(adapter->dev, false); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/main.h +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/main.h @@ -132,6 +132,10 @@ #define PKT_TYPE_MGMT 0xE5 +#define MWIFIEX_LED_ON 1 +#define MWIFIEX_LED_OFF 0 +#define MWIFIEX_LED_MAX 3 + /* * Do not check for data_received for USB, as data_received * is handled in mwifiex_usb_recv for USB @@ -700,6 +704,7 @@ struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX]; u8 assoc_resp_ht_param; bool ht_param_present; + bool is_edge_gateway; }; @@ -1017,6 +1022,7 @@ /* For synchronizing FW initialization with device lifecycle. */ struct completion *fw_done; + bool is_up; bool ext_scan; u8 fw_api_ver; @@ -1294,19 +1300,6 @@ return pos; } -/* This function return interface number with the same bss_type. - */ -static inline u8 -mwifiex_get_intf_num(struct mwifiex_adapter *adapter, u8 bss_type) -{ - u8 i, num = 0; - - for (i = 0; i < adapter->priv_num; i++) - if (adapter->priv[i] && adapter->priv[i]->bss_type == bss_type) - num++; - return num; -} - /* * This function returns the correct private structure pointer based * upon the BSS type and BSS number. @@ -1319,6 +1312,9 @@ for (i = 0; i < adapter->priv_num; i++) { if (adapter->priv[i]) { + if (adapter->priv[i]->bss_mode == NL80211_IFTYPE_UNSPECIFIED) + continue; + if ((adapter->priv[i]->bss_num == bss_num) && (adapter->priv[i]->bss_type == bss_type)) break; @@ -1506,6 +1502,7 @@ struct cmd_ctrl_node *cmd_queued); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, struct cfg80211_ssid *req_ssid); +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); int mwifiex_disable_auto_ds(struct mwifiex_private *priv); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/pcie.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -50,6 +50,8 @@ } static void mwifiex_pcie_work(struct work_struct *work); +static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter); +static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter); static int mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, @@ -58,8 +60,8 @@ struct pcie_service_card *card = adapter->card; struct mwifiex_dma_mapping mapping; - mapping.addr = pci_map_single(card->dev, skb->data, size, flags); - if (pci_dma_mapping_error(card->dev, mapping.addr)) { + mapping.addr = dma_map_single(&card->dev->dev, skb->data, size, flags); + if (dma_mapping_error(&card->dev->dev, mapping.addr)) { mwifiex_dbg(adapter, ERROR, "failed to map pci memory!\n"); return -1; } @@ -75,7 +77,7 @@ struct mwifiex_dma_mapping mapping; mwifiex_get_mapping(skb, &mapping); - pci_unmap_single(card->dev, mapping.addr, mapping.len, flags); + dma_unmap_single(&card->dev->dev, mapping.addr, mapping.len, flags); } /* @@ -229,6 +231,8 @@ const struct pci_device_id *ent) { struct pcie_service_card *card; + struct mwifiex_private *priv; + struct pci_dev *pdev_host; int ret; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", @@ -267,6 +271,14 @@ return -1; } + priv = mwifiex_get_priv(card->adapter, MWIFIEX_BSS_ROLE_STA); + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); + if (!pdev_host) + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); + if (pdev_host) { + priv->is_edge_gateway = true; + pci_dev_put(pdev_host); + } return 0; } @@ -377,6 +389,8 @@ clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = true; } /* @@ -405,6 +419,8 @@ dev_err(&pdev->dev, "reinit failed: %d\n", ret); else mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = false; } static const struct pci_error_handlers mwifiex_pcie_err_handler = { @@ -461,10 +477,9 @@ struct sk_buff *cmdrsp = card->cmdrsp_buf; for (count = 0; count < max_delay_loop_cnt; count++) { - pci_dma_sync_single_for_cpu(card->dev, - MWIFIEX_SKB_DMA_ADDR(cmdrsp), - sizeof(sleep_cookie), - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&card->dev->dev, + MWIFIEX_SKB_DMA_ADDR(cmdrsp), + sizeof(sleep_cookie), DMA_FROM_DEVICE); buffer = cmdrsp->data; sleep_cookie = get_unaligned_le32(buffer); @@ -473,10 +488,10 @@ "sleep cookie found at count %d\n", count); break; } - pci_dma_sync_single_for_device(card->dev, - MWIFIEX_SKB_DMA_ADDR(cmdrsp), - sizeof(sleep_cookie), - PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(&card->dev->dev, + MWIFIEX_SKB_DMA_ADDR(cmdrsp), + sizeof(sleep_cookie), + DMA_FROM_DEVICE); usleep_range(20, 30); } @@ -624,14 +639,15 @@ if (!skb) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb for RX ring.\n"); - kfree(card->rxbd_ring_vbase); return -ENOMEM; } if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; + DMA_FROM_DEVICE)) { + kfree_skb(skb); + return -ENOMEM; + } buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); @@ -681,14 +697,15 @@ if (!skb) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb for EVENT buf.\n"); - kfree(card->evtbd_ring_vbase); return -ENOMEM; } skb_put(skb, MAX_EVENT_SIZE); if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; + DMA_FROM_DEVICE)) { + kfree_skb(skb); + return -ENOMEM; + } buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); @@ -727,7 +744,7 @@ if (card->tx_buf_list[i]) { skb = card->tx_buf_list[i]; mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); dev_kfree_skb_any(skb); } memset(desc2, 0, sizeof(*desc2)); @@ -736,7 +753,7 @@ if (card->tx_buf_list[i]) { skb = card->tx_buf_list[i]; mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); dev_kfree_skb_any(skb); } memset(desc, 0, sizeof(*desc)); @@ -766,7 +783,7 @@ if (card->rx_buf_list[i]) { skb = card->rx_buf_list[i]; mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb_any(skb); } memset(desc2, 0, sizeof(*desc2)); @@ -775,7 +792,7 @@ if (card->rx_buf_list[i]) { skb = card->rx_buf_list[i]; mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb_any(skb); } memset(desc, 0, sizeof(*desc)); @@ -801,7 +818,7 @@ if (card->evt_buf_list[i]) { skb = card->evt_buf_list[i]; mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb_any(skb); } card->evt_buf_list[i] = NULL; @@ -842,9 +859,10 @@ mwifiex_dbg(adapter, INFO, "info: txbd_ring: Allocating %d bytes\n", card->txbd_ring_size); - card->txbd_ring_vbase = pci_alloc_consistent(card->dev, - card->txbd_ring_size, - &card->txbd_ring_pbase); + card->txbd_ring_vbase = dma_alloc_coherent(&card->dev->dev, + card->txbd_ring_size, + &card->txbd_ring_pbase, + GFP_KERNEL); if (!card->txbd_ring_vbase) { mwifiex_dbg(adapter, ERROR, "allocate consistent memory (%d bytes) failed!\n", @@ -868,9 +886,9 @@ mwifiex_cleanup_txq_ring(adapter); if (card->txbd_ring_vbase) - pci_free_consistent(card->dev, card->txbd_ring_size, - card->txbd_ring_vbase, - card->txbd_ring_pbase); + dma_free_coherent(&card->dev->dev, card->txbd_ring_size, + card->txbd_ring_vbase, + card->txbd_ring_pbase); card->txbd_ring_size = 0; card->txbd_wrptr = 0; card->txbd_rdptr = 0 | reg->tx_rollover_ind; @@ -885,6 +903,7 @@ */ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) { + int ret; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -906,9 +925,10 @@ mwifiex_dbg(adapter, INFO, "info: rxbd_ring: Allocating %d bytes\n", card->rxbd_ring_size); - card->rxbd_ring_vbase = pci_alloc_consistent(card->dev, - card->rxbd_ring_size, - &card->rxbd_ring_pbase); + card->rxbd_ring_vbase = dma_alloc_coherent(&card->dev->dev, + card->rxbd_ring_size, + &card->rxbd_ring_pbase, + GFP_KERNEL); if (!card->rxbd_ring_vbase) { mwifiex_dbg(adapter, ERROR, "allocate consistent memory (%d bytes) failed!\n", @@ -922,7 +942,10 @@ (u32)((u64)card->rxbd_ring_pbase >> 32), card->rxbd_ring_size); - return mwifiex_init_rxq_ring(adapter); + ret = mwifiex_init_rxq_ring(adapter); + if (ret) + mwifiex_pcie_delete_rxbd_ring(adapter); + return ret; } /* @@ -936,9 +959,9 @@ mwifiex_cleanup_rxq_ring(adapter); if (card->rxbd_ring_vbase) - pci_free_consistent(card->dev, card->rxbd_ring_size, - card->rxbd_ring_vbase, - card->rxbd_ring_pbase); + dma_free_coherent(&card->dev->dev, card->rxbd_ring_size, + card->rxbd_ring_vbase, + card->rxbd_ring_pbase); card->rxbd_ring_size = 0; card->rxbd_wrptr = 0; card->rxbd_rdptr = 0 | reg->rx_rollover_ind; @@ -953,6 +976,7 @@ */ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) { + int ret; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -970,9 +994,10 @@ mwifiex_dbg(adapter, INFO, "info: evtbd_ring: Allocating %d bytes\n", card->evtbd_ring_size); - card->evtbd_ring_vbase = pci_alloc_consistent(card->dev, - card->evtbd_ring_size, - &card->evtbd_ring_pbase); + card->evtbd_ring_vbase = dma_alloc_coherent(&card->dev->dev, + card->evtbd_ring_size, + &card->evtbd_ring_pbase, + GFP_KERNEL); if (!card->evtbd_ring_vbase) { mwifiex_dbg(adapter, ERROR, "allocate consistent memory (%d bytes) failed!\n", @@ -986,7 +1011,10 @@ (u32)((u64)card->evtbd_ring_pbase >> 32), card->evtbd_ring_size); - return mwifiex_pcie_init_evt_ring(adapter); + ret = mwifiex_pcie_init_evt_ring(adapter); + if (ret) + mwifiex_pcie_delete_evtbd_ring(adapter); + return ret; } /* @@ -1000,9 +1028,9 @@ mwifiex_cleanup_evt_ring(adapter); if (card->evtbd_ring_vbase) - pci_free_consistent(card->dev, card->evtbd_ring_size, - card->evtbd_ring_vbase, - card->evtbd_ring_pbase); + dma_free_coherent(&card->dev->dev, card->evtbd_ring_size, + card->evtbd_ring_vbase, + card->evtbd_ring_pbase); card->evtbd_wrptr = 0; card->evtbd_rdptr = 0 | reg->evt_rollover_ind; card->evtbd_ring_size = 0; @@ -1029,8 +1057,10 @@ } skb_put(skb, MWIFIEX_UPLD_SIZE); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) + DMA_FROM_DEVICE)) { + kfree_skb(skb); return -1; + } card->cmdrsp_buf = skb; @@ -1051,14 +1081,14 @@ if (card && card->cmdrsp_buf) { mwifiex_unmap_pci_memory(adapter, card->cmdrsp_buf, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); dev_kfree_skb_any(card->cmdrsp_buf); card->cmdrsp_buf = NULL; } if (card && card->cmd_buf) { mwifiex_unmap_pci_memory(adapter, card->cmd_buf, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); dev_kfree_skb_any(card->cmd_buf); card->cmd_buf = NULL; } @@ -1071,22 +1101,22 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - u32 tmp; + u32 *cookie; - card->sleep_cookie_vbase = pci_alloc_consistent(card->dev, sizeof(u32), - &card->sleep_cookie_pbase); + card->sleep_cookie_vbase = dma_alloc_coherent(&card->dev->dev, + sizeof(u32), + &card->sleep_cookie_pbase, + GFP_KERNEL); if (!card->sleep_cookie_vbase) { mwifiex_dbg(adapter, ERROR, "pci_alloc_consistent failed!\n"); return -ENOMEM; } + cookie = (u32 *)card->sleep_cookie_vbase; /* Init val of Sleep Cookie */ - tmp = FW_AWAKE_COOKIE; - put_unaligned(tmp, card->sleep_cookie_vbase); + *cookie = FW_AWAKE_COOKIE; - mwifiex_dbg(adapter, INFO, - "alloc_scook: sleep cookie=0x%x\n", - get_unaligned(card->sleep_cookie_vbase)); + mwifiex_dbg(adapter, INFO, "alloc_scook: sleep cookie=0x%x\n", *cookie); return 0; } @@ -1104,9 +1134,9 @@ card = adapter->card; if (card && card->sleep_cookie_vbase) { - pci_free_consistent(card->dev, sizeof(u32), - card->sleep_cookie_vbase, - card->sleep_cookie_pbase); + dma_free_coherent(&card->dev->dev, sizeof(u32), + card->sleep_cookie_vbase, + card->sleep_cookie_pbase); card->sleep_cookie_vbase = NULL; } @@ -1178,7 +1208,7 @@ "SEND COMP: Detach skb %p at txbd_rdidx=%d\n", skb, wrdoneidx); mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); unmap_count++; @@ -1271,7 +1301,7 @@ put_unaligned_le16(MWIFIEX_TYPE_DATA, payload + 2); if (mwifiex_map_pci_memory(adapter, skb, skb->len, - PCI_DMA_TODEVICE)) + DMA_TO_DEVICE)) return -1; wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; @@ -1319,6 +1349,14 @@ ret = -1; goto done_unmap; } + + /* The firmware (latest version 15.68.19.p21) of the 88W8897 PCIe+USB card + * seems to crash randomly after setting the TX ring write pointer when + * ASPM powersaving is enabled. A workaround seems to be keeping the bus + * busy by reading a random register afterwards. + */ + mwifiex_read_reg(adapter, PCI_VENDOR_ID, &rx_val); + if ((mwifiex_pcie_txbd_not_full(card)) && tx_param->next_pkt_len) { /* have more packets and TxBD still can hold more */ @@ -1353,7 +1391,7 @@ return -EINPROGRESS; done_unmap: - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); card->tx_buf_list[wrindx] = NULL; atomic_dec(&adapter->tx_hw_pending); if (reg->pfu_enabled) @@ -1407,7 +1445,7 @@ if (!skb_data) return -ENOMEM; - mwifiex_unmap_pci_memory(adapter, skb_data, PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb_data, DMA_FROM_DEVICE); card->rx_buf_list[rd_index] = NULL; /* Get data length from interface header - @@ -1445,7 +1483,7 @@ if (mwifiex_map_pci_memory(adapter, skb_tmp, MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE)) + DMA_FROM_DEVICE)) return -1; buf_pa = MWIFIEX_SKB_DMA_ADDR(skb_tmp); @@ -1522,7 +1560,7 @@ return -1; } - if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE)) + if (mwifiex_map_pci_memory(adapter, skb, skb->len, DMA_TO_DEVICE)) return -1; buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); @@ -1534,7 +1572,7 @@ mwifiex_dbg(adapter, ERROR, "%s: failed to write download command to boot code.\n", __func__); - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); return -1; } @@ -1546,7 +1584,7 @@ mwifiex_dbg(adapter, ERROR, "%s: failed to write download command to boot code.\n", __func__); - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); return -1; } @@ -1555,7 +1593,7 @@ mwifiex_dbg(adapter, ERROR, "%s: failed to write command len to cmd_size scratch reg\n", __func__); - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); return -1; } @@ -1564,7 +1602,7 @@ CPU_INTR_DOOR_BELL)) { mwifiex_dbg(adapter, ERROR, "%s: failed to assert door-bell intr\n", __func__); - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); return -1; } @@ -1623,7 +1661,7 @@ put_unaligned_le16((u16)skb->len, &payload[0]); put_unaligned_le16(MWIFIEX_TYPE_CMD, &payload[2]); - if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE)) + if (mwifiex_map_pci_memory(adapter, skb, skb->len, DMA_TO_DEVICE)) return -1; card->cmd_buf = skb; @@ -1723,17 +1761,16 @@ "info: Rx CMD Response\n"); if (adapter->curr_cmd) - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_FROM_DEVICE); else - pci_dma_sync_single_for_cpu(card->dev, - MWIFIEX_SKB_DMA_ADDR(skb), - MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_cpu(&card->dev->dev, + MWIFIEX_SKB_DMA_ADDR(skb), + MWIFIEX_UPLD_SIZE, DMA_FROM_DEVICE); /* Unmap the command as a response has been received. */ if (card->cmd_buf) { mwifiex_unmap_pci_memory(adapter, card->cmd_buf, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); dev_kfree_skb_any(card->cmd_buf); card->cmd_buf = NULL; } @@ -1744,10 +1781,10 @@ if (!adapter->curr_cmd) { if (adapter->ps_state == PS_STATE_SLEEP_CFM) { - pci_dma_sync_single_for_device(card->dev, - MWIFIEX_SKB_DMA_ADDR(skb), - MWIFIEX_SLEEP_COOKIE_SIZE, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(&card->dev->dev, + MWIFIEX_SKB_DMA_ADDR(skb), + MWIFIEX_SLEEP_COOKIE_SIZE, + DMA_FROM_DEVICE); if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_SLEEP_CFM_DONE)) { @@ -1758,7 +1795,7 @@ mwifiex_delay_for_sleep_cookie(adapter, MWIFIEX_MAX_DELAY_COUNT); mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); skb_pull(skb, adapter->intf_hdr_len); while (reg->sleep_cookie && (count++ < 10) && mwifiex_pcie_ok_to_access_hw(adapter)) @@ -1774,7 +1811,7 @@ min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); skb_push(skb, adapter->intf_hdr_len); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) + DMA_FROM_DEVICE)) return -1; } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { skb_pull(skb, adapter->intf_hdr_len); @@ -1816,7 +1853,7 @@ card->cmdrsp_buf = skb; skb_push(card->cmdrsp_buf, adapter->intf_hdr_len); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, - PCI_DMA_FROMDEVICE)) + DMA_FROM_DEVICE)) return -1; } @@ -1871,7 +1908,7 @@ mwifiex_dbg(adapter, INFO, "info: Read Index: %d\n", rdptr); skb_cmd = card->evt_buf_list[rdptr]; - mwifiex_unmap_pci_memory(adapter, skb_cmd, PCI_DMA_FROMDEVICE); + mwifiex_unmap_pci_memory(adapter, skb_cmd, DMA_FROM_DEVICE); /* Take the pointer and set it to event pointer in adapter and will return back after event handling callback */ @@ -1951,7 +1988,7 @@ skb_put(skb, MAX_EVENT_SIZE - skb->len); if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE)) + DMA_FROM_DEVICE)) return -1; card->evt_buf_list[rdptr] = skb; desc = card->evtbd_ring[rdptr]; @@ -2233,7 +2270,7 @@ "interrupt status during fw dnld.\n", __func__); mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); ret = -1; goto done; } @@ -2245,12 +2282,12 @@ mwifiex_dbg(adapter, ERROR, "%s: Card failed to ACK download\n", __func__); mwifiex_unmap_pci_memory(adapter, skb, - PCI_DMA_TODEVICE); + DMA_TO_DEVICE); ret = -1; goto done; } - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE); + mwifiex_unmap_pci_memory(adapter, skb, DMA_TO_DEVICE); offset += txlen; } while (true); @@ -2920,13 +2957,13 @@ pci_set_master(pdev); - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { pr_err("set_dma_mask(32) failed: %d\n", ret); goto err_set_dma_mask; } - ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { pr_err("set_consistent_dma_mask(64) failed\n"); goto err_set_dma_mask; @@ -2990,7 +3027,19 @@ int ret; u32 fw_status; - cancel_work_sync(&card->work); + /* Perform the cancel_work_sync() only when we're not resetting + * the card. It's because that function never returns if we're + * in reset path. If we're here when resetting the card, it means + * that we failed to reset the card (reset failure path). + */ + if (!card->pci_reset_ongoing) { + mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n"); + cancel_work_sync(&card->work); + mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n"); + } else { + mwifiex_dbg(adapter, MSG, + "skipped cancel_work_sync() because we're in card reset failure path\n"); + } ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); if (fw_status == FIRMWARE_READY_PCIE) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/pcie.h +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -391,6 +391,8 @@ struct mwifiex_msix_context share_irq_ctx; struct work_struct work; unsigned long work_flags; + + bool pci_reset_ongoing; }; static inline int --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/scan.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1891,7 +1891,7 @@ chan, CFG80211_BSS_FTYPE_UNKNOWN, bssid, timestamp, cap_info_bitmap, beacon_period, - ie_buf, ie_len, rssi, GFP_KERNEL); + ie_buf, ie_len, rssi, GFP_ATOMIC); if (bss) { bss_priv = (struct mwifiex_bss_priv *)bss->priv; bss_priv->band = band; @@ -2202,9 +2202,9 @@ if (nd_config) { adapter->nd_info = - kzalloc(sizeof(struct cfg80211_wowlan_nd_match) + - sizeof(struct cfg80211_wowlan_nd_match *) * - scan_rsp->number_of_sets, GFP_ATOMIC); + kzalloc(struct_size(adapter->nd_info, matches, + scan_rsp->number_of_sets), + GFP_ATOMIC); if (adapter->nd_info) adapter->nd_info->n_matches = scan_rsp->number_of_sets; @@ -2563,8 +2563,7 @@ ext_scan_resp = &resp->params.ext_scan; tlv = (void *)ext_scan_resp->tlv_buffer; - buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN - - 1); + buf_left = le16_to_cpu(resp->size) - (sizeof(*ext_scan_resp) + S_DS_GEN); while (buf_left >= sizeof(struct mwifiex_ie_types_header)) { type = le16_to_cpu(tlv->type); @@ -2886,6 +2885,13 @@ vs_param_set->header.len = cpu_to_le16((((u16) priv->vs_ie[id].ie[1]) & 0x00FF) + 2); + if (le16_to_cpu(vs_param_set->header.len) > + MWIFIEX_MAX_VSIE_LEN) { + mwifiex_dbg(priv->adapter, ERROR, + "Invalid param length!\n"); + break; + } + memcpy(vs_param_set->ie, priv->vs_ie[id].ie, le16_to_cpu(vs_param_set->header.len)); *buffer += le16_to_cpu(vs_param_set->header.len) + --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -58,6 +58,7 @@ }; static const struct of_device_id mwifiex_sdio_of_match_table[] = { + { .compatible = "marvell,sd8787" }, { .compatible = "marvell,sd8897" }, { .compatible = "marvell,sd8997" }, { } @@ -444,6 +445,9 @@ return 0; } + if (!adapter->is_up) + return -EBUSY; + mwifiex_enable_wake(adapter); /* Enable the Host Sleep */ @@ -1993,6 +1997,8 @@ kfree(card->mpa_rx.buf); card->mpa_tx.buf_size = 0; card->mpa_rx.buf_size = 0; + card->mpa_tx.buf = NULL; + card->mpa_rx.buf = NULL; } return ret; @@ -2220,22 +2226,30 @@ struct sdio_func *func = card->func; int ret; + /* Prepare the adapter for the reset. */ mwifiex_shutdown_sw(adapter); + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - /* power cycle the adapter */ + /* Run a HW reset of the SDIO interface. */ sdio_claim_host(func); - mmc_hw_reset(func->card->host); + ret = mmc_hw_reset(func->card->host); sdio_release_host(func); - /* Previous save_adapter won't be valid after this. We will cancel - * pending work requests. - */ - clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); - clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - - ret = mwifiex_reinit_sw(adapter); - if (ret) - dev_err(&func->dev, "reinit failed: %d\n", ret); + switch (ret) { + case 1: + dev_dbg(&func->dev, "SDIO HW reset asynchronous\n"); + complete_all(adapter->fw_done); + break; + case 0: + ret = mwifiex_reinit_sw(adapter); + if (ret) + dev_err(&func->dev, "reinit failed: %d\n", ret); + break; + default: + dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret); + break; + } } /* This function read/write firmware */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sdio.h +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -36,9 +36,9 @@ #define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin" #define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin" #define SD8801_DEFAULT_FW_NAME "mrvl/sd8801_uapsta.bin" -#define SD8977_DEFAULT_FW_NAME "mrvl/sd8977_uapsta.bin" +#define SD8977_DEFAULT_FW_NAME "mrvl/sdsd8977_combo_v2.bin" #define SD8987_DEFAULT_FW_NAME "mrvl/sd8987_uapsta.bin" -#define SD8997_DEFAULT_FW_NAME "mrvl/sd8997_uapsta.bin" +#define SD8997_DEFAULT_FW_NAME "mrvl/sdsd8997_combo_v4.bin" #define BLOCK_MODE 1 #define BYTE_MODE 0 --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -424,6 +424,31 @@ return 0; } +static int mwifiex_cmd_802_11_led_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_led_param *ledcfg_param) +{ + struct host_cmd_ds_802_11_led_control *led_cfg = &cmd->params.led_cfg; + struct mwifiex_ie_types_led_param *led_tlv; + u8 *pos; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_LED_CONTROL); + cmd->size = cpu_to_le16(S_DS_GEN); + le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_802_11_led_control)); + + led_cfg->action = cpu_to_le16(cmd_action); + led_cfg->num_led = cpu_to_le16(MWIFIEX_LED_MAX); + + pos = (u8 *)led_cfg + sizeof(struct host_cmd_ds_802_11_led_control); + led_tlv = (void *)pos; + led_tlv->header.type = cpu_to_le16(TLV_TYPE_LED_CONTROL); + led_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_led_param)); + memcpy(&led_tlv->led_cfg, ledcfg_param, sizeof(struct mwifiex_led_param)); + le16_add_cpu(&cmd->size, sizeof(struct mwifiex_ie_types_led_param)); + return 0; +} + /* * This function prepares command to set/get MAC address. * @@ -1999,6 +2024,10 @@ ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action, (struct mwifiex_hs_config_param *) data_buf); break; + case HostCmd_CMD_802_11_LED_CONTROL: + ret = mwifiex_cmd_802_11_led_cfg(priv, cmd_ptr, cmd_action, + data_buf); + break; case HostCmd_CMD_802_11_SCAN: ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); break; --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -580,6 +580,11 @@ { struct host_cmd_ds_802_11_key_material *key = &resp->params.key_material; + int len; + + len = le16_to_cpu(key->key_param_set.key_len); + if (len > sizeof(key->key_param_set.key)) + return -EINVAL; if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) { @@ -593,9 +598,8 @@ memset(priv->aes_key.key_param_set.key, 0, sizeof(key->key_param_set.key)); - priv->aes_key.key_param_set.key_len = key->key_param_set.key_len; - memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, - le16_to_cpu(priv->aes_key.key_param_set.key_len)); + priv->aes_key.key_param_set.key_len = cpu_to_le16(len); + memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key, len); return 0; } @@ -610,9 +614,14 @@ struct host_cmd_ds_command *resp) { struct host_cmd_ds_802_11_key_material_v2 *key_v2; - __le16 len; + int len; key_v2 = &resp->params.key_material_v2; + + len = le16_to_cpu(key_v2->key_param_set.key_params.aes.key_len); + if (len > sizeof(key_v2->key_param_set.key_params.aes.key)) + return -EINVAL; + if (le16_to_cpu(key_v2->action) == HostCmd_ACT_GEN_SET) { if ((le16_to_cpu(key_v2->key_param_set.key_info) & KEY_MCAST)) { mwifiex_dbg(priv->adapter, INFO, "info: key: GTK is set\n"); @@ -626,12 +635,11 @@ return 0; memset(priv->aes_key_v2.key_param_set.key_params.aes.key, 0, - WLAN_KEY_LEN_CCMP); + sizeof(key_v2->key_param_set.key_params.aes.key)); priv->aes_key_v2.key_param_set.key_params.aes.key_len = - key_v2->key_param_set.key_params.aes.key_len; - len = priv->aes_key_v2.key_param_set.key_params.aes.key_len; + cpu_to_le16(len); memcpy(priv->aes_key_v2.key_param_set.key_params.aes.key, - key_v2->key_param_set.key_params.aes.key, le16_to_cpu(len)); + key_v2->key_param_set.key_params.aes.key, len); return 0; } @@ -1400,6 +1408,8 @@ case HostCmd_CMD_ROBUST_COEX: ret = mwifiex_ret_robust_coex(priv, resp, data_buf); break; + case HostCmd_CMD_802_11_LED_CONTROL: + break; case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: break; case HostCmd_CMD_CHAN_REGION_CFG: --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -364,10 +364,12 @@ sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { sta_ptr->tx_pause = tp->tx_pause; + spin_unlock_bh(&priv->sta_list_spinlock); mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause); + } else { + spin_unlock_bh(&priv->sta_list_spinlock); } - spin_unlock_bh(&priv->sta_list_spinlock); } } @@ -399,11 +401,13 @@ sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { sta_ptr->tx_pause = tp->tx_pause; + spin_unlock_bh(&priv->sta_list_spinlock); mwifiex_update_ralist_tx_pause(priv, tp->peermac, tp->tx_pause); + } else { + spin_unlock_bh(&priv->sta_list_spinlock); } - spin_unlock_bh(&priv->sta_list_spinlock); } } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -229,6 +229,14 @@ "11D: skip setting domain info in FW\n"); return 0; } + + if (country_ie_len > + (IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) { + rcu_read_unlock(); + mwifiex_dbg(priv->adapter, ERROR, + "11D: country_ie_len overflow!, deauth AP\n"); + return -EINVAL; + } memcpy(priv->adapter->country_code, &country_ie[2], 2); domain_info->country_code[0] = country_ie[2]; @@ -272,8 +280,9 @@ priv->scan_block = false; if (bss) { - if (adapter->region_code == 0x00) - mwifiex_process_country_ie(priv, bss); + if (adapter->region_code == 0x00 && + mwifiex_process_country_ie(priv, bss)) + return -EINVAL; /* Allocate and fill new bss descriptor */ bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), @@ -560,6 +569,24 @@ } EXPORT_SYMBOL_GPL(mwifiex_enable_hs); +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on) +{ + struct mwifiex_private *priv; + struct mwifiex_led_param ledcfg; + + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); + if (!priv->is_edge_gateway) + return -ENODEV; + + memset(&ledcfg, 0, sizeof(struct mwifiex_led_param)); + ledcfg.on = cpu_to_le16(on); + + return mwifiex_send_cmd(priv, + HostCmd_CMD_802_11_LED_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &ledcfg, true); +} + /* * IOCTL request handler to get BSS information. * --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/sta_rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/sta_rx.c @@ -98,12 +98,23 @@ rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; - if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, - sizeof(bridge_tunnel_header))) || - (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, - sizeof(rfc1042_header)) && - ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && - ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) { + if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) + + rx_pkt_off > skb->len) { + mwifiex_dbg(priv->adapter, ERROR, + "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", + skb->len, rx_pkt_off); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return -1; + } + + if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len && + ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, + sizeof(bridge_tunnel_header))) || + (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, + sizeof(rfc1042_header)) && + ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && + ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) { /* * Replace the 803 header and rfc1042 header (llc/snap) with an * EthernetII header, keep the src/dst and snap_type @@ -206,7 +217,8 @@ rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset; - if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) { + if ((rx_pkt_offset + rx_pkt_length) > skb->len || + sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) { mwifiex_dbg(adapter, ERROR, "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len, rx_pkt_offset, rx_pkt_length); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/tdls.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -734,6 +734,7 @@ int ret; u16 capab; struct ieee80211_ht_cap *ht_cap; + unsigned int extra; u8 radio, *pos; capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; @@ -752,7 +753,10 @@ switch (action_code) { case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: - skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); + /* See the layout of 'struct ieee80211_mgmt'. */ + extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + + sizeof(mgmt->u.action.category); + skb_put(skb, extra); mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; @@ -761,8 +765,7 @@ mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(capab); /* move back for addr4 */ - memmove(pos + ETH_ALEN, &mgmt->u.action.category, - sizeof(mgmt->u.action.u.tdls_discover_resp)); + memmove(pos + ETH_ALEN, &mgmt->u.action, extra); /* init address 4 */ eth_broadcast_addr(pos); @@ -894,7 +897,7 @@ u8 *peer, *pos, *end; u8 i, action, basic; u16 cap = 0; - int ie_len = 0; + int ies_len = 0; if (len < (sizeof(struct ethhdr) + 3)) return; @@ -916,7 +919,7 @@ pos = buf + sizeof(struct ethhdr) + 4; /* payload 1+ category 1 + action 1 + dialog 1 */ cap = get_unaligned_le16(pos); - ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; + ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN; pos += 2; break; @@ -926,7 +929,7 @@ /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/ pos = buf + sizeof(struct ethhdr) + 6; cap = get_unaligned_le16(pos); - ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; + ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN; pos += 2; break; @@ -934,7 +937,7 @@ if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN)) return; pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN; - ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; + ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN; break; default: mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n"); @@ -947,65 +950,104 @@ sta_ptr->tdls_cap.capab = cpu_to_le16(cap); - for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) { - if (pos + 2 + pos[1] > end) + for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) { + u8 ie_len = pos[1]; + + if (pos + 2 + ie_len > end) break; switch (*pos) { case WLAN_EID_SUPP_RATES: - sta_ptr->tdls_cap.rates_len = pos[1]; - for (i = 0; i < pos[1]; i++) + if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; + sta_ptr->tdls_cap.rates_len = ie_len; + for (i = 0; i < ie_len; i++) sta_ptr->tdls_cap.rates[i] = pos[i + 2]; break; case WLAN_EID_EXT_SUPP_RATES: + if (ie_len > sizeof(sta_ptr->tdls_cap.rates)) + return; basic = sta_ptr->tdls_cap.rates_len; - for (i = 0; i < pos[1]; i++) + if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic) + return; + for (i = 0; i < ie_len; i++) sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2]; - sta_ptr->tdls_cap.rates_len += pos[1]; + sta_ptr->tdls_cap.rates_len += ie_len; break; case WLAN_EID_HT_CAPABILITY: - memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos, + if (ie_len != sizeof(struct ieee80211_ht_cap)) + return; + /* copy the ie's value into ht_capb*/ + memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2, sizeof(struct ieee80211_ht_cap)); sta_ptr->is_11n_enabled = 1; break; case WLAN_EID_HT_OPERATION: - memcpy(&sta_ptr->tdls_cap.ht_oper, pos, + if (ie_len != sizeof(struct ieee80211_ht_operation)) + return; + /* copy the ie's value into ht_oper*/ + memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2, sizeof(struct ieee80211_ht_operation)); break; case WLAN_EID_BSS_COEX_2040: + if (ie_len != sizeof(pos[2])) + return; sta_ptr->tdls_cap.coex_2040 = pos[2]; break; case WLAN_EID_EXT_CAPABILITY: + if (ie_len < sizeof(struct ieee_types_header)) + return; + if (ie_len > 8) + return; memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos, sizeof(struct ieee_types_header) + - min_t(u8, pos[1], 8)); + min_t(u8, ie_len, 8)); break; case WLAN_EID_RSN: + if (ie_len < sizeof(struct ieee_types_header)) + return; + if (ie_len > IEEE_MAX_IE_SIZE - + sizeof(struct ieee_types_header)) + return; memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, sizeof(struct ieee_types_header) + - min_t(u8, pos[1], IEEE_MAX_IE_SIZE - + min_t(u8, ie_len, IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header))); break; case WLAN_EID_QOS_CAPA: + if (ie_len != sizeof(pos[2])) + return; sta_ptr->tdls_cap.qos_info = pos[2]; break; case WLAN_EID_VHT_OPERATION: - if (priv->adapter->is_hw_11ac_capable) - memcpy(&sta_ptr->tdls_cap.vhtoper, pos, + if (priv->adapter->is_hw_11ac_capable) { + if (ie_len != + sizeof(struct ieee80211_vht_operation)) + return; + /* copy the ie's value into vhtoper*/ + memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2, sizeof(struct ieee80211_vht_operation)); + } break; case WLAN_EID_VHT_CAPABILITY: if (priv->adapter->is_hw_11ac_capable) { - memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos, + if (ie_len != sizeof(struct ieee80211_vht_cap)) + return; + /* copy the ie's value into vhtcap*/ + memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2, sizeof(struct ieee80211_vht_cap)); sta_ptr->is_11ac_enabled = 1; } break; case WLAN_EID_AID: - if (priv->adapter->is_hw_11ac_capable) + if (priv->adapter->is_hw_11ac_capable) { + if (ie_len != sizeof(u16)) + return; sta_ptr->tdls_cap.aid = get_unaligned_le16((pos + 2)); + } + break; default: break; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/uap_cmd.c @@ -479,6 +479,7 @@ static int mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) { + struct host_cmd_tlv_mac_addr *mac_tlv; struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_ssid *ssid; @@ -498,6 +499,13 @@ int i; u16 cmd_size = *param_size; + mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv; + mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS); + mac_tlv->header.len = cpu_to_le16(ETH_ALEN); + memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN); + cmd_size += sizeof(struct host_cmd_tlv_mac_addr); + tlv += sizeof(struct host_cmd_tlv_mac_addr); + if (bss_cfg->ssid.ssid_len) { ssid = (struct host_cmd_tlv_ssid *)tlv; ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/uap_txrx.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/uap_txrx.c @@ -115,6 +115,16 @@ return; } + if (sizeof(*rx_pkt_hdr) + + le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) { + mwifiex_dbg(adapter, ERROR, + "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n", + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return; + } + if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, sizeof(bridge_tunnel_header))) || (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, @@ -255,7 +265,15 @@ if (is_multicast_ether_addr(ra)) { skb_uap = skb_copy(skb, GFP_ATOMIC); - mwifiex_uap_queue_bridged_pkt(priv, skb_uap); + if (likely(skb_uap)) { + mwifiex_uap_queue_bridged_pkt(priv, skb_uap); + } else { + mwifiex_dbg(adapter, ERROR, + "failed to copy skb for uAP\n"); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return -1; + } } else { if (mwifiex_get_sta_entry(priv, ra)) { /* Requeue Intra-BSS packet */ @@ -383,6 +401,16 @@ rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); + if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) + + sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) { + mwifiex_dbg(adapter, ERROR, + "wrong rx packet for struct ethhdr: len=%d, offset=%d\n", + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return 0; + } + ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/usb.c @@ -130,7 +130,8 @@ default: mwifiex_dbg(adapter, ERROR, "unknown recv_type %#x\n", recv_type); - return -1; + ret = -1; + goto exit_restore_skb; } break; case MWIFIEX_USB_EP_DATA: @@ -505,6 +506,22 @@ } } + switch (card->usb_boot_state) { + case USB8XXX_FW_DNLD: + /* Reject broken descriptors. */ + if (!card->rx_cmd_ep || !card->tx_cmd_ep) + return -ENODEV; + if (card->bulk_out_maxpktsize == 0) + return -ENODEV; + break; + case USB8XXX_FW_READY: + /* Assume the driver can handle missing endpoints for now. */ + break; + default: + WARN_ON(1); + return -ENODEV; + } + usb_set_intfdata(intf, card); ret = mwifiex_add_card(card, &card->fw_done, &usb_ops, @@ -1353,7 +1370,8 @@ skb_dequeue(&port->tx_aggr.aggr_list))) mwifiex_write_data_complete(adapter, skb_tmp, 0, -1); - del_timer_sync(&port->tx_aggr.timer_cnxt.hold_timer); + if (port->tx_aggr.timer_cnxt.hold_timer.function) + del_timer_sync(&port->tx_aggr.timer_cnxt.hold_timer); port->tx_aggr.timer_cnxt.is_hold_timer_set = false; port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/util.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/util.c @@ -405,11 +405,15 @@ } rx_pd = (struct rxpd *)skb->data; + pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); + if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) { + mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length"); + return -1; + } skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); skb_pull(skb, sizeof(pkt_len)); - - pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); + pkt_len -= sizeof(pkt_len); ieee_hdr = (void *)skb->data; if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { @@ -422,7 +426,7 @@ skb->data + sizeof(struct ieee80211_hdr), pkt_len - sizeof(struct ieee80211_hdr)); - pkt_len -= ETH_ALEN + sizeof(pkt_len); + pkt_len -= ETH_ALEN; rx_pd->rx_pkt_length = cpu_to_le16(pkt_len); cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq, --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwifiex/wmm.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwifiex/wmm.c @@ -970,6 +970,10 @@ "WMM Parameter Set Count: %d\n", wmm_param_ie->qos_info_bitmap & mask); + if (wmm_param_ie->vend_hdr.len + 2 > + sizeof(struct ieee_types_wmm_parameter)) + break; + memcpy((u8 *) &priv->curr_bss_params.bss_descriptor. wmm_ie, wmm_param_ie, wmm_param_ie->vend_hdr.len + 2); --- linux-oracle-5.4.0.orig/drivers/net/wireless/marvell/mwl8k.c +++ linux-oracle-5.4.0/drivers/net/wireless/marvell/mwl8k.c @@ -1469,6 +1469,7 @@ txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); if (txq->skb == NULL) { pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); + txq->txd = NULL; return -ENOMEM; } @@ -2713,7 +2714,7 @@ cmd->action |= cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); cmd->numaddr = cpu_to_le16(mc_count); netdev_hw_addr_list_for_each(ha, mc_list) { - memcpy(cmd->addr[i], ha->addr, ETH_ALEN); + memcpy(cmd->addr[i++], ha->addr, ETH_ALEN); } } @@ -5520,7 +5521,7 @@ rc = -EBUSY; break; } - ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); + rc = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: @@ -5795,8 +5796,8 @@ fail: priv->fw_state = FW_STATE_ERROR; complete(&priv->firmware_loading_complete); - device_release_driver(&priv->pdev->dev); mwl8k_release_firmware(priv); + device_release_driver(&priv->pdev->dev); } #define MAX_RESTART_ATTEMPTS 1 --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/agg-rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/agg-rx.c @@ -143,8 +143,8 @@ struct ieee80211_sta *sta; struct mt76_rx_tid *tid; bool sn_less; - u16 seqno, head, size; - u8 ackp, idx; + u16 seqno, head, size, idx; + u8 ackp; __skb_queue_tail(frames, skb); @@ -230,7 +230,7 @@ } int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno, - u16 ssn, u8 size) + u16 ssn, u16 size) { struct mt76_rx_tid *tid; @@ -254,7 +254,7 @@ static void mt76_rx_aggr_shutdown(struct mt76_dev *dev, struct mt76_rx_tid *tid) { - u8 size = tid->size; + u16 size = tid->size; int i; cancel_delayed_work(&tid->reorder_work); @@ -268,6 +268,7 @@ if (!skb) continue; + tid->reorder_buf[i] = NULL; tid->nframes--; dev_kfree_skb(skb); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/dma.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/dma.c @@ -261,10 +261,13 @@ struct mt76_queue_buf buf; dma_addr_t addr; + if (q->queued + 1 >= q->ndesc - 1) + goto error; + addr = dma_map_single(dev->dev, skb->data, skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev->dev, addr))) - return -ENOMEM; + goto error; buf.addr = addr; buf.len = skb->len; @@ -275,6 +278,10 @@ spin_unlock_bh(&q->lock); return 0; + +error: + dev_kfree_skb(skb); + return -ENOMEM; } static int @@ -404,6 +411,7 @@ bool more; spin_lock_bh(&q->lock); + do { buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more); if (!buf) @@ -411,6 +419,12 @@ skb_free_frag(buf); } while (1); + + if (q->rx_head) { + dev_kfree_skb(q->rx_head); + q->rx_head = NULL; + } + spin_unlock_bh(&q->lock); if (!q->rx_page.va) @@ -433,31 +447,33 @@ mt76_dma_rx_cleanup(dev, q); mt76_dma_sync_idx(dev, q); mt76_dma_rx_fill(dev, q); - - if (!q->rx_head) - return; - - dev_kfree_skb(q->rx_head); - q->rx_head = NULL; } static void mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, int len, bool more) { - struct page *page = virt_to_head_page(data); - int offset = data - page_address(page); struct sk_buff *skb = q->rx_head; + struct skb_shared_info *shinfo = skb_shinfo(skb); + int nr_frags = shinfo->nr_frags; - offset += q->buf_offset; - skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, - q->buf_size); + if (nr_frags < ARRAY_SIZE(shinfo->frags)) { + struct page *page = virt_to_head_page(data); + int offset = data - page_address(page) + q->buf_offset; + + skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size); + } else { + skb_free_frag(data); + } if (more) return; q->rx_head = NULL; - dev->drv->rx_skb(dev, q - dev->q_rx, skb); + if (nr_frags < ARRAY_SIZE(shinfo->frags)) + dev->drv->rx_skb(dev, q - dev->q_rx, skb); + else + dev_kfree_skb(skb); } static int --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mac80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -103,9 +103,18 @@ if (!of_property_read_u32(np, "led-sources", &led_pin)) dev->led_pin = led_pin; dev->led_al = of_property_read_bool(np, "led-active-low"); + of_node_put(np); } - return devm_led_classdev_register(dev->dev, &dev->led_cdev); + return led_classdev_register(dev->dev, &dev->led_cdev); +} + +static void mt76_led_cleanup(struct mt76_dev *dev) +{ + if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set) + return; + + led_classdev_unregister(&dev->led_cdev); } static void mt76_init_stream_cap(struct mt76_dev *dev, @@ -360,6 +369,8 @@ { struct ieee80211_hw *hw = dev->hw; + if (IS_ENABLED(CONFIG_MT76_LEDS)) + mt76_led_cleanup(dev); mt76_tx_status_check(dev, NULL, true); ieee80211_unregister_hw(hw); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76.h +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76.h @@ -240,8 +240,8 @@ struct delayed_work reorder_work; u16 head; - u8 size; - u8 nframes; + u16 size; + u16 nframes; u8 started:1, stopped:1, timer_pending:1; @@ -367,8 +367,8 @@ enum mt76u_out_ep { MT_EP_OUT_INBAND_CMD, - MT_EP_OUT_AC_BK, MT_EP_OUT_AC_BE, + MT_EP_OUT_AC_BK, MT_EP_OUT_AC_VI, MT_EP_OUT_AC_VO, MT_EP_OUT_HCCA, @@ -723,7 +723,7 @@ void mt76_set_stream_caps(struct mt76_dev *dev, bool vht); int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, - u16 ssn, u8 size); + u16 ssn, u16 size); void mt76_rx_aggr_stop(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid); void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, @@ -799,7 +799,8 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len, int timeout) { - struct usb_device *udev = to_usb_device(dev->dev); + struct usb_interface *uintf = to_usb_interface(dev->dev); + struct usb_device *udev = interface_to_usbdev(uintf); struct mt76_usb *usb = &dev->usb; unsigned int pipe; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7603/core.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7603/core.c @@ -39,11 +39,13 @@ } if (intr & MT_INT_RX_DONE(0)) { + dev->rx_pse_check = 0; mt7603_irq_disable(dev, MT_INT_RX_DONE(0)); napi_schedule(&dev->mt76.napi[0]); } if (intr & MT_INT_RX_DONE(1)) { + dev->rx_pse_check = 0; mt7603_irq_disable(dev, MT_INT_RX_DONE(1)); napi_schedule(&dev->mt76.napi[1]); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7603/mac.c @@ -1032,8 +1032,10 @@ if (idx && (cur_rate->idx != info->status.rates[i].idx || cur_rate->flags != info->status.rates[i].flags)) { i++; - if (i == ARRAY_SIZE(info->status.rates)) + if (i == ARRAY_SIZE(info->status.rates)) { + i--; break; + } info->status.rates[i] = *cur_rate; info->status.rates[i].count = 0; @@ -1414,20 +1416,29 @@ { u32 addr, val; - if (mt76_rr(dev, MT_MCU_DEBUG_RESET) & MT_MCU_DEBUG_RESET_QUEUES) - return true; - if (mt7603_rx_fifo_busy(dev)) - return false; + goto out; addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR + MT_CLIENT_STATUS); mt76_wr(dev, addr, 3); val = mt76_rr(dev, addr) >> 16; - if (is_mt7628(dev) && (val & 0x4001) == 0x4001) - return true; + if (!(val & BIT(0))) + return false; - return (val & 0x8001) == 0x8001 || (val & 0xe001) == 0xe001; + if (is_mt7628(dev)) + val &= 0xa000; + else + val &= 0x8000; + if (!val) + return false; + +out: + if (mt76_rr(dev, MT_INT_SOURCE_CSR) & + (MT_INT_RX_DONE(0) | MT_INT_RX_DONE(1))) + return false; + + return true; } static bool --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -555,12 +555,14 @@ u16 ssn = params->ssn; u8 ba_size = params->buf_size; struct mt76_txq *mtxq; + int ret = 0; if (!txq) return -EINVAL; mtxq = (struct mt76_txq *)txq->drv_priv; + mutex_lock(&dev->mt76.mutex); switch (action) { case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn, @@ -582,7 +584,7 @@ break; case IEEE80211_AMPDU_TX_START: mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; @@ -590,8 +592,9 @@ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } + mutex_unlock(&dev->mt76.mutex); - return 0; + return ret; } static void @@ -603,6 +606,9 @@ struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates); int i; + if (!sta_rates) + return; + spin_lock_bh(&dev->mt76.lock); for (i = 0; i < ARRAY_SIZE(msta->rates); i++) { msta->rates[i].idx = sta_rates->rate[i].idx; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -13,10 +13,7 @@ #include "../dma.h" #include "mac.h" -static inline s8 to_rssi(u32 field, u32 rxv) -{ - return (FIELD_GET(field, rxv) - 220) / 2; -} +#define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2) static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev, u8 idx, bool unicast) @@ -840,22 +837,20 @@ int first_idx = 0, last_idx; int i, idx, count; bool fixed_rate, ack_timeout; - bool probe, ampdu, cck = false; + bool ampdu, cck = false; bool rs_idx; u32 rate_set_tsf; u32 final_rate, final_rate_flags, final_nss, txs; - fixed_rate = info->status.rates[0].count; - probe = !!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); - txs = le32_to_cpu(txs_data[1]); - ampdu = !fixed_rate && (txs & MT_TXS1_AMPDU); + ampdu = txs & MT_TXS1_AMPDU; txs = le32_to_cpu(txs_data[3]); count = FIELD_GET(MT_TXS3_TX_COUNT, txs); last_idx = FIELD_GET(MT_TXS3_LAST_TX_RATE, txs); txs = le32_to_cpu(txs_data[0]); + fixed_rate = txs & MT_TXS0_FIXED_RATE; final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs); ack_timeout = txs & MT_TXS0_ACK_TIMEOUT; @@ -877,7 +872,7 @@ first_idx = max_t(int, 0, last_idx - (count + 1) / MT7615_RATE_RETRY); - if (fixed_rate && !probe) { + if (fixed_rate) { info->status.rates[0].count = count; i = 0; goto out; @@ -914,8 +909,10 @@ if (idx && (cur_rate->idx != info->status.rates[i].idx || cur_rate->flags != info->status.rates[i].flags)) { i++; - if (i == ARRAY_SIZE(info->status.rates)) + if (i == ARRAY_SIZE(info->status.rates)) { + i--; break; + } info->status.rates[i] = *cur_rate; info->status.rates[i].count = 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -385,6 +385,9 @@ struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates); int i; + if (!sta_rates) + return; + spin_lock_bh(&dev->mt76.lock); for (i = 0; i < ARRAY_SIZE(msta->rates); i++) { msta->rates[i].idx = sta_rates->rate[i].idx; @@ -449,12 +452,14 @@ u16 tid = params->tid; u16 ssn = params->ssn; struct mt76_txq *mtxq; + int ret = 0; if (!txq) return -EINVAL; mtxq = (struct mt76_txq *)txq->drv_priv; + mutex_lock(&dev->mt76.mutex); switch (action) { case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn, @@ -477,7 +482,7 @@ break; case IEEE80211_AMPDU_TX_START: mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; @@ -485,8 +490,9 @@ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } + mutex_unlock(&dev->mt76.mutex); - return 0; + return ret; } const struct ieee80211_ops mt7615_ops = { --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -119,8 +119,10 @@ struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data; int ret = 0; - if (seq != rxd->seq) - return -EAGAIN; + if (seq != rxd->seq) { + ret = -EAGAIN; + goto out; + } switch (cmd) { case -MCU_CMD_PATCH_SEM_CONTROL: @@ -134,6 +136,7 @@ default: break; } +out: dev_kfree_skb(skb); return ret; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c @@ -226,7 +226,7 @@ u32 mac_rev; int ret; - mdev = mt76_alloc_device(&usb_dev->dev, sizeof(*dev), &mt76x0u_ops, + mdev = mt76_alloc_device(&usb_intf->dev, sizeof(*dev), &mt76x0u_ops, &drv_ops); if (!mdev) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02.h +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x02.h @@ -212,6 +212,7 @@ static inline bool is_mt76x2(struct mt76x02_dev *dev) { return mt76_chip(&dev->mt76) == 0x7612 || + mt76_chip(&dev->mt76) == 0x7632 || mt76_chip(&dev->mt76) == 0x7662 || mt76_chip(&dev->mt76) == 0x7602; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c @@ -77,10 +77,7 @@ for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) { if (vif_idx == i) { force_update = !!dev->beacons[i] ^ !!skb; - - if (dev->beacons[i]) - dev_kfree_skb(dev->beacons[i]); - + dev_kfree_skb(dev->beacons[i]); dev->beacons[i] = skb; __mt76x02_mac_set_beacon(dev, bcn_idx, skb); } else if (force_update && dev->beacons[i]) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c @@ -131,15 +131,8 @@ s8 *lna_2g, s8 *lna_5g, struct ieee80211_channel *chan) { - u16 val; u8 lna; - val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); - if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G) - *lna_2g = 0; - if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G) - memset(lna_5g, 0, sizeof(s8) * 3); - if (chan->band == NL80211_BAND_2GHZ) lna = *lna_2g; else if (chan->hw_value <= 64) --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c @@ -154,7 +154,7 @@ mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop)); } -static __le16 +static u16 mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev, const struct ieee80211_tx_rate *rate, u8 *nss_val) { @@ -200,14 +200,14 @@ rateval |= MT_RXWI_RATE_SGI; *nss_val = nss; - return cpu_to_le16(rateval); + return rateval; } void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid, const struct ieee80211_tx_rate *rate) { s8 max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); - __le16 rateval; + u16 rateval; u32 tx_info; s8 nss; @@ -320,7 +320,7 @@ struct ieee80211_key_conf *key = info->control.hw_key; u32 wcid_tx_info; u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2)); - u16 txwi_flags = 0; + u16 txwi_flags = 0, rateval; u8 nss; s8 txpwr_adj, max_txpwr_adj; u8 ccmp_pn[8], nstreams = dev->mt76.chainmask & 0xf; @@ -356,14 +356,15 @@ if (wcid && (rate->idx < 0 || !rate->count)) { wcid_tx_info = wcid->tx_info; - txwi->rate = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info); + rateval = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info); max_txpwr_adj = FIELD_GET(MT_WCID_TX_INFO_TXPWR_ADJ, wcid_tx_info); nss = FIELD_GET(MT_WCID_TX_INFO_NSS, wcid_tx_info); } else { - txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss); + rateval = mt76x02_mac_tx_rate_val(dev, rate, &nss); max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate); } + txwi->rate = cpu_to_le16(rateval); txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf, max_txpwr_adj); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -365,12 +365,14 @@ u16 tid = params->tid; u16 ssn = params->ssn; struct mt76_txq *mtxq; + int ret = 0; if (!txq) return -EINVAL; mtxq = (struct mt76_txq *)txq->drv_priv; + mutex_lock(&dev->mt76.mutex); switch (action) { case IEEE80211_AMPDU_RX_START: mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, @@ -393,15 +395,16 @@ break; case IEEE80211_AMPDU_TX_START: mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: mtxq->aggr = false; ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; } + mutex_unlock(&dev->mt76.mutex); - return 0; + return ret; } EXPORT_SYMBOL_GPL(mt76x02_ampdu_action); @@ -448,6 +451,10 @@ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -EOPNOTSUPP; + /* MT76x0 GTK offloading does not work with more than one VIF */ + if (is_mt76x0(dev) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + msta = sta ? (struct mt76x02_sta *)sta->drv_priv : NULL; wcid = msta ? &msta->wcid : &mvif->group_wcid; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c @@ -251,7 +251,8 @@ struct ieee80211_channel *chan = dev->mt76.chandef.chan; int channel = chan->hw_value; s8 lna_5g[3], lna_2g; - u8 lna; + bool use_lna; + u8 lna = 0; u16 val; if (chan->band == NL80211_BAND_2GHZ) @@ -270,7 +271,15 @@ dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; - lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); + val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); + if (chan->band == NL80211_BAND_2GHZ) + use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G); + else + use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G); + + if (use_lna) + lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); + dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); } EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c @@ -76,7 +76,7 @@ mt76_rmw_field(dev, 0x15a10, 0x1f << 16, 0x9); /* RG_SSUSB_G1_CDR_BIC_LTR = 0xf */ - mt76_rmw_field(dev, 0x15a0c, 0xf << 28, 0xf); + mt76_rmw_field(dev, 0x15a0c, 0xfU << 28, 0xf); /* RG_SSUSB_CDR_BR_PE1D = 0x3 */ mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c @@ -18,6 +18,7 @@ { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */ { USB_DEVICE(0x0846, 0x9053) }, /* Netgear A6210 */ { USB_DEVICE(0x045e, 0x02e6) }, /* XBox One Wireless Adapter */ + { USB_DEVICE(0x045e, 0x02fe) }, /* XBox One Wireless Adapter */ { }, }; @@ -39,7 +40,7 @@ struct mt76_dev *mdev; int err; - mdev = mt76_alloc_device(&udev->dev, sizeof(*dev), &mt76x2u_ops, + mdev = mt76_alloc_device(&intf->dev, sizeof(*dev), &mt76x2u_ops, &drv_ops); if (!mdev) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt76/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt76/usb.c @@ -20,7 +20,8 @@ u8 req_type, u16 val, u16 offset, void *buf, size_t len) { - struct usb_device *udev = to_usb_device(dev->dev); + struct usb_interface *uintf = to_usb_interface(dev->dev); + struct usb_device *udev = interface_to_usbdev(uintf); unsigned int pipe; int i, ret; @@ -235,7 +236,8 @@ static bool mt76u_check_sg(struct mt76_dev *dev) { - struct usb_device *udev = to_usb_device(dev->dev); + struct usb_interface *uintf = to_usb_interface(dev->dev); + struct usb_device *udev = interface_to_usbdev(uintf); return (!disable_usb_sg && udev->bus->sg_tablesize > 0 && (udev->bus->no_sg_constraint || @@ -370,7 +372,8 @@ struct urb *urb, usb_complete_t complete_fn, void *context) { - struct usb_device *udev = to_usb_device(dev->dev); + struct usb_interface *uintf = to_usb_interface(dev->dev); + struct usb_device *udev = interface_to_usbdev(uintf); unsigned int pipe; if (dir == USB_DIR_IN) @@ -952,6 +955,7 @@ .rd_rp = mt76u_rd_rp, .type = MT76_BUS_USB, }; + struct usb_device *udev = interface_to_usbdev(intf); struct mt76_usb *usb = &dev->usb; tasklet_init(&usb->rx_tasklet, mt76u_rx_tasklet, (unsigned long)dev); @@ -965,6 +969,8 @@ dev->bus = &mt76u_ops; dev->queue_ops = &usb_queue_ops; + dev_set_drvdata(&udev->dev, dev); + usb->sg_en = mt76u_check_sg(dev); return mt76u_set_endpoints(intf, usb); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt7601u/dma.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt7601u/dma.c @@ -118,7 +118,8 @@ if (data_len < min_seg_len || WARN_ON_ONCE(!dma_len) || WARN_ON_ONCE(dma_len + MT_DMA_HDRS > data_len) || - WARN_ON_ONCE(dma_len & 0x3)) + WARN_ON_ONCE(dma_len & 0x3) || + WARN_ON_ONCE(dma_len < min_seg_len)) return 0; return MT_DMA_HDRS + dma_len; @@ -152,8 +153,7 @@ if (new_p) { /* we have one extra ref from the allocator */ - __free_pages(e->p, MT_RX_ORDER); - + put_page(e->p); e->p = new_p; } } @@ -310,7 +310,6 @@ } e = &q->e[q->end]; - e->skb = skb; usb_fill_bulk_urb(e->urb, usb_dev, snd_pipe, skb->data, skb->len, mt7601u_complete_tx, q); ret = usb_submit_urb(e->urb, GFP_ATOMIC); @@ -328,6 +327,7 @@ q->end = (q->end + 1) % q->entries; q->used++; + e->skb = skb; if (q->used >= q->entries) ieee80211_stop_queue(dev->hw, skb_get_queue_mapping(skb)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt7601u/eeprom.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt7601u/eeprom.c @@ -99,7 +99,7 @@ { u16 nic_conf1 = get_unaligned_le16(eeprom + MT_EE_NIC_CONF_1); - return ~nic_conf1 && (nic_conf1 & MT_EE_NIC_CONF_1_TX_ALC_EN); + return (u16)~nic_conf1 && (nic_conf1 & MT_EE_NIC_CONF_1_TX_ALC_EN); } static void --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt7601u/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt7601u/main.c @@ -372,8 +372,7 @@ break; case IEEE80211_AMPDU_TX_START: msta->agg_ssn[tid] = ssn << 4; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt7601u/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt7601u/phy.c @@ -213,7 +213,7 @@ do { val = mt7601u_bbp_rr(dev, MT_BBP_REG_VERSION); - if (val && ~val) + if (val && val != 0xff) break; } while (--i); --- linux-oracle-5.4.0.orig/drivers/net/wireless/mediatek/mt7601u/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/mediatek/mt7601u/usb.c @@ -26,6 +26,7 @@ { USB_DEVICE(0x2717, 0x4106) }, { USB_DEVICE(0x2955, 0x0001) }, { USB_DEVICE(0x2955, 0x1001) }, + { USB_DEVICE(0x2955, 0x1003) }, { USB_DEVICE(0x2a5f, 0x1000) }, { USB_DEVICE(0x7392, 0x7710) }, { 0, } --- linux-oracle-5.4.0.orig/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ linux-oracle-5.4.0/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -83,6 +83,7 @@ struct qlink_cmd *cmd; struct qlink_resp *resp = NULL; struct sk_buff *resp_skb = NULL; + int resp_res = 0; u16 cmd_id; u8 mac_id; u8 vif_id; @@ -113,6 +114,7 @@ } resp = (struct qlink_resp *)resp_skb->data; + resp_res = le16_to_cpu(resp->result); ret = qtnf_cmd_check_reply_header(resp, cmd_id, mac_id, vif_id, const_resp_size); if (ret) @@ -128,8 +130,8 @@ else consume_skb(resp_skb); - if (!ret && resp) - return qtnf_cmd_resp_result_decode(le16_to_cpu(resp->result)); + if (!ret) + return qtnf_cmd_resp_result_decode(resp_res); pr_warn("VIF%u.%u: cmd 0x%.4X failed: %d\n", mac_id, vif_id, cmd_id, ret); @@ -832,6 +834,7 @@ default: pr_warn("VIF%u.%u: unsupported iftype %d\n", vif->mac->macid, vif->vifid, vif->wdev.iftype); + dev_kfree_skb(cmd_skb); ret = -EINVAL; goto out; } @@ -1994,6 +1997,7 @@ break; default: pr_err("unsupported iftype %d\n", vif->wdev.iftype); + dev_kfree_skb(cmd_skb); ret = -EINVAL; goto out; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/quantenna/qtnfmac/event.c +++ linux-oracle-5.4.0/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -171,8 +171,9 @@ return -EPROTO; } - pr_debug("VIF%u.%u: BSSID:%pM status:%u\n", - vif->mac->macid, vif->vifid, join_info->bssid, status); + pr_debug("VIF%u.%u: BSSID:%pM chan:%u status:%u\n", + vif->mac->macid, vif->vifid, join_info->bssid, + le16_to_cpu(join_info->chan.chan.center_freq), status); if (status != WLAN_STATUS_SUCCESS) goto done; @@ -181,7 +182,7 @@ if (!cfg80211_chandef_valid(&chandef)) { pr_warn("MAC%u.%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n", vif->mac->macid, vif->vifid, - chandef.chan->center_freq, + chandef.chan ? chandef.chan->center_freq : 0, chandef.center_freq1, chandef.center_freq2, chandef.width); @@ -598,8 +599,10 @@ return 0; if (ev->ssid_len) { - memcpy(auth.ssid.ssid, ev->ssid, ev->ssid_len); - auth.ssid.ssid_len = ev->ssid_len; + int len = clamp_val(ev->ssid_len, 0, IEEE80211_MAX_SSID_LEN); + + memcpy(auth.ssid.ssid, ev->ssid, len); + auth.ssid.ssid_len = len; } auth.key_mgmt_suite = le32_to_cpu(ev->akm_suite); --- linux-oracle-5.4.0.orig/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c +++ linux-oracle-5.4.0/drivers/net/wireless/quantenna/qtnfmac/pcie/pcie.c @@ -130,6 +130,8 @@ int qtnf_pcie_fw_boot_done(struct qtnf_bus *bus) { + struct qtnf_pcie_bus_priv *priv = get_bus_priv(bus); + char card_id[64]; int ret; bus->fw_state = QTNF_FW_STATE_BOOT_DONE; @@ -137,7 +139,9 @@ if (ret) { pr_err("failed to attach core\n"); } else { - qtnf_debugfs_init(bus, DRV_NAME); + snprintf(card_id, sizeof(card_id), "%s:%s", + DRV_NAME, pci_name(priv->pdev)); + qtnf_debugfs_init(bus, card_id); qtnf_debugfs_add_entry(bus, "mps", qtnf_dbg_mps_show); qtnf_debugfs_add_entry(bus, "msi_enabled", qtnf_dbg_msi_show); qtnf_debugfs_add_entry(bus, "shm_stats", qtnf_dbg_shm_stats); @@ -295,19 +299,19 @@ sysctl_bar = qtnf_map_bar(pdev, QTN_SYSCTL_BAR); if (IS_ERR(sysctl_bar)) { pr_err("failed to map BAR%u\n", QTN_SYSCTL_BAR); - return ret; + return PTR_ERR(sysctl_bar); } dmareg_bar = qtnf_map_bar(pdev, QTN_DMA_BAR); if (IS_ERR(dmareg_bar)) { pr_err("failed to map BAR%u\n", QTN_DMA_BAR); - return ret; + return PTR_ERR(dmareg_bar); } epmem_bar = qtnf_map_bar(pdev, QTN_SHMEM_BAR); if (IS_ERR(epmem_bar)) { pr_err("failed to map BAR%u\n", QTN_SHMEM_BAR); - return ret; + return PTR_ERR(epmem_bar); } chipid = qtnf_chip_id_get(sysctl_bar); --- linux-oracle-5.4.0.orig/drivers/net/wireless/ralink/rt2x00/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ralink/rt2x00/Kconfig @@ -95,20 +95,20 @@ config RT2800PCI_RT53XX - bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)" - default y - ---help--- - This adds support for rt53xx wireless chipset family to the - rt2800pci driver. - Supported chips: RT5390 + bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)" + default y + ---help--- + This adds support for rt53xx wireless chipset family to the + rt2800pci driver. + Supported chips: RT5390 config RT2800PCI_RT3290 - bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)" - default y - ---help--- - This adds support for rt3290 wireless chipset family to the - rt2800pci driver. - Supported chips: RT3290 + bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)" + default y + ---help--- + This adds support for rt3290 wireless chipset family to the + rt2800pci driver. + Supported chips: RT3290 endif config RT2500USB @@ -174,18 +174,18 @@ in the rt2800usb driver. config RT2800USB_RT53XX - bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" - ---help--- - This adds support for rt53xx wireless chipset family to the - rt2800usb driver. - Supported chips: RT5370 + bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" + ---help--- + This adds support for rt53xx wireless chipset family to the + rt2800usb driver. + Supported chips: RT5370 config RT2800USB_RT55XX - bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)" - ---help--- - This adds support for rt55xx wireless chipset family to the - rt2800usb driver. - Supported chips: RT5572 + bool "rt2800usb - Include support for rt55xx devices (EXPERIMENTAL)" + ---help--- + This adds support for rt55xx wireless chipset family to the + rt2800usb driver. + Supported chips: RT5572 config RT2800USB_UNKNOWN bool "rt2800usb - Include support for unknown (USB) devices" --- linux-oracle-5.4.0.orig/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ linux-oracle-5.4.0/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -4154,7 +4154,10 @@ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); - rt2800_bbp_write(rt2x00dev, 86, 0); + if (rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 86, 0x38); + else + rt2800_bbp_write(rt2x00dev, 86, 0); } if (rf->channel <= 14) { @@ -4355,7 +4358,8 @@ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); - rt2800_iq_calibrate(rt2x00dev, rf->channel); + if (rt2x00_rt(rt2x00dev, RT5592)) + rt2800_iq_calibrate(rt2x00dev, rf->channel); } bbp = rt2800_bbp_read(rt2x00dev, 4); @@ -5628,7 +5632,8 @@ if (qual->vgc_level != vgc_level) { if (rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT3883)) { + rt2x00_rt(rt2x00dev, RT3883) || + rt2x00_rt(rt2x00dev, RT6352)) { rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); } else if (rt2x00_rt(rt2x00dev, RT5592)) { @@ -5839,8 +5844,7 @@ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || - rt2x00_rt(rt2x00dev, RT6352)) { + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); @@ -5852,10 +5856,8 @@ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); } else if (rt2x00_rt(rt2x00dev, RT6352)) { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401); - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000); + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); - rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); @@ -6116,6 +6118,27 @@ reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 125); rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); + } else if (rt2x00_is_soc(rt2x00dev)) { + struct clk *clk = clk_get_sys("bus", NULL); + int rate; + + if (IS_ERR(clk)) { + clk = clk_get_sys("cpu", NULL); + + if (IS_ERR(clk)) { + rate = 125; + } else { + rate = clk_get_rate(clk) / 3000000; + clk_put(clk); + } + } else { + rate = clk_get_rate(clk) / 1000000; + clk_put(clk); + } + + reg = rt2800_register_read(rt2x00dev, US_CYC_CNT); + rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, rate); + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); } reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0); @@ -10476,7 +10499,7 @@ * when the hw reorders frames due to aggregation. */ if (sta_priv->wcid > WCID_END) - return 1; + return -ENOSPC; switch (action) { case IEEE80211_AMPDU_RX_START: @@ -10489,7 +10512,7 @@ */ break; case IEEE80211_AMPDU_TX_START: - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: --- linux-oracle-5.4.0.orig/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ linux-oracle-5.4.0/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c @@ -101,6 +101,7 @@ rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); rt2x00queue_flush_queues(rt2x00dev, true); + rt2x00queue_stop_queue(rt2x00dev->bcn); /* * Disable radio. @@ -1283,6 +1284,7 @@ rt2x00dev->intf_ap_count = 0; rt2x00dev->intf_sta_count = 0; rt2x00dev->intf_associated = 0; + rt2x00dev->intf_beaconing = 0; /* Enable the radio */ retval = rt2x00lib_enable_radio(rt2x00dev); @@ -1310,6 +1312,7 @@ rt2x00dev->intf_ap_count = 0; rt2x00dev->intf_sta_count = 0; rt2x00dev->intf_associated = 0; + rt2x00dev->intf_beaconing = 0; } static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -578,6 +578,17 @@ */ if (changes & BSS_CHANGED_BEACON_ENABLED) { mutex_lock(&intf->beacon_skb_mutex); + + /* + * Clear the 'enable_beacon' flag and clear beacon because + * the beacon queue has been stopped after hardware reset. + */ + if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) && + intf->enable_beacon) { + intf->enable_beacon = false; + rt2x00queue_clear_beacon(rt2x00dev, vif); + } + if (!bss_conf->enable_beacon && intf->enable_beacon) { rt2x00dev->intf_beaconing--; intf->enable_beacon = false; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c @@ -25,6 +25,9 @@ if (status == -ENODEV || status == -ENOENT) return true; + if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) + return false; + if (status == -EPROTO || status == -ETIMEDOUT) rt2x00dev->num_proto_errs++; else --- linux-oracle-5.4.0.orig/drivers/net/wireless/ray_cs.c +++ linux-oracle-5.4.0/drivers/net/wireless/ray_cs.c @@ -270,13 +270,14 @@ { ray_dev_t *local; struct net_device *dev; + int ret; dev_dbg(&p_dev->dev, "ray_attach()\n"); /* Allocate space for private device-specific data */ dev = alloc_etherdev(sizeof(ray_dev_t)); if (!dev) - goto fail_alloc_dev; + return -ENOMEM; local = netdev_priv(dev); local->finder = p_dev; @@ -313,11 +314,16 @@ timer_setup(&local->timer, NULL, 0); this_device = p_dev; - return ray_config(p_dev); + ret = ray_config(p_dev); + if (ret) + goto err_free_dev; + + return 0; -fail_alloc_dev: - return -ENOMEM; -} /* ray_attach */ +err_free_dev: + free_netdev(dev); + return ret; +} static void ray_detach(struct pcmcia_device *link) { @@ -382,6 +388,8 @@ goto failed; local->sram = ioremap(link->resource[2]->start, resource_size(link->resource[2])); + if (!local->sram) + goto failed; /*** Set up 16k window for shared memory (receive buffer) ***************/ link->resource[3]->flags |= @@ -396,6 +404,8 @@ goto failed; local->rmem = ioremap(link->resource[3]->start, resource_size(link->resource[3])); + if (!local->rmem) + goto failed; /*** Set up window for attribute memory ***********************************/ link->resource[4]->flags |= @@ -410,6 +420,8 @@ goto failed; local->amem = ioremap(link->resource[4]->start, resource_size(link->resource[4])); + if (!local->amem) + goto failed; dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram); dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem); @@ -1635,38 +1647,34 @@ /*===========================================================================*/ static int parse_addr(char *in_str, UCHAR *out) { + int i, k; int len; - int i, j, k; - int status; if (in_str == NULL) return 0; - if ((len = strlen(in_str)) < 2) + len = strnlen(in_str, ADDRLEN * 2 + 1) - 1; + if (len < 1) return 0; memset(out, 0, ADDRLEN); - status = 1; - j = len - 1; - if (j > 12) - j = 12; i = 5; - while (j > 0) { - if ((k = hex_to_bin(in_str[j--])) != -1) + while (len > 0) { + if ((k = hex_to_bin(in_str[len--])) != -1) out[i] = k; else return 0; - if (j == 0) + if (len == 0) break; - if ((k = hex_to_bin(in_str[j--])) != -1) + if ((k = hex_to_bin(in_str[len--])) != -1) out[i] += k << 4; else return 0; if (!i--) break; } - return status; + return 1; } /*===========================================================================*/ --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c @@ -460,8 +460,10 @@ struct rtl8180_priv *priv = dev->priv; struct rtl8180_tx_ring *ring; struct rtl8180_tx_desc *entry; + unsigned int prio = 0; unsigned long flags; - unsigned int idx, prio, hw_prio; + unsigned int idx, hw_prio; + dma_addr_t mapping; u32 tx_flags; u8 rc_flags; @@ -470,7 +472,9 @@ /* do arithmetic and then convert to le16 */ u16 frame_duration = 0; - prio = skb_get_queue_mapping(skb); + /* rtl8180/rtl8185 only has one useable tx queue */ + if (dev->queues > IEEE80211_AC_BK) + prio = skb_get_queue_mapping(skb); ring = &priv->tx_ring[prio]; mapping = pci_map_single(priv->pdev, skb->data, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c @@ -28,7 +28,7 @@ usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500); val = priv->io_dmabuf->bits8; mutex_unlock(&priv->io_mutex); @@ -45,7 +45,7 @@ usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500); val = priv->io_dmabuf->bits16; mutex_unlock(&priv->io_mutex); @@ -62,7 +62,7 @@ usb_control_msg(priv->udev, usb_rcvctrlpipe(priv->udev, 0), RTL8187_REQ_GET_REG, RTL8187_REQT_READ, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500); val = priv->io_dmabuf->bits32; mutex_unlock(&priv->io_mutex); @@ -79,7 +79,7 @@ usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits8, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits8, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -93,7 +93,7 @@ usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits16, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits16, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -107,7 +107,7 @@ usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, (unsigned long)addr, idx & 0x03, - &priv->io_dmabuf->bits32, sizeof(val), HZ / 2); + &priv->io_dmabuf->bits32, sizeof(val), 500); mutex_unlock(&priv->io_mutex); } @@ -183,7 +183,7 @@ usb_control_msg(priv->udev, usb_sndctrlpipe(priv->udev, 0), RTL8187_REQ_SET_REG, RTL8187_REQT_WRITE, addr, 0x8225, &priv->io_dmabuf->bits16, sizeof(data), - HZ / 2); + 500); mutex_unlock(&priv->io_mutex); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -853,15 +853,10 @@ u8 usb_optional_function; u8 res9[2]; u8 mac_addr[ETH_ALEN]; /* 0xd7 */ - u8 res10[2]; - u8 vendor_name[7]; - u8 res11[2]; - u8 device_name[0x0b]; /* 0xe8 */ - u8 res12[2]; - u8 serial[0x0b]; /* 0xf5 */ - u8 res13[0x30]; + u8 device_info[80]; + u8 res11[3]; u8 unknown[0x0d]; /* 0x130 */ - u8 res14[0xc3]; + u8 res12[0xc3]; }; struct rtl8xxxu_reg8val { @@ -1183,10 +1178,83 @@ u8 dummy3_0; } __packed ra_report; }; -}; +} __packed; struct rtl8xxxu_fileops; +/*mlme related.*/ +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0, + /* Sub-Element */ + WIRELESS_MODE_B = BIT(0), + WIRELESS_MODE_G = BIT(1), + WIRELESS_MODE_A = BIT(2), + WIRELESS_MODE_N_24G = BIT(3), + WIRELESS_MODE_N_5G = BIT(4), + WIRELESS_AUTO = BIT(5), + WIRELESS_MODE_AC = BIT(6), + WIRELESS_MODE_MAX = 0x7F, +}; + +/* from rtlwifi/wifi.h */ +enum ratr_table_mode_new { + RATEID_IDX_BGN_40M_2SS = 0, + RATEID_IDX_BGN_40M_1SS = 1, + RATEID_IDX_BGN_20M_2SS_BN = 2, + RATEID_IDX_BGN_20M_1SS_BN = 3, + RATEID_IDX_GN_N2SS = 4, + RATEID_IDX_GN_N1SS = 5, + RATEID_IDX_BG = 6, + RATEID_IDX_G = 7, + RATEID_IDX_B = 8, + RATEID_IDX_VHT_2SS = 9, + RATEID_IDX_VHT_1SS = 10, + RATEID_IDX_MIX1 = 11, + RATEID_IDX_MIX2 = 12, + RATEID_IDX_VHT_3SS = 13, + RATEID_IDX_BGN_3SS = 14, +}; + +#define BT_INFO_8723B_1ANT_B_FTP BIT(7) +#define BT_INFO_8723B_1ANT_B_A2DP BIT(6) +#define BT_INFO_8723B_1ANT_B_HID BIT(5) +#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT(4) +#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT(3) +#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT(2) +#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT(1) +#define BT_INFO_8723B_1ANT_B_CONNECTION BIT(0) + +enum _BT_8723B_1ANT_STATUS { + BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE = 0x0, + BT_8723B_1ANT_STATUS_CONNECTED_IDLE = 0x1, + BT_8723B_1ANT_STATUS_INQ_PAGE = 0x2, + BT_8723B_1ANT_STATUS_ACL_BUSY = 0x3, + BT_8723B_1ANT_STATUS_SCO_BUSY = 0x4, + BT_8723B_1ANT_STATUS_ACL_SCO_BUSY = 0x5, + BT_8723B_1ANT_STATUS_MAX +}; + +struct rtl8xxxu_btcoex { + u8 bt_status; + bool bt_busy; + bool has_sco; + bool has_a2dp; + bool has_hid; + bool has_pan; + bool hid_only; + bool a2dp_only; + bool c2h_bt_inquiry; +}; + +#define RTL8XXXU_RATR_STA_INIT 0 +#define RTL8XXXU_RATR_STA_HIGH 1 +#define RTL8XXXU_RATR_STA_MID 2 +#define RTL8XXXU_RATR_STA_LOW 3 + +#define RTL8XXXU_NOISE_FLOOR_MIN -100 +#define RTL8XXXU_SNR_THRESH_HIGH 50 +#define RTL8XXXU_SNR_THRESH_LOW 20 + struct rtl8xxxu_priv { struct ieee80211_hw *hw; struct usb_device *udev; @@ -1260,6 +1328,7 @@ u32 rege9c; u32 regeb4; u32 regebc; + u32 regrcr; int next_mbox; int nr_out_eps; @@ -1291,6 +1360,17 @@ u8 pi_enabled:1; u8 no_pape:1; u8 int_buf[USB_INTR_CONTENT_LENGTH]; + u8 rssi_level; + /* + * Only one virtual interface permitted because only STA mode + * is supported and no iface_combinations are provided. + */ + struct ieee80211_vif *vif; + struct delayed_work ra_watchdog; + struct work_struct c2hcmd_work; + struct sk_buff_head c2hcmd_queue; + spinlock_t c2hcmd_lock; + struct rtl8xxxu_btcoex bt_coex; }; struct rtl8xxxu_rx_urb { @@ -1326,7 +1406,7 @@ void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel, bool ht40); void (*update_rate_mask) (struct rtl8xxxu_priv *priv, - u32 ramask, int sgi); + u32 ramask, u8 rateid, int sgi); void (*report_connect) (struct rtl8xxxu_priv *priv, u8 macid, bool connect); void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr, @@ -1341,6 +1421,7 @@ u8 has_s0s1:1; u8 has_tx_report:1; u8 gen2_thermal_meter:1; + u8 needs_full_init:1; u32 adda_1t_init; u32 adda_1t_path_on; u32 adda_2t_path_on_a; @@ -1411,9 +1492,9 @@ void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv); void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv); void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, - u32 ramask, int sgi); + u32 ramask, u8 rateid, int sgi); void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, - u32 ramask, int sgi); + u32 ramask, u8 rateid, int sgi); void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv, u8 macid, bool connect); void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, @@ -1437,6 +1518,8 @@ struct rtl8xxxu_txdesc32 *tx_desc32, bool sgi, bool short_preamble, bool ampdu_enable, u32 rts_rate); +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5); extern struct rtl8xxxu_fileops rtl8192cu_fops; extern struct rtl8xxxu_fileops rtl8192eu_fops; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -554,9 +554,43 @@ } } +static void rtl8192eu_log_next_device_info(struct rtl8xxxu_priv *priv, + char *record_name, + char *device_info, + unsigned int *record_offset) +{ + char *record = device_info + *record_offset; + + /* A record is [ total length | 0x03 | value ] */ + unsigned char l = record[0]; + + /* + * The whole device info section seems to be 80 characters, make sure + * we don't read further. + */ + if (*record_offset + l > 80) { + dev_warn(&priv->udev->dev, + "invalid record length %d while parsing \"%s\" at offset %u.\n", + l, record_name, *record_offset); + return; + } + + if (l >= 2) { + char value[80]; + + memcpy(value, &record[2], l - 2); + value[l - 2] = '\0'; + dev_info(&priv->udev->dev, "%s: %s\n", record_name, value); + *record_offset = *record_offset + l; + } else { + dev_info(&priv->udev->dev, "%s not available.\n", record_name); + } +} + static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) { struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu; + unsigned int record_offset; int i; if (efuse->rtl_id != cpu_to_le16(0x8129)) @@ -604,12 +638,25 @@ priv->has_xtalk = 1; priv->xtalk = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f; - dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name); - dev_info(&priv->udev->dev, "Product: %.11s\n", efuse->device_name); - if (memchr_inv(efuse->serial, 0xff, 11)) - dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial); - else - dev_info(&priv->udev->dev, "Serial not available.\n"); + /* + * device_info section seems to be laid out as records + * [ total length | 0x03 | value ] so: + * - vendor length + 2 + * - 0x03 + * - vendor string (not null terminated) + * - product length + 2 + * - 0x03 + * - product string (not null terminated) + * Then there is one or 2 0x00 on all the 4 devices I own or found + * dumped online. + * As previous version of the code handled an optional serial + * string, I now assume there may be a third record if the + * length is not 0. + */ + record_offset = 0; + rtl8192eu_log_next_device_info(priv, "Vendor", efuse->device_info, &record_offset); + rtl8192eu_log_next_device_info(priv, "Product", efuse->device_info, &record_offset); + rtl8192eu_log_next_device_info(priv, "Serial", efuse->device_info, &record_offset); if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) { unsigned char *raw = priv->efuse_wifi.raw; @@ -1624,6 +1671,11 @@ val8 = rtl8xxxu_read8(priv, REG_PAD_CTRL1); val8 &= ~BIT(0); rtl8xxxu_write8(priv, REG_PAD_CTRL1, val8); + + /* + * Fix transmission failure of rtl8192e. + */ + rtl8xxxu_write8(priv, REG_TXPAUSE, 0x00); } struct rtl8xxxu_fileops rtl8192eu_fops = { @@ -1650,6 +1702,7 @@ .rx_desc_size = sizeof(struct rtl8xxxu_rxdesc24), .has_s0s1 = 0, .gen2_thermal_meter = 1, + .needs_full_init = 1, .adda_1t_init = 0x0fc01616, .adda_1t_path_on = 0x0fc01616, .adda_2t_path_on_a = 0x0fc01616, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c @@ -1580,9 +1580,7 @@ /* * Software control, antenna at WiFi side */ -#ifdef NEED_PS_TDMA rtl8723bu_set_ps_tdma(priv, 0x08, 0x00, 0x00, 0x00, 0x00); -#endif rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555); @@ -1670,6 +1668,7 @@ .has_s0s1 = 1, .has_tx_report = 1, .gen2_thermal_meter = 1, + .needs_full_init = 1, .adda_1t_init = 0x01c00014, .adda_1t_path_on = 0x01c00014, .adda_2t_path_on_a = 0x01c00014, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "rtl8xxxu.h" #include "rtl8xxxu_regs.h" @@ -1390,13 +1391,13 @@ u8 cck[RTL8723A_MAX_RF_PATHS], ofdm[RTL8723A_MAX_RF_PATHS]; u8 ofdmbase[RTL8723A_MAX_RF_PATHS], mcsbase[RTL8723A_MAX_RF_PATHS]; u32 val32, ofdm_a, ofdm_b, mcs_a, mcs_b; - u8 val8; + u8 val8, base; int group, i; group = rtl8xxxu_gen1_channel_to_group(channel); - cck[0] = priv->cck_tx_power_index_A[group] - 1; - cck[1] = priv->cck_tx_power_index_B[group] - 1; + cck[0] = priv->cck_tx_power_index_A[group]; + cck[1] = priv->cck_tx_power_index_B[group]; if (priv->hi_pa) { if (cck[0] > 0x20) @@ -1407,10 +1408,6 @@ ofdm[0] = priv->ht40_1s_tx_power_index_A[group]; ofdm[1] = priv->ht40_1s_tx_power_index_B[group]; - if (ofdm[0]) - ofdm[0] -= 1; - if (ofdm[1]) - ofdm[1] -= 1; ofdmbase[0] = ofdm[0] + priv->ofdm_tx_power_index_diff[group].a; ofdmbase[1] = ofdm[1] + priv->ofdm_tx_power_index_diff[group].b; @@ -1499,20 +1496,19 @@ rtl8xxxu_write32(priv, REG_TX_AGC_A_MCS15_MCS12, mcs_a + power_base->reg_0e1c); + val8 = u32_get_bits(mcs_a + power_base->reg_0e1c, 0xff000000); for (i = 0; i < 3; i++) { - if (i != 2) - val8 = (mcsbase[0] > 8) ? (mcsbase[0] - 8) : 0; - else - val8 = (mcsbase[0] > 6) ? (mcsbase[0] - 6) : 0; + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); rtl8xxxu_write8(priv, REG_OFDM0_XC_TX_IQ_IMBALANCE + i, val8); } + rtl8xxxu_write32(priv, REG_TX_AGC_B_MCS15_MCS12, mcs_b + power_base->reg_0868); + val8 = u32_get_bits(mcs_b + power_base->reg_0868, 0xff000000); for (i = 0; i < 3; i++) { - if (i != 2) - val8 = (mcsbase[1] > 8) ? (mcsbase[1] - 8) : 0; - else - val8 = (mcsbase[1] > 6) ? (mcsbase[1] - 6) : 0; + base = i != 2 ? 8 : 6; + val8 = max_t(int, val8 - base, 0); rtl8xxxu_write8(priv, REG_OFDM0_XD_TX_IQ_IMBALANCE + i, val8); } } @@ -1608,18 +1604,18 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv) { struct device *dev = &priv->udev->dev; - u32 val32, bonding; + u32 val32, bonding, sys_cfg; u16 val16; - val32 = rtl8xxxu_read32(priv, REG_SYS_CFG); - priv->chip_cut = (val32 & SYS_CFG_CHIP_VERSION_MASK) >> + sys_cfg = rtl8xxxu_read32(priv, REG_SYS_CFG); + priv->chip_cut = (sys_cfg & SYS_CFG_CHIP_VERSION_MASK) >> SYS_CFG_CHIP_VERSION_SHIFT; - if (val32 & SYS_CFG_TRP_VAUX_EN) { + if (sys_cfg & SYS_CFG_TRP_VAUX_EN) { dev_info(dev, "Unsupported test chip\n"); return -ENOTSUPP; } - if (val32 & SYS_CFG_BT_FUNC) { + if (sys_cfg & SYS_CFG_BT_FUNC) { if (priv->chip_cut >= 3) { sprintf(priv->chip_name, "8723BU"); priv->rtl_chip = RTL8723B; @@ -1641,7 +1637,7 @@ if (val32 & MULTI_GPS_FUNC_EN) priv->has_gps = 1; priv->is_multi_func = 1; - } else if (val32 & SYS_CFG_TYPE_ID) { + } else if (sys_cfg & SYS_CFG_TYPE_ID) { bonding = rtl8xxxu_read32(priv, REG_HPON_FSM); bonding &= HPON_FSM_BONDING_MASK; if (priv->fops->tx_desc_size == @@ -1689,7 +1685,7 @@ case RTL8188E: case RTL8192E: case RTL8723B: - switch (val32 & SYS_CFG_VENDOR_EXT_MASK) { + switch (sys_cfg & SYS_CFG_VENDOR_EXT_MASK) { case SYS_CFG_VENDOR_ID_TSMC: sprintf(priv->chip_vendor, "TSMC"); break; @@ -1706,7 +1702,7 @@ } break; default: - if (val32 & SYS_CFG_VENDOR_ID) { + if (sys_cfg & SYS_CFG_VENDOR_ID) { sprintf(priv->chip_vendor, "UMC"); priv->vendor_umc = 1; } else { @@ -1875,13 +1871,6 @@ /* We have 8 bits to indicate validity */ map_addr = offset * 8; - if (map_addr >= EFUSE_MAP_LEN) { - dev_warn(dev, "%s: Illegal map_addr (%04x), " - "efuse corrupt!\n", - __func__, map_addr); - ret = -EINVAL; - goto exit; - } for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { /* Check word enable condition in the section */ if (word_mask & BIT(i)) { @@ -1892,6 +1881,13 @@ ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); if (ret) goto exit; + if (map_addr >= EFUSE_MAP_LEN - 1) { + dev_warn(dev, "%s: Illegal map_addr (%04x), " + "efuse corrupt!\n", + __func__, map_addr); + ret = -EINVAL; + goto exit; + } priv->efuse_wifi.raw[map_addr++] = val8; ret = rtl8xxxu_read_efuse8(priv, efuse_addr++, &val8); @@ -2926,12 +2922,12 @@ } if (!(simubitmap & 0x30) && priv->tx_paths > 1) { - /* path B RX OK */ + /* path B TX OK */ for (i = 4; i < 6; i++) result[3][i] = result[c1][i]; } - if (!(simubitmap & 0x30) && priv->tx_paths > 1) { + if (!(simubitmap & 0xc0) && priv->tx_paths > 1) { /* path B RX OK */ for (i = 6; i < 8; i++) result[3][i] = result[c1][i]; @@ -3820,9 +3816,8 @@ rtl8xxxu_write8(priv, REG_RSV_CTRL, 0x0e); } -#ifdef NEED_PS_TDMA -static void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, - u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) +void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv, + u8 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) { struct h2c_cmd h2c; @@ -3835,7 +3830,6 @@ h2c.b_type_dma.data5 = arg5; rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.b_type_dma)); } -#endif void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv) { @@ -3902,6 +3896,9 @@ else macpower = true; + if (fops->needs_full_init) + macpower = false; + ret = fops->power_on(priv); if (ret < 0) { dev_warn(dev, "%s: Failed power on\n", __func__); @@ -4045,6 +4042,7 @@ RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL | RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC; rtl8xxxu_write32(priv, REG_RCR, val32); + priv->regrcr = val32; /* * Accept all multicast @@ -4304,7 +4302,8 @@ rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); } -void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi) +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, + u32 ramask, u8 rateid, int sgi) { struct h2c_cmd h2c; @@ -4324,7 +4323,7 @@ } void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv, - u32 ramask, int sgi) + u32 ramask, u8 rateid, int sgi) { struct h2c_cmd h2c; u8 bw = 0; @@ -4338,7 +4337,7 @@ h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff; h2c.ramask.arg = 0x80; - h2c.b_macid_cfg.data1 = 0; + h2c.b_macid_cfg.data1 = rateid; if (sgi) h2c.b_macid_cfg.data1 |= BIT(7); @@ -4369,12 +4368,9 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv, u8 macid, bool connect) { -#ifdef RTL8XXXU_GEN2_REPORT_CONNECT /* - * Barry Day reports this causes issues with 8192eu and 8723bu - * devices reconnecting. The reason for this is unclear, but - * until it is better understood, leave the code in place but - * disabled, so it is not lost. + * The firmware turns on the rate control when it knows it's + * connected to a network. */ struct h2c_cmd h2c; @@ -4387,7 +4383,6 @@ h2c.media_status_rpt.parm &= ~BIT(0); rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt)); -#endif } void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv) @@ -4478,6 +4473,35 @@ rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx); } +static u16 +rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta) +{ + u16 network_type = WIRELESS_MODE_UNKNOWN; + + if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) { + if (sta->vht_cap.vht_supported) + network_type = WIRELESS_MODE_AC; + else if (sta->ht_cap.ht_supported) + network_type = WIRELESS_MODE_N_5G; + + network_type |= WIRELESS_MODE_A; + } else { + if (sta->vht_cap.vht_supported) + network_type = WIRELESS_MODE_AC; + else if (sta->ht_cap.ht_supported) + network_type = WIRELESS_MODE_N_24G; + + if (sta->supp_rates[0] <= 0xf) + network_type |= WIRELESS_MODE_B; + else if (sta->supp_rates[0] & 0xf) + network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G); + else + network_type |= WIRELESS_MODE_G; + } + + return network_type; +} + static void rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changed) @@ -4520,7 +4544,10 @@ sgi = 1; rcu_read_unlock(); - priv->fops->update_rate_mask(priv, ramask, sgi); + priv->vif = vif; + priv->rssi_level = RTL8XXXU_RATR_STA_INIT; + + priv->fops->update_rate_mask(priv, ramask, 0, sgi); rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff); @@ -4947,6 +4974,8 @@ if (control && control->sta) sta = control->sta; + queue = rtl8xxxu_queue_select(hw, skb); + tx_desc = skb_push(skb, tx_desc_size); memset(tx_desc, 0, tx_desc_size); @@ -4959,7 +4988,6 @@ is_broadcast_ether_addr(ieee80211_get_DA(hdr))) tx_desc->txdw0 |= TXDESC_BROADMULTICAST; - queue = rtl8xxxu_queue_select(hw, skb); tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT); if (tx_info->control.hw_key) { @@ -5095,7 +5123,7 @@ pending = priv->rx_urb_pending_count; } else { skb = (struct sk_buff *)rx_urb->urb.context; - dev_kfree_skb(skb); + dev_kfree_skb_irq(skb); usb_free_urb(&rx_urb->urb); } @@ -5148,12 +5176,259 @@ } } +/* + * The RTL8723BU/RTL8192EU vendor driver use coexistence table type + * 0-7 to represent writing different combinations of register values + * to REG_BT_COEX_TABLEs. It's for different kinds of coexistence use + * cases which Realtek doesn't provide detail for these settings. Keep + * this aligned with vendor driver for easier maintenance. + */ +void rtl8723bu_set_coex_with_type(struct rtl8xxxu_priv *priv, u8 type) +{ + switch (type) { + case 0: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 1: + case 3: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 2: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 4: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaa5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 5: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x5a5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaa5a5a5a); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 6: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0x55555555); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + case 7: + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE1, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE2, 0xaaaaaaaa); + rtl8xxxu_write32(priv, REG_BT_COEX_TABLE3, 0x00ffffff); + rtl8xxxu_write8(priv, REG_BT_COEX_TABLE4, 0x03); + break; + default: + break; + } +} + +void rtl8723bu_update_bt_link_info(struct rtl8xxxu_priv *priv, u8 bt_info) +{ + struct rtl8xxxu_btcoex *btcoex = &priv->bt_coex; + + if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) + btcoex->c2h_bt_inquiry = true; + else + btcoex->c2h_bt_inquiry = false; + + if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { + btcoex->bt_status = BT_8723B_1ANT_STATUS_NON_CONNECTED_IDLE; + btcoex->has_sco = false; + btcoex->has_hid = false; + btcoex->has_pan = false; + btcoex->has_a2dp = false; + } else { + if ((bt_info & 0x1f) == BT_INFO_8723B_1ANT_B_CONNECTION) + btcoex->bt_status = BT_8723B_1ANT_STATUS_CONNECTED_IDLE; + else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || + (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) + btcoex->bt_status = BT_8723B_1ANT_STATUS_SCO_BUSY; + else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) + btcoex->bt_status = BT_8723B_1ANT_STATUS_ACL_BUSY; + else + btcoex->bt_status = BT_8723B_1ANT_STATUS_MAX; + + if (bt_info & BT_INFO_8723B_1ANT_B_FTP) + btcoex->has_pan = true; + else + btcoex->has_pan = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) + btcoex->has_a2dp = true; + else + btcoex->has_a2dp = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_HID) + btcoex->has_hid = true; + else + btcoex->has_hid = false; + + if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) + btcoex->has_sco = true; + else + btcoex->has_sco = false; + } + + if (!btcoex->has_a2dp && !btcoex->has_sco && + !btcoex->has_pan && btcoex->has_hid) + btcoex->hid_only = true; + else + btcoex->hid_only = false; + + if (!btcoex->has_sco && !btcoex->has_pan && + !btcoex->has_hid && btcoex->has_a2dp) + btcoex->has_a2dp = true; + else + btcoex->has_a2dp = false; + + if (btcoex->bt_status == BT_8723B_1ANT_STATUS_SCO_BUSY || + btcoex->bt_status == BT_8723B_1ANT_STATUS_ACL_BUSY) + btcoex->bt_busy = true; + else + btcoex->bt_busy = false; +} + +void rtl8723bu_handle_bt_inquiry(struct rtl8xxxu_priv *priv) +{ + struct ieee80211_vif *vif; + struct rtl8xxxu_btcoex *btcoex; + bool wifi_connected; + + vif = priv->vif; + btcoex = &priv->bt_coex; + wifi_connected = (vif && vif->bss_conf.assoc); + + if (!wifi_connected) { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 0); + } else if (btcoex->has_sco || btcoex->has_hid || btcoex->has_a2dp) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else if (btcoex->has_pan) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x3f, 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 7); + } +} + +void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv) +{ + struct ieee80211_vif *vif; + struct rtl8xxxu_btcoex *btcoex; + bool wifi_connected; + + vif = priv->vif; + btcoex = &priv->bt_coex; + wifi_connected = (vif && vif->bss_conf.assoc); + + if (wifi_connected) { + u32 val32 = 0; + u32 high_prio_tx = 0, high_prio_rx = 0; + + val32 = rtl8xxxu_read32(priv, 0x770); + high_prio_tx = val32 & 0x0000ffff; + high_prio_rx = (val32 & 0xffff0000) >> 16; + + if (btcoex->bt_busy) { + if (btcoex->hid_only) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x20, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 5); + } else if (btcoex->a2dp_only) { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } else if ((btcoex->has_a2dp && btcoex->has_pan) || + (btcoex->has_hid && btcoex->has_a2dp && + btcoex->has_pan)) { + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, + 0x3, 0x10, 0x10); + rtl8723bu_set_coex_with_type(priv, 4); + } else if (btcoex->has_hid && btcoex->has_a2dp) { + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, + 0x3, 0x10, 0x10); + rtl8723bu_set_coex_with_type(priv, 3); + } else { + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, + 0x3, 0x11, 0x11); + rtl8723bu_set_coex_with_type(priv, 4); + } + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + if (high_prio_tx + high_prio_rx <= 60) + rtl8723bu_set_coex_with_type(priv, 2); + else + rtl8723bu_set_coex_with_type(priv, 7); + } + } else { + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0); + rtl8723bu_set_coex_with_type(priv, 0); + } +} + +static void rtl8xxxu_c2hcmd_callback(struct work_struct *work) +{ + struct rtl8xxxu_priv *priv; + struct rtl8723bu_c2h *c2h; + struct sk_buff *skb = NULL; + unsigned long flags; + u8 bt_info = 0; + struct rtl8xxxu_btcoex *btcoex; + + priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work); + btcoex = &priv->bt_coex; + + if (priv->rf_paths > 1) + goto out; + + while (!skb_queue_empty(&priv->c2hcmd_queue)) { + spin_lock_irqsave(&priv->c2hcmd_lock, flags); + skb = __skb_dequeue(&priv->c2hcmd_queue); + spin_unlock_irqrestore(&priv->c2hcmd_lock, flags); + + c2h = (struct rtl8723bu_c2h *)skb->data; + + switch (c2h->id) { + case C2H_8723B_BT_INFO: + bt_info = c2h->bt_info.bt_info; + + rtl8723bu_update_bt_link_info(priv, bt_info); + if (btcoex->c2h_bt_inquiry) { + rtl8723bu_handle_bt_inquiry(priv); + break; + } + rtl8723bu_handle_bt_info(priv); + break; + default: + break; + } + } + +out: + dev_kfree_skb(skb); +} + static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv, struct sk_buff *skb) { struct rtl8723bu_c2h *c2h = (struct rtl8723bu_c2h *)skb->data; struct device *dev = &priv->udev->dev; int len; + unsigned long flags; len = skb->len - 2; @@ -5191,6 +5466,12 @@ 16, 1, c2h->raw.payload, len, false); break; } + + spin_lock_irqsave(&priv->c2hcmd_lock, flags); + __skb_queue_tail(&priv->c2hcmd_queue, skb); + spin_unlock_irqrestore(&priv->c2hcmd_lock, flags); + + schedule_work(&priv->c2hcmd_work); } int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb) @@ -5315,7 +5596,6 @@ struct device *dev = &priv->udev->dev; dev_dbg(dev, "%s: C2H packet\n", __func__); rtl8723bu_handle_c2h(priv, skb); - dev_kfree_skb(skb); return RX_TYPE_C2H; } @@ -5452,6 +5732,7 @@ rtl8xxxu_write32(priv, REG_USB_HIMR, val32); error: + usb_free_urb(urb); return ret; } @@ -5464,6 +5745,10 @@ switch (vif->type) { case NL80211_IFTYPE_STATION: + if (!priv->vif) + priv->vif = vif; + else + return -EOPNOTSUPP; rtl8xxxu_stop_tx_beacon(priv); val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); @@ -5487,13 +5772,15 @@ struct rtl8xxxu_priv *priv = hw->priv; dev_dbg(&priv->udev->dev, "%s\n", __func__); + + if (priv->vif) + priv->vif = NULL; } static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed) { struct rtl8xxxu_priv *priv = hw->priv; struct device *dev = &priv->udev->dev; - u16 val16; int ret = 0, channel; bool ht40; @@ -5503,14 +5790,6 @@ __func__, hw->conf.chandef.chan->hw_value, changed, hw->conf.chandef.width); - if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - val16 = ((hw->conf.long_frame_max_tx_count << - RETRY_LIMIT_LONG_SHIFT) & RETRY_LIMIT_LONG_MASK) | - ((hw->conf.short_frame_max_tx_count << - RETRY_LIMIT_SHORT_SHIFT) & RETRY_LIMIT_SHORT_MASK); - rtl8xxxu_write16(priv, REG_RETRY_LIMIT, val16); - } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { switch (hw->conf.chandef.width) { case NL80211_CHAN_WIDTH_20_NOHT: @@ -5593,7 +5872,7 @@ unsigned int *total_flags, u64 multicast) { struct rtl8xxxu_priv *priv = hw->priv; - u32 rcr = rtl8xxxu_read32(priv, REG_RCR); + u32 rcr = priv->regrcr; dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n", __func__, changed_flags, *total_flags); @@ -5639,6 +5918,7 @@ */ rtl8xxxu_write32(priv, REG_RCR, rcr); + priv->regrcr = rcr; *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL | @@ -5772,11 +6052,184 @@ return 0; } +static u8 rtl8xxxu_signal_to_snr(int signal) +{ + if (signal < RTL8XXXU_NOISE_FLOOR_MIN) + signal = RTL8XXXU_NOISE_FLOOR_MIN; + else if (signal > 0) + signal = 0; + return (u8)(signal - RTL8XXXU_NOISE_FLOOR_MIN); +} + +static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv, + int signal, struct ieee80211_sta *sta) +{ + struct ieee80211_hw *hw = priv->hw; + u16 wireless_mode; + u8 rssi_level, ratr_idx; + u8 txbw_40mhz; + u8 snr, snr_thresh_high, snr_thresh_low; + u8 go_up_gap = 5; + + rssi_level = priv->rssi_level; + snr = rtl8xxxu_signal_to_snr(signal); + snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH; + snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW; + txbw_40mhz = (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) ? 1 : 0; + + switch (rssi_level) { + case RTL8XXXU_RATR_STA_MID: + snr_thresh_high += go_up_gap; + break; + case RTL8XXXU_RATR_STA_LOW: + snr_thresh_high += go_up_gap; + snr_thresh_low += go_up_gap; + break; + default: + break; + } + + if (snr > snr_thresh_high) + rssi_level = RTL8XXXU_RATR_STA_HIGH; + else if (snr > snr_thresh_low) + rssi_level = RTL8XXXU_RATR_STA_MID; + else + rssi_level = RTL8XXXU_RATR_STA_LOW; + + if (rssi_level != priv->rssi_level) { + int sgi = 0; + u32 rate_bitmap = 0; + + rcu_read_lock(); + rate_bitmap = (sta->supp_rates[0] & 0xfff) | + (sta->ht_cap.mcs.rx_mask[0] << 12) | + (sta->ht_cap.mcs.rx_mask[1] << 20); + if (sta->ht_cap.cap & + (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20)) + sgi = 1; + rcu_read_unlock(); + + wireless_mode = rtl8xxxu_wireless_mode(hw, sta); + switch (wireless_mode) { + case WIRELESS_MODE_B: + ratr_idx = RATEID_IDX_B; + if (rate_bitmap & 0x0000000c) + rate_bitmap &= 0x0000000d; + else + rate_bitmap &= 0x0000000f; + break; + case WIRELESS_MODE_A: + case WIRELESS_MODE_G: + ratr_idx = RATEID_IDX_G; + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) + rate_bitmap &= 0x00000f00; + else + rate_bitmap &= 0x00000ff0; + break; + case (WIRELESS_MODE_B | WIRELESS_MODE_G): + ratr_idx = RATEID_IDX_BG; + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) + rate_bitmap &= 0x00000f00; + else if (rssi_level == RTL8XXXU_RATR_STA_MID) + rate_bitmap &= 0x00000ff0; + else + rate_bitmap &= 0x00000ff5; + break; + case WIRELESS_MODE_N_24G: + case WIRELESS_MODE_N_5G: + case (WIRELESS_MODE_G | WIRELESS_MODE_N_24G): + case (WIRELESS_MODE_A | WIRELESS_MODE_N_5G): + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_GN_N2SS; + else + ratr_idx = RATEID_IDX_GN_N1SS; + break; + case (WIRELESS_MODE_B | WIRELESS_MODE_G | WIRELESS_MODE_N_24G): + case (WIRELESS_MODE_B | WIRELESS_MODE_N_24G): + if (txbw_40mhz) { + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_BGN_40M_2SS; + else + ratr_idx = RATEID_IDX_BGN_40M_1SS; + } else { + if (priv->tx_paths == 2 && priv->rx_paths == 2) + ratr_idx = RATEID_IDX_BGN_20M_2SS_BN; + else + ratr_idx = RATEID_IDX_BGN_20M_1SS_BN; + } + + if (priv->tx_paths == 2 && priv->rx_paths == 2) { + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) { + rate_bitmap &= 0x0f8f0000; + } else if (rssi_level == RTL8XXXU_RATR_STA_MID) { + rate_bitmap &= 0x0f8ff000; + } else { + if (txbw_40mhz) + rate_bitmap &= 0x0f8ff015; + else + rate_bitmap &= 0x0f8ff005; + } + } else { + if (rssi_level == RTL8XXXU_RATR_STA_HIGH) { + rate_bitmap &= 0x000f0000; + } else if (rssi_level == RTL8XXXU_RATR_STA_MID) { + rate_bitmap &= 0x000ff000; + } else { + if (txbw_40mhz) + rate_bitmap &= 0x000ff015; + else + rate_bitmap &= 0x000ff005; + } + } + break; + default: + ratr_idx = RATEID_IDX_BGN_40M_2SS; + rate_bitmap &= 0x0fffffff; + break; + } + + priv->rssi_level = rssi_level; + priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi); + } +} + +static void rtl8xxxu_watchdog_callback(struct work_struct *work) +{ + struct ieee80211_vif *vif; + struct rtl8xxxu_priv *priv; + + priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work); + vif = priv->vif; + + if (vif && vif->type == NL80211_IFTYPE_STATION) { + int signal; + struct ieee80211_sta *sta; + + rcu_read_lock(); + sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); + if (!sta) { + struct device *dev = &priv->udev->dev; + + dev_dbg(dev, "%s: no sta found\n", __func__); + rcu_read_unlock(); + goto out; + } + rcu_read_unlock(); + + signal = ieee80211_ave_rssi(vif); + rtl8xxxu_refresh_rate_mask(priv, signal, sta); + } + +out: + schedule_delayed_work(&priv->ra_watchdog, 2 * HZ); +} + static int rtl8xxxu_start(struct ieee80211_hw *hw) { struct rtl8xxxu_priv *priv = hw->priv; struct rtl8xxxu_rx_urb *rx_urb; struct rtl8xxxu_tx_urb *tx_urb; + struct sk_buff *skb; unsigned long flags; int ret, i; @@ -5827,7 +6280,16 @@ rx_urb->hw = hw; ret = rtl8xxxu_submit_rx_urb(priv, rx_urb); + if (ret) { + if (ret != -ENOMEM) { + skb = (struct sk_buff *)rx_urb->urb.context; + dev_kfree_skb(skb); + } + rtl8xxxu_queue_rx_urb(priv, rx_urb); + } } + + schedule_delayed_work(&priv->ra_watchdog, 2 * HZ); exit: /* * Accept all data and mgmt frames @@ -5879,6 +6341,8 @@ if (priv->usb_interrupts) rtl8xxxu_write32(priv, REG_USB_HIMR, 0); + cancel_delayed_work_sync(&priv->ra_watchdog); + rtl8xxxu_free_rx_resources(priv); rtl8xxxu_free_tx_resources(priv); } @@ -5911,7 +6375,7 @@ u8 dir, xtype, num; int ret = 0; - host_interface = &interface->altsetting[0]; + host_interface = interface->cur_altsetting; interface_desc = &host_interface->desc; endpoints = interface_desc->bNumEndpoints; @@ -6051,6 +6515,10 @@ INIT_LIST_HEAD(&priv->rx_urb_pending_list); spin_lock_init(&priv->rx_urb_lock); INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work); + INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback); + spin_lock_init(&priv->c2hcmd_lock); + INIT_WORK(&priv->c2hcmd_work, rtl8xxxu_c2hcmd_callback); + skb_queue_head_init(&priv->c2hcmd_queue); usb_set_intfdata(interface, hw); @@ -6360,6 +6828,18 @@ .driver_info = (unsigned long)&rtl8192eu_fops}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192eu_fops}, +/* D-Link DWA-131 rev C1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3312, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* TP-Link TL-WN8200ND V2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0126, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UM */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UH */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0104, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, #endif { } }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/base.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/base.c @@ -195,8 +195,8 @@ } else { if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "1T2R or 2T2R\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; ht_cap->mcs.rx_mask[4] = 0x01; @@ -204,7 +204,7 @@ ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -436,22 +436,22 @@ } } -static void _rtl_init_deferred_work(struct ieee80211_hw *hw) +static int _rtl_init_deferred_work(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); + struct workqueue_struct *wq; + + wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); + if (!wq) + return -ENOMEM; /* <1> timer */ timer_setup(&rtlpriv->works.watchdog_timer, rtl_watch_dog_timer_callback, 0); - timer_setup(&rtlpriv->works.dualmac_easyconcurrent_retrytimer, - rtl_easy_concurrent_retrytimer_callback, 0); + /* <2> work queue */ rtlpriv->works.hw = hw; - rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name); - if (unlikely(!rtlpriv->works.rtl_wq)) { - pr_err("Failed to allocate work queue\n"); - return; - } + rtlpriv->works.rtl_wq = wq; INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); @@ -465,6 +465,7 @@ (void *)rtl_fwevt_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.c2hcmd_wq, (void *)rtl_c2hcmd_wq_callback); + return 0; } void rtl_deinit_deferred_work(struct ieee80211_hw *hw, bool ips_wq) @@ -564,9 +565,7 @@ rtlmac->link_state = MAC80211_NOLINK; /* <6> init deferred work */ - _rtl_init_deferred_work(hw); - - return 0; + return _rtl_init_deferred_work(hw); } EXPORT_SYMBOL_GPL(rtl_init_core); @@ -1324,7 +1323,7 @@ rtlpriv->cfg->ops->chk_switch_dmdp(hw); } if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); mac->link_state = MAC80211_LINKING; /* Dul mac */ @@ -1385,7 +1384,7 @@ if (mac->act_scanning) return false; - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, "%s ACT_ADDBAREQ From :%pM\n", is_tx ? "Tx" : "Rx", hdr->addr2); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n", @@ -1400,8 +1399,8 @@ rcu_read_lock(); sta = rtl_find_sta(hw, hdr->addr3); if (sta == NULL) { - RT_TRACE(rtlpriv, COMP_SEND | COMP_RECV, - DBG_DMESG, "sta is NULL\n"); + rtl_dbg(rtlpriv, COMP_SEND | COMP_RECV, + DBG_DMESG, "sta is NULL\n"); rcu_read_unlock(); return true; } @@ -1428,13 +1427,13 @@ } break; case ACT_ADDBARSP: - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "ACT_ADDBADEL From :%pM\n", hdr->addr2); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -1519,9 +1518,9 @@ /* 68 : UDP BOOTP client * 67 : UDP BOOTP server */ - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), - DBG_DMESG, "dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx"); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), + DBG_DMESG, "dhcp %s !!\n", + (is_tx) ? "Tx" : "Rx"); if (is_tx) setup_special_tx(rtlpriv, ppsc, @@ -1540,8 +1539,8 @@ rtlpriv->btcoexist.btc_info.in_4way = true; rtlpriv->btcoexist.btc_info.in_4way_ts = jiffies; - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); + rtl_dbg(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, + "802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"); if (is_tx) { rtlpriv->ra.is_special_data = true; @@ -1583,12 +1582,12 @@ info = IEEE80211_SKB_CB(skb); ieee80211_tx_info_clear_status(info); if (ack) { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD, - "tx report: ack\n"); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: ack\n"); info->flags |= IEEE80211_TX_STAT_ACK; } else { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_LOUD, - "tx report: not ack\n"); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_LOUD, + "tx report: not ack\n"); info->flags &= ~IEEE80211_TX_STAT_ACK; } ieee80211_tx_status_irqsafe(hw, skb); @@ -1626,8 +1625,8 @@ tx_report->last_sent_time = jiffies; tx_info->sn = sn; tx_info->send_time = tx_report->last_sent_time; - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG, - "Send TX-Report sn=0x%X\n", sn); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Send TX-Report sn=0x%X\n", sn); return sn; } @@ -1674,9 +1673,9 @@ break; } } - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_DMESG, - "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n", - st, sn, retry); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_DMESG, + "Recv TX-Report st=0x%02X sn=0x%X retry=0x%X\n", + st, sn, retry); } EXPORT_SYMBOL_GPL(rtl_tx_report_handler); @@ -1689,9 +1688,9 @@ return true; if (time_before(tx_report->last_sent_time + 3 * HZ, jiffies)) { - RT_TRACE(rtlpriv, COMP_TX_REPORT, DBG_WARNING, - "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n", - tx_report->last_sent_sn, tx_report->last_recv_sn); + rtl_dbg(rtlpriv, COMP_TX_REPORT, DBG_WARNING, + "Check TX-Report timeout!! s_sn=0x%X r_sn=0x%X\n", + tx_report->last_sent_sn, tx_report->last_recv_sn); return true; /* 3 sec. (timeout) seen as acked */ } @@ -1707,8 +1706,8 @@ if (rtl_check_tx_report_acked(hw)) break; usleep_range(1000, 2000); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "Wait 1ms (%d/%d) to disable key.\n", i, wait_ms); } } @@ -1770,14 +1769,13 @@ return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - *ssn); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d seq:%d\n", sta->addr, tid, + *ssn); tid_data->agg.agg_state = RTL_AGG_START; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - return 0; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; } int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -1789,8 +1787,8 @@ if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1829,8 +1827,8 @@ return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); tid_data->agg.rx_agg_state = RTL_RX_AGG_START; return 0; @@ -1845,8 +1843,8 @@ if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1866,8 +1864,8 @@ if (sta == NULL) return -EINVAL; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - "on ra = %pM tid = %d\n", sta->addr, tid); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, + "on ra = %pM tid = %d\n", sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1887,9 +1885,9 @@ btc_ops->btc_get_ampdu_cfg(rtlpriv, &reject_agg, &ctrl_agg_size, &agg_size); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d", - reject_agg, ctrl_agg_size, agg_size); + rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, + "Set RX AMPDU: coex - reject=%d, ctrl_agg_size=%d, size=%d", + reject_agg, ctrl_agg_size, agg_size); rtlpriv->hw->max_rx_aggregation_subframes = (ctrl_agg_size ? agg_size : IEEE80211_MAX_AMPDU_BUF_HT); @@ -1977,9 +1975,9 @@ list_del(&entry->list); rtlpriv->scan_list.num--; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "BSSID=%pM is expire in scan list (total=%d)\n", - entry->bssid, rtlpriv->scan_list.num); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "BSSID=%pM is expire in scan list (total=%d)\n", + entry->bssid, rtlpriv->scan_list.num); kfree(entry); } @@ -1995,8 +1993,7 @@ struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); unsigned long flags; - struct rtl_bssid_entry *entry; - bool entry_found = false; + struct rtl_bssid_entry *entry = NULL, *iter; /* check if it is scanning */ if (!mac->act_scanning) @@ -2009,18 +2006,18 @@ spin_lock_irqsave(&rtlpriv->locks.scan_list_lock, flags); - list_for_each_entry(entry, &rtlpriv->scan_list.list, list) { - if (memcmp(entry->bssid, hdr->addr3, ETH_ALEN) == 0) { - list_del_init(&entry->list); - entry_found = true; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "Update BSSID=%pM to scan list (total=%d)\n", - hdr->addr3, rtlpriv->scan_list.num); + list_for_each_entry(iter, &rtlpriv->scan_list.list, list) { + if (memcmp(iter->bssid, hdr->addr3, ETH_ALEN) == 0) { + list_del_init(&iter->list); + entry = iter; + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Update BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); break; } } - if (!entry_found) { + if (!entry) { entry = kmalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) @@ -2029,9 +2026,9 @@ memcpy(entry->bssid, hdr->addr3, ETH_ALEN); rtlpriv->scan_list.num++; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - "Add BSSID=%pM to scan list (total=%d)\n", - hdr->addr3, rtlpriv->scan_list.num); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, + "Add BSSID=%pM to scan list (total=%d)\n", + hdr->addr3, rtlpriv->scan_list.num); } entry->age = jiffies; @@ -2191,8 +2188,8 @@ if ((rtlpriv->link_info.bcn_rx_inperiod + rtlpriv->link_info.num_rx_inperiod) == 0) { rtlpriv->link_info.roam_times++; - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "AP off for %d s\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "AP off for %d s\n", (rtlpriv->link_info.roam_times * 2)); /* if we can't recv beacon for 10s, @@ -2305,11 +2302,11 @@ switch (cmd_id) { case C2H_DBG: - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "[C2H], C2H_DBG!!\n"); break; case C2H_TXBF: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_TXBF!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_TXBF!!\n"); break; case C2H_TX_REPORT: rtl_tx_report_handler(hw, cmd_buf, cmd_len); @@ -2319,20 +2316,20 @@ hal_ops->c2h_ra_report_handler(hw, cmd_buf, cmd_len); break; case C2H_BT_INFO: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_BT_INFO!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_INFO!!\n"); if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_btinfo_notify(rtlpriv, cmd_buf, cmd_len); break; case C2H_BT_MP: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], C2H_BT_MP!!\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], C2H_BT_MP!!\n"); if (rtlpriv->cfg->ops->get_btc_status()) btc_ops->btc_btmpinfo_notify(rtlpriv, cmd_buf, cmd_len); break; default: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id); + rtl_dbg(rtlpriv, COMP_FW, DBG_TRACE, + "[C2H], Unknown packet!! cmd_id(%#X)!\n", cmd_id); break; } } @@ -2356,8 +2353,8 @@ if (!skb) break; - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", - *((u8 *)skb->cb)); + rtl_dbg(rtlpriv, COMP_FW, DBG_DMESG, "C2H rx_desc_shift=%d\n", + *((u8 *)skb->cb)); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_DMESG, "C2H data: ", skb->data, skb->len); @@ -2379,19 +2376,6 @@ rtl_c2hcmd_launcher(hw, 1); } -void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t) -{ - struct rtl_priv *rtlpriv = - from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer); - struct ieee80211_hw *hw = rtlpriv->hw; - struct rtl_priv *buddy_priv = rtlpriv->buddy_priv; - - if (buddy_priv == NULL) - return; - - rtlpriv->cfg->ops->dualmac_easy_concurrent(hw); -} - /********************************************************* * * frame process functions @@ -2702,29 +2686,29 @@ (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; @@ -2737,9 +2721,6 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core"); -struct rtl_global_var rtl_global_var = {}; -EXPORT_SYMBOL_GPL(rtl_global_var); - static int __init rtl_core_module_init(void) { BUILD_BUG_ON(TX_PWR_BY_RATE_NUM_RATE < TX_PWR_BY_RATE_NUM_SECTION); @@ -2753,10 +2734,6 @@ /* add debugfs */ rtl_debugfs_add_topdir(); - /* init some global vars */ - INIT_LIST_HEAD(&rtl_global_var.glb_priv_list); - spin_lock_init(&rtl_global_var.glb_list_lock); - return 0; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/base.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/base.h @@ -127,8 +127,6 @@ u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); u8 rtl_tid_to_ac(u8 tid); -void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t); -extern struct rtl_global_var rtl_global_var; void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/cam.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/cam.c @@ -43,14 +43,14 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "The Key ID is %d\n", entry_no); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "The Key ID is %d\n", entry_no); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { @@ -64,10 +64,10 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A4: %x\n", target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A0: %x\n", target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); } else { @@ -83,15 +83,15 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A4: %x\n", target_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "WRITE A0: %x\n", target_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A4: %x\n", target_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "WRITE A0: %x\n", target_command); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "after set key, usconfig:%x\n", us_config); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "after set key, usconfig:%x\n", us_config); } u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -101,14 +101,14 @@ u32 us_config; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "ulKeyId exceed!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ulKeyId exceed!\n"); return 0; } @@ -120,7 +120,7 @@ rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *)key_content, us_config); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "end\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "end\n"); return 1; @@ -133,7 +133,7 @@ u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -141,10 +141,10 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, 0); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); return 0; @@ -195,10 +195,10 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s: WRITE A0: %x\n", __func__, ul_command); } EXPORT_SYMBOL(rtl_cam_mark_invalid); @@ -245,12 +245,10 @@ rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content); rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - "rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A4: %x\n", __func__, ul_content); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, + "%s: WRITE A0: %x\n", __func__, ul_command); } } @@ -313,8 +311,8 @@ /* Remove from HW Security CAM */ eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "&&&&&&&&&del entry %d\n", i); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "&&&&&&&&&del entry %d\n", i); } } return; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/core.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/core.c @@ -76,8 +76,8 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); int err; - RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - "Firmware callback routine entered!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); complete(&rtlpriv->firmware_loading_complete); if (!firmware) { if (rtlpriv->cfg->alt_fw_name) { @@ -214,8 +214,8 @@ u8 retry_limit = 0x30; if (mac->vif) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "vif has been set!! mac->vif = 0x%p\n", mac->vif); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -230,16 +230,16 @@ /*fall through*/ case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_STATION\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]); } break; case NL80211_IFTYPE_ADHOC: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_ADHOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -256,8 +256,8 @@ mac->p2p = P2P_ROLE_GO; /*fall through*/ case NL80211_IFTYPE_AP: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_AP\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -271,8 +271,8 @@ retry_limit = 0x07; break; case NL80211_IFTYPE_MESH_POINT: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "NL80211_IFTYPE_MESH_POINT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "NL80211_IFTYPE_MESH_POINT\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -293,8 +293,8 @@ } if (mac->p2p) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "p2p role %x\n", vif->type); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p role %x\n", vif->type); mac->basic_rates = 0xff0;/*disable cck rate for p2p*/ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, (u8 *)(&mac->basic_rates)); @@ -360,8 +360,8 @@ vif->type = new_type; vif->p2p = p2p; ret = rtl_op_add_interface(hw, vif); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "p2p %x\n", p2p); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "p2p %x\n", p2p); return ret; } @@ -435,8 +435,8 @@ memset(mask, 0, MAX_WOL_BIT_MASK_SIZE); if (patterns[i].pattern_len < 0 || patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_WARNING, - "Pattern[%d] is too long\n", i); + rtl_dbg(rtlpriv, COMP_POWER, DBG_WARNING, + "Pattern[%d] is too long\n", i); continue; } pattern_os = patterns[i].pattern; @@ -515,8 +515,8 @@ "pattern to hw\n", content, len); /* 3. calculate crc */ rtl_pattern.crc = _calculate_wol_pattern_crc(content, len); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "CRC_Remainder = 0x%x\n", rtl_pattern.crc); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "CRC_Remainder = 0x%x\n", rtl_pattern.crc); /* 4. write crc & mask_for_hw to hw */ rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i); @@ -531,7 +531,7 @@ struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); if (WARN_ON(!wow)) return -EINVAL; @@ -557,7 +557,7 @@ struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); time64_t now; - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, "\n"); rtlhal->driver_is_goingto_unload = false; rtlhal->enter_pnp_sleep = false; rtlhal->wake_from_pnp_sleep = true; @@ -588,8 +588,8 @@ mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2)*/ - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -632,9 +632,9 @@ } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); /* brought up everything changes (changed == ~0) indicates first * open, so use our default value instead of that of wiphy. */ @@ -809,13 +809,13 @@ if (*new_flags & FIF_ALLMULTI) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive multicast frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive multicast frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive multicast frame\n"); } update_rcr = true; } @@ -823,12 +823,12 @@ if (changed_flags & FIF_FCSFAIL) { if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive FCS error frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive FCS error frame\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive FCS error frame\n"); } if (!update_rcr) update_rcr = true; @@ -855,12 +855,12 @@ if (*new_flags & FIF_CONTROL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive control frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive control frame.\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive control frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive control frame.\n"); } if (!update_rcr) update_rcr = true; @@ -869,12 +869,12 @@ if (changed_flags & FIF_OTHER_BSS) { if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Enable receive other BSS's frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Enable receive other BSS's frame.\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "Disable receive other BSS's frame.\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "Disable receive other BSS's frame.\n"); } if (!update_rcr) update_rcr = true; @@ -923,7 +923,7 @@ sta->supp_rates[0] &= 0xfffffff0; memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, "Add sta addr is %pM\n", sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); } @@ -939,8 +939,8 @@ struct rtl_sta_info *sta_entry; if (sta) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "Remove sta addr is %pM\n", sta->addr); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "Remove sta addr is %pM\n", sta->addr); sta_entry = (struct rtl_sta_info *)sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -988,8 +988,8 @@ int aci; if (queue >= AC_MAX) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "queue number %d is incorrect!\n", queue); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -1034,8 +1034,8 @@ (changed & BSS_CHANGED_BEACON_ENABLED && bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_BEACON_ENABLED\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -1052,8 +1052,8 @@ if ((changed & BSS_CHANGED_BEACON_ENABLED && !bss_conf->enable_beacon)) { if (mac->beacon_enabled == 1) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "ADHOC DISABLE BEACON\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -1062,8 +1062,8 @@ } } if (changed & BSS_CHANGED_BEACON_INT) { - RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, - "BSS_CHANGED_BEACON_INT\n"); + rtl_dbg(rtlpriv, COMP_BEACON, DBG_TRACE, + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -1102,8 +1102,8 @@ rcu_read_unlock(); goto out; } - RT_TRACE(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, - "send PS STATIC frame\n"); + rtl_dbg(rtlpriv, COMP_EASY_CONCURRENT, DBG_LOUD, + "send PS STATIC frame\n"); if (rtlpriv->dm.supp_phymode_switch) { if (sta->ht_cap.ht_supported) rtl_send_smps_action(hw, sta, @@ -1143,8 +1143,8 @@ HW_VAR_KEEP_ALIVE, (u8 *)(&keep_alive)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_ASSOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_ASSOC\n"); } else { struct cfg80211_bss *bss = NULL; @@ -1161,14 +1161,14 @@ IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_OFF); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "bssid = %pMF\n", mac->bssid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid = %pMF\n", mac->bssid); if (bss) { cfg80211_unlink_bss(hw->wiphy, bss); cfg80211_put_bss(hw->wiphy, bss); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "cfg80211_unlink !!\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "cfg80211_unlink !!\n"); } eth_zero_addr(mac->bssid); @@ -1179,8 +1179,8 @@ if (rtlpriv->cfg->ops->chk_switch_dmdp) rtlpriv->cfg->ops->chk_switch_dmdp(hw); } - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "BSS_CHANGED_UN_ASSOC\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "BSS_CHANGED_UN_ASSOC\n"); } rtlpriv->cfg->ops->set_network_type(hw, vif->type); /* For FW LPS: @@ -1198,14 +1198,14 @@ } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_ERP_CTS_PROT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; @@ -1214,8 +1214,8 @@ } if (changed & BSS_CHANGED_ERP_SLOT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_ERP_SLOT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -1229,8 +1229,8 @@ if (changed & BSS_CHANGED_HT) { struct ieee80211_sta *sta = NULL; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "BSS_CHANGED_HT\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); @@ -1261,8 +1261,8 @@ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *)bss_conf->bssid); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - "bssid: %pM\n", bss_conf->bssid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_DMESG, + "bssid: %pM\n", bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); @@ -1393,27 +1393,27 @@ switch (action) { case IEEE80211_AMPDU_TX_START: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl_tx_agg_start(hw, vif, sta, tid, ssn); case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl_tx_agg_stop(hw, vif, sta, tid); case IEEE80211_AMPDU_TX_OPERATIONAL: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); return rtl_rx_agg_start(hw, sta, tid); case IEEE80211_AMPDU_RX_STOP: - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_TRACE, + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); return rtl_rx_agg_stop(hw, sta, tid); default: pr_err("IEEE80211_AMPDU_ERR!!!!:\n"); @@ -1429,7 +1429,7 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = true; if (rtlpriv->link_info.higher_busytraffic) { mac->skip_scan = true; @@ -1467,7 +1467,7 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; mac->skip_scan = false; @@ -1517,8 +1517,8 @@ rtlpriv->btcoexist.btc_info.in_4way = false; if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "not open hw encryption\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } /* To support IBSS, use sw-crypto for GTK */ @@ -1526,10 +1526,10 @@ vif->type == NL80211_IFTYPE_MESH_POINT) && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -ENOSPC; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -1538,28 +1538,28 @@ switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: /* HW don't support CMAC encryption, * use software CMAC encryption */ key_type = AESCMAC_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n"); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "HW don't support CMAC encryption, use software CMAC encryption\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CMAC\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "HW don't support CMAC encryption, use software CMAC encryption\n"); err = -EOPNOTSUPP; goto out_unlock; default: @@ -1605,9 +1605,9 @@ key_type == WEP104_ENCRYPTION)) wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", - key_type); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1615,8 +1615,8 @@ switch (cmd) { case SET_KEY: if (wep_only) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set WEP(group/pairwise) key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1626,8 +1626,8 @@ rtlpriv->sec.key_len[key_idx] = key->keylen; eth_zero_addr(mac_addr); } else if (group_key) { /* group key */ - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set group key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1636,8 +1636,8 @@ rtlpriv->sec.key_len[key_idx] = key->keylen; memcpy(mac_addr, bcast_addr, ETH_ALEN); } else { /* pairwise key */ - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set pairwise key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set pairwise key\n"); if (!sta) { WARN_ONCE(true, "rtlwifi: pairwise key without mac_addr\n"); @@ -1669,8 +1669,8 @@ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; break; case DISABLE_KEY: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "disable key delete one entry\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "disable key delete one entry\n"); /*set local buf about wep key. */ if (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_MESH_POINT) { @@ -1718,9 +1718,9 @@ if (unlikely(radio_state != rtlpriv->rfkill.rfkill_state)) { rtlpriv->rfkill.rfkill_state = radio_state; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "wireless radio switch turned %s\n", - radio_state ? "on" : "off"); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); @@ -1765,26 +1765,27 @@ do { cfg_cmd = pwrcfgcmd[ary_idx]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", - GET_PWR_CFG_OFFSET(cfg_cmd), - GET_PWR_CFG_CUT_MASK(cfg_cmd), - GET_PWR_CFG_FAB_MASK(cfg_cmd), - GET_PWR_CFG_INTF_MASK(cfg_cmd), - GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), - GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: offset(%#x),cut_msk(%#x), famsk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", + __func__, + GET_PWR_CFG_OFFSET(cfg_cmd), + GET_PWR_CFG_CUT_MASK(cfg_cmd), + GET_PWR_CFG_FAB_MASK(cfg_cmd), + GET_PWR_CFG_INTF_MASK(cfg_cmd), + GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), + GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { switch (GET_PWR_CFG_CMD(cfg_cmd)) { case PWR_CMD_READ: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); break; case PWR_CMD_WRITE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "%s(): PWR_CMD_WRITE\n", __func__); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s(): PWR_CMD_WRITE\n", __func__); offset = GET_PWR_CFG_OFFSET(cfg_cmd); /*Read the value from system register*/ @@ -1797,7 +1798,7 @@ rtl_write_byte(rtlpriv, offset, value); break; case PWR_CMD_POLLING: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); polling_bit = false; offset = GET_PWR_CFG_OFFSET(cfg_cmd); @@ -1818,8 +1819,8 @@ } while (!polling_bit); break; case PWR_CMD_DELAY: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_DELAY\n", __func__); if (GET_PWR_CFG_VALUE(cfg_cmd) == PWRSEQ_DELAY_US) udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); @@ -1827,8 +1828,8 @@ mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); break; case PWR_CMD_END: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "%s: PWR_CMD_END\n", __func__); return true; default: WARN_ONCE(true, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -298,8 +298,8 @@ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -307,7 +307,7 @@ num = sscanf(tmp, "%x %x %x", &addr, &val, &len); if (num != 3) - return count; + return -EINVAL; switch (len) { case 1: @@ -349,8 +349,8 @@ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -360,8 +360,8 @@ &h2c_data[4], &h2c_data[5], &h2c_data[6], &h2c_data[7]); - if (h2c_len <= 0) - return count; + if (h2c_len == 0) + return -EINVAL; for (i = 0; i < h2c_len; i++) h2c_data_packed[i] = (u8)h2c_data[i]; @@ -395,8 +395,8 @@ tmp_len = (count > sizeof(tmp) - 1 ? sizeof(tmp) - 1 : count); - if (!buffer || copy_from_user(tmp, buffer, tmp_len)) - return count; + if (copy_from_user(tmp, buffer, tmp_len)) + return -EFAULT; tmp[tmp_len] = '\0'; @@ -404,9 +404,9 @@ &path, &addr, &bitmask, &data); if (num != 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "Format is \n"); - return count; + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "Format is \n"); + return -EINVAL; } rtl_set_rfreg(hw, path, addr, bitmask, data); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/debug.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/debug.h @@ -160,6 +160,10 @@ const char *titlestring, const void *hexdata, int hexdatalen); +#define rtl_dbg(rtlpriv, comp, level, fmt, ...) \ + _rtl_dbg_trace(rtlpriv, comp, level, \ + fmt, ##__VA_ARGS__) + #define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ _rtl_dbg_trace(rtlpriv, comp, level, \ fmt, ##__VA_ARGS__) @@ -177,6 +181,13 @@ struct rtl_priv; __printf(4, 5) +static inline void rtl_dbg(struct rtl_priv *rtlpriv, + u64 comp, int level, + const char *fmt, ...) +{ +} + +__printf(4, 5) static inline void RT_TRACE(struct rtl_priv *rtlpriv, u64 comp, int level, const char *fmt, ...) --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/efuse.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/efuse.c @@ -120,8 +120,8 @@ const u32 efuse_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", - address, value); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); if (address < efuse_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -211,9 +211,9 @@ u8 efuse_usage; if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", - _offset, _size_byte); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: Invalid offset(%#x) with read bytes(%#x)!!\n", + __func__, _offset, _size_byte); return; } @@ -376,9 +376,9 @@ (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) result = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "%s: totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + __func__, totalbytes, hdr_num, words_need, efuse_used); return result; } @@ -416,7 +416,7 @@ u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); if (!efuse_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -424,8 +424,8 @@ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse out of capacity!!\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -464,8 +464,8 @@ if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "PG section(%#x) fail!!\n", offset); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "PG section(%#x) fail!!\n", offset); break; } } @@ -478,7 +478,7 @@ &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, "\n"); return true; } @@ -616,8 +616,8 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpidx = 0; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "Addr = %x Data=%x\n", addr, data); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "Addr = %x Data=%x\n", addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -997,8 +997,8 @@ if (efuse_addr >= (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "efuse_addr(%#x) Out of size!!\n", efuse_addr); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1038,8 +1038,8 @@ u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); + rtl_dbg(rtlpriv, COMP_EFUSE, DBG_LOUD, + "word_en = %x efuse_addr=%x\n", word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; @@ -1242,11 +1242,11 @@ eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != params[0]) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1257,30 +1257,30 @@ rtlefuse->eeprom_did = *(u16 *)&hwinfo[params[2]]; rtlefuse->eeprom_svid = *(u16 *)&hwinfo[params[3]]; rtlefuse->eeprom_smid = *(u16 *)&hwinfo[params[4]]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROMId = 0x%4x\n", eeprom_id); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROMId = 0x%4x\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[params[5] + i]; *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); rtlefuse->eeprom_channelplan = *&hwinfo[params[6]]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[params[7]]; rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *&hwinfo[params[8]]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel plan to world wide 13 */ rtlefuse->channel_plan = params[9]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -164,21 +164,29 @@ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + value &= PCI_EXP_LNKCTL_ASPMC; + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) - value |= 0x40; + value |= PCI_EXP_LNKCTL_CCC; - pci_write_config_byte(rtlpci->pdev, 0x80, value); + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC | value, + value); return false; } -/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ -static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) +/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ +static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - pci_write_config_byte(rtlpci->pdev, 0x81, value); + value &= PCI_EXP_LNKCTL_CLKREQ_EN; + + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN, + value); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) udelay(100); @@ -192,11 +200,8 @@ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; - u8 num4bytes = pcipriv->ndis_adapter.num4bytes; /*Retrieve original configuration settings. */ u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; - u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. - pcibridge_linkctrlreg; u16 aspmlevel = 0; u8 tmp_u1b = 0; @@ -204,8 +209,8 @@ return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "PCI(Bridge) UNKNOWN\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); return; } @@ -221,16 +226,8 @@ /*Set corresponding value. */ aspmlevel |= BIT(0) | BIT(1); linkctrl_reg &= ~aspmlevel; - pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); - udelay(50); - - /*4 Disable Pci Bridge ASPM */ - pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), - pcibridge_linkctrlreg); - - udelay(50); } /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for @@ -245,39 +242,18 @@ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; - u8 num4bytes = pcipriv->ndis_adapter.num4bytes; u16 aspmlevel; - u8 u_pcibridge_aspmsetting; u8 u_device_aspmsetting; if (!ppsc->support_aspm) return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "PCI(Bridge) UNKNOWN\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "PCI(Bridge) UNKNOWN\n"); return; } - /*4 Enable Pci Bridge ASPM */ - - u_pcibridge_aspmsetting = - pcipriv->ndis_adapter.pcibridge_linkctrlreg | - rtlpci->const_hostpci_aspm_setting; - - if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) - u_pcibridge_aspmsetting &= ~BIT(0); - - pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), - u_pcibridge_aspmsetting); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "PlatformEnableASPM(): Write reg[%x] = %x\n", - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting); - - udelay(50); - /*Get ASPM level (with/without Clock Req) */ aspmlevel = rtlpci->const_devicepci_aspm_setting; u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; @@ -291,7 +267,8 @@ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & - RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_RF_OFF_LEVL_CLK_REQ) ? + PCI_EXP_LNKCTL_CLKREQ_EN : 0); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); } udelay(100); @@ -318,63 +295,6 @@ return status; } -static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, - struct rtl_priv **buddy_priv) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - bool find_buddy_priv = false; - struct rtl_priv *tpriv; - struct rtl_pci_priv *tpcipriv = NULL; - - if (!list_empty(&rtlpriv->glb_var->glb_priv_list)) { - list_for_each_entry(tpriv, &rtlpriv->glb_var->glb_priv_list, - list) { - tpcipriv = (struct rtl_pci_priv *)tpriv->priv; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "pcipriv->ndis_adapter.funcnumber %x\n", - pcipriv->ndis_adapter.funcnumber); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "tpcipriv->ndis_adapter.funcnumber %x\n", - tpcipriv->ndis_adapter.funcnumber); - - if (pcipriv->ndis_adapter.busnumber == - tpcipriv->ndis_adapter.busnumber && - pcipriv->ndis_adapter.devnumber == - tpcipriv->ndis_adapter.devnumber && - pcipriv->ndis_adapter.funcnumber != - tpcipriv->ndis_adapter.funcnumber) { - find_buddy_priv = true; - break; - } - } - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "find_buddy_priv %d\n", find_buddy_priv); - - if (find_buddy_priv) - *buddy_priv = tpriv; - - return find_buddy_priv; -} - -static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); - u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; - u8 linkctrl_reg; - u8 num4bbytes; - - num4bbytes = (capabilityoffset + 0x10) / 4; - - /*Read Link Control Register */ - pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg); - - pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; -} - static void rtl_pci_parse_configuration(struct pci_dev *pdev, struct ieee80211_hw *hw) { @@ -388,8 +308,8 @@ pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -483,11 +403,6 @@ if (!rtlpriv->rtlhal.earlymode_enable) return; - if (rtlpriv->dm.supp_phymode_switch && - (rtlpriv->easy_concurrent_ctl.switch_in_process || - (rtlpriv->buddy_priv && - rtlpriv->buddy_priv->easy_concurrent_ctl.switch_in_process))) - return; /* we just use em for BE/BK/VI/VO */ for (tid = 7; tid >= 0; tid--) { u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; @@ -557,11 +472,11 @@ if (rtlpriv->rtlhal.earlymode_enable) skb_pull(skb, EM_HDR_LEN); - RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, - "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *)(skb->data + 22)); + rtl_dbg(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *)(skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -608,10 +523,10 @@ } if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", - prio, ring->idx, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping(skb)); } @@ -801,9 +716,9 @@ skb_reserve(skb, stats.rx_drvinfo_size + stats.rx_bufshift); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "skb->end - skb->tail = %d, len is %d\n", - skb->end - skb->tail, len); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "skb->end - skb->tail = %d, len is %d\n", + skb->end - skb->tail, len); dev_kfree_skb_any(skb); goto new_trx_end; } @@ -925,67 +840,67 @@ /*<1> beacon related */ if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "beacon ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon ok interrupt!\n"); if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "beacon err interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "beacon err interrupt!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BCNINT]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "prepare beacon for interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<2> Tx related */ if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "Manage ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "HIGH_QUEUE ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "BK Tx OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "BE TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "VI TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "Vo TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -993,8 +908,8 @@ if (intvec.intd & rtlpriv->cfg->maps[RTL_IMR_H2CDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "H2C TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "H2C TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, H2C_QUEUE); } } @@ -1003,34 +918,34 @@ if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "CMD TX OK interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<3> Rx related */ if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "rx descriptor unavailable!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(intvec.intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } /*<4> fw related*/ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { if (intvec.inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "firmware interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "firmware interrupt!\n"); queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.fwevt_wq, 0); } @@ -1046,8 +961,8 @@ rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) { if (unlikely(intvec.inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - "hsisr interrupt!\n"); + rtl_dbg(rtlpriv, COMP_INTR, DBG_TRACE, + "hsisr interrupt!\n"); _rtl_pci_hs_interrupt(hw); } } @@ -1061,13 +976,15 @@ return ret; } -static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) +static void _rtl_pci_irq_tasklet(unsigned long data) { + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; _rtl_pci_tx_chk_waitq(hw); } -static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) +static void _rtl_pci_prepare_bcn_tasklet(unsigned long data) { + struct ieee80211_hw *hw = (struct ieee80211_hw *)data; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); @@ -1193,10 +1110,10 @@ /*task */ tasklet_init(&rtlpriv->works.irq_tasklet, - (void (*)(unsigned long))_rtl_pci_irq_tasklet, + _rtl_pci_irq_tasklet, (unsigned long)hw); tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, - (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, + _rtl_pci_prepare_bcn_tasklet, (unsigned long)hw); INIT_WORK(&rtlpriv->works.lps_change_work, rtl_lps_change_work_callback); @@ -1249,8 +1166,8 @@ rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", - prio, desc); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, desc); /* init every desc in this ring */ if (!rtlpriv->use_new_trx_flow) { @@ -1647,10 +1564,10 @@ true, HW_DESC_OWN); if (own == 1 && hw_queue != BEACON_QUEUE) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); @@ -1660,8 +1577,8 @@ if (rtlpriv->cfg->ops->get_available_desc && rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "get_available_desc fail\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "get_available_desc fail\n"); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); return skb->len; } @@ -1684,8 +1601,8 @@ if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && hw_queue != BEACON_QUEUE) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", hw_queue, ring->idx, idx, skb_queue_len(&ring->queue)); @@ -1792,8 +1709,8 @@ err = rtlpriv->cfg->ops->hw_init(hw); if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Failed to config hardware!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Failed to config hardware!\n"); kfree(rtlpriv->btcoexist.btc_context); kfree(rtlpriv->btcoexist.wifi_only_context); return err; @@ -1802,7 +1719,7 @@ &rtlmac->retry_long); rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl_init_rx_config(hw); @@ -1813,7 +1730,7 @@ rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%s OK\n", __func__); return 0; } @@ -1907,71 +1824,71 @@ deviceid == RTL_PCI_8171_DID) { switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192 PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; return false; case RTL_PCI_REVISION_ID_8192SE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192SE is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Err: Unknown device - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; } } else if (deviceid == RTL_PCI_8723AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8723AE PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8723AE PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192C PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8192D PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8188EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8188EE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8188EE\n"); } else if (deviceid == RTL_PCI_8723BE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8723BE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8723BE\n"); } else if (deviceid == RTL_PCI_8192EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8192EE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8192EE\n"); } else if (deviceid == RTL_PCI_8821AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8821AE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8821AE\n"); } else if (deviceid == RTL_PCI_8812AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8812AE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8812AE\n"); } else if (deviceid == RTL_PCI_8822BE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8822BE; rtlhal->bandset = BAND_ON_BOTH; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find adapter, Hardware type is 8822BE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8822BE\n"); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Err: Unknown device - vid/did=%x/%x\n", + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Err: Unknown device - vid/did=%x/%x\n", venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; @@ -1980,17 +1897,17 @@ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find 92DE MAC0\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Find 92DE MAC1\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } @@ -2024,9 +1941,9 @@ for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Pci Bridge Vendor is found index: %d\n", - tmp); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -2040,12 +1957,6 @@ PCI_SLOT(bridge_pdev->devfn); pcipriv->ndis_adapter.pcibridge_funcnum = PCI_FUNC(bridge_pdev->devfn); - pcipriv->ndis_adapter.pcibridge_pciehdr_offset = - pci_pcie_cap(bridge_pdev); - pcipriv->ndis_adapter.num4bytes = - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; - - rtl_pci_get_linkcontrol_field(hw); if (pcipriv->ndis_adapter.pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD) { @@ -2054,25 +1965,22 @@ } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); + + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); - list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list); return true; } @@ -2097,8 +2005,8 @@ rtlpci->using_msi = true; - RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, - "MSI Interrupt Mode!\n"); + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "MSI Interrupt Mode!\n"); return 0; } @@ -2115,8 +2023,8 @@ return ret; rtlpci->using_msi = false; - RT_TRACE(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, - "Pin-based Interrupt Mode!\n"); + rtl_dbg(rtlpriv, COMP_INIT | COMP_INTR, DBG_DMESG, + "Pin-based Interrupt Mode!\n"); return 0; } @@ -2219,7 +2127,6 @@ rtlpriv->rtlhal.interface = INTF_PCI; rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data); rtlpriv->intf_ops = &rtl_pci_ops; - rtlpriv->glb_var = &rtl_global_var; rtl_efuse_ops_init(hw); /* MEM map */ @@ -2243,10 +2150,10 @@ goto fail2; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -2270,7 +2177,7 @@ if (rtlpriv->cfg->ops->init_sw_vars(hw)) { pr_err("Can't init_sw_vars\n"); err = -ENODEV; - goto fail3; + goto fail2; } rtlpriv->cfg->ops->init_sw_leds(hw); @@ -2288,14 +2195,14 @@ err = rtl_pci_init(hw, pdev); if (err) { pr_err("Failed to init PCI\n"); - goto fail3; + goto fail4; } err = ieee80211_register_hw(hw); if (err) { pr_err("Can't register mac80211 hw.\n"); err = -ENODEV; - goto fail3; + goto fail5; } rtlpriv->mac80211.mac80211_registered = 1; @@ -2308,9 +2215,9 @@ rtlpci = rtl_pcidev(pcipriv); err = rtl_pci_intr_mode_decide(hw); if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy)); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; } rtlpci->irq_alloc = 1; @@ -2318,16 +2225,19 @@ set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; -fail3: - pci_set_drvdata(pdev, NULL); +fail5: + rtl_pci_deinit(hw); +fail4: rtl_deinit_core(hw); +fail3: + wait_for_completion(&rtlpriv->firmware_loading_complete); + rtlpriv->cfg->ops->deinit_sw_vars(hw); fail2: if (rtlpriv->io.pci_mem_start != 0) pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); pci_release_regions(pdev); - complete(&rtlpriv->firmware_loading_complete); fail1: if (hw) @@ -2378,7 +2288,6 @@ if (rtlpci->using_msi) pci_disable_msi(rtlpci->pdev); - list_del(&rtlpriv->list); if (rtlpriv->io.pci_mem_start != 0) { pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); pci_release_regions(pdev); @@ -2438,7 +2347,6 @@ .read_efuse_byte = read_efuse_byte, .adapter_start = rtl_pci_start, .adapter_stop = rtl_pci_stop, - .check_buddy_priv = rtl_pci_check_buddy_priv, .adapter_tx = rtl_pci_tx, .flush = rtl_pci_flush, .reset_trx_ring = rtl_pci_reset_trx_ring, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/pci.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/pci.h @@ -236,11 +236,6 @@ u16 pcibridge_vendorid; u16 pcibridge_deviceid; - u8 num4bytes; - - u8 pcibridge_pciehdr_offset; - u8 pcibridge_linkctrlreg; - bool amd_l1_patch; }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/ps.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/ps.c @@ -19,8 +19,8 @@ rtlpriv->intf_ops->reset_trx_ring(hw); if (is_hal_stop(rtlhal)) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Driver is already down!\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Driver is already down!\n"); /*<2> Enable Adapter */ if (rtlpriv->cfg->ops->hw_init(hw)) @@ -81,9 +81,9 @@ if (ppsc->rfchange_inprogress) { spin_unlock(&rtlpriv->locks.rf_ps_lock); - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "RF Change in progress! Wait to set..state_toset(%d).\n", - state_toset); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "RF Change in progress! Wait to set..state_toset(%d).\n", + state_toset); /* Set RF after the previous action is done. */ while (ppsc->rfchange_inprogress) { @@ -195,8 +195,8 @@ enum rf_pwrstate rtstate; if (mac->opmode != NL80211_IFTYPE_STATION) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "not station return\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "not station return\n"); return; } @@ -232,8 +232,8 @@ !ppsc->swrf_processing && (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "IPSEnter(): Turn off RF\n"); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->in_powersavemode = true; @@ -311,8 +311,8 @@ ppsc->last_delaylps_stamp_jiffies); if (ps_timediff < 2000) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -357,9 +357,9 @@ if ((ppsc->fwctrl_lps) && ppsc->report_linked) { if (ppsc->dot11_psmode == EACTIVE) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); enter_fwlps = false; ppsc->pwr_mode = FW_PS_ACTIVE_MODE; ppsc->smart_ps = 0; @@ -372,9 +372,9 @@ rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); } else { if (rtl_get_fwlps_doze(hw)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); if (rtlpriv->cfg->ops->get_btc_status()) rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); enter_fwlps = true; @@ -424,8 +424,8 @@ * bt_ccoexist may ask to enter lps. * In normal case, this constraint move to rtl_lps_set_psmode(). */ - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Enter 802.11 power save mode...\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); mutex_unlock(&rtlpriv->locks.lps_mutex); @@ -453,8 +453,8 @@ RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); } - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Busy Traffic,Leave 802.11 power save..\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -538,8 +538,8 @@ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } } EXPORT_SYMBOL_GPL(rtl_swlps_beacon); @@ -634,9 +634,9 @@ /* this print should always be dtim_conter = 0 & * sleep = dtim_period, that meaons, we should * awake before every dtim */ - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "dtim_counter:%x will sleep :%d beacon_intv\n", - rtlpriv->psc.dtim_counter, sleep_intv); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, @@ -748,9 +748,9 @@ if (ie[0] == 12) { find_p2p_ps_ie = true; if ((noa_len - 2) % 13 != 0) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "P2P notice of absence: invalid length.%d\n", - noa_len); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -761,8 +761,8 @@ noa_index = ie[3]; if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == P2P_PS_NONE || noa_index != p2pinfo->noa_index) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "update NOA ie.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "update NOA ie.\n"); p2pinfo->noa_index = noa_index; p2pinfo->opp_ps = (ie[4] >> 7); p2pinfo->ctwindow = ie[4] & 0x7F; @@ -833,7 +833,7 @@ if (ie == NULL) return; - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); /*to find noa ie*/ while (ie + 1 < end) { noa_len = READEF2BYTE((__le16 *)&ie[1]); @@ -841,13 +841,13 @@ return; if (ie[0] == 12) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "find NOA IE.\n"); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", ie, noa_len); if ((noa_len - 2) % 13 != 0) { - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "P2P notice of absence: invalid length.%d\n", - noa_len); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "P2P notice of absence: invalid length.%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -905,7 +905,7 @@ struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n" , p2p_ps_state); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, " p2p state %x\n", p2p_ps_state); switch (p2p_ps_state) { case P2P_PS_DISABLE: p2pinfo->p2p_ps_state = p2p_ps_state; @@ -957,18 +957,18 @@ default: break; } - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "ctwindow %x oppps %x\n", - p2pinfo->ctwindow , p2pinfo->opp_ps); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, - "count %x duration %x index %x interval %x start time %x noa num %x\n", - p2pinfo->noa_count_type[0], - p2pinfo->noa_duration[0], - p2pinfo->noa_index, - p2pinfo->noa_interval[0], - p2pinfo->noa_start_time[0], - p2pinfo->noa_num); - RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "ctwindow %x oppps %x\n", + p2pinfo->ctwindow, p2pinfo->opp_ps); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, + "count %x duration %x index %x interval %x start time %x noa num %x\n", + p2pinfo->noa_count_type[0], + p2pinfo->noa_duration[0], + p2pinfo->noa_index, + p2pinfo->noa_interval[0], + p2pinfo->noa_start_time[0], + p2pinfo->noa_num); + rtl_dbg(rtlpriv, COMP_FW, DBG_LOUD, "end\n"); } void rtl_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rc.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rc.c @@ -261,7 +261,7 @@ { } -static void *rtl_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +static void *rtl_rate_alloc(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); return rtlpriv; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/regd.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/regd.c @@ -386,20 +386,20 @@ struct wiphy *wiphy = hw->wiphy; struct country_code_to_enum_rd *country = NULL; - if (wiphy == NULL || &rtlpriv->regd == NULL) + if (!wiphy) return -EINVAL; /* init country_code from efuse channel plan */ rtlpriv->regd.country_code = channel_plan_to_country_code(rtlpriv->efuse.channel_plan); - RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - "rtl: EEPROM regdomain: 0x%0x country code: %d\n", - rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM regdomain: 0x%0x country code: %d\n", + rtlpriv->efuse.channel_plan, rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { - RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); + rtl_dbg(rtlpriv, COMP_REGD, DBG_DMESG, + "rtl: EEPROM indicates invalid country code, world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -414,9 +414,9 @@ rtlpriv->regd.alpha2[1] = '0'; } - RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); + rtl_dbg(rtlpriv, COMP_REGD, DBG_TRACE, + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -428,7 +428,7 @@ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); + rtl_dbg(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c @@ -805,7 +805,7 @@ } if (rtlpriv->btcoexist.bt_edca_dl != 0) { - edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; bt_change_edca = true; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c @@ -16,7 +16,6 @@ static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); -static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask); static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, @@ -46,7 +45,7 @@ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -69,7 +68,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -95,7 +94,7 @@ original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); @@ -124,7 +123,7 @@ original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -210,17 +209,6 @@ rfpath, pphyreg->rf3wire_offset, data_and_addr); } -static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - bool rtl88e_phy_mac_config(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h @@ -561,6 +561,7 @@ rxmcs == DESC92C_RATE11M) struct phy_status_rpt { + u8 padding[2]; u8 ch_corr[2]; u8 cck_sig_qual_ofdm_pwdb_all; u8 cck_agc_rpt_ofdm_cfosho_a; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192c/dm_common.c @@ -640,7 +640,7 @@ } if (rtlpriv->btcoexist.bt_edca_dl != 0) { - edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; bt_change_edca = true; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c @@ -17,7 +17,7 @@ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -40,7 +40,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -143,18 +143,6 @@ } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} -EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); - static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) { rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h @@ -196,7 +196,6 @@ void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, enum wireless_mode wirelessmode, u8 txpwridx); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c @@ -39,7 +39,7 @@ rfpath, regaddr); } - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -110,7 +110,7 @@ original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -122,7 +122,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h @@ -94,7 +94,6 @@ u32 offset); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/hw.c @@ -618,8 +618,8 @@ u8 queue_sel) { u16 beq, bkq, viq, voq, mgtq, hiq; - u16 uninitialized_var(valuehi); - u16 uninitialized_var(valuelow); + u16 valuehi; + u16 valuelow; switch (queue_sel) { case (TX_SELE_HQ | TX_SELE_LQ): @@ -1000,6 +1000,7 @@ _initpabias(hw); rtl92c_dm_init(hw); exit: + local_irq_disable(); local_irq_restore(flags); return err; } @@ -1540,6 +1541,8 @@ * This is maybe necessary: * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb); */ + dev_kfree_skb(skb); + return true; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c @@ -32,7 +32,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); } - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", @@ -56,7 +56,7 @@ original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -67,7 +67,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c @@ -1176,6 +1176,7 @@ rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); + rtlpci->irq_enabled = true; } void rtl92de_disable_interrupt(struct ieee80211_hw *hw) @@ -1185,7 +1186,7 @@ rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); - synchronize_irq(rtlpci->pdev->irq); + rtlpci->irq_enabled = false; } static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) @@ -1351,7 +1352,7 @@ bcn_interval = mac->beacon_interval; atim_window = 2; - /*rtl92de_disable_interrupt(hw); */ + rtl92de_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); @@ -1371,9 +1372,9 @@ RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", bcn_interval); - /* rtl92de_disable_interrupt(hw); */ + rtl92de_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - /* rtl92de_enable_interrupt(hw); */ + rtl92de_enable_interrupt(hw); } void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c @@ -160,17 +160,14 @@ 25711, 25658, 25606, 25554, 25502, 25451, 25328 }; -static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - - return i; -} +static const u8 channel_all[59] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, + 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, + 114, 116, 118, 120, 122, 124, 126, 128, 130, + 132, 134, 136, 138, 140, 149, 151, 153, 155, + 157, 159, 161, 163, 165 +}; u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { @@ -194,7 +191,7 @@ } else { originalvalue = rtl_read_dword(rtlpriv, regaddr); } - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", @@ -226,7 +223,7 @@ dbi_direct); else originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) @@ -314,7 +311,7 @@ regaddr, rfpath, bitmask); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -341,7 +338,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } @@ -1361,14 +1358,6 @@ u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) { - u8 channel_all[59] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, - 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, - 114, 116, 118, 120, 122, 124, 126, 128, 130, - 132, 134, 136, 138, 140, 149, 151, 153, 155, - 157, 159, 161, 163, 165 - }; u8 place = chnl; if (chnl > 14) { @@ -2392,14 +2381,10 @@ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Just Read IQK Matrix reg for channel:%d....\n", channel); - if ((rtlphy->iqk_matrix[indexforchannel]. - value[0] != NULL) - /*&&(regea4 != 0) */) + if (rtlphy->iqk_matrix[indexforchannel].value[0][0] != 0) _rtl92d_phy_patha_fill_iqk_matrix(hw, true, - rtlphy->iqk_matrix[ - indexforchannel].value, 0, - (rtlphy->iqk_matrix[ - indexforchannel].value[0][2] == 0)); + rtlphy->iqk_matrix[indexforchannel].value, 0, + rtlphy->iqk_matrix[indexforchannel].value[0][2] == 0); if (IS_92D_SINGLEPHY(rtlhal->version)) { if ((rtlphy->iqk_matrix[ indexforchannel].value[0][4] != 0) @@ -3227,37 +3212,28 @@ u8 rtl92d_get_chnlgroup_fromarray(u8 chnl) { u8 group; - u8 channel_info[59] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, - 58, 60, 62, 64, 100, 102, 104, 106, 108, - 110, 112, 114, 116, 118, 120, 122, 124, - 126, 128, 130, 132, 134, 136, 138, 140, - 149, 151, 153, 155, 157, 159, 161, 163, - 165 - }; - if (channel_info[chnl] <= 3) + if (channel_all[chnl] <= 3) group = 0; - else if (channel_info[chnl] <= 9) + else if (channel_all[chnl] <= 9) group = 1; - else if (channel_info[chnl] <= 14) + else if (channel_all[chnl] <= 14) group = 2; - else if (channel_info[chnl] <= 44) + else if (channel_all[chnl] <= 44) group = 3; - else if (channel_info[chnl] <= 54) + else if (channel_all[chnl] <= 54) group = 4; - else if (channel_info[chnl] <= 64) + else if (channel_all[chnl] <= 64) group = 5; - else if (channel_info[chnl] <= 112) + else if (channel_all[chnl] <= 112) group = 6; - else if (channel_info[chnl] <= 126) + else if (channel_all[chnl] <= 126) group = 7; - else if (channel_info[chnl] <= 140) + else if (channel_all[chnl] <= 140) group = 8; - else if (channel_info[chnl] <= 153) + else if (channel_all[chnl] <= 153) group = 9; - else if (channel_info[chnl] <= 159) + else if (channel_all[chnl] <= 159) group = 10; else group = 11; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c @@ -216,6 +216,7 @@ .led_control = rtl92de_led_control, .set_desc = rtl92de_set_desc, .get_desc = rtl92de_get_desc, + .is_tx_desc_closed = rtl92de_is_tx_desc_closed, .tx_polling = rtl92de_tx_polling, .enable_hw_sec = rtl92de_enable_hw_security_config, .set_key = rtl92de_set_key, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.c @@ -804,13 +804,15 @@ break; } } else { - struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; switch (desc_name) { case HW_DESC_OWN: - ret = GET_RX_DESC_OWN(pdesc); + ret = GET_RX_DESC_OWN(p_desc); break; case HW_DESC_RXPKT_LEN: - ret = GET_RX_DESC_PKT_LEN(pdesc); + ret = GET_RX_DESC_PKT_LEN(p_desc); + break; + case HW_DESC_RXBUFF_ADDR: + ret = GET_RX_DESC_BUFF_ADDR(p_desc); break; default: WARN_ONCE(true, "rtl8192de: ERR rxdesc :%d not processed\n", @@ -821,6 +823,23 @@ return ret; } +bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index) +{ + struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; + u8 *entry = (u8 *)(&ring->desc[ring->idx]); + u8 own = (u8)rtl92de_get_desc(hw, entry, true, HW_DESC_OWN); + + /* a beacon packet will only use the first + * descriptor by defaut, and the own bit may not + * be cleared by the hardware + */ + if (own) + return false; + return true; +} + void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) { struct rtl_priv *rtlpriv = rtl_priv(hw); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/trx.h @@ -715,6 +715,8 @@ u8 desc_name, u8 *val); u64 rtl92de_get_desc(struct ieee80211_hw *hw, u8 *p_desc, bool istx, u8 desc_name); +bool rtl92de_is_tx_desc_closed(struct ieee80211_hw *hw, + u8 hw_queue, u16 index); void rtl92de_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool b_firstseg, bool b_lastseg, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c @@ -16,7 +16,6 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); -static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask); static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, @@ -46,7 +45,7 @@ RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, @@ -68,7 +67,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -93,7 +92,7 @@ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); @@ -121,7 +120,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = (original_value & (~bitmask)) | (data << bitshift); } @@ -204,17 +203,6 @@ pphyreg->rf3wire_offset, data_and_addr); } -static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) { return _rtl92ee_phy_config_mac_with_headerfile(hw); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/dm.c @@ -144,10 +144,10 @@ thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", - thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); if (thermalvalue) { rtlpriv->dm.thermalvalue = thermalvalue; @@ -158,8 +158,8 @@ (rtlpriv->efuse.thermalmeter[0] << 8) | (thermalvalue << 16)); - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "Write to FW Thermal Val = 0x%x\n", fw_cmd); + rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Write to FW Thermal Val = 0x%x\n", fw_cmd); rtl_write_dword(rtlpriv, WFM5, fw_cmd); rtl92s_phy_chk_fwcmd_iodone(hw); @@ -264,10 +264,10 @@ } if (ra->pre_ratr_state != ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, - ra->pre_ratr_state, ra->ratr_state); + rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", + rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, + ra->pre_ratr_state, ra->ratr_state); rcu_read_lock(); sta = rtl_find_sta(hw, mac->bssid); @@ -576,8 +576,8 @@ if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "Not connected to any\n"); + rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; @@ -588,21 +588,21 @@ if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Client PWDB = 0x%lx\n", + undec_sm_pwdb); } else { undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "STA Default Port PWDB = 0x%lx\n", + undec_sm_pwdb); } } else { undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "AP Ext Port PWDB = 0x%lx\n", + undec_sm_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c @@ -39,8 +39,8 @@ do { cpustatus = rtl_read_byte(rtlpriv, TCR); if (cpustatus & IMEM_RDY) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "IMEM Ready after CPU has refilled\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "IMEM Ready after CPU has refilled\n"); break; } @@ -195,8 +195,8 @@ short pollingcnt = 1000; bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "LoadStaus(%d)\n", loadfw_status); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "LoadStaus(%d)\n", loadfw_status); firmware->fwstatus = (enum fw_status)loadfw_status; @@ -256,9 +256,9 @@ goto status_check_fail; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "DMEM code download success, cpustatus(%#x)\n", - cpustatus); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "DMEM code download success, cpustatus(%#x)\n", + cpustatus); /* Prevent Delay too much and being scheduled out */ /* Polling Load Firmware ready */ @@ -270,9 +270,9 @@ udelay(40); } while (pollingcnt--); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Polling Load Firmware ready, cpustatus(%x)\n", - cpustatus); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Polling Load Firmware ready, cpustatus(%x)\n", + cpustatus); if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || (pollingcnt <= 0)) { @@ -290,8 +290,8 @@ rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS | RCR_APP_ICV | RCR_APP_MIC)); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Current RCR settings(%#x)\n", tmpu4b); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Current RCR settings(%#x)\n", tmpu4b); /* Set to normal mode. */ rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); @@ -304,9 +304,9 @@ } status_check_fail: - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "loadfw_status(%d), rtstatus(%x)\n", - loadfw_status, rtstatus); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "loadfw_status(%d), rtstatus(%x)\n", + loadfw_status, rtstatus); return rtstatus; } @@ -337,11 +337,11 @@ firmware->firmwareversion = byte(pfwheader->version, 0); firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", - pfwheader->signature, - pfwheader->version, pfwheader->dmem_size, - pfwheader->img_imem_size, pfwheader->img_sram_size); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", + pfwheader->signature, + pfwheader->version, pfwheader->dmem_size, + pfwheader->img_imem_size, pfwheader->img_sram_size); /* 2. Retrieve IMEM image. */ if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c @@ -111,8 +111,8 @@ case HW_VAR_SLOT_TIME:{ u8 e_aci; - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "HW_VAR_SLOT_TIME %x\n", val[0]); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); @@ -156,9 +156,9 @@ *val = min_spacing_to_set; - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -172,9 +172,9 @@ mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -215,9 +215,9 @@ (factorlevel[17] << 4)); rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset); + rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -253,9 +253,9 @@ acm_ctrl |= ACMHW_VOQEN; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", - acm); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -276,8 +276,8 @@ } } - RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); + rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, + "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); rtl_write_byte(rtlpriv, ACMHWCTRL, acm_ctrl); break; } @@ -417,14 +417,14 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); u8 sec_reg_value = 0x0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "not open hw encryption\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); return; } @@ -435,8 +435,8 @@ sec_reg_value |= SCR_RXUSEDK; } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", - sec_reg_value); + rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -870,10 +870,10 @@ /* Change Program timing */ rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); } @@ -960,9 +960,8 @@ /* 2. download firmware */ rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Failed to download FW. Init HW without FW now... " - "Please copy FW into /lib/firmware/rtlwifi\n"); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); err = 1; goto exit; } @@ -1014,7 +1013,7 @@ rtl_write_byte(rtlpriv, RF_CTRL, 0x07); if (!rtl92s_phy_rf_config(hw)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); err = rtstatus; goto exit; } @@ -1147,23 +1146,23 @@ switch (type) { case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to NO LINK!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to Ad Hoc!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to STA!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to AP!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, + "Set Network type to AP!\n"); break; default: pr_err("Network type %d not supported!\n", type); @@ -1606,8 +1605,8 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", - add_msr, rm_msr); + rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1671,11 +1670,11 @@ eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "EEPROM ID(%#x) is invalid!!\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1692,16 +1691,16 @@ rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROMId = 0x%4x\n", eeprom_id); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROMId = 0x%4x\n", eeprom_id); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1711,7 +1710,7 @@ for (i = 0; i < 6; i++) rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); /* Get Tx Power Level by Channel */ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ @@ -1964,15 +1963,15 @@ tempval = rtl_read_byte(rtlpriv, 0x07); if (!(tempval & BIT(0))) { rtlefuse->b1x1_recvcombine = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "RF_TYPE=1T2R but only 1SS\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "RF_TYPE=1T2R but only 1SS\n"); } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", - rtlefuse->eeprom_oemid); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1987,15 +1986,15 @@ tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92se_read_adapter_info(hw); } else { @@ -2101,8 +2100,8 @@ else rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", - rtl_read_dword(rtlpriv, ARFR0)); + rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, ARFR0)); } static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2256,8 +2255,8 @@ mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); - RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", - mask, ratr_bitmap); + rtl_dbg(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", + mask, ratr_bitmap); rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); @@ -2332,15 +2331,15 @@ rfpwr_toset = _rtl92se_rf_onoff_detect(hw); if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "RFKILL-HW Radio ON, RF ON\n"); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "RFKILL-HW Radio ON, RF ON\n"); rfpwr_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; } else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, - DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); + rtl_dbg(rtlpriv, COMP_RF, + DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); rfpwr_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2404,7 +2403,7 @@ u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2463,26 +2462,26 @@ } if (rtlpriv->sec.key_len[key_index] == 0) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "delete one entry, entry_id is %d\n", - entry_id); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "add one entry\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "add one entry\n"); if (is_pairwise) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set Pairwise key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, rtlpriv->sec.key_buf[key_index]); } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set group key\n"); + rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/led.c @@ -27,8 +27,8 @@ u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", - LEDCFG, pled->ledpin); + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -57,8 +57,8 @@ rtlpriv = rtl_priv(hw); if (!rtlpriv || rtlpriv->max_fw_size) return; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", - LEDCFG, pled->ledpin); + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -119,7 +119,7 @@ ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); + rtl_dbg(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92se_sw_led_control(hw, ledaction); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c @@ -14,32 +14,20 @@ #include "hw.h" #include "table.h" -static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - - return i; -} - u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue = 0, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", - regaddr, bitmask); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", - bitmask, regaddr, originalvalue); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -51,21 +39,21 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } @@ -123,8 +111,8 @@ retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, BLSSI_READBACK_DATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf_rb, retvalue); return retvalue; @@ -146,8 +134,8 @@ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } @@ -157,22 +145,22 @@ struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -187,16 +175,16 @@ if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) return; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } @@ -204,9 +192,9 @@ spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); + rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } @@ -239,9 +227,9 @@ struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz"); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (rtlphy->set_bwmode_inprogress) return; @@ -296,7 +284,7 @@ rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, @@ -434,8 +422,8 @@ u32 delay; bool ret; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", - rtlphy->current_channel); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); if (rtlphy->sw_chnl_inprogress) return 0; @@ -471,7 +459,7 @@ rtlphy->sw_chnl_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); + rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); return 1; } @@ -530,20 +518,19 @@ u32 initializecount = 0; do { initializecount++; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic enable\n"); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while (!rtstatus && (initializecount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "awake, sleeped:%d ms state_inap:%x\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies), - rtlpriv->psc.state_inap); + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "awake, slept:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; rtl_write_word(rtlpriv, CMDR, 0x37FC); rtl_write_byte(rtlpriv, TXPAUSE, 0x00); @@ -560,8 +547,8 @@ } case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic disable\n"); + rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -586,34 +573,34 @@ queue_id++; continue; } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", - i + 1, queue_id, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue)); + rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies)); - - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - "sleep awaked:%d ms state_inap:%x\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); + + rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92se_phy_set_rf_sleep(hw); @@ -968,7 +955,7 @@ radio_b_tblen = RADIOB_ARRAYLENGTH; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); rtstatus = true; switch (rfpath) { @@ -1088,20 +1075,20 @@ ROFDM0_XCAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3]); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); /* read framesync */ rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync); + rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } @@ -1163,10 +1150,10 @@ _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0], &ofdmpowerlevel[0]); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", - channel, cckpowerlevel[0], cckpowerlevel[1], - ofdmpowerlevel[0], ofdmpowerlevel[1]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + channel, cckpowerlevel[0], cckpowerlevel[1], + ofdmpowerlevel[0], ofdmpowerlevel[1]); _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], &ofdmpowerlevel[0]); @@ -1224,17 +1211,17 @@ skip: switch (rtlhal->current_fwcmd_io) { case FW_CMD_RA_RESET: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_ACTIVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_N: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); input = FW_RA_REFRESH; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); @@ -1242,29 +1229,29 @@ rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_BG: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - "FW_CMD_RA_REFRESH_BG\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_BG\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); rtl92s_phy_chk_fwcmd_iodone(hw); rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_N_COMB: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - "FW_CMD_RA_REFRESH_N_COMB\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_N_COMB\n"); input = FW_RA_IOT_N_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_BG_COMB: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - "FW_CMD_RA_REFRESH_BG_COMB\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, + "FW_CMD_RA_REFRESH_BG_COMB\n"); input = FW_RA_IOT_BG_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_IQK_ENABLE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1299,7 +1286,7 @@ rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); break; case FW_CMD_LPS_ENTER: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); current_aid = rtlpriv->mac80211.assoc_id; rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | ((current_aid | 0xc000) << 8))); @@ -1308,18 +1295,18 @@ * turbo mode until driver leave LPS */ break; case FW_CMD_LPS_LEAVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_ADD_A2_ENTRY: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_CTRL_DM_BY_DRIVER: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "FW_CMD_CTRL_DM_BY_DRIVER\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "FW_CMD_CTRL_DM_BY_DRIVER\n"); rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1344,9 +1331,9 @@ u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); bool postprocessing = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", - fw_cmdio, rtlhal->set_fwcmd_inprogress); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", + fw_cmdio, rtlhal->set_fwcmd_inprogress); do { /* We re-map to combined FW CMD ones if firmware version */ @@ -1383,30 +1370,30 @@ * DM map table in the future. */ switch (fw_cmdio) { case FW_CMD_RA_INIT: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); fw_cmdmap |= FW_RA_INIT_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); /* Clear control flag to sync with FW. */ FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL); break; case FW_CMD_DIG_DISABLE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Set DIG disable!!\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG disable!!\n"); fw_cmdmap &= ~FW_DIG_ENABLE_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; case FW_CMD_DIG_ENABLE: case FW_CMD_DIG_RESUME: if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Set DIG enable or resume!!\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG enable or resume!!\n"); fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); } break; case FW_CMD_DIG_HALT: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Set DIG halt!!\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set DIG halt!!\n"); fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1421,9 +1408,9 @@ fw_param |= ((thermalval << 24) | (rtlefuse->thermalmeter[0] << 16)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", - fw_cmdmap, fw_param); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1443,9 +1430,9 @@ /* Clear FW parameter in terms of RA parts. */ fw_param &= FW_RA_PARAM_CLR; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", - fw_cmdmap, fw_param); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1531,8 +1518,8 @@ FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; case FW_CMD_PAPE_CONTROL: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "[FW CMD] Set PAPE Control\n"); + rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, + "[FW CMD] Set PAPE Control\n"); fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rf.c @@ -95,13 +95,13 @@ } if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", - p_final_pwridx[0], p_final_pwridx[1]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", - p_final_pwridx[0], p_final_pwridx[1]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } } @@ -124,9 +124,9 @@ if (ant_pwr_diff < -8) ant_pwr_diff = -8; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", - ant_pwr_diff, ant_pwr_diff & 0xf); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", + ant_pwr_diff, ant_pwr_diff & 0xf); ant_pwr_diff &= 0xf; } @@ -143,8 +143,8 @@ rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), u4reg_val); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", - RFPGA0_TXGAINSTAGE, u4reg_val); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", + RFPGA0_TXGAINSTAGE, u4reg_val); } static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, @@ -169,8 +169,8 @@ writeval = rtlphy->mcs_offset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "RTK better performance, writeval = 0x%x\n", writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "RTK better performance, writeval = 0x%x\n", writeval); break; case 1: /* Realtek regulatory increase power diff defined @@ -178,9 +178,9 @@ if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { writeval = ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Realtek regulatory, 40MHz, writeval = 0x%x\n", - writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Realtek regulatory, 40MHz, writeval = 0x%x\n", + writeval); } else { chnlgroup = 0; @@ -199,16 +199,16 @@ + ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Realtek regulatory, 20MHz, writeval = 0x%x\n", - writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Realtek regulatory, 20MHz, writeval = 0x%x\n", + writeval); } break; case 2: /* Better regulatory don't increase any power diff */ writeval = ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Better regulatory, writeval = 0x%x\n", writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Better regulatory, writeval = 0x%x\n", writeval); break; case 3: /* Customer defined power diff. increase power diff @@ -216,15 +216,15 @@ chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "customer's limit, 40MHz = 0x%x\n", - rtlefuse->pwrgroup_ht40 - [RF90_PATH_A][chnl - 1]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "customer's limit, 40MHz = 0x%x\n", + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "customer's limit, 20MHz = 0x%x\n", - rtlefuse->pwrgroup_ht20 - [RF90_PATH_A][chnl - 1]); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "customer's limit, 20MHz = 0x%x\n", + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]); } for (i = 0; i < 4; i++) { @@ -256,20 +256,20 @@ (pwrdiff_limit[2] << 16) | (pwrdiff_limit[1] << 8) | (pwrdiff_limit[0]); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Customer's limit = 0x%x\n", customer_limit); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Customer's limit = 0x%x\n", customer_limit); writeval = customer_limit + ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Customer, writeval = 0x%x\n", writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "Customer, writeval = 0x%x\n", writeval); break; default: chnlgroup = 0; writeval = rtlphy->mcs_offset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "RTK better performance, writeval = 0x%x\n", writeval); + rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, + "RTK better performance, writeval = 0x%x\n", writeval); break; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c @@ -66,24 +66,25 @@ struct rt_firmware *pfirmware = NULL; char *fw_name = "rtlwifi/rtl8192sefw.bin"; - RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - "Firmware callback routine entered!\n"); - complete(&rtlpriv->firmware_loading_complete); + rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); if (!firmware) { pr_err("Firmware %s not available\n", fw_name); rtlpriv->max_fw_size = 0; - return; + goto exit; } if (firmware->size > rtlpriv->max_fw_size) { pr_err("Firmware is too big!\n"); rtlpriv->max_fw_size = 0; release_firmware(firmware); - return; + goto exit; } pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); pfirmware->sz_fw_tmpbufferlen = firmware->size; release_firmware(firmware); +exit: + complete(&rtlpriv->firmware_loading_complete); } static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/trx.c @@ -333,8 +333,8 @@ u8 bw_40 = 0; if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "DMA mapping error\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); return; } if (mac->opmode == NL80211_IFTYPE_STATION) { @@ -487,7 +487,7 @@ /* DOWRD 8 */ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, @@ -502,8 +502,8 @@ PCI_DMA_TODEVICE); if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "DMA mapping error\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, + "DMA mapping error\n"); return; } /* Clear all status */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c @@ -578,7 +578,7 @@ } if (rtlpriv->btcoexist.bt_edca_dl != 0) { - edca_be_ul = rtlpriv->btcoexist.bt_edca_dl; + edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; bt_change_edca = true; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c @@ -50,7 +50,7 @@ rfpath, regaddr); } - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); @@ -82,7 +82,7 @@ original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -91,7 +91,7 @@ rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data); } else { if (bitmask != RFREG_OFFSET_MASK) { - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c @@ -42,7 +42,7 @@ spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); @@ -70,7 +70,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = rtl8723_phy_rf_serial_read(hw, path, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8723com/phy_common.c @@ -53,13 +53,9 @@ u32 rtl8723_phy_calculate_bit_shift(u32 bitmask) { - u32 i; + u32 i = ffs(bitmask); - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; + return i ? i - 1 : 32; } EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -27,7 +27,13 @@ static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); -static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask); +static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) +{ + if (WARN_ON_ONCE(!bitmask)) + return 0; + + return __ffs(bitmask); +} static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); @@ -274,17 +280,6 @@ rfpath, pphyreg->rf3wire_offset, data_and_addr); } -static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw) { bool rtstatus = 0; @@ -1587,7 +1582,7 @@ } /* string is in decimal */ -static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint) +static bool _rtl8812ae_get_integer_from_string(const char *str, u8 *pint) { u16 i = 0; *pint = 0; @@ -1605,18 +1600,6 @@ return true; } -static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num) -{ - if (num == 0) - return false; - while (num > 0) { - num--; - if (str1[num] != str2[num]) - return false; - } - return true; -} - static s8 _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, u8 band, u8 channel) { @@ -1643,10 +1626,11 @@ return channel_index; } -static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, - u8 *pband, u8 *pbandwidth, - u8 *prate_section, u8 *prf_path, - u8 *pchannel, u8 *ppower_limit) +static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, + const char *pregulation, + const char *pband, const char *pbandwidth, + const char *prate_section, const char *prf_path, + const char *pchannel, const char *ppower_limit) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &rtlpriv->phy; @@ -1654,8 +1638,8 @@ u8 channel_index; s8 power_limit = 0, prev_power_limit, ret; - if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) || - !_rtl8812ae_get_integer_from_string((char *)ppower_limit, + if (!_rtl8812ae_get_integer_from_string(pchannel, &channel) || + !_rtl8812ae_get_integer_from_string(ppower_limit, &power_limit)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Illegal index of pwr_lmt table [chnl %d][val %d]\n", @@ -1665,42 +1649,42 @@ power_limit = power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit; - if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3)) + if (strcmp(pregulation, "FCC") == 0) regulation = 0; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3)) + else if (strcmp(pregulation, "MKK") == 0) regulation = 1; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4)) + else if (strcmp(pregulation, "ETSI") == 0) regulation = 2; - else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4)) + else if (strcmp(pregulation, "WW13") == 0) regulation = 3; - if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3)) + if (strcmp(prate_section, "CCK") == 0) rate_section = 0; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4)) + else if (strcmp(prate_section, "OFDM") == 0) rate_section = 1; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "1T") == 0) rate_section = 2; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + else if (strcmp(prate_section, "HT") == 0 && + strcmp(prf_path, "2T") == 0) rate_section = 3; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "1T") == 0) rate_section = 4; - else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && - _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) + else if (strcmp(prate_section, "VHT") == 0 && + strcmp(prf_path, "2T") == 0) rate_section = 5; - if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3)) + if (strcmp(pbandwidth, "20M") == 0) bandwidth = 0; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3)) + else if (strcmp(pbandwidth, "40M") == 0) bandwidth = 1; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3)) + else if (strcmp(pbandwidth, "80M") == 0) bandwidth = 2; - else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4)) + else if (strcmp(pbandwidth, "160M") == 0) bandwidth = 3; - if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) { + if (strcmp(pband, "2.4G") == 0) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G, channel); @@ -1724,7 +1708,7 @@ regulation, bandwidth, rate_section, channel_index, rtlphy->txpwr_limit_2_4g[regulation][bandwidth] [rate_section][channel_index][RF90_PATH_A]); - } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) { + } else if (strcmp(pband, "5G") == 0) { ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G, channel); @@ -1755,10 +1739,10 @@ } static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw, - u8 *regulation, u8 *band, - u8 *bandwidth, u8 *rate_section, - u8 *rf_path, u8 *channel, - u8 *power_limit) + const char *regulation, const char *band, + const char *bandwidth, const char *rate_section, + const char *rf_path, const char *channel, + const char *power_limit) { _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth, rate_section, rf_path, channel, @@ -1771,7 +1755,7 @@ struct rtl_hal *rtlhal = rtl_hal(rtlpriv); u32 i = 0; u32 array_len; - u8 **array; + const char **array; if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN; @@ -1785,13 +1769,13 @@ "\n"); for (i = 0; i < array_len; i += 7) { - u8 *regulation = array[i]; - u8 *band = array[i+1]; - u8 *bandwidth = array[i+2]; - u8 *rate = array[i+3]; - u8 *rf_path = array[i+4]; - u8 *chnl = array[i+5]; - u8 *val = array[i+6]; + const char *regulation = array[i]; + const char *band = array[i+1]; + const char *bandwidth = array[i+2]; + const char *rate = array[i+3]; + const char *rf_path = array[i+4]; + const char *chnl = array[i+5]; + const char *val = array[i+6]; _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band, bandwidth, rate, rf_path, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.c @@ -249,7 +249,7 @@ 0x824, 0x00030FE0, 0x828, 0x00000000, 0x82C, 0x002081DD, - 0x830, 0x2AAA8E24, + 0x830, 0x2AAAEEC8, 0x834, 0x0037A706, 0x838, 0x06489B44, 0x83C, 0x0000095B, @@ -324,10 +324,10 @@ 0x9D8, 0x00000000, 0x9DC, 0x00000000, 0x9E0, 0x00005D00, - 0x9E4, 0x00000002, + 0x9E4, 0x00000003, 0x9E8, 0x00000001, 0xA00, 0x00D047C8, - 0xA04, 0x01FF000C, + 0xA04, 0x01FF800C, 0xA08, 0x8C8A8300, 0xA0C, 0x2E68000F, 0xA10, 0x9500BB78, @@ -1320,7 +1320,11 @@ 0x083, 0x00021800, 0x084, 0x00028000, 0x085, 0x00048000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x086, 0x0009483A, + 0xA0000000, 0x00000000, 0x086, 0x00094838, + 0xB0000000, 0x00000000, 0x087, 0x00044980, 0x088, 0x00048000, 0x089, 0x0000D480, @@ -1409,36 +1413,32 @@ 0x03C, 0x000CA000, 0x0EF, 0x00000000, 0x0EF, 0x00001100, - 0xFF0F0104, 0xABCD, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0004ADF3, 0x034, 0x00049DF0, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0004ADF3, 0x034, 0x00049DF0, - 0xFF0F0404, 0xCDEF, - 0x034, 0x0004ADF3, - 0x034, 0x00049DF0, - 0xFF0F0200, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0004ADF5, 0x034, 0x00049DF2, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004A0F3, + 0x034, 0x000490B1, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0004A0F3, 0x034, 0x000490B1, - 0xCDCDCDCD, 0xCDCD, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF5, + 0x034, 0x00049DF2, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0004ADF3, + 0x034, 0x00049DF0, + 0xA0000000, 0x00000000, 0x034, 0x0004ADF7, 0x034, 0x00049DF3, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, - 0x034, 0x00048DED, - 0x034, 0x00047DEA, - 0x034, 0x00046DE7, - 0x034, 0x00045CE9, - 0x034, 0x00044CE6, - 0x034, 0x000438C6, - 0x034, 0x00042886, - 0x034, 0x00041486, - 0x034, 0x00040447, - 0xFF0F0204, 0xCDEF, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00048DED, 0x034, 0x00047DEA, 0x034, 0x00046DE7, @@ -1448,7 +1448,7 @@ 0x034, 0x00042886, 0x034, 0x00041486, 0x034, 0x00040447, - 0xFF0F0404, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00048DED, 0x034, 0x00047DEA, 0x034, 0x00046DE7, @@ -1458,7 +1458,17 @@ 0x034, 0x00042886, 0x034, 0x00041486, 0x034, 0x00040447, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000480AE, + 0x034, 0x000470AB, + 0x034, 0x0004608B, + 0x034, 0x00045069, + 0x034, 0x00044048, + 0x034, 0x00043045, + 0x034, 0x00042026, + 0x034, 0x00041023, + 0x034, 0x00040002, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x000480AE, 0x034, 0x000470AB, 0x034, 0x0004608B, @@ -1468,7 +1478,17 @@ 0x034, 0x00042026, 0x034, 0x00041023, 0x034, 0x00040002, - 0xCDCDCDCD, 0xCDCD, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00048DED, + 0x034, 0x00047DEA, + 0x034, 0x00046DE7, + 0x034, 0x00045CE9, + 0x034, 0x00044CE6, + 0x034, 0x000438C6, + 0x034, 0x00042886, + 0x034, 0x00041486, + 0x034, 0x00040447, + 0xA0000000, 0x00000000, 0x034, 0x00048DEF, 0x034, 0x00047DEC, 0x034, 0x00046DE9, @@ -1478,38 +1498,36 @@ 0x034, 0x0004248A, 0x034, 0x0004108D, 0x034, 0x0004008A, - 0xFF0F0104, 0xDEAD, - 0xFF0F0200, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000210, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0002ADF4, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002A0F3, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0002A0F3, - 0xCDCDCDCD, 0xCDCD, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0002ADF4, + 0xA0000000, 0x00000000, 0x034, 0x0002ADF7, - 0xFF0F0200, 0xDEAD, - 0xFF0F0104, 0xABCD, - 0x034, 0x00029DF4, - 0xFF0F0204, 0xCDEF, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00029DF4, - 0xFF0F0404, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00029DF4, - 0xFF0F0200, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00029DF1, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000290F0, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x000290F0, - 0xCDCDCDCD, 0xCDCD, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF1, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00029DF4, + 0xA0000000, 0x00000000, 0x034, 0x00029DF2, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, - 0x034, 0x00028DF1, - 0x034, 0x00027DEE, - 0x034, 0x00026DEB, - 0x034, 0x00025CEC, - 0x034, 0x00024CE9, - 0x034, 0x000238CA, - 0x034, 0x00022889, - 0x034, 0x00021489, - 0x034, 0x0002044A, - 0xFF0F0204, 0xCDEF, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00028DF1, 0x034, 0x00027DEE, 0x034, 0x00026DEB, @@ -1519,7 +1537,7 @@ 0x034, 0x00022889, 0x034, 0x00021489, 0x034, 0x0002044A, - 0xFF0F0404, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00028DF1, 0x034, 0x00027DEE, 0x034, 0x00026DEB, @@ -1529,7 +1547,7 @@ 0x034, 0x00022889, 0x034, 0x00021489, 0x034, 0x0002044A, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x000280AF, 0x034, 0x000270AC, 0x034, 0x0002608B, @@ -1539,7 +1557,27 @@ 0x034, 0x00022026, 0x034, 0x00021023, 0x034, 0x00020002, - 0xCDCDCDCD, 0xCDCD, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x000280AF, + 0x034, 0x000270AC, + 0x034, 0x0002608B, + 0x034, 0x00025069, + 0x034, 0x00024048, + 0x034, 0x00023045, + 0x034, 0x00022026, + 0x034, 0x00021023, + 0x034, 0x00020002, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00028DF1, + 0x034, 0x00027DEE, + 0x034, 0x00026DEB, + 0x034, 0x00025CEC, + 0x034, 0x00024CE9, + 0x034, 0x000238CA, + 0x034, 0x00022889, + 0x034, 0x00021489, + 0x034, 0x0002044A, + 0xA0000000, 0x00000000, 0x034, 0x00028DEE, 0x034, 0x00027DEB, 0x034, 0x00026CCD, @@ -1549,27 +1587,24 @@ 0x034, 0x00022849, 0x034, 0x00021449, 0x034, 0x0002004D, - 0xFF0F0104, 0xDEAD, - 0xFF0F02C0, 0xABCD, + 0xB0000000, 0x00000000, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000A0D7, + 0x034, 0x000090D3, + 0x034, 0x000080B1, + 0x034, 0x000070AE, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0000A0D7, 0x034, 0x000090D3, 0x034, 0x000080B1, 0x034, 0x000070AE, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x034, 0x0000ADF7, 0x034, 0x00009DF4, 0x034, 0x00008DF1, 0x034, 0x00007DEE, - 0xFF0F02C0, 0xDEAD, - 0xFF0F0104, 0xABCD, - 0x034, 0x00006DEB, - 0x034, 0x00005CEC, - 0x034, 0x00004CE9, - 0x034, 0x000038CA, - 0x034, 0x00002889, - 0x034, 0x00001489, - 0x034, 0x0000044A, - 0xFF0F0204, 0xCDEF, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00006DEB, 0x034, 0x00005CEC, 0x034, 0x00004CE9, @@ -1577,7 +1612,7 @@ 0x034, 0x00002889, 0x034, 0x00001489, 0x034, 0x0000044A, - 0xFF0F0404, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x00006DEB, 0x034, 0x00005CEC, 0x034, 0x00004CE9, @@ -1585,7 +1620,7 @@ 0x034, 0x00002889, 0x034, 0x00001489, 0x034, 0x0000044A, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, 0x034, 0x0000608D, 0x034, 0x0000506B, 0x034, 0x0000404A, @@ -1593,7 +1628,23 @@ 0x034, 0x00002044, 0x034, 0x00001025, 0x034, 0x00000004, - 0xCDCDCDCD, 0xCDCD, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x0000608D, + 0x034, 0x0000506B, + 0x034, 0x0000404A, + 0x034, 0x00003047, + 0x034, 0x00002044, + 0x034, 0x00001025, + 0x034, 0x00000004, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x034, 0x00006DEB, + 0x034, 0x00005CEC, + 0x034, 0x00004CE9, + 0x034, 0x000038CA, + 0x034, 0x00002889, + 0x034, 0x00001489, + 0x034, 0x0000044A, + 0xA0000000, 0x00000000, 0x034, 0x00006DCD, 0x034, 0x00005CCD, 0x034, 0x00004CCA, @@ -1601,11 +1652,11 @@ 0x034, 0x00002888, 0x034, 0x00001488, 0x034, 0x00000486, - 0xFF0F0104, 0xDEAD, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x0001712A, 0x0EF, 0x00000040, - 0xFF0F0104, 0xABCD, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x035, 0x00000187, 0x035, 0x00008187, 0x035, 0x00010187, @@ -1615,7 +1666,7 @@ 0x035, 0x00040188, 0x035, 0x00048188, 0x035, 0x00050188, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x035, 0x00000187, 0x035, 0x00008187, 0x035, 0x00010187, @@ -1625,7 +1676,37 @@ 0x035, 0x00040188, 0x035, 0x00048188, 0x035, 0x00050188, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000145, + 0x035, 0x00008145, + 0x035, 0x00010145, + 0x035, 0x00020196, + 0x035, 0x00028196, + 0x035, 0x00030196, + 0x035, 0x000401C7, + 0x035, 0x000481C7, + 0x035, 0x000501C7, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x035, 0x00000128, + 0x035, 0x00008128, + 0x035, 0x00010128, + 0x035, 0x000201C8, + 0x035, 0x000281C8, + 0x035, 0x000301C8, + 0x035, 0x000401C8, + 0x035, 0x000481C8, + 0x035, 0x000501C8, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x035, 0x00000187, 0x035, 0x00008187, 0x035, 0x00010187, @@ -1635,7 +1716,7 @@ 0x035, 0x00040188, 0x035, 0x00048188, 0x035, 0x00050188, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x035, 0x00000145, 0x035, 0x00008145, 0x035, 0x00010145, @@ -1645,11 +1726,11 @@ 0x035, 0x000401C7, 0x035, 0x000481C7, 0x035, 0x000501C7, - 0xFF0F0104, 0xDEAD, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x0001712A, 0x0EF, 0x00000010, - 0xFF0F0104, 0xABCD, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x036, 0x00085733, 0x036, 0x0008D733, 0x036, 0x00095733, @@ -1662,7 +1743,7 @@ 0x036, 0x000CE4B4, 0x036, 0x000D64B4, 0x036, 0x000DE4B4, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x036, 0x00085733, 0x036, 0x0008D733, 0x036, 0x00095733, @@ -1675,7 +1756,46 @@ 0x036, 0x000CE4B4, 0x036, 0x000D64B4, 0x036, 0x000DE4B4, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000056B3, + 0x036, 0x0000D6B3, + 0x036, 0x000156B3, + 0x036, 0x0001D6B3, + 0x036, 0x00026634, + 0x036, 0x0002E634, + 0x036, 0x00036634, + 0x036, 0x0003E634, + 0x036, 0x000467B4, + 0x036, 0x0004E7B4, + 0x036, 0x000567B4, + 0x036, 0x0005E7B4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x036, 0x000063B5, + 0x036, 0x0000E3B5, + 0x036, 0x000163B5, + 0x036, 0x0001E3B5, + 0x036, 0x000263B5, + 0x036, 0x0002E3B5, + 0x036, 0x000363B5, + 0x036, 0x0003E3B5, + 0x036, 0x000463B5, + 0x036, 0x0004E3B5, + 0x036, 0x000563B5, + 0x036, 0x0005E3B5, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x036, 0x00085733, 0x036, 0x0008D733, 0x036, 0x00095733, @@ -1688,7 +1808,7 @@ 0x036, 0x000CE4B4, 0x036, 0x000D64B4, 0x036, 0x000DE4B4, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x036, 0x000056B3, 0x036, 0x0000D6B3, 0x036, 0x000156B3, @@ -1701,103 +1821,162 @@ 0x036, 0x0004E7B4, 0x036, 0x000567B4, 0x036, 0x0005E7B4, - 0xFF0F0104, 0xDEAD, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0EF, 0x00000008, - 0xFF0F0104, 0xABCD, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x000001C8, 0x03C, 0x00000492, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x000001C8, 0x03C, 0x00000492, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x0000022A, + 0x03C, 0x00000594, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x000001B6, + 0x03C, 0x00000492, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x000001C8, 0x03C, 0x00000492, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x03C, 0x0000022A, 0x03C, 0x00000594, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x00000800, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x00000800, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x00000800, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, 0x03C, 0x00000820, - 0xCDCDCDCD, 0xCDCD, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000820, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x03C, 0x00000800, + 0xA0000000, 0x00000000, 0x03C, 0x00000900, - 0xFF0F0104, 0xDEAD, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x018, 0x0001712A, 0x0EF, 0x00000002, - 0xFF0F0104, 0xABCD, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x008, 0x0004E400, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x008, 0x0004E400, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x008, 0x00002000, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x008, 0x0004E400, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x008, 0x00002000, - 0xFF0F0104, 0xDEAD, + 0xB0000000, 0x00000000, 0x0EF, 0x00000000, 0x0DF, 0x000000C0, - 0x01F, 0x00040064, - 0xFF0F0104, 0xABCD, + 0x01F, 0x00000064, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x058, 0x000A7284, 0x059, 0x000600EC, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x058, 0x000A7284, 0x059, 0x000600EC, - 0xFF0F0404, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x058, 0x00081184, + 0x059, 0x0006016C, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x058, 0x000A7284, 0x059, 0x000600EC, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x058, 0x00081184, 0x059, 0x0006016C, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x000E8D73, 0x062, 0x00093FC5, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x000E8D73, 0x062, 0x00093FC5, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EAD53, + 0x062, 0x00093BC4, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x061, 0x000EFD83, + 0x062, 0x00093FCC, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x061, 0x000E8D73, 0x062, 0x00093FC5, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x061, 0x000EAD53, 0x062, 0x00093BC4, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, 0x063, 0x000110E9, - 0xFF0F0204, 0xCDEF, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, 0x063, 0x000110E9, - 0xFF0F0404, 0xCDEF, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, 0x063, 0x000110E9, - 0xFF0F0200, 0xCDEF, - 0x063, 0x000710E9, - 0xFF0F02C0, 0xCDEF, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x063, 0x000110E9, - 0xCDCDCDCD, 0xCDCD, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110EB, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, + 0x063, 0x000110E9, + 0xA0000000, 0x00000000, 0x063, 0x000714E9, - 0xFF0F0104, 0xDEAD, - 0xFF0F0104, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C27C, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, 0x064, 0x0001C27C, - 0xFF0F0204, 0xCDEF, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x064, 0x0001C67C, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, 0x064, 0x0001C27C, - 0xFF0F0404, 0xCDEF, + 0x90000410, 0x00000000, 0x40000000, 0x00000000, 0x064, 0x0001C27C, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x064, 0x0001C67C, - 0xFF0F0104, 0xDEAD, - 0xFF0F0200, 0xABCD, + 0xB0000000, 0x00000000, + 0x80000111, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000110, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00091016, + 0x90000210, 0x00000000, 0x40000000, 0x00000000, 0x065, 0x00093016, - 0xFF0F02C0, 0xCDEF, + 0x9000020c, 0x00000000, 0x40000000, 0x00000000, 0x065, 0x00093015, - 0xCDCDCDCD, 0xCDCD, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093015, + 0x90000200, 0x00000000, 0x40000000, 0x00000000, + 0x065, 0x00093016, + 0xA0000000, 0x00000000, 0x065, 0x00091016, - 0xFF0F0200, 0xDEAD, + 0xB0000000, 0x00000000, 0x018, 0x00000006, 0x0EF, 0x00002000, 0x03B, 0x0003824B, @@ -1895,9 +2074,10 @@ 0x0B4, 0x0001214C, 0x0B7, 0x0003000C, 0x01C, 0x000539D2, + 0x0C4, 0x000AFE00, 0x018, 0x0001F12A, - 0x0FE, 0x00000000, - 0x0FE, 0x00000000, + 0xFFE, 0x00000000, + 0xFFE, 0x00000000, 0x018, 0x0001712A, }; @@ -2017,6 +2197,7 @@ u32 RTL8812AE_MAC_1T_ARRAYLEN = ARRAY_SIZE(RTL8812AE_MAC_REG_ARRAY); u32 RTL8821AE_MAC_REG_ARRAY[] = { + 0x421, 0x0000000F, 0x428, 0x0000000A, 0x429, 0x00000010, 0x430, 0x00000000, @@ -2485,7 +2666,7 @@ 0x81C, 0xA6360001, 0x81C, 0xA5380001, 0x81C, 0xA43A0001, - 0x81C, 0xA33C0001, + 0x81C, 0x683C0001, 0x81C, 0x673E0001, 0x81C, 0x66400001, 0x81C, 0x65420001, @@ -2519,7 +2700,66 @@ 0x81C, 0x017A0001, 0x81C, 0x017C0001, 0x81C, 0x017E0001, - 0xFF0F02C0, 0xABCD, + 0x8000020c, 0x00000000, 0x40000000, 0x00000000, + 0x81C, 0xFB000101, + 0x81C, 0xFA020101, + 0x81C, 0xF9040101, + 0x81C, 0xF8060101, + 0x81C, 0xF7080101, + 0x81C, 0xF60A0101, + 0x81C, 0xF50C0101, + 0x81C, 0xF40E0101, + 0x81C, 0xF3100101, + 0x81C, 0xF2120101, + 0x81C, 0xF1140101, + 0x81C, 0xF0160101, + 0x81C, 0xEF180101, + 0x81C, 0xEE1A0101, + 0x81C, 0xED1C0101, + 0x81C, 0xEC1E0101, + 0x81C, 0xEB200101, + 0x81C, 0xEA220101, + 0x81C, 0xE9240101, + 0x81C, 0xE8260101, + 0x81C, 0xE7280101, + 0x81C, 0xE62A0101, + 0x81C, 0xE52C0101, + 0x81C, 0xE42E0101, + 0x81C, 0xE3300101, + 0x81C, 0xA5320101, + 0x81C, 0xA4340101, + 0x81C, 0xA3360101, + 0x81C, 0x87380101, + 0x81C, 0x863A0101, + 0x81C, 0x853C0101, + 0x81C, 0x843E0101, + 0x81C, 0x69400101, + 0x81C, 0x68420101, + 0x81C, 0x67440101, + 0x81C, 0x66460101, + 0x81C, 0x49480101, + 0x81C, 0x484A0101, + 0x81C, 0x474C0101, + 0x81C, 0x2A4E0101, + 0x81C, 0x29500101, + 0x81C, 0x28520101, + 0x81C, 0x27540101, + 0x81C, 0x26560101, + 0x81C, 0x25580101, + 0x81C, 0x245A0101, + 0x81C, 0x235C0101, + 0x81C, 0x055E0101, + 0x81C, 0x04600101, + 0x81C, 0x03620101, + 0x81C, 0x02640101, + 0x81C, 0x01660101, + 0x81C, 0x01680101, + 0x81C, 0x016A0101, + 0x81C, 0x016C0101, + 0x81C, 0x016E0101, + 0x81C, 0x01700101, + 0x81C, 0x01720101, + 0x9000040c, 0x00000000, 0x40000000, 0x00000000, 0x81C, 0xFB000101, 0x81C, 0xFA020101, 0x81C, 0xF9040101, @@ -2578,7 +2818,7 @@ 0x81C, 0x016E0101, 0x81C, 0x01700101, 0x81C, 0x01720101, - 0xCDCDCDCD, 0xCDCD, + 0xA0000000, 0x00000000, 0x81C, 0xFF000101, 0x81C, 0xFF020101, 0x81C, 0xFE040101, @@ -2637,7 +2877,7 @@ 0x81C, 0x046E0101, 0x81C, 0x03700101, 0x81C, 0x02720101, - 0xFF0F02C0, 0xDEAD, + 0xB0000000, 0x00000000, 0x81C, 0x01740101, 0x81C, 0x01760101, 0x81C, 0x01780101, @@ -2654,7 +2894,7 @@ * TXPWR_LMT.TXT ******************************************************************************/ -u8 *RTL8812AE_TXPWR_LMT[] = { +const char *RTL8812AE_TXPWR_LMT[] = { "FCC", "2.4G", "20M", "CCK", "1T", "01", "36", "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", @@ -3223,7 +3463,7 @@ u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN = ARRAY_SIZE(RTL8812AE_TXPWR_LMT); -u8 *RTL8821AE_TXPWR_LMT[] = { +const char *RTL8821AE_TXPWR_LMT[] = { "FCC", "2.4G", "20M", "CCK", "1T", "01", "32", "ETSI", "2.4G", "20M", "CCK", "1T", "01", "32", "MKK", "2.4G", "20M", "CCK", "1T", "01", "32", --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/table.h @@ -28,7 +28,7 @@ extern u32 RTL8812AE_AGC_TAB_1TARRAYLEN; extern u32 RTL8812AE_AGC_TAB_ARRAY[]; extern u32 RTL8812AE_TXPWR_LMT_ARRAY_LEN; -extern u8 *RTL8812AE_TXPWR_LMT[]; +extern const char *RTL8812AE_TXPWR_LMT[]; extern u32 RTL8821AE_TXPWR_LMT_ARRAY_LEN; -extern u8 *RTL8821AE_TXPWR_LMT[]; +extern const char *RTL8821AE_TXPWR_LMT[]; #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -259,15 +259,15 @@ ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "Invalid endpoint map setting!\n"); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -337,10 +337,10 @@ else if (usb_endpoint_dir_out(pep_desc)) rtlusb->out_ep_nums++; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", - pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval); + rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", + pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, + pep_desc->bInterval); } if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) { pr_err("Too few input end points found\n"); @@ -718,8 +718,11 @@ usb_anchor_urb(urb, &rtlusb->rx_submitted); err = usb_submit_urb(urb, GFP_KERNEL); - if (err) + if (err) { + usb_unanchor_urb(urb); + usb_free_urb(urb); goto err_out; + } usb_free_urb(urb); } return 0; @@ -881,10 +884,8 @@ WARN_ON(NULL == skb); _urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!_urb) { - kfree_skb(skb); + if (!_urb) return NULL; - } _rtl_install_trx_info(rtlusb, skb, ep_num); usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, ep_num), skb->data, skb->len, _rtl_tx_complete, skb); @@ -898,7 +899,6 @@ struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); u32 ep_num; struct urb *_urb = NULL; - struct sk_buff *_skb = NULL; WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { @@ -907,8 +907,7 @@ return; } ep_num = rtlusb->ep_map.ep_mapping[qnum]; - _skb = skb; - _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); + _urb = _rtl_usb_tx_urb_setup(hw, skb, ep_num); if (unlikely(!_urb)) { pr_err("Can't allocate urb. Drop skb!\n"); kfree_skb(skb); @@ -932,7 +931,7 @@ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_dbg(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); } if (rtlpriv->psc.sw_ps_enabled) { @@ -1014,15 +1013,17 @@ hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - WARN_ONCE(true, "rtl_usb: ieee80211 alloc failed\n"); + pr_warn("rtl_usb: ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv; rtlpriv->hw = hw; rtlpriv->usb_data = kcalloc(RTL_USB_MAX_RX_COUNT, sizeof(u32), GFP_KERNEL); - if (!rtlpriv->usb_data) + if (!rtlpriv->usb_data) { + ieee80211_free_hw(hw); return -ENOMEM; + } /* this spin lock must be initialized early */ spin_lock_init(&rtlpriv->locks.usb_lock); @@ -1078,11 +1079,12 @@ return 0; error_out: + rtl_usb_deinit(hw); rtl_deinit_core(hw); error_out2: _rtl_usb_io_handler_release(hw); usb_put_dev(udev); - complete(&rtlpriv->firmware_loading_complete); + kfree(rtlpriv->usb_data); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -2302,7 +2302,6 @@ u32 regaddr, u32 bitmask, u32 data); void (*linked_set_reg)(struct ieee80211_hw *hw); void (*chk_switch_dmdp)(struct ieee80211_hw *hw); - void (*dualmac_easy_concurrent)(struct ieee80211_hw *hw); void (*dualmac_switch_to_dmdp)(struct ieee80211_hw *hw); bool (*phy_rf6052_config)(struct ieee80211_hw *hw); void (*phy_rf6052_set_cck_txpower)(struct ieee80211_hw *hw, @@ -2338,8 +2337,6 @@ void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); int (*adapter_start)(struct ieee80211_hw *hw); void (*adapter_stop)(struct ieee80211_hw *hw); - bool (*check_buddy_priv)(struct ieee80211_hw *hw, - struct rtl_priv **buddy_priv); int (*adapter_tx)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, @@ -2468,7 +2465,6 @@ /*timer */ struct timer_list watchdog_timer; - struct timer_list dualmac_easyconcurrent_retrytimer; struct timer_list fw_clockoff_timer; struct timer_list fast_antenna_training_timer; /*task */ @@ -2500,14 +2496,6 @@ #define MIMO_PS_DYNAMIC 1 #define MIMO_PS_NOLIMIT 3 -struct rtl_dualmac_easy_concurrent_ctl { - enum band_type currentbandtype_backfordmdp; - bool close_bbandrf_for_dmsp; - bool change_to_dmdp; - bool change_to_dmsp; - bool switch_in_process; -}; - struct rtl_dmsp_ctl { bool activescan_for_slaveofdmsp; bool scan_for_anothermac_fordmsp; @@ -2592,14 +2580,6 @@ u32 rssi_max; }; -struct rtl_global_var { - /* from this list we can get - * other adapter's rtl_priv - */ - struct list_head glb_priv_list; - spinlock_t glb_list_lock; -}; - #define IN_4WAY_TIMEOUT_TIME (30 * MSEC_PER_SEC) /* 30 seconds */ struct rtl_btc_info { @@ -2745,10 +2725,7 @@ struct rtl_priv { struct ieee80211_hw *hw; struct completion firmware_loading_complete; - struct list_head list; struct rtl_priv *buddy_priv; - struct rtl_global_var *glb_var; - struct rtl_dualmac_easy_concurrent_ctl easy_concurrent_ctl; struct rtl_dmsp_ctl dmsp_ctl; struct rtl_locks locks; struct rtl_works works; @@ -3230,4 +3207,11 @@ return ieee80211_find_sta(mac->vif, mac_addr); } +static inline u32 calculate_bit_shift(u32 bitmask) +{ + if (WARN_ON_ONCE(!bitmask)) + return 0; + + return __ffs(bitmask); +} #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/Kconfig @@ -12,6 +12,7 @@ config RTW88_CORE tristate + select WANT_DEV_COREDUMP config RTW88_PCI tristate @@ -36,6 +37,16 @@ 802.11ac PCIe wireless network adapter +config RTW88_8723DE + bool "Realtek 8723DE PCI wireless network adapter" + depends on PCI + select RTW88_CORE + select RTW88_PCI + help + Select this option will enable support for 8723DE chipset + + 802.11n PCIe wireless network adapter + config RTW88_DEBUG bool "Realtek rtw88 debug support" depends on RTW88_CORE @@ -52,4 +63,14 @@ If unsure, say Y to simplify debug problems +config RTW88_REGD_USER_REG_HINTS + bool "Realtek rtw88 user regulatory hints" + depends on RTW88_CORE + default n + help + Enable regulatoy user hints + + If unsure, say N. This should only be allowed on distributions + that need this to correct the regulatory. + endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/Makefile +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/Makefile @@ -14,10 +14,14 @@ fw.o \ ps.o \ sec.o \ + bf.o \ + wow.o \ + sar.o \ regd.o rtw88-$(CONFIG_RTW88_8822BE) += rtw8822b.o rtw8822b_table.o rtw88-$(CONFIG_RTW88_8822CE) += rtw8822c.o rtw8822c_table.o +rtw88-$(CONFIG_RTW88_8723DE) += rtw8723d.o rtw8723d_table.o obj-$(CONFIG_RTW88_PCI) += rtwpci.o rtwpci-objs := pci.o --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/bf.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/bf.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation. + */ + +#include "main.h" +#include "reg.h" +#include "bf.h" +#include "debug.h" + +void rtw_bf_disassoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + if (bfee->role == RTW_BFEE_NONE) + return; + + if (bfee->role == RTW_BFEE_MU) + bfinfo->bfer_mu_cnt--; + else if (bfee->role == RTW_BFEE_SU) + bfinfo->bfer_su_cnt--; + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, false); + + bfee->role = RTW_BFEE_NONE; +} + +void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf) +{ + struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_sta *sta; + struct ieee80211_sta_vht_cap *vht_cap; + struct ieee80211_sta_vht_cap *ic_vht_cap; + const u8 *bssid = bss_conf->bssid; + u32 sound_dim; + u8 i; + + if (!(chip->band & RTW_BAND_5G)) + return; + + rcu_read_lock(); + + sta = ieee80211_find_sta(vif, bssid); + if (!sta) { + rtw_warn(rtwdev, "failed to find station entry for bss %pM\n", + bssid); + goto out_unlock; + } + + ic_vht_cap = &hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap; + vht_cap = &sta->vht_cap; + + if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) && + (vht_cap->cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { + if (bfinfo->bfer_mu_cnt >= chip->bfer_mu_max_num) { + rtw_dbg(rtwdev, RTW_DBG_BF, "mu bfer number over limit\n"); + goto out_unlock; + } + + ether_addr_copy(bfee->mac_addr, bssid); + bfee->role = RTW_BFEE_MU; + bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7); + bfee->aid = bss_conf->aid; + bfinfo->bfer_mu_cnt++; + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true); + } else if ((ic_vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) && + (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)) { + if (bfinfo->bfer_su_cnt >= chip->bfer_su_max_num) { + rtw_dbg(rtwdev, RTW_DBG_BF, "su bfer number over limit\n"); + goto out_unlock; + } + + sound_dim = vht_cap->cap & + IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK; + sound_dim >>= IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + + ether_addr_copy(bfee->mac_addr, bssid); + bfee->role = RTW_BFEE_SU; + bfee->sound_dim = (u8)sound_dim; + bfee->g_id = 0; + bfee->p_aid = (bssid[5] << 1) | (bssid[4] >> 7); + bfinfo->bfer_su_cnt++; + for (i = 0; i < chip->bfer_su_max_num; i++) { + if (!test_bit(i, bfinfo->bfer_su_reg_maping)) { + set_bit(i, bfinfo->bfer_su_reg_maping); + bfee->su_reg_index = i; + break; + } + } + + rtw_chip_config_bfee(rtwdev, rtwvif, bfee, true); + } + +out_unlock: + rcu_read_unlock(); +} + +void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, + struct mu_bfer_init_para *param) +{ + u16 mu_bf_ctl = 0; + u8 *addr = param->bfer_address; + int i; + + for (i = 0; i < ETH_ALEN; i++) + rtw_write8(rtwdev, REG_ASSOCIATED_BFMER0_INFO + i, addr[i]); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 6, param->paid); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, param->csi_para); + + mu_bf_ctl = rtw_read16(rtwdev, REG_WMAC_MU_BF_CTL) & 0xC000; + mu_bf_ctl |= param->my_aid | (param->csi_length_sel << 12); + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, mu_bf_ctl); +} + +void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, + enum rtw_trx_desc_rate rate) +{ + u32 psf_ctl = 0; + u8 csi_rsc = 0x1; + + psf_ctl = rtw_read32(rtwdev, REG_BBPSF_CTRL) | + BIT_WMAC_USE_NDPARATE | + (csi_rsc << 13); + + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING); + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, 0x26); + rtw_write8_clr(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF_REPORT_POLL); + rtw_write8_clr(rtwdev, REG_RXFLTMAP4, BIT_RXFLTMAP4_BF_REPORT_POLL); + + if (vif->net_type == RTW_NET_AP_MODE) + rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl | BIT(12)); + else + rtw_write32(rtwdev, REG_BBPSF_CTRL, psf_ctl & ~BIT(12)); +} + +void rtw_bf_cfg_mu_bfee(struct rtw_dev *rtwdev, struct cfg_mumimo_para *param) +{ + u8 mu_tbl_sel; + u8 mu_valid; + + mu_valid = rtw_read8(rtwdev, REG_MU_TX_CTL) & + ~BIT_MASK_R_MU_TABLE_VALID; + + rtw_write8(rtwdev, REG_MU_TX_CTL, + (mu_valid | BIT(0) | BIT(1)) & ~(BIT(7))); + + mu_tbl_sel = rtw_read8(rtwdev, REG_MU_TX_CTL + 1) & 0xF8; + + rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel); + rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[0]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[0]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4, + param->given_user_pos[1]); + + rtw_write8(rtwdev, REG_MU_TX_CTL + 1, mu_tbl_sel | 1); + rtw_write32(rtwdev, REG_MU_STA_GID_VLD, param->given_gid_tab[1]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO, param->given_user_pos[2]); + rtw_write32(rtwdev, REG_MU_STA_USER_POS_INFO + 4, + param->given_user_pos[3]); +} + +void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0); + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0); + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0); + rtw_write8(rtwdev, REG_MU_TX_CTL, 0); +} + +void rtw_bf_del_sounding(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, 0); +} + +void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + u8 nc_index = 1; + u8 nr_index = bfee->sound_dim; + u8 grouping = 0, codebookinfo = 1, coefficientsize = 3; + u32 addr_bfer_info, addr_csi_rpt, csi_param; + u8 i; + + rtw_dbg(rtwdev, RTW_DBG_BF, "config as an su bfee\n"); + + switch (bfee->su_reg_index) { + case 1: + addr_bfer_info = REG_ASSOCIATED_BFMER1_INFO; + addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20 + 2; + break; + case 0: + default: + addr_bfer_info = REG_ASSOCIATED_BFMER0_INFO; + addr_csi_rpt = REG_TX_CSI_RPT_PARAM_BW20; + break; + } + + /* Sounding protocol control */ + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_SOUNDING); + + /* MAC address/Partial AID of Beamformer */ + for (i = 0; i < ETH_ALEN; i++) + rtw_write8(rtwdev, addr_bfer_info + i, bfee->mac_addr[i]); + + csi_param = (u16)((coefficientsize << 10) | + (codebookinfo << 8) | + (grouping << 6) | + (nr_index << 3) | + nc_index); + rtw_write16(rtwdev, addr_csi_rpt, csi_param); + + /* ndp rx standby timer */ + rtw_write8(rtwdev, REG_SND_PTCL_CTRL + 3, RTW_NDP_RX_STANDBY_TIME); +} + +/* nc index: 1 2T2R 0 1T1R + * nr index: 1 use Nsts 0 use reg setting + * codebookinfo: 1 802.11ac 3 802.11n + */ +void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bf_info = &rtwdev->bf_info; + struct mu_bfer_init_para param; + u8 nc_index = 1, nr_index = 1; + u8 grouping = 0, codebookinfo = 1, coefficientsize = 0; + u32 csi_param; + + rtw_dbg(rtwdev, RTW_DBG_BF, "config as an mu bfee\n"); + + csi_param = (u16)((coefficientsize << 10) | + (codebookinfo << 8) | + (grouping << 6) | + (nr_index << 3) | + nc_index); + + rtw_dbg(rtwdev, RTW_DBG_BF, "nc=%d nr=%d group=%d codebookinfo=%d coefficientsize=%d\n", + nc_index, nr_index, grouping, codebookinfo, + coefficientsize); + + param.paid = bfee->p_aid; + param.csi_para = csi_param; + param.my_aid = bfee->aid & 0xfff; + param.csi_length_sel = HAL_CSI_SEG_4K; + ether_addr_copy(param.bfer_address, bfee->mac_addr); + + rtw_bf_init_bfer_entry_mu(rtwdev, ¶m); + + bf_info->cur_csi_rpt_rate = DESC_RATE6M; + rtw_bf_cfg_sounding(rtwdev, vif, DESC_RATE6M); + + /* accept action_no_ack */ + rtw_write16_set(rtwdev, REG_RXFLTMAP0, BIT_RXFLTMAP0_ACTIONNOACK); + + /* accept NDPA and BF report poll */ + rtw_write16_set(rtwdev, REG_RXFLTMAP1, BIT_RXFLTMAP1_BF); +} + +void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + rtw_dbg(rtwdev, RTW_DBG_BF, "remove as a su bfee\n"); + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE); + + switch (bfee->su_reg_index) { + case 0: + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER0_INFO, 0); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER0_INFO + 4, 0); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20, 0); + break; + case 1: + rtw_write32(rtwdev, REG_ASSOCIATED_BFMER1_INFO, 0); + rtw_write16(rtwdev, REG_ASSOCIATED_BFMER1_INFO + 4, 0); + rtw_write16(rtwdev, REG_TX_CSI_RPT_PARAM_BW20 + 2, 0); + break; + } + + clear_bit(bfee->su_reg_index, bfinfo->bfer_su_reg_maping); + bfee->su_reg_index = 0xFF; +} + +void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_bfee *bfee) +{ + struct rtw_bf_info *bfinfo = &rtwdev->bf_info; + + rtw_write8(rtwdev, REG_SND_PTCL_CTRL, RTW_SND_CTRL_REMOVE); + + rtw_bf_del_bfer_entry_mu(rtwdev); + + if (bfinfo->bfer_su_cnt == 0 && bfinfo->bfer_mu_cnt == 0) + rtw_bf_del_sounding(rtwdev); +} + +void rtw_bf_set_gid_table(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_bfee *bfee = &rtwvif->bfee; + struct cfg_mumimo_para param; + + if (bfee->role != RTW_BFEE_MU) { + rtw_dbg(rtwdev, RTW_DBG_BF, "this vif is not mu bfee\n"); + return; + } + + param.grouping_bitmap = 0; + param.mu_tx_en = 0; + memset(param.sounding_sts, 0, 6); + memcpy(param.given_gid_tab, conf->mu_group.membership, 8); + memcpy(param.given_user_pos, conf->mu_group.position, 16); + rtw_dbg(rtwdev, RTW_DBG_BF, "STA0: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n", + param.given_gid_tab[0], param.given_user_pos[0], + param.given_user_pos[1]); + + rtw_dbg(rtwdev, RTW_DBG_BF, "STA1: gid_valid=0x%x, user_position_l=0x%x, user_position_h=0x%x\n", + param.given_gid_tab[1], param.given_user_pos[2], + param.given_user_pos[3]); + + rtw_bf_cfg_mu_bfee(rtwdev, ¶m); +} + +void rtw_bf_phy_init(struct rtw_dev *rtwdev) +{ + u8 tmp8; + u32 tmp32; + u8 retry_limit = 0xA; + u8 ndpa_rate = 0x10; + u8 ack_policy = 3; + + tmp32 = rtw_read32(rtwdev, REG_MU_TX_CTL); + /* Enable P1 aggr new packet according to P0 transfer time */ + tmp32 |= BIT_MU_P1_WAIT_STATE_EN; + /* MU Retry Limit */ + tmp32 &= ~BIT_MASK_R_MU_RL; + tmp32 |= (retry_limit << BIT_SHIFT_R_MU_RL) & BIT_MASK_R_MU_RL; + /* Disable Tx MU-MIMO until sounding done */ + tmp32 &= ~BIT_EN_MU_MIMO; + /* Clear validity of MU STAs */ + tmp32 &= ~BIT_MASK_R_MU_TABLE_VALID; + rtw_write32(rtwdev, REG_MU_TX_CTL, tmp32); + + /* MU-MIMO Option as default value */ + tmp8 = ack_policy << BIT_SHIFT_WMAC_TXMU_ACKPOLICY; + tmp8 |= BIT_WMAC_TXMU_ACKPOLICY_EN; + rtw_write8(rtwdev, REG_WMAC_MU_BF_OPTION, tmp8); + + /* MU-MIMO Control as default value */ + rtw_write16(rtwdev, REG_WMAC_MU_BF_CTL, 0); + /* Set MU NDPA rate & BW source */ + rtw_write32_set(rtwdev, REG_TXBF_CTRL, BIT_USE_NDPA_PARAMETER); + /* Set NDPA Rate */ + rtw_write8(rtwdev, REG_NDPA_OPT_CTRL, ndpa_rate); + + rtw_write32_mask(rtwdev, REG_BBPSF_CTRL, BIT_MASK_CSI_RATE, + DESC_RATE6M); +} + +void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate) +{ + u32 csi_cfg; + u16 cur_rrsr; + + csi_cfg = rtw_read32(rtwdev, REG_BBPSF_CTRL) & ~BIT_MASK_CSI_RATE; + cur_rrsr = rtw_read16(rtwdev, REG_RRSR); + + if (rssi >= 40) { + if (cur_rate != DESC_RATE54M) { + cur_rrsr |= BIT(DESC_RATE54M); + csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) << + BIT_SHIFT_CSI_RATE; + rtw_write16(rtwdev, REG_RRSR, cur_rrsr); + rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg); + } + *new_rate = DESC_RATE54M; + } else { + if (cur_rate != DESC_RATE24M) { + cur_rrsr &= ~BIT(DESC_RATE54M); + csi_cfg |= (DESC_RATE54M & BIT_MASK_CSI_RATE_VAL) << + BIT_SHIFT_CSI_RATE; + rtw_write16(rtwdev, REG_RRSR, cur_rrsr); + rtw_write32(rtwdev, REG_BBPSF_CTRL, csi_cfg); + } + *new_rate = DESC_RATE24M; + } +} --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/bf.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/bf.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation. + */ + +#ifndef __RTW_BF_H_ +#define __RTW_BF_H_ + +#define REG_TXBF_CTRL 0x042C +#define REG_RRSR 0x0440 +#define REG_NDPA_OPT_CTRL 0x045F + +#define REG_ASSOCIATED_BFMER0_INFO 0x06E4 +#define REG_ASSOCIATED_BFMER1_INFO 0x06EC +#define REG_TX_CSI_RPT_PARAM_BW20 0x06F4 +#define REG_SND_PTCL_CTRL 0x0718 +#define REG_MU_TX_CTL 0x14C0 +#define REG_MU_STA_GID_VLD 0x14C4 +#define REG_MU_STA_USER_POS_INFO 0x14C8 +#define REG_CSI_RRSR 0x1678 +#define REG_WMAC_MU_BF_OPTION 0x167C +#define REG_WMAC_MU_BF_CTL 0x1680 + +#define BIT_WMAC_USE_NDPARATE BIT(30) +#define BIT_WMAC_TXMU_ACKPOLICY_EN BIT(6) +#define BIT_USE_NDPA_PARAMETER BIT(30) +#define BIT_MU_P1_WAIT_STATE_EN BIT(16) +#define BIT_EN_MU_MIMO BIT(7) + +#define R_MU_RL 0xf +#define BIT_SHIFT_R_MU_RL 12 +#define BIT_SHIFT_WMAC_TXMU_ACKPOLICY 4 +#define BIT_SHIFT_CSI_RATE 24 + +#define BIT_MASK_R_MU_RL (R_MU_RL << BIT_SHIFT_R_MU_RL) +#define BIT_MASK_R_MU_TABLE_VALID 0x3f +#define BIT_MASK_CSI_RATE_VAL 0x3F +#define BIT_MASK_CSI_RATE (BIT_MASK_CSI_RATE_VAL << BIT_SHIFT_CSI_RATE) + +#define BIT_RXFLTMAP0_ACTIONNOACK BIT(14) +#define BIT_RXFLTMAP1_BF (BIT(4) | BIT(5)) +#define BIT_RXFLTMAP1_BF_REPORT_POLL BIT(4) +#define BIT_RXFLTMAP4_BF_REPORT_POLL BIT(4) + +#define RTW_NDP_RX_STANDBY_TIME 0x70 +#define RTW_SND_CTRL_REMOVE 0xD8 +#define RTW_SND_CTRL_SOUNDING 0xDB + +enum csi_seg_len { + HAL_CSI_SEG_4K = 0, + HAL_CSI_SEG_8K = 1, + HAL_CSI_SEG_11K = 2, +}; + +struct cfg_mumimo_para { + u8 sounding_sts[6]; + u16 grouping_bitmap; + u8 mu_tx_en; + u32 given_gid_tab[2]; + u32 given_user_pos[4]; +}; + +struct mu_bfer_init_para { + u16 paid; + u16 csi_para; + u16 my_aid; + enum csi_seg_len csi_length_sel; + u8 bfer_address[ETH_ALEN]; +}; + +void rtw_bf_disassoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); +void rtw_bf_assoc(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf); +void rtw_bf_init_bfer_entry_mu(struct rtw_dev *rtwdev, + struct mu_bfer_init_para *param); +void rtw_bf_cfg_sounding(struct rtw_dev *rtwdev, struct rtw_vif *vif, + enum rtw_trx_desc_rate rate); +void rtw_bf_cfg_mu_bfee(struct rtw_dev *rtwdev, struct cfg_mumimo_para *param); +void rtw_bf_del_bfer_entry_mu(struct rtw_dev *rtwdev); +void rtw_bf_del_sounding(struct rtw_dev *rtwdev); +void rtw_bf_enable_bfee_su(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee); +void rtw_bf_enable_bfee_mu(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee); +void rtw_bf_remove_bfee_su(struct rtw_dev *rtwdev, struct rtw_bfee *bfee); +void rtw_bf_remove_bfee_mu(struct rtw_dev *rtwdev, struct rtw_bfee *bfee); +void rtw_bf_set_gid_table(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); +void rtw_bf_phy_init(struct rtw_dev *rtwdev); +void rtw_bf_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate); +static inline void rtw_chip_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (rtwdev->chip->ops->config_bfee) + rtwdev->chip->ops->config_bfee(rtwdev, vif, bfee, enable); +} + +static inline void rtw_chip_set_gid_table(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf) +{ + if (rtwdev->chip->ops->set_gid_table) + rtwdev->chip->ops->set_gid_table(rtwdev, vif, conf); +} + +static inline void rtw_chip_cfg_csi_rate(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate) +{ + if (rtwdev->chip->ops->cfg_csi_rate) + rtwdev->chip->ops->cfg_csi_rate(rtwdev, rssi, cur_rate, + fixrate_en, new_rate); +} +#endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/coex.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/coex.c @@ -383,9 +383,9 @@ u8 rssi_step; u8 rssi; - scan = rtw_flag_check(rtwdev, RTW_FLAG_SCANNING); + scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags); coex_stat->wl_connected = !!rtwdev->sta_cnt; - coex_stat->wl_gl_busy = rtw_flag_check(rtwdev, RTW_FLAG_BUSY_TRAFFIC); + coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); if (stats->tx_throughput > stats->rx_throughput) coex_stat->wl_tput_dir = COEX_WL_TPUT_TX; @@ -748,10 +748,18 @@ static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control) { - if (wifi_control) + struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_hw_reg *btg_reg = chip->btg_reg; + + if (wifi_control) { rtw_write32_set(rtwdev, REG_SYS_SDIO_CTRL, BIT_LTE_MUX_CTRL_PATH); - else + if (btg_reg) + rtw_write8_set(rtwdev, btg_reg->addr, btg_reg->mask); + } else { rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_LTE_MUX_CTRL_PATH); + if (btg_reg) + rtw_write8_clr(rtwdev, btg_reg->addr, btg_reg->mask); + } } static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state) @@ -810,8 +818,6 @@ static void rtw_coex_power_save_state(struct rtw_dev *rtwdev, u8 ps_type, u8 lps_val, u8 rpwm_val) { - struct rtw_lps_conf *lps_conf = &rtwdev->lps_conf; - struct rtw_vif *rtwvif; struct rtw_coex *coex = &rtwdev->coex; struct rtw_coex_stat *coex_stat = &coex->stat; u8 lps_mode = 0x0; @@ -823,18 +829,14 @@ /* recover to original 32k low power setting */ coex_stat->wl_force_lps_ctrl = false; - rtwvif = lps_conf->rtwvif; - if (rtwvif && rtw_in_lps(rtwdev)) - rtw_leave_lps(rtwdev, rtwvif); + rtw_leave_lps(rtwdev); break; case COEX_PS_LPS_OFF: coex_stat->wl_force_lps_ctrl = true; if (lps_mode) rtw_fw_coex_tdma_type(rtwdev, 0x8, 0, 0, 0, 0); - rtwvif = lps_conf->rtwvif; - if (rtwvif && rtw_in_lps(rtwdev)) - rtw_leave_lps(rtwdev, rtwvif); + rtw_leave_lps(rtwdev); break; default: break; @@ -1308,6 +1310,7 @@ struct rtw_chip_info *chip = rtwdev->chip; bool wl_hi_pri = false; u8 table_case, tdma_case; + u32 slot_type = 0; if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 || coex_stat->wl_hi_pri_task2) @@ -1318,14 +1321,16 @@ if (wl_hi_pri) { table_case = 15; if (coex_stat->bt_a2dp_exist && - !coex_stat->bt_pan_exist) + !coex_stat->bt_pan_exist) { + slot_type = TDMA_4SLOT; tdma_case = 11; - else if (coex_stat->wl_hi_pri_task1) + } else if (coex_stat->wl_hi_pri_task1) { tdma_case = 6; - else if (!coex_stat->bt_page) + } else if (!coex_stat->bt_page) { tdma_case = 8; - else + } else { tdma_case = 9; + } } else if (coex_stat->wl_connected) { table_case = 10; tdma_case = 10; @@ -1346,12 +1351,15 @@ tdma_case = 108; else tdma_case = 109; + } else if (coex_stat->wl_gl_busy) { + table_case = 114; + tdma_case = 121; } else if (coex_stat->wl_connected) { - table_case = 101; - tdma_case = 110; - } else { table_case = 100; tdma_case = 100; + } else { + table_case = 101; + tdma_case = 100; } } @@ -1361,7 +1369,7 @@ rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G); rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); rtw_coex_table(rtwdev, table_case); - rtw_coex_tdma(rtwdev, false, tdma_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); } static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev) @@ -1475,13 +1483,13 @@ if (efuse->share_ant) { /* Shared-Ant */ + slot_type = TDMA_4SLOT; + if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0) table_case = 10; else table_case = 9; - slot_type = TDMA_4SLOT; - if (coex_stat->wl_gl_busy) tdma_case = 13; else @@ -1585,13 +1593,14 @@ if (efuse->share_ant) { /* Shared-Ant */ + slot_type = TDMA_4SLOT; + if (coex_stat->bt_ble_exist) table_case = 26; else table_case = 9; if (coex_stat->wl_gl_busy) { - slot_type = TDMA_4SLOT; tdma_case = 13; } else { tdma_case = 14; @@ -1794,10 +1803,12 @@ struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_chip_info *chip = rtwdev->chip; u8 table_case, tdma_case; + u32 slot_type = 0; if (efuse->share_ant) { /* Shared-Ant */ if (coex_stat->bt_a2dp_exist) { + slot_type = TDMA_4SLOT; table_case = 9; tdma_case = 11; } else { @@ -1818,7 +1829,7 @@ rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G); rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]); rtw_coex_table(rtwdev, table_case); - rtw_coex_tdma(rtwdev, false, tdma_case); + rtw_coex_tdma(rtwdev, false, tdma_case | slot_type); } static void rtw_coex_action_wl_not_connected(struct rtw_dev *rtwdev) @@ -1904,6 +1915,9 @@ lockdep_assert_held(&rtwdev->mutex); + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + return; + coex_dm->reason = reason; /* update wifi_link_info_ext variable */ @@ -1917,7 +1931,8 @@ if (coex_stat->wl_under_ips) return; - if (coex->freeze && !coex_stat->bt_setup_link) + if (coex->freeze && coex_dm->reason == COEX_RSN_BTINFO && + !coex_stat->bt_setup_link) return; coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN]++; @@ -2500,3 +2515,495 @@ rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS); mutex_unlock(&rtwdev->mutex); } + +#ifdef CONFIG_RTW88_DEBUGFS +#define INFO_SIZE 80 + +#define case_BTINFO(src) \ + case COEX_BTINFO_SRC_##src: return #src + +static const char *rtw_coex_get_bt_info_src_string(u8 bt_info_src) +{ + switch (bt_info_src) { + case_BTINFO(WL_FW); + case_BTINFO(BT_RSP); + case_BTINFO(BT_ACT); + default: + return "Unknown"; + } +} + +#define case_RSN(src) \ + case COEX_RSN_##src: return #src + +static const char *rtw_coex_get_reason_string(u8 reason) +{ + switch (reason) { + case_RSN(2GSCANSTART); + case_RSN(5GSCANSTART); + case_RSN(SCANFINISH); + case_RSN(2GSWITCHBAND); + case_RSN(5GSWITCHBAND); + case_RSN(2GCONSTART); + case_RSN(5GCONSTART); + case_RSN(2GCONFINISH); + case_RSN(5GCONFINISH); + case_RSN(2GMEDIA); + case_RSN(5GMEDIA); + case_RSN(MEDIADISCON); + case_RSN(BTINFO); + case_RSN(LPS); + case_RSN(WLSTATUS); + default: + return "Unknown"; + } +} + +static int rtw_coex_addr_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char addr_info[], int n) +{ + const char *rf_prefix = ""; + const char *sep = n == 0 ? "" : "/ "; + int ffs, fls; + int max_fls; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + max_fls = 31; + break; + case RTW_REG_DOMAIN_MAC16: + max_fls = 15; + break; + case RTW_REG_DOMAIN_MAC8: + max_fls = 7; + break; + case RTW_REG_DOMAIN_RF_A: + case RTW_REG_DOMAIN_RF_B: + rf_prefix = "RF_"; + max_fls = 19; + break; + default: + return 0; + } + + ffs = __ffs(reg->mask); + fls = __fls(reg->mask); + + if (ffs == 0 && fls == max_fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x", + sep, rf_prefix, reg->addr); + else if (ffs == fls) + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d]", + sep, rf_prefix, reg->addr, ffs); + else + return scnprintf(addr_info + n, INFO_SIZE - n, "%s%s%x[%d:%d]", + sep, rf_prefix, reg->addr, fls, ffs); +} + +static int rtw_coex_val_info(struct rtw_dev *rtwdev, + const struct rtw_reg_domain *reg, + char val_info[], int n) +{ + const char *sep = n == 0 ? "" : "/ "; + u8 rf_path; + + if (INFO_SIZE - n <= 0) + return 0; + + switch (reg->domain) { + case RTW_REG_DOMAIN_MAC32: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read32_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC16: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read16_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_MAC8: + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read8_mask(rtwdev, reg->addr, reg->mask)); + case RTW_REG_DOMAIN_RF_A: + rf_path = RF_PATH_A; + break; + case RTW_REG_DOMAIN_RF_B: + rf_path = RF_PATH_B; + break; + default: + return 0; + } + + /* only RF go through here */ + return scnprintf(val_info + n, INFO_SIZE - n, "%s0x%x", sep, + rtw_read_rf(rtwdev, rf_path, reg->addr, reg->mask)); +} + +static void rtw_coex_set_coexinfo_hw(struct rtw_dev *rtwdev, struct seq_file *m) +{ + struct rtw_chip_info *chip = rtwdev->chip; + const struct rtw_reg_domain *reg; + char addr_info[INFO_SIZE]; + int n_addr = 0; + char val_info[INFO_SIZE]; + int n_val = 0; + int i; + + for (i = 0; i < chip->coex_info_hw_regs_num; i++) { + reg = &chip->coex_info_hw_regs[i]; + + n_addr += rtw_coex_addr_info(rtwdev, reg, addr_info, n_addr); + n_val += rtw_coex_val_info(rtwdev, reg, val_info, n_val); + + if (reg->domain == RTW_REG_DOMAIN_NL) { + seq_printf(m, "%-40s = %s\n", addr_info, val_info); + n_addr = 0; + n_val = 0; + } + } + + if (n_addr != 0 && n_val != 0) + seq_printf(m, "%-40s = %s\n", addr_info, val_info); +} + +static bool rtw_coex_get_bt_reg(struct rtw_dev *rtwdev, + u8 type, u16 addr, u16 *val) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + __le16 le_addr; + u8 *payload; + + le_addr = cpu_to_le16(addr); + req.op_code = BT_MP_INFO_OP_READ_REG; + req.para1 = type; + req.para2 = le16_get_bits(le_addr, GENMASK(7, 0)); + req.para3 = le16_get_bits(le_addr, GENMASK(15, 8)); + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) { + *val = 0xeaea; + return false; + } + + payload = get_payload_from_coex_resp(skb); + *val = GET_COEX_RESP_BT_REG_VAL(payload); + + return true; +} + +static bool rtw_coex_get_bt_patch_version(struct rtw_dev *rtwdev, + u32 *patch_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_PATCH_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *patch_version = GET_COEX_RESP_BT_PATCH_VER(payload); + ret = true; + +out: + return ret; +} + +static bool rtw_coex_get_bt_supported_version(struct rtw_dev *rtwdev, + u32 *supported_version) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_SUPP_VER; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *supported_version = GET_COEX_RESP_BT_SUPP_VER(payload); + ret = true; + +out: + return ret; +} + +static bool rtw_coex_get_bt_supported_feature(struct rtw_dev *rtwdev, + u32 *supported_feature) +{ + struct rtw_coex_info_req req = {0}; + struct sk_buff *skb; + u8 *payload; + bool ret = false; + + req.op_code = BT_MP_INFO_OP_SUPP_FEAT; + skb = rtw_coex_info_request(rtwdev, &req); + if (!skb) + goto out; + + payload = get_payload_from_coex_resp(skb); + *supported_feature = GET_COEX_RESP_BT_SUPP_FEAT(payload); + ret = true; + +out: + return ret; +} + +struct rtw_coex_sta_stat_iter_data { + struct rtw_vif *rtwvif; + struct seq_file *file; +}; + +static void rtw_coex_sta_stat_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_coex_sta_stat_iter_data *sta_iter_data = data; + struct rtw_vif *rtwvif = sta_iter_data->rtwvif; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct seq_file *m = sta_iter_data->file; + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 rssi; + + if (si->vif != vif) + return; + + rssi = ewma_rssi_read(&si->avg_rssi); + seq_printf(m, "\tPeer %3d\n", si->mac_id); + seq_printf(m, "\t\t%-24s = %d\n", "RSSI", rssi); + seq_printf(m, "\t\t%-24s = %d\n", "BW mode", si->bw_mode); +} + +struct rtw_coex_vif_stat_iter_data { + struct rtw_dev *rtwdev; + struct seq_file *file; +}; + +static void rtw_coex_vif_stat_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_coex_vif_stat_iter_data *vif_iter_data = data; + struct rtw_coex_sta_stat_iter_data sta_iter_data; + struct rtw_dev *rtwdev = vif_iter_data->rtwdev; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct seq_file *m = vif_iter_data->file; + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + + seq_printf(m, "Iface on Port (%d)\n", rtwvif->port); + seq_printf(m, "\t%-32s = %d\n", + "Beacon interval", bss_conf->beacon_int); + seq_printf(m, "\t%-32s = %d\n", + "Network Type", rtwvif->net_type); + + sta_iter_data.rtwvif = rtwvif; + sta_iter_data.file = m; + rtw_iterate_stas_atomic(rtwdev, rtw_coex_sta_stat_iter, + &sta_iter_data); +} + +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_coex_vif_stat_iter_data vif_iter_data; + u8 reason = coex_dm->reason; + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; + u32 lte_coex, bt_coex; + u32 bt_hi_pri, bt_lo_pri; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); + score_board_WB = coex_stat->score_board; + wl_reg_6c0 = rtw_read32(rtwdev, 0x6c0); + wl_reg_6c4 = rtw_read32(rtwdev, 0x6c4); + wl_reg_6c8 = rtw_read32(rtwdev, 0x6c8); + wl_reg_6cc = rtw_read32(rtwdev, 0x6cc); + wl_reg_778 = rtw_read32(rtwdev, 0x778); + bt_hi_pri = rtw_read32(rtwdev, 0x770); + bt_lo_pri = rtw_read32(rtwdev, 0x774); + rtw_write8(rtwdev, 0x76e, 0xc); + sys_lte = rtw_read8(rtwdev, 0x73); + lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); + bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); + + if (!coex_stat->bt_disabled && !coex_stat->bt_mailbox_reply) { + rtw_coex_get_bt_supported_version(rtwdev, + &coex_stat->bt_supported_version); + rtw_coex_get_bt_patch_version(rtwdev, &coex_stat->patch_ver); + rtw_coex_get_bt_supported_feature(rtwdev, + &coex_stat->bt_supported_feature); + rtw_coex_get_bt_reg(rtwdev, 3, 0xae, &coex_stat->bt_reg_vendor_ae); + rtw_coex_get_bt_reg(rtwdev, 3, 0xac, &coex_stat->bt_reg_vendor_ac); + + if (coex_stat->patch_ver != 0) + coex_stat->bt_mailbox_reply = true; + } + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Coexist info %x\n", chip->id); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %d\n", + "Mech/ RFE", + efuse->share_ant ? "Shared" : "Non-Shared", + efuse->rfe_option); + seq_printf(m, "%-40s = %08x/ 0x%02x/ 0x%08x %s\n", + "Coex Ver/ BT Dez/ BT Rpt", + chip->coex_para_ver, chip->bt_desired_ver, + coex_stat->bt_supported_version, + coex_stat->bt_disabled ? "(BT disabled)" : + coex_stat->bt_supported_version >= chip->bt_desired_ver ? + "(Match)" : "(Mismatch)"); + seq_printf(m, "%-40s = %s/ %u/ %d\n", + "Role/ RoleSwCnt/ IgnWL/ Feature", + coex_stat->bt_slave ? "Slave" : "Master", + coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH], + coex_dm->ignore_wl_act); + seq_printf(m, "%-40s = %u.%u/ 0x%x/ %c\n", + "WL FW/ BT FW/ KT", + fw->version, fw->sub_version, + coex_stat->patch_ver, coex_stat->kt_ver + 65); + seq_printf(m, "%-40s = %u/ %u/ %u/ ch-(%u)\n", + "AFH Map", + coex_dm->wl_ch_info[0], coex_dm->wl_ch_info[1], + coex_dm->wl_ch_info[2], hal->current_channel); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tBT Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %ddBm/ %u/ %u\n", + "BT status/ rssi/ retry/ pop", + coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ? "non-conn" : + coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE ? "conn-idle" : "busy", + coex_stat->bt_rssi - 100, + coex_stat->cnt_bt[COEX_CNT_BT_RETRY], + coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]); + seq_printf(m, "%-40s = %s%s%s%s%s (multi-link %d)\n", + "Profiles", + coex_stat->bt_a2dp_exist ? (coex_stat->bt_a2dp_sink ? + "A2DP sink," : "A2DP,") : "", + coex_stat->bt_hfp_exist ? "HFP," : "", + coex_stat->bt_hid_exist ? + (coex_stat->bt_ble_exist ? "HID(RCU)," : + coex_stat->bt_hid_slot >= 2 ? "HID(4/18)" : + "HID(2/18),") : "", + coex_stat->bt_pan_exist ? coex_stat->bt_opp_exist ? + "OPP," : "PAN," : "", + coex_stat->bt_ble_voice ? "Voice," : "", + coex_stat->bt_multi_link); + seq_printf(m, "%-40s = %u/ %u/ %u/ 0x%08x\n", + "Reinit/ Relink/ IgnWl/ Feature", + coex_stat->cnt_bt[COEX_CNT_BT_REINIT], + coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK], + coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT], + coex_stat->bt_supported_feature); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "Page/ Inq/ iqk/ iqk fail", + coex_stat->cnt_bt[COEX_CNT_BT_PAGE], + coex_stat->cnt_bt[COEX_CNT_BT_INQ], + coex_stat->cnt_bt[COEX_CNT_BT_IQK], + coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]); + seq_printf(m, "%-40s = 0x%04x/ 0x%04x/ 0x%04x/ 0x%04x\n", + "0xae/ 0xac/ score board (W->B)/ (B->W)", + coex_stat->bt_reg_vendor_ae, + coex_stat->bt_reg_vendor_ac, + score_board_WB, score_board_BW); + seq_printf(m, "%-40s = %u/%u, %u/%u\n", + "Hi-Pri TX/RX, Lo-Pri TX/RX", + bt_hi_pri & 0xffff, bt_hi_pri >> 16, + bt_lo_pri & 0xffff, bt_lo_pri >> 16); + for (i = 0; i < COEX_BTINFO_SRC_BT_IQK; i++) + seq_printf(m, "%-40s = %7ph\n", + rtw_coex_get_bt_info_src_string(i), + coex_stat->bt_info_c2h[i]); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tWiFi Status\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %d\n", + "Scanning", test_bit(RTW_FLAG_SCANNING, rtwdev->flags)); + seq_printf(m, "%-40s = %u/ TX %d Mbps/ RX %d Mbps\n", + "G_busy/ TX/ RX", + coex_stat->wl_gl_busy, + rtwdev->stats.tx_throughput, rtwdev->stats.rx_throughput); + seq_printf(m, "%-40s = %u/ %u/ %u\n", + "IPS/ Low Power/ PS mode", + test_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags), + test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags), + rtwdev->lps_conf.mode); + + vif_iter_data.rtwdev = rtwdev; + vif_iter_data.file = m; + rtw_iterate_vifs_atomic(rtwdev, rtw_coex_vif_stat_iter, &vif_iter_data); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tMechanism\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %5ph (case-%d)\n", + "TDMA", + coex_dm->ps_tdma_para, coex_dm->cur_ps_tdma); + seq_printf(m, "%-40s = %d\n", + "Timer base", coex_stat->tdma_timer_base); + seq_printf(m, "%-40s = %d/ 0x%08x/ 0x%08x/ 0x%08x\n", + "Table/ 0x6c0/ 0x6c4/ 0x6c8", + coex_dm->cur_table, wl_reg_6c0, wl_reg_6c4, wl_reg_6c8); + seq_printf(m, "%-40s = 0x%08x/ 0x%08x/ reason (%s)\n", + "0x778/ 0x6cc/ Reason", + wl_reg_778, wl_reg_6cc, rtw_coex_get_reason_string(reason)); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u/ %u\n", + "Null All/ Retry/ Ack/ BT Empty/ BT Late", + coex_stat->wl_fw_dbg_info[1], coex_stat->wl_fw_dbg_info[2], + coex_stat->wl_fw_dbg_info[3], coex_stat->wl_fw_dbg_info[4], + coex_stat->wl_fw_dbg_info[5]); + seq_printf(m, "%-40s = %u/ %u/ %s/ %u\n", + "Cnt TDMA Toggle/ Lk 5ms/ Lk 5ms on/ FW", + coex_stat->wl_fw_dbg_info[6], + coex_stat->wl_fw_dbg_info[7], + coex_stat->wl_slot_extend ? "Yes" : "No", + coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]); + + seq_printf(m, "**********************************************\n"); + seq_printf(m, "\t\tHW setting\n"); + seq_printf(m, "**********************************************\n"); + seq_printf(m, "%-40s = %s/ %s\n", + "LTE Coex/ Path Owner", + lte_coex & BIT(7) ? "ON" : "OFF", + sys_lte & BIT(2) ? "WL" : "BT"); + seq_printf(m, "%-40s = RF:%s_BB:%s/ RF:%s_BB:%s/ %s\n", + "GNT_WL_CTRL/ GNT_BT_CTRL/ Dbg", + lte_coex & BIT(12) ? "SW" : "HW", + lte_coex & BIT(8) ? "SW" : "HW", + lte_coex & BIT(14) ? "SW" : "HW", + lte_coex & BIT(10) ? "SW" : "HW", + sys_lte & BIT(3) ? "On" : "Off"); + seq_printf(m, "%-40s = %lu/ %lu\n", + "GNT_WL/ GNT_BT", + (bt_coex & BIT(2)) >> 2, (bt_coex & BIT(3)) >> 3); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC OK CCK/ OFDM/ HT/ VHT", + dm_info->cck_ok_cnt, dm_info->ofdm_ok_cnt, + dm_info->ht_ok_cnt, dm_info->vht_ok_cnt); + seq_printf(m, "%-40s = %u/ %u/ %u/ %u\n", + "CRC ERR CCK/ OFDM/ HT/ VHT", + dm_info->cck_err_cnt, dm_info->ofdm_err_cnt, + dm_info->ht_err_cnt, dm_info->vht_err_cnt); + seq_printf(m, "%-40s = %s/ %s/ %s/ %u\n", + "HiPr/ Locking/ Locked/ Noisy", + coex_stat->wl_hi_pri_task1 ? "Y" : "N", + coex_stat->wl_cck_lock ? "Y" : "N", + coex_stat->wl_cck_lock_ever ? "Y" : "N", + coex_stat->wl_noisy_level); + + rtw_coex_set_coexinfo_hw(rtwdev, m); +} +#endif /* CONFIG_RTW88_DEBUGFS */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/coex.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/coex.h @@ -46,6 +46,14 @@ (__rssi__ == COEX_RSSI_STATE_LOW || \ __rssi__ == COEX_RSSI_STATE_STAY_LOW ? true : false); }) +#define GET_COEX_RESP_BT_SUPP_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 32)) +#define GET_COEX_RESP_BT_SUPP_FEAT(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) +#define GET_COEX_RESP_BT_PATCH_VER(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(55, 24)) +#define GET_COEX_RESP_BT_REG_VAL(payload) \ + le64_get_bits(*((__le64 *)(payload)), GENMASK_ULL(39, 24)) #define GET_COEX_RESP_BT_SCAN_TYPE(payload) \ le64_get_bits(*((__le64 *)(payload)), GENMASK(31, 24)) @@ -367,4 +375,6 @@ void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type); void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev); +void rtw_coex_display_coex_info(struct rtw_dev *rtwdev, struct seq_file *m); + #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/debug.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/debug.c @@ -5,10 +5,12 @@ #include #include #include "main.h" +#include "coex.h" #include "sec.h" #include "fw.h" #include "debug.h" #include "phy.h" +#include "sar.h" #ifdef CONFIG_RTW88_DEBUGFS @@ -146,6 +148,8 @@ { int tmp_len; + memset(tmp, 0, size); + if (count < num) return -EFAULT; @@ -498,20 +502,40 @@ seq_printf(m, " VHT%uSMCS%u", n_ss, mcs_n); } +static void rtw_print_rate(struct seq_file *m, u8 rate) +{ + switch (rate) { + case DESC_RATE1M...DESC_RATE11M: + rtw_print_cck_rate_txt(m, rate); + break; + case DESC_RATE6M...DESC_RATE54M: + rtw_print_ofdm_rate_txt(m, rate); + break; + case DESC_RATEMCS0...DESC_RATEMCS15: + rtw_print_ht_rate_txt(m, rate); + break; + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: + rtw_print_vht_rate_txt(m, rate); + break; + default: + seq_printf(m, " Unknown rate=0x%x\n", rate); + break; + } +} + static int rtw_debugfs_get_tx_pwr_tbl(struct seq_file *m, void *v) { struct rtw_debugfs_priv *debugfs_priv = m->private; struct rtw_dev *rtwdev = debugfs_priv->rtwdev; struct rtw_hal *hal = &rtwdev->hal; - void (*print_rate)(struct seq_file *, u8) = NULL; u8 path, rate; struct rtw_power_params pwr_param = {0}; u8 bw = hal->current_band_width; u8 ch = hal->current_channel; u8 regd = rtwdev->regd.txpwr_regd; - seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s)\n", - "path", "rate", "pwr", "", "base", "", "byr", "lmt"); + seq_printf(m, "%-4s %-10s %-3s%6s %-4s %4s (%-4s %-4s %-4s %-4s)\n", + "path", "rate", "pwr", "", "base", "", "byr", "lmt", "sar", "rem"); mutex_lock(&hal->tx_power_mutex); for (path = RF_PATH_A; path <= RF_PATH_B; path++) { @@ -528,37 +552,20 @@ rate < DESC_RATEVHT1SS_MCS0) continue; - switch (rate) { - case DESC_RATE1M...DESC_RATE11M: - print_rate = rtw_print_cck_rate_txt; - break; - case DESC_RATE6M...DESC_RATE54M: - print_rate = rtw_print_ofdm_rate_txt; - break; - case DESC_RATEMCS0...DESC_RATEMCS15: - print_rate = rtw_print_ht_rate_txt; - break; - case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT2SS_MCS9: - print_rate = rtw_print_vht_rate_txt; - break; - default: - print_rate = NULL; - break; - } - rtw_get_tx_power_params(rtwdev, path, rate, bw, ch, regd, &pwr_param); seq_printf(m, "%4c ", path + 'A'); - if (print_rate) - print_rate(m, rate); - seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d)\n", + rtw_print_rate(m, rate); + seq_printf(m, " %3u(0x%02x) %4u %4d (%4d %4d %4d %4d)\n", hal->tx_pwr_tbl[path][rate], hal->tx_pwr_tbl[path][rate], pwr_param.pwr_base, - min_t(s8, pwr_param.pwr_offset, - pwr_param.pwr_limit), - pwr_param.pwr_offset, pwr_param.pwr_limit); + min3(pwr_param.pwr_offset, + pwr_param.pwr_limit, + pwr_param.pwr_sar), + pwr_param.pwr_offset, pwr_param.pwr_limit, + pwr_param.pwr_sar, pwr_param.pwr_remnant); } } @@ -567,6 +574,208 @@ return 0; } +static int rtw_debugfs_get_phy_info(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_pkt_count *last_cnt = &dm_info->last_pkt_count; + struct rtw_efuse *efuse = &rtwdev->efuse; + struct ewma_evm *ewma_evm = dm_info->ewma_evm; + struct ewma_snr *ewma_snr = dm_info->ewma_snr; + u8 ss, rate_id; + + seq_puts(m, "==========[Common Info]========\n"); + seq_printf(m, "Is link = %c\n", rtw_is_assoc(rtwdev) ? 'Y' : 'N'); + seq_printf(m, "Current CH(fc) = %u\n", rtwdev->hal.current_channel); + seq_printf(m, "Current BW = %u\n", rtwdev->hal.current_band_width); + seq_printf(m, "Current IGI = 0x%x\n", dm_info->igi_history[0]); + seq_printf(m, "TP {Tx, Rx} = {%u, %u}Mbps\n\n", + stats->tx_throughput, stats->rx_throughput); + + seq_puts(m, "==========[Tx Phy Info]========\n"); + seq_puts(m, "[Tx Rate] = "); + rtw_print_rate(m, dm_info->tx_rate); + seq_printf(m, "(0x%x)\n\n", dm_info->tx_rate); + + seq_puts(m, "==========[Rx Phy Info]========\n"); + seq_printf(m, "[Rx Beacon Count] = %u\n", last_cnt->num_bcn_pkt); + seq_puts(m, "[Rx Rate] = "); + rtw_print_rate(m, dm_info->curr_rx_rate); + seq_printf(m, "(0x%x)\n", dm_info->curr_rx_rate); + + seq_puts(m, "[Rx Rate Count]:\n"); + seq_printf(m, " * CCK = {%u, %u, %u, %u}\n", + last_cnt->num_qry_pkt[DESC_RATE1M], + last_cnt->num_qry_pkt[DESC_RATE2M], + last_cnt->num_qry_pkt[DESC_RATE5_5M], + last_cnt->num_qry_pkt[DESC_RATE11M]); + + seq_printf(m, " * OFDM = {%u, %u, %u, %u, %u, %u, %u, %u}\n", + last_cnt->num_qry_pkt[DESC_RATE6M], + last_cnt->num_qry_pkt[DESC_RATE9M], + last_cnt->num_qry_pkt[DESC_RATE12M], + last_cnt->num_qry_pkt[DESC_RATE18M], + last_cnt->num_qry_pkt[DESC_RATE24M], + last_cnt->num_qry_pkt[DESC_RATE36M], + last_cnt->num_qry_pkt[DESC_RATE48M], + last_cnt->num_qry_pkt[DESC_RATE54M]); + + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { + rate_id = DESC_RATEMCS0 + ss * 8; + seq_printf(m, " * HT_MCS[%u:%u] = {%u, %u, %u, %u, %u, %u, %u, %u}\n", + ss * 8, ss * 8 + 7, + last_cnt->num_qry_pkt[rate_id], + last_cnt->num_qry_pkt[rate_id + 1], + last_cnt->num_qry_pkt[rate_id + 2], + last_cnt->num_qry_pkt[rate_id + 3], + last_cnt->num_qry_pkt[rate_id + 4], + last_cnt->num_qry_pkt[rate_id + 5], + last_cnt->num_qry_pkt[rate_id + 6], + last_cnt->num_qry_pkt[rate_id + 7]); + } + + for (ss = 0; ss < efuse->hw_cap.nss; ss++) { + rate_id = DESC_RATEVHT1SS_MCS0 + ss * 10; + seq_printf(m, " * VHT_MCS-%uss MCS[0:9] = {%u, %u, %u, %u, %u, %u, %u, %u, %u, %u}\n", + ss + 1, + last_cnt->num_qry_pkt[rate_id], + last_cnt->num_qry_pkt[rate_id + 1], + last_cnt->num_qry_pkt[rate_id + 2], + last_cnt->num_qry_pkt[rate_id + 3], + last_cnt->num_qry_pkt[rate_id + 4], + last_cnt->num_qry_pkt[rate_id + 5], + last_cnt->num_qry_pkt[rate_id + 6], + last_cnt->num_qry_pkt[rate_id + 7], + last_cnt->num_qry_pkt[rate_id + 8], + last_cnt->num_qry_pkt[rate_id + 9]); + } + + seq_printf(m, "[RSSI(dBm)] = {%d, %d}\n", + dm_info->rssi[RF_PATH_A] - 100, + dm_info->rssi[RF_PATH_B] - 100); + seq_printf(m, "[Rx EVM(dB)] = {-%d, -%d}\n", + dm_info->rx_evm_dbm[RF_PATH_A], + dm_info->rx_evm_dbm[RF_PATH_B]); + seq_printf(m, "[Rx SNR] = {%d, %d}\n", + dm_info->rx_snr[RF_PATH_A], + dm_info->rx_snr[RF_PATH_B]); + seq_printf(m, "[CFO_tail(KHz)] = {%d, %d}\n", + dm_info->cfo_tail[RF_PATH_A], + dm_info->cfo_tail[RF_PATH_B]); + + if (dm_info->curr_rx_rate >= DESC_RATE11M) { + seq_puts(m, "[Rx Average Status]:\n"); + seq_printf(m, " * OFDM, EVM: {-%d}, SNR: {%d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_OFDM]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_OFDM_A])); + seq_printf(m, " * 1SS, EVM: {-%d}, SNR: {%d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_1SS]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_1SS_A])); + seq_printf(m, " * 2SS, EVM: {-%d, -%d}, SNR: {%d, %d}\n", + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_A]), + (u8)ewma_evm_read(&ewma_evm[RTW_EVM_2SS_B]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_A]), + (u8)ewma_snr_read(&ewma_snr[RTW_SNR_2SS_B])); + } + + seq_puts(m, "[Rx Counter]:\n"); + seq_printf(m, " * CCA (CCK, OFDM, Total) = (%u, %u, %u)\n", + dm_info->cck_cca_cnt, + dm_info->ofdm_cca_cnt, + dm_info->total_cca_cnt); + seq_printf(m, " * False Alarm (CCK, OFDM, Total) = (%u, %u, %u)\n", + dm_info->cck_fa_cnt, + dm_info->ofdm_fa_cnt, + dm_info->total_fa_cnt); + seq_printf(m, " * CCK cnt (ok, err) = (%u, %u)\n", + dm_info->cck_ok_cnt, dm_info->cck_err_cnt); + seq_printf(m, " * OFDM cnt (ok, err) = (%u, %u)\n", + dm_info->ofdm_ok_cnt, dm_info->ofdm_err_cnt); + seq_printf(m, " * HT cnt (ok, err) = (%u, %u)\n", + dm_info->ht_ok_cnt, dm_info->ht_err_cnt); + seq_printf(m, " * VHT cnt (ok, err) = (%u, %u)\n", + dm_info->vht_ok_cnt, dm_info->vht_err_cnt); + + return 0; +} + +static int rtw_debugfs_get_coex_info(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + rtw_coex_display_coex_info(rtwdev, m); + + return 0; +} + +static ssize_t rtw_debugfs_set_coex_enable(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct seq_file *seqpriv = (struct seq_file *)filp->private_data; + struct rtw_debugfs_priv *debugfs_priv = seqpriv->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + char tmp[32 + 1]; + bool enable; + int ret; + + rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); + + ret = kstrtobool(tmp, &enable); + if (ret) { + rtw_warn(rtwdev, "invalid arguments\n"); + return ret; + } + + mutex_lock(&rtwdev->mutex); + coex->stop_dm = enable == 0; + mutex_unlock(&rtwdev->mutex); + + return count; +} + +static int rtw_debugfs_get_coex_enable(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + struct rtw_coex *coex = &rtwdev->coex; + + seq_printf(m, "coex mechanism %s\n", + coex->stop_dm ? "disabled" : "enabled"); + + return 0; +} + +static ssize_t rtw_debugfs_set_edcca_enable(struct file *filp, + const char __user *buffer, + size_t count, loff_t *loff) +{ + struct rtw_debugfs_priv *debugfs_priv = filp->private_data; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + char tmp[32 + 1]; + + rtw_debugfs_copy_from_user(tmp, sizeof(tmp), buffer, count, 1); + + kstrtobool(tmp, &rtw_edcca_enabled); + rtw_phy_adaptivity_set_mode(rtwdev); + + return count; +} + +static int rtw_debugfs_get_sar(struct seq_file *m, void *v) +{ + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; + + rtw_sar_dump_via_debugfs(rtwdev, m); + + return 0; +} + #define rtw_debug_impl_mac(page, addr) \ static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ .cb_read = rtw_debug_get_mac_page, \ @@ -653,12 +862,33 @@ .cb_read = rtw_debugfs_get_rsvd_page, }; +static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { + .cb_read = rtw_debugfs_get_phy_info, +}; + +static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { + .cb_write = rtw_debugfs_set_coex_enable, + .cb_read = rtw_debugfs_get_coex_enable, +}; + +static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { + .cb_read = rtw_debugfs_get_coex_info, +}; + +static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { + .cb_write = rtw_debugfs_set_edcca_enable, +}; + +static struct rtw_debugfs_priv rtw_debug_priv_sar = { + .cb_read = rtw_debugfs_get_sar, +}; + #define rtw_debugfs_add_core(name, mode, fopname, parent) \ do { \ rtw_debug_priv_ ##name.rtwdev = rtwdev; \ - if (!debugfs_create_file(#name, mode, \ + if (IS_ERR(debugfs_create_file(#name, mode, \ parent, &rtw_debug_priv_ ##name,\ - &file_ops_ ##fopname)) \ + &file_ops_ ##fopname))) \ pr_debug("Unable to initialize debugfs:%s\n", \ #name); \ } while (0) @@ -682,6 +912,10 @@ rtw_debugfs_add_rw(rf_read); rtw_debugfs_add_rw(dump_cam); rtw_debugfs_add_rw(rsvd_page); + rtw_debugfs_add_r(phy_info); + rtw_debugfs_add_r(coex_info); + rtw_debugfs_add_rw(coex_enable); + rtw_debugfs_add_r(sar); rtw_debugfs_add_r(mac_0); rtw_debugfs_add_r(mac_1); rtw_debugfs_add_r(mac_2); @@ -722,6 +956,7 @@ } rtw_debugfs_add_r(rf_dump); rtw_debugfs_add_r(tx_pwr_tbl); + rtw_debugfs_add_w(edcca_enable); } #endif /* CONFIG_RTW88_DEBUGFS */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/debug.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/debug.h @@ -16,6 +16,9 @@ RTW_DBG_RFK = 0x00000080, RTW_DBG_REGD = 0x00000100, RTW_DBG_DEBUGFS = 0x00000200, + RTW_DBG_PS = 0x00000400, + RTW_DBG_BF = 0x00000800, + RTW_DBG_WOW = 0x00001000, RTW_DBG_ALL = 0xffffffff }; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/efuse.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/efuse.c @@ -90,6 +90,8 @@ u32 addr; u32 cnt; + rtw_chip_efuse_grant_on(rtwdev); + switch_efuse_bank(rtwdev); /* disable 2.5V LDO */ @@ -113,6 +115,8 @@ *(map + addr) = (u8)(efuse_ctl & BIT_MASK_EF_DATA); } + rtw_chip_efuse_grant_off(rtwdev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/fw.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/fw.c @@ -7,7 +7,10 @@ #include "fw.h" #include "tx.h" #include "reg.h" +#include "sec.h" #include "debug.h" +#include "util.h" +#include "wow.h" static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, struct sk_buff *skb) @@ -20,13 +23,107 @@ switch (sub_cmd_id) { case C2H_CCX_RPT: - rtw_tx_report_handle(rtwdev, skb); + rtw_tx_report_handle(rtwdev, skb, C2H_CCX_RPT); break; default: break; } } +static u16 get_max_amsdu_len(u32 bit_rate) +{ + /* lower than ofdm, do not aggregate */ + if (bit_rate < 550) + return 1; + + /* lower than 20M 2ss mcs8, make it small */ + if (bit_rate < 1800) + return 1200; + + /* lower than 40M 2ss mcs9, make it medium */ + if (bit_rate < 4000) + return 2600; + + /* not yet 80M 2ss mcs8/9, make it twice regular packet size */ + if (bit_rate < 7000) + return 3500; + + /* unlimited */ + return 0; +} + +struct rtw_fw_iter_ra_data { + struct rtw_dev *rtwdev; + u8 *payload; +}; + +static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_fw_iter_ra_data *ra_data = data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + u8 mac_id, rate, sgi, bw; + u8 mcs, nss; + u32 bit_rate; + + mac_id = GET_RA_REPORT_MACID(ra_data->payload); + if (si->mac_id != mac_id) + return; + + si->ra_report.txrate.flags = 0; + + rate = GET_RA_REPORT_RATE(ra_data->payload); + sgi = GET_RA_REPORT_SGI(ra_data->payload); + bw = GET_RA_REPORT_BW(ra_data->payload); + + if (rate < DESC_RATEMCS0) { + si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); + goto legacy; + } + + rtw_desc_to_mcsrate(rate, &mcs, &nss); + if (rate >= DESC_RATEVHT1SS_MCS0) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_VHT_MCS; + else if (rate >= DESC_RATEMCS0) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_MCS; + + if (rate >= DESC_RATEMCS0) { + si->ra_report.txrate.mcs = mcs; + si->ra_report.txrate.nss = nss; + } + + if (sgi) + si->ra_report.txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; + + if (bw == RTW_CHANNEL_WIDTH_80) + si->ra_report.txrate.bw = RATE_INFO_BW_80; + else if (bw == RTW_CHANNEL_WIDTH_40) + si->ra_report.txrate.bw = RATE_INFO_BW_40; + else + si->ra_report.txrate.bw = RATE_INFO_BW_20; + +legacy: + bit_rate = cfg80211_calculate_bitrate(&si->ra_report.txrate); + + si->ra_report.desc_rate = rate; + si->ra_report.bit_rate = bit_rate; + + sta->max_rc_amsdu_len = get_max_amsdu_len(bit_rate); +} + +static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload, + u8 length) +{ + struct rtw_fw_iter_ra_data ra_data; + + if (WARN(length < 7, "invalid ra report c2h length\n")) + return; + + rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload); + ra_data.rtwdev = rtwdev; + ra_data.payload = payload; + rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data); +} + void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) { struct rtw_c2h_cmd *c2h; @@ -39,7 +136,13 @@ mutex_lock(&rtwdev->mutex); + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + goto unlock; + switch (c2h->id) { + case C2H_CCX_TX_RPT: + rtw_tx_report_handle(rtwdev, skb, C2H_CCX_TX_RPT); + break; case C2H_BT_INFO: rtw_coex_bt_info_notify(rtwdev, c2h->payload, len); break; @@ -49,10 +152,15 @@ case C2H_HALMAC: rtw_fw_c2h_cmd_handle_ext(rtwdev, skb); break; + case C2H_RA_RPT: + rtw_fw_ra_report_handle(rtwdev, c2h->payload, len); + break; default: + rtw_dbg(rtwdev, RTW_DBG_FW, "C2H 0x%x isn't handled\n", c2h->id); break; } +unlock: mutex_unlock(&rtwdev->mutex); } @@ -166,6 +274,9 @@ u8 h2c_pkt[H2C_PKT_SIZE] = {0}; u16 total_size = H2C_PKT_HDR_SIZE + 4; + if (rtw_chip_wcpu_11n(rtwdev)) + return; + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_GENERAL_INFO); SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); @@ -186,6 +297,9 @@ u16 total_size = H2C_PKT_HDR_SIZE + 8; u8 fw_rf_type = 0; + if (rtw_chip_wcpu_11n(rtwdev)) + return; + if (hal->rf_type == RF_1T1R) fw_rf_type = FW_RF_1T1R; else if (hal->rf_type == RF_2T2R) @@ -216,6 +330,17 @@ rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); } +void rtw_fw_set_default_port(struct rtw_dev *rtwdev, u8 port) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_DEFAULT_PORT); + + SET_DEFAULT_PORT_PORTID(h2c_pkt, port); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + void rtw_fw_query_bt_info(struct rtw_dev *rtwdev) { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; @@ -340,7 +465,7 @@ SET_RA_INFO_INIT_RA_LVL(h2c_pkt, si->init_ra_lv); SET_RA_INFO_SGI_EN(h2c_pkt, si->sgi_enable); SET_RA_INFO_BW_MODE(h2c_pkt, si->bw_mode); - SET_RA_INFO_LDPC(h2c_pkt, si->ldpc_en); + SET_RA_INFO_LDPC(h2c_pkt, !!si->ldpc_en); SET_RA_INFO_NO_UPDATE(h2c_pkt, no_update); SET_RA_INFO_VHT_EN(h2c_pkt, si->vht_enable); SET_RA_INFO_DIS_PT(h2c_pkt, disable_pt); @@ -371,6 +496,8 @@ struct rtw_lps_conf *conf = &rtwdev->lps_conf; u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + rtw_fw_set_default_port(rtwdev, conf->port_id); + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_SET_PWR_MODE); SET_PWR_MODE_SET_MODE(h2c_pkt, conf->mode); @@ -383,13 +510,103 @@ rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } +void rtw_fw_set_keep_alive_cmd(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + struct rtw_fw_wow_keep_alive_para mode = { + .adopt = true, + .pkt_type = KEEP_ALIVE_NULL_PKT, + .period = 5, + }; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_KEEP_ALIVE); + SET_KEEP_ALIVE_ENABLE(h2c_pkt, enable); + SET_KEEP_ALIVE_ADOPT(h2c_pkt, mode.adopt); + SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt, mode.pkt_type); + SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, mode.period); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + struct rtw_fw_wow_disconnect_para mode = { + .adopt = true, + .period = 30, + .retry_count = 5, + }; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_DISCONNECT_DECISION); + + if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) { + SET_DISCONNECT_DECISION_ENABLE(h2c_pkt, enable); + SET_DISCONNECT_DECISION_ADOPT(h2c_pkt, mode.adopt); + SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt, mode.period); + SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt, mode.retry_count); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_WOWLAN); + + SET_WOWLAN_FUNC_ENABLE(h2c_pkt, enable); + if (rtw_wow_mgd_linked(rtwdev)) { + if (test_bit(RTW_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags)) + SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt, enable); + if (test_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags)) + SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt, enable); + if (test_bit(RTW_WOW_FLAG_EN_REKEY_PKT, rtw_wow->flags)) + SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt, enable); + if (rtw_wow->pattern_cnt) + SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt, enable); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev *rtwdev, + u8 pairwise_key_enc, + u8 group_key_enc) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_AOAC_GLOBAL_INFO); + + SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt, pairwise_key_enc); + SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt, group_key_enc); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_REMOTE_WAKE_CTRL); + + SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt, enable); + + if (rtw_wow_no_link(rtwdev)) + SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt, enable); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + static u8 rtw_get_rsvd_page_location(struct rtw_dev *rtwdev, enum rtw_rsvd_packet_type type) { struct rtw_rsvd_page *rsvd_pkt; u8 location = 0; - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) { + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { if (type == rsvd_pkt->type) location = rsvd_pkt->page; } @@ -397,6 +614,79 @@ return location; } +void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 loc_nlo; + + loc_nlo = rtw_get_rsvd_page_location(rtwdev, RSVD_NLO_INFO); + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_NLO_INFO); + + SET_NLO_FUN_EN(h2c_pkt, enable); + if (enable) { + if (rtw_fw_lps_deep_mode) + SET_NLO_PS_32K(h2c_pkt, enable); + SET_NLO_IGNORE_SECURITY(h2c_pkt, enable); + SET_NLO_LOC_NLO_INFO(h2c_pkt, loc_nlo); + } + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +void rtw_fw_set_pg_info(struct rtw_dev *rtwdev) +{ + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u8 loc_pg, loc_dpk; + + loc_pg = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_INFO); + loc_dpk = rtw_get_rsvd_page_location(rtwdev, RSVD_LPS_PG_DPK); + + SET_H2C_CMD_ID_CLASS(h2c_pkt, H2C_CMD_LPS_PG_INFO); + + LPS_PG_INFO_LOC(h2c_pkt, loc_pg); + LPS_PG_DPK_LOC(h2c_pkt, loc_dpk); + LPS_PG_SEC_CAM_EN(h2c_pkt, conf->sec_cam_backup); + LPS_PG_PATTERN_CAM_EN(h2c_pkt, conf->pattern_cam_backup); + + rtw_fw_send_h2c_command(rtwdev, h2c_pkt); +} + +u8 rtw_get_rsvd_page_probe_req_location(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + u8 location = 0; + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + if (rsvd_pkt->type != RSVD_PROBE_REQ) + continue; + if ((!ssid && !rsvd_pkt->ssid) || + rtw_ssid_equal(rsvd_pkt->ssid, ssid)) + location = rsvd_pkt->page; + } + + return location; +} + +u16 rtw_get_rsvd_page_probe_req_size(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + u16 size = 0; + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + if (rsvd_pkt->type != RSVD_PROBE_REQ) + continue; + if ((!ssid && !rsvd_pkt->ssid) || + rtw_ssid_equal(rsvd_pkt->ssid, ssid)) + size = rsvd_pkt->skb->len; + } + + return size; +} + void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev) { u8 h2c_pkt[H2C_PKT_SIZE] = {0}; @@ -423,34 +713,175 @@ rtw_fw_send_h2c_command(rtwdev, h2c_pkt); } -static struct sk_buff * -rtw_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +static struct sk_buff *rtw_nlo_info_get(struct ieee80211_hw *hw) { - struct sk_buff *skb_new; + struct rtw_dev *rtwdev = hw->priv; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req; + struct rtw_nlo_info_hdr *nlo_hdr; + struct cfg80211_ssid *ssid; + struct sk_buff *skb; + u8 *pos, loc; + u32 size; + int i; - if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_ADHOC && - !ieee80211_vif_is_mesh(vif)) { - skb_new = alloc_skb(1, GFP_KERNEL); - if (!skb_new) + if (!pno_req->inited || !pno_req->match_set_cnt) + return NULL; + + size = sizeof(struct rtw_nlo_info_hdr) + pno_req->match_set_cnt * + IEEE80211_MAX_SSID_LEN + chip->tx_pkt_desc_sz; + + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + + nlo_hdr = skb_put_zero(skb, sizeof(struct rtw_nlo_info_hdr)); + + nlo_hdr->nlo_count = pno_req->match_set_cnt; + nlo_hdr->hidden_ap_count = pno_req->match_set_cnt; + + /* pattern check for firmware */ + memset(nlo_hdr->pattern_check, 0xA5, FW_NLO_INFO_CHECK_SIZE); + + for (i = 0; i < pno_req->match_set_cnt; i++) + nlo_hdr->ssid_len[i] = pno_req->match_sets[i].ssid.ssid_len; + + for (i = 0; i < pno_req->match_set_cnt; i++) { + ssid = &pno_req->match_sets[i].ssid; + loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid); + if (!loc) { + rtw_err(rtwdev, "failed to get probe req rsvd loc\n"); + kfree(skb); return NULL; - skb_put(skb_new, 1); - } else { - skb_new = ieee80211_beacon_get(hw, vif); + } + nlo_hdr->location[i] = loc; } - return skb_new; + for (i = 0; i < pno_req->match_set_cnt; i++) { + pos = skb_put_zero(skb, IEEE80211_MAX_SSID_LEN); + memcpy(pos, pno_req->match_sets[i].ssid.ssid, + pno_req->match_sets[i].ssid.ssid_len); + } + + return skb; +} + +static struct sk_buff *rtw_cs_channel_info_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pno_request *pno_req = &rtwdev->wow.pno_req; + struct ieee80211_channel *channels = pno_req->channels; + struct sk_buff *skb; + int count = pno_req->channel_cnt; + u8 *pos; + int i = 0; + + skb = alloc_skb(4 * count + chip->tx_pkt_desc_sz, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + + for (i = 0; i < count; i++) { + pos = skb_put_zero(skb, 4); + + CHSW_INFO_SET_CH(pos, channels[i].hw_value); + + if (channels[i].flags & IEEE80211_CHAN_RADAR) + CHSW_INFO_SET_ACTION_ID(pos, 0); + else + CHSW_INFO_SET_ACTION_ID(pos, 1); + CHSW_INFO_SET_TIMEOUT(pos, 1); + CHSW_INFO_SET_PRI_CH_IDX(pos, 1); + CHSW_INFO_SET_BW(pos, 0); + } + + return skb; +} + +static struct sk_buff *rtw_lps_pg_dpk_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; + struct rtw_lps_pg_dpk_hdr *dpk_hdr; + struct sk_buff *skb; + u32 size; + + size = chip->tx_pkt_desc_sz + sizeof(*dpk_hdr); + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + dpk_hdr = skb_put_zero(skb, sizeof(*dpk_hdr)); + dpk_hdr->dpk_ch = dpk_info->dpk_ch; + dpk_hdr->dpk_path_ok = dpk_info->dpk_path_ok[0]; + memcpy(dpk_hdr->dpk_txagc, dpk_info->dpk_txagc, 2); + memcpy(dpk_hdr->dpk_gs, dpk_info->dpk_gs, 4); + memcpy(dpk_hdr->coef, dpk_info->coef, 160); + + return skb; +} + +static struct sk_buff *rtw_lps_pg_info_get(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_lps_conf *conf = &rtwdev->lps_conf; + struct rtw_lps_pg_info_hdr *pg_info_hdr; + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct sk_buff *skb; + u32 size; + + size = chip->tx_pkt_desc_sz + sizeof(*pg_info_hdr); + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + + skb_reserve(skb, chip->tx_pkt_desc_sz); + pg_info_hdr = skb_put_zero(skb, sizeof(*pg_info_hdr)); + pg_info_hdr->tx_bu_page_count = rtwdev->fifo.rsvd_drv_pg_num; + pg_info_hdr->macid = find_first_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); + pg_info_hdr->sec_cam_count = + rtw_sec_cam_pg_backup(rtwdev, pg_info_hdr->sec_cam); + pg_info_hdr->pattern_count = rtw_wow->pattern_cnt; + + conf->sec_cam_backup = pg_info_hdr->sec_cam_count != 0; + conf->pattern_cam_backup = rtw_wow->pattern_cnt != 0; + + return skb; } static struct sk_buff *rtw_get_rsvd_page_skb(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum rtw_rsvd_packet_type type) + struct rtw_rsvd_page *rsvd_pkt) { + struct ieee80211_vif *vif; + struct rtw_vif *rtwvif; struct sk_buff *skb_new; + struct cfg80211_ssid *ssid; + + if (rsvd_pkt->type == RSVD_DUMMY) { + skb_new = alloc_skb(1, GFP_KERNEL); + if (!skb_new) + return NULL; + + skb_put(skb_new, 1); + return skb_new; + } - switch (type) { + rtwvif = rsvd_pkt->rtwvif; + if (!rtwvif) + return NULL; + + vif = rtwvif_to_vif(rtwvif); + + switch (rsvd_pkt->type) { case RSVD_BEACON: - skb_new = rtw_beacon_get(hw, vif); + skb_new = ieee80211_beacon_get(hw, vif); break; case RSVD_PS_POLL: skb_new = ieee80211_pspoll_get(hw, vif); @@ -464,6 +895,27 @@ case RSVD_QOS_NULL: skb_new = ieee80211_nullfunc_get(hw, vif, true); break; + case RSVD_LPS_PG_DPK: + skb_new = rtw_lps_pg_dpk_get(hw); + break; + case RSVD_LPS_PG_INFO: + skb_new = rtw_lps_pg_info_get(hw); + break; + case RSVD_PROBE_REQ: + ssid = (struct cfg80211_ssid *)rsvd_pkt->ssid; + if (ssid) + skb_new = ieee80211_probereq_get(hw, vif->addr, + ssid->ssid, + ssid->ssid_len, 0); + else + skb_new = ieee80211_probereq_get(hw, vif->addr, NULL, 0, 0); + break; + case RSVD_NLO_INFO: + skb_new = rtw_nlo_info_get(hw); + break; + case RSVD_CH_INFO: + skb_new = rtw_cs_channel_info_get(hw); + break; default: return NULL; } @@ -474,14 +926,14 @@ return skb_new; } -static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb) +static void rtw_fill_rsvd_page_desc(struct rtw_dev *rtwdev, struct sk_buff *skb, + enum rtw_rsvd_packet_type type) { - struct rtw_tx_pkt_info pkt_info; + struct rtw_tx_pkt_info pkt_info = {0}; struct rtw_chip_info *chip = rtwdev->chip; u8 *pkt_desc; - memset(&pkt_info, 0, sizeof(pkt_info)); - rtw_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb); + rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type); pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); memset(pkt_desc, 0, chip->tx_pkt_desc_sz); rtw_tx_fill_tx_desc(&pkt_info, skb); @@ -498,9 +950,6 @@ { struct sk_buff *skb = rsvd_pkt->skb; - if (rsvd_pkt->add_txdesc) - rtw_fill_rsvd_page_desc(rtwdev, skb); - if (page >= 1) memcpy(buf + page_margin + page_size * (page - 1), skb->data, skb->len); @@ -508,47 +957,152 @@ memcpy(buf, skb->data, skb->len); } -void rtw_add_rsvd_page(struct rtw_dev *rtwdev, enum rtw_rsvd_packet_type type, - bool txdesc) +static struct rtw_rsvd_page *rtw_alloc_rsvd_page(struct rtw_dev *rtwdev, + enum rtw_rsvd_packet_type type, + bool txdesc) { - struct rtw_rsvd_page *rsvd_pkt; + struct rtw_rsvd_page *rsvd_pkt = NULL; + + rsvd_pkt = kzalloc(sizeof(*rsvd_pkt), GFP_KERNEL); + + if (!rsvd_pkt) + return NULL; + INIT_LIST_HEAD(&rsvd_pkt->vif_list); + INIT_LIST_HEAD(&rsvd_pkt->build_list); + rsvd_pkt->type = type; + rsvd_pkt->add_txdesc = txdesc; + + return rsvd_pkt; +} + +static void rtw_insert_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + struct rtw_rsvd_page *rsvd_pkt) +{ lockdep_assert_held(&rtwdev->mutex); - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) { - if (rsvd_pkt->type == type) - return; + list_add_tail(&rsvd_pkt->vif_list, &rtwvif->rsvd_page_list); +} + +static void rtw_add_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + enum rtw_rsvd_packet_type type, + bool txdesc) +{ + struct rtw_rsvd_page *rsvd_pkt; + + rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, type, txdesc); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to alloc rsvd page %d\n", type); + return; } - rsvd_pkt = kmalloc(sizeof(*rsvd_pkt), GFP_KERNEL); - if (!rsvd_pkt) + rsvd_pkt->rtwvif = rtwvif; + rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt); +} + +static void rtw_add_rsvd_page_probe_req(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + struct cfg80211_ssid *ssid) +{ + struct rtw_rsvd_page *rsvd_pkt; + + rsvd_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_PROBE_REQ, true); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to alloc probe req rsvd page\n"); return; + } - rsvd_pkt->type = type; - rsvd_pkt->add_txdesc = txdesc; - list_add_tail(&rsvd_pkt->list, &rtwdev->rsvd_page_list); + rsvd_pkt->rtwvif = rtwvif; + rsvd_pkt->ssid = ssid; + rtw_insert_rsvd_page(rtwdev, rtwvif, rsvd_pkt); } -void rtw_reset_rsvd_page(struct rtw_dev *rtwdev) +void rtw_remove_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) { struct rtw_rsvd_page *rsvd_pkt, *tmp; lockdep_assert_held(&rtwdev->mutex); - list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, list) { - if (rsvd_pkt->type == RSVD_BEACON) - continue; - list_del(&rsvd_pkt->list); + /* remove all of the rsvd pages for vif */ + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwvif->rsvd_page_list, + vif_list) { + list_del(&rsvd_pkt->vif_list); + if (!list_empty(&rsvd_pkt->build_list)) + list_del(&rsvd_pkt->build_list); kfree(rsvd_pkt); } } +void rtw_add_rsvd_page_bcn(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + + if (vif->type != NL80211_IFTYPE_AP && + vif->type != NL80211_IFTYPE_ADHOC && + vif->type != NL80211_IFTYPE_MESH_POINT) { + rtw_warn(rtwdev, "Cannot add beacon rsvd page for %d\n", + vif->type); + return; + } + + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_BEACON, false); +} + +void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *rtw_pno_req = &rtw_wow->pno_req; + struct cfg80211_ssid *ssid; + int i; + + if (vif->type != NL80211_IFTYPE_STATION) { + rtw_warn(rtwdev, "Cannot add PNO rsvd page for %d\n", + vif->type); + return; + } + + for (i = 0 ; i < rtw_pno_req->match_set_cnt; i++) { + ssid = &rtw_pno_req->match_sets[i].ssid; + rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, ssid); + } + + rtw_add_rsvd_page_probe_req(rtwdev, rtwvif, NULL); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NLO_INFO, false); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_CH_INFO, true); +} + +void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + + if (vif->type != NL80211_IFTYPE_STATION) { + rtw_warn(rtwdev, "Cannot add sta rsvd page for %d\n", + vif->type); + return; + } + + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_PS_POLL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_QOS_NULL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_NULL, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_DPK, true); + rtw_add_rsvd_page(rtwdev, rtwvif, RSVD_LPS_PG_INFO, true); +} + int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, u8 *buf, u32 size) { u8 bckp[2]; u8 val; u16 rsvd_pg_head; + u32 bcn_valid_addr; + u32 bcn_valid_mask; int ret; lockdep_assert_held(&rtwdev->mutex); @@ -556,8 +1110,13 @@ if (!size) return -EINVAL; - pg_addr &= BIT_MASK_BCN_HEAD_1_V1; - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr | BIT_BCN_VALID_V1); + if (rtw_chip_wcpu_11n(rtwdev)) { + rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID); + } else { + pg_addr &= BIT_MASK_BCN_HEAD_1_V1; + pg_addr |= BIT_BCN_VALID_V1; + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, pg_addr); + } val = rtw_read8(rtwdev, REG_CR + 1); bckp[0] = val; @@ -575,7 +1134,15 @@ goto restore; } - if (!check_hw_ready(rtwdev, REG_FIFOPAGE_CTRL_2, BIT_BCN_VALID_V1, 1)) { + if (rtw_chip_wcpu_11n(rtwdev)) { + bcn_valid_addr = REG_DWBCN0_CTRL; + bcn_valid_mask = BIT_BCN_VALID; + } else { + bcn_valid_addr = REG_FIFOPAGE_CTRL_2; + bcn_valid_mask = BIT_BCN_VALID_V1; + } + + if (!check_hw_ready(rtwdev, bcn_valid_addr, bcn_valid_mask, 1)) { rtw_err(rtwdev, "error beacon valid\n"); ret = -EBUSY; } @@ -606,8 +1173,72 @@ return rtw_fw_write_data_rsvd_page(rtwdev, pg_addr, buf, size); } -static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, - struct ieee80211_vif *vif, u32 *size) +static void __rtw_build_rsvd_page_reset(struct rtw_dev *rtwdev) +{ + struct rtw_rsvd_page *rsvd_pkt, *tmp; + + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, + build_list) { + list_del_init(&rsvd_pkt->build_list); + + /* Don't free except for the dummy rsvd page, + * others will be freed when removing vif + */ + if (rsvd_pkt->type == RSVD_DUMMY) + kfree(rsvd_pkt); + } +} + +static void rtw_build_rsvd_page_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_rsvd_page *rsvd_pkt; + + list_for_each_entry(rsvd_pkt, &rtwvif->rsvd_page_list, vif_list) { + if (rsvd_pkt->type == RSVD_BEACON) + list_add(&rsvd_pkt->build_list, + &rtwdev->rsvd_page_list); + else + list_add_tail(&rsvd_pkt->build_list, + &rtwdev->rsvd_page_list); + } +} + +static int __rtw_build_rsvd_page_from_vifs(struct rtw_dev *rtwdev) +{ + struct rtw_rsvd_page *rsvd_pkt; + + __rtw_build_rsvd_page_reset(rtwdev); + + /* gather rsvd page from vifs */ + rtw_iterate_vifs_atomic(rtwdev, rtw_build_rsvd_page_iter, rtwdev); + + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, build_list); + if (!rsvd_pkt) { + WARN(1, "Should not have an empty reserved page\n"); + return -EINVAL; + } + + /* the first rsvd should be beacon, otherwise add a dummy one */ + if (rsvd_pkt->type != RSVD_BEACON) { + struct rtw_rsvd_page *dummy_pkt; + + dummy_pkt = rtw_alloc_rsvd_page(rtwdev, RSVD_DUMMY, false); + if (!dummy_pkt) { + rtw_err(rtwdev, "failed to alloc dummy rsvd page\n"); + return -ENOMEM; + } + + list_add(&dummy_pkt->build_list, &rtwdev->rsvd_page_list); + } + + return 0; +} + +static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) { struct ieee80211_hw *hw = rtwdev->hw; struct rtw_chip_info *chip = rtwdev->chip; @@ -617,24 +1248,54 @@ u8 total_page = 0; u8 page_size, page_margin, tx_desc_sz; u8 *buf; + int ret; page_size = chip->page_size; tx_desc_sz = chip->tx_pkt_desc_sz; page_margin = page_size - tx_desc_sz; - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) { - iter = rtw_get_rsvd_page_skb(hw, vif, rsvd_pkt->type); + ret = __rtw_build_rsvd_page_from_vifs(rtwdev); + if (ret) { + rtw_err(rtwdev, + "failed to build rsvd page from vifs, ret %d\n", ret); + return NULL; + } + + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { + iter = rtw_get_rsvd_page_skb(hw, rsvd_pkt); if (!iter) { - rtw_err(rtwdev, "fail to build rsvd packet\n"); + rtw_err(rtwdev, "failed to build rsvd packet\n"); goto release_skb; } + + /* Fill the tx_desc for the rsvd pkt that requires one. + * And iter->len will be added with size of tx_desc_sz. + */ + if (rsvd_pkt->add_txdesc) + rtw_fill_rsvd_page_desc(rtwdev, iter, rsvd_pkt->type); + rsvd_pkt->skb = iter; rsvd_pkt->page = total_page; - if (rsvd_pkt->add_txdesc) + + /* Reserved page is downloaded via TX path, and TX path will + * generate a tx_desc at the header to describe length of + * the buffer. If we are not counting page numbers with the + * size of tx_desc added at the first rsvd_pkt (usually a + * beacon, firmware default refer to the first page as the + * content of beacon), we could generate a buffer which size + * is smaller than the actual size of the whole rsvd_page + */ + if (total_page == 0) { + if (rsvd_pkt->type != RSVD_BEACON && + rsvd_pkt->type != RSVD_DUMMY) { + rtw_err(rtwdev, "first page should be a beacon\n"); + goto release_skb; + } total_page += rtw_len_to_page(iter->len + tx_desc_sz, page_size); - else + } else { total_page += rtw_len_to_page(iter->len, page_size); + } } if (total_page > rtwdev->fifo.rsvd_drv_pg_num) { @@ -647,35 +1308,62 @@ if (!buf) goto release_skb; - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) { + /* Copy the content of each rsvd_pkt to the buf, and they should + * be aligned to the pages. + * + * Note that the first rsvd_pkt is a beacon no matter what vif->type. + * And that rsvd_pkt does not require tx_desc because when it goes + * through TX path, the TX path will generate one for it. + */ + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { rtw_rsvd_page_list_to_buf(rtwdev, page_size, page_margin, page, buf, rsvd_pkt); - page += rtw_len_to_page(rsvd_pkt->skb->len, page_size); - } - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) + if (page == 0) + page += rtw_len_to_page(rsvd_pkt->skb->len + + tx_desc_sz, page_size); + else + page += rtw_len_to_page(rsvd_pkt->skb->len, page_size); + kfree_skb(rsvd_pkt->skb); + rsvd_pkt->skb = NULL; + } return buf; release_skb: - list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, list) + list_for_each_entry(rsvd_pkt, &rtwdev->rsvd_page_list, build_list) { kfree_skb(rsvd_pkt->skb); + rsvd_pkt->skb = NULL; + } return NULL; } -static int -rtw_download_beacon(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) +static int rtw_download_beacon(struct rtw_dev *rtwdev) { struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_rsvd_page *rsvd_pkt; struct sk_buff *skb; int ret = 0; - skb = rtw_beacon_get(hw, vif); + rsvd_pkt = list_first_entry_or_null(&rtwdev->rsvd_page_list, + struct rtw_rsvd_page, build_list); + if (!rsvd_pkt) { + rtw_err(rtwdev, "failed to get rsvd page from build list\n"); + return -ENOENT; + } + + if (rsvd_pkt->type != RSVD_BEACON && + rsvd_pkt->type != RSVD_DUMMY) { + rtw_err(rtwdev, "invalid rsvd page type %d, should be beacon or dummy\n", + rsvd_pkt->type); + return -EINVAL; + } + + skb = rtw_get_rsvd_page_skb(hw, rsvd_pkt); if (!skb) { rtw_err(rtwdev, "failed to get beacon skb\n"); - ret = -ENOMEM; - goto out; + return -ENOMEM; } ret = rtw_download_drv_rsvd_page(rtwdev, skb->data, skb->len); @@ -684,17 +1372,16 @@ dev_kfree_skb(skb); -out: return ret; } -int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev, struct ieee80211_vif *vif) +int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev) { u8 *buf; u32 size; int ret; - buf = rtw_build_rsvd_page(rtwdev, vif, &size); + buf = rtw_build_rsvd_page(rtwdev, &size); if (!buf) { rtw_err(rtwdev, "failed to build rsvd page pkt\n"); return -ENOMEM; @@ -706,7 +1393,12 @@ goto free; } - ret = rtw_download_beacon(rtwdev, vif); + /* The last thing is to download the *ONLY* beacon again, because + * the previous tx_desc is to describe the total rsvd page. Download + * the beacon again to replace the TX desc header, and we will get + * a correct tx_desc for the beacon in the rsvd page. + */ + ret = rtw_download_beacon(rtwdev); if (ret) { rtw_err(rtwdev, "failed to download beacon\n"); goto free; @@ -764,3 +1456,81 @@ rtw_write8(rtwdev, REG_RCR + 2, rcr); return 0; } + +static void __rtw_fw_update_pkt(struct rtw_dev *rtwdev, u8 pkt_id, u16 size, + u8 location) +{ + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_UPDATE_PKT_LEN; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_UPDATE_PKT); + + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + UPDATE_PKT_SET_PKT_ID(h2c_pkt, pkt_id); + UPDATE_PKT_SET_LOCATION(h2c_pkt, location); + + /* include txdesc size */ + UPDATE_PKT_SET_SIZE(h2c_pkt, size); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} + +void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid) +{ + u8 loc; + u32 size; + + loc = rtw_get_rsvd_page_probe_req_location(rtwdev, ssid); + if (!loc) { + rtw_err(rtwdev, "failed to get probe_req rsvd loc\n"); + return; + } + + size = rtw_get_rsvd_page_probe_req_size(rtwdev, ssid); + if (!size) { + rtw_err(rtwdev, "failed to get probe_req rsvd size\n"); + return; + } + + __rtw_fw_update_pkt(rtwdev, RTW_PACKET_PROBE_REQ, size, loc); +} + +void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable) +{ + struct rtw_pno_request *rtw_pno_req = &rtwdev->wow.pno_req; + u8 h2c_pkt[H2C_PKT_SIZE] = {0}; + u16 total_size = H2C_PKT_HDR_SIZE + H2C_PKT_CH_SWITCH_LEN; + u8 loc_ch_info; + const struct rtw_ch_switch_option cs_option = { + .dest_ch_en = 1, + .dest_ch = 1, + .periodic_option = 2, + .normal_period = 5, + .normal_period_sel = 0, + .normal_cycle = 10, + .slow_period = 1, + .slow_period_sel = 1, + }; + + rtw_h2c_pkt_set_header(h2c_pkt, H2C_PKT_CH_SWITCH); + SET_PKT_H2C_TOTAL_LEN(h2c_pkt, total_size); + + CH_SWITCH_SET_START(h2c_pkt, enable); + CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, cs_option.dest_ch_en); + CH_SWITCH_SET_DEST_CH(h2c_pkt, cs_option.dest_ch); + CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, cs_option.normal_period); + CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, cs_option.normal_period_sel); + CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, cs_option.slow_period); + CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, cs_option.slow_period_sel); + CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, cs_option.normal_cycle); + CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, cs_option.periodic_option); + + CH_SWITCH_SET_CH_NUM(h2c_pkt, rtw_pno_req->channel_cnt); + CH_SWITCH_SET_INFO_SIZE(h2c_pkt, rtw_pno_req->channel_cnt * 4); + + loc_ch_info = rtw_get_rsvd_page_location(rtwdev, RSVD_CH_INFO); + CH_SWITCH_SET_INFO_LOC(h2c_pkt, loc_ch_info); + + rtw_fw_send_h2c_packet(rtwdev, h2c_pkt); +} --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/fw.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/fw.h @@ -11,31 +11,25 @@ /* FW bin information */ #define FW_HDR_SIZE 64 #define FW_HDR_CHKSUM_SIZE 8 -#define FW_HDR_VERSION 4 -#define FW_HDR_SUBVERSION 6 -#define FW_HDR_SUBINDEX 7 -#define FW_HDR_MONTH 16 -#define FW_HDR_DATE 17 -#define FW_HDR_HOUR 18 -#define FW_HDR_MIN 19 -#define FW_HDR_YEAR 20 -#define FW_HDR_MEM_USAGE 24 -#define FW_HDR_H2C_FMT_VER 28 -#define FW_HDR_DMEM_ADDR 32 -#define FW_HDR_DMEM_SIZE 36 -#define FW_HDR_IMEM_SIZE 48 -#define FW_HDR_EMEM_SIZE 52 -#define FW_HDR_EMEM_ADDR 56 -#define FW_HDR_IMEM_ADDR 60 + +#define FW_NLO_INFO_CHECK_SIZE 4 #define FIFO_PAGE_SIZE_SHIFT 12 #define FIFO_PAGE_SIZE 4096 #define RSVD_PAGE_START_ADDR 0x780 #define FIFO_DUMP_ADDR 0x8000 +#define DLFW_PAGE_SIZE_SHIFT_LEGACY 12 +#define DLFW_PAGE_SIZE_LEGACY 0x1000 +#define DLFW_BLK_SIZE_SHIFT_LEGACY 2 +#define DLFW_BLK_SIZE_LEGACY 4 +#define FW_START_ADDR_LEGACY 0x1000 + enum rtw_c2h_cmd_id { + C2H_CCX_TX_RPT = 0x03, C2H_BT_INFO = 0x09, C2H_BT_MP_INFO = 0x0b, + C2H_RA_RPT = 0x0c, C2H_HW_FEATURE_REPORT = 0x19, C2H_WLAN_INFO = 0x27, C2H_HW_FEATURE_DUMP = 0xfd, @@ -54,10 +48,16 @@ enum rtw_rsvd_packet_type { RSVD_BEACON, + RSVD_DUMMY, RSVD_PS_POLL, RSVD_PROBE_RESP, RSVD_NULL, RSVD_QOS_NULL, + RSVD_LPS_PG_DPK, + RSVD_LPS_PG_INFO, + RSVD_PROBE_REQ, + RSVD_NLO_INFO, + RSVD_CH_INFO, }; enum rtw_fw_rf_type { @@ -86,17 +86,148 @@ u8 segment_iqk; }; +struct rtw_lps_pg_dpk_hdr { + u16 dpk_path_ok; + u8 dpk_txagc[2]; + u16 dpk_gs[2]; + u32 coef[2][20]; + u8 dpk_ch; +} __packed; + +struct rtw_lps_pg_info_hdr { + u8 macid; + u8 mbssid; + u8 pattern_count; + u8 mu_tab_group_id; + u8 sec_cam_count; + u8 tx_bu_page_count; + u16 rsvd; + u8 sec_cam[MAX_PG_CAM_BACKUP_NUM]; +} __packed; + struct rtw_rsvd_page { - struct list_head list; + /* associated with each vif */ + struct list_head vif_list; + struct rtw_vif *rtwvif; + + /* associated when build rsvd page */ + struct list_head build_list; + struct sk_buff *skb; enum rtw_rsvd_packet_type type; u8 page; bool add_txdesc; + struct cfg80211_ssid *ssid; +}; + +enum rtw_keep_alive_pkt_type { + KEEP_ALIVE_NULL_PKT = 0, + KEEP_ALIVE_ARP_RSP = 1, +}; + +struct rtw_nlo_info_hdr { + u8 nlo_count; + u8 hidden_ap_count; + u8 rsvd1[2]; + u8 pattern_check[FW_NLO_INFO_CHECK_SIZE]; + u8 rsvd2[8]; + u8 ssid_len[16]; + u8 chiper[16]; + u8 rsvd3[16]; + u8 location[8]; +} __packed; + +enum rtw_packet_type { + RTW_PACKET_PROBE_REQ = 0x00, + + RTW_PACKET_UNDEFINE = 0x7FFFFFFF, }; +struct rtw_fw_wow_keep_alive_para { + bool adopt; + u8 pkt_type; + u8 period; /* unit: sec */ +}; + +struct rtw_fw_wow_disconnect_para { + bool adopt; + u8 period; /* unit: sec */ + u8 retry_count; +}; + +struct rtw_ch_switch_option { + u8 periodic_option; + u32 tsf_high; + u32 tsf_low; + u8 dest_ch_en; + u8 absolute_time_en; + u8 dest_ch; + u8 normal_period; + u8 normal_period_sel; + u8 normal_cycle; + u8 slow_period; + u8 slow_period_sel; + u8 nlo_en; +}; + +struct rtw_fw_hdr { + __le16 signature; + u8 category; + u8 function; + __le16 version; /* 0x04 */ + u8 subversion; + u8 subindex; + __le32 rsvd; /* 0x08 */ + __le32 rsvd2; /* 0x0C */ + u8 month; /* 0x10 */ + u8 day; + u8 hour; + u8 min; + __le16 year; /* 0x14 */ + __le16 rsvd3; + u8 mem_usage; /* 0x18 */ + u8 rsvd4[3]; + __le16 h2c_fmt_ver; /* 0x1C */ + __le16 rsvd5; + __le32 dmem_addr; /* 0x20 */ + __le32 dmem_size; + __le32 rsvd6; + __le32 rsvd7; + __le32 imem_size; /* 0x30 */ + __le32 emem_size; + __le32 emem_addr; + __le32 imem_addr; +} __packed; + +struct rtw_fw_hdr_legacy { + __le16 signature; + u8 category; + u8 function; + __le16 version; /* 0x04 */ + u8 subversion1; + u8 subversion2; + u8 month; /* 0x08 */ + u8 day; + u8 hour; + u8 minute; + __le16 size; + __le16 rsvd2; + __le32 idx; /* 0x10 */ + __le32 rsvd3; + __le32 rsvd4; /* 0x18 */ + __le32 rsvd5; +} __packed; + /* C2H */ -#define GET_CCX_REPORT_SEQNUM(c2h_payload) (c2h_payload[8] & 0xfc) -#define GET_CCX_REPORT_STATUS(c2h_payload) (c2h_payload[9] & 0xc0) +#define GET_CCX_REPORT_SEQNUM_V0(c2h_payload) (c2h_payload[6] & 0xfc) +#define GET_CCX_REPORT_STATUS_V0(c2h_payload) (c2h_payload[0] & 0xc0) +#define GET_CCX_REPORT_SEQNUM_V1(c2h_payload) (c2h_payload[8] & 0xfc) +#define GET_CCX_REPORT_STATUS_V1(c2h_payload) (c2h_payload[9] & 0xc0) + +#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f) +#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7) +#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6]) +#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1]) /* PKT H2C */ #define H2C_PKT_CMD_ID 0xFF @@ -106,6 +237,12 @@ #define H2C_PKT_PHYDM_INFO 0x11 #define H2C_PKT_IQK 0x0E +#define H2C_PKT_CH_SWITCH 0x02 +#define H2C_PKT_UPDATE_PKT 0x0C + +#define H2C_PKT_CH_SWITCH_LEN 0x20 +#define H2C_PKT_UPDATE_PKT_LEN 0x4 + #define SET_PKT_H2C_CATEGORY(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(6, 0)) #define SET_PKT_H2C_CMD_ID(h2c_pkt, value) \ @@ -142,10 +279,63 @@ #define IQK_SET_SEGMENT_IQK(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(1)) +#define CHSW_INFO_SET_CH(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(7, 0)) +#define CHSW_INFO_SET_PRI_CH_IDX(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(11, 8)) +#define CHSW_INFO_SET_BW(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(15, 12)) +#define CHSW_INFO_SET_TIMEOUT(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(23, 16)) +#define CHSW_INFO_SET_ACTION_ID(pkt, value) \ + le32p_replace_bits((__le32 *)(pkt) + 0x00, value, GENMASK(30, 24)) + +#define UPDATE_PKT_SET_SIZE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 0)) +#define UPDATE_PKT_SET_PKT_ID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) +#define UPDATE_PKT_SET_LOCATION(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(31, 24)) + +#define CH_SWITCH_SET_START(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(0)) +#define CH_SWITCH_SET_DEST_CH_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(1)) +#define CH_SWITCH_SET_ABSOLUTE_TIME(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, BIT(2)) +#define CH_SWITCH_SET_PERIODIC_OPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(4, 3)) +#define CH_SWITCH_SET_INFO_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(15, 8)) +#define CH_SWITCH_SET_CH_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(23, 16)) +#define CH_SWITCH_SET_PRI_CH_IDX(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x02, value, GENMASK(27, 24)) +#define CH_SWITCH_SET_DEST_CH(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(7, 0)) +#define CH_SWITCH_SET_NORMAL_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(13, 8)) +#define CH_SWITCH_SET_NORMAL_PERIOD_SEL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(15, 14)) +#define CH_SWITCH_SET_SLOW_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(21, 16)) +#define CH_SWITCH_SET_SLOW_PERIOD_SEL(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(23, 22)) +#define CH_SWITCH_SET_NORMAL_CYCLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x03, value, GENMASK(31, 24)) +#define CH_SWITCH_SET_TSF_HIGH(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x04, value, GENMASK(31, 0)) +#define CH_SWITCH_SET_TSF_LOW(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x05, value, GENMASK(31, 0)) +#define CH_SWITCH_SET_INFO_SIZE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x06, value, GENMASK(15, 0)) + /* Command H2C */ #define H2C_CMD_RSVD_PAGE 0x0 #define H2C_CMD_MEDIA_STATUS_RPT 0x01 #define H2C_CMD_SET_PWR_MODE 0x20 +#define H2C_CMD_LPS_PG_INFO 0x2b +#define H2C_CMD_DEFAULT_PORT 0x2c #define H2C_CMD_RA_INFO 0x40 #define H2C_CMD_RSSI_MONITOR 0x42 @@ -157,6 +347,13 @@ #define H2C_CMD_QUERY_BT_MP_INFO 0x67 #define H2C_CMD_BT_WIFI_CONTROL 0x69 +#define H2C_CMD_KEEP_ALIVE 0x03 +#define H2C_CMD_DISCONNECT_DECISION 0x04 +#define H2C_CMD_WOWLAN 0x80 +#define H2C_CMD_REMOTE_WAKE_CTRL 0x81 +#define H2C_CMD_AOAC_GLOBAL_INFO 0x82 +#define H2C_CMD_NLO_INFO 0x8C + #define SET_H2C_CMD_ID_CLASS(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(7, 0)) @@ -177,6 +374,14 @@ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(7, 5)) #define SET_PWR_MODE_SET_PWR_STATE(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) +#define LPS_PG_INFO_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define LPS_PG_DPK_LOC(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) +#define LPS_PG_SEC_CAM_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define LPS_PG_PATTERN_CAM_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) #define SET_RSSI_INFO_MACID(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) #define SET_RSSI_INFO_RSSI(h2c_pkt, value) \ @@ -253,6 +458,58 @@ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(15, 8)) #define SET_BT_WIFI_CONTROL_DATA5(h2c_pkt, value) \ le32p_replace_bits((__le32 *)(h2c_pkt) + 0x01, value, GENMASK(23, 16)) +#define SET_DEFAULT_PORT_PORTID(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) + +#define SET_KEEP_ALIVE_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_KEEP_ALIVE_ADOPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_KEEP_ALIVE_PKT_TYPE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_KEEP_ALIVE_CHECK_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_DISCONNECT_DECISION_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_DISCONNECT_DECISION_ADOPT(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_DISCONNECT_DECISION_CHECK_PERIOD(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) +#define SET_DISCONNECT_DECISION_TRY_PKT_NUM(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(31, 24)) + +#define SET_WOWLAN_FUNC_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_WOWLAN_PATTERN_MATCH_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_WOWLAN_MAGIC_PKT_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_WOWLAN_UNICAST_PKT_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(11)) +#define SET_WOWLAN_REKEY_WAKEUP_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(14)) +#define SET_WOWLAN_DEAUTH_WAKEUP_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(15)) + +#define SET_REMOTE_WAKECTRL_ENABLE(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(12)) + +#define SET_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(15, 8)) +#define SET_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) + +#define SET_NLO_FUN_EN(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(8)) +#define SET_NLO_PS_32K(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(9)) +#define SET_NLO_IGNORE_SECURITY(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, BIT(10)) +#define SET_NLO_LOC_NLO_INFO(h2c_pkt, value) \ + le32p_replace_bits((__le32 *)(h2c_pkt) + 0x00, value, GENMASK(23, 16)) static inline struct rtw_c2h_cmd *get_c2h_from_skb(struct sk_buff *skb) { @@ -269,7 +526,9 @@ void rtw_fw_send_phydm_info(struct rtw_dev *rtwdev); void rtw_fw_do_iqk(struct rtw_dev *rtwdev, struct rtw_iqk_para *para); +void rtw_fw_set_default_port(struct rtw_dev *rtwdev, u8 port); void rtw_fw_set_pwr_mode(struct rtw_dev *rtwdev); +void rtw_fw_set_pg_info(struct rtw_dev *rtwdev); void rtw_fw_query_bt_info(struct rtw_dev *rtwdev); void rtw_fw_wl_ch_info(struct rtw_dev *rtwdev, u8 link, u8 ch, u8 bw); void rtw_fw_query_bt_mp_info(struct rtw_dev *rtwdev, @@ -282,14 +541,30 @@ void rtw_fw_send_rssi_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); void rtw_fw_send_ra_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); void rtw_fw_media_status_report(struct rtw_dev *rtwdev, u8 mac_id, bool conn); -void rtw_add_rsvd_page(struct rtw_dev *rtwdev, enum rtw_rsvd_packet_type type, - bool txdesc); int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr, u8 *buf, u32 size); -void rtw_reset_rsvd_page(struct rtw_dev *rtwdev); -int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev, - struct ieee80211_vif *vif); +void rtw_remove_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_bcn(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_pno(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif); +int rtw_fw_download_rsvd_page(struct rtw_dev *rtwdev); void rtw_send_rsvd_page_h2c(struct rtw_dev *rtwdev); int rtw_dump_drv_rsvd_page(struct rtw_dev *rtwdev, u32 offset, u32 size, u32 *buf); +void rtw_fw_set_remote_wake_ctrl_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_wowlan_ctrl_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_keep_alive_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_disconnect_decision_cmd(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_set_aoac_global_info_cmd(struct rtw_dev *rtwdev, + u8 pairwise_key_enc, + u8 group_key_enc); + +void rtw_fw_set_nlo_info(struct rtw_dev *rtwdev, bool enable); +void rtw_fw_update_pkt_probe_req(struct rtw_dev *rtwdev, + struct cfg80211_ssid *ssid); +void rtw_fw_channel_switch(struct rtw_dev *rtwdev, bool enable); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/hci.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/hci.h @@ -13,6 +13,9 @@ int (*setup)(struct rtw_dev *rtwdev); int (*start)(struct rtw_dev *rtwdev); void (*stop)(struct rtw_dev *rtwdev); + void (*deep_ps)(struct rtw_dev *rtwdev, bool enter); + void (*link_ps)(struct rtw_dev *rtwdev, bool enter); + void (*interface_cfg)(struct rtw_dev *rtwdev); int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size); int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size); @@ -47,6 +50,21 @@ rtwdev->hci.ops->stop(rtwdev); } +static inline void rtw_hci_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + rtwdev->hci.ops->deep_ps(rtwdev, enter); +} + +static inline void rtw_hci_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + rtwdev->hci.ops->link_ps(rtwdev, enter); +} + +static inline void rtw_hci_interface_cfg(struct rtw_dev *rtwdev) +{ + rtwdev->hci.ops->interface_cfg(rtwdev); +} + static inline int rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) { @@ -173,6 +191,32 @@ ret = (orig & mask) >> shift; return ret; +} + +static inline u16 +rtw_read16_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw_read16(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; +} + +static inline u8 +rtw_read8_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask) +{ + u32 shift = __ffs(mask); + u32 orig; + u32 ret; + + orig = rtw_read8(rtwdev, addr); + ret = (orig & mask) >> shift; + + return ret; } static inline void --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/mac.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/mac.c @@ -16,10 +16,12 @@ u8 value8; txsc20 = primary_ch_idx; - if (txsc20 == 1 || txsc20 == 3) - txsc40 = 9; - else - txsc40 = 10; + if (bw == RTW_CHANNEL_WIDTH_80) { + if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) + txsc40 = RTW_SC_40_UPPER; + else + txsc40 = RTW_SC_40_LOWER; + } rtw_write8(rtwdev, REG_DATA_SC, BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40)); @@ -38,6 +40,9 @@ } rtw_write32(rtwdev, REG_WMAC_TRXPTCL_CTL, value32); + if (rtw_chip_wcpu_11n(rtwdev)) + return; + value32 = rtw_read32(rtwdev, REG_AFE_CTRL1) & ~(BIT_MAC_CLK_SEL); value32 |= (MAC_CLK_HW_DEF_80M << BIT_SHIFT_MAC_CLK_SEL); rtw_write32(rtwdev, REG_AFE_CTRL1, value32); @@ -47,7 +52,7 @@ value8 = rtw_read8(rtwdev, REG_CCK_CHECK); value8 = value8 & ~BIT_CHECK_CCK_EN; - if (channel > 35) + if (IS_CH_5G_BAND(channel)) value8 |= BIT_CHECK_CCK_EN; rtw_write8(rtwdev, REG_CCK_CHECK, value8); } @@ -59,6 +64,14 @@ rtw_write8(rtwdev, REG_RSV_CTRL, 0); + if (rtw_chip_wcpu_11n(rtwdev)) { + if (rtw_read32(rtwdev, REG_SYS_CFG1) & BIT_LDO) + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, LDO_SEL); + else + rtw_write8(rtwdev, REG_LDO_SWR_CTRL, SPS_SEL); + return 0; + } + switch (rtw_hci_type(rtwdev)) { case RTW_HCI_TYPE_PCIE: rtw_write32_set(rtwdev, REG_HCI_OPT_CTRL, BIT_BT_DIG_CLK_EN); @@ -98,42 +111,55 @@ return 0; } +static bool do_pwr_poll_cmd(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 target) +{ + u32 cnt; + + target &= mask; + + for (cnt = 0; cnt < RTW_PWR_POLLING_CNT; cnt++) { + if ((rtw_read8(rtwdev, addr) & mask) == target) + return true; + + udelay(50); + } + + return false; +} + static int rtw_pwr_cmd_polling(struct rtw_dev *rtwdev, struct rtw_pwr_seq_cmd *cmd) { u8 value; - u8 flag = 0; u32 offset; - u32 cnt = RTW_PWR_POLLING_CNT; if (cmd->base == RTW_PWR_ADDR_SDIO) offset = cmd->offset | SDIO_LOCAL_OFFSET; else offset = cmd->offset; - do { - cnt--; - value = rtw_read8(rtwdev, offset); - value &= cmd->mask; - if (value == (cmd->value & cmd->mask)) - return 0; - if (cnt == 0) { - if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && - flag == 0) { - value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); - value |= BIT(3); - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - value &= ~BIT(3); - rtw_write8(rtwdev, REG_SYS_PW_CTRL, value); - cnt = RTW_PWR_POLLING_CNT; - flag = 1; - } else { - return -EBUSY; - } - } else { - udelay(50); - } - } while (1); + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + + if (rtw_hci_type(rtwdev) != RTW_HCI_TYPE_PCIE) + goto err; + + /* if PCIE, toggle BIT_PFM_WOWL and try again */ + value = rtw_read8(rtwdev, REG_SYS_PW_CTRL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value & ~BIT_PFM_WOWL); + if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D) + rtw_write8(rtwdev, REG_SYS_PW_CTRL, value | BIT_PFM_WOWL); + + if (do_pwr_poll_cmd(rtwdev, offset, cmd->mask, cmd->value)) + return 0; + +err: + rtw_err(rtwdev, "failed to poll offset=0x%x mask=0x%x value=0x%x\n", + offset, cmd->mask, cmd->value); + return -EBUSY; } static int rtw_sub_pwr_seq_parser(struct rtw_dev *rtwdev, u8 intf_mask, @@ -210,7 +236,7 @@ ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd); if (ret) - return -EBUSY; + return ret; idx++; } while (1); @@ -224,13 +250,16 @@ struct rtw_pwr_seq_cmd **pwr_seq; u8 rpwm; bool cur_pwr; + int ret; - rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + if (rtw_chip_wcpu_11ac(rtwdev)) { + rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); - /* Check FW still exist or not */ - if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) { - rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE; - rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm); + /* Check FW still exist or not */ + if (rtw_read16(rtwdev, REG_MCUFW_CTRL) == 0xC078) { + rpwm = (rpwm ^ BIT_RPWM_TOGGLE) & BIT_RPWM_TOGGLE; + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, rpwm); + } } if (rtw_read8(rtwdev, REG_CR) == 0xea) @@ -241,17 +270,18 @@ else cur_pwr = true; - if (pwr_on && cur_pwr) + if (pwr_on == cur_pwr) return -EALREADY; pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; - if (rtw_pwr_seq_parser(rtwdev, pwr_seq)) - return -EINVAL; + ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); + if (ret) + return ret; return 0; } -static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +static int __rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) { u8 sys_func_en = rtwdev->chip->sys_func_en; u8 value8; @@ -261,7 +291,7 @@ value |= BIT_WL_PLATFORM_RST | BIT_DDMA_EN; rtw_write32(rtwdev, REG_CPU_DMEM_CON, value); - rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, sys_func_en); + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, sys_func_en); value8 = (rtw_read8(rtwdev, REG_CR_EXT + 3) & 0xF0) | 0x0C; rtw_write8(rtwdev, REG_CR_EXT + 3, value8); @@ -276,6 +306,29 @@ return 0; } +static int __rtw_mac_init_system_cfg_legacy(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_CR, 0xff); + mdelay(2); + rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0x7f); + mdelay(2); + + rtw_write8_set(rtwdev, REG_SYS_CLKR, BIT_WAKEPAD_EN); + rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); + + rtw_write16(rtwdev, REG_CR, 0x2ff); + + return 0; +} + +static int rtw_mac_init_system_cfg(struct rtw_dev *rtwdev) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + return __rtw_mac_init_system_cfg_legacy(rtwdev); + + return __rtw_mac_init_system_cfg(rtwdev); +} + int rtw_mac_power_on(struct rtw_dev *rtwdev) { int ret = 0; @@ -312,15 +365,16 @@ static bool check_firmware_size(const u8 *data, u32 size) { + const struct rtw_fw_hdr *fw_hdr = (const struct rtw_fw_hdr *)data; u32 dmem_size; u32 imem_size; u32 emem_size; u32 real_size; - dmem_size = le32_to_cpu(*((__le32 *)(data + FW_HDR_DMEM_SIZE))); - imem_size = le32_to_cpu(*((__le32 *)(data + FW_HDR_IMEM_SIZE))); - emem_size = ((*(data + FW_HDR_MEM_USAGE)) & BIT(4)) ? - le32_to_cpu(*((__le32 *)(data + FW_HDR_EMEM_SIZE))) : 0; + dmem_size = le32_to_cpu(fw_hdr->dmem_size); + imem_size = le32_to_cpu(fw_hdr->imem_size); + emem_size = (fw_hdr->mem_usage & BIT(4)) ? + le32_to_cpu(fw_hdr->emem_size) : 0; dmem_size += FW_HDR_CHKSUM_SIZE; imem_size += FW_HDR_CHKSUM_SIZE; @@ -566,27 +620,10 @@ return 0; } -static void update_firmware_info(struct rtw_dev *rtwdev, - struct rtw_fw_state *fw) -{ - const u8 *data = fw->firmware->data; - - fw->h2c_version = - le16_to_cpu(*((__le16 *)(data + FW_HDR_H2C_FMT_VER))); - fw->version = - le16_to_cpu(*((__le16 *)(data + FW_HDR_VERSION))); - fw->sub_version = *(data + FW_HDR_SUBVERSION); - fw->sub_index = *(data + FW_HDR_SUBINDEX); - - rtw_dbg(rtwdev, RTW_DBG_FW, "fw h2c version: %x\n", fw->h2c_version); - rtw_dbg(rtwdev, RTW_DBG_FW, "fw version: %x\n", fw->version); - rtw_dbg(rtwdev, RTW_DBG_FW, "fw sub version: %x\n", fw->sub_version); - rtw_dbg(rtwdev, RTW_DBG_FW, "fw sub index: %x\n", fw->sub_index); -} - static int start_download_firmware(struct rtw_dev *rtwdev, const u8 *data, u32 size) { + const struct rtw_fw_hdr *fw_hdr = (const struct rtw_fw_hdr *)data; const u8 *cur_fw; u16 val; u32 imem_size; @@ -595,10 +632,10 @@ u32 addr; int ret; - dmem_size = le32_to_cpu(*((__le32 *)(data + FW_HDR_DMEM_SIZE))); - imem_size = le32_to_cpu(*((__le32 *)(data + FW_HDR_IMEM_SIZE))); - emem_size = ((*(data + FW_HDR_MEM_USAGE)) & BIT(4)) ? - le32_to_cpu(*((__le32 *)(data + FW_HDR_EMEM_SIZE))) : 0; + dmem_size = le32_to_cpu(fw_hdr->dmem_size); + imem_size = le32_to_cpu(fw_hdr->imem_size); + emem_size = (fw_hdr->mem_usage & BIT(4)) ? + le32_to_cpu(fw_hdr->emem_size) : 0; dmem_size += FW_HDR_CHKSUM_SIZE; imem_size += FW_HDR_CHKSUM_SIZE; emem_size += emem_size ? FW_HDR_CHKSUM_SIZE : 0; @@ -608,14 +645,14 @@ rtw_write16(rtwdev, REG_MCUFW_CTRL, val); cur_fw = data + FW_HDR_SIZE; - addr = le32_to_cpu(*((__le32 *)(data + FW_HDR_DMEM_ADDR))); + addr = le32_to_cpu(fw_hdr->dmem_addr); addr &= ~BIT(31); ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, dmem_size); if (ret) return ret; cur_fw = data + FW_HDR_SIZE + dmem_size; - addr = le32_to_cpu(*((__le32 *)(data + FW_HDR_IMEM_ADDR))); + addr = le32_to_cpu(fw_hdr->imem_addr); addr &= ~BIT(31); ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, imem_size); if (ret) @@ -623,7 +660,7 @@ if (emem_size) { cur_fw = data + FW_HDR_SIZE + dmem_size + imem_size; - addr = le32_to_cpu(*((__le32 *)(data + FW_HDR_EMEM_ADDR))); + addr = le32_to_cpu(fw_hdr->emem_addr); addr &= ~BIT(31); ret = download_firmware_to_mem(rtwdev, cur_fw, 0, addr, emem_size); @@ -663,7 +700,7 @@ rtw_write16(rtwdev, REG_MCUFW_CTRL, fw_ctrl); } -int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +int __rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) { struct rtw_backup_info bckp[DLFW_RESTORE_REG_NUM]; const u8 *data = fw->firmware->data; @@ -699,15 +736,13 @@ if (ret) goto dlfw_fail; - update_firmware_info(rtwdev, fw); - /* reset desc and index */ rtw_hci_setup(rtwdev); rtwdev->h2c.last_box_num = 0; rtwdev->h2c.seq = 0; - rtw_flag_set(rtwdev, RTW_FLAG_FW_RUNNING); + set_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); return 0; @@ -719,6 +754,230 @@ return ret; } +static void en_download_firmware_legacy(struct rtw_dev *rtwdev, bool en) +{ + int try; + + if (en) { + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + + for (try = 0; try < 10; try++) { + if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_MCUFWDL_EN) + goto fwdl_ready; + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + msleep(20); + } + rtw_err(rtwdev, "failed to check fw download ready\n"); +fwdl_ready: + rtw_write32_clr(rtwdev, REG_MCUFW_CTRL, BIT_ROM_DLEN); + } else { + rtw_write8_clr(rtwdev, REG_MCUFW_CTRL, BIT_MCUFWDL_EN); + } +} + +static void +write_firmware_page(struct rtw_dev *rtwdev, u32 page, const u8 *data, u32 size) +{ + u32 val32; + u32 block_nr; + u32 remain_size; + u32 write_addr = FW_START_ADDR_LEGACY; + const __le32 *ptr = (const __le32 *)data; + u32 block; + __le32 remain_data = 0; + + block_nr = size >> DLFW_BLK_SIZE_SHIFT_LEGACY; + remain_size = size & (DLFW_BLK_SIZE_LEGACY - 1); + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 &= ~BIT_ROM_PGE; + val32 |= (page << BIT_SHIFT_ROM_PGE) & BIT_ROM_PGE; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + for (block = 0; block < block_nr; block++) { + rtw_write32(rtwdev, write_addr, le32_to_cpu(*ptr)); + + write_addr += DLFW_BLK_SIZE_LEGACY; + ptr++; + } + + if (remain_size) { + memcpy(&remain_data, ptr, remain_size); + rtw_write32(rtwdev, write_addr, le32_to_cpu(remain_data)); + } +} + +static int +download_firmware_legacy(struct rtw_dev *rtwdev, const u8 *data, u32 size) +{ + u32 page; + u32 total_page; + u32 last_page_size; + + data += sizeof(struct rtw_fw_hdr_legacy); + size -= sizeof(struct rtw_fw_hdr_legacy); + + total_page = size >> DLFW_PAGE_SIZE_SHIFT_LEGACY; + last_page_size = size & (DLFW_PAGE_SIZE_LEGACY - 1); + + rtw_write8_set(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT); + + for (page = 0; page < total_page; page++) { + write_firmware_page(rtwdev, page, data, DLFW_PAGE_SIZE_LEGACY); + data += DLFW_PAGE_SIZE_LEGACY; + } + if (last_page_size) + write_firmware_page(rtwdev, page, data, last_page_size); + + if (!check_hw_ready(rtwdev, REG_MCUFW_CTRL, BIT_FWDL_CHK_RPT, 1)) { + rtw_err(rtwdev, "failed to check download fimrware report\n"); + return -EINVAL; + } + + return 0; +} + +static int download_firmware_validate_legacy(struct rtw_dev *rtwdev) +{ + u32 val32; + int try; + + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + val32 |= BIT_MCUFWDL_RDY; + val32 &= ~BIT_WINTINI_RDY; + rtw_write32(rtwdev, REG_MCUFW_CTRL, val32); + + wlan_cpu_enable(rtwdev, false); + wlan_cpu_enable(rtwdev, true); + + for (try = 0; try < 10; try++) { + val32 = rtw_read32(rtwdev, REG_MCUFW_CTRL); + if ((val32 & FW_READY_LEGACY) == FW_READY_LEGACY) + return 0; + msleep(20); + } + + rtw_err(rtwdev, "failed to validate fimrware\n"); + return -EINVAL; +} + +int __rtw_download_firmware_legacy(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + int ret = 0; + + en_download_firmware_legacy(rtwdev, true); + ret = download_firmware_legacy(rtwdev, fw->firmware->data, fw->firmware->size); + en_download_firmware_legacy(rtwdev, false); + if (ret) + goto out; + + ret = download_firmware_validate_legacy(rtwdev); + if (ret) + goto out; + + /* reset desc and index */ + rtw_hci_setup(rtwdev); + + rtwdev->h2c.last_box_num = 0; + rtwdev->h2c.seq = 0; + + set_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + +out: + return ret; +} + +int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + return __rtw_download_firmware_legacy(rtwdev, fw); + + return __rtw_download_firmware(rtwdev, fw); +} + +static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) +{ + struct rtw_rqpn *rqpn = rtwdev->fifo.rqpn; + u32 prio_queues = 0; + + if (queues & BIT(IEEE80211_AC_VO)) + prio_queues |= BIT(rqpn->dma_map_vo); + if (queues & BIT(IEEE80211_AC_VI)) + prio_queues |= BIT(rqpn->dma_map_vi); + if (queues & BIT(IEEE80211_AC_BE)) + prio_queues |= BIT(rqpn->dma_map_be); + if (queues & BIT(IEEE80211_AC_BK)) + prio_queues |= BIT(rqpn->dma_map_bk); + + return prio_queues; +} + +static void __rtw_mac_flush_prio_queue(struct rtw_dev *rtwdev, + u32 prio_queue, bool drop) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_prioq_addr *addr; + bool wsize; + u16 avail_page, rsvd_page; + int i; + + if (prio_queue >= RTW_DMA_MAPPING_MAX) + return; + + addr = &chip->prioq_addrs->prio[prio_queue]; + wsize = chip->prioq_addrs->wsize; + + /* check if all of the reserved pages are available for 100 msecs */ + for (i = 0; i < 5; i++) { + rsvd_page = wsize ? rtw_read16(rtwdev, addr->rsvd) : + rtw_read8(rtwdev, addr->rsvd); + avail_page = wsize ? rtw_read16(rtwdev, addr->avail) : + rtw_read8(rtwdev, addr->avail); + if (rsvd_page == avail_page) + return; + + msleep(20); + } + + /* priority queue is still not empty, throw a warning, + * + * Note that if we want to flush the tx queue when having a lot of + * traffic (ex, 100Mbps up), some of the packets could be dropped. + * And it requires like ~2secs to flush the full priority queue. + */ + if (!drop) + rtw_warn(rtwdev, "timed out to flush queue %d\n", prio_queue); +} + +static void rtw_mac_flush_prio_queues(struct rtw_dev *rtwdev, + u32 prio_queues, bool drop) +{ + u32 q; + + for (q = 0; q < RTW_DMA_MAPPING_MAX; q++) + if (prio_queues & BIT(q)) + __rtw_mac_flush_prio_queue(rtwdev, q, drop); +} + +void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop) +{ + u32 prio_queues = 0; + + /* If all of the hardware queues are requested to flush, + * or the priority queues are not mapped yet, + * flush all of the priority queues + */ + if (queues == BIT(rtwdev->hw->queues) - 1 || !rtwdev->fifo.rqpn) + prio_queues = BIT(RTW_DMA_MAPPING_MAX) - 1; + else + prio_queues = get_priority_queues(rtwdev, queues); + + rtw_mac_flush_prio_queues(rtwdev, prio_queues, drop); +} + static int txdma_queue_mapping(struct rtw_dev *rtwdev) { struct rtw_chip_info *chip = rtwdev->chip; @@ -743,6 +1002,7 @@ return -EINVAL; } + rtwdev->fifo.rqpn = rqpn; txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); @@ -753,7 +1013,8 @@ rtw_write8(rtwdev, REG_CR, 0); rtw_write8(rtwdev, REG_CR, MAC_TRX_ENABLE); - rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, REG_H2CQ_CSR, BIT_H2CQ_FULL); return 0; } @@ -768,13 +1029,16 @@ /* config rsvd page num */ fifo->rsvd_drv_pg_num = 8; fifo->txff_pg_num = chip->txff_size >> 7; - fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + - RSVD_PG_H2C_EXTRAINFO_NUM + - RSVD_PG_H2C_STATICINFO_NUM + - RSVD_PG_H2CQ_NUM + - RSVD_PG_CPU_INSTRUCTION_NUM + - RSVD_PG_FW_TXBUF_NUM + - csi_buf_pg_num; + if (rtw_chip_wcpu_11n(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num + + RSVD_PG_H2C_EXTRAINFO_NUM + + RSVD_PG_H2C_STATICINFO_NUM + + RSVD_PG_H2CQ_NUM + + RSVD_PG_CPU_INSTRUCTION_NUM + + RSVD_PG_FW_TXBUF_NUM + + csi_buf_pg_num; if (fifo->rsvd_pg_num > fifo->txff_pg_num) return -ENOMEM; @@ -783,18 +1047,20 @@ fifo->rsvd_boundary = fifo->txff_pg_num - fifo->rsvd_pg_num; cur_pg_addr = fifo->txff_pg_num; - cur_pg_addr -= csi_buf_pg_num; - fifo->rsvd_csibuf_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; - fifo->rsvd_fw_txbuf_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM; - fifo->rsvd_cpu_instr_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2CQ_NUM; - fifo->rsvd_h2cq_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM; - fifo->rsvd_h2c_sta_info_addr = cur_pg_addr; - cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM; - fifo->rsvd_h2c_info_addr = cur_pg_addr; + if (rtw_chip_wcpu_11ac(rtwdev)) { + cur_pg_addr -= csi_buf_pg_num; + fifo->rsvd_csibuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_FW_TXBUF_NUM; + fifo->rsvd_fw_txbuf_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_CPU_INSTRUCTION_NUM; + fifo->rsvd_cpu_instr_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2CQ_NUM; + fifo->rsvd_h2cq_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_STATICINFO_NUM; + fifo->rsvd_h2c_sta_info_addr = cur_pg_addr; + cur_pg_addr -= RSVD_PG_H2C_EXTRAINFO_NUM; + fifo->rsvd_h2c_info_addr = cur_pg_addr; + } cur_pg_addr -= fifo->rsvd_drv_pg_num; fifo->rsvd_drv_addr = cur_pg_addr; @@ -806,6 +1072,63 @@ return 0; } +static int __priority_queue_cfg(struct rtw_dev *rtwdev, + struct rtw_page_table *pg_tbl, u16 pubq_num) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + struct rtw_chip_info *chip = rtwdev->chip; + + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, pg_tbl->hq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_2, pg_tbl->lq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_3, pg_tbl->nq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_4, pg_tbl->exq_num); + rtw_write16(rtwdev, REG_FIFOPAGE_INFO_5, pubq_num); + rtw_write32_set(rtwdev, REG_RQPN_CTRL_2, BIT_LD_RQPN); + + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, fifo->rsvd_boundary); + rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL + 2, BIT_EN_WR_FREE_TAIL >> 16); + + rtw_write16(rtwdev, REG_BCNQ_BDNY_V1, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); + rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); + rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) + return -EBUSY; + + rtw_write8(rtwdev, REG_CR + 3, 0); + + return 0; +} + +static int __priority_queue_cfg_legacy(struct rtw_dev *rtwdev, + struct rtw_page_table *pg_tbl, u16 pubq_num) +{ + struct rtw_fifo_conf *fifo = &rtwdev->fifo; + struct rtw_chip_info *chip = rtwdev->chip; + u32 val32; + + val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); + rtw_write32(rtwdev, REG_RQPN_NPQ, val32); + val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); + rtw_write32(rtwdev, REG_RQPN, val32); + + rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); + rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, chip->rxff_size - REPORT_BUF - 1); + rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); + rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); + + rtw_write32_set(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT); + + if (!check_hw_ready(rtwdev, REG_AUTO_LLT, BIT_AUTO_INIT_LLT, 0)) + return -EBUSY; + + return 0; +} + static int priority_queue_cfg(struct rtw_dev *rtwdev) { struct rtw_fifo_conf *fifo = &rtwdev->fifo; @@ -838,28 +1161,10 @@ pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_1, pg_tbl->hq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_2, pg_tbl->lq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_3, pg_tbl->nq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_4, pg_tbl->exq_num); - rtw_write16(rtwdev, REG_FIFOPAGE_INFO_5, pubq_num); - rtw_write32_set(rtwdev, REG_RQPN_CTRL_2, BIT_LD_RQPN); - - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2, fifo->rsvd_boundary); - rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL + 2, BIT_EN_WR_FREE_TAIL >> 16); - - rtw_write16(rtwdev, REG_BCNQ_BDNY_V1, fifo->rsvd_boundary); - rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2 + 2, fifo->rsvd_boundary); - rtw_write16(rtwdev, REG_BCNQ1_BDNY_V1, fifo->rsvd_boundary); - rtw_write32(rtwdev, REG_RXFF_BNDY, chip->rxff_size - C2H_PKT_BUF - 1); - rtw_write8_set(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1); - - if (!check_hw_ready(rtwdev, REG_AUTO_LLT_V1, BIT_AUTO_INIT_LLT_V1, 0)) - return -EBUSY; - - rtw_write8(rtwdev, REG_CR + 3, 0); - - return 0; + if (rtw_chip_wcpu_11n(rtwdev)) + return __priority_queue_cfg_legacy(rtwdev, pg_tbl, pubq_num); + else + return __priority_queue_cfg(rtwdev, pg_tbl, pubq_num); } static int init_h2c(struct rtw_dev *rtwdev) @@ -872,6 +1177,9 @@ u32 h2cq_free; u32 wp, rp; + if (rtw_chip_wcpu_11n(rtwdev)) + return 0; + h2cq_addr = fifo->rsvd_h2cq_addr << TX_PAGE_SIZE_SHIFT; h2cq_size = RSVD_PG_H2CQ_NUM << TX_PAGE_SIZE_SHIFT; @@ -936,11 +1244,13 @@ u8 value8; rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); - value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); - value8 &= 0xF0; - /* For rxdesc len = 0 issue */ - value8 |= 0xF; - rtw_write8(rtwdev, REG_TRXFF_BNDY + 1, value8); + if (rtw_chip_wcpu_11ac(rtwdev)) { + value8 = rtw_read8(rtwdev, REG_TRXFF_BNDY + 1); + value8 &= 0xF0; + /* For rxdesc len = 0 issue */ + value8 |= 0xF; + rtw_write8(rtwdev, REG_TRXFF_BNDY + 1, value8); + } rtw_write32_set(rtwdev, REG_RCR, BIT_APP_PHYSTS); rtw_write32_clr(rtwdev, REG_WMAC_OPTION_FUNCTION + 4, BIT(8) | BIT(9)); @@ -964,5 +1274,7 @@ if (ret) return ret; + rtw_hci_interface_cfg(rtwdev); + return 0; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/mac.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/mac.h @@ -10,6 +10,7 @@ #define SDIO_LOCAL_OFFSET 0x10250000 #define DDMA_POLLING_COUNT 1000 #define C2H_PKT_BUF 256 +#define REPORT_BUF 128 #define PHY_STATUS_SIZE 4 #define ILLEGAL_KEY_GROUP 0xFAAAAA00 @@ -31,5 +32,11 @@ void rtw_mac_power_off(struct rtw_dev *rtwdev); int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); int rtw_mac_init(struct rtw_dev *rtwdev); +void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); + +static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +{ + rtw_mac_flush_queues(rtwdev, BIT(rtwdev->hw->queues) - 1, drop); +} #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/mac80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -10,26 +10,39 @@ #include "coex.h" #include "ps.h" #include "reg.h" +#include "bf.h" #include "debug.h" +#include "wow.h" static void rtw_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct rtw_dev *rtwdev = hw->priv; - struct rtw_tx_pkt_info pkt_info = {0}; - if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING)) - goto out; + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) { + ieee80211_free_txskb(hw, skb); + return; + } - rtw_tx_pkt_info_update(rtwdev, &pkt_info, control, skb); - if (rtw_hci_tx(rtwdev, &pkt_info, skb)) - goto out; + rtw_tx(rtwdev, control, skb); +} - return; +static void rtw_ops_wake_tx_queue(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv; -out: - ieee80211_free_txskb(hw, skb); + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + return; + + spin_lock_bh(&rtwdev->txq_lock); + if (list_empty(&rtwtxq->list)) + list_add_tail(&rtwtxq->list, &rtwdev->txqs); + spin_unlock_bh(&rtwdev->txq_lock); + + tasklet_schedule(&rtwdev->tx_tasklet); } static int rtw_ops_start(struct ieee80211_hw *hw) @@ -60,21 +73,33 @@ mutex_lock(&rtwdev->mutex); - if (changed & IEEE80211_CONF_CHANGE_IDLE) { - if (hw->conf.flags & IEEE80211_CONF_IDLE) { - rtw_enter_ips(rtwdev); + rtw_leave_lps_deep(rtwdev); + + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + !(hw->conf.flags & IEEE80211_CONF_IDLE)) { + ret = rtw_leave_ips(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave idle state\n"); + goto out; + } + } + + if (changed & IEEE80211_CONF_CHANGE_PS) { + if (hw->conf.flags & IEEE80211_CONF_PS) { + rtwdev->ps_enabled = true; } else { - ret = rtw_leave_ips(rtwdev); - if (ret) { - rtw_err(rtwdev, "failed to leave idle state\n"); - goto out; - } + rtwdev->ps_enabled = false; + rtw_leave_lps(rtwdev); } } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) rtw_set_channel(rtwdev); + if ((changed & IEEE80211_CONF_CHANGE_IDLE) && + (hw->conf.flags & IEEE80211_CONF_IDLE)) + rtw_enter_ips(rtwdev); + out: mutex_unlock(&rtwdev->mutex); return ret; @@ -129,31 +154,40 @@ u8 bcn_ctrl = 0; rtwvif->port = port; - rtwvif->vif = vif; rtwvif->stats.tx_unicast = 0; rtwvif->stats.rx_unicast = 0; rtwvif->stats.tx_cnt = 0; rtwvif->stats.rx_cnt = 0; - rtwvif->in_lps = false; + memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee)); rtwvif->conf = &rtw_vif_port[port]; + rtw_txq_init(rtwdev, vif->txq); + INIT_LIST_HEAD(&rtwvif->rsvd_page_list); mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: + rtw_add_rsvd_page_bcn(rtwdev, rtwvif); net_type = RTW_NET_AP_MODE; bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; break; case NL80211_IFTYPE_ADHOC: + rtw_add_rsvd_page_bcn(rtwdev, rtwvif); net_type = RTW_NET_AD_HOC; bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; break; case NL80211_IFTYPE_STATION: - default: + rtw_add_rsvd_page_sta(rtwdev, rtwvif); net_type = RTW_NET_NO_LINK; bcn_ctrl = BIT_EN_BCN_FUNCTION; break; + default: + WARN_ON(1); + mutex_unlock(&rtwdev->mutex); + return -EINVAL; } ether_addr_copy(rtwvif->mac_addr, vif->addr); @@ -181,6 +215,11 @@ mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + + rtw_txq_cleanup(rtwdev, vif->txq); + rtw_remove_rsvd_page(rtwdev, rtwvif); + eth_zero_addr(rtwvif->mac_addr); config |= PORT_SET_MAC_ADDR; rtwvif->net_type = RTW_NET_NO_LINK; @@ -204,11 +243,13 @@ mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + if (changed_flags & FIF_ALLMULTI) { if (*new_flags & FIF_ALLMULTI) - rtwdev->hal.rcr |= BIT_AM | BIT_AB; + rtwdev->hal.rcr |= BIT_AM; else - rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); + rtwdev->hal.rcr &= ~(BIT_AM); } if (changed_flags & FIF_FCSFAIL) { if (*new_flags & FIF_FCSFAIL) @@ -238,6 +279,54 @@ mutex_unlock(&rtwdev->mutex); } +/* Only have one group of EDCA parameters now */ +static const u32 ac_to_edca_param[IEEE80211_NUM_ACS] = { + [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM, + [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM, + [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM, + [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM, +}; + +static u8 rtw_aifsn_to_aifs(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, u8 aifsn) +{ + struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif); + u8 slot_time; + u8 sifs; + + slot_time = vif->bss_conf.use_short_slot ? 9 : 20; + sifs = rtwdev->hal.current_band_type == RTW_BAND_5G ? 16 : 10; + + return aifsn * slot_time + sifs; +} + +static void __rtw_conf_tx(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, u16 ac) +{ + struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac]; + u32 edca_param = ac_to_edca_param[ac]; + u8 ecw_max, ecw_min; + u8 aifs; + + /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */ + ecw_max = ilog2(params->cw_max + 1); + ecw_min = ilog2(params->cw_min + 1); + aifs = rtw_aifsn_to_aifs(rtwdev, rtwvif, params->aifs); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_TXOP_LMT, params->txop); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMAX, ecw_max); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMIN, ecw_min); + rtw_write32_mask(rtwdev, edca_param, BIT_MASK_AIFS, aifs); +} + +static void rtw_conf_tx(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + u16 ac; + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) + __rtw_conf_tx(rtwdev, rtwvif, ac); +} + static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *conf, @@ -249,26 +338,26 @@ mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + if (changed & BSS_CHANGED_ASSOC) { - struct rtw_chip_info *chip = rtwdev->chip; enum rtw_net_type net_type; if (conf->assoc) { rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH); net_type = RTW_NET_MGD_LINKED; - chip->ops->phy_calibration(rtwdev); rtwvif->aid = conf->aid; - rtw_add_rsvd_page(rtwdev, RSVD_PS_POLL, true); - rtw_add_rsvd_page(rtwdev, RSVD_QOS_NULL, true); - rtw_add_rsvd_page(rtwdev, RSVD_NULL, true); - rtw_fw_download_rsvd_page(rtwdev, vif); + rtw_fw_download_rsvd_page(rtwdev); rtw_send_rsvd_page_h2c(rtwdev); rtw_coex_media_status_notify(rtwdev, conf->assoc); + if (rtw_bf_support) + rtw_bf_assoc(rtwdev, vif, conf); } else { + rtw_leave_lps(rtwdev); net_type = RTW_NET_NO_LINK; rtwvif->aid = 0; - rtw_reset_rsvd_page(rtwdev); + rtw_bf_disassoc(rtwdev, vif, conf); } rtwvif->net_type = net_type; @@ -282,13 +371,38 @@ } if (changed & BSS_CHANGED_BEACON) - rtw_fw_download_rsvd_page(rtwdev, vif); + rtw_fw_download_rsvd_page(rtwdev); + + if (changed & BSS_CHANGED_MU_GROUPS) + rtw_chip_set_gid_table(rtwdev, vif, conf); + + if (changed & BSS_CHANGED_ERP_SLOT) + rtw_conf_tx(rtwdev, rtwvif); rtw_vif_port_config(rtwdev, rtwvif, config); mutex_unlock(&rtwdev->mutex); } +static int rtw_ops_conf_tx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u16 ac, + const struct ieee80211_tx_queue_params *params) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + + mutex_lock(&rtwdev->mutex); + + rtw_leave_lps_deep(rtwdev); + + rtwvif->tx_params[ac] = *params; + __rtw_conf_tx(rtwdev, rtwvif, ac); + + mutex_unlock(&rtwdev->mutex); + + return 0; +} + static u8 rtw_acquire_macid(struct rtw_dev *rtwdev) { unsigned long mac_id; @@ -311,6 +425,7 @@ { struct rtw_dev *rtwdev = hw->priv; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + int i; int ret = 0; mutex_lock(&rtwdev->mutex); @@ -325,6 +440,8 @@ si->vif = vif; si->init_ra_lv = 1; ewma_rssi_init(&si->avg_rssi); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw_txq_init(rtwdev, sta->txq[i]); rtw_update_sta_info(rtwdev, si); rtw_fw_media_status_report(rtwdev, si->mac_id, true); @@ -345,12 +462,18 @@ { struct rtw_dev *rtwdev = hw->priv; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + int i; mutex_lock(&rtwdev->mutex); rtw_release_macid(rtwdev, si->mac_id); rtw_fw_media_status_report(rtwdev, si->mac_id, false); + for (i = 0; i < ARRAY_SIZE(sta->txq); i++) + rtw_txq_cleanup(rtwdev, sta->txq[i]); + + kfree(si->mask); + rtwdev->sta_cnt--; rtw_info(rtwdev, "sta %pM with macid %d left\n", @@ -389,6 +512,9 @@ case WLAN_CIPHER_SUITE_BIP_CMAC_256: case WLAN_CIPHER_SUITE_BIP_GMAC_128: case WLAN_CIPHER_SUITE_BIP_GMAC_256: + case WLAN_CIPHER_SUITE_CCMP_256: + case WLAN_CIPHER_SUITE_GCMP: + case WLAN_CIPHER_SUITE_GCMP_256: /* suppress error messages */ return -EOPNOTSUPP; default: @@ -397,6 +523,8 @@ mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { hw_key_idx = rtw_sec_get_free_cam(sec); } else { @@ -418,10 +546,15 @@ hw_key_type, hw_key_idx); break; case DISABLE_KEY: + rtw_mac_flush_all_queues(rtwdev, false); rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx); break; } + /* download new cam settings for PG to backup */ + if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) + rtw_fw_download_rsvd_page(rtwdev); + out: mutex_unlock(&rtwdev->mutex); @@ -434,17 +567,21 @@ { struct ieee80211_sta *sta = params->sta; u16 tid = params->tid; + struct ieee80211_txq *txq = sta->txq[tid]; + struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv; switch (params->action) { case IEEE80211_AMPDU_TX_START: - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; + return IEEE80211_AMPDU_TX_START_IMMEDIATE; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + clear_bit(RTW_TXQ_AMPDU, &rtwtxq->flags); ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: + set_bit(RTW_TXQ_AMPDU, &rtwtxq->flags); + break; case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_STOP: break; @@ -456,6 +593,20 @@ return 0; } +static bool rtw_ops_can_aggregate_in_amsdu(struct ieee80211_hw *hw, + struct sk_buff *head, + struct sk_buff *skb) +{ + struct rtw_dev *rtwdev = hw->priv; + struct rtw_hal *hal = &rtwdev->hal; + + /* we don't want to enable TX AMSDU on 2.4G */ + if (hal->current_band_type == RTW_BAND_2G) + return false; + + return true; +} + static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, const u8 *mac_addr) @@ -464,18 +615,18 @@ struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; u32 config = 0; - rtw_leave_lps(rtwdev, rtwvif); - mutex_lock(&rtwdev->mutex); + rtw_leave_lps(rtwdev); + ether_addr_copy(rtwvif->mac_addr, mac_addr); config |= PORT_SET_MAC_ADDR; rtw_vif_port_config(rtwdev, rtwvif, config); rtw_coex_scan_notify(rtwdev, COEX_SCAN_START); - rtw_flag_set(rtwdev, RTW_FLAG_DIG_DISABLE); - rtw_flag_set(rtwdev, RTW_FLAG_SCANNING); + set_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); + set_bit(RTW_FLAG_SCANNING, rtwdev->flags); mutex_unlock(&rtwdev->mutex); } @@ -489,8 +640,8 @@ mutex_lock(&rtwdev->mutex); - rtw_flag_clear(rtwdev, RTW_FLAG_SCANNING); - rtw_flag_clear(rtwdev, RTW_FLAG_DIG_DISABLE); + clear_bit(RTW_FLAG_SCANNING, rtwdev->flags); + clear_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags); ether_addr_copy(rtwvif->mac_addr, vif->addr); config |= PORT_SET_MAC_ADDR; @@ -508,12 +659,138 @@ struct rtw_dev *rtwdev = hw->priv; mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START); + rtw_chip_prepare_tx(rtwdev); mutex_unlock(&rtwdev->mutex); } +static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtwdev->rts_threshold = value; + mutex_unlock(&rtwdev->mutex); + + return 0; +} + +static void rtw_ops_sta_statistics(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct station_info *sinfo) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + sinfo->txrate = si->ra_report.txrate; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +} + +static void rtw_ops_flush(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 queues, bool drop) +{ + struct rtw_dev *rtwdev = hw->priv; + + mutex_lock(&rtwdev->mutex); + rtw_leave_lps_deep(rtwdev); + + rtw_mac_flush_queues(rtwdev, queues, drop); + mutex_unlock(&rtwdev->mutex); +} + +struct rtw_iter_bitrate_mask_data { + struct rtw_dev *rtwdev; + struct ieee80211_vif *vif; + const struct cfg80211_bitrate_mask *mask; +}; + +static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_iter_bitrate_mask_data *br_data = data; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + + if (si->vif != br_data->vif) + return; + + /* free previous mask setting */ + kfree(si->mask); + si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask), + GFP_ATOMIC); + if (!si->mask) { + si->use_cfg_mask = false; + return; + } + + si->use_cfg_mask = true; + rtw_update_sta_info(br_data->rtwdev, si); +} + +static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_iter_bitrate_mask_data br_data; + + br_data.rtwdev = rtwdev; + br_data.vif = vif; + br_data.mask = mask; + rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data); +} + +static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + const struct cfg80211_bitrate_mask *mask) +{ + struct rtw_dev *rtwdev = hw->priv; + + rtw_ra_mask_info_update(rtwdev, vif, mask); + + return 0; +} + +#ifdef CONFIG_PM +static int rtw_ops_suspend(struct ieee80211_hw *hw, + struct cfg80211_wowlan *wowlan) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + mutex_lock(&rtwdev->mutex); + ret = rtw_wow_suspend(rtwdev, wowlan); + if (ret) + rtw_err(rtwdev, "failed to suspend for wow %d\n", ret); + mutex_unlock(&rtwdev->mutex); + + return ret ? 1 : 0; +} + +static int rtw_ops_resume(struct ieee80211_hw *hw) +{ + struct rtw_dev *rtwdev = hw->priv; + int ret; + + mutex_lock(&rtwdev->mutex); + ret = rtw_wow_resume(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to resume for wow %d\n", ret); + mutex_unlock(&rtwdev->mutex); + + return ret ? 1 : 0; +} + +static void rtw_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled) +{ + struct rtw_dev *rtwdev = hw->priv; + + device_set_wakeup_enable(rtwdev->dev, enabled); +} +#endif + const struct ieee80211_ops rtw_ops = { .tx = rtw_ops_tx, + .wake_tx_queue = rtw_ops_wake_tx_queue, .start = rtw_ops_start, .stop = rtw_ops_stop, .config = rtw_ops_config, @@ -521,12 +798,23 @@ .remove_interface = rtw_ops_remove_interface, .configure_filter = rtw_ops_configure_filter, .bss_info_changed = rtw_ops_bss_info_changed, + .conf_tx = rtw_ops_conf_tx, .sta_add = rtw_ops_sta_add, .sta_remove = rtw_ops_sta_remove, .set_key = rtw_ops_set_key, .ampdu_action = rtw_ops_ampdu_action, + .can_aggregate_in_amsdu = rtw_ops_can_aggregate_in_amsdu, .sw_scan_start = rtw_ops_sw_scan_start, .sw_scan_complete = rtw_ops_sw_scan_complete, .mgd_prepare_tx = rtw_ops_mgd_prepare_tx, + .set_rts_threshold = rtw_ops_set_rts_threshold, + .sta_statistics = rtw_ops_sta_statistics, + .flush = rtw_ops_flush, + .set_bitrate_mask = rtw_ops_set_bitrate_mask, +#ifdef CONFIG_PM + .suspend = rtw_ops_suspend, + .resume = rtw_ops_resume, + .set_wakeup = rtw_ops_set_wakeup, +#endif }; EXPORT_SYMBOL(rtw_ops); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/main.c @@ -12,16 +12,24 @@ #include "phy.h" #include "reg.h" #include "efuse.h" +#include "tx.h" #include "debug.h" +#include "bf.h" +#include "sar.h" -static bool rtw_fw_support_lps; +unsigned int rtw_fw_lps_deep_mode; +EXPORT_SYMBOL(rtw_fw_lps_deep_mode); +bool rtw_bf_support = true; unsigned int rtw_debug_mask; EXPORT_SYMBOL(rtw_debug_mask); +bool rtw_edcca_enabled = true; -module_param_named(support_lps, rtw_fw_support_lps, bool, 0644); +module_param_named(lps_deep_mode, rtw_fw_lps_deep_mode, uint, 0644); +module_param_named(support_bf, rtw_bf_support, bool, 0644); module_param_named(debug_mask, rtw_debug_mask, uint, 0644); -MODULE_PARM_DESC(support_lps, "Set Y to enable Leisure Power Save support, to turn radio off between beacons"); +MODULE_PARM_DESC(lps_deep_mode, "Deeper PS mode. If 0, deep PS is disabled"); +MODULE_PARM_DESC(support_bf, "Set Y to enable beamformee support"); MODULE_PARM_DESC(debug_mask, "Debugging mask"); static struct ieee80211_channel rtw_channeltable_2g[] = { @@ -84,6 +92,18 @@ {.bitrate = 540, .hw_value = 0x0b,}, }; +u16 rtw_desc_to_bitrate(u8 desc_rate) +{ + struct ieee80211_rate rate; + + if (WARN(desc_rate >= ARRAY_SIZE(rtw_ratetable), "invalid desc rate\n")) + return 0; + + rate = rtw_ratetable[desc_rate]; + + return rate.bitrate; +} + static struct ieee80211_supported_band rtw_band_2ghz = { .band = NL80211_BAND_2GHZ, @@ -112,29 +132,39 @@ }; struct rtw_watch_dog_iter_data { + struct rtw_dev *rtwdev; struct rtw_vif *rtwvif; - bool active; - u8 assoc_cnt; }; +static void rtw_dynamic_csi_rate(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +{ + struct rtw_bf_info *bf_info = &rtwdev->bf_info; + u8 fix_rate_enable = 0; + u8 new_csi_rate_idx; + + if (rtwvif->bfee.role != RTW_BFEE_SU && + rtwvif->bfee.role != RTW_BFEE_MU) + return; + + rtw_chip_cfg_csi_rate(rtwdev, rtwdev->dm_info.min_rssi, + bf_info->cur_csi_rpt_rate, + fix_rate_enable, &new_csi_rate_idx); + + if (new_csi_rate_idx != bf_info->cur_csi_rpt_rate) + bf_info->cur_csi_rpt_rate = new_csi_rate_idx; +} + static void rtw_vif_watch_dog_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { struct rtw_watch_dog_iter_data *iter_data = data; struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; - if (vif->type == NL80211_IFTYPE_STATION) { - if (vif->bss_conf.assoc) { - iter_data->assoc_cnt++; + if (vif->type == NL80211_IFTYPE_STATION) + if (vif->bss_conf.assoc) iter_data->rtwvif = rtwvif; - } - if (rtwvif->stats.tx_cnt > RTW_LPS_THRESHOLD || - rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD) - iter_data->active = true; - } else { - /* only STATION mode can enter lps */ - iter_data->active = true; - } + + rtw_dynamic_csi_rate(iter_data->rtwdev, rtwvif); rtwvif->stats.tx_unicast = 0; rtwvif->stats.rx_unicast = 0; @@ -149,46 +179,74 @@ { struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, watch_dog_work.work); + struct rtw_traffic_stats *stats = &rtwdev->stats; struct rtw_watch_dog_iter_data data = {}; - bool busy_traffic = rtw_flag_check(rtwdev, RTW_FLAG_BUSY_TRAFFIC); + bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); + bool ps_active; - if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING)) - return; + mutex_lock(&rtwdev->mutex); + + if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) + goto unlock; ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, RTW_WATCH_DOG_DELAY_TIME); if (rtwdev->stats.tx_cnt > 100 || rtwdev->stats.rx_cnt > 100) - rtw_flag_set(rtwdev, RTW_FLAG_BUSY_TRAFFIC); + set_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); else - rtw_flag_clear(rtwdev, RTW_FLAG_BUSY_TRAFFIC); + clear_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); - if (busy_traffic != rtw_flag_check(rtwdev, RTW_FLAG_BUSY_TRAFFIC)) + if (busy_traffic != test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags)) rtw_coex_wl_status_change_notify(rtwdev); + if (stats->tx_cnt > RTW_LPS_THRESHOLD || + stats->rx_cnt > RTW_LPS_THRESHOLD) + ps_active = true; + else + ps_active = false; + + ewma_tp_add(&stats->tx_ewma_tp, + (u32)(stats->tx_unicast >> RTW_TP_SHIFT)); + ewma_tp_add(&stats->rx_ewma_tp, + (u32)(stats->rx_unicast >> RTW_TP_SHIFT)); + stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); + stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); + /* reset tx/rx statictics */ - rtwdev->stats.tx_unicast = 0; - rtwdev->stats.rx_unicast = 0; - rtwdev->stats.tx_cnt = 0; - rtwdev->stats.rx_cnt = 0; + stats->tx_unicast = 0; + stats->rx_unicast = 0; + stats->tx_cnt = 0; + stats->rx_cnt = 0; + + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + goto unlock; + + /* make sure BB/RF is working for dynamic mech */ + rtw_leave_lps(rtwdev); + + rtw_phy_dynamic_mechanism(rtwdev); + data.rtwdev = rtwdev; /* use atomic version to avoid taking local->iflist_mtx mutex */ rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data); /* fw supports only one station associated to enter lps, if there are * more than two stations associated to the AP, then we can not enter * lps, because fw does not handle the overlapped beacon interval + * + * mac80211 should iterate vifs and determine if driver can enter + * ps by passing IEEE80211_CONF_PS to us, all we need to do is to + * get that vif and check if device is having traffic more than the + * threshold. */ - if (rtw_fw_support_lps && - data.rtwvif && !data.active && data.assoc_cnt == 1) - rtw_enter_lps(rtwdev, data.rtwvif); - - if (rtw_flag_check(rtwdev, RTW_FLAG_SCANNING)) - return; - - rtw_phy_dynamic_mechanism(rtwdev); + if (rtwdev->ps_enabled && data.rtwvif && !ps_active) + rtw_enter_lps(rtwdev, data.rtwvif->port); rtwdev->watch_dog_cnt++; + +unlock: + mutex_unlock(&rtwdev->mutex); } static void rtw_c2h_work(struct work_struct *work) @@ -203,6 +261,40 @@ } } +struct rtw_txq_ba_iter_data { +}; + +static void rtw_txq_ba_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + int ret; + u8 tid; + + tid = find_first_bit(si->tid_ba, IEEE80211_NUM_TIDS); + while (tid != IEEE80211_NUM_TIDS) { + clear_bit(tid, si->tid_ba); + ret = ieee80211_start_tx_ba_session(sta, tid, 0); + if (ret == -EINVAL) { + struct ieee80211_txq *txq; + struct rtw_txq *rtwtxq; + + txq = sta->txq[tid]; + rtwtxq = (struct rtw_txq *)txq->drv_priv; + set_bit(RTW_TXQ_BLOCK_BA, &rtwtxq->flags); + } + + tid = find_first_bit(si->tid_ba, IEEE80211_NUM_TIDS); + } +} + +static void rtw_txq_ba_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ba_work); + struct rtw_txq_ba_iter_data data; + + rtw_iterate_stas_atomic(rtwdev, rtw_txq_ba_iter, &data); +} + void rtw_get_channel_params(struct cfg80211_chan_def *chandef, struct rtw_channel_params *chan_params) { @@ -226,15 +318,15 @@ case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: bandwidth = RTW_CHANNEL_WIDTH_20; - primary_chan_idx = 0; + primary_chan_idx = RTW_SC_DONT_CARE; break; case NL80211_CHAN_WIDTH_40: bandwidth = RTW_CHANNEL_WIDTH_40; if (primary_freq > center_freq) { - primary_chan_idx = 1; + primary_chan_idx = RTW_SC_20_UPPER; center_chan -= 2; } else { - primary_chan_idx = 2; + primary_chan_idx = RTW_SC_20_LOWER; center_chan += 2; } break; @@ -242,10 +334,10 @@ bandwidth = RTW_CHANNEL_WIDTH_80; if (primary_freq > center_freq) { if (primary_freq - center_freq == 10) { - primary_chan_idx = 1; + primary_chan_idx = RTW_SC_20_UPPER; center_chan -= 2; } else { - primary_chan_idx = 3; + primary_chan_idx = RTW_SC_20_UPMOST; center_chan -= 6; } /* assign the center channel used @@ -254,10 +346,10 @@ cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan + 4; } else { if (center_freq - primary_freq == 10) { - primary_chan_idx = 2; + primary_chan_idx = RTW_SC_20_LOWER; center_chan += 2; } else { - primary_chan_idx = 4; + primary_chan_idx = RTW_SC_20_LOWEST; center_chan += 6; } /* assign the center channel used @@ -311,13 +403,29 @@ if (hal->current_band_type == RTW_BAND_5G) { rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_5G); } else { - if (rtw_flag_check(rtwdev, RTW_FLAG_SCANNING)) + if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_24G); else rtw_coex_switchband_notify(rtwdev, COEX_SWITCH_TO_24G_NOFORSCAN); } rtw_phy_set_tx_power_level(rtwdev, center_chan); + + /* If set channel isn't for scanning, we'll do RF calibration once in + * this channel while mgd_prepare_tx. + */ + if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) + rtwdev->need_rfk = true; +} + +void rtw_chip_prepare_tx(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + + if (rtwdev->need_rfk) { + rtwdev->need_rfk = false; + chip->ops->phy_calibration(rtwdev); + } } static void rtw_vif_write_addr(struct rtw_dev *rtwdev, u32 start, u8 *addr) @@ -382,6 +490,7 @@ static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 hw_ant_num) { struct rtw_hal *hal = &rtwdev->hal; + struct rtw_chip_info *chip = rtwdev->chip; if (hw_ant_num == EFUSE_HW_CAP_IGNORE || hw_ant_num >= hal->rf_path_num) @@ -391,6 +500,8 @@ case 1: hal->rf_type = RF_1T1R; hal->rf_path_num = 1; + if (!chip->fix_rf_phy_num) + hal->rf_phy_num = hal->rf_path_num; hal->antenna_tx = BB_PATH_A; hal->antenna_rx = BB_PATH_A; break; @@ -529,12 +640,71 @@ #define RA_MASK_OFDM_IN_HT_2G 0x00010 #define RA_MASK_OFDM_IN_HT_5G 0x00030 +static u64 rtw_update_rate_mask(struct rtw_dev *rtwdev, + struct rtw_sta_info *si, + u64 ra_mask, bool is_vht_enable, + u8 wireless_set) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct cfg80211_bitrate_mask *mask = si->mask; + u64 cfg_mask = GENMASK_ULL(63, 0); + u8 rssi_level, band; + + if (wireless_set != WIRELESS_CCK) { + rssi_level = si->rssi_level; + if (rssi_level == 0) + ra_mask &= 0xffffffffffffffffULL; + else if (rssi_level == 1) + ra_mask &= 0xfffffffffffffff0ULL; + else if (rssi_level == 2) + ra_mask &= 0xffffffffffffefe0ULL; + else if (rssi_level == 3) + ra_mask &= 0xffffffffffffcfc0ULL; + else if (rssi_level == 4) + ra_mask &= 0xffffffffffff8f80ULL; + else if (rssi_level >= 5) + ra_mask &= 0xffffffffffff0f00ULL; + } + + if (!si->use_cfg_mask) + return ra_mask; + + band = hal->current_band_type; + if (band == RTW_BAND_2G) { + band = NL80211_BAND_2GHZ; + cfg_mask = mask->control[band].legacy; + } else if (band == RTW_BAND_5G) { + band = NL80211_BAND_5GHZ; + cfg_mask = u64_encode_bits(mask->control[band].legacy, + RA_MASK_OFDM_RATES); + } + + if (!is_vht_enable) { + if (ra_mask & RA_MASK_HT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[0], + RA_MASK_HT_RATES_1SS); + if (ra_mask & RA_MASK_HT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].ht_mcs[1], + RA_MASK_HT_RATES_2SS); + } else { + if (ra_mask & RA_MASK_VHT_RATES_1SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[0], + RA_MASK_VHT_RATES_1SS); + if (ra_mask & RA_MASK_VHT_RATES_2SS) + cfg_mask |= u64_encode_bits(mask->control[band].vht_mcs[1], + RA_MASK_VHT_RATES_2SS); + } + + ra_mask &= cfg_mask; + + return ra_mask; +} + void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) { struct ieee80211_sta *sta = si->sta; struct rtw_efuse *efuse = &rtwdev->efuse; struct rtw_hal *hal = &rtwdev->hal; - u8 rssi_level; u8 wireless_set; u8 bw_mode; u8 rate_id; @@ -553,20 +723,18 @@ stbc_en = VHT_STBC_EN; if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) ldpc_en = VHT_LDPC_EN; - if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) - is_support_sgi = true; } else if (sta->ht_cap.ht_supported) { - ra_mask |= (sta->ht_cap.mcs.rx_mask[NL80211_BAND_5GHZ] << 20) | - (sta->ht_cap.mcs.rx_mask[NL80211_BAND_2GHZ] << 12); + ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) | + (sta->ht_cap.mcs.rx_mask[0] << 12); if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = HT_STBC_EN; if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) ldpc_en = HT_LDPC_EN; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20 || - sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) - is_support_sgi = true; } + if (efuse->hw_cap.nss == 1) + ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + if (hal->current_band_type == RTW_BAND_5G) { ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; if (sta->vht_cap.vht_supported) { @@ -600,20 +768,21 @@ wireless_set = 0; } - if (efuse->hw_cap.nss == 1) { - ra_mask &= RA_MASK_VHT_RATES_1SS; - ra_mask &= RA_MASK_HT_RATES_1SS; - } - switch (sta->bandwidth) { case IEEE80211_STA_RX_BW_80: bw_mode = RTW_CHANNEL_WIDTH_80; + is_support_sgi = sta->vht_cap.vht_supported && + (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); break; case IEEE80211_STA_RX_BW_40: bw_mode = RTW_CHANNEL_WIDTH_40; + is_support_sgi = sta->ht_cap.ht_supported && + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); break; default: bw_mode = RTW_CHANNEL_WIDTH_20; + is_support_sgi = sta->ht_cap.ht_supported && + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); break; } @@ -627,21 +796,8 @@ rate_id = get_rate_id(wireless_set, bw_mode, tx_num); - if (wireless_set != WIRELESS_CCK) { - rssi_level = si->rssi_level; - if (rssi_level == 0) - ra_mask &= 0xffffffffffffffffULL; - else if (rssi_level == 1) - ra_mask &= 0xfffffffffffffff0ULL; - else if (rssi_level == 2) - ra_mask &= 0xffffffffffffefe0ULL; - else if (rssi_level == 3) - ra_mask &= 0xffffffffffffcfc0ULL; - else if (rssi_level == 4) - ra_mask &= 0xffffffffffff8f80ULL; - else if (rssi_level >= 5) - ra_mask &= 0xffffffffffff0f00ULL; - } + ra_mask = rtw_update_rate_mask(rtwdev, si, ra_mask, is_vht_enable, + wireless_set); si->bw_mode = bw_mode; si->stbc_en = stbc_en; @@ -656,6 +812,26 @@ rtw_fw_send_ra_info(rtwdev, si); } +static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; + + fw = &rtwdev->fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + return -EINVAL; + + if (chip->wow_fw_name) { + fw = &rtwdev->wow_fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + return -EINVAL; + } + + return 0; +} + static int rtw_power_on(struct rtw_dev *rtwdev) { struct rtw_chip_info *chip = rtwdev->chip; @@ -676,11 +852,10 @@ goto err; } - wait_for_completion(&fw->completion); - if (!fw->firmware) { - ret = -EINVAL; - rtw_err(rtwdev, "failed to load firmware\n"); - goto err; + ret = rtw_wait_firmware_completion(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to wait firmware completion\n"); + goto err_off; } ret = rtw_download_firmware(rtwdev, fw); @@ -736,15 +911,17 @@ ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, RTW_WATCH_DOG_DELAY_TIME); + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->sar.work, + RTW_SAR_DELAY_TIME); - rtw_flag_set(rtwdev, RTW_FLAG_RUNNING); + set_bit(RTW_FLAG_RUNNING, rtwdev->flags); return 0; } static void rtw_power_off(struct rtw_dev *rtwdev) { - rtwdev->hci.ops->stop(rtwdev); + rtw_hci_stop(rtwdev); rtw_mac_power_off(rtwdev); } @@ -752,14 +929,20 @@ { struct rtw_coex *coex = &rtwdev->coex; - rtw_flag_clear(rtwdev, RTW_FLAG_RUNNING); - rtw_flag_clear(rtwdev, RTW_FLAG_FW_RUNNING); + clear_bit(RTW_FLAG_RUNNING, rtwdev->flags); + clear_bit(RTW_FLAG_FW_RUNNING, rtwdev->flags); + + mutex_unlock(&rtwdev->mutex); + cancel_work_sync(&rtwdev->c2h_work); cancel_delayed_work_sync(&rtwdev->watch_dog_work); + cancel_delayed_work_sync(&rtwdev->sar.work); cancel_delayed_work_sync(&coex->bt_relink_work); cancel_delayed_work_sync(&coex->bt_reenable_work); cancel_delayed_work_sync(&coex->defreeze_work); + mutex_lock(&rtwdev->mutex); + rtw_power_off(rtwdev); } @@ -772,7 +955,7 @@ ht_cap->cap = 0; ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_MAX_AMSDU | - IEEE80211_HT_CAP_LDPC_CODING | + (rtw_chip_wcpu_11ac(rtwdev) ? IEEE80211_HT_CAP_LDPC_CODING : 0) | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40)) ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | @@ -814,6 +997,12 @@ IEEE80211_VHT_CAP_HTC_VHT | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | 0; + + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + vht_cap->cap |= (rtwdev->hal.bfee_sts_cap << + IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT); + mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | @@ -875,29 +1064,87 @@ kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); } +static void __update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + const struct rtw_fw_hdr *fw_hdr = + (const struct rtw_fw_hdr *)fw->firmware->data; + + fw->h2c_version = le16_to_cpu(fw_hdr->h2c_fmt_ver); + fw->version = le16_to_cpu(fw_hdr->version); + fw->sub_version = fw_hdr->subversion; + fw->sub_index = fw_hdr->subindex; +} + +static void __update_firmware_info_legacy(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + struct rtw_fw_hdr_legacy *legacy = + (struct rtw_fw_hdr_legacy *)fw->firmware->data; + + fw->h2c_version = 0; + fw->version = le16_to_cpu(legacy->version); + fw->sub_version = legacy->subversion1; + fw->sub_index = legacy->subversion2; +} + +static void update_firmware_info(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +{ + if (rtw_chip_wcpu_11n(rtwdev)) + __update_firmware_info_legacy(rtwdev, fw); + else + __update_firmware_info(rtwdev, fw); +} + static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) { - struct rtw_dev *rtwdev = context; - struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_fw_state *fw = context; + struct rtw_dev *rtwdev = fw->rtwdev; - if (!firmware) + if (!firmware || !firmware->data) { rtw_err(rtwdev, "failed to request firmware\n"); + complete_all(&fw->completion); + return; + } fw->firmware = firmware; + update_firmware_info(rtwdev, fw); complete_all(&fw->completion); + + rtw_info(rtwdev, "Firmware version %u.%u.%u, H2C version %u\n", + fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); } -static int rtw_load_firmware(struct rtw_dev *rtwdev, const char *fw_name) +static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type) { - struct rtw_fw_state *fw = &rtwdev->fw; + const char *fw_name; + struct rtw_fw_state *fw; int ret; + switch (type) { + case RTW_WOWLAN_FW: + fw = &rtwdev->wow_fw; + fw_name = rtwdev->chip->wow_fw_name; + break; + + case RTW_NORMAL_FW: + fw = &rtwdev->fw; + fw_name = rtwdev->chip->fw_name; + break; + + default: + rtw_warn(rtwdev, "unsupported firmware type\n"); + return -ENOENT; + } + + fw->rtwdev = rtwdev; init_completion(&fw->completion); ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, - GFP_KERNEL, rtwdev, rtw_load_firmware_cb); + GFP_KERNEL, fw, rtw_load_firmware_cb); if (ret) { - rtw_err(rtwdev, "async firmware request failed\n"); + rtw_err(rtwdev, "failed to async firmware request\n"); return ret; } @@ -914,6 +1161,7 @@ switch (rtw_hci_type(rtwdev)) { case RTW_HCI_TYPE_PCIE: rtwdev->hci.rpwm_addr = 0x03d9; + rtwdev->hci.cpwm_addr = 0x03da; break; default: rtw_err(rtwdev, "unsupported hci type\n"); @@ -935,6 +1183,8 @@ hal->antenna_tx = BB_PATH_A; hal->antenna_rx = BB_PATH_A; } + hal->rf_phy_num = chip->fix_rf_phy_num ? chip->fix_rf_phy_num : + hal->rf_path_num; if (hal->fab_version == 2) hal->fab_version = 1; @@ -948,6 +1198,8 @@ /* default use ack */ rtwdev->hal.rcr |= BIT_VHT_DACK; + hal->bfee_sts_cap = 3; + return ret; } @@ -1020,7 +1272,8 @@ rtw_hw_config_rf_ant_num(rtwdev, efuse->hw_cap.ant_num); - if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE) + if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE || + efuse->hw_cap.nss > rtwdev->hal.rf_path_num) efuse->hw_cap.nss = rtwdev->hal.rf_path_num; rtw_dbg(rtwdev, RTW_DBG_EFUSE, @@ -1047,19 +1300,19 @@ /* power on mac to read efuse */ ret = rtw_chip_efuse_enable(rtwdev); if (ret) - goto out; + goto out_unlock; ret = rtw_parse_efuse_map(rtwdev); if (ret) - goto out; + goto out_disable; ret = rtw_dump_hw_feature(rtwdev); if (ret) - goto out; + goto out_disable; ret = rtw_check_supported_rfe(rtwdev); if (ret) - goto out; + goto out_disable; if (efuse->crystal_cap == 0xff) efuse->crystal_cap = 0; @@ -1086,9 +1339,10 @@ efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0; efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0; +out_disable: rtw_chip_efuse_disable(rtwdev); -out: +out_unlock: mutex_unlock(&rtwdev->mutex); return ret; } @@ -1108,6 +1362,7 @@ rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl); rtw_phy_tx_power_by_rate_config(hal); rtw_phy_tx_power_limit_config(hal); + rtw_sar_load_table(rtwdev); return 0; } @@ -1141,29 +1396,49 @@ } EXPORT_SYMBOL(rtw_chip_info_setup); +static void rtw_stats_init(struct rtw_dev *rtwdev) +{ + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + int i; + + ewma_tp_init(&stats->tx_ewma_tp); + ewma_tp_init(&stats->rx_ewma_tp); + + for (i = 0; i < RTW_EVM_NUM; i++) + ewma_evm_init(&dm_info->ewma_evm[i]); + for (i = 0; i < RTW_SNR_NUM; i++) + ewma_snr_init(&dm_info->ewma_snr[i]); +} + int rtw_core_init(struct rtw_dev *rtwdev) { + struct rtw_chip_info *chip = rtwdev->chip; struct rtw_coex *coex = &rtwdev->coex; int ret; INIT_LIST_HEAD(&rtwdev->rsvd_page_list); + INIT_LIST_HEAD(&rtwdev->txqs); timer_setup(&rtwdev->tx_report.purge_timer, rtw_tx_report_purge_timer, 0); + tasklet_init(&rtwdev->tx_tasklet, rtw_tx_tasklet, + (unsigned long)rtwdev); INIT_DELAYED_WORK(&rtwdev->watch_dog_work, rtw_watch_dog_work); - INIT_DELAYED_WORK(&rtwdev->lps_work, rtw_lps_work); + INIT_DELAYED_WORK(&rtwdev->sar.work, rtw_sar_work); INIT_DELAYED_WORK(&coex->bt_relink_work, rtw_coex_bt_relink_work); INIT_DELAYED_WORK(&coex->bt_reenable_work, rtw_coex_bt_reenable_work); INIT_DELAYED_WORK(&coex->defreeze_work, rtw_coex_defreeze_work); INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work); + INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work); skb_queue_head_init(&rtwdev->c2h_queue); skb_queue_head_init(&rtwdev->coex.queue); skb_queue_head_init(&rtwdev->tx_report.queue); - spin_lock_init(&rtwdev->dm_lock); spin_lock_init(&rtwdev->rf_lock); spin_lock_init(&rtwdev->h2c.lock); + spin_lock_init(&rtwdev->txq_lock); spin_lock_init(&rtwdev->tx_report.q_lock); mutex_init(&rtwdev->mutex); @@ -1175,22 +1450,31 @@ rtwdev->sec.total_cam_num = 32; rtwdev->hal.current_channel = 1; set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map); + if (!(BIT(rtw_fw_lps_deep_mode) & chip->lps_deep_mode_supported)) + rtwdev->lps_conf.deep_mode = LPS_DEEP_MODE_NONE; + else + rtwdev->lps_conf.deep_mode = rtw_fw_lps_deep_mode; - mutex_lock(&rtwdev->mutex); - rtw_add_rsvd_page(rtwdev, RSVD_BEACON, false); - mutex_unlock(&rtwdev->mutex); + rtw_stats_init(rtwdev); /* default rx filter setting */ rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | BIT_AB | BIT_AM | BIT_APM; - ret = rtw_load_firmware(rtwdev, rtwdev->chip->fw_name); + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); if (ret) { rtw_warn(rtwdev, "no firmware loaded\n"); return ret; } + if (chip->wow_fw_name) { + ret = rtw_load_firmware(rtwdev, RTW_WOWLAN_FW); + if (ret) { + rtw_warn(rtwdev, "no wow firmware loaded\n"); + return ret; + } + } return 0; } EXPORT_SYMBOL(rtw_core_init); @@ -1198,21 +1482,29 @@ void rtw_core_deinit(struct rtw_dev *rtwdev) { struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_fw_state *wow_fw = &rtwdev->wow_fw; struct rtw_rsvd_page *rsvd_pkt, *tmp; unsigned long flags; if (fw->firmware) release_firmware(fw->firmware); + if (wow_fw->firmware) + release_firmware(wow_fw->firmware); + + tasklet_kill(&rtwdev->tx_tasklet); spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags); skb_queue_purge(&rtwdev->tx_report.queue); spin_unlock_irqrestore(&rtwdev->tx_report.q_lock, flags); - list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, list) { - list_del(&rsvd_pkt->list); + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, + build_list) { + list_del(&rsvd_pkt->build_list); kfree(rsvd_pkt); } + rtw_sar_release_table(rtwdev); + mutex_destroy(&rtwdev->mutex); mutex_destroy(&rtwdev->coex.mutex); mutex_destroy(&rtwdev->hal.tx_power_mutex); @@ -1229,6 +1521,7 @@ hw->extra_tx_headroom = max_tx_headroom; hw->queues = IEEE80211_NUM_ACS; + hw->txq_data_size = sizeof(struct rtw_txq); hw->sta_data_size = sizeof(struct rtw_sta_info); hw->vif_data_size = sizeof(struct rtw_vif); @@ -1241,6 +1534,8 @@ ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); + ieee80211_hw_set(hw, HAS_RATE_CONTROL); + ieee80211_hw_set(hw, TX_AMSDU); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -1252,6 +1547,12 @@ hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); + +#ifdef CONFIG_PM + hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; + hw->wiphy->max_sched_scan_ssids = rtwdev->chip->max_sched_scan_ssids; +#endif rtw_set_supported_band(hw, rtwdev->chip); SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr); @@ -1263,11 +1564,16 @@ return ret; } - if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2)) - rtw_err(rtwdev, "regulatory_hint fail\n"); + if (!rtwdev->efuse.country_worldwide) { + if (regulatory_hint(hw->wiphy, rtwdev->efuse.country_code)) + rtw_err(rtwdev, "regulatory_hint fail\n"); + } rtw_debugfs_init(rtwdev); + rtwdev->bf_info.bfer_mu_cnt = 0; + rtwdev->bf_info.bfer_su_cnt = 0; + return 0; } EXPORT_SYMBOL(rtw_register_hw); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/main.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/main.h @@ -11,11 +11,17 @@ #include #include #include +#include #include "util.h" #define RTW_MAX_MAC_ID_NUM 32 #define RTW_MAX_SEC_CAM_NUM 32 +#define MAX_PG_CAM_BACKUP_NUM 8 + +#define RTW_MAX_PATTERN_NUM 12 +#define RTW_MAX_PATTERN_MASK_SIZE 16 +#define RTW_MAX_PATTERN_SIZE 128 #define RTW_WATCH_DOG_DELAY_TIME round_jiffies_relative(HZ * 2) @@ -27,15 +33,25 @@ #define RTW_RF_PATH_MAX 4 #define HW_FEATURE_LEN 13 +#define RTW_TP_SHIFT 18 /* bytes/2s --> Mbps */ + +extern bool rtw_bf_support; +extern unsigned int rtw_fw_lps_deep_mode; extern unsigned int rtw_debug_mask; +extern bool rtw_edcca_enabled; extern const struct ieee80211_ops rtw_ops; extern struct rtw_chip_info rtw8822b_hw_spec; extern struct rtw_chip_info rtw8822c_hw_spec; +extern struct rtw_chip_info rtw8723d_hw_spec; #define RTW_MAX_CHANNEL_NUM_2G 14 #define RTW_MAX_CHANNEL_NUM_5G 49 struct rtw_dev; +struct rtw_sar_rwrd; +union rtw_sar_rwsi; +union rtw_sar_rwgs; +struct rtw_sar_read; enum rtw_hci_type { RTW_HCI_TYPE_PCIE, @@ -50,10 +66,24 @@ enum rtw_hci_type type; u32 rpwm_addr; + u32 cpwm_addr; u8 bulkout_num; }; +#define IS_CH_5G_BAND_1(channel) ((channel) >= 36 && (channel <= 48)) +#define IS_CH_5G_BAND_2(channel) ((channel) >= 52 && (channel <= 64)) +#define IS_CH_5G_BAND_3(channel) ((channel) >= 100 && (channel <= 144)) +#define IS_CH_5G_BAND_4(channel) ((channel) >= 149 && (channel <= 177)) + +#define IS_CH_5G_BAND_MID(channel) \ + (IS_CH_5G_BAND_2(channel) || IS_CH_5G_BAND_3(channel)) + +#define IS_CH_2G_BAND(channel) ((channel) <= 14) +#define IS_CH_5G_BAND(channel) \ + (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel) || \ + IS_CH_5G_BAND_3(channel) || IS_CH_5G_BAND_4(channel)) + enum rtw_supported_band { RTW_BAND_2G = 1 << 0, RTW_BAND_5G = 1 << 1, @@ -75,6 +105,16 @@ RTW_CHANNEL_WIDTH_10 = 6, }; +enum rtw_sc_offset { + RTW_SC_DONT_CARE = 0, + RTW_SC_20_UPPER = 1, + RTW_SC_20_LOWER = 2, + RTW_SC_20_UPMOST = 3, + RTW_SC_20_LOWEST = 4, + RTW_SC_40_UPPER = 9, + RTW_SC_40_LOWER = 10, +}; + enum rtw_net_type { RTW_NET_NO_LINK = 0, RTW_NET_AD_HOC = 1, @@ -149,6 +189,7 @@ enum rtw_chip_type { RTW_CHIP_TYPE_8822B, RTW_CHIP_TYPE_8822C, + RTW_CHIP_TYPE_8723D, }; enum rtw_tx_queue_type { @@ -173,6 +214,11 @@ RTK_MAX_RX_QUEUE_NUM }; +enum rtw_fw_type { + RTW_NORMAL_FW = 0x0, + RTW_WOWLAN_FW = 0x1, +}; + enum rtw_rate_index { RTW_RATEID_BGN_40M_2SS = 0, RTW_RATEID_BGN_40M_1SS = 1, @@ -303,18 +349,67 @@ RTW_REGD_MAX }; +enum rtw_txq_flags { + RTW_TXQ_AMPDU, + RTW_TXQ_BLOCK_BA, +}; + enum rtw_flags { RTW_FLAG_RUNNING, RTW_FLAG_FW_RUNNING, RTW_FLAG_SCANNING, RTW_FLAG_INACTIVE_PS, RTW_FLAG_LEISURE_PS, + RTW_FLAG_LEISURE_PS_DEEP, RTW_FLAG_DIG_DISABLE, RTW_FLAG_BUSY_TRAFFIC, + RTW_FLAG_WOWLAN, NUM_OF_RTW_FLAGS, }; +enum rtw_evm { + RTW_EVM_OFDM = 0, + RTW_EVM_1SS, + RTW_EVM_2SS_A, + RTW_EVM_2SS_B, + /* keep it last */ + RTW_EVM_NUM +}; + +enum rtw_snr { + RTW_SNR_OFDM_A = 0, + RTW_SNR_OFDM_B, + RTW_SNR_OFDM_C, + RTW_SNR_OFDM_D, + RTW_SNR_1SS_A, + RTW_SNR_1SS_B, + RTW_SNR_1SS_C, + RTW_SNR_1SS_D, + RTW_SNR_2SS_A, + RTW_SNR_2SS_B, + RTW_SNR_2SS_C, + RTW_SNR_2SS_D, + /* keep it last */ + RTW_SNR_NUM +}; + +enum rtw_wow_flags { + RTW_WOW_FLAG_EN_MAGIC_PKT, + RTW_WOW_FLAG_EN_REKEY_PKT, + RTW_WOW_FLAG_EN_DISCONNECT, + + /* keep it last */ + RTW_WOW_FLAG_MAX, +}; + +enum rtw_sar_sources { + RTW_SAR_SOURCE_NONE, + RTW_SAR_SOURCE_VNDCMD, + RTW_SAR_SOURCE_ACPI_STATIC, + RTW_SAR_SOURCE_ACPI_DYNAMIC, +}; + /* the power index is represented by differences, which cck-1s & ht40-1s are * the base values, so for 1s's differences, there are only ht20 & ofdm */ @@ -434,6 +529,36 @@ u32 mask; }; +struct rtw_reg_domain { + u32 addr; + u32 mask; +#define RTW_REG_DOMAIN_MAC32 0 +#define RTW_REG_DOMAIN_MAC16 1 +#define RTW_REG_DOMAIN_MAC8 2 +#define RTW_REG_DOMAIN_RF_A 3 +#define RTW_REG_DOMAIN_RF_B 4 +#define RTW_REG_DOMAIN_NL 0xFF + u8 domain; +}; + +struct rtw_hw_reg_offset { + struct rtw_hw_reg hw_reg; + u8 offset; +}; + +struct rtw_rf_sipi_addr { + u32 hssi_1; + u32 hssi_2; + u32 lssi_read; + u32 lssi_read_pi; +}; + +struct rtw_ltecoex_addr { + u32 ctrl; + u32 wdata; + u32 rdata; +}; + struct rtw_backup_info { u8 len; u32 reg; @@ -480,6 +605,13 @@ bool fs; bool short_gi; bool report; + bool rts; + bool nav_use_hdr; + bool dis_qselseq; + bool en_hwseq; + u8 hw_ssn_sel; + bool en_hw_exseq; + bool bt_null; }; struct rtw_rx_pkt_stat { @@ -502,10 +634,16 @@ s8 rx_power[RTW_RF_PATH_MAX]; u8 rssi; u8 rxsc; + s8 rx_snr[RTW_RF_PATH_MAX]; + u8 rx_evm[RTW_RF_PATH_MAX]; + s8 cfo_tail[RTW_RF_PATH_MAX]; + struct rtw_sta_info *si; struct ieee80211_vif *vif; }; +DECLARE_EWMA(tp, 10, 2); + struct rtw_traffic_stats { /* units in bytes */ u64 tx_unicast; @@ -518,6 +656,8 @@ /* units in Mbps */ u32 tx_throughput; u32 rx_throughput; + struct ewma_tp tx_ewma_tp; + struct ewma_tp rx_ewma_tp; }; enum rtw_lps_mode { @@ -526,6 +666,12 @@ RTW_MODE_WMM_PS = 2, }; +enum rtw_lps_deep_mode { + LPS_DEEP_MODE_NONE = 0, + LPS_DEEP_MODE_LCLK = 1, + LPS_DEEP_MODE_PG = 2, +}; + enum rtw_pwr_state { RTW_RF_OFF = 0x0, RTW_RF_ON = 0x4, @@ -533,14 +679,15 @@ }; struct rtw_lps_conf { - /* the interface to enter lps */ - struct rtw_vif *rtwvif; enum rtw_lps_mode mode; + enum rtw_lps_deep_mode deep_mode; enum rtw_pwr_state state; u8 awake_interval; u8 rlbm; u8 smart_ps; u8 port_id; + bool sec_cam_backup; + bool pattern_cam_backup; }; enum rtw_hw_key_type { @@ -576,6 +723,19 @@ struct timer_list purge_timer; }; +struct rtw_ra_report { + struct rate_info txrate; + u32 bit_rate; + u8 desc_rate; +}; + +struct rtw_txq { + struct list_head list; + + unsigned long flags; + unsigned long last_push; +}; + #define RTW_BC_MC_MACID 1 DECLARE_EWMA(rssi, 10, 16); @@ -598,20 +758,57 @@ bool updated; u8 init_ra_lv; u64 ra_mask; + + DECLARE_BITMAP(tid_ba, IEEE80211_NUM_TIDS); + + struct rtw_ra_report ra_report; + + bool use_cfg_mask; + struct cfg80211_bitrate_mask *mask; +}; + +enum rtw_bfee_role { + RTW_BFEE_NONE, + RTW_BFEE_SU, + RTW_BFEE_MU +}; + +struct rtw_bfee { + enum rtw_bfee_role role; + + u16 p_aid; + u8 g_id; + u8 mac_addr[ETH_ALEN]; + u8 sound_dim; + + /* SU-MIMO */ + u8 su_reg_index; + + /* MU-MIMO */ + u16 aid; +}; + +struct rtw_bf_info { + u8 bfer_mu_cnt; + u8 bfer_su_cnt; + DECLARE_BITMAP(bfer_su_reg_maping, 2); + u8 cur_csi_rpt_rate; }; struct rtw_vif { - struct ieee80211_vif *vif; enum rtw_net_type net_type; u16 aid; u8 mac_addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 port; u8 bcn_ctrl; + struct list_head rsvd_page_list; + struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS]; const struct rtw_vif_port *conf; struct rtw_traffic_stats stats; - bool in_lps; + + struct rtw_bfee bfee; }; struct rtw_regulatory { @@ -622,6 +819,7 @@ struct rtw_chip_ops { int (*mac_init)(struct rtw_dev *rtwdev); + void (*shutdown)(struct rtw_dev *rtwdev); int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map); void (*phy_set_param)(struct rtw_dev *rtwdev); void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, @@ -639,10 +837,21 @@ void (*set_antenna)(struct rtw_dev *rtwdev, u8 antenna_tx, u8 antenna_rx); void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); + void (*efuse_grant)(struct rtw_dev *rtwdev, bool enable); void (*false_alarm_statistics)(struct rtw_dev *rtwdev); void (*phy_calibration)(struct rtw_dev *rtwdev); void (*dpk_track)(struct rtw_dev *rtwdev); void (*cck_pd_set)(struct rtw_dev *rtwdev, u8 level); + void (*pwr_track)(struct rtw_dev *rtwdev); + void (*config_bfee)(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable); + void (*set_gid_table)(struct rtw_dev *rtwdev, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *conf); + void (*cfg_csi_rate)(struct rtw_dev *rtwdev, u8 rssi, u8 cur_rate, + u8 fixrate_en, u8 *new_rate); + void (*adaptivity_init)(struct rtw_dev *rtwdev); + void (*adaptivity)(struct rtw_dev *rtwdev); /* for coex */ void (*coex_set_init)(struct rtw_dev *rtwdev); @@ -674,6 +883,7 @@ #define RTW_PWR_INTF_PCI_MSK BIT(2) #define RTW_PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define RTW_PWR_CUT_TEST_MSK BIT(0) #define RTW_PWR_CUT_A_MSK BIT(1) #define RTW_PWR_CUT_B_MSK BIT(2) #define RTW_PWR_CUT_C_MSK BIT(3) @@ -747,6 +957,7 @@ RTW_DMA_MAPPING_NORMAL = 2, RTW_DMA_MAPPING_HIGH = 3, + RTW_DMA_MAPPING_MAX, RTW_DMA_MAPPING_UNDEF, }; @@ -759,6 +970,16 @@ enum rtw_dma_mapping dma_map_hi; }; +struct rtw_prioq_addr { + u32 rsvd; + u32 avail; +}; + +struct rtw_prioq_addrs { + struct rtw_prioq_addr prio[RTW_DMA_MAPPING_MAX]; + bool wsize; +}; + struct rtw_page_table { u16 hq_num; u16 nq_num; @@ -775,6 +996,33 @@ u16 platform; }; +struct rtw_wow_pattern { + u16 crc; + u8 type; + u8 valid; + u8 mask[RTW_MAX_PATTERN_MASK_SIZE]; +}; + +struct rtw_pno_request { + bool inited; + u32 match_set_cnt; + struct cfg80211_match_set *match_sets; + u8 channel_cnt; + struct ieee80211_channel *channels; + struct cfg80211_sched_scan_plan scan_plan; +}; + +struct rtw_wow_param { + struct ieee80211_vif *wow_vif; + DECLARE_BITMAP(flags, RTW_WOW_FLAG_MAX); + u8 txpause; + u8 pattern_cnt; + struct rtw_wow_pattern patterns[RTW_MAX_PATTERN_NUM]; + + bool ips_enabled; + struct rtw_pno_request pno_req; +}; + struct rtw_intf_phy_para_table { struct rtw_intf_phy_para *usb2_para; struct rtw_intf_phy_para *usb3_para; @@ -818,12 +1066,48 @@ .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ } +#define RTW_PWR_TRK_5G_1 0 +#define RTW_PWR_TRK_5G_2 1 +#define RTW_PWR_TRK_5G_3 2 +#define RTW_PWR_TRK_5G_NUM 3 + +#define RTW_PWR_TRK_TBL_SZ 30 + +/* This table stores the values of TX power that will be adjusted by power + * tracking. + * + * For 5G bands, there are 3 different settings. + * For 2G there are cck rate and ofdm rate with different settings. + */ +struct rtw_pwr_track_tbl { + const u8 *pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM]; + const u8 *pwrtrk_2gb_n; + const u8 *pwrtrk_2gb_p; + const u8 *pwrtrk_2ga_n; + const u8 *pwrtrk_2ga_p; + const u8 *pwrtrk_2g_cckb_n; + const u8 *pwrtrk_2g_cckb_p; + const u8 *pwrtrk_2g_ccka_n; + const u8 *pwrtrk_2g_ccka_p; + const s8 *pwrtrk_xtal_n; + const s8 *pwrtrk_xtal_p; +}; + +enum rtw_wlan_cpu { + RTW_WCPU_11AC, + RTW_WCPU_11N, +}; + /* hardware configuration for each IC */ struct rtw_chip_info { struct rtw_chip_ops *ops; u8 id; const char *fw_name; + enum rtw_wlan_cpu wlan_cpu; u8 tx_pkt_desc_sz; u8 tx_buf_desc_sz; u8 rx_pkt_desc_sz; @@ -844,18 +1128,24 @@ bool ht_supported; bool vht_supported; + u8 lps_deep_mode_supported; /* init values */ u8 sys_func_en; struct rtw_pwr_seq_cmd **pwr_on_seq; struct rtw_pwr_seq_cmd **pwr_off_seq; struct rtw_rqpn *rqpn_table; + struct rtw_prioq_addrs *prioq_addrs; struct rtw_page_table *page_table; struct rtw_intf_phy_para_table *intf_table; struct rtw_hw_reg *dig; + struct rtw_hw_reg *dig_cck; u32 rf_base_addr[2]; u32 rf_sipi_addr[2]; + struct rtw_rf_sipi_addr *rf_sipi_read_addr; + u8 fix_rf_phy_num; + struct rtw_ltecoex_addr *ltecoex_addr; const struct rtw_table *mac_tbl; const struct rtw_table *agc_tbl; @@ -868,6 +1158,19 @@ bool en_dis_dpd; u16 dpd_ratemask; + u8 iqk_threshold; + const struct rtw_pwr_track_tbl *pwr_track_tbl; + + u8 bfer_su_max_num; + u8 bfer_mu_max_num; + + struct rtw_hw_reg_offset *edcca_th; + s8 l2h_th_ini_cs; + s8 l2h_th_ini_ad; + + const char *wow_fw_name; + const struct wiphy_wowlan_support *wowlan_stub; + const u8 max_sched_scan_ssids; /* coex paras */ u32 coex_para_ver; @@ -886,6 +1189,7 @@ u8 bt_afh_span_bw40; u8 afh_5g_num; u8 wl_rf_para_num; + u8 coex_info_hw_regs_num; const u8 *bt_rssi_step; const u8 *wl_rssi_step; const struct coex_table_para *table_nsant; @@ -895,6 +1199,8 @@ const struct coex_rf_para *wl_rf_para_tx; const struct coex_rf_para *wl_rf_para_rx; const struct coex_5g_afh_map *afh_5g; + const struct rtw_hw_reg *btg_reg; + const struct rtw_reg_domain *coex_info_hw_regs; }; enum rtw_coex_bt_state_cnt { @@ -941,6 +1247,7 @@ struct rtw_coex_dm { bool cur_ps_tdma_on; bool cur_wl_rx_low_gain_en; + bool ignore_wl_act; u8 reason; u8 bt_rssi_state[4]; @@ -1021,6 +1328,9 @@ u32 bt_supported_version; u32 bt_supported_feature; + u32 patch_ver; + u16 bt_reg_vendor_ae; + u16 bt_reg_vendor_ac; s8 bt_rssi; u8 kt_ver; u8 gnt_workaround_state; @@ -1121,10 +1431,50 @@ #define DACK_MSBK_BACKUP_NUM 0xf #define DACK_DCK_BACKUP_NUM 0x2 +struct rtw_swing_table { + const u8 *p[RTW_RF_PATH_MAX]; + const u8 *n[RTW_RF_PATH_MAX]; +}; + +struct rtw_pkt_count { + u16 num_bcn_pkt; + u16 num_qry_pkt[DESC_RATE_MAX]; +}; + +DECLARE_EWMA(evm, 10, 4); +DECLARE_EWMA(snr, 10, 4); + +#define EDCCA_TH_L2H_IDX 0 +#define EDCCA_TH_H2L_IDX 1 +#define EDCCA_TH_L2H_LB 48 +#define EDCCA_ADC_BACKOFF 12 +#define EDCCA_IGI_BASE 50 +#define EDCCA_IGI_L2H_DIFF 8 +#define EDCCA_L2H_H2L_DIFF 7 +#define EDCCA_L2H_H2L_DIFF_NORMAL 8 + +enum rtw_edcca_mode { + RTW_EDCCA_NORMAL = 0, + RTW_EDCCA_ADAPTIVITY = 1, +}; + +struct rtw_iqk_info { + bool done; + struct { + u32 s1_x; + u32 s1_y; + u32 s0_x; + u32 s0_y; + } result; +}; + struct rtw_dm_info { u32 cck_fa_cnt; u32 ofdm_fa_cnt; u32 total_fa_cnt; + u32 cck_cca_cnt; + u32 ofdm_cca_cnt; + u32 total_cca_cnt; u32 cck_ok_cnt; u32 cck_err_cnt; @@ -1147,6 +1497,17 @@ u8 cck_gi_u_bnd; u8 cck_gi_l_bnd; + u8 tx_rate; + u8 thermal_avg[RTW_RF_PATH_MAX]; + u8 thermal_meter_k; + s8 delta_power_index[RTW_RF_PATH_MAX]; + u8 default_ofdm_index; + bool pwr_trk_triggered; + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; + s8 txagc_remnant_ofdm; + /* backup dack results for each path and I/Q */ u32 dack_adck[RTW_RF_PATH_MAX]; u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM]; @@ -1157,6 +1518,22 @@ /* [bandwidth 0:20M/1:40M][number of path] */ u8 cck_pd_lv[2][RTW_RF_PATH_MAX]; u32 cck_fa_avg; + + /* save the last rx phy status for debug */ + s8 rx_snr[RTW_RF_PATH_MAX]; + u8 rx_evm_dbm[RTW_RF_PATH_MAX]; + s16 cfo_tail[RTW_RF_PATH_MAX]; + u8 rssi[RTW_RF_PATH_MAX]; + u8 curr_rx_rate; + struct rtw_pkt_count cur_pkt_count; + struct rtw_pkt_count last_pkt_count; + struct ewma_evm ewma_evm[RTW_EVM_NUM]; + struct ewma_snr ewma_snr[RTW_SNR_NUM]; + + s8 l2h_th_ini; + enum rtw_edcca_mode edcca_mode; + + struct rtw_iqk_info iqk; }; struct rtw_efuse { @@ -1168,13 +1545,17 @@ u8 addr[ETH_ALEN]; u8 channel_plan; u8 country_code[2]; + bool country_worldwide; u8 rf_board_option; u8 rfe_option; - u8 thermal_meter; + u8 power_track_type; + u8 thermal_meter[RTW_RF_PATH_MAX]; + u8 thermal_meter_k; u8 crystal_cap; u8 ant_div_cfg; u8 ant_div_type; u8 regd; + u8 afe; u8 lna_type_2g; u8 lna_type_5g; @@ -1252,11 +1633,12 @@ u16 rsvd_cpu_instr_addr; u16 rsvd_fw_txbuf_addr; u16 rsvd_csibuf_addr; - enum rtw_dma_mapping pq_map[RTW_PQ_MAP_NUM]; + struct rtw_rqpn *rqpn; }; struct rtw_fw_state { const struct firmware *firmware; + struct rtw_dev *rtwdev; struct completion completion; u16 version; u8 sub_version; @@ -1264,6 +1646,15 @@ u16 h2c_version; }; +struct rtw_sar { + enum rtw_sar_sources source; + struct rtw_sar_rwrd *rwrd; + union rtw_sar_rwsi *rwsi; + union rtw_sar_rwgs *rwgs; + const struct rtw_sar_read *read; + struct delayed_work work; +}; + struct rtw_hal { u32 rcr; @@ -1287,8 +1678,10 @@ u8 sec_ch_offset; u8 rf_type; u8 rf_path_num; + u8 rf_phy_num; u8 antenna_tx; u8 antenna_rx; + u8 bfee_sts_cap; /* protect tx power section */ struct mutex tx_power_mutex; @@ -1308,6 +1701,10 @@ [RTW_CHANNEL_WIDTH_MAX] [RTW_RATE_SECTION_MAX] [RTW_MAX_CHANNEL_NUM_5G]; + s8 tx_pwr_sar_2g[RTW_REGD_MAX][RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX] + [RTW_MAX_CHANNEL_NUM_2G]; + s8 tx_pwr_sar_5g[RTW_REGD_MAX][RTW_RF_PATH_MAX][RTW_RATE_SECTION_MAX] + [RTW_MAX_CHANNEL_NUM_5G]; s8 tx_pwr_tbl[RTW_RF_PATH_MAX] [DESC_RATE_MAX]; }; @@ -1326,6 +1723,7 @@ struct rtw_sec_desc sec; struct rtw_traffic_stats stats; struct rtw_regulatory regd; + struct rtw_bf_info bf_info; struct rtw_dm_info dm_info; struct rtw_coex coex; @@ -1333,9 +1731,6 @@ /* ensures exclusive access from mac80211 callbacks */ struct mutex mutex; - /* lock for dm to use */ - spinlock_t dm_lock; - /* read/write rf register */ spinlock_t rf_lock; @@ -1349,6 +1744,12 @@ struct sk_buff_head c2h_queue; struct work_struct c2h_work; + /* used to protect txqs list */ + spinlock_t txq_lock; + struct list_head txqs; + struct tasklet_struct tx_tasklet; + struct work_struct ba_work; + struct rtw_tx_report tx_report; struct { @@ -1361,41 +1762,82 @@ /* lps power state & handler work */ struct rtw_lps_conf lps_conf; - struct delayed_work lps_work; + bool ps_enabled; struct dentry *debugfs; u8 sta_cnt; + u32 rts_threshold; DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); u8 mp_mode; + struct rtw_fw_state wow_fw; + struct rtw_wow_param wow; + + struct rtw_sar sar; + + bool need_rfk; + /* hci related data, must be last */ u8 priv[0] __aligned(sizeof(void *)); }; #include "hci.h" -static inline bool rtw_flag_check(struct rtw_dev *rtwdev, enum rtw_flags flag) +static inline bool rtw_is_assoc(struct rtw_dev *rtwdev) { - return test_bit(flag, rtwdev->flags); + return !!rtwdev->sta_cnt; } -static inline void rtw_flag_clear(struct rtw_dev *rtwdev, enum rtw_flags flag) +static inline struct ieee80211_txq *rtwtxq_to_txq(struct rtw_txq *rtwtxq) { - clear_bit(flag, rtwdev->flags); + void *p = rtwtxq; + + return container_of(p, struct ieee80211_txq, drv_priv); } -static inline void rtw_flag_set(struct rtw_dev *rtwdev, enum rtw_flags flag) +static inline struct ieee80211_vif *rtwvif_to_vif(struct rtw_vif *rtwvif) { - set_bit(flag, rtwdev->flags); + void *p = rtwvif; + + return container_of(p, struct ieee80211_vif, drv_priv); } -static inline bool rtw_is_assoc(struct rtw_dev *rtwdev) +static inline bool rtw_ssid_equal(struct cfg80211_ssid *a, + struct cfg80211_ssid *b) { - return !!rtwdev->sta_cnt; + if (!a || !b || a->ssid_len != b->ssid_len) + return false; + + if (memcmp(a->ssid, b->ssid, a->ssid_len)) + return false; + + return true; +} + +static inline void rtw_chip_efuse_grant_on(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->efuse_grant) + rtwdev->chip->ops->efuse_grant(rtwdev, true); +} + +static inline void rtw_chip_efuse_grant_off(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->efuse_grant) + rtwdev->chip->ops->efuse_grant(rtwdev, false); +} + +static inline bool rtw_chip_wcpu_11n(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_11N; +} + +static inline bool rtw_chip_wcpu_11ac(struct rtw_dev *rtwdev) +{ + return rtwdev->chip->wlan_cpu == RTW_WCPU_11AC; } void rtw_get_channel_params(struct cfg80211_chan_def *chandef, @@ -1405,7 +1847,9 @@ bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value); void rtw_restore_reg(struct rtw_dev *rtwdev, struct rtw_backup_info *bckp, u32 num); +void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss); void rtw_set_channel(struct rtw_dev *rtwdev); +void rtw_chip_prepare_tx(struct rtw_dev *rtwdev); void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, u32 config); void rtw_tx_report_purge_timer(struct timer_list *t); @@ -1417,5 +1861,6 @@ void rtw_core_deinit(struct rtw_dev *rtwdev); int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); +u16 rtw_desc_to_bitrate(u8 desc_rate); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/pci.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/pci.c @@ -6,9 +6,11 @@ #include #include "main.h" #include "pci.h" +#include "reg.h" #include "tx.h" #include "rx.h" #include "fw.h" +#include "ps.h" #include "debug.h" static bool rtw_disable_msi; @@ -380,6 +382,7 @@ rtwpci->irq_mask[3] = IMR_H2CDOK | 0; spin_lock_init(&rtwpci->irq_lock); + spin_lock_init(&rtwpci->hwirq_lock); ret = rtw_pci_init_trx_ring(rtwdev); return ret; @@ -398,12 +401,14 @@ dma = rtwpci->tx_rings[RTW_TX_QUEUE_BCN].r.dma; rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_BCNQ, dma); - len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; - dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; - rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; - rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.wp = 0; - rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_H2CQ, len); - rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_H2CQ, dma); + if (!rtw_chip_wcpu_11n(rtwdev)) { + len = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.len; + dma = rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.dma; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.rp = 0; + rtwpci->tx_rings[RTW_TX_QUEUE_H2C].r.wp = 0; + rtw_write16(rtwdev, RTK_PCI_TXBD_NUM_H2CQ, len); + rtw_write32(rtwdev, RTK_PCI_TXBD_DESA_H2CQ, dma); + } len = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.len; dma = rtwpci->tx_rings[RTW_TX_QUEUE_BK].r.dma; @@ -457,9 +462,10 @@ /* reset read/write point */ rtw_write32(rtwdev, RTK_PCI_TXBD_RWPTR_CLR, 0xffffffff); - /* rest H2C Queue index */ - rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, BIT_CLR_H2CQ_HOST_IDX); - rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, BIT_CLR_H2CQ_HW_IDX); + /* reset H2C Queue index in a single write */ + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32_set(rtwdev, RTK_PCI_TXBD_H2CQ_CSR, + BIT_CLR_H2CQ_HOST_IDX | BIT_CLR_H2CQ_HW_IDX); } static void rtw_pci_reset_trx_ring(struct rtw_dev *rtwdev) @@ -470,26 +476,39 @@ static void rtw_pci_enable_interrupt(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) { + unsigned long flags; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + rtw_write32(rtwdev, RTK_PCI_HIMR0, rtwpci->irq_mask[0]); rtw_write32(rtwdev, RTK_PCI_HIMR1, rtwpci->irq_mask[1]); - rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, rtwpci->irq_mask[3]); + rtwpci->irq_enabled = true; + + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); } static void rtw_pci_disable_interrupt(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) { + unsigned long flags; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + + if (!rtwpci->irq_enabled) + goto out; + rtw_write32(rtwdev, RTK_PCI_HIMR0, 0); rtw_write32(rtwdev, RTK_PCI_HIMR1, 0); - rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); - rtwpci->irq_enabled = false; -} + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HIMR3, 0); -static int rtw_pci_setup(struct rtw_dev *rtwdev) -{ - rtw_pci_reset_trx_ring(rtwdev); + rtwpci->irq_enabled = false; - return 0; +out: + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); } static void rtw_pci_dma_reset(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) @@ -500,11 +519,22 @@ rtwpci->rx_tag = 0; } +static int rtw_pci_setup(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + rtw_pci_reset_trx_ring(rtwdev); + rtw_pci_dma_reset(rtwdev, rtwpci); + + return 0; +} + static void rtw_pci_dma_release(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci) { struct rtw_pci_tx_ring *tx_ring; u8 queue; + rtw_pci_reset_trx_ring(rtwdev); for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { tx_ring = &rtwpci->tx_rings[queue]; rtw_pci_free_tx_ring_skbs(rtwdev, tx_ring); @@ -514,13 +544,10 @@ static int rtw_pci_start(struct rtw_dev *rtwdev) { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - unsigned long flags; - - rtw_pci_dma_reset(rtwdev, rtwpci); - spin_lock_irqsave(&rtwpci->irq_lock, flags); + spin_lock_bh(&rtwpci->irq_lock); rtw_pci_enable_interrupt(rtwdev, rtwpci); - spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + spin_unlock_bh(&rtwpci->irq_lock); return 0; } @@ -528,12 +555,73 @@ static void rtw_pci_stop(struct rtw_dev *rtwdev) { struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - unsigned long flags; - spin_lock_irqsave(&rtwpci->irq_lock, flags); + spin_lock_bh(&rtwpci->irq_lock); rtw_pci_disable_interrupt(rtwdev, rtwpci); rtw_pci_dma_release(rtwdev, rtwpci); - spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + spin_unlock_bh(&rtwpci->irq_lock); +} + +static void rtw_pci_deep_ps_enter(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct rtw_pci_tx_ring *tx_ring; + bool tx_empty = true; + u8 queue; + + lockdep_assert_held(&rtwpci->irq_lock); + + /* Deep PS state is not allowed to TX-DMA */ + for (queue = 0; queue < RTK_MAX_TX_QUEUE_NUM; queue++) { + /* BCN queue is rsvd page, does not have DMA interrupt + * H2C queue is managed by firmware + */ + if (queue == RTW_TX_QUEUE_BCN || + queue == RTW_TX_QUEUE_H2C) + continue; + + tx_ring = &rtwpci->tx_rings[queue]; + + /* check if there is any skb DMAing */ + if (skb_queue_len(&tx_ring->queue)) { + tx_empty = false; + break; + } + } + + if (!tx_empty) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "TX path not empty, cannot enter deep power save state\n"); + return; + } + + set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); + rtw_power_mode_change(rtwdev, true); +} + +static void rtw_pci_deep_ps_leave(struct rtw_dev *rtwdev) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + lockdep_assert_held(&rtwpci->irq_lock); + + if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_power_mode_change(rtwdev, false); +} + +static void rtw_pci_deep_ps(struct rtw_dev *rtwdev, bool enter) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + spin_lock_bh(&rtwpci->irq_lock); + + if (enter && !test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_pci_deep_ps_enter(rtwdev); + + if (!enter && test_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) + rtw_pci_deep_ps_leave(rtwdev); + + spin_unlock_bh(&rtwpci->irq_lock); } static u8 ac_to_hwq[] = { @@ -651,6 +739,10 @@ tx_data = rtw_pci_get_tx_data(skb); tx_data->dma = dma; tx_data->sn = pkt_info->sn; + + spin_lock_bh(&rtwpci->irq_lock); + + rtw_pci_deep_ps_leave(rtwdev); skb_queue_tail(&ring->queue, skb); /* kick off tx queue */ @@ -666,6 +758,7 @@ reg_bcn_work |= BIT_PCI_BCNQ_FLAG; rtw_write8(rtwdev, RTK_PCI_TXBD_BCN_WORK, reg_bcn_work); } + spin_unlock_bh(&rtwpci->irq_lock); return 0; } @@ -674,43 +767,24 @@ u32 size) { struct sk_buff *skb; - struct rtw_tx_pkt_info pkt_info; - u32 tx_pkt_desc_sz; - u32 length; - - tx_pkt_desc_sz = rtwdev->chip->tx_pkt_desc_sz; - length = size + tx_pkt_desc_sz; - skb = dev_alloc_skb(length); + struct rtw_tx_pkt_info pkt_info = {0}; + + skb = rtw_tx_write_data_rsvd_page_get(rtwdev, &pkt_info, buf, size); if (!skb) return -ENOMEM; - skb_reserve(skb, tx_pkt_desc_sz); - memcpy((u8 *)skb_put(skb, size), buf, size); - memset(&pkt_info, 0, sizeof(pkt_info)); - pkt_info.tx_pkt_size = size; - pkt_info.offset = tx_pkt_desc_sz; - return rtw_pci_xmit(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_BCN); } static int rtw_pci_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size) { struct sk_buff *skb; - struct rtw_tx_pkt_info pkt_info; - u32 tx_pkt_desc_sz; - u32 length; - - tx_pkt_desc_sz = rtwdev->chip->tx_pkt_desc_sz; - length = size + tx_pkt_desc_sz; - skb = dev_alloc_skb(length); + struct rtw_tx_pkt_info pkt_info = {0}; + + skb = rtw_tx_write_data_h2c_get(rtwdev, &pkt_info, buf, size); if (!skb) return -ENOMEM; - skb_reserve(skb, tx_pkt_desc_sz); - memcpy((u8 *)skb_put(skb, size), buf, size); - memset(&pkt_info, 0, sizeof(pkt_info)); - pkt_info.tx_pkt_size = size; - return rtw_pci_xmit(rtwdev, &pkt_info, skb, RTW_TX_QUEUE_H2C); } @@ -762,6 +836,11 @@ while (count--) { skb = skb_dequeue(&ring->queue); + if (!skb) { + rtw_err(rtwdev, "failed to dequeue %d skb TX queue %d, BD=0x%08x, rp %d -> %d\n", + count, hw_queue, bd_idx, ring->r.rp, cur_rp); + break; + } tx_data = rtw_pci_get_tx_data(skb); pci_unmap_single(rtwpci->pdev, tx_data->dma, skb->len, PCI_DMA_TODEVICE); @@ -883,15 +962,25 @@ static void rtw_pci_irq_recognized(struct rtw_dev *rtwdev, struct rtw_pci *rtwpci, u32 *irq_status) { + unsigned long flags; + + spin_lock_irqsave(&rtwpci->hwirq_lock, flags); + irq_status[0] = rtw_read32(rtwdev, RTK_PCI_HISR0); irq_status[1] = rtw_read32(rtwdev, RTK_PCI_HISR1); - irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); + if (rtw_chip_wcpu_11ac(rtwdev)) + irq_status[3] = rtw_read32(rtwdev, RTK_PCI_HISR3); + else + irq_status[3] = 0; irq_status[0] &= rtwpci->irq_mask[0]; irq_status[1] &= rtwpci->irq_mask[1]; irq_status[3] &= rtwpci->irq_mask[3]; rtw_write32(rtwdev, RTK_PCI_HISR0, irq_status[0]); rtw_write32(rtwdev, RTK_PCI_HISR1, irq_status[1]); - rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); + if (rtw_chip_wcpu_11ac(rtwdev)) + rtw_write32(rtwdev, RTK_PCI_HISR3, irq_status[3]); + + spin_unlock_irqrestore(&rtwpci->hwirq_lock, flags); } static irqreturn_t rtw_pci_interrupt_handler(int irq, void *dev) @@ -899,10 +988,6 @@ struct rtw_dev *rtwdev = dev; struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - spin_lock(&rtwpci->irq_lock); - if (!rtwpci->irq_enabled) - goto out; - /* disable RTW PCI interrupt to avoid more interrupts before the end of * thread function * @@ -912,8 +997,6 @@ * a new HISR flag is set. */ rtw_pci_disable_interrupt(rtwdev, rtwpci); -out: - spin_unlock(&rtwpci->irq_lock); return IRQ_WAKE_THREAD; } @@ -922,10 +1005,9 @@ { struct rtw_dev *rtwdev = dev; struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; - unsigned long flags; u32 irq_status[4]; - spin_lock_irqsave(&rtwpci->irq_lock, flags); + spin_lock_bh(&rtwpci->irq_lock); rtw_pci_irq_recognized(rtwdev, rtwpci, irq_status); if (irq_status[0] & IMR_MGNTDOK) @@ -947,7 +1029,7 @@ /* all of the jobs for this interrupt have been done */ rtw_pci_enable_interrupt(rtwdev, rtwpci); - spin_unlock_irqrestore(&rtwpci->irq_lock, flags); + spin_unlock_bh(&rtwpci->irq_lock); return IRQ_HANDLED; } @@ -969,6 +1051,7 @@ len = pci_resource_len(pdev, bar_id); rtwpci->mmap = pci_iomap(pdev, bar_id, len); if (!rtwpci->mmap) { + pci_release_regions(pdev); rtw_err(rtwdev, "failed to map pci memory\n"); return -ENOMEM; } @@ -990,23 +1073,49 @@ static void rtw_dbi_write8(struct rtw_dev *rtwdev, u16 addr, u8 data) { u16 write_addr; - u16 remainder = addr & 0x3; + u16 remainder = addr & ~(BITS_DBI_WREN | BITS_DBI_ADDR_MASK); u8 flag; - u8 cnt = 20; + u8 cnt; - write_addr = ((addr & 0x0ffc) | (BIT(0) << (remainder + 12))); + write_addr = addr & BITS_DBI_ADDR_MASK; + write_addr |= u16_encode_bits(BIT(remainder), BITS_DBI_WREN); rtw_write8(rtwdev, REG_DBI_WDATA_V1 + remainder, data); rtw_write16(rtwdev, REG_DBI_FLAG_V1, write_addr); - rtw_write8(rtwdev, REG_DBI_FLAG_V1 + 2, 0x01); + rtw_write8(rtwdev, REG_DBI_FLAG_V1 + 2, BIT_DBI_WFLAG >> 16); + + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { + flag = rtw_read8(rtwdev, REG_DBI_FLAG_V1 + 2); + if (flag == 0) + return; - flag = rtw_read8(rtwdev, REG_DBI_FLAG_V1 + 2); - while (flag && (cnt != 0)) { udelay(10); + } + + WARN(flag, "failed to write to DBI register, addr=0x%04x\n", addr); +} + +static int rtw_dbi_read8(struct rtw_dev *rtwdev, u16 addr, u8 *value) +{ + u16 read_addr = addr & BITS_DBI_ADDR_MASK; + u8 flag; + u8 cnt; + + rtw_write16(rtwdev, REG_DBI_FLAG_V1, read_addr); + rtw_write8(rtwdev, REG_DBI_FLAG_V1 + 2, BIT_DBI_RFLAG >> 16); + + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { flag = rtw_read8(rtwdev, REG_DBI_FLAG_V1 + 2); - cnt--; + if (flag == 0) { + read_addr = REG_DBI_RDATA_V1 + (addr & 3); + *value = rtw_read8(rtwdev, read_addr); + return 0; + } + + udelay(10); } - WARN(flag, "DBI write fail\n"); + WARN(1, "failed to read DBI register, addr=0x%04x\n", addr); + return -EIO; } static void rtw_mdio_write(struct rtw_dev *rtwdev, u8 addr, u16 data, bool g1) @@ -1017,23 +1126,135 @@ rtw_write16(rtwdev, REG_MDIO_V1, data); - page = addr < 0x20 ? 0 : 1; - page += g1 ? 0 : 2; - rtw_write8(rtwdev, REG_PCIE_MIX_CFG, addr & 0x1f); + page = addr < RTW_PCI_MDIO_PG_SZ ? 0 : 1; + page += g1 ? RTW_PCI_MDIO_PG_OFFS_G1 : RTW_PCI_MDIO_PG_OFFS_G2; + rtw_write8(rtwdev, REG_PCIE_MIX_CFG, addr & BITS_MDIO_ADDR_MASK); rtw_write8(rtwdev, REG_PCIE_MIX_CFG + 3, page); - rtw_write32_mask(rtwdev, REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1, 1); - wflag = rtw_read32_mask(rtwdev, REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1); - cnt = 20; - while (wflag && (cnt != 0)) { - udelay(10); + for (cnt = 0; cnt < RTW_PCI_WR_RETRY_CNT; cnt++) { wflag = rtw_read32_mask(rtwdev, REG_PCIE_MIX_CFG, BIT_MDIO_WFLAG_V1); - cnt--; + if (wflag == 0) + return; + + udelay(10); + } + + WARN(wflag, "failed to write to MDIO register, addr=0x%02x\n", addr); +} + +static void rtw_pci_clkreq_set(struct rtw_dev *rtwdev, bool enable) +{ + u8 value; + int ret; + + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); + if (ret) { + rtw_err(rtwdev, "failed to read CLKREQ_L1, ret=%d", ret); + return; + } + + if (enable) + value |= BIT_CLKREQ_SW_EN; + else + value &= ~BIT_CLKREQ_SW_EN; + + rtw_dbi_write8(rtwdev, RTK_PCIE_LINK_CFG, value); +} + +static void rtw_pci_aspm_set(struct rtw_dev *rtwdev, bool enable) +{ + u8 value; + int ret; + + ret = rtw_dbi_read8(rtwdev, RTK_PCIE_LINK_CFG, &value); + if (ret) { + rtw_err(rtwdev, "failed to read ASPM, ret=%d", ret); + return; + } + + if (enable) + value |= BIT_L1_SW_EN; + else + value &= ~BIT_L1_SW_EN; + + rtw_dbi_write8(rtwdev, RTK_PCIE_LINK_CFG, value); +} + +static void rtw_pci_link_ps(struct rtw_dev *rtwdev, bool enter) +{ + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + + /* Like CLKREQ, ASPM is also implemented by two HW modules, and can + * only be enabled when host supports it. + * + * And ASPM mechanism should be enabled when driver/firmware enters + * power save mode, without having heavy traffic. Because we've + * experienced some inter-operability issues that the link tends + * to enter L1 state on the fly even when driver is having high + * throughput. This is probably because the ASPM behavior slightly + * varies from different SOC. + */ + if (rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1) + rtw_pci_aspm_set(rtwdev, enter); +} + +static void rtw_pci_link_cfg(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_pci *rtwpci = (struct rtw_pci *)rtwdev->priv; + struct pci_dev *pdev = rtwpci->pdev; + u16 link_ctrl; + int ret; + + /* RTL8822CE has enabled REFCLK auto calibration, it does not need + * to add clock delay to cover the REFCLK timing gap. + */ + if (chip->id == RTW_CHIP_TYPE_8822C) + rtw_dbi_write8(rtwdev, RTK_PCIE_CLKDLY_CTRL, 0); + + /* Though there is standard PCIE configuration space to set the + * link control register, but by Realtek's design, driver should + * check if host supports CLKREQ/ASPM to enable the HW module. + * + * These functions are implemented by two HW modules associated, + * one is responsible to access PCIE configuration space to + * follow the host settings, and another is in charge of doing + * CLKREQ/ASPM mechanisms, it is default disabled. Because sometimes + * the host does not support it, and due to some reasons or wrong + * settings (ex. CLKREQ# not Bi-Direction), it could lead to device + * loss if HW misbehaves on the link. + * + * Hence it's designed that driver should first check the PCIE + * configuration space is sync'ed and enabled, then driver can turn + * on the other module that is actually working on the mechanism. + */ + ret = pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &link_ctrl); + if (ret) { + rtw_err(rtwdev, "failed to read PCI cap, ret=%d\n", ret); + return; } - WARN(wflag, "MDIO write fail\n"); + if (link_ctrl & PCI_EXP_LNKCTL_CLKREQ_EN) + rtw_pci_clkreq_set(rtwdev, true); + + rtwpci->link_ctrl = link_ctrl; +} + +static void rtw_pci_interface_cfg(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + + switch (chip->id) { + case RTW_CHIP_TYPE_8822C: + if (rtwdev->hal.cut_version >= RTW_CHIP_VER_CUT_D) + rtw_write32_mask(rtwdev, REG_HCI_MIX_CFG, + BIT_PCIE_EMAC_PDN_AUX_TO_FAST_CLK, 1); + break; + default: + break; + } } static void rtw_pci_phy_cfg(struct rtw_dev *rtwdev) @@ -1074,8 +1295,27 @@ else rtw_dbi_write8(rtwdev, offset, value); } + + rtw_pci_link_cfg(rtwdev); } +#ifdef CONFIG_PM +static int rtw_pci_suspend(struct device *dev) +{ + return 0; +} + +static int rtw_pci_resume(struct device *dev) +{ + return 0; +} + +static SIMPLE_DEV_PM_OPS(rtw_pm_ops, rtw_pci_suspend, rtw_pci_resume); +#define RTW_PM_OPS (&rtw_pm_ops) +#else +#define RTW_PM_OPS NULL +#endif + static int rtw_pci_claim(struct rtw_dev *rtwdev, struct pci_dev *pdev) { int ret; @@ -1120,8 +1360,6 @@ goto err_io_unmap; } - rtw_pci_phy_cfg(rtwdev); - return 0; err_io_unmap: @@ -1142,6 +1380,9 @@ .setup = rtw_pci_setup, .start = rtw_pci_start, .stop = rtw_pci_stop, + .deep_ps = rtw_pci_deep_ps, + .link_ps = rtw_pci_link_ps, + .interface_cfg = rtw_pci_interface_cfg, .read8 = rtw_pci_read8, .read16 = rtw_pci_read16, @@ -1233,6 +1474,8 @@ goto err_destroy_pci; } + rtw_pci_phy_cfg(rtwdev); + ret = rtw_register_hw(rtwdev, hw); if (ret) { rtw_err(rtwdev, "failed to register hw\n"); @@ -1283,12 +1526,32 @@ ieee80211_free_hw(hw); } +static void rtw_pci_shutdown(struct pci_dev *pdev) +{ + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct rtw_dev *rtwdev; + struct rtw_chip_info *chip; + + if (!hw) + return; + + rtwdev = hw->priv; + chip = rtwdev->chip; + + if (chip->ops->shutdown) + chip->ops->shutdown(rtwdev); +} + static const struct pci_device_id rtw_pci_id_table[] = { #ifdef CONFIG_RTW88_8822BE { RTK_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xB822, rtw8822b_hw_spec) }, #endif #ifdef CONFIG_RTW88_8822CE { RTK_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC822, rtw8822c_hw_spec) }, + { RTK_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xC82F, rtw8822c_hw_spec) }, +#endif +#ifdef CONFIG_RTW88_8723DE + { RTK_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0xD723, rtw8723d_hw_spec) }, #endif {}, }; @@ -1299,6 +1562,8 @@ .id_table = rtw_pci_id_table, .probe = rtw_pci_probe, .remove = rtw_pci_remove, + .driver.pm = RTW_PM_OPS, + .shutdown = rtw_pci_shutdown, }; module_pci_driver(rtw_pci_driver); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/pci.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/pci.h @@ -13,17 +13,33 @@ #define RTK_BEQ_TX_DESC_NUM 256 #define RTK_MAX_RX_DESC_NUM 512 -/* 8K + rx desc size */ -#define RTK_PCI_RX_BUF_SIZE (8192 + 24) +/* 11K + rx desc size */ +#define RTK_PCI_RX_BUF_SIZE (11454 + 24) #define RTK_PCI_CTRL 0x300 #define BIT_RST_TRXDMA_INTF BIT(20) #define BIT_RX_TAG_EN BIT(15) #define REG_DBI_WDATA_V1 0x03E8 +#define REG_DBI_RDATA_V1 0x03EC #define REG_DBI_FLAG_V1 0x03F0 +#define BIT_DBI_RFLAG BIT(17) +#define BIT_DBI_WFLAG BIT(16) +#define BITS_DBI_WREN GENMASK(15, 12) +#define BITS_DBI_ADDR_MASK GENMASK(11, 2) + #define REG_MDIO_V1 0x03F4 #define REG_PCIE_MIX_CFG 0x03F8 +#define BITS_MDIO_ADDR_MASK GENMASK(4, 0) #define BIT_MDIO_WFLAG_V1 BIT(5) +#define RTW_PCI_MDIO_PG_SZ BIT(5) +#define RTW_PCI_MDIO_PG_OFFS_G1 0 +#define RTW_PCI_MDIO_PG_OFFS_G2 2 +#define RTW_PCI_WR_RETRY_CNT 20 + +#define RTK_PCIE_LINK_CFG 0x0719 +#define BIT_CLKREQ_SW_EN BIT(4) +#define BIT_L1_SW_EN BIT(3) +#define RTK_PCIE_CLKDLY_CTRL 0x0725 #define BIT_PCI_BCNQ_FLAG BIT(4) #define RTK_PCI_TXBD_DESA_BCNQ 0x308 @@ -182,7 +198,9 @@ struct rtw_pci { struct pci_dev *pdev; - /* used for pci interrupt */ + /* Used for PCI interrupt. */ + spinlock_t hwirq_lock; + /* Used for PCI TX queueing. */ spinlock_t irq_lock; u32 irq_mask[4]; bool irq_enabled; @@ -190,11 +208,12 @@ u16 rx_tag; struct rtw_pci_tx_ring tx_rings[RTK_MAX_TX_QUEUE_NUM]; struct rtw_pci_rx_ring rx_rings[RTK_MAX_RX_QUEUE_NUM]; + u16 link_ctrl; void __iomem *mmap; }; -static u32 max_num_of_tx_queue(u8 queue) +static inline u32 max_num_of_tx_queue(u8 queue) { u32 max_num; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/phy.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/phy.c @@ -20,15 +20,6 @@ struct phy_cfg_pair cfg; }; -struct phy_pg_cfg_pair { - u32 band; - u32 rf_path; - u32 tx_num; - u32 addr; - u32 bitmask; - u32 data; -}; - static const u32 db_invert_table[12][8] = { {10, 13, 16, 20, 25, 32, 40, 50}, @@ -118,12 +109,63 @@ for (i = 0; i <= RTW_CHANNEL_WIDTH_40; i++) { for (j = 0; j < RTW_RF_PATH_MAX; j++) - dm_info->cck_pd_lv[i][j] = 0; + dm_info->cck_pd_lv[i][j] = CCK_PD_LV0; } dm_info->cck_fa_avg = CCK_FA_AVG_RESET; } +void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) +{ + struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.mask, + l2h + edcca_th[EDCCA_TH_L2H_IDX].offset); + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_H2L_IDX].hw_reg.addr, + edcca_th[EDCCA_TH_H2L_IDX].hw_reg.mask, + h2l + edcca_th[EDCCA_TH_H2L_IDX].offset); +} + +void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + /* turn off in debugfs for debug usage */ + if (!rtw_edcca_enabled) { + dm_info->edcca_mode = RTW_EDCCA_NORMAL; + rtw_dbg(rtwdev, RTW_DBG_PHY, "disable edcca\n"); + return; + } + + switch (rtwdev->regd.txpwr_regd) { + case RTW_REGD_WW: + case RTW_REGD_ETSI: + dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; + dm_info->l2h_th_ini = chip->l2h_th_ini_ad; + break; + case RTW_REGD_MKK: + dm_info->edcca_mode = RTW_EDCCA_ADAPTIVITY; + dm_info->l2h_th_ini = chip->l2h_th_ini_cs; + break; + default: + dm_info->edcca_mode = RTW_EDCCA_NORMAL; + break; + } +} + +static void rtw_phy_adaptivity_init(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + + rtw_phy_adaptivity_set_mode(rtwdev); + if (chip->ops->adaptivity_init) + chip->ops->adaptivity_init(rtwdev); +} + void rtw_phy_init(struct rtw_dev *rtwdev) { struct rtw_chip_info *chip = rtwdev->chip; @@ -143,15 +185,21 @@ mask = chip->dig[0].mask; dm_info->igi_history[0] = rtw_read32_mask(rtwdev, addr, mask); rtw_phy_cck_pd_init(rtwdev); + rtw_phy_adaptivity_init(rtwdev); + dm_info->iqk.done = false; } void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi) { struct rtw_chip_info *chip = rtwdev->chip; struct rtw_hal *hal = &rtwdev->hal; + struct rtw_hw_reg *dig_cck = &chip->dig_cck[0]; u32 addr, mask; u8 path; + if (dig_cck) + rtw_write32_mask(rtwdev, dig_cck->addr, dig_cck->mask, igi >> 1); + for (path = 0; path < hal->rf_path_num; path++) { addr = chip->dig[path].addr; mask = chip->dig[path].mask; @@ -222,10 +270,19 @@ dm_info->min_rssi = data.min_rssi; } +static void rtw_phy_stat_rate_cnt(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->last_pkt_count = dm_info->cur_pkt_count; + memset(&dm_info->cur_pkt_count, 0, sizeof(dm_info->cur_pkt_count)); +} + static void rtw_phy_statistics(struct rtw_dev *rtwdev) { rtw_phy_stat_rssi(rtwdev); rtw_phy_stat_false_alarm(rtwdev); + rtw_phy_stat_rate_cnt(rtwdev); } #define DIG_PERF_FA_TH_LOW 250 @@ -394,7 +451,7 @@ u8 step[3]; bool linked; - if (rtw_flag_check(rtwdev, RTW_FLAG_DIG_DISABLE)) + if (test_bit(RTW_FLAG_DIG_DISABLE, rtwdev->flags)) return; if (rtw_phy_dig_check_damping(dm_info)) @@ -461,7 +518,6 @@ chip->ops->dpk_track(rtwdev); } -#define CCK_PD_LV_MAX 5 #define CCK_PD_FA_LV1_MIN 1000 #define CCK_PD_FA_LV0_MAX 500 @@ -471,10 +527,10 @@ u32 cck_fa_avg = dm_info->cck_fa_avg; if (cck_fa_avg > CCK_PD_FA_LV1_MIN) - return 1; + return CCK_PD_LV1; if (cck_fa_avg < CCK_PD_FA_LV0_MAX) - return 0; + return CCK_PD_LV0; return CCK_PD_LV_MAX; } @@ -494,15 +550,15 @@ u32 cck_fa_avg = dm_info->cck_fa_avg; if (igi > CCK_PD_IGI_LV4_VAL && rssi > CCK_PD_RSSI_LV4_VAL) - return 4; + return CCK_PD_LV4; if (igi > CCK_PD_IGI_LV3_VAL && rssi > CCK_PD_RSSI_LV3_VAL) - return 3; + return CCK_PD_LV3; if (igi > CCK_PD_IGI_LV2_VAL || rssi > CCK_PD_RSSI_LV2_VAL) - return 2; + return CCK_PD_LV2; if (cck_fa_avg > CCK_PD_FA_LV1_MIN) - return 1; + return CCK_PD_LV1; if (cck_fa_avg < CCK_PD_FA_LV0_MAX) - return 0; + return CCK_PD_LV0; return CCK_PD_LV_MAX; } @@ -539,6 +595,17 @@ chip->ops->cck_pd_set(rtwdev, level); } +static void rtw_phy_pwr_track(struct rtw_dev *rtwdev) +{ + rtwdev->chip->ops->pwr_track(rtwdev); +} + +static void rtw_phy_adaptivity(struct rtw_dev *rtwdev) +{ + if (rtwdev->chip->ops->adaptivity) + rtwdev->chip->ops->adaptivity(rtwdev); +} + void rtw_phy_dynamic_mechanism(struct rtw_dev *rtwdev) { /* for further calculation */ @@ -547,6 +614,8 @@ rtw_phy_cck_pd(rtwdev); rtw_phy_ra_info_update(rtwdev); rtw_phy_dpk_track(rtwdev); + rtw_phy_pwr_track(rtwdev); + rtw_phy_adaptivity(rtwdev); } #define FRAC_BITS 3 @@ -674,7 +743,7 @@ const u32 *base_addr = chip->rf_base_addr; u32 val, direct_addr; - if (rf_path >= hal->rf_path_num) { + if (rf_path >= hal->rf_phy_num) { rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); return INV_RF_DATA; } @@ -688,6 +757,54 @@ return val; } +u32 rtw_phy_read_rf_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask) +{ + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_rf_sipi_addr *rf_sipi_addr; + struct rtw_rf_sipi_addr *rf_sipi_addr_a; + u32 val32; + u32 en_pi; + u32 r_addr; + u32 shift; + + if (rf_path >= hal->rf_phy_num) { + rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); + return INV_RF_DATA; + } + + if (!chip->rf_sipi_read_addr) { + rtw_err(rtwdev, "rf_sipi_read_addr isn't defined\n"); + return INV_RF_DATA; + } + + rf_sipi_addr = &chip->rf_sipi_read_addr[rf_path]; + rf_sipi_addr_a = &chip->rf_sipi_read_addr[RF_PATH_A]; + + addr &= 0xff; + + val32 = rtw_read32(rtwdev, rf_sipi_addr->hssi_2); + val32 = (val32 & ~LSSI_READ_ADDR_MASK) | (addr << 23); + rtw_write32(rtwdev, rf_sipi_addr->hssi_2, val32); + + /* toggle read edge of path A */ + val32 = rtw_read32(rtwdev, rf_sipi_addr_a->hssi_2); + rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 & ~LSSI_READ_EDGE_MASK); + rtw_write32(rtwdev, rf_sipi_addr_a->hssi_2, val32 | LSSI_READ_EDGE_MASK); + + udelay(120); + + en_pi = rtw_read32_mask(rtwdev, rf_sipi_addr->hssi_1, BIT(8)); + r_addr = en_pi ? rf_sipi_addr->lssi_read_pi : rf_sipi_addr->lssi_read; + + val32 = rtw_read32_mask(rtwdev, r_addr, LSSI_READ_DATA_MASK); + + shift = __ffs(mask); + + return (val32 & mask) >> shift; +} + bool rtw_phy_write_rf_reg_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask, u32 data) { @@ -698,7 +815,7 @@ u32 old_data = 0; u32 shift; - if (rf_path >= hal->rf_path_num) { + if (rf_path >= hal->rf_phy_num) { rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); return false; } @@ -707,7 +824,7 @@ mask &= RFREG_MASK; if (mask != RFREG_MASK) { - old_data = rtw_phy_read_rf(rtwdev, rf_path, addr, RFREG_MASK); + old_data = chip->ops->read_rf(rtwdev, rf_path, addr, RFREG_MASK); if (old_data == INV_RF_DATA) { rtw_err(rtwdev, "Write fail, rf is disabled\n"); @@ -735,7 +852,7 @@ const u32 *base_addr = chip->rf_base_addr; u32 direct_addr; - if (rf_path >= hal->rf_path_num) { + if (rf_path >= hal->rf_phy_num) { rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); return false; } @@ -744,20 +861,10 @@ direct_addr = base_addr[rf_path] + (addr << 2); mask &= RFREG_MASK; - if (addr == RF_CFGCH) { - rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, DISABLE_PI); - rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, DISABLE_PI); - } - rtw_write32_mask(rtwdev, direct_addr, mask, data); udelay(1); - if (addr == RF_CFGCH) { - rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, ENABLE_PI); - rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, ENABLE_PI); - } - return true; } @@ -1211,10 +1318,8 @@ void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl) { - const struct phy_pg_cfg_pair *p = tbl->data; - const struct phy_pg_cfg_pair *end = p + tbl->size / 6; - - BUILD_BUG_ON(sizeof(struct phy_pg_cfg_pair) != sizeof(u32) * 6); + const struct rtw_phy_pg_cfg_pair *p = tbl->data; + const struct rtw_phy_pg_cfg_pair *end = p + tbl->size; for (; p < end; p++) { if (p->addr == 0xfe || p->addr == 0xffe) { @@ -1292,6 +1397,94 @@ } } +static void +rtw_phy_set_tx_power_sar_by_chidx(struct rtw_dev *rtwdev, u8 regd, u8 rfpath, + u8 band, u8 rs, u8 ch_idx, s8 sar) +{ + struct rtw_hal *hal = &rtwdev->hal; + s8 base; + s8 ww_sar; + s8 s; + + if (band == PHY_BAND_2G) { + base = hal->tx_pwr_by_rate_base_2g[rfpath][rs]; + s = sar - base; + hal->tx_pwr_sar_2g[regd][rfpath][rs][ch_idx] = s; + if (regd == RTW_REGD_WW) + return; + ww_sar = hal->tx_pwr_sar_2g[RTW_REGD_WW][rfpath][rs][ch_idx]; + ww_sar = min(ww_sar, s); + hal->tx_pwr_sar_2g[RTW_REGD_WW][rfpath][rs][ch_idx] = ww_sar; + } else { + base = hal->tx_pwr_by_rate_base_5g[rfpath][rs]; + s = sar - base; + hal->tx_pwr_sar_5g[regd][rfpath][rs][ch_idx] = s; + if (regd == RTW_REGD_WW) + return; + ww_sar = hal->tx_pwr_sar_5g[RTW_REGD_WW][rfpath][rs][ch_idx]; + ww_sar = min(ww_sar, s); + hal->tx_pwr_sar_5g[RTW_REGD_WW][rfpath][rs][ch_idx] = ww_sar; + } +} + +static void +rtw_phy_set_tx_power_sar_by_range(struct rtw_dev *rtwdev, u8 regd, u8 rfpath, + u8 band, u8 chidx_start, u8 chidx_end, u8 sar_q3) +{ + u8 rs; + u8 ch_idx; + s8 sar; + + if (regd >= RTW_REGD_MAX || rfpath >= RTW_RF_PATH_MAX) + return; + + sar = sar_q3 >> (3 - (int)rtwdev->chip->txgi_factor); + + for (ch_idx = chidx_start; ch_idx <= chidx_end; ch_idx++) + for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) + rtw_phy_set_tx_power_sar_by_chidx(rtwdev, regd, rfpath, + band, rs, ch_idx, sar); +} + +void rtw_phy_set_tx_power_sar(struct rtw_dev *rtwdev, u8 regd, u8 rfpath, + u8 ch_start, u8 ch_end, u8 sar_q3) +{ + u8 band_start, band_end; + int chidx_start, chidx_end; + + band_start = ch_start <= 14 ? PHY_BAND_2G : PHY_BAND_5G; + band_end = ch_end <= 14 ? PHY_BAND_2G : PHY_BAND_5G; + + if (band_start == band_end) { + chidx_start = rtw_channel_to_idx(band_start, ch_start); + chidx_end = rtw_channel_to_idx(band_start, ch_end); + if (chidx_start < 0 || chidx_end < 0) + goto err; + rtw_phy_set_tx_power_sar_by_range(rtwdev, regd, rfpath, band_start, + chidx_start, chidx_end, sar_q3); + return; + } + + chidx_start = rtw_channel_to_idx(PHY_BAND_2G, ch_start); + if (chidx_start < 0) + goto err; + rtw_phy_set_tx_power_sar_by_range(rtwdev, regd, rfpath, PHY_BAND_2G, + chidx_start, RTW_MAX_CHANNEL_NUM_2G - 1, + sar_q3); + + chidx_end = rtw_channel_to_idx(PHY_BAND_5G, ch_end); + if (chidx_end < 0) + goto err; + rtw_phy_set_tx_power_sar_by_range(rtwdev, regd, rfpath, PHY_BAND_5G, + 0, chidx_end, sar_q3); + + return; + +err: + rtw_warn(rtwdev, "SAR: invalid channel (start/end)=(%d/%d)\n", + ch_start, ch_end); +} + /* cross-reference 5G power limits if values are not assigned */ static void rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd, @@ -1431,7 +1624,7 @@ rtw_load_table(rtwdev, chip->rfk_init_tbl); - dpk_info->is_dpk_pwr_on = 1; + dpk_info->is_dpk_pwr_on = true; } void rtw_phy_load_tables(struct rtw_dev *rtwdev) @@ -1452,7 +1645,7 @@ } } -static u8 rtw_get_channel_group(u8 channel) +static u8 rtw_get_channel_group(u8 channel, u8 rate) { switch (channel) { default: @@ -1496,6 +1689,7 @@ case 106: return 4; case 14: + return rate <= DESC_RATE11M ? 5 : 4; case 108: case 110: case 112: @@ -1673,9 +1867,10 @@ return tx_power; } -static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, - enum rtw_bandwidth bw, u8 rf_path, - u8 rate, u8 channel, u8 regd) +static void rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, + enum rtw_bandwidth bw, u8 rf_path, + u8 rate, u8 channel, u8 regd, + struct rtw_power_params *pwr_param) { struct rtw_hal *hal = &rtwdev->hal; u8 *cch_by_bw = hal->cch_by_bw; @@ -1684,9 +1879,10 @@ int ch_idx; u8 cur_bw, cur_ch; s8 cur_lmt; + s8 sar, sar_ww; if (regd > RTW_REGD_WW) - return power_limit; + goto err; if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) rs = RTW_RATE_SECTION_CCK; @@ -1726,44 +1922,71 @@ power_limit = min_t(s8, cur_lmt, power_limit); } - return power_limit; + ch_idx = rtw_channel_to_idx(band, channel); + if (ch_idx < 0) + goto err; + + if (band == PHY_BAND_2G) { + sar = hal->tx_pwr_sar_2g[regd][rf_path][rs][ch_idx]; + sar_ww = hal->tx_pwr_sar_2g[RTW_REGD_WW][rf_path][rs][ch_idx]; + } else { + sar = hal->tx_pwr_sar_5g[regd][rf_path][rs][ch_idx]; + sar_ww = hal->tx_pwr_sar_5g[RTW_REGD_WW][rf_path][rs][ch_idx]; + } + if (sar >= rtwdev->chip->max_power_index) + sar = sar_ww; + + pwr_param->pwr_sar = sar; + pwr_param->pwr_limit = power_limit; + return; err: WARN(1, "invalid arguments, band=%d, bw=%d, path=%d, rate=%d, ch=%d\n", band, bw, rf_path, rate, channel); - return (s8)rtwdev->chip->max_power_index; + pwr_param->pwr_sar = (s8)rtwdev->chip->max_power_index; + pwr_param->pwr_limit = (s8)rtwdev->chip->max_power_index; } -void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, - u8 ch, u8 regd, struct rtw_power_params *pwr_param) +static void rtw_phy_get_tx_power_base(struct rtw_dev *rtwdev, u8 band, + enum rtw_bandwidth bw, u8 path, u8 rate, + u8 ch, struct rtw_power_params *pwr_param) { struct rtw_hal *hal = &rtwdev->hal; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; struct rtw_txpwr_idx *pwr_idx; - u8 group, band; - u8 *base = &pwr_param->pwr_base; - s8 *offset = &pwr_param->pwr_offset; - s8 *limit = &pwr_param->pwr_limit; + u8 group; + u8 base; + s8 offset; pwr_idx = &rtwdev->efuse.txpwr_idx_table[path]; - group = rtw_get_channel_group(ch); + group = rtw_get_channel_group(ch, rate); /* base power index for 2.4G/5G */ - if (ch <= 14) { - band = PHY_BAND_2G; - *base = rtw_phy_get_2g_tx_power_index(rtwdev, - &pwr_idx->pwr_idx_2g, - bw, rate, group); - *offset = hal->tx_pwr_by_rate_offset_2g[path][rate]; + if (band == PHY_BAND_2G) { + base = rtw_phy_get_2g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_2g, + bw, rate, group); + offset = hal->tx_pwr_by_rate_offset_2g[path][rate]; } else { - band = PHY_BAND_5G; - *base = rtw_phy_get_5g_tx_power_index(rtwdev, - &pwr_idx->pwr_idx_5g, - bw, rate, group); - *offset = hal->tx_pwr_by_rate_offset_5g[path][rate]; + base = rtw_phy_get_5g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_5g, + bw, rate, group); + offset = hal->tx_pwr_by_rate_offset_5g[path][rate]; } - *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, - rate, ch, regd); + pwr_param->pwr_base = base; + pwr_param->pwr_offset = offset; + pwr_param->pwr_remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : + dm_info->txagc_remnant_ofdm); +} + +void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, + u8 ch, u8 regd, struct rtw_power_params *pwr_param) +{ + u8 band = IS_CH_2G_BAND(ch) ? PHY_BAND_2G : PHY_BAND_5G; + + rtw_phy_get_tx_power_base(rtwdev, band, bw, path, rate, ch, pwr_param); + rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, rate, ch, regd, pwr_param); } u8 @@ -1778,12 +2001,13 @@ channel, regd, &pwr_param); tx_power = pwr_param.pwr_base; - offset = min_t(s8, pwr_param.pwr_offset, pwr_param.pwr_limit); + offset = min3(pwr_param.pwr_offset, pwr_param.pwr_limit, + pwr_param.pwr_sar); if (rtwdev->chip->en_dis_dpd) offset += rtw_phy_get_dis_dpd_by_rate_diff(rtwdev, rate); - tx_power += offset; + tx_power += offset + pwr_param.pwr_remnant; if (tx_power > rtwdev->chip->max_power_index) tx_power = rtwdev->chip->max_power_index; @@ -1967,4 +2191,130 @@ for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) rtw_phy_init_tx_power_limit(rtwdev, regd, bw, rs); + + /* init tx power sar */ + memset(hal->tx_pwr_sar_2g, rtwdev->chip->max_power_index, + sizeof(hal->tx_pwr_sar_2g)); + memset(hal->tx_pwr_sar_5g, rtwdev->chip->max_power_index, + sizeof(hal->tx_pwr_sar_5g)); +} + +void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table) +{ + const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; + u8 channel = rtwdev->hal.current_channel; + + if (IS_CH_2G_BAND(channel)) { + if (rtwdev->dm_info.tx_rate <= DESC_RATE11M) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2g_ccka_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2g_ccka_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2g_cckb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2g_cckb_n; + } else { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + } + } else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_1]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_1]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_1]; + } else if (IS_CH_5G_BAND_3(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_2]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_2]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_2]; + } else if (IS_CH_5G_BAND_4(channel)) { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_5ga_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_5ga_n[RTW_PWR_TRK_5G_3]; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_5gb_p[RTW_PWR_TRK_5G_3]; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_5gb_n[RTW_PWR_TRK_5G_3]; + } else { + swing_table->p[RF_PATH_A] = tbl->pwrtrk_2ga_p; + swing_table->n[RF_PATH_A] = tbl->pwrtrk_2ga_n; + swing_table->p[RF_PATH_B] = tbl->pwrtrk_2gb_p; + swing_table->n[RF_PATH_B] = tbl->pwrtrk_2gb_n; + } +} + +void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + ewma_thermal_add(&dm_info->avg_thermal[path], thermal); + dm_info->thermal_avg[path] = + ewma_thermal_read(&dm_info->avg_thermal[path]); +} + +bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 avg = ewma_thermal_read(&dm_info->avg_thermal[path]); + + if (avg == thermal) + return false; + + return true; +} + +u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 therm_avg, therm_efuse, therm_delta; + + therm_avg = dm_info->thermal_avg[path]; + therm_efuse = rtwdev->efuse.thermal_meter[path]; + therm_delta = abs(therm_avg - therm_efuse); + + return min_t(u8, therm_delta, RTW_PWR_TRK_TBL_SZ - 1); +} + +s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 tbl_path, u8 therm_path, u8 delta) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + const u8 *delta_swing_table_idx_pos; + const u8 *delta_swing_table_idx_neg; + + if (delta >= RTW_PWR_TRK_TBL_SZ) { + rtw_warn(rtwdev, "power track table overflow\n"); + return 0; + } + + if (!swing_table) { + rtw_warn(rtwdev, "swing table not configured\n"); + return 0; + } + + delta_swing_table_idx_pos = swing_table->p[tbl_path]; + delta_swing_table_idx_neg = swing_table->n[tbl_path]; + + if (!delta_swing_table_idx_pos || !delta_swing_table_idx_neg) { + rtw_warn(rtwdev, "invalid swing table index\n"); + return 0; + } + + if (dm_info->thermal_avg[therm_path] > + rtwdev->efuse.thermal_meter[therm_path]) + return delta_swing_table_idx_pos[delta]; + else + return -delta_swing_table_idx_neg[delta]; +} + +bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 delta_iqk; + + delta_iqk = abs(dm_info->thermal_avg[0] - dm_info->thermal_meter_k); + if (delta_iqk >= rtwdev->chip->iqk_threshold) { + dm_info->thermal_meter_k = dm_info->thermal_avg[0]; + return true; + } + return false; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/phy.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/phy.h @@ -21,6 +21,8 @@ u8 rtw_phy_rf_power_2_rssi(s8 *rf_power, u8 path_num); u32 rtw_phy_read_rf(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask); +u32 rtw_phy_read_rf_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); bool rtw_phy_write_rf_reg_sipi(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask, u32 data); bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, @@ -41,9 +43,23 @@ u32 addr, u32 data); void rtw_phy_init_tx_power(struct rtw_dev *rtwdev); void rtw_phy_load_tables(struct rtw_dev *rtwdev); +u8 rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, + enum rtw_bandwidth bw, u8 channel, u8 regd); void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel); void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal); void rtw_phy_tx_power_limit_config(struct rtw_hal *hal); +void rtw_phy_pwrtrack_avg(struct rtw_dev *rtwdev, u8 thermal, u8 path); +bool rtw_phy_pwrtrack_thermal_changed(struct rtw_dev *rtwdev, u8 thermal, + u8 path); +u8 rtw_phy_pwrtrack_get_delta(struct rtw_dev *rtwdev, u8 path); +s8 rtw_phy_pwrtrack_get_pwridx(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 tbl_path, u8 therm_path, u8 delta); +bool rtw_phy_pwrtrack_need_iqk(struct rtw_dev *rtwdev); +void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table); +void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l); +void rtw_phy_adaptivity_set_mode(struct rtw_dev *rtwdev); struct rtw_txpwr_lmt_cfg_pair { u8 regd; @@ -54,6 +70,15 @@ s8 txpwr_lmt; }; +struct rtw_phy_pg_cfg_pair { + u32 band; + u32 rf_path; + u32 tx_num; + u32 addr; + u32 bitmask; + u32 data; +}; + #define RTW_DECL_TABLE_PHY_COND_CORE(name, cfg, path) \ const struct rtw_table name ## _tbl = { \ .data = name, \ @@ -118,12 +143,25 @@ u8 pwr_base; s8 pwr_offset; s8 pwr_limit; + s8 pwr_sar; + s8 pwr_remnant; }; void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, u8 ch, u8 regd, struct rtw_power_params *pwr_param); +void rtw_phy_set_tx_power_sar(struct rtw_dev *rtwdev, u8 regd, u8 rfpath, + u8 ch_start, u8 ch_end, u8 sar_q3); + +enum rtw_phy_cck_pd_lv { + CCK_PD_LV0, + CCK_PD_LV1, + CCK_PD_LV2, + CCK_PD_LV3, + CCK_PD_LV4, + CCK_PD_LV_MAX, +}; #define MASKBYTE0 0xff #define MASKBYTE1 0xff00 @@ -148,4 +186,8 @@ #define CCK_FA_AVG_RESET 0xffffffff +#define LSSI_READ_ADDR_MASK 0x7f800000 +#define LSSI_READ_EDGE_MASK 0x80000000 +#define LSSI_READ_DATA_MASK 0xfffff + #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/ps.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/ps.c @@ -3,6 +3,7 @@ */ #include "main.h" +#include "reg.h" #include "fw.h" #include "ps.h" #include "mac.h" @@ -18,18 +19,19 @@ rtw_err(rtwdev, "leave idle state failed\n"); rtw_set_channel(rtwdev); - rtw_flag_clear(rtwdev, RTW_FLAG_INACTIVE_PS); + clear_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags); return ret; } int rtw_enter_ips(struct rtw_dev *rtwdev) { - rtw_flag_set(rtwdev, RTW_FLAG_INACTIVE_PS); + set_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags); rtw_coex_ips_notify(rtwdev, COEX_IPS_ENTER); rtw_core_stop(rtwdev); + rtw_hci_link_ps(rtwdev, true); return 0; } @@ -48,6 +50,8 @@ { int ret; + rtw_hci_link_ps(rtwdev, false); + ret = rtw_ips_pwr_up(rtwdev); if (ret) { rtw_err(rtwdev, "failed to leave ips state\n"); @@ -61,6 +65,85 @@ return 0; } +void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter) +{ + u8 request, confirm, polling; + u8 polling_cnt; + u8 retry_cnt = 0; + + for (retry_cnt = 0; retry_cnt < 3; retry_cnt++) { + request = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); + confirm = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); + + /* toggle to request power mode, others remain 0 */ + request ^= request | BIT_RPWM_TOGGLE; + if (!enter) { + request |= POWER_MODE_ACK; + } else { + request |= POWER_MODE_LCLK; + if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) + request |= POWER_MODE_PG; + } + + rtw_write8(rtwdev, rtwdev->hci.rpwm_addr, request); + + if (enter) + return; + + /* check confirm power mode has left power save state */ + for (polling_cnt = 0; polling_cnt < 50; polling_cnt++) { + polling = rtw_read8(rtwdev, rtwdev->hci.cpwm_addr); + if ((polling ^ confirm) & BIT_RPWM_TOGGLE) + return; + udelay(100); + } + + /* in case of fw/hw missed the request, retry */ + rtw_warn(rtwdev, "failed to leave deep PS, retry=%d\n", + retry_cnt); + } + + /* Hit here means that driver failed to change hardware power mode to + * active state after retry 3 times. If the power state is locked at + * Deep sleep, most of the hardware circuits is not working, even + * register read/write. It should be treated as fatal error and + * requires an entire analysis about the firmware/hardware + */ + WARN(1, "Hardware power state locked\n"); +} +EXPORT_SYMBOL(rtw_power_mode_change); + +static void __rtw_leave_lps_deep(struct rtw_dev *rtwdev) +{ + rtw_hci_deep_ps(rtwdev, false); +} + +static void rtw_fw_leave_lps_state_check(struct rtw_dev *rtwdev) +{ + int i; + + /* Driver needs to wait for firmware to leave LPS state + * successfully. Firmware will send null packet to inform AP, + * and see if AP sends an ACK back, then firmware will restore + * the REG_TCR register. + * + * If driver does not wait for firmware, null packet with + * PS bit could be sent due to incorrect REG_TCR setting. + * + * In our test, 100ms should be enough for firmware to finish + * the flow. If REG_TCR Register is still incorrect after 100ms, + * just modify it directly, and throw a warn message. + */ + for (i = 0 ; i < LEAVE_LPS_TRY_CNT; i++) { + if (rtw_read32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN) == 0) + return; + msleep(20); + } + + rtw_write32_mask(rtwdev, REG_TCR, BIT_PWRMGT_HWDATA_EN, 0); + rtw_warn(rtwdev, "firmware failed to restore hardware setting\n"); +} + static void rtw_leave_lps_core(struct rtw_dev *rtwdev) { struct rtw_lps_conf *conf = &rtwdev->lps_conf; @@ -70,12 +153,32 @@ conf->rlbm = 0; conf->smart_ps = 0; + rtw_hci_link_ps(rtwdev, false); rtw_fw_set_pwr_mode(rtwdev); - rtw_flag_clear(rtwdev, RTW_FLAG_LEISURE_PS); + rtw_fw_leave_lps_state_check(rtwdev); + + clear_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags); rtw_coex_lps_notify(rtwdev, COEX_LPS_DISABLE); } +static void __rtw_enter_lps_deep(struct rtw_dev *rtwdev) +{ + if (rtwdev->lps_conf.deep_mode == LPS_DEEP_MODE_NONE) + return; + + if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "Should enter LPS before entering deep PS\n"); + return; + } + + if (rtw_fw_lps_deep_mode == LPS_DEEP_MODE_PG) + rtw_fw_set_pg_info(rtwdev); + + rtw_hci_deep_ps(rtwdev, true); +} + static void rtw_enter_lps_core(struct rtw_dev *rtwdev) { struct rtw_lps_conf *conf = &rtwdev->lps_conf; @@ -88,88 +191,64 @@ rtw_coex_lps_notify(rtwdev, COEX_LPS_ENABLE); rtw_fw_set_pwr_mode(rtwdev); - rtw_flag_set(rtwdev, RTW_FLAG_LEISURE_PS); -} + rtw_hci_link_ps(rtwdev, true); -void rtw_lps_work(struct work_struct *work) -{ - struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, - lps_work.work); - struct rtw_lps_conf *conf = &rtwdev->lps_conf; - struct rtw_vif *rtwvif = conf->rtwvif; - - if (WARN_ON(!rtwvif)) - return; - - if (conf->mode == RTW_MODE_LPS) - rtw_enter_lps_core(rtwdev); - else - rtw_leave_lps_core(rtwdev); + set_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags); } -void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +static void __rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id) { struct rtw_lps_conf *conf = &rtwdev->lps_conf; - if (rtwvif->in_lps) + if (test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) return; conf->mode = RTW_MODE_LPS; - conf->rtwvif = rtwvif; - rtwvif->in_lps = true; + conf->port_id = port_id; - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0); + rtw_enter_lps_core(rtwdev); } -void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +static void __rtw_leave_lps(struct rtw_dev *rtwdev) { struct rtw_lps_conf *conf = &rtwdev->lps_conf; - if (!rtwvif->in_lps) + if (test_and_clear_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags)) { + rtw_dbg(rtwdev, RTW_DBG_PS, + "Should leave deep PS before leaving LPS\n"); + __rtw_leave_lps_deep(rtwdev); + } + + if (!test_bit(RTW_FLAG_LEISURE_PS, rtwdev->flags)) return; conf->mode = RTW_MODE_ACTIVE; - conf->rtwvif = rtwvif; - rtwvif->in_lps = false; - - ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->lps_work, 0); -} -bool rtw_in_lps(struct rtw_dev *rtwdev) -{ - return rtw_flag_check(rtwdev, RTW_FLAG_LEISURE_PS); + rtw_leave_lps_core(rtwdev); } -void rtw_enter_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id) { - struct rtw_lps_conf *conf = &rtwdev->lps_conf; - - if (WARN_ON(!rtwvif)) - return; + lockdep_assert_held(&rtwdev->mutex); - if (rtwvif->in_lps) + if (rtwdev->coex.stat.wl_force_lps_ctrl) return; - conf->mode = RTW_MODE_LPS; - conf->rtwvif = rtwvif; - rtwvif->in_lps = true; - - rtw_enter_lps_core(rtwdev); + __rtw_enter_lps(rtwdev, port_id); + __rtw_enter_lps_deep(rtwdev); } -void rtw_leave_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif) +void rtw_leave_lps(struct rtw_dev *rtwdev) { - struct rtw_lps_conf *conf = &rtwdev->lps_conf; - - if (WARN_ON(!rtwvif)) - return; + lockdep_assert_held(&rtwdev->mutex); - if (!rtwvif->in_lps) - return; + __rtw_leave_lps_deep(rtwdev); + __rtw_leave_lps(rtwdev); +} - conf->mode = RTW_MODE_ACTIVE; - conf->rtwvif = rtwvif; - rtwvif->in_lps = false; +void rtw_leave_lps_deep(struct rtw_dev *rtwdev) +{ + lockdep_assert_held(&rtwdev->mutex); - rtw_leave_lps_core(rtwdev); + __rtw_leave_lps_deep(rtwdev); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/ps.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/ps.h @@ -5,16 +5,20 @@ #ifndef __RTW_PS_H_ #define __RTW_PS_H_ -#define RTW_LPS_THRESHOLD 2 +#define RTW_LPS_THRESHOLD 50 + +#define POWER_MODE_ACK BIT(6) +#define POWER_MODE_PG BIT(4) +#define POWER_MODE_LCLK BIT(0) + +#define LEAVE_LPS_TRY_CNT 5 int rtw_enter_ips(struct rtw_dev *rtwdev); int rtw_leave_ips(struct rtw_dev *rtwdev); -void rtw_lps_work(struct work_struct *work); -void rtw_enter_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); -void rtw_leave_lps_irqsafe(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); -void rtw_enter_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); -void rtw_leave_lps(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif); -bool rtw_in_lps(struct rtw_dev *rtwdev); +void rtw_power_mode_change(struct rtw_dev *rtwdev, bool enter); +void rtw_enter_lps(struct rtw_dev *rtwdev, u8 port_id); +void rtw_leave_lps(struct rtw_dev *rtwdev); +void rtw_leave_lps_deep(struct rtw_dev *rtwdev); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/reg.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/reg.h @@ -6,13 +6,23 @@ #define __RTW_REG_DEF_H__ #define REG_SYS_FUNC_EN 0x0002 +#define BIT_FEN_EN_25_1 BIT(13) +#define BIT_FEN_ELDR BIT(12) #define BIT_FEN_CPUEN BIT(2) #define BIT_FEN_BB_GLB_RST BIT(1) #define BIT_FEN_BB_RSTB BIT(0) +#define BIT_R_DIS_PRST BIT(6) +#define BIT_WLOCK_1C_B6 BIT(5) #define REG_SYS_PW_CTRL 0x0004 +#define BIT_PFM_WOWL BIT(3) #define REG_SYS_CLK_CTRL 0x0008 #define BIT_CPU_CLK_EN BIT(14) +#define REG_SYS_CLKR 0x0008 +#define BIT_ANA8M BIT(1) +#define BIT_WAKEPAD_EN BIT(3) +#define BIT_LOADER_CLK_EN BIT(5) + #define REG_RSV_CTRL 0x001C #define DISABLE_PI 0x3 #define ENABLE_PI 0x2 @@ -31,12 +41,23 @@ #define BIT_MASK_EF_ADDR 0x3ff #define BIT_MASK_EF_DATA 0xff #define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR) +#define BITS_PLL 0xf0 + +#define REG_AFE_CTRL3 0x2c +#define BIT_MASK_XTAL 0x00FFF000 +#define BIT_XTAL_GMP_BIT4 BIT(28) #define REG_LDO_EFUSE_CTRL 0x0034 #define BIT_MASK_EFUSE_BANK_SEL (BIT(8) | BIT(9)) +#define BIT_LDO25_VOLTAGE_V25 0x03 +#define BIT_MASK_LDO25_VOLTAGE GENMASK(6, 4) +#define BIT_SHIFT_LDO25_VOLTAGE 4 +#define BIT_LDO25_EN BIT(7) + #define REG_GPIO_MUXCFG 0x0040 #define BIT_FSPI_EN BIT(19) +#define BIT_EN_SIC BIT(12) #define BIT_BT_AOD_GPIO3 BIT(9) #define BIT_BT_PTA_EN BIT(5) #define BIT_WLRFE_4_5_EN BIT(2) @@ -46,7 +67,9 @@ #define BIT_PAPE_SEL_EN BIT(25) #define BIT_DPDT_WL_SEL BIT(24) #define BIT_DPDT_SEL_EN BIT(23) +#define REG_LEDCFG2 0x004E #define REG_PAD_CTRL1 0x0064 +#define BIT_BT_BTG_SEL BIT(31) #define BIT_PAPE_WLBT_SEL BIT(29) #define BIT_LNAON_WLBT_SEL BIT(28) #define BIT_BTGP_JTAG_EN BIT(24) @@ -60,31 +83,56 @@ #define BIT_DBG_GNT_WL_BT BIT(27) #define BIT_LTE_MUX_CTRL_PATH BIT(26) #define REG_HCI_OPT_CTRL 0x0074 +#define BIT_USB_SUS_DIS BIT(8) + +#define REG_AFE_CTRL_4 0x0078 +#define BIT_CK320M_AFE_EN BIT(4) +#define BIT_EN_SYN BIT(15) + +#define REG_LDO_SWR_CTRL 0x007C +#define LDO_SEL 0xC3 +#define SPS_SEL 0x83 +#define BIT_XTA1 BIT(29) +#define BIT_XTA0 BIT(28) #define REG_MCUFW_CTRL 0x0080 #define BIT_ANA_PORT_EN BIT(22) #define BIT_MAC_PORT_EN BIT(21) #define BIT_BOOT_FSPI_EN BIT(20) +#define BIT_ROM_DLEN BIT(19) +#define BIT_ROM_PGE GENMASK(18, 16) /* legacy only */ +#define BIT_SHIFT_ROM_PGE 16 #define BIT_FW_INIT_RDY BIT(15) #define BIT_FW_DW_RDY BIT(14) #define BIT_RPWM_TOGGLE BIT(7) +#define BIT_RAM_DL_SEL BIT(7) /* legacy only */ #define BIT_DMEM_CHKSUM_OK BIT(6) +#define BIT_WINTINI_RDY BIT(6) /* legacy only */ #define BIT_DMEM_DW_OK BIT(5) #define BIT_IMEM_CHKSUM_OK BIT(4) #define BIT_IMEM_DW_OK BIT(3) #define BIT_IMEM_BOOT_LOAD_CHECKSUM_OK BIT(2) +#define BIT_FWDL_CHK_RPT BIT(2) /* legacy only */ +#define BIT_MCUFWDL_RDY BIT(1) /* legacy only */ #define BIT_MCUFWDL_EN BIT(0) #define BIT_CHECK_SUM_OK (BIT(4) | BIT(6)) #define FW_READY (BIT_FW_INIT_RDY | BIT_FW_DW_RDY | \ BIT_IMEM_DW_OK | BIT_DMEM_DW_OK | \ BIT_CHECK_SUM_OK) +#define FW_READY_LEGACY (BIT_MCUFWDL_RDY | BIT_FWDL_CHK_RPT | \ + BIT_WINTINI_RDY | BIT_RAM_DL_SEL) #define FW_READY_MASK 0xffff +#define REG_EFUSE_ACCESS 0x00CF +#define EFUSE_ACCESS_ON 0x69 +#define EFUSE_ACCESS_OFF 0x00 + #define REG_WLRF1 0x00EC #define REG_WIFI_BT_INFO 0x00AA #define BIT_BT_INT_EN BIT(15) #define REG_SYS_CFG1 0x00F0 #define BIT_RTL_ID BIT(23) +#define BIT_LDO BIT(24) #define BIT_RF_TYPE_ID BIT(27) #define BIT_SHIFT_VENDOR_ID 16 #define BIT_MASK_VENDOR_ID 0xf @@ -160,8 +208,13 @@ #define REG_CR 0x0100 #define REG_TRXFF_BNDY 0x0114 #define REG_RXFF_BNDY 0x011C +#define REG_FE1IMR 0x0120 +#define BIT_FS_RXDONE BIT(16) #define REG_PKTBUF_DBG_CTRL 0x0140 #define REG_C2HEVT 0x01A0 +#define REG_MCUTST_1 0x01C0 +#define REG_MCUTST_II 0x01C4 +#define REG_WOWLAN_WAKE_REASON 0x01C7 #define REG_HMETFR 0x01CC #define REG_HMEBOX0 0x01D0 #define REG_HMEBOX1 0x01D4 @@ -172,14 +225,42 @@ #define REG_HMEBOX2_EX 0x01F8 #define REG_HMEBOX3_EX 0x01FC +#define REG_RQPN 0x0200 +#define BIT_MASK_HPQ 0xff +#define BIT_SHIFT_HPQ 0 +#define BIT_RQPN_HPQ(x) (((x) & BIT_MASK_HPQ) << BIT_SHIFT_HPQ) +#define BIT_MASK_LPQ 0xff +#define BIT_SHIFT_LPQ 8 +#define BIT_RQPN_LPQ(x) (((x) & BIT_MASK_LPQ) << BIT_SHIFT_LPQ) +#define BIT_MASK_PUBQ 0xff +#define BIT_SHIFT_PUBQ 16 +#define BIT_RQPN_PUBQ(x) (((x) & BIT_MASK_PUBQ) << BIT_SHIFT_PUBQ) +#define BIT_RQPN_HLP(h, l, p) (BIT_LD_RQPN | BIT_RQPN_HPQ(h) | \ + BIT_RQPN_LPQ(l) | BIT_RQPN_PUBQ(p)) + #define REG_FIFOPAGE_CTRL_2 0x0204 #define BIT_BCN_VALID_V1 BIT(15) #define BIT_MASK_BCN_HEAD_1_V1 0xfff #define REG_AUTO_LLT_V1 0x0208 #define BIT_AUTO_INIT_LLT_V1 BIT(0) +#define REG_DWBCN0_CTRL 0x0208 +#define BIT_BCN_VALID BIT(16) #define REG_TXDMA_OFFSET_CHK 0x020C +#define BIT_DROP_DATA_EN BIT(9) #define REG_TXDMA_STATUS 0x0210 #define BTI_PAGE_OVF BIT(2) + +#define REG_RQPN_NPQ 0x0214 +#define BIT_MASK_NPQ 0xff +#define BIT_SHIFT_NPQ 0 +#define BIT_MASK_EPQ 0xff +#define BIT_SHIFT_EPQ 16 +#define BIT_RQPN_NPQ(x) (((x) & BIT_MASK_NPQ) << BIT_SHIFT_NPQ) +#define BIT_RQPN_EPQ(x) (((x) & BIT_MASK_EPQ) << BIT_SHIFT_EPQ) +#define BIT_RQPN_NE(n, e) (BIT_RQPN_NPQ(n) | BIT_RQPN_EPQ(e)) + +#define REG_AUTO_LLT 0x0224 +#define BIT_AUTO_INIT_LLT BIT(16) #define REG_RQPN_CTRL_1 0x0228 #define REG_RQPN_CTRL_2 0x022C #define BIT_LD_RQPN BIT(31) @@ -192,13 +273,26 @@ #define REG_H2C_TAIL 0x0248 #define REG_H2C_READ_ADDR 0x024C #define REG_H2C_INFO 0x0254 +#define REG_RXPKT_NUM 0x0284 +#define BIT_RXDMA_REQ BIT(19) +#define BIT_RW_RELEASE BIT(18) +#define BIT_RXDMA_IDLE BIT(17) +#define REG_RXPKTNUM 0x02B0 #define REG_INT_MIG 0x0304 +#define REG_HCI_MIX_CFG 0x03FC +#define BIT_PCIE_EMAC_PDN_AUX_TO_FAST_CLK BIT(26) +#define REG_BCNQ_INFO 0x0418 +#define BIT_MGQ_CPU_EMPTY BIT(24) #define REG_FWHW_TXQ_CTRL 0x0420 #define BIT_EN_BCNQ_DL BIT(22) #define BIT_EN_WR_FREE_TAIL BIT(20) +#define REG_HWSEQ_CTRL 0x0423 + #define REG_BCNQ_BDNY_V1 0x0424 +#define REG_BCNQ_BDNY 0x0424 +#define REG_MGQ_BDNY 0x0425 #define REG_LIFETIME_EN 0x0426 #define BIT_BA_PARSER_EN BIT(5) #define REG_SPEC_SIFS 0x0428 @@ -214,6 +308,8 @@ #define BIT_CHECK_CCK_EN BIT(7) #define REG_AMPDU_MAX_TIME_V1 0x0455 #define REG_BCNQ1_BDNY_V1 0x0456 +#define REG_AMPDU_MAX_TIME 0x0456 +#define REG_WMAC_LBK_BF_HD 0x045D #define REG_TX_HANG_CTRL 0x045E #define BIT_EN_GNT_BT_AWAKE BIT(3) #define BIT_EN_EOF_V1 BIT(2) @@ -228,7 +324,10 @@ #define REG_QUEUE_CTRL 0x04C6 #define BIT_PTA_WL_TX_EN BIT(4) #define BIT_PTA_EDCCA_EN BIT(5) +#define REG_SINGLE_AMPDU_CTRL 0x04C7 +#define BIT_EN_SINGLE_APMDU BIT(7) #define REG_PROT_MODE_CTRL 0x04C8 +#define REG_MAX_AGGR_NUM 0x04CA #define REG_BAR_MODE_CTRL 0x04CC #define REG_PRECNT_CTRL 0x04E5 #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) @@ -239,38 +338,51 @@ #define REG_EDCA_VI_PARAM 0x0504 #define REG_EDCA_BE_PARAM 0x0508 #define REG_EDCA_BK_PARAM 0x050C +#define BIT_MASK_TXOP_LMT GENMASK(26, 16) +#define BIT_MASK_CWMAX GENMASK(15, 12) +#define BIT_MASK_CWMIN GENMASK(11, 8) +#define BIT_MASK_AIFS GENMASK(7, 0) #define REG_PIFS 0x0512 #define REG_SIFS 0x0514 #define BIT_SHIFT_SIFS_OFDM_CTX 8 #define BIT_SHIFT_SIFS_CCK_TRX 16 #define BIT_SHIFT_SIFS_OFDM_TRX 24 +#define REG_AGGR_BREAK_TIME 0x051A #define REG_SLOT 0x051B #define REG_TX_PTCL_CTRL 0x0520 +#define BIT_DIS_EDCCA BIT(15) #define BIT_SIFS_BK_EN BIT(12) #define REG_TXPAUSE 0x0522 #define REG_RD_CTRL 0x0524 +#define BIT_EDCCA_MSK_CNTDOWN_EN BIT(11) #define BIT_DIS_TXOP_CFE BIT(10) #define BIT_DIS_LSIG_CFE BIT(9) #define BIT_DIS_STBC_CFE BIT(8) #define REG_TBTT_PROHIBIT 0x0540 #define BIT_SHIFT_TBTT_HOLD_TIME_AP 8 #define REG_RD_NAV_NXT 0x0544 +#define REG_NAV_PROT_LEN 0x0546 #define REG_BCN_CTRL 0x0550 #define BIT_DIS_TSF_UDT BIT(4) #define BIT_EN_BCN_FUNCTION BIT(3) +#define BIT_EN_TXBCN_RPT BIT(2) #define REG_BCN_CTRL_CLINT0 0x0551 #define REG_DRVERLYINT 0x0558 #define REG_BCNDMATIM 0x0559 +#define REG_ATIMWND 0x055A #define REG_USTIME_TSF 0x055C #define REG_BCN_MAX_ERR 0x055D #define REG_RXTSF_OFFSET_CCK 0x055E #define REG_MISC_CTRL 0x0577 #define BIT_EN_FREE_CNT BIT(3) #define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1)) +#define REG_HIQ_NO_LMT_EN 0x5A7 +#define BIT_HIQ_NO_LMT_EN_ROOT BIT(0) #define REG_TIMER0_SRC_SEL 0x05B4 #define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) #define REG_TCR 0x0604 +#define BIT_PWRMGT_HWDATA_EN BIT(7) #define REG_RCR 0x0608 #define BIT_APP_FCS BIT(31) #define BIT_APP_MIC BIT(30) @@ -291,6 +403,7 @@ #define BIT_HTC_LOC_CTRL BIT(14) #define BIT_RPFM_CAM_ENABLE BIT(12) #define BIT_TA_BCN BIT(11) +#define BIT_RCR_ADF BIT(11) #define BIT_DISDECMYPKT BIT(10) #define BIT_AICV BIT(9) #define BIT_ACRC32 BIT(8) @@ -305,8 +418,10 @@ #define REG_RX_PKT_LIMIT 0x060C #define REG_RX_DRVINFO_SZ 0x060F #define BIT_APP_PHYSTS BIT(28) +#define REG_MAR 0x0620 #define REG_USTIME_EDCA 0x0638 #define REG_ACKTO_CCK 0x0639 +#define REG_MAC_SPEC_SIFS 0x063A #define REG_RESP_SIFS_CCK 0x063C #define REG_RESP_SIFS_OFDM 0x063E #define REG_ACKTO 0x0640 @@ -317,9 +432,24 @@ #define BIT_RFMOD_80M BIT(8) #define BIT_RFMOD_40M BIT(7) #define REG_WMAC_TRXPTCL_CTL_H 0x066C +#define REG_WKFMCAM_CMD 0x0698 +#define BIT_WKFCAM_POLLING_V1 BIT(31) +#define BIT_WKFCAM_CLR_V1 BIT(30) +#define BIT_WKFCAM_WE BIT(16) +#define BIT_SHIFT_WKFCAM_ADDR_V2 8 +#define BIT_MASK_WKFCAM_ADDR_V2 0xff +#define BIT_WKFCAM_ADDR_V2(x) \ + (((x) & BIT_MASK_WKFCAM_ADDR_V2) << BIT_SHIFT_WKFCAM_ADDR_V2) +#define REG_WKFMCAM_RWD 0x069C +#define BIT_WKFMCAM_VALID BIT(31) +#define BIT_WKFMCAM_BC BIT(26) +#define BIT_WKFMCAM_MC BIT(25) +#define BIT_WKFMCAM_UC BIT(24) + #define REG_RXFLTMAP0 0x06A0 #define REG_RXFLTMAP1 0x06A2 #define REG_RXFLTMAP2 0x06A4 +#define REG_RXFLTMAP4 0x068A #define REG_BT_COEX_TABLE0 0x06C0 #define REG_BT_COEX_TABLE1 0x06C4 #define REG_BT_COEX_BRK_TABLE 0x06C8 @@ -334,12 +464,19 @@ #define BIT_LTE_COEX_EN BIT(7) #define REG_BT_STAT_CTRL 0x0778 #define REG_BT_TDMA_TIME 0x0790 +#define REG_LTR_IDLE_LATENCY 0x0798 +#define REG_LTR_ACTIVE_LATENCY 0x079C +#define REG_LTR_CTRL_BASIC 0x07A4 #define REG_WMAC_OPTION_FUNCTION 0x07D0 #define REG_WMAC_OPTION_FUNCTION_1 0x07D4 +#define REG_FPGA0_RFMOD 0x0800 +#define BIT_CCKEN BIT(24) +#define BIT_OFDMEN BIT(25) #define REG_RX_GAIN_EN 0x081c #define REG_RFE_CTRL_E 0x0974 +#define REG_2ND_CCA_CTRL 0x0976 #define REG_DIS_DPD 0x0a70 #define DIS_DPD_MASK GENMASK(9, 0) @@ -478,7 +615,10 @@ #define REG_IGN_GNTBT4 0x4160 +#define RF_MODE 0x00 #define RF_MODOPT 0x01 +#define RF_WLINT 0x01 +#define RF_WLSEL 0x02 #define RF_DTXLOK 0x08 #define RF_CFGCH 0x18 #define RF_RCK 0x1d @@ -486,9 +626,15 @@ #define RF_LUTWD1 0x3e #define RF_LUTWD0 0x3f #define RF_T_METER 0x42 +#define RF_BSPAD 0x54 +#define RF_GAINTX 0x56 +#define RF_TXATANK 0x64 +#define RF_TRXIQ 0x66 +#define RF_RXIQGEN 0x8d #define RF_XTALX2 0xb8 #define RF_MALSEL 0xbe #define RF_RCKD 0xde +#define RF_TXADBG 0xde #define RF_LUTDBG 0xdf #define RF_LUTWE2 0xee #define RF_LUTWE 0xef --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/regd.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/regd.c @@ -7,6 +7,18 @@ #include "debug.h" #include "phy.h" +static const struct ieee80211_regdomain rtw88_world_regdom = { + .n_reg_rules = 5, + .alpha2 = "99", + .reg_rules = { + REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0), + REG_RULE(2467 - 10, 2484 + 10, 40, 0, 20, NL80211_RRF_NO_IR), + REG_RULE(5180 - 10, 5240 + 10, 80, 0, 20, NL80211_RRF_NO_IR), + REG_RULE(5260 - 10, 5700 + 10, 80, 0, 20, + NL80211_RRF_NO_IR | NL80211_RRF_DFS), + REG_RULE(5745 - 10, 5825 + 10, 80, 0, 20, NL80211_RRF_NO_IR), + } +}; #define COUNTRY_CHPLAN_ENT(_alpha2, _chplan, _txpwr_regd) \ {.alpha2 = (_alpha2), \ .chplan = (_chplan), \ @@ -339,12 +351,31 @@ return rtw_defined_chplan; } +static bool rtw_regd_is_ww(struct rtw_regulatory *reg) +{ + if (reg->txpwr_regd == RTW_REGD_WW) + return true; + return false; +} + static int rtw_regd_notifier_apply(struct rtw_dev *rtwdev, struct wiphy *wiphy, struct regulatory_request *request) { - if (request->initiator == NL80211_REGDOM_SET_BY_USER) + if (request->initiator == NL80211_REGDOM_SET_BY_DRIVER) + return -EINVAL; + if (request->initiator == NL80211_REGDOM_SET_BY_USER && + !IS_ENABLED(CONFIG_RTW88_REGD_USER_REG_HINTS)) + return -EINVAL; + if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && + !rtw_regd_is_ww(&rtwdev->regd)) + return -EINVAL; + if (request->initiator == NL80211_REGDOM_SET_BY_CORE && + !rtwdev->efuse.country_worldwide) { + rtwdev->regd = + rtw_regd_find_reg_by_name(rtwdev->efuse.country_code); return 0; + } rtwdev->regd = rtw_regd_find_reg_by_name(request->alpha2); rtw_regd_apply_world_flags(wiphy, request->initiator); @@ -352,15 +383,22 @@ } static int -rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy, +rtw_regd_init_wiphy(struct rtw_dev *rtwdev, struct wiphy *wiphy, void (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) { + struct rtw_regulatory *reg = &rtwdev->regd; + wiphy->reg_notifier = reg_notifier; - wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG; - wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG; - wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS; + if (rtw_regd_is_ww(reg)) { + rtwdev->efuse.country_worldwide = true; + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; + wiphy_apply_custom_regulatory(wiphy, &rtw88_world_regdom); + } else { + rtwdev->efuse.country_worldwide = false; + } + wiphy->regulatory_flags |= REGULATORY_STRICT_REG; rtw_regd_apply_hw_cap_flags(wiphy); @@ -377,7 +415,7 @@ return -EINVAL; rtwdev->regd = rtw_regd_find_reg_by_name(rtwdev->efuse.country_code); - rtw_regd_init_wiphy(&rtwdev->regd, wiphy, reg_notifier); + rtw_regd_init_wiphy(rtwdev, wiphy, reg_notifier); return 0; } @@ -388,11 +426,14 @@ struct rtw_dev *rtwdev = hw->priv; struct rtw_hal *hal = &rtwdev->hal; - rtw_regd_notifier_apply(rtwdev, wiphy, request); - rtw_dbg(rtwdev, RTW_DBG_REGD, - "get alpha2 %c%c from initiator %d, mapping to chplan 0x%x, txregd %d\n", - request->alpha2[0], request->alpha2[1], request->initiator, - rtwdev->regd.chplan, rtwdev->regd.txpwr_regd); + if (!rtw_regd_notifier_apply(rtwdev, wiphy, request)) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "get alpha2 %c%c from initiator %d, mapping to chplan 0x%x, txregd %d\n", + request->alpha2[0], request->alpha2[1], + request->initiator, rtwdev->regd.chplan, + rtwdev->regd.txpwr_regd); + rtw_phy_adaptivity_set_mode(rtwdev); + } rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8723d.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8723d.c @@ -0,0 +1,2793 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "coex.h" +#include "fw.h" +#include "tx.h" +#include "rx.h" +#include "phy.h" +#include "rtw8723d.h" +#include "rtw8723d_table.h" +#include "mac.h" +#include "reg.h" +#include "debug.h" + +static const struct rtw_hw_reg rtw8723d_txagc[] = { + [DESC_RATE1M] = { .addr = 0xe08, .mask = 0x0000ff00 }, + [DESC_RATE2M] = { .addr = 0x86c, .mask = 0x0000ff00 }, + [DESC_RATE5_5M] = { .addr = 0x86c, .mask = 0x00ff0000 }, + [DESC_RATE11M] = { .addr = 0x86c, .mask = 0xff000000 }, + [DESC_RATE6M] = { .addr = 0xe00, .mask = 0x000000ff }, + [DESC_RATE9M] = { .addr = 0xe00, .mask = 0x0000ff00 }, + [DESC_RATE12M] = { .addr = 0xe00, .mask = 0x00ff0000 }, + [DESC_RATE18M] = { .addr = 0xe00, .mask = 0xff000000 }, + [DESC_RATE24M] = { .addr = 0xe04, .mask = 0x000000ff }, + [DESC_RATE36M] = { .addr = 0xe04, .mask = 0x0000ff00 }, + [DESC_RATE48M] = { .addr = 0xe04, .mask = 0x00ff0000 }, + [DESC_RATE54M] = { .addr = 0xe04, .mask = 0xff000000 }, + [DESC_RATEMCS0] = { .addr = 0xe10, .mask = 0x000000ff }, + [DESC_RATEMCS1] = { .addr = 0xe10, .mask = 0x0000ff00 }, + [DESC_RATEMCS2] = { .addr = 0xe10, .mask = 0x00ff0000 }, + [DESC_RATEMCS3] = { .addr = 0xe10, .mask = 0xff000000 }, + [DESC_RATEMCS4] = { .addr = 0xe14, .mask = 0x000000ff }, + [DESC_RATEMCS5] = { .addr = 0xe14, .mask = 0x0000ff00 }, + [DESC_RATEMCS6] = { .addr = 0xe14, .mask = 0x00ff0000 }, + [DESC_RATEMCS7] = { .addr = 0xe14, .mask = 0xff000000 }, +}; + +#define WLAN_TXQ_RPT_EN 0x1F +#define WLAN_SLOT_TIME 0x09 +#define WLAN_RL_VAL 0x3030 +#define WLAN_BAR_VAL 0x0201ffff +#define BIT_MASK_TBTT_HOLD 0x00000fff +#define BIT_SHIFT_TBTT_HOLD 8 +#define BIT_MASK_TBTT_SETUP 0x000000ff +#define BIT_SHIFT_TBTT_SETUP 0 +#define BIT_MASK_TBTT_MASK ((BIT_MASK_TBTT_HOLD << BIT_SHIFT_TBTT_HOLD) | \ + (BIT_MASK_TBTT_SETUP << BIT_SHIFT_TBTT_SETUP)) +#define TBTT_TIME(s, h)((((s) & BIT_MASK_TBTT_SETUP) << BIT_SHIFT_TBTT_SETUP) |\ + (((h) & BIT_MASK_TBTT_HOLD) << BIT_SHIFT_TBTT_HOLD)) +#define WLAN_TBTT_TIME_NORMAL TBTT_TIME(0x04, 0x80) +#define WLAN_TBTT_TIME_STOP_BCN TBTT_TIME(0x04, 0x64) +#define WLAN_PIFS_VAL 0 +#define WLAN_AGG_BRK_TIME 0x16 +#define WLAN_NAV_PROT_LEN 0x0040 +#define WLAN_SPEC_SIFS 0x100a +#define WLAN_RX_PKT_LIMIT 0x17 +#define WLAN_MAX_AGG_NR 0x0A +#define WLAN_AMPDU_MAX_TIME 0x1C +#define WLAN_ANT_SEL 0x82 +#define WLAN_LTR_IDLE_LAT 0x90039003 +#define WLAN_LTR_ACT_LAT 0x883c883c +#define WLAN_LTR_CTRL1 0xCB004010 +#define WLAN_LTR_CTRL2 0x01233425 + +static void rtw8723d_lck(struct rtw_dev *rtwdev) +{ +#define BIT_LCK BIT(15) + u8 val_ctx; + u32 lc_cal, cnt; + + val_ctx = rtw_read8(rtwdev, REG_CTX); + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) + rtw_write8(rtwdev, REG_CTX, val_ctx & ~BIT_MASK_CTX_TYPE); + else + rtw_write8(rtwdev, REG_TXPAUSE, 0xFF); + lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal | BIT_LCK); + for (cnt = 0; cnt < 100; cnt++) { + if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, BIT_LCK) != 0x1) + break; + mdelay(10); + } + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); + if ((val_ctx & BIT_MASK_CTX_TYPE) != 0) + rtw_write8(rtwdev, REG_CTX, val_ctx); + else + rtw_write8(rtwdev, REG_TXPAUSE, 0x00); +} + +#define RTW_DEF_OFDM_SWING_INDEX 28 +#define RTW_OFDM_SWING_TABLE_SIZE 43 +#define OFDM_SWING_A(swing) ((swing) & 0x000003FF) +#define OFDM_SWING_B(swing) (((swing) & 0x0000FC00) >> 10) +#define OFDM_SWING_C(swing) (((swing) & 0x003F0000) >> 16) +#define OFDM_SWING_D(swing) (((swing) & 0xFFC00000) >> 22) +static const u32 rtw8723d_ofdm_swing_table[] = { + 0x0b40002d, 0x0c000030, 0x0cc00033, 0x0d800036, 0x0e400039, 0x0f00003c, + 0x10000040, 0x11000044, 0x12000048, 0x1300004c, 0x14400051, 0x15800056, + 0x16c0005b, 0x18000060, 0x19800066, 0x1b00006c, 0x1c800072, 0x1e400079, + 0x20000080, 0x22000088, 0x24000090, 0x26000098, 0x288000a2, 0x2ac000ab, + 0x2d4000b5, 0x300000c0, 0x32c000cb, 0x35c000d7, 0x390000e4, 0x3c8000f2, + 0x40000100, 0x43c0010f, 0x47c0011f, 0x4c000130, 0x50800142, 0x55400155, + 0x5a400169, 0x5fc0017f, 0x65400195, 0x6b8001ae, 0x71c001c7, 0x788001e2, + 0x7f8001fe, +}; + +#define RTW_DEF_CCK_SWING_INDEX 28 +#define RTW_CCK_TABLE_SIZE 41 +static const u32 rtw8723d_cck_swing_table[] = { + 0x0CD, 0x0D9, 0x0E6, 0x0F3, 0x102, 0x111, 0x121, 0x132, 0x144, 0x158, + 0x16C, 0x182, 0x198, 0x1B1, 0x1CA, 0x1E5, 0x202, 0x221, 0x241, 0x263, + 0x287, 0x2AE, 0x2D6, 0x301, 0x32F, 0x35F, 0x392, 0x3C9, 0x402, 0x43F, + 0x47F, 0x4C3, 0x50C, 0x558, 0x5A9, 0x5FF, 0x65A, 0x6BA, 0x720, 0x78C, + 0x7FF, +}; + +static_assert(ARRAY_SIZE(rtw8723d_ofdm_swing_table) == RTW_OFDM_SWING_TABLE_SIZE); +static_assert(ARRAY_SIZE(rtw8723d_cck_swing_table) == RTW_CCK_TABLE_SIZE); + +static void rtw8723d_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + dm_info->default_ofdm_index = RTW_DEF_OFDM_SWING_INDEX; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; + dm_info->txagc_remnant_ofdm = 0; +} + +static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +{ + u8 xtal_cap; + u32 val32; + + /* power on BB/RF domain */ + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, + BIT_FEN_EN_25_1 | BIT_FEN_BB_GLB_RST | BIT_FEN_BB_RSTB); + rtw_write8_set(rtwdev, REG_RF_CTRL, + BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); + rtw_write8(rtwdev, REG_AFE_CTRL1 + 1, 0x80); + + rtw_phy_load_tables(rtwdev); + + /* post init after header files config */ + rtw_write32_clr(rtwdev, REG_RCR, BIT_RCR_ADF); + rtw_write8_set(rtwdev, REG_HIQ_NO_LMT_EN, BIT_HIQ_NO_LMT_EN_ROOT); + rtw_write16_set(rtwdev, REG_AFE_CTRL_4, BIT_CK320M_AFE_EN | BIT_EN_SYN); + + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); + rtw_write32_set(rtwdev, REG_FPGA0_RFMOD, BIT_CCKEN | BIT_OFDMEN); + if ((rtwdev->efuse.afe >> 4) == 14) { + rtw_write32_set(rtwdev, REG_AFE_CTRL3, BIT_XTAL_GMP_BIT4); + rtw_write32_clr(rtwdev, REG_AFE_CTRL1, BITS_PLL); + rtw_write32_set(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA1); + rtw_write32_clr(rtwdev, REG_LDO_SWR_CTRL, BIT_XTA0); + } + + rtw_write8(rtwdev, REG_SLOT, WLAN_SLOT_TIME); + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + rtw_write16(rtwdev, REG_RETRY_LIMIT, WLAN_RL_VAL); + rtw_write32(rtwdev, REG_BAR_MODE_CTRL, WLAN_BAR_VAL); + rtw_write8(rtwdev, REG_ATIMWND, 0x2); + rtw_write8(rtwdev, REG_BCN_CTRL, + BIT_DIS_TSF_UDT | BIT_EN_BCN_FUNCTION | BIT_EN_TXBCN_RPT); + val32 = rtw_read32(rtwdev, REG_TBTT_PROHIBIT); + val32 &= ~BIT_MASK_TBTT_MASK; + val32 |= WLAN_TBTT_TIME_STOP_BCN; + rtw_write8(rtwdev, REG_TBTT_PROHIBIT, val32); + rtw_write8(rtwdev, REG_PIFS, WLAN_PIFS_VAL); + rtw_write8(rtwdev, REG_AGGR_BREAK_TIME, WLAN_AGG_BRK_TIME); + rtw_write16(rtwdev, REG_NAV_PROT_LEN, WLAN_NAV_PROT_LEN); + rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS, WLAN_SPEC_SIFS); + rtw_write16(rtwdev, REG_SIFS + 2, WLAN_SPEC_SIFS); + rtw_write8(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); + rtw_write8(rtwdev, REG_RX_PKT_LIMIT, WLAN_RX_PKT_LIMIT); + rtw_write8(rtwdev, REG_MAX_AGGR_NUM, WLAN_MAX_AGG_NR); + rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, WLAN_AMPDU_MAX_TIME); + rtw_write8(rtwdev, REG_LEDCFG2, WLAN_ANT_SEL); + + rtw_write32(rtwdev, REG_LTR_IDLE_LATENCY, WLAN_LTR_IDLE_LAT); + rtw_write32(rtwdev, REG_LTR_ACTIVE_LATENCY, WLAN_LTR_ACT_LAT); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC, WLAN_LTR_CTRL1); + rtw_write32(rtwdev, REG_LTR_CTRL_BASIC + 4, WLAN_LTR_CTRL2); + + rtw_phy_init(rtwdev); + + rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); + + rtw8723d_lck(rtwdev); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x20); + + rtw8723d_pwrtrack_init(rtwdev); +} + +static void rtw8723de_efuse_parsing(struct rtw_efuse *efuse, + struct rtw8723d_efuse *map) +{ + ether_addr_copy(efuse->addr, map->e.mac_addr); +} + +static int rtw8723d_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw8723d_efuse *map; + int i; + + map = (struct rtw8723d_efuse *)log_map; + + efuse->rfe_option = 0; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; + efuse->pa_type_2g = map->pa_type; + efuse->lna_type_2g = map->lna_type_2g[0]; + efuse->channel_plan = map->channel_plan; + efuse->country_code[0] = map->country_code[0]; + efuse->country_code[1] = map->country_code[1]; + efuse->bt_setting = map->rf_bt_setting; + efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[0] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; + efuse->afe = map->afe; + + for (i = 0; i < 4; i++) + efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; + + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + rtw8723de_efuse_parsing(efuse, map); + break; + default: + /* unsupported now */ + return -ENOTSUPP; + } + + return 0; +} + +static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 min_rx_power = -120; + u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); + + pkt_stat->rx_power[RF_PATH_A] = pwdb - 97; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = RTW_CHANNEL_WIDTH_20; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; +} + +static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 rxsc, bw; + s8 min_rx_power = -120; + s8 rx_evm; + + if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) + rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); + else + rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); + + if (GET_PHY_STAT_P1_RF_MODE(phy_status) == 0) + bw = RTW_CHANNEL_WIDTH_20; + else if ((rxsc == 1) || (rxsc == 2)) + bw = RTW_CHANNEL_WIDTH_20; + else + bw = RTW_CHANNEL_WIDTH_40; + + pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); + pkt_stat->bw = bw; + pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], + min_rx_power); + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + + dm_info->curr_rx_rate = pkt_stat->rate; + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; + dm_info->rx_snr[RF_PATH_A] = pkt_stat->rx_snr[RF_PATH_A] >> 1; + dm_info->cfo_tail[RF_PATH_A] = (pkt_stat->cfo_tail[RF_PATH_A] * 5) >> 1; + + rx_evm = clamp_t(s8, -pkt_stat->rx_evm[RF_PATH_A] >> 1, 0, 64); + rx_evm &= 0x3F; /* 64->0: second path of 1SS rate is 64 */ + dm_info->rx_evm_dbm[RF_PATH_A] = rx_evm; +} + +static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, + struct rtw_rx_pkt_stat *pkt_stat) +{ + u8 page; + + page = *phy_status & 0xf; + + switch (page) { + case 0: + query_phy_status_page0(rtwdev, phy_status, pkt_stat); + break; + case 1: + query_phy_status_page1(rtwdev, phy_status, pkt_stat); + break; + default: + rtw_warn(rtwdev, "unused phy status page (%d)\n", page); + return; + } +} + +static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_rx_status *rx_status) +{ + struct ieee80211_hdr *hdr; + u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; + u8 *phy_status = NULL; + + memset(pkt_stat, 0, sizeof(*pkt_stat)); + + pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); + pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); + pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; + pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); + pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); + pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); + pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); + pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); + pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); + pkt_stat->ppdu_cnt = 0; + pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); + + /* drv_info_sz is in unit of 8-bytes */ + pkt_stat->drv_info_sz *= 8; + + /* c2h cmd pkt's rx/phy status is not interested */ + if (pkt_stat->is_c2h) + return; + + hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + + pkt_stat->drv_info_sz); + if (pkt_stat->phy_status) { + phy_status = rx_desc + desc_sz + pkt_stat->shift; + query_phy_status(rtwdev, phy_status, pkt_stat); + } + + rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +} + +static +bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, u8 channel, u32 thres) +{ +#define DIS_3WIRE 0xccf000c0 +#define EN_3WIRE 0xccc000c0 +#define START_PSD 0x400000 +#define FREQ_CH13 0xFCCD +#define FREQ_CH14 0xFF9A + + u32 freq; + bool ret = false; + + if (channel == 13) + freq = FREQ_CH13; + else if (channel == 14) + freq = FREQ_CH14; + else + return false; + + rtw_write32(rtwdev, REG_ANALOG_P4, DIS_3WIRE); + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_PSDFN, START_PSD | freq); + + msleep(30); + if (rtw_read32(rtwdev, REG_PSDRPT) >= thres) + ret = true; + + rtw_write32(rtwdev, REG_PSDFN, freq); + rtw_write32(rtwdev, REG_ANALOG_P4, EN_3WIRE); + + return ret; +} + +static void rtw8723d_cfg_notch(struct rtw_dev *rtwdev, u8 channel, bool notch) +{ +#define BIT_MASK_RXDSP (BIT(28) | BIT(27) | BIT(26) | BIT(25) | BIT(24)) +#define BIT_EN_RXDSP BIT(9) +#define BIT_EN_CFOTRK BIT(28) + + if (!notch) + goto no_notch; + + switch (channel) { + case 13: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0xB); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x04000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + case 14: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x5); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x1); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00080000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x1); + break; + default: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); + break; + } + + return; + +no_notch: + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_MASK_RXDSP, 0x1f); + rtw_write32_mask(rtwdev, REG_OFDM0_RXDSP, BIT_EN_RXDSP, 0x0); + rtw_write32(rtwdev, REG_OFDM1_CSI1, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI2, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI3, 0x00000000); + rtw_write32(rtwdev, REG_OFDM1_CSI4, 0x00000000); + rtw_write32_mask(rtwdev, REG_OFDM1_CFOTRK, BIT_EN_CFOTRK, 0x0); +} + +static void rtw8723d_spur_cal(struct rtw_dev *rtwdev, u8 channel) +{ +#define SPUR_THRES 0x16 + bool notch = false; + + if (channel < 13) + goto do_notch; + + notch = rtw8723d_check_spur_ov_thres(rtwdev, channel, SPUR_THRES); + +do_notch: + rtw8723d_cfg_notch(rtwdev, channel, notch); +} + +static void rtw8723d_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) +{ +#define RFCFGCH_CHANNEL_MASK GENMASK(7, 0) +#define RFCFGCH_BW_MASK (BIT(11) | BIT(10)) +#define RFCFGCH_BW_20M (BIT(11) | BIT(10)) +#define RFCFGCH_BW_40M (BIT(10)) + + u32 rf_cfgch[2]; + + rf_cfgch[0] = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); + rf_cfgch[1] = rtw_read_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK); + + rf_cfgch[0] &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch[1] &= ~RFCFGCH_CHANNEL_MASK; + rf_cfgch[0] |= (channel & RFCFGCH_CHANNEL_MASK); + rf_cfgch[1] |= (channel & RFCFGCH_CHANNEL_MASK); + + rf_cfgch[0] &= ~RFCFGCH_BW_MASK; + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rf_cfgch[0] |= RFCFGCH_BW_20M; + break; + case RTW_CHANNEL_WIDTH_40: + rf_cfgch[0] |= RFCFGCH_BW_40M; + break; + default: + break; + } + + rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_cfgch[0]); + rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_cfgch[1]); + + rtw8723d_spur_cal(rtwdev, channel); +} + +#define CCK_DFIR_NR 3 +static const struct rtw_backup_info cck_dfir_cfg[][CCK_DFIR_NR] = { + [0] = { + { .len = 4, .reg = 0xA24, .val = 0x64B80C1C }, + { .len = 4, .reg = 0xA28, .val = 0x00008810 }, + { .len = 4, .reg = 0xAAC, .val = 0x01235667 }, + }, + [1] = { + { .len = 4, .reg = 0xA24, .val = 0x0000B81C }, + { .len = 4, .reg = 0xA28, .val = 0x00000000 }, + { .len = 4, .reg = 0xAAC, .val = 0x00003667 }, + }, +}; + +static void rtw8723d_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx) +{ +#define BIT_CCK_SIDE_BAND BIT(4) +#define BIT_MASK_RFMOD BIT(0) +#define BIT_RXBB_DFIR_EN BIT(19) +#define BIT_MASK_RXBB_DFIR (BIT(27) | BIT(26) | BIT(25) | BIT(24)) + + const struct rtw_backup_info *cck_dfir = + channel <= 13 ? cck_dfir_cfg[0] : cck_dfir_cfg[1]; + int i; + + for (i = 0; i < CCK_DFIR_NR; i++, cck_dfir++) + rtw_write32(rtwdev, cck_dfir->reg, cck_dfir->val); + + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x0); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 1); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_MASK_RXBB_DFIR, 0xa); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_FPGA0_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32_mask(rtwdev, REG_FPGA1_RFMOD, BIT_MASK_RFMOD, 0x1); + rtw_write32_mask(rtwdev, REG_BBRX_DFIR, BIT_RXBB_DFIR_EN, 0); + rtw_write32_mask(rtwdev, REG_CCK0_SYS, BIT_CCK_SIDE_BAND, + (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); + break; + default: + break; + } +} + +static void rtw8723d_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_chan_idx) +{ + rtw8723d_set_channel_rf(rtwdev, channel, bw); + rtw_set_channel_mac(rtwdev, channel, bw, primary_chan_idx); + rtw8723d_set_channel_bb(rtwdev, channel, bw, primary_chan_idx); +} + +#define BIT_CFENDFORM BIT(9) +#define BIT_WMAC_TCR_ERR0 BIT(12) +#define BIT_WMAC_TCR_ERR1 BIT(13) +#define BIT_TCR_CFG (BIT_CFENDFORM | BIT_WMAC_TCR_ERR0 | \ + BIT_WMAC_TCR_ERR1) +#define WLAN_RX_FILTER0 0xFFFF +#define WLAN_RX_FILTER1 0x400 +#define WLAN_RX_FILTER2 0xFFFF +#define WLAN_RCR_CFG 0x700060CE + +static int rtw8723d_mac_init(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, WLAN_TXQ_RPT_EN); + rtw_write32(rtwdev, REG_TCR, BIT_TCR_CFG); + + rtw_write16(rtwdev, REG_RXFLTMAP0, WLAN_RX_FILTER0); + rtw_write16(rtwdev, REG_RXFLTMAP1, WLAN_RX_FILTER1); + rtw_write16(rtwdev, REG_RXFLTMAP2, WLAN_RX_FILTER2); + rtw_write32(rtwdev, REG_RCR, WLAN_RCR_CFG); + + rtw_write32(rtwdev, REG_INT_MIG, 0); + rtw_write32(rtwdev, REG_MCUTST_1, 0x0); + + rtw_write8(rtwdev, REG_MISC_CTRL, BIT_DIS_SECOND_CCA); + rtw_write8(rtwdev, REG_2ND_CCA_CTRL, 0); + + return 0; +} + +static void rtw8723d_shutdown(struct rtw_dev *rtwdev) +{ + rtw_write16_set(rtwdev, REG_HCI_OPT_CTRL, BIT_USB_SUS_DIS); +} + +static void rtw8723d_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) +{ + u8 ldo_pwr; + + ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); + if (enable) { + ldo_pwr &= ~BIT_MASK_LDO25_VOLTAGE; + ldo_pwr = (BIT_LDO25_VOLTAGE_V25 << 4) | BIT_LDO25_EN; + } else { + ldo_pwr &= ~BIT_LDO25_EN; + } + rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); +} + +static void +rtw8723d_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_hw_reg *txagc; + u8 rate, pwr_index; + int j; + + for (j = 0; j < rtw_rate_size[rs]; j++) { + rate = rtw_rate_section[rs][j]; + pwr_index = hal->tx_pwr_tbl[path][rate]; + + if (rate >= ARRAY_SIZE(rtw8723d_txagc)) { + rtw_warn(rtwdev, "rate 0x%x isn't supported\n", rate); + continue; + } + txagc = &rtw8723d_txagc[rate]; + if (!txagc->addr) { + rtw_warn(rtwdev, "rate 0x%x isn't defined\n", rate); + continue; + } + + rtw_write32_mask(rtwdev, txagc->addr, txagc->mask, pwr_index); + } +} + +static void rtw8723d_set_tx_power_index(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + int rs, path; + + for (path = 0; path < hal->rf_path_num; path++) { + for (rs = 0; rs <= RTW_RATE_SECTION_HT_1S; rs++) + rtw8723d_set_tx_power_index_by_rate(rtwdev, path, rs); + } +} + +static void rtw8723d_efuse_grant(struct rtw_dev *rtwdev, bool on) +{ + if (on) { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); + + rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); + rtw_write16_set(rtwdev, REG_SYS_CLKR, BIT_LOADER_CLK_EN | BIT_ANA8M); + } else { + rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); + } +} + +static void rtw8723d_false_alarm_statistics(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 cck_fa_cnt; + u32 ofdm_fa_cnt; + u32 crc32_cnt; + u32 val32; + + /* hold counter */ + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 1); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KEEP, 1); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KEEP, 1); + + cck_fa_cnt = rtw_read32_mask(rtwdev, REG_CCK_FA_LSB_11N, MASKBYTE0); + cck_fa_cnt += rtw_read32_mask(rtwdev, REG_CCK_FA_MSB_11N, MASKBYTE3) << 8; + + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE1_11N); + ofdm_fa_cnt = u32_get_bits(val32, BIT_MASK_OFDM_FF_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_SF_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE2_11N); + dm_info->ofdm_cca_cnt = u32_get_bits(val32, BIT_MASK_OFDM_CCA_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_PF_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE3_11N); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_RI_CNT); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_CRC_CNT); + val32 = rtw_read32(rtwdev, REG_OFDM_FA_TYPE4_11N); + ofdm_fa_cnt += u32_get_bits(val32, BIT_MASK_OFDM_MNS_CNT); + + dm_info->cck_fa_cnt = cck_fa_cnt; + dm_info->ofdm_fa_cnt = ofdm_fa_cnt; + dm_info->total_fa_cnt = cck_fa_cnt + ofdm_fa_cnt; + + dm_info->cck_err_cnt = rtw_read32(rtwdev, REG_IGI_C_11N); + dm_info->cck_ok_cnt = rtw_read32(rtwdev, REG_IGI_D_11N); + crc32_cnt = rtw_read32(rtwdev, REG_OFDM_CRC32_CNT_11N); + dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_ERR); + dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_OFDM_LCRC_OK); + crc32_cnt = rtw_read32(rtwdev, REG_HT_CRC32_CNT_11N); + dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_ERR); + dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, BIT_MASK_HT_CRC_OK); + dm_info->vht_err_cnt = 0; + dm_info->vht_ok_cnt = 0; + + val32 = rtw_read32(rtwdev, REG_CCK_CCA_CNT_11N); + dm_info->cck_cca_cnt = (u32_get_bits(val32, BIT_MASK_CCK_FA_MSB) << 8) | + u32_get_bits(val32, BIT_MASK_CCK_FA_LSB); + dm_info->total_cca_cnt = dm_info->cck_cca_cnt + dm_info->ofdm_cca_cnt; + + /* reset counter */ + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTC_11N, BIT_MASK_OFDM_FA_RST, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 1); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_RST1, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_HOLDC_11N, BIT_MASK_OFDM_FA_KEEP, 0); + rtw_write32_mask(rtwdev, REG_OFDM_FA_RSTD_11N, BIT_MASK_OFDM_FA_KEEP1, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_CNT_KPEN, 2); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 0); + rtw_write32_mask(rtwdev, REG_CCK_FA_RST_11N, BIT_MASK_CCK_FA_KPEN, 2); + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 1); + rtw_write32_mask(rtwdev, REG_PAGE_F_RST_11N, BIT_MASK_F_RST_ALL, 0); +} + +#define MAX_TOLERANCE 5 +#define IQK_TX_X_ERR 0x142 +#define IQK_TX_Y_ERR 0x42 +#define IQK_RX_X_UPPER 0x11a +#define IQK_RX_X_LOWER 0xe6 +#define IQK_RX_Y_LMT 0x1a + +static const u32 iqk_adda_regs[] = { + 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, + 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec +}; + +static const u32 iqk_mac8_regs[] = {0x522, 0x550, 0x551}; +static const u32 iqk_mac32_regs[] = {0x40}; + +static const u32 iqk_bb_regs[] = { + 0xc04, 0xc08, 0x874, 0xb68, 0xb6c, 0x870, 0x860, 0x864, 0xa04 +}; + +#define IQK_ADDA_REG_NUM ARRAY_SIZE(iqk_adda_regs) +#define IQK_MAC8_REG_NUM ARRAY_SIZE(iqk_mac8_regs) +#define IQK_MAC32_REG_NUM ARRAY_SIZE(iqk_mac32_regs) +#define IQK_BB_REG_NUM ARRAY_SIZE(iqk_bb_regs) + +struct iqk_backup_regs { + u32 adda[IQK_ADDA_REG_NUM]; + u8 mac8[IQK_MAC8_REG_NUM]; + u32 mac32[IQK_MAC32_REG_NUM]; + u32 bb[IQK_BB_REG_NUM]; + + u32 lte_path; + u32 lte_gnt; + + u8 btg_sel; + u32 bb_sel_btg; + + u8 igia; + u8 igib; +}; + +static void rtw8723d_iqk_backup_regs(struct rtw_dev *rtwdev, + struct iqk_backup_regs *backup) +{ + int i; + + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + backup->adda[i] = rtw_read32(rtwdev, iqk_adda_regs[i]); + + for (i = 0; i < IQK_MAC8_REG_NUM; i++) + backup->mac8[i] = rtw_read8(rtwdev, iqk_mac8_regs[i]); + for (i = 0; i < IQK_MAC32_REG_NUM; i++) + backup->mac32[i] = rtw_read32(rtwdev, iqk_mac32_regs[i]); + + for (i = 0; i < IQK_BB_REG_NUM; i++) + backup->bb[i] = rtw_read32(rtwdev, iqk_bb_regs[i]); + + backup->igia = (u8)rtw_read32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0); + backup->igib = (u8)rtw_read32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0); + + backup->bb_sel_btg = rtw_read32(rtwdev, REG_BB_SEL_BTG); +} + +static void rtw8723d_iqk_restore_regs(struct rtw_dev *rtwdev, + const struct iqk_backup_regs *backup) +{ + int i; + + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + rtw_write32(rtwdev, iqk_adda_regs[i], backup->adda[i]); + + for (i = 0; i < IQK_MAC8_REG_NUM; i++) + rtw_write8(rtwdev, iqk_mac8_regs[i], backup->mac8[i]); + for (i = 0; i < IQK_MAC32_REG_NUM; i++) + rtw_write32(rtwdev, iqk_mac32_regs[i], backup->mac32[i]); + + for (i = 0; i < IQK_BB_REG_NUM; i++) + rtw_write32(rtwdev, iqk_bb_regs[i], backup->bb[i]); + + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XAAGC1, MASKBYTE0, backup->igia); + + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, 0x50); + rtw_write32_mask(rtwdev, REG_OFDM0_XBAGC1, MASKBYTE0, backup->igib); + + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x01008c00); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x01008c00); +} + +static void rtw8723d_iqk_backup_path_ctrl(struct rtw_dev *rtwdev, + struct iqk_backup_regs *backup) +{ + backup->btg_sel = rtw_read8(rtwdev, REG_BTG_SEL); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] original 0x67 = 0x%x\n", + backup->btg_sel); +} + +static void rtw8723d_iqk_config_path_ctrl(struct rtw_dev *rtwdev) +{ + rtw_write32_mask(rtwdev, REG_PAD_CTRL1, BIT_BT_BTG_SEL, 0x1); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] set 0x67 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +} + +static void rtw8723d_iqk_restore_path_ctrl(struct rtw_dev *rtwdev, + const struct iqk_backup_regs *backup) +{ + rtw_write8(rtwdev, REG_BTG_SEL, backup->btg_sel); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] restore 0x67 = 0x%x\n", + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); +} + +static void rtw8723d_iqk_backup_lte_path_gnt(struct rtw_dev *rtwdev, + struct iqk_backup_regs *backup) +{ + backup->lte_path = rtw_read32(rtwdev, REG_LTECOEX_PATH_CONTROL); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0038); + mdelay(1); + backup->lte_gnt = rtw_read32(rtwdev, REG_LTECOEX_READ_DATA); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] OriginalGNT = 0x%x\n", + backup->lte_gnt); +} + +static void rtw8723d_iqk_config_lte_path_gnt(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, 0x0000ff00); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc0020038); + rtw_write32_mask(rtwdev, REG_LTECOEX_PATH_CONTROL, BIT_LTE_MUX_CTRL_PATH, 0x1); +} + +static void rtw8723d_iqk_restore_lte_path_gnt(struct rtw_dev *rtwdev, + const struct iqk_backup_regs *bak) +{ + rtw_write32(rtwdev, REG_LTECOEX_WRITE_DATA, bak->lte_gnt); + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0xc00f0038); + rtw_write32(rtwdev, REG_LTECOEX_PATH_CONTROL, bak->lte_path); +} + +struct rtw_8723d_iqk_cfg { + const char *name; + u32 val_bb_sel_btg; + u32 reg_lutwe; + u32 val_txiqk_pi; + u32 reg_padlut; + u32 reg_gaintx; + u32 reg_bspad; + u32 val_wlint; + u32 val_wlsel; + u32 val_iqkpts; +}; + +static const struct rtw_8723d_iqk_cfg iqk_tx_cfg[PATH_NR] = { + [PATH_S1] = { + .name = "S1", + .val_bb_sel_btg = 0x99000000, + .reg_lutwe = RF_LUTWE, + .val_txiqk_pi = 0x8214019f, + .reg_padlut = RF_LUTDBG, + .reg_gaintx = RF_GAINTX, + .reg_bspad = RF_BSPAD, + .val_wlint = 0xe0d, + .val_wlsel = 0x60d, + .val_iqkpts = 0xfa000000, + }, + [PATH_S0] = { + .name = "S0", + .val_bb_sel_btg = 0x99000280, + .reg_lutwe = RF_LUTWE2, + .val_txiqk_pi = 0x8214018a, + .reg_padlut = RF_TXADBG, + .reg_gaintx = RF_TRXIQ, + .reg_bspad = RF_TXATANK, + .val_wlint = 0xe6d, + .val_wlsel = 0x66d, + .val_iqkpts = 0xf9000000, + }, +}; + +enum { + IQK_TX_OK = BIT(0), + IQK_RX_OK = BIT(1), +}; + +static u8 rtw8723d_iqk_check_tx_failed(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + s32 tx_x, tx_y; + u32 tx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe94 = 0x%x, 0xe9c = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_TX), + rtw_read32(rtwdev, REG_IQK_RES_TY)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xe90(before IQK)= 0x%x, 0xe98(afer IQK) = 0x%x\n", + rtw_read32(rtwdev, 0xe90), + rtw_read32(rtwdev, 0xe98)); + + tx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_TX_FAIL); + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + if (!tx_fail && tx_x != IQK_TX_X_ERR && tx_y != IQK_TX_Y_ERR) + return IQK_TX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s TXIQK is failed\n", + iqk_cfg->name); + + return 0; +} + +static u8 rtw8723d_iqk_check_rx_failed(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + s32 rx_x, rx_y; + u32 rx_fail; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xea4 = 0x%x, 0xeac = 0x%x\n", + rtw_read32(rtwdev, REG_IQK_RES_RX), + rtw_read32(rtwdev, REG_IQK_RES_RY)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] 0xea0(before IQK)= 0x%x, 0xea8(afer IQK) = 0x%x\n", + rtw_read32(rtwdev, 0xea0), + rtw_read32(rtwdev, 0xea8)); + + rx_fail = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_IQK_RX_FAIL); + rx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + rx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + rx_y = abs(iqkxy_to_s32(rx_y)); + + if (!rx_fail && rx_x < IQK_RX_X_UPPER && rx_x > IQK_RX_X_LOWER && + rx_y < IQK_RX_Y_LMT) + return IQK_RX_OK; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] %s RXIQK STEP2 is failed\n", + iqk_cfg->name); + + return 0; +} + +static void rtw8723d_iqk_one_shot(struct rtw_dev *rtwdev, bool tx, + const struct rtw_8723d_iqk_cfg *iqk_cfg) +{ + u32 pts = (tx ? iqk_cfg->val_iqkpts : 0xf9000000); + + /* enter IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + rtw8723d_iqk_config_lte_path_gnt(rtwdev); + + rtw_write32(rtwdev, REG_LTECOEX_CTRL, 0x800f0054); + mdelay(1); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] GNT_BT @%s %sIQK1 = 0x%x\n", + iqk_cfg->name, tx ? "TX" : "RX", + rtw_read32(rtwdev, REG_LTECOEX_READ_DATA)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x948 @%s %sIQK1 = 0x%x\n", + iqk_cfg->name, tx ? "TX" : "RX", + rtw_read32(rtwdev, REG_BB_SEL_BTG)); + + /* One shot, LOK & IQK */ + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, pts); + rtw_write32(rtwdev, REG_IQK_AGC_PTS_11N, 0xf8000000); + + if (!check_hw_ready(rtwdev, REG_IQK_RES_RY, BIT_IQK_DONE, 1)) + rtw_warn(rtwdev, "%s %s IQK isn't done\n", iqk_cfg->name, + tx ? "TX" : "RX"); +} + +static void rtw8723d_iqk_txrx_path_post(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct iqk_backup_regs *backup) +{ + rtw8723d_iqk_restore_lte_path_gnt(rtwdev, backup); + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup->bb_sel_btg); + + /* leave IQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, BIT(0), 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, BIT(0), 0x0); +} + +static u8 rtw8723d_iqk_tx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct iqk_backup_regs *backup) +{ + u8 result = 0x00; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s TXIQK!!\n", iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + + rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00004); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005d); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xBFFE0); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x08008c0c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, iqk_cfg->val_txiqk_pi); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160200); + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x00462911); + + /* PA, PAD setting */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x1E0, 0x3); + rtw_write_rf(rtwdev, RF_PATH_A, RF_RXIQGEN, 0x1F, 0xf); + + /* LOK setting for 8723D */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x10, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_bspad, 0x1, 0x1); + + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s TXIQK = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, true, iqk_cfg); + result |= rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); + + rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); + + return result; +} + +static u8 rtw8723d_iqk_rx_path(struct rtw_dev *rtwdev, + const struct rtw_8723d_iqk_cfg *iqk_cfg, + const struct iqk_backup_regs *backup) +{ + u32 tx_x, tx_y; + u8 result = 0x00; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK Step1!!\n", + iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + rtw_write32(rtwdev, REG_BB_SEL_BTG, iqk_cfg->val_bb_sel_btg); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + + /* IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + /* path IQK setting */ + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82160000); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28160000); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a911); + + /* RXIQK mode */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x80000); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00006); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xa7ffb); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + /* PA/PAD=0 */ + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_padlut, 0x800, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_gaintx, 0x600, 0x0); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK, iqk_cfg->val_wlint); + rtw_write_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK, iqk_cfg->val_wlsel); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1@ path %s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2@ path %s RXIQK1 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); + result |= rtw8723d_iqk_check_tx_failed(rtwdev, iqk_cfg); + + if (!result) + goto restore; + + tx_x = rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + tx_y = rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + + rtw_write32(rtwdev, REG_TXIQK_11N, BIT_SET_TXIQK_11N(tx_x, tx_y)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0xe40 = 0x%x u4tmp = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQK_11N), + BIT_SET_TXIQK_11N(tx_x, tx_y)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path %s RXIQK STEP2!!\n", + iqk_cfg->name); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] 0x67 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read32_mask(rtwdev, REG_PAD_CTRL1, MASKBYTE3)); + + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + rtw_write32(rtwdev, REG_TXIQK_TONE_A_11N, 0x38008c1c); + rtw_write32(rtwdev, REG_RXIQK_TONE_A_11N, 0x18008c1c); + rtw_write32(rtwdev, REG_TX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_RX_IQK_TONE_B, 0x38008c1c); + rtw_write32(rtwdev, REG_TXIQK_PI_A_11N, 0x82170000); + rtw_write32(rtwdev, REG_RXIQK_PI_A_11N, 0x28171400); + + /* LOK setting */ + rtw_write32(rtwdev, REG_IQK_AGC_RSP_11N, 0x0046a8d1); + + /* RXIQK mode */ + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, 0x80000, 0x1); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, RFREG_MASK, 0x00007); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD1, RFREG_MASK, 0x0005f); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, RFREG_MASK, 0xb3fdb); + rtw_write_rf(rtwdev, RF_PATH_A, iqk_cfg->reg_lutwe, RFREG_MASK, 0x00000); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x1 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLINT, RFREG_MASK)); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] RF0x2 @%s RXIQK2 = 0x%x\n", + iqk_cfg->name, + rtw_read_rf(rtwdev, RF_PATH_A, RF_WLSEL, RFREG_MASK)); + + rtw8723d_iqk_one_shot(rtwdev, false, iqk_cfg); + result |= rtw8723d_iqk_check_rx_failed(rtwdev, iqk_cfg); + +restore: + rtw8723d_iqk_txrx_path_post(rtwdev, iqk_cfg, backup); + + return result; +} + +static +void rtw8723d_iqk_fill_s1_matrix(struct rtw_dev *rtwdev, const s32 result[]) +{ + s32 oldval_1; + s32 x, y; + s32 tx1_a, tx1_a_ext; + s32 tx1_c, tx1_c_ext; + + if (result[IQK_S1_TX_X] == 0) + return; + + oldval_1 = rtw_read32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_D); + + x = iqkxy_to_s32(result[IQK_S1_TX_X]); + tx1_a = iqk_mult(x, oldval_1, &tx1_a_ext); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_A, tx1_a); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_A, tx1_a_ext); + + y = iqkxy_to_s32(result[IQK_S1_TX_Y]); + tx1_c = iqk_mult(y, oldval_1, &tx1_c_ext); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + BIT_SET_TXIQ_ELM_C1(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, + BIT_MASK_TXIQ_ELM_C, BIT_SET_TXIQ_ELM_C2(tx1_c)); + rtw_write32_mask(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, + BIT_MASK_OFDM0_EXT_C, tx1_c_ext); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] X = 0x%x, TX1_A = 0x%x, oldval_1 0x%x\n", + x, tx1_a, oldval_1); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Y = 0x%x, TX1_C = 0x%x\n", y, tx1_c); + + if (result[IQK_S1_RX_X] == 0) + return; + + rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_X, + result[IQK_S1_RX_X]); + rtw_write32_mask(rtwdev, REG_A_RXIQI, BIT_MASK_RXIQ_S1_Y1, + BIT_SET_RXIQ_S1_Y1(result[IQK_S1_RX_Y])); + rtw_write32_mask(rtwdev, REG_RXIQK_MATRIX_LSB_11N, BIT_MASK_RXIQ_S1_Y2, + BIT_SET_RXIQ_S1_Y2(result[IQK_S1_RX_Y])); +} + +static +void rtw8723d_iqk_fill_s0_matrix(struct rtw_dev *rtwdev, const s32 result[]) +{ + s32 oldval_0; + s32 x, y; + s32 tx0_a, tx0_a_ext; + s32 tx0_c, tx0_c_ext; + + if (result[IQK_S0_TX_X] == 0) + return; + + oldval_0 = rtw_read32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0); + + x = iqkxy_to_s32(result[IQK_S0_TX_X]); + tx0_a = iqk_mult(x, oldval_0, &tx0_a_ext); + + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, tx0_a); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, tx0_a_ext); + + y = iqkxy_to_s32(result[IQK_S0_TX_Y]); + tx0_c = iqk_mult(y, oldval_0, &tx0_c_ext); + + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, tx0_c); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, tx0_c_ext); + + if (result[IQK_S0_RX_X] == 0) + return; + + rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_X_S0, + result[IQK_S0_RX_X]); + rtw_write32_mask(rtwdev, REG_RXIQ_AB_S0, BIT_MASK_RXIQ_Y_S0, + result[IQK_S0_RX_Y]); +} + +static void rtw8723d_iqk_path_adda_on(struct rtw_dev *rtwdev) +{ + int i; + + for (i = 0; i < IQK_ADDA_REG_NUM; i++) + rtw_write32(rtwdev, iqk_adda_regs[i], 0x03c00016); +} + +static void rtw8723d_iqk_config_mac(struct rtw_dev *rtwdev) +{ + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); +} + +static +void rtw8723d_iqk_rf_standby(struct rtw_dev *rtwdev, enum rtw_rf_path path) +{ + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path-%s standby mode!\n", + path == RF_PATH_A ? "S1" : "S0"); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + rtw_write_rf(rtwdev, path, RF_MODE, RFREG_MASK, 0x10000); + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); +} + +static +bool rtw8723d_iqk_similarity_cmp(struct rtw_dev *rtwdev, s32 result[][IQK_NR], + u8 c1, u8 c2) +{ + u32 i, j, diff; + u32 bitmap = 0; + u8 candidate[PATH_NR] = {IQK_ROUND_INVALID, IQK_ROUND_INVALID}; + bool ret = true; + + s32 tmp1, tmp2; + + for (i = 0; i < IQK_NR; i++) { + tmp1 = iqkxy_to_s32(result[c1][i]); + tmp2 = iqkxy_to_s32(result[c2][i]); + + diff = abs(tmp1 - tmp2); + + if (diff <= MAX_TOLERANCE) + continue; + + if ((i == IQK_S1_RX_X || i == IQK_S0_RX_X) && !bitmap) { + if (result[c1][i] + result[c1][i + 1] == 0) + candidate[i / IQK_SX_NR] = c2; + else if (result[c2][i] + result[c2][i + 1] == 0) + candidate[i / IQK_SX_NR] = c1; + else + bitmap |= BIT(i); + } else { + bitmap |= BIT(i); + } + } + + if (bitmap != 0) + goto check_sim; + + for (i = 0; i < PATH_NR; i++) { + if (candidate[i] == IQK_ROUND_INVALID) + continue; + + for (j = i * IQK_SX_NR; j < i * IQK_SX_NR + 2; j++) + result[IQK_ROUND_HYBRID][j] = result[candidate[i]][j]; + ret = false; + } + + return ret; + +check_sim: + for (i = 0; i < IQK_NR; i++) { + j = i & ~1; /* 2 bits are a pair for IQ[X, Y] */ + if (bitmap & GENMASK(j + 1, j)) + continue; + + result[IQK_ROUND_HYBRID][i] = result[c1][i]; + } + + return false; +} + +static +void rtw8723d_iqk_precfg_path(struct rtw_dev *rtwdev, enum rtw8723d_path path) +{ + if (path == PATH_S0) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_A); + rtw8723d_iqk_path_adda_on(rtwdev); + } + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, EN_IQK); + rtw_write32(rtwdev, REG_TXIQK_11N, 0x01007c00); + rtw_write32(rtwdev, REG_RXIQK_11N, 0x01004800); + + if (path == PATH_S1) { + rtw8723d_iqk_rf_standby(rtwdev, RF_PATH_B); + rtw8723d_iqk_path_adda_on(rtwdev); + } +} + +#define PATH_IQK_RETRY 2 + +static +void rtw8723d_iqk_one_round(struct rtw_dev *rtwdev, s32 result[][IQK_NR], u8 t, + const struct iqk_backup_regs *backup) +{ + u32 i; + u8 s1_ok, s0_ok; + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] IQ Calibration for 1T1R_S0/S1 for %d times\n", t); + + rtw8723d_iqk_path_adda_on(rtwdev); + rtw8723d_iqk_config_mac(rtwdev); + rtw_write32_mask(rtwdev, REG_CCK_ANT_SEL_11N, 0x0f000000, 0xf); + rtw_write32(rtwdev, REG_BB_RX_PATH_11N, 0x03a05611); + rtw_write32(rtwdev, REG_TRMUX_11N, 0x000800e4); + rtw_write32(rtwdev, REG_BB_PWR_SAV1_11N, 0x25204200); + rtw8723d_iqk_precfg_path(rtwdev, PATH_S1); + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s1_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); + if (s1_ok == IQK_TX_OK) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S1 Tx IQK Success!!\n"); + result[t][IQK_S1_TX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + result[t][IQK_S1_TX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Tx IQK Fail!!\n"); + result[t][IQK_S1_TX_X] = 0x100; + result[t][IQK_S1_TX_Y] = 0x0; + } + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s1_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S1], backup); + if (s1_ok == (IQK_TX_OK | IQK_RX_OK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S1 Rx IQK Success!!\n"); + result[t][IQK_S1_RX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + result[t][IQK_S1_RX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 Rx IQK Fail!!\n"); + result[t][IQK_S1_RX_X] = 0x100; + result[t][IQK_S1_RX_Y] = 0x0; + } + + if (s1_ok == 0x0) + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S1 IQK is failed!!\n"); + + rtw8723d_iqk_precfg_path(rtwdev, PATH_S0); + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s0_ok = rtw8723d_iqk_tx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); + if (s0_ok == IQK_TX_OK) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S0 Tx IQK Success!!\n"); + result[t][IQK_S0_TX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TX, BIT_MASK_RES_TX); + result[t][IQK_S0_TX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_TY, BIT_MASK_RES_TY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Tx IQK Fail!!\n"); + result[t][IQK_S0_TX_X] = 0x100; + result[t][IQK_S0_TX_Y] = 0x0; + } + + for (i = 0; i < PATH_IQK_RETRY; i++) { + s0_ok = rtw8723d_iqk_rx_path(rtwdev, &iqk_tx_cfg[PATH_S0], backup); + if (s0_ok == (IQK_TX_OK | IQK_RX_OK)) { + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] path S0 Rx IQK Success!!\n"); + + result[t][IQK_S0_RX_X] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RX, BIT_MASK_RES_RX); + result[t][IQK_S0_RX_Y] = + rtw_read32_mask(rtwdev, REG_IQK_RES_RY, BIT_MASK_RES_RY); + break; + } + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 Rx IQK Fail!!\n"); + result[t][IQK_S0_RX_X] = 0x100; + result[t][IQK_S0_RX_Y] = 0x0; + } + + if (s0_ok == 0x0) + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] path S0 IQK is failed!!\n"); + + rtw_write32_mask(rtwdev, REG_FPGA0_IQK_11N, BIT_MASK_IQK_MOD, RST_IQK); + mdelay(1); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] back to BB mode, load original value!\n"); +} + +static void rtw8723d_phy_calibration(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 result[IQK_ROUND_SIZE][IQK_NR]; + struct iqk_backup_regs backup; + u8 i, j; + u8 final_candidate = IQK_ROUND_INVALID; + bool good; + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] Start!!!\n"); + + memset(result, 0, sizeof(result)); + + rtw8723d_iqk_backup_path_ctrl(rtwdev, &backup); + rtw8723d_iqk_backup_lte_path_gnt(rtwdev, &backup); + rtw8723d_iqk_backup_regs(rtwdev, &backup); + + for (i = IQK_ROUND_0; i <= IQK_ROUND_2; i++) { + rtw8723d_iqk_config_path_ctrl(rtwdev); + rtw8723d_iqk_config_lte_path_gnt(rtwdev); + + rtw8723d_iqk_one_round(rtwdev, result, i, &backup); + + if (i > IQK_ROUND_0) + rtw8723d_iqk_restore_regs(rtwdev, &backup); + rtw8723d_iqk_restore_lte_path_gnt(rtwdev, &backup); + rtw8723d_iqk_restore_path_ctrl(rtwdev, &backup); + + for (j = IQK_ROUND_0; j < i; j++) { + good = rtw8723d_iqk_similarity_cmp(rtwdev, result, j, i); + + if (good) { + final_candidate = j; + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] cmp %d:%d final_candidate is %x\n", + j, i, final_candidate); + goto iqk_done; + } + } + } + + if (final_candidate == IQK_ROUND_INVALID) { + s32 reg_tmp = 0; + + for (i = 0; i < IQK_NR; i++) + reg_tmp += result[IQK_ROUND_HYBRID][i]; + + if (reg_tmp != 0) { + final_candidate = IQK_ROUND_HYBRID; + } else { + WARN(1, "IQK is failed\n"); + goto out; + } + } + +iqk_done: + rtw8723d_iqk_fill_s1_matrix(rtwdev, result[final_candidate]); + rtw8723d_iqk_fill_s0_matrix(rtwdev, result[final_candidate]); + + dm_info->iqk.result.s1_x = result[final_candidate][IQK_S1_TX_X]; + dm_info->iqk.result.s1_y = result[final_candidate][IQK_S1_TX_Y]; + dm_info->iqk.result.s0_x = result[final_candidate][IQK_S0_TX_X]; + dm_info->iqk.result.s0_y = result[final_candidate][IQK_S0_TX_Y]; + dm_info->iqk.done = true; + +out: + rtw_write32(rtwdev, REG_BB_SEL_BTG, backup.bb_sel_btg); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] final_candidate is %x\n", + final_candidate); + + for (i = IQK_ROUND_0; i < IQK_ROUND_SIZE; i++) + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK] Result %u: rege94_s1=%x rege9c_s1=%x regea4_s1=%x regeac_s1=%x rege94_s0=%x rege9c_s0=%x regea4_s0=%x regeac_s0=%x %s\n", + i, + result[i][0], result[i][1], result[i][2], result[i][3], + result[i][4], result[i][5], result[i][6], result[i][7], + final_candidate == i ? "(final candidate)" : ""); + + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK]0xc80 = 0x%x 0xc94 = 0x%x 0xc14 = 0x%x 0xca0 = 0x%x\n", + rtw_read32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE), + rtw_read32(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N), + rtw_read32(rtwdev, REG_A_RXIQI), + rtw_read32(rtwdev, REG_RXIQK_MATRIX_LSB_11N)); + rtw_dbg(rtwdev, RTW_DBG_RFK, + "[IQK]0xcd0 = 0x%x 0xcd4 = 0x%x 0xcd8 = 0x%x\n", + rtw_read32(rtwdev, REG_TXIQ_AB_S0), + rtw_read32(rtwdev, REG_TXIQ_CD_S0), + rtw_read32(rtwdev, REG_RXIQ_AB_S0)); + + rtw_dbg(rtwdev, RTW_DBG_RFK, "[IQK] finished\n"); +} + +/* for coex */ +static void rtw8723d_coex_cfg_init(struct rtw_dev *rtwdev) +{ + /* enable TBTT nterrupt */ + rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION); + + /* BT report packet sample rate */ + /* 0x790[5:0]=0x5 */ + rtw_write8_set(rtwdev, REG_BT_TDMA_TIME, 0x05); + + /* enable BT counter statistics */ + rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x1); + + /* enable PTA (3-wire function form BT side) */ + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); + rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_AOD_GPIO3); + + /* enable PTA (tx/rx signal form WiFi side) */ + rtw_write8_set(rtwdev, REG_QUEUE_CTRL, BIT_PTA_WL_TX_EN); +} + +static void rtw8723d_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) +{ +} + +static void rtw8723d_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) +{ + rtw_write8_mask(rtwdev, REG_LEDCFG2, BIT(6), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(0), 0); + rtw_write8_mask(rtwdev, REG_GPIO_INTM + 2, BIT(4), 0); + rtw_write8_mask(rtwdev, REG_GPIO_MUXCFG + 2, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 3, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_PAD_CTRL1 + 2, BIT(7), 0); + rtw_write8_mask(rtwdev, REG_SYS_CLKR + 1, BIT(1), 0); + rtw_write8_mask(rtwdev, REG_SYS_SDIO_CTRL + 3, BIT(3), 0); +} + +static void rtw8723d_coex_cfg_rfe_type(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_rfe *coex_rfe = &coex->rfe; + bool aux = efuse->bt_setting & BIT(6); + + coex_rfe->rfe_module_type = rtwdev->efuse.rfe_option; + coex_rfe->ant_switch_polarity = 0; + coex_rfe->ant_switch_exist = false; + coex_rfe->ant_switch_with_bt = false; + coex_rfe->ant_switch_diversity = false; + coex_rfe->wlg_at_btg = true; + + /* decide antenna at main or aux */ + if (efuse->share_ant) { + if (aux) + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x80); + else + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x200); + } else { + if (aux) + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x280); + else + rtw_write16(rtwdev, REG_BB_SEL_BTG, 0x0); + } + + /* disable LTE coex in wifi side */ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, BIT_LTE_COEX_EN, 0x0); + rtw_coex_write_indirect_reg(rtwdev, LTE_WL_TRX_CTRL, MASKLWORD, 0xffff); + rtw_coex_write_indirect_reg(rtwdev, LTE_BT_TRX_CTRL, MASKLWORD, 0xffff); +} + +static void rtw8723d_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + static const u8 wl_tx_power[] = {0xb2, 0x90}; + u8 pwr; + + if (wl_pwr == coex_dm->cur_wl_pwr_lvl) + return; + + coex_dm->cur_wl_pwr_lvl = wl_pwr; + + if (coex_dm->cur_wl_pwr_lvl >= ARRAY_SIZE(wl_tx_power)) + coex_dm->cur_wl_pwr_lvl = ARRAY_SIZE(wl_tx_power) - 1; + + pwr = wl_tx_power[coex_dm->cur_wl_pwr_lvl]; + + rtw_write8(rtwdev, REG_ANA_PARAM1 + 3, pwr); +} + +static void rtw8723d_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) +{ + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_dm *coex_dm = &coex->dm; + /* WL Rx Low gain on */ + static const u32 wl_rx_low_gain_on[] = { + 0xec120101, 0xeb130101, 0xce140101, 0xcd150101, 0xcc160101, + 0xcb170101, 0xca180101, 0x8d190101, 0x8c1a0101, 0x8b1b0101, + 0x4f1c0101, 0x4e1d0101, 0x4d1e0101, 0x4c1f0101, 0x0e200101, + 0x0d210101, 0x0c220101, 0x0b230101, 0xcf240001, 0xce250001, + 0xcd260001, 0xcc270001, 0x8f280001 + }; + /* WL Rx Low gain off */ + static const u32 wl_rx_low_gain_off[] = { + 0xec120101, 0xeb130101, 0xea140101, 0xe9150101, 0xe8160101, + 0xe7170101, 0xe6180101, 0xe5190101, 0xe41a0101, 0xe31b0101, + 0xe21c0101, 0xe11d0101, 0xe01e0101, 0x861f0101, 0x85200101, + 0x84210101, 0x83220101, 0x82230101, 0x81240101, 0x80250101, + 0x44260101, 0x43270101, 0x42280101 + }; + u8 i; + + if (low_gain == coex_dm->cur_wl_rx_low_gain_en) + return; + + coex_dm->cur_wl_rx_low_gain_en = low_gain; + + if (coex_dm->cur_wl_rx_low_gain_en) { + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_on); i++) + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_on[i]); + } else { + for (i = 0; i < ARRAY_SIZE(wl_rx_low_gain_off); i++) + rtw_write32(rtwdev, REG_AGCRSSI, wl_rx_low_gain_off[i]); + } +} + +static u8 rtw8723d_pwrtrack_get_limit_ofdm(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 tx_rate = dm_info->tx_rate; + u8 limit_ofdm = 30; + + switch (tx_rate) { + case DESC_RATE1M...DESC_RATE5_5M: + case DESC_RATE11M: + break; + case DESC_RATE6M...DESC_RATE48M: + limit_ofdm = 36; + break; + case DESC_RATE54M: + limit_ofdm = 34; + break; + case DESC_RATEMCS0...DESC_RATEMCS2: + limit_ofdm = 38; + break; + case DESC_RATEMCS3...DESC_RATEMCS4: + limit_ofdm = 36; + break; + case DESC_RATEMCS5...DESC_RATEMCS7: + limit_ofdm = 34; + break; + default: + rtw_warn(rtwdev, "pwrtrack unhandled tx_rate 0x%x\n", tx_rate); + break; + } + + return limit_ofdm; +} + +static void rtw8723d_set_iqk_matrix_by_result(struct rtw_dev *rtwdev, + u32 ofdm_swing, u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 ele_A, ele_D, ele_C; + s32 ele_A_ext, ele_C_ext, ele_D_ext; + s32 iqk_result_x; + s32 iqk_result_y; + s32 value32; + + switch (rf_path) { + default: + case RF_PATH_A: + iqk_result_x = dm_info->iqk.result.s1_x; + iqk_result_y = dm_info->iqk.result.s1_y; + break; + case RF_PATH_B: + iqk_result_x = dm_info->iqk.result.s0_x; + iqk_result_y = dm_info->iqk.result.s0_y; + break; + } + + /* new element D */ + ele_D = OFDM_SWING_D(ofdm_swing); + iqk_mult(iqk_result_x, ele_D, &ele_D_ext); + /* new element A */ + iqk_result_x = iqkxy_to_s32(iqk_result_x); + ele_A = iqk_mult(iqk_result_x, ele_D, &ele_A_ext); + /* new element C */ + iqk_result_y = iqkxy_to_s32(iqk_result_y); + ele_C = iqk_mult(iqk_result_y, ele_D, &ele_C_ext); + + switch (rf_path) { + case RF_PATH_A: + default: + /* write new elements A, C, D, and element B is always 0 */ + value32 = BIT_SET_TXIQ_ELM_ACD(ele_A, ele_C, ele_D); + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, value32); + value32 = BIT_SET_TXIQ_ELM_C1(ele_C); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + value32); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + value32 |= BIT_SET_OFDM0_EXTS(ele_A_ext, ele_C_ext, ele_D_ext); + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + /* write new elements A, C, D, and element B is always 0 */ + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, ele_D); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, ele_C); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, ele_A); + + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, + ele_D_ext); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, + ele_A_ext); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, + ele_C_ext); + break; + } +} + +static void rtw8723d_set_iqk_matrix(struct rtw_dev *rtwdev, s8 ofdm_index, + u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s32 value32; + u32 ofdm_swing; + + if (ofdm_index >= RTW_OFDM_SWING_TABLE_SIZE) + ofdm_index = RTW_OFDM_SWING_TABLE_SIZE - 1; + else if (ofdm_index < 0) + ofdm_index = 0; + + ofdm_swing = rtw8723d_ofdm_swing_table[ofdm_index]; + + if (dm_info->iqk.done) { + rtw8723d_set_iqk_matrix_by_result(rtwdev, ofdm_swing, rf_path); + return; + } + + switch (rf_path) { + case RF_PATH_A: + default: + rtw_write32(rtwdev, REG_OFDM_0_XA_TX_IQ_IMBALANCE, ofdm_swing); + rtw_write32_mask(rtwdev, REG_TXIQK_MATRIXA_LSB2_11N, MASKH4BITS, + 0x00); + value32 = rtw_read32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD); + value32 &= ~BIT_MASK_OFDM0_EXTS; + rtw_write32(rtwdev, REG_OFDM_0_ECCA_THRESHOLD, value32); + break; + + case RF_PATH_B: + /* image S1:c80 to S0:Cd0 and Cd4 */ + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_S0, + OFDM_SWING_A(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_B_S0, + OFDM_SWING_B(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_S0, + OFDM_SWING_C(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_S0, + OFDM_SWING_D(ofdm_swing)); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_D_EXT_S0, 0x0); + rtw_write32_mask(rtwdev, REG_TXIQ_CD_S0, BIT_MASK_TXIQ_C_EXT_S0, 0x0); + rtw_write32_mask(rtwdev, REG_TXIQ_AB_S0, BIT_MASK_TXIQ_A_EXT_S0, 0x0); + break; + } +} + +static void rtw8723d_pwrtrack_set_ofdm_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_ofdm = txagc_idx; + + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); +} + +static void rtw8723d_pwrtrack_set_cck_pwr(struct rtw_dev *rtwdev, s8 swing_idx, + s8 txagc_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + dm_info->txagc_remnant_cck = txagc_idx; + + rtw_write32_mask(rtwdev, 0xab4, 0x000007FF, + rtw8723d_cck_swing_table[swing_idx]); +} + +static void rtw8723d_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_hal *hal = &rtwdev->hal; + u8 limit_ofdm; + u8 limit_cck = 40; + s8 final_ofdm_swing_index; + s8 final_cck_swing_index; + + limit_ofdm = rtw8723d_pwrtrack_get_limit_ofdm(rtwdev); + + final_ofdm_swing_index = RTW_DEF_OFDM_SWING_INDEX + + dm_info->delta_power_index[path]; + final_cck_swing_index = RTW_DEF_CCK_SWING_INDEX + + dm_info->delta_power_index[path]; + + if (final_ofdm_swing_index > limit_ofdm) + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, limit_ofdm, + final_ofdm_swing_index - limit_ofdm); + else if (final_ofdm_swing_index < 0) + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, 0, + final_ofdm_swing_index); + else + rtw8723d_pwrtrack_set_ofdm_pwr(rtwdev, final_ofdm_swing_index, 0); + + if (final_cck_swing_index > limit_cck) + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, limit_cck, + final_cck_swing_index - limit_cck); + else if (final_cck_swing_index < 0) + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, 0, + final_cck_swing_index); + else + rtw8723d_pwrtrack_set_cck_pwr(rtwdev, final_cck_swing_index, 0); + + rtw_phy_set_tx_power_level(rtwdev, hal->current_channel); +} + +static void rtw8723d_pwrtrack_set_xtal(struct rtw_dev *rtwdev, u8 therm_path, + u8 delta) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; + const s8 *pwrtrk_xtal; + s8 xtal_cap; + + if (dm_info->thermal_avg[therm_path] > + rtwdev->efuse.thermal_meter[therm_path]) + pwrtrk_xtal = tbl->pwrtrk_xtal_p; + else + pwrtrk_xtal = tbl->pwrtrk_xtal_n; + + xtal_cap = rtwdev->efuse.crystal_cap & 0x3F; + xtal_cap = clamp_t(s8, xtal_cap + pwrtrk_xtal[delta], 0, 0x3F); + rtw_write32_mask(rtwdev, REG_AFE_CTRL3, BIT_MASK_XTAL, + xtal_cap | (xtal_cap << 6)); +} + +static void rtw8723d_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, delta, path; + bool do_iqk = false; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[0] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + do_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); + + if (do_iqk) + rtw8723d_lck(rtwdev); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + delta = min_t(u8, delta, RTW_PWR_TRK_TBL_SZ - 1); + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) { + s8 delta_cur, delta_last; + + delta_last = dm_info->delta_power_index[path]; + delta_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, + path, RF_PATH_A, delta); + if (delta_last == delta_cur) + continue; + + dm_info->delta_power_index[path] = delta_cur; + rtw8723d_pwrtrack_set(rtwdev, path); + } + + rtw8723d_pwrtrack_set_xtal(rtwdev, RF_PATH_A, delta); + +iqk: + if (do_iqk) + rtw8723d_phy_calibration(rtwdev); +} + +void rtw8723d_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8723d_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723d_read_efuse, + .query_rx_desc = rtw8723d_query_rx_desc, + .set_channel = rtw8723d_set_channel, + .mac_init = rtw8723d_mac_init, + .shutdown = rtw8723d_shutdown, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8723d_set_tx_power_index, + .set_antenna = NULL, + .cfg_ldo25 = rtw8723d_cfg_ldo25, + .efuse_grant = rtw8723d_efuse_grant, + .false_alarm_statistics = rtw8723d_false_alarm_statistics, + .phy_calibration = rtw8723d_phy_calibration, + .pwr_track = rtw8723d_pwr_track, + .config_bfee = NULL, + .set_gid_table = NULL, + .cfg_csi_rate = NULL, + .adaptivity_init = NULL, + .adaptivity = NULL, + + .coex_set_init = rtw8723d_coex_cfg_init, + .coex_set_ant_switch = NULL, + .coex_set_gnt_fix = rtw8723d_coex_cfg_gnt_fix, + .coex_set_gnt_debug = rtw8723d_coex_cfg_gnt_debug, + .coex_set_rfe_type = rtw8723d_coex_cfg_rfe_type, + .coex_set_wl_tx_power = rtw8723d_coex_cfg_wl_tx_power, + .coex_set_wl_rx_gain = rtw8723d_coex_cfg_wl_rx_gain, +}; + +/* Shared-Antenna Coex Table */ +static const struct coex_table_para table_sant_8723d[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ + {0x55555555, 0x55555555}, + {0x65555555, 0x65555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-5 */ + {0xa5555555, 0xaaaa5aaa}, + {0x6a5a5a5a, 0x5a5a5a5a}, + {0x6a5a5a5a, 0x6a5a5a5a}, + {0x65555555, 0x5a5a5a5a}, + {0x65555555, 0x6a5a5a5a}, /* case-10 */ + {0x65555555, 0xfafafafa}, + {0x65555555, 0x6a5a5aaa}, + {0x65555555, 0x5aaa5aaa}, + {0x65555555, 0xaaaa5aaa}, + {0x65555555, 0xaaaaaaaa}, /* case-15 */ + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x6afa5afa}, + {0xaaffffaa, 0xfafafafa}, + {0xaa5555aa, 0x5a5a5a5a}, + {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ + {0xaa5555aa, 0xaaaaaaaa}, + {0xffffffff, 0x5a5a5a5a}, + {0xffffffff, 0x6a5a5a5a}, + {0xffffffff, 0x55555555}, + {0xffffffff, 0x6a5a5aaa}, /* case-25 */ + {0x55555555, 0x5a5a5a5a}, + {0x55555555, 0xaaaaaaaa}, + {0x55555555, 0x6a6a6a6a}, + {0x656a656a, 0x656a656a} +}; + +/* Non-Shared-Antenna Coex Table */ +static const struct coex_table_para table_nsant_8723d[] = { + {0xffffffff, 0xffffffff}, /* case-100 */ + {0x55555555, 0x55555555}, + {0x65555555, 0x65555555}, + {0xaaaaaaaa, 0xaaaaaaaa}, + {0x5a5a5a5a, 0x5a5a5a5a}, + {0xfafafafa, 0xfafafafa}, /* case-105 */ + {0x5afa5afa, 0x5afa5afa}, + {0x55555555, 0xfafafafa}, + {0x65555555, 0xfafafafa}, + {0x65555555, 0x5a5a5a5a}, + {0x65555555, 0x6a5a5a5a}, /* case-110 */ + {0x65555555, 0xaaaaaaaa}, + {0xffff55ff, 0xfafafafa}, + {0xffff55ff, 0x5afa5afa}, + {0xffff55ff, 0xaaaaaaaa}, + {0xaaffffaa, 0xfafafafa}, /* case-115 */ + {0xaaffffaa, 0x5afa5afa}, + {0xaaffffaa, 0xaaaaaaaa}, + {0xffffffff, 0xfafafafa}, + {0xffffffff, 0x5afa5afa}, + {0xffffffff, 0xaaaaaaaa},/* case-120 */ + {0x55ff55ff, 0x5afa5afa}, + {0x55ff55ff, 0xaaaaaaaa}, + {0x55ff55ff, 0x55ff55ff} +}; + +/* Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_sant_8723d[] = { + { {0x08, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-5 */ + { {0x61, 0x48, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ + { {0x61, 0x10, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x10, 0x03, 0x10, 0x54} }, + { {0x51, 0x10, 0x03, 0x10, 0x55} }, + { {0x51, 0x10, 0x07, 0x10, 0x54} }, /* case-15 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x15, 0x03, 0x10, 0x50} }, /* case-20 */ + { {0x51, 0x4a, 0x03, 0x10, 0x50} }, + { {0x51, 0x0c, 0x03, 0x10, 0x54} }, + { {0x55, 0x08, 0x03, 0x10, 0x54} }, + { {0x65, 0x10, 0x03, 0x11, 0x11} }, + { {0x51, 0x10, 0x03, 0x10, 0x51} }, + { {0x61, 0x15, 0x03, 0x11, 0x10} } +}; + +/* Non-Shared-Antenna TDMA */ +static const struct coex_tdma_para tdma_nsant_8723d[] = { + { {0x00, 0x00, 0x00, 0x40, 0x01} }, /* case-100 */ + { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-101 */ + { {0x61, 0x3a, 0x03, 0x11, 0x11} }, + { {0x61, 0x30, 0x03, 0x11, 0x11} }, + { {0x61, 0x20, 0x03, 0x11, 0x11} }, + { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ + { {0x61, 0x45, 0x03, 0x11, 0x10} }, + { {0x61, 0x3a, 0x03, 0x11, 0x10} }, + { {0x61, 0x30, 0x03, 0x11, 0x10} }, + { {0x61, 0x20, 0x03, 0x11, 0x10} }, + { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ + { {0x61, 0x08, 0x03, 0x11, 0x14} }, + { {0x61, 0x08, 0x03, 0x10, 0x14} }, + { {0x51, 0x08, 0x03, 0x10, 0x54} }, + { {0x51, 0x08, 0x03, 0x10, 0x55} }, + { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ + { {0x51, 0x45, 0x03, 0x10, 0x50} }, + { {0x51, 0x3a, 0x03, 0x10, 0x50} }, + { {0x51, 0x30, 0x03, 0x10, 0x50} }, + { {0x51, 0x20, 0x03, 0x10, 0x50} }, + { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-120 */ + { {0x51, 0x08, 0x03, 0x10, 0x50} }, +}; + +/* rssi in percentage % (dbm = % - 100) */ +static const u8 wl_rssi_step_8723d[] = {60, 50, 44, 30}; +static const u8 bt_rssi_step_8723d[] = {30, 30, 30, 30}; +static const struct coex_5g_afh_map afh_5g_8723d[] = { {0, 0, 0} }; + +static const struct rtw_hw_reg btg_reg_8723d = { + .addr = REG_BTG_SEL, .mask = BIT_MASK_BTG_WL, +}; + +/* wl_tx_dec_power, bt_tx_dec_power, wl_rx_gain, bt_rx_lna_constrain */ +static const struct coex_rf_para rf_para_tx_8723d[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 4}, + {1, 2, true, 4}, + {1, 10, true, 4}, + {1, 15, true, 4} +}; + +static const struct coex_rf_para rf_para_rx_8723d[] = { + {0, 0, false, 7}, /* for normal */ + {0, 10, false, 7}, /* for WL-CPT */ + {1, 0, true, 5}, + {1, 2, true, 5}, + {1, 10, true, 5}, + {1, 15, true, 5} +}; + +static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8723d[] = { + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), 0}, + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8723d[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0001, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3) | BIT(2)), 0}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, + {0x0075, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, (BIT(1) | BIT(0)), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(7), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(0), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0063, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0062, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0058, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x005A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0068, + RTW_PWR_CUT_TEST_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, + {0x0069, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0077, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x001f, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x07}, + {0x0077, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x07}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { + trans_carddis_to_cardemu_8723d, + trans_cardemu_to_act_8723d, + NULL +}; + +static struct rtw_pwr_seq_cmd trans_act_to_lps_8723d[] = { + {0x0301, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x0522, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, + {0x05F8, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05F9, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FA, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x05FB, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, 0xFF, 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0100, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x03}, + {0x0101, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x00}, + {0x0553, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_act_to_pre_carddis_8723d[] = { + {0x0003, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), 0}, + {0x0080, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8723d[] = { + {0x0002, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x0049, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), 0}, + {0x0006, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0x0010, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(6), 0}, + {0x0000, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8723d[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x20}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x0005, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_PCI_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3) | BIT(4)}, + {0x004A, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 1}, + {0x0023, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, + RTW_PWR_ADDR_SDIO, + RTW_PWR_CMD_POLLING, BIT(1), 0}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd trans_act_to_post_carddis_8723d[] = { + {0x001D, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), 0}, + {0x001D, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, + {0x001C, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, 0xFF, 0x0E}, + {0xFFFF, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + 0, + RTW_PWR_CMD_END, 0, 0}, +}; + +static struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { + trans_act_to_lps_8723d, + trans_act_to_pre_carddis_8723d, + trans_act_to_cardemu_8723d, + trans_cardemu_to_carddis_8723d, + trans_act_to_post_carddis_8723d, + NULL +}; + +static struct rtw_page_table page_table_8723d[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +}; + +static struct rtw_rqpn rqpn_table_8723d[] = { + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_HIGH, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, +}; + +static struct rtw_prioq_addrs prioq_addrs_8723d = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, + }, + .wsize = false, +}; + +static struct rtw_intf_phy_para pcie_gen1_param_8723d[] = { + {0x0008, 0x4a22, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, + {0x0009, 0x1000, + RTW_IP_SEL_PHY, + ~(RTW_INTF_PHY_CUT_A | RTW_INTF_PHY_CUT_B), + RTW_INTF_PHY_PLATFORM_ALL}, + {0xFFFF, 0x0000, + RTW_IP_SEL_PHY, + RTW_INTF_PHY_CUT_ALL, + RTW_INTF_PHY_PLATFORM_ALL}, +}; + +static struct rtw_intf_phy_para_table phy_para_table_8723d = { + .gen1_para = pcie_gen1_param_8723d, + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), +}; + +static struct rtw_hw_reg rtw8723d_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xc50, .mask = 0x7f }, +}; + +static struct rtw_hw_reg rtw8723d_dig_cck[] = { + [0] = { .addr = 0xa0c, .mask = 0x3f00 }, +}; + +static struct rtw_rf_sipi_addr rtw8723d_rf_sipi_addr[] = { + [RF_PATH_A] = { .hssi_1 = 0x820, .lssi_read = 0x8a0, + .hssi_2 = 0x824, .lssi_read_pi = 0x8b8}, + [RF_PATH_B] = { .hssi_1 = 0x828, .lssi_read = 0x8a4, + .hssi_2 = 0x82c, .lssi_read_pi = 0x8bc}, +}; + +static struct rtw_ltecoex_addr rtw8723d_ltecoex_addr = { + .ctrl = REG_LTECOEX_CTRL, + .wdata = REG_LTECOEX_WRITE_DATA, + .rdata = REG_LTECOEX_READ_DATA, +}; + +static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { + [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, + .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, +}; + +static const u8 rtw8723d_pwrtrk_2gb_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2gb_p[] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2ga_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2ga_p[] = { + 0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, + 7, 8, 8, 8, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_b_n[] = { + 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_b_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_a_n[] = { + 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 6, 7, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 +}; + +static const u8 rtw8723d_pwrtrk_2g_cck_a_p[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, + 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11 +}; + +static const s8 rtw8723d_pwrtrk_xtal_n[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const s8 rtw8723d_pwrtrk_xtal_p[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -10, -12, -14, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16 +}; + +static const struct rtw_pwr_track_tbl rtw8723d_rtw_pwr_track_tbl = { + .pwrtrk_2gb_n = rtw8723d_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8723d_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8723d_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8723d_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8723d_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8723d_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8723d_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8723d_pwrtrk_2g_cck_a_p, + .pwrtrk_xtal_p = rtw8723d_pwrtrk_xtal_p, + .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, +}; + +static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x964, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0x864, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0xab7, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0xa01, BIT(7), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, +}; + +struct rtw_chip_info rtw8723d_hw_spec = { + .ops = &rtw8723d_ops, + .id = RTW_CHIP_TYPE_8723D, + .fw_name = "rtw88/rtw8723d_fw.bin", + .wlan_cpu = RTW_WCPU_11N, + .tx_pkt_desc_sz = 40, + .tx_buf_desc_sz = 16, + .rx_pkt_desc_sz = 24, + .rx_buf_desc_sz = 8, + .phy_efuse_size = 512, + .log_efuse_size = 512, + .ptct_efuse_size = 96 + 1, + .txff_size = 32768, + .rxff_size = 16384, + .txgi_factor = 1, + .is_pwr_by_rate_dec = true, + .max_power_index = 0x3f, + .csi_buf_pg_num = 0, + .band = RTW_BAND_2G, + .page_size = 128, + .dig_min = 0x20, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, + .sys_func_en = 0xFD, + .pwr_on_seq = card_enable_flow_8723d, + .pwr_off_seq = card_disable_flow_8723d, + .page_table = page_table_8723d, + .rqpn_table = rqpn_table_8723d, + .prioq_addrs = &prioq_addrs_8723d, + .intf_table = &phy_para_table_8723d, + .dig = rtw8723d_dig, + .dig_cck = rtw8723d_dig_cck, + .rf_sipi_addr = {0x840, 0x844}, + .rf_sipi_read_addr = rtw8723d_rf_sipi_addr, + .fix_rf_phy_num = 2, + .ltecoex_addr = &rtw8723d_ltecoex_addr, + .mac_tbl = &rtw8723d_mac_tbl, + .agc_tbl = &rtw8723d_agc_tbl, + .bb_tbl = &rtw8723d_bb_tbl, + .rf_tbl = {&rtw8723d_rf_a_tbl}, + .rfe_defs = rtw8723d_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, + .iqk_threshold = 8, + + .coex_para_ver = 0x1905302f, + .bt_desired_ver = 0x2f, + .scbd_support = true, + .new_scbd10_def = true, + .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, + .bt_rssi_type = COEX_BTRSSI_RATIO, + .ant_isolation = 15, + .rssi_tolerance = 2, + .wl_rssi_step = wl_rssi_step_8723d, + .bt_rssi_step = bt_rssi_step_8723d, + .table_sant_num = ARRAY_SIZE(table_sant_8723d), + .table_sant = table_sant_8723d, + .table_nsant_num = ARRAY_SIZE(table_nsant_8723d), + .table_nsant = table_nsant_8723d, + .tdma_sant_num = ARRAY_SIZE(tdma_sant_8723d), + .tdma_sant = tdma_sant_8723d, + .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8723d), + .tdma_nsant = tdma_nsant_8723d, + .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8723d), + .wl_rf_para_tx = rf_para_tx_8723d, + .wl_rf_para_rx = rf_para_rx_8723d, + .bt_afh_span_bw20 = 0x20, + .bt_afh_span_bw40 = 0x30, + .afh_5g_num = ARRAY_SIZE(afh_5g_8723d), + .afh_5g = afh_5g_8723d, + .btg_reg = &btg_reg_8723d, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8723d), + .coex_info_hw_regs = coex_info_hw_regs_8723d, +}; +EXPORT_SYMBOL(rtw8723d_hw_spec); + +MODULE_FIRMWARE("rtw88/rtw8723d_fw.bin"); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8723d.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8723d.h @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8723D_H__ +#define __RTW8723D_H__ + +enum rtw8723d_path { + PATH_S1, + PATH_S0, + PATH_NR, +}; + +enum rtw8723d_iqk_round { + IQK_ROUND_0, + IQK_ROUND_1, + IQK_ROUND_2, + IQK_ROUND_HYBRID, + IQK_ROUND_SIZE, + IQK_ROUND_INVALID = 0xff, +}; + +enum rtw8723d_iqk_result { + IQK_S1_TX_X, + IQK_S1_TX_Y, + IQK_S1_RX_X, + IQK_S1_RX_Y, + IQK_S0_TX_X, + IQK_S0_TX_Y, + IQK_S0_RX_X, + IQK_S0_RX_Y, + IQK_NR, + IQK_SX_NR = IQK_NR / PATH_NR, +}; + +struct rtw8723de_efuse { + u8 mac_addr[ETH_ALEN]; /* 0xd0 */ + u8 vender_id[2]; + u8 device_id[2]; + u8 sub_vender_id[2]; + u8 sub_device_id[2]; +}; + +struct rtw8723d_efuse { + __le16 rtl_id; + u8 rsvd[2]; + u8 afe; + u8 rsvd1[11]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; + u8 thermal_meter; + u8 iqk_lck; + u8 pa_type; /* 0xbc */ + u8 lna_type_2g[2]; /* 0xbd */ + u8 lna_type_5g[2]; + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; + u8 eeprom_version; + u8 eeprom_customer_id; + u8 tx_bb_swing_setting_2g; + u8 res_c7; + u8 tx_pwr_calibrate_rate; + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; + u8 res[3]; + struct rtw8723de_efuse e; +}; + +/* phy status page0 */ +#define GET_PHY_STAT_P0_PWDB(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) + +/* phy status page1 */ +#define GET_PHY_STAT_P1_PWDB_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_PWDB_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x00), GENMASK(23, 16)) +#define GET_PHY_STAT_P1_RF_MODE(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x03), GENMASK(29, 28)) +#define GET_PHY_STAT_P1_L_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) +#define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) + +static inline s32 iqkxy_to_s32(s32 val) +{ + /* val is Q10.8 */ + return sign_extend32(val, 9); +} + +static inline s32 iqk_mult(s32 x, s32 y, s32 *ext) +{ + /* x, y and return value are Q10.8 */ + s32 t; + + t = x * y; + if (ext) + *ext = (t >> 7) & 0x1; /* Q.16 --> Q.9; get LSB of Q.9 */ + + return (t >> 8); /* Q.16 --> Q.8 */ +} + +#define REG_GPIO_INTM 0x0048 +#define REG_BTG_SEL 0x0067 +#define BIT_MASK_BTG_WL BIT(7) +#define REG_LTECOEX_PATH_CONTROL 0x0070 +#define REG_LTECOEX_CTRL 0x07c0 +#define REG_LTECOEX_WRITE_DATA 0x07c4 +#define REG_LTECOEX_READ_DATA 0x07c8 +#define REG_PSDFN 0x0808 +#define REG_BB_PWR_SAV1_11N 0x0874 +#define REG_ANA_PARAM1 0x0880 +#define REG_ANALOG_P4 0x088c +#define REG_PSDRPT 0x08b4 +#define REG_FPGA1_RFMOD 0x0900 +#define REG_BB_SEL_BTG 0x0948 +#define REG_BBRX_DFIR 0x0954 +#define REG_CCK0_SYS 0x0a00 +#define REG_CCK_ANT_SEL_11N 0x0a04 +#define REG_CCK_FA_RST_11N 0x0a2c +#define BIT_MASK_CCK_CNT_KEEP BIT(12) +#define BIT_MASK_CCK_CNT_EN BIT(13) +#define BIT_MASK_CCK_CNT_KPEN (BIT_MASK_CCK_CNT_KEEP | BIT_MASK_CCK_CNT_EN) +#define BIT_MASK_CCK_FA_KEEP BIT(14) +#define BIT_MASK_CCK_FA_EN BIT(15) +#define BIT_MASK_CCK_FA_KPEN (BIT_MASK_CCK_FA_KEEP | BIT_MASK_CCK_FA_EN) +#define REG_CCK_FA_LSB_11N 0x0a5c +#define REG_CCK_FA_MSB_11N 0x0a58 +#define REG_CCK_CCA_CNT_11N 0x0a60 +#define BIT_MASK_CCK_FA_MSB GENMASK(7, 0) +#define BIT_MASK_CCK_FA_LSB GENMASK(15, 8) +#define REG_OFDM_FA_HOLDC_11N 0x0c00 +#define BIT_MASK_OFDM_FA_KEEP BIT(31) +#define REG_BB_RX_PATH_11N 0x0c04 +#define REG_TRMUX_11N 0x0c08 +#define REG_OFDM_FA_RSTC_11N 0x0c0c +#define BIT_MASK_OFDM_FA_RST BIT(31) +#define REG_A_RXIQI 0x0c14 +#define BIT_MASK_RXIQ_S1_X 0x000003FF +#define BIT_MASK_RXIQ_S1_Y1 0x0000FC00 +#define BIT_SET_RXIQ_S1_Y1(y) ((y) & 0x3F) +#define REG_OFDM0_RXDSP 0x0c40 +#define REG_OFDM_0_ECCA_THRESHOLD 0x0c4c +#define BIT_MASK_OFDM0_EXT_A BIT(31) +#define BIT_MASK_OFDM0_EXT_C BIT(29) +#define BIT_MASK_OFDM0_EXTS (BIT(31) | BIT(29) | BIT(28)) +#define BIT_SET_OFDM0_EXTS(a, c, d) (((a) << 31) | ((c) << 29) | ((d) << 28)) +#define REG_OFDM0_XAAGC1 0x0c50 +#define REG_OFDM0_XBAGC1 0x0c58 +#define REG_AGCRSSI 0x0c78 +#define REG_OFDM_0_XA_TX_IQ_IMBALANCE 0x0c80 +#define BIT_MASK_TXIQ_ELM_A 0x03ff +#define BIT_SET_TXIQ_ELM_ACD(a, c, d) (((d) << 22) | (((c) & 0x3F) << 16) | \ + ((a) & 0x03ff)) +#define BIT_MASK_TXIQ_ELM_C GENMASK(21, 16) +#define BIT_SET_TXIQ_ELM_C2(c) ((c) & 0x3F) +#define BIT_MASK_TXIQ_ELM_D GENMASK(31, 22) +#define REG_TXIQK_MATRIXA_LSB2_11N 0x0c94 +#define BIT_SET_TXIQ_ELM_C1(c) (((c) & 0x000003C0) >> 6) +#define REG_RXIQK_MATRIX_LSB_11N 0x0ca0 +#define BIT_MASK_RXIQ_S1_Y2 0xF0000000 +#define BIT_SET_RXIQ_S1_Y2(y) (((y) >> 6) & 0xF) +#define REG_TXIQ_AB_S0 0x0cd0 +#define BIT_MASK_TXIQ_A_S0 0x000007FE +#define BIT_MASK_TXIQ_A_EXT_S0 BIT(0) +#define BIT_MASK_TXIQ_B_S0 0x0007E000 +#define REG_TXIQ_CD_S0 0x0cd4 +#define BIT_MASK_TXIQ_C_S0 0x000007FE +#define BIT_MASK_TXIQ_C_EXT_S0 BIT(0) +#define BIT_MASK_TXIQ_D_S0 GENMASK(22, 13) +#define BIT_MASK_TXIQ_D_EXT_S0 BIT(12) +#define REG_RXIQ_AB_S0 0x0cd8 +#define BIT_MASK_RXIQ_X_S0 0x000003FF +#define BIT_MASK_RXIQ_Y_S0 0x003FF000 +#define REG_OFDM_FA_TYPE1_11N 0x0cf0 +#define BIT_MASK_OFDM_FF_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_SF_CNT GENMASK(31, 16) +#define REG_OFDM_FA_RSTD_11N 0x0d00 +#define BIT_MASK_OFDM_FA_RST1 BIT(27) +#define BIT_MASK_OFDM_FA_KEEP1 BIT(31) +#define REG_CTX 0x0d03 +#define BIT_MASK_CTX_TYPE GENMASK(6, 4) +#define REG_OFDM1_CFOTRK 0x0d2c +#define REG_OFDM1_CSI1 0x0d40 +#define REG_OFDM1_CSI2 0x0d44 +#define REG_OFDM1_CSI3 0x0d48 +#define REG_OFDM1_CSI4 0x0d4c +#define REG_OFDM_FA_TYPE2_11N 0x0da0 +#define BIT_MASK_OFDM_CCA_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_PF_CNT GENMASK(31, 16) +#define REG_OFDM_FA_TYPE3_11N 0x0da4 +#define BIT_MASK_OFDM_RI_CNT GENMASK(15, 0) +#define BIT_MASK_OFDM_CRC_CNT GENMASK(31, 16) +#define REG_OFDM_FA_TYPE4_11N 0x0da8 +#define BIT_MASK_OFDM_MNS_CNT GENMASK(15, 0) +#define REG_FPGA0_IQK_11N 0x0e28 +#define BIT_MASK_IQK_MOD 0xffffff00 +#define EN_IQK 0x808000 +#define RST_IQK 0x000000 +#define REG_TXIQK_TONE_A_11N 0x0e30 +#define REG_RXIQK_TONE_A_11N 0x0e34 +#define REG_TXIQK_PI_A_11N 0x0e38 +#define REG_RXIQK_PI_A_11N 0x0e3c +#define REG_TXIQK_11N 0x0e40 +#define BIT_SET_TXIQK_11N(x, y) (0x80007C00 | ((x) << 16) | (y)) +#define REG_RXIQK_11N 0x0e44 +#define REG_IQK_AGC_PTS_11N 0x0e48 +#define REG_IQK_AGC_RSP_11N 0x0e4c +#define REG_TX_IQK_TONE_B 0x0e50 +#define REG_RX_IQK_TONE_B 0x0e54 +#define REG_IQK_RES_TX 0x0e94 +#define BIT_MASK_RES_TX GENMASK(25, 16) +#define REG_IQK_RES_TY 0x0e9c +#define BIT_MASK_RES_TY GENMASK(25, 16) +#define REG_IQK_RES_RX 0x0ea4 +#define BIT_MASK_RES_RX GENMASK(25, 16) +#define REG_IQK_RES_RY 0x0eac +#define BIT_IQK_TX_FAIL BIT(28) +#define BIT_IQK_RX_FAIL BIT(27) +#define BIT_IQK_DONE BIT(26) +#define BIT_MASK_RES_RY GENMASK(25, 16) +#define REG_PAGE_F_RST_11N 0x0f14 +#define BIT_MASK_F_RST_ALL BIT(16) +#define REG_IGI_C_11N 0x0f84 +#define REG_IGI_D_11N 0x0f88 +#define REG_HT_CRC32_CNT_11N 0x0f90 +#define BIT_MASK_HT_CRC_OK GENMASK(15, 0) +#define BIT_MASK_HT_CRC_ERR GENMASK(31, 16) +#define REG_OFDM_CRC32_CNT_11N 0x0f94 +#define BIT_MASK_OFDM_LCRC_OK GENMASK(15, 0) +#define BIT_MASK_OFDM_LCRC_ERR GENMASK(31, 16) +#define REG_HT_CRC32_CNT_11N_AGG 0x0fb8 + +#endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8723d_table.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8723d_table.c @@ -0,0 +1,1196 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "phy.h" +#include "rtw8723d_table.h" + +static const u32 rtw8723d_mac[] = { + 0x020, 0x00000013, + 0x02F, 0x00000010, + 0x077, 0x00000007, + 0x421, 0x0000000F, + 0x428, 0x0000000A, + 0x429, 0x00000010, + 0x430, 0x00000000, + 0x431, 0x00000000, + 0x432, 0x00000000, + 0x433, 0x00000001, + 0x434, 0x00000002, + 0x435, 0x00000003, + 0x436, 0x00000005, + 0x437, 0x00000007, + 0x438, 0x00000000, + 0x439, 0x00000000, + 0x43A, 0x00000000, + 0x43B, 0x00000001, + 0x43C, 0x00000002, + 0x43D, 0x00000003, + 0x43E, 0x00000005, + 0x43F, 0x00000007, + 0x440, 0x0000005D, + 0x441, 0x00000001, + 0x442, 0x00000000, + 0x444, 0x00000010, + 0x445, 0x00000000, + 0x446, 0x00000000, + 0x447, 0x00000000, + 0x448, 0x00000000, + 0x449, 0x000000F0, + 0x44A, 0x0000000F, + 0x44B, 0x0000003E, + 0x44C, 0x00000010, + 0x44D, 0x00000000, + 0x44E, 0x00000000, + 0x44F, 0x00000000, + 0x450, 0x00000000, + 0x451, 0x000000F0, + 0x452, 0x0000000F, + 0x453, 0x00000000, + 0x456, 0x0000005E, + 0x460, 0x00000066, + 0x461, 0x00000066, + 0x4C8, 0x000000FF, + 0x4C9, 0x00000008, + 0x4CC, 0x000000FF, + 0x4CD, 0x000000FF, + 0x4CE, 0x00000001, + 0x500, 0x00000026, + 0x501, 0x000000A2, + 0x502, 0x0000002F, + 0x503, 0x00000000, + 0x504, 0x00000028, + 0x505, 0x000000A3, + 0x506, 0x0000005E, + 0x507, 0x00000000, + 0x508, 0x0000002B, + 0x509, 0x000000A4, + 0x50A, 0x0000005E, + 0x50B, 0x00000000, + 0x50C, 0x0000004F, + 0x50D, 0x000000A4, + 0x50E, 0x00000000, + 0x50F, 0x00000000, + 0x512, 0x0000001C, + 0x514, 0x0000000A, + 0x516, 0x0000000A, + 0x525, 0x0000004F, + 0x550, 0x00000010, + 0x551, 0x00000010, + 0x559, 0x00000002, + 0x55C, 0x00000028, + 0x55D, 0x000000FF, + 0x605, 0x00000030, + 0x608, 0x0000000E, + 0x609, 0x0000002A, + 0x620, 0x000000FF, + 0x621, 0x000000FF, + 0x622, 0x000000FF, + 0x623, 0x000000FF, + 0x624, 0x000000FF, + 0x625, 0x000000FF, + 0x626, 0x000000FF, + 0x627, 0x000000FF, + 0x638, 0x00000028, + 0x63C, 0x0000000A, + 0x63D, 0x0000000A, + 0x63E, 0x0000000C, + 0x63F, 0x0000000C, + 0x640, 0x00000040, + 0x642, 0x00000040, + 0x643, 0x00000000, + 0x652, 0x000000C8, + 0x66A, 0x000000B0, + 0x66E, 0x00000005, + 0x700, 0x00000021, + 0x701, 0x00000043, + 0x702, 0x00000065, + 0x703, 0x00000087, + 0x708, 0x00000021, + 0x709, 0x00000043, + 0x70A, 0x00000065, + 0x70B, 0x00000087, + 0x765, 0x00000018, + 0x76E, 0x00000004, + 0x7C0, 0x00000038, + 0x7C2, 0x0000000F, + 0x7C3, 0x000000C0, + 0x073, 0x00000004, + 0x7C4, 0x00000077, + 0x07C, 0x00000003, + 0x016, 0x000000B3, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_mac, rtw_phy_cfg_mac); + +static const u32 rtw8723d_agc[] = { + 0xC78, 0xFE000101, + 0xC78, 0xFD010101, + 0xC78, 0xFC020101, + 0xC78, 0xFB030101, + 0xC78, 0xFA040101, + 0xC78, 0xF9050101, + 0xC78, 0xF8060101, + 0xC78, 0xF7070101, + 0xC78, 0xF6080101, + 0xC78, 0xF5090101, + 0xC78, 0xF40A0101, + 0xC78, 0xF30B0101, + 0xC78, 0xF20C0101, + 0xC78, 0xF10D0101, + 0xC78, 0xF00E0101, + 0xC78, 0xEF0F0101, + 0xC78, 0xEE100101, + 0xC78, 0xED110101, + 0xC78, 0xEC120101, + 0xC78, 0xEB130101, + 0xC78, 0xEA140101, + 0xC78, 0xE9150101, + 0xC78, 0xE8160101, + 0xC78, 0xE7170101, + 0xC78, 0xE6180101, + 0xC78, 0xE5190101, + 0xC78, 0xE41A0101, + 0xC78, 0xE31B0101, + 0xC78, 0xE21C0101, + 0xC78, 0xE11D0101, + 0xC78, 0xE01E0101, + 0xC78, 0x861F0101, + 0xC78, 0x85200101, + 0xC78, 0x84210101, + 0xC78, 0x83220101, + 0xC78, 0x82230101, + 0xC78, 0x81240101, + 0xC78, 0x80250101, + 0xC78, 0x44260101, + 0xC78, 0x43270101, + 0xC78, 0x42280101, + 0xC78, 0x41290101, + 0xC78, 0x402A0101, + 0xC78, 0x022B0101, + 0xC78, 0x012C0101, + 0xC78, 0x002D0101, + 0xC78, 0xC52E0001, + 0xC78, 0xC42F0001, + 0xC78, 0xC3300001, + 0xC78, 0xC2310001, + 0xC78, 0xC1320001, + 0xC78, 0xC0330001, + 0xC78, 0x04340001, + 0xC78, 0x03350001, + 0xC78, 0x02360001, + 0xC78, 0x01370001, + 0xC78, 0x00380001, + 0xC78, 0x00390001, + 0xC78, 0x003A0001, + 0xC78, 0x003B0001, + 0xC78, 0x003C0001, + 0xC78, 0x003D0001, + 0xC78, 0x003E0001, + 0xC78, 0x003F0001, + 0xC78, 0x6F002001, + 0xC78, 0x6F012001, + 0xC78, 0x6F022001, + 0xC78, 0x6F032001, + 0xC78, 0x6F042001, + 0xC78, 0x6F052001, + 0xC78, 0x6F062001, + 0xC78, 0x6F072001, + 0xC78, 0x6F082001, + 0xC78, 0x6F092001, + 0xC78, 0x6F0A2001, + 0xC78, 0x6F0B2001, + 0xC78, 0x6F0C2001, + 0xC78, 0x6F0D2001, + 0xC78, 0x6F0E2001, + 0xC78, 0x6F0F2001, + 0xC78, 0x6F102001, + 0xC78, 0x6F112001, + 0xC78, 0x6F122001, + 0xC78, 0x6F132001, + 0xC78, 0x6F142001, + 0xC78, 0x6F152001, + 0xC78, 0x6F162001, + 0xC78, 0x6F172001, + 0xC78, 0x6F182001, + 0xC78, 0x6F192001, + 0xC78, 0x6F1A2001, + 0xC78, 0x6F1B2001, + 0xC78, 0x6F1C2001, + 0xC78, 0x6F1D2001, + 0xC78, 0x6F1E2001, + 0xC78, 0x6F1F2001, + 0xC78, 0x6F202001, + 0xC78, 0x6F212001, + 0xC78, 0x6F222001, + 0xC78, 0x6F232001, + 0xC78, 0x6E242001, + 0xC78, 0x6D252001, + 0xC78, 0x6C262001, + 0xC78, 0x6B272001, + 0xC78, 0x6A282001, + 0xC78, 0x69292001, + 0xC78, 0x4B2A2001, + 0xC78, 0x4A2B2001, + 0xC78, 0x492C2001, + 0xC78, 0x482D2001, + 0xC78, 0x472E2001, + 0xC78, 0x462F2001, + 0xC78, 0x45302001, + 0xC78, 0x44312001, + 0xC78, 0x43322001, + 0xC78, 0x42332001, + 0xC78, 0x41342001, + 0xC78, 0x40352001, + 0xC78, 0x02362001, + 0xC78, 0x01372001, + 0xC78, 0x00382001, + 0xC78, 0x00392001, + 0xC78, 0x003A2001, + 0xC78, 0x003B2001, + 0xC78, 0x003C2001, + 0xC78, 0x003D2001, + 0xC78, 0x003E2001, + 0xC78, 0x003F2001, + 0xC78, 0x7F003101, + 0xC78, 0x7F013101, + 0xC78, 0x7F023101, + 0xC78, 0x7F033101, + 0xC78, 0x7F043101, + 0xC78, 0x7F053101, + 0xC78, 0x7F063101, + 0xC78, 0x7F073101, + 0xC78, 0x7E083101, + 0xC78, 0x7D093101, + 0xC78, 0x7C0A3101, + 0xC78, 0x7B0B3101, + 0xC78, 0x7A0C3101, + 0xC78, 0x790D3101, + 0xC78, 0x780E3101, + 0xC78, 0x770F3101, + 0xC78, 0x76103101, + 0xC78, 0x75113101, + 0xC78, 0x74123101, + 0xC78, 0x73133101, + 0xC78, 0x72143101, + 0xC78, 0x71153101, + 0xC78, 0x70163101, + 0xC78, 0x6F173101, + 0xC78, 0x6E183101, + 0xC78, 0x6D193101, + 0xC78, 0x6C1A3101, + 0xC78, 0x6B1B3101, + 0xC78, 0x6A1C3101, + 0xC78, 0x691D3101, + 0xC78, 0x681E3101, + 0xC78, 0x4B1F3101, + 0xC78, 0x4A203101, + 0xC78, 0x49213101, + 0xC78, 0x48223101, + 0xC78, 0x47233101, + 0xC78, 0x46243101, + 0xC78, 0x45253101, + 0xC78, 0x44263101, + 0xC78, 0x43273101, + 0xC78, 0x42283101, + 0xC78, 0x41293101, + 0xC78, 0x402A3101, + 0xC78, 0x022B3101, + 0xC78, 0x012C3101, + 0xC78, 0x002D3101, + 0xC78, 0x002E3101, + 0xC78, 0x002F3101, + 0xC78, 0x00303101, + 0xC78, 0x00313101, + 0xC78, 0x00323101, + 0xC78, 0x00333101, + 0xC78, 0x00343101, + 0xC78, 0x00353101, + 0xC78, 0x00363101, + 0xC78, 0x00373101, + 0xC78, 0x00383101, + 0xC78, 0x00393101, + 0xC78, 0x003A3101, + 0xC78, 0x003B3101, + 0xC78, 0x003C3101, + 0xC78, 0x003D3101, + 0xC78, 0x003E3101, + 0xC78, 0x003F3101, + 0xC78, 0xFE403101, + 0xC78, 0xFD413101, + 0xC78, 0xFC423101, + 0xC78, 0xFB433101, + 0xC78, 0xFA443101, + 0xC78, 0xF9453101, + 0xC78, 0xF8463101, + 0xC78, 0xF7473101, + 0xC78, 0xF6483101, + 0xC78, 0xF5493101, + 0xC78, 0xF44A3101, + 0xC78, 0xF34B3101, + 0xC78, 0xF24C3101, + 0xC78, 0xF14D3101, + 0xC78, 0xF04E3101, + 0xC78, 0xEF4F3101, + 0xC78, 0xEE503101, + 0xC78, 0xED513101, + 0xC78, 0xEC523101, + 0xC78, 0xEB533101, + 0xC78, 0xEA543101, + 0xC78, 0xE9553101, + 0xC78, 0xE8563101, + 0xC78, 0xE7573101, + 0xC78, 0xE6583101, + 0xC78, 0xE5593101, + 0xC78, 0xE45A3101, + 0xC78, 0xE35B3101, + 0xC78, 0xE25C3101, + 0xC78, 0xE15D3101, + 0xC78, 0xE05E3101, + 0xC78, 0x865F3101, + 0xC78, 0x85603101, + 0xC78, 0x84613101, + 0xC78, 0x83623101, + 0xC78, 0x82633101, + 0xC78, 0x81643101, + 0xC78, 0x80653101, + 0xC78, 0x80663101, + 0xC78, 0x80673101, + 0xC78, 0x80683101, + 0xC78, 0x80693101, + 0xC78, 0x806A3101, + 0xC78, 0x806B3101, + 0xC78, 0x806C3101, + 0xC78, 0x806D3101, + 0xC78, 0x806E3101, + 0xC78, 0x806F3101, + 0xC78, 0x80703101, + 0xC78, 0x80713101, + 0xC78, 0x80723101, + 0xC78, 0x80733101, + 0xC78, 0x80743101, + 0xC78, 0x80753101, + 0xC78, 0x80763101, + 0xC78, 0x80773101, + 0xC78, 0x80783101, + 0xC78, 0x80793101, + 0xC78, 0x807A3101, + 0xC78, 0x807B3101, + 0xC78, 0x807C3101, + 0xC78, 0x807D3101, + 0xC78, 0x807E3101, + 0xC78, 0x807F3101, + 0xC78, 0xEF402001, + 0xC78, 0xEF412001, + 0xC78, 0xEF422001, + 0xC78, 0xEF432001, + 0xC78, 0xEF442001, + 0xC78, 0xEF452001, + 0xC78, 0xEF462001, + 0xC78, 0xEF472001, + 0xC78, 0xEF482001, + 0xC78, 0xEF492001, + 0xC78, 0xEF4A2001, + 0xC78, 0xEF4B2001, + 0xC78, 0xEF4C2001, + 0xC78, 0xEF4D2001, + 0xC78, 0xEF4E2001, + 0xC78, 0xEF4F2001, + 0xC78, 0xEF502001, + 0xC78, 0xEF512001, + 0xC78, 0xEF522001, + 0xC78, 0xEF532001, + 0xC78, 0xEF542001, + 0xC78, 0xEF552001, + 0xC78, 0xEF562001, + 0xC78, 0xEF572001, + 0xC78, 0xEF582001, + 0xC78, 0xEF592001, + 0xC78, 0xEF5A2001, + 0xC78, 0xEF5B2001, + 0xC78, 0xEF5C2001, + 0xC78, 0xEF5D2001, + 0xC78, 0xEF5E2001, + 0xC78, 0xEF5F2001, + 0xC78, 0xEF602001, + 0xC78, 0xEE612001, + 0xC78, 0xED622001, + 0xC78, 0xEC632001, + 0xC78, 0xEB642001, + 0xC78, 0xEA652001, + 0xC78, 0xE9662001, + 0xC78, 0xE8672001, + 0xC78, 0xCB682001, + 0xC78, 0xCA692001, + 0xC78, 0xC96A2001, + 0xC78, 0xC86B2001, + 0xC78, 0xC76C2001, + 0xC78, 0xC66D2001, + 0xC78, 0xC56E2001, + 0xC78, 0xC46F2001, + 0xC78, 0xC3702001, + 0xC78, 0xC2712001, + 0xC78, 0xC1722001, + 0xC78, 0xC0732001, + 0xC78, 0x82742001, + 0xC78, 0x81752001, + 0xC78, 0x80762001, + 0xC78, 0x80772001, + 0xC78, 0x80782001, + 0xC78, 0x80792001, + 0xC78, 0x807A2001, + 0xC78, 0x807B2001, + 0xC78, 0x807C2001, + 0xC78, 0x807D2001, + 0xC78, 0x807E2001, + 0xC78, 0x807F2001, + 0xC78, 0xFA001101, + 0xC78, 0xF9011101, + 0xC78, 0xF8021101, + 0xC78, 0xF7031101, + 0xC78, 0xF6041101, + 0xC78, 0xF5051101, + 0xC78, 0xF4061101, + 0xC78, 0xD7071101, + 0xC78, 0xD6081101, + 0xC78, 0xD5091101, + 0xC78, 0xD40A1101, + 0xC78, 0x970B1101, + 0xC78, 0x960C1101, + 0xC78, 0x950D1101, + 0xC78, 0x940E1101, + 0xC78, 0x930F1101, + 0xC78, 0x92101101, + 0xC78, 0x91111101, + 0xC78, 0x90121101, + 0xC78, 0x8F131101, + 0xC78, 0x8E141101, + 0xC78, 0x8D151101, + 0xC78, 0x8C161101, + 0xC78, 0x8B171101, + 0xC78, 0x8A181101, + 0xC78, 0x89191101, + 0xC78, 0x881A1101, + 0xC78, 0x871B1101, + 0xC78, 0x861C1101, + 0xC78, 0x851D1101, + 0xC78, 0x841E1101, + 0xC78, 0x831F1101, + 0xC78, 0x82201101, + 0xC78, 0x81211101, + 0xC78, 0x80221101, + 0xC78, 0x43231101, + 0xC78, 0x42241101, + 0xC78, 0x41251101, + 0xC78, 0x04261101, + 0xC78, 0x03271101, + 0xC78, 0x02281101, + 0xC78, 0x01291101, + 0xC78, 0x002A1101, + 0xC78, 0xC42B1001, + 0xC78, 0xC32C1001, + 0xC78, 0xC22D1001, + 0xC78, 0xC12E1001, + 0xC78, 0xC02F1001, + 0xC78, 0x85301001, + 0xC78, 0x84311001, + 0xC78, 0x83321001, + 0xC78, 0x82331001, + 0xC78, 0x81341001, + 0xC78, 0x80351001, + 0xC78, 0x05361001, + 0xC78, 0x04371001, + 0xC78, 0x03381001, + 0xC78, 0x02391001, + 0xC78, 0x013A1001, + 0xC78, 0x003B1001, + 0xC78, 0x003C1001, + 0xC78, 0x003D1001, + 0xC78, 0x003E1001, + 0xC78, 0x003F1001, + 0xC50, 0x69553422, + 0xC50, 0x69553420, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_agc, rtw_phy_cfg_agc); + +static const u32 rtw8723d_bb[] = { + 0x800, 0x80046C00, + 0x804, 0x00000003, + 0x808, 0x0000FC00, + 0x80C, 0x0000000A, + 0x810, 0x10001331, + 0x814, 0x020C3D10, + 0x818, 0x00200385, + 0x81C, 0x00000000, + 0x820, 0x01000100, + 0x824, 0x00390204, + 0x828, 0x00000000, + 0x82C, 0x00000000, + 0x830, 0x00000000, + 0x834, 0x00000000, + 0x838, 0x00000000, + 0x83C, 0x00000000, + 0x840, 0x00010000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84C, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x569A11A9, + 0x85C, 0x01000014, + 0x860, 0x66F60110, + 0x864, 0x461F0641, + 0x868, 0x00000000, + 0x86C, 0x27272700, + 0x870, 0x07000460, + 0x874, 0x25004000, + 0x878, 0x00000808, + 0x87C, 0x004F0201, + 0x880, 0xB2002E12, + 0x884, 0x00000007, + 0x888, 0x00000000, + 0x88C, 0xCCC000C0, + 0x890, 0x00000800, + 0x894, 0xFFFFFFFE, + 0x898, 0x40302010, + 0x89C, 0x00706050, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90C, 0x81121111, + 0x910, 0x00000402, + 0x914, 0x00000300, + 0x920, 0x18C6318C, + 0x924, 0x0000018C, + 0x948, 0x99000000, + 0x94C, 0x00000010, + 0x950, 0x00003800, + 0x954, 0x5A380000, + 0x958, 0x4BC6D87A, + 0x95C, 0x04EB9B79, + 0x96C, 0x00000003, + 0x970, 0x00000000, + 0x974, 0x00000000, + 0x978, 0x00000000, + 0x97C, 0x13000000, + 0x980, 0x00000000, + 0xA00, 0x00D046C8, + 0xA04, 0x80FF800C, + 0xA08, 0x8C838300, + 0xA0C, 0x2E20100F, + 0xA10, 0x9500BB78, + 0xA14, 0x1114D028, + 0xA18, 0x00881117, + 0xA1C, 0x89140F00, + 0xA20, 0xE82C0001, + 0xA24, 0x64B80C1C, + 0xA28, 0x00008810, + 0xA2C, 0x00D30000, + 0xA70, 0x101FBF00, + 0xA74, 0x00000007, + 0xA78, 0x00008900, + 0xA7C, 0x225B0606, + 0xA80, 0x2180FA74, + 0xA84, 0x00200000, + 0xA88, 0x040C0000, + 0xA8C, 0x12345678, + 0xA90, 0xABCDEF00, + 0xA94, 0x001B1B89, + 0xA98, 0x00000000, + 0xA9C, 0x00020000, + 0xAA0, 0x00000000, + 0xAA4, 0x0000000C, + 0xAA8, 0xCA100008, + 0xAAC, 0x01235667, + 0xAB0, 0x00000000, + 0xAB4, 0x20201402, + 0xB2C, 0x00000000, + 0xC00, 0x48071D40, + 0xC04, 0x03A05611, + 0xC08, 0x000000E4, + 0xC0C, 0x6C6C6C6C, + 0xC10, 0x28800000, + 0xC14, 0x40000100, + 0xC18, 0x08800000, + 0xC1C, 0x40000100, + 0xC20, 0x00000000, + 0xC24, 0x00000000, + 0xC28, 0x00000000, + 0xC2C, 0x00000000, + 0xC30, 0x69E9AC48, + 0xC34, 0x31000040, + 0xC38, 0x21688080, + 0xC3C, 0x000016D4, + 0xC40, 0x1F78403F, + 0xC44, 0x00010036, + 0xC48, 0xEC020107, + 0xC4C, 0x007F037F, + 0xC50, 0x69553420, + 0xC54, 0x43BC0094, + 0xC58, 0x00015969, + 0xC5C, 0x00310492, + 0xC60, 0x00280A00, + 0xC64, 0x7112848B, + 0xC68, 0x47C074FF, + 0xC6C, 0x00000036, + 0xC70, 0x2C7F000D, + 0xC74, 0x020600DB, + 0xC78, 0x0000001F, + 0xC7C, 0x00B91612, + 0xC80, 0x390000E4, + 0xC84, 0x21F60000, + 0xC88, 0x40000100, + 0xC8C, 0x20200000, + 0xC90, 0x00091521, + 0xC94, 0x00000000, + 0xC98, 0x00121820, + 0xC9C, 0x00007F7F, + 0xCA0, 0x00012000, + 0xCA4, 0x800000A0, + 0xCA8, 0x84E6C606, + 0xCAC, 0x00000060, + 0xCB0, 0x00000000, + 0xCB4, 0x00000000, + 0xCB8, 0x00000000, + 0xCBC, 0x28000000, + 0xCC0, 0x0010A3D0, + 0xCC4, 0x00000F7D, + 0xCC8, 0x000442D6, + 0xCCC, 0x00000000, + 0xCD0, 0x000001C8, + 0xCD4, 0x001C8000, + 0xCD8, 0x00000100, + 0xCDC, 0x40100000, + 0xCE0, 0x00222220, + 0xCE4, 0x20000000, + 0xCE8, 0x37644302, + 0xCEC, 0x2F97D40C, + 0xD00, 0x00030740, + 0xD04, 0x40020401, + 0xD08, 0x0000907F, + 0xD0C, 0x20010201, + 0xD10, 0xA0633333, + 0xD14, 0x3333BC53, + 0xD18, 0x7A8F5B6F, + 0xD2C, 0xCC979975, + 0xD30, 0x00000000, + 0xD34, 0x40608000, + 0xD38, 0x88000000, + 0xD3C, 0xC0127343, + 0xD40, 0x00000000, + 0xD44, 0x00000000, + 0xD48, 0x00000000, + 0xD4C, 0x00000000, + 0xD50, 0x00000038, + 0xD54, 0x00000000, + 0xD58, 0x00000282, + 0xD5C, 0x30032064, + 0xD60, 0x4653DE68, + 0xD64, 0x04518A3C, + 0xD68, 0x00002101, + 0xE00, 0x2D2D2D2D, + 0xE04, 0x2D2D2D2D, + 0xE08, 0x0390272D, + 0xE10, 0x2D2D2D2D, + 0xE14, 0x2D2D2D2D, + 0xE18, 0x2D2D2D2D, + 0xE1C, 0x2D2D2D2D, + 0xE28, 0x00000000, + 0xE30, 0x1000DC1F, + 0xE34, 0x10008C1F, + 0xE38, 0x02140102, + 0xE3C, 0x681604C2, + 0xE40, 0x01007C00, + 0xE44, 0x01004800, + 0xE48, 0xFB000000, + 0xE4C, 0x000028D1, + 0xE50, 0x1000DC1F, + 0xE54, 0x10008C1F, + 0xE58, 0x02140102, + 0xE5C, 0x28160D05, + 0xE60, 0x00000008, + 0xE68, 0x001B25A4, + 0xE6C, 0x01C00014, + 0xE70, 0x01C00016, + 0xE74, 0x02000014, + 0xE78, 0x02000014, + 0xE7C, 0x02000014, + 0xE80, 0x02000014, + 0xE84, 0x01C00014, + 0xE88, 0x02000014, + 0xE8C, 0x01C00014, + 0xED0, 0x01C00014, + 0xED4, 0x01C00014, + 0xED8, 0x01C00014, + 0xEDC, 0x00000014, + 0xEE0, 0x00000014, + 0xEE8, 0x21555448, + 0xEEC, 0x03C00014, + 0xF14, 0x00000003, + 0xF00, 0x00100300, + 0xF08, 0x0000800B, + 0xF0C, 0x0000F007, + 0xF10, 0x0000A487, + 0xF1C, 0x80000064, + 0xF38, 0x00030155, + 0xF3C, 0x0000003A, + 0xF4C, 0x13000000, + 0xF50, 0x00000000, + 0xF18, 0x00000000, +}; + +RTW_DECL_TABLE_PHY_COND(rtw8723d_bb, rtw_phy_cfg_bb); + +static const struct rtw_phy_pg_cfg_pair rtw8723d_bb_pg[] = { + { 0, 0, 0, 0x00000e08, 0x0000ff00, 0x00003200, }, + { 0, 0, 0, 0x0000086c, 0xffffff00, 0x32323200, }, + { 0, 0, 0, 0x00000e00, 0xffffffff, 0x32343434, }, + { 0, 0, 0, 0x00000e04, 0xffffffff, 0x28303032, }, + { 0, 0, 0, 0x00000e10, 0xffffffff, 0x30323234, }, + { 0, 0, 0, 0x00000e14, 0xffffffff, 0x26282830, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8723d_bb_pg); + +static const u32 rtw8723d_rf_a[] = { + 0x050, 0x0001C000, + 0x049, 0x0004AA00, + 0x000, 0x00010000, + 0x0B1, 0x00054573, + 0x0B4, 0x000508AB, + 0x0B7, 0x00014787, + 0x0B8, 0x000064CB, + 0x01B, 0x00073A40, + 0x051, 0x00038CAF, + 0x052, 0x000FCCA3, + 0x053, 0x00090F38, + 0x054, 0x00011083, + 0x057, 0x000D0000, + 0x08D, 0x00000A1A, + 0x082, 0x00082AAC, + 0x08E, 0x00076940, + 0x08F, 0x00088400, + 0x061, 0x00038CAF, + 0x062, 0x000FCCA3, + 0x063, 0x00090F38, + 0x064, 0x00011083, + 0x067, 0x000D0000, + 0x092, 0x00082AAC, + 0x0EF, 0x00000400, + 0x030, 0x000008CA, + 0x030, 0x000018CA, + 0x030, 0x000028CA, + 0x030, 0x000038CA, + 0x0EF, 0x00000000, + 0x0EE, 0x00000400, + 0x030, 0x000008CA, + 0x030, 0x000018CA, + 0x030, 0x000028CA, + 0x030, 0x000038CA, + 0x0EE, 0x00000000, + 0x0EF, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x0000CCA3, + 0x033, 0x00000001, + 0x03F, 0x0000CCA3, + 0x033, 0x00000002, + 0x03F, 0x0000CCA3, + 0x033, 0x00000003, + 0x03F, 0x0000CCA3, + 0x033, 0x00000004, + 0x03F, 0x0000CCA3, + 0x033, 0x00000005, + 0x03F, 0x0000CCA3, + 0x033, 0x00000006, + 0x03F, 0x0000CCA3, + 0x033, 0x00000007, + 0x03F, 0x0000CCA3, + 0x0EF, 0x00000000, + 0x0EE, 0x00000100, + 0x033, 0x00000000, + 0x03F, 0x0000CCA3, + 0x033, 0x00000001, + 0x03F, 0x0000CCA3, + 0x033, 0x00000002, + 0x03F, 0x0000CCA3, + 0x033, 0x00000003, + 0x03F, 0x0000CCA3, + 0x033, 0x00000004, + 0x03F, 0x0000CCA3, + 0x033, 0x00000005, + 0x03F, 0x0000CCA3, + 0x033, 0x00000006, + 0x03F, 0x0000CCA3, + 0x033, 0x00000007, + 0x03F, 0x0000CCA3, + 0x0EE, 0x00000000, + 0x0EF, 0x00000800, + 0x030, 0x0000002D, + 0x030, 0x0000122C, + 0x030, 0x0000222F, + 0x030, 0x0000326C, + 0x030, 0x0000466B, + 0x030, 0x0000566E, + 0x030, 0x000066EB, + 0x030, 0x000077EC, + 0x030, 0x000087EF, + 0x030, 0x000097F2, + 0x030, 0x0000A7F5, + 0x0EF, 0x00000000, + 0x0EE, 0x00000800, + 0x030, 0x00000001, + 0x030, 0x00001011, + 0x030, 0x00002011, + 0x030, 0x00003013, + 0x030, 0x00004033, + 0x030, 0x00005033, + 0x030, 0x00006037, + 0x030, 0x0000703F, + 0x030, 0x0000803F, + 0x030, 0x0000903F, + 0x030, 0x0000A03F, + 0x0EE, 0x00000000, + 0x082, 0x00083B8C, + 0x0ED, 0x00000008, + 0x030, 0x000030F6, + 0x030, 0x00002004, + 0x030, 0x000010F6, + 0x030, 0x000000F6, + 0x0ED, 0x00000000, + 0x092, 0x00083B8C, + 0x0EC, 0x00000008, + 0x030, 0x000030F6, + 0x030, 0x00002004, + 0x030, 0x000010F6, + 0x030, 0x000000F6, + 0x0EC, 0x00000000, + 0x0EF, 0x00010000, + 0x030, 0x0001C11C, + 0x030, 0x000181F4, + 0x030, 0x00014108, + 0x030, 0x000101E4, + 0x030, 0x0000C11C, + 0x030, 0x000081F4, + 0x030, 0x00004108, + 0x030, 0x000001E4, + 0x0EF, 0x00000000, + 0x0EE, 0x00010000, + 0x030, 0x0001C11C, + 0x030, 0x000181F4, + 0x030, 0x00014108, + 0x030, 0x000101E4, + 0x030, 0x0000C11C, + 0x030, 0x000081F4, + 0x030, 0x00004108, + 0x030, 0x000001E4, + 0x0EE, 0x00000000, + 0x0EF, 0x00080000, + 0x033, 0x00000007, + 0x03E, 0x0000005F, + 0x03F, 0x000B3FDB, + 0x033, 0x00000004, + 0x03E, 0x0000005D, + 0x03F, 0x000BFFE0, + 0x033, 0x00000005, + 0x03E, 0x0000005D, + 0x03F, 0x000FBFCE, + 0x033, 0x00000006, + 0x03E, 0x0000005F, + 0x03F, 0x000A7FFB, + 0x0EF, 0x00000000, + 0x0EE, 0x00000002, + 0x030, 0x00000001, + 0x030, 0x00002001, + 0x030, 0x00004001, + 0x030, 0x00007001, + 0x030, 0x00006001, + 0x030, 0x00020001, + 0x030, 0x00022001, + 0x030, 0x00024001, + 0x030, 0x00027001, + 0x030, 0x00026001, + 0x030, 0x00034001, + 0x030, 0x00037001, + 0x030, 0x00036001, + 0x030, 0x00008000, + 0x030, 0x0000A000, + 0x030, 0x0000C000, + 0x83000100, 0x00000000, 0x40000000, 0x00000000, + 0x030, 0x0000E024, + 0xA0000000, 0x00000000, + 0x030, 0x0000E000, + 0xB0000000, 0x00000000, + 0x030, 0x0001C000, + 0x030, 0x0001E000, + 0x0EE, 0x00000000, + 0x0EE, 0x00020000, + 0x0EF, 0x00020000, + 0x030, 0x00000F75, + 0x030, 0x00002F55, + 0x030, 0x00003F75, + 0x0EE, 0x00000000, + 0x0EF, 0x00000000, + 0x018, 0x00008401, + 0xFFE, 0x00000000, +}; + +RTW_DECL_TABLE_RF_RADIO(rtw8723d_rf_a, A); + +static const struct rtw_txpwr_lmt_cfg_pair rtw8723d_txpwr_lmt[] = { + {0, 0, 0, 0, 1, 30, }, + {2, 0, 0, 0, 1, 30, }, + {1, 0, 0, 0, 1, 30, }, + {0, 0, 0, 0, 2, 30, }, + {2, 0, 0, 0, 2, 30, }, + {1, 0, 0, 0, 2, 30, }, + {0, 0, 0, 0, 3, 30, }, + {2, 0, 0, 0, 3, 30, }, + {1, 0, 0, 0, 3, 30, }, + {0, 0, 0, 0, 4, 30, }, + {2, 0, 0, 0, 4, 30, }, + {1, 0, 0, 0, 4, 30, }, + {0, 0, 0, 0, 5, 30, }, + {2, 0, 0, 0, 5, 30, }, + {1, 0, 0, 0, 5, 30, }, + {0, 0, 0, 0, 6, 30, }, + {2, 0, 0, 0, 6, 30, }, + {1, 0, 0, 0, 6, 30, }, + {0, 0, 0, 0, 7, 30, }, + {2, 0, 0, 0, 7, 30, }, + {1, 0, 0, 0, 7, 30, }, + {0, 0, 0, 0, 8, 30, }, + {2, 0, 0, 0, 8, 30, }, + {1, 0, 0, 0, 8, 30, }, + {0, 0, 0, 0, 9, 30, }, + {2, 0, 0, 0, 9, 30, }, + {1, 0, 0, 0, 9, 30, }, + {0, 0, 0, 0, 10, 30, }, + {2, 0, 0, 0, 10, 30, }, + {1, 0, 0, 0, 10, 30, }, + {0, 0, 0, 0, 11, 30, }, + {2, 0, 0, 0, 11, 30, }, + {1, 0, 0, 0, 11, 30, }, + {0, 0, 0, 0, 12, 30, }, + {2, 0, 0, 0, 12, 30, }, + {1, 0, 0, 0, 12, 30, }, + {0, 0, 0, 0, 13, 17, }, + {2, 0, 0, 0, 13, 30, }, + {1, 0, 0, 0, 13, 30, }, + {0, 0, 0, 0, 14, 63, }, + {2, 0, 0, 0, 14, 63, }, + {1, 0, 0, 0, 14, 30, }, + {0, 0, 0, 1, 1, 26, }, + {2, 0, 0, 1, 1, 31, }, + {1, 0, 0, 1, 1, 31, }, + {0, 0, 0, 1, 2, 28, }, + {2, 0, 0, 1, 2, 31, }, + {1, 0, 0, 1, 2, 31, }, + {0, 0, 0, 1, 3, 30, }, + {2, 0, 0, 1, 3, 31, }, + {1, 0, 0, 1, 3, 31, }, + {0, 0, 0, 1, 4, 30, }, + {2, 0, 0, 1, 4, 31, }, + {1, 0, 0, 1, 4, 31, }, + {0, 0, 0, 1, 5, 30, }, + {2, 0, 0, 1, 5, 31, }, + {1, 0, 0, 1, 5, 31, }, + {0, 0, 0, 1, 6, 30, }, + {2, 0, 0, 1, 6, 31, }, + {1, 0, 0, 1, 6, 31, }, + {0, 0, 0, 1, 7, 30, }, + {2, 0, 0, 1, 7, 31, }, + {1, 0, 0, 1, 7, 31, }, + {0, 0, 0, 1, 8, 30, }, + {2, 0, 0, 1, 8, 31, }, + {1, 0, 0, 1, 8, 31, }, + {0, 0, 0, 1, 9, 30, }, + {2, 0, 0, 1, 9, 31, }, + {1, 0, 0, 1, 9, 31, }, + {0, 0, 0, 1, 10, 28, }, + {2, 0, 0, 1, 10, 31, }, + {1, 0, 0, 1, 10, 31, }, + {0, 0, 0, 1, 11, 26, }, + {2, 0, 0, 1, 11, 31, }, + {1, 0, 0, 1, 11, 31, }, + {0, 0, 0, 1, 12, 24, }, + {2, 0, 0, 1, 12, 31, }, + {1, 0, 0, 1, 12, 31, }, + {0, 0, 0, 1, 13, 14, }, + {2, 0, 0, 1, 13, 31, }, + {1, 0, 0, 1, 13, 31, }, + {0, 0, 0, 1, 14, 63, }, + {2, 0, 0, 1, 14, 63, }, + {1, 0, 0, 1, 14, 63, }, + {0, 0, 0, 2, 1, 24, }, + {2, 0, 0, 2, 1, 31, }, + {1, 0, 0, 2, 1, 31, }, + {0, 0, 0, 2, 2, 26, }, + {2, 0, 0, 2, 2, 31, }, + {1, 0, 0, 2, 2, 31, }, + {0, 0, 0, 2, 3, 30, }, + {2, 0, 0, 2, 3, 31, }, + {1, 0, 0, 2, 3, 31, }, + {0, 0, 0, 2, 4, 30, }, + {2, 0, 0, 2, 4, 31, }, + {1, 0, 0, 2, 4, 31, }, + {0, 0, 0, 2, 5, 30, }, + {2, 0, 0, 2, 5, 31, }, + {1, 0, 0, 2, 5, 31, }, + {0, 0, 0, 2, 6, 30, }, + {2, 0, 0, 2, 6, 31, }, + {1, 0, 0, 2, 6, 31, }, + {0, 0, 0, 2, 7, 30, }, + {2, 0, 0, 2, 7, 31, }, + {1, 0, 0, 2, 7, 31, }, + {0, 0, 0, 2, 8, 30, }, + {2, 0, 0, 2, 8, 31, }, + {1, 0, 0, 2, 8, 31, }, + {0, 0, 0, 2, 9, 30, }, + {2, 0, 0, 2, 9, 31, }, + {1, 0, 0, 2, 9, 31, }, + {0, 0, 0, 2, 10, 26, }, + {2, 0, 0, 2, 10, 31, }, + {1, 0, 0, 2, 10, 31, }, + {0, 0, 0, 2, 11, 24, }, + {2, 0, 0, 2, 11, 31, }, + {1, 0, 0, 2, 11, 31, }, + {0, 0, 0, 2, 12, 23, }, + {2, 0, 0, 2, 12, 31, }, + {1, 0, 0, 2, 12, 31, }, + {0, 0, 0, 2, 13, 13, }, + {2, 0, 0, 2, 13, 31, }, + {1, 0, 0, 2, 13, 31, }, + {0, 0, 0, 2, 14, 63, }, + {2, 0, 0, 2, 14, 63, }, + {1, 0, 0, 2, 14, 63, }, + {0, 0, 0, 3, 1, 28, }, + {2, 0, 0, 3, 1, 30, }, + {1, 0, 0, 3, 1, 30, }, + {0, 0, 0, 3, 2, 28, }, + {2, 0, 0, 3, 2, 30, }, + {1, 0, 0, 3, 2, 30, }, + {0, 0, 0, 3, 3, 30, }, + {2, 0, 0, 3, 3, 30, }, + {1, 0, 0, 3, 3, 30, }, + {0, 0, 0, 3, 4, 30, }, + {2, 0, 0, 3, 4, 30, }, + {1, 0, 0, 3, 4, 30, }, + {0, 0, 0, 3, 5, 30, }, + {2, 0, 0, 3, 5, 30, }, + {1, 0, 0, 3, 5, 30, }, + {0, 0, 0, 3, 6, 30, }, + {2, 0, 0, 3, 6, 30, }, + {1, 0, 0, 3, 6, 30, }, + {0, 0, 0, 3, 7, 30, }, + {2, 0, 0, 3, 7, 30, }, + {1, 0, 0, 3, 7, 30, }, + {0, 0, 0, 3, 8, 30, }, + {2, 0, 0, 3, 8, 30, }, + {1, 0, 0, 3, 8, 30, }, + {0, 0, 0, 3, 9, 28, }, + {2, 0, 0, 3, 9, 30, }, + {1, 0, 0, 3, 9, 30, }, + {0, 0, 0, 3, 10, 28, }, + {2, 0, 0, 3, 10, 30, }, + {1, 0, 0, 3, 10, 30, }, + {0, 0, 0, 3, 11, 28, }, + {2, 0, 0, 3, 11, 30, }, + {1, 0, 0, 3, 11, 30, }, + {0, 0, 0, 3, 12, 63, }, + {2, 0, 0, 3, 12, 30, }, + {1, 0, 0, 3, 12, 30, }, + {0, 0, 0, 3, 13, 63, }, + {2, 0, 0, 3, 13, 30, }, + {1, 0, 0, 3, 13, 30, }, + {0, 0, 0, 3, 14, 63, }, + {2, 0, 0, 3, 14, 63, }, + {1, 0, 0, 3, 14, 63, }, + {0, 0, 1, 2, 1, 63, }, + {2, 0, 1, 2, 1, 63, }, + {1, 0, 1, 2, 1, 63, }, + {0, 0, 1, 2, 2, 63, }, + {2, 0, 1, 2, 2, 63, }, + {1, 0, 1, 2, 2, 63, }, + {0, 0, 1, 2, 3, 24, }, + {2, 0, 1, 2, 3, 30, }, + {1, 0, 1, 2, 3, 30, }, + {0, 0, 1, 2, 4, 24, }, + {2, 0, 1, 2, 4, 30, }, + {1, 0, 1, 2, 4, 30, }, + {0, 0, 1, 2, 5, 24, }, + {2, 0, 1, 2, 5, 30, }, + {1, 0, 1, 2, 5, 30, }, + {0, 0, 1, 2, 6, 24, }, + {2, 0, 1, 2, 6, 30, }, + {1, 0, 1, 2, 6, 30, }, + {0, 0, 1, 2, 7, 24, }, + {2, 0, 1, 2, 7, 30, }, + {1, 0, 1, 2, 7, 30, }, + {0, 0, 1, 2, 8, 24, }, + {2, 0, 1, 2, 8, 30, }, + {1, 0, 1, 2, 8, 30, }, + {0, 0, 1, 2, 9, 24, }, + {2, 0, 1, 2, 9, 30, }, + {1, 0, 1, 2, 9, 30, }, + {0, 0, 1, 2, 10, 22, }, + {2, 0, 1, 2, 10, 30, }, + {1, 0, 1, 2, 10, 30, }, + {0, 0, 1, 2, 11, 20, }, + {2, 0, 1, 2, 11, 30, }, + {1, 0, 1, 2, 11, 30, }, + {0, 0, 1, 2, 12, 63, }, + {2, 0, 1, 2, 12, 30, }, + {1, 0, 1, 2, 12, 30, }, + {0, 0, 1, 2, 13, 63, }, + {2, 0, 1, 2, 13, 30, }, + {1, 0, 1, 2, 13, 30, }, + {0, 0, 1, 2, 14, 63, }, + {2, 0, 1, 2, 14, 63, }, + {1, 0, 1, 2, 14, 63, }, + {0, 0, 1, 3, 1, 63, }, + {2, 0, 1, 3, 1, 63, }, + {1, 0, 1, 3, 1, 63, }, + {0, 0, 1, 3, 2, 63, }, + {2, 0, 1, 3, 2, 63, }, + {1, 0, 1, 3, 2, 63, }, + {0, 0, 1, 3, 3, 26, }, + {2, 0, 1, 3, 3, 26, }, + {1, 0, 1, 3, 3, 26, }, + {0, 0, 1, 3, 4, 26, }, + {2, 0, 1, 3, 4, 26, }, + {1, 0, 1, 3, 4, 26, }, + {0, 0, 1, 3, 5, 26, }, + {2, 0, 1, 3, 5, 26, }, + {1, 0, 1, 3, 5, 26, }, + {0, 0, 1, 3, 6, 26, }, + {2, 0, 1, 3, 6, 26, }, + {1, 0, 1, 3, 6, 26, }, + {0, 0, 1, 3, 7, 26, }, + {2, 0, 1, 3, 7, 26, }, + {1, 0, 1, 3, 7, 26, }, + {0, 0, 1, 3, 8, 26, }, + {2, 0, 1, 3, 8, 26, }, + {1, 0, 1, 3, 8, 26, }, + {0, 0, 1, 3, 9, 26, }, + {2, 0, 1, 3, 9, 26, }, + {1, 0, 1, 3, 9, 26, }, + {0, 0, 1, 3, 10, 26, }, + {2, 0, 1, 3, 10, 26, }, + {1, 0, 1, 3, 10, 26, }, + {0, 0, 1, 3, 11, 26, }, + {2, 0, 1, 3, 11, 26, }, + {1, 0, 1, 3, 11, 26, }, + {0, 0, 1, 3, 12, 63, }, + {2, 0, 1, 3, 12, 26, }, + {1, 0, 1, 3, 12, 26, }, + {0, 0, 1, 3, 13, 63, }, + {2, 0, 1, 3, 13, 26, }, + {1, 0, 1, 3, 13, 26, }, + {0, 0, 1, 3, 14, 63, }, + {2, 0, 1, 3, 14, 63, }, + {1, 0, 1, 3, 14, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8723d_txpwr_lmt); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8723d_table.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8723d_table.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW8723D_TABLE_H__ +#define __RTW8723D_TABLE_H__ + +extern const struct rtw_table rtw8723d_mac_tbl; +extern const struct rtw_table rtw8723d_agc_tbl; +extern const struct rtw_table rtw8723d_bb_tbl; +extern const struct rtw_table rtw8723d_bb_pg_tbl; +extern const struct rtw_table rtw8723d_rf_a_tbl; +extern const struct rtw_table rtw8723d_txpwr_lmt_tbl; + +#endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822b.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822b.c @@ -13,6 +13,7 @@ #include "mac.h" #include "reg.h" #include "debug.h" +#include "bf.h" static void rtw8822b_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, u8 rx_path, bool is_tx2_path); @@ -43,6 +44,8 @@ efuse->country_code[1] = map->country_code[1]; efuse->bt_setting = map->rf_bt_setting; efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->thermal_meter; + efuse->thermal_meter_k = map->thermal_meter; for (i = 0; i < 4; i++) efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; @@ -75,6 +78,56 @@ rtw_write32_mask(rtwdev, 0x974, (BIT(11) | BIT(10)), 0x3); } +#define RTW_TXSCALE_SIZE 37 +static const u32 rtw8822b_txscale_tbl[RTW_TXSCALE_SIZE] = { + 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, + 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, + 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, + 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe +}; + +static const u8 rtw8822b_get_swing_index(struct rtw_dev *rtwdev) +{ + u8 i = 0; + u32 swing, table_value; + + swing = rtw_read32_mask(rtwdev, 0xc1c, 0xffe00000); + for (i = 0; i < RTW_TXSCALE_SIZE; i++) { + table_value = rtw8822b_txscale_tbl[i]; + if (swing == table_value) + break; + } + + return i; +} + +static void rtw8822b_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 swing_idx = rtw8822b_get_swing_index(rtwdev); + u8 path; + + if (swing_idx >= RTW_TXSCALE_SIZE) + dm_info->default_ofdm_index = 24; + else + dm_info->default_ofdm_index = swing_idx; + + for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->delta_power_index[path] = 0; + } + dm_info->pwr_trk_triggered = false; + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + +static void rtw8822b_phy_bf_init(struct rtw_dev *rtwdev) +{ + rtw_bf_phy_init(rtwdev); + /* Grouping bitmap parameters */ + rtw_write32(rtwdev, 0x1C94, 0xAFFFAFFF); +} + static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) { struct rtw_hal *hal = &rtwdev->hal; @@ -106,6 +159,9 @@ rtw_phy_init(rtwdev); rtw8822b_phy_rfe_init(rtwdev); + rtw8822b_pwrtrack_init(rtwdev); + + rtw8822b_phy_bf_init(rtwdev); } #define WLAN_SLOT_TIME 0x09 @@ -211,9 +267,8 @@ static void rtw8822b_set_channel_rfe_efem(struct rtw_dev *rtwdev, u8 channel) { struct rtw_hal *hal = &rtwdev->hal; - bool is_channel_2g = (channel <= 14) ? true : false; - if (is_channel_2g) { + if (IS_CH_2G_BAND(channel)) { rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x705770); rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57); rtw_write32s_mask(rtwdev, REG_RFECTL, BIT(4), 0); @@ -241,9 +296,8 @@ static void rtw8822b_set_channel_rfe_ifem(struct rtw_dev *rtwdev, u8 channel) { struct rtw_hal *hal = &rtwdev->hal; - bool is_channel_2g = (channel <= 14) ? true : false; - if (is_channel_2g) { + if (IS_CH_2G_BAND(channel)) { /* signal source */ rtw_write32s_mask(rtwdev, REG_RFESEL0, 0xffffff, 0x745774); rtw_write32s_mask(rtwdev, REG_RFESEL8, MASKBYTE1, 0x57); @@ -255,7 +309,7 @@ rtw_write32s_mask(rtwdev, REG_RFEINV, BIT(11) | BIT(10) | 0x3f, 0x0); - if (is_channel_2g) { + if (IS_CH_2G_BAND(channel)) { if (hal->antenna_rx == BB_PATH_AB || hal->antenna_tx == BB_PATH_AB) { /* 2TX or 2RX */ @@ -337,6 +391,7 @@ static const struct rtw8822b_rfe_info rtw8822b_rfe_info[] = { [2] = I2GE5G_CCUT(efem), + [3] = IFEM_EXT_CCUT(ifem), [5] = IFEM_EXT_CCUT(ifem), }; @@ -350,7 +405,7 @@ u32 reg82c, reg830, reg838; bool is_efem_cca = false, is_ifem_cca = false, is_rfe_type = false; - if (channel <= 14) { + if (IS_CH_2G_BAND(channel)) { cca_ccut = rfe_info->cca_ccut_2g; if (hal->antenna_rx == BB_PATH_A || @@ -381,7 +436,7 @@ is_efem_cca = true; break; case RTW_RFE_IFEM2G_EFEM5G: - if (channel <= 14) + if (IS_CH_2G_BAND(channel)) is_ifem_cca = true; else is_efem_cca = true; @@ -405,9 +460,7 @@ if (is_efem_cca && !(hal->cut_version == RTW_CHIP_VER_CUT_B)) rtw_write32_mask(rtwdev, REG_L1WT, MASKDWORD, 0x9194b2b9); - if (bw == RTW_CHANNEL_WIDTH_20 && - ((channel >= 52 && channel <= 64) || - (channel >= 100 && channel <= 144))) + if (bw == RTW_CHANNEL_WIDTH_20 && IS_CH_5G_BAND_MID(channel)) rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0, 0x4); } @@ -442,7 +495,7 @@ rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | RF18_BW_MASK); - rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); rf_reg18 |= (channel & RF18_CHANNEL_MASK); if (channel > 144) rf_reg18 |= RF18_RFSI_GT_CH144; @@ -464,13 +517,13 @@ break; } - if (channel <= 14) + if (IS_CH_2G_BAND(channel)) rf_reg_be = 0x0; - else if (channel >= 36 && channel <= 64) + else if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) rf_reg_be = low_band[(channel - 36) >> 1]; - else if (channel >= 100 && channel <= 144) + else if (IS_CH_5G_BAND_3(channel)) rf_reg_be = middle_band[(channel - 100) >> 1]; - else if (channel >= 149 && channel <= 177) + else if (IS_CH_5G_BAND_4(channel)) rf_reg_be = high_band[(channel - 149) >> 1]; else goto err; @@ -539,7 +592,7 @@ u8 rfe_option = efuse->rfe_option; u32 val32; - if (channel <= 14) { + if (IS_CH_2G_BAND(channel)) { rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x1); rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x0); rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x0); @@ -556,22 +609,22 @@ } rtw_write32_mask(rtwdev, REG_RFEINV, 0x300, 0x2); - } else if (channel > 35) { + } else if (IS_CH_5G_BAND(channel)) { rtw_write32_mask(rtwdev, REG_ENTXCCK, BIT(18), 0x1); rtw_write32_mask(rtwdev, REG_CCK_CHECK, BIT(7), 0x1); rtw_write32_mask(rtwdev, REG_RXPSEL, BIT(28), 0x0); rtw_write32_mask(rtwdev, REG_RXCCAMSK, 0x0000FC00, 34); - if (channel >= 36 && channel <= 64) + if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x1); - else if (channel >= 100 && channel <= 144) + else if (IS_CH_5G_BAND_3(channel)) rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x2); - else if (channel >= 149) + else if (IS_CH_5G_BAND_4(channel)) rtw_write32_mask(rtwdev, REG_ACGG2TBL, 0x1f, 0x3); - if (channel >= 36 && channel <= 48) + if (IS_CH_5G_BAND_1(channel)) rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x494); - else if (channel >= 52 && channel <= 64) + else if (IS_CH_5G_BAND_2(channel)) rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x453); else if (channel >= 100 && channel <= 116) rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, 0x452); @@ -592,7 +645,7 @@ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); break; case RTW_CHANNEL_WIDTH_40: - if (primary_ch_idx == 1) + if (primary_ch_idx == RTW_SC_20_UPPER) rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); else rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); @@ -612,7 +665,7 @@ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0x1); - if (rfe_option == 2) { + if (rfe_option == 2 || rfe_option == 3) { rtw_write32_mask(rtwdev, REG_L1PKWT, 0x0000f000, 0x6); rtw_write32_mask(rtwdev, REG_ADC40, BIT(10), 0x1); } @@ -763,6 +816,7 @@ static void query_phy_status_page0(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; s8 min_rx_power = -120; u8 pwdb = GET_PHY_STAT_P0_PWDB(phy_status); @@ -772,13 +826,19 @@ pkt_stat->bw = RTW_CHANNEL_WIDTH_20; pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], min_rx_power); + dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; } static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u8 rxsc, bw; s8 min_rx_power = -120; + s8 rx_evm; + u8 evm_dbm = 0; + u8 rssi; + int path; if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); @@ -801,6 +861,34 @@ pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], pkt_stat->rx_power[RF_PATH_B], min_rx_power); + + dm_info->curr_rx_rate = pkt_stat->rate; + + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); + + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); + + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); + + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; + + rx_evm = pkt_stat->rx_evm[path]; + + if (rx_evm < 0) { + if (rx_evm == S8_MIN) + evm_dbm = 0; + else + evm_dbm = ((u8)-rx_evm >> 1); + } + dm_info->rx_evm_dbm[path] = evm_dbm; + } } static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, @@ -836,7 +924,8 @@ pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc); + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); @@ -935,7 +1024,7 @@ u8 ldo_pwr; ldo_pwr = rtw_read8(rtwdev, REG_LDO_EFUSE_CTRL + 3); - ldo_pwr = enable ? ldo_pwr | BIT(7) : ldo_pwr & ~BIT(7); + ldo_pwr = enable ? ldo_pwr | BIT_LDO25_EN : ldo_pwr & ~BIT_LDO25_EN; rtw_write8(rtwdev, REG_LDO_EFUSE_CTRL + 3, ldo_pwr); } @@ -946,6 +1035,7 @@ u32 cck_fa_cnt; u32 ofdm_fa_cnt; u32 crc32_cnt; + u32 cca32_cnt; cck_enable = rtw_read32(rtwdev, 0x808) & BIT(28); cck_fa_cnt = rtw_read16(rtwdev, 0xa5c); @@ -969,6 +1059,15 @@ dm_info->vht_ok_cnt = crc32_cnt & 0xffff; dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + cca32_cnt = rtw_read32(rtwdev, 0xf08); + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) { + cca32_cnt = rtw_read32(rtwdev, 0xfcc); + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + } + rtw_write32_set(rtwdev, 0x9a4, BIT(17)); rtw_write32_clr(rtwdev, 0x9a4, BIT(17)); rtw_write32_clr(rtwdev, 0xa2c, BIT(15)); @@ -1255,6 +1354,226 @@ } } +static void rtw8822b_txagc_swing_offset(struct rtw_dev *rtwdev, u8 path, + u8 tx_pwr_idx_offset, + s8 *txagc_idx, u8 *swing_idx) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 delta_pwr_idx = dm_info->delta_power_index[path]; + u8 swing_upper_bound = dm_info->default_ofdm_index + 10; + u8 swing_lower_bound = 0; + u8 max_tx_pwr_idx_offset = 0xf; + s8 agc_index = 0; + u8 swing_index = dm_info->default_ofdm_index; + + tx_pwr_idx_offset = min_t(u8, tx_pwr_idx_offset, max_tx_pwr_idx_offset); + + if (delta_pwr_idx >= 0) { + if (delta_pwr_idx <= tx_pwr_idx_offset) { + agc_index = delta_pwr_idx; + swing_index = dm_info->default_ofdm_index; + } else if (delta_pwr_idx > tx_pwr_idx_offset) { + agc_index = tx_pwr_idx_offset; + swing_index = dm_info->default_ofdm_index + + delta_pwr_idx - tx_pwr_idx_offset; + swing_index = min_t(u8, swing_index, swing_upper_bound); + } + } else { + if (dm_info->default_ofdm_index > abs(delta_pwr_idx)) + swing_index = + dm_info->default_ofdm_index + delta_pwr_idx; + else + swing_index = swing_lower_bound; + swing_index = max_t(u8, swing_index, swing_lower_bound); + + agc_index = 0; + } + + if (swing_index >= RTW_TXSCALE_SIZE) { + rtw_warn(rtwdev, "swing index overflow\n"); + swing_index = RTW_TXSCALE_SIZE - 1; + } + *txagc_idx = agc_index; + *swing_idx = swing_index; +} + +static void rtw8822b_pwrtrack_set_pwr(struct rtw_dev *rtwdev, u8 path, + u8 pwr_idx_offset) +{ + s8 txagc_idx; + u8 swing_idx; + u32 reg1, reg2; + + if (path == RF_PATH_A) { + reg1 = 0xc94; + reg2 = 0xc1c; + } else if (path == RF_PATH_B) { + reg1 = 0xe94; + reg2 = 0xe1c; + } else { + return; + } + + rtw8822b_txagc_swing_offset(rtwdev, path, pwr_idx_offset, + &txagc_idx, &swing_idx); + rtw_write32_mask(rtwdev, reg1, GENMASK(29, 25), txagc_idx); + rtw_write32_mask(rtwdev, reg2, GENMASK(31, 21), + rtw8822b_txscale_tbl[swing_idx]); +} + +static void rtw8822b_pwrtrack_set(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 pwr_idx_offset, tx_pwr_idx; + u8 channel = rtwdev->hal.current_channel; + u8 band_width = rtwdev->hal.current_band_width; + u8 regd = rtwdev->regd.txpwr_regd; + u8 tx_rate = dm_info->tx_rate; + u8 max_pwr_idx = rtwdev->chip->max_power_index; + + tx_pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, tx_rate, + band_width, channel, regd); + + tx_pwr_idx = min_t(u8, tx_pwr_idx, max_pwr_idx); + + pwr_idx_offset = max_pwr_idx - tx_pwr_idx; + + rtw8822b_pwrtrack_set_pwr(rtwdev, path, pwr_idx_offset); +} + +static void rtw8822b_phy_pwrtrack_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 power_idx_cur, power_idx_last; + u8 delta; + + /* 8822B only has one thermal meter at PATH A */ + delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); + + power_idx_last = dm_info->delta_power_index[path]; + power_idx_cur = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, + path, RF_PATH_A, delta); + + /* if delta of power indexes are the same, just skip */ + if (power_idx_cur == power_idx_last) + return; + + dm_info->delta_power_index[path] = power_idx_cur; + rtw8822b_pwrtrack_set(rtwdev, path); +} + +static void rtw8822b_phy_pwrtrack(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_swing_table swing_table; + u8 thermal_value, path; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + if (rtwdev->efuse.thermal_meter[RF_PATH_A] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); + + if (dm_info->pwr_trk_init_trigger) + dm_info->pwr_trk_init_trigger = false; + else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, + RF_PATH_A)) + goto iqk; + + for (path = 0; path < rtwdev->hal.rf_path_num; path++) + rtw8822b_phy_pwrtrack_path(rtwdev, &swing_table, path); + +iqk: + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8822b_do_iqk(rtwdev); +} + +static void rtw8822b_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, + GENMASK(17, 16), 0x03); + dm_info->pwr_trk_triggered = true; + return; + } + + rtw8822b_phy_pwrtrack(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8822b_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8822b_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8822b_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8822b_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8822b_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + +static void rtw8822b_adaptivity_init(struct rtw_dev *rtwdev) +{ + rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f); + /* mac edcca state setting */ + rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0); + rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1); + + rtw_write32_mask(rtwdev, REG_EDCCA_SOURCE, BIT_SOURCE_OPTION, 1); + rtw_write32_mask(rtwdev, REG_EDCCA_POW_MA, BIT_MA_LEVEL, 0); + /* edcca decistion opt */ + rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 1); +} + +static void rtw8822b_adaptivity(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 l2h, h2l; + u8 igi; + + igi = dm_info->igi_history[0]; + if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { + l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); + h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; + } else { + l2h = min_t(s8, igi, dm_info->l2h_th_ini); + h2l = l2h - EDCCA_L2H_H2L_DIFF; + } + + rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +} + static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822b[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, @@ -1754,6 +2073,7 @@ static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { [2] = RTW_DEF_RFE(8822b, 2, 2), + [3] = RTW_DEF_RFE(8822b, 3, 0), [5] = RTW_DEF_RFE(8822b, 5, 5), }; @@ -1762,6 +2082,12 @@ [1] = { .addr = 0xe50, .mask = 0x7f }, }; +static struct rtw_ltecoex_addr rtw8822b_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + static struct rtw_page_table page_table_8822b[] = { {64, 64, 64, 64, 1}, {64, 64, 64, 64, 1}, @@ -1788,6 +2114,22 @@ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; +static struct rtw_prioq_addrs prioq_addrs_8822b = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + static struct rtw_chip_ops rtw8822b_ops = { .phy_set_param = rtw8822b_phy_set_param, .read_efuse = rtw8822b_read_efuse, @@ -1801,6 +2143,12 @@ .cfg_ldo25 = rtw8822b_cfg_ldo25, .false_alarm_statistics = rtw8822b_false_alarm_statistics, .phy_calibration = rtw8822b_phy_calibration, + .pwr_track = rtw8822b_pwr_track, + .config_bfee = rtw8822b_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .adaptivity_init = rtw8822b_adaptivity_init, + .adaptivity = rtw8822b_adaptivity, .coex_set_init = rtw8822b_coex_cfg_init, .coex_set_ant_switch = rtw8822b_coex_cfg_ant_switch, @@ -1955,10 +2303,166 @@ static_assert(ARRAY_SIZE(rf_para_tx_8822b) == ARRAY_SIZE(rf_para_rx_8822b)); +static const u8 +rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, +}; + +static const u8 +rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23 }, +}; + +static const u8 +rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 8, 9, 10, 11, 11, 12, 13, 14, 14, + 15, 16, 17, 17, 18, 19, 20, 20, 21, 22 }, +}; + +static const u8 +rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, + { 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, + 8, 9, 9, 10, 11, 12, 13, 14, 14, 15, + 16, 17, 18, 19, 19, 20, 21, 22, 22, 23}, +}; + +static const u8 rtw8822b_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 +}; + +static const u8 rtw8822b_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, + 5, 5, 6, 6, 6, 7, 7, 8, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, + 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, + 8, 9, 9, 9, 10, 10, 11, 11, 11, 12 +}; + +static const u8 rtw8822b_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, + 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 +}; + +static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gb_n = rtw8822b_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8822b_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8822b_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8822b_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8822b_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8822b_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8822b_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, +}; + +static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcba, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xc58, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0xcbd, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + +static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0}, + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0}, +}; + struct rtw_chip_info rtw8822b_hw_spec = { .ops = &rtw8822b_ops, .id = RTW_CHIP_TYPE_8822B, .fw_name = "rtw88/rtw8822b_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, @@ -1977,21 +2481,32 @@ .dig_min = 0x1c, .ht_supported = true, .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), .sys_func_en = 0xDC, .pwr_on_seq = card_enable_flow_8822b, .pwr_off_seq = card_disable_flow_8822b, .page_table = page_table_8822b, .rqpn_table = rqpn_table_8822b, + .prioq_addrs = &prioq_addrs_8822b, .intf_table = &phy_para_table_8822b, .dig = rtw8822b_dig, + .dig_cck = NULL, .rf_base_addr = {0x2800, 0x2c00}, .rf_sipi_addr = {0xc90, 0xe90}, + .ltecoex_addr = &rtw8822b_ltecoex_addr, .mac_tbl = &rtw8822b_mac_tbl, .agc_tbl = &rtw8822b_agc_tbl, .bb_tbl = &rtw8822b_bb_tbl, .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, .rfe_defs = rtw8822b_rfe_defs, .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), + .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, + .edcca_th = rtw8822b_edcca_th, + .l2h_th_ini_cs = 10 + EDCCA_IGI_BASE, + .l2h_th_ini_ad = -14 + EDCCA_IGI_BASE, .coex_para_ver = 0x19062706, .bt_desired_ver = 0x6, @@ -2018,6 +2533,9 @@ .bt_afh_span_bw40 = 0x36, .afh_5g_num = ARRAY_SIZE(afh_5g_8822b), .afh_5g = afh_5g_8822b, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822b), + .coex_info_hw_regs = coex_info_hw_regs_8822b, }; EXPORT_SYMBOL(rtw8822b_hw_spec); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822b.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822b.h @@ -127,6 +127,18 @@ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) #define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) #define REG_HTSTFWT 0x800 #define REG_RXPSEL 0x808 @@ -140,11 +152,17 @@ #define REG_L1PKWT 0x840 #define REG_MRC 0x850 #define REG_CLKTRK 0x860 +#define REG_EDCCA_POW_MA 0x8a0 +#define BIT_MA_LEVEL GENMASK(1, 0) #define REG_ADCCLK 0x8ac #define REG_ADC160 0x8c4 #define REG_ADC40 0x8c8 +#define REG_EDCCA_DECISION 0x8dc +#define BIT_EDCCA_OPTION BIT(5) #define REG_CDDTXP 0x93c #define REG_TXPSEL1 0x940 +#define REG_EDCCA_SOURCE 0x944 +#define BIT_SOURCE_OPTION GENMASK(29, 28) #define REG_ACBB0 0x948 #define REG_ACBBRXFIR 0x94c #define REG_ACGG2TBL 0x958 --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822b_table.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822b_table.c @@ -11643,104 +11643,155 @@ RTW_DECL_TABLE_PHY_COND(rtw8822b_bb, rtw_phy_cfg_bb); -static const u32 rtw8822b_bb_pg_type2[] = { - 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, - 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, - 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, - 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, - 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, - 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, - 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, - 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, - 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, - 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, - 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, - 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, - 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, - 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, - 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, - 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, - 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, - 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, - 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, - 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, - 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, - 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, - 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, - 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, - 1, 0, 0, 0x00000c24, 0xffffffff, 0x40424446, - 1, 0, 0, 0x00000c28, 0xffffffff, 0x32343638, - 1, 0, 0, 0x00000c2c, 0xffffffff, 0x38404244, - 1, 0, 0, 0x00000c30, 0xffffffff, 0x30323436, - 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404244, - 1, 0, 1, 0x00000c38, 0xffffffff, 0x30323436, - 1, 0, 0, 0x00000c3c, 0xffffffff, 0x38404244, - 1, 0, 0, 0x00000c40, 0xffffffff, 0x30323436, - 1, 0, 0, 0x00000c44, 0xffffffff, 0x42442628, - 1, 0, 1, 0x00000c48, 0xffffffff, 0x34363840, - 1, 0, 1, 0x00000c4c, 0xffffffff, 0x26283032, - 1, 1, 0, 0x00000e24, 0xffffffff, 0x40424446, - 1, 1, 0, 0x00000e28, 0xffffffff, 0x32343638, - 1, 1, 0, 0x00000e2c, 0xffffffff, 0x38404244, - 1, 1, 0, 0x00000e30, 0xffffffff, 0x30323436, - 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404244, - 1, 1, 1, 0x00000e38, 0xffffffff, 0x30323436, - 1, 1, 0, 0x00000e3c, 0xffffffff, 0x38404244, - 1, 1, 0, 0x00000e40, 0xffffffff, 0x30323436, - 1, 1, 0, 0x00000e44, 0xffffffff, 0x42442628, - 1, 1, 1, 0x00000e48, 0xffffffff, 0x34363840, - 1, 1, 1, 0x00000e4c, 0xffffffff, 0x26283032 +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type2[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x40424446, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x30323436, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404244, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x30323436, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x38404244, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x30323436, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42442628, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x34363840, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x40424446, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x30323436, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404244, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x30323436, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x38404244, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x30323436, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42442628, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x34363840, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x26283032, }, }; RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type2); -static const u32 rtw8822b_bb_pg_type5[] = { - 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, - 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, - 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, - 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, - 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, - 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, - 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, - 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, - 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, - 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, - 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, - 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, - 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, - 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, - 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, - 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, - 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, - 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, - 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, - 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, - 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, - 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, - 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, - 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, - 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, - 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, - 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, - 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, - 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, - 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, - 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, - 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, - 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, - 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, - 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, - 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, - 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, - 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, - 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, - 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, - 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, - 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, - 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, - 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, - 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, - 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426 +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type3[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, +}; + +RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type3); + +static const struct rtw_phy_pg_cfg_pair rtw8822b_bb_pg_type5[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36384042, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x34363840, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x34363840, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x26283032, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x38402224, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30323436, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x32343638, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x36384042, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303234, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x26283032, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x34363840, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x34363840, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x26283032, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x38402224, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30323436, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34363840, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32343638, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343638, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x36382022, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303234, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x20222426, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x34363840, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x26283032, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32343638, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32343638, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x36382022, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303234, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x20222426, }, }; RTW_DECL_TABLE_BB_PG(rtw8822b_bb_pg_type5); @@ -20382,6 +20433,596 @@ RTW_DECL_TABLE_RF_RADIO(rtw8822b_rf_b, B); +static const struct rtw_txpwr_lmt_cfg_pair rtw8822b_txpwr_lmt_type0[] = { + { 0, 0, 0, 0, 1, 32, }, + { 2, 0, 0, 0, 1, 28, }, + { 1, 0, 0, 0, 1, 30, }, + { 0, 0, 0, 0, 2, 32, }, + { 2, 0, 0, 0, 2, 28, }, + { 1, 0, 0, 0, 2, 30, }, + { 0, 0, 0, 0, 3, 32, }, + { 2, 0, 0, 0, 3, 28, }, + { 1, 0, 0, 0, 3, 30, }, + { 0, 0, 0, 0, 4, 32, }, + { 2, 0, 0, 0, 4, 28, }, + { 1, 0, 0, 0, 4, 30, }, + { 0, 0, 0, 0, 5, 32, }, + { 2, 0, 0, 0, 5, 28, }, + { 1, 0, 0, 0, 5, 30, }, + { 0, 0, 0, 0, 6, 32, }, + { 2, 0, 0, 0, 6, 28, }, + { 1, 0, 0, 0, 6, 30, }, + { 0, 0, 0, 0, 7, 32, }, + { 2, 0, 0, 0, 7, 28, }, + { 1, 0, 0, 0, 7, 30, }, + { 0, 0, 0, 0, 8, 32, }, + { 2, 0, 0, 0, 8, 28, }, + { 1, 0, 0, 0, 8, 30, }, + { 0, 0, 0, 0, 9, 32, }, + { 2, 0, 0, 0, 9, 28, }, + { 1, 0, 0, 0, 9, 30, }, + { 0, 0, 0, 0, 10, 32, }, + { 2, 0, 0, 0, 10, 28, }, + { 1, 0, 0, 0, 10, 30, }, + { 0, 0, 0, 0, 11, 32, }, + { 2, 0, 0, 0, 11, 28, }, + { 1, 0, 0, 0, 11, 30, }, + { 0, 0, 0, 0, 12, 26, }, + { 2, 0, 0, 0, 12, 28, }, + { 1, 0, 0, 0, 12, 30, }, + { 0, 0, 0, 0, 13, 20, }, + { 2, 0, 0, 0, 13, 28, }, + { 1, 0, 0, 0, 13, 28, }, + { 0, 0, 0, 0, 14, 63, }, + { 2, 0, 0, 0, 14, 63, }, + { 1, 0, 0, 0, 14, 32, }, + { 0, 0, 0, 1, 1, 26, }, + { 2, 0, 0, 1, 1, 30, }, + { 1, 0, 0, 1, 1, 34, }, + { 0, 0, 0, 1, 2, 30, }, + { 2, 0, 0, 1, 2, 30, }, + { 1, 0, 0, 1, 2, 34, }, + { 0, 0, 0, 1, 3, 32, }, + { 2, 0, 0, 1, 3, 30, }, + { 1, 0, 0, 1, 3, 34, }, + { 0, 0, 0, 1, 4, 34, }, + { 2, 0, 0, 1, 4, 30, }, + { 1, 0, 0, 1, 4, 34, }, + { 0, 0, 0, 1, 5, 34, }, + { 2, 0, 0, 1, 5, 30, }, + { 1, 0, 0, 1, 5, 34, }, + { 0, 0, 0, 1, 6, 34, }, + { 2, 0, 0, 1, 6, 30, }, + { 1, 0, 0, 1, 6, 34, }, + { 0, 0, 0, 1, 7, 34, }, + { 2, 0, 0, 1, 7, 30, }, + { 1, 0, 0, 1, 7, 34, }, + { 0, 0, 0, 1, 8, 34, }, + { 2, 0, 0, 1, 8, 30, }, + { 1, 0, 0, 1, 8, 34, }, + { 0, 0, 0, 1, 9, 32, }, + { 2, 0, 0, 1, 9, 30, }, + { 1, 0, 0, 1, 9, 34, }, + { 0, 0, 0, 1, 10, 30, }, + { 2, 0, 0, 1, 10, 30, }, + { 1, 0, 0, 1, 10, 34, }, + { 0, 0, 0, 1, 11, 28, }, + { 2, 0, 0, 1, 11, 30, }, + { 1, 0, 0, 1, 11, 34, }, + { 0, 0, 0, 1, 12, 22, }, + { 2, 0, 0, 1, 12, 30, }, + { 1, 0, 0, 1, 12, 34, }, + { 0, 0, 0, 1, 13, 14, }, + { 2, 0, 0, 1, 13, 30, }, + { 1, 0, 0, 1, 13, 34, }, + { 0, 0, 0, 1, 14, 63, }, + { 2, 0, 0, 1, 14, 63, }, + { 1, 0, 0, 1, 14, 63, }, + { 0, 0, 0, 2, 1, 26, }, + { 2, 0, 0, 2, 1, 30, }, + { 1, 0, 0, 2, 1, 34, }, + { 0, 0, 0, 2, 2, 30, }, + { 2, 0, 0, 2, 2, 30, }, + { 1, 0, 0, 2, 2, 34, }, + { 0, 0, 0, 2, 3, 32, }, + { 2, 0, 0, 2, 3, 30, }, + { 1, 0, 0, 2, 3, 34, }, + { 0, 0, 0, 2, 4, 34, }, + { 2, 0, 0, 2, 4, 30, }, + { 1, 0, 0, 2, 4, 34, }, + { 0, 0, 0, 2, 5, 34, }, + { 2, 0, 0, 2, 5, 30, }, + { 1, 0, 0, 2, 5, 34, }, + { 0, 0, 0, 2, 6, 34, }, + { 2, 0, 0, 2, 6, 30, }, + { 1, 0, 0, 2, 6, 34, }, + { 0, 0, 0, 2, 7, 34, }, + { 2, 0, 0, 2, 7, 30, }, + { 1, 0, 0, 2, 7, 34, }, + { 0, 0, 0, 2, 8, 34, }, + { 2, 0, 0, 2, 8, 30, }, + { 1, 0, 0, 2, 8, 34, }, + { 0, 0, 0, 2, 9, 32, }, + { 2, 0, 0, 2, 9, 30, }, + { 1, 0, 0, 2, 9, 34, }, + { 0, 0, 0, 2, 10, 30, }, + { 2, 0, 0, 2, 10, 30, }, + { 1, 0, 0, 2, 10, 34, }, + { 0, 0, 0, 2, 11, 26, }, + { 2, 0, 0, 2, 11, 30, }, + { 1, 0, 0, 2, 11, 34, }, + { 0, 0, 0, 2, 12, 20, }, + { 2, 0, 0, 2, 12, 30, }, + { 1, 0, 0, 2, 12, 34, }, + { 0, 0, 0, 2, 13, 14, }, + { 2, 0, 0, 2, 13, 30, }, + { 1, 0, 0, 2, 13, 34, }, + { 0, 0, 0, 2, 14, 63, }, + { 2, 0, 0, 2, 14, 63, }, + { 1, 0, 0, 2, 14, 63, }, + { 0, 0, 0, 3, 1, 26, }, + { 2, 0, 0, 3, 1, 18, }, + { 1, 0, 0, 3, 1, 30, }, + { 0, 0, 0, 3, 2, 28, }, + { 2, 0, 0, 3, 2, 18, }, + { 1, 0, 0, 3, 2, 30, }, + { 0, 0, 0, 3, 3, 30, }, + { 2, 0, 0, 3, 3, 18, }, + { 1, 0, 0, 3, 3, 30, }, + { 0, 0, 0, 3, 4, 30, }, + { 2, 0, 0, 3, 4, 18, }, + { 1, 0, 0, 3, 4, 30, }, + { 0, 0, 0, 3, 5, 32, }, + { 2, 0, 0, 3, 5, 18, }, + { 1, 0, 0, 3, 5, 30, }, + { 0, 0, 0, 3, 6, 32, }, + { 2, 0, 0, 3, 6, 18, }, + { 1, 0, 0, 3, 6, 30, }, + { 0, 0, 0, 3, 7, 32, }, + { 2, 0, 0, 3, 7, 18, }, + { 1, 0, 0, 3, 7, 30, }, + { 0, 0, 0, 3, 8, 30, }, + { 2, 0, 0, 3, 8, 18, }, + { 1, 0, 0, 3, 8, 30, }, + { 0, 0, 0, 3, 9, 30, }, + { 2, 0, 0, 3, 9, 18, }, + { 1, 0, 0, 3, 9, 30, }, + { 0, 0, 0, 3, 10, 28, }, + { 2, 0, 0, 3, 10, 18, }, + { 1, 0, 0, 3, 10, 30, }, + { 0, 0, 0, 3, 11, 26, }, + { 2, 0, 0, 3, 11, 18, }, + { 1, 0, 0, 3, 11, 30, }, + { 0, 0, 0, 3, 12, 20, }, + { 2, 0, 0, 3, 12, 18, }, + { 1, 0, 0, 3, 12, 30, }, + { 0, 0, 0, 3, 13, 14, }, + { 2, 0, 0, 3, 13, 18, }, + { 1, 0, 0, 3, 13, 30, }, + { 0, 0, 0, 3, 14, 63, }, + { 2, 0, 0, 3, 14, 63, }, + { 1, 0, 0, 3, 14, 63, }, + { 0, 0, 1, 2, 1, 63, }, + { 2, 0, 1, 2, 1, 63, }, + { 1, 0, 1, 2, 1, 63, }, + { 0, 0, 1, 2, 2, 63, }, + { 2, 0, 1, 2, 2, 63, }, + { 1, 0, 1, 2, 2, 63, }, + { 0, 0, 1, 2, 3, 26, }, + { 2, 0, 1, 2, 3, 30, }, + { 1, 0, 1, 2, 3, 34, }, + { 0, 0, 1, 2, 4, 26, }, + { 2, 0, 1, 2, 4, 30, }, + { 1, 0, 1, 2, 4, 34, }, + { 0, 0, 1, 2, 5, 30, }, + { 2, 0, 1, 2, 5, 30, }, + { 1, 0, 1, 2, 5, 34, }, + { 0, 0, 1, 2, 6, 32, }, + { 2, 0, 1, 2, 6, 30, }, + { 1, 0, 1, 2, 6, 34, }, + { 0, 0, 1, 2, 7, 30, }, + { 2, 0, 1, 2, 7, 30, }, + { 1, 0, 1, 2, 7, 34, }, + { 0, 0, 1, 2, 8, 26, }, + { 2, 0, 1, 2, 8, 30, }, + { 1, 0, 1, 2, 8, 34, }, + { 0, 0, 1, 2, 9, 26, }, + { 2, 0, 1, 2, 9, 30, }, + { 1, 0, 1, 2, 9, 34, }, + { 0, 0, 1, 2, 10, 20, }, + { 2, 0, 1, 2, 10, 30, }, + { 1, 0, 1, 2, 10, 34, }, + { 0, 0, 1, 2, 11, 14, }, + { 2, 0, 1, 2, 11, 30, }, + { 1, 0, 1, 2, 11, 34, }, + { 0, 0, 1, 2, 12, 63, }, + { 2, 0, 1, 2, 12, 63, }, + { 1, 0, 1, 2, 12, 63, }, + { 0, 0, 1, 2, 13, 63, }, + { 2, 0, 1, 2, 13, 63, }, + { 1, 0, 1, 2, 13, 63, }, + { 0, 0, 1, 2, 14, 63, }, + { 2, 0, 1, 2, 14, 63, }, + { 1, 0, 1, 2, 14, 63, }, + { 0, 0, 1, 3, 1, 63, }, + { 2, 0, 1, 3, 1, 63, }, + { 1, 0, 1, 3, 1, 63, }, + { 0, 0, 1, 3, 2, 63, }, + { 2, 0, 1, 3, 2, 63, }, + { 1, 0, 1, 3, 2, 63, }, + { 0, 0, 1, 3, 3, 24, }, + { 2, 0, 1, 3, 3, 18, }, + { 1, 0, 1, 3, 3, 30, }, + { 0, 0, 1, 3, 4, 24, }, + { 2, 0, 1, 3, 4, 18, }, + { 1, 0, 1, 3, 4, 30, }, + { 0, 0, 1, 3, 5, 26, }, + { 2, 0, 1, 3, 5, 18, }, + { 1, 0, 1, 3, 5, 30, }, + { 0, 0, 1, 3, 6, 28, }, + { 2, 0, 1, 3, 6, 18, }, + { 1, 0, 1, 3, 6, 30, }, + { 0, 0, 1, 3, 7, 26, }, + { 2, 0, 1, 3, 7, 18, }, + { 1, 0, 1, 3, 7, 30, }, + { 0, 0, 1, 3, 8, 26, }, + { 2, 0, 1, 3, 8, 18, }, + { 1, 0, 1, 3, 8, 30, }, + { 0, 0, 1, 3, 9, 26, }, + { 2, 0, 1, 3, 9, 18, }, + { 1, 0, 1, 3, 9, 30, }, + { 0, 0, 1, 3, 10, 20, }, + { 2, 0, 1, 3, 10, 18, }, + { 1, 0, 1, 3, 10, 30, }, + { 0, 0, 1, 3, 11, 14, }, + { 2, 0, 1, 3, 11, 18, }, + { 1, 0, 1, 3, 11, 30, }, + { 0, 0, 1, 3, 12, 63, }, + { 2, 0, 1, 3, 12, 63, }, + { 1, 0, 1, 3, 12, 63, }, + { 0, 0, 1, 3, 13, 63, }, + { 2, 0, 1, 3, 13, 63, }, + { 1, 0, 1, 3, 13, 63, }, + { 0, 0, 1, 3, 14, 63, }, + { 2, 0, 1, 3, 14, 63, }, + { 1, 0, 1, 3, 14, 63, }, + { 0, 1, 0, 1, 36, 30, }, + { 2, 1, 0, 1, 36, 32, }, + { 1, 1, 0, 1, 36, 30, }, + { 0, 1, 0, 1, 40, 32, }, + { 2, 1, 0, 1, 40, 32, }, + { 1, 1, 0, 1, 40, 30, }, + { 0, 1, 0, 1, 44, 32, }, + { 2, 1, 0, 1, 44, 32, }, + { 1, 1, 0, 1, 44, 30, }, + { 0, 1, 0, 1, 48, 32, }, + { 2, 1, 0, 1, 48, 32, }, + { 1, 1, 0, 1, 48, 30, }, + { 0, 1, 0, 1, 52, 32, }, + { 2, 1, 0, 1, 52, 32, }, + { 1, 1, 0, 1, 52, 28, }, + { 0, 1, 0, 1, 56, 32, }, + { 2, 1, 0, 1, 56, 32, }, + { 1, 1, 0, 1, 56, 28, }, + { 0, 1, 0, 1, 60, 32, }, + { 2, 1, 0, 1, 60, 32, }, + { 1, 1, 0, 1, 60, 28, }, + { 0, 1, 0, 1, 64, 28, }, + { 2, 1, 0, 1, 64, 32, }, + { 1, 1, 0, 1, 64, 28, }, + { 0, 1, 0, 1, 100, 26, }, + { 2, 1, 0, 1, 100, 32, }, + { 1, 1, 0, 1, 100, 32, }, + { 0, 1, 0, 1, 104, 32, }, + { 2, 1, 0, 1, 104, 32, }, + { 1, 1, 0, 1, 104, 32, }, + { 0, 1, 0, 1, 108, 32, }, + { 2, 1, 0, 1, 108, 32, }, + { 1, 1, 0, 1, 108, 32, }, + { 0, 1, 0, 1, 112, 32, }, + { 2, 1, 0, 1, 112, 32, }, + { 1, 1, 0, 1, 112, 32, }, + { 0, 1, 0, 1, 116, 32, }, + { 2, 1, 0, 1, 116, 32, }, + { 1, 1, 0, 1, 116, 32, }, + { 0, 1, 0, 1, 120, 32, }, + { 2, 1, 0, 1, 120, 32, }, + { 1, 1, 0, 1, 120, 32, }, + { 0, 1, 0, 1, 124, 32, }, + { 2, 1, 0, 1, 124, 32, }, + { 1, 1, 0, 1, 124, 32, }, + { 0, 1, 0, 1, 128, 32, }, + { 2, 1, 0, 1, 128, 32, }, + { 1, 1, 0, 1, 128, 32, }, + { 0, 1, 0, 1, 132, 32, }, + { 2, 1, 0, 1, 132, 32, }, + { 1, 1, 0, 1, 132, 32, }, + { 0, 1, 0, 1, 136, 32, }, + { 2, 1, 0, 1, 136, 32, }, + { 1, 1, 0, 1, 136, 32, }, + { 0, 1, 0, 1, 140, 28, }, + { 2, 1, 0, 1, 140, 32, }, + { 1, 1, 0, 1, 140, 32, }, + { 0, 1, 0, 1, 144, 28, }, + { 2, 1, 0, 1, 144, 32, }, + { 1, 1, 0, 1, 144, 63, }, + { 0, 1, 0, 1, 149, 32, }, + { 2, 1, 0, 1, 149, 63, }, + { 1, 1, 0, 1, 149, 63, }, + { 0, 1, 0, 1, 153, 32, }, + { 2, 1, 0, 1, 153, 63, }, + { 1, 1, 0, 1, 153, 63, }, + { 0, 1, 0, 1, 157, 32, }, + { 2, 1, 0, 1, 157, 63, }, + { 1, 1, 0, 1, 157, 63, }, + { 0, 1, 0, 1, 161, 32, }, + { 2, 1, 0, 1, 161, 63, }, + { 1, 1, 0, 1, 161, 63, }, + { 0, 1, 0, 1, 165, 32, }, + { 2, 1, 0, 1, 165, 63, }, + { 1, 1, 0, 1, 165, 63, }, + { 0, 1, 0, 2, 36, 30, }, + { 2, 1, 0, 2, 36, 32, }, + { 1, 1, 0, 2, 36, 28, }, + { 0, 1, 0, 2, 40, 32, }, + { 2, 1, 0, 2, 40, 32, }, + { 1, 1, 0, 2, 40, 28, }, + { 0, 1, 0, 2, 44, 32, }, + { 2, 1, 0, 2, 44, 32, }, + { 1, 1, 0, 2, 44, 28, }, + { 0, 1, 0, 2, 48, 32, }, + { 2, 1, 0, 2, 48, 32, }, + { 1, 1, 0, 2, 48, 28, }, + { 0, 1, 0, 2, 52, 32, }, + { 2, 1, 0, 2, 52, 32, }, + { 1, 1, 0, 2, 52, 28, }, + { 0, 1, 0, 2, 56, 32, }, + { 2, 1, 0, 2, 56, 32, }, + { 1, 1, 0, 2, 56, 28, }, + { 0, 1, 0, 2, 60, 32, }, + { 2, 1, 0, 2, 60, 32, }, + { 1, 1, 0, 2, 60, 28, }, + { 0, 1, 0, 2, 64, 28, }, + { 2, 1, 0, 2, 64, 32, }, + { 1, 1, 0, 2, 64, 28, }, + { 0, 1, 0, 2, 100, 26, }, + { 2, 1, 0, 2, 100, 32, }, + { 1, 1, 0, 2, 100, 32, }, + { 0, 1, 0, 2, 104, 32, }, + { 2, 1, 0, 2, 104, 32, }, + { 1, 1, 0, 2, 104, 32, }, + { 0, 1, 0, 2, 108, 32, }, + { 2, 1, 0, 2, 108, 32, }, + { 1, 1, 0, 2, 108, 32, }, + { 0, 1, 0, 2, 112, 32, }, + { 2, 1, 0, 2, 112, 32, }, + { 1, 1, 0, 2, 112, 32, }, + { 0, 1, 0, 2, 116, 32, }, + { 2, 1, 0, 2, 116, 32, }, + { 1, 1, 0, 2, 116, 32, }, + { 0, 1, 0, 2, 120, 32, }, + { 2, 1, 0, 2, 120, 32, }, + { 1, 1, 0, 2, 120, 32, }, + { 0, 1, 0, 2, 124, 32, }, + { 2, 1, 0, 2, 124, 32, }, + { 1, 1, 0, 2, 124, 32, }, + { 0, 1, 0, 2, 128, 32, }, + { 2, 1, 0, 2, 128, 32, }, + { 1, 1, 0, 2, 128, 32, }, + { 0, 1, 0, 2, 132, 32, }, + { 2, 1, 0, 2, 132, 32, }, + { 1, 1, 0, 2, 132, 32, }, + { 0, 1, 0, 2, 136, 32, }, + { 2, 1, 0, 2, 136, 32, }, + { 1, 1, 0, 2, 136, 32, }, + { 0, 1, 0, 2, 140, 26, }, + { 2, 1, 0, 2, 140, 32, }, + { 1, 1, 0, 2, 140, 32, }, + { 0, 1, 0, 2, 144, 26, }, + { 2, 1, 0, 2, 144, 63, }, + { 1, 1, 0, 2, 144, 63, }, + { 0, 1, 0, 2, 149, 32, }, + { 2, 1, 0, 2, 149, 63, }, + { 1, 1, 0, 2, 149, 63, }, + { 0, 1, 0, 2, 153, 32, }, + { 2, 1, 0, 2, 153, 63, }, + { 1, 1, 0, 2, 153, 63, }, + { 0, 1, 0, 2, 157, 32, }, + { 2, 1, 0, 2, 157, 63, }, + { 1, 1, 0, 2, 157, 63, }, + { 0, 1, 0, 2, 161, 32, }, + { 2, 1, 0, 2, 161, 63, }, + { 1, 1, 0, 2, 161, 63, }, + { 0, 1, 0, 2, 165, 32, }, + { 2, 1, 0, 2, 165, 63, }, + { 1, 1, 0, 2, 165, 63, }, + { 0, 1, 0, 3, 36, 28, }, + { 2, 1, 0, 3, 36, 20, }, + { 1, 1, 0, 3, 36, 22, }, + { 0, 1, 0, 3, 40, 30, }, + { 2, 1, 0, 3, 40, 20, }, + { 1, 1, 0, 3, 40, 22, }, + { 0, 1, 0, 3, 44, 30, }, + { 2, 1, 0, 3, 44, 20, }, + { 1, 1, 0, 3, 44, 22, }, + { 0, 1, 0, 3, 48, 30, }, + { 2, 1, 0, 3, 48, 20, }, + { 1, 1, 0, 3, 48, 22, }, + { 0, 1, 0, 3, 52, 30, }, + { 2, 1, 0, 3, 52, 20, }, + { 1, 1, 0, 3, 52, 22, }, + { 0, 1, 0, 3, 56, 30, }, + { 2, 1, 0, 3, 56, 20, }, + { 1, 1, 0, 3, 56, 22, }, + { 0, 1, 0, 3, 60, 30, }, + { 2, 1, 0, 3, 60, 20, }, + { 1, 1, 0, 3, 60, 22, }, + { 0, 1, 0, 3, 64, 28, }, + { 2, 1, 0, 3, 64, 20, }, + { 1, 1, 0, 3, 64, 22, }, + { 0, 1, 0, 3, 100, 26, }, + { 2, 1, 0, 3, 100, 20, }, + { 1, 1, 0, 3, 100, 30, }, + { 0, 1, 0, 3, 104, 30, }, + { 2, 1, 0, 3, 104, 20, }, + { 1, 1, 0, 3, 104, 30, }, + { 0, 1, 0, 3, 108, 32, }, + { 2, 1, 0, 3, 108, 20, }, + { 1, 1, 0, 3, 108, 30, }, + { 0, 1, 0, 3, 112, 32, }, + { 2, 1, 0, 3, 112, 20, }, + { 1, 1, 0, 3, 112, 30, }, + { 0, 1, 0, 3, 116, 32, }, + { 2, 1, 0, 3, 116, 20, }, + { 1, 1, 0, 3, 116, 30, }, + { 0, 1, 0, 3, 120, 32, }, + { 2, 1, 0, 3, 120, 20, }, + { 1, 1, 0, 3, 120, 30, }, + { 0, 1, 0, 3, 124, 32, }, + { 2, 1, 0, 3, 124, 20, }, + { 1, 1, 0, 3, 124, 30, }, + { 0, 1, 0, 3, 128, 32, }, + { 2, 1, 0, 3, 128, 20, }, + { 1, 1, 0, 3, 128, 30, }, + { 0, 1, 0, 3, 132, 32, }, + { 2, 1, 0, 3, 132, 20, }, + { 1, 1, 0, 3, 132, 30, }, + { 0, 1, 0, 3, 136, 30, }, + { 2, 1, 0, 3, 136, 20, }, + { 1, 1, 0, 3, 136, 30, }, + { 0, 1, 0, 3, 140, 26, }, + { 2, 1, 0, 3, 140, 20, }, + { 1, 1, 0, 3, 140, 30, }, + { 0, 1, 0, 3, 144, 26, }, + { 2, 1, 0, 3, 144, 63, }, + { 1, 1, 0, 3, 144, 63, }, + { 0, 1, 0, 3, 149, 32, }, + { 2, 1, 0, 3, 149, 63, }, + { 1, 1, 0, 3, 149, 63, }, + { 0, 1, 0, 3, 153, 32, }, + { 2, 1, 0, 3, 153, 63, }, + { 1, 1, 0, 3, 153, 63, }, + { 0, 1, 0, 3, 157, 32, }, + { 2, 1, 0, 3, 157, 63, }, + { 1, 1, 0, 3, 157, 63, }, + { 0, 1, 0, 3, 161, 32, }, + { 2, 1, 0, 3, 161, 63, }, + { 1, 1, 0, 3, 161, 63, }, + { 0, 1, 0, 3, 165, 32, }, + { 2, 1, 0, 3, 165, 63, }, + { 1, 1, 0, 3, 165, 63, }, + { 0, 1, 1, 2, 38, 22, }, + { 2, 1, 1, 2, 38, 30, }, + { 1, 1, 1, 2, 38, 30, }, + { 0, 1, 1, 2, 46, 30, }, + { 2, 1, 1, 2, 46, 30, }, + { 1, 1, 1, 2, 46, 30, }, + { 0, 1, 1, 2, 54, 30, }, + { 2, 1, 1, 2, 54, 30, }, + { 1, 1, 1, 2, 54, 30, }, + { 0, 1, 1, 2, 62, 24, }, + { 2, 1, 1, 2, 62, 30, }, + { 1, 1, 1, 2, 62, 30, }, + { 0, 1, 1, 2, 102, 24, }, + { 2, 1, 1, 2, 102, 30, }, + { 1, 1, 1, 2, 102, 30, }, + { 0, 1, 1, 2, 110, 30, }, + { 2, 1, 1, 2, 110, 30, }, + { 1, 1, 1, 2, 110, 30, }, + { 0, 1, 1, 2, 118, 30, }, + { 2, 1, 1, 2, 118, 30, }, + { 1, 1, 1, 2, 118, 30, }, + { 0, 1, 1, 2, 126, 30, }, + { 2, 1, 1, 2, 126, 30, }, + { 1, 1, 1, 2, 126, 30, }, + { 0, 1, 1, 2, 134, 30, }, + { 2, 1, 1, 2, 134, 30, }, + { 1, 1, 1, 2, 134, 30, }, + { 0, 1, 1, 2, 142, 30, }, + { 2, 1, 1, 2, 142, 63, }, + { 1, 1, 1, 2, 142, 63, }, + { 0, 1, 1, 2, 151, 30, }, + { 2, 1, 1, 2, 151, 63, }, + { 1, 1, 1, 2, 151, 63, }, + { 0, 1, 1, 2, 159, 30, }, + { 2, 1, 1, 2, 159, 63, }, + { 1, 1, 1, 2, 159, 63, }, + { 0, 1, 1, 3, 38, 20, }, + { 2, 1, 1, 3, 38, 20, }, + { 1, 1, 1, 3, 38, 22, }, + { 0, 1, 1, 3, 46, 30, }, + { 2, 1, 1, 3, 46, 20, }, + { 1, 1, 1, 3, 46, 22, }, + { 0, 1, 1, 3, 54, 30, }, + { 2, 1, 1, 3, 54, 20, }, + { 1, 1, 1, 3, 54, 22, }, + { 0, 1, 1, 3, 62, 22, }, + { 2, 1, 1, 3, 62, 20, }, + { 1, 1, 1, 3, 62, 22, }, + { 0, 1, 1, 3, 102, 22, }, + { 2, 1, 1, 3, 102, 20, }, + { 1, 1, 1, 3, 102, 30, }, + { 0, 1, 1, 3, 110, 30, }, + { 2, 1, 1, 3, 110, 20, }, + { 1, 1, 1, 3, 110, 30, }, + { 0, 1, 1, 3, 118, 30, }, + { 2, 1, 1, 3, 118, 20, }, + { 1, 1, 1, 3, 118, 30, }, + { 0, 1, 1, 3, 126, 30, }, + { 2, 1, 1, 3, 126, 20, }, + { 1, 1, 1, 3, 126, 30, }, + { 0, 1, 1, 3, 134, 30, }, + { 2, 1, 1, 3, 134, 20, }, + { 1, 1, 1, 3, 134, 30, }, + { 0, 1, 1, 3, 142, 30, }, + { 2, 1, 1, 3, 142, 63, }, + { 1, 1, 1, 3, 142, 63, }, + { 0, 1, 1, 3, 151, 30, }, + { 2, 1, 1, 3, 151, 63, }, + { 1, 1, 1, 3, 151, 63, }, + { 0, 1, 1, 3, 159, 30, }, + { 2, 1, 1, 3, 159, 63, }, + { 1, 1, 1, 3, 159, 63, }, + { 0, 1, 2, 4, 42, 20, }, + { 2, 1, 2, 4, 42, 30, }, + { 1, 1, 2, 4, 42, 28, }, + { 0, 1, 2, 4, 58, 20, }, + { 2, 1, 2, 4, 58, 30, }, + { 1, 1, 2, 4, 58, 28, }, + { 0, 1, 2, 4, 106, 20, }, + { 2, 1, 2, 4, 106, 30, }, + { 1, 1, 2, 4, 106, 30, }, + { 0, 1, 2, 4, 122, 30, }, + { 2, 1, 2, 4, 122, 30, }, + { 1, 1, 2, 4, 122, 30, }, + { 0, 1, 2, 4, 138, 30, }, + { 2, 1, 2, 4, 138, 63, }, + { 1, 1, 2, 4, 138, 63, }, + { 0, 1, 2, 4, 155, 30, }, + { 2, 1, 2, 4, 155, 63, }, + { 1, 1, 2, 4, 155, 63, }, + { 0, 1, 2, 5, 42, 18, }, + { 2, 1, 2, 5, 42, 20, }, + { 1, 1, 2, 5, 42, 22, }, + { 0, 1, 2, 5, 58, 18, }, + { 2, 1, 2, 5, 58, 20, }, + { 1, 1, 2, 5, 58, 22, }, + { 0, 1, 2, 5, 106, 20, }, + { 2, 1, 2, 5, 106, 20, }, + { 1, 1, 2, 5, 106, 30, }, + { 0, 1, 2, 5, 122, 30, }, + { 2, 1, 2, 5, 122, 20, }, + { 1, 1, 2, 5, 122, 30, }, + { 0, 1, 2, 5, 138, 30, }, + { 2, 1, 2, 5, 138, 63, }, + { 1, 1, 2, 5, 138, 63, }, + { 0, 1, 2, 5, 155, 30, }, + { 2, 1, 2, 5, 155, 63, }, + { 1, 1, 2, 5, 155, 63, }, +}; + +RTW_DECL_TABLE_TXPWR_LMT(rtw8822b_txpwr_lmt_type0); + static const struct rtw_txpwr_lmt_cfg_pair rtw8822b_txpwr_lmt_type2[] = { { 0, 0, 0, 0, 1, 32, }, { 2, 0, 0, 0, 1, 28, }, --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822b_table.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822b_table.h @@ -9,9 +9,11 @@ extern const struct rtw_table rtw8822b_agc_tbl; extern const struct rtw_table rtw8822b_bb_tbl; extern const struct rtw_table rtw8822b_bb_pg_type2_tbl; +extern const struct rtw_table rtw8822b_bb_pg_type3_tbl; extern const struct rtw_table rtw8822b_bb_pg_type5_tbl; extern const struct rtw_table rtw8822b_rf_a_tbl; extern const struct rtw_table rtw8822b_rf_b_tbl; +extern const struct rtw_table rtw8822b_txpwr_lmt_type0_tbl; extern const struct rtw_table rtw8822b_txpwr_lmt_type2_tbl; extern const struct rtw_table rtw8822b_txpwr_lmt_type5_tbl; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -14,6 +14,7 @@ #include "reg.h" #include "debug.h" #include "util.h" +#include "bf.h" static void rtw8822c_config_trx_mode(struct rtw_dev *rtwdev, u8 tx_path, u8 rx_path, bool is_tx2_path); @@ -40,6 +41,11 @@ efuse->country_code[1] = map->country_code[1]; efuse->bt_setting = map->rf_bt_setting; efuse->regd = map->rf_board_option & 0x7; + efuse->thermal_meter[RF_PATH_A] = map->path_a_thermal; + efuse->thermal_meter[RF_PATH_B] = map->path_b_thermal; + efuse->thermal_meter_k = + (map->path_a_thermal + map->path_b_thermal) >> 1; + efuse->power_track_type = (map->tx_pwr_calibrate_rate >> 4) & 0xf; for (i = 0; i < 4; i++) efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; @@ -1000,6 +1006,21 @@ rtw8822c_rf_x2_check(rtwdev); } +static void rtw8822c_pwrtrack_init(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 path; + + for (path = RF_PATH_A; path < RTW_RF_PATH_MAX; path++) { + dm_info->delta_power_index[path] = 0; + ewma_thermal_init(&dm_info->avg_thermal[path]); + dm_info->thermal_avg[path] = 0xff; + } + + dm_info->pwr_trk_triggered = false; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; +} + static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; @@ -1047,6 +1068,9 @@ dm_info->cck_gi_l_bnd = ((cck_gi_l_bnd_msb << 4) | (cck_gi_l_bnd_lsb)); rtw8822c_rf_init(rtwdev); + rtw8822c_pwrtrack_init(rtwdev); + + rtw_bf_phy_init(rtwdev); } #define WLAN_TXQ_RPT_EN 0x1F @@ -1088,8 +1112,8 @@ #define WLAN_AMPDU_MAX_TIME 0x70 #define WLAN_RTS_LEN_TH 0xFF #define WLAN_RTS_TX_TIME_TH 0x08 -#define WLAN_MAX_AGG_PKT_LIMIT 0x20 -#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x20 +#define WLAN_MAX_AGG_PKT_LIMIT 0x3f +#define WLAN_RTS_MAX_AGG_PKT_LIMIT 0x3f #define WLAN_PRE_TXCNT_TIME_TH 0x1E0 #define FAST_EDCA_VO_TH 0x06 #define FAST_EDCA_VI_TH 0x06 @@ -1112,6 +1136,7 @@ #define WLAN_RTS_RATE_FB_RATE4_H 0x400003E0 #define WLAN_RTS_RATE_FB_RATE5 0x0600F015 #define WLAN_RTS_RATE_FB_RATE5_H 0x000000E0 +#define WLAN_MULTI_ADDR 0xFFFFFFFF #define WLAN_TX_FUNC_CFG1 0x30 #define WLAN_TX_FUNC_CFG2 0x30 @@ -1221,6 +1246,8 @@ rtw_write8(rtwdev, REG_BCN_MAX_ERR, WLAN_BCN_MAX_ERR); /* WMAC configuration */ + rtw_write32(rtwdev, REG_MAR, WLAN_MULTI_ADDR); + rtw_write32(rtwdev, REG_MAR + 4, WLAN_MULTI_ADDR); rtw_write8(rtwdev, REG_BBPSF_CTRL + 2, WLAN_RESP_TXRATE); rtw_write8(rtwdev, REG_ACKTO, WLAN_ACK_TO); rtw_write8(rtwdev, REG_ACKTO_CCK, WLAN_ACK_TO_CCK); @@ -1262,6 +1289,17 @@ return 0; } +static void rtw8822c_rstb_3wire(struct rtw_dev *rtwdev, bool enable) +{ + if (enable) { + rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x1); + rtw_write32_mask(rtwdev, REG_ANAPAR_A, BIT_ANAPAR_UPDATE, 0x1); + rtw_write32_mask(rtwdev, REG_ANAPAR_B, BIT_ANAPAR_UPDATE, 0x1); + } else { + rtw_write32_mask(rtwdev, REG_RSTB, BIT_RSTB_3WIRE, 0x0); + } +} + static void rtw8822c_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) { #define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) @@ -1284,11 +1322,11 @@ rf_reg18 &= ~(RF18_BAND_MASK | RF18_CHANNEL_MASK | RF18_RFSI_MASK | RF18_BW_MASK); - rf_reg18 |= (channel <= 14 ? RF18_BAND_2G : RF18_BAND_5G); + rf_reg18 |= (IS_CH_2G_BAND(channel) ? RF18_BAND_2G : RF18_BAND_5G); rf_reg18 |= (channel & RF18_CHANNEL_MASK); - if (channel > 144) + if (IS_CH_5G_BAND_4(channel)) rf_reg18 |= RF18_RFSI_GT_CH140; - else if (channel >= 80) + else if (IS_CH_5G_BAND_3(channel)) rf_reg18 |= RF18_RFSI_GE_CH80; switch (bw) { @@ -1310,6 +1348,8 @@ break; } + rtw8822c_rstb_3wire(rtwdev, false); + rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE2, 0x04, 0x01); rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWA, 0x1f, 0x12); rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWD0, 0xfffff, rf_rxbb); @@ -1322,6 +1362,8 @@ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, rf_reg18); rtw_write_rf(rtwdev, RF_PATH_B, RF_CFGCH, RFREG_MASK, rf_reg18); + + rtw8822c_rstb_3wire(rtwdev, true); } static void rtw8822c_toggle_igi(struct rtw_dev *rtwdev) @@ -1338,7 +1380,7 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, u8 primary_ch_idx) { - if (channel <= 14) { + if (IS_CH_2G_BAND(channel)) { rtw_write32_clr(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x8); rtw_write32_set(rtwdev, REG_TXF4, BIT(20)); @@ -1403,7 +1445,7 @@ rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); else rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x1); - } else if (channel > 35) { + } else if (IS_CH_5G_BAND(channel)) { rtw_write32_set(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); rtw_write32_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); rtw_write32_set(rtwdev, REG_BGCTRL, BITS_RX_IQ_WEIGHT); @@ -1411,17 +1453,17 @@ rtw_write32_mask(rtwdev, REG_RXCCKSEL, 0xf0000000, 0x0); rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22); rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); - if (channel >= 36 && channel <= 64) { + if (IS_CH_5G_BAND_1(channel) || IS_CH_5G_BAND_2(channel)) { rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 0x1); rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 0x1); - } else if (channel >= 100 && channel <= 144) { + } else if (IS_CH_5G_BAND_3(channel)) { rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 0x2); rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, 0x2); - } else if (channel >= 149) { + } else if (IS_CH_5G_BAND_4(channel)) { rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, 0x3); rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, @@ -1455,7 +1497,7 @@ break; case RTW_CHANNEL_WIDTH_40: rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4), - (primary_ch_idx == 1 ? 1 : 0)); + (primary_ch_idx == RTW_SC_20_UPPER ? 1 : 0)); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0x5); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, @@ -1616,6 +1658,8 @@ u8 gain_a, gain_b; s8 rx_power[RTW_RF_PATH_MAX]; s8 min_rx_power = -120; + u8 rssi; + int path; rx_power[RF_PATH_A] = GET_PHY_STAT_P0_PWDB_A(phy_status); rx_power[RF_PATH_B] = GET_PHY_STAT_P0_PWDB_B(phy_status); @@ -1638,6 +1682,11 @@ pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + } + pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); pkt_stat->bw = RTW_CHANNEL_WIDTH_20; pkt_stat->signal_power = max(pkt_stat->rx_power[RF_PATH_A], @@ -1647,20 +1696,27 @@ static void query_phy_status_page1(struct rtw_dev *rtwdev, u8 *phy_status, struct rtw_rx_pkt_stat *pkt_stat) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u8 rxsc, bw; s8 min_rx_power = -120; + s8 rx_evm; + u8 evm_dbm = 0; + u8 rssi; + int path; if (pkt_stat->rate > DESC_RATE11M && pkt_stat->rate < DESC_RATEMCS0) rxsc = GET_PHY_STAT_P1_L_RXSC(phy_status); else rxsc = GET_PHY_STAT_P1_HT_RXSC(phy_status); - if (rxsc >= 9 && rxsc <= 12) + if (rxsc == 0) + bw = rtwdev->hal.current_band_width; + else if (rxsc >= 1 && rxsc <= 8) + bw = RTW_CHANNEL_WIDTH_20; + else if (rxsc >= 9 && rxsc <= 12) bw = RTW_CHANNEL_WIDTH_40; - else if (rxsc >= 13) - bw = RTW_CHANNEL_WIDTH_80; else - bw = RTW_CHANNEL_WIDTH_20; + bw = RTW_CHANNEL_WIDTH_80; pkt_stat->rx_power[RF_PATH_A] = GET_PHY_STAT_P1_PWDB_A(phy_status) - 110; pkt_stat->rx_power[RF_PATH_B] = GET_PHY_STAT_P1_PWDB_B(phy_status) - 110; @@ -1669,6 +1725,34 @@ pkt_stat->signal_power = max3(pkt_stat->rx_power[RF_PATH_A], pkt_stat->rx_power[RF_PATH_B], min_rx_power); + + dm_info->curr_rx_rate = pkt_stat->rate; + + pkt_stat->rx_evm[RF_PATH_A] = GET_PHY_STAT_P1_RXEVM_A(phy_status); + pkt_stat->rx_evm[RF_PATH_B] = GET_PHY_STAT_P1_RXEVM_B(phy_status); + + pkt_stat->rx_snr[RF_PATH_A] = GET_PHY_STAT_P1_RXSNR_A(phy_status); + pkt_stat->rx_snr[RF_PATH_B] = GET_PHY_STAT_P1_RXSNR_B(phy_status); + + pkt_stat->cfo_tail[RF_PATH_A] = GET_PHY_STAT_P1_CFO_TAIL_A(phy_status); + pkt_stat->cfo_tail[RF_PATH_B] = GET_PHY_STAT_P1_CFO_TAIL_B(phy_status); + + for (path = 0; path <= rtwdev->hal.rf_path_num; path++) { + rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[path], 1); + dm_info->rssi[path] = rssi; + dm_info->rx_snr[path] = pkt_stat->rx_snr[path] >> 1; + dm_info->cfo_tail[path] = (pkt_stat->cfo_tail[path] * 5) >> 1; + + rx_evm = pkt_stat->rx_evm[path]; + + if (rx_evm < 0) { + if (rx_evm == S8_MIN) + evm_dbm = 0; + else + evm_dbm = ((u8)-rx_evm >> 1); + } + dm_info->rx_evm_dbm[path] = evm_dbm; + } } static void query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, @@ -1704,7 +1788,8 @@ pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); - pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc); + pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && + GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); @@ -1822,6 +1907,7 @@ u32 cck_enable; u32 cck_fa_cnt; u32 crc32_cnt; + u32 cca32_cnt; u32 ofdm_fa_cnt; u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, @@ -1866,6 +1952,13 @@ dm_info->vht_ok_cnt = crc32_cnt & 0xffff; dm_info->vht_err_cnt = (crc32_cnt & 0xffff0000) >> 16; + cca32_cnt = rtw_read32(rtwdev, 0x2c08); + dm_info->ofdm_cca_cnt = ((cca32_cnt & 0xffff0000) >> 16); + dm_info->cck_cca_cnt = cca32_cnt & 0xffff; + dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; + if (cck_enable) + dm_info->total_cca_cnt += dm_info->cck_cca_cnt; + rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 0); rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2); rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0); @@ -2053,6 +2146,57 @@ } } +static void rtw8822c_bf_enable_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee) +{ + u8 csi_rsc = 0; + u32 tmp6dc; + + rtw_bf_enable_bfee_su(rtwdev, vif, bfee); + + tmp6dc = rtw_read32(rtwdev, REG_BBPSF_CTRL) | + BIT_WMAC_USE_NDPARATE | + (csi_rsc << 13); + if (vif->net_type == RTW_NET_AP_MODE) + rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc | BIT(12)); + else + rtw_write32(rtwdev, REG_BBPSF_CTRL, tmp6dc & ~BIT(12)); + + rtw_write32(rtwdev, REG_CSI_RRSR, 0x550); +} + +static void rtw8822c_bf_config_bfee_su(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw8822c_bf_enable_bfee_su(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_su(rtwdev, bfee); +} + +static void rtw8822c_bf_config_bfee_mu(struct rtw_dev *rtwdev, + struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (enable) + rtw_bf_enable_bfee_mu(rtwdev, vif, bfee); + else + rtw_bf_remove_bfee_mu(rtwdev, bfee); +} + +static void rtw8822c_bf_config_bfee(struct rtw_dev *rtwdev, struct rtw_vif *vif, + struct rtw_bfee *bfee, bool enable) +{ + if (bfee->role == RTW_BFEE_SU) + rtw8822c_bf_config_bfee_su(rtwdev, vif, bfee, enable); + else if (bfee->role == RTW_BFEE_MU) + rtw8822c_bf_config_bfee_mu(rtwdev, vif, bfee, enable); + else + rtw_warn(rtwdev, "wrong bfee role\n"); +} + struct dpk_cfg_pair { u32 addr; u32 bitmask; @@ -2603,9 +2747,9 @@ { if (coef_i == 0x1000 || coef_i == 0x0fff || coef_q == 0x1000 || coef_q == 0x0fff) - return 1; - else - return 0; + return true; + + return false; } static u32 rtw8822c_dpk_coef_transfer(struct rtw_dev *rtwdev) @@ -2843,7 +2987,7 @@ dpk_info->dpk_gs[path] = tmp_gs; } -void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) +static void rtw8822c_dpk_cal_coef1(struct rtw_dev *rtwdev) { struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; u32 offset[DPK_RF_PATH_NUM] = {0, 0x58}; @@ -3084,7 +3228,7 @@ rtw8822c_do_dpk(rtwdev); } -void rtw8822c_dpk_track(struct rtw_dev *rtwdev) +static void rtw8822c_dpk_track(struct rtw_dev *rtwdev) { struct rtw_dpk_info *dpk_info = &rtwdev->dm_info.dpk_info; u8 path; @@ -3168,8 +3312,8 @@ static void rtw8822c_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) { struct rtw_dm_info *dm_info = &rtwdev->dm_info; - s8 pd_lvl[4] = {2, 4, 6, 8}; - s8 cs_lvl[4] = {2, 2, 2, 4}; + s8 pd_lvl[CCK_PD_LV_MAX] = {0, 2, 4, 6, 8}; + s8 cs_lvl[CCK_PD_LV_MAX] = {0, 2, 2, 2, 4}; u8 cur_lvl; u8 nrx, bw; @@ -3191,6 +3335,118 @@ dm_info->cck_pd_lv[bw][nrx] = new_lvl; } +#define PWR_TRACK_MASK 0x7f +static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + switch (rf_path) { + case RF_PATH_A: + rtw_write32_mask(rtwdev, 0x18a0, PWR_TRACK_MASK, + dm_info->delta_power_index[rf_path]); + break; + case RF_PATH_B: + rtw_write32_mask(rtwdev, 0x41a0, PWR_TRACK_MASK, + dm_info->delta_power_index[rf_path]); + break; + default: + break; + } +} + +static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 thermal_value, delta; + + if (rtwdev->efuse.thermal_meter[path] == 0xff) + return; + + thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); + + rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); + + delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); + + dm_info->delta_power_index[path] = + rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, + delta); + + rtw8822c_pwrtrack_set(rtwdev, path); +} + +static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_swing_table swing_table; + u8 i; + + rtw_phy_config_swing_table(rtwdev, &swing_table); + + for (i = 0; i < rtwdev->hal.rf_path_num; i++) + rtw8822c_pwr_track_path(rtwdev, &swing_table, i); + + if (rtw_phy_pwrtrack_need_iqk(rtwdev)) + rtw8822c_do_iqk(rtwdev); +} + +static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) +{ + struct rtw_efuse *efuse = &rtwdev->efuse; + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + + if (efuse->power_track_type != 0) + return; + + if (!dm_info->pwr_trk_triggered) { + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x00); + rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, BIT(19), 0x01); + + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x00); + rtw_write_rf(rtwdev, RF_PATH_B, RF_T_METER, BIT(19), 0x01); + + dm_info->pwr_trk_triggered = true; + return; + } + + __rtw8822c_pwr_track(rtwdev); + dm_info->pwr_trk_triggered = false; +} + +static void rtw8822c_adaptivity_init(struct rtw_dev *rtwdev) +{ + rtw_phy_set_edcca_th(rtwdev, 0x7f, 0x7f); + /* mac edcca state setting */ + rtw_write32_mask(rtwdev, REG_TX_PTCL_CTRL, BIT_DIS_EDCCA, 0); + rtw_write32_mask(rtwdev, REG_RD_CTRL, BIT_EDCCA_MSK_CNTDOWN_EN, 1); + /* edcca decistion opt */ + rtw_write32_mask(rtwdev, REG_EDCCA_DECISION, BIT_EDCCA_OPTION, 0); +} + +static void rtw8822c_adaptivity(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + s8 l2h, h2l; + u8 igi; + + igi = dm_info->igi_history[0]; + if (dm_info->edcca_mode == RTW_EDCCA_NORMAL) { + l2h = max_t(s8, igi + EDCCA_IGI_L2H_DIFF, EDCCA_TH_L2H_LB); + h2l = l2h - EDCCA_L2H_H2L_DIFF_NORMAL; + } else { + if (igi < dm_info->l2h_th_ini - EDCCA_ADC_BACKOFF) + l2h = igi + EDCCA_ADC_BACKOFF; + else + l2h = dm_info->l2h_th_ini; + h2l = l2h - EDCCA_L2H_H2L_DIFF; + } + + rtw_phy_set_edcca_th(rtwdev, l2h, h2l); +} + static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8822c[] = { {0x0086, RTW_PWR_CUT_ALL_MSK, @@ -3279,12 +3535,12 @@ RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, RTW_PWR_ADDR_MAC, - RTW_PWR_CMD_WRITE, BIT(7), 0}, - {0x0005, + RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + {0x1018, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, RTW_PWR_ADDR_MAC, - RTW_PWR_CMD_WRITE, (BIT(4) | BIT(3)), 0}, + RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, {0x0005, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, @@ -3336,6 +3592,11 @@ RTW_PWR_INTF_ALL_MSK, RTW_PWR_ADDR_MAC, RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, + {0x1064, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, + RTW_PWR_ADDR_MAC, + RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, {0xFFFF, RTW_PWR_CUT_ALL_MSK, RTW_PWR_INTF_ALL_MSK, @@ -3531,6 +3792,12 @@ [1] = { .addr = 0x1d70, .mask = 0x7f00 }, }; +static struct rtw_ltecoex_addr rtw8822c_ltecoex_addr = { + .ctrl = LTECOEX_ACCESS_CTRL, + .wdata = LTECOEX_WRITE_DATA, + .rdata = LTECOEX_READ_DATA, +}; + static struct rtw_page_table page_table_8822c[] = { {64, 64, 64, 64, 1}, {64, 64, 64, 64, 1}, @@ -3557,6 +3824,22 @@ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, }; +static struct rtw_prioq_addrs prioq_addrs_8822c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, + .prio[RTW_DMA_MAPPING_LOW] = { + .rsvd = REG_FIFOPAGE_INFO_2, .avail = REG_FIFOPAGE_INFO_2 + 2, + }, + .prio[RTW_DMA_MAPPING_NORMAL] = { + .rsvd = REG_FIFOPAGE_INFO_3, .avail = REG_FIFOPAGE_INFO_3 + 2, + }, + .prio[RTW_DMA_MAPPING_HIGH] = { + .rsvd = REG_FIFOPAGE_INFO_1, .avail = REG_FIFOPAGE_INFO_1 + 2, + }, + .wsize = true, +}; + static struct rtw_chip_ops rtw8822c_ops = { .phy_set_param = rtw8822c_phy_set_param, .read_efuse = rtw8822c_read_efuse, @@ -3571,6 +3854,12 @@ .dpk_track = rtw8822c_dpk_track, .phy_calibration = rtw8822c_phy_calibration, .cck_pd_set = rtw8822c_phy_cck_pd_set, + .pwr_track = rtw8822c_pwr_track, + .config_bfee = rtw8822c_bf_config_bfee, + .set_gid_table = rtw_bf_set_gid_table, + .cfg_csi_rate = rtw_bf_cfg_csi_rate, + .adaptivity_init = rtw8822c_adaptivity_init, + .adaptivity = rtw8822c_adaptivity, .coex_set_init = rtw8822c_coex_cfg_init, .coex_set_ant_switch = NULL, @@ -3725,10 +4014,180 @@ static_assert(ARRAY_SIZE(rf_para_tx_8822c) == ARRAY_SIZE(rf_para_rx_8822c)); +static const u8 +rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, + { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 32 }, +}; + +static const u8 +rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 22, 23, 24, 25, 26, 27 }, +}; + +static const u8 +rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, + { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, + 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 33 }, +}; + +static const u8 +rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_NUM][RTW_PWR_TRK_TBL_SZ] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, +}; + +static const u8 rtw8822c_pwrtrk_2gb_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, + 9, 9, 10, 11, 12, 13, 14, 15, 15, 16, + 17, 18, 19, 20, 20, 21, 22, 23, 24, 25 +}; + +static const u8 rtw8822c_pwrtrk_2gb_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 +}; + +static const u8 rtw8822c_pwrtrk_2ga_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, + 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, + 13, 14, 15, 15, 16, 17, 17, 18, 19, 19 +}; + +static const u8 rtw8822c_pwrtrk_2ga_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 25, 26, 27 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_b_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, + 17, 18, 19, 20, 21, 22, 23, 23, 24, 25 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_b_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_a_n[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, + 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, + 15, 16, 17, 18, 18, 19, 20, 21, 21, 22 +}; + +static const u8 rtw8822c_pwrtrk_2g_cck_a_p[RTW_PWR_TRK_TBL_SZ] = { + 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, + 9, 10, 11, 11, 12, 13, 14, 15, 16, 17, + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 +}; + +static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_p[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_n[RTW_PWR_TRK_5G_3], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_1], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_2], + .pwrtrk_5ga_p[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5ga_p[RTW_PWR_TRK_5G_3], + .pwrtrk_2gb_n = rtw8822c_pwrtrk_2gb_n, + .pwrtrk_2gb_p = rtw8822c_pwrtrk_2gb_p, + .pwrtrk_2ga_n = rtw8822c_pwrtrk_2ga_n, + .pwrtrk_2ga_p = rtw8822c_pwrtrk_2ga_p, + .pwrtrk_2g_cckb_n = rtw8822c_pwrtrk_2g_cck_b_n, + .pwrtrk_2g_cckb_p = rtw8822c_pwrtrk_2g_cck_b_p, + .pwrtrk_2g_ccka_n = rtw8822c_pwrtrk_2g_cck_a_n, + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, +}; + +static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 + }, + [EDCCA_TH_H2L_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE3}, .offset = 0x80 + }, +}; + +#ifdef CONFIG_PM +static const struct wiphy_wowlan_support rtw_wowlan_stub_8822c = { + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_NET_DETECT, + .n_patterns = RTW_MAX_PATTERN_NUM, + .pattern_max_len = RTW_MAX_PATTERN_SIZE, + .pattern_min_len = 1, + .max_nd_match_sets = 4, +}; +#endif + +static const struct rtw_reg_domain coex_info_hw_regs_8822c[] = { + {0x1860, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x4160, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x1c32, BIT(6), RTW_REG_DOMAIN_MAC8}, + {0x1c38, BIT(28), RTW_REG_DOMAIN_MAC32}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, + {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, + {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, + {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, + {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, + {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_B}, + {0, 0, RTW_REG_DOMAIN_NL}, + {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, +}; + struct rtw_chip_info rtw8822c_hw_spec = { .ops = &rtw8822c_ops, .id = RTW_CHIP_TYPE_8822C, .fw_name = "rtw88/rtw8822c_fw.bin", + .wlan_cpu = RTW_WCPU_11AC, .tx_pkt_desc_sz = 48, .tx_buf_desc_sz = 16, .rx_pkt_desc_sz = 24, @@ -3747,15 +4206,19 @@ .dig_min = 0x20, .ht_supported = true, .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK) | BIT(LPS_DEEP_MODE_PG), .sys_func_en = 0xD8, .pwr_on_seq = card_enable_flow_8822c, .pwr_off_seq = card_disable_flow_8822c, .page_table = page_table_8822c, .rqpn_table = rqpn_table_8822c, + .prioq_addrs = &prioq_addrs_8822c, .intf_table = &phy_para_table_8822c, .dig = rtw8822c_dig, + .dig_cck = NULL, .rf_base_addr = {0x3c00, 0x4c00}, .rf_sipi_addr = {0x1808, 0x4108}, + .ltecoex_addr = &rtw8822c_ltecoex_addr, .mac_tbl = &rtw8822c_mac_tbl, .agc_tbl = &rtw8822c_agc_tbl, .bb_tbl = &rtw8822c_bb_tbl, @@ -3765,7 +4228,19 @@ .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), .en_dis_dpd = true, .dpd_ratemask = DIS_DPD_RATEALL, - + .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, + .edcca_th = rtw8822c_edcca_th, + .l2h_th_ini_cs = 60, + .l2h_th_ini_ad = 45, + +#ifdef CONFIG_PM + .wow_fw_name = "rtw88/rtw8822c_wow_fw.bin", + .wowlan_stub = &rtw_wowlan_stub_8822c, + .max_sched_scan_ssids = 4, +#endif .coex_para_ver = 0x19062706, .bt_desired_ver = 0x6, .scbd_support = true, @@ -3791,7 +4266,11 @@ .bt_afh_span_bw40 = 0x36, .afh_5g_num = ARRAY_SIZE(afh_5g_8822c), .afh_5g = afh_5g_8822c, + + .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8822c), + .coex_info_hw_regs = coex_info_hw_regs_8822c, }; EXPORT_SYMBOL(rtw8822c_hw_spec); MODULE_FIRMWARE("rtw88/rtw8822c_fw.bin"); +MODULE_FIRMWARE("rtw88/rtw8822c_wow_fw.bin"); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822c.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822c.h @@ -149,6 +149,18 @@ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(11, 8)) #define GET_PHY_STAT_P1_HT_RXSC(phy_stat) \ le32_get_bits(*((__le32 *)(phy_stat) + 0x01), GENMASK(15, 12)) +#define GET_PHY_STAT_P1_RXEVM_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXEVM_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x04), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_CFO_TAIL_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_CFO_TAIL_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x05), GENMASK(15, 8)) +#define GET_PHY_STAT_P1_RXSNR_A(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(7, 0)) +#define GET_PHY_STAT_P1_RXSNR_B(phy_stat) \ + le32_get_bits(*((__le32 *)(phy_stat) + 0x06), GENMASK(15, 8)) #define REG_ANAPARLDO_POW_MAC 0x0029 #define BIT_LDOE25_PON BIT(0) @@ -159,6 +171,8 @@ #define REG_DFIRBW 0x810 #define REG_ANTMAP0 0x820 #define REG_ANTMAP 0x824 +#define REG_EDCCA_DECISION 0x844 +#define BIT_EDCCA_OPTION GENMASK(30, 29) #define REG_DYMPRITH 0x86c #define REG_DYMENTH0 0x870 #define REG_DYMENTH 0x874 @@ -178,6 +192,8 @@ #define BIT_3WIRE_TX_EN BIT(0) #define BIT_3WIRE_RX_EN BIT(1) #define BIT_3WIRE_PI_ON BIT(28) +#define REG_ANAPAR_A 0x1830 +#define BIT_ANAPAR_UPDATE BIT(29) #define REG_RXAGCCTL0 0x18ac #define BITS_RXAGC_CCK GENMASK(15, 12) #define BITS_RXAGC_OFDM GENMASK(8, 4) @@ -211,6 +227,8 @@ #define BIT_CCK_BLK_EN BIT(1) #define BIT_CCK_OFDM_BLK_EN (BIT(0) | BIT(1)) #define REG_CCAMSK 0x1c80 +#define REG_RSTB 0x1c90 +#define BIT_RSTB_3WIRE BIT(8) #define REG_RX_BREAK 0x1d2c #define BIT_COM_RX_GCK_EN BIT(31) #define REG_RXFNCTL 0x1d30 @@ -231,6 +249,7 @@ #define REG_OFDM_TXCNT 0x2de0 #define REG_ORITXCODE2 0x4100 #define REG_3WIRE2 0x410c +#define REG_ANAPAR_B 0x4130 #define REG_RXAGCCTL 0x41ac #define REG_DCKB_I_0 0x41bc #define REG_DCKB_I_1 0x41c0 --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c @@ -1762,53 +1762,53 @@ RTW_DECL_TABLE_PHY_COND(rtw8822c_bb, rtw_phy_cfg_bb); -static const u32 rtw8822c_bb_pg_type0[] = { - 0, 0, 0, 0x00000c20, 0xffffffff, 0x484c5054, - 0, 0, 0, 0x00000c24, 0xffffffff, 0x54585c60, - 0, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, - 0, 0, 0, 0x00000c2c, 0xffffffff, 0x5054585c, - 0, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, - 0, 0, 1, 0x00000c34, 0xffffffff, 0x5054585c, - 0, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, - 0, 0, 0, 0x00000c3c, 0xffffffff, 0x5054585c, - 0, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, - 0, 0, 0, 0x00000c44, 0xffffffff, 0x585c383c, - 0, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, - 0, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, - 0, 1, 0, 0x00000e20, 0xffffffff, 0x484c5054, - 0, 1, 0, 0x00000e24, 0xffffffff, 0x54585c60, - 0, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, - 0, 1, 0, 0x00000e2c, 0xffffffff, 0x5054585c, - 0, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, - 0, 1, 1, 0x00000e34, 0xffffffff, 0x5054585c, - 0, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, - 0, 1, 0, 0x00000e3c, 0xffffffff, 0x5054585c, - 0, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, - 0, 1, 0, 0x00000e44, 0xffffffff, 0x585c383c, - 0, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, - 0, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044, - 1, 0, 0, 0x00000c24, 0xffffffff, 0x54585c60, - 1, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, - 1, 0, 0, 0x00000c2c, 0xffffffff, 0x5054585c, - 1, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, - 1, 0, 1, 0x00000c34, 0xffffffff, 0x5054585c, - 1, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, - 1, 0, 0, 0x00000c3c, 0xffffffff, 0x5054585c, - 1, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, - 1, 0, 0, 0x00000c44, 0xffffffff, 0x585c383c, - 1, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, - 1, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, - 1, 1, 0, 0x00000e24, 0xffffffff, 0x54585c60, - 1, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, - 1, 1, 0, 0x00000e2c, 0xffffffff, 0x5054585c, - 1, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, - 1, 1, 1, 0x00000e34, 0xffffffff, 0x5054585c, - 1, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, - 1, 1, 0, 0x00000e3c, 0xffffffff, 0x5054585c, - 1, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, - 1, 1, 0, 0x00000e44, 0xffffffff, 0x585c383c, - 1, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, - 1, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044 +static const struct rtw_phy_pg_cfg_pair rtw8822c_bb_pg_type0[] = { + { 0, 0, 0, 0x00000c20, 0xffffffff, 0x484c5054, }, + { 0, 0, 0, 0x00000c24, 0xffffffff, 0x54585c60, }, + { 0, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, }, + { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x5054585c, }, + { 0, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, }, + { 0, 0, 1, 0x00000c34, 0xffffffff, 0x5054585c, }, + { 0, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, }, + { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x5054585c, }, + { 0, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, }, + { 0, 0, 0, 0x00000c44, 0xffffffff, 0x585c383c, }, + { 0, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, }, + { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, }, + { 0, 1, 0, 0x00000e20, 0xffffffff, 0x484c5054, }, + { 0, 1, 0, 0x00000e24, 0xffffffff, 0x54585c60, }, + { 0, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, }, + { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x5054585c, }, + { 0, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, }, + { 0, 1, 1, 0x00000e34, 0xffffffff, 0x5054585c, }, + { 0, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, }, + { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x5054585c, }, + { 0, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, }, + { 0, 1, 0, 0x00000e44, 0xffffffff, 0x585c383c, }, + { 0, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, }, + { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044, }, + { 1, 0, 0, 0x00000c24, 0xffffffff, 0x54585c60, }, + { 1, 0, 0, 0x00000c28, 0xffffffff, 0x44484c50, }, + { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x5054585c, }, + { 1, 0, 0, 0x00000c30, 0xffffffff, 0x4044484c, }, + { 1, 0, 1, 0x00000c34, 0xffffffff, 0x5054585c, }, + { 1, 0, 1, 0x00000c38, 0xffffffff, 0x4044484c, }, + { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x5054585c, }, + { 1, 0, 0, 0x00000c40, 0xffffffff, 0x4044484c, }, + { 1, 0, 0, 0x00000c44, 0xffffffff, 0x585c383c, }, + { 1, 0, 1, 0x00000c48, 0xffffffff, 0x484c5054, }, + { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x383c4044, }, + { 1, 1, 0, 0x00000e24, 0xffffffff, 0x54585c60, }, + { 1, 1, 0, 0x00000e28, 0xffffffff, 0x44484c50, }, + { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x5054585c, }, + { 1, 1, 0, 0x00000e30, 0xffffffff, 0x4044484c, }, + { 1, 1, 1, 0x00000e34, 0xffffffff, 0x5054585c, }, + { 1, 1, 1, 0x00000e38, 0xffffffff, 0x4044484c, }, + { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x5054585c, }, + { 1, 1, 0, 0x00000e40, 0xffffffff, 0x4044484c, }, + { 1, 1, 0, 0x00000e44, 0xffffffff, 0x585c383c, }, + { 1, 1, 1, 0x00000e48, 0xffffffff, 0x484c5054, }, + { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x383c4044, }, }; RTW_DECL_TABLE_BB_PG(rtw8822c_bb_pg_type0); --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rx.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rx.c @@ -5,6 +5,7 @@ #include "main.h" #include "rx.h" #include "ps.h" +#include "debug.h" void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, struct sk_buff *skb) @@ -25,8 +26,6 @@ rtwvif = (struct rtw_vif *)vif->drv_priv; rtwvif->stats.rx_unicast += skb->len; rtwvif->stats.rx_cnt++; - if (rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD) - rtw_leave_lps_irqsafe(rtwdev, rtwvif); } } } @@ -39,6 +38,60 @@ u8 *bssid; }; +static void rtw_rx_phy_stat(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + struct rtw_pkt_count *cur_pkt_cnt = &dm_info->cur_pkt_count; + u8 rate_ss, rate_ss_evm, evm_id; + u8 i, idx; + + dm_info->curr_rx_rate = pkt_stat->rate; + + if (ieee80211_is_beacon(hdr->frame_control)) + cur_pkt_cnt->num_bcn_pkt++; + + switch (pkt_stat->rate) { + case DESC_RATE1M...DESC_RATE11M: + goto pkt_num; + case DESC_RATE6M...DESC_RATE54M: + rate_ss = 0; + rate_ss_evm = 1; + evm_id = RTW_EVM_OFDM; + break; + case DESC_RATEMCS0...DESC_RATEMCS7: + case DESC_RATEVHT1SS_MCS0...DESC_RATEVHT1SS_MCS9: + rate_ss = 1; + rate_ss_evm = 1; + evm_id = RTW_EVM_1SS; + break; + case DESC_RATEMCS8...DESC_RATEMCS15: + case DESC_RATEVHT2SS_MCS0...DESC_RATEVHT2SS_MCS9: + rate_ss = 2; + rate_ss_evm = 2; + evm_id = RTW_EVM_2SS_A; + break; + default: + rtw_warn(rtwdev, "unknown pkt rate = %d\n", pkt_stat->rate); + return; + } + + for (i = 0; i < rate_ss_evm; i++) { + idx = evm_id + i; + ewma_evm_add(&dm_info->ewma_evm[idx], + dm_info->rx_evm_dbm[i]); + } + + for (i = 0; i < rtwdev->hal.rf_path_num; i++) { + idx = RTW_SNR_OFDM_A + 4 * rate_ss + i; + ewma_snr_add(&dm_info->ewma_snr[idx], + dm_info->rx_snr[i]); + } +pkt_num: + cur_pkt_cnt->num_qry_pkt[pkt_stat->rate]++; +} + static void rtw_rx_addr_match_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { @@ -50,14 +103,16 @@ struct rtw_rx_pkt_stat *pkt_stat = iter_data->pkt_stat; u8 *bssid = iter_data->bssid; - if (ether_addr_equal(vif->bss_conf.bssid, bssid) && - (ether_addr_equal(vif->addr, hdr->addr1) || - ieee80211_is_beacon(hdr->frame_control))) - sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2, - vif->addr); - else + if (!ether_addr_equal(vif->bss_conf.bssid, bssid)) return; + if (!(ether_addr_equal(vif->addr, hdr->addr1) || + ieee80211_is_beacon(hdr->frame_control))) + return; + + rtw_rx_phy_stat(rtwdev, pkt_stat, hdr); + sta = ieee80211_find_sta_by_ifaddr(rtwdev->hw, hdr->addr2, + vif->addr); if (!sta) return; @@ -105,35 +160,17 @@ else if (pkt_stat->rate >= DESC_RATEMCS0) rx_status->encoding = RX_ENC_HT; - if (pkt_stat->rate >= DESC_RATEVHT1SS_MCS0 && - pkt_stat->rate <= DESC_RATEVHT1SS_MCS9) { - rx_status->nss = 1; - rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT1SS_MCS0; - } else if (pkt_stat->rate >= DESC_RATEVHT2SS_MCS0 && - pkt_stat->rate <= DESC_RATEVHT2SS_MCS9) { - rx_status->nss = 2; - rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT2SS_MCS0; - } else if (pkt_stat->rate >= DESC_RATEVHT3SS_MCS0 && - pkt_stat->rate <= DESC_RATEVHT3SS_MCS9) { - rx_status->nss = 3; - rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT3SS_MCS0; - } else if (pkt_stat->rate >= DESC_RATEVHT4SS_MCS0 && - pkt_stat->rate <= DESC_RATEVHT4SS_MCS9) { - rx_status->nss = 4; - rx_status->rate_idx = pkt_stat->rate - DESC_RATEVHT4SS_MCS0; - } else if (pkt_stat->rate >= DESC_RATEMCS0 && - pkt_stat->rate <= DESC_RATEMCS15) { - rx_status->rate_idx = pkt_stat->rate - DESC_RATEMCS0; - } else if (rx_status->band == NL80211_BAND_5GHZ && - pkt_stat->rate >= DESC_RATE6M && - pkt_stat->rate <= DESC_RATE54M) { + if (rx_status->band == NL80211_BAND_5GHZ && + pkt_stat->rate >= DESC_RATE6M && + pkt_stat->rate <= DESC_RATE54M) { rx_status->rate_idx = pkt_stat->rate - DESC_RATE6M; } else if (rx_status->band == NL80211_BAND_2GHZ && pkt_stat->rate >= DESC_RATE1M && pkt_stat->rate <= DESC_RATE54M) { rx_status->rate_idx = pkt_stat->rate - DESC_RATE1M; - } else { - rx_status->rate_idx = 0; + } else if (pkt_stat->rate >= DESC_RATEMCS0) { + rtw_desc_to_mcsrate(pkt_stat->rate, &rx_status->rate_idx, + &rx_status->nss); } rx_status->flag |= RX_FLAG_MACTIME_START; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/rx.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/rx.h @@ -5,6 +5,15 @@ #ifndef __RTW_RX_H_ #define __RTW_RX_H_ +enum rtw_rx_desc_enc { + RX_DESC_ENC_NONE = 0, + RX_DESC_ENC_WEP40 = 1, + RX_DESC_ENC_TKIP_WO_MIC = 2, + RX_DESC_ENC_TKIP_MIC = 3, + RX_DESC_ENC_AES = 4, + RX_DESC_ENC_WEP104 = 5, +}; + #define GET_RX_DESC_PHYST(rxdesc) \ le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26)) #define GET_RX_DESC_ICV_ERR(rxdesc) \ @@ -21,6 +30,8 @@ le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16)) #define GET_RX_DESC_SHIFT(rxdesc) \ le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24)) +#define GET_RX_DESC_ENC_TYPE(rxdesc) \ + le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20)) #define GET_RX_DESC_RX_RATE(rxdesc) \ le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0)) #define GET_RX_DESC_MACID(rxdesc) \ --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/sar.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/sar.c @@ -0,0 +1,778 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include +#include "main.h" +#include "debug.h" +#include "phy.h" +#include "sar.h" + +#define RTW_SAR_WRDS_CHAIN_NR 2 + +enum rtw_sar_limit_index { + RTW_SAR_LMT_CH1_14, + RTW_SAR_LMT_CH36_64, + RTW_SAR_LMT_UND1, + RTW_SAR_LMT_CH100_144, + RTW_SAR_LMT_CH149_165, + + RTW_SAR_LMT_TOTAL_NR, +}; + +struct rtw_sar_limits { + s8 limit[RTW_SAR_LMT_TOTAL_NR]; +}; + +struct rtw_sar_wrds { + struct rtw_sar_limits chain[RTW_SAR_WRDS_CHAIN_NR]; +}; + +#define ACPI_WRDS_METHOD "WRDS" +#define ACPI_WRDS_SIZE sizeof(struct rtw_sar_wrds) +#define ACPI_WRDS_TOTAL_SIZE (sizeof(struct rtw_sar_wrds) + 2) +#define ACPI_WIFI_DOMAIN 0x07 + +#ifdef CONFIG_ACPI +static union acpi_object *rtw_sar_get_acpiobj(struct rtw_dev *rtwdev, + const char *method) +{ + struct device *dev = rtwdev->dev; + acpi_handle root_handle; + acpi_handle handle; + acpi_status status; + struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; + + /* Check device handler */ + root_handle = ACPI_HANDLE(dev); + if (!root_handle) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: Could not retireve root port ACPI handle\n"); + return NULL; + } + + /* Get method's handler */ + status = acpi_get_handle(root_handle, (acpi_string)method, &handle); + if (ACPI_FAILURE(status)) { + rtw_dbg(rtwdev, RTW_DBG_REGD, "SAR: %s method not found (0x%x)\n", + method, status); + return NULL; + } + + /* Call specific method with no argument */ + status = acpi_evaluate_object(handle, NULL, NULL, &buf); + if (ACPI_FAILURE(status)) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: %s invocation failed (0x%x)\n", method, status); + return NULL; + } + + return buf.pointer; +} + +static union acpi_object *rtw_sar_get_wifi_pkt(struct rtw_dev *rtwdev, + union acpi_object *obj, + u32 element_count) +{ + union acpi_object *wifi_pkg; + u32 i; + + if (obj->type != ACPI_TYPE_PACKAGE || + obj->package.count < 2 || + obj->package.elements[0].type != ACPI_TYPE_INTEGER || + obj->package.elements[0].integer.value != 0) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: Unsupported wifi package structure\n"); + return NULL; + } + + /* loop through all the packages to find the one for WiFi */ + for (i = 1; i < obj->package.count; i++) { + union acpi_object *domain; + + wifi_pkg = &obj->package.elements[i]; + + /* Skip anything that is not a package with the right amount of + * elements (i.e. domain_type, enabled/disabled plus the sar + * table size.) + */ + if (wifi_pkg->type != ACPI_TYPE_PACKAGE || + wifi_pkg->package.count != element_count) + continue; + + domain = &wifi_pkg->package.elements[0]; + if (domain->type == ACPI_TYPE_INTEGER && + domain->integer.value == ACPI_WIFI_DOMAIN) + return wifi_pkg; + } + + return NULL; +} + +static void *rtw_sar_get_wrds_table(struct rtw_dev *rtwdev) +{ + union acpi_object *wrds, *wrds_pkg; + int i, idx = 2; + u8 *wrds_raw = NULL; + + wrds = rtw_sar_get_acpiobj(rtwdev, ACPI_WRDS_METHOD); + if (!wrds) + return NULL; + + wrds_pkg = rtw_sar_get_wifi_pkt(rtwdev, wrds, ACPI_WRDS_TOTAL_SIZE); + if (!wrds_pkg) + goto out; + + /* WiFiSarEnable 0: ignore BIOS config; 1: use BIOS config */ + if (wrds_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || + wrds_pkg->package.elements[1].integer.value == 0) + goto out; + + wrds_raw = kmalloc(ACPI_WRDS_SIZE, GFP_KERNEL); + if (!wrds_raw) + goto out; + + /* read elements[2~11] */ + for (i = 0; i < ACPI_WRDS_SIZE; i++) { + union acpi_object *entry; + + entry = &wrds_pkg->package.elements[idx++]; + if (entry->type != ACPI_TYPE_INTEGER || + entry->integer.value > U8_MAX) { + kfree(wrds_raw); + wrds_raw = NULL; + goto out; + } + + wrds_raw[i] = entry->integer.value; + } +out: + kfree(wrds); + + return wrds_raw; +} + +static void rtw_sar_apply_wrds(struct rtw_dev *rtwdev, + const struct rtw_sar_wrds *wrds) +{ + int path; + + for (path = 0; path < RTW_SAR_WRDS_CHAIN_NR; path++) { + rtw_phy_set_tx_power_sar(rtwdev, RTW_REGD_WW, path, 1, 14, + wrds->chain[path].limit[RTW_SAR_LMT_CH1_14]); + rtw_phy_set_tx_power_sar(rtwdev, RTW_REGD_WW, path, 36, 64, + wrds->chain[path].limit[RTW_SAR_LMT_CH36_64]); + rtw_phy_set_tx_power_sar(rtwdev, RTW_REGD_WW, path, 100, 144, + wrds->chain[path].limit[RTW_SAR_LMT_CH100_144]); + rtw_phy_set_tx_power_sar(rtwdev, RTW_REGD_WW, path, 149, 165, + wrds->chain[path].limit[RTW_SAR_LMT_CH149_165]); + } + + rtwdev->sar.source = RTW_SAR_SOURCE_ACPI_STATIC; +} + +static int rtw_sar_load_static_tables(struct rtw_dev *rtwdev) +{ + struct rtw_sar_wrds *wrds; + + wrds = rtw_sar_get_wrds_table(rtwdev); + if (!wrds) + return -ENOENT; + + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: Apply WRDS to TX power\n"); + + rtw_sar_apply_wrds(rtwdev, wrds); + kfree(wrds); + + return 0; +} + +#define ACPI_RWRD_METHOD "RWRD" +#define ACPI_RWSI_METHOD "RWSI" +#define ACPI_RWGS_METHOD "RWGS" + +#define RTW_SAR_RWRD_ID_HP 0x5048 +#define RTW_SAR_RWRD_ID_RT 0x5452 + +#define RTW_SAR_RWRD_CHAIN_NR 4 + +struct rtw_sar_rwrd { + u16 id; + u8 en; + u8 count; + struct { + struct rtw_sar_limits chain[RTW_SAR_RWRD_CHAIN_NR]; + } mode[0]; +} __packed; + +struct rtw_sar_rwsi_hp { + u8 index[RTW_SAR_RWRD_CHAIN_NR]; +} __packed; + +struct rtw_sar_rwsi_rt { + u8 index; +} __packed; + +union rtw_sar_rwsi { + struct rtw_sar_rwsi_hp hp; + struct rtw_sar_rwsi_rt rt; +}; + +enum rtw_sar_rwgs_band { + RTW_SAR_RWGS_2G, + RTW_SAR_RWGS_5G, + RTW_SAR_RWGS_BAND_NR, +}; + +enum rtw_sar_rwgs_geo_hp { + RTW_SAR_RWGS_HP_FCC_IC, + RTW_SAR_RWGS_HP_ETSI_MKK, + RTW_SAR_RWGS_HP_WW_KCC, + + RTW_SAR_RWGS_HP_NR, +}; + +struct rtw_sar_rwgs_hp { + struct { + struct { + s8 max; /* Q1 + 10 */ + s8 delta[4]; /* Q1 */ + } band[RTW_SAR_RWGS_BAND_NR]; + } geo[RTW_SAR_RWGS_HP_NR]; +} __packed; + +enum rtw_sar_rwgs_geo_rt { + RTW_SAR_RWGS_RT_FCC, + RTW_SAR_RWGS_RT_CE, + RTW_SAR_RWGS_RT_MKK, + RTW_SAR_RWGS_RT_IC, + RTW_SAR_RWGS_RT_KCC, + RTW_SAR_RWGS_RT_WW, + + RTW_SAR_RWGS_RT_NR, +}; + +struct rtw_sar_rwgs_rt { + struct { + struct { + u8 max; /* Q3 */ + s8 delta; /* Q1 */ + } band[RTW_SAR_RWGS_BAND_NR]; + } geo[RTW_SAR_RWGS_RT_NR]; +} __packed; + +union rtw_sar_rwgs { + struct rtw_sar_rwgs_hp hp; + struct rtw_sar_rwgs_rt rt; +}; + +struct rtw_sar_geo_map { + int idx; /* index of rwgs.geo[] */ + int rd; /* RTW_REGD_xxx */ +}; + +static const struct rtw_sar_geo_map geo_map_hp[] = { + {RTW_SAR_RWGS_HP_FCC_IC, RTW_REGD_FCC}, + {RTW_SAR_RWGS_HP_FCC_IC, RTW_REGD_IC}, + {RTW_SAR_RWGS_HP_ETSI_MKK, RTW_REGD_ETSI}, + {RTW_SAR_RWGS_HP_ETSI_MKK, RTW_REGD_MKK}, + {RTW_SAR_RWGS_HP_WW_KCC, RTW_REGD_KCC}, + {RTW_SAR_RWGS_HP_WW_KCC, RTW_REGD_WW}, +}; + +static const struct rtw_sar_geo_map geo_map_rt[] = { + {RTW_SAR_RWGS_RT_FCC, RTW_REGD_FCC}, + {RTW_SAR_RWGS_RT_CE, RTW_REGD_ETSI}, + {RTW_SAR_RWGS_RT_MKK, RTW_REGD_MKK}, + {RTW_SAR_RWGS_RT_IC, RTW_REGD_IC}, + {RTW_SAR_RWGS_RT_KCC, RTW_REGD_KCC}, + {RTW_SAR_RWGS_RT_WW, RTW_REGD_WW}, +}; + +struct rtw_sar_read { + int (*rwsi_mode)(struct rtw_dev *rtwdev, int path); + int (*rwrd_base_q3)(struct rtw_dev *rtwdev, int mode, int path, int chidx); + int (*rwgs_delta_q3)(struct rtw_dev *rtwdev, int gi, int path, int band); + int (*rwgs_max_q3)(struct rtw_dev *rtwdev, int gi, int band); + const struct rtw_sar_geo_map *gm, *gm_end; + int rwsi_sz; + int rwgs_sz; + int rwgs_geos; +}; + +static int rwsi_mode_hp(struct rtw_dev *rtwdev, int path) +{ + return rtwdev->sar.rwsi->hp.index[path] - 1; +} + +static int rwrd_base_q3_hp(struct rtw_dev *rtwdev, int mode, int path, int chidx) +{ + int sar; + + sar = rtwdev->sar.rwrd->mode[mode].chain[path].limit[chidx]; + + return (10 << 3) + (sar << 2); +} + +static int rwgs_delta_q3_hp(struct rtw_dev *rtwdev, int gi, int path, int band) +{ + return rtwdev->sar.rwgs->hp.geo[gi].band[band].delta[path] << 2; +} + +static int rwgs_max_q3_hp(struct rtw_dev *rtwdev, int gi, int band) +{ + return (10 << 3) + (rtwdev->sar.rwgs->hp.geo[gi].band[band].max << 2); +} + +static const struct rtw_sar_read sar_read_hp = { + .rwsi_mode = rwsi_mode_hp, + .rwrd_base_q3 = rwrd_base_q3_hp, + .rwgs_delta_q3 = rwgs_delta_q3_hp, + .rwgs_max_q3 = rwgs_max_q3_hp, + .gm = geo_map_hp, + .gm_end = geo_map_hp + ARRAY_SIZE(geo_map_hp), + .rwsi_sz = sizeof(struct rtw_sar_rwsi_hp), + .rwgs_sz = sizeof(struct rtw_sar_rwgs_hp), + .rwgs_geos = RTW_SAR_RWGS_HP_NR, +}; + +static int rwsi_mode_rt(struct rtw_dev *rtwdev, int path) +{ + return rtwdev->sar.rwsi->rt.index - 1; +} + +static int rwrd_base_q3_rt(struct rtw_dev *rtwdev, int mode, int path, int chidx) +{ + return rtwdev->sar.rwrd->mode[mode].chain[path].limit[chidx] << 3; +} + +static int rwgs_delta_q3_rt(struct rtw_dev *rtwdev, int gi, int path, int band) +{ + return rtwdev->sar.rwgs->rt.geo[gi].band[band].delta << 2; +} + +static int rwgs_max_q3_rt(struct rtw_dev *rtwdev, int gi, int band) +{ + return rtwdev->sar.rwgs->rt.geo[gi].band[band].max; +} + +static const struct rtw_sar_read sar_read_rt = { + .rwsi_mode = rwsi_mode_rt, + .rwrd_base_q3 = rwrd_base_q3_rt, + .rwgs_delta_q3 = rwgs_delta_q3_rt, + .rwgs_max_q3 = rwgs_max_q3_rt, + .gm = geo_map_rt, + .gm_end = geo_map_rt + ARRAY_SIZE(geo_map_rt), + .rwsi_sz = sizeof(struct rtw_sar_rwsi_rt), + .rwgs_sz = sizeof(struct rtw_sar_rwgs_rt), + .rwgs_geos = RTW_SAR_RWGS_RT_NR, +}; + +static u8 *rtw_sar_get_raw_package(struct rtw_dev *rtwdev, + union acpi_object *obj, int *len) +{ + u8 *raw; + u32 i; + + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count <= 0) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: Unsupported obj to dump\n"); + return NULL; + } + + raw = kmalloc(obj->package.count, GFP_KERNEL); + if (!raw) + return NULL; + + for (i = 0; i < obj->package.count; i++) { + union acpi_object *element; + + element = &obj->package.elements[i]; + + if (element->type != ACPI_TYPE_INTEGER) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: Unexpected element type\n"); + kfree(raw); + return NULL; + } + + raw[i] = (u8)element->integer.value; + } + + *len = obj->package.count; + + return raw; +} + +static void *rtw_sar_get_raw_table(struct rtw_dev *rtwdev, const char *method, + int *len) +{ + union acpi_object *obj; + u8 *raw; + + obj = rtw_sar_get_acpiobj(rtwdev, method); + if (!obj) + return NULL; + + raw = rtw_sar_get_raw_package(rtwdev, obj, len); + kfree(obj); + + return raw; +} + +static bool is_valid_rwrd(struct rtw_dev *rtwdev, const struct rtw_sar_rwrd *rwrd, + int len) +{ + if (len < sizeof(*rwrd)) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWRD: len %d is too short\n", len); + return false; + } + + switch (rwrd->id) { + case RTW_SAR_RWRD_ID_HP: + rtwdev->sar.read = &sar_read_hp; + break; + case RTW_SAR_RWRD_ID_RT: + rtwdev->sar.read = &sar_read_rt; + break; + default: + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWRD: ID %04x isn't supported\n", rwrd->id); + return false; + } + + if (sizeof(*rwrd) + rwrd->count * sizeof(rwrd->mode[0]) != len) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWRD: len(%d) doesn't match count(%d)\n", + len, rwrd->count); + return false; + } + + return true; +} + +static bool is_valid_rwsi_idx(struct rtw_dev *rtwdev, const struct rtw_sar_rwrd *rwrd, + const u8 index[], int len) +{ + /* index range is one based. i.e. 1 <= index[] <= rwrd->count */ + int i; + + for (i = 0; i < len; i++) + if (index[i] < 1 || index[i] > rwrd->count) { + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWSI: index is out of range\n"); + return false; + } + + return true; +} + +static bool is_valid_rwsi(struct rtw_dev *rtwdev, const struct rtw_sar_rwrd *rwrd, + const union rtw_sar_rwsi *rwsi, int len) +{ + const struct rtw_sar_read *r = rtwdev->sar.read; + + if (r->rwsi_sz != len) + goto err; + + if (rwrd->id == RTW_SAR_RWRD_ID_HP && + is_valid_rwsi_idx(rtwdev, rwrd, rwsi->hp.index, RTW_SAR_RWRD_CHAIN_NR)) + return true; + + if (rwrd->id == RTW_SAR_RWRD_ID_RT && + is_valid_rwsi_idx(rtwdev, rwrd, &rwsi->rt.index, 1)) { + return true; + } + +err: + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWSI: len doesn't match struct size\n"); + + return false; +} + +static bool is_valid_rwgs(struct rtw_dev *rtwdev, const struct rtw_sar_rwrd *rwrd, + const union rtw_sar_rwgs *rwgs, int len) +{ + const struct rtw_sar_read *r = rtwdev->sar.read; + + if (r->rwgs_sz == len) + return true; + + rtw_dbg(rtwdev, RTW_DBG_REGD, + "SAR: RWGS: len doesn't match struct size\n"); + + return false; +} + +#ifdef CONFIG_RTW88_DEBUGFS +void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m) +{ +#define q3_int(q3) ((q3) >> 3) +#define q3_fra(q3) (((q3) & 0x7) * 125) + + const struct rtw_sar_rwrd *rwrd = rtwdev->sar.rwrd; + const union rtw_sar_rwsi *rwsi = rtwdev->sar.rwsi; + const union rtw_sar_rwgs *rwgs = rtwdev->sar.rwgs; + const struct rtw_sar_read *r = rtwdev->sar.read; + int q3; + int mode; + int path; + int chidx; + int gi; + int band; + + if (!rwrd || !rwsi || !rwgs || !r) { + seq_puts(m, "(No SAR data)\n"); + return; + } + + seq_printf(m, "Customer ID: 0x%04x\n", rwrd->id); + seq_printf(m, "WiFiEnable: 0x%x\n", rwrd->en); + seq_printf(m, "Total SAR Table Count: %d\n", rwrd->count); + seq_printf(m, "Current SAR Table Index: (%*ph)\n", r->rwsi_sz, rwsi); + seq_puts(m, "\n"); + + seq_printf(m, "Dump RWRD SAR RAW DATA. (Total Count: %ld)\n", + rwrd->count * sizeof(rwrd->mode[0])); + for (mode = 0; mode < rwrd->count; mode++) + seq_printf(m, "%02x: %20ph\n", mode + 1, &rwrd->mode[mode]); + seq_puts(m, "\n"); + + seq_puts(m, "Show SAR PowerLimit:\n"); + for (path = 0; path < 2; path++) { + mode = r->rwsi_mode(rtwdev, path); + q3 = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH1_14); + seq_printf(m, "2.4G Antenna %d: [%d.%d] dBm\n", path, + q3_int(q3), q3_fra(q3)); + } + seq_puts(m, "\n"); + + for (path = 0; path < 2; path++) { + mode = r->rwsi_mode(rtwdev, path); + seq_printf(m, "5G Antenna %d: [", path); + for (chidx = RTW_SAR_LMT_CH36_64; chidx <= RTW_SAR_LMT_CH149_165; + chidx++) { + q3 = r->rwrd_base_q3(rtwdev, mode, path, chidx); + seq_printf(m, "%d.%d, ", q3_int(q3), q3_fra(q3)); + } + seq_puts(m, "] dBm\n"); + } + seq_puts(m, "\n"); + + seq_printf(m, "Dump Geo-SAR Table RAW DATA. (Total Count: %d)\n", + r->rwgs_sz); + for (gi = 0; gi < r->rwgs_geos; gi++) { + seq_printf(m, "geo-%d: %*ph\n", gi, r->rwgs_sz / r->rwgs_geos, + (u8 *)rwgs + gi * (r->rwgs_sz / r->rwgs_geos)); + } + seq_puts(m, "\n"); + + gi = 1; /* take index 1 as an example */ + seq_puts(m, "Show Geo-SAR PowerLimit:\n"); + seq_printf(m, "2G Geo Table Index: %d\n", gi); + seq_printf(m, "5G Geo Table Index: %d\n", gi); + for (band = RTW_SAR_RWGS_2G; band < RTW_SAR_RWGS_BAND_NR; band++) { + seq_puts(m, "\n"); + seq_printf(m, "%dGHz:\n", band == 0 ? 2 : 5); + q3 = r->rwgs_max_q3(rtwdev, gi, band); + seq_printf(m, "Max Power: [%d.%d] dBm\n", q3_int(q3), + q3_fra(q3)); + for (path = 0; path < 2; path++) { + q3 = r->rwgs_delta_q3(rtwdev, gi, path, band); + seq_printf(m, "Ant-%d delta value: [%d.%d] dB\n", path, + q3_int(q3), q3_fra(q3)); + } + } +} +#endif + +static void rtw_sar_apply_dynamic_tables(struct rtw_dev *rtwdev) +{ + struct rtw_hal *hal = &rtwdev->hal; + const struct rtw_sar_read *r = rtwdev->sar.read; + const struct rtw_sar_geo_map *gm = r->gm; + const struct rtw_sar_geo_map *gm_end = r->gm_end; + int path_num = min_t(int, RTW_SAR_RWRD_CHAIN_NR, hal->rf_path_num); + int path, mode; + int sar, delta, max; + + for (; gm < gm_end; gm++) { + for (path = 0; path < path_num; path++) { + mode = r->rwsi_mode(rtwdev, path); + + /* 2.4G part */ + delta = r->rwgs_delta_q3(rtwdev, gm->idx, path, RTW_SAR_RWGS_2G); + max = r->rwgs_max_q3(rtwdev, gm->idx, RTW_SAR_RWGS_2G); + + sar = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH1_14); + sar = min(sar + delta, max); + rtw_phy_set_tx_power_sar(rtwdev, gm->rd, path, 1, 14, sar); + + /* 5G part */ + delta = r->rwgs_delta_q3(rtwdev, gm->idx, path, RTW_SAR_RWGS_5G); + max = r->rwgs_max_q3(rtwdev, gm->idx, RTW_SAR_RWGS_5G); + + sar = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH36_64); + sar = min(sar + delta, max); + rtw_phy_set_tx_power_sar(rtwdev, gm->rd, path, 36, 64, sar); + + sar = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH100_144); + sar = min(sar + delta, max); + rtw_phy_set_tx_power_sar(rtwdev, gm->rd, path, 100, 144, sar); + + sar = r->rwrd_base_q3(rtwdev, mode, path, RTW_SAR_LMT_CH149_165); + sar = min(sar + delta, max); + rtw_phy_set_tx_power_sar(rtwdev, gm->rd, path, 149, 165, sar); + } + } + + rtwdev->sar.source = RTW_SAR_SOURCE_ACPI_DYNAMIC; +} + +static bool rtw_sar_is_rwsi_changed(struct rtw_dev *rtwdev) +{ + union rtw_sar_rwsi *rwsi, *old; + bool valid; + int len; + + if (rtwdev->sar.source != RTW_SAR_SOURCE_ACPI_DYNAMIC) + return false; + + if (!rtwdev->sar.rwrd || !rtwdev->sar.rwsi || !rtwdev->sar.rwgs) + return false; + + rwsi = rtw_sar_get_raw_table(rtwdev, ACPI_RWSI_METHOD, &len); + if (!rwsi) + return false; + valid = is_valid_rwsi(rtwdev, rtwdev->sar.rwrd, rwsi, len); + if (!valid) { + kfree(rwsi); + return false; + } + + if (memcmp(rwsi, rtwdev->sar.rwsi, len) == 0) { + kfree(rwsi); + return true; + } + + old = rtwdev->sar.rwsi; + rtwdev->sar.rwsi = rwsi; + kfree(old); + + rtw_dbg(rtwdev, RTW_DBG_REGD, "SAR: RWSI is changed\n"); + + rtw_sar_apply_dynamic_tables(rtwdev); + + rtw_phy_set_tx_power_level(rtwdev, rtwdev->hal.current_channel); + + return true; +} + +static int rtw_sar_load_dynamic_tables(struct rtw_dev *rtwdev) +{ + struct rtw_sar_rwrd *rwrd; + union rtw_sar_rwsi *rwsi; + union rtw_sar_rwgs *rwgs; + int len; + bool valid; + + rwrd = rtw_sar_get_raw_table(rtwdev, ACPI_RWRD_METHOD, &len); + if (!rwrd) + goto out; + valid = is_valid_rwrd(rtwdev, rwrd, len); + if (!valid) + goto out_rwrd; + if (!rwrd->en) { + rtw_dbg(rtwdev, RTW_DBG_REGD, "SAR: RWRD isn't enabled\n"); + goto out_rwrd; + } + + rwsi = rtw_sar_get_raw_table(rtwdev, ACPI_RWSI_METHOD, &len); + if (!rwsi) + goto out_rwrd; + valid = is_valid_rwsi(rtwdev, rwrd, rwsi, len); + if (!valid) + goto out_rwsi; + + rwgs = rtw_sar_get_raw_table(rtwdev, ACPI_RWGS_METHOD, &len); + if (!rwgs) + goto out_rwsi; + valid = is_valid_rwgs(rtwdev, rwrd, rwgs, len); + if (!valid) + goto out_rwgs; + + rtwdev->sar.rwrd = rwrd; + rtwdev->sar.rwsi = rwsi; + rtwdev->sar.rwgs = rwgs; + + rtw_sar_apply_dynamic_tables(rtwdev); + + rtw_dbg(rtwdev, RTW_DBG_REGD, "SAR: RWRD/RWSI/RWGS is adopted\n"); + + return 0; + +out_rwgs: + kfree(rwgs); +out_rwsi: + kfree(rwsi); +out_rwrd: + kfree(rwrd); +out: + return -ENOENT; +} +#else +static int rtw_sar_load_static_tables(struct rtw_dev *rtwdev) +{ + return -ENOENT; +} + +static bool rtw_sar_is_rwsi_changed(struct rtw_dev *rtwdev) +{ + return false; +} + +static int rtw_sar_load_dynamic_tables(struct rtw_dev *rtwdev) +{ + return -ENOENT; +} + +#ifdef CONFIG_RTW88_DEBUGFS +void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m) +{ + seq_puts(m, "(No SAR data)\n"); +} +#endif +#endif /* CONFIG_ACPI */ + +void rtw_sar_load_table(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtw_sar_load_dynamic_tables(rtwdev); + if (!ret) + return; /* if dynamic SAR table is loaded, ignore static SAR table */ + + rtw_sar_load_static_tables(rtwdev); +} + +void rtw_sar_release_table(struct rtw_dev *rtwdev) +{ + kfree(rtwdev->sar.rwrd); + kfree(rtwdev->sar.rwsi); + kfree(rtwdev->sar.rwgs); +} + +void rtw_sar_work(struct work_struct *work) +{ + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, + sar.work.work); + + if (!rtw_sar_is_rwsi_changed(rtwdev)) + return; + + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->sar.work, + RTW_SAR_DELAY_TIME); +} --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/sar.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/sar.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_SAR_H_ +#define __RTW_SAR_H_ + +void rtw_sar_load_table(struct rtw_dev *rtwdev); +void rtw_sar_release_table(struct rtw_dev *rtwdev); +void rtw_sar_work(struct work_struct *work); +void rtw_sar_dump_via_debugfs(struct rtw_dev *rtwdev, struct seq_file *m); + +#define RTW_SAR_DELAY_TIME (10 * HZ) + +#endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/sec.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/sec.c @@ -44,7 +44,7 @@ write_cmd = RTW_SEC_CMD_WRITE_ENABLE | RTW_SEC_CMD_POLLING; addr = hw_key_idx << RTW_SEC_CAM_ENTRY_SHIFT; - for (i = 5; i >= 0; i--) { + for (i = 7; i >= 0; i--) { switch (i) { case 0: content = ((key->keyidx & 0x3)) | @@ -60,6 +60,10 @@ (cam->addr[4] << 16) | (cam->addr[5] << 24); break; + case 6: + case 7: + content = 0; + break; default: j = (i - 2) << 2; content = (key->key[j]) | @@ -96,6 +100,27 @@ rtw_write32(rtwdev, RTW_SEC_CMD_REG, command); } +u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam) +{ + struct rtw_sec_desc *sec = &rtwdev->sec; + u8 offset = 0; + u8 count, n; + + if (!used_cam) + return 0; + + for (count = 0; count < MAX_PG_CAM_BACKUP_NUM; count++) { + n = find_next_bit(sec->cam_map, RTW_MAX_SEC_CAM_NUM, offset); + if (n == RTW_MAX_SEC_CAM_NUM) + break; + + used_cam[count] = n; + offset = n + 1; + } + + return count; +} + void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev) { struct rtw_sec_desc *sec = &rtwdev->sec; --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/sec.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/sec.h @@ -34,6 +34,7 @@ void rtw_sec_clear_cam(struct rtw_dev *rtwdev, struct rtw_sec_desc *sec, u8 hw_key_idx); +u8 rtw_sec_cam_pg_backup(struct rtw_dev *rtwdev, u8 *used_cam); void rtw_sec_enable_sec_engine(struct rtw_dev *rtwdev); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/tx.c @@ -6,6 +6,7 @@ #include "tx.h" #include "fw.h" #include "ps.h" +#include "debug.h" static void rtw_tx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, @@ -27,8 +28,6 @@ rtwvif = (struct rtw_vif *)vif->drv_priv; rtwvif->stats.tx_unicast += skb->len; rtwvif->stats.tx_cnt++; - if (rtwvif->stats.tx_cnt > RTW_LPS_THRESHOLD) - rtw_leave_lps_irqsafe(rtwdev, rtwvif); } } } @@ -58,6 +57,13 @@ SET_TX_DESC_DATA_SHORT(txdesc, pkt_info->short_gi); SET_TX_DESC_SPE_RPT(txdesc, pkt_info->report); SET_TX_DESC_SW_DEFINE(txdesc, pkt_info->sn); + SET_TX_DESC_USE_RTS(txdesc, pkt_info->rts); + SET_TX_DESC_NAVUSEHDR(txdesc, pkt_info->nav_use_hdr); + SET_TX_DESC_DISQSELSEQ(txdesc, pkt_info->dis_qselseq); + SET_TX_DESC_EN_HWSEQ(txdesc, pkt_info->en_hwseq); + SET_TX_DESC_EN_HWEXSEQ(txdesc, pkt_info->en_hw_exseq); + SET_TX_DESC_HW_SSN_SEL(txdesc, pkt_info->hw_ssn_sel); + SET_TX_DESC_BT_NULL(txdesc, pkt_info->bt_null); } EXPORT_SYMBOL(rtw_tx_fill_tx_desc); @@ -153,7 +159,7 @@ if (skb_queue_len(&tx_report->queue) == 0) return; - WARN(1, "purge skb(s) not reported by firmware\n"); + rtw_dbg(rtwdev, RTW_DBG_TX, "purge skb(s) not reported by firmware\n"); spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_purge(&tx_report->queue); @@ -193,7 +199,7 @@ ieee80211_tx_status_irqsafe(rtwdev->hw, skb); } -void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) +void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src) { struct rtw_tx_report *tx_report = &rtwdev->tx_report; struct rtw_c2h_cmd *c2h; @@ -204,8 +210,13 @@ c2h = get_c2h_from_skb(skb); - sn = GET_CCX_REPORT_SEQNUM(c2h->payload); - st = GET_CCX_REPORT_STATUS(c2h->payload); + if (src == C2H_CCX_TX_RPT) { + sn = GET_CCX_REPORT_SEQNUM_V0(c2h->payload); + st = GET_CCX_REPORT_STATUS_V0(c2h->payload); + } else { + sn = GET_CCX_REPORT_SEQNUM_V1(c2h->payload); + st = GET_CCX_REPORT_STATUS_V1(c2h->payload); + } spin_lock_irqsave(&tx_report->q_lock, flags); skb_queue_walk_safe(&tx_report->queue, cur, tmp) { @@ -219,16 +230,62 @@ spin_unlock_irqrestore(&tx_report->q_lock, flags); } -static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev, +static void rtw_tx_pkt_info_update_rate(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, - struct ieee80211_tx_control *control, struct sk_buff *skb) { + if (rtwdev->hal.current_band_type == RTW_BAND_2G) { + pkt_info->rate_id = RTW_RATEID_B_20M; + pkt_info->rate = DESC_RATE1M; + } else { + pkt_info->rate_id = RTW_RATEID_G; + pkt_info->rate = DESC_RATE6M; + } + pkt_info->use_rate = true; - pkt_info->rate_id = 6; pkt_info->dis_rate_fallback = true; } +static void rtw_tx_pkt_info_update_sec(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + u8 sec_type = 0; + + if (info && info->control.hw_key) { + struct ieee80211_key_conf *key = info->control.hw_key; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + sec_type = 0x01; + break; + case WLAN_CIPHER_SUITE_CCMP: + sec_type = 0x03; + break; + default: + break; + } + } + + pkt_info->sec_type = sec_type; +} + +static void rtw_tx_mgmt_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb); + pkt_info->dis_qselseq = true; + pkt_info->en_hwseq = true; + pkt_info->hw_ssn_sel = 0; + pkt_info->en_hw_exseq = false; + /* TODO: need to change hw port and hw ssn sel for multiple vifs */ +} + static void rtw_tx_data_pkt_info_update(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, struct ieee80211_tx_control *control, @@ -260,6 +317,9 @@ ampdu_density = get_tx_ampdu_density(sta); } + if (info->control.use_rts) + pkt_info->rts = true; + if (sta->vht_cap.vht_supported) rate = get_highest_vht_tx_rate(rtwdev, sta); else if (sta->ht_cap.ht_supported) @@ -299,7 +359,6 @@ struct rtw_sta_info *si; struct ieee80211_vif *vif = NULL; __le16 fc = hdr->frame_control; - u8 sec_type = 0; bool bmc; if (control->sta) { @@ -312,23 +371,6 @@ else if (ieee80211_is_data(fc)) rtw_tx_data_pkt_info_update(rtwdev, pkt_info, control, skb); - if (info->control.hw_key) { - struct ieee80211_key_conf *key = info->control.hw_key; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - sec_type = 0x01; - break; - case WLAN_CIPHER_SUITE_CCMP: - sec_type = 0x03; - break; - default: - break; - } - } - bmc = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); @@ -336,7 +378,7 @@ rtw_tx_report_enable(rtwdev, pkt_info); pkt_info->bmc = bmc; - pkt_info->sec_type = sec_type; + rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb); pkt_info->tx_pkt_size = skb->len; pkt_info->offset = chip->tx_pkt_desc_sz; pkt_info->qsel = skb->priority; @@ -346,22 +388,222 @@ rtw_tx_stats(rtwdev, vif, skb); } -void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, - struct rtw_tx_pkt_info *pkt_info, - struct sk_buff *skb) +void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_rsvd_packet_type type) { struct rtw_chip_info *chip = rtwdev->chip; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; bool bmc; + /* A beacon or dummy reserved page packet indicates that it is the first + * reserved page, and the qsel of it will be set in each hci. + */ + if (type != RSVD_BEACON && type != RSVD_DUMMY) + pkt_info->qsel = TX_DESC_QSEL_MGMT; + + rtw_tx_pkt_info_update_rate(rtwdev, pkt_info, skb); + bmc = is_broadcast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1); - pkt_info->use_rate = true; - pkt_info->rate_id = 6; - pkt_info->dis_rate_fallback = true; pkt_info->bmc = bmc; pkt_info->tx_pkt_size = skb->len; pkt_info->offset = chip->tx_pkt_desc_sz; - pkt_info->qsel = TX_DESC_QSEL_MGMT; pkt_info->ls = true; + if (type == RSVD_PS_POLL) { + pkt_info->nav_use_hdr = true; + } else { + pkt_info->dis_qselseq = true; + pkt_info->en_hwseq = true; + pkt_info->hw_ssn_sel = 0; + pkt_info->en_hw_exseq = false; + } + if (type == RSVD_QOS_NULL) + pkt_info->bt_null = true; + + rtw_tx_pkt_info_update_sec(rtwdev, pkt_info, skb); + + /* TODO: need to change hw port and hw ssn sel for multiple vifs */ +} + +struct sk_buff * +rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + u32 tx_pkt_desc_sz; + u32 length; + + tx_pkt_desc_sz = chip->tx_pkt_desc_sz; + length = size + tx_pkt_desc_sz; + skb = dev_alloc_skb(length); + if (!skb) { + rtw_err(rtwdev, "failed to alloc write data rsvd page skb\n"); + return NULL; + } + + skb_reserve(skb, tx_pkt_desc_sz); + skb_put_data(skb, buf, size); + rtw_tx_rsvd_page_pkt_info_update(rtwdev, pkt_info, skb, RSVD_BEACON); + + return skb; +} +EXPORT_SYMBOL(rtw_tx_write_data_rsvd_page_get); + +struct sk_buff * +rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb; + u32 tx_pkt_desc_sz; + u32 length; + + tx_pkt_desc_sz = chip->tx_pkt_desc_sz; + length = size + tx_pkt_desc_sz; + skb = dev_alloc_skb(length); + if (!skb) { + rtw_err(rtwdev, "failed to alloc write data h2c skb\n"); + return NULL; + } + + skb_reserve(skb, tx_pkt_desc_sz); + skb_put_data(skb, buf, size); + pkt_info->tx_pkt_size = size; + + return skb; +} +EXPORT_SYMBOL(rtw_tx_write_data_h2c_get); + +void rtw_tx(struct rtw_dev *rtwdev, + struct ieee80211_tx_control *control, + struct sk_buff *skb) +{ + struct rtw_tx_pkt_info pkt_info = {0}; + + rtw_tx_pkt_info_update(rtwdev, &pkt_info, control, skb); + if (rtw_hci_tx(rtwdev, &pkt_info, skb)) + goto out; + + return; + +out: + ieee80211_free_txskb(rtwdev->hw, skb); +} + +static void rtw_txq_check_agg(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + struct sk_buff *skb) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct ieee80211_tx_info *info; + struct rtw_sta_info *si; + + if (test_bit(RTW_TXQ_AMPDU, &rtwtxq->flags)) { + info = IEEE80211_SKB_CB(skb); + info->flags |= IEEE80211_TX_CTL_AMPDU; + return; + } + + if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO) + return; + + if (test_bit(RTW_TXQ_BLOCK_BA, &rtwtxq->flags)) + return; + + if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE))) + return; + + if (!txq->sta) + return; + + si = (struct rtw_sta_info *)txq->sta->drv_priv; + set_bit(txq->tid, si->tid_ba); + + ieee80211_queue_work(rtwdev->hw, &rtwdev->ba_work); +} + +static bool rtw_txq_dequeue(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq) +{ + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + struct ieee80211_tx_control control; + struct sk_buff *skb; + + skb = ieee80211_tx_dequeue(rtwdev->hw, txq); + if (!skb) + return false; + + rtw_txq_check_agg(rtwdev, rtwtxq, skb); + + control.sta = txq->sta; + rtw_tx(rtwdev, &control, skb); + rtwtxq->last_push = jiffies; + + return true; +} + +static void rtw_txq_push(struct rtw_dev *rtwdev, + struct rtw_txq *rtwtxq, + unsigned long frames) +{ + int i; + + rcu_read_lock(); + + for (i = 0; i < frames; i++) + if (!rtw_txq_dequeue(rtwdev, rtwtxq)) + break; + + rcu_read_unlock(); +} + +void rtw_tx_tasklet(unsigned long data) +{ + struct rtw_dev *rtwdev = (void *)data; + struct rtw_txq *rtwtxq, *tmp; + + spin_lock_bh(&rtwdev->txq_lock); + + list_for_each_entry_safe(rtwtxq, tmp, &rtwdev->txqs, list) { + struct ieee80211_txq *txq = rtwtxq_to_txq(rtwtxq); + unsigned long frame_cnt; + unsigned long byte_cnt; + + ieee80211_txq_get_depth(txq, &frame_cnt, &byte_cnt); + rtw_txq_push(rtwdev, rtwtxq, frame_cnt); + + list_del_init(&rtwtxq->list); + } + + spin_unlock_bh(&rtwdev->txq_lock); +} + +void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) +{ + struct rtw_txq *rtwtxq; + + if (!txq) + return; + + rtwtxq = (struct rtw_txq *)txq->drv_priv; + INIT_LIST_HEAD(&rtwtxq->list); +} + +void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq) +{ + struct rtw_txq *rtwtxq; + + if (!txq) + return; + + rtwtxq = (struct rtw_txq *)txq->drv_priv; + spin_lock_bh(&rtwdev->txq_lock); + if (!list_empty(&rtwtxq->list)) + list_del_init(&rtwtxq->list); + spin_unlock_bh(&rtwdev->txq_lock); } --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/tx.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/tx.h @@ -35,6 +35,8 @@ le32p_replace_bits((__le32 *)(txdesc) + 0x09, value, GENMASK(23, 12)) #define SET_TX_DESC_MAX_AGG_NUM(txdesc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(21, 17)) +#define SET_TX_DESC_USE_RTS(tx_desc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(12)) #define SET_TX_DESC_AMPDU_DENSITY(txdesc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, GENMASK(22, 20)) #define SET_TX_DESC_DATA_STBC(txdesc, value) \ @@ -51,6 +53,18 @@ le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(19)) #define SET_TX_DESC_SW_DEFINE(tx_desc, value) \ le32p_replace_bits((__le32 *)(txdesc) + 0x06, value, GENMASK(11, 0)) +#define SET_TX_DESC_NAVUSEHDR(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, BIT(15)) +#define SET_TX_DESC_DISQSELSEQ(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x00, value, BIT(31)) +#define SET_TX_DESC_EN_HWSEQ(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(15)) +#define SET_TX_DESC_EN_HWEXSEQ(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x08, value, BIT(14)) +#define SET_TX_DESC_HW_SSN_SEL(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x03, value, GENMASK(7, 6)) +#define SET_TX_DESC_BT_NULL(txdesc, value) \ + le32p_replace_bits((__le32 *)(txdesc) + 0x02, value, BIT(23)) enum rtw_tx_desc_queue_select { TX_DESC_QSEL_TID0 = 0, @@ -75,15 +89,32 @@ TX_DESC_QSEL_H2C = 19, }; +enum rtw_rsvd_packet_type; + +void rtw_tx(struct rtw_dev *rtwdev, + struct ieee80211_tx_control *control, + struct sk_buff *skb); +void rtw_txq_init(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); +void rtw_txq_cleanup(struct rtw_dev *rtwdev, struct ieee80211_txq *txq); +void rtw_tx_tasklet(unsigned long data); void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev, struct rtw_tx_pkt_info *pkt_info, struct ieee80211_tx_control *control, struct sk_buff *skb); void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); -void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb); -void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, - struct rtw_tx_pkt_info *pkt_info, - struct sk_buff *skb); +void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); +void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + struct sk_buff *skb, + enum rtw_rsvd_packet_type type); +struct sk_buff * +rtw_tx_write_data_rsvd_page_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size); +struct sk_buff * +rtw_tx_write_data_h2c_get(struct rtw_dev *rtwdev, + struct rtw_tx_pkt_info *pkt_info, + u8 *buf, u32 size); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/util.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/util.c @@ -22,22 +22,28 @@ bool ltecoex_read_reg(struct rtw_dev *rtwdev, u16 offset, u32 *val) { - if (!check_hw_ready(rtwdev, LTECOEX_ACCESS_CTRL, LTECOEX_READY, 1)) + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr; + + if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1)) return false; - rtw_write32(rtwdev, LTECOEX_ACCESS_CTRL, 0x800F0000 | offset); - *val = rtw_read32(rtwdev, LTECOEX_READ_DATA); + rtw_write32(rtwdev, ltecoex->ctrl, 0x800F0000 | offset); + *val = rtw_read32(rtwdev, ltecoex->rdata); return true; } bool ltecoex_reg_write(struct rtw_dev *rtwdev, u16 offset, u32 value) { - if (!check_hw_ready(rtwdev, LTECOEX_ACCESS_CTRL, LTECOEX_READY, 1)) + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_ltecoex_addr *ltecoex = chip->ltecoex_addr; + + if (!check_hw_ready(rtwdev, ltecoex->ctrl, LTECOEX_READY, 1)) return false; - rtw_write32(rtwdev, LTECOEX_WRITE_DATA, value); - rtw_write32(rtwdev, LTECOEX_ACCESS_CTRL, 0xC00F0000 | offset); + rtw_write32(rtwdev, ltecoex->wdata, value); + rtw_write32(rtwdev, ltecoex->ctrl, 0xC00F0000 | offset); return true; } @@ -70,3 +76,30 @@ } } } + +void rtw_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss) +{ + if (rate <= DESC_RATE54M) + return; + + if (rate >= DESC_RATEVHT1SS_MCS0 && + rate <= DESC_RATEVHT1SS_MCS9) { + *nss = 1; + *mcs = rate - DESC_RATEVHT1SS_MCS0; + } else if (rate >= DESC_RATEVHT2SS_MCS0 && + rate <= DESC_RATEVHT2SS_MCS9) { + *nss = 2; + *mcs = rate - DESC_RATEVHT2SS_MCS0; + } else if (rate >= DESC_RATEVHT3SS_MCS0 && + rate <= DESC_RATEVHT3SS_MCS9) { + *nss = 3; + *mcs = rate - DESC_RATEVHT3SS_MCS0; + } else if (rate >= DESC_RATEVHT4SS_MCS0 && + rate <= DESC_RATEVHT4SS_MCS9) { + *nss = 4; + *mcs = rate - DESC_RATEVHT4SS_MCS0; + } else if (rate >= DESC_RATEMCS0 && + rate <= DESC_RATEMCS15) { + *mcs = rate - DESC_RATEMCS0; + } +} --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/util.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/util.h @@ -15,6 +15,8 @@ IEEE80211_IFACE_ITER_NORMAL, iterator, data) #define rtw_iterate_stas_atomic(rtwdev, iterator, data) \ ieee80211_iterate_stations_atomic(rtwdev->hw, iterator, data) +#define rtw_iterate_keys(rtwdev, vif, iterator, data) \ + ieee80211_iter_keys(rtwdev->hw, vif, iterator, data) static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/wow.c +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/wow.c @@ -0,0 +1,882 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#include "main.h" +#include "fw.h" +#include "wow.h" +#include "reg.h" +#include "debug.h" +#include "mac.h" +#include "ps.h" + +static void rtw_wow_show_wakeup_reason(struct rtw_dev *rtwdev) +{ + u8 reason; + + reason = rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON); + + if (reason == RTW_WOW_RSN_RX_DEAUTH) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx deauth\n"); + else if (reason == RTW_WOW_RSN_DISCONNECT) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: AP is off\n"); + else if (reason == RTW_WOW_RSN_RX_MAGIC_PKT) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx magic packet\n"); + else if (reason == RTW_WOW_RSN_RX_GTK_REKEY) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx gtk rekey\n"); + else if (reason == RTW_WOW_RSN_RX_PTK_REKEY) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx ptk rekey\n"); + else if (reason == RTW_WOW_RSN_RX_PATTERN_MATCH) + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: Rx pattern match packet\n"); + else if (reason == RTW_WOW_RSN_RX_NLO) + rtw_dbg(rtwdev, RTW_DBG_WOW, "Rx NLO\n"); + else + rtw_warn(rtwdev, "Unknown wakeup reason %x\n", reason); +} + +static void rtw_wow_pattern_write_cam(struct rtw_dev *rtwdev, u8 addr, + u32 wdata) +{ + rtw_write32(rtwdev, REG_WKFMCAM_RWD, wdata); + rtw_write32(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | + BIT_WKFCAM_WE | BIT_WKFCAM_ADDR_V2(addr)); + + if (!check_hw_ready(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1, 0)) + rtw_err(rtwdev, "failed to write pattern cam\n"); +} + +static void rtw_wow_pattern_write_cam_ent(struct rtw_dev *rtwdev, u8 id, + struct rtw_wow_pattern *rtw_pattern) +{ + int i; + u8 addr; + u32 wdata; + + for (i = 0; i < RTW_MAX_PATTERN_MASK_SIZE / 4; i++) { + addr = (id << 3) + i; + wdata = rtw_pattern->mask[i * 4]; + wdata |= rtw_pattern->mask[i * 4 + 1] << 8; + wdata |= rtw_pattern->mask[i * 4 + 2] << 16; + wdata |= rtw_pattern->mask[i * 4 + 3] << 24; + rtw_wow_pattern_write_cam(rtwdev, addr, wdata); + } + + wdata = rtw_pattern->crc; + addr = (id << 3) + RTW_MAX_PATTERN_MASK_SIZE / 4; + + switch (rtw_pattern->type) { + case RTW_PATTERN_BROADCAST: + wdata |= BIT_WKFMCAM_BC | BIT_WKFMCAM_VALID; + break; + case RTW_PATTERN_MULTICAST: + wdata |= BIT_WKFMCAM_MC | BIT_WKFMCAM_VALID; + break; + case RTW_PATTERN_UNICAST: + wdata |= BIT_WKFMCAM_UC | BIT_WKFMCAM_VALID; + break; + default: + break; + } + rtw_wow_pattern_write_cam(rtwdev, addr, wdata); +} + +/* RTK internal CRC16 for Pattern Cam */ +static u16 __rtw_cal_crc16(u8 data, u16 crc) +{ + u8 shift_in, data_bit; + u8 crc_bit4, crc_bit11, crc_bit15; + u16 crc_result; + int index; + + for (index = 0; index < 8; index++) { + crc_bit15 = ((crc & BIT(15)) ? 1 : 0); + data_bit = (data & (BIT(0) << index) ? 1 : 0); + shift_in = crc_bit15 ^ data_bit; + + crc_result = crc << 1; + + if (shift_in == 0) + crc_result &= (~BIT(0)); + else + crc_result |= BIT(0); + + crc_bit11 = ((crc & BIT(11)) ? 1 : 0) ^ shift_in; + + if (crc_bit11 == 0) + crc_result &= (~BIT(12)); + else + crc_result |= BIT(12); + + crc_bit4 = ((crc & BIT(4)) ? 1 : 0) ^ shift_in; + + if (crc_bit4 == 0) + crc_result &= (~BIT(5)); + else + crc_result |= BIT(5); + + crc = crc_result; + } + return crc; +} + +static u16 rtw_calc_crc(u8 *pdata, int length) +{ + u16 crc = 0xffff; + int i; + + for (i = 0; i < length; i++) + crc = __rtw_cal_crc16(pdata[i], crc); + + /* get 1' complement */ + return ~crc; +} + +static void rtw_wow_pattern_generate(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif, + const struct cfg80211_pkt_pattern *pkt_pattern, + struct rtw_wow_pattern *rtw_pattern) +{ + const u8 *mask; + const u8 *pattern; + u8 mask_hw[RTW_MAX_PATTERN_MASK_SIZE] = {0}; + u8 content[RTW_MAX_PATTERN_SIZE] = {0}; + u8 mac_addr[ETH_ALEN] = {0}; + u8 mask_len; + u16 count; + int len; + int i; + + pattern = pkt_pattern->pattern; + len = pkt_pattern->pattern_len; + mask = pkt_pattern->mask; + + ether_addr_copy(mac_addr, rtwvif->mac_addr); + memset(rtw_pattern, 0, sizeof(*rtw_pattern)); + + mask_len = DIV_ROUND_UP(len, 8); + + if (is_broadcast_ether_addr(pattern)) + rtw_pattern->type = RTW_PATTERN_BROADCAST; + else if (is_multicast_ether_addr(pattern)) + rtw_pattern->type = RTW_PATTERN_MULTICAST; + else if (ether_addr_equal(pattern, mac_addr)) + rtw_pattern->type = RTW_PATTERN_UNICAST; + else + rtw_pattern->type = RTW_PATTERN_INVALID; + + /* translate mask from os to mask for hw + * pattern from OS uses 'ethenet frame', like this: + * | 6 | 6 | 2 | 20 | Variable | 4 | + * |--------+--------+------+-----------+------------+-----| + * | 802.3 Mac Header | IP Header | TCP Packet | FCS | + * | DA | SA | Type | + * + * BUT, packet catched by our HW is in '802.11 frame', begin from LLC + * | 24 or 30 | 6 | 2 | 20 | Variable | 4 | + * |-------------------+--------+------+-----------+------------+-----| + * | 802.11 MAC Header | LLC | IP Header | TCP Packet | FCS | + * | Others | Tpye | + * + * Therefore, we need translate mask_from_OS to mask_to_hw. + * We should left-shift mask by 6 bits, then set the new bit[0~5] = 0, + * because new mask[0~5] means 'SA', but our HW packet begins from LLC, + * bit[0~5] corresponds to first 6 Bytes in LLC, they just don't match. + */ + + /* Shift 6 bits */ + for (i = 0; i < mask_len - 1; i++) { + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); + mask_hw[i] |= u8_get_bits(mask[i + 1], GENMASK(5, 0)) << 2; + } + mask_hw[i] = u8_get_bits(mask[i], GENMASK(7, 6)); + + /* Set bit 0-5 to zero */ + mask_hw[0] &= (~GENMASK(5, 0)); + + memcpy(rtw_pattern->mask, mask_hw, RTW_MAX_PATTERN_MASK_SIZE); + + /* To get the wake up pattern from the mask. + * We do not count first 12 bits which means + * DA[6] and SA[6] in the pattern to match HW design. + */ + count = 0; + for (i = 12; i < len; i++) { + if ((mask[i / 8] >> (i % 8)) & 0x01) { + content[count] = pattern[i]; + count++; + } + } + + rtw_pattern->crc = rtw_calc_crc(content, count); +} + +static void rtw_wow_pattern_clear_cam(struct rtw_dev *rtwdev) +{ + bool ret; + + rtw_write32(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1 | + BIT_WKFCAM_CLR_V1); + + ret = check_hw_ready(rtwdev, REG_WKFMCAM_CMD, BIT_WKFCAM_POLLING_V1, 0); + if (!ret) + rtw_err(rtwdev, "failed to clean pattern cam\n"); +} + +static void rtw_wow_pattern_write(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_wow_pattern *rtw_pattern = rtw_wow->patterns; + int i = 0; + + for (i = 0; i < rtw_wow->pattern_cnt; i++) + rtw_wow_pattern_write_cam_ent(rtwdev, i, rtw_pattern + i); +} + +static void rtw_wow_pattern_clear(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + rtw_wow_pattern_clear_cam(rtwdev); + + rtw_wow->pattern_cnt = 0; + memset(rtw_wow->patterns, 0, sizeof(rtw_wow->patterns)); +} + +static void rtw_wow_bb_stop(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + /* wait 100ms for firmware to finish TX */ + msleep(100); + + if (!rtw_read32_mask(rtwdev, REG_BCNQ_INFO, BIT_MGQ_CPU_EMPTY)) + rtw_warn(rtwdev, "Wrong status of MGQ_CPU empty!\n"); + + rtw_wow->txpause = rtw_read8(rtwdev, REG_TXPAUSE); + rtw_write8(rtwdev, REG_TXPAUSE, 0xff); + rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); +} + +static void rtw_wow_bb_start(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_BB_RSTB); + rtw_write8(rtwdev, REG_TXPAUSE, rtw_wow->txpause); +} + +static void rtw_wow_rx_dma_stop(struct rtw_dev *rtwdev) +{ + /* wait 100ms for HW to finish rx dma */ + msleep(100); + + rtw_write32_set(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE); + + if (!check_hw_ready(rtwdev, REG_RXPKT_NUM, BIT_RXDMA_IDLE, 1)) + rtw_err(rtwdev, "failed to stop rx dma\n"); +} + +static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev) +{ + rtw_write32_clr(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE); +} + +static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable) +{ + /* wait 100ms for wow firmware to finish work */ + msleep(100); + + if (wow_enable) { + if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON)) + goto wow_fail; + } else { + if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) || + rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE)) + goto wow_fail; + } + + return 0; + +wow_fail: + rtw_err(rtwdev, "failed to check wow status %s\n", + wow_enable ? "enabled" : "disabled"); + return -EBUSY; +} + +static void rtw_wow_fw_security_type_iter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key, + void *data) +{ + struct rtw_fw_key_type_iter_data *iter_data = data; + struct rtw_dev *rtwdev = hw->priv; + u8 hw_key_type; + + if (vif != rtwdev->wow.wow_vif) + return; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + hw_key_type = RTW_CAM_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + hw_key_type = RTW_CAM_WEP104; + break; + case WLAN_CIPHER_SUITE_TKIP: + hw_key_type = RTW_CAM_TKIP; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + break; + case WLAN_CIPHER_SUITE_CCMP: + hw_key_type = RTW_CAM_AES; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; + break; + default: + rtw_err(rtwdev, "Unsupported key type for wowlan mode\n"); + hw_key_type = 0; + break; + } + + if (sta) + iter_data->pairwise_key_type = hw_key_type; + else + iter_data->group_key_type = hw_key_type; +} + +static void rtw_wow_fw_security_type(struct rtw_dev *rtwdev) +{ + struct rtw_fw_key_type_iter_data data = {}; + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + + data.rtwdev = rtwdev; + rtw_iterate_keys(rtwdev, wow_vif, + rtw_wow_fw_security_type_iter, &data); + rtw_fw_set_aoac_global_info_cmd(rtwdev, data.pairwise_key_type, + data.group_key_type); +} + +static int rtw_wow_fw_start(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + if (rtw_wow_mgd_linked(rtwdev)) { + rtw_send_rsvd_page_h2c(rtwdev); + rtw_wow_pattern_write(rtwdev); + rtw_wow_fw_security_type(rtwdev); + rtw_fw_set_disconnect_decision_cmd(rtwdev, true); + rtw_fw_set_keep_alive_cmd(rtwdev, true); + } else if (rtw_wow_no_link(rtwdev)) { + rtw_fw_set_nlo_info(rtwdev, true); + rtw_fw_update_pkt_probe_req(rtwdev, NULL); + rtw_fw_channel_switch(rtwdev, true); + } + + rtw_fw_set_default_port(rtwdev, rtwvif->port); + rtw_fw_set_wowlan_ctrl_cmd(rtwdev, true); + rtw_fw_set_remote_wake_ctrl_cmd(rtwdev, true); + + return rtw_wow_check_fw_status(rtwdev, true); +} + +static int rtw_wow_fw_stop(struct rtw_dev *rtwdev) +{ + if (rtw_wow_mgd_linked(rtwdev)) { + rtw_fw_set_disconnect_decision_cmd(rtwdev, false); + rtw_fw_set_keep_alive_cmd(rtwdev, false); + rtw_wow_pattern_clear(rtwdev); + } else if (rtw_wow_no_link(rtwdev)) { + rtw_fw_channel_switch(rtwdev, false); + rtw_fw_set_nlo_info(rtwdev, false); + } + + rtw_fw_set_wowlan_ctrl_cmd(rtwdev, false); + rtw_fw_set_remote_wake_ctrl_cmd(rtwdev, false); + + return rtw_wow_check_fw_status(rtwdev, false); +} + +static void rtw_wow_avoid_reset_mac(struct rtw_dev *rtwdev) +{ + /* When resuming from wowlan mode, some hosts issue signal + * (PCIE: PREST, USB: SE0RST) to device, and lead to reset + * mac core. If it happens, the connection to AP will be lost. + * Setting REG_RSV_CTRL Register can avoid this process. + */ + switch (rtw_hci_type(rtwdev)) { + case RTW_HCI_TYPE_PCIE: + case RTW_HCI_TYPE_USB: + rtw_write8(rtwdev, REG_RSV_CTRL, BIT_WLOCK_1C_B6); + rtw_write8(rtwdev, REG_RSV_CTRL, + BIT_WLOCK_1C_B6 | BIT_R_DIS_PRST); + break; + default: + rtw_warn(rtwdev, "Unsupported hci type to disable reset MAC\n"); + break; + } +} + +static void rtw_wow_fw_media_status_iter(void *data, struct ieee80211_sta *sta) +{ + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + struct rtw_fw_media_status_iter_data *iter_data = data; + struct rtw_dev *rtwdev = iter_data->rtwdev; + + rtw_fw_media_status_report(rtwdev, si->mac_id, iter_data->connect); +} + +static void rtw_wow_fw_media_status(struct rtw_dev *rtwdev, bool connect) +{ + struct rtw_fw_media_status_iter_data data; + + data.rtwdev = rtwdev; + data.connect = connect; + + rtw_iterate_stas_atomic(rtwdev, rtw_wow_fw_media_status_iter, &data); +} + +static void rtw_wow_config_pno_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + rtw_add_rsvd_page_pno(rtwdev, rtwvif); +} + +static void rtw_wow_config_linked_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + rtw_add_rsvd_page_sta(rtwdev, rtwvif); +} + +static void rtw_wow_config_rsvd_page(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif) +{ + rtw_remove_rsvd_page(rtwdev, rtwvif); + + if (rtw_wow_mgd_linked(rtwdev)) { + rtw_wow_config_linked_rsvd_page(rtwdev, rtwvif); + } else if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags) && + rtw_wow_no_link(rtwdev)) { + rtw_wow_config_pno_rsvd_page(rtwdev, rtwvif); + } +} + +static int rtw_wow_dl_fw_rsvd_page(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + rtw_wow_config_rsvd_page(rtwdev, rtwvif); + + return rtw_fw_download_rsvd_page(rtwdev); +} + +static int rtw_wow_swap_fw(struct rtw_dev *rtwdev, enum rtw_fw_type type) +{ + struct rtw_fw_state *fw; + int ret; + + switch (type) { + case RTW_WOWLAN_FW: + fw = &rtwdev->wow_fw; + break; + + case RTW_NORMAL_FW: + fw = &rtwdev->fw; + break; + + default: + rtw_warn(rtwdev, "unsupported firmware type to swap\n"); + return -ENOENT; + } + + ret = rtw_download_firmware(rtwdev, fw); + if (ret) + goto out; + + rtw_fw_send_general_info(rtwdev); + rtw_fw_send_phydm_info(rtwdev); + rtw_wow_fw_media_status(rtwdev, true); + +out: + return ret; +} + +static void rtw_wow_check_pno(struct rtw_dev *rtwdev, + struct cfg80211_sched_scan_request *nd_config) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *pno_req = &rtw_wow->pno_req; + struct ieee80211_channel *channel; + int i, size; + + if (!nd_config->n_match_sets || !nd_config->n_channels) + goto err; + + pno_req->match_set_cnt = nd_config->n_match_sets; + size = sizeof(*pno_req->match_sets) * pno_req->match_set_cnt; + pno_req->match_sets = kmemdup(nd_config->match_sets, size, GFP_KERNEL); + if (!pno_req->match_sets) + goto err; + + pno_req->channel_cnt = nd_config->n_channels; + size = sizeof(*nd_config->channels[0]) * nd_config->n_channels; + pno_req->channels = kmalloc(size, GFP_KERNEL); + if (!pno_req->channels) + goto channel_err; + + for (i = 0 ; i < pno_req->channel_cnt; i++) { + channel = pno_req->channels + i; + memcpy(channel, nd_config->channels[i], sizeof(*channel)); + } + + pno_req->scan_plan = *nd_config->scan_plans; + pno_req->inited = true; + + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: net-detect is enabled\n"); + + return; + +channel_err: + kfree(pno_req->match_sets); + +err: + rtw_dbg(rtwdev, RTW_DBG_WOW, "WOW: net-detect is disabled\n"); +} + +static int rtw_wow_leave_linked_ps(struct rtw_dev *rtwdev) +{ + if (!test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) + cancel_delayed_work_sync(&rtwdev->watch_dog_work); + + rtw_leave_lps(rtwdev); + + return 0; +} + +static int rtw_wow_leave_no_link_ps(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + int ret = 0; + + if (test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) { + if (rtw_fw_lps_deep_mode) + rtw_leave_lps_deep(rtwdev); + } else { + if (test_bit(RTW_FLAG_INACTIVE_PS, rtwdev->flags)) { + rtw_wow->ips_enabled = true; + ret = rtw_leave_ips(rtwdev); + if (ret) + return ret; + } + } + + return 0; +} + +static int rtw_wow_leave_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_mgd_linked(rtwdev)) + ret = rtw_wow_leave_linked_ps(rtwdev); + else if (rtw_wow_no_link(rtwdev)) + ret = rtw_wow_leave_no_link_ps(rtwdev); + + return ret; +} + +static int rtw_wow_restore_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_no_link(rtwdev) && rtwdev->wow.ips_enabled) + ret = rtw_enter_ips(rtwdev); + + return ret; +} + +static int rtw_wow_enter_linked_ps(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct ieee80211_vif *wow_vif = rtw_wow->wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + rtw_enter_lps(rtwdev, rtwvif->port); + + return 0; +} + +static int rtw_wow_enter_no_link_ps(struct rtw_dev *rtwdev) +{ + /* firmware enters deep ps by itself if supported */ + set_bit(RTW_FLAG_LEISURE_PS_DEEP, rtwdev->flags); + + return 0; +} + +static int rtw_wow_enter_ps(struct rtw_dev *rtwdev) +{ + int ret = 0; + + if (rtw_wow_mgd_linked(rtwdev)) + ret = rtw_wow_enter_linked_ps(rtwdev); + else if (rtw_wow_no_link(rtwdev) && rtw_fw_lps_deep_mode) + ret = rtw_wow_enter_no_link_ps(rtwdev); + + return ret; +} + +static void rtw_wow_stop_trx(struct rtw_dev *rtwdev) +{ + rtw_wow_bb_stop(rtwdev); + rtw_wow_rx_dma_stop(rtwdev); +} + +static int rtw_wow_start(struct rtw_dev *rtwdev) +{ + int ret; + + ret = rtw_wow_fw_start(rtwdev); + if (ret) + goto out; + + rtw_hci_stop(rtwdev); + rtw_wow_bb_start(rtwdev); + rtw_wow_avoid_reset_mac(rtwdev); + +out: + return ret; +} + +static int rtw_wow_enable(struct rtw_dev *rtwdev) +{ + int ret = 0; + + rtw_wow_stop_trx(rtwdev); + + ret = rtw_wow_swap_fw(rtwdev, RTW_WOWLAN_FW); + if (ret) { + rtw_err(rtwdev, "failed to swap wow fw\n"); + goto error; + } + + set_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + + ret = rtw_wow_dl_fw_rsvd_page(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to download wowlan rsvd page\n"); + goto error; + } + + ret = rtw_wow_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start wow\n"); + goto error; + } + + return ret; + +error: + clear_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + return ret; +} + +static int rtw_wow_stop(struct rtw_dev *rtwdev) +{ + int ret; + + /* some HCI related registers will be reset after resume, + * need to set them again. + */ + ret = rtw_hci_setup(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to setup hci\n"); + return ret; + } + + ret = rtw_hci_start(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to start hci\n"); + return ret; + } + + ret = rtw_wow_fw_stop(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to stop wowlan fw\n"); + + rtw_wow_bb_stop(rtwdev); + + return ret; +} + +static void rtw_wow_resume_trx(struct rtw_dev *rtwdev) +{ + rtw_wow_rx_dma_start(rtwdev); + rtw_wow_bb_start(rtwdev); + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work, + RTW_WATCH_DOG_DELAY_TIME); +} + +static int rtw_wow_disable(struct rtw_dev *rtwdev) +{ + int ret; + + clear_bit(RTW_FLAG_WOWLAN, rtwdev->flags); + + ret = rtw_wow_stop(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to stop wow\n"); + goto out; + } + + ret = rtw_wow_swap_fw(rtwdev, RTW_NORMAL_FW); + if (ret) { + rtw_err(rtwdev, "failed to swap normal fw\n"); + goto out; + } + + ret = rtw_wow_dl_fw_rsvd_page(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to download normal rsvd page\n"); + +out: + rtw_wow_resume_trx(rtwdev); + return ret; +} + +static void rtw_wow_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct rtw_dev *rtwdev = data; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + + /* Current wowlan function support setting of only one STATION vif. + * So when one suitable vif is found, stop the iteration. + */ + if (rtw_wow->wow_vif || vif->type != NL80211_IFTYPE_STATION) + return; + + switch (rtwvif->net_type) { + case RTW_NET_MGD_LINKED: + rtw_wow->wow_vif = vif; + break; + case RTW_NET_NO_LINK: + if (rtw_wow->pno_req.inited) + rtwdev->wow.wow_vif = vif; + break; + default: + break; + } +} + +static int rtw_wow_set_wakeups(struct rtw_dev *rtwdev, + struct cfg80211_wowlan *wowlan) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_wow_pattern *rtw_patterns = rtw_wow->patterns; + struct rtw_vif *rtwvif; + int i; + + if (wowlan->disconnect) + set_bit(RTW_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags); + if (wowlan->magic_pkt) + set_bit(RTW_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags); + if (wowlan->gtk_rekey_failure) + set_bit(RTW_WOW_FLAG_EN_REKEY_PKT, rtw_wow->flags); + + if (wowlan->nd_config) + rtw_wow_check_pno(rtwdev, wowlan->nd_config); + + rtw_iterate_vifs_atomic(rtwdev, rtw_wow_vif_iter, rtwdev); + if (!rtw_wow->wow_vif) + return -EPERM; + + rtwvif = (struct rtw_vif *)rtw_wow->wow_vif->drv_priv; + if (wowlan->n_patterns && wowlan->patterns) { + rtw_wow->pattern_cnt = wowlan->n_patterns; + for (i = 0; i < wowlan->n_patterns; i++) + rtw_wow_pattern_generate(rtwdev, rtwvif, + wowlan->patterns + i, + rtw_patterns + i); + } + + return 0; +} + +static void rtw_wow_clear_wakeups(struct rtw_dev *rtwdev) +{ + struct rtw_wow_param *rtw_wow = &rtwdev->wow; + struct rtw_pno_request *pno_req = &rtw_wow->pno_req; + + if (pno_req->inited) { + kfree(pno_req->channels); + kfree(pno_req->match_sets); + } + + memset(rtw_wow, 0, sizeof(rtwdev->wow)); +} + +int rtw_wow_suspend(struct rtw_dev *rtwdev, struct cfg80211_wowlan *wowlan) +{ + int ret = 0; + + ret = rtw_wow_set_wakeups(rtwdev, wowlan); + if (ret) { + rtw_err(rtwdev, "failed to set wakeup event\n"); + goto out; + } + + ret = rtw_wow_leave_ps(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave ps from normal mode\n"); + goto out; + } + + ret = rtw_wow_enable(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to enable wow\n"); + rtw_wow_restore_ps(rtwdev); + goto out; + } + + ret = rtw_wow_enter_ps(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to enter ps for wow\n"); + +out: + return ret; +} + +int rtw_wow_resume(struct rtw_dev *rtwdev) +{ + int ret; + + /* If wowlan mode is not enabled, do nothing */ + if (!test_bit(RTW_FLAG_WOWLAN, rtwdev->flags)) { + rtw_err(rtwdev, "wow is not enabled\n"); + ret = -EPERM; + goto out; + } + + ret = rtw_wow_leave_ps(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to leave ps from wowlan mode\n"); + goto out; + } + + rtw_wow_show_wakeup_reason(rtwdev); + + ret = rtw_wow_disable(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to disable wow\n"); + goto out; + } + + ret = rtw_wow_restore_ps(rtwdev); + if (ret) + rtw_err(rtwdev, "failed to restore ps to normal mode\n"); + +out: + rtw_wow_clear_wakeups(rtwdev); + return ret; +} --- linux-oracle-5.4.0.orig/drivers/net/wireless/realtek/rtw88/wow.h +++ linux-oracle-5.4.0/drivers/net/wireless/realtek/rtw88/wow.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ +/* Copyright(c) 2018-2019 Realtek Corporation + */ + +#ifndef __RTW_WOW_H__ +#define __RTW_WOW_H__ + +#define PNO_CHECK_BYTE 4 + +enum rtw_wow_pattern_type { + RTW_PATTERN_BROADCAST = 0, + RTW_PATTERN_MULTICAST, + RTW_PATTERN_UNICAST, + RTW_PATTERN_VALID, + RTW_PATTERN_INVALID, +}; + +enum rtw_wake_reason { + RTW_WOW_RSN_RX_PTK_REKEY = 0x1, + RTW_WOW_RSN_RX_GTK_REKEY = 0x2, + RTW_WOW_RSN_RX_DEAUTH = 0x8, + RTW_WOW_RSN_DISCONNECT = 0x10, + RTW_WOW_RSN_RX_MAGIC_PKT = 0x21, + RTW_WOW_RSN_RX_PATTERN_MATCH = 0x23, + RTW_WOW_RSN_RX_NLO = 0x55, +}; + +struct rtw_fw_media_status_iter_data { + struct rtw_dev *rtwdev; + u8 connect; +}; + +struct rtw_fw_key_type_iter_data { + struct rtw_dev *rtwdev; + u8 group_key_type; + u8 pairwise_key_type; +}; + +static inline bool rtw_wow_mgd_linked(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + return (rtwvif->net_type == RTW_NET_MGD_LINKED); +} + +static inline bool rtw_wow_no_link(struct rtw_dev *rtwdev) +{ + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw_vif *rtwvif = (struct rtw_vif *)wow_vif->drv_priv; + + return (rtwvif->net_type == RTW_NET_NO_LINK); +} + +int rtw_wow_suspend(struct rtw_dev *rtwdev, struct cfg80211_wowlan *wowlan); +int rtw_wow_resume(struct rtw_dev *rtwdev); + +#endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/rndis_wlan.c +++ linux-oracle-5.4.0/drivers/net/wireless/rndis_wlan.c @@ -700,8 +700,8 @@ struct rndis_query *get; struct rndis_query_c *get_c; } u; - int ret, buflen; - int resplen, respoffs, copylen; + int ret; + size_t buflen, resplen, respoffs, copylen; buflen = *len + sizeof(*u.get); if (buflen < CONTROL_BUFFER_SIZE) @@ -736,22 +736,15 @@ if (respoffs > buflen) { /* Device returned data offset outside buffer, error. */ - netdev_dbg(dev->net, "%s(%s): received invalid " - "data offset: %d > %d\n", __func__, - oid_to_string(oid), respoffs, buflen); + netdev_dbg(dev->net, + "%s(%s): received invalid data offset: %zu > %zu\n", + __func__, oid_to_string(oid), respoffs, buflen); ret = -EINVAL; goto exit_unlock; } - if ((resplen + respoffs) > buflen) { - /* Device would have returned more data if buffer would - * have been big enough. Copy just the bits that we got. - */ - copylen = buflen - respoffs; - } else { - copylen = resplen; - } + copylen = min(resplen, buflen - respoffs); if (copylen > *len) copylen = *len; --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_coex.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_coex.c @@ -160,6 +160,7 @@ rsi_coex_scheduler_thread, "Coex-Tx-Thread")) { rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__); + kfree(coex_cb); return -EINVAL; } return 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_core.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_core.c @@ -400,6 +400,8 @@ info = IEEE80211_SKB_CB(skb); tx_params = (struct skb_info *)info->driver_data; + /* info->driver_data and info->control part of union so make copy */ + tx_params->have_key = !!info->control.hw_key; wh = (struct ieee80211_hdr *)&skb->data[0]; tx_params->sta_id = 0; @@ -464,7 +466,9 @@ tid, 0); } } - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { + + if (IEEE80211_SKB_CB(skb)->control.flags & + IEEE80211_TX_CTRL_PORT_CTRL_PROTO) { q_num = MGMT_SOFT_Q; skb->priority = q_num; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_hal.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -162,12 +162,16 @@ u8 header_size; u8 vap_id = 0; u8 dword_align_bytes; + bool tx_eapol; u16 seq_num; info = IEEE80211_SKB_CB(skb); vif = info->control.vif; tx_params = (struct skb_info *)info->driver_data; + tx_eapol = IEEE80211_SKB_CB(skb)->control.flags & + IEEE80211_TX_CTRL_PORT_CTRL_PROTO; + header_size = FRAME_DESC_SZ + sizeof(struct rsi_xtended_desc); if (header_size > skb_headroom(skb)) { rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__); @@ -203,7 +207,7 @@ wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE); if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) && - (common->secinfo.security_enable)) { + tx_params->have_key) { if (rsi_is_cipher_wep(common)) ieee80211_size += 4; else @@ -214,22 +218,24 @@ RSI_WIFI_DATA_Q); data_desc->header_len = ieee80211_size; - if (common->min_rate != RSI_RATE_AUTO) { + if (common->rate_config[common->band].fixed_enabled) { /* Send fixed rate */ + u16 fixed_rate = common->rate_config[common->band].fixed_hw_rate; + data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE); - data_desc->rate_info = cpu_to_le16(common->min_rate); + data_desc->rate_info = cpu_to_le16(fixed_rate); if (conf_is_ht40(&common->priv->hw->conf)) data_desc->bbp_info = cpu_to_le16(FULL40M_ENABLE); - if ((common->vif_info[0].sgi) && (common->min_rate & 0x100)) { + if (common->vif_info[0].sgi && (fixed_rate & 0x100)) { /* Only MCS rates */ data_desc->rate_info |= cpu_to_le16(ENABLE_SHORTGI_RATE); } } - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) { + if (tx_eapol) { rsi_dbg(INFO_ZONE, "*** Tx EAPOL ***\n"); data_desc->frame_info = cpu_to_le16(RATE_INFO_ENABLE); @@ -248,7 +254,8 @@ rsi_set_len_qno(&data_desc->len_qno, (skb->len - FRAME_DESC_SZ), RSI_WIFI_MGMT_Q); - if ((skb->len - header_size) == EAPOL4_PACKET_LEN) { + if (((skb->len - header_size) == EAPOL4_PACKET_LEN) || + ((skb->len - header_size) == EAPOL4_PACKET_LEN - 2)) { data_desc->misc_flags |= RSI_DESC_REQUIRE_CFM_TO_HOST; xtend_desc->confirm_frame_type = EAPOL4_CONFIRM; @@ -469,9 +476,9 @@ } if (common->band == NL80211_BAND_2GHZ) - bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_1); + bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_1); else - bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_6); + bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_6); if (mac_bcn->data[tim_offset + 2] == 0) bcn_frm->frame_info |= cpu_to_le16(RSI_DATA_DESC_DTIM_BEACON); @@ -622,6 +629,7 @@ bl_start_cmd_timer(adapter, timeout); status = bl_write_cmd(adapter, cmd, exp_resp, ®out_val); if (status < 0) { + bl_stop_cmd_timer(adapter); rsi_dbg(ERR_ZONE, "%s: Command %s (%0x) writing failed..\n", __func__, str, cmd); @@ -737,10 +745,9 @@ } status = bl_cmd(adapter, cmd_req, cmd_resp, str); - if (status) { - bl_stop_cmd_timer(adapter); + if (status) return status; - } + return 0; } @@ -828,10 +835,9 @@ status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL, "EOF_REACHED"); - if (status) { - bl_stop_cmd_timer(adapter); + if (status) return status; - } + rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n"); return 0; } @@ -849,6 +855,7 @@ ®out_val, RSI_COMMON_REG_SIZE); if (status < 0) { + bl_stop_cmd_timer(adapter); rsi_dbg(ERR_ZONE, "%s: REGOUT read failed\n", __func__); return status; @@ -1037,8 +1044,10 @@ } ta_firmware = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); - if (!ta_firmware) + if (!ta_firmware) { + status = -ENOMEM; goto fail_release_fw; + } fw_p = ta_firmware; instructions_sz = fw_entry->size; rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", instructions_sz); --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -510,7 +510,6 @@ if ((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_P2P_GO)) { rsi_send_rx_filter_frame(common, DISALLOW_BEACONS); - common->min_rate = RSI_RATE_AUTO; for (i = 0; i < common->max_stations; i++) common->stations[i].sta = NULL; } @@ -1027,7 +1026,6 @@ mutex_lock(&common->mutex); switch (cmd) { case SET_KEY: - secinfo->security_enable = true; status = rsi_hal_key_config(hw, vif, key, sta); if (status) { mutex_unlock(&common->mutex); @@ -1046,8 +1044,6 @@ break; case DISABLE_KEY: - if (vif->type == NL80211_IFTYPE_STATION) - secinfo->security_enable = false; rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__); memset(key, 0, sizeof(struct ieee80211_key_conf)); status = rsi_hal_key_config(hw, vif, key, sta); @@ -1140,8 +1136,7 @@ else if ((vif->type == NL80211_IFTYPE_AP) || (vif->type == NL80211_IFTYPE_P2P_GO)) rsta->seq_start[tid] = seq_no; - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - status = 0; + status = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; case IEEE80211_AMPDU_TX_STOP_CONT: @@ -1214,20 +1209,32 @@ struct ieee80211_vif *vif, const struct cfg80211_bitrate_mask *mask) { + const unsigned int mcs_offset = ARRAY_SIZE(rsi_rates); struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; - enum nl80211_band band = hw->conf.chandef.chan->band; + int i; mutex_lock(&common->mutex); - common->fixedrate_mask[band] = 0; - if (mask->control[band].legacy == 0xfff) { - common->fixedrate_mask[band] = - (mask->control[band].ht_mcs[0] << 12); - } else { - common->fixedrate_mask[band] = - mask->control[band].legacy; + for (i = 0; i < ARRAY_SIZE(common->rate_config); i++) { + struct rsi_rate_config *cfg = &common->rate_config[i]; + u32 bm; + + bm = mask->control[i].legacy | (mask->control[i].ht_mcs[0] << mcs_offset); + if (hweight32(bm) == 1) { /* single rate */ + int rate_index = ffs(bm) - 1; + + if (rate_index < mcs_offset) + cfg->fixed_hw_rate = rsi_rates[rate_index].hw_value; + else + cfg->fixed_hw_rate = rsi_mcsrates[rate_index - mcs_offset]; + cfg->fixed_enabled = true; + } else { + cfg->configured_mask = bm; + cfg->fixed_enabled = false; + } } + mutex_unlock(&common->mutex); return 0; @@ -1363,46 +1370,6 @@ ieee80211_rx_irqsafe(hw, skb); } -static void rsi_set_min_rate(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, - struct rsi_common *common) -{ - u8 band = hw->conf.chandef.chan->band; - u8 ii; - u32 rate_bitmap; - bool matched = false; - - common->bitrate_mask[band] = sta->supp_rates[band]; - - rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]); - - if (rate_bitmap & 0xfff) { - /* Find out the min rate */ - for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { - if (rate_bitmap & BIT(ii)) { - common->min_rate = rsi_rates[ii].hw_value; - matched = true; - break; - } - } - } - - common->vif_info[0].is_ht = sta->ht_cap.ht_supported; - - if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) { - for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) { - if ((rate_bitmap >> 12) & BIT(ii)) { - common->min_rate = rsi_mcsrates[ii]; - matched = true; - break; - } - } - } - - if (!matched) - common->min_rate = 0xffff; -} - /** * rsi_mac80211_sta_add() - This function notifies driver about a peer getting * connected. @@ -1501,9 +1468,9 @@ if ((vif->type == NL80211_IFTYPE_STATION) || (vif->type == NL80211_IFTYPE_P2P_CLIENT)) { - rsi_set_min_rate(hw, sta, common); + common->bitrate_mask[common->band] = sta->supp_rates[common->band]; + common->vif_info[0].is_ht = sta->ht_cap.ht_supported; if (sta->ht_cap.ht_supported) { - common->vif_info[0].is_ht = true; common->bitrate_mask[NL80211_BAND_2GHZ] = sta->supp_rates[NL80211_BAND_2GHZ]; if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || @@ -1577,7 +1544,6 @@ bss->qos = sta->wme; common->bitrate_mask[NL80211_BAND_2GHZ] = 0; common->bitrate_mask[NL80211_BAND_5GHZ] = 0; - common->min_rate = 0xffff; common->vif_info[0].is_ht = false; common->vif_info[0].sgi = false; common->vif_info[0].seq_start = 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_main.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_main.c @@ -23,6 +23,7 @@ #include "rsi_common.h" #include "rsi_coex.h" #include "rsi_hal.h" +#include "rsi_usb.h" u32 rsi_zone_enabled = /* INFO_ZONE | INIT_ZONE | @@ -167,6 +168,9 @@ frame_desc = &rx_pkt[index]; actual_length = *(u16 *)&frame_desc[0]; offset = *(u16 *)&frame_desc[2]; + if (!rcv_pkt_len && offset > + RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ) + goto fail; queueno = rsi_get_queueno(frame_desc, offset); length = rsi_get_length(frame_desc, offset); @@ -210,9 +214,10 @@ bt_pkt_type = frame_desc[offset + BT_RX_PKT_TYPE_OFST]; if (bt_pkt_type == BT_CARD_READY_IND) { rsi_dbg(INFO_ZONE, "BT Card ready recvd\n"); - if (rsi_bt_ops.attach(common, &g_proto_ops)) - rsi_dbg(ERR_ZONE, - "Failed to attach BT module\n"); + if (common->fsm_state == FSM_MAC_INIT_DONE) + rsi_attach_bt(common); + else + common->bt_defer_attach = true; } else { if (common->bt_adapter) rsi_bt_ops.recv_pkt(common->bt_adapter, @@ -277,6 +282,15 @@ } #endif +void rsi_attach_bt(struct rsi_common *common) +{ +#ifdef CONFIG_RSI_COEX + if (rsi_bt_ops.attach(common, &g_proto_ops)) + rsi_dbg(ERR_ZONE, + "Failed to attach BT module\n"); +#endif +} + /** * rsi_91x_init() - This function initializes os interface operations. * @void: Void. @@ -358,6 +372,7 @@ if (common->coex_mode > 1) { if (rsi_coex_attach(common)) { rsi_dbg(ERR_ZONE, "Failed to init coex module\n"); + rsi_kill_thread(&common->tx_thread); goto err; } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -276,7 +276,7 @@ common->channel_width = BW_20MHZ; common->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; common->channel = 1; - common->min_rate = 0xffff; + memset(&common->rate_config, 0, sizeof(common->rate_config)); common->fsm_state = FSM_CARD_NOT_READY; common->iface_down = true; common->endpoint = EP_2GHZ_20MHZ; @@ -1304,7 +1304,7 @@ u8 band = hw->conf.chandef.chan->band; u8 num_supported_rates = 0; u8 rate_table_offset, rate_offset = 0; - u32 rate_bitmap; + u32 rate_bitmap, configured_rates; u16 *selected_rates, min_rate; bool is_ht = false, is_sgi = false; u16 frame_len = sizeof(struct rsi_auto_rate); @@ -1354,6 +1354,10 @@ is_sgi = true; } + /* Limit to any rates administratively configured by cfg80211 */ + configured_rates = common->rate_config[band].configured_mask ?: 0xffffffff; + rate_bitmap &= configured_rates; + if (band == NL80211_BAND_2GHZ) { if ((rate_bitmap == 0) && (is_ht)) min_rate = RSI_RATE_MCS0; @@ -1379,10 +1383,13 @@ num_supported_rates = jj; if (is_ht) { - for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) - selected_rates[jj++] = mcs[ii]; - num_supported_rates += ARRAY_SIZE(mcs); - rate_offset += ARRAY_SIZE(mcs); + for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) { + if (configured_rates & BIT(ii + ARRAY_SIZE(rsi_rates))) { + selected_rates[jj++] = mcs[ii]; + num_supported_rates++; + rate_offset++; + } + } } sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL); @@ -1467,7 +1474,7 @@ qos_enable, aid, sta_id, vif); - if (common->min_rate == 0xffff) + if (!common->rate_config[common->band].fixed_enabled) rsi_send_auto_rate_request(common, sta, sta_id, vif); if (opmode == RSI_OPMODE_STA && !(assoc_cap & WLAN_CAPABILITY_PRIVACY) && @@ -1756,6 +1763,7 @@ skb_pull(skb, (64 - dword_align_bytes)); if (rsi_prepare_beacon(common, skb)) { rsi_dbg(ERR_ZONE, "Failed to prepare beacon\n"); + dev_kfree_skb(skb); return -EINVAL; } skb_queue_tail(&common->tx_queue[MGMT_BEACON_Q], skb); @@ -1787,8 +1795,7 @@ RSI_WIFI_MGMT_Q); cmd_frame->desc.desc_dword0.frame_type = WOWLAN_CONFIG_PARAMS; cmd_frame->host_sleep_status = sleep_status; - if (common->secinfo.security_enable && - common->secinfo.gtk_cipher) + if (common->secinfo.gtk_cipher) flags |= RSI_WOW_GTK_REKEY; if (sleep_status) cmd_frame->wow_flags = flags; @@ -2056,6 +2063,9 @@ if (common->reinit_hw) { complete(&common->wlan_init_completion); } else { + if (common->bt_defer_attach) + rsi_attach_bt(common); + return rsi_mac80211_attach(common); } } --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -24,10 +24,7 @@ /* Default operating mode is wlan STA + BT */ static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; module_param(dev_oper_mode, ushort, 0444); -MODULE_PARM_DESC(dev_oper_mode, - "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n" - "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" - "6[AP + BT classic], 14[AP + BT classic + BT LE]"); +MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC); /** * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg. @@ -153,9 +150,7 @@ if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED) return; - dev->sdio_irq_task = current; - rsi_interrupt_handler(adapter); - dev->sdio_irq_task = NULL; + rsi_set_event(&dev->rx_thread.event); } /** @@ -1059,8 +1054,6 @@ rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); goto fail_kill_thread; } - skb_queue_head_init(&sdev->rx_q.head); - sdev->rx_q.num_rx_pkts = 0; sdio_claim_host(pfunction); if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { @@ -1486,9 +1479,6 @@ if (sdev->write_fail) rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n"); - if (rsi_set_sdio_pm_caps(adapter)) - rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); - rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); } @@ -1515,7 +1505,7 @@ } static const struct dev_pm_ops rsi_pm_ops = { .suspend = rsi_suspend, - .resume = rsi_resume, + .resume_noirq = rsi_resume, .freeze = rsi_freeze, .thaw = rsi_thaw, .restore = rsi_restore, --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -60,39 +60,20 @@ return status; } +static void rsi_rx_handler(struct rsi_hw *adapter); + void rsi_sdio_rx_thread(struct rsi_common *common) { struct rsi_hw *adapter = common->priv; struct rsi_91x_sdiodev *sdev = adapter->rsi_dev; - struct sk_buff *skb; - int status; do { rsi_wait_event(&sdev->rx_thread.event, EVENT_WAIT_FOREVER); rsi_reset_event(&sdev->rx_thread.event); + rsi_rx_handler(adapter); + } while (!atomic_read(&sdev->rx_thread.thread_done)); - while (true) { - if (atomic_read(&sdev->rx_thread.thread_done)) - goto out; - - skb = skb_dequeue(&sdev->rx_q.head); - if (!skb) - break; - if (sdev->rx_q.num_rx_pkts > 0) - sdev->rx_q.num_rx_pkts--; - status = rsi_read_pkt(common, skb->data, skb->len); - if (status) { - rsi_dbg(ERR_ZONE, "Failed to read the packet\n"); - dev_kfree_skb(skb); - break; - } - dev_kfree_skb(skb); - } - } while (1); - -out: rsi_dbg(INFO_ZONE, "%s: Terminated SDIO RX thread\n", __func__); - skb_queue_purge(&sdev->rx_q.head); atomic_inc(&sdev->rx_thread.thread_done); complete_and_exit(&sdev->rx_thread.completion, 0); } @@ -113,10 +94,6 @@ u32 rcv_pkt_len = 0; int status = 0; u8 value = 0; - struct sk_buff *skb; - - if (dev->rx_q.num_rx_pkts >= RSI_MAX_RX_PKTS) - return 0; num_blks = ((adapter->interrupt_status & 1) | ((adapter->interrupt_status >> RECV_NUM_BLOCKS) << 1)); @@ -144,22 +121,19 @@ rcv_pkt_len = (num_blks * 256); - skb = dev_alloc_skb(rcv_pkt_len); - if (!skb) - return -ENOMEM; - - status = rsi_sdio_host_intf_read_pkt(adapter, skb->data, rcv_pkt_len); + status = rsi_sdio_host_intf_read_pkt(adapter, dev->pktbuffer, + rcv_pkt_len); if (status) { rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n", __func__); - dev_kfree_skb(skb); return status; } - skb_put(skb, rcv_pkt_len); - skb_queue_tail(&dev->rx_q.head, skb); - dev->rx_q.num_rx_pkts++; - rsi_set_event(&dev->rx_thread.event); + status = rsi_read_pkt(common, dev->pktbuffer, rcv_pkt_len); + if (status) { + rsi_dbg(ERR_ZONE, "Failed to read the packet\n"); + return status; + } return 0; } @@ -251,12 +225,12 @@ } /** - * rsi_interrupt_handler() - This function read and process SDIO interrupts. + * rsi_rx_handler() - Read and process SDIO interrupts. * @adapter: Pointer to the adapter structure. * * Return: None. */ -void rsi_interrupt_handler(struct rsi_hw *adapter) +static void rsi_rx_handler(struct rsi_hw *adapter) { struct rsi_common *common = adapter->priv; struct rsi_91x_sdiodev *dev = --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_91x_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -16,6 +16,7 @@ */ #include +#include #include #include "rsi_usb.h" #include "rsi_hal.h" @@ -24,12 +25,9 @@ /* Default operating mode is wlan STA + BT */ static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL; module_param(dev_oper_mode, ushort, 0444); -MODULE_PARM_DESC(dev_oper_mode, - "1[Wi-Fi], 4[BT], 8[BT LE], 5[Wi-Fi STA + BT classic]\n" - "9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n" - "6[AP + BT classic], 14[AP + BT classic + BT LE]"); +MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC); -static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num); +static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags); /** * rsi_usb_card_write() - This function writes to the USB Card. @@ -60,7 +58,7 @@ (void *)seg, (int)len, &transfer, - HZ * 5); + USB_CTRL_SET_TIMEOUT); if (status < 0) { rsi_dbg(ERR_ZONE, @@ -117,7 +115,7 @@ __le16 buffer_size; int ii, bin_found = 0, bout_found = 0; - iface_desc = &(interface->altsetting[0]); + iface_desc = interface->cur_altsetting; for (ii = 0; ii < iface_desc->desc.bNumEndpoints; ++ii) { endpoint = &(iface_desc->endpoint[ii].desc); @@ -263,8 +261,12 @@ struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data; int status = -EINVAL; + if (!rx_cb->rx_skb) + return; + if (urb->status) { dev_kfree_skb(rx_cb->rx_skb); + rx_cb->rx_skb = NULL; return; } @@ -285,11 +287,22 @@ status = 0; out: - if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num)) + if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC)) rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__); - if (status) + if (status) { dev_kfree_skb(rx_cb->rx_skb); + rx_cb->rx_skb = NULL; + } +} + +static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num) +{ + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; + struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; + struct urb *urb = rx_cb->rx_urb; + + usb_kill_urb(urb); } /** @@ -298,7 +311,7 @@ * * Return: 0 on success, a negative error code on failure. */ -static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num) +static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags) { struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1]; @@ -307,7 +320,6 @@ struct sk_buff *skb; u8 dword_align_bytes = 0; -#define RSI_MAX_RX_USB_PKT_SIZE 3000 skb = dev_alloc_skb(RSI_MAX_RX_USB_PKT_SIZE); if (!skb) return -ENOMEM; @@ -328,9 +340,11 @@ rsi_rx_done_handler, rx_cb); - status = usb_submit_urb(urb, GFP_KERNEL); - if (status) + status = usb_submit_urb(urb, mem_flags); + if (status) { rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__); + dev_kfree_skb(skb); + } return status; } @@ -721,24 +735,24 @@ if (ret < 0) goto fail; } else { - if ((rsi_usb_master_reg_write(adapter, - NWP_WWD_INTERRUPT_TIMER, - NWP_WWD_INT_TIMER_CLKS, - RSI_9116_REG_SIZE)) < 0) { + ret = rsi_usb_master_reg_write(adapter, + NWP_WWD_INTERRUPT_TIMER, + NWP_WWD_INT_TIMER_CLKS, + RSI_9116_REG_SIZE); + if (ret < 0) goto fail; - } - if ((rsi_usb_master_reg_write(adapter, - NWP_WWD_SYSTEM_RESET_TIMER, - NWP_WWD_SYS_RESET_TIMER_CLKS, - RSI_9116_REG_SIZE)) < 0) { + ret = rsi_usb_master_reg_write(adapter, + NWP_WWD_SYSTEM_RESET_TIMER, + NWP_WWD_SYS_RESET_TIMER_CLKS, + RSI_9116_REG_SIZE); + if (ret < 0) goto fail; - } - if ((rsi_usb_master_reg_write(adapter, - NWP_WWD_MODE_AND_RSTART, - NWP_WWD_TIMER_DISABLE, - RSI_9116_REG_SIZE)) < 0) { + ret = rsi_usb_master_reg_write(adapter, + NWP_WWD_MODE_AND_RSTART, + NWP_WWD_TIMER_DISABLE, + RSI_9116_REG_SIZE); + if (ret < 0) goto fail; - } } rsi_dbg(INFO_ZONE, "Reset card done\n"); @@ -794,6 +808,7 @@ } else { rsi_dbg(ERR_ZONE, "%s: Unsupported RSI device id 0x%x\n", __func__, id->idProduct); + status = -ENODEV; goto err1; } @@ -816,17 +831,20 @@ rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__); } - status = rsi_rx_urb_submit(adapter, WLAN_EP); + status = rsi_rx_urb_submit(adapter, WLAN_EP, GFP_KERNEL); if (status) goto err1; if (adapter->priv->coex_mode > 1) { - status = rsi_rx_urb_submit(adapter, BT_EP); + status = rsi_rx_urb_submit(adapter, BT_EP, GFP_KERNEL); if (status) - goto err1; + goto err_kill_wlan_urb; } return 0; + +err_kill_wlan_urb: + rsi_rx_urb_kill(adapter, WLAN_EP); err1: rsi_deinit_usb_interface(adapter); err: @@ -857,6 +875,10 @@ adapter->priv->bt_adapter = NULL; } + if (adapter->priv->coex_mode > 1) + rsi_rx_urb_kill(adapter, BT_EP); + rsi_rx_urb_kill(adapter, WLAN_EP); + rsi_reset_card(adapter); rsi_deinit_usb_interface(adapter); rsi_91x_deinit(adapter); --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_hal.h +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_hal.h @@ -28,6 +28,17 @@ #define DEV_OPMODE_AP_BT 6 #define DEV_OPMODE_AP_BT_DUAL 14 +#define DEV_OPMODE_PARAM_DESC \ + __stringify(DEV_OPMODE_WIFI_ALONE) "[Wi-Fi alone], " \ + __stringify(DEV_OPMODE_BT_ALONE) "[BT classic alone], " \ + __stringify(DEV_OPMODE_BT_LE_ALONE) "[BT LE alone], " \ + __stringify(DEV_OPMODE_BT_DUAL) "[BT classic + BT LE alone], " \ + __stringify(DEV_OPMODE_STA_BT) "[Wi-Fi STA + BT classic], " \ + __stringify(DEV_OPMODE_STA_BT_LE) "[Wi-Fi STA + BT LE], " \ + __stringify(DEV_OPMODE_STA_BT_DUAL) "[Wi-Fi STA + BT classic + BT LE], " \ + __stringify(DEV_OPMODE_AP_BT) "[Wi-Fi AP + BT classic], " \ + __stringify(DEV_OPMODE_AP_BT_DUAL) "[Wi-Fi AP + BT classic + BT LE]" + #define FLASH_WRITE_CHUNK_SIZE (4 * 1024) #define FLASH_SECTOR_SIZE (4 * 1024) --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_main.h +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_main.h @@ -61,6 +61,7 @@ extern u32 rsi_zone_enabled; extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...); +#define RSI_MAX_BANDS 2 #define RSI_MAX_VIFS 3 #define NUM_EDCA_QUEUES 4 #define IEEE80211_ADDR_LEN 6 @@ -139,6 +140,7 @@ u8 internal_hdr_size; struct ieee80211_vif *vif; u8 vap_id; + bool have_key; }; enum edca_queue { @@ -151,7 +153,6 @@ }; struct security_info { - bool security_enable; u32 ptk_cipher; u32 gtk_cipher; }; @@ -230,6 +231,12 @@ u32 ps_options; }; +struct rsi_rate_config { + u32 configured_mask; /* configured by mac80211 bits 0-11=legacy 12+ mcs */ + u16 fixed_hw_rate; + bool fixed_enabled; +}; + struct rsi_common { struct rsi_hw *priv; struct vif_priv vif_info[RSI_MAX_VIFS]; @@ -255,8 +262,8 @@ u8 channel_width; u16 rts_threshold; - u16 bitrate_mask[2]; - u32 fixedrate_mask[2]; + u32 bitrate_mask[RSI_MAX_BANDS]; + struct rsi_rate_config rate_config[RSI_MAX_BANDS]; u8 rf_reset; struct transmit_q_stats tx_stats; @@ -277,7 +284,6 @@ u8 mac_id; u8 radio_id; u16 rate_pwr[20]; - u16 min_rate; /* WMM algo related */ u8 selected_qnum; @@ -321,6 +327,7 @@ struct ieee80211_vif *roc_vif; bool eapol4_confirm; + bool bt_defer_attach; void *bt_adapter; struct cfg80211_scan_request *hwscan; @@ -402,5 +409,6 @@ enum rsi_host_intf rsi_get_host_intf(void *priv); void rsi_set_bt_context(void *priv, void *bt_context); +void rsi_attach_bt(struct rsi_common *common); #endif --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_sdio.h +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_sdio.h @@ -111,11 +111,6 @@ u32 buf_available_counter; }; -struct rsi_sdio_rx_q { - u8 num_rx_pkts; - struct sk_buff_head head; -}; - struct rsi_91x_sdiodev { struct sdio_func *pfunction; struct task_struct *sdio_irq_task; @@ -128,11 +123,10 @@ u16 tx_blk_size; u8 write_fail; bool buff_status_updated; - struct rsi_sdio_rx_q rx_q; struct rsi_thread rx_thread; + u8 pktbuffer[8192] __aligned(4); }; -void rsi_interrupt_handler(struct rsi_hw *adapter); int rsi_init_sdio_slave_regs(struct rsi_hw *adapter); int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data); int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length); --- linux-oracle-5.4.0.orig/drivers/net/wireless/rsi/rsi_usb.h +++ linux-oracle-5.4.0/drivers/net/wireless/rsi/rsi_usb.h @@ -44,6 +44,8 @@ #define RSI_USB_BUF_SIZE 4096 #define RSI_USB_CTRL_BUF_SIZE 0x04 +#define RSI_MAX_RX_USB_PKT_SIZE 3000 + struct rx_usb_ctrl_block { u8 *data; struct urb *rx_urb; --- linux-oracle-5.4.0.orig/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ linux-oracle-5.4.0/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -60,6 +60,7 @@ { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) }, { /* end: all zeroes */ }, }; +MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids); /* hwbus_ops implemetation */ --- linux-oracle-5.4.0.orig/drivers/net/wireless/st/cw1200/fwio.c +++ linux-oracle-5.4.0/drivers/net/wireless/st/cw1200/fwio.c @@ -320,12 +320,12 @@ goto out; } - priv->hw_type = cw1200_get_hw_type(val32, &major_revision); - if (priv->hw_type < 0) { + ret = cw1200_get_hw_type(val32, &major_revision); + if (ret < 0) { pr_err("Can't deduce hardware type.\n"); - ret = -ENOTSUPP; goto out; } + priv->hw_type = ret; /* Set DPLL Reg value, and read back to confirm writes work */ ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID, --- linux-oracle-5.4.0.orig/drivers/net/wireless/st/cw1200/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/st/cw1200/main.c @@ -381,6 +381,7 @@ CW1200_LINK_ID_MAX, cw1200_skb_dtor, priv)) { + destroy_workqueue(priv->workqueue); ieee80211_free_hw(hw); return NULL; } @@ -392,6 +393,7 @@ for (; i > 0; i--) cw1200_queue_deinit(&priv->tx_queue[i - 1]); cw1200_queue_stats_deinit(&priv->tx_queue_stats); + destroy_workqueue(priv->workqueue); ieee80211_free_hw(hw); return NULL; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/st/cw1200/scan.c +++ linux-oracle-5.4.0/drivers/net/wireless/st/cw1200/scan.c @@ -120,8 +120,7 @@ ++priv->scan.n_ssids; } - if (frame.skb) - dev_kfree_skb(frame.skb); + dev_kfree_skb(frame.skb); mutex_unlock(&priv->conf_mutex); queue_work(priv->workqueue, &priv->scan.work); return 0; --- linux-oracle-5.4.0.orig/drivers/net/wireless/st/cw1200/txrx.c +++ linux-oracle-5.4.0/drivers/net/wireless/st/cw1200/txrx.c @@ -1170,7 +1170,7 @@ size_t ies_len = skb->len - (ies - (u8 *)(skb->data)); tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies, ies_len); - if (tim_ie) { + if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) { struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *)&tim_ie[2]; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wl1251/cmd.c +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wl1251/cmd.c @@ -466,9 +466,12 @@ cmd->channels[i].channel = channels[i]->hw_value; } - cmd->params.ssid_len = ssid_len; - if (ssid) - memcpy(cmd->params.ssid, ssid, ssid_len); + if (ssid) { + int len = clamp_val(ssid_len, 0, IEEE80211_MAX_SSID_LEN); + + cmd->params.ssid_len = len; + memcpy(cmd->params.ssid, ssid, len); + } ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wl1251/event.c +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wl1251/event.c @@ -70,7 +70,7 @@ break; } - return 0; + return ret; } static void wl1251_event_mbox_dump(struct event_mailbox *mbox) --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wl12xx/Kconfig +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wl12xx/Kconfig @@ -1,10 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-only config WL12XX - tristate "TI wl12xx support" + tristate "TI wl12xx support" depends on MAC80211 - select WLCORE - ---help--- + select WLCORE + ---help--- This module adds support for wireless adapters based on TI wl1271, wl1273, wl1281 and wl1283 chipsets. This module does *not* include support for wl1251. For wl1251 support, use the separate homonymous - driver instead. + driver instead. --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wl12xx/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wl12xx/main.c @@ -635,7 +635,6 @@ wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; wl->mr_fw_name = WL127X_FW_NAME_MULTI; @@ -659,7 +658,6 @@ wl->quirks |= WLCORE_QUIRK_LEGACY_NVS | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wl->plt_fw_name = WL127X_PLT_FW_NAME; wl->sr_fw_name = WL127X_FW_NAME_SINGLE; @@ -688,7 +686,6 @@ wl->quirks |= WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_DUAL_PROBE_TMPL | WLCORE_QUIRK_TKIP_HEADER_SPACE | - WLCORE_QUIRK_START_STA_FAILS | WLCORE_QUIRK_AP_ZERO_SESSION_ID; wlcore_set_min_fw_ver(wl, WL128X_CHIP_VER, @@ -1506,6 +1503,13 @@ u32 mac1, mac2; int ret; + /* Device may be in ELP from the bootloader or kexec */ + ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + + usleep_range(500000, 700000); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); if (ret < 0) goto out; --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wlcore/main.c +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wlcore/main.c @@ -2546,24 +2546,24 @@ if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) || test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) { ret = -EBUSY; - goto out; + goto out_unlock; } ret = wl12xx_init_vif_data(wl, vif); if (ret < 0) - goto out; + goto out_unlock; wlvif->wl = wl; role_type = wl12xx_get_role_type(wl, wlvif); if (role_type == WL12XX_INVALID_ROLE_TYPE) { ret = -EINVAL; - goto out; + goto out_unlock; } ret = wlcore_allocate_hw_queue_base(wl, wlvif); if (ret < 0) - goto out; + goto out_unlock; /* * TODO: after the nvs issue will be solved, move this block @@ -2578,7 +2578,7 @@ ret = wl12xx_init_fw(wl); if (ret < 0) - goto out; + goto out_unlock; } /* @@ -2862,21 +2862,8 @@ if (is_ibss) ret = wl12xx_cmd_role_start_ibss(wl, wlvif); - else { - if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) { - /* - * TODO: this is an ugly workaround for wl12xx fw - * bug - we are not able to tx/rx after the first - * start_sta, so make dummy start+stop calls, - * and then call start_sta again. - * this should be fixed in the fw. - */ - wl12xx_cmd_role_start_sta(wl, wlvif); - wl12xx_cmd_role_stop_sta(wl, wlvif); - } - + else ret = wl12xx_cmd_role_start_sta(wl, wlvif); - } return ret; } @@ -3658,8 +3645,10 @@ goto out; ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(wl->dev); goto out; + } ret = wlcore_cmd_regdomain_config_locked(wl); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wlcore/tx.c +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wlcore/tx.c @@ -863,6 +863,7 @@ ret = wlcore_tx_work_locked(wl); if (ret < 0) { + pm_runtime_put_noidle(wl->dev); wl12xx_queue_recovery_work(wl); goto out; } --- linux-oracle-5.4.0.orig/drivers/net/wireless/ti/wlcore/wlcore.h +++ linux-oracle-5.4.0/drivers/net/wireless/ti/wlcore/wlcore.h @@ -547,9 +547,6 @@ /* Each RX/TX transaction requires an end-of-transaction transfer */ #define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0) -/* the first start_role(sta) sometimes doesn't work on wl12xx */ -#define WLCORE_QUIRK_START_STA_FAILS BIT(1) - /* wl127x and SPI don't support SDIO block size alignment */ #define WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN BIT(2) --- linux-oracle-5.4.0.orig/drivers/net/wireless/virt_wifi.c +++ linux-oracle-5.4.0/drivers/net/wireless/virt_wifi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static struct wiphy *common_wiphy; @@ -135,6 +136,32 @@ /* Assigned at module init. Guaranteed locally-administered and unicast. */ static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; +#define VIRT_WIFI_SSID "VirtWifi" +#define VIRT_WIFI_SSID_LEN 8 + +static void virt_wifi_inform_bss(struct wiphy *wiphy) +{ + u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); + struct cfg80211_bss *informed_bss; + static const struct { + u8 tag; + u8 len; + u8 ssid[8]; + } __packed ssid = { + .tag = WLAN_EID_SSID, + .len = VIRT_WIFI_SSID_LEN, + .ssid = VIRT_WIFI_SSID, + }; + + informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, + CFG80211_BSS_FTYPE_PRESP, + fake_router_bssid, tsf, + WLAN_CAPABILITY_ESS, 0, + (void *)&ssid, sizeof(ssid), + DBM_TO_MBM(-50), GFP_KERNEL); + cfg80211_put_bss(wiphy, informed_bss); +} + /* Called with the rtnl lock held. */ static int virt_wifi_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) @@ -155,28 +182,13 @@ /* Acquires and releases the rdev BSS lock. */ static void virt_wifi_scan_result(struct work_struct *work) { - struct { - u8 tag; - u8 len; - u8 ssid[8]; - } __packed ssid = { - .tag = WLAN_EID_SSID, .len = 8, .ssid = "VirtWifi", - }; - struct cfg80211_bss *informed_bss; struct virt_wifi_wiphy_priv *priv = container_of(work, struct virt_wifi_wiphy_priv, scan_result.work); struct wiphy *wiphy = priv_to_wiphy(priv); struct cfg80211_scan_info scan_info = { .aborted = false }; - informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, - CFG80211_BSS_FTYPE_PRESP, - fake_router_bssid, - ktime_get_boottime_ns(), - WLAN_CAPABILITY_ESS, 0, - (void *)&ssid, sizeof(ssid), - DBM_TO_MBM(-50), GFP_KERNEL); - cfg80211_put_bss(wiphy, informed_bss); + virt_wifi_inform_bss(wiphy); /* Schedules work which acquires and releases the rtnl lock. */ cfg80211_scan_done(priv->scan_request, &scan_info); @@ -204,6 +216,8 @@ struct net_device *upperdev; u32 tx_packets; u32 tx_failed; + u32 connect_requested_ssid_len; + u8 connect_requested_ssid[IEEE80211_MAX_SSID_LEN]; u8 connect_requested_bss[ETH_ALEN]; bool is_up; bool is_connected; @@ -220,14 +234,22 @@ if (priv->being_deleted || !priv->is_up) return -EBUSY; + if (!sme->ssid) + return -EINVAL; + + priv->connect_requested_ssid_len = sme->ssid_len; + memcpy(priv->connect_requested_ssid, sme->ssid, sme->ssid_len); + could_schedule = schedule_delayed_work(&priv->connect, HZ * 2); if (!could_schedule) return -EBUSY; - if (sme->bssid) + if (sme->bssid) { ether_addr_copy(priv->connect_requested_bss, sme->bssid); - else + } else { + virt_wifi_inform_bss(wiphy); eth_zero_addr(priv->connect_requested_bss); + } wiphy_debug(wiphy, "connect\n"); @@ -240,11 +262,16 @@ struct virt_wifi_netdev_priv *priv = container_of(work, struct virt_wifi_netdev_priv, connect.work); u8 *requested_bss = priv->connect_requested_bss; - bool has_addr = !is_zero_ether_addr(requested_bss); bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); + bool right_ssid = priv->connect_requested_ssid_len == VIRT_WIFI_SSID_LEN && + !memcmp(priv->connect_requested_ssid, VIRT_WIFI_SSID, + priv->connect_requested_ssid_len); u16 status = WLAN_STATUS_SUCCESS; - if (!priv->is_up || (has_addr && !right_addr)) + if (is_zero_ether_addr(requested_bss)) + requested_bss = NULL; + + if (!priv->is_up || (requested_bss && !right_addr) || !right_ssid) status = WLAN_STATUS_UNSPECIFIED_FAILURE; else priv->is_connected = true; @@ -450,7 +477,6 @@ */ kfree(dev->ieee80211_ptr); dev->ieee80211_ptr = NULL; - free_netdev(dev); } /* No lock interaction. */ @@ -458,7 +484,7 @@ { ether_setup(dev); dev->netdev_ops = &virt_wifi_ops; - dev->priv_destructor = virt_wifi_net_device_destructor; + dev->needs_free_netdev = true; } /* Called in a RCU read critical section from netif_receive_skb */ @@ -544,6 +570,7 @@ goto unregister_netdev; } + dev->priv_destructor = virt_wifi_net_device_destructor; priv->being_deleted = false; priv->is_connected = false; priv->is_up = false; --- linux-oracle-5.4.0.orig/drivers/net/wireless/wl3501.h +++ linux-oracle-5.4.0/drivers/net/wireless/wl3501.h @@ -379,16 +379,7 @@ u8 mib_value[100]; }; -struct wl3501_join_req { - u16 next_blk; - u8 sig_id; - u8 reserved; - struct iw_mgmt_data_rset operational_rset; - u16 reserved2; - u16 timeout; - u16 probe_delay; - u8 timestamp[8]; - u8 local_time[8]; +struct wl3501_req { u16 beacon_period; u16 dtim_period; u16 cap_info; @@ -401,6 +392,19 @@ struct iw_mgmt_data_rset bss_basic_rset; }; +struct wl3501_join_req { + u16 next_blk; + u8 sig_id; + u8 reserved; + struct iw_mgmt_data_rset operational_rset; + u16 reserved2; + u16 timeout; + u16 probe_delay; + u8 timestamp[8]; + u8 local_time[8]; + struct wl3501_req req; +}; + struct wl3501_join_confirm { u16 next_blk; u8 sig_id; @@ -443,16 +447,7 @@ u16 status; char timestamp[8]; char localtime[8]; - u16 beacon_period; - u16 dtim_period; - u16 cap_info; - u8 bss_type; - u8 bssid[ETH_ALEN]; - struct iw_mgmt_essid_pset ssid; - struct iw_mgmt_ds_pset ds_pset; - struct iw_mgmt_cf_pset cf_pset; - struct iw_mgmt_ibss_pset ibss_pset; - struct iw_mgmt_data_rset bss_basic_rset; + struct wl3501_req req; u8 rssi; }; @@ -471,8 +466,10 @@ u16 size; u8 pri; u8 service_class; - u8 daddr[ETH_ALEN]; - u8 saddr[ETH_ALEN]; + struct { + u8 daddr[ETH_ALEN]; + u8 saddr[ETH_ALEN]; + } addr; }; struct wl3501_md_ind { @@ -484,8 +481,10 @@ u8 reception; u8 pri; u8 service_class; - u8 daddr[ETH_ALEN]; - u8 saddr[ETH_ALEN]; + struct { + u8 daddr[ETH_ALEN]; + u8 saddr[ETH_ALEN]; + } addr; }; struct wl3501_md_confirm { --- linux-oracle-5.4.0.orig/drivers/net/wireless/wl3501_cs.c +++ linux-oracle-5.4.0/drivers/net/wireless/wl3501_cs.c @@ -134,8 +134,8 @@ /** * iw_valid_channel - validate channel in regulatory domain - * @reg_comain - regulatory domain - * @channel - channel to validate + * @reg_domain: regulatory domain + * @channel: channel to validate * * Returns 0 if invalid in the specified regulatory domain, non-zero if valid. */ @@ -154,7 +154,7 @@ /** * iw_default_channel - get default channel for a regulatory domain - * @reg_comain - regulatory domain + * @reg_domain: regulatory domain * * Returns the default channel for a regulatory domain */ @@ -237,6 +237,7 @@ /** * wl3501_set_to_wla - Move 'size' bytes from PC to card + * @this: Card * @dest: Card addressing space * @src: PC addressing space * @size: Bytes to move @@ -259,6 +260,7 @@ /** * wl3501_get_from_wla - Move 'size' bytes from card to PC + * @this: Card * @src: Card addressing space * @dest: PC addressing space * @size: Bytes to move @@ -455,12 +457,10 @@ /** * wl3501_send_pkt - Send a packet. - * @this - card - * - * Send a packet. - * - * data = Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr, + * @this: Card + * @data: Ethernet raw frame. (e.g. data[0] - data[5] is Dest MAC Addr, * data[6] - data[11] is Src MAC Addr) + * @len: Packet length * Ref: IEEE 802.11 */ static int wl3501_send_pkt(struct wl3501_card *this, u8 *data, u16 len) @@ -469,6 +469,7 @@ struct wl3501_md_req sig = { .sig_id = WL3501_SIG_MD_REQ, }; + size_t sig_addr_len = sizeof(sig.addr); u8 *pdata = (char *)data; int rc = -EIO; @@ -484,9 +485,9 @@ goto out; } rc = 0; - memcpy(&sig.daddr[0], pdata, 12); - pktlen = len - 12; - pdata += 12; + memcpy(&sig.addr, pdata, sig_addr_len); + pktlen = len - sig_addr_len; + pdata += sig_addr_len; sig.data = bf; if (((*pdata) * 256 + (*(pdata + 1))) > 1500) { u8 addr4[ETH_ALEN] = { @@ -589,7 +590,7 @@ struct wl3501_join_req sig = { .sig_id = WL3501_SIG_JOIN_REQ, .timeout = 10, - .ds_pset = { + .req.ds_pset = { .el = { .id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET, .len = 1, @@ -598,7 +599,7 @@ }, }; - memcpy(&sig.beacon_period, &this->bss_set[stas].beacon_period, 72); + memcpy(&sig.req, &this->bss_set[stas].req, sizeof(sig.req)); return wl3501_esbq_exec(this, &sig, sizeof(sig)); } @@ -666,35 +667,37 @@ if (sig.status == WL3501_STATUS_SUCCESS) { pr_debug("success"); if ((this->net_type == IW_MODE_INFRA && - (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) || + (sig.req.cap_info & WL3501_MGMT_CAPABILITY_ESS)) || (this->net_type == IW_MODE_ADHOC && - (sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) || + (sig.req.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) || this->net_type == IW_MODE_AUTO) { if (!this->essid.el.len) matchflag = 1; else if (this->essid.el.len == 3 && !memcmp(this->essid.essid, "ANY", 3)) matchflag = 1; - else if (this->essid.el.len != sig.ssid.el.len) + else if (this->essid.el.len != sig.req.ssid.el.len) matchflag = 0; - else if (memcmp(this->essid.essid, sig.ssid.essid, + else if (memcmp(this->essid.essid, sig.req.ssid.essid, this->essid.el.len)) matchflag = 0; else matchflag = 1; if (matchflag) { for (i = 0; i < this->bss_cnt; i++) { - if (ether_addr_equal_unaligned(this->bss_set[i].bssid, sig.bssid)) { + if (ether_addr_equal_unaligned(this->bss_set[i].req.bssid, + sig.req.bssid)) { matchflag = 0; break; } } } if (matchflag && (i < 20)) { - memcpy(&this->bss_set[i].beacon_period, - &sig.beacon_period, 73); + memcpy(&this->bss_set[i].req, + &sig.req, sizeof(sig.req)); this->bss_cnt++; this->rssi = sig.rssi; + this->bss_set[i].rssi = sig.rssi; } } } else if (sig.status == WL3501_STATUS_TIMEOUT) { @@ -720,7 +723,7 @@ /** * wl3501_block_interrupt - Mask interrupt from SUTRO - * @this - card + * @this: Card * * Mask interrupt from SUTRO. (i.e. SUTRO cannot interrupt the HOST) * Return: 1 if interrupt is originally enabled @@ -737,7 +740,7 @@ /** * wl3501_unblock_interrupt - Enable interrupt from SUTRO - * @this - card + * @this: Card * * Enable interrupt from SUTRO. (i.e. SUTRO can interrupt the HOST) * Return: 1 if interrupt is originally enabled @@ -886,19 +889,19 @@ if (this->join_sta_bss < this->bss_cnt) { const int i = this->join_sta_bss; memcpy(this->bssid, - this->bss_set[i].bssid, ETH_ALEN); - this->chan = this->bss_set[i].ds_pset.chan; + this->bss_set[i].req.bssid, ETH_ALEN); + this->chan = this->bss_set[i].req.ds_pset.chan; iw_copy_mgmt_info_element(&this->keep_essid.el, - &this->bss_set[i].ssid.el); + &this->bss_set[i].req.ssid.el); wl3501_mgmt_auth(this); } } else { const int i = this->join_sta_bss; - memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN); - this->chan = this->bss_set[i].ds_pset.chan; + memcpy(&this->bssid, &this->bss_set[i].req.bssid, ETH_ALEN); + this->chan = this->bss_set[i].req.ds_pset.chan; iw_copy_mgmt_info_element(&this->keep_essid.el, - &this->bss_set[i].ssid.el); + &this->bss_set[i].req.ssid.el); wl3501_online(dev); } } else { @@ -980,7 +983,8 @@ } else { skb->dev = dev; skb_reserve(skb, 2); /* IP headers on 16 bytes boundaries */ - skb_copy_to_linear_data(skb, (unsigned char *)&sig.daddr, 12); + skb_copy_to_linear_data(skb, (unsigned char *)&sig.addr, + sizeof(sig.addr)); wl3501_receive(this, skb->data, pkt_len); skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, dev); @@ -1110,8 +1114,8 @@ /** * wl3501_interrupt - Hardware interrupt from card. - * @irq - Interrupt number - * @dev_id - net_device + * @irq: Interrupt number + * @dev_id: net_device * * We must acknowledge the interrupt as soon as possible, and block the * interrupt from the same card immediately to prevent re-entry. @@ -1247,7 +1251,7 @@ /** * wl3501_reset - Reset the SUTRO. - * @dev - network device + * @dev: network device * * It is almost the same as wl3501_open(). In fact, we may just wl3501_close() * and wl3501_open() again, but I wouldn't like to free_irq() when the driver @@ -1324,7 +1328,7 @@ } else { ++dev->stats.tx_packets; dev->stats.tx_bytes += skb->len; - kfree_skb(skb); + dev_kfree_skb_irq(skb); if (this->tx_buffer_cnt < 2) netif_stop_queue(dev); @@ -1410,7 +1414,7 @@ /** * wl3501_detach - deletes a driver "instance" - * @link - FILL_IN + * @link: FILL_IN * * This deletes a driver "instance". The device is de-registered with Card * Services. If it has been released, all local data structures are freed. @@ -1431,9 +1435,7 @@ wl3501_release(link); unregister_netdev(dev); - - if (link->priv) - free_netdev(link->priv); + free_netdev(dev); } static int wl3501_get_name(struct net_device *dev, struct iw_request_info *info, @@ -1573,30 +1575,30 @@ for (i = 0; i < this->bss_cnt; ++i) { iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN); + memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].req.bssid, ETH_ALEN); current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - iwe.u.data.length = this->bss_set[i].ssid.el.len; + iwe.u.data.length = this->bss_set[i].req.ssid.el.len; current_ev = iwe_stream_add_point(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, - this->bss_set[i].ssid.essid); + this->bss_set[i].req.ssid.essid); iwe.cmd = SIOCGIWMODE; - iwe.u.mode = this->bss_set[i].bss_type; + iwe.u.mode = this->bss_set[i].req.bss_type; current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN); iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = this->bss_set[i].ds_pset.chan; + iwe.u.freq.m = this->bss_set[i].req.ds_pset.chan; iwe.u.freq.e = 0; current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN); iwe.cmd = SIOCGIWENCODE; - if (this->bss_set[i].cap_info & WL3501_MGMT_CAPABILITY_PRIVACY) + if (this->bss_set[i].req.cap_info & WL3501_MGMT_CAPABILITY_PRIVACY) iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; else iwe.u.data.flags = IW_ENCODE_DISABLED; @@ -1860,6 +1862,7 @@ { struct net_device *dev; struct wl3501_card *this; + int ret; /* The io structure describes IO port mapping */ p_dev->resource[0]->end = 16; @@ -1871,8 +1874,7 @@ dev = alloc_etherdev(sizeof(struct wl3501_card)); if (!dev) - goto out_link; - + return -ENOMEM; dev->netdev_ops = &wl3501_netdev_ops; dev->watchdog_timeo = 5 * HZ; @@ -1885,9 +1887,15 @@ netif_stop_queue(dev); p_dev->priv = dev; - return wl3501_config(p_dev); -out_link: - return -ENOMEM; + ret = wl3501_config(p_dev); + if (ret) + goto out_free_etherdev; + + return 0; + +out_free_etherdev: + free_netdev(dev); + return ret; } static int wl3501_config(struct pcmcia_device *link) @@ -1943,8 +1951,7 @@ goto failed; } - for (i = 0; i < 6; i++) - dev->dev_addr[i] = ((char *)&this->mac_addr)[i]; + eth_hw_addr_set(dev, this->mac_addr); /* print probe information */ printk(KERN_INFO "%s: wl3501 @ 0x%3.3x, IRQ %d, " --- linux-oracle-5.4.0.orig/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ linux-oracle-5.4.0/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -1263,7 +1263,7 @@ static int eject_installer(struct usb_interface *intf) { struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_interface *iface_desc = &intf->altsetting[0]; + struct usb_host_interface *iface_desc = intf->cur_altsetting; struct usb_endpoint_descriptor *endpoint; unsigned char *cmd; u8 bulk_out_ep; --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/common.h +++ linux-oracle-5.4.0/drivers/net/xen-netback/common.h @@ -48,7 +48,6 @@ #include typedef unsigned int pending_ring_idx_t; -#define INVALID_PENDING_RING_IDX (~0U) struct pending_tx_info { struct xen_netif_tx_request req; /* tx request */ @@ -82,8 +81,6 @@ /* Discriminate from any valid pending_idx value. */ #define INVALID_PENDING_IDX 0xFFFF -#define MAX_BUFFER_OFFSET XEN_PAGE_SIZE - #define MAX_PENDING_REQS XEN_NETIF_TX_RING_SIZE /* The maximum number of frags is derived from the size of a grant (same @@ -140,6 +137,20 @@ char name[QUEUE_NAME_SIZE]; /* DEVNAME-qN */ struct xenvif *vif; /* Parent VIF */ + /* + * TX/RX common EOI handling. + * When feature-split-event-channels = 0, interrupt handler sets + * NETBK_COMMON_EOI, otherwise NETBK_RX_EOI and NETBK_TX_EOI are set + * by the RX and TX interrupt handlers. + * RX and TX handler threads will issue an EOI when either + * NETBK_COMMON_EOI or their specific bits (NETBK_RX_EOI or + * NETBK_TX_EOI) are set and they will reset those bits. + */ + atomic_t eoi_pending; +#define NETBK_RX_EOI 0x01 +#define NETBK_TX_EOI 0x02 +#define NETBK_COMMON_EOI 0x04 + /* Use NAPI for guest TX */ struct napi_struct napi; /* When feature-split-event-channels = 0, tx_irq = rx_irq. */ @@ -155,7 +166,7 @@ struct pending_tx_info pending_tx_info[MAX_PENDING_REQS]; grant_handle_t grant_tx_handle[MAX_PENDING_REQS]; - struct gnttab_copy tx_copy_ops[MAX_PENDING_REQS]; + struct gnttab_copy tx_copy_ops[2 * MAX_PENDING_REQS]; struct gnttab_map_grant_ref tx_map_ops[MAX_PENDING_REQS]; struct gnttab_unmap_grant_ref tx_unmap_ops[MAX_PENDING_REQS]; /* passed to gnttab_[un]map_refs with pages under (un)mapping */ @@ -189,6 +200,7 @@ unsigned int rx_queue_max; unsigned int rx_queue_len; unsigned long last_rx_time; + unsigned int rx_slots_needed; bool stalled; struct xenvif_copy_state rx_copy; @@ -349,11 +361,6 @@ int xenvif_xenbus_init(void); void xenvif_xenbus_fini(void); -int xenvif_schedulable(struct xenvif *vif); - -int xenvif_queue_stopped(struct xenvif_queue *queue); -void xenvif_wake_queue(struct xenvif_queue *queue); - /* (Un)Map communication rings. */ void xenvif_unmap_frontend_data_rings(struct xenvif_queue *queue); int xenvif_map_frontend_data_rings(struct xenvif_queue *queue, @@ -375,17 +382,14 @@ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data); -void xenvif_rx_action(struct xenvif_queue *queue); -void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb); +bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread); +bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb); void xenvif_carrier_on(struct xenvif *vif); /* Callback from stack when TX packet can be released */ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success); -/* Unmap a pending page and release it back to the guest */ -void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); - static inline pending_ring_idx_t nr_pending_reqs(struct xenvif_queue *queue) { return MAX_PENDING_REQS - --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/hash.c +++ linux-oracle-5.4.0/drivers/net/xen-netback/hash.c @@ -51,7 +51,8 @@ found = false; oldest = NULL; - list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) { + list_for_each_entry_rcu(entry, &vif->hash.cache.list, link, + lockdep_is_held(&vif->hash.cache.lock)) { /* Make sure we don't add duplicate entries */ if (entry->len == len && memcmp(entry->tag, tag, len) == 0) @@ -94,7 +95,7 @@ static void xenvif_flush_hash(struct xenvif *vif) { - struct xenvif_hash_cache_entry *entry; + struct xenvif_hash_cache_entry *entry, *n; unsigned long flags; if (xenvif_hash_cache_size == 0) @@ -102,7 +103,7 @@ spin_lock_irqsave(&vif->hash.cache.lock, flags); - list_for_each_entry_rcu(entry, &vif->hash.cache.list, link) { + list_for_each_entry_safe(entry, n, &vif->hash.cache.list, link) { list_del_rcu(&entry->link); vif->hash.cache.count--; kfree_rcu(entry, rcu); --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/interface.c +++ linux-oracle-5.4.0/drivers/net/xen-netback/interface.c @@ -41,7 +41,6 @@ #include #include -#define XENVIF_QUEUE_LENGTH 32 #define XENVIF_NAPI_WEIGHT 64 /* Number of bytes allowed on the internal guest Rx queue. */ @@ -70,19 +69,35 @@ wake_up(&queue->dealloc_wq); } -int xenvif_schedulable(struct xenvif *vif) +static int xenvif_schedulable(struct xenvif *vif) { return netif_running(vif->dev) && test_bit(VIF_STATUS_CONNECTED, &vif->status) && !vif->disabled; } +static bool xenvif_handle_tx_interrupt(struct xenvif_queue *queue) +{ + bool rc; + + rc = RING_HAS_UNCONSUMED_REQUESTS(&queue->tx); + if (rc) + napi_schedule(&queue->napi); + return rc; +} + static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id) { struct xenvif_queue *queue = dev_id; + int old; - if (RING_HAS_UNCONSUMED_REQUESTS(&queue->tx)) - napi_schedule(&queue->napi); + old = atomic_fetch_or(NETBK_TX_EOI, &queue->eoi_pending); + WARN(old & NETBK_TX_EOI, "Interrupt while EOI pending\n"); + + if (!xenvif_handle_tx_interrupt(queue)) { + atomic_andnot(NETBK_TX_EOI, &queue->eoi_pending); + xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); + } return IRQ_HANDLED; } @@ -116,35 +131,50 @@ return work_done; } +static bool xenvif_handle_rx_interrupt(struct xenvif_queue *queue) +{ + bool rc; + + rc = xenvif_have_rx_work(queue, false); + if (rc) + xenvif_kick_thread(queue); + return rc; +} + static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id) { struct xenvif_queue *queue = dev_id; + int old; - xenvif_kick_thread(queue); + old = atomic_fetch_or(NETBK_RX_EOI, &queue->eoi_pending); + WARN(old & NETBK_RX_EOI, "Interrupt while EOI pending\n"); + + if (!xenvif_handle_rx_interrupt(queue)) { + atomic_andnot(NETBK_RX_EOI, &queue->eoi_pending); + xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); + } return IRQ_HANDLED; } irqreturn_t xenvif_interrupt(int irq, void *dev_id) { - xenvif_tx_interrupt(irq, dev_id); - xenvif_rx_interrupt(irq, dev_id); + struct xenvif_queue *queue = dev_id; + int old; + bool has_rx, has_tx; - return IRQ_HANDLED; -} + old = atomic_fetch_or(NETBK_COMMON_EOI, &queue->eoi_pending); + WARN(old, "Interrupt while EOI pending\n"); -int xenvif_queue_stopped(struct xenvif_queue *queue) -{ - struct net_device *dev = queue->vif->dev; - unsigned int id = queue->id; - return netif_tx_queue_stopped(netdev_get_tx_queue(dev, id)); -} + has_tx = xenvif_handle_tx_interrupt(queue); + has_rx = xenvif_handle_rx_interrupt(queue); -void xenvif_wake_queue(struct xenvif_queue *queue) -{ - struct net_device *dev = queue->vif->dev; - unsigned int id = queue->id; - netif_tx_wake_queue(netdev_get_tx_queue(dev, id)); + if (!has_rx && !has_tx) { + atomic_andnot(NETBK_COMMON_EOI, &queue->eoi_pending); + xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS); + } + + return IRQ_HANDLED; } static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, @@ -224,14 +254,16 @@ if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) skb_clear_hash(skb); - xenvif_rx_queue_tail(queue, skb); + if (!xenvif_rx_queue_tail(queue, skb)) + goto drop; + xenvif_kick_thread(queue); return NETDEV_TX_OK; drop: vif->dev->stats.tx_dropped++; - dev_kfree_skb(skb); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -493,8 +525,6 @@ dev->features = dev->hw_features | NETIF_F_RXCSUM; dev->ethtool_ops = &xenvif_ethtool_ops; - dev->tx_queue_len = XENVIF_QUEUE_LENGTH; - dev->min_mtu = ETH_MIN_MTU; dev->max_mtu = ETH_MAX_MTU - VLAN_ETH_HLEN; @@ -595,7 +625,7 @@ shared = (struct xen_netif_ctrl_sring *)addr; BACK_RING_INIT(&vif->ctrl, shared, XEN_PAGE_SIZE); - err = bind_interdomain_evtchn_to_irq(vif->domid, evtchn); + err = bind_interdomain_evtchn_to_irq_lateeoi(vif->domid, evtchn); if (err < 0) goto err_unmap; @@ -653,7 +683,7 @@ if (tx_evtchn == rx_evtchn) { /* feature-split-event-channels == 0 */ - err = bind_interdomain_evtchn_to_irqhandler( + err = bind_interdomain_evtchn_to_irqhandler_lateeoi( queue->vif->domid, tx_evtchn, xenvif_interrupt, 0, queue->name, queue); if (err < 0) @@ -664,7 +694,7 @@ /* feature-split-event-channels == 1 */ snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name), "%s-tx", queue->name); - err = bind_interdomain_evtchn_to_irqhandler( + err = bind_interdomain_evtchn_to_irqhandler_lateeoi( queue->vif->domid, tx_evtchn, xenvif_tx_interrupt, 0, queue->tx_irq_name, queue); if (err < 0) @@ -674,7 +704,7 @@ snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name), "%s-rx", queue->name); - err = bind_interdomain_evtchn_to_irqhandler( + err = bind_interdomain_evtchn_to_irqhandler_lateeoi( queue->vif->domid, rx_evtchn, xenvif_rx_interrupt, 0, queue->rx_irq_name, queue); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/netback.c +++ linux-oracle-5.4.0/drivers/net/xen-netback/netback.c @@ -97,13 +97,14 @@ MODULE_PARM_DESC(hash_cache_size, "Number of flows in the hash cache"); static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, - u8 status); + s8 status); static void make_tx_response(struct xenvif_queue *queue, - struct xen_netif_tx_request *txp, + const struct xen_netif_tx_request *txp, unsigned int extra_count, - s8 st); -static void push_tx_responses(struct xenvif_queue *queue); + s8 status); + +static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx); static inline int tx_work_todo(struct xenvif_queue *queue); @@ -162,6 +163,10 @@ if (more_to_do) napi_schedule(&queue->napi); + else if (atomic_fetch_andnot(NETBK_TX_EOI | NETBK_COMMON_EOI, + &queue->eoi_pending) & + (NETBK_TX_EOI | NETBK_COMMON_EOI)) + xen_irq_lateeoi(queue->tx_irq, 0); } static void tx_add_credit(struct xenvif_queue *queue) @@ -195,13 +200,9 @@ unsigned int extra_count, RING_IDX end) { RING_IDX cons = queue->tx.req_cons; - unsigned long flags; do { - spin_lock_irqsave(&queue->response_lock, flags); make_tx_response(queue, txp, extra_count, XEN_NETIF_RSP_ERROR); - push_tx_responses(queue); - spin_unlock_irqrestore(&queue->response_lock, flags); if (cons == end) break; RING_COPY_REQUEST(&queue->tx, cons++, txp); @@ -319,10 +320,14 @@ struct xenvif_tx_cb { - u16 pending_idx; + u16 copy_pending_idx[XEN_NETBK_LEGACY_SLOTS_MAX + 1]; + u8 copy_count; + u32 split_mask; }; #define XENVIF_TX_CB(skb) ((struct xenvif_tx_cb *)(skb)->cb) +#define copy_pending_idx(skb, i) (XENVIF_TX_CB(skb)->copy_pending_idx[i]) +#define copy_count(skb) (XENVIF_TX_CB(skb)->copy_count) static inline void xenvif_tx_create_map_op(struct xenvif_queue *queue, u16 pending_idx, @@ -345,6 +350,8 @@ struct sk_buff *skb = alloc_skb(size + NET_SKB_PAD + NET_IP_ALIGN, GFP_ATOMIC | __GFP_NOWARN); + + BUILD_BUG_ON(sizeof(*XENVIF_TX_CB(skb)) > sizeof(skb->cb)); if (unlikely(skb == NULL)) return NULL; @@ -357,52 +364,152 @@ return skb; } -static struct gnttab_map_grant_ref *xenvif_get_requests(struct xenvif_queue *queue, - struct sk_buff *skb, - struct xen_netif_tx_request *txp, - struct gnttab_map_grant_ref *gop, - unsigned int frag_overflow, - struct sk_buff *nskb) +static void xenvif_get_requests(struct xenvif_queue *queue, + struct sk_buff *skb, + struct xen_netif_tx_request *first, + struct xen_netif_tx_request *txfrags, + unsigned *copy_ops, + unsigned *map_ops, + unsigned int frag_overflow, + struct sk_buff *nskb, + unsigned int extra_count, + unsigned int data_len) { struct skb_shared_info *shinfo = skb_shinfo(skb); skb_frag_t *frags = shinfo->frags; - u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; - int start; + u16 pending_idx; pending_ring_idx_t index; unsigned int nr_slots; + struct gnttab_copy *cop = queue->tx_copy_ops + *copy_ops; + struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops; + struct xen_netif_tx_request *txp = first; + + nr_slots = shinfo->nr_frags + frag_overflow + 1; + + copy_count(skb) = 0; + XENVIF_TX_CB(skb)->split_mask = 0; + + /* Create copy ops for exactly data_len bytes into the skb head. */ + __skb_put(skb, data_len); + while (data_len > 0) { + int amount = data_len > txp->size ? txp->size : data_len; + bool split = false; + + cop->source.u.ref = txp->gref; + cop->source.domid = queue->vif->domid; + cop->source.offset = txp->offset; + + cop->dest.domid = DOMID_SELF; + cop->dest.offset = (offset_in_page(skb->data + + skb_headlen(skb) - + data_len)) & ~XEN_PAGE_MASK; + cop->dest.u.gmfn = virt_to_gfn(skb->data + skb_headlen(skb) + - data_len); + + /* Don't cross local page boundary! */ + if (cop->dest.offset + amount > XEN_PAGE_SIZE) { + amount = XEN_PAGE_SIZE - cop->dest.offset; + XENVIF_TX_CB(skb)->split_mask |= 1U << copy_count(skb); + split = true; + } + + cop->len = amount; + cop->flags = GNTCOPY_source_gref; + + index = pending_index(queue->pending_cons); + pending_idx = queue->pending_ring[index]; + callback_param(queue, pending_idx).ctx = NULL; + copy_pending_idx(skb, copy_count(skb)) = pending_idx; + if (!split) + copy_count(skb)++; + + cop++; + data_len -= amount; - nr_slots = shinfo->nr_frags; + if (amount == txp->size) { + /* The copy op covered the full tx_request */ - /* Skip first skb fragment if it is on same page as header fragment. */ - start = (frag_get_pending_idx(&shinfo->frags[0]) == pending_idx); + memcpy(&queue->pending_tx_info[pending_idx].req, + txp, sizeof(*txp)); + queue->pending_tx_info[pending_idx].extra_count = + (txp == first) ? extra_count : 0; + + if (txp == first) + txp = txfrags; + else + txp++; + queue->pending_cons++; + nr_slots--; + } else { + /* The copy op partially covered the tx_request. + * The remainder will be mapped or copied in the next + * iteration. + */ + txp->offset += amount; + txp->size -= amount; + } + } + + for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS; + nr_slots--) { + if (unlikely(!txp->size)) { + make_tx_response(queue, txp, 0, XEN_NETIF_RSP_OKAY); + ++txp; + continue; + } - for (shinfo->nr_frags = start; shinfo->nr_frags < nr_slots; - shinfo->nr_frags++, txp++, gop++) { index = pending_index(queue->pending_cons++); pending_idx = queue->pending_ring[index]; - xenvif_tx_create_map_op(queue, pending_idx, txp, 0, gop); + xenvif_tx_create_map_op(queue, pending_idx, txp, + txp == first ? extra_count : 0, gop); frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); + ++shinfo->nr_frags; + ++gop; + + if (txp == first) + txp = txfrags; + else + txp++; } - if (frag_overflow) { + if (nr_slots > 0) { shinfo = skb_shinfo(nskb); frags = shinfo->frags; - for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow; - shinfo->nr_frags++, txp++, gop++) { + for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots; ++txp) { + if (unlikely(!txp->size)) { + make_tx_response(queue, txp, 0, + XEN_NETIF_RSP_OKAY); + continue; + } + index = pending_index(queue->pending_cons++); pending_idx = queue->pending_ring[index]; xenvif_tx_create_map_op(queue, pending_idx, txp, 0, gop); frag_set_pending_idx(&frags[shinfo->nr_frags], pending_idx); + ++shinfo->nr_frags; + ++gop; + } + + if (shinfo->nr_frags) { + skb_shinfo(skb)->frag_list = nskb; + nskb = NULL; } + } - skb_shinfo(skb)->frag_list = nskb; + if (nskb) { + /* A frag_list skb was allocated but it is no longer needed + * because enough slots were converted to copy ops above or some + * were empty. + */ + kfree_skb(nskb); } - return gop; + (*copy_ops) = cop - queue->tx_copy_ops; + (*map_ops) = gop - queue->tx_map_ops; } static inline void xenvif_grant_handle_set(struct xenvif_queue *queue, @@ -438,7 +545,7 @@ struct gnttab_copy **gopp_copy) { struct gnttab_map_grant_ref *gop_map = *gopp_map; - u16 pending_idx = XENVIF_TX_CB(skb)->pending_idx; + u16 pending_idx; /* This always points to the shinfo of the skb being checked, which * could be either the first or the one on the frag_list */ @@ -449,24 +556,44 @@ struct skb_shared_info *first_shinfo = NULL; int nr_frags = shinfo->nr_frags; const bool sharedslot = nr_frags && - frag_get_pending_idx(&shinfo->frags[0]) == pending_idx; - int i, err; - - /* Check status of header. */ - err = (*gopp_copy)->status; - if (unlikely(err)) { - if (net_ratelimit()) - netdev_dbg(queue->vif->dev, - "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n", - (*gopp_copy)->status, - pending_idx, - (*gopp_copy)->source.u.ref); - /* The first frag might still have this slot mapped */ - if (!sharedslot) - xenvif_idx_release(queue, pending_idx, - XEN_NETIF_RSP_ERROR); + frag_get_pending_idx(&shinfo->frags[0]) == + copy_pending_idx(skb, copy_count(skb) - 1); + int i, err = 0; + + for (i = 0; i < copy_count(skb); i++) { + int newerr; + + /* Check status of header. */ + pending_idx = copy_pending_idx(skb, i); + + newerr = (*gopp_copy)->status; + + /* Split copies need to be handled together. */ + if (XENVIF_TX_CB(skb)->split_mask & (1U << i)) { + (*gopp_copy)++; + if (!newerr) + newerr = (*gopp_copy)->status; + } + if (likely(!newerr)) { + /* The first frag might still have this slot mapped */ + if (i < copy_count(skb) - 1 || !sharedslot) + xenvif_idx_release(queue, pending_idx, + XEN_NETIF_RSP_OKAY); + } else { + err = newerr; + if (net_ratelimit()) + netdev_dbg(queue->vif->dev, + "Grant copy of header failed! status: %d pending_idx: %u ref: %u\n", + (*gopp_copy)->status, + pending_idx, + (*gopp_copy)->source.u.ref); + /* The first frag might still have this slot mapped */ + if (i < copy_count(skb) - 1 || !sharedslot) + xenvif_idx_release(queue, pending_idx, + XEN_NETIF_RSP_ERROR); + } + (*gopp_copy)++; } - (*gopp_copy)++; check_frags: for (i = 0; i < nr_frags; i++, gop_map++) { @@ -488,7 +615,7 @@ * the header's copy failed, and they are * sharing a slot, send an error */ - if (i == 0 && sharedslot) + if (i == 0 && !first_shinfo && sharedslot) xenvif_idx_release(queue, pending_idx, XEN_NETIF_RSP_ERROR); else @@ -513,14 +640,6 @@ if (err) continue; - /* First error: if the header haven't shared a slot with the - * first frag, release it as well. - */ - if (!sharedslot) - xenvif_idx_release(queue, - XENVIF_TX_CB(skb)->pending_idx, - XEN_NETIF_RSP_OKAY); - /* Invalidate preceding fragments of this skb. */ for (j = 0; j < i; j++) { pending_idx = frag_get_pending_idx(&shinfo->frags[j]); @@ -790,7 +909,6 @@ unsigned *copy_ops, unsigned *map_ops) { - struct gnttab_map_grant_ref *gop = queue->tx_map_ops; struct sk_buff *skb, *nskb; int ret; unsigned int frag_overflow; @@ -856,7 +974,6 @@ (ret == 0) ? XEN_NETIF_RSP_OKAY : XEN_NETIF_RSP_ERROR); - push_tx_responses(queue); continue; } @@ -868,12 +985,15 @@ make_tx_response(queue, &txreq, extra_count, XEN_NETIF_RSP_OKAY); - push_tx_responses(queue); continue; } + data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN) ? + XEN_NETBACK_TX_COPY_LEN : txreq.size; + ret = xenvif_count_requests(queue, &txreq, extra_count, txfrags, work_to_do); + if (unlikely(ret < 0)) break; @@ -888,10 +1008,8 @@ /* No crossing a page as the payload mustn't fragment. */ if (unlikely((txreq.offset + txreq.size) > XEN_PAGE_SIZE)) { - netdev_err(queue->vif->dev, - "txreq.offset: %u, size: %u, end: %lu\n", - txreq.offset, txreq.size, - (unsigned long)(txreq.offset&~XEN_PAGE_MASK) + txreq.size); + netdev_err(queue->vif->dev, "Cross page boundary, txreq.offset: %u, size: %u\n", + txreq.offset, txreq.size); xenvif_fatal_tx_err(queue->vif); break; } @@ -899,9 +1017,8 @@ index = pending_index(queue->pending_cons); pending_idx = queue->pending_ring[index]; - data_len = (txreq.size > XEN_NETBACK_TX_COPY_LEN && - ret < XEN_NETBK_LEGACY_SLOTS_MAX) ? - XEN_NETBACK_TX_COPY_LEN : txreq.size; + if (ret >= XEN_NETBK_LEGACY_SLOTS_MAX - 1 && data_len < txreq.size) + data_len = txreq.size; skb = xenvif_alloc_skb(data_len); if (unlikely(skb == NULL)) { @@ -912,8 +1029,6 @@ } skb_shinfo(skb)->nr_frags = ret; - if (data_len < txreq.size) - skb_shinfo(skb)->nr_frags++; /* At this point shinfo->nr_frags is in fact the number of * slots, which can be as large as XEN_NETBK_LEGACY_SLOTS_MAX. */ @@ -975,54 +1090,19 @@ type); } - XENVIF_TX_CB(skb)->pending_idx = pending_idx; - - __skb_put(skb, data_len); - queue->tx_copy_ops[*copy_ops].source.u.ref = txreq.gref; - queue->tx_copy_ops[*copy_ops].source.domid = queue->vif->domid; - queue->tx_copy_ops[*copy_ops].source.offset = txreq.offset; - - queue->tx_copy_ops[*copy_ops].dest.u.gmfn = - virt_to_gfn(skb->data); - queue->tx_copy_ops[*copy_ops].dest.domid = DOMID_SELF; - queue->tx_copy_ops[*copy_ops].dest.offset = - offset_in_page(skb->data) & ~XEN_PAGE_MASK; - - queue->tx_copy_ops[*copy_ops].len = data_len; - queue->tx_copy_ops[*copy_ops].flags = GNTCOPY_source_gref; - - (*copy_ops)++; - - if (data_len < txreq.size) { - frag_set_pending_idx(&skb_shinfo(skb)->frags[0], - pending_idx); - xenvif_tx_create_map_op(queue, pending_idx, &txreq, - extra_count, gop); - gop++; - } else { - frag_set_pending_idx(&skb_shinfo(skb)->frags[0], - INVALID_PENDING_IDX); - memcpy(&queue->pending_tx_info[pending_idx].req, - &txreq, sizeof(txreq)); - queue->pending_tx_info[pending_idx].extra_count = - extra_count; - } - - queue->pending_cons++; - - gop = xenvif_get_requests(queue, skb, txfrags, gop, - frag_overflow, nskb); + xenvif_get_requests(queue, skb, &txreq, txfrags, copy_ops, + map_ops, frag_overflow, nskb, extra_count, + data_len); __skb_queue_tail(&queue->tx_queue, skb); queue->tx.req_cons = idx; - if (((gop-queue->tx_map_ops) >= ARRAY_SIZE(queue->tx_map_ops)) || + if ((*map_ops >= ARRAY_SIZE(queue->tx_map_ops)) || (*copy_ops >= ARRAY_SIZE(queue->tx_copy_ops))) break; } - (*map_ops) = gop - queue->tx_map_ops; return; } @@ -1101,9 +1181,8 @@ while ((skb = __skb_dequeue(&queue->tx_queue)) != NULL) { struct xen_netif_tx_request *txp; u16 pending_idx; - unsigned data_len; - pending_idx = XENVIF_TX_CB(skb)->pending_idx; + pending_idx = copy_pending_idx(skb, 0); txp = &queue->pending_tx_info[pending_idx].req; /* Check the remap error code. */ @@ -1122,18 +1201,6 @@ continue; } - data_len = skb->len; - callback_param(queue, pending_idx).ctx = NULL; - if (data_len < txp->size) { - /* Append the packet payload as a fragment. */ - txp->offset += data_len; - txp->size -= data_len; - } else { - /* Schedule a response immediately. */ - xenvif_idx_release(queue, pending_idx, - XEN_NETIF_RSP_OKAY); - } - if (txp->flags & XEN_NETTXF_csum_blank) skb->ip_summed = CHECKSUM_PARTIAL; else if (txp->flags & XEN_NETTXF_data_validated) @@ -1319,7 +1386,7 @@ /* Called after netfront has transmitted */ int xenvif_tx_action(struct xenvif_queue *queue, int budget) { - unsigned nr_mops, nr_cops = 0; + unsigned nr_mops = 0, nr_cops = 0; int work_done, ret; if (unlikely(!tx_work_todo(queue))) @@ -1336,7 +1403,15 @@ NULL, queue->pages_to_map, nr_mops); - BUG_ON(ret); + if (ret) { + unsigned int i; + + netdev_err(queue->vif->dev, "Map fail: nr %u ret %d\n", + nr_mops, ret); + for (i = 0; i < nr_mops; ++i) + WARN_ON_ONCE(queue->tx_map_ops[i].status == + GNTST_okay); + } } work_done = xenvif_tx_submit(queue); @@ -1344,8 +1419,35 @@ return work_done; } +static void _make_tx_response(struct xenvif_queue *queue, + const struct xen_netif_tx_request *txp, + unsigned int extra_count, + s8 status) +{ + RING_IDX i = queue->tx.rsp_prod_pvt; + struct xen_netif_tx_response *resp; + + resp = RING_GET_RESPONSE(&queue->tx, i); + resp->id = txp->id; + resp->status = status; + + while (extra_count-- != 0) + RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; + + queue->tx.rsp_prod_pvt = ++i; +} + +static void push_tx_responses(struct xenvif_queue *queue) +{ + int notify; + + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); + if (notify) + notify_remote_via_irq(queue->tx_irq); +} + static void xenvif_idx_release(struct xenvif_queue *queue, u16 pending_idx, - u8 status) + s8 status) { struct pending_tx_info *pending_tx_info; pending_ring_idx_t index; @@ -1355,8 +1457,8 @@ spin_lock_irqsave(&queue->response_lock, flags); - make_tx_response(queue, &pending_tx_info->req, - pending_tx_info->extra_count, status); + _make_tx_response(queue, &pending_tx_info->req, + pending_tx_info->extra_count, status); /* Release the pending index before pusing the Tx response so * its available before a new Tx request is pushed by the @@ -1370,35 +1472,22 @@ spin_unlock_irqrestore(&queue->response_lock, flags); } - static void make_tx_response(struct xenvif_queue *queue, - struct xen_netif_tx_request *txp, + const struct xen_netif_tx_request *txp, unsigned int extra_count, - s8 st) + s8 status) { - RING_IDX i = queue->tx.rsp_prod_pvt; - struct xen_netif_tx_response *resp; - - resp = RING_GET_RESPONSE(&queue->tx, i); - resp->id = txp->id; - resp->status = st; - - while (extra_count-- != 0) - RING_GET_RESPONSE(&queue->tx, ++i)->status = XEN_NETIF_RSP_NULL; + unsigned long flags; - queue->tx.rsp_prod_pvt = ++i; -} + spin_lock_irqsave(&queue->response_lock, flags); -static void push_tx_responses(struct xenvif_queue *queue) -{ - int notify; + _make_tx_response(queue, txp, extra_count, status); + push_tx_responses(queue); - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&queue->tx, notify); - if (notify) - notify_remote_via_irq(queue->tx_irq); + spin_unlock_irqrestore(&queue->response_lock, flags); } -void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) +static void xenvif_idx_unmap(struct xenvif_queue *queue, u16 pending_idx) { int ret; struct gnttab_unmap_grant_ref tx_unmap_op; @@ -1622,9 +1711,14 @@ irqreturn_t xenvif_ctrl_irq_fn(int irq, void *data) { struct xenvif *vif = data; + unsigned int eoi_flag = XEN_EOI_FLAG_SPURIOUS; - while (xenvif_ctrl_work_todo(vif)) + while (xenvif_ctrl_work_todo(vif)) { xenvif_ctrl_action(vif); + eoi_flag = 0; + } + + xen_irq_lateeoi(irq, eoi_flag); return IRQ_HANDLED; } --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/rx.c +++ linux-oracle-5.4.0/drivers/net/xen-netback/rx.c @@ -33,22 +33,37 @@ #include #include +/* + * Update the needed ring page slots for the first SKB queued. + * Note that any call sequence outside the RX thread calling this function + * needs to wake up the RX thread via a call of xenvif_kick_thread() + * afterwards in order to avoid a race with putting the thread to sleep. + */ +static void xenvif_update_needed_slots(struct xenvif_queue *queue, + const struct sk_buff *skb) +{ + unsigned int needed = 0; + + if (skb) { + needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE); + if (skb_is_gso(skb)) + needed++; + if (skb->sw_hash) + needed++; + } + + WRITE_ONCE(queue->rx_slots_needed, needed); +} + static bool xenvif_rx_ring_slots_available(struct xenvif_queue *queue) { RING_IDX prod, cons; - struct sk_buff *skb; - int needed; + unsigned int needed; - skb = skb_peek(&queue->rx_queue); - if (!skb) + needed = READ_ONCE(queue->rx_slots_needed); + if (!needed) return false; - needed = DIV_ROUND_UP(skb->len, XEN_PAGE_SIZE); - if (skb_is_gso(skb)) - needed++; - if (skb->sw_hash) - needed++; - do { prod = queue->rx.sring->req_prod; cons = queue->rx.req_cons; @@ -67,22 +82,30 @@ return false; } -void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb) +bool xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb) { unsigned long flags; + bool ret = true; spin_lock_irqsave(&queue->rx_queue.lock, flags); - __skb_queue_tail(&queue->rx_queue, skb); - - queue->rx_queue_len += skb->len; - if (queue->rx_queue_len > queue->rx_queue_max) { + if (queue->rx_queue_len >= queue->rx_queue_max) { struct net_device *dev = queue->vif->dev; netif_tx_stop_queue(netdev_get_tx_queue(dev, queue->id)); + ret = false; + } else { + if (skb_queue_empty(&queue->rx_queue)) + xenvif_update_needed_slots(queue, skb); + + __skb_queue_tail(&queue->rx_queue, skb); + + queue->rx_queue_len += skb->len; } spin_unlock_irqrestore(&queue->rx_queue.lock, flags); + + return ret; } static struct sk_buff *xenvif_rx_dequeue(struct xenvif_queue *queue) @@ -93,6 +116,8 @@ skb = __skb_dequeue(&queue->rx_queue); if (skb) { + xenvif_update_needed_slots(queue, skb_peek(&queue->rx_queue)); + queue->rx_queue_len -= skb->len; if (queue->rx_queue_len < queue->rx_queue_max) { struct netdev_queue *txq; @@ -127,6 +152,7 @@ break; xenvif_rx_dequeue(queue); kfree_skb(skb); + queue->vif->dev->stats.rx_dropped++; } } @@ -449,7 +475,7 @@ #define RX_BATCH_SIZE 64 -void xenvif_rx_action(struct xenvif_queue *queue) +static void xenvif_rx_action(struct xenvif_queue *queue) { struct sk_buff_head completed_skbs; unsigned int work_done = 0; @@ -458,6 +484,7 @@ queue->rx_copy.completed = &completed_skbs; while (xenvif_rx_ring_slots_available(queue) && + !skb_queue_empty(&queue->rx_queue) && work_done < RX_BATCH_SIZE) { xenvif_rx_skb(queue); work_done++; @@ -467,36 +494,40 @@ xenvif_rx_copy_flush(queue); } -static bool xenvif_rx_queue_stalled(struct xenvif_queue *queue) +static RING_IDX xenvif_rx_queue_slots(const struct xenvif_queue *queue) { RING_IDX prod, cons; prod = queue->rx.sring->req_prod; cons = queue->rx.req_cons; + return prod - cons; +} + +static bool xenvif_rx_queue_stalled(const struct xenvif_queue *queue) +{ + unsigned int needed = READ_ONCE(queue->rx_slots_needed); + return !queue->stalled && - prod - cons < 1 && + xenvif_rx_queue_slots(queue) < needed && time_after(jiffies, queue->last_rx_time + queue->vif->stall_timeout); } static bool xenvif_rx_queue_ready(struct xenvif_queue *queue) { - RING_IDX prod, cons; - - prod = queue->rx.sring->req_prod; - cons = queue->rx.req_cons; + unsigned int needed = READ_ONCE(queue->rx_slots_needed); - return queue->stalled && prod - cons >= 1; + return queue->stalled && xenvif_rx_queue_slots(queue) >= needed; } -static bool xenvif_have_rx_work(struct xenvif_queue *queue) +bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread) { return xenvif_rx_ring_slots_available(queue) || (queue->vif->stall_timeout && (xenvif_rx_queue_stalled(queue) || xenvif_rx_queue_ready(queue))) || - kthread_should_stop() || + (test_kthread && kthread_should_stop()) || queue->vif->disabled; } @@ -527,15 +558,20 @@ { DEFINE_WAIT(wait); - if (xenvif_have_rx_work(queue)) + if (xenvif_have_rx_work(queue, true)) return; for (;;) { long ret; prepare_to_wait(&queue->wq, &wait, TASK_INTERRUPTIBLE); - if (xenvif_have_rx_work(queue)) + if (xenvif_have_rx_work(queue, true)) break; + if (atomic_fetch_andnot(NETBK_RX_EOI | NETBK_COMMON_EOI, + &queue->eoi_pending) & + (NETBK_RX_EOI | NETBK_COMMON_EOI)) + xen_irq_lateeoi(queue->rx_irq, 0); + ret = schedule_timeout(xenvif_rx_queue_timeout(queue)); if (!ret) break; --- linux-oracle-5.4.0.orig/drivers/net/xen-netback/xenbus.c +++ linux-oracle-5.4.0/drivers/net/xen-netback/xenbus.c @@ -202,10 +202,10 @@ set_backend_state(be, XenbusStateClosed); unregister_hotplug_status_watch(be); + xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); if (be->vif) { kobject_uevent(&dev->dev.kobj, KOBJ_OFFLINE); xen_unregister_watchers(be->vif); - xenbus_rm(XBT_NIL, dev->nodename, "hotplug-status"); xenvif_free(be->vif); be->vif = NULL; } @@ -713,12 +713,14 @@ return -ENOMEM; snprintf(node, maxlen, "%s/rate", dev->nodename); vif->credit_watch.node = node; + vif->credit_watch.will_handle = NULL; vif->credit_watch.callback = xen_net_rate_changed; err = register_xenbus_watch(&vif->credit_watch); if (err) { pr_err("Failed to set watcher %s\n", vif->credit_watch.node); kfree(node); vif->credit_watch.node = NULL; + vif->credit_watch.will_handle = NULL; vif->credit_watch.callback = NULL; } return err; @@ -765,6 +767,7 @@ snprintf(node, maxlen, "%s/request-multicast-control", dev->otherend); vif->mcast_ctrl_watch.node = node; + vif->mcast_ctrl_watch.will_handle = NULL; vif->mcast_ctrl_watch.callback = xen_mcast_ctrl_changed; err = register_xenbus_watch(&vif->mcast_ctrl_watch); if (err) { @@ -772,6 +775,7 @@ vif->mcast_ctrl_watch.node); kfree(node); vif->mcast_ctrl_watch.node = NULL; + vif->mcast_ctrl_watch.will_handle = NULL; vif->mcast_ctrl_watch.callback = NULL; } return err; @@ -975,7 +979,7 @@ xenvif_carrier_on(be->vif); unregister_hotplug_status_watch(be); - err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, + err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL, hotplug_status_changed, "%s/%s", dev->nodename, "hotplug-status"); if (!err) --- linux-oracle-5.4.0.orig/drivers/net/xen-netfront.c +++ linux-oracle-5.4.0/drivers/net/xen-netfront.c @@ -63,6 +63,12 @@ MODULE_PARM_DESC(max_queues, "Maximum number of queues per virtual interface"); +static bool __read_mostly xennet_trusted = true; +module_param_named(trusted, xennet_trusted, bool, 0644); +MODULE_PARM_DESC(trusted, "Is the backend trusted"); + +#define XENNET_TIMEOUT (5 * HZ) + static const struct ethtool_ops xennet_ethtool_ops; struct netfront_cb { @@ -119,21 +125,17 @@ /* * {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries - * are linked from tx_skb_freelist through skb_entry.link. - * - * NB. Freelist index entries are always going to be less than - * PAGE_OFFSET, whereas pointers to skbs will always be equal or - * greater than PAGE_OFFSET: we use this property to distinguish - * them. + * are linked from tx_skb_freelist through tx_link. */ - union skb_entry { - struct sk_buff *skb; - unsigned long link; - } tx_skbs[NET_TX_RING_SIZE]; + struct sk_buff *tx_skbs[NET_TX_RING_SIZE]; + unsigned short tx_link[NET_TX_RING_SIZE]; +#define TX_LINK_NONE 0xffff +#define TX_PENDING 0xfffe grant_ref_t gref_tx_head; grant_ref_t grant_tx_ref[NET_TX_RING_SIZE]; struct page *grant_tx_page[NET_TX_RING_SIZE]; unsigned tx_skb_freelist; + unsigned int tx_pend_queue; spinlock_t rx_lock ____cacheline_aligned_in_smp; struct xen_netif_rx_front_ring rx; @@ -144,6 +146,9 @@ struct sk_buff *rx_skbs[NET_RX_RING_SIZE]; grant_ref_t gref_rx_head; grant_ref_t grant_rx_ref[NET_RX_RING_SIZE]; + + unsigned int rx_rsp_unconsumed; + spinlock_t rx_cons_lock; }; struct netfront_info { @@ -159,6 +164,12 @@ struct netfront_stats __percpu *rx_stats; struct netfront_stats __percpu *tx_stats; + /* Is device behaving sane? */ + bool broken; + + /* Should skbs be bounced into a zeroed buffer? */ + bool bounce; + atomic_t rx_gso_checksum_fixup; }; @@ -167,33 +178,25 @@ struct xen_netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; }; -static void skb_entry_set_link(union skb_entry *list, unsigned short id) -{ - list->link = id; -} - -static int skb_entry_is_link(const union skb_entry *list) -{ - BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link)); - return (unsigned long)list->skb < PAGE_OFFSET; -} - /* * Access macros for acquiring freeing slots in tx_skbs[]. */ -static void add_id_to_freelist(unsigned *head, union skb_entry *list, - unsigned short id) +static void add_id_to_list(unsigned *head, unsigned short *list, + unsigned short id) { - skb_entry_set_link(&list[id], *head); + list[id] = *head; *head = id; } -static unsigned short get_id_from_freelist(unsigned *head, - union skb_entry *list) +static unsigned short get_id_from_list(unsigned *head, unsigned short *list) { unsigned int id = *head; - *head = list[id].link; + + if (id != TX_LINK_NONE) { + *head = list[id]; + list[id] = TX_LINK_NONE; + } return id; } @@ -265,7 +268,7 @@ if (unlikely(!skb)) return NULL; - page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | __GFP_ZERO); if (!page) { kfree_skb(skb); return NULL; @@ -349,7 +352,7 @@ unsigned int i = 0; struct netfront_queue *queue = NULL; - if (!np->queues) + if (!np->queues || np->broken) return -ENODEV; for (i = 0; i < num_queues; ++i) { @@ -371,41 +374,62 @@ return 0; } -static void xennet_tx_buf_gc(struct netfront_queue *queue) +static bool xennet_tx_buf_gc(struct netfront_queue *queue) { RING_IDX cons, prod; unsigned short id; struct sk_buff *skb; bool more_to_do; + bool work_done = false; + const struct device *dev = &queue->info->netdev->dev; BUG_ON(!netif_carrier_ok(queue->info->netdev)); do { prod = queue->tx.sring->rsp_prod; + if (RING_RESPONSE_PROD_OVERFLOW(&queue->tx, prod)) { + dev_alert(dev, "Illegal number of responses %u\n", + prod - queue->tx.rsp_cons); + goto err; + } rmb(); /* Ensure we see responses up to 'rp'. */ for (cons = queue->tx.rsp_cons; cons != prod; cons++) { - struct xen_netif_tx_response *txrsp; + struct xen_netif_tx_response txrsp; - txrsp = RING_GET_RESPONSE(&queue->tx, cons); - if (txrsp->status == XEN_NETIF_RSP_NULL) + work_done = true; + + RING_COPY_RESPONSE(&queue->tx, cons, &txrsp); + if (txrsp.status == XEN_NETIF_RSP_NULL) continue; - id = txrsp->id; - skb = queue->tx_skbs[id].skb; - if (unlikely(gnttab_query_foreign_access( - queue->grant_tx_ref[id]) != 0)) { - pr_alert("%s: warning -- grant still in use by backend domain\n", - __func__); - BUG(); + id = txrsp.id; + if (id >= RING_SIZE(&queue->tx)) { + dev_alert(dev, + "Response has incorrect id (%u)\n", + id); + goto err; + } + if (queue->tx_link[id] != TX_PENDING) { + dev_alert(dev, + "Response for inactive request\n"); + goto err; + } + + queue->tx_link[id] = TX_LINK_NONE; + skb = queue->tx_skbs[id]; + queue->tx_skbs[id] = NULL; + if (unlikely(!gnttab_end_foreign_access_ref( + queue->grant_tx_ref[id], GNTMAP_readonly))) { + dev_alert(dev, + "Grant still in use by backend domain\n"); + goto err; } - gnttab_end_foreign_access_ref( - queue->grant_tx_ref[id], GNTMAP_readonly); gnttab_release_grant_reference( &queue->gref_tx_head, queue->grant_tx_ref[id]); queue->grant_tx_ref[id] = GRANT_INVALID_REF; queue->grant_tx_page[id] = NULL; - add_id_to_freelist(&queue->tx_skb_freelist, queue->tx_skbs, id); + add_id_to_list(&queue->tx_skb_freelist, queue->tx_link, id); dev_kfree_skb_irq(skb); } @@ -415,13 +439,22 @@ } while (more_to_do); xennet_maybe_wake_tx(queue); + + return work_done; + + err: + queue->info->broken = true; + dev_alert(dev, "Disabled for further use\n"); + + return work_done; } struct xennet_gnttab_make_txreq { struct netfront_queue *queue; struct sk_buff *skb; struct page *page; - struct xen_netif_tx_request *tx; /* Last request */ + struct xen_netif_tx_request *tx; /* Last request on ring page */ + struct xen_netif_tx_request tx_local; /* Last request local copy*/ unsigned int size; }; @@ -437,7 +470,7 @@ struct netfront_queue *queue = info->queue; struct sk_buff *skb = info->skb; - id = get_id_from_freelist(&queue->tx_skb_freelist, queue->tx_skbs); + id = get_id_from_list(&queue->tx_skb_freelist, queue->tx_link); tx = RING_GET_REQUEST(&queue->tx, queue->tx.req_prod_pvt++); ref = gnttab_claim_grant_reference(&queue->gref_tx_head); WARN_ON_ONCE(IS_ERR_VALUE((unsigned long)(int)ref)); @@ -445,34 +478,37 @@ gnttab_grant_foreign_access_ref(ref, queue->info->xbdev->otherend_id, gfn, GNTMAP_readonly); - queue->tx_skbs[id].skb = skb; + queue->tx_skbs[id] = skb; queue->grant_tx_page[id] = page; queue->grant_tx_ref[id] = ref; - tx->id = id; - tx->gref = ref; - tx->offset = offset; - tx->size = len; - tx->flags = 0; + info->tx_local.id = id; + info->tx_local.gref = ref; + info->tx_local.offset = offset; + info->tx_local.size = len; + info->tx_local.flags = 0; + + *tx = info->tx_local; + + /* + * Put the request in the pending queue, it will be set to be pending + * when the producer index is about to be raised. + */ + add_id_to_list(&queue->tx_pend_queue, queue->tx_link, id); info->tx = tx; - info->size += tx->size; + info->size += info->tx_local.size; } static struct xen_netif_tx_request *xennet_make_first_txreq( - struct netfront_queue *queue, struct sk_buff *skb, - struct page *page, unsigned int offset, unsigned int len) + struct xennet_gnttab_make_txreq *info, + unsigned int offset, unsigned int len) { - struct xennet_gnttab_make_txreq info = { - .queue = queue, - .skb = skb, - .page = page, - .size = 0, - }; + info->size = 0; - gnttab_for_one_grant(page, offset, len, xennet_tx_setup_grant, &info); + gnttab_for_one_grant(info->page, offset, len, xennet_tx_setup_grant, info); - return info.tx; + return info->tx; } static void xennet_make_one_txreq(unsigned long gfn, unsigned int offset, @@ -485,35 +521,27 @@ xennet_tx_setup_grant(gfn, offset, len, data); } -static struct xen_netif_tx_request *xennet_make_txreqs( - struct netfront_queue *queue, struct xen_netif_tx_request *tx, - struct sk_buff *skb, struct page *page, +static void xennet_make_txreqs( + struct xennet_gnttab_make_txreq *info, + struct page *page, unsigned int offset, unsigned int len) { - struct xennet_gnttab_make_txreq info = { - .queue = queue, - .skb = skb, - .tx = tx, - }; - /* Skip unused frames from start of page */ page += offset >> PAGE_SHIFT; offset &= ~PAGE_MASK; while (len) { - info.page = page; - info.size = 0; + info->page = page; + info->size = 0; gnttab_foreach_grant_in_range(page, offset, len, xennet_make_one_txreq, - &info); + info); page++; offset = 0; - len -= info.size; + len -= info->size; } - - return info.tx; } /* @@ -560,13 +588,50 @@ return queue_idx; } +static void xennet_mark_tx_pending(struct netfront_queue *queue) +{ + unsigned int i; + + while ((i = get_id_from_list(&queue->tx_pend_queue, queue->tx_link)) != + TX_LINK_NONE) + queue->tx_link[i] = TX_PENDING; +} + +struct sk_buff *bounce_skb(const struct sk_buff *skb) +{ + unsigned int headerlen = skb_headroom(skb); + /* Align size to allocate full pages and avoid contiguous data leaks */ + unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len, + XEN_PAGE_SIZE); + struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO); + + if (!n) + return NULL; + + if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) { + WARN_ONCE(1, "misaligned skb allocated\n"); + kfree_skb(n); + return NULL; + } + + /* Set the data pointer */ + skb_reserve(n, headerlen); + /* Set the tail pointer and length */ + skb_put(n, skb->len); + + BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len)); + + skb_copy_header(n, skb); + return n; +} + #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1) static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); struct netfront_stats *tx_stats = this_cpu_ptr(np->tx_stats); - struct xen_netif_tx_request *tx, *first_tx; + struct xen_netif_tx_request *first_tx; unsigned int i; int notify; int slots; @@ -575,6 +640,7 @@ unsigned int len; unsigned long flags; struct netfront_queue *queue = NULL; + struct xennet_gnttab_make_txreq info = { }; unsigned int num_queues = dev->real_num_tx_queues; u16 queue_index; struct sk_buff *nskb; @@ -582,6 +648,8 @@ /* Drop the packet if no queues are set up */ if (num_queues < 1) goto drop; + if (unlikely(np->broken)) + goto drop; /* Determine which queue to transmit this SKB on */ queue_index = skb_get_queue_mapping(skb); queue = &np->queues[queue_index]; @@ -609,9 +677,13 @@ /* The first req should be at least ETH_HLEN size or the packet will be * dropped by netback. + * + * If the backend is not trusted bounce all data to zeroed pages to + * avoid exposing contiguous data on the granted page not belonging to + * the skb. */ - if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) { - nskb = skb_copy(skb, GFP_ATOMIC); + if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) { + nskb = bounce_skb(skb); if (!nskb) goto drop; dev_consume_skb_any(skb); @@ -632,21 +704,24 @@ } /* First request for the linear area. */ - first_tx = tx = xennet_make_first_txreq(queue, skb, - page, offset, len); - offset += tx->size; + info.queue = queue; + info.skb = skb; + info.page = page; + first_tx = xennet_make_first_txreq(&info, offset, len); + offset += info.tx_local.size; if (offset == PAGE_SIZE) { page++; offset = 0; } - len -= tx->size; + len -= info.tx_local.size; if (skb->ip_summed == CHECKSUM_PARTIAL) /* local packet? */ - tx->flags |= XEN_NETTXF_csum_blank | XEN_NETTXF_data_validated; + first_tx->flags |= XEN_NETTXF_csum_blank | + XEN_NETTXF_data_validated; else if (skb->ip_summed == CHECKSUM_UNNECESSARY) /* remote but checksummed. */ - tx->flags |= XEN_NETTXF_data_validated; + first_tx->flags |= XEN_NETTXF_data_validated; /* Optional extra info after the first request. */ if (skb_shinfo(skb)->gso_size) { @@ -655,7 +730,7 @@ gso = (struct xen_netif_extra_info *) RING_GET_REQUEST(&queue->tx, queue->tx.req_prod_pvt++); - tx->flags |= XEN_NETTXF_extra_info; + first_tx->flags |= XEN_NETTXF_extra_info; gso->u.gso.size = skb_shinfo(skb)->gso_size; gso->u.gso.type = (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) ? @@ -669,12 +744,12 @@ } /* Requests for the rest of the linear area. */ - tx = xennet_make_txreqs(queue, tx, skb, page, offset, len); + xennet_make_txreqs(&info, page, offset, len); /* Requests for all the frags. */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - tx = xennet_make_txreqs(queue, tx, skb, skb_frag_page(frag), + xennet_make_txreqs(&info, skb_frag_page(frag), skb_frag_off(frag), skb_frag_size(frag)); } @@ -682,6 +757,8 @@ /* First request has the packet length. */ first_tx->size = skb->len; + xennet_mark_tx_pending(queue); + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&queue->tx, notify); if (notify) notify_remote_via_irq(queue->tx_irq); @@ -710,7 +787,7 @@ static int xennet_close(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); - unsigned int num_queues = dev->real_num_tx_queues; + unsigned int num_queues = np->queues ? dev->real_num_tx_queues : 0; unsigned int i; struct netfront_queue *queue; netif_tx_stop_all_queues(np->netdev); @@ -721,6 +798,41 @@ return 0; } +static void xennet_destroy_queues(struct netfront_info *info) +{ + unsigned int i; + + if (!info->queues) + return; + + for (i = 0; i < info->netdev->real_num_tx_queues; i++) { + struct netfront_queue *queue = &info->queues[i]; + + if (netif_running(info->netdev)) + napi_disable(&queue->napi); + netif_napi_del(&queue->napi); + } + + kfree(info->queues); + info->queues = NULL; +} + +static void xennet_uninit(struct net_device *dev) +{ + struct netfront_info *np = netdev_priv(dev); + xennet_destroy_queues(np); +} + +static void xennet_set_rx_rsp_cons(struct netfront_queue *queue, RING_IDX val) +{ + unsigned long flags; + + spin_lock_irqsave(&queue->rx_cons_lock, flags); + queue->rx.rsp_cons = val; + queue->rx_rsp_unconsumed = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx); + spin_unlock_irqrestore(&queue->rx_cons_lock, flags); +} + static void xennet_move_rx_slot(struct netfront_queue *queue, struct sk_buff *skb, grant_ref_t ref) { @@ -739,7 +851,7 @@ RING_IDX rp) { - struct xen_netif_extra_info *extra; + struct xen_netif_extra_info extra; struct device *dev = &queue->info->netdev->dev; RING_IDX cons = queue->rx.rsp_cons; int err = 0; @@ -755,26 +867,24 @@ break; } - extra = (struct xen_netif_extra_info *) - RING_GET_RESPONSE(&queue->rx, ++cons); + RING_COPY_RESPONSE(&queue->rx, ++cons, &extra); - if (unlikely(!extra->type || - extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + if (unlikely(!extra.type || + extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { if (net_ratelimit()) dev_warn(dev, "Invalid extra type: %d\n", - extra->type); + extra.type); err = -EINVAL; } else { - memcpy(&extras[extra->type - 1], extra, - sizeof(*extra)); + extras[extra.type - 1] = extra; } skb = xennet_get_rx_skb(queue, cons); ref = xennet_get_rx_ref(queue, cons); xennet_move_rx_slot(queue, skb, ref); - } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); + } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE); - queue->rx.rsp_cons = cons; + xennet_set_rx_rsp_cons(queue, cons); return err; } @@ -782,7 +892,7 @@ struct netfront_rx_info *rinfo, RING_IDX rp, struct sk_buff_head *list) { - struct xen_netif_rx_response *rx = &rinfo->rx; + struct xen_netif_rx_response *rx = &rinfo->rx, rx_local; struct xen_netif_extra_info *extras = rinfo->extras; struct device *dev = &queue->info->netdev->dev; RING_IDX cons = queue->rx.rsp_cons; @@ -791,7 +901,6 @@ int max = XEN_NETIF_NR_SLOTS_MIN + (rx->status <= RX_COPY_THRESHOLD); int slots = 1; int err = 0; - unsigned long ret; if (rx->flags & XEN_NETRXF_extra_info) { err = xennet_get_extras(queue, extras, rp); @@ -822,8 +931,13 @@ goto next; } - ret = gnttab_end_foreign_access_ref(ref, 0); - BUG_ON(!ret); + if (!gnttab_end_foreign_access_ref(ref, 0)) { + dev_alert(dev, + "Grant still in use by backend domain\n"); + queue->info->broken = true; + dev_alert(dev, "Disabled for further use\n"); + return -EINVAL; + } gnttab_release_grant_reference(&queue->gref_rx_head, ref); @@ -840,7 +954,8 @@ break; } - rx = RING_GET_RESPONSE(&queue->rx, cons + slots); + RING_COPY_RESPONSE(&queue->rx, cons + slots, &rx_local); + rx = &rx_local; skb = xennet_get_rx_skb(queue, cons + slots); ref = xennet_get_rx_ref(queue, cons + slots); slots++; @@ -853,7 +968,7 @@ } if (unlikely(err)) - queue->rx.rsp_cons = cons + slots; + xennet_set_rx_rsp_cons(queue, cons + slots); return err; } @@ -895,10 +1010,11 @@ struct sk_buff *nskb; while ((nskb = __skb_dequeue(list))) { - struct xen_netif_rx_response *rx = - RING_GET_RESPONSE(&queue->rx, ++cons); + struct xen_netif_rx_response rx; skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; + RING_COPY_RESPONSE(&queue->rx, ++cons, &rx); + if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) { unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; @@ -906,20 +1022,21 @@ __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); } if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) { - queue->rx.rsp_cons = ++cons + skb_queue_len(list); + xennet_set_rx_rsp_cons(queue, + ++cons + skb_queue_len(list)); kfree_skb(nskb); return -ENOENT; } skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, skb_frag_page(nfrag), - rx->offset, rx->status, PAGE_SIZE); + rx.offset, rx.status, PAGE_SIZE); skb_shinfo(nskb)->nr_frags = 0; kfree_skb(nskb); } - queue->rx.rsp_cons = cons; + xennet_set_rx_rsp_cons(queue, cons); return 0; } @@ -1006,17 +1123,28 @@ skb_queue_head_init(&tmpq); rp = queue->rx.sring->rsp_prod; + if (RING_RESPONSE_PROD_OVERFLOW(&queue->rx, rp)) { + dev_alert(&dev->dev, "Illegal number of responses %u\n", + rp - queue->rx.rsp_cons); + queue->info->broken = true; + spin_unlock(&queue->rx_lock); + return 0; + } rmb(); /* Ensure we see queued responses up to 'rp'. */ i = queue->rx.rsp_cons; work_done = 0; while ((i != rp) && (work_done < budget)) { - memcpy(rx, RING_GET_RESPONSE(&queue->rx, i), sizeof(*rx)); + RING_COPY_RESPONSE(&queue->rx, i, rx); memset(extras, 0, sizeof(rinfo.extras)); err = xennet_get_responses(queue, &rinfo, rp, &tmpq); if (unlikely(err)) { + if (queue->info->broken) { + spin_unlock(&queue->rx_lock); + return 0; + } err: while ((skb = __skb_dequeue(&tmpq))) __skb_queue_tail(&errq, skb); @@ -1033,7 +1161,9 @@ if (unlikely(xennet_set_skb_gso(skb, gso))) { __skb_queue_head(&tmpq, skb); - queue->rx.rsp_cons += skb_queue_len(&tmpq); + xennet_set_rx_rsp_cons(queue, + queue->rx.rsp_cons + + skb_queue_len(&tmpq)); goto err; } } @@ -1057,7 +1187,8 @@ __skb_queue_tail(&rxq, skb); - i = ++queue->rx.rsp_cons; + i = queue->rx.rsp_cons + 1; + xennet_set_rx_rsp_cons(queue, i); work_done++; } @@ -1133,17 +1264,18 @@ for (i = 0; i < NET_TX_RING_SIZE; i++) { /* Skip over entries which are actually freelist references */ - if (skb_entry_is_link(&queue->tx_skbs[i])) + if (!queue->tx_skbs[i]) continue; - skb = queue->tx_skbs[i].skb; + skb = queue->tx_skbs[i]; + queue->tx_skbs[i] = NULL; get_page(queue->grant_tx_page[i]); gnttab_end_foreign_access(queue->grant_tx_ref[i], GNTMAP_readonly, (unsigned long)page_address(queue->grant_tx_page[i])); queue->grant_tx_page[i] = NULL; queue->grant_tx_ref[i] = GRANT_INVALID_REF; - add_id_to_freelist(&queue->tx_skb_freelist, queue->tx_skbs, i); + add_id_to_list(&queue->tx_skb_freelist, queue->tx_link, i); dev_kfree_skb_irq(skb); } } @@ -1218,34 +1350,79 @@ return 0; } -static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id) +static bool xennet_handle_tx(struct netfront_queue *queue, unsigned int *eoi) { - struct netfront_queue *queue = dev_id; unsigned long flags; + if (unlikely(queue->info->broken)) + return false; + spin_lock_irqsave(&queue->tx_lock, flags); - xennet_tx_buf_gc(queue); + if (xennet_tx_buf_gc(queue)) + *eoi = 0; spin_unlock_irqrestore(&queue->tx_lock, flags); + return true; +} + +static irqreturn_t xennet_tx_interrupt(int irq, void *dev_id) +{ + unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; + + if (likely(xennet_handle_tx(dev_id, &eoiflag))) + xen_irq_lateeoi(irq, eoiflag); + return IRQ_HANDLED; } -static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id) +static bool xennet_handle_rx(struct netfront_queue *queue, unsigned int *eoi) { - struct netfront_queue *queue = dev_id; - struct net_device *dev = queue->info->netdev; + unsigned int work_queued; + unsigned long flags; + + if (unlikely(queue->info->broken)) + return false; - if (likely(netif_carrier_ok(dev) && - RING_HAS_UNCONSUMED_RESPONSES(&queue->rx))) + spin_lock_irqsave(&queue->rx_cons_lock, flags); + work_queued = RING_HAS_UNCONSUMED_RESPONSES(&queue->rx); + if (work_queued > queue->rx_rsp_unconsumed) { + queue->rx_rsp_unconsumed = work_queued; + *eoi = 0; + } else if (unlikely(work_queued < queue->rx_rsp_unconsumed)) { + const struct device *dev = &queue->info->netdev->dev; + + spin_unlock_irqrestore(&queue->rx_cons_lock, flags); + dev_alert(dev, "RX producer index going backwards\n"); + dev_alert(dev, "Disabled for further use\n"); + queue->info->broken = true; + return false; + } + spin_unlock_irqrestore(&queue->rx_cons_lock, flags); + + if (likely(netif_carrier_ok(queue->info->netdev) && work_queued)) napi_schedule(&queue->napi); + return true; +} + +static irqreturn_t xennet_rx_interrupt(int irq, void *dev_id) +{ + unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; + + if (likely(xennet_handle_rx(dev_id, &eoiflag))) + xen_irq_lateeoi(irq, eoiflag); + return IRQ_HANDLED; } static irqreturn_t xennet_interrupt(int irq, void *dev_id) { - xennet_tx_interrupt(irq, dev_id); - xennet_rx_interrupt(irq, dev_id); + unsigned int eoiflag = XEN_EOI_FLAG_SPURIOUS; + + if (xennet_handle_tx(dev_id, &eoiflag) && + xennet_handle_rx(dev_id, &eoiflag)) + xen_irq_lateeoi(irq, eoiflag); + return IRQ_HANDLED; } @@ -1256,12 +1433,17 @@ struct netfront_info *info = netdev_priv(dev); unsigned int num_queues = dev->real_num_tx_queues; unsigned int i; + + if (info->broken) + return; + for (i = 0; i < num_queues; ++i) xennet_interrupt(0, &info->queues[i]); } #endif static const struct net_device_ops xennet_netdev_ops = { + .ndo_uninit = xennet_uninit, .ndo_open = xennet_open, .ndo_stop = xennet_close, .ndo_start_xmit = xennet_start_xmit, @@ -1334,12 +1516,15 @@ netif_carrier_off(netdev); - xenbus_switch_state(dev, XenbusStateInitialising); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) != - XenbusStateClosed && - xenbus_read_driver_state(dev->otherend) != - XenbusStateUnknown); + do { + xenbus_switch_state(dev, XenbusStateInitialising); + err = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) != + XenbusStateClosed && + xenbus_read_driver_state(dev->otherend) != + XenbusStateUnknown, XENNET_TIMEOUT); + } while (!err); + return netdev; exit: @@ -1434,7 +1619,17 @@ dev_dbg(&dev->dev, "%s\n", dev->nodename); + netif_tx_lock_bh(info->netdev); + netif_device_detach(info->netdev); + netif_tx_unlock_bh(info->netdev); + xennet_disconnect_backend(info); + + rtnl_lock(); + if (info->queues) + xennet_destroy_queues(info); + rtnl_unlock(); + return 0; } @@ -1468,9 +1663,10 @@ if (err < 0) goto fail; - err = bind_evtchn_to_irqhandler(queue->tx_evtchn, - xennet_interrupt, - 0, queue->info->netdev->name, queue); + err = bind_evtchn_to_irqhandler_lateeoi(queue->tx_evtchn, + xennet_interrupt, 0, + queue->info->netdev->name, + queue); if (err < 0) goto bind_fail; queue->rx_evtchn = queue->tx_evtchn; @@ -1498,18 +1694,18 @@ snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name), "%s-tx", queue->name); - err = bind_evtchn_to_irqhandler(queue->tx_evtchn, - xennet_tx_interrupt, - 0, queue->tx_irq_name, queue); + err = bind_evtchn_to_irqhandler_lateeoi(queue->tx_evtchn, + xennet_tx_interrupt, 0, + queue->tx_irq_name, queue); if (err < 0) goto bind_tx_fail; queue->tx_irq = err; snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name), "%s-rx", queue->name); - err = bind_evtchn_to_irqhandler(queue->rx_evtchn, - xennet_rx_interrupt, - 0, queue->rx_irq_name, queue); + err = bind_evtchn_to_irqhandler_lateeoi(queue->rx_evtchn, + xennet_rx_interrupt, 0, + queue->rx_irq_name, queue); if (err < 0) goto bind_rx_fail; queue->rx_irq = err; @@ -1533,7 +1729,7 @@ struct netfront_queue *queue, unsigned int feature_split_evtchn) { struct xen_netif_tx_sring *txs; - struct xen_netif_rx_sring *rxs; + struct xen_netif_rx_sring *rxs = NULL; grant_ref_t gref; int err; @@ -1553,21 +1749,21 @@ err = xenbus_grant_ring(dev, txs, 1, &gref); if (err < 0) - goto grant_tx_ring_fail; + goto fail; queue->tx_ring_ref = gref; rxs = (struct xen_netif_rx_sring *)get_zeroed_page(GFP_NOIO | __GFP_HIGH); if (!rxs) { err = -ENOMEM; xenbus_dev_fatal(dev, err, "allocating rx ring page"); - goto alloc_rx_ring_fail; + goto fail; } SHARED_RING_INIT(rxs); FRONT_RING_INIT(&queue->rx, rxs, XEN_PAGE_SIZE); err = xenbus_grant_ring(dev, rxs, 1, &gref); if (err < 0) - goto grant_rx_ring_fail; + goto fail; queue->rx_ring_ref = gref; if (feature_split_evtchn) @@ -1580,22 +1776,28 @@ err = setup_netfront_single(queue); if (err) - goto alloc_evtchn_fail; + goto fail; return 0; /* If we fail to setup netfront, it is safe to just revoke access to * granted pages because backend is not accessing it at this point. */ -alloc_evtchn_fail: - gnttab_end_foreign_access_ref(queue->rx_ring_ref, 0); -grant_rx_ring_fail: - free_page((unsigned long)rxs); -alloc_rx_ring_fail: - gnttab_end_foreign_access_ref(queue->tx_ring_ref, 0); -grant_tx_ring_fail: - free_page((unsigned long)txs); -fail: + fail: + if (queue->rx_ring_ref != GRANT_INVALID_REF) { + gnttab_end_foreign_access(queue->rx_ring_ref, 0, + (unsigned long)rxs); + queue->rx_ring_ref = GRANT_INVALID_REF; + } else { + free_page((unsigned long)rxs); + } + if (queue->tx_ring_ref != GRANT_INVALID_REF) { + gnttab_end_foreign_access(queue->tx_ring_ref, 0, + (unsigned long)txs); + queue->tx_ring_ref = GRANT_INVALID_REF; + } else { + free_page((unsigned long)txs); + } return err; } @@ -1611,6 +1813,7 @@ spin_lock_init(&queue->tx_lock); spin_lock_init(&queue->rx_lock); + spin_lock_init(&queue->rx_cons_lock); timer_setup(&queue->rx_refill_timer, rx_refill_timeout, 0); @@ -1618,13 +1821,15 @@ snprintf(queue->name, sizeof(queue->name), "vif%s-q%u", devid, queue->id); - /* Initialise tx_skbs as a free chain containing every entry. */ + /* Initialise tx_skb_freelist as a free chain containing every entry. */ queue->tx_skb_freelist = 0; + queue->tx_pend_queue = TX_LINK_NONE; for (i = 0; i < NET_TX_RING_SIZE; i++) { - skb_entry_set_link(&queue->tx_skbs[i], i+1); + queue->tx_link[i] = i + 1; queue->grant_tx_ref[i] = GRANT_INVALID_REF; queue->grant_tx_page[i] = NULL; } + queue->tx_link[NET_TX_RING_SIZE - 1] = TX_LINK_NONE; /* Clear out rx_skbs */ for (i = 0; i < NET_RX_RING_SIZE; i++) { @@ -1738,22 +1943,6 @@ return err; } -static void xennet_destroy_queues(struct netfront_info *info) -{ - unsigned int i; - - for (i = 0; i < info->netdev->real_num_tx_queues; i++) { - struct netfront_queue *queue = &info->queues[i]; - - if (netif_running(info->netdev)) - napi_disable(&queue->napi); - netif_napi_del(&queue->napi); - } - - kfree(info->queues); - info->queues = NULL; -} - static int xennet_create_queues(struct netfront_info *info, unsigned int *num_queues) { @@ -1809,6 +1998,10 @@ info->netdev->irq = 0; + /* Check if backend is trusted. */ + info->bounce = !xennet_trusted || + !xenbus_read_unsigned(dev->nodename, "trusted", 1); + /* Check if backend supports multiple queues */ max_queues = xenbus_read_unsigned(info->xbdev->otherend, "multi-queue-max-queues", 1); @@ -1829,6 +2022,9 @@ if (info->queues) xennet_destroy_queues(info); + /* For the case of a reconnect reset the "broken" indicator. */ + info->broken = false; + err = xennet_create_queues(info, &num_queues); if (err < 0) { xenbus_dev_fatal(dev, err, "creating queues"); @@ -1959,6 +2155,9 @@ err = talk_to_netback(np->xbdev, np); if (err) return err; + if (np->bounce) + dev_info(&np->xbdev->dev, + "bouncing transmitted data to zeroed pages\n"); /* talk_to_netback() sets the correct number of queues */ num_queues = dev->real_num_tx_queues; @@ -1982,6 +2181,10 @@ * domain a kick because we've probably just requeued some * packets. */ + netif_tx_lock_bh(np->netdev); + netif_device_attach(np->netdev); + netif_tx_unlock_bh(np->netdev); + netif_carrier_on(np->netdev); for (j = 0; j < num_queues; ++j) { queue = &np->queues[j]; @@ -2139,28 +2342,43 @@ }; #endif /* CONFIG_SYSFS */ -static int xennet_remove(struct xenbus_device *dev) +static void xennet_bus_close(struct xenbus_device *dev) { - struct netfront_info *info = dev_get_drvdata(&dev->dev); - - dev_dbg(&dev->dev, "%s\n", dev->nodename); + int ret; - if (xenbus_read_driver_state(dev->otherend) != XenbusStateClosed) { + if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + return; + do { xenbus_switch_state(dev, XenbusStateClosing); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosing || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown); + ret = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosing || + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); + } while (!ret); + + if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + return; + do { xenbus_switch_state(dev, XenbusStateClosed); - wait_event(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosed || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown); - } + ret = wait_event_timeout(module_wq, + xenbus_read_driver_state(dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); + } while (!ret); +} + +static int xennet_remove(struct xenbus_device *dev) +{ + struct netfront_info *info = dev_get_drvdata(&dev->dev); + xennet_bus_close(dev); xennet_disconnect_backend(info); if (info->netdev->reg_state == NETREG_REGISTERED) --- linux-oracle-5.4.0.orig/drivers/nfc/fdp/fdp.c +++ linux-oracle-5.4.0/drivers/nfc/fdp/fdp.c @@ -184,7 +184,7 @@ const struct firmware *fw; struct sk_buff *skb; unsigned long len; - u8 max_size, payload_size; + int max_size, payload_size; int rc = 0; if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) || @@ -207,8 +207,7 @@ while (len) { - payload_size = min_t(unsigned long, (unsigned long) max_size, - len); + payload_size = min_t(unsigned long, max_size, len); skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/nfc/fdp/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/fdp/i2c.c @@ -255,6 +255,9 @@ len, sizeof(**fw_vsc_cfg), GFP_KERNEL); + if (!*fw_vsc_cfg) + goto alloc_err; + r = device_property_read_u8_array(dev, FDP_DP_FW_VSC_CFG_NAME, *fw_vsc_cfg, len); @@ -268,6 +271,7 @@ *fw_vsc_cfg = NULL; } +alloc_err: dev_dbg(dev, "Clock type: %d, clock frequency: %d, VSC: %s", *clock_type, *clock_freq, *fw_vsc_cfg != NULL ? "yes" : "no"); } --- linux-oracle-5.4.0.orig/drivers/nfc/nfcmrvl/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/nfcmrvl/i2c.c @@ -151,10 +151,15 @@ ret = -EREMOTEIO; } else ret = 0; + } + + if (ret) { kfree_skb(skb); + return ret; } - return ret; + consume_skb(skb); + return 0; } static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv, @@ -186,9 +191,9 @@ pdata->irq_polarity = IRQF_TRIGGER_RISING; ret = irq_of_parse_and_map(node, 0); - if (ret < 0) { - pr_err("Unable to get irq, error: %d\n", ret); - return ret; + if (!ret) { + pr_err("Unable to get irq\n"); + return -EINVAL; } pdata->irq = ret; --- linux-oracle-5.4.0.orig/drivers/nfc/nfcmrvl/main.c +++ linux-oracle-5.4.0/drivers/nfc/nfcmrvl/main.c @@ -194,6 +194,7 @@ { struct nci_dev *ndev = priv->ndev; + nci_unregister_device(ndev); if (priv->ndev->nfc_dev->fw_download_in_progress) nfcmrvl_fw_dnld_abort(priv); @@ -202,7 +203,6 @@ if (gpio_is_valid(priv->config.reset_n_io)) gpio_free(priv->config.reset_n_io); - nci_unregister_device(ndev); nci_free_device(ndev); kfree(priv); } --- linux-oracle-5.4.0.orig/drivers/nfc/nfcmrvl/spi.c +++ linux-oracle-5.4.0/drivers/nfc/nfcmrvl/spi.c @@ -129,9 +129,9 @@ } ret = irq_of_parse_and_map(node, 0); - if (ret < 0) { - pr_err("Unable to get irq, error: %d\n", ret); - return ret; + if (!ret) { + pr_err("Unable to get irq\n"); + return -EINVAL; } pdata->irq = ret; --- linux-oracle-5.4.0.orig/drivers/nfc/nfcmrvl/usb.c +++ linux-oracle-5.4.0/drivers/nfc/nfcmrvl/usb.c @@ -401,13 +401,25 @@ int err; while ((urb = usb_get_from_anchor(&drv_data->deferred))) { + usb_anchor_urb(urb, &drv_data->tx_anchor); + err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) + if (err) { + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + usb_free_urb(urb); break; + } drv_data->tx_in_flight++; + usb_free_urb(urb); + } + + /* Cleanup the rest deferred urbs. */ + while ((urb = usb_get_from_anchor(&drv_data->deferred))) { + kfree(urb->setup_packet); + usb_free_urb(urb); } - usb_scuttle_anchored_urbs(&drv_data->deferred); } static int nfcmrvl_resume(struct usb_interface *intf) --- linux-oracle-5.4.0.orig/drivers/nfc/nfcsim.c +++ linux-oracle-5.4.0/drivers/nfc/nfcsim.c @@ -192,8 +192,7 @@ if (!IS_ERR(skb)) dev_kfree_skb(skb); - - skb = ERR_PTR(-ENODEV); + return; } dev->cb(dev->nfc_digital_dev, dev->arg, skb); @@ -337,10 +336,6 @@ static void nfcsim_debugfs_init(void) { nfcsim_debugfs_root = debugfs_create_dir("nfcsim", NULL); - - if (!nfcsim_debugfs_root) - pr_err("Could not create debugfs entry\n"); - } static void nfcsim_debugfs_remove(void) --- linux-oracle-5.4.0.orig/drivers/nfc/nxp-nci/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/nxp-nci/i2c.c @@ -122,7 +122,9 @@ skb_put_data(*skb, &header, NXP_NCI_FW_HDR_LEN); r = i2c_master_recv(client, skb_put(*skb, frame_len), frame_len); - if (r != frame_len) { + if (r < 0) { + goto fw_read_exit_free_skb; + } else if (r != frame_len) { nfc_err(&client->dev, "Invalid frame length: %u (expected %zu)\n", r, frame_len); @@ -162,8 +164,13 @@ skb_put_data(*skb, (void *)&header, NCI_CTRL_HDR_SIZE); + if (!header.plen) + return 0; + r = i2c_master_recv(client, skb_put(*skb, header.plen), header.plen); - if (r != header.plen) { + if (r < 0) { + goto nci_read_exit_free_skb; + } else if (r != header.plen) { nfc_err(&client->dev, "Invalid frame payload length: %u (expected %u)\n", r, header.plen); @@ -278,7 +285,7 @@ r = devm_acpi_dev_add_driver_gpios(dev, acpi_nxp_nci_gpios); if (r) - return r; + dev_dbg(dev, "Unable to add GPIO mapping table\n"); phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(phy->gpiod_en)) { --- linux-oracle-5.4.0.orig/drivers/nfc/pn533/pn533.c +++ linux-oracle-5.4.0/drivers/nfc/pn533/pn533.c @@ -185,6 +185,32 @@ u8 gt[]; } __packed; +struct pn532_autopoll_resp { + u8 type; + u8 ln; + u8 tg; + u8 tgdata[]; +}; + +/* PN532_CMD_IN_AUTOPOLL */ +#define PN532_AUTOPOLL_POLLNR_INFINITE 0xff +#define PN532_AUTOPOLL_PERIOD 0x03 /* in units of 150 ms */ + +#define PN532_AUTOPOLL_TYPE_GENERIC_106 0x00 +#define PN532_AUTOPOLL_TYPE_GENERIC_212 0x01 +#define PN532_AUTOPOLL_TYPE_GENERIC_424 0x02 +#define PN532_AUTOPOLL_TYPE_JEWEL 0x04 +#define PN532_AUTOPOLL_TYPE_MIFARE 0x10 +#define PN532_AUTOPOLL_TYPE_FELICA212 0x11 +#define PN532_AUTOPOLL_TYPE_FELICA424 0x12 +#define PN532_AUTOPOLL_TYPE_ISOA 0x20 +#define PN532_AUTOPOLL_TYPE_ISOB 0x23 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106 0x40 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212 0x41 +#define PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424 0x42 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106 0x80 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_212 0x81 +#define PN532_AUTOPOLL_TYPE_DEP_ACTIVE_424 0x82 /* PN533_TG_INIT_AS_TARGET */ #define PN533_INIT_TARGET_PASSIVE 0x1 @@ -680,6 +706,9 @@ if (PN533_TYPE_A_SEL_CASCADE(type_a->sel_res) != 0) return false; + if (type_a->nfcid_len > NFC_NFCID1_MAXSIZE) + return false; + return true; } @@ -1290,6 +1319,8 @@ if (IS_ERR(resp)) return PTR_ERR(resp); + memset(&nfc_target, 0, sizeof(struct nfc_target)); + rsp = (struct pn533_cmd_jump_dep_response *)resp->data; rc = rsp->status & PN533_CMD_RET_MASK; @@ -1389,6 +1420,101 @@ return rc; } +static int pn533_autopoll_complete(struct pn533 *dev, void *arg, + struct sk_buff *resp) +{ + struct pn532_autopoll_resp *apr; + struct nfc_target nfc_tgt; + u8 nbtg; + int rc; + + if (IS_ERR(resp)) { + rc = PTR_ERR(resp); + + nfc_err(dev->dev, "%s autopoll complete error %d\n", + __func__, rc); + + if (rc == -ENOENT) { + if (dev->poll_mod_count != 0) + return rc; + goto stop_poll; + } else if (rc < 0) { + nfc_err(dev->dev, + "Error %d when running autopoll\n", rc); + goto stop_poll; + } + } + + nbtg = resp->data[0]; + if ((nbtg > 2) || (nbtg <= 0)) + return -EAGAIN; + + apr = (struct pn532_autopoll_resp *)&resp->data[1]; + while (nbtg--) { + memset(&nfc_tgt, 0, sizeof(struct nfc_target)); + switch (apr->type) { + case PN532_AUTOPOLL_TYPE_ISOA: + dev_dbg(dev->dev, "ISOA\n"); + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_FELICA212: + case PN532_AUTOPOLL_TYPE_FELICA424: + dev_dbg(dev->dev, "FELICA\n"); + rc = pn533_target_found_felica(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_JEWEL: + dev_dbg(dev->dev, "JEWEL\n"); + rc = pn533_target_found_jewel(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_ISOB: + dev_dbg(dev->dev, "ISOB\n"); + rc = pn533_target_found_type_b(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + case PN532_AUTOPOLL_TYPE_MIFARE: + dev_dbg(dev->dev, "Mifare\n"); + rc = pn533_target_found_type_a(&nfc_tgt, apr->tgdata, + apr->ln - 1); + break; + default: + nfc_err(dev->dev, + "Unknown current poll modulation\n"); + rc = -EPROTO; + } + + if (rc) + goto done; + + if (!(nfc_tgt.supported_protocols & dev->poll_protocols)) { + nfc_err(dev->dev, + "The Tg found doesn't have the desired protocol\n"); + rc = -EAGAIN; + goto done; + } + + dev->tgt_available_prots = nfc_tgt.supported_protocols; + apr = (struct pn532_autopoll_resp *) + (apr->tgdata + (apr->ln - 1)); + } + + pn533_poll_reset_mod_list(dev); + nfc_targets_found(dev->nfc_dev, &nfc_tgt, 1); + +done: + dev_kfree_skb(resp); + return rc; + +stop_poll: + nfc_err(dev->dev, "autopoll operation has been stopped\n"); + + pn533_poll_reset_mod_list(dev); + dev->poll_protocols = 0; + return rc; +} + static int pn533_poll_complete(struct pn533 *dev, void *arg, struct sk_buff *resp) { @@ -1532,6 +1658,7 @@ { struct pn533 *dev = nfc_get_drvdata(nfc_dev); struct pn533_poll_modulations *cur_mod; + struct sk_buff *skb; u8 rand_mod; int rc; @@ -1557,9 +1684,78 @@ tm_protocols = 0; } - pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); dev->poll_protocols = im_protocols; dev->listen_protocols = tm_protocols; + if (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL) { + skb = pn533_alloc_skb(dev, 4 + 6); + if (!skb) + return -ENOMEM; + + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_POLLNR_INFINITE; + *((u8 *)skb_put(skb, sizeof(u8))) = PN532_AUTOPOLL_PERIOD; + + if ((im_protocols & NFC_PROTO_MIFARE_MASK) && + (im_protocols & NFC_PROTO_ISO14443_MASK) && + (im_protocols & NFC_PROTO_NFC_DEP_MASK)) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_GENERIC_106; + else { + if (im_protocols & NFC_PROTO_MIFARE_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_MIFARE; + + if (im_protocols & NFC_PROTO_ISO14443_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_ISOA; + + if (im_protocols & NFC_PROTO_NFC_DEP_MASK) { + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_106; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_212; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_PASSIVE_424; + } + } + + if (im_protocols & NFC_PROTO_FELICA_MASK || + im_protocols & NFC_PROTO_NFC_DEP_MASK) { + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_FELICA212; + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_FELICA424; + } + + if (im_protocols & NFC_PROTO_JEWEL_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_JEWEL; + + if (im_protocols & NFC_PROTO_ISO14443_B_MASK) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_ISOB; + + if (tm_protocols) + *((u8 *)skb_put(skb, sizeof(u8))) = + PN532_AUTOPOLL_TYPE_DEP_ACTIVE_106; + + rc = pn533_send_cmd_async(dev, PN533_CMD_IN_AUTOPOLL, skb, + pn533_autopoll_complete, NULL); + + if (rc < 0) + dev_kfree_skb(skb); + else + dev->poll_mod_count++; + + return rc; + } + + pn533_poll_create_mod_list(dev, im_protocols, tm_protocols); + if (!dev->poll_mod_count) { + nfc_err(dev->dev, + "Poll mod list is empty\n"); + return -EINVAL; + } /* Do not always start polling from the same modulation */ get_random_bytes(&rand_mod, sizeof(rand_mod)); @@ -1771,6 +1967,8 @@ dev_dbg(dev->dev, "Creating new target\n"); + memset(&nfc_target, 0, sizeof(struct nfc_target)); + nfc_target.supported_protocols = NFC_PROTO_NFC_DEP_MASK; nfc_target.nfcid1_len = 10; memcpy(nfc_target.nfcid1, rsp->nfcid3t, nfc_target.nfcid1_len); @@ -2069,7 +2267,7 @@ frag = pn533_alloc_skb(dev, frag_size); if (!frag) { skb_queue_purge(&dev->fragment_skb); - break; + return -ENOMEM; } if (!dev->tgt_mode) { @@ -2140,7 +2338,7 @@ /* jumbo frame ? */ if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { rc = pn533_fill_fragment_skbs(dev, skb); - if (rc <= 0) + if (rc < 0) goto error; skb = skb_dequeue(&dev->fragment_skb); @@ -2212,7 +2410,7 @@ /* let's split in multiple chunks if size's too big */ if (skb->len > PN533_CMD_DATAEXCH_DATA_MAXLEN) { rc = pn533_fill_fragment_skbs(dev, skb); - if (rc <= 0) + if (rc < 0) goto error; /* get the first skb */ @@ -2458,7 +2656,11 @@ { struct pn533 *dev = nfc_get_drvdata(nfc_dev); - if (dev->device_type == PN533_DEVICE_PN532) { + if (dev->phy_ops->dev_up) + dev->phy_ops->dev_up(dev); + + if ((dev->device_type == PN533_DEVICE_PN532) || + (dev->device_type == PN533_DEVICE_PN532_AUTOPOLL)) { int rc = pn532_sam_configuration(nfc_dev); if (rc) @@ -2470,7 +2672,14 @@ static int pn533_dev_down(struct nfc_dev *nfc_dev) { - return pn533_rf_field(nfc_dev, 0); + struct pn533 *dev = nfc_get_drvdata(nfc_dev); + int ret; + + ret = pn533_rf_field(nfc_dev, 0); + if (dev->phy_ops->dev_down && !ret) + dev->phy_ops->dev_down(dev); + + return ret; } static struct nfc_ops pn533_nfc_ops = { @@ -2498,6 +2707,7 @@ case PN533_DEVICE_PASORI: case PN533_DEVICE_ACR122U: case PN533_DEVICE_PN532: + case PN533_DEVICE_PN532_AUTOPOLL: max_retries.mx_rty_atr = 0x2; max_retries.mx_rty_psl = 0x1; max_retries.mx_rty_passive_act = @@ -2534,6 +2744,7 @@ switch (dev->device_type) { case PN533_DEVICE_STD: case PN533_DEVICE_PN532: + case PN533_DEVICE_PN532_AUTOPOLL: break; case PN533_DEVICE_PASORI: --- linux-oracle-5.4.0.orig/drivers/nfc/pn533/pn533.h +++ linux-oracle-5.4.0/drivers/nfc/pn533/pn533.h @@ -6,10 +6,11 @@ * Copyright (C) 2012-2013 Tieto Poland */ -#define PN533_DEVICE_STD 0x1 -#define PN533_DEVICE_PASORI 0x2 -#define PN533_DEVICE_ACR122U 0x3 -#define PN533_DEVICE_PN532 0x4 +#define PN533_DEVICE_STD 0x1 +#define PN533_DEVICE_PASORI 0x2 +#define PN533_DEVICE_ACR122U 0x3 +#define PN533_DEVICE_PN532 0x4 +#define PN533_DEVICE_PN532_AUTOPOLL 0x5 #define PN533_ALL_PROTOCOLS (NFC_PROTO_JEWEL_MASK | NFC_PROTO_MIFARE_MASK |\ NFC_PROTO_FELICA_MASK | NFC_PROTO_ISO14443_MASK |\ @@ -70,6 +71,7 @@ #define PN533_CMD_IN_ATR 0x50 #define PN533_CMD_IN_RELEASE 0x52 #define PN533_CMD_IN_JUMP_FOR_DEP 0x56 +#define PN533_CMD_IN_AUTOPOLL 0x60 #define PN533_CMD_TG_INIT_AS_TARGET 0x8c #define PN533_CMD_TG_GET_DATA 0x86 @@ -207,6 +209,15 @@ struct sk_buff *out); int (*send_ack)(struct pn533 *dev, gfp_t flags); void (*abort_cmd)(struct pn533 *priv, gfp_t flags); + /* + * dev_up and dev_down are optional. + * They are used to inform the phy layer that the nfc chip + * is going to be really used very soon. The phy layer can then + * bring up it's interface to the chip and have it suspended for power + * saving reasons otherwise. + */ + void (*dev_up)(struct pn533 *priv); + void (*dev_down)(struct pn533 *priv); }; --- linux-oracle-5.4.0.orig/drivers/nfc/pn533/usb.c +++ linux-oracle-5.4.0/drivers/nfc/pn533/usb.c @@ -153,10 +153,17 @@ return usb_submit_urb(phy->ack_urb, flags); } +struct pn533_out_arg { + struct pn533_usb_phy *phy; + struct completion done; +}; + static int pn533_usb_send_frame(struct pn533 *dev, struct sk_buff *out) { struct pn533_usb_phy *phy = dev->phy; + struct pn533_out_arg arg; + void *cntx; int rc; if (phy->priv == NULL) @@ -168,10 +175,18 @@ print_hex_dump_debug("PN533 TX: ", DUMP_PREFIX_NONE, 16, 1, out->data, out->len, false); + arg.phy = phy; + init_completion(&arg.done); + cntx = phy->out_urb->context; + phy->out_urb->context = &arg; + rc = usb_submit_urb(phy->out_urb, GFP_KERNEL); if (rc) return rc; + wait_for_completion(&arg.done); + phy->out_urb->context = cntx; + if (dev->protocol_type == PN533_PROTO_REQ_RESP) { /* request for response for sent packet directly */ rc = pn533_submit_urb_for_response(phy, GFP_KERNEL); @@ -391,7 +406,7 @@ cmd, sizeof(cmd), false); rc = usb_bulk_msg(phy->udev, phy->out_urb->pipe, buffer, sizeof(cmd), - &transferred, 0); + &transferred, 5000); kfree(buffer); if (rc || (transferred != sizeof(cmd))) { nfc_err(&phy->udev->dev, @@ -412,7 +427,31 @@ return arg.rc; } -static void pn533_send_complete(struct urb *urb) +static void pn533_out_complete(struct urb *urb) +{ + struct pn533_out_arg *arg = urb->context; + struct pn533_usb_phy *phy = arg->phy; + + switch (urb->status) { + case 0: + break; /* success */ + case -ECONNRESET: + case -ENOENT: + dev_dbg(&phy->udev->dev, + "The urb has been stopped (status %d)\n", + urb->status); + break; + case -ESHUTDOWN: + default: + nfc_err(&phy->udev->dev, + "Urb failure (status %d)\n", + urb->status); + } + + complete(&arg->done); +} + +static void pn533_ack_complete(struct urb *urb) { struct pn533_usb_phy *phy = urb->context; @@ -500,10 +539,10 @@ usb_fill_bulk_urb(phy->out_urb, phy->udev, usb_sndbulkpipe(phy->udev, out_endpoint), - NULL, 0, pn533_send_complete, phy); + NULL, 0, pn533_out_complete, phy); usb_fill_bulk_urb(phy->ack_urb, phy->udev, usb_sndbulkpipe(phy->udev, out_endpoint), - NULL, 0, pn533_send_complete, phy); + NULL, 0, pn533_ack_complete, phy); switch (id->driver_info) { case PN533_DEVICE_STD: --- linux-oracle-5.4.0.orig/drivers/nfc/pn544/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/pn544/i2c.c @@ -225,6 +225,7 @@ out: gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity); + usleep_range(10000, 15000); } static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode) --- linux-oracle-5.4.0.orig/drivers/nfc/pn544/pn544.c +++ linux-oracle-5.4.0/drivers/nfc/pn544/pn544.c @@ -693,7 +693,7 @@ target->nfcid1_len != 10) return -EOPNOTSUPP; - return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, + return nfc_hci_send_cmd(hdev, NFC_HCI_RF_READER_A_GATE, PN544_RF_READER_CMD_ACTIVATE_NEXT, target->nfcid1, target->nfcid1_len, NULL); } else if (target->supported_protocols & (NFC_PROTO_JEWEL_MASK | --- linux-oracle-5.4.0.orig/drivers/nfc/port100.c +++ linux-oracle-5.4.0/drivers/nfc/port100.c @@ -565,7 +565,7 @@ { struct port100_frame *frame = _frame; - frame->datalen = cpu_to_le16(le16_to_cpu(frame->datalen) + len); + le16_add_cpu(&frame->datalen, len); } static bool port100_rx_frame_is_valid(void *_frame) @@ -1003,11 +1003,11 @@ skb = port100_alloc_skb(dev, 0); if (!skb) - return -ENOMEM; + return 0; resp = port100_send_cmd_sync(dev, PORT100_CMD_GET_COMMAND_TYPE, skb); if (IS_ERR(resp)) - return PTR_ERR(resp); + return 0; if (resp->len < 8) mask = 0; @@ -1609,7 +1609,9 @@ nfc_digital_free_device(dev->nfc_digital_dev); error: + usb_kill_urb(dev->in_urb); usb_free_urb(dev->in_urb); + usb_kill_urb(dev->out_urb); usb_free_urb(dev->out_urb); usb_put_dev(dev->udev); --- linux-oracle-5.4.0.orig/drivers/nfc/s3fwrn5/core.c +++ linux-oracle-5.4.0/drivers/nfc/s3fwrn5/core.c @@ -97,11 +97,15 @@ } ret = s3fwrn5_write(info, skb); - if (ret < 0) + if (ret < 0) { kfree_skb(skb); + mutex_unlock(&info->mutex); + return ret; + } + consume_skb(skb); mutex_unlock(&info->mutex); - return ret; + return 0; } static int s3fwrn5_nci_post_setup(struct nci_dev *ndev) @@ -198,6 +202,7 @@ case S3FWRN5_MODE_FW: return s3fwrn5_fw_recv_frame(ndev, skb); default: + kfree_skb(skb); return -ENODEV; } } --- linux-oracle-5.4.0.orig/drivers/nfc/s3fwrn5/firmware.c +++ linux-oracle-5.4.0/drivers/nfc/s3fwrn5/firmware.c @@ -293,8 +293,10 @@ if (ret < 0) return ret; - if (fw->fw->size < S3FWRN5_FW_IMAGE_HEADER_SIZE) + if (fw->fw->size < S3FWRN5_FW_IMAGE_HEADER_SIZE) { + release_firmware(fw->fw); return -EINVAL; + } memcpy(fw->date, fw->fw->data + 0x00, 12); fw->date[12] = '\0'; --- linux-oracle-5.4.0.orig/drivers/nfc/s3fwrn5/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/s3fwrn5/i2c.c @@ -26,8 +26,8 @@ struct i2c_client *i2c_dev; struct nci_dev *ndev; - unsigned int gpio_en; - unsigned int gpio_fw_wake; + int gpio_en; + int gpio_fw_wake; struct mutex mutex; --- linux-oracle-5.4.0.orig/drivers/nfc/st-nci/ndlc.c +++ linux-oracle-5.4.0/drivers/nfc/st-nci/ndlc.c @@ -286,13 +286,15 @@ void ndlc_remove(struct llt_ndlc *ndlc) { - st_nci_remove(ndlc->ndev); - /* cancel timers */ del_timer_sync(&ndlc->t1_timer); del_timer_sync(&ndlc->t2_timer); ndlc->t2_active = false; ndlc->t1_active = false; + /* cancel work */ + cancel_work_sync(&ndlc->sm_work); + + st_nci_remove(ndlc->ndev); skb_queue_purge(&ndlc->rcv_q); skb_queue_purge(&ndlc->send_q); --- linux-oracle-5.4.0.orig/drivers/nfc/st-nci/se.c +++ linux-oracle-5.4.0/drivers/nfc/st-nci/se.c @@ -327,7 +327,7 @@ * AID 81 5 to 16 * PARAMETERS 82 0 to 255 */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 && + if (skb->len < NFC_MIN_AID_LENGTH + 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; @@ -341,8 +341,10 @@ /* Check next byte is PARAMETERS tag (82) */ if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) + NFC_EVT_TRANSACTION_PARAMS_TAG) { + devm_kfree(dev, transaction); return -EPROTO; + } transaction->params_len = skb->data[transaction->aid_len + 3]; memcpy(transaction->params, skb->data + @@ -663,6 +665,12 @@ ST_NCI_EVT_TRANSMIT_DATA, apdu, apdu_length); default: + /* Need to free cb_context here as at the moment we can't + * clearly indicate to the caller if the callback function + * would be called (and free it) or not. In both cases a + * negative value may be returned to the caller. + */ + kfree(cb_context); return -ENODEV; } } --- linux-oracle-5.4.0.orig/drivers/nfc/st21nfca/dep.c +++ linux-oracle-5.4.0/drivers/nfc/st21nfca/dep.c @@ -173,8 +173,10 @@ memcpy(atr_res->gbi, atr_req->gbi, gb_len); r = nfc_set_remote_general_bytes(hdev->ndev, atr_res->gbi, gb_len); - if (r < 0) + if (r < 0) { + kfree_skb(skb); return r; + } } info->dep_info.curr_nfc_dep_pni = 0; --- linux-oracle-5.4.0.orig/drivers/nfc/st21nfca/i2c.c +++ linux-oracle-5.4.0/drivers/nfc/st21nfca/i2c.c @@ -533,7 +533,8 @@ phy->gpiod_ena = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(phy->gpiod_ena)) { nfc_err(dev, "Unable to get ENABLE GPIO\n"); - return PTR_ERR(phy->gpiod_ena); + r = PTR_ERR(phy->gpiod_ena); + goto out_free; } phy->se_status.is_ese_present = @@ -544,7 +545,7 @@ r = st21nfca_hci_platform_init(phy); if (r < 0) { nfc_err(&client->dev, "Unable to reboot st21nfca\n"); - return r; + goto out_free; } r = devm_request_threaded_irq(&client->dev, client->irq, NULL, @@ -553,15 +554,23 @@ ST21NFCA_HCI_DRIVER_NAME, phy); if (r < 0) { nfc_err(&client->dev, "Unable to register IRQ handler\n"); - return r; + goto out_free; } - return st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, - ST21NFCA_FRAME_HEADROOM, - ST21NFCA_FRAME_TAILROOM, - ST21NFCA_HCI_LLC_MAX_PAYLOAD, - &phy->hdev, - &phy->se_status); + r = st21nfca_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME, + ST21NFCA_FRAME_HEADROOM, + ST21NFCA_FRAME_TAILROOM, + ST21NFCA_HCI_LLC_MAX_PAYLOAD, + &phy->hdev, + &phy->se_status); + if (r) + goto out_free; + + return 0; + +out_free: + kfree_skb(phy->pending_skb); + return r; } static int st21nfca_hci_i2c_remove(struct i2c_client *client) @@ -574,6 +583,8 @@ if (phy->powered) st21nfca_hci_i2c_disable(phy); + if (phy->pending_skb) + kfree_skb(phy->pending_skb); return 0; } --- linux-oracle-5.4.0.orig/drivers/nfc/st21nfca/se.c +++ linux-oracle-5.4.0/drivers/nfc/st21nfca/se.c @@ -236,12 +236,18 @@ ST21NFCA_EVT_TRANSMIT_DATA, apdu, apdu_length); default: + /* Need to free cb_context here as at the moment we can't + * clearly indicate to the caller if the callback function + * would be called (and free it) or not. In both cases a + * negative value may be returned to the caller. + */ + kfree(cb_context); return -ENODEV; } } EXPORT_SYMBOL(st21nfca_hci_se_io); -static void st21nfca_se_wt_timeout(struct timer_list *t) +static void st21nfca_se_wt_work(struct work_struct *work) { /* * No answer from the secure element @@ -254,8 +260,9 @@ */ /* hardware reset managed through VCC_UICC_OUT power supply */ u8 param = 0x01; - struct st21nfca_hci_info *info = from_timer(info, t, - se_info.bwi_timer); + struct st21nfca_hci_info *info = container_of(work, + struct st21nfca_hci_info, + se_info.timeout_work); pr_debug("\n"); @@ -273,6 +280,13 @@ info->se_info.cb(info->se_info.cb_context, NULL, 0, -ETIME); } +static void st21nfca_se_wt_timeout(struct timer_list *t) +{ + struct st21nfca_hci_info *info = from_timer(info, t, se_info.bwi_timer); + + schedule_work(&info->se_info.timeout_work); +} + static void st21nfca_se_activation_timeout(struct timer_list *t) { struct st21nfca_hci_info *info = from_timer(info, t, @@ -296,6 +310,8 @@ int r = 0; struct device *dev = &hdev->ndev->dev; struct nfc_evt_transaction *transaction; + u32 aid_len; + u8 params_len; pr_debug("connectivity gate event: %x\n", event); @@ -304,34 +320,48 @@ r = nfc_se_connectivity(hdev->ndev, host); break; case ST21NFCA_EVT_TRANSACTION: - /* - * According to specification etsi 102 622 + /* According to specification etsi 102 622 * 11.2.2.4 EVT_TRANSACTION Table 52 * Description Tag Length * AID 81 5 to 16 * PARAMETERS 82 0 to 255 + * + * The key differences are aid storage length is variably sized + * in the packet, but fixed in nfc_evt_transaction, and that the aid_len + * is u8 in the packet, but u32 in the structure, and the tags in + * the packet are not included in nfc_evt_transaction. + * + * size in bytes: 1 1 5-16 1 1 0-255 + * offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4 + * member name: aid_tag(M) aid_len aid params_tag(M) params_len params + * example: 0x81 5-16 X 0x82 0-255 X */ - if (skb->len < NFC_MIN_AID_LENGTH + 2 && - skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) + if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG) return -EPROTO; - transaction = (struct nfc_evt_transaction *)devm_kzalloc(dev, - skb->len - 2, GFP_KERNEL); + aid_len = skb->data[1]; + + if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid)) + return -EPROTO; + + params_len = skb->data[aid_len + 3]; + + /* Verify PARAMETERS tag is (82), and final check that there is enough + * space in the packet to read everything. + */ + if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) || + (skb->len < aid_len + 4 + params_len)) + return -EPROTO; + + transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL); if (!transaction) return -ENOMEM; - transaction->aid_len = skb->data[1]; - memcpy(transaction->aid, &skb->data[2], - transaction->aid_len); - - /* Check next byte is PARAMETERS tag (82) */ - if (skb->data[transaction->aid_len + 2] != - NFC_EVT_TRANSACTION_PARAMS_TAG) - return -EPROTO; + transaction->aid_len = aid_len; + transaction->params_len = params_len; - transaction->params_len = skb->data[transaction->aid_len + 3]; - memcpy(transaction->params, skb->data + - transaction->aid_len + 4, transaction->params_len); + memcpy(transaction->aid, &skb->data[2], aid_len); + memcpy(transaction->params, &skb->data[aid_len + 4], params_len); r = nfc_se_transaction(hdev->ndev, host, transaction); break; @@ -355,6 +385,7 @@ switch (event) { case ST21NFCA_EVT_TRANSMIT_DATA: del_timer_sync(&info->se_info.bwi_timer); + cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; r = nfc_hci_send_event(hdev, ST21NFCA_DEVICE_MGNT_GATE, ST21NFCA_EVT_SE_END_OF_APDU_TRANSFER, NULL, 0); @@ -384,6 +415,7 @@ struct st21nfca_hci_info *info = nfc_hci_get_clientdata(hdev); init_completion(&info->se_info.req_completion); + INIT_WORK(&info->se_info.timeout_work, st21nfca_se_wt_work); /* initialize timers */ timer_setup(&info->se_info.bwi_timer, st21nfca_se_wt_timeout, 0); info->se_info.bwi_active = false; @@ -411,6 +443,7 @@ if (info->se_info.se_active) del_timer_sync(&info->se_info.se_active_timer); + cancel_work_sync(&info->se_info.timeout_work); info->se_info.bwi_active = false; info->se_info.se_active = false; } --- linux-oracle-5.4.0.orig/drivers/nfc/st21nfca/st21nfca.h +++ linux-oracle-5.4.0/drivers/nfc/st21nfca/st21nfca.h @@ -141,6 +141,7 @@ se_io_cb_t cb; void *cb_context; + struct work_struct timeout_work; }; struct st21nfca_hci_info { --- linux-oracle-5.4.0.orig/drivers/nfc/st95hf/core.c +++ linux-oracle-5.4.0/drivers/nfc/st95hf/core.c @@ -966,7 +966,7 @@ rc = down_killable(&stcontext->exchange_lock); if (rc) { WARN(1, "Semaphore is not found up in st95hf_in_send_cmd\n"); - return rc; + goto free_skb_resp; } rc = st95hf_spi_send(&stcontext->spicontext, skb->data, --- linux-oracle-5.4.0.orig/drivers/nfc/trf7970a.c +++ linux-oracle-5.4.0/drivers/nfc/trf7970a.c @@ -424,7 +424,8 @@ enum trf7970a_state state; struct device *dev; struct spi_device *spi; - struct regulator *regulator; + struct regulator *vin_regulator; + struct regulator *vddio_regulator; struct nfc_digital_dev *ddev; u32 quirks; bool is_initiator; @@ -1883,7 +1884,7 @@ if (trf->state != TRF7970A_ST_PWR_OFF) return 0; - ret = regulator_enable(trf->regulator); + ret = regulator_enable(trf->vin_regulator); if (ret) { dev_err(trf->dev, "%s - Can't enable VIN: %d\n", __func__, ret); return ret; @@ -1926,7 +1927,7 @@ if (trf->en2_gpiod && !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) gpiod_set_value_cansleep(trf->en2_gpiod, 0); - ret = regulator_disable(trf->regulator); + ret = regulator_disable(trf->vin_regulator); if (ret) dev_err(trf->dev, "%s - Can't disable VIN: %d\n", __func__, ret); @@ -2065,37 +2066,37 @@ mutex_init(&trf->lock); INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler); - trf->regulator = devm_regulator_get(&spi->dev, "vin"); - if (IS_ERR(trf->regulator)) { - ret = PTR_ERR(trf->regulator); + trf->vin_regulator = devm_regulator_get(&spi->dev, "vin"); + if (IS_ERR(trf->vin_regulator)) { + ret = PTR_ERR(trf->vin_regulator); dev_err(trf->dev, "Can't get VIN regulator: %d\n", ret); goto err_destroy_lock; } - ret = regulator_enable(trf->regulator); + ret = regulator_enable(trf->vin_regulator); if (ret) { dev_err(trf->dev, "Can't enable VIN: %d\n", ret); goto err_destroy_lock; } - uvolts = regulator_get_voltage(trf->regulator); + uvolts = regulator_get_voltage(trf->vin_regulator); if (uvolts > 4000000) trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3; - trf->regulator = devm_regulator_get(&spi->dev, "vdd-io"); - if (IS_ERR(trf->regulator)) { - ret = PTR_ERR(trf->regulator); + trf->vddio_regulator = devm_regulator_get(&spi->dev, "vdd-io"); + if (IS_ERR(trf->vddio_regulator)) { + ret = PTR_ERR(trf->vddio_regulator); dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret); - goto err_destroy_lock; + goto err_disable_vin_regulator; } - ret = regulator_enable(trf->regulator); + ret = regulator_enable(trf->vddio_regulator); if (ret) { dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret); - goto err_destroy_lock; + goto err_disable_vin_regulator; } - if (regulator_get_voltage(trf->regulator) == 1800000) { + if (regulator_get_voltage(trf->vddio_regulator) == 1800000) { trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW; dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n"); } @@ -2108,7 +2109,7 @@ if (!trf->ddev) { dev_err(trf->dev, "Can't allocate NFC digital device\n"); ret = -ENOMEM; - goto err_disable_regulator; + goto err_disable_vddio_regulator; } nfc_digital_set_parent_dev(trf->ddev, trf->dev); @@ -2137,8 +2138,10 @@ trf7970a_shutdown(trf); err_free_ddev: nfc_digital_free_device(trf->ddev); -err_disable_regulator: - regulator_disable(trf->regulator); +err_disable_vddio_regulator: + regulator_disable(trf->vddio_regulator); +err_disable_vin_regulator: + regulator_disable(trf->vin_regulator); err_destroy_lock: mutex_destroy(&trf->lock); return ret; @@ -2157,7 +2160,8 @@ nfc_digital_unregister_device(trf->ddev); nfc_digital_free_device(trf->ddev); - regulator_disable(trf->regulator); + regulator_disable(trf->vddio_regulator); + regulator_disable(trf->vin_regulator); mutex_destroy(&trf->lock); --- linux-oracle-5.4.0.orig/drivers/ntb/core.c +++ linux-oracle-5.4.0/drivers/ntb/core.c @@ -214,10 +214,8 @@ case NTB_TOPO_B2B_DSD: return NTB_PORT_SEC_DSD; default: - break; + return 0; } - - return -EINVAL; } EXPORT_SYMBOL(ntb_default_port_number); @@ -240,10 +238,8 @@ case NTB_TOPO_B2B_DSD: return NTB_PORT_PRI_USD; default: - break; + return 0; } - - return -EINVAL; } EXPORT_SYMBOL(ntb_default_peer_port_number); @@ -315,4 +311,3 @@ bus_unregister(&ntb_bus); } module_exit(ntb_driver_exit); - --- linux-oracle-5.4.0.orig/drivers/ntb/hw/amd/ntb_hw_amd.c +++ linux-oracle-5.4.0/drivers/ntb/hw/amd/ntb_hw_amd.c @@ -1036,6 +1036,7 @@ err_dma_mask: pci_clear_master(pdev); + pci_release_regions(pdev); err_pci_regions: pci_disable_device(pdev); err_pci_enable: @@ -1152,12 +1153,17 @@ static int __init amd_ntb_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER); if (debugfs_initialized()) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); - return pci_register_driver(&amd_ntb_pci_driver); + ret = pci_register_driver(&amd_ntb_pci_driver); + if (ret) + debugfs_remove_recursive(debugfs_dir); + + return ret; } module_init(amd_ntb_pci_driver_init); --- linux-oracle-5.4.0.orig/drivers/ntb/hw/idt/ntb_hw_idt.c +++ linux-oracle-5.4.0/drivers/ntb/hw/idt/ntb_hw_idt.c @@ -2908,6 +2908,7 @@ static int __init idt_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER); /* Create the top DebugFS directory if the FS is initialized */ @@ -2915,7 +2916,11 @@ dbgfs_topdir = debugfs_create_dir(KBUILD_MODNAME, NULL); /* Register the NTB hardware driver to handle the PCI device */ - return pci_register_driver(&idt_pci_driver); + ret = pci_register_driver(&idt_pci_driver); + if (ret) + debugfs_remove_recursive(dbgfs_topdir); + + return ret; } module_init(idt_pci_driver_init); --- linux-oracle-5.4.0.orig/drivers/ntb/hw/intel/ntb_hw_gen1.c +++ linux-oracle-5.4.0/drivers/ntb/hw/intel/ntb_hw_gen1.c @@ -775,7 +775,7 @@ ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->ntb.pdev), debugfs_dir); - if (!ndev->debugfs_dir) + if (IS_ERR(ndev->debugfs_dir)) ndev->debugfs_info = NULL; else ndev->debugfs_info = @@ -2065,12 +2065,17 @@ static int __init intel_ntb_pci_driver_init(void) { + int ret; pr_info("%s %s\n", NTB_DESC, NTB_VER); if (debugfs_initialized()) debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); - return pci_register_driver(&intel_ntb_pci_driver); + ret = pci_register_driver(&intel_ntb_pci_driver); + if (ret) + debugfs_remove_recursive(debugfs_dir); + + return ret; } module_init(intel_ntb_pci_driver_init); --- linux-oracle-5.4.0.orig/drivers/ntb/hw/mscc/ntb_hw_switchtec.c +++ linux-oracle-5.4.0/drivers/ntb/hw/mscc/ntb_hw_switchtec.c @@ -1558,6 +1558,7 @@ switchtec_ntb_deinit_db_msg_irq(sndev); switchtec_ntb_deinit_shared_mw(sndev); switchtec_ntb_deinit_crosslink(sndev); + cancel_work_sync(&sndev->check_link_status_work); kfree(sndev); dev_info(dev, "ntb device unregistered\n"); } --- linux-oracle-5.4.0.orig/drivers/ntb/ntb_transport.c +++ linux-oracle-5.4.0/drivers/ntb/ntb_transport.c @@ -412,7 +412,7 @@ rc = device_register(dev); if (rc) { - kfree(client_dev); + put_device(dev); goto err; } @@ -911,7 +911,7 @@ return 0; } -static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) +static void ntb_qp_link_context_reset(struct ntb_transport_qp *qp) { qp->link_is_up = false; qp->active = false; @@ -934,6 +934,13 @@ qp->tx_async = 0; } +static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) +{ + ntb_qp_link_context_reset(qp); + if (qp->remote_rx_info) + qp->remote_rx_info->entry = qp->rx_max_entry - 1; +} + static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp) { struct ntb_transport_ctx *nt = qp->transport; @@ -1176,7 +1183,7 @@ qp->ndev = nt->ndev; qp->client_ready = false; qp->event_handler = NULL; - ntb_qp_link_down_reset(qp); + ntb_qp_link_context_reset(qp); if (mw_num < qp_count % mw_count) num_qps_mw = qp_count / mw_count + 1; @@ -2278,9 +2285,13 @@ struct ntb_queue_entry *entry; int rc; - if (!qp || !qp->link_is_up || !len) + if (!qp || !len) return -EINVAL; + /* If the qp link is down already, just ignore. */ + if (!qp->link_is_up) + return 0; + entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); if (!entry) { qp->tx_err_no_buf++; @@ -2420,7 +2431,7 @@ unsigned int head = qp->tx_index; unsigned int tail = qp->remote_rx_info->entry; - return tail > head ? tail - head : qp->tx_max_entry + tail - head; + return tail >= head ? tail - head : qp->tx_max_entry + tail - head; } EXPORT_SYMBOL_GPL(ntb_transport_tx_free_entry); --- linux-oracle-5.4.0.orig/drivers/ntb/test/ntb_msi_test.c +++ linux-oracle-5.4.0/drivers/ntb/test/ntb_msi_test.c @@ -372,8 +372,10 @@ if (ret) goto remove_dbgfs; - if (!nm->isr_ctx) + if (!nm->isr_ctx) { + ret = -ENOMEM; goto remove_dbgfs; + } ntb_link_enable(ntb, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); --- linux-oracle-5.4.0.orig/drivers/ntb/test/ntb_perf.c +++ linux-oracle-5.4.0/drivers/ntb/test/ntb_perf.c @@ -158,6 +158,8 @@ /* NTB connection setup service */ struct work_struct service; unsigned long sts; + + struct completion init_comp; }; #define to_peer_service(__work) \ container_of(__work, struct perf_peer, service) @@ -546,6 +548,7 @@ /* Initialization is finally done */ set_bit(PERF_STS_DONE, &peer->sts); + complete_all(&peer->init_comp); return 0; } @@ -556,7 +559,7 @@ return; (void)ntb_mw_clear_trans(peer->perf->ntb, peer->pidx, peer->gidx); - dma_free_coherent(&peer->perf->ntb->dev, peer->inbuf_size, + dma_free_coherent(&peer->perf->ntb->pdev->dev, peer->inbuf_size, peer->inbuf, peer->inbuf_xlat); peer->inbuf = NULL; } @@ -585,14 +588,16 @@ perf_free_inbuf(peer); - peer->inbuf = dma_alloc_coherent(&perf->ntb->dev, peer->inbuf_size, - &peer->inbuf_xlat, GFP_KERNEL); + peer->inbuf = dma_alloc_coherent(&perf->ntb->pdev->dev, + peer->inbuf_size, &peer->inbuf_xlat, + GFP_KERNEL); if (!peer->inbuf) { dev_err(&perf->ntb->dev, "Failed to alloc inbuf of %pa\n", &peer->inbuf_size); return -ENOMEM; } if (!IS_ALIGNED(peer->inbuf_xlat, xlat_align)) { + ret = -EINVAL; dev_err(&perf->ntb->dev, "Unaligned inbuf allocated\n"); goto err_free_inbuf; } @@ -636,6 +641,7 @@ perf_setup_outbuf(peer); if (test_and_clear_bit(PERF_CMD_CLEAR, &peer->sts)) { + init_completion(&peer->init_comp); clear_bit(PERF_STS_DONE, &peer->sts); if (test_bit(0, &peer->perf->busy_flag) && peer == peer->perf->test_peer) { @@ -652,7 +658,7 @@ { u64 mask; - if (ntb_peer_mw_count(perf->ntb) < perf->pcnt + 1) { + if (ntb_peer_mw_count(perf->ntb) < perf->pcnt) { dev_err(&perf->ntb->dev, "Not enough memory windows\n"); return -EINVAL; } @@ -1051,8 +1057,9 @@ struct perf_thread *pthr; int tidx, ret; - if (!test_bit(PERF_STS_DONE, &peer->sts)) - return -ENOLINK; + ret = wait_for_completion_interruptible(&peer->init_comp); + if (ret < 0) + return ret; if (test_and_set_bit_lock(0, &perf->busy_flag)) return -EBUSY; @@ -1418,10 +1425,21 @@ peer->gidx = pidx; } INIT_WORK(&peer->service, perf_service_work); + init_completion(&peer->init_comp); } if (perf->gidx == -1) perf->gidx = pidx; + /* + * Hardware with only two ports may not have unique port + * numbers. In this case, the gidxs should all be zero. + */ + if (perf->pcnt == 1 && ntb_port_number(perf->ntb) == 0 && + ntb_peer_port_number(perf->ntb, 0) == 0) { + perf->gidx = 0; + perf->peers[0].gidx = 0; + } + for (pidx = 0; pidx < perf->pcnt; pidx++) { ret = perf_setup_peer_mw(&perf->peers[pidx]); if (ret) @@ -1517,4 +1535,3 @@ destroy_workqueue(perf_wq); } module_exit(perf_exit); - --- linux-oracle-5.4.0.orig/drivers/ntb/test/ntb_pingpong.c +++ linux-oracle-5.4.0/drivers/ntb/test/ntb_pingpong.c @@ -121,15 +121,14 @@ link = ntb_link_is_up(pp->ntb, NULL, NULL); /* Find next available peer */ - if (link & pp->nmask) { + if (link & pp->nmask) pidx = __ffs64(link & pp->nmask); - out_db = BIT_ULL(pidx + 1); - } else if (link & pp->pmask) { + else if (link & pp->pmask) pidx = __ffs64(link & pp->pmask); - out_db = BIT_ULL(pidx); - } else { + else return -ENODEV; - } + + out_db = BIT_ULL(ntb_peer_port_number(pp->ntb, pidx)); spin_lock(&pp->lock); pp->out_pidx = pidx; @@ -303,7 +302,7 @@ break; } - pp->in_db = BIT_ULL(pidx); + pp->in_db = BIT_ULL(lport); pp->pmask = GENMASK_ULL(pidx, 0) >> 1; pp->nmask = GENMASK_ULL(pcnt - 1, pidx); @@ -435,4 +434,3 @@ debugfs_remove_recursive(pp_dbgfs_topdir); } module_exit(pp_exit); - --- linux-oracle-5.4.0.orig/drivers/ntb/test/ntb_tool.c +++ linux-oracle-5.4.0/drivers/ntb/test/ntb_tool.c @@ -367,14 +367,16 @@ u64 bits; int n; + if (*offp) + return 0; + buf = kmalloc(size + 1, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = simple_write_to_buffer(buf, size, offp, ubuf, size); - if (ret < 0) { + if (copy_from_user(buf, ubuf, size)) { kfree(buf); - return ret; + return -EFAULT; } buf[size] = 0; @@ -504,7 +506,7 @@ buf[1] = '\n'; buf[2] = '\0'; - return simple_read_from_buffer(ubuf, size, offp, buf, 3); + return simple_read_from_buffer(ubuf, size, offp, buf, 2); } static TOOL_FOPS_RDWR(tool_peer_link_fops, @@ -590,7 +592,7 @@ inmw->size = min_t(resource_size_t, req_size, size); inmw->size = round_up(inmw->size, addr_align); inmw->size = round_up(inmw->size, size_align); - inmw->mm_base = dma_alloc_coherent(&tc->ntb->dev, inmw->size, + inmw->mm_base = dma_alloc_coherent(&tc->ntb->pdev->dev, inmw->size, &inmw->dma_base, GFP_KERNEL); if (!inmw->mm_base) return -ENOMEM; @@ -612,7 +614,7 @@ return 0; err_free_dma: - dma_free_coherent(&tc->ntb->dev, inmw->size, inmw->mm_base, + dma_free_coherent(&tc->ntb->pdev->dev, inmw->size, inmw->mm_base, inmw->dma_base); inmw->mm_base = NULL; inmw->dma_base = 0; @@ -629,7 +631,7 @@ if (inmw->mm_base != NULL) { ntb_mw_clear_trans(tc->ntb, pidx, widx); - dma_free_coherent(&tc->ntb->dev, inmw->size, + dma_free_coherent(&tc->ntb->pdev->dev, inmw->size, inmw->mm_base, inmw->dma_base); } @@ -996,6 +998,8 @@ tc->peers[pidx].outmws = devm_kcalloc(&tc->ntb->dev, tc->peers[pidx].outmw_cnt, sizeof(*tc->peers[pidx].outmws), GFP_KERNEL); + if (tc->peers[pidx].outmws == NULL) + return -ENOMEM; for (widx = 0; widx < tc->peers[pidx].outmw_cnt; widx++) { tc->peers[pidx].outmws[widx].pidx = pidx; @@ -1690,4 +1694,3 @@ debugfs_remove_recursive(tool_dbgfs_topdir); } module_exit(tool_exit); - --- linux-oracle-5.4.0.orig/drivers/nvdimm/btt.c +++ linux-oracle-5.4.0/drivers/nvdimm/btt.c @@ -1261,11 +1261,11 @@ ret = btt_data_read(arena, page, off, postmap, cur_len); if (ret) { - int rc; - /* Media error - set the e_flag */ - rc = btt_map_write(arena, premap, postmap, 0, 1, - NVDIMM_IO_ATOMIC); + if (btt_map_write(arena, premap, postmap, 0, 1, NVDIMM_IO_ATOMIC)) + dev_warn_ratelimited(to_dev(arena), + "Error persistently tracking bad blocks at %#x\n", + premap); goto out_rtt; } --- linux-oracle-5.4.0.orig/drivers/nvdimm/bus.c +++ linux-oracle-5.4.0/drivers/nvdimm/bus.c @@ -187,8 +187,8 @@ ndr_end = nd_region->ndr_start + nd_region->ndr_size - 1; /* make sure we are in the region */ - if (ctx->phys < nd_region->ndr_start - || (ctx->phys + ctx->cleared) > ndr_end) + if (ctx->phys < nd_region->ndr_start || + (ctx->phys + ctx->cleared - 1) > ndr_end) return 0; sector = (ctx->phys - nd_region->ndr_start) / 512; @@ -1010,8 +1010,10 @@ return -EFAULT; } - if (!desc || (desc->out_num + desc->in_num == 0) || - !test_bit(cmd, &cmd_mask)) + if (!desc || + (desc->out_num + desc->in_num == 0) || + cmd > ND_CMD_CALL || + !test_bit(cmd, &cmd_mask)) return -ENOTTY; /* fail write commands (when read-only) */ --- linux-oracle-5.4.0.orig/drivers/nvdimm/dax_devs.c +++ linux-oracle-5.4.0/drivers/nvdimm/dax_devs.c @@ -113,12 +113,12 @@ nvdimm_bus_lock(&ndns->dev); nd_dax = nd_dax_alloc(nd_region); - nd_pfn = &nd_dax->nd_pfn; - dax_dev = nd_pfn_devinit(nd_pfn, ndns); + dax_dev = nd_dax_devinit(nd_dax, ndns); nvdimm_bus_unlock(&ndns->dev); if (!dax_dev) return -ENOMEM; pfn_sb = devm_kmalloc(dev, sizeof(*pfn_sb), GFP_KERNEL); + nd_pfn = &nd_dax->nd_pfn; nd_pfn->pfn_sb = pfn_sb; rc = nd_pfn_validate(nd_pfn, DAX_SIG); dev_dbg(dev, "dax: %s\n", rc == 0 ? dev_name(dax_dev) : ""); --- linux-oracle-5.4.0.orig/drivers/nvdimm/dimm_devs.c +++ linux-oracle-5.4.0/drivers/nvdimm/dimm_devs.c @@ -344,16 +344,16 @@ } static DEVICE_ATTR_RO(state); -static ssize_t available_slots_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t __available_slots_show(struct nvdimm_drvdata *ndd, char *buf) { - struct nvdimm_drvdata *ndd = dev_get_drvdata(dev); + struct device *dev; ssize_t rc; u32 nfree; if (!ndd) return -ENXIO; + dev = ndd->dev; nvdimm_bus_lock(dev); nfree = nd_label_nfree(ndd); if (nfree - 1 > nfree) { @@ -365,6 +365,18 @@ nvdimm_bus_unlock(dev); return rc; } + +static ssize_t available_slots_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t rc; + + nd_device_lock(dev); + rc = __available_slots_show(dev_get_drvdata(dev), buf); + nd_device_unlock(dev); + + return rc; +} static DEVICE_ATTR_RO(available_slots); __weak ssize_t security_show(struct device *dev, --- linux-oracle-5.4.0.orig/drivers/nvdimm/label.c +++ linux-oracle-5.4.0/drivers/nvdimm/label.c @@ -980,6 +980,15 @@ } } + /* release slots associated with any invalidated UUIDs */ + mutex_lock(&nd_mapping->lock); + list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) + if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)) { + reap_victim(nd_mapping, label_ent); + list_move(&label_ent->list, &list); + } + mutex_unlock(&nd_mapping->lock); + /* * Find the resource associated with the first label in the set * per the v1.2 namespace specification. @@ -999,8 +1008,10 @@ if (is_old_resource(res, old_res_list, old_num_resources)) continue; /* carry-over */ slot = nd_label_alloc_slot(ndd); - if (slot == UINT_MAX) + if (slot == UINT_MAX) { + rc = -ENXIO; goto abort; + } dev_dbg(ndd->dev, "allocated: %d\n", slot); nd_label = to_label(ndd, slot); --- linux-oracle-5.4.0.orig/drivers/nvdimm/namespace_devs.c +++ linux-oracle-5.4.0/drivers/nvdimm/namespace_devs.c @@ -2486,7 +2486,7 @@ static int init_active_labels(struct nd_region *nd_region) { - int i; + int i, rc = 0; for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; @@ -2505,13 +2505,14 @@ else if (test_bit(NDD_ALIASING, &nvdimm->flags)) /* fail, labels needed to disambiguate dpa */; else - return 0; + continue; dev_err(&nd_region->dev, "%s: is %s, failing probe\n", dev_name(&nd_mapping->nvdimm->dev), test_bit(NDD_LOCKED, &nvdimm->flags) ? "locked" : "disabled"); - return -ENXIO; + rc = -ENXIO; + goto out; } nd_mapping->ndd = ndd; atomic_inc(&nvdimm->busy); @@ -2545,13 +2546,17 @@ break; } - if (i < nd_region->ndr_mappings) { + if (i < nd_region->ndr_mappings) + rc = -ENOMEM; + +out: + if (rc) { deactivate_labels(nd_region); - return -ENOMEM; + return rc; } return devm_add_action_or_reset(&nd_region->dev, deactivate_labels, - nd_region); + nd_region); } int nd_region_register_namespaces(struct nd_region *nd_region, int *err) --- linux-oracle-5.4.0.orig/drivers/nvdimm/nd.h +++ linux-oracle-5.4.0/drivers/nvdimm/nd.h @@ -326,6 +326,13 @@ int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns); bool is_nd_dax(struct device *dev); struct device *nd_dax_create(struct nd_region *nd_region); +static inline struct device *nd_dax_devinit(struct nd_dax *nd_dax, + struct nd_namespace_common *ndns) +{ + if (!nd_dax) + return NULL; + return nd_pfn_devinit(&nd_dax->nd_pfn, ndns); +} #else static inline int nd_dax_probe(struct device *dev, struct nd_namespace_common *ndns) --- linux-oracle-5.4.0.orig/drivers/nvdimm/nd_virtio.c +++ linux-oracle-5.4.0/drivers/nvdimm/nd_virtio.c @@ -44,6 +44,15 @@ unsigned long flags; int err, err1; + /* + * Don't bother to submit the request to the device if the device is + * not activated. + */ + if (vdev->config->get_status(vdev) & VIRTIO_CONFIG_S_NEEDS_RESET) { + dev_info(&vdev->dev, "virtio pmem device needs a reset\n"); + return -EIO; + } + might_sleep(); req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); if (!req_data) --- linux-oracle-5.4.0.orig/drivers/nvdimm/of_pmem.c +++ linux-oracle-5.4.0/drivers/nvdimm/of_pmem.c @@ -42,7 +42,13 @@ return -ENOMEM; priv->bus_desc.attr_groups = bus_attr_groups; - priv->bus_desc.provider_name = kstrdup(pdev->name, GFP_KERNEL); + priv->bus_desc.provider_name = devm_kstrdup(&pdev->dev, pdev->name, + GFP_KERNEL); + if (!priv->bus_desc.provider_name) { + kfree(priv); + return -ENOMEM; + } + priv->bus_desc.module = THIS_MODULE; priv->bus_desc.of_node = np; --- linux-oracle-5.4.0.orig/drivers/nvdimm/pmem.c +++ linux-oracle-5.4.0/drivers/nvdimm/pmem.c @@ -423,11 +423,11 @@ pmem->pfn_flags |= PFN_MAP; memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res)); } else { + addr = devm_memremap(dev, pmem->phys_addr, + pmem->size, ARCH_MEMREMAP_PMEM); if (devm_add_action_or_reset(dev, pmem_release_queue, &pmem->pgmap)) return -ENOMEM; - addr = devm_memremap(dev, pmem->phys_addr, - pmem->size, ARCH_MEMREMAP_PMEM); memcpy(&bb_res, &nsio->res, sizeof(bb_res)); } --- linux-oracle-5.4.0.orig/drivers/nvdimm/region_devs.c +++ linux-oracle-5.4.0/drivers/nvdimm/region_devs.c @@ -898,7 +898,8 @@ { unsigned int cpu, lane; - cpu = get_cpu(); + migrate_disable(); + cpu = smp_processor_id(); if (nd_region->num_lanes < nr_cpu_ids) { struct nd_percpu_lane *ndl_lock, *ndl_count; @@ -917,16 +918,15 @@ void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane) { if (nd_region->num_lanes < nr_cpu_ids) { - unsigned int cpu = get_cpu(); + unsigned int cpu = smp_processor_id(); struct nd_percpu_lane *ndl_lock, *ndl_count; ndl_count = per_cpu_ptr(nd_region->lane, cpu); ndl_lock = per_cpu_ptr(nd_region->lane, lane); if (--ndl_count->count == 0) spin_unlock(&ndl_lock->lock); - put_cpu(); } - put_cpu(); + migrate_enable(); } EXPORT_SYMBOL(nd_region_release_lane); @@ -1142,6 +1142,11 @@ || !IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API)) return -ENXIO; + /* Test if an explicit flush function is defined */ + if (test_bit(ND_REGION_ASYNC, &nd_region->flags) && nd_region->flush) + return 1; + + /* Test if any flush hints for the region are available */ for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; struct nvdimm *nvdimm = nd_mapping->nvdimm; @@ -1152,8 +1157,8 @@ } /* - * The platform defines dimm devices without hints, assume - * platform persistence mechanism like ADR + * The platform defines dimm devices without hints nor explicit flush, + * assume platform persistence mechanism like ADR */ return 0; } --- linux-oracle-5.4.0.orig/drivers/nvdimm/security.c +++ linux-oracle-5.4.0/drivers/nvdimm/security.c @@ -379,11 +379,6 @@ || !nvdimm->sec.flags) return -EOPNOTSUPP; - if (dev->driver == NULL) { - dev_dbg(dev, "Unable to overwrite while DIMM active.\n"); - return -EINVAL; - } - rc = check_security_state(nvdimm); if (rc) return rc; @@ -450,14 +445,19 @@ else dev_dbg(&nvdimm->dev, "overwrite completed\n"); - if (nvdimm->sec.overwrite_state) - sysfs_notify_dirent(nvdimm->sec.overwrite_state); + /* + * Mark the overwrite work done and update dimm security flags, + * then send a sysfs event notification to wake up userspace + * poll threads to picked up the changed state. + */ nvdimm->sec.overwrite_tmo = 0; clear_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags); clear_bit(NDD_WORK_PENDING, &nvdimm->flags); - put_device(&nvdimm->dev); nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_USER); - nvdimm->sec.flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); + nvdimm->sec.ext_flags = nvdimm_security_flags(nvdimm, NVDIMM_MASTER); + if (nvdimm->sec.overwrite_state) + sysfs_notify_dirent(nvdimm->sec.overwrite_state); + put_device(&nvdimm->dev); } void nvdimm_security_overwrite_query(struct work_struct *work) --- linux-oracle-5.4.0.orig/drivers/nvme/host/Kconfig +++ linux-oracle-5.4.0/drivers/nvme/host/Kconfig @@ -62,8 +62,10 @@ config NVME_TCP tristate "NVM Express over Fabrics TCP host driver" depends on INET - depends on BLK_DEV_NVME + depends on BLOCK + select NVME_CORE select NVME_FABRICS + select CRYPTO select CRYPTO_CRC32C help This provides support for the NVMe over Fabrics protocol using --- linux-oracle-5.4.0.orig/drivers/nvme/host/core.c +++ linux-oracle-5.4.0/drivers/nvme/host/core.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -66,8 +67,8 @@ * nvme_reset_wq - hosts nvme reset works * nvme_delete_wq - hosts nvme delete works * - * nvme_wq will host works such are scan, aen handling, fw activation, - * keep-alive error recovery, periodic reconnects etc. nvme_reset_wq + * nvme_wq will host works such as scan, aen handling, fw activation, + * keep-alive, periodic reconnects etc. nvme_reset_wq * runs reset works which also flush works hosted on nvme_wq for * serialization purposes. nvme_delete_wq host controller deletion * works which flush reset works for serialization. @@ -287,11 +288,8 @@ nvme_req(req)->ctrl->comp_seen = true; if (unlikely(status != BLK_STS_OK && nvme_req_needs_retry(req))) { - if ((req->cmd_flags & REQ_NVME_MPATH) && - blk_path_error(status)) { - nvme_failover_req(req); + if ((req->cmd_flags & REQ_NVME_MPATH) && nvme_failover_req(req)) return; - } if (!blk_queue_dying(req->q)) { nvme_retry_req(req); @@ -313,12 +311,33 @@ if (blk_mq_request_completed(req)) return true; - nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR; + nvme_req(req)->status = NVME_SC_HOST_ABORTED_CMD; + nvme_req(req)->flags |= NVME_REQ_CANCELLED; blk_mq_complete_request(req); return true; } EXPORT_SYMBOL_GPL(nvme_cancel_request); +void nvme_cancel_tagset(struct nvme_ctrl *ctrl) +{ + if (ctrl->tagset) { + blk_mq_tagset_busy_iter(ctrl->tagset, + nvme_cancel_request, ctrl); + blk_mq_tagset_wait_completed_request(ctrl->tagset); + } +} +EXPORT_SYMBOL_GPL(nvme_cancel_tagset); + +void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl) +{ + if (ctrl->admin_tagset) { + blk_mq_tagset_busy_iter(ctrl->admin_tagset, + nvme_cancel_request, ctrl); + blk_mq_tagset_wait_completed_request(ctrl->admin_tagset); + } +} +EXPORT_SYMBOL_GPL(nvme_cancel_admin_tagset); + bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state) { @@ -437,7 +456,6 @@ nvme_mpath_remove_disk(head); ida_simple_remove(&head->subsys->ns_ida, head->instance); - list_del_init(&head->entry); cleanup_srcu_struct(&head->srcu); nvme_put_subsystem(head->subsys); kfree(head); @@ -611,8 +629,14 @@ struct nvme_dsm_range *range; struct bio *bio; - range = kmalloc_array(segments, sizeof(*range), - GFP_ATOMIC | __GFP_NOWARN); + /* + * Some devices do not consider the DSM 'Number of Ranges' field when + * determining how much data to DMA. Always allocate memory for maximum + * number of segments to prevent device reading beyond end of buffer. + */ + static const size_t alloc_size = sizeof(*range) * NVME_DSM_MAX_RANGES; + + range = kzalloc(alloc_size, GFP_ATOMIC | __GFP_NOWARN); if (!range) { /* * If we fail allocation our range, fallback to the controller @@ -626,7 +650,7 @@ } __rq_for_each_bio(bio, req) { - u64 slba = nvme_block_nr(ns, bio->bi_iter.bi_sector); + u64 slba = nvme_sect_to_lba(ns, bio->bi_iter.bi_sector); u32 nlb = bio->bi_iter.bi_size >> ns->lba_shift; if (n < segments) { @@ -652,7 +676,7 @@ req->special_vec.bv_page = virt_to_page(range); req->special_vec.bv_offset = offset_in_page(range); - req->special_vec.bv_len = sizeof(*range) * segments; + req->special_vec.bv_len = alloc_size; req->rq_flags |= RQF_SPECIAL_PAYLOAD; return BLK_STS_OK; @@ -667,10 +691,13 @@ cmnd->write_zeroes.opcode = nvme_cmd_write_zeroes; cmnd->write_zeroes.nsid = cpu_to_le32(ns->head->ns_id); cmnd->write_zeroes.slba = - cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req))); + cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); cmnd->write_zeroes.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); - cmnd->write_zeroes.control = 0; + if (nvme_ns_has_pi(ns)) + cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT); + else + cmnd->write_zeroes.control = 0; return BLK_STS_OK; } @@ -691,7 +718,7 @@ cmnd->rw.opcode = (rq_data_dir(req) ? nvme_cmd_write : nvme_cmd_read); cmnd->rw.nsid = cpu_to_le32(ns->head->ns_id); - cmnd->rw.slba = cpu_to_le64(nvme_block_nr(ns, blk_rq_pos(req))); + cmnd->rw.slba = cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); cmnd->rw.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); if (req_op(req) == REQ_OP_WRITE && ctrl->nr_streams) @@ -738,6 +765,7 @@ clear_bit_unlock(0, &ns->ctrl->discard_page_busy); else kfree(page_address(page) + req->special_vec.bv_offset); + req->rq_flags &= ~RQF_SPECIAL_PAYLOAD; } } EXPORT_SYMBOL_GPL(nvme_cleanup_cmd); @@ -894,11 +922,16 @@ bool write = nvme_is_write(cmd); struct nvme_ns *ns = q->queuedata; struct gendisk *disk = ns ? ns->disk : NULL; + bool supports_metadata = disk && blk_get_integrity(disk); + bool has_metadata = meta_buffer && meta_len; struct request *req; struct bio *bio = NULL; void *meta = NULL; int ret; + if (has_metadata && !supports_metadata) + return -EINVAL; + req = nvme_alloc_request(q, cmd, 0, NVME_QID_ANY); if (IS_ERR(req)) return PTR_ERR(req); @@ -913,7 +946,7 @@ goto out; bio = req->bio; bio->bi_disk = disk; - if (disk && meta_buffer && meta_len) { + if (has_metadata) { meta = nvme_add_user_metadata(bio, meta_buffer, meta_len, meta_seed, write); if (IS_ERR(meta)) { @@ -966,7 +999,7 @@ startka = true; spin_unlock_irqrestore(&ctrl->lock, flags); if (startka) - schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); + queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); } static int nvme_keep_alive(struct nvme_ctrl *ctrl) @@ -996,7 +1029,7 @@ dev_dbg(ctrl->device, "reschedule traffic based keep-alive timer\n"); ctrl->comp_seen = false; - schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); + queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); return; } @@ -1013,7 +1046,7 @@ if (unlikely(ctrl->kato == 0)) return; - schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); + queue_delayed_work(nvme_wq, &ctrl->ka_work, ctrl->kato * HZ); } void nvme_stop_keep_alive(struct nvme_ctrl *ctrl) @@ -1025,6 +1058,19 @@ } EXPORT_SYMBOL_GPL(nvme_stop_keep_alive); +/* + * In NVMe 1.0 the CNS field was just a binary controller or namespace + * flag, thus sending any new CNS opcodes has a big chance of not working. + * Qemu unfortunately had that bug after reporting a 1.1 version compliance + * (but not for any later version). + */ +static bool nvme_ctrl_limited_cns(struct nvme_ctrl *ctrl) +{ + if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS) + return ctrl->vs < NVME_VS(1, 2, 0); + return ctrl->vs < NVME_VS(1, 1, 0); +} + static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) { struct nvme_command c = { }; @@ -1040,8 +1086,10 @@ error = nvme_submit_sync_cmd(dev->admin_q, &c, *id, sizeof(struct nvme_id_ctrl)); - if (error) + if (error) { kfree(*id); + *id = NULL; + } return error; } @@ -1054,6 +1102,9 @@ int pos; int len; + if (ctrl->quirks & NVME_QUIRK_NO_NS_DESC_LIST) + return 0; + c.identify.opcode = nvme_admin_identify; c.identify.nsid = cpu_to_le32(nsid); c.identify.cns = NVME_ID_CNS_NS_DESC_LIST; @@ -1064,8 +1115,11 @@ status = nvme_submit_sync_cmd(ctrl->admin_q, &c, data, NVME_IDENTIFY_DATA_SIZE); - if (status) + if (status) { + dev_warn(ctrl->device, + "Identify Descriptors failed (%d)\n", status); goto free_data; + } for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) { struct nvme_ns_id_desc *cur = data + pos; @@ -1147,6 +1201,7 @@ if (error) { dev_warn(ctrl->device, "Identify namespace failed (%d)\n", error); kfree(*id); + *id = NULL; } return error; @@ -1155,8 +1210,8 @@ static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid, unsigned int dword11, void *buffer, size_t buflen, u32 *result) { + union nvme_result res = { 0 }; struct nvme_command c; - union nvme_result res; int ret; memset(&c, 0, sizeof(c)); @@ -1197,7 +1252,13 @@ status = nvme_set_features(ctrl, NVME_FEAT_NUM_QUEUES, q_count, NULL, 0, &result); - if (status < 0) + + /* + * It's either a kernel error or the host observed a connection + * lost. In either case it's not possible communicate with the + * controller and thus enter the error code path. + */ + if (status < 0 || status == NVME_SC_HOST_PATH_ERROR) return status; /* @@ -1238,6 +1299,18 @@ queue_work(nvme_wq, &ctrl->async_event_work); } +/* + * Convert integer values from ioctl structures to user pointers, silently + * ignoring the upper bits in the compat case to match behaviour of 32-bit + * kernels. + */ +static void __user *nvme_to_user_ptr(uintptr_t ptrval) +{ + if (in_compat_syscall()) + ptrval = (compat_uptr_t)ptrval; + return (void __user *)ptrval; +} + static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio) { struct nvme_user_io io; @@ -1260,8 +1333,21 @@ } length = (io.nblocks + 1) << ns->lba_shift; - meta_len = (io.nblocks + 1) * ns->ms; - metadata = (void __user *)(uintptr_t)io.metadata; + + if ((io.control & NVME_RW_PRINFO_PRACT) && + ns->ms == sizeof(struct t10_pi_tuple)) { + /* + * Protection information is stripped/inserted by the + * controller. + */ + if (nvme_to_user_ptr(io.metadata)) + return -EINVAL; + meta_len = 0; + metadata = NULL; + } else { + meta_len = (io.nblocks + 1) * ns->ms; + metadata = nvme_to_user_ptr(io.metadata); + } if (ns->ext) { length += meta_len; @@ -1284,7 +1370,7 @@ c.rw.appmask = cpu_to_le16(io.appmask); return nvme_submit_user_cmd(ns->queue, &c, - (void __user *)(uintptr_t)io.addr, length, + nvme_to_user_ptr(io.addr), length, metadata, meta_len, lower_32_bits(io.slba), NULL, 0); } @@ -1404,9 +1490,9 @@ effects = nvme_passthru_start(ctrl, ns, cmd.opcode); status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, - (void __user *)(uintptr_t)cmd.addr, cmd.data_len, - (void __user *)(uintptr_t)cmd.metadata, - cmd.metadata_len, 0, &result, timeout); + nvme_to_user_ptr(cmd.addr), cmd.data_len, + nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, + 0, &result, timeout); nvme_passthru_end(ctrl, effects); if (status >= 0) { @@ -1451,8 +1537,8 @@ effects = nvme_passthru_start(ctrl, ns, cmd.opcode); status = nvme_submit_user_cmd(ns ? ns->queue : ctrl->admin_q, &c, - (void __user *)(uintptr_t)cmd.addr, cmd.data_len, - (void __user *)(uintptr_t)cmd.metadata, cmd.metadata_len, + nvme_to_user_ptr(cmd.addr), cmd.data_len, + nvme_to_user_ptr(cmd.metadata), cmd.metadata_len, 0, &cmd.result, timeout); nvme_passthru_end(ctrl, effects); @@ -1645,12 +1731,6 @@ } #endif /* CONFIG_BLK_DEV_INTEGRITY */ -static void nvme_set_chunk_size(struct nvme_ns *ns) -{ - u32 chunk_size = (((u32)ns->noiob) << (ns->lba_shift - 9)); - blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(chunk_size)); -} - static void nvme_config_discard(struct gendisk *disk, struct nvme_ns *ns) { struct nvme_ctrl *ctrl = ns->ctrl; @@ -1682,53 +1762,32 @@ blk_queue_max_write_zeroes_sectors(queue, UINT_MAX); } -static void nvme_config_write_zeroes(struct gendisk *disk, struct nvme_ns *ns) +/* + * Even though NVMe spec explicitly states that MDTS is not applicable to the + * write-zeroes, we are cautious and limit the size to the controllers + * max_hw_sectors value, which is based on the MDTS field and possibly other + * limiting factors. + */ +static void nvme_config_write_zeroes(struct request_queue *q, + struct nvme_ctrl *ctrl) { - u32 max_sectors; - unsigned short bs = 1 << ns->lba_shift; - - if (!(ns->ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) || - (ns->ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) - return; - /* - * Even though NVMe spec explicitly states that MDTS is not - * applicable to the write-zeroes:- "The restriction does not apply to - * commands that do not transfer data between the host and the - * controller (e.g., Write Uncorrectable ro Write Zeroes command).". - * In order to be more cautious use controller's max_hw_sectors value - * to configure the maximum sectors for the write-zeroes which is - * configured based on the controller's MDTS field in the - * nvme_init_identify() if available. - */ - if (ns->ctrl->max_hw_sectors == UINT_MAX) - max_sectors = ((u32)(USHRT_MAX + 1) * bs) >> 9; - else - max_sectors = ((u32)(ns->ctrl->max_hw_sectors + 1) * bs) >> 9; - - blk_queue_max_write_zeroes_sectors(disk->queue, max_sectors); + if ((ctrl->oncs & NVME_CTRL_ONCS_WRITE_ZEROES) && + !(ctrl->quirks & NVME_QUIRK_DISABLE_WRITE_ZEROES)) + blk_queue_max_write_zeroes_sectors(q, ctrl->max_hw_sectors); } static int nvme_report_ns_ids(struct nvme_ctrl *ctrl, unsigned int nsid, struct nvme_id_ns *id, struct nvme_ns_ids *ids) { - int ret = 0; - memset(ids, 0, sizeof(*ids)); if (ctrl->vs >= NVME_VS(1, 1, 0)) memcpy(ids->eui64, id->eui64, sizeof(id->eui64)); if (ctrl->vs >= NVME_VS(1, 2, 0)) memcpy(ids->nguid, id->nguid, sizeof(id->nguid)); - if (ctrl->vs >= NVME_VS(1, 3, 0)) { - /* Don't treat error as fatal we potentially - * already have a NGUID or EUI-64 - */ - ret = nvme_identify_ns_descs(ctrl, nsid, ids); - if (ret) - dev_warn(ctrl->device, - "Identify Descriptors failed (%d)\n", ret); - } - return ret; + if (ctrl->vs >= NVME_VS(1, 3, 0)) + return nvme_identify_ns_descs(ctrl, nsid, ids); + return 0; } static bool nvme_ns_ids_valid(struct nvme_ns_ids *ids) @@ -1748,7 +1807,7 @@ static void nvme_update_disk_info(struct gendisk *disk, struct nvme_ns *ns, struct nvme_id_ns *id) { - sector_t capacity = le64_to_cpu(id->nsze) << (ns->lba_shift - 9); + sector_t capacity = nvme_lba_to_sect(ns, le64_to_cpu(id->nsze)); unsigned short bs = 1 << ns->lba_shift; u32 atomic_bs, phys_bs, io_opt; @@ -1801,7 +1860,7 @@ set_capacity(disk, capacity); nvme_config_discard(disk, ns); - nvme_config_write_zeroes(disk, ns); + nvme_config_write_zeroes(disk->queue, ns->ctrl); if (id->nsattr & (1 << 0)) set_disk_ro(disk, true); @@ -1814,6 +1873,7 @@ static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id) { struct nvme_ns *ns = disk->private_data; + u32 iob; /* * If identify namespace failed, use default 512 byte block size so @@ -1822,7 +1882,13 @@ ns->lba_shift = id->lbaf[id->flbas & NVME_NS_FLBAS_LBA_MASK].ds; if (ns->lba_shift == 0) ns->lba_shift = 9; - ns->noiob = le16_to_cpu(id->noiob); + + if ((ns->ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && + is_power_of_2(ns->ctrl->max_hw_sectors)) + iob = ns->ctrl->max_hw_sectors; + else + iob = nvme_lba_to_sect(ns, le16_to_cpu(id->noiob)); + ns->ms = le16_to_cpu(id->lbaf[id->flbas & NVME_NS_FLBAS_LBA_MASK].ms); ns->ext = ns->ms && (id->flbas & NVME_NS_FLBAS_META_EXT); /* the PI implementation requires metadata equal t10 pi tuple size */ @@ -1831,14 +1897,14 @@ else ns->pi_type = 0; - if (ns->noiob) - nvme_set_chunk_size(ns); + if (iob) + blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(iob)); nvme_update_disk_info(disk, ns, id); #ifdef CONFIG_NVME_MULTIPATH if (ns->head->disk) { nvme_update_disk_info(ns->head->disk, ns, id); blk_queue_stack_limits(ns->head->disk->queue, ns->queue); - revalidate_disk(ns->head->disk); + nvme_mpath_update_disk_size(ns->head->disk); } #endif } @@ -1967,18 +2033,21 @@ enum pr_type type, bool abort) { u32 cdw10 = nvme_pr_type(type) << 8 | (abort ? 2 : 1); + return nvme_pr_command(bdev, cdw10, old, new, nvme_cmd_resv_acquire); } static int nvme_pr_clear(struct block_device *bdev, u64 key) { - u32 cdw10 = 1 | (key ? 1 << 3 : 0); - return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register); + u32 cdw10 = 1 | (key ? 0 : 1 << 3); + + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); } static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type) { - u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0); + u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 0 : 1 << 3); + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); } @@ -2183,9 +2252,6 @@ blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors); blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX)); } - if ((ctrl->quirks & NVME_QUIRK_STRIPE_SIZE) && - is_power_of_2(ctrl->max_hw_sectors)) - blk_queue_chunk_sectors(q, ctrl->max_hw_sectors); blk_queue_virt_boundary(q, ctrl->page_size - 1); if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) vwc = true; @@ -2369,7 +2435,8 @@ if (ctrl->ps_max_latency_us != latency) { ctrl->ps_max_latency_us = latency; - nvme_configure_apst(ctrl); + if (ctrl->state == NVME_CTRL_LIVE) + nvme_configure_apst(ctrl); } } @@ -2404,16 +2471,6 @@ .vid = 0x14a4, .fr = "22301111", .quirks = NVME_QUIRK_SIMPLE_SUSPEND, - }, - { - /* - * This Kingston E8FK11.T firmware version has no interrupt - * after resume with actions related to suspend to idle - * https://bugzilla.kernel.org/show_bug.cgi?id=204887 - */ - .vid = 0x2646, - .fr = "E8FK11.T", - .quirks = NVME_QUIRK_SIMPLE_SUSPEND, } }; @@ -2629,7 +2686,6 @@ nvme_init_subnqn(subsys, ctrl, id); memcpy(subsys->serial, id->sn, sizeof(subsys->serial)); memcpy(subsys->model, id->mn, sizeof(subsys->model)); - memcpy(subsys->firmware_rev, id->fr, sizeof(subsys->firmware_rev)); subsys->vendor_id = le16_to_cpu(id->vid); subsys->cmic = id->cmic; subsys->awupf = le16_to_cpu(id->awupf); @@ -2765,10 +2821,6 @@ if (!ctrl->identified) { int i; - ret = nvme_init_subsystem(ctrl, id); - if (ret) - goto out_free; - /* * Check for quirks. Quirk can depend on firmware version, * so, in principle, the set of quirks present can change @@ -2781,7 +2833,13 @@ if (quirk_matches(id, &core_quirks[i])) ctrl->quirks |= core_quirks[i].quirks; } + + ret = nvme_init_subsystem(ctrl, id); + if (ret) + goto out_free; } + memcpy(ctrl->subsys->firmware_rev, id->fr, + sizeof(ctrl->subsys->firmware_rev)); if (force_apst && (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS)) { dev_warn(ctrl->device, "forcibly allowing all power states due to nvme_core.force_apst -- use at your own risk\n"); @@ -2868,7 +2926,7 @@ ctrl->hmmaxd = le16_to_cpu(id->hmmaxd); } - ret = nvme_mpath_init(ctrl, id); + ret = nvme_mpath_init_identify(ctrl, id); kfree(id); if (ret < 0) @@ -2917,10 +2975,26 @@ return -EWOULDBLOCK; } + nvme_get_ctrl(ctrl); + if (!try_module_get(ctrl->ops->module)) { + nvme_put_ctrl(ctrl); + return -EINVAL; + } + file->private_data = ctrl; return 0; } +static int nvme_dev_release(struct inode *inode, struct file *file) +{ + struct nvme_ctrl *ctrl = + container_of(inode->i_cdev, struct nvme_ctrl, cdev); + + module_put(ctrl->ops->module); + nvme_put_ctrl(ctrl); + return 0; +} + static int nvme_dev_user_cmd(struct nvme_ctrl *ctrl, void __user *argp) { struct nvme_ns *ns; @@ -2968,11 +3042,17 @@ case NVME_IOCTL_IO_CMD: return nvme_dev_user_cmd(ctrl, argp); case NVME_IOCTL_RESET: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; dev_warn(ctrl->device, "resetting controller\n"); return nvme_reset_ctrl_sync(ctrl); case NVME_IOCTL_SUBSYS_RESET: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; return nvme_reset_subsystem(ctrl); case NVME_IOCTL_RESCAN: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; nvme_queue_scan(ctrl); return 0; default: @@ -2983,6 +3063,7 @@ static const struct file_operations nvme_dev_fops = { .owner = THIS_MODULE, .open = nvme_dev_open, + .release = nvme_dev_release, .unlocked_ioctl = nvme_dev_ioctl, .compat_ioctl = nvme_dev_ioctl, }; @@ -3181,6 +3262,10 @@ { struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + /* Can't delete non-created controllers */ + if (!ctrl->created) + return -EBUSY; + if (device_remove_file_self(dev, attr)) nvme_delete_ctrl_sync(ctrl); return count; @@ -3306,7 +3391,6 @@ list_for_each_entry(h, &subsys->nsheads, entry) { if (nvme_ns_ids_valid(&new->ids) && - !list_empty(&h->list) && nvme_ns_ids_equal(&new->ids, &h->ids)) return -EINVAL; } @@ -3401,6 +3485,7 @@ "IDs don't match for shared namespace %d\n", nsid); ret = -EINVAL; + nvme_put_ns_head(head); goto out_unlock; } } @@ -3555,10 +3640,14 @@ return 0; out_put_disk: + /* prevent double queue cleanup */ + ns->disk->queue = NULL; put_disk(ns->disk); out_unlink_ns: mutex_lock(&ctrl->subsys->lock); list_del_rcu(&ns->siblings); + if (list_empty(&ns->head->list)) + list_del_init(&ns->head->entry); mutex_unlock(&ctrl->subsys->lock); nvme_put_ns_head(ns->head); out_free_id: @@ -3581,7 +3670,10 @@ mutex_lock(&ns->ctrl->subsys->lock); list_del_rcu(&ns->siblings); + if (list_empty(&ns->head->list)) + list_del_init(&ns->head->entry); mutex_unlock(&ns->ctrl->subsys->lock); + synchronize_rcu(); /* guarantee not available in head->list */ nvme_mpath_clear_current_path(ns); synchronize_srcu(&ns->head->srcu); /* wait for concurrent submissions */ @@ -3729,8 +3821,7 @@ mutex_lock(&ctrl->scan_lock); nn = le32_to_cpu(id->nn); - if (ctrl->vs >= NVME_VS(1, 1, 0) && - !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) { + if (!nvme_ctrl_limited_cns(ctrl)) { if (!nvme_scan_ns_list(ctrl, nn)) goto out_free_id; } @@ -3830,7 +3921,14 @@ container_of(work, struct nvme_ctrl, async_event_work); nvme_aen_uevent(ctrl); - ctrl->ops->submit_async_event(ctrl); + + /* + * The transport drivers must guarantee AER submission here is safe by + * flushing ctrl async_event_work after changing the controller state + * from LIVE and before freeing the admin queue. + */ + if (ctrl->state == NVME_CTRL_LIVE) + ctrl->ops->submit_async_event(ctrl); } static bool nvme_ctrl_pp_status(struct nvme_ctrl *ctrl) @@ -3855,7 +3953,7 @@ if (!log) return; - if (nvme_get_log(ctrl, NVME_NSID_ALL, 0, NVME_LOG_FW_SLOT, log, + if (nvme_get_log(ctrl, NVME_NSID_ALL, NVME_LOG_FW_SLOT, 0, log, sizeof(*log), 0)) dev_warn(ctrl->device, "Get FW SLOT INFO log error\n"); kfree(log); @@ -3893,11 +3991,19 @@ nvme_get_fw_slot_info(ctrl); } -static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) +static u32 nvme_aer_type(u32 result) { - u32 aer_notice_type = (result & 0xff00) >> 8; + return result & 0x7; +} - trace_nvme_async_event(ctrl, aer_notice_type); +static u32 nvme_aer_subtype(u32 result) +{ + return (result & 0xff00) >> 8; +} + +static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) +{ + u32 aer_notice_type = nvme_aer_subtype(result); switch (aer_notice_type) { case NVME_AER_NOTICE_NS_CHANGED: @@ -3928,24 +4034,40 @@ } } +static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl) +{ + dev_warn(ctrl->device, "resetting controller due to AER\n"); + nvme_reset_ctrl(ctrl); +} + void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, volatile union nvme_result *res) { u32 result = le32_to_cpu(res->u32); - u32 aer_type = result & 0x07; + u32 aer_type = nvme_aer_type(result); + u32 aer_subtype = nvme_aer_subtype(result); if (le16_to_cpu(status) >> 1 != NVME_SC_SUCCESS) return; + trace_nvme_async_event(ctrl, result); switch (aer_type) { case NVME_AER_NOTICE: nvme_handle_aen_notice(ctrl, result); break; case NVME_AER_ERROR: + /* + * For a persistent internal error, don't run async_event_work + * to submit a new AER. The controller reset will do it. + */ + if (aer_subtype == NVME_AER_ERROR_PERSIST_INT_ERR) { + nvme_handle_aer_persistent_error(ctrl); + return; + } + fallthrough; case NVME_AER_SMART: case NVME_AER_CSS: case NVME_AER_VS: - trace_nvme_async_event(ctrl, aer_type); ctrl->aen_result = result; break; default: @@ -3961,6 +4083,8 @@ nvme_stop_keep_alive(ctrl); flush_work(&ctrl->async_event_work); cancel_work_sync(&ctrl->fw_act_work); + if (ctrl->ops->stop_ctrl) + ctrl->ops->stop_ctrl(ctrl); } EXPORT_SYMBOL_GPL(nvme_stop_ctrl); @@ -3974,7 +4098,9 @@ if (ctrl->queue_count > 1) { nvme_queue_scan(ctrl); nvme_start_queues(ctrl); + nvme_mpath_update(ctrl); } + ctrl->created = true; } EXPORT_SYMBOL_GPL(nvme_start_ctrl); @@ -3992,7 +4118,7 @@ container_of(dev, struct nvme_ctrl, ctrl_device); struct nvme_subsystem *subsys = ctrl->subsys; - if (subsys && ctrl->instance != subsys->instance) + if (!subsys || ctrl->instance != subsys->instance) ida_simple_remove(&nvme_instance_ida, ctrl->instance); kfree(ctrl->effects); @@ -4065,6 +4191,7 @@ if (ret) goto out_release_instance; + nvme_get_ctrl(ctrl); cdev_init(&ctrl->cdev, &nvme_dev_fops); ctrl->cdev.owner = ops->module; ret = cdev_device_add(&ctrl->cdev, ctrl->device); @@ -4080,9 +4207,11 @@ min(default_ps_max_latency_us, (unsigned long)S32_MAX)); nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device)); + nvme_mpath_init_ctrl(ctrl); return 0; out_free_name: + nvme_put_ctrl(ctrl); kfree_const(ctrl->device->kobj.name); out_release_instance: ida_simple_remove(&nvme_instance_ida, ctrl->instance); @@ -4128,7 +4257,7 @@ } EXPORT_SYMBOL_GPL(nvme_unfreeze); -void nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout) +int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout) { struct nvme_ns *ns; @@ -4139,6 +4268,7 @@ break; } up_read(&ctrl->namespaces_rwsem); + return timeout; } EXPORT_SYMBOL_GPL(nvme_wait_freeze_timeout); @@ -4186,8 +4316,7 @@ } EXPORT_SYMBOL_GPL(nvme_start_queues); - -void nvme_sync_queues(struct nvme_ctrl *ctrl) +void nvme_sync_io_queues(struct nvme_ctrl *ctrl) { struct nvme_ns *ns; @@ -4195,7 +4324,12 @@ list_for_each_entry(ns, &ctrl->namespaces, list) blk_sync_queue(ns->queue); up_read(&ctrl->namespaces_rwsem); +} +EXPORT_SYMBOL_GPL(nvme_sync_io_queues); +void nvme_sync_queues(struct nvme_ctrl *ctrl) +{ + nvme_sync_io_queues(ctrl); if (ctrl->admin_q) blk_sync_queue(ctrl->admin_q); } --- linux-oracle-5.4.0.orig/drivers/nvme/host/fabrics.c +++ linux-oracle-5.4.0/drivers/nvme/host/fabrics.c @@ -336,6 +336,11 @@ cmd->connect.recfmt); break; + case NVME_SC_HOST_PATH_ERROR: + dev_err(ctrl->device, + "Connect command failed: host path error\n"); + break; + default: dev_err(ctrl->device, "Connect command failed, error wo/DNR bit: %d\n", @@ -565,10 +570,14 @@ struct nvme_request *req = nvme_req(rq); /* - * If we are in some state of setup or teardown only allow - * internally generated commands. + * currently we have a problem sending passthru commands + * on the admin_q if the controller is not LIVE because we can't + * make sure that they are going out after the admin connect, + * controller enable and/or other commands in the initialization + * sequence. until the controller will be LIVE, fail with + * BLK_STS_RESOURCE so that they will be rescheduled. */ - if (!blk_rq_is_passthrough(rq) || (req->flags & NVME_REQ_USERCMD)) + if (rq->q == ctrl->admin_q && (req->flags & NVME_REQ_USERCMD)) return false; /* @@ -576,9 +585,8 @@ * which is require to set the queue live in the appropinquate states. */ switch (ctrl->state) { - case NVME_CTRL_NEW: case NVME_CTRL_CONNECTING: - if (nvme_is_fabrics(req->cmd) && + if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) && req->cmd->fabrics.fctype == nvme_fabrics_type_connect) return true; break; --- linux-oracle-5.4.0.orig/drivers/nvme/host/fc.c +++ linux-oracle-5.4.0/drivers/nvme/host/fc.c @@ -1224,7 +1224,7 @@ lsreq->rqstlen = sizeof(*assoc_rqst); lsreq->rspaddr = assoc_acc; lsreq->rsplen = sizeof(*assoc_acc); - lsreq->timeout = NVME_FC_CONNECT_TIMEOUT_SEC; + lsreq->timeout = NVME_FC_LS_TIMEOUT_SEC; ret = nvme_fc_send_ls_req(ctrl->rport, lsop); if (ret) @@ -1264,7 +1264,7 @@ if (fcret) { ret = -EBADF; dev_err(ctrl->dev, - "q %d connect failed: %s\n", + "q %d Create Association LS failed: %s\n", queue->qnum, validation_errors[fcret]); } else { ctrl->association_id = @@ -1332,7 +1332,7 @@ lsreq->rqstlen = sizeof(*conn_rqst); lsreq->rspaddr = conn_acc; lsreq->rsplen = sizeof(*conn_acc); - lsreq->timeout = NVME_FC_CONNECT_TIMEOUT_SEC; + lsreq->timeout = NVME_FC_LS_TIMEOUT_SEC; ret = nvme_fc_send_ls_req(ctrl->rport, lsop); if (ret) @@ -1363,7 +1363,7 @@ if (fcret) { ret = -EBADF; dev_err(ctrl->dev, - "q %d connect failed: %s\n", + "q %d Create I/O Connection LS failed: %s\n", queue->qnum, validation_errors[fcret]); } else { queue->connection_id = @@ -1376,7 +1376,7 @@ out_no_memory: if (ret) dev_err(ctrl->dev, - "queue %d connect command failed (%d).\n", + "queue %d connect I/O queue failed (%d).\n", queue->qnum, ret); return ret; } @@ -1413,8 +1413,8 @@ static void nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl) { - struct fcnvme_ls_disconnect_rqst *discon_rqst; - struct fcnvme_ls_disconnect_acc *discon_acc; + struct fcnvme_ls_disconnect_assoc_rqst *discon_rqst; + struct fcnvme_ls_disconnect_assoc_acc *discon_acc; struct nvmefc_ls_req_op *lsop; struct nvmefc_ls_req *lsreq; int ret; @@ -1430,11 +1430,11 @@ lsreq = &lsop->ls_req; lsreq->private = (void *)&lsop[1]; - discon_rqst = (struct fcnvme_ls_disconnect_rqst *) + discon_rqst = (struct fcnvme_ls_disconnect_assoc_rqst *) (lsreq->private + ctrl->lport->ops->lsrqst_priv_sz); - discon_acc = (struct fcnvme_ls_disconnect_acc *)&discon_rqst[1]; + discon_acc = (struct fcnvme_ls_disconnect_assoc_acc *)&discon_rqst[1]; - discon_rqst->w0.ls_cmd = FCNVME_LS_DISCONNECT; + discon_rqst->w0.ls_cmd = FCNVME_LS_DISCONNECT_ASSOC; discon_rqst->desc_list_len = cpu_to_be32( sizeof(struct fcnvme_lsdesc_assoc_id) + sizeof(struct fcnvme_lsdesc_disconn_cmd)); @@ -1451,22 +1451,17 @@ discon_rqst->discon_cmd.desc_len = fcnvme_lsdesc_len( sizeof(struct fcnvme_lsdesc_disconn_cmd)); - discon_rqst->discon_cmd.scope = FCNVME_DISCONN_ASSOCIATION; - discon_rqst->discon_cmd.id = cpu_to_be64(ctrl->association_id); lsreq->rqstaddr = discon_rqst; lsreq->rqstlen = sizeof(*discon_rqst); lsreq->rspaddr = discon_acc; lsreq->rsplen = sizeof(*discon_acc); - lsreq->timeout = NVME_FC_CONNECT_TIMEOUT_SEC; + lsreq->timeout = NVME_FC_LS_TIMEOUT_SEC; ret = nvme_fc_send_ls_req_async(ctrl->rport, lsop, nvme_fc_disconnect_assoc_done); if (ret) kfree(lsop); - - /* only meaningful part to terminating the association */ - ctrl->association_id = 0; } @@ -1608,7 +1603,7 @@ sizeof(op->rsp_iu), DMA_FROM_DEVICE); if (opstate == FCPOP_STATE_ABORTED) - status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); + status = cpu_to_le16(NVME_SC_HOST_ABORTED_CMD << 1); else if (freq->status) { status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); dev_info(ctrl->ctrl.device, @@ -1662,7 +1657,7 @@ (freq->rcv_rsplen / 4) || be32_to_cpu(op->rsp_iu.xfrd_len) != freq->transferred_length || - op->rsp_iu.status_code || + op->rsp_iu.ersp_result || sqe->common.command_id != cqe->command_id)) { status = cpu_to_le16(NVME_SC_HOST_PATH_ERROR << 1); dev_info(ctrl->ctrl.device, @@ -1672,7 +1667,7 @@ ctrl->cnum, be16_to_cpu(op->rsp_iu.iu_len), be32_to_cpu(op->rsp_iu.xfrd_len), freq->transferred_length, - op->rsp_iu.status_code, + op->rsp_iu.ersp_result, sqe->common.command_id, cqe->command_id); goto done; @@ -1731,16 +1726,21 @@ op->rq = rq; op->rqno = rqno; - cmdiu->scsi_id = NVME_CMD_SCSI_ID; + cmdiu->format_id = NVME_CMD_FORMAT_ID; cmdiu->fc_id = NVME_CMD_FC_ID; cmdiu->iu_len = cpu_to_be16(sizeof(*cmdiu) / sizeof(u32)); + if (queue->qnum) + cmdiu->rsv_cat = fccmnd_set_cat_css(0, + (NVME_CC_CSS_NVM >> NVME_CC_CSS_SHIFT)); + else + cmdiu->rsv_cat = fccmnd_set_cat_admin(0); op->fcp_req.cmddma = fc_dma_map_single(ctrl->lport->dev, &op->cmd_iu, sizeof(op->cmd_iu), DMA_TO_DEVICE); if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.cmddma)) { dev_err(ctrl->dev, "FCP Op failed - cmdiu dma mapping failed.\n"); - ret = EFAULT; + ret = -EFAULT; goto out_on_error; } @@ -1750,7 +1750,7 @@ if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.rspdma)) { dev_err(ctrl->dev, "FCP Op failed - rspiu dma mapping failed.\n"); - ret = EFAULT; + ret = -EFAULT; } atomic_set(&op->state, FCPOP_STATE_IDLE); @@ -1820,6 +1820,7 @@ struct nvme_fc_fcp_op *aen_op; int i; + cancel_work_sync(&ctrl->ctrl.async_event_work); aen_op = ctrl->aen_ops; for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) { if (!aen_op->fcp_req.private) @@ -2695,7 +2696,7 @@ /* warn if maxcmd is lower than queue_size */ dev_warn(ctrl->ctrl.device, "queue_size %zu > ctrl maxcmd %u, reducing " - "to queue_size\n", + "to maxcmd\n", opts->queue_size, ctrl->ctrl.maxcmd); opts->queue_size = ctrl->ctrl.maxcmd; } @@ -2703,7 +2704,8 @@ if (opts->queue_size > ctrl->ctrl.sqsize + 1) { /* warn if sqsize is lower than queue_size */ dev_warn(ctrl->ctrl.device, - "queue_size %zu > ctrl sqsize %u, clamping down\n", + "queue_size %zu > ctrl sqsize %u, reducing " + "to sqsize\n", opts->queue_size, ctrl->ctrl.sqsize + 1); opts->queue_size = ctrl->ctrl.sqsize + 1; } @@ -2739,6 +2741,7 @@ out_disconnect_admin_queue: /* send a Disconnect(association) LS to fc-nvme target */ nvme_fc_xmt_disconnect_assoc(ctrl); + ctrl->association_id = 0; out_delete_hw_queue: __nvme_fc_delete_hw_queue(ctrl, &ctrl->queues[0], 0); out_free_queue: @@ -2830,6 +2833,8 @@ if (ctrl->association_id) nvme_fc_xmt_disconnect_assoc(ctrl); + ctrl->association_id = 0; + if (ctrl->ctrl.tagset) { nvme_fc_delete_hw_io_queues(ctrl); nvme_fc_free_io_queues(ctrl); @@ -2907,10 +2912,22 @@ static void __nvme_fc_terminate_io(struct nvme_fc_ctrl *ctrl) { - nvme_stop_keep_alive(&ctrl->ctrl); + /* + * if state is connecting - the error occurred as part of a + * reconnect attempt. The create_association error paths will + * clean up any outstanding io. + * + * if it's a different state - ensure all pending io is + * terminated. Given this can delay while waiting for the + * aborted io to return, we recheck adapter state below + * before changing state. + */ + if (ctrl->ctrl.state != NVME_CTRL_CONNECTING) { + nvme_stop_keep_alive(&ctrl->ctrl); - /* will block will waiting for io to terminate */ - nvme_fc_delete_association(ctrl); + /* will block will waiting for io to terminate */ + nvme_fc_delete_association(ctrl); + } if (ctrl->ctrl.state != NVME_CTRL_CONNECTING && !nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) @@ -3158,10 +3175,7 @@ goto fail_ctrl; } - nvme_get_ctrl(&ctrl->ctrl); - if (!queue_delayed_work(nvme_wq, &ctrl->connect_work, 0)) { - nvme_put_ctrl(&ctrl->ctrl); dev_err(ctrl->ctrl.device, "NVME-FC{%d}: failed to schedule initial connect\n", ctrl->cnum); @@ -3186,6 +3200,7 @@ /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); + nvme_put_ctrl(&ctrl->ctrl); /* Remove core ctrl ref. */ nvme_put_ctrl(&ctrl->ctrl); @@ -3308,12 +3323,14 @@ spin_lock_irqsave(&nvme_fc_lock, flags); list_for_each_entry(lport, &nvme_fc_lport_list, port_list) { if (lport->localport.node_name != laddr.nn || - lport->localport.port_name != laddr.pn) + lport->localport.port_name != laddr.pn || + lport->localport.port_state != FC_OBJSTATE_ONLINE) continue; list_for_each_entry(rport, &lport->endp_list, endp_list) { if (rport->remoteport.node_name != raddr.nn || - rport->remoteport.port_name != raddr.pn) + rport->remoteport.port_name != raddr.pn || + rport->remoteport.port_state != FC_OBJSTATE_ONLINE) continue; /* if fail to get reference fall through. Will error */ --- linux-oracle-5.4.0.orig/drivers/nvme/host/multipath.c +++ linux-oracle-5.4.0/drivers/nvme/host/multipath.c @@ -3,6 +3,7 @@ * Copyright (c) 2017-2018 Christoph Hellwig. */ +#include #include #include #include "nvme.h" @@ -64,17 +65,12 @@ } } -void nvme_failover_req(struct request *req) +bool nvme_failover_req(struct request *req) { struct nvme_ns *ns = req->q->queuedata; u16 status = nvme_req(req)->status; unsigned long flags; - spin_lock_irqsave(&ns->head->requeue_lock, flags); - blk_steal_bios(&ns->head->requeue_list, req); - spin_unlock_irqrestore(&ns->head->requeue_lock, flags); - blk_mq_end_request(req, 0); - switch (status & 0x7ff) { case NVME_SC_ANA_TRANSITION: case NVME_SC_ANA_INACCESSIBLE: @@ -95,6 +91,7 @@ } break; case NVME_SC_HOST_PATH_ERROR: + case NVME_SC_HOST_ABORTED_CMD: /* * Temporary transport disruption in talking to the controller. * Try to send on a new path. @@ -102,15 +99,17 @@ nvme_mpath_clear_current_path(ns); break; default: - /* - * Reset the controller for any non-ANA error as we don't know - * what caused the error. - */ - nvme_reset_ctrl(ns->ctrl); - break; + /* This was a non-ANA error so follow the normal error path. */ + return false; } + spin_lock_irqsave(&ns->head->requeue_lock, flags); + blk_steal_bios(&ns->head->requeue_list, req); + spin_unlock_irqrestore(&ns->head->requeue_lock, flags); + blk_mq_end_request(req, 0); + kblockd_schedule_work(&ns->head->requeue_work); + return true; } void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) @@ -157,13 +156,12 @@ { struct nvme_ns *ns; - mutex_lock(&ctrl->scan_lock); down_read(&ctrl->namespaces_rwsem); - list_for_each_entry(ns, &ctrl->namespaces, list) - if (nvme_mpath_clear_current_path(ns)) - kblockd_schedule_work(&ns->head->requeue_work); + list_for_each_entry(ns, &ctrl->namespaces, list) { + nvme_mpath_clear_current_path(ns); + kblockd_schedule_work(&ns->head->requeue_work); + } up_read(&ctrl->namespaces_rwsem); - mutex_unlock(&ctrl->scan_lock); } static bool nvme_path_is_disabled(struct nvme_ns *ns) @@ -182,7 +180,8 @@ if (nvme_path_is_disabled(ns)) continue; - if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA) + if (ns->ctrl->numa_node != NUMA_NO_NODE && + READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_NUMA) distance = node_distance(node, ns->ctrl->numa_node); else distance = LOCAL_DISTANCE; @@ -234,7 +233,7 @@ } for (ns = nvme_next_ns(head, old); - ns != old; + ns && ns != old; ns = nvme_next_ns(head, ns)) { if (nvme_path_is_disabled(ns)) continue; @@ -247,6 +246,17 @@ fallback = ns; } + /* + * The loop above skips the current path for round-robin semantics. + * Fall back to the current path if either: + * - no other optimized path found and current is optimized, + * - no other usable path found and current is usable. + */ + if (!nvme_path_is_disabled(old) && + (old->ana_state == NVME_ANA_OPTIMIZED || + (!fallback && old->ana_state == NVME_ANA_NONOPTIMIZED))) + return old; + if (!fallback) return NULL; found = fallback; @@ -267,10 +277,13 @@ struct nvme_ns *ns; ns = srcu_dereference(head->current_path[node], &head->srcu); - if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_RR && ns) - ns = nvme_round_robin_path(head, node, ns); - if (unlikely(!ns || !nvme_path_is_optimized(ns))) - ns = __nvme_find_path(head, node); + if (unlikely(!ns)) + return __nvme_find_path(head, node); + + if (READ_ONCE(head->subsys->iopolicy) == NVME_IOPOLICY_RR) + return nvme_round_robin_path(head, node, ns); + if (unlikely(!nvme_path_is_optimized(ns))) + return __nvme_find_path(head, node); return ns; } @@ -317,7 +330,7 @@ trace_block_bio_remap(bio->bi_disk->queue, bio, disk_devt(ns->head->disk), bio->bi_iter.bi_sector); - ret = direct_make_request(bio); + ret = generic_make_request(bio); } else if (nvme_available_path(head)) { dev_warn_ratelimited(dev, "no usable path - requeuing I/O\n"); @@ -412,26 +425,26 @@ { struct nvme_ns_head *head = ns->head; - lockdep_assert_held(&ns->head->lock); - if (!head->disk) return; - if (!(head->disk->flags & GENHD_FL_UP)) + if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) device_add_disk(&head->subsys->dev, head->disk, nvme_ns_id_attr_groups); + mutex_lock(&head->lock); if (nvme_path_is_optimized(ns)) { int node, srcu_idx; srcu_idx = srcu_read_lock(&head->srcu); - for_each_node(node) + for_each_online_node(node) __nvme_find_path(head, node); srcu_read_unlock(&head->srcu, srcu_idx); } + mutex_unlock(&head->lock); - synchronize_srcu(&ns->head->srcu); - kblockd_schedule_work(&ns->head->requeue_work); + synchronize_srcu(&head->srcu); + kblockd_schedule_work(&head->requeue_work); } static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data, @@ -446,8 +459,14 @@ for (i = 0; i < le16_to_cpu(ctrl->ana_log_buf->ngrps); i++) { struct nvme_ana_group_desc *desc = base + offset; - u32 nr_nsids = le32_to_cpu(desc->nnsids); - size_t nsid_buf_size = nr_nsids * sizeof(__le32); + u32 nr_nsids; + size_t nsid_buf_size; + + if (WARN_ON_ONCE(offset > ctrl->ana_log_size - sizeof(*desc))) + return -EINVAL; + + nr_nsids = le32_to_cpu(desc->nnsids); + nsid_buf_size = nr_nsids * sizeof(__le32); if (WARN_ON_ONCE(desc->grpid == 0)) return -EINVAL; @@ -467,8 +486,6 @@ return error; offset += nsid_buf_size; - if (WARN_ON_ONCE(offset > ctrl->ana_log_size - sizeof(*desc))) - return -EINVAL; } return 0; @@ -482,14 +499,21 @@ static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc, struct nvme_ns *ns) { - mutex_lock(&ns->head->lock); ns->ana_grpid = le32_to_cpu(desc->grpid); ns->ana_state = desc->state; clear_bit(NVME_NS_ANA_PENDING, &ns->flags); - - if (nvme_state_is_live(ns->ana_state)) + /* + * nvme_mpath_set_live() will trigger I/O to the multipath path device + * and in turn to this path device. However we cannot accept this I/O + * if the controller is not live. This may deadlock if called from + * nvme_mpath_init_identify() and the ctrl will never complete + * initialization, preventing I/O from completing. For this case we + * will reprocess the ANA log page in nvme_mpath_update() once the + * controller is ready. + */ + if (nvme_state_is_live(ns->ana_state) && + ns->ctrl->state == NVME_CTRL_LIVE) nvme_mpath_set_live(ns); - mutex_unlock(&ns->head->lock); } static int nvme_update_ana_state(struct nvme_ctrl *ctrl, @@ -509,18 +533,21 @@ if (!nr_nsids) return 0; - down_write(&ctrl->namespaces_rwsem); + down_read(&ctrl->namespaces_rwsem); list_for_each_entry(ns, &ctrl->namespaces, list) { - unsigned nsid = le32_to_cpu(desc->nsids[n]); - + unsigned nsid; +again: + nsid = le32_to_cpu(desc->nsids[n]); if (ns->head->ns_id < nsid) continue; if (ns->head->ns_id == nsid) nvme_update_ns_ana_state(desc, ns); if (++n == nr_nsids) break; + if (ns->head->ns_id > nsid) + goto again; } - up_write(&ctrl->namespaces_rwsem); + up_read(&ctrl->namespaces_rwsem); return 0; } @@ -569,6 +596,18 @@ nvme_read_ana_log(ctrl); } +void nvme_mpath_update(struct nvme_ctrl *ctrl) +{ + u32 nr_change_groups = 0; + + if (!ctrl->ana_log_buf) + return; + + mutex_lock(&ctrl->ana_lock); + nvme_parse_ana_log(ctrl, &nr_change_groups, nvme_update_ana_state); + mutex_unlock(&ctrl->ana_lock); +} + static void nvme_anatt_timeout(struct timer_list *t) { struct nvme_ctrl *ctrl = from_timer(ctrl, t, anatt_timer); @@ -639,31 +678,49 @@ } DEVICE_ATTR_RO(ana_state); -static int nvme_set_ns_ana_state(struct nvme_ctrl *ctrl, +static int nvme_lookup_ana_group_desc(struct nvme_ctrl *ctrl, struct nvme_ana_group_desc *desc, void *data) { - struct nvme_ns *ns = data; + struct nvme_ana_group_desc *dst = data; - if (ns->ana_grpid == le32_to_cpu(desc->grpid)) { - nvme_update_ns_ana_state(desc, ns); - return -ENXIO; /* just break out of the loop */ - } + if (desc->grpid != dst->grpid) + return 0; - return 0; + *dst = *desc; + return -ENXIO; /* just break out of the loop */ } void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id) { if (nvme_ctrl_use_ana(ns->ctrl)) { + struct nvme_ana_group_desc desc = { + .grpid = id->anagrpid, + .state = 0, + }; + mutex_lock(&ns->ctrl->ana_lock); ns->ana_grpid = le32_to_cpu(id->anagrpid); - nvme_parse_ana_log(ns->ctrl, ns, nvme_set_ns_ana_state); + nvme_parse_ana_log(ns->ctrl, &desc, nvme_lookup_ana_group_desc); mutex_unlock(&ns->ctrl->ana_lock); + if (desc.state) { + /* found the group desc: update */ + nvme_update_ns_ana_state(&desc, ns); + } else { + /* group desc not found: trigger a re-read */ + set_bit(NVME_NS_ANA_PENDING, &ns->flags); + queue_work(nvme_wq, &ns->ctrl->ana_work); + } } else { - mutex_lock(&ns->head->lock); ns->ana_state = NVME_ANA_OPTIMIZED; nvme_mpath_set_live(ns); - mutex_unlock(&ns->head->lock); + } + + if (bdi_cap_stable_pages_required(ns->queue->backing_dev_info)) { + struct gendisk *disk = ns->head->disk; + + if (disk) + disk->queue->backing_dev_info->capabilities |= + BDI_CAP_STABLE_WRITES; } } @@ -678,12 +735,29 @@ kblockd_schedule_work(&head->requeue_work); flush_work(&head->requeue_work); blk_cleanup_queue(head->disk->queue); + if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { + /* + * if device_add_disk wasn't called, prevent + * disk release to put a bogus reference on the + * request queue + */ + head->disk->queue = NULL; + } put_disk(head->disk); } -int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) +void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) { - int error; + mutex_init(&ctrl->ana_lock); + timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); + INIT_WORK(&ctrl->ana_work, nvme_ana_work); +} + +int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) +{ + size_t max_transfer_size = ctrl->max_hw_sectors << SECTOR_SHIFT; + size_t ana_log_size; + int error = 0; /* check if multipath is enabled and we have the capability */ if (!multipath || !ctrl->subsys || !(ctrl->subsys->cmic & (1 << 3))) @@ -694,36 +768,31 @@ ctrl->nanagrpid = le32_to_cpu(id->nanagrpid); ctrl->anagrpmax = le32_to_cpu(id->anagrpmax); - mutex_init(&ctrl->ana_lock); - timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); - ctrl->ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + - ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc); - ctrl->ana_log_size += ctrl->max_namespaces * sizeof(__le32); - - if (ctrl->ana_log_size > ctrl->max_hw_sectors << SECTOR_SHIFT) { + ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + + ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc) + + ctrl->max_namespaces * sizeof(__le32); + if (ana_log_size > max_transfer_size) { dev_err(ctrl->device, - "ANA log page size (%zd) larger than MDTS (%d).\n", - ctrl->ana_log_size, - ctrl->max_hw_sectors << SECTOR_SHIFT); + "ANA log page size (%zd) larger than MDTS (%zd).\n", + ana_log_size, max_transfer_size); dev_err(ctrl->device, "disabling ANA support.\n"); - return 0; + goto out_uninit; } - - INIT_WORK(&ctrl->ana_work, nvme_ana_work); - ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL); - if (!ctrl->ana_log_buf) { - error = -ENOMEM; - goto out; + if (ana_log_size > ctrl->ana_log_size) { + nvme_mpath_stop(ctrl); + kfree(ctrl->ana_log_buf); + ctrl->ana_log_buf = kmalloc(ana_log_size, GFP_KERNEL); + if (!ctrl->ana_log_buf) + return -ENOMEM; } - + ctrl->ana_log_size = ana_log_size; error = nvme_read_ana_log(ctrl); if (error) - goto out_free_ana_log_buf; + goto out_uninit; return 0; -out_free_ana_log_buf: - kfree(ctrl->ana_log_buf); - ctrl->ana_log_buf = NULL; -out: + +out_uninit: + nvme_mpath_uninit(ctrl); return error; } --- linux-oracle-5.4.0.orig/drivers/nvme/host/nvme.h +++ linux-oracle-5.4.0/drivers/nvme/host/nvme.h @@ -115,6 +115,13 @@ * Prevent tag overlap between queues */ NVME_QUIRK_SHARED_TAGS = (1 << 13), + + /* + * The controller doesn't handle the Identify Namespace + * Identification Descriptor list subcommand despite claiming + * NVMe 1.3 compliance. + */ + NVME_QUIRK_NO_NS_DESC_LIST = (1 << 15), }; /* @@ -246,6 +253,7 @@ struct nvme_command ka_cmd; struct work_struct fw_act_work; unsigned long events; + bool created; #ifdef CONFIG_NVME_MULTIPATH /* asymmetric namespace access: */ @@ -284,6 +292,11 @@ struct nvme_fault_inject fault_inject; }; +static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) +{ + return READ_ONCE(ctrl->state); +} + enum nvme_iopolicy { NVME_IOPOLICY_NUMA, NVME_IOPOLICY_RR, @@ -345,6 +358,8 @@ spinlock_t requeue_lock; struct work_struct requeue_work; struct mutex lock; + unsigned long flags; +#define NVME_NSHEAD_DISK_LIVE 0 struct nvme_ns __rcu *current_path[]; #endif }; @@ -374,7 +389,6 @@ #define NVME_NS_REMOVING 0 #define NVME_NS_DEAD 1 #define NVME_NS_ANA_PENDING 2 - u16 noiob; struct nvme_fault_inject fault_inject; @@ -393,6 +407,7 @@ void (*free_ctrl)(struct nvme_ctrl *ctrl); void (*submit_async_event)(struct nvme_ctrl *ctrl); void (*delete_ctrl)(struct nvme_ctrl *ctrl); + void (*stop_ctrl)(struct nvme_ctrl *ctrl); int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); }; @@ -412,16 +427,39 @@ static inline void nvme_should_fail(struct request *req) {} #endif +bool nvme_wait_reset(struct nvme_ctrl *ctrl); +int nvme_try_sched_reset(struct nvme_ctrl *ctrl); + static inline int nvme_reset_subsystem(struct nvme_ctrl *ctrl) { + int ret; + if (!ctrl->subsystem) return -ENOTTY; - return ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (!nvme_wait_reset(ctrl)) + return -EBUSY; + + ret = ctrl->ops->reg_write32(ctrl, NVME_REG_NSSR, 0x4E564D65); + if (ret) + return ret; + + return nvme_try_sched_reset(ctrl); +} + +/* + * Convert a 512B sector number to a device logical block number. + */ +static inline u64 nvme_sect_to_lba(struct nvme_ns *ns, sector_t sector) +{ + return sector >> (ns->lba_shift - SECTOR_SHIFT); } -static inline u64 nvme_block_nr(struct nvme_ns *ns, sector_t sector) +/* + * Convert a device logical block number to a 512B sector number. + */ +static inline sector_t nvme_lba_to_sect(struct nvme_ns *ns, u64 lba) { - return (sector >> (ns->lba_shift - 9)); + return lba << (ns->lba_shift - SECTOR_SHIFT); } static inline void nvme_end_request(struct request *req, __le16 status, @@ -433,7 +471,8 @@ rq->result = result; /* inject error when permitted by fault injection framework */ nvme_should_fail(req); - blk_mq_complete_request(req); + if (likely(!blk_should_fake_timeout(req->q))) + blk_mq_complete_request(req); } static inline void nvme_get_ctrl(struct nvme_ctrl *ctrl) @@ -448,9 +487,10 @@ void nvme_complete_rq(struct request *req); bool nvme_cancel_request(struct request *req, void *data, bool reserved); +void nvme_cancel_tagset(struct nvme_ctrl *ctrl); +void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl); bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state); -bool nvme_wait_reset(struct nvme_ctrl *ctrl); int nvme_disable_ctrl(struct nvme_ctrl *ctrl); int nvme_enable_ctrl(struct nvme_ctrl *ctrl); int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); @@ -474,9 +514,10 @@ void nvme_start_queues(struct nvme_ctrl *ctrl); void nvme_kill_queues(struct nvme_ctrl *ctrl); void nvme_sync_queues(struct nvme_ctrl *ctrl); +void nvme_sync_io_queues(struct nvme_ctrl *ctrl); void nvme_unfreeze(struct nvme_ctrl *ctrl); void nvme_wait_freeze(struct nvme_ctrl *ctrl); -void nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout); +int nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout); void nvme_start_freeze(struct nvme_ctrl *ctrl); #define NVME_QID_ANY -1 @@ -501,7 +542,6 @@ void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); -int nvme_try_sched_reset(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, @@ -521,12 +561,14 @@ void nvme_mpath_start_freeze(struct nvme_subsystem *subsys); void nvme_set_disk_name(char *disk_name, struct nvme_ns *ns, struct nvme_ctrl *ctrl, int *flags); -void nvme_failover_req(struct request *req); +bool nvme_failover_req(struct request *req); void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl); int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id); void nvme_mpath_remove_disk(struct nvme_ns_head *head); -int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); +int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); +void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl); +void nvme_mpath_update(struct nvme_ctrl *ctrl); void nvme_mpath_uninit(struct nvme_ctrl *ctrl); void nvme_mpath_stop(struct nvme_ctrl *ctrl); bool nvme_mpath_clear_current_path(struct nvme_ns *ns); @@ -551,6 +593,16 @@ req->bio, status); } +static inline void nvme_mpath_update_disk_size(struct gendisk *disk) +{ + struct block_device *bdev = bdget_disk(disk, 0); + + if (bdev) { + bd_set_size(bdev, get_capacity(disk) << SECTOR_SHIFT); + bdput(bdev); + } +} + extern struct device_attribute dev_attr_ana_grpid; extern struct device_attribute dev_attr_ana_state; extern struct device_attribute subsys_attr_iopolicy; @@ -570,8 +622,9 @@ sprintf(disk_name, "nvme%dn%d", ctrl->instance, ns->head->instance); } -static inline void nvme_failover_req(struct request *req) +static inline bool nvme_failover_req(struct request *req) { + return false; } static inline void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl) { @@ -602,7 +655,10 @@ blk_status_t status) { } -static inline int nvme_mpath_init(struct nvme_ctrl *ctrl, +static inline void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) +{ +} +static inline int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) { if (ctrl->subsys->cmic & (1 << 3)) @@ -610,6 +666,9 @@ "Please enable CONFIG_NVME_MULTIPATH for full support of multi-port devices.\n"); return 0; } +static inline void nvme_mpath_update(struct nvme_ctrl *ctrl) +{ +} static inline void nvme_mpath_uninit(struct nvme_ctrl *ctrl) { } @@ -625,6 +684,9 @@ static inline void nvme_mpath_start_freeze(struct nvme_subsystem *subsys) { } +static inline void nvme_mpath_update_disk_size(struct gendisk *disk) +{ +} #endif /* CONFIG_NVME_MULTIPATH */ #ifdef CONFIG_NVM --- linux-oracle-5.4.0.orig/drivers/nvme/host/pci.c +++ linux-oracle-5.4.0/drivers/nvme/host/pci.c @@ -68,14 +68,14 @@ module_param_cb(io_queue_depth, &io_queue_depth_ops, &io_queue_depth, 0644); MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2"); -static int write_queues; -module_param(write_queues, int, 0644); +static unsigned int write_queues; +module_param(write_queues, uint, 0644); MODULE_PARM_DESC(write_queues, "Number of queues to use for writes. If not set, reads and writes " "will share a queue set."); -static int poll_queues; -module_param(poll_queues, int, 0644); +static unsigned int poll_queues; +module_param(poll_queues, uint, 0644); MODULE_PARM_DESC(poll_queues, "Number of queues to use for polled IO."); struct nvme_dev; @@ -117,17 +117,21 @@ mempool_t *iod_mempool; /* shadow doorbell buffer support: */ - u32 *dbbuf_dbs; + __le32 *dbbuf_dbs; dma_addr_t dbbuf_dbs_dma_addr; - u32 *dbbuf_eis; + __le32 *dbbuf_eis; dma_addr_t dbbuf_eis_dma_addr; /* host memory buffer support: */ u64 host_mem_size; u32 nr_host_mem_descs; + u32 host_mem_descs_size; dma_addr_t host_mem_descs_dma; struct nvme_host_mem_buf_desc *host_mem_descs; void **host_mem_desc_bufs; + unsigned int nr_allocated_queues; + unsigned int nr_write_queues; + unsigned int nr_poll_queues; }; static int io_queue_depth_set(const char *val, const struct kernel_param *kp) @@ -167,7 +171,6 @@ /* only used for poll queues: */ spinlock_t cq_poll_lock ____cacheline_aligned_in_smp; volatile struct nvme_completion *cqes; - struct blk_mq_tags **tags; dma_addr_t sq_dma_addr; dma_addr_t cq_dma_addr; u32 __iomem *q_db; @@ -185,10 +188,10 @@ #define NVMEQ_SQ_CMB 1 #define NVMEQ_DELETE_ERROR 2 #define NVMEQ_POLLED 3 - u32 *dbbuf_sq_db; - u32 *dbbuf_cq_db; - u32 *dbbuf_sq_ei; - u32 *dbbuf_cq_ei; + __le32 *dbbuf_sq_db; + __le32 *dbbuf_cq_db; + __le32 *dbbuf_sq_ei; + __le32 *dbbuf_cq_ei; struct completion delete_done; }; @@ -211,25 +214,14 @@ struct scatterlist *sg; }; -static unsigned int max_io_queues(void) +static inline unsigned int nvme_dbbuf_size(struct nvme_dev *dev) { - return num_possible_cpus() + write_queues + poll_queues; -} - -static unsigned int max_queue_count(void) -{ - /* IO queues + admin queue */ - return 1 + max_io_queues(); -} - -static inline unsigned int nvme_dbbuf_size(u32 stride) -{ - return (max_queue_count() * 8 * stride); + return dev->nr_allocated_queues * 8 * dev->db_stride; } static int nvme_dbbuf_dma_alloc(struct nvme_dev *dev) { - unsigned int mem_size = nvme_dbbuf_size(dev->db_stride); + unsigned int mem_size = nvme_dbbuf_size(dev); if (dev->dbbuf_dbs) return 0; @@ -254,7 +246,7 @@ static void nvme_dbbuf_dma_free(struct nvme_dev *dev) { - unsigned int mem_size = nvme_dbbuf_size(dev->db_stride); + unsigned int mem_size = nvme_dbbuf_size(dev); if (dev->dbbuf_dbs) { dma_free_coherent(dev->dev, mem_size, @@ -280,9 +272,21 @@ nvmeq->dbbuf_cq_ei = &dev->dbbuf_eis[cq_idx(qid, dev->db_stride)]; } +static void nvme_dbbuf_free(struct nvme_queue *nvmeq) +{ + if (!nvmeq->qid) + return; + + nvmeq->dbbuf_sq_db = NULL; + nvmeq->dbbuf_cq_db = NULL; + nvmeq->dbbuf_sq_ei = NULL; + nvmeq->dbbuf_cq_ei = NULL; +} + static void nvme_dbbuf_set(struct nvme_dev *dev) { struct nvme_command c; + unsigned int i; if (!dev->dbbuf_dbs) return; @@ -296,6 +300,9 @@ dev_warn(dev->ctrl.device, "unable to set dbbuf\n"); /* Free memory and continue on */ nvme_dbbuf_dma_free(dev); + + for (i = 1; i <= dev->online_queues; i++) + nvme_dbbuf_free(&dev->queues[i]); } } @@ -305,11 +312,11 @@ } /* Update dbbuf and return true if an MMIO is required */ -static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db, - volatile u32 *dbbuf_ei) +static bool nvme_dbbuf_update_and_check_event(u16 value, __le32 *dbbuf_db, + volatile __le32 *dbbuf_ei) { if (dbbuf_db) { - u16 old_value; + u16 old_value, event_idx; /* * Ensure that the queue is written before updating @@ -317,8 +324,8 @@ */ wmb(); - old_value = *dbbuf_db; - *dbbuf_db = value; + old_value = le32_to_cpu(*dbbuf_db); + *dbbuf_db = cpu_to_le32(value); /* * Ensure that the doorbell is updated before reading the event @@ -328,7 +335,8 @@ */ mb(); - if (!nvme_dbbuf_need_event(*dbbuf_ei, value, old_value)) + event_idx = le32_to_cpu(*dbbuf_ei); + if (!nvme_dbbuf_need_event(event_idx, value, old_value)) return false; } @@ -377,29 +385,17 @@ WARN_ON(hctx_idx != 0); WARN_ON(dev->admin_tagset.tags[0] != hctx->tags); - WARN_ON(nvmeq->tags); hctx->driver_data = nvmeq; - nvmeq->tags = &dev->admin_tagset.tags[0]; return 0; } -static void nvme_admin_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) -{ - struct nvme_queue *nvmeq = hctx->driver_data; - - nvmeq->tags = NULL; -} - static int nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, unsigned int hctx_idx) { struct nvme_dev *dev = data; struct nvme_queue *nvmeq = &dev->queues[hctx_idx + 1]; - if (!nvmeq->tags) - nvmeq->tags = &dev->tagset.tags[hctx_idx]; - WARN_ON(dev->tagset.tags[hctx_idx] != hctx->tags); hctx->driver_data = nvmeq; return 0; @@ -534,50 +530,71 @@ return true; } -static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) +static void nvme_free_prps(struct nvme_dev *dev, struct request *req) { - struct nvme_iod *iod = blk_mq_rq_to_pdu(req); const int last_prp = dev->ctrl.page_size / sizeof(__le64) - 1; - dma_addr_t dma_addr = iod->first_dma, next_dma_addr; + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + dma_addr_t dma_addr = iod->first_dma; int i; - if (iod->dma_len) { - dma_unmap_page(dev->dev, dma_addr, iod->dma_len, - rq_dma_dir(req)); - return; + for (i = 0; i < iod->npages; i++) { + __le64 *prp_list = nvme_pci_iod_list(req)[i]; + dma_addr_t next_dma_addr = le64_to_cpu(prp_list[last_prp]); + + dma_pool_free(dev->prp_page_pool, prp_list, dma_addr); + dma_addr = next_dma_addr; } - WARN_ON_ONCE(!iod->nents); +} - if (is_pci_p2pdma_page(sg_page(iod->sg))) - pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, - rq_dma_dir(req)); - else - dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); +static void nvme_free_sgls(struct nvme_dev *dev, struct request *req) +{ + const int last_sg = SGES_PER_PAGE - 1; + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + dma_addr_t dma_addr = iod->first_dma; + int i; + for (i = 0; i < iod->npages; i++) { + struct nvme_sgl_desc *sg_list = nvme_pci_iod_list(req)[i]; + dma_addr_t next_dma_addr = le64_to_cpu((sg_list[last_sg]).addr); - if (iod->npages == 0) - dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], - dma_addr); + dma_pool_free(dev->prp_page_pool, sg_list, dma_addr); + dma_addr = next_dma_addr; + } - for (i = 0; i < iod->npages; i++) { - void *addr = nvme_pci_iod_list(req)[i]; +} - if (iod->use_sgl) { - struct nvme_sgl_desc *sg_list = addr; +static void nvme_unmap_sg(struct nvme_dev *dev, struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - next_dma_addr = - le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr); - } else { - __le64 *prp_list = addr; + if (is_pci_p2pdma_page(sg_page(iod->sg))) + pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, + rq_dma_dir(req)); + else + dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); +} - next_dma_addr = le64_to_cpu(prp_list[last_prp]); - } +static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) +{ + struct nvme_iod *iod = blk_mq_rq_to_pdu(req); - dma_pool_free(dev->prp_page_pool, addr, dma_addr); - dma_addr = next_dma_addr; + if (iod->dma_len) { + dma_unmap_page(dev->dev, iod->first_dma, iod->dma_len, + rq_dma_dir(req)); + return; } + WARN_ON_ONCE(!iod->nents); + + nvme_unmap_sg(dev, req); + if (iod->npages == 0) + dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], + iod->first_dma); + else if (iod->use_sgl) + nvme_free_sgls(dev, req); + else + nvme_free_prps(dev, req); mempool_free(iod->sg, dev->iod_mempool); } @@ -654,7 +671,7 @@ __le64 *old_prp_list = prp_list; prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma); if (!prp_list) - return BLK_STS_RESOURCE; + goto free_prps; list[iod->npages++] = prp_list; prp_list[0] = old_prp_list[i - 1]; old_prp_list[i - 1] = cpu_to_le64(prp_dma); @@ -674,14 +691,14 @@ dma_addr = sg_dma_address(sg); dma_len = sg_dma_len(sg); } - done: cmnd->dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma); - return BLK_STS_OK; - - bad_sgl: +free_prps: + nvme_free_prps(dev, req); + return BLK_STS_RESOURCE; +bad_sgl: WARN(DO_ONCE(nvme_print_sgl, iod->sg, iod->nents), "Invalid SGL for payload:%d nents:%d\n", blk_rq_payload_bytes(req), iod->nents); @@ -753,7 +770,7 @@ sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma); if (!sg_list) - return BLK_STS_RESOURCE; + goto free_sgls; i = 0; nvme_pci_iod_list(req)[iod->npages++] = sg_list; @@ -766,6 +783,9 @@ } while (--entries > 0); return BLK_STS_OK; +free_sgls: + nvme_free_sgls(dev, req); + return BLK_STS_RESOURCE; } static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, @@ -820,7 +840,7 @@ return nvme_setup_prp_simple(dev, req, &cmnd->rw, &bv); - if (iod->nvmeq->qid && + if (iod->nvmeq->qid && sgl_threshold && dev->ctrl.sgls & ((1 << 0) | (1 << 1))) return nvme_setup_sgl_simple(dev, req, &cmnd->rw, &bv); @@ -834,7 +854,7 @@ sg_init_table(iod->sg, blk_rq_nr_phys_segments(req)); iod->nents = blk_rq_map_sg(req->q, req, iod->sg); if (!iod->nents) - goto out; + goto out_free_sg; if (is_pci_p2pdma_page(sg_page(iod->sg))) nr_mapped = pci_p2pdma_map_sg_attrs(dev->dev, iod->sg, @@ -843,16 +863,21 @@ nr_mapped = dma_map_sg_attrs(dev->dev, iod->sg, iod->nents, rq_dma_dir(req), DMA_ATTR_NO_WARN); if (!nr_mapped) - goto out; + goto out_free_sg; iod->use_sgl = nvme_pci_use_sgls(dev, req); if (iod->use_sgl) ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw, nr_mapped); else ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); -out: if (ret != BLK_STS_OK) - nvme_unmap_data(dev, req); + goto out_unmap_sg; + return BLK_STS_OK; + +out_unmap_sg: + nvme_unmap_sg(dev, req); +out_free_sg: + mempool_free(iod->sg, dev->iod_mempool); return ret; } @@ -914,7 +939,8 @@ nvme_submit_cmd(nvmeq, &cmnd, bd->last); return BLK_STS_OK; out_unmap_data: - nvme_unmap_data(dev, req); + if (blk_rq_nr_phys_segments(req)) + nvme_unmap_data(dev, req); out_free_cmd: nvme_cleanup_cmd(req); return ret; @@ -950,18 +976,18 @@ writel(head, nvmeq->q_db + nvmeq->dev->db_stride); } +static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq) +{ + if (!nvmeq->qid) + return nvmeq->dev->admin_tagset.tags[0]; + return nvmeq->dev->tagset.tags[nvmeq->qid - 1]; +} + static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) { volatile struct nvme_completion *cqe = &nvmeq->cqes[idx]; struct request *req; - if (unlikely(cqe->command_id >= nvmeq->q_depth)) { - dev_warn(nvmeq->dev->ctrl.device, - "invalid id %d completed on queue %d\n", - cqe->command_id, le16_to_cpu(cqe->sq_id)); - return; - } - /* * AEN requests are special as they don't time out and can * survive any kind of queue freeze and often don't respond to @@ -975,7 +1001,14 @@ return; } - req = blk_mq_tag_to_rq(*nvmeq->tags, cqe->command_id); + req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), cqe->command_id); + if (unlikely(!req)) { + dev_warn(nvmeq->dev->ctrl.device, + "invalid id %d completed on queue %d\n", + cqe->command_id, le16_to_cpu(cqe->sq_id)); + return; + } + trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail); nvme_end_request(req, cqe->status, cqe->result); } @@ -1090,9 +1123,9 @@ spin_lock(&nvmeq->cq_poll_lock); found = nvme_process_cq(nvmeq, &start, &end, -1); + nvme_complete_cqes(nvmeq, start, end); spin_unlock(&nvmeq->cq_poll_lock); - nvme_complete_cqes(nvmeq, start, end); return found; } @@ -1288,8 +1321,8 @@ dev_warn_ratelimited(dev->ctrl.device, "I/O %d QID %d timeout, disable controller\n", req->tag, nvmeq->qid); - nvme_dev_disable(dev, true); nvme_req(req)->flags |= NVME_REQ_CANCELLED; + nvme_dev_disable(dev, true); return BLK_EH_DONE; case NVME_CTRL_RESETTING: return BLK_EH_RESET_TIMER; @@ -1306,10 +1339,10 @@ dev_warn(dev->ctrl.device, "I/O %d QID %d timeout, reset controller\n", req->tag, nvmeq->qid); + nvme_req(req)->flags |= NVME_REQ_CANCELLED; nvme_dev_disable(dev, false); nvme_reset_ctrl(&dev->ctrl); - nvme_req(req)->flags |= NVME_REQ_CANCELLED; return BLK_EH_DONE; } @@ -1413,6 +1446,23 @@ nvme_poll_irqdisable(nvmeq, -1); } +/* + * Called only on a device that has been disabled and after all other threads + * that can check this device's completion queues have synced. This is the + * last chance for the driver to see a natural completion before + * nvme_cancel_request() terminates all incomplete requests. + */ +static void nvme_reap_pending_cqes(struct nvme_dev *dev) +{ + u16 start, end; + int i; + + for (i = dev->ctrl.queue_count - 1; i > 0; i--) { + nvme_process_cq(&dev->queues[i], &start, &end, -1); + nvme_complete_cqes(&dev->queues[i], start, end); + } +} + static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues, int entry_size) { @@ -1578,7 +1628,6 @@ .queue_rq = nvme_queue_rq, .complete = nvme_pci_complete_rq, .init_hctx = nvme_admin_init_hctx, - .exit_hctx = nvme_admin_exit_hctx, .init_request = nvme_init_request, .timeout = nvme_timeout, }; @@ -1628,6 +1677,7 @@ dev->ctrl.admin_q = blk_mq_init_queue(&dev->admin_tagset); if (IS_ERR(dev->ctrl.admin_q)) { blk_mq_free_tag_set(&dev->admin_tagset); + dev->ctrl.admin_q = NULL; return -ENOMEM; } if (!blk_get_queue(dev->ctrl.admin_q)) { @@ -1875,10 +1925,10 @@ kfree(dev->host_mem_desc_bufs); dev->host_mem_desc_bufs = NULL; - dma_free_coherent(dev->dev, - dev->nr_host_mem_descs * sizeof(*dev->host_mem_descs), + dma_free_coherent(dev->dev, dev->host_mem_descs_size, dev->host_mem_descs, dev->host_mem_descs_dma); dev->host_mem_descs = NULL; + dev->host_mem_descs_size = 0; dev->nr_host_mem_descs = 0; } @@ -1886,7 +1936,7 @@ u32 chunk_size) { struct nvme_host_mem_buf_desc *descs; - u32 max_entries, len; + u32 max_entries, len, descs_size; dma_addr_t descs_dma; int i = 0; void **bufs; @@ -1899,8 +1949,9 @@ if (dev->ctrl.hmmaxd && dev->ctrl.hmmaxd < max_entries) max_entries = dev->ctrl.hmmaxd; - descs = dma_alloc_coherent(dev->dev, max_entries * sizeof(*descs), - &descs_dma, GFP_KERNEL); + descs_size = max_entries * sizeof(*descs); + descs = dma_alloc_coherent(dev->dev, descs_size, &descs_dma, + GFP_KERNEL); if (!descs) goto out; @@ -1929,6 +1980,7 @@ dev->host_mem_size = size; dev->host_mem_descs = descs; dev->host_mem_descs_dma = descs_dma; + dev->host_mem_descs_size = descs_size; dev->host_mem_desc_bufs = bufs; return 0; @@ -1943,8 +1995,7 @@ kfree(bufs); out_free_descs: - dma_free_coherent(dev->dev, max_entries * sizeof(*descs), descs, - descs_dma); + dma_free_coherent(dev->dev, descs_size, descs, descs_dma); out: dev->host_mem_descs = NULL; return -ENOMEM; @@ -2020,7 +2071,7 @@ static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs) { struct nvme_dev *dev = affd->priv; - unsigned int nr_read_queues; + unsigned int nr_read_queues, nr_write_queues = dev->nr_write_queues; /* * If there is no interupt available for queues, ensure that @@ -2036,12 +2087,12 @@ if (!nrirqs) { nrirqs = 1; nr_read_queues = 0; - } else if (nrirqs == 1 || !write_queues) { + } else if (nrirqs == 1 || !nr_write_queues) { nr_read_queues = 0; - } else if (write_queues >= nrirqs) { + } else if (nr_write_queues >= nrirqs) { nr_read_queues = 1; } else { - nr_read_queues = nrirqs - write_queues; + nr_read_queues = nrirqs - nr_write_queues; } dev->io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; @@ -2060,21 +2111,17 @@ .priv = dev, }; unsigned int irq_queues, this_p_queues; - unsigned int nr_cpus = num_possible_cpus(); /* * Poll queues don't need interrupts, but we need at least one IO * queue left over for non-polled IO. */ - this_p_queues = poll_queues; + this_p_queues = dev->nr_poll_queues; if (this_p_queues >= nr_io_queues) { this_p_queues = nr_io_queues - 1; irq_queues = 1; } else { - if (nr_cpus < nr_io_queues - this_p_queues) - irq_queues = nr_cpus + 1; - else - irq_queues = nr_io_queues - this_p_queues + 1; + irq_queues = nr_io_queues - this_p_queues + 1; } dev->io_queues[HCTX_TYPE_POLL] = this_p_queues; @@ -2099,14 +2146,25 @@ __nvme_disable_io_queues(dev, nvme_admin_delete_cq); } +static unsigned int nvme_max_io_queues(struct nvme_dev *dev) +{ + return num_possible_cpus() + dev->nr_write_queues + dev->nr_poll_queues; +} + static int nvme_setup_io_queues(struct nvme_dev *dev) { struct nvme_queue *adminq = &dev->queues[0]; struct pci_dev *pdev = to_pci_dev(dev->dev); - int result, nr_io_queues; + unsigned int nr_io_queues; unsigned long size; + int result; - nr_io_queues = max_io_queues(); + /* + * Sample the module parameters once at reset time so that we have + * stable values to work with. + */ + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; /* * If tags are shared with admin queue (Apple bug), then @@ -2114,6 +2172,9 @@ */ if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS) nr_io_queues = 1; + else + nr_io_queues = min(nvme_max_io_queues(dev), + dev->nr_allocated_queues - 1); result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); if (result < 0) @@ -2252,11 +2313,6 @@ if (timeout == 0) return false; - /* handle any remaining CQEs */ - if (opcode == nvme_admin_delete_cq && - !test_bit(NVMEQ_DELETE_ERROR, &nvmeq->flags)) - nvme_poll_irqdisable(nvmeq, -1); - sent--; if (nr_queues) goto retry; @@ -2445,6 +2501,7 @@ nvme_suspend_io_queues(dev); nvme_suspend_queue(&dev->queues[0]); nvme_pci_disable(dev); + nvme_reap_pending_cqes(dev); blk_mq_tagset_busy_iter(&dev->tagset, nvme_cancel_request, &dev->ctrl); blk_mq_tagset_busy_iter(&dev->admin_tagset, nvme_cancel_request, &dev->ctrl); @@ -2538,7 +2595,9 @@ bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); int result; - if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { + if (dev->ctrl.state != NVME_CTRL_RESETTING) { + dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n", + dev->ctrl.state); result = -ENODEV; goto out; } @@ -2751,8 +2810,27 @@ (dmi_match(DMI_BOARD_NAME, "PRIME B350M-A") || dmi_match(DMI_BOARD_NAME, "PRIME Z370-A"))) return NVME_QUIRK_NO_APST; + } else if ((pdev->vendor == 0x144d && (pdev->device == 0xa801 || + pdev->device == 0xa808 || pdev->device == 0xa809)) || + (pdev->vendor == 0x1e0f && pdev->device == 0x0001)) { + /* + * Forcing to use host managed nvme power settings for + * lowest idle power with quick resume latency on + * Samsung and Toshiba SSDs based on suspend behavior + * on Coffee Lake board for LENOVO C640 + */ + if ((dmi_match(DMI_BOARD_VENDOR, "LENOVO")) && + dmi_match(DMI_BOARD_NAME, "LNVNB161216")) + return NVME_QUIRK_SIMPLE_SUSPEND; } + /* + * NVMe SSD drops off the PCIe bus after system idle + * for 10 hours on a Lenovo N60z board. + */ + if (dmi_match(DMI_BOARD_NAME, "LXKT-ZXEG-N6")) + return NVME_QUIRK_NO_APST; + return 0; } @@ -2773,15 +2851,16 @@ size_t alloc_size; node = dev_to_node(&pdev->dev); - if (node == NUMA_NO_NODE) - set_dev_node(&pdev->dev, first_memory_node); dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); if (!dev) return -ENOMEM; - dev->queues = kcalloc_node(max_queue_count(), sizeof(struct nvme_queue), - GFP_KERNEL, node); + dev->nr_write_queues = write_queues; + dev->nr_poll_queues = poll_queues; + dev->nr_allocated_queues = nvme_max_io_queues(dev) + 1; + dev->queues = kcalloc_node(dev->nr_allocated_queues, + sizeof(struct nvme_queue), GFP_KERNEL, node); if (!dev->queues) goto free; @@ -2827,7 +2906,6 @@ dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev)); nvme_reset_ctrl(&dev->ctrl); - nvme_get_ctrl(&dev->ctrl); async_schedule(nvme_async_probe, dev); return 0; @@ -2888,7 +2966,6 @@ if (!pci_device_is_present(pdev)) { nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD); nvme_dev_disable(dev, true); - nvme_dev_remove_admin(dev); } flush_work(&dev->ctrl.reset_work); @@ -2948,9 +3025,15 @@ * the PCI bus layer to put it into D3 in order to take the PCIe link * down, so as to allow the platform to achieve its minimum low-power * state (which may not be possible if the link is up). + * + * If a host memory buffer is enabled, shut down the device as the NVMe + * specification allows the device to access the host memory buffer in + * host DRAM from all power states, but hosts will fail access to DRAM + * during S3. */ if (pm_suspend_via_firmware() || !ctrl->npss || !pcie_aspm_enabled(pdev) || + ndev->nr_host_mem_descs || (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) return nvme_disable_prepare_reset(ndev, true); @@ -3082,14 +3165,18 @@ NVME_QUIRK_DEALLOCATE_ZEROES, }, { PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | - NVME_QUIRK_MEDIUM_PRIO_SQ }, + NVME_QUIRK_MEDIUM_PRIO_SQ | + NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_VDEVICE(INTEL, 0xf1a6), /* Intel 760p/Pro 7600p */ .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */ .driver_data = NVME_QUIRK_IDENTIFY_CNS | NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x126f, 0x2263), /* Silicon Motion unidentified */ + .driver_data = NVME_QUIRK_NO_NS_DESC_LIST, }, { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ - .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | + NVME_QUIRK_NO_NS_DESC_LIST, }, { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, { PCI_DEVICE(0x1c58, 0x0023), /* WDC SN200 adapter */ @@ -3099,7 +3186,14 @@ { PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, { PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */ - .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | + NVME_QUIRK_DISABLE_WRITE_ZEROES| + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ + .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ .driver_data = NVME_QUIRK_LIGHTNVM, }, { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ @@ -3111,13 +3205,19 @@ { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, - { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, - { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) }, + { PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), + .driver_data = NVME_QUIRK_SINGLE_VECTOR }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005), .driver_data = NVME_QUIRK_SINGLE_VECTOR | NVME_QUIRK_128_BYTES_SQES | NVME_QUIRK_SHARED_TAGS }, + + { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) }, { 0, } }; MODULE_DEVICE_TABLE(pci, nvme_id_table); --- linux-oracle-5.4.0.orig/drivers/nvme/host/rdma.c +++ linux-oracle-5.4.0/drivers/nvme/host/rdma.c @@ -451,7 +451,7 @@ * Spread I/O queues completion vectors according their queue index. * Admin queues can always go on completion vector 0. */ - comp_vector = idx == 0 ? idx : idx - 1; + comp_vector = (idx == 0 ? idx : idx - 1) % ibdev->num_comp_vectors; /* Polling queues need direct cq polling context */ if (nvme_rdma_poll_queue(queue)) @@ -665,10 +665,13 @@ if (ret) return ret; - ctrl->ctrl.queue_count = nr_io_queues + 1; - if (ctrl->ctrl.queue_count < 2) - return 0; + if (nr_io_queues == 0) { + dev_err(ctrl->ctrl.device, + "unable to set any I/O queues\n"); + return -ENOMEM; + } + ctrl->ctrl.queue_count = nr_io_queues + 1; dev_info(ctrl->ctrl.device, "creating %d I/O queues.\n", nr_io_queues); @@ -768,6 +771,7 @@ blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); } if (ctrl->async_event_sqe.data) { + cancel_work_sync(&ctrl->ctrl.async_event_work); nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, sizeof(struct nvme_command), DMA_TO_DEVICE); ctrl->async_event_sqe.data = NULL; @@ -834,12 +838,16 @@ error = nvme_init_identify(&ctrl->ctrl); if (error) - goto out_stop_queue; + goto out_quiesce_queue; return 0; +out_quiesce_queue: + blk_mq_quiesce_queue(ctrl->ctrl.admin_q); + blk_sync_queue(ctrl->ctrl.admin_q); out_stop_queue: nvme_rdma_stop_queue(&ctrl->queues[0]); + nvme_cancel_admin_tagset(&ctrl->ctrl); out_cleanup_queue: if (new) blk_cleanup_queue(ctrl->ctrl.admin_q); @@ -850,9 +858,11 @@ if (new) blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); out_free_async_qe: - nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, - sizeof(struct nvme_command), DMA_TO_DEVICE); - ctrl->async_event_sqe.data = NULL; + if (ctrl->async_event_sqe.data) { + nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, + sizeof(struct nvme_command), DMA_TO_DEVICE); + ctrl->async_event_sqe.data = NULL; + } out_free_queue: nvme_rdma_free_queue(&ctrl->queues[0]); return error; @@ -888,18 +898,38 @@ ret = PTR_ERR(ctrl->ctrl.connect_q); goto out_free_tag_set; } - } else { - blk_mq_update_nr_hw_queues(&ctrl->tag_set, - ctrl->ctrl.queue_count - 1); } ret = nvme_rdma_start_io_queues(ctrl); if (ret) goto out_cleanup_connect_q; + if (!new) { + nvme_start_freeze(&ctrl->ctrl); + nvme_start_queues(&ctrl->ctrl); + if (!nvme_wait_freeze_timeout(&ctrl->ctrl, NVME_IO_TIMEOUT)) { + /* + * If we timed out waiting for freeze we are likely to + * be stuck. Fail the controller initialization just + * to be safe. + */ + ret = -ENODEV; + nvme_unfreeze(&ctrl->ctrl); + goto out_wait_freeze_timed_out; + } + blk_mq_update_nr_hw_queues(ctrl->ctrl.tagset, + ctrl->ctrl.queue_count - 1); + nvme_unfreeze(&ctrl->ctrl); + } + return 0; +out_wait_freeze_timed_out: + nvme_stop_queues(&ctrl->ctrl); + nvme_sync_io_queues(&ctrl->ctrl); + nvme_rdma_stop_io_queues(ctrl); out_cleanup_connect_q: + nvme_cancel_tagset(&ctrl->ctrl); if (new) blk_cleanup_queue(ctrl->ctrl.connect_q); out_free_tag_set: @@ -914,6 +944,7 @@ bool remove) { blk_mq_quiesce_queue(ctrl->ctrl.admin_q); + blk_sync_queue(ctrl->ctrl.admin_q); nvme_rdma_stop_queue(&ctrl->queues[0]); if (ctrl->ctrl.admin_tagset) { blk_mq_tagset_busy_iter(ctrl->ctrl.admin_tagset, @@ -930,6 +961,7 @@ { if (ctrl->ctrl.queue_count > 1) { nvme_stop_queues(&ctrl->ctrl); + nvme_sync_io_queues(&ctrl->ctrl); nvme_rdma_stop_io_queues(ctrl); if (ctrl->ctrl.tagset) { blk_mq_tagset_busy_iter(ctrl->ctrl.tagset, @@ -942,6 +974,14 @@ } } +static void nvme_rdma_stop_ctrl(struct nvme_ctrl *nctrl) +{ + struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); + + cancel_work_sync(&ctrl->err_work); + cancel_delayed_work_sync(&ctrl->reconnect_work); +} + static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) { struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); @@ -988,11 +1028,13 @@ return ret; if (ctrl->ctrl.icdoff) { + ret = -EOPNOTSUPP; dev_err(ctrl->ctrl.device, "icdoff is not supported!\n"); goto destroy_admin; } if (!(ctrl->ctrl.sgls & (1 << 2))) { + ret = -EOPNOTSUPP; dev_err(ctrl->ctrl.device, "Mandatory keyed sgls are not supported!\n"); goto destroy_admin; @@ -1032,10 +1074,18 @@ return 0; destroy_io: - if (ctrl->ctrl.queue_count > 1) + if (ctrl->ctrl.queue_count > 1) { + nvme_stop_queues(&ctrl->ctrl); + nvme_sync_io_queues(&ctrl->ctrl); + nvme_rdma_stop_io_queues(ctrl); + nvme_cancel_tagset(&ctrl->ctrl); nvme_rdma_destroy_io_queues(ctrl, new); + } destroy_admin: + blk_mq_quiesce_queue(ctrl->ctrl.admin_q); + blk_sync_queue(ctrl->ctrl.admin_q); nvme_rdma_stop_queue(&ctrl->queues[0]); + nvme_cancel_admin_tagset(&ctrl->ctrl); nvme_rdma_destroy_admin_queue(ctrl, new); return ret; } @@ -1069,6 +1119,7 @@ struct nvme_rdma_ctrl, err_work); nvme_stop_keep_alive(&ctrl->ctrl); + flush_work(&ctrl->ctrl.async_event_work); nvme_rdma_teardown_io_queues(ctrl, false); nvme_start_queues(&ctrl->ctrl); nvme_rdma_teardown_admin_queue(ctrl, false); @@ -1088,7 +1139,8 @@ if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) return; - queue_work(nvme_wq, &ctrl->err_work); + dev_warn(ctrl->ctrl.device, "starting error recovery\n"); + queue_work(nvme_reset_wq, &ctrl->err_work); } static void nvme_rdma_wr_error(struct ib_cq *cq, struct ib_wc *wc, @@ -1494,6 +1546,14 @@ return; } + /* sanity checking for received data length */ + if (unlikely(wc->byte_len < len)) { + dev_err(queue->ctrl->ctrl.device, + "Unexpected nvme completion length(%d)\n", wc->byte_len); + nvme_rdma_error_recovery(queue->ctrl); + return; + } + ib_dma_sync_single_for_cpu(ibdev, qe->dma, len, DMA_FROM_DEVICE); /* * AEN requests are special as they don't time out and can @@ -1653,7 +1713,6 @@ complete(&queue->cm_done); return 0; case RDMA_CM_EVENT_REJECTED: - nvme_rdma_destroy_queue_ib(queue); cm_error = nvme_rdma_conn_rejected(queue, ev); break; case RDMA_CM_EVENT_ROUTE_ERROR: @@ -1691,6 +1750,18 @@ return 0; } +static void nvme_rdma_complete_timed_out(struct request *rq) +{ + struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); + struct nvme_rdma_queue *queue = req->queue; + + nvme_rdma_stop_queue(queue); + if (blk_mq_request_started(rq) && !blk_mq_request_completed(rq)) { + nvme_req(rq)->status = NVME_SC_HOST_ABORTED_CMD; + blk_mq_complete_request(rq); + } +} + static enum blk_eh_timer_return nvme_rdma_timeout(struct request *rq, bool reserved) { @@ -1701,29 +1772,29 @@ dev_warn(ctrl->ctrl.device, "I/O %d QID %d timeout\n", rq->tag, nvme_rdma_queue_idx(queue)); - /* - * Restart the timer if a controller reset is already scheduled. Any - * timed out commands would be handled before entering the connecting - * state. - */ - if (ctrl->ctrl.state == NVME_CTRL_RESETTING) - return BLK_EH_RESET_TIMER; - if (ctrl->ctrl.state != NVME_CTRL_LIVE) { /* - * Teardown immediately if controller times out while starting - * or we are already started error recovery. all outstanding - * requests are completed on shutdown, so we return BLK_EH_DONE. + * If we are resetting, connecting or deleting we should + * complete immediately because we may block controller + * teardown or setup sequence + * - ctrl disable/shutdown fabrics requests + * - connect requests + * - initialization admin requests + * - I/O requests that entered after unquiescing and + * the controller stopped responding + * + * All other requests should be cancelled by the error + * recovery work, so it's fine that we fail it here. */ - flush_work(&ctrl->err_work); - nvme_rdma_teardown_io_queues(ctrl, false); - nvme_rdma_teardown_admin_queue(ctrl, false); + nvme_rdma_complete_timed_out(rq); return BLK_EH_DONE; } - dev_warn(ctrl->ctrl.device, "starting error recovery\n"); + /* + * LIVE state should trigger the normal error recovery which will + * handle completing this request. + */ nvme_rdma_error_recovery(ctrl); - return BLK_EH_RESET_TIMER; } @@ -1885,9 +1956,6 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) { - cancel_work_sync(&ctrl->err_work); - cancel_delayed_work_sync(&ctrl->reconnect_work); - nvme_rdma_teardown_io_queues(ctrl, shutdown); blk_mq_quiesce_queue(ctrl->ctrl.admin_q); if (shutdown) @@ -1937,6 +2005,7 @@ .submit_async_event = nvme_rdma_submit_async_event, .delete_ctrl = nvme_rdma_delete_ctrl, .get_address = nvmf_get_address, + .stop_ctrl = nvme_rdma_stop_ctrl, }; /* @@ -2045,8 +2114,6 @@ dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISpcs\n", ctrl->ctrl.opts->subsysnqn, &ctrl->addr); - nvme_get_ctrl(&ctrl->ctrl); - mutex_lock(&nvme_rdma_ctrl_mutex); list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list); mutex_unlock(&nvme_rdma_ctrl_mutex); @@ -2056,6 +2123,7 @@ out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); nvme_put_ctrl(&ctrl->ctrl); + nvme_put_ctrl(&ctrl->ctrl); if (ret > 0) ret = -EIO; return ERR_PTR(ret); --- linux-oracle-5.4.0.orig/drivers/nvme/host/tcp.c +++ linux-oracle-5.4.0/drivers/nvme/host/tcp.c @@ -164,16 +164,14 @@ static inline bool nvme_tcp_has_inline_data(struct nvme_tcp_request *req) { struct request *rq; - unsigned int bytes; if (unlikely(nvme_tcp_async_req(req))) return false; /* async events don't have a request */ rq = blk_mq_rq_from_pdu(req); - bytes = blk_rq_payload_bytes(rq); - return rq_data_dir(rq) == WRITE && bytes && - bytes <= nvme_tcp_inline_data_size(req->queue); + return rq_data_dir(rq) == WRITE && req->data_len && + req->data_len <= nvme_tcp_inline_data_size(req->queue); } static inline struct page *nvme_tcp_req_cur_page(struct nvme_tcp_request *req) @@ -188,7 +186,7 @@ static inline size_t nvme_tcp_req_cur_length(struct nvme_tcp_request *req) { - return min_t(size_t, req->iter.bvec->bv_len - req->iter.iov_offset, + return min_t(size_t, iov_iter_single_seg_count(&req->iter), req->pdu_len - req->pdu_sent); } @@ -422,7 +420,8 @@ if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) return; - queue_work(nvme_wq, &to_tcp_ctrl(ctrl)->err_work); + dev_warn(ctrl->device, "starting error recovery\n"); + queue_work(nvme_reset_wq, &to_tcp_ctrl(ctrl)->err_work); } static int nvme_tcp_process_nvme_cqe(struct nvme_tcp_queue *queue, @@ -513,6 +512,13 @@ req->pdu_len = le32_to_cpu(pdu->r2t_length); req->pdu_sent = 0; + if (unlikely(!req->pdu_len)) { + dev_err(queue->ctrl->ctrl.device, + "req %d r2t len is %u, probably a bug...\n", + rq->tag, req->pdu_len); + return -EPROTO; + } + if (unlikely(req->data_sent + req->pdu_len > req->data_len)) { dev_err(queue->ctrl->ctrl.device, "req %d r2t len %u exceeded data len %u (%zu sent)\n", @@ -636,17 +642,9 @@ unsigned int *offset, size_t *len) { struct nvme_tcp_data_pdu *pdu = (void *)queue->pdu; - struct nvme_tcp_request *req; - struct request *rq; - - rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); - if (!rq) { - dev_err(queue->ctrl->ctrl.device, - "queue %d tag %#x not found\n", - nvme_tcp_queue_id(queue), pdu->command_id); - return -ENOENT; - } - req = blk_mq_rq_to_pdu(rq); + struct request *rq = + blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); + struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); while (true) { int recv_len, ret; @@ -786,11 +784,11 @@ { struct nvme_tcp_queue *queue; - read_lock(&sk->sk_callback_lock); + read_lock_bh(&sk->sk_callback_lock); queue = sk->sk_user_data; if (likely(queue && queue->rd_enabled)) queue_work_on(queue->io_cpu, nvme_tcp_wq, &queue->io_work); - read_unlock(&sk->sk_callback_lock); + read_unlock_bh(&sk->sk_callback_lock); } static void nvme_tcp_write_space(struct sock *sk) @@ -810,7 +808,7 @@ { struct nvme_tcp_queue *queue; - read_lock(&sk->sk_callback_lock); + read_lock_bh(&sk->sk_callback_lock); queue = sk->sk_user_data; if (!queue) goto done; @@ -832,7 +830,7 @@ queue->state_change(sk); done: - read_unlock(&sk->sk_callback_lock); + read_unlock_bh(&sk->sk_callback_lock); } static inline void nvme_tcp_done_send_req(struct nvme_tcp_queue *queue) @@ -842,7 +840,15 @@ static void nvme_tcp_fail_request(struct nvme_tcp_request *req) { - nvme_tcp_end_request(blk_mq_rq_from_pdu(req), NVME_SC_HOST_PATH_ERROR); + if (nvme_tcp_async_req(req)) { + union nvme_result res = {}; + + nvme_complete_async_event(&req->queue->ctrl->ctrl, + cpu_to_le16(NVME_SC_HOST_PATH_ERROR), &res); + } else { + nvme_tcp_end_request(blk_mq_rq_from_pdu(req), + NVME_SC_HOST_PATH_ERROR); + } } static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) @@ -861,12 +867,11 @@ else flags |= MSG_MORE; - /* can't zcopy slab pages */ - if (unlikely(PageSlab(page))) { - ret = sock_no_sendpage(queue->sock, page, offset, len, + if (sendpage_ok(page)) { + ret = kernel_sendpage(queue->sock, page, offset, len, flags); } else { - ret = kernel_sendpage(queue->sock, page, offset, len, + ret = sock_no_sendpage(queue->sock, page, offset, len, flags); } if (ret <= 0) @@ -965,7 +970,7 @@ int ret; struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_EOR }; struct kvec iov = { - .iov_base = &req->ddgst + req->offset, + .iov_base = (u8 *)&req->ddgst + req->offset, .iov_len = NVME_TCP_DIGEST_LENGTH - req->offset }; @@ -1054,7 +1059,12 @@ } else if (unlikely(result < 0)) { dev_err(queue->ctrl->ctrl.device, "failed to send request %d\n", result); - if (result != -EPIPE) + + /* + * Fail the request unless peer closed the connection, + * in which case error recovery flow will complete all. + */ + if ((result != -EPIPE) && (result != -ECONNRESET)) nvme_tcp_fail_request(queue->request); nvme_tcp_done_send_req(queue); return; @@ -1064,7 +1074,7 @@ if (result > 0) pending = true; - if (!pending) + if (!pending || !queue->rd_enabled) return; } while (!time_after(jiffies, deadline)); /* quota is exhausted */ @@ -1316,6 +1326,9 @@ } } + /* Set 10 seconds timeout for icresp recvmsg */ + queue->sock->sk->sk_rcvtimeo = 10 * HZ; + queue->sock->sk->sk_allocation = GFP_ATOMIC; if (!qid) n = 0; @@ -1374,22 +1387,7 @@ if (ret) goto err_init_connect; - queue->rd_enabled = true; set_bit(NVME_TCP_Q_ALLOCATED, &queue->flags); - nvme_tcp_init_recv_ctx(queue); - - write_lock_bh(&queue->sock->sk->sk_callback_lock); - queue->sock->sk->sk_user_data = queue; - queue->state_change = queue->sock->sk->sk_state_change; - queue->data_ready = queue->sock->sk->sk_data_ready; - queue->write_space = queue->sock->sk->sk_write_space; - queue->sock->sk->sk_data_ready = nvme_tcp_data_ready; - queue->sock->sk->sk_state_change = nvme_tcp_state_change; - queue->sock->sk->sk_write_space = nvme_tcp_write_space; -#ifdef CONFIG_NET_RX_BUSY_POLL - queue->sock->sk->sk_ll_usec = 1; -#endif - write_unlock_bh(&queue->sock->sk->sk_callback_lock); return 0; @@ -1406,7 +1404,7 @@ return ret; } -static void nvme_tcp_restore_sock_calls(struct nvme_tcp_queue *queue) +static void nvme_tcp_restore_sock_ops(struct nvme_tcp_queue *queue) { struct socket *sock = queue->sock; @@ -1421,7 +1419,7 @@ static void __nvme_tcp_stop_queue(struct nvme_tcp_queue *queue) { kernel_sock_shutdown(queue->sock, SHUT_RDWR); - nvme_tcp_restore_sock_calls(queue); + nvme_tcp_restore_sock_ops(queue); cancel_work_sync(&queue->io_work); } @@ -1432,25 +1430,45 @@ if (!test_and_clear_bit(NVME_TCP_Q_LIVE, &queue->flags)) return; - __nvme_tcp_stop_queue(queue); } +static void nvme_tcp_setup_sock_ops(struct nvme_tcp_queue *queue) +{ + write_lock_bh(&queue->sock->sk->sk_callback_lock); + queue->sock->sk->sk_user_data = queue; + queue->state_change = queue->sock->sk->sk_state_change; + queue->data_ready = queue->sock->sk->sk_data_ready; + queue->write_space = queue->sock->sk->sk_write_space; + queue->sock->sk->sk_data_ready = nvme_tcp_data_ready; + queue->sock->sk->sk_state_change = nvme_tcp_state_change; + queue->sock->sk->sk_write_space = nvme_tcp_write_space; +#ifdef CONFIG_NET_RX_BUSY_POLL + queue->sock->sk->sk_ll_usec = 1; +#endif + write_unlock_bh(&queue->sock->sk->sk_callback_lock); +} + static int nvme_tcp_start_queue(struct nvme_ctrl *nctrl, int idx) { struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); + struct nvme_tcp_queue *queue = &ctrl->queues[idx]; int ret; + queue->rd_enabled = true; + nvme_tcp_init_recv_ctx(queue); + nvme_tcp_setup_sock_ops(queue); + if (idx) ret = nvmf_connect_io_queue(nctrl, idx, false); else ret = nvmf_connect_admin_queue(nctrl); if (!ret) { - set_bit(NVME_TCP_Q_LIVE, &ctrl->queues[idx].flags); + set_bit(NVME_TCP_Q_LIVE, &queue->flags); } else { - if (test_bit(NVME_TCP_Q_ALLOCATED, &ctrl->queues[idx].flags)) - __nvme_tcp_stop_queue(&ctrl->queues[idx]); + if (test_bit(NVME_TCP_Q_ALLOCATED, &queue->flags)) + __nvme_tcp_stop_queue(queue); dev_err(nctrl->device, "failed to connect queue: %d ret=%d\n", idx, ret); } @@ -1500,6 +1518,7 @@ static void nvme_tcp_free_admin_queue(struct nvme_ctrl *ctrl) { if (to_tcp_ctrl(ctrl)->async_req.pdu) { + cancel_work_sync(&ctrl->async_event_work); nvme_tcp_free_async_req(to_tcp_ctrl(ctrl)); to_tcp_ctrl(ctrl)->async_req.pdu = NULL; } @@ -1636,10 +1655,13 @@ if (ret) return ret; - ctrl->queue_count = nr_io_queues + 1; - if (ctrl->queue_count < 2) - return 0; + if (nr_io_queues == 0) { + dev_err(ctrl->device, + "unable to set any I/O queues\n"); + return -ENOMEM; + } + ctrl->queue_count = nr_io_queues + 1; dev_info(ctrl->device, "creating %d I/O queues.\n", nr_io_queues); @@ -1678,18 +1700,38 @@ ret = PTR_ERR(ctrl->connect_q); goto out_free_tag_set; } - } else { - blk_mq_update_nr_hw_queues(ctrl->tagset, - ctrl->queue_count - 1); } ret = nvme_tcp_start_io_queues(ctrl); if (ret) goto out_cleanup_connect_q; + if (!new) { + nvme_start_freeze(ctrl); + nvme_start_queues(ctrl); + if (!nvme_wait_freeze_timeout(ctrl, NVME_IO_TIMEOUT)) { + /* + * If we timed out waiting for freeze we are likely to + * be stuck. Fail the controller initialization just + * to be safe. + */ + ret = -ENODEV; + nvme_unfreeze(ctrl); + goto out_wait_freeze_timed_out; + } + blk_mq_update_nr_hw_queues(ctrl->tagset, + ctrl->queue_count - 1); + nvme_unfreeze(ctrl); + } + return 0; +out_wait_freeze_timed_out: + nvme_stop_queues(ctrl); + nvme_sync_io_queues(ctrl); + nvme_tcp_stop_io_queues(ctrl); out_cleanup_connect_q: + nvme_cancel_tagset(ctrl); if (new) blk_cleanup_queue(ctrl->connect_q); out_free_tag_set: @@ -1751,12 +1793,16 @@ error = nvme_init_identify(ctrl); if (error) - goto out_stop_queue; + goto out_quiesce_queue; return 0; +out_quiesce_queue: + blk_mq_quiesce_queue(ctrl->admin_q); + blk_sync_queue(ctrl->admin_q); out_stop_queue: nvme_tcp_stop_queue(ctrl, 0); + nvme_cancel_admin_tagset(ctrl); out_cleanup_queue: if (new) blk_cleanup_queue(ctrl->admin_q); @@ -1775,6 +1821,7 @@ bool remove) { blk_mq_quiesce_queue(ctrl->admin_q); + blk_sync_queue(ctrl->admin_q); nvme_tcp_stop_queue(ctrl, 0); if (ctrl->admin_tagset) { blk_mq_tagset_busy_iter(ctrl->admin_tagset, @@ -1791,7 +1838,9 @@ { if (ctrl->queue_count <= 1) return; + blk_mq_quiesce_queue(ctrl->admin_q); nvme_stop_queues(ctrl); + nvme_sync_io_queues(ctrl); nvme_tcp_stop_io_queues(ctrl); if (ctrl->tagset) { blk_mq_tagset_busy_iter(ctrl->tagset, @@ -1866,10 +1915,18 @@ return 0; destroy_io: - if (ctrl->queue_count > 1) + if (ctrl->queue_count > 1) { + nvme_stop_queues(ctrl); + nvme_sync_io_queues(ctrl); + nvme_tcp_stop_io_queues(ctrl); + nvme_cancel_tagset(ctrl); nvme_tcp_destroy_io_queues(ctrl, new); + } destroy_admin: + blk_mq_quiesce_queue(ctrl->admin_q); + blk_sync_queue(ctrl->admin_q); nvme_tcp_stop_queue(ctrl, 0); + nvme_cancel_admin_tagset(ctrl); nvme_tcp_destroy_admin_queue(ctrl, new); return ret; } @@ -1905,6 +1962,7 @@ struct nvme_ctrl *ctrl = &tcp_ctrl->ctrl; nvme_stop_keep_alive(ctrl); + flush_work(&ctrl->async_event_work); nvme_tcp_teardown_io_queues(ctrl, false); /* unquiesce to fail fast pending requests */ nvme_start_queues(ctrl); @@ -1922,9 +1980,6 @@ static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown) { - cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work); - cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work); - nvme_tcp_teardown_io_queues(ctrl, shutdown); blk_mq_quiesce_queue(ctrl->admin_q); if (shutdown) @@ -1963,6 +2018,12 @@ nvme_tcp_reconnect_or_remove(ctrl); } +static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl) +{ + cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work); + cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work); +} + static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl) { struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); @@ -2039,40 +2100,52 @@ nvme_tcp_queue_request(&ctrl->async_req); } +static void nvme_tcp_complete_timed_out(struct request *rq) +{ + struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); + struct nvme_ctrl *ctrl = &req->queue->ctrl->ctrl; + + nvme_tcp_stop_queue(ctrl, nvme_tcp_queue_id(req->queue)); + if (blk_mq_request_started(rq) && !blk_mq_request_completed(rq)) { + nvme_req(rq)->status = NVME_SC_HOST_ABORTED_CMD; + blk_mq_complete_request(rq); + } +} + static enum blk_eh_timer_return nvme_tcp_timeout(struct request *rq, bool reserved) { struct nvme_tcp_request *req = blk_mq_rq_to_pdu(rq); - struct nvme_tcp_ctrl *ctrl = req->queue->ctrl; + struct nvme_ctrl *ctrl = &req->queue->ctrl->ctrl; struct nvme_tcp_cmd_pdu *pdu = req->pdu; - /* - * Restart the timer if a controller reset is already scheduled. Any - * timed out commands would be handled before entering the connecting - * state. - */ - if (ctrl->ctrl.state == NVME_CTRL_RESETTING) - return BLK_EH_RESET_TIMER; - - dev_warn(ctrl->ctrl.device, + dev_warn(ctrl->device, "queue %d: timeout request %#x type %d\n", nvme_tcp_queue_id(req->queue), rq->tag, pdu->hdr.type); - if (ctrl->ctrl.state != NVME_CTRL_LIVE) { + if (ctrl->state != NVME_CTRL_LIVE) { /* - * Teardown immediately if controller times out while starting - * or we are already started error recovery. all outstanding - * requests are completed on shutdown, so we return BLK_EH_DONE. + * If we are resetting, connecting or deleting we should + * complete immediately because we may block controller + * teardown or setup sequence + * - ctrl disable/shutdown fabrics requests + * - connect requests + * - initialization admin requests + * - I/O requests that entered after unquiescing and + * the controller stopped responding + * + * All other requests should be cancelled by the error + * recovery work, so it's fine that we fail it here. */ - flush_work(&ctrl->err_work); - nvme_tcp_teardown_io_queues(&ctrl->ctrl, false); - nvme_tcp_teardown_admin_queue(&ctrl->ctrl, false); + nvme_tcp_complete_timed_out(rq); return BLK_EH_DONE; } - dev_warn(ctrl->ctrl.device, "starting error recovery\n"); - nvme_tcp_error_recovery(&ctrl->ctrl); - + /* + * LIVE state should trigger the normal error recovery which will + * handle completing this request. + */ + nvme_tcp_error_recovery(ctrl); return BLK_EH_RESET_TIMER; } @@ -2085,7 +2158,9 @@ c->common.flags |= NVME_CMD_SGL_METABUF; - if (rq_data_dir(rq) == WRITE && req->data_len && + if (!blk_rq_nr_phys_segments(rq)) + nvme_tcp_set_sg_null(c); + else if (rq_data_dir(rq) == WRITE && req->data_len <= nvme_tcp_inline_data_size(queue)) nvme_tcp_set_sg_inline(queue, c, req->data_len); else @@ -2112,7 +2187,8 @@ req->data_sent = 0; req->pdu_len = 0; req->pdu_sent = 0; - req->data_len = blk_rq_payload_bytes(rq); + req->data_len = blk_rq_nr_phys_segments(rq) ? + blk_rq_payload_bytes(rq) : 0; req->curr_bio = rq->bio; if (rq_data_dir(rq) == WRITE && @@ -2256,6 +2332,7 @@ .submit_async_event = nvme_tcp_submit_async_event, .delete_ctrl = nvme_tcp_delete_ctrl, .get_address = nvmf_get_address, + .stop_ctrl = nvme_tcp_stop_ctrl, }; static bool @@ -2354,8 +2431,6 @@ dev_info(ctrl->ctrl.device, "new ctrl: NQN \"%s\", addr %pISp\n", ctrl->ctrl.opts->subsysnqn, &ctrl->addr); - nvme_get_ctrl(&ctrl->ctrl); - mutex_lock(&nvme_tcp_ctrl_mutex); list_add_tail(&ctrl->list, &nvme_tcp_ctrl_list); mutex_unlock(&nvme_tcp_ctrl_mutex); @@ -2365,6 +2440,7 @@ out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); nvme_put_ctrl(&ctrl->ctrl); + nvme_put_ctrl(&ctrl->ctrl); if (ret > 0) ret = -EIO; return ERR_PTR(ret); --- linux-oracle-5.4.0.orig/drivers/nvme/host/trace.h +++ linux-oracle-5.4.0/drivers/nvme/host/trace.h @@ -56,7 +56,7 @@ __field(u8, fctype) __field(u16, cid) __field(u32, nsid) - __field(u64, metadata) + __field(bool, metadata) __array(u8, cdw10, 24) ), TP_fast_assign( @@ -66,13 +66,13 @@ __entry->flags = cmd->common.flags; __entry->cid = cmd->common.command_id; __entry->nsid = le32_to_cpu(cmd->common.nsid); - __entry->metadata = le64_to_cpu(cmd->common.metadata); + __entry->metadata = !!blk_integrity_rq(req); __entry->fctype = cmd->fabrics.fctype; __assign_disk_name(__entry->disk, req->rq_disk); memcpy(__entry->cdw10, &cmd->common.cdw10, sizeof(__entry->cdw10)); ), - TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", + TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%x, cmd=(%s %s)", __entry->ctrl_id, __print_disk_name(__entry->disk), __entry->qid, __entry->cid, __entry->nsid, __entry->flags, __entry->metadata, @@ -127,15 +127,12 @@ ), TP_printk("nvme%d: NVME_AEN=%#08x [%s]", __entry->ctrl_id, __entry->result, - __print_symbolic(__entry->result, - aer_name(NVME_AER_NOTICE_NS_CHANGED), - aer_name(NVME_AER_NOTICE_ANA), - aer_name(NVME_AER_NOTICE_FW_ACT_STARTING), - aer_name(NVME_AER_NOTICE_DISC_CHANGED), - aer_name(NVME_AER_ERROR), - aer_name(NVME_AER_SMART), - aer_name(NVME_AER_CSS), - aer_name(NVME_AER_VS)) + __print_symbolic(__entry->result & 0x7, + aer_name(NVME_AER_ERROR), + aer_name(NVME_AER_SMART), + aer_name(NVME_AER_NOTICE), + aer_name(NVME_AER_CSS), + aer_name(NVME_AER_VS)) ) ); --- linux-oracle-5.4.0.orig/drivers/nvme/target/configfs.c +++ linux-oracle-5.4.0/drivers/nvme/target/configfs.c @@ -507,10 +507,18 @@ if (strtobool(page, &enable)) return -EINVAL; + /* + * take a global nvmet_config_sem because the disable routine has a + * window where it releases the subsys-lock, giving a chance to + * a parallel enable to concurrently execute causing the disable to + * have a misaccounting of the ns percpu_ref. + */ + down_write(&nvmet_config_sem); if (enable) ret = nvmet_ns_enable(ns); else nvmet_ns_disable(ns); + up_write(&nvmet_config_sem); return ret ? ret : count; } @@ -1148,6 +1156,8 @@ { struct nvmet_port *port = to_nvmet_port(item); + /* Let inflight controllers teardown complete */ + flush_scheduled_work(); list_del(&port->global_entry); kfree(port->ana_state); --- linux-oracle-5.4.0.orig/drivers/nvme/target/core.c +++ linux-oracle-5.4.0/drivers/nvme/target/core.c @@ -369,6 +369,9 @@ static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl) { + if (unlikely(ctrl->kato == 0)) + return; + pr_debug("ctrl %d start keep-alive timer for %d secs\n", ctrl->cntlid, ctrl->kato); @@ -378,6 +381,9 @@ static void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl) { + if (unlikely(ctrl->kato == 0)) + return; + pr_debug("ctrl %d stop keep-alive\n", ctrl->cntlid); cancel_delayed_work_sync(&ctrl->ka_work); @@ -555,7 +561,8 @@ } else { struct nvmet_ns *old; - list_for_each_entry_rcu(old, &subsys->namespaces, dev_link) { + list_for_each_entry_rcu(old, &subsys->namespaces, dev_link, + lockdep_is_held(&subsys->lock)) { BUG_ON(ns->nsid == old->nsid); if (ns->nsid < old->nsid) break; @@ -702,6 +709,8 @@ static void __nvmet_req_complete(struct nvmet_req *req, u16 status) { + struct nvmet_ns *ns = req->ns; + if (!req->sq->sqhd_disabled) nvmet_update_sq_head(req); req->cqe->sq_id = cpu_to_le16(req->sq->qid); @@ -712,15 +721,17 @@ trace_nvmet_req_complete(req); - if (req->ns) - nvmet_put_namespace(req->ns); req->ops->queue_response(req); + if (ns) + nvmet_put_namespace(ns); } void nvmet_req_complete(struct nvmet_req *req, u16 status) { + struct nvmet_sq *sq = req->sq; + __nvmet_req_complete(req, status); - percpu_ref_put(&req->sq->ref); + percpu_ref_put(&sq->ref); } EXPORT_SYMBOL_GPL(nvmet_req_complete); @@ -871,8 +882,6 @@ req->error_loc = NVMET_NO_ERROR_LOC; req->error_slba = 0; - trace_nvmet_req_init(req, req->cmd); - /* no support for fused commands yet */ if (unlikely(flags & (NVME_CMD_FUSE_FIRST | NVME_CMD_FUSE_SECOND))) { req->error_loc = offsetof(struct nvme_common_command, flags); @@ -906,6 +915,8 @@ if (status) goto fail; + trace_nvmet_req_init(req, req->cmd); + if (unlikely(!percpu_ref_tryget_live(&sq->ref))) { status = NVME_SC_INVALID_FIELD | NVME_SC_DNR; goto fail; @@ -1024,9 +1035,20 @@ { lockdep_assert_held(&ctrl->lock); - if (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || - nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES || - nvmet_cc_mps(ctrl->cc) != 0 || + /* + * Only I/O controllers should verify iosqes,iocqes. + * Strictly speaking, the spec says a discovery controller + * should verify iosqes,iocqes are zeroed, however that + * would break backwards compatibility, so don't enforce it. + */ + if (ctrl->subsys->type != NVME_NQN_DISC && + (nvmet_cc_iosqes(ctrl->cc) != NVME_NVM_IOSQES || + nvmet_cc_iocqes(ctrl->cc) != NVME_NVM_IOCQES)) { + ctrl->csts = NVME_CSTS_CFS; + return; + } + + if (nvmet_cc_mps(ctrl->cc) != 0 || nvmet_cc_ams(ctrl->cc) != 0 || nvmet_cc_css(ctrl->cc) != 0) { ctrl->csts = NVME_CSTS_CFS; @@ -1041,7 +1063,8 @@ * in case a host died before it enabled the controller. Hence, simply * reset the keep alive timer when the controller is enabled. */ - mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ); + if (ctrl->kato) + mod_delayed_work(system_wq, &ctrl->ka_work, ctrl->kato * HZ); } static void nvmet_clear_ctrl(struct nvmet_ctrl *ctrl) @@ -1084,19 +1107,19 @@ ctrl->cap |= NVMET_QUEUE_SIZE - 1; } -u16 nvmet_ctrl_find_get(const char *subsysnqn, const char *hostnqn, u16 cntlid, - struct nvmet_req *req, struct nvmet_ctrl **ret) +struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn, + const char *hostnqn, u16 cntlid, + struct nvmet_req *req) { + struct nvmet_ctrl *ctrl = NULL; struct nvmet_subsys *subsys; - struct nvmet_ctrl *ctrl; - u16 status = 0; subsys = nvmet_find_get_subsys(req->port, subsysnqn); if (!subsys) { pr_warn("connect request for invalid subsystem %s!\n", subsysnqn); req->cqe->result.u32 = IPO_IATTR_CONNECT_DATA(subsysnqn); - return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; + goto out; } mutex_lock(&subsys->lock); @@ -1109,20 +1132,21 @@ if (!kref_get_unless_zero(&ctrl->ref)) continue; - *ret = ctrl; - goto out; + /* ctrl found */ + goto found; } } + ctrl = NULL; /* ctrl not found */ pr_warn("could not find controller %d for subsys %s / host %s\n", cntlid, subsysnqn, hostnqn); req->cqe->result.u32 = IPO_IATTR_CONNECT_DATA(cntlid); - status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; -out: +found: mutex_unlock(&subsys->lock); nvmet_subsys_put(subsys); - return status; +out: + return ctrl; } u16 nvmet_check_ctrl_status(struct nvmet_req *req, struct nvme_command *cmd) @@ -1174,7 +1198,8 @@ ctrl->p2p_client = get_device(req->p2p_client); - list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link) + list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link, + lockdep_is_held(&ctrl->subsys->lock)) nvmet_p2pmem_ns_add_p2p(ctrl, ns); } --- linux-oracle-5.4.0.orig/drivers/nvme/target/fabrics-cmd.c +++ linux-oracle-5.4.0/drivers/nvme/target/fabrics-cmd.c @@ -105,6 +105,7 @@ u16 qid = le16_to_cpu(c->qid); u16 sqsize = le16_to_cpu(c->sqsize); struct nvmet_ctrl *old; + u16 ret; old = cmpxchg(&req->sq->ctrl, NULL, ctrl); if (old) { @@ -115,7 +116,9 @@ if (!sqsize) { pr_warn("queue size zero!\n"); req->error_loc = offsetof(struct nvmf_connect_command, sqsize); - return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; + req->cqe->result.u32 = IPO_IATTR_CONNECT_SQE(sqsize); + ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; + goto err; } /* note: convert queue size from 0's-based value to 1's-based value */ @@ -128,16 +131,19 @@ } if (ctrl->ops->install_queue) { - u16 ret = ctrl->ops->install_queue(req->sq); - + ret = ctrl->ops->install_queue(req->sq); if (ret) { pr_err("failed to install queue %d cntlid %d ret %x\n", - qid, ret, ctrl->cntlid); - return ret; + qid, ctrl->cntlid, ret); + goto err; } } return 0; + +err: + req->sq->ctrl = NULL; + return ret; } static void nvmet_execute_admin_connect(struct nvmet_req *req) @@ -176,6 +182,8 @@ goto out; } + d->subsysnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; + d->hostnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; status = nvmet_alloc_ctrl(d->subsysnqn, d->hostnqn, req, le32_to_cpu(c->kato), &ctrl); if (status) { @@ -207,7 +215,7 @@ { struct nvmf_connect_command *c = &req->cmd->connect; struct nvmf_connect_data *d; - struct nvmet_ctrl *ctrl = NULL; + struct nvmet_ctrl *ctrl; u16 qid = le16_to_cpu(c->qid); u16 status = 0; @@ -231,11 +239,14 @@ goto out; } - status = nvmet_ctrl_find_get(d->subsysnqn, d->hostnqn, - le16_to_cpu(d->cntlid), - req, &ctrl); - if (status) + d->subsysnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; + d->hostnqn[NVMF_NQN_FIELD_LEN - 1] = '\0'; + ctrl = nvmet_ctrl_find_get(d->subsysnqn, d->hostnqn, + le16_to_cpu(d->cntlid), req); + if (!ctrl) { + status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR; goto out; + } if (unlikely(qid > ctrl->subsys->max_qid)) { pr_warn("invalid queue id (%d)\n", qid); @@ -245,11 +256,11 @@ } status = nvmet_install_queue(ctrl, req); - if (status) { - /* pass back cntlid that had the issue of installing queue */ - req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid); + if (status) goto out_ctrl_put; - } + + /* pass back cntlid for successful completion */ + req->cqe->result.u16 = cpu_to_le16(ctrl->cntlid); pr_debug("adding queue %d to ctrl %d.\n", qid, ctrl->cntlid); --- linux-oracle-5.4.0.orig/drivers/nvme/target/fc.c +++ linux-oracle-5.4.0/drivers/nvme/target/fc.c @@ -796,6 +796,9 @@ int idx; bool needrandom = true; + if (!tgtport->pe) + return NULL; + assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); if (!assoc) return NULL; @@ -1362,8 +1365,10 @@ else { queue = nvmet_fc_alloc_target_queue(iod->assoc, 0, be16_to_cpu(rqst->assoc_cmd.sqsize)); - if (!queue) + if (!queue) { ret = VERR_QUEUE_ALLOC_FAIL; + nvmet_fc_tgt_a_put(iod->assoc); + } } } @@ -1495,20 +1500,20 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport, struct nvmet_fc_ls_iod *iod) { - struct fcnvme_ls_disconnect_rqst *rqst = - (struct fcnvme_ls_disconnect_rqst *)iod->rqstbuf; - struct fcnvme_ls_disconnect_acc *acc = - (struct fcnvme_ls_disconnect_acc *)iod->rspbuf; + struct fcnvme_ls_disconnect_assoc_rqst *rqst = + (struct fcnvme_ls_disconnect_assoc_rqst *)iod->rqstbuf; + struct fcnvme_ls_disconnect_assoc_acc *acc = + (struct fcnvme_ls_disconnect_assoc_acc *)iod->rspbuf; struct nvmet_fc_tgt_assoc *assoc; int ret = 0; memset(acc, 0, sizeof(*acc)); - if (iod->rqstdatalen < sizeof(struct fcnvme_ls_disconnect_rqst)) + if (iod->rqstdatalen < sizeof(struct fcnvme_ls_disconnect_assoc_rqst)) ret = VERR_DISCONN_LEN; else if (rqst->desc_list_len != fcnvme_lsdesc_len( - sizeof(struct fcnvme_ls_disconnect_rqst))) + sizeof(struct fcnvme_ls_disconnect_assoc_rqst))) ret = VERR_DISCONN_RQST_LEN; else if (rqst->associd.desc_tag != cpu_to_be32(FCNVME_LSDESC_ASSOC_ID)) ret = VERR_ASSOC_ID; @@ -1523,8 +1528,11 @@ fcnvme_lsdesc_len( sizeof(struct fcnvme_lsdesc_disconn_cmd))) ret = VERR_DISCONN_CMD_LEN; - else if ((rqst->discon_cmd.scope != FCNVME_DISCONN_ASSOCIATION) && - (rqst->discon_cmd.scope != FCNVME_DISCONN_CONNECTION)) + /* + * As the standard changed on the LS, check if old format and scope + * something other than Association (e.g. 0). + */ + else if (rqst->discon_cmd.rsvd8[0]) ret = VERR_DISCONN_SCOPE; else { /* match an active association */ @@ -1556,8 +1564,8 @@ nvmet_fc_format_rsp_hdr(acc, FCNVME_LS_ACC, fcnvme_lsdesc_len( - sizeof(struct fcnvme_ls_disconnect_acc)), - FCNVME_LS_DISCONNECT); + sizeof(struct fcnvme_ls_disconnect_assoc_acc)), + FCNVME_LS_DISCONNECT_ASSOC); /* release get taken in nvmet_fc_find_target_assoc */ nvmet_fc_tgt_a_put(iod->assoc); @@ -1632,7 +1640,7 @@ /* Creates an IO Queue/Connection */ nvmet_fc_ls_create_connection(tgtport, iod); break; - case FCNVME_LS_DISCONNECT: + case FCNVME_LS_DISCONNECT_ASSOC: /* Terminate a Queue/Connection or the Association */ nvmet_fc_ls_disconnect(tgtport, iod); break; @@ -1994,9 +2002,9 @@ return; if (fcpreq->fcp_error || fcpreq->transferred_length != fcpreq->transfer_length) { - spin_lock(&fod->flock); + spin_lock_irqsave(&fod->flock, flags); fod->abort = true; - spin_unlock(&fod->flock); + spin_unlock_irqrestore(&fod->flock, flags); nvmet_req_complete(&fod->req, NVME_SC_INTERNAL); return; @@ -2152,13 +2160,6 @@ int ret; /* - * if there is no nvmet mapping to the targetport there - * shouldn't be requests. just terminate them. - */ - if (!tgtport->pe) - goto transport_error; - - /* * Fused commands are currently not supported in the linux * implementation. * @@ -2185,6 +2186,8 @@ fod->req.cmd = &fod->cmdiubuf.sqe; fod->req.cqe = &fod->rspiubuf.cqe; + if (!tgtport->pe) + goto transport_error; fod->req.port = tgtport->pe->port; /* clear any response payload */ @@ -2299,7 +2302,7 @@ /* validate iu, so the connection id can be used to find the queue */ if ((cmdiubuf_len != sizeof(*cmdiu)) || - (cmdiu->scsi_id != NVME_CMD_SCSI_ID) || + (cmdiu->format_id != NVME_CMD_FORMAT_ID) || (cmdiu->fc_id != NVME_CMD_FC_ID) || (be16_to_cpu(cmdiu->iu_len) != (sizeof(*cmdiu)/4))) return -EIO; --- linux-oracle-5.4.0.orig/drivers/nvme/target/fcloop.c +++ linux-oracle-5.4.0/drivers/nvme/target/fcloop.c @@ -431,10 +431,11 @@ struct fcloop_fcpreq *tfcp_req = container_of(work, struct fcloop_fcpreq, fcp_rcv_work); struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq; + unsigned long flags; int ret = 0; bool aborted = false; - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); switch (tfcp_req->inistate) { case INI_IO_START: tfcp_req->inistate = INI_IO_ACTIVE; @@ -443,11 +444,11 @@ aborted = true; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); if (unlikely(aborted)) ret = -ECANCELED; @@ -468,8 +469,9 @@ container_of(work, struct fcloop_fcpreq, abort_rcv_work); struct nvmefc_fcp_req *fcpreq; bool completed = false; + unsigned long flags; - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; switch (tfcp_req->inistate) { case INI_IO_ABORTED: @@ -478,11 +480,11 @@ completed = true; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); if (unlikely(completed)) { /* remove reference taken in original abort downcall */ @@ -494,9 +496,9 @@ nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport, &tfcp_req->tgt_fcp_req); - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->fcpreq = NULL; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED); /* call_host_done releases reference for abort downcall */ @@ -512,11 +514,12 @@ struct fcloop_fcpreq *tfcp_req = container_of(work, struct fcloop_fcpreq, tio_done_work); struct nvmefc_fcp_req *fcpreq; + unsigned long flags; - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; tfcp_req->inistate = INI_IO_COMPLETED; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); fcloop_call_host_done(fcpreq, tfcp_req, tfcp_req->status); } @@ -620,13 +623,14 @@ u32 rsplen = 0, xfrlen = 0; int fcp_err = 0, active, aborted; u8 op = tgt_fcpreq->op; + unsigned long flags; - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); fcpreq = tfcp_req->fcpreq; active = tfcp_req->active; aborted = tfcp_req->aborted; tfcp_req->active = true; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); if (unlikely(active)) /* illegal - call while i/o active */ @@ -634,9 +638,9 @@ if (unlikely(aborted)) { /* target transport has aborted i/o prior */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->active = false; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); tgt_fcpreq->transferred_length = 0; tgt_fcpreq->fcp_error = -ECANCELED; tgt_fcpreq->done(tgt_fcpreq); @@ -693,9 +697,9 @@ break; } - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->active = false; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); tgt_fcpreq->transferred_length = xfrlen; tgt_fcpreq->fcp_error = fcp_err; @@ -709,15 +713,16 @@ struct nvmefc_tgt_fcp_req *tgt_fcpreq) { struct fcloop_fcpreq *tfcp_req = tgt_fcp_req_to_fcpreq(tgt_fcpreq); + unsigned long flags; /* * mark aborted only in case there were 2 threads in transport * (one doing io, other doing abort) and only kills ops posted * after the abort request */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); tfcp_req->aborted = true; - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); tfcp_req->status = NVME_SC_INTERNAL; @@ -753,6 +758,7 @@ struct fcloop_ini_fcpreq *inireq = fcpreq->private; struct fcloop_fcpreq *tfcp_req; bool abortio = true; + unsigned long flags; spin_lock(&inireq->inilock); tfcp_req = inireq->tfcp_req; @@ -765,7 +771,7 @@ return; /* break initiator/target relationship for io */ - spin_lock_irq(&tfcp_req->reqlock); + spin_lock_irqsave(&tfcp_req->reqlock, flags); switch (tfcp_req->inistate) { case INI_IO_START: case INI_IO_ACTIVE: @@ -775,11 +781,11 @@ abortio = false; break; default: - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); WARN_ON(1); return; } - spin_unlock_irq(&tfcp_req->reqlock); + spin_unlock_irqrestore(&tfcp_req->reqlock, flags); if (abortio) /* leave the reference while the work item is scheduled */ --- linux-oracle-5.4.0.orig/drivers/nvme/target/io-cmd-bdev.c +++ linux-oracle-5.4.0/drivers/nvme/target/io-cmd-bdev.c @@ -36,7 +36,7 @@ */ id->nsfeat |= 1 << 4; /* NPWG = Namespace Preferred Write Granularity. 0's based */ - id->npwg = lpp0b; + id->npwg = to0based(bdev_io_min(bdev) / bdev_logical_block_size(bdev)); /* NPWA = Namespace Preferred Write Alignment. 0's based */ id->npwa = id->npwg; /* NPDG = Namespace Preferred Deallocate Granularity. 0's based */ --- linux-oracle-5.4.0.orig/drivers/nvme/target/io-cmd-file.c +++ linux-oracle-5.4.0/drivers/nvme/target/io-cmd-file.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "nvmet.h" #define NVMET_MAX_MPOOL_BVEC 16 @@ -38,9 +39,11 @@ ns->file = filp_open(ns->device_path, flags, 0); if (IS_ERR(ns->file)) { - pr_err("failed to open file %s: (%ld)\n", - ns->device_path, PTR_ERR(ns->file)); - return PTR_ERR(ns->file); + ret = PTR_ERR(ns->file); + pr_err("failed to open file %s: (%d)\n", + ns->device_path, ret); + ns->file = NULL; + return ret; } ret = vfs_getattr(&ns->file->f_path, @@ -252,7 +255,8 @@ if (req->ns->buffered_io) { if (likely(!req->f.mpool_alloc) && - nvmet_file_execute_io(req, IOCB_NOWAIT)) + (req->ns->file->f_mode & FMODE_NOWAIT) && + nvmet_file_execute_io(req, IOCB_NOWAIT)) return; nvmet_file_submit_buffered_io(req); } else --- linux-oracle-5.4.0.orig/drivers/nvme/target/loop.c +++ linux-oracle-5.4.0/drivers/nvme/target/loop.c @@ -252,7 +252,8 @@ static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl) { - clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags); + if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) + return; nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); blk_cleanup_queue(ctrl->ctrl.admin_q); blk_cleanup_queue(ctrl->ctrl.fabrics_q); @@ -288,6 +289,7 @@ clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[i].flags); nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); } + ctrl->ctrl.queue_count = 1; } static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) @@ -394,6 +396,7 @@ return 0; out_cleanup_queue: + clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags); blk_cleanup_queue(ctrl->ctrl.admin_q); out_cleanup_fabrics_q: blk_cleanup_queue(ctrl->ctrl.fabrics_q); @@ -619,8 +622,6 @@ dev_info(ctrl->ctrl.device, "new ctrl: \"%s\"\n", ctrl->ctrl.opts->subsysnqn); - nvme_get_ctrl(&ctrl->ctrl); - changed = nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_LIVE); WARN_ON_ONCE(!changed); @@ -638,6 +639,7 @@ kfree(ctrl->queues); out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); + nvme_put_ctrl(&ctrl->ctrl); out_put_ctrl: nvme_put_ctrl(&ctrl->ctrl); if (ret > 0) --- linux-oracle-5.4.0.orig/drivers/nvme/target/nvmet.h +++ linux-oracle-5.4.0/drivers/nvme/target/nvmet.h @@ -394,8 +394,9 @@ void nvmet_update_cc(struct nvmet_ctrl *ctrl, u32 new); u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, struct nvmet_req *req, u32 kato, struct nvmet_ctrl **ctrlp); -u16 nvmet_ctrl_find_get(const char *subsysnqn, const char *hostnqn, u16 cntlid, - struct nvmet_req *req, struct nvmet_ctrl **ret); +struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn, + const char *hostnqn, u16 cntlid, + struct nvmet_req *req); void nvmet_ctrl_put(struct nvmet_ctrl *ctrl); u16 nvmet_check_ctrl_status(struct nvmet_req *req, struct nvme_command *cmd); --- linux-oracle-5.4.0.orig/drivers/nvme/target/rdma.c +++ linux-oracle-5.4.0/drivers/nvme/target/rdma.c @@ -75,6 +75,7 @@ struct nvmet_rdma_queue { struct rdma_cm_id *cm_id; + struct ib_qp *qp; struct nvmet_port *port; struct ib_cq *cq; atomic_t sq_wr_avail; @@ -427,12 +428,8 @@ return 0; out_free: - while (--i >= 0) { - struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; - - list_del(&rsp->free_list); - nvmet_rdma_free_rsp(ndev, rsp); - } + while (--i >= 0) + nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); kfree(queue->rsps); out: return ret; @@ -443,12 +440,8 @@ struct nvmet_rdma_device *ndev = queue->dev; int i, nr_rsps = queue->recv_queue_size * 2; - for (i = 0; i < nr_rsps; i++) { - struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; - - list_del(&rsp->free_list); - nvmet_rdma_free_rsp(ndev, rsp); - } + for (i = 0; i < nr_rsps; i++) + nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); kfree(queue->rsps); } @@ -464,7 +457,7 @@ if (ndev->srq) ret = ib_post_srq_recv(ndev->srq, &cmd->wr, NULL); else - ret = ib_post_recv(cmd->queue->cm_id->qp, &cmd->wr, NULL); + ret = ib_post_recv(cmd->queue->qp, &cmd->wr, NULL); if (unlikely(ret)) pr_err("post_recv cmd failed\n"); @@ -503,7 +496,7 @@ atomic_add(1 + rsp->n_rdma, &queue->sq_wr_avail); if (rsp->n_rdma) { - rdma_rw_ctx_destroy(&rsp->rw, queue->cm_id->qp, + rdma_rw_ctx_destroy(&rsp->rw, queue->qp, queue->cm_id->port_num, rsp->req.sg, rsp->req.sg_cnt, nvmet_data_dir(&rsp->req)); } @@ -587,7 +580,7 @@ WARN_ON(rsp->n_rdma <= 0); atomic_add(rsp->n_rdma, &queue->sq_wr_avail); - rdma_rw_ctx_destroy(&rsp->rw, queue->cm_id->qp, + rdma_rw_ctx_destroy(&rsp->rw, queue->qp, queue->cm_id->port_num, rsp->req.sg, rsp->req.sg_cnt, nvmet_data_dir(&rsp->req)); rsp->n_rdma = 0; @@ -742,7 +735,7 @@ } if (nvmet_rdma_need_data_in(rsp)) { - if (rdma_rw_ctx_post(&rsp->rw, queue->cm_id->qp, + if (rdma_rw_ctx_post(&rsp->rw, queue->qp, queue->cm_id->port_num, &rsp->read_cqe, NULL)) nvmet_req_complete(&rsp->req, NVME_SC_DATA_XFER_ERROR); } else { @@ -1025,6 +1018,7 @@ pr_err("failed to create_qp ret= %d\n", ret); goto err_destroy_cq; } + queue->qp = queue->cm_id->qp; atomic_set(&queue->sq_wr_avail, qp_attr.cap.max_send_wr); @@ -1053,11 +1047,10 @@ static void nvmet_rdma_destroy_queue_ib(struct nvmet_rdma_queue *queue) { - struct ib_qp *qp = queue->cm_id->qp; - - ib_drain_qp(qp); - rdma_destroy_id(queue->cm_id); - ib_destroy_qp(qp); + ib_drain_qp(queue->qp); + if (queue->cm_id) + rdma_destroy_id(queue->cm_id); + ib_destroy_qp(queue->qp); ib_free_cq(queue->cq); } @@ -1291,9 +1284,12 @@ ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn); if (ret) { - schedule_work(&queue->release_work); - /* Destroying rdma_cm id is not needed here */ - return 0; + /* + * Don't destroy the cm_id in free path, as we implicitly + * destroy the cm_id here with non-zero ret code. + */ + queue->cm_id = NULL; + goto free_queue; } mutex_lock(&nvmet_rdma_queue_mutex); @@ -1302,6 +1298,8 @@ return 0; +free_queue: + nvmet_rdma_free_queue(queue); put_device: kref_put(&ndev->ref, nvmet_rdma_free_dev); @@ -1345,6 +1343,16 @@ spin_lock_irqsave(&queue->state_lock, flags); switch (queue->state) { case NVMET_RDMA_Q_CONNECTING: + while (!list_empty(&queue->rsp_wait_list)) { + struct nvmet_rdma_rsp *rsp; + + rsp = list_first_entry(&queue->rsp_wait_list, + struct nvmet_rdma_rsp, + wait_list); + list_del(&rsp->wait_list); + nvmet_rdma_put_rsp(rsp); + } + fallthrough; case NVMET_RDMA_Q_LIVE: queue->state = NVMET_RDMA_Q_DISCONNECTING; disconnect = true; --- linux-oracle-5.4.0.orig/drivers/nvme/target/tcp.c +++ linux-oracle-5.4.0/drivers/nvme/target/tcp.c @@ -18,6 +18,7 @@ #include "nvmet.h" #define NVMET_TCP_DEF_INLINE_DATA_SIZE (4 * PAGE_SIZE) +#define NVMET_TCP_MAXH2CDATA 0x400000 /* 16M arbitrary limit */ #define NVMET_TCP_RECV_BUDGET 8 #define NVMET_TCP_SEND_BUDGET 8 @@ -150,6 +151,11 @@ static inline u16 nvmet_tcp_cmd_tag(struct nvmet_tcp_queue *queue, struct nvmet_tcp_cmd *cmd) { + if (unlikely(!queue->nr_cmds)) { + /* We didn't allocate cmds yet, send 0xffff */ + return USHRT_MAX; + } + return cmd - queue->cmds; } @@ -287,7 +293,7 @@ length = cmd->pdu_len; cmd->nr_mapped = DIV_ROUND_UP(length, PAGE_SIZE); offset = cmd->rbytes_done; - cmd->sg_idx = DIV_ROUND_UP(offset, PAGE_SIZE); + cmd->sg_idx = offset / PAGE_SIZE; sg_offset = offset % PAGE_SIZE; sg = &cmd->req.sg[cmd->sg_idx]; @@ -300,6 +306,7 @@ length -= iov_len; sg = sg_next(sg); iov++; + sg_offset = 0; } iov_iter_kvec(&cmd->recv_msg.msg_iter, READ, cmd->iov, @@ -315,6 +322,15 @@ kernel_sock_shutdown(queue->sock, SHUT_RDWR); } +static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status) +{ + queue->rcv_state = NVMET_TCP_RECV_ERR; + if (status == -EPIPE || status == -ECONNRESET) + kernel_sock_shutdown(queue->sock, SHUT_RDWR); + else + nvmet_tcp_fatal_error(queue); +} + static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd) { struct nvme_sgl_desc *sgl = &cmd->req.cmd->common.dptr.sgl; @@ -515,7 +531,7 @@ return 1; } -static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd) +static int nvmet_try_send_data(struct nvmet_tcp_cmd *cmd, bool last_in_batch) { struct nvmet_tcp_queue *queue = cmd->queue; int ret; @@ -523,9 +539,15 @@ while (cmd->cur_sg) { struct page *page = sg_page(cmd->cur_sg); u32 left = cmd->cur_sg->length - cmd->offset; + int flags = MSG_DONTWAIT; + + if ((!last_in_batch && cmd->queue->send_list_len) || + cmd->wbytes_done + left < cmd->req.transfer_len || + queue->data_digest || !queue->nvme_sq.sqhd_disabled) + flags |= MSG_MORE; ret = kernel_sendpage(cmd->queue->sock, page, cmd->offset, - left, MSG_DONTWAIT | MSG_MORE); + left, flags); if (ret <= 0) return ret; @@ -619,10 +641,11 @@ static int nvmet_try_send_ddgst(struct nvmet_tcp_cmd *cmd) { struct nvmet_tcp_queue *queue = cmd->queue; + int left = NVME_TCP_DIGEST_LENGTH - cmd->offset; struct msghdr msg = { .msg_flags = MSG_DONTWAIT }; struct kvec iov = { - .iov_base = &cmd->exp_ddgst + cmd->offset, - .iov_len = NVME_TCP_DIGEST_LENGTH - cmd->offset + .iov_base = (u8 *)&cmd->exp_ddgst + cmd->offset, + .iov_len = left }; int ret; @@ -631,6 +654,10 @@ return ret; cmd->offset += ret; + left -= ret; + + if (left) + return -EAGAIN; if (queue->nvme_sq.sqhd_disabled) { cmd->queue->snd_cmd = NULL; @@ -660,7 +687,7 @@ } if (cmd->state == NVMET_TCP_SEND_DATA) { - ret = nvmet_try_send_data(cmd); + ret = nvmet_try_send_data(cmd, last_in_batch); if (ret <= 0) goto done_send; } @@ -697,11 +724,15 @@ for (i = 0; i < budget; i++) { ret = nvmet_tcp_try_send_one(queue, i == budget - 1); - if (ret <= 0) + if (unlikely(ret < 0)) { + nvmet_tcp_socket_error(queue, ret); + goto done; + } else if (ret == 0) { break; + } (*sends)++; } - +done: return ret; } @@ -761,6 +792,7 @@ pr_err("bad nvme-tcp pdu length (%d)\n", le32_to_cpu(icreq->hdr.plen)); nvmet_tcp_fatal_error(queue); + return -EPROTO; } if (icreq->pfv != NVME_TCP_PFV_1_0) { @@ -788,7 +820,7 @@ icresp->hdr.pdo = 0; icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen); icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0); - icresp->maxdata = cpu_to_le32(0xffff); /* FIXME: support r2t */ + icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA); icresp->cpda = 0; if (queue->hdr_digest) icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE; @@ -799,15 +831,11 @@ iov.iov_len = sizeof(*icresp); ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len); if (ret < 0) - goto free_crypto; + return ret; /* queue removal will cleanup */ queue->state = NVMET_TCP_Q_LIVE; nvmet_prepare_receive_pdu(queue); return 0; -free_crypto: - if (queue->hdr_digest || queue->data_digest) - nvmet_tcp_free_crypto(queue); - return ret; } static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue, @@ -840,20 +868,43 @@ { struct nvme_tcp_data_pdu *data = &queue->pdu.data; struct nvmet_tcp_cmd *cmd; + unsigned int exp_data_len; - cmd = &queue->cmds[data->ttag]; + if (likely(queue->nr_cmds)) { + if (unlikely(data->ttag >= queue->nr_cmds)) { + pr_err("queue %d: received out of bound ttag %u, nr_cmds %u\n", + queue->idx, data->ttag, queue->nr_cmds); + nvmet_tcp_fatal_error(queue); + return -EPROTO; + } + cmd = &queue->cmds[data->ttag]; + } else { + cmd = &queue->connect; + } if (le32_to_cpu(data->data_offset) != cmd->rbytes_done) { pr_err("ttag %u unexpected data offset %u (expected %u)\n", data->ttag, le32_to_cpu(data->data_offset), cmd->rbytes_done); /* FIXME: use path and transport errors */ - nvmet_req_complete(&cmd->req, - NVME_SC_INVALID_FIELD | NVME_SC_DNR); + nvmet_tcp_fatal_error(queue); return -EPROTO; } + exp_data_len = le32_to_cpu(data->hdr.plen) - + nvmet_tcp_hdgst_len(queue) - + nvmet_tcp_ddgst_len(queue) - + sizeof(*data); + cmd->pdu_len = le32_to_cpu(data->data_length); + if (unlikely(cmd->pdu_len != exp_data_len || + cmd->pdu_len == 0 || + cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { + pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); + /* FIXME: use proper transport errors */ + nvmet_tcp_fatal_error(queue); + return -EPROTO; + } cmd->pdu_recv = 0; nvmet_tcp_map_pdu_iovec(cmd); queue->cmd = cmd; @@ -1005,7 +1056,7 @@ } if (queue->hdr_digest && - nvmet_tcp_verify_hdgst(queue, &queue->pdu, queue->offset)) { + nvmet_tcp_verify_hdgst(queue, &queue->pdu, hdr->hlen)) { nvmet_tcp_fatal_error(queue); /* fatal */ return -EPROTO; } @@ -1140,11 +1191,15 @@ for (i = 0; i < budget; i++) { ret = nvmet_tcp_try_recv_one(queue); - if (ret <= 0) + if (unlikely(ret < 0)) { + nvmet_tcp_socket_error(queue, ret); + goto done; + } else if (ret == 0) { break; + } (*recvs)++; } - +done: return ret; } @@ -1169,27 +1224,16 @@ pending = false; ret = nvmet_tcp_try_recv(queue, NVMET_TCP_RECV_BUDGET, &ops); - if (ret > 0) { + if (ret > 0) pending = true; - } else if (ret < 0) { - if (ret == -EPIPE || ret == -ECONNRESET) - kernel_sock_shutdown(queue->sock, SHUT_RDWR); - else - nvmet_tcp_fatal_error(queue); + else if (ret < 0) return; - } ret = nvmet_tcp_try_send(queue, NVMET_TCP_SEND_BUDGET, &ops); - if (ret > 0) { - /* transmitted message/data */ + if (ret > 0) pending = true; - } else if (ret < 0) { - if (ret == -EPIPE || ret == -ECONNRESET) - kernel_sock_shutdown(queue->sock, SHUT_RDWR); - else - nvmet_tcp_fatal_error(queue); + else if (ret < 0) return; - } } while (pending && ops < NVMET_TCP_IO_WORK_BUDGET); @@ -1328,6 +1372,7 @@ static void nvmet_tcp_release_queue_work(struct work_struct *w) { + struct page *page; struct nvmet_tcp_queue *queue = container_of(w, struct nvmet_tcp_queue, release_work); @@ -1347,6 +1392,8 @@ nvmet_tcp_free_crypto(queue); ida_simple_remove(&nvmet_tcp_queue_ida, queue->idx); + page = virt_to_head_page(queue->pf_cache.va); + __page_frag_cache_drain(page, queue->pf_cache.pagecnt_bias); kfree(queue); } @@ -1387,17 +1434,19 @@ { struct nvmet_tcp_queue *queue; - write_lock_bh(&sk->sk_callback_lock); + read_lock_bh(&sk->sk_callback_lock); queue = sk->sk_user_data; if (!queue) goto done; switch (sk->sk_state) { + case TCP_FIN_WAIT2: + case TCP_LAST_ACK: + break; case TCP_FIN_WAIT1: case TCP_CLOSE_WAIT: case TCP_CLOSE: /* FALLTHRU */ - sk->sk_user_data = NULL; nvmet_tcp_schedule_release_queue(queue); break; default: @@ -1405,7 +1454,7 @@ queue->idx, sk->sk_state); } done: - write_unlock_bh(&sk->sk_callback_lock); + read_unlock_bh(&sk->sk_callback_lock); } static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) @@ -1650,6 +1699,17 @@ return ret; } +static void nvmet_tcp_destroy_port_queues(struct nvmet_tcp_port *port) +{ + struct nvmet_tcp_queue *queue; + + mutex_lock(&nvmet_tcp_queue_mutex); + list_for_each_entry(queue, &nvmet_tcp_queue_list, queue_list) + if (queue->port == port) + kernel_sock_shutdown(queue->sock, SHUT_RDWR); + mutex_unlock(&nvmet_tcp_queue_mutex); +} + static void nvmet_tcp_remove_port(struct nvmet_port *nport) { struct nvmet_tcp_port *port = nport->priv; @@ -1659,6 +1719,11 @@ port->sock->sk->sk_user_data = NULL; write_unlock_bh(&port->sock->sk->sk_callback_lock); cancel_work_sync(&port->accept_work); + /* + * Destroy the remaining queues, which are not belong to any + * controller yet. + */ + nvmet_tcp_destroy_port_queues(port); sock_release(port->sock); kfree(port); @@ -1686,8 +1751,10 @@ } queue->nr_cmds = sq->size * 2; - if (nvmet_tcp_alloc_cmds(queue)) + if (nvmet_tcp_alloc_cmds(queue)) { + queue->nr_cmds = 0; return NVME_SC_INTERNAL; + } return 0; } @@ -1724,7 +1791,8 @@ { int ret; - nvmet_tcp_wq = alloc_workqueue("nvmet_tcp_wq", WQ_HIGHPRI, 0); + nvmet_tcp_wq = alloc_workqueue("nvmet_tcp_wq", + WQ_MEM_RECLAIM | WQ_HIGHPRI, 0); if (!nvmet_tcp_wq) return -ENOMEM; @@ -1752,6 +1820,7 @@ flush_scheduled_work(); destroy_workqueue(nvmet_tcp_wq); + ida_destroy(&nvmet_tcp_queue_ida); } module_init(nvmet_tcp_init); --- linux-oracle-5.4.0.orig/drivers/nvme/target/trace.c +++ linux-oracle-5.4.0/drivers/nvme/target/trace.c @@ -195,7 +195,7 @@ return ret; } -const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl) +const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id) { const char *ret = trace_seq_buffer_ptr(p); @@ -208,8 +208,8 @@ * If we can know the extra data of the connect command in this stage, * we can update this print statement later. */ - if (ctrl) - trace_seq_printf(p, "%d", ctrl->cntlid); + if (ctrl_id) + trace_seq_printf(p, "%d", ctrl_id); else trace_seq_printf(p, "_"); trace_seq_putc(p, 0); --- linux-oracle-5.4.0.orig/drivers/nvme/target/trace.h +++ linux-oracle-5.4.0/drivers/nvme/target/trace.h @@ -32,33 +32,32 @@ nvmet_trace_parse_nvm_cmd(p, opcode, cdw10) : \ nvmet_trace_parse_admin_cmd(p, opcode, cdw10))) -const char *nvmet_trace_ctrl_name(struct trace_seq *p, struct nvmet_ctrl *ctrl); -#define __print_ctrl_name(ctrl) \ - nvmet_trace_ctrl_name(p, ctrl) +const char *nvmet_trace_ctrl_id(struct trace_seq *p, u16 ctrl_id); +#define __print_ctrl_id(ctrl_id) \ + nvmet_trace_ctrl_id(p, ctrl_id) const char *nvmet_trace_disk_name(struct trace_seq *p, char *name); #define __print_disk_name(name) \ nvmet_trace_disk_name(p, name) #ifndef TRACE_HEADER_MULTI_READ -static inline struct nvmet_ctrl *nvmet_req_to_ctrl(struct nvmet_req *req) +static inline u16 nvmet_req_to_ctrl_id(struct nvmet_req *req) { - return req->sq->ctrl; + /* + * The queue and controller pointers are not valid until an association + * has been established. + */ + if (!req->sq || !req->sq->ctrl) + return 0; + return req->sq->ctrl->cntlid; } -static inline void __assign_disk_name(char *name, struct nvmet_req *req, - bool init) +static inline void __assign_req_name(char *name, struct nvmet_req *req) { - struct nvmet_ctrl *ctrl = nvmet_req_to_ctrl(req); - struct nvmet_ns *ns; - - if ((init && req->sq->qid) || (!init && req->cq->qid)) { - ns = nvmet_find_namespace(ctrl, req->cmd->rw.nsid); - strncpy(name, ns->device_path, DISK_NAME_LEN); - return; - } - - memset(name, 0, DISK_NAME_LEN); + if (req->ns) + strncpy(name, req->ns->device_path, DISK_NAME_LEN); + else + memset(name, 0, DISK_NAME_LEN); } #endif @@ -67,7 +66,7 @@ TP_ARGS(req, cmd), TP_STRUCT__entry( __field(struct nvme_command *, cmd) - __field(struct nvmet_ctrl *, ctrl) + __field(u16, ctrl_id) __array(char, disk, DISK_NAME_LEN) __field(int, qid) __field(u16, cid) @@ -80,8 +79,8 @@ ), TP_fast_assign( __entry->cmd = cmd; - __entry->ctrl = nvmet_req_to_ctrl(req); - __assign_disk_name(__entry->disk, req, true); + __entry->ctrl_id = nvmet_req_to_ctrl_id(req); + __assign_req_name(__entry->disk, req); __entry->qid = req->sq->qid; __entry->cid = cmd->common.command_id; __entry->opcode = cmd->common.opcode; @@ -94,7 +93,7 @@ ), TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " "meta=%#llx, cmd=(%s, %s)", - __print_ctrl_name(__entry->ctrl), + __print_ctrl_id(__entry->ctrl_id), __print_disk_name(__entry->disk), __entry->qid, __entry->cid, __entry->nsid, __entry->flags, __entry->metadata, @@ -108,7 +107,7 @@ TP_PROTO(struct nvmet_req *req), TP_ARGS(req), TP_STRUCT__entry( - __field(struct nvmet_ctrl *, ctrl) + __field(u16, ctrl_id) __array(char, disk, DISK_NAME_LEN) __field(int, qid) __field(int, cid) @@ -116,15 +115,15 @@ __field(u16, status) ), TP_fast_assign( - __entry->ctrl = nvmet_req_to_ctrl(req); + __entry->ctrl_id = nvmet_req_to_ctrl_id(req); __entry->qid = req->cq->qid; __entry->cid = req->cqe->command_id; __entry->result = le64_to_cpu(req->cqe->result.u64); __entry->status = le16_to_cpu(req->cqe->status) >> 1; - __assign_disk_name(__entry->disk, req, false); + __assign_req_name(__entry->disk, req); ), TP_printk("nvmet%s: %sqid=%d, cmdid=%u, res=%#llx, status=%#x", - __print_ctrl_name(__entry->ctrl), + __print_ctrl_id(__entry->ctrl_id), __print_disk_name(__entry->disk), __entry->qid, __entry->cid, __entry->result, __entry->status) --- linux-oracle-5.4.0.orig/drivers/nvmem/core.c +++ linux-oracle-5.4.0/drivers/nvmem/core.c @@ -110,7 +110,7 @@ list_del(&cell->node); mutex_unlock(&nvmem_mutex); of_node_put(cell->np); - kfree(cell->name); + kfree_const(cell->name); kfree(cell); } @@ -130,9 +130,9 @@ blocking_notifier_call_chain(&nvmem_notifier, NVMEM_CELL_ADD, cell); } -static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, - const struct nvmem_cell_info *info, - struct nvmem_cell *cell) +static int nvmem_cell_info_to_nvmem_cell_nodup(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info, + struct nvmem_cell *cell) { cell->nvmem = nvmem; cell->offset = info->offset; @@ -149,13 +149,30 @@ if (!IS_ALIGNED(cell->offset, nvmem->stride)) { dev_err(&nvmem->dev, "cell %s unaligned to nvmem stride %d\n", - cell->name, nvmem->stride); + cell->name ?: "", nvmem->stride); return -EINVAL; } return 0; } +static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, + const struct nvmem_cell_info *info, + struct nvmem_cell *cell) +{ + int err; + + err = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, cell); + if (err) + return err; + + cell->name = kstrdup_const(info->name, GFP_KERNEL); + if (!cell->name) + return -ENOMEM; + + return 0; +} + /** * nvmem_add_cells() - Add cell information to an nvmem device * @@ -297,17 +314,21 @@ for_each_child_of_node(parent, child) { addr = of_get_property(child, "reg", &len); - if (!addr || (len < 2 * sizeof(u32))) { + if (!addr) + continue; + if (len < 2 * sizeof(u32)) { dev_err(dev, "nvmem: invalid reg on %pOF\n", child); + of_node_put(child); return -EINVAL; } cell = kzalloc(sizeof(*cell), GFP_KERNEL); - if (!cell) + if (!cell) { + of_node_put(child); return -ENOMEM; + } cell->nvmem = nvmem; - cell->np = of_node_get(child); cell->offset = be32_to_cpup(addr++); cell->bytes = be32_to_cpup(addr); cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); @@ -327,11 +348,13 @@ dev_err(dev, "cell %s unaligned to nvmem stride %d\n", cell->name, nvmem->stride); /* Cells already added will be freed later. */ - kfree(cell->name); + kfree_const(cell->name); kfree(cell); + of_node_put(child); return -EINVAL; } + cell->np = of_node_get(child); nvmem_cell_add(cell); } @@ -416,7 +439,7 @@ if (config->cells) { rval = nvmem_add_cells(nvmem, config->cells, config->ncells); if (rval) - goto err_teardown_compat; + goto err_remove_cells; } rval = nvmem_add_cells_from_table(nvmem); @@ -433,7 +456,6 @@ err_remove_cells: nvmem_device_remove_all_cells(nvmem); -err_teardown_compat: if (config->compat) nvmem_sysfs_remove_compat(nvmem, config); err_device_del: @@ -662,13 +684,13 @@ EXPORT_SYMBOL_GPL(nvmem_device_put); /** - * devm_nvmem_device_get() - Get nvmem cell of device form a given id + * devm_nvmem_device_get() - Get nvmem device of device form a given id * * @dev: Device that requests the nvmem device. * @id: name id for the requested nvmem device. * - * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_cell - * on success. The nvmem_cell will be freed by the automatically once the + * Return: ERR_PTR() on error or a valid pointer to a struct nvmem_device + * on success. The nvmem_device will be freed by the automatically once the * device is freed. */ struct nvmem_device *devm_nvmem_device_get(struct device *dev, const char *id) @@ -931,7 +953,8 @@ *p-- = 0; /* clear msb bits if any leftover in the last byte */ - *p &= GENMASK((cell->nbits%BITS_PER_BYTE) - 1, 0); + if (cell->nbits % BITS_PER_BYTE) + *p &= GENMASK((cell->nbits % BITS_PER_BYTE) - 1, 0); } static int __nvmem_cell_read(struct nvmem_device *nvmem, @@ -1060,6 +1083,8 @@ return -EINVAL; if (cell->bit_offset || cell->nbits) { + if (len != BITS_TO_BYTES(cell->nbits) && len != cell->bytes) + return -EINVAL; buf = nvmem_cell_prepare_write_buffer(cell, buf, len); if (IS_ERR(buf)) return PTR_ERR(buf); @@ -1172,7 +1197,7 @@ if (!nvmem) return -EINVAL; - rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell); + rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); if (rc) return rc; @@ -1202,7 +1227,7 @@ if (!nvmem) return -EINVAL; - rc = nvmem_cell_info_to_nvmem_cell(nvmem, info, &cell); + rc = nvmem_cell_info_to_nvmem_cell_nodup(nvmem, info, &cell); if (rc) return rc; --- linux-oracle-5.4.0.orig/drivers/nvmem/imx-ocotp.c +++ linux-oracle-5.4.0/drivers/nvmem/imx-ocotp.c @@ -433,7 +433,7 @@ }; static const struct ocotp_params imx6sll_params = { - .nregs = 128, + .nregs = 80, .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, }; @@ -445,13 +445,13 @@ }; static const struct ocotp_params imx6ul_params = { - .nregs = 128, + .nregs = 144, .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, }; static const struct ocotp_params imx6ull_params = { - .nregs = 64, + .nregs = 80, .bank_address_words = 0, .set_timing = imx_ocotp_set_imx6_timing, }; @@ -521,6 +521,10 @@ if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); + clk_prepare_enable(priv->clk); + imx_ocotp_clr_err_if_set(priv->base); + clk_disable_unprepare(priv->clk); + priv->params = of_device_get_match_data(&pdev->dev); imx_ocotp_nvmem_config.size = 4 * priv->params->nregs; imx_ocotp_nvmem_config.dev = dev; --- linux-oracle-5.4.0.orig/drivers/nvmem/meson-efuse.c +++ linux-oracle-5.4.0/drivers/nvmem/meson-efuse.c @@ -17,15 +17,25 @@ static int meson_efuse_read(void *context, unsigned int offset, void *val, size_t bytes) { - return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset, - bytes, 0, 0, 0); + struct meson_sm_firmware *fw = context; + int ret; + + ret = meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, + bytes, 0, 0, 0); + + return ret < 0 ? ret : 0; } static int meson_efuse_write(void *context, unsigned int offset, void *val, size_t bytes) { - return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset, - bytes, 0, 0, 0); + struct meson_sm_firmware *fw = context; + int ret; + + ret = meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, + bytes, 0, 0, 0); + + return ret < 0 ? ret : 0; } static const struct of_device_id meson_efuse_match[] = { @@ -37,35 +47,29 @@ static int meson_efuse_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct meson_sm_firmware *fw; + struct device_node *sm_np; struct nvmem_device *nvmem; struct nvmem_config *econfig; struct clk *clk; unsigned int size; - int ret; - clk = devm_clk_get(dev, NULL); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get efuse gate"); - return ret; + sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); + if (!sm_np) { + dev_err(&pdev->dev, "no secure-monitor node\n"); + return -ENODEV; } - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "failed to enable gate"); - return ret; - } - - ret = devm_add_action_or_reset(dev, - (void(*)(void *))clk_disable_unprepare, - clk); - if (ret) { - dev_err(dev, "failed to add disable callback"); - return ret; - } + fw = meson_sm_get(sm_np); + of_node_put(sm_np); + if (!fw) + return -EPROBE_DEFER; + + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to get efuse gate"); - if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { + if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { dev_err(dev, "failed to get max user"); return -EINVAL; } @@ -81,6 +85,7 @@ econfig->reg_read = meson_efuse_read; econfig->reg_write = meson_efuse_write; econfig->size = size; + econfig->priv = fw; nvmem = devm_nvmem_register(&pdev->dev, econfig); --- linux-oracle-5.4.0.orig/drivers/nvmem/nvmem-sysfs.c +++ linux-oracle-5.4.0/drivers/nvmem/nvmem-sysfs.c @@ -56,6 +56,9 @@ count = round_down(count, nvmem->word_size); + if (!nvmem->reg_read) + return -EPERM; + rc = nvmem->reg_read(nvmem->priv, pos, buf, count); if (rc) @@ -90,6 +93,9 @@ count = round_down(count, nvmem->word_size); + if (!nvmem->reg_write) + return -EPERM; + rc = nvmem->reg_write(nvmem->priv, pos, buf, count); if (rc) --- linux-oracle-5.4.0.orig/drivers/nvmem/qfprom.c +++ linux-oracle-5.4.0/drivers/nvmem/qfprom.c @@ -27,25 +27,11 @@ return 0; } -static int qfprom_reg_write(void *context, - unsigned int reg, void *_val, size_t bytes) -{ - struct qfprom_priv *priv = context; - u8 *val = _val; - int i = 0, words = bytes; - - while (words--) - writeb(*val++, priv->base + reg + i++); - - return 0; -} - static struct nvmem_config econfig = { .name = "qfprom", .stride = 1, .word_size = 1, .reg_read = qfprom_reg_read, - .reg_write = qfprom_reg_write, }; static int qfprom_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/of/Kconfig +++ linux-oracle-5.4.0/drivers/of/Kconfig @@ -103,4 +103,8 @@ config OF_NUMA bool +config OF_DMA_DEFAULT_COHERENT + # arches should select this if DMA is coherent by default for OF devices + bool + endif # OF --- linux-oracle-5.4.0.orig/drivers/of/address.c +++ linux-oracle-5.4.0/drivers/of/address.c @@ -692,7 +692,7 @@ if (ret < 0) return of_get_parent(np); - return of_node_get(args.np); + return args.np; } u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) @@ -998,11 +998,17 @@ * @np: device node * * It returns true if "dma-coherent" property was found - * for this device in DT. + * for this device in the DT, or if DMA is coherent by + * default for OF devices on the current platform. */ bool of_dma_is_coherent(struct device_node *np) { - struct device_node *node = of_node_get(np); + struct device_node *node; + + if (IS_ENABLED(CONFIG_OF_DMA_DEFAULT_COHERENT)) + return true; + + node = of_node_get(np); while (node) { if (of_property_read_bool(node, "dma-coherent")) { --- linux-oracle-5.4.0.orig/drivers/of/base.c +++ linux-oracle-5.4.0/drivers/of/base.c @@ -306,7 +306,7 @@ * @prev: Previous node or NULL to start iteration * of_node_put() will be called on it * - * Returns a node pointer with refcount incremented, use + * Return: A node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_all_nodes(struct device_node *prev) @@ -367,7 +367,7 @@ return (u32)phys_id == cpu; } -/** +/* * Checks if the given "prop_name" property holds the physical id of the * core/thread corresponding to the logical cpu 'cpu'. If 'thread' is not * NULL, local thread number within the core is returned in it. @@ -436,7 +436,7 @@ * before booting secondary cores. This function uses arch_match_cpu_phys_id * which can be overridden by architecture specific implementation. * - * Returns a node pointer for the logical cpu with refcount incremented, use + * Return: A node pointer for the logical cpu with refcount incremented, use * of_node_put() on it when done. Returns NULL if not found. */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) @@ -456,8 +456,8 @@ * * @cpu_node: Pointer to the device_node for CPU. * - * Returns the logical CPU number of the given CPU device_node. - * Returns -ENODEV if the CPU is not found. + * Return: The logical CPU number of the given CPU device_node or -ENODEV if the + * CPU is not found. */ int of_cpu_node_to_id(struct device_node *cpu_node) { @@ -478,6 +478,42 @@ EXPORT_SYMBOL(of_cpu_node_to_id); /** + * of_get_cpu_state_node - Get CPU's idle state node at the given index + * + * @cpu_node: The device node for the CPU + * @index: The index in the list of the idle states + * + * Two generic methods can be used to describe a CPU's idle states, either via + * a flattened description through the "cpu-idle-states" binding or via the + * hierarchical layout, using the "power-domains" and the "domain-idle-states" + * bindings. This function check for both and returns the idle state node for + * the requested index. + * + * Return: An idle state node if found at @index. The refcount is incremented + * for it, so call of_node_put() on it when done. Returns NULL if not found. + */ +struct device_node *of_get_cpu_state_node(struct device_node *cpu_node, + int index) +{ + struct of_phandle_args args; + int err; + + err = of_parse_phandle_with_args(cpu_node, "power-domains", + "#power-domain-cells", 0, &args); + if (!err) { + struct device_node *state_node = + of_parse_phandle(args.np, "domain-idle-states", index); + + of_node_put(args.np); + if (state_node) + return state_node; + } + + return of_parse_phandle(cpu_node, "cpu-idle-states", index); +} +EXPORT_SYMBOL(of_get_cpu_state_node); + +/** * __of_device_is_compatible() - Check if the node matches given constraints * @device: pointer to node * @compat: required compatible string, NULL or "" for any match @@ -587,7 +623,7 @@ * of_machine_is_compatible - Test root of device tree for a given compatible value * @compat: compatible string to look for in root node's compatible property. * - * Returns a positive integer if the root node has the given value in its + * Return: A positive integer if the root node has the given value in its * compatible property. */ int of_machine_is_compatible(const char *compat) @@ -609,7 +645,7 @@ * * @device: Node to check for availability, with locks already held * - * Returns true if the status property is absent or set to "okay" or "ok", + * Return: True if the status property is absent or set to "okay" or "ok", * false otherwise */ static bool __of_device_is_available(const struct device_node *device) @@ -637,7 +673,7 @@ * * @device: Node to check for availability * - * Returns true if the status property is absent or set to "okay" or "ok", + * Return: True if the status property is absent or set to "okay" or "ok", * false otherwise */ bool of_device_is_available(const struct device_node *device) @@ -658,7 +694,7 @@ * * @device: Node to check for endianness * - * Returns true if the device has a "big-endian" property, or if the kernel + * Return: True if the device has a "big-endian" property, or if the kernel * was compiled for BE *and* the device has a "native-endian" property. * Returns false otherwise. * @@ -677,11 +713,11 @@ EXPORT_SYMBOL(of_device_is_big_endian); /** - * of_get_parent - Get a node's parent if any - * @node: Node to get parent + * of_get_parent - Get a node's parent if any + * @node: Node to get parent * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_get_parent(const struct device_node *node) { @@ -699,15 +735,15 @@ EXPORT_SYMBOL(of_get_parent); /** - * of_get_next_parent - Iterate to a node's parent - * @node: Node to get parent of + * of_get_next_parent - Iterate to a node's parent + * @node: Node to get parent of * - * This is like of_get_parent() except that it drops the - * refcount on the passed node, making it suitable for iterating - * through a node's parents. + * This is like of_get_parent() except that it drops the + * refcount on the passed node, making it suitable for iterating + * through a node's parents. * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_get_next_parent(struct device_node *node) { @@ -745,13 +781,13 @@ child = __of_get_next_child(parent, child)) /** - * of_get_next_child - Iterate a node childs - * @node: parent node - * @prev: previous child of the parent node, or NULL to get first - * - * Returns a node pointer with refcount incremented, use of_node_put() on - * it when done. Returns NULL when prev is the last child. Decrements the - * refcount of prev. + * of_get_next_child - Iterate a node childs + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first + * + * Return: A node pointer with refcount incremented, use of_node_put() on + * it when done. Returns NULL when prev is the last child. Decrements the + * refcount of prev. */ struct device_node *of_get_next_child(const struct device_node *node, struct device_node *prev) @@ -767,12 +803,12 @@ EXPORT_SYMBOL(of_get_next_child); /** - * of_get_next_available_child - Find the next available child node - * @node: parent node - * @prev: previous child of the parent node, or NULL to get first + * of_get_next_available_child - Find the next available child node + * @node: parent node + * @prev: previous child of the parent node, or NULL to get first * - * This function is like of_get_next_child(), except that it - * automatically skips any disabled nodes (i.e. status = "disabled"). + * This function is like of_get_next_child(), except that it + * automatically skips any disabled nodes (i.e. status = "disabled"). */ struct device_node *of_get_next_available_child(const struct device_node *node, struct device_node *prev) @@ -798,12 +834,12 @@ EXPORT_SYMBOL(of_get_next_available_child); /** - * of_get_next_cpu_node - Iterate on cpu nodes - * @prev: previous child of the /cpus node, or NULL to get first + * of_get_next_cpu_node - Iterate on cpu nodes + * @prev: previous child of the /cpus node, or NULL to get first * - * Returns a cpu node pointer with refcount incremented, use of_node_put() - * on it when done. Returns NULL when prev is the last child. Decrements - * the refcount of prev. + * Return: A cpu node pointer with refcount incremented, use of_node_put() + * on it when done. Returns NULL when prev is the last child. Decrements + * the refcount of prev. */ struct device_node *of_get_next_cpu_node(struct device_node *prev) { @@ -842,7 +878,7 @@ * Lookup child node whose compatible property contains the given compatible * string. * - * Returns a node pointer with refcount incremented, use of_node_put() on it + * Return: a node pointer with refcount incremented, use of_node_put() on it * when done; or NULL if not found. */ struct device_node *of_get_compatible_child(const struct device_node *parent, @@ -860,15 +896,15 @@ EXPORT_SYMBOL(of_get_compatible_child); /** - * of_get_child_by_name - Find the child node by name for a given parent - * @node: parent node - * @name: child name to look for. - * - * This function looks for child node for given matching name - * - * Returns a node pointer if found, with refcount incremented, use - * of_node_put() on it when done. - * Returns NULL if node is not found. + * of_get_child_by_name - Find the child node by name for a given parent + * @node: parent node + * @name: child name to look for. + * + * This function looks for child node for given matching name + * + * Return: A node pointer if found, with refcount incremented, use + * of_node_put() on it when done. + * Returns NULL if node is not found. */ struct device_node *of_get_child_by_name(const struct device_node *node, const char *name) @@ -919,22 +955,22 @@ } /** - * of_find_node_opts_by_path - Find a node matching a full OF path - * @path: Either the full path to match, or if the path does not - * start with '/', the name of a property of the /aliases - * node (an alias). In the case of an alias, the node - * matching the alias' value will be returned. - * @opts: Address of a pointer into which to store the start of - * an options string appended to the end of the path with - * a ':' separator. - * - * Valid paths: - * /foo/bar Full path - * foo Valid alias - * foo/bar Valid alias + relative path + * of_find_node_opts_by_path - Find a node matching a full OF path + * @path: Either the full path to match, or if the path does not + * start with '/', the name of a property of the /aliases + * node (an alias). In the case of an alias, the node + * matching the alias' value will be returned. + * @opts: Address of a pointer into which to store the start of + * an options string appended to the end of the path with + * a ':' separator. + * + * Valid paths: + * * /foo/bar Full path + * * foo Valid alias + * * foo/bar Valid alias + relative path * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_node_opts_by_path(const char *path, const char **opts) { @@ -952,10 +988,10 @@ /* The path could begin with an alias */ if (*path != '/') { int len; - const char *p = separator; + const char *p = strchrnul(path, '/'); - if (!p) - p = strchrnul(path, '/'); + if (separator && separator < p) + p = separator; len = p - path; /* of_aliases must not be NULL */ @@ -984,15 +1020,15 @@ EXPORT_SYMBOL(of_find_node_opts_by_path); /** - * of_find_node_by_name - Find a node by its "name" property - * @from: The node to start searching from or NULL; the node + * of_find_node_by_name - Find a node by its "name" property + * @from: The node to start searching from or NULL; the node * you pass will not be searched, only the next one * will. Typically, you pass what the previous call * returned. of_node_put() will be called on @from. - * @name: The name string to match against + * @name: The name string to match against * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_node_by_name(struct device_node *from, const char *name) @@ -1011,16 +1047,16 @@ EXPORT_SYMBOL(of_find_node_by_name); /** - * of_find_node_by_type - Find a node by its "device_type" property - * @from: The node to start searching from, or NULL to start searching + * of_find_node_by_type - Find a node by its "device_type" property + * @from: The node to start searching from, or NULL to start searching * the entire device tree. The node you pass will not be * searched, only the next one will; typically, you pass * what the previous call returned. of_node_put() will be * called on from for you. - * @type: The type string to match against + * @type: The type string to match against * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_node_by_type(struct device_node *from, const char *type) @@ -1039,18 +1075,18 @@ EXPORT_SYMBOL(of_find_node_by_type); /** - * of_find_compatible_node - Find a node based on type and one of the + * of_find_compatible_node - Find a node based on type and one of the * tokens in its "compatible" property - * @from: The node to start searching from or NULL, the node - * you pass will not be searched, only the next one - * will; typically, you pass what the previous call - * returned. of_node_put() will be called on it - * @type: The type string to match "device_type" or NULL to ignore - * @compatible: The string to match to one of the tokens in the device - * "compatible" list. + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @type: The type string to match "device_type" or NULL to ignore + * @compatible: The string to match to one of the tokens in the device + * "compatible" list. * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_compatible_node(struct device_node *from, const char *type, const char *compatible) @@ -1070,16 +1106,16 @@ EXPORT_SYMBOL(of_find_compatible_node); /** - * of_find_node_with_property - Find a node which has a property with - * the given name. - * @from: The node to start searching from or NULL, the node - * you pass will not be searched, only the next one - * will; typically, you pass what the previous call - * returned. of_node_put() will be called on it - * @prop_name: The name of the property to look for. + * of_find_node_with_property - Find a node which has a property with + * the given name. + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @prop_name: The name of the property to look for. * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_node_with_property(struct device_node *from, const char *prop_name) @@ -1128,10 +1164,10 @@ /** * of_match_node - Tell if a device_node has a matching of_match structure - * @matches: array of of device match structures to search in - * @node: the of device structure to match against + * @matches: array of of device match structures to search in + * @node: the of device structure to match against * - * Low level utility function used by device matching. + * Low level utility function used by device matching. */ const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) @@ -1147,17 +1183,17 @@ EXPORT_SYMBOL(of_match_node); /** - * of_find_matching_node_and_match - Find a node based on an of_device_id - * match table. - * @from: The node to start searching from or NULL, the node - * you pass will not be searched, only the next one - * will; typically, you pass what the previous call - * returned. of_node_put() will be called on it - * @matches: array of of device match structures to search in - * @match Updated to point at the matches entry which matched + * of_find_matching_node_and_match - Find a node based on an of_device_id + * match table. + * @from: The node to start searching from or NULL, the node + * you pass will not be searched, only the next one + * will; typically, you pass what the previous call + * returned. of_node_put() will be called on it + * @matches: array of of device match structures to search in + * @match: Updated to point at the matches entry which matched * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. */ struct device_node *of_find_matching_node_and_match(struct device_node *from, const struct of_device_id *matches, @@ -1196,7 +1232,7 @@ * It does this by stripping the manufacturer prefix (as delimited by a ',') * from the first entry in the compatible list property. * - * This routine returns 0 on success, <0 on failure. + * Return: This routine returns 0 on success, <0 on failure. */ int of_modalias_node(struct device_node *node, char *modalias, int len) { @@ -1216,7 +1252,7 @@ * of_find_node_by_phandle - Find a node given a phandle * @handle: phandle of the node to find * - * Returns a node pointer with refcount incremented, use + * Return: A node pointer with refcount incremented, use * of_node_put() on it when done. */ struct device_node *of_find_node_by_phandle(phandle handle) @@ -1366,9 +1402,14 @@ * property data length */ if (it->cur + count > it->list_end) { - pr_err("%pOF: %s = %d found %d\n", - it->parent, it->cells_name, - count, it->cell_count); + if (it->cells_name) + pr_err("%pOF: %s = %d found %td\n", + it->parent, it->cells_name, + count, it->list_end - it->cur); + else + pr_err("%pOF: phandle %s needs %d, found %td\n", + it->parent, of_node_full_name(it->node), + count, it->list_end - it->cur); goto err; } } @@ -1464,7 +1505,7 @@ * @index: For properties holding a table of phandles, this is the index into * the table * - * Returns the device_node pointer with refcount incremented. Use + * Return: The device_node pointer with refcount incremented. Use * of_node_put() on it when done. */ struct device_node *of_parse_phandle(const struct device_node *np, @@ -1498,21 +1539,21 @@ * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * - * Example: + * Example:: * - * phandle1: node1 { + * phandle1: node1 { * #list-cells = <2>; - * } + * }; * - * phandle2: node2 { + * phandle2: node2 { * #list-cells = <1>; - * } + * }; * - * node3 { + * node3 { * list = <&phandle1 1 2 &phandle2 3>; - * } + * }; * - * To get a device_node of the `node2' node you may call this: + * To get a device_node of the ``node2`` node you may call this: * of_parse_phandle_with_args(node3, "list", "#list-cells", 1, &args); */ int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, @@ -1550,29 +1591,29 @@ * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * - * Example: - * - * phandle1: node1 { - * #list-cells = <2>; - * } - * - * phandle2: node2 { - * #list-cells = <1>; - * } + * Example:: * - * phandle3: node3 { - * #list-cells = <1>; - * list-map = <0 &phandle2 3>, - * <1 &phandle2 2>, - * <2 &phandle1 5 1>; - * list-map-mask = <0x3>; - * }; - * - * node4 { - * list = <&phandle1 1 2 &phandle3 0>; - * } + * phandle1: node1 { + * #list-cells = <2>; + * }; + * + * phandle2: node2 { + * #list-cells = <1>; + * }; + * + * phandle3: node3 { + * #list-cells = <1>; + * list-map = <0 &phandle2 3>, + * <1 &phandle2 2>, + * <2 &phandle1 5 1>; + * list-map-mask = <0x3>; + * }; + * + * node4 { + * list = <&phandle1 1 2 &phandle3 0>; + * }; * - * To get a device_node of the `node2' node you may call this: + * To get a device_node of the ``node2`` node you may call this: * of_parse_phandle_with_args(node4, "list", "list", 1, &args); */ int of_parse_phandle_with_args_map(const struct device_node *np, @@ -1654,8 +1695,10 @@ map_len--; /* Check if not found */ - if (!new) + if (!new) { + ret = -EINVAL; goto put; + } if (!of_device_is_available(new)) match = 0; @@ -1665,17 +1708,20 @@ goto put; /* Check for malformed properties */ - if (WARN_ON(new_size > MAX_PHANDLE_ARGS)) - goto put; - if (map_len < new_size) + if (WARN_ON(new_size > MAX_PHANDLE_ARGS) || + map_len < new_size) { + ret = -EINVAL; goto put; + } /* Move forward by new node's #-cells amount */ map += new_size; map_len -= new_size; } - if (!match) + if (!match) { + ret = -ENOENT; goto put; + } /* Get the -map-pass-thru property (optional) */ pass = of_get_property(cur, pass_name, NULL); @@ -1687,7 +1733,6 @@ * specifier into the out_args structure, keeping the * bits specified in -map-pass-thru. */ - match_array = map - new_size; for (i = 0; i < new_size; i++) { __be32 val = *(map - new_size + i); @@ -1696,6 +1741,7 @@ val |= cpu_to_be32(out_args->args[i]) & pass[i]; } + initial_match_array[i] = val; out_args->args[i] = be32_to_cpu(val); } out_args->args_count = list_size = new_size; @@ -1703,6 +1749,7 @@ out_args->np = new; of_node_put(cur); cur = new; + new = NULL; } put: of_node_put(cur); @@ -1732,19 +1779,19 @@ * Caller is responsible to call of_node_put() on the returned out_args->np * pointer. * - * Example: + * Example:: * - * phandle1: node1 { - * } + * phandle1: node1 { + * }; * - * phandle2: node2 { - * } + * phandle2: node2 { + * }; * - * node3 { - * list = <&phandle1 0 2 &phandle2 2 3>; - * } + * node3 { + * list = <&phandle1 0 2 &phandle2 2 3>; + * }; * - * To get a device_node of the `node2' node you may call this: + * To get a device_node of the ``node2`` node you may call this: * of_parse_phandle_with_fixed_args(node3, "list", 2, 1, &args); */ int of_parse_phandle_with_fixed_args(const struct device_node *np, @@ -1764,7 +1811,7 @@ * @list_name: property name that contains a list * @cells_name: property name that specifies phandles' arguments count * - * Returns the number of phandle + argument tuples within a property. It + * Return: The number of phandle + argument tuples within a property. It * is a typical pattern to encode a list of phandle and variable * arguments into a single property. The number of arguments is encoded * by a property in the phandle-target node. For example, a gpios @@ -1812,6 +1859,8 @@ /** * __of_add_property - Add a property to a node without lock operations + * @np: Caller's Device Node + * @prob: Property to add */ int __of_add_property(struct device_node *np, struct property *prop) { @@ -1833,6 +1882,8 @@ /** * of_add_property - Add a property to a node + * @np: Caller's Device Node + * @prob: Property to add */ int of_add_property(struct device_node *np, struct property *prop) { @@ -1877,6 +1928,8 @@ /** * of_remove_property - Remove a property from a node. + * @np: Caller's Device Node + * @prob: Property to remove * * Note that we don't actually remove it, since we have given out * who-knows-how-many pointers to the data using get-property. @@ -1983,13 +2036,12 @@ /** * of_alias_scan - Scan all properties of the 'aliases' node + * @dt_alloc: An allocator that provides a virtual address to memory + * for storing the resulting tree * * The function scans all the properties of the 'aliases' node and populates * the global lookup table with the properties. It returns the * number of alias properties found, or an error code in case of failure. - * - * @dt_alloc: An allocator that provides a virtual address to memory - * for storing the resulting tree */ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) { @@ -2058,7 +2110,9 @@ * @stem: Alias stem of the given device_node * * The function travels the lookup table to get the alias id for the given - * device_node and alias stem. It returns the alias id if found. + * device_node and alias stem. + * + * Return: The alias id if found. */ int of_alias_get_id(struct device_node *np, const char *stem) { @@ -2162,13 +2216,14 @@ /** * of_console_check() - Test and setup console for DT setup - * @dn - Pointer to device node - * @name - Name to use for preferred console without index. ex. "ttyS" - * @index - Index to use for preferred console. + * @dn: Pointer to device node + * @name: Name to use for preferred console without index. ex. "ttyS" + * @index: Index to use for preferred console. * * Check if the given device node matches the stdout-path property in the - * /chosen node. If it does then register it as the preferred console and return - * TRUE. Otherwise return FALSE. + * /chosen node. If it does then register it as the preferred console. + * + * Return: TRUE if console successfully setup. Otherwise return FALSE. */ bool of_console_check(struct device_node *dn, char *name, int index) { @@ -2184,12 +2239,12 @@ EXPORT_SYMBOL_GPL(of_console_check); /** - * of_find_next_cache_node - Find a node's subsidiary cache - * @np: node of type "cpu" or "cache" + * of_find_next_cache_node - Find a node's subsidiary cache + * @np: node of type "cpu" or "cache" * - * Returns a node pointer with refcount incremented, use - * of_node_put() on it when done. Caller should hold a reference - * to np. + * Return: A node pointer with refcount incremented, use + * of_node_put() on it when done. Caller should hold a reference + * to np. */ struct device_node *of_find_next_cache_node(const struct device_node *np) { @@ -2219,7 +2274,7 @@ * * @cpu: cpu number(logical index) for which the last cache level is needed * - * Returns the the level at which the last cache is present. It is exactly + * Return: The the level at which the last cache is present. It is exactly * same as the total number of cache levels for the given logical cpu. */ int of_find_last_cache_level(unsigned int cpu) @@ -2239,15 +2294,15 @@ } /** - * of_map_rid - Translate a requester ID through a downstream mapping. + * of_map_id - Translate an ID through a downstream mapping. * @np: root complex device node. - * @rid: device requester ID to map. + * @id: device ID to map. * @map_name: property name of the map to use. * @map_mask_name: optional property name of the mask to use. * @target: optional pointer to a target device node. * @id_out: optional pointer to receive the translated ID. * - * Given a device requester ID, look up the appropriate implementation-defined + * Given a device ID, look up the appropriate implementation-defined * platform ID and/or the target device which receives transactions on that * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or * @id_out may be NULL if only the other is required. If @target points to @@ -2257,11 +2312,11 @@ * * Return: 0 on success or a standard error code on failure. */ -int of_map_rid(struct device_node *np, u32 rid, +int of_map_id(struct device_node *np, u32 id, const char *map_name, const char *map_mask_name, struct device_node **target, u32 *id_out) { - u32 map_mask, masked_rid; + u32 map_mask, masked_id; int map_len; const __be32 *map = NULL; @@ -2273,7 +2328,7 @@ if (target) return -ENODEV; /* Otherwise, no map implies no translation */ - *id_out = rid; + *id_out = id; return 0; } @@ -2293,22 +2348,22 @@ if (map_mask_name) of_property_read_u32(np, map_mask_name, &map_mask); - masked_rid = map_mask & rid; + masked_id = map_mask & id; for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { struct device_node *phandle_node; - u32 rid_base = be32_to_cpup(map + 0); + u32 id_base = be32_to_cpup(map + 0); u32 phandle = be32_to_cpup(map + 1); u32 out_base = be32_to_cpup(map + 2); - u32 rid_len = be32_to_cpup(map + 3); + u32 id_len = be32_to_cpup(map + 3); - if (rid_base & ~map_mask) { - pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + if (id_base & ~map_mask) { + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n", np, map_name, map_name, - map_mask, rid_base); + map_mask, id_base); return -EFAULT; } - if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) + if (masked_id < id_base || masked_id >= id_base + id_len) continue; phandle_node = of_find_node_by_phandle(phandle); @@ -2326,20 +2381,20 @@ } if (id_out) - *id_out = masked_rid - rid_base + out_base; + *id_out = masked_id - id_base + out_base; - pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n", - np, map_name, map_mask, rid_base, out_base, - rid_len, rid, masked_rid - rid_base + out_base); + pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n", + np, map_name, map_mask, id_base, out_base, + id_len, id, masked_id - id_base + out_base); return 0; } - pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name, - rid, target && *target ? *target : NULL); + pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name, + id, target && *target ? *target : NULL); /* Bypasses translation */ if (id_out) - *id_out = rid; + *id_out = id; return 0; } -EXPORT_SYMBOL_GPL(of_map_rid); +EXPORT_SYMBOL_GPL(of_map_id); --- linux-oracle-5.4.0.orig/drivers/of/device.c +++ linux-oracle-5.4.0/drivers/of/device.c @@ -246,12 +246,15 @@ if (size < 0) return size; - str = kmalloc(size + 1, GFP_KERNEL); + /* Reserve an additional byte for the trailing '\0' */ + size++; + + str = kmalloc(size, GFP_KERNEL); if (!str) return -ENOMEM; of_device_get_modalias(dev, str, size); - str[size] = '\0'; + str[size - 1] = '\0'; ret = request_module(str); kfree(str); --- linux-oracle-5.4.0.orig/drivers/of/dynamic.c +++ linux-oracle-5.4.0/drivers/of/dynamic.c @@ -27,7 +27,7 @@ * @node: Node to inc refcount, NULL is supported to simplify writing of * callers * - * Returns node. + * Return: The node with refcount incremented. */ struct device_node *of_node_get(struct device_node *node) { @@ -104,8 +104,10 @@ * @arg - argument of the of notifier * * Returns the new state of a device based on the notifier used. - * Returns 0 on device going from enabled to disabled, 1 on device - * going from disabled to enabled and -1 on no change. + * + * Return: OF_RECONFIG_CHANGE_REMOVE on device going from enabled to + * disabled, OF_RECONFIG_CHANGE_ADD on device going from disabled to + * enabled and OF_RECONFIG_NO_CHANGE on no change. */ int of_reconfig_get_state_change(unsigned long action, struct of_reconfig_data *pr) { @@ -372,7 +374,8 @@ * property structure and the property name & contents. The property's * flags have the OF_DYNAMIC bit set so that we can differentiate between * dynamically allocated properties and not. - * Returns the newly allocated property or NULL on out of memory error. + * + * Return: The newly allocated property or NULL on out of memory error. */ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) { @@ -415,7 +418,7 @@ * another node. The node data are dynamically allocated and all the node * flags have the OF_DYNAMIC & OF_DETACHED bits set. * - * Returns the newly allocated node or NULL on out of memory error. + * Return: The newly allocated node or NULL on out of memory error. */ struct device_node *__of_node_dup(const struct device_node *np, const char *full_name) @@ -781,7 +784,8 @@ * Any side-effects of live tree state changes are applied here on * success, like creation/destruction of devices and side-effects * like creation of sysfs properties and directories. - * Returns 0 on success, a negative error value in case of an error. + * + * Return: 0 on success, a negative error value in case of an error. * On error the partially applied effects are reverted. */ int of_changeset_apply(struct of_changeset *ocs) @@ -875,7 +879,8 @@ * was before the application. * Any side-effects like creation/destruction of devices and * removal of sysfs properties and directories are applied. - * Returns 0 on success, a negative error value in case of an error. + * + * Return: 0 on success, a negative error value in case of an error. */ int of_changeset_revert(struct of_changeset *ocs) { @@ -903,7 +908,8 @@ * + OF_RECONFIG_ADD_PROPERTY * + OF_RECONFIG_REMOVE_PROPERTY, * + OF_RECONFIG_UPDATE_PROPERTY - * Returns 0 on success, a negative error value in case of an error. + * + * Return: 0 on success, a negative error value in case of an error. */ int of_changeset_action(struct of_changeset *ocs, unsigned long action, struct device_node *np, struct property *prop) --- linux-oracle-5.4.0.orig/drivers/of/fdt.c +++ linux-oracle-5.4.0/drivers/of/fdt.c @@ -282,7 +282,7 @@ * @dad: Parent struct device_node * @nodepp: The device_node tree created by the call * - * It returns the size of unflattened device tree or error code + * Return: The size of unflattened device tree or error code */ static int unflatten_dt_nodes(const void *blob, void *mem, @@ -315,7 +315,7 @@ for (offset = 0; offset >= 0 && depth >= initial_depth; offset = fdt_next_node(blob, offset, &depth)) { - if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH)) + if (WARN_ON_ONCE(depth >= FDT_MAX_DEPTH - 1)) continue; if (!IS_ENABLED(CONFIG_OF_KOBJ) && @@ -349,11 +349,6 @@ /** * __unflatten_device_tree - create tree of device_nodes from flat blob - * - * unflattens a device-tree, creating the - * tree of struct device_node. It also fills the "name" and "type" - * pointers of the nodes so the normal device-tree walking functions - * can be used. * @blob: The blob to expand * @dad: Parent device node * @mynodes: The device_node tree created by the call @@ -361,7 +356,11 @@ * for the resulting tree * @detached: if true set OF_DETACHED on @mynodes * - * Returns NULL on failure or the memory chunk containing the unflattened + * unflattens a device-tree, creating the tree of struct device_node. It also + * fills the "name" and "type" pointers of the nodes so the normal device-tree + * walking functions can be used. + * + * Return: NULL on failure or the memory chunk containing the unflattened * device tree on success. */ void *__unflatten_device_tree(const void *blob, @@ -442,7 +441,7 @@ * pointers of the nodes so the normal device-tree walking functions * can be used. * - * Returns NULL on failure or the memory chunk containing the unflattened + * Return: NULL on failure or the memory chunk containing the unflattened * device tree on success. */ void *of_fdt_unflatten_tree(const unsigned long *blob, @@ -501,11 +500,11 @@ if (size && early_init_dt_reserve_memory_arch(base, size, nomap) == 0) - pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); else - pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); len -= t_len; if (first) { @@ -720,7 +719,7 @@ * @node: node to test * @compat: compatible string to compare with compatible list. * - * On match, returns a non-zero value with smaller values returned for more + * Return: a non-zero value on match with smaller values returned for more * specific compatible values. */ static int of_fdt_is_compatible(const void *blob, --- linux-oracle-5.4.0.orig/drivers/of/irq.c +++ linux-oracle-5.4.0/drivers/of/irq.c @@ -48,7 +48,7 @@ * of_irq_find_parent - Given a device node, find its interrupt parent node * @child: pointer to device node * - * Returns a pointer to the interrupt parent node, or NULL if the interrupt + * Return: A pointer to the interrupt parent node, or NULL if the interrupt * parent could not be determined. */ struct device_node *of_irq_find_parent(struct device_node *child) @@ -81,14 +81,14 @@ * @addr: address specifier (start of "reg" property of the device) in be32 format * @out_irq: structure of_phandle_args updated by this function * - * Returns 0 on success and a negative number on error - * * This function is a low-level interrupt tree walking function. It * can be used to do a partial walk with synthetized reg and interrupts * properties, for example when resolving PCI interrupts when no device * node exist for the parent. It takes an interrupt specifier structure as * input, walks the tree looking for any interrupt-map properties, translates * the specifier for each map, and then returns the translated map. + * + * Return: 0 on success and a negative number on error */ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) { @@ -288,7 +288,8 @@ struct device_node *p; const __be32 *addr; u32 intsize; - int i, res; + int i, res, addr_len; + __be32 addr_buf[3] = { 0 }; pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index); @@ -297,13 +298,20 @@ return of_irq_parse_oldworld(device, index, out_irq); /* Get the reg property (if any) */ - addr = of_get_property(device, "reg", NULL); + addr_len = 0; + addr = of_get_property(device, "reg", &addr_len); + + /* Prevent out-of-bounds read in case of longer interrupt parent address size */ + if (addr_len > sizeof(addr_buf)) + addr_len = sizeof(addr_buf); + if (addr) + memcpy(addr_buf, addr, addr_len); /* Try the new-style interrupts-extended first */ res = of_parse_phandle_with_args(device, "interrupts-extended", "#interrupt-cells", index, out_irq); if (!res) - return of_irq_parse_raw(addr, out_irq); + return of_irq_parse_raw(addr_buf, out_irq); /* Look for the interrupt parent. */ p = of_irq_find_parent(device); @@ -333,7 +341,7 @@ /* Check if there are any interrupt-map translations to process */ - res = of_irq_parse_raw(addr, out_irq); + res = of_irq_parse_raw(addr_buf, out_irq); out: of_node_put(p); return res; @@ -380,7 +388,7 @@ * @dev: pointer to device tree node * @index: zero-based index of the IRQ * - * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or + * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * of any other failure. */ @@ -407,7 +415,7 @@ * @dev: pointer to device tree node * @name: IRQ name * - * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or + * Return: Linux IRQ number on success, or 0 on the IRQ mapping failure, or * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case * of any other failure. */ @@ -447,7 +455,7 @@ * @res: array of resources to fill in * @nr_irqs: the number of IRQs (and upper bound for num of @res elements) * - * Returns the size of the filled in table (up to @nr_irqs). + * Return: The size of the filled in table (up to @nr_irqs). */ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, int nr_irqs) @@ -576,55 +584,57 @@ } } -static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, - u32 rid_in) +static u32 __of_msi_map_id(struct device *dev, struct device_node **np, + u32 id_in) { struct device *parent_dev; - u32 rid_out = rid_in; + u32 id_out = id_in; /* * Walk up the device parent links looking for one with a * "msi-map" property. */ for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) - if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map", - "msi-map-mask", np, &rid_out)) + if (!of_map_id(parent_dev->of_node, id_in, "msi-map", + "msi-map-mask", np, &id_out)) break; - return rid_out; + return id_out; } /** - * of_msi_map_rid - Map a MSI requester ID for a device. + * of_msi_map_id - Map a MSI ID for a device. * @dev: device for which the mapping is to be done. * @msi_np: device node of the expected msi controller. - * @rid_in: unmapped MSI requester ID for the device. + * @id_in: unmapped MSI ID for the device. * * Walk up the device hierarchy looking for devices with a "msi-map" - * property. If found, apply the mapping to @rid_in. + * property. If found, apply the mapping to @id_in. * - * Returns the mapped MSI requester ID. + * Return: The mapped MSI ID. */ -u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in) +u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) { - return __of_msi_map_rid(dev, &msi_np, rid_in); + return __of_msi_map_id(dev, &msi_np, id_in); } /** * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain * @dev: device for which the mapping is to be done. - * @rid: Requester ID for the device. + * @id: Device ID. + * @bus_token: Bus token * * Walk up the device hierarchy looking for devices with a "msi-map" * property. * * Returns: the MSI domain for this device (or NULL on failure) */ -struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid) +struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id, + u32 bus_token) { struct device_node *np = NULL; - __of_msi_map_rid(dev, &np, rid); - return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); + __of_msi_map_id(dev, &np, id); + return irq_find_matching_host(np, bus_token); } /** @@ -633,8 +643,7 @@ * @np: device node for @dev * @token: bus type for this domain * - * Parse the msi-parent property (both the simple and the complex - * versions), and returns the corresponding MSI domain. + * Parse the msi-parent property and returns the corresponding MSI domain. * * Returns: the MSI domain for this device (or NULL on failure). */ @@ -642,33 +651,14 @@ struct device_node *np, enum irq_domain_bus_token token) { - struct device_node *msi_np; + struct of_phandle_iterator it; struct irq_domain *d; + int err; - /* Check for a single msi-parent property */ - msi_np = of_parse_phandle(np, "msi-parent", 0); - if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) { - d = irq_find_matching_host(msi_np, token); - if (!d) - of_node_put(msi_np); - return d; - } - - if (token == DOMAIN_BUS_PLATFORM_MSI) { - /* Check for the complex msi-parent version */ - struct of_phandle_args args; - int index = 0; - - while (!of_parse_phandle_with_args(np, "msi-parent", - "#msi-cells", - index, &args)) { - d = irq_find_matching_host(args.np, token); - if (d) - return d; - - of_node_put(args.np); - index++; - } + of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) { + d = irq_find_matching_host(it.node, token); + if (d) + return d; } return NULL; --- linux-oracle-5.4.0.orig/drivers/of/kobj.c +++ linux-oracle-5.4.0/drivers/of/kobj.c @@ -119,7 +119,7 @@ struct property *pp; int rc; - if (!of_kset) + if (!IS_ENABLED(CONFIG_SYSFS) || !of_kset) return 0; np->kobj.kset = of_kset; @@ -134,8 +134,6 @@ if (!name) return -ENOMEM; - of_node_get(np); - rc = kobject_add(&np->kobj, parent, "%s", name); kfree(name); if (rc) @@ -144,6 +142,7 @@ for_each_property_of_node(np, pp) __of_add_property_sysfs(np, pp); + of_node_get(np); return 0; } --- linux-oracle-5.4.0.orig/drivers/of/of_mdio.c +++ linux-oracle-5.4.0/drivers/of/of_mdio.c @@ -265,8 +265,14 @@ child, addr); if (of_mdiobus_child_is_phy(child)) { + /* -ENODEV is the return code that PHYLIB has + * standardized on to indicate that bus + * scanning should continue. + */ rc = of_mdiobus_register_phy(mdio, child, addr); - if (rc && rc != -ENODEV) + if (!rc) + break; + if (rc != -ENODEV) goto unregister; } } @@ -275,6 +281,7 @@ return 0; unregister: + of_node_put(child); mdiobus_unregister(mdio); return rc; } --- linux-oracle-5.4.0.orig/drivers/of/of_reserved_mem.c +++ linux-oracle-5.4.0/drivers/of/of_reserved_mem.c @@ -134,9 +134,9 @@ ret = early_init_dt_alloc_reserved_memory_arch(size, align, start, end, nomap, &base); if (ret == 0) { - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", uname, &base, - (unsigned long)size / SZ_1M); + (unsigned long)(size / SZ_1M)); break; } len -= t_len; @@ -146,8 +146,8 @@ ret = early_init_dt_alloc_reserved_memory_arch(size, align, 0, 0, nomap, &base); if (ret == 0) - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); } if (base == 0) { @@ -200,6 +200,16 @@ if (ra->base > rb->base) return 1; + /* + * Put the dynamic allocations (address == 0, size == 0) before static + * allocations at address 0x0 so that overlap detection works + * correctly. + */ + if (ra->size < rb->size) + return -1; + if (ra->size > rb->size) + return 1; + return 0; } @@ -217,8 +227,7 @@ this = &reserved_mem[i]; next = &reserved_mem[i + 1]; - if (!(this->base && next->base)) - continue; + if (this->base + this->size > next->base) { phys_addr_t this_end, next_end; --- linux-oracle-5.4.0.orig/drivers/of/overlay.c +++ linux-oracle-5.4.0/drivers/of/overlay.c @@ -170,9 +170,7 @@ ret = blocking_notifier_call_chain(&overlay_notify_chain, action, &nd); - if (ret == NOTIFY_OK || ret == NOTIFY_STOP) - return 0; - if (ret) { + if (notifier_to_errno(ret)) { ret = notifier_to_errno(ret); pr_err("overlay changeset %s notifier error %d, target: %pOF\n", of_overlay_action_name[action], ret, nd.target); @@ -261,6 +259,8 @@ of_property_set_flag(new_prop, OF_DYNAMIC); + kfree(target_path); + return new_prop; err_free_new_prop: @@ -296,7 +296,7 @@ * * Update of property in symbols node is not allowed. * - * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if + * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * invalid @overlay. */ static int add_changeset_property(struct overlay_changeset *ovcs, @@ -305,7 +305,6 @@ { struct property *new_prop = NULL, *prop; int ret = 0; - bool check_for_non_overlay_node = false; if (target->in_livetree) if (!of_prop_cmp(overlay_prop->name, "name") || @@ -318,6 +317,25 @@ else prop = NULL; + if (prop) { + if (!of_prop_cmp(prop->name, "#address-cells")) { + if (!of_prop_val_eq(prop, overlay_prop)) { + pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", + target->np); + ret = -EINVAL; + } + return ret; + + } else if (!of_prop_cmp(prop->name, "#size-cells")) { + if (!of_prop_val_eq(prop, overlay_prop)) { + pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", + target->np); + ret = -EINVAL; + } + return ret; + } + } + if (is_symbols_prop) { if (prop) return -EINVAL; @@ -330,33 +348,18 @@ return -ENOMEM; if (!prop) { - check_for_non_overlay_node = true; if (!target->in_livetree) { new_prop->next = target->np->deadprops; target->np->deadprops = new_prop; } ret = of_changeset_add_property(&ovcs->cset, target->np, new_prop); - } else if (!of_prop_cmp(prop->name, "#address-cells")) { - if (!of_prop_val_eq(prop, new_prop)) { - pr_err("ERROR: changing value of #address-cells is not allowed in %pOF\n", - target->np); - ret = -EINVAL; - } - } else if (!of_prop_cmp(prop->name, "#size-cells")) { - if (!of_prop_val_eq(prop, new_prop)) { - pr_err("ERROR: changing value of #size-cells is not allowed in %pOF\n", - target->np); - ret = -EINVAL; - } } else { - check_for_non_overlay_node = true; ret = of_changeset_update_property(&ovcs->cset, target->np, new_prop); } - if (check_for_non_overlay_node && - !of_node_check_flag(target->np, OF_OVERLAY)) + if (!of_node_check_flag(target->np, OF_OVERLAY)) pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n", target->np, new_prop->name); @@ -398,7 +401,7 @@ * * NOTE_2: Multiple mods of created nodes not supported. * - * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if + * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * invalid @overlay. */ static int add_changeset_node(struct overlay_changeset *ovcs, @@ -470,7 +473,7 @@ * * Do not allow symbols node to have any children. * - * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if + * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * invalid @overlay_node. */ static int build_changeset_next_level(struct overlay_changeset *ovcs, @@ -544,7 +547,7 @@ fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np); fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np); - node_path_match = !strcmp(fn_1, fn_2); + node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2); kfree(fn_1); kfree(fn_2); if (node_path_match) { @@ -579,7 +582,7 @@ fn_1 = kasprintf(GFP_KERNEL, "%pOF", ce_1->np); fn_2 = kasprintf(GFP_KERNEL, "%pOF", ce_2->np); - node_path_match = !strcmp(fn_1, fn_2); + node_path_match = !fn_1 || !fn_2 || !strcmp(fn_1, fn_2); kfree(fn_1); kfree(fn_2); if (node_path_match && @@ -601,7 +604,7 @@ * the same node or duplicate {add, delete, or update} properties entries * for the same property. * - * Returns 0 on success, or -EINVAL if duplicate changeset entry found. + * Return: 0 on success, or -EINVAL if duplicate changeset entry found. */ static int changeset_dup_entry_check(struct overlay_changeset *ovcs) { @@ -625,7 +628,7 @@ * any portions of the changeset that were successfully created will remain * in @ovcs->cset. * - * Returns 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if + * Return: 0 on success, -ENOMEM if memory allocation failure, or -EINVAL if * invalid overlay in @ovcs->fragments[]. */ static int build_changeset(struct overlay_changeset *ovcs) @@ -721,7 +724,7 @@ * the top level of @tree. The relevant top level nodes are the fragment * nodes and the __symbols__ node. Any other top level node will be ignored. * - * Returns 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error + * Return: 0 on success, -ENOMEM if memory allocation failure, -EINVAL if error * detected in @tree, or -ENOSPC if idr_alloc() error. */ static int init_overlay_changeset(struct overlay_changeset *ovcs, @@ -1177,7 +1180,7 @@ * If an error is returned by an overlay changeset post-remove notifier * then no further overlay changeset post-remove notifier will be called. * - * Returns 0 on success, or a negative error number. *ovcs_id is set to + * Return: 0 on success, or a negative error number. *ovcs_id is set to * zero after reverting the changeset, even if a subsequent error occurs. */ int of_overlay_remove(int *ovcs_id) @@ -1264,7 +1267,7 @@ * * Removes all overlays from the system in the correct order. * - * Returns 0 on success, or a negative error number + * Return: 0 on success, or a negative error number */ int of_overlay_remove_all(void) { --- linux-oracle-5.4.0.orig/drivers/of/platform.c +++ linux-oracle-5.4.0/drivers/of/platform.c @@ -44,7 +44,7 @@ * Takes a reference to the embedded struct device which needs to be dropped * after use. * - * Returns platform_device pointer, or NULL if not found + * Return: platform_device pointer, or NULL if not found */ struct platform_device *of_find_device_by_node(struct device_node *np) { @@ -160,7 +160,7 @@ * @platform_data: pointer to populate platform_data pointer with * @parent: Linux device model parent device. * - * Returns pointer to created platform device, or NULL if a device was not + * Return: Pointer to created platform device, or NULL if a device was not * registered. Unavailable devices will not get registered. */ static struct platform_device *of_platform_device_create_pdata( @@ -204,7 +204,7 @@ * @bus_id: name to assign device * @parent: Linux device model parent device. * - * Returns pointer to created platform device, or NULL if a device was not + * Return: Pointer to created platform device, or NULL if a device was not * registered. Unavailable devices will not get registered. */ struct platform_device *of_platform_device_create(struct device_node *np, @@ -463,7 +463,7 @@ * New board support should be using this function instead of * of_platform_bus_probe(). * - * Returns 0 on success, < 0 on failure. + * Return: 0 on success, < 0 on failure. */ int of_platform_populate(struct device_node *root, const struct of_device_id *matches, @@ -594,7 +594,7 @@ * Similar to of_platform_populate(), but will automatically call * of_platform_depopulate() when the device is unbound from the bus. * - * Returns 0 on success, < 0 on failure. + * Return: 0 on success, < 0 on failure. */ int devm_of_platform_populate(struct device *dev) { --- linux-oracle-5.4.0.orig/drivers/of/property.c +++ linux-oracle-5.4.0/drivers/of/property.c @@ -36,9 +36,11 @@ * @elem_size: size of the individual element * * Search for a property in a device node and count the number of elements of - * size elem_size in it. Returns number of elements on sucess, -EINVAL if the - * property does not exist or its length does not match a multiple of elem_size - * and -ENODATA if the property does not have a value. + * size elem_size in it. + * + * Return: The number of elements on sucess, -EINVAL if the property does not + * exist or its length does not match a multiple of elem_size and -ENODATA if + * the property does not have a value. */ int of_property_count_elems_of_size(const struct device_node *np, const char *propname, int elem_size) @@ -70,8 +72,9 @@ * @len: if !=NULL, actual length is written to here * * Search for a property in a device node and valid the requested size. - * Returns the property value on success, -EINVAL if the property does not - * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the + * + * Return: The property value on success, -EINVAL if the property does not + * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the * property data is too small or too large. * */ @@ -104,7 +107,9 @@ * @out_value: pointer to return value, modified only if no error. * * Search for a property in a device node and read nth 32-bit value from - * it. Returns 0 on success, -EINVAL if the property does not exist, + * it. + * + * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * @@ -136,7 +141,9 @@ * @out_value: pointer to return value, modified only if no error. * * Search for a property in a device node and read nth 64-bit value from - * it. Returns 0 on success, -EINVAL if the property does not exist, + * it. + * + * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * @@ -171,12 +178,14 @@ * sz_min will be read. * * Search for a property in a device node and read 8-bit value(s) from - * it. Returns number of elements read on success, -EINVAL if the property - * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW - * if the property data is smaller than sz_min or longer than sz_max. + * it. * * dts entry of array should be like: - * property = /bits/ 8 <0x50 0x60 0x70>; + * ``property = /bits/ 8 <0x50 0x60 0x70>;`` + * + * Return: The number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u8 value can be decoded. */ @@ -219,12 +228,14 @@ * sz_min will be read. * * Search for a property in a device node and read 16-bit value(s) from - * it. Returns number of elements read on success, -EINVAL if the property - * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW - * if the property data is smaller than sz_min or longer than sz_max. + * it. * * dts entry of array should be like: - * property = /bits/ 16 <0x5000 0x6000 0x7000>; + * ``property = /bits/ 16 <0x5000 0x6000 0x7000>;`` + * + * Return: The number of elements read on success, -EINVAL if the property + * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW + * if the property data is smaller than sz_min or longer than sz_max. * * The out_values is modified only if a valid u16 value can be decoded. */ @@ -267,7 +278,9 @@ * sz_min will be read. * * Search for a property in a device node and read 32-bit value(s) from - * it. Returns number of elements read on success, -EINVAL if the property + * it. + * + * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * @@ -306,7 +319,9 @@ * @out_value: pointer to return value, modified only if return value is 0. * * Search for a property in a device node and read a 64-bit value from - * it. Returns 0 on success, -EINVAL if the property does not exist, + * it. + * + * Return: 0 on success, -EINVAL if the property does not exist, * -ENODATA if property does not have a value, and -EOVERFLOW if the * property data isn't large enough. * @@ -341,7 +356,9 @@ * sz_min will be read. * * Search for a property in a device node and read 64-bit value(s) from - * it. Returns number of elements read on success, -EINVAL if the property + * it. + * + * Return: The number of elements read on success, -EINVAL if the property * does not exist, -ENODATA if property does not have a value, and -EOVERFLOW * if the property data is smaller than sz_min or longer than sz_max. * @@ -383,10 +400,11 @@ * return value is 0. * * Search for a property in a device tree node and retrieve a null - * terminated string value (pointer to data, not a copy). Returns 0 on - * success, -EINVAL if the property does not exist, -ENODATA if property - * does not have a value, and -EILSEQ if the string is not null-terminated - * within the length of the property data. + * terminated string value (pointer to data, not a copy). + * + * Return: 0 on success, -EINVAL if the property does not exist, -ENODATA if + * property does not have a value, and -EILSEQ if the string is not + * null-terminated within the length of the property data. * * The out_string pointer is modified only if a valid string can be decoded. */ @@ -750,7 +768,7 @@ * @node: pointer to a local endpoint device_node * * Return: Remote port node associated with remote endpoint node linked - * to @node. Use of_node_put() on it when done. + * to @node. Use of_node_put() on it when done. */ struct device_node *of_graph_get_remote_port(const struct device_node *node) { @@ -783,7 +801,7 @@ * @endpoint: identifier (value of reg property) of the endpoint node * * Return: Remote device node associated with remote endpoint node linked - * to @node. Use of_node_put() on it when done. + * to @node. Use of_node_put() on it when done. */ struct device_node *of_graph_get_remote_node(const struct device_node *node, u32 port, u32 endpoint) @@ -918,8 +936,10 @@ nargs, index, &of_args); if (ret < 0) return ret; - if (!args) + if (!args) { + of_node_put(of_args.np); return 0; + } args->nargs = of_args.args_count; args->fwnode = of_fwnode_handle(of_args.np); --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/Makefile +++ linux-oracle-5.4.0/drivers/of/unittest-data/Makefile @@ -21,7 +21,13 @@ overlay_bad_add_dup_prop.dtb.o \ overlay_bad_phandle.dtb.o \ overlay_bad_symbol.dtb.o \ - overlay_base.dtb.o + overlay_base.dtb.o \ + overlay_gpio_01.dtb.o \ + overlay_gpio_02a.dtb.o \ + overlay_gpio_02b.dtb.o \ + overlay_gpio_03.dtb.o \ + overlay_gpio_04a.dtb.o \ + overlay_gpio_04b.dtb.o # enable creation of __symbols__ node DTC_FLAGS_overlay += -@ --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_01.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_01.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@0 { + compatible = "unittest-gpio"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + gpio-line-names = "line-A", "line-B"; + + line-b { + gpio-hog; + gpios = <2 0>; + input; + line-name = "line-B-input"; + }; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_02a.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_02a.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@2 { + compatible = "unittest-gpio"; + reg = <2>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + gpio-line-names = "line-A", "line-B"; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_02b.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_02b.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@2 { + line-a { + gpio-hog; + gpios = <1 0>; + input; + line-name = "line-A-input"; + }; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_03.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_03.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@3 { + compatible = "unittest-gpio"; + reg = <3>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + gpio-line-names = "line-A", "line-B", "line-C", "line-D"; + + line-d { + gpio-hog; + gpios = <4 0>; + input; + line-name = "line-D-input"; + }; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_04a.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_04a.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@4 { + compatible = "unittest-gpio"; + reg = <4>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + gpio-line-names = "line-A", "line-B", "line-C", "line-D"; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/overlay_gpio_04b.dts +++ linux-oracle-5.4.0/drivers/of/unittest-data/overlay_gpio_04b.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&unittest_test_bus { + #address-cells = <1>; + #size-cells = <0>; + gpio@4 { + line-c { + gpio-hog; + gpios = <3 0>; + input; + line-name = "line-C-input"; + }; + }; +}; --- linux-oracle-5.4.0.orig/drivers/of/unittest-data/tests-phandle.dtsi +++ linux-oracle-5.4.0/drivers/of/unittest-data/tests-phandle.dtsi @@ -38,6 +38,13 @@ phandle-map-pass-thru = <0x0 0xf0>; }; + provider5: provider5 { + #phandle-cells = <2>; + phandle-map = <2 7 &provider4 2 3>; + phandle-map-mask = <0xff 0xf>; + phandle-map-pass-thru = <0x0 0xf0>; + }; + consumer-a { phandle-list = <&provider1 1>, <&provider2 2 0>, @@ -64,7 +71,8 @@ <&provider4 4 0x100>, <&provider4 0 0x61>, <&provider0>, - <&provider4 19 0x20>; + <&provider4 19 0x20>, + <&provider5 2 7>; phandle-list-bad-phandle = <12345678 0 0>; phandle-list-bad-args = <&provider2 1 0>, <&provider4 0>; --- linux-oracle-5.4.0.orig/drivers/of/unittest.c +++ linux-oracle-5.4.0/drivers/of/unittest.c @@ -23,6 +23,7 @@ #include #include +#include #include @@ -45,6 +46,103 @@ failed; \ }) +#ifdef CONFIG_OF_KOBJ +#define OF_KREF_READ(NODE) kref_read(&(NODE)->kobj.kref) +#else +#define OF_KREF_READ(NODE) 1 +#endif + +/* + * Expected message may have a message level other than KERN_INFO. + * Print the expected message only if the current loglevel will allow + * the actual message to print. + */ +#define EXPECT_BEGIN(level, fmt, ...) \ + printk(level pr_fmt("EXPECT \\ : ") fmt, ##__VA_ARGS__) + +#define EXPECT_END(level, fmt, ...) \ + printk(level pr_fmt("EXPECT / : ") fmt, ##__VA_ARGS__) + +struct unittest_gpio_dev { + struct gpio_chip chip; +}; + +static int unittest_gpio_chip_request_count; +static int unittest_gpio_probe_count; +static int unittest_gpio_probe_pass_count; + +static int unittest_gpio_chip_request(struct gpio_chip *chip, unsigned int offset) +{ + unittest_gpio_chip_request_count++; + + pr_debug("%s(): %s %d %d\n", __func__, chip->label, offset, + unittest_gpio_chip_request_count); + return 0; +} + +static int unittest_gpio_probe(struct platform_device *pdev) +{ + struct unittest_gpio_dev *devptr; + int ret; + + unittest_gpio_probe_count++; + + devptr = kzalloc(sizeof(*devptr), GFP_KERNEL); + if (!devptr) + return -ENOMEM; + + platform_set_drvdata(pdev, devptr); + + devptr->chip.of_node = pdev->dev.of_node; + devptr->chip.label = "of-unittest-gpio"; + devptr->chip.base = -1; /* dynamic allocation */ + devptr->chip.ngpio = 5; + devptr->chip.request = unittest_gpio_chip_request; + + ret = gpiochip_add_data(&devptr->chip, NULL); + + unittest(!ret, + "gpiochip_add_data() for node @%pOF failed, ret = %d\n", devptr->chip.of_node, ret); + + if (!ret) + unittest_gpio_probe_pass_count++; + return ret; +} + +static int unittest_gpio_remove(struct platform_device *pdev) +{ + struct unittest_gpio_dev *gdev = platform_get_drvdata(pdev); + struct device *dev = &pdev->dev; + struct device_node *np = pdev->dev.of_node; + + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); + + if (!gdev) + return -EINVAL; + + if (gdev->chip.base != -1) + gpiochip_remove(&gdev->chip); + + platform_set_drvdata(pdev, NULL); + kfree(gdev); + + return 0; +} + +static const struct of_device_id unittest_gpio_id[] = { + { .compatible = "unittest-gpio", }, + {} +}; + +static struct platform_driver unittest_gpio_driver = { + .probe = unittest_gpio_probe, + .remove = unittest_gpio_remove, + .driver = { + .name = "unittest-gpio", + .of_match_table = of_match_ptr(unittest_gpio_id), + }, +}; + static void __init of_unittest_find_node_by_name(void) { struct device_node *np; @@ -52,7 +150,7 @@ np = of_find_node_by_path("/testcase-data"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find /testcase-data failed\n"); of_node_put(np); kfree(name); @@ -63,14 +161,14 @@ np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find /testcase-data/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); np = of_find_node_by_path("testcase-alias"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find testcase-alias failed\n"); of_node_put(np); kfree(name); @@ -81,7 +179,7 @@ np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find testcase-alias/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); @@ -430,6 +528,9 @@ unittest(passed, "index %i - data error on node %pOF rc=%i\n", i, args.np, rc); + + if (rc == 0) + of_node_put(args.np); } /* Check for missing list property */ @@ -471,8 +572,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) { - struct device_node *np, *p0, *p1, *p2, *p3; + struct device_node *np, *p[6] = {}; struct of_phandle_args args; + unsigned int prefs[6]; int i, rc; np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b"); @@ -481,34 +583,24 @@ return; } - p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); - if (!p0) { - pr_err("missing testcase data\n"); - return; - } - - p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); - if (!p1) { - pr_err("missing testcase data\n"); - return; - } - - p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); - if (!p2) { - pr_err("missing testcase data\n"); - return; - } - - p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); - if (!p3) { - pr_err("missing testcase data\n"); - return; + p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); + p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); + p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); + p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); + p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4"); + p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5"); + for (i = 0; i < ARRAY_SIZE(p); ++i) { + if (!p[i]) { + pr_err("missing testcase data\n"); + return; + } + prefs[i] = OF_KREF_READ(p[i]); } rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); - unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); + unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc); - for (i = 0; i < 8; i++) { + for (i = 0; i < 9; i++) { bool passed = true; memset(&args, 0, sizeof(args)); @@ -519,13 +611,13 @@ switch (i) { case 0: passed &= !rc; - passed &= (args.np == p1); + passed &= (args.np == p[1]); passed &= (args.args_count == 1); passed &= (args.args[0] == 1); break; case 1: passed &= !rc; - passed &= (args.np == p3); + passed &= (args.np == p[3]); passed &= (args.args_count == 3); passed &= (args.args[0] == 2); passed &= (args.args[1] == 5); @@ -536,28 +628,36 @@ break; case 3: passed &= !rc; - passed &= (args.np == p0); + passed &= (args.np == p[0]); passed &= (args.args_count == 0); break; case 4: passed &= !rc; - passed &= (args.np == p1); + passed &= (args.np == p[1]); passed &= (args.args_count == 1); passed &= (args.args[0] == 3); break; case 5: passed &= !rc; - passed &= (args.np == p0); + passed &= (args.np == p[0]); passed &= (args.args_count == 0); break; case 6: passed &= !rc; - passed &= (args.np == p2); + passed &= (args.np == p[2]); passed &= (args.args_count == 2); passed &= (args.args[0] == 15); passed &= (args.args[1] == 0x20); break; case 7: + passed &= !rc; + passed &= (args.np == p[3]); + passed &= (args.args_count == 3); + passed &= (args.args[0] == 2); + passed &= (args.args[1] == 5); + passed &= (args.args[2] == 3); + break; + case 8: passed &= (rc == -ENOENT); break; default: @@ -566,6 +666,9 @@ unittest(passed, "index %i - data error on node %s rc=%i\n", i, args.np->full_name, rc); + + if (rc == 0) + of_node_put(args.np); } /* Check for missing list property */ @@ -591,6 +694,13 @@ rc = of_parse_phandle_with_args_map(np, "phandle-list-bad-args", "phandle", 1, &args); unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); + + for (i = 0; i < ARRAY_SIZE(p); ++i) { + unittest(prefs[i] == OF_KREF_READ(p[i]), + "provider%d: expected:%d got:%d\n", + i, prefs[i], OF_KREF_READ(p[i])); + of_node_put(p[i]); + } } static void __init of_unittest_property_string(void) @@ -776,6 +886,10 @@ unittest(!of_changeset_revert(&chgset), "revert failed\n"); of_changeset_destroy(&chgset); + + of_node_put(n1); + of_node_put(n2); + of_node_put(n21); #endif } @@ -1061,10 +1175,13 @@ of_platform_populate(np, match, NULL, &test_bus->dev); for_each_child_of_node(np, child) { - for_each_child_of_node(child, grandchild) - unittest(of_find_device_by_node(grandchild), + for_each_child_of_node(child, grandchild) { + pdev = of_find_device_by_node(grandchild); + unittest(pdev, "Could not create device for node '%pOFn'\n", grandchild); + of_dev_put(pdev); + } } of_platform_depopulate(&test_bus->dev); @@ -1144,10 +1261,14 @@ const char *full_name; full_name = kasprintf(GFP_KERNEL, "%pOF", np); + if (!full_name) + return; if (!strcmp(full_name, "/__local_fixups__") || - !strcmp(full_name, "/__fixups__")) + !strcmp(full_name, "/__fixups__")) { + kfree(full_name); return; + } dup = of_find_node_by_path(full_name); kfree(full_name); @@ -1571,7 +1692,7 @@ } /* unittest device must be again in before state */ - if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) { + if (of_unittest_device_exists(unittest_nr, ovtype) != before) { unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), unittest_path(unittest_nr, ovtype), @@ -2091,6 +2212,153 @@ #endif +static void __init of_unittest_overlay_gpio(void) +{ + int chip_request_count; + int probe_pass_count; + int ret; + + /* + * tests: apply overlays before registering driver + * Similar to installing a driver as a module, the + * driver is registered after applying the overlays. + * + * - apply overlay_gpio_01 + * - apply overlay_gpio_02a + * - apply overlay_gpio_02b + * - register driver + * + * register driver will result in + * - probe and processing gpio hog for overlay_gpio_01 + * - probe for overlay_gpio_02a + * - processing gpio for overlay_gpio_02b + */ + + probe_pass_count = unittest_gpio_probe_pass_count; + chip_request_count = unittest_gpio_chip_request_count; + + /* + * overlay_gpio_01 contains gpio node and child gpio hog node + * overlay_gpio_02a contains gpio node + * overlay_gpio_02b contains child gpio hog node + */ + + unittest(overlay_data_apply("overlay_gpio_01", NULL), + "Adding overlay 'overlay_gpio_01' failed\n"); + + unittest(overlay_data_apply("overlay_gpio_02a", NULL), + "Adding overlay 'overlay_gpio_02a' failed\n"); + + unittest(overlay_data_apply("overlay_gpio_02b", NULL), + "Adding overlay 'overlay_gpio_02b' failed\n"); + + /* + * messages are the result of the probes, after the + * driver is registered + */ + + EXPECT_BEGIN(KERN_INFO, + "gpio-<> (line-B-input): hogged as input\n"); + + EXPECT_BEGIN(KERN_INFO, + "gpio-<> (line-A-input): hogged as input\n"); + + ret = platform_driver_register(&unittest_gpio_driver); + if (unittest(ret == 0, "could not register unittest gpio driver\n")) + return; + + EXPECT_END(KERN_INFO, + "gpio-<> (line-A-input): hogged as input\n"); + EXPECT_END(KERN_INFO, + "gpio-<> (line-B-input): hogged as input\n"); + + unittest(probe_pass_count + 2 == unittest_gpio_probe_pass_count, + "unittest_gpio_probe() failed or not called\n"); + + unittest(chip_request_count + 2 == unittest_gpio_chip_request_count, + "unittest_gpio_chip_request() called %d times (expected 1 time)\n", + unittest_gpio_chip_request_count - chip_request_count); + + /* + * tests: apply overlays after registering driver + * + * Similar to a driver built-in to the kernel, the + * driver is registered before applying the overlays. + * + * overlay_gpio_03 contains gpio node and child gpio hog node + * + * - apply overlay_gpio_03 + * + * apply overlay will result in + * - probe and processing gpio hog. + */ + + probe_pass_count = unittest_gpio_probe_pass_count; + chip_request_count = unittest_gpio_chip_request_count; + + EXPECT_BEGIN(KERN_INFO, + "gpio-<> (line-D-input): hogged as input\n"); + + /* overlay_gpio_03 contains gpio node and child gpio hog node */ + + unittest(overlay_data_apply("overlay_gpio_03", NULL), + "Adding overlay 'overlay_gpio_03' failed\n"); + + EXPECT_END(KERN_INFO, + "gpio-<> (line-D-input): hogged as input\n"); + + unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count, + "unittest_gpio_probe() failed or not called\n"); + + unittest(chip_request_count + 1 == unittest_gpio_chip_request_count, + "unittest_gpio_chip_request() called %d times (expected 1 time)\n", + unittest_gpio_chip_request_count - chip_request_count); + + /* + * overlay_gpio_04a contains gpio node + * + * - apply overlay_gpio_04a + * + * apply the overlay will result in + * - probe for overlay_gpio_04a + */ + + probe_pass_count = unittest_gpio_probe_pass_count; + chip_request_count = unittest_gpio_chip_request_count; + + /* overlay_gpio_04a contains gpio node */ + + unittest(overlay_data_apply("overlay_gpio_04a", NULL), + "Adding overlay 'overlay_gpio_04a' failed\n"); + + unittest(probe_pass_count + 1 == unittest_gpio_probe_pass_count, + "unittest_gpio_probe() failed or not called\n"); + + /* + * overlay_gpio_04b contains child gpio hog node + * + * - apply overlay_gpio_04b + * + * apply the overlay will result in + * - processing gpio for overlay_gpio_04b + */ + + EXPECT_BEGIN(KERN_INFO, + "gpio-<> (line-C-input): hogged as input\n"); + + /* overlay_gpio_04b contains child gpio hog node */ + + unittest(overlay_data_apply("overlay_gpio_04b", NULL), + "Adding overlay 'overlay_gpio_04b' failed\n"); + + EXPECT_END(KERN_INFO, + "gpio-<> (line-C-input): hogged as input\n"); + + unittest(chip_request_count + 1 == unittest_gpio_chip_request_count, + "unittest_gpio_chip_request() called %d times (expected 1 time)\n", + unittest_gpio_chip_request_count - chip_request_count); +} + static void __init of_unittest_overlay(void) { struct device_node *bus_np = NULL; @@ -2150,6 +2418,8 @@ of_unittest_overlay_i2c_cleanup(); #endif + of_unittest_overlay_gpio(); + of_unittest_destroy_tracked_overlays(); out: @@ -2203,6 +2473,12 @@ OVERLAY_INFO_EXTERN(overlay_12); OVERLAY_INFO_EXTERN(overlay_13); OVERLAY_INFO_EXTERN(overlay_15); +OVERLAY_INFO_EXTERN(overlay_gpio_01); +OVERLAY_INFO_EXTERN(overlay_gpio_02a); +OVERLAY_INFO_EXTERN(overlay_gpio_02b); +OVERLAY_INFO_EXTERN(overlay_gpio_03); +OVERLAY_INFO_EXTERN(overlay_gpio_04a); +OVERLAY_INFO_EXTERN(overlay_gpio_04b); OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node); OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop); OVERLAY_INFO_EXTERN(overlay_bad_phandle); @@ -2227,6 +2503,12 @@ OVERLAY_INFO(overlay_12, 0), OVERLAY_INFO(overlay_13, 0), OVERLAY_INFO(overlay_15, 0), + OVERLAY_INFO(overlay_gpio_01, 0), + OVERLAY_INFO(overlay_gpio_02a, 0), + OVERLAY_INFO(overlay_gpio_02b, 0), + OVERLAY_INFO(overlay_gpio_03, 0), + OVERLAY_INFO(overlay_gpio_04a, 0), + OVERLAY_INFO(overlay_gpio_04b, 0), OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL), OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL), OVERLAY_INFO(overlay_bad_phandle, -EINVAL), @@ -2472,8 +2754,11 @@ goto err_unlock; } if (__of_add_property(of_symbols, new_prop)) { + kfree(new_prop->name); + kfree(new_prop->value); + kfree(new_prop); /* "name" auto-generated by unflatten */ - if (!strcmp(new_prop->name, "name")) + if (!strcmp(prop->name, "name")) continue; unittest(0, "duplicate property '%s' in overlay_base node __symbols__", prop->name); --- linux-oracle-5.4.0.orig/drivers/opp/core.c +++ linux-oracle-5.4.0/drivers/opp/core.c @@ -843,10 +843,12 @@ /* Return early if nothing to do */ if (old_freq == freq) { - dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n", - __func__, freq); - ret = 0; - goto put_opp_table; + if (!opp_table->required_opp_tables && !opp_table->regulators) { + dev_dbg(dev, "%s: old/new frequencies (%lu Hz) are same, nothing to do\n", + __func__, freq); + ret = 0; + goto put_opp_table; + } } temp_freq = old_freq; @@ -988,7 +990,6 @@ BLOCKING_INIT_NOTIFIER_HEAD(&opp_table->head); INIT_LIST_HEAD(&opp_table->opp_list); kref_init(&opp_table->kref); - kref_init(&opp_table->list_kref); /* Secure the device table modification */ list_add(&opp_table->node, &opp_tables); @@ -1045,6 +1046,10 @@ struct opp_table *opp_table = container_of(kref, struct opp_table, kref); struct opp_device *opp_dev, *temp; + /* Drop the lock as soon as we can */ + list_del(&opp_table->node); + mutex_unlock(&opp_table_lock); + _of_clear_opp_table(opp_table); /* Release clk */ @@ -1066,37 +1071,7 @@ mutex_destroy(&opp_table->genpd_virt_dev_lock); mutex_destroy(&opp_table->lock); - list_del(&opp_table->node); kfree(opp_table); - - mutex_unlock(&opp_table_lock); -} - -void _opp_remove_all_static(struct opp_table *opp_table) -{ - struct dev_pm_opp *opp, *tmp; - - list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) { - if (!opp->dynamic) - dev_pm_opp_put(opp); - } - - opp_table->parsed_static_opps = false; -} - -static void _opp_table_list_kref_release(struct kref *kref) -{ - struct opp_table *opp_table = container_of(kref, struct opp_table, - list_kref); - - _opp_remove_all_static(opp_table); - mutex_unlock(&opp_table_lock); -} - -void _put_opp_list_kref(struct opp_table *opp_table) -{ - kref_put_mutex(&opp_table->list_kref, _opp_table_list_kref_release, - &opp_table_lock); } void dev_pm_opp_put_opp_table(struct opp_table *opp_table) @@ -1202,6 +1177,24 @@ } EXPORT_SYMBOL_GPL(dev_pm_opp_remove); +void _opp_remove_all_static(struct opp_table *opp_table) +{ + struct dev_pm_opp *opp, *tmp; + + mutex_lock(&opp_table->lock); + + if (!opp_table->parsed_static_opps || --opp_table->parsed_static_opps) + goto unlock; + + list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) { + if (!opp->dynamic) + dev_pm_opp_put_unlocked(opp); + } + +unlock: + mutex_unlock(&opp_table->lock); +} + /** * dev_pm_opp_remove_all_dynamic() - Remove all dynamically created OPPs * @dev: device for which we do this operation @@ -1804,6 +1797,9 @@ { int index; + if (!opp_table->genpd_virt_devs) + return; + for (index = 0; index < opp_table->required_opp_count; index++) { if (!opp_table->genpd_virt_devs[index]) continue; @@ -1850,6 +1846,9 @@ if (!opp_table) return ERR_PTR(-ENOMEM); + if (opp_table->genpd_virt_devs) + return opp_table; + /* * If the genpd's OPP table isn't already initialized, parsing of the * required-opps fail for dev. We should retry this after genpd's OPP @@ -1882,8 +1881,8 @@ } virt_dev = dev_pm_domain_attach_by_name(dev, *name); - if (IS_ERR(virt_dev)) { - ret = PTR_ERR(virt_dev); + if (IS_ERR_OR_NULL(virt_dev)) { + ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV; dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); goto err; } @@ -2207,7 +2206,7 @@ return; } - _put_opp_list_kref(opp_table); + _opp_remove_all_static(opp_table); /* Drop reference taken by _find_opp_table() */ dev_pm_opp_put_opp_table(opp_table); --- linux-oracle-5.4.0.orig/drivers/opp/debugfs.c +++ linux-oracle-5.4.0/drivers/opp/debugfs.c @@ -162,7 +162,7 @@ dentry = debugfs_rename(rootdir, opp_dev->dentry, rootdir, opp_table->dentry_name); - if (!dentry) { + if (IS_ERR(dentry)) { dev_err(dev, "%s: Failed to rename link from: %s to %s\n", __func__, dev_name(opp_dev->dev), dev_name(dev)); return; --- linux-oracle-5.4.0.orig/drivers/opp/of.c +++ linux-oracle-5.4.0/drivers/opp/of.c @@ -95,15 +95,7 @@ static struct device_node *of_parse_required_opp(struct device_node *np, int index) { - struct device_node *required_np; - - required_np = of_parse_phandle(np, "required-opps", index); - if (unlikely(!required_np)) { - pr_err("%s: Unable to parse required-opps: %pOF, index: %d\n", - __func__, np, index); - } - - return required_np; + return of_parse_phandle(np, "required-opps", index); } /* The caller must call dev_pm_opp_put_opp_table() after the table is used */ @@ -647,7 +639,7 @@ free_opp: _opp_free(new_opp); - return ERR_PTR(ret); + return ret ? ERR_PTR(ret) : NULL; } /* Initializes OPP tables based on new bindings */ @@ -658,17 +650,15 @@ struct dev_pm_opp *opp; /* OPP table is already initialized for the device */ + mutex_lock(&opp_table->lock); if (opp_table->parsed_static_opps) { - kref_get(&opp_table->list_kref); + opp_table->parsed_static_opps++; + mutex_unlock(&opp_table->lock); return 0; } - /* - * Re-initialize list_kref every time we add static OPPs to the OPP - * table as the reference count may be 0 after the last tie static OPPs - * were removed. - */ - kref_init(&opp_table->list_kref); + opp_table->parsed_static_opps = 1; + mutex_unlock(&opp_table->lock); /* We have opp-table node now, iterate over it and add OPPs */ for_each_available_child_of_node(opp_table->np, np) { @@ -678,15 +668,18 @@ dev_err(dev, "%s: Failed to add OPP, %d\n", __func__, ret); of_node_put(np); - return ret; + goto remove_static_opp; } else if (opp) { count++; } } - /* There should be one of more OPP defined */ - if (WARN_ON(!count)) - return -ENOENT; + /* There should be one or more OPPs defined */ + if (!count) { + dev_err(dev, "%s: no supported OPPs", __func__); + ret = -ENOENT; + goto remove_static_opp; + } list_for_each_entry(opp, &opp_table->opp_list, node) pstate_count += !!opp->pstate; @@ -695,15 +688,19 @@ if (pstate_count && pstate_count != count) { dev_err(dev, "Not all nodes have performance state set (%d: %d)\n", count, pstate_count); - return -ENOENT; + ret = -ENOENT; + goto remove_static_opp; } if (pstate_count) opp_table->genpd_performance_state = true; - opp_table->parsed_static_opps = true; - return 0; + +remove_static_opp: + _opp_remove_all_static(opp_table); + + return ret; } /* Initializes OPP tables based on old-deprecated bindings */ @@ -729,6 +726,10 @@ return -EINVAL; } + mutex_lock(&opp_table->lock); + opp_table->parsed_static_opps = 1; + mutex_unlock(&opp_table->lock); + val = prop->value; while (nr) { unsigned long freq = be32_to_cpup(val++) * 1000; @@ -738,6 +739,7 @@ if (ret) { dev_err(dev, "%s: Failed to add OPP %ld (%d)\n", __func__, freq, ret); + _opp_remove_all_static(opp_table); return ret; } nr -= 2; @@ -986,7 +988,7 @@ required_np = of_parse_required_opp(np, index); if (!required_np) - return -EINVAL; + return -ENODEV; opp_table = _find_table_of_opp_np(required_np); if (IS_ERR(opp_table)) { --- linux-oracle-5.4.0.orig/drivers/opp/opp.h +++ linux-oracle-5.4.0/drivers/opp/opp.h @@ -127,11 +127,10 @@ * @dev_list: list of devices that share these OPPs * @opp_list: table of opps * @kref: for reference count of the table. - * @list_kref: for reference count of the OPP list. * @lock: mutex protecting the opp_list and dev_list. * @np: struct device_node pointer for opp's DT node. * @clock_latency_ns_max: Max clock latency in nanoseconds. - * @parsed_static_opps: True if OPPs are initialized from DT. + * @parsed_static_opps: Count of devices for which OPPs are initialized from DT. * @shared_opp: OPP is shared between multiple devices. * @suspend_opp: Pointer to OPP to be used during device suspend. * @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointers. @@ -167,7 +166,6 @@ struct list_head dev_list; struct list_head opp_list; struct kref kref; - struct kref list_kref; struct mutex lock; struct device_node *np; @@ -176,7 +174,7 @@ /* For backward compatibility with v1 bindings */ unsigned int voltage_tolerance_v1; - bool parsed_static_opps; + unsigned int parsed_static_opps; enum opp_table_access shared_opp; struct dev_pm_opp *suspend_opp; --- linux-oracle-5.4.0.orig/drivers/parisc/ccio-dma.c +++ linux-oracle-5.4.0/drivers/parisc/ccio-dma.c @@ -1003,7 +1003,7 @@ ioc->usg_calls++; #endif - while(sg_dma_len(sglist) && nents--) { + while (nents && sg_dma_len(sglist)) { #ifdef CCIO_COLLECT_STATS ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT; @@ -1011,6 +1011,7 @@ ccio_unmap_page(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction, 0); ++sglist; + nents--; } DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); @@ -1377,15 +1378,17 @@ } } -static void __init ccio_init_resources(struct ioc *ioc) +static int __init ccio_init_resources(struct ioc *ioc) { struct resource *res = ioc->mmio_region; char *name = kmalloc(14, GFP_KERNEL); - + if (unlikely(!name)) + return -ENOMEM; snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); + return 0; } static int new_ioc_area(struct resource *res, unsigned long size, @@ -1540,7 +1543,11 @@ return -ENOMEM; } ccio_ioc_init(ioc); - ccio_init_resources(ioc); + if (ccio_init_resources(ioc)) { + iounmap(ioc->ioc_regs); + kfree(ioc); + return -ENOMEM; + } hppa_dma_ops = &ccio_ops; hba = kzalloc(sizeof(*hba), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/parisc/dino.c +++ linux-oracle-5.4.0/drivers/parisc/dino.c @@ -142,9 +142,8 @@ { struct pci_hba_data hba; /* 'C' inheritance - must be first */ spinlock_t dinosaur_pen; - unsigned long txn_addr; /* EIR addr to generate interrupt */ - u32 txn_data; /* EIR data assign to each dino */ u32 imr; /* IRQ's which are enabled */ + struct gsc_irq gsc_irq; int global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */ #ifdef DINO_DEBUG unsigned int dino_irr0; /* save most recent IRQ line stat */ @@ -156,15 +155,6 @@ return container_of(hba, struct dino_device, hba); } -/* Check if PCI device is behind a Card-mode Dino. */ -static int pci_dev_is_behind_card_dino(struct pci_dev *dev) -{ - struct dino_device *dino_dev; - - dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge)); - return is_card_dino(&dino_dev->hba.dev->id); -} - /* * Dino Configuration Space Accessor Functions */ @@ -348,14 +338,43 @@ if (tmp & DINO_MASK_IRQ(local_irq)) { DBG(KERN_WARNING "%s(): IRQ asserted! (ILR 0x%x)\n", __func__, tmp); - gsc_writel(dino_dev->txn_data, dino_dev->txn_addr); + gsc_writel(dino_dev->gsc_irq.txn_data, dino_dev->gsc_irq.txn_addr); } } +#ifdef CONFIG_SMP +static int dino_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, + bool force) +{ + struct dino_device *dino_dev = irq_data_get_irq_chip_data(d); + struct cpumask tmask; + int cpu_irq; + u32 eim; + + if (!cpumask_and(&tmask, dest, cpu_online_mask)) + return -EINVAL; + + cpu_irq = cpu_check_affinity(d, &tmask); + if (cpu_irq < 0) + return cpu_irq; + + dino_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq); + eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data; + __raw_writel(eim, dino_dev->hba.base_addr+DINO_IAR0); + + irq_data_update_effective_affinity(d, &tmask); + + return IRQ_SET_MASK_OK; +} +#endif + static struct irq_chip dino_interrupt_type = { .name = "GSC-PCI", .irq_unmask = dino_unmask_irq, .irq_mask = dino_mask_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = dino_set_affinity_irq, +#endif }; @@ -447,6 +466,15 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus ); #ifdef CONFIG_TULIP +/* Check if PCI device is behind a Card-mode Dino. */ +static int pci_dev_is_behind_card_dino(struct pci_dev *dev) +{ + struct dino_device *dino_dev; + + dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge)); + return is_card_dino(&dino_dev->hba.dev->id); +} + static void pci_fixup_tulip(struct pci_dev *dev) { if (!pci_dev_is_behind_card_dino(dev)) @@ -806,7 +834,6 @@ { int status; u32 eim; - struct gsc_irq gsc_irq; struct resource *res; pcibios_register_hba(&dino_dev->hba); @@ -821,10 +848,8 @@ ** still only has 11 IRQ input lines - just map some of them ** to a different processor. */ - dev->irq = gsc_alloc_irq(&gsc_irq); - dino_dev->txn_addr = gsc_irq.txn_addr; - dino_dev->txn_data = gsc_irq.txn_data; - eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; + dev->irq = gsc_alloc_irq(&dino_dev->gsc_irq); + eim = ((u32) dino_dev->gsc_irq.txn_addr) | dino_dev->gsc_irq.txn_data; /* ** Dino needs a PA "IRQ" to get a processor's attention. --- linux-oracle-5.4.0.orig/drivers/parisc/gsc.c +++ linux-oracle-5.4.0/drivers/parisc/gsc.c @@ -135,10 +135,41 @@ */ } +#ifdef CONFIG_SMP +static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, + bool force) +{ + struct gsc_asic *gsc_dev = irq_data_get_irq_chip_data(d); + struct cpumask tmask; + int cpu_irq; + + if (!cpumask_and(&tmask, dest, cpu_online_mask)) + return -EINVAL; + + cpu_irq = cpu_check_affinity(d, &tmask); + if (cpu_irq < 0) + return cpu_irq; + + gsc_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq); + gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data; + + /* switch IRQ's for devices below LASI/WAX to other CPU */ + gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR); + + irq_data_update_effective_affinity(d, &tmask); + + return IRQ_SET_MASK_OK; +} +#endif + + static struct irq_chip gsc_asic_interrupt_type = { .name = "GSC-ASIC", .irq_unmask = gsc_asic_unmask_irq, .irq_mask = gsc_asic_mask_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = gsc_set_affinity_irq, +#endif }; int gsc_assign_irq(struct irq_chip *type, void *data) --- linux-oracle-5.4.0.orig/drivers/parisc/gsc.h +++ linux-oracle-5.4.0/drivers/parisc/gsc.h @@ -31,6 +31,7 @@ int version; int type; int eim; + struct gsc_irq gsc_irq; int global_irq[32]; }; --- linux-oracle-5.4.0.orig/drivers/parisc/iosapic.c +++ linux-oracle-5.4.0/drivers/parisc/iosapic.c @@ -202,9 +202,9 @@ static DEFINE_SPINLOCK(iosapic_lock); -static inline void iosapic_eoi(void __iomem *addr, unsigned int data) +static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data) { - __raw_writel(data, addr); + __raw_writel((__force u32)data, addr); } /* @@ -875,6 +875,7 @@ return vi->txn_irq; } +EXPORT_SYMBOL(iosapic_serial_irq); #endif --- linux-oracle-5.4.0.orig/drivers/parisc/iosapic_private.h +++ linux-oracle-5.4.0/drivers/parisc/iosapic_private.h @@ -118,8 +118,8 @@ struct vector_info { struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ struct irt_entry *irte; /* IRT entry */ - u32 __iomem *eoi_addr; /* precalculate EOI reg address */ - u32 eoi_data; /* IA64: ? PA: swapped txn_data */ + __le32 __iomem *eoi_addr; /* precalculate EOI reg address */ + __le32 eoi_data; /* IA64: ? PA: swapped txn_data */ int txn_irq; /* virtual IRQ number for processor */ ulong txn_addr; /* IA64: id_eid PA: partial HPA */ u32 txn_data; /* CPU interrupt bit */ --- linux-oracle-5.4.0.orig/drivers/parisc/lasi.c +++ linux-oracle-5.4.0/drivers/parisc/lasi.c @@ -163,7 +163,6 @@ { extern void (*chassis_power_off)(void); struct gsc_asic *lasi; - struct gsc_irq gsc_irq; int ret; lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); @@ -185,7 +184,7 @@ lasi_init_irq(lasi); /* the IRQ lasi should use */ - dev->irq = gsc_alloc_irq(&gsc_irq); + dev->irq = gsc_alloc_irq(&lasi->gsc_irq); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); @@ -193,9 +192,9 @@ return -EBUSY; } - lasi->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; + lasi->eim = ((u32) lasi->gsc_irq.txn_addr) | lasi->gsc_irq.txn_data; - ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi); + ret = request_irq(lasi->gsc_irq.irq, gsc_asic_intr, 0, "lasi", lasi); if (ret < 0) { kfree(lasi); return ret; --- linux-oracle-5.4.0.orig/drivers/parisc/led.c +++ linux-oracle-5.4.0/drivers/parisc/led.c @@ -56,8 +56,8 @@ static int led_type __read_mostly = -1; static unsigned char lastleds; /* LED state from most recent update */ static unsigned int led_heartbeat __read_mostly = 1; -static unsigned int led_diskio __read_mostly = 1; -static unsigned int led_lanrxtx __read_mostly = 1; +static unsigned int led_diskio __read_mostly; +static unsigned int led_lanrxtx __read_mostly; static char lcd_text[32] __read_mostly; static char lcd_text_default[32] __read_mostly; static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */ @@ -137,6 +137,9 @@ /* Create the work queue and queue the LED task */ led_wq = create_singlethread_workqueue("led_wq"); + if (!led_wq) + return -ENOMEM; + queue_delayed_work(led_wq, &led_task, 0); return 0; --- linux-oracle-5.4.0.orig/drivers/parisc/pdc_stable.c +++ linux-oracle-5.4.0/drivers/parisc/pdc_stable.c @@ -979,8 +979,10 @@ entry->kobj.kset = paths_kset; err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL, "%s", entry->name); - if (err) + if (err) { + kobject_put(&entry->kobj); return err; + } /* kobject is now registered */ write_lock(&entry->rw_lock); --- linux-oracle-5.4.0.orig/drivers/parisc/sba_iommu.c +++ linux-oracle-5.4.0/drivers/parisc/sba_iommu.c @@ -1047,7 +1047,7 @@ spin_unlock_irqrestore(&ioc->res_lock, flags); #endif - while (sg_dma_len(sglist) && nents--) { + while (nents && sg_dma_len(sglist)) { sba_unmap_page(dev, sg_dma_address(sglist), sg_dma_len(sglist), direction, 0); @@ -1056,6 +1056,7 @@ ioc->usingle_calls--; /* kluge since call is unmap_sg() */ #endif ++sglist; + nents--; } DBG_RUN_SG("%s() DONE (nents %d)\n", __func__, nents); @@ -1270,7 +1271,7 @@ ** (one that doesn't overlap memory or LMMIO space) in the ** IBASE and IMASK registers. */ - ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE); + ioc->ibase = READ_REG(ioc->ioc_hpa + IOC_IBASE) & ~0x1fffffULL; iova_space_size = ~(READ_REG(ioc->ioc_hpa + IOC_IMASK) & 0xFFFFFFFFUL) + 1; if ((ioc->ibase < 0xfed00000UL) && ((ioc->ibase + iova_space_size) > 0xfee00000UL)) { --- linux-oracle-5.4.0.orig/drivers/parisc/wax.c +++ linux-oracle-5.4.0/drivers/parisc/wax.c @@ -68,7 +68,6 @@ { struct gsc_asic *wax; struct parisc_device *parent; - struct gsc_irq gsc_irq; int ret; wax = kzalloc(sizeof(*wax), GFP_KERNEL); @@ -85,7 +84,7 @@ wax_init_irq(wax); /* the IRQ wax should use */ - dev->irq = gsc_claim_irq(&gsc_irq, WAX_GSC_IRQ); + dev->irq = gsc_claim_irq(&wax->gsc_irq, WAX_GSC_IRQ); if (dev->irq < 0) { printk(KERN_ERR "%s(): cannot get GSC irq\n", __func__); @@ -93,9 +92,9 @@ return -EBUSY; } - wax->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; + wax->eim = ((u32) wax->gsc_irq.txn_addr) | wax->gsc_irq.txn_data; - ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "wax", wax); + ret = request_irq(wax->gsc_irq.irq, gsc_asic_intr, 0, "wax", wax); if (ret < 0) { kfree(wax); return ret; --- linux-oracle-5.4.0.orig/drivers/parport/daisy.c +++ linux-oracle-5.4.0/drivers/parport/daisy.c @@ -109,8 +109,7 @@ ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) { /* Leave original as port zero. */ port->muxport = 0; - printk(KERN_INFO - "%s: 1st (default) port of %d-way multiplexor\n", + pr_info("%s: 1st (default) port of %d-way multiplexor\n", port->name, num_ports); for (i = 1; i < num_ports; i++) { /* Clone the port. */ @@ -123,8 +122,7 @@ continue; } - printk(KERN_INFO - "%s: %d%s port of %d-way multiplexor on %s\n", + pr_info("%s: %d%s port of %d-way multiplexor on %s\n", extra->name, i + 1, th[i + 1], num_ports, port->name); --- linux-oracle-5.4.0.orig/drivers/parport/ieee1284.c +++ linux-oracle-5.4.0/drivers/parport/ieee1284.c @@ -329,7 +329,7 @@ #ifndef CONFIG_PARPORT_1284 if (mode == IEEE1284_MODE_COMPAT) return 0; - printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); + pr_err("parport: IEEE1284 not supported in this kernel\n"); return -1; #else int m = mode & ~IEEE1284_ADDR; @@ -694,7 +694,7 @@ ssize_t parport_read (struct parport *port, void *buffer, size_t len) { #ifndef CONFIG_PARPORT_1284 - printk (KERN_ERR "parport: IEEE1284 not supported in this kernel\n"); + pr_err("parport: IEEE1284 not supported in this kernel\n"); return -ENODEV; #else int mode = port->physport->ieee1284.mode; --- linux-oracle-5.4.0.orig/drivers/parport/ieee1284_ops.c +++ linux-oracle-5.4.0/drivers/parport/ieee1284_ops.c @@ -535,7 +535,7 @@ goto out; /* Yield the port for a while. */ - if (count && dev->port->irq != PARPORT_IRQ_NONE) { + if (dev->port->irq != PARPORT_IRQ_NONE) { parport_release (dev); schedule_timeout_interruptible(msecs_to_jiffies(40)); parport_claim_or_block (dev); @@ -599,8 +599,7 @@ DPRINTK (KERN_DEBUG "ECP read timed out at 45\n"); if (command) - printk (KERN_WARNING - "%s: command ignored (%02x)\n", + pr_warn("%s: command ignored (%02x)\n", port->name, byte); break; --- linux-oracle-5.4.0.orig/drivers/parport/parport_amiga.c +++ linux-oracle-5.4.0/drivers/parport/parport_amiga.c @@ -212,7 +212,7 @@ if (err) goto out_irq; - printk(KERN_INFO "%s: Amiga built-in port using irq\n", p->name); + pr_info("%s: Amiga built-in port using irq\n", p->name); /* XXX: set operating mode */ parport_announce_port(p); --- linux-oracle-5.4.0.orig/drivers/parport/parport_atari.c +++ linux-oracle-5.4.0/drivers/parport/parport_atari.c @@ -200,7 +200,7 @@ } this_port = p; - printk(KERN_INFO "%s: Atari built-in port using irq\n", p->name); + pr_info("%s: Atari built-in port using irq\n", p->name); parport_announce_port (p); return 0; --- linux-oracle-5.4.0.orig/drivers/parport/parport_cs.c +++ linux-oracle-5.4.0/drivers/parport/parport_cs.c @@ -142,10 +142,8 @@ link->irq, PARPORT_DMA_NONE, &link->dev, IRQF_SHARED); if (p == NULL) { - printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " - "0x%3x, irq %u failed\n", - (unsigned int) link->resource[0]->start, - link->irq); + pr_notice("parport_cs: parport_pc_probe_port() at 0x%3x, irq %u failed\n", + (unsigned int)link->resource[0]->start, link->irq); goto failed; } --- linux-oracle-5.4.0.orig/drivers/parport/parport_gsc.c +++ linux-oracle-5.4.0/drivers/parport/parport_gsc.c @@ -282,7 +282,7 @@ p->size = (p->modes & PARPORT_MODE_EPP)?8:3; p->private_data = priv; - printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); + pr_info("%s: PC-style at 0x%lx", p->name, p->base); p->irq = irq; if (p->irq == PARPORT_IRQ_AUTO) { p->irq = PARPORT_IRQ_NONE; @@ -299,12 +299,16 @@ p->dma = PARPORT_DMA_NONE; pr_cont(" ["); -#define printmode(x) {if(p->modes&PARPORT_MODE_##x){pr_cont("%s%s",f?",":"",#x);f++;}} +#define printmode(x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) { int f = 0; printmode(PCSPP); printmode(TRISTATE); - printmode(COMPAT) + printmode(COMPAT); printmode(EPP); // printmode(ECP); // printmode(DMA); @@ -315,8 +319,7 @@ if (p->irq != PARPORT_IRQ_NONE) { if (request_irq (p->irq, parport_irq_handler, 0, p->name, p)) { - printk (KERN_WARNING "%s: irq %d in use, " - "resorting to polled operation\n", + pr_warn("%s: irq %d in use, resorting to polled operation\n", p->name, p->irq); p->irq = PARPORT_IRQ_NONE; p->dma = PARPORT_DMA_NONE; @@ -347,7 +350,7 @@ unsigned long port; if (!dev->irq) { - printk(KERN_WARNING "IRQ not found for parallel device at 0x%llx\n", + pr_warn("IRQ not found for parallel device at 0x%llx\n", (unsigned long long)dev->hpa.start); return -ENODEV; } --- linux-oracle-5.4.0.orig/drivers/parport/parport_ip32.c +++ linux-oracle-5.4.0/drivers/parport/parport_ip32.c @@ -1337,9 +1337,8 @@ ecr = parport_ip32_read_econtrol(p); if ((ecr & ECR_F_EMPTY) && !(ecr & ECR_SERVINTR) && !lost_interrupt) { - printk(KERN_WARNING PPIP32 - "%s: lost interrupt in %s\n", - p->name, __func__); + pr_warn(PPIP32 "%s: lost interrupt in %s\n", + p->name, __func__); lost_interrupt = 1; } } @@ -1643,8 +1642,8 @@ DSR_nBUSY | DSR_nFAULT)) { /* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); + pr_info(PPIP32 "%s: not ready in %s\n", + p->name, __func__); ready_before = 0; goto stop; } @@ -1724,8 +1723,8 @@ DSR_nBUSY | DSR_nFAULT)) { /* Avoid to flood the logs */ if (ready_before) - printk(KERN_INFO PPIP32 "%s: not ready in %s\n", - p->name, __func__); + pr_info(PPIP32 "%s: not ready in %s\n", + p->name, __func__); ready_before = 0; goto stop; } @@ -2064,8 +2063,7 @@ p->modes |= PARPORT_MODE_TRISTATE; if (!parport_ip32_fifo_supported(p)) { - printk(KERN_WARNING PPIP32 - "%s: error: FIFO disabled\n", p->name); + pr_warn(PPIP32 "%s: error: FIFO disabled\n", p->name); /* Disable hardware modes depending on a working FIFO. */ features &= ~PARPORT_IP32_ENABLE_SPP; features &= ~PARPORT_IP32_ENABLE_ECP; @@ -2077,8 +2075,7 @@ if (features & PARPORT_IP32_ENABLE_IRQ) { int irq = MACEISA_PARALLEL_IRQ; if (request_irq(irq, parport_ip32_interrupt, 0, p->name, p)) { - printk(KERN_WARNING PPIP32 - "%s: error: IRQ disabled\n", p->name); + pr_warn(PPIP32 "%s: error: IRQ disabled\n", p->name); /* DMA cannot work without interrupts. */ features &= ~PARPORT_IP32_ENABLE_DMA; } else { @@ -2091,8 +2088,7 @@ /* Allocate DMA resources */ if (features & PARPORT_IP32_ENABLE_DMA) { if (parport_ip32_dma_register()) - printk(KERN_WARNING PPIP32 - "%s: error: DMA disabled\n", p->name); + pr_warn(PPIP32 "%s: error: DMA disabled\n", p->name); else { pr_probe(p, "DMA support enabled\n"); p->dma = 0; /* arbitrary value != PARPORT_DMA_NONE */ @@ -2134,8 +2130,7 @@ parport_ip32_dump_state(p, "end init", 0); /* Print out what we found */ - printk(KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)", - p->name, p->base, p->base_hi); + pr_info("%s: SGI IP32 at 0x%lx (0x%lx)", p->name, p->base, p->base_hi); if (p->irq != PARPORT_IRQ_NONE) printk(", irq %d", p->irq); printk(" ["); --- linux-oracle-5.4.0.orig/drivers/parport/parport_mfc3.c +++ linux-oracle-5.4.0/drivers/parport/parport_mfc3.c @@ -325,7 +325,7 @@ p->dev = &z->dev; this_port[pias++] = p; - printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); + pr_info("%s: Multiface III port using irq\n", p->name); /* XXX: set operating mode */ p->private_data = (void *)piabase; --- linux-oracle-5.4.0.orig/drivers/parport/parport_pc.c +++ linux-oracle-5.4.0/drivers/parport/parport_pc.c @@ -475,7 +475,7 @@ const unsigned char *bufp = buf; size_t left = length; unsigned long expire = jiffies + port->physport->cad->timeout; - const int fifo = FIFO(port); + const unsigned long fifo = FIFO(port); int poll_for = 8; /* 80 usecs */ const struct parport_pc_private *priv = port->physport->private_data; const int fifo_depth = priv->fifo_depth; @@ -982,28 +982,24 @@ outb(0xaa, io); if (verbose_probing) { - printk(KERN_INFO - "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, " - "A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n", + pr_info("SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n", cr1, cr4, cra, cr23, cr26, cr27); /* The documentation calls DMA and IRQ-Lines by letters, so the board maker can/will wire them appropriately/randomly... G=reserved H=IDE-irq, */ - printk(KERN_INFO - "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, fifo threshold=%d\n", - cr23 * 4, - (cr27 & 0x0f) ? 'A' - 1 + (cr27 & 0x0f) : '-', - (cr26 & 0x0f) ? 'A' - 1 + (cr26 & 0x0f) : '-', - cra & 0x0f); - printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n", - (cr23 * 4 >= 0x100) ? "yes" : "no", - (cr1 & 4) ? "yes" : "no"); - printk(KERN_INFO - "SMSC LPT Config: Port mode=%s, EPP version =%s\n", - (cr1 & 0x08) ? "Standard mode only (SPP)" - : modes[cr4 & 0x03], - (cr4 & 0x40) ? "1.7" : "1.9"); + pr_info("SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, fifo threshold=%d\n", + cr23 * 4, + (cr27 & 0x0f) ? 'A' - 1 + (cr27 & 0x0f) : '-', + (cr26 & 0x0f) ? 'A' - 1 + (cr26 & 0x0f) : '-', + cra & 0x0f); + pr_info("SMSC LPT Config: enabled=%s power=%s\n", + (cr23 * 4 >= 0x100) ? "yes" : "no", + (cr1 & 4) ? "yes" : "no"); + pr_info("SMSC LPT Config: Port mode=%s, EPP version =%s\n", + (cr1 & 0x08) ? "Standard mode only (SPP)" + : modes[cr4 & 0x03], + (cr4 & 0x40) ? "1.7" : "1.9"); } /* Heuristics ! BIOS setup for this mainboard device limits @@ -1013,7 +1009,7 @@ if (cr23 * 4 >= 0x100) { /* if active */ s = find_free_superio(); if (s == NULL) - printk(KERN_INFO "Super-IO: too many chips!\n"); + pr_info("Super-IO: too many chips!\n"); else { int d; switch (cr23 * 4) { @@ -1078,26 +1074,24 @@ outb(0xaa, io); if (verbose_probing) { - printk(KERN_INFO - "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x 70=%02x 74=%02x, f0=%02x\n", - cr30, cr60, cr61, cr70, cr74, crf0); - printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", - (cr30 & 0x01) ? "yes" : "no", cr60, cr61, cr70 & 0x0f); + pr_info("Winbond LPT Config: cr_30=%02x 60,61=%02x%02x 70=%02x 74=%02x, f0=%02x\n", + cr30, cr60, cr61, cr70, cr74, crf0); + pr_info("Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", + (cr30 & 0x01) ? "yes" : "no", cr60, cr61, cr70 & 0x0f); if ((cr74 & 0x07) > 3) pr_cont("dma=none\n"); else pr_cont("dma=%d\n", cr74 & 0x07); - printk(KERN_INFO - "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n", - irqtypes[crf0>>7], (crf0>>3)&0x0f); - printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", - modes[crf0 & 0x07]); + pr_info("Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n", + irqtypes[crf0 >> 7], (crf0 >> 3) & 0x0f); + pr_info("Winbond LPT Config: Port mode=%s\n", + modes[crf0 & 0x07]); } if (cr30 & 0x01) { /* the settings can be interrogated later ... */ s = find_free_superio(); if (s == NULL) - printk(KERN_INFO "Super-IO: too many chips!\n"); + pr_info("Super-IO: too many chips!\n"); else { s->io = (cr60 << 8) | cr61; s->irq = cr70 & 0x0f; @@ -1151,9 +1145,8 @@ progif = 0; if (verbose_probing) - printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x " - "devid=%02x devrev=%02x oldid=%02x type=%s\n", - efer, key, devid, devrev, oldid, type); + pr_info("Winbond chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x oldid=%02x type=%s\n", + efer, key, devid, devrev, oldid, type); if (progif == 2) show_parconfig_winbond(efer, key); @@ -1184,9 +1177,8 @@ type = "37c666GT"; if (verbose_probing) - printk(KERN_INFO "SMSC chip at EFER=0x%x " - "key=0x%02x devid=%02x devrev=%02x type=%s\n", - efer, key, devid, devrev, type); + pr_info("SMSC chip at EFER=0x%x key=0x%02x devid=%02x devrev=%02x type=%s\n", + efer, key, devid, devrev, type); if (func) func(efer, key); @@ -1358,7 +1350,7 @@ dev |= inb(0x2f); if (dev == 0x8712 || dev == 0x8705 || dev == 0x8715 || dev == 0x8716 || dev == 0x8718 || dev == 0x8726) { - printk(KERN_INFO "IT%04X SuperIO detected.\n", dev); + pr_info("IT%04X SuperIO detected\n", dev); outb(0x07, 0x2E); /* Parallel Port */ outb(0x03, 0x2F); outb(0xF0, 0x2E); /* BOOT 0x80 off */ @@ -1445,8 +1437,8 @@ if (user_specified) /* That didn't work, but the user thinks there's a * port here. */ - printk(KERN_INFO "parport 0x%lx (WARNING): CTR: " - "wrote 0x%02x, read 0x%02x\n", pb->base, w, r); + pr_info("parport 0x%lx (WARNING): CTR: wrote 0x%02x, read 0x%02x\n", + pb->base, w, r); /* Try the data register. The data lines aren't tri-stated at * this stage, so we expect back what we wrote. */ @@ -1464,10 +1456,9 @@ if (user_specified) { /* Didn't work, but the user is convinced this is the * place. */ - printk(KERN_INFO "parport 0x%lx (WARNING): DATA: " - "wrote 0x%02x, read 0x%02x\n", pb->base, w, r); - printk(KERN_INFO "parport 0x%lx: You gave this address, " - "but there is probably no parallel port there!\n", + pr_info("parport 0x%lx (WARNING): DATA: wrote 0x%02x, read 0x%02x\n", + pb->base, w, r); + pr_info("parport 0x%lx: You gave this address, but there is probably no parallel port there!\n", pb->base); } @@ -1642,7 +1633,7 @@ if (i <= priv->fifo_depth) { if (verbose_probing) - printk(KERN_INFO "0x%lx: readIntrThreshold is %d\n", + pr_info("0x%lx: readIntrThreshold is %d\n", pb->base, i); } else /* Number of bytes we can read if we get an interrupt. */ @@ -1657,17 +1648,14 @@ switch (pword) { case 0: pword = 2; - printk(KERN_WARNING "0x%lx: Unsupported pword size!\n", - pb->base); + pr_warn("0x%lx: Unsupported pword size!\n", pb->base); break; case 2: pword = 4; - printk(KERN_WARNING "0x%lx: Unsupported pword size!\n", - pb->base); + pr_warn("0x%lx: Unsupported pword size!\n", pb->base); break; default: - printk(KERN_WARNING "0x%lx: Unknown implementation ID\n", - pb->base); + pr_warn("0x%lx: Unknown implementation ID\n", pb->base); /* Fall through - Assume 1 */ case 1: pword = 1; @@ -2107,9 +2095,9 @@ p->size = (p->modes & PARPORT_MODE_EPP) ? 8 : 3; - printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base); + pr_info("%s: PC-style at 0x%lx", p->name, p->base); if (p->base_hi && priv->ecr) - printk(KERN_CONT " (0x%lx)", p->base_hi); + pr_cont(" (0x%lx)", p->base_hi); if (p->irq == PARPORT_IRQ_AUTO) { p->irq = PARPORT_IRQ_NONE; parport_irq_probe(p); @@ -2120,7 +2108,7 @@ p->irq = PARPORT_IRQ_NONE; } if (p->irq != PARPORT_IRQ_NONE) { - printk(KERN_CONT ", irq %d", p->irq); + pr_cont(", irq %d", p->irq); priv->ctr_writable |= 0x10; if (p->dma == PARPORT_DMA_AUTO) { @@ -2144,41 +2132,39 @@ /* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */ #endif /* IEEE 1284 support */ if (p->dma != PARPORT_DMA_NONE) { - printk(KERN_CONT ", dma %d", p->dma); + pr_cont(", dma %d", p->dma); p->modes |= PARPORT_MODE_DMA; } else - printk(KERN_CONT ", using FIFO"); + pr_cont(", using FIFO"); } else /* We can't use the DMA channel after all. */ p->dma = PARPORT_DMA_NONE; #endif /* Allowed to use FIFO/DMA */ - printk(KERN_CONT " ["); + pr_cont(" ["); -#define printmode(x) \ - {\ - if (p->modes & PARPORT_MODE_##x) {\ - printk(KERN_CONT "%s%s", f ? "," : "", #x);\ - f++;\ - } \ - } +#define printmode(x) \ +do { \ + if (p->modes & PARPORT_MODE_##x) \ + pr_cont("%s%s", f++ ? "," : "", #x); \ +} while (0) { int f = 0; printmode(PCSPP); printmode(TRISTATE); - printmode(COMPAT) + printmode(COMPAT); printmode(EPP); printmode(ECP); printmode(DMA); } #undef printmode #ifndef CONFIG_PARPORT_1284 - printk(KERN_CONT "(,...)"); + pr_cont("(,...)"); #endif /* CONFIG_PARPORT_1284 */ - printk(KERN_CONT "]\n"); + pr_cont("]\n"); if (probedirq != PARPORT_IRQ_NONE) - printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq); + pr_info("%s: irq %d detected\n", p->name, probedirq); /* If No ECP release the ports grabbed above. */ if (ECR_res && (p->modes & PARPORT_MODE_ECP) == 0) { @@ -2193,8 +2179,7 @@ if (p->irq != PARPORT_IRQ_NONE) { if (request_irq(p->irq, parport_irq_handler, irqflags, p->name, p)) { - printk(KERN_WARNING "%s: irq %d in use, " - "resorting to polled operation\n", + pr_warn("%s: irq %d in use, resorting to polled operation\n", p->name, p->irq); p->irq = PARPORT_IRQ_NONE; p->dma = PARPORT_DMA_NONE; @@ -2204,8 +2189,7 @@ #ifdef HAS_DMA if (p->dma != PARPORT_DMA_NONE) { if (request_dma(p->dma, p->name)) { - printk(KERN_WARNING "%s: dma %d in use, " - "resorting to PIO operation\n", + pr_warn("%s: dma %d in use, resorting to PIO operation\n", p->name, p->dma); p->dma = PARPORT_DMA_NONE; } else { @@ -2215,9 +2199,7 @@ &priv->dma_handle, GFP_KERNEL); if (!priv->dma_buf) { - printk(KERN_WARNING "%s: " - "cannot get buffer for DMA, " - "resorting to PIO operation\n", + pr_warn("%s: cannot get buffer for DMA, resorting to PIO operation\n", p->name); free_dma(p->dma); p->dma = PARPORT_DMA_NONE; @@ -2330,7 +2312,7 @@ } } if (i >= 5) { - printk(KERN_INFO "parport_pc: cannot find ITE8872 INTA\n"); + pr_info("parport_pc: cannot find ITE8872 INTA\n"); return 0; } @@ -2339,29 +2321,28 @@ switch (type) { case 0x2: - printk(KERN_INFO "parport_pc: ITE8871 found (1P)\n"); + pr_info("parport_pc: ITE8871 found (1P)\n"); ite8872set = 0x64200000; break; case 0xa: - printk(KERN_INFO "parport_pc: ITE8875 found (1P)\n"); + pr_info("parport_pc: ITE8875 found (1P)\n"); ite8872set = 0x64200000; break; case 0xe: - printk(KERN_INFO "parport_pc: ITE8872 found (2S1P)\n"); + pr_info("parport_pc: ITE8872 found (2S1P)\n"); ite8872set = 0x64e00000; break; case 0x6: - printk(KERN_INFO "parport_pc: ITE8873 found (1S)\n"); + pr_info("parport_pc: ITE8873 found (1S)\n"); release_region(inta_addr[i], 32); return 0; case 0x8: - printk(KERN_INFO "parport_pc: ITE8874 found (2S)\n"); + pr_info("parport_pc: ITE8874 found (2S)\n"); release_region(inta_addr[i], 32); return 0; default: - printk(KERN_INFO "parport_pc: unknown ITE887x\n"); - printk(KERN_INFO "parport_pc: please mail 'lspci -nvv' " - "output to Rich.Liu@ite.com.tw\n"); + pr_info("parport_pc: unknown ITE887x\n"); + pr_info("parport_pc: please mail 'lspci -nvv' output to Rich.Liu@ite.com.tw\n"); release_region(inta_addr[i], 32); return 0; } @@ -2396,9 +2377,8 @@ release_region(inta_addr[i], 32); if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi, irq, PARPORT_DMA_NONE, &pdev->dev, 0)) { - printk(KERN_INFO - "parport_pc: ITE 8872 parallel port: io=0x%X", - ite8872_lpt); + pr_info("parport_pc: ITE 8872 parallel port: io=0x%X", + ite8872_lpt); if (irq != PARPORT_IRQ_NONE) pr_cont(", irq=%d", irq); pr_cont("\n"); @@ -2525,7 +2505,7 @@ pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp); if (siofunc == VIA_FUNCTION_PARPORT_DISABLE) { - printk(KERN_INFO "parport_pc: VIA parallel port disabled in BIOS\n"); + pr_info("parport_pc: VIA parallel port disabled in BIOS\n"); return 0; } @@ -2558,9 +2538,8 @@ case 0x278: port2 = 0x678; break; default: - printk(KERN_INFO - "parport_pc: Weird VIA parport base 0x%X, ignoring\n", - port1); + pr_info("parport_pc: Weird VIA parport base 0x%X, ignoring\n", + port1); return 0; } @@ -2579,8 +2558,7 @@ /* finally, do the probe with values obtained */ if (parport_pc_probe_port(port1, port2, irq, dma, &pdev->dev, 0)) { - printk(KERN_INFO - "parport_pc: VIA parallel port: io=0x%X", port1); + pr_info("parport_pc: VIA parallel port: io=0x%X", port1); if (irq != PARPORT_IRQ_NONE) pr_cont(", irq=%d", irq); if (dma != PARPORT_DMA_NONE) @@ -2589,7 +2567,7 @@ return 1; } - printk(KERN_WARNING "parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n", + pr_warn("parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n", port1, irq, dma); return 0; } @@ -2646,8 +2624,11 @@ netmos_9815, netmos_9901, netmos_9865, + asix_ax99100, quatech_sppxp100, wch_ch382l, + brainboxes_uc146, + brainboxes_px203, }; @@ -2709,8 +2690,11 @@ /* netmos_9815 */ { 2, { { 0, 1 }, { 2, 3 }, } }, /* netmos_9901 */ { 1, { { 0, -1 }, } }, /* netmos_9865 */ { 1, { { 0, -1 }, } }, + /* asix_ax99100 */ { 1, { { 0, 1 }, } }, /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, /* wch_ch382l */ { 1, { { 2, -1 }, } }, + /* brainboxes_uc146 */ { 1, { { 3, -1 }, } }, + /* brainboxes_px203 */ { 1, { { 0, -1 }, } }, }; static const struct pci_device_id parport_pc_pci_tbl[] = { @@ -2797,11 +2781,31 @@ 0xA000, 0x1000, 0, 0, netmos_9865 }, { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865, 0xA000, 0x2000, 0, 0, netmos_9865 }, + /* ASIX AX99100 PCIe to Multi I/O Controller */ + { PCI_VENDOR_ID_ASIX, PCI_DEVICE_ID_ASIX_AX99100, + 0xA000, 0x2000, 0, 0, asix_ax99100 }, /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, /* WCH CH382L PCI-E single parallel port card */ { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382l }, + /* Brainboxes IX-500/550 */ + { PCI_VENDOR_ID_INTASHIELD, 0x402a, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, + /* Brainboxes UC-146/UC-157 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0be1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0be2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc146 }, + /* Brainboxes PX-146/PX-257 */ + { PCI_VENDOR_ID_INTASHIELD, 0x401c, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, + /* Brainboxes PX-203 */ + { PCI_VENDOR_ID_INTASHIELD, 0x4007, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px203 }, + /* Brainboxes PX-475 */ + { PCI_VENDOR_ID_INTASHIELD, 0x401f, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, oxsemi_pcie_pport }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, parport_pc_pci_tbl); @@ -3111,7 +3115,7 @@ if (ep != s) *val = r; else { - printk(KERN_ERR "parport: bad specifier `%s'\n", s); + pr_err("parport: bad specifier `%s'\n", s); return -1; } } @@ -3201,10 +3205,7 @@ irqval[0] = val; break; default: - printk(KERN_WARNING - "parport_pc: irq specified " - "without base address. Use 'io=' " - "to specify one\n"); + pr_warn("parport_pc: irq specified without base address. Use 'io=' to specify one\n"); } if (dma[0] && !parport_parse_dma(dma[0], &val)) @@ -3214,10 +3215,7 @@ dmaval[0] = val; break; default: - printk(KERN_WARNING - "parport_pc: dma specified " - "without base address. Use 'io=' " - "to specify one\n"); + pr_warn("parport_pc: dma specified without base address. Use 'io=' to specify one\n"); } } return 0; @@ -3256,12 +3254,12 @@ val = simple_strtoul(str, &endptr, 0); if (endptr == str) { - printk(KERN_WARNING "parport=%s not understood\n", str); + pr_warn("parport=%s not understood\n", str); return 1; } if (parport_setup_ptr == PARPORT_PC_MAX_PORTS) { - printk(KERN_ERR "parport=%s ignored, too many ports\n", str); + pr_err("parport=%s ignored, too many ports\n", str); return 1; } --- linux-oracle-5.4.0.orig/drivers/parport/parport_serial.c +++ linux-oracle-5.4.0/drivers/parport/parport_serial.c @@ -65,6 +65,10 @@ sunix_5069a, sunix_5079a, sunix_5099a, + brainboxes_uc257, + brainboxes_is300, + brainboxes_uc414, + brainboxes_px263, }; /* each element directly indexed from enum list, above */ @@ -158,6 +162,10 @@ /* sunix_5069a */ { 1, { { 1, 2 }, } }, /* sunix_5079a */ { 1, { { 1, 2 }, } }, /* sunix_5099a */ { 1, { { 1, 2 }, } }, + /* brainboxes_uc257 */ { 1, { { 3, -1 }, } }, + /* brainboxes_is300 */ { 1, { { 3, -1 }, } }, + /* brainboxes_uc414 */ { 1, { { 3, -1 }, } }, + /* brainboxes_px263 */ { 1, { { 3, -1 }, } }, }; static struct pci_device_id parport_serial_pci_tbl[] = { @@ -277,6 +285,38 @@ { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, 0x0104, 0, 0, sunix_5099a }, + /* Brainboxes UC-203 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0bc1, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0bc2, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes UC-257 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0861, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0862, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0863, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes UC-414 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0e61, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc414 }, + + /* Brainboxes UC-475 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0981, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + { PCI_VENDOR_ID_INTASHIELD, 0x0982, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, + + /* Brainboxes IS-300/IS-500 */ + { PCI_VENDOR_ID_INTASHIELD, 0x0da0, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_is300 }, + + /* Brainboxes PX-263/PX-295 */ + { PCI_VENDOR_ID_INTASHIELD, 0x402c, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px263 }, + { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); @@ -542,6 +582,30 @@ .base_baud = 921600, .uart_offset = 0x8, }, + [brainboxes_uc257] = { + .flags = FL_BASE2, + .num_ports = 2, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_is300] = { + .flags = FL_BASE2, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_uc414] = { + .flags = FL_BASE2, + .num_ports = 4, + .base_baud = 115200, + .uart_offset = 8, + }, + [brainboxes_px263] = { + .flags = FL_BASE2, + .num_ports = 4, + .base_baud = 921600, + .uart_offset = 8, + }, }; struct parport_serial_private { --- linux-oracle-5.4.0.orig/drivers/parport/parport_sunbpp.c +++ linux-oracle-5.4.0/drivers/parport/parport_sunbpp.c @@ -314,7 +314,7 @@ value_tcr &= ~P_TCR_DIR; sbus_writeb(value_tcr, ®s->p_tcr); - printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); + pr_info("%s: sunbpp at 0x%lx\n", p->name, p->base); dev_set_drvdata(&op->dev, p); --- linux-oracle-5.4.0.orig/drivers/parport/probe.c +++ linux-oracle-5.4.0/drivers/parport/probe.c @@ -38,7 +38,7 @@ { struct parport_device_info *info = &port->probe_info[device + 1]; - printk(KERN_INFO "%s", port->name); + pr_info("%s", port->name); if (device >= 0) printk (" (addr %d)", device); @@ -58,7 +58,7 @@ struct parport_device_info *info = &port->probe_info[device + 1]; if (!txt) { - printk(KERN_WARNING "%s probe: memory squeeze\n", port->name); + pr_warn("%s probe: memory squeeze\n", port->name); return; } strcpy(txt, str); @@ -98,7 +98,8 @@ goto rock_on; } } - printk(KERN_WARNING "%s probe: warning, class '%s' not understood.\n", port->name, sep); + pr_warn("%s probe: warning, class '%s' not understood\n", + port->name, sep); info->class = PARPORT_CLASS_OTHER; } else if (!strcmp(p, "CMD") || !strcmp(p, "COMMAND SET")) { --- linux-oracle-5.4.0.orig/drivers/parport/procfs.c +++ linux-oracle-5.4.0/drivers/parport/procfs.c @@ -51,12 +51,12 @@ for (dev = port->devices; dev ; dev = dev->next) { if(dev == port->cad) { - len += sprintf(buffer, "%s\n", dev->name); + len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name); } } if(!len) { - len += sprintf(buffer, "%s\n", "none"); + len += scnprintf(buffer, sizeof(buffer), "%s\n", "none"); } if (len > *lenp) @@ -87,19 +87,19 @@ } if ((str = info->class_name) != NULL) - len += sprintf (buffer + len, "CLASS:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); if ((str = info->model) != NULL) - len += sprintf (buffer + len, "MODEL:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); if ((str = info->mfr) != NULL) - len += sprintf (buffer + len, "MANUFACTURER:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); if ((str = info->description) != NULL) - len += sprintf (buffer + len, "DESCRIPTION:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); if ((str = info->cmdset) != NULL) - len += sprintf (buffer + len, "COMMAND SET:%s;\n", str); + len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); if (len > *lenp) len = *lenp; @@ -117,7 +117,7 @@ size_t *lenp, loff_t *ppos) { struct parport *port = (struct parport *)table->extra1; - char buffer[20]; + char buffer[64]; int len = 0; if (*ppos) { @@ -128,7 +128,7 @@ if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%lu\t%lu\n", port->base, port->base_hi); + len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); if (len > *lenp) len = *lenp; @@ -156,7 +156,7 @@ if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%d\n", port->irq); + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq); if (len > *lenp) len = *lenp; @@ -184,7 +184,7 @@ if (write) /* permissions prevent this anyway */ return -EACCES; - len += sprintf (buffer, "%d\n", port->dma); + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma); if (len > *lenp) len = *lenp; @@ -213,7 +213,11 @@ return -EACCES; { -#define printmode(x) {if(port->modes&PARPORT_MODE_##x){len+=sprintf(buffer+len,"%s%s",f?",":"",#x);f++;}} +#define printmode(x) \ +do { \ + if (port->modes & PARPORT_MODE_##x) \ + len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ +} while (0) int f = 0; printmode(PCSPP); printmode(TRISTATE); --- linux-oracle-5.4.0.orig/drivers/parport/share.c +++ linux-oracle-5.4.0/drivers/parport/share.c @@ -230,6 +230,18 @@ return 0; } +/* + * Iterates through all the devices connected to the bus and return 1 + * if the device is a parallel port. + */ + +static int port_detect(struct device *dev, void *dev_drv) +{ + if (is_parport(dev)) + return 1; + return 0; +} + /** * parport_register_driver - register a parallel port device driver * @drv: structure describing the driver @@ -282,6 +294,15 @@ if (ret) return ret; + /* + * check if bus has any parallel port registered, if + * none is found then load the lowlevel driver. + */ + ret = bus_for_each_dev(&parport_bus_type, NULL, NULL, + port_detect); + if (!ret) + get_lowlevel_driver(); + mutex_lock(®istration_lock); if (drv->match_port) bus_for_each_dev(&parport_bus_type, NULL, drv, @@ -534,8 +555,8 @@ #endif if (!port->dev) - printk(KERN_WARNING "%s: fix this legacy no-device port driver!\n", - port->name); + pr_warn("%s: fix this legacy no-device port driver!\n", + port->name); parport_proc_register(port); mutex_lock(®istration_lock); @@ -707,7 +728,8 @@ if (flags & PARPORT_DEV_LURK) { if (!pf || !kf) { - printk(KERN_INFO "%s: refused to register lurking device (%s) without callbacks\n", port->name, name); + pr_info("%s: refused to register lurking device (%s) without callbacks\n", + port->name, name); return NULL; } } @@ -976,7 +998,7 @@ #ifdef PARPORT_PARANOID if (!dev) { - printk(KERN_ERR "parport_unregister_device: passed NULL\n"); + pr_err("%s: passed NULL\n", __func__); return; } #endif @@ -1117,8 +1139,7 @@ unsigned long flags; if (port->cad == dev) { - printk(KERN_INFO "%s: %s already owner\n", - dev->port->name,dev->name); + pr_info("%s: %s already owner\n", dev->port->name, dev->name); return 0; } @@ -1138,9 +1159,8 @@ * I think we'll actually deadlock rather than * get here, but just in case.. */ - printk(KERN_WARNING - "%s: %s released port when preempted!\n", - port->name, oldcad->name); + pr_warn("%s: %s released port when preempted!\n", + port->name, oldcad->name); if (port->cad) goto blocked; } @@ -1300,8 +1320,8 @@ write_lock_irqsave(&port->cad_lock, flags); if (port->cad != dev) { write_unlock_irqrestore(&port->cad_lock, flags); - printk(KERN_WARNING "%s: %s tried to release parport when not owner\n", - port->name, dev->name); + pr_warn("%s: %s tried to release parport when not owner\n", + port->name, dev->name); return; } @@ -1341,7 +1361,8 @@ if (dev->port->cad) /* racy but no matter */ return; } else { - printk(KERN_ERR "%s: don't know how to wake %s\n", port->name, pd->name); + pr_err("%s: don't know how to wake %s\n", + port->name, pd->name); } } --- linux-oracle-5.4.0.orig/drivers/pci/access.c +++ linux-oracle-5.4.0/drivers/pci/access.c @@ -160,9 +160,12 @@ * write happen to have any RW1C (write-one-to-clear) bits set, we * just inadvertently cleared something we shouldn't have. */ - dev_warn_ratelimited(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n", - size, pci_domain_nr(bus), bus->number, - PCI_SLOT(devfn), PCI_FUNC(devfn), where); + if (!bus->unsafe_warn) { + dev_warn(&bus->dev, "%d-byte config write to %04x:%02x:%02x.%d offset %#x may corrupt adjacent RW1C bits\n", + size, pci_domain_nr(bus), bus->number, + PCI_SLOT(devfn), PCI_FUNC(devfn), where); + bus->unsafe_warn = 1; + } mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); tmp = readl(addr) & mask; @@ -204,17 +207,13 @@ static DECLARE_WAIT_QUEUE_HEAD(pci_cfg_wait); static noinline void pci_wait_cfg(struct pci_dev *dev) + __must_hold(&pci_lock) { - DECLARE_WAITQUEUE(wait, current); - - __add_wait_queue(&pci_cfg_wait, &wait); do { - set_current_state(TASK_UNINTERRUPTIBLE); raw_spin_unlock_irq(&pci_lock); - schedule(); + wait_event(pci_cfg_wait, !dev->block_cfg_access); raw_spin_lock_irq(&pci_lock); } while (dev->block_cfg_access); - __remove_wait_queue(&pci_cfg_wait, &wait); } /* Returns 0 on success, negative values indicate error. */ --- linux-oracle-5.4.0.orig/drivers/pci/bus.c +++ linux-oracle-5.4.0/drivers/pci/bus.c @@ -322,12 +322,8 @@ dev->match_driver = true; retval = device_attach(&dev->dev); - if (retval < 0 && retval != -EPROBE_DEFER) { + if (retval < 0 && retval != -EPROBE_DEFER) pci_warn(dev, "device attach failed (%d)\n", retval); - pci_proc_detach_device(dev); - pci_remove_sysfs_dev_files(dev); - return; - } pci_dev_assign_added(dev, true); } --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pci-imx6.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pci-imx6.c @@ -413,6 +413,11 @@ dev_err(dev, "failed to disable vpcie regulator: %d\n", ret); } + + /* Some boards don't have PCIe reset GPIO. */ + if (gpio_is_valid(imx6_pcie->reset_gpio)) + gpio_set_value_cansleep(imx6_pcie->reset_gpio, + imx6_pcie->gpio_active_high); } static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie) @@ -535,15 +540,6 @@ /* allow the clocks to stabilize */ usleep_range(200, 500); - /* Some boards don't have PCIe reset GPIO. */ - if (gpio_is_valid(imx6_pcie->reset_gpio)) { - gpio_set_value_cansleep(imx6_pcie->reset_gpio, - imx6_pcie->gpio_active_high); - msleep(100); - gpio_set_value_cansleep(imx6_pcie->reset_gpio, - !imx6_pcie->gpio_active_high); - } - switch (imx6_pcie->drvdata->variant) { case IMX8MQ: reset_control_deassert(imx6_pcie->pciephy_reset); @@ -586,6 +582,15 @@ break; } + /* Some boards don't have PCIe reset GPIO. */ + if (gpio_is_valid(imx6_pcie->reset_gpio)) { + msleep(100); + gpio_set_value_cansleep(imx6_pcie->reset_gpio, + !imx6_pcie->gpio_active_high); + /* Wait for 100ms after PERST# deassertion (PCIe r5.0, 6.6.1) */ + msleep(100); + } + return; err_ref_clk: @@ -1290,6 +1295,13 @@ static int __init imx6_pcie_init(void) { #ifdef CONFIG_ARM + struct device_node *np; + + np = of_find_matching_node(NULL, imx6_pcie_of_match); + if (!np) + return -ENODEV; + of_node_put(np); + /* * Since probe() can be deferred we need to make sure that * hook_fault_code is not called after __init memory is freed --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pci-keystone.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pci-keystone.c @@ -35,6 +35,11 @@ #define PCIE_DEVICEID_SHIFT 16 /* Application registers */ +#define PID 0x000 +#define RTL GENMASK(15, 11) +#define RTL_SHIFT 11 +#define AM6_PCI_PG1_RTL_VER 0x15 + #define CMD_STATUS 0x004 #define LTSSM_EN_VAL BIT(0) #define OB_XLAT_EN_VAL BIT(1) @@ -107,6 +112,8 @@ #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) +#define PCI_DEVICE_ID_TI_AM654X 0xb00c + struct ks_pcie_of_data { enum dw_pcie_device_mode mode; const struct dw_pcie_host_ops *host_ops; @@ -422,7 +429,7 @@ lower_32_bits(start) | OB_ENABLEN); ks_pcie_app_writel(ks_pcie, OB_OFFSET_HI(i), upper_32_bits(start)); - start += OB_WIN_SIZE; + start += OB_WIN_SIZE * SZ_1M; } val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); @@ -510,7 +517,7 @@ /* Disable Link training */ val = ks_pcie_app_readl(ks_pcie, CMD_STATUS); val &= ~LTSSM_EN_VAL; - ks_pcie_app_writel(ks_pcie, CMD_STATUS, LTSSM_EN_VAL | val); + ks_pcie_app_writel(ks_pcie, CMD_STATUS, val); } static int ks_pcie_start_link(struct dw_pcie *pci) @@ -534,7 +541,11 @@ static void ks_pcie_quirk(struct pci_dev *dev) { struct pci_bus *bus = dev->bus; + struct keystone_pcie *ks_pcie; + struct device *bridge_dev; struct pci_dev *bridge; + u32 val; + static const struct pci_device_id rc_pci_devids[] = { { PCI_DEVICE(PCI_VENDOR_ID_TI, PCIE_RC_K2HK), .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, @@ -546,6 +557,11 @@ .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, { 0, }, }; + static const struct pci_device_id am6_pci_devids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_AM654X), + .class = PCI_CLASS_BRIDGE_PCI << 8, .class_mask = ~0, }, + { 0, }, + }; if (pci_is_root_bus(bus)) bridge = dev; @@ -567,10 +583,36 @@ */ if (pci_match_id(rc_pci_devids, bridge)) { if (pcie_get_readrq(dev) > 256) { - dev_info(&dev->dev, "limiting MRRS to 256\n"); + dev_info(&dev->dev, "limiting MRRS to 256 bytes\n"); pcie_set_readrq(dev, 256); } } + + /* + * Memory transactions fail with PCI controller in AM654 PG1.0 + * when MRRS is set to more than 128 bytes. Force the MRRS to + * 128 bytes in all downstream devices. + */ + if (pci_match_id(am6_pci_devids, bridge)) { + bridge_dev = pci_get_host_bridge_device(dev); + if (!bridge_dev || !bridge_dev->parent) + return; + + ks_pcie = dev_get_drvdata(bridge_dev->parent); + if (!ks_pcie) + return; + + val = ks_pcie_app_readl(ks_pcie, PID); + val &= RTL; + val >>= RTL_SHIFT; + if (val != AM6_PCI_PG1_RTL_VER) + return; + + if (pcie_get_readrq(dev) > 128) { + dev_info(&dev->dev, "limiting MRRS to 128 bytes\n"); + pcie_set_readrq(dev, 128); + } + } } DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, ks_pcie_quirk); @@ -861,8 +903,8 @@ return ks_pcie_handle_error_irq(ks_pcie); } -static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, - struct platform_device *pdev) +static int ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, + struct platform_device *pdev) { struct dw_pcie *pci = ks_pcie->pci; struct pcie_port *pp = &pci->pp; @@ -992,8 +1034,8 @@ .get_features = &ks_pcie_am654_get_features, }; -static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie, - struct platform_device *pdev) +static int ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie, + struct platform_device *pdev) { int ret; struct dw_pcie_ep *ep; @@ -1181,7 +1223,7 @@ { }, }; -static int __init ks_pcie_probe(struct platform_device *pdev) +static int ks_pcie_probe(struct platform_device *pdev) { const struct dw_pcie_host_ops *host_ops; const struct dw_pcie_ep_ops *ep_ops; @@ -1305,7 +1347,16 @@ goto err_link; } + /* Obtain references to the PHYs */ + for (i = 0; i < num_lanes; i++) + phy_pm_runtime_get_sync(ks_pcie->phy[i]); + ret = ks_pcie_enable_phy(ks_pcie); + + /* Release references to the PHYs */ + for (i = 0; i < num_lanes; i++) + phy_pm_runtime_put_sync(ks_pcie->phy[i]); + if (ret) { dev_err(dev, "failed to enable phy\n"); goto err_link; @@ -1354,7 +1405,7 @@ ret = of_property_read_u32(np, "num-viewport", &num_viewport); if (ret < 0) { dev_err(dev, "unable to read *num-viewport* property\n"); - return ret; + goto err_get_sync; } /* @@ -1407,7 +1458,7 @@ return ret; } -static int __exit ks_pcie_remove(struct platform_device *pdev) +static int ks_pcie_remove(struct platform_device *pdev) { struct keystone_pcie *ks_pcie = platform_get_drvdata(pdev); struct device_link **link = ks_pcie->link; @@ -1423,9 +1474,9 @@ return 0; } -static struct platform_driver ks_pcie_driver __refdata = { +static struct platform_driver ks_pcie_driver = { .probe = ks_pcie_probe, - .remove = __exit_p(ks_pcie_remove), + .remove = ks_pcie_remove, .driver = { .name = "keystone-pcie", .of_match_table = of_match_ptr(ks_pcie_of_match), --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pci-meson.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pci-meson.c @@ -250,15 +250,15 @@ if (IS_ERR(res->port_clk)) return PTR_ERR(res->port_clk); - res->mipi_gate = meson_pcie_probe_clock(dev, "pcie_mipi_en", 0); + res->mipi_gate = meson_pcie_probe_clock(dev, "mipi", 0); if (IS_ERR(res->mipi_gate)) return PTR_ERR(res->mipi_gate); - res->general_clk = meson_pcie_probe_clock(dev, "pcie_general", 0); + res->general_clk = meson_pcie_probe_clock(dev, "general", 0); if (IS_ERR(res->general_clk)) return PTR_ERR(res->general_clk); - res->clk = meson_pcie_probe_clock(dev, "pcie", 0); + res->clk = meson_pcie_probe_clock(dev, "pclk", 0); if (IS_ERR(res->clk)) return PTR_ERR(res->clk); @@ -301,11 +301,11 @@ meson_cfg_writel(mp, val, PCIE_CFG0); val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF); - val &= ~LINK_CAPABLE_MASK; + val &= ~(LINK_CAPABLE_MASK | FAST_LINK_MODE); meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF); val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF); - val |= LINK_CAPABLE_X1 | FAST_LINK_MODE; + val |= LINK_CAPABLE_X1; meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF); val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF); --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pcie-designware-host.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pcie-designware-host.c @@ -78,7 +78,8 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) { int i, pos, irq; - u32 val, num_ctrls; + unsigned long val; + u32 status, num_ctrls; irqreturn_t ret = IRQ_NONE; num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; @@ -86,14 +87,14 @@ for (i = 0; i < num_ctrls; i++) { dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + (i * MSI_REG_CTRL_BLOCK_SIZE), - 4, &val); - if (!val) + 4, &status); + if (!status) continue; ret = IRQ_HANDLED; + val = status; pos = 0; - while ((pos = find_next_bit((unsigned long *) &val, - MAX_MSI_IRQS_PER_CTRL, + while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, pos)) != MAX_MSI_IRQS_PER_CTRL) { irq = irq_find_mapping(pp->irq_domain, (i * MAX_MSI_IRQS_PER_CTRL) + @@ -262,6 +263,8 @@ return -ENOMEM; } + irq_domain_update_bus_token(pp->irq_domain, DOMAIN_BUS_NEXUS); + pp->msi_domain = pci_msi_create_irq_domain(fwnode, &dw_pcie_msi_domain_info, pp->irq_domain); --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pcie-qcom.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pcie-qcom.c @@ -45,7 +45,13 @@ #define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10 #define PCIE20_PARF_PHY_CTRL 0x40 +#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK GENMASK(20, 16) +#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) ((x) << 16) + #define PCIE20_PARF_PHY_REFCLK 0x4C +#define PHY_REFCLK_SSP_EN BIT(16) +#define PHY_REFCLK_USE_PAD BIT(12) + #define PCIE20_PARF_DBI_BASE_ADDR 0x168 #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174 @@ -76,6 +82,18 @@ #define DBI_RO_WR_EN 1 #define PERST_DELAY_US 1000 +/* PARF registers */ +#define PCIE20_PARF_PCS_DEEMPH 0x34 +#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16) +#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8) +#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0) + +#define PCIE20_PARF_PCS_SWING 0x38 +#define PCS_SWING_TX_SWING_FULL(x) ((x) << 8) +#define PCS_SWING_TX_SWING_LOW(x) ((x) << 0) + +#define PCIE20_PARF_CONFIG_BITS 0x50 +#define PHY_RX0_EQ(x) ((x) << 24) #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 #define SLV_ADDR_SPACE_SZ 0x10000000 @@ -85,11 +103,14 @@ struct clk *iface_clk; struct clk *core_clk; struct clk *phy_clk; + struct clk *aux_clk; + struct clk *ref_clk; struct reset_control *pci_reset; struct reset_control *axi_reset; struct reset_control *ahb_reset; struct reset_control *por_reset; struct reset_control *phy_reset; + struct reset_control *ext_reset; struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; }; @@ -235,6 +256,14 @@ if (IS_ERR(res->phy_clk)) return PTR_ERR(res->phy_clk); + res->aux_clk = devm_clk_get_optional(dev, "aux"); + if (IS_ERR(res->aux_clk)) + return PTR_ERR(res->aux_clk); + + res->ref_clk = devm_clk_get_optional(dev, "ref"); + if (IS_ERR(res->ref_clk)) + return PTR_ERR(res->ref_clk); + res->pci_reset = devm_reset_control_get_exclusive(dev, "pci"); if (IS_ERR(res->pci_reset)) return PTR_ERR(res->pci_reset); @@ -251,6 +280,10 @@ if (IS_ERR(res->por_reset)) return PTR_ERR(res->por_reset); + res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext"); + if (IS_ERR(res->ext_reset)) + return PTR_ERR(res->ext_reset); + res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); return PTR_ERR_OR_ZERO(res->phy_reset); } @@ -259,14 +292,20 @@ { struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; + clk_disable_unprepare(res->phy_clk); reset_control_assert(res->pci_reset); reset_control_assert(res->axi_reset); reset_control_assert(res->ahb_reset); reset_control_assert(res->por_reset); - reset_control_assert(res->pci_reset); + reset_control_assert(res->ext_reset); + reset_control_assert(res->phy_reset); clk_disable_unprepare(res->iface_clk); clk_disable_unprepare(res->core_clk); - clk_disable_unprepare(res->phy_clk); + clk_disable_unprepare(res->aux_clk); + clk_disable_unprepare(res->ref_clk); + + writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL); + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); } @@ -275,9 +314,20 @@ struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; struct dw_pcie *pci = pcie->pci; struct device *dev = pci->dev; + struct device_node *node = dev->of_node; u32 val; int ret; + /* reset the PCIe interface as uboot can leave it undefined state */ + reset_control_assert(res->pci_reset); + reset_control_assert(res->axi_reset); + reset_control_assert(res->ahb_reset); + reset_control_assert(res->por_reset); + reset_control_assert(res->ext_reset); + reset_control_assert(res->phy_reset); + + writel(1, pcie->parf + PCIE20_PARF_PHY_CTRL); + ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); if (ret < 0) { dev_err(dev, "cannot enable regulators\n"); @@ -296,32 +346,66 @@ goto err_assert_ahb; } - ret = clk_prepare_enable(res->phy_clk); - if (ret) { - dev_err(dev, "cannot prepare/enable phy clock\n"); - goto err_clk_phy; - } - ret = clk_prepare_enable(res->core_clk); if (ret) { dev_err(dev, "cannot prepare/enable core clock\n"); goto err_clk_core; } + ret = clk_prepare_enable(res->aux_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable aux clock\n"); + goto err_clk_aux; + } + + ret = clk_prepare_enable(res->ref_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable ref clock\n"); + goto err_clk_ref; + } + ret = reset_control_deassert(res->ahb_reset); if (ret) { dev_err(dev, "cannot deassert ahb reset\n"); goto err_deassert_ahb; } + ret = reset_control_deassert(res->ext_reset); + if (ret) { + dev_err(dev, "cannot deassert ext reset\n"); + goto err_deassert_ahb; + } + /* enable PCIe clocks and resets */ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); val &= ~BIT(0); writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); + if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) { + writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) | + PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) | + PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34), + pcie->parf + PCIE20_PARF_PCS_DEEMPH); + writel(PCS_SWING_TX_SWING_FULL(120) | + PCS_SWING_TX_SWING_LOW(120), + pcie->parf + PCIE20_PARF_PCS_SWING); + writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS); + } + + if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) { + /* set TX termination offset */ + val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); + val &= ~PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK; + val |= PHY_CTRL_PHY_TX0_TERM_OFFSET(7); + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); + } + /* enable external reference clock */ val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); - val |= BIT(16); + /* USE_PAD is required only for ipq806x */ + if (!of_device_is_compatible(node, "qcom,pcie-apq8064")) + val &= ~PHY_REFCLK_USE_PAD; + val |= PHY_REFCLK_SSP_EN; writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); ret = reset_control_deassert(res->phy_reset); @@ -348,6 +432,12 @@ return ret; } + ret = clk_prepare_enable(res->phy_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable phy clock\n"); + goto err_deassert_ahb; + } + /* wait for clock acquisition */ usleep_range(1000, 1500); @@ -361,10 +451,12 @@ return 0; err_deassert_ahb: + clk_disable_unprepare(res->ref_clk); +err_clk_ref: + clk_disable_unprepare(res->aux_clk); +err_clk_aux: clk_disable_unprepare(res->core_clk); err_clk_core: - clk_disable_unprepare(res->phy_clk); -err_clk_phy: clk_disable_unprepare(res->iface_clk); err_assert_ahb: regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); @@ -1251,22 +1343,21 @@ } ret = phy_init(pcie->phy); - if (ret) { - pm_runtime_disable(&pdev->dev); + if (ret) goto err_pm_runtime_put; - } platform_set_drvdata(pdev, pcie); ret = dw_pcie_host_init(pp); if (ret) { dev_err(dev, "cannot initialize host\n"); - pm_runtime_disable(&pdev->dev); - goto err_pm_runtime_put; + goto err_phy_exit; } return 0; +err_phy_exit: + phy_exit(pcie->phy); err_pm_runtime_put: pm_runtime_put(dev); pm_runtime_disable(dev); @@ -1289,7 +1380,13 @@ { dev->class = PCI_CLASS_BRIDGE_PCI << 8; } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, PCI_ANY_ID, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0101, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0104, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0106, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0107, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x0302, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1000, qcom_fixup_class); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_QCOM, 0x1001, qcom_fixup_class); static struct platform_driver qcom_pcie_driver = { .probe = qcom_pcie_probe, --- linux-oracle-5.4.0.orig/drivers/pci/controller/dwc/pcie-tegra194.c +++ linux-oracle-5.4.0/drivers/pci/controller/dwc/pcie-tegra194.c @@ -7,6 +7,7 @@ * Author: Vidya Sagar */ +#include #include #include #include @@ -321,8 +322,7 @@ */ val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA); if (val & PCI_EXP_LNKSTA_LBMS) { - current_link_width = (val & PCI_EXP_LNKSTA_NLW) >> - PCI_EXP_LNKSTA_NLW_SHIFT; + current_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val); if (pcie->init_link_width > current_link_width) { dev_warn(pci->dev, "PCIe link is bad, width reduced\n"); val = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + @@ -345,15 +345,14 @@ { struct dw_pcie *pci = &pcie->pci; struct pcie_port *pp = &pci->pp; - u32 val, tmp; + u32 val, status_l0, status_l1; u16 val_w; - val = appl_readl(pcie, APPL_INTR_STATUS_L0); - if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); - if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) { - appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0); - + status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0); + if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0); + appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0); + if (status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) { /* SBR & Surprise Link Down WAR */ val = appl_readl(pcie, APPL_CAR_RESET_OVRD); val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N; @@ -369,15 +368,15 @@ } } - if (val & APPL_INTR_STATUS_L0_INT_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0); - if (val & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) { + if (status_l0 & APPL_INTR_STATUS_L0_INT_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_8_0); + if (status_l1 & APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS) { appl_writel(pcie, APPL_INTR_STATUS_L1_8_0_AUTO_BW_INT_STS, APPL_INTR_STATUS_L1_8_0); apply_bad_link_workaround(pp); } - if (val & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) { + if (status_l1 & APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS) { appl_writel(pcie, APPL_INTR_STATUS_L1_8_0_BW_MGT_INT_STS, APPL_INTR_STATUS_L1_8_0); @@ -389,25 +388,24 @@ } } - val = appl_readl(pcie, APPL_INTR_STATUS_L0); - if (val & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) { - val = appl_readl(pcie, APPL_INTR_STATUS_L1_18); - tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) { + if (status_l0 & APPL_INTR_STATUS_L0_CDM_REG_CHK_INT) { + status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_18); + val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS); + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMPLT) { dev_info(pci->dev, "CDM check complete\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE; + val |= PCIE_PL_CHK_REG_CHK_REG_COMPLETE; } - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) { + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_CMP_ERR) { dev_err(pci->dev, "CDM comparison mismatch\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR; + val |= PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR; } - if (val & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) { + if (status_l1 & APPL_INTR_STATUS_L1_18_CDM_REG_CHK_LOGIC_ERR) { dev_err(pci->dev, "CDM Logic error\n"); - tmp |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR; + val |= PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR; } - dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, tmp); - tmp = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR); - dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", tmp); + dw_pcie_writel_dbi(pci, PCIE_PL_CHK_REG_CONTROL_STATUS, val); + val = dw_pcie_readl_dbi(pci, PCIE_PL_CHK_REG_ERR_ADDR); + dev_err(pci->dev, "CDM Error Address Offset = 0x%08X\n", val); } return IRQ_HANDLED; @@ -598,8 +596,7 @@ val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + PCI_EXP_LNKSTA); - pcie->init_link_width = (val_w & PCI_EXP_LNKSTA_NLW) >> - PCI_EXP_LNKSTA_NLW_SHIFT; + pcie->init_link_width = FIELD_GET(PCI_EXP_LNKSTA_NLW, val_w); val_w = dw_pcie_readw_dbi(&pcie->pci, pcie->pcie_cap_base + PCI_EXP_LNKCTL); @@ -775,7 +772,7 @@ /* Configure Max lane width from DT */ val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP); val &= ~PCI_EXP_LNKCAP_MLW; - val |= (pcie->num_lanes << PCI_EXP_LNKSTA_NLW_SHIFT); + val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, pcie->num_lanes); dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, val); config_gen3_gen4_eq_presets(pcie); @@ -856,7 +853,7 @@ offset = dw_pcie_find_ext_capability(pci, PCI_EXT_CAP_ID_DLF); val = dw_pcie_readl_dbi(pci, offset + PCI_DLF_CAP); val &= ~PCI_DLF_EXCHANGE_ENABLE; - dw_pcie_writel_dbi(pci, offset, val); + dw_pcie_writel_dbi(pci, offset + PCI_DLF_CAP, val); tegra_pcie_prepare_host(pp); @@ -1395,7 +1392,7 @@ ret = pinctrl_pm_select_default_state(dev); if (ret < 0) { dev_err(dev, "Failed to configure sideband pins: %d\n", ret); - goto fail_pinctrl; + goto fail_pm_get_sync; } tegra_pcie_init_controller(pcie); @@ -1422,9 +1419,8 @@ fail_host_init: tegra_pcie_deinit_controller(pcie); -fail_pinctrl: - pm_runtime_put_sync(dev); fail_pm_get_sync: + pm_runtime_put_sync(dev); pm_runtime_disable(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-aardvark.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-aardvark.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include "../pci.h" @@ -25,21 +27,8 @@ /* PCIe core registers */ #define PCIE_CORE_DEV_ID_REG 0x0 #define PCIE_CORE_CMD_STATUS_REG 0x4 -#define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) -#define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) -#define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) #define PCIE_CORE_DEV_REV_REG 0x8 #define PCIE_CORE_PCIEXP_CAP 0xc0 -#define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 -#define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) -#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 -#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) -#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 -#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 -#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 -#define PCIE_CORE_LINK_L0S_ENTRY BIT(0) -#define PCIE_CORE_LINK_TRAINING BIT(5) -#define PCIE_CORE_LINK_WIDTH_SHIFT 20 #define PCIE_CORE_ERR_CAPCTL_REG 0x118 #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) @@ -61,7 +50,8 @@ #define PIO_COMPLETION_STATUS_UR 1 #define PIO_COMPLETION_STATUS_CRS 2 #define PIO_COMPLETION_STATUS_CA 4 -#define PIO_NON_POSTED_REQ BIT(0) +#define PIO_NON_POSTED_REQ BIT(10) +#define PIO_ERR_STATUS BIT(11) #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) @@ -107,27 +97,112 @@ #define PCIE_ISR0_MSI_INT_PENDING BIT(24) #define PCIE_ISR0_INTX_ASSERT(val) BIT(16 + (val)) #define PCIE_ISR0_INTX_DEASSERT(val) BIT(20 + (val)) -#define PCIE_ISR0_ALL_MASK GENMASK(26, 0) +#define PCIE_ISR0_ALL_MASK GENMASK(31, 0) #define PCIE_ISR1_REG (CONTROL_BASE_ADDR + 0x48) #define PCIE_ISR1_MASK_REG (CONTROL_BASE_ADDR + 0x4C) #define PCIE_ISR1_POWER_STATE_CHANGE BIT(4) #define PCIE_ISR1_FLUSH BIT(5) #define PCIE_ISR1_INTX_ASSERT(val) BIT(8 + (val)) -#define PCIE_ISR1_ALL_MASK GENMASK(11, 4) +#define PCIE_ISR1_ALL_MASK GENMASK(31, 0) #define PCIE_MSI_ADDR_LOW_REG (CONTROL_BASE_ADDR + 0x50) #define PCIE_MSI_ADDR_HIGH_REG (CONTROL_BASE_ADDR + 0x54) #define PCIE_MSI_STATUS_REG (CONTROL_BASE_ADDR + 0x58) #define PCIE_MSI_MASK_REG (CONTROL_BASE_ADDR + 0x5C) +#define PCIE_MSI_ALL_MASK GENMASK(31, 0) #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) +#define PCIE_MSI_DATA_MASK GENMASK(15, 0) + +/* PCIe window configuration */ +#define OB_WIN_BASE_ADDR 0x4c00 +#define OB_WIN_BLOCK_SIZE 0x20 +#define OB_WIN_COUNT 8 +#define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ + OB_WIN_BLOCK_SIZE * (win) + \ + (offset)) +#define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) +#define OB_WIN_ENABLE BIT(0) +#define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) +#define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) +#define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) +#define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) +#define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) +#define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) +#define OB_WIN_DEFAULT_ACTIONS (OB_WIN_ACTIONS(OB_WIN_COUNT-1) + 0x4) +#define OB_WIN_FUNC_NUM_MASK GENMASK(31, 24) +#define OB_WIN_FUNC_NUM_SHIFT 24 +#define OB_WIN_FUNC_NUM_ENABLE BIT(23) +#define OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20) +#define OB_WIN_BUS_NUM_BITS_SHIFT 20 +#define OB_WIN_MSG_CODE_ENABLE BIT(22) +#define OB_WIN_MSG_CODE_MASK GENMASK(21, 14) +#define OB_WIN_MSG_CODE_SHIFT 14 +#define OB_WIN_MSG_PAYLOAD_LEN BIT(12) +#define OB_WIN_ATTR_ENABLE BIT(11) +#define OB_WIN_ATTR_TC_MASK GENMASK(10, 8) +#define OB_WIN_ATTR_TC_SHIFT 8 +#define OB_WIN_ATTR_RELAXED BIT(7) +#define OB_WIN_ATTR_NOSNOOP BIT(6) +#define OB_WIN_ATTR_POISON BIT(5) +#define OB_WIN_ATTR_IDO BIT(4) +#define OB_WIN_TYPE_MASK GENMASK(3, 0) +#define OB_WIN_TYPE_SHIFT 0 +#define OB_WIN_TYPE_MEM 0x0 +#define OB_WIN_TYPE_IO 0x4 +#define OB_WIN_TYPE_CONFIG_TYPE0 0x8 +#define OB_WIN_TYPE_CONFIG_TYPE1 0x9 +#define OB_WIN_TYPE_MSG 0xc /* LMI registers base address and register offsets */ #define LMI_BASE_ADDR 0x6000 #define CFG_REG (LMI_BASE_ADDR + 0x0) #define LTSSM_SHIFT 24 #define LTSSM_MASK 0x3f -#define LTSSM_L0 0x10 #define RC_BAR_CONFIG 0x300 +/* LTSSM values in CFG_REG */ +enum { + LTSSM_DETECT_QUIET = 0x0, + LTSSM_DETECT_ACTIVE = 0x1, + LTSSM_POLLING_ACTIVE = 0x2, + LTSSM_POLLING_COMPLIANCE = 0x3, + LTSSM_POLLING_CONFIGURATION = 0x4, + LTSSM_CONFIG_LINKWIDTH_START = 0x5, + LTSSM_CONFIG_LINKWIDTH_ACCEPT = 0x6, + LTSSM_CONFIG_LANENUM_ACCEPT = 0x7, + LTSSM_CONFIG_LANENUM_WAIT = 0x8, + LTSSM_CONFIG_COMPLETE = 0x9, + LTSSM_CONFIG_IDLE = 0xa, + LTSSM_RECOVERY_RCVR_LOCK = 0xb, + LTSSM_RECOVERY_SPEED = 0xc, + LTSSM_RECOVERY_RCVR_CFG = 0xd, + LTSSM_RECOVERY_IDLE = 0xe, + LTSSM_L0 = 0x10, + LTSSM_RX_L0S_ENTRY = 0x11, + LTSSM_RX_L0S_IDLE = 0x12, + LTSSM_RX_L0S_FTS = 0x13, + LTSSM_TX_L0S_ENTRY = 0x14, + LTSSM_TX_L0S_IDLE = 0x15, + LTSSM_TX_L0S_FTS = 0x16, + LTSSM_L1_ENTRY = 0x17, + LTSSM_L1_IDLE = 0x18, + LTSSM_L2_IDLE = 0x19, + LTSSM_L2_TRANSMIT_WAKE = 0x1a, + LTSSM_DISABLED = 0x20, + LTSSM_LOOPBACK_ENTRY_MASTER = 0x21, + LTSSM_LOOPBACK_ACTIVE_MASTER = 0x22, + LTSSM_LOOPBACK_EXIT_MASTER = 0x23, + LTSSM_LOOPBACK_ENTRY_SLAVE = 0x24, + LTSSM_LOOPBACK_ACTIVE_SLAVE = 0x25, + LTSSM_LOOPBACK_EXIT_SLAVE = 0x26, + LTSSM_HOT_RESET = 0x27, + LTSSM_RECOVERY_EQUALIZATION_PHASE0 = 0x28, + LTSSM_RECOVERY_EQUALIZATION_PHASE1 = 0x29, + LTSSM_RECOVERY_EQUALIZATION_PHASE2 = 0x2a, + LTSSM_RECOVERY_EQUALIZATION_PHASE3 = 0x2b, +}; + +#define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44) + /* PCIe core controller registers */ #define CTRL_CORE_BASE_ADDR 0x18000 #define CTRL_CONFIG_REG (CTRL_CORE_BASE_ADDR + 0x0) @@ -158,7 +233,7 @@ #define PCIE_IRQ_MSI_INT2_DET BIT(21) #define PCIE_IRQ_RC_DBELL_DET BIT(22) #define PCIE_IRQ_EP_STATUS BIT(23) -#define PCIE_IRQ_ALL_MASK 0xfff0fb +#define PCIE_IRQ_ALL_MASK GENMASK(31, 0) #define PCIE_IRQ_ENABLE_INTS_MASK PCIE_IRQ_CORE_INT /* Transaction types */ @@ -175,20 +250,33 @@ (PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn)) | \ PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where)) -#define PIO_TIMEOUT_MS 1 +#define PIO_RETRY_CNT 750000 /* 1.5 s */ +#define PIO_RETRY_DELAY 2 /* 2 us*/ #define LINK_WAIT_MAX_RETRIES 10 #define LINK_WAIT_USLEEP_MIN 90000 #define LINK_WAIT_USLEEP_MAX 100000 +#define RETRAIN_WAIT_MAX_RETRIES 10 +#define RETRAIN_WAIT_USLEEP_US 2000 #define MSI_IRQ_NUM 32 +#define CFG_RD_CRS_VAL 0xffff0001 + struct advk_pcie { struct platform_device *pdev; void __iomem *base; struct list_head resources; + struct { + phys_addr_t match; + phys_addr_t remap; + phys_addr_t mask; + u32 actions; + } wins[OB_WIN_COUNT]; + u8 wins_count; struct irq_domain *irq_domain; struct irq_chip irq_chip; + raw_spinlock_t irq_lock; struct irq_domain *msi_domain; struct irq_domain *msi_inner_domain; struct irq_chip msi_bottom_irq_chip; @@ -198,7 +286,9 @@ struct mutex msi_used_lock; u16 msi_msg; int root_bus_nr; + int link_gen; struct pci_bridge_emul bridge; + struct gpio_desc *reset_gpio; }; static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) @@ -211,37 +301,186 @@ return readl(pcie->base + reg); } -static int advk_pcie_link_up(struct advk_pcie *pcie) +static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie) { - u32 val, ltssm_state; + u32 val; + u8 ltssm_state; val = advk_readl(pcie, CFG_REG); ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK; - return ltssm_state >= LTSSM_L0; + return ltssm_state; +} + +static inline bool advk_pcie_link_up(struct advk_pcie *pcie) +{ + /* check if LTSSM is in normal operation - some L* state */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; +} + +static inline bool advk_pcie_link_active(struct advk_pcie *pcie) +{ + /* + * According to PCIe Base specification 3.0, Table 4-14: Link + * Status Mapped to the LTSSM, and 4.2.6.3.6 Configuration.Idle + * is Link Up mapped to LTSSM Configuration.Idle, Recovery, L0, + * L0s, L1 and L2 states. And according to 3.2.1. Data Link + * Control and Management State Machine Rules is DL Up status + * reported in DL Active state. + */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ltssm_state >= LTSSM_CONFIG_IDLE && ltssm_state < LTSSM_DISABLED; +} + +static inline bool advk_pcie_link_training(struct advk_pcie *pcie) +{ + /* + * According to PCIe Base specification 3.0, Table 4-14: Link + * Status Mapped to the LTSSM is Link Training mapped to LTSSM + * Configuration and Recovery states. + */ + u8 ltssm_state = advk_pcie_ltssm_state(pcie); + return ((ltssm_state >= LTSSM_CONFIG_LINKWIDTH_START && + ltssm_state < LTSSM_L0) || + (ltssm_state >= LTSSM_RECOVERY_EQUALIZATION_PHASE0 && + ltssm_state <= LTSSM_RECOVERY_EQUALIZATION_PHASE3)); } static int advk_pcie_wait_for_link(struct advk_pcie *pcie) { - struct device *dev = &pcie->pdev->dev; int retries; /* check if the link is up or not */ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { - if (advk_pcie_link_up(pcie)) { - dev_info(dev, "link up\n"); + if (advk_pcie_link_up(pcie)) return 0; - } usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); } - dev_err(dev, "link never came up\n"); return -ETIMEDOUT; } +static void advk_pcie_wait_for_retrain(struct advk_pcie *pcie) +{ + size_t retries; + + for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) { + if (advk_pcie_link_training(pcie)) + break; + udelay(RETRAIN_WAIT_USLEEP_US); + } +} + +static void advk_pcie_issue_perst(struct advk_pcie *pcie) +{ + if (!pcie->reset_gpio) + return; + + /* 10ms delay is needed for some cards */ + dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); + gpiod_set_value_cansleep(pcie->reset_gpio, 1); + usleep_range(10000, 11000); + gpiod_set_value_cansleep(pcie->reset_gpio, 0); +} + +static void advk_pcie_train_link(struct advk_pcie *pcie) +{ + struct device *dev = &pcie->pdev->dev; + u32 reg; + int ret; + + /* + * Setup PCIe rev / gen compliance based on device tree property + * 'max-link-speed' which also forces maximal link speed. + */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~PCIE_GEN_SEL_MSK; + if (pcie->link_gen == 3) + reg |= SPEED_GEN_3; + else if (pcie->link_gen == 2) + reg |= SPEED_GEN_2; + else + reg |= SPEED_GEN_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* + * Set maximal link speed value also into PCIe Link Control 2 register. + * Armada 3700 Functional Specification says that default value is based + * on SPEED_GEN but tests showed that default value is always 8.0 GT/s. + */ + reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); + reg &= ~PCI_EXP_LNKCTL2_TLS; + if (pcie->link_gen == 3) + reg |= PCI_EXP_LNKCTL2_TLS_8_0GT; + else if (pcie->link_gen == 2) + reg |= PCI_EXP_LNKCTL2_TLS_5_0GT; + else + reg |= PCI_EXP_LNKCTL2_TLS_2_5GT; + advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); + + /* Enable link training after selecting PCIe generation */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg |= LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* + * Reset PCIe card via PERST# signal. Some cards are not detected + * during link training when they are in some non-initial state. + */ + advk_pcie_issue_perst(pcie); + + /* + * PERST# signal could have been asserted by pinctrl subsystem before + * probe() callback has been called or issued explicitly by reset gpio + * function advk_pcie_issue_perst(), making the endpoint going into + * fundamental reset. As required by PCI Express spec (PCI Express + * Base Specification, REV. 4.0 PCI Express, February 19 2014, 6.6.1 + * Conventional Reset) a delay for at least 100ms after such a reset + * before sending a Configuration Request to the device is needed. + * So wait until PCIe link is up. Function advk_pcie_wait_for_link() + * waits for link at least 900ms. + */ + ret = advk_pcie_wait_for_link(pcie); + if (ret < 0) + dev_err(dev, "link never came up\n"); + else + dev_info(dev, "link up\n"); +} + +/* + * Set PCIe address window register which could be used for memory + * mapping. + */ +static void advk_pcie_set_ob_win(struct advk_pcie *pcie, u8 win_num, + phys_addr_t match, phys_addr_t remap, + phys_addr_t mask, u32 actions) +{ + advk_writel(pcie, OB_WIN_ENABLE | + lower_32_bits(match), OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, upper_32_bits(match), OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, lower_32_bits(remap), OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, upper_32_bits(remap), OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, lower_32_bits(mask), OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, upper_32_bits(mask), OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, actions, OB_WIN_ACTIONS(win_num)); +} + +static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num) +{ + advk_writel(pcie, 0, OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_ACTIONS(win_num)); +} + static void advk_pcie_setup_hw(struct advk_pcie *pcie) { u32 reg; + int i; /* Set to Direct mode */ reg = advk_readl(pcie, CTRL_CONFIG_REG); @@ -254,6 +493,41 @@ reg |= (IS_RC_MSK << IS_RC_SHIFT); advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + /* + * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab. + * VENDOR_ID_REG contains vendor id in low 16 bits and subsystem vendor + * id in high 16 bits. Updating this register changes readback value of + * read-only vendor id bits in PCIE_CORE_DEV_ID_REG register. Workaround + * for erratum 4.1: "The value of device and vendor ID is incorrect". + */ + reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; + advk_writel(pcie, reg, VENDOR_ID_REG); + + /* + * Change Class Code of PCI Bridge device to PCI Bridge (0x600400), + * because the default value is Mass storage controller (0x010400). + * + * Note that this Aardvark PCI Bridge does not have compliant Type 1 + * Configuration Space and it even cannot be accessed via Aardvark's + * PCI config space access method. Something like config space is + * available in internal Aardvark registers starting at offset 0x0 + * and is reported as Type 0. In range 0x10 - 0x34 it has totally + * different registers. + * + * Therefore driver uses emulation of PCI Bridge which emulates + * access to configuration space via internal Aardvark registers or + * emulated configuration buffer. + */ + reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); + reg &= ~0xffffff00; + reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8; + advk_writel(pcie, reg, PCIE_CORE_DEV_REV_REG); + + /* Disable Root Bridge I/O space, memory space and bus mastering */ + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); + /* Set Advanced Error Capabilities and Control PF0 register */ reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | @@ -261,42 +535,34 @@ PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV; advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); - /* Set PCIe Device Control and Status 1 PF0 register */ - reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | - (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | - PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | - (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << - PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); - advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); + /* Set PCIe Device Control register */ + reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + reg &= ~PCI_EXP_DEVCTL_RELAX_EN; + reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; + reg &= ~PCI_EXP_DEVCTL_PAYLOAD; + reg &= ~PCI_EXP_DEVCTL_READRQ; + reg |= PCI_EXP_DEVCTL_PAYLOAD_512B; + reg |= PCI_EXP_DEVCTL_READRQ_512B; + advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); /* Program PCIe Control 2 to disable strict ordering */ reg = PCIE_CORE_CTRL2_RESERVED | PCIE_CORE_CTRL2_TD_ENABLE; advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); - /* Set GEN2 */ - reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); - reg &= ~PCIE_GEN_SEL_MSK; - reg |= SPEED_GEN_2; - advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); - /* Set lane X1 */ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); reg &= ~LANE_CNT_MSK; reg |= LANE_COUNT_1; advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); - /* Enable link training */ - reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); - reg |= LINK_TRAINING_EN; - advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); - /* Enable MSI */ reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); reg |= PCIE_CORE_CTRL2_MSI_ENABLE; advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); /* Clear all interrupts */ + advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_STATUS_REG); advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); @@ -309,97 +575,244 @@ advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); /* Unmask all MSIs */ - advk_writel(pcie, 0, PCIE_MSI_MASK_REG); + advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG); /* Enable summary interrupt for GIC SPI source */ reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); + /* + * Enable AXI address window location generation: + * When it is enabled, the default outbound window + * configurations (Default User Field: 0xD0074CFC) + * are used to transparent address translation for + * the outbound transactions. Thus, PCIe address + * windows are not required for transparent memory + * access when default outbound window configuration + * is set for memory access. + */ reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); - /* Bypass the address window mapping for PIO */ + /* + * Set memory access in Default User Field so it + * is not required to configure PCIe address for + * transparent memory access. + */ + advk_writel(pcie, OB_WIN_TYPE_MEM, OB_WIN_DEFAULT_ACTIONS); + + /* + * Bypass the address window mapping for PIO: + * Since PIO access already contains all required + * info over AXI interface by PIO registers, the + * address window is not required. + */ reg = advk_readl(pcie, PIO_CTRL); reg |= PIO_CTRL_ADDR_WIN_DISABLE; advk_writel(pcie, reg, PIO_CTRL); - /* Start link training */ - reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); - reg |= PCIE_CORE_LINK_TRAINING; - advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); - - advk_pcie_wait_for_link(pcie); - - reg = PCIE_CORE_LINK_L0S_ENTRY | - (1 << PCIE_CORE_LINK_WIDTH_SHIFT); - advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); + /* + * Configure PCIe address windows for non-memory or + * non-transparent access as by default PCIe uses + * transparent memory access. + */ + for (i = 0; i < pcie->wins_count; i++) + advk_pcie_set_ob_win(pcie, i, + pcie->wins[i].match, pcie->wins[i].remap, + pcie->wins[i].mask, pcie->wins[i].actions); + + /* Disable remaining PCIe outbound windows */ + for (i = pcie->wins_count; i < OB_WIN_COUNT; i++) + advk_pcie_disable_ob_win(pcie, i); - reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); - reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | - PCIE_CORE_CMD_IO_ACCESS_EN | - PCIE_CORE_CMD_MEM_IO_REQ_EN; - advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); + advk_pcie_train_link(pcie); } -static void advk_pcie_check_pio_status(struct advk_pcie *pcie) +static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val) { struct device *dev = &pcie->pdev->dev; u32 reg; unsigned int status; char *strcomp_status, *str_posted; + int ret; reg = advk_readl(pcie, PIO_STAT); status = (reg & PIO_COMPLETION_STATUS_MASK) >> PIO_COMPLETION_STATUS_SHIFT; - if (!status) - return; - + /* + * According to HW spec, the PIO status check sequence as below: + * 1) even if COMPLETION_STATUS(bit9:7) indicates successful, + * it still needs to check Error Status(bit11), only when this bit + * indicates no error happen, the operation is successful. + * 2) value Unsupported Request(1) of COMPLETION_STATUS(bit9:7) only + * means a PIO write error, and for PIO read it is successful with + * a read value of 0xFFFFFFFF. + * 3) value Completion Retry Status(CRS) of COMPLETION_STATUS(bit9:7) + * only means a PIO write error, and for PIO read it is successful + * with a read value of 0xFFFF0001. + * 4) value Completer Abort (CA) of COMPLETION_STATUS(bit9:7) means + * error for both PIO read and PIO write operation. + * 5) other errors are indicated as 'unknown'. + */ switch (status) { + case PIO_COMPLETION_STATUS_OK: + if (reg & PIO_ERR_STATUS) { + strcomp_status = "COMP_ERR"; + ret = -EFAULT; + break; + } + /* Get the read result */ + if (val) + *val = advk_readl(pcie, PIO_RD_DATA); + /* No error */ + strcomp_status = NULL; + ret = 0; + break; case PIO_COMPLETION_STATUS_UR: strcomp_status = "UR"; + ret = -EOPNOTSUPP; break; case PIO_COMPLETION_STATUS_CRS: + if (allow_crs && val) { + /* PCIe r4.0, sec 2.3.2, says: + * If CRS Software Visibility is enabled: + * For a Configuration Read Request that includes both + * bytes of the Vendor ID field of a device Function's + * Configuration Space Header, the Root Complex must + * complete the Request to the host by returning a + * read-data value of 0001h for the Vendor ID field and + * all '1's for any additional bytes included in the + * request. + * + * So CRS in this case is not an error status. + */ + *val = CFG_RD_CRS_VAL; + strcomp_status = NULL; + ret = 0; + break; + } + /* PCIe r4.0, sec 2.3.2, says: + * If CRS Software Visibility is not enabled, the Root Complex + * must re-issue the Configuration Request as a new Request. + * If CRS Software Visibility is enabled: For a Configuration + * Write Request or for any other Configuration Read Request, + * the Root Complex must re-issue the Configuration Request as + * a new Request. + * A Root Complex implementation may choose to limit the number + * of Configuration Request/CRS Completion Status loops before + * determining that something is wrong with the target of the + * Request and taking appropriate action, e.g., complete the + * Request to the host as a failed transaction. + * + * So return -EAGAIN and caller (pci-aardvark.c driver) will + * re-issue request again up to the PIO_RETRY_CNT retries. + */ strcomp_status = "CRS"; + ret = -EAGAIN; break; case PIO_COMPLETION_STATUS_CA: strcomp_status = "CA"; + ret = -ECANCELED; break; default: strcomp_status = "Unknown"; + ret = -EINVAL; break; } + if (!strcomp_status) + return ret; + if (reg & PIO_NON_POSTED_REQ) str_posted = "Non-posted"; else str_posted = "Posted"; - dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n", + dev_dbg(dev, "%s PIO Response Status: %s, %#x @ %#x\n", str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); + + return ret; } static int advk_pcie_wait_pio(struct advk_pcie *pcie) { struct device *dev = &pcie->pdev->dev; - unsigned long timeout; - - timeout = jiffies + msecs_to_jiffies(PIO_TIMEOUT_MS); + int i; - while (time_before(jiffies, timeout)) { + for (i = 1; i <= PIO_RETRY_CNT; i++) { u32 start, isr; start = advk_readl(pcie, PIO_START); isr = advk_readl(pcie, PIO_ISR); if (!start && isr) - return 0; + return i; + udelay(PIO_RETRY_DELAY); } - dev_err(dev, "config read/write timed out\n"); + dev_err(dev, "PIO read/write transfer time out\n"); return -ETIMEDOUT; } +static pci_bridge_emul_read_status_t +advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge, + int reg, u32 *value) +{ + struct advk_pcie *pcie = bridge->data; + + switch (reg) { + case PCI_COMMAND: + *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + return PCI_BRIDGE_EMUL_HANDLED; + + case PCI_INTERRUPT_LINE: { + /* + * From the whole 32bit register we support reading from HW only + * one bit: PCI_BRIDGE_CTL_BUS_RESET. + * Other bits are retrieved only from emulated config buffer. + */ + __le32 *cfgspace = (__le32 *)&bridge->conf; + u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]); + if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN) + val |= PCI_BRIDGE_CTL_BUS_RESET << 16; + else + val &= ~(PCI_BRIDGE_CTL_BUS_RESET << 16); + *value = val; + return PCI_BRIDGE_EMUL_HANDLED; + } + + default: + return PCI_BRIDGE_EMUL_NOT_HANDLED; + } +} + +static void +advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, + int reg, u32 old, u32 new, u32 mask) +{ + struct advk_pcie *pcie = bridge->data; + + switch (reg) { + case PCI_COMMAND: + advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); + break; + + case PCI_INTERRUPT_LINE: + if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { + u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); + if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16)) + val |= HOT_RESET_GEN; + else + val &= ~HOT_RESET_GEN; + advk_writel(pcie, val, PCIE_CORE_CTRL1_REG); + } + break; + + default: + break; + } +} static pci_bridge_emul_read_status_t advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, @@ -415,22 +828,47 @@ case PCI_EXP_RTCTL: { u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); - *value = (val & PCIE_MSG_PM_PME_MASK) ? PCI_EXP_RTCTL_PMEIE : 0; + *value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE; + *value |= le16_to_cpu(bridge->pcie_conf.rootctl) & PCI_EXP_RTCTL_CRSSVE; + *value |= PCI_EXP_RTCAP_CRSVIS << 16; return PCI_BRIDGE_EMUL_HANDLED; } case PCI_EXP_RTSTA: { u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG); u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG); - *value = (isr0 & PCIE_MSG_PM_PME_MASK) << 16 | (msglog >> 16); + *value = msglog >> 16; + if (isr0 & PCIE_MSG_PM_PME_MASK) + *value |= PCI_EXP_RTSTA_PME; + return PCI_BRIDGE_EMUL_HANDLED; + } + + case PCI_EXP_LNKCAP: { + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); + /* + * PCI_EXP_LNKCAP_DLLLARC bit is hardwired in aardvark HW to 0. + * But support for PCI_EXP_LNKSTA_DLLLA is emulated via ltssm + * state so explicitly enable PCI_EXP_LNKCAP_DLLLARC flag. + */ + val |= PCI_EXP_LNKCAP_DLLLARC; + *value = val; + return PCI_BRIDGE_EMUL_HANDLED; + } + + case PCI_EXP_LNKCTL: { + /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */ + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) & + ~(PCI_EXP_LNKSTA_LT << 16); + if (advk_pcie_link_training(pcie)) + val |= (PCI_EXP_LNKSTA_LT << 16); + if (advk_pcie_link_active(pcie)) + val |= (PCI_EXP_LNKSTA_DLLLA << 16); + *value = val; return PCI_BRIDGE_EMUL_HANDLED; } - case PCI_CAP_LIST_ID: case PCI_EXP_DEVCAP: case PCI_EXP_DEVCTL: - case PCI_EXP_LNKCAP: - case PCI_EXP_LNKCTL: *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); return PCI_BRIDGE_EMUL_HANDLED; default: @@ -447,14 +885,24 @@ switch (reg) { case PCI_EXP_DEVCTL: + advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg); + break; + case PCI_EXP_LNKCTL: advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg); + if (new & PCI_EXP_LNKCTL_RL) + advk_pcie_wait_for_retrain(pcie); break; - case PCI_EXP_RTCTL: - new = (new & PCI_EXP_RTCTL_PMEIE) << 3; - advk_writel(pcie, new, PCIE_ISR0_MASK_REG); + case PCI_EXP_RTCTL: { + /* Only mask/unmask PME interrupt */ + u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) & + ~PCIE_MSG_PM_PME_MASK; + if ((new & PCI_EXP_RTCTL_PMEIE) == 0) + val |= PCIE_MSG_PM_PME_MASK; + advk_writel(pcie, val, PCIE_ISR0_MASK_REG); break; + } case PCI_EXP_RTSTA: new = (new & PCI_EXP_RTSTA_PME) >> 9; @@ -467,6 +915,8 @@ } static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { + .read_base = advk_pci_bridge_emul_base_conf_read, + .write_base = advk_pci_bridge_emul_base_conf_write, .read_pcie = advk_pci_bridge_emul_pcie_conf_read, .write_pcie = advk_pci_bridge_emul_pcie_conf_write, }; @@ -475,32 +925,39 @@ * Initialize the configuration space of the PCI-to-PCI bridge * associated with the given PCIe interface. */ -static void advk_sw_pci_bridge_init(struct advk_pcie *pcie) +static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) { struct pci_bridge_emul *bridge = &pcie->bridge; - bridge->conf.vendor = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff; - bridge->conf.device = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16; + bridge->conf.vendor = + cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); + bridge->conf.device = + cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16); bridge->conf.class_revision = - advk_readl(pcie, PCIE_CORE_DEV_REV_REG) & 0xff; + cpu_to_le32(advk_readl(pcie, PCIE_CORE_DEV_REV_REG) & 0xff); /* Support 32 bits I/O addressing */ bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; /* Support 64 bits memory pref */ - bridge->conf.pref_mem_base = PCI_PREF_RANGE_TYPE_64; - bridge->conf.pref_mem_limit = PCI_PREF_RANGE_TYPE_64; + bridge->conf.pref_mem_base = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); + bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); /* Support interrupt A for MSI feature */ bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; + /* Aardvark HW provides PCIe Capability structure in version 2 */ + bridge->pcie_conf.cap = cpu_to_le16(2); + + /* Indicates supports for Completion Retry Status */ + bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); + bridge->has_pcie = true; bridge->data = pcie; bridge->ops = &advk_pci_bridge_emul_ops; - pci_bridge_emul_init(bridge, 0); - + return pci_bridge_emul_init(bridge, 0); } static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, @@ -509,13 +966,51 @@ if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) return false; + /* + * If the link goes down after we check for link-up, nothing bad + * happens but the config access times out. + */ + if (bus->number != pcie->root_bus_nr && !advk_pcie_link_up(pcie)) + return false; + return true; } +static bool advk_pcie_pio_is_running(struct advk_pcie *pcie) +{ + struct device *dev = &pcie->pdev->dev; + + /* + * Trying to start a new PIO transfer when previous has not completed + * cause External Abort on CPU which results in kernel panic: + * + * SError Interrupt on CPU0, code 0xbf000002 -- SError + * Kernel panic - not syncing: Asynchronous SError Interrupt + * + * Functions advk_pcie_rd_conf() and advk_pcie_wr_conf() are protected + * by raw_spin_lock_irqsave() at pci_lock_config() level to prevent + * concurrent calls at the same time. But because PIO transfer may take + * about 1.5s when link is down or card is disconnected, it means that + * advk_pcie_wait_pio() does not always have to wait for completion. + * + * Some versions of ARM Trusted Firmware handles this External Abort at + * EL3 level and mask it to prevent kernel panic. Relevant TF-A commit: + * https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50 + */ + if (advk_readl(pcie, PIO_START)) { + dev_err(dev, "Previous PIO read/write transfer is still running\n"); + return true; + } + + return false; +} + static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { struct advk_pcie *pcie = bus->sysdata; + int retry_count; + bool allow_crs; u32 reg; int ret; @@ -528,9 +1023,17 @@ return pci_bridge_emul_conf_read(&pcie->bridge, where, size, val); - /* Start PIO */ - advk_writel(pcie, 0, PIO_START); - advk_writel(pcie, 1, PIO_ISR); + /* + * Completion Retry Status is possible to return only when reading all + * 4 bytes from PCI_VENDOR_ID and PCI_DEVICE_ID registers at once and + * CRSSVE flag on Root Bridge is enabled. + */ + allow_crs = (where == PCI_VENDOR_ID) && (size == 4) && + (le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & + PCI_EXP_RTCTL_CRSSVE); + + if (advk_pcie_pio_is_running(pcie)) + goto try_crs; /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); @@ -549,23 +1052,45 @@ /* Program the data strobe */ advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); - /* Start the transfer */ - advk_writel(pcie, 1, PIO_START); + retry_count = 0; + do { + /* Clear PIO DONE ISR and start the transfer */ + advk_writel(pcie, 1, PIO_ISR); + advk_writel(pcie, 1, PIO_START); + + ret = advk_pcie_wait_pio(pcie); + if (ret < 0) + goto try_crs; + + retry_count += ret; + + /* Check PIO status and get the read result */ + ret = advk_pcie_check_pio_status(pcie, allow_crs, val); + } while (ret == -EAGAIN && retry_count < PIO_RETRY_CNT); - ret = advk_pcie_wait_pio(pcie); if (ret < 0) - return PCIBIOS_SET_FAILED; + goto fail; - advk_pcie_check_pio_status(pcie); - - /* Get the read result */ - *val = advk_readl(pcie, PIO_RD_DATA); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) *val = (*val >> (8 * (where & 3))) & 0xffff; return PCIBIOS_SUCCESSFUL; + +try_crs: + /* + * If it is possible, return Completion Retry Status so that caller + * tries to issue the request again instead of failing. + */ + if (allow_crs) { + *val = CFG_RD_CRS_VAL; + return PCIBIOS_SUCCESSFUL; + } + +fail: + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; } static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, @@ -574,6 +1099,7 @@ struct advk_pcie *pcie = bus->sysdata; u32 reg; u32 data_strobe = 0x0; + int retry_count; int offset; int ret; @@ -587,9 +1113,8 @@ if (where % size) return PCIBIOS_SET_FAILED; - /* Start PIO */ - advk_writel(pcie, 0, PIO_START); - advk_writel(pcie, 1, PIO_ISR); + if (advk_pcie_pio_is_running(pcie)) + return PCIBIOS_SET_FAILED; /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); @@ -616,16 +1141,22 @@ /* Program the data strobe */ advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); - /* Start the transfer */ - advk_writel(pcie, 1, PIO_START); + retry_count = 0; + do { + /* Clear PIO DONE ISR and start the transfer */ + advk_writel(pcie, 1, PIO_ISR); + advk_writel(pcie, 1, PIO_START); + + ret = advk_pcie_wait_pio(pcie); + if (ret < 0) + return PCIBIOS_SET_FAILED; - ret = advk_pcie_wait_pio(pcie); - if (ret < 0) - return PCIBIOS_SET_FAILED; + retry_count += ret; - advk_pcie_check_pio_status(pcie); + ret = advk_pcie_check_pio_status(pcie, false, NULL); + } while (ret == -EAGAIN && retry_count < PIO_RETRY_CNT); - return PCIBIOS_SUCCESSFUL; + return ret < 0 ? PCIBIOS_SET_FAILED : PCIBIOS_SUCCESSFUL; } static struct pci_ops advk_pcie_ops = { @@ -641,7 +1172,7 @@ msg->address_lo = lower_32_bits(msi_msg); msg->address_hi = upper_32_bits(msi_msg); - msg->data = data->irq; + msg->data = data->hwirq; } static int advk_msi_set_affinity(struct irq_data *irq_data, @@ -658,15 +1189,11 @@ int hwirq, i; mutex_lock(&pcie->msi_used_lock); - hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM, - 0, nr_irqs, 0); - if (hwirq >= MSI_IRQ_NUM) { - mutex_unlock(&pcie->msi_used_lock); - return -ENOSPC; - } - - bitmap_set(pcie->msi_used, hwirq, nr_irqs); + hwirq = bitmap_find_free_region(pcie->msi_used, MSI_IRQ_NUM, + order_base_2(nr_irqs)); mutex_unlock(&pcie->msi_used_lock); + if (hwirq < 0) + return -ENOSPC; for (i = 0; i < nr_irqs; i++) irq_domain_set_info(domain, virq + i, hwirq + i, @@ -674,7 +1201,7 @@ domain->host_data, handle_simple_irq, NULL, NULL); - return hwirq; + return 0; } static void advk_msi_irq_domain_free(struct irq_domain *domain, @@ -684,7 +1211,7 @@ struct advk_pcie *pcie = domain->host_data; mutex_lock(&pcie->msi_used_lock); - bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs); + bitmap_release_region(pcie->msi_used, d->hwirq, order_base_2(nr_irqs)); mutex_unlock(&pcie->msi_used_lock); } @@ -697,22 +1224,28 @@ { struct advk_pcie *pcie = d->domain->host_data; irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; u32 mask; + raw_spin_lock_irqsave(&pcie->irq_lock, flags); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); mask |= PCIE_ISR1_INTX_ASSERT(hwirq); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); + raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); } static void advk_pcie_irq_unmask(struct irq_data *d) { struct advk_pcie *pcie = d->domain->host_data; irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long flags; u32 mask; + raw_spin_lock_irqsave(&pcie->irq_lock, flags); mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); mask &= ~PCIE_ISR1_INTX_ASSERT(hwirq); advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); + raw_spin_unlock_irqrestore(&pcie->irq_lock, flags); } static int advk_pcie_irq_map(struct irq_domain *h, @@ -796,6 +1329,8 @@ struct irq_chip *irq_chip; int ret = 0; + raw_spin_lock_init(&pcie->irq_lock); + pcie_intc_node = of_get_next_child(node, NULL); if (!pcie_intc_node) { dev_err(dev, "No PCIe Intc node found\n"); @@ -837,19 +1372,19 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie) { u32 msi_val, msi_mask, msi_status, msi_idx; - u16 msi_data; + int virq; msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG); msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG); - msi_status = msi_val & ~msi_mask; + msi_status = msi_val & ((~msi_mask) & PCIE_MSI_ALL_MASK); for (msi_idx = 0; msi_idx < MSI_IRQ_NUM; msi_idx++) { if (!(BIT(msi_idx) & msi_status)) continue; advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); - msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; - generic_handle_irq(msi_data); + virq = irq_find_mapping(pcie->msi_inner_domain, msi_idx); + generic_handle_irq(virq); } advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, @@ -870,12 +1405,6 @@ isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK); - if (!isr0_status && !isr1_status) { - advk_writel(pcie, isr0_val, PCIE_ISR0_REG); - advk_writel(pcie, isr1_val, PCIE_ISR1_REG); - return; - } - /* Process MSI interrupts */ if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) advk_pcie_handle_msi(pcie); @@ -968,6 +1497,7 @@ struct advk_pcie *pcie; struct resource *res; struct pci_host_bridge *bridge; + struct resource_entry *entry; int ret, irq; bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie)); @@ -997,9 +1527,109 @@ return ret; } + resource_list_for_each_entry(entry, &pcie->resources) { + resource_size_t start = entry->res->start; + resource_size_t size = resource_size(entry->res); + unsigned long type = resource_type(entry->res); + u64 win_size; + + /* + * Aardvark hardware allows to configure also PCIe window + * for config type 0 and type 1 mapping, but driver uses + * only PIO for issuing configuration transfers which does + * not use PCIe window configuration. + */ + if (type != IORESOURCE_MEM && type != IORESOURCE_MEM_64 && + type != IORESOURCE_IO) + continue; + + /* + * Skip transparent memory resources. Default outbound access + * configuration is set to transparent memory access so it + * does not need window configuration. + */ + if ((type == IORESOURCE_MEM || type == IORESOURCE_MEM_64) && + entry->offset == 0) + continue; + + /* + * The n-th PCIe window is configured by tuple (match, remap, mask) + * and an access to address A uses this window if A matches the + * match with given mask. + * So every PCIe window size must be a power of two and every start + * address must be aligned to window size. Minimal size is 64 KiB + * because lower 16 bits of mask must be zero. Remapped address + * may have set only bits from the mask. + */ + while (pcie->wins_count < OB_WIN_COUNT && size > 0) { + /* Calculate the largest aligned window size */ + win_size = (1ULL << (fls64(size)-1)) | + (start ? (1ULL << __ffs64(start)) : 0); + win_size = 1ULL << __ffs64(win_size); + if (win_size < 0x10000) + break; + + dev_dbg(dev, + "Configuring PCIe window %d: [0x%llx-0x%llx] as %lu\n", + pcie->wins_count, (unsigned long long)start, + (unsigned long long)start + win_size, type); + + if (type == IORESOURCE_IO) { + pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_IO; + pcie->wins[pcie->wins_count].match = pci_pio_to_address(start); + } else { + pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_MEM; + pcie->wins[pcie->wins_count].match = start; + } + pcie->wins[pcie->wins_count].remap = start - entry->offset; + pcie->wins[pcie->wins_count].mask = ~(win_size - 1); + + if (pcie->wins[pcie->wins_count].remap & (win_size - 1)) + break; + + start += win_size; + size -= win_size; + pcie->wins_count++; + } + + if (size > 0) { + dev_err(&pcie->pdev->dev, + "Invalid PCIe region [0x%llx-0x%llx]\n", + (unsigned long long)entry->res->start, + (unsigned long long)entry->res->end + 1); + return -EINVAL; + } + } + + pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, + "reset-gpios", 0, + GPIOD_OUT_LOW, + "pcie1-reset"); + ret = PTR_ERR_OR_ZERO(pcie->reset_gpio); + if (ret) { + if (ret == -ENOENT) { + pcie->reset_gpio = NULL; + } else { + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get reset-gpio: %i\n", + ret); + return ret; + } + } + + ret = of_pci_get_max_link_speed(dev->of_node); + if (ret <= 0 || ret > 3) + pcie->link_gen = 3; + else + pcie->link_gen = ret; + advk_pcie_setup_hw(pcie); - advk_sw_pci_bridge_init(pcie); + ret = advk_sw_pci_bridge_init(pcie); + if (ret) { + dev_err(dev, "Failed to register emulated root PCI bridge\n"); + return ret; + } ret = advk_pcie_init_irq_domain(pcie); if (ret) { --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-ftpci100.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-ftpci100.c @@ -458,22 +458,12 @@ p->dev = dev; /* Retrieve and enable optional clocks */ - clk = devm_clk_get(dev, "PCLK"); + clk = devm_clk_get_enabled(dev, "PCLK"); if (IS_ERR(clk)) return PTR_ERR(clk); - ret = clk_prepare_enable(clk); - if (ret) { - dev_err(dev, "could not prepare PCLK\n"); - return ret; - } - p->bus_clk = devm_clk_get(dev, "PCICLK"); + p->bus_clk = devm_clk_get_enabled(dev, "PCICLK"); if (IS_ERR(p->bus_clk)) return PTR_ERR(p->bus_clk); - ret = clk_prepare_enable(p->bus_clk); - if (ret) { - dev_err(dev, "could not prepare PCICLK\n"); - return ret; - } regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); p->base = devm_ioremap_resource(dev, regs); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-hyperv.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-hyperv.c @@ -682,8 +682,8 @@ PCI_CAPABILITY_LIST) { /* ROM BARs are unimplemented */ *val = 0; - } else if (where >= PCI_INTERRUPT_LINE && where + size <= - PCI_INTERRUPT_PIN) { + } else if ((where >= PCI_INTERRUPT_LINE && where + size <= PCI_INTERRUPT_PIN) || + (where >= PCI_INTERRUPT_PIN && where + size <= PCI_MIN_GNT)) { /* * Interrupt Line and Interrupt PIN are hard-wired to zero * because this front-end only supports message-signaled @@ -1110,6 +1110,10 @@ u8 buffer[sizeof(struct pci_delete_interrupt)]; } ctxt; + if (!int_desc->vector_count) { + kfree(int_desc); + return; + } memset(&ctxt, 0, sizeof(ctxt)); int_pkt = (struct pci_delete_interrupt *)&ctxt.pkt.message; int_pkt->message_type.type = @@ -1172,6 +1176,28 @@ pci_msi_mask_irq(data); } +static unsigned int hv_msi_get_int_vector(struct irq_data *data) +{ + struct irq_cfg *cfg = irqd_cfg(data); + + return cfg->vector; +} + +static int hv_msi_prepare(struct irq_domain *domain, struct device *dev, + int nvec, msi_alloc_info_t *info) +{ + int ret = pci_msi_prepare(domain, dev, nvec, info); + + /* + * By using the interrupt remapper in the hypervisor IOMMU, contiguous + * CPU vectors is not needed for multi-MSI + */ + if (info->type == X86_IRQ_ALLOC_TYPE_MSI) + info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS; + + return ret; +} + /** * hv_irq_unmask() - "Unmask" the IRQ by setting its current * affinity. @@ -1187,6 +1213,7 @@ struct msi_desc *msi_desc = irq_data_get_msi_desc(data); struct irq_cfg *cfg = irqd_cfg(data); struct retarget_msi_interrupt *params; + struct tran_int_desc *int_desc; struct hv_pcibus_device *hbus; struct cpumask *dest; cpumask_var_t tmp; @@ -1201,6 +1228,7 @@ pdev = msi_desc_to_pci_dev(msi_desc); pbus = pdev->bus; hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); + int_desc = data->chip_data; spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags); @@ -1208,8 +1236,8 @@ memset(params, 0, sizeof(*params)); params->partition_id = HV_PARTITION_ID_SELF; params->int_entry.source = 1; /* MSI(-X) */ - params->int_entry.address = msi_desc->msg.address_lo; - params->int_entry.data = msi_desc->msg.data; + params->int_entry.address = int_desc->address & 0xffffffff; + params->int_entry.data = int_desc->data; params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | (hbus->hdev->dev_instance.b[4] << 16) | (hbus->hdev->dev_instance.b[7] << 8) | @@ -1296,12 +1324,12 @@ static u32 hv_compose_msi_req_v1( struct pci_create_interrupt *int_pkt, struct cpumask *affinity, - u32 slot, u8 vector) + u32 slot, u8 vector, u8 vector_count) { int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE; int_pkt->wslot.slot = slot; int_pkt->int_desc.vector = vector; - int_pkt->int_desc.vector_count = 1; + int_pkt->int_desc.vector_count = vector_count; int_pkt->int_desc.delivery_mode = dest_Fixed; /* @@ -1315,14 +1343,14 @@ static u32 hv_compose_msi_req_v2( struct pci_create_interrupt2 *int_pkt, struct cpumask *affinity, - u32 slot, u8 vector) + u32 slot, u8 vector, u8 vector_count) { int cpu; int_pkt->message_type.type = PCI_CREATE_INTERRUPT_MESSAGE2; int_pkt->wslot.slot = slot; int_pkt->int_desc.vector = vector; - int_pkt->int_desc.vector_count = 1; + int_pkt->int_desc.vector_count = vector_count; int_pkt->int_desc.delivery_mode = dest_Fixed; /* @@ -1350,7 +1378,6 @@ */ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { - struct irq_cfg *cfg = irqd_cfg(data); struct hv_pcibus_device *hbus; struct hv_pci_dev *hpdev; struct pci_bus *pbus; @@ -1359,6 +1386,8 @@ unsigned long flags; struct compose_comp_ctxt comp; struct tran_int_desc *int_desc; + struct msi_desc *msi_desc; + u8 vector, vector_count; struct { struct pci_packet pci_pkt; union { @@ -1370,7 +1399,17 @@ u32 size; int ret; - pdev = msi_desc_to_pci_dev(irq_data_get_msi_desc(data)); + /* Reuse the previous allocation */ + if (data->chip_data) { + int_desc = data->chip_data; + msg->address_hi = int_desc->address >> 32; + msg->address_lo = int_desc->address & 0xffffffff; + msg->data = int_desc->data; + return; + } + + msi_desc = irq_data_get_msi_desc(data); + pdev = msi_desc_to_pci_dev(msi_desc); dest = irq_data_get_effective_affinity_mask(data); pbus = pdev->bus; hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); @@ -1378,17 +1417,40 @@ if (!hpdev) goto return_null_message; - /* Free any previous message that might have already been composed. */ - if (data->chip_data) { - int_desc = data->chip_data; - data->chip_data = NULL; - hv_int_desc_free(hpdev, int_desc); - } - int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC); if (!int_desc) goto drop_reference; + if (!msi_desc->msi_attrib.is_msix && msi_desc->nvec_used > 1) { + /* + * If this is not the first MSI of Multi MSI, we already have + * a mapping. Can exit early. + */ + if (msi_desc->irq != data->irq) { + data->chip_data = int_desc; + int_desc->address = msi_desc->msg.address_lo | + (u64)msi_desc->msg.address_hi << 32; + int_desc->data = msi_desc->msg.data + + (data->irq - msi_desc->irq); + msg->address_hi = msi_desc->msg.address_hi; + msg->address_lo = msi_desc->msg.address_lo; + msg->data = int_desc->data; + put_pcichild(hpdev); + return; + } + /* + * The vector we select here is a dummy value. The correct + * value gets sent to the hypervisor in unmask(). This needs + * to be aligned with the count, and also not zero. Multi-msi + * is powers of 2 up to 32, so 32 will always work here. + */ + vector = 32; + vector_count = msi_desc->nvec_used; + } else { + vector = hv_msi_get_int_vector(data); + vector_count = 1; + } + memset(&ctxt, 0, sizeof(ctxt)); init_completion(&comp.comp_pkt.host_event); ctxt.pci_pkt.completion_func = hv_pci_compose_compl; @@ -1399,14 +1461,16 @@ size = hv_compose_msi_req_v1(&ctxt.int_pkts.v1, dest, hpdev->desc.win_slot.slot, - cfg->vector); + vector, + vector_count); break; case PCI_PROTOCOL_VERSION_1_2: size = hv_compose_msi_req_v2(&ctxt.int_pkts.v2, dest, hpdev->desc.win_slot.slot, - cfg->vector); + vector, + vector_count); break; default: @@ -1518,7 +1582,7 @@ static struct msi_domain_ops hv_msi_ops = { .get_hwirq = hv_msi_domain_ops_get_hwirq, - .msi_prepare = pci_msi_prepare, + .msi_prepare = hv_msi_prepare, .set_desc = pci_msi_set_desc, .msi_free = hv_msi_free, }; @@ -2675,6 +2739,24 @@ if (!ret) ret = wait_for_response(hdev, &comp); + /* + * In the case of fast device addition/removal, it's possible that + * vmbus_sendpacket() or wait_for_response() returns -ENODEV but we + * already got a PCI_BUS_RELATIONS* message from the host and the + * channel callback already scheduled a work to hbus->wq, which can be + * running pci_devices_present_work() -> survey_child_resources() -> + * complete(&hbus->survey_event), even after hv_pci_query_relations() + * exits and the stack variable 'comp' is no longer valid; as a result, + * a hang or a page fault may happen when the complete() calls + * raw_spin_lock_irqsave(). Flush hbus->wq before we exit from + * hv_pci_query_relations() to avoid the issues. Note: if 'ret' is + * -ENODEV, there can't be any more work item scheduled to hbus->wq + * after the flush_workqueue(): see vmbus_onoffer_rescind() -> + * vmbus_reset_channel_cb(), vmbus_rescind_cleanup() -> + * channel->rescind = true. + */ + flush_workqueue(hbus->wq); + return ret; } @@ -3121,6 +3203,9 @@ static int __init init_hv_pci_drv(void) { + if (!hv_is_hyperv_initialized()) + return -ENODEV; + /* Set the invalid domain number's bit, so it will not be used */ set_bit(HVPCI_DOM_INVALID, hvpci_dom_map); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-mvebu.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-mvebu.c @@ -105,6 +105,7 @@ struct mvebu_pcie_window memwin; struct mvebu_pcie_window iowin; u32 saved_pcie_stat; + struct resource regs; }; static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) @@ -149,7 +150,9 @@ /* * Setup PCIE BARs and Address Decode Wins: - * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks + * BAR[0] -> internal registers (needed for MSI) + * BAR[1] -> covers all DRAM banks + * BAR[2] -> Disabled * WIN[0-3] -> DRAM bank[0-3] */ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) @@ -203,6 +206,12 @@ mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1)); mvebu_writel(port, ((size - 1) & 0xffff0000) | 1, PCIE_BAR_CTRL_OFF(1)); + + /* + * Point BAR[0] to the device's internal registers. + */ + mvebu_writel(port, round_down(port->regs.start, SZ_1M), PCIE_BAR_LO_OFF(0)); + mvebu_writel(port, 0, PCIE_BAR_HI_OFF(0)); } static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) @@ -567,6 +576,8 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) { struct pci_bridge_emul *bridge = &port->bridge; + u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP); + u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS); bridge->conf.vendor = PCI_VENDOR_ID_MARVELL; bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; @@ -579,6 +590,12 @@ bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; } + /* + * Older mvebu hardware provides PCIe Capability structure only in + * version 1. New hardware provides it in version 2. + */ + bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver); + bridge->has_pcie = true; bridge->data = port; bridge->ops = &mvebu_pci_bridge_emul_ops; @@ -708,14 +725,13 @@ struct device_node *np, struct mvebu_pcie_port *port) { - struct resource regs; int ret = 0; - ret = of_address_to_resource(np, 0, ®s); + ret = of_address_to_resource(np, 0, &port->regs); if (ret) return ERR_PTR(ret); - return devm_ioremap_resource(&pdev->dev, ®s); + return devm_ioremap_resource(&pdev->dev, &port->regs); } #define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03) --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-tegra.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-tegra.c @@ -181,13 +181,6 @@ #define AFI_PEXBIAS_CTRL_0 0x168 -#define RP_PRIV_XP_DL 0x00000494 -#define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1) - -#define RP_RX_HDR_LIMIT 0x00000e00 -#define RP_RX_HDR_LIMIT_PW_MASK (0xff << 8) -#define RP_RX_HDR_LIMIT_PW (0x0e << 8) - #define RP_ECTL_2_R1 0x00000e84 #define RP_ECTL_2_R1_RX_CTLE_1C_MASK 0xffff @@ -323,7 +316,6 @@ bool program_uphy; bool update_clamp_threshold; bool program_deskew_time; - bool raw_violation_fixup; bool update_fc_timer; bool has_cache_bars; struct { @@ -669,23 +661,6 @@ writel(value, port->base + RP_VEND_CTL0); } - /* Fixup for read after write violation. */ - if (soc->raw_violation_fixup) { - value = readl(port->base + RP_RX_HDR_LIMIT); - value &= ~RP_RX_HDR_LIMIT_PW_MASK; - value |= RP_RX_HDR_LIMIT_PW; - writel(value, port->base + RP_RX_HDR_LIMIT); - - value = readl(port->base + RP_PRIV_XP_DL); - value |= RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD; - writel(value, port->base + RP_PRIV_XP_DL); - - value = readl(port->base + RP_VEND_XP); - value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK; - value |= soc->update_fc_threshold; - writel(value, port->base + RP_VEND_XP); - } - if (soc->update_fc_timer) { value = readl(port->base + RP_VEND_XP); value &= ~RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK; @@ -2292,13 +2267,15 @@ rp->np = port; rp->base = devm_pci_remap_cfg_resource(dev, &rp->regs); - if (IS_ERR(rp->base)) - return PTR_ERR(rp->base); + if (IS_ERR(rp->base)) { + err = PTR_ERR(rp->base); + goto err_node_put; + } label = devm_kasprintf(dev, GFP_KERNEL, "pex-reset-%u", index); if (!label) { - dev_err(dev, "failed to create reset GPIO label\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_node_put; } /* @@ -2314,9 +2291,10 @@ if (PTR_ERR(rp->reset_gpio) == -ENOENT) { rp->reset_gpio = NULL; } else { - dev_err(dev, "failed to get reset GPIO: %d\n", - err); - return PTR_ERR(rp->reset_gpio); + dev_err(dev, "failed to get reset GPIO: %ld\n", + PTR_ERR(rp->reset_gpio)); + err = PTR_ERR(rp->reset_gpio); + goto err_node_put; } } @@ -2499,7 +2477,6 @@ .num_ports = 2, .ports = tegra20_pcie_ports, .msi_base_shift = 0, - .afi_pex2_ctrl = 0x128, .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, .pads_refclk_cfg0 = 0xfa5cfa5c, @@ -2512,7 +2489,6 @@ .program_uphy = true, .update_clamp_threshold = false, .program_deskew_time = false, - .raw_violation_fixup = false, .update_fc_timer = false, .has_cache_bars = true, .ectl.enable = false, @@ -2528,6 +2504,7 @@ .num_ports = 3, .ports = tegra30_pcie_ports, .msi_base_shift = 8, + .afi_pex2_ctrl = 0x128, .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .pads_refclk_cfg0 = 0xfa5cfa5c, @@ -2541,7 +2518,6 @@ .program_uphy = true, .update_clamp_threshold = false, .program_deskew_time = false, - .raw_violation_fixup = false, .update_fc_timer = false, .has_cache_bars = false, .ectl.enable = false, @@ -2554,8 +2530,6 @@ .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .pads_refclk_cfg0 = 0x44ac44ac, - /* FC threshold is bit[25:18] */ - .update_fc_threshold = 0x03fc0000, .has_pex_clkreq_en = true, .has_pex_bias_ctrl = true, .has_intr_prsnt_sense = true, @@ -2565,7 +2539,6 @@ .program_uphy = true, .update_clamp_threshold = true, .program_deskew_time = false, - .raw_violation_fixup = true, .update_fc_timer = false, .has_cache_bars = false, .ectl.enable = false, @@ -2589,7 +2562,6 @@ .program_uphy = true, .update_clamp_threshold = true, .program_deskew_time = true, - .raw_violation_fixup = false, .update_fc_timer = true, .has_cache_bars = false, .ectl = { @@ -2631,7 +2603,6 @@ .program_uphy = false, .update_clamp_threshold = false, .program_deskew_time = false, - .raw_violation_fixup = false, .update_fc_timer = false, .has_cache_bars = false, .ectl.enable = false, @@ -2645,6 +2616,7 @@ { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie }, { }, }; +MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) { @@ -2798,9 +2770,9 @@ pm_runtime_enable(pcie->dev); err = pm_runtime_get_sync(pcie->dev); - if (err) { + if (err < 0) { dev_err(dev, "fail to enable pcie controller: %d\n", err); - goto teardown_msi; + goto pm_runtime_put; } err = tegra_pcie_request_resources(pcie); @@ -2840,7 +2812,6 @@ pm_runtime_put: pm_runtime_put_sync(pcie->dev); pm_runtime_disable(pcie->dev); -teardown_msi: tegra_pcie_msi_teardown(pcie); put_resources: tegra_pcie_put_resources(pcie); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-thunder-ecam.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-thunder-ecam.c @@ -116,7 +116,7 @@ * the config space access window. Since we are working with * the high-order 32 bits, shift everything down by 32 bits. */ - node_bits = (cfg->res.start >> 32) & (1 << 12); + node_bits = upper_32_bits(cfg->res.start) & (1 << 12); v |= node_bits; set_val(v, where, size, val); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-thunder-pem.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-thunder-pem.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "../pci.h" #if defined(CONFIG_PCI_HOST_THUNDER_PEM) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)) @@ -314,9 +315,9 @@ * structure here for the BAR. */ bar4_start = res_pem->start + 0xf00000; - pem_pci->ea_entry[0] = (u32)bar4_start | 2; - pem_pci->ea_entry[1] = (u32)(res_pem->end - bar4_start) & ~3u; - pem_pci->ea_entry[2] = (u32)(bar4_start >> 32); + pem_pci->ea_entry[0] = lower_32_bits(bar4_start) | 2; + pem_pci->ea_entry[1] = lower_32_bits(res_pem->end - bar4_start) & ~3u; + pem_pci->ea_entry[2] = upper_32_bits(bar4_start); cfg->priv = pem_pci; return 0; @@ -324,9 +325,9 @@ #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) -#define PEM_RES_BASE 0x87e0c0000000UL -#define PEM_NODE_MASK GENMASK(45, 44) -#define PEM_INDX_MASK GENMASK(26, 24) +#define PEM_RES_BASE 0x87e0c0000000ULL +#define PEM_NODE_MASK GENMASK_ULL(45, 44) +#define PEM_INDX_MASK GENMASK_ULL(26, 24) #define PEM_MIN_DOM_IN_NODE 4 #define PEM_MAX_DOM_IN_NODE 10 --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-v3-semi.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-v3-semi.c @@ -743,7 +743,7 @@ int ret; LIST_HEAD(res); - host = pci_alloc_host_bridge(sizeof(*v3)); + host = devm_pci_alloc_host_bridge(dev, sizeof(*v3)); if (!host) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/pci/controller/pci-xgene-msi.c +++ linux-oracle-5.4.0/drivers/pci/controller/pci-xgene-msi.c @@ -384,13 +384,9 @@ if (!msi_group->gic_irq) continue; - irq_set_chained_handler(msi_group->gic_irq, - xgene_msi_isr); - err = irq_set_handler_data(msi_group->gic_irq, msi_group); - if (err) { - pr_err("failed to register GIC IRQ handler\n"); - return -EINVAL; - } + irq_set_chained_handler_and_data(msi_group->gic_irq, + xgene_msi_isr, msi_group); + /* * Statically allocate MSI GIC IRQs to each CPU core. * With 8-core X-Gene v1, 2 MSI GIC IRQs are allocated --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-cadence-ep.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-cadence-ep.c @@ -178,8 +178,7 @@ struct cdns_pcie *pcie = &ep->pcie; u32 r; - r = find_first_zero_bit(&ep->ob_region_map, - sizeof(ep->ob_region_map) * BITS_PER_LONG); + r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG); if (r >= ep->max_regions - 1) { dev_err(&epc->dev, "no free outbound region\n"); return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-cadence-host.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-cadence-host.c @@ -102,6 +102,7 @@ { struct cdns_pcie *pcie = &rc->pcie; u32 value, ctrl; + u32 id; /* * Set the root complex BAR configuration register: @@ -121,8 +122,12 @@ cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value); /* Set root port configuration space */ - if (rc->vendor_id != 0xffff) - cdns_pcie_rp_writew(pcie, PCI_VENDOR_ID, rc->vendor_id); + if (rc->vendor_id != 0xffff) { + id = CDNS_PCIE_LM_ID_VENDOR(rc->vendor_id) | + CDNS_PCIE_LM_ID_SUBSYS(rc->vendor_id); + cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id); + } + if (rc->device_id != 0xffff) cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-iproc-msi.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-iproc-msi.c @@ -171,7 +171,7 @@ static struct msi_domain_info iproc_msi_domain_info = { .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | - MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX, + MSI_FLAG_PCI_MSIX, .chip = &iproc_msi_irq_chip, }; @@ -209,15 +209,20 @@ struct iproc_msi *msi = irq_data_get_irq_chip_data(data); int target_cpu = cpumask_first(mask); int curr_cpu; + int ret; curr_cpu = hwirq_to_cpu(msi, data->hwirq); if (curr_cpu == target_cpu) - return IRQ_SET_MASK_OK_DONE; + ret = IRQ_SET_MASK_OK_DONE; + else { + /* steer MSI to the target CPU */ + data->hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq) + target_cpu; + ret = IRQ_SET_MASK_OK; + } - /* steer MSI to the target CPU */ - data->hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq) + target_cpu; + irq_data_update_effective_affinity(data, cpumask_of(target_cpu)); - return IRQ_SET_MASK_OK; + return ret; } static void iproc_msi_irq_compose_msi_msg(struct irq_data *data, @@ -245,20 +250,23 @@ struct iproc_msi *msi = domain->host_data; int hwirq, i; + if (msi->nr_cpus > 1 && nr_irqs > 1) + return -EINVAL; + mutex_lock(&msi->bitmap_lock); - /* Allocate 'nr_cpus' number of MSI vectors each time */ - hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0, - msi->nr_cpus, 0); - if (hwirq < msi->nr_msi_vecs) { - bitmap_set(msi->bitmap, hwirq, msi->nr_cpus); - } else { - mutex_unlock(&msi->bitmap_lock); - return -ENOSPC; - } + /* + * Allocate 'nr_irqs' multiplied by 'nr_cpus' number of MSI vectors + * each time + */ + hwirq = bitmap_find_free_region(msi->bitmap, msi->nr_msi_vecs, + order_base_2(msi->nr_cpus * nr_irqs)); mutex_unlock(&msi->bitmap_lock); + if (hwirq < 0) + return -ENOSPC; + for (i = 0; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, hwirq + i, &iproc_msi_bottom_irq_chip, @@ -266,7 +274,7 @@ NULL, NULL); } - return hwirq; + return 0; } static void iproc_msi_irq_domain_free(struct irq_domain *domain, @@ -279,7 +287,8 @@ mutex_lock(&msi->bitmap_lock); hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq); - bitmap_clear(msi->bitmap, hwirq, msi->nr_cpus); + bitmap_release_region(msi->bitmap, hwirq, + order_base_2(msi->nr_cpus * nr_irqs)); mutex_unlock(&msi->bitmap_lock); @@ -533,6 +542,9 @@ mutex_init(&msi->bitmap_lock); msi->nr_cpus = num_possible_cpus(); + if (msi->nr_cpus == 1) + iproc_msi_domain_info.flags |= MSI_FLAG_MULTI_PCI_MSI; + msi->nr_irqs = of_irq_count(node); if (!msi->nr_irqs) { dev_err(pcie->dev, "found no MSI GIC interrupt\n"); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-iproc.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-iproc.c @@ -307,7 +307,7 @@ }; /* iProc PCIe PAXB BCMA registers */ -static const u16 iproc_pcie_reg_paxb_bcma[] = { +static const u16 iproc_pcie_reg_paxb_bcma[IPROC_PCIE_MAX_NUM_REG] = { [IPROC_PCIE_CLK_CTRL] = 0x000, [IPROC_PCIE_CFG_IND_ADDR] = 0x120, [IPROC_PCIE_CFG_IND_DATA] = 0x124, @@ -318,7 +318,7 @@ }; /* iProc PCIe PAXB registers */ -static const u16 iproc_pcie_reg_paxb[] = { +static const u16 iproc_pcie_reg_paxb[IPROC_PCIE_MAX_NUM_REG] = { [IPROC_PCIE_CLK_CTRL] = 0x000, [IPROC_PCIE_CFG_IND_ADDR] = 0x120, [IPROC_PCIE_CFG_IND_DATA] = 0x124, @@ -334,7 +334,7 @@ }; /* iProc PCIe PAXB v2 registers */ -static const u16 iproc_pcie_reg_paxb_v2[] = { +static const u16 iproc_pcie_reg_paxb_v2[IPROC_PCIE_MAX_NUM_REG] = { [IPROC_PCIE_CLK_CTRL] = 0x000, [IPROC_PCIE_CFG_IND_ADDR] = 0x120, [IPROC_PCIE_CFG_IND_DATA] = 0x124, @@ -363,7 +363,7 @@ }; /* iProc PCIe PAXC v1 registers */ -static const u16 iproc_pcie_reg_paxc[] = { +static const u16 iproc_pcie_reg_paxc[IPROC_PCIE_MAX_NUM_REG] = { [IPROC_PCIE_CLK_CTRL] = 0x000, [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, @@ -372,7 +372,7 @@ }; /* iProc PCIe PAXC v2 registers */ -static const u16 iproc_pcie_reg_paxc_v2[] = { +static const u16 iproc_pcie_reg_paxc_v2[IPROC_PCIE_MAX_NUM_REG] = { [IPROC_PCIE_MSI_GIC_MODE] = 0x050, [IPROC_PCIE_MSI_BASE_ADDR] = 0x074, [IPROC_PCIE_MSI_WINDOW_SIZE] = 0x078, @@ -1608,6 +1608,30 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_disable_msi_parsing); +static void quirk_paxc_bridge(struct pci_dev *pdev) +{ + /* + * The PCI config space is shared with the PAXC root port and the first + * Ethernet device. So, we need to workaround this by telling the PCI + * code that the bridge is not an Ethernet device. + */ + if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) + pdev->class = PCI_CLASS_BRIDGE_PCI << 8; + + /* + * MPSS is not being set properly (as it is currently 0). This is + * because that area of the PCI config space is hard coded to zero, and + * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS) + * so that the MPS can be set to the real max value. + */ + pdev->pcie_mpss = 2; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge); + MODULE_AUTHOR("Ray Jui "); MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-mediatek.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-mediatek.c @@ -623,14 +623,20 @@ if (status & MSI_STATUS){ unsigned long imsi_status; + /* + * The interrupt status can be cleared even if the + * MSI status remains pending. As such, given the + * edge-triggered interrupt type, its status should + * be cleared before being dispatched to the + * handler of the underlying device. + */ + writel(MSI_STATUS, port->base + PCIE_INT_STATUS); while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) { virq = irq_find_mapping(port->inner_domain, bit); generic_handle_irq(virq); } } - /* Clear MSI interrupt status */ - writel(MSI_STATUS, port->base + PCIE_INT_STATUS); } } @@ -1063,14 +1069,14 @@ err = of_pci_get_devfn(child); if (err < 0) { dev_err(dev, "failed to parse devfn: %d\n", err); - return err; + goto error_put_node; } slot = PCI_SLOT(err); err = mtk_pcie_parse_port(pcie, child, slot); if (err) - return err; + goto error_put_node; } err = mtk_pcie_subsys_powerup(pcie); @@ -1086,6 +1092,9 @@ mtk_pcie_subsys_powerdown(pcie); return 0; +error_put_node: + of_node_put(child); + return err; } static int mtk_pcie_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-mobiveil.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-mobiveil.c @@ -235,7 +235,7 @@ return PCIBIOS_SUCCESSFUL; } -static u32 csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size) +static u32 mobiveil_csr_read(struct mobiveil_pcie *pcie, u32 off, size_t size) { void *addr; u32 val; @@ -250,7 +250,8 @@ return val; } -static void csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, size_t size) +static void mobiveil_csr_write(struct mobiveil_pcie *pcie, u32 val, u32 off, + size_t size) { void *addr; int ret; @@ -262,19 +263,19 @@ dev_err(&pcie->pdev->dev, "write CSR address failed\n"); } -static u32 csr_readl(struct mobiveil_pcie *pcie, u32 off) +static u32 mobiveil_csr_readl(struct mobiveil_pcie *pcie, u32 off) { - return csr_read(pcie, off, 0x4); + return mobiveil_csr_read(pcie, off, 0x4); } -static void csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off) +static void mobiveil_csr_writel(struct mobiveil_pcie *pcie, u32 val, u32 off) { - csr_write(pcie, val, off, 0x4); + mobiveil_csr_write(pcie, val, off, 0x4); } static bool mobiveil_pcie_link_up(struct mobiveil_pcie *pcie) { - return (csr_readl(pcie, LTSSM_STATUS) & + return (mobiveil_csr_readl(pcie, LTSSM_STATUS) & LTSSM_STATUS_L0_MASK) == LTSSM_STATUS_L0; } @@ -323,7 +324,7 @@ PCI_SLOT(devfn) << PAB_DEVICE_SHIFT | PCI_FUNC(devfn) << PAB_FUNCTION_SHIFT; - csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0)); + mobiveil_csr_writel(pcie, value, PAB_AXI_AMAP_PEX_WIN_L(WIN_NUM_0)); return pcie->config_axi_slave_base + where; } @@ -353,13 +354,14 @@ chained_irq_enter(chip, desc); /* read INTx status */ - val = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT); - mask = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); + val = mobiveil_csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT); + mask = mobiveil_csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); intr_status = val & mask; /* Handle INTx */ if (intr_status & PAB_INTP_INTX_MASK) { - shifted_status = csr_readl(pcie, PAB_INTP_AMBA_MISC_STAT); + shifted_status = mobiveil_csr_readl(pcie, + PAB_INTP_AMBA_MISC_STAT); shifted_status &= PAB_INTP_INTX_MASK; shifted_status >>= PAB_INTX_START; do { @@ -373,12 +375,13 @@ bit); /* clear interrupt handled */ - csr_writel(pcie, 1 << (PAB_INTX_START + bit), - PAB_INTP_AMBA_MISC_STAT); + mobiveil_csr_writel(pcie, + 1 << (PAB_INTX_START + bit), + PAB_INTP_AMBA_MISC_STAT); } - shifted_status = csr_readl(pcie, - PAB_INTP_AMBA_MISC_STAT); + shifted_status = mobiveil_csr_readl(pcie, + PAB_INTP_AMBA_MISC_STAT); shifted_status &= PAB_INTP_INTX_MASK; shifted_status >>= PAB_INTX_START; } while (shifted_status != 0); @@ -413,7 +416,7 @@ } /* Clear the interrupt status */ - csr_writel(pcie, intr_status, PAB_INTP_AMBA_MISC_STAT); + mobiveil_csr_writel(pcie, intr_status, PAB_INTP_AMBA_MISC_STAT); chained_irq_exit(chip, desc); } @@ -474,24 +477,24 @@ return; } - value = csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num)); + value = mobiveil_csr_readl(pcie, PAB_PEX_AMAP_CTRL(win_num)); value &= ~(AMAP_CTRL_TYPE_MASK << AMAP_CTRL_TYPE_SHIFT | WIN_SIZE_MASK); value |= type << AMAP_CTRL_TYPE_SHIFT | 1 << AMAP_CTRL_EN_SHIFT | (lower_32_bits(size64) & WIN_SIZE_MASK); - csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num)); + mobiveil_csr_writel(pcie, value, PAB_PEX_AMAP_CTRL(win_num)); - csr_writel(pcie, upper_32_bits(size64), - PAB_EXT_PEX_AMAP_SIZEN(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(size64), + PAB_EXT_PEX_AMAP_SIZEN(win_num)); - csr_writel(pcie, lower_32_bits(cpu_addr), - PAB_PEX_AMAP_AXI_WIN(win_num)); - csr_writel(pcie, upper_32_bits(cpu_addr), - PAB_EXT_PEX_AMAP_AXI_WIN(win_num)); - - csr_writel(pcie, lower_32_bits(pci_addr), - PAB_PEX_AMAP_PEX_WIN_L(win_num)); - csr_writel(pcie, upper_32_bits(pci_addr), - PAB_PEX_AMAP_PEX_WIN_H(win_num)); + mobiveil_csr_writel(pcie, lower_32_bits(cpu_addr), + PAB_PEX_AMAP_AXI_WIN(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(cpu_addr), + PAB_EXT_PEX_AMAP_AXI_WIN(win_num)); + + mobiveil_csr_writel(pcie, lower_32_bits(pci_addr), + PAB_PEX_AMAP_PEX_WIN_L(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(pci_addr), + PAB_PEX_AMAP_PEX_WIN_H(win_num)); pcie->ib_wins_configured++; } @@ -515,27 +518,29 @@ * program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit * to 4 KB in PAB_AXI_AMAP_CTRL register */ - value = csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num)); + value = mobiveil_csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num)); value &= ~(WIN_TYPE_MASK << WIN_TYPE_SHIFT | WIN_SIZE_MASK); value |= 1 << WIN_ENABLE_SHIFT | type << WIN_TYPE_SHIFT | (lower_32_bits(size64) & WIN_SIZE_MASK); - csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num)); + mobiveil_csr_writel(pcie, value, PAB_AXI_AMAP_CTRL(win_num)); - csr_writel(pcie, upper_32_bits(size64), PAB_EXT_AXI_AMAP_SIZE(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(size64), + PAB_EXT_AXI_AMAP_SIZE(win_num)); /* * program AXI window base with appropriate value in * PAB_AXI_AMAP_AXI_WIN0 register */ - csr_writel(pcie, lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK), - PAB_AXI_AMAP_AXI_WIN(win_num)); - csr_writel(pcie, upper_32_bits(cpu_addr), - PAB_EXT_AXI_AMAP_AXI_WIN(win_num)); - - csr_writel(pcie, lower_32_bits(pci_addr), - PAB_AXI_AMAP_PEX_WIN_L(win_num)); - csr_writel(pcie, upper_32_bits(pci_addr), - PAB_AXI_AMAP_PEX_WIN_H(win_num)); + mobiveil_csr_writel(pcie, + lower_32_bits(cpu_addr) & (~AXI_WINDOW_ALIGN_MASK), + PAB_AXI_AMAP_AXI_WIN(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(cpu_addr), + PAB_EXT_AXI_AMAP_AXI_WIN(win_num)); + + mobiveil_csr_writel(pcie, lower_32_bits(pci_addr), + PAB_AXI_AMAP_PEX_WIN_L(win_num)); + mobiveil_csr_writel(pcie, upper_32_bits(pci_addr), + PAB_AXI_AMAP_PEX_WIN_H(win_num)); pcie->ob_wins_configured++; } @@ -579,42 +584,42 @@ struct resource_entry *win; /* setup bus numbers */ - value = csr_readl(pcie, PCI_PRIMARY_BUS); + value = mobiveil_csr_readl(pcie, PCI_PRIMARY_BUS); value &= 0xff000000; value |= 0x00ff0100; - csr_writel(pcie, value, PCI_PRIMARY_BUS); + mobiveil_csr_writel(pcie, value, PCI_PRIMARY_BUS); /* * program Bus Master Enable Bit in Command Register in PAB Config * Space */ - value = csr_readl(pcie, PCI_COMMAND); + value = mobiveil_csr_readl(pcie, PCI_COMMAND); value |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - csr_writel(pcie, value, PCI_COMMAND); + mobiveil_csr_writel(pcie, value, PCI_COMMAND); /* * program PIO Enable Bit to 1 (and PEX PIO Enable to 1) in PAB_CTRL * register */ - pab_ctrl = csr_readl(pcie, PAB_CTRL); + pab_ctrl = mobiveil_csr_readl(pcie, PAB_CTRL); pab_ctrl |= (1 << AMBA_PIO_ENABLE_SHIFT) | (1 << PEX_PIO_ENABLE_SHIFT); - csr_writel(pcie, pab_ctrl, PAB_CTRL); + mobiveil_csr_writel(pcie, pab_ctrl, PAB_CTRL); - csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK), - PAB_INTP_AMBA_MISC_ENB); + mobiveil_csr_writel(pcie, (PAB_INTP_INTX_MASK | PAB_INTP_MSI_MASK), + PAB_INTP_AMBA_MISC_ENB); /* * program PIO Enable Bit to 1 and Config Window Enable Bit to 1 in * PAB_AXI_PIO_CTRL Register */ - value = csr_readl(pcie, PAB_AXI_PIO_CTRL); + value = mobiveil_csr_readl(pcie, PAB_AXI_PIO_CTRL); value |= APIO_EN_MASK; - csr_writel(pcie, value, PAB_AXI_PIO_CTRL); + mobiveil_csr_writel(pcie, value, PAB_AXI_PIO_CTRL); /* Enable PCIe PIO master */ - value = csr_readl(pcie, PAB_PEX_PIO_CTRL); + value = mobiveil_csr_readl(pcie, PAB_PEX_PIO_CTRL); value |= 1 << PIO_ENABLE_SHIFT; - csr_writel(pcie, value, PAB_PEX_PIO_CTRL); + mobiveil_csr_writel(pcie, value, PAB_PEX_PIO_CTRL); /* * we'll program one outbound window for config reads and @@ -647,10 +652,10 @@ } /* fixup for PCIe class register */ - value = csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS); + value = mobiveil_csr_readl(pcie, PAB_INTP_AXI_PIO_CLASS); value &= 0xff; value |= (PCI_CLASS_BRIDGE_PCI << 16); - csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS); + mobiveil_csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS); /* setup MSI hardware registers */ mobiveil_pcie_enable_msi(pcie); @@ -668,9 +673,9 @@ pcie = irq_desc_get_chip_data(desc); mask = 1 << ((data->hwirq + PAB_INTX_START) - 1); raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags); - shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); + shifted_val = mobiveil_csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); shifted_val &= ~mask; - csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB); + mobiveil_csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB); raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags); } @@ -684,9 +689,9 @@ pcie = irq_desc_get_chip_data(desc); mask = 1 << ((data->hwirq + PAB_INTX_START) - 1); raw_spin_lock_irqsave(&pcie->intx_mask_lock, flags); - shifted_val = csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); + shifted_val = mobiveil_csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB); shifted_val |= mask; - csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB); + mobiveil_csr_writel(pcie, shifted_val, PAB_INTP_AMBA_MISC_ENB); raw_spin_unlock_irqrestore(&pcie->intx_mask_lock, flags); } --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-rcar.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-rcar.c @@ -93,8 +93,11 @@ #define LINK_SPEED_2_5GTS (1 << 16) #define LINK_SPEED_5_0GTS (2 << 16) #define MACCTLR 0x011058 +#define MACCTLR_NFTS_MASK GENMASK(23, 16) /* The name is from SH7786 */ #define SPEED_CHANGE BIT(24) #define SCRAMBLE_DISABLE BIT(27) +#define LTSMDIS BIT(31) +#define MACCTLR_INIT_VAL (LTSMDIS | MACCTLR_NFTS_MASK) #define PMSR 0x01105c #define MACS2R 0x011078 #define MACCGSPSETR 0x011084 @@ -332,11 +335,12 @@ }; static void rcar_pcie_setup_window(int win, struct rcar_pcie *pcie, - struct resource *res) + struct resource_entry *window) { /* Setup PCIe address space mappings for each resource */ resource_size_t size; resource_size_t res_start; + struct resource *res = window->res; u32 mask; rcar_pci_write_reg(pcie, 0x00000000, PCIEPTCTLR(win)); @@ -350,9 +354,9 @@ rcar_pci_write_reg(pcie, mask << 7, PCIEPAMR(win)); if (res->flags & IORESOURCE_IO) - res_start = pci_pio_to_address(res->start); + res_start = pci_pio_to_address(res->start) - window->offset; else - res_start = res->start; + res_start = res->start - window->offset; rcar_pci_write_reg(pcie, upper_32_bits(res_start), PCIEPAUR(win)); rcar_pci_write_reg(pcie, lower_32_bits(res_start) & ~0x7F, @@ -381,7 +385,7 @@ switch (resource_type(res)) { case IORESOURCE_IO: case IORESOURCE_MEM: - rcar_pcie_setup_window(i, pci, res); + rcar_pcie_setup_window(i, pci, win); i++; break; case IORESOURCE_BUS: @@ -615,6 +619,8 @@ if (IS_ENABLED(CONFIG_PCI_MSI)) rcar_pci_write_reg(pcie, 0x801f0000, PCIEMSITXR); + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); + /* Finish initialization - establish a PCI Express link */ rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); @@ -1237,6 +1243,7 @@ return 0; /* Re-establish the PCIe link */ + rcar_pci_write_reg(pcie, MACCTLR_INIT_VAL, MACCTLR); rcar_pci_write_reg(pcie, CFINIT, PCIETCTLR); return rcar_pcie_wait_for_dl(pcie); } --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-rockchip-ep.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-rockchip-ep.c @@ -66,18 +66,26 @@ ROCKCHIP_PCIE_AT_OB_REGION_CPU_ADDR1(region)); } +static int rockchip_pcie_ep_ob_atu_num_bits(struct rockchip_pcie *rockchip, + u64 pci_addr, size_t size) +{ + int num_pass_bits = fls64(pci_addr ^ (pci_addr + size - 1)); + + return clamp(num_pass_bits, + ROCKCHIP_PCIE_AT_MIN_NUM_BITS, + ROCKCHIP_PCIE_AT_MAX_NUM_BITS); +} + static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, u32 r, u32 type, u64 cpu_addr, u64 pci_addr, size_t size) { - u64 sz = 1ULL << fls64(size - 1); - int num_pass_bits = ilog2(sz); + int num_pass_bits; u32 addr0, addr1, desc0, desc1; bool is_nor_msg = (type == AXI_WRAPPER_NOR_MSG); - /* The minimal region size is 1MB */ - if (num_pass_bits < 8) - num_pass_bits = 8; + num_pass_bits = rockchip_pcie_ep_ob_atu_num_bits(rockchip, + pci_addr, size); cpu_addr -= rockchip->mem_res->start; addr0 = ((is_nor_msg ? 0x10 : (num_pass_bits - 1)) & @@ -124,20 +132,20 @@ static int rockchip_pcie_ep_write_header(struct pci_epc *epc, u8 fn, struct pci_epf_header *hdr) { + u32 reg; struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip; /* All functions share the same vendor ID with function 0 */ if (fn == 0) { - u32 vid_regs = (hdr->vendorid & GENMASK(15, 0)) | - (hdr->subsys_vendor_id & GENMASK(31, 16)) << 16; - - rockchip_pcie_write(rockchip, vid_regs, + rockchip_pcie_write(rockchip, + hdr->vendorid | hdr->subsys_vendor_id << 16, PCIE_CORE_CONFIG_VENDOR); } - rockchip_pcie_write(rockchip, hdr->deviceid << 16, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + PCI_VENDOR_ID); + reg = rockchip_pcie_read(rockchip, PCIE_EP_CONFIG_DID_VID); + reg = (reg & 0xFFFF) | (hdr->deviceid << 16); + rockchip_pcie_write(rockchip, reg, PCIE_EP_CONFIG_DID_VID); rockchip_pcie_write(rockchip, hdr->revid | @@ -263,8 +271,7 @@ struct rockchip_pcie *pcie = &ep->rockchip; u32 r; - r = find_first_zero_bit(&ep->ob_region_map, - sizeof(ep->ob_region_map) * BITS_PER_LONG); + r = find_first_zero_bit(&ep->ob_region_map, BITS_PER_LONG); /* * Region 0 is reserved for configuration space and shouldn't * be used elsewhere per TRM, so leave it out. @@ -312,15 +319,15 @@ { struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags; + u32 flags; flags = rockchip_pcie_read(rockchip, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + ROCKCHIP_PCIE_EP_MSI_CTRL_REG); flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK; flags |= - ((multi_msg_cap << 1) << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | - PCI_MSI_FLAGS_64BIT; + (multi_msg_cap << ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET) | + (PCI_MSI_FLAGS_64BIT << ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET); flags &= ~ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP; rockchip_pcie_write(rockchip, flags, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + @@ -332,7 +339,7 @@ { struct rockchip_pcie_ep *ep = epc_get_drvdata(epc); struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags; + u32 flags; flags = rockchip_pcie_read(rockchip, ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + @@ -345,48 +352,25 @@ } static void rockchip_pcie_ep_assert_intx(struct rockchip_pcie_ep *ep, u8 fn, - u8 intx, bool is_asserted) + u8 intx, bool do_assert) { struct rockchip_pcie *rockchip = &ep->rockchip; - u32 r = ep->max_regions - 1; - u32 offset; - u32 status; - u8 msg_code; - - if (unlikely(ep->irq_pci_addr != ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR || - ep->irq_pci_fn != fn)) { - rockchip_pcie_prog_ep_ob_atu(rockchip, fn, r, - AXI_WRAPPER_NOR_MSG, - ep->irq_phys_addr, 0, 0); - ep->irq_pci_addr = ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR; - ep->irq_pci_fn = fn; - } intx &= 3; - if (is_asserted) { + + if (do_assert) { ep->irq_pending |= BIT(intx); - msg_code = ROCKCHIP_PCIE_MSG_CODE_ASSERT_INTA + intx; + rockchip_pcie_write(rockchip, + PCIE_CLIENT_INT_IN_ASSERT | + PCIE_CLIENT_INT_PEND_ST_PEND, + PCIE_CLIENT_LEGACY_INT_CTRL); } else { ep->irq_pending &= ~BIT(intx); - msg_code = ROCKCHIP_PCIE_MSG_CODE_DEASSERT_INTA + intx; - } - - status = rockchip_pcie_read(rockchip, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + - ROCKCHIP_PCIE_EP_CMD_STATUS); - status &= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; - - if ((status != 0) ^ (ep->irq_pending != 0)) { - status ^= ROCKCHIP_PCIE_EP_CMD_STATUS_IS; - rockchip_pcie_write(rockchip, status, - ROCKCHIP_PCIE_EP_FUNC_BASE(fn) + - ROCKCHIP_PCIE_EP_CMD_STATUS); + rockchip_pcie_write(rockchip, + PCIE_CLIENT_INT_IN_DEASSERT | + PCIE_CLIENT_INT_PEND_ST_NORMAL, + PCIE_CLIENT_LEGACY_INT_CTRL); } - - offset = - ROCKCHIP_PCIE_MSG_ROUTING(ROCKCHIP_PCIE_MSG_ROUTING_LOCAL_INTX) | - ROCKCHIP_PCIE_MSG_CODE(msg_code) | ROCKCHIP_PCIE_MSG_NO_DATA; - writel(0, ep->irq_cpu_addr + offset); } static int rockchip_pcie_ep_send_legacy_irq(struct rockchip_pcie_ep *ep, u8 fn, @@ -416,7 +400,7 @@ u8 interrupt_num) { struct rockchip_pcie *rockchip = &ep->rockchip; - u16 flags, mme, data, data_mask; + u32 flags, mme, data, data_mask; u8 msi_count; u64 pci_addr, pci_addr_mask = 0xff; @@ -506,6 +490,7 @@ .linkup_notifier = false, .msi_capable = true, .msix_capable = false, + .align = 256, }; static const struct pci_epc_features* @@ -631,6 +616,9 @@ ep->irq_pci_addr = ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR; + rockchip_pcie_write(rockchip, PCIE_CLIENT_CONF_ENABLE, + PCIE_CLIENT_CONFIG); + return 0; err_epc_mem_exit: pci_epc_mem_exit(epc); --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-rockchip.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-rockchip.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -83,7 +84,7 @@ } rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev, - "mgmt-sticky"); + "mgmt-sticky"); if (IS_ERR(rockchip->mgmt_sticky_rst)) { if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER) dev_err(dev, "missing mgmt-sticky reset property in node\n"); @@ -119,11 +120,11 @@ } if (rockchip->is_rc) { - rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); - if (IS_ERR(rockchip->ep_gpio)) { - dev_err(dev, "missing ep-gpios property in node\n"); - return PTR_ERR(rockchip->ep_gpio); - } + rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep", + GPIOD_OUT_LOW); + if (IS_ERR(rockchip->ep_gpio)) + return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio), + "failed to get ep GPIO\n"); } rockchip->aclk_pcie = devm_clk_get(dev, "aclk"); @@ -154,6 +155,12 @@ } EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt); +#define rockchip_pcie_read_addr(addr) rockchip_pcie_read(rockchip, addr) +/* 100 ms max wait time for PHY PLLs to lock */ +#define RK_PHY_PLL_LOCK_TIMEOUT_US 100000 +/* Sleep should be less than 20ms */ +#define RK_PHY_PLL_LOCK_SLEEP_US 1000 + int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) { struct device *dev = rockchip->dev; @@ -255,6 +262,16 @@ } } + err = readx_poll_timeout(rockchip_pcie_read_addr, + PCIE_CLIENT_SIDE_BAND_STATUS, + regs, !(regs & PCIE_CLIENT_PHY_ST), + RK_PHY_PLL_LOCK_SLEEP_US, + RK_PHY_PLL_LOCK_TIMEOUT_US); + if (err) { + dev_err(dev, "PHY PLLs could not lock, %d\n", err); + goto err_power_off_phy; + } + /* * Please don't reorder the deassert sequence of the following * four reset pins. --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-rockchip.h +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-rockchip.h @@ -37,6 +37,13 @@ #define PCIE_CLIENT_MODE_EP HIWORD_UPDATE(0x0040, 0) #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) +#define PCIE_CLIENT_LEGACY_INT_CTRL (PCIE_CLIENT_BASE + 0x0c) +#define PCIE_CLIENT_INT_IN_ASSERT HIWORD_UPDATE_BIT(0x0002) +#define PCIE_CLIENT_INT_IN_DEASSERT HIWORD_UPDATE(0x0002, 0) +#define PCIE_CLIENT_INT_PEND_ST_PEND HIWORD_UPDATE_BIT(0x0001) +#define PCIE_CLIENT_INT_PEND_ST_NORMAL HIWORD_UPDATE(0x0001, 0) +#define PCIE_CLIENT_SIDE_BAND_STATUS (PCIE_CLIENT_BASE + 0x20) +#define PCIE_CLIENT_PHY_ST BIT(12) #define PCIE_CLIENT_DEBUG_OUT_0 (PCIE_CLIENT_BASE + 0x3c) #define PCIE_CLIENT_DEBUG_LTSSM_MASK GENMASK(5, 0) #define PCIE_CLIENT_DEBUG_LTSSM_L1 0x18 @@ -132,6 +139,8 @@ #define PCIE_RC_RP_ATS_BASE 0x400000 #define PCIE_RC_CONFIG_NORMAL_BASE 0x800000 #define PCIE_RC_CONFIG_BASE 0xa00000 +#define PCIE_EP_CONFIG_BASE 0xa00000 +#define PCIE_EP_CONFIG_DID_VID (PCIE_EP_CONFIG_BASE + 0x00) #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) #define PCIE_RC_CONFIG_SCC_SHIFT 16 #define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) @@ -223,6 +232,7 @@ #define ROCKCHIP_PCIE_EP_CMD_STATUS 0x4 #define ROCKCHIP_PCIE_EP_CMD_STATUS_IS BIT(19) #define ROCKCHIP_PCIE_EP_MSI_CTRL_REG 0x90 +#define ROCKCHIP_PCIE_EP_MSI_FLAGS_OFFSET 16 #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_OFFSET 17 #define ROCKCHIP_PCIE_EP_MSI_CTRL_MMC_MASK GENMASK(19, 17) #define ROCKCHIP_PCIE_EP_MSI_CTRL_MME_OFFSET 20 @@ -230,8 +240,11 @@ #define ROCKCHIP_PCIE_EP_MSI_CTRL_ME BIT(16) #define ROCKCHIP_PCIE_EP_MSI_CTRL_MASK_MSI_CAP BIT(24) #define ROCKCHIP_PCIE_EP_DUMMY_IRQ_ADDR 0x1 -#define ROCKCHIP_PCIE_EP_PCI_LEGACY_IRQ_ADDR 0x3 #define ROCKCHIP_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12)) + +#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8 +#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20 + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ (PCIE_RC_RP_ATS_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008) #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \ --- linux-oracle-5.4.0.orig/drivers/pci/controller/pcie-xilinx-nwl.c +++ linux-oracle-5.4.0/drivers/pci/controller/pcie-xilinx-nwl.c @@ -6,6 +6,7 @@ * (C) Copyright 2014 - 2015, Xilinx, Inc. */ +#include #include #include #include @@ -78,8 +79,8 @@ #define MSGF_MISC_SR_NON_FATAL_DEV BIT(22) #define MSGF_MISC_SR_FATAL_DEV BIT(23) #define MSGF_MISC_SR_LINK_DOWN BIT(24) -#define MSGF_MSIC_SR_LINK_AUTO_BWIDTH BIT(25) -#define MSGF_MSIC_SR_LINK_BWIDTH BIT(26) +#define MSGF_MISC_SR_LINK_AUTO_BWIDTH BIT(25) +#define MSGF_MISC_SR_LINK_BWIDTH BIT(26) #define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \ MSGF_MISC_SR_RXMSG_OVER | \ @@ -94,8 +95,8 @@ MSGF_MISC_SR_NON_FATAL_DEV | \ MSGF_MISC_SR_FATAL_DEV | \ MSGF_MISC_SR_LINK_DOWN | \ - MSGF_MSIC_SR_LINK_AUTO_BWIDTH | \ - MSGF_MSIC_SR_LINK_BWIDTH) + MSGF_MISC_SR_LINK_AUTO_BWIDTH | \ + MSGF_MISC_SR_LINK_BWIDTH) /* Legacy interrupt status mask bits */ #define MSGF_LEG_SR_INTA BIT(0) @@ -169,6 +170,7 @@ u8 root_busno; struct nwl_msi msi; struct irq_domain *legacy_irq_domain; + struct clk *clk; raw_spinlock_t leg_mask_lock; }; @@ -306,10 +308,10 @@ if (misc_stat & MSGF_MISC_SR_FATAL_DEV) dev_err(dev, "Fatal Error Detected\n"); - if (misc_stat & MSGF_MSIC_SR_LINK_AUTO_BWIDTH) + if (misc_stat & MSGF_MISC_SR_LINK_AUTO_BWIDTH) dev_info(dev, "Link Autonomous Bandwidth Management Status bit set\n"); - if (misc_stat & MSGF_MSIC_SR_LINK_BWIDTH) + if (misc_stat & MSGF_MISC_SR_LINK_BWIDTH) dev_info(dev, "Link Bandwidth Management Status bit set\n"); /* Clear misc interrupt status */ @@ -382,14 +384,12 @@ static void nwl_mask_leg_irq(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(data->irq); - struct nwl_pcie *pcie; + struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); unsigned long flags; u32 mask; u32 val; - pcie = irq_desc_get_chip_data(desc); - mask = 1 << (data->hwirq - 1); + mask = 1 << data->hwirq; raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); nwl_bridge_writel(pcie, (val & (~mask)), MSGF_LEG_MASK); @@ -398,14 +398,12 @@ static void nwl_unmask_leg_irq(struct irq_data *data) { - struct irq_desc *desc = irq_to_desc(data->irq); - struct nwl_pcie *pcie; + struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); unsigned long flags; u32 mask; u32 val; - pcie = irq_desc_get_chip_data(desc); - mask = 1 << (data->hwirq - 1); + mask = 1 << data->hwirq; raw_spin_lock_irqsave(&pcie->leg_mask_lock, flags); val = nwl_bridge_readl(pcie, MSGF_LEG_MASK); nwl_bridge_writel(pcie, (val | mask), MSGF_LEG_MASK); @@ -839,6 +837,16 @@ return err; } + pcie->clk = devm_clk_get(dev, NULL); + if (IS_ERR(pcie->clk)) + return PTR_ERR(pcie->clk); + + err = clk_prepare_enable(pcie->clk); + if (err) { + dev_err(dev, "can't enable PCIe ref clock\n"); + return err; + } + err = nwl_pcie_bridge_init(pcie); if (err) { dev_err(dev, "HW Initialization failed\n"); --- linux-oracle-5.4.0.orig/drivers/pci/controller/vmd.c +++ linux-oracle-5.4.0/drivers/pci/controller/vmd.c @@ -593,25 +593,41 @@ if (!membar2) return -ENOMEM; offset[0] = vmd->dev->resource[VMD_MEMBAR1].start - - readq(membar2 + MB2_SHADOW_OFFSET); + (readq(membar2 + MB2_SHADOW_OFFSET) & + PCI_BASE_ADDRESS_MEM_MASK); offset[1] = vmd->dev->resource[VMD_MEMBAR2].start - - readq(membar2 + MB2_SHADOW_OFFSET + 8); + (readq(membar2 + MB2_SHADOW_OFFSET + 8) & + PCI_BASE_ADDRESS_MEM_MASK); pci_iounmap(vmd->dev, membar2); } } /* * Certain VMD devices may have a root port configuration option which - * limits the bus range to between 0-127 or 128-255 + * limits the bus range to between 0-127, 128-255, or 224-255 */ if (features & VMD_FEAT_HAS_BUS_RESTRICTIONS) { - u32 vmcap, vmconfig; + u16 reg16; - pci_read_config_dword(vmd->dev, PCI_REG_VMCAP, &vmcap); - pci_read_config_dword(vmd->dev, PCI_REG_VMCONFIG, &vmconfig); - if (BUS_RESTRICT_CAP(vmcap) && - (BUS_RESTRICT_CFG(vmconfig) == 0x1)) - vmd->busn_start = 128; + pci_read_config_word(vmd->dev, PCI_REG_VMCAP, ®16); + if (BUS_RESTRICT_CAP(reg16)) { + pci_read_config_word(vmd->dev, PCI_REG_VMCONFIG, + ®16); + + switch (BUS_RESTRICT_CFG(reg16)) { + case 1: + vmd->busn_start = 128; + break; + case 2: + vmd->busn_start = 224; + break; + case 3: + pci_err(vmd->dev, "Unknown Bus Offset Setting\n"); + return -ENODEV; + default: + break; + } + } } res = &vmd->dev->resource[VMD_CFGBAR]; @@ -678,9 +694,10 @@ vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info, x86_vector_domain); - irq_domain_free_fwnode(fn); - if (!vmd->irq_domain) + if (!vmd->irq_domain) { + irq_domain_free_fwnode(fn); return -ENODEV; + } pci_add_resource(&resources, &vmd->resources[0]); pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]); @@ -691,6 +708,7 @@ if (!vmd->bus) { pci_free_resource_list(&resources); irq_domain_remove(vmd->irq_domain); + irq_domain_free_fwnode(fn); return -ENODEV; } @@ -805,6 +823,7 @@ static void vmd_remove(struct pci_dev *dev) { struct vmd_dev *vmd = pci_get_drvdata(dev); + struct fwnode_handle *fn = vmd->irq_domain->fwnode; sysfs_remove_link(&vmd->dev->dev.kobj, "domain"); pci_stop_root_bus(vmd->bus); @@ -813,6 +832,7 @@ vmd_teardown_dma_ops(vmd); vmd_detach_resources(vmd); irq_domain_remove(vmd->irq_domain); + irq_domain_free_fwnode(fn); } #ifdef CONFIG_PM_SLEEP @@ -854,6 +874,8 @@ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_28C0), .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW | VMD_FEAT_HAS_BUS_RESTRICTIONS,}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VMD_9A0B), + .driver_data = VMD_FEAT_HAS_BUS_RESTRICTIONS,}, {0,} }; MODULE_DEVICE_TABLE(pci, vmd_ids); --- linux-oracle-5.4.0.orig/drivers/pci/ecam.c +++ linux-oracle-5.4.0/drivers/pci/ecam.c @@ -164,4 +164,14 @@ .write = pci_generic_config_write32, } }; + +/* ECAM ops for 32-bit read only (non-compliant) */ +const struct pci_ecam_ops pci_32b_read_ops = { + .bus_shift = 20, + .pci_ops = { + .map_bus = pci_ecam_map_bus, + .read = pci_generic_config_read32, + .write = pci_generic_config_write, + } +}; #endif --- linux-oracle-5.4.0.orig/drivers/pci/endpoint/functions/pci-epf-test.c +++ linux-oracle-5.4.0/drivers/pci/endpoint/functions/pci-epf-test.c @@ -604,6 +604,7 @@ ret = pci_epf_register_driver(&test_driver); if (ret) { + destroy_workqueue(kpcitest_workqueue); pr_err("Failed to register pci epf test driver --> %d\n", ret); return ret; } @@ -614,6 +615,8 @@ static void __exit pci_epf_test_exit(void) { + if (kpcitest_workqueue) + destroy_workqueue(kpcitest_workqueue); pci_epf_unregister_driver(&test_driver); } module_exit(pci_epf_test_exit); --- linux-oracle-5.4.0.orig/drivers/pci/endpoint/pci-epc-core.c +++ linux-oracle-5.4.0/drivers/pci/endpoint/pci-epc-core.c @@ -578,7 +578,7 @@ { int r; - r = devres_destroy(dev, devm_pci_epc_release, devm_pci_epc_match, + r = devres_release(dev, devm_pci_epc_release, devm_pci_epc_match, epc); dev_WARN_ONCE(dev, r, "couldn't find PCI EPC resource\n"); } --- linux-oracle-5.4.0.orig/drivers/pci/endpoint/pci-epc-mem.c +++ linux-oracle-5.4.0/drivers/pci/endpoint/pci-epc-mem.c @@ -79,6 +79,7 @@ mem->page_size = page_size; mem->pages = pages; mem->size = size; + mutex_init(&mem->lock); epc->mem = mem; @@ -122,7 +123,7 @@ phys_addr_t *phys_addr, size_t size) { int pageno; - void __iomem *virt_addr; + void __iomem *virt_addr = NULL; struct pci_epc_mem *mem = epc->mem; unsigned int page_shift = ilog2(mem->page_size); int order; @@ -130,15 +131,18 @@ size = ALIGN(size, mem->page_size); order = pci_epc_mem_get_order(mem, size); + mutex_lock(&mem->lock); pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order); if (pageno < 0) - return NULL; + goto ret; *phys_addr = mem->phys_base + (pageno << page_shift); virt_addr = ioremap(*phys_addr, size); if (!virt_addr) bitmap_release_region(mem->bitmap, pageno, order); +ret: + mutex_unlock(&mem->lock); return virt_addr; } EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr); @@ -164,7 +168,9 @@ pageno = (phys_addr - mem->phys_base) >> page_shift; size = ALIGN(size, mem->page_size); order = pci_epc_mem_get_order(mem, size); + mutex_lock(&mem->lock); bitmap_release_region(mem->bitmap, pageno, order); + mutex_unlock(&mem->lock); } EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/TODO +++ linux-oracle-5.4.0/drivers/pci/hotplug/TODO @@ -40,9 +40,6 @@ * The return value of pci_hp_register() is not checked. -* iounmap(io_mem) is called in the error path of ebda_rsrc_controller() - and once more in the error path of its caller ibmphp_access_ebda(). - * The various slot data structures are difficult to follow and need to be simplified. A lot of functions are too large and too complex, they need to be broken up into smaller, manageable pieces. Negative examples are --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/acpiphp_glue.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/acpiphp_glue.c @@ -122,13 +122,21 @@ struct acpiphp_context *context; acpi_lock_hp_context(); + context = acpiphp_get_context(adev); - if (!context || context->func.parent->is_going_away) { - acpi_unlock_hp_context(); - return NULL; + if (!context) + goto unlock; + + if (context->func.parent->is_going_away) { + acpiphp_put_context(context); + context = NULL; + goto unlock; } + get_bridge(context->func.parent); acpiphp_put_context(context); + +unlock: acpi_unlock_hp_context(); return context; } @@ -449,8 +457,15 @@ /* Scan non-hotplug bridges that need to be reconfigured */ for_each_pci_bridge(dev, bus) { - if (!hotplug_is_native(dev)) - max = pci_scan_bridge(bus, dev, max, 1); + if (hotplug_is_native(dev)) + continue; + + max = pci_scan_bridge(bus, dev, max, 1); + if (dev->subordinate) { + pcibios_resource_survey_bus(dev->subordinate); + pci_bus_size_bridges(dev->subordinate); + pci_bus_assign_resources(dev->subordinate); + } } } @@ -480,7 +495,6 @@ if (PCI_SLOT(dev->devfn) == slot->device) acpiphp_native_scan_bridge(dev); } - pci_assign_unassigned_bridge_resources(bus->self); } else { LIST_HEAD(add_list); int max, pass; @@ -526,6 +540,7 @@ slot->flags &= ~SLOT_ENABLED; continue; } + pci_dev_put(dev); } } --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/cpqphp_pci.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/cpqphp_pci.c @@ -135,11 +135,13 @@ static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value) { u32 vendID = 0; + int ret; - if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID) == -1) - return -1; - if (vendID == 0xffffffff) - return -1; + ret = pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &vendID); + if (ret != PCIBIOS_SUCCESSFUL) + return PCIBIOS_DEVICE_NOT_FOUND; + if (PCI_POSSIBLE_ERROR(vendID)) + return PCIBIOS_DEVICE_NOT_FOUND; return pci_bus_read_config_dword(bus, devfn, offset, value); } @@ -200,13 +202,15 @@ { u16 tdevice; u32 work; + int ret; u8 tbus; ctrl->pci_bus->number = bus_num; for (tdevice = 0; tdevice < 0xFF; tdevice++) { /* Scan for access first */ - if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) + ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work); + if (ret) continue; dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); /* Yep we got one. Not a bridge ? */ @@ -218,7 +222,8 @@ } for (tdevice = 0; tdevice < 0xFF; tdevice++) { /* Scan for access first */ - if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) + ret = PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work); + if (ret) continue; dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); /* Yep we got one. bridge ? */ @@ -251,7 +256,7 @@ *dev_num = tdevice; ctrl->pci_bus->number = tbus; pci_bus_read_config_dword(ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); - if (!nobridge || (work == 0xffffffff)) + if (!nobridge || PCI_POSSIBLE_ERROR(work)) return 0; dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/ibmphp_ebda.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/ibmphp_ebda.c @@ -714,8 +714,7 @@ /* init hpc structure */ hpc_ptr = alloc_ebda_hpc(slot_num, bus_num); if (!hpc_ptr) { - rc = -ENOMEM; - goto error_no_hpc; + return -ENOMEM; } hpc_ptr->ctlr_id = ctlr_id; hpc_ptr->ctlr_relative_id = ctlr; @@ -910,8 +909,6 @@ kfree(tmp_slot); error_no_slot: free_ebda_hpc(hpc_ptr); -error_no_hpc: - iounmap(io_mem); return rc; } --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pciehp.h +++ linux-oracle-5.4.0/drivers/pci/hotplug/pciehp.h @@ -72,6 +72,9 @@ * @reset_lock: prevents access to the Data Link Layer Link Active bit in the * Link Status register and to the Presence Detect State bit in the Slot * Status register during a slot reset which may cause them to flap + * @depth: Number of additional hotplug ports in the path to the root bus, + * used as lock subclass for @reset_lock + * @ist_running: flag to keep user request waiting while IRQ thread is running * @request_result: result of last user request submitted to the IRQ thread * @requester: wait queue to wake up on completion of user request, * used for synchronous slot enable/disable request via sysfs @@ -101,6 +104,8 @@ struct hotplug_slot hotplug_slot; /* hotplug core interface */ struct rw_semaphore reset_lock; + unsigned int depth; + unsigned int ist_running; int request_result; wait_queue_head_t requester; }; @@ -172,10 +177,10 @@ void pciehp_get_latch_status(struct controller *ctrl, u8 *status); int pciehp_query_power_fault(struct controller *ctrl); -bool pciehp_card_present(struct controller *ctrl); -bool pciehp_card_present_or_link_active(struct controller *ctrl); +int pciehp_card_present(struct controller *ctrl); +int pciehp_card_present_or_link_active(struct controller *ctrl); int pciehp_check_link_status(struct controller *ctrl); -bool pciehp_check_link_active(struct controller *ctrl); +int pciehp_check_link_active(struct controller *ctrl); void pciehp_release_ctrl(struct controller *ctrl); int pciehp_sysfs_enable_slot(struct hotplug_slot *hotplug_slot); --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pciehp_core.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/pciehp_core.c @@ -139,10 +139,15 @@ { struct controller *ctrl = to_ctrl(hotplug_slot); struct pci_dev *pdev = ctrl->pcie->port; + int ret; pci_config_pm_runtime_get(pdev); - *value = pciehp_card_present_or_link_active(ctrl); + ret = pciehp_card_present_or_link_active(ctrl); pci_config_pm_runtime_put(pdev); + if (ret < 0) + return ret; + + *value = ret; return 0; } @@ -158,13 +163,13 @@ */ static void pciehp_check_presence(struct controller *ctrl) { - bool occupied; + int occupied; - down_read(&ctrl->reset_lock); + down_read_nested(&ctrl->reset_lock, ctrl->depth); mutex_lock(&ctrl->state_lock); occupied = pciehp_card_present_or_link_active(ctrl); - if ((occupied && (ctrl->state == OFF_STATE || + if ((occupied > 0 && (ctrl->state == OFF_STATE || ctrl->state == BLINKINGON_STATE)) || (!occupied && (ctrl->state == ON_STATE || ctrl->state == BLINKINGOFF_STATE))) @@ -253,7 +258,7 @@ return pcie_ports_native || host->native_pme; } -static int pciehp_suspend(struct pcie_device *dev) +static void pciehp_disable_interrupt(struct pcie_device *dev) { /* * Disable hotplug interrupt so that it does not trigger @@ -261,7 +266,19 @@ */ if (pme_is_native(dev)) pcie_disable_interrupt(get_service_data(dev)); +} + +#ifdef CONFIG_PM_SLEEP +static int pciehp_suspend(struct pcie_device *dev) +{ + /* + * If the port is already runtime suspended we can keep it that + * way. + */ + if (dev_pm_smart_suspend_and_suspended(&dev->port->dev)) + return 0; + pciehp_disable_interrupt(dev); return 0; } @@ -279,6 +296,7 @@ return 0; } +#endif static int pciehp_resume(struct pcie_device *dev) { @@ -292,6 +310,12 @@ return 0; } +static int pciehp_runtime_suspend(struct pcie_device *dev) +{ + pciehp_disable_interrupt(dev); + return 0; +} + static int pciehp_runtime_resume(struct pcie_device *dev) { struct controller *ctrl = get_service_data(dev); @@ -318,10 +342,12 @@ .remove = pciehp_remove, #ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .suspend = pciehp_suspend, .resume_noirq = pciehp_resume_noirq, .resume = pciehp_resume, - .runtime_suspend = pciehp_suspend, +#endif + .runtime_suspend = pciehp_runtime_suspend, .runtime_resume = pciehp_runtime_resume, #endif /* PM */ }; --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pciehp_ctrl.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/pciehp_ctrl.c @@ -226,7 +226,7 @@ void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events) { - bool present, link_active; + int present, link_active; /* * If the slot is on and presence or link has changed, turn it off. @@ -257,7 +257,15 @@ mutex_lock(&ctrl->state_lock); present = pciehp_card_present(ctrl); link_active = pciehp_check_link_active(ctrl); - if (!present && !link_active) { + if (present <= 0 && link_active <= 0) { + if (ctrl->state == BLINKINGON_STATE) { + ctrl->state = OFF_STATE; + cancel_delayed_work(&ctrl->button_work); + pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, + INDICATOR_NOOP); + ctrl_info(ctrl, "Slot(%s): Card not present\n", + slot_name(ctrl)); + } mutex_unlock(&ctrl->state_lock); return; } @@ -375,7 +383,8 @@ ctrl->request_result = -ENODEV; pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC); wait_event(ctrl->requester, - !atomic_read(&ctrl->pending_events)); + !atomic_read(&ctrl->pending_events) && + !ctrl->ist_running); return ctrl->request_result; case POWERON_STATE: ctrl_info(ctrl, "Slot(%s): Already in powering on state\n", @@ -408,7 +417,8 @@ mutex_unlock(&ctrl->state_lock); pciehp_request(ctrl, DISABLE_SLOT); wait_event(ctrl->requester, - !atomic_read(&ctrl->pending_events)); + !atomic_read(&ctrl->pending_events) && + !ctrl->ist_running); return ctrl->request_result; case POWEROFF_STATE: ctrl_info(ctrl, "Slot(%s): Already in powering off state\n", --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pciehp_hpc.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/pciehp_hpc.c @@ -79,6 +79,8 @@ if (slot_status & PCI_EXP_SLTSTA_CC) { pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_CC); + ctrl->cmd_busy = 0; + smp_mb(); return 1; } if (timeout < 0) @@ -201,17 +203,29 @@ pcie_do_write_cmd(ctrl, cmd, mask, false); } -bool pciehp_check_link_active(struct controller *ctrl) +/** + * pciehp_check_link_active() - Is the link active + * @ctrl: PCIe hotplug controller + * + * Check whether the downstream link is currently active. Note it is + * possible that the card is removed immediately after this so the + * caller may need to take it into account. + * + * If the hotplug controller itself is not available anymore returns + * %-ENODEV. + */ +int pciehp_check_link_active(struct controller *ctrl) { struct pci_dev *pdev = ctrl_dev(ctrl); u16 lnk_status; - bool ret; + int ret; - pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); - ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); + ret = pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnk_status); + if (ret == PCIBIOS_DEVICE_NOT_FOUND || lnk_status == (u16)~0) + return -ENODEV; - if (ret) - ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); + ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); + ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); return ret; } @@ -279,17 +293,11 @@ static int __pciehp_link_set(struct controller *ctrl, bool enable) { struct pci_dev *pdev = ctrl_dev(ctrl); - u16 lnk_ctrl; - pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_LD, + enable ? 0 : PCI_EXP_LNKCTL_LD); - if (enable) - lnk_ctrl &= ~PCI_EXP_LNKCTL_LD; - else - lnk_ctrl |= PCI_EXP_LNKCTL_LD; - - pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl); - ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); return 0; } @@ -373,13 +381,29 @@ *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS); } -bool pciehp_card_present(struct controller *ctrl) +/** + * pciehp_card_present() - Is the card present + * @ctrl: PCIe hotplug controller + * + * Function checks whether the card is currently present in the slot and + * in that case returns true. Note it is possible that the card is + * removed immediately after the check so the caller may need to take + * this into account. + * + * It the hotplug controller itself is not available anymore returns + * %-ENODEV. + */ +int pciehp_card_present(struct controller *ctrl) { struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_status; + int ret; - pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); - return slot_status & PCI_EXP_SLTSTA_PDS; + ret = pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); + if (ret == PCIBIOS_DEVICE_NOT_FOUND || slot_status == (u16)~0) + return -ENODEV; + + return !!(slot_status & PCI_EXP_SLTSTA_PDS); } /** @@ -390,10 +414,19 @@ * Presence Detect State bit, this helper also returns true if the Link Active * bit is set. This is a concession to broken hotplug ports which hardwire * Presence Detect State to zero, such as Wilocity's [1ae9:0200]. + * + * Returns: %1 if the slot is occupied and %0 if it is not. If the hotplug + * port is not present anymore returns %-ENODEV. */ -bool pciehp_card_present_or_link_active(struct controller *ctrl) +int pciehp_card_present_or_link_active(struct controller *ctrl) { - return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl); + int ret; + + ret = pciehp_card_present(ctrl); + if (ret) + return ret; + + return pciehp_check_link_active(ctrl); } int pciehp_query_power_fault(struct controller *ctrl) @@ -492,7 +525,7 @@ struct controller *ctrl = (struct controller *)dev_id; struct pci_dev *pdev = ctrl_dev(ctrl); struct device *parent = pdev->dev.parent; - u16 status, events; + u16 status, events = 0; /* * Interrupts only occur in D3hot or shallower and only if enabled @@ -517,6 +550,7 @@ } } +read_status: pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); if (status == (u16) ~0) { ctrl_info(ctrl, "%s: no response from device\n", __func__); @@ -529,24 +563,39 @@ * Slot Status contains plain status bits as well as event * notification bits; right now we only want the event bits. */ - events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | - PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | - PCI_EXP_SLTSTA_DLLSC); + status &= PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | + PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | + PCI_EXP_SLTSTA_DLLSC; /* * If we've already reported a power fault, don't report it again * until we've done something to handle it. */ if (ctrl->power_fault_detected) - events &= ~PCI_EXP_SLTSTA_PFD; + status &= ~PCI_EXP_SLTSTA_PFD; + else if (status & PCI_EXP_SLTSTA_PFD) + ctrl->power_fault_detected = true; + events |= status; if (!events) { if (parent) pm_runtime_put(parent); return IRQ_NONE; } - pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); + if (status) { + pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, status); + + /* + * In MSI mode, all event bits must be zero before the port + * will send a new interrupt (PCIe Base Spec r5.0 sec 6.7.3.4). + * So re-read the Slot Status register in case a bit was set + * between read and write. + */ + if (pci_dev_msi_enabled(pdev) && !pciehp_poll_mode) + goto read_status; + } + ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); if (parent) pm_runtime_put(parent); @@ -583,23 +632,22 @@ irqreturn_t ret; u32 events; + ctrl->ist_running = true; pci_config_pm_runtime_get(pdev); /* rerun pciehp_isr() if the port was inaccessible on interrupt */ if (atomic_fetch_and(~RERUN_ISR, &ctrl->pending_events) & RERUN_ISR) { ret = pciehp_isr(irq, dev_id); enable_irq(irq); - if (ret != IRQ_WAKE_THREAD) { - pci_config_pm_runtime_put(pdev); - return ret; - } + if (ret != IRQ_WAKE_THREAD) + goto out; } synchronize_hardirq(irq); events = atomic_xchg(&ctrl->pending_events, 0); if (!events) { - pci_config_pm_runtime_put(pdev); - return IRQ_NONE; + ret = IRQ_NONE; + goto out; } /* Check Attention Button Pressed */ @@ -610,8 +658,7 @@ } /* Check Power Fault Detected */ - if ((events & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) { - ctrl->power_fault_detected = 1; + if (events & PCI_EXP_SLTSTA_PFD) { ctrl_err(ctrl, "Slot(%s): Power fault\n", slot_name(ctrl)); pciehp_set_indicators(ctrl, PCI_EXP_SLTCTL_PWR_IND_OFF, PCI_EXP_SLTCTL_ATTN_IND_ON); @@ -621,16 +668,19 @@ * Disable requests have higher priority than Presence Detect Changed * or Data Link Layer State Changed events. */ - down_read(&ctrl->reset_lock); + down_read_nested(&ctrl->reset_lock, ctrl->depth); if (events & DISABLE_SLOT) pciehp_handle_disable_request(ctrl); else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) pciehp_handle_presence_or_link_change(ctrl, events); up_read(&ctrl->reset_lock); + ret = IRQ_HANDLED; +out: pci_config_pm_runtime_put(pdev); + ctrl->ist_running = false; wake_up(&ctrl->requester); - return IRQ_HANDLED; + return ret; } static int pciehp_poll(void *data) @@ -752,7 +802,7 @@ if (probe) return 0; - down_write(&ctrl->reset_lock); + down_write_nested(&ctrl->reset_lock, ctrl->depth); if (!ATTN_BUTTN(ctrl)) { ctrl_mask |= PCI_EXP_SLTCTL_PDCE; @@ -808,6 +858,20 @@ #define FLAG(x, y) (((x) & (y)) ? '+' : '-') +static inline int pcie_hotplug_depth(struct pci_dev *dev) +{ + struct pci_bus *bus = dev->bus; + int depth = 0; + + while (bus->parent) { + bus = bus->parent; + if (bus->self && bus->self->is_hotplug_bridge) + depth++; + } + + return depth; +} + struct controller *pcie_init(struct pcie_device *dev) { struct controller *ctrl; @@ -821,6 +885,7 @@ return NULL; ctrl->pcie = dev; + ctrl->depth = pcie_hotplug_depth(dev->port); pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); if (pdev->hotplug_user_indicators) @@ -903,6 +968,8 @@ } DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); +DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0110, + PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0400, PCI_CLASS_BRIDGE_PCI, 8, quirk_cmd_compl); DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0401, --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pciehp_pci.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/pciehp_pci.c @@ -63,7 +63,14 @@ pci_assign_unassigned_bridge_resources(bridge); pcie_bus_configure_settings(parent); + + /* + * Release reset_lock during driver binding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_bus_add_devices(parent); + down_read_nested(&ctrl->reset_lock, ctrl->depth); out: pci_unlock_rescan_remove(); @@ -104,7 +111,15 @@ list_for_each_entry_safe_reverse(dev, temp, &parent->devices, bus_list) { pci_dev_get(dev); + + /* + * Release reset_lock during driver unbinding + * to avoid AB-BA deadlock with device_lock. + */ + up_read(&ctrl->reset_lock); pci_stop_and_remove_bus_device(dev); + down_read_nested(&ctrl->reset_lock, ctrl->depth); + /* * Ensure that no new Requests will be generated from * the device. --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/pnv_php.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/pnv_php.c @@ -18,6 +18,9 @@ #define DRIVER_AUTHOR "Gavin Shan, IBM Corporation" #define DRIVER_DESC "PowerPC PowerNV PCI Hotplug Driver" +#define SLOT_WARN(sl, x...) \ + ((sl)->pdev ? pci_warn((sl)->pdev, x) : dev_warn(&(sl)->bus->dev, x)) + struct pnv_php_event { bool added; struct pnv_php_slot *php_slot; @@ -35,7 +38,6 @@ bool disable_device) { struct pci_dev *pdev = php_slot->pdev; - int irq = php_slot->irq; u16 ctrl; if (php_slot->irq > 0) { @@ -54,7 +56,7 @@ php_slot->wq = NULL; } - if (disable_device || irq > 0) { + if (disable_device) { if (pdev->msix_enabled) pci_disable_msix(pdev); else if (pdev->msi_enabled) @@ -151,17 +153,11 @@ static void pnv_php_detach_device_nodes(struct device_node *parent) { struct device_node *dn; - int refcount; for_each_child_of_node(parent, dn) { pnv_php_detach_device_nodes(dn); of_node_put(dn); - refcount = kref_read(&dn->kobj.kref); - if (refcount != 1) - pr_warn("Invalid refcount %d on <%pOF>\n", - refcount, dn); - of_detach_node(dn); } } @@ -271,7 +267,7 @@ ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000); if (ret) { - pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret); + SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret); goto free_fdt1; } @@ -285,7 +281,7 @@ dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL); if (!dt) { ret = -EINVAL; - pci_warn(php_slot->pdev, "Cannot unflatten FDT\n"); + SLOT_WARN(php_slot, "Cannot unflatten FDT\n"); goto free_fdt; } @@ -295,15 +291,15 @@ ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn); if (ret) { pnv_php_reverse_nodes(php_slot->dn); - pci_warn(php_slot->pdev, "Error %d populating changeset\n", - ret); + SLOT_WARN(php_slot, "Error %d populating changeset\n", + ret); goto free_dt; } php_slot->dn->child = NULL; ret = of_changeset_apply(&php_slot->ocs); if (ret) { - pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret); + SLOT_WARN(php_slot, "Error %d applying changeset\n", ret); goto destroy_changeset; } @@ -342,18 +338,19 @@ ret = pnv_pci_set_power_state(php_slot->id, state, &msg); if (ret > 0) { if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle || - be64_to_cpu(msg.params[2]) != state || - be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) { - pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n", - be64_to_cpu(msg.params[1]), - be64_to_cpu(msg.params[2]), - be64_to_cpu(msg.params[3])); + be64_to_cpu(msg.params[2]) != state) { + SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n", + be64_to_cpu(msg.params[1]), + be64_to_cpu(msg.params[2]), + be64_to_cpu(msg.params[3])); return -ENOMSG; } + if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) { + ret = -ENODEV; + goto error; + } } else if (ret < 0) { - pci_warn(php_slot->pdev, "Error %d powering %s\n", - ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); - return ret; + goto error; } if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE) @@ -362,6 +359,11 @@ ret = pnv_php_add_devtree(php_slot); return ret; + +error: + SLOT_WARN(php_slot, "Error %d powering %s\n", + ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off"); + return ret; } EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state); @@ -378,8 +380,8 @@ */ ret = pnv_pci_get_power_state(php_slot->id, &power_state); if (ret) { - pci_warn(php_slot->pdev, "Error %d getting power status\n", - ret); + SLOT_WARN(php_slot, "Error %d getting power status\n", + ret); } else { *state = power_state; } @@ -402,7 +404,7 @@ *state = presence; ret = 0; } else { - pci_warn(php_slot->pdev, "Error %d getting presence\n", ret); + SLOT_WARN(php_slot, "Error %d getting presence\n", ret); } return ret; @@ -566,7 +568,13 @@ struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); int ret; - if (php_slot->state != PNV_PHP_STATE_POPULATED) + /* + * Allow to disable a slot already in the registered state to + * cover cases where the slot couldn't be enabled and never + * reached the populated state + */ + if (php_slot->state != PNV_PHP_STATE_POPULATED && + php_slot->state != PNV_PHP_STATE_REGISTERED) return 0; /* Remove all devices behind the slot */ @@ -675,7 +683,7 @@ ret = pci_hp_register(&php_slot->slot, php_slot->bus, php_slot->slot_no, php_slot->name); if (ret) { - pci_warn(php_slot->pdev, "Error %d registering slot\n", ret); + SLOT_WARN(php_slot, "Error %d registering slot\n", ret); return ret; } @@ -728,7 +736,7 @@ /* Enable MSIx */ ret = pci_enable_msix_exact(pdev, &entry, 1); if (ret) { - pci_warn(pdev, "Error %d enabling MSIx\n", ret); + SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret); return ret; } @@ -778,8 +786,9 @@ (sts & PCI_EXP_SLTSTA_PDC)) { ret = pnv_pci_get_presence_state(php_slot->id, &presence); if (ret) { - pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n", - php_slot->name, ret, sts); + SLOT_WARN(php_slot, + "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n", + php_slot->name, ret, sts); return IRQ_HANDLED; } @@ -809,8 +818,9 @@ */ event = kzalloc(sizeof(*event), GFP_ATOMIC); if (!event) { - pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n", - php_slot->name, sts); + SLOT_WARN(php_slot, + "PCI slot [%s] missed hotplug event 0x%04x\n", + php_slot->name, sts); return IRQ_HANDLED; } @@ -834,7 +844,7 @@ /* Allocate workqueue */ php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name); if (!php_slot->wq) { - pci_warn(pdev, "Cannot alloc workqueue\n"); + SLOT_WARN(php_slot, "Cannot alloc workqueue\n"); pnv_php_disable_irq(php_slot, true); return; } @@ -858,7 +868,7 @@ php_slot->name, php_slot); if (ret) { pnv_php_disable_irq(php_slot, true); - pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq); + SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq); return; } @@ -894,7 +904,7 @@ ret = pci_enable_device(pdev); if (ret) { - pci_warn(pdev, "Error %d enabling device\n", ret); + SLOT_WARN(php_slot, "Error %d enabling device\n", ret); return; } @@ -1009,6 +1019,8 @@ for_each_compatible_node(dn, NULL, "ibm,ioda3-phb") pnv_php_register(dn); + for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb") + pnv_php_register_one(dn); /* slot directly under the PHB */ return 0; } @@ -1021,6 +1033,9 @@ for_each_compatible_node(dn, NULL, "ibm,ioda3-phb") pnv_php_unregister(dn); + + for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb") + pnv_php_unregister_one(dn); /* slot directly under the PHB */ } module_init(pnv_php_init); --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/rpadlpar_sysfs.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/rpadlpar_sysfs.c @@ -34,12 +34,11 @@ if (nbytes >= MAX_DRC_NAME_LEN) return 0; - memcpy(drc_name, buf, nbytes); + strscpy(drc_name, buf, nbytes + 1); end = strchr(drc_name, '\n'); - if (!end) - end = &drc_name[nbytes]; - *end = '\0'; + if (end) + *end = '\0'; rc = dlpar_add_slot(drc_name); if (rc) @@ -65,12 +64,11 @@ if (nbytes >= MAX_DRC_NAME_LEN) return 0; - memcpy(drc_name, buf, nbytes); + strscpy(drc_name, buf, nbytes + 1); end = strchr(drc_name, '\n'); - if (!end) - end = &drc_name[nbytes]; - *end = '\0'; + if (end) + *end = '\0'; rc = dlpar_remove_slot(drc_name); if (rc) --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/rpaphp_core.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/rpaphp_core.c @@ -154,11 +154,11 @@ return speed; } -static int get_children_props(struct device_node *dn, const int **drc_indexes, - const int **drc_names, const int **drc_types, - const int **drc_power_domains) +static int get_children_props(struct device_node *dn, const __be32 **drc_indexes, + const __be32 **drc_names, const __be32 **drc_types, + const __be32 **drc_power_domains) { - const int *indexes, *names, *types, *domains; + const __be32 *indexes, *names, *types, *domains; indexes = of_get_property(dn, "ibm,drc-indexes", NULL); names = of_get_property(dn, "ibm,drc-names", NULL); @@ -194,8 +194,8 @@ char *drc_type, unsigned int my_index) { char *name_tmp, *type_tmp; - const int *indexes, *names; - const int *types, *domains; + const __be32 *indexes, *names; + const __be32 *types, *domains; int i, rc; rc = get_children_props(dn->parent, &indexes, &names, &types, &domains); @@ -208,7 +208,7 @@ /* Iterate through parent properties, looking for my-drc-index */ for (i = 0; i < be32_to_cpu(indexes[0]); i++) { - if ((unsigned int) indexes[i + 1] == my_index) + if (be32_to_cpu(indexes[i + 1]) == my_index) break; name_tmp += (strlen(name_tmp) + 1); @@ -239,6 +239,8 @@ value = of_prop_next_u32(info, NULL, &entries); if (!value) return -EINVAL; + else + value++; for (j = 0; j < entries; j++) { of_read_drc_info_cell(&info, &value, &drc); @@ -246,9 +248,10 @@ /* Should now know end of current entry */ /* Found it */ - if (my_index <= drc.last_drc_index) { + if (my_index >= drc.drc_index_start && my_index <= drc.last_drc_index) { + int index = my_index - drc.drc_index_start; sprintf(cell_drc_name, "%s%d", drc.drc_name_prefix, - my_index); + drc.drc_name_suffix_start + index); break; } } @@ -265,7 +268,7 @@ int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, char *drc_type) { - const unsigned int *my_index; + const __be32 *my_index; my_index = of_get_property(dn, "ibm,my-drc-index", NULL); if (!my_index) { @@ -273,12 +276,12 @@ return -EINVAL; } - if (firmware_has_feature(FW_FEATURE_DRC_INFO)) + if (of_find_property(dn->parent, "ibm,drc-info", NULL)) return rpaphp_check_drc_props_v2(dn, drc_name, drc_type, - *my_index); + be32_to_cpu(*my_index)); else return rpaphp_check_drc_props_v1(dn, drc_name, drc_type, - *my_index); + be32_to_cpu(*my_index)); } EXPORT_SYMBOL_GPL(rpaphp_check_drc_props); @@ -309,10 +312,11 @@ * for built-in pci slots (even when the built-in slots are * dlparable.) */ -static int is_php_dn(struct device_node *dn, const int **indexes, - const int **names, const int **types, const int **power_domains) +static int is_php_dn(struct device_node *dn, const __be32 **indexes, + const __be32 **names, const __be32 **types, + const __be32 **power_domains) { - const int *drc_types; + const __be32 *drc_types; int rc; rc = get_children_props(dn, indexes, names, &drc_types, power_domains); @@ -347,7 +351,7 @@ struct slot *slot; int retval = 0; int i; - const int *indexes, *names, *types, *power_domains; + const __be32 *indexes, *names, *types, *power_domains; char *name, *type; if (!dn->name || strcmp(dn->name, "pci")) --- linux-oracle-5.4.0.orig/drivers/pci/hotplug/s390_pci_hpc.c +++ linux-oracle-5.4.0/drivers/pci/hotplug/s390_pci_hpc.c @@ -19,7 +19,6 @@ #include #define SLOT_NAME_SIZE 10 -static LIST_HEAD(s390_hotplug_slot_list); static int zpci_fn_configured(enum zpci_state state) { @@ -27,104 +26,90 @@ state == ZPCI_FN_STATE_ONLINE; } -/* - * struct slot - slot information for each *physical* slot - */ -struct slot { - struct list_head slot_list; - struct hotplug_slot hotplug_slot; - struct zpci_dev *zdev; -}; - -static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot) -{ - return container_of(hotplug_slot, struct slot, hotplug_slot); -} - -static inline int slot_configure(struct slot *slot) +static inline int zdev_configure(struct zpci_dev *zdev) { - int ret = sclp_pci_configure(slot->zdev->fid); + int ret = sclp_pci_configure(zdev->fid); - zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret); + zpci_dbg(3, "conf fid:%x, rc:%d\n", zdev->fid, ret); if (!ret) - slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; + zdev->state = ZPCI_FN_STATE_CONFIGURED; return ret; } -static inline int slot_deconfigure(struct slot *slot) +static inline int zdev_deconfigure(struct zpci_dev *zdev) { - int ret = sclp_pci_deconfigure(slot->zdev->fid); + int ret = sclp_pci_deconfigure(zdev->fid); - zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret); + zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret); if (!ret) - slot->zdev->state = ZPCI_FN_STATE_STANDBY; + zdev->state = ZPCI_FN_STATE_STANDBY; return ret; } static int enable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = to_slot(hotplug_slot); + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, + hotplug_slot); + struct zpci_bus *zbus = zdev->zbus; int rc; - if (slot->zdev->state != ZPCI_FN_STATE_STANDBY) + if (zdev->state != ZPCI_FN_STATE_STANDBY) return -EIO; - rc = slot_configure(slot); + rc = zdev_configure(zdev); if (rc) return rc; - rc = zpci_enable_device(slot->zdev); + rc = zpci_enable_device(zdev); if (rc) goto out_deconfigure; - pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); + pci_scan_slot(zbus->bus, zdev->devfn); pci_lock_rescan_remove(); - pci_bus_add_devices(slot->zdev->bus); + pci_bus_add_devices(zbus->bus); pci_unlock_rescan_remove(); return rc; out_deconfigure: - slot_deconfigure(slot); + zdev_deconfigure(zdev); return rc; } static int disable_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot = to_slot(hotplug_slot); + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, + hotplug_slot); struct pci_dev *pdev; int rc; - if (!zpci_fn_configured(slot->zdev->state)) + if (!zpci_fn_configured(zdev->state)) return -EIO; - pdev = pci_get_slot(slot->zdev->bus, ZPCI_DEVFN); - if (pdev) { - pci_stop_and_remove_bus_device_locked(pdev); + pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); + if (pdev && pci_num_vf(pdev)) { pci_dev_put(pdev); + return -EBUSY; } + pci_dev_put(pdev); + + zpci_remove_device(zdev, false); - rc = zpci_disable_device(slot->zdev); + rc = zpci_disable_device(zdev); if (rc) return rc; - return slot_deconfigure(slot); + return zdev_deconfigure(zdev); } static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = to_slot(hotplug_slot); + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, + hotplug_slot); - switch (slot->zdev->state) { - case ZPCI_FN_STATE_STANDBY: - *value = 0; - break; - default: - *value = 1; - break; - } + *value = zpci_is_device_configured(zdev) ? 1 : 0; return 0; } @@ -145,44 +130,16 @@ int zpci_init_slot(struct zpci_dev *zdev) { char name[SLOT_NAME_SIZE]; - struct slot *slot; - int rc; + struct zpci_bus *zbus = zdev->zbus; - if (!zdev) - return 0; - - slot = kzalloc(sizeof(*slot), GFP_KERNEL); - if (!slot) - goto error; - - slot->zdev = zdev; - slot->hotplug_slot.ops = &s390_hotplug_slot_ops; + zdev->hotplug_slot.ops = &s390_hotplug_slot_ops; snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); - rc = pci_hp_register(&slot->hotplug_slot, zdev->bus, - ZPCI_DEVFN, name); - if (rc) - goto error_reg; - - list_add(&slot->slot_list, &s390_hotplug_slot_list); - return 0; - -error_reg: - kfree(slot); -error: - return -ENOMEM; + return pci_hp_register(&zdev->hotplug_slot, zbus->bus, + zdev->devfn, name); } void zpci_exit_slot(struct zpci_dev *zdev) { - struct slot *slot, *next; - - list_for_each_entry_safe(slot, next, &s390_hotplug_slot_list, - slot_list) { - if (slot->zdev != zdev) - continue; - list_del(&slot->slot_list); - pci_hp_deregister(&slot->hotplug_slot); - kfree(slot); - } + pci_hp_deregister(&zdev->hotplug_slot); } --- linux-oracle-5.4.0.orig/drivers/pci/iov.c +++ linux-oracle-5.4.0/drivers/pci/iov.c @@ -134,12 +134,35 @@ &physfn->sriov->subsystem_device); } +int pci_iov_sysfs_link(struct pci_dev *dev, + struct pci_dev *virtfn, int id) +{ + char buf[VIRTFN_ID_LEN]; + int rc; + + sprintf(buf, "virtfn%u", id); + rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); + if (rc) + goto failed; + rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn"); + if (rc) + goto failed1; + + kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); + + return 0; + +failed1: + sysfs_remove_link(&dev->dev.kobj, buf); +failed: + return rc; +} + int pci_iov_add_virtfn(struct pci_dev *dev, int id) { int i; int rc = -ENOMEM; u64 size; - char buf[VIRTFN_ID_LEN]; struct pci_dev *virtfn; struct resource *res; struct pci_sriov *iov = dev->sriov; @@ -158,6 +181,7 @@ virtfn->device = iov->vf_device; virtfn->is_virtfn = 1; virtfn->physfn = pci_dev_get(dev); + virtfn->no_command_memory = 1; if (id == 0) pci_read_vf_config_common(virtfn); @@ -183,26 +207,16 @@ } pci_device_add(virtfn, virtfn->bus); - - sprintf(buf, "virtfn%u", id); - rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); + rc = pci_iov_sysfs_link(dev, virtfn, id); if (rc) - goto failed2; - rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn"); - if (rc) - goto failed3; - - kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE); + goto failed1; pci_bus_add_device(virtfn); return 0; -failed3: - sysfs_remove_link(&dev->dev.kobj, buf); -failed2: - pci_stop_and_remove_bus_device(virtfn); failed1: + pci_stop_and_remove_bus_device(virtfn); pci_dev_put(dev); failed0: virtfn_remove_bus(dev->bus, bus); @@ -254,8 +268,14 @@ char *buf) { struct pci_dev *pdev = to_pci_dev(dev); + u16 num_vfs; + + /* Serialize vs sriov_numvfs_store() so readers see valid num_VFs */ + device_lock(&pdev->dev); + num_vfs = pdev->sriov->num_VFs; + device_unlock(&pdev->dev); - return sprintf(buf, "%u\n", pdev->sriov->num_VFs); + return sprintf(buf, "%u\n", num_vfs); } /* @@ -553,9 +573,6 @@ struct pci_sriov *iov = dev->sriov; int i; - if (dev->no_vf_scan) - return; - for (i = 0; i < iov->num_VFs; i++) pci_iov_remove_virtfn(dev, i); } --- linux-oracle-5.4.0.orig/drivers/pci/irq.c +++ linux-oracle-5.4.0/drivers/pci/irq.c @@ -94,6 +94,8 @@ va_start(ap, fmt); devname = kvasprintf(GFP_KERNEL, fmt, ap); va_end(ap); + if (!devname) + return -ENOMEM; ret = request_threaded_irq(pci_irq_vector(dev, nr), handler, thread_fn, irqflags, devname, dev_id); --- linux-oracle-5.4.0.orig/drivers/pci/msi.c +++ linux-oracle-5.4.0/drivers/pci/msi.c @@ -170,24 +170,25 @@ * reliably as devices without an INTx disable bit will then generate a * level IRQ which will never be cleared. */ -u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) +void __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) { - u32 mask_bits = desc->masked; + raw_spinlock_t *lock = &desc->dev->msi_lock; + unsigned long flags; if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit) - return 0; + return; - mask_bits &= ~mask; - mask_bits |= flag; + raw_spin_lock_irqsave(lock, flags); + desc->masked &= ~mask; + desc->masked |= flag; pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos, - mask_bits); - - return mask_bits; + desc->masked); + raw_spin_unlock_irqrestore(lock, flags); } static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) { - desc->masked = __pci_msi_desc_mask_irq(desc, mask, flag); + __pci_msi_desc_mask_irq(desc, mask, flag); } static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) @@ -213,12 +214,13 @@ if (pci_msi_ignore_mask) return 0; + desc_addr = pci_msix_desc_addr(desc); if (!desc_addr) return 0; mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; - if (flag) + if (flag & PCI_MSIX_ENTRY_CTRL_MASKBIT) mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; writel(mask_bits, desc_addr + PCI_MSIX_ENTRY_VECTOR_CTRL); @@ -315,13 +317,31 @@ /* Don't touch the hardware now */ } else if (entry->msi_attrib.is_msix) { void __iomem *base = pci_msix_desc_addr(entry); + bool unmasked = !(entry->masked & PCI_MSIX_ENTRY_CTRL_MASKBIT); if (!base) goto skip; + /* + * The specification mandates that the entry is masked + * when the message is modified: + * + * "If software changes the Address or Data value of an + * entry while the entry is unmasked, the result is + * undefined." + */ + if (unmasked) + __pci_msix_desc_mask_irq(entry, PCI_MSIX_ENTRY_CTRL_MASKBIT); + writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); writel(msg->data, base + PCI_MSIX_ENTRY_DATA); + + if (unmasked) + __pci_msix_desc_mask_irq(entry, 0); + + /* Ensure that the writes are visible in the device */ + readl(base + PCI_MSIX_ENTRY_DATA); } else { int pos = dev->msi_cap; u16 msgctl; @@ -342,6 +362,8 @@ pci_write_config_word(dev, pos + PCI_MSI_DATA_32, msg->data); } + /* Ensure that the writes are visible in the device */ + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); } skip: @@ -373,18 +395,6 @@ for (i = 0; i < entry->nvec_used; i++) BUG_ON(irq_has_action(entry->irq + i)); - pci_msi_teardown_msi_irqs(dev); - - list_for_each_entry_safe(entry, tmp, msi_list, list) { - if (entry->msi_attrib.is_msix) { - if (list_is_last(&entry->list, msi_list)) - iounmap(entry->mask_base); - } - - list_del(&entry->list); - free_msi_entry(entry); - } - if (dev->msi_irq_groups) { sysfs_remove_groups(&dev->dev.kobj, dev->msi_irq_groups); msi_attrs = dev->msi_irq_groups[0]->attrs; @@ -400,6 +410,18 @@ kfree(dev->msi_irq_groups); dev->msi_irq_groups = NULL; } + + pci_msi_teardown_msi_irqs(dev); + + list_for_each_entry_safe(entry, tmp, msi_list, list) { + if (entry->msi_attrib.is_msix) { + if (list_is_last(&entry->list, msi_list)) + iounmap(entry->mask_base); + } + + list_del(&entry->list); + free_msi_entry(entry); + } } static void pci_intx_for_msi(struct pci_dev *dev, int enable) @@ -569,6 +591,9 @@ goto out; pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); + /* Lies, damned lies, and MSIs */ + if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) + control |= PCI_MSI_FLAGS_MASKBIT; entry->msi_attrib.is_msix = 0; entry->msi_attrib.is_64 = !!(control & PCI_MSI_FLAGS_64BIT); @@ -641,21 +666,21 @@ /* Configure MSI capability structure */ ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } ret = msi_verify_entries(dev); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } ret = populate_msi_sysfs(dev); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } @@ -696,6 +721,7 @@ { struct irq_affinity_desc *curmsk, *masks = NULL; struct msi_desc *entry; + void __iomem *addr; int ret, i; int vec_count = pci_msix_vec_count(dev); @@ -716,6 +742,7 @@ entry->msi_attrib.is_msix = 1; entry->msi_attrib.is_64 = 1; + if (entries) entry->msi_attrib.entry_nr = entries[i].entry; else @@ -727,6 +754,10 @@ entry->msi_attrib.default_irq = dev->irq; entry->mask_base = base; + addr = pci_msix_desc_addr(entry); + if (addr) + entry->masked = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); if (masks) curmsk++; @@ -737,26 +768,28 @@ return ret; } -static void msix_program_entries(struct pci_dev *dev, - struct msix_entry *entries) +static void msix_update_entries(struct pci_dev *dev, struct msix_entry *entries) { struct msi_desc *entry; - int i = 0; - void __iomem *desc_addr; for_each_pci_msi_entry(entry, dev) { - if (entries) - entries[i++].vector = entry->irq; + if (entries) { + entries->vector = entry->irq; + entries++; + } + } +} - desc_addr = pci_msix_desc_addr(entry); - if (desc_addr) - entry->masked = readl(desc_addr + - PCI_MSIX_ENTRY_VECTOR_CTRL); - else - entry->masked = 0; +static void msix_mask_all(void __iomem *base, int tsize) +{ + u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT; + int i; - msix_mask_irq(entry, 1); - } + if (pci_msi_ignore_mask) + return; + + for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE) + writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL); } /** @@ -773,22 +806,33 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec, struct irq_affinity *affd) { - int ret; - u16 control; void __iomem *base; + int ret, tsize; + u16 control; - /* Ensure MSI-X is disabled while it is set up */ - pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); + /* + * Some devices require MSI-X to be enabled before the MSI-X + * registers can be accessed. Mask all the vectors to prevent + * interrupts coming in before they're fully set up. + */ + pci_msix_clear_and_set_ctrl(dev, 0, PCI_MSIX_FLAGS_MASKALL | + PCI_MSIX_FLAGS_ENABLE); pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); /* Request & Map MSI-X table region */ - base = msix_map_region(dev, msix_table_size(control)); - if (!base) - return -ENOMEM; + tsize = msix_table_size(control); + base = msix_map_region(dev, tsize); + if (!base) { + ret = -ENOMEM; + goto out_disable; + } + + /* Ensure that all table entries are masked. */ + msix_mask_all(base, tsize); ret = msix_setup_entries(dev, base, entries, nvec, affd); if (ret) - return ret; + goto out_disable; ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); if (ret) @@ -799,15 +843,7 @@ if (ret) goto out_free; - /* - * Some devices require MSI-X to be enabled before we can touch the - * MSI-X registers. We need to mask all the vectors to prevent - * interrupts coming in before they're fully set up. - */ - pci_msix_clear_and_set_ctrl(dev, 0, - PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE); - - msix_program_entries(dev, entries); + msix_update_entries(dev, entries); ret = populate_msi_sysfs(dev); if (ret) @@ -841,6 +877,9 @@ out_free: free_msi_irqs(dev); +out_disable: + pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE, 0); + return ret; } @@ -928,8 +967,7 @@ /* Return the device with MSI unmasked as initial states */ mask = msi_mask(desc->msi_attrib.multi_cap); - /* Keep cached state to be restored */ - __pci_msi_desc_mask_irq(desc, mask, ~mask); + msi_mask_irq(desc, mask, 0); /* Restore dev->irq to its default pin-assertion IRQ */ dev->irq = desc->msi_attrib.default_irq; @@ -1014,10 +1052,8 @@ } /* Return the device with MSI-X masked as initial states */ - for_each_pci_msi_entry(entry, dev) { - /* Keep cached states to be restored */ + for_each_pci_msi_entry(entry, dev) __pci_msix_desc_mask_irq(entry, 1); - } pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); pci_intx_for_msi(dev, 1); @@ -1251,19 +1287,24 @@ /** * pci_irq_vector - return Linux IRQ number of a device vector - * @dev: PCI device to operate on - * @nr: device-relative interrupt vector index (0-based). + * @dev: PCI device to operate on + * @nr: Interrupt vector index (0-based) + * + * @nr has the following meanings depending on the interrupt mode: + * MSI-X: The index in the MSI-X vector table + * MSI: The index of the enabled MSI vectors + * INTx: Must be 0 + * + * Return: The Linux interrupt number or -EINVAl if @nr is out of range. */ int pci_irq_vector(struct pci_dev *dev, unsigned int nr) { if (dev->msix_enabled) { struct msi_desc *entry; - int i = 0; for_each_pci_msi_entry(entry, dev) { - if (i == nr) + if (entry->msi_attrib.entry_nr == nr) return entry->irq; - i++; } WARN_ON_ONCE(1); return -EINVAL; @@ -1287,17 +1328,22 @@ * pci_irq_get_affinity - return the affinity of a particular MSI vector * @dev: PCI device to operate on * @nr: device-relative interrupt vector index (0-based). + * + * @nr has the following meanings depending on the interrupt mode: + * MSI-X: The index in the MSI-X vector table + * MSI: The index of the enabled MSI vectors + * INTx: Must be 0 + * + * Return: A cpumask pointer or NULL if @nr is out of range */ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr) { if (dev->msix_enabled) { struct msi_desc *entry; - int i = 0; for_each_pci_msi_entry(entry, dev) { - if (i == nr) + if (entry->msi_attrib.entry_nr == nr) return &entry->affinity->mask; - i++; } WARN_ON_ONCE(1); return NULL; @@ -1375,7 +1421,7 @@ { return (irq_hw_number_t)desc->msi_attrib.entry_nr | pci_dev_id(dev) << 11 | - (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; + ((irq_hw_number_t)(pci_domain_nr(dev->bus) & 0xFFFFFFFF)) << 27; } static inline bool pci_msi_desc_is_multi_msi(struct msi_desc *desc) @@ -1550,8 +1596,8 @@ pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); of_node = irq_domain_get_of_node(domain); - rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) : - iort_msi_map_rid(&pdev->dev, rid); + rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) : + iort_msi_map_id(&pdev->dev, rid); return rid; } @@ -1571,9 +1617,10 @@ u32 rid = pci_dev_id(pdev); pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); - dom = of_msi_map_get_device_domain(&pdev->dev, rid); + dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI); if (!dom) - dom = iort_get_device_domain(&pdev->dev, rid); + dom = iort_get_device_domain(&pdev->dev, rid, + DOMAIN_BUS_PCI_MSI); return dom; } #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */ --- linux-oracle-5.4.0.orig/drivers/pci/p2pdma.c +++ linux-oracle-5.4.0/drivers/pci/p2pdma.c @@ -292,10 +292,41 @@ {} }; +/* + * This lookup function tries to find the PCI device corresponding to a given + * host bridge. + * + * It assumes the host bridge device is the first PCI device in the + * bus->devices list and that the devfn is 00.0. These assumptions should hold + * for all the devices in the whitelist above. + * + * This function is equivalent to pci_get_slot(host->bus, 0), however it does + * not take the pci_bus_sem lock seeing __host_bridge_whitelist() must not + * sleep. + * + * For this to be safe, the caller should hold a reference to a device on the + * bridge, which should ensure the host_bridge device will not be freed + * or removed from the head of the devices list. + */ +static struct pci_dev *pci_host_bridge_dev(struct pci_host_bridge *host) +{ + struct pci_dev *root; + + root = list_first_entry_or_null(&host->bus->devices, + struct pci_dev, bus_list); + + if (!root) + return NULL; + if (root->devfn != PCI_DEVFN(0, 0)) + return NULL; + + return root; +} + static bool __host_bridge_whitelist(struct pci_host_bridge *host, bool same_host_bridge) { - struct pci_dev *root = pci_get_slot(host->bus, PCI_DEVFN(0, 0)); + struct pci_dev *root = pci_host_bridge_dev(host); const struct pci_p2pdma_whitelist_entry *entry; unsigned short vendor, device; @@ -304,7 +335,6 @@ vendor = root->vendor; device = root->device; - pci_dev_put(root); for (entry = pci_p2pdma_whitelist; entry->vendor; entry++) { if (vendor != entry->vendor || device != entry->device) --- linux-oracle-5.4.0.orig/drivers/pci/pci-acpi.c +++ linux-oracle-5.4.0/drivers/pci/pci-acpi.c @@ -909,7 +909,7 @@ { int acpi_state, d_max; - if (pdev->no_d3cold) + if (pdev->no_d3cold || !pdev->d3cold_allowed) d_max = ACPI_STATE_D3_HOT; else d_max = ACPI_STATE_D3_COLD; @@ -944,6 +944,16 @@ if (!dev->is_hotplug_bridge) return false; + /* Assume D3 support if the bridge is power-manageable by ACPI. */ + adev = ACPI_COMPANION(&dev->dev); + if (!adev && !pci_dev_is_added(dev)) { + adev = acpi_pci_find_companion(&dev->dev); + ACPI_COMPANION_SET(&dev->dev, adev); + } + + if (adev && acpi_device_power_manageable(adev)) + return true; + /* * Look for a special _DSD property for the root port and if it * is set we know the hierarchy behind it supports D3 just fine. @@ -1050,7 +1060,7 @@ { while (bus->parent) { if (acpi_pm_device_can_wakeup(&bus->self->dev)) - return acpi_pm_set_bridge_wakeup(&bus->self->dev, enable); + return acpi_pm_set_device_wakeup(&bus->self->dev, enable); bus = bus->parent; } @@ -1058,7 +1068,7 @@ /* We have reached the root bus. */ if (bus->bridge) { if (acpi_pm_device_can_wakeup(bus->bridge)) - return acpi_pm_set_bridge_wakeup(bus->bridge, enable); + return acpi_pm_set_device_wakeup(bus->bridge, enable); } return 0; } --- linux-oracle-5.4.0.orig/drivers/pci/pci-bridge-emul.c +++ linux-oracle-5.4.0/drivers/pci/pci-bridge-emul.c @@ -21,8 +21,9 @@ #include "pci-bridge-emul.h" #define PCI_BRIDGE_CONF_END PCI_STD_HEADER_SIZEOF +#define PCI_CAP_PCIE_SIZEOF (PCI_EXP_SLTSTA2 + 2) #define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END -#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2) +#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF) struct pci_bridge_reg_behavior { /* Read-only bits */ @@ -38,7 +39,8 @@ u32 rsvd; }; -static const struct pci_bridge_reg_behavior pci_regs_behavior[] = { +static const +struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = { [PCI_VENDOR_ID / 4] = { .ro = ~0 }, [PCI_COMMAND / 4] = { .rw = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -173,7 +175,8 @@ }, }; -static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { +static const +struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] = { [PCI_CAP_LIST_ID / 4] = { /* * Capability ID, Next Capability Pointer and @@ -195,8 +198,8 @@ * RO, the rest is reserved */ .w1c = GENMASK(19, 16), - .ro = GENMASK(20, 19), - .rsvd = GENMASK(31, 21), + .ro = GENMASK(21, 20), + .rsvd = GENMASK(31, 22), }, [PCI_EXP_LNKCAP / 4] = { @@ -236,7 +239,7 @@ PCI_EXP_SLTSTA_CC | PCI_EXP_SLTSTA_DLLSC) << 16, .ro = (PCI_EXP_SLTSTA_MRLSS | PCI_EXP_SLTSTA_PDS | PCI_EXP_SLTSTA_EIS) << 16, - .rsvd = GENMASK(15, 12) | (GENMASK(15, 9) << 16), + .rsvd = GENMASK(15, 13) | (GENMASK(15, 9) << 16), }, [PCI_EXP_RTCTL / 4] = { @@ -270,10 +273,12 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge, unsigned int flags) { - bridge->conf.class_revision |= PCI_CLASS_BRIDGE_PCI << 16; + BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END); + + bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16); bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; bridge->conf.cache_line_size = 0x10; - bridge->conf.status = PCI_STATUS_CAP_LIST; + bridge->conf.status = cpu_to_le16(PCI_STATUS_CAP_LIST); bridge->pci_regs_behavior = kmemdup(pci_regs_behavior, sizeof(pci_regs_behavior), GFP_KERNEL); @@ -282,10 +287,9 @@ if (bridge->has_pcie) { bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; + bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST); bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; - /* Set PCIe v2, root port, slot support */ - bridge->pcie_conf.cap = PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | - PCI_EXP_FLAGS_SLOT; + bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4); bridge->pcie_cap_regs_behavior = kmemdup(pcie_cap_regs_behavior, sizeof(pcie_cap_regs_behavior), @@ -294,6 +298,27 @@ kfree(bridge->pci_regs_behavior); return -ENOMEM; } + /* These bits are applicable only for PCI and reserved on PCIe */ + bridge->pci_regs_behavior[PCI_CACHE_LINE_SIZE / 4].ro &= + ~GENMASK(15, 8); + bridge->pci_regs_behavior[PCI_COMMAND / 4].ro &= + ~((PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | + PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_WAIT | + PCI_COMMAND_FAST_BACK) | + (PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK | + PCI_STATUS_DEVSEL_MASK) << 16); + bridge->pci_regs_behavior[PCI_PRIMARY_BUS / 4].ro &= + ~GENMASK(31, 24); + bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro &= + ~((PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK | + PCI_STATUS_DEVSEL_MASK) << 16); + bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].rw &= + ~((PCI_BRIDGE_CTL_MASTER_ABORT | + BIT(8) | BIT(9) | BIT(11)) << 16); + bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].ro &= + ~((PCI_BRIDGE_CTL_FAST_BACK) << 16); + bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].w1c &= + ~(BIT(10) << 16); } if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) { @@ -327,7 +352,7 @@ int reg = where & ~3; pci_bridge_emul_read_status_t (*read_op)(struct pci_bridge_emul *bridge, int reg, u32 *value); - u32 *cfgspace; + __le32 *cfgspace; const struct pci_bridge_reg_behavior *behavior; if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END) { @@ -343,11 +368,11 @@ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) { reg -= PCI_CAP_PCIE_START; read_op = bridge->ops->read_pcie; - cfgspace = (u32 *) &bridge->pcie_conf; + cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; } else { read_op = bridge->ops->read_base; - cfgspace = (u32 *) &bridge->conf; + cfgspace = (__le32 *) &bridge->conf; behavior = bridge->pci_regs_behavior; } @@ -357,7 +382,7 @@ ret = PCI_BRIDGE_EMUL_NOT_HANDLED; if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED) - *value = cfgspace[reg / 4]; + *value = le32_to_cpu(cfgspace[reg / 4]); /* * Make sure we never return any reserved bit with a value @@ -387,7 +412,7 @@ int mask, ret, old, new, shift; void (*write_op)(struct pci_bridge_emul *bridge, int reg, u32 old, u32 new, u32 mask); - u32 *cfgspace; + __le32 *cfgspace; const struct pci_bridge_reg_behavior *behavior; if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END) @@ -414,11 +439,11 @@ if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) { reg -= PCI_CAP_PCIE_START; write_op = bridge->ops->write_pcie; - cfgspace = (u32 *) &bridge->pcie_conf; + cfgspace = (__le32 *) &bridge->pcie_conf; behavior = bridge->pcie_cap_regs_behavior; } else { write_op = bridge->ops->write_base; - cfgspace = (u32 *) &bridge->conf; + cfgspace = (__le32 *) &bridge->conf; behavior = bridge->pci_regs_behavior; } @@ -431,7 +456,20 @@ /* Clear the W1C bits */ new &= ~((value << shift) & (behavior[reg / 4].w1c & mask)); - cfgspace[reg / 4] = new; + /* Save the new value with the cleared W1C bits into the cfgspace */ + cfgspace[reg / 4] = cpu_to_le32(new); + + /* + * Clear the W1C bits not specified by the write mask, so that the + * write_op() does not clear them. + */ + new &= ~(behavior[reg / 4].w1c & ~mask); + + /* + * Set the W1C bits specified by the write mask, so that write_op() + * knows about that they are to be cleared. + */ + new |= (value << shift) & (behavior[reg / 4].w1c & mask); if (write_op) write_op(bridge, reg, old, new, mask); --- linux-oracle-5.4.0.orig/drivers/pci/pci-bridge-emul.h +++ linux-oracle-5.4.0/drivers/pci/pci-bridge-emul.h @@ -6,65 +6,65 @@ /* PCI configuration space of a PCI-to-PCI bridge. */ struct pci_bridge_emul_conf { - u16 vendor; - u16 device; - u16 command; - u16 status; - u32 class_revision; + __le16 vendor; + __le16 device; + __le16 command; + __le16 status; + __le32 class_revision; u8 cache_line_size; u8 latency_timer; u8 header_type; u8 bist; - u32 bar[2]; + __le32 bar[2]; u8 primary_bus; u8 secondary_bus; u8 subordinate_bus; u8 secondary_latency_timer; u8 iobase; u8 iolimit; - u16 secondary_status; - u16 membase; - u16 memlimit; - u16 pref_mem_base; - u16 pref_mem_limit; - u32 prefbaseupper; - u32 preflimitupper; - u16 iobaseupper; - u16 iolimitupper; + __le16 secondary_status; + __le16 membase; + __le16 memlimit; + __le16 pref_mem_base; + __le16 pref_mem_limit; + __le32 prefbaseupper; + __le32 preflimitupper; + __le16 iobaseupper; + __le16 iolimitupper; u8 capabilities_pointer; u8 reserve[3]; - u32 romaddr; + __le32 romaddr; u8 intline; u8 intpin; - u16 bridgectrl; + __le16 bridgectrl; }; /* PCI configuration space of the PCIe capabilities */ struct pci_bridge_emul_pcie_conf { u8 cap_id; u8 next; - u16 cap; - u32 devcap; - u16 devctl; - u16 devsta; - u32 lnkcap; - u16 lnkctl; - u16 lnksta; - u32 slotcap; - u16 slotctl; - u16 slotsta; - u16 rootctl; - u16 rsvd; - u32 rootsta; - u32 devcap2; - u16 devctl2; - u16 devsta2; - u32 lnkcap2; - u16 lnkctl2; - u16 lnksta2; - u32 slotcap2; - u16 slotctl2; - u16 slotsta2; + __le16 cap; + __le32 devcap; + __le16 devctl; + __le16 devsta; + __le32 lnkcap; + __le16 lnkctl; + __le16 lnksta; + __le32 slotcap; + __le16 slotctl; + __le16 slotsta; + __le16 rootctl; + __le16 rootcap; + __le32 rootsta; + __le32 devcap2; + __le16 devctl2; + __le16 devsta2; + __le32 lnkcap2; + __le16 lnkctl2; + __le16 lnksta2; + __le32 slotcap2; + __le16 slotctl2; + __le16 slotsta2; }; struct pci_bridge_emul; --- linux-oracle-5.4.0.orig/drivers/pci/pci-driver.c +++ linux-oracle-5.4.0/drivers/pci/pci-driver.c @@ -439,16 +439,21 @@ struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = pci_dev->driver; - if (drv) { - if (drv->remove) { - pm_runtime_get_sync(dev); - drv->remove(pci_dev); - pm_runtime_put_noidle(dev); - } - pcibios_free_irq(pci_dev); - pci_dev->driver = NULL; - pci_iov_remove(pci_dev); - } + if (drv->remove) { + pm_runtime_get_sync(dev); + /* + * If the driver provides a .runtime_idle() callback and it has + * started to run already, it may continue to run in parallel + * with the code below, so wait until all of the runtime PM + * activity has completed. + */ + pm_runtime_barrier(dev); + drv->remove(pci_dev); + pm_runtime_put_noidle(dev); + } + pcibios_free_irq(pci_dev); + pci_dev->driver = NULL; + pci_iov_remove(pci_dev); /* Undo the runtime PM settings in local_pci_probe() */ pm_runtime_put_sync(dev); @@ -919,6 +924,8 @@ struct pci_dev *pci_dev = to_pci_dev(dev); struct device_driver *drv = dev->driver; int error = 0; + pci_power_t prev_state = pci_dev->current_state; + bool skip_bus_pm = pci_dev->skip_bus_pm; if (dev_pm_may_skip_resume(dev)) return 0; @@ -937,16 +944,18 @@ * configuration here and attempting to put them into D0 again is * pointless, so avoid doing that. */ - if (!(pci_dev->skip_bus_pm && pm_suspend_no_platform())) + if (!(skip_bus_pm && pm_suspend_no_platform())) pci_pm_default_resume_early(pci_dev); pci_fixup_device(pci_fixup_resume_early, pci_dev); + pcie_pme_root_status_cleanup(pci_dev); + + if (!skip_bus_pm && prev_state == PCI_D3cold) + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_resume_early(dev); - pcie_pme_root_status_cleanup(pci_dev); - if (drv && drv->pm && drv->pm->resume_noirq) error = drv->pm->resume_noirq(dev); @@ -1076,17 +1085,22 @@ return error; } - if (pci_has_legacy_pm_support(pci_dev)) - return pci_legacy_resume_early(dev); - /* - * pci_restore_state() requires the device to be in D0 (because of MSI - * restoration among other things), so force it into D0 in case the - * driver's "freeze" callbacks put it into a low-power state directly. + * Both the legacy ->resume_early() and the new pm->thaw_noirq() + * callbacks assume the device has been returned to D0 and its + * config state has been restored. + * + * In addition, pci_restore_state() restores MSI-X state in MMIO + * space, which requires the device to be in D0, so return it to D0 + * in case the driver's "freeze" callbacks put it into a low-power + * state. */ pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev); + if (pci_has_legacy_pm_support(pci_dev)) + return pci_legacy_resume_early(dev); + if (drv && drv->pm && drv->pm->thaw_noirq) error = drv->pm->thaw_noirq(dev); @@ -1329,6 +1343,7 @@ int rc = 0; struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + pci_power_t prev_state = pci_dev->current_state; /* * Restoring config space is necessary even if the device is not bound @@ -1344,6 +1359,9 @@ pci_enable_wake(pci_dev, PCI_D0, false); pci_fixup_device(pci_fixup_resume, pci_dev); + if (prev_state == PCI_D3cold) + pci_bridge_wait_for_secondary_bus(pci_dev, "resume", PCI_RESET_WAIT); + if (pm && pm->runtime_resume) rc = pm->runtime_resume(dev); --- linux-oracle-5.4.0.orig/drivers/pci/pci-label.c +++ linux-oracle-5.4.0/drivers/pci/pci-label.c @@ -162,7 +162,7 @@ len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer, obj->buffer.length, UTF16_LITTLE_ENDIAN, - buf, PAGE_SIZE); + buf, PAGE_SIZE - 1); buf[len] = '\n'; } --- linux-oracle-5.4.0.orig/drivers/pci/pci-sysfs.c +++ linux-oracle-5.4.0/drivers/pci/pci-sysfs.c @@ -156,7 +156,8 @@ { struct pci_dev *pdev = to_pci_dev(dev); - return sprintf(buf, "%s\n", PCIE_SPEED2STR(pcie_get_speed_cap(pdev))); + return sprintf(buf, "%s\n", + pci_speed_string(pcie_get_speed_cap(pdev))); } static DEVICE_ATTR_RO(max_link_speed); @@ -175,33 +176,15 @@ struct pci_dev *pci_dev = to_pci_dev(dev); u16 linkstat; int err; - const char *speed; + enum pci_bus_speed speed; err = pcie_capability_read_word(pci_dev, PCI_EXP_LNKSTA, &linkstat); if (err) return -EINVAL; - switch (linkstat & PCI_EXP_LNKSTA_CLS) { - case PCI_EXP_LNKSTA_CLS_32_0GB: - speed = "32 GT/s"; - break; - case PCI_EXP_LNKSTA_CLS_16_0GB: - speed = "16 GT/s"; - break; - case PCI_EXP_LNKSTA_CLS_8_0GB: - speed = "8 GT/s"; - break; - case PCI_EXP_LNKSTA_CLS_5_0GB: - speed = "5 GT/s"; - break; - case PCI_EXP_LNKSTA_CLS_2_5GB: - speed = "2.5 GT/s"; - break; - default: - speed = "Unknown speed"; - } + speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS]; - return sprintf(buf, "%s\n", speed); + return sprintf(buf, "%s\n", pci_speed_string(speed)); } static DEVICE_ATTR_RO(current_link_speed); @@ -464,7 +447,8 @@ } return count; } -static DEVICE_ATTR_WO(dev_rescan); +static struct device_attribute dev_attr_dev_rescan = __ATTR(rescan, 0200, NULL, + dev_rescan_store); static ssize_t remove_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -501,7 +485,33 @@ } return count; } -static DEVICE_ATTR_WO(bus_rescan); +static struct device_attribute dev_attr_bus_rescan = __ATTR(rescan, 0200, NULL, + bus_rescan_store); + +static ssize_t reset_subordinate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct pci_bus *bus = pdev->subordinate; + unsigned long val; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (kstrtoul(buf, 0, &val) < 0) + return -EINVAL; + + if (val) { + int ret = __pci_reset_bus(bus); + + if (ret) + return ret; + } + + return count; +} +static DEVICE_ATTR_WO(reset_subordinate); #if defined(CONFIG_PM) && defined(CONFIG_ACPI) static ssize_t d3cold_allowed_store(struct device *dev, @@ -515,10 +525,7 @@ return -EINVAL; pdev->d3cold_allowed = !!val; - if (pdev->d3cold_allowed) - pci_d3cold_enable(pdev); - else - pci_d3cold_disable(pdev); + pci_bridge_d3_update(pdev); pm_runtime_resume(dev); @@ -629,6 +636,7 @@ static struct attribute *pci_bridge_attrs[] = { &dev_attr_subordinate_bus_number.attr, &dev_attr_secondary_bus_number.attr, + &dev_attr_reset_subordinate.attr, NULL, }; @@ -1155,11 +1163,9 @@ sysfs_bin_attr_init(res_attr); if (write_combine) { - pdev->res_attr_wc[num] = res_attr; sprintf(res_attr_name, "resource%d_wc", num); res_attr->mmap = pci_mmap_resource_wc; } else { - pdev->res_attr[num] = res_attr; sprintf(res_attr_name, "resource%d", num); if (pci_resource_flags(pdev, num) & IORESOURCE_IO) { res_attr->read = pci_read_resource_io; @@ -1175,10 +1181,17 @@ res_attr->size = pci_resource_len(pdev, num); res_attr->private = (void *)(unsigned long)num; retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr); - if (retval) + if (retval) { kfree(res_attr); + return retval; + } - return retval; + if (write_combine) + pdev->res_attr_wc[num] = res_attr; + else + pdev->res_attr[num] = res_attr; + + return 0; } /** @@ -1330,7 +1343,6 @@ int retval; pcie_vpd_create_sysfs_dev_files(dev); - pcie_aspm_create_sysfs_dev_files(dev); if (dev->reset_fn) { retval = device_create_file(&dev->dev, &dev_attr_reset); @@ -1340,7 +1352,6 @@ return 0; error: - pcie_aspm_remove_sysfs_dev_files(dev); pcie_vpd_remove_sysfs_dev_files(dev); return retval; } @@ -1416,7 +1427,6 @@ static void pci_remove_capabilities_sysfs(struct pci_dev *dev) { pcie_vpd_remove_sysfs_dev_files(dev); - pcie_aspm_remove_sysfs_dev_files(dev); if (dev->reset_fn) { device_remove_file(&dev->dev, &dev_attr_reset); dev->reset_fn = 0; @@ -1588,6 +1598,9 @@ #ifdef CONFIG_PCIEAER &aer_stats_attr_group, #endif +#ifdef CONFIG_PCIEASPM + &aspm_ctrl_attr_group, +#endif NULL, }; --- linux-oracle-5.4.0.orig/drivers/pci/pci.c +++ linux-oracle-5.4.0/drivers/pci/pci.c @@ -224,7 +224,7 @@ *endptr = strchrnul(path, ';'); - wpath = kmemdup_nul(path, *endptr - path, GFP_KERNEL); + wpath = kmemdup_nul(path, *endptr - path, GFP_ATOMIC); if (!wpath) return -ENOMEM; @@ -802,7 +802,9 @@ static inline bool platform_pci_bridge_d3(struct pci_dev *dev) { - return pci_platform_pm ? pci_platform_pm->bridge_d3(dev) : false; + if (pci_platform_pm && pci_platform_pm->bridge_d3) + return pci_platform_pm->bridge_d3(dev); + return false; } /** @@ -1019,8 +1021,6 @@ * because have already delayed for the bridge. */ if (dev->runtime_d3cold) { - if (dev->d3cold_delay && !dev->imm_ready) - msleep(dev->d3cold_delay); /* * When powering on a bridge from D3cold, the * whole hierarchy may be powered on into @@ -1672,11 +1672,7 @@ * so that things like MSI message writing will behave as expected * (e.g. if the device really is in D0 at enable time). */ - if (dev->pm_cap) { - u16 pmcsr; - pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); - dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); - } + pci_update_current_state(dev, dev->current_state); if (atomic_inc_return(&dev->enable_cnt) > 1) return 0; /* already enabled */ @@ -2253,7 +2249,14 @@ if (enable) { int error; - if (pci_pme_capable(dev, state)) + /* + * Enable PME signaling if the device can signal PME from + * D3cold regardless of whether or not it can signal PME from + * the current target state, because that will allow it to + * signal PME when the hierarchy above it goes into D3cold and + * the device itself ends up in D3cold as a result of that. + */ + if (pci_pme_capable(dev, state) || pci_pme_capable(dev, PCI_D3cold)) pci_pme_active(dev, true); else ret = 1; @@ -2357,16 +2360,20 @@ if (dev->current_state == PCI_D3cold) target_state = PCI_D3cold; - if (wakeup) { + if (wakeup && dev->pme_support) { + pci_power_t state = target_state; + /* * Find the deepest state from which the device can generate * PME#. */ - if (dev->pme_support) { - while (target_state - && !(dev->pme_support & (1 << target_state))) - target_state--; - } + while (state && !(dev->pme_support & (1 << state))) + state--; + + if (state) + return state; + else if (dev->pme_support & 1) + return PCI_D0; } return target_state; @@ -2607,6 +2614,30 @@ DMI_MATCH(DMI_BOARD_NAME, "X299 DESIGNARE EX-CF"), }, }, + { + /* + * Downstream device is not accessible after putting a root port + * into D3cold and back into D0 on Elo Continental Z2 board + */ + .ident = "Elo Continental Z2", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Elo Touch Solutions"), + DMI_MATCH(DMI_BOARD_NAME, "Geminilake"), + DMI_MATCH(DMI_BOARD_VERSION, "Continental Z2"), + }, + }, + { + /* + * Changing power state of root port dGPU is connected fails + * https://gitlab.freedesktop.org/drm/amd/-/issues/3229 + */ + .ident = "Hewlett-Packard HP Pavilion 17 Notebook PC/1972", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_BOARD_NAME, "1972"), + DMI_MATCH(DMI_BOARD_VERSION, "95.33"), + }, + }, #endif { } }; @@ -3471,7 +3502,14 @@ return 0; pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); - return (cap & PCI_REBAR_CAP_SIZES) >> 4; + cap &= PCI_REBAR_CAP_SIZES; + + /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ + if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && + bar == 0 && cap == 0x7000) + cap = 0x3f000; + + return cap >> 4; } /** @@ -3896,6 +3934,10 @@ ret = logic_pio_register_range(range); if (ret) kfree(range); + + /* Ignore duplicates due to deferred probing */ + if (ret == -EEXIST) + ret = 0; #endif return ret; @@ -4453,7 +4495,7 @@ return -ENOTTY; } - if (delay > 1000) + if (delay > PCI_RESET_WAIT) pci_info(dev, "not ready %dms after %s; waiting\n", delay - 1, reset_type); @@ -4462,7 +4504,7 @@ pci_read_config_dword(dev, PCI_COMMAND, &id); } - if (delay > 1000) + if (delay > PCI_RESET_WAIT) pci_info(dev, "ready %dms after %s\n", delay - 1, reset_type); @@ -4605,14 +4647,17 @@ return pci_dev_wait(dev, "PM D3->D0", PCIE_RESET_READY_POLL_MS); } + /** - * pcie_wait_for_link - Wait until link is active or inactive + * pcie_wait_for_link_delay - Wait until link is active or inactive * @pdev: Bridge device * @active: waiting for active or inactive? + * @delay: Delay to wait after link has become active (in ms) * * Use this to wait till link becomes active or inactive. */ -bool pcie_wait_for_link(struct pci_dev *pdev, bool active) +static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active, + int delay) { int timeout = 1000; bool ret; @@ -4620,10 +4665,10 @@ /* * Some controllers might not implement link active reporting. In this - * case, we wait for 1000 + 100 ms. + * case, we wait for 1000 ms + any delay requested by the caller. */ if (!pdev->link_active_reporting) { - msleep(1100); + msleep(timeout + delay); return true; } @@ -4649,13 +4694,146 @@ timeout -= 10; } if (active && ret) - msleep(100); + msleep(delay); else if (ret != active) pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", active ? "set" : "cleared"); return ret == active; } +/** + * pcie_wait_for_link - Wait until link is active or inactive + * @pdev: Bridge device + * @active: waiting for active or inactive? + * + * Use this to wait till link becomes active or inactive. + */ +bool pcie_wait_for_link(struct pci_dev *pdev, bool active) +{ + return pcie_wait_for_link_delay(pdev, active, 100); +} + +/* + * Find maximum D3cold delay required by all the devices on the bus. The + * spec says 100 ms, but firmware can lower it and we allow drivers to + * increase it as well. + * + * Called with @pci_bus_sem locked for reading. + */ +static int pci_bus_max_d3cold_delay(const struct pci_bus *bus) +{ + const struct pci_dev *pdev; + int min_delay = 100; + int max_delay = 0; + + list_for_each_entry(pdev, &bus->devices, bus_list) { + if (pdev->d3cold_delay < min_delay) + min_delay = pdev->d3cold_delay; + if (pdev->d3cold_delay > max_delay) + max_delay = pdev->d3cold_delay; + } + + return max(min_delay, max_delay); +} + +/** + * pci_bridge_wait_for_secondary_bus - Wait for secondary bus to be accessible + * @dev: PCI bridge + * @reset_type: reset type in human-readable form + * @timeout: maximum time to wait for devices on secondary bus (milliseconds) + * + * Handle necessary delays before access to the devices on the secondary + * side of the bridge are permitted after D3cold to D0 transition + * or Conventional Reset. + * + * For PCIe this means the delays in PCIe 5.0 section 6.6.1. For + * conventional PCI it means Tpvrh + Trhfa specified in PCI 3.0 section + * 4.3.2. + * + * Return 0 on success or -ENOTTY if the first device on the secondary bus + * failed to become accessible. + */ +int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, + int timeout) +{ + struct pci_dev *child; + int delay; + + if (pci_dev_is_disconnected(dev)) + return 0; + + if (!pci_is_bridge(dev)) + return 0; + + down_read(&pci_bus_sem); + + /* + * We only deal with devices that are present currently on the bus. + * For any hot-added devices the access delay is handled in pciehp + * board_added(). In case of ACPI hotplug the firmware is expected + * to configure the devices before OS is notified. + */ + if (!dev->subordinate || list_empty(&dev->subordinate->devices)) { + up_read(&pci_bus_sem); + return 0; + } + + /* Take d3cold_delay requirements into account */ + delay = pci_bus_max_d3cold_delay(dev->subordinate); + if (!delay) { + up_read(&pci_bus_sem); + return 0; + } + + child = list_first_entry(&dev->subordinate->devices, struct pci_dev, + bus_list); + up_read(&pci_bus_sem); + + /* + * Conventional PCI and PCI-X we need to wait Tpvrh + Trhfa before + * accessing the device after reset (that is 1000 ms + 100 ms). + */ + if (!pci_is_pcie(dev)) { + pci_dbg(dev, "waiting %d ms for secondary bus\n", 1000 + delay); + msleep(1000 + delay); + return 0; + } + + /* + * For PCIe downstream and root ports that do not support speeds + * greater than 5 GT/s need to wait minimum 100 ms. For higher + * speeds (gen3) we need to wait first for the data link layer to + * become active. + * + * However, 100 ms is the minimum and the PCIe spec says the + * software must allow at least 1s before it can determine that the + * device that did not respond is a broken device. There is + * evidence that 100 ms is not always enough, for example certain + * Titan Ridge xHCI controller does not always respond to + * configuration requests if we only wait for 100 ms (see + * https://bugzilla.kernel.org/show_bug.cgi?id=203885). + * + * Therefore we wait for 100 ms and check for the device presence + * until the timeout expires. + */ + if (!pcie_downstream_port(dev)) + return 0; + + if (pcie_get_speed_cap(dev) <= PCIE_SPEED_5_0GT) { + pci_dbg(dev, "waiting %d ms for downstream link\n", delay); + msleep(delay); + } else { + pci_dbg(dev, "waiting %d ms for downstream link, after activation\n", + delay); + if (!pcie_wait_for_link_delay(dev, true, delay)) { + /* Did not train, no need to wait any further */ + return -ENOTTY; + } + } + + return pci_dev_wait(child, reset_type, timeout - delay); +} + void pci_reset_secondary_bus(struct pci_dev *dev) { u16 ctrl; @@ -4672,15 +4850,6 @@ ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET; pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl); - - /* - * Trhfa for conventional PCI is 2^25 clock cycles. - * Assuming a minimum 33MHz clock this results in a 1s - * delay before we can consider subordinate devices to - * be re-initialized. PCIe has some ways to shorten this, - * but we don't make use of them yet. - */ - ssleep(1); } void __weak pcibios_reset_secondary_bus(struct pci_dev *dev) @@ -4699,7 +4868,8 @@ { pcibios_reset_secondary_bus(dev); - return pci_dev_wait(dev, "bus reset", PCIE_RESET_READY_POLL_MS); + return pci_bridge_wait_for_secondary_bus(dev, "bus reset", + PCIE_RESET_READY_POLL_MS); } EXPORT_SYMBOL_GPL(pci_bridge_secondary_bus_reset); @@ -4753,18 +4923,18 @@ static void pci_dev_lock(struct pci_dev *dev) { - pci_cfg_access_lock(dev); /* block PM suspend, driver probe, etc. */ device_lock(&dev->dev); + pci_cfg_access_lock(dev); } /* Return 1 on successful lock, 0 on contention */ static int pci_dev_trylock(struct pci_dev *dev) { - if (pci_cfg_access_trylock(dev)) { - if (device_trylock(&dev->dev)) + if (device_trylock(&dev->dev)) { + if (pci_cfg_access_trylock(dev)) return 1; - pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); } return 0; @@ -4772,8 +4942,8 @@ static void pci_dev_unlock(struct pci_dev *dev) { - device_unlock(&dev->dev); pci_cfg_access_unlock(dev); + device_unlock(&dev->dev); } static void pci_dev_save_and_disable(struct pci_dev *dev) @@ -5030,10 +5200,12 @@ { struct pci_dev *dev; + pci_dev_lock(bus->self); list_for_each_entry(dev, &bus->devices, bus_list) { - pci_dev_lock(dev); if (dev->subordinate) pci_bus_lock(dev->subordinate); + else + pci_dev_lock(dev); } } @@ -5045,8 +5217,10 @@ list_for_each_entry(dev, &bus->devices, bus_list) { if (dev->subordinate) pci_bus_unlock(dev->subordinate); - pci_dev_unlock(dev); + else + pci_dev_unlock(dev); } + pci_dev_unlock(bus->self); } /* Return 1 on successful lock, 0 on contention */ @@ -5054,15 +5228,15 @@ { struct pci_dev *dev; + if (!pci_dev_trylock(bus->self)) + return 0; + list_for_each_entry(dev, &bus->devices, bus_list) { - if (!pci_dev_trylock(dev)) - goto unlock; if (dev->subordinate) { - if (!pci_bus_trylock(dev->subordinate)) { - pci_dev_unlock(dev); + if (!pci_bus_trylock(dev->subordinate)) goto unlock; - } - } + } else if (!pci_dev_trylock(dev)) + goto unlock; } return 1; @@ -5070,8 +5244,10 @@ list_for_each_entry_continue_reverse(dev, &bus->devices, bus_list) { if (dev->subordinate) pci_bus_unlock(dev->subordinate); - pci_dev_unlock(dev); + else + pci_dev_unlock(dev); } + pci_dev_unlock(bus->self); return 0; } @@ -5103,9 +5279,10 @@ list_for_each_entry(dev, &slot->bus->devices, bus_list) { if (!dev->slot || dev->slot != slot) continue; - pci_dev_lock(dev); if (dev->subordinate) pci_bus_lock(dev->subordinate); + else + pci_dev_lock(dev); } } @@ -5131,14 +5308,13 @@ list_for_each_entry(dev, &slot->bus->devices, bus_list) { if (!dev->slot || dev->slot != slot) continue; - if (!pci_dev_trylock(dev)) - goto unlock; if (dev->subordinate) { if (!pci_bus_trylock(dev->subordinate)) { pci_dev_unlock(dev); goto unlock; } - } + } else if (!pci_dev_trylock(dev)) + goto unlock; } return 1; @@ -5149,7 +5325,8 @@ continue; if (dev->subordinate) pci_bus_unlock(dev->subordinate); - pci_dev_unlock(dev); + else + pci_dev_unlock(dev); } return 0; } @@ -5361,7 +5538,7 @@ * * Same as above except return -EAGAIN if the bus cannot be locked */ -static int __pci_reset_bus(struct pci_bus *bus) +int __pci_reset_bus(struct pci_bus *bus) { int rc; @@ -5657,19 +5834,10 @@ * where only 2.5 GT/s and 5.0 GT/s speeds were defined. */ pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); - if (lnkcap2) { /* PCIe r3.0-compliant */ - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_32_0GB) - return PCIE_SPEED_32_0GT; - else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_16_0GB) - return PCIE_SPEED_16_0GT; - else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) - return PCIE_SPEED_8_0GT; - else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB) - return PCIE_SPEED_5_0GT; - else if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB) - return PCIE_SPEED_2_5GT; - return PCI_SPEED_UNKNOWN; - } + + /* PCIe r3.0-compliant */ + if (lnkcap2) + return PCIE_LNKCAP2_SLS2SPEED(lnkcap2); pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB) @@ -5745,14 +5913,14 @@ if (bw_avail >= bw_cap && verbose) pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth (%s x%d link)\n", bw_cap / 1000, bw_cap % 1000, - PCIE_SPEED2STR(speed_cap), width_cap); + pci_speed_string(speed_cap), width_cap); else if (bw_avail < bw_cap) pci_info(dev, "%u.%03u Gb/s available PCIe bandwidth, limited by %s x%d link at %s (capable of %u.%03u Gb/s with %s x%d link)\n", bw_avail / 1000, bw_avail % 1000, - PCIE_SPEED2STR(speed), width, + pci_speed_string(speed), width, limiting_dev ? pci_name(limiting_dev) : "", bw_cap / 1000, bw_cap % 1000, - PCIE_SPEED2STR(speed_cap), width_cap); + pci_speed_string(speed_cap), width_cap); } /** @@ -5854,10 +6022,29 @@ return 0; } +#ifdef CONFIG_ACPI +bool pci_pr3_present(struct pci_dev *pdev) +{ + struct acpi_device *adev; + + if (acpi_disabled) + return false; + + adev = ACPI_COMPANION(&pdev->dev); + if (!adev) + return false; + + return adev->power.flags.power_resources && + acpi_has_method(adev->handle, "_PR3"); +} +EXPORT_SYMBOL_GPL(pci_pr3_present); +#endif + /** * pci_add_dma_alias - Add a DMA devfn alias for a device * @dev: the PCI device for which alias is added - * @devfn: alias slot and function + * @devfn_from: alias slot and function + * @nr_devfns: number of subsequent devfns to alias * * This helper encodes an 8-bit devfn as a bit number in dma_alias_mask * which is used to program permissible bus-devfn source addresses for DMA @@ -5873,18 +6060,29 @@ * cannot be left as a userspace activity). DMA aliases should therefore * be configured via quirks, such as the PCI fixup header quirk. */ -void pci_add_dma_alias(struct pci_dev *dev, u8 devfn) +void pci_add_dma_alias(struct pci_dev *dev, u8 devfn_from, unsigned nr_devfns) { + int devfn_to; + + nr_devfns = min(nr_devfns, (unsigned) MAX_NR_DEVFNS - devfn_from); + devfn_to = devfn_from + nr_devfns - 1; + if (!dev->dma_alias_mask) - dev->dma_alias_mask = bitmap_zalloc(U8_MAX, GFP_KERNEL); + dev->dma_alias_mask = bitmap_zalloc(MAX_NR_DEVFNS, GFP_KERNEL); if (!dev->dma_alias_mask) { pci_warn(dev, "Unable to allocate DMA alias mask\n"); return; } - set_bit(devfn, dev->dma_alias_mask); - pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n", - PCI_SLOT(devfn), PCI_FUNC(devfn)); + bitmap_set(dev->dma_alias_mask, devfn_from, nr_devfns); + + if (nr_devfns == 1) + pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n", + PCI_SLOT(devfn_from), PCI_FUNC(devfn_from)); + else if (nr_devfns > 1) + pci_info(dev, "Enabling fixed DMA alias for devfn range from %02x.%d to %02x.%d\n", + PCI_SLOT(devfn_from), PCI_FUNC(devfn_from), + PCI_SLOT(devfn_to), PCI_FUNC(devfn_to)); } bool pci_devs_are_dma_aliases(struct pci_dev *dev1, struct pci_dev *dev2) @@ -5899,6 +6097,8 @@ { u32 v; + /* Check PF if pdev is a VF, since VF Vendor/Device IDs are 0xffff */ + pdev = pci_physfn(pdev); if (pci_dev_is_disconnected(pdev)) return false; return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0); @@ -5965,19 +6165,21 @@ while (*p) { count = 0; if (sscanf(p, "%d%n", &align_order, &count) == 1 && - p[count] == '@') { + p[count] == '@') { p += count + 1; + if (align_order > 63) { + pr_err("PCI: Invalid requested alignment (order %d)\n", + align_order); + align_order = PAGE_SHIFT; + } } else { - align_order = -1; + align_order = PAGE_SHIFT; } ret = pci_dev_str_match(dev, p, &p); if (ret == 1) { *resize = true; - if (align_order == -1) - align = PAGE_SIZE; - else - align = 1 << align_order; + align = 1ULL << align_order; break; } else if (ret < 0) { pr_err("PCI: Can't parse resource_alignment parameter: %s\n", --- linux-oracle-5.4.0.orig/drivers/pci/pci.h +++ linux-oracle-5.4.0/drivers/pci/pci.h @@ -4,6 +4,9 @@ #include +/* Number of possible devfns: 0.0 to 1f.7 inclusive */ +#define MAX_NR_DEVFNS 256 + #define PCI_FIND_CAP_TTL 48 #define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */ @@ -38,12 +41,20 @@ int pci_probe_reset_function(struct pci_dev *dev); int pci_bridge_secondary_bus_reset(struct pci_dev *dev); int pci_bus_error_reset(struct pci_dev *dev); +int __pci_reset_bus(struct pci_bus *bus); #define PCI_PM_D2_DELAY 200 #define PCI_PM_D3_WAIT 10 #define PCI_PM_D3COLD_WAIT 100 #define PCI_PM_BUS_WAIT 50 +/* + * Following exit from Conventional Reset, devices must be ready within 1 sec + * (PCIe r6.0 sec 6.6.1). A D3cold to D0 transition implies a Conventional + * Reset (PCIe r6.0 sec 5.8). + */ +#define PCI_RESET_WAIT 1000 /* msec */ + /** * struct pci_platform_pm_ops - Firmware PM callbacks * @@ -104,6 +115,8 @@ void pci_free_cap_save_buffers(struct pci_dev *dev); bool pci_bridge_d3_possible(struct pci_dev *dev); void pci_bridge_d3_update(struct pci_dev *dev); +int pci_bridge_wait_for_secondary_bus(struct pci_dev *dev, char *reset_type, + int timeout); static inline void pci_wakeup_event(struct pci_dev *dev) { @@ -286,22 +299,25 @@ struct pci_bus *pci_bus_get(struct pci_bus *bus); void pci_bus_put(struct pci_bus *bus); -/* PCIe link information */ -#define PCIE_SPEED2STR(speed) \ - ((speed) == PCIE_SPEED_16_0GT ? "16 GT/s" : \ - (speed) == PCIE_SPEED_8_0GT ? "8 GT/s" : \ - (speed) == PCIE_SPEED_5_0GT ? "5 GT/s" : \ - (speed) == PCIE_SPEED_2_5GT ? "2.5 GT/s" : \ - "Unknown speed") +/* PCIe link information from Link Capabilities 2 */ +#define PCIE_LNKCAP2_SLS2SPEED(lnkcap2) \ + ((lnkcap2) & PCI_EXP_LNKCAP2_SLS_32_0GB ? PCIE_SPEED_32_0GT : \ + (lnkcap2) & PCI_EXP_LNKCAP2_SLS_16_0GB ? PCIE_SPEED_16_0GT : \ + (lnkcap2) & PCI_EXP_LNKCAP2_SLS_8_0GB ? PCIE_SPEED_8_0GT : \ + (lnkcap2) & PCI_EXP_LNKCAP2_SLS_5_0GB ? PCIE_SPEED_5_0GT : \ + (lnkcap2) & PCI_EXP_LNKCAP2_SLS_2_5GB ? PCIE_SPEED_2_5GT : \ + PCI_SPEED_UNKNOWN) /* PCIe speed to Mb/s reduced by encoding overhead */ #define PCIE_SPEED2MBS_ENC(speed) \ - ((speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \ + ((speed) == PCIE_SPEED_32_0GT ? 32000*128/130 : \ + (speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \ (speed) == PCIE_SPEED_8_0GT ? 8000*128/130 : \ (speed) == PCIE_SPEED_5_0GT ? 5000*8/10 : \ (speed) == PCIE_SPEED_2_5GT ? 2500*8/10 : \ 0) +const char *pci_speed_string(enum pci_bus_speed speed); enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); u32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed, @@ -342,62 +358,40 @@ * @dev - pci device to set new error_state * @new - the state we want dev to be in * - * Must be called with device_lock held. + * If the device is experiencing perm_failure, it has to remain in that state. + * Any other transition is allowed. * * Returns true if state has been changed to the requested state. */ static inline bool pci_dev_set_io_state(struct pci_dev *dev, pci_channel_state_t new) { - bool changed = false; + pci_channel_state_t old; - device_lock_assert(&dev->dev); switch (new) { case pci_channel_io_perm_failure: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - case pci_channel_io_perm_failure: - changed = true; - break; - } - break; + xchg(&dev->error_state, pci_channel_io_perm_failure); + return true; case pci_channel_io_frozen: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - changed = true; - break; - } - break; + old = cmpxchg(&dev->error_state, pci_channel_io_normal, + pci_channel_io_frozen); + return old != pci_channel_io_perm_failure; case pci_channel_io_normal: - switch (dev->error_state) { - case pci_channel_io_frozen: - case pci_channel_io_normal: - changed = true; - break; - } - break; + old = cmpxchg(&dev->error_state, pci_channel_io_frozen, + pci_channel_io_normal); + return old != pci_channel_io_perm_failure; + default: + return false; } - if (changed) - dev->error_state = new; - return changed; } static inline int pci_dev_set_disconnected(struct pci_dev *dev, void *unused) { - device_lock(&dev->dev); pci_dev_set_io_state(dev, pci_channel_io_perm_failure); - device_unlock(&dev->dev); return 0; } -static inline bool pci_dev_is_disconnected(const struct pci_dev *dev) -{ - return dev->error_state == pci_channel_io_perm_failure; -} - /* pci_dev priv_flags */ #define PCI_DEV_ADDED 0 @@ -541,14 +535,6 @@ static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { } #endif -#ifdef CONFIG_PCIEASPM_DEBUG -void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev); -void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev); -#else -static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { } -static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { } -#endif - #ifdef CONFIG_PCIE_ECRC void pcie_set_ecrc_checking(struct pci_dev *dev); void pcie_ecrc_get_policy(char *str); @@ -584,6 +570,12 @@ #if defined(CONFIG_PCI_QUIRKS) && defined(CONFIG_ARM64) int acpi_get_rc_resources(struct device *dev, const char *hid, u16 segment, struct resource *res); +#else +static inline int acpi_get_rc_resources(struct device *dev, const char *hid, + u16 segment, struct resource *res) +{ + return -ENODEV; +} #endif u32 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar); @@ -667,4 +659,8 @@ } #endif +#ifdef CONFIG_PCIEASPM +extern const struct attribute_group aspm_ctrl_attr_group; +#endif + #endif /* DRIVERS_PCI_H */ --- linux-oracle-5.4.0.orig/drivers/pci/pcie/Kconfig +++ linux-oracle-5.4.0/drivers/pci/pcie/Kconfig @@ -79,13 +79,6 @@ When in doubt, say Y. -config PCIEASPM_DEBUG - bool "Debug PCI Express ASPM" - depends on PCIEASPM - help - This enables PCI Express ASPM debug support. It will add per-device - interface to control ASPM. - choice prompt "Default ASPM policy" default PCIEASPM_DEFAULT --- linux-oracle-5.4.0.orig/drivers/pci/pcie/aer.c +++ linux-oracle-5.4.0/drivers/pci/pcie/aer.c @@ -782,7 +782,7 @@ u8 bus = info->id >> 8; u8 devfn = info->id & 0xff; - pci_info(dev, "%s%s error received: %04x:%02x:%02x.%d\n", + pci_info(dev, "%s%s error message received from %04x:%02x:%02x.%d\n", info->multi_error_valid ? "Multiple " : "", aer_error_severity_string[info->severity], pci_domain_nr(dev->bus), bus, PCI_SLOT(devfn), @@ -968,7 +968,12 @@ pci_walk_bus(parent->subordinate, find_device_iter, e_info); if (!e_info->error_dev_num) { - pci_info(parent, "can't find device of ID%04x\n", e_info->id); + u8 bus = e_info->id >> 8; + u8 devfn = e_info->id & 0xff; + + pci_info(parent, "found no error details for %04x:%02x:%02x.%d\n", + pci_domain_nr(parent->bus), bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)); return false; } return true; @@ -1212,7 +1217,7 @@ { struct pcie_device *dev = (struct pcie_device *)context; struct aer_rpc *rpc = get_service_data(dev); - struct aer_err_source uninitialized_var(e_src); + struct aer_err_source e_src; if (kfifo_is_empty(&rpc->aer_fifo)) return IRQ_NONE; @@ -1387,6 +1392,7 @@ return -ENOMEM; rpc->rpd = port; + INIT_KFIFO(rpc->aer_fifo); set_service_data(dev, rpc); status = devm_request_threaded_irq(device, dev->irq, aer_irq, aer_isr, @@ -1401,6 +1407,22 @@ return 0; } +static int aer_suspend(struct pcie_device *dev) +{ + struct aer_rpc *rpc = get_service_data(dev); + + aer_disable_rootport(rpc); + return 0; +} + +static int aer_resume(struct pcie_device *dev) +{ + struct aer_rpc *rpc = get_service_data(dev); + + aer_enable_rootport(rpc); + return 0; +} + /** * aer_root_reset - reset link on Root Port * @dev: pointer to Root Port's pci_dev data structure @@ -1441,6 +1463,8 @@ .service = PCIE_PORT_SERVICE_AER, .probe = aer_probe, + .suspend = aer_suspend, + .resume = aer_resume, .remove = aer_remove, .reset_link = aer_root_reset, }; --- linux-oracle-5.4.0.orig/drivers/pci/pcie/aspm.c +++ linux-oracle-5.4.0/drivers/pci/pcie/aspm.c @@ -64,6 +64,7 @@ u32 clkpm_capable:1; /* Clock PM capable? */ u32 clkpm_enabled:1; /* Current Clock PM state */ u32 clkpm_default:1; /* Default Clock PM state by BIOS */ + u32 clkpm_disable:1; /* Clock PM disabled */ /* Exit latencies */ struct aspm_latency latency_up; /* Upstream direction exit latency */ @@ -161,8 +162,11 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) { - /* Don't enable Clock PM if the link is not Clock PM capable */ - if (!link->clkpm_capable) + /* + * Don't enable Clock PM if the link is not Clock PM capable + * or Clock PM is disabled + */ + if (!link->clkpm_capable || link->clkpm_disable) enable = 0; /* Need nothing if the specified equals to current state */ if (link->clkpm_enabled == enable) @@ -192,15 +196,43 @@ } link->clkpm_enabled = enabled; link->clkpm_default = enabled; - link->clkpm_capable = (blacklist) ? 0 : capable; + link->clkpm_capable = capable; + link->clkpm_disable = blacklist ? 1 : 0; } -static bool pcie_retrain_link(struct pcie_link_state *link) +static int pcie_wait_for_retrain(struct pci_dev *pdev) { - struct pci_dev *parent = link->pdev; unsigned long end_jiffies; u16 reg16; + /* Wait for Link Training to be cleared by hardware */ + end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; + do { + pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, ®16); + if (!(reg16 & PCI_EXP_LNKSTA_LT)) + return 0; + msleep(1); + } while (time_before(jiffies, end_jiffies)); + + return -ETIMEDOUT; +} + +static int pcie_retrain_link(struct pcie_link_state *link) +{ + struct pci_dev *parent = link->pdev; + int rc; + u16 reg16; + + /* + * Ensure the updated LNKCTL parameters are used during link + * training by checking that there is no ongoing link training to + * avoid LTSSM race as recommended in Implementation Note at the + * end of PCIe r6.0.1 sec 7.5.3.7. + */ + rc = pcie_wait_for_retrain(parent); + if (rc) + return rc; + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); reg16 |= PCI_EXP_LNKCTL_RL; pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); @@ -214,15 +246,7 @@ pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); } - /* Wait for link training end. Break out after waiting for timeout */ - end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT; - do { - pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); - if (!(reg16 & PCI_EXP_LNKSTA_LT)) - break; - msleep(1); - } while (time_before(jiffies, end_jiffies)); - return !(reg16 & PCI_EXP_LNKSTA_LT); + return pcie_wait_for_retrain(parent); } /* @@ -233,7 +257,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) { int same_clock = 1; - u16 reg16, parent_reg, child_reg[8]; + u16 reg16, ccc, parent_old_ccc, child_old_ccc[8]; struct pci_dev *child, *parent = link->pdev; struct pci_bus *linkbus = parent->subordinate; /* @@ -255,6 +279,7 @@ /* Port might be already in common clock mode */ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC; if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) { bool consistent = true; @@ -271,35 +296,30 @@ pci_warn(parent, "ASPM: current common clock configuration is broken, reconfiguring\n"); } + ccc = same_clock ? PCI_EXP_LNKCTL_CCC : 0; /* Configure downstream component, all functions */ list_for_each_entry(child, &linkbus->devices, bus_list) { pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); - child_reg[PCI_FUNC(child->devfn)] = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); + child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC; + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, ccc); } /* Configure upstream component */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); - parent_reg = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, ccc); - if (pcie_retrain_link(link)) - return; + if (pcie_retrain_link(link)) { - /* Training failed. Restore common clock configurations */ - pci_err(parent, "ASPM: Could not configure common clock\n"); - list_for_each_entry(child, &linkbus->devices, bus_list) - pcie_capability_write_word(child, PCI_EXP_LNKCTL, - child_reg[PCI_FUNC(child->devfn)]); - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); + /* Training failed. Restore common clock configurations */ + pci_err(parent, "ASPM: Could not configure common clock\n"); + list_for_each_entry(child, &linkbus->devices, bus_list) + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, + child_old_ccc[PCI_FUNC(child->devfn)]); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, parent_old_ccc); + } } /* Convert L0s latency encoding to ns */ @@ -623,16 +643,6 @@ /* Setup initial capable state. Will be updated later */ link->aspm_capable = link->aspm_support; - /* - * If the downstream component has pci bridge function, don't - * do ASPM for now. - */ - list_for_each_entry(child, &linkbus->devices, bus_list) { - if (pci_pcie_type(child) == PCI_EXP_TYPE_PCI_BRIDGE) { - link->aspm_disable = ASPM_STATE_ALL; - break; - } - } /* Get and check endpoint acceptable latencies */ list_for_each_entry(child, &linkbus->devices, bus_list) { @@ -742,9 +752,9 @@ /* Enable what we need to enable */ pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1, - PCI_L1SS_CAP_L1_PM_SS, val); + PCI_L1SS_CTL1_L1SS_MASK, val); pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1, - PCI_L1SS_CAP_L1_PM_SS, val); + PCI_L1SS_CTL1_L1SS_MASK, val); } static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) @@ -894,6 +904,14 @@ return link; } +static void pcie_aspm_update_sysfs_visibility(struct pci_dev *pdev) +{ + struct pci_dev *child; + + list_for_each_entry(child, &pdev->subordinate->devices, bus_list) + sysfs_update_group(&child->dev.kobj, &aspm_ctrl_attr_group); +} + /* * pcie_aspm_init_link_state: Initiate PCI express link state. * It is called after the pcie and its children devices are scanned. @@ -955,6 +973,8 @@ pcie_set_clkpm(link, policy_to_clkpm_state(link)); } + pcie_aspm_update_sysfs_visibility(pdev); + unlock: mutex_unlock(&aspm_lock); out: @@ -996,21 +1016,24 @@ down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - /* - * All PCIe functions are in one slot, remove one function will remove - * the whole slot, so just wait until we are the last function left. - */ - if (!list_empty(&parent->subordinate->devices)) - goto out; link = parent->link_state; root = link->root; parent_link = link->parent; - /* All functions are removed, so just disable ASPM for the link */ + /* + * link->downstream is a pointer to the pci_dev of function 0. If + * we remove that function, the pci_dev is about to be deallocated, + * so we can't use link->downstream again. Free the link state to + * avoid this. + * + * If we're removing a non-0 function, it's possible we could + * retain the link state, but PCIe r6.0, sec 7.5.3.7, recommends + * programming the same ASPM Control value for all functions of + * multi-function devices, so disable ASPM for all of them. + */ pcie_config_aspm_link(link, 0); list_del(&link->sibling); - /* Clock PM is for endpoint device */ free_link_state(link); /* Recheck latencies and configure upstream links */ @@ -1018,7 +1041,7 @@ pcie_update_aspm_capable(root); pcie_config_aspm_path(parent_link); } -out: + mutex_unlock(&aspm_lock); up_read(&pci_bus_sem); } @@ -1061,19 +1084,26 @@ up_read(&pci_bus_sem); } -static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) +static struct pcie_link_state *pcie_aspm_get_link(struct pci_dev *pdev) { - struct pci_dev *parent = pdev->bus->self; - struct pcie_link_state *link; + struct pci_dev *bridge; if (!pci_is_pcie(pdev)) - return 0; + return NULL; - if (pcie_downstream_port(pdev)) - parent = pdev; - if (!parent || !parent->link_state) - return -EINVAL; + bridge = pci_upstream_bridge(pdev); + if (!bridge || !pci_is_pcie(bridge)) + return NULL; + + return bridge->link_state; +} + +static int __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem) +{ + struct pcie_link_state *link = pcie_aspm_get_link(pdev); + if (!link) + return -EINVAL; /* * A driver requested that ASPM be disabled on this device, but * if we don't have permission to manage ASPM (e.g., on ACPI @@ -1090,17 +1120,24 @@ if (sem) down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - link = parent->link_state; if (state & PCIE_LINK_STATE_L0S) link->aspm_disable |= ASPM_STATE_L0S; if (state & PCIE_LINK_STATE_L1) - link->aspm_disable |= ASPM_STATE_L1; + /* L1 PM substates require L1 */ + link->aspm_disable |= ASPM_STATE_L1 | ASPM_STATE_L1SS; + if (state & PCIE_LINK_STATE_L1_1) + link->aspm_disable |= ASPM_STATE_L1_1; + if (state & PCIE_LINK_STATE_L1_2) + link->aspm_disable |= ASPM_STATE_L1_2; + if (state & PCIE_LINK_STATE_L1_1_PCIPM) + link->aspm_disable |= ASPM_STATE_L1_1_PCIPM; + if (state & PCIE_LINK_STATE_L1_2_PCIPM) + link->aspm_disable |= ASPM_STATE_L1_2_PCIPM; pcie_config_aspm_link(link, policy_to_aspm_state(link)); - if (state & PCIE_LINK_STATE_CLKPM) { - link->clkpm_capable = 0; - pcie_set_clkpm(link, 0); - } + if (state & PCIE_LINK_STATE_CLKPM) + link->clkpm_disable = 1; + pcie_set_clkpm(link, policy_to_clkpm_state(link)); mutex_unlock(&aspm_lock); if (sem) up_read(&pci_bus_sem); @@ -1163,6 +1200,7 @@ cnt += sprintf(buffer + cnt, "[%s] ", policy_str[i]); else cnt += sprintf(buffer + cnt, "%s ", policy_str[i]); + cnt += sprintf(buffer + cnt, "\n"); return cnt; } @@ -1172,127 +1210,161 @@ /** * pcie_aspm_enabled - Check if PCIe ASPM has been enabled for a device. * @pdev: Target device. + * + * Relies on the upstream bridge's link_state being valid. The link_state + * is deallocated only when the last child of the bridge (i.e., @pdev or a + * sibling) is removed, and the caller should be holding a reference to + * @pdev, so this should be safe. */ bool pcie_aspm_enabled(struct pci_dev *pdev) { - struct pci_dev *bridge = pci_upstream_bridge(pdev); - bool ret; + struct pcie_link_state *link = pcie_aspm_get_link(pdev); - if (!bridge) + if (!link) return false; - mutex_lock(&aspm_lock); - ret = bridge->link_state ? !!bridge->link_state->aspm_enabled : false; - mutex_unlock(&aspm_lock); - - return ret; + return link->aspm_enabled; } EXPORT_SYMBOL_GPL(pcie_aspm_enabled); -#ifdef CONFIG_PCIEASPM_DEBUG -static ssize_t link_state_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t aspm_attr_show_common(struct device *dev, + struct device_attribute *attr, + char *buf, u8 state) { - struct pci_dev *pci_device = to_pci_dev(dev); - struct pcie_link_state *link_state = pci_device->link_state; + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link = pcie_aspm_get_link(pdev); - return sprintf(buf, "%d\n", link_state->aspm_enabled); + return sprintf(buf, "%d\n", (link->aspm_enabled & state) ? 1 : 0); } -static ssize_t link_state_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t n) +static ssize_t aspm_attr_store_common(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len, u8 state) { struct pci_dev *pdev = to_pci_dev(dev); - struct pcie_link_state *link, *root = pdev->link_state->root; - u32 state; - - if (aspm_disabled) - return -EPERM; + struct pcie_link_state *link = pcie_aspm_get_link(pdev); + bool state_enable; - if (kstrtouint(buf, 10, &state)) - return -EINVAL; - if ((state & ~ASPM_STATE_ALL) != 0) + if (strtobool(buf, &state_enable) < 0) return -EINVAL; down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - list_for_each_entry(link, &link_list, sibling) { - if (link->root != root) - continue; - pcie_config_aspm_link(link, state); + + if (state_enable) { + link->aspm_disable &= ~state; + /* need to enable L1 for substates */ + if (state & ASPM_STATE_L1SS) + link->aspm_disable &= ~ASPM_STATE_L1; + } else { + link->aspm_disable |= state; } + + pcie_config_aspm_link(link, policy_to_aspm_state(link)); + mutex_unlock(&aspm_lock); up_read(&pci_bus_sem); - return n; + + return len; } -static ssize_t clk_ctl_show(struct device *dev, - struct device_attribute *attr, - char *buf) +#define ASPM_ATTR(_f, _s) \ +static ssize_t _f##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ return aspm_attr_show_common(dev, attr, buf, ASPM_STATE_##_s); } \ + \ +static ssize_t _f##_store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t len) \ +{ return aspm_attr_store_common(dev, attr, buf, len, ASPM_STATE_##_s); } + +ASPM_ATTR(l0s_aspm, L0S) +ASPM_ATTR(l1_aspm, L1) +ASPM_ATTR(l1_1_aspm, L1_1) +ASPM_ATTR(l1_2_aspm, L1_2) +ASPM_ATTR(l1_1_pcipm, L1_1_PCIPM) +ASPM_ATTR(l1_2_pcipm, L1_2_PCIPM) + +static ssize_t clkpm_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct pci_dev *pci_device = to_pci_dev(dev); - struct pcie_link_state *link_state = pci_device->link_state; + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link = pcie_aspm_get_link(pdev); - return sprintf(buf, "%d\n", link_state->clkpm_enabled); + return sprintf(buf, "%d\n", link->clkpm_enabled); } -static ssize_t clk_ctl_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t n) +static ssize_t clkpm_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) { struct pci_dev *pdev = to_pci_dev(dev); - bool state; + struct pcie_link_state *link = pcie_aspm_get_link(pdev); + bool state_enable; - if (strtobool(buf, &state)) + if (strtobool(buf, &state_enable) < 0) return -EINVAL; down_read(&pci_bus_sem); mutex_lock(&aspm_lock); - pcie_set_clkpm_nocheck(pdev->link_state, state); + + link->clkpm_disable = !state_enable; + pcie_set_clkpm(link, policy_to_clkpm_state(link)); + mutex_unlock(&aspm_lock); up_read(&pci_bus_sem); - return n; + return len; } -static DEVICE_ATTR_RW(link_state); -static DEVICE_ATTR_RW(clk_ctl); +static DEVICE_ATTR_RW(clkpm); +static DEVICE_ATTR_RW(l0s_aspm); +static DEVICE_ATTR_RW(l1_aspm); +static DEVICE_ATTR_RW(l1_1_aspm); +static DEVICE_ATTR_RW(l1_2_aspm); +static DEVICE_ATTR_RW(l1_1_pcipm); +static DEVICE_ATTR_RW(l1_2_pcipm); + +static struct attribute *aspm_ctrl_attrs[] = { + &dev_attr_clkpm.attr, + &dev_attr_l0s_aspm.attr, + &dev_attr_l1_aspm.attr, + &dev_attr_l1_1_aspm.attr, + &dev_attr_l1_2_aspm.attr, + &dev_attr_l1_1_pcipm.attr, + &dev_attr_l1_2_pcipm.attr, + NULL +}; -static char power_group[] = "power"; -void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) +static umode_t aspm_ctrl_attrs_are_visible(struct kobject *kobj, + struct attribute *a, int n) { - struct pcie_link_state *link_state = pdev->link_state; - - if (!link_state) - return; - - if (link_state->aspm_support) - sysfs_add_file_to_group(&pdev->dev.kobj, - &dev_attr_link_state.attr, power_group); - if (link_state->clkpm_capable) - sysfs_add_file_to_group(&pdev->dev.kobj, - &dev_attr_clk_ctl.attr, power_group); -} + struct device *dev = kobj_to_dev(kobj); + struct pci_dev *pdev = to_pci_dev(dev); + struct pcie_link_state *link = pcie_aspm_get_link(pdev); + static const u8 aspm_state_map[] = { + ASPM_STATE_L0S, + ASPM_STATE_L1, + ASPM_STATE_L1_1, + ASPM_STATE_L1_2, + ASPM_STATE_L1_1_PCIPM, + ASPM_STATE_L1_2_PCIPM, + }; -void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) -{ - struct pcie_link_state *link_state = pdev->link_state; + if (aspm_disabled || !link) + return 0; - if (!link_state) - return; + if (n == 0) + return link->clkpm_capable ? a->mode : 0; - if (link_state->aspm_support) - sysfs_remove_file_from_group(&pdev->dev.kobj, - &dev_attr_link_state.attr, power_group); - if (link_state->clkpm_capable) - sysfs_remove_file_from_group(&pdev->dev.kobj, - &dev_attr_clk_ctl.attr, power_group); + return link->aspm_capable & aspm_state_map[n - 1] ? a->mode : 0; } -#endif + +const struct attribute_group aspm_ctrl_attr_group = { + .name = "link", + .attrs = aspm_ctrl_attrs, + .is_visible = aspm_ctrl_attrs_are_visible, +}; static int __init pcie_aspm_disable(char *str) { --- linux-oracle-5.4.0.orig/drivers/pci/pcie/dpc.c +++ linux-oracle-5.4.0/drivers/pci/pcie/dpc.c @@ -195,7 +195,7 @@ for (i = 0; i < dpc->rp_log_size - 5; i++) { pci_read_config_dword(pdev, - cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix); + cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, &prefix); pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix); } clear_status: @@ -291,7 +291,7 @@ int status; u16 ctl, cap; - if (pcie_aer_get_firmware_first(pdev)) + if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native) return -ENOTSUPP; dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/pci/pcie/portdrv.h +++ linux-oracle-5.4.0/drivers/pci/pcie/portdrv.h @@ -25,6 +25,8 @@ #define PCIE_PORT_DEVICE_MAXSERVICES 5 +extern bool pcie_ports_dpc_native; + #ifdef CONFIG_PCIEAER int pcie_aer_init(void); #else --- linux-oracle-5.4.0.orig/drivers/pci/pcie/portdrv_core.c +++ linux-oracle-5.4.0/drivers/pci/pcie/portdrv_core.c @@ -250,13 +250,23 @@ pcie_pme_interrupt_enable(dev, false); } + /* + * With dpc-native, allow Linux to use DPC even if it doesn't have + * permission to use AER. + */ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) && - pci_aer_available() && services & PCIE_PORT_SERVICE_AER) + pci_aer_available() && + (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER))) services |= PCIE_PORT_SERVICE_DPC; if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM || - pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) - services |= PCIE_PORT_SERVICE_BWNOTIF; + pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { + u32 linkcap; + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &linkcap); + if (linkcap & PCI_EXP_LNKCAP_LBNC) + services |= PCIE_PORT_SERVICE_BWNOTIF; + } return services; } --- linux-oracle-5.4.0.orig/drivers/pci/pcie/portdrv_pci.c +++ linux-oracle-5.4.0/drivers/pci/pcie/portdrv_pci.c @@ -29,12 +29,20 @@ */ bool pcie_ports_native; +/* + * If the user specified "pcie_ports=dpc-native", use the Linux DPC PCIe + * service even if the platform hasn't given us permission. + */ +bool pcie_ports_dpc_native; + static int __init pcie_port_setup(char *str) { if (!strncmp(str, "compat", 6)) pcie_ports_disabled = true; else if (!strncmp(str, "native", 6)) pcie_ports_native = true; + else if (!strncmp(str, "dpc-native", 10)) + pcie_ports_dpc_native = true; return 1; } --- linux-oracle-5.4.0.orig/drivers/pci/pcie/ptm.c +++ linux-oracle-5.4.0/drivers/pci/pcie/ptm.c @@ -21,7 +21,7 @@ snprintf(clock_desc, sizeof(clock_desc), ">254ns"); break; default: - snprintf(clock_desc, sizeof(clock_desc), "%udns", + snprintf(clock_desc, sizeof(clock_desc), "%uns", dev->ptm_granularity); break; } @@ -39,10 +39,6 @@ if (!pci_is_pcie(dev)) return; - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); - if (!pos) - return; - /* * Enable PTM only on interior devices (root ports, switch ports, * etc.) on the assumption that it causes no link traffic until an @@ -52,6 +48,23 @@ pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)) return; + /* + * Switch Downstream Ports are not permitted to have a PTM + * capability; their PTM behavior is controlled by the Upstream + * Port (PCIe r5.0, sec 7.9.16). + */ + ups = pci_upstream_bridge(dev); + if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM && + ups && ups->ptm_enabled) { + dev->ptm_granularity = ups->ptm_granularity; + dev->ptm_enabled = 1; + return; + } + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); + if (!pos) + return; + pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap); local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; @@ -61,7 +74,6 @@ * the spec recommendation (PCIe r3.1, sec 7.32.3), select the * furthest upstream Time Source as the PTM Root. */ - ups = pci_upstream_bridge(dev); if (ups && ups->ptm_enabled) { ctrl = PCI_PTM_CTRL_ENABLE; if (ups->ptm_granularity == 0) --- linux-oracle-5.4.0.orig/drivers/pci/probe.c +++ linux-oracle-5.4.0/drivers/pci/probe.c @@ -564,7 +564,7 @@ return b; } -static void devm_pci_release_host_bridge_dev(struct device *dev) +static void pci_release_host_bridge_dev(struct device *dev) { struct pci_host_bridge *bridge = to_pci_host_bridge(dev); @@ -572,12 +572,8 @@ bridge->release_fn(bridge); pci_free_resource_list(&bridge->windows); -} - -static void pci_release_host_bridge_dev(struct device *dev) -{ - devm_pci_release_host_bridge_dev(dev); - kfree(to_pci_host_bridge(dev)); + pci_free_resource_list(&bridge->dma_ranges); + kfree(bridge); } static void pci_init_host_bridge(struct pci_host_bridge *bridge) @@ -596,6 +592,8 @@ bridge->native_shpc_hotplug = 1; bridge->native_pme = 1; bridge->native_ltr = 1; + + device_initialize(&bridge->dev); } struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) @@ -613,17 +611,25 @@ } EXPORT_SYMBOL(pci_alloc_host_bridge); +static void devm_pci_alloc_host_bridge_release(void *data) +{ + pci_free_host_bridge(data); +} + struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, size_t priv) { + int ret; struct pci_host_bridge *bridge; - bridge = devm_kzalloc(dev, sizeof(*bridge) + priv, GFP_KERNEL); + bridge = pci_alloc_host_bridge(priv); if (!bridge) return NULL; - pci_init_host_bridge(bridge); - bridge->dev.release = devm_pci_release_host_bridge_dev; + ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release, + bridge); + if (ret) + return NULL; return bridge; } @@ -631,13 +637,11 @@ void pci_free_host_bridge(struct pci_host_bridge *bridge) { - pci_free_resource_list(&bridge->windows); - pci_free_resource_list(&bridge->dma_ranges); - - kfree(bridge); + put_device(&bridge->dev); } EXPORT_SYMBOL(pci_free_host_bridge); +/* Indexed by PCI_X_SSTATUS_FREQ (secondary bus mode and frequency) */ static const unsigned char pcix_bus_speed[] = { PCI_SPEED_UNKNOWN, /* 0 */ PCI_SPEED_66MHz_PCIX, /* 1 */ @@ -657,6 +661,7 @@ PCI_SPEED_133MHz_PCIX_533 /* F */ }; +/* Indexed by PCI_EXP_LNKCAP_SLS, PCI_EXP_LNKSTA_CLS */ const unsigned char pcie_link_speed[] = { PCI_SPEED_UNKNOWN, /* 0 */ PCIE_SPEED_2_5GT, /* 1 */ @@ -675,6 +680,44 @@ PCI_SPEED_UNKNOWN, /* E */ PCI_SPEED_UNKNOWN /* F */ }; +EXPORT_SYMBOL_GPL(pcie_link_speed); + +const char *pci_speed_string(enum pci_bus_speed speed) +{ + /* Indexed by the pci_bus_speed enum */ + static const char *speed_strings[] = { + "33 MHz PCI", /* 0x00 */ + "66 MHz PCI", /* 0x01 */ + "66 MHz PCI-X", /* 0x02 */ + "100 MHz PCI-X", /* 0x03 */ + "133 MHz PCI-X", /* 0x04 */ + NULL, /* 0x05 */ + NULL, /* 0x06 */ + NULL, /* 0x07 */ + NULL, /* 0x08 */ + "66 MHz PCI-X 266", /* 0x09 */ + "100 MHz PCI-X 266", /* 0x0a */ + "133 MHz PCI-X 266", /* 0x0b */ + "Unknown AGP", /* 0x0c */ + "1x AGP", /* 0x0d */ + "2x AGP", /* 0x0e */ + "4x AGP", /* 0x0f */ + "8x AGP", /* 0x10 */ + "66 MHz PCI-X 533", /* 0x11 */ + "100 MHz PCI-X 533", /* 0x12 */ + "133 MHz PCI-X 533", /* 0x13 */ + "2.5 GT/s PCIe", /* 0x14 */ + "5.0 GT/s PCIe", /* 0x15 */ + "8.0 GT/s PCIe", /* 0x16 */ + "16.0 GT/s PCIe", /* 0x17 */ + "32.0 GT/s PCIe", /* 0x18 */ + }; + + if (speed < ARRAY_SIZE(speed_strings)) + return speed_strings[speed]; + return "Unknown"; +} +EXPORT_SYMBOL_GPL(pci_speed_string); void pcie_update_link_speed(struct pci_bus *bus, u16 linksta) { @@ -865,10 +908,11 @@ if (err) goto free; - err = device_register(&bridge->dev); - if (err) + err = device_add(&bridge->dev); + if (err) { put_device(&bridge->dev); - + goto free; + } bus->bridge = get_device(&bridge->dev); device_enable_async_suspend(bus->bridge); pci_set_bus_of_node(bus); @@ -931,7 +975,7 @@ unregister: put_device(&bridge->dev); - device_unregister(&bridge->dev); + device_del(&bridge->dev); free: kfree(bus); @@ -1089,14 +1133,15 @@ * @sec: updated with secondary bus number from EA * @sub: updated with subordinate bus number from EA * - * If @dev is a bridge with EA capability, update @sec and @sub with - * fixed bus numbers from the capability and return true. Otherwise, - * return false. + * If @dev is a bridge with EA capability that specifies valid secondary + * and subordinate bus numbers, return true with the bus numbers in @sec + * and @sub. Otherwise return false. */ static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub) { int ea, offset; u32 dw; + u8 ea_sec, ea_sub; if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) return false; @@ -1108,8 +1153,13 @@ offset = ea + PCI_EA_FIRST_ENT; pci_read_config_dword(dev, offset, &dw); - *sec = dw & PCI_EA_SEC_BUS_MASK; - *sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; + ea_sec = dw & PCI_EA_SEC_BUS_MASK; + ea_sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT; + if (ea_sec == 0 || ea_sub < ea_sec) + return false; + + *sec = ea_sec; + *sub = ea_sub; return true; } @@ -1770,7 +1820,7 @@ /* Device class may be changed after fixup */ class = dev->class >> 8; - if (dev->non_compliant_bars) { + if (dev->non_compliant_bars && !dev->mmio_always_on) { pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { pci_info(dev, "device has non-compliant BARs; disabling IO/MEM decoding\n"); @@ -1882,13 +1932,33 @@ struct pci_dev *bridge = pci_upstream_bridge(dev); int mps, mpss, p_mps, rc; - if (!pci_is_pcie(dev) || !bridge || !pci_is_pcie(bridge)) + if (!pci_is_pcie(dev)) return; /* MPS and MRRS fields are of type 'RsvdP' for VFs, short-circuit out */ if (dev->is_virtfn) return; + /* + * For Root Complex Integrated Endpoints, program the maximum + * supported value unless limited by the PCIE_BUS_PEER2PEER case. + */ + if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { + if (pcie_bus_config == PCIE_BUS_PEER2PEER) + mps = 128; + else + mps = 128 << dev->pcie_mpss; + rc = pcie_set_mps(dev, mps); + if (rc) { + pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n", + mps); + } + return; + } + + if (!bridge || !pci_is_pcie(bridge)) + return; + mps = pcie_get_mps(dev); p_mps = pcie_get_mps(bridge); @@ -2271,6 +2341,7 @@ pci_set_of_node(dev); if (pci_setup_device(dev)) { + pci_release_of_node(dev); pci_bus_put(dev->bus); kfree(dev); return NULL; @@ -2916,7 +2987,7 @@ return bridge->bus; err_out: - kfree(bridge); + put_device(&bridge->dev); return NULL; } EXPORT_SYMBOL_GPL(pci_create_root_bus); --- linux-oracle-5.4.0.orig/drivers/pci/quirks.c +++ linux-oracle-5.4.0/drivers/pci/quirks.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include /* isa_dma_bridge_buggy */ #include "pci.h" @@ -205,6 +206,21 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); +/* The BAR0 ~ BAR4 of Marvell 9125 device can't be accessed +* by IO resource file, and need to skip the files +*/ +static void quirk_marvell_mask_bar(struct pci_dev *dev) +{ + int i; + + for (i = 0; i < 5; i++) + if (dev->resource[i].start) + dev->resource[i].start = + dev->resource[i].end = 0; +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125, + quirk_marvell_mask_bar); + /* * The Mellanox Tavor device gives false positive parity errors. Mark this * device with a broken_parity_status to allow PCI scanning code to "skip" @@ -596,7 +612,7 @@ /* * In the AMD NL platform, this device ([1022:7912]) has a class code of * PCI_CLASS_SERIAL_USB_XHCI (0x0c0330), which means the xhci driver will - * claim it. + * claim it. The same applies on the VanGogh platform device ([1022:163a]). * * But the dwc3 driver is a more specific driver for this device, and we'd * prefer to use it instead of xhci. To prevent xhci from claiming the @@ -604,17 +620,22 @@ * defines as "USB device (not host controller)". The dwc3 driver can then * claim it based on its Vendor and Device ID. */ -static void quirk_amd_nl_class(struct pci_dev *pdev) +static void quirk_amd_dwc_class(struct pci_dev *pdev) { u32 class = pdev->class; - /* Use "USB Device (not host controller)" class */ - pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; - pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", - class, pdev->class); + if (class != PCI_CLASS_SERIAL_USB_DEVICE) { + /* Use "USB Device (not host controller)" class */ + pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; + pci_info(pdev, + "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", + class, pdev->class); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, - quirk_amd_nl_class); + quirk_amd_dwc_class); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VANGOGH_USB, + quirk_amd_dwc_class); /* * Synopsys USB 3.x host HAPS platform has a class code of @@ -1871,19 +1892,41 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); +static void quirk_d3hot_delay(struct pci_dev *dev, unsigned int delay) +{ + if (dev->d3_delay >= delay) + return; + + dev->d3_delay = delay; + pci_info(dev, "extending delay after power-on from D3hot to %d msec\n", + dev->d3_delay); +} + static void quirk_radeon_pm(struct pci_dev *dev) { if (dev->subsystem_vendor == PCI_VENDOR_ID_APPLE && - dev->subsystem_device == 0x00e2) { - if (dev->d3_delay < 20) { - dev->d3_delay = 20; - pci_info(dev, "extending delay after power-on from D3 to %d msec\n", - dev->d3_delay); - } - } + dev->subsystem_device == 0x00e2) + quirk_d3hot_delay(dev, 20); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6741, quirk_radeon_pm); +/* + * Ryzen5/7 XHCI controllers fail upon resume from runtime suspend or s2idle. + * https://bugzilla.kernel.org/show_bug.cgi?id=205587 + * + * The kernel attempts to transition these devices to D3cold, but that seems + * to be ineffective on the platforms in question; the PCI device appears to + * remain on in D3hot state. The D3hot-to-D0 transition then requires an + * extended delay in order to succeed. + */ +static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev) +{ + quirk_d3hot_delay(dev, 20); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1639, quirk_ryzen_xhci_d3hot); + #ifdef CONFIG_X86_IO_APIC static int dmi_disable_ioapicreroute(const struct dmi_system_id *d) { @@ -1949,26 +1992,92 @@ /* * IO-APIC1 on 6300ESB generates boot interrupts, see Intel order no * 300641-004US, section 5.7.3. + * + * Core IO on Xeon E5 1600/2600/4600, see Intel order no 326509-003. + * Core IO on Xeon E5 v2, see Intel order no 329188-003. + * Core IO on Xeon E7 v2, see Intel order no 329595-002. + * Core IO on Xeon E5 v3, see Intel order no 330784-003. + * Core IO on Xeon E7 v3, see Intel order no 332315-001US. + * Core IO on Xeon E5 v4, see Intel order no 333810-002US. + * Core IO on Xeon E7 v4, see Intel order no 332315-001US. + * Core IO on Xeon D-1500, see Intel order no 332051-001. + * Core IO on Xeon Scalable, see Intel order no 610950. */ -#define INTEL_6300_IOAPIC_ABAR 0x40 +#define INTEL_6300_IOAPIC_ABAR 0x40 /* Bus 0, Dev 29, Func 5 */ #define INTEL_6300_DISABLE_BOOT_IRQ (1<<14) +#define INTEL_CIPINTRC_CFG_OFFSET 0x14C /* Bus 0, Dev 5, Func 0 */ +#define INTEL_CIPINTRC_DIS_INTX_ICH (1<<25) + static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev) { u16 pci_config_word; + u32 pci_config_dword; if (noioapicquirk) return; - pci_read_config_word(dev, INTEL_6300_IOAPIC_ABAR, &pci_config_word); - pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ; - pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word); - + switch (dev->device) { + case PCI_DEVICE_ID_INTEL_ESB_10: + pci_read_config_word(dev, INTEL_6300_IOAPIC_ABAR, + &pci_config_word); + pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ; + pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, + pci_config_word); + break; + case 0x3c28: /* Xeon E5 1600/2600/4600 */ + case 0x0e28: /* Xeon E5/E7 V2 */ + case 0x2f28: /* Xeon E5/E7 V3,V4 */ + case 0x6f28: /* Xeon D-1500 */ + case 0x2034: /* Xeon Scalable Family */ + pci_read_config_dword(dev, INTEL_CIPINTRC_CFG_OFFSET, + &pci_config_dword); + pci_config_dword |= INTEL_CIPINTRC_DIS_INTX_ICH; + pci_write_config_dword(dev, INTEL_CIPINTRC_CFG_OFFSET, + pci_config_dword); + break; + default: + return; + } pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n", dev->vendor, dev->device); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, quirk_disable_intel_boot_interrupt); -DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, quirk_disable_intel_boot_interrupt); +/* + * Device 29 Func 5 Device IDs of IO-APIC + * containing ABAR—APIC1 Alternate Base Address Register + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, + quirk_disable_intel_boot_interrupt); + +/* + * Device 5 Func 0 Device IDs of Core IO modules/hubs + * containing Coherent Interface Protocol Interrupt Control + * + * Device IDs obtained from volume 2 datasheets of commented + * families above. + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x3c28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0e28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2f28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x6f28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2034, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x3c28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x0e28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x2f28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x6f28, + quirk_disable_intel_boot_interrupt); +DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x2034, + quirk_disable_intel_boot_interrupt); /* Disable boot interrupts on HT-1000 */ #define BC_HT1000_FEATURE_REG 0x64 @@ -2243,6 +2352,19 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); +static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev) +{ + pci_info(dev, "Disabling ASPM L0s/L1\n"); + pci_disable_link_state(dev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); +} + +/* + * ASM1083/1085 PCIe-PCI bridge devices cause AER timeout errors on the + * upstream PCIe root port when ASPM is enabled. At least L0s mode is affected; + * disable both L0s and L1 for now to be safe. + */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x1080, quirk_disable_aspm_l0s_l1); + /* * Some Pericom PCIe-to-PCI bridges in reverse mode need the PCIe Retrain * Link bit cleared after starting the link retrain process to allow this @@ -2381,32 +2503,6 @@ PCI_DEVICE_ID_TIGON3_5719, quirk_brcm_5719_limit_mrrs); -#ifdef CONFIG_PCIE_IPROC_PLATFORM -static void quirk_paxc_bridge(struct pci_dev *pdev) -{ - /* - * The PCI config space is shared with the PAXC root port and the first - * Ethernet device. So, we need to workaround this by telling the PCI - * code that the bridge is not an Ethernet device. - */ - if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) - pdev->class = PCI_CLASS_BRIDGE_PCI << 8; - - /* - * MPSS is not being set properly (as it is currently 0). This is - * because that area of the PCI config space is hard coded to zero, and - * is not modifiable by firmware. Set this to 2 (e.g., 512 byte MPS) - * so that the MPS can be set to the real max value. - */ - pdev->pcie_mpss = 2; -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge); -#endif - /* * Originally in EDAC sources for i82875P: Intel tells BIOS developers to * hide device 6 which configures the overflow device access containing the @@ -3170,12 +3266,13 @@ { dev->pcie_mpss = 1; /* 256 bytes */ } -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SOLARFLARE, - PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_0, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000A_1, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLARFLARE, + PCI_DEVICE_ID_SOLARFLARE_SFC4000B, fixup_mpss_256); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ASMEDIA, 0x0612, fixup_mpss_256); /* * Intel 5000 and 5100 Memory controllers have an erratum with read completion @@ -3359,6 +3456,8 @@ quirk_broken_intx_masking); DECLARE_PCI_FIXUP_FINAL(0x1b7c, 0x0004, /* Ceton InfiniTV4 */ quirk_broken_intx_masking); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K2, + quirk_broken_intx_masking); /* * Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10) @@ -3484,6 +3583,18 @@ } /* + * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be + * prevented for those affected devices. + */ +static void quirk_nvidia_no_bus_reset(struct pci_dev *dev) +{ + if ((dev->device & 0xffc0) == 0x2340) + quirk_no_bus_reset(dev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, + quirk_nvidia_no_bus_reset); + +/* * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. * The device will throw a Link Down error on AER-capable systems and * regardless of AER, config space of the device is never accessible again @@ -3495,6 +3606,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003e, quirk_no_bus_reset); /* * Root port on some Cavium CN8xxx chips do not successfully complete a bus @@ -3503,6 +3615,16 @@ */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CAVIUM, 0xa100, quirk_no_bus_reset); +/* + * Some TI KeyStone C667X devices do not support bus/hot reset. The PCIESS + * automatically disables LTSSM when Secondary Bus Reset is received and + * the device stops working. Prevent bus reset for these devices. With + * this change, the device can be assigned to VMs with VFIO, but it will + * leak state between VMs. Reference + * https://e2e.ti.com/support/processors/f/791/t/954382 + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0xb005, quirk_no_bus_reset); + static void quirk_no_pm_reset(struct pci_dev *dev) { /* @@ -3525,6 +3647,19 @@ PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset); /* + * Spectrum-{1,2,3,4} devices report that a D3hot->D0 transition causes a reset + * (i.e., they advertise NoSoftRst-). However, this transition does not have + * any effect on the device: It continues to be operational and network ports + * remain up. Advertising this support makes it seem as if a PM reset is viable + * for these devices. Mark it as unavailable to skip it when testing reset + * methods. + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcb84, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf6c, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf70, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf80, quirk_no_pm_reset); + +/* * Thunderbolt controllers with broken MSI hotplug signaling: * Entire 1st generation (Light Ridge, Eagle Ridge, Light Peak) and part * of the 2nd generation (Cactus Ridge 4C up to revision 1, Port Ridge). @@ -3571,6 +3706,16 @@ return; if (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) return; + + /* + * SXIO/SXFP/SXLF turns off power to the Thunderbolt controller. + * We don't know how to turn it back on again, but firmware does, + * so we can only use SXIO/SXFP/SXLF if we're suspending via + * firmware. + */ + if (!pm_suspend_via_firmware()) + return; + bridge = ACPI_HANDLE(&dev->dev); if (!bridge) return; @@ -3895,6 +4040,69 @@ return 0; } +#define PCI_DEVICE_ID_HINIC_VF 0x375E +#define HINIC_VF_FLR_TYPE 0x1000 +#define HINIC_VF_FLR_CAP_BIT (1UL << 30) +#define HINIC_VF_OP 0xE80 +#define HINIC_VF_FLR_PROC_BIT (1UL << 18) +#define HINIC_OPERATION_TIMEOUT 15000 /* 15 seconds */ + +/* Device-specific reset method for Huawei Intelligent NIC virtual functions */ +static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe) +{ + unsigned long timeout; + void __iomem *bar; + u32 val; + + if (probe) + return 0; + + bar = pci_iomap(pdev, 0, 0); + if (!bar) + return -ENOTTY; + + /* Get and check firmware capabilities */ + val = ioread32be(bar + HINIC_VF_FLR_TYPE); + if (!(val & HINIC_VF_FLR_CAP_BIT)) { + pci_iounmap(pdev, bar); + return -ENOTTY; + } + + /* Set HINIC_VF_FLR_PROC_BIT for the start of FLR */ + val = ioread32be(bar + HINIC_VF_OP); + val = val | HINIC_VF_FLR_PROC_BIT; + iowrite32be(val, bar + HINIC_VF_OP); + + pcie_flr(pdev); + + /* + * The device must recapture its Bus and Device Numbers after FLR + * in order generate Completions. Issue a config write to let the + * device capture this information. + */ + pci_write_config_word(pdev, PCI_VENDOR_ID, 0); + + /* Firmware clears HINIC_VF_FLR_PROC_BIT when reset is complete */ + timeout = jiffies + msecs_to_jiffies(HINIC_OPERATION_TIMEOUT); + do { + val = ioread32be(bar + HINIC_VF_OP); + if (!(val & HINIC_VF_FLR_PROC_BIT)) + goto reset_complete; + msleep(20); + } while (time_before(jiffies, timeout)); + + val = ioread32be(bar + HINIC_VF_OP); + if (!(val & HINIC_VF_FLR_PROC_BIT)) + goto reset_complete; + + pci_warn(pdev, "Reset dev timeout, FLR ack reg: %#010x\n", val); + +reset_complete: + pci_iounmap(pdev, bar); + + return 0; +} + static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, @@ -3906,6 +4114,8 @@ { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr }, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, reset_chelsio_generic_dev }, + { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, + reset_hinic_vf_dev }, { 0 } }; @@ -3932,7 +4142,7 @@ static void quirk_dma_func0_alias(struct pci_dev *dev) { if (PCI_FUNC(dev->devfn) != 0) - pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 0), 1); } /* @@ -3943,10 +4153,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RICOH, 0xe832, quirk_dma_func0_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_RICOH, 0xe476, quirk_dma_func0_alias); +/* Some Glenfly chips use function 0 as the PCIe Requester ID for DMA */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GLENFLY, 0x3d40, quirk_dma_func0_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_GLENFLY, 0x3d41, quirk_dma_func0_alias); + static void quirk_dma_func1_alias(struct pci_dev *dev) { if (PCI_FUNC(dev->devfn) != 1) - pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 1)); + pci_add_dma_alias(dev, PCI_DEVFN(PCI_SLOT(dev->devfn), 1), 1); } /* @@ -3959,6 +4173,9 @@ quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123, quirk_dma_func1_alias); +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c136 */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125, + quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ @@ -3981,12 +4198,17 @@ /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, quirk_dma_func1_alias); +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9215, + quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c49 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230, quirk_dma_func1_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9235, + quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642, quirk_dma_func1_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645, @@ -4031,7 +4253,7 @@ id = pci_match_id(fixed_dma_alias_tbl, dev); if (id) - pci_add_dma_alias(dev, id->driver_data); + pci_add_dma_alias(dev, id->driver_data, 1); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADAPTEC2, 0x0285, quirk_fixed_dma_alias); @@ -4073,14 +4295,43 @@ */ static void quirk_mic_x200_dma_alias(struct pci_dev *pdev) { - pci_add_dma_alias(pdev, PCI_DEVFN(0x10, 0x0)); - pci_add_dma_alias(pdev, PCI_DEVFN(0x11, 0x0)); - pci_add_dma_alias(pdev, PCI_DEVFN(0x12, 0x3)); + pci_add_dma_alias(pdev, PCI_DEVFN(0x10, 0x0), 1); + pci_add_dma_alias(pdev, PCI_DEVFN(0x11, 0x0), 1); + pci_add_dma_alias(pdev, PCI_DEVFN(0x12, 0x3), 1); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2260, quirk_mic_x200_dma_alias); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2264, quirk_mic_x200_dma_alias); /* + * Intel Visual Compute Accelerator (VCA) is a family of PCIe add-in devices + * exposing computational units via Non Transparent Bridges (NTB, PEX 87xx). + * + * Similarly to MIC x200, we need to add DMA aliases to allow buffer access + * when IOMMU is enabled. These aliases allow computational unit access to + * host memory. These aliases mark the whole VCA device as one IOMMU + * group. + * + * All possible slot numbers (0x20) are used, since we are unable to tell + * what slot is used on other side. This quirk is intended for both host + * and computational unit sides. The VCA devices have up to five functions + * (four for DMA channels and one additional). + */ +static void quirk_pex_vca_alias(struct pci_dev *pdev) +{ + const unsigned int num_pci_slots = 0x20; + unsigned int slot; + + for (slot = 0; slot < num_pci_slots; slot++) + pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x0), 5); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2954, quirk_pex_vca_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2955, quirk_pex_vca_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2956, quirk_pex_vca_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2958, quirk_pex_vca_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2959, quirk_pex_vca_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x295A, quirk_pex_vca_alias); + +/* * The IOMMU and interrupt controller on Broadcom Vulcan/Cavium ThunderX2 are * associated not at the root bus, but at a bridge below. This quirk avoids * generating invalid DMA aliases. @@ -4263,6 +4514,47 @@ quirk_chelsio_T5_disable_root_port_attributes); /* + * pci_acs_ctrl_enabled - compare desired ACS controls with those provided + * by a device + * @acs_ctrl_req: Bitmask of desired ACS controls + * @acs_ctrl_ena: Bitmask of ACS controls enabled or provided implicitly by + * the hardware design + * + * Return 1 if all ACS controls in the @acs_ctrl_req bitmask are included + * in @acs_ctrl_ena, i.e., the device provides all the access controls the + * caller desires. Return 0 otherwise. + */ +static int pci_acs_ctrl_enabled(u16 acs_ctrl_req, u16 acs_ctrl_ena) +{ + if ((acs_ctrl_req & acs_ctrl_ena) == acs_ctrl_req) + return 1; + return 0; +} + +/* + * Many Zhaoxin Root Ports and Switch Downstream Ports have no ACS capability. + * But the implementation could block peer-to-peer transactions between them + * and provide ACS-like functionality. + */ +static int pci_quirk_zhaoxin_pcie_ports_acs(struct pci_dev *dev, u16 acs_flags) +{ + if (!pci_is_pcie(dev) || + ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && + (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) + return -ENOTTY; + + switch (dev->device) { + case 0x0710 ... 0x071e: + case 0x0721: + case 0x0723 ... 0x0732: + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); + } + + return false; +} + +/* * AMD has indicated that the devices below do not support peer-to-peer * in any system where they are found in the southbridge with an AMD * IOMMU in the system. Multifunction devices that do not support @@ -4302,10 +4594,12 @@ if (ACPI_FAILURE(status)) return -ENODEV; + acpi_put_table(header); + /* Filter out flags not applicable to multifunction */ acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT); - return acs_flags & ~(PCI_ACS_RR | PCI_ACS_CR) ? 0 : 1; + return pci_acs_ctrl_enabled(acs_flags, PCI_ACS_RR | PCI_ACS_CR); #else return -ENODEV; #endif @@ -4313,33 +4607,38 @@ static bool pci_quirk_cavium_acs_match(struct pci_dev *dev) { + if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) + return false; + + switch (dev->device) { /* - * Effectively selects all downstream ports for whole ThunderX 1 - * family by 0xf800 mask (which represents 8 SoCs), while the lower - * bits of device ID are used to indicate which subdevice is used - * within the SoC. - */ - return (pci_is_pcie(dev) && - (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) && - ((dev->device & 0xf800) == 0xa000)); + * Effectively selects all downstream ports for whole ThunderX1 + * (which represents 8 SoCs). + */ + case 0xa000 ... 0xa7ff: /* ThunderX1 */ + case 0xaf84: /* ThunderX2 */ + case 0xb884: /* ThunderX3 */ + return true; + default: + return false; + } } static int pci_quirk_cavium_acs(struct pci_dev *dev, u16 acs_flags) { + if (!pci_quirk_cavium_acs_match(dev)) + return -ENOTTY; + /* - * Cavium root ports don't advertise an ACS capability. However, + * Cavium Root Ports don't advertise an ACS capability. However, * the RTL internally implements similar protection as if ACS had - * Request Redirection, Completion Redirection, Source Validation, + * Source Validation, Request Redirection, Completion Redirection, * and Upstream Forwarding features enabled. Assert that the * hardware implements and enables equivalent ACS functionality for * these flags. */ - acs_flags &= ~(PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_SV | PCI_ACS_UF); - - if (!pci_quirk_cavium_acs_match(dev)) - return -ENOTTY; - - return acs_flags ? 0 : 1; + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } static int pci_quirk_xgene_acs(struct pci_dev *dev, u16 acs_flags) @@ -4349,13 +4648,12 @@ * transactions with others, allowing masking out these bits as if they * were unimplemented in the ACS capability. */ - acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); - - return acs_flags ? 0 : 1; + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } /* - * Many Intel PCH root ports do provide ACS-like features to disable peer + * Many Intel PCH Root Ports do provide ACS-like features to disable peer * transactions and validate bus numbers in requests, but do not provide an * actual PCIe ACS capability. This is the list of device IDs known to fall * into that category as provided by Intel in Red Hat bugzilla 1037684. @@ -4403,37 +4701,44 @@ return false; } -#define INTEL_PCH_ACS_FLAGS (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV) - static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) { - u16 flags = dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK ? - INTEL_PCH_ACS_FLAGS : 0; - if (!pci_quirk_intel_pch_acs_match(dev)) return -ENOTTY; - return acs_flags & ~flags ? 0 : 1; + if (dev->dev_flags & PCI_DEV_FLAGS_ACS_ENABLED_QUIRK) + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); + + return pci_acs_ctrl_enabled(acs_flags, 0); } /* - * These QCOM root ports do provide ACS-like features to disable peer + * These QCOM Root Ports do provide ACS-like features to disable peer * transactions and validate bus numbers in requests, but do not provide an * actual PCIe ACS capability. Hardware supports source validation but it * will report the issue as Completer Abort instead of ACS Violation. - * Hardware doesn't support peer-to-peer and each root port is a root - * complex with unique segment numbers. It is not possible for one root - * port to pass traffic to another root port. All PCIe transactions are - * terminated inside the root port. + * Hardware doesn't support peer-to-peer and each Root Port is a Root + * Complex with unique segment numbers. It is not possible for one Root + * Port to pass traffic to another Root Port. All PCIe transactions are + * terminated inside the Root Port. */ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags) { - u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV); - int ret = acs_flags & ~flags ? 0 : 1; - - pci_info(dev, "Using QCOM ACS Quirk (%d)\n", ret); + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); +} - return ret; +/* + * Each of these NXP Root Ports is in a Root Complex with a unique segment + * number and does provide isolation features to disable peer transactions + * and validate bus numbers in requests, but does not provide an ACS + * capability. + */ +static int pci_quirk_nxp_rp_acs(struct pci_dev *dev, u16 acs_flags) +{ + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } static int pci_quirk_al_acs(struct pci_dev *dev, u16 acs_flags) @@ -4505,6 +4810,7 @@ return false; switch (dev->device) { + case 0x06ac ... 0x06c3: /* Comet Lake */ case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ case 0x9d10 ... 0x9d1b: /* 7th & 8th Gen Mobile */ @@ -4534,7 +4840,7 @@ pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl); - return acs_flags & ~ctrl ? 0 : 1; + return pci_acs_ctrl_enabled(acs_flags, ctrl); } static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags) @@ -4548,10 +4854,23 @@ * perform peer-to-peer with other functions, allowing us to mask out * these bits as if they were unimplemented in the ACS capability. */ - acs_flags &= ~(PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | - PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_TB | PCI_ACS_RR | + PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_DT); +} - return acs_flags ? 0 : 1; +static int pci_quirk_rciep_acs(struct pci_dev *dev, u16 acs_flags) +{ + /* + * Intel RCiEP's are required to allow p2p only on translated + * addresses. Refer to Intel VT-d specification, r3.1, sec 3.16, + * "Root-Complex Peer to Peer Considerations". + */ + if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END) + return -ENOTTY; + + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags) @@ -4562,9 +4881,31 @@ * Allow each Root Port to be in a separate IOMMU group by masking * SV/RR/CR/UF bits. */ - acs_flags &= ~(PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); +} - return acs_flags ? 0 : 1; +/* + * Wangxun 40G/25G/10G/1G NICs have no ACS capability, but on + * multi-function devices, the hardware isolates the functions by + * directing all peer-to-peer traffic upstream as though PCI_ACS_RR and + * PCI_ACS_CR were set. + * SFxxx 1G NICs(em). + * RP1000/RP2000 10G NICs(sp). + * FF5xxx 40G/25G/10G NICs(aml). + */ +static int pci_quirk_wangxun_nic_acs(struct pci_dev *dev, u16 acs_flags) +{ + switch (dev->device) { + case 0x0100 ... 0x010F: /* EM */ + case 0x1001: case 0x2001: /* SP */ + case 0x5010: case 0x5025: case 0x5040: /* AML */ + case 0x5110: case 0x5125: case 0x5140: /* AML */ + return pci_acs_ctrl_enabled(acs_flags, + PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); + } + + return false; } static const struct pci_dev_acs_enabled { @@ -4637,9 +4978,12 @@ /* I219 */ { PCI_VENDOR_ID_INTEL, 0x15b7, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_rciep_acs }, /* QCOM QDF2xxx root ports */ { PCI_VENDOR_ID_QCOM, 0x0400, pci_quirk_qcom_rp_acs }, { PCI_VENDOR_ID_QCOM, 0x0401, pci_quirk_qcom_rp_acs }, + /* QCOM SA8775P root port */ + { PCI_VENDOR_ID_QCOM, 0x0115, pci_quirk_qcom_rp_acs }, /* HXT SD4800 root ports. The ACS design is same as QCOM QDF2xxx */ { PCI_VENDOR_ID_HXT, 0x0401, pci_quirk_qcom_rp_acs }, /* Intel PCH root ports */ @@ -4649,6 +4993,10 @@ { 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */ /* Cavium ThunderX */ { PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID, pci_quirk_cavium_acs }, + /* Cavium multi-function devices */ + { PCI_VENDOR_ID_CAVIUM, 0xA026, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_CAVIUM, 0xA059, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_CAVIUM, 0xA060, pci_quirk_mf_endpoint_acs }, /* APM X-Gene */ { PCI_VENDOR_ID_AMCC, 0xE004, pci_quirk_xgene_acs }, /* Ampere Computing */ @@ -4660,12 +5008,73 @@ { PCI_VENDOR_ID_AMPERE, 0xE00A, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs }, + /* Broadcom multi-function device */ + { PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1750, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1751, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1752, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1760, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1761, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1762, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_BROADCOM, 0x1763, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs }, /* Amazon Annapurna Labs */ { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs }, + /* Zhaoxin multi-function devices */ + { PCI_VENDOR_ID_ZHAOXIN, 0x3038, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_ZHAOXIN, 0x3104, pci_quirk_mf_endpoint_acs }, + { PCI_VENDOR_ID_ZHAOXIN, 0x9083, pci_quirk_mf_endpoint_acs }, + /* NXP root ports, xx=16, 12, or 08 cores */ + /* LX2xx0A : without security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d81, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da1, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d83, pci_quirk_nxp_rp_acs }, + /* LX2xx0C : security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d80, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da0, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d82, pci_quirk_nxp_rp_acs }, + /* LX2xx0E : security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d90, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db0, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d92, pci_quirk_nxp_rp_acs }, + /* LX2xx0N : without security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d91, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db1, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d93, pci_quirk_nxp_rp_acs }, + /* LX2xx2A : without security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d89, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da9, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d8b, pci_quirk_nxp_rp_acs }, + /* LX2xx2C : security features + CAN-FD */ + { PCI_VENDOR_ID_NXP, 0x8d88, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8da8, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d8a, pci_quirk_nxp_rp_acs }, + /* LX2xx2E : security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d98, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db8, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d9a, pci_quirk_nxp_rp_acs }, + /* LX2xx2N : without security features + CAN */ + { PCI_VENDOR_ID_NXP, 0x8d99, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8db9, pci_quirk_nxp_rp_acs }, + { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs }, + /* Zhaoxin Root/Downstream Ports */ + { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, + /* Wangxun nics */ + { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, { 0 } }; +/* + * pci_dev_specific_acs_enabled - check whether device provides ACS controls + * @dev: PCI device + * @acs_flags: Bitmask of desired ACS controls + * + * Returns: + * -ENOTTY: No quirk applies to this device; we can't tell whether the + * device provides the desired controls + * 0: Device does not provide all the desired controls + * >0: Device provides all the controls in @acs_flags + */ int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags) { const struct pci_dev_acs_enabled *i; @@ -4706,7 +5115,7 @@ #define INTEL_BSPR_REG_BPPD (1 << 9) /* Upstream Peer Decode Configuration Register */ -#define INTEL_UPDCR_REG 0x1114 +#define INTEL_UPDCR_REG 0x1014 /* 5:0 Peer Decode Enable bits */ #define INTEL_UPDCR_REG_MASK 0x3f @@ -4985,13 +5394,47 @@ } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x443, quirk_intel_qat_vf_cap); -/* FLR may cause some 82579 devices to hang */ -static void quirk_intel_no_flr(struct pci_dev *dev) +/* + * FLR may cause the following to devices to hang: + * + * AMD Starship/Matisse HD Audio Controller 0x1487 + * AMD Starship USB 3.0 Host Controller 0x148c + * AMD Matisse USB 3.0 Host Controller 0x149c + * Intel 82579LM Gigabit Ethernet Controller 0x1502 + * Intel 82579V Gigabit Ethernet Controller 0x1503 + * + */ +static void quirk_no_flr(struct pci_dev *dev) { dev->dev_flags |= PCI_DEV_FLAGS_NO_FLR_RESET; } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x1487, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x148c, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x149c, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AMD, 0x7901, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_no_flr); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_no_flr); + +static void quirk_intel_th_rtit_bar(struct pci_dev *dev) +{ + struct resource *r = &dev->resource[4]; + + /* + * Hello, Denverton! + * Denverton reports 2k of RTIT_BAR (resource 4), which can't be + * right given the 16 threads. When Intel TH gets enabled, the + * actual resource overlaps the XHCI MMIO space and causes it + * to die. + * We're not really using RTIT_BAR at all at the moment, so it's + * a safe choice to disable this resource. + */ + if (r->end == r->start + 0x7ff) { + r->flags = 0; + r->start = 0; + r->end = 0; + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x19e1, quirk_intel_th_rtit_bar); static void quirk_no_ext_tags(struct pci_dev *pdev) { @@ -5005,6 +5448,7 @@ pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL); } +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_3WARE, 0x1004, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0132, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0141, quirk_no_ext_tags); @@ -5014,19 +5458,55 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); #ifdef CONFIG_PCI_ATS -/* - * Some devices have a broken ATS implementation causing IOMMU stalls. - * Don't use ATS for those devices. - */ static void quirk_no_ats(struct pci_dev *pdev) { - pci_info(pdev, "disabling ATS (broken on this device)\n"); + pci_info(pdev, "disabling ATS\n"); pdev->ats_cap = 0; } +/* + * Some devices require additional driver setup to enable ATS. Don't use + * ATS for those devices as ATS will be enabled before the driver has had a + * chance to load and configure the device. + */ +static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) +{ + if ((pdev->device == 0x7312 && pdev->revision != 0x00) || + (pdev->device == 0x7340 && pdev->revision != 0xc5) || + (pdev->device == 0x7341 && pdev->revision != 0x00)) + return; + + quirk_no_ats(pdev); +} + /* AMD Stoney platform GPU */ -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_no_ats); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x98e4, quirk_amd_harvest_no_ats); +/* AMD Iceland dGPU */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats); +/* AMD Navi10 dGPU */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); +/* AMD Navi14 dGPU */ +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); + +/* + * Intel IPU E2000 revisions before C0 implement incorrect endianness + * in ATS Invalidate Request message body. Disable ATS for those devices. + */ +static void quirk_intel_e2000_no_ats(struct pci_dev *pdev) +{ + if (pdev->revision < 0x20) + quirk_no_ats(pdev); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1451, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1452, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1453, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1454, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1455, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1457, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1459, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145a, quirk_intel_e2000_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x145c, quirk_intel_e2000_no_ats); #endif /* CONFIG_PCI_ATS */ /* Freescale PCIe doesn't support MSI in RC mode */ @@ -5090,7 +5570,7 @@ PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda); /* - * Create device link for NVIDIA GPU with integrated USB xHCI Host + * Create device link for GPUs with integrated USB xHCI Host * controller to VGA. */ static void quirk_gpu_usb(struct pci_dev *usb) @@ -5099,9 +5579,11 @@ } DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID, + PCI_CLASS_SERIAL_USB, 8, quirk_gpu_usb); /* - * Create device link for NVIDIA GPU with integrated Type-C UCSI controller + * Create device link for GPUs with integrated Type-C UCSI controller * to VGA. Currently there is no class code defined for UCSI device over PCI * so using UNKNOWN class for now and it will be updated when UCSI * over PCI gets a class code. @@ -5114,6 +5596,9 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_CLASS_SERIAL_UNKNOWN, 8, quirk_gpu_usb_typec_ucsi); +DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID, + PCI_CLASS_SERIAL_UNKNOWN, 8, + quirk_gpu_usb_typec_ucsi); /* * Enable the NVIDIA GPU integrated HDA controller if the BIOS left it @@ -5273,7 +5758,7 @@ pci_dbg(pdev, "Aliasing Partition %d Proxy ID %02x.%d\n", pp, PCI_SLOT(devfn), PCI_FUNC(devfn)); - pci_add_dma_alias(pdev, devfn); + pci_add_dma_alias(pdev, devfn, 1); } } @@ -5316,6 +5801,21 @@ SWITCHTEC_QUIRK(0x8576); /* PFXI 96XG3 */ /* + * The PLX NTB uses devfn proxy IDs to move TLPs between NT endpoints. + * These IDs are used to forward responses to the originator on the other + * side of the NTB. Alias all possible IDs to the NTB to permit access when + * the IOMMU is turned on. + */ +static void quirk_plx_ntb_dma_alias(struct pci_dev *pdev) +{ + pci_info(pdev, "Setting PLX NTB proxy ID aliases\n"); + /* PLX NTB may use all 256 devfns */ + pci_add_dma_alias(pdev, 0, 256); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, 0x87b0, quirk_plx_ntb_dma_alias); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, 0x87b1, quirk_plx_ntb_dma_alias); + +/* * On Lenovo Thinkpad P50 SKUs with a Nvidia Quadro M1000M, the BIOS does * not always reset the secondary Nvidia GPU between reboots if the system * is configured to use Hybrid Graphics mode. This results in the GPU @@ -5372,3 +5872,40 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, 0x13b1, PCI_CLASS_DISPLAY_VGA, 8, quirk_reset_lenovo_thinkpad_p50_nvgpu); + +/* + * Device [1b21:2142] + * When in D0, PME# doesn't get asserted when plugging USB 3.0 device. + */ +static void pci_fixup_no_d0_pme(struct pci_dev *dev) +{ + pci_info(dev, "PME# does not work under D0, disabling it\n"); + dev->pme_support &= ~(PCI_PM_CAP_PME_D0 >> PCI_PM_CAP_PME_SHIFT); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASMEDIA, 0x2142, pci_fixup_no_d0_pme); + +static void apex_pci_fixup_class(struct pci_dev *pdev) +{ + pdev->class = (PCI_CLASS_SYSTEM_OTHER << 8) | pdev->class; +} +DECLARE_PCI_FIXUP_CLASS_HEADER(0x1ac1, 0x089a, + PCI_CLASS_NOT_DEFINED, 8, apex_pci_fixup_class); + +static void nvidia_ion_ahci_fixup(struct pci_dev *pdev) +{ + pdev->dev_flags |= PCI_DEV_FLAGS_HAS_MSI_MASKING; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0ab8, nvidia_ion_ahci_fixup); + +/* + * Device [12d8:0x400e] and [12d8:0x400f] + * These devices advertise PME# support in all power states but don't + * reliably assert it. + */ +static void pci_fixup_no_pme(struct pci_dev *dev) +{ + pci_info(dev, "PME# is unreliable, disabling it\n"); + dev->pme_support = 0; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_PERICOM, 0x400e, pci_fixup_no_pme); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_PERICOM, 0x400f, pci_fixup_no_pme); --- linux-oracle-5.4.0.orig/drivers/pci/remove.c +++ linux-oracle-5.4.0/drivers/pci/remove.c @@ -160,6 +160,6 @@ host_bridge->bus = NULL; /* remove the host bridge */ - device_unregister(&host_bridge->dev); + device_del(&host_bridge->dev); } EXPORT_SYMBOL_GPL(pci_remove_root_bus); --- linux-oracle-5.4.0.orig/drivers/pci/rom.c +++ linux-oracle-5.4.0/drivers/pci/rom.c @@ -195,20 +195,3 @@ pci_disable_rom(pdev); } EXPORT_SYMBOL(pci_unmap_rom); - -/** - * pci_platform_rom - provides a pointer to any ROM image provided by the - * platform - * @pdev: pointer to pci device struct - * @size: pointer to receive size of pci window over ROM - */ -void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) -{ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt((phys_addr_t)pdev->rom); - } - - return NULL; -} -EXPORT_SYMBOL(pci_platform_rom); --- linux-oracle-5.4.0.orig/drivers/pci/search.c +++ linux-oracle-5.4.0/drivers/pci/search.c @@ -41,9 +41,9 @@ * DMA, iterate over that too. */ if (unlikely(pdev->dma_alias_mask)) { - u8 devfn; + unsigned int devfn; - for_each_set_bit(devfn, pdev->dma_alias_mask, U8_MAX) { + for_each_set_bit(devfn, pdev->dma_alias_mask, MAX_NR_DEVFNS) { ret = fn(pdev, PCI_DEVID(pdev->bus->number, devfn), data); if (ret) --- linux-oracle-5.4.0.orig/drivers/pci/setup-bus.c +++ linux-oracle-5.4.0/drivers/pci/setup-bus.c @@ -752,24 +752,32 @@ } /* - * Helper function for sizing routines: find first available bus resource - * of a given type. Note: we intentionally skip the bus resources which - * have already been assigned (that is, have non-NULL parent resource). + * Helper function for sizing routines. Assigned resources have non-NULL + * parent resource. + * + * Return first unassigned resource of the correct type. If there is none, + * return first assigned resource of the correct type. If none of the + * above, return NULL. + * + * Returning an assigned resource of the correct type allows the caller to + * distinguish between already assigned and no resource of the correct type. */ -static struct resource *find_free_bus_resource(struct pci_bus *bus, - unsigned long type_mask, - unsigned long type) +static struct resource *find_bus_resource_of_type(struct pci_bus *bus, + unsigned long type_mask, + unsigned long type) { + struct resource *r, *r_assigned = NULL; int i; - struct resource *r; pci_bus_for_each_resource(bus, r, i) { if (r == &ioport_resource || r == &iomem_resource) continue; if (r && (r->flags & type_mask) == type && !r->parent) return r; + if (r && (r->flags & type_mask) == type && !r_assigned) + r_assigned = r; } - return NULL; + return r_assigned; } static resource_size_t calculate_iosize(resource_size_t size, @@ -810,11 +818,9 @@ size = min_size; if (old_size == 1) old_size = 0; - if (size < old_size) - size = old_size; - size = ALIGN(max(size, add_size) + children_add_size, align); - return size; + size = max(size, add_size) + children_add_size; + return ALIGN(max(size, old_size), align); } resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus, @@ -866,8 +872,8 @@ struct list_head *realloc_head) { struct pci_dev *dev; - struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO, - IORESOURCE_IO); + struct resource *b_res = find_bus_resource_of_type(bus, IORESOURCE_IO, + IORESOURCE_IO); resource_size_t size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; resource_size_t min_align, align; @@ -875,6 +881,10 @@ if (!b_res) return; + /* If resource is already assigned, nothing more to do */ + if (b_res->parent) + return; + min_align = window_alignment(bus, IORESOURCE_IO); list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -978,7 +988,7 @@ resource_size_t min_align, align, size, size0, size1; resource_size_t aligns[18]; /* Alignments from 1MB to 128GB */ int order, max_order; - struct resource *b_res = find_free_bus_resource(bus, + struct resource *b_res = find_bus_resource_of_type(bus, mask | IORESOURCE_PREFETCH, type); resource_size_t children_add_size = 0; resource_size_t children_add_align = 0; @@ -987,6 +997,10 @@ if (!b_res) return -ENOSPC; + /* If resource is already assigned, nothing more to do */ + if (b_res->parent) + return 0; + memset(aligns, 0, sizeof(aligns)); max_order = 0; size = 0; @@ -1785,12 +1799,18 @@ /* Restore size and flags */ list_for_each_entry(fail_res, &fail_head, list) { struct resource *res = fail_res->res; + int idx; res->start = fail_res->start; res->end = fail_res->end; res->flags = fail_res->flags; - if (fail_res->dev->subordinate) - res->flags = 0; + + if (pci_is_bridge(fail_res->dev)) { + idx = res - &fail_res->dev->resource[0]; + if (idx >= PCI_BRIDGE_RESOURCES && + idx <= PCI_BRIDGE_RESOURCE_END) + res->flags = 0; + } } free_list(&fail_head); @@ -2037,12 +2057,18 @@ /* Restore size and flags */ list_for_each_entry(fail_res, &fail_head, list) { struct resource *res = fail_res->res; + int idx; res->start = fail_res->start; res->end = fail_res->end; res->flags = fail_res->flags; - if (fail_res->dev->subordinate) - res->flags = 0; + + if (pci_is_bridge(fail_res->dev)) { + idx = res - &fail_res->dev->resource[0]; + if (idx >= PCI_BRIDGE_RESOURCES && + idx <= PCI_BRIDGE_RESOURCE_END) + res->flags = 0; + } } free_list(&fail_head); --- linux-oracle-5.4.0.orig/drivers/pci/setup-res.c +++ linux-oracle-5.4.0/drivers/pci/setup-res.c @@ -209,6 +209,17 @@ root = pci_find_parent_resource(dev, res); if (!root) { + /* + * If dev is behind a bridge, accesses will only reach it + * if res is inside the relevant bridge window. + */ + if (pci_upstream_bridge(dev)) + return -ENXIO; + + /* + * On the root bus, assume the host bridge will forward + * everything. + */ if (res->flags & IORESOURCE_IO) root = &ioport_resource; else @@ -409,10 +420,16 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size) { struct resource *res = dev->resource + resno; + struct pci_host_bridge *host; int old, ret; u32 sizes; u16 cmd; + /* Check if we must preserve the firmware's resource assignment */ + host = pci_find_host_bridge(dev->bus); + if (host->preserve_config) + return -ENOTSUPP; + /* Make sure the resource isn't assigned before resizing it. */ if (!(res->flags & IORESOURCE_UNSET)) return -EBUSY; @@ -439,10 +456,11 @@ res->end = res->start + pci_rebar_size_to_bytes(size) - 1; /* Check if the new config works by trying to assign everything. */ - ret = pci_reassign_bridge_resources(dev->bus->self, res->flags); - if (ret) - goto error_resize; - + if (dev->bus->self) { + ret = pci_reassign_bridge_resources(dev->bus->self, res->flags); + if (ret) + goto error_resize; + } return 0; error_resize: --- linux-oracle-5.4.0.orig/drivers/pci/slot.c +++ linux-oracle-5.4.0/drivers/pci/slot.c @@ -49,45 +49,9 @@ slot->number); } -/* these strings match up with the values in pci_bus_speed */ -static const char *pci_bus_speed_strings[] = { - "33 MHz PCI", /* 0x00 */ - "66 MHz PCI", /* 0x01 */ - "66 MHz PCI-X", /* 0x02 */ - "100 MHz PCI-X", /* 0x03 */ - "133 MHz PCI-X", /* 0x04 */ - NULL, /* 0x05 */ - NULL, /* 0x06 */ - NULL, /* 0x07 */ - NULL, /* 0x08 */ - "66 MHz PCI-X 266", /* 0x09 */ - "100 MHz PCI-X 266", /* 0x0a */ - "133 MHz PCI-X 266", /* 0x0b */ - "Unknown AGP", /* 0x0c */ - "1x AGP", /* 0x0d */ - "2x AGP", /* 0x0e */ - "4x AGP", /* 0x0f */ - "8x AGP", /* 0x10 */ - "66 MHz PCI-X 533", /* 0x11 */ - "100 MHz PCI-X 533", /* 0x12 */ - "133 MHz PCI-X 533", /* 0x13 */ - "2.5 GT/s PCIe", /* 0x14 */ - "5.0 GT/s PCIe", /* 0x15 */ - "8.0 GT/s PCIe", /* 0x16 */ - "16.0 GT/s PCIe", /* 0x17 */ - "32.0 GT/s PCIe", /* 0x18 */ -}; - static ssize_t bus_speed_read(enum pci_bus_speed speed, char *buf) { - const char *speed_string; - - if (speed < ARRAY_SIZE(pci_bus_speed_strings)) - speed_string = pci_bus_speed_strings[speed]; - else - speed_string = "Unknown"; - - return sprintf(buf, "%s\n", speed_string); + return sprintf(buf, "%s\n", pci_speed_string(speed)); } static ssize_t max_speed_read_file(struct pci_slot *slot, char *buf) @@ -115,6 +79,7 @@ up_read(&pci_bus_sem); list_del(&slot->list); + pci_bus_put(slot->bus); kfree(slot); } @@ -296,7 +261,7 @@ goto err; } - slot->bus = parent; + slot->bus = pci_bus_get(parent); slot->number = slot_nr; slot->kobj.kset = pci_slots_kset; @@ -304,16 +269,20 @@ slot_name = make_slot_name(name); if (!slot_name) { err = -ENOMEM; + pci_bus_put(slot->bus); + kfree(slot); goto err; } + INIT_LIST_HEAD(&slot->list); + list_add(&slot->list, &parent->slots); + err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL, "%s", slot_name); - if (err) + if (err) { + kobject_put(&slot->kobj); goto err; - - INIT_LIST_HEAD(&slot->list); - list_add(&slot->list, &parent->slots); + } down_read(&pci_bus_sem); list_for_each_entry(dev, &parent->devices, bus_list) @@ -329,7 +298,6 @@ mutex_unlock(&pci_slot_mutex); return slot; err: - kfree(slot); slot = ERR_PTR(err); goto out; } --- linux-oracle-5.4.0.orig/drivers/pci/switch/switchtec.c +++ linux-oracle-5.4.0/drivers/pci/switch/switchtec.c @@ -175,7 +175,7 @@ kref_get(&stuser->kref); stuser->read_len = sizeof(stuser->data); stuser_set_state(stuser, MRPC_QUEUED); - init_completion(&stuser->comp); + reinit_completion(&stuser->comp); list_add_tail(&stuser->list, &stdev->mrpc_queue); mrpc_cmd_submit(stdev); @@ -675,7 +675,7 @@ return -ENOMEM; s->global = ioread32(&stdev->mmio_sw_event->global_summary); - s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); + s->part_bitmap = ioread64(&stdev->mmio_sw_event->part_event_bitmap); s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); for (i = 0; i < stdev->partition_count; i++) { @@ -1082,13 +1082,6 @@ { struct switchtec_dev *stdev = to_stdev(dev); - if (stdev->dma_mrpc) { - iowrite32(0, &stdev->mmio_mrpc->dma_en); - flush_wc_buf(stdev); - writeq(0, &stdev->mmio_mrpc->dma_addr); - dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), - stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); - } kfree(stdev); } @@ -1131,7 +1124,7 @@ return ERR_PTR(-ENOMEM); stdev->alive = true; - stdev->pdev = pdev; + stdev->pdev = pci_dev_get(pdev); INIT_LIST_HEAD(&stdev->mrpc_queue); mutex_init(&stdev->mrpc_mutex); stdev->mrpc_busy = 0; @@ -1165,6 +1158,7 @@ return stdev; err_put: + pci_dev_put(stdev->pdev); put_device(&stdev->dev); return ERR_PTR(rc); } @@ -1276,7 +1270,7 @@ if (nvecs < 0) return nvecs; - event_irq = ioread32(&stdev->mmio_part_cfg->vep_vector_number); + event_irq = ioread16(&stdev->mmio_part_cfg->vep_vector_number); if (event_irq < 0 || event_irq >= nvecs) return -EFAULT; @@ -1349,7 +1343,7 @@ if (rc) return rc; - rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (rc) return rc; @@ -1407,6 +1401,18 @@ return 0; } +static void switchtec_exit_pci(struct switchtec_dev *stdev) +{ + if (stdev->dma_mrpc) { + iowrite32(0, &stdev->mmio_mrpc->dma_en); + flush_wc_buf(stdev); + writeq(0, &stdev->mmio_mrpc->dma_addr); + dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), + stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); + stdev->dma_mrpc = NULL; + } +} + static int switchtec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1427,7 +1433,7 @@ rc = switchtec_init_isr(stdev); if (rc) { dev_err(&stdev->dev, "failed to init isr.\n"); - goto err_put; + goto err_exit_pci; } iowrite32(SWITCHTEC_EVENT_CLEAR | @@ -1448,6 +1454,8 @@ err_devadd: stdev_kill(stdev); +err_exit_pci: + switchtec_exit_pci(stdev); err_put: ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); put_device(&stdev->dev); @@ -1464,6 +1472,9 @@ ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); dev_info(&stdev->dev, "unregistered.\n"); stdev_kill(stdev); + switchtec_exit_pci(stdev); + pci_dev_put(stdev->pdev); + stdev->pdev = NULL; put_device(&stdev->dev); } --- linux-oracle-5.4.0.orig/drivers/pci/syscall.c +++ linux-oracle-5.4.0/drivers/pci/syscall.c @@ -20,10 +20,12 @@ u16 word; u32 dword; long err; - long cfg_ret; + int cfg_ret; + err = -EPERM; + dev = NULL; if (!capable(CAP_SYS_ADMIN)) - return -EPERM; + goto error; err = -ENODEV; dev = pci_get_domain_bus_and_slot(0, bus, dfn); @@ -46,7 +48,7 @@ } err = -EIO; - if (cfg_ret != PCIBIOS_SUCCESSFUL) + if (cfg_ret) goto error; switch (len) { @@ -105,7 +107,7 @@ if (err) break; err = pci_user_write_config_byte(dev, off, byte); - if (err != PCIBIOS_SUCCESSFUL) + if (err) err = -EIO; break; @@ -114,7 +116,7 @@ if (err) break; err = pci_user_write_config_word(dev, off, word); - if (err != PCIBIOS_SUCCESSFUL) + if (err) err = -EIO; break; @@ -123,7 +125,7 @@ if (err) break; err = pci_user_write_config_dword(dev, off, dword); - if (err != PCIBIOS_SUCCESSFUL) + if (err) err = -EIO; break; --- linux-oracle-5.4.0.orig/drivers/pci/vpd.c +++ linux-oracle-5.4.0/drivers/pci/vpd.c @@ -570,7 +570,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID, quirk_blacklist_vpd); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd); /* * The Amazon Annapurna Labs 0x0031 device id is reused for other non Root Port * device types, so the quirk is registered for the PCI_CLASS_BRIDGE_PCI class. --- linux-oracle-5.4.0.orig/drivers/pcmcia/Kconfig +++ linux-oracle-5.4.0/drivers/pcmcia/Kconfig @@ -151,7 +151,7 @@ config PCMCIA_ALCHEMY_DEVBOARD tristate "Alchemy Db/Pb1xxx PCMCIA socket services" - depends on MIPS_ALCHEMY && PCMCIA + depends on MIPS_DB1XXX && PCMCIA help Enable this driver of you want PCMCIA support on your Alchemy Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 --- linux-oracle-5.4.0.orig/drivers/pcmcia/cs.c +++ linux-oracle-5.4.0/drivers/pcmcia/cs.c @@ -605,6 +605,7 @@ dev_warn(&skt->dev, "PCMCIA: unable to register socket\n"); skt->thread = NULL; complete(&skt->thread_done); + put_device(&skt->dev); return 0; } ret = pccard_sysfs_add_socket(&skt->dev); @@ -666,18 +667,16 @@ if (events || sysfs_events) continue; + set_current_state(TASK_INTERRUPTIBLE); if (kthread_should_stop()) break; - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - /* make sure we are running */ - __set_current_state(TASK_RUNNING); - try_to_freeze(); } + /* make sure we are running before we exit */ + __set_current_state(TASK_RUNNING); /* shut down socket, if a device is still present */ if (skt->state & SOCKET_PRESENT) { --- linux-oracle-5.4.0.orig/drivers/pcmcia/ds.c +++ linux-oracle-5.4.0/drivers/pcmcia/ds.c @@ -518,9 +518,6 @@ /* by default don't allow DMA */ p_dev->dma_mask = DMA_MASK_NONE; p_dev->dev.dma_mask = &p_dev->dma_mask; - dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); - if (!dev_name(&p_dev->dev)) - goto err_free; p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev)); if (!p_dev->devname) goto err_free; @@ -578,8 +575,15 @@ pcmcia_device_query(p_dev); - if (device_register(&p_dev->dev)) - goto err_unreg; + dev_set_name(&p_dev->dev, "%d.%d", p_dev->socket->sock, p_dev->device_no); + if (device_register(&p_dev->dev)) { + mutex_lock(&s->ops_mutex); + list_del(&p_dev->socket_device_list); + s->device_count--; + mutex_unlock(&s->ops_mutex); + put_device(&p_dev->dev); + return NULL; + } return p_dev; --- linux-oracle-5.4.0.orig/drivers/pcmcia/i82092.c +++ linux-oracle-5.4.0/drivers/pcmcia/i82092.c @@ -106,6 +106,7 @@ for (i = 0;iio_db; @@ -809,6 +812,9 @@ unsigned long min, max; int ret, i, j; + if (!res) + return NULL; + low = low || !(s->features & SS_CAP_PAGE_REGS); data.mask = align - 1; @@ -1047,6 +1053,8 @@ q = p->next; kfree(p); } + + kfree(data); } --- linux-oracle-5.4.0.orig/drivers/pcmcia/yenta_socket.c +++ linux-oracle-5.4.0/drivers/pcmcia/yenta_socket.c @@ -637,11 +637,11 @@ start = PCIBIOS_MIN_CARDBUS_IO; end = ~0U; } else { - unsigned long avail = root->end - root->start; + unsigned long avail = resource_size(root); int i; size = BRIDGE_MEM_MAX; - if (size > avail/8) { - size = (avail+1)/8; + if (size > (avail - 1) / 8) { + size = avail / 8; /* round size down to next power of 2 */ i = 0; while ((size /= 2) != 0) --- linux-oracle-5.4.0.orig/drivers/perf/Kconfig +++ linux-oracle-5.4.0/drivers/perf/Kconfig @@ -41,6 +41,13 @@ PMU (perf) driver supporting the ARM CCN (Cache Coherent Network) interconnect. +config ARM_CMN + tristate "Arm CMN-600 PMU support" + depends on ARM64 || (COMPILE_TEST && 64BIT) + help + Support for PMU events monitoring on the Arm CMN-600 Coherent Mesh + Network interconnect. + config ARM_PMU depends on ARM || ARM64 bool "ARM PMU framework" @@ -79,13 +86,6 @@ can give information about memory throughput and other related events. -config HISI_PMU - bool "HiSilicon SoC PMU" - depends on ARM64 && ACPI - help - Support for HiSilicon SoC uncore performance monitoring - unit (PMU), such as: L3C, HHA and DDRC. - config QCOM_L2_PMU bool "Qualcomm Technologies L2-cache PMU" depends on ARCH_QCOM && ARM64 && ACPI @@ -129,4 +129,12 @@ Extension, which provides periodic sampling of operations in the CPU pipeline and reports this via the perf AUX interface. +config ARM_DMC620_PMU + tristate "Enable PMU support for the ARM DMC-620 memory controller" + depends on (ARM64 && ACPI) || COMPILE_TEST + help + Support for PMU events monitoring on the ARM DMC-620 memory + controller. +source "drivers/perf/hisilicon/Kconfig" + endmenu --- linux-oracle-5.4.0.orig/drivers/perf/Makefile +++ linux-oracle-5.4.0/drivers/perf/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_ARM_CCI_PMU) += arm-cci.o obj-$(CONFIG_ARM_CCN) += arm-ccn.o +obj-$(CONFIG_ARM_CMN) += arm-cmn.o obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o @@ -12,3 +13,4 @@ obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o +obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o --- linux-oracle-5.4.0.orig/drivers/perf/arm-cci.c +++ linux-oracle-5.4.0/drivers/perf/arm-cci.c @@ -1720,6 +1720,7 @@ .driver = { .name = DRIVER_NAME, .of_match_table = arm_cci_pmu_matches, + .suppress_bind_attrs = true, }, .probe = cci_pmu_probe, .remove = cci_pmu_remove, --- linux-oracle-5.4.0.orig/drivers/perf/arm-ccn.c +++ linux-oracle-5.4.0/drivers/perf/arm-ccn.c @@ -1545,6 +1545,7 @@ .driver = { .name = "arm-ccn", .of_match_table = arm_ccn_match, + .suppress_bind_attrs = true, }, .probe = arm_ccn_probe, .remove = arm_ccn_remove, --- linux-oracle-5.4.0.orig/drivers/perf/arm-cmn.c +++ linux-oracle-5.4.0/drivers/perf/arm-cmn.c @@ -0,0 +1,1638 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2016-2020 Arm Limited +// CMN-600 Coherent Mesh Network PMU driver + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Common register stuff */ +#define CMN_NODE_INFO 0x0000 +#define CMN_NI_NODE_TYPE GENMASK_ULL(15, 0) +#define CMN_NI_NODE_ID GENMASK_ULL(31, 16) +#define CMN_NI_LOGICAL_ID GENMASK_ULL(47, 32) + +#define CMN_NODEID_DEVID(reg) ((reg) & 3) +#define CMN_NODEID_PID(reg) (((reg) >> 2) & 1) +#define CMN_NODEID_X(reg, bits) ((reg) >> (3 + (bits))) +#define CMN_NODEID_Y(reg, bits) (((reg) >> 3) & ((1U << (bits)) - 1)) + +#define CMN_CHILD_INFO 0x0080 +#define CMN_CI_CHILD_COUNT GENMASK_ULL(15, 0) +#define CMN_CI_CHILD_PTR_OFFSET GENMASK_ULL(31, 16) + +#define CMN_CHILD_NODE_ADDR GENMASK(27,0) +#define CMN_CHILD_NODE_EXTERNAL BIT(31) + +#define CMN_ADDR_NODE_PTR GENMASK(27, 14) + +#define CMN_NODE_PTR_DEVID(ptr) (((ptr) >> 2) & 3) +#define CMN_NODE_PTR_PID(ptr) ((ptr) & 1) +#define CMN_NODE_PTR_X(ptr, bits) ((ptr) >> (6 + (bits))) +#define CMN_NODE_PTR_Y(ptr, bits) (((ptr) >> 6) & ((1U << (bits)) - 1)) + +#define CMN_MAX_XPS (8 * 8) + +/* The CFG node has one other useful purpose */ +#define CMN_CFGM_PERIPH_ID_2 0x0010 +#define CMN_CFGM_PID2_REVISION GENMASK(7, 4) + +/* PMU registers occupy the 3rd 4KB page of each node's 16KB space */ +#define CMN_PMU_OFFSET 0x2000 + +/* For most nodes, this is all there is */ +#define CMN_PMU_EVENT_SEL 0x000 +#define CMN_PMU_EVENTn_ID_SHIFT(n) ((n) * 8) + +/* DTMs live in the PMU space of XP registers */ +#define CMN_DTM_WPn(n) (0x1A0 + (n) * 0x18) +#define CMN_DTM_WPn_CONFIG(n) (CMN_DTM_WPn(n) + 0x00) +#define CMN_DTM_WPn_CONFIG_WP_COMBINE BIT(6) +#define CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE BIT(5) +#define CMN_DTM_WPn_CONFIG_WP_GRP BIT(4) +#define CMN_DTM_WPn_CONFIG_WP_CHN_SEL GENMASK_ULL(3, 1) +#define CMN_DTM_WPn_CONFIG_WP_DEV_SEL BIT(0) +#define CMN_DTM_WPn_VAL(n) (CMN_DTM_WPn(n) + 0x08) +#define CMN_DTM_WPn_MASK(n) (CMN_DTM_WPn(n) + 0x10) + +#define CMN_DTM_PMU_CONFIG 0x210 +#define CMN__PMEVCNT0_INPUT_SEL GENMASK_ULL(37, 32) +#define CMN__PMEVCNT0_INPUT_SEL_WP 0x00 +#define CMN__PMEVCNT0_INPUT_SEL_XP 0x04 +#define CMN__PMEVCNT0_INPUT_SEL_DEV 0x10 +#define CMN__PMEVCNT0_GLOBAL_NUM GENMASK_ULL(18, 16) +#define CMN__PMEVCNTn_GLOBAL_NUM_SHIFT(n) ((n) * 4) +#define CMN__PMEVCNT_PAIRED(n) BIT(4 + (n)) +#define CMN__PMEVCNT23_COMBINED BIT(2) +#define CMN__PMEVCNT01_COMBINED BIT(1) +#define CMN_DTM_PMU_CONFIG_PMU_EN BIT(0) + +#define CMN_DTM_PMEVCNT 0x220 + +#define CMN_DTM_PMEVCNTSR 0x240 + +#define CMN_DTM_NUM_COUNTERS 4 + +/* The DTC node is where the magic happens */ +#define CMN_DT_DTC_CTL 0x0a00 +#define CMN_DT_DTC_CTL_DT_EN BIT(0) + +/* DTC counters are paired in 64-bit registers on a 16-byte stride. Yuck */ +#define _CMN_DT_CNT_REG(n) ((((n) / 2) * 4 + (n) % 2) * 4) +#define CMN_DT_PMEVCNT(n) (CMN_PMU_OFFSET + _CMN_DT_CNT_REG(n)) +#define CMN_DT_PMCCNTR (CMN_PMU_OFFSET + 0x40) + +#define CMN_DT_PMEVCNTSR(n) (CMN_PMU_OFFSET + 0x50 + _CMN_DT_CNT_REG(n)) +#define CMN_DT_PMCCNTRSR (CMN_PMU_OFFSET + 0x90) + +#define CMN_DT_PMCR (CMN_PMU_OFFSET + 0x100) +#define CMN_DT_PMCR_PMU_EN BIT(0) +#define CMN_DT_PMCR_CNTR_RST BIT(5) +#define CMN_DT_PMCR_OVFL_INTR_EN BIT(6) + +#define CMN_DT_PMOVSR (CMN_PMU_OFFSET + 0x118) +#define CMN_DT_PMOVSR_CLR (CMN_PMU_OFFSET + 0x120) + +#define CMN_DT_PMSSR (CMN_PMU_OFFSET + 0x128) +#define CMN_DT_PMSSR_SS_STATUS(n) BIT(n) + +#define CMN_DT_PMSRR (CMN_PMU_OFFSET + 0x130) +#define CMN_DT_PMSRR_SS_REQ BIT(0) + +#define CMN_DT_NUM_COUNTERS 8 +#define CMN_MAX_DTCS 4 + +/* + * Even in the worst case a DTC counter can't wrap in fewer than 2^42 cycles, + * so throwing away one bit to make overflow handling easy is no big deal. + */ +#define CMN_COUNTER_INIT 0x80000000 +/* Similarly for the 40-bit cycle counter */ +#define CMN_CC_INIT 0x8000000000ULL + + +/* Event attributes */ +#define CMN_CONFIG_TYPE GENMASK(15, 0) +#define CMN_CONFIG_EVENTID GENMASK(23, 16) +#define CMN_CONFIG_OCCUPID GENMASK(27, 24) +#define CMN_CONFIG_BYNODEID BIT(31) +#define CMN_CONFIG_NODEID GENMASK(47, 32) + +#define CMN_EVENT_TYPE(event) FIELD_GET(CMN_CONFIG_TYPE, (event)->attr.config) +#define CMN_EVENT_EVENTID(event) FIELD_GET(CMN_CONFIG_EVENTID, (event)->attr.config) +#define CMN_EVENT_OCCUPID(event) FIELD_GET(CMN_CONFIG_OCCUPID, (event)->attr.config) +#define CMN_EVENT_BYNODEID(event) FIELD_GET(CMN_CONFIG_BYNODEID, (event)->attr.config) +#define CMN_EVENT_NODEID(event) FIELD_GET(CMN_CONFIG_NODEID, (event)->attr.config) + +#define CMN_CONFIG_WP_COMBINE GENMASK(27, 24) +#define CMN_CONFIG_WP_DEV_SEL BIT(48) +#define CMN_CONFIG_WP_CHN_SEL GENMASK(50, 49) +#define CMN_CONFIG_WP_GRP BIT(52) +#define CMN_CONFIG_WP_EXCLUSIVE BIT(53) +#define CMN_CONFIG1_WP_VAL GENMASK(63, 0) +#define CMN_CONFIG2_WP_MASK GENMASK(63, 0) + +#define CMN_EVENT_WP_COMBINE(event) FIELD_GET(CMN_CONFIG_WP_COMBINE, (event)->attr.config) +#define CMN_EVENT_WP_DEV_SEL(event) FIELD_GET(CMN_CONFIG_WP_DEV_SEL, (event)->attr.config) +#define CMN_EVENT_WP_CHN_SEL(event) FIELD_GET(CMN_CONFIG_WP_CHN_SEL, (event)->attr.config) +#define CMN_EVENT_WP_GRP(event) FIELD_GET(CMN_CONFIG_WP_GRP, (event)->attr.config) +#define CMN_EVENT_WP_EXCLUSIVE(event) FIELD_GET(CMN_CONFIG_WP_EXCLUSIVE, (event)->attr.config) +#define CMN_EVENT_WP_VAL(event) FIELD_GET(CMN_CONFIG1_WP_VAL, (event)->attr.config1) +#define CMN_EVENT_WP_MASK(event) FIELD_GET(CMN_CONFIG2_WP_MASK, (event)->attr.config2) + +/* Made-up event IDs for watchpoint direction */ +#define CMN_WP_UP 0 +#define CMN_WP_DOWN 2 + + +/* r0px probably don't exist in silicon, thankfully */ +enum cmn_revision { + CMN600_R1P0, + CMN600_R1P1, + CMN600_R1P2, + CMN600_R1P3, + CMN600_R2P0, + CMN600_R3P0, +}; + +enum cmn_node_type { + CMN_TYPE_INVALID, + CMN_TYPE_DVM, + CMN_TYPE_CFG, + CMN_TYPE_DTC, + CMN_TYPE_HNI, + CMN_TYPE_HNF, + CMN_TYPE_XP, + CMN_TYPE_SBSX, + CMN_TYPE_RNI = 0xa, + CMN_TYPE_RND = 0xd, + CMN_TYPE_RNSAM = 0xf, + CMN_TYPE_CXRA = 0x100, + CMN_TYPE_CXHA = 0x101, + CMN_TYPE_CXLA = 0x102, + /* Not a real node type */ + CMN_TYPE_WP = 0x7770 +}; + +struct arm_cmn_node { + void __iomem *pmu_base; + u16 id, logid; + enum cmn_node_type type; + + union { + /* Device node */ + struct { + int to_xp; + /* DN/HN-F/CXHA */ + unsigned int occupid_val; + unsigned int occupid_count; + }; + /* XP */ + struct { + int dtc; + u32 pmu_config_low; + union { + u8 input_sel[4]; + __le32 pmu_config_high; + }; + s8 wp_event[4]; + }; + }; + + union { + u8 event[4]; + __le32 event_sel; + }; +}; + +struct arm_cmn_dtc { + void __iomem *base; + int irq; + int irq_friend; + bool cc_active; + + struct perf_event *counters[CMN_DT_NUM_COUNTERS]; + struct perf_event *cycles; +}; + +#define CMN_STATE_DISABLED BIT(0) +#define CMN_STATE_TXN BIT(1) + +struct arm_cmn { + struct device *dev; + void __iomem *base; + + enum cmn_revision rev; + u8 mesh_x; + u8 mesh_y; + u16 num_xps; + u16 num_dns; + struct arm_cmn_node *xps; + struct arm_cmn_node *dns; + + struct arm_cmn_dtc *dtc; + unsigned int num_dtcs; + + int cpu; + struct hlist_node cpuhp_node; + + unsigned int state; + struct pmu pmu; +}; + +#define to_cmn(p) container_of(p, struct arm_cmn, pmu) + +static int arm_cmn_hp_state; + +struct arm_cmn_hw_event { + struct arm_cmn_node *dn; + u64 dtm_idx[2]; + unsigned int dtc_idx; + u8 dtcs_used; + u8 num_dns; +}; + +#define for_each_hw_dn(hw, dn, i) \ + for (i = 0, dn = hw->dn; i < hw->num_dns; i++, dn++) + +static struct arm_cmn_hw_event *to_cmn_hw(struct perf_event *event) +{ + BUILD_BUG_ON(sizeof(struct arm_cmn_hw_event) > offsetof(struct hw_perf_event, target)); + return (struct arm_cmn_hw_event *)&event->hw; +} + +static void arm_cmn_set_index(u64 x[], unsigned int pos, unsigned int val) +{ + x[pos / 32] |= (u64)val << ((pos % 32) * 2); +} + +static unsigned int arm_cmn_get_index(u64 x[], unsigned int pos) +{ + return (x[pos / 32] >> ((pos % 32) * 2)) & 3; +} + +struct arm_cmn_event_attr { + struct device_attribute attr; + enum cmn_node_type type; + u8 eventid; + u8 occupid; +}; + +struct arm_cmn_format_attr { + struct device_attribute attr; + u64 field; + int config; +}; + +static int arm_cmn_xyidbits(const struct arm_cmn *cmn) +{ + return cmn->mesh_x > 4 || cmn->mesh_y > 4 ? 3 : 2; +} + +static void arm_cmn_init_node_to_xp(const struct arm_cmn *cmn, + struct arm_cmn_node *dn) +{ + int bits = arm_cmn_xyidbits(cmn); + int x = CMN_NODEID_X(dn->id, bits); + int y = CMN_NODEID_Y(dn->id, bits); + int xp_idx = cmn->mesh_x * y + x; + + dn->to_xp = (cmn->xps + xp_idx) - dn; +} + +static struct arm_cmn_node *arm_cmn_node_to_xp(struct arm_cmn_node *dn) +{ + return dn->type == CMN_TYPE_XP ? dn : dn + dn->to_xp; +} + +static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn, + enum cmn_node_type type) +{ + int i; + + for (i = 0; i < cmn->num_dns; i++) + if (cmn->dns[i].type == type) + return &cmn->dns[i]; + return NULL; +} + +#define CMN_EVENT_ATTR(_name, _type, _eventid, _occupid) \ + (&((struct arm_cmn_event_attr[]) {{ \ + .attr = __ATTR(_name, 0444, arm_cmn_event_show, NULL), \ + .type = _type, \ + .eventid = _eventid, \ + .occupid = _occupid, \ + }})[0].attr.attr) + +static bool arm_cmn_is_occup_event(enum cmn_node_type type, unsigned int id) +{ + return (type == CMN_TYPE_DVM && id == 0x05) || + (type == CMN_TYPE_HNF && id == 0x0f); +} + +static ssize_t arm_cmn_event_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct arm_cmn_event_attr *eattr; + + eattr = container_of(attr, typeof(*eattr), attr); + + if (eattr->type == CMN_TYPE_DTC) + return snprintf(buf, PAGE_SIZE, "type=0x%x\n", eattr->type); + + if (eattr->type == CMN_TYPE_WP) + return snprintf(buf, PAGE_SIZE, + "type=0x%x,eventid=0x%x,wp_dev_sel=?,wp_chn_sel=?,wp_grp=?,wp_val=?,wp_mask=?\n", + eattr->type, eattr->eventid); + + if (arm_cmn_is_occup_event(eattr->type, eattr->eventid)) + return snprintf(buf, PAGE_SIZE, "type=0x%x,eventid=0x%x,occupid=0x%x\n", + eattr->type, eattr->eventid, eattr->occupid); + + return snprintf(buf, PAGE_SIZE, "type=0x%x,eventid=0x%x\n", + eattr->type, eattr->eventid); +} + +static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, + struct attribute *attr, + int unused) +{ + struct device *dev = kobj_to_dev(kobj); + struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev)); + struct arm_cmn_event_attr *eattr; + enum cmn_node_type type; + + eattr = container_of(attr, typeof(*eattr), attr.attr); + type = eattr->type; + + /* Watchpoints aren't nodes */ + if (type == CMN_TYPE_WP) + type = CMN_TYPE_XP; + + /* Revision-specific differences */ + if (cmn->rev < CMN600_R1P2) { + if (type == CMN_TYPE_HNF && eattr->eventid == 0x1b) + return 0; + } + + if (!arm_cmn_node(cmn, type)) + return 0; + + return attr->mode; +} + +#define _CMN_EVENT_DVM(_name, _event, _occup) \ + CMN_EVENT_ATTR(dn_##_name, CMN_TYPE_DVM, _event, _occup) +#define CMN_EVENT_DTC(_name) \ + CMN_EVENT_ATTR(dtc_##_name, CMN_TYPE_DTC, 0, 0) +#define _CMN_EVENT_HNF(_name, _event, _occup) \ + CMN_EVENT_ATTR(hnf_##_name, CMN_TYPE_HNF, _event, _occup) +#define CMN_EVENT_HNI(_name, _event) \ + CMN_EVENT_ATTR(hni_##_name, CMN_TYPE_HNI, _event, 0) +#define __CMN_EVENT_XP(_name, _event) \ + CMN_EVENT_ATTR(mxp_##_name, CMN_TYPE_XP, _event, 0) +#define CMN_EVENT_SBSX(_name, _event) \ + CMN_EVENT_ATTR(sbsx_##_name, CMN_TYPE_SBSX, _event, 0) +#define CMN_EVENT_RNID(_name, _event) \ + CMN_EVENT_ATTR(rnid_##_name, CMN_TYPE_RNI, _event, 0) + +#define CMN_EVENT_DVM(_name, _event) \ + _CMN_EVENT_DVM(_name, _event, 0) +#define CMN_EVENT_HNF(_name, _event) \ + _CMN_EVENT_HNF(_name, _event, 0) +#define _CMN_EVENT_XP(_name, _event) \ + __CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)), \ + __CMN_EVENT_XP(w_##_name, (_event) | (1 << 2)), \ + __CMN_EVENT_XP(n_##_name, (_event) | (2 << 2)), \ + __CMN_EVENT_XP(s_##_name, (_event) | (3 << 2)), \ + __CMN_EVENT_XP(p0_##_name, (_event) | (4 << 2)), \ + __CMN_EVENT_XP(p1_##_name, (_event) | (5 << 2)) + +/* Good thing there are only 3 fundamental XP events... */ +#define CMN_EVENT_XP(_name, _event) \ + _CMN_EVENT_XP(req_##_name, (_event) | (0 << 5)), \ + _CMN_EVENT_XP(rsp_##_name, (_event) | (1 << 5)), \ + _CMN_EVENT_XP(snp_##_name, (_event) | (2 << 5)), \ + _CMN_EVENT_XP(dat_##_name, (_event) | (3 << 5)) + + +static struct attribute *arm_cmn_event_attrs[] = { + CMN_EVENT_DTC(cycles), + + /* + * DVM node events conflict with HN-I events in the equivalent PMU + * slot, but our lazy short-cut of using the DTM counter index for + * the PMU index as well happens to avoid that by construction. + */ + CMN_EVENT_DVM(rxreq_dvmop, 0x01), + CMN_EVENT_DVM(rxreq_dvmsync, 0x02), + CMN_EVENT_DVM(rxreq_dvmop_vmid_filtered, 0x03), + CMN_EVENT_DVM(rxreq_retried, 0x04), + _CMN_EVENT_DVM(rxreq_trk_occupancy_all, 0x05, 0), + _CMN_EVENT_DVM(rxreq_trk_occupancy_dvmop, 0x05, 1), + _CMN_EVENT_DVM(rxreq_trk_occupancy_dvmsync, 0x05, 2), + + CMN_EVENT_HNF(cache_miss, 0x01), + CMN_EVENT_HNF(slc_sf_cache_access, 0x02), + CMN_EVENT_HNF(cache_fill, 0x03), + CMN_EVENT_HNF(pocq_retry, 0x04), + CMN_EVENT_HNF(pocq_reqs_recvd, 0x05), + CMN_EVENT_HNF(sf_hit, 0x06), + CMN_EVENT_HNF(sf_evictions, 0x07), + CMN_EVENT_HNF(dir_snoops_sent, 0x08), + CMN_EVENT_HNF(brd_snoops_sent, 0x09), + CMN_EVENT_HNF(slc_eviction, 0x0a), + CMN_EVENT_HNF(slc_fill_invalid_way, 0x0b), + CMN_EVENT_HNF(mc_retries, 0x0c), + CMN_EVENT_HNF(mc_reqs, 0x0d), + CMN_EVENT_HNF(qos_hh_retry, 0x0e), + _CMN_EVENT_HNF(qos_pocq_occupancy_all, 0x0f, 0), + _CMN_EVENT_HNF(qos_pocq_occupancy_read, 0x0f, 1), + _CMN_EVENT_HNF(qos_pocq_occupancy_write, 0x0f, 2), + _CMN_EVENT_HNF(qos_pocq_occupancy_atomic, 0x0f, 3), + _CMN_EVENT_HNF(qos_pocq_occupancy_stash, 0x0f, 4), + CMN_EVENT_HNF(pocq_addrhaz, 0x10), + CMN_EVENT_HNF(pocq_atomic_addrhaz, 0x11), + CMN_EVENT_HNF(ld_st_swp_adq_full, 0x12), + CMN_EVENT_HNF(cmp_adq_full, 0x13), + CMN_EVENT_HNF(txdat_stall, 0x14), + CMN_EVENT_HNF(txrsp_stall, 0x15), + CMN_EVENT_HNF(seq_full, 0x16), + CMN_EVENT_HNF(seq_hit, 0x17), + CMN_EVENT_HNF(snp_sent, 0x18), + CMN_EVENT_HNF(sfbi_dir_snp_sent, 0x19), + CMN_EVENT_HNF(sfbi_brd_snp_sent, 0x1a), + CMN_EVENT_HNF(snp_sent_untrk, 0x1b), + CMN_EVENT_HNF(intv_dirty, 0x1c), + CMN_EVENT_HNF(stash_snp_sent, 0x1d), + CMN_EVENT_HNF(stash_data_pull, 0x1e), + CMN_EVENT_HNF(snp_fwded, 0x1f), + + CMN_EVENT_HNI(rrt_rd_occ_cnt_ovfl, 0x20), + CMN_EVENT_HNI(rrt_wr_occ_cnt_ovfl, 0x21), + CMN_EVENT_HNI(rdt_rd_occ_cnt_ovfl, 0x22), + CMN_EVENT_HNI(rdt_wr_occ_cnt_ovfl, 0x23), + CMN_EVENT_HNI(wdb_occ_cnt_ovfl, 0x24), + CMN_EVENT_HNI(rrt_rd_alloc, 0x25), + CMN_EVENT_HNI(rrt_wr_alloc, 0x26), + CMN_EVENT_HNI(rdt_rd_alloc, 0x27), + CMN_EVENT_HNI(rdt_wr_alloc, 0x28), + CMN_EVENT_HNI(wdb_alloc, 0x29), + CMN_EVENT_HNI(txrsp_retryack, 0x2a), + CMN_EVENT_HNI(arvalid_no_arready, 0x2b), + CMN_EVENT_HNI(arready_no_arvalid, 0x2c), + CMN_EVENT_HNI(awvalid_no_awready, 0x2d), + CMN_EVENT_HNI(awready_no_awvalid, 0x2e), + CMN_EVENT_HNI(wvalid_no_wready, 0x2f), + CMN_EVENT_HNI(txdat_stall, 0x30), + CMN_EVENT_HNI(nonpcie_serialization, 0x31), + CMN_EVENT_HNI(pcie_serialization, 0x32), + + CMN_EVENT_XP(txflit_valid, 0x01), + CMN_EVENT_XP(txflit_stall, 0x02), + CMN_EVENT_XP(partial_dat_flit, 0x03), + /* We treat watchpoints as a special made-up class of XP events */ + CMN_EVENT_ATTR(watchpoint_up, CMN_TYPE_WP, 0, 0), + CMN_EVENT_ATTR(watchpoint_down, CMN_TYPE_WP, 2, 0), + + CMN_EVENT_SBSX(rd_req, 0x01), + CMN_EVENT_SBSX(wr_req, 0x02), + CMN_EVENT_SBSX(cmo_req, 0x03), + CMN_EVENT_SBSX(txrsp_retryack, 0x04), + CMN_EVENT_SBSX(txdat_flitv, 0x05), + CMN_EVENT_SBSX(txrsp_flitv, 0x06), + CMN_EVENT_SBSX(rd_req_trkr_occ_cnt_ovfl, 0x11), + CMN_EVENT_SBSX(wr_req_trkr_occ_cnt_ovfl, 0x12), + CMN_EVENT_SBSX(cmo_req_trkr_occ_cnt_ovfl, 0x13), + CMN_EVENT_SBSX(wdb_occ_cnt_ovfl, 0x14), + CMN_EVENT_SBSX(rd_axi_trkr_occ_cnt_ovfl, 0x15), + CMN_EVENT_SBSX(cmo_axi_trkr_occ_cnt_ovfl, 0x16), + CMN_EVENT_SBSX(arvalid_no_arready, 0x21), + CMN_EVENT_SBSX(awvalid_no_awready, 0x22), + CMN_EVENT_SBSX(wvalid_no_wready, 0x23), + CMN_EVENT_SBSX(txdat_stall, 0x24), + CMN_EVENT_SBSX(txrsp_stall, 0x25), + + CMN_EVENT_RNID(s0_rdata_beats, 0x01), + CMN_EVENT_RNID(s1_rdata_beats, 0x02), + CMN_EVENT_RNID(s2_rdata_beats, 0x03), + CMN_EVENT_RNID(rxdat_flits, 0x04), + CMN_EVENT_RNID(txdat_flits, 0x05), + CMN_EVENT_RNID(txreq_flits_total, 0x06), + CMN_EVENT_RNID(txreq_flits_retried, 0x07), + CMN_EVENT_RNID(rrt_occ_ovfl, 0x08), + CMN_EVENT_RNID(wrt_occ_ovfl, 0x09), + CMN_EVENT_RNID(txreq_flits_replayed, 0x0a), + CMN_EVENT_RNID(wrcancel_sent, 0x0b), + CMN_EVENT_RNID(s0_wdata_beats, 0x0c), + CMN_EVENT_RNID(s1_wdata_beats, 0x0d), + CMN_EVENT_RNID(s2_wdata_beats, 0x0e), + CMN_EVENT_RNID(rrt_alloc, 0x0f), + CMN_EVENT_RNID(wrt_alloc, 0x10), + CMN_EVENT_RNID(rdb_unord, 0x11), + CMN_EVENT_RNID(rdb_replay, 0x12), + CMN_EVENT_RNID(rdb_hybrid, 0x13), + CMN_EVENT_RNID(rdb_ord, 0x14), + + NULL +}; + +static const struct attribute_group arm_cmn_event_attrs_group = { + .name = "events", + .attrs = arm_cmn_event_attrs, + .is_visible = arm_cmn_event_attr_is_visible, +}; + +static ssize_t arm_cmn_format_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct arm_cmn_format_attr *fmt = container_of(attr, typeof(*fmt), attr); + int lo = __ffs(fmt->field), hi = __fls(fmt->field); + + if (lo == hi) + return snprintf(buf, PAGE_SIZE, "config:%d\n", lo); + + if (!fmt->config) + return snprintf(buf, PAGE_SIZE, "config:%d-%d\n", lo, hi); + + return snprintf(buf, PAGE_SIZE, "config%d:%d-%d\n", fmt->config, lo, hi); +} + +#define _CMN_FORMAT_ATTR(_name, _cfg, _fld) \ + (&((struct arm_cmn_format_attr[]) {{ \ + .attr = __ATTR(_name, 0444, arm_cmn_format_show, NULL), \ + .config = _cfg, \ + .field = _fld, \ + }})[0].attr.attr) +#define CMN_FORMAT_ATTR(_name, _fld) _CMN_FORMAT_ATTR(_name, 0, _fld) + +static struct attribute *arm_cmn_format_attrs[] = { + CMN_FORMAT_ATTR(type, CMN_CONFIG_TYPE), + CMN_FORMAT_ATTR(eventid, CMN_CONFIG_EVENTID), + CMN_FORMAT_ATTR(occupid, CMN_CONFIG_OCCUPID), + CMN_FORMAT_ATTR(bynodeid, CMN_CONFIG_BYNODEID), + CMN_FORMAT_ATTR(nodeid, CMN_CONFIG_NODEID), + + CMN_FORMAT_ATTR(wp_dev_sel, CMN_CONFIG_WP_DEV_SEL), + CMN_FORMAT_ATTR(wp_chn_sel, CMN_CONFIG_WP_CHN_SEL), + CMN_FORMAT_ATTR(wp_grp, CMN_CONFIG_WP_GRP), + CMN_FORMAT_ATTR(wp_exclusive, CMN_CONFIG_WP_EXCLUSIVE), + CMN_FORMAT_ATTR(wp_combine, CMN_CONFIG_WP_COMBINE), + + _CMN_FORMAT_ATTR(wp_val, 1, CMN_CONFIG1_WP_VAL), + _CMN_FORMAT_ATTR(wp_mask, 2, CMN_CONFIG2_WP_MASK), + + NULL +}; + +static const struct attribute_group arm_cmn_format_attrs_group = { + .name = "format", + .attrs = arm_cmn_format_attrs, +}; + +static ssize_t arm_cmn_cpumask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev)); + + return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu)); +} + +static struct device_attribute arm_cmn_cpumask_attr = + __ATTR(cpumask, 0444, arm_cmn_cpumask_show, NULL); + +static struct attribute *arm_cmn_cpumask_attrs[] = { + &arm_cmn_cpumask_attr.attr, + NULL, +}; + +static struct attribute_group arm_cmn_cpumask_attr_group = { + .attrs = arm_cmn_cpumask_attrs, +}; + +static const struct attribute_group *arm_cmn_attr_groups[] = { + &arm_cmn_event_attrs_group, + &arm_cmn_format_attrs_group, + &arm_cmn_cpumask_attr_group, + NULL +}; + +static int arm_cmn_wp_idx(struct perf_event *event) +{ + return CMN_EVENT_EVENTID(event) + CMN_EVENT_WP_GRP(event); +} + +static u32 arm_cmn_wp_config(struct perf_event *event) +{ + u32 config; + u32 dev = CMN_EVENT_WP_DEV_SEL(event); + u32 chn = CMN_EVENT_WP_CHN_SEL(event); + u32 grp = CMN_EVENT_WP_GRP(event); + u32 exc = CMN_EVENT_WP_EXCLUSIVE(event); + u32 combine = CMN_EVENT_WP_COMBINE(event); + + config = FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL, dev) | + FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_CHN_SEL, chn) | + FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp) | + FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE, exc); + if (combine && !grp) + config |= CMN_DTM_WPn_CONFIG_WP_COMBINE; + + return config; +} + +static void arm_cmn_set_state(struct arm_cmn *cmn, u32 state) +{ + if (!cmn->state) + writel_relaxed(0, cmn->dtc[0].base + CMN_DT_PMCR); + cmn->state |= state; +} + +static void arm_cmn_clear_state(struct arm_cmn *cmn, u32 state) +{ + cmn->state &= ~state; + if (!cmn->state) + writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, + cmn->dtc[0].base + CMN_DT_PMCR); +} + +static void arm_cmn_pmu_enable(struct pmu *pmu) +{ + arm_cmn_clear_state(to_cmn(pmu), CMN_STATE_DISABLED); +} + +static void arm_cmn_pmu_disable(struct pmu *pmu) +{ + arm_cmn_set_state(to_cmn(pmu), CMN_STATE_DISABLED); +} + +static u64 arm_cmn_read_dtm(struct arm_cmn *cmn, struct arm_cmn_hw_event *hw, + bool snapshot) +{ + struct arm_cmn_node *dn; + unsigned int i, offset; + u64 count = 0; + + offset = snapshot ? CMN_DTM_PMEVCNTSR : CMN_DTM_PMEVCNT; + for_each_hw_dn(hw, dn, i) { + struct arm_cmn_node *xp = arm_cmn_node_to_xp(dn); + int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i); + u64 reg = readq_relaxed(xp->pmu_base + offset); + u16 dtm_count = reg >> (dtm_idx * 16); + + count += dtm_count; + } + return count; +} + +static u64 arm_cmn_read_cc(struct arm_cmn_dtc *dtc) +{ + u64 val = readq_relaxed(dtc->base + CMN_DT_PMCCNTR); + + writeq_relaxed(CMN_CC_INIT, dtc->base + CMN_DT_PMCCNTR); + return (val - CMN_CC_INIT) & ((CMN_CC_INIT << 1) - 1); +} + +static u32 arm_cmn_read_counter(struct arm_cmn_dtc *dtc, int idx) +{ + u32 val, pmevcnt = CMN_DT_PMEVCNT(idx); + + val = readl_relaxed(dtc->base + pmevcnt); + writel_relaxed(CMN_COUNTER_INIT, dtc->base + pmevcnt); + return val - CMN_COUNTER_INIT; +} + +static void arm_cmn_init_counter(struct perf_event *event) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + unsigned int i, pmevcnt = CMN_DT_PMEVCNT(hw->dtc_idx); + u64 count; + + for (i = 0; hw->dtcs_used & (1U << i); i++) { + writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + pmevcnt); + cmn->dtc[i].counters[hw->dtc_idx] = event; + } + + count = arm_cmn_read_dtm(cmn, hw, false); + local64_set(&event->hw.prev_count, count); +} + +static void arm_cmn_event_read(struct perf_event *event) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + u64 delta, new, prev; + unsigned long flags; + unsigned int i; + + if (hw->dtc_idx == CMN_DT_NUM_COUNTERS) { + i = __ffs(hw->dtcs_used); + delta = arm_cmn_read_cc(cmn->dtc + i); + local64_add(delta, &event->count); + return; + } + new = arm_cmn_read_dtm(cmn, hw, false); + prev = local64_xchg(&event->hw.prev_count, new); + + delta = new - prev; + + local_irq_save(flags); + for (i = 0; hw->dtcs_used & (1U << i); i++) { + new = arm_cmn_read_counter(cmn->dtc + i, hw->dtc_idx); + delta += new << 16; + } + local_irq_restore(flags); + local64_add(delta, &event->count); +} + +static void arm_cmn_event_start(struct perf_event *event, int flags) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + struct arm_cmn_node *dn; + enum cmn_node_type type = CMN_EVENT_TYPE(event); + int i; + + if (type == CMN_TYPE_DTC) { + i = __ffs(hw->dtcs_used); + writeq_relaxed(CMN_CC_INIT, cmn->dtc[i].base + CMN_DT_PMCCNTR); + cmn->dtc[i].cc_active = true; + } else if (type == CMN_TYPE_WP) { + int wp_idx = arm_cmn_wp_idx(event); + u64 val = CMN_EVENT_WP_VAL(event); + u64 mask = CMN_EVENT_WP_MASK(event); + + for_each_hw_dn(hw, dn, i) { + writeq_relaxed(val, dn->pmu_base + CMN_DTM_WPn_VAL(wp_idx)); + writeq_relaxed(mask, dn->pmu_base + CMN_DTM_WPn_MASK(wp_idx)); + } + } else for_each_hw_dn(hw, dn, i) { + int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i); + + dn->event[dtm_idx] = CMN_EVENT_EVENTID(event); + writel_relaxed(le32_to_cpu(dn->event_sel), dn->pmu_base + CMN_PMU_EVENT_SEL); + } +} + +static void arm_cmn_event_stop(struct perf_event *event, int flags) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + struct arm_cmn_node *dn; + enum cmn_node_type type = CMN_EVENT_TYPE(event); + int i; + + if (type == CMN_TYPE_DTC) { + i = __ffs(hw->dtcs_used); + cmn->dtc[i].cc_active = false; + } else if (type == CMN_TYPE_WP) { + int wp_idx = arm_cmn_wp_idx(event); + + for_each_hw_dn(hw, dn, i) { + writeq_relaxed(0, dn->pmu_base + CMN_DTM_WPn_MASK(wp_idx)); + writeq_relaxed(~0ULL, dn->pmu_base + CMN_DTM_WPn_VAL(wp_idx)); + } + } else for_each_hw_dn(hw, dn, i) { + int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i); + + dn->event[dtm_idx] = 0; + writel_relaxed(le32_to_cpu(dn->event_sel), dn->pmu_base + CMN_PMU_EVENT_SEL); + } + + arm_cmn_event_read(event); +} + +struct arm_cmn_val { + u8 dtm_count[CMN_MAX_XPS]; + u8 occupid[CMN_MAX_XPS]; + u8 wp[CMN_MAX_XPS][4]; + int dtc_count; + bool cycles; +}; + +static void arm_cmn_val_add_event(struct arm_cmn_val *val, struct perf_event *event) +{ + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + struct arm_cmn_node *dn; + enum cmn_node_type type; + int i; + u8 occupid; + + if (is_software_event(event)) + return; + + type = CMN_EVENT_TYPE(event); + if (type == CMN_TYPE_DTC) { + val->cycles = true; + return; + } + + val->dtc_count++; + if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event))) + occupid = CMN_EVENT_OCCUPID(event) + 1; + else + occupid = 0; + + for_each_hw_dn(hw, dn, i) { + int wp_idx, xp = arm_cmn_node_to_xp(dn)->logid; + + val->dtm_count[xp]++; + val->occupid[xp] = occupid; + + if (type != CMN_TYPE_WP) + continue; + + wp_idx = arm_cmn_wp_idx(event); + val->wp[xp][wp_idx] = CMN_EVENT_WP_COMBINE(event) + 1; + } +} + +static int arm_cmn_validate_group(struct perf_event *event) +{ + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + struct arm_cmn_node *dn; + struct perf_event *sibling, *leader = event->group_leader; + enum cmn_node_type type; + struct arm_cmn_val val; + int i; + u8 occupid; + + if (leader == event) + return 0; + + if (event->pmu != leader->pmu && !is_software_event(leader)) + return -EINVAL; + + memset(&val, 0, sizeof(val)); + + arm_cmn_val_add_event(&val, leader); + for_each_sibling_event(sibling, leader) + arm_cmn_val_add_event(&val, sibling); + + type = CMN_EVENT_TYPE(event); + if (type == CMN_TYPE_DTC) + return val.cycles ? -EINVAL : 0; + + if (val.dtc_count == CMN_DT_NUM_COUNTERS) + return -EINVAL; + + if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event))) + occupid = CMN_EVENT_OCCUPID(event) + 1; + else + occupid = 0; + + for_each_hw_dn(hw, dn, i) { + int wp_idx, wp_cmb, xp = arm_cmn_node_to_xp(dn)->logid; + + if (val.dtm_count[xp] == CMN_DTM_NUM_COUNTERS) + return -EINVAL; + + if (occupid && val.occupid[xp] && occupid != val.occupid[xp]) + return -EINVAL; + + if (type != CMN_TYPE_WP) + continue; + + wp_idx = arm_cmn_wp_idx(event); + if (val.wp[xp][wp_idx]) + return -EINVAL; + + wp_cmb = val.wp[xp][wp_idx ^ 1]; + if (wp_cmb && wp_cmb != CMN_EVENT_WP_COMBINE(event) + 1) + return -EINVAL; + } + + return 0; +} + +static int arm_cmn_event_init(struct perf_event *event) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + enum cmn_node_type type; + unsigned int i; + bool bynodeid; + u16 nodeid, eventid; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) + return -EINVAL; + + event->cpu = cmn->cpu; + if (event->cpu < 0) + return -EINVAL; + + type = CMN_EVENT_TYPE(event); + /* DTC events (i.e. cycles) already have everything they need */ + if (type == CMN_TYPE_DTC) + return 0; + + /* For watchpoints we need the actual XP node here */ + if (type == CMN_TYPE_WP) { + type = CMN_TYPE_XP; + /* ...and we need a "real" direction */ + eventid = CMN_EVENT_EVENTID(event); + if (eventid != CMN_WP_UP && eventid != CMN_WP_DOWN) + return -EINVAL; + } + + bynodeid = CMN_EVENT_BYNODEID(event); + nodeid = CMN_EVENT_NODEID(event); + + hw->dn = arm_cmn_node(cmn, type); + for (i = hw->dn - cmn->dns; i < cmn->num_dns && cmn->dns[i].type == type; i++) { + if (!bynodeid) { + hw->num_dns++; + } else if (cmn->dns[i].id != nodeid) { + hw->dn++; + } else { + hw->num_dns = 1; + break; + } + } + + if (!hw->num_dns) { + int bits = arm_cmn_xyidbits(cmn); + + dev_dbg(cmn->dev, "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n", + nodeid, CMN_NODEID_X(nodeid, bits), CMN_NODEID_Y(nodeid, bits), + CMN_NODEID_PID(nodeid), CMN_NODEID_DEVID(nodeid), type); + return -EINVAL; + } + /* + * By assuming events count in all DTC domains, we cunningly avoid + * needing to know anything about how XPs are assigned to domains. + */ + hw->dtcs_used = (1U << cmn->num_dtcs) - 1; + + return arm_cmn_validate_group(event); +} + +static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event, + int i) +{ + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + enum cmn_node_type type = CMN_EVENT_TYPE(event); + + while (i--) { + struct arm_cmn_node *xp = arm_cmn_node_to_xp(hw->dn + i); + unsigned int dtm_idx = arm_cmn_get_index(hw->dtm_idx, i); + + if (type == CMN_TYPE_WP) + hw->dn[i].wp_event[arm_cmn_wp_idx(event)] = -1; + + if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event))) + hw->dn[i].occupid_count--; + + xp->pmu_config_low &= ~CMN__PMEVCNT_PAIRED(dtm_idx); + writel_relaxed(xp->pmu_config_low, xp->pmu_base + CMN_DTM_PMU_CONFIG); + } + memset(hw->dtm_idx, 0, sizeof(hw->dtm_idx)); + + for (i = 0; hw->dtcs_used & (1U << i); i++) + cmn->dtc[i].counters[hw->dtc_idx] = NULL; +} + +static int arm_cmn_event_add(struct perf_event *event, int flags) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + struct arm_cmn_dtc *dtc = &cmn->dtc[0]; + struct arm_cmn_node *dn; + enum cmn_node_type type = CMN_EVENT_TYPE(event); + unsigned int i, dtc_idx, input_sel; + + if (type == CMN_TYPE_DTC) { + i = 0; + while (cmn->dtc[i].cycles) + if (++i == cmn->num_dtcs) + return -ENOSPC; + + cmn->dtc[i].cycles = event; + hw->dtc_idx = CMN_DT_NUM_COUNTERS; + hw->dtcs_used = 1U << i; + + if (flags & PERF_EF_START) + arm_cmn_event_start(event, 0); + return 0; + } + + /* Grab a free global counter first... */ + dtc_idx = 0; + while (dtc->counters[dtc_idx]) + if (++dtc_idx == CMN_DT_NUM_COUNTERS) + return -ENOSPC; + + hw->dtc_idx = dtc_idx; + + /* ...then the local counters to feed it. */ + for_each_hw_dn(hw, dn, i) { + struct arm_cmn_node *xp = arm_cmn_node_to_xp(dn); + unsigned int dtm_idx, shift; + u64 reg; + + dtm_idx = 0; + while (xp->pmu_config_low & CMN__PMEVCNT_PAIRED(dtm_idx)) + if (++dtm_idx == CMN_DTM_NUM_COUNTERS) + goto free_dtms; + + if (type == CMN_TYPE_XP) { + input_sel = CMN__PMEVCNT0_INPUT_SEL_XP + dtm_idx; + } else if (type == CMN_TYPE_WP) { + int tmp, wp_idx = arm_cmn_wp_idx(event); + u32 cfg = arm_cmn_wp_config(event); + + if (dn->wp_event[wp_idx] >= 0) + goto free_dtms; + + tmp = dn->wp_event[wp_idx ^ 1]; + if (tmp >= 0 && CMN_EVENT_WP_COMBINE(event) != + CMN_EVENT_WP_COMBINE(dtc->counters[tmp])) + goto free_dtms; + + input_sel = CMN__PMEVCNT0_INPUT_SEL_WP + wp_idx; + dn->wp_event[wp_idx] = dtc_idx; + writel_relaxed(cfg, dn->pmu_base + CMN_DTM_WPn_CONFIG(wp_idx)); + } else { + unsigned int port = CMN_NODEID_PID(dn->id); + unsigned int dev = CMN_NODEID_DEVID(dn->id); + + input_sel = CMN__PMEVCNT0_INPUT_SEL_DEV + dtm_idx + + (port << 4) + (dev << 2); + + if (arm_cmn_is_occup_event(type, CMN_EVENT_EVENTID(event))) { + int occupid = CMN_EVENT_OCCUPID(event); + + if (dn->occupid_count == 0) { + dn->occupid_val = occupid; + writel_relaxed(occupid, + dn->pmu_base + CMN_PMU_EVENT_SEL + 4); + } else if (dn->occupid_val != occupid) { + goto free_dtms; + } + dn->occupid_count++; + } + } + + arm_cmn_set_index(hw->dtm_idx, i, dtm_idx); + + xp->input_sel[dtm_idx] = input_sel; + shift = CMN__PMEVCNTn_GLOBAL_NUM_SHIFT(dtm_idx); + xp->pmu_config_low &= ~(CMN__PMEVCNT0_GLOBAL_NUM << shift); + xp->pmu_config_low |= FIELD_PREP(CMN__PMEVCNT0_GLOBAL_NUM, dtc_idx) << shift; + xp->pmu_config_low |= CMN__PMEVCNT_PAIRED(dtm_idx); + reg = (u64)le32_to_cpu(xp->pmu_config_high) << 32 | xp->pmu_config_low; + writeq_relaxed(reg, xp->pmu_base + CMN_DTM_PMU_CONFIG); + } + + /* Go go go! */ + arm_cmn_init_counter(event); + + if (flags & PERF_EF_START) + arm_cmn_event_start(event, 0); + + return 0; + +free_dtms: + arm_cmn_event_clear(cmn, event, i); + return -ENOSPC; +} + +static void arm_cmn_event_del(struct perf_event *event, int flags) +{ + struct arm_cmn *cmn = to_cmn(event->pmu); + struct arm_cmn_hw_event *hw = to_cmn_hw(event); + enum cmn_node_type type = CMN_EVENT_TYPE(event); + + arm_cmn_event_stop(event, PERF_EF_UPDATE); + + if (type == CMN_TYPE_DTC) + cmn->dtc[__ffs(hw->dtcs_used)].cycles = NULL; + else + arm_cmn_event_clear(cmn, event, hw->num_dns); +} + +/* + * We stop the PMU for both add and read, to avoid skew across DTM counters. + * In theory we could use snapshots to read without stopping, but then it + * becomes a lot trickier to deal with overlow and racing against interrupts, + * plus it seems they don't work properly on some hardware anyway :( + */ +static void arm_cmn_start_txn(struct pmu *pmu, unsigned int flags) +{ + arm_cmn_set_state(to_cmn(pmu), CMN_STATE_TXN); +} + +static void arm_cmn_end_txn(struct pmu *pmu) +{ + arm_cmn_clear_state(to_cmn(pmu), CMN_STATE_TXN); +} + +static int arm_cmn_commit_txn(struct pmu *pmu) +{ + arm_cmn_end_txn(pmu); + return 0; +} + +static int arm_cmn_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node) +{ + struct arm_cmn *cmn; + unsigned int i, target; + + cmn = hlist_entry_safe(node, struct arm_cmn, cpuhp_node); + if (cpu != cmn->cpu) + return 0; + + target = cpumask_any_but(cpu_online_mask, cpu); + if (target >= nr_cpu_ids) + return 0; + + perf_pmu_migrate_context(&cmn->pmu, cpu, target); + for (i = 0; i < cmn->num_dtcs; i++) + irq_set_affinity_hint(cmn->dtc[i].irq, cpumask_of(target)); + cmn->cpu = target; + return 0; +} + +static irqreturn_t arm_cmn_handle_irq(int irq, void *dev_id) +{ + struct arm_cmn_dtc *dtc = dev_id; + irqreturn_t ret = IRQ_NONE; + + for (;;) { + u32 status = readl_relaxed(dtc->base + CMN_DT_PMOVSR); + u64 delta; + int i; + + for (i = 0; i < CMN_DTM_NUM_COUNTERS; i++) { + if (status & (1U << i)) { + ret = IRQ_HANDLED; + if (WARN_ON(!dtc->counters[i])) + continue; + delta = (u64)arm_cmn_read_counter(dtc, i) << 16; + local64_add(delta, &dtc->counters[i]->count); + } + } + + if (status & (1U << CMN_DT_NUM_COUNTERS)) { + ret = IRQ_HANDLED; + if (dtc->cc_active && !WARN_ON(!dtc->cycles)) { + delta = arm_cmn_read_cc(dtc); + local64_add(delta, &dtc->cycles->count); + } + } + + writel_relaxed(status, dtc->base + CMN_DT_PMOVSR_CLR); + + if (!dtc->irq_friend) + return ret; + dtc += dtc->irq_friend; + } +} + +/* We can reasonably accommodate DTCs of the same CMN sharing IRQs */ +static int arm_cmn_init_irqs(struct arm_cmn *cmn) +{ + int i, j, irq, err; + + for (i = 0; i < cmn->num_dtcs; i++) { + irq = cmn->dtc[i].irq; + for (j = i; j--; ) { + if (cmn->dtc[j].irq == irq) { + cmn->dtc[j].irq_friend = j - i; + goto next; + } + } + err = devm_request_irq(cmn->dev, irq, arm_cmn_handle_irq, + IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED, + dev_name(cmn->dev), &cmn->dtc[i]); + if (err) + return err; + + err = irq_set_affinity_hint(irq, cpumask_of(cmn->cpu)); + if (err) + return err; + next: + ; /* isn't C great? */ + } + return 0; +} + +static void arm_cmn_init_dtm(struct arm_cmn_node *xp) +{ + int i; + + for (i = 0; i < 4; i++) { + xp->wp_event[i] = -1; + writeq_relaxed(0, xp->pmu_base + CMN_DTM_WPn_MASK(i)); + writeq_relaxed(~0ULL, xp->pmu_base + CMN_DTM_WPn_VAL(i)); + } + xp->pmu_config_low = CMN_DTM_PMU_CONFIG_PMU_EN; + xp->dtc = -1; +} + +static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int idx) +{ + struct arm_cmn_dtc *dtc = cmn->dtc + idx; + struct arm_cmn_node *xp; + + dtc->base = dn->pmu_base - CMN_PMU_OFFSET; + dtc->irq = platform_get_irq(to_platform_device(cmn->dev), idx); + if (dtc->irq < 0) + return dtc->irq; + + writel_relaxed(0, dtc->base + CMN_DT_PMCR); + writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR); + writel_relaxed(CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR); + + /* We do at least know that a DTC's XP must be in that DTC's domain */ + xp = arm_cmn_node_to_xp(dn); + xp->dtc = idx; + + return 0; +} + +static int arm_cmn_node_cmp(const void *a, const void *b) +{ + const struct arm_cmn_node *dna = a, *dnb = b; + int cmp; + + cmp = dna->type - dnb->type; + if (!cmp) + cmp = dna->logid - dnb->logid; + return cmp; +} + +static int arm_cmn_init_dtcs(struct arm_cmn *cmn) +{ + struct arm_cmn_node *dn; + int dtc_idx = 0; + + cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL); + if (!cmn->dtc) + return -ENOMEM; + + sort(cmn->dns, cmn->num_dns, sizeof(cmn->dns[0]), arm_cmn_node_cmp, NULL); + + cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP); + + for (dn = cmn->dns; dn < cmn->dns + cmn->num_dns; dn++) { + if (dn->type != CMN_TYPE_XP) + arm_cmn_init_node_to_xp(cmn, dn); + else if (cmn->num_dtcs == 1) + dn->dtc = 0; + + if (dn->type == CMN_TYPE_DTC) + arm_cmn_init_dtc(cmn, dn, dtc_idx++); + + /* To the PMU, RN-Ds don't add anything over RN-Is, so smoosh them together */ + if (dn->type == CMN_TYPE_RND) + dn->type = CMN_TYPE_RNI; + } + + writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL); + + return 0; +} + +static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node) +{ + int level; + u64 reg = readq_relaxed(cmn->base + offset + CMN_NODE_INFO); + + node->type = FIELD_GET(CMN_NI_NODE_TYPE, reg); + node->id = FIELD_GET(CMN_NI_NODE_ID, reg); + node->logid = FIELD_GET(CMN_NI_LOGICAL_ID, reg); + + node->pmu_base = cmn->base + offset + CMN_PMU_OFFSET; + + if (node->type == CMN_TYPE_CFG) + level = 0; + else if (node->type == CMN_TYPE_XP) + level = 1; + else + level = 2; + + dev_dbg(cmn->dev, "node%*c%#06hx%*ctype:%-#6hx id:%-4hd off:%#x\n", + (level * 2) + 1, ' ', node->id, 5 - (level * 2), ' ', + node->type, node->logid, offset); +} + +static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) +{ + void __iomem *cfg_region; + struct arm_cmn_node cfg, *dn; + u16 child_count, child_poff; + u32 xp_offset[CMN_MAX_XPS]; + u64 reg; + int i, j; + + cfg_region = cmn->base + rgn_offset; + reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_2); + cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg); + dev_dbg(cmn->dev, "periph_id_2 revision: %d\n", cmn->rev); + + arm_cmn_init_node_info(cmn, rgn_offset, &cfg); + if (cfg.type != CMN_TYPE_CFG) + return -ENODEV; + + reg = readq_relaxed(cfg_region + CMN_CHILD_INFO); + child_count = FIELD_GET(CMN_CI_CHILD_COUNT, reg); + child_poff = FIELD_GET(CMN_CI_CHILD_PTR_OFFSET, reg); + + cmn->num_xps = child_count; + cmn->num_dns = cmn->num_xps; + + /* Pass 1: visit the XPs, enumerate their children */ + for (i = 0; i < cmn->num_xps; i++) { + reg = readq_relaxed(cfg_region + child_poff + i * 8); + xp_offset[i] = reg & CMN_CHILD_NODE_ADDR; + + reg = readq_relaxed(cmn->base + xp_offset[i] + CMN_CHILD_INFO); + cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg); + } + + /* Cheeky +1 to help terminate pointer-based iteration */ + cmn->dns = devm_kcalloc(cmn->dev, cmn->num_dns + 1, + sizeof(*cmn->dns), GFP_KERNEL); + if (!cmn->dns) + return -ENOMEM; + + /* Pass 2: now we can actually populate the nodes */ + dn = cmn->dns; + for (i = 0; i < cmn->num_xps; i++) { + void __iomem *xp_region = cmn->base + xp_offset[i]; + struct arm_cmn_node *xp = dn++; + + arm_cmn_init_node_info(cmn, xp_offset[i], xp); + arm_cmn_init_dtm(xp); + /* + * Thanks to the order in which XP logical IDs seem to be + * assigned, we can handily infer the mesh X dimension by + * looking out for the XP at (0,1) without needing to know + * the exact node ID format, which we can later derive. + */ + if (xp->id == (1 << 3)) + cmn->mesh_x = xp->logid; + + reg = readq_relaxed(xp_region + CMN_CHILD_INFO); + child_count = FIELD_GET(CMN_CI_CHILD_COUNT, reg); + child_poff = FIELD_GET(CMN_CI_CHILD_PTR_OFFSET, reg); + + for (j = 0; j < child_count; j++) { + reg = readq_relaxed(xp_region + child_poff + j * 8); + /* + * Don't even try to touch anything external, since in general + * we haven't a clue how to power up arbitrary CHI requesters. + * As of CMN-600r1 these could only be RN-SAMs or CXLAs, + * neither of which have any PMU events anyway. + * (Actually, CXLAs do seem to have grown some events in r1p2, + * but they don't go to regular XP DTMs, and they depend on + * secure configuration which we can't easily deal with) + */ + if (reg & CMN_CHILD_NODE_EXTERNAL) { + dev_dbg(cmn->dev, "ignoring external node %llx\n", reg); + continue; + } + + arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn); + + switch (dn->type) { + case CMN_TYPE_DTC: + cmn->num_dtcs++; + dn++; + break; + /* These guys have PMU events */ + case CMN_TYPE_DVM: + case CMN_TYPE_HNI: + case CMN_TYPE_HNF: + case CMN_TYPE_SBSX: + case CMN_TYPE_RNI: + case CMN_TYPE_RND: + case CMN_TYPE_CXRA: + case CMN_TYPE_CXHA: + dn++; + break; + /* Nothing to see here */ + case CMN_TYPE_RNSAM: + case CMN_TYPE_CXLA: + break; + /* Something has gone horribly wrong */ + default: + dev_err(cmn->dev, "invalid device node type: 0x%hx\n", dn->type); + return -ENODEV; + } + } + } + + /* Correct for any nodes we skipped */ + cmn->num_dns = dn - cmn->dns; + + /* + * If mesh_x wasn't set during discovery then we never saw + * an XP at (0,1), thus we must have an Nx1 configuration. + */ + if (!cmn->mesh_x) + cmn->mesh_x = cmn->num_xps; + cmn->mesh_y = cmn->num_xps / cmn->mesh_x; + + dev_dbg(cmn->dev, "mesh %dx%d, ID width %d\n", + cmn->mesh_x, cmn->mesh_y, arm_cmn_xyidbits(cmn)); + + return 0; +} + +static int arm_cmn_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn) +{ + struct resource *cfg, *root; + + cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!cfg) + return -EINVAL; + + root = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!root) + return -EINVAL; + + if (!resource_contains(cfg, root)) + swap(cfg, root); + /* + * Note that devm_ioremap_resource() is dumb and won't let the platform + * device claim cfg when the ACPI companion device has already claimed + * root within it. But since they *are* already both claimed in the + * appropriate name, we don't really need to do it again here anyway. + */ + cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg)); + if (!cmn->base) + return -ENOMEM; + + return root->start - cfg->start; +} + +static int arm_cmn_of_probe(struct platform_device *pdev, struct arm_cmn *cmn) +{ + struct device_node *np = pdev->dev.of_node; + u32 rootnode; + int ret; + + cmn->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(cmn->base)) + return PTR_ERR(cmn->base); + + ret = of_property_read_u32(np, "arm,root-node", &rootnode); + if (ret) + return ret; + + return rootnode; +} + +static int arm_cmn_probe(struct platform_device *pdev) +{ + struct arm_cmn *cmn; + const char *name; + static atomic_t id; + int err, rootnode; + + cmn = devm_kzalloc(&pdev->dev, sizeof(*cmn), GFP_KERNEL); + if (!cmn) + return -ENOMEM; + + cmn->dev = &pdev->dev; + platform_set_drvdata(pdev, cmn); + + if (has_acpi_companion(cmn->dev)) + rootnode = arm_cmn_acpi_probe(pdev, cmn); + else + rootnode = arm_cmn_of_probe(pdev, cmn); + if (rootnode < 0) + return rootnode; + + err = arm_cmn_discover(cmn, rootnode); + if (err) + return err; + + err = arm_cmn_init_dtcs(cmn); + if (err) + return err; + + err = arm_cmn_init_irqs(cmn); + if (err) + return err; + + cmn->cpu = raw_smp_processor_id(); + cmn->pmu = (struct pmu) { + .module = THIS_MODULE, + .attr_groups = arm_cmn_attr_groups, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .task_ctx_nr = perf_invalid_context, + .pmu_enable = arm_cmn_pmu_enable, + .pmu_disable = arm_cmn_pmu_disable, + .event_init = arm_cmn_event_init, + .add = arm_cmn_event_add, + .del = arm_cmn_event_del, + .start = arm_cmn_event_start, + .stop = arm_cmn_event_stop, + .read = arm_cmn_event_read, + .start_txn = arm_cmn_start_txn, + .commit_txn = arm_cmn_commit_txn, + .cancel_txn = arm_cmn_end_txn, + }; + + name = devm_kasprintf(cmn->dev, GFP_KERNEL, "arm_cmn_%d", atomic_fetch_inc(&id)); + if (!name) + return -ENOMEM; + + err = cpuhp_state_add_instance(arm_cmn_hp_state, &cmn->cpuhp_node); + if (err) + return err; + + err = perf_pmu_register(&cmn->pmu, name, -1); + if (err) + cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node); + return err; +} + +static int arm_cmn_remove(struct platform_device *pdev) +{ + struct arm_cmn *cmn = platform_get_drvdata(pdev); + int i; + + writel_relaxed(0, cmn->dtc[0].base + CMN_DT_DTC_CTL); + + perf_pmu_unregister(&cmn->pmu); + cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node); + + for (i = 0; i < cmn->num_dtcs; i++) + irq_set_affinity_hint(cmn->dtc[i].irq, NULL); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id arm_cmn_of_match[] = { + { .compatible = "arm,cmn-600", }, + {} +}; +MODULE_DEVICE_TABLE(of, arm_cmn_of_match); +#endif + +#ifdef CONFIG_ACPI +static const struct acpi_device_id arm_cmn_acpi_match[] = { + { "ARMHC600", }, + {} +}; +MODULE_DEVICE_TABLE(acpi, arm_cmn_acpi_match); +#endif + +static struct platform_driver arm_cmn_driver = { + .driver = { + .name = "arm-cmn", + .of_match_table = of_match_ptr(arm_cmn_of_match), + .acpi_match_table = ACPI_PTR(arm_cmn_acpi_match), + }, + .probe = arm_cmn_probe, + .remove = arm_cmn_remove, +}; + +static int __init arm_cmn_init(void) +{ + int ret; + + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, + "perf/arm/cmn:online", NULL, + arm_cmn_pmu_offline_cpu); + if (ret < 0) + return ret; + + arm_cmn_hp_state = ret; + ret = platform_driver_register(&arm_cmn_driver); + if (ret) + cpuhp_remove_multi_state(arm_cmn_hp_state); + return ret; +} + +static void __exit arm_cmn_exit(void) +{ + platform_driver_unregister(&arm_cmn_driver); + cpuhp_remove_multi_state(arm_cmn_hp_state); +} + +module_init(arm_cmn_init); +module_exit(arm_cmn_exit); + +MODULE_AUTHOR("Robin Murphy "); +MODULE_DESCRIPTION("Arm CMN-600 PMU driver"); +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/perf/arm_dmc620_pmu.c +++ linux-oracle-5.4.0/drivers/perf/arm_dmc620_pmu.c @@ -0,0 +1,749 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * ARM DMC-620 memory controller PMU driver + * + * Copyright (C) 2020 Ampere Computing LLC. + */ + +#define DMC620_PMUNAME "arm_dmc620" +#define DMC620_DRVNAME DMC620_PMUNAME "_pmu" +#define pr_fmt(fmt) DMC620_DRVNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DMC620_PA_SHIFT 12 +#define DMC620_CNT_INIT 0x80000000 +#define DMC620_CNT_MAX_PERIOD 0xffffffff +#define DMC620_PMU_CLKDIV2_MAX_COUNTERS 8 +#define DMC620_PMU_CLK_MAX_COUNTERS 2 +#define DMC620_PMU_MAX_COUNTERS \ + (DMC620_PMU_CLKDIV2_MAX_COUNTERS + DMC620_PMU_CLK_MAX_COUNTERS) + +/* + * The PMU registers start at 0xA00 in the DMC-620 memory map, and these + * offsets are relative to that base. + * + * Each counter has a group of control/value registers, and the + * DMC620_PMU_COUNTERn offsets are within a counter group. + * + * The counter registers groups start at 0xA10. + */ +#define DMC620_PMU_OVERFLOW_STATUS_CLKDIV2 0x8 +#define DMC620_PMU_OVERFLOW_STATUS_CLKDIV2_MASK \ + (DMC620_PMU_CLKDIV2_MAX_COUNTERS - 1) +#define DMC620_PMU_OVERFLOW_STATUS_CLK 0xC +#define DMC620_PMU_OVERFLOW_STATUS_CLK_MASK \ + (DMC620_PMU_CLK_MAX_COUNTERS - 1) +#define DMC620_PMU_COUNTERS_BASE 0x10 +#define DMC620_PMU_COUNTERn_MASK_31_00 0x0 +#define DMC620_PMU_COUNTERn_MASK_63_32 0x4 +#define DMC620_PMU_COUNTERn_MATCH_31_00 0x8 +#define DMC620_PMU_COUNTERn_MATCH_63_32 0xC +#define DMC620_PMU_COUNTERn_CONTROL 0x10 +#define DMC620_PMU_COUNTERn_CONTROL_ENABLE BIT(0) +#define DMC620_PMU_COUNTERn_CONTROL_INVERT BIT(1) +#define DMC620_PMU_COUNTERn_CONTROL_EVENT_MUX GENMASK(6, 2) +#define DMC620_PMU_COUNTERn_CONTROL_INCR_MUX GENMASK(8, 7) +#define DMC620_PMU_COUNTERn_VALUE 0x20 +/* Offset of the registers for a given counter, relative to 0xA00 */ +#define DMC620_PMU_COUNTERn_OFFSET(n) \ + (DMC620_PMU_COUNTERS_BASE + 0x28 * (n)) + +static LIST_HEAD(dmc620_pmu_irqs); +static DEFINE_MUTEX(dmc620_pmu_irqs_lock); + +struct dmc620_pmu_irq { + struct hlist_node node; + struct list_head pmus_node; + struct list_head irqs_node; + refcount_t refcount; + unsigned int irq_num; + unsigned int cpu; +}; + +struct dmc620_pmu { + struct pmu pmu; + + void __iomem *base; + struct dmc620_pmu_irq *irq; + struct list_head pmus_node; + + /* + * We put all clkdiv2 and clk counters to a same array. + * The first DMC620_PMU_CLKDIV2_MAX_COUNTERS bits belong to + * clkdiv2 counters, the last DMC620_PMU_CLK_MAX_COUNTERS + * belong to clk counters. + */ + DECLARE_BITMAP(used_mask, DMC620_PMU_MAX_COUNTERS); + struct perf_event *events[DMC620_PMU_MAX_COUNTERS]; +}; + +#define to_dmc620_pmu(p) (container_of(p, struct dmc620_pmu, pmu)) + +static int cpuhp_state_num; + +struct dmc620_pmu_event_attr { + struct device_attribute attr; + u8 clkdiv2; + u8 eventid; +}; + +static ssize_t +dmc620_pmu_event_show(struct device *dev, + struct device_attribute *attr, char *page) +{ + struct dmc620_pmu_event_attr *eattr; + + eattr = container_of(attr, typeof(*eattr), attr); + + return sprintf(page, "event=0x%x,clkdiv2=0x%x\n", eattr->eventid, eattr->clkdiv2); +} + +#define DMC620_PMU_EVENT_ATTR(_name, _eventid, _clkdiv2) \ + (&((struct dmc620_pmu_event_attr[]) {{ \ + .attr = __ATTR(_name, 0444, dmc620_pmu_event_show, NULL), \ + .clkdiv2 = _clkdiv2, \ + .eventid = _eventid, \ + }})[0].attr.attr) + +static struct attribute *dmc620_pmu_events_attrs[] = { + /* clkdiv2 events list */ + DMC620_PMU_EVENT_ATTR(clkdiv2_cycle_count, 0x0, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_allocate, 0x1, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_queue_depth, 0x2, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_waiting_for_wr_data, 0x3, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_read_backlog, 0x4, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_waiting_for_mi, 0x5, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_hazard_resolution, 0x6, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_enqueue, 0x7, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_arbitrate, 0x8, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_lrank_turnaround_activate, 0x9, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_prank_turnaround_activate, 0xa, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_read_depth, 0xb, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_write_depth, 0xc, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_highigh_qos_depth, 0xd, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_high_qos_depth, 0xe, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_medium_qos_depth, 0xf, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_low_qos_depth, 0x10, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_activate, 0x11, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_rdwr, 0x12, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_refresh, 0x13, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_training_request, 0x14, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_t_mac_tracker, 0x15, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_bk_fsm_tracker, 0x16, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_bk_open_tracker, 0x17, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_ranks_in_pwr_down, 0x18, 1), + DMC620_PMU_EVENT_ATTR(clkdiv2_ranks_in_sref, 0x19, 1), + + /* clk events list */ + DMC620_PMU_EVENT_ATTR(clk_cycle_count, 0x0, 0), + DMC620_PMU_EVENT_ATTR(clk_request, 0x1, 0), + DMC620_PMU_EVENT_ATTR(clk_upload_stall, 0x2, 0), + NULL, +}; + +static struct attribute_group dmc620_pmu_events_attr_group = { + .name = "events", + .attrs = dmc620_pmu_events_attrs, +}; + +/* User ABI */ +#define ATTR_CFG_FLD_mask_CFG config +#define ATTR_CFG_FLD_mask_LO 0 +#define ATTR_CFG_FLD_mask_HI 44 +#define ATTR_CFG_FLD_match_CFG config1 +#define ATTR_CFG_FLD_match_LO 0 +#define ATTR_CFG_FLD_match_HI 44 +#define ATTR_CFG_FLD_invert_CFG config2 +#define ATTR_CFG_FLD_invert_LO 0 +#define ATTR_CFG_FLD_invert_HI 0 +#define ATTR_CFG_FLD_incr_CFG config2 +#define ATTR_CFG_FLD_incr_LO 1 +#define ATTR_CFG_FLD_incr_HI 2 +#define ATTR_CFG_FLD_event_CFG config2 +#define ATTR_CFG_FLD_event_LO 3 +#define ATTR_CFG_FLD_event_HI 8 +#define ATTR_CFG_FLD_clkdiv2_CFG config2 +#define ATTR_CFG_FLD_clkdiv2_LO 9 +#define ATTR_CFG_FLD_clkdiv2_HI 9 + +#define __GEN_PMU_FORMAT_ATTR(cfg, lo, hi) \ + (lo) == (hi) ? #cfg ":" #lo "\n" : #cfg ":" #lo "-" #hi + +#define _GEN_PMU_FORMAT_ATTR(cfg, lo, hi) \ + __GEN_PMU_FORMAT_ATTR(cfg, lo, hi) + +#define GEN_PMU_FORMAT_ATTR(name) \ + PMU_FORMAT_ATTR(name, \ + _GEN_PMU_FORMAT_ATTR(ATTR_CFG_FLD_##name##_CFG, \ + ATTR_CFG_FLD_##name##_LO, \ + ATTR_CFG_FLD_##name##_HI)) + +#define _ATTR_CFG_GET_FLD(attr, cfg, lo, hi) \ + ((((attr)->cfg) >> lo) & GENMASK_ULL(hi - lo, 0)) + +#define ATTR_CFG_GET_FLD(attr, name) \ + _ATTR_CFG_GET_FLD(attr, \ + ATTR_CFG_FLD_##name##_CFG, \ + ATTR_CFG_FLD_##name##_LO, \ + ATTR_CFG_FLD_##name##_HI) + +GEN_PMU_FORMAT_ATTR(mask); +GEN_PMU_FORMAT_ATTR(match); +GEN_PMU_FORMAT_ATTR(invert); +GEN_PMU_FORMAT_ATTR(incr); +GEN_PMU_FORMAT_ATTR(event); +GEN_PMU_FORMAT_ATTR(clkdiv2); + +static struct attribute *dmc620_pmu_formats_attrs[] = { + &format_attr_mask.attr, + &format_attr_match.attr, + &format_attr_invert.attr, + &format_attr_incr.attr, + &format_attr_event.attr, + &format_attr_clkdiv2.attr, + NULL, +}; + +static struct attribute_group dmc620_pmu_format_attr_group = { + .name = "format", + .attrs = dmc620_pmu_formats_attrs, +}; + +static const struct attribute_group *dmc620_pmu_attr_groups[] = { + &dmc620_pmu_events_attr_group, + &dmc620_pmu_format_attr_group, + NULL, +}; + +static inline +u32 dmc620_pmu_creg_read(struct dmc620_pmu *dmc620_pmu, + unsigned int idx, unsigned int reg) +{ + return readl(dmc620_pmu->base + DMC620_PMU_COUNTERn_OFFSET(idx) + reg); +} + +static inline +void dmc620_pmu_creg_write(struct dmc620_pmu *dmc620_pmu, + unsigned int idx, unsigned int reg, u32 val) +{ + writel(val, dmc620_pmu->base + DMC620_PMU_COUNTERn_OFFSET(idx) + reg); +} + +static +unsigned int dmc620_event_to_counter_control(struct perf_event *event) +{ + struct perf_event_attr *attr = &event->attr; + unsigned int reg = 0; + + reg |= FIELD_PREP(DMC620_PMU_COUNTERn_CONTROL_INVERT, + ATTR_CFG_GET_FLD(attr, invert)); + reg |= FIELD_PREP(DMC620_PMU_COUNTERn_CONTROL_EVENT_MUX, + ATTR_CFG_GET_FLD(attr, event)); + reg |= FIELD_PREP(DMC620_PMU_COUNTERn_CONTROL_INCR_MUX, + ATTR_CFG_GET_FLD(attr, incr)); + + return reg; +} + +static int dmc620_get_event_idx(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + int idx, start_idx, end_idx; + + if (ATTR_CFG_GET_FLD(&event->attr, clkdiv2)) { + start_idx = 0; + end_idx = DMC620_PMU_CLKDIV2_MAX_COUNTERS; + } else { + start_idx = DMC620_PMU_CLKDIV2_MAX_COUNTERS; + end_idx = DMC620_PMU_MAX_COUNTERS; + } + + for (idx = start_idx; idx < end_idx; ++idx) { + if (!test_and_set_bit(idx, dmc620_pmu->used_mask)) + return idx; + } + + /* The counters are all in use. */ + return -EAGAIN; +} + +static inline +u64 dmc620_pmu_read_counter(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + + return dmc620_pmu_creg_read(dmc620_pmu, + event->hw.idx, DMC620_PMU_COUNTERn_VALUE); +} + +static void dmc620_pmu_event_update(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + u64 delta, prev_count, new_count; + + do { + /* We may also be called from the irq handler */ + prev_count = local64_read(&hwc->prev_count); + new_count = dmc620_pmu_read_counter(event); + } while (local64_cmpxchg(&hwc->prev_count, + prev_count, new_count) != prev_count); + delta = (new_count - prev_count) & DMC620_CNT_MAX_PERIOD; + local64_add(delta, &event->count); +} + +static void dmc620_pmu_event_set_period(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + + local64_set(&event->hw.prev_count, DMC620_CNT_INIT); + dmc620_pmu_creg_write(dmc620_pmu, + event->hw.idx, DMC620_PMU_COUNTERn_VALUE, DMC620_CNT_INIT); +} + +static void dmc620_pmu_enable_counter(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + u32 reg; + + reg = dmc620_event_to_counter_control(event) | DMC620_PMU_COUNTERn_CONTROL_ENABLE; + dmc620_pmu_creg_write(dmc620_pmu, + event->hw.idx, DMC620_PMU_COUNTERn_CONTROL, reg); +} + +static void dmc620_pmu_disable_counter(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + + dmc620_pmu_creg_write(dmc620_pmu, + event->hw.idx, DMC620_PMU_COUNTERn_CONTROL, 0); +} + +static irqreturn_t dmc620_pmu_handle_irq(int irq_num, void *data) +{ + struct dmc620_pmu_irq *irq = data; + struct dmc620_pmu *dmc620_pmu; + irqreturn_t ret = IRQ_NONE; + + rcu_read_lock(); + list_for_each_entry_rcu(dmc620_pmu, &irq->pmus_node, pmus_node) { + unsigned long status; + struct perf_event *event; + unsigned int idx; + + /* + * HW doesn't provide a control to atomically disable all counters. + * To prevent race condition (overflow happens while clearing status register), + * disable all events before continuing + */ + for (idx = 0; idx < DMC620_PMU_MAX_COUNTERS; idx++) { + event = dmc620_pmu->events[idx]; + if (!event) + continue; + dmc620_pmu_disable_counter(event); + } + + status = readl(dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLKDIV2); + status |= (readl(dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLK) << + DMC620_PMU_CLKDIV2_MAX_COUNTERS); + if (status) { + for_each_set_bit(idx, &status, + DMC620_PMU_MAX_COUNTERS) { + event = dmc620_pmu->events[idx]; + if (WARN_ON_ONCE(!event)) + continue; + dmc620_pmu_event_update(event); + dmc620_pmu_event_set_period(event); + } + + if (status & DMC620_PMU_OVERFLOW_STATUS_CLKDIV2_MASK) + writel(0, dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLKDIV2); + + if ((status >> DMC620_PMU_CLKDIV2_MAX_COUNTERS) & + DMC620_PMU_OVERFLOW_STATUS_CLK_MASK) + writel(0, dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLK); + } + + for (idx = 0; idx < DMC620_PMU_MAX_COUNTERS; idx++) { + event = dmc620_pmu->events[idx]; + if (!event) + continue; + if (!(event->hw.state & PERF_HES_STOPPED)) + dmc620_pmu_enable_counter(event); + } + + ret = IRQ_HANDLED; + } + rcu_read_unlock(); + + return ret; +} + +static struct dmc620_pmu_irq *__dmc620_pmu_get_irq(int irq_num) +{ + struct dmc620_pmu_irq *irq; + int ret; + + list_for_each_entry(irq, &dmc620_pmu_irqs, irqs_node) + if (irq->irq_num == irq_num && refcount_inc_not_zero(&irq->refcount)) + return irq; + + irq = kzalloc(sizeof(*irq), GFP_KERNEL); + if (!irq) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&irq->pmus_node); + + /* Pick one CPU to be the preferred one to use */ + irq->cpu = raw_smp_processor_id(); + refcount_set(&irq->refcount, 1); + + ret = request_irq(irq_num, dmc620_pmu_handle_irq, + IRQF_NOBALANCING | IRQF_NO_THREAD, + "dmc620-pmu", irq); + if (ret) + goto out_free_aff; + + ret = irq_set_affinity_hint(irq_num, cpumask_of(irq->cpu)); + if (ret) + goto out_free_irq; + + ret = cpuhp_state_add_instance_nocalls(cpuhp_state_num, &irq->node); + if (ret) + goto out_free_irq; + + irq->irq_num = irq_num; + list_add(&irq->irqs_node, &dmc620_pmu_irqs); + + return irq; + +out_free_irq: + free_irq(irq_num, irq); +out_free_aff: + kfree(irq); + return ERR_PTR(ret); +} + +static int dmc620_pmu_get_irq(struct dmc620_pmu *dmc620_pmu, int irq_num) +{ + struct dmc620_pmu_irq *irq; + + mutex_lock(&dmc620_pmu_irqs_lock); + irq = __dmc620_pmu_get_irq(irq_num); + mutex_unlock(&dmc620_pmu_irqs_lock); + + if (IS_ERR(irq)) + return PTR_ERR(irq); + + dmc620_pmu->irq = irq; + mutex_lock(&dmc620_pmu_irqs_lock); + list_add_rcu(&dmc620_pmu->pmus_node, &irq->pmus_node); + mutex_unlock(&dmc620_pmu_irqs_lock); + + return 0; +} + +static void dmc620_pmu_put_irq(struct dmc620_pmu *dmc620_pmu) +{ + struct dmc620_pmu_irq *irq = dmc620_pmu->irq; + + mutex_lock(&dmc620_pmu_irqs_lock); + list_del_rcu(&dmc620_pmu->pmus_node); + + if (!refcount_dec_and_test(&irq->refcount)) { + mutex_unlock(&dmc620_pmu_irqs_lock); + return; + } + + list_del(&irq->irqs_node); + mutex_unlock(&dmc620_pmu_irqs_lock); + + WARN_ON(irq_set_affinity_hint(irq->irq_num, NULL)); + free_irq(irq->irq_num, irq); + cpuhp_state_remove_instance_nocalls(cpuhp_state_num, &irq->node); + kfree(irq); +} + +static int dmc620_pmu_event_init(struct perf_event *event) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + struct hw_perf_event *hwc = &event->hw; + struct perf_event *sibling; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* + * DMC 620 PMUs are shared across all cpus and cannot + * support task bound and sampling events. + */ + if (is_sampling_event(event) || + event->attach_state & PERF_ATTACH_TASK) { + dev_dbg(dmc620_pmu->pmu.dev, + "Can't support per-task counters\n"); + return -EOPNOTSUPP; + } + + /* + * Many perf core operations (eg. events rotation) operate on a + * single CPU context. This is obvious for CPU PMUs, where one + * expects the same sets of events being observed on all CPUs, + * but can lead to issues for off-core PMUs, where each + * event could be theoretically assigned to a different CPU. To + * mitigate this, we enforce CPU assignment to one, selected + * processor. + */ + event->cpu = dmc620_pmu->irq->cpu; + if (event->cpu < 0) + return -EINVAL; + + /* + * We can't atomically disable all HW counters so only one event allowed, + * although software events are acceptable. + */ + if (event->group_leader != event && + !is_software_event(event->group_leader)) + return -EINVAL; + + for_each_sibling_event(sibling, event->group_leader) { + if (sibling != event && + !is_software_event(sibling)) + return -EINVAL; + } + + hwc->idx = -1; + return 0; +} + +static void dmc620_pmu_read(struct perf_event *event) +{ + dmc620_pmu_event_update(event); +} + +static void dmc620_pmu_start(struct perf_event *event, int flags) +{ + event->hw.state = 0; + dmc620_pmu_event_set_period(event); + dmc620_pmu_enable_counter(event); +} + +static void dmc620_pmu_stop(struct perf_event *event, int flags) +{ + if (event->hw.state & PERF_HES_STOPPED) + return; + + dmc620_pmu_disable_counter(event); + dmc620_pmu_event_update(event); + event->hw.state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; +} + +static int dmc620_pmu_add(struct perf_event *event, int flags) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + struct perf_event_attr *attr = &event->attr; + struct hw_perf_event *hwc = &event->hw; + int idx; + u64 reg; + + idx = dmc620_get_event_idx(event); + if (idx < 0) + return idx; + + hwc->idx = idx; + dmc620_pmu->events[idx] = event; + hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE; + + reg = ATTR_CFG_GET_FLD(attr, mask); + dmc620_pmu_creg_write(dmc620_pmu, + idx, DMC620_PMU_COUNTERn_MASK_31_00, lower_32_bits(reg)); + dmc620_pmu_creg_write(dmc620_pmu, + idx, DMC620_PMU_COUNTERn_MASK_63_32, upper_32_bits(reg)); + + reg = ATTR_CFG_GET_FLD(attr, match); + dmc620_pmu_creg_write(dmc620_pmu, + idx, DMC620_PMU_COUNTERn_MATCH_31_00, lower_32_bits(reg)); + dmc620_pmu_creg_write(dmc620_pmu, + idx, DMC620_PMU_COUNTERn_MATCH_63_32, upper_32_bits(reg)); + + if (flags & PERF_EF_START) + dmc620_pmu_start(event, PERF_EF_RELOAD); + + perf_event_update_userpage(event); + return 0; +} + +static void dmc620_pmu_del(struct perf_event *event, int flags) +{ + struct dmc620_pmu *dmc620_pmu = to_dmc620_pmu(event->pmu); + struct hw_perf_event *hwc = &event->hw; + int idx = hwc->idx; + + dmc620_pmu_stop(event, PERF_EF_UPDATE); + dmc620_pmu->events[idx] = NULL; + clear_bit(idx, dmc620_pmu->used_mask); + perf_event_update_userpage(event); +} + +static int dmc620_pmu_cpu_teardown(unsigned int cpu, + struct hlist_node *node) +{ + struct dmc620_pmu_irq *irq; + struct dmc620_pmu *dmc620_pmu; + unsigned int target; + + irq = hlist_entry_safe(node, struct dmc620_pmu_irq, node); + if (cpu != irq->cpu) + return 0; + + target = cpumask_any_but(cpu_online_mask, cpu); + if (target >= nr_cpu_ids) + return 0; + + /* We're only reading, but this isn't the place to be involving RCU */ + mutex_lock(&dmc620_pmu_irqs_lock); + list_for_each_entry(dmc620_pmu, &irq->pmus_node, pmus_node) + perf_pmu_migrate_context(&dmc620_pmu->pmu, irq->cpu, target); + mutex_unlock(&dmc620_pmu_irqs_lock); + + WARN_ON(irq_set_affinity_hint(irq->irq_num, cpumask_of(target))); + irq->cpu = target; + + return 0; +} + +static int dmc620_pmu_device_probe(struct platform_device *pdev) +{ + struct dmc620_pmu *dmc620_pmu; + struct resource *res; + char *name; + int irq_num; + int i, ret; + + dmc620_pmu = devm_kzalloc(&pdev->dev, + sizeof(struct dmc620_pmu), GFP_KERNEL); + if (!dmc620_pmu) + return -ENOMEM; + + platform_set_drvdata(pdev, dmc620_pmu); + + dmc620_pmu->pmu = (struct pmu) { + .module = THIS_MODULE, + .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .task_ctx_nr = perf_invalid_context, + .event_init = dmc620_pmu_event_init, + .add = dmc620_pmu_add, + .del = dmc620_pmu_del, + .start = dmc620_pmu_start, + .stop = dmc620_pmu_stop, + .read = dmc620_pmu_read, + .attr_groups = dmc620_pmu_attr_groups, + }; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dmc620_pmu->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(dmc620_pmu->base)) + return PTR_ERR(dmc620_pmu->base); + + /* Make sure device is reset before enabling interrupt */ + for (i = 0; i < DMC620_PMU_MAX_COUNTERS; i++) + dmc620_pmu_creg_write(dmc620_pmu, i, DMC620_PMU_COUNTERn_CONTROL, 0); + writel(0, dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLKDIV2); + writel(0, dmc620_pmu->base + DMC620_PMU_OVERFLOW_STATUS_CLK); + + irq_num = platform_get_irq(pdev, 0); + if (irq_num < 0) + return irq_num; + + ret = dmc620_pmu_get_irq(dmc620_pmu, irq_num); + if (ret) + return ret; + + name = devm_kasprintf(&pdev->dev, GFP_KERNEL, + "%s_%llx", DMC620_PMUNAME, + (u64)(res->start >> DMC620_PA_SHIFT)); + if (!name) { + dev_err(&pdev->dev, + "Create name failed, PMU @%pa\n", &res->start); + ret = -ENOMEM; + goto out_teardown_dev; + } + + ret = perf_pmu_register(&dmc620_pmu->pmu, name, -1); + if (ret) + goto out_teardown_dev; + + return 0; + +out_teardown_dev: + dmc620_pmu_put_irq(dmc620_pmu); + synchronize_rcu(); + return ret; +} + +static int dmc620_pmu_device_remove(struct platform_device *pdev) +{ + struct dmc620_pmu *dmc620_pmu = platform_get_drvdata(pdev); + + dmc620_pmu_put_irq(dmc620_pmu); + + /* perf will synchronise RCU before devres can free dmc620_pmu */ + perf_pmu_unregister(&dmc620_pmu->pmu); + + return 0; +} + +static const struct acpi_device_id dmc620_acpi_match[] = { + { "ARMHD620", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, dmc620_acpi_match); +static struct platform_driver dmc620_pmu_driver = { + .driver = { + .name = DMC620_DRVNAME, + .acpi_match_table = dmc620_acpi_match, + }, + .probe = dmc620_pmu_device_probe, + .remove = dmc620_pmu_device_remove, +}; + +static int __init dmc620_pmu_init(void) +{ + cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, + DMC620_DRVNAME, + NULL, + dmc620_pmu_cpu_teardown); + if (cpuhp_state_num < 0) + return cpuhp_state_num; + + return platform_driver_register(&dmc620_pmu_driver); +} + +static void __exit dmc620_pmu_exit(void) +{ + platform_driver_unregister(&dmc620_pmu_driver); + cpuhp_remove_multi_state(cpuhp_state_num); +} + +module_init(dmc620_pmu_init); +module_exit(dmc620_pmu_exit); + +MODULE_DESCRIPTION("Perf driver for the ARM DMC-620 memory controller"); +MODULE_AUTHOR("Tuan Phan #include #include #include @@ -603,18 +604,19 @@ } /** - * dsu_pmu_dt_get_cpus: Get the list of CPUs in the cluster. + * dsu_pmu_dt_get_cpus: Get the list of CPUs in the cluster + * from device tree. */ -static int dsu_pmu_dt_get_cpus(struct device_node *dev, cpumask_t *mask) +static int dsu_pmu_dt_get_cpus(struct device *dev, cpumask_t *mask) { int i = 0, n, cpu; struct device_node *cpu_node; - n = of_count_phandle_with_args(dev, "cpus", NULL); + n = of_count_phandle_with_args(dev->of_node, "cpus", NULL); if (n <= 0) return -ENODEV; for (; i < n; i++) { - cpu_node = of_parse_phandle(dev, "cpus", i); + cpu_node = of_parse_phandle(dev->of_node, "cpus", i); if (!cpu_node) break; cpu = of_cpu_node_to_id(cpu_node); @@ -631,6 +633,36 @@ return 0; } +/** + * dsu_pmu_acpi_get_cpus: Get the list of CPUs in the cluster + * from ACPI. + */ +static int dsu_pmu_acpi_get_cpus(struct device *dev, cpumask_t *mask) +{ +#ifdef CONFIG_ACPI + int cpu; + + /* + * A dsu pmu node is inside a cluster parent node along with cpu nodes. + * We need to find out all cpus that have the same parent with this pmu. + */ + for_each_possible_cpu(cpu) { + struct acpi_device *acpi_dev; + struct device *cpu_dev = get_cpu_device(cpu); + + if (!cpu_dev) + continue; + + acpi_dev = ACPI_COMPANION(cpu_dev); + if (acpi_dev && + acpi_dev->parent == ACPI_COMPANION(dev)->parent) + cpumask_set_cpu(cpu, mask); + } +#endif + + return 0; +} + /* * dsu_pmu_probe_pmu: Probe the PMU details on a CPU in the cluster. */ @@ -676,6 +708,7 @@ { int irq, rc; struct dsu_pmu *dsu_pmu; + struct fwnode_handle *fwnode = dev_fwnode(&pdev->dev); char *name; static atomic_t pmu_idx = ATOMIC_INIT(-1); @@ -683,7 +716,16 @@ if (IS_ERR(dsu_pmu)) return PTR_ERR(dsu_pmu); - rc = dsu_pmu_dt_get_cpus(pdev->dev.of_node, &dsu_pmu->associated_cpus); + if (IS_ERR_OR_NULL(fwnode)) + return -ENOENT; + + if (is_of_node(fwnode)) + rc = dsu_pmu_dt_get_cpus(&pdev->dev, &dsu_pmu->associated_cpus); + else if (is_acpi_device_node(fwnode)) + rc = dsu_pmu_acpi_get_cpus(&pdev->dev, &dsu_pmu->associated_cpus); + else + return -ENOENT; + if (rc) { dev_warn(&pdev->dev, "Failed to parse the CPUs\n"); return rc; @@ -700,7 +742,7 @@ if (!name) return -ENOMEM; rc = devm_request_irq(&pdev->dev, irq, dsu_pmu_handle_irq, - IRQF_NOBALANCING, name, dsu_pmu); + IRQF_NOBALANCING | IRQF_SHARED, name, dsu_pmu); if (rc) { dev_warn(&pdev->dev, "Failed to request IRQ %d\n", irq); return rc; @@ -754,11 +796,22 @@ { .compatible = "arm,dsu-pmu", }, {}, }; +MODULE_DEVICE_TABLE(of, dsu_pmu_of_match); + +#ifdef CONFIG_ACPI +static const struct acpi_device_id dsu_pmu_acpi_match[] = { + { "ARMHD500", 0}, + {}, +}; +MODULE_DEVICE_TABLE(acpi, dsu_pmu_acpi_match); +#endif static struct platform_driver dsu_pmu_driver = { .driver = { .name = DRVNAME, .of_match_table = of_match_ptr(dsu_pmu_of_match), + .acpi_match_table = ACPI_PTR(dsu_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = dsu_pmu_device_probe, .remove = dsu_pmu_device_remove, @@ -815,7 +868,11 @@ if (ret < 0) return ret; dsu_pmu_cpuhp_state = ret; - return platform_driver_register(&dsu_pmu_driver); + ret = platform_driver_register(&dsu_pmu_driver); + if (ret) + cpuhp_remove_multi_state(dsu_pmu_cpuhp_state); + + return ret; } static void __exit dsu_pmu_exit(void) @@ -827,7 +884,6 @@ module_init(dsu_pmu_init); module_exit(dsu_pmu_exit); -MODULE_DEVICE_TABLE(of, dsu_pmu_of_match); MODULE_DESCRIPTION("Perf driver for ARM DynamIQ Shared Unit"); MODULE_AUTHOR("Suzuki K Poulose "); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/perf/arm_pmu.c +++ linux-oracle-5.4.0/drivers/perf/arm_pmu.c @@ -322,6 +322,9 @@ if (!validate_event(event->pmu, &fake_pmu, leader)) return -EINVAL; + if (event == leader) + return 0; + for_each_sibling_event(sibling, leader) { if (!validate_event(event->pmu, &fake_pmu, sibling)) return -EINVAL; @@ -411,12 +414,7 @@ local64_set(&hwc->period_left, hwc->sample_period); } - if (event->group_leader != event) { - if (validate_group(event) != 0) - return -EINVAL; - } - - return 0; + return validate_group(event); } static int armpmu_event_init(struct perf_event *event) --- linux-oracle-5.4.0.orig/drivers/perf/arm_pmu_acpi.c +++ linux-oracle-5.4.0/drivers/perf/arm_pmu_acpi.c @@ -24,8 +24,6 @@ int gsi, trigger; gicc = acpi_cpu_get_madt_gicc(cpu); - if (WARN_ON(!gicc)) - return -EINVAL; gsi = gicc->performance_interrupt; @@ -64,11 +62,10 @@ int gsi; gicc = acpi_cpu_get_madt_gicc(cpu); - if (!gicc) - return; gsi = gicc->performance_interrupt; - acpi_unregister_gsi(gsi); + if (gsi) + acpi_unregister_gsi(gsi); } #if IS_ENABLED(CONFIG_ARM_SPE_PMU) --- linux-oracle-5.4.0.orig/drivers/perf/arm_pmu_platform.c +++ linux-oracle-5.4.0/drivers/perf/arm_pmu_platform.c @@ -118,7 +118,7 @@ if (num_irqs == 1) { int irq = platform_get_irq(pdev, 0); - if (irq && irq_is_percpu_devid(irq)) + if ((irq > 0) && irq_is_percpu_devid(irq)) return pmu_parse_percpu_irq(pmu, irq); } @@ -236,7 +236,7 @@ ret = armpmu_register(pmu); if (ret) - goto out_free; + goto out_free_irqs; return 0; --- linux-oracle-5.4.0.orig/drivers/perf/arm_smmuv3_pmu.c +++ linux-oracle-5.4.0/drivers/perf/arm_smmuv3_pmu.c @@ -95,6 +95,7 @@ #define SMMU_PMCG_PA_SHIFT 12 #define SMMU_PMCG_EVCNTR_RDONLY BIT(0) +#define SMMU_PMCG_HARDEN_DISABLE BIT(1) static int cpuhp_state_num; @@ -138,6 +139,20 @@ writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR); } +static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, + struct perf_event *event, int idx); + +static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu) +{ + struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); + unsigned int idx; + + for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) + smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx); + + smmu_pmu_enable(pmu); +} + static inline void smmu_pmu_disable(struct pmu *pmu) { struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); @@ -146,6 +161,22 @@ writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL); } +static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu) +{ + struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); + unsigned int idx; + + /* + * The global disable of PMU sometimes fail to stop the counting. + * Harden this by writing an invalid event type to each used counter + * to forcibly stop counting. + */ + for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) + writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx)); + + smmu_pmu_disable(pmu); +} + static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu, u32 idx, u64 value) { @@ -275,7 +306,7 @@ struct perf_event *event, int idx) { u32 span, sid; - unsigned int num_ctrs = smmu_pmu->num_counters; + unsigned int cur_idx, num_ctrs = smmu_pmu->num_counters; bool filter_en = !!get_filter_enable(event); span = filter_en ? get_filter_span(event) : @@ -283,17 +314,19 @@ sid = filter_en ? get_filter_stream_id(event) : SMMU_PMCG_DEFAULT_FILTER_SID; - /* Support individual filter settings */ - if (!smmu_pmu->global_filter) { + cur_idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); + /* + * Per-counter filtering, or scheduling the first globally-filtered + * event into an empty PMU so idx == 0 and it works out equivalent. + */ + if (!smmu_pmu->global_filter || cur_idx == num_ctrs) { smmu_pmu_set_event_filter(event, idx, span, sid); return 0; } - /* Requested settings same as current global settings*/ - idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); - if (idx == num_ctrs || - smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) { - smmu_pmu_set_event_filter(event, 0, span, sid); + /* Otherwise, must match whatever's currently scheduled */ + if (smmu_pmu_check_global_filter(smmu_pmu->events[cur_idx], event)) { + smmu_pmu_set_evtyper(smmu_pmu, idx, get_event(event)); return 0; } @@ -717,7 +750,10 @@ switch (model) { case IORT_SMMU_V3_PMCG_HISI_HIP08: /* HiSilicon Erratum 162001800 */ - smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY; + smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE; + break; + case IORT_SMMU_V3_PMCG_HISI_HIP09: + smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE; break; } @@ -742,6 +778,7 @@ platform_set_drvdata(pdev, smmu_pmu); smmu_pmu->pmu = (struct pmu) { + .module = THIS_MODULE, .task_ctx_nr = perf_invalid_context, .pmu_enable = smmu_pmu_enable, .pmu_disable = smmu_pmu_disable, @@ -772,7 +809,7 @@ smmu_pmu->reloc_base = smmu_pmu->reg_base; } - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq > 0) smmu_pmu->irq = irq; @@ -805,6 +842,16 @@ smmu_pmu_get_acpi_options(smmu_pmu); + /* + * For platforms suffer this quirk, the PMU disable sometimes fails to + * stop the counters. This will leads to inaccurate or error counting. + * Forcibly disable the counters with these quirk handler. + */ + if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) { + smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09; + smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09; + } + /* Pick one CPU to be the preferred one to use */ smmu_pmu->on_cpu = raw_smp_processor_id(); WARN_ON(irq_set_affinity_hint(smmu_pmu->irq, @@ -815,7 +862,7 @@ if (err) { dev_err(dev, "Error %d registering hotplug, PMU @%pa\n", err, &res_0->start); - goto out_cpuhp_err; + goto out_clear_affinity; } err = perf_pmu_register(&smmu_pmu->pmu, name, -1); @@ -834,8 +881,8 @@ out_unregister: cpuhp_state_remove_instance_nocalls(cpuhp_state_num, &smmu_pmu->node); -out_cpuhp_err: - put_cpu(); +out_clear_affinity: + irq_set_affinity_hint(smmu_pmu->irq, NULL); return err; } @@ -845,6 +892,7 @@ perf_pmu_unregister(&smmu_pmu->pmu); cpuhp_state_remove_instance_nocalls(cpuhp_state_num, &smmu_pmu->node); + irq_set_affinity_hint(smmu_pmu->irq, NULL); return 0; } @@ -859,6 +907,7 @@ static struct platform_driver smmu_pmu_driver = { .driver = { .name = "arm-smmu-v3-pmcg", + .suppress_bind_attrs = true, }, .probe = smmu_pmu_probe, .remove = smmu_pmu_remove, @@ -867,6 +916,8 @@ static int __init arm_smmu_pmu_init(void) { + int ret; + cpuhp_state_num = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "perf/arm/pmcg:online", NULL, @@ -874,7 +925,11 @@ if (cpuhp_state_num < 0) return cpuhp_state_num; - return platform_driver_register(&smmu_pmu_driver); + ret = platform_driver_register(&smmu_pmu_driver); + if (ret) + cpuhp_remove_multi_state(cpuhp_state_num); + + return ret; } module_init(arm_smmu_pmu_init); --- linux-oracle-5.4.0.orig/drivers/perf/arm_spe_pmu.c +++ linux-oracle-5.4.0/drivers/perf/arm_spe_pmu.c @@ -1228,6 +1228,7 @@ .driver = { .name = DRVNAME, .of_match_table = of_match_ptr(arm_spe_pmu_of_match), + .suppress_bind_attrs = true, }, .probe = arm_spe_pmu_device_probe, .remove = arm_spe_pmu_device_remove, --- linux-oracle-5.4.0.orig/drivers/perf/fsl_imx8_ddr_perf.c +++ linux-oracle-5.4.0/drivers/perf/fsl_imx8_ddr_perf.c @@ -29,7 +29,7 @@ #define CNTL_OVER_MASK 0xFFFFFFFE #define CNTL_CSV_SHIFT 24 -#define CNTL_CSV_MASK (0xFF << CNTL_CSV_SHIFT) +#define CNTL_CSV_MASK (0xFFU << CNTL_CSV_SHIFT) #define EVENT_CYCLES_ID 0 #define EVENT_CYCLES_COUNTER 0 @@ -45,7 +45,8 @@ static DEFINE_IDA(ddr_ida); /* DDR Perf hardware feature */ -#define DDR_CAP_AXI_ID_FILTER 0x1 /* support AXI ID filter */ +#define DDR_CAP_AXI_ID_FILTER 0x1 /* support AXI ID filter */ +#define DDR_CAP_AXI_ID_FILTER_ENHANCED 0x3 /* support enhanced AXI ID filter */ struct fsl_ddr_devtype_data { unsigned int quirks; /* quirks needed for different DDR Perf core */ @@ -76,6 +77,7 @@ const struct fsl_ddr_devtype_data *devtype_data; int irq; int id; + int active_counter; }; static ssize_t ddr_perf_cpumask_show(struct device *dev, @@ -178,6 +180,36 @@ NULL, }; +static bool ddr_perf_is_filtered(struct perf_event *event) +{ + return event->attr.config == 0x41 || event->attr.config == 0x42; +} + +static u32 ddr_perf_filter_val(struct perf_event *event) +{ + return event->attr.config1; +} + +static bool ddr_perf_filters_compatible(struct perf_event *a, + struct perf_event *b) +{ + if (!ddr_perf_is_filtered(a)) + return true; + if (!ddr_perf_is_filtered(b)) + return true; + return ddr_perf_filter_val(a) == ddr_perf_filter_val(b); +} + +static bool ddr_perf_is_enhanced_filtered(struct perf_event *event) +{ + unsigned int filt; + struct ddr_pmu *pmu = to_ddr_pmu(event->pmu); + + filt = pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED; + return (filt == DDR_CAP_AXI_ID_FILTER_ENHANCED) && + ddr_perf_is_filtered(event); +} + static u32 ddr_perf_alloc_counter(struct ddr_pmu *pmu, int event) { int i; @@ -209,27 +241,17 @@ static u32 ddr_perf_read_counter(struct ddr_pmu *pmu, int counter) { - return readl_relaxed(pmu->base + COUNTER_READ + counter * 4); -} + struct perf_event *event = pmu->events[counter]; + void __iomem *base = pmu->base; -static bool ddr_perf_is_filtered(struct perf_event *event) -{ - return event->attr.config == 0x41 || event->attr.config == 0x42; -} - -static u32 ddr_perf_filter_val(struct perf_event *event) -{ - return event->attr.config1; -} - -static bool ddr_perf_filters_compatible(struct perf_event *a, - struct perf_event *b) -{ - if (!ddr_perf_is_filtered(a)) - return true; - if (!ddr_perf_is_filtered(b)) - return true; - return ddr_perf_filter_val(a) == ddr_perf_filter_val(b); + /* + * return bytes instead of bursts from ddr transaction for + * axid-read and axid-write event if PMU core supports enhanced + * filter. + */ + base += ddr_perf_is_enhanced_filtered(event) ? COUNTER_DPCR1 : + COUNTER_READ; + return readl_relaxed(base + counter * 4); } static int ddr_perf_event_init(struct perf_event *event) @@ -306,9 +328,10 @@ if (enable) { /* - * must disable first, then enable again - * otherwise, cycle counter will not work - * if previous state is enabled. + * cycle counter is special which should firstly write 0 then + * write 1 into CLEAR bit to clear it. Other counters only + * need write 0 into CLEAR bit and it turns out to be 1 by + * hardware. Below enable flow is harmless for all counters. */ writel(0, pmu->base + reg); val = CNTL_EN | CNTL_CLEAR; @@ -316,7 +339,8 @@ writel(val, pmu->base + reg); } else { /* Disable counter */ - writel(0, pmu->base + reg); + val = readl_relaxed(pmu->base + reg) & CNTL_EN_MASK; + writel(val, pmu->base + reg); } } @@ -330,6 +354,10 @@ ddr_perf_counter_enable(pmu, event->attr.config, counter, true); + if (!pmu->active_counter++) + ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, + EVENT_CYCLES_COUNTER, true); + hwc->state = 0; } @@ -384,6 +412,10 @@ ddr_perf_counter_enable(pmu, event->attr.config, counter, false); ddr_perf_event_update(event); + if (!--pmu->active_counter) + ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, + EVENT_CYCLES_COUNTER, false); + hwc->state |= PERF_HES_STOPPED; } @@ -402,25 +434,10 @@ static void ddr_perf_pmu_enable(struct pmu *pmu) { - struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); - - /* enable cycle counter if cycle is not active event list */ - if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) - ddr_perf_counter_enable(ddr_pmu, - EVENT_CYCLES_ID, - EVENT_CYCLES_COUNTER, - true); } static void ddr_perf_pmu_disable(struct pmu *pmu) { - struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); - - if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) - ddr_perf_counter_enable(ddr_pmu, - EVENT_CYCLES_ID, - EVENT_CYCLES_COUNTER, - false); } static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base, @@ -428,6 +445,7 @@ { *pmu = (struct ddr_pmu) { .pmu = (struct pmu) { + .module = THIS_MODULE, .capabilities = PERF_PMU_CAP_NO_EXCLUDE, .task_ctx_nr = perf_invalid_context, .attr_groups = attr_groups, @@ -538,8 +556,10 @@ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d", num); - if (!name) - return -ENOMEM; + if (!name) { + ret = -ENOMEM; + goto cpuhp_state_err; + } pmu->devtype_data = of_device_get_match_data(&pdev->dev); @@ -551,13 +571,17 @@ if (ret < 0) { dev_err(&pdev->dev, "cpuhp_setup_state_multi failed\n"); - goto ddr_perf_err; + goto cpuhp_state_err; } pmu->cpuhp_state = ret; /* Register the pmu instance for cpu hotplug */ - cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node); + ret = cpuhp_state_add_instance_nocalls(pmu->cpuhp_state, &pmu->node); + if (ret) { + dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); + goto cpuhp_instance_err; + } /* Request irq */ irq = of_irq_get(np, 0); @@ -591,9 +615,10 @@ return 0; ddr_perf_err: - if (pmu->cpuhp_state) - cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node); - + cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node); +cpuhp_instance_err: + cpuhp_remove_multi_state(pmu->cpuhp_state); +cpuhp_state_err: ida_simple_remove(&ddr_ida, pmu->id); dev_warn(&pdev->dev, "i.MX8 DDR Perf PMU failed (%d), disabled\n", ret); return ret; @@ -604,6 +629,7 @@ struct ddr_pmu *pmu = platform_get_drvdata(pdev); cpuhp_state_remove_instance_nocalls(pmu->cpuhp_state, &pmu->node); + cpuhp_remove_multi_state(pmu->cpuhp_state); irq_set_affinity_hint(pmu->irq, NULL); perf_pmu_unregister(&pmu->pmu); @@ -616,6 +642,7 @@ .driver = { .name = "imx-ddr-pmu", .of_match_table = imx_ddr_pmu_dt_ids, + .suppress_bind_attrs = true, }, .probe = ddr_perf_probe, .remove = ddr_perf_remove, --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/Kconfig +++ linux-oracle-5.4.0/drivers/perf/hisilicon/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +config HISI_PMU + tristate "HiSilicon SoC PMU drivers" + depends on ARM64 && ACPI + help + Support for HiSilicon SoC L3 Cache performance monitor, Hydra Home + Agent performance monitor and DDR Controller performance monitor. --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/Makefile +++ linux-oracle-5.4.0/drivers/perf/hisilicon/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o +obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \ + hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c +++ linux-oracle-5.4.0/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c @@ -381,6 +381,7 @@ ddrc_pmu->sccl_id, ddrc_pmu->index_id); ddrc_pmu->pmu = (struct pmu) { .name = name, + .module = THIS_MODULE, .task_ctx_nr = perf_invalid_context, .event_init = hisi_uncore_pmu_event_init, .pmu_enable = hisi_uncore_pmu_enable, @@ -397,8 +398,9 @@ ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1); if (ret) { dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n"); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, - &ddrc_pmu->node); + cpuhp_state_remove_instance_nocalls( + CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node); + irq_set_affinity_hint(ddrc_pmu->irq, NULL); } return ret; @@ -409,8 +411,9 @@ struct hisi_pmu *ddrc_pmu = platform_get_drvdata(pdev); perf_pmu_unregister(&ddrc_pmu->pmu); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, - &ddrc_pmu->node); + cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, + &ddrc_pmu->node); + irq_set_affinity_hint(ddrc_pmu->irq, NULL); return 0; } @@ -419,6 +422,7 @@ .driver = { .name = "hisi_ddrc_pmu", .acpi_match_table = ACPI_PTR(hisi_ddrc_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = hisi_ddrc_pmu_probe, .remove = hisi_ddrc_pmu_remove, --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c +++ linux-oracle-5.4.0/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c @@ -285,7 +285,7 @@ HISI_PMU_EVENT_ATTR(rx_wbip, 0x05), HISI_PMU_EVENT_ATTR(rx_wtistash, 0x11), HISI_PMU_EVENT_ATTR(rd_ddr_64b, 0x1c), - HISI_PMU_EVENT_ATTR(wr_dr_64b, 0x1d), + HISI_PMU_EVENT_ATTR(wr_ddr_64b, 0x1d), HISI_PMU_EVENT_ATTR(rd_ddr_128b, 0x1e), HISI_PMU_EVENT_ATTR(wr_ddr_128b, 0x1f), HISI_PMU_EVENT_ATTR(spill_num, 0x20), @@ -392,6 +392,7 @@ hha_pmu->sccl_id, hha_pmu->index_id); hha_pmu->pmu = (struct pmu) { .name = name, + .module = THIS_MODULE, .task_ctx_nr = perf_invalid_context, .event_init = hisi_uncore_pmu_event_init, .pmu_enable = hisi_uncore_pmu_enable, @@ -408,8 +409,9 @@ ret = perf_pmu_register(&hha_pmu->pmu, name, -1); if (ret) { dev_err(hha_pmu->dev, "HHA PMU register failed!\n"); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, - &hha_pmu->node); + cpuhp_state_remove_instance_nocalls( + CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node); + irq_set_affinity_hint(hha_pmu->irq, NULL); } return ret; @@ -420,8 +422,9 @@ struct hisi_pmu *hha_pmu = platform_get_drvdata(pdev); perf_pmu_unregister(&hha_pmu->pmu); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, - &hha_pmu->node); + cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, + &hha_pmu->node); + irq_set_affinity_hint(hha_pmu->irq, NULL); return 0; } @@ -430,6 +433,7 @@ .driver = { .name = "hisi_hha_pmu", .acpi_match_table = ACPI_PTR(hisi_hha_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = hisi_hha_pmu_probe, .remove = hisi_hha_pmu_remove, --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c +++ linux-oracle-5.4.0/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c @@ -35,7 +35,7 @@ /* L3C has 8-counters */ #define L3C_NR_COUNTERS 0x8 -#define L3C_PERF_CTRL_EN 0x20000 +#define L3C_PERF_CTRL_EN 0x10000 #define L3C_EVTYPE_NONE 0xff /* @@ -382,6 +382,7 @@ l3c_pmu->sccl_id, l3c_pmu->index_id); l3c_pmu->pmu = (struct pmu) { .name = name, + .module = THIS_MODULE, .task_ctx_nr = perf_invalid_context, .event_init = hisi_uncore_pmu_event_init, .pmu_enable = hisi_uncore_pmu_enable, @@ -398,8 +399,9 @@ ret = perf_pmu_register(&l3c_pmu->pmu, name, -1); if (ret) { dev_err(l3c_pmu->dev, "L3C PMU register failed!\n"); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, - &l3c_pmu->node); + cpuhp_state_remove_instance_nocalls( + CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node); + irq_set_affinity_hint(l3c_pmu->irq, NULL); } return ret; @@ -410,8 +412,9 @@ struct hisi_pmu *l3c_pmu = platform_get_drvdata(pdev); perf_pmu_unregister(&l3c_pmu->pmu); - cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, - &l3c_pmu->node); + cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, + &l3c_pmu->node); + irq_set_affinity_hint(l3c_pmu->irq, NULL); return 0; } @@ -420,6 +423,7 @@ .driver = { .name = "hisi_l3c_pmu", .acpi_match_table = ACPI_PTR(hisi_l3c_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = hisi_l3c_pmu_probe, .remove = hisi_l3c_pmu_remove, --- linux-oracle-5.4.0.orig/drivers/perf/hisilicon/hisi_uncore_pmu.c +++ linux-oracle-5.4.0/drivers/perf/hisilicon/hisi_uncore_pmu.c @@ -34,6 +34,7 @@ return sprintf(buf, "%s\n", (char *)eattr->var); } +EXPORT_SYMBOL_GPL(hisi_format_sysfs_show); /* * PMU event attributes @@ -47,6 +48,7 @@ return sprintf(page, "config=0x%lx\n", (unsigned long)eattr->var); } +EXPORT_SYMBOL_GPL(hisi_event_sysfs_show); /* * sysfs cpumask attributes. For uncore PMU, we only have a single CPU to show @@ -58,6 +60,7 @@ return sprintf(buf, "%d\n", hisi_pmu->on_cpu); } +EXPORT_SYMBOL_GPL(hisi_cpumask_sysfs_show); static bool hisi_validate_event_group(struct perf_event *event) { @@ -96,6 +99,7 @@ { return idx >= 0 && idx < hisi_pmu->num_counters; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_counter_valid); int hisi_uncore_pmu_get_event_idx(struct perf_event *event) { @@ -112,6 +116,7 @@ return idx; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx); static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx) { @@ -172,6 +177,7 @@ return 0; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_init); /* * Set the counter to count the event that we're interested in, @@ -219,6 +225,7 @@ /* Write start value to the hardware event counter */ hisi_pmu->ops->write_counter(hisi_pmu, hwc, val); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_set_event_period); void hisi_uncore_pmu_event_update(struct perf_event *event) { @@ -239,6 +246,7 @@ HISI_MAX_PERIOD(hisi_pmu->counter_bits); local64_add(delta, &event->count); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_event_update); void hisi_uncore_pmu_start(struct perf_event *event, int flags) { @@ -261,6 +269,7 @@ hisi_uncore_pmu_enable_event(event); perf_event_update_userpage(event); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_start); void hisi_uncore_pmu_stop(struct perf_event *event, int flags) { @@ -277,6 +286,7 @@ hisi_uncore_pmu_event_update(event); hwc->state |= PERF_HES_UPTODATE; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_stop); int hisi_uncore_pmu_add(struct perf_event *event, int flags) { @@ -299,6 +309,7 @@ return 0; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_add); void hisi_uncore_pmu_del(struct perf_event *event, int flags) { @@ -310,12 +321,14 @@ perf_event_update_userpage(event); hisi_pmu->pmu_events.hw_events[hwc->idx] = NULL; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_del); void hisi_uncore_pmu_read(struct perf_event *event) { /* Read hardware counter and update the perf counter statistics */ hisi_uncore_pmu_event_update(event); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read); void hisi_uncore_pmu_enable(struct pmu *pmu) { @@ -328,6 +341,7 @@ hisi_pmu->ops->start_counters(hisi_pmu); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_enable); void hisi_uncore_pmu_disable(struct pmu *pmu) { @@ -335,6 +349,7 @@ hisi_pmu->ops->stop_counters(hisi_pmu); } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_disable); /* * Read Super CPU cluster and CPU cluster ID from MPIDR_EL1. @@ -398,10 +413,11 @@ hisi_pmu->on_cpu = cpu; /* Overflow interrupt also should use the same CPU */ - WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu))); + WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(cpu))); return 0; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_online_cpu); int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node) { @@ -430,7 +446,10 @@ perf_pmu_migrate_context(&hisi_pmu->pmu, cpu, target); /* Use this CPU for event counting */ hisi_pmu->on_cpu = target; - WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(target))); + WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(target))); return 0; } +EXPORT_SYMBOL_GPL(hisi_uncore_pmu_offline_cpu); + +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/perf/qcom_l2_pmu.c +++ linux-oracle-5.4.0/drivers/perf/qcom_l2_pmu.c @@ -781,7 +781,7 @@ { u64 mpidr; int cpu_cluster_id; - struct cluster_pmu *cluster = NULL; + struct cluster_pmu *cluster; /* * This assumes that the cluster_id is in MPIDR[aff1] for @@ -803,10 +803,10 @@ cluster->cluster_id); cpumask_set_cpu(cpu, &cluster->cluster_cpus); *per_cpu_ptr(l2cache_pmu->pmu_cluster, cpu) = cluster; - break; + return cluster; } - return cluster; + return NULL; } static int l2cache_pmu_online_cpu(unsigned int cpu, struct hlist_node *node) @@ -1028,6 +1028,7 @@ .driver = { .name = "qcom-l2cache-pmu", .acpi_match_table = ACPI_PTR(l2_cache_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = l2_cache_pmu_probe, .remove = l2_cache_pmu_remove, --- linux-oracle-5.4.0.orig/drivers/perf/qcom_l3_pmu.c +++ linux-oracle-5.4.0/drivers/perf/qcom_l3_pmu.c @@ -814,6 +814,7 @@ .driver = { .name = "qcom-l3cache-pmu", .acpi_match_table = ACPI_PTR(qcom_l3_cache_pmu_acpi_match), + .suppress_bind_attrs = true, }, .probe = qcom_l3_cache_pmu_probe, }; --- linux-oracle-5.4.0.orig/drivers/perf/thunderx2_pmu.c +++ linux-oracle-5.4.0/drivers/perf/thunderx2_pmu.c @@ -627,14 +627,17 @@ list_for_each_entry(rentry, &list, node) { if (resource_type(rentry->res) == IORESOURCE_MEM) { res = *rentry->res; + rentry = NULL; break; } } + acpi_dev_free_resource_list(&list); - if (!rentry->res) + if (rentry) { + dev_err(dev, "PMU type %d: Fail to find resource\n", type); return NULL; + } - acpi_dev_free_resource_list(&list); base = devm_ioremap_resource(dev, &res); if (IS_ERR(base)) { dev_err(dev, "PMU type %d: Fail to map resource\n", type); @@ -816,6 +819,7 @@ .driver = { .name = "tx2-uncore-pmu", .acpi_match_table = ACPI_PTR(tx2_uncore_acpi_match), + .suppress_bind_attrs = true, }, .probe = tx2_uncore_probe, .remove = tx2_uncore_remove, --- linux-oracle-5.4.0.orig/drivers/perf/xgene_pmu.c +++ linux-oracle-5.4.0/drivers/perf/xgene_pmu.c @@ -1459,17 +1459,6 @@ } #if defined(CONFIG_ACPI) -static int acpi_pmu_dev_add_resource(struct acpi_resource *ares, void *data) -{ - struct resource *res = data; - - if (ares->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) - acpi_dev_resource_memory(ares, res); - - /* Always tell the ACPI core to skip this resource */ - return 1; -} - static struct xgene_pmu_dev_ctx *acpi_get_pmu_hw_inf(struct xgene_pmu *xgene_pmu, struct acpi_device *adev, u32 type) @@ -1481,6 +1470,7 @@ struct hw_pmu_info *inf; void __iomem *dev_csr; struct resource res; + struct resource_entry *rentry; int enable_bit; int rc; @@ -1489,11 +1479,23 @@ return NULL; INIT_LIST_HEAD(&resource_list); - rc = acpi_dev_get_resources(adev, &resource_list, - acpi_pmu_dev_add_resource, &res); + rc = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); + if (rc <= 0) { + dev_err(dev, "PMU type %d: No resources found\n", type); + return NULL; + } + + list_for_each_entry(rentry, &resource_list, node) { + if (resource_type(rentry->res) == IORESOURCE_MEM) { + res = *rentry->res; + rentry = NULL; + break; + } + } acpi_dev_free_resource_list(&resource_list); - if (rc < 0) { - dev_err(dev, "PMU type %d: No resource address found\n", type); + + if (rentry) { + dev_err(dev, "PMU type %d: No memory resource found\n", type); return NULL; } @@ -1981,6 +1983,7 @@ .name = "xgene-pmu", .of_match_table = xgene_pmu_of_match, .acpi_match_table = ACPI_PTR(xgene_pmu_acpi_match), + .suppress_bind_attrs = true, }, }; --- linux-oracle-5.4.0.orig/drivers/phy/allwinner/phy-sun4i-usb.c +++ linux-oracle-5.4.0/drivers/phy/allwinner/phy-sun4i-usb.c @@ -545,13 +545,14 @@ struct sun4i_usb_phy_data *data = container_of(work, struct sun4i_usb_phy_data, detect.work); struct phy *phy0 = data->phys[0].phy; - struct sun4i_usb_phy *phy = phy_get_drvdata(phy0); + struct sun4i_usb_phy *phy; bool force_session_end, id_notify = false, vbus_notify = false; int id_det, vbus_det; - if (phy0 == NULL) + if (!phy0) return; + phy = phy_get_drvdata(phy0); id_det = sun4i_usb_phy0_get_id_det(data); vbus_det = sun4i_usb_phy0_get_vbus_det(data); --- linux-oracle-5.4.0.orig/drivers/phy/broadcom/phy-bcm-sr-usb.c +++ linux-oracle-5.4.0/drivers/phy/broadcom/phy-bcm-sr-usb.c @@ -16,8 +16,6 @@ }; enum bcm_usb_phy_reg { - PLL_NDIV_FRAC, - PLL_NDIV_INT, PLL_CTRL, PHY_CTRL, PHY_PLL_CTRL, @@ -31,18 +29,11 @@ }; static const u8 bcm_usb_combo_phy_hs[] = { - [PLL_NDIV_FRAC] = 0x04, - [PLL_NDIV_INT] = 0x08, [PLL_CTRL] = 0x0c, [PHY_CTRL] = 0x10, }; -#define HSPLL_NDIV_INT_VAL 0x13 -#define HSPLL_NDIV_FRAC_VAL 0x1005 - static const u8 bcm_usb_hs_phy[] = { - [PLL_NDIV_FRAC] = 0x0, - [PLL_NDIV_INT] = 0x4, [PLL_CTRL] = 0x8, [PHY_CTRL] = 0xc, }; @@ -52,7 +43,6 @@ SSPLL_SUSPEND_EN, PLL_SEQ_START, PLL_LOCK, - PLL_PDIV, }; static const u8 u3pll_ctrl[] = { @@ -66,29 +56,17 @@ #define HSPLL_PDIV_VAL 0x1 static const u8 u2pll_ctrl[] = { - [PLL_PDIV] = 1, [PLL_RESETB] = 5, [PLL_LOCK] = 6, }; enum bcm_usb_phy_ctrl_bits { CORERDY, - AFE_LDO_PWRDWNB, - AFE_PLL_PWRDWNB, - AFE_BG_PWRDWNB, - PHY_ISO, PHY_RESETB, PHY_PCTL, }; #define PHY_PCTL_MASK 0xffff -/* - * 0x0806 of PCTL_VAL has below bits set - * BIT-8 : refclk divider 1 - * BIT-3:2: device mode; mode is not effect - * BIT-1: soft reset active low - */ -#define HSPHY_PCTL_VAL 0x0806 #define SSPHY_PCTL_VAL 0x0006 static const u8 u3phy_ctrl[] = { @@ -98,10 +76,6 @@ static const u8 u2phy_ctrl[] = { [CORERDY] = 0, - [AFE_LDO_PWRDWNB] = 1, - [AFE_PLL_PWRDWNB] = 2, - [AFE_BG_PWRDWNB] = 3, - [PHY_ISO] = 4, [PHY_RESETB] = 5, [PHY_PCTL] = 6, }; @@ -186,38 +160,13 @@ int ret = 0; void __iomem *regs = phy_cfg->regs; const u8 *offset; - u32 rd_data; offset = phy_cfg->offset; - writel(HSPLL_NDIV_INT_VAL, regs + offset[PLL_NDIV_INT]); - writel(HSPLL_NDIV_FRAC_VAL, regs + offset[PLL_NDIV_FRAC]); - - rd_data = readl(regs + offset[PLL_CTRL]); - rd_data &= ~(HSPLL_PDIV_MASK << u2pll_ctrl[PLL_PDIV]); - rd_data |= (HSPLL_PDIV_VAL << u2pll_ctrl[PLL_PDIV]); - writel(rd_data, regs + offset[PLL_CTRL]); - - /* Set Core Ready high */ - bcm_usb_reg32_setbits(regs + offset[PHY_CTRL], - BIT(u2phy_ctrl[CORERDY])); - - /* Maximum timeout for Core Ready done */ - msleep(30); - + bcm_usb_reg32_clrbits(regs + offset[PLL_CTRL], + BIT(u2pll_ctrl[PLL_RESETB])); bcm_usb_reg32_setbits(regs + offset[PLL_CTRL], BIT(u2pll_ctrl[PLL_RESETB])); - bcm_usb_reg32_setbits(regs + offset[PHY_CTRL], - BIT(u2phy_ctrl[PHY_RESETB])); - - - rd_data = readl(regs + offset[PHY_CTRL]); - rd_data &= ~(PHY_PCTL_MASK << u2phy_ctrl[PHY_PCTL]); - rd_data |= (HSPHY_PCTL_VAL << u2phy_ctrl[PHY_PCTL]); - writel(rd_data, regs + offset[PHY_CTRL]); - - /* Maximum timeout for PLL reset done */ - msleep(30); ret = bcm_usb_pll_lock_check(regs + offset[PLL_CTRL], BIT(u2pll_ctrl[PLL_LOCK])); --- linux-oracle-5.4.0.orig/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +++ linux-oracle-5.4.0/drivers/phy/hisilicon/phy-hisi-inno-usb2.c @@ -155,7 +155,7 @@ phy_set_drvdata(phy, &priv->ports[i]); i++; - if (i > INNO_PHY_PORT_NUM) { + if (i >= INNO_PHY_PORT_NUM) { dev_warn(dev, "Support %d ports in maximum\n", i); break; } --- linux-oracle-5.4.0.orig/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c +++ linux-oracle-5.4.0/drivers/phy/lantiq/phy-lantiq-vrx200-pcie.c @@ -323,7 +323,8 @@ goto err_disable_pdi_clk; /* Check if we are in "startup ready" status */ - if (ltq_vrx200_pcie_phy_wait_for_pll(phy) != 0) + ret = ltq_vrx200_pcie_phy_wait_for_pll(phy); + if (ret) goto err_disable_phy_clk; ltq_vrx200_pcie_phy_apply_workarounds(phy); --- linux-oracle-5.4.0.orig/drivers/phy/marvell/Kconfig +++ linux-oracle-5.4.0/drivers/phy/marvell/Kconfig @@ -3,8 +3,8 @@ # Phy drivers for Marvell platforms # config ARMADA375_USBCLUSTER_PHY - def_bool y - depends on MACH_ARMADA_375 || COMPILE_TEST + bool "Armada 375 USB cluster PHY support" if COMPILE_TEST + default y if MACH_ARMADA_375 depends on OF && HAS_IOMEM select GENERIC_PHY --- linux-oracle-5.4.0.orig/drivers/phy/marvell/phy-armada38x-comphy.c +++ linux-oracle-5.4.0/drivers/phy/marvell/phy-armada38x-comphy.c @@ -41,6 +41,7 @@ struct a38x_comphy { void __iomem *base; + void __iomem *conf; struct device *dev; struct a38x_comphy_lane lane[MAX_A38X_COMPHY]; }; @@ -54,6 +55,21 @@ { 0, 0, 3 }, }; +static void a38x_set_conf(struct a38x_comphy_lane *lane, bool enable) +{ + struct a38x_comphy *priv = lane->priv; + u32 conf; + + if (priv->conf) { + conf = readl_relaxed(priv->conf); + if (enable) + conf |= BIT(lane->port); + else + conf &= ~BIT(lane->port); + writel(conf, priv->conf); + } +} + static void a38x_comphy_set_reg(struct a38x_comphy_lane *lane, unsigned int offset, u32 mask, u32 value) { @@ -97,6 +113,7 @@ { struct a38x_comphy_lane *lane = phy_get_drvdata(phy); unsigned int gen; + int ret; if (mode != PHY_MODE_ETHERNET) return -EINVAL; @@ -115,13 +132,20 @@ return -EINVAL; } + a38x_set_conf(lane, false); + a38x_comphy_set_speed(lane, gen, gen); - return a38x_comphy_poll(lane, COMPHY_STAT1, - COMPHY_STAT1_PLL_RDY_TX | - COMPHY_STAT1_PLL_RDY_RX, - COMPHY_STAT1_PLL_RDY_TX | - COMPHY_STAT1_PLL_RDY_RX); + ret = a38x_comphy_poll(lane, COMPHY_STAT1, + COMPHY_STAT1_PLL_RDY_TX | + COMPHY_STAT1_PLL_RDY_RX, + COMPHY_STAT1_PLL_RDY_TX | + COMPHY_STAT1_PLL_RDY_RX); + + if (ret == 0) + a38x_set_conf(lane, true); + + return ret; } static const struct phy_ops a38x_comphy_ops = { @@ -174,14 +198,21 @@ if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); priv->dev = &pdev->dev; priv->base = base; + /* Optional */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "conf"); + if (res) { + priv->conf = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->conf)) + return PTR_ERR(priv->conf); + } + for_each_available_child_of_node(pdev->dev.of_node, child) { struct phy *phy; int ret; --- linux-oracle-5.4.0.orig/drivers/phy/marvell/phy-mvebu-a3700-comphy.c +++ linux-oracle-5.4.0/drivers/phy/marvell/phy-mvebu-a3700-comphy.c @@ -26,7 +26,6 @@ #define COMPHY_SIP_POWER_ON 0x82000001 #define COMPHY_SIP_POWER_OFF 0x82000002 #define COMPHY_SIP_PLL_LOCK 0x82000003 -#define COMPHY_FW_NOT_SUPPORTED (-1) #define COMPHY_FW_MODE_SATA 0x1 #define COMPHY_FW_MODE_SGMII 0x2 @@ -112,10 +111,19 @@ unsigned long mode) { struct arm_smccc_res res; + s32 ret; arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); + ret = res.a0; - return res.a0; + switch (ret) { + case SMCCC_RET_SUCCESS: + return 0; + case SMCCC_RET_NOT_SUPPORTED: + return -EOPNOTSUPP; + default: + return -EINVAL; + } } static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, @@ -220,7 +228,7 @@ } ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); - if (ret == COMPHY_FW_NOT_SUPPORTED) + if (ret == -EOPNOTSUPP) dev_err(lane->dev, "unsupported SMC call, try updating your firmware\n"); --- linux-oracle-5.4.0.orig/drivers/phy/marvell/phy-mvebu-cp110-comphy.c +++ linux-oracle-5.4.0/drivers/phy/marvell/phy-mvebu-cp110-comphy.c @@ -123,7 +123,6 @@ #define COMPHY_SIP_POWER_ON 0x82000001 #define COMPHY_SIP_POWER_OFF 0x82000002 -#define COMPHY_FW_NOT_SUPPORTED (-1) /* * A lane is described by the following bitfields: @@ -273,10 +272,19 @@ unsigned long lane, unsigned long mode) { struct arm_smccc_res res; + s32 ret; arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res); + ret = res.a0; - return res.a0; + switch (ret) { + case SMCCC_RET_SUCCESS: + return 0; + case SMCCC_RET_NOT_SUPPORTED: + return -EOPNOTSUPP; + default: + return -EINVAL; + } } static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, @@ -819,7 +827,7 @@ if (!ret) return ret; - if (ret == COMPHY_FW_NOT_SUPPORTED) + if (ret == -EOPNOTSUPP) dev_err(priv->dev, "unsupported SMC call, try updating your firmware\n"); --- linux-oracle-5.4.0.orig/drivers/phy/motorola/phy-cpcap-usb.c +++ linux-oracle-5.4.0/drivers/phy/motorola/phy-cpcap-usb.c @@ -115,7 +115,7 @@ enum cpcap_gpio_mode { CPCAP_DM_DP, CPCAP_MDM_RX_TX, - CPCAP_UNKNOWN, + CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */ CPCAP_OTG_DM_DP, }; @@ -207,6 +207,19 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata); static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata); +static void cpcap_usb_try_musb_mailbox(struct cpcap_phy_ddata *ddata, + enum musb_vbus_id_status status) +{ + int error; + + error = musb_mailbox(status); + if (!error) + return; + + dev_dbg(ddata->dev, "%s: musb_mailbox failed: %i\n", + __func__, error); +} + static void cpcap_usb_detect(struct work_struct *work) { struct cpcap_phy_ddata *ddata; @@ -226,9 +239,7 @@ if (error) goto out_err; - error = musb_mailbox(MUSB_ID_GROUND); - if (error) - goto out_err; + cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, CPCAP_BIT_VBUSSTBY_EN | @@ -257,9 +268,7 @@ error = cpcap_usb_set_usb_mode(ddata); if (error) goto out_err; - error = musb_mailbox(MUSB_ID_GROUND); - if (error) - goto out_err; + cpcap_usb_try_musb_mailbox(ddata, MUSB_ID_GROUND); return; } @@ -269,22 +278,18 @@ error = cpcap_usb_set_usb_mode(ddata); if (error) goto out_err; - error = musb_mailbox(MUSB_VBUS_VALID); - if (error) - goto out_err; + cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_VALID); return; } + cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); + /* Default to debug UART mode */ error = cpcap_usb_set_uart_mode(ddata); if (error) goto out_err; - error = musb_mailbox(MUSB_VBUS_OFF); - if (error) - goto out_err; - dev_dbg(ddata->dev, "set UART mode\n"); return; @@ -376,7 +381,8 @@ { int error; - error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP); + /* Disable lines to prevent glitches from waking up mdm6600 */ + error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); if (error) goto out_err; @@ -403,6 +409,11 @@ if (error) goto out_err; + /* Enable UART mode */ + error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP); + if (error) + goto out_err; + return 0; out_err: @@ -415,7 +426,8 @@ { int error; - error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP); + /* Disable lines to prevent glitches from waking up mdm6600 */ + error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED); if (error) return error; @@ -455,6 +467,11 @@ if (error) goto out_err; + /* Enable USB mode */ + error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP); + if (error) + goto out_err; + return 0; out_err: @@ -608,35 +625,42 @@ generic_phy = devm_phy_create(ddata->dev, NULL, &ops); if (IS_ERR(generic_phy)) { error = PTR_ERR(generic_phy); - return PTR_ERR(generic_phy); + goto out_reg_disable; } phy_set_drvdata(generic_phy, ddata); phy_provider = devm_of_phy_provider_register(ddata->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); + if (IS_ERR(phy_provider)) { + error = PTR_ERR(phy_provider); + goto out_reg_disable; + } error = cpcap_usb_init_optional_pins(ddata); if (error) - return error; + goto out_reg_disable; cpcap_usb_init_optional_gpios(ddata); error = cpcap_usb_init_iio(ddata); if (error) - return error; + goto out_reg_disable; error = cpcap_usb_init_interrupts(pdev, ddata); if (error) - return error; + goto out_reg_disable; usb_add_phy_dev(&ddata->phy); atomic_set(&ddata->active, 1); schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1)); return 0; + +out_reg_disable: + regulator_disable(ddata->vusb); + + return error; } static int cpcap_usb_phy_remove(struct platform_device *pdev) @@ -649,9 +673,7 @@ if (error) dev_err(ddata->dev, "could not set UART mode\n"); - error = musb_mailbox(MUSB_VBUS_OFF); - if (error) - dev_err(ddata->dev, "could not set mailbox\n"); + cpcap_usb_try_musb_mailbox(ddata, MUSB_VBUS_OFF); usb_remove_phy(&ddata->phy); cancel_delayed_work_sync(&ddata->detect_work); --- linux-oracle-5.4.0.orig/drivers/phy/motorola/phy-mapphone-mdm6600.c +++ linux-oracle-5.4.0/drivers/phy/motorola/phy-mapphone-mdm6600.c @@ -20,6 +20,7 @@ #define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */ #define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */ +#define PHY_MDM6600_WAKE_KICK_MS 600 /* time on after GPIO toggle */ #define MDM6600_MODEM_IDLE_DELAY_MS 1000 /* modem after USB suspend */ #define MDM6600_MODEM_WAKE_DELAY_MS 200 /* modem response after idle */ @@ -121,16 +122,10 @@ { struct phy_mdm6600 *ddata = phy_get_drvdata(x); struct gpio_desc *enable_gpio = ddata->ctrl_gpios[PHY_MDM6600_ENABLE]; - int error; if (!ddata->enabled) return -ENODEV; - error = pinctrl_pm_select_default_state(ddata->dev); - if (error) - dev_warn(ddata->dev, "%s: error with default_state: %i\n", - __func__, error); - gpiod_set_value_cansleep(enable_gpio, 1); /* Allow aggressive PM for USB, it's only needed for n_gsm port */ @@ -159,11 +154,6 @@ gpiod_set_value_cansleep(enable_gpio, 0); - error = pinctrl_pm_select_sleep_state(ddata->dev); - if (error) - dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", - __func__, error); - return 0; } @@ -200,7 +190,7 @@ struct phy_mdm6600 *ddata; struct device *dev; DECLARE_BITMAP(values, PHY_MDM6600_NR_STATUS_LINES); - int error, i, val = 0; + int error; ddata = container_of(work, struct phy_mdm6600, status_work.work); dev = ddata->dev; @@ -212,16 +202,11 @@ if (error) return; - for (i = 0; i < PHY_MDM6600_NR_STATUS_LINES; i++) { - val |= test_bit(i, values) << i; - dev_dbg(ddata->dev, "XXX %s: i: %i values[i]: %i val: %i\n", - __func__, i, test_bit(i, values), val); - } - ddata->status = values[0]; + ddata->status = values[0] & ((1 << PHY_MDM6600_NR_STATUS_LINES) - 1); dev_info(dev, "modem status: %i %s\n", ddata->status, - phy_mdm6600_status_name[ddata->status & 7]); + phy_mdm6600_status_name[ddata->status]); complete(&ddata->ack); } @@ -248,10 +233,24 @@ { struct phy_mdm6600 *ddata = data; struct gpio_desc *mode_gpio1; + int error, wakeup; mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1]; - dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", - gpiod_get_value(mode_gpio1)); + wakeup = gpiod_get_value(mode_gpio1); + if (!wakeup) + return IRQ_NONE; + + dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", wakeup); + error = pm_runtime_get_sync(ddata->dev); + if (error < 0) { + pm_runtime_put_noidle(ddata->dev); + + return IRQ_NONE; + } + + /* Just wake-up and kick the autosuspend timer */ + pm_runtime_mark_last_busy(ddata->dev); + pm_runtime_put_autosuspend(ddata->dev); return IRQ_HANDLED; } @@ -445,6 +444,7 @@ { struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; + int error; ddata->enabled = false; phy_mdm6600_cmd(ddata, PHY_MDM6600_CMD_BP_SHUTDOWN_REQ); @@ -460,6 +460,17 @@ } else { dev_err(ddata->dev, "Timed out powering down\n"); } + + /* + * Keep reset gpio high with padconf internal pull-up resistor to + * prevent modem from waking up during deeper SoC idle states. The + * gpio bank lines can have glitches if not in the always-on wkup + * domain. + */ + error = pinctrl_pm_select_sleep_state(ddata->dev); + if (error) + dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", + __func__, error); } static void phy_mdm6600_deferred_power_on(struct work_struct *work) @@ -501,8 +512,14 @@ ddata = container_of(work, struct phy_mdm6600, modem_wake_work.work); phy_mdm6600_wake_modem(ddata); + + /* + * The modem does not always stay awake 1.2 seconds after toggling + * the wake GPIO, and sometimes it idles after about some 600 ms + * making writes time out. + */ schedule_delayed_work(&ddata->modem_wake_work, - msecs_to_jiffies(MDM6600_MODEM_IDLE_DELAY_MS)); + msecs_to_jiffies(PHY_MDM6600_WAKE_KICK_MS)); } static int __maybe_unused phy_mdm6600_runtime_suspend(struct device *dev) @@ -554,12 +571,6 @@ ddata->dev = &pdev->dev; platform_set_drvdata(pdev, ddata); - /* Active state selected in phy_mdm6600_power_on() */ - error = pinctrl_pm_select_sleep_state(ddata->dev); - if (error) - dev_warn(ddata->dev, "%s: error with sleep_state: %i\n", - __func__, error); - error = phy_mdm6600_init_lines(ddata); if (error) return error; @@ -610,8 +621,11 @@ pm_runtime_put_autosuspend(ddata->dev); cleanup: - if (error < 0) + if (error < 0) { phy_mdm6600_device_power_off(ddata); + pm_runtime_disable(ddata->dev); + pm_runtime_dont_use_autosuspend(ddata->dev); + } return error; } @@ -621,6 +635,7 @@ struct phy_mdm6600 *ddata = platform_get_drvdata(pdev); struct gpio_desc *reset_gpio = ddata->ctrl_gpios[PHY_MDM6600_RESET]; + pm_runtime_get_noresume(ddata->dev); pm_runtime_dont_use_autosuspend(ddata->dev); pm_runtime_put_sync(ddata->dev); pm_runtime_disable(ddata->dev); --- linux-oracle-5.4.0.orig/drivers/phy/phy-core-mipi-dphy.c +++ linux-oracle-5.4.0/drivers/phy/phy-core-mipi-dphy.c @@ -66,10 +66,10 @@ cfg->hs_trail = max(4 * 8 * ui, 60000 + 4 * 4 * ui); cfg->init = 100; - cfg->lpx = 60000; + cfg->lpx = 50000; cfg->ta_get = 5 * cfg->lpx; cfg->ta_go = 4 * cfg->lpx; - cfg->ta_sure = 2 * cfg->lpx; + cfg->ta_sure = cfg->lpx; cfg->wakeup = 1000; cfg->hs_clk_rate = hs_clk_rate; --- linux-oracle-5.4.0.orig/drivers/phy/phy-core.c +++ linux-oracle-5.4.0/drivers/phy/phy-core.c @@ -138,8 +138,10 @@ return phy_provider; for_each_child_of_node(phy_provider->children, child) - if (child == node) + if (child == node) { + of_node_put(child); return phy_provider; + } } return ERR_PTR(-EPROBE_DEFER); @@ -507,8 +509,10 @@ return ERR_PTR(-ENODEV); /* This phy type handled by the usb-phy subsystem for now */ - if (of_device_is_compatible(args.np, "usb-nop-xceiv")) - return ERR_PTR(-ENODEV); + if (of_device_is_compatible(args.np, "usb-nop-xceiv")) { + phy = ERR_PTR(-ENODEV); + goto out_put_node; + } mutex_lock(&phy_provider_mutex); phy_provider = of_phy_provider_lookup(args.np); @@ -530,6 +534,7 @@ out_unlock: mutex_unlock(&phy_provider_mutex); +out_put_node: of_node_put(args.np); return phy; @@ -601,7 +606,7 @@ if (!phy) return; - r = devres_destroy(dev, devm_phy_release, devm_phy_match, phy); + r = devres_release(dev, devm_phy_release, devm_phy_match, phy); dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); } EXPORT_SYMBOL_GPL(devm_phy_put); @@ -953,7 +958,7 @@ { int r; - r = devres_destroy(dev, devm_phy_consume, devm_phy_match, phy); + r = devres_release(dev, devm_phy_consume, devm_phy_match, phy); dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); } EXPORT_SYMBOL_GPL(devm_phy_destroy); @@ -1089,11 +1094,12 @@ * of_phy_provider_unregister to unregister the phy provider. */ void devm_of_phy_provider_unregister(struct device *dev, - struct phy_provider *phy_provider) { + struct phy_provider *phy_provider) +{ int r; - r = devres_destroy(dev, devm_phy_provider_release, devm_phy_match, - phy_provider); + r = devres_release(dev, devm_phy_provider_release, devm_phy_match, + phy_provider); dev_WARN_ONCE(dev, r, "couldn't find PHY provider device resource\n"); } EXPORT_SYMBOL_GPL(devm_of_phy_provider_unregister); --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c @@ -80,7 +80,7 @@ if (readl_relaxed(addr) & mask) return 0; - usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); + usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50); } while (!time_after(jiffies, timeout)); return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT; --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-qmp.c +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-qmp.c @@ -66,7 +66,7 @@ /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */ #define CLAMP_EN BIT(0) /* enables i/o clamp_n */ -#define PHY_INIT_COMPLETE_TIMEOUT 1000 +#define PHY_INIT_COMPLETE_TIMEOUT 10000 #define POWER_DOWN_DELAY_US_MIN 10 #define POWER_DOWN_DELAY_US_MAX 11 @@ -402,8 +402,8 @@ QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0xf), QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x1), QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x0), - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0x1f), - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x1f), QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x6), QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0xf), QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x0), @@ -429,7 +429,6 @@ QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x0), QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x1), - QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0xa), QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x1), QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31), QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x1), @@ -438,7 +437,6 @@ QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0x2f), QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x19), QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV, 0x19), - QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x7), }; static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl[] = { @@ -446,6 +444,8 @@ QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x6), QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET, 0x2), QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_TX_EMP_POST1_LVL, 0x36), + QMP_PHY_INIT_CFG(QSERDES_TX_SLEW_CNTL, 0x0a), }; static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl[] = { @@ -456,7 +456,6 @@ QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0xdb), QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b), QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN, 0x4), - QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF, 0x4), }; static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl[] = { @@ -1107,6 +1106,9 @@ .pwrdn_ctrl = SW_PWRDN, }; +static const char * const ipq8074_pciephy_clk_l[] = { + "aux", "cfg_ahb", +}; /* list of resets */ static const char * const ipq8074_pciephy_reset_l[] = { "phy", "common", @@ -1124,8 +1126,8 @@ .rx_tbl_num = ARRAY_SIZE(ipq8074_pcie_rx_tbl), .pcs_tbl = ipq8074_pcie_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(ipq8074_pcie_pcs_tbl), - .clk_list = NULL, - .num_clks = 0, + .clk_list = ipq8074_pciephy_clk_l, + .num_clks = ARRAY_SIZE(ipq8074_pciephy_clk_l), .reset_list = ipq8074_pciephy_reset_l, .num_resets = ARRAY_SIZE(ipq8074_pciephy_reset_l), .vreg_list = NULL, @@ -1515,7 +1517,7 @@ qcom_qmp_phy_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num); ret = reset_control_deassert(qmp->ufs_reset); if (ret) - goto err_lane_rst; + goto err_pcs_ready; /* * Pull out PHY from POWER DOWN state. @@ -1858,6 +1860,11 @@ .owner = THIS_MODULE, }; +static void qcom_qmp_reset_control_put(void *data) +{ + reset_control_put(data); +} + static int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id) { @@ -1927,7 +1934,7 @@ * all phys that don't need this. */ snprintf(prop_name, sizeof(prop_name), "pipe%d", id); - qphy->pipe_clk = of_clk_get_by_name(np, prop_name); + qphy->pipe_clk = devm_get_clk_from_child(dev, np, prop_name); if (IS_ERR(qphy->pipe_clk)) { if (qmp->cfg->type == PHY_TYPE_PCIE || qmp->cfg->type == PHY_TYPE_USB3) { @@ -1949,6 +1956,10 @@ dev_err(dev, "failed to get lane%d reset\n", id); return PTR_ERR(qphy->lane_rst); } + ret = devm_add_action_or_reset(dev, qcom_qmp_reset_control_put, + qphy->lane_rst); + if (ret) + return ret; } if (qmp->cfg->type == PHY_TYPE_UFS) --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-qmp.h +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -77,6 +77,8 @@ #define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc /* Only for QMP V2 PHY - TX registers */ +#define QSERDES_TX_EMP_POST1_LVL 0x018 +#define QSERDES_TX_SLEW_CNTL 0x040 #define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054 #define QSERDES_TX_DEBUG_BUS_SEL 0x064 #define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068 --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-qusb2.c +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-qusb2.c @@ -432,7 +432,7 @@ { struct device *dev = &qphy->phy->dev; const struct qusb2_phy_cfg *cfg = qphy->cfg; - u8 *val; + u8 *val, hstx_trim; /* efuse register is optional */ if (!qphy->cell) @@ -446,7 +446,13 @@ * set while configuring the phy. */ val = nvmem_cell_read(qphy->cell, NULL); - if (IS_ERR(val) || !val[0]) { + if (IS_ERR(val)) { + dev_dbg(dev, "failed to read a valid hs-tx trim value\n"); + return; + } + hstx_trim = val[0]; + kfree(val); + if (!hstx_trim) { dev_dbg(dev, "failed to read a valid hs-tx trim value\n"); return; } @@ -454,12 +460,10 @@ /* Fused TUNE1/2 value is the higher nibble only */ if (cfg->update_tune1_with_efuse) qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE1], - val[0] << HSTX_TRIM_SHIFT, - HSTX_TRIM_MASK); + hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK); else qusb2_write_mask(qphy->base, cfg->regs[QUSB2PHY_PORT_TUNE2], - val[0] << HSTX_TRIM_SHIFT, - HSTX_TRIM_MASK); + hstx_trim << HSTX_TRIM_SHIFT, HSTX_TRIM_MASK); } static int qusb2_phy_set_mode(struct phy *phy, --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-usb-hs.c +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-usb-hs.c @@ -158,8 +158,8 @@ /* setup initial state */ qcom_usb_hs_phy_vbus_notifier(&uphy->vbus_notify, state, uphy->vbus_edev); - ret = devm_extcon_register_notifier(&ulpi->dev, uphy->vbus_edev, - EXTCON_USB, &uphy->vbus_notify); + ret = extcon_register_notifier(uphy->vbus_edev, EXTCON_USB, + &uphy->vbus_notify); if (ret) goto err_ulpi; } @@ -180,6 +180,9 @@ { struct qcom_usb_hs_phy *uphy = phy_get_drvdata(phy); + if (uphy->vbus_edev) + extcon_unregister_notifier(uphy->vbus_edev, EXTCON_USB, + &uphy->vbus_notify); regulator_disable(uphy->v3p3); regulator_disable(uphy->v1p8); clk_disable_unprepare(uphy->sleep_clk); --- linux-oracle-5.4.0.orig/drivers/phy/qualcomm/phy-qcom-usb-hsic.c +++ linux-oracle-5.4.0/drivers/phy/qualcomm/phy-qcom-usb-hsic.c @@ -54,8 +54,10 @@ /* Configure pins for HSIC functionality */ pins_default = pinctrl_lookup_state(uphy->pctl, PINCTRL_STATE_DEFAULT); - if (IS_ERR(pins_default)) - return PTR_ERR(pins_default); + if (IS_ERR(pins_default)) { + ret = PTR_ERR(pins_default); + goto err_ulpi; + } ret = pinctrl_select_state(uphy->pctl, pins_default); if (ret) --- linux-oracle-5.4.0.orig/drivers/phy/renesas/phy-rcar-gen2.c +++ linux-oracle-5.4.0/drivers/phy/renesas/phy-rcar-gen2.c @@ -71,6 +71,7 @@ struct rcar_gen2_phy_data { const struct phy_ops *gen2_phy_ops; const u32 (*select_value)[PHYS_PER_CHANNEL]; + const u32 num_channels; }; static int rcar_gen2_phy_init(struct phy *p) @@ -271,11 +272,13 @@ static const struct rcar_gen2_phy_data rcar_gen2_usb_phy_data = { .gen2_phy_ops = &rcar_gen2_phy_ops, .select_value = pci_select_value, + .num_channels = ARRAY_SIZE(pci_select_value), }; static const struct rcar_gen2_phy_data rz_g1c_usb_phy_data = { .gen2_phy_ops = &rz_g1c_phy_ops, .select_value = usb20_select_value, + .num_channels = ARRAY_SIZE(usb20_select_value), }; static const struct of_device_id rcar_gen2_phy_match_table[] = { @@ -389,7 +392,7 @@ channel->selected_phy = -1; error = of_property_read_u32(np, "reg", &channel_num); - if (error || channel_num > 2) { + if (error || channel_num >= data->num_channels) { dev_err(dev, "Invalid \"reg\" property\n"); of_node_put(np); return error; --- linux-oracle-5.4.0.orig/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ linux-oracle-5.4.0/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -110,6 +111,7 @@ struct work_struct work; struct mutex lock; /* protects rphys[...].powered */ enum usb_dr_mode dr_mode; + int irq; bool extcon_host; bool is_otg_channel; bool uses_otg_pins; @@ -320,9 +322,9 @@ if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch)) return -EIO; - if (!strncmp(buf, "host", strlen("host"))) + if (sysfs_streq(buf, "host")) new_mode = PHY_MODE_USB_HOST; - else if (!strncmp(buf, "peripheral", strlen("peripheral"))) + else if (sysfs_streq(buf, "peripheral")) new_mode = PHY_MODE_USB_DEVICE; else return -EINVAL; @@ -388,12 +390,38 @@ rcar_gen3_device_recognition(ch); } +static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) +{ + struct rcar_gen3_chan *ch = _ch; + void __iomem *usb2_base = ch->base; + u32 status = readl(usb2_base + USB2_OBINTSTA); + irqreturn_t ret = IRQ_NONE; + + if (status & USB2_OBINT_BITS) { + dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); + writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); + rcar_gen3_device_recognition(ch); + ret = IRQ_HANDLED; + } + + return ret; +} + static int rcar_gen3_phy_usb2_init(struct phy *p) { struct rcar_gen3_phy *rphy = phy_get_drvdata(p); struct rcar_gen3_chan *channel = rphy->ch; void __iomem *usb2_base = channel->base; u32 val; + int ret; + + if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) { + INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); + ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq, + IRQF_SHARED, dev_name(channel->dev), channel); + if (ret < 0) + dev_err(channel->dev, "No irq handler (%d)\n", channel->irq); + } /* Initialize USB2 part */ val = readl(usb2_base + USB2_INT_ENABLE); @@ -432,6 +460,9 @@ val &= ~USB2_INT_ENABLE_UCOM_INTEN; writel(val, usb2_base + USB2_INT_ENABLE); + if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel)) + free_irq(channel->irq, channel); + return 0; } @@ -502,23 +533,6 @@ .owner = THIS_MODULE, }; -static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch) -{ - struct rcar_gen3_chan *ch = _ch; - void __iomem *usb2_base = ch->base; - u32 status = readl(usb2_base + USB2_OBINTSTA); - irqreturn_t ret = IRQ_NONE; - - if (status & USB2_OBINT_BITS) { - dev_vdbg(ch->dev, "%s: %08x\n", __func__, status); - writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA); - rcar_gen3_device_recognition(ch); - ret = IRQ_HANDLED; - } - - return ret; -} - static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = { { .compatible = "renesas,usb2-phy-r8a77470", @@ -597,7 +611,7 @@ struct phy_provider *provider; struct resource *res; const struct phy_ops *phy_usb2_ops; - int irq, ret = 0, i; + int ret = 0, i; if (!dev->of_node) { dev_err(dev, "This driver needs device tree\n"); @@ -613,20 +627,10 @@ if (IS_ERR(channel->base)) return PTR_ERR(channel->base); - /* call request_irq for OTG */ - irq = platform_get_irq(pdev, 0); - if (irq >= 0) { - INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); - irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, - IRQF_SHARED, dev_name(dev), channel); - if (irq < 0) - dev_err(dev, "No irq handler (%d)\n", irq); - } - + /* get irq number here and request_irq for OTG in phy_init */ + channel->irq = platform_get_irq_optional(pdev, 0); channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node); if (channel->dr_mode != USB_DR_MODE_UNKNOWN) { - int ret; - channel->is_otg_channel = true; channel->uses_otg_pins = !of_property_read_bool(dev->of_node, "renesas,no-otg-pins"); @@ -648,8 +652,10 @@ */ pm_runtime_enable(dev); phy_usb2_ops = of_device_get_match_data(dev); - if (!phy_usb2_ops) - return -EINVAL; + if (!phy_usb2_ops) { + ret = -EINVAL; + goto error; + } mutex_init(&channel->lock); for (i = 0; i < NUM_OF_PHYS; i++) { @@ -683,8 +689,6 @@ ret = PTR_ERR(provider); goto error; } else if (channel->is_otg_channel) { - int ret; - ret = device_create_file(dev, &dev_attr_role); if (ret < 0) goto error; --- linux-oracle-5.4.0.orig/drivers/phy/rockchip/phy-rockchip-emmc.c +++ linux-oracle-5.4.0/drivers/phy/rockchip/phy-rockchip-emmc.c @@ -240,15 +240,17 @@ * - SDHCI driver to get the PHY * - SDHCI driver to init the PHY * - * The clock is optional, so upon any error we just set to NULL. + * The clock is optional, using clk_get_optional() to get the clock + * and do error processing if the return value != NULL * * NOTE: we don't do anything special for EPROBE_DEFER here. Given the * above expected use case, EPROBE_DEFER isn't sensible to expect, so * it's just like any other error. */ - rk_phy->emmcclk = clk_get(&phy->dev, "emmcclk"); + rk_phy->emmcclk = clk_get_optional(&phy->dev, "emmcclk"); if (IS_ERR(rk_phy->emmcclk)) { - dev_dbg(&phy->dev, "Error getting emmcclk: %d\n", ret); + ret = PTR_ERR(rk_phy->emmcclk); + dev_err(&phy->dev, "Error getting emmcclk: %d\n", ret); rk_phy->emmcclk = NULL; } --- linux-oracle-5.4.0.orig/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ linux-oracle-5.4.0/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -603,6 +603,8 @@ { const struct pre_pll_config *cfg = pre_pll_cfg_table; + rate = (rate / 1000) * 1000; + for (; cfg->pixclock != 0; cfg++) if (cfg->pixclock == rate && !cfg->fracdiv) break; @@ -743,10 +745,12 @@ do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); } - inno->pixclock = vco; - dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); + inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; + + dev_dbg(inno->dev, "%s rate %lu vco %llu\n", + __func__, inno->pixclock, vco); - return vco; + return inno->pixclock; } static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, @@ -755,6 +759,8 @@ { const struct pre_pll_config *cfg = pre_pll_cfg_table; + rate = (rate / 1000) * 1000; + for (; cfg->pixclock != 0; cfg++) if (cfg->pixclock == rate) break; @@ -786,8 +792,8 @@ RK3328_PRE_PLL_POWER_DOWN); /* Configure pre-pll */ - inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, - RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); + inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, + RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; @@ -1017,9 +1023,10 @@ inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); if (cfg->postdiv == 1) { - inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); + inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } else { v = (cfg->postdiv / 2) - 1; v &= RK3328_POST_PLL_POST_DIV_MASK; @@ -1027,7 +1034,8 @@ inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | - RK3328_POST_PLL_REFCLK_SEL_TMDS); + RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } for (v = 0; v < 14; v++) --- linux-oracle-5.4.0.orig/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ linux-oracle-5.4.0/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -467,8 +467,10 @@ return ret; ret = property_enable(base, &rport->port_cfg->phy_sus, false); - if (ret) + if (ret) { + clk_disable_unprepare(rphy->clk480m); return ret; + } /* waiting for the utmi_clk to become stable */ usleep_range(1500, 2000); --- linux-oracle-5.4.0.orig/drivers/phy/rockchip/phy-rockchip-typec.c +++ linux-oracle-5.4.0/drivers/phy/rockchip/phy-rockchip-typec.c @@ -808,9 +808,8 @@ struct extcon_dev *edev = tcphy->extcon; union extcon_property_value property; unsigned int id; - bool ufp, dp; u8 mode; - int ret; + int ret, ufp, dp; if (!edev) return MODE_DFP_USB; --- linux-oracle-5.4.0.orig/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ linux-oracle-5.4.0/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -287,9 +287,9 @@ reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; /* FSEL settings corresponding to reference clock */ - reg &= ~PHYCLKRST_FSEL_PIPE_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK; + reg &= ~(PHYCLKRST_FSEL_PIPE_MASK | + PHYCLKRST_MPLL_MULTIPLIER_MASK | + PHYCLKRST_SSC_REFCLKSEL_MASK); switch (phy_drd->extrefclk) { case EXYNOS5_FSEL_50MHZ: reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF | @@ -331,9 +331,9 @@ reg &= ~PHYCLKRST_REFCLKSEL_MASK; reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK; - reg &= ~PHYCLKRST_FSEL_UTMI_MASK | - PHYCLKRST_MPLL_MULTIPLIER_MASK | - PHYCLKRST_SSC_REFCLKSEL_MASK; + reg &= ~(PHYCLKRST_FSEL_UTMI_MASK | + PHYCLKRST_MPLL_MULTIPLIER_MASK | + PHYCLKRST_SSC_REFCLKSEL_MASK); reg |= PHYCLKRST_FSEL(phy_drd->extrefclk); return reg; @@ -714,7 +714,9 @@ struct phy_usb_instance *inst = phy_get_drvdata(phy); struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); - return exynos5420_usbdrd_phy_calibrate(phy_drd); + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) + return exynos5420_usbdrd_phy_calibrate(phy_drd); + return 0; } static const struct phy_ops exynos5_usbdrd_phy_ops = { --- linux-oracle-5.4.0.orig/drivers/phy/samsung/phy-exynos5250-sata.c +++ linux-oracle-5.4.0/drivers/phy/samsung/phy-exynos5250-sata.c @@ -190,6 +190,7 @@ return -EINVAL; sata_phy->client = of_find_i2c_device_by_node(node); + of_node_put(node); if (!sata_phy->client) return -EPROBE_DEFER; @@ -198,20 +199,21 @@ sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl"); if (IS_ERR(sata_phy->phyclk)) { dev_err(dev, "failed to get clk for PHY\n"); - return PTR_ERR(sata_phy->phyclk); + ret = PTR_ERR(sata_phy->phyclk); + goto put_dev; } ret = clk_prepare_enable(sata_phy->phyclk); if (ret < 0) { dev_err(dev, "failed to enable source clk\n"); - return ret; + goto put_dev; } sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops); if (IS_ERR(sata_phy->phy)) { - clk_disable_unprepare(sata_phy->phyclk); dev_err(dev, "failed to create PHY\n"); - return PTR_ERR(sata_phy->phy); + ret = PTR_ERR(sata_phy->phy); + goto clk_disable; } phy_set_drvdata(sata_phy->phy, sata_phy); @@ -219,11 +221,18 @@ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(phy_provider)) { - clk_disable_unprepare(sata_phy->phyclk); - return PTR_ERR(phy_provider); + ret = PTR_ERR(phy_provider); + goto clk_disable; } return 0; + +clk_disable: + clk_disable_unprepare(sata_phy->phyclk); +put_dev: + put_device(&sata_phy->client->dev); + + return ret; } static const struct of_device_id exynos_sata_phy_of_match[] = { --- linux-oracle-5.4.0.orig/drivers/phy/samsung/phy-s5pv210-usb2.c +++ linux-oracle-5.4.0/drivers/phy/samsung/phy-s5pv210-usb2.c @@ -139,6 +139,10 @@ udelay(10); rst &= ~rstbits; writel(rst, drv->reg_phy + S5PV210_UPHYRST); + /* The following delay is necessary for the reset sequence to be + * completed + */ + udelay(80); } else { pwr = readl(drv->reg_phy + S5PV210_UPHYPWR); pwr |= phypwr; --- linux-oracle-5.4.0.orig/drivers/phy/socionext/phy-uniphier-pcie.c +++ linux-oracle-5.4.0/drivers/phy/socionext/phy-uniphier-pcie.c @@ -20,11 +20,13 @@ /* PHY */ #define PCL_PHY_TEST_I 0x2000 -#define PCL_PHY_TEST_O 0x2004 #define TESTI_DAT_MASK GENMASK(13, 6) #define TESTI_ADR_MASK GENMASK(5, 1) #define TESTI_WR_EN BIT(0) +#define PCL_PHY_TEST_O 0x2004 +#define TESTO_DAT_MASK GENMASK(7, 0) + #define PCL_PHY_RESET 0x200c #define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */ #define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */ @@ -72,11 +74,12 @@ val = FIELD_PREP(TESTI_DAT_MASK, 1); val |= FIELD_PREP(TESTI_ADR_MASK, reg); uniphier_pciephy_testio_write(priv, val); - val = readl(priv->base + PCL_PHY_TEST_O); + val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK; /* update value */ - val &= ~FIELD_PREP(TESTI_DAT_MASK, mask); - val = FIELD_PREP(TESTI_DAT_MASK, mask & param); + val &= ~mask; + val |= mask & param; + val = FIELD_PREP(TESTI_DAT_MASK, val); val |= FIELD_PREP(TESTI_ADR_MASK, reg); uniphier_pciephy_testio_write(priv, val); uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN); --- linux-oracle-5.4.0.orig/drivers/phy/socionext/phy-uniphier-usb3ss.c +++ linux-oracle-5.4.0/drivers/phy/socionext/phy-uniphier-usb3ss.c @@ -22,11 +22,13 @@ #include #define SSPHY_TESTI 0x0 -#define SSPHY_TESTO 0x4 #define TESTI_DAT_MASK GENMASK(13, 6) #define TESTI_ADR_MASK GENMASK(5, 1) #define TESTI_WR_EN BIT(0) +#define SSPHY_TESTO 0x4 +#define TESTO_DAT_MASK GENMASK(7, 0) + #define PHY_F(regno, msb, lsb) { (regno), (msb), (lsb) } #define CDR_CPD_TRIM PHY_F(7, 3, 0) /* RxPLL charge pump current */ @@ -84,12 +86,12 @@ val = FIELD_PREP(TESTI_DAT_MASK, 1); val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); uniphier_u3ssphy_testio_write(priv, val); - val = readl(priv->base + SSPHY_TESTO); + val = readl(priv->base + SSPHY_TESTO) & TESTO_DAT_MASK; /* update value */ - val &= ~FIELD_PREP(TESTI_DAT_MASK, field_mask); + val &= ~field_mask; data = field_mask & (p->value << p->field.lsb); - val = FIELD_PREP(TESTI_DAT_MASK, data); + val = FIELD_PREP(TESTI_DAT_MASK, data | val); val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); uniphier_u3ssphy_testio_write(priv, val); uniphier_u3ssphy_testio_write(priv, val | TESTI_WR_EN); @@ -315,6 +317,10 @@ .data = &uniphier_pro4_data, }, { + .compatible = "socionext,uniphier-pro5-usb3-ssphy", + .data = &uniphier_pro4_data, + }, + { .compatible = "socionext,uniphier-pxs2-usb3-ssphy", .data = &uniphier_pxs2_data, }, --- linux-oracle-5.4.0.orig/drivers/phy/st/phy-miphy28lp.c +++ linux-oracle-5.4.0/drivers/phy/st/phy-miphy28lp.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -484,19 +485,11 @@ static inline int miphy28lp_wait_compensation(struct miphy28lp_phy *miphy_phy) { - unsigned long finish = jiffies + 5 * HZ; u8 val; /* Waiting for Compensation to complete */ - do { - val = readb_relaxed(miphy_phy->base + MIPHY_COMP_FSM_6); - - if (time_after_eq(jiffies, finish)) - return -EBUSY; - cpu_relax(); - } while (!(val & COMP_DONE)); - - return 0; + return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_COMP_FSM_6, + val, val & COMP_DONE, 1, 5 * USEC_PER_SEC); } @@ -805,7 +798,6 @@ static inline int miphy_is_ready(struct miphy28lp_phy *miphy_phy) { - unsigned long finish = jiffies + 5 * HZ; u8 mask = HFC_PLL | HFC_RDY; u8 val; @@ -816,21 +808,14 @@ if (miphy_phy->type == PHY_TYPE_SATA) mask |= PHY_RDY; - do { - val = readb_relaxed(miphy_phy->base + MIPHY_STATUS_1); - if ((val & mask) != mask) - cpu_relax(); - else - return 0; - } while (!time_after_eq(jiffies, finish)); - - return -EBUSY; + return readb_relaxed_poll_timeout(miphy_phy->base + MIPHY_STATUS_1, + val, (val & mask) == mask, 1, + 5 * USEC_PER_SEC); } static int miphy_osc_is_ready(struct miphy28lp_phy *miphy_phy) { struct miphy28lp_dev *miphy_dev = miphy_phy->phydev; - unsigned long finish = jiffies + 5 * HZ; u32 val; if (!miphy_phy->osc_rdy) @@ -839,17 +824,10 @@ if (!miphy_phy->syscfg_reg[SYSCFG_STATUS]) return -EINVAL; - do { - regmap_read(miphy_dev->regmap, - miphy_phy->syscfg_reg[SYSCFG_STATUS], &val); - - if ((val & MIPHY_OSC_RDY) != MIPHY_OSC_RDY) - cpu_relax(); - else - return 0; - } while (!time_after_eq(jiffies, finish)); - - return -EBUSY; + return regmap_read_poll_timeout(miphy_dev->regmap, + miphy_phy->syscfg_reg[SYSCFG_STATUS], + val, val & MIPHY_OSC_RDY, 1, + 5 * USEC_PER_SEC); } static int miphy28lp_get_resource_byname(struct device_node *child, --- linux-oracle-5.4.0.orig/drivers/phy/st/phy-stm32-usbphyc.c +++ linux-oracle-5.4.0/drivers/phy/st/phy-stm32-usbphyc.c @@ -393,6 +393,8 @@ ret = of_property_read_u32(child, "reg", &index); if (ret || index > usbphyc->nphys) { dev_err(&phy->dev, "invalid reg property: %d\n", ret); + if (!ret) + ret = -EINVAL; goto put_child; } --- linux-oracle-5.4.0.orig/drivers/phy/tegra/xusb-tegra186.c +++ linux-oracle-5.4.0/drivers/phy/tegra/xusb-tegra186.c @@ -415,6 +415,7 @@ unsigned int index = lane->index; struct device *dev = padctl->dev; int err; + u32 reg; port = tegra_xusb_find_usb2_port(padctl, index); if (!port) { @@ -422,6 +423,16 @@ return -ENODEV; } + if (port->mode == USB_DR_MODE_OTG || + port->mode == USB_DR_MODE_PERIPHERAL) { + /* reset VBUS&ID OVERRIDE */ + reg = padctl_readl(padctl, USB2_VBUS_ID); + reg &= ~VBUS_OVERRIDE; + reg &= ~ID_OVERRIDE(~0); + reg |= ID_OVERRIDE_FLOATING; + padctl_writel(padctl, reg, USB2_VBUS_ID); + } + if (port->supply && port->mode == USB_DR_MODE_HOST) { err = regulator_disable(port->supply); if (err) { --- linux-oracle-5.4.0.orig/drivers/phy/tegra/xusb.c +++ linux-oracle-5.4.0/drivers/phy/tegra/xusb.c @@ -443,7 +443,7 @@ name = kasprintf(GFP_KERNEL, "%s-%u", type, index); if (!name) { of_node_put(ports); - return ERR_PTR(-ENOMEM); + return NULL; } np = of_get_child_by_name(ports, name); kfree(name); @@ -606,6 +606,7 @@ usb2->base.lane = usb2->base.ops->map(&usb2->base); if (IS_ERR(usb2->base.lane)) { err = PTR_ERR(usb2->base.lane); + tegra_xusb_port_unregister(&usb2->base); goto out; } @@ -658,6 +659,7 @@ ulpi->base.lane = ulpi->base.ops->map(&ulpi->base); if (IS_ERR(ulpi->base.lane)) { err = PTR_ERR(ulpi->base.lane); + tegra_xusb_port_unregister(&ulpi->base); goto out; } @@ -949,6 +951,7 @@ reset: reset_control_assert(padctl->rst); remove: + platform_set_drvdata(pdev, NULL); soc->ops->remove(padctl); return err; } --- linux-oracle-5.4.0.orig/drivers/phy/ti/phy-am654-serdes.c +++ linux-oracle-5.4.0/drivers/phy/ti/phy-am654-serdes.c @@ -625,8 +625,10 @@ pm_runtime_enable(dev); phy = devm_phy_create(dev, NULL, &ops); - if (IS_ERR(phy)) - return PTR_ERR(phy); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto clk_err; + } phy_set_drvdata(phy, am654_phy); phy_provider = devm_of_phy_provider_register(dev, serdes_am654_xlate); @@ -639,7 +641,7 @@ clk_err: of_clk_del_provider(node); - + pm_runtime_disable(dev); return ret; } --- linux-oracle-5.4.0.orig/drivers/phy/ti/phy-dm816x-usb.c +++ linux-oracle-5.4.0/drivers/phy/ti/phy-dm816x-usb.c @@ -246,19 +246,28 @@ pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, NULL, &ops); - if (IS_ERR(generic_phy)) - return PTR_ERR(generic_phy); + if (IS_ERR(generic_phy)) { + error = PTR_ERR(generic_phy); + goto clk_unprepare; + } phy_set_drvdata(generic_phy, phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); + if (IS_ERR(phy_provider)) { + error = PTR_ERR(phy_provider); + goto clk_unprepare; + } usb_add_phy_dev(&phy->phy); return 0; + +clk_unprepare: + pm_runtime_disable(phy->dev); + clk_unprepare(phy->refclk); + return error; } static int dm816x_usb_phy_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/phy/ti/phy-gmii-sel.c +++ linux-oracle-5.4.0/drivers/phy/ti/phy-gmii-sel.c @@ -69,31 +69,31 @@ break; case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_RXID: gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII; break; case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII; rgmii_id = 1; break; case PHY_INTERFACE_MODE_MII: - mode = AM33XX_GMII_SEL_MODE_MII; + case PHY_INTERFACE_MODE_GMII: + gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII; break; default: - dev_warn(dev, - "port%u: unsupported mode: \"%s\". Defaulting to MII.\n", - if_phy->id, phy_modes(rgmii_id)); + dev_warn(dev, "port%u: unsupported mode: \"%s\"\n", + if_phy->id, phy_modes(submode)); return -EINVAL; } if_phy->phy_if_mode = submode; dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n", - __func__, if_phy->id, mode, rgmii_id, + __func__, if_phy->id, submode, rgmii_id, if_phy->rmii_clock_external); regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE]; --- linux-oracle-5.4.0.orig/drivers/phy/ti/phy-omap-usb2.c +++ linux-oracle-5.4.0/drivers/phy/ti/phy-omap-usb2.c @@ -58,7 +58,7 @@ { struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - if (!phy->comparator) + if (!phy->comparator || !phy->comparator->set_vbus) return -ENODEV; return phy->comparator->set_vbus(phy->comparator, enabled); @@ -68,7 +68,7 @@ { struct omap_usb *phy = phy_to_omapusb(otg->usb_phy); - if (!phy->comparator) + if (!phy->comparator || !phy->comparator->start_srp) return -ENODEV; return phy->comparator->start_srp(phy->comparator); @@ -157,7 +157,7 @@ return 0; err1: - clk_disable(phy->wkupclk); + clk_disable_unprepare(phy->wkupclk); err0: return ret; --- linux-oracle-5.4.0.orig/drivers/phy/ti/phy-twl4030-usb.c +++ linux-oracle-5.4.0/drivers/phy/ti/phy-twl4030-usb.c @@ -779,7 +779,7 @@ usb_remove_phy(&twl->phy); pm_runtime_get_sync(twl->dev); - cancel_delayed_work(&twl->id_workaround_work); + cancel_delayed_work_sync(&twl->id_workaround_work); device_remove_file(twl->dev, &dev_attr_vbus); /* set transceiver mode to power on defaults */ --- linux-oracle-5.4.0.orig/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ linux-oracle-5.4.0/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -334,7 +334,7 @@ #define D22 40 SIG_EXPR_LIST_DECL_SESG(D22, SD1CLK, SD1, SIG_DESC_SET(SCU414, 8)); -SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU414, 8)); +SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU4B4, 8)); PIN_DECL_2(D22, GPIOF0, SD1CLK, PWM8); GROUP_DECL(PWM8G0, D22); @@ -1088,60 +1088,52 @@ #define AB7 176 SIG_EXPR_LIST_DECL_SESG(AB7, LAD0, LPC, SIG_DESC_SET(SCU434, 16), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AB7, ESPID0, ESPI, SIG_DESC_SET(SCU434, 16), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AB7, ESPID0, ESPI, SIG_DESC_SET(SCU434, 16)); PIN_DECL_2(AB7, GPIOW0, LAD0, ESPID0); #define AB8 177 SIG_EXPR_LIST_DECL_SESG(AB8, LAD1, LPC, SIG_DESC_SET(SCU434, 17), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AB8, ESPID1, ESPI, SIG_DESC_SET(SCU434, 17), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AB8, ESPID1, ESPI, SIG_DESC_SET(SCU434, 17)); PIN_DECL_2(AB8, GPIOW1, LAD1, ESPID1); #define AC8 178 SIG_EXPR_LIST_DECL_SESG(AC8, LAD2, LPC, SIG_DESC_SET(SCU434, 18), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AC8, ESPID2, ESPI, SIG_DESC_SET(SCU434, 18), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AC8, ESPID2, ESPI, SIG_DESC_SET(SCU434, 18)); PIN_DECL_2(AC8, GPIOW2, LAD2, ESPID2); #define AC7 179 SIG_EXPR_LIST_DECL_SESG(AC7, LAD3, LPC, SIG_DESC_SET(SCU434, 19), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AC7, ESPID3, ESPI, SIG_DESC_SET(SCU434, 19), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AC7, ESPID3, ESPI, SIG_DESC_SET(SCU434, 19)); PIN_DECL_2(AC7, GPIOW3, LAD3, ESPID3); #define AE7 180 SIG_EXPR_LIST_DECL_SESG(AE7, LCLK, LPC, SIG_DESC_SET(SCU434, 20), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AE7, ESPICK, ESPI, SIG_DESC_SET(SCU434, 20), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AE7, ESPICK, ESPI, SIG_DESC_SET(SCU434, 20)); PIN_DECL_2(AE7, GPIOW4, LCLK, ESPICK); #define AF7 181 SIG_EXPR_LIST_DECL_SESG(AF7, LFRAME, LPC, SIG_DESC_SET(SCU434, 21), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AF7, ESPICS, ESPI, SIG_DESC_SET(SCU434, 21), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AF7, ESPICS, ESPI, SIG_DESC_SET(SCU434, 21)); PIN_DECL_2(AF7, GPIOW5, LFRAME, ESPICS); #define AD7 182 SIG_EXPR_LIST_DECL_SESG(AD7, LSIRQ, LSIRQ, SIG_DESC_SET(SCU434, 22), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AD7, ESPIALT, ESPIALT, SIG_DESC_SET(SCU434, 22), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AD7, ESPIALT, ESPIALT, SIG_DESC_SET(SCU434, 22)); PIN_DECL_2(AD7, GPIOW6, LSIRQ, ESPIALT); FUNC_GROUP_DECL(LSIRQ, AD7); FUNC_GROUP_DECL(ESPIALT, AD7); #define AD8 183 SIG_EXPR_LIST_DECL_SESG(AD8, LPCRST, LPC, SIG_DESC_SET(SCU434, 23), - SIG_DESC_CLEAR(SCU510, 6)); -SIG_EXPR_LIST_DECL_SESG(AD8, ESPIRST, ESPI, SIG_DESC_SET(SCU434, 23), SIG_DESC_SET(SCU510, 6)); +SIG_EXPR_LIST_DECL_SESG(AD8, ESPIRST, ESPI, SIG_DESC_SET(SCU434, 23)); PIN_DECL_2(AD8, GPIOW7, LPCRST, ESPIRST); FUNC_GROUP_DECL(LPC, AB7, AB8, AC8, AC7, AE7, AF7, AD8); --- linux-oracle-5.4.0.orig/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ linux-oracle-5.4.0/drivers/pinctrl/aspeed/pinctrl-aspeed.c @@ -115,7 +115,7 @@ int ret = 0; if (!exprs) - return true; + return -EINVAL; while (*exprs && !ret) { ret = aspeed_sig_expr_disable(ctx, *exprs); @@ -277,13 +277,76 @@ static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr) { /* - * The signal type is GPIO if the signal name has "GPIO" as a prefix. - * strncmp (rather than strcmp) is used to implement the prefix - * requirement. + * We need to differentiate between GPIO and non-GPIO signals to + * implement the gpio_request_enable() interface. For better or worse + * the ASPEED pinctrl driver uses the expression names to determine + * whether an expression will mux a pin for GPIO. * - * expr->signal might look like "GPIOT3" in the GPIO case. + * Generally we have the following - A GPIO such as B1 has: + * + * - expr->signal set to "GPIOB1" + * - expr->function set to "GPIOB1" + * + * Using this fact we can determine whether the provided expression is + * a GPIO expression by testing the signal name for the string prefix + * "GPIO". + * + * However, some GPIOs are input-only, and the ASPEED datasheets name + * them differently. An input-only GPIO such as T0 has: + * + * - expr->signal set to "GPIT0" + * - expr->function set to "GPIT0" + * + * It's tempting to generalise the prefix test from "GPIO" to "GPI" to + * account for both GPIOs and GPIs, but in doing so we run aground on + * another feature: + * + * Some pins in the ASPEED BMC SoCs have a "pass-through" GPIO + * function where the input state of one pin is replicated as the + * output state of another (as if they were shorted together - a mux + * configuration that is typically enabled by hardware strapping). + * This feature allows the BMC to pass e.g. power button state through + * to the host while the BMC is yet to boot, but take control of the + * button state once the BMC has booted by muxing each pin as a + * separate, pin-specific GPIO. + * + * Conceptually this pass-through mode is a form of GPIO and is named + * as such in the datasheets, e.g. "GPID0". This naming similarity + * trips us up with the simple GPI-prefixed-signal-name scheme + * discussed above, as the pass-through configuration is not what we + * want when muxing a pin as GPIO for the GPIO subsystem. + * + * On e.g. the AST2400, a pass-through function "GPID0" is grouped on + * balls A18 and D16, where we have: + * + * For ball A18: + * - expr->signal set to "GPID0IN" + * - expr->function set to "GPID0" + * + * For ball D16: + * - expr->signal set to "GPID0OUT" + * - expr->function set to "GPID0" + * + * By contrast, the pin-specific GPIO expressions for the same pins are + * as follows: + * + * For ball A18: + * - expr->signal looks like "GPIOD0" + * - expr->function looks like "GPIOD0" + * + * For ball D16: + * - expr->signal looks like "GPIOD1" + * - expr->function looks like "GPIOD1" + * + * Testing both the signal _and_ function names gives us the means + * differentiate the pass-through GPIO pinmux configuration from the + * pin-specific configuration that the GPIO subsystem is after: An + * expression is a pin-specific (non-pass-through) GPIO configuration + * if the signal prefix is "GPI" and the signal name matches the + * function name. */ - return strncmp(expr->signal, "GPIO", 4) == 0; + return !strncmp(expr->signal, "GPI", 3) && + !strcmp(expr->signal, expr->function); } static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs) --- linux-oracle-5.4.0.orig/drivers/pinctrl/aspeed/pinmux-aspeed.h +++ linux-oracle-5.4.0/drivers/pinctrl/aspeed/pinmux-aspeed.h @@ -452,10 +452,11 @@ * evaluation of the descriptors. * * @signal: The signal name for the priority level on the pin. If the signal - * type is GPIO, then the signal name must begin with the string - * "GPIO", e.g. GPIOA0, GPIOT4 etc. + * type is GPIO, then the signal name must begin with the + * prefix "GPI", e.g. GPIOA0, GPIT0 etc. * @function: The name of the function the signal participates in for the - * associated expression + * associated expression. For pin-specific GPIO, the function + * name must match the signal name. * @ndescs: The number of signal descriptors in the expression * @descs: Pointer to an array of signal descriptors that comprise the * function expression --- linux-oracle-5.4.0.orig/drivers/pinctrl/bcm/Kconfig +++ linux-oracle-5.4.0/drivers/pinctrl/bcm/Kconfig @@ -23,6 +23,7 @@ select PINMUX select PINCONF select GENERIC_PINCONF + select GPIOLIB select GPIOLIB_IRQCHIP default ARCH_BCM2835 || ARCH_BRCMSTB help --- linux-oracle-5.4.0.orig/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ linux-oracle-5.4.0/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -37,12 +38,10 @@ #define MODULE_NAME "pinctrl-bcm2835" #define BCM2835_NUM_GPIOS 54 +#define BCM2711_NUM_GPIOS 58 #define BCM2835_NUM_BANKS 2 #define BCM2835_NUM_IRQS 3 -#define BCM2835_PIN_BITMAP_SZ \ - DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8) - /* GPIO register offsets */ #define GPFSEL0 0x0 /* Function Select */ #define GPSET0 0x1c /* Pin Output Set */ @@ -78,13 +77,15 @@ struct bcm2835_pinctrl { struct device *dev; void __iomem *base; + int *wake_irq; /* note: locking assumes each bank will have its own unsigned long */ unsigned long enabled_irq_map[BCM2835_NUM_BANKS]; - unsigned int irq_type[BCM2835_NUM_GPIOS]; + unsigned int irq_type[BCM2711_NUM_GPIOS]; struct pinctrl_dev *pctl_dev; struct gpio_chip gpio_chip; + struct pinctrl_desc pctl_desc; struct pinctrl_gpio_range gpio_range; raw_spinlock_t irq_lock[BCM2835_NUM_BANKS]; @@ -147,6 +148,10 @@ BCM2835_GPIO_PIN(51), BCM2835_GPIO_PIN(52), BCM2835_GPIO_PIN(53), + BCM2835_GPIO_PIN(54), + BCM2835_GPIO_PIN(55), + BCM2835_GPIO_PIN(56), + BCM2835_GPIO_PIN(57), }; /* one pin per group */ @@ -205,6 +210,10 @@ "gpio51", "gpio52", "gpio53", + "gpio54", + "gpio55", + "gpio56", + "gpio57", }; enum bcm2835_fsel { @@ -355,6 +364,22 @@ .can_sleep = false, }; +static const struct gpio_chip bcm2711_gpio_chip = { + .label = "pinctrl-bcm2711", + .owner = THIS_MODULE, + .request = gpiochip_generic_request, + .free = gpiochip_generic_free, + .direction_input = bcm2835_gpio_direction_input, + .direction_output = bcm2835_gpio_direction_output, + .get_direction = bcm2835_gpio_get_direction, + .get = bcm2835_gpio_get, + .set = bcm2835_gpio_set, + .set_config = gpiochip_generic_config, + .base = -1, + .ngpio = BCM2711_NUM_GPIOS, + .can_sleep = false, +}; + static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, unsigned int bank, u32 mask) { @@ -401,7 +426,7 @@ bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000); bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff); break; - case 2: /* IRQ2 covers GPIOs 46-53 */ + case 2: /* IRQ2 covers GPIOs 46-57 */ bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000); break; } @@ -409,6 +434,11 @@ chained_irq_exit(host_chip, desc); } +static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id) +{ + return IRQ_HANDLED; +} + static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc, unsigned reg, unsigned offset, bool enable) { @@ -608,6 +638,34 @@ bcm2835_gpio_set_bit(pc, GPEDS0, gpio); } +static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct bcm2835_pinctrl *pc = gpiochip_get_data(chip); + unsigned gpio = irqd_to_hwirq(data); + unsigned int irqgroup; + int ret = -EINVAL; + + if (!pc->wake_irq) + return ret; + + if (gpio <= 27) + irqgroup = 0; + else if (gpio >= 28 && gpio <= 45) + irqgroup = 1; + else if (gpio >= 46 && gpio <= 57) + irqgroup = 2; + else + return ret; + + if (on) + ret = enable_irq_wake(pc->wake_irq[irqgroup]); + else + ret = disable_irq_wake(pc->wake_irq[irqgroup]); + + return ret; +} + static struct irq_chip bcm2835_gpio_irq_chip = { .name = MODULE_NAME, .irq_enable = bcm2835_gpio_irq_enable, @@ -616,11 +674,13 @@ .irq_ack = bcm2835_gpio_irq_ack, .irq_mask = bcm2835_gpio_irq_disable, .irq_unmask = bcm2835_gpio_irq_enable, + .irq_set_wake = bcm2835_gpio_irq_set_wake, + .flags = IRQCHIP_MASK_ON_SUSPEND, }; static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev) { - return ARRAY_SIZE(bcm2835_gpio_groups); + return BCM2835_NUM_GPIOS; } static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev, @@ -778,7 +838,7 @@ err = of_property_read_u32_index(np, "brcm,pins", i, &pin); if (err) goto out; - if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) { + if (pin >= pc->pctl_desc.npins) { dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n", np, pin); err = -EINVAL; @@ -854,7 +914,7 @@ { /* every pin can do every function */ *groups = bcm2835_gpio_groups; - *num_groups = ARRAY_SIZE(bcm2835_gpio_groups); + *num_groups = BCM2835_NUM_GPIOS; return 0; } @@ -1054,29 +1114,66 @@ .pin_config_set = bcm2711_pinconf_set, }; -static struct pinctrl_desc bcm2835_pinctrl_desc = { +static const struct pinctrl_desc bcm2835_pinctrl_desc = { .name = MODULE_NAME, .pins = bcm2835_gpio_pins, - .npins = ARRAY_SIZE(bcm2835_gpio_pins), + .npins = BCM2835_NUM_GPIOS, .pctlops = &bcm2835_pctl_ops, .pmxops = &bcm2835_pmx_ops, .confops = &bcm2835_pinconf_ops, .owner = THIS_MODULE, }; -static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = { +static const struct pinctrl_desc bcm2711_pinctrl_desc = { + .name = "pinctrl-bcm2711", + .pins = bcm2835_gpio_pins, + .npins = BCM2711_NUM_GPIOS, + .pctlops = &bcm2835_pctl_ops, + .pmxops = &bcm2835_pmx_ops, + .confops = &bcm2711_pinconf_ops, + .owner = THIS_MODULE, +}; + +static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = { .name = MODULE_NAME, .npins = BCM2835_NUM_GPIOS, }; +static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = { + .name = "pinctrl-bcm2711", + .npins = BCM2711_NUM_GPIOS, +}; + +struct bcm_plat_data { + const struct gpio_chip *gpio_chip; + const struct pinctrl_desc *pctl_desc; + const struct pinctrl_gpio_range *gpio_range; +}; + +static const struct bcm_plat_data bcm2835_plat_data = { + .gpio_chip = &bcm2835_gpio_chip, + .pctl_desc = &bcm2835_pinctrl_desc, + .gpio_range = &bcm2835_pinctrl_gpio_range, +}; + +static const struct bcm_plat_data bcm2711_plat_data = { + .gpio_chip = &bcm2711_gpio_chip, + .pctl_desc = &bcm2711_pinctrl_desc, + .gpio_range = &bcm2711_pinctrl_gpio_range, +}; + static const struct of_device_id bcm2835_pinctrl_match[] = { { .compatible = "brcm,bcm2835-gpio", - .data = &bcm2835_pinconf_ops, + .data = &bcm2835_plat_data, }, { .compatible = "brcm,bcm2711-gpio", - .data = &bcm2711_pinconf_ops, + .data = &bcm2711_plat_data, + }, + { + .compatible = "brcm,bcm7211-gpio", + .data = &bcm2711_plat_data, }, {} }; @@ -1085,14 +1182,16 @@ { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; + const struct bcm_plat_data *pdata; struct bcm2835_pinctrl *pc; struct gpio_irq_chip *girq; struct resource iomem; int err, i; const struct of_device_id *match; + int is_7211 = 0; - BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS); - BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS); + BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS); + BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS); pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); if (!pc) @@ -1111,7 +1210,14 @@ if (IS_ERR(pc->base)) return PTR_ERR(pc->base); - pc->gpio_chip = bcm2835_gpio_chip; + match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); + if (!match) + return -EINVAL; + + pdata = match->data; + is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio"); + + pc->gpio_chip = *pdata->gpio_chip; pc->gpio_chip.parent = dev; pc->gpio_chip.of_node = np; @@ -1135,6 +1241,18 @@ raw_spin_lock_init(&pc->irq_lock[i]); } + pc->pctl_desc = *pdata->pctl_desc; + pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc); + if (IS_ERR(pc->pctl_dev)) { + gpiochip_remove(&pc->gpio_chip); + return PTR_ERR(pc->pctl_dev); + } + + pc->gpio_range = *pdata->gpio_range; + pc->gpio_range.base = pc->gpio_chip.base; + pc->gpio_range.gc = &pc->gpio_chip; + pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); + girq = &pc->gpio_chip.irq; girq->chip = &bcm2835_gpio_irq_chip; girq->parent_handler = bcm2835_gpio_irq_handler; @@ -1142,8 +1260,21 @@ girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS, sizeof(*girq->parents), GFP_KERNEL); - if (!girq->parents) - return -ENOMEM; + if (!girq->parents) { + err = -ENOMEM; + goto out_remove; + } + + if (is_7211) { + pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS, + sizeof(*pc->wake_irq), + GFP_KERNEL); + if (!pc->wake_irq) { + err = -ENOMEM; + goto out_remove; + } + } + /* * Use the same handler for all groups: this is necessary * since we use one gpiochip to cover all lines - the @@ -1151,35 +1282,50 @@ * bank that was firing the IRQ and look up the per-group * and bank data. */ - for (i = 0; i < BCM2835_NUM_IRQS; i++) + for (i = 0; i < BCM2835_NUM_IRQS; i++) { + int len; + char *name; + girq->parents[i] = irq_of_parse_and_map(np, i); + if (!is_7211) + continue; + + /* Skip over the all banks interrupts */ + pc->wake_irq[i] = irq_of_parse_and_map(np, i + + BCM2835_NUM_IRQS + 1); + + len = strlen(dev_name(pc->dev)) + 16; + name = devm_kzalloc(pc->dev, len, GFP_KERNEL); + if (!name) { + err = -ENOMEM; + goto out_remove; + } + + snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i); + + /* These are optional interrupts */ + err = devm_request_irq(dev, pc->wake_irq[i], + bcm2835_gpio_wake_irq_handler, + IRQF_SHARED, name, pc); + if (err) + dev_warn(dev, "unable to request wake IRQ %d\n", + pc->wake_irq[i]); + } + girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; err = gpiochip_add_data(&pc->gpio_chip, pc); if (err) { dev_err(dev, "could not add GPIO chip\n"); - return err; - } - - match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node); - if (match) { - bcm2835_pinctrl_desc.confops = - (const struct pinconf_ops *)match->data; + goto out_remove; } - pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc); - if (IS_ERR(pc->pctl_dev)) { - gpiochip_remove(&pc->gpio_chip); - return PTR_ERR(pc->pctl_dev); - } - - pc->gpio_range = bcm2835_pinctrl_gpio_range; - pc->gpio_range.base = pc->gpio_chip.base; - pc->gpio_range.gc = &pc->gpio_chip; - pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range); - return 0; + +out_remove: + pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range); + return err; } static struct platform_driver bcm2835_pinctrl_driver = { --- linux-oracle-5.4.0.orig/drivers/pinctrl/bcm/pinctrl-ns.c +++ linux-oracle-5.4.0/drivers/pinctrl/bcm/pinctrl-ns.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -13,7 +12,6 @@ #include #include #include -#include #include #define FLAG_BCM4708 BIT(1) @@ -24,8 +22,7 @@ struct device *dev; unsigned int chipset_flag; struct pinctrl_dev *pctldev; - struct regmap *regmap; - u32 offset; + void __iomem *base; struct pinctrl_desc pctldesc; struct ns_pinctrl_group *groups; @@ -232,9 +229,9 @@ unset |= BIT(pin_number); } - regmap_read(ns_pinctrl->regmap, ns_pinctrl->offset, &tmp); + tmp = readl(ns_pinctrl->base); tmp &= ~unset; - regmap_write(ns_pinctrl->regmap, ns_pinctrl->offset, tmp); + writel(tmp, ns_pinctrl->base); return 0; } @@ -266,13 +263,13 @@ static int ns_pinctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; const struct of_device_id *of_id; struct ns_pinctrl *ns_pinctrl; struct pinctrl_desc *pctldesc; struct pinctrl_pin_desc *pin; struct ns_pinctrl_group *group; struct ns_pinctrl_function *function; + struct resource *res; int i; ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL); @@ -290,18 +287,12 @@ return -EINVAL; ns_pinctrl->chipset_flag = (uintptr_t)of_id->data; - ns_pinctrl->regmap = syscon_node_to_regmap(of_get_parent(np)); - if (IS_ERR(ns_pinctrl->regmap)) { - int err = PTR_ERR(ns_pinctrl->regmap); - - dev_err(dev, "Failed to map pinctrl regs: %d\n", err); - - return err; - } - - if (of_property_read_u32(np, "offset", &ns_pinctrl->offset)) { - dev_err(dev, "Failed to get register offset\n"); - return -ENOENT; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "cru_gpio_control"); + ns_pinctrl->base = devm_ioremap_resource(dev, res); + if (IS_ERR(ns_pinctrl->base)) { + dev_err(dev, "Failed to map pinctrl regs\n"); + return PTR_ERR(ns_pinctrl->base); } memcpy(pctldesc, &ns_pinctrl_desc, sizeof(*pctldesc)); --- linux-oracle-5.4.0.orig/drivers/pinctrl/cirrus/Kconfig +++ linux-oracle-5.4.0/drivers/pinctrl/cirrus/Kconfig @@ -1,7 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only config PINCTRL_LOCHNAGAR tristate "Cirrus Logic Lochnagar pinctrl driver" - depends on MFD_LOCHNAGAR + # Avoid clash caused by MIPS defining RST, which is used in the driver + depends on MFD_LOCHNAGAR && !MIPS + select GPIOLIB select PINMUX select PINCONF select GENERIC_PINCONF --- linux-oracle-5.4.0.orig/drivers/pinctrl/core.c +++ linux-oracle-5.4.0/drivers/pinctrl/core.c @@ -203,6 +203,7 @@ const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; + int error; pindesc = pin_desc_get(pctldev, pin->number); if (pindesc) { @@ -224,18 +225,25 @@ } else { pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (!pindesc->name) { - kfree(pindesc); - return -ENOMEM; + error = -ENOMEM; + goto failed; } pindesc->dynamic_name = true; } pindesc->drv_data = pin->drv_data; - radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + error = radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); + if (error) + goto failed; + pr_debug("registered pin %d (%s) on %s\n", pin->number, pindesc->name, pctldev->desc->name); return 0; + +failed: + kfree(pindesc); + return error; } static int pinctrl_register_pins(struct pinctrl_dev *pctldev, @@ -1082,8 +1090,8 @@ * an -EPROBE_DEFER later, as that is the worst case. */ if (ret == -EPROBE_DEFER) { - pinctrl_free(p, false); mutex_unlock(&pinctrl_maps_mutex); + pinctrl_free(p, false); return ERR_PTR(ret); } } @@ -1237,17 +1245,17 @@ static int pinctrl_commit_state(struct pinctrl *p, struct pinctrl_state *state) { struct pinctrl_setting *setting, *setting2; - struct pinctrl_state *old_state = p->state; + struct pinctrl_state *old_state = READ_ONCE(p->state); int ret; - if (p->state) { + if (old_state) { /* * For each pinmux setting in the old state, forget SW's record * of mux owner for that pingroup. Any pingroups which are * still owned by the new state will be re-acquired by the call * to pinmux_enable_setting() in the loop below. */ - list_for_each_entry(setting, &p->state->settings, node) { + list_for_each_entry(setting, &old_state->settings, node) { if (setting->type != PIN_MAP_TYPE_MUX_GROUP) continue; pinmux_disable_setting(setting); @@ -2009,6 +2017,14 @@ return ERR_PTR(ret); } +static void pinctrl_uninit_controller(struct pinctrl_dev *pctldev, struct pinctrl_desc *pctldesc) +{ + pinctrl_free_pindescs(pctldev, pctldesc->pins, + pctldesc->npins); + mutex_destroy(&pctldev->mutex); + kfree(pctldev); +} + static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) { pctldev->p = create_pinctrl(pctldev->dev, pctldev); @@ -2025,7 +2041,6 @@ return PTR_ERR(pctldev->p); } - kref_get(&pctldev->p->users); pctldev->hog_default = pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); if (IS_ERR(pctldev->hog_default)) { @@ -2054,11 +2069,7 @@ error = pinctrl_claim_hogs(pctldev); if (error) { - dev_err(pctldev->dev, "could not claim hogs: %i\n", - error); - mutex_destroy(&pctldev->mutex); - kfree(pctldev); - + dev_err(pctldev->dev, "could not claim hogs: %i\n", error); return error; } @@ -2094,8 +2105,10 @@ return pctldev; error = pinctrl_enable(pctldev); - if (error) + if (error) { + pinctrl_uninit_controller(pctldev, pctldesc); return ERR_PTR(error); + } return pctldev; --- linux-oracle-5.4.0.orig/drivers/pinctrl/devicetree.c +++ linux-oracle-5.4.0/drivers/pinctrl/devicetree.c @@ -29,6 +29,13 @@ static void dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { + int i; + + for (i = 0; i < num_maps; ++i) { + kfree_const(map[i].dev_name); + map[i].dev_name = NULL; + } + if (pctldev) { const struct pinctrl_ops *ops = pctldev->desc->pctlops; if (ops->dt_free_map) @@ -63,7 +70,13 @@ /* Initialize common mapping table entry fields */ for (i = 0; i < num_maps; i++) { - map[i].dev_name = dev_name(p->dev); + const char *devname; + + devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL); + if (!devname) + goto err_free_map; + + map[i].dev_name = devname; map[i].name = statename; if (pctldev) map[i].ctrl_dev_name = dev_name(pctldev->dev); @@ -71,10 +84,8 @@ /* Remember the converted mapping table entries */ dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL); - if (!dt_map) { - dt_free_map(pctldev, map, num_maps); - return -ENOMEM; - } + if (!dt_map) + goto err_free_map; dt_map->pctldev = pctldev; dt_map->map = map; @@ -82,6 +93,10 @@ list_add_tail(&dt_map->node, &p->dt_maps); return pinctrl_register_map(map, num_maps, false); + +err_free_map: + dt_free_map(pctldev, map, num_maps); + return -ENOMEM; } struct pinctrl_dev *of_pinctrl_get(struct device_node *np) @@ -208,12 +223,16 @@ for (state = 0; ; state++) { /* Retrieve the pinctrl-* property */ propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); + if (!propname) { + ret = -ENOMEM; + goto err; + } prop = of_find_property(np, propname, &size); kfree(propname); if (!prop) { if (state == 0) { - of_node_put(np); - return -ENODEV; + ret = -ENODEV; + goto err; } break; } --- linux-oracle-5.4.0.orig/drivers/pinctrl/freescale/pinctrl-imx.c +++ linux-oracle-5.4.0/drivers/pinctrl/freescale/pinctrl-imx.c @@ -774,16 +774,6 @@ return 0; } -/* - * imx_free_resources() - free memory used by this driver - * @info: info driver instance - */ -static void imx_free_resources(struct imx_pinctrl *ipctl) -{ - if (ipctl->pctl) - pinctrl_unregister(ipctl->pctl); -} - int imx_pinctrl_probe(struct platform_device *pdev, const struct imx_pinctrl_soc_info *info) { @@ -874,23 +864,18 @@ &ipctl->pctl); if (ret) { dev_err(&pdev->dev, "could not register IMX pinctrl driver\n"); - goto free; + return ret; } ret = imx_pinctrl_probe_dt(pdev, ipctl); if (ret) { dev_err(&pdev->dev, "fail to probe dt properties\n"); - goto free; + return ret; } dev_info(&pdev->dev, "initialized IMX pinctrl driver\n"); return pinctrl_enable(ipctl->pctl); - -free: - imx_free_resources(ipctl); - - return ret; } static int __maybe_unused imx_pinctrl_suspend(struct device *dev) --- linux-oracle-5.4.0.orig/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ linux-oracle-5.4.0/drivers/pinctrl/freescale/pinctrl-imx1-core.c @@ -638,7 +638,6 @@ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); if (ret) { - pinctrl_unregister(ipctl->pctl); dev_err(&pdev->dev, "Failed to populate subdevices\n"); return ret; } --- linux-oracle-5.4.0.orig/drivers/pinctrl/freescale/pinctrl-mxs.c +++ linux-oracle-5.4.0/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -405,8 +405,8 @@ int ret; u32 val; - child = of_get_next_child(np, NULL); - if (!child) { + val = of_get_child_count(np); + if (val == 0) { dev_err(&pdev->dev, "no group is defined\n"); return -ENOENT; } --- linux-oracle-5.4.0.orig/drivers/pinctrl/freescale/pinctrl-scu.c +++ linux-oracle-5.4.0/drivers/pinctrl/freescale/pinctrl-scu.c @@ -23,12 +23,12 @@ struct imx_sc_rpc_msg hdr; u32 val; u16 pad; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_req_pad_get { struct imx_sc_rpc_msg hdr; u16 pad; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_resp_pad_get { struct imx_sc_rpc_msg hdr; --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-baytrail.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -110,7 +110,6 @@ struct platform_device *pdev; struct pinctrl_dev *pctl_dev; struct pinctrl_desc pctl_desc; - raw_spinlock_t lock; const struct intel_pinctrl_soc_data *soc_data; struct intel_community *communities_copy; struct byt_gpio_pin_context *saved_context; @@ -549,6 +548,8 @@ NULL }; +static DEFINE_RAW_SPINLOCK(byt_lock); + static struct intel_community *byt_get_community(struct byt_gpio *vg, unsigned int pin) { @@ -658,7 +659,7 @@ unsigned long flags; int i; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); for (i = 0; i < group.npins; i++) { void __iomem *padcfg0; @@ -678,7 +679,7 @@ writel(value, padcfg0); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static void byt_set_group_mixed_mux(struct byt_gpio *vg, @@ -688,7 +689,7 @@ unsigned long flags; int i; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); for (i = 0; i < group.npins; i++) { void __iomem *padcfg0; @@ -708,7 +709,7 @@ writel(value, padcfg0); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector, @@ -749,11 +750,17 @@ unsigned long flags; u32 value; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); - value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + + /* Do not clear direct-irq enabled IRQs (from gpio_disable_free) */ + if (value & BYT_DIRECT_IRQ_EN) + /* nothing to do */ ; + else + value &= ~(BYT_TRIG_POS | BYT_TRIG_NEG | BYT_TRIG_LVL); + writel(value, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_gpio_request_enable(struct pinctrl_dev *pctl_dev, @@ -765,7 +772,7 @@ u32 value, gpio_mux; unsigned long flags; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); /* * In most cases, func pin mux 000 means GPIO function. @@ -787,7 +794,7 @@ "pin %u forcibly re-configured as GPIO\n", offset); } - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); pm_runtime_get(&vg->pdev->dev); @@ -804,6 +811,21 @@ pm_runtime_put(&vg->pdev->dev); } +static void byt_gpio_direct_irq_check(struct byt_gpio *vg, + unsigned int offset) +{ + void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); + + /* + * Before making any direction modifications, do a check if gpio is set + * for direct IRQ. On Bay Trail, setting GPIO to output does not make + * sense, so let's at least inform the caller before they shoot + * themselves in the foot. + */ + if (readl(conf_reg) & BYT_DIRECT_IRQ_EN) + dev_info_once(&vg->pdev->dev, "Potential Error: Setting GPIO with direct_irq_en to output"); +} + static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev, struct pinctrl_gpio_range *range, unsigned int offset, @@ -811,28 +833,21 @@ { struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); - void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); unsigned long flags; u32 value; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(val_reg); value &= ~BYT_DIR_MASK; if (input) value |= BYT_OUTPUT_EN; else - /* - * Before making any direction modifications, do a check if gpio - * is set for direct IRQ. On baytrail, setting GPIO to output - * does not make sense, so let's at least warn the caller before - * they shoot themselves in the foot. - */ - WARN(readl(conf_reg) & BYT_DIRECT_IRQ_EN, - "Potential Error: Setting GPIO with direct_irq_en to output"); + byt_gpio_direct_irq_check(vg, offset); + writel(value, val_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } @@ -901,11 +916,11 @@ u32 conf, pull, val, debounce; u16 arg = 0; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); conf = readl(conf_reg); pull = conf & BYT_PULL_ASSIGN_MASK; val = readl(val_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -932,9 +947,9 @@ if (!(conf & BYT_DEBOUNCE_EN)) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); debounce = readl(db_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); switch (debounce & BYT_DEBOUNCE_PULSE_MASK) { case BYT_DEBOUNCE_PULSE_375US: @@ -986,7 +1001,7 @@ u32 conf, val, debounce; int i, ret = 0; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); conf = readl(conf_reg); val = readl(val_reg); @@ -1045,7 +1060,6 @@ break; case PIN_CONFIG_INPUT_DEBOUNCE: debounce = readl(db_reg); - debounce &= ~BYT_DEBOUNCE_PULSE_MASK; if (arg) conf |= BYT_DEBOUNCE_EN; @@ -1054,24 +1068,31 @@ switch (arg) { case 375: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_375US; break; case 750: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_750US; break; case 1500: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_1500US; break; case 3000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_3MS; break; case 6000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_6MS; break; case 12000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_12MS; break; case 24000: + debounce &= ~BYT_DEBOUNCE_PULSE_MASK; debounce |= BYT_DEBOUNCE_PULSE_24MS; break; default: @@ -1094,7 +1115,7 @@ if (!ret) writel(conf, conf_reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return ret; } @@ -1119,9 +1140,9 @@ unsigned long flags; u32 val; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); val = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return !!(val & BYT_LEVEL); } @@ -1136,13 +1157,13 @@ if (!reg) return; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); old_val = readl(reg); if (value) writel(old_val | BYT_LEVEL, reg); else writel(old_val & ~BYT_LEVEL, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) @@ -1155,9 +1176,9 @@ if (!reg) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); if (!(value & BYT_OUTPUT_EN)) return 0; @@ -1169,19 +1190,50 @@ static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { - return pinctrl_gpio_direction_input(chip->base + offset); + struct byt_gpio *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; + + raw_spin_lock_irqsave(&byt_lock, flags); + + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + reg |= BYT_OUTPUT_EN; + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); + return 0; } +/* + * Note despite the temptation this MUST NOT be converted into a call to + * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this + * MUST be done as a single BYT_VAL_REG register write. + * See the commit message of the commit adding this comment for details. + */ static int byt_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) { - int ret = pinctrl_gpio_direction_output(chip->base + offset); + struct byt_gpio *vg = gpiochip_get_data(chip); + void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); + unsigned long flags; + u32 reg; - if (ret) - return ret; + raw_spin_lock_irqsave(&byt_lock, flags); - byt_gpio_set(chip, offset, value); + byt_gpio_direct_irq_check(vg, offset); + reg = readl(val_reg); + reg &= ~BYT_DIR_MASK; + if (value) + reg |= BYT_LEVEL; + else + reg &= ~BYT_LEVEL; + + writel(reg, val_reg); + + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } @@ -1200,14 +1252,14 @@ const char *label; unsigned int pin; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); pin = vg->soc_data->pins[i].number; reg = byt_gpio_reg(vg, pin, BYT_CONF0_REG); if (!reg) { seq_printf(s, "Could not retrieve pin %i conf0 reg\n", pin); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); continue; } conf0 = readl(reg); @@ -1216,11 +1268,11 @@ if (!reg) { seq_printf(s, "Could not retrieve pin %i val reg\n", pin); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); continue; } val = readl(reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); comm = byt_get_community(vg, pin); if (!comm) { @@ -1290,6 +1342,7 @@ .direction_output = byt_gpio_direction_output, .get = byt_gpio_get, .set = byt_gpio_set, + .set_config = gpiochip_generic_config, .dbg_show = byt_gpio_dbg_show, }; @@ -1304,9 +1357,9 @@ if (!reg) return; - raw_spin_lock(&vg->lock); + raw_spin_lock(&byt_lock); writel(BIT(offset % 32), reg); - raw_spin_unlock(&vg->lock); + raw_spin_unlock(&byt_lock); } static void byt_irq_mask(struct irq_data *d) @@ -1330,7 +1383,7 @@ if (!reg) return; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); switch (irqd_get_trigger_type(d)) { @@ -1353,7 +1406,7 @@ writel(value, reg); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); } static int byt_irq_type(struct irq_data *d, unsigned int type) @@ -1367,7 +1420,7 @@ if (!reg || offset >= vg->chip.ngpio) return -EINVAL; - raw_spin_lock_irqsave(&vg->lock, flags); + raw_spin_lock_irqsave(&byt_lock, flags); value = readl(reg); WARN(value & BYT_DIRECT_IRQ_EN, @@ -1389,7 +1442,7 @@ else if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(d, handle_level_irq); - raw_spin_unlock_irqrestore(&vg->lock, flags); + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } @@ -1425,9 +1478,9 @@ continue; } - raw_spin_lock(&vg->lock); + raw_spin_lock(&byt_lock); pending = readl(reg); - raw_spin_unlock(&vg->lock); + raw_spin_unlock(&byt_lock); for_each_set_bit(pin, &pending, 32) { virq = irq_find_mapping(vg->chip.irq.domain, base + pin); generic_handle_irq(virq); @@ -1638,8 +1691,6 @@ return PTR_ERR(vg->pctl_dev); } - raw_spin_lock_init(&vg->lock); - ret = byt_gpio_probe(vg); if (ret) return ret; @@ -1654,8 +1705,11 @@ static int byt_gpio_suspend(struct device *dev) { struct byt_gpio *vg = dev_get_drvdata(dev); + unsigned long flags; int i; + raw_spin_lock_irqsave(&byt_lock, flags); + for (i = 0; i < vg->soc_data->npins; i++) { void __iomem *reg; u32 value; @@ -1676,14 +1730,18 @@ vg->saved_context[i].val = value; } + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } static int byt_gpio_resume(struct device *dev) { struct byt_gpio *vg = dev_get_drvdata(dev); + unsigned long flags; int i; + raw_spin_lock_irqsave(&byt_lock, flags); + for (i = 0; i < vg->soc_data->npins; i++) { void __iomem *reg; u32 value; @@ -1721,6 +1779,7 @@ } } + raw_spin_unlock_irqrestore(&byt_lock, flags); return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-cherryview.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1021,11 +1021,6 @@ break; - case PIN_CONFIG_DRIVE_OPEN_DRAIN: - if (!(ctrl1 & CHV_PADCTRL1_ODEN)) - return -EINVAL; - break; - case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { u32 cfg; @@ -1035,6 +1030,16 @@ return -EINVAL; break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (ctrl1 & CHV_PADCTRL1_ODEN) + return -EINVAL; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(ctrl1 & CHV_PADCTRL1_ODEN)) + return -EINVAL; + break; } default: @@ -1474,11 +1479,15 @@ struct chv_pinctrl *pctrl = gpiochip_get_data(gc); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned long pending; + unsigned long flags; u32 intr_line; chained_irq_enter(chip, desc); + raw_spin_lock_irqsave(&chv_lock, flags); pending = readl(pctrl->regs + CHV_INTSTAT); + raw_spin_unlock_irqrestore(&chv_lock, flags); + for_each_set_bit(intr_line, &pending, pctrl->community->nirqs) { unsigned irq, offset; --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-intel.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-intel.c @@ -459,9 +459,14 @@ writel(value, padcfg0); } +static int __intel_gpio_get_gpio_mode(u32 value) +{ + return (value & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; +} + static int intel_gpio_get_gpio_mode(void __iomem *padcfg0) { - return (readl(padcfg0) & PADCFG0_PMODE_MASK) >> PADCFG0_PMODE_SHIFT; + return __intel_gpio_get_gpio_mode(readl(padcfg0)); } static void intel_gpio_set_gpio_mode(void __iomem *padcfg0) @@ -662,6 +667,10 @@ value |= PADCFG1_TERM_UP; + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 5000; + switch (arg) { case 20000: value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; @@ -684,6 +693,10 @@ case PIN_CONFIG_BIAS_PULL_DOWN: value &= ~(PADCFG1_TERM_UP | PADCFG1_TERM_MASK); + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 5000; + switch (arg) { case 20000: value |= PADCFG1_TERM_20K << PADCFG1_TERM_SHIFT; @@ -1497,9 +1510,16 @@ EXPORT_SYMBOL_GPL(intel_pinctrl_probe_by_uid); #ifdef CONFIG_PM_SLEEP +static bool __intel_gpio_is_direct_irq(u32 value) +{ + return (value & PADCFG0_GPIROUTIOXAPIC) && (value & PADCFG0_GPIOTXDIS) && + (__intel_gpio_get_gpio_mode(value) == PADCFG0_PMODE_GPIO); +} + static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned int pin) { const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin); + u32 value; if (!pd || !intel_pad_usable(pctrl, pin)) return false; @@ -1514,6 +1534,24 @@ gpiochip_line_is_irq(&pctrl->chip, intel_pin_to_gpio(pctrl, pin))) return true; + /* + * The firmware on some systems may configure GPIO pins to be + * an interrupt source in so called "direct IRQ" mode. In such + * cases the GPIO controller driver has no idea if those pins + * are being used or not. At the same time, there is a known bug + * in the firmwares that don't restore the pin settings correctly + * after suspend, i.e. by an unknown reason the Rx value becomes + * inverted. + * + * Hence, let's save and restore the pins that are configured + * as GPIOs in the input mode with GPIROUTIOXAPIC bit set. + * + * See https://bugzilla.kernel.org/show_bug.cgi?id=214749. + */ + value = readl(intel_get_padcfg(pctrl, pin, PADCFG0)); + if (__intel_gpio_is_direct_irq(value)) + return true; + return false; } @@ -1623,7 +1661,12 @@ void __iomem *padcfg; u32 val; - if (!intel_pinctrl_should_save(pctrl, desc->number)) + if (!(intel_pinctrl_should_save(pctrl, desc->number) || + /* + * If the firmware mangled the register contents too much, + * check the saved value for the Direct IRQ mode. + */ + __intel_gpio_is_direct_irq(pads[i].padcfg0))) continue; padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0); --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-lewisburg.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-lewisburg.c @@ -33,6 +33,7 @@ .npins = ((e) - (s) + 1), \ } +/* Lewisburg */ static const struct pinctrl_pin_desc lbg_pins[] = { /* GPP_A */ PINCTRL_PIN(0, "RCINB"), @@ -72,7 +73,7 @@ PINCTRL_PIN(33, "SRCCLKREQB_4"), PINCTRL_PIN(34, "SRCCLKREQB_5"), PINCTRL_PIN(35, "GPP_B_11"), - PINCTRL_PIN(36, "GLB_RST_WARN_N"), + PINCTRL_PIN(36, "SLP_S0B"), PINCTRL_PIN(37, "PLTRSTB"), PINCTRL_PIN(38, "SPKR"), PINCTRL_PIN(39, "GPP_B_15"), @@ -185,96 +186,96 @@ PINCTRL_PIN(141, "GBE_PCI_DIS"), PINCTRL_PIN(142, "GBE_LAN_DIS"), PINCTRL_PIN(143, "GPP_I_10"), - PINCTRL_PIN(144, "GPIO_RCOMP_3P3"), /* GPP_J */ - PINCTRL_PIN(145, "GBE_LED_0_0"), - PINCTRL_PIN(146, "GBE_LED_0_1"), - PINCTRL_PIN(147, "GBE_LED_1_0"), - PINCTRL_PIN(148, "GBE_LED_1_1"), - PINCTRL_PIN(149, "GBE_LED_2_0"), - PINCTRL_PIN(150, "GBE_LED_2_1"), - PINCTRL_PIN(151, "GBE_LED_3_0"), - PINCTRL_PIN(152, "GBE_LED_3_1"), - PINCTRL_PIN(153, "GBE_SCL_0"), - PINCTRL_PIN(154, "GBE_SDA_0"), - PINCTRL_PIN(155, "GBE_SCL_1"), - PINCTRL_PIN(156, "GBE_SDA_1"), - PINCTRL_PIN(157, "GBE_SCL_2"), - PINCTRL_PIN(158, "GBE_SDA_2"), - PINCTRL_PIN(159, "GBE_SCL_3"), - PINCTRL_PIN(160, "GBE_SDA_3"), - PINCTRL_PIN(161, "GBE_SDP_0_0"), - PINCTRL_PIN(162, "GBE_SDP_0_1"), - PINCTRL_PIN(163, "GBE_SDP_1_0"), - PINCTRL_PIN(164, "GBE_SDP_1_1"), - PINCTRL_PIN(165, "GBE_SDP_2_0"), - PINCTRL_PIN(166, "GBE_SDP_2_1"), - PINCTRL_PIN(167, "GBE_SDP_3_0"), - PINCTRL_PIN(168, "GBE_SDP_3_1"), + PINCTRL_PIN(144, "GBE_LED_0_0"), + PINCTRL_PIN(145, "GBE_LED_0_1"), + PINCTRL_PIN(146, "GBE_LED_1_0"), + PINCTRL_PIN(147, "GBE_LED_1_1"), + PINCTRL_PIN(148, "GBE_LED_2_0"), + PINCTRL_PIN(149, "GBE_LED_2_1"), + PINCTRL_PIN(150, "GBE_LED_3_0"), + PINCTRL_PIN(151, "GBE_LED_3_1"), + PINCTRL_PIN(152, "GBE_SCL_0"), + PINCTRL_PIN(153, "GBE_SDA_0"), + PINCTRL_PIN(154, "GBE_SCL_1"), + PINCTRL_PIN(155, "GBE_SDA_1"), + PINCTRL_PIN(156, "GBE_SCL_2"), + PINCTRL_PIN(157, "GBE_SDA_2"), + PINCTRL_PIN(158, "GBE_SCL_3"), + PINCTRL_PIN(159, "GBE_SDA_3"), + PINCTRL_PIN(160, "GBE_SDP_0_0"), + PINCTRL_PIN(161, "GBE_SDP_0_1"), + PINCTRL_PIN(162, "GBE_SDP_1_0"), + PINCTRL_PIN(163, "GBE_SDP_1_1"), + PINCTRL_PIN(164, "GBE_SDP_2_0"), + PINCTRL_PIN(165, "GBE_SDP_2_1"), + PINCTRL_PIN(166, "GBE_SDP_3_0"), + PINCTRL_PIN(167, "GBE_SDP_3_1"), /* GPP_K */ - PINCTRL_PIN(169, "GBE_RMIICLK"), - PINCTRL_PIN(170, "GBE_RMII_TXD_0"), - PINCTRL_PIN(171, "GBE_RMII_TXD_1"), + PINCTRL_PIN(168, "GBE_RMIICLK"), + PINCTRL_PIN(169, "GBE_RMII_RXD_0"), + PINCTRL_PIN(170, "GBE_RMII_RXD_1"), + PINCTRL_PIN(171, "GBE_RMII_CRS_DV"), PINCTRL_PIN(172, "GBE_RMII_TX_EN"), - PINCTRL_PIN(173, "GBE_RMII_CRS_DV"), - PINCTRL_PIN(174, "GBE_RMII_RXD_0"), - PINCTRL_PIN(175, "GBE_RMII_RXD_1"), - PINCTRL_PIN(176, "GBE_RMII_RX_ER"), - PINCTRL_PIN(177, "GBE_RMII_ARBIN"), - PINCTRL_PIN(178, "GBE_RMII_ARB_OUT"), - PINCTRL_PIN(179, "PE_RST_N"), - PINCTRL_PIN(180, "GPIO_RCOMP_1P8_3P3"), + PINCTRL_PIN(173, "GBE_RMII_TXD_0"), + PINCTRL_PIN(174, "GBE_RMII_TXD_1"), + PINCTRL_PIN(175, "GBE_RMII_RX_ER"), + PINCTRL_PIN(176, "GBE_RMII_ARBIN"), + PINCTRL_PIN(177, "GBE_RMII_ARB_OUT"), + PINCTRL_PIN(178, "PE_RST_N"), /* GPP_G */ - PINCTRL_PIN(181, "FAN_TACH_0"), - PINCTRL_PIN(182, "FAN_TACH_1"), - PINCTRL_PIN(183, "FAN_TACH_2"), - PINCTRL_PIN(184, "FAN_TACH_3"), - PINCTRL_PIN(185, "FAN_TACH_4"), - PINCTRL_PIN(186, "FAN_TACH_5"), - PINCTRL_PIN(187, "FAN_TACH_6"), - PINCTRL_PIN(188, "FAN_TACH_7"), - PINCTRL_PIN(189, "FAN_PWM_0"), - PINCTRL_PIN(190, "FAN_PWM_1"), - PINCTRL_PIN(191, "FAN_PWM_2"), - PINCTRL_PIN(192, "FAN_PWM_3"), - PINCTRL_PIN(193, "GSXDOUT"), - PINCTRL_PIN(194, "GSXSLOAD"), - PINCTRL_PIN(195, "GSXDIN"), - PINCTRL_PIN(196, "GSXSRESETB"), - PINCTRL_PIN(197, "GSXCLK"), - PINCTRL_PIN(198, "ADR_COMPLETE"), - PINCTRL_PIN(199, "NMIB"), - PINCTRL_PIN(200, "SMIB"), - PINCTRL_PIN(201, "SSATA_DEVSLP_0"), - PINCTRL_PIN(202, "SSATA_DEVSLP_1"), - PINCTRL_PIN(203, "SSATA_DEVSLP_2"), - PINCTRL_PIN(204, "SSATAXPCIE0_SSATAGP0"), + PINCTRL_PIN(179, "FAN_TACH_0"), + PINCTRL_PIN(180, "FAN_TACH_1"), + PINCTRL_PIN(181, "FAN_TACH_2"), + PINCTRL_PIN(182, "FAN_TACH_3"), + PINCTRL_PIN(183, "FAN_TACH_4"), + PINCTRL_PIN(184, "FAN_TACH_5"), + PINCTRL_PIN(185, "FAN_TACH_6"), + PINCTRL_PIN(186, "FAN_TACH_7"), + PINCTRL_PIN(187, "FAN_PWM_0"), + PINCTRL_PIN(188, "FAN_PWM_1"), + PINCTRL_PIN(189, "FAN_PWM_2"), + PINCTRL_PIN(190, "FAN_PWM_3"), + PINCTRL_PIN(191, "GSXDOUT"), + PINCTRL_PIN(192, "GSXSLOAD"), + PINCTRL_PIN(193, "GSXDIN"), + PINCTRL_PIN(194, "GSXSRESETB"), + PINCTRL_PIN(195, "GSXCLK"), + PINCTRL_PIN(196, "ADR_COMPLETE"), + PINCTRL_PIN(197, "NMIB"), + PINCTRL_PIN(198, "SMIB"), + PINCTRL_PIN(199, "SSATA_DEVSLP_0"), + PINCTRL_PIN(200, "SSATA_DEVSLP_1"), + PINCTRL_PIN(201, "SSATA_DEVSLP_2"), + PINCTRL_PIN(202, "SSATAXPCIE0_SSATAGP0"), /* GPP_H */ - PINCTRL_PIN(205, "SRCCLKREQB_6"), - PINCTRL_PIN(206, "SRCCLKREQB_7"), - PINCTRL_PIN(207, "SRCCLKREQB_8"), - PINCTRL_PIN(208, "SRCCLKREQB_9"), - PINCTRL_PIN(209, "SRCCLKREQB_10"), - PINCTRL_PIN(210, "SRCCLKREQB_11"), - PINCTRL_PIN(211, "SRCCLKREQB_12"), - PINCTRL_PIN(212, "SRCCLKREQB_13"), - PINCTRL_PIN(213, "SRCCLKREQB_14"), - PINCTRL_PIN(214, "SRCCLKREQB_15"), - PINCTRL_PIN(215, "SML2CLK"), - PINCTRL_PIN(216, "SML2DATA"), - PINCTRL_PIN(217, "SML2ALERTB"), - PINCTRL_PIN(218, "SML3CLK"), - PINCTRL_PIN(219, "SML3DATA"), - PINCTRL_PIN(220, "SML3ALERTB"), - PINCTRL_PIN(221, "SML4CLK"), - PINCTRL_PIN(222, "SML4DATA"), - PINCTRL_PIN(223, "SML4ALERTB"), - PINCTRL_PIN(224, "SSATAXPCIE1_SSATAGP1"), - PINCTRL_PIN(225, "SSATAXPCIE2_SSATAGP2"), - PINCTRL_PIN(226, "SSATAXPCIE3_SSATAGP3"), - PINCTRL_PIN(227, "SSATAXPCIE4_SSATAGP4"), - PINCTRL_PIN(228, "SSATAXPCIE5_SSATAGP5"), + PINCTRL_PIN(203, "SRCCLKREQB_6"), + PINCTRL_PIN(204, "SRCCLKREQB_7"), + PINCTRL_PIN(205, "SRCCLKREQB_8"), + PINCTRL_PIN(206, "SRCCLKREQB_9"), + PINCTRL_PIN(207, "SRCCLKREQB_10"), + PINCTRL_PIN(208, "SRCCLKREQB_11"), + PINCTRL_PIN(209, "SRCCLKREQB_12"), + PINCTRL_PIN(210, "SRCCLKREQB_13"), + PINCTRL_PIN(211, "SRCCLKREQB_14"), + PINCTRL_PIN(212, "SRCCLKREQB_15"), + PINCTRL_PIN(213, "SML2CLK"), + PINCTRL_PIN(214, "SML2DATA"), + PINCTRL_PIN(215, "SML2ALERTB"), + PINCTRL_PIN(216, "SML3CLK"), + PINCTRL_PIN(217, "SML3DATA"), + PINCTRL_PIN(218, "SML3ALERTB"), + PINCTRL_PIN(219, "SML4CLK"), + PINCTRL_PIN(220, "SML4DATA"), + PINCTRL_PIN(221, "SML4ALERTB"), + PINCTRL_PIN(222, "SSATAXPCIE1_SSATAGP1"), + PINCTRL_PIN(223, "SSATAXPCIE2_SSATAGP2"), + PINCTRL_PIN(224, "SSATAXPCIE3_SSATAGP3"), + PINCTRL_PIN(225, "SSATAXPCIE4_SSATAGP4"), + PINCTRL_PIN(226, "SSATAXPCIE5_SSATAGP5"), /* GPP_L */ + PINCTRL_PIN(227, "GPP_L_0"), + PINCTRL_PIN(228, "EC_CSME_INTR_OUT"), PINCTRL_PIN(229, "VISA2CH0_D0"), PINCTRL_PIN(230, "VISA2CH0_D1"), PINCTRL_PIN(231, "VISA2CH0_D2"), @@ -298,9 +299,9 @@ static const struct intel_community lbg_communities[] = { LBG_COMMUNITY(0, 0, 71), LBG_COMMUNITY(1, 72, 132), - LBG_COMMUNITY(3, 133, 144), - LBG_COMMUNITY(4, 145, 180), - LBG_COMMUNITY(5, 181, 246), + LBG_COMMUNITY(3, 133, 143), + LBG_COMMUNITY(4, 144, 178), + LBG_COMMUNITY(5, 179, 246), }; static const struct intel_pinctrl_soc_data lbg_soc_data = { --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-merrifield.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -741,6 +741,10 @@ mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; bits |= BUFCFG_PU_EN; + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 20000; + switch (arg) { case 50000: bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; @@ -761,6 +765,10 @@ mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; bits |= BUFCFG_PD_EN; + /* Set default strength value in case none is given */ + if (arg == 1) + arg = 20000; + switch (arg) { case 50000: bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; --- linux-oracle-5.4.0.orig/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ linux-oracle-5.4.0/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -15,17 +15,18 @@ #include "pinctrl-intel.h" -#define SPT_PAD_OWN 0x020 -#define SPT_PADCFGLOCK 0x0a0 -#define SPT_HOSTSW_OWN 0x0d0 -#define SPT_GPI_IS 0x100 -#define SPT_GPI_IE 0x120 +#define SPT_PAD_OWN 0x020 +#define SPT_H_PADCFGLOCK 0x090 +#define SPT_LP_PADCFGLOCK 0x0a0 +#define SPT_HOSTSW_OWN 0x0d0 +#define SPT_GPI_IS 0x100 +#define SPT_GPI_IE 0x120 #define SPT_COMMUNITY(b, s, e) \ { \ .barno = (b), \ .padown_offset = SPT_PAD_OWN, \ - .padcfglock_offset = SPT_PADCFGLOCK, \ + .padcfglock_offset = SPT_LP_PADCFGLOCK, \ .hostown_offset = SPT_HOSTSW_OWN, \ .is_offset = SPT_GPI_IS, \ .ie_offset = SPT_GPI_IE, \ @@ -47,8 +48,9 @@ { \ .barno = (b), \ .padown_offset = SPT_PAD_OWN, \ - .padcfglock_offset = SPT_PADCFGLOCK, \ + .padcfglock_offset = SPT_H_PADCFGLOCK, \ .hostown_offset = SPT_HOSTSW_OWN, \ + .is_offset = SPT_GPI_IS, \ .ie_offset = SPT_GPI_IE, \ .pin_base = (s), \ .npins = ((e) - (s) + 1), \ --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/mtk-eint.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/mtk-eint.c @@ -277,12 +277,15 @@ static unsigned int mtk_eint_hw_init(struct mtk_eint *eint) { - void __iomem *reg = eint->base + eint->regs->dom_en; + void __iomem *dom_en = eint->base + eint->regs->dom_en; + void __iomem *mask_set = eint->base + eint->regs->mask_set; unsigned int i; for (i = 0; i < eint->hw->ap_num; i += 32) { - writel(0xffffffff, reg); - reg += 4; + writel(0xffffffff, dom_en); + writel(0xffffffff, mask_set); + dom_en += 4; + mask_set += 4; } return 0; --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-mt6765.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-mt6765.c @@ -1070,15 +1070,12 @@ .ngrps = ARRAY_SIZE(mtk_pins_mt6765), .eint_hw = &mt6765_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt6765_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt6765_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set, - .bias_disable_get = mtk_pinconf_bias_disable_get, - .bias_set = mtk_pinconf_bias_set, - .bias_get = mtk_pinconf_bias_get, - .drive_set = mtk_pinconf_drive_set_rev1, - .drive_get = mtk_pinconf_drive_get_rev1, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, + .drive_set = mtk_pinconf_drive_set_raw, + .drive_get = mtk_pinconf_drive_get_raw, .adv_pull_get = mtk_pinconf_adv_pull_get, .adv_pull_set = mtk_pinconf_adv_pull_set, }; --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-mt8183.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-mt8183.c @@ -554,13 +554,10 @@ .ngrps = ARRAY_SIZE(mtk_pins_mt8183), .eint_hw = &mt8183_eint_hw, .gpio_m = 0, - .ies_present = true, .base_names = mt8183_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt8183_pinctrl_register_base_names), - .bias_disable_set = mtk_pinconf_bias_disable_set_rev1, - .bias_disable_get = mtk_pinconf_bias_disable_get_rev1, - .bias_set = mtk_pinconf_bias_set_rev1, - .bias_get = mtk_pinconf_bias_get_rev1, + .bias_set_combo = mtk_pinconf_bias_set_combo, + .bias_get_combo = mtk_pinconf_bias_get_combo, .drive_set = mtk_pinconf_drive_set_rev1, .drive_get = mtk_pinconf_drive_get_rev1, .adv_pull_get = mtk_pinconf_adv_pull_get, --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -6,6 +6,7 @@ * */ +#include #include #include #include @@ -66,34 +67,44 @@ const struct mtk_pin_desc *desc, int field, struct mtk_pin_field *pfd) { - const struct mtk_pin_field_calc *c, *e; + const struct mtk_pin_field_calc *c; const struct mtk_pin_reg_calc *rc; + int start = 0, end, check; + bool found = false; u32 bits; if (hw->soc->reg_cal && hw->soc->reg_cal[field].range) { rc = &hw->soc->reg_cal[field]; } else { dev_dbg(hw->dev, - "Not support field %d for pin %d (%s)\n", - field, desc->number, desc->name); + "Not support field %d for this soc\n", field); return -ENOTSUPP; } - c = rc->range; - e = c + rc->nranges; + end = rc->nranges - 1; - while (c < e) { - if (desc->number >= c->s_pin && desc->number <= c->e_pin) + while (start <= end) { + check = (start + end) >> 1; + if (desc->number >= rc->range[check].s_pin + && desc->number <= rc->range[check].e_pin) { + found = true; + break; + } else if (start == end) break; - c++; + else if (desc->number < rc->range[check].s_pin) + end = check - 1; + else + start = check + 1; } - if (c >= e) { + if (!found) { dev_dbg(hw->dev, "Not support field %d for pin = %d (%s)\n", field, desc->number, desc->name); return -ENOTSUPP; } + c = rc->range + check; + if (c->i_base > hw->nbase - 1) { dev_err(hw->dev, "Invalid base for field %d for pin = %d (%s)\n", @@ -182,6 +193,9 @@ if (err) return err; + if (value < 0 || value > pf.mask) + return -EINVAL; + if (!pf.next) mtk_rmw(hw, pf.index, pf.offset, pf.mask << pf.bitpos, (value & pf.mask) << pf.bitpos); @@ -236,8 +250,12 @@ desc = (const struct mtk_pin_desc *)hw->soc->pins; *gpio_chip = &hw->chip; - /* Be greedy to guess first gpio_n is equal to eint_n */ - if (desc[eint_n].eint.eint_n == eint_n) + /* + * Be greedy to guess first gpio_n is equal to eint_n. + * Only eint virtual eint number is greater than gpio number. + */ + if (hw->soc->npins > eint_n && + desc[eint_n].eint.eint_n == eint_n) *gpio_n = eint_n; else *gpio_n = mtk_xt_find_eint_num(hw, eint_n); @@ -502,6 +520,226 @@ return 0; } +/* Combo for the following pull register type: + * 1. PU + PD + * 2. PULLSEL + PULLEN + * 3. PUPD + R0 + R1 + */ +static int mtk_pinconf_bias_set_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, pu, pd; + + if (arg == MTK_DISABLE) { + pu = 0; + pd = 0; + } else if ((arg == MTK_ENABLE) && pullup) { + pu = 1; + pd = 0; + } else if ((arg == MTK_ENABLE) && !pullup) { + pu = 0; + pd = 1; + } else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PU, pu); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PD, pd); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, enable; + + if (arg == MTK_DISABLE) + enable = 0; + else if (arg == MTK_ENABLE) + enable = 1; + else { + err = -EINVAL; + goto out; + } + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + +out: + return err; +} + +static int mtk_pinconf_bias_set_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err, r0, r1; + + if ((arg == MTK_DISABLE) || (arg == MTK_PUPD_SET_R1R0_00)) { + pullup = 0; + r0 = 0; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_01) { + r0 = 1; + r1 = 0; + } else if (arg == MTK_PUPD_SET_R1R0_10) { + r0 = 0; + r1 = 1; + } else if (arg == MTK_PUPD_SET_R1R0_11) { + r0 = 1; + r1 = 1; + } else { + err = -EINVAL; + goto out; + } + + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_PUPD, !pullup); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R0, r0); + if (err) + goto out; + + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_R1, r1); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pu_pd(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, pu, pd; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PU, &pu); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PD, &pd); + if (err) + goto out; + + if (pu == 0 && pd == 0) { + *pullup = 0; + *enable = MTK_DISABLE; + } else if (pu == 1 && pd == 0) { + *pullup = 1; + *enable = MTK_ENABLE; + } else if (pu == 0 && pd == 1) { + *pullup = 0; + *enable = MTK_ENABLE; + } else + err = -EINVAL; + +out: + return err; +} + +static int mtk_pinconf_bias_get_pullsel_pullen(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLSEL, pullup); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PULLEN, enable); + +out: + return err; +} + +static int mtk_pinconf_bias_get_pupd_r1_r0(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err, r0, r1; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_PUPD, pullup); + if (err) + goto out; + /* MTK HW PUPD bit: 1 for pull-down, 0 for pull-up */ + *pullup = !(*pullup); + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R0, &r0); + if (err) + goto out; + + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_R1, &r1); + if (err) + goto out; + + if ((r1 == 0) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_00; + else if ((r1 == 0) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_01; + else if ((r1 == 1) && (r0 == 0)) + *enable = MTK_PUPD_SET_R1R0_10; + else if ((r1 == 1) && (r0 == 1)) + *enable = MTK_PUPD_SET_R1R0_11; + else + err = -EINVAL; + +out: + return err; +} + +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 arg) +{ + int err; + + err = mtk_pinconf_bias_set_pu_pd(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pullsel_pullen(hw, desc, pullup, arg); + if (!err) + goto out; + + err = mtk_pinconf_bias_set_pupd_r1_r0(hw, desc, pullup, arg); + +out: + return err; +} + +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable) +{ + int err; + + err = mtk_pinconf_bias_get_pu_pd(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pullsel_pullen(hw, desc, pullup, enable); + if (!err) + goto out; + + err = mtk_pinconf_bias_get_pupd_r1_r0(hw, desc, pullup, enable); + +out: + return err; +} + /* Revision 0 */ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg) @@ -593,6 +831,18 @@ return 0; } +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg) +{ + return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DRV, arg); +} + +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val) +{ + return mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, val); +} + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg) @@ -626,7 +876,9 @@ if (err) return err; } else { - return -ENOTSUPP; + err = mtk_pinconf_bias_set_rev1(hw, desc, pullup); + if (err) + err = mtk_pinconf_bias_set(hw, desc, pullup); } } --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.h @@ -216,6 +216,11 @@ int (*bias_get)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); + int (*bias_set_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 pullup, u32 arg); + int (*bias_get_combo)(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 *pullup, u32 *arg); + int (*drive_set)(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); int (*drive_get)(struct mtk_pinctrl *hw, @@ -277,6 +282,12 @@ int mtk_pinconf_bias_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, int *res); +int mtk_pinconf_bias_set_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 pullup, u32 enable); +int mtk_pinconf_bias_get_combo(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, + u32 *pullup, u32 *enable); int mtk_pinconf_drive_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, u32 arg); @@ -288,6 +299,11 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, int *val); +int mtk_pinconf_drive_set_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, u32 arg); +int mtk_pinconf_drive_get_raw(struct mtk_pinctrl *hw, + const struct mtk_pin_desc *desc, int *val); + int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, const struct mtk_pin_desc *desc, bool pullup, u32 arg); --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -1038,6 +1038,7 @@ node = of_parse_phandle(np, "mediatek,pctl-regmap", 0); if (node) { pctl->regmap1 = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(pctl->regmap1)) return PTR_ERR(pctl->regmap1); } else if (regmap) { @@ -1051,6 +1052,7 @@ node = of_parse_phandle(np, "mediatek,pctl-regmap", 1); if (node) { pctl->regmap2 = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(pctl->regmap2)) return PTR_ERR(pctl->regmap2); } --- linux-oracle-5.4.0.orig/drivers/pinctrl/mediatek/pinctrl-paris.c +++ linux-oracle-5.4.0/drivers/pinctrl/mediatek/pinctrl-paris.c @@ -78,265 +78,186 @@ { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); u32 param = pinconf_to_config_param(*config); - int val, val2, err, reg, ret = 1; + int pullup, reg, err = -ENOTSUPP, ret = 1; const struct mtk_pin_desc *desc; + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch (param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_get) { - err = hw->soc->bias_disable_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_get) { - err = hw->soc->bias_get(hw, desc, 1, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_get) { - err = hw->soc->bias_get(hw, desc, 0, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; + if (!hw->soc->bias_get_combo) + break; + err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); + if (err) + break; + if (ret == MTK_PUPD_SET_R1R0_00) + ret = MTK_DISABLE; + if (param == PIN_CONFIG_BIAS_DISABLE) { + if (ret != MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_UP) { + if (!pullup || ret == MTK_DISABLE) + err = -EINVAL; + } else if (param == PIN_CONFIG_BIAS_PULL_DOWN) { + if (pullup || ret == MTK_DISABLE) + err = -EINVAL; } break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &val); - if (err) - return err; - - if (!val) - return -EINVAL; - + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SR, &ret); break; case PIN_CONFIG_INPUT_ENABLE: - case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_IES, &ret); + if (!ret) + err = -EINVAL; + break; + case PIN_CONFIG_OUTPUT: + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; + break; - /* HW takes input mode as zero; output mode as non-zero */ - if ((val && param == PIN_CONFIG_INPUT_ENABLE) || - (!val && param == PIN_CONFIG_OUTPUT_ENABLE)) - return -EINVAL; + if (!ret) { + err = -EINVAL; + break; + } + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DO, &ret); break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &val); - if (err) - return err; - - err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &val2); + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &ret); if (err) - return err; - - if (val || !val2) - return -EINVAL; + break; + /* return error when in output mode + * because schmitt trigger only work in input mode + */ + if (ret) { + err = -EINVAL; + break; + } + err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_SMT, &ret); + if (!ret) + err = -EINVAL; break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_get) { - err = hw->soc->drive_get(hw, desc, &ret); - if (err) - return err; - } else { - err = -ENOTSUPP; - } + if (!hw->soc->drive_get) + break; + err = hw->soc->drive_get(hw, desc, &ret); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - - err = mtk_hw_get_value(hw, desc, reg, &val); - if (err) - return err; - - ret = val; - + err = mtk_hw_get_value(hw, desc, reg, &ret); break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_get) { - bool pullup; - - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_pull_get) + break; + pullup = param == MTK_PIN_CONFIG_PU_ADV; + err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_get) { - err = hw->soc->adv_drive_get(hw, desc, &ret); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_drive_get) + break; + err = hw->soc->adv_drive_get(hw, desc, &ret); break; - default: - return -ENOTSUPP; } - *config = pinconf_to_config_packed(param, ret); + if (!err) + *config = pinconf_to_config_packed(param, ret); - return 0; + return err; } static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, - enum pin_config_param param, - enum pin_config_param arg) + enum pin_config_param param, u32 arg) { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); const struct mtk_pin_desc *desc; - int err = 0; + int err = -ENOTSUPP; u32 reg; + if (pin >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; switch ((u32)param) { case PIN_CONFIG_BIAS_DISABLE: - if (hw->soc->bias_disable_set) { - err = hw->soc->bias_disable_set(hw, desc); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); break; case PIN_CONFIG_BIAS_PULL_UP: - if (hw->soc->bias_set) { - err = hw->soc->bias_set(hw, desc, 1); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 1, arg); break; case PIN_CONFIG_BIAS_PULL_DOWN: - if (hw->soc->bias_set) { - err = hw->soc->bias_set(hw, desc, 0); - if (err) - return err; - } else { - return -ENOTSUPP; - } - break; - case PIN_CONFIG_OUTPUT_ENABLE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - MTK_DISABLE); - if (err) - goto err; - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_OUTPUT); - if (err) - goto err; + if (!hw->soc->bias_set_combo) + break; + err = hw->soc->bias_set_combo(hw, desc, 0, arg); break; case PIN_CONFIG_INPUT_ENABLE: - if (hw->soc->ies_present) { - mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, - MTK_ENABLE); - } - - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - MTK_INPUT); - if (err) - goto err; + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_IES, !!arg); break; case PIN_CONFIG_SLEW_RATE: - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, - arg); - if (err) - goto err; - + /* regard all non-zero value as enable */ + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SR, !!arg); break; case PIN_CONFIG_OUTPUT: err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, MTK_OUTPUT); if (err) - goto err; + break; err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, arg); - if (err) - goto err; break; + case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT_ENABLE: /* arg = 1: Input mode & SMT enable ; * arg = 0: Output mode & SMT disable */ - arg = arg ? 2 : 1; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, - arg & 1); + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DIR, !arg); if (err) - goto err; + break; - err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, - !!(arg & 2)); - if (err) - goto err; + err = mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_SMT, !!arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - if (hw->soc->drive_set) { - err = hw->soc->drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->drive_set) + break; + err = hw->soc->drive_set(hw, desc, arg); break; case MTK_PIN_CONFIG_TDSEL: case MTK_PIN_CONFIG_RDSEL: reg = (param == MTK_PIN_CONFIG_TDSEL) ? PINCTRL_PIN_REG_TDSEL : PINCTRL_PIN_REG_RDSEL; - err = mtk_hw_set_value(hw, desc, reg, arg); - if (err) - goto err; break; case MTK_PIN_CONFIG_PU_ADV: case MTK_PIN_CONFIG_PD_ADV: - if (hw->soc->adv_pull_set) { - bool pullup; - - pullup = param == MTK_PIN_CONFIG_PU_ADV; - err = hw->soc->adv_pull_set(hw, desc, pullup, - arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_pull_set) + break; + err = hw->soc->adv_pull_set(hw, desc, + (param == MTK_PIN_CONFIG_PU_ADV), + arg); break; case MTK_PIN_CONFIG_DRV_ADV: - if (hw->soc->adv_drive_set) { - err = hw->soc->adv_drive_set(hw, desc, arg); - if (err) - return err; - } else { - return -ENOTSUPP; - } + if (!hw->soc->adv_drive_set) + break; + err = hw->soc->adv_drive_set(hw, desc, arg); break; - default: - err = -ENOTSUPP; } -err: return err; } @@ -647,10 +568,10 @@ unsigned long *config) { struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev); + struct mtk_pinctrl_group *grp = &hw->groups[group]; - *config = hw->groups[group].config; - - return 0; + /* One pin per group only */ + return mtk_pinconf_get(pctldev, grp->pin, config); } static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, @@ -666,8 +587,6 @@ pinconf_to_config_argument(configs[i])); if (ret < 0) return ret; - - grp->config = configs[i]; } return 0; @@ -693,6 +612,9 @@ const struct mtk_pin_desc *desc; int value, err; + if (gpio >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DIR, &value); @@ -708,6 +630,9 @@ const struct mtk_pin_desc *desc; int value, err; + if (gpio >= hw->soc->npins) + return -EINVAL; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DI, &value); @@ -722,6 +647,9 @@ struct mtk_pinctrl *hw = gpiochip_get_data(chip); const struct mtk_pin_desc *desc; + if (gpio >= hw->soc->npins) + return; + desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_DO, !!value); @@ -729,12 +657,22 @@ static int mtk_gpio_direction_input(struct gpio_chip *chip, unsigned int gpio) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio >= hw->soc->npins) + return -EINVAL; + return pinctrl_gpio_direction_input(chip->base + gpio); } static int mtk_gpio_direction_output(struct gpio_chip *chip, unsigned int gpio, int value) { + struct mtk_pinctrl *hw = gpiochip_get_data(chip); + + if (gpio >= hw->soc->npins) + return -EINVAL; + mtk_gpio_set(chip, gpio, value); return pinctrl_gpio_direction_output(chip->base + gpio); --- linux-oracle-5.4.0.orig/drivers/pinctrl/meson/pinctrl-meson-axg.c +++ linux-oracle-5.4.0/drivers/pinctrl/meson/pinctrl-meson-axg.c @@ -400,6 +400,7 @@ GPIO_GROUP(GPIOA_15), GPIO_GROUP(GPIOA_16), GPIO_GROUP(GPIOA_17), + GPIO_GROUP(GPIOA_18), GPIO_GROUP(GPIOA_19), GPIO_GROUP(GPIOA_20), --- linux-oracle-5.4.0.orig/drivers/pinctrl/meson/pinctrl-meson-gxl.c +++ linux-oracle-5.4.0/drivers/pinctrl/meson/pinctrl-meson-gxl.c @@ -147,8 +147,8 @@ static const unsigned int sdio_d1_pins[] = { GPIOX_1 }; static const unsigned int sdio_d2_pins[] = { GPIOX_2 }; static const unsigned int sdio_d3_pins[] = { GPIOX_3 }; -static const unsigned int sdio_cmd_pins[] = { GPIOX_4 }; -static const unsigned int sdio_clk_pins[] = { GPIOX_5 }; +static const unsigned int sdio_clk_pins[] = { GPIOX_4 }; +static const unsigned int sdio_cmd_pins[] = { GPIOX_5 }; static const unsigned int sdio_irq_pins[] = { GPIOX_7 }; static const unsigned int nand_ce0_pins[] = { BOOT_8 }; --- linux-oracle-5.4.0.orig/drivers/pinctrl/meson/pinctrl-meson.c +++ linux-oracle-5.4.0/drivers/pinctrl/meson/pinctrl-meson.c @@ -441,6 +441,7 @@ return ret; meson_calc_reg_and_bit(bank, pin, REG_DS, ®, &bit); + bit = bit << 1; ret = regmap_read(pc->reg_ds, reg, &val); if (ret) --- linux-oracle-5.4.0.orig/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ linux-oracle-5.4.0/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -166,10 +166,14 @@ PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"), PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"), PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"), - PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"), - PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), - PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), - PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), + PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5), + "pwm", "led"), + PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6), + "pwm", "led"), PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), @@ -183,11 +187,6 @@ PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), 18, 2, "gpio", "uart"), - PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), - PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), - PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), - PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), - }; static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { @@ -595,10 +594,10 @@ regmap_read(info->regmap, in_reg, &in_val); /* Set initial polarity based on current input level. */ - if (in_val & d->mask) - val |= d->mask; /* falling */ + if (in_val & BIT(d->hwirq % GPIO_PER_REG)) + val |= BIT(d->hwirq % GPIO_PER_REG); /* falling */ else - val &= ~d->mask; /* rising */ + val &= ~(BIT(d->hwirq % GPIO_PER_REG)); /* rising */ break; } default: @@ -774,7 +773,7 @@ for (i = 0; i < nr_irq_parent; i++) { int irq = irq_of_parse_and_map(np, i); - if (irq < 0) + if (!irq) continue; gpiochip_set_chained_irqchip(gc, irqchip, irq, --- linux-oracle-5.4.0.orig/drivers/pinctrl/mvebu/pinctrl-armada-xp.c +++ linux-oracle-5.4.0/drivers/pinctrl/mvebu/pinctrl-armada-xp.c @@ -414,7 +414,7 @@ MPP_VAR_FUNCTION(0x1, "i2c0", "sck", V_98DX3236_PLUS)), MPP_MODE(15, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS), - MPP_VAR_FUNCTION(0x4, "i2c0", "sda", V_98DX3236_PLUS)), + MPP_VAR_FUNCTION(0x1, "i2c0", "sda", V_98DX3236_PLUS)), MPP_MODE(16, MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS), MPP_VAR_FUNCTION(0x4, "dev", "oe", V_98DX3236_PLUS)), --- linux-oracle-5.4.0.orig/drivers/pinctrl/mvebu/pinctrl-dove.c +++ linux-oracle-5.4.0/drivers/pinctrl/mvebu/pinctrl-dove.c @@ -769,7 +769,7 @@ of_match_device(dove_pinctrl_of_match, &pdev->dev); struct mvebu_mpp_ctrl_data *mpp_data; void __iomem *base; - int i; + int i, ret; pdev->dev.platform_data = (void *)match->data; @@ -786,13 +786,17 @@ mpp_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, mpp_res); - if (IS_ERR(base)) - return PTR_ERR(base); + if (IS_ERR(base)) { + ret = PTR_ERR(base); + goto err_probe; + } mpp_data = devm_kcalloc(&pdev->dev, dove_pinctrl_info.ncontrols, sizeof(*mpp_data), GFP_KERNEL); - if (!mpp_data) - return -ENOMEM; + if (!mpp_data) { + ret = -ENOMEM; + goto err_probe; + } dove_pinctrl_info.control_data = mpp_data; for (i = 0; i < ARRAY_SIZE(dove_mpp_controls); i++) @@ -811,8 +815,10 @@ } mpp4_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(mpp4_base)) - return PTR_ERR(mpp4_base); + if (IS_ERR(mpp4_base)) { + ret = PTR_ERR(mpp4_base); + goto err_probe; + } res = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (!res) { @@ -823,8 +829,10 @@ } pmu_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pmu_base)) - return PTR_ERR(pmu_base); + if (IS_ERR(pmu_base)) { + ret = PTR_ERR(pmu_base); + goto err_probe; + } gconfmap = syscon_regmap_lookup_by_compatible("marvell,dove-global-config"); if (IS_ERR(gconfmap)) { @@ -834,12 +842,17 @@ adjust_resource(&fb_res, (mpp_res->start & INT_REGS_MASK) + GC_REGS_OFFS, 0x14); gc_base = devm_ioremap_resource(&pdev->dev, &fb_res); - if (IS_ERR(gc_base)) - return PTR_ERR(gc_base); + if (IS_ERR(gc_base)) { + ret = PTR_ERR(gc_base); + goto err_probe; + } + gconfmap = devm_regmap_init_mmio(&pdev->dev, gc_base, &gc_regmap_config); - if (IS_ERR(gconfmap)) - return PTR_ERR(gconfmap); + if (IS_ERR(gconfmap)) { + ret = PTR_ERR(gconfmap); + goto err_probe; + } } /* Warn on any missing DT resource */ @@ -847,6 +860,9 @@ dev_warn(&pdev->dev, FW_BUG "Missing pinctrl regs in DTB. Please update your firmware.\n"); return mvebu_pinctrl_probe(pdev); +err_probe: + clk_disable_unprepare(clk); + return ret; } static struct platform_driver dove_pinctrl_driver = { --- linux-oracle-5.4.0.orig/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ linux-oracle-5.4.0/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1461,8 +1461,10 @@ has_config = nmk_pinctrl_dt_get_config(np, &configs); np_config = of_parse_phandle(np, "ste,config", 0); - if (np_config) + if (np_config) { has_config |= nmk_pinctrl_dt_get_config(np_config, &configs); + of_node_put(np_config); + } if (has_config) { const char *gpio_name; const char *pin; @@ -1923,8 +1925,10 @@ } prcm_np = of_parse_phandle(np, "prcm", 0); - if (prcm_np) + if (prcm_np) { npct->prcm_base = of_iomap(prcm_np, 0); + of_node_put(prcm_np); + } if (!npct->prcm_base) { if (version == PINCTRL_NMK_STN8815) { dev_info(&pdev->dev, --- linux-oracle-5.4.0.orig/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c +++ linux-oracle-5.4.0/drivers/pinctrl/nuvoton/pinctrl-npcm7xx.c @@ -78,7 +78,6 @@ struct gpio_chip gc; int irqbase; int irq; - void *priv; struct irq_chip irq_chip; u32 pinctrl_id; int (*direction_input)(struct gpio_chip *chip, unsigned offset); @@ -226,7 +225,7 @@ chained_irq_enter(chip, desc); sts = ioread32(bank->base + NPCM7XX_GP_N_EVST); en = ioread32(bank->base + NPCM7XX_GP_N_EVEN); - dev_dbg(chip->parent_device, "==> got irq sts %.8x %.8x\n", sts, + dev_dbg(bank->gc.parent, "==> got irq sts %.8x %.8x\n", sts, en); sts &= en; @@ -241,33 +240,33 @@ gpiochip_get_data(irq_data_get_irq_chip_data(d)); unsigned int gpio = BIT(d->hwirq); - dev_dbg(d->chip->parent_device, "setirqtype: %u.%u = %u\n", gpio, + dev_dbg(bank->gc.parent, "setirqtype: %u.%u = %u\n", gpio, d->irq, type); switch (type) { case IRQ_TYPE_EDGE_RISING: - dev_dbg(d->chip->parent_device, "edge.rising\n"); + dev_dbg(bank->gc.parent, "edge.rising\n"); npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio); npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio); break; case IRQ_TYPE_EDGE_FALLING: - dev_dbg(d->chip->parent_device, "edge.falling\n"); + dev_dbg(bank->gc.parent, "edge.falling\n"); npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio); npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio); break; case IRQ_TYPE_EDGE_BOTH: - dev_dbg(d->chip->parent_device, "edge.both\n"); + dev_dbg(bank->gc.parent, "edge.both\n"); npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio); break; case IRQ_TYPE_LEVEL_LOW: - dev_dbg(d->chip->parent_device, "level.low\n"); + dev_dbg(bank->gc.parent, "level.low\n"); npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio); break; case IRQ_TYPE_LEVEL_HIGH: - dev_dbg(d->chip->parent_device, "level.high\n"); + dev_dbg(bank->gc.parent, "level.high\n"); npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio); break; default: - dev_dbg(d->chip->parent_device, "invalid irq type\n"); + dev_dbg(bank->gc.parent, "invalid irq type\n"); return -EINVAL; } @@ -289,7 +288,7 @@ gpiochip_get_data(irq_data_get_irq_chip_data(d)); unsigned int gpio = d->hwirq; - dev_dbg(d->chip->parent_device, "irq_ack: %u.%u\n", gpio, d->irq); + dev_dbg(bank->gc.parent, "irq_ack: %u.%u\n", gpio, d->irq); iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVST); } @@ -301,7 +300,7 @@ unsigned int gpio = d->hwirq; /* Clear events */ - dev_dbg(d->chip->parent_device, "irq_mask: %u.%u\n", gpio, d->irq); + dev_dbg(bank->gc.parent, "irq_mask: %u.%u\n", gpio, d->irq); iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENC); } @@ -313,7 +312,7 @@ unsigned int gpio = d->hwirq; /* Enable events */ - dev_dbg(d->chip->parent_device, "irq_unmask: %u.%u\n", gpio, d->irq); + dev_dbg(bank->gc.parent, "irq_unmask: %u.%u\n", gpio, d->irq); iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENS); } @@ -323,7 +322,7 @@ unsigned int gpio = d->hwirq; /* active-high, input, clear interrupt, enable interrupt */ - dev_dbg(d->chip->parent_device, "startup: %u.%u\n", gpio, d->irq); + dev_dbg(gc->parent, "startup: %u.%u\n", gpio, d->irq); npcmgpio_direction_input(gc, gpio); npcmgpio_irq_ack(d); npcmgpio_irq_unmask(d); @@ -905,7 +904,7 @@ #define DRIVE_STRENGTH_HI_SHIFT 12 #define DRIVE_STRENGTH_MASK 0x0000FF00 -#define DS(lo, hi) (((lo) << DRIVE_STRENGTH_LO_SHIFT) | \ +#define DSTR(lo, hi) (((lo) << DRIVE_STRENGTH_LO_SHIFT) | \ ((hi) << DRIVE_STRENGTH_HI_SHIFT)) #define DSLO(x) (((x) >> DRIVE_STRENGTH_LO_SHIFT) & 0xF) #define DSHI(x) (((x) >> DRIVE_STRENGTH_HI_SHIFT) & 0xF) @@ -925,31 +924,31 @@ static const struct npcm7xx_pincfg pincfg[] = { /* PIN FUNCTION 1 FUNCTION 2 FUNCTION 3 FLAGS */ NPCM7XX_PINCFG(0, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(1, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(2, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(1, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(2, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(3, iox1, MFSEL1, 30, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(4, iox2, MFSEL3, 14, smb1d, I2CSEGSEL, 7, none, NONE, 0, SLEW), NPCM7XX_PINCFG(5, iox2, MFSEL3, 14, smb1d, I2CSEGSEL, 7, none, NONE, 0, SLEW), NPCM7XX_PINCFG(6, iox2, MFSEL3, 14, smb2d, I2CSEGSEL, 10, none, NONE, 0, SLEW), NPCM7XX_PINCFG(7, iox2, MFSEL3, 14, smb2d, I2CSEGSEL, 10, none, NONE, 0, SLEW), - NPCM7XX_PINCFG(8, lkgpo1, FLOCKR1, 4, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(9, lkgpo2, FLOCKR1, 8, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(10, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(11, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(8, lkgpo1, FLOCKR1, 4, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(9, lkgpo2, FLOCKR1, 8, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(10, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(11, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(12, gspi, MFSEL1, 24, smb5b, I2CSEGSEL, 19, none, NONE, 0, SLEW), NPCM7XX_PINCFG(13, gspi, MFSEL1, 24, smb5b, I2CSEGSEL, 19, none, NONE, 0, SLEW), NPCM7XX_PINCFG(14, gspi, MFSEL1, 24, smb5c, I2CSEGSEL, 20, none, NONE, 0, SLEW), NPCM7XX_PINCFG(15, gspi, MFSEL1, 24, smb5c, I2CSEGSEL, 20, none, NONE, 0, SLEW), - NPCM7XX_PINCFG(16, lkgpo0, FLOCKR1, 0, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(17, pspi2, MFSEL3, 13, smb4den, I2CSEGSEL, 23, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(18, pspi2, MFSEL3, 13, smb4b, I2CSEGSEL, 14, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(19, pspi2, MFSEL3, 13, smb4b, I2CSEGSEL, 14, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(16, lkgpo0, FLOCKR1, 0, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(17, pspi2, MFSEL3, 13, smb4den, I2CSEGSEL, 23, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(18, pspi2, MFSEL3, 13, smb4b, I2CSEGSEL, 14, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(19, pspi2, MFSEL3, 13, smb4b, I2CSEGSEL, 14, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(20, smb4c, I2CSEGSEL, 15, smb15, MFSEL3, 8, none, NONE, 0, 0), NPCM7XX_PINCFG(21, smb4c, I2CSEGSEL, 15, smb15, MFSEL3, 8, none, NONE, 0, 0), NPCM7XX_PINCFG(22, smb4d, I2CSEGSEL, 16, smb14, MFSEL3, 7, none, NONE, 0, 0), NPCM7XX_PINCFG(23, smb4d, I2CSEGSEL, 16, smb14, MFSEL3, 7, none, NONE, 0, 0), - NPCM7XX_PINCFG(24, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(25, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(24, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(25, ioxh, MFSEL3, 18, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(26, smb5, MFSEL1, 2, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(27, smb5, MFSEL1, 2, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(28, smb4, MFSEL1, 1, none, NONE, 0, none, NONE, 0, 0), @@ -965,12 +964,12 @@ NPCM7XX_PINCFG(39, smb3b, I2CSEGSEL, 11, none, NONE, 0, none, NONE, 0, SLEW), NPCM7XX_PINCFG(40, smb3b, I2CSEGSEL, 11, none, NONE, 0, none, NONE, 0, SLEW), NPCM7XX_PINCFG(41, bmcuart0a, MFSEL1, 9, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(42, bmcuart0a, MFSEL1, 9, none, NONE, 0, none, NONE, 0, DS(2, 4) | GPO), + NPCM7XX_PINCFG(42, bmcuart0a, MFSEL1, 9, none, NONE, 0, none, NONE, 0, DSTR(2, 4) | GPO), NPCM7XX_PINCFG(43, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, bmcuart1, MFSEL3, 24, 0), NPCM7XX_PINCFG(44, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, bmcuart1, MFSEL3, 24, 0), NPCM7XX_PINCFG(45, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(46, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, none, NONE, 0, DS(2, 8)), - NPCM7XX_PINCFG(47, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, none, NONE, 0, DS(2, 8)), + NPCM7XX_PINCFG(46, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, none, NONE, 0, DSTR(2, 8)), + NPCM7XX_PINCFG(47, uart1, MFSEL1, 10, jtag2, MFSEL4, 0, none, NONE, 0, DSTR(2, 8)), NPCM7XX_PINCFG(48, uart2, MFSEL1, 11, bmcuart0b, MFSEL4, 1, none, NONE, 0, GPO), NPCM7XX_PINCFG(49, uart2, MFSEL1, 11, bmcuart0b, MFSEL4, 1, none, NONE, 0, 0), NPCM7XX_PINCFG(50, uart2, MFSEL1, 11, none, NONE, 0, none, NONE, 0, 0), @@ -980,8 +979,8 @@ NPCM7XX_PINCFG(54, uart2, MFSEL1, 11, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(55, uart2, MFSEL1, 11, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(56, r1err, MFSEL1, 12, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(57, r1md, MFSEL1, 13, none, NONE, 0, none, NONE, 0, DS(2, 4)), - NPCM7XX_PINCFG(58, r1md, MFSEL1, 13, none, NONE, 0, none, NONE, 0, DS(2, 4)), + NPCM7XX_PINCFG(57, r1md, MFSEL1, 13, none, NONE, 0, none, NONE, 0, DSTR(2, 4)), + NPCM7XX_PINCFG(58, r1md, MFSEL1, 13, none, NONE, 0, none, NONE, 0, DSTR(2, 4)), NPCM7XX_PINCFG(59, smb3d, I2CSEGSEL, 13, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(60, smb3d, I2CSEGSEL, 13, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(61, uart1, MFSEL1, 10, none, NONE, 0, none, NONE, 0, GPO), @@ -1004,19 +1003,19 @@ NPCM7XX_PINCFG(77, fanin13, MFSEL2, 13, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(78, fanin14, MFSEL2, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(79, fanin15, MFSEL2, 15, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(80, pwm0, MFSEL2, 16, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(81, pwm1, MFSEL2, 17, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(82, pwm2, MFSEL2, 18, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(83, pwm3, MFSEL2, 19, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(84, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(85, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(86, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(80, pwm0, MFSEL2, 16, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(81, pwm1, MFSEL2, 17, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(82, pwm2, MFSEL2, 18, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(83, pwm3, MFSEL2, 19, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(84, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(85, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(86, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(87, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(88, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(89, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(90, r2err, MFSEL1, 15, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(91, r2md, MFSEL1, 16, none, NONE, 0, none, NONE, 0, DS(2, 4)), - NPCM7XX_PINCFG(92, r2md, MFSEL1, 16, none, NONE, 0, none, NONE, 0, DS(2, 4)), + NPCM7XX_PINCFG(91, r2md, MFSEL1, 16, none, NONE, 0, none, NONE, 0, DSTR(2, 4)), + NPCM7XX_PINCFG(92, r2md, MFSEL1, 16, none, NONE, 0, none, NONE, 0, DSTR(2, 4)), NPCM7XX_PINCFG(93, ga20kbc, MFSEL1, 17, smb5d, I2CSEGSEL, 21, none, NONE, 0, 0), NPCM7XX_PINCFG(94, ga20kbc, MFSEL1, 17, smb5d, I2CSEGSEL, 21, none, NONE, 0, 0), NPCM7XX_PINCFG(95, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, 0), @@ -1062,34 +1061,34 @@ NPCM7XX_PINCFG(133, smb10, MFSEL4, 13, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(134, smb11, MFSEL4, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(135, smb11, MFSEL4, 14, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(136, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(137, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(138, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(139, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(140, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(136, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(137, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(138, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(139, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(140, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(141, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(142, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(142, sd1, MFSEL3, 12, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(143, sd1, MFSEL3, 12, sd1pwr, MFSEL4, 5, none, NONE, 0, 0), - NPCM7XX_PINCFG(144, pwm4, MFSEL2, 20, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(145, pwm5, MFSEL2, 21, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(146, pwm6, MFSEL2, 22, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(147, pwm7, MFSEL2, 23, none, NONE, 0, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(148, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(149, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(150, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(151, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(152, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(144, pwm4, MFSEL2, 20, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(145, pwm5, MFSEL2, 21, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(146, pwm6, MFSEL2, 22, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(147, pwm7, MFSEL2, 23, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(148, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(149, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(150, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(151, mmc8, MFSEL3, 11, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(152, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(153, mmcwp, FLOCKR1, 24, none, NONE, 0, none, NONE, 0, 0), /* Z1/A1 */ - NPCM7XX_PINCFG(154, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(154, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(155, mmccd, MFSEL3, 25, mmcrst, MFSEL4, 6, none, NONE, 0, 0), /* Z1/A1 */ - NPCM7XX_PINCFG(156, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(157, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(158, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(159, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - - NPCM7XX_PINCFG(160, clkout, MFSEL1, 21, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(161, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, DS(8, 12)), - NPCM7XX_PINCFG(162, serirq, NONE, 0, gpio, MFSEL1, 31, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(156, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(157, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(158, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(159, mmc, MFSEL3, 10, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + + NPCM7XX_PINCFG(160, clkout, MFSEL1, 21, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(161, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, DSTR(8, 12)), + NPCM7XX_PINCFG(162, serirq, NONE, 0, gpio, MFSEL1, 31, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(163, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, 0), NPCM7XX_PINCFG(164, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, SLEWLPC), NPCM7XX_PINCFG(165, lpc, NONE, 0, espi, MFSEL4, 8, gpio, MFSEL1, 26, SLEWLPC), @@ -1102,25 +1101,25 @@ NPCM7XX_PINCFG(172, smb6, MFSEL3, 1, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(173, smb7, MFSEL3, 2, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(174, smb7, MFSEL3, 2, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(175, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(176, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(177, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(178, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(179, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(180, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), + NPCM7XX_PINCFG(175, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(176, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(177, pspi1, MFSEL3, 4, faninx, MFSEL3, 3, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(178, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(179, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(180, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), NPCM7XX_PINCFG(181, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(182, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(183, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(184, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW | GPO), - NPCM7XX_PINCFG(185, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW | GPO), - NPCM7XX_PINCFG(186, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(187, spi3cs1, MFSEL4, 17, none, NONE, 0, none, NONE, 0, DS(8, 12)), - NPCM7XX_PINCFG(188, spi3quad, MFSEL4, 20, spi3cs2, MFSEL4, 18, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(189, spi3quad, MFSEL4, 20, spi3cs3, MFSEL4, 19, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(190, gpio, FLOCKR1, 20, nprd_smi, NONE, 0, none, NONE, 0, DS(2, 4)), - NPCM7XX_PINCFG(191, none, NONE, 0, none, NONE, 0, none, NONE, 0, DS(8, 12)), /* XX */ + NPCM7XX_PINCFG(183, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(184, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW | GPO), + NPCM7XX_PINCFG(185, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW | GPO), + NPCM7XX_PINCFG(186, spi3, MFSEL4, 16, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(187, spi3cs1, MFSEL4, 17, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), + NPCM7XX_PINCFG(188, spi3quad, MFSEL4, 20, spi3cs2, MFSEL4, 18, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(189, spi3quad, MFSEL4, 20, spi3cs3, MFSEL4, 19, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(190, gpio, FLOCKR1, 20, nprd_smi, NONE, 0, none, NONE, 0, DSTR(2, 4)), + NPCM7XX_PINCFG(191, none, NONE, 0, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), /* XX */ - NPCM7XX_PINCFG(192, none, NONE, 0, none, NONE, 0, none, NONE, 0, DS(8, 12)), /* XX */ + NPCM7XX_PINCFG(192, none, NONE, 0, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), /* XX */ NPCM7XX_PINCFG(193, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(194, smb0b, I2CSEGSEL, 0, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(195, smb0b, I2CSEGSEL, 0, none, NONE, 0, none, NONE, 0, 0), @@ -1131,11 +1130,11 @@ NPCM7XX_PINCFG(200, r2, MFSEL1, 14, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(201, r1, MFSEL3, 9, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(202, smb0c, I2CSEGSEL, 1, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(203, faninx, MFSEL3, 3, none, NONE, 0, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(203, faninx, MFSEL3, 3, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(204, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, SLEW), NPCM7XX_PINCFG(205, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, SLEW), - NPCM7XX_PINCFG(206, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, DS(4, 8)), - NPCM7XX_PINCFG(207, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, DS(4, 8)), + NPCM7XX_PINCFG(206, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, DSTR(4, 8)), + NPCM7XX_PINCFG(207, ddc, NONE, 0, gpio, MFSEL3, 22, none, NONE, 0, DSTR(4, 8)), NPCM7XX_PINCFG(208, rg2, MFSEL4, 24, ddr, MFSEL3, 26, none, NONE, 0, 0), NPCM7XX_PINCFG(209, rg2, MFSEL4, 24, ddr, MFSEL3, 26, none, NONE, 0, 0), NPCM7XX_PINCFG(210, rg2, MFSEL4, 24, ddr, MFSEL3, 26, none, NONE, 0, 0), @@ -1147,20 +1146,20 @@ NPCM7XX_PINCFG(216, rg2mdio, MFSEL4, 23, ddr, MFSEL3, 26, none, NONE, 0, 0), NPCM7XX_PINCFG(217, rg2mdio, MFSEL4, 23, ddr, MFSEL3, 26, none, NONE, 0, 0), NPCM7XX_PINCFG(218, wdog1, MFSEL3, 19, none, NONE, 0, none, NONE, 0, 0), - NPCM7XX_PINCFG(219, wdog2, MFSEL3, 20, none, NONE, 0, none, NONE, 0, DS(4, 8)), + NPCM7XX_PINCFG(219, wdog2, MFSEL3, 20, none, NONE, 0, none, NONE, 0, DSTR(4, 8)), NPCM7XX_PINCFG(220, smb12, MFSEL3, 5, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(221, smb12, MFSEL3, 5, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(222, smb13, MFSEL3, 6, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(223, smb13, MFSEL3, 6, none, NONE, 0, none, NONE, 0, 0), NPCM7XX_PINCFG(224, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, SLEW), - NPCM7XX_PINCFG(225, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW | GPO), - NPCM7XX_PINCFG(226, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW | GPO), - NPCM7XX_PINCFG(227, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(228, spixcs1, MFSEL4, 28, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(229, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(230, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DS(8, 12) | SLEW), - NPCM7XX_PINCFG(231, clkreq, MFSEL4, 9, none, NONE, 0, none, NONE, 0, DS(8, 12)), + NPCM7XX_PINCFG(225, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW | GPO), + NPCM7XX_PINCFG(226, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW | GPO), + NPCM7XX_PINCFG(227, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(228, spixcs1, MFSEL4, 28, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(229, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(230, spix, MFSEL4, 27, none, NONE, 0, none, NONE, 0, DSTR(8, 12) | SLEW), + NPCM7XX_PINCFG(231, clkreq, MFSEL4, 9, none, NONE, 0, none, NONE, 0, DSTR(8, 12)), NPCM7XX_PINCFG(253, none, NONE, 0, none, NONE, 0, none, NONE, 0, GPI), /* SDHC1 power */ NPCM7XX_PINCFG(254, none, NONE, 0, none, NONE, 0, none, NONE, 0, GPI), /* SDHC2 power */ NPCM7XX_PINCFG(255, none, NONE, 0, none, NONE, 0, none, NONE, 0, GPI), /* DACOSEL */ @@ -1561,7 +1560,7 @@ { struct npcm7xx_pinctrl *npcm = pinctrl_dev_get_drvdata(pctldev); - dev_dbg(npcm->dev, "group size: %d\n", ARRAY_SIZE(npcm7xx_groups)); + dev_dbg(npcm->dev, "group size: %zu\n", ARRAY_SIZE(npcm7xx_groups)); return ARRAY_SIZE(npcm7xx_groups); } --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinconf-generic.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinconf-generic.c @@ -30,10 +30,10 @@ PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false), PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false), - PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false), + PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", "ohms", true), PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, - "input bias pull to pin specific state", NULL, false), - PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false), + "input bias pull to pin specific state", "ohms", true), + PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", "ohms", true), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false), PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false), PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false), @@ -391,8 +391,10 @@ for_each_available_child_of_node(np_config, np) { ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, &reserved_maps, num_maps, type); - if (ret < 0) + if (ret < 0) { + of_node_put(np); goto exit; + } } return 0; --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-amd.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-amd.c @@ -123,6 +123,14 @@ struct amd_gpio *gpio_dev = gpiochip_get_data(gc); raw_spin_lock_irqsave(&gpio_dev->lock, flags); + + /* Use special handling for Pin0 debounce */ + if (offset == 0) { + pin_reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG); + if (pin_reg & INTERNAL_GPIO0_DEBOUNCE) + debounce = 0; + } + pin_reg = readl(gpio_dev->base + offset * 4); if (debounce) { @@ -153,7 +161,7 @@ pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); pin_reg &= ~BIT(DB_TMR_LARGE_OFF); } else if (debounce < 250000) { - time = debounce / 15600; + time = debounce / 15625; pin_reg |= time & DB_TMR_OUT_MASK; pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); pin_reg |= BIT(DB_TMR_LARGE_OFF); @@ -163,14 +171,14 @@ pin_reg |= BIT(DB_TMR_OUT_UNIT_OFF); pin_reg |= BIT(DB_TMR_LARGE_OFF); } else { - pin_reg &= ~DB_CNTRl_MASK; + pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); ret = -EINVAL; } } else { pin_reg &= ~BIT(DB_TMR_OUT_UNIT_OFF); pin_reg &= ~BIT(DB_TMR_LARGE_OFF); pin_reg &= ~DB_TMR_OUT_MASK; - pin_reg &= ~DB_CNTRl_MASK; + pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); } writel(pin_reg, gpio_dev->base + offset * 4); raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); @@ -178,18 +186,6 @@ return ret; } -static int amd_gpio_set_config(struct gpio_chip *gc, unsigned offset, - unsigned long config) -{ - u32 debounce; - - if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) - return -ENOTSUPP; - - debounce = pinconf_to_config_argument(config); - return amd_gpio_set_debounce(gc, offset, debounce); -} - #ifdef CONFIG_DEBUG_FS static void amd_gpio_dbg_show(struct seq_file *s, struct gpio_chip *gc) { @@ -212,6 +208,7 @@ char *output_value; char *output_enable; + seq_printf(s, "WAKE_INT_MASTER_REG: 0x%08x\n", readl(gpio_dev->base + WAKE_INT_MASTER_REG)); for (bank = 0; bank < gpio_dev->hwbank_num; bank++) { seq_printf(s, "GPIO bank%d\t", bank); @@ -435,7 +432,6 @@ pin_reg &= ~BIT(LEVEL_TRIG_OFF); pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF; - pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; irq_set_handler_locked(d, handle_edge_irq); break; @@ -443,7 +439,6 @@ pin_reg &= ~BIT(LEVEL_TRIG_OFF); pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF; - pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; irq_set_handler_locked(d, handle_edge_irq); break; @@ -451,7 +446,6 @@ pin_reg &= ~BIT(LEVEL_TRIG_OFF); pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); pin_reg |= BOTH_EADGE << ACTIVE_LEVEL_OFF; - pin_reg |= DB_TYPE_REMOVE_GLITCH << DB_CNTRL_OFF; irq_set_handler_locked(d, handle_edge_irq); break; @@ -459,8 +453,6 @@ pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF; pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); pin_reg |= ACTIVE_HIGH << ACTIVE_LEVEL_OFF; - pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); - pin_reg |= DB_TYPE_PRESERVE_LOW_GLITCH << DB_CNTRL_OFF; irq_set_handler_locked(d, handle_level_irq); break; @@ -468,8 +460,6 @@ pin_reg |= LEVEL_TRIGGER << LEVEL_TRIG_OFF; pin_reg &= ~(ACTIVE_LEVEL_MASK << ACTIVE_LEVEL_OFF); pin_reg |= ACTIVE_LOW << ACTIVE_LEVEL_OFF; - pin_reg &= ~(DB_CNTRl_MASK << DB_CNTRL_OFF); - pin_reg |= DB_TYPE_PRESERVE_HIGH_GLITCH << DB_CNTRL_OFF; irq_set_handler_locked(d, handle_level_irq); break; @@ -540,7 +530,8 @@ irqreturn_t ret = IRQ_NONE; unsigned int i, irqnr; unsigned long flags; - u32 *regs, regval; + u32 __iomem *regs; + u32 regval; u64 status, mask; /* Read the wake status */ @@ -668,7 +659,7 @@ break; default: - dev_err(&gpio_dev->pdev->dev, "Invalid config param %04x\n", + dev_dbg(&gpio_dev->pdev->dev, "Invalid config param %04x\n", param); return -ENOTSUPP; } @@ -679,7 +670,7 @@ } static int amd_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, - unsigned long *configs, unsigned num_configs) + unsigned long *configs, unsigned int num_configs) { int i; u32 arg; @@ -721,7 +712,7 @@ break; default: - dev_err(&gpio_dev->pdev->dev, + dev_dbg(&gpio_dev->pdev->dev, "Invalid config param %04x\n", param); ret = -ENOTSUPP; } @@ -769,6 +760,20 @@ return 0; } +static int amd_gpio_set_config(struct gpio_chip *gc, unsigned int pin, + unsigned long config) +{ + struct amd_gpio *gpio_dev = gpiochip_get_data(gc); + + if (pinconf_to_config_param(config) == PIN_CONFIG_INPUT_DEBOUNCE) { + u32 debounce = pinconf_to_config_argument(config); + + return amd_gpio_set_debounce(gc, pin, debounce); + } + + return amd_pinconf_set(gpio_dev->pctrl, pin, &config, 1); +} + static const struct pinconf_ops amd_pinconf_ops = { .pin_config_get = amd_pinconf_get, .pin_config_set = amd_pinconf_set, @@ -776,6 +781,34 @@ .pin_config_group_set = amd_pinconf_group_set, }; +static void amd_gpio_irq_init(struct amd_gpio *gpio_dev) +{ + struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + unsigned long flags; + u32 pin_reg, mask; + int i; + + mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3) | + BIT(INTERRUPT_MASK_OFF) | BIT(INTERRUPT_ENABLE_OFF) | + BIT(WAKE_CNTRL_OFF_S4); + + for (i = 0; i < desc->npins; i++) { + int pin = desc->pins[i].number; + const struct pin_desc *pd = pin_desc_get(gpio_dev->pctrl, pin); + + if (!pd) + continue; + + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + + pin_reg = readl(gpio_dev->base + pin * 4); + pin_reg &= ~mask; + writel(pin_reg, gpio_dev->base + pin * 4); + + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); + } +} + #ifdef CONFIG_PM_SLEEP static bool amd_gpio_should_save(struct amd_gpio *gpio_dev, unsigned int pin) { @@ -799,6 +832,7 @@ { struct amd_gpio *gpio_dev = dev_get_drvdata(dev); struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + unsigned long flags; int i; for (i = 0; i < desc->npins; i++) { @@ -807,7 +841,9 @@ if (!amd_gpio_should_save(gpio_dev, pin)) continue; - gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin*4); + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + gpio_dev->saved_regs[i] = readl(gpio_dev->base + pin * 4) & ~PIN_IRQ_PENDING; + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); } return 0; @@ -817,6 +853,7 @@ { struct amd_gpio *gpio_dev = dev_get_drvdata(dev); struct pinctrl_desc *desc = gpio_dev->pctrl->desc; + unsigned long flags; int i; for (i = 0; i < desc->npins; i++) { @@ -825,7 +862,10 @@ if (!amd_gpio_should_save(gpio_dev, pin)) continue; - writel(gpio_dev->saved_regs[i], gpio_dev->base + pin*4); + raw_spin_lock_irqsave(&gpio_dev->lock, flags); + gpio_dev->saved_regs[i] |= readl(gpio_dev->base + pin * 4) & PIN_IRQ_PENDING; + writel(gpio_dev->saved_regs[i], gpio_dev->base + pin * 4); + raw_spin_unlock_irqrestore(&gpio_dev->lock, flags); } return 0; @@ -851,6 +891,7 @@ int irq_base; struct resource *res; struct amd_gpio *gpio_dev; + struct gpio_irq_chip *girq; gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct amd_gpio), GFP_KERNEL); @@ -912,6 +953,18 @@ return PTR_ERR(gpio_dev->pctrl); } + /* Disable and mask interrupts */ + amd_gpio_irq_init(gpio_dev); + + girq = &gpio_dev->gc.irq; + girq->chip = &amd_gpio_irqchip; + /* This will let us handle the parent IRQ in the driver */ + girq->parent_handler = NULL; + girq->num_parents = 0; + girq->parents = NULL; + girq->default_type = IRQ_TYPE_NONE; + girq->handler = handle_simple_irq; + ret = gpiochip_add_data(&gpio_dev->gc, gpio_dev); if (ret) return ret; @@ -923,17 +976,6 @@ goto out2; } - ret = gpiochip_irqchip_add(&gpio_dev->gc, - &amd_gpio_irqchip, - 0, - handle_simple_irq, - IRQ_TYPE_NONE); - if (ret) { - dev_err(&pdev->dev, "could not add irqchip\n"); - ret = -ENODEV; - goto out2; - } - ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, IRQF_SHARED, KBUILD_MODNAME, gpio_dev); if (ret) @@ -964,6 +1006,7 @@ static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, { "AMDI0030", 0}, + { "AMDI0031", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-amd.h +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-amd.h @@ -17,6 +17,7 @@ #define AMD_GPIO_PINS_BANK3 32 #define WAKE_INT_MASTER_REG 0xfc +#define INTERNAL_GPIO0_DEBOUNCE (1 << 15) #define EOI_MASK (1 << 29) #define WAKE_INT_STATUS_REG0 0x2f8 @@ -252,7 +253,7 @@ { .name = "uart0", .pins = uart0_pins, - .npins = 9, + .npins = 5, }, { .name = "uart1", --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-at91-pio4.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-at91-pio4.c @@ -928,6 +928,13 @@ } }; +/* + * This lock class allows to tell lockdep that parent IRQ and children IRQ do + * not share the same class so it does not raise false positive + */ +static struct lock_class_key atmel_lock_key; +static struct lock_class_key atmel_request_key; + static int atmel_pinctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1011,8 +1018,10 @@ pin_desc[i].number = i; /* Pin naming convention: P(bank_name)(bank_pin_number). */ - pin_desc[i].name = kasprintf(GFP_KERNEL, "P%c%d", - bank + 'A', line); + pin_desc[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "P%c%d", + bank + 'A', line); + if (!pin_desc[i].name) + return -ENOMEM; group->name = group_names[i] = pin_desc[i].name; group->pin = pin_desc[i].number; @@ -1069,7 +1078,6 @@ dev_err(dev, "can't add the irq domain\n"); return -ENODEV; } - atmel_pioctrl->irq_domain->name = "atmel gpio"; for (i = 0; i < atmel_pioctrl->npins; i++) { int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i); @@ -1077,6 +1085,7 @@ irq_set_chip_and_handler(irq, &atmel_gpio_irq_chip, handle_simple_irq); irq_set_chip_data(irq, atmel_pioctrl); + irq_set_lockdep_class(irq, &atmel_lock_key, &atmel_request_key); dev_dbg(dev, "atmel gpio irq domain: hwirq: %d, linux irq: %d\n", i, irq); --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-at91.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-at91.c @@ -1398,8 +1398,11 @@ /* We will handle a range of GPIO pins */ for (i = 0; i < gpio_banks; i++) - if (gpio_chips[i]) + if (gpio_chips[i]) { pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range); + gpiochip_add_pin_range(&gpio_chips[i]->chip, dev_name(info->pctl->dev), 0, + gpio_chips[i]->range.pin_base, gpio_chips[i]->range.npins); + } dev_info(&pdev->dev, "initialized AT91 pinctrl driver\n"); @@ -1891,7 +1894,7 @@ } for (i = 0; i < chip->ngpio; i++) - names[i] = kasprintf(GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); + names[i] = devm_kasprintf(&pdev->dev, GFP_KERNEL, "pio%c%d", alias_idx + 'A', i); chip->names = (const char *const *)names; --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-falcon.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-falcon.c @@ -431,27 +431,31 @@ /* load and remap the pad resources of the different banks */ for_each_compatible_node(np, NULL, "lantiq,pad-falcon") { - struct platform_device *ppdev = of_find_device_by_node(np); const __be32 *bank = of_get_property(np, "lantiq,bank", NULL); struct resource res; + struct platform_device *ppdev; u32 avail; int pins; if (!of_device_is_available(np)) continue; - if (!ppdev) { - dev_err(&pdev->dev, "failed to find pad pdev\n"); - continue; - } if (!bank || *bank >= PORTS) continue; if (of_address_to_resource(np, 0, &res)) continue; + + ppdev = of_find_device_by_node(np); + if (!ppdev) { + dev_err(&pdev->dev, "failed to find pad pdev\n"); + continue; + } + falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL); + put_device(&ppdev->dev); if (IS_ERR(falcon_info.clk[*bank])) { dev_err(&ppdev->dev, "failed to get clock\n"); - of_node_put(np) + of_node_put(np); return PTR_ERR(falcon_info.clk[*bank]); } falcon_info.membase[*bank] = devm_ioremap_resource(&pdev->dev, --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-ingenic.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-ingenic.c @@ -348,7 +348,7 @@ }; static const u32 jz4760_pull_ups[6] = { - 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0xfffff00f, + 0xffffffff, 0xfffcf3ff, 0xffffffff, 0xffffcfff, 0xfffffb7c, 0x0000000f, }; static const u32 jz4760_pull_downs[6] = { @@ -611,11 +611,11 @@ }; static const u32 jz4770_pull_ups[6] = { - 0x3fffffff, 0xfff0030c, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0xffa7f00f, + 0x3fffffff, 0xfff0f3fc, 0xffffffff, 0xffff4fff, 0xfffffb7c, 0x0024f00f, }; static const u32 jz4770_pull_downs[6] = { - 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x00580ff0, + 0x00000000, 0x000f0c03, 0x00000000, 0x0000b000, 0x00000483, 0x005b0ff0, }; static int jz4770_uart0_data_pins[] = { 0xa0, 0xa3, }; @@ -1378,7 +1378,7 @@ static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc, u8 offset, int value) { - if (jzgc->jzpc->version >= ID_JZ4760) + if (jzgc->jzpc->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value); @@ -1389,7 +1389,7 @@ { u8 reg1, reg2; - if (jzgc->jzpc->version >= ID_JZ4760) { + if (jzgc->jzpc->version >= ID_JZ4770) { reg1 = JZ4760_GPIO_PAT1; reg2 = JZ4760_GPIO_PAT0; } else { @@ -1464,7 +1464,7 @@ struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc); int irq = irqd->hwirq; - if (jzgc->jzpc->version >= ID_JZ4760) + if (jzgc->jzpc->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true); @@ -1480,7 +1480,7 @@ ingenic_gpio_irq_mask(irqd); - if (jzgc->jzpc->version >= ID_JZ4760) + if (jzgc->jzpc->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false); @@ -1500,12 +1500,12 @@ */ high = ingenic_gpio_get_value(jzgc, irq); if (high) - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_LOW); else - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING); + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH); } - if (jzgc->jzpc->version >= ID_JZ4760) + if (jzgc->jzpc->version >= ID_JZ4770) ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false); else ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true); @@ -1538,7 +1538,7 @@ */ bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq); - type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING; + type = high ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH; } irq_set_type(jzgc, irqd->hwirq, type); @@ -1562,7 +1562,7 @@ chained_irq_enter(irq_chip, desc); - if (jzgc->jzpc->version >= ID_JZ4760) + if (jzgc->jzpc->version >= ID_JZ4770) flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG); else flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG); @@ -1643,8 +1643,9 @@ struct ingenic_pinctrl *jzpc = jzgc->jzpc; unsigned int pin = gc->base + offset; - if (jzpc->version >= ID_JZ4760) - return ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1); + if (jzpc->version >= ID_JZ4770) + return ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) || + ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1); if (ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_SELECT)) return true; @@ -1675,7 +1676,7 @@ ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1); ingenic_shadow_config_pin_load(jzpc, pin); - } else if (jzpc->version >= ID_JZ4760) { + } else if (jzpc->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, false); ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2); @@ -1683,7 +1684,7 @@ } else { ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true); ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2); - ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0); + ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1); } return 0; @@ -1733,7 +1734,7 @@ ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true); ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); ingenic_shadow_config_pin_load(jzpc, pin); - } else if (jzpc->version >= ID_JZ4760) { + } else if (jzpc->version >= ID_JZ4770) { ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false); ingenic_config_pin(jzpc, pin, GPIO_MSK, true); ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input); @@ -1763,7 +1764,7 @@ unsigned int offt = pin / PINS_PER_GPIO_CHIP; bool pull; - if (jzpc->version >= ID_JZ4760) + if (jzpc->version >= ID_JZ4770) pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN); else pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS); @@ -1795,7 +1796,7 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc, unsigned int pin, bool enabled) { - if (jzpc->version >= ID_JZ4760) + if (jzpc->version >= ID_JZ4770) ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !enabled); else ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !enabled); @@ -1845,7 +1846,8 @@ break; default: - unreachable(); + /* unreachable */ + break; } } --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-mcp23s08.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-mcp23s08.c @@ -120,9 +120,10 @@ .num_reg_defaults = ARRAY_SIZE(mcp23x08_defaults), .cache_type = REGCACHE_FLAT, .max_register = MCP_OLAT, + .disable_locking = true, /* mcp->lock protects the regmap */ }; -static const struct reg_default mcp23x16_defaults[] = { +static const struct reg_default mcp23x17_defaults[] = { {.reg = MCP_IODIR << 1, .def = 0xffff}, {.reg = MCP_IPOL << 1, .def = 0x0000}, {.reg = MCP_GPINTEN << 1, .def = 0x0000}, @@ -133,23 +134,23 @@ {.reg = MCP_OLAT << 1, .def = 0x0000}, }; -static const struct regmap_range mcp23x16_volatile_range = { +static const struct regmap_range mcp23x17_volatile_range = { .range_min = MCP_INTF << 1, .range_max = MCP_GPIO << 1, }; -static const struct regmap_access_table mcp23x16_volatile_table = { - .yes_ranges = &mcp23x16_volatile_range, +static const struct regmap_access_table mcp23x17_volatile_table = { + .yes_ranges = &mcp23x17_volatile_range, .n_yes_ranges = 1, }; -static const struct regmap_range mcp23x16_precious_range = { - .range_min = MCP_GPIO << 1, +static const struct regmap_range mcp23x17_precious_range = { + .range_min = MCP_INTCAP << 1, .range_max = MCP_GPIO << 1, }; -static const struct regmap_access_table mcp23x16_precious_table = { - .yes_ranges = &mcp23x16_precious_range, +static const struct regmap_access_table mcp23x17_precious_table = { + .yes_ranges = &mcp23x17_precious_range, .n_yes_ranges = 1, }; @@ -159,12 +160,13 @@ .reg_stride = 2, .max_register = MCP_OLAT << 1, - .volatile_table = &mcp23x16_volatile_table, - .precious_table = &mcp23x16_precious_table, - .reg_defaults = mcp23x16_defaults, - .num_reg_defaults = ARRAY_SIZE(mcp23x16_defaults), + .volatile_table = &mcp23x17_volatile_table, + .precious_table = &mcp23x17_precious_table, + .reg_defaults = mcp23x17_defaults, + .num_reg_defaults = ARRAY_SIZE(mcp23x17_defaults), .cache_type = REGCACHE_FLAT, .val_format_endian = REGMAP_ENDIAN_LITTLE, + .disable_locking = true, /* mcp->lock protects the regmap */ }; static int mcp_read(struct mcp23s08 *mcp, unsigned int reg, unsigned int *val) @@ -261,7 +263,9 @@ switch (param) { case PIN_CONFIG_BIAS_PULL_UP: + mutex_lock(&mcp->lock); ret = mcp_read(mcp, MCP_GPPU, &data); + mutex_unlock(&mcp->lock); if (ret < 0) return ret; status = (data & BIT(pin)) ? 1 : 0; @@ -290,7 +294,9 @@ switch (param) { case PIN_CONFIG_BIAS_PULL_UP: + mutex_lock(&mcp->lock); ret = mcp_set_bit(mcp, MCP_GPPU, pin, arg); + mutex_unlock(&mcp->lock); break; default: dev_dbg(mcp->dev, "Invalid config param %04x\n", param); @@ -459,6 +465,11 @@ if (mcp_read(mcp, MCP_INTF, &intf)) goto unlock; + if (intf == 0) { + /* There is no interrupt pending */ + goto unlock; + } + if (mcp_read(mcp, MCP_INTCAP, &intcap)) goto unlock; @@ -476,11 +487,6 @@ mcp->cached_gpio = gpio; mutex_unlock(&mcp->lock); - if (intf == 0) { - /* There is no interrupt pending */ - return IRQ_HANDLED; - } - dev_dbg(mcp->chip.parent, "intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n", intcap, intf, gpio_orig, gpio); --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-ocelot.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-ocelot.c @@ -420,7 +420,7 @@ regmap_update_bits(info->map, REG_ALT(0, info, pin->pin), BIT(p), f << p); regmap_update_bits(info->map, REG_ALT(1, info, pin->pin), - BIT(p), f << (p - 1)); + BIT(p), (f >> 1) << p); return 0; } @@ -711,11 +711,12 @@ struct irq_chip *parent_chip = irq_desc_get_chip(desc); struct gpio_chip *chip = irq_desc_get_handler_data(desc); struct ocelot_pinctrl *info = gpiochip_get_data(chip); + unsigned int id_reg = OCELOT_GPIO_INTR_IDENT * info->stride; unsigned int reg = 0, irq, i; unsigned long irqs; for (i = 0; i < info->stride; i++) { - regmap_read(info->map, OCELOT_GPIO_INTR_IDENT + 4 * i, ®); + regmap_read(info->map, id_reg + 4 * i, ®); if (!reg) continue; --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-pistachio.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-pistachio.c @@ -1370,10 +1370,10 @@ } irq = irq_of_parse_and_map(child, 0); - if (irq < 0) { - dev_err(pctl->dev, "No IRQ for bank %u: %d\n", i, irq); + if (!irq) { + dev_err(pctl->dev, "No IRQ for bank %u\n", i); of_node_put(child); - ret = irq; + ret = -EINVAL; goto err; } --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-rockchip.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-rockchip.c @@ -62,7 +62,7 @@ RK3399, }; -/** +/* * Encode variants of iomux registers into a type variable */ #define IOMUX_GPIO_ONLY BIT(0) @@ -72,6 +72,7 @@ #define IOMUX_WIDTH_3BIT BIT(4) /** + * struct rockchip_iomux * @type: iomux variant using IOMUX_* constants * @offset: if initialized to -1 it will be autocalculated, by specifying * an initial offset value the relevant source offset can be reset @@ -82,7 +83,7 @@ int offset; }; -/** +/* * enum type index corresponding to rockchip_perpin_drv_list arrays index. */ enum rockchip_pin_drv_type { @@ -94,7 +95,7 @@ DRV_TYPE_MAX }; -/** +/* * enum type index corresponding to rockchip_pull_list arrays index. */ enum rockchip_pin_pull_type { @@ -104,6 +105,7 @@ }; /** + * struct rockchip_drv * @drv_type: drive strength variant using rockchip_perpin_drv_type * @offset: if initialized to -1 it will be autocalculated, by specifying * an initial offset value the relevant source offset can be reset @@ -117,8 +119,9 @@ }; /** + * struct rockchip_pin_bank * @reg_base: register base of the gpio bank - * @reg_pull: optional separate register for additional pull settings + * @regmap_pull: optional separate register for additional pull settings * @clk: clock of the gpio bank * @irq: interrupt of the gpio bank * @saved_masks: Saved content of GPIO_INTEN at suspend time. @@ -136,6 +139,8 @@ * @gpio_chip: gpiolib chip * @grange: gpio range * @slock: spinlock for the gpio bank + * @toggle_edge_mode: bit mask to toggle (falling/rising) edge mode + * @recalced_mask: bit mask to indicate a need to recalulate the mask * @route_mask: bits describing the routing pins of per bank */ struct rockchip_pin_bank { @@ -310,6 +315,7 @@ * @bank_num: bank number. * @pin: index at register or used to calc index. * @func: the min pin. + * @route_location: the mux route location (same, pmu, grf). * @route_offset: the max pin. * @route_val: the register offset. */ @@ -322,8 +328,6 @@ u32 route_val; }; -/** - */ struct rockchip_pin_ctrl { struct rockchip_pin_bank *pin_banks; u32 nr_banks; @@ -361,9 +365,7 @@ * @name: name of the pin group, used to lookup the group. * @pins: the pins included in this group. * @npins: number of pins included in this group. - * @func: the mux function number to be programmed when selected. - * @configs: the config values to be set for each pin - * @nconfigs: number of configs for each pin + * @data: local pin configuration */ struct rockchip_pin_group { const char *name; @@ -376,7 +378,7 @@ * struct rockchip_pmx_func: represent a pin function. * @name: name of the pin function, used to lookup the function. * @groups: one or more names of pin groups that provide this function. - * @num_groups: number of groups included in @groups. + * @ngroups: number of groups included in @groups. */ struct rockchip_pmx_func { const char *name; @@ -506,8 +508,8 @@ } map_num += grp->npins; - new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), - GFP_KERNEL); + + new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); if (!new_map) return -ENOMEM; @@ -517,7 +519,7 @@ /* create mux map */ parent = of_get_parent(np); if (!parent) { - devm_kfree(pctldev->dev, new_map); + kfree(new_map); return -EINVAL; } new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; @@ -544,6 +546,7 @@ static void rockchip_dt_free_map(struct pinctrl_dev *pctldev, struct pinctrl_map *map, unsigned num_maps) { + kfree(map); } static const struct pinctrl_ops rockchip_pctrl_ops = { @@ -658,23 +661,68 @@ static struct rockchip_mux_recalced_data rk3328_mux_recalced_data[] = { { - .num = 2, - .pin = 12, - .reg = 0x24, - .bit = 8, - .mask = 0x3 - }, { + /* gpio2_b7_sel */ .num = 2, .pin = 15, .reg = 0x28, .bit = 0, .mask = 0x7 }, { + /* gpio2_c7_sel */ .num = 2, .pin = 23, .reg = 0x30, .bit = 14, .mask = 0x3 + }, { + /* gpio3_b1_sel */ + .num = 3, + .pin = 9, + .reg = 0x44, + .bit = 2, + .mask = 0x3 + }, { + /* gpio3_b2_sel */ + .num = 3, + .pin = 10, + .reg = 0x44, + .bit = 4, + .mask = 0x3 + }, { + /* gpio3_b3_sel */ + .num = 3, + .pin = 11, + .reg = 0x44, + .bit = 6, + .mask = 0x3 + }, { + /* gpio3_b4_sel */ + .num = 3, + .pin = 12, + .reg = 0x44, + .bit = 8, + .mask = 0x3 + }, { + /* gpio3_b5_sel */ + .num = 3, + .pin = 13, + .reg = 0x44, + .bit = 10, + .mask = 0x3 + }, { + /* gpio3_b6_sel */ + .num = 3, + .pin = 14, + .reg = 0x44, + .bit = 12, + .mask = 0x3 + }, { + /* gpio3_b7_sel */ + .num = 3, + .pin = 15, + .reg = 0x44, + .bit = 14, + .mask = 0x3 }, }; @@ -2187,8 +2235,10 @@ if (ret) { /* revert the already done pin settings */ - for (cnt--; cnt >= 0; cnt--) + for (cnt--; cnt >= 0; cnt--) { + bank = pin_to_bank(info, pins[cnt]); rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); + } return ret; } @@ -2533,6 +2583,7 @@ np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); ret = pinconf_generic_parse_dt_config(np_config, NULL, &grp->data[j].configs, &grp->data[j].nconfigs); + of_node_put(np_config); if (ret) return ret; } @@ -2810,7 +2861,9 @@ if (!bank->domain) return -ENXIO; + clk_enable(bank->clk); virq = irq_create_mapping(bank->domain, offset); + clk_disable(bank->clk); return (virq) ? : -ENXIO; } @@ -3383,12 +3436,15 @@ static int __maybe_unused rockchip_pinctrl_resume(struct device *dev) { struct rockchip_pinctrl *info = dev_get_drvdata(dev); - int ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, - rk3288_grf_gpio6c_iomux | - GPIO6C6_SEL_WRITE_ENABLE); + int ret; - if (ret) - return ret; + if (info->ctrl->type == RK3288) { + ret = regmap_write(info->regmap_base, RK3288_GRF_GPIO6C_IOMUX, + rk3288_grf_gpio6c_iomux | + GPIO6C6_SEL_WRITE_ENABLE); + if (ret) + return ret; + } return pinctrl_force_default(info->pctl_dev); } @@ -3427,6 +3483,7 @@ node = of_parse_phandle(np, "rockchip,grf", 0); if (node) { info->regmap_base = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(info->regmap_base)) return PTR_ERR(info->regmap_base); } else { @@ -3463,6 +3520,7 @@ node = of_parse_phandle(np, "rockchip,pmu", 0); if (node) { info->regmap_pmu = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(info->regmap_pmu)) return PTR_ERR(info->regmap_pmu); } @@ -3713,7 +3771,7 @@ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, - IOMUX_WIDTH_3BIT, + 0, IOMUX_WIDTH_3BIT, 0), PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-rza1.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-rza1.c @@ -418,7 +418,7 @@ }; static const struct rza1_swio_entry rza1l_swio_entries[] = { - [0] = { ARRAY_SIZE(rza1h_swio_pins), rza1h_swio_pins }, + [0] = { ARRAY_SIZE(rza1l_swio_pins), rza1l_swio_pins }, }; /* RZ/A1L (r7s72102x) pinmux flags table */ --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-rza2.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-rza2.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,7 @@ struct pinctrl_dev *pctl; struct pinctrl_gpio_range gpio_range; int npins; + struct mutex mutex; /* serialize adding groups and functions */ }; #define RZA2_PDR(port) (0x0000 + (port) * 2) /* Direction 16-bit */ @@ -213,8 +215,8 @@ "PC_0", "PC_1", "PC_2", "PC_3", "PC_4", "PC_5", "PC_6", "PC_7", "PD_0", "PD_1", "PD_2", "PD_3", "PD_4", "PD_5", "PD_6", "PD_7", "PE_0", "PE_1", "PE_2", "PE_3", "PE_4", "PE_5", "PE_6", "PE_7", - "PF_0", "PF_1", "PF_2", "PF_3", "P0_4", "PF_5", "PF_6", "PF_7", - "PG_0", "PG_1", "PG_2", "P0_3", "PG_4", "PG_5", "PG_6", "PG_7", + "PF_0", "PF_1", "PF_2", "PF_3", "PF_4", "PF_5", "PF_6", "PF_7", + "PG_0", "PG_1", "PG_2", "PG_3", "PG_4", "PG_5", "PG_6", "PG_7", "PH_0", "PH_1", "PH_2", "PH_3", "PH_4", "PH_5", "PH_6", "PH_7", /* port I does not exist */ "PJ_0", "PJ_1", "PJ_2", "PJ_3", "PJ_4", "PJ_5", "PJ_6", "PJ_7", @@ -359,10 +361,14 @@ psel_val[i] = MUX_FUNC(value); } + mutex_lock(&priv->mutex); + /* Register a single pin group listing all the pins we read from DT */ gsel = pinctrl_generic_add_group(pctldev, np->name, pins, npins, NULL); - if (gsel < 0) - return gsel; + if (gsel < 0) { + ret = gsel; + goto unlock; + } /* * Register a single group function where the 'data' is an array PSEL @@ -391,6 +397,8 @@ (*map)->data.mux.function = np->name; *num_maps = 1; + mutex_unlock(&priv->mutex); + return 0; remove_function: @@ -399,6 +407,9 @@ remove_group: pinctrl_generic_remove_group(pctldev, gsel); +unlock: + mutex_unlock(&priv->mutex); + dev_err(priv->dev, "Unable to parse DT node %s\n", np->name); return ret; @@ -476,6 +487,8 @@ if (IS_ERR(priv->base)) return PTR_ERR(priv->base); + mutex_init(&priv->mutex); + platform_set_drvdata(pdev, priv); priv->npins = (int)(uintptr_t)of_device_get_match_data(&pdev->dev) * --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-single.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-single.c @@ -323,6 +323,8 @@ return -ENOTSUPP; fselector = setting->func; function = pinmux_generic_get_function(pctldev, fselector); + if (!function) + return -EINVAL; *func = function->data; if (!(*func)) { dev_err(pcs->dev, "%s could not find function%i\n", @@ -345,6 +347,8 @@ if (!pcs->fmask) return 0; function = pinmux_generic_get_function(pctldev, fselector); + if (!function) + return -EINVAL; func = function->data; if (!func) return -EINVAL; @@ -703,7 +707,7 @@ mux_bytes = pcs->width / BITS_PER_BYTE; - if (pcs->bits_per_mux) { + if (pcs->bits_per_mux && pcs->fmask) { pcs->bits_per_pin = fls(pcs->fmask); nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; num_pins_in_register = pcs->width / pcs->bits_per_pin; @@ -916,7 +920,7 @@ /* If pinconf isn't supported, don't parse properties in below. */ if (!PCS_HAS_PINCONF) - return 0; + return -ENOTSUPP; /* cacluate how much properties are supported in current node */ for (i = 0; i < ARRAY_SIZE(prop2); i++) { @@ -928,7 +932,7 @@ nconfs++; } if (!nconfs) - return 0; + return -ENOTSUPP; func->conf = devm_kcalloc(pcs->dev, nconfs, sizeof(struct pcs_conf_vals), @@ -1056,9 +1060,12 @@ if (PCS_HAS_PINCONF && function) { res = pcs_parse_pinconf(pcs, np, function, map); - if (res) + if (res == 0) + *num_maps = 2; + else if (res == -ENOTSUPP) + *num_maps = 1; + else goto free_pingroups; - *num_maps = 2; } else { *num_maps = 1; } @@ -1198,6 +1205,7 @@ if (PCS_HAS_PINCONF) { dev_err(pcs->dev, "pinconf not supported\n"); + res = -ENOTSUPP; goto free_pingroups; } @@ -1305,7 +1313,6 @@ static void pcs_free_resources(struct pcs_device *pcs) { pcs_irq_free(pcs); - pinctrl_unregister(pcs->pctl); #if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) if (pcs->missing_nr_pinctrl_cells) @@ -1858,7 +1865,7 @@ if (ret < 0) goto free; - ret = pinctrl_register_and_init(&pcs->desc, pcs->dev, pcs, &pcs->pctl); + ret = devm_pinctrl_register_and_init(pcs->dev, &pcs->desc, pcs, &pcs->pctl); if (ret) { dev_err(pcs->dev, "could not register single pinctrl driver\n"); goto free; @@ -1891,8 +1898,11 @@ dev_info(pcs->dev, "%i pins, size %u\n", pcs->desc.npins, pcs->size); - return pinctrl_enable(pcs->pctl); + ret = pinctrl_enable(pcs->pctl); + if (ret) + goto free; + return 0; free: pcs_free_resources(pcs); --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinctrl-stmfx.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinctrl-stmfx.c @@ -540,7 +540,7 @@ u8 pending[NR_GPIO_REGS]; u8 src[NR_GPIO_REGS] = {0, 0, 0}; unsigned long n, status; - int ret; + int i, ret; ret = regmap_bulk_read(pctl->stmfx->map, STMFX_REG_IRQ_GPI_PENDING, &pending, NR_GPIO_REGS); @@ -550,7 +550,9 @@ regmap_bulk_write(pctl->stmfx->map, STMFX_REG_IRQ_GPI_SRC, src, NR_GPIO_REGS); - status = *(unsigned long *)pending; + BUILD_BUG_ON(NR_GPIO_REGS > sizeof(status)); + for (i = 0, status = 0; i < NR_GPIO_REGS; i++) + status |= (unsigned long)pending[i] << (i * 8); for_each_set_bit(n, &status, gc->ngpio) { handle_nested_irq(irq_find_mapping(gc->irq.domain, n)); stmfx_pinctrl_irq_toggle_trigger(pctl, n); --- linux-oracle-5.4.0.orig/drivers/pinctrl/pinmux.c +++ linux-oracle-5.4.0/drivers/pinctrl/pinmux.c @@ -85,7 +85,7 @@ const struct pinmux_ops *ops = pctldev->desc->pmxops; /* Can't inspect pin, assume it can be used */ - if (!desc) + if (!desc || !ops) return true; if (ops->strict && desc->mux_usecount) --- linux-oracle-5.4.0.orig/drivers/pinctrl/qcom/pinctrl-msm.c +++ linux-oracle-5.4.0/drivers/pinctrl/qcom/pinctrl-msm.c @@ -688,7 +688,7 @@ pol = msm_readl_intr_cfg(pctrl, g); pol ^= BIT(g->intr_polarity_bit); - msm_writel_intr_cfg(val, pctrl, g); + msm_writel_intr_cfg(pol, pctrl, g); val2 = msm_readl_io(pctrl, g) & BIT(g->in_bit); intstat = msm_readl_intr_status(pctrl, g); --- linux-oracle-5.4.0.orig/drivers/pinctrl/qcom/pinctrl-msm8916.c +++ linux-oracle-5.4.0/drivers/pinctrl/qcom/pinctrl-msm8916.c @@ -844,8 +844,8 @@ PINGROUP(28, pwr_modem_enabled_a, NA, NA, NA, NA, NA, qdss_tracedata_b, NA, atest_combodac), PINGROUP(29, cci_i2c, NA, NA, NA, NA, NA, qdss_tracedata_b, NA, atest_combodac), PINGROUP(30, cci_i2c, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b), - PINGROUP(31, cci_timer0, NA, NA, NA, NA, NA, NA, NA, NA), - PINGROUP(32, cci_timer1, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(31, cci_timer0, flash_strobe, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(32, cci_timer1, flash_strobe, NA, NA, NA, NA, NA, NA, NA), PINGROUP(33, cci_async, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b), PINGROUP(34, pwr_nav_enabled_a, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b), PINGROUP(35, pwr_crypto_enabled_a, NA, NA, NA, NA, NA, NA, NA, qdss_tracedata_b), --- linux-oracle-5.4.0.orig/drivers/pinctrl/qcom/pinctrl-sc7180.c +++ linux-oracle-5.4.0/drivers/pinctrl/qcom/pinctrl-sc7180.c @@ -77,6 +77,7 @@ .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ + .tile = SOUTH, \ .mux_bit = -1, \ .pull_bit = pull, \ .drv_bit = drv, \ @@ -102,6 +103,7 @@ .intr_cfg_reg = 0, \ .intr_status_reg = 0, \ .intr_target_reg = 0, \ + .tile = SOUTH, \ .mux_bit = -1, \ .pull_bit = 3, \ .drv_bit = 0, \ @@ -1087,14 +1089,14 @@ [116] = PINGROUP(116, WEST, qup04, qup04, _, _, _, _, _, _, _), [117] = PINGROUP(117, WEST, dp_hot, _, _, _, _, _, _, _, _), [118] = PINGROUP(118, WEST, _, _, _, _, _, _, _, _, _), - [119] = UFS_RESET(ufs_reset, 0x97f000), - [120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x97a000, 15, 0), - [121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x97a000, 13, 6), - [122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x97a000, 11, 3), - [123] = SDC_QDSD_PINGROUP(sdc1_data, 0x97a000, 9, 0), - [124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x97b000, 14, 6), - [125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x97b000, 11, 3), - [126] = SDC_QDSD_PINGROUP(sdc2_data, 0x97b000, 9, 0), + [119] = UFS_RESET(ufs_reset, 0x7f000), + [120] = SDC_QDSD_PINGROUP(sdc1_rclk, 0x7a000, 15, 0), + [121] = SDC_QDSD_PINGROUP(sdc1_clk, 0x7a000, 13, 6), + [122] = SDC_QDSD_PINGROUP(sdc1_cmd, 0x7a000, 11, 3), + [123] = SDC_QDSD_PINGROUP(sdc1_data, 0x7a000, 9, 0), + [124] = SDC_QDSD_PINGROUP(sdc2_clk, 0x7b000, 14, 6), + [125] = SDC_QDSD_PINGROUP(sdc2_cmd, 0x7b000, 11, 3), + [126] = SDC_QDSD_PINGROUP(sdc2_data, 0x7b000, 9, 0), }; static const struct msm_pinctrl_soc_data sc7180_pinctrl = { --- linux-oracle-5.4.0.orig/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ linux-oracle-5.4.0/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c @@ -170,6 +170,7 @@ struct regmap *map; struct pinctrl_dev *ctrl; struct gpio_chip chip; + struct irq_chip irq; }; static const struct pinconf_generic_params pmic_gpio_bindings[] = { @@ -917,16 +918,6 @@ return 0; } -static struct irq_chip pmic_gpio_irq_chip = { - .name = "spmi-gpio", - .irq_ack = irq_chip_ack_parent, - .irq_mask = irq_chip_mask_parent, - .irq_unmask = irq_chip_unmask_parent, - .irq_set_type = irq_chip_set_type_parent, - .irq_set_wake = irq_chip_set_wake_parent, - .flags = IRQCHIP_MASK_ON_SUSPEND, -}; - static int pmic_gpio_domain_translate(struct irq_domain *domain, struct irq_fwspec *fwspec, unsigned long *hwirq, @@ -1053,8 +1044,16 @@ if (!parent_domain) return -ENXIO; + state->irq.name = "spmi-gpio", + state->irq.irq_ack = irq_chip_ack_parent, + state->irq.irq_mask = irq_chip_mask_parent, + state->irq.irq_unmask = irq_chip_unmask_parent, + state->irq.irq_set_type = irq_chip_set_type_parent, + state->irq.irq_set_wake = irq_chip_set_wake_parent, + state->irq.flags = IRQCHIP_MASK_ON_SUSPEND, + girq = &state->chip.irq; - girq->chip = &pmic_gpio_irq_chip; + girq->chip = &state->irq; girq->default_type = IRQ_TYPE_NONE; girq->handler = handle_level_irq; girq->fwnode = of_node_to_fwnode(state->dev->of_node); @@ -1107,6 +1106,8 @@ static const struct of_device_id pmic_gpio_of_match[] = { { .compatible = "qcom,pm8005-gpio", .data = (void *) 4 }, { .compatible = "qcom,pm8916-gpio", .data = (void *) 4 }, + /* pm8937 has 8 GPIOs with holes on 3, 4 and 6 */ + { .compatible = "qcom,pm8937-gpio", .data = (void *) 8 }, { .compatible = "qcom,pm8941-gpio", .data = (void *) 36 }, { .compatible = "qcom,pm8994-gpio", .data = (void *) 22 }, { .compatible = "qcom,pmi8994-gpio", .data = (void *) 10 }, --- linux-oracle-5.4.0.orig/drivers/pinctrl/samsung/pinctrl-exynos.c +++ linux-oracle-5.4.0/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -40,6 +40,8 @@ u32 eint_pend; u32 eint_wake_mask_value; u32 eint_wake_mask_reg; + void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata, + struct exynos_irq_chip *irq_chip); }; static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip) @@ -53,7 +55,7 @@ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; - unsigned long mask; + unsigned int mask; unsigned long flags; spin_lock_irqsave(&bank->slock, flags); @@ -81,7 +83,7 @@ struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip); struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd); unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset; - unsigned long mask; + unsigned int mask; unsigned long flags; /* @@ -265,6 +267,7 @@ u32 eint_con; u32 eint_fltcon0; u32 eint_fltcon1; + u32 eint_mask; }; /* @@ -342,6 +345,47 @@ return 0; } +static void +exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, + struct exynos_irq_chip *irq_chip) +{ + struct regmap *pmu_regs; + + if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) { + dev_warn(drvdata->dev, + "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n"); + return; + } + + pmu_regs = drvdata->retention_ctrl->priv; + dev_info(drvdata->dev, + "Setting external wakeup interrupt mask: 0x%x\n", + irq_chip->eint_wake_mask_value); + + regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg, + irq_chip->eint_wake_mask_value); +} + +static void +s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, + struct exynos_irq_chip *irq_chip) + +{ + void __iomem *clk_base; + + if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) { + dev_warn(drvdata->dev, + "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n"); + return; + } + + + clk_base = (void __iomem *) drvdata->retention_ctrl->priv; + + __raw_writel(irq_chip->eint_wake_mask_value, + clk_base + irq_chip->eint_wake_mask_reg); +} + /* * irq_chip for wakeup interrupts */ @@ -360,8 +404,9 @@ .eint_mask = EXYNOS_WKUP_EMASK_OFFSET, .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, - /* Only difference with exynos4210_wkup_irq_chip: */ + /* Only differences with exynos4210_wkup_irq_chip: */ .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK, + .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask, }; static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = { @@ -380,6 +425,7 @@ .eint_pend = EXYNOS_WKUP_EPEND_OFFSET, .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK, + .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, }; static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = { @@ -398,6 +444,7 @@ .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET, .eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED, .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK, + .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask, }; /* list of external wakeup controllers supported */ @@ -427,7 +474,7 @@ chained_irq_exit(chip, desc); } -static inline void exynos_irq_demux_eint(unsigned long pend, +static inline void exynos_irq_demux_eint(unsigned int pend, struct irq_domain *domain) { unsigned int irq; @@ -444,8 +491,8 @@ { struct irq_chip *chip = irq_desc_get_chip(desc); struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc); - unsigned long pend; - unsigned long mask; + unsigned int pend; + unsigned int mask; int i; chained_irq_enter(chip, desc); @@ -486,8 +533,10 @@ if (match) { irq_chip = kmemdup(match->data, sizeof(*irq_chip), GFP_KERNEL); - if (!irq_chip) + if (!irq_chip) { + of_node_put(np); return -ENOMEM; + } wkup_np = np; break; } @@ -504,6 +553,7 @@ bank->nr_pins, &exynos_eint_irqd_ops, bank); if (!bank->irq_domain) { dev_err(dev, "wkup irq domain add failed\n"); + of_node_put(wkup_np); return -ENXIO; } @@ -518,8 +568,10 @@ weint_data = devm_kcalloc(dev, bank->nr_pins, sizeof(*weint_data), GFP_KERNEL); - if (!weint_data) + if (!weint_data) { + of_node_put(wkup_np); return -ENOMEM; + } for (idx = 0; idx < bank->nr_pins; ++idx) { irq = irq_of_parse_and_map(bank->of_node, idx); @@ -536,10 +588,13 @@ } } - if (!muxed_banks) + if (!muxed_banks) { + of_node_put(wkup_np); return 0; + } irq = irq_of_parse_and_map(wkup_np, 0); + of_node_put(wkup_np); if (!irq) { dev_err(dev, "irq number for muxed EINTs not found\n"); return 0; @@ -566,27 +621,6 @@ return 0; } -static void -exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata, - struct exynos_irq_chip *irq_chip) -{ - struct regmap *pmu_regs; - - if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) { - dev_warn(drvdata->dev, - "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n"); - return; - } - - pmu_regs = drvdata->retention_ctrl->priv; - dev_info(drvdata->dev, - "Setting external wakeup interrupt mask: 0x%x\n", - irq_chip->eint_wake_mask_value); - - regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg, - irq_chip->eint_wake_mask_value); -} - static void exynos_pinctrl_suspend_bank( struct samsung_pinctrl_drv_data *drvdata, struct samsung_pin_bank *bank) @@ -600,10 +634,13 @@ + 2 * bank->eint_offset); save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4); + save->eint_mask = readl(regs + bank->irq_chip->eint_mask + + bank->eint_offset); pr_debug("%s: save con %#010x\n", bank->name, save->eint_con); pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0); pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1); + pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask); } void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata) @@ -618,8 +655,8 @@ else if (bank->eint_type == EINT_TYPE_WKUP) { if (!irq_chip) { irq_chip = bank->irq_chip; - exynos_pinctrl_set_eint_wakeup_mask(drvdata, - irq_chip); + irq_chip->set_eint_wakeup_mask(drvdata, + irq_chip); } else if (bank->irq_chip != irq_chip) { dev_warn(drvdata->dev, "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n", @@ -645,6 +682,9 @@ pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name, readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4), save->eint_fltcon1); + pr_debug("%s: mask %#010x => %#010x\n", bank->name, + readl(regs + bank->irq_chip->eint_mask + + bank->eint_offset), save->eint_mask); writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET + bank->eint_offset); @@ -652,6 +692,8 @@ + 2 * bank->eint_offset); writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET + 2 * bank->eint_offset + 4); + writel(save->eint_mask, regs + bank->irq_chip->eint_mask + + bank->eint_offset); } void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata) --- linux-oracle-5.4.0.orig/drivers/pinctrl/samsung/pinctrl-s3c24xx.c +++ linux-oracle-5.4.0/drivers/pinctrl/samsung/pinctrl-s3c24xx.c @@ -490,8 +490,10 @@ return -ENODEV; eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL); - if (!eint_data) + if (!eint_data) { + of_node_put(eint_np); return -ENOMEM; + } eint_data->drvdata = d; @@ -503,12 +505,14 @@ irq = irq_of_parse_and_map(eint_np, i); if (!irq) { dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); + of_node_put(eint_np); return -ENXIO; } eint_data->parents[i] = irq; irq_set_chained_handler_and_data(irq, handlers[i], eint_data); } + of_node_put(eint_np); bank = d->pin_banks; for (i = 0; i < d->nr_banks; ++i, ++bank) { --- linux-oracle-5.4.0.orig/drivers/pinctrl/samsung/pinctrl-s3c64xx.c +++ linux-oracle-5.4.0/drivers/pinctrl/samsung/pinctrl-s3c64xx.c @@ -704,8 +704,10 @@ return -ENODEV; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) + if (!data) { + of_node_put(eint0_np); return -ENOMEM; + } data->drvdata = d; for (i = 0; i < NUM_EINT0_IRQ; ++i) { @@ -714,6 +716,7 @@ irq = irq_of_parse_and_map(eint0_np, i); if (!irq) { dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); + of_node_put(eint0_np); return -ENXIO; } @@ -721,6 +724,7 @@ s3c64xx_eint0_handlers[i], data); } + of_node_put(eint0_np); bank = d->pin_banks; for (i = 0; i < d->nr_banks; ++i, ++bank) { --- linux-oracle-5.4.0.orig/drivers/pinctrl/samsung/pinctrl-samsung.c +++ linux-oracle-5.4.0/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -272,6 +272,7 @@ &reserved_maps, num_maps); if (ret < 0) { samsung_dt_free_map(pctldev, *map, *num_maps); + of_node_put(np); return ret; } } @@ -785,8 +786,10 @@ if (!of_get_child_count(cfg_np)) { ret = samsung_pinctrl_create_function(dev, drvdata, cfg_np, func); - if (ret < 0) + if (ret < 0) { + of_node_put(cfg_np); return ERR_PTR(ret); + } if (ret > 0) { ++func; ++func_cnt; @@ -797,8 +800,11 @@ for_each_child_of_node(cfg_np, func_np) { ret = samsung_pinctrl_create_function(dev, drvdata, func_np, func); - if (ret < 0) + if (ret < 0) { + of_node_put(func_np); + of_node_put(cfg_np); return ERR_PTR(ret); + } if (ret > 0) { ++func; ++func_cnt; @@ -912,7 +918,7 @@ pin_bank->grange.pin_base = drvdata->pin_base + pin_bank->pin_base; pin_bank->grange.base = pin_bank->grange.pin_base; - pin_bank->grange.npins = pin_bank->gpio_chip.ngpio; + pin_bank->grange.npins = pin_bank->nr_pins; pin_bank->grange.gc = &pin_bank->gpio_chip; pinctrl_add_gpio_range(drvdata->pctl_dev, &pin_bank->grange); } @@ -996,6 +1002,16 @@ return &(of_data->ctrl[id]); } +static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d) +{ + struct samsung_pin_bank *bank; + unsigned int i; + + bank = d->pin_banks; + for (i = 0; i < d->nr_banks; ++i, ++bank) + of_node_put(bank->of_node); +} + /* retrieve the soc specific data */ static const struct samsung_pin_ctrl * samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d, @@ -1110,19 +1126,19 @@ if (ctrl->retention_data) { drvdata->retention_ctrl = ctrl->retention_data->init(drvdata, ctrl->retention_data); - if (IS_ERR(drvdata->retention_ctrl)) - return PTR_ERR(drvdata->retention_ctrl); + if (IS_ERR(drvdata->retention_ctrl)) { + ret = PTR_ERR(drvdata->retention_ctrl); + goto err_put_banks; + } } ret = samsung_pinctrl_register(pdev, drvdata); if (ret) - return ret; + goto err_put_banks; ret = samsung_gpiolib_register(pdev, drvdata); - if (ret) { - samsung_pinctrl_unregister(pdev, drvdata); - return ret; - } + if (ret) + goto err_unregister; if (ctrl->eint_gpio_init) ctrl->eint_gpio_init(drvdata); @@ -1132,6 +1148,12 @@ platform_set_drvdata(pdev, drvdata); return 0; + +err_unregister: + samsung_pinctrl_unregister(pdev, drvdata); +err_put_banks: + samsung_banks_of_node_put(drvdata); + return ret; } /** --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/core.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/core.c @@ -29,12 +29,12 @@ static int sh_pfc_map_resources(struct sh_pfc *pfc, struct platform_device *pdev) { - unsigned int num_windows, num_irqs; struct sh_pfc_window *windows; unsigned int *irqs = NULL; + unsigned int num_windows; struct resource *res; unsigned int i; - int irq; + int num_irqs; /* Count the MEM and IRQ resources. */ for (num_windows = 0;; num_windows++) { @@ -42,17 +42,13 @@ if (!res) break; } - for (num_irqs = 0;; num_irqs++) { - irq = platform_get_irq(pdev, num_irqs); - if (irq == -EPROBE_DEFER) - return irq; - if (irq < 0) - break; - } - if (num_windows == 0) return -EINVAL; + num_irqs = platform_irq_count(pdev); + if (num_irqs < 0) + return num_irqs; + /* Allocate memory windows and IRQs arrays. */ windows = devm_kcalloc(pfc->dev, num_windows, sizeof(*windows), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-r8a77470.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-r8a77470.c @@ -2121,7 +2121,7 @@ VI0_CLK_MARK, }; /* - VIN1 ------------------------------------------------------------------- */ -static const union vin_data vin1_data_pins = { +static const union vin_data12 vin1_data_pins = { .data12 = { RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 4), @@ -2131,7 +2131,7 @@ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 16), }, }; -static const union vin_data vin1_data_mux = { +static const union vin_data12 vin1_data_mux = { .data12 = { VI1_DATA0_MARK, VI1_DATA1_MARK, VI1_DATA2_MARK, VI1_DATA3_MARK, --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-r8a7778.c @@ -2305,7 +2305,7 @@ FN_ATAG0_A, 0, FN_REMOCON_B, 0, /* IP0_11_8 [4] */ FN_SD1_DAT2_A, FN_MMC_D2, 0, FN_BS, - FN_ATADIR0_A, 0, FN_SDSELF_B, 0, + FN_ATADIR0_A, 0, FN_SDSELF_A, 0, FN_PWM4_B, 0, 0, 0, 0, 0, 0, 0, /* IP0_7_5 [3] */ @@ -2349,7 +2349,7 @@ FN_TS_SDAT0_A, 0, 0, 0, 0, 0, 0, 0, /* IP1_10_8 [3] */ - FN_SD1_CLK_B, FN_MMC_D6, 0, FN_A24, + FN_SD1_CD_A, FN_MMC_D6, 0, FN_A24, FN_DREQ1_A, 0, FN_HRX0_B, FN_TS_SPSYNC0_A, /* IP1_7_5 [3] */ FN_A23, FN_HTX0_B, FN_TX2_B, FN_DACK2_A, --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-r8a7796.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-r8a7796.c @@ -68,6 +68,7 @@ PIN_NOGP_CFG(QSPI1_MOSI_IO0, "QSPI1_MOSI_IO0", fn, CFG_FLAGS), \ PIN_NOGP_CFG(QSPI1_SPCLK, "QSPI1_SPCLK", fn, CFG_FLAGS), \ PIN_NOGP_CFG(QSPI1_SSL, "QSPI1_SSL", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(PRESET_N, "PRESET#", fn, SH_PFC_PIN_CFG_PULL_DOWN),\ PIN_NOGP_CFG(RPC_INT_N, "RPC_INT#", fn, CFG_FLAGS), \ PIN_NOGP_CFG(RPC_RESET_N, "RPC_RESET#", fn, CFG_FLAGS), \ PIN_NOGP_CFG(RPC_WP_N, "RPC_WP#", fn, CFG_FLAGS), \ @@ -6109,7 +6110,7 @@ [ 4] = RCAR_GP_PIN(6, 29), /* USB30_OVC */ [ 5] = RCAR_GP_PIN(6, 30), /* GP6_30 */ [ 6] = RCAR_GP_PIN(6, 31), /* GP6_31 */ - [ 7] = SH_PFC_PIN_NONE, + [ 7] = PIN_PRESET_N, /* PRESET# */ [ 8] = SH_PFC_PIN_NONE, [ 9] = SH_PFC_PIN_NONE, [10] = SH_PFC_PIN_NONE, --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-r8a77965.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-r8a77965.c @@ -5984,7 +5984,7 @@ { PIN_DU_DOTCLKIN1, 0, 2 }, /* DU_DOTCLKIN1 */ } }, { PINMUX_DRIVE_REG("DRVCTRL12", 0xe6060330) { - { PIN_DU_DOTCLKIN3, 28, 2 }, /* DU_DOTCLKIN3 */ + { PIN_DU_DOTCLKIN3, 24, 2 }, /* DU_DOTCLKIN3 */ { PIN_FSCLKST, 20, 2 }, /* FSCLKST */ { PIN_TMS, 4, 2 }, /* TMS */ } }, @@ -6240,8 +6240,8 @@ [31] = PIN_DU_DOTCLKIN1, /* DU_DOTCLKIN1 */ } }, { PINMUX_BIAS_REG("PUEN3", 0xe606040c, "PUD3", 0xe606044c) { - [ 0] = PIN_DU_DOTCLKIN3, /* DU_DOTCLKIN3 */ - [ 1] = SH_PFC_PIN_NONE, + [ 0] = SH_PFC_PIN_NONE, + [ 1] = PIN_DU_DOTCLKIN3, /* DU_DOTCLKIN3 */ [ 2] = PIN_FSCLKST, /* FSCLKST */ [ 3] = PIN_EXTALR, /* EXTALR*/ [ 4] = PIN_TRST_N, /* TRST# */ --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-r8a77990.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-r8a77990.c @@ -54,10 +54,10 @@ PIN_NOGP_CFG(FSCLKST_N, "FSCLKST_N", fn, CFG_FLAGS), \ PIN_NOGP_CFG(MLB_REF, "MLB_REF", fn, CFG_FLAGS), \ PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT_N", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TCK, "TCK", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TDI, "TDI", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TMS, "TMS", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TRST_N, "TRST_N", fn, CFG_FLAGS) + PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TRST_N, "TRST_N", fn, SH_PFC_PIN_CFG_PULL_UP) /* * F_() : just information @@ -448,6 +448,8 @@ #define MOD_SEL0_1_0 REV4(FM(SEL_SPEED_PULSE_IF_0), FM(SEL_SPEED_PULSE_IF_1), FM(SEL_SPEED_PULSE_IF_2), F_(0, 0)) /* MOD_SEL1 */ /* 0 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */ /* 7 */ +#define MOD_SEL1_31 FM(SEL_SIMCARD_0) FM(SEL_SIMCARD_1) +#define MOD_SEL1_30 FM(SEL_SSI2_0) FM(SEL_SSI2_1) #define MOD_SEL1_29 FM(SEL_TIMER_TMU_0) FM(SEL_TIMER_TMU_1) #define MOD_SEL1_28 FM(SEL_USB_20_CH0_0) FM(SEL_USB_20_CH0_1) #define MOD_SEL1_26 FM(SEL_DRIF2_0) FM(SEL_DRIF2_1) @@ -468,7 +470,8 @@ #define PINMUX_MOD_SELS \ \ -MOD_SEL0_30_29 \ + MOD_SEL1_31 \ +MOD_SEL0_30_29 MOD_SEL1_30 \ MOD_SEL1_29 \ MOD_SEL0_28 MOD_SEL1_28 \ MOD_SEL0_27_26 \ @@ -1058,7 +1061,7 @@ PINMUX_IPSR_MSEL(IP10_27_24, RIF0_CLK_B, SEL_DRIF0_1), PINMUX_IPSR_MSEL(IP10_27_24, SCL2_B, SEL_I2C2_1), PINMUX_IPSR_MSEL(IP10_27_24, TCLK1_A, SEL_TIMER_TMU_0), - PINMUX_IPSR_GPSR(IP10_27_24, SSI_SCK2_B), + PINMUX_IPSR_MSEL(IP10_27_24, SSI_SCK2_B, SEL_SSI2_1), PINMUX_IPSR_GPSR(IP10_27_24, TS_SCK0), PINMUX_IPSR_GPSR(IP10_31_28, SD0_WP), @@ -1067,7 +1070,7 @@ PINMUX_IPSR_MSEL(IP10_31_28, RIF0_D0_B, SEL_DRIF0_1), PINMUX_IPSR_MSEL(IP10_31_28, SDA2_B, SEL_I2C2_1), PINMUX_IPSR_MSEL(IP10_31_28, TCLK2_A, SEL_TIMER_TMU_0), - PINMUX_IPSR_GPSR(IP10_31_28, SSI_WS2_B), + PINMUX_IPSR_MSEL(IP10_31_28, SSI_WS2_B, SEL_SSI2_1), PINMUX_IPSR_GPSR(IP10_31_28, TS_SDAT0), /* IPSR11 */ @@ -1085,13 +1088,13 @@ PINMUX_IPSR_MSEL(IP11_11_8, RX0_A, SEL_SCIF0_0), PINMUX_IPSR_MSEL(IP11_11_8, HRX1_A, SEL_HSCIF1_0), - PINMUX_IPSR_GPSR(IP11_11_8, SSI_SCK2_A), + PINMUX_IPSR_MSEL(IP11_11_8, SSI_SCK2_A, SEL_SSI2_0), PINMUX_IPSR_GPSR(IP11_11_8, RIF1_SYNC), PINMUX_IPSR_GPSR(IP11_11_8, TS_SCK1), PINMUX_IPSR_MSEL(IP11_15_12, TX0_A, SEL_SCIF0_0), PINMUX_IPSR_GPSR(IP11_15_12, HTX1_A), - PINMUX_IPSR_GPSR(IP11_15_12, SSI_WS2_A), + PINMUX_IPSR_MSEL(IP11_15_12, SSI_WS2_A, SEL_SSI2_0), PINMUX_IPSR_GPSR(IP11_15_12, RIF1_D0), PINMUX_IPSR_GPSR(IP11_15_12, TS_SDAT1), @@ -1196,7 +1199,7 @@ PINMUX_IPSR_MSEL(IP13_19_16, RIF0_D1_A, SEL_DRIF0_0), PINMUX_IPSR_MSEL(IP13_19_16, SDA1_B, SEL_I2C1_1), PINMUX_IPSR_MSEL(IP13_19_16, TCLK2_B, SEL_TIMER_TMU_1), - PINMUX_IPSR_GPSR(IP13_19_16, SIM0_D_A), + PINMUX_IPSR_MSEL(IP13_19_16, SIM0_D_A, SEL_SIMCARD_0), PINMUX_IPSR_GPSR(IP13_23_20, MLB_DAT), PINMUX_IPSR_MSEL(IP13_23_20, TX0_B, SEL_SCIF0_1), @@ -1264,7 +1267,7 @@ PINMUX_IPSR_GPSR(IP15_15_12, TPU0TO2), PINMUX_IPSR_MSEL(IP15_15_12, SDA1_D, SEL_I2C1_3), PINMUX_IPSR_MSEL(IP15_15_12, FSO_CFE_1_N_B, SEL_FSO_1), - PINMUX_IPSR_GPSR(IP15_15_12, SIM0_D_B), + PINMUX_IPSR_MSEL(IP15_15_12, SIM0_D_B, SEL_SIMCARD_1), PINMUX_IPSR_GPSR(IP15_19_16, SSI_SDATA6), PINMUX_IPSR_MSEL(IP15_19_16, HRTS2_N_A, SEL_HSCIF2_0), @@ -4957,11 +4960,11 @@ MOD_SEL0_1_0 )) }, { PINMUX_CFG_REG_VAR("MOD_SEL1", 0xe6060504, 32, - GROUP(2, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, - 2, 2, 2, 1, 1, 2, 1, 4), + GROUP(1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, + 1, 2, 2, 2, 1, 1, 2, 1, 4), GROUP( - /* RESERVED 31, 30 */ - 0, 0, 0, 0, + MOD_SEL1_31 + MOD_SEL1_30 MOD_SEL1_29 MOD_SEL1_28 /* RESERVED 27 */ --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-sh7264.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-sh7264.c @@ -497,17 +497,15 @@ SD_WP_MARK, SD_CLK_MARK, SD_CMD_MARK, CRX0_MARK, CRX1_MARK, CTX0_MARK, CTX1_MARK, + CRX0_CRX1_MARK, CTX0_CTX1_MARK, PWM1A_MARK, PWM1B_MARK, PWM1C_MARK, PWM1D_MARK, PWM1E_MARK, PWM1F_MARK, PWM1G_MARK, PWM1H_MARK, PWM2A_MARK, PWM2B_MARK, PWM2C_MARK, PWM2D_MARK, PWM2E_MARK, PWM2F_MARK, PWM2G_MARK, PWM2H_MARK, IERXD_MARK, IETXD_MARK, - CRX0_CRX1_MARK, WDTOVF_MARK, - CRX0X1_MARK, - /* DMAC */ TEND0_MARK, DACK0_MARK, DREQ0_MARK, TEND1_MARK, DACK1_MARK, DREQ1_MARK, @@ -995,12 +993,12 @@ PINMUX_DATA(PJ3_DATA, PJ3MD_00), PINMUX_DATA(CRX1_MARK, PJ3MD_01), - PINMUX_DATA(CRX0X1_MARK, PJ3MD_10), + PINMUX_DATA(CRX0_CRX1_MARK, PJ3MD_10), PINMUX_DATA(IRQ1_PJ_MARK, PJ3MD_11), PINMUX_DATA(PJ2_DATA, PJ2MD_000), PINMUX_DATA(CTX1_MARK, PJ2MD_001), - PINMUX_DATA(CRX0_CRX1_MARK, PJ2MD_010), + PINMUX_DATA(CTX0_CTX1_MARK, PJ2MD_010), PINMUX_DATA(CS2_MARK, PJ2MD_011), PINMUX_DATA(SCK0_MARK, PJ2MD_100), PINMUX_DATA(LCD_M_DISP_MARK, PJ2MD_101), @@ -1245,6 +1243,7 @@ GPIO_FN(CTX1), GPIO_FN(CRX1), GPIO_FN(CTX0), + GPIO_FN(CTX0_CTX1), GPIO_FN(CRX0), GPIO_FN(CRX0_CRX1), --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-sh7269.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-sh7269.c @@ -737,13 +737,12 @@ CRX0_MARK, CTX0_MARK, CRX1_MARK, CTX1_MARK, CRX2_MARK, CTX2_MARK, - CRX0_CRX1_MARK, - CRX0_CRX1_CRX2_MARK, - CTX0CTX1CTX2_MARK, + CRX0_CRX1_MARK, CTX0_CTX1_MARK, + CRX0_CRX1_CRX2_MARK, CTX0_CTX1_CTX2_MARK, CRX1_PJ22_MARK, CTX1_PJ23_MARK, CRX2_PJ20_MARK, CTX2_PJ21_MARK, - CRX0CRX1_PJ22_MARK, - CRX0CRX1CRX2_PJ20_MARK, + CRX0_CRX1_PJ22_MARK, CTX0_CTX1_PJ23_MARK, + CRX0_CRX1_CRX2_PJ20_MARK, CTX0_CTX1_CTX2_PJ21_MARK, /* VDC */ DV_CLK_MARK, @@ -821,6 +820,7 @@ PINMUX_DATA(CS3_MARK, PC8MD_001), PINMUX_DATA(TXD7_MARK, PC8MD_010), PINMUX_DATA(CTX1_MARK, PC8MD_011), + PINMUX_DATA(CTX0_CTX1_MARK, PC8MD_100), PINMUX_DATA(PC7_DATA, PC7MD_000), PINMUX_DATA(CKE_MARK, PC7MD_001), @@ -833,11 +833,12 @@ PINMUX_DATA(CAS_MARK, PC6MD_001), PINMUX_DATA(SCK7_MARK, PC6MD_010), PINMUX_DATA(CTX0_MARK, PC6MD_011), + PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC6MD_100), PINMUX_DATA(PC5_DATA, PC5MD_000), PINMUX_DATA(RAS_MARK, PC5MD_001), PINMUX_DATA(CRX0_MARK, PC5MD_011), - PINMUX_DATA(CTX0CTX1CTX2_MARK, PC5MD_100), + PINMUX_DATA(CTX0_CTX1_CTX2_MARK, PC5MD_100), PINMUX_DATA(IRQ0_PC_MARK, PC5MD_101), PINMUX_DATA(PC4_DATA, PC4MD_00), @@ -1289,30 +1290,32 @@ PINMUX_DATA(LCD_DATA23_PJ23_MARK, PJ23MD_010), PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011), PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100), - PINMUX_DATA(CTX1_MARK, PJ23MD_101), + PINMUX_DATA(CTX1_PJ23_MARK, PJ23MD_101), + PINMUX_DATA(CTX0_CTX1_PJ23_MARK, PJ23MD_110), PINMUX_DATA(PJ22_DATA, PJ22MD_000), PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001), PINMUX_DATA(LCD_DATA22_PJ22_MARK, PJ22MD_010), PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011), PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100), - PINMUX_DATA(CRX1_MARK, PJ22MD_101), - PINMUX_DATA(CRX0_CRX1_MARK, PJ22MD_110), + PINMUX_DATA(CRX1_PJ22_MARK, PJ22MD_101), + PINMUX_DATA(CRX0_CRX1_PJ22_MARK, PJ22MD_110), PINMUX_DATA(PJ21_DATA, PJ21MD_000), PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001), PINMUX_DATA(LCD_DATA21_PJ21_MARK, PJ21MD_010), PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011), PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100), - PINMUX_DATA(CTX2_MARK, PJ21MD_101), + PINMUX_DATA(CTX2_PJ21_MARK, PJ21MD_101), + PINMUX_DATA(CTX0_CTX1_CTX2_PJ21_MARK, PJ21MD_110), PINMUX_DATA(PJ20_DATA, PJ20MD_000), PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001), PINMUX_DATA(LCD_DATA20_PJ20_MARK, PJ20MD_010), PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011), PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100), - PINMUX_DATA(CRX2_MARK, PJ20MD_101), - PINMUX_DATA(CRX0CRX1CRX2_PJ20_MARK, PJ20MD_110), + PINMUX_DATA(CRX2_PJ20_MARK, PJ20MD_101), + PINMUX_DATA(CRX0_CRX1_CRX2_PJ20_MARK, PJ20MD_110), PINMUX_DATA(PJ19_DATA, PJ19MD_000), PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001), @@ -1663,12 +1666,24 @@ GPIO_FN(WDTOVF), /* CAN */ + GPIO_FN(CTX2), + GPIO_FN(CRX2), GPIO_FN(CTX1), GPIO_FN(CRX1), GPIO_FN(CTX0), GPIO_FN(CRX0), + GPIO_FN(CTX0_CTX1), GPIO_FN(CRX0_CRX1), + GPIO_FN(CTX0_CTX1_CTX2), GPIO_FN(CRX0_CRX1_CRX2), + GPIO_FN(CTX2_PJ21), + GPIO_FN(CRX2_PJ20), + GPIO_FN(CTX1_PJ23), + GPIO_FN(CRX1_PJ22), + GPIO_FN(CTX0_CTX1_PJ23), + GPIO_FN(CRX0_CRX1_PJ22), + GPIO_FN(CTX0_CTX1_CTX2_PJ21), + GPIO_FN(CRX0_CRX1_CRX2_PJ20), /* DMAC */ GPIO_FN(TEND0), --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/pfc-sh7734.c +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/pfc-sh7734.c @@ -1450,7 +1450,7 @@ GPIO_FN(ET0_ETXD2_A), GPIO_FN(EX_CS5), GPIO_FN(SD1_CMD_A), GPIO_FN(ATADIR), GPIO_FN(QSSL_B), GPIO_FN(ET0_ETXD3_A), - GPIO_FN(RD_WR), GPIO_FN(TCLK1_B), + GPIO_FN(RD_WR), GPIO_FN(TCLK0), GPIO_FN(CAN_CLK_B), GPIO_FN(ET0_ETXD4), GPIO_FN(EX_WAIT0), GPIO_FN(TCLK1_B), GPIO_FN(EX_WAIT1), GPIO_FN(SD1_DAT0_A), GPIO_FN(DREQ2), GPIO_FN(CAN1_TX_C), GPIO_FN(ET0_LINK_C), GPIO_FN(ET0_ETXD5_A), @@ -1949,7 +1949,7 @@ /* IP3_20 [1] */ FN_EX_WAIT0, FN_TCLK1_B, /* IP3_19_18 [2] */ - FN_RD_WR, FN_TCLK1_B, 0, 0, + FN_RD_WR, FN_TCLK0, FN_CAN_CLK_B, FN_ET0_ETXD4, /* IP3_17_15 [3] */ FN_EX_CS5, FN_SD1_CMD_A, FN_ATADIR, FN_QSSL_B, FN_ET0_ETXD3_A, 0, 0, 0, --- linux-oracle-5.4.0.orig/drivers/pinctrl/sh-pfc/sh_pfc.h +++ linux-oracle-5.4.0/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -422,12 +422,12 @@ /* * Describe a pinmux configuration in which a pin is physically multiplexed * with other pins. - * - ipsr: IPSR field (unused, for documentation purposes only) + * - ipsr: IPSR field * - fn: Function name * - psel: Physical multiplexing selector */ #define PINMUX_IPSR_PHYS(ipsr, fn, psel) \ - PINMUX_DATA(fn##_MARK, FN_##psel) + PINMUX_DATA(fn##_MARK, FN_##psel, FN_##ipsr) /* * Describe a pinmux configuration for a single-function pin with GPIO --- linux-oracle-5.4.0.orig/drivers/pinctrl/stm32/pinctrl-stm32.c +++ linux-oracle-5.4.0/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1153,7 +1153,7 @@ struct resource res; struct reset_control *rstc; int npins = STM32_GPIO_PINS_PER_BANK; - int bank_nr, err; + int bank_nr, err, i = 0; rstc = of_reset_control_get_exclusive(np, NULL); if (!IS_ERR(rstc)) @@ -1182,9 +1182,14 @@ of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label); - if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args)) { + if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, i, &args)) { bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK; bank->gpio_chip.base = args.args[1]; + + /* get the last defined gpio line (offset + nb of pins) */ + npins = args.args[0] + args.args[2]; + while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, ++i, &args)) + npins = max(npins, (int)(args.args[0] + args.args[2])); } else { bank_nr = pctl->nbanks; bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK; @@ -1210,15 +1215,17 @@ bank->bank_ioport_nr = bank_ioport_nr; spin_lock_init(&bank->lock); - /* create irq hierarchical domain */ - bank->fwnode = of_node_to_fwnode(np); + if (pctl->domain) { + /* create irq hierarchical domain */ + bank->fwnode = of_node_to_fwnode(np); - bank->domain = irq_domain_create_hierarchy(pctl->domain, 0, - STM32_GPIO_IRQ_LINE, bank->fwnode, - &stm32_gpio_domain_ops, bank); + bank->domain = irq_domain_create_hierarchy(pctl->domain, 0, STM32_GPIO_IRQ_LINE, + bank->fwnode, &stm32_gpio_domain_ops, + bank); - if (!bank->domain) - return -ENODEV; + if (!bank->domain) + return -ENODEV; + } err = gpiochip_add_data(&bank->gpio_chip, bank); if (err) { @@ -1243,6 +1250,7 @@ return ERR_PTR(-ENXIO); domain = irq_find_host(parent); + of_node_put(parent); if (!domain) /* domain not registered yet */ return ERR_PTR(-EPROBE_DEFER); @@ -1388,6 +1396,8 @@ pctl->domain = stm32_pctrl_get_irq_domain(np); if (IS_ERR(pctl->domain)) return PTR_ERR(pctl->domain); + if (!pctl->domain) + dev_warn(dev, "pinctrl without interrupt support\n"); /* hwspinlock is optional */ hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0); @@ -1549,8 +1559,8 @@ struct stm32_pinctrl_group *g = pctl->groups; int i; - for (i = g->pin; i < g->pin + pctl->ngroups; i++) - stm32_pinctrl_restore_gpio_regs(pctl, i); + for (i = 0; i < pctl->ngroups; i++, g++) + stm32_pinctrl_restore_gpio_regs(pctl, g->pin); return 0; } --- linux-oracle-5.4.0.orig/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c +++ linux-oracle-5.4.0/drivers/pinctrl/sunxi/pinctrl-sun50i-h6-r.c @@ -105,6 +105,7 @@ .npins = ARRAY_SIZE(sun50i_h6_r_pins), .pin_base = PL_BASE, .irq_banks = 2, + .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL, }; static int sun50i_h6_r_pinctrl_probe(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +++ linux-oracle-5.4.0/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c @@ -158,26 +158,26 @@ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand")), /* CE2 */ + SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand")), /* CE3 */ + SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), SUNXI_FUNCTION(0x0, "gpio_in"), --- linux-oracle-5.4.0.orig/drivers/pinctrl/sunxi/pinctrl-suniv-f1c100s.c +++ linux-oracle-5.4.0/drivers/pinctrl/sunxi/pinctrl-suniv-f1c100s.c @@ -204,7 +204,7 @@ SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), SUNXI_FUNCTION(0x2, "lcd"), /* D20 */ - SUNXI_FUNCTION(0x3, "lvds1"), /* RX */ + SUNXI_FUNCTION(0x3, "uart2"), /* RX */ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 14)), SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 15), SUNXI_FUNCTION(0x0, "gpio_in"), --- linux-oracle-5.4.0.orig/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ linux-oracle-5.4.0/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -536,6 +536,8 @@ struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); int i; + pin -= pctl->desc->pin_base; + for (i = 0; i < num_configs; i++) { enum pin_config_param param; unsigned long flags; @@ -614,7 +616,7 @@ unsigned pin, struct regulator *supply) { - unsigned short bank = pin / PINS_PER_BANK; + unsigned short bank; unsigned long flags; u32 val, reg; int uV; @@ -630,6 +632,9 @@ if (uV == 0) return 0; + pin -= pctl->desc->pin_base; + bank = pin / PINS_PER_BANK; + switch (pctl->desc->io_bias_cfg_variant) { case BIAS_VOLTAGE_GRP_CONFIG: /* @@ -647,8 +652,6 @@ else val = 0xD; /* 3.3V */ - pin -= pctl->desc->pin_base; - reg = readl(pctl->membase + sunxi_grp_config_reg(pin)); reg &= ~IO_BIAS_MASK; writel(reg | val, pctl->membase + sunxi_grp_config_reg(pin)); @@ -1130,20 +1133,22 @@ if (bank == pctl->desc->irq_banks) return; + chained_irq_enter(chip, desc); + reg = sunxi_irq_status_reg_from_bank(pctl->desc, bank); val = readl(pctl->membase + reg); if (val) { int irqoffset; - chained_irq_enter(chip, desc); for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) { int pin_irq = irq_find_mapping(pctl->domain, bank * IRQ_PER_BANK + irqoffset); generic_handle_irq(pin_irq); } - chained_irq_exit(chip, desc); } + + chained_irq_exit(chip, desc); } static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl, --- linux-oracle-5.4.0.orig/drivers/pinctrl/tegra/pinctrl-tegra.c +++ linux-oracle-5.4.0/drivers/pinctrl/tegra/pinctrl-tegra.c @@ -685,8 +685,8 @@ } const struct dev_pm_ops tegra_pinctrl_pm = { - .suspend = &tegra_pinctrl_suspend, - .resume = &tegra_pinctrl_resume + .suspend_noirq = &tegra_pinctrl_suspend, + .resume_noirq = &tegra_pinctrl_resume }; static bool gpio_node_has_range(const char *compatible) --- linux-oracle-5.4.0.orig/drivers/pinctrl/ti/pinctrl-ti-iodelay.c +++ linux-oracle-5.4.0/drivers/pinctrl/ti/pinctrl-ti-iodelay.c @@ -496,7 +496,7 @@ return -EINVAL; rows = pinctrl_count_index_with_args(np, name); - if (rows == -EINVAL) + if (rows < 0) return rows; *map = devm_kzalloc(iod->dev, sizeof(**map), GFP_KERNEL); @@ -881,7 +881,7 @@ iod->desc.name = dev_name(dev); iod->desc.owner = THIS_MODULE; - ret = pinctrl_register_and_init(&iod->desc, dev, iod, &iod->pctl); + ret = devm_pinctrl_register_and_init(dev, &iod->desc, iod, &iod->pctl); if (ret) { dev_err(dev, "Failed to register pinctrl\n"); goto exit_out; @@ -889,7 +889,11 @@ platform_set_drvdata(pdev, iod); - return pinctrl_enable(iod->pctl); + ret = pinctrl_enable(iod->pctl); + if (ret) + goto exit_out; + + return 0; exit_out: of_node_put(np); @@ -906,12 +910,6 @@ { struct ti_iodelay_device *iod = platform_get_drvdata(pdev); - if (!iod) - return 0; - - if (iod->pctl) - pinctrl_unregister(iod->pctl); - ti_iodelay_pinconf_deinit_dev(iod); /* Expect other allocations to be freed by devm */ --- linux-oracle-5.4.0.orig/drivers/platform/chrome/chromeos_laptop.c +++ linux-oracle-5.4.0/drivers/platform/chrome/chromeos_laptop.c @@ -716,6 +716,7 @@ chromeos_laptop_prepare_i2c_peripherals(struct chromeos_laptop *cros_laptop, const struct chromeos_laptop *src) { + struct i2c_peripheral *i2c_peripherals; struct i2c_peripheral *i2c_dev; struct i2c_board_info *info; int i; @@ -724,17 +725,15 @@ if (!src->num_i2c_peripherals) return 0; - cros_laptop->i2c_peripherals = kmemdup(src->i2c_peripherals, - src->num_i2c_peripherals * - sizeof(*src->i2c_peripherals), - GFP_KERNEL); - if (!cros_laptop->i2c_peripherals) + i2c_peripherals = kmemdup(src->i2c_peripherals, + src->num_i2c_peripherals * + sizeof(*src->i2c_peripherals), + GFP_KERNEL); + if (!i2c_peripherals) return -ENOMEM; - cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; - - for (i = 0; i < cros_laptop->num_i2c_peripherals; i++) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + for (i = 0; i < src->num_i2c_peripherals; i++) { + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; error = chromeos_laptop_setup_irq(i2c_dev); @@ -752,16 +751,19 @@ } } + cros_laptop->i2c_peripherals = i2c_peripherals; + cros_laptop->num_i2c_peripherals = src->num_i2c_peripherals; + return 0; err_out: while (--i >= 0) { - i2c_dev = &cros_laptop->i2c_peripherals[i]; + i2c_dev = &i2c_peripherals[i]; info = &i2c_dev->board_info; if (info->properties) property_entries_free(info->properties); } - kfree(cros_laptop->i2c_peripherals); + kfree(i2c_peripherals); return error; } --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_chardev.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_chardev.c @@ -285,7 +285,7 @@ u_cmd.insize > EC_MAX_MSG_BYTES) return -EINVAL; - s_cmd = kmalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), + s_cmd = kzalloc(sizeof(*s_cmd) + max(u_cmd.outsize, u_cmd.insize), GFP_KERNEL); if (!s_cmd) return -ENOMEM; @@ -328,6 +328,9 @@ if (copy_from_user(&s_mem, arg, sizeof(s_mem))) return -EFAULT; + if (s_mem.bytes > sizeof(s_mem.buffer)) + return -EINVAL; + num = ec_dev->cmd_readmem(ec_dev, s_mem.offset, s_mem.bytes, s_mem.buffer); if (num <= 0) --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_debugfs.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_debugfs.c @@ -26,6 +26,9 @@ #define CIRC_ADD(idx, size, value) (((idx) + (value)) & ((size) - 1)) +/* waitqueue for log readers */ +static DECLARE_WAIT_QUEUE_HEAD(cros_ec_debugfs_log_wq); + /** * struct cros_ec_debugfs - EC debugging information. * @@ -34,7 +37,6 @@ * @log_buffer: circular buffer for console log information * @read_msg: preallocated EC command and buffer to read console log * @log_mutex: mutex to protect circular buffer - * @log_wq: waitqueue for log readers * @log_poll_work: recurring task to poll EC for new console log data * @panicinfo_blob: panicinfo debugfs blob */ @@ -45,7 +47,6 @@ struct circ_buf log_buffer; struct cros_ec_command *read_msg; struct mutex log_mutex; - wait_queue_head_t log_wq; struct delayed_work log_poll_work; /* EC panicinfo */ struct debugfs_blob_wrapper panicinfo_blob; @@ -108,7 +109,7 @@ buf_space--; } - wake_up(&debug_info->log_wq); + wake_up(&cros_ec_debugfs_log_wq); } mutex_unlock(&debug_info->log_mutex); @@ -142,7 +143,7 @@ mutex_unlock(&debug_info->log_mutex); - ret = wait_event_interruptible(debug_info->log_wq, + ret = wait_event_interruptible(cros_ec_debugfs_log_wq, CIRC_CNT(cb->head, cb->tail, LOG_SIZE)); if (ret < 0) return ret; @@ -174,7 +175,7 @@ struct cros_ec_debugfs *debug_info = file->private_data; __poll_t mask = 0; - poll_wait(file, &debug_info->log_wq, wait); + poll_wait(file, &cros_ec_debugfs_log_wq, wait); mutex_lock(&debug_info->log_mutex); if (CIRC_CNT(debug_info->log_buffer.head, @@ -307,6 +308,7 @@ if (!msg) return 0; + msg->version = 1; msg->command = EC_CMD_GET_CMD_VERSIONS + ec->cmd_offset; msg->outsize = sizeof(*params); msg->insize = sizeof(*response); @@ -359,7 +361,6 @@ debug_info->log_buffer.tail = 0; mutex_init(&debug_info->log_mutex); - init_waitqueue_head(&debug_info->log_wq); debugfs_create_file("console_log", S_IFREG | 0444, debug_info->dir, debug_info, &cros_ec_console_log_fops); --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_ishtp.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_ishtp.c @@ -645,8 +645,10 @@ /* Register croc_ec_dev mfd */ rv = cros_ec_dev_init(client_data); - if (rv) + if (rv) { + down_write(&init_lock); goto end_cros_ec_dev_init_error; + } return 0; --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_proto.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_proto.c @@ -213,6 +213,15 @@ msg->insize = sizeof(struct ec_response_get_protocol_info); ret = send_command(ec_dev, msg); + /* + * Send command once again when timeout occurred. + * Fingerprint MCU (FPMCU) is restarted during system boot which + * introduces small window in which FPMCU won't respond for any + * messages sent by kernel. There is no need to wait before next + * attempt because we waited at least EC_MSG_DEADLINE_MS. + */ + if (ret == -ETIMEDOUT) + ret = send_command(ec_dev, msg); if (ret < 0) { dev_dbg(ec_dev->dev, --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_rpmsg.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_rpmsg.c @@ -42,6 +42,8 @@ struct completion xfer_ack; struct work_struct host_event_work; struct rpmsg_endpoint *ept; + bool has_pending_host_event; + bool probe_done; }; /** @@ -186,7 +188,14 @@ memcpy(ec_dev->din, resp->data, len); complete(&ec_rpmsg->xfer_ack); } else if (resp->type == HOST_EVENT_MARK) { - schedule_work(&ec_rpmsg->host_event_work); + /* + * If the host event is sent before cros_ec_register is + * finished, queue the host event. + */ + if (ec_rpmsg->probe_done) + schedule_work(&ec_rpmsg->host_event_work); + else + ec_rpmsg->has_pending_host_event = true; } else { dev_warn(ec_dev->dev, "rpmsg received invalid type = %d", resp->type); @@ -249,6 +258,11 @@ return ret; } + ec_rpmsg->probe_done = true; + + if (ec_rpmsg->has_pending_host_event) + schedule_work(&ec_rpmsg->host_event_work); + return 0; } --- linux-oracle-5.4.0.orig/drivers/platform/chrome/cros_ec_spi.c +++ linux-oracle-5.4.0/drivers/platform/chrome/cros_ec_spi.c @@ -739,7 +739,6 @@ int err; spi->bits_per_word = 8; - spi->mode = SPI_MODE_0; spi->rt = true; err = spi_setup(spi); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/platform/chrome/wilco_ec/telemetry.c +++ linux-oracle-5.4.0/drivers/platform/chrome/wilco_ec/telemetry.c @@ -406,8 +406,8 @@ struct telem_device_data *dev_data = platform_get_drvdata(pdev); cdev_device_del(&dev_data->cdev, &dev_data->dev); - put_device(&dev_data->dev); ida_simple_remove(&telem_ida, MINOR(dev_data->dev.devt)); + put_device(&dev_data->dev); return 0; } --- linux-oracle-5.4.0.orig/drivers/platform/mellanox/mlxbf-tmfifo.c +++ linux-oracle-5.4.0/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -56,6 +56,7 @@ * @vq: pointer to the virtio virtqueue * @desc: current descriptor of the pending packet * @desc_head: head descriptor of the pending packet + * @drop_desc: dummy desc for packet dropping * @cur_len: processed length of the current descriptor * @rem_len: remaining length of the pending packet * @pkt_len: total length of the pending packet @@ -72,6 +73,7 @@ struct virtqueue *vq; struct vring_desc *desc; struct vring_desc *desc_head; + struct vring_desc drop_desc; int cur_len; int rem_len; u32 pkt_len; @@ -83,6 +85,14 @@ struct mlxbf_tmfifo *fifo; }; +/* Check whether vring is in drop mode. */ +#define IS_VRING_DROP(_r) ({ \ + typeof(_r) (r) = (_r); \ + (r->desc_head == &r->drop_desc ? true : false); }) + +/* A stub length to drop maximum length packet. */ +#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0) + /* Interrupt types. */ enum { MLXBF_TM_RX_LWM_IRQ, @@ -149,7 +159,7 @@ * @work: work struct for deferred process * @timer: background timer * @vring: Tx/Rx ring - * @spin_lock: spin lock + * @spin_lock: Tx/Rx spin lock * @is_ready: ready flag */ struct mlxbf_tmfifo { @@ -164,7 +174,7 @@ struct work_struct work; struct timer_list timer; struct mlxbf_tmfifo_vring *vring[2]; - spinlock_t spin_lock; /* spin lock */ + spinlock_t spin_lock[2]; /* spin lock */ bool is_ready; }; @@ -195,7 +205,7 @@ static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr"; /* Maximum L2 header length. */ -#define MLXBF_TMFIFO_NET_L2_OVERHEAD 36 +#define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN) /* Supported virtio-net features. */ #define MLXBF_TMFIFO_NET_FEATURES \ @@ -243,6 +253,7 @@ vring->align = SMP_CACHE_BYTES; vring->index = i; vring->vdev_id = tm_vdev->vdev.id.device; + vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; dev = &tm_vdev->vdev.dev; size = vring_size(vring->num, vring->align); @@ -294,6 +305,9 @@ if (vring->next_avail == virtio16_to_cpu(vdev, vr->avail->idx)) return NULL; + /* Make sure 'avail->idx' is visible already. */ + virtio_rmb(false); + idx = vring->next_avail % vr->num; head = virtio16_to_cpu(vdev, vr->avail->ring[idx]); if (WARN_ON(head >= vr->num)) @@ -322,7 +336,7 @@ * done or not. Add a memory barrier here to make sure the update above * completes before updating the idx. */ - mb(); + virtio_mb(false); vr->used->idx = cpu_to_virtio16(vdev, vr_idx + 1); } @@ -345,7 +359,7 @@ return len; } -static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring) +static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring) { struct vring_desc *desc_head; u32 len = 0; @@ -525,7 +539,7 @@ writeq(*(u64 *)&hdr, fifo->tx_base + MLXBF_TMFIFO_TX_DATA); /* Use spin-lock to protect the 'cons->tx_buf'. */ - spin_lock_irqsave(&fifo->spin_lock, flags); + spin_lock_irqsave(&fifo->spin_lock[0], flags); while (size > 0) { addr = cons->tx_buf.buf + cons->tx_buf.tail; @@ -552,7 +566,7 @@ } } - spin_unlock_irqrestore(&fifo->spin_lock, flags); + spin_unlock_irqrestore(&fifo->spin_lock[0], flags); } /* Rx/Tx one word in the descriptor buffer. */ @@ -574,19 +588,26 @@ if (vring->cur_len + sizeof(u64) <= len) { /* The whole word. */ - if (is_rx) - memcpy(addr + vring->cur_len, &data, sizeof(u64)); - else - memcpy(&data, addr + vring->cur_len, sizeof(u64)); + if (is_rx) { + if (!IS_VRING_DROP(vring)) + memcpy(addr + vring->cur_len, &data, + sizeof(u64)); + } else { + memcpy(&data, addr + vring->cur_len, + sizeof(u64)); + } vring->cur_len += sizeof(u64); } else { /* Leftover bytes. */ - if (is_rx) - memcpy(addr + vring->cur_len, &data, - len - vring->cur_len); - else + if (is_rx) { + if (!IS_VRING_DROP(vring)) + memcpy(addr + vring->cur_len, &data, + len - vring->cur_len); + } else { + data = 0; memcpy(&data, addr + vring->cur_len, len - vring->cur_len); + } vring->cur_len = len; } @@ -603,13 +624,14 @@ * flag is set. */ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, - struct vring_desc *desc, + struct vring_desc **desc, bool is_rx, bool *vring_change) { struct mlxbf_tmfifo *fifo = vring->fifo; struct virtio_net_config *config; struct mlxbf_tmfifo_msg_hdr hdr; int vdev_id, hdr_len; + bool drop_rx = false; /* Read/Write packet header. */ if (is_rx) { @@ -625,9 +647,12 @@ vdev_id = VIRTIO_ID_NET; hdr_len = sizeof(struct virtio_net_hdr); config = &fifo->vdev[vdev_id]->config.net; - if (ntohs(hdr.len) > config->mtu + - MLXBF_TMFIFO_NET_L2_OVERHEAD) - return; + /* A legacy-only interface for now. */ + if (ntohs(hdr.len) > + __virtio16_to_cpu(virtio_legacy_is_little_endian(), + config->mtu) + + MLXBF_TMFIFO_NET_L2_OVERHEAD) + drop_rx = true; } else { vdev_id = VIRTIO_ID_CONSOLE; hdr_len = 0; @@ -642,16 +667,25 @@ if (!tm_dev2) return; - vring->desc = desc; + vring->desc = *desc; vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX]; *vring_change = true; } + + if (drop_rx && !IS_VRING_DROP(vring)) { + if (vring->desc_head) + mlxbf_tmfifo_release_pkt(vring); + *desc = &vring->drop_desc; + vring->desc_head = *desc; + vring->desc = *desc; + } + vring->pkt_len = ntohs(hdr.len) + hdr_len; } else { /* Network virtio has an extra header. */ hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ? sizeof(struct virtio_net_hdr) : 0; - vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc); + vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc); hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; hdr.len = htons(vring->pkt_len - hdr_len); @@ -684,15 +718,23 @@ /* Get the descriptor of the next packet. */ if (!vring->desc) { desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx); - if (!desc) - return false; + if (!desc) { + /* Drop next Rx packet to avoid stuck. */ + if (is_rx) { + desc = &vring->drop_desc; + vring->desc_head = desc; + vring->desc = desc; + } else { + return false; + } + } } else { desc = vring->desc; } /* Beginning of a packet. Start to Rx/Tx packet header. */ if (vring->pkt_len == 0) { - mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change); + mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change); (*avail)--; /* Return if new packet is for another ring. */ @@ -718,22 +760,35 @@ vring->rem_len -= len; /* Get the next desc on the chain. */ - if (vring->rem_len > 0 && + if (!IS_VRING_DROP(vring) && vring->rem_len > 0 && (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) { idx = virtio16_to_cpu(vdev, desc->next); desc = &vr->desc[idx]; goto mlxbf_tmfifo_desc_done; } - /* Done and release the pending packet. */ - mlxbf_tmfifo_release_pending_pkt(vring); + /* Done and release the packet. */ desc = NULL; fifo->vring[is_rx] = NULL; + if (!IS_VRING_DROP(vring)) { + mlxbf_tmfifo_release_pkt(vring); + } else { + vring->pkt_len = 0; + vring->desc_head = NULL; + vring->desc = NULL; + return false; + } + + /* + * Make sure the load/store are in order before + * returning back to virtio. + */ + virtio_mb(false); /* Notify upper layer that packet is done. */ - spin_lock_irqsave(&fifo->spin_lock, flags); + spin_lock_irqsave(&fifo->spin_lock[is_rx], flags); vring_interrupt(0, vring->vq); - spin_unlock_irqrestore(&fifo->spin_lock, flags); + spin_unlock_irqrestore(&fifo->spin_lock[is_rx], flags); } mlxbf_tmfifo_desc_done: @@ -852,10 +907,11 @@ * worker handler. */ if (vring->vdev_id == VIRTIO_ID_CONSOLE) { - spin_lock_irqsave(&fifo->spin_lock, flags); + spin_lock_irqsave(&fifo->spin_lock[0], flags); tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE]; mlxbf_tmfifo_console_output(tm_vdev, vring); - spin_unlock_irqrestore(&fifo->spin_lock, flags); + spin_unlock_irqrestore(&fifo->spin_lock[0], flags); + set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events)) { return true; @@ -901,7 +957,7 @@ /* Release the pending packet. */ if (vring->desc) - mlxbf_tmfifo_release_pending_pkt(vring); + mlxbf_tmfifo_release_pkt(vring); vq = vring->vq; if (vq) { vring->vq = NULL; @@ -1189,7 +1245,8 @@ if (!fifo) return -ENOMEM; - spin_lock_init(&fifo->spin_lock); + spin_lock_init(&fifo->spin_lock[0]); + spin_lock_init(&fifo->spin_lock[1]); INIT_WORK(&fifo->work, mlxbf_tmfifo_work_handler); mutex_init(&fifo->lock); @@ -1230,8 +1287,12 @@ /* Create the network vdev. */ memset(&net_config, 0, sizeof(net_config)); - net_config.mtu = ETH_DATA_LEN; - net_config.status = VIRTIO_NET_S_LINK_UP; + + /* A legacy-only interface for now. */ + net_config.mtu = __cpu_to_virtio16(virtio_legacy_is_little_endian(), + ETH_DATA_LEN); + net_config.status = __cpu_to_virtio16(virtio_legacy_is_little_endian(), + VIRTIO_NET_S_LINK_UP); mlxbf_tmfifo_get_cfg_mac(net_config.mac); rc = mlxbf_tmfifo_create_vdev(dev, fifo, VIRTIO_ID_NET, MLXBF_TMFIFO_NET_FEATURES, &net_config, --- linux-oracle-5.4.0.orig/drivers/platform/mellanox/mlxreg-io.c +++ linux-oracle-5.4.0/drivers/platform/mellanox/mlxreg-io.c @@ -123,7 +123,7 @@ return -EINVAL; /* Convert buffer to input value. */ - ret = kstrtou32(buf, len, &input_val); + ret = kstrtou32(buf, 0, &input_val); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/platform/mips/cpu_hwmon.c +++ linux-oracle-5.4.0/drivers/platform/mips/cpu_hwmon.c @@ -161,11 +161,14 @@ cpu_hwmon_dev = hwmon_device_register(NULL); if (IS_ERR(cpu_hwmon_dev)) { - ret = -ENOMEM; + ret = PTR_ERR(cpu_hwmon_dev); pr_err("hwmon_device_register fail!\n"); goto fail_hwmon_device_register; } + if (!csr_temp_enable && !loongson_chiptemp[0]) + return -ENODEV; + nr_packages = loongson_sysconf.nr_cpus / loongson_sysconf.cores_per_package; --- linux-oracle-5.4.0.orig/drivers/platform/olpc/olpc-ec.c +++ linux-oracle-5.4.0/drivers/platform/olpc/olpc-ec.c @@ -265,7 +265,7 @@ int i, m; unsigned char ec_cmd[EC_MAX_CMD_ARGS]; unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; - char cmdbuf[64]; + char cmdbuf[64] = ""; int ec_cmd_bytes; mutex_lock(&ec_dbgfs_lock); @@ -426,11 +426,8 @@ /* get the EC revision */ err = olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, &ec->version, 1); - if (err) { - ec_priv = NULL; - kfree(ec); - return err; - } + if (err) + goto error; config.dev = pdev->dev.parent; config.driver_data = ec; @@ -439,11 +436,17 @@ &config); if (IS_ERR(ec->dcon_rdev)) { dev_err(&pdev->dev, "failed to register DCON regulator\n"); - return PTR_ERR(ec->dcon_rdev); + err = PTR_ERR(ec->dcon_rdev); + goto error; } ec->dbgfs_dir = olpc_ec_setup_debugfs(); + return 0; + +error: + ec_priv = NULL; + kfree(ec); return err; } --- linux-oracle-5.4.0.orig/drivers/platform/x86/Kconfig +++ linux-oracle-5.4.0/drivers/platform/x86/Kconfig @@ -261,6 +261,20 @@ image for the image update to take effect. See for more details on the driver. +config DELL_UART_BACKLIGHT + tristate "Dell AIO UART Backlight driver" + depends on SERIAL_8250 + depends on ACPI + ---help--- + Say Y here if you want to support Dell AIO UART backlight interface. + The Dell AIO machines released after 2017 come with a UART interface + to communicate with the backlight scalar board. This driver creates + a standard backlight interface and talks to the scalar board through + UART to adjust the AIO screen brightness. + + To compile this driver as a module, choose M here: the module will + be called dell_uart_backlight. + config FUJITSU_LAPTOP tristate "Fujitsu Laptop Extras" @@ -269,6 +283,7 @@ depends on BACKLIGHT_CLASS_DEVICE depends on ACPI_VIDEO || ACPI_VIDEO = n select INPUT_SPARSEKMAP + select NEW_LEDS select LEDS_CLASS ---help--- This is a driver for laptops built by Fujitsu: @@ -806,7 +821,6 @@ tristate "PEAQ 2-in-1 WMI hotkey driver" depends on ACPI_WMI depends on INPUT - select INPUT_POLLDEV help Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s. --- linux-oracle-5.4.0.orig/drivers/platform/x86/Makefile +++ linux-oracle-5.4.0/drivers/platform/x86/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o obj-$(CONFIG_DELL_RBU) += dell_rbu.o +obj-$(CONFIG_DELL_UART_BACKLIGHT) += dell-uart-backlight.o obj-$(CONFIG_ACER_WMI) += acer-wmi.o obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o obj-$(CONFIG_ACERHDF) += acerhdf.o --- linux-oracle-5.4.0.orig/drivers/platform/x86/acer-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/acer-wmi.c @@ -30,6 +30,7 @@ #include #include +ACPI_MODULE_NAME(KBUILD_MODNAME); MODULE_AUTHOR("Carlos Corbacho"); MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); MODULE_LICENSE("GPL"); @@ -80,7 +81,7 @@ enum acer_wmi_event_ids { WMID_HOTKEY_EVENT = 0x1, - WMID_ACCEL_EVENT = 0x5, + WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, }; static const struct key_entry acer_wmi_keymap[] __initconst = { @@ -92,6 +93,7 @@ {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ {KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */ {KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */ + {KE_KEY, 0x27, {KEY_HELP} }, {KE_KEY, 0x29, {KEY_PROG3} }, /* P_Key for TM8372 */ {KE_IGNORE, 0x41, {KEY_MUTE} }, {KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} }, @@ -105,12 +107,19 @@ {KE_IGNORE, 0x48, {KEY_VOLUMEUP} }, {KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} }, {KE_IGNORE, 0x4a, {KEY_VOLUMEDOWN} }, - {KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} }, + /* + * 0x61 is KEY_SWITCHVIDEOMODE. Usually this is a duplicate input event + * with the "Video Bus" input device events. But sometimes it is not + * a dup. Map it to KEY_UNKNOWN instead of using KE_IGNORE so that + * udev/hwdb can override it on systems where it is not a dup. + */ + {KE_KEY, 0x61, {KEY_UNKNOWN} }, {KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} }, {KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} }, {KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */ {KE_IGNORE, 0x81, {KEY_SLEEP} }, {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad Toggle */ + {KE_IGNORE, 0x84, {KEY_KBDILLUMTOGGLE} }, /* Automatic Keyboard background light toggle */ {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} }, {KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} }, @@ -127,7 +136,9 @@ u8 function; u8 key_num; u16 device_state; - u32 reserved; + u16 reserved1; + u8 kbd_dock_state; + u8 reserved2; } __attribute__((packed)); /* @@ -205,14 +216,13 @@ /* * Interface capability flags */ -#define ACER_CAP_MAILLED (1<<0) -#define ACER_CAP_WIRELESS (1<<1) -#define ACER_CAP_BLUETOOTH (1<<2) -#define ACER_CAP_BRIGHTNESS (1<<3) -#define ACER_CAP_THREEG (1<<4) -#define ACER_CAP_ACCEL (1<<5) -#define ACER_CAP_RFBTN (1<<6) -#define ACER_CAP_ANY (0xFFFFFFFF) +#define ACER_CAP_MAILLED BIT(0) +#define ACER_CAP_WIRELESS BIT(1) +#define ACER_CAP_BLUETOOTH BIT(2) +#define ACER_CAP_BRIGHTNESS BIT(3) +#define ACER_CAP_THREEG BIT(4) +#define ACER_CAP_SET_FUNCTION_MODE BIT(5) +#define ACER_CAP_KBD_DOCK BIT(6) /* * Interface type flags @@ -235,6 +245,7 @@ static int brightness = -1; static int threeg = -1; static int force_series; +static int force_caps = -1; static bool ec_raw_mode; static bool has_type_aa; static u16 commun_func_bitmap; @@ -244,11 +255,13 @@ module_param(brightness, int, 0444); module_param(threeg, int, 0444); module_param(force_series, int, 0444); +module_param(force_caps, int, 0444); module_param(ec_raw_mode, bool, 0444); MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); MODULE_PARM_DESC(force_series, "Force a different laptop series"); +MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value"); MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); struct acer_data { @@ -318,6 +331,15 @@ return 1; } +static int __init set_force_caps(const struct dmi_system_id *dmi) +{ + if (force_caps == -1) { + force_caps = (uintptr_t)dmi->driver_data; + pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps); + } + return 1; +} + static struct quirk_entry quirk_unknown = { }; @@ -496,6 +518,42 @@ }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = set_force_caps, + .ident = "Acer Aspire Switch 10E SW3-016", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, + { + .callback = set_force_caps, + .ident = "Acer Aspire Switch 10 SW5-012", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, + { + .callback = set_force_caps, + .ident = "Acer Aspire Switch V 10 SW5-017", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, + { + .callback = set_force_caps, + .ident = "Acer One 10 (S1003)", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, {} }; @@ -1252,10 +1310,8 @@ interface->capability |= ACER_CAP_THREEG; if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) interface->capability |= ACER_CAP_BLUETOOTH; - if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { - interface->capability |= ACER_CAP_RFBTN; + if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; - } commun_fn_key_number = type_aa->commun_fn_key_number; } @@ -1519,7 +1575,7 @@ struct acpi_buffer output; union acpi_object out_obj[5]; - if (!has_cap(ACER_CAP_ACCEL)) + if (!acer_wmi_accel_dev) return -1; output.length = sizeof(out_obj); @@ -1543,6 +1599,71 @@ } /* + * Switch series keyboard dock status + */ +static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state) +{ + switch (kbd_dock_state) { + case 0x01: /* Docked, traditional clamshell laptop mode */ + return 0; + case 0x04: /* Stand-alone tablet */ + case 0x40: /* Docked, tent mode, keyboard not usable */ + return 1; + default: + pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state); + } + + return 0; +} + +static void acer_kbd_dock_get_initial_state(void) +{ + u8 *output, input[8] = { 0x05, 0x00, }; + struct acpi_buffer input_buf = { sizeof(input), input }; + struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + int sw_tablet_mode; + + status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status")); + return; + } + + obj = output_buf.pointer; + if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { + pr_err("Unexpected output format getting keyboard-dock initial status\n"); + goto out_free_obj; + } + + output = obj->buffer.pointer; + if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) { + pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n", + output[0], output[3]); + goto out_free_obj; + } + + sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]); + input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); + +out_free_obj: + kfree(obj); +} + +static void acer_kbd_dock_event(const struct event_return_value *event) +{ + int sw_tablet_mode; + + if (!has_cap(ACER_CAP_KBD_DOCK)) + return; + + sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state); + input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); + input_sync(acer_wmi_input_dev); +} + +/* * Rfkill devices */ static void acer_rfkill_update(struct work_struct *ignored); @@ -1769,8 +1890,9 @@ sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); } break; - case WMID_ACCEL_EVENT: + case WMID_ACCEL_OR_KBD_DOCK_EVENT: acer_gsensor_event(); + acer_kbd_dock_event(&return_value); break; default: pr_warn("Unknown function number - %d - %d\n", @@ -1893,8 +2015,6 @@ gsensor_handle = acpi_device_handle(adev); acpi_dev_put(adev); - interface->capability |= ACER_CAP_ACCEL; - acer_wmi_accel_dev = input_allocate_device(); if (!acer_wmi_accel_dev) return -ENOMEM; @@ -1920,11 +2040,6 @@ return err; } -static void acer_wmi_accel_destroy(void) -{ - input_unregister_device(acer_wmi_accel_dev); -} - static int __init acer_wmi_input_setup(void) { acpi_status status; @@ -1942,6 +2057,9 @@ if (err) goto err_free_dev; + if (has_cap(ACER_CAP_KBD_DOCK)) + input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE); + status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, acer_wmi_notify, NULL); if (ACPI_FAILURE(status)) { @@ -1949,6 +2067,9 @@ goto err_free_dev; } + if (has_cap(ACER_CAP_KBD_DOCK)) + acer_kbd_dock_get_initial_state(); + err = input_register_device(acer_wmi_input_dev); if (err) goto err_uninstall_notifier; @@ -2079,7 +2200,7 @@ if (has_cap(ACER_CAP_BRIGHTNESS)) set_u32(data->brightness, ACER_CAP_BRIGHTNESS); - if (has_cap(ACER_CAP_ACCEL)) + if (acer_wmi_accel_dev) acer_gsensor_init(); return 0; @@ -2180,7 +2301,7 @@ } /* WMID always provides brightness methods */ interface->capability |= ACER_CAP_BRIGHTNESS; - } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { + } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) { pr_err("No WMID device detection method found\n"); return -ENODEV; } @@ -2210,7 +2331,14 @@ if (acpi_video_get_backlight_type() != acpi_backlight_vendor) interface->capability &= ~ACER_CAP_BRIGHTNESS; - if (wmi_has_guid(WMID_GUID3)) { + if (wmi_has_guid(WMID_GUID3)) + interface->capability |= ACER_CAP_SET_FUNCTION_MODE; + + if (force_caps != -1) + interface->capability = force_caps; + + if (wmi_has_guid(WMID_GUID3) && + (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) { if (ACPI_FAILURE(acer_wmi_enable_rf_button())) pr_warn("Cannot enable RF Button Driver\n"); @@ -2269,8 +2397,8 @@ error_platform_register: if (wmi_has_guid(ACERWMID_EVENT_GUID)) acer_wmi_input_destroy(); - if (has_cap(ACER_CAP_ACCEL)) - acer_wmi_accel_destroy(); + if (acer_wmi_accel_dev) + input_unregister_device(acer_wmi_accel_dev); return err; } @@ -2280,8 +2408,8 @@ if (wmi_has_guid(ACERWMID_EVENT_GUID)) acer_wmi_input_destroy(); - if (has_cap(ACER_CAP_ACCEL)) - acer_wmi_accel_destroy(); + if (acer_wmi_accel_dev) + input_unregister_device(acer_wmi_accel_dev); remove_debugfs(); platform_device_unregister(acer_platform_device); --- linux-oracle-5.4.0.orig/drivers/platform/x86/apple-gmux.c +++ linux-oracle-5.4.0/drivers/platform/x86/apple-gmux.c @@ -625,7 +625,7 @@ } gmux_data->iostart = res->start; - gmux_data->iolen = res->end - res->start; + gmux_data->iolen = resource_size(res); if (gmux_data->iolen < GMUX_MIN_IO_LEN) { pr_err("gmux I/O region too small (%lu < %u)\n", --- linux-oracle-5.4.0.orig/drivers/platform/x86/asus-nb-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/asus-nb-wmi.c @@ -110,6 +110,16 @@ .wmi_force_als_set = true, }; +static struct quirk_entry quirk_asus_ga401i = { + .wmi_backlight_power = true, + .wmi_backlight_set_devstate = true, +}; + +static struct quirk_entry quirk_asus_ga502i = { + .wmi_backlight_power = true, + .wmi_backlight_set_devstate = true, +}; + static int dmi_matched(const struct dmi_system_id *dmi) { pr_info("Identified laptop model '%s'\n", dmi->ident); @@ -411,6 +421,78 @@ }, .driver_data = &quirk_asus_forceals, }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA401IH", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"), + }, + .driver_data = &quirk_asus_ga401i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA401II", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"), + }, + .driver_data = &quirk_asus_ga401i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA401IU", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"), + }, + .driver_data = &quirk_asus_ga401i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA401IV", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"), + }, + .driver_data = &quirk_asus_ga401i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA401IVC", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"), + }, + .driver_data = &quirk_asus_ga401i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA502II", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"), + }, + .driver_data = &quirk_asus_ga502i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA502IU", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"), + }, + .driver_data = &quirk_asus_ga502i, + }, + { + .callback = dmi_matched, + .ident = "ASUSTeK COMPUTER INC. GA502IV", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"), + }, + .driver_data = &quirk_asus_ga502i, + }, {}, }; @@ -446,6 +528,7 @@ { KE_KEY, 0x30, { KEY_VOLUMEUP } }, { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, { KE_KEY, 0x32, { KEY_MUTE } }, + { KE_KEY, 0x33, { KEY_SCREENLOCK } }, { KE_KEY, 0x35, { KEY_SCREENLOCK } }, { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, { KE_KEY, 0x41, { KEY_NEXTSONG } }, @@ -472,6 +555,7 @@ { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, { KE_IGNORE, 0x6E, }, /* Low Battery notification */ { KE_KEY, 0x7a, { KEY_ALS_TOGGLE } }, /* Ambient Light Sensor Toggle */ + { KE_IGNORE, 0x7B, }, /* Charger connect/disconnect notification */ { KE_KEY, 0x7c, { KEY_MICMUTE } }, { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, /* Bluetooth Enable */ { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, /* Bluetooth Disable */ @@ -497,9 +581,11 @@ { KE_KEY, 0xA6, { KEY_SWITCHVIDEOMODE } }, /* SDSP CRT + TV + HDMI */ { KE_KEY, 0xA7, { KEY_SWITCHVIDEOMODE } }, /* SDSP LCD + CRT + TV + HDMI */ { KE_KEY, 0xB5, { KEY_CALC } }, + { KE_IGNORE, 0xC0, }, /* External display connect/disconnect notification */ { KE_KEY, 0xC4, { KEY_KBDILLUMUP } }, { KE_KEY, 0xC5, { KEY_KBDILLUMDOWN } }, { KE_IGNORE, 0xC6, }, /* Ambient Light Sensor notification */ + { KE_IGNORE, 0xCF, }, /* AC mode */ { KE_KEY, 0xFA, { KEY_PROG2 } }, /* Lid flip action */ { KE_END, 0}, }; @@ -514,9 +600,33 @@ .detect_quirks = asus_nb_wmi_quirks, }; +static const struct dmi_system_id asus_nb_wmi_blacklist[] __initconst = { + { + /* + * asus-nb-wm adds no functionality. The T100TA has a detachable + * USB kbd, so no hotkeys and it has no WMI rfkill; and loading + * asus-nb-wm causes the camera LED to turn and _stay_ on. + */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"), + }, + }, + { + /* The Asus T200TA has the same issue as the T100TA */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T200TA"), + }, + }, + {} /* Terminating entry */ +}; static int __init asus_nb_wmi_init(void) { + if (dmi_check_system(asus_nb_wmi_blacklist)) + return -ENODEV; + return asus_wmi_register_driver(&asus_nb_wmi_driver); } --- linux-oracle-5.4.0.orig/drivers/platform/x86/asus-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/asus-wmi.c @@ -111,6 +111,8 @@ u32 arg0; u32 arg1; u32 arg2; /* At least TUF Gaming series uses 3 dword input buffer. */ + u32 arg4; + u32 arg5; } __packed; /* @@ -418,8 +420,12 @@ { /* The WMI method does not provide a way to specific a battery, so we * just assume it is the first battery. + * Note: On some newer ASUS laptops (Zenbook UM431DA), the primary/first + * battery is named BATT. */ - if (strcmp(battery->desc->name, "BAT0") != 0) + if (strcmp(battery->desc->name, "BAT0") != 0 && + strcmp(battery->desc->name, "BAT1") != 0 && + strcmp(battery->desc->name, "BATT") != 0) return -ENODEV; if (device_create_file(&battery->dev, @@ -512,13 +518,7 @@ { int ctrl_param = 0; - /* - * bits 0-2: level - * bit 7: light on/off - */ - if (asus->kbd_led_wk > 0) - ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); - + ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL); } @@ -1195,6 +1195,8 @@ pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, cpu_to_le32(ports_available)); + pci_dev_put(xhci_pdev); + pr_info("set USB_INTEL_XUSB2PR old: 0x%04x, new: 0x%04x\n", orig_ports_available, ports_available); } --- linux-oracle-5.4.0.orig/drivers/platform/x86/asus-wmi.h +++ linux-oracle-5.4.0/drivers/platform/x86/asus-wmi.h @@ -18,7 +18,7 @@ #include #define ASUS_WMI_KEY_IGNORE (-1) -#define ASUS_WMI_BRN_DOWN 0x20 +#define ASUS_WMI_BRN_DOWN 0x2e #define ASUS_WMI_BRN_UP 0x2f struct module; --- linux-oracle-5.4.0.orig/drivers/platform/x86/dell-laptop.c +++ linux-oracle-5.4.0/drivers/platform/x86/dell-laptop.c @@ -33,6 +33,7 @@ struct quirk_entry { bool touchpad_led; + bool kbd_led_not_present; bool kbd_led_levels_off_1; bool kbd_missing_ac_tag; @@ -73,6 +74,10 @@ .kbd_led_levels_off_1 = true, }; +static struct quirk_entry quirk_dell_inspiron_1012 = { + .kbd_led_not_present = true, +}; + static struct platform_driver platform_driver = { .driver = { .name = "dell-laptop", @@ -310,6 +315,24 @@ }, .driver_data = &quirk_dell_latitude_e6410, }, + { + .callback = dmi_matched, + .ident = "Dell Inspiron 1012", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), + }, + .driver_data = &quirk_dell_inspiron_1012, + }, + { + .callback = dmi_matched, + .ident = "Dell Inspiron 1018", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1018"), + }, + .driver_data = &quirk_dell_inspiron_1012, + }, { } }; @@ -1493,6 +1516,9 @@ { int ret; + if (quirks && quirks->kbd_led_not_present) + return; + ret = kbd_init_info(); kbd_init_tokens(); @@ -2178,10 +2204,13 @@ dell_laptop_register_notifier(&dell_laptop_notifier); - micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); - if (ret < 0) - goto fail_led; + if (dell_smbios_find_token(GLOBAL_MIC_MUTE_DISABLE) && + dell_smbios_find_token(GLOBAL_MIC_MUTE_ENABLE)) { + micmute_led_cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); + ret = led_classdev_register(&platform_device->dev, &micmute_led_cdev); + if (ret < 0) + goto fail_led; + } if (acpi_video_get_backlight_type() != acpi_backlight_vendor) return 0; --- linux-oracle-5.4.0.orig/drivers/platform/x86/dell-smbios-base.c +++ linux-oracle-5.4.0/drivers/platform/x86/dell-smbios-base.c @@ -594,6 +594,7 @@ if (wmi && smm) { pr_err("No SMBIOS backends available (wmi: %d, smm: %d)\n", wmi, smm); + ret = -ENODEV; goto fail_create_group; } @@ -609,7 +610,10 @@ return 0; fail_sysfs: - free_group(platform_device); + if (!wmi) + exit_dell_smbios_wmi(); + if (!smm) + exit_dell_smbios_smm(); fail_create_group: platform_device_del(platform_device); --- linux-oracle-5.4.0.orig/drivers/platform/x86/dell-smbios-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/dell-smbios-wmi.c @@ -69,6 +69,7 @@ if (obj->type == ACPI_TYPE_INTEGER) dev_dbg(&wdev->dev, "SMBIOS call failed: %llu\n", obj->integer.value); + kfree(output.pointer); return -EIO; } memcpy(&priv->buf->std, obj->buffer.pointer, obj->buffer.length); @@ -271,7 +272,8 @@ void exit_dell_smbios_wmi(void) { - wmi_driver_unregister(&dell_smbios_wmi_driver); + if (wmi_supported) + wmi_driver_unregister(&dell_smbios_wmi_driver); } MODULE_DEVICE_TABLE(wmi, dell_smbios_wmi_id_table); --- linux-oracle-5.4.0.orig/drivers/platform/x86/dell-uart-backlight.c +++ linux-oracle-5.4.0/drivers/platform/x86/dell-uart-backlight.c @@ -0,0 +1,530 @@ +/* + * Dell AIO Serial Backlight Driver + * + * Copyright (C) 2017 AceLan Kao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dell-uart-backlight.h" + +struct dell_uart_backlight { + struct device *dev; + struct backlight_device *dell_uart_bd; + struct mutex brightness_mutex; + int line; + int bl_power; +}; +struct uart_8250_port *serial8250_get_port(int line); +static struct tty_struct *tty; +static struct file *ftty; + +unsigned int (*io_serial_in)(struct uart_port *p, int offset); +int (*uart_write)(struct tty_struct *tty, const unsigned char *buf, int count); +int (*uart_chars_in_buffer)(struct tty_struct *tty); + +static bool force; +module_param(force, bool, 0444); +MODULE_PARM_DESC(force, "load the driver regardless of the scalar status"); + +static struct dell_uart_bl_cmd uart_cmd[] = { + /* + * Get Firmware Version: Tool uses this command to get firmware version. + * Command: 0x6A 0x06 0x8F (Length:3 Type: 0x0A, Cmd:6 Checksum:0x8F) + * Return data: 0x0D 0x06 Data checksum (Length:13,Cmd:0x06, + * Data :F/W version(APRILIA=APR27-VXXX,PHINE=PHI23-VXXX), + * checksum:SUM(Length and Cmd and Data)xor 0xFF . + */ + [DELL_UART_GET_FIRMWARE_VER] = { + .cmd = {0x6A, 0x06, 0x8F}, + .tx_len = 3, + }, + /* + * Get Scalar Status: Tool uses this command to check if scalar IC controls brightness. + * Command: 0x6A 0x1F 0x8F (Length:3 Type: 0x0A, Cmd:0x1F Checksum:0x76) + * Return data: 0x04 0x1F Data checksum + * (Data = 0: scalar cannot adjust brightness, Data = 1: scalar can adjust brightness) + */ + [DELL_UART_GET_SCALAR] = { + .cmd = {0x6A,0x1F,0x76}, + .ret = {0x04,0x1F,0x00,0x00}, + .tx_len = 3, + .rx_len = 4, + }, + /* + * Get Brightness level: Application uses this command for scaler to + * get brightness. + * Command: 0x6A 0x0C 0x89 + * (Length:3 Type: 0x0A, Cmd:0x0C, Checksum:0x89) + * Return data: 0x04 0x0C Data checksum + * (Length:4 Cmd: 0x0C Data: brightness level + * checksum: SUM(Length and Cmd and Data)xor 0xFF) + * brightness level which ranges from 0~100. + */ + [DELL_UART_GET_BRIGHTNESS] = { + .cmd = {0x6A, 0x0C, 0x89}, + .ret = {0x04, 0x0C, 0x00, 0x00}, + .tx_len = 3, + .rx_len = 4, + }, + /* Set Brightness level: Application uses this command for scaler to + * set brightness. + * Command: 0x8A 0x0B Byte2 Checksum (Length:4 Type: 0x0A, Cmd:0x0B) + * where Byte2 is the brightness level which ranges from 0~100. + * Return data: 0x03 0x0B 0xF1(Length:3,Cmd:B,checksum:0xF1) + * Scaler must send the 3bytes ack within 1 second when success, + * other value if error + */ + [DELL_UART_SET_BRIGHTNESS] = { + .cmd = {0x8A, 0x0B, 0x0, 0x0}, + .ret = {0x03, 0x0B, 0xF1}, + .tx_len = 4, + .rx_len = 3, + }, + /* + * Screen ON/OFF Control: Application uses this command to control + * screen ON or OFF. + * Command: 0x8A 0x0E Byte2 Checksum (Length:4 Type: 0x0A, Cmd:0x0E) + * where + * Byte2=0 to turn OFF the screen. + * Byte2=1 to turn ON the screen + * Other value of Byte2 is reserved and invalid. + * Return data: 0x03 0x0E 0xEE(Length:3,Cmd:E,checksum:0xEE) + */ + [DELL_UART_SET_BACKLIGHT_POWER] = { + .cmd = {0x8A, 0x0E, 0x00, 0x0}, + .ret = {0x03, 0x0E, 0xEE}, + .tx_len = 4, + .rx_len = 3, + }, +}; + +static const struct dmi_system_id dell_uart_backlight_alpha_platform[] __initconst = { + { + .ident = "Dell Inspiron 7777 AIO", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7777 AIO"), + }, + }, + { + .ident = "Dell Inspiron 5477 AIO", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5477 AIO"), + }, + }, + { + .ident = "Dell OptiPlex 7769 AIO", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7769 AIO"), + }, + }, + { + .ident = "Dell OptiPlex 5260 AIO", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 5260 AIO"), + }, + }, + { } +}; + +static int dell_uart_write(struct uart_8250_port *up, __u8 *buf, int len) +{ + int actual = 0; + struct uart_port *port = &up->port; + + tty_port_tty_wakeup(&port->state->port); + tty = tty_port_tty_get(&port->state->port); + actual = uart_write(tty, buf, len); + while (uart_chars_in_buffer(tty)) + udelay(10); + + return actual; +} + +static int dell_uart_read(struct uart_8250_port *up, __u8 *buf, int len) +{ + int i, retry; + unsigned long flags; + + spin_lock_irqsave(&up->port.lock, flags); + for (i = 0; i < len; i++) { + retry = 10; + while (!(io_serial_in(&up->port, UART_LSR) & UART_LSR_DR)) { + if (--retry == 0) + break; + mdelay(20); + } + + if (retry == 0) + break; + buf[i] = io_serial_in(&up->port, UART_RX); + } + spin_unlock_irqrestore(&up->port.lock, flags); + + return i; +} + +static void dell_uart_dump_cmd(const char *func, const char *prefix, + const char *cmd, int len) +{ + char buf[80]; + + snprintf(buf, 80, "dell_uart_backlight:%s:%s", func, prefix); + if (len != 0) + print_hex_dump_debug(buf, DUMP_PREFIX_NONE, + 16, 1, cmd, len, false); + else + pr_debug("dell_uart_backlight:%s:%sNULL\n", func, prefix); + +} + +/* + * checksum: SUM(Length and Cmd and Data)xor 0xFF) + */ +static unsigned char dell_uart_checksum(unsigned char *buf, int len) +{ + unsigned char val = 0; + + while (len-- > 0) + val += buf[len]; + + return val ^ 0xff; +} + +/* + * There is no command to get backlight power status, + * so we set the backlight power to "on" while initializing, + * and then track and report its status by bl_power variable + */ +static inline int dell_uart_get_bl_power(struct dell_uart_backlight *dell_pdata) +{ + return dell_pdata->bl_power; +} + +static int dell_uart_set_bl_power(struct backlight_device *bd, int power) +{ + struct dell_uart_bl_cmd *bl_cmd = + &uart_cmd[DELL_UART_SET_BACKLIGHT_POWER]; + struct dell_uart_backlight *dell_pdata = bl_get_data(bd); + struct uart_8250_port *uart = serial8250_get_port(dell_pdata->line); + int rx_len; + + if (power != FB_BLANK_POWERDOWN) + power = FB_BLANK_UNBLANK; + + bl_cmd->cmd[2] = power ? 0 : 1; + bl_cmd->cmd[3] = dell_uart_checksum(bl_cmd->cmd, bl_cmd->tx_len - 1); + + dell_uart_dump_cmd(__func__, "tx: ", bl_cmd->cmd, bl_cmd->tx_len); + + if (mutex_lock_killable(&dell_pdata->brightness_mutex) < 0) { + pr_debug("Failed to get mutex_lock"); + return 0; + } + + dell_uart_write(uart, bl_cmd->cmd, bl_cmd->tx_len); + rx_len = dell_uart_read(uart, bl_cmd->ret, bl_cmd->rx_len); + + mutex_unlock(&dell_pdata->brightness_mutex); + + dell_uart_dump_cmd(__func__, "rx: ", bl_cmd->ret, rx_len); + + bd->props.power = power; + dell_pdata->bl_power = power; + + return 0; +} + +static int dell_uart_get_brightness(struct backlight_device *bd) +{ + struct dell_uart_bl_cmd *bl_cmd = &uart_cmd[DELL_UART_GET_BRIGHTNESS]; + struct dell_uart_backlight *dell_pdata = bl_get_data(bd); + struct uart_8250_port *uart = serial8250_get_port(dell_pdata->line); + int rx_len, brightness = 0; + + dell_uart_dump_cmd(__func__, "tx: ", bl_cmd->cmd, bl_cmd->tx_len); + + if (mutex_lock_killable(&dell_pdata->brightness_mutex) < 0) { + pr_debug("Failed to get mutex_lock"); + return 0; + } + + dell_uart_write(uart, bl_cmd->cmd, bl_cmd->tx_len); + rx_len = dell_uart_read(uart, bl_cmd->ret, bl_cmd->rx_len); + + mutex_unlock(&dell_pdata->brightness_mutex); + + dell_uart_dump_cmd(__func__, "rx: ", bl_cmd->ret, rx_len); + + brightness = (unsigned int)bl_cmd->ret[2]; + + return brightness; +} + +static int dell_uart_update_status(struct backlight_device *bd) +{ + struct dell_uart_bl_cmd *bl_cmd = &uart_cmd[DELL_UART_SET_BRIGHTNESS]; + struct dell_uart_backlight *dell_pdata = bl_get_data(bd); + struct uart_8250_port *uart = serial8250_get_port(dell_pdata->line); + int rx_len; + + bl_cmd->cmd[2] = bd->props.brightness; + bl_cmd->cmd[3] = dell_uart_checksum(bl_cmd->cmd, bl_cmd->tx_len - 1); + + dell_uart_dump_cmd(__func__, "tx: ", bl_cmd->cmd, bl_cmd->tx_len); + + if (mutex_lock_killable(&dell_pdata->brightness_mutex) < 0) { + pr_debug("Failed to get mutex_lock"); + return 0; + } + + dell_uart_write(uart, bl_cmd->cmd, bl_cmd->tx_len); + rx_len = dell_uart_read(uart, bl_cmd->ret, bl_cmd->rx_len); + + mutex_unlock(&dell_pdata->brightness_mutex); + + dell_uart_dump_cmd(__func__, "rx: ", bl_cmd->ret, rx_len); + + if (bd->props.power != dell_uart_get_bl_power(dell_pdata)) + dell_uart_set_bl_power(bd, bd->props.power); + + return 0; +} + +static int dell_uart_get_scalar_status(struct dell_uart_backlight *dell_pdata) +{ + struct dell_uart_bl_cmd *bl_cmd = &uart_cmd[DELL_UART_GET_SCALAR]; + struct uart_8250_port *uart = serial8250_get_port(dell_pdata->line); + int rx_len; + int status = 0, retry = 50; + + dell_uart_dump_cmd(__func__, "tx: ", bl_cmd->cmd, bl_cmd->tx_len); + + if (mutex_lock_killable(&dell_pdata->brightness_mutex) < 0) { + pr_debug("Failed to get mutex_lock"); + return 0; + } + + dell_uart_write(uart, bl_cmd->cmd, bl_cmd->tx_len); + do { + rx_len = dell_uart_read(uart, bl_cmd->ret, bl_cmd->rx_len); + if (rx_len == 0) + msleep(100); + } while (rx_len == 0 && --retry); + + mutex_unlock(&dell_pdata->brightness_mutex); + + dell_uart_dump_cmd(__func__, "rx: ", bl_cmd->ret, rx_len); + + if (rx_len == 4) + status = (unsigned int)bl_cmd->ret[2]; + + return status; +} + +static int dell_uart_show_firmware_ver(struct dell_uart_backlight *dell_pdata) +{ + struct dell_uart_bl_cmd *bl_cmd = &uart_cmd[DELL_UART_GET_FIRMWARE_VER]; + struct uart_8250_port *uart = serial8250_get_port(dell_pdata->line); + int rx_len = 0, retry = 10; + + dell_uart_dump_cmd(__func__, "tx: ", bl_cmd->cmd, bl_cmd->tx_len); + + if (mutex_lock_killable(&dell_pdata->brightness_mutex) < 0) { + pr_debug("Failed to get mutex_lock"); + return -1; + } + + dell_uart_write(uart, bl_cmd->cmd, bl_cmd->tx_len); + while (retry-- > 0) { + /* first byte is data length */ + dell_uart_read(uart, bl_cmd->ret, 1); + rx_len = (int)bl_cmd->ret[0]; + if (bl_cmd->ret[0] > 80 || bl_cmd->ret[0] == 0) { + pr_debug("Failed to get firmware version\n"); + if (retry == 0) { + mutex_unlock(&dell_pdata->brightness_mutex); + return -1; + } + msleep(100); + continue; + } + + dell_uart_read(uart, bl_cmd->ret+1, rx_len-1); + break; + } + mutex_unlock(&dell_pdata->brightness_mutex); + + dell_uart_dump_cmd(__func__, "rx: ", bl_cmd->ret, rx_len); + + pr_debug("Firmare str(%d)= %s\n", (int)bl_cmd->ret[0], bl_cmd->ret+2); + return rx_len; +} + +static const struct backlight_ops dell_uart_backlight_ops = { + .get_brightness = dell_uart_get_brightness, + .update_status = dell_uart_update_status, +}; + +static int dell_uart_startup(struct dell_uart_backlight *dell_pdata) +{ + struct uart_8250_port *uartp; + struct uart_port *port; + + dell_pdata->line = 0; + uartp = serial8250_get_port(dell_pdata->line); + port = &uartp->port; + tty = port->state->port.tty; + io_serial_in = port->serial_in; + uart_write = tty->driver->ops->write; + uart_chars_in_buffer = tty->driver->ops->chars_in_buffer; + + return 0; +} + +static int dell_uart_bl_add(struct acpi_device *dev) +{ + struct dell_uart_backlight *dell_pdata; + struct backlight_properties props; + struct backlight_device *dell_uart_bd; + + dell_pdata = kzalloc(sizeof(struct dell_uart_backlight), GFP_KERNEL); + if (!dell_pdata) { + pr_debug("Failed to allocate memory for dell_uart_backlight\n"); + return -ENOMEM; + } + dell_pdata->dev = &dev->dev; + dell_uart_startup(dell_pdata); + dev->driver_data = dell_pdata; + + mutex_init(&dell_pdata->brightness_mutex); + + if (!force) { + if (dmi_check_system(dell_uart_backlight_alpha_platform)) { + /* try another command to make sure there is no scalar IC */ + if (dell_uart_show_firmware_ver(dell_pdata) <= 4) { + pr_debug("Scalar is not in charge of brightness adjustment.\n"); + kzfree(dell_pdata); + return -ENODEV; + } + } + else if (!dell_uart_get_scalar_status(dell_pdata)) { + pr_debug("Scalar is not in charge of brightness adjustment.\n"); + kzfree(dell_pdata); + return -ENODEV; + } + } + dell_uart_show_firmware_ver(dell_pdata); + + memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_PLATFORM; + props.max_brightness = 100; + + dell_uart_bd = backlight_device_register("dell_uart_backlight", + &dev->dev, + dell_pdata, + &dell_uart_backlight_ops, + &props); + if (IS_ERR(dell_uart_bd)) { + kzfree(dell_pdata); + pr_debug("Backlight registration failed\n"); + return PTR_ERR(dell_uart_bd); + } + + dell_pdata->dell_uart_bd = dell_uart_bd; + + dell_uart_set_bl_power(dell_uart_bd, FB_BLANK_UNBLANK); + dell_uart_bd->props.brightness = 100; + backlight_update_status(dell_uart_bd); + + /* unregister acpi backlight interface */ + acpi_video_set_dmi_backlight_type(acpi_backlight_vendor); + + return 0; +} + +static int dell_uart_bl_remove(struct acpi_device *dev) +{ + struct dell_uart_backlight *dell_pdata = dev->driver_data; + + backlight_device_unregister(dell_pdata->dell_uart_bd); + kzfree(dell_pdata); + + return 0; +} + +static int dell_uart_bl_suspend(struct device *dev) +{ + filp_close(ftty, NULL); + return 0; +} + +static int dell_uart_bl_resume(struct device *dev) +{ + ftty = filp_open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY, 0); + return 0; +} + +static SIMPLE_DEV_PM_OPS(dell_uart_bl_pm, dell_uart_bl_suspend, dell_uart_bl_resume); + +static const struct acpi_device_id dell_uart_bl_ids[] = { + {"DELL0501", 0}, + {"", 0}, +}; + +static struct acpi_driver dell_uart_backlight_driver = { + .name = "Dell AIO serial backlight", + .ids = dell_uart_bl_ids, + .ops = { + .add = dell_uart_bl_add, + .remove = dell_uart_bl_remove, + }, + .drv.pm = &dell_uart_bl_pm, +}; + +static int __init dell_uart_bl_init(void) +{ + ftty = filp_open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY, 0); + if (IS_ERR(ftty)) { + pr_debug("cannot open /dev/ttyS0\n"); + return -EINVAL; + } + + return acpi_bus_register_driver(&dell_uart_backlight_driver); +} + +static void __exit dell_uart_bl_exit(void) +{ + filp_close(ftty, NULL); + + acpi_bus_unregister_driver(&dell_uart_backlight_driver); +} + +module_init(dell_uart_bl_init); +module_exit(dell_uart_bl_exit); +MODULE_DEVICE_TABLE(acpi, dell_uart_bl_ids); +MODULE_DESCRIPTION("Dell AIO Serial Backlight module"); +MODULE_AUTHOR("AceLan Kao "); +MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/platform/x86/dell-uart-backlight.h +++ linux-oracle-5.4.0/drivers/platform/x86/dell-uart-backlight.h @@ -0,0 +1,36 @@ +/* + * Dell AIO Serial Backlight Driver + * + * Copyright (C) 2017 AceLan Kao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _DELL_UART_BACKLIGHT_H_ +#define _DELL_UART_BACKLIGHT_H_ + +enum { + DELL_UART_GET_FIRMWARE_VER, + DELL_UART_GET_SCALAR, + DELL_UART_GET_BRIGHTNESS, + DELL_UART_SET_BRIGHTNESS, + DELL_UART_SET_BACKLIGHT_POWER, +}; + +struct dell_uart_bl_cmd { + unsigned char cmd[10]; + unsigned char ret[80]; + unsigned short tx_len; + unsigned short rx_len; +}; + +#endif /* _DELL_UART_BACKLIGHT_H_ */ --- linux-oracle-5.4.0.orig/drivers/platform/x86/gpd-pocket-fan.c +++ linux-oracle-5.4.0/drivers/platform/x86/gpd-pocket-fan.c @@ -16,17 +16,27 @@ #define MAX_SPEED 3 -static int temp_limits[3] = { 55000, 60000, 65000 }; +#define TEMP_LIMIT0_DEFAULT 55000 +#define TEMP_LIMIT1_DEFAULT 60000 +#define TEMP_LIMIT2_DEFAULT 65000 + +#define HYSTERESIS_DEFAULT 3000 + +#define SPEED_ON_AC_DEFAULT 2 + +static int temp_limits[3] = { + TEMP_LIMIT0_DEFAULT, TEMP_LIMIT1_DEFAULT, TEMP_LIMIT2_DEFAULT, +}; module_param_array(temp_limits, int, NULL, 0444); MODULE_PARM_DESC(temp_limits, "Millicelsius values above which the fan speed increases"); -static int hysteresis = 3000; +static int hysteresis = HYSTERESIS_DEFAULT; module_param(hysteresis, int, 0444); MODULE_PARM_DESC(hysteresis, "Hysteresis in millicelsius before lowering the fan speed"); -static int speed_on_ac = 2; +static int speed_on_ac = SPEED_ON_AC_DEFAULT; module_param(speed_on_ac, int, 0444); MODULE_PARM_DESC(speed_on_ac, "minimum fan speed to allow when system is powered by AC"); @@ -117,21 +127,24 @@ int i; for (i = 0; i < ARRAY_SIZE(temp_limits); i++) { - if (temp_limits[i] < 40000 || temp_limits[i] > 70000) { - dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n", + if (temp_limits[i] < 20000 || temp_limits[i] > 90000) { + dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 20000 and 90000)\n", temp_limits[i]); - return -EINVAL; + temp_limits[0] = TEMP_LIMIT0_DEFAULT; + temp_limits[1] = TEMP_LIMIT1_DEFAULT; + temp_limits[2] = TEMP_LIMIT2_DEFAULT; + break; } } if (hysteresis < 1000 || hysteresis > 10000) { dev_err(&pdev->dev, "Invalid hysteresis %d (must be between 1000 and 10000)\n", hysteresis); - return -EINVAL; + hysteresis = HYSTERESIS_DEFAULT; } if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) { dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n", speed_on_ac); - return -EINVAL; + speed_on_ac = SPEED_ON_AC_DEFAULT; } fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/platform/x86/hdaps.c +++ linux-oracle-5.4.0/drivers/platform/x86/hdaps.c @@ -366,7 +366,7 @@ static ssize_t hdaps_temp1_show(struct device *dev, struct device_attribute *attr, char *buf) { - u8 uninitialized_var(temp); + u8 temp; int ret; ret = hdaps_readb_one(HDAPS_PORT_TEMP1, &temp); @@ -379,7 +379,7 @@ static ssize_t hdaps_temp2_show(struct device *dev, struct device_attribute *attr, char *buf) { - u8 uninitialized_var(temp); + u8 temp; int ret; ret = hdaps_readb_one(HDAPS_PORT_TEMP2, &temp); --- linux-oracle-5.4.0.orig/drivers/platform/x86/hp-wireless.c +++ linux-oracle-5.4.0/drivers/platform/x86/hp-wireless.c @@ -17,12 +17,14 @@ MODULE_AUTHOR("Alex Hung"); MODULE_ALIAS("acpi*:HPQ6001:*"); MODULE_ALIAS("acpi*:WSTADEF:*"); +MODULE_ALIAS("acpi*:AMDI0051:*"); static struct input_dev *hpwl_input_dev; static const struct acpi_device_id hpwl_ids[] = { {"HPQ6001", 0}, {"WSTADEF", 0}, + {"AMDI0051", 0}, {"", 0}, }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/hp-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/hp-wmi.c @@ -32,6 +32,10 @@ MODULE_ALIAS("wmi:95F24279-4D7B-4334-9387-ACCDC67EF61C"); MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); +static int enable_tablet_mode_sw = -1; +module_param(enable_tablet_mode_sw, int, 0444); +MODULE_PARM_DESC(enable_tablet_mode_sw, "Enable SW_TABLET_MODE reporting (-1=auto, 0=no, 1=yes)"); + #define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C" #define HPWMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" @@ -58,6 +62,8 @@ HPWMI_BACKLIT_KB_BRIGHTNESS = 0x0D, HPWMI_PEAKSHIFT_PERIOD = 0x0F, HPWMI_BATTERY_CHARGE_PERIOD = 0x10, + HPWMI_SANITIZATION_MODE = 0x17, + HPWMI_SMART_EXPERIENCE_APP = 0x21, }; struct bios_args { @@ -65,7 +71,7 @@ u32 command; u32 commandtype; u32 datasize; - u32 data; + u8 data[128]; }; enum hp_wmi_commandtype { @@ -216,7 +222,7 @@ .command = command, .commandtype = query, .datasize = insize, - .data = 0, + .data = { 0 }, }; struct acpi_buffer input = { sizeof(struct bios_args), &args }; struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; @@ -228,7 +234,7 @@ if (WARN_ON(insize > sizeof(args.data))) return -EINVAL; - memcpy(&args.data, buffer, insize); + memcpy(&args.data[0], buffer, insize); wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output); @@ -300,7 +306,7 @@ static int __init hp_wmi_bios_2009_later(void) { - int state = 0; + u8 state[128]; int ret = hp_wmi_perform_query(HPWMI_FEATURE2_QUERY, HPWMI_READ, &state, sizeof(state), sizeof(state)); if (!ret) @@ -380,7 +386,7 @@ int err, i; err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + sizeof(state), sizeof(state)); if (err) return err; @@ -461,8 +467,14 @@ static ssize_t als_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - u32 tmp = simple_strtoul(buf, NULL, 10); - int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp, + u32 tmp; + int ret; + + ret = kstrtou32(buf, 10, &tmp); + if (ret) + return ret; + + ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, HPWMI_WRITE, &tmp, sizeof(tmp), sizeof(tmp)); if (ret) return ret < 0 ? ret : -EINVAL; @@ -619,6 +631,10 @@ break; case HPWMI_BATTERY_CHARGE_PERIOD: break; + case HPWMI_SANITIZATION_MODE: + break; + case HPWMI_SMART_EXPERIENCE_APP: + break; default: pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data); break; @@ -648,10 +664,12 @@ } /* Tablet mode */ - val = hp_wmi_hw_state(HPWMI_TABLET_MASK); - if (!(val < 0)) { - __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); - input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); + if (enable_tablet_mode_sw > 0) { + val = hp_wmi_hw_state(HPWMI_TABLET_MASK); + if (val >= 0) { + __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit); + input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val); + } } err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL); @@ -778,7 +796,7 @@ int err, i; err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, HPWMI_READ, &state, - 0, sizeof(state)); + sizeof(state), sizeof(state)); if (err) return err < 0 ? err : -EINVAL; @@ -865,8 +883,16 @@ wwan_rfkill = NULL; rfkill2_count = 0; - if (hp_wmi_rfkill_setup(device)) - hp_wmi_rfkill2_setup(device); + /* + * In pre-2009 BIOS, command 1Bh return 0x4 to indicate that + * BIOS no longer controls the power for the wireless + * devices. All features supported by this command will no + * longer be supported. + */ + if (!hp_wmi_bios_2009_later()) { + if (hp_wmi_rfkill_setup(device)) + hp_wmi_rfkill2_setup(device); + } return 0; } --- linux-oracle-5.4.0.orig/drivers/platform/x86/hp_accel.c +++ linux-oracle-5.4.0/drivers/platform/x86/hp_accel.c @@ -88,6 +88,9 @@ static int lis3lv02d_acpi_init(struct lis3lv02d *lis3) { struct acpi_device *dev = lis3->bus_priv; + if (!lis3->init_required) + return 0; + if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, NULL, NULL) != AE_OK) return -EINVAL; @@ -356,6 +359,7 @@ } /* call the core layer do its init */ + lis3_dev.init_required = true; ret = lis3lv02d_init_device(&lis3_dev); if (ret) return ret; @@ -368,9 +372,11 @@ INIT_WORK(&hpled_led.work, delayed_set_status_worker); ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) { + i8042_remove_filter(hp_accel_i8042_filter); lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); + lis3lv02d_remove_fs(&lis3_dev); return ret; } @@ -403,11 +409,27 @@ static int lis3lv02d_resume(struct device *dev) { + lis3_dev.init_required = false; + lis3lv02d_poweron(&lis3_dev); + return 0; +} + +static int lis3lv02d_restore(struct device *dev) +{ + lis3_dev.init_required = true; lis3lv02d_poweron(&lis3_dev); return 0; } -static SIMPLE_DEV_PM_OPS(hp_accel_pm, lis3lv02d_suspend, lis3lv02d_resume); +static const struct dev_pm_ops hp_accel_pm = { + .suspend = lis3lv02d_suspend, + .resume = lis3lv02d_resume, + .freeze = lis3lv02d_suspend, + .thaw = lis3lv02d_resume, + .poweroff = lis3lv02d_suspend, + .restore = lis3lv02d_restore, +}; + #define HP_ACCEL_PM (&hp_accel_pm) #else #define HP_ACCEL_PM NULL --- linux-oracle-5.4.0.orig/drivers/platform/x86/huawei-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/huawei-wmi.c @@ -41,6 +41,8 @@ { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, + // Ignore Ambient Light Sensoring + { KE_KEY, 0x2c1, { KEY_RESERVED } }, { KE_END, 0 } }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/i2c-multi-instantiate.c +++ linux-oracle-5.4.0/drivers/platform/x86/i2c-multi-instantiate.c @@ -166,13 +166,29 @@ {} }; -static const struct i2c_inst_data int3515_data[] = { - { "tps6598x", IRQ_RESOURCE_APIC, 0 }, - { "tps6598x", IRQ_RESOURCE_APIC, 1 }, - { "tps6598x", IRQ_RESOURCE_APIC, 2 }, - { "tps6598x", IRQ_RESOURCE_APIC, 3 }, - {} -}; +/* + * Device with _HID INT3515 (TI PD controllers) has some unresolved interrupt + * issues. The most common problem seen is interrupt flood. + * + * There are at least two known causes. Firstly, on some boards, the + * I2CSerialBus resource index does not match the Interrupt resource, i.e. they + * are not one-to-one mapped like in the array below. Secondly, on some boards + * the IRQ line from the PD controller is not actually connected at all. But the + * interrupt flood is also seen on some boards where those are not a problem, so + * there are some other problems as well. + * + * Because of the issues with the interrupt, the device is disabled for now. If + * you wish to debug the issues, uncomment the below, and add an entry for the + * INT3515 device to the i2c_multi_instance_ids table. + * + * static const struct i2c_inst_data int3515_data[] = { + * { "tps6598x", IRQ_RESOURCE_APIC, 0 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 1 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 2 }, + * { "tps6598x", IRQ_RESOURCE_APIC, 3 }, + * { } + * }; + */ /* * Note new device-ids must also be added to i2c_multi_instantiate_ids in @@ -181,7 +197,6 @@ static const struct acpi_device_id i2c_multi_inst_acpi_ids[] = { { "BSG1160", (unsigned long)bsg1160_data }, { "BSG2150", (unsigned long)bsg2150_data }, - { "INT3515", (unsigned long)int3515_data }, { } }; MODULE_DEVICE_TABLE(acpi, i2c_multi_inst_acpi_ids); --- linux-oracle-5.4.0.orig/drivers/platform/x86/ideapad-laptop.c +++ linux-oracle-5.4.0/drivers/platform/x86/ideapad-laptop.c @@ -92,6 +92,7 @@ struct dentry *debug; unsigned long cfg; bool has_hw_rfkill_switch; + bool has_touchpad_switch; const char *fnesc_guid; }; @@ -535,7 +536,9 @@ } else if (attr == &dev_attr_fn_lock.attr) { supported = acpi_has_method(priv->adev->handle, "HALS") && acpi_has_method(priv->adev->handle, "SALS"); - } else + } else if (attr == &dev_attr_touchpad.attr) + supported = priv->has_touchpad_switch; + else supported = true; return supported ? attr->mode : 0; @@ -867,6 +870,9 @@ { unsigned long value; + if (!priv->has_touchpad_switch) + return; + /* Without reading from EC touchpad LED doesn't switch state */ if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only @@ -989,6 +995,9 @@ priv->platform_device = pdev; priv->has_hw_rfkill_switch = dmi_check_system(hw_rfkill_list); + /* Most ideapads with ELAN0634 touchpad don't use EC touchpad switch */ + priv->has_touchpad_switch = !acpi_dev_present("ELAN0634", NULL, -1); + ret = ideapad_sysfs_init(priv); if (ret) return ret; @@ -1006,6 +1015,10 @@ if (!priv->has_hw_rfkill_switch) write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); + /* The same for Touchpad */ + if (!priv->has_touchpad_switch) + write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, 1); + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) ideapad_register_rfkill(priv, i); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel-hid.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel-hid.c @@ -20,8 +20,11 @@ static const struct acpi_device_id intel_hid_ids[] = { {"INT33D5", 0}, + {"INTC1051", 0}, + {"INTC1054", 0}, {"", 0}, }; +MODULE_DEVICE_TABLE(acpi, intel_hid_ids); /* In theory, these are HID usages. */ static const struct key_entry intel_hid_keymap[] = { @@ -77,6 +80,20 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Wacom MobileStudio Pro 16"), }, }, + { + .ident = "HP Spectre x2 (2015)", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x2 Detachable"), + }, + }, + { + .ident = "Lenovo ThinkPad X1 Tablet Gen 2", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), + }, + }, { } }; @@ -435,7 +452,7 @@ static int intel_hid_probe(struct platform_device *device) { acpi_handle handle = ACPI_HANDLE(&device->dev); - unsigned long long mode; + unsigned long long mode, dummy; struct intel_hid_priv *priv; acpi_status status; int err; @@ -487,18 +504,15 @@ if (err) goto err_remove_notify; - if (priv->array) { - unsigned long long dummy; - - intel_button_array_enable(&device->dev, true); + intel_button_array_enable(&device->dev, true); - /* Call button load method to enable HID power button */ - if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, - &dummy)) { - dev_warn(&device->dev, - "failed to enable HID power button\n"); - } - } + /* + * Call button load method to enable HID power button + * Always do this since it activates events on some devices without + * a button array too. + */ + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) + dev_warn(&device->dev, "failed to enable HID power button\n"); device_init_wakeup(&device->dev, true); /* @@ -540,7 +554,6 @@ .probe = intel_hid_probe, .remove = intel_hid_remove, }; -MODULE_DEVICE_TABLE(acpi, intel_hid_ids); /* * Unfortunately, some laptops provide a _HID="INT33D5" device with @@ -563,7 +576,7 @@ return AE_OK; if (acpi_match_device_ids(dev, ids) == 0) - if (acpi_create_platform_device(dev, NULL)) + if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL))) dev_info(&dev->dev, "intel-hid: created platform device\n"); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel-vbtn.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel-vbtn.c @@ -15,9 +15,13 @@ #include #include +/* Returned when NOT in tablet mode on some HP Stream x360 11 models */ +#define VGBS_TABLET_MODE_FLAG_ALT 0x10 /* When NOT in tablet mode, VGBS returns with the flag 0x40 */ -#define TABLET_MODE_FLAG 0x40 -#define DOCK_MODE_FLAG 0x80 +#define VGBS_TABLET_MODE_FLAG 0x40 +#define VGBS_DOCK_MODE_FLAG 0x80 + +#define VGBS_TABLET_MODE_FLAGS (VGBS_TABLET_MODE_FLAG | VGBS_TABLET_MODE_FLAG_ALT) MODULE_LICENSE("GPL"); MODULE_AUTHOR("AceLan Kao"); @@ -39,28 +43,59 @@ { KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } }, /* volume-down key release */ { KE_KEY, 0xC8, { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key press */ { KE_KEY, 0xC9, { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key release */ - { KE_SW, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ - { KE_SW, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ +}; + +static const struct key_entry intel_vbtn_switchmap[] = { + /* + * SW_DOCK should only be reported for docking stations, but DSDTs using the + * intel-vbtn code, always seem to use this for 2-in-1s / convertibles and set + * SW_DOCK=1 when in laptop-mode (in tandem with setting SW_TABLET_MODE=0). + * This causes userspace to think the laptop is docked to a port-replicator + * and to disable suspend-on-lid-close, which is undesirable. + * Map the dock events to KEY_IGNORE to avoid this broken SW_DOCK reporting. + */ + { KE_IGNORE, 0xCA, { .sw = { SW_DOCK, 1 } } }, /* Docked */ + { KE_IGNORE, 0xCB, { .sw = { SW_DOCK, 0 } } }, /* Undocked */ { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */ { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */ - { KE_END }, }; +#define KEYMAP_LEN \ + (ARRAY_SIZE(intel_vbtn_keymap) + ARRAY_SIZE(intel_vbtn_switchmap) + 1) + struct intel_vbtn_priv { + struct key_entry keymap[KEYMAP_LEN]; struct input_dev *input_dev; + bool has_switches; bool wakeup_mode; }; static int intel_vbtn_input_setup(struct platform_device *device) { struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); - int ret; + int ret, keymap_len = 0; + + if (true) { + memcpy(&priv->keymap[keymap_len], intel_vbtn_keymap, + ARRAY_SIZE(intel_vbtn_keymap) * + sizeof(struct key_entry)); + keymap_len += ARRAY_SIZE(intel_vbtn_keymap); + } + + if (priv->has_switches) { + memcpy(&priv->keymap[keymap_len], intel_vbtn_switchmap, + ARRAY_SIZE(intel_vbtn_switchmap) * + sizeof(struct key_entry)); + keymap_len += ARRAY_SIZE(intel_vbtn_switchmap); + } + + priv->keymap[keymap_len].type = KE_END; priv->input_dev = devm_input_allocate_device(&device->dev); if (!priv->input_dev) return -ENOMEM; - ret = sparse_keymap_setup(priv->input_dev, intel_vbtn_keymap, NULL); + ret = sparse_keymap_setup(priv->input_dev, priv->keymap, NULL); if (ret) return ret; @@ -115,31 +150,86 @@ static void detect_tablet_mode(struct platform_device *device) { - const char *chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE); struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev); acpi_handle handle = ACPI_HANDLE(&device->dev); - struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; + unsigned long long vgbs; acpi_status status; int m; - if (!(chassis_type && strcmp(chassis_type, "31") == 0)) - goto out; - - status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output); + status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs); if (ACPI_FAILURE(status)) - goto out; - - obj = vgbs_output.pointer; - if (!(obj && obj->type == ACPI_TYPE_INTEGER)) - goto out; + return; - m = !(obj->integer.value & TABLET_MODE_FLAG); + m = !(vgbs & VGBS_TABLET_MODE_FLAGS); input_report_switch(priv->input_dev, SW_TABLET_MODE, m); - m = (obj->integer.value & DOCK_MODE_FLAG) ? 1 : 0; + m = (vgbs & VGBS_DOCK_MODE_FLAG) ? 1 : 0; input_report_switch(priv->input_dev, SW_DOCK, m); -out: - kfree(vgbs_output.pointer); +} + +/* + * There are several laptops (non 2-in-1) models out there which support VGBS, + * but simply always return 0, which we translate to SW_TABLET_MODE=1. This in + * turn causes userspace (libinput) to suppress events from the builtin + * keyboard and touchpad, making the laptop essentially unusable. + * + * Since the problem of wrongly reporting SW_TABLET_MODE=1 in combination + * with libinput, leads to a non-usable system. Where as OTOH many people will + * not even notice when SW_TABLET_MODE is not being reported, a DMI based allow + * list is used here. This list mainly matches on the chassis-type of 2-in-1s. + * + * There are also some 2-in-1s which use the intel-vbtn ACPI interface to report + * SW_TABLET_MODE with a chassis-type of 8 ("Portable") or 10 ("Notebook"), + * these are matched on a per model basis, since many normal laptops with a + * possible broken VGBS ACPI-method also use these chassis-types. + */ +static const struct dmi_system_id dmi_switches_allow_list[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "31" /* Convertible */), + }, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_CHASSIS_TYPE, "32" /* Detachable */), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion 13 x360 PC"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7352"), + }, + }, + {} /* Array terminator */ +}; + +static bool intel_vbtn_has_switches(acpi_handle handle) +{ + unsigned long long vgbs; + acpi_status status; + + if (!dmi_check_system(dmi_switches_allow_list)) + return false; + + status = acpi_evaluate_integer(handle, "VGBS", NULL, &vgbs); + return ACPI_SUCCESS(status); } static int intel_vbtn_probe(struct platform_device *device) @@ -160,13 +250,16 @@ return -ENOMEM; dev_set_drvdata(&device->dev, priv); + priv->has_switches = intel_vbtn_has_switches(handle); + err = intel_vbtn_input_setup(device); if (err) { pr_err("Failed to setup Intel Virtual Button\n"); return err; } - detect_tablet_mode(device); + if (priv->has_switches) + detect_tablet_mode(device); status = acpi_install_notify_handler(handle, ACPI_DEVICE_NOTIFY, @@ -251,7 +344,7 @@ return AE_OK; if (acpi_match_device_ids(dev, ids) == 0) - if (acpi_create_platform_device(dev, NULL)) + if (!IS_ERR_OR_NULL(acpi_create_platform_device(dev, NULL))) dev_info(&dev->dev, "intel-vbtn: created platform device\n"); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_bxtwc_tmu.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_bxtwc_tmu.c @@ -48,9 +48,8 @@ static int bxt_wcove_tmu_probe(struct platform_device *pdev) { struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent); - struct regmap_irq_chip_data *regmap_irq_chip; struct wcove_tmu *wctmu; - int ret, virq, irq; + int ret; wctmu = devm_kzalloc(&pdev->dev, sizeof(*wctmu), GFP_KERNEL); if (!wctmu) @@ -59,27 +58,18 @@ wctmu->dev = &pdev->dev; wctmu->regmap = pmic->regmap; - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + wctmu->irq = platform_get_irq(pdev, 0); + if (wctmu->irq < 0) + return wctmu->irq; - regmap_irq_chip = pmic->irq_chip_data_tmu; - virq = regmap_irq_get_virq(regmap_irq_chip, irq); - if (virq < 0) { - dev_err(&pdev->dev, - "failed to get virtual interrupt=%d\n", irq); - return virq; - } - - ret = devm_request_threaded_irq(&pdev->dev, virq, + ret = devm_request_threaded_irq(&pdev->dev, wctmu->irq, NULL, bxt_wcove_tmu_irq_handler, IRQF_ONESHOT, "bxt_wcove_tmu", wctmu); if (ret) { dev_err(&pdev->dev, "request irq failed: %d,virq: %d\n", - ret, virq); + ret, wctmu->irq); return ret; } - wctmu->irq = virq; /* Unmask TMU second level Wake & System alarm */ regmap_update_bits(wctmu->regmap, BXTWC_MTMUIRQ_REG, --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_int0002_vgpio.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_int0002_vgpio.c @@ -127,6 +127,14 @@ return IRQ_HANDLED; } +static bool int0002_check_wake(void *data) +{ + u32 gpe_sts_reg; + + gpe_sts_reg = inl(GPE0A_STS_PORT); + return (gpe_sts_reg & GPE0A_PME_B0_STS_BIT); +} + static struct irq_chip int0002_byt_irqchip = { .name = DRV_NAME, .irq_ack = int0002_irq_ack, @@ -220,6 +228,7 @@ gpiochip_set_chained_irqchip(chip, irq_chip, irq, NULL); + acpi_register_wakeup_handler(irq, int0002_check_wake, NULL); device_init_wakeup(dev, true); return 0; } @@ -227,6 +236,7 @@ static int int0002_remove(struct platform_device *pdev) { device_init_wakeup(&pdev->dev, false); + acpi_unregister_wakeup_handler(int0002_check_wake, NULL); return 0; } --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_ips.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_ips.c @@ -1432,6 +1432,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"), }, }, + { + .callback = ips_blacklist_callback, + .ident = "G60JX", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "G60JX"), + }, + }, { } /* terminating entry */ }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_mid_powerbtn.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_mid_powerbtn.c @@ -146,9 +146,10 @@ input_set_capability(input, EV_KEY, KEY_POWER); - ddata = (struct mid_pb_ddata *)id->driver_data; + ddata = devm_kmemdup(&pdev->dev, (void *)id->driver_data, + sizeof(*ddata), GFP_KERNEL); if (!ddata) - return -ENODATA; + return -ENOMEM; ddata->dev = &pdev->dev; ddata->irq = irq; --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_pmc_core.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_pmc_core.c @@ -158,8 +158,9 @@ .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; -/* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */ +/* Cannon Lake: PGD PFET Enable Ack Status Register(s) bitmap */ static const struct pmc_bit_map cnp_pfear_map[] = { + /* Reserved for Cannon Lake but valid for Comet Lake */ {"PMC", BIT(0)}, {"OPI-DMI", BIT(1)}, {"SPI/eSPI", BIT(2)}, @@ -185,7 +186,7 @@ {"SDX", BIT(4)}, {"SPE", BIT(5)}, {"Fuse", BIT(6)}, - /* Reserved for Cannonlake but valid for Icelake */ + /* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */ {"SBR8", BIT(7)}, {"CSME_FSC", BIT(0)}, @@ -229,12 +230,12 @@ {"HDA_PGD4", BIT(2)}, {"HDA_PGD5", BIT(3)}, {"HDA_PGD6", BIT(4)}, - /* Reserved for Cannonlake but valid for Icelake */ + /* Reserved for Cannon Lake but valid for Ice Lake and Comet Lake */ {"PSF6", BIT(5)}, {"PSF7", BIT(6)}, {"PSF8", BIT(7)}, - /* Icelake generation onwards only */ + /* Ice Lake generation onwards only */ {"RES_65", BIT(0)}, {"RES_66", BIT(1)}, {"RES_67", BIT(2)}, @@ -324,7 +325,7 @@ {"ISH", CNP_PMC_LTR_ISH}, {"UFSX2", CNP_PMC_LTR_UFSX2}, {"EMMC", CNP_PMC_LTR_EMMC}, - /* Reserved for Cannonlake but valid for Icelake */ + /* Reserved for Cannon Lake but valid for Ice Lake */ {"WIGIG", ICL_PMC_LTR_WIGIG}, /* Below two cannot be used for LTR_IGNORE */ {"CURRENT_PLATFORM", CNP_PMC_LTR_CUR_PLT}, @@ -813,6 +814,8 @@ INTEL_CPU_FAM6(CANNONLAKE_L, cnp_reg_map), INTEL_CPU_FAM6(ICELAKE_L, icl_reg_map), INTEL_CPU_FAM6(ICELAKE_NNPI, icl_reg_map), + INTEL_CPU_FAM6(COMETLAKE, cnp_reg_map), + INTEL_CPU_FAM6(COMETLAKE_L, cnp_reg_map), {} }; @@ -828,9 +831,15 @@ * the platform BIOS enforces 24Mhx Crystal to shutdown * before PMC can assert SLP_S0#. */ +static bool xtal_ignore; static int quirk_xtal_ignore(const struct dmi_system_id *id) { - struct pmc_dev *pmcdev = &pmc; + xtal_ignore = true; + return 0; +} + +static void pmc_core_xtal_ignore(struct pmc_dev *pmcdev) +{ u32 value; value = pmc_core_reg_read(pmcdev, pmcdev->map->pm_vric1_offset); @@ -839,7 +848,6 @@ /* Low Voltage Mode Enable */ value &= ~SPT_PMC_VRIC1_SLPS0LVEN; pmc_core_reg_write(pmcdev, pmcdev->map->pm_vric1_offset, value); - return 0; } static const struct dmi_system_id pmc_core_dmi_table[] = { @@ -854,6 +862,14 @@ {} }; +static void pmc_core_do_dmi_quirks(struct pmc_dev *pmcdev) +{ + dmi_check_system(pmc_core_dmi_table); + + if (xtal_ignore) + pmc_core_xtal_ignore(pmcdev); +} + static int pmc_core_probe(struct platform_device *pdev) { static bool device_initialized; @@ -871,8 +887,8 @@ pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data; /* - * Coffeelake has CPU ID of Kabylake and Cannonlake PCH. So here - * Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap + * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here + * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap * in this case. */ if (pmcdev->map == &spt_reg_map && !pci_dev_present(pmc_pci_ids)) @@ -895,7 +911,7 @@ mutex_init(&pmcdev->lock); platform_set_drvdata(pdev, pmcdev); pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(); - dmi_check_system(pmc_core_dmi_table); + pmc_core_do_dmi_quirks(pmcdev); pmc_core_dbgfs_register(pmcdev); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_pmc_core_pltdrv.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_pmc_core_pltdrv.c @@ -18,6 +18,8 @@ #include #include +#include + static void intel_pmc_core_release(struct device *dev) { /* Nothing to do. */ @@ -44,6 +46,8 @@ INTEL_CPU_FAM6(KABYLAKE, pmc_core_device), INTEL_CPU_FAM6(CANNONLAKE_L, pmc_core_device), INTEL_CPU_FAM6(ICELAKE_L, pmc_core_device), + INTEL_CPU_FAM6(COMETLAKE, pmc_core_device), + INTEL_CPU_FAM6(COMETLAKE_L, pmc_core_device), {} }; MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_platform_ids); @@ -54,6 +58,13 @@ if (acpi_dev_present("INT33A1", NULL, -1)) return -ENODEV; + /* + * Skip forcefully attaching the device for VMs. Make an exception for + * Xen dom0, which does have full hardware access. + */ + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR) && !xen_initial_domain()) + return -ENODEV; + if (!x86_match_cpu(intel_pmc_core_platform_ids)) return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_punit_ipc.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_punit_ipc.c @@ -8,7 +8,6 @@ * which provide mailbox interface for power management usage. */ -#include #include #include #include @@ -328,13 +327,14 @@ { "INT34D4", 0 }, { } }; +MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); static struct platform_driver intel_punit_ipc_driver = { .probe = intel_punit_ipc_probe, .remove = intel_punit_ipc_remove, .driver = { .name = "intel_punit_ipc", - .acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids), + .acpi_match_table = punit_ipc_acpi_ids, }, }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_scu_ipc.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_scu_ipc.c @@ -67,26 +67,22 @@ struct intel_scu_ipc_pdata_t { u32 i2c_base; u32 i2c_len; - u8 irq_mode; }; static const struct intel_scu_ipc_pdata_t intel_scu_ipc_lincroft_pdata = { .i2c_base = 0xff12b000, .i2c_len = 0x10, - .irq_mode = 0, }; /* Penwell and Cloverview */ static const struct intel_scu_ipc_pdata_t intel_scu_ipc_penwell_pdata = { .i2c_base = 0xff12b000, .i2c_len = 0x10, - .irq_mode = 1, }; static const struct intel_scu_ipc_pdata_t intel_scu_ipc_tangier_pdata = { .i2c_base = 0xff00d000, .i2c_len = 0x10, - .irq_mode = 0, }; struct intel_scu_ipc_dev { @@ -99,6 +95,9 @@ static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ +#define IPC_STATUS 0x04 +#define IPC_STATUS_IRQ BIT(2) + /* * IPC Read Buffer (Read Only): * 16 byte buffer for receiving data from SCU, if IPC command @@ -120,11 +119,8 @@ */ static inline void ipc_command(struct intel_scu_ipc_dev *scu, u32 cmd) { - if (scu->irq_mode) { - reinit_completion(&scu->cmd_complete); - writel(cmd | IPC_IOC, scu->ipc_base); - } - writel(cmd, scu->ipc_base); + reinit_completion(&scu->cmd_complete); + writel(cmd | IPC_IOC, scu->ipc_base); } /* @@ -185,7 +181,7 @@ return 0; } -/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */ +/* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ static inline int ipc_wait_for_interrupt(struct intel_scu_ipc_dev *scu) { int status; @@ -610,9 +606,10 @@ static irqreturn_t ioc(int irq, void *dev_id) { struct intel_scu_ipc_dev *scu = dev_id; + int status = ipc_read_status(scu); - if (scu->irq_mode) - complete(&scu->cmd_complete); + writel(status | IPC_STATUS_IRQ, scu->ipc_base + IPC_STATUS); + complete(&scu->cmd_complete); return IRQ_HANDLED; } @@ -638,8 +635,6 @@ if (!pdata) return -ENODEV; - scu->irq_mode = pdata->irq_mode; - err = pcim_enable_device(pdev); if (err) return err; --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_speed_select_if/isst_if_common.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_speed_select_if/isst_if_common.c @@ -529,7 +529,10 @@ return ret; } -static DEFINE_MUTEX(punit_misc_dev_lock); +/* Lock to prevent module registration when already opened by user space */ +static DEFINE_MUTEX(punit_misc_dev_open_lock); +/* Lock to allow one share misc device for all ISST interace */ +static DEFINE_MUTEX(punit_misc_dev_reg_lock); static int misc_usage_count; static int misc_device_ret; static int misc_device_open; @@ -539,7 +542,7 @@ int i, ret = 0; /* Fail open, if a module is going away */ - mutex_lock(&punit_misc_dev_lock); + mutex_lock(&punit_misc_dev_open_lock); for (i = 0; i < ISST_IF_DEV_MAX; ++i) { struct isst_if_cmd_cb *cb = &punit_callbacks[i]; @@ -561,7 +564,7 @@ } else { misc_device_open++; } - mutex_unlock(&punit_misc_dev_lock); + mutex_unlock(&punit_misc_dev_open_lock); return ret; } @@ -570,7 +573,7 @@ { int i; - mutex_lock(&punit_misc_dev_lock); + mutex_lock(&punit_misc_dev_open_lock); misc_device_open--; for (i = 0; i < ISST_IF_DEV_MAX; ++i) { struct isst_if_cmd_cb *cb = &punit_callbacks[i]; @@ -578,7 +581,7 @@ if (cb->registered) module_put(cb->owner); } - mutex_unlock(&punit_misc_dev_lock); + mutex_unlock(&punit_misc_dev_open_lock); return 0; } @@ -595,6 +598,43 @@ .fops = &isst_if_char_driver_ops, }; +static int isst_misc_reg(void) +{ + mutex_lock(&punit_misc_dev_reg_lock); + if (misc_device_ret) + goto unlock_exit; + + if (!misc_usage_count) { + misc_device_ret = isst_if_cpu_info_init(); + if (misc_device_ret) + goto unlock_exit; + + misc_device_ret = misc_register(&isst_if_char_driver); + if (misc_device_ret) { + isst_if_cpu_info_exit(); + goto unlock_exit; + } + } + misc_usage_count++; + +unlock_exit: + mutex_unlock(&punit_misc_dev_reg_lock); + + return misc_device_ret; +} + +static void isst_misc_unreg(void) +{ + mutex_lock(&punit_misc_dev_reg_lock); + if (misc_usage_count) + misc_usage_count--; + if (!misc_usage_count && !misc_device_ret) { + misc_deregister(&isst_if_char_driver); + isst_if_cpu_info_exit(); + } + mutex_unlock(&punit_misc_dev_reg_lock); +} + /** * isst_if_cdev_register() - Register callback for IOCTL * @device_type: The device type this callback handling. @@ -612,38 +652,31 @@ */ int isst_if_cdev_register(int device_type, struct isst_if_cmd_cb *cb) { - if (misc_device_ret) - return misc_device_ret; + int ret; if (device_type >= ISST_IF_DEV_MAX) return -EINVAL; - mutex_lock(&punit_misc_dev_lock); + mutex_lock(&punit_misc_dev_open_lock); + /* Device is already open, we don't want to add new callbacks */ if (misc_device_open) { - mutex_unlock(&punit_misc_dev_lock); + mutex_unlock(&punit_misc_dev_open_lock); return -EAGAIN; } - if (!misc_usage_count) { - int ret; - - misc_device_ret = misc_register(&isst_if_char_driver); - if (misc_device_ret) - goto unlock_exit; - - ret = isst_if_cpu_info_init(); - if (ret) { - misc_deregister(&isst_if_char_driver); - misc_device_ret = ret; - goto unlock_exit; - } - } memcpy(&punit_callbacks[device_type], cb, sizeof(*cb)); punit_callbacks[device_type].registered = 1; - misc_usage_count++; -unlock_exit: - mutex_unlock(&punit_misc_dev_lock); + mutex_unlock(&punit_misc_dev_open_lock); - return misc_device_ret; + ret = isst_misc_reg(); + if (ret) { + /* + * No need of mutex as the misc device register failed + * as no one can open device yet. Hence no contention. + */ + punit_callbacks[device_type].registered = 0; + return ret; + } + return 0; } EXPORT_SYMBOL_GPL(isst_if_cdev_register); @@ -658,16 +691,12 @@ */ void isst_if_cdev_unregister(int device_type) { - mutex_lock(&punit_misc_dev_lock); - misc_usage_count--; + isst_misc_unreg(); + mutex_lock(&punit_misc_dev_open_lock); punit_callbacks[device_type].registered = 0; if (device_type == ISST_IF_DEV_MBOX) isst_delete_hash(); - if (!misc_usage_count && !misc_device_ret) { - misc_deregister(&isst_if_char_driver); - isst_if_cpu_info_exit(); - } - mutex_unlock(&punit_misc_dev_lock); + mutex_unlock(&punit_misc_dev_open_lock); } EXPORT_SYMBOL_GPL(isst_if_cdev_unregister); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_speed_select_if/isst_if_common.h +++ linux-oracle-5.4.0/drivers/platform/x86/intel_speed_select_if/isst_if_common.h @@ -13,6 +13,9 @@ #define INTEL_RAPL_PRIO_DEVID_0 0x3451 #define INTEL_CFG_MBOX_DEVID_0 0x3459 +#define INTEL_RAPL_PRIO_DEVID_1 0x3251 +#define INTEL_CFG_MBOX_DEVID_1 0x3259 + /* * Validate maximum commands in a single request. * This is enough to handle command to every core in one ioctl, or all --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_speed_select_if/isst_if_mbox_pci.c @@ -148,6 +148,7 @@ static const struct pci_device_id isst_if_mbox_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_0)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CFG_MBOX_DEVID_1)}, { 0 }, }; MODULE_DEVICE_TABLE(pci, isst_if_mbox_ids); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_speed_select_if/isst_if_mmio.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_speed_select_if/isst_if_mmio.c @@ -72,6 +72,7 @@ static const struct pci_device_id isst_if_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_0)}, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_1)}, { 0 }, }; MODULE_DEVICE_TABLE(pci, isst_if_ids); --- linux-oracle-5.4.0.orig/drivers/platform/x86/intel_telemetry_core.c +++ linux-oracle-5.4.0/drivers/platform/x86/intel_telemetry_core.c @@ -102,7 +102,7 @@ /** * telemetry_update_events() - Update telemetry Configuration * @pss_evtconfig: PSS related config. No change if num_evts = 0. - * @pss_evtconfig: IOSS related config. No change if num_evts = 0. + * @ioss_evtconfig: IOSS related config. No change if num_evts = 0. * * This API updates the IOSS & PSS Telemetry configuration. Old config * is overwritten. Call telemetry_reset_events when logging is over @@ -176,7 +176,7 @@ /** * telemetry_get_eventconfig() - Returns the pss and ioss events enabled * @pss_evtconfig: Pointer to PSS related configuration. - * @pss_evtconfig: Pointer to IOSS related configuration. + * @ioss_evtconfig: Pointer to IOSS related configuration. * @pss_len: Number of u32 elements allocated for pss_evtconfig array * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array * --- linux-oracle-5.4.0.orig/drivers/platform/x86/mlx-platform.c +++ linux-oracle-5.4.0/drivers/platform/x86/mlx-platform.c @@ -234,24 +234,6 @@ }; /* Platform hotplug devices */ -static struct i2c_board_info mlxplat_mlxcpld_psu[] = { - { - I2C_BOARD_INFO("24c02", 0x51), - }, - { - I2C_BOARD_INFO("24c02", 0x50), - }, -}; - -static struct i2c_board_info mlxplat_mlxcpld_ng_psu[] = { - { - I2C_BOARD_INFO("24c32", 0x51), - }, - { - I2C_BOARD_INFO("24c32", 0x50), - }, -}; - static struct i2c_board_info mlxplat_mlxcpld_pwr[] = { { I2C_BOARD_INFO("dps460", 0x59), @@ -282,15 +264,13 @@ .label = "psu1", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(0), - .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0], - .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, { .label = "psu2", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(1), - .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1], - .hpdev.nr = MLXPLAT_CPLD_PSU_DEFAULT_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, }; @@ -357,7 +337,7 @@ .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF, .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = MLXPLAT_CPLD_PSU_MASK, - .count = ARRAY_SIZE(mlxplat_mlxcpld_psu), + .count = ARRAY_SIZE(mlxplat_mlxcpld_default_psu_items_data), .inversed = 1, .health = false, }, @@ -366,7 +346,7 @@ .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF, .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET, .mask = MLXPLAT_CPLD_PWR_MASK, - .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr), + .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_items_data), .inversed = 0, .health = false, }, @@ -375,7 +355,7 @@ .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF, .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET, .mask = MLXPLAT_CPLD_FAN_MASK, - .count = ARRAY_SIZE(mlxplat_mlxcpld_fan), + .count = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_items_data), .inversed = 1, .health = false, }, @@ -453,15 +433,13 @@ .label = "psu1", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(0), - .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0], - .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, { .label = "psu2", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(1), - .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1], - .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, }; @@ -611,15 +589,13 @@ .label = "psu1", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(0), - .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[0], - .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, { .label = "psu2", .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET, .mask = BIT(1), - .hpdev.brdinfo = &mlxplat_mlxcpld_ng_psu[1], - .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR, + .hpdev.nr = MLXPLAT_CPLD_NR_NONE, }, }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/msi-laptop.c +++ linux-oracle-5.4.0/drivers/platform/x86/msi-laptop.c @@ -210,7 +210,7 @@ return -EINVAL; if (quirks->ec_read_only) - return -EOPNOTSUPP; + return 0; /* read current device state */ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); @@ -596,11 +596,10 @@ { .ident = "MSI S270", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD"), + DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT"), DMI_MATCH(DMI_PRODUCT_NAME, "MS-1013"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, - "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT") }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb @@ -633,8 +632,7 @@ DMI_MATCH(DMI_SYS_VENDOR, "NOTEBOOK"), DMI_MATCH(DMI_PRODUCT_NAME, "SAM2000"), DMI_MATCH(DMI_PRODUCT_VERSION, "0131"), - DMI_MATCH(DMI_CHASSIS_VENDOR, - "MICRO-STAR INT'L CO.,LTD") + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR INT") }, .driver_data = &quirk_old_ec_model, .callback = dmi_check_cb @@ -843,15 +841,15 @@ static void msi_init_rfkill(struct work_struct *ignored) { if (rfk_wlan) { - rfkill_set_sw_state(rfk_wlan, !wlan_s); + msi_rfkill_set_state(rfk_wlan, !wlan_s); rfkill_wlan_set(NULL, !wlan_s); } if (rfk_bluetooth) { - rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); + msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); rfkill_bluetooth_set(NULL, !bluetooth_s); } if (rfk_threeg) { - rfkill_set_sw_state(rfk_threeg, !threeg_s); + msi_rfkill_set_state(rfk_threeg, !threeg_s); rfkill_threeg_set(NULL, !threeg_s); } } @@ -1048,8 +1046,7 @@ return -EINVAL; /* Register backlight stuff */ - - if (quirks->old_ec_model || + if (quirks->old_ec_model && acpi_video_get_backlight_type() == acpi_backlight_vendor) { struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); @@ -1117,6 +1114,8 @@ fail_create_group: if (quirks->load_scm_model) { i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_touchpad_dwork); + input_unregister_device(msi_laptop_input_dev); cancel_delayed_work_sync(&msi_rfkill_dwork); cancel_work_sync(&msi_rfkill_work); rfkill_cleanup(); @@ -1137,6 +1136,7 @@ { if (quirks->load_scm_model) { i8042_remove_filter(msi_laptop_i8042_filter); + cancel_delayed_work_sync(&msi_touchpad_dwork); input_unregister_device(msi_laptop_input_dev); cancel_delayed_work_sync(&msi_rfkill_dwork); cancel_work_sync(&msi_rfkill_work); --- linux-oracle-5.4.0.orig/drivers/platform/x86/mxm-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/mxm-wmi.c @@ -35,13 +35,11 @@ .xarg = 1, }; struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_status status; printk("calling mux switch %d\n", adapter); - status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, - &output); + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL); if (ACPI_FAILURE(status)) return status; @@ -60,13 +58,11 @@ .xarg = 1, }; struct acpi_buffer input = { (acpi_size)sizeof(args), &args }; - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_status status; printk("calling mux switch %d\n", adapter); - status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, - &output); + status = wmi_evaluate_method(MXM_WMMX_GUID, 0x0, adapter, &input, NULL); if (ACPI_FAILURE(status)) return status; --- linux-oracle-5.4.0.orig/drivers/platform/x86/pcengines-apuv2.c +++ linux-oracle-5.4.0/drivers/platform/x86/pcengines-apuv2.c @@ -78,7 +78,6 @@ { .name = "apu:green:1" }, { .name = "apu:green:2" }, { .name = "apu:green:3" }, - { .name = "apu:simswap" }, }; static const struct gpio_led_platform_data apu2_leds_pdata = { @@ -95,8 +94,7 @@ NULL, 1, GPIO_ACTIVE_LOW), GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3, NULL, 2, GPIO_ACTIVE_LOW), - GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_REG_SIMSWAP, - NULL, 3, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ } }; @@ -126,6 +124,7 @@ .table = { GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_MODESW, NULL, 0, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ } }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/peaq-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/peaq-wmi.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include @@ -18,8 +18,7 @@ MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID); -static unsigned int peaq_ignore_events_counter; -static struct input_polled_dev *peaq_poll_dev; +static struct input_dev *peaq_poll_dev; /* * The Dolby button (yes really a Dolby button) causes an ACPI variable to get @@ -28,8 +27,10 @@ * (if polling after the release) or twice (polling between press and release). * We ignore events for 0.5s after the first event to avoid reporting 2 presses. */ -static void peaq_wmi_poll(struct input_polled_dev *dev) +static void peaq_wmi_poll(struct input_dev *input_dev) { + static unsigned long last_event_time; + static bool had_events; union acpi_object obj; acpi_status status; u32 dummy = 0; @@ -44,22 +45,25 @@ return; if (obj.type != ACPI_TYPE_INTEGER) { - dev_err(&peaq_poll_dev->input->dev, + dev_err(&input_dev->dev, "Error WMBC did not return an integer\n"); return; } - if (peaq_ignore_events_counter && peaq_ignore_events_counter--) + if (!obj.integer.value) return; - if (obj.integer.value) { - input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 1); - input_sync(peaq_poll_dev->input); - input_event(peaq_poll_dev->input, EV_KEY, KEY_SOUND, 0); - input_sync(peaq_poll_dev->input); - peaq_ignore_events_counter = max(1u, - PEAQ_POLL_IGNORE_MS / peaq_poll_dev->poll_interval); - } + if (had_events && time_before(jiffies, last_event_time + + msecs_to_jiffies(PEAQ_POLL_IGNORE_MS))) + return; + + input_event(input_dev, EV_KEY, KEY_SOUND, 1); + input_sync(input_dev); + input_event(input_dev, EV_KEY, KEY_SOUND, 0); + input_sync(input_dev); + + last_event_time = jiffies; + had_events = true; } /* Some other devices (Shuttle XS35) use the same WMI GUID for other purposes */ @@ -75,6 +79,8 @@ static int __init peaq_wmi_init(void) { + int err; + /* WMI GUID is not unique, also check for a DMI match */ if (!dmi_check_system(peaq_dmi_table)) return -ENODEV; @@ -82,24 +88,36 @@ if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID)) return -ENODEV; - peaq_poll_dev = input_allocate_polled_device(); + peaq_poll_dev = input_allocate_device(); if (!peaq_poll_dev) return -ENOMEM; - peaq_poll_dev->poll = peaq_wmi_poll; - peaq_poll_dev->poll_interval = PEAQ_POLL_INTERVAL_MS; - peaq_poll_dev->poll_interval_max = PEAQ_POLL_MAX_MS; - peaq_poll_dev->input->name = "PEAQ WMI hotkeys"; - peaq_poll_dev->input->phys = "wmi/input0"; - peaq_poll_dev->input->id.bustype = BUS_HOST; - input_set_capability(peaq_poll_dev->input, EV_KEY, KEY_SOUND); - - return input_register_polled_device(peaq_poll_dev); + peaq_poll_dev->name = "PEAQ WMI hotkeys"; + peaq_poll_dev->phys = "wmi/input0"; + peaq_poll_dev->id.bustype = BUS_HOST; + input_set_capability(peaq_poll_dev, EV_KEY, KEY_SOUND); + + err = input_setup_polling(peaq_poll_dev, peaq_wmi_poll); + if (err) + goto err_out; + + input_set_poll_interval(peaq_poll_dev, PEAQ_POLL_INTERVAL_MS); + input_set_max_poll_interval(peaq_poll_dev, PEAQ_POLL_MAX_MS); + + err = input_register_device(peaq_poll_dev); + if (err) + goto err_out; + + return 0; + +err_out: + input_free_device(peaq_poll_dev); + return err; } static void __exit peaq_wmi_exit(void) { - input_unregister_polled_device(peaq_poll_dev); + input_unregister_device(peaq_poll_dev); } module_init(peaq_wmi_init); --- linux-oracle-5.4.0.orig/drivers/platform/x86/pmc_atom.c +++ linux-oracle-5.4.0/drivers/platform/x86/pmc_atom.c @@ -244,7 +244,7 @@ pm1_cnt_port = acpi_base_addr + PM1_CNT; pm1_cnt_value = inl(pm1_cnt_port); - pm1_cnt_value &= SLEEP_TYPE_MASK; + pm1_cnt_value &= ~SLEEP_TYPE_MASK; pm1_cnt_value |= SLEEP_TYPE_S5; pm1_cnt_value |= SLEEP_ENABLE; @@ -385,34 +385,18 @@ }, { /* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Beckhoff CB3163", + .ident = "Lex 2I385SW", .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"), - DMI_MATCH(DMI_BOARD_NAME, "CB3163"), - }, - }, - { - /* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Beckhoff CB4063", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"), - DMI_MATCH(DMI_BOARD_NAME, "CB4063"), - }, - }, - { - /* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Beckhoff CB6263", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"), - DMI_MATCH(DMI_BOARD_NAME, "CB6263"), + DMI_MATCH(DMI_SYS_VENDOR, "Lex BayTrail"), + DMI_MATCH(DMI_PRODUCT_NAME, "2I385SW"), }, }, { /* pmc_plt_clk* - are used for ethernet controllers */ - .ident = "Beckhoff CB6363", + .ident = "Beckhoff Baytrail", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Beckhoff Automation"), - DMI_MATCH(DMI_BOARD_NAME, "CB6363"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "CBxx63"), }, }, { @@ -429,6 +413,14 @@ DMI_MATCH(DMI_PRODUCT_VERSION, "6AV7882-0"), }, }, + { + .ident = "CONNECT X300", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SIEMENS AG"), + DMI_MATCH(DMI_PRODUCT_VERSION, "A5E45074588"), + }, + }, + { /*sentinel*/ } }; --- linux-oracle-5.4.0.orig/drivers/platform/x86/samsung-laptop.c +++ linux-oracle-5.4.0/drivers/platform/x86/samsung-laptop.c @@ -1121,8 +1121,6 @@ if (value > samsung->kbd_led.max_brightness) value = samsung->kbd_led.max_brightness; - else if (value < 0) - value = 0; samsung->kbd_led_wk = value; queue_work(samsung->led_workqueue, &samsung->kbd_led_work); --- linux-oracle-5.4.0.orig/drivers/platform/x86/sony-laptop.c +++ linux-oracle-5.4.0/drivers/platform/x86/sony-laptop.c @@ -1899,14 +1899,21 @@ break; } - ret = sony_call_snc_handle(handle, probe_base, &result); - if (ret) - return ret; + /* + * Only probe if there is a separate probe_base, otherwise the probe call + * is equivalent to __sony_nc_kbd_backlight_mode_set(0), resulting in + * the keyboard backlight being turned off. + */ + if (probe_base) { + ret = sony_call_snc_handle(handle, probe_base, &result); + if (ret) + return ret; - if ((handle == 0x0137 && !(result & 0x02)) || - !(result & 0x01)) { - dprintk("no backlight keyboard found\n"); - return 0; + if ((handle == 0x0137 && !(result & 0x02)) || + !(result & 0x01)) { + dprintk("no backlight keyboard found\n"); + return 0; + } } kbdbl_ctl = kzalloc(sizeof(*kbdbl_ctl), GFP_KERNEL); --- linux-oracle-5.4.0.orig/drivers/platform/x86/thinkpad_acpi.c +++ linux-oracle-5.4.0/drivers/platform/x86/thinkpad_acpi.c @@ -1188,15 +1188,6 @@ return status; } -/* Query FW and update rfkill sw state for all rfkill switches */ -static void tpacpi_rfk_update_swstate_all(void) -{ - unsigned int i; - - for (i = 0; i < TPACPI_RFK_SW_MAX; i++) - tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]); -} - /* * Sync the HW-blocking state of all rfkill switches, * do notice it causes the rfkill core to schedule uevents @@ -2587,7 +2578,7 @@ */ static int hotkey_kthread(void *data) { - struct tp_nvram_state s[2]; + struct tp_nvram_state s[2] = { 0 }; u32 poll_mask, event_mask; unsigned int si, so; unsigned long t; @@ -3135,9 +3126,6 @@ if (wlsw == TPACPI_RFK_RADIO_OFF) tpacpi_rfk_update_hwblock_state(true); - /* Sync sw blocking state */ - tpacpi_rfk_update_swstate_all(); - /* Sync hw blocking state last if it is hw-unblocked */ if (wlsw == TPACPI_RFK_RADIO_ON) tpacpi_rfk_update_hwblock_state(false); @@ -3232,7 +3220,14 @@ in_tablet_mode = hotkey_gmms_get_tablet_mode(res, &has_tablet_mode); - if (has_tablet_mode) + /* + * The Yoga 11e series has 2 accelerometers described by a + * BOSC0200 ACPI node. This setup relies on a Windows service + * which calls special ACPI methods on this node to report + * the laptop/tent/tablet mode to the EC. The bmc150 iio driver + * does not support this, so skip the hotkey on these models. + */ + if (has_tablet_mode && !acpi_dev_present("BOSC0200", "1", -1)) tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GMMS; type = "GMMS"; } else if (acpi_evalf(hkey_handle, &res, "MHKG", "qd")) { @@ -4082,13 +4077,19 @@ case TP_HKEY_EV_KEY_NUMLOCK: case TP_HKEY_EV_KEY_FN: - case TP_HKEY_EV_KEY_FN_ESC: /* key press events, we just ignore them as long as the EC * is still reporting them in the normal keyboard stream */ *send_acpi_ev = false; *ignore_acpi_ev = true; return true; + case TP_HKEY_EV_KEY_FN_ESC: + /* Get the media key status to foce the status LED to update */ + acpi_evalf(hkey_handle, NULL, "GMKS", "v"); + *send_acpi_ev = false; + *ignore_acpi_ev = true; + return true; + case TP_HKEY_EV_TABLET_CHANGED: tpacpi_input_send_tabletsw(); hotkey_tablet_mode_notify_change(); @@ -4238,6 +4239,7 @@ pr_err("error while attempting to reset the event firmware interface\n"); tpacpi_send_radiosw_update(); + tpacpi_input_send_tabletsw(); hotkey_tablet_mode_notify_change(); hotkey_wakeup_reason_notify_change(); hotkey_wakeup_hotunplug_complete_notify_change(); @@ -6270,6 +6272,7 @@ enum { /* TPACPI_THERMAL_TPEC_* */ TP_EC_THERMAL_TMP0 = 0x78, /* ACPI EC regs TMP 0..7 */ TP_EC_THERMAL_TMP8 = 0xC0, /* ACPI EC regs TMP 8..15 */ + TP_EC_FUNCREV = 0xEF, /* ACPI EC Functional revision */ TP_EC_THERMAL_TMP_NA = -128, /* ACPI EC sensor not available */ TPACPI_THERMAL_SENSOR_NA = -128000, /* Sensor not available */ @@ -6468,7 +6471,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) { - u8 t, ta1, ta2; + u8 t, ta1, ta2, ver = 0; int i; int acpi_tmp7; int res; @@ -6483,7 +6486,14 @@ * 0x78-0x7F, 0xC0-0xC7. Registers return 0x00 for * non-implemented, thermal sensors return 0x80 when * not available + * The above rule is unfortunately flawed. This has been seen with + * 0xC2 (power supply ID) causing thermal control problems. + * The EC version can be determined by offset 0xEF and at least for + * version 3 the Lenovo firmware team confirmed that registers 0xC0-0xC7 + * are not thermal registers. */ + if (!acpi_ec_read(TP_EC_FUNCREV, &ver)) + pr_warn("Thinkpad ACPI EC unable to access EC version\n"); ta1 = ta2 = 0; for (i = 0; i < 8; i++) { @@ -6493,11 +6503,13 @@ ta1 = 0; break; } - if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) { - ta2 |= t; - } else { - ta1 = 0; - break; + if (ver < 3) { + if (acpi_ec_read(TP_EC_THERMAL_TMP8 + i, &t)) { + ta2 |= t; + } else { + ta1 = 0; + break; + } } } if (ta1 == 0) { @@ -6510,9 +6522,12 @@ thermal_read_mode = TPACPI_THERMAL_NONE; } } else { - thermal_read_mode = - (ta2 != 0) ? - TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; + if (ver >= 3) + thermal_read_mode = TPACPI_THERMAL_TPEC_8; + else + thermal_read_mode = + (ta2 != 0) ? + TPACPI_THERMAL_TPEC_16 : TPACPI_THERMAL_TPEC_8; } } else if (acpi_tmp7) { if (tpacpi_is_ibm() && @@ -6863,8 +6878,10 @@ list_for_each_entry(child, &device->children, node) { acpi_status status = acpi_evaluate_object(child->handle, "_BCL", NULL, &buffer); - if (ACPI_FAILURE(status)) + if (ACPI_FAILURE(status)) { + buffer.length = ACPI_ALLOCATE_BUFFER; continue; + } obj = (union acpi_object *)buffer.pointer; if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { @@ -6997,10 +7014,13 @@ pr_warn("Cannot enable backlight brightness support, ACPI is already handling it. Refer to the acpi_backlight kernel parameter.\n"); return 1; } - } else if (tp_features.bright_acpimode && brightness_enable > 1) { - pr_notice("Standard ACPI backlight interface not available, thinkpad_acpi native brightness control enabled\n"); + } else if (!tp_features.bright_acpimode) { + pr_notice("ACPI backlight interface not available\n"); + return 1; } + pr_notice("ACPI native brightness control enabled\n"); + /* * Check for module parameter bogosity, note that we * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be @@ -9057,7 +9077,7 @@ if (strlencmp(cmd, "level auto") == 0) level = TP_EC_FAN_AUTO; - else if ((strlencmp(cmd, "level disengaged") == 0) | + else if ((strlencmp(cmd, "level disengaged") == 0) || (strlencmp(cmd, "level full-speed") == 0)) level = TP_EC_FAN_FULLSPEED; else if (sscanf(cmd, "level %d", &level) != 1) @@ -9682,11 +9702,14 @@ * Individual addressing is broken on models that expose the * primary battery as BAT1. */ + TPACPI_Q_LNV('G', '8', true), /* ThinkPad X131e */ + TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */ TPACPI_Q_LNV('J', '7', true), /* B5400 */ TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */ TPACPI_Q_LNV3('R', '0', 'B', true), /* Thinkpad 11e gen 3 */ TPACPI_Q_LNV3('R', '0', 'C', true), /* Thinkpad 13 */ TPACPI_Q_LNV3('R', '0', 'J', true), /* Thinkpad 13 gen 2 */ + TPACPI_Q_LNV3('R', '0', 'K', true), /* Thinkpad 11e gen 4 celeron BIOS */ }; static int __init tpacpi_battery_init(struct ibm_init_struct *ibm) --- linux-oracle-5.4.0.orig/drivers/platform/x86/toshiba_acpi.c +++ linux-oracle-5.4.0/drivers/platform/x86/toshiba_acpi.c @@ -1485,7 +1485,7 @@ struct toshiba_acpi_dev *dev = PDE_DATA(file_inode(file)); char *buffer; char *cmd; - int lcd_out, crt_out, tv_out; + int lcd_out = -1, crt_out = -1, tv_out = -1; int remain = count; int value; int ret; @@ -1517,7 +1517,6 @@ kfree(cmd); - lcd_out = crt_out = tv_out = -1; ret = get_video_status(dev, &video_out); if (!ret) { unsigned int new_video_out = video_out; @@ -2842,6 +2841,7 @@ if (!dev->info_supported && !dev->system_event_supported) { pr_warn("No hotkey query interface found\n"); + error = -EINVAL; goto err_remove_filter; } --- linux-oracle-5.4.0.orig/drivers/platform/x86/touchscreen_dmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/touchscreen_dmi.c @@ -169,6 +169,23 @@ .properties = connect_tablet9_props, }; +static const struct property_entry csl_panther_tab_hd_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 1), + PROPERTY_ENTRY_U32("touchscreen-min-y", 20), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1526), + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-csl-panther-tab-hd.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + { } +}; + +static const struct ts_dmi_data csl_panther_tab_hd_data = { + .acpi_name = "MSSL1680:00", + .properties = csl_panther_tab_hd_props, +}; + static const struct property_entry cube_iwork8_air_props[] = { PROPERTY_ENTRY_U32("touchscreen-min-x", 1), PROPERTY_ENTRY_U32("touchscreen-min-y", 3), @@ -215,6 +232,22 @@ .properties = dexp_ursus_7w_props, }; +static const struct property_entry dexp_ursus_kx210i_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 5), + PROPERTY_ENTRY_U32("touchscreen-min-y", 2), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1720), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1137), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-dexp-ursus-kx210i.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), + { } +}; + +static const struct ts_dmi_data dexp_ursus_kx210i_data = { + .acpi_name = "MSSL1680:00", + .properties = dexp_ursus_kx210i_props, +}; + static const struct property_entry digma_citi_e200_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 1980), PROPERTY_ENTRY_U32("touchscreen-size-y", 1500), @@ -231,6 +264,16 @@ .properties = digma_citi_e200_props, }; +static const struct property_entry estar_beauty_hd_props[] = { + PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + { } +}; + +static const struct ts_dmi_data estar_beauty_hd_data = { + .acpi_name = "GDIX1001:00", + .properties = estar_beauty_hd_props, +}; + static const struct property_entry gp_electronic_t701_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 960), PROPERTY_ENTRY_U32("touchscreen-size-y", 640), @@ -264,6 +307,21 @@ .properties = irbis_tw90_props, }; +static const struct property_entry irbis_tw118_props[] = { + PROPERTY_ENTRY_U32("touchscreen-min-x", 20), + PROPERTY_ENTRY_U32("touchscreen-min-y", 30), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1960), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1510), + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-irbis-tw118.fw"), + PROPERTY_ENTRY_U32("silead,max-fingers", 10), + { } +}; + +static const struct ts_dmi_data irbis_tw118_data = { + .acpi_name = "MSSL1680:00", + .properties = irbis_tw118_props, +}; + static const struct property_entry itworks_tw891_props[] = { PROPERTY_ENTRY_U32("touchscreen-min-x", 1), PROPERTY_ENTRY_U32("touchscreen-min-y", 5), @@ -697,6 +755,14 @@ }, }, { + /* CSL Panther Tab HD */ + .driver_data = (void *)&csl_panther_tab_hd_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CSL Computer GmbH & Co. KG"), + DMI_MATCH(DMI_PRODUCT_NAME, "CSL Panther Tab HD"), + }, + }, + { /* CUBE iwork8 Air */ .driver_data = (void *)&cube_iwork8_air_data, .matches = { @@ -724,6 +790,14 @@ }, }, { + /* DEXP Ursus KX210i */ + .driver_data = (void *)&dexp_ursus_kx210i_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "INSYDE Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "S107I"), + }, + }, + { /* Digma Citi E200 */ .driver_data = (void *)&digma_citi_e200_data, .matches = { @@ -733,6 +807,14 @@ }, }, { + /* Estar Beauty HD (MID 7316R) */ + .driver_data = (void *)&estar_beauty_hd_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Estar"), + DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), + }, + }, + { /* GP-electronic T701 */ .driver_data = (void *)&gp_electronic_t701_data, .matches = { @@ -759,6 +841,14 @@ }, }, { + /* Irbis TW118 */ + .driver_data = (void *)&irbis_tw118_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"), + DMI_MATCH(DMI_PRODUCT_NAME, "TW118"), + }, + }, + { /* I.T.Works TW891 */ .driver_data = (void *)&itworks_tw891_data, .matches = { @@ -798,6 +888,14 @@ }, }, { + /* Mediacom WinPad 7.0 W700 (same hw as Wintron surftab 7") */ + .driver_data = (void *)&trekstor_surftab_wintron70_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIACOM"), + DMI_MATCH(DMI_PRODUCT_NAME, "WinPad 7 W10 - WPW700"), + }, + }, + { /* Mediacom Flexbook Edge 11 (same hw as TS Primebook C11) */ .driver_data = (void *)&trekstor_primebook_c11_data, .matches = { --- linux-oracle-5.4.0.orig/drivers/platform/x86/wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/wmi.c @@ -39,7 +39,7 @@ static LIST_HEAD(wmi_block_list); struct guid_block { - char guid[16]; + guid_t guid; union { char object_id[2]; struct { @@ -110,17 +110,17 @@ static bool find_guid(const char *guid_string, struct wmi_block **out) { - uuid_le guid_input; + guid_t guid_input; struct wmi_block *wblock; struct guid_block *block; - if (uuid_le_to_bin(guid_string, &guid_input)) + if (guid_parse(guid_string, &guid_input)) return false; list_for_each_entry(wblock, &wmi_block_list, list) { block = &wblock->gblock; - if (memcmp(block->guid, &guid_input, 16) == 0) { + if (guid_equal(&block->guid, &guid_input)) { if (out) *out = wblock; return true; @@ -129,11 +129,20 @@ return false; } +static bool guid_parse_and_compare(const char *string, const guid_t *guid) +{ + guid_t guid_input; + + if (guid_parse(string, &guid_input)) + return false; + + return guid_equal(&guid_input, guid); +} + static const void *find_guid_context(struct wmi_block *wblock, struct wmi_driver *wdriver) { const struct wmi_device_id *id; - uuid_le guid_input; if (wblock == NULL || wdriver == NULL) return NULL; @@ -142,9 +151,7 @@ id = wdriver->id_table; while (*id->guid_string) { - if (uuid_le_to_bin(id->guid_string, &guid_input)) - continue; - if (!memcmp(wblock->gblock.guid, &guid_input, 16)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return id->context; id++; } @@ -177,7 +184,7 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) { - struct guid_block *block = NULL; + struct guid_block *block; char method[5]; acpi_status status; acpi_handle handle; @@ -251,8 +258,8 @@ acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 method_id, const struct acpi_buffer *in, struct acpi_buffer *out) { - struct guid_block *block = NULL; - struct wmi_block *wblock = NULL; + struct guid_block *block; + struct wmi_block *wblock; acpi_handle handle; acpi_status status; struct acpi_object_list input; @@ -299,7 +306,7 @@ static acpi_status __query_block(struct wmi_block *wblock, u8 instance, struct acpi_buffer *out) { - struct guid_block *block = NULL; + struct guid_block *block; acpi_handle handle; acpi_status status, wc_status = AE_ERROR; struct acpi_object_list input; @@ -353,7 +360,14 @@ * the WQxx method failed - we should disable collection anyway. */ if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { - status = acpi_execute_simple_method(handle, wc_method, 0); + /* + * Ignore whether this WCxx call succeeds or not since + * the previously executed WQxx method call might have + * succeeded, and returning the failing status code + * of this call would throw away the result of the WQxx + * call, potentially leaking memory. + */ + acpi_execute_simple_method(handle, wc_method, 0); } return status; @@ -405,8 +419,8 @@ acpi_status wmi_set_block(const char *guid_string, u8 instance, const struct acpi_buffer *in) { - struct guid_block *block = NULL; struct wmi_block *wblock = NULL; + struct guid_block *block; acpi_handle handle; struct acpi_object_list input; union acpi_object params[2]; @@ -449,7 +463,7 @@ static void wmi_dump_wdg(const struct guid_block *g) { - pr_info("%pUL:\n", g->guid); + pr_info("%pUL:\n", &g->guid); if (g->flags & ACPI_WMI_EVENT) pr_info("\tnotify_id: 0x%02X\n", g->notify_id); else @@ -519,18 +533,18 @@ { struct wmi_block *block; acpi_status status = AE_NOT_EXIST; - uuid_le guid_input; + guid_t guid_input; if (!guid || !handler) return AE_BAD_PARAMETER; - if (uuid_le_to_bin(guid, &guid_input)) + if (guid_parse(guid, &guid_input)) return AE_BAD_PARAMETER; list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status; - if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (block->handler && block->handler != wmi_notify_debug) return AE_ALREADY_ACQUIRED; @@ -558,18 +572,18 @@ { struct wmi_block *block; acpi_status status = AE_NOT_EXIST; - uuid_le guid_input; + guid_t guid_input; if (!guid) return AE_BAD_PARAMETER; - if (uuid_le_to_bin(guid, &guid_input)) + if (guid_parse(guid, &guid_input)) return AE_BAD_PARAMETER; list_for_each_entry(block, &wmi_block_list, list) { acpi_status wmi_status; - if (memcmp(block->gblock.guid, &guid_input, 16) == 0) { + if (guid_equal(&block->gblock.guid, &guid_input)) { if (!block->handler || block->handler == wmi_notify_debug) return AE_NULL_ENTRY; @@ -605,7 +619,6 @@ { struct acpi_object_list input; union acpi_object params[1]; - struct guid_block *gblock; struct wmi_block *wblock; input.count = 1; @@ -614,7 +627,7 @@ params[0].integer.value = event; list_for_each_entry(wblock, &wmi_block_list, list) { - gblock = &wblock->gblock; + struct guid_block *gblock = &wblock->gblock; if ((gblock->flags & ACPI_WMI_EVENT) && (gblock->notify_id == event)) @@ -675,7 +688,7 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid); + return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(modalias); @@ -684,7 +697,7 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - return sprintf(buf, "%pUL\n", wblock->gblock.guid); + return sprintf(buf, "%pUL\n", &wblock->gblock.guid); } static DEVICE_ATTR_RO(guid); @@ -767,10 +780,10 @@ { struct wmi_block *wblock = dev_to_wblock(dev); - if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid)) return -ENOMEM; - if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid)) + if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid)) return -ENOMEM; return 0; @@ -794,11 +807,7 @@ return 0; while (*id->guid_string) { - uuid_le driver_guid; - - if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid))) - continue; - if (!memcmp(&driver_guid, wblock->gblock.guid, 16)) + if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid)) return 1; id++; @@ -808,21 +817,13 @@ } static int wmi_char_open(struct inode *inode, struct file *filp) { - const char *driver_name = filp->f_path.dentry->d_iname; - struct wmi_block *wblock = NULL; - struct wmi_block *next = NULL; - - list_for_each_entry_safe(wblock, next, &wmi_block_list, list) { - if (!wblock->dev.dev.driver) - continue; - if (strcmp(driver_name, wblock->dev.dev.driver->name) == 0) { - filp->private_data = wblock; - break; - } - } + /* + * The miscdevice already stores a pointer to itself + * inside filp->private_data + */ + struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev); - if (!filp->private_data) - return -ENODEV; + filp->private_data = wblock; return nonseekable_open(inode, filp); } @@ -842,8 +843,8 @@ struct wmi_ioctl_buffer __user *input = (struct wmi_ioctl_buffer __user *) arg; struct wmi_block *wblock = filp->private_data; - struct wmi_ioctl_buffer *buf = NULL; - struct wmi_driver *wdriver = NULL; + struct wmi_ioctl_buffer *buf; + struct wmi_driver *wdriver; int ret; if (_IOC_TYPE(cmd) != WMI_IOC) @@ -1032,7 +1033,6 @@ }; static int wmi_create_device(struct device *wmi_bus_dev, - const struct guid_block *gblock, struct wmi_block *wblock, struct acpi_device *device) { @@ -1040,12 +1040,12 @@ char method[5]; int result; - if (gblock->flags & ACPI_WMI_EVENT) { + if (wblock->gblock.flags & ACPI_WMI_EVENT) { wblock->dev.dev.type = &wmi_type_event; goto out_init; } - if (gblock->flags & ACPI_WMI_METHOD) { + if (wblock->gblock.flags & ACPI_WMI_METHOD) { wblock->dev.dev.type = &wmi_type_method; mutex_init(&wblock->char_mutex); goto out_init; @@ -1095,7 +1095,7 @@ wblock->dev.dev.bus = &wmi_bus_type; wblock->dev.dev.parent = wmi_bus_dev; - dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid); + dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid); device_initialize(&wblock->dev.dev); @@ -1115,13 +1115,12 @@ } } -static bool guid_already_parsed(struct acpi_device *device, - const u8 *guid) +static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid) { struct wmi_block *wblock; list_for_each_entry(wblock, &wmi_block_list, list) { - if (memcmp(wblock->gblock.guid, guid, 16) == 0) { + if (guid_equal(&wblock->gblock.guid, guid)) { /* * Because we historically didn't track the relationship * between GUIDs and ACPI nodes, we don't know whether @@ -1147,8 +1146,8 @@ struct wmi_block *wblock, *next; union acpi_object *obj; acpi_status status; - int retval = 0; u32 i, total; + int retval; status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out); if (ACPI_FAILURE(status)) @@ -1159,8 +1158,8 @@ return -ENXIO; if (obj->type != ACPI_TYPE_BUFFER) { - retval = -ENXIO; - goto out_free_pointer; + kfree(obj); + return -ENXIO; } gblock = (const struct guid_block *)obj->buffer.pointer; @@ -1176,19 +1175,19 @@ * case yet, so for now, we'll just ignore the duplicate * for device creation. */ - if (guid_already_parsed(device, gblock[i].guid)) + if (guid_already_parsed(device, &gblock[i].guid)) continue; wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL); if (!wblock) { - retval = -ENOMEM; - break; + dev_err(wmi_bus_dev, "Failed to allocate %pUL\n", &gblock[i].guid); + continue; } wblock->acpi_device = device; wblock->gblock = gblock[i]; - retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device); + retval = wmi_create_device(wmi_bus_dev, wblock, device); if (retval) { kfree(wblock); continue; @@ -1213,7 +1212,7 @@ retval = device_add(&wblock->dev.dev); if (retval) { dev_err(wmi_bus_dev, "failed to register %pUL\n", - wblock->gblock.guid); + &wblock->gblock.guid); if (debug_event) wmi_method_enable(wblock, 0); list_del(&wblock->list); @@ -1221,9 +1220,9 @@ } } -out_free_pointer: - kfree(out.pointer); - return retval; + kfree(obj); + + return 0; } /* @@ -1273,12 +1272,11 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event, void *context) { - struct guid_block *block; struct wmi_block *wblock; bool found_it = false; list_for_each_entry(wblock, &wmi_block_list, list) { - block = &wblock->gblock; + struct guid_block *block = &wblock->gblock; if (wblock->acpi_device->handle == handle && (block->flags & ACPI_WMI_EVENT) && @@ -1326,10 +1324,8 @@ wblock->handler(event, wblock->handler_data); } - if (debug_event) { - pr_info("DEBUG Event GUID: %pUL\n", - wblock->gblock.guid); - } + if (debug_event) + pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid); acpi_bus_generate_netlink_event( wblock->acpi_device->pnp.device_class, --- linux-oracle-5.4.0.orig/drivers/platform/x86/xiaomi-wmi.c +++ linux-oracle-5.4.0/drivers/platform/x86/xiaomi-wmi.c @@ -23,7 +23,7 @@ unsigned int key_code; }; -int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) +static int xiaomi_wmi_probe(struct wmi_device *wdev, const void *context) { struct xiaomi_wmi *data; @@ -48,7 +48,7 @@ return input_register_device(data->input_dev); } -void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) +static void xiaomi_wmi_notify(struct wmi_device *wdev, union acpi_object *dummy) { struct xiaomi_wmi *data; --- linux-oracle-5.4.0.orig/drivers/pnp/core.c +++ linux-oracle-5.4.0/drivers/pnp/core.c @@ -160,14 +160,14 @@ dev->dev.coherent_dma_mask = dev->dma_mask; dev->dev.release = &pnp_release_device; - dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number); - dev_id = pnp_add_id(dev, pnpid); if (!dev_id) { kfree(dev); return NULL; } + dev_set_name(&dev->dev, "%02x:%02x", dev->protocol->number, dev->number); + return dev; } --- linux-oracle-5.4.0.orig/drivers/pnp/isapnp/core.c +++ linux-oracle-5.4.0/drivers/pnp/isapnp/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "../base.h" @@ -973,7 +974,7 @@ .disable = isapnp_disable_resources, }; -static int __init isapnp_init(void) +static int __init real_isapnp_init(void) { int cards; struct pnp_card *card; @@ -1067,6 +1068,16 @@ return 0; } +static void __init async_isapnp_init(void *unused, async_cookie_t cookie) +{ + (void)real_isapnp_init(); +} + +static int __init isapnp_init(void) +{ + async_schedule(async_isapnp_init, NULL); + return 0; +} device_initcall(isapnp_init); /* format is: noisapnp */ --- linux-oracle-5.4.0.orig/drivers/pnp/pnpacpi/rsparser.c +++ linux-oracle-5.4.0/drivers/pnp/pnpacpi/rsparser.c @@ -151,13 +151,13 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, struct acpi_resource_vendor_typed *vendor) { - if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { - u64 start, length; + struct { u64 start, length; } range; - memcpy(&start, vendor->byte_data, sizeof(start)); - memcpy(&length, vendor->byte_data + 8, sizeof(length)); - - pnp_add_mem_resource(dev, start, start + length - 1, 0); + if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, + sizeof(range))) { + memcpy(&range, vendor->byte_data, sizeof(range)); + pnp_add_mem_resource(dev, range.start, range.start + + range.length - 1, 0); } } --- linux-oracle-5.4.0.orig/drivers/power/avs/smartreflex.c +++ linux-oracle-5.4.0/drivers/power/avs/smartreflex.c @@ -213,10 +213,10 @@ if (sr_class->notify && sr_class->notify_flags && sr_info->irq) { ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq, - sr_interrupt, 0, sr_info->name, sr_info); + sr_interrupt, IRQF_NO_AUTOEN, + sr_info->name, sr_info); if (ret) goto error; - disable_irq(sr_info->irq); } if (pdata && pdata->enable_on_init) @@ -942,6 +942,7 @@ err_debugfs: debugfs_remove_recursive(sr_info->dbg_dir); err_list_del: + pm_runtime_disable(&pdev->dev); list_del(&sr_info->node); pm_runtime_put_sync(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/power/reset/arm-versatile-reboot.c +++ linux-oracle-5.4.0/drivers/power/reset/arm-versatile-reboot.c @@ -146,6 +146,7 @@ versatile_reboot_type = (enum versatile_reboot)reboot_id->data; syscon_regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(syscon_regmap)) return PTR_ERR(syscon_regmap); --- linux-oracle-5.4.0.orig/drivers/power/reset/at91-sama5d2_shdwc.c +++ linux-oracle-5.4.0/drivers/power/reset/at91-sama5d2_shdwc.c @@ -37,7 +37,7 @@ #define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */ #define AT91_SHDW_WKUPDBC_SHIFT 24 -#define AT91_SHDW_WKUPDBC_MASK GENMASK(31, 16) +#define AT91_SHDW_WKUPDBC_MASK GENMASK(26, 24) #define AT91_SHDW_WKUPDBC(x) (((x) << AT91_SHDW_WKUPDBC_SHIFT) \ & AT91_SHDW_WKUPDBC_MASK) --- linux-oracle-5.4.0.orig/drivers/power/reset/brcmstb-reboot.c +++ linux-oracle-5.4.0/drivers/power/reset/brcmstb-reboot.c @@ -72,9 +72,6 @@ return NOTIFY_DONE; } - while (1) - ; - return NOTIFY_DONE; } --- linux-oracle-5.4.0.orig/drivers/power/reset/gemini-poweroff.c +++ linux-oracle-5.4.0/drivers/power/reset/gemini-poweroff.c @@ -107,8 +107,8 @@ return PTR_ERR(gpw->base); irq = platform_get_irq(pdev, 0); - if (!irq) - return -EINVAL; + if (irq < 0) + return irq; gpw->dev = dev; --- linux-oracle-5.4.0.orig/drivers/power/reset/gpio-poweroff.c +++ linux-oracle-5.4.0/drivers/power/reset/gpio-poweroff.c @@ -90,6 +90,7 @@ { .compatible = "gpio-poweroff", }, {}, }; +MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match); static struct platform_driver gpio_poweroff_driver = { .probe = gpio_poweroff_probe, --- linux-oracle-5.4.0.orig/drivers/power/reset/ltc2952-poweroff.c +++ linux-oracle-5.4.0/drivers/power/reset/ltc2952-poweroff.c @@ -160,8 +160,8 @@ static void ltc2952_poweroff_default(struct ltc2952_poweroff *data) { - data->wde_interval = 300L * 1E6L; - data->trigger_delay = ktime_set(2, 500L*1E6L); + data->wde_interval = 300L * NSEC_PER_MSEC; + data->trigger_delay = ktime_set(2, 500L * NSEC_PER_MSEC); hrtimer_init(&data->timer_trigger, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->timer_trigger.function = ltc2952_poweroff_timer_trigger; --- linux-oracle-5.4.0.orig/drivers/power/reset/vexpress-poweroff.c +++ linux-oracle-5.4.0/drivers/power/reset/vexpress-poweroff.c @@ -143,6 +143,7 @@ .driver = { .name = "vexpress-reset", .of_match_table = vexpress_reset_of_match, + .suppress_bind_attrs = true, }, }; --- linux-oracle-5.4.0.orig/drivers/power/supply/88pm860x_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/88pm860x_battery.c @@ -433,7 +433,7 @@ int ret; int data; int bat_remove; - int soc; + int soc = 0; /* measure enable on GPADC1 */ data = MEAS1_GP1; @@ -496,7 +496,9 @@ } mutex_unlock(&info->lock); - calc_soc(info, OCV_MODE_ACTIVE, &soc); + ret = calc_soc(info, OCV_MODE_ACTIVE, &soc); + if (ret < 0) + goto out; data = pm860x_reg_read(info->i2c, PM8607_POWER_UP_LOG); bat_remove = data & BAT_WU_LOG; --- linux-oracle-5.4.0.orig/drivers/power/supply/Kconfig +++ linux-oracle-5.4.0/drivers/power/supply/Kconfig @@ -577,7 +577,7 @@ tristate "TI BQ24250/24251/24257 battery charger driver" depends on I2C depends on GPIOLIB || COMPILE_TEST - depends on REGMAP_I2C + select REGMAP_I2C help Say Y to enable support for the TI BQ24250, BQ24251, and BQ24257 battery chargers. @@ -643,7 +643,8 @@ config BATTERY_RT5033 tristate "RT5033 fuel gauge support" - depends on MFD_RT5033 + depends on I2C + select REGMAP_I2C help This adds support for battery fuel gauge in Richtek RT5033 PMIC. The fuelgauge calculates and determines the battery state of charge --- linux-oracle-5.4.0.orig/drivers/power/supply/ab8500_btemp.c +++ linux-oracle-5.4.0/drivers/power/supply/ab8500_btemp.c @@ -919,10 +919,8 @@ */ static void ab8500_btemp_external_power_changed(struct power_supply *psy) { - struct ab8500_btemp *di = power_supply_get_drvdata(psy); - - class_for_each_device(power_supply_class, NULL, - di->btemp_psy, ab8500_btemp_get_ext_psy_data); + class_for_each_device(power_supply_class, NULL, psy, + ab8500_btemp_get_ext_psy_data); } /* ab8500 btemp driver interrupts and their respective isr */ @@ -1120,6 +1118,7 @@ { .compatible = "stericsson,ab8500-btemp", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_btemp_match); static struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, --- linux-oracle-5.4.0.orig/drivers/power/supply/ab8500_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/ab8500_charger.c @@ -407,6 +407,14 @@ static void ab8500_power_supply_changed(struct ab8500_charger *di, struct power_supply *psy) { + /* + * This happens if we get notifications or interrupts and + * the platform has been configured not to support one or + * other type of charging. + */ + if (!psy) + return; + if (di->autopower_cfg) { if (!di->usb.charger_connected && !di->ac.charger_connected && @@ -433,7 +441,15 @@ if (!connected) di->flags.vbus_drop_end = false; - sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present"); + /* + * Sometimes the platform is configured not to support + * USB charging and no psy has been created, but we still + * will get these notifications. + */ + if (di->usb_chg.psy) { + sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, + "present"); + } if (connected) { mutex_lock(&di->charger_attached_mutex); @@ -3617,6 +3633,7 @@ { .compatible = "stericsson,ab8500-charger", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_charger_match); static struct platform_driver ab8500_charger_driver = { .probe = ab8500_charger_probe, --- linux-oracle-5.4.0.orig/drivers/power/supply/ab8500_fg.c +++ linux-oracle-5.4.0/drivers/power/supply/ab8500_fg.c @@ -2380,10 +2380,8 @@ */ static void ab8500_fg_external_power_changed(struct power_supply *psy) { - struct ab8500_fg *di = power_supply_get_drvdata(psy); - - class_for_each_device(power_supply_class, NULL, - di->fg_psy, ab8500_fg_get_ext_psy_data); + class_for_each_device(power_supply_class, NULL, psy, + ab8500_fg_get_ext_psy_data); } /** @@ -2541,8 +2539,10 @@ ret = kobject_init_and_add(&di->fg_kobject, &ab8500_fg_ktype, NULL, "battery"); - if (ret < 0) + if (ret < 0) { + kobject_put(&di->fg_kobject); dev_err(di->dev, "failed to create sysfs entry\n"); + } return ret; } @@ -3230,6 +3230,7 @@ { .compatible = "stericsson,ab8500-fg", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_fg_match); static struct platform_driver ab8500_fg_driver = { .probe = ab8500_fg_probe, --- linux-oracle-5.4.0.orig/drivers/power/supply/adp5061.c +++ linux-oracle-5.4.0/drivers/power/supply/adp5061.c @@ -427,11 +427,11 @@ if (ret < 0) return ret; - chg_type = adp5061_chg_type[ADP5061_CHG_STATUS_1_CHG_STATUS(status1)]; - if (chg_type > ADP5061_CHG_FAST_CV) + chg_type = ADP5061_CHG_STATUS_1_CHG_STATUS(status1); + if (chg_type >= ARRAY_SIZE(adp5061_chg_type)) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else - val->intval = chg_type; + val->intval = adp5061_chg_type[chg_type]; return ret; } --- linux-oracle-5.4.0.orig/drivers/power/supply/axp20x_ac_power.c +++ linux-oracle-5.4.0/drivers/power/supply/axp20x_ac_power.c @@ -23,6 +23,8 @@ #define AXP20X_PWR_STATUS_ACIN_PRESENT BIT(7) #define AXP20X_PWR_STATUS_ACIN_AVAIL BIT(6) +#define AXP813_ACIN_PATH_SEL BIT(7) + #define AXP813_VHOLD_MASK GENMASK(5, 3) #define AXP813_VHOLD_UV_TO_BIT(x) ((((x) / 100000) - 40) << 3) #define AXP813_VHOLD_REG_TO_UV(x) \ @@ -40,6 +42,7 @@ struct power_supply *supply; struct iio_channel *acin_v; struct iio_channel *acin_i; + bool has_acin_path_sel; }; static irqreturn_t axp20x_ac_power_irq(int irq, void *devid) @@ -86,6 +89,17 @@ return ret; val->intval = !!(reg & AXP20X_PWR_STATUS_ACIN_AVAIL); + + /* ACIN_PATH_SEL disables ACIN even if ACIN_AVAIL is set. */ + if (val->intval && power->has_acin_path_sel) { + ret = regmap_read(power->regmap, AXP813_ACIN_PATH_CTRL, + ®); + if (ret) + return ret; + + val->intval = !!(reg & AXP813_ACIN_PATH_SEL); + } + return 0; case POWER_SUPPLY_PROP_VOLTAGE_NOW: @@ -224,21 +238,25 @@ struct axp_data { const struct power_supply_desc *power_desc; bool acin_adc; + bool acin_path_sel; }; static const struct axp_data axp20x_data = { - .power_desc = &axp20x_ac_power_desc, - .acin_adc = true, + .power_desc = &axp20x_ac_power_desc, + .acin_adc = true, + .acin_path_sel = false, }; static const struct axp_data axp22x_data = { - .power_desc = &axp22x_ac_power_desc, - .acin_adc = false, + .power_desc = &axp22x_ac_power_desc, + .acin_adc = false, + .acin_path_sel = false, }; static const struct axp_data axp813_data = { - .power_desc = &axp813_ac_power_desc, - .acin_adc = false, + .power_desc = &axp813_ac_power_desc, + .acin_adc = false, + .acin_path_sel = true, }; static int axp20x_ac_power_probe(struct platform_device *pdev) @@ -282,6 +300,7 @@ } power->regmap = dev_get_regmap(pdev->dev.parent, NULL); + power->has_acin_path_sel = axp_data->acin_path_sel; platform_set_drvdata(pdev, power); --- linux-oracle-5.4.0.orig/drivers/power/supply/axp20x_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/axp20x_battery.c @@ -40,6 +40,7 @@ #define AXP209_FG_PERCENT GENMASK(6, 0) #define AXP22X_FG_VALID BIT(7) +#define AXP20X_CHRG_CTRL1_ENABLE BIT(7) #define AXP20X_CHRG_CTRL1_TGT_VOLT GENMASK(6, 5) #define AXP20X_CHRG_CTRL1_TGT_4_1V (0 << 5) #define AXP20X_CHRG_CTRL1_TGT_4_15V (1 << 5) @@ -185,7 +186,6 @@ union power_supply_propval *val) { struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); - struct iio_channel *chan; int ret = 0, reg, val1; switch (psp) { @@ -265,12 +265,12 @@ if (ret) return ret; - if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) - chan = axp20x_batt->batt_chrg_i; - else - chan = axp20x_batt->batt_dischrg_i; - - ret = iio_read_channel_processed(chan, &val->intval); + if (reg & AXP20X_PWR_STATUS_BAT_CHARGING) { + ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval); + } else { + ret = iio_read_channel_processed(axp20x_batt->batt_dischrg_i, &val1); + val->intval = -val1; + } if (ret) return ret; @@ -304,11 +304,11 @@ val->intval = reg & AXP209_FG_PERCENT; break; - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + case POWER_SUPPLY_PROP_VOLTAGE_MAX: return axp20x_batt->data->get_max_voltage(axp20x_batt, &val->intval); - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + case POWER_SUPPLY_PROP_VOLTAGE_MIN: ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®); if (ret) return ret; @@ -456,10 +456,10 @@ struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); switch (psp) { - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: + case POWER_SUPPLY_PROP_VOLTAGE_MIN: return axp20x_set_voltage_min_design(axp20x_batt, val->intval); - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: + case POWER_SUPPLY_PROP_VOLTAGE_MAX: return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: @@ -468,7 +468,18 @@ case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: return axp20x_set_max_constant_charge_current(axp20x_batt, val->intval); - + case POWER_SUPPLY_PROP_STATUS: + switch (val->intval) { + case POWER_SUPPLY_STATUS_CHARGING: + return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, + AXP20X_CHRG_CTRL1_ENABLE, AXP20X_CHRG_CTRL1_ENABLE); + + case POWER_SUPPLY_STATUS_DISCHARGING: + case POWER_SUPPLY_STATUS_NOT_CHARGING: + return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, + AXP20X_CHRG_CTRL1_ENABLE, 0); + } + fallthrough; default: return -EINVAL; } @@ -483,16 +494,17 @@ POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_HEALTH, - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, + POWER_SUPPLY_PROP_VOLTAGE_MAX, + POWER_SUPPLY_PROP_VOLTAGE_MIN, POWER_SUPPLY_PROP_CAPACITY, }; static int axp20x_battery_prop_writeable(struct power_supply *psy, enum power_supply_property psp) { - return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || - psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || + return psp == POWER_SUPPLY_PROP_STATUS || + psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || + psp == POWER_SUPPLY_PROP_VOLTAGE_MAX || psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; } --- linux-oracle-5.4.0.orig/drivers/power/supply/axp288_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/axp288_charger.c @@ -21,6 +21,7 @@ #include #include #include +#include #define PS_STAT_VBUS_TRIGGER BIT(0) #define PS_STAT_BAT_CHRG_DIR BIT(2) @@ -40,11 +41,11 @@ #define VBUS_ISPOUT_CUR_LIM_1500MA 0x1 /* 1500mA */ #define VBUS_ISPOUT_CUR_LIM_2000MA 0x2 /* 2000mA */ #define VBUS_ISPOUT_CUR_NO_LIM 0x3 /* 2500mA */ -#define VBUS_ISPOUT_VHOLD_SET_MASK 0x31 +#define VBUS_ISPOUT_VHOLD_SET_MASK 0x38 #define VBUS_ISPOUT_VHOLD_SET_BIT_POS 0x3 #define VBUS_ISPOUT_VHOLD_SET_OFFSET 4000 /* 4000mV */ #define VBUS_ISPOUT_VHOLD_SET_LSB_RES 100 /* 100mV */ -#define VBUS_ISPOUT_VHOLD_SET_4300MV 0x3 /* 4300mV */ +#define VBUS_ISPOUT_VHOLD_SET_4400MV 0x4 /* 4400mV */ #define VBUS_ISPOUT_VBUS_PATH_DIS BIT(7) #define CHRG_CCCV_CC_MASK 0xf /* 4 bits */ @@ -167,18 +168,18 @@ u8 reg_val; int ret; - if (cv <= CV_4100MV) { - reg_val = CHRG_CCCV_CV_4100MV; - cv = CV_4100MV; - } else if (cv <= CV_4150MV) { - reg_val = CHRG_CCCV_CV_4150MV; - cv = CV_4150MV; - } else if (cv <= CV_4200MV) { + if (cv >= CV_4350MV) { + reg_val = CHRG_CCCV_CV_4350MV; + cv = CV_4350MV; + } else if (cv >= CV_4200MV) { reg_val = CHRG_CCCV_CV_4200MV; cv = CV_4200MV; + } else if (cv >= CV_4150MV) { + reg_val = CHRG_CCCV_CV_4150MV; + cv = CV_4150MV; } else { - reg_val = CHRG_CCCV_CV_4350MV; - cv = CV_4350MV; + reg_val = CHRG_CCCV_CV_4100MV; + cv = CV_4100MV; } reg_val = reg_val << CHRG_CCCV_CV_BIT_POS; @@ -370,8 +371,8 @@ dev_warn(&info->pdev->dev, "set charge current failed\n"); break; case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: - scaled_val = min(val->intval, info->max_cv); - scaled_val = DIV_ROUND_CLOSEST(scaled_val, 1000); + scaled_val = DIV_ROUND_CLOSEST(val->intval, 1000); + scaled_val = min(scaled_val, info->max_cv); ret = axp288_charger_set_cv(info, scaled_val); if (ret < 0) dev_warn(&info->pdev->dev, "set charge voltage failed\n"); @@ -545,6 +546,55 @@ return IRQ_HANDLED; } +/* + * The HP Pavilion x2 10 series comes in a number of variants: + * Bay Trail SoC + AXP288 PMIC, Micro-USB, DMI_BOARD_NAME: "8021" + * Bay Trail SoC + AXP288 PMIC, Type-C, DMI_BOARD_NAME: "815D" + * Cherry Trail SoC + AXP288 PMIC, Type-C, DMI_BOARD_NAME: "813E" + * Cherry Trail SoC + TI PMIC, Type-C, DMI_BOARD_NAME: "827C" or "82F4" + * + * The variants with the AXP288 + Type-C connector are all kinds of special: + * + * 1. They use a Type-C connector which the AXP288 does not support, so when + * using a Type-C charger it is not recognized. Unlike most AXP288 devices, + * this model actually has mostly working ACPI AC / Battery code, the ACPI code + * "solves" this by simply setting the input_current_limit to 3A. + * There are still some issues with the ACPI code, so we use this native driver, + * and to solve the charging not working (500mA is not enough) issue we hardcode + * the 3A input_current_limit like the ACPI code does. + * + * 2. If no charger is connected the machine boots with the vbus-path disabled. + * Normally this is done when a 5V boost converter is active to avoid the PMIC + * trying to charge from the 5V boost converter's output. This is done when + * an OTG host cable is inserted and the ID pin on the micro-B receptacle is + * pulled low and the ID pin has an ACPI event handler associated with it + * which re-enables the vbus-path when the ID pin is pulled high when the + * OTG host cable is removed. The Type-C connector has no ID pin, there is + * no ID pin handler and there appears to be no 5V boost converter, so we + * end up not charging because the vbus-path is disabled, until we unplug + * the charger which automatically clears the vbus-path disable bit and then + * on the second plug-in of the adapter we start charging. To solve the not + * charging on first charger plugin we unconditionally enable the vbus-path at + * probe on this model, which is safe since there is no 5V boost converter. + */ +static const struct dmi_system_id axp288_hp_x2_dmi_ids[] = { + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "815D"), + }, + }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "813E"), + }, + }, + {} /* Terminating entry */ +}; + static void axp288_charger_extcon_evt_worker(struct work_struct *work) { struct axp288_chrg_info *info = @@ -568,7 +618,11 @@ } /* Determine cable/charger type */ - if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) { + if (dmi_check_system(axp288_hp_x2_dmi_ids)) { + /* See comment above axp288_hp_x2_dmi_ids declaration */ + dev_dbg(&info->pdev->dev, "HP X2 with Type-C, setting inlmt to 3A\n"); + current_limit = 3000000; + } else if (extcon_get_state(edev, EXTCON_CHG_USB_SDP) > 0) { dev_dbg(&info->pdev->dev, "USB SDP charger is connected\n"); current_limit = 500000; } else if (extcon_get_state(edev, EXTCON_CHG_USB_CDP) > 0) { @@ -685,6 +739,23 @@ return ret; } + if (dmi_check_system(axp288_hp_x2_dmi_ids)) { + /* See comment above axp288_hp_x2_dmi_ids declaration */ + ret = axp288_charger_vbus_path_select(info, true); + if (ret < 0) + return ret; + } else { + /* Set Vhold to the factory default / recommended 4.4V */ + val = VBUS_ISPOUT_VHOLD_SET_4400MV << VBUS_ISPOUT_VHOLD_SET_BIT_POS; + ret = regmap_update_bits(info->regmap, AXP20X_VBUS_IPSOUT_MGMT, + VBUS_ISPOUT_VHOLD_SET_MASK, val); + if (ret < 0) { + dev_err(&info->pdev->dev, "register(%x) write error(%d)\n", + AXP20X_VBUS_IPSOUT_MGMT, ret); + return ret; + } + } + /* Read current charge voltage and current limit */ ret = regmap_read(info->regmap, AXP20X_CHRG_CTRL1, &val); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/power/supply/axp288_fuel_gauge.c +++ linux-oracle-5.4.0/drivers/power/supply/axp288_fuel_gauge.c @@ -149,7 +149,7 @@ } if (ret < 0) { - dev_err(&info->pdev->dev, "axp288 reg read err:%d\n", ret); + dev_err(&info->pdev->dev, "Error reading reg 0x%02x err: %d\n", reg, ret); return ret; } @@ -163,7 +163,7 @@ ret = regmap_write(info->regmap, reg, (unsigned int)val); if (ret < 0) - dev_err(&info->pdev->dev, "axp288 reg write err:%d\n", ret); + dev_err(&info->pdev->dev, "Error writing reg 0x%02x err: %d\n", reg, ret); return ret; } @@ -706,14 +706,14 @@ { /* Intel Cherry Trail Compute Stick, Windows version */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), DMI_MATCH(DMI_PRODUCT_NAME, "STK1AW32SC"), }, }, { /* Intel Cherry Trail Compute Stick, version without an OS */ .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_SYS_VENDOR, "Intel"), DMI_MATCH(DMI_PRODUCT_NAME, "STK1A32SC"), }, }, --- linux-oracle-5.4.0.orig/drivers/power/supply/bd70528-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/bd70528-charger.c @@ -741,3 +741,4 @@ MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("BD70528 power-supply driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd70528-power"); --- linux-oracle-5.4.0.orig/drivers/power/supply/bq24190_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/bq24190_charger.c @@ -41,6 +41,7 @@ #define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0 #define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1 #define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2 +#define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3 #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1)) #define BQ24190_REG_POC_SYS_MIN_SHIFT 1 #define BQ24190_REG_POC_SYS_MIN_MIN 3000 @@ -448,8 +449,10 @@ return -EINVAL; ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v); if (ret) @@ -548,7 +551,11 @@ pm_runtime_mark_last_busy(bdi->dev); pm_runtime_put_autosuspend(bdi->dev); - return ret ? ret : val == BQ24190_REG_POC_CHG_CONFIG_OTG; + if (ret) + return ret; + + return (val == BQ24190_REG_POC_CHG_CONFIG_OTG || + val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT); } static const struct regulator_ops bq24190_vbus_ops = { @@ -1075,8 +1082,10 @@ dev_dbg(bdi->dev, "prop: %d\n", psp); ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } switch (psp) { case POWER_SUPPLY_PROP_CHARGE_TYPE: @@ -1147,8 +1156,10 @@ dev_dbg(bdi->dev, "prop: %d\n", psp); ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: @@ -1200,8 +1211,19 @@ struct bq24190_dev_info *bdi = container_of(work, struct bq24190_dev_info, input_current_limit_work.work); + union power_supply_propval val; + int ret; - power_supply_set_input_current_limit_from_supplier(bdi->charger); + ret = power_supply_get_property_from_supplier(bdi->charger, + POWER_SUPPLY_PROP_CURRENT_MAX, + &val); + if (ret) + return; + + bq24190_charger_set_property(bdi->charger, + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, + &val); + power_supply_changed(bdi->charger); } /* Sync the input-current-limit with our parent supply (if we have one) */ @@ -1408,8 +1430,10 @@ dev_dbg(bdi->dev, "prop: %d\n", psp); ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -1454,8 +1478,10 @@ dev_dbg(bdi->dev, "prop: %d\n", psp); ret = pm_runtime_get_sync(bdi->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(bdi->dev); return ret; + } switch (psp) { case POWER_SUPPLY_PROP_ONLINE: --- linux-oracle-5.4.0.orig/drivers/power/supply/bq25890_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/bq25890_charger.c @@ -531,12 +531,12 @@ if (!new_state->online) { /* power removed */ /* disable ADC */ - ret = bq25890_field_write(bq, F_CONV_START, 0); + ret = bq25890_field_write(bq, F_CONV_RATE, 0); if (ret < 0) goto error; } else if (!old_state.online) { /* power inserted */ /* enable ADC, to have control of charge current/voltage */ - ret = bq25890_field_write(bq, F_CONV_START, 1); + ret = bq25890_field_write(bq, F_CONV_RATE, 1); if (ret < 0) goto error; } --- linux-oracle-5.4.0.orig/drivers/power/supply/bq27xxx_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/bq27xxx_battery.c @@ -886,10 +886,8 @@ return ret; mutex_lock(&bq27xxx_list_lock); - list_for_each_entry(di, &bq27xxx_battery_devices, list) { - cancel_delayed_work_sync(&di->work); - schedule_delayed_work(&di->work, 0); - } + list_for_each_entry(di, &bq27xxx_battery_devices, list) + mod_delayed_work(system_wq, &di->work, 0); mutex_unlock(&bq27xxx_list_lock); return ret; @@ -1500,27 +1498,6 @@ } /* - * Read an average power register. - * Return < 0 if something fails. - */ -static int bq27xxx_battery_read_pwr_avg(struct bq27xxx_device_info *di) -{ - int tval; - - tval = bq27xxx_read(di, BQ27XXX_REG_AP, false); - if (tval < 0) { - dev_err(di->dev, "error reading average power register %02x: %d\n", - BQ27XXX_REG_AP, tval); - return tval; - } - - if (di->opts & BQ27XXX_O_ZERO) - return (tval * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS; - else - return tval; -} - -/* * Returns true if a battery over temperature condition is detected */ static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags) @@ -1568,7 +1545,7 @@ return POWER_SUPPLY_HEALTH_GOOD; } -void bq27xxx_battery_update(struct bq27xxx_device_info *di) +static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di) { struct bq27xxx_reg_cache cache = {0, }; bool has_ci_flag = di->opts & BQ27XXX_O_ZERO; @@ -1604,8 +1581,6 @@ } if (di->regs[BQ27XXX_REG_CYCT] != INVALID_REG_ADDR) cache.cycle_count = bq27xxx_battery_read_cyct(di); - if (di->regs[BQ27XXX_REG_AP] != INVALID_REG_ADDR) - cache.power_avg = bq27xxx_battery_read_pwr_avg(di); /* We only have to read charge design full once */ if (di->charge_design_full <= 0) @@ -1620,6 +1595,16 @@ di->cache = cache; di->last_update = jiffies; + + if (!di->removed && poll_interval > 0) + mod_delayed_work(system_wq, &di->work, poll_interval * HZ); +} + +void bq27xxx_battery_update(struct bq27xxx_device_info *di) +{ + mutex_lock(&di->lock); + bq27xxx_battery_update_unlocked(di); + mutex_unlock(&di->lock); } EXPORT_SYMBOL_GPL(bq27xxx_battery_update); @@ -1630,9 +1615,6 @@ work.work); bq27xxx_battery_update(di); - - if (poll_interval > 0) - schedule_delayed_work(&di->work, poll_interval * HZ); } /* @@ -1668,6 +1650,32 @@ return 0; } +/* + * Get the average power in µW + * Return < 0 if something fails. + */ +static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di, + union power_supply_propval *val) +{ + int power; + + power = bq27xxx_read(di, BQ27XXX_REG_AP, false); + if (power < 0) { + dev_err(di->dev, + "error reading average power register %02x: %d\n", + BQ27XXX_REG_AP, power); + return power; + } + + if (di->opts & BQ27XXX_O_ZERO) + val->intval = (power * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS; + else + /* Other gauges return a signed value in units of 10mW */ + val->intval = (int)((s16)power) * 10000; + + return 0; +} + static int bq27xxx_battery_status(struct bq27xxx_device_info *di, union power_supply_propval *val) { @@ -1678,8 +1686,6 @@ status = POWER_SUPPLY_STATUS_FULL; else if (di->cache.flags & BQ27000_FLAG_CHGS) status = POWER_SUPPLY_STATUS_CHARGING; - else if (power_supply_am_i_supplied(di->bat) > 0) - status = POWER_SUPPLY_STATUS_NOT_CHARGING; else status = POWER_SUPPLY_STATUS_DISCHARGING; } else { @@ -1691,6 +1697,10 @@ status = POWER_SUPPLY_STATUS_CHARGING; } + if ((status == POWER_SUPPLY_STATUS_DISCHARGING) && + (power_supply_am_i_supplied(di->bat) > 0)) + status = POWER_SUPPLY_STATUS_NOT_CHARGING; + val->intval = status; return 0; @@ -1765,10 +1775,8 @@ struct bq27xxx_device_info *di = power_supply_get_drvdata(psy); mutex_lock(&di->lock); - if (time_is_before_jiffies(di->last_update + 5 * HZ)) { - cancel_delayed_work_sync(&di->work); - bq27xxx_battery_poll(&di->work.work); - } + if (time_is_before_jiffies(di->last_update + 5 * HZ)) + bq27xxx_battery_update_unlocked(di); mutex_unlock(&di->lock); if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0) @@ -1833,7 +1841,7 @@ ret = bq27xxx_simple_value(di->cache.energy, val); break; case POWER_SUPPLY_PROP_POWER_AVG: - ret = bq27xxx_simple_value(di->cache.power_avg, val); + ret = bq27xxx_battery_pwr_avg(di, val); break; case POWER_SUPPLY_PROP_HEALTH: ret = bq27xxx_simple_value(di->cache.health, val); @@ -1852,8 +1860,8 @@ { struct bq27xxx_device_info *di = power_supply_get_drvdata(psy); - cancel_delayed_work_sync(&di->work); - schedule_delayed_work(&di->work, 0); + /* After charger plug in/out wait 0.5s for things to stabilize */ + mod_delayed_work(system_wq, &di->work, HZ / 2); } int bq27xxx_battery_setup(struct bq27xxx_device_info *di) @@ -1885,7 +1893,10 @@ di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); if (IS_ERR(di->bat)) { - dev_err(di->dev, "failed to register battery\n"); + if (PTR_ERR(di->bat) == -EPROBE_DEFER) + dev_dbg(di->dev, "failed to register battery, deferring probe\n"); + else + dev_err(di->dev, "failed to register battery\n"); return PTR_ERR(di->bat); } @@ -1902,22 +1913,18 @@ void bq27xxx_battery_teardown(struct bq27xxx_device_info *di) { - /* - * power_supply_unregister call bq27xxx_battery_get_property which - * call bq27xxx_battery_poll. - * Make sure that bq27xxx_battery_poll will not call - * schedule_delayed_work again after unregister (which cause OOPS). - */ - poll_interval = 0; - - cancel_delayed_work_sync(&di->work); - - power_supply_unregister(di->bat); - mutex_lock(&bq27xxx_list_lock); list_del(&di->list); mutex_unlock(&bq27xxx_list_lock); + /* Set removed to avoid bq27xxx_battery_update() re-queuing the work */ + mutex_lock(&di->lock); + di->removed = true; + mutex_unlock(&di->lock); + + cancel_delayed_work_sync(&di->work); + + power_supply_unregister(di->bat); mutex_destroy(&di->lock); } EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown); --- linux-oracle-5.4.0.orig/drivers/power/supply/bq27xxx_battery_i2c.c +++ linux-oracle-5.4.0/drivers/power/supply/bq27xxx_battery_i2c.c @@ -187,7 +187,7 @@ i2c_set_clientdata(client, di); if (client->irq) { - ret = devm_request_threaded_irq(&client->dev, client->irq, + ret = request_threaded_irq(client->irq, NULL, bq27xxx_battery_irq_handler_thread, IRQF_ONESHOT, di->name, di); @@ -195,7 +195,8 @@ dev_err(&client->dev, "Unable to register IRQ %d error %d\n", client->irq, ret); - return ret; + bq27xxx_battery_teardown(di); + goto err_failed; } } @@ -216,6 +217,9 @@ { struct bq27xxx_device_info *di = i2c_get_clientdata(client); + if (client->irq) + free_irq(client->irq, di); + bq27xxx_battery_teardown(di); mutex_lock(&battery_mutex); --- linux-oracle-5.4.0.orig/drivers/power/supply/charger-manager.c +++ linux-oracle-5.4.0/drivers/power/supply/charger-manager.c @@ -1470,6 +1470,7 @@ }, {}, }; +MODULE_DEVICE_TABLE(of, charger_manager_match); static struct charger_desc *of_cm_parse_desc(struct device *dev) { --- linux-oracle-5.4.0.orig/drivers/power/supply/cpcap-battery.c +++ linux-oracle-5.4.0/drivers/power/supply/cpcap-battery.c @@ -562,12 +562,14 @@ switch (d->action) { case CPCAP_BATTERY_IRQ_ACTION_BATTERY_LOW: if (latest->current_ua >= 0) - dev_warn(ddata->dev, "Battery low at 3.3V!\n"); + dev_warn(ddata->dev, "Battery low at %imV!\n", + latest->voltage / 1000); break; case CPCAP_BATTERY_IRQ_ACTION_POWEROFF: - if (latest->current_ua >= 0) { + if (latest->current_ua >= 0 && latest->voltage <= 3200000) { dev_emerg(ddata->dev, - "Battery empty at 3.1V, powering off\n"); + "Battery empty at %imV, powering off\n", + latest->voltage / 1000); orderly_poweroff(true); } break; --- linux-oracle-5.4.0.orig/drivers/power/supply/cros_usbpd-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/cros_usbpd-charger.c @@ -282,7 +282,7 @@ port->psy_current_max = 0; break; default: - dev_err(dev, "Port %d: default case!\n", port->port_number); + dev_dbg(dev, "Port %d: default case!\n", port->port_number); port->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP; } --- linux-oracle-5.4.0.orig/drivers/power/supply/da9150-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/da9150-charger.c @@ -662,6 +662,7 @@ if (!IS_ERR_OR_NULL(charger->usb_phy)) usb_unregister_notifier(charger->usb_phy, &charger->otg_nb); + cancel_work_sync(&charger->otg_work); power_supply_unregister(charger->battery); power_supply_unregister(charger->usb); --- linux-oracle-5.4.0.orig/drivers/power/supply/da9150-fg.c +++ linux-oracle-5.4.0/drivers/power/supply/da9150-fg.c @@ -247,9 +247,9 @@ DA9150_QIF_SD_GAIN_SIZE); da9150_fg_read_sync_end(fg); - div = (u64) (sd_gain * shunt_val * 65536ULL); + div = 65536ULL * sd_gain * shunt_val; do_div(div, 1000000); - res = (u64) (iavg * 1000000ULL); + res = 1000000ULL * iavg; do_div(res, div); val->intval = (int) res; --- linux-oracle-5.4.0.orig/drivers/power/supply/generic-adc-battery.c +++ linux-oracle-5.4.0/drivers/power/supply/generic-adc-battery.c @@ -138,6 +138,9 @@ result); if (ret < 0) pr_err("read channel error\n"); + else + *result *= 1000; + return ret; } @@ -382,7 +385,7 @@ } kfree(adc_bat->psy_desc.properties); - cancel_delayed_work(&adc_bat->bat_work); + cancel_delayed_work_sync(&adc_bat->bat_work); return 0; } --- linux-oracle-5.4.0.orig/drivers/power/supply/ingenic-battery.c +++ linux-oracle-5.4.0/drivers/power/supply/ingenic-battery.c @@ -100,10 +100,17 @@ return -EINVAL; } - return iio_write_channel_attribute(bat->channel, - scale_raw[best_idx], - scale_raw[best_idx + 1], - IIO_CHAN_INFO_SCALE); + /* Only set scale if there is more than one (fractional) entry */ + if (scale_len > 2) { + ret = iio_write_channel_attribute(bat->channel, + scale_raw[best_idx], + scale_raw[best_idx + 1], + IIO_CHAN_INFO_SCALE); + if (ret) + return ret; + } + + return 0; } static enum power_supply_property ingenic_battery_properties[] = { --- linux-oracle-5.4.0.orig/drivers/power/supply/lp8788-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/lp8788-charger.c @@ -501,7 +501,7 @@ ret = request_threaded_irq(virq, NULL, lp8788_charger_irq_thread, - 0, name, pchg); + IRQF_ONESHOT, name, pchg); if (ret) break; } @@ -572,27 +572,14 @@ return; /* ADC channel for battery voltage */ - chan = iio_channel_get(dev, pdata->adc_vbatt); + chan = devm_iio_channel_get(dev, pdata->adc_vbatt); pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan; /* ADC channel for battery temperature */ - chan = iio_channel_get(dev, pdata->adc_batt_temp); + chan = devm_iio_channel_get(dev, pdata->adc_batt_temp); pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan; } -static void lp8788_release_adc_channel(struct lp8788_charger *pchg) -{ - int i; - - for (i = 0; i < LP8788_NUM_CHG_ADC; i++) { - if (!pchg->chan[i]) - continue; - - iio_channel_release(pchg->chan[i]); - pchg->chan[i] = NULL; - } -} - static ssize_t lp8788_show_charger_status(struct device *dev, struct device_attribute *attr, char *buf) { @@ -735,7 +722,6 @@ flush_work(&pchg->charger_work); lp8788_irq_unregister(pdev, pchg); lp8788_psy_unregister(pchg); - lp8788_release_adc_channel(pchg); return 0; } --- linux-oracle-5.4.0.orig/drivers/power/supply/ltc2941-battery-gauge.c +++ linux-oracle-5.4.0/drivers/power/supply/ltc2941-battery-gauge.c @@ -449,7 +449,7 @@ { struct ltc294x_info *info = i2c_get_clientdata(client); - cancel_delayed_work(&info->work); + cancel_delayed_work_sync(&info->work); power_supply_unregister(info->supply); return 0; } --- linux-oracle-5.4.0.orig/drivers/power/supply/max17040_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/max17040_battery.c @@ -105,7 +105,7 @@ vcell = max17040_read_reg(client, MAX17040_VCELL); - chip->vcell = vcell; + chip->vcell = (vcell >> 4) * 1250; } static void max17040_get_soc(struct i2c_client *client) --- linux-oracle-5.4.0.orig/drivers/power/supply/max17042_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/max17042_battery.c @@ -312,7 +312,10 @@ val->intval = data * 625 / 8; break; case POWER_SUPPLY_PROP_CAPACITY: - ret = regmap_read(map, MAX17042_RepSOC, &data); + if (chip->pdata->enable_current_sense) + ret = regmap_read(map, MAX17042_RepSOC, &data); + else + ret = regmap_read(map, MAX17042_VFSOC, &data); if (ret < 0) return ret; @@ -726,7 +729,7 @@ struct max17042_config_data *config = chip->pdata->config_data; max17042_override_por(map, MAX17042_TGAIN, config->tgain); - max17042_override_por(map, MAx17042_TOFF, config->toff); + max17042_override_por(map, MAX17042_TOFF, config->toff); max17042_override_por(map, MAX17042_CGAIN, config->cgain); max17042_override_por(map, MAX17042_COFF, config->coff); @@ -831,10 +834,14 @@ /* program interrupt thesholds such that we should * get interrupt for every 'off' perc change in the soc */ - regmap_read(map, MAX17042_RepSOC, &soc); + if (chip->pdata->enable_current_sense) + regmap_read(map, MAX17042_RepSOC, &soc); + else + regmap_read(map, MAX17042_VFSOC, &soc); soc >>= 8; soc_tr = (soc + off) << 8; - soc_tr |= (soc - off); + if (off < soc) + soc_tr |= soc - off; regmap_write(map, MAX17042_SALRT_Th, soc_tr); } @@ -842,8 +849,12 @@ { struct max17042_chip *chip = dev; u32 val; + int ret; + + ret = regmap_read(chip->regmap, MAX17042_STATUS, &val); + if (ret) + return IRQ_HANDLED; - regmap_read(chip->regmap, MAX17042_STATUS, &val); if ((val & STATUS_INTR_SOCMIN_BIT) || (val & STATUS_INTR_SOCMAX_BIT)) { dev_info(&chip->client->dev, "SOC threshold INTR\n"); @@ -1076,7 +1087,7 @@ } if (client->irq) { - unsigned int flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + unsigned int flags = IRQF_ONESHOT; /* * On ACPI systems the IRQ may be handled by ACPI-event code, --- linux-oracle-5.4.0.orig/drivers/power/supply/pm2301_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/pm2301_charger.c @@ -1095,7 +1095,7 @@ ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), NULL, pm2xxx_charger_irq[0].isr, - pm2->pdata->irq_type, + pm2->pdata->irq_type | IRQF_ONESHOT, pm2xxx_charger_irq[0].name, pm2); if (ret != 0) { --- linux-oracle-5.4.0.orig/drivers/power/supply/power_supply_core.c +++ linux-oracle-5.4.0/drivers/power/supply/power_supply_core.c @@ -347,6 +347,10 @@ struct power_supply *psy = dev_get_drvdata(dev); unsigned int *count = data; + if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret)) + if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE) + return 0; + (*count)++; if (psy->desc->type != POWER_SUPPLY_TYPE_BATTERY) if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE, @@ -365,8 +369,8 @@ __power_supply_is_system_supplied); /* - * If no power class device was found at all, most probably we are - * running on a desktop system, so assume we are on mains power. + * If no system scope power class device was found at all, most probably we + * are running on a desktop system, so assume we are on mains power. */ if (count == 0) return 1; @@ -375,46 +379,49 @@ } EXPORT_SYMBOL_GPL(power_supply_is_system_supplied); -static int __power_supply_get_supplier_max_current(struct device *dev, - void *data) +struct psy_get_supplier_prop_data { + struct power_supply *psy; + enum power_supply_property psp; + union power_supply_propval *val; +}; + +static int __power_supply_get_supplier_property(struct device *dev, void *_data) { - union power_supply_propval ret = {0,}; struct power_supply *epsy = dev_get_drvdata(dev); - struct power_supply *psy = data; + struct psy_get_supplier_prop_data *data = _data; - if (__power_supply_is_supplied_by(epsy, psy)) - if (!epsy->desc->get_property(epsy, - POWER_SUPPLY_PROP_CURRENT_MAX, - &ret)) - return ret.intval; + if (__power_supply_is_supplied_by(epsy, data->psy)) + if (!epsy->desc->get_property(epsy, data->psp, data->val)) + return 1; /* Success */ - return 0; + return 0; /* Continue iterating */ } -int power_supply_set_input_current_limit_from_supplier(struct power_supply *psy) +int power_supply_get_property_from_supplier(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) { - union power_supply_propval val = {0,}; - int curr; - - if (!psy->desc->set_property) - return -EINVAL; + struct psy_get_supplier_prop_data data = { + .psy = psy, + .psp = psp, + .val = val, + }; + int ret; /* * This function is not intended for use with a supply with multiple - * suppliers, we simply pick the first supply to report a non 0 - * max-current. + * suppliers, we simply pick the first supply to report the psp. */ - curr = class_for_each_device(power_supply_class, NULL, psy, - __power_supply_get_supplier_max_current); - if (curr <= 0) - return (curr == 0) ? -ENODEV : curr; - - val.intval = curr; + ret = class_for_each_device(power_supply_class, NULL, &data, + __power_supply_get_supplier_property); + if (ret < 0) + return ret; + if (ret == 0) + return -ENODEV; - return psy->desc->set_property(psy, - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); + return 0; } -EXPORT_SYMBOL_GPL(power_supply_set_input_current_limit_from_supplier); +EXPORT_SYMBOL_GPL(power_supply_get_property_from_supplier); int power_supply_set_battery_charged(struct power_supply *psy) { @@ -472,8 +479,6 @@ */ void power_supply_put(struct power_supply *psy) { - might_sleep(); - atomic_dec(&psy->use_cnt); put_device(&psy->dev); } @@ -648,6 +653,11 @@ int i, tab_len, size; propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index); + if (!propname) { + power_supply_put_battery_info(psy, info); + err = -ENOMEM; + goto out_put_node; + } list = of_get_property(battery_np, propname, &size); if (!list || !size) { dev_err(&psy->dev, "failed to get %s\n", propname); @@ -742,6 +752,10 @@ return NULL; for (i = 0; i < POWER_SUPPLY_OCV_TEMP_MAX; i++) { + /* Out of capacity tables */ + if (!info->ocv_table[i]) + break; + temp_diff = abs(info->ocv_temp[i] - temp); if (temp_diff < best_temp_diff) { @@ -1100,8 +1114,8 @@ register_cooler_failed: psy_unregister_thermal(psy); register_thermal_failed: - device_del(dev); wakeup_init_failed: + device_del(dev); device_add_failed: check_supplies_failed: dev_set_name_failed: --- linux-oracle-5.4.0.orig/drivers/power/supply/power_supply_hwmon.c +++ linux-oracle-5.4.0/drivers/power/supply/power_supply_hwmon.c @@ -144,7 +144,7 @@ u32 attr, int channel, const char **str) { - *str = channel ? "temp" : "temp ambient"; + *str = channel ? "temp ambient" : "temp"; return 0; } @@ -304,7 +304,7 @@ goto error; } - ret = devm_add_action(dev, power_supply_hwmon_bitmap_free, + ret = devm_add_action_or_reset(dev, power_supply_hwmon_bitmap_free, psyhw->props); if (ret) goto error; --- linux-oracle-5.4.0.orig/drivers/power/supply/power_supply_leds.c +++ linux-oracle-5.4.0/drivers/power/supply/power_supply_leds.c @@ -34,8 +34,9 @@ led_trigger_event(psy->charging_full_trig, LED_FULL); led_trigger_event(psy->charging_trig, LED_OFF); led_trigger_event(psy->full_trig, LED_FULL); - led_trigger_event(psy->charging_blink_full_solid_trig, - LED_FULL); + /* Going from blink to LED on requires a LED_OFF event to stop blink */ + led_trigger_event(psy->charging_blink_full_solid_trig, LED_OFF); + led_trigger_event(psy->charging_blink_full_solid_trig, LED_FULL); break; case POWER_SUPPLY_STATUS_CHARGING: led_trigger_event(psy->charging_full_trig, LED_FULL); --- linux-oracle-5.4.0.orig/drivers/power/supply/power_supply_sysfs.c +++ linux-oracle-5.4.0/drivers/power/supply/power_supply_sysfs.c @@ -127,7 +127,8 @@ if (ret < 0) { if (ret == -ENODATA) - dev_dbg(dev, "driver has no data for `%s' property\n", + dev_dbg_ratelimited(dev, + "driver has no data for `%s' property\n", attr->attr.name); else if (ret != -ENODEV && ret != -EAGAIN) dev_err_ratelimited(dev, --- linux-oracle-5.4.0.orig/drivers/power/supply/rt5033_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/rt5033_battery.c @@ -60,7 +60,7 @@ regmap_read(battery->regmap, regh, &msb); regmap_read(battery->regmap, regl, &lsb); - ret = ((msb << 4) + (lsb >> 4)) * 1250 / 1000; + ret = ((msb << 4) + (lsb >> 4)) * 1250; return ret; } @@ -164,9 +164,16 @@ }; MODULE_DEVICE_TABLE(i2c, rt5033_battery_id); +static const struct of_device_id rt5033_battery_of_match[] = { + { .compatible = "richtek,rt5033-battery", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5033_battery_of_match); + static struct i2c_driver rt5033_battery_driver = { .driver = { .name = "rt5033-battery", + .of_match_table = rt5033_battery_of_match, }, .probe = rt5033_battery_probe, .remove = rt5033_battery_remove, --- linux-oracle-5.4.0.orig/drivers/power/supply/rt9455_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/rt9455_charger.c @@ -193,6 +193,7 @@ 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000 }; +#if IS_ENABLED(CONFIG_USB_PHY) /* * When the charger is in boost mode, REG02[7:2] represent boost output * voltage. @@ -208,6 +209,7 @@ 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, }; +#endif /* REG07[3:0] (VMREG) in uV */ static const int rt9455_vmreg_values[] = { --- linux-oracle-5.4.0.orig/drivers/power/supply/s3c_adc_battery.c +++ linux-oracle-5.4.0/drivers/power/supply/s3c_adc_battery.c @@ -394,7 +394,7 @@ gpio_free(pdata->gpio_charge_finished); } - cancel_delayed_work(&bat_work); + cancel_delayed_work_sync(&bat_work); if (pdata->exit) pdata->exit(); --- linux-oracle-5.4.0.orig/drivers/power/supply/sbs-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/sbs-charger.c @@ -25,7 +25,7 @@ #define SBS_CHARGER_REG_STATUS 0x13 #define SBS_CHARGER_REG_ALARM_WARNING 0x16 -#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(1) +#define SBS_CHARGER_STATUS_CHARGE_INHIBITED BIT(0) #define SBS_CHARGER_STATUS_RES_COLD BIT(9) #define SBS_CHARGER_STATUS_RES_HOT BIT(10) #define SBS_CHARGER_STATUS_BATTERY_PRESENT BIT(14) --- linux-oracle-5.4.0.orig/drivers/power/supply/sc2731_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/sc2731_charger.c @@ -524,6 +524,7 @@ { .compatible = "sprd,sc2731-charger", }, { } }; +MODULE_DEVICE_TABLE(of, sc2731_charger_of_match); static struct platform_driver sc2731_charger_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/power/supply/sc27xx_fuel_gauge.c +++ linux-oracle-5.4.0/drivers/power/supply/sc27xx_fuel_gauge.c @@ -634,13 +634,6 @@ return ret; } -static void sc27xx_fgu_external_power_changed(struct power_supply *psy) -{ - struct sc27xx_fgu_data *data = power_supply_get_drvdata(psy); - - power_supply_changed(data->battery); -} - static int sc27xx_fgu_property_is_writeable(struct power_supply *psy, enum power_supply_property psp) { @@ -671,7 +664,7 @@ .num_properties = ARRAY_SIZE(sc27xx_fgu_props), .get_property = sc27xx_fgu_get_property, .set_property = sc27xx_fgu_set_property, - .external_power_changed = sc27xx_fgu_external_power_changed, + .external_power_changed = power_supply_changed, .property_is_writeable = sc27xx_fgu_property_is_writeable, }; @@ -1215,6 +1208,7 @@ { .compatible = "sprd,sc2731-fgu", }, { } }; +MODULE_DEVICE_TABLE(of, sc27xx_fgu_of_match); static struct platform_driver sc27xx_fgu_driver = { .probe = sc27xx_fgu_probe, --- linux-oracle-5.4.0.orig/drivers/power/supply/smb347-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/smb347-charger.c @@ -1138,6 +1138,7 @@ switch (reg) { case IRQSTAT_A: case IRQSTAT_C: + case IRQSTAT_D: case IRQSTAT_E: case IRQSTAT_F: case STAT_A: --- linux-oracle-5.4.0.orig/drivers/power/supply/test_power.c +++ linux-oracle-5.4.0/drivers/power/supply/test_power.c @@ -341,6 +341,7 @@ static int param_get_ac_online(char *buffer, const struct kernel_param *kp) { strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } @@ -354,6 +355,7 @@ static int param_get_usb_online(char *buffer, const struct kernel_param *kp) { strcpy(buffer, map_get_key(map_ac_online, usb_online, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } @@ -368,6 +370,7 @@ static int param_get_battery_status(char *buffer, const struct kernel_param *kp) { strcpy(buffer, map_get_key(map_status, battery_status, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } @@ -382,6 +385,7 @@ static int param_get_battery_health(char *buffer, const struct kernel_param *kp) { strcpy(buffer, map_get_key(map_health, battery_health, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } @@ -397,6 +401,7 @@ const struct kernel_param *kp) { strcpy(buffer, map_get_key(map_present, battery_present, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } @@ -414,6 +419,7 @@ { strcpy(buffer, map_get_key(map_technology, battery_technology, "unknown")); + strcat(buffer, "\n"); return strlen(buffer); } --- linux-oracle-5.4.0.orig/drivers/power/supply/tps65090-charger.c +++ linux-oracle-5.4.0/drivers/power/supply/tps65090-charger.c @@ -301,7 +301,7 @@ if (irq != -ENXIO) { ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, - tps65090_charger_isr, 0, "tps65090-charger", cdata); + tps65090_charger_isr, IRQF_ONESHOT, "tps65090-charger", cdata); if (ret) { dev_err(cdata->dev, "Unable to register irq %d err %d\n", irq, --- linux-oracle-5.4.0.orig/drivers/power/supply/tps65217_charger.c +++ linux-oracle-5.4.0/drivers/power/supply/tps65217_charger.c @@ -238,7 +238,7 @@ for (i = 0; i < NUM_CHARGER_IRQS; i++) { ret = devm_request_threaded_irq(&pdev->dev, irq[i], NULL, tps65217_charger_irq, - 0, "tps65217-charger", + IRQF_ONESHOT, "tps65217-charger", charger); if (ret) { dev_err(charger->dev, --- linux-oracle-5.4.0.orig/drivers/power/supply/wm8350_power.c +++ linux-oracle-5.4.0/drivers/power/supply/wm8350_power.c @@ -408,44 +408,112 @@ * Initialisation *********************************************************************/ -static void wm8350_init_charger(struct wm8350 *wm8350) +static int wm8350_init_charger(struct wm8350 *wm8350) { + int ret; + /* register our interest in charger events */ - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350_charger_handler, 0, "Battery hot", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, + if (ret) + goto err; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350_charger_handler, 0, "Battery cold", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, + if (ret) + goto free_chg_bat_hot; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350_charger_handler, 0, "Battery fail", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO, + if (ret) + goto free_chg_bat_cold; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350_charger_handler, 0, "Charger timeout", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END, + if (ret) + goto free_chg_bat_fail; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END, wm8350_charger_handler, 0, "Charge end", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START, + if (ret) + goto free_chg_to; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START, wm8350_charger_handler, 0, "Charge start", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, + if (ret) + goto free_chg_end; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350_charger_handler, 0, "Fast charge ready", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, + if (ret) + goto free_chg_start; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350_charger_handler, 0, "Battery <3.9V", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, + if (ret) + goto free_chg_fast_rdy; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350_charger_handler, 0, "Battery <3.1V", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, + if (ret) + goto free_chg_vbatt_lt_3p9; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350_charger_handler, 0, "Battery <2.85V", wm8350); + if (ret) + goto free_chg_vbatt_lt_3p1; /* and supply change events */ - wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB, + ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350_charger_handler, 0, "USB", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, + if (ret) + goto free_chg_vbatt_lt_2p85; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350_charger_handler, 0, "Wall", wm8350); - wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, + if (ret) + goto free_ext_usb_fb; + + ret = wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350_charger_handler, 0, "Battery", wm8350); + if (ret) + goto free_ext_wall_fb; + + return 0; + +free_ext_wall_fb: + wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350); +free_ext_usb_fb: + wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350); +free_chg_vbatt_lt_2p85: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350); +free_chg_vbatt_lt_3p1: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350); +free_chg_vbatt_lt_3p9: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350); +free_chg_fast_rdy: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350); +free_chg_start: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350); +free_chg_end: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350); +free_chg_to: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350); +free_chg_bat_fail: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350); +free_chg_bat_cold: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350); +free_chg_bat_hot: + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350); +err: + return ret; } static void free_charger_irq(struct wm8350 *wm8350) @@ -456,6 +524,7 @@ wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START, wm8350); + wm8350_free_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350); wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350); --- linux-oracle-5.4.0.orig/drivers/powercap/Kconfig +++ linux-oracle-5.4.0/drivers/powercap/Kconfig @@ -18,10 +18,12 @@ # Client driver configurations go here. config INTEL_RAPL_CORE tristate + depends on PCI + select IOSF_MBI config INTEL_RAPL tristate "Intel RAPL Support via MSR Interface" - depends on X86 && IOSF_MBI + depends on X86 && PCI select INTEL_RAPL_CORE ---help--- This enables support for the Intel Running Average Power Limit (RAPL) --- linux-oracle-5.4.0.orig/drivers/powercap/intel_rapl_common.c +++ linux-oracle-5.4.0/drivers/powercap/intel_rapl_common.c @@ -885,6 +885,9 @@ y = value & 0x1f; value = (1 << y) * (4 + f) * rp->time_unit / 4; } else { + if (value < rp->time_unit) + return 0; + do_div(value, rp->time_unit); y = ilog2(value); f = div64_u64(4 * (value - (1 << y)), 1 << y); @@ -978,6 +981,8 @@ INTEL_CPU_FAM6(ICELAKE_NNPI, rapl_defaults_core), INTEL_CPU_FAM6(ICELAKE_X, rapl_defaults_hsw_server), INTEL_CPU_FAM6(ICELAKE_D, rapl_defaults_hsw_server), + INTEL_CPU_FAM6(COMETLAKE_L, rapl_defaults_core), + INTEL_CPU_FAM6(COMETLAKE, rapl_defaults_core), INTEL_CPU_FAM6(ATOM_SILVERMONT, rapl_defaults_byt), INTEL_CPU_FAM6(ATOM_AIRMONT, rapl_defaults_cht), @@ -1293,6 +1298,9 @@ struct cpuinfo_x86 *c = &cpu_data(cpu); int ret; + if (!rapl_defaults) + return ERR_PTR(-ENODEV); + rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL); if (!rp) return ERR_PTR(-ENOMEM); @@ -1419,7 +1427,7 @@ id = x86_match_cpu(rapl_ids); if (!id) { - pr_err("driver does not support CPU family %d model %d\n", + pr_info("driver does not support CPU family %d model %d\n", boot_cpu_data.x86, boot_cpu_data.x86_model); return -ENODEV; --- linux-oracle-5.4.0.orig/drivers/powercap/intel_rapl_msr.c +++ linux-oracle-5.4.0/drivers/powercap/intel_rapl_msr.c @@ -22,7 +22,6 @@ #include #include -#include #include #include --- linux-oracle-5.4.0.orig/drivers/powercap/powercap_sys.c +++ linux-oracle-5.4.0/drivers/powercap/powercap_sys.c @@ -224,46 +224,46 @@ for (i = 0; i < MAX_CONSTRAINTS_PER_ZONE; ++i) { ret = create_constraint_attribute(i, "power_limit_uw", - S_IWUSR | S_IRUGO, + S_IWUSR | S_IRUSR, &constraint_attrs[i].power_limit_attr, show_constraint_power_limit_uw, store_constraint_power_limit_uw); if (ret) goto err_alloc; ret = create_constraint_attribute(i, "time_window_us", - S_IWUSR | S_IRUGO, + S_IWUSR | S_IRUSR, &constraint_attrs[i].time_window_attr, show_constraint_time_window_us, store_constraint_time_window_us); if (ret) goto err_alloc; - ret = create_constraint_attribute(i, "name", S_IRUGO, + ret = create_constraint_attribute(i, "name", S_IRUSR, &constraint_attrs[i].name_attr, show_constraint_name, NULL); if (ret) goto err_alloc; - ret = create_constraint_attribute(i, "max_power_uw", S_IRUGO, + ret = create_constraint_attribute(i, "max_power_uw", S_IRUSR, &constraint_attrs[i].max_power_attr, show_constraint_max_power_uw, NULL); if (ret) goto err_alloc; - ret = create_constraint_attribute(i, "min_power_uw", S_IRUGO, + ret = create_constraint_attribute(i, "min_power_uw", S_IRUSR, &constraint_attrs[i].min_power_attr, show_constraint_min_power_uw, NULL); if (ret) goto err_alloc; ret = create_constraint_attribute(i, "max_time_window_us", - S_IRUGO, + S_IRUSR, &constraint_attrs[i].max_time_window_attr, show_constraint_max_time_window_us, NULL); if (ret) goto err_alloc; ret = create_constraint_attribute(i, "min_time_window_us", - S_IRUGO, + S_IRUSR, &constraint_attrs[i].min_time_window_attr, show_constraint_min_time_window_us, NULL); @@ -362,23 +362,29 @@ int count = 0; power_zone->zone_dev_attrs[count++] = &dev_attr_name.attr; - if (power_zone->ops->get_max_energy_range_uj) + if (power_zone->ops->get_max_energy_range_uj) { + dev_attr_max_energy_range_uj.attr.mode = S_IRUSR; power_zone->zone_dev_attrs[count++] = &dev_attr_max_energy_range_uj.attr; + } if (power_zone->ops->get_energy_uj) { if (power_zone->ops->reset_energy_uj) - dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUGO; + dev_attr_energy_uj.attr.mode = S_IWUSR | S_IRUSR; else - dev_attr_energy_uj.attr.mode = S_IRUGO; + dev_attr_energy_uj.attr.mode = S_IRUSR; power_zone->zone_dev_attrs[count++] = &dev_attr_energy_uj.attr; } - if (power_zone->ops->get_power_uw) + if (power_zone->ops->get_power_uw) { + dev_attr_power_uw.attr.mode = S_IRUSR; power_zone->zone_dev_attrs[count++] = &dev_attr_power_uw.attr; - if (power_zone->ops->get_max_power_range_uw) + } + if (power_zone->ops->get_max_power_range_uw) { + dev_attr_max_power_range_uw.attr.mode = S_IRUSR; power_zone->zone_dev_attrs[count++] = &dev_attr_max_power_range_uw.attr; + } power_zone->zone_dev_attrs[count] = NULL; power_zone->zone_attr_count = count; } @@ -530,9 +536,6 @@ power_zone->name = kstrdup(name, GFP_KERNEL); if (!power_zone->name) goto err_name_alloc; - dev_set_name(&power_zone->dev, "%s:%x", - dev_name(power_zone->dev.parent), - power_zone->id); power_zone->constraints = kcalloc(nr_constraints, sizeof(*power_zone->constraints), GFP_KERNEL); @@ -555,9 +558,16 @@ power_zone->dev_attr_groups[0] = &power_zone->dev_zone_attr_group; power_zone->dev_attr_groups[1] = NULL; power_zone->dev.groups = power_zone->dev_attr_groups; + dev_set_name(&power_zone->dev, "%s:%x", + dev_name(power_zone->dev.parent), + power_zone->id); result = device_register(&power_zone->dev); - if (result) - goto err_dev_ret; + if (result) { + put_device(&power_zone->dev); + mutex_unlock(&control_type->lock); + + return ERR_PTR(result); + } control_type->nr_zones++; mutex_unlock(&control_type->lock); --- linux-oracle-5.4.0.orig/drivers/pps/clients/pps-gpio.c +++ linux-oracle-5.4.0/drivers/pps/clients/pps-gpio.c @@ -232,8 +232,8 @@ return -EINVAL; } - dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", - data->irq); + dev_dbg(&data->pps->dev, "Registered IRQ %d as PPS source\n", + data->irq); return 0; } --- linux-oracle-5.4.0.orig/drivers/pps/clients/pps-ktimer.c +++ linux-oracle-5.4.0/drivers/pps/clients/pps-ktimer.c @@ -56,7 +56,7 @@ static void __exit pps_ktimer_exit(void) { - dev_info(pps->dev, "ktimer PPS source unregistered\n"); + dev_dbg(&pps->dev, "ktimer PPS source unregistered\n"); del_timer_sync(&ktimer); pps_unregister_source(pps); @@ -74,7 +74,7 @@ timer_setup(&ktimer, pps_ktimer_event, 0); mod_timer(&ktimer, jiffies + HZ); - dev_info(pps->dev, "ktimer PPS source registered\n"); + dev_dbg(&pps->dev, "ktimer PPS source registered\n"); return 0; } --- linux-oracle-5.4.0.orig/drivers/pps/clients/pps-ldisc.c +++ linux-oracle-5.4.0/drivers/pps/clients/pps-ldisc.c @@ -34,7 +34,7 @@ pps_event(pps, &ts, status ? PPS_CAPTUREASSERT : PPS_CAPTURECLEAR, NULL); - dev_dbg(pps->dev, "PPS %s at %lu\n", + dev_dbg(&pps->dev, "PPS %s at %lu\n", status ? "assert" : "clear", jiffies); } @@ -71,7 +71,7 @@ goto err_unregister; } - dev_info(pps->dev, "source \"%s\" added\n", info.path); + dev_dbg(&pps->dev, "source \"%s\" added\n", info.path); return 0; @@ -91,7 +91,7 @@ if (WARN_ON(!pps)) return; - dev_info(pps->dev, "removed\n"); + dev_info(&pps->dev, "removed\n"); pps_unregister_source(pps); } --- linux-oracle-5.4.0.orig/drivers/pps/clients/pps_parport.c +++ linux-oracle-5.4.0/drivers/pps/clients/pps_parport.c @@ -83,7 +83,7 @@ /* check the signal (no signal means the pulse is lost this time) */ if (!signal_is_set(port)) { local_irq_restore(flags); - dev_err(dev->pps->dev, "lost the signal\n"); + dev_err(&dev->pps->dev, "lost the signal\n"); goto out_assert; } @@ -100,7 +100,7 @@ /* timeout */ dev->cw_err++; if (dev->cw_err >= CLEAR_WAIT_MAX_ERRORS) { - dev_err(dev->pps->dev, "disabled clear edge capture after %d" + dev_err(&dev->pps->dev, "disabled clear edge capture after %d" " timeouts\n", dev->cw_err); dev->cw = 0; dev->cw_err = 0; @@ -144,7 +144,10 @@ return; } - index = ida_simple_get(&pps_client_index, 0, 0, GFP_KERNEL); + index = ida_alloc(&pps_client_index, GFP_KERNEL); + if (index < 0) + goto err_free_device; + memset(&pps_client_cb, 0, sizeof(pps_client_cb)); pps_client_cb.private = device; pps_client_cb.irq_func = parport_irq; @@ -155,7 +158,7 @@ index); if (!device->pardev) { pr_err("couldn't register with %s\n", port->name); - goto err_free; + goto err_free_ida; } if (parport_claim_or_block(device->pardev) < 0) { @@ -183,8 +186,9 @@ parport_release(device->pardev); err_unregister_dev: parport_unregister_device(device->pardev); -err_free: - ida_simple_remove(&pps_client_index, index); +err_free_ida: + ida_free(&pps_client_index, index); +err_free_device: kfree(device); } @@ -204,7 +208,7 @@ pps_unregister_source(device->pps); parport_release(pardev); parport_unregister_device(pardev); - ida_simple_remove(&pps_client_index, device->index); + ida_free(&pps_client_index, device->index); kfree(device); } --- linux-oracle-5.4.0.orig/drivers/pps/kapi.c +++ linux-oracle-5.4.0/drivers/pps/kapi.c @@ -41,7 +41,7 @@ static void pps_echo_client_default(struct pps_device *pps, int event, void *data) { - dev_info(pps->dev, "echo %s %s\n", + dev_info(&pps->dev, "echo %s %s\n", event & PPS_CAPTUREASSERT ? "assert" : "", event & PPS_CAPTURECLEAR ? "clear" : ""); } @@ -112,7 +112,7 @@ goto kfree_pps; } - dev_info(pps->dev, "new PPS source %s\n", info->name); + dev_dbg(&pps->dev, "new PPS source %s\n", info->name); return pps; @@ -166,7 +166,7 @@ /* check event type */ BUG_ON((event & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR)) == 0); - dev_dbg(pps->dev, "PPS event at %lld.%09ld\n", + dev_dbg(&pps->dev, "PPS event at %lld.%09ld\n", (s64)ts->ts_real.tv_sec, ts->ts_real.tv_nsec); timespec_to_pps_ktime(&ts_real, ts->ts_real); @@ -188,7 +188,7 @@ /* Save the time stamp */ pps->assert_tu = ts_real; pps->assert_sequence++; - dev_dbg(pps->dev, "capture assert seq #%u\n", + dev_dbg(&pps->dev, "capture assert seq #%u\n", pps->assert_sequence); captured = ~0; @@ -202,7 +202,7 @@ /* Save the time stamp */ pps->clear_tu = ts_real; pps->clear_sequence++; - dev_dbg(pps->dev, "capture clear seq #%u\n", + dev_dbg(&pps->dev, "capture clear seq #%u\n", pps->clear_sequence); captured = ~0; --- linux-oracle-5.4.0.orig/drivers/pps/kc.c +++ linux-oracle-5.4.0/drivers/pps/kc.c @@ -43,11 +43,11 @@ pps_kc_hardpps_mode = 0; pps_kc_hardpps_dev = NULL; spin_unlock_irq(&pps_kc_hardpps_lock); - dev_info(pps->dev, "unbound kernel" + dev_info(&pps->dev, "unbound kernel" " consumer\n"); } else { spin_unlock_irq(&pps_kc_hardpps_lock); - dev_err(pps->dev, "selected kernel consumer" + dev_err(&pps->dev, "selected kernel consumer" " is not bound\n"); return -EINVAL; } @@ -57,11 +57,11 @@ pps_kc_hardpps_mode = bind_args->edge; pps_kc_hardpps_dev = pps; spin_unlock_irq(&pps_kc_hardpps_lock); - dev_info(pps->dev, "bound kernel consumer: " + dev_info(&pps->dev, "bound kernel consumer: " "edge=0x%x\n", bind_args->edge); } else { spin_unlock_irq(&pps_kc_hardpps_lock); - dev_err(pps->dev, "another kernel consumer" + dev_err(&pps->dev, "another kernel consumer" " is already bound\n"); return -EINVAL; } @@ -83,7 +83,7 @@ pps_kc_hardpps_mode = 0; pps_kc_hardpps_dev = NULL; spin_unlock_irq(&pps_kc_hardpps_lock); - dev_info(pps->dev, "unbound kernel consumer" + dev_info(&pps->dev, "unbound kernel consumer" " on device removal\n"); } else spin_unlock_irq(&pps_kc_hardpps_lock); --- linux-oracle-5.4.0.orig/drivers/pps/pps.c +++ linux-oracle-5.4.0/drivers/pps/pps.c @@ -25,7 +25,7 @@ * Local variables */ -static dev_t pps_devt; +static int pps_major; static struct class *pps_class; static DEFINE_MUTEX(pps_idr_lock); @@ -62,7 +62,7 @@ else { unsigned long ticks; - dev_dbg(pps->dev, "timeout %lld.%09d\n", + dev_dbg(&pps->dev, "timeout %lld.%09d\n", (long long) fdata->timeout.sec, fdata->timeout.nsec); ticks = fdata->timeout.sec * HZ; @@ -80,7 +80,7 @@ /* Check for pending signals */ if (err == -ERESTARTSYS) { - dev_dbg(pps->dev, "pending signal caught\n"); + dev_dbg(&pps->dev, "pending signal caught\n"); return -EINTR; } @@ -98,7 +98,7 @@ switch (cmd) { case PPS_GETPARAMS: - dev_dbg(pps->dev, "PPS_GETPARAMS\n"); + dev_dbg(&pps->dev, "PPS_GETPARAMS\n"); spin_lock_irq(&pps->lock); @@ -114,7 +114,7 @@ break; case PPS_SETPARAMS: - dev_dbg(pps->dev, "PPS_SETPARAMS\n"); + dev_dbg(&pps->dev, "PPS_SETPARAMS\n"); /* Check the capabilities */ if (!capable(CAP_SYS_TIME)) @@ -124,14 +124,14 @@ if (err) return -EFAULT; if (!(params.mode & (PPS_CAPTUREASSERT | PPS_CAPTURECLEAR))) { - dev_dbg(pps->dev, "capture mode unspecified (%x)\n", + dev_dbg(&pps->dev, "capture mode unspecified (%x)\n", params.mode); return -EINVAL; } /* Check for supported capabilities */ if ((params.mode & ~pps->info.mode) != 0) { - dev_dbg(pps->dev, "unsupported capabilities (%x)\n", + dev_dbg(&pps->dev, "unsupported capabilities (%x)\n", params.mode); return -EINVAL; } @@ -144,7 +144,7 @@ /* Restore the read only parameters */ if ((params.mode & (PPS_TSFMT_TSPEC | PPS_TSFMT_NTPFP)) == 0) { /* section 3.3 of RFC 2783 interpreted */ - dev_dbg(pps->dev, "time format unspecified (%x)\n", + dev_dbg(&pps->dev, "time format unspecified (%x)\n", params.mode); pps->params.mode |= PPS_TSFMT_TSPEC; } @@ -165,7 +165,7 @@ break; case PPS_GETCAP: - dev_dbg(pps->dev, "PPS_GETCAP\n"); + dev_dbg(&pps->dev, "PPS_GETCAP\n"); err = put_user(pps->info.mode, iuarg); if (err) @@ -176,7 +176,7 @@ case PPS_FETCH: { struct pps_fdata fdata; - dev_dbg(pps->dev, "PPS_FETCH\n"); + dev_dbg(&pps->dev, "PPS_FETCH\n"); err = copy_from_user(&fdata, uarg, sizeof(struct pps_fdata)); if (err) @@ -206,7 +206,7 @@ case PPS_KC_BIND: { struct pps_bind_args bind_args; - dev_dbg(pps->dev, "PPS_KC_BIND\n"); + dev_dbg(&pps->dev, "PPS_KC_BIND\n"); /* Check the capabilities */ if (!capable(CAP_SYS_TIME)) @@ -218,7 +218,7 @@ /* Check for supported capabilities */ if ((bind_args.edge & ~pps->info.mode) != 0) { - dev_err(pps->dev, "unsupported capabilities (%x)\n", + dev_err(&pps->dev, "unsupported capabilities (%x)\n", bind_args.edge); return -EINVAL; } @@ -227,7 +227,7 @@ if (bind_args.tsformat != PPS_TSFMT_TSPEC || (bind_args.edge & ~PPS_CAPTUREBOTH) != 0 || bind_args.consumer != PPS_KC_HARDPPS) { - dev_err(pps->dev, "invalid kernel consumer bind" + dev_err(&pps->dev, "invalid kernel consumer bind" " parameters (%x)\n", bind_args.edge); return -EINVAL; } @@ -259,7 +259,7 @@ struct pps_fdata fdata; int err; - dev_dbg(pps->dev, "PPS_FETCH\n"); + dev_dbg(&pps->dev, "PPS_FETCH\n"); err = copy_from_user(&compat, uarg, sizeof(struct pps_fdata_compat)); if (err) @@ -296,20 +296,36 @@ #define pps_cdev_compat_ioctl NULL #endif +static struct pps_device *pps_idr_get(unsigned long id) +{ + struct pps_device *pps; + + mutex_lock(&pps_idr_lock); + pps = idr_find(&pps_idr, id); + if (pps) + get_device(&pps->dev); + + mutex_unlock(&pps_idr_lock); + return pps; +} + static int pps_cdev_open(struct inode *inode, struct file *file) { - struct pps_device *pps = container_of(inode->i_cdev, - struct pps_device, cdev); + struct pps_device *pps = pps_idr_get(iminor(inode)); + + if (!pps) + return -ENODEV; + file->private_data = pps; - kobject_get(&pps->dev->kobj); return 0; } static int pps_cdev_release(struct inode *inode, struct file *file) { - struct pps_device *pps = container_of(inode->i_cdev, - struct pps_device, cdev); - kobject_put(&pps->dev->kobj); + struct pps_device *pps = file->private_data; + + WARN_ON(pps->id != iminor(inode)); + put_device(&pps->dev); return 0; } @@ -332,22 +348,13 @@ { struct pps_device *pps = dev_get_drvdata(dev); - cdev_del(&pps->cdev); - - /* Now we can release the ID for re-use */ pr_debug("deallocating pps%d\n", pps->id); - mutex_lock(&pps_idr_lock); - idr_remove(&pps_idr, pps->id); - mutex_unlock(&pps_idr_lock); - - kfree(dev); kfree(pps); } int pps_register_cdev(struct pps_device *pps) { int err; - dev_t devt; mutex_lock(&pps_idr_lock); /* @@ -364,40 +371,29 @@ goto out_unlock; } pps->id = err; - mutex_unlock(&pps_idr_lock); - - devt = MKDEV(MAJOR(pps_devt), pps->id); - - cdev_init(&pps->cdev, &pps_cdev_fops); - pps->cdev.owner = pps->info.owner; - err = cdev_add(&pps->cdev, devt, 1); - if (err) { - pr_err("%s: failed to add char device %d:%d\n", - pps->info.name, MAJOR(pps_devt), pps->id); + pps->dev.class = pps_class; + pps->dev.parent = pps->info.dev; + pps->dev.devt = MKDEV(pps_major, pps->id); + dev_set_drvdata(&pps->dev, pps); + dev_set_name(&pps->dev, "pps%d", pps->id); + err = device_register(&pps->dev); + if (err) goto free_idr; - } - pps->dev = device_create(pps_class, pps->info.dev, devt, pps, - "pps%d", pps->id); - if (IS_ERR(pps->dev)) { - err = PTR_ERR(pps->dev); - goto del_cdev; - } /* Override the release function with our own */ - pps->dev->release = pps_device_destruct; + pps->dev.release = pps_device_destruct; - pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, - MAJOR(pps_devt), pps->id); + pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, pps_major, + pps->id); + get_device(&pps->dev); + mutex_unlock(&pps_idr_lock); return 0; -del_cdev: - cdev_del(&pps->cdev); - free_idr: - mutex_lock(&pps_idr_lock); idr_remove(&pps_idr, pps->id); + put_device(&pps->dev); out_unlock: mutex_unlock(&pps_idr_lock); return err; @@ -407,7 +403,13 @@ { pr_debug("unregistering pps%d\n", pps->id); pps->lookup_cookie = NULL; - device_destroy(pps_class, pps->dev->devt); + device_destroy(pps_class, pps->dev.devt); + + /* Now we can release the ID for re-use */ + mutex_lock(&pps_idr_lock); + idr_remove(&pps_idr, pps->id); + put_device(&pps->dev); + mutex_unlock(&pps_idr_lock); } /* @@ -427,6 +429,11 @@ * so that it will not be used again, even if the pps device cannot * be removed from the idr due to pending references holding the minor * number in use. + * + * Since pps_idr holds a reference to the device, the returned + * pps_device is guaranteed to be valid until pps_unregister_cdev() is + * called on it. But after calling pps_unregister_cdev(), it may be + * freed at any time. */ struct pps_device *pps_lookup_dev(void const *cookie) { @@ -449,13 +456,11 @@ static void __exit pps_exit(void) { class_destroy(pps_class); - unregister_chrdev_region(pps_devt, PPS_MAX_SOURCES); + __unregister_chrdev(pps_major, 0, PPS_MAX_SOURCES, "pps"); } static int __init pps_init(void) { - int err; - pps_class = class_create(THIS_MODULE, "pps"); if (IS_ERR(pps_class)) { pr_err("failed to allocate class\n"); @@ -463,8 +468,9 @@ } pps_class->dev_groups = pps_groups; - err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); - if (err < 0) { + pps_major = __register_chrdev(0, 0, PPS_MAX_SOURCES, "pps", + &pps_cdev_fops); + if (pps_major < 0) { pr_err("failed to allocate char device region\n"); goto remove_class; } @@ -477,8 +483,7 @@ remove_class: class_destroy(pps_class); - - return err; + return pps_major; } subsys_initcall(pps_init); --- linux-oracle-5.4.0.orig/drivers/ps3/ps3stor_lib.c +++ linux-oracle-5.4.0/drivers/ps3/ps3stor_lib.c @@ -189,7 +189,7 @@ dev->bounce_lpar = ps3_mm_phys_to_lpar(__pa(dev->bounce_buf)); dev->bounce_dma = dma_map_single(&dev->sbd.core, dev->bounce_buf, dev->bounce_size, DMA_BIDIRECTIONAL); - if (!dev->bounce_dma) { + if (dma_mapping_error(&dev->sbd.core, dev->bounce_dma)) { dev_err(&dev->sbd.core, "%s:%u: map DMA region failed\n", __func__, __LINE__); error = -ENODEV; --- linux-oracle-5.4.0.orig/drivers/ptp/Kconfig +++ linux-oracle-5.4.0/drivers/ptp/Kconfig @@ -92,7 +92,8 @@ config PTP_1588_CLOCK_PCH tristate "Intel PCH EG20T as PTP clock" depends on X86_32 || COMPILE_TEST - depends on HAS_IOMEM && NET + depends on HAS_IOMEM && PCI + depends on NET imply PTP_1588_CLOCK help This driver adds support for using the PCH EG20T as a PTP --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_chardev.c +++ linux-oracle-5.4.0/drivers/ptp/ptp_chardev.c @@ -84,7 +84,8 @@ } if (info->verify(info, pin, func, chan)) { - pr_err("driver cannot use function %u on pin %u\n", func, chan); + pr_err("driver cannot use function %u and channel %u on pin %u\n", + func, chan, pin); return -EOPNOTSUPP; } @@ -443,7 +444,8 @@ for (i = 0; i < cnt; i++) { event[i] = queue->buf[queue->head]; - queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + /* Paired with READ_ONCE() in queue_cnt() */ + WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); } spin_unlock_irqrestore(&queue->lock, flags); --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_clock.c +++ linux-oracle-5.4.0/drivers/ptp/ptp_clock.c @@ -55,15 +55,16 @@ dst->t.sec = seconds; dst->t.nsec = remainder; + /* Both WRITE_ONCE() are paired with READ_ONCE() in queue_cnt() */ if (!queue_free(queue)) - queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); - queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS; + WRITE_ONCE(queue->tail, (queue->tail + 1) % PTP_MAX_TIMESTAMPS); spin_unlock_irqrestore(&queue->lock, flags); } -s32 scaled_ppm_to_ppb(long ppm) +long scaled_ppm_to_ppb(long ppm) { /* * The 'freq' field in the 'struct timex' is in parts per @@ -80,7 +81,7 @@ s64 ppb = 1 + ppm; ppb *= 125; ppb >>= 13; - return (s32) ppb; + return (long) ppb; } EXPORT_SYMBOL(scaled_ppm_to_ppb); @@ -138,7 +139,7 @@ delta = ktime_to_ns(kt); err = ops->adjtime(ops, delta); } else if (tx->modes & ADJ_FREQUENCY) { - s32 ppb = scaled_ppm_to_ppb(tx->freq); + long ppb = scaled_ppm_to_ppb(tx->freq); if (ppb > ops->max_adj || ppb < -ops->max_adj) return -ERANGE; if (ops->adjfine) @@ -166,16 +167,25 @@ .read = ptp_read, }; -static void delete_ptp_clock(struct posix_clock *pc) +static void ptp_clock_release(struct device *dev) { - struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); + struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev); + /* Release the clock's resources. */ + if (ptp->pps_source) + pps_unregister_source(ptp->pps_source); + ptp_cleanup_pin_groups(ptp); mutex_destroy(&ptp->tsevq_mux); mutex_destroy(&ptp->pincfg_mux); ida_simple_remove(&ptp_clocks_map, ptp->index); kfree(ptp); } +static int ptp_enable(struct ptp_clock_info *ptp, struct ptp_clock_request *request, int on) +{ + return -EOPNOTSUPP; +} + static void ptp_aux_kworker(struct kthread_work *work) { struct ptp_clock *ptp = container_of(work, struct ptp_clock, @@ -213,7 +223,6 @@ } ptp->clock.ops = ptp_clock_ops; - ptp->clock.release = delete_ptp_clock; ptp->info = info; ptp->devid = MKDEV(major, index); ptp->index = index; @@ -222,6 +231,9 @@ mutex_init(&ptp->pincfg_mux); init_waitqueue_head(&ptp->tsev_wq); + if (!ptp->info->enable) + ptp->info->enable = ptp_enable; + if (ptp->info->do_aux_work) { kthread_init_delayed_work(&ptp->aux_work, ptp_aux_kworker); ptp->kworker = kthread_create_worker(0, "ptp%d", ptp->index); @@ -236,15 +248,6 @@ if (err) goto no_pin_groups; - /* Create a new device in our class. */ - ptp->dev = device_create_with_groups(ptp_class, parent, ptp->devid, - ptp, ptp->pin_attr_groups, - "ptp%d", ptp->index); - if (IS_ERR(ptp->dev)) { - err = PTR_ERR(ptp->dev); - goto no_device; - } - /* Register a new PPS source. */ if (info->pps) { struct pps_source_info pps; @@ -260,8 +263,18 @@ } } - /* Create a posix clock. */ - err = posix_clock_register(&ptp->clock, ptp->devid); + /* Initialize a new device of our class in our clock structure. */ + device_initialize(&ptp->dev); + ptp->dev.devt = ptp->devid; + ptp->dev.class = ptp_class; + ptp->dev.parent = parent; + ptp->dev.groups = ptp->pin_attr_groups; + ptp->dev.release = ptp_clock_release; + dev_set_drvdata(&ptp->dev, ptp); + dev_set_name(&ptp->dev, "ptp%d", ptp->index); + + /* Create a posix clock and link it to the device. */ + err = posix_clock_register(&ptp->clock, &ptp->dev); if (err) { pr_err("failed to create posix clock\n"); goto no_clock; @@ -273,8 +286,6 @@ if (ptp->pps_source) pps_unregister_source(ptp->pps_source); no_pps: - device_destroy(ptp_class, ptp->devid); -no_device: ptp_cleanup_pin_groups(ptp); no_pin_groups: if (ptp->kworker) @@ -299,15 +310,8 @@ kthread_cancel_delayed_work_sync(&ptp->aux_work); kthread_destroy_worker(ptp->kworker); } - - /* Release the clock's resources. */ - if (ptp->pps_source) - pps_unregister_source(ptp->pps_source); - - device_destroy(ptp_class, ptp->devid); - ptp_cleanup_pin_groups(ptp); - posix_clock_unregister(&ptp->clock); + return 0; } EXPORT_SYMBOL(ptp_clock_unregister); --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_pch.c +++ linux-oracle-5.4.0/drivers/ptp/ptp_pch.c @@ -683,6 +683,7 @@ }, {0} }; +MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id); static struct pci_driver pch_driver = { .name = KBUILD_MODNAME, --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_private.h +++ linux-oracle-5.4.0/drivers/ptp/ptp_private.h @@ -28,7 +28,7 @@ struct ptp_clock { struct posix_clock clock; - struct device *dev; + struct device dev; struct ptp_clock_info *info; dev_t devid; int index; /* index into clocks.map */ @@ -55,9 +55,13 @@ * that a writer might concurrently increment the tail does not * matter, since the queue remains nonempty nonetheless. */ -static inline int queue_cnt(struct timestamp_event_queue *q) +static inline int queue_cnt(const struct timestamp_event_queue *q) { - int cnt = q->tail - q->head; + /* + * Paired with WRITE_ONCE() in enqueue_external_timestamp(), + * ptp_read(), extts_fifo_show(). + */ + int cnt = READ_ONCE(q->tail) - READ_ONCE(q->head); return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt; } --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_qoriq.c +++ linux-oracle-5.4.0/drivers/ptp/ptp_qoriq.c @@ -604,7 +604,7 @@ return 0; no_clock: - iounmap(ptp_qoriq->base); + iounmap(base); no_ioremap: release_resource(ptp_qoriq->rsrc); no_resource: --- linux-oracle-5.4.0.orig/drivers/ptp/ptp_sysfs.c +++ linux-oracle-5.4.0/drivers/ptp/ptp_sysfs.c @@ -13,7 +13,7 @@ struct device_attribute *attr, char *page) { struct ptp_clock *ptp = dev_get_drvdata(dev); - return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); + return sysfs_emit(page, "%s\n", ptp->info->name); } static DEVICE_ATTR_RO(clock_name); @@ -78,7 +78,8 @@ qcnt = queue_cnt(queue); if (qcnt) { event = queue->buf[queue->head]; - queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; + /* Paired with READ_ONCE() in queue_cnt() */ + WRITE_ONCE(queue->head, (queue->head + 1) % PTP_MAX_TIMESTAMPS); } spin_unlock_irqrestore(&queue->lock, flags); @@ -227,7 +228,7 @@ mutex_unlock(&ptp->pincfg_mux); - return snprintf(page, PAGE_SIZE, "%u %u\n", func, chan); + return sysfs_emit(page, "%u %u\n", func, chan); } static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr, --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-bcm-iproc.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-bcm-iproc.c @@ -85,8 +85,6 @@ u64 tmp, multi, rate; u32 value, prescale; - rate = clk_get_rate(ip->clk); - value = readl(ip->base + IPROC_PWM_CTRL_OFFSET); if (value & BIT(IPROC_PWM_CTRL_EN_SHIFT(pwm->hwpwm))) @@ -99,6 +97,13 @@ else state->polarity = PWM_POLARITY_INVERSED; + rate = clk_get_rate(ip->clk); + if (rate == 0) { + state->period = 0; + state->duty_cycle = 0; + return; + } + value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET); prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm); prescale &= IPROC_PWM_PRESCALE_MAX; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-bcm2835.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-bcm2835.c @@ -166,6 +166,7 @@ pc->chip.dev = &pdev->dev; pc->chip.ops = &bcm2835_pwm_ops; + pc->chip.base = -1; pc->chip.npwm = 2; pc->chip.of_xlate = of_pwm_xlate_with_flags; pc->chip.of_pwm_n_cells = 3; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-brcmstb.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-brcmstb.c @@ -298,7 +298,7 @@ { struct brcmstb_pwm *p = dev_get_drvdata(dev); - clk_disable(p->clk); + clk_disable_unprepare(p->clk); return 0; } @@ -307,7 +307,7 @@ { struct brcmstb_pwm *p = dev_get_drvdata(dev); - clk_enable(p->clk); + clk_prepare_enable(p->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-cros-ec.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-cros-ec.c @@ -125,6 +125,7 @@ state->enabled = (ret > 0); state->period = EC_PWM_MAX_DUTY; + state->polarity = PWM_POLARITY_NORMAL; /* Note that "disabled" and "duty cycle == 0" are treated the same */ state->duty_cycle = ret; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-hibvt.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-hibvt.c @@ -146,6 +146,7 @@ value = readl(base + PWM_CTRL_ADDR(pwm->hwpwm)); state->enabled = (PWM_ENABLE_MASK & value); + state->polarity = (PWM_POLARITY_MASK & value) ? PWM_POLARITY_INVERSED : PWM_POLARITY_NORMAL; } static int hibvt_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-img.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-img.c @@ -129,8 +129,10 @@ duty = DIV_ROUND_UP(timebase * duty_ns, period_ns); ret = pm_runtime_get_sync(chip->dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_autosuspend(chip->dev); return ret; + } val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); val &= ~(PWM_CTRL_CFG_DIV_MASK << PWM_CTRL_CFG_DIV_SHIFT(pwm->hwpwm)); @@ -154,7 +156,7 @@ struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip); int ret; - ret = pm_runtime_get_sync(chip->dev); + ret = pm_runtime_resume_and_get(chip->dev); if (ret < 0) return ret; @@ -275,6 +277,8 @@ return PTR_ERR(pwm->pwm_clk); } + platform_set_drvdata(pdev, pwm); + pm_runtime_set_autosuspend_delay(&pdev->dev, IMG_PWM_PM_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -311,7 +315,6 @@ goto err_suspend; } - platform_set_drvdata(pdev, pwm); return 0; err_suspend: @@ -326,21 +329,7 @@ static int img_pwm_remove(struct platform_device *pdev) { struct img_pwm_chip *pwm_chip = platform_get_drvdata(pdev); - u32 val; - unsigned int i; - int ret; - - ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) - return ret; - - for (i = 0; i < pwm_chip->chip.npwm; i++) { - val = img_pwm_readl(pwm_chip, PWM_CTRL_CFG); - val &= ~BIT(i); - img_pwm_writel(pwm_chip, PWM_CTRL_CFG, val); - } - pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); if (!pm_runtime_status_suspended(&pdev->dev)) img_pwm_runtime_suspend(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-imx-tpm.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-imx-tpm.c @@ -108,7 +108,9 @@ p->prescale = prescale; period_count = (clock_unit + ((1 << prescale) >> 1)) >> prescale; - p->mod = period_count; + if (period_count == 0) + return -EINVAL; + p->mod = period_count - 1; /* calculate real period HW can support */ tmp = (u64)period_count << prescale; @@ -405,6 +407,13 @@ if (tpm->enable_count > 0) return -EBUSY; + /* + * Force 'real_period' to be zero to force period update code + * can be executed after system resume back, since suspend causes + * the period related registers to become their reset values. + */ + tpm->real_period = 0; + clk_disable_unprepare(tpm->clk); return 0; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-imx1.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-imx1.c @@ -180,8 +180,6 @@ { struct pwm_imx1_chip *imx = platform_get_drvdata(pdev); - pwm_imx1_clk_disable_unprepare(&imx->chip); - return pwmchip_remove(&imx->chip); } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-jz4740.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-jz4740.c @@ -92,11 +92,12 @@ { struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip); unsigned long long tmp; - unsigned long period, duty; + unsigned long rate, period, duty; unsigned int prescaler = 0; uint16_t ctrl; - tmp = (unsigned long long)clk_get_rate(jz4740->clk) * state->period; + rate = clk_get_rate(jz4740->clk); + tmp = rate * state->period; do_div(tmp, 1000000000); period = tmp; @@ -108,8 +109,8 @@ if (prescaler == 6) return -EINVAL; - tmp = (unsigned long long)period * state->duty_cycle; - do_div(tmp, state->period); + tmp = (unsigned long long)rate * state->duty_cycle; + do_div(tmp, NSEC_PER_SEC); duty = period - tmp; if (duty >= period) --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-lp3943.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-lp3943.c @@ -125,6 +125,7 @@ if (err) return err; + duty_ns = min(duty_ns, period_ns); val = (u8)(duty_ns * LP3943_MAX_DUTY / period_ns); return lp3943_write_byte(lp3943, reg_duty, val); @@ -275,6 +276,7 @@ lp3943_pwm->chip.dev = &pdev->dev; lp3943_pwm->chip.ops = &lp3943_pwm_ops; lp3943_pwm->chip.npwm = LP3943_NUM_PWMS; + lp3943_pwm->chip.base = -1; platform_set_drvdata(pdev, lp3943_pwm); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-lpc18xx-sct.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-lpc18xx-sct.c @@ -400,12 +400,6 @@ lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_LIMIT, BIT(lpc18xx_pwm->period_event)); - ret = pwmchip_add(&lpc18xx_pwm->chip); - if (ret < 0) { - dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret); - goto disable_pwmclk; - } - for (i = 0; i < lpc18xx_pwm->chip.npwm; i++) { struct lpc18xx_pwm_data *data; @@ -415,14 +409,12 @@ GFP_KERNEL); if (!data) { ret = -ENOMEM; - goto remove_pwmchip; + goto disable_pwmclk; } pwm_set_chip_data(pwm, data); } - platform_set_drvdata(pdev, lpc18xx_pwm); - val = lpc18xx_pwm_readl(lpc18xx_pwm, LPC18XX_PWM_CTRL); val &= ~LPC18XX_PWM_BIDIR; val &= ~LPC18XX_PWM_CTRL_HALT; @@ -430,10 +422,16 @@ val |= LPC18XX_PWM_PRE(0); lpc18xx_pwm_writel(lpc18xx_pwm, LPC18XX_PWM_CTRL, val); + ret = pwmchip_add(&lpc18xx_pwm->chip); + if (ret < 0) { + dev_err(&pdev->dev, "pwmchip_add failed: %d\n", ret); + goto disable_pwmclk; + } + + platform_set_drvdata(pdev, lpc18xx_pwm); + return 0; -remove_pwmchip: - pwmchip_remove(&lpc18xx_pwm->chip); disable_pwmclk: clk_disable_unprepare(lpc18xx_pwm->pwm_clk); return ret; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-lpc32xx.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-lpc32xx.c @@ -51,10 +51,10 @@ if (duty_cycles > 255) duty_cycles = 255; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val &= ~0xFFFF; val |= (period_cycles << 8) | duty_cycles; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); return 0; } @@ -69,9 +69,9 @@ if (ret) return ret; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val |= PWM_ENABLE; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); return 0; } @@ -81,9 +81,9 @@ struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip); u32 val; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val &= ~PWM_ENABLE; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); clk_disable_unprepare(lpc32xx->clk); } @@ -120,17 +120,17 @@ lpc32xx->chip.npwm = 1; lpc32xx->chip.base = -1; + /* If PWM is disabled, configure the output to the default value */ + val = readl(lpc32xx->base); + val &= ~PWM_PIN_LEVEL; + writel(val, lpc32xx->base); + ret = pwmchip_add(&lpc32xx->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add PWM chip, error %d\n", ret); return ret; } - /* When PWM is disable, configure the output to the default value */ - val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); - val &= ~PWM_PIN_LEVEL; - writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); - platform_set_drvdata(pdev, lpc32xx); return 0; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-lpss.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-lpss.c @@ -93,10 +93,12 @@ * The equation is: * base_unit = round(base_unit_range * freq / c) */ - base_unit_range = BIT(lpwm->info->base_unit_bits) - 1; + base_unit_range = BIT(lpwm->info->base_unit_bits); freq *= base_unit_range; base_unit = DIV_ROUND_CLOSEST_ULL(freq, c); + /* base_unit must not be 0 and we also want to avoid overflowing it */ + base_unit = clamp_val(base_unit, 1, base_unit_range - 1); on_time_div = 255ULL * duty_ns; do_div(on_time_div, period_ns); @@ -104,8 +106,7 @@ orig_ctrl = ctrl = pwm_lpss_read(pwm); ctrl &= ~PWM_ON_TIME_DIV_MASK; - ctrl &= ~(base_unit_range << PWM_BASE_UNIT_SHIFT); - base_unit &= base_unit_range; + ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT); ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT; ctrl |= on_time_div; --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-meson.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-meson.c @@ -147,12 +147,13 @@ return err; } - return pwm_set_chip_data(pwm, channel); + return 0; } static void meson_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { - struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); + struct meson_pwm *meson = to_meson_pwm(chip); + struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; if (channel) clk_disable_unprepare(channel->clk); @@ -161,13 +162,20 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm, const struct pwm_state *state) { - struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); - unsigned int duty, period, pre_div, cnt, duty_cnt; - unsigned long fin_freq = -1; + struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; + unsigned int pre_div, cnt, duty_cnt; + unsigned long fin_freq; + u64 duty, period; duty = state->duty_cycle; period = state->period; + /* + * Note this is wrong. The result is an output wave that isn't really + * inverted and so is wrongly identified by .get_state as normal. + * Fixing this needs some care however as some machines might rely on + * this. + */ if (state->polarity == PWM_POLARITY_INVERSED) duty = period - duty; @@ -179,19 +187,19 @@ dev_dbg(meson->chip.dev, "fin_freq: %lu Hz\n", fin_freq); - pre_div = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * 0xffffLL); + pre_div = div64_u64(fin_freq * period, NSEC_PER_SEC * 0xffffLL); if (pre_div > MISC_CLK_DIV_MASK) { dev_err(meson->chip.dev, "unable to get period pre_div\n"); return -EINVAL; } - cnt = div64_u64(fin_freq * (u64)period, NSEC_PER_SEC * (pre_div + 1)); + cnt = div64_u64(fin_freq * period, NSEC_PER_SEC * (pre_div + 1)); if (cnt > 0xffff) { dev_err(meson->chip.dev, "unable to get period cnt\n"); return -EINVAL; } - dev_dbg(meson->chip.dev, "period=%u pre_div=%u cnt=%u\n", period, + dev_dbg(meson->chip.dev, "period=%llu pre_div=%u cnt=%u\n", period, pre_div, cnt); if (duty == period) { @@ -204,14 +212,13 @@ channel->lo = cnt; } else { /* Then check is we can have the duty with the same pre_div */ - duty_cnt = div64_u64(fin_freq * (u64)duty, - NSEC_PER_SEC * (pre_div + 1)); + duty_cnt = div64_u64(fin_freq * duty, NSEC_PER_SEC * (pre_div + 1)); if (duty_cnt > 0xffff) { dev_err(meson->chip.dev, "unable to get duty cycle\n"); return -EINVAL; } - dev_dbg(meson->chip.dev, "duty=%u pre_div=%u duty_cnt=%u\n", + dev_dbg(meson->chip.dev, "duty=%llu pre_div=%u duty_cnt=%u\n", duty, pre_div, duty_cnt); channel->pre_div = pre_div; @@ -224,7 +231,7 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm) { - struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); + struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; struct meson_pwm_channel_data *channel_data; unsigned long flags; u32 value; @@ -267,8 +274,8 @@ static int meson_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { - struct meson_pwm_channel *channel = pwm_get_chip_data(pwm); struct meson_pwm *meson = to_meson_pwm(chip); + struct meson_pwm_channel *channel = &meson->channels[pwm->hwpwm]; int err = 0; if (!state) @@ -366,6 +373,7 @@ state->period = 0; state->duty_cycle = 0; } + state->polarity = PWM_POLARITY_NORMAL; } static const struct pwm_ops meson_pwm_ops = { @@ -417,7 +425,7 @@ }; static const char * const pwm_axg_ao_parent_names[] = { - "aoclk81", "xtal", "fclk_div4", "fclk_div5" + "xtal", "axg_ao_clk81", "fclk_div4", "fclk_div5" }; static const struct meson_pwm_data pwm_axg_ao_data = { @@ -426,7 +434,7 @@ }; static const char * const pwm_g12a_ao_ab_parent_names[] = { - "xtal", "aoclk81", "fclk_div4", "fclk_div5" + "xtal", "g12a_ao_clk81", "fclk_div4", "fclk_div5" }; static const struct meson_pwm_data pwm_g12a_ao_ab_data = { @@ -435,7 +443,7 @@ }; static const char * const pwm_g12a_ao_cd_parent_names[] = { - "xtal", "aoclk81", + "xtal", "g12a_ao_clk81", }; static const struct meson_pwm_data pwm_g12a_ao_cd_data = { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-mtk-disp.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-mtk-disp.c @@ -74,6 +74,19 @@ u64 div, rate; int err; + err = clk_prepare_enable(mdp->clk_main); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); + return err; + } + + err = clk_prepare_enable(mdp->clk_mm); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); + return err; + } + /* * Find period, high_width and clk_div to suit duty_ns and period_ns. * Calculate proper div value to keep period value in the bound. @@ -87,8 +100,11 @@ rate = clk_get_rate(mdp->clk_main); clk_div = div_u64(rate * period_ns, NSEC_PER_SEC) >> PWM_PERIOD_BIT_WIDTH; - if (clk_div > PWM_CLKDIV_MAX) + if (clk_div > PWM_CLKDIV_MAX) { + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); return -EINVAL; + } div = NSEC_PER_SEC * (clk_div + 1); period = div64_u64(rate * period_ns, div); @@ -98,14 +114,17 @@ high_width = div64_u64(rate * duty_ns, div); value = period | (high_width << PWM_HIGH_WIDTH_SHIFT); - err = clk_enable(mdp->clk_main); - if (err < 0) - return err; - - err = clk_enable(mdp->clk_mm); - if (err < 0) { - clk_disable(mdp->clk_main); - return err; + if (mdp->data->bls_debug && !mdp->data->has_commit) { + /* + * For MT2701, disable double buffer before writing register + * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. + */ + mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, + mdp->data->bls_debug_mask, + mdp->data->bls_debug_mask); + mtk_disp_pwm_update_bits(mdp, mdp->data->con0, + mdp->data->con0_sel, + mdp->data->con0_sel); } mtk_disp_pwm_update_bits(mdp, mdp->data->con0, @@ -124,8 +143,8 @@ 0x0); } - clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); return 0; } @@ -135,13 +154,16 @@ struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip); int err; - err = clk_enable(mdp->clk_main); - if (err < 0) + err = clk_prepare_enable(mdp->clk_main); + if (err < 0) { + dev_err(chip->dev, "Can't enable mdp->clk_main: %pe\n", ERR_PTR(err)); return err; + } - err = clk_enable(mdp->clk_mm); + err = clk_prepare_enable(mdp->clk_mm); if (err < 0) { - clk_disable(mdp->clk_main); + dev_err(chip->dev, "Can't enable mdp->clk_mm: %pe\n", ERR_PTR(err)); + clk_disable_unprepare(mdp->clk_main); return err; } @@ -158,8 +180,8 @@ mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask, 0x0); - clk_disable(mdp->clk_mm); - clk_disable(mdp->clk_main); + clk_disable_unprepare(mdp->clk_mm); + clk_disable_unprepare(mdp->clk_main); } static const struct pwm_ops mtk_disp_pwm_ops = { @@ -194,14 +216,6 @@ if (IS_ERR(mdp->clk_mm)) return PTR_ERR(mdp->clk_mm); - ret = clk_prepare(mdp->clk_main); - if (ret < 0) - return ret; - - ret = clk_prepare(mdp->clk_mm); - if (ret < 0) - goto disable_clk_main; - mdp->chip.dev = &pdev->dev; mdp->chip.ops = &mtk_disp_pwm_ops; mdp->chip.base = -1; @@ -209,44 +223,22 @@ ret = pwmchip_add(&mdp->chip); if (ret < 0) { - dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - goto disable_clk_mm; + dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret)); + return ret; } platform_set_drvdata(pdev, mdp); - /* - * For MT2701, disable double buffer before writing register - * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH. - */ - if (!mdp->data->has_commit) { - mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug, - mdp->data->bls_debug_mask, - mdp->data->bls_debug_mask); - mtk_disp_pwm_update_bits(mdp, mdp->data->con0, - mdp->data->con0_sel, - mdp->data->con0_sel); - } - return 0; - -disable_clk_mm: - clk_unprepare(mdp->clk_mm); -disable_clk_main: - clk_unprepare(mdp->clk_main); - return ret; } static int mtk_disp_pwm_remove(struct platform_device *pdev) { struct mtk_disp_pwm *mdp = platform_get_drvdata(pdev); - int ret; - ret = pwmchip_remove(&mdp->chip); - clk_unprepare(mdp->clk_mm); - clk_unprepare(mdp->clk_main); + pwmchip_remove(&mdp->chip); - return ret; + return 0; } static const struct mtk_pwm_data mt2701_pwm_data = { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-omap-dmtimer.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-omap-dmtimer.c @@ -256,7 +256,7 @@ if (!timer_pdev) { dev_err(&pdev->dev, "Unable to find Timer pdev\n"); ret = -ENODEV; - goto put; + goto err_find_timer_pdev; } timer_pdata = dev_get_platdata(&timer_pdev->dev); @@ -264,7 +264,7 @@ dev_dbg(&pdev->dev, "dmtimer pdata structure NULL, deferring probe\n"); ret = -EPROBE_DEFER; - goto put; + goto err_platdata; } pdata = timer_pdata->timer_ops; @@ -283,30 +283,25 @@ !pdata->write_counter) { dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); ret = -EINVAL; - goto put; + goto err_platdata; } if (!of_get_property(timer, "ti,timer-pwm", NULL)) { dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); ret = -ENODEV; - goto put; + goto err_timer_property; } dm_timer = pdata->request_by_node(timer); if (!dm_timer) { ret = -EPROBE_DEFER; - goto put; + goto err_request_timer; } -put: - of_node_put(timer); - if (ret < 0) - return ret; - omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); if (!omap) { - pdata->free(dm_timer); - return -ENOMEM; + ret = -ENOMEM; + goto err_alloc_omap; } omap->pdata = pdata; @@ -339,27 +334,56 @@ ret = pwmchip_add(&omap->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM\n"); - omap->pdata->free(omap->dm_timer); - return ret; + goto err_pwmchip_add; } + of_node_put(timer); + platform_set_drvdata(pdev, omap); return 0; + +err_pwmchip_add: + + /* + * *omap is allocated using devm_kzalloc, + * so no free necessary here + */ +err_alloc_omap: + + pdata->free(dm_timer); +err_request_timer: + +err_timer_property: +err_platdata: + + put_device(&timer_pdev->dev); +err_find_timer_pdev: + + of_node_put(timer); + + return ret; } static int pwm_omap_dmtimer_remove(struct platform_device *pdev) { struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev); + int ret; + + ret = pwmchip_remove(&omap->chip); + if (ret) + return ret; if (pm_runtime_active(&omap->dm_timer_pdev->dev)) omap->pdata->stop(omap->dm_timer); omap->pdata->free(omap->dm_timer); + put_device(&omap->dm_timer_pdev->dev); + mutex_destroy(&omap->mutex); - return pwmchip_remove(&omap->chip); + return 0; } static const struct of_device_id pwm_omap_dmtimer_of_match[] = { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-pca9685.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-pca9685.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * Because the PCA9685 has only one prescaler per chip, changing the period of @@ -74,6 +75,7 @@ #if IS_ENABLED(CONFIG_GPIOLIB) struct mutex lock; struct gpio_chip gpio; + DECLARE_BITMAP(pwms_inuse, PCA9685_MAXCHAN + 1); #endif }; @@ -83,51 +85,51 @@ } #if IS_ENABLED(CONFIG_GPIOLIB) -static int pca9685_pwm_gpio_request(struct gpio_chip *gpio, unsigned int offset) +static bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca, int pwm_idx) { - struct pca9685 *pca = gpiochip_get_data(gpio); - struct pwm_device *pwm; + bool is_inuse; mutex_lock(&pca->lock); - - pwm = &pca->chip.pwms[offset]; - - if (pwm->flags & (PWMF_REQUESTED | PWMF_EXPORTED)) { - mutex_unlock(&pca->lock); - return -EBUSY; + if (pwm_idx >= PCA9685_MAXCHAN) { + /* + * "all LEDs" channel: + * pretend already in use if any of the PWMs are requested + */ + if (!bitmap_empty(pca->pwms_inuse, PCA9685_MAXCHAN)) { + is_inuse = true; + goto out; + } + } else { + /* + * regular channel: + * pretend already in use if the "all LEDs" channel is requested + */ + if (test_bit(PCA9685_MAXCHAN, pca->pwms_inuse)) { + is_inuse = true; + goto out; + } } - - pwm_set_chip_data(pwm, (void *)1); - + is_inuse = test_and_set_bit(pwm_idx, pca->pwms_inuse); +out: mutex_unlock(&pca->lock); - pm_runtime_get_sync(pca->chip.dev); - return 0; + return is_inuse; } -static bool pca9685_pwm_is_gpio(struct pca9685 *pca, struct pwm_device *pwm) +static void pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) { - bool is_gpio = false; - mutex_lock(&pca->lock); + clear_bit(pwm_idx, pca->pwms_inuse); + mutex_unlock(&pca->lock); +} - if (pwm->hwpwm >= PCA9685_MAXCHAN) { - unsigned int i; - - /* - * Check if any of the GPIOs are requested and in that case - * prevent using the "all LEDs" channel. - */ - for (i = 0; i < pca->gpio.ngpio; i++) - if (gpiochip_is_requested(&pca->gpio, i)) { - is_gpio = true; - break; - } - } else if (pwm_get_chip_data(pwm)) { - is_gpio = true; - } +static int pca9685_pwm_gpio_request(struct gpio_chip *gpio, unsigned int offset) +{ + struct pca9685 *pca = gpiochip_get_data(gpio); - mutex_unlock(&pca->lock); - return is_gpio; + if (pca9685_pwm_test_and_set_inuse(pca, offset)) + return -EBUSY; + pm_runtime_get_sync(pca->chip.dev); + return 0; } static int pca9685_pwm_gpio_get(struct gpio_chip *gpio, unsigned int offset) @@ -159,13 +161,10 @@ static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset) { struct pca9685 *pca = gpiochip_get_data(gpio); - struct pwm_device *pwm; pca9685_pwm_gpio_set(gpio, offset, 0); pm_runtime_put(pca->chip.dev); - mutex_lock(&pca->lock); - pwm = &pca->chip.pwms[offset]; - mutex_unlock(&pca->lock); + pca9685_pwm_clear_inuse(pca, offset); } static int pca9685_pwm_gpio_get_direction(struct gpio_chip *chip, @@ -217,12 +216,17 @@ return devm_gpiochip_add_data(dev, &pca->gpio, pca); } #else -static inline bool pca9685_pwm_is_gpio(struct pca9685 *pca, - struct pwm_device *pwm) +static inline bool pca9685_pwm_test_and_set_inuse(struct pca9685 *pca, + int pwm_idx) { return false; } +static inline void +pca9685_pwm_clear_inuse(struct pca9685 *pca, int pwm_idx) +{ +} + static inline int pca9685_pwm_gpio_probe(struct pca9685 *pca) { return 0; @@ -406,7 +410,7 @@ { struct pca9685 *pca = to_pca(chip); - if (pca9685_pwm_is_gpio(pca, pwm)) + if (pca9685_pwm_test_and_set_inuse(pca, pwm->hwpwm)) return -EBUSY; pm_runtime_get_sync(chip->dev); @@ -415,8 +419,11 @@ static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { + struct pca9685 *pca = to_pca(chip); + pca9685_pwm_disable(chip, pwm); pm_runtime_put(chip->dev); + pca9685_pwm_clear_inuse(pca, pwm->hwpwm); } static const struct pwm_ops pca9685_pwm_ops = { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-rcar.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-rcar.c @@ -228,24 +228,28 @@ rcar_pwm->chip.base = -1; rcar_pwm->chip.npwm = 1; + pm_runtime_enable(&pdev->dev); + ret = pwmchip_add(&rcar_pwm->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM chip: %d\n", ret); + pm_runtime_disable(&pdev->dev); return ret; } - pm_runtime_enable(&pdev->dev); - return 0; } static int rcar_pwm_remove(struct platform_device *pdev) { struct rcar_pwm_chip *rcar_pwm = platform_get_drvdata(pdev); + int ret; + + ret = pwmchip_remove(&rcar_pwm->chip); pm_runtime_disable(&pdev->dev); - return pwmchip_remove(&rcar_pwm->chip); + return ret; } static const struct of_device_id rcar_pwm_of_table[] = { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-renesas-tpu.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-renesas-tpu.c @@ -415,16 +415,17 @@ tpu->chip.base = -1; tpu->chip.npwm = TPU_CHANNEL_MAX; + pm_runtime_enable(&pdev->dev); + ret = pwmchip_add(&tpu->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM chip\n"); + pm_runtime_disable(&pdev->dev); return ret; } dev_info(&pdev->dev, "TPU PWM %d registered\n", tpu->pdev->id); - pm_runtime_enable(&pdev->dev); - return 0; } @@ -434,12 +435,10 @@ int ret; ret = pwmchip_remove(&tpu->chip); - if (ret) - return ret; pm_runtime_disable(&pdev->dev); - return 0; + return ret; } #ifdef CONFIG_OF --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-rockchip.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-rockchip.c @@ -361,7 +361,6 @@ ret = pwmchip_add(&pc->chip); if (ret < 0) { - clk_unprepare(pc->clk); dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); goto err_pclk; } @@ -384,20 +383,6 @@ { struct rockchip_pwm_chip *pc = platform_get_drvdata(pdev); - /* - * Disable the PWM clk before unpreparing it if the PWM device is still - * running. This should only happen when the last PWM user left it - * enabled, or when nobody requested a PWM that was previously enabled - * by the bootloader. - * - * FIXME: Maybe the core should disable all PWM devices in - * pwmchip_remove(). In this case we'd only have to call - * clk_unprepare() after pwmchip_remove(). - * - */ - if (pwm_is_enabled(pc->chip.pwms)) - clk_disable(pc->clk); - clk_unprepare(pc->pclk); clk_unprepare(pc->clk); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-sifive.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-sifive.c @@ -43,7 +43,7 @@ struct pwm_sifive_ddata { struct pwm_chip chip; - struct mutex lock; /* lock to protect user_count */ + struct mutex lock; /* lock to protect user_count and approx_period */ struct notifier_block notifier; struct clk *clk; void __iomem *regs; @@ -78,6 +78,7 @@ mutex_unlock(&ddata->lock); } +/* Called holding ddata->lock */ static void pwm_sifive_update_clock(struct pwm_sifive_ddata *ddata, unsigned long rate) { @@ -166,7 +167,6 @@ return ret; } - mutex_lock(&ddata->lock); cur_state = pwm->state; enabled = cur_state.enabled; @@ -185,14 +185,23 @@ /* The hardware cannot generate a 100% duty cycle */ frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1); + mutex_lock(&ddata->lock); if (state->period != ddata->approx_period) { - if (ddata->user_count != 1) { + /* + * Don't let a 2nd user change the period underneath the 1st user. + * However if ddate->approx_period == 0 this is the first time we set + * any period, so let whoever gets here first set the period so other + * users who agree on the period won't fail. + */ + if (ddata->user_count != 1 && ddata->approx_period) { + mutex_unlock(&ddata->lock); ret = -EBUSY; goto exit; } ddata->approx_period = state->period; pwm_sifive_update_clock(ddata, clk_get_rate(ddata->clk)); } + mutex_unlock(&ddata->lock); writel(frac, ddata->regs + PWM_SIFIVE_PWMCMP0 + pwm->hwpwm * PWM_SIFIVE_SIZE_PWMCMP); @@ -202,7 +211,6 @@ exit: clk_disable(ddata->clk); - mutex_unlock(&ddata->lock); return ret; } @@ -221,8 +229,11 @@ struct pwm_sifive_ddata *ddata = container_of(nb, struct pwm_sifive_ddata, notifier); - if (event == POST_RATE_CHANGE) + if (event == POST_RATE_CHANGE) { + mutex_lock(&ddata->lock); pwm_sifive_update_clock(ddata, ndata->new_rate); + mutex_unlock(&ddata->lock); + } return NOTIFY_OK; } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-spear.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-spear.c @@ -231,10 +231,6 @@ static int spear_pwm_remove(struct platform_device *pdev) { struct spear_pwm_chip *pc = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < NUM_PWM; i++) - pwm_disable(&pc->chip.pwms[i]); /* clk was prepared in probe, hence unprepare it here */ clk_unprepare(pc->clk); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-sprd.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-sprd.c @@ -109,6 +109,7 @@ duty = val & SPRD_PWM_DUTY_MSK; tmp = (prescale + 1) * NSEC_PER_SEC * duty; state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, chn->clk_rate); + state->polarity = PWM_POLARITY_NORMAL; /* Disable PWM clocks if the PWM channel is not in enable state. */ if (!state->enabled) @@ -180,13 +181,10 @@ } } - if (state->period != cstate->period || - state->duty_cycle != cstate->duty_cycle) { - ret = sprd_pwm_config(spc, pwm, state->duty_cycle, - state->period); - if (ret) - return ret; - } + ret = sprd_pwm_config(spc, pwm, state->duty_cycle, + state->period); + if (ret) + return ret; sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1); } else if (cstate->enabled) { --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-sti.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-sti.c @@ -79,6 +79,7 @@ unsigned int cpt_num_devs; unsigned int max_pwm_cnt; unsigned int max_prescale; + struct sti_cpt_ddata *ddata; }; struct sti_pwm_chip { @@ -314,7 +315,7 @@ { struct sti_pwm_chip *pc = to_sti_pwmchip(chip); struct sti_pwm_compat_data *cdata = pc->cdata; - struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm); + struct sti_cpt_ddata *ddata = &cdata->ddata[pwm->hwpwm]; struct device *dev = pc->dev; unsigned int effective_ticks; unsigned long long high, low; @@ -417,7 +418,7 @@ while (cpt_int_stat) { devicenum = ffs(cpt_int_stat) - 1; - ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]); + ddata = &pc->cdata->ddata[devicenum]; /* * Capture input: @@ -593,61 +594,55 @@ if (ret) return ret; - if (!cdata->pwm_num_devs) - goto skip_pwm; - - pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm"); - if (IS_ERR(pc->pwm_clk)) { - dev_err(dev, "failed to get PWM clock\n"); - return PTR_ERR(pc->pwm_clk); - } + if (cdata->pwm_num_devs) { + pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm"); + if (IS_ERR(pc->pwm_clk)) { + dev_err(dev, "failed to get PWM clock\n"); + return PTR_ERR(pc->pwm_clk); + } - ret = clk_prepare(pc->pwm_clk); - if (ret) { - dev_err(dev, "failed to prepare clock\n"); - return ret; + ret = clk_prepare(pc->pwm_clk); + if (ret) { + dev_err(dev, "failed to prepare clock\n"); + return ret; + } } -skip_pwm: - if (!cdata->cpt_num_devs) - goto skip_cpt; + if (cdata->cpt_num_devs) { + pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture"); + if (IS_ERR(pc->cpt_clk)) { + dev_err(dev, "failed to get PWM capture clock\n"); + return PTR_ERR(pc->cpt_clk); + } - pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture"); - if (IS_ERR(pc->cpt_clk)) { - dev_err(dev, "failed to get PWM capture clock\n"); - return PTR_ERR(pc->cpt_clk); - } + ret = clk_prepare(pc->cpt_clk); + if (ret) { + dev_err(dev, "failed to prepare clock\n"); + return ret; + } - ret = clk_prepare(pc->cpt_clk); - if (ret) { - dev_err(dev, "failed to prepare clock\n"); - return ret; + cdata->ddata = devm_kzalloc(dev, cdata->cpt_num_devs * sizeof(*cdata->ddata), GFP_KERNEL); + if (!cdata->ddata) + return -ENOMEM; } -skip_cpt: pc->chip.dev = dev; pc->chip.ops = &sti_pwm_ops; pc->chip.base = -1; pc->chip.npwm = pc->cdata->pwm_num_devs; - ret = pwmchip_add(&pc->chip); - if (ret < 0) { - clk_unprepare(pc->pwm_clk); - clk_unprepare(pc->cpt_clk); - return ret; - } - for (i = 0; i < cdata->cpt_num_devs; i++) { - struct sti_cpt_ddata *ddata; - - ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); - if (!ddata) - return -ENOMEM; + struct sti_cpt_ddata *ddata = &cdata->ddata[i]; init_waitqueue_head(&ddata->wait); mutex_init(&ddata->lock); + } - pwm_set_chip_data(&pc->chip.pwms[i], ddata); + ret = pwmchip_add(&pc->chip); + if (ret < 0) { + clk_unprepare(pc->pwm_clk); + clk_unprepare(pc->cpt_clk); + return ret; } platform_set_drvdata(pdev, pc); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-stm32-lp.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-stm32-lp.c @@ -127,7 +127,7 @@ /* ensure CMP & ARR registers are properly written */ ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, - (val & STM32_LPTIM_CMPOK_ARROK), + (val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK, 100, 1000); if (ret) { dev_err(priv->chip.dev, "ARR/CMP registers write issue\n"); @@ -225,8 +225,6 @@ { struct stm32_pwm_lp *priv = platform_get_drvdata(pdev); - pwm_disable(&priv->chip.pwms[0]); - return pwmchip_remove(&priv->chip); } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-stm32.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-stm32.c @@ -337,6 +337,9 @@ prd = div; + if (!prd) + return -EINVAL; + if (prescaler > MAX_TIM_PSC) return -EINVAL; @@ -448,8 +451,9 @@ enabled = pwm->state.enabled; - if (enabled && !state->enabled) { - stm32_pwm_disable(priv, pwm->hwpwm); + if (!state->enabled) { + if (enabled) + stm32_pwm_disable(priv, pwm->hwpwm); return 0; } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-sun4i.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-sun4i.c @@ -137,10 +137,10 @@ val = sun4i_pwm_readl(sun4i_pwm, PWM_CH_PRD(pwm->hwpwm)); - tmp = prescaler * NSEC_PER_SEC * PWM_REG_DTY(val); + tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_DTY(val); state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); - tmp = prescaler * NSEC_PER_SEC * PWM_REG_PRD(val); + tmp = (u64)prescaler * NSEC_PER_SEC * PWM_REG_PRD(val); state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); } --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-tegra.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-tegra.c @@ -232,7 +232,6 @@ static int tegra_pwm_remove(struct platform_device *pdev) { struct tegra_pwm_chip *pc = platform_get_drvdata(pdev); - unsigned int i; int err; if (WARN_ON(!pc)) @@ -242,18 +241,6 @@ if (err < 0) return err; - for (i = 0; i < pc->chip.npwm; i++) { - struct pwm_device *pwm = &pc->chip.pwms[i]; - - if (!pwm_is_enabled(pwm)) - if (clk_prepare_enable(pc->clk) < 0) - continue; - - pwm_writel(pc, i, 0); - - clk_disable_unprepare(pc->clk); - } - reset_control_assert(pc->rst); clk_disable_unprepare(pc->clk); --- linux-oracle-5.4.0.orig/drivers/pwm/pwm-zx.c +++ linux-oracle-5.4.0/drivers/pwm/pwm-zx.c @@ -238,6 +238,7 @@ ret = pwmchip_add(&zpc->chip); if (ret < 0) { dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); + clk_disable_unprepare(zpc->pclk); return ret; } --- linux-oracle-5.4.0.orig/drivers/pwm/sysfs.c +++ linux-oracle-5.4.0/drivers/pwm/sysfs.c @@ -424,6 +424,13 @@ if (!export) continue; + /* If pwmchip was not enabled before suspend, do nothing. */ + if (!export->suspend.enabled) { + /* release lock taken in pwm_class_get_state */ + mutex_unlock(&export->lock); + continue; + } + state.enabled = export->suspend.enabled; ret = pwm_class_apply_state(export, pwm, &state); if (ret < 0) @@ -448,7 +455,17 @@ if (!export) continue; + /* + * If pwmchip was not enabled before suspend, save + * state for resume time and do nothing else. + */ export->suspend = state; + if (!state.enabled) { + /* release lock taken in pwm_class_get_state */ + mutex_unlock(&export->lock); + continue; + } + state.enabled = false; ret = pwm_class_apply_state(export, pwm, &state); if (ret < 0) { --- linux-oracle-5.4.0.orig/drivers/rapidio/Kconfig +++ linux-oracle-5.4.0/drivers/rapidio/Kconfig @@ -37,7 +37,7 @@ config RAPIDIO_DMA_ENGINE bool "DMA Engine support for RapidIO" depends on RAPIDIO - select DMADEVICES + depends on DMADEVICES select DMA_ENGINE help Say Y here if you want to use DMA Engine frameork for RapidIO data --- linux-oracle-5.4.0.orig/drivers/rapidio/devices/rio_mport_cdev.c +++ linux-oracle-5.4.0/drivers/rapidio/devices/rio_mport_cdev.c @@ -873,9 +873,15 @@ rmcd_error("get_user_pages_unlocked err=%ld", pinned); nr_pages = 0; - } else + } else { rmcd_error("pinned %ld out of %ld pages", pinned, nr_pages); + /* + * Set nr_pages up to mean "how many pages to unpin, in + * the error handler: + */ + nr_pages = pinned; + } ret = -EFAULT; goto err_pg; } @@ -1677,6 +1683,7 @@ struct rio_dev *rdev; struct rio_switch *rswitch = NULL; struct rio_mport *mport; + struct device *dev; size_t size; u32 rval; u32 swpinfo = 0; @@ -1691,8 +1698,10 @@ rmcd_debug(RDEV, "name:%s ct:0x%x did:0x%x hc:0x%x", dev_info.name, dev_info.comptag, dev_info.destid, dev_info.hopcount); - if (bus_find_device_by_name(&rio_bus_type, NULL, dev_info.name)) { + dev = bus_find_device_by_name(&rio_bus_type, NULL, dev_info.name); + if (dev) { rmcd_debug(RDEV, "device %s already exists", dev_info.name); + put_device(dev); return -EEXIST; } @@ -1734,7 +1743,8 @@ err = rio_add_net(net); if (err) { rmcd_debug(RDEV, "failed to register net, err=%d", err); - kfree(net); + put_device(&net->dev); + mport->net = NULL; goto cleanup; } } @@ -1798,8 +1808,11 @@ rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); err = rio_add_device(rdev); - if (err) - goto cleanup; + if (err) { + put_device(&rdev->dev); + return err; + } + rio_dev_get(rdev); return 0; @@ -1895,10 +1908,6 @@ priv->md = chdev; - mutex_lock(&chdev->file_mutex); - list_add_tail(&priv->list, &chdev->file_list); - mutex_unlock(&chdev->file_mutex); - INIT_LIST_HEAD(&priv->db_filters); INIT_LIST_HEAD(&priv->pw_filters); spin_lock_init(&priv->fifo_lock); @@ -1907,6 +1916,7 @@ sizeof(struct rio_event) * MPORT_EVENT_DEPTH, GFP_KERNEL); if (ret < 0) { + put_device(&chdev->dev); dev_err(&chdev->dev, DRV_NAME ": kfifo_alloc failed\n"); ret = -ENOMEM; goto err_fifo; @@ -1917,6 +1927,9 @@ spin_lock_init(&priv->req_lock); mutex_init(&priv->dma_lock); #endif + mutex_lock(&chdev->file_mutex); + list_add_tail(&priv->list, &chdev->file_list); + mutex_unlock(&chdev->file_mutex); filp->private_data = priv; goto out; @@ -2379,13 +2392,6 @@ cdev_init(&md->cdev, &mport_fops); md->cdev.owner = THIS_MODULE; - ret = cdev_device_add(&md->cdev, &md->dev); - if (ret) { - rmcd_error("Failed to register mport %d (err=%d)", - mport->id, ret); - goto err_cdev; - } - INIT_LIST_HEAD(&md->doorbells); spin_lock_init(&md->db_lock); INIT_LIST_HEAD(&md->portwrites); @@ -2405,6 +2411,13 @@ #else md->properties.transfer_mode |= RIO_TRANSFER_MODE_TRANSFER; #endif + + ret = cdev_device_add(&md->cdev, &md->dev); + if (ret) { + rmcd_error("Failed to register mport %d (err=%d)", + mport->id, ret); + goto err_cdev; + } ret = rio_query_mport(mport, &attr); if (!ret) { md->properties.flags = attr.flags; --- linux-oracle-5.4.0.orig/drivers/rapidio/rio-scan.c +++ linux-oracle-5.4.0/drivers/rapidio/rio-scan.c @@ -456,8 +456,12 @@ 0, 0xffff); ret = rio_add_device(rdev); - if (ret) - goto cleanup; + if (ret) { + if (rswitch) + kfree(rswitch->route_table); + put_device(&rdev->dev); + return NULL; + } rio_dev_get(rdev); @@ -869,7 +873,10 @@ dev_set_name(&net->dev, "rnet_%d", net->id); net->dev.parent = &mport->dev; net->dev.release = rio_scan_release_dev; - rio_add_net(net); + if (rio_add_net(net)) { + put_device(&net->dev); + net = NULL; + } } return net; --- linux-oracle-5.4.0.orig/drivers/rapidio/rio.c +++ linux-oracle-5.4.0/drivers/rapidio/rio.c @@ -2267,11 +2267,16 @@ atomic_set(&port->state, RIO_DEVICE_RUNNING); res = device_register(&port->dev); - if (res) + if (res) { dev_err(&port->dev, "RIO: mport%d registration failed ERR=%d\n", port->id, res); - else + mutex_lock(&rio_mport_list_lock); + list_del(&port->node); + mutex_unlock(&rio_mport_list_lock); + put_device(&port->dev); + } else { dev_dbg(&port->dev, "RIO: registered mport%d\n", port->id); + } return res; } --- linux-oracle-5.4.0.orig/drivers/rapidio/rio_cm.c +++ linux-oracle-5.4.0/drivers/rapidio/rio_cm.c @@ -2127,6 +2127,14 @@ return -ENODEV; } + cm->rx_wq = create_workqueue(DRV_NAME "/rxq"); + if (!cm->rx_wq) { + rio_release_inb_mbox(mport, cmbox); + rio_release_outb_mbox(mport, cmbox); + kfree(cm); + return -ENOMEM; + } + /* * Allocate and register inbound messaging buffers to be ready * to receive channel and system management requests @@ -2137,15 +2145,6 @@ cm->rx_slots = RIOCM_RX_RING_SIZE; mutex_init(&cm->rx_lock); riocm_rx_fill(cm, RIOCM_RX_RING_SIZE); - cm->rx_wq = create_workqueue(DRV_NAME "/rxq"); - if (!cm->rx_wq) { - riocm_error("failed to allocate IBMBOX_%d on %s", - cmbox, mport->name); - rio_release_outb_mbox(mport, cmbox); - kfree(cm); - return -ENOMEM; - } - INIT_WORK(&cm->rx_work, rio_ibmsg_handler); cm->tx_slot = 0; --- linux-oracle-5.4.0.orig/drivers/ras/cec.c +++ linux-oracle-5.4.0/drivers/ras/cec.c @@ -309,11 +309,20 @@ return ret; } +/** + * cec_add_elem - Add an element to the CEC array. + * @pfn: page frame number to insert + * + * Return values: + * - <0: on error + * - 0: on success + * - >0: when the inserted pfn was offlined + */ int cec_add_elem(u64 pfn) { struct ce_array *ca = &ce_arr; + int count, err, ret = 0; unsigned int to = 0; - int count, ret = 0; /* * We can be called very early on the identify_cpu() path where we are @@ -330,8 +339,8 @@ if (ca->n == MAX_ELEMS) WARN_ON(!del_lru_elem_unlocked(ca)); - ret = find_elem(ca, pfn, &to); - if (ret < 0) { + err = find_elem(ca, pfn, &to); + if (err < 0) { /* * Shift range [to-end] to make room for one more element. */ --- linux-oracle-5.4.0.orig/drivers/regulator/ab8500.c +++ linux-oracle-5.4.0/drivers/regulator/ab8500.c @@ -953,23 +953,6 @@ .update_val_idle = 0x82, .update_val_normal = 0x02, }, - [AB8505_LDO_USB] = { - .desc = { - .name = "LDO-USB", - .ops = &ab8500_regulator_mode_ops, - .type = REGULATOR_VOLTAGE, - .id = AB8505_LDO_USB, - .owner = THIS_MODULE, - .n_voltages = 1, - .volt_table = fixed_3300000_voltage, - }, - .update_bank = 0x03, - .update_reg = 0x82, - .update_mask = 0x03, - .update_val = 0x01, - .update_val_idle = 0x03, - .update_val_normal = 0x01, - }, [AB8505_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", --- linux-oracle-5.4.0.orig/drivers/regulator/axp20x-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/axp20x-regulator.c @@ -42,8 +42,9 @@ #define AXP20X_DCDC2_V_OUT_MASK GENMASK(5, 0) #define AXP20X_DCDC3_V_OUT_MASK GENMASK(7, 0) -#define AXP20X_LDO24_V_OUT_MASK GENMASK(7, 4) +#define AXP20X_LDO2_V_OUT_MASK GENMASK(7, 4) #define AXP20X_LDO3_V_OUT_MASK GENMASK(6, 0) +#define AXP20X_LDO4_V_OUT_MASK GENMASK(3, 0) #define AXP20X_LDO5_V_OUT_MASK GENMASK(7, 4) #define AXP20X_PWR_OUT_EXTEN_MASK BIT_MASK(0) @@ -413,10 +414,13 @@ int i; for (i = 0; i < rate_count; i++) { - if (ramp <= slew_rates[i]) - cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); - else + if (ramp > slew_rates[i]) break; + + if (id == AXP20X_DCDC2) + cfg = AXP20X_DCDC2_LDO3_V_RAMP_DCDC2_RATE(i); + else + cfg = AXP20X_DCDC2_LDO3_V_RAMP_LDO3_RATE(i); } if (cfg == 0xff) { @@ -541,14 +545,14 @@ AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_DCDC3_MASK), AXP_DESC_FIXED(AXP20X, LDO1, "ldo1", "acin", 1300), AXP_DESC(AXP20X, LDO2, "ldo2", "ldo24in", 1800, 3300, 100, - AXP20X_LDO24_V_OUT, AXP20X_LDO24_V_OUT_MASK, + AXP20X_LDO24_V_OUT, AXP20X_LDO2_V_OUT_MASK, AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO2_MASK), AXP_DESC(AXP20X, LDO3, "ldo3", "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, AXP20X_LDO3_V_OUT_MASK, AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO3_MASK), AXP_DESC_RANGES(AXP20X, LDO4, "ldo4", "ldo24in", axp20x_ldo4_ranges, AXP20X_LDO4_V_OUT_NUM_VOLTAGES, - AXP20X_LDO24_V_OUT, AXP20X_LDO24_V_OUT_MASK, + AXP20X_LDO24_V_OUT, AXP20X_LDO4_V_OUT_MASK, AXP20X_PWR_OUT_CTRL, AXP20X_PWR_OUT_LDO4_MASK), AXP_DESC_IO(AXP20X, LDO5, "ldo5", "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, AXP20X_LDO5_V_OUT_MASK, @@ -592,7 +596,7 @@ AXP22X_DLDO1_V_OUT, AXP22X_DLDO1_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO1_MASK), AXP_DESC(AXP22X, DLDO2, "dldo2", "dldoin", 700, 3300, 100, - AXP22X_DLDO2_V_OUT, AXP22X_PWR_OUT_DLDO2_MASK, + AXP22X_DLDO2_V_OUT, AXP22X_DLDO2_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_DLDO2_MASK), AXP_DESC(AXP22X, DLDO3, "dldo3", "dldoin", 700, 3300, 100, AXP22X_DLDO3_V_OUT, AXP22X_DLDO3_V_OUT_MASK, @@ -605,7 +609,7 @@ AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), AXP_DESC(AXP22X, ELDO2, "eldo2", "eldoin", 700, 3300, 100, AXP22X_ELDO2_V_OUT, AXP22X_ELDO2_V_OUT_MASK, - AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO1_MASK), + AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO2_MASK), AXP_DESC(AXP22X, ELDO3, "eldo3", "eldoin", 700, 3300, 100, AXP22X_ELDO3_V_OUT, AXP22X_ELDO3_V_OUT_MASK, AXP22X_PWR_OUT_CTRL2, AXP22X_PWR_OUT_ELDO3_MASK), @@ -1068,7 +1072,7 @@ static int axp20x_regulator_parse_dt(struct platform_device *pdev) { struct device_node *np, *regulators; - int ret; + int ret = 0; u32 dcdcfreq = 0; np = of_node_get(pdev->dev.parent->of_node); @@ -1083,13 +1087,12 @@ ret = axp20x_set_dcdc_freq(pdev, dcdcfreq); if (ret < 0) { dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret); - return ret; } - of_node_put(regulators); } - return 0; + of_node_put(np); + return ret; } static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode) --- linux-oracle-5.4.0.orig/drivers/regulator/bd70528-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/bd70528-regulator.c @@ -101,7 +101,6 @@ .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, - .set_ramp_delay = bd70528_set_ramp_delay, }; static const struct regulator_ops bd70528_led_ops = { @@ -286,3 +285,4 @@ MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("BD70528 voltage regulator driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd70528-pmic"); --- linux-oracle-5.4.0.orig/drivers/regulator/bd718x7-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/bd718x7-regulator.c @@ -15,6 +15,36 @@ #include #include +/* Typical regulator startup times as per data sheet in uS */ +#define BD71847_BUCK1_STARTUP_TIME 144 +#define BD71847_BUCK2_STARTUP_TIME 162 +#define BD71847_BUCK3_STARTUP_TIME 162 +#define BD71847_BUCK4_STARTUP_TIME 240 +#define BD71847_BUCK5_STARTUP_TIME 270 +#define BD71847_BUCK6_STARTUP_TIME 200 +#define BD71847_LDO1_STARTUP_TIME 440 +#define BD71847_LDO2_STARTUP_TIME 370 +#define BD71847_LDO3_STARTUP_TIME 310 +#define BD71847_LDO4_STARTUP_TIME 400 +#define BD71847_LDO5_STARTUP_TIME 530 +#define BD71847_LDO6_STARTUP_TIME 400 + +#define BD71837_BUCK1_STARTUP_TIME 160 +#define BD71837_BUCK2_STARTUP_TIME 180 +#define BD71837_BUCK3_STARTUP_TIME 180 +#define BD71837_BUCK4_STARTUP_TIME 180 +#define BD71837_BUCK5_STARTUP_TIME 160 +#define BD71837_BUCK6_STARTUP_TIME 240 +#define BD71837_BUCK7_STARTUP_TIME 220 +#define BD71837_BUCK8_STARTUP_TIME 200 +#define BD71837_LDO1_STARTUP_TIME 440 +#define BD71837_LDO2_STARTUP_TIME 370 +#define BD71837_LDO3_STARTUP_TIME 310 +#define BD71837_LDO4_STARTUP_TIME 400 +#define BD71837_LDO5_STARTUP_TIME 310 +#define BD71837_LDO6_STARTUP_TIME 400 +#define BD71837_LDO7_STARTUP_TIME 530 + /* * BUCK1/2/3/4 * BUCK1RAMPRATE[1:0] BUCK1 DVS ramp rate setting @@ -495,6 +525,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD718XX_REG_BUCK1_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK1_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck1_set_hw_dvs_levels, }, @@ -519,6 +550,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD718XX_REG_BUCK2_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK2_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck2_set_hw_dvs_levels, }, @@ -547,6 +579,7 @@ .linear_range_selectors = bd71847_buck3_volt_range_sel, .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK3_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -574,6 +607,7 @@ .vsel_range_mask = BD71847_BUCK4_RANGE_MASK, .linear_range_selectors = bd71847_buck4_volt_range_sel, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK4_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -596,6 +630,7 @@ .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK5_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -620,6 +655,7 @@ .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71847_BUCK6_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -646,6 +682,7 @@ .linear_range_selectors = bd718xx_ldo1_volt_range_sel, .enable_reg = BD718XX_REG_LDO1_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO1_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -668,6 +705,7 @@ .n_voltages = ARRAY_SIZE(ldo_2_volts), .enable_reg = BD718XX_REG_LDO2_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO2_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -691,6 +729,7 @@ .vsel_mask = BD718XX_LDO3_MASK, .enable_reg = BD718XX_REG_LDO3_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO3_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -714,6 +753,7 @@ .vsel_mask = BD718XX_LDO4_MASK, .enable_reg = BD718XX_REG_LDO4_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO4_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -740,6 +780,7 @@ .linear_range_selectors = bd71847_ldo5_volt_range_sel, .enable_reg = BD718XX_REG_LDO5_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO5_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -765,6 +806,7 @@ .vsel_mask = BD718XX_LDO6_MASK, .enable_reg = BD718XX_REG_LDO6_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71847_LDO6_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -791,6 +833,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD718XX_REG_BUCK1_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK1_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck1_set_hw_dvs_levels, }, @@ -815,6 +858,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD718XX_REG_BUCK2_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK2_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck2_set_hw_dvs_levels, }, @@ -839,6 +883,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD71837_REG_BUCK3_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK3_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck3_set_hw_dvs_levels, }, @@ -863,6 +908,7 @@ .vsel_mask = DVS_BUCK_RUN_MASK, .enable_reg = BD71837_REG_BUCK4_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK4_STARTUP_TIME, .owner = THIS_MODULE, .of_parse_cb = buck4_set_hw_dvs_levels, }, @@ -891,6 +937,7 @@ .linear_range_selectors = bd71837_buck5_volt_range_sel, .enable_reg = BD718XX_REG_1ST_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK5_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -915,6 +962,7 @@ .vsel_mask = BD71837_BUCK6_MASK, .enable_reg = BD718XX_REG_2ND_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK6_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -937,6 +985,7 @@ .vsel_mask = BD718XX_3RD_NODVS_BUCK_MASK, .enable_reg = BD718XX_REG_3RD_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK7_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -961,6 +1010,7 @@ .vsel_mask = BD718XX_4TH_NODVS_BUCK_MASK, .enable_reg = BD718XX_REG_4TH_NODVS_BUCK_CTRL, .enable_mask = BD718XX_BUCK_EN, + .enable_time = BD71837_BUCK8_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -987,6 +1037,7 @@ .linear_range_selectors = bd718xx_ldo1_volt_range_sel, .enable_reg = BD718XX_REG_LDO1_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO1_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1009,6 +1060,7 @@ .n_voltages = ARRAY_SIZE(ldo_2_volts), .enable_reg = BD718XX_REG_LDO2_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO2_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1032,6 +1084,7 @@ .vsel_mask = BD718XX_LDO3_MASK, .enable_reg = BD718XX_REG_LDO3_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO3_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1055,6 +1108,7 @@ .vsel_mask = BD718XX_LDO4_MASK, .enable_reg = BD718XX_REG_LDO4_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO4_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1080,6 +1134,7 @@ .vsel_mask = BD71837_LDO5_MASK, .enable_reg = BD718XX_REG_LDO5_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO5_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1107,6 +1162,7 @@ .vsel_mask = BD718XX_LDO6_MASK, .enable_reg = BD718XX_REG_LDO6_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO6_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { @@ -1132,6 +1188,7 @@ .vsel_mask = BD71837_LDO7_MASK, .enable_reg = BD71837_REG_LDO7_VOLT, .enable_mask = BD718XX_LDO_EN, + .enable_time = BD71837_LDO7_STARTUP_TIME, .owner = THIS_MODULE, }, .init = { --- linux-oracle-5.4.0.orig/drivers/regulator/bd9571mwv-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/bd9571mwv-regulator.c @@ -124,7 +124,7 @@ static const struct regulator_desc regulators[] = { BD9571MWV_REG("VD09", "vd09", VD09, avs_ops, 0, 0x7f, - 0x80, 600000, 10000, 0x3c), + 0x6f, 600000, 10000, 0x3c), BD9571MWV_REG("VD18", "vd18", VD18, vid_ops, BD9571MWV_VD18_VID, 0xf, 16, 1625000, 25000, 0), BD9571MWV_REG("VD25", "vd25", VD25, vid_ops, BD9571MWV_VD25_VID, 0xf, @@ -133,7 +133,7 @@ 11, 2800000, 100000, 0), BD9571MWV_REG("DVFS", "dvfs", DVFS, reg_ops, BD9571MWV_DVFS_MONIVDAC, 0x7f, - 0x80, 600000, 10000, 0x3c), + 0x6f, 600000, 10000, 0x3c), }; #ifdef CONFIG_PM_SLEEP --- linux-oracle-5.4.0.orig/drivers/regulator/core.c +++ linux-oracle-5.4.0/drivers/regulator/core.c @@ -217,6 +217,78 @@ } EXPORT_SYMBOL_GPL(regulator_unlock); +/** + * regulator_lock_two - lock two regulators + * @rdev1: first regulator + * @rdev2: second regulator + * @ww_ctx: w/w mutex acquire context + * + * Locks both rdevs using the regulator_ww_class. + */ +static void regulator_lock_two(struct regulator_dev *rdev1, + struct regulator_dev *rdev2, + struct ww_acquire_ctx *ww_ctx) +{ + struct regulator_dev *tmp; + int ret; + + ww_acquire_init(ww_ctx, ®ulator_ww_class); + + /* Try to just grab both of them */ + ret = regulator_lock_nested(rdev1, ww_ctx); + WARN_ON(ret); + ret = regulator_lock_nested(rdev2, ww_ctx); + if (ret != -EDEADLOCK) { + WARN_ON(ret); + goto exit; + } + + while (true) { + /* + * Start of loop: rdev1 was locked and rdev2 was contended. + * Need to unlock rdev1, slowly lock rdev2, then try rdev1 + * again. + */ + regulator_unlock(rdev1); + + ww_mutex_lock_slow(&rdev2->mutex, ww_ctx); + rdev2->ref_cnt++; + rdev2->mutex_owner = current; + ret = regulator_lock_nested(rdev1, ww_ctx); + + if (ret == -EDEADLOCK) { + /* More contention; swap which needs to be slow */ + tmp = rdev1; + rdev1 = rdev2; + rdev2 = tmp; + } else { + WARN_ON(ret); + break; + } + } + +exit: + ww_acquire_done(ww_ctx); +} + +/** + * regulator_unlock_two - unlock two regulators + * @rdev1: first regulator + * @rdev2: second regulator + * @ww_ctx: w/w mutex acquire context + * + * The inverse of regulator_lock_two(). + */ + +static void regulator_unlock_two(struct regulator_dev *rdev1, + struct regulator_dev *rdev2, + struct ww_acquire_ctx *ww_ctx) +{ + regulator_unlock(rdev2); + regulator_unlock(rdev1); + ww_acquire_fini(ww_ctx); +} + static bool regulator_supply_is_couple(struct regulator_dev *rdev) { struct regulator_dev *c_rdev; @@ -235,8 +307,8 @@ static void regulator_unlock_recursive(struct regulator_dev *rdev, unsigned int n_coupled) { - struct regulator_dev *c_rdev; - int i; + struct regulator_dev *c_rdev, *supply_rdev; + int i, supply_n_coupled; for (i = n_coupled; i > 0; i--) { c_rdev = rdev->coupling_desc.coupled_rdevs[i - 1]; @@ -244,10 +316,13 @@ if (!c_rdev) continue; - if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) - regulator_unlock_recursive( - c_rdev->supply->rdev, - c_rdev->coupling_desc.n_coupled); + if (c_rdev->supply && !regulator_supply_is_couple(c_rdev)) { + supply_rdev = c_rdev->supply->rdev; + supply_n_coupled = supply_rdev->coupling_desc.n_coupled; + + regulator_unlock_recursive(supply_rdev, + supply_n_coupled); + } regulator_unlock(c_rdev); } @@ -341,6 +416,7 @@ ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); old_contended_rdev = new_contended_rdev; old_contended_rdev->ref_cnt++; + old_contended_rdev->mutex_owner = current; } err = regulator_lock_recursive(rdev, @@ -953,7 +1029,7 @@ /* get input voltage */ input_uV = 0; if (rdev->supply) - input_uV = regulator_get_voltage(rdev->supply); + input_uV = regulator_get_voltage_rdev(rdev->supply->rdev); if (input_uV <= 0) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) { @@ -1272,7 +1348,6 @@ /** * set_machine_constraints - sets regulator constraints * @rdev: regulator source - * @constraints: constraints to apply * * Allows platform initialisation code to define and constrain * regulator circuits e.g. valid voltage/current ranges, etc. NOTE: @@ -1280,21 +1355,11 @@ * regulator operations to proceed i.e. set_voltage, set_current_limit, * set_mode. */ -static int set_machine_constraints(struct regulator_dev *rdev, - const struct regulation_constraints *constraints) +static int set_machine_constraints(struct regulator_dev *rdev) { int ret = 0; const struct regulator_ops *ops = rdev->desc->ops; - if (constraints) - rdev->constraints = kmemdup(constraints, sizeof(*constraints), - GFP_KERNEL); - else - rdev->constraints = kzalloc(sizeof(*constraints), - GFP_KERNEL); - if (!rdev->constraints) - return -ENOMEM; - ret = machine_constraints_voltage(rdev, rdev->constraints); if (ret != 0) return ret; @@ -1389,7 +1454,19 @@ * and we have control then make sure it is enabled. */ if (rdev->constraints->always_on || rdev->constraints->boot_on) { - if (rdev->supply) { + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ + if (rdev->supply_name && !rdev->supply) + return -EPROBE_DEFER; + + /* If supplying regulator has already been enabled, + * it's not intended to have use_count increment + * when rdev is only boot-on. + */ + if (rdev->supply && + (rdev->constraints->always_on || + !regulator_is_enabled(rdev->supply))) { ret = regulator_enable(rdev->supply); if (ret < 0) { _regulator_put(rdev->supply); @@ -1403,7 +1480,9 @@ rdev_err(rdev, "failed to enable\n"); return ret; } - rdev->use_count++; + + if (rdev->constraints->always_on) + rdev->use_count++; } print_constraints(rdev); @@ -1412,8 +1491,8 @@ /** * set_supply - set regulator supply regulator - * @rdev: regulator name - * @supply_rdev: supply regulator name + * @rdev: regulator (locked) + * @supply_rdev: supply regulator (locked)) * * Called by platform initialisation code to set the supply regulator for this * regulator. This ensures that a regulators supply will also be enabled by the @@ -1431,6 +1510,7 @@ rdev->supply = create_regulator(supply_rdev, &rdev->dev, "SUPPLY"); if (rdev->supply == NULL) { + module_put(supply_rdev->owner); err = -ENOMEM; return err; } @@ -1454,7 +1534,7 @@ const char *consumer_dev_name, const char *supply) { - struct regulator_map *node; + struct regulator_map *node, *new_node; int has_dev; if (supply == NULL) @@ -1465,6 +1545,22 @@ else has_dev = 0; + new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); + if (new_node == NULL) + return -ENOMEM; + + new_node->regulator = rdev; + new_node->supply = supply; + + if (has_dev) { + new_node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL); + if (new_node->dev_name == NULL) { + kfree(new_node); + return -ENOMEM; + } + } + + mutex_lock(®ulator_list_mutex); list_for_each_entry(node, ®ulator_map_list, list) { if (node->dev_name && consumer_dev_name) { if (strcmp(node->dev_name, consumer_dev_name) != 0) @@ -1482,26 +1578,19 @@ node->regulator->desc->name, supply, dev_name(&rdev->dev), rdev_get_name(rdev)); - return -EBUSY; + goto fail; } - node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); - if (node == NULL) - return -ENOMEM; - - node->regulator = rdev; - node->supply = supply; - - if (has_dev) { - node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL); - if (node->dev_name == NULL) { - kfree(node); - return -ENOMEM; - } - } + list_add(&new_node->list, ®ulator_map_list); + mutex_unlock(®ulator_list_mutex); - list_add(&node->list, ®ulator_map_list); return 0; + +fail: + mutex_unlock(®ulator_list_mutex); + kfree(new_node->dev_name); + kfree(new_node); + return -EBUSY; } static void unset_regulator_supplies(struct regulator_dev *rdev) @@ -1573,57 +1662,69 @@ const char *supply_name) { struct regulator *regulator; - char buf[REG_STR_SIZE]; - int err, size; + int err = 0; + + lockdep_assert_held_once(&rdev->mutex.base); + + if (dev) { + char buf[REG_STR_SIZE]; + int size; + + size = snprintf(buf, REG_STR_SIZE, "%s-%s", + dev->kobj.name, supply_name); + if (size >= REG_STR_SIZE) + return NULL; + + supply_name = kstrdup(buf, GFP_KERNEL); + if (supply_name == NULL) + return NULL; + } else { + supply_name = kstrdup_const(supply_name, GFP_KERNEL); + if (supply_name == NULL) + return NULL; + } regulator = kzalloc(sizeof(*regulator), GFP_KERNEL); - if (regulator == NULL) + if (regulator == NULL) { + kfree_const(supply_name); return NULL; + } - regulator_lock(rdev); regulator->rdev = rdev; + regulator->supply_name = supply_name; + list_add(®ulator->list, &rdev->consumer_list); if (dev) { regulator->dev = dev; /* Add a link to the device sysfs entry */ - size = snprintf(buf, REG_STR_SIZE, "%s-%s", - dev->kobj.name, supply_name); - if (size >= REG_STR_SIZE) - goto overflow_err; - - regulator->supply_name = kstrdup(buf, GFP_KERNEL); - if (regulator->supply_name == NULL) - goto overflow_err; - err = sysfs_create_link_nowarn(&rdev->dev.kobj, &dev->kobj, - buf); + supply_name); if (err) { rdev_dbg(rdev, "could not add device link %s err %d\n", dev->kobj.name, err); /* non-fatal */ } - } else { - regulator->supply_name = kstrdup_const(supply_name, GFP_KERNEL); - if (regulator->supply_name == NULL) - goto overflow_err; } - regulator->debugfs = debugfs_create_dir(regulator->supply_name, - rdev->debugfs); - if (!regulator->debugfs) { - rdev_dbg(rdev, "Failed to create debugfs directory\n"); - } else { + if (err != -EEXIST) { + regulator->debugfs = debugfs_create_dir(supply_name, rdev->debugfs); + if (IS_ERR(regulator->debugfs)) { + rdev_dbg(rdev, "Failed to create debugfs directory\n"); + regulator->debugfs = NULL; + } + } + + if (regulator->debugfs) { debugfs_create_u32("uA_load", 0444, regulator->debugfs, ®ulator->uA_load); debugfs_create_u32("min_uV", 0444, regulator->debugfs, ®ulator->voltage[PM_SUSPEND_ON].min_uV); debugfs_create_u32("max_uV", 0444, regulator->debugfs, ®ulator->voltage[PM_SUSPEND_ON].max_uV); - debugfs_create_file("constraint_flags", 0444, - regulator->debugfs, regulator, - &constraint_flags_fops); + debugfs_create_file("constraint_flags", 0444, regulator->debugfs, + regulator, &constraint_flags_fops); } /* @@ -1635,13 +1736,7 @@ _regulator_is_enabled(rdev)) regulator->always_on = true; - regulator_unlock(rdev); return regulator; -overflow_err: - list_del(®ulator->list); - kfree(regulator); - regulator_unlock(rdev); - return NULL; } static int _regulator_get_enable_time(struct regulator_dev *rdev) @@ -1722,6 +1817,7 @@ node = of_get_regulator(dev, supply); if (node) { r = of_find_regulator_by_node(node); + of_node_put(node); if (r) return r; @@ -1766,13 +1862,14 @@ { struct regulator_dev *r; struct device *dev = rdev->dev.parent; - int ret; + struct ww_acquire_ctx ww_ctx; + int ret = 0; /* No supply to resolve? */ if (!rdev->supply_name) return 0; - /* Supply already resolved? */ + /* Supply already resolved? (fast-path without locking contention) */ if (rdev->supply) return 0; @@ -1782,7 +1879,7 @@ /* Did the lookup explicitly defer for us? */ if (ret == -EPROBE_DEFER) - return ret; + goto out; if (have_full_constraints()) { r = dummy_regulator_rdev; @@ -1790,8 +1887,20 @@ } else { dev_err(dev, "Failed to resolve %s-supply for %s\n", rdev->supply_name, rdev->desc->name); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto out; + } + } + + if (r == rdev) { + dev_err(dev, "Supply for %s (%s) resolved to itself\n", + rdev->desc->name, rdev->supply_name); + if (!have_full_constraints()) { + ret = -EINVAL; + goto out; } + r = dummy_regulator_rdev; + get_device(&r->dev); } /* @@ -1803,7 +1912,8 @@ if (r->dev.parent && r->dev.parent != rdev->dev.parent) { if (!device_is_bound(r->dev.parent)) { put_device(&r->dev); - return -EPROBE_DEFER; + ret = -EPROBE_DEFER; + goto out; } } @@ -1811,15 +1921,32 @@ ret = regulator_resolve_supply(r); if (ret < 0) { put_device(&r->dev); - return ret; + goto out; + } + + /* + * Recheck rdev->supply with rdev->mutex lock held to avoid a race + * between rdev->supply null check and setting rdev->supply in + * set_supply() from concurrent tasks. + */ + regulator_lock_two(rdev, r, &ww_ctx); + + /* Supply just resolved by a concurrent task? */ + if (rdev->supply) { + regulator_unlock_two(rdev, r, &ww_ctx); + put_device(&r->dev); + goto out; } ret = set_supply(rdev, r); if (ret < 0) { + regulator_unlock_two(rdev, r, &ww_ctx); put_device(&r->dev); - return ret; + goto out; } + regulator_unlock_two(rdev, r, &ww_ctx); + /* * In set_machine_constraints() we may have turned this regulator on * but we couldn't propagate to the supply if it hadn't been resolved @@ -1830,11 +1957,12 @@ if (ret < 0) { _regulator_put(rdev->supply); rdev->supply = NULL; - return ret; + goto out; } } - return 0; +out: + return ret; } /* Internal regulator request function */ @@ -1932,11 +2060,13 @@ return regulator; } + regulator_lock(rdev); regulator = create_regulator(rdev, dev, id); + regulator_unlock(rdev); if (regulator == NULL) { regulator = ERR_PTR(-ENOMEM); - put_device(&rdev->dev); module_put(rdev->owner); + put_device(&rdev->dev); return regulator; } @@ -1945,10 +2075,13 @@ rdev->exclusive = 1; ret = _regulator_is_enabled(rdev); - if (ret > 0) + if (ret > 0) { rdev->use_count = 1; - else + regulator->enable_count = 1; + } else { rdev->use_count = 0; + regulator->enable_count = 0; + } } device_link_add(dev, &rdev->dev, DL_FLAG_STATELESS); @@ -2057,13 +2190,13 @@ rdev->open_count--; rdev->exclusive = 0; - put_device(&rdev->dev); regulator_unlock(rdev); kfree_const(regulator->supply_name); kfree(regulator); module_put(rdev->owner); + put_device(&rdev->dev); } /** @@ -2215,10 +2348,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, const struct regulator_config *config) { - struct regulator_enable_gpio *pin; + struct regulator_enable_gpio *pin, *new_pin; struct gpio_desc *gpiod; gpiod = config->ena_gpiod; + new_pin = kzalloc(sizeof(*new_pin), GFP_KERNEL); + + mutex_lock(®ulator_list_mutex); list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { if (pin->gpiod == gpiod) { @@ -2227,9 +2363,13 @@ } } - pin = kzalloc(sizeof(struct regulator_enable_gpio), GFP_KERNEL); - if (pin == NULL) + if (new_pin == NULL) { + mutex_unlock(®ulator_list_mutex); return -ENOMEM; + } + + pin = new_pin; + new_pin = NULL; pin->gpiod = gpiod; list_add(&pin->list, ®ulator_ena_gpio_list); @@ -2237,6 +2377,10 @@ update_ena_gpio_to_rdev: pin->request_count++; rdev->ena_pin = pin; + + mutex_unlock(®ulator_list_mutex); + kfree(new_pin); + return 0; } @@ -2429,13 +2573,18 @@ */ static int _regulator_handle_consumer_enable(struct regulator *regulator) { + int ret; struct regulator_dev *rdev = regulator->rdev; lockdep_assert_held_once(&rdev->mutex.base); regulator->enable_count++; - if (regulator->uA_load && regulator->enable_count == 1) - return drms_uA_update(rdev); + if (regulator->uA_load && regulator->enable_count == 1) { + ret = drms_uA_update(rdev); + if (ret) + regulator->enable_count--; + return ret; + } return 0; } @@ -2514,7 +2663,8 @@ /* Fallthrough on positive return values - already enabled */ } - rdev->use_count++; + if (regulator->enable_count == 1) + rdev->use_count++; return 0; @@ -2592,37 +2742,40 @@ lockdep_assert_held_once(&rdev->mutex.base); - if (WARN(rdev->use_count <= 0, + if (WARN(regulator->enable_count == 0, "unbalanced disables for %s\n", rdev_get_name(rdev))) return -EIO; - /* are we the last user and permitted to disable ? */ - if (rdev->use_count == 1 && - (rdev->constraints && !rdev->constraints->always_on)) { - - /* we are last user */ - if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { - ret = _notifier_call_chain(rdev, - REGULATOR_EVENT_PRE_DISABLE, - NULL); - if (ret & NOTIFY_STOP_MASK) - return -EINVAL; - - ret = _regulator_do_disable(rdev); - if (ret < 0) { - rdev_err(rdev, "failed to disable\n"); - _notifier_call_chain(rdev, - REGULATOR_EVENT_ABORT_DISABLE, + if (regulator->enable_count == 1) { + /* disabling last enable_count from this regulator */ + /* are we the last user and permitted to disable ? */ + if (rdev->use_count == 1 && + (rdev->constraints && !rdev->constraints->always_on)) { + + /* we are last user */ + if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { + ret = _notifier_call_chain(rdev, + REGULATOR_EVENT_PRE_DISABLE, + NULL); + if (ret & NOTIFY_STOP_MASK) + return -EINVAL; + + ret = _regulator_do_disable(rdev); + if (ret < 0) { + rdev_err(rdev, "failed to disable\n"); + _notifier_call_chain(rdev, + REGULATOR_EVENT_ABORT_DISABLE, + NULL); + return ret; + } + _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, NULL); - return ret; } - _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, - NULL); - } - rdev->use_count = 0; - } else if (rdev->use_count > 1) { - rdev->use_count--; + rdev->use_count = 0; + } else if (rdev->use_count > 1) { + rdev->use_count--; + } } if (ret == 0) @@ -2921,6 +3074,7 @@ return map ? map : ERR_PTR(-EOPNOTSUPP); } +EXPORT_SYMBOL_GPL(regulator_get_regmap); /** * regulator_get_hardware_vsel_register - get the HW voltage selector register @@ -3460,6 +3614,7 @@ out: return ret; } +EXPORT_SYMBOL_GPL(regulator_set_voltage_rdev); static int regulator_limit_voltage_step(struct regulator_dev *rdev, int *current_uV, int *min_uV) @@ -4016,6 +4171,8 @@ ret = rdev->desc->fixed_uV; } else if (rdev->supply) { ret = regulator_get_voltage_rdev(rdev->supply->rdev); + } else if (rdev->supply_name) { + return -EPROBE_DEFER; } else { return -EINVAL; } @@ -4024,6 +4181,7 @@ return ret; return ret - rdev->constraints->uV_offset; } +EXPORT_SYMBOL_GPL(regulator_get_voltage_rdev); /** * regulator_get_voltage - get regulator output voltage @@ -4736,6 +4894,7 @@ { struct regulator_dev *rdev = dev_get_drvdata(dev); + debugfs_remove_recursive(rdev->debugfs); kfree(rdev->constraints); of_node_put(rdev->dev.of_node); kfree(rdev); @@ -4755,10 +4914,8 @@ } rdev->debugfs = debugfs_create_dir(rname, debugfs_root); - if (!rdev->debugfs) { - rdev_warn(rdev, "Failed to create debugfs directory\n"); - return; - } + if (IS_ERR(rdev->debugfs)) + rdev_dbg(rdev, "Failed to create debugfs directory\n"); debugfs_create_u32("use_count", 0444, rdev->debugfs, &rdev->use_count); @@ -4853,13 +5010,9 @@ return; } - regulator_lock(c_rdev); - c_desc->coupled_rdevs[i] = c_rdev; c_desc->n_resolved++; - regulator_unlock(c_rdev); - regulator_resolve_coupling(c_rdev); } } @@ -4944,7 +5097,10 @@ if (!of_check_coupling_data(rdev)) return -EPERM; + mutex_lock(®ulator_list_mutex); rdev->coupling_desc.coupler = regulator_find_coupler(rdev); + mutex_unlock(®ulator_list_mutex); + if (IS_ERR(rdev->coupling_desc.coupler)) { err = PTR_ERR(rdev->coupling_desc.coupler); rdev_err(rdev, "failed to get coupler: %d\n", err); @@ -4983,7 +5139,6 @@ regulator_register(const struct regulator_desc *regulator_desc, const struct regulator_config *cfg) { - const struct regulation_constraints *constraints = NULL; const struct regulator_init_data *init_data; struct regulator_config *config = NULL; static atomic_t regulator_no = ATOMIC_INIT(-1); @@ -5039,6 +5194,7 @@ ret = -ENOMEM; goto rinse; } + device_initialize(&rdev->dev); /* * Duplicate the config so the driver could override it after @@ -5046,9 +5202,8 @@ */ config = kmemdup(cfg, sizeof(*cfg), GFP_KERNEL); if (config == NULL) { - kfree(rdev); ret = -ENOMEM; - goto rinse; + goto clean; } init_data = regulator_of_get_init_data(dev, regulator_desc, config, @@ -5060,10 +5215,8 @@ * from a gpio extender or something else. */ if (PTR_ERR(init_data) == -EPROBE_DEFER) { - kfree(config); - kfree(rdev); ret = -EPROBE_DEFER; - goto rinse; + goto clean; } /* @@ -5104,9 +5257,7 @@ } if (config->ena_gpiod) { - mutex_lock(®ulator_list_mutex); ret = regulator_ena_gpio_request(rdev, config); - mutex_unlock(®ulator_list_mutex); if (ret != 0) { rdev_err(rdev, "Failed to request enable GPIO: %d\n", ret); @@ -5122,49 +5273,59 @@ rdev->dev.parent = dev; dev_set_name(&rdev->dev, "regulator.%lu", (unsigned long) atomic_inc_return(®ulator_no)); + dev_set_drvdata(&rdev->dev, rdev); /* set regulator constraints */ if (init_data) - constraints = &init_data->constraints; + rdev->constraints = kmemdup(&init_data->constraints, + sizeof(*rdev->constraints), + GFP_KERNEL); + else + rdev->constraints = kzalloc(sizeof(*rdev->constraints), + GFP_KERNEL); + if (!rdev->constraints) { + ret = -ENOMEM; + goto wash; + } if (init_data && init_data->supply_regulator) rdev->supply_name = init_data->supply_regulator; else if (regulator_desc->supply_name) rdev->supply_name = regulator_desc->supply_name; - /* - * Attempt to resolve the regulator supply, if specified, - * but don't return an error if we fail because we will try - * to resolve it again later as more regulators are added. - */ - if (regulator_resolve_supply(rdev)) - rdev_dbg(rdev, "unable to resolve supply\n"); - - ret = set_machine_constraints(rdev, constraints); + ret = set_machine_constraints(rdev); + if (ret == -EPROBE_DEFER) { + /* Regulator might be in bypass mode and so needs its supply + * to set the constraints */ + /* FIXME: this currently triggers a chicken-and-egg problem + * when creating -SUPPLY symlink in sysfs to a regulator + * that is just being created */ + ret = regulator_resolve_supply(rdev); + if (!ret) + ret = set_machine_constraints(rdev); + else + rdev_dbg(rdev, "unable to resolve supply early: %pe\n", + ERR_PTR(ret)); + } if (ret < 0) goto wash; - mutex_lock(®ulator_list_mutex); ret = regulator_init_coupling(rdev); - mutex_unlock(®ulator_list_mutex); if (ret < 0) goto wash; /* add consumers devices */ if (init_data) { - mutex_lock(®ulator_list_mutex); for (i = 0; i < init_data->num_consumer_supplies; i++) { ret = set_consumer_device_supply(rdev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); if (ret < 0) { - mutex_unlock(®ulator_list_mutex); dev_err(dev, "Failed to set supply %s\n", init_data->consumer_supplies[i].supply); goto unset_supplies; } } - mutex_unlock(®ulator_list_mutex); } if (!rdev->desc->ops->get_voltage && @@ -5172,12 +5333,9 @@ !rdev->desc->fixed_uV) rdev->is_switch = true; - dev_set_drvdata(&rdev->dev, rdev); - ret = device_register(&rdev->dev); - if (ret != 0) { - put_device(&rdev->dev); + ret = device_add(&rdev->dev); + if (ret != 0) goto unset_supplies; - } rdev_init_debugfs(rdev); @@ -5198,15 +5356,16 @@ regulator_remove_coupling(rdev); mutex_unlock(®ulator_list_mutex); wash: - kfree(rdev->constraints); + regulator_put(rdev->supply); + kfree(rdev->coupling_desc.coupled_rdevs); mutex_lock(®ulator_list_mutex); regulator_ena_gpio_free(rdev); mutex_unlock(®ulator_list_mutex); clean: if (dangling_of_gpiod) gpiod_put(config->ena_gpiod); - kfree(rdev); kfree(config); + put_device(&rdev->dev); rinse: if (dangling_cfg_gpiod) gpiod_put(cfg->ena_gpiod); @@ -5235,7 +5394,6 @@ mutex_lock(®ulator_list_mutex); - debugfs_remove_recursive(rdev->debugfs); WARN_ON(rdev->open_count); regulator_remove_coupling(rdev); unset_regulator_supplies(rdev); @@ -5579,6 +5737,7 @@ ww_mutex_lock_slow(&new_contended_rdev->mutex, ww_ctx); old_contended_rdev = new_contended_rdev; old_contended_rdev->ref_cnt++; + old_contended_rdev->mutex_owner = current; } err = regulator_summary_lock_all(ww_ctx, @@ -5639,8 +5798,8 @@ ret = class_register(®ulator_class); debugfs_root = debugfs_create_dir("regulator", NULL); - if (!debugfs_root) - pr_warn("regulator: Failed to create debugfs directory\n"); + if (IS_ERR(debugfs_root)) + pr_debug("regulator: Failed to create debugfs directory\n"); #ifdef CONFIG_DEBUG_FS debugfs_create_file("supply_map", 0444, debugfs_root, NULL, --- linux-oracle-5.4.0.orig/drivers/regulator/da9052-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/da9052-regulator.c @@ -250,7 +250,8 @@ case DA9052_ID_BUCK3: case DA9052_ID_LDO2: case DA9052_ID_LDO3: - ret = (new_sel - old_sel) * info->step_uV / 6250; + ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV, + 6250); break; } --- linux-oracle-5.4.0.orig/drivers/regulator/da9211-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/da9211-regulator.c @@ -471,6 +471,12 @@ chip->chip_irq = i2c->irq; + ret = da9211_regulator_init(chip); + if (ret < 0) { + dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); + return ret; + } + if (chip->chip_irq != 0) { ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL, da9211_irq_handler, @@ -485,11 +491,6 @@ dev_warn(chip->dev, "No IRQ configured\n"); } - ret = da9211_regulator_init(chip); - - if (ret < 0) - dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); - return ret; } --- linux-oracle-5.4.0.orig/drivers/regulator/fan53555.c +++ linux-oracle-5.4.0/drivers/regulator/fan53555.c @@ -8,18 +8,19 @@ // Copyright (c) 2012 Marvell Technology Ltd. // Yunfan Zhang +#include +#include +#include #include +#include #include -#include #include +#include #include +#include #include #include -#include -#include #include -#include -#include /* Voltage setting */ #define FAN53555_VSEL0 0x00 --- linux-oracle-5.4.0.orig/drivers/regulator/fixed.c +++ linux-oracle-5.4.0/drivers/regulator/fixed.c @@ -181,8 +181,8 @@ drvdata->enable_clock = devm_clk_get(dev, NULL); if (IS_ERR(drvdata->enable_clock)) { - dev_err(dev, "Cant get enable-clock from devicetree\n"); - return -ENOENT; + dev_err(dev, "Can't get enable-clock from devicetree\n"); + return PTR_ERR(drvdata->enable_clock); } } else { drvdata->desc.ops = &fixed_voltage_ops; --- linux-oracle-5.4.0.orig/drivers/regulator/helpers.c +++ linux-oracle-5.4.0/drivers/regulator/helpers.c @@ -13,6 +13,8 @@ #include #include +#include "internal.h" + /** * regulator_is_enabled_regmap - standard is_enabled() for regmap users * @@ -881,3 +883,15 @@ consumers[i].supply = supply_names[i]; } EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names); + +/** + * regulator_is_equal - test whether two regulators are the same + * + * @reg1: first regulator to operate on + * @reg2: second regulator to operate on + */ +bool regulator_is_equal(struct regulator *reg1, struct regulator *reg2) +{ + return reg1->rdev == reg2->rdev; +} +EXPORT_SYMBOL_GPL(regulator_is_equal); --- linux-oracle-5.4.0.orig/drivers/regulator/hi6421-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/hi6421-regulator.c @@ -366,9 +366,8 @@ static int hi6421_regulator_enable(struct regulator_dev *rdev) { - struct hi6421_regulator_pdata *pdata; + struct hi6421_regulator_pdata *pdata = rdev_get_drvdata(rdev); - pdata = dev_get_drvdata(rdev->dev.parent); /* hi6421 spec requires regulator enablement must be serialized: * - Because when BUCK, LDO switching from off to on, it will have * a huge instantaneous current; so you can not turn on two or @@ -385,9 +384,10 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 reg_val; + struct hi6421_regulator_info *info; + unsigned int reg_val; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_IDLE; @@ -397,9 +397,10 @@ static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 reg_val; + struct hi6421_regulator_info *info; + unsigned int reg_val; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_STANDBY; @@ -410,9 +411,10 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 new_mode; + struct hi6421_regulator_info *info; + unsigned int new_mode; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); switch (mode) { case REGULATOR_MODE_NORMAL: new_mode = 0; @@ -434,9 +436,10 @@ static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 new_mode; + struct hi6421_regulator_info *info; + unsigned int new_mode; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); switch (mode) { case REGULATOR_MODE_NORMAL: new_mode = 0; @@ -459,7 +462,9 @@ hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + struct hi6421_regulator_info *info; + + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); if (load_uA > info->eco_microamp) return REGULATOR_MODE_NORMAL; @@ -543,14 +548,13 @@ if (!pdata) return -ENOMEM; mutex_init(&pdata->lock); - platform_set_drvdata(pdev, pdata); for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { /* assign per-regulator data */ info = &hi6421_regulator_info[i]; config.dev = pdev->dev.parent; - config.driver_data = info; + config.driver_data = pdata; config.regmap = pmic->regmap; rdev = devm_regulator_register(&pdev->dev, &info->desc, --- linux-oracle-5.4.0.orig/drivers/regulator/hi655x-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/hi655x-regulator.c @@ -72,7 +72,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev) { unsigned int value = 0; - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); regmap_read(rdev->regmap, regulator->status_reg, &value); return (value & rdev->desc->enable_mask); @@ -80,7 +80,7 @@ static int hi655x_disable(struct regulator_dev *rdev) { - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); return regmap_write(rdev->regmap, regulator->disable_reg, rdev->desc->enable_mask); @@ -169,7 +169,6 @@ static int hi655x_regulator_probe(struct platform_device *pdev) { unsigned int i; - struct hi655x_regulator *regulator; struct hi655x_pmic *pmic; struct regulator_config config = { }; struct regulator_dev *rdev; @@ -180,22 +179,17 @@ return -ENODEV; } - regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL); - if (!regulator) - return -ENOMEM; - - platform_set_drvdata(pdev, regulator); - config.dev = pdev->dev.parent; config.regmap = pmic->regmap; - config.driver_data = regulator; for (i = 0; i < ARRAY_SIZE(regulators); i++) { + config.driver_data = (void *) ®ulators[i]; + rdev = devm_regulator_register(&pdev->dev, ®ulators[i].rdesc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", - regulator->rdesc.name); + regulators[i].rdesc.name); return PTR_ERR(rdev); } } --- linux-oracle-5.4.0.orig/drivers/regulator/max77620-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/max77620-regulator.c @@ -814,6 +814,13 @@ config.dev = dev; config.driver_data = pmic; + /* + * Set of_node_reuse flag to prevent driver core from attempting to + * claim any pinmux resources already claimed by the parent device. + * Otherwise PMIC driver will fail to re-probe. + */ + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); + for (id = 0; id < MAX77620_NUM_REGS; id++) { struct regulator_dev *rdev; struct regulator_desc *rdesc; --- linux-oracle-5.4.0.orig/drivers/regulator/max77802-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/max77802-regulator.c @@ -95,9 +95,11 @@ { unsigned int val = MAX77802_OFF_PWRREQ; struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -111,7 +113,7 @@ static int max77802_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); @@ -128,6 +130,9 @@ return -EINVAL; } + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + max77802->opmode[id] = val; return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, rdev->desc->enable_mask, val << shift); @@ -136,8 +141,10 @@ static unsigned max77802_get_mode(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; return max77802_map_mode(max77802->opmode[id]); } @@ -161,10 +168,13 @@ unsigned int mode) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); unsigned int val; int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; + /* * If the regulator has been disabled for suspend * then is invalid to try setting a suspend mode. @@ -210,9 +220,11 @@ static int max77802_enable(struct regulator_dev *rdev) { struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); - int id = rdev_get_id(rdev); + unsigned int id = rdev_get_id(rdev); int shift = max77802_get_opmode_shift(id); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(max77802->opmode))) + return -EINVAL; if (max77802->opmode[id] == MAX77802_OFF_PWRREQ) max77802->opmode[id] = MAX77802_OPMODE_NORMAL; @@ -541,7 +553,7 @@ for (i = 0; i < MAX77802_REG_MAX; i++) { struct regulator_dev *rdev; - int id = regulators[i].id; + unsigned int id = regulators[i].id; int shift = max77802_get_opmode_shift(id); int ret; @@ -559,10 +571,12 @@ * the hardware reports OFF as the regulator operating mode. * Default to operating mode NORMAL in that case. */ - if (val == MAX77802_STATUS_OFF) - max77802->opmode[id] = MAX77802_OPMODE_NORMAL; - else - max77802->opmode[id] = val; + if (id < ARRAY_SIZE(max77802->opmode)) { + if (val == MAX77802_STATUS_OFF) + max77802->opmode[id] = MAX77802_OPMODE_NORMAL; + else + max77802->opmode[id] = val; + } rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); --- linux-oracle-5.4.0.orig/drivers/regulator/max8907-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/max8907-regulator.c @@ -296,7 +296,10 @@ memcpy(pmic->desc, max8907_regulators, sizeof(pmic->desc)); /* Backwards compatibility with MAX8907B; SD1 uses different voltages */ - regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); + ret = regmap_read(max8907->regmap_gen, MAX8907_REG_II2RR, &val); + if (ret) + return ret; + if ((val & MAX8907_II2RR_VERSION_MASK) == MAX8907_II2RR_VERSION_REV_B) { pmic->desc[MAX8907_SD1].min_uV = 637500; @@ -333,14 +336,20 @@ } if (pmic->desc[i].ops == &max8907_ldo_ops) { - regmap_read(config.regmap, pmic->desc[i].enable_reg, + ret = regmap_read(config.regmap, pmic->desc[i].enable_reg, &val); + if (ret) + return ret; + if ((val & MAX8907_MASK_LDO_SEQ) != MAX8907_MASK_LDO_SEQ) pmic->desc[i].ops = &max8907_ldo_hwctl_ops; } else if (pmic->desc[i].ops == &max8907_out5v_ops) { - regmap_read(config.regmap, pmic->desc[i].enable_reg, + ret = regmap_read(config.regmap, pmic->desc[i].enable_reg, &val); + if (ret) + return ret; + if ((val & (MAX8907_MASK_OUT5V_VINEN | MAX8907_MASK_OUT5V_ENSRC)) != MAX8907_MASK_OUT5V_ENSRC) --- linux-oracle-5.4.0.orig/drivers/regulator/mt6358-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/mt6358-regulator.c @@ -457,7 +457,7 @@ MT6358_REG_FIXED("ldo_vaud28", VAUD28, MT6358_LDO_VAUD28_CON0, 0, 2800000), MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx, - MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0), + MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf, 0), MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx, MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8), MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx, --- linux-oracle-5.4.0.orig/drivers/regulator/of_regulator.c +++ linux-oracle-5.4.0/drivers/regulator/of_regulator.c @@ -206,8 +206,12 @@ } suspend_np = of_get_child_by_name(np, regulator_states[i]); - if (!suspend_np || !suspend_state) + if (!suspend_np) continue; + if (!suspend_state) { + of_node_put(suspend_np); + continue; + } if (!of_property_read_u32(suspend_np, "regulator-mode", &pval)) { @@ -373,7 +377,7 @@ "failed to parse DT for regulator %pOFn\n", child); of_node_put(child); - return -EINVAL; + goto err_put; } match->of_node = of_node_get(child); count++; @@ -382,6 +386,18 @@ } return count; + +err_put: + for (i = 0; i < num_matches; i++) { + struct of_regulator_match *match = &matches[i]; + + match->init_data = NULL; + if (match->of_node) { + of_node_put(match->of_node); + match->of_node = NULL; + } + } + return -EINVAL; } EXPORT_SYMBOL_GPL(of_regulator_match); --- linux-oracle-5.4.0.orig/drivers/regulator/pfuze100-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/pfuze100-regulator.c @@ -209,6 +209,19 @@ }; +static const struct regulator_ops pfuze3000_sw_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_ascend, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = pfuze100_set_ramp_delay, + +}; + #define PFUZE100_FIXED_REG(_chip, _name, base, voltage) \ [_chip ## _ ## _name] = { \ .desc = { \ @@ -318,23 +331,28 @@ .stby_mask = 0x20, \ } - -#define PFUZE3000_SW2_REG(_chip, _name, base, min, max, step) { \ - .desc = { \ - .name = #_name,\ - .n_voltages = ((max) - (min)) / (step) + 1, \ - .ops = &pfuze100_sw_regulator_ops, \ - .type = REGULATOR_VOLTAGE, \ - .id = _chip ## _ ## _name, \ - .owner = THIS_MODULE, \ - .min_uV = (min), \ - .uV_step = (step), \ - .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ - .vsel_mask = 0x7, \ - }, \ - .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ - .stby_mask = 0x7, \ -} +/* No linar case for the some switches of PFUZE3000 */ +#define PFUZE3000_SW_REG(_chip, _name, base, mask, voltages) \ + [_chip ## _ ## _name] = { \ + .desc = { \ + .name = #_name, \ + .n_voltages = ARRAY_SIZE(voltages), \ + .ops = &pfuze3000_sw_regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = _chip ## _ ## _name, \ + .owner = THIS_MODULE, \ + .volt_table = voltages, \ + .vsel_reg = (base) + PFUZE100_VOL_OFFSET, \ + .vsel_mask = (mask), \ + .enable_reg = (base) + PFUZE100_MODE_OFFSET, \ + .enable_mask = 0xf, \ + .enable_val = 0x8, \ + .enable_time = 500, \ + }, \ + .stby_reg = (base) + PFUZE100_STANDBY_OFFSET, \ + .stby_mask = (mask), \ + .sw_reg = true, \ + } #define PFUZE3000_SW3_REG(_chip, _name, base, min, max, step) { \ .desc = { \ @@ -391,9 +409,9 @@ }; static struct pfuze_regulator pfuze3000_regulators[] = { - PFUZE100_SWB_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), + PFUZE3000_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), - PFUZE100_SWB_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), + PFUZE3000_SW_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), PFUZE3000_SW3_REG(PFUZE3000, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), PFUZE100_SWB_REG(PFUZE3000, SWBST, PFUZE100_SWBSTCON1, 0x3, pfuze100_swbst), PFUZE100_SWB_REG(PFUZE3000, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), @@ -407,8 +425,8 @@ }; static struct pfuze_regulator pfuze3001_regulators[] = { - PFUZE100_SWB_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), - PFUZE100_SWB_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), + PFUZE3000_SW_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), + PFUZE3000_SW_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), PFUZE100_SWB_REG(PFUZE3001, VSNVS, PFUZE100_VSNVSVOL, 0x7, pfuze100_vsnvs), PFUZE100_VGEN_REG(PFUZE3001, VLDO1, PFUZE100_VGEN1VOL, 1800000, 3300000, 100000), @@ -510,6 +528,7 @@ parent = of_get_child_by_name(np, "regulators"); if (!parent) { dev_err(dev, "regulators node not found\n"); + of_node_put(np); return -EINVAL; } @@ -539,6 +558,7 @@ } of_node_put(parent); + of_node_put(np); if (ret < 0) { dev_err(dev, "Error parsing regulator init data: %d\n", ret); @@ -768,7 +788,7 @@ ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, - sizeof(pfuze_chip->regulator_descs)); + regulator_num * sizeof(struct pfuze_regulator)); ret = pfuze_parse_regulators_dt(pfuze_chip); if (ret) @@ -815,11 +835,14 @@ * the switched regulator till yet. */ if (pfuze_chip->flags & PFUZE_FLAG_DISABLE_SW) { - if (pfuze_chip->regulator_descs[i].sw_reg) { - desc->ops = &pfuze100_sw_disable_regulator_ops; - desc->enable_val = 0x8; - desc->disable_val = 0x0; - desc->enable_time = 500; + if (pfuze_chip->chip_id == PFUZE100 || + pfuze_chip->chip_id == PFUZE200) { + if (pfuze_chip->regulator_descs[i].sw_reg) { + desc->ops = &pfuze100_sw_disable_regulator_ops; + desc->enable_val = 0x8; + desc->disable_val = 0x0; + desc->enable_time = 500; + } } } --- linux-oracle-5.4.0.orig/drivers/regulator/pwm-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/pwm-regulator.c @@ -158,6 +158,9 @@ pwm_get_state(drvdata->pwm, &pstate); voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit); + if (voltage < min(max_uV_duty, min_uV_duty) || + voltage > max(max_uV_duty, min_uV_duty)) + return -ENOTRECOVERABLE; /* * The dutycycle for min_uV might be greater than the one for max_uV. @@ -279,7 +282,7 @@ return ret; } - drvdata->state = -EINVAL; + drvdata->state = -ENOTRECOVERABLE; drvdata->duty_cycle_table = duty_cycle_table; drvdata->desc.ops = &pwm_regulator_voltage_table_ops; drvdata->desc.n_voltages = length / sizeof(*duty_cycle_table); --- linux-oracle-5.4.0.orig/drivers/regulator/qcom-rpmh-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/qcom-rpmh-regulator.c @@ -726,8 +726,8 @@ static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = { .regulator_type = VRM, .ops = &rpmh_regulator_vrm_ops, - .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600), - .n_voltages = 5, + .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 235, 16000), + .n_voltages = 236, .pmic_mode_map = pmic_mode_map_pmic5_smps, .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode, }; @@ -832,11 +832,11 @@ RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l2-l10"), RPMH_VREG("ldo11", "ldo%s11", &pmic5_nldo, "vdd-l1-l8-l11"), RPMH_VREG("ldo12", "ldo%s12", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l6-l17"), + RPMH_VREG("ldo13", "ldo%s13", &pmic5_pldo, "vdd-l13-l16-l17"), RPMH_VREG("ldo14", "ldo%s14", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), RPMH_VREG("ldo15", "ldo%s15", &pmic5_pldo_lv, "vdd-l7-l12-l14-l15"), - RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l6-l17"), - RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l6-l17"), + RPMH_VREG("ldo16", "ldo%s16", &pmic5_pldo, "vdd-l13-l16-l17"), + RPMH_VREG("ldo17", "ldo%s17", &pmic5_pldo, "vdd-l13-l16-l17"), RPMH_VREG("ldo18", "ldo%s18", &pmic5_nldo, "vdd-l3-l4-l5-l18"), {}, }; @@ -857,7 +857,7 @@ RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l4-l5-l6"), RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l4-l5-l6"), RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo, "vdd-l7-l11"), - RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l1-l8-l11"), + RPMH_VREG("ldo8", "ldo%s8", &pmic5_pldo_lv, "vdd-l1-l8"), RPMH_VREG("ldo9", "ldo%s9", &pmic5_pldo, "vdd-l9-l10"), RPMH_VREG("ldo10", "ldo%s10", &pmic5_pldo, "vdd-l9-l10"), RPMH_VREG("ldo11", "ldo%s11", &pmic5_pldo, "vdd-l7-l11"), @@ -874,7 +874,7 @@ RPMH_VREG("ldo4", "ldo%s4", &pmic5_nldo, "vdd-l4"), RPMH_VREG("ldo5", "ldo%s5", &pmic5_pldo, "vdd-l5-l6"), RPMH_VREG("ldo6", "ldo%s6", &pmic5_pldo, "vdd-l5-l6"), - RPMH_VREG("ldo7", "ldo%s6", &pmic5_pldo_lv, "vdd-l7"), + RPMH_VREG("ldo7", "ldo%s7", &pmic5_pldo_lv, "vdd-l7"), {}, }; --- linux-oracle-5.4.0.orig/drivers/regulator/qcom_rpm-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/qcom_rpm-regulator.c @@ -812,6 +812,12 @@ }; static const struct rpm_regulator_data rpm_pm8058_regulators[] = { + { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, + { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, + { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, + { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, + { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, + { "l0", QCOM_RPM_PM8058_LDO0, &pm8058_nldo, "vdd_l0_l1_lvs" }, { "l1", QCOM_RPM_PM8058_LDO1, &pm8058_nldo, "vdd_l0_l1_lvs" }, { "l2", QCOM_RPM_PM8058_LDO2, &pm8058_pldo, "vdd_l2_l11_l12" }, @@ -839,12 +845,6 @@ { "l24", QCOM_RPM_PM8058_LDO24, &pm8058_nldo, "vdd_l23_l24_l25" }, { "l25", QCOM_RPM_PM8058_LDO25, &pm8058_nldo, "vdd_l23_l24_l25" }, - { "s0", QCOM_RPM_PM8058_SMPS0, &pm8058_smps, "vdd_s0" }, - { "s1", QCOM_RPM_PM8058_SMPS1, &pm8058_smps, "vdd_s1" }, - { "s2", QCOM_RPM_PM8058_SMPS2, &pm8058_smps, "vdd_s2" }, - { "s3", QCOM_RPM_PM8058_SMPS3, &pm8058_smps, "vdd_s3" }, - { "s4", QCOM_RPM_PM8058_SMPS4, &pm8058_smps, "vdd_s4" }, - { "lvs0", QCOM_RPM_PM8058_LVS0, &pm8058_switch, "vdd_l0_l1_lvs" }, { "lvs1", QCOM_RPM_PM8058_LVS1, &pm8058_switch, "vdd_l0_l1_lvs" }, @@ -853,6 +853,12 @@ }; static const struct rpm_regulator_data rpm_pm8901_regulators[] = { + { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, + { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, + { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, + { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, + { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, + { "l0", QCOM_RPM_PM8901_LDO0, &pm8901_nldo, "vdd_l0" }, { "l1", QCOM_RPM_PM8901_LDO1, &pm8901_pldo, "vdd_l1" }, { "l2", QCOM_RPM_PM8901_LDO2, &pm8901_pldo, "vdd_l2" }, @@ -861,12 +867,6 @@ { "l5", QCOM_RPM_PM8901_LDO5, &pm8901_pldo, "vdd_l5" }, { "l6", QCOM_RPM_PM8901_LDO6, &pm8901_pldo, "vdd_l6" }, - { "s0", QCOM_RPM_PM8901_SMPS0, &pm8901_ftsmps, "vdd_s0" }, - { "s1", QCOM_RPM_PM8901_SMPS1, &pm8901_ftsmps, "vdd_s1" }, - { "s2", QCOM_RPM_PM8901_SMPS2, &pm8901_ftsmps, "vdd_s2" }, - { "s3", QCOM_RPM_PM8901_SMPS3, &pm8901_ftsmps, "vdd_s3" }, - { "s4", QCOM_RPM_PM8901_SMPS4, &pm8901_ftsmps, "vdd_s4" }, - { "lvs0", QCOM_RPM_PM8901_LVS0, &pm8901_switch, "lvs0_in" }, { "lvs1", QCOM_RPM_PM8901_LVS1, &pm8901_switch, "lvs1_in" }, { "lvs2", QCOM_RPM_PM8901_LVS2, &pm8901_switch, "lvs2_in" }, --- linux-oracle-5.4.0.orig/drivers/regulator/qcom_smd-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/qcom_smd-regulator.c @@ -9,6 +9,7 @@ #include #include #include +#include #include struct qcom_rpm_reg { @@ -776,52 +777,93 @@ }; MODULE_DEVICE_TABLE(of, rpm_of_match); -static int rpm_reg_probe(struct platform_device *pdev) +/** + * rpm_regulator_init_vreg() - initialize all attributes of a qcom_smd-regulator + * @vreg: Pointer to the individual qcom_smd-regulator resource + * @dev: Pointer to the top level qcom_smd-regulator PMIC device + * @node: Pointer to the individual qcom_smd-regulator resource + * device node + * @rpm: Pointer to the rpm bus node + * @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator + * resources defined for the top level PMIC device + * + * Return: 0 on success, errno on failure + */ +static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev, + struct device_node *node, struct qcom_smd_rpm *rpm, + const struct rpm_regulator_data *pmic_rpm_data) { - const struct rpm_regulator_data *reg; - const struct of_device_id *match; - struct regulator_config config = { }; + struct regulator_config config = {}; + const struct rpm_regulator_data *rpm_data; struct regulator_dev *rdev; + int ret; + + for (rpm_data = pmic_rpm_data; rpm_data->name; rpm_data++) + if (of_node_name_eq(node, rpm_data->name)) + break; + + if (!rpm_data->name) { + dev_err(dev, "Unknown regulator %pOFn\n", node); + return -EINVAL; + } + + vreg->dev = dev; + vreg->rpm = rpm; + vreg->type = rpm_data->type; + vreg->id = rpm_data->id; + + memcpy(&vreg->desc, rpm_data->desc, sizeof(vreg->desc)); + vreg->desc.name = rpm_data->name; + vreg->desc.supply_name = rpm_data->supply; + vreg->desc.owner = THIS_MODULE; + vreg->desc.type = REGULATOR_VOLTAGE; + vreg->desc.of_match = rpm_data->name; + + config.dev = dev; + config.of_node = node; + config.driver_data = vreg; + + rdev = devm_regulator_register(dev, &vreg->desc, &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "%pOFn: devm_regulator_register() failed, ret=%d\n", node, ret); + return ret; + } + + return 0; +} + +static int rpm_reg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct rpm_regulator_data *vreg_data; + struct device_node *node; struct qcom_rpm_reg *vreg; struct qcom_smd_rpm *rpm; + int ret; rpm = dev_get_drvdata(pdev->dev.parent); if (!rpm) { - dev_err(&pdev->dev, "unable to retrieve handle to rpm\n"); + dev_err(&pdev->dev, "Unable to retrieve handle to rpm\n"); return -ENODEV; } - match = of_match_device(rpm_of_match, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "failed to match device\n"); + vreg_data = of_device_get_match_data(dev); + if (!vreg_data) return -ENODEV; - } - for (reg = match->data; reg->name; reg++) { + for_each_available_child_of_node(dev->of_node, node) { vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); - if (!vreg) + if (!vreg) { + of_node_put(node); return -ENOMEM; + } + + ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data); - vreg->dev = &pdev->dev; - vreg->type = reg->type; - vreg->id = reg->id; - vreg->rpm = rpm; - - memcpy(&vreg->desc, reg->desc, sizeof(vreg->desc)); - - vreg->desc.id = -1; - vreg->desc.owner = THIS_MODULE; - vreg->desc.type = REGULATOR_VOLTAGE; - vreg->desc.name = reg->name; - vreg->desc.supply_name = reg->supply; - vreg->desc.of_match = reg->name; - - config.dev = &pdev->dev; - config.driver_data = vreg; - rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, "failed to register %s\n", reg->name); - return PTR_ERR(rdev); + if (ret < 0) { + of_node_put(node); + return ret; } } --- linux-oracle-5.4.0.orig/drivers/regulator/rk808-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/rk808-regulator.c @@ -959,6 +959,8 @@ .n_linear_ranges = ARRAY_SIZE(rk817_buck1_voltage_ranges), .vsel_reg = RK817_BUCK3_ON_VSEL_REG, .vsel_mask = RK817_BUCK_VSEL_MASK, + .apply_reg = RK817_POWER_CONFIG, + .apply_bit = RK817_BUCK3_FB_RES_INTER, .enable_reg = RK817_POWER_EN_REG(0), .enable_mask = ENABLE_MASK(RK817_ID_DCDC3), .enable_val = ENABLE_MASK(RK817_ID_DCDC3), @@ -1297,7 +1299,7 @@ } if (!pdata->dvs_gpio[i]) { - dev_warn(dev, "there is no dvs%d gpio\n", i); + dev_info(dev, "there is no dvs%d gpio\n", i); continue; } --- linux-oracle-5.4.0.orig/drivers/regulator/rn5t618-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/rn5t618-regulator.c @@ -148,6 +148,7 @@ module_platform_driver(rn5t618_regulator_driver); +MODULE_ALIAS("platform:rn5t618-regulator"); MODULE_AUTHOR("Beniamino Galvani "); MODULE_DESCRIPTION("RN5T618 regulator driver"); MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/regulator/s5m8767.c +++ linux-oracle-5.4.0/drivers/regulator/s5m8767.c @@ -544,14 +544,18 @@ rdata = devm_kcalloc(&pdev->dev, pdata->num_regulators, sizeof(*rdata), GFP_KERNEL); - if (!rdata) + if (!rdata) { + of_node_put(regulators_np); return -ENOMEM; + } rmode = devm_kcalloc(&pdev->dev, pdata->num_regulators, sizeof(*rmode), GFP_KERNEL); - if (!rmode) + if (!rmode) { + of_node_put(regulators_np); return -ENOMEM; + } pdata->regulators = rdata; pdata->opmode = rmode; @@ -574,10 +578,13 @@ 0, GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE, "s5m8767"); - if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT) + if (PTR_ERR(rdata->ext_control_gpiod) == -ENOENT) { rdata->ext_control_gpiod = NULL; - else if (IS_ERR(rdata->ext_control_gpiod)) + } else if (IS_ERR(rdata->ext_control_gpiod)) { + of_node_put(reg_np); + of_node_put(regulators_np); return PTR_ERR(rdata->ext_control_gpiod); + } rdata->id = i; rdata->initdata = of_get_regulator_init_data( @@ -844,18 +851,15 @@ /* DS4 GPIO */ gpio_direction_output(pdata->buck_ds[2], 0x0); - if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || - pdata->buck4_gpiodvs) { - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK2CTRL, 1 << 1, - (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK3CTRL, 1 << 1, - (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); - regmap_update_bits(s5m8767->iodev->regmap_pmic, - S5M8767_REG_BUCK4CTRL, 1 << 1, - (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1)); - } + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK2CTRL, 1 << 1, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK3CTRL, 1 << 1, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1)); + regmap_update_bits(s5m8767->iodev->regmap_pmic, + S5M8767_REG_BUCK4CTRL, 1 << 1, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1)); /* Initialize GPIO DVS registers */ for (i = 0; i < 8; i++) { @@ -920,10 +924,14 @@ for (i = 0; i < pdata->num_regulators; i++) { const struct sec_voltage_desc *desc; - int id = pdata->regulators[i].id; + unsigned int id = pdata->regulators[i].id; int enable_reg, enable_val; struct regulator_dev *rdev; + BUILD_BUG_ON(ARRAY_SIZE(regulators) != ARRAY_SIZE(reg_voltage_map)); + if (WARN_ON_ONCE(id >= ARRAY_SIZE(regulators))) + continue; + desc = reg_voltage_map[id]; if (desc) { regulators[id].n_voltages = --- linux-oracle-5.4.0.orig/drivers/regulator/slg51000-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/slg51000-regulator.c @@ -465,6 +465,8 @@ chip->cs_gpiod = cs_gpiod; } + usleep_range(10000, 11000); + i2c_set_clientdata(client, chip); chip->chip_irq = client->irq; chip->dev = dev; --- linux-oracle-5.4.0.orig/drivers/regulator/stm32-pwr.c +++ linux-oracle-5.4.0/drivers/regulator/stm32-pwr.c @@ -129,17 +129,16 @@ static int stm32_pwr_regulator_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; struct stm32_pwr_reg *priv; void __iomem *base; struct regulator_dev *rdev; struct regulator_config config = { }; int i, ret = 0; - base = of_iomap(np, 0); - if (!base) { + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) { dev_err(&pdev->dev, "Unable to map IO memory\n"); - return -ENOMEM; + return PTR_ERR(base); } config.dev = &pdev->dev; --- linux-oracle-5.4.0.orig/drivers/regulator/stm32-vrefbuf.c +++ linux-oracle-5.4.0/drivers/regulator/stm32-vrefbuf.c @@ -88,7 +88,7 @@ } val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); - val = (val & ~STM32_ENVR) | STM32_HIZ; + val &= ~STM32_ENVR; writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); pm_runtime_mark_last_busy(priv->dev); @@ -175,6 +175,7 @@ .volt_table = stm32_vrefbuf_voltages, .n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages), .ops = &stm32_vrefbuf_volt_ops, + .off_on_delay = 1000, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }; --- linux-oracle-5.4.0.orig/drivers/regulator/ti-abb-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/ti-abb-regulator.c @@ -342,8 +342,17 @@ return ret; } - /* If data is exactly the same, then just update index, no change */ info = &abb->info[sel]; + /* + * When Linux kernel is starting up, we are'nt sure of the + * Bias configuration that bootloader has configured. + * So, we get to know the actual setting the first time + * we are asked to transition. + */ + if (abb->current_info_idx == -EINVAL) + goto just_set_abb; + + /* If data is exactly the same, then just update index, no change */ oinfo = &abb->info[abb->current_info_idx]; if (!memcmp(info, oinfo, sizeof(*info))) { dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n", __func__, @@ -351,6 +360,7 @@ goto out; } +just_set_abb: ret = ti_abb_set_opp(rdev, abb, info); out: --- linux-oracle-5.4.0.orig/drivers/regulator/twl6030-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/twl6030-regulator.c @@ -67,6 +67,7 @@ #define TWL6030_CFG_STATE_SLEEP 0x03 #define TWL6030_CFG_STATE_GRP_SHIFT 5 #define TWL6030_CFG_STATE_APP_SHIFT 2 +#define TWL6030_CFG_STATE_MASK 0x03 #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT) #define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\ TWL6030_CFG_STATE_APP_SHIFT) @@ -128,13 +129,14 @@ if (grp < 0) return grp; grp &= P1_GRP_6030; + val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); + val = TWL6030_CFG_STATE_APP(val); } else { + val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); + val &= TWL6030_CFG_STATE_MASK; grp = 1; } - val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); - val = TWL6030_CFG_STATE_APP(val); - return grp && (val == TWL6030_CFG_STATE_ON); } @@ -187,7 +189,12 @@ val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE); - switch (TWL6030_CFG_STATE_APP(val)) { + if (info->features & TWL6032_SUBCLASS) + val &= TWL6030_CFG_STATE_MASK; + else + val = TWL6030_CFG_STATE_APP(val); + + switch (val) { case TWL6030_CFG_STATE_ON: return REGULATOR_STATUS_NORMAL; @@ -530,6 +537,7 @@ #define TWL6032_ADJUSTABLE_LDO(label, offset) \ static const struct twlreg_info TWL6032_INFO_##label = { \ .base = offset, \ + .features = TWL6032_SUBCLASS, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ @@ -562,6 +570,7 @@ #define TWL6032_ADJUSTABLE_SMPS(label, offset) \ static const struct twlreg_info TWLSMPS_INFO_##label = { \ .base = offset, \ + .features = TWL6032_SUBCLASS, \ .desc = { \ .name = #label, \ .id = TWL6032_REG_##label, \ --- linux-oracle-5.4.0.orig/drivers/regulator/uniphier-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/uniphier-regulator.c @@ -203,6 +203,7 @@ }, { /* Sentinel */ }, }; +MODULE_DEVICE_TABLE(of, uniphier_regulator_match); static struct platform_driver uniphier_regulator_driver = { .probe = uniphier_regulator_probe, --- linux-oracle-5.4.0.orig/drivers/regulator/vctrl-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/vctrl-regulator.c @@ -11,10 +11,13 @@ #include #include #include +#include #include #include #include +#include "internal.h" + struct vctrl_voltage_range { int min_uV; int max_uV; @@ -34,7 +37,6 @@ struct vctrl_data { struct regulator_dev *rdev; struct regulator_desc desc; - struct regulator *ctrl_reg; bool enabled; unsigned int min_slew_down_rate; unsigned int ovp_threshold; @@ -79,7 +81,12 @@ static int vctrl_get_voltage(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg); + int ctrl_uV; + + if (!rdev->supply) + return -EPROBE_DEFER; + + ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev); return vctrl_calc_output_voltage(vctrl, ctrl_uV); } @@ -89,17 +96,22 @@ unsigned int *selector) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - struct regulator *ctrl_reg = vctrl->ctrl_reg; - int orig_ctrl_uV = regulator_get_voltage(ctrl_reg); - int uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV); + int orig_ctrl_uV; + int uV; int ret; + if (!rdev->supply) + return -EPROBE_DEFER; + + orig_ctrl_uV = regulator_get_voltage_rdev(rdev->supply->rdev); + uV = vctrl_calc_output_voltage(vctrl, orig_ctrl_uV); + if (req_min_uV >= uV || !vctrl->ovp_threshold) /* voltage rising or no OVP */ - return regulator_set_voltage( - ctrl_reg, + return regulator_set_voltage_rdev(rdev->supply->rdev, vctrl_calc_ctrl_voltage(vctrl, req_min_uV), - vctrl_calc_ctrl_voltage(vctrl, req_max_uV)); + vctrl_calc_ctrl_voltage(vctrl, req_max_uV), + PM_SUSPEND_ON); while (uV > req_min_uV) { int max_drop_uV = (uV * vctrl->ovp_threshold) / 100; @@ -114,9 +126,10 @@ next_uV = max_t(int, req_min_uV, uV - max_drop_uV); next_ctrl_uV = vctrl_calc_ctrl_voltage(vctrl, next_uV); - ret = regulator_set_voltage(ctrl_reg, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, + next_ctrl_uV, next_ctrl_uV, - next_ctrl_uV); + PM_SUSPEND_ON); if (ret) goto err; @@ -130,7 +143,8 @@ err: /* Try to go back to original voltage */ - regulator_set_voltage(ctrl_reg, orig_ctrl_uV, orig_ctrl_uV); + regulator_set_voltage_rdev(rdev->supply->rdev, orig_ctrl_uV, orig_ctrl_uV, + PM_SUSPEND_ON); return ret; } @@ -146,18 +160,21 @@ unsigned int selector) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - struct regulator *ctrl_reg = vctrl->ctrl_reg; unsigned int orig_sel = vctrl->sel; int ret; + if (!rdev->supply) + return -EPROBE_DEFER; + if (selector >= rdev->desc->n_voltages) return -EINVAL; if (selector >= vctrl->sel || !vctrl->ovp_threshold) { /* voltage rising or no OVP */ - ret = regulator_set_voltage(ctrl_reg, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, + vctrl->vtable[selector].ctrl, vctrl->vtable[selector].ctrl, - vctrl->vtable[selector].ctrl); + PM_SUSPEND_ON); if (!ret) vctrl->sel = selector; @@ -173,9 +190,10 @@ else next_sel = vctrl->vtable[vctrl->sel].ovp_min_sel; - ret = regulator_set_voltage(ctrl_reg, + ret = regulator_set_voltage_rdev(rdev->supply->rdev, vctrl->vtable[next_sel].ctrl, - vctrl->vtable[next_sel].ctrl); + vctrl->vtable[next_sel].ctrl, + PM_SUSPEND_ON); if (ret) { dev_err(&rdev->dev, "failed to set control voltage to %duV\n", @@ -195,9 +213,10 @@ err: if (vctrl->sel != orig_sel) { /* Try to go back to original voltage */ - if (!regulator_set_voltage(ctrl_reg, + if (!regulator_set_voltage_rdev(rdev->supply->rdev, + vctrl->vtable[orig_sel].ctrl, vctrl->vtable[orig_sel].ctrl, - vctrl->vtable[orig_sel].ctrl)) + PM_SUSPEND_ON)) vctrl->sel = orig_sel; else dev_warn(&rdev->dev, @@ -226,10 +245,6 @@ u32 pval; u32 vrange_ctrl[2]; - vctrl->ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl"); - if (IS_ERR(vctrl->ctrl_reg)) - return PTR_ERR(vctrl->ctrl_reg); - ret = of_property_read_u32(np, "ovp-threshold-percent", &pval); if (!ret) { vctrl->ovp_threshold = pval; @@ -307,11 +322,11 @@ return at->ctrl - bt->ctrl; } -static int vctrl_init_vtable(struct platform_device *pdev) +static int vctrl_init_vtable(struct platform_device *pdev, + struct regulator *ctrl_reg) { struct vctrl_data *vctrl = platform_get_drvdata(pdev); struct regulator_desc *rdesc = &vctrl->desc; - struct regulator *ctrl_reg = vctrl->ctrl_reg; struct vctrl_voltage_range *vrange_ctrl = &vctrl->vrange.ctrl; int n_voltages; int ctrl_uV; @@ -387,23 +402,19 @@ static int vctrl_enable(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ret = regulator_enable(vctrl->ctrl_reg); - if (!ret) - vctrl->enabled = true; + vctrl->enabled = true; - return ret; + return 0; } static int vctrl_disable(struct regulator_dev *rdev) { struct vctrl_data *vctrl = rdev_get_drvdata(rdev); - int ret = regulator_disable(vctrl->ctrl_reg); - if (!ret) - vctrl->enabled = false; + vctrl->enabled = false; - return ret; + return 0; } static int vctrl_is_enabled(struct regulator_dev *rdev) @@ -439,6 +450,7 @@ struct regulator_desc *rdesc; struct regulator_config cfg = { }; struct vctrl_voltage_range *vrange_ctrl; + struct regulator *ctrl_reg; int ctrl_uV; int ret; @@ -453,15 +465,20 @@ if (ret) return ret; + ctrl_reg = devm_regulator_get(&pdev->dev, "ctrl"); + if (IS_ERR(ctrl_reg)) + return PTR_ERR(ctrl_reg); + vrange_ctrl = &vctrl->vrange.ctrl; rdesc = &vctrl->desc; rdesc->name = "vctrl"; rdesc->type = REGULATOR_VOLTAGE; rdesc->owner = THIS_MODULE; + rdesc->supply_name = "ctrl"; - if ((regulator_get_linear_step(vctrl->ctrl_reg) == 1) || - (regulator_count_voltages(vctrl->ctrl_reg) == -EINVAL)) { + if ((regulator_get_linear_step(ctrl_reg) == 1) || + (regulator_count_voltages(ctrl_reg) == -EINVAL)) { rdesc->continuous_voltage_range = true; rdesc->ops = &vctrl_ops_cont; } else { @@ -478,11 +495,12 @@ cfg.init_data = init_data; if (!rdesc->continuous_voltage_range) { - ret = vctrl_init_vtable(pdev); + ret = vctrl_init_vtable(pdev, ctrl_reg); if (ret) return ret; - ctrl_uV = regulator_get_voltage(vctrl->ctrl_reg); + /* Use locked consumer API when not in regulator framework */ + ctrl_uV = regulator_get_voltage(ctrl_reg); if (ctrl_uV < 0) { dev_err(&pdev->dev, "failed to get control voltage\n"); return ctrl_uV; @@ -505,6 +523,9 @@ } } + /* Drop ctrl-supply here in favor of regulator core managed supply */ + devm_regulator_put(ctrl_reg); + vctrl->rdev = devm_regulator_register(&pdev->dev, rdesc, &cfg); if (IS_ERR(vctrl->rdev)) { ret = PTR_ERR(vctrl->rdev); --- linux-oracle-5.4.0.orig/drivers/regulator/wm8994-regulator.c +++ linux-oracle-5.4.0/drivers/regulator/wm8994-regulator.c @@ -82,6 +82,35 @@ .min_uV = 2400000, .uV_step = 100000, .enable_time = 3000, + .off_on_delay = 36000, + .owner = THIS_MODULE, + }, + { + .name = "LDO2", + .id = 2, + .type = REGULATOR_VOLTAGE, + .n_voltages = WM8994_LDO2_MAX_SELECTOR + 1, + .vsel_reg = WM8994_LDO_2, + .vsel_mask = WM8994_LDO2_VSEL_MASK, + .ops = &wm8994_ldo2_ops, + .enable_time = 3000, + .off_on_delay = 36000, + .owner = THIS_MODULE, + }, +}; + +static const struct regulator_desc wm8958_ldo_desc[] = { + { + .name = "LDO1", + .id = 1, + .type = REGULATOR_VOLTAGE, + .n_voltages = WM8994_LDO1_MAX_SELECTOR + 1, + .vsel_reg = WM8994_LDO_1, + .vsel_mask = WM8994_LDO1_VSEL_MASK, + .ops = &wm8994_ldo1_ops, + .min_uV = 2400000, + .uV_step = 100000, + .enable_time = 3000, .owner = THIS_MODULE, }, { @@ -172,9 +201,16 @@ * regulator core and we need not worry about it on the * error path. */ - ldo->regulator = devm_regulator_register(&pdev->dev, - &wm8994_ldo_desc[id], - &config); + if (ldo->wm8994->type == WM8994) { + ldo->regulator = devm_regulator_register(&pdev->dev, + &wm8994_ldo_desc[id], + &config); + } else { + ldo->regulator = devm_regulator_register(&pdev->dev, + &wm8958_ldo_desc[id], + &config); + } + if (IS_ERR(ldo->regulator)) { ret = PTR_ERR(ldo->regulator); dev_err(wm8994->dev, "Failed to register LDO%d: %d\n", --- linux-oracle-5.4.0.orig/drivers/remoteproc/imx_rproc.c +++ linux-oracle-5.4.0/drivers/remoteproc/imx_rproc.c @@ -286,6 +286,11 @@ struct resource res; node = of_parse_phandle(np, "memory-region", a); + if (!node) + continue; + /* Not map vdevbuffer, vdevring region */ + if (!strncmp(node->name, "vdev", strlen("vdev"))) + continue; err = of_address_to_resource(node, 0, &res); if (err) { dev_err(dev, "unable to resolve memory region\n"); --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_q6v5.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_q6v5.c @@ -151,6 +151,8 @@ { int ret; + q6v5->running = false; + qcom_smem_state_update_bits(q6v5->state, BIT(q6v5->stop_bit), BIT(q6v5->stop_bit)); --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_q6v5_adsp.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_q6v5_adsp.c @@ -184,8 +184,10 @@ dev_pm_genpd_set_performance_state(adsp->dev, INT_MAX); ret = pm_runtime_get_sync(adsp->dev); - if (ret) + if (ret) { + pm_runtime_put_noidle(adsp->dev); goto disable_xo_clk; + } ret = clk_bulk_prepare_enable(adsp->num_clks, adsp->clks); if (ret) { @@ -345,15 +347,12 @@ struct platform_device *pdev) { struct device_node *syscon; - struct resource *res; int ret; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - adsp->qdsp6ss_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!adsp->qdsp6ss_base) { + adsp->qdsp6ss_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(adsp->qdsp6ss_base)) { dev_err(adsp->dev, "failed to map QDSP6SS registers\n"); - return -ENOMEM; + return PTR_ERR(adsp->qdsp6ss_base); } syscon = of_parse_phandle(pdev->dev.of_node, "qcom,halt-regs", 0); @@ -390,6 +389,7 @@ } ret = of_address_to_resource(node, 0, &r); + of_node_put(node); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_q6v5_mss.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_q6v5_mss.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,9 @@ void *mba_region; size_t mba_size; + phys_addr_t mdata_phys; + size_t mdata_size; + phys_addr_t mpss_phys; phys_addr_t mpss_reloc; void *mpss_region; @@ -331,8 +335,11 @@ for (i = 0; i < pd_count; i++) { dev_pm_genpd_set_performance_state(pds[i], INT_MAX); ret = pm_runtime_get_sync(pds[i]); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(pds[i]); + dev_pm_genpd_set_performance_state(pds[i], 0); goto unroll_pd_votes; + } } return 0; @@ -381,6 +388,12 @@ { struct q6v5 *qproc = rproc->priv; + /* MBA is restricted to a maximum size of 1M */ + if (fw->size > qproc->mba_size || fw->size > SZ_1M) { + dev_err(qproc->dev, "MBA firmware load failed\n"); + return -EINVAL; + } + memcpy(qproc->mba_region, fw->data, fw->size); return 0; @@ -670,15 +683,35 @@ if (IS_ERR(metadata)) return PTR_ERR(metadata); - ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); - if (!ptr) { - kfree(metadata); - dev_err(qproc->dev, "failed to allocate mdt buffer\n"); - return -ENOMEM; + if (qproc->mdata_phys) { + if (size > qproc->mdata_size) { + ret = -EINVAL; + dev_err(qproc->dev, "metadata size outside memory range\n"); + goto free_metadata; + } + + phys = qproc->mdata_phys; + ptr = memremap(qproc->mdata_phys, size, MEMREMAP_WC); + if (!ptr) { + ret = -EBUSY; + dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", + &qproc->mdata_phys, size); + goto free_metadata; + } + } else { + ptr = dma_alloc_attrs(qproc->dev, size, &phys, GFP_KERNEL, dma_attrs); + if (!ptr) { + ret = -ENOMEM; + dev_err(qproc->dev, "failed to allocate mdt buffer\n"); + goto free_metadata; + } } memcpy(ptr, metadata, size); + if (qproc->mdata_phys) + memunmap(ptr); + /* Hypervisor mapping to access metadata by modem */ mdata_perm = BIT(QCOM_SCM_VMID_HLOS); ret = q6v5_xfer_mem_ownership(qproc, &mdata_perm, true, phys, size); @@ -705,7 +738,9 @@ "mdt buffer not reclaimed system may become unstable\n"); free_dma_attrs: - dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); + if (!qproc->mdata_phys) + dma_free_attrs(qproc->dev, size, ptr, phys, dma_attrs); +free_metadata: kfree(metadata); return ret < 0 ? ret : 0; @@ -875,11 +910,6 @@ writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); } - ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, - false, qproc->mpss_phys, - qproc->mpss_size); - WARN_ON(ret); - q6v5_reset_assert(qproc); q6v5_clk_disable(qproc->dev, qproc->reset_clks, @@ -909,6 +939,23 @@ } } +static int q6v5_reload_mba(struct rproc *rproc) +{ + struct q6v5 *qproc = rproc->priv; + const struct firmware *fw; + int ret; + + ret = request_firmware(&fw, rproc->firmware, qproc->dev); + if (ret < 0) + return ret; + + q6v5_load(rproc, fw); + ret = q6v5_mba_load(qproc); + release_firmware(fw); + + return ret; +} + static int q6v5_mpss_load(struct q6v5 *qproc) { const struct elf32_phdr *phdrs; @@ -969,6 +1016,14 @@ max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); } + /** + * In case of a modem subsystem restart on secure devices, the modem + * memory can be reclaimed only after MBA is loaded. For modem cold + * boot this will be a nop + */ + q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, false, + qproc->mpss_phys, qproc->mpss_size); + mpss_reloc = relocate ? min_addr : qproc->mpss_phys; qproc->mpss_reloc = mpss_reloc; /* Load firmware segments */ @@ -985,7 +1040,13 @@ goto release_firmware; } - ptr = qproc->mpss_region + offset; + ptr = ioremap_wc(qproc->mpss_phys + offset, phdr->p_memsz); + if (!ptr) { + dev_err(qproc->dev, + "unable to map memory region: %pa+%zx-%x\n", + &qproc->mpss_phys, offset, phdr->p_memsz); + goto release_firmware; + } if (phdr->p_filesz && phdr->p_offset < fw->size) { /* Firmware is large enough to be non-split */ @@ -994,6 +1055,7 @@ "failed to load segment %d from truncated file %s\n", i, fw_name); ret = -EINVAL; + iounmap(ptr); goto release_firmware; } @@ -1001,14 +1063,14 @@ } else if (phdr->p_filesz) { /* Replace "xxx.xxx" with "xxx.bxx" */ sprintf(fw_name + fw_name_len - 3, "b%02d", i); - ret = request_firmware(&seg_fw, fw_name, qproc->dev); + ret = request_firmware_into_buf(&seg_fw, fw_name, qproc->dev, + ptr, phdr->p_filesz); if (ret) { dev_err(qproc->dev, "failed to load %s\n", fw_name); + iounmap(ptr); goto release_firmware; } - memcpy(ptr, seg_fw->data, seg_fw->size); - release_firmware(seg_fw); } @@ -1016,6 +1078,7 @@ memset(ptr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } + iounmap(ptr); size += phdr->p_memsz; } @@ -1055,23 +1118,43 @@ int ret = 0; struct q6v5 *qproc = rproc->priv; unsigned long mask = BIT((unsigned long)segment->priv); - void *ptr = rproc_da_to_va(rproc, segment->da, segment->size); + int offset = segment->da - qproc->mpss_reloc; + void *ptr = NULL; /* Unlock mba before copying segments */ - if (!qproc->dump_mba_loaded) - ret = q6v5_mba_load(qproc); + if (!qproc->dump_mba_loaded) { + ret = q6v5_reload_mba(rproc); + if (!ret) { + /* Reset ownership back to Linux to copy segments */ + ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, + false, + qproc->mpss_phys, + qproc->mpss_size); + } + } - if (!ptr || ret) - memset(dest, 0xff, segment->size); - else + if (!ret) + ptr = ioremap_wc(qproc->mpss_phys + offset, segment->size); + + if (ptr) { memcpy(dest, ptr, segment->size); + iounmap(ptr); + } else { + memset(dest, 0xff, segment->size); + } qproc->dump_segment_mask |= mask; /* Reclaim mba after copying segments */ if (qproc->dump_segment_mask == qproc->dump_complete_mask) { - if (qproc->dump_mba_loaded) + if (qproc->dump_mba_loaded) { + /* Try to reset ownership back to Q6 */ + q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, + true, + qproc->mpss_phys, + qproc->mpss_size); q6v5_mba_reclaim(qproc); + } } } @@ -1111,10 +1194,6 @@ return 0; reclaim_mpss: - xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mpss_perm, - false, qproc->mpss_phys, - qproc->mpss_size); - WARN_ON(xfermemop_ret); q6v5_mba_reclaim(qproc); return ret; @@ -1330,6 +1409,7 @@ static int q6v5_alloc_memory_region(struct q6v5 *qproc) { struct device_node *child; + struct reserved_mem *rmem; struct device_node *node; struct resource r; int ret; @@ -1363,13 +1443,27 @@ qproc->mpss_phys = qproc->mpss_reloc = r.start; qproc->mpss_size = resource_size(&r); - qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size); - if (!qproc->mpss_region) { - dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", - &r.start, qproc->mpss_size); - return -EBUSY; + + if (!child) { + node = of_parse_phandle(qproc->dev->of_node, "memory-region", 2); + } else { + child = of_get_child_by_name(qproc->dev->of_node, "metadata"); + node = of_parse_phandle(child, "memory-region", 0); + of_node_put(child); } + if (!node) + return 0; + + rmem = of_reserved_mem_lookup(node); + if (!rmem) { + dev_err(qproc->dev, "unable to resolve metadata region\n"); + return -EINVAL; + } + + qproc->mdata_phys = rmem->base; + qproc->mdata_size = rmem->size; + return 0; } @@ -1410,7 +1504,7 @@ ret = of_property_read_string_index(pdev->dev.of_node, "firmware-name", 1, &qproc->hexagon_mdt_image); if (ret < 0 && ret != -EINVAL) - return ret; + goto free_rproc; platform_set_drvdata(pdev, qproc); --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_q6v5_pas.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_q6v5_pas.c @@ -230,6 +230,7 @@ } ret = of_address_to_resource(node, 0, &r); + of_node_put(node); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_sysmon.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_sysmon.c @@ -518,7 +518,9 @@ if (sysmon->shutdown_irq != -ENODATA) { dev_err(sysmon->dev, "failed to retrieve shutdown-ack IRQ\n"); - return ERR_PTR(sysmon->shutdown_irq); + ret = sysmon->shutdown_irq; + kfree(sysmon); + return ERR_PTR(ret); } } else { ret = devm_request_threaded_irq(sysmon->dev, @@ -529,6 +531,7 @@ if (ret) { dev_err(sysmon->dev, "failed to acquire shutdown-ack IRQ\n"); + kfree(sysmon); return ERR_PTR(ret); } } --- linux-oracle-5.4.0.orig/drivers/remoteproc/qcom_wcnss.c +++ linux-oracle-5.4.0/drivers/remoteproc/qcom_wcnss.c @@ -407,6 +407,7 @@ irq_handler_t thread_fn) { int ret; + int irq_number; ret = platform_get_irq_byname(pdev, name); if (ret < 0 && optional) { @@ -417,14 +418,19 @@ return ret; } + irq_number = ret; + ret = devm_request_threaded_irq(&pdev->dev, ret, NULL, thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "wcnss", wcnss); - if (ret) + if (ret) { dev_err(&pdev->dev, "request %s IRQ failed\n", name); + return ret; + } - return ret; + /* Return the IRQ number if the IRQ was successfully acquired */ + return irq_number; } static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss) @@ -440,6 +446,7 @@ } ret = of_address_to_resource(node, 0, &r); + of_node_put(node); if (ret) return ret; --- linux-oracle-5.4.0.orig/drivers/remoteproc/remoteproc_core.c +++ linux-oracle-5.4.0/drivers/remoteproc/remoteproc_core.c @@ -400,7 +400,7 @@ void rproc_free_vring(struct rproc_vring *rvring) { struct rproc *rproc = rvring->rvdev->rproc; - int idx = rvring->rvdev->vring - rvring; + int idx = rvring - rvring->rvdev->vring; struct fw_rsc_vdev *rsc; idr_remove(&rproc->notifyids, rvring->notifyid); @@ -511,7 +511,7 @@ /* Initialise vdev subdevice */ snprintf(name, sizeof(name), "vdev%dbuffer", rvdev->index); - rvdev->dev.parent = rproc->dev.parent; + rvdev->dev.parent = &rproc->dev; rvdev->dev.dma_pfn_offset = rproc->dev.parent->dma_pfn_offset; rvdev->dev.release = rproc_rvdev_release; dev_set_name(&rvdev->dev, "%s#%s", dev_name(rvdev->dev.parent), name); @@ -2036,6 +2036,7 @@ rproc->dev.type = &rproc_type; rproc->dev.class = &rproc_class; rproc->dev.driver_data = rproc; + idr_init(&rproc->notifyids); /* Assign a unique device index and name */ rproc->index = ida_simple_get(&rproc_dev_index, 0, 0, GFP_KERNEL); @@ -2060,8 +2061,6 @@ mutex_init(&rproc->lock); - idr_init(&rproc->notifyids); - INIT_LIST_HEAD(&rproc->carveouts); INIT_LIST_HEAD(&rproc->mappings); INIT_LIST_HEAD(&rproc->traces); @@ -2224,7 +2223,7 @@ return 0; } -module_init(remoteproc_init); +subsys_initcall(remoteproc_init); static void __exit remoteproc_exit(void) { --- linux-oracle-5.4.0.orig/drivers/remoteproc/remoteproc_virtio.c +++ linux-oracle-5.4.0/drivers/remoteproc/remoteproc_virtio.c @@ -334,6 +334,13 @@ struct rproc_mem_entry *mem; int ret; + if (rproc->ops->kick == NULL) { + ret = -EINVAL; + dev_err(dev, ".kick method not defined for %s", + rproc->name); + goto out; + } + /* Try to find dedicated vdev buffer carveout */ mem = rproc_find_carveout_by_name(rproc, "vdev%dbuffer", rvdev->index); if (mem) { @@ -368,6 +375,18 @@ goto out; } } + } else { + struct device_node *np = rproc->dev.parent->of_node; + + /* + * If we don't have dedicated buffer, just attempt to re-assign + * the reserved memory from our parent. A default memory-region + * at index 0 from the parent's memory-regions is assigned for + * the rvdev dev to allocate from. Failure is non-critical and + * the allocations will fall back to global pools, so don't + * check return value either. + */ + of_reserved_mem_device_init_by_idx(dev, np, 0); } /* Allocate virtio device */ --- linux-oracle-5.4.0.orig/drivers/remoteproc/st_remoteproc.c +++ linux-oracle-5.4.0/drivers/remoteproc/st_remoteproc.c @@ -129,6 +129,7 @@ while (of_phandle_iterator_next(&it) == 0) { rmem = of_reserved_mem_lookup(it.node); if (!rmem) { + of_node_put(it.node); dev_err(dev, "unable to acquire memory-region\n"); return -EINVAL; } @@ -150,8 +151,10 @@ it.node->name); } - if (!mem) + if (!mem) { + of_node_put(it.node); return -ENOMEM; + } rproc_add_carveout(rproc, mem); index++; --- linux-oracle-5.4.0.orig/drivers/remoteproc/stm32_rproc.c +++ linux-oracle-5.4.0/drivers/remoteproc/stm32_rproc.c @@ -211,11 +211,13 @@ while (of_phandle_iterator_next(&it) == 0) { rmem = of_reserved_mem_lookup(it.node); if (!rmem) { + of_node_put(it.node); dev_err(dev, "unable to acquire memory-region\n"); return -EINVAL; } if (stm32_rproc_pa_to_da(rproc, rmem->base, &da) < 0) { + of_node_put(it.node); dev_err(dev, "memory region not valid %pa\n", &rmem->base); return -EINVAL; @@ -242,8 +244,10 @@ it.node->name); } - if (!mem) + if (!mem) { + of_node_put(it.node); return -ENOMEM; + } rproc_add_carveout(rproc, mem); index++; --- linux-oracle-5.4.0.orig/drivers/reset/core.c +++ linux-oracle-5.4.0/drivers/reset/core.c @@ -565,7 +565,10 @@ if (!rstc) return ERR_PTR(-ENOMEM); - try_module_get(rcdev->owner); + if (!try_module_get(rcdev->owner)) { + kfree(rstc); + return ERR_PTR(-ENODEV); + } rstc->rcdev = rcdev; list_add(&rstc->list, &rcdev->reset_control_head); @@ -594,6 +597,9 @@ { lockdep_assert_held(&reset_list_mutex); + if (IS_ERR_OR_NULL(rstc)) + return; + kref_put(&rstc->refcnt, __reset_control_release); } @@ -787,7 +793,7 @@ return ERR_PTR(-ENOMEM); rstc = __reset_control_get(dev, id, index, shared, optional, acquired); - if (!IS_ERR(rstc)) { + if (!IS_ERR_OR_NULL(rstc)) { *ptr = rstc; devres_add(dev, ptr); } else { @@ -861,8 +867,7 @@ * @acquired: only one reset control may be acquired for a given controller * and ID * - * Returns pointer to allocated reset_control_array on success or - * error on failure + * Returns pointer to allocated reset_control on success or error on failure */ struct reset_control * of_reset_control_array_get(struct device_node *np, bool shared, bool optional, @@ -915,8 +920,7 @@ * that just have to be asserted or deasserted, without any * requirements on the order. * - * Returns pointer to allocated reset_control_array on success or - * error on failure + * Returns pointer to allocated reset_control on success or error on failure */ struct reset_control * devm_reset_control_array_get(struct device *dev, bool shared, bool optional) @@ -930,7 +934,7 @@ return ERR_PTR(-ENOMEM); rstc = of_reset_control_array_get(dev->of_node, shared, optional, true); - if (IS_ERR(rstc)) { + if (IS_ERR_OR_NULL(rstc)) { devres_free(devres); return rstc; } --- linux-oracle-5.4.0.orig/drivers/reset/hisilicon/hi6220_reset.c +++ linux-oracle-5.4.0/drivers/reset/hisilicon/hi6220_reset.c @@ -33,6 +33,7 @@ enum hi6220_reset_ctrl_type { PERIPHERAL, MEDIA, + AO, }; struct hi6220_reset_data { @@ -92,6 +93,65 @@ .deassert = hi6220_media_deassert, }; +#define AO_SCTRL_SC_PW_CLKEN0 0x800 +#define AO_SCTRL_SC_PW_CLKDIS0 0x804 + +#define AO_SCTRL_SC_PW_RSTEN0 0x810 +#define AO_SCTRL_SC_PW_RSTDIS0 0x814 + +#define AO_SCTRL_SC_PW_ISOEN0 0x820 +#define AO_SCTRL_SC_PW_ISODIS0 0x824 +#define AO_MAX_INDEX 12 + +static int hi6220_ao_assert(struct reset_controller_dev *rc_dev, + unsigned long idx) +{ + struct hi6220_reset_data *data = to_reset_data(rc_dev); + struct regmap *regmap = data->regmap; + int ret; + + ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTEN0, BIT(idx)); + if (ret) + return ret; + + ret = regmap_write(regmap, AO_SCTRL_SC_PW_ISOEN0, BIT(idx)); + if (ret) + return ret; + + ret = regmap_write(regmap, AO_SCTRL_SC_PW_CLKDIS0, BIT(idx)); + return ret; +} + +static int hi6220_ao_deassert(struct reset_controller_dev *rc_dev, + unsigned long idx) +{ + struct hi6220_reset_data *data = to_reset_data(rc_dev); + struct regmap *regmap = data->regmap; + int ret; + + /* + * It was suggested to disable isolation before enabling + * the clocks and deasserting reset, to avoid glitches. + * But this order is preserved to keep it matching the + * vendor code. + */ + ret = regmap_write(regmap, AO_SCTRL_SC_PW_RSTDIS0, BIT(idx)); + if (ret) + return ret; + + ret = regmap_write(regmap, AO_SCTRL_SC_PW_ISODIS0, BIT(idx)); + if (ret) + return ret; + + ret = regmap_write(regmap, AO_SCTRL_SC_PW_CLKEN0, BIT(idx)); + return ret; +} + +static const struct reset_control_ops hi6220_ao_reset_ops = { + .assert = hi6220_ao_assert, + .deassert = hi6220_ao_deassert, +}; + static int hi6220_reset_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -104,7 +164,7 @@ if (!data) return -ENOMEM; - type = (enum hi6220_reset_ctrl_type)of_device_get_match_data(dev); + type = (uintptr_t)of_device_get_match_data(dev); regmap = syscon_node_to_regmap(np); if (IS_ERR(regmap)) { @@ -117,9 +177,12 @@ if (type == MEDIA) { data->rc_dev.ops = &hi6220_media_reset_ops; data->rc_dev.nr_resets = MEDIA_MAX_INDEX; - } else { + } else if (type == PERIPHERAL) { data->rc_dev.ops = &hi6220_peripheral_reset_ops; data->rc_dev.nr_resets = PERIPH_MAX_INDEX; + } else { + data->rc_dev.ops = &hi6220_ao_reset_ops; + data->rc_dev.nr_resets = AO_MAX_INDEX; } return reset_controller_register(&data->rc_dev); @@ -134,6 +197,10 @@ .compatible = "hisilicon,hi6220-mediactrl", .data = (void *)MEDIA, }, + { + .compatible = "hisilicon,hi6220-aoctrl", + .data = (void *)AO, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, hi6220_reset_match); --- linux-oracle-5.4.0.orig/drivers/reset/reset-a10sr.c +++ linux-oracle-5.4.0/drivers/reset/reset-a10sr.c @@ -118,6 +118,7 @@ .probe = a10sr_reset_probe, .driver = { .name = "altr_a10sr_reset", + .of_match_table = a10sr_reset_of_match, }, }; module_platform_driver(a10sr_reset_driver); --- linux-oracle-5.4.0.orig/drivers/reset/reset-berlin.c +++ linux-oracle-5.4.0/drivers/reset/reset-berlin.c @@ -68,13 +68,14 @@ static int berlin2_reset_probe(struct platform_device *pdev) { - struct device_node *parent_np = of_get_parent(pdev->dev.of_node); + struct device_node *parent_np; struct berlin_reset_priv *priv; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + parent_np = of_get_parent(pdev->dev.of_node); priv->regmap = syscon_node_to_regmap(parent_np); of_node_put(parent_np); if (IS_ERR(priv->regmap)) --- linux-oracle-5.4.0.orig/drivers/reset/reset-brcmstb.c +++ linux-oracle-5.4.0/drivers/reset/reset-brcmstb.c @@ -91,12 +91,6 @@ return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!IS_ALIGNED(res->start, SW_INIT_BANK_SIZE) || - !IS_ALIGNED(resource_size(res), SW_INIT_BANK_SIZE)) { - dev_err(kdev, "incorrect register range\n"); - return -EINVAL; - } - priv->base = devm_ioremap_resource(kdev, res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); @@ -117,6 +111,7 @@ { .compatible = "brcm,brcmstb-reset" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, brcmstb_reset_of_match); static struct platform_driver brcmstb_reset_driver = { .probe = brcmstb_reset_probe, --- linux-oracle-5.4.0.orig/drivers/reset/reset-socfpga.c +++ linux-oracle-5.4.0/drivers/reset/reset-socfpga.c @@ -86,3 +86,29 @@ for_each_matching_node(np, socfpga_early_reset_dt_ids) a10_reset_init(np); } + +/* + * The early driver is problematic, because it doesn't register + * itself as a driver. This causes certain device links to prevent + * consumer devices from probing. The hacky solution is to register + * an empty driver, whose only job is to attach itself to the reset + * manager and call probe. + */ +static const struct of_device_id socfpga_reset_dt_ids[] = { + { .compatible = "altr,rst-mgr", }, + { /* sentinel */ }, +}; + +static int reset_simple_probe(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver reset_socfpga_driver = { + .probe = reset_simple_probe, + .driver = { + .name = "socfpga-reset", + .of_match_table = socfpga_reset_dt_ids, + }, +}; +builtin_platform_driver(reset_socfpga_driver); --- linux-oracle-5.4.0.orig/drivers/reset/reset-ti-sci.c +++ linux-oracle-5.4.0/drivers/reset/reset-ti-sci.c @@ -1,7 +1,7 @@ /* * Texas Instrument's System Control Interface (TI-SCI) reset driver * - * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/ * Andrew F. Davis * * This program is free software; you can redistribute it and/or modify --- linux-oracle-5.4.0.orig/drivers/reset/reset-ti-syscon.c +++ linux-oracle-5.4.0/drivers/reset/reset-ti-syscon.c @@ -58,8 +58,8 @@ unsigned int nr_controls; }; -#define to_ti_syscon_reset_data(rcdev) \ - container_of(rcdev, struct ti_syscon_reset_data, rcdev) +#define to_ti_syscon_reset_data(_rcdev) \ + container_of(_rcdev, struct ti_syscon_reset_data, rcdev) /** * ti_syscon_reset_assert() - assert device reset --- linux-oracle-5.4.0.orig/drivers/reset/reset-uniphier.c +++ linux-oracle-5.4.0/drivers/reset/reset-uniphier.c @@ -193,8 +193,8 @@ #define UNIPHIER_PERI_RESET_FI2C(id, ch) \ UNIPHIER_RESETX((id), 0x114, 24 + (ch)) -#define UNIPHIER_PERI_RESET_SCSSI(id) \ - UNIPHIER_RESETX((id), 0x110, 17) +#define UNIPHIER_PERI_RESET_SCSSI(id, ch) \ + UNIPHIER_RESETX((id), 0x110, 17 + (ch)) #define UNIPHIER_PERI_RESET_MCSSI(id) \ UNIPHIER_RESETX((id), 0x114, 14) @@ -209,7 +209,7 @@ UNIPHIER_PERI_RESET_I2C(6, 2), UNIPHIER_PERI_RESET_I2C(7, 3), UNIPHIER_PERI_RESET_I2C(8, 4), - UNIPHIER_PERI_RESET_SCSSI(11), + UNIPHIER_PERI_RESET_SCSSI(11, 0), UNIPHIER_RESET_END, }; @@ -225,8 +225,11 @@ UNIPHIER_PERI_RESET_FI2C(8, 4), UNIPHIER_PERI_RESET_FI2C(9, 5), UNIPHIER_PERI_RESET_FI2C(10, 6), - UNIPHIER_PERI_RESET_SCSSI(11), - UNIPHIER_PERI_RESET_MCSSI(12), + UNIPHIER_PERI_RESET_SCSSI(11, 0), + UNIPHIER_PERI_RESET_SCSSI(12, 1), + UNIPHIER_PERI_RESET_SCSSI(13, 2), + UNIPHIER_PERI_RESET_SCSSI(14, 3), + UNIPHIER_PERI_RESET_MCSSI(15), UNIPHIER_RESET_END, }; --- linux-oracle-5.4.0.orig/drivers/reset/reset-zynqmp.c +++ linux-oracle-5.4.0/drivers/reset/reset-zynqmp.c @@ -46,7 +46,8 @@ unsigned long id) { struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev); - int val, err; + int err; + u32 val; err = priv->eemi_ops->reset_get_status(ZYNQMP_RESET_ID + id, &val); if (err) --- linux-oracle-5.4.0.orig/drivers/reset/tegra/reset-bpmp.c +++ linux-oracle-5.4.0/drivers/reset/tegra/reset-bpmp.c @@ -20,6 +20,7 @@ struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc); struct mrq_reset_request request; struct tegra_bpmp_message msg; + int err; memset(&request, 0, sizeof(request)); request.cmd = command; @@ -30,7 +31,13 @@ msg.tx.data = &request; msg.tx.size = sizeof(request); - return tegra_bpmp_transfer(bpmp, &msg); + err = tegra_bpmp_transfer(bpmp, &msg); + if (err) + return err; + if (msg.rx.ret) + return -EINVAL; + + return 0; } static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc, --- linux-oracle-5.4.0.orig/drivers/rpmsg/qcom_glink_native.c +++ linux-oracle-5.4.0/drivers/rpmsg/qcom_glink_native.c @@ -92,6 +92,8 @@ * @rcids: idr of all channels with a known remote channel id * @features: remote features * @intentless: flag to indicate that there is no intent + * @tx_avail_notify: Waitqueue for pending tx tasks + * @sent_read_notify: flag to check cmd sent or not */ struct qcom_glink { struct device *dev; @@ -118,6 +120,8 @@ unsigned long features; bool intentless; + wait_queue_head_t tx_avail_notify; + bool sent_read_notify; }; enum { @@ -187,20 +191,20 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops; -#define RPM_CMD_VERSION 0 -#define RPM_CMD_VERSION_ACK 1 -#define RPM_CMD_OPEN 2 -#define RPM_CMD_CLOSE 3 -#define RPM_CMD_OPEN_ACK 4 -#define RPM_CMD_INTENT 5 -#define RPM_CMD_RX_DONE 6 -#define RPM_CMD_RX_INTENT_REQ 7 -#define RPM_CMD_RX_INTENT_REQ_ACK 8 -#define RPM_CMD_TX_DATA 9 -#define RPM_CMD_CLOSE_ACK 11 -#define RPM_CMD_TX_DATA_CONT 12 -#define RPM_CMD_READ_NOTIF 13 -#define RPM_CMD_RX_DONE_W_REUSE 14 +#define GLINK_CMD_VERSION 0 +#define GLINK_CMD_VERSION_ACK 1 +#define GLINK_CMD_OPEN 2 +#define GLINK_CMD_CLOSE 3 +#define GLINK_CMD_OPEN_ACK 4 +#define GLINK_CMD_INTENT 5 +#define GLINK_CMD_RX_DONE 6 +#define GLINK_CMD_RX_INTENT_REQ 7 +#define GLINK_CMD_RX_INTENT_REQ_ACK 8 +#define GLINK_CMD_TX_DATA 9 +#define GLINK_CMD_CLOSE_ACK 11 +#define GLINK_CMD_TX_DATA_CONT 12 +#define GLINK_CMD_READ_NOTIF 13 +#define GLINK_CMD_RX_DONE_W_REUSE 14 #define GLINK_FEATURE_INTENTLESS BIT(1) @@ -222,6 +226,10 @@ channel->glink = glink; channel->name = kstrdup(name, GFP_KERNEL); + if (!channel->name) { + kfree(channel); + return ERR_PTR(-ENOMEM); + } init_completion(&channel->open_req); init_completion(&channel->open_ack); @@ -241,10 +249,31 @@ { struct glink_channel *channel = container_of(ref, struct glink_channel, refcount); + struct glink_core_rx_intent *intent; + struct glink_core_rx_intent *tmp; unsigned long flags; + int iid; + + /* cancel pending rx_done work */ + cancel_work_sync(&channel->intent_work); spin_lock_irqsave(&channel->intent_lock, flags); + /* Free all non-reuse intents pending rx_done work */ + list_for_each_entry_safe(intent, tmp, &channel->done_intents, node) { + if (!intent->reuse) { + kfree(intent->data); + kfree(intent); + } + } + + idr_for_each_entry(&channel->liids, tmp, iid) { + kfree(tmp->data); + kfree(tmp); + } idr_destroy(&channel->liids); + + idr_for_each_entry(&channel->riids, tmp, iid) + kfree(tmp); idr_destroy(&channel->riids); spin_unlock_irqrestore(&channel->intent_lock, flags); @@ -280,6 +309,20 @@ glink->tx_pipe->write(glink->tx_pipe, hdr, hlen, data, dlen); } +static void qcom_glink_send_read_notify(struct qcom_glink *glink) +{ + struct glink_msg msg; + + msg.cmd = cpu_to_le16(GLINK_CMD_READ_NOTIF); + msg.param1 = 0; + msg.param2 = 0; + + qcom_glink_tx_write(glink, &msg, sizeof(msg), NULL, 0); + + mbox_send_message(glink->mbox_chan, NULL); + mbox_client_txdone(glink->mbox_chan, 0); +} + static int qcom_glink_tx(struct qcom_glink *glink, const void *hdr, size_t hlen, const void *data, size_t dlen, bool wait) @@ -300,12 +343,21 @@ goto out; } + if (!glink->sent_read_notify) { + glink->sent_read_notify = true; + qcom_glink_send_read_notify(glink); + } + /* Wait without holding the tx_lock */ spin_unlock_irqrestore(&glink->tx_lock, flags); - usleep_range(10000, 15000); + wait_event_timeout(glink->tx_avail_notify, + qcom_glink_tx_avail(glink) >= tlen, 10 * HZ); spin_lock_irqsave(&glink->tx_lock, flags); + + if (qcom_glink_tx_avail(glink) >= tlen) + glink->sent_read_notify = false; } qcom_glink_tx_write(glink, hdr, hlen, data, dlen); @@ -323,7 +375,7 @@ { struct glink_msg msg; - msg.cmd = cpu_to_le16(RPM_CMD_VERSION); + msg.cmd = cpu_to_le16(GLINK_CMD_VERSION); msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); @@ -334,7 +386,7 @@ { struct glink_msg msg; - msg.cmd = cpu_to_le16(RPM_CMD_VERSION_ACK); + msg.cmd = cpu_to_le16(GLINK_CMD_VERSION_ACK); msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); @@ -346,7 +398,7 @@ { struct glink_msg msg; - msg.cmd = cpu_to_le16(RPM_CMD_OPEN_ACK); + msg.cmd = cpu_to_le16(GLINK_CMD_OPEN_ACK); msg.param1 = cpu_to_le16(channel->rcid); msg.param2 = cpu_to_le32(0); @@ -372,11 +424,11 @@ } /** - * qcom_glink_send_open_req() - send a RPM_CMD_OPEN request to the remote + * qcom_glink_send_open_req() - send a GLINK_CMD_OPEN request to the remote * @glink: Ptr to the glink edge * @channel: Ptr to the channel that the open req is sent * - * Allocates a local channel id and sends a RPM_CMD_OPEN message to the remote. + * Allocates a local channel id and sends a GLINK_CMD_OPEN message to the remote. * Will return with refcount held, regardless of outcome. * * Returns 0 on success, negative errno otherwise. @@ -405,7 +457,7 @@ channel->lcid = ret; - req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN); + req.msg.cmd = cpu_to_le16(GLINK_CMD_OPEN); req.msg.param1 = cpu_to_le16(channel->lcid); req.msg.param2 = cpu_to_le32(name_len); strcpy(req.name, channel->name); @@ -430,7 +482,7 @@ { struct glink_msg req; - req.cmd = cpu_to_le16(RPM_CMD_CLOSE); + req.cmd = cpu_to_le16(GLINK_CMD_CLOSE); req.param1 = cpu_to_le16(channel->lcid); req.param2 = 0; @@ -442,7 +494,7 @@ { struct glink_msg req; - req.cmd = cpu_to_le16(RPM_CMD_CLOSE_ACK); + req.cmd = cpu_to_le16(GLINK_CMD_CLOSE_ACK); req.param1 = cpu_to_le16(rcid); req.param2 = 0; @@ -473,7 +525,7 @@ iid = intent->id; reuse = intent->reuse; - cmd.id = reuse ? RPM_CMD_RX_DONE_W_REUSE : RPM_CMD_RX_DONE; + cmd.id = reuse ? GLINK_CMD_RX_DONE_W_REUSE : GLINK_CMD_RX_DONE; cmd.lcid = cid; cmd.liid = iid; @@ -585,7 +637,7 @@ { struct glink_msg msg; - msg.cmd = cpu_to_le16(RPM_CMD_RX_INTENT_REQ_ACK); + msg.cmd = cpu_to_le16(GLINK_CMD_RX_INTENT_REQ_ACK); msg.param1 = cpu_to_le16(channel->lcid); msg.param2 = cpu_to_le32(granted); @@ -616,7 +668,7 @@ } __packed; struct command cmd; - cmd.id = cpu_to_le16(RPM_CMD_INTENT); + cmd.id = cpu_to_le16(GLINK_CMD_INTENT); cmd.lcid = cpu_to_le16(channel->lcid); cmd.count = cpu_to_le32(1); cmd.size = cpu_to_le32(intent->size); @@ -836,6 +888,7 @@ dev_err(glink->dev, "no intent found for channel %s intent %d", channel->name, liid); + ret = -ENOENT; goto advance_rx; } } @@ -907,6 +960,7 @@ spin_unlock_irqrestore(&glink->idr_lock, flags); if (!channel) { dev_err(glink->dev, "intents for non-existing channel\n"); + qcom_glink_rx_advance(glink, ALIGN(msglen, 8)); return; } @@ -949,7 +1003,7 @@ return -EINVAL; } - complete(&channel->open_ack); + complete_all(&channel->open_ack); return 0; } @@ -964,6 +1018,9 @@ unsigned int cmd; int ret = 0; + /* To wakeup any blocking writers */ + wake_up_all(&glink->tx_avail_notify); + for (;;) { avail = qcom_glink_rx_avail(glink); if (avail < sizeof(msg)) @@ -976,42 +1033,43 @@ param2 = le32_to_cpu(msg.param2); switch (cmd) { - case RPM_CMD_VERSION: - case RPM_CMD_VERSION_ACK: - case RPM_CMD_CLOSE: - case RPM_CMD_CLOSE_ACK: - case RPM_CMD_RX_INTENT_REQ: + case GLINK_CMD_VERSION: + case GLINK_CMD_VERSION_ACK: + case GLINK_CMD_CLOSE: + case GLINK_CMD_CLOSE_ACK: + case GLINK_CMD_RX_INTENT_REQ: ret = qcom_glink_rx_defer(glink, 0); break; - case RPM_CMD_OPEN_ACK: + case GLINK_CMD_OPEN_ACK: ret = qcom_glink_rx_open_ack(glink, param1); qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); break; - case RPM_CMD_OPEN: - ret = qcom_glink_rx_defer(glink, param2); + case GLINK_CMD_OPEN: + /* upper 16 bits of param2 are the "prio" field */ + ret = qcom_glink_rx_defer(glink, param2 & 0xffff); break; - case RPM_CMD_TX_DATA: - case RPM_CMD_TX_DATA_CONT: + case GLINK_CMD_TX_DATA: + case GLINK_CMD_TX_DATA_CONT: ret = qcom_glink_rx_data(glink, avail); break; - case RPM_CMD_READ_NOTIF: + case GLINK_CMD_READ_NOTIF: qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); mbox_send_message(glink->mbox_chan, NULL); mbox_client_txdone(glink->mbox_chan, 0); break; - case RPM_CMD_INTENT: + case GLINK_CMD_INTENT: qcom_glink_handle_intent(glink, param1, param2, avail); break; - case RPM_CMD_RX_DONE: + case GLINK_CMD_RX_DONE: qcom_glink_handle_rx_done(glink, param1, param2, false); qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); break; - case RPM_CMD_RX_DONE_W_REUSE: + case GLINK_CMD_RX_DONE_W_REUSE: qcom_glink_handle_rx_done(glink, param1, param2, true); qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); break; - case RPM_CMD_RX_INTENT_REQ_ACK: + case GLINK_CMD_RX_INTENT_REQ_ACK: qcom_glink_handle_intent_req_ack(glink, param1, param2); qcom_glink_rx_advance(glink, ALIGN(sizeof(msg), 8)); break; @@ -1094,13 +1152,12 @@ close_link: /* * Send a close request to "undo" our open-ack. The close-ack will - * release the last reference. + * release qcom_glink_send_open_req() reference and the last reference + * will be relesed after receiving remote_close or transport unregister + * by calling qcom_glink_native_remove(). */ qcom_glink_send_close_req(glink, channel); - /* Release qcom_glink_send_open_req() reference */ - kref_put(&channel->refcount, qcom_glink_channel_release); - return ret; } @@ -1158,7 +1215,7 @@ __be32 *val = defaults; int size; - if (glink->intentless) + if (glink->intentless || !completion_done(&channel->open_ack)) return 0; prop = of_find_property(np, "qcom,intents", NULL); @@ -1215,7 +1272,7 @@ reinit_completion(&channel->intent_req_comp); - cmd.id = RPM_CMD_RX_INTENT_REQ; + cmd.id = GLINK_CMD_RX_INTENT_REQ; cmd.cid = channel->lcid; cmd.size = size; @@ -1250,6 +1307,8 @@ } __packed req; int ret; unsigned long flags; + int chunk_size = len; + int left_size = 0; if (!glink->intentless) { while (!intent) { @@ -1283,18 +1342,48 @@ iid = intent->id; } - req.msg.cmd = cpu_to_le16(RPM_CMD_TX_DATA); + if (wait && chunk_size > SZ_8K) { + chunk_size = SZ_8K; + left_size = len - chunk_size; + } + req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA); req.msg.param1 = cpu_to_le16(channel->lcid); req.msg.param2 = cpu_to_le32(iid); - req.chunk_size = cpu_to_le32(len); - req.left_size = cpu_to_le32(0); + req.chunk_size = cpu_to_le32(chunk_size); + req.left_size = cpu_to_le32(left_size); - ret = qcom_glink_tx(glink, &req, sizeof(req), data, len, wait); + ret = qcom_glink_tx(glink, &req, sizeof(req), data, chunk_size, wait); /* Mark intent available if we failed */ - if (ret && intent) - intent->in_use = false; + if (ret) { + if (intent) + intent->in_use = false; + return ret; + } + + while (left_size > 0) { + data = (void *)((char *)data + chunk_size); + chunk_size = left_size; + if (chunk_size > SZ_8K) + chunk_size = SZ_8K; + left_size -= chunk_size; + + req.msg.cmd = cpu_to_le16(GLINK_CMD_TX_DATA_CONT); + req.msg.param1 = cpu_to_le16(channel->lcid); + req.msg.param2 = cpu_to_le32(iid); + req.chunk_size = cpu_to_le32(chunk_size); + req.left_size = cpu_to_le32(left_size); + + ret = qcom_glink_tx(glink, &req, sizeof(req), data, + chunk_size, wait); + /* Mark intent available if we failed */ + if (ret) { + if (intent) + intent->in_use = false; + break; + } + } return ret; } @@ -1353,6 +1442,7 @@ struct glink_channel *channel = to_glink_channel(rpdev->ept); channel->rpdev = NULL; + kfree(rpdev->driver_override); kfree(rpdev); } @@ -1393,7 +1483,7 @@ channel->rcid = ret; spin_unlock_irqrestore(&glink->idr_lock, flags); - complete(&channel->open_req); + complete_all(&channel->open_req); if (create_device) { rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); @@ -1415,15 +1505,13 @@ ret = rpmsg_register_device(rpdev); if (ret) - goto free_rpdev; + goto rcid_remove; channel->rpdev = rpdev; } return 0; -free_rpdev: - kfree(rpdev); rcid_remove: spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->rcids, channel->rcid); @@ -1453,7 +1541,7 @@ cancel_work_sync(&channel->intent_work); if (channel->rpdev) { - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); chinfo.src = RPMSG_ADDR_ANY; chinfo.dst = RPMSG_ADDR_ANY; @@ -1475,6 +1563,9 @@ struct glink_channel *channel; unsigned long flags; + /* To wakeup any blocking writers */ + wake_up_all(&glink->tx_avail_notify); + spin_lock_irqsave(&glink->idr_lock, flags); channel = idr_find(&glink->lcids, lcid); if (WARN(!channel, "close ack on unknown channel\n")) { @@ -1517,22 +1608,22 @@ param2 = le32_to_cpu(msg->param2); switch (cmd) { - case RPM_CMD_VERSION: + case GLINK_CMD_VERSION: qcom_glink_receive_version(glink, param1, param2); break; - case RPM_CMD_VERSION_ACK: + case GLINK_CMD_VERSION_ACK: qcom_glink_receive_version_ack(glink, param1, param2); break; - case RPM_CMD_OPEN: + case GLINK_CMD_OPEN: qcom_glink_rx_open(glink, param1, msg->data); break; - case RPM_CMD_CLOSE: + case GLINK_CMD_CLOSE: qcom_glink_rx_close(glink, param1); break; - case RPM_CMD_CLOSE_ACK: + case GLINK_CMD_CLOSE_ACK: qcom_glink_rx_close_ack(glink, param1); break; - case RPM_CMD_RX_INTENT_REQ: + case GLINK_CMD_RX_INTENT_REQ: qcom_glink_handle_intent_req(glink, param1, param2); break; default: @@ -1544,6 +1635,18 @@ } } +static void qcom_glink_cancel_rx_work(struct qcom_glink *glink) +{ + struct glink_defer_cmd *dcmd; + struct glink_defer_cmd *tmp; + + /* cancel any pending deferred rx_work */ + cancel_work_sync(&glink->rx_work); + + list_for_each_entry_safe(dcmd, tmp, &glink->rx_queue, node) + kfree(dcmd); +} + struct qcom_glink *qcom_glink_native_probe(struct device *dev, unsigned long features, struct qcom_glink_pipe *rx, @@ -1569,6 +1672,7 @@ spin_lock_init(&glink->rx_lock); INIT_LIST_HEAD(&glink->rx_queue); INIT_WORK(&glink->rx_work, qcom_glink_work); + init_waitqueue_head(&glink->tx_avail_notify); spin_lock_init(&glink->idr_lock); idr_init(&glink->lcids); @@ -1619,23 +1723,24 @@ struct glink_channel *channel; int cid; int ret; - unsigned long flags; disable_irq(glink->irq); - cancel_work_sync(&glink->rx_work); + qcom_glink_cancel_rx_work(glink); ret = device_for_each_child(glink->dev, NULL, qcom_glink_remove_device); if (ret) dev_warn(glink->dev, "Can't remove GLINK devices: %d\n", ret); - spin_lock_irqsave(&glink->idr_lock, flags); /* Release any defunct local channels, waiting for close-ack */ idr_for_each_entry(&glink->lcids, channel, cid) kref_put(&channel->refcount, qcom_glink_channel_release); + /* Release any defunct local channels, waiting for close-req */ + idr_for_each_entry(&glink->rcids, channel, cid) + kref_put(&channel->refcount, qcom_glink_channel_release); + idr_destroy(&glink->lcids); idr_destroy(&glink->rcids); - spin_unlock_irqrestore(&glink->idr_lock, flags); mbox_free_channel(glink->mbox_chan); } EXPORT_SYMBOL_GPL(qcom_glink_native_remove); --- linux-oracle-5.4.0.orig/drivers/rpmsg/qcom_glink_smem.c +++ linux-oracle-5.4.0/drivers/rpmsg/qcom_glink_smem.c @@ -105,7 +105,7 @@ tail = le32_to_cpu(*pipe->tail); tail += count; - if (tail > pipe->native.length) + if (tail >= pipe->native.length) tail -= pipe->native.length; *pipe->tail = cpu_to_le32(tail); --- linux-oracle-5.4.0.orig/drivers/rpmsg/qcom_smd.c +++ linux-oracle-5.4.0/drivers/rpmsg/qcom_smd.c @@ -1073,7 +1073,7 @@ /* Assign public information to the rpmsg_device */ rpdev = &qsdev->rpdev; - strncpy(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); + strscpy_pad(rpdev->id.name, channel->name, RPMSG_NAME_SIZE); rpdev->src = RPMSG_ADDR_ANY; rpdev->dst = RPMSG_ADDR_ANY; @@ -1304,7 +1304,7 @@ spin_unlock_irqrestore(&edge->channels_lock, flags); - strncpy(chinfo.name, channel->name, sizeof(chinfo.name)); + strscpy_pad(chinfo.name, channel->name, sizeof(chinfo.name)); chinfo.src = RPMSG_ADDR_ANY; chinfo.dst = RPMSG_ADDR_ANY; rpmsg_unregister_device(&edge->dev, &chinfo); @@ -1338,7 +1338,7 @@ ret = of_property_read_u32(node, key, &edge->edge_id); if (ret) { dev_err(dev, "edge missing %s property\n", key); - return -EINVAL; + goto put_node; } edge->remote_pid = QCOM_SMEM_HOST_ANY; @@ -1349,32 +1349,38 @@ edge->mbox_client.knows_txdone = true; edge->mbox_chan = mbox_request_channel(&edge->mbox_client, 0); if (IS_ERR(edge->mbox_chan)) { - if (PTR_ERR(edge->mbox_chan) != -ENODEV) - return PTR_ERR(edge->mbox_chan); + if (PTR_ERR(edge->mbox_chan) != -ENODEV) { + ret = PTR_ERR(edge->mbox_chan); + goto put_node; + } edge->mbox_chan = NULL; syscon_np = of_parse_phandle(node, "qcom,ipc", 0); if (!syscon_np) { dev_err(dev, "no qcom,ipc node\n"); - return -ENODEV; + ret = -ENODEV; + goto put_node; } edge->ipc_regmap = syscon_node_to_regmap(syscon_np); - if (IS_ERR(edge->ipc_regmap)) - return PTR_ERR(edge->ipc_regmap); + of_node_put(syscon_np); + if (IS_ERR(edge->ipc_regmap)) { + ret = PTR_ERR(edge->ipc_regmap); + goto put_node; + } key = "qcom,ipc"; ret = of_property_read_u32_index(node, key, 1, &edge->ipc_offset); if (ret < 0) { dev_err(dev, "no offset in %s\n", key); - return -EINVAL; + goto put_node; } ret = of_property_read_u32_index(node, key, 2, &edge->ipc_bit); if (ret < 0) { dev_err(dev, "no bit in %s\n", key); - return -EINVAL; + goto put_node; } } @@ -1383,9 +1389,10 @@ edge->name = node->name; irq = irq_of_parse_and_map(node, 0); - if (irq < 0) { + if (!irq) { dev_err(dev, "required smd interrupt missing\n"); - return -EINVAL; + ret = -EINVAL; + goto put_node; } ret = devm_request_irq(dev, irq, @@ -1393,12 +1400,18 @@ node->name, edge); if (ret) { dev_err(dev, "failed to request smd irq\n"); - return ret; + goto put_node; } edge->irq = irq; return 0; + +put_node: + of_node_put(node); + edge->of_node = NULL; + + return ret; } /* --- linux-oracle-5.4.0.orig/drivers/rpmsg/rpmsg_char.c +++ linux-oracle-5.4.0/drivers/rpmsg/rpmsg_char.c @@ -92,7 +92,7 @@ /* wake up any blocked readers */ wake_up_interruptible(&eptdev->readq); - device_del(&eptdev->dev); + cdev_device_del(&eptdev->cdev, &eptdev->dev); put_device(&eptdev->dev); return 0; @@ -227,8 +227,10 @@ if (!kbuf) return -ENOMEM; - if (!copy_from_iter_full(kbuf, len, from)) - return -EFAULT; + if (!copy_from_iter_full(kbuf, len, from)) { + ret = -EFAULT; + goto free_kbuf; + } if (mutex_lock_interruptible(&eptdev->ept_lock)) { ret = -ERESTARTSYS; @@ -334,7 +336,6 @@ ida_simple_remove(&rpmsg_ept_ida, dev->id); ida_simple_remove(&rpmsg_minor_ida, MINOR(eptdev->dev.devt)); - cdev_del(&eptdev->cdev); kfree(eptdev); } @@ -379,19 +380,13 @@ dev->id = ret; dev_set_name(dev, "rpmsg%d", ret); - ret = cdev_add(&eptdev->cdev, dev->devt, 1); + ret = cdev_device_add(&eptdev->cdev, &eptdev->dev); if (ret) goto free_ept_ida; /* We can now rely on the release function for cleanup */ dev->release = rpmsg_eptdev_release_device; - ret = device_add(dev); - if (ret) { - dev_err(dev, "device_add failed: %d\n", ret); - put_device(dev); - } - return ret; free_ept_ida: @@ -460,7 +455,6 @@ ida_simple_remove(&rpmsg_ctrl_ida, dev->id); ida_simple_remove(&rpmsg_minor_ida, MINOR(dev->devt)); - cdev_del(&ctrldev->cdev); kfree(ctrldev); } @@ -495,19 +489,13 @@ dev->id = ret; dev_set_name(&ctrldev->dev, "rpmsg_ctrl%d", ret); - ret = cdev_add(&ctrldev->cdev, dev->devt, 1); + ret = cdev_device_add(&ctrldev->cdev, &ctrldev->dev); if (ret) goto free_ctrl_ida; /* We can now rely on the release function for cleanup */ dev->release = rpmsg_ctrldev_release_device; - ret = device_add(dev); - if (ret) { - dev_err(&rpdev->dev, "device_add failed: %d\n", ret); - put_device(dev); - } - dev_set_drvdata(&rpdev->dev, ctrldev); return ret; @@ -533,7 +521,7 @@ if (ret) dev_warn(&rpdev->dev, "failed to nuke endpoints: %d\n", ret); - device_del(&ctrldev->dev); + cdev_device_del(&ctrldev->cdev, &ctrldev->dev); put_device(&ctrldev->dev); } --- linux-oracle-5.4.0.orig/drivers/rpmsg/rpmsg_core.c +++ linux-oracle-5.4.0/drivers/rpmsg/rpmsg_core.c @@ -332,7 +332,8 @@ const char *buf, size_t sz) \ { \ struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ - char *new, *old; \ + const char *old; \ + char *new; \ \ new = kstrndup(buf, sz, GFP_KERNEL); \ if (!new) \ @@ -473,13 +474,25 @@ err = rpdrv->probe(rpdev); if (err) { dev_err(dev, "%s: failed: %d\n", __func__, err); - if (ept) - rpmsg_destroy_ept(ept); - goto out; + goto destroy_ept; } - if (ept && rpdev->ops->announce_create) + if (ept && rpdev->ops->announce_create) { err = rpdev->ops->announce_create(rpdev); + if (err) { + dev_err(dev, "failed to announce creation\n"); + goto remove_rpdev; + } + } + + return 0; + +remove_rpdev: + if (rpdrv->remove) + rpdrv->remove(rpdev); +destroy_ept: + if (ept) + rpmsg_destroy_ept(ept); out: return err; } @@ -513,24 +526,52 @@ .remove = rpmsg_dev_remove, }; -int rpmsg_register_device(struct rpmsg_device *rpdev) +/* + * A helper for registering rpmsg device with driver override and name. + * Drivers should not be using it, but instead rpmsg_register_device(). + */ +int rpmsg_register_device_override(struct rpmsg_device *rpdev, + const char *driver_override) { struct device *dev = &rpdev->dev; int ret; + if (driver_override) + strcpy(rpdev->id.name, driver_override); + dev_set_name(&rpdev->dev, "%s.%s.%d.%d", dev_name(dev->parent), rpdev->id.name, rpdev->src, rpdev->dst); rpdev->dev.bus = &rpmsg_bus; - ret = device_register(&rpdev->dev); + device_initialize(dev); + if (driver_override) { + ret = driver_set_override(dev, &rpdev->driver_override, + driver_override, + strlen(driver_override)); + if (ret) { + dev_err(dev, "device_set_override failed: %d\n", ret); + put_device(dev); + return ret; + } + } + + ret = device_add(dev); if (ret) { - dev_err(dev, "device_register failed: %d\n", ret); + dev_err(dev, "device_add failed: %d\n", ret); + kfree(rpdev->driver_override); + rpdev->driver_override = NULL; put_device(&rpdev->dev); } return ret; } +EXPORT_SYMBOL(rpmsg_register_device_override); + +int rpmsg_register_device(struct rpmsg_device *rpdev) +{ + return rpmsg_register_device_override(rpdev, NULL); +} EXPORT_SYMBOL(rpmsg_register_device); /* --- linux-oracle-5.4.0.orig/drivers/rpmsg/rpmsg_internal.h +++ linux-oracle-5.4.0/drivers/rpmsg/rpmsg_internal.h @@ -84,10 +84,7 @@ */ static inline int rpmsg_chrdev_register_device(struct rpmsg_device *rpdev) { - strcpy(rpdev->id.name, "rpmsg_chrdev"); - rpdev->driver_override = "rpmsg_chrdev"; - - return rpmsg_register_device(rpdev); + return rpmsg_register_device_override(rpdev, "rpmsg_ctrl"); } #endif --- linux-oracle-5.4.0.orig/drivers/rpmsg/virtio_rpmsg_bus.c +++ linux-oracle-5.4.0/drivers/rpmsg/virtio_rpmsg_bus.c @@ -381,6 +381,7 @@ struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev); + kfree(rpdev->driver_override); kfree(vch); } --- linux-oracle-5.4.0.orig/drivers/rtc/Kconfig +++ linux-oracle-5.4.0/drivers/rtc/Kconfig @@ -217,6 +217,15 @@ This driver can also be built as a module. If so, the module will be called rtc-ac100. +config RTC_DRV_AM1805 + tristate "Ambiq micro AM1805 RTC driver" + help + If you say yes here you get support for Ambiq micro AM1805 RTC + chip. + + This driver can also be built as a module. If so, the module + will be called rtc-am1805. + config RTC_DRV_BRCMSTB tristate "Broadcom STB wake-timer" depends on ARCH_BRCMSTB || BMIPS_GENERIC || COMPILE_TEST @@ -240,6 +249,7 @@ config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057" + select REGMAP_I2C help If you say yes here you get support for various compatible RTC chips (often with battery backup) connected with I2C. This driver @@ -326,6 +336,7 @@ config RTC_DRV_MAX8907 tristate "Maxim MAX8907" depends on MFD_MAX8907 || COMPILE_TEST + select REGMAP_IRQ help If you say yes here you will get support for the RTC of Maxim MAX8907 PMIC. @@ -623,6 +634,7 @@ config RTC_DRV_RX8010 tristate "Epson RX8010SJ" + select REGMAP_I2C help If you say yes here you get support for the Epson RX8010SJ RTC chip. @@ -632,6 +644,7 @@ config RTC_DRV_RX8581 tristate "Epson RX-8571/RX-8581" + select REGMAP_I2C help If you say yes here you will get support for the Epson RX-8571/ RX-8581. @@ -659,6 +672,7 @@ config RTC_DRV_RV3028 tristate "Micro Crystal RV3028" + select REGMAP_I2C help If you say yes here you get support for the Micro Crystal RV3028. @@ -679,6 +693,7 @@ tristate "Samsung S2M/S5M series" depends on MFD_SEC_CORE || COMPILE_TEST select REGMAP_IRQ + select REGMAP_I2C help If you say yes here you will get support for the RTC of Samsung S2MPS14 and S5M PMIC series. @@ -688,6 +703,7 @@ config RTC_DRV_SD3078 tristate "ZXW Shenzhen whwave SD3078" + select REGMAP_I2C help If you say yes here you get support for the ZXW Shenzhen whwave SD3078 RTC chips. @@ -859,14 +875,14 @@ default m if I2C=m default y if I2C=y default y if SPI_MASTER=y - select REGMAP_I2C if I2C - select REGMAP_SPI if SPI_MASTER comment "SPI and I2C RTC drivers" config RTC_DRV_DS3232 tristate "Dallas/Maxim DS3232/DS3234" depends on RTC_I2C_AND_SPI + select REGMAP_I2C if I2C + select REGMAP_SPI if SPI_MASTER help If you say yes here you get support for Dallas Semiconductor DS3232 and DS3234 real-time clock chips. If an interrupt is associated @@ -886,6 +902,8 @@ config RTC_DRV_PCF2127 tristate "NXP PCF2127" depends on RTC_I2C_AND_SPI + select REGMAP_I2C if I2C + select REGMAP_SPI if SPI_MASTER select WATCHDOG_CORE if WATCHDOG help If you say yes here you get support for the NXP PCF2127/29 RTC @@ -902,6 +920,8 @@ config RTC_DRV_RV3029C2 tristate "Micro Crystal RV3029/3049" depends on RTC_I2C_AND_SPI + select REGMAP_I2C if I2C + select REGMAP_SPI if SPI_MASTER help If you say yes here you get support for the Micro Crystal RV3029 and RV3049 RTC chips. @@ -1800,7 +1820,8 @@ config RTC_DRV_MT6397 tristate "MediaTek PMIC based RTC" - depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN) + depends on MFD_MT6397 || COMPILE_TEST + select IRQ_DOMAIN help This selects the MediaTek(R) RTC driver. RTC is part of MediaTek MT6397 PMIC. You should enable MT6397 PMIC MFD before select --- linux-oracle-5.4.0.orig/drivers/rtc/Makefile +++ linux-oracle-5.4.0/drivers/rtc/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_RTC_DRV_ABEOZ9) += rtc-ab-eoz9.o obj-$(CONFIG_RTC_DRV_ABX80X) += rtc-abx80x.o obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o +obj-$(CONFIG_RTC_DRV_AM1805) += rtc-am1805.o obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o --- linux-oracle-5.4.0.orig/drivers/rtc/class.c +++ linux-oracle-5.4.0/drivers/rtc/class.c @@ -26,6 +26,15 @@ static void rtc_device_release(struct device *dev) { struct rtc_device *rtc = to_rtc_device(dev); + struct timerqueue_head *head = &rtc->timerqueue; + struct timerqueue_node *node; + + mutex_lock(&rtc->ops_lock); + while ((node = timerqueue_getnext(head))) + timerqueue_del(head, node); + mutex_unlock(&rtc->ops_lock); + + cancel_work_sync(&rtc->irqwork); ida_simple_remove(&rtc_ida, rtc->id); kfree(rtc); --- linux-oracle-5.4.0.orig/drivers/rtc/interface.c +++ linux-oracle-5.4.0/drivers/rtc/interface.c @@ -125,7 +125,7 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) { - int err; + int err, uie; err = rtc_valid_tm(tm); if (err != 0) @@ -137,6 +137,17 @@ rtc_subtract_offset(rtc, tm); +#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL + uie = rtc->uie_rtctimer.enabled || rtc->uie_irq_active; +#else + uie = rtc->uie_rtctimer.enabled; +#endif + if (uie) { + err = rtc_update_irq_enable(rtc, 0); + if (err) + return err; + } + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -153,6 +164,12 @@ /* A timer might have just expired */ schedule_work(&rtc->irqwork); + if (uie) { + err = rtc_update_irq_enable(rtc, 1); + if (err) + return err; + } + trace_rtc_set_time(rtc_tm_to_time64(tm), err); return err; } @@ -257,10 +274,9 @@ return err; /* full-function RTCs won't have such missing fields */ - if (rtc_valid_tm(&alarm->time) == 0) { - rtc_add_offset(rtc, &alarm->time); - return 0; - } + err = rtc_valid_tm(&alarm->time); + if (!err) + goto done; /* get the "after" timestamp, to detect wrapped fields */ err = rtc_read_time(rtc, &now); @@ -362,6 +378,8 @@ if (err) dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time); + else + rtc_add_offset(rtc, &alarm->time); return err; } @@ -776,9 +794,13 @@ struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); struct rtc_time tm; ktime_t now; + int err; + + err = __rtc_read_time(rtc, &tm); + if (err) + return err; timer->enabled = 1; - __rtc_read_time(rtc, &tm); now = rtc_tm_to_ktime(tm); /* Skip over expired timers */ @@ -792,7 +814,6 @@ trace_rtc_timer_enqueue(timer); if (!next || ktime_before(timer->node.expires, next->expires)) { struct rtc_wkalrm alarm; - int err; alarm.time = rtc_ktime_to_tm(timer->node.expires); alarm.enabled = 1; @@ -873,13 +894,18 @@ struct timerqueue_node *next; ktime_t now; struct rtc_time tm; + int err; struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork); mutex_lock(&rtc->ops_lock); again: - __rtc_read_time(rtc, &tm); + err = __rtc_read_time(rtc, &tm); + if (err) { + mutex_unlock(&rtc->ops_lock); + return; + } now = rtc_tm_to_ktime(tm); while ((next = timerqueue_getnext(&rtc->timerqueue))) { if (next->expires > now) --- linux-oracle-5.4.0.orig/drivers/rtc/proc.c +++ linux-oracle-5.4.0/drivers/rtc/proc.c @@ -23,8 +23,8 @@ int size; char name[NAME_SIZE]; - size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id); - if (size > NAME_SIZE) + size = snprintf(name, NAME_SIZE, "rtc%d", rtc->id); + if (size >= NAME_SIZE) return false; return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-88pm860x.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-88pm860x.c @@ -336,6 +336,10 @@ info->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, info); + info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc_dev)) + return PTR_ERR(info->rtc_dev); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, rtc_update_handler, IRQF_ONESHOT, "rtc", info); @@ -377,13 +381,11 @@ } } - info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm860x-rtc", - &pm860x_rtc_ops, THIS_MODULE); - ret = PTR_ERR(info->rtc_dev); - if (IS_ERR(info->rtc_dev)) { - dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + info->rtc_dev->ops = &pm860x_rtc_ops; + + ret = rtc_register_device(info->rtc_dev); + if (ret) return ret; - } /* * enable internal XO instead of internal 3.25MHz clock since it can --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-ab-eoz9.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-ab-eoz9.c @@ -281,13 +281,6 @@ if (ret < 0) return ret; - if ((val & ABEOZ9_REG_CTRL_STATUS_V1F) || - (val & ABEOZ9_REG_CTRL_STATUS_V2F)) { - dev_err(dev, - "thermometer might be disabled due to low voltage\n"); - return -EINVAL; - } - switch (attr) { case hwmon_temp_input: ret = regmap_read(regmap, ABEOZ9_REG_REG_TEMP, &val); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-abx80x.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-abx80x.c @@ -36,7 +36,7 @@ #define ABX8XX_REG_STATUS 0x0f #define ABX8XX_STATUS_AF BIT(2) #define ABX8XX_STATUS_BLF BIT(4) -#define ABX8XX_STATUS_WDT BIT(6) +#define ABX8XX_STATUS_WDT BIT(5) #define ABX8XX_REG_CTRL1 0x10 #define ABX8XX_CTRL_WRITE BIT(0) --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-am1805.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-am1805.c @@ -0,0 +1,1562 @@ +/* + * Copyright (C) 2016 Eurotech S.p.A. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/* + * Version History. + * 2016-10-26 0.6.0 fixed time fields in rtc_read_alarm function + * + * 2016-10-03 0.5.0 notify that UIE is not supported by our hw + * add mutex lock/unlock to read/set time functions + * + * 2016-07-12 0.4-0 Add clock_adj parameter for XT clock calibration + * + * 2016-04-20 0.3.0 Add board turn on feature + * Feature is enabled as parameter and can be changed + * via sysfs + * Trickle charger as module parameter + * + * 2016-04-01 0.2.0 Add alarm, watchdog functionality + * watchdog create a 60ms pulse on sRST pin 3.3V -> 0 -> 3.3V + * alarm create a 250ms pulse on nIRQ pin 3.3V -> 0 -> 3.3V + * + * 2016-01-22 0.1.0 First Release + * date time get/set commands + * 256 byte get/set via sysfs. + * ram_address allows to get/set ram_byte + * watchdog + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_FORCE_SMBUS 0 +static bool force_smbus = DEFAULT_FORCE_SMBUS; +module_param(force_smbus, bool, 0444); +MODULE_PARM_DESC(force_smbus, "force smbus protocol (default=" + __MODULE_STRING(DEFAULT_FORCE_SMBUS) ")"); + +#define DEFAULT_WATCHDOG_TIMEOUT 30 +static int timeout = DEFAULT_WATCHDOG_TIMEOUT; +module_param(timeout, int, 0444); +MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=124, default=" + __MODULE_STRING(DEFAULT_WATCHDOG_TIMEOUT) ")"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0444); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" + __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +#define DEFAULT_DISABLE_ON_BOOT 1 +static bool disable_on_boot = DEFAULT_DISABLE_ON_BOOT; +module_param(disable_on_boot, bool, 0444); +MODULE_PARM_DESC(disable_on_boot, "Watchdog automatically disabled at boot time (default=" + __MODULE_STRING(DEFAULT_DISABLE_ON_BOOT)")"); + +/* + * the following paramweter could be removed since revA board should + * provide WDT IRQ to cortex via RST pin only + */ +#define DEFAULT_STEERING 1 +static bool watchdog_steering = DEFAULT_STEERING; +module_param(watchdog_steering, bool, 0444); +MODULE_PARM_DESC(watchdog_steering, "Watchdog IRQ steering : 0 WIRQ , 1 RST (default=" + __MODULE_STRING(DEFAULT_STEERING)")"); + +#define DEFAULT_BOARD_TURN_ON 0 +static bool board_turn_on = DEFAULT_BOARD_TURN_ON; +module_param(board_turn_on, bool, 0444); +MODULE_PARM_DESC(board_turn_on, "Enable board turn on via alarm route (default=" + __MODULE_STRING(DEFAULT_BOARD_TURN_ON)")"); + +#define DEFAULT_TRICKLE_REGISTER 0x00 +static int trickle_register = DEFAULT_TRICKLE_REGISTER; +module_param(trickle_register, int, 0444); +MODULE_PARM_DESC(trickle_register, "trickle charger register (default=" + __MODULE_STRING(DEFAULT_TRICKLE_REGISTER)")"); + +#define DEFAULT_XT_CLOCK_ADJ 0 +static int xt_clock_adj = DEFAULT_XT_CLOCK_ADJ; +module_param(xt_clock_adj, int, 0444); +MODULE_PARM_DESC(xt_clock_adj, "Adj parameter as per Ambiq micro procedure (default=" + __MODULE_STRING(DEFAULT_XT_CLOCK_ADJ)")"); + +#define DRIVER_NAME "rtc-am1805" +#define DRIVER_VERSION "0.6.0" + +#define AM1805_IDENTITY_CODE 0x18 +#define SECONDS_BITS 0x7F +#define MINUTES_BITS 0x7F +#define HOURS_BITS 0x3F +#define DATE_BITS 0x3F +#define MONTHS_BITS 0x1F +#define WEEKDAY_BITS 0x07 + +#define REG_HUNDREDS_ADDR 0x00 // hundreds of seconds register address +#define REG_SECONDS_ADDR 0x01 // seconds register address +#define REG_MINUTES_ADDR 0x02 // minutes register address +#define REG_HOURS_ADDR 0x03 // hours register address +#define REG_MDAY_ADDR 0x04 // day of the month register address +#define REG_MONTH_ADDR 0x05 // month register address +#define REG_YEAR_ADDR 0x06 // years register address +#define REG_WDAY_ADDR 0x07 // day of the week register address + +#define REG_ALM_HUNDREDS_ADDR 0x08 // Alarm hundreds of seconds register address +#define REG_ALM_SECONDS_ADDR 0x09 // Alarm seconds register address +#define REG_ALM_MINUTES_ADDR 0x0A // Alarm minutes register address +#define REG_ALM_HOURS_ADDR 0x0B // Alarm hours register address +#define REG_ALM_MDAY_ADDR 0x0C // Alarm day of the month register address +#define REG_ALM_MONTH_ADDR 0x0D // Alarm month register address +#define REG_ALM_WDAY_ADDR 0x0E // Alarm day of the week register address + +#define REG_STATUS_ADDR 0x0F // status register address +#define REG_STATUS_ALM (1 << 2) // Alarm function enabled +#define REG_STATUS_WDT (1 << 5) // Watchdog expired bit +#define REG_STATUS_CB (1 << 7) // Century rollover bit + +#define REG_CONTROL1_ADDR 0x10 // control1 register address +#define REG_CONTROL1_WRTC 1 // write enable for counter registers +#define REG_CONTROL1_PWR2 (1 << 1) // PWR2 +#define REG_CONTROL1_ARST (1 << 2) // auto reset on read +#define REG_CONTROL1_RSP (1 << 3) // nRST polarity 1 high 0 low +#define REG_CONTROL1_OUT (1 << 4) // nIRQ pin static value +#define REG_CONTROL1_OUTB (1 << 5) // nIRQ2 pin static value +#define REG_CONTROL1_1224 (1 << 6) // 12/24 format selection 0 = 24h +#define REG_CONTROL1_STOP (1 << 7) // stop the clocking system + +#define REG_CONTROL2_ADDR 0x11 // control2 register address +#define REG_CONTROL2_OUT2S_BITS 0x1C // control2 register out2s bits +#define REG_IRQ_MASK_ADDR 0x12 // Interrupt Mask register address +#define REG_IRQ_MASK_AIE (1 << 2) // Alarm interrupt enable + +#define REG_XT_CALIB_ADDR 0x14 // XT calibration register address +#define REG_XT_CALIB_OFFSETX_MASK 0x7F // OFFSET X BIT MASK +#define REG_XT_CALIB_CMDX 0x80 // cmdx field + + +#define REG_TIMER_CTRL_ADDR 0x18 // Countdown timer control register address +#define REG_TIMER_CTRL_RPT_BITS 0x1C // only the RPT bits + +#define REG_WATCHDOG_ADDR 0x1B // watchdog register address +#define REG_WATCHDOG_WDS (1 << 7) // watchodg steering bit +#define WRB_1_SECOND 0x02 //watchdog clock 1Hz +#define WRB_4_SECONDS 0x03 //watchdog clock 1/4 Hz + +#define REG_OSC_STATUS_ADDR 0x1D // oscillator status register address +#define REG_OSC_STATUS_ACAL_MASK 0x60 // ACAL bit field mask +#define REG_OSC_STATUS_ACAL_0 0x00 +#define REG_OSC_STATUS_ACAL_1 0x40 +#define REG_OSC_STATUS_ACAL_2 0x80 +#define REG_OSC_STATUS_ACAL_3 0xC0 + +#define REG_CONFIGKEY_ADDR 0x1F // configuration key register address + + +#define REG_TRICKLE_ADDR 0x20 // trickle charger register + +#define REG_IDENTITY_ADDR 0x28 // identity register address must contain 0x18 + +#define REG_EXTRAM_ADDR 0x3F // Extension ram register address +#define REG_EXTRAM_XADA (1 << 2) //select bank of memory + +static struct i2c_driver am1805_driver; + +struct am1805_data { + struct i2c_client *client; + struct rtc_device *rtc; + struct mutex mutex; + int use_smbus; + int watchdog_timeout; + int watchdog_disable_on_boot; + int watchdog_steering; + int watchdog_registered; + int watchdog_enabled; + unsigned char watchdog_reg; + unsigned long int watchdog_start_jiffies; + int ram_byte_file_created; + int ram_address_file_created; + unsigned char ram_address; + int board_turn_on; + int board_turn_on_file_created; + unsigned char trickle_register; +}; + +static int am1805_read(struct am1805_data *amq, u8 *buf, int len) +{ + int err, i; + u8 base_reg; + struct i2c_msg msgs[] = { + + { + .addr = amq->client->addr, + .flags = (amq->client->flags & I2C_M_TEN), + .len = 1, + .buf = buf, + }, + { + .addr = amq->client->addr, + .flags = (amq->client->flags & I2C_M_TEN) | I2C_M_RD, + .len = len, + .buf = buf, + }, + }; + if (amq->use_smbus) { + /* use SMBUS transfer protocol */ + base_reg = buf[0]; + for (i = 0; i < len; i++) { + err = i2c_smbus_read_byte_data(amq->client, base_reg); + if (err < 0) { + dev_err(&amq->client->dev, + "read transfer error reg 0x%02X\n", + base_reg); + break; + } + buf[i] = (u8)err; + base_reg++; + err = 0; + } + } else { + /* use I2C transfer protocol */ + err = i2c_transfer(amq->client->adapter, msgs, 2); + + if (err != 2) { + dev_err(&amq->client->dev, "I2C read transfer error\n"); + err = -EIO; + } else { + err = 0; + } + } + return err; +} + +static int am1805_write(struct am1805_data *amq, u8 *buf, int len) +{ + int err = 0, i; + u8 base_reg; + struct i2c_msg msgs[] = { + { + .addr = amq->client->addr, + .flags = (amq->client->flags & I2C_M_TEN), + .len = len + 1, + .buf = buf, + }, + }; + + if (amq->use_smbus) { + /* use SMBUS transfer protocol */ + base_reg = buf[0]; + for (i = 1; i <= len; i++) { + err = i2c_smbus_write_byte_data(amq->client, base_reg, + buf[i]); + if (err < 0) { + dev_err(&amq->client->dev, + "write transfer error reg 0x%02X\n", + base_reg); + break; + } + base_reg++; + } + } else { + /* use I2C transfer protocol */ + err = i2c_transfer(amq->client->adapter, msgs, 1); + if (err != 1) { + dev_err(&amq->client->dev, "I2C write transfer error\n"); + err = -EIO; + } else { + err = 0; + } + } + return err; +} + + +static int am1805_stop_rtc(struct am1805_data *amq) +{ + u8 regs[2]; + int err; + + regs[0] = REG_CONTROL1_ADDR; + + err = am1805_read(amq, regs, 1); + if (err < 0) + return err; + regs[1] = regs[0]; + regs[0] = REG_CONTROL1_ADDR; + + + regs[1] |= (REG_CONTROL1_STOP|REG_CONTROL1_WRTC); + + err = am1805_write(amq, regs, 1); + if (err < 0) + return err; + + return 0; +} + + +static int am1805_start_rtc(struct am1805_data *amq) +{ + u8 regs[2]; + int err; + + regs[0] = REG_CONTROL1_ADDR; + + err = am1805_read(amq, regs, 1); + if (err < 0) + return err; + regs[1] = regs[0]; + regs[0] = REG_CONTROL1_ADDR; + + regs[1] &= (~(REG_CONTROL1_STOP|REG_CONTROL1_WRTC)); + + err = am1805_write(amq, regs, 1); + if (err < 0) + return err; + + return 0; +} + +static int am1805_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct am1805_data *amq; + u8 regs[8]; + int err; + + amq = i2c_get_clientdata(client); + mutex_lock(&amq->mutex); + + regs[0] = REG_SECONDS_ADDR; + err = am1805_read(amq, regs, 7); + if (err) + goto exit; + + /* read the status register */ + regs[7] = REG_STATUS_ADDR; + err = am1805_read(amq, ®s[7], 1); + if (err) + goto exit; + regs[0] &= SECONDS_BITS; + regs[1] &= MINUTES_BITS; + regs[2] &= HOURS_BITS; + regs[3] &= DATE_BITS; + regs[4] &= MONTHS_BITS; + regs[6] &= WEEKDAY_BITS; + + tm->tm_sec = bcd2bin(regs[0]); + tm->tm_min = bcd2bin(regs[1]); + tm->tm_hour = bcd2bin(regs[2]); + tm->tm_mday = bcd2bin(regs[3]); + tm->tm_mon = bcd2bin(regs[4]); + tm->tm_mon--; + tm->tm_year = bcd2bin(regs[5])+100; + + if (regs[7] & REG_STATUS_CB) + tm->tm_year += 100; + tm->tm_wday = regs[6]; + + err = rtc_valid_tm(tm); +exit: + mutex_unlock(&amq->mutex); + return err; +} + + +static int am1805_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + struct am1805_data *amq; + u8 regs[10]; + int err; + + amq = i2c_get_clientdata(client); + + mutex_lock(&amq->mutex); + + err = am1805_stop_rtc(amq); + if (err < 0) + goto exit; + regs[0] = REG_HUNDREDS_ADDR; + regs[1] = bin2bcd(0); + regs[2] = bin2bcd(tm->tm_sec); + regs[3] = bin2bcd(tm->tm_min); + regs[4] = bin2bcd(tm->tm_hour); + regs[5] = bin2bcd(tm->tm_mday); + regs[6] = bin2bcd(tm->tm_mon+1); + regs[7] = bin2bcd(tm->tm_year - 100); + regs[8] = tm->tm_wday; + + + err = am1805_write(amq, regs, 8); + if (am1805_start_rtc(amq)) + err = -1; +exit: + mutex_unlock(&amq->mutex); + return err; +} + +/******************************************************************************* + * RAM byte + * 256 bytes available + * read return the byte pointed by ram_address + * write store the values in ram_address + */ + +static ssize_t am1805_ram_byte_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int err; + unsigned char ram_byte; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + + mutex_lock(&amq->mutex); + ram_byte = amq->ram_address; + ram_byte |= 0x80; + err = am1805_read(amq, &ram_byte, 1); + mutex_unlock(&amq->mutex); + + if (err == 0) + err = sprintf(buf, "%02X\n", ram_byte); + return err; +} + +static ssize_t am1805_ram_byte_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned char reg[2]; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + + err = kstrtou8(buf, 10, ®[1]); + if (err == 0) { + reg[0] = amq->ram_address; + reg[0] |= 0x80; + err = am1805_write(amq, reg, 1); + } + + mutex_unlock(&amq->mutex); + if (err) + return err; + return count; +} + +static const struct device_attribute am1805_ram_byte_device_attribute = { + .attr.name = "ram_byte", + .attr.mode = 0600, + .show = am1805_ram_byte_show, + .store = am1805_ram_byte_store, +}; +/****** END RAM BYTE ATTIBUTES ********/ + +/******************************************************************************* + * RAM Address + * 256 bytes available + * read return current ram_address + * write store the values in ram_address and set Extension Ram register + */ + +static ssize_t am1805_ram_address_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int err; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + + mutex_lock(&amq->mutex); + err = sprintf(buf, "%02X\n", amq->ram_address); + mutex_unlock(&amq->mutex); + return err; +} + +static ssize_t am1805_ram_address_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned char reg[2], ram_addr; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + + err = kstrtou8(buf, 10, &ram_addr); + if (err == 0) { + reg[0] = (unsigned char)(ram_addr ^ amq->ram_address); + reg[0] &= 0x80; + if (reg[0] == 0) { + /* no changes , same bank of memory) */ + amq->ram_address = ram_addr; + } else { + reg[0] = REG_EXTRAM_ADDR; + err = am1805_read(amq, reg, 1); + if (err == 0) { + reg[1] = reg[0]; + reg[0] = REG_EXTRAM_ADDR; + if (ram_addr & 0x80) + reg[1] |= REG_EXTRAM_XADA; + else + reg[1] &= ~REG_EXTRAM_XADA; + err = am1805_write(amq, reg, 1); + if (err == 0) + amq->ram_address = ram_addr; + } + } + } + + mutex_unlock(&amq->mutex); + if (err) + return err; + return count; +} + +static const struct device_attribute am1805_ram_address_device_attribute = { + .attr.name = "ram_address", + .attr.mode = 0600, + .show = am1805_ram_address_show, + .store = am1805_ram_address_store, +}; +/****** END RAM ADDRESS ATTIBUTES ********/ + + +/******************************************************************************* + * WATCHDOG + * gettimeleft function is implemented via jiffies since hw doesn't support + * this capability + */ + +static int am1805_watchdog_compute_seconds(int *seconds, + unsigned char *wdt_reg, int steer) +{ + int err = 0; + unsigned char reg_value = 0x00; + + /* WatchDog-duration = BMB x stepsize */ + if (*seconds > 120) { + *seconds = 124; + reg_value = 31; + reg_value <<= 2; + reg_value |= WRB_4_SECONDS; + } else if (*seconds > 31) { + reg_value = (unsigned char)(*seconds); + reg_value >>= 2; + if (((int)reg_value * 4) != *seconds) + reg_value++; + *seconds = reg_value; + *seconds <<= 2; + reg_value <<= 2; + reg_value |= WRB_4_SECONDS; + } else if (*seconds >= 0) { + reg_value = (unsigned char)*seconds; + reg_value <<= 2; + reg_value |= WRB_1_SECOND; + } else { + err = -EINVAL; + } + if (steer) + reg_value |= REG_WATCHDOG_WDS; + if (wdt_reg != NULL) + *wdt_reg = reg_value; + return err; +} + +static int am1805_watchdog_disable(struct am1805_data *am_data) +{ + int err; + unsigned char regs[2]; + + /* disable wdt */ + regs[0] = REG_WATCHDOG_ADDR; + if (am_data->watchdog_steering) + regs[1] = (unsigned char)REG_WATCHDOG_WDS; + else + regs[1] = 0x00; + err = am1805_write(am_data, regs, 1); + if (err) { + dev_err(&am_data->client->dev, + "[%s] write watchdog reg ERROR\n", __func__); + return err; + } + regs[0] = REG_STATUS_ADDR; + err = am1805_read(am_data, regs, 1); + if (err) { + dev_err(&am_data->client->dev, + "[%s] read status reg ERROR\n", __func__); + return err; + } + regs[1] = regs[0]; + regs[0] = REG_STATUS_ADDR; + regs[1] &= ~REG_STATUS_WDT; + err = am1805_write(am_data, regs, 1); + if (err) + dev_err(&am_data->client->dev, + "[%s] write status reg ERROR\n", __func__); + am_data->watchdog_enabled = 0; + return err; +} + +static int am1805_watchdog_enable(struct am1805_data *am_data) +{ + int err; + unsigned char regs[2]; + + err = am1805_watchdog_disable(am_data); + if (err) + return err; + /* CALCULATE THE REFRESH VALUE */ + err = am1805_watchdog_compute_seconds(&am_data->watchdog_timeout, + &am_data->watchdog_reg, + am_data->watchdog_steering); + if (err) { + dev_err(&am_data->client->dev, + "[%s] problems while computing actual timeout\n", + __func__); + return err; + } + + regs[0] = REG_WATCHDOG_ADDR; + regs[1] = am_data->watchdog_reg; + err = am1805_write(am_data, regs, 1); + if (err) { + dev_err(&am_data->client->dev, + "[%s] write watchdog reg ERROR\n", __func__); + return err; + } + am_data->watchdog_start_jiffies = jiffies; + am_data->watchdog_enabled = 1; + return 0; +} + +static int am1805_watchdog_start_op(struct watchdog_device *device) +{ + int err; + struct i2c_client *client; + struct am1805_data *amq; + + client = watchdog_get_drvdata(device); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + + mutex_lock(&amq->mutex); + /* disable wdt */ + //err=am1805_watchdog_disable(amq); + //if (err==0) { + err = am1805_watchdog_enable(amq); + if (err == 0) + dev_dbg(&client->dev, + "[%s] watchdog enabled, seconds = %d\n", + __func__, amq->watchdog_timeout); + //} + mutex_unlock(&amq->mutex); + return err; +} + +static int am1805_watchdog_stop_op(struct watchdog_device *device) +{ + int err; + struct i2c_client *client; + struct am1805_data *amq; + + client = watchdog_get_drvdata(device); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + + mutex_lock(&amq->mutex); + err = am1805_watchdog_disable(amq); + if (err == 0) + dev_dbg(&client->dev, "[%s] watchdog disabled\n", __func__); + mutex_unlock(&amq->mutex); + return err; +} + +static int am1805_watchdog_ping_op(struct watchdog_device *device) +{ + unsigned char regs[2]; + int err; + struct i2c_client *client; + struct am1805_data *amq; + + client = watchdog_get_drvdata(device); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + + mutex_lock(&amq->mutex); + if (amq->watchdog_enabled) { + regs[0] = REG_WATCHDOG_ADDR; + regs[1] = amq->watchdog_reg; + err = am1805_write(amq, regs, 1); + if (err) + dev_err(&amq->client->dev, + "[%s] write watchdog reg ERROR\n", __func__); + } else { + err = 0; + dev_dbg(&client->dev, "[%s] can not ping disabled watchdog\n", + __func__); + } + mutex_unlock(&amq->mutex); + return err; +} + +static int am1805_watchdog_set_timeout_op(struct watchdog_device *device, + unsigned int timeout) +{ + int err; + unsigned int seconds; + struct i2c_client *client; + struct am1805_data *amq; + unsigned char reg_data; + + client = watchdog_get_drvdata(device); + amq = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "[%s]\n", __func__); + seconds = (int)timeout; + mutex_lock(&amq->mutex); + err = am1805_watchdog_compute_seconds((int *)&seconds, ®_data, + amq->watchdog_steering); + if (err == 0) { + device->timeout = (unsigned int)seconds; + amq->watchdog_timeout = seconds; + amq->watchdog_reg = reg_data; + } else + dev_err(&client->dev, + "[%s] problems while computing actual timeout\n", + __func__); + + mutex_unlock(&amq->mutex); + return 0; +} + +static unsigned int am1805_watchdog_get_timeleft_op(struct watchdog_device + *device) +{ + unsigned int time_left; + struct i2c_client *client; + struct am1805_data *amq; + + client = watchdog_get_drvdata(device); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + time_left = jiffies; + time_left -= amq->watchdog_start_jiffies; + time_left = (unsigned int)(time_left/HZ); + mutex_unlock(&amq->mutex); + return time_left; +} + +static struct watchdog_info am1805_watchdog_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING + | WDIOF_MAGICCLOSE, + .firmware_version = 0x00000100, + .identity = "AM1805 Watchdog", +}; + +static struct watchdog_ops am1805_watchdog_ops = { + .owner = THIS_MODULE, + .start = am1805_watchdog_start_op, + .stop = am1805_watchdog_stop_op, + .ping = am1805_watchdog_ping_op, + .set_timeout = am1805_watchdog_set_timeout_op, + .get_timeleft = am1805_watchdog_get_timeleft_op, +}; + +static struct watchdog_device am1805_watchdog_device = { + .info = &am1805_watchdog_info, + .ops = &am1805_watchdog_ops, + .timeout = DEFAULT_WATCHDOG_TIMEOUT, + .min_timeout = 1, + .max_timeout = 124, +}; + +/****** END Watchdog FUNCTIONS ********/ + +/****** START ALARM FUNCTIONS ********/ + +static int am1805_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + int err; + unsigned char regs[7]; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + regs[0] = REG_ALM_SECONDS_ADDR; + err = am1805_read(amq, regs, 6); + if (err) { + dev_err(&client->dev, "[%s] read %02X 6 register\n", __func__, + REG_ALM_SECONDS_ADDR); + goto exit; + } + regs[0] &= SECONDS_BITS; + regs[1] &= MINUTES_BITS; + regs[2] &= HOURS_BITS; + regs[3] &= DATE_BITS; + regs[4] &= MONTHS_BITS; + regs[5] &= WEEKDAY_BITS; + + alarm->time.tm_sec = bcd2bin(regs[0]); + alarm->time.tm_min = bcd2bin(regs[1]); + alarm->time.tm_hour = bcd2bin(regs[2]); + alarm->time.tm_mday = bcd2bin(regs[3]); + alarm->time.tm_mon = bcd2bin(regs[4]); + if (alarm->time.tm_mon > 0) + alarm->time.tm_mon--; + alarm->time.tm_wday = regs[5]; + + alarm->time.tm_year = -1; + alarm->time.tm_yday = -1; + alarm->time.tm_isdst = -1; + + regs[0] = REG_IRQ_MASK_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", __func__, + REG_IRQ_MASK_ADDR); + goto exit; + } + alarm->enabled = (regs[0] & REG_IRQ_MASK_AIE) ? 1 : 0; + + regs[0] = REG_STATUS_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_STATUS_ADDR); + goto exit; + } + alarm->pending = (regs[0] & REG_STATUS_ALM) ? 1 : 0; +exit: + mutex_unlock(&amq->mutex); + return err; +} + + +static int am1805_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + int err; + unsigned char regs[8]; + unsigned char timer_ctrl_reg, irq_mask_reg; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + /* Disable alarm */ + mutex_lock(&amq->mutex); + regs[0] = REG_TIMER_CTRL_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_TIMER_CTRL_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_TIMER_CTRL_ADDR; + regs[1] &= (unsigned char)(~REG_TIMER_CTRL_RPT_BITS); + timer_ctrl_reg = regs[1]; + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_TIMER_CTRL_ADDR); + err = -EIO; + goto exit; + } + + regs[0] = REG_IRQ_MASK_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_IRQ_MASK_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_IRQ_MASK_ADDR; + regs[1] &= (unsigned char)(~REG_IRQ_MASK_AIE); + irq_mask_reg = regs[1]; + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_IRQ_MASK_ADDR); + err = -EIO; + goto exit; + } + regs[0] = REG_STATUS_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_STATUS_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_STATUS_ADDR; + regs[1] &= (unsigned char)(~REG_STATUS_ALM); + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_STATUS_ADDR); + err = -EIO; + goto exit; + } + if (alarm->enabled) { + regs[0] = REG_ALM_HUNDREDS_ADDR; + regs[1] = bin2bcd(0); /* hundreds of seconds */ + regs[2] = bin2bcd(alarm->time.tm_sec); + regs[3] = bin2bcd(alarm->time.tm_min); + regs[4] = bin2bcd(alarm->time.tm_hour); + regs[5] = bin2bcd(alarm->time.tm_mday); + regs[6] = bin2bcd(alarm->time.tm_mon + 1); + regs[7] = (unsigned char)(alarm->time.tm_wday & 0x07); + err = am1805_write(amq, regs, 7); + if (err) { + dev_err(&client->dev, "[%s] write %02X 7 register\n", + __func__, REG_ALM_HUNDREDS_ADDR); + err = -EIO; + goto exit; + } + regs[0] = REG_IRQ_MASK_ADDR; + regs[1] = irq_mask_reg; + regs[1] |= REG_IRQ_MASK_AIE; + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_IRQ_MASK_ADDR); + err = -EIO; + goto exit; + } + regs[0] = REG_TIMER_CTRL_ADDR; + regs[1] = timer_ctrl_reg; + regs[1] |= (unsigned char)(1 << 2); + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, + "[%s] write %02X 1 register\n", __func__, + REG_TIMER_CTRL_ADDR); + err = -EIO; + } + } +exit: + mutex_unlock(&amq->mutex); + return err; +} + +static ssize_t am1805_board_turn_on_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int err; + struct i2c_client *client; + struct am1805_data *amq; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + if (amq->board_turn_on) + err = sprintf(buf, "1\n"); + else + err = sprintf(buf, "0\n"); + return err; +} + +static ssize_t am1805_board_turn_on_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int err, value; + struct i2c_client *client; + struct am1805_data *amq; + unsigned char regs[4]; + + client = to_i2c_client(dev); + amq = i2c_get_clientdata(client); + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + + err = kstrtos32(buf, 10, &value); + if (err == 0) { + regs[0] = REG_CONTROL1_ADDR; + err = am1805_read(amq, regs, 2); + if (err) { + dev_err(&client->dev, + "[%s] read %02X register , count=2\n", + __func__, REG_CONTROL1_ADDR); + err = -EIO; + goto exit; + } + regs[2] = regs[1]; + regs[1] = regs[0]; + regs[0] = REG_CONTROL1_ADDR; + regs[1] |= REG_CONTROL1_OUTB; + regs[2] &= (unsigned char)(~REG_CONTROL2_OUT2S_BITS); + if (value == 0) { + regs[2] |= (unsigned char)(7 << 2); + amq->board_turn_on = 0; + } else { + regs[2] |= (unsigned char)(3 << 2); + amq->board_turn_on = 1; + } + err = am1805_write(amq, regs, 2); + if (err) { + dev_err(&client->dev, + "[%s] write %02X register , count=2\n", + __func__, REG_CONTROL1_ADDR); + err = -EIO; + goto exit; + } else + err = count; + } +exit: + mutex_unlock(&amq->mutex); + return err; +} + +static const struct device_attribute am1805_board_turn_on_device_attribute = { + .attr.name = "board_turn_on", + .attr.mode = 0600, + .show = am1805_board_turn_on_show, + .store = am1805_board_turn_on_store, +}; + +/****** END ALARM FUNCTIONS ********/ + +static const struct rtc_class_ops am1805_rtc_ops = { + .read_time = am1805_rtc_read_time, + .set_time = am1805_rtc_set_time, + .set_alarm = am1805_rtc_set_alarm, + .read_alarm = am1805_rtc_read_alarm, +}; + +static void am1805_unload(struct i2c_client *client) +{ + struct am1805_data *amq; + + dev_dbg(&client->dev, "[%s]\n", __func__); + + amq = i2c_get_clientdata(client); + if (amq->ram_byte_file_created) { + sysfs_remove_file(&client->dev.kobj, + &am1805_ram_byte_device_attribute.attr); + } + if (amq->ram_address_file_created) { + sysfs_remove_file(&client->dev.kobj, + &am1805_ram_address_device_attribute.attr); + } + if (amq->board_turn_on_file_created) { + sysfs_remove_file(&client->dev.kobj, + &am1805_board_turn_on_device_attribute.attr); + } + + if (amq->watchdog_registered) { + device_wakeup_disable(&client->dev); + watchdog_unregister_device(&am1805_watchdog_device); + } + devm_kfree(&client->dev, amq); +} + +static int am1805_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct am1805_data *amq; + int err; + u8 regs[2]; + u8 xt_calib_value = 0; + u32 smbus_func = (I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA + | I2C_FUNC_SMBUS_I2C_BLOCK); + + dev_info(&client->dev, "probe_start, driver version %s\n", + DRIVER_VERSION); + + amq = devm_kzalloc(&client->dev, sizeof(struct am1805_data), + GFP_KERNEL); + if (amq == NULL) { + err = -ENOMEM; + dev_err(&client->dev, + "failed to allocate memory for module data: %d\n", err); + goto exit; + } + amq->ram_byte_file_created = 0; + amq->ram_address_file_created = 0; + amq->watchdog_timeout = timeout; + amq->watchdog_disable_on_boot = disable_on_boot; + amq->watchdog_steering = watchdog_steering; + amq->watchdog_enabled = 0; + amq->board_turn_on = board_turn_on; + amq->board_turn_on_file_created = 0; + amq->trickle_register = (unsigned char)trickle_register; + if (amq->watchdog_steering) + amq->watchdog_reg = REG_WATCHDOG_WDS; + else + amq->watchdog_reg = 0; + amq->watchdog_start_jiffies = 0; + amq->watchdog_registered = 0; + if ((i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + && (force_smbus == 0)) { + amq->use_smbus = 0; + } else { + dev_warn(&client->dev, "client not i2c capable\n"); + if (i2c_check_functionality(client->adapter, smbus_func)) { + amq->use_smbus = 1; + dev_warn(&client->dev, "client smbus capable\n"); + } else { + err = -ENODEV; + dev_err(&client->dev, "client not SMBUS capable\n"); + goto exit; + } + } + + mutex_init(&amq->mutex); + + amq->client = client; + i2c_set_clientdata(client, amq); + + /* check identity register */ + regs[0] = REG_IDENTITY_ADDR; + if (am1805_read(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, + "fail to fetch identity register 0x%02X\n", + REG_IDENTITY_ADDR); + goto exit; + } + + if (regs[0] != AM1805_IDENTITY_CODE) { + err = -ENODEV; + dev_err(&client->dev, + "chip not found,invalid identity code 0x%02X\n", + regs[0]); + goto exit; + + } + + /* set the trickle_register */ + regs[0] = REG_CONFIGKEY_ADDR; + regs[1] = 0x9D; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, + "fail to set configuration key register\n"); + goto exit; + } + regs[0] = REG_TRICKLE_ADDR; + regs[1] = amq->trickle_register; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set trickle register\n"); + goto exit; + } + + /* set extended ram register to default value */ + amq->ram_address = 0x00; + regs[0] = REG_EXTRAM_ADDR; + + if (am1805_read(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to fetch extension ram register\n"); + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_EXTRAM_ADDR; + regs[1] &= ~REG_EXTRAM_XADA; + + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set extension ram register\n"); + goto exit; + } + + /* ulock LKO2 in oscillator status register in order to drive OUTB */ + /* + * Bit_6-7 xtcal = 0 + * Bit_5 LKO2 = 0 + * Bit_4 OMODE = 0 + * Bit_2-3 RESERVED = 0 + * Bit_1 OF = 1 + * Bit_0 ACF = 0 + */ + /* calibrate the XT oscillator */ + regs[1] = 0x02; + xt_calib_value = 0x00; + if (xt_clock_adj < -320) + dev_warn(&client->dev, + "XT frequency too high to be calibrated adj = %d\n", + xt_clock_adj); + else if (xt_clock_adj < -256) { + /* XTCAL=3 CMDX=1 OFFSETX=(adj+192)/2 */ + regs[1] |= REG_OSC_STATUS_ACAL_3; + xt_calib_value = (unsigned char)((int)(xt_clock_adj+192)>>1); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + xt_calib_value |= REG_XT_CALIB_CMDX; + } else if (xt_clock_adj < -192) { + /* XTCAL=3 CMDX=0 OFFSETX=(adj+192) */ + regs[1] |= REG_OSC_STATUS_ACAL_3; + xt_calib_value = (unsigned char)((int)(xt_clock_adj+192)); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + } else if (xt_clock_adj < -128) { + /* XTCAL=2 CMDX=0 OFFSETX=(adj+128) */ + regs[1] |= REG_OSC_STATUS_ACAL_2; + xt_calib_value = (unsigned char)((int)(xt_clock_adj+128)); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + } else if (xt_clock_adj < -64) { + /* XTCAL=1 CMDX=0 OFFSETX=(adj+64) */ + regs[1] |= REG_OSC_STATUS_ACAL_1; + xt_calib_value = (unsigned char)((int)(xt_clock_adj+64)); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + } else if (xt_clock_adj < 64) { + /* XTCAL=0 CMDX=0 OFFSETX=(adj) */ + regs[1] |= REG_OSC_STATUS_ACAL_0; + xt_calib_value = (unsigned char)(xt_clock_adj); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + } else if (xt_clock_adj < 128) { + /* XTCAL=0 CMDX=1 OFFSETX=(adj)/2 */ + regs[1] |= REG_OSC_STATUS_ACAL_0; + xt_calib_value = (unsigned char)((int)(xt_clock_adj>>1)); + xt_calib_value &= REG_XT_CALIB_OFFSETX_MASK; + xt_calib_value |= REG_XT_CALIB_CMDX; + } else + dev_warn(&client->dev, + "XT frequency too low to be calibrated adj = %d\n", + xt_clock_adj); + + regs[0] = REG_OSC_STATUS_ADDR; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, + "fail to set oscillator status register\n"); + goto exit; + } + + /* Calibration XT Register */ + regs[0] = REG_XT_CALIB_ADDR; + regs[1] = xt_calib_value; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set XT calibration register\n"); + goto exit; + } + + /* + * CONTROL1 register + * STOP = 0 12/24 = 0 + * OUTB = 1 remove power latch due to rtc , OUT = 1 + * RSP = 0 due to watchdog active low + * ARST = 0 PWR2 = 1 WRTC = 1 + */ + regs[0] = REG_CONTROL1_ADDR; + regs[1] = (REG_CONTROL1_OUTB|REG_CONTROL1_OUT | REG_CONTROL1_PWR2 + | REG_CONTROL1_WRTC); + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set control1 register\n"); + goto exit; + } + + /* + * CONTROL2 register + * Bit_6-7 reseved = 0 + * Bit_5 RS1E = 0 due to watchdog + * Bit_2-4 OUT2S = 7 (board_turn_on =0) ; (3 board turn on =1) + * Bit_0-1 OUT1S = 3 due to alarm + */ + regs[0] = REG_CONTROL2_ADDR; + regs[1] = 0; + if (amq->board_turn_on) + regs[1] |= 0x03; + else + regs[1] |= 0x07; + regs[1] <<= 2; + regs[1] |= 0x03; + + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set control2 register\n"); + goto exit; + } + + /* + * alarm IRQ must be on level + * Bit_7 CEB = 1 + * Bit_5-6 IM = 3 ALARM IRQ 1/4 sec + * Bit_4 BLIE = 0 + * Bit_3 TIE = 0 + * Bit_2 AIE = 0 + * Bit_1 EX2E = 0 + * Bit_0 EX1E = 0 + */ + regs[0] = REG_IRQ_MASK_ADDR; + regs[1] = 0xE0; /* set im field to 0 */ + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to set interrupt mask register\n"); + goto exit; + } + /* + * Disable alarm interrupt + * Bit_7 TE = 0 + * Bit_6 TM = 0 + * Bit_5 TRPT = 1 + * Bit_2-4 RPT=0 ALARM DISABLE + * Bit_0-1 TFS=3 + */ + regs[0] = REG_TIMER_CTRL_ADDR; + regs[1] = 0x23; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, + "fail to set countdown timer control register\n"); + goto exit; + } + + + /* clear the status register */ + regs[0] = REG_STATUS_ADDR; + regs[1] = 0x00; + if (am1805_write(amq, regs, 1)) { + err = -ENODEV; + dev_err(&client->dev, "fail to clear status register\n"); + goto exit; + } + + amq->rtc = devm_rtc_device_register(&client->dev, + am1805_driver.driver.name, + &am1805_rtc_ops, THIS_MODULE); + + if (IS_ERR(amq->rtc)) { + dev_err(&client->dev, "fail to register rtc device\n"); + err = PTR_ERR(amq->rtc); + goto exit; + } + amq->rtc->uie_unsupported = 1; + + + /* RAM byte initialization */ + err = sysfs_create_file(&client->dev.kobj, + &am1805_ram_byte_device_attribute.attr); + if (err) { + dev_err(&client->dev, "fail to create sysfs file \"%s\"\n", + am1805_ram_byte_device_attribute.attr.name); + goto exit; + } + amq->ram_byte_file_created = 1; + + /* RAM address initialization */ + err = sysfs_create_file(&client->dev.kobj, + &am1805_ram_address_device_attribute.attr); + if (err) { + dev_err(&client->dev, "fail to create sysfs file \"%s\"\n", + am1805_ram_address_device_attribute.attr.name); + goto exit; + } + amq->ram_address_file_created = 1; + + /* board turn on initialization */ + err = sysfs_create_file(&client->dev.kobj, + &am1805_board_turn_on_device_attribute.attr); + if (err) { + dev_err(&client->dev, "fail to create sysfs file \"%s\"\n", + am1805_board_turn_on_device_attribute.attr.name); + goto exit; + } + amq->board_turn_on_file_created = 1; + + /* Watchdog driver registration */ + watchdog_set_drvdata(&am1805_watchdog_device, client); + watchdog_init_timeout(&am1805_watchdog_device, amq->watchdog_timeout, + NULL); + watchdog_set_nowayout(&am1805_watchdog_device, nowayout); + err = watchdog_register_device(&am1805_watchdog_device); + if (err) { + dev_err(&client->dev, + "ERROR, FAIL to register watchdog device\n"); + goto exit; + } + amq->watchdog_registered = 1; + dev_info(&client->dev, "registered %s as watchdog%d\n", + am1805_driver.driver.name, am1805_watchdog_device.id); + + if (amq->watchdog_disable_on_boot) { + dev_info(&client->dev, "watchdog timer disabled at boot\n"); + err = am1805_watchdog_disable(amq); + if (err) + goto exit; + } else { + dev_info(&client->dev, + "watchdog timer enabled at boot, %d s\n", + amq->watchdog_timeout); + err = am1805_watchdog_enable(amq); + if (err) + goto exit; + } + err = device_init_wakeup(&client->dev, true); + if (err) + dev_err(&client->dev, "dev_init_wakeup [%d] FAIL\n", err); + dev_info(&client->dev, "probe_end, init OK\n"); + return 0; +exit: + dev_info(&client->dev, "probe_end, init FAIL\n"); + am1805_unload(client); + return err; +} + +static int am1805_remove(struct i2c_client *client) +{ + dev_dbg(&client->dev, "[%s]\n", __func__); + am1805_unload(client); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int am1805_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct am1805_data *amq; + unsigned char regs[2]; + int err; + + amq = i2c_get_clientdata(client); + + dev_dbg(&client->dev, "[%s]\n", __func__); + mutex_lock(&amq->mutex); + /* is alarm expired? */ + regs[0] = REG_STATUS_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_STATUS_ADDR); + err = -EIO; + goto exit; + } + + if (regs[0] & REG_STATUS_ALM) { + /* Disable alarm */ + regs[0] = REG_TIMER_CTRL_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_TIMER_CTRL_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_TIMER_CTRL_ADDR; + regs[1] &= (unsigned char)(~REG_TIMER_CTRL_RPT_BITS); + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_TIMER_CTRL_ADDR); + err = -EIO; + goto exit; + } + + regs[0] = REG_IRQ_MASK_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_IRQ_MASK_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_IRQ_MASK_ADDR; + regs[1] &= (unsigned char)(~REG_IRQ_MASK_AIE); + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_IRQ_MASK_ADDR); + err = -EIO; + goto exit; + } + regs[0] = REG_STATUS_ADDR; + err = am1805_read(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] read %02X 1 register\n", + __func__, REG_STATUS_ADDR); + err = -EIO; + goto exit; + } + regs[1] = regs[0]; + regs[0] = REG_STATUS_ADDR; + regs[1] &= (unsigned char)(~REG_STATUS_ALM); + err = am1805_write(amq, regs, 1); + if (err) { + dev_err(&client->dev, "[%s] write %02X 1 register\n", + __func__, REG_STATUS_ADDR); + err = -EIO; + goto exit; + } + } + +exit: + mutex_unlock(&amq->mutex); + return err; +} + +static int am1805_suspend(struct device *dev) +{ + /* nothing to do at the moment */ + return 0; +} +#else +#define am1805_suspend NULL +#define am1805_resume NULL +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(am1805_pm, am1805_suspend, am1805_resume); + +static const struct i2c_device_id am1805_id[] = { + { "am1805", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, am1805_id); + +static struct i2c_driver am1805_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .pm = &am1805_pm, + }, + .probe = am1805_probe, + .remove = am1805_remove, + .id_table = am1805_id, +}; +module_i2c_driver(am1805_driver); + +MODULE_AUTHOR("Pierluigi Driusso "); +MODULE_DESCRIPTION("Ambiq micro AM1805 RTC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(DRIVER_VERSION); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-at91sam9.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-at91sam9.c @@ -370,6 +370,7 @@ return ret; rtc->gpbr = syscon_node_to_regmap(args.np); + of_node_put(args.np); rtc->gpbr_offset = args.args[0]; if (IS_ERR(rtc->gpbr)) { dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n"); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-bd70528.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-bd70528.c @@ -491,3 +491,4 @@ MODULE_AUTHOR("Matti Vaittinen "); MODULE_DESCRIPTION("BD70528 RTC driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:bd70528-rtc"); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-brcmstb-waketimer.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-brcmstb-waketimer.c @@ -277,6 +277,7 @@ struct brcmstb_waketmr *timer = dev_get_drvdata(&pdev->dev); unregister_reboot_notifier(&timer->reboot_notifier); + clk_disable_unprepare(timer->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-cmos.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-cmos.c @@ -463,7 +463,10 @@ min = t->time.tm_min; sec = t->time.tm_sec; + spin_lock_irq(&rtc_lock); rtc_control = CMOS_READ(RTC_CONTROL); + spin_unlock_irq(&rtc_lock); + if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { /* Writing 0xff means "don't care" or "match all". */ mon = (mon <= 12) ? bin2bcd(mon) : 0xff; @@ -594,11 +597,10 @@ size_t count) { unsigned char *buf = val; - int retval; off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); - for (retval = 0; count; count--, off++, retval++) { + for (; count; count--, off++) { if (off < 128) *buf++ = CMOS_READ(off); else if (can_bank2) @@ -608,7 +610,7 @@ } spin_unlock_irq(&rtc_lock); - return retval; + return count ? -EIO : 0; } static int cmos_nvram_write(void *priv, unsigned int off, void *val, @@ -616,7 +618,6 @@ { struct cmos_rtc *cmos = priv; unsigned char *buf = val; - int retval; /* NOTE: on at least PCs and Ataris, the boot firmware uses a * checksum on part of the NVRAM data. That's currently ignored @@ -625,7 +626,7 @@ */ off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); - for (retval = 0; count; count--, off++, retval++) { + for (; count; count--, off++) { /* don't trash RTC registers */ if (off == cmos->day_alrm || off == cmos->mon_alrm @@ -640,7 +641,7 @@ } spin_unlock_irq(&rtc_lock); - return retval; + return count ? -EIO : 0; } /*----------------------------------------------------------------*/ @@ -850,7 +851,7 @@ rtc_cmos_int_handler = cmos_interrupt; retval = request_irq(rtc_irq, rtc_cmos_int_handler, - IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev), + 0, dev_name(&cmos_rtc.rtc->dev), cmos_rtc.rtc); if (retval < 0) { dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-ds1307.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-ds1307.c @@ -265,7 +265,11 @@ t->tm_min = bcd2bin(regs[DS1307_REG_MIN] & 0x7f); tmp = regs[DS1307_REG_HOUR] & 0x3f; t->tm_hour = bcd2bin(tmp); - t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1; + /* rx8130 is bit position, not BCD */ + if (ds1307->type == rx_8130) + t->tm_wday = fls(regs[DS1307_REG_WDAY] & 0x7f); + else + t->tm_wday = bcd2bin(regs[DS1307_REG_WDAY] & 0x07) - 1; t->tm_mday = bcd2bin(regs[DS1307_REG_MDAY] & 0x3f); tmp = regs[DS1307_REG_MONTH] & 0x1f; t->tm_mon = bcd2bin(tmp) - 1; @@ -312,7 +316,11 @@ regs[DS1307_REG_SECS] = bin2bcd(t->tm_sec); regs[DS1307_REG_MIN] = bin2bcd(t->tm_min); regs[DS1307_REG_HOUR] = bin2bcd(t->tm_hour); - regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); + /* rx8130 is bit position, not BCD */ + if (ds1307->type == rx_8130) + regs[DS1307_REG_WDAY] = 1 << t->tm_wday; + else + regs[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1); regs[DS1307_REG_MDAY] = bin2bcd(t->tm_mday); regs[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-ds1374.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-ds1374.c @@ -620,6 +620,10 @@ if (!ds1374) return -ENOMEM; + ds1374->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(ds1374->rtc)) + return PTR_ERR(ds1374->rtc); + ds1374->client = client; i2c_set_clientdata(client, ds1374); @@ -641,12 +645,11 @@ device_set_wakeup_capable(&client->dev, 1); } - ds1374->rtc = devm_rtc_device_register(&client->dev, client->name, - &ds1374_rtc_ops, THIS_MODULE); - if (IS_ERR(ds1374->rtc)) { - dev_err(&client->dev, "unable to register the class device\n"); - return PTR_ERR(ds1374->rtc); - } + ds1374->rtc->ops = &ds1374_rtc_ops; + + ret = rtc_register_device(ds1374->rtc); + if (ret) + return ret; #ifdef CONFIG_RTC_DRV_DS1374_WDT save_client = client; --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-ds1685.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-ds1685.c @@ -1437,7 +1437,7 @@ unreachable(); } } -EXPORT_SYMBOL(ds1685_rtc_poweroff); +EXPORT_SYMBOL_GPL(ds1685_rtc_poweroff); /* ----------------------------------------------------------------------- */ --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-ep93xx.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-ep93xx.c @@ -33,7 +33,7 @@ static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, unsigned short *delete) { - struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); + struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev); unsigned long comp; comp = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_SWCOMP); @@ -51,7 +51,7 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); + struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev); unsigned long time; time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA); @@ -62,7 +62,7 @@ static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); + struct ep93xx_rtc *ep93xx_rtc = dev_get_drvdata(dev); unsigned long secs = rtc_tm_to_time64(tm); writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-fsl-ftm-alarm.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-fsl-ftm-alarm.c @@ -316,6 +316,7 @@ { .compatible = "fsl,lx2160a-ftm-alarm", }, { }, }; +MODULE_DEVICE_TABLE(of, ftm_rtc_match); static struct platform_driver ftm_rtc_driver = { .probe = ftm_rtc_probe, --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-goldfish.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-goldfish.c @@ -73,6 +73,7 @@ rtc_alarm64 = rtc_tm_to_time64(&alrm->time) * NSEC_PER_SEC; writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH); writel(rtc_alarm64, base + TIMER_ALARM_LOW); + writel(1, base + TIMER_IRQ_ENABLED); } else { /* * if this function was called with enabled=0 --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-hym8563.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-hym8563.c @@ -97,7 +97,7 @@ if (!hym8563->valid) { dev_warn(&client->dev, "no valid clock/calendar values available\n"); - return -EPERM; + return -EINVAL; } ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-isl1208.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-isl1208.c @@ -743,14 +743,13 @@ { struct isl1208_state *isl1208 = priv; struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); - int ret; /* nvmem sanitizes offset/count for us, but count==0 is possible */ if (!count) return count; - ret = isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, + + return isl1208_i2c_read_regs(client, ISL1208_REG_USR1 + off, buf, count); - return ret == 0 ? count : ret; } static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf, @@ -758,15 +757,13 @@ { struct isl1208_state *isl1208 = priv; struct i2c_client *client = to_i2c_client(isl1208->rtc->dev.parent); - int ret; /* nvmem sanitizes off/count for us, but count==0 is possible */ if (!count) return count; - ret = isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, - count); - return ret == 0 ? count : ret; + return isl1208_i2c_set_regs(client, ISL1208_REG_USR1 + off, buf, + count); } static const struct nvmem_config isl1208_nvmem_config = { --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-max77686.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-max77686.c @@ -707,8 +707,8 @@ add_rtc_irq: ret = regmap_add_irq_chip(info->rtc_regmap, info->rtc_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT | - IRQF_SHARED, 0, info->drv_data->rtc_irq_chip, + IRQF_ONESHOT | IRQF_SHARED, + 0, info->drv_data->rtc_irq_chip, &info->rtc_irq_data); if (ret < 0) { dev_err(info->dev, "Failed to add RTC irq chip: %d\n", ret); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-mc13xxx.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-mc13xxx.c @@ -308,8 +308,10 @@ mc13xxx_unlock(mc13xxx); ret = rtc_register_device(priv->rtc); - if (ret) + if (ret) { + mc13xxx_lock(mc13xxx); goto err_irq_request; + } return 0; --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-mc146818-lib.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-mc146818-lib.c @@ -83,7 +83,7 @@ time->tm_year += real_year - 72; #endif - if (century > 20) + if (century > 19) time->tm_year += (century - 19) * 100; /* @@ -99,6 +99,17 @@ } EXPORT_SYMBOL_GPL(mc146818_get_time); +/* AMD systems don't allow access to AltCentury with DV1 */ +static bool apply_amd_register_a_behavior(void) +{ +#ifdef CONFIG_X86 + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) + return true; +#endif + return false; +} + /* Set the current date and time in the real time clock. */ int mc146818_set_time(struct rtc_time *time) { @@ -172,7 +183,10 @@ save_control = CMOS_READ(RTC_CONTROL); CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); save_freq_select = CMOS_READ(RTC_FREQ_SELECT); - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + if (apply_amd_register_a_behavior()) + CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT); + else + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); #ifdef CONFIG_MACH_DECSTATION CMOS_WRITE(real_yrs, RTC_DEC_YEAR); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-meson-vrtc.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-meson-vrtc.c @@ -23,7 +23,7 @@ struct timespec64 time; dev_dbg(dev, "%s\n", __func__); - ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); rtc_time64_to_tm(time.tv_sec, tm); return 0; @@ -101,7 +101,7 @@ long alarm_secs; struct timespec64 time; - ktime_get_raw_ts64(&time); + ktime_get_real_ts64(&time); local_time = time.tv_sec; dev_dbg(dev, "alarm_time = %lus, local_time=%lus\n", --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-msm6242.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-msm6242.c @@ -133,7 +133,8 @@ msm6242_read(priv, MSM6242_SECOND1); tm->tm_min = msm6242_read(priv, MSM6242_MINUTE10) * 10 + msm6242_read(priv, MSM6242_MINUTE1); - tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 + + tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10) & + MSM6242_HOUR10_HR_MASK) * 10 + msm6242_read(priv, MSM6242_HOUR1); tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 + msm6242_read(priv, MSM6242_DAY1); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-mt6397.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-mt6397.c @@ -47,6 +47,14 @@ #define RTC_AL_SEC 0x0018 +#define RTC_AL_SEC_MASK 0x003f +#define RTC_AL_MIN_MASK 0x003f +#define RTC_AL_HOU_MASK 0x001f +#define RTC_AL_DOM_MASK 0x001f +#define RTC_AL_DOW_MASK 0x0007 +#define RTC_AL_MTH_MASK 0x000f +#define RTC_AL_YEA_MASK 0x007f + #define RTC_PDN2 0x002e #define RTC_PDN2_PWRON_ALARM BIT(4) @@ -103,7 +111,7 @@ irqen = irqsta & ~RTC_IRQ_EN_AL; mutex_lock(&rtc->lock); if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, - irqen) < 0) + irqen) == 0) mtk_rtc_write_trigger(rtc); mutex_unlock(&rtc->lock); @@ -225,12 +233,12 @@ alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); mutex_unlock(&rtc->lock); - tm->tm_sec = data[RTC_OFFSET_SEC]; - tm->tm_min = data[RTC_OFFSET_MIN]; - tm->tm_hour = data[RTC_OFFSET_HOUR]; - tm->tm_mday = data[RTC_OFFSET_DOM]; - tm->tm_mon = data[RTC_OFFSET_MTH]; - tm->tm_year = data[RTC_OFFSET_YEAR]; + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; tm->tm_year += RTC_MIN_YEAR_OFFSET; tm->tm_mon--; @@ -251,14 +259,25 @@ tm->tm_year -= RTC_MIN_YEAR_OFFSET; tm->tm_mon++; - data[RTC_OFFSET_SEC] = tm->tm_sec; - data[RTC_OFFSET_MIN] = tm->tm_min; - data[RTC_OFFSET_HOUR] = tm->tm_hour; - data[RTC_OFFSET_DOM] = tm->tm_mday; - data[RTC_OFFSET_MTH] = tm->tm_mon; - data[RTC_OFFSET_YEAR] = tm->tm_year; - mutex_lock(&rtc->lock); + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) | + (tm->tm_sec & RTC_AL_SEC_MASK)); + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) | + (tm->tm_min & RTC_AL_MIN_MASK)); + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) | + (tm->tm_hour & RTC_AL_HOU_MASK)); + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) | + (tm->tm_mday & RTC_AL_DOM_MASK)); + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) | + (tm->tm_mon & RTC_AL_MTH_MASK)); + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) | + (tm->tm_year & RTC_AL_YEA_MASK)); + if (alm->enabled) { ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_AL_SEC, @@ -312,6 +331,8 @@ return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -EINVAL; rtc->addr_base = res->start; rtc->irq = platform_get_irq(pdev, 0); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-mxc_v2.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-mxc_v2.c @@ -337,8 +337,10 @@ } pdata->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(pdata->rtc)) + if (IS_ERR(pdata->rtc)) { + clk_disable_unprepare(pdata->clk); return PTR_ERR(pdata->rtc); + } pdata->rtc->ops = &mxc_rtc_ops; pdata->rtc->range_max = U32_MAX; @@ -373,6 +375,7 @@ { .compatible = "fsl,imx53-rtc", }, {} }; +MODULE_DEVICE_TABLE(of, mxc_ids); static struct platform_driver mxc_rtc_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-omap.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-omap.c @@ -26,6 +26,7 @@ #include #include #include +#include /* * The OMAP RTC is a year/month/day/hours/minutes/seconds BCD clock --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pcf2127.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pcf2127.c @@ -230,10 +230,8 @@ if (ret) return ret; - ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD, - val, bytes); - - return ret ?: bytes; + return regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_RD_CMD, + val, bytes); } static int pcf2127_nvmem_write(void *priv, unsigned int offset, @@ -248,10 +246,8 @@ if (ret) return ret; - ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, - val, bytes); - - return ret ?: bytes; + return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, + val, bytes); } /* watchdog driver */ --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pcf85063.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pcf85063.c @@ -159,10 +159,10 @@ if (ret) return ret; - alrm->time.tm_sec = bcd2bin(buf[0]); - alrm->time.tm_min = bcd2bin(buf[1]); - alrm->time.tm_hour = bcd2bin(buf[2]); - alrm->time.tm_mday = bcd2bin(buf[3]); + alrm->time.tm_sec = bcd2bin(buf[0] & 0x7f); + alrm->time.tm_min = bcd2bin(buf[1] & 0x7f); + alrm->time.tm_hour = bcd2bin(buf[2] & 0x3f); + alrm->time.tm_mday = bcd2bin(buf[3] & 0x3f); ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val); if (ret) @@ -332,7 +332,16 @@ static int pcf85063_nvmem_read(void *priv, unsigned int offset, void *val, size_t bytes) { - return regmap_read(priv, PCF85063_REG_RAM, val); + unsigned int tmp; + int ret; + + ret = regmap_read(priv, PCF85063_REG_RAM, &tmp); + if (ret < 0) + return ret; + + *(u8 *)val = tmp; + + return 0; } static int pcf85063_nvmem_write(void *priv, unsigned int offset, --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pcf85363.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pcf85363.c @@ -407,7 +407,7 @@ if (client->irq > 0) { regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, - PIN_IO_INTA_OUT, PIN_IO_INTAPM); + PIN_IO_INTAPM, PIN_IO_INTA_OUT); ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf85363_rtc_handle_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pic32.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pic32.c @@ -326,16 +326,16 @@ spin_lock_init(&pdata->alarm_lock); + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); + clk_prepare_enable(pdata->clk); pic32_rtc_enable(pdata, 1); device_init_wakeup(&pdev->dev, 1); - pdata->rtc = devm_rtc_allocate_device(&pdev->dev); - if (IS_ERR(pdata->rtc)) - return PTR_ERR(pdata->rtc); - pdata->rtc->ops = &pic32_rtcops; pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; pdata->rtc->range_max = RTC_TIMESTAMP_END_2099; --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pl031.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pl031.c @@ -379,8 +379,10 @@ device_init_wakeup(&adev->dev, true); ldata->rtc = devm_rtc_allocate_device(&adev->dev); - if (IS_ERR(ldata->rtc)) - return PTR_ERR(ldata->rtc); + if (IS_ERR(ldata->rtc)) { + ret = PTR_ERR(ldata->rtc); + goto out; + } ldata->rtc->ops = ops; --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pm8xxx.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pm8xxx.c @@ -219,7 +219,6 @@ { int rc, i; u8 value[NUM_8_BIT_RTC_REGS]; - unsigned int ctrl_reg; unsigned long secs, irq_flags; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; @@ -231,6 +230,11 @@ secs >>= 8; } + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, 0); + if (rc) + return rc; + spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, @@ -240,19 +244,11 @@ goto rtc_rw_fail; } - rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); - if (rc) - goto rtc_rw_fail; - - if (alarm->enabled) - ctrl_reg |= regs->alarm_en; - else - ctrl_reg &= ~regs->alarm_en; - - rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); - if (rc) { - dev_err(dev, "Write to RTC alarm control register failed\n"); - goto rtc_rw_fail; + if (alarm->enabled) { + rc = regmap_update_bits(rtc_dd->regmap, regs->alarm_ctrl, + regs->alarm_en, regs->alarm_en); + if (rc) + goto rtc_rw_fail; } dev_dbg(dev, "Alarm Set for h:m:s=%ptRt, y-m-d=%ptRdr\n", --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-pxa.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-pxa.c @@ -330,6 +330,10 @@ if (sa1100_rtc->irq_alarm < 0) return -ENXIO; + sa1100_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(sa1100_rtc->rtc)) + return PTR_ERR(sa1100_rtc->rtc); + pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start, resource_size(pxa_rtc->ress)); if (!pxa_rtc->base) { --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-rv3028.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-rv3028.c @@ -625,6 +625,8 @@ return -ENOMEM; rv3028->regmap = devm_regmap_init_i2c(client, ®map_config); + if (IS_ERR(rv3028->regmap)) + return PTR_ERR(rv3028->regmap); i2c_set_clientdata(client, rv3028); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-rx8010.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-rx8010.c @@ -424,16 +424,26 @@ } } -static struct rtc_class_ops rx8010_rtc_ops = { +static const struct rtc_class_ops rx8010_rtc_ops_default = { .read_time = rx8010_get_time, .set_time = rx8010_set_time, .ioctl = rx8010_ioctl, }; +static const struct rtc_class_ops rx8010_rtc_ops_alarm = { + .read_time = rx8010_get_time, + .set_time = rx8010_set_time, + .ioctl = rx8010_ioctl, + .read_alarm = rx8010_read_alarm, + .set_alarm = rx8010_set_alarm, + .alarm_irq_enable = rx8010_alarm_irq_enable, +}; + static int rx8010_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = client->adapter; + const struct rtc_class_ops *rtc_ops; struct rx8010_data *rx8010; int err = 0; @@ -464,16 +474,16 @@ if (err) { dev_err(&client->dev, "unable to request IRQ\n"); - client->irq = 0; - } else { - rx8010_rtc_ops.read_alarm = rx8010_read_alarm; - rx8010_rtc_ops.set_alarm = rx8010_set_alarm; - rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable; + return err; } + + rtc_ops = &rx8010_rtc_ops_alarm; + } else { + rtc_ops = &rx8010_rtc_ops_default; } rx8010->rtc = devm_rtc_device_register(&client->dev, client->name, - &rx8010_rtc_ops, THIS_MODULE); + rtc_ops, THIS_MODULE); if (IS_ERR(rx8010->rtc)) { dev_err(&client->dev, "unable to register the class device\n"); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-sa1100.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-sa1100.c @@ -182,7 +182,6 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) { - struct rtc_device *rtc; int ret; spin_lock_init(&info->lock); @@ -211,15 +210,14 @@ writel_relaxed(0, info->rcnr); } - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { + info->rtc->ops = &sa1100_rtc_ops; + info->rtc->max_user_freq = RTC_FREQ; + + ret = rtc_register_device(info->rtc); + if (ret) { clk_disable_unprepare(info->clk); - return PTR_ERR(rtc); + return ret; } - info->rtc = rtc; - - rtc->max_user_freq = RTC_FREQ; /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). @@ -268,6 +266,10 @@ info->irq_1hz = irq_1hz; info->irq_alarm = irq_alarm; + info->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc)) + return PTR_ERR(info->rtc); + ret = devm_request_irq(&pdev->dev, irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", &pdev->dev); if (ret) { --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-snvs.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-snvs.c @@ -33,6 +33,14 @@ #define SNVS_LPPGDR_INIT 0x41736166 #define CNTR_TO_SECS_SH 15 +/* The maximum RTC clock cycles that are allowed to pass between two + * consecutive clock counter register reads. If the values are corrupted a + * bigger difference is expected. The RTC frequency is 32kHz. With 320 cycles + * we end at 10ms which should be enough for most cases. If it once takes + * longer than expected we do a retry. + */ +#define MAX_RTC_READ_DIFF_CYCLES 320 + struct snvs_rtc_data { struct rtc_device *rtc; struct regmap *regmap; @@ -57,6 +65,7 @@ static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) { u64 read1, read2; + s64 diff; unsigned int timeout = 100; /* As expected, the registers might update between the read of the LSB @@ -67,7 +76,8 @@ do { read2 = read1; read1 = rtc_read_lpsrt(data); - } while (read1 != read2 && --timeout); + diff = read1 - read2; + } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); if (!timeout) dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); @@ -79,13 +89,15 @@ static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb) { u32 count1, count2; + s32 diff; unsigned int timeout = 100; regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); do { count2 = count1; regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); - } while (count1 != count2 && --timeout); + diff = count1 - count2; + } while (((diff < 0) || (diff > MAX_RTC_READ_DIFF_CYCLES)) && --timeout); if (!timeout) { dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); return -ETIMEDOUT; --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-st-lpc.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-st-lpc.c @@ -221,17 +221,16 @@ return -EINVAL; } - ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, 0, - pdev->name, rtc); + ret = devm_request_irq(&pdev->dev, rtc->irq, st_rtc_handler, + IRQF_NO_AUTOEN, pdev->name, rtc); if (ret) { dev_err(&pdev->dev, "Failed to request irq %i\n", rtc->irq); return ret; } enable_irq_wake(rtc->irq); - disable_irq(rtc->irq); - rtc->clk = clk_get(&pdev->dev, NULL); + rtc->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(rtc->clk)) { dev_err(&pdev->dev, "Unable to request clock\n"); return PTR_ERR(rtc->clk); @@ -241,6 +240,7 @@ rtc->clkrate = clk_get_rate(rtc->clk); if (!rtc->clkrate) { + clk_disable_unprepare(rtc->clk); dev_err(&pdev->dev, "Unable to fetch clock rate\n"); return -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-stm32.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-stm32.c @@ -756,7 +756,7 @@ ret = clk_prepare_enable(rtc->rtc_ck); if (ret) - goto err; + goto err_no_rtc_ck; if (rtc->data->need_dbp) regmap_update_bits(rtc->dbp, rtc->dbp_reg, @@ -832,10 +832,12 @@ } return 0; + err: + clk_disable_unprepare(rtc->rtc_ck); +err_no_rtc_ck: if (rtc->data->has_pclk) clk_disable_unprepare(rtc->pclk); - clk_disable_unprepare(rtc->rtc_ck); if (rtc->data->need_dbp) regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-sun6i.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-sun6i.c @@ -129,7 +129,6 @@ unsigned int fixed_prescaler : 16; unsigned int has_prescaler : 1; unsigned int has_out_clk : 1; - unsigned int export_iosc : 1; unsigned int has_losc_en : 1; unsigned int has_auto_swt : 1; }; @@ -251,23 +250,19 @@ writel(reg, rtc->base + SUN6I_LOSC_CTRL); } - /* Switch to the external, more precise, oscillator */ - reg |= SUN6I_LOSC_CTRL_EXT_OSC; - if (rtc->data->has_losc_en) - reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + /* Switch to the external, more precise, oscillator, if present */ + if (of_get_property(node, "clocks", NULL)) { + reg |= SUN6I_LOSC_CTRL_EXT_OSC; + if (rtc->data->has_losc_en) + reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + } writel(reg, rtc->base + SUN6I_LOSC_CTRL); /* Yes, I know, this is ugly. */ sun6i_rtc = rtc; - /* Deal with old DTs */ - if (!of_get_property(node, "clocks", NULL)) - goto err; - - /* Only read IOSC name from device tree if it is exported */ - if (rtc->data->export_iosc) - of_property_read_string_index(node, "clock-output-names", 2, - &iosc_name); + of_property_read_string_index(node, "clock-output-names", 2, + &iosc_name); rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL, iosc_name, @@ -276,15 +271,17 @@ 300000000); if (IS_ERR(rtc->int_osc)) { pr_crit("Couldn't register the internal oscillator\n"); - return; + goto err; } parents[0] = clk_hw_get_name(rtc->int_osc); + /* If there is no external oscillator, this will be NULL and ... */ parents[1] = of_clk_get_parent_name(node, 0); rtc->hw.init = &init; init.parent_names = parents; + /* ... number of clock parents will be 1. */ init.num_parents = of_clk_get_parent_count(node) + 1; of_property_read_string_index(node, "clock-output-names", 0, &init.name); @@ -292,7 +289,7 @@ rtc->losc = clk_register(NULL, &rtc->hw); if (IS_ERR(rtc->losc)) { pr_crit("Couldn't register the LOSC clock\n"); - return; + goto err_register; } of_property_read_string_index(node, "clock-output-names", 1, @@ -303,19 +300,18 @@ &rtc->lock); if (IS_ERR(rtc->ext_losc)) { pr_crit("Couldn't register the LOSC external gate\n"); - return; + goto err_register; } - clk_data->num = 2; + clk_data->num = 3; clk_data->hws[0] = &rtc->hw; clk_data->hws[1] = __clk_get_hw(rtc->ext_losc); - if (rtc->data->export_iosc) { - clk_data->hws[2] = rtc->int_osc; - clk_data->num = 3; - } + clk_data->hws[2] = rtc->int_osc; of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); return; +err_register: + clk_hw_unregister_fixed_rate(rtc->int_osc); err: kfree(clk_data); } @@ -350,7 +346,6 @@ .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, }; static void __init sun8i_h3_rtc_clk_init(struct device_node *node) @@ -368,7 +363,6 @@ .fixed_prescaler = 32, .has_prescaler = 1, .has_out_clk = 1, - .export_iosc = 1, .has_losc_en = 1, .has_auto_swt = 1, }; @@ -380,6 +374,22 @@ CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", sun50i_h6_rtc_clk_init); +/* + * The R40 user manual is self-conflicting on whether the prescaler is + * fixed or configurable. The clock diagram shows it as fixed, but there + * is also a configurable divider in the RTC block. + */ +static const struct sun6i_rtc_clk_data sun8i_r40_rtc_data = { + .rc_osc_rate = 16000000, + .fixed_prescaler = 512, +}; +static void __init sun8i_r40_rtc_clk_init(struct device_node *node) +{ + sun6i_rtc_clk_init(node, &sun8i_r40_rtc_data); +} +CLK_OF_DECLARE_DRIVER(sun8i_r40_rtc_clk, "allwinner,sun8i-r40-rtc", + sun8i_r40_rtc_clk_init); + static const struct sun6i_rtc_clk_data sun8i_v3_rtc_data = { .rc_osc_rate = 32000, .has_out_clk = 1, --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-tps65910.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-tps65910.c @@ -460,6 +460,6 @@ }; module_platform_driver(tps65910_rtc_driver); -MODULE_ALIAS("platform:rtc-tps65910"); +MODULE_ALIAS("platform:tps65910-rtc"); MODULE_AUTHOR("Venu Byravarasu "); MODULE_LICENSE("GPL"); --- linux-oracle-5.4.0.orig/drivers/rtc/rtc-wm8350.c +++ linux-oracle-5.4.0/drivers/rtc/rtc-wm8350.c @@ -432,14 +432,21 @@ return ret; } - wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, + ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350_rtc_update_handler, 0, "RTC Seconds", wm8350); + if (ret) + return ret; + wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); - wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, + ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350_rtc_alarm_handler, 0, "RTC Alarm", wm8350); + if (ret) { + wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); + return ret; + } return 0; } --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd.c @@ -178,6 +178,8 @@ (unsigned long) block); INIT_LIST_HEAD(&block->ccw_queue); spin_lock_init(&block->queue_lock); + INIT_LIST_HEAD(&block->format_list); + spin_lock_init(&block->format_lock); timer_setup(&block->timer, dasd_block_timeout, 0); spin_lock_init(&block->profile.lock); @@ -735,18 +737,20 @@ * we count each request only once. */ device = cqr->startdev; - if (device->profile.data) { - counter = 1; /* request is not yet queued on the start device */ - list_for_each(l, &device->ccw_queue) - if (++counter >= 31) - break; - } + if (!device->profile.data) + return; + + spin_lock(get_ccwdev_lock(device->cdev)); + counter = 1; /* request is not yet queued on the start device */ + list_for_each(l, &device->ccw_queue) + if (++counter >= 31) + break; + spin_unlock(get_ccwdev_lock(device->cdev)); + spin_lock(&device->profile.lock); - if (device->profile.data) { - device->profile.data->dasd_io_nr_req[counter]++; - if (rq_data_dir(req) == READ) - device->profile.data->dasd_read_nr_req[counter]++; - } + device->profile.data->dasd_io_nr_req[counter]++; + if (rq_data_dir(req) == READ) + device->profile.data->dasd_read_nr_req[counter]++; spin_unlock(&device->profile.lock); } @@ -1460,6 +1464,13 @@ if (!cqr->lpm) cqr->lpm = dasd_path_get_opm(device); } + /* + * remember the amount of formatted tracks to prevent double format on + * ESE devices + */ + if (cqr->block) + cqr->trkcount = atomic_read(&cqr->block->trkcount); + if (cqr->cpmode == 1) { rc = ccw_device_tm_start(device->cdev, cqr->cpaddr, (long) cqr, cqr->lpm); @@ -1654,9 +1665,15 @@ if (!sense) return 0; - return !!(sense[1] & SNS1_NO_REC_FOUND) || - !!(sense[1] & SNS1_FILE_PROTECTED) || - scsw_cstat(&irb->scsw) == SCHN_STAT_INCORR_LEN; + if (sense[1] & SNS1_NO_REC_FOUND) + return 1; + + if ((sense[1] & SNS1_INV_TRACK_FORMAT) && + scsw_is_tm(&irb->scsw) && + !(sense[2] & SNS2_ENV_DATA_PRESENT)) + return 1; + + return 0; } static int dasd_ese_oos_cond(u8 *sense) @@ -1677,7 +1694,8 @@ struct dasd_device *device; unsigned long now; int nrf_suppressed = 0; - int fp_suppressed = 0; + int it_suppressed = 0; + struct request *req; u8 *sense = NULL; int expires; @@ -1731,8 +1749,9 @@ */ sense = dasd_get_sense(irb); if (sense) { - fp_suppressed = (sense[1] & SNS1_FILE_PROTECTED) && - test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); + it_suppressed = (sense[1] & SNS1_INV_TRACK_FORMAT) && + !(sense[2] & SNS2_ENV_DATA_PRESENT) && + test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); nrf_suppressed = (sense[1] & SNS1_NO_REC_FOUND) && test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); @@ -1747,7 +1766,7 @@ return; } } - if (!(fp_suppressed || nrf_suppressed)) + if (!(it_suppressed || nrf_suppressed)) device->discipline->dump_sense_dbf(device, irb, "int"); if (device->features & DASD_FEATURE_ERPLOG) @@ -1778,21 +1797,32 @@ } if (dasd_ese_needs_format(cqr->block, irb)) { - if (rq_data_dir((struct request *)cqr->callback_data) == READ) { - device->discipline->ese_read(cqr); + req = dasd_get_callback_data(cqr); + if (!req) { + cqr->status = DASD_CQR_ERROR; + return; + } + if (rq_data_dir(req) == READ) { + device->discipline->ese_read(cqr, irb); cqr->status = DASD_CQR_SUCCESS; cqr->stopclk = now; dasd_device_clear_timer(device); dasd_schedule_device_bh(device); return; } - fcqr = device->discipline->ese_format(device, cqr); + fcqr = device->discipline->ese_format(device, cqr, irb); if (IS_ERR(fcqr)) { + if (PTR_ERR(fcqr) == -EINVAL) { + cqr->status = DASD_CQR_ERROR; + return; + } /* * If we can't format now, let the request go * one extra round. Maybe we can format later. */ cqr->status = DASD_CQR_QUEUED; + dasd_schedule_device_bh(device); + return; } else { fcqr->status = DASD_CQR_QUEUED; cqr->status = DASD_CQR_QUEUED; @@ -2107,8 +2137,8 @@ if (device->stopped & ~(DASD_STOPPED_DC_WAIT | DASD_UNRESUMED_PM)) return; - rc = device->discipline->verify_path(device, - dasd_path_get_tbvpm(device)); + rc = device->discipline->pe_handler(device, + dasd_path_get_tbvpm(device)); if (rc) dasd_device_set_timer(device, 50); else @@ -2490,14 +2520,17 @@ rc = 0; list_for_each_entry_safe(cqr, n, ccw_queue, blocklist) { /* - * In some cases the 'File Protected' or 'Incorrect Length' - * error might be expected and error recovery would be - * unnecessary in these cases. Check if the according suppress - * bit is set. + * In some cases certain errors might be expected and + * error recovery would be unnecessary in these cases. + * Check if the according suppress bit is set. */ sense = dasd_get_sense(&cqr->irb); - if (sense && sense[1] & SNS1_FILE_PROTECTED && - test_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags)) + if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) && + !(sense[2] & SNS2_ENV_DATA_PRESENT) && + test_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags)) + continue; + if (sense && (sense[1] & SNS1_NO_REC_FOUND) && + test_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags)) continue; if (scsw_cstat(&cqr->irb.scsw) == 0x40 && test_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags)) @@ -2748,11 +2781,13 @@ { struct request *req; blk_status_t error = BLK_STS_OK; + unsigned int proc_bytes; int status; req = (struct request *) cqr->callback_data; dasd_profile_end(cqr->block, cqr, req); + proc_bytes = cqr->proc_bytes; status = cqr->block->base->discipline->free_cp(cqr, req); if (status < 0) error = errno_to_blk_status(status); @@ -2783,7 +2818,17 @@ blk_mq_end_request(req, error); blk_mq_run_hw_queues(req->q, true); } else { - blk_mq_complete_request(req); + /* + * Partial completed requests can happen with ESE devices. + * During read we might have gotten a NRF error and have to + * complete a request partially. + */ + if (proc_bytes) { + blk_update_request(req, BLK_STS_OK, proc_bytes); + blk_mq_requeue_request(req, true); + } else if (likely(!blk_should_fake_timeout(req->q))) { + blk_mq_complete_request(req); + } } } @@ -2952,35 +2997,32 @@ * Requeue a request back to the block request queue * only works for block requests */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) +static void _dasd_requeue_request(struct dasd_ccw_req *cqr) { - struct dasd_block *block = cqr->block; struct request *req; - if (!block) - return -EINVAL; + /* + * If the request is an ERP request there is nothing to requeue. + * This will be done with the remaining original request. + */ + if (cqr->refers) + return; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; - blk_mq_requeue_request(req, false); + blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock); - return 0; + return; } -/* - * Go through all request on the dasd_block request queue, cancel them - * on the respective dasd_device, and return them to the generic - * block layer. - */ -static int dasd_flush_block_queue(struct dasd_block *block) +static int _dasd_requests_to_flushqueue(struct dasd_block *block, + struct list_head *flush_queue) { struct dasd_ccw_req *cqr, *n; - int rc, i; - struct list_head flush_queue; unsigned long flags; + int rc, i; - INIT_LIST_HEAD(&flush_queue); - spin_lock_bh(&block->queue_lock); + spin_lock_irqsave(&block->queue_lock, flags); rc = 0; restart: list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { @@ -2995,13 +3037,32 @@ * is returned from the dasd_device layer. */ cqr->callback = _dasd_wake_block_flush_cb; - for (i = 0; cqr != NULL; cqr = cqr->refers, i++) - list_move_tail(&cqr->blocklist, &flush_queue); + for (i = 0; cqr; cqr = cqr->refers, i++) + list_move_tail(&cqr->blocklist, flush_queue); if (i > 1) /* moved more than one request - need to restart */ goto restart; } - spin_unlock_bh(&block->queue_lock); + spin_unlock_irqrestore(&block->queue_lock, flags); + + return rc; +} + +/* + * Go through all request on the dasd_block request queue, cancel them + * on the respective dasd_device, and return them to the generic + * block layer. + */ +static int dasd_flush_block_queue(struct dasd_block *block) +{ + struct dasd_ccw_req *cqr, *n; + struct list_head flush_queue; + unsigned long flags; + int rc; + + INIT_LIST_HEAD(&flush_queue); + rc = _dasd_requests_to_flushqueue(block, &flush_queue); + /* Now call the callback function of flushed requests */ restart_cb: list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { @@ -3060,7 +3121,8 @@ basedev = block->base; spin_lock_irq(&dq->lock); - if (basedev->state < DASD_STATE_READY) { + if (basedev->state < DASD_STATE_READY || + test_bit(DASD_FLAG_OFFLINE, &basedev->flags)) { DBF_DEV_EVENT(DBF_ERR, basedev, "device not ready for request %p", req); rc = BLK_STS_IOERR; @@ -3495,8 +3557,6 @@ struct dasd_device *device; struct dasd_block *block; - cdev->handler = NULL; - device = dasd_device_from_cdev(cdev); if (IS_ERR(device)) { dasd_remove_sysfs_files(cdev); @@ -3515,6 +3575,7 @@ * no quite down yet. */ dasd_set_target_state(device, DASD_STATE_NEW); + cdev->handler = NULL; /* dasd_delete_device destroys the device reference. */ block = device->block; dasd_delete_device(device); @@ -3938,75 +3999,36 @@ */ static int dasd_generic_requeue_all_requests(struct dasd_device *device) { + struct dasd_block *block = device->block; struct list_head requeue_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc; - INIT_LIST_HEAD(&requeue_queue); - spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = 0; - list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { - /* Check status and move request to flush_queue */ - if (cqr->status == DASD_CQR_IN_IO) { - rc = device->discipline->term_IO(cqr); - if (rc) { - /* unable to terminate requeust */ - dev_err(&device->cdev->dev, - "Unable to terminate request %p " - "on suspend\n", cqr); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - dasd_put_device(device); - return rc; - } - } - list_move_tail(&cqr->devlist, &requeue_queue); - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - - list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) { - wait_event(dasd_flush_wq, - (cqr->status != DASD_CQR_CLEAR_PENDING)); + if (!block) + return 0; - /* - * requeue requests to blocklayer will only work - * for block device requests - */ - if (_dasd_requeue_request(cqr)) - continue; + INIT_LIST_HEAD(&requeue_queue); + rc = _dasd_requests_to_flushqueue(block, &requeue_queue); - /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; + /* Now call the callback function of flushed requests */ +restart_cb: + list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) { + wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); + /* Process finished ERP request. */ + if (cqr->refers) { + spin_lock_bh(&block->queue_lock); + __dasd_process_erp(block->base, cqr); + spin_unlock_bh(&block->queue_lock); + /* restart list_for_xx loop since dasd_process_erp + * might remove multiple elements + */ + goto restart_cb; } - - /* - * _dasd_requeue_request already checked for a valid - * blockdevice, no need to check again - * all erp requests (cqr->refers) have a cqr->block - * pointer copy from the original cqr - */ + _dasd_requeue_request(cqr); list_del_init(&cqr->blocklist); cqr->block->base->discipline->free_cp( cqr, (struct request *) cqr->callback_data); } - - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&requeue_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(device->cdev)); - list_splice_tail(&requeue_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - } dasd_schedule_device_bh(device); return rc; } --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_3990_erp.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_3990_erp.c @@ -1401,14 +1401,8 @@ struct dasd_device *device = erp->startdev; - /* - * In some cases the 'File Protected' error might be expected and - * log messages shouldn't be written then. - * Check if the according suppress bit is set. - */ - if (!test_bit(DASD_CQR_SUPPRESS_FP, &erp->flags)) - dev_err(&device->cdev->dev, - "Accessing the DASD failed because of a hardware error\n"); + dev_err(&device->cdev->dev, + "Accessing the DASD failed because of a hardware error\n"); return dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); @@ -2436,7 +2430,7 @@ erp->block = cqr->block; erp->magic = cqr->magic; erp->expires = cqr->expires; - erp->retries = 256; + erp->retries = device->default_retries; erp->buildclk = get_tod_clock(); erp->status = DASD_CQR_FILLED; --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_alias.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_alias.c @@ -256,7 +256,6 @@ return; device->discipline->get_uid(device, &uid); spin_lock_irqsave(&lcu->lock, flags); - list_del_init(&device->alias_list); /* make sure that the workers don't use this device */ if (device == lcu->suc_data.device) { spin_unlock_irqrestore(&lcu->lock, flags); @@ -283,6 +282,7 @@ spin_lock_irqsave(&aliastree.lock, flags); spin_lock(&lcu->lock); + list_del_init(&device->alias_list); if (list_empty(&lcu->grouplist) && list_empty(&lcu->active_devices) && list_empty(&lcu->inactive_devices)) { @@ -462,11 +462,19 @@ spin_unlock_irqrestore(&lcu->lock, flags); rc = dasd_sleep_on(cqr); - if (rc && !suborder_not_supported(cqr)) { + if (!rc) + goto out; + + if (suborder_not_supported(cqr)) { + /* suborder not supported or device unusable for IO */ + rc = -EOPNOTSUPP; + } else { + /* IO failed but should be retried */ spin_lock_irqsave(&lcu->lock, flags); lcu->flags |= NEED_UAC_UPDATE; spin_unlock_irqrestore(&lcu->lock, flags); } +out: dasd_sfree_request(cqr, cqr->memdev); return rc; } @@ -503,6 +511,14 @@ return rc; spin_lock_irqsave(&lcu->lock, flags); + /* + * there is another update needed skip the remaining handling + * the data might already be outdated + * but especially do not add the device to an LCU with pending + * update + */ + if (lcu->flags & NEED_UAC_UPDATE) + goto out; lcu->pav = NO_PAV; for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) { switch (lcu->uac->unit[i].ua_type) { @@ -521,6 +537,7 @@ alias_list) { _add_device_to_lcu(lcu, device, refdev); } +out: spin_unlock_irqrestore(&lcu->lock, flags); return 0; } @@ -625,6 +642,7 @@ } if (lcu->flags & UPDATE_PENDING) { list_move(&device->alias_list, &lcu->active_devices); + private->pavgroup = NULL; _schedule_lcu_update(lcu, device); } spin_unlock_irqrestore(&lcu->lock, flags); @@ -657,12 +675,12 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device) { struct dasd_eckd_private *alias_priv, *private = base_device->private; - struct alias_pav_group *group = private->pavgroup; struct alias_lcu *lcu = private->lcu; struct dasd_device *alias_device; + struct alias_pav_group *group; unsigned long flags; - if (!group || !lcu) + if (!lcu) return NULL; if (lcu->pav == NO_PAV || lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING)) @@ -679,6 +697,11 @@ } spin_lock_irqsave(&lcu->lock, flags); + group = private->pavgroup; + if (!group) { + spin_unlock_irqrestore(&lcu->lock, flags); + return NULL; + } alias_device = group->next; if (!alias_device) { if (list_empty(&group->aliaslist)) { --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_diag.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_diag.c @@ -58,7 +58,7 @@ struct dasd_diag_req { unsigned int block_count; - struct dasd_diag_bio bio[0]; + struct dasd_diag_bio bio[]; }; static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ @@ -319,7 +319,7 @@ struct dasd_diag_characteristics *rdc_data; struct vtoc_cms_label *label; struct dasd_block *block; - struct dasd_diag_bio bio; + struct dasd_diag_bio *bio; unsigned int sb, bsize; blocknum_t end_block; int rc; @@ -395,29 +395,36 @@ rc = -ENOMEM; goto out; } + bio = kzalloc(sizeof(*bio), GFP_KERNEL); + if (bio == NULL) { + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "No memory to allocate initialization bio"); + rc = -ENOMEM; + goto out_label; + } rc = 0; end_block = 0; /* try all sizes - needed for ECKD devices */ for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { mdsk_init_io(device, bsize, 0, &end_block); - memset(&bio, 0, sizeof (struct dasd_diag_bio)); - bio.type = MDSK_READ_REQ; - bio.block_number = private->pt_block + 1; - bio.buffer = label; + memset(bio, 0, sizeof(*bio)); + bio->type = MDSK_READ_REQ; + bio->block_number = private->pt_block + 1; + bio->buffer = label; memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io)); private->iob.dev_nr = rdc_data->dev_nr; private->iob.key = 0; private->iob.flags = 0; /* do synchronous io */ private->iob.block_count = 1; private->iob.interrupt_params = 0; - private->iob.bio_list = &bio; + private->iob.bio_list = bio; private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; rc = dia250(&private->iob, RW_BIO); if (rc == 3) { pr_warn("%s: A 64-bit DIAG call failed\n", dev_name(&device->cdev->dev)); rc = -EOPNOTSUPP; - goto out_label; + goto out_bio; } mdsk_term_io(device); if (rc == 0) @@ -427,7 +434,7 @@ pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n", dev_name(&device->cdev->dev), rc); rc = -EIO; - goto out_label; + goto out_bio; } /* check for label block */ if (memcmp(label->label_id, DASD_DIAG_CMS1, @@ -457,6 +464,8 @@ (rc == 4) ? ", read-only device" : ""); rc = 0; } +out_bio: + kfree(bio); out_label: free_page((long) label); out: @@ -635,12 +644,17 @@ blk_queue_segment_boundary(q, PAGE_SIZE - 1); } +static int dasd_diag_pe_handler(struct dasd_device *device, __u8 tbvpm) +{ + return dasd_generic_verify_path(device, tbvpm); +} + static struct dasd_discipline dasd_diag_discipline = { .owner = THIS_MODULE, .name = "DIAG", .ebcname = "DIAG", .check_device = dasd_diag_check_device, - .verify_path = dasd_generic_verify_path, + .pe_handler = dasd_diag_pe_handler, .fill_geometry = dasd_diag_fill_geometry, .setup_blk_queue = dasd_diag_setup_blk_queue, .start_IO = dasd_start_diag, --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_eckd.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_eckd.c @@ -103,7 +103,7 @@ }; /* definitions for the path verification worker */ -struct path_verification_work_data { +struct pe_handler_work_data { struct work_struct worker; struct dasd_device *device; struct dasd_ccw_req cqr; @@ -112,8 +112,8 @@ int isglobal; __u8 tbvpm; }; -static struct path_verification_work_data *path_verification_worker; -static DEFINE_MUTEX(dasd_path_verification_mutex); +static struct pe_handler_work_data *pe_handler_worker; +static DEFINE_MUTEX(dasd_pe_handler_mutex); struct check_attention_work_data { struct work_struct worker; @@ -207,6 +207,45 @@ geo->head |= head; } +/* + * calculate failing track from sense data depending if + * it is an EAV device or not + */ +static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device, + sector_t *track) +{ + struct dasd_eckd_private *private = device->private; + u8 *sense = NULL; + u32 cyl; + u8 head; + + sense = dasd_get_sense(irb); + if (!sense) { + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "ESE error no sense data\n"); + return -EINVAL; + } + if (!(sense[27] & DASD_SENSE_BIT_2)) { + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "ESE error no valid track data\n"); + return -EINVAL; + } + + if (sense[27] & DASD_SENSE_BIT_3) { + /* enhanced addressing */ + cyl = sense[30] << 20; + cyl |= (sense[31] & 0xF0) << 12; + cyl |= sense[28] << 8; + cyl |= sense[29]; + } else { + cyl = sense[29] << 8; + cyl |= sense[30]; + } + head = sense[31] & 0x0F; + *track = cyl * private->rdc_data.trk_per_cyl + head; + return 0; +} + static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, struct dasd_device *device) { @@ -1128,7 +1167,8 @@ { struct dasd_eckd_private *private = device->private; int fcx_in_css, fcx_in_gneq, fcx_in_features; - int tpm, mdc; + unsigned int mdc; + int tpm; if (dasd_nofcx) return 0; @@ -1142,7 +1182,7 @@ return 0; mdc = ccw_device_get_mdc(device->cdev, 0); - if (mdc < 0) { + if (mdc == 0) { dev_warn(&device->cdev->dev, "Detecting the maximum supported data size for zHPF requests failed\n"); return 0; } else { @@ -1153,12 +1193,12 @@ static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) { struct dasd_eckd_private *private = device->private; - int mdc; + unsigned int mdc; u32 fcx_max_data; if (private->fcx_max_data) { mdc = ccw_device_get_mdc(device->cdev, lpm); - if ((mdc < 0)) { + if (mdc == 0) { dev_warn(&device->cdev->dev, "Detecting the maximum data size for zHPF " "requests failed (rc=%d) for a new path %x\n", @@ -1179,7 +1219,7 @@ } static int rebuild_device_uid(struct dasd_device *device, - struct path_verification_work_data *data) + struct pe_handler_work_data *data) { struct dasd_eckd_private *private = device->private; __u8 lpm, opm = dasd_path_get_opm(device); @@ -1217,10 +1257,9 @@ return rc; } -static void do_path_verification_work(struct work_struct *work) +static void dasd_eckd_path_available_action(struct dasd_device *device, + struct pe_handler_work_data *data) { - struct path_verification_work_data *data; - struct dasd_device *device; struct dasd_eckd_private path_private; struct dasd_uid *uid; __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; @@ -1229,19 +1268,6 @@ char print_uid[60]; int rc; - data = container_of(work, struct path_verification_work_data, worker); - device = data->device; - - /* delay path verification until device was resumed */ - if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { - schedule_work(work); - return; - } - /* check if path verification already running and delay if so */ - if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { - schedule_work(work); - return; - } opm = 0; npm = 0; ppm = 0; @@ -1378,30 +1404,54 @@ dasd_path_add_nohpfpm(device, hpfpm); spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); } +} + +static void do_pe_handler_work(struct work_struct *work) +{ + struct pe_handler_work_data *data; + struct dasd_device *device; + + data = container_of(work, struct pe_handler_work_data, worker); + device = data->device; + + /* delay path verification until device was resumed */ + if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) { + schedule_work(work); + return; + } + /* check if path verification already running and delay if so */ + if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) { + schedule_work(work); + return; + } + + dasd_eckd_path_available_action(device, data); + clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags); dasd_put_device(device); if (data->isglobal) - mutex_unlock(&dasd_path_verification_mutex); + mutex_unlock(&dasd_pe_handler_mutex); else kfree(data); } -static int dasd_eckd_verify_path(struct dasd_device *device, __u8 lpm) +static int dasd_eckd_pe_handler(struct dasd_device *device, __u8 lpm) { - struct path_verification_work_data *data; + struct pe_handler_work_data *data; data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); if (!data) { - if (mutex_trylock(&dasd_path_verification_mutex)) { - data = path_verification_worker; + if (mutex_trylock(&dasd_pe_handler_mutex)) { + data = pe_handler_worker; data->isglobal = 1; - } else + } else { return -ENOMEM; + } } else { memset(data, 0, sizeof(*data)); data->isglobal = 0; } - INIT_WORK(&data->worker, do_path_verification_work); + INIT_WORK(&data->worker, do_pe_handler_work); dasd_get_device(device); data->device = device; data->tbvpm = lpm; @@ -2073,7 +2123,7 @@ dasd_free_block(device->block); device->block = NULL; out_err1: - kfree(private->conf_data); + dasd_eckd_clear_conf_data(device); kfree(device->private); device->private = NULL; return rc; @@ -2082,7 +2132,6 @@ static void dasd_eckd_uncheck_device(struct dasd_device *device) { struct dasd_eckd_private *private = device->private; - int i; if (!private) return; @@ -2092,21 +2141,7 @@ private->sneq = NULL; private->vdsneq = NULL; private->gneq = NULL; - private->conf_len = 0; - for (i = 0; i < 8; i++) { - kfree(device->path[i].conf_data); - if ((__u8 *)device->path[i].conf_data == - private->conf_data) { - private->conf_data = NULL; - private->conf_len = 0; - } - device->path[i].conf_data = NULL; - device->path[i].cssid = 0; - device->path[i].ssid = 0; - device->path[i].chpid = 0; - } - kfree(private->conf_data); - private->conf_data = NULL; + dasd_eckd_clear_conf_data(device); } static struct dasd_ccw_req * @@ -2166,6 +2201,7 @@ cqr->status = DASD_CQR_FILLED; /* Set flags to suppress output for expected errors */ set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); + set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); return cqr; } @@ -2447,7 +2483,6 @@ cqr->buildclk = get_tod_clock(); cqr->status = DASD_CQR_FILLED; /* Set flags to suppress output for expected errors */ - set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); return cqr; @@ -3000,6 +3035,49 @@ 0, NULL); } +static bool test_and_set_format_track(struct dasd_format_entry *to_format, + struct dasd_ccw_req *cqr) +{ + struct dasd_block *block = cqr->block; + struct dasd_format_entry *format; + unsigned long flags; + bool rc = false; + + spin_lock_irqsave(&block->format_lock, flags); + if (cqr->trkcount != atomic_read(&block->trkcount)) { + /* + * The number of formatted tracks has changed after request + * start and we can not tell if the current track was involved. + * To avoid data corruption treat it as if the current track is + * involved + */ + rc = true; + goto out; + } + list_for_each_entry(format, &block->format_list, list) { + if (format->track == to_format->track) { + rc = true; + goto out; + } + } + list_add_tail(&to_format->list, &block->format_list); + +out: + spin_unlock_irqrestore(&block->format_lock, flags); + return rc; +} + +static void clear_format_track(struct dasd_format_entry *format, + struct dasd_block *block) +{ + unsigned long flags; + + spin_lock_irqsave(&block->format_lock, flags); + atomic_inc(&block->trkcount); + list_del_init(&format->list); + spin_unlock_irqrestore(&block->format_lock, flags); +} + /* * Callback function to free ESE format requests. */ @@ -3007,15 +3085,19 @@ { struct dasd_device *device = cqr->startdev; struct dasd_eckd_private *private = device->private; + struct dasd_format_entry *format = data; + clear_format_track(format, cqr->basedev->block); private->count--; dasd_ffree_request(cqr, device); } static struct dasd_ccw_req * -dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) +dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, + struct irb *irb) { struct dasd_eckd_private *private; + struct dasd_format_entry *format; struct format_data_t fdata; unsigned int recs_per_trk; struct dasd_ccw_req *fcqr; @@ -3025,23 +3107,42 @@ struct request *req; sector_t first_trk; sector_t last_trk; + sector_t curr_trk; int rc; - req = cqr->callback_data; - base = cqr->block->base; + req = dasd_get_callback_data(cqr); + block = cqr->block; + base = block->base; private = base->private; - block = base->block; blksize = block->bp_block; recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); + format = &startdev->format_entry; first_trk = blk_rq_pos(req) >> block->s2b_shift; sector_div(first_trk, recs_per_trk); last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; sector_div(last_trk, recs_per_trk); + rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); + if (rc) + return ERR_PTR(rc); + + if (curr_trk < first_trk || curr_trk > last_trk) { + DBF_DEV_EVENT(DBF_WARNING, startdev, + "ESE error track %llu not within range %llu - %llu\n", + curr_trk, first_trk, last_trk); + return ERR_PTR(-EINVAL); + } + format->track = curr_trk; + /* test if track is already in formatting by another thread */ + if (test_and_set_format_track(format, cqr)) { + /* this is no real error so do not count down retries */ + cqr->retries++; + return ERR_PTR(-EEXIST); + } - fdata.start_unit = first_trk; - fdata.stop_unit = last_trk; + fdata.start_unit = curr_trk; + fdata.stop_unit = curr_trk; fdata.blksize = blksize; fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; @@ -3058,6 +3159,7 @@ return fcqr; fcqr->callback = dasd_eckd_ese_format_cb; + fcqr->callback_data = (void *) format; return fcqr; } @@ -3065,29 +3167,86 @@ /* * When data is read from an unformatted area of an ESE volume, this function * returns zeroed data and thereby mimics a read of zero data. + * + * The first unformatted track is the one that got the NRF error, the address is + * encoded in the sense data. + * + * All tracks before have returned valid data and should not be touched. + * All tracks after the unformatted track might be formatted or not. This is + * currently not known, remember the processed data and return the remainder of + * the request to the blocklayer in __dasd_cleanup_cqr(). */ -static void dasd_eckd_ese_read(struct dasd_ccw_req *cqr) +static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) { + struct dasd_eckd_private *private; + sector_t first_trk, last_trk; + sector_t first_blk, last_blk; unsigned int blksize, off; + unsigned int recs_per_trk; struct dasd_device *base; struct req_iterator iter; + struct dasd_block *block; + unsigned int skip_block; + unsigned int blk_count; struct request *req; struct bio_vec bv; + sector_t curr_trk; + sector_t end_blk; char *dst; + int rc; req = (struct request *) cqr->callback_data; base = cqr->block->base; blksize = base->block->bp_block; + block = cqr->block; + private = base->private; + skip_block = 0; + blk_count = 0; + + recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); + first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift; + sector_div(first_trk, recs_per_trk); + last_trk = last_blk = + (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; + sector_div(last_trk, recs_per_trk); + rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); + if (rc) + return rc; + + /* sanity check if the current track from sense data is valid */ + if (curr_trk < first_trk || curr_trk > last_trk) { + DBF_DEV_EVENT(DBF_WARNING, base, + "ESE error track %llu not within range %llu - %llu\n", + curr_trk, first_trk, last_trk); + return -EINVAL; + } + + /* + * if not the first track got the NRF error we have to skip over valid + * blocks + */ + if (curr_trk != first_trk) + skip_block = curr_trk * recs_per_trk - first_blk; + + /* we have no information beyond the current track */ + end_blk = (curr_trk + 1) * recs_per_trk; rq_for_each_segment(bv, req, iter) { dst = page_address(bv.bv_page) + bv.bv_offset; for (off = 0; off < bv.bv_len; off += blksize) { - if (dst && rq_data_dir(req) == READ) { - dst += off; - memset(dst, 0, blksize); + if (first_blk + blk_count >= end_blk) { + cqr->proc_bytes = blk_count * blksize; + return 0; } + if (dst && !skip_block) + memset(dst, 0, blksize); + else + skip_block--; + dst += blksize; + blk_count++; } } + return 0; } /* @@ -3872,8 +4031,6 @@ /* Set flags to suppress output for expected errors */ if (dasd_eckd_is_ese(basedev)) { - set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); - set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); } @@ -4375,9 +4532,8 @@ /* Set flags to suppress output for expected errors */ if (dasd_eckd_is_ese(basedev)) { - set_bit(DASD_CQR_SUPPRESS_FP, &cqr->flags); - set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags); set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags); + set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags); } return cqr; @@ -4478,7 +4634,6 @@ struct dasd_device *basedev; struct req_iterator iter; struct dasd_ccw_req *cqr; - unsigned int first_offs; unsigned int trkcount; unsigned long *idaws; unsigned int size; @@ -4512,7 +4667,6 @@ last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) / DASD_RAW_SECTORS_PER_TRACK; trkcount = last_trk - first_trk + 1; - first_offs = 0; if (rq_data_dir(req) == READ) cmd = DASD_ECKD_CCW_READ_TRACK; @@ -4556,13 +4710,13 @@ if (use_prefix) { prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev, - startdev, 1, first_offs + 1, trkcount, 0, 0); + startdev, 1, 0, trkcount, 0, 0); } else { define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0); ccw[-1].flags |= CCW_FLAG_CC; data += sizeof(struct DE_eckd_data); - locate_record_ext(ccw++, data, first_trk, first_offs + 1, + locate_record_ext(ccw++, data, first_trk, 0, trkcount, cmd, basedev, 0, 0); } @@ -5549,36 +5703,32 @@ { u8 *sense = dasd_get_sense(irb); - if (scsw_is_tm(&irb->scsw)) { - /* - * In some cases the 'File Protected' or 'Incorrect Length' - * error might be expected and log messages shouldn't be written - * then. Check if the according suppress bit is set. - */ - if (sense && (sense[1] & SNS1_FILE_PROTECTED) && - test_bit(DASD_CQR_SUPPRESS_FP, &req->flags)) - return; - if (scsw_cstat(&irb->scsw) == 0x40 && - test_bit(DASD_CQR_SUPPRESS_IL, &req->flags)) - return; + /* + * In some cases certain errors might be expected and + * log messages shouldn't be written then. + * Check if the according suppress bit is set. + */ + if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) && + !(sense[2] & SNS2_ENV_DATA_PRESENT) && + test_bit(DASD_CQR_SUPPRESS_IT, &req->flags)) + return; - dasd_eckd_dump_sense_tcw(device, req, irb); - } else { - /* - * In some cases the 'Command Reject' or 'No Record Found' - * error might be expected and log messages shouldn't be - * written then. Check if the according suppress bit is set. - */ - if (sense && sense[0] & SNS0_CMD_REJECT && - test_bit(DASD_CQR_SUPPRESS_CR, &req->flags)) - return; + if (sense && sense[0] & SNS0_CMD_REJECT && + test_bit(DASD_CQR_SUPPRESS_CR, &req->flags)) + return; - if (sense && sense[1] & SNS1_NO_REC_FOUND && - test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags)) - return; + if (sense && sense[1] & SNS1_NO_REC_FOUND && + test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags)) + return; + if (scsw_cstat(&irb->scsw) == 0x40 && + test_bit(DASD_CQR_SUPPRESS_IL, &req->flags)) + return; + + if (scsw_is_tm(&irb->scsw)) + dasd_eckd_dump_sense_tcw(device, req, irb); + else dasd_eckd_dump_sense_ccw(device, req, irb); - } } static int dasd_eckd_pm_freeze(struct dasd_device *device) @@ -6547,7 +6697,7 @@ .check_device = dasd_eckd_check_characteristics, .uncheck_device = dasd_eckd_uncheck_device, .do_analysis = dasd_eckd_do_analysis, - .verify_path = dasd_eckd_verify_path, + .pe_handler = dasd_eckd_pe_handler, .basic_to_ready = dasd_eckd_basic_to_ready, .online_to_ready = dasd_eckd_online_to_ready, .basic_to_known = dasd_eckd_basic_to_known, @@ -6606,18 +6756,20 @@ return -ENOMEM; dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req), GFP_KERNEL | GFP_DMA); - if (!dasd_vol_info_req) + if (!dasd_vol_info_req) { + kfree(dasd_reserve_req); return -ENOMEM; - path_verification_worker = kmalloc(sizeof(*path_verification_worker), - GFP_KERNEL | GFP_DMA); - if (!path_verification_worker) { + } + pe_handler_worker = kmalloc(sizeof(*pe_handler_worker), + GFP_KERNEL | GFP_DMA); + if (!pe_handler_worker) { kfree(dasd_reserve_req); kfree(dasd_vol_info_req); return -ENOMEM; } rawpadpage = (void *)__get_free_page(GFP_KERNEL); if (!rawpadpage) { - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); kfree(dasd_vol_info_req); return -ENOMEM; @@ -6626,7 +6778,7 @@ if (!ret) wait_for_device_probe(); else { - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); kfree(dasd_vol_info_req); free_page((unsigned long)rawpadpage); @@ -6638,7 +6790,7 @@ dasd_eckd_cleanup(void) { ccw_driver_unregister(&dasd_eckd_driver); - kfree(path_verification_worker); + kfree(pe_handler_worker); kfree(dasd_reserve_req); free_page((unsigned long)rawpadpage); } --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_eckd.h +++ linux-oracle-5.4.0/drivers/s390/block/dasd_eckd.h @@ -220,7 +220,7 @@ __u8 imbedded_count; __u8 extended_operation; __u16 extended_parameter_length; - __u8 extended_parameter[0]; + __u8 extended_parameter[]; } __attribute__ ((packed)); /* Prefix data for format 0x00 and 0x01 */ --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_fba.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_fba.c @@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); static struct dasd_discipline dasd_fba_discipline; +static void *dasd_fba_zero_page; struct dasd_fba_private { struct dasd_fba_characteristics rdc_data; @@ -270,7 +271,7 @@ ccw->cmd_code = DASD_FBA_CCW_WRITE; ccw->flags |= CCW_FLAG_SLI; ccw->count = count; - ccw->cda = (__u32) (addr_t) page_to_phys(ZERO_PAGE(0)); + ccw->cda = (__u32) (addr_t) dasd_fba_zero_page; } /* @@ -802,13 +803,18 @@ blk_queue_flag_set(QUEUE_FLAG_DISCARD, q); } +static int dasd_fba_pe_handler(struct dasd_device *device, __u8 tbvpm) +{ + return dasd_generic_verify_path(device, tbvpm); +} + static struct dasd_discipline dasd_fba_discipline = { .owner = THIS_MODULE, .name = "FBA ", .ebcname = "FBA ", .check_device = dasd_fba_check_characteristics, .do_analysis = dasd_fba_do_analysis, - .verify_path = dasd_generic_verify_path, + .pe_handler = dasd_fba_pe_handler, .setup_blk_queue = dasd_fba_setup_blk_queue, .fill_geometry = dasd_fba_fill_geometry, .start_IO = dasd_start_IO, @@ -830,6 +836,11 @@ int ret; ASCEBC(dasd_fba_discipline.ebcname, 4); + + dasd_fba_zero_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!dasd_fba_zero_page) + return -ENOMEM; + ret = ccw_driver_register(&dasd_fba_driver); if (!ret) wait_for_device_probe(); @@ -841,6 +852,7 @@ dasd_fba_cleanup(void) { ccw_driver_unregister(&dasd_fba_driver); + free_page((unsigned long)dasd_fba_zero_page); } module_init(dasd_fba_init); --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_int.h +++ linux-oracle-5.4.0/drivers/s390/block/dasd_int.h @@ -187,6 +187,8 @@ void (*callback)(struct dasd_ccw_req *, void *data); void *callback_data; + unsigned int proc_bytes; /* bytes for partial completion */ + unsigned int trkcount; /* count formatted tracks */ }; /* @@ -224,7 +226,7 @@ * The following flags are used to suppress output of certain errors. */ #define DASD_CQR_SUPPRESS_NRF 4 /* Suppress 'No Record Found' error */ -#define DASD_CQR_SUPPRESS_FP 5 /* Suppress 'File Protected' error*/ +#define DASD_CQR_SUPPRESS_IT 5 /* Suppress 'Invalid Track' error*/ #define DASD_CQR_SUPPRESS_IL 6 /* Suppress 'Incorrect Length' error */ #define DASD_CQR_SUPPRESS_CR 7 /* Suppress 'Command Reject' error */ @@ -296,7 +298,7 @@ * e.g. verify that new path is compatible with the current * configuration. */ - int (*verify_path)(struct dasd_device *, __u8); + int (*pe_handler)(struct dasd_device *, __u8); /* * Last things to do when a device is set online, and first things @@ -387,8 +389,9 @@ int (*ext_pool_warn_thrshld)(struct dasd_device *); int (*ext_pool_oos)(struct dasd_device *); int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); - struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); - void (*ese_read)(struct dasd_ccw_req *); + struct dasd_ccw_req *(*ese_format)(struct dasd_device *, + struct dasd_ccw_req *, struct irb *); + int (*ese_read)(struct dasd_ccw_req *, struct irb *); }; extern struct dasd_discipline *dasd_diag_discipline_pointer; @@ -474,6 +477,11 @@ spinlock_t lock; }; +struct dasd_format_entry { + struct list_head list; + sector_t track; +}; + struct dasd_device { /* Block device stuff. */ struct dasd_block *block; @@ -539,6 +547,7 @@ struct dentry *debugfs_dentry; struct dentry *hosts_dentry; struct dasd_profile profile; + struct dasd_format_entry format_entry; }; struct dasd_block { @@ -564,6 +573,10 @@ struct dentry *debugfs_dentry; struct dasd_profile profile; + + struct list_head format_list; + spinlock_t format_lock; + atomic_t trkcount; }; struct dasd_attention_data { @@ -712,6 +725,18 @@ return 0; } +/* + * return the callback data of the original request in case there are + * ERP requests build on top of it + */ +static inline void *dasd_get_callback_data(struct dasd_ccw_req *cqr) +{ + while (cqr->refers) + cqr = cqr->refers; + + return cqr->callback_data; +} + /* externals in dasd.c */ #define DASD_PROFILE_OFF 0 #define DASD_PROFILE_ON 1 --- linux-oracle-5.4.0.orig/drivers/s390/block/dasd_ioctl.c +++ linux-oracle-5.4.0/drivers/s390/block/dasd_ioctl.c @@ -137,6 +137,7 @@ spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); dasd_schedule_block_bh(block); + dasd_schedule_device_bh(base); return 0; } @@ -457,10 +458,9 @@ /* * Return dasd information. Used for BIODASDINFO and BIODASDINFO2. */ -static int dasd_ioctl_information(struct dasd_block *block, - unsigned int cmd, void __user *argp) +static int __dasd_ioctl_information(struct dasd_block *block, + struct dasd_information2_t *dasd_info) { - struct dasd_information2_t *dasd_info; struct subchannel_id sch_id; struct ccw_dev_id dev_id; struct dasd_device *base; @@ -473,15 +473,9 @@ if (!base->discipline || !base->discipline->fill_info) return -EINVAL; - dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL); - if (dasd_info == NULL) - return -ENOMEM; - rc = base->discipline->fill_info(base, dasd_info); - if (rc) { - kfree(dasd_info); + if (rc) return rc; - } cdev = base->cdev; ccw_device_get_id(cdev, &dev_id); @@ -516,19 +510,28 @@ memcpy(dasd_info->type, base->discipline->name, 4); - spin_lock_irqsave(&block->queue_lock, flags); + spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); list_for_each(l, &base->ccw_queue) dasd_info->chanq_len++; - spin_unlock_irqrestore(&block->queue_lock, flags); + spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); + return 0; +} - rc = 0; - if (copy_to_user(argp, dasd_info, - ((cmd == (unsigned int) BIODASDINFO2) ? - sizeof(struct dasd_information2_t) : - sizeof(struct dasd_information_t)))) - rc = -EFAULT; +static int dasd_ioctl_information(struct dasd_block *block, void __user *argp, + size_t copy_size) +{ + struct dasd_information2_t *dasd_info; + int error; + + dasd_info = kzalloc(sizeof(*dasd_info), GFP_KERNEL); + if (!dasd_info) + return -ENOMEM; + + error = __dasd_ioctl_information(block, dasd_info); + if (!error && copy_to_user(argp, dasd_info, copy_size)) + error = -EFAULT; kfree(dasd_info); - return rc; + return error; } /* @@ -622,10 +625,12 @@ rc = dasd_ioctl_check_format(bdev, argp); break; case BIODASDINFO: - rc = dasd_ioctl_information(block, cmd, argp); + rc = dasd_ioctl_information(block, argp, + sizeof(struct dasd_information_t)); break; case BIODASDINFO2: - rc = dasd_ioctl_information(block, cmd, argp); + rc = dasd_ioctl_information(block, argp, + sizeof(struct dasd_information2_t)); break; case BIODASDPRRD: rc = dasd_ioctl_read_profile(block, argp); --- linux-oracle-5.4.0.orig/drivers/s390/block/scm_blk.c +++ linux-oracle-5.4.0/drivers/s390/block/scm_blk.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "scm_blk.h" @@ -131,7 +132,7 @@ for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) { msb = &scmrq->aob->msb[i]; - aidaw = msb->data_addr; + aidaw = (u64)phys_to_virt(msb->data_addr); if ((msb->flags & MSB_FLAG_IDA) && aidaw && IS_ALIGNED(aidaw, PAGE_SIZE)) @@ -196,12 +197,12 @@ msb->scm_addr = scmdev->address + ((u64) blk_rq_pos(req) << 9); msb->oc = (rq_data_dir(req) == READ) ? MSB_OC_READ : MSB_OC_WRITE; msb->flags |= MSB_FLAG_IDA; - msb->data_addr = (u64) aidaw; + msb->data_addr = (u64)virt_to_phys(aidaw); rq_for_each_segment(bv, req, iter) { WARN_ON(bv.bv_offset); msb->blk_count += bv.bv_len >> 12; - aidaw->data_addr = (u64) page_address(bv.bv_page); + aidaw->data_addr = virt_to_phys(page_address(bv.bv_page)); aidaw++; } @@ -256,7 +257,8 @@ for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) { error = blk_mq_rq_to_pdu(scmrq->request[i]); *error = scmrq->error; - blk_mq_complete_request(scmrq->request[i]); + if (likely(!blk_should_fake_timeout(scmrq->request[i]->q))) + blk_mq_complete_request(scmrq->request[i]); } atomic_dec(&bdev->queued_reqs); --- linux-oracle-5.4.0.orig/drivers/s390/char/Makefile +++ linux-oracle-5.4.0/drivers/s390/char/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_PCI) += sclp_pci.o +obj-$(subst m,y,$(CONFIG_ZCRYPT)) += sclp_ap.o + obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o obj-$(CONFIG_VMCP) += vmcp.o --- linux-oracle-5.4.0.orig/drivers/s390/char/keyboard.h +++ linux-oracle-5.4.0/drivers/s390/char/keyboard.h @@ -56,7 +56,7 @@ kbd_put_queue(struct tty_port *port, int ch) { tty_insert_flip_char(port, ch, 0); - tty_schedule_flip(port); + tty_flip_buffer_push(port); } static inline void @@ -64,5 +64,5 @@ { while (*cp) tty_insert_flip_char(port, *cp++, 0); - tty_schedule_flip(port); + tty_flip_buffer_push(port); } --- linux-oracle-5.4.0.orig/drivers/s390/char/raw3270.h +++ linux-oracle-5.4.0/drivers/s390/char/raw3270.h @@ -211,7 +211,7 @@ struct list_head update; unsigned long size; unsigned long len; - char string[0]; + char string[]; } __attribute__ ((aligned(8))); static inline struct string * --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp.c @@ -1208,6 +1208,7 @@ fail_unregister_reboot_notifier: unregister_reboot_notifier(&sclp_reboot_notifier); fail_init_state_uninitialized: + list_del(&sclp_state_change_event.list); sclp_init_state = sclp_init_state_uninitialized; free_page((unsigned long) sclp_read_sccb); free_page((unsigned long) sclp_init_sccb); --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp.h +++ linux-oracle-5.4.0/drivers/s390/char/sclp.h @@ -229,7 +229,7 @@ #define SCLP_HAS_CPU_INFO (sclp.facilities & 0x0800000000000000ULL) #define SCLP_HAS_CPU_RECONFIG (sclp.facilities & 0x0400000000000000ULL) #define SCLP_HAS_PCI_RECONFIG (sclp.facilities & 0x0000000040000000ULL) - +#define SCLP_HAS_AP_RECONFIG (sclp.facilities & 0x0000000100000000ULL) struct gds_subvector { u8 length; --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp_ap.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp_ap.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * s390 crypto adapter related sclp functions. + * + * Copyright IBM Corp. 2020 + */ +#define KMSG_COMPONENT "sclp_cmd" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include "sclp.h" + +#define SCLP_CMDW_CONFIGURE_AP 0x001f0001 +#define SCLP_CMDW_DECONFIGURE_AP 0x001e0001 + +struct ap_cfg_sccb { + struct sccb_header header; +} __packed; + +static int do_ap_configure(sclp_cmdw_t cmd, u32 apid) +{ + struct ap_cfg_sccb *sccb; + int rc; + + if (!SCLP_HAS_AP_RECONFIG) + return -EOPNOTSUPP; + + sccb = (struct ap_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!sccb) + return -ENOMEM; + + sccb->header.length = PAGE_SIZE; + cmd |= (apid & 0xFF) << 8; + rc = sclp_sync_request(cmd, sccb); + if (rc) + goto out; + switch (sccb->header.response_code) { + case 0x0020: case 0x0120: case 0x0440: case 0x0450: + break; + default: + pr_warn("configure AP adapter %u failed: cmd=0x%08x response=0x%04x\n", + apid, cmd, sccb->header.response_code); + rc = -EIO; + break; + } +out: + free_page((unsigned long) sccb); + return rc; +} + +int sclp_ap_configure(u32 apid) +{ + return do_ap_configure(SCLP_CMDW_CONFIGURE_AP, apid); +} +EXPORT_SYMBOL(sclp_ap_configure); + +int sclp_ap_deconfigure(u32 apid) +{ + return do_ap_configure(SCLP_CMDW_DECONFIGURE_AP, apid); +} +EXPORT_SYMBOL(sclp_ap_deconfigure); --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp_early.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp_early.c @@ -40,13 +40,14 @@ sclp.has_gisaf = !!(sccb->fac118 & 0x08); sclp.has_hvs = !!(sccb->fac119 & 0x80); sclp.has_kss = !!(sccb->fac98 & 0x01); - sclp.has_sipl = !!(sccb->cbl & 0x4000); if (sccb->fac85 & 0x02) S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; if (sccb->fac91 & 0x40) S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; if (sccb->cpuoff > 134) sclp.has_diag318 = !!(sccb->byte_134 & 0x80); + if (sccb->cpuoff > 137) + sclp.has_sipl = !!(sccb->cbl & 0x4000); sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; sclp.rzm <<= 20; --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp_pci.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp_pci.c @@ -39,7 +39,7 @@ u8 atype; u32 fh; u32 fid; - u8 data[0]; + u8 data[]; } __packed; struct err_notify_sccb { --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp_sd.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp_sd.c @@ -319,8 +319,14 @@ &esize); if (rc) { /* Cancel running request if interrupted */ - if (rc == -ERESTARTSYS) - sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL); + if (rc == -ERESTARTSYS) { + if (sclp_sd_sync(page, SD_EQ_HALT, di, 0, 0, NULL, NULL)) { + pr_warn("Could not stop Store Data request - leaking at least %zu bytes\n", + (size_t)dsize * PAGE_SIZE); + data = NULL; + asce = 0; + } + } vfree(data); goto out; } --- linux-oracle-5.4.0.orig/drivers/s390/char/sclp_vt220.c +++ linux-oracle-5.4.0/drivers/s390/char/sclp_vt220.c @@ -35,8 +35,8 @@ #define SCLP_VT220_MINOR 65 #define SCLP_VT220_DRIVER_NAME "sclp_vt220" #define SCLP_VT220_DEVICE_NAME "ttysclp" -#define SCLP_VT220_CONSOLE_NAME "ttyS" -#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */ +#define SCLP_VT220_CONSOLE_NAME "ttysclp" +#define SCLP_VT220_CONSOLE_INDEX 0 /* console=ttysclp0 */ /* Representation of a single write request */ struct sclp_vt220_request { @@ -325,7 +325,7 @@ buffer = (void *) ((addr_t) sccb + sccb->header.length); if (convertlf) { - /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ + /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/ for (from=0, to=0; (from < count) && (to < sclp_vt220_space_left(request)); from++) { @@ -334,8 +334,8 @@ /* Perform conversion */ if (c == 0x0a) { if (to + 1 < sclp_vt220_space_left(request)) { - ((unsigned char *) buffer)[to++] = c; ((unsigned char *) buffer)[to++] = 0x0d; + ((unsigned char *) buffer)[to++] = c; } else break; --- linux-oracle-5.4.0.orig/drivers/s390/char/tape_std.c +++ linux-oracle-5.4.0/drivers/s390/char/tape_std.c @@ -53,7 +53,6 @@ tape_std_assign(struct tape_device *device) { int rc; - struct timer_list timeout; struct tape_request *request; request = tape_alloc_request(2, 11); @@ -70,7 +69,7 @@ * So we set up a timeout for this call. */ timer_setup(&request->timer, tape_std_assign_timeout, 0); - mod_timer(&timeout, jiffies + 2 * HZ); + mod_timer(&request->timer, jiffies + msecs_to_jiffies(2000)); rc = tape_do_io_interruptible(device, request); --- linux-oracle-5.4.0.orig/drivers/s390/char/zcore.c +++ linux-oracle-5.4.0/drivers/s390/char/zcore.c @@ -53,6 +53,7 @@ static struct dentry *zcore_hsa_file; static struct ipl_parameter_block *zcore_ipl_block; +static DEFINE_MUTEX(hsa_buf_mutex); static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE); /* @@ -69,19 +70,24 @@ if (!hsa_available) return -ENODATA; + mutex_lock(&hsa_buf_mutex); while (count) { if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { TRACE("sclp_sdias_copy() failed\n"); + mutex_unlock(&hsa_buf_mutex); return -EIO; } offset = src % PAGE_SIZE; bytes = min(PAGE_SIZE - offset, count); - if (copy_to_user(dest, hsa_buf + offset, bytes)) + if (copy_to_user(dest, hsa_buf + offset, bytes)) { + mutex_unlock(&hsa_buf_mutex); return -EFAULT; + } src += bytes; dest += bytes; count -= bytes; } + mutex_unlock(&hsa_buf_mutex); return 0; } @@ -99,9 +105,11 @@ if (!hsa_available) return -ENODATA; + mutex_lock(&hsa_buf_mutex); while (count) { if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { TRACE("sclp_sdias_copy() failed\n"); + mutex_unlock(&hsa_buf_mutex); return -EIO; } offset = src % PAGE_SIZE; @@ -111,6 +119,7 @@ dest += bytes; count -= bytes; } + mutex_unlock(&hsa_buf_mutex); return 0; } --- linux-oracle-5.4.0.orig/drivers/s390/cio/airq.c +++ linux-oracle-5.4.0/drivers/s390/cio/airq.c @@ -105,16 +105,12 @@ return IRQ_HANDLED; } -static struct irqaction airq_interrupt = { - .name = "AIO", - .handler = do_airq_interrupt, -}; - void __init init_airq_interrupts(void) { irq_set_chip_and_handler(THIN_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); - setup_irq(THIN_INTERRUPT, &airq_interrupt); + if (request_irq(THIN_INTERRUPT, do_airq_interrupt, 0, "AIO", NULL)) + panic("Failed to register AIO interrupt\n"); } static inline unsigned long iv_size(unsigned long bits) --- linux-oracle-5.4.0.orig/drivers/s390/cio/blacklist.c +++ linux-oracle-5.4.0/drivers/s390/cio/blacklist.c @@ -303,8 +303,10 @@ cio_ignore_proc_seq_next(struct seq_file *s, void *it, loff_t *offset) { struct ccwdev_iter *iter; + loff_t p = *offset; - if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) + (*offset)++; + if (p >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) return NULL; iter = it; if (iter->devno == __MAX_SUBCHANNEL) { @@ -314,7 +316,6 @@ return NULL; } else iter->devno++; - (*offset)++; return iter; } --- linux-oracle-5.4.0.orig/drivers/s390/cio/chp.c +++ linux-oracle-5.4.0/drivers/s390/cio/chp.c @@ -255,6 +255,9 @@ if (!num_args) return count; + /* Wait until previous actions have settled. */ + css_wait_for_slow_path(); + if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 1); --- linux-oracle-5.4.0.orig/drivers/s390/cio/chsc.c +++ linux-oracle-5.4.0/drivers/s390/cio/chsc.c @@ -753,8 +753,6 @@ { struct channel_path *chp = chpid_to_chp(chpid); - /* Wait until previous actions have settled. */ - css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ --- linux-oracle-5.4.0.orig/drivers/s390/cio/cio.c +++ linux-oracle-5.4.0/drivers/s390/cio/cio.c @@ -563,16 +563,12 @@ return IRQ_HANDLED; } -static struct irqaction io_interrupt = { - .name = "I/O", - .handler = do_cio_interrupt, -}; - void __init init_cio_interrupts(void) { irq_set_chip_and_handler(IO_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); - setup_irq(IO_INTERRUPT, &io_interrupt); + if (request_irq(IO_INTERRUPT, do_cio_interrupt, 0, "I/O", NULL)) + panic("Failed to register I/O interrupt\n"); } #ifdef CONFIG_CCW_CONSOLE --- linux-oracle-5.4.0.orig/drivers/s390/cio/css.c +++ linux-oracle-5.4.0/drivers/s390/cio/css.c @@ -426,9 +426,26 @@ } static DEVICE_ATTR_RO(pimpampom); +static ssize_t dev_busid_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct subchannel *sch = to_subchannel(dev); + struct pmcw *pmcw = &sch->schib.pmcw; + + if ((pmcw->st == SUBCHANNEL_TYPE_IO && pmcw->dnv) || + (pmcw->st == SUBCHANNEL_TYPE_MSG && pmcw->w)) + return sysfs_emit(buf, "0.%x.%04x\n", sch->schid.ssid, + pmcw->dev); + else + return sysfs_emit(buf, "none\n"); +} +static DEVICE_ATTR_RO(dev_busid); + static struct attribute *io_subchannel_type_attrs[] = { &dev_attr_chpids.attr, &dev_attr_pimpampom.attr, + &dev_attr_dev_busid.attr, NULL, }; ATTRIBUTE_GROUPS(io_subchannel_type); @@ -677,6 +694,11 @@ rc = css_evaluate_known_subchannel(sch, 1); if (rc == -EAGAIN) css_schedule_eval(sch->schid); + /* + * The loop might take long time for platforms with lots of + * known devices. Allow scheduling here. + */ + cond_resched(); } return 0; } --- linux-oracle-5.4.0.orig/drivers/s390/cio/device.c +++ linux-oracle-5.4.0/drivers/s390/cio/device.c @@ -849,8 +849,10 @@ * Now we know this subchannel will stay, we can throw * our delayed uevent. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } /* make it known to the system */ ret = ccw_device_add(cdev); if (ret) { @@ -1058,8 +1060,11 @@ * Throw the delayed uevent for the subchannel, register * the ccw_device and exit. */ - dev_set_uevent_suppress(&sch->dev, 0); - kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + if (dev_get_uevent_suppress(&sch->dev)) { + /* should always be the case for the console */ + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } cdev = sch_get_cdev(sch); rc = ccw_device_add(cdev); if (rc) { @@ -1380,6 +1385,7 @@ enum io_sch_action { IO_SCH_UNREG, IO_SCH_ORPH_UNREG, + IO_SCH_UNREG_CDEV, IO_SCH_ATTACH, IO_SCH_UNREG_ATTACH, IO_SCH_ORPH_ATTACH, @@ -1412,7 +1418,7 @@ } if ((sch->schib.pmcw.pam & sch->opm) == 0) { if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) - return IO_SCH_UNREG; + return IO_SCH_UNREG_CDEV; return IO_SCH_DISC; } if (device_is_disconnected(cdev)) @@ -1474,6 +1480,7 @@ case IO_SCH_ORPH_ATTACH: ccw_device_set_disconnected(cdev); break; + case IO_SCH_UNREG_CDEV: case IO_SCH_UNREG_ATTACH: case IO_SCH_UNREG: if (!cdev) @@ -1507,6 +1514,7 @@ if (rc) goto out; break; + case IO_SCH_UNREG_CDEV: case IO_SCH_UNREG_ATTACH: spin_lock_irqsave(sch->lock, flags); if (cdev->private->flags.resuming) { @@ -1659,10 +1667,10 @@ struct io_subchannel_private *io_priv = to_io_private(sch); set_io_private(sch, NULL); - put_device(&sch->dev); - put_device(&cdev->dev); dma_free_coherent(&sch->dev, sizeof(*io_priv->dma_area), io_priv->dma_area, io_priv->dma_area_dma); + put_device(&sch->dev); + put_device(&cdev->dev); kfree(io_priv); } --- linux-oracle-5.4.0.orig/drivers/s390/cio/device_ops.c +++ linux-oracle-5.4.0/drivers/s390/cio/device_ops.c @@ -635,7 +635,7 @@ * @mask: mask of paths to use * * Return the number of 64K-bytes blocks all paths at least support - * for a transport command. Return values <= 0 indicate failures. + * for a transport command. Return value 0 indicates failure. */ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask) { @@ -717,13 +717,23 @@ */ void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size) { - return cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); + void *addr; + + if (!get_device(&cdev->dev)) + return NULL; + addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); + if (IS_ERR_OR_NULL(addr)) + put_device(&cdev->dev); + return addr; } EXPORT_SYMBOL(ccw_device_dma_zalloc); void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size) { + if (!cpu_addr) + return; cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size); + put_device(&cdev->dev); } EXPORT_SYMBOL(ccw_device_dma_free); --- linux-oracle-5.4.0.orig/drivers/s390/cio/idset.c +++ linux-oracle-5.4.0/drivers/s390/cio/idset.c @@ -13,23 +13,24 @@ struct idset { int num_ssid; int num_id; - unsigned long bitmap[0]; + unsigned long bitmap[]; }; -static inline unsigned long bitmap_size(int num_ssid, int num_id) +static inline unsigned long idset_bitmap_size(int num_ssid, int num_id) { - return BITS_TO_LONGS(num_ssid * num_id) * sizeof(unsigned long); + return bitmap_size(size_mul(num_ssid, num_id)); } static struct idset *idset_new(int num_ssid, int num_id) { struct idset *set; - set = vmalloc(sizeof(struct idset) + bitmap_size(num_ssid, num_id)); + set = vmalloc(sizeof(struct idset) + + idset_bitmap_size(num_ssid, num_id)); if (set) { set->num_ssid = num_ssid; set->num_id = num_id; - memset(set->bitmap, 0, bitmap_size(num_ssid, num_id)); + memset(set->bitmap, 0, idset_bitmap_size(num_ssid, num_id)); } return set; } @@ -41,7 +42,8 @@ void idset_fill(struct idset *set) { - memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); + memset(set->bitmap, 0xff, + idset_bitmap_size(set->num_ssid, set->num_id)); } static inline void idset_add(struct idset *set, int ssid, int id) --- linux-oracle-5.4.0.orig/drivers/s390/cio/qdio.h +++ linux-oracle-5.4.0/drivers/s390/cio/qdio.h @@ -82,21 +82,22 @@ #define QDIO_SIGA_WRITE 0x00 #define QDIO_SIGA_READ 0x01 #define QDIO_SIGA_SYNC 0x02 +#define QDIO_SIGA_WRITEM 0x03 #define QDIO_SIGA_WRITEQ 0x04 #define QDIO_SIGA_QEBSM_FLAG 0x80 static inline int do_sqbs(u64 token, unsigned char state, int queue, int *start, int *count) { - register unsigned long _ccq asm ("0") = *count; - register unsigned long _token asm ("1") = token; unsigned long _queuestart = ((unsigned long)queue << 32) | *start; + unsigned long _ccq = *count; asm volatile( - " .insn rsy,0xeb000000008A,%1,0,0(%2)" - : "+d" (_ccq), "+d" (_queuestart) - : "d" ((unsigned long)state), "d" (_token) - : "memory", "cc"); + " lgr 1,%[token]\n" + " .insn rsy,0xeb000000008a,%[qs],%[ccq],0(%[state])" + : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart) + : [state] "a" ((unsigned long)state), [token] "d" (token) + : "memory", "cc", "1"); *count = _ccq & 0xff; *start = _queuestart & 0xff; @@ -106,16 +107,17 @@ static inline int do_eqbs(u64 token, unsigned char *state, int queue, int *start, int *count, int ack) { - register unsigned long _ccq asm ("0") = *count; - register unsigned long _token asm ("1") = token; unsigned long _queuestart = ((unsigned long)queue << 32) | *start; unsigned long _state = (unsigned long)ack << 63; + unsigned long _ccq = *count; asm volatile( - " .insn rrf,0xB99c0000,%1,%2,0,0" - : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) - : "d" (_token) - : "memory", "cc"); + " lgr 1,%[token]\n" + " .insn rrf,0xb99c0000,%[qs],%[state],%[ccq],0" + : [ccq] "+&d" (_ccq), [qs] "+&d" (_queuestart), + [state] "+&d" (_state) + : [token] "d" (token) + : "memory", "cc", "1"); *count = _ccq & 0xff; *start = _queuestart & 0xff; *state = _state & 0xff; @@ -372,7 +374,6 @@ extern u64 last_ai_time; /* prototypes for thin interrupt */ -void qdio_setup_thinint(struct qdio_irq *irq_ptr); int qdio_establish_thinint(struct qdio_irq *irq_ptr); void qdio_shutdown_thinint(struct qdio_irq *irq_ptr); void tiqdio_add_input_queues(struct qdio_irq *irq_ptr); --- linux-oracle-5.4.0.orig/drivers/s390/cio/qdio_main.c +++ linux-oracle-5.4.0/drivers/s390/cio/qdio_main.c @@ -31,38 +31,41 @@ MODULE_LICENSE("GPL"); static inline int do_siga_sync(unsigned long schid, - unsigned int out_mask, unsigned int in_mask, + unsigned long out_mask, unsigned long in_mask, unsigned int fc) { - register unsigned long __fc asm ("0") = fc; - register unsigned long __schid asm ("1") = schid; - register unsigned long out asm ("2") = out_mask; - register unsigned long in asm ("3") = in_mask; int cc; asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[schid]\n" + " lgr 2,%[out]\n" + " lgr 3,%[in]\n" " siga 0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc) - : "d" (__fc), "d" (__schid), "d" (out), "d" (in) : "cc"); + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=&d" (cc) + : [fc] "d" (fc), [schid] "d" (schid), + [out] "d" (out_mask), [in] "d" (in_mask) + : "cc", "0", "1", "2", "3"); return cc; } -static inline int do_siga_input(unsigned long schid, unsigned int mask, - unsigned int fc) +static inline int do_siga_input(unsigned long schid, unsigned long mask, + unsigned long fc) { - register unsigned long __fc asm ("0") = fc; - register unsigned long __schid asm ("1") = schid; - register unsigned long __mask asm ("2") = mask; int cc; asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[schid]\n" + " lgr 2,%[mask]\n" " siga 0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc) - : "d" (__fc), "d" (__schid), "d" (__mask) : "cc"); + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=&d" (cc) + : [fc] "d" (fc), [schid] "d" (schid), [mask] "d" (mask) + : "cc", "0", "1", "2"); return cc; } @@ -78,23 +81,24 @@ * Note: For IQDC unicast queues only the highest priority queue is processed. */ static inline int do_siga_output(unsigned long schid, unsigned long mask, - unsigned int *bb, unsigned int fc, + unsigned int *bb, unsigned long fc, unsigned long aob) { - register unsigned long __fc asm("0") = fc; - register unsigned long __schid asm("1") = schid; - register unsigned long __mask asm("2") = mask; - register unsigned long __aob asm("3") = aob; int cc; asm volatile( + " lgr 0,%[fc]\n" + " lgr 1,%[schid]\n" + " lgr 2,%[mask]\n" + " lgr 3,%[aob]\n" " siga 0\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc), "+d" (__fc), "+d" (__aob) - : "d" (__schid), "d" (__mask) - : "cc"); - *bb = __fc >> 31; + " lgr %[fc],0\n" + " ipm %[cc]\n" + " srl %[cc],28\n" + : [cc] "=&d" (cc), [fc] "+&d" (fc) + : [schid] "d" (schid), [mask] "d" (mask), [aob] "d" (aob) + : "cc", "0", "1", "2", "3"); + *bb = fc >> 31; return cc; } @@ -310,18 +314,19 @@ return qdio_siga_sync(q, q->mask, 0); } -static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit, - unsigned long aob) +static int qdio_siga_output(struct qdio_q *q, unsigned int count, + unsigned int *busy_bit, unsigned long aob) { unsigned long schid = *((u32 *) &q->irq_ptr->schid); unsigned int fc = QDIO_SIGA_WRITE; u64 start_time = 0; int retries = 0, cc; - unsigned long laob = 0; - if (aob) { - fc = QDIO_SIGA_WRITEQ; - laob = aob; + if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) { + if (count > 1) + fc = QDIO_SIGA_WRITEM; + else if (aob) + fc = QDIO_SIGA_WRITEQ; } if (is_qebsm(q)) { @@ -329,7 +334,7 @@ fc |= QDIO_SIGA_QEBSM_FLAG; } again: - cc = do_siga_output(schid, q->mask, busy_bit, fc, laob); + cc = do_siga_output(schid, q->mask, busy_bit, fc, aob); /* hipersocket busy condition */ if (unlikely(*busy_bit)) { @@ -781,7 +786,8 @@ return count; } -static int qdio_kick_outbound_q(struct qdio_q *q, unsigned long aob) +static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count, + unsigned long aob) { int retries = 0, cc; unsigned int busy_bit; @@ -793,7 +799,7 @@ retry: qperf_inc(q, siga_write); - cc = qdio_siga_output(q, &busy_bit, aob); + cc = qdio_siga_output(q, count, &busy_bit, aob); switch (cc) { case 0: break; @@ -1526,7 +1532,7 @@ * @count: how many buffers are filled */ static int handle_outbound(struct qdio_q *q, unsigned int callflags, - int bufnr, int count) + unsigned int bufnr, unsigned int count) { const unsigned int scan_threshold = q->irq_ptr->scan_threshold; unsigned char state = 0; @@ -1549,13 +1555,10 @@ if (queue_type(q) == QDIO_IQDIO_QFMT) { unsigned long phys_aob = 0; - /* One SIGA-W per buffer required for unicast HSI */ - WARN_ON_ONCE(count > 1 && !multicast_outbound(q)); - - if (q->u.out.use_cq) + if (q->u.out.use_cq && count == 1) phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr); - rc = qdio_kick_outbound_q(q, phys_aob); + rc = qdio_kick_outbound_q(q, count, phys_aob); } else if (need_siga_sync(q)) { rc = qdio_siga_sync_q(q); } else if (count < QDIO_MAX_BUFFERS_PER_Q && @@ -1564,7 +1567,7 @@ /* The previous buffer is not processed yet, tack on. */ qperf_inc(q, fast_requeue); } else { - rc = qdio_kick_outbound_q(q, 0); + rc = qdio_kick_outbound_q(q, count, 0); } /* Let drivers implement their own completion scanning: */ --- linux-oracle-5.4.0.orig/drivers/s390/cio/qdio_setup.c +++ linux-oracle-5.4.0/drivers/s390/cio/qdio_setup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "cio.h" @@ -207,7 +208,7 @@ /* fill in sl */ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) - q->sl->element[j].sbal = (unsigned long)q->sbal[j]; + q->sl->element[j].sbal = virt_to_phys(q->sbal[j]); } static void setup_queues(struct qdio_irq *irq_ptr, @@ -478,7 +479,6 @@ setup_queues(irq_ptr, init_data); setup_qib(irq_ptr, init_data); - qdio_setup_thinint(irq_ptr); set_impl_params(irq_ptr, init_data->qib_param_field_format, init_data->qib_param_field, init_data->input_slib_elements, --- linux-oracle-5.4.0.orig/drivers/s390/cio/qdio_thinint.c +++ linux-oracle-5.4.0/drivers/s390/cio/qdio_thinint.c @@ -268,17 +268,19 @@ int qdio_establish_thinint(struct qdio_irq *irq_ptr) { + int rc; + if (!is_thinint_irq(irq_ptr)) return 0; - return set_subchannel_ind(irq_ptr, 0); -} -void qdio_setup_thinint(struct qdio_irq *irq_ptr) -{ - if (!is_thinint_irq(irq_ptr)) - return; irq_ptr->dsci = get_indicator(); DBF_HEX(&irq_ptr->dsci, sizeof(void *)); + + rc = set_subchannel_ind(irq_ptr, 0); + if (rc) + put_indicator(irq_ptr->dsci); + + return rc; } void qdio_shutdown_thinint(struct qdio_irq *irq_ptr) --- linux-oracle-5.4.0.orig/drivers/s390/cio/trace.h +++ linux-oracle-5.4.0/drivers/s390/cio/trace.h @@ -50,7 +50,7 @@ __entry->devno = schib->pmcw.dev; __entry->schib = *schib; __entry->pmcw_ena = schib->pmcw.ena; - __entry->pmcw_st = schib->pmcw.ena; + __entry->pmcw_st = schib->pmcw.st; __entry->pmcw_dnv = schib->pmcw.dnv; __entry->pmcw_dev = schib->pmcw.dev; __entry->pmcw_lpm = schib->pmcw.lpm; --- linux-oracle-5.4.0.orig/drivers/s390/cio/vfio_ccw_cp.c +++ linux-oracle-5.4.0/drivers/s390/cio/vfio_ccw_cp.c @@ -636,6 +636,10 @@ { int ret; + /* this is an error in the caller */ + if (cp->initialized) + return -EBUSY; + /* * XXX: * Only support prefetch enable mode now. --- linux-oracle-5.4.0.orig/drivers/s390/cio/vfio_ccw_drv.c +++ linux-oracle-5.4.0/drivers/s390/cio/vfio_ccw_drv.c @@ -83,6 +83,7 @@ struct vfio_ccw_private *private; struct irb *irb; bool is_final; + bool cp_is_finished = false; private = container_of(work, struct vfio_ccw_private, io_work); irb = &private->irb; @@ -91,14 +92,21 @@ (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); if (scsw_is_solicited(&irb->scsw)) { cp_update_scsw(&private->cp, &irb->scsw); - if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) + if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) { cp_free(&private->cp); + cp_is_finished = true; + } } mutex_lock(&private->io_mutex); memcpy(private->io_region->irb_area, irb, sizeof(*irb)); mutex_unlock(&private->io_mutex); - if (private->mdev && is_final) + /* + * Reset to IDLE only if processing of a channel program + * has finished. Do not overwrite a possible processing + * state if the final interrupt was for HSCH or CSCH. + */ + if (private->mdev && cp_is_finished) private->state = VFIO_CCW_STATE_IDLE; if (private->io_trigger) @@ -167,6 +175,11 @@ if (ret) goto out_disable; + if (dev_get_uevent_suppress(&sch->dev)) { + dev_set_uevent_suppress(&sch->dev, 0); + kobject_uevent(&sch->dev.kobj, KOBJ_ADD); + } + VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n", sch->schid.cssid, sch->schid.ssid, sch->schid.sch_no); @@ -234,19 +247,11 @@ if (work_pending(&sch->todo_work)) goto out_unlock; - if (cio_update_schib(sch)) { - vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); - rc = 0; - goto out_unlock; - } - - private = dev_get_drvdata(&sch->dev); - if (private->state == VFIO_CCW_STATE_NOT_OPER) { - private->state = private->mdev ? VFIO_CCW_STATE_IDLE : - VFIO_CCW_STATE_STANDBY; - } rc = 0; + if (cio_update_schib(sch)) + vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_NOT_OPER); + out_unlock: spin_unlock_irqrestore(sch->lock, flags); --- linux-oracle-5.4.0.orig/drivers/s390/cio/vfio_ccw_ops.c +++ linux-oracle-5.4.0/drivers/s390/cio/vfio_ccw_ops.c @@ -506,7 +506,7 @@ if (ret) return ret; - return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_GET_REGION_INFO: { @@ -524,7 +524,7 @@ if (ret) return ret; - return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_GET_IRQ_INFO: { @@ -545,7 +545,7 @@ if (info.count == -1) return -EINVAL; - return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } case VFIO_DEVICE_SET_IRQS: { --- linux-oracle-5.4.0.orig/drivers/s390/crypto/Makefile +++ linux-oracle-5.4.0/drivers/s390/crypto/Makefile @@ -7,7 +7,8 @@ obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o # zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o -zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o zcrypt_ccamisc.o +zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o +zcrypt-objs += zcrypt_ccamisc.o zcrypt_ep11misc.o obj-$(CONFIG_ZCRYPT) += zcrypt.o # adapter drivers depend on ap.o and zcrypt.o obj-$(CONFIG_ZCRYPT) += zcrypt_cex2c.o zcrypt_cex2a.o zcrypt_cex4.o --- linux-oracle-5.4.0.orig/drivers/s390/crypto/ap_bus.c +++ linux-oracle-5.4.0/drivers/s390/crypto/ap_bus.c @@ -18,13 +18,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -60,10 +60,15 @@ module_param_named(aqmask, aqm_str, charp, 0440); MODULE_PARM_DESC(aqmask, "AP bus domain mask."); +atomic_t ap_max_msg_size = ATOMIC_INIT(AP_DEFAULT_MAX_MSG_SIZE); +EXPORT_SYMBOL(ap_max_msg_size); + static struct device *ap_root_device; -DEFINE_SPINLOCK(ap_list_lock); -LIST_HEAD(ap_card_list); +/* Hashtable of all queue devices on the AP bus */ +DEFINE_HASHTABLE(ap_queues, 8); +/* lock used for the ap_queues hashtable */ +DEFINE_SPINLOCK(ap_queues_lock); /* Default permissions (ioctl, card and domain masking) */ struct ap_perms ap_perms; @@ -71,8 +76,7 @@ DEFINE_MUTEX(ap_perms_mutex); EXPORT_SYMBOL(ap_perms_mutex); -static struct ap_config_info *ap_configuration; -static bool initialised; +static struct ap_config_info *ap_qci_info; /* * AP bus related debug feature things. @@ -91,7 +95,7 @@ * Tasklet & timer for AP request polling and interrupts */ static void ap_tasklet_fn(unsigned long); -static DECLARE_TASKLET(ap_tasklet, ap_tasklet_fn, 0); +static DECLARE_TASKLET_OLD(ap_tasklet, ap_tasklet_fn); static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); static struct task_struct *ap_poll_kthread; static DEFINE_MUTEX(ap_poll_thread_mutex); @@ -103,16 +107,11 @@ */ static unsigned long long poll_timeout = 250000; -/* Suspend flag */ -static int ap_suspend_flag; -/* Maximum domain id */ -static int ap_max_domain_id; -/* - * Flag to check if domain was set through module parameter domain=. This is - * important when supsend and resume is done in a z/VM environment where the - * domain might change. - */ -static int user_set_domain; +/* Maximum domain id, if not given via qci */ +static int ap_max_domain_id = 15; +/* Maximum adapter id, if not given via qci */ +static int ap_max_adapter_id = 63; + static struct bus_type ap_bus_type; /* Adapter interrupt definitions */ @@ -159,12 +158,12 @@ } /** - * ap_configuration_available(): Test if AP configuration - * information is available. + * ap_qci_available(): Test if AP configuration + * information can be queried via QCI subfunction. * - * Returns 1 if AP configuration information is available. + * Returns 1 if subfunction PQAP(QCI) is available. */ -static int ap_configuration_available(void) +static int ap_qci_available(void) { return test_facility(12); } @@ -187,22 +186,22 @@ */ static inline int ap_qact_available(void) { - if (ap_configuration) - return ap_configuration->qact; + if (ap_qci_info) + return ap_qci_info->qact; return 0; } /* - * ap_query_configuration(): Fetch cryptographic config info + * ap_fetch_qci_info(): Fetch cryptographic config info * * Returns the ap configuration info fetched via PQAP(QCI). * On success 0 is returned, on failure a negative errno * is returned, e.g. if the PQAP(QCI) instruction is not * available, the return value will be -EOPNOTSUPP. */ -static inline int ap_query_configuration(struct ap_config_info *info) +static inline int ap_fetch_qci_info(struct ap_config_info *info) { - if (!ap_configuration_available()) + if (!ap_qci_available()) return -EOPNOTSUPP; if (!info) return -EINVAL; @@ -210,21 +209,40 @@ } /** - * ap_init_configuration(): Allocate and query configuration array. + * ap_init_qci_info(): Allocate and query qci config info. + * Does also update the static variables ap_max_domain_id + * and ap_max_adapter_id if this info is available. + */ -static void ap_init_configuration(void) +static void __init ap_init_qci_info(void) { - if (!ap_configuration_available()) + if (!ap_qci_available()) { + AP_DBF_INFO("%s QCI not supported\n", __func__); return; + } - ap_configuration = kzalloc(sizeof(*ap_configuration), GFP_KERNEL); - if (!ap_configuration) + ap_qci_info = kzalloc(sizeof(*ap_qci_info), GFP_KERNEL); + if (!ap_qci_info) return; - if (ap_query_configuration(ap_configuration) != 0) { - kfree(ap_configuration); - ap_configuration = NULL; + if (ap_fetch_qci_info(ap_qci_info) != 0) { + kfree(ap_qci_info); + ap_qci_info = NULL; return; } + AP_DBF_INFO("%s successful fetched initial qci info\n", __func__); + + if (ap_qci_info->apxa) { + if (ap_qci_info->Na) { + ap_max_adapter_id = ap_qci_info->Na; + AP_DBF_INFO("%s new ap_max_adapter_id is %d\n", + __func__, ap_max_adapter_id); + } + if (ap_qci_info->Nd) { + ap_max_domain_id = ap_qci_info->Nd; + AP_DBF_INFO("%s new ap_max_domain_id is %d\n", + __func__, ap_max_domain_id); + } + } } /* @@ -238,7 +256,6 @@ /* * ap_test_config_card_id(): Test, whether an AP card ID is configured. - * @id AP card ID * * Returns 0 if the card is not configured * 1 if the card is configured or @@ -246,16 +263,16 @@ */ static inline int ap_test_config_card_id(unsigned int id) { - if (!ap_configuration) /* QCI not supported */ - /* only ids 0...3F may be probed */ - return id < 0x40 ? 1 : 0; - return ap_test_config(ap_configuration->apm, id); + if (id > ap_max_adapter_id) + return 0; + if (ap_qci_info) + return ap_test_config(ap_qci_info->apm, id); + return 1; } /* * ap_test_config_usage_domain(): Test, whether an AP usage domain * is configured. - * @domain AP usage domain ID * * Returns 0 if the usage domain is not configured * 1 if the usage domain is configured or @@ -263,9 +280,11 @@ */ int ap_test_config_usage_domain(unsigned int domain) { - if (!ap_configuration) /* QCI not supported */ - return domain < 16; - return ap_test_config(ap_configuration->aqm, domain); + if (domain > ap_max_domain_id) + return 0; + if (ap_qci_info) + return ap_test_config(ap_qci_info->aqm, domain); + return 1; } EXPORT_SYMBOL(ap_test_config_usage_domain); @@ -279,43 +298,62 @@ */ int ap_test_config_ctrl_domain(unsigned int domain) { - if (!ap_configuration) /* QCI not supported */ + if (!ap_qci_info || domain > ap_max_domain_id) return 0; - return ap_test_config(ap_configuration->adm, domain); + return ap_test_config(ap_qci_info->adm, domain); } EXPORT_SYMBOL(ap_test_config_ctrl_domain); -/** - * ap_query_queue(): Check if an AP queue is available. - * @qid: The AP queue number - * @queue_depth: Pointer to queue depth value - * @device_type: Pointer to device type value - * @facilities: Pointer to facility indicator +/* + * ap_queue_info(): Check and get AP queue info. + * Returns true if TAPQ succeeded and the info is filled or + * false otherwise. */ -static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type, - unsigned int *facilities) +static bool ap_queue_info(ap_qid_t qid, int *q_type, unsigned int *q_fac, + int *q_depth, int *q_ml, bool *q_decfg) { struct ap_queue_status status; - unsigned long info; - int nd; - - if (!ap_test_config_card_id(AP_QID_CARD(qid))) - return -ENODEV; + union { + unsigned long value; + struct { + unsigned int fac : 32; /* facility bits */ + unsigned int at : 8; /* ap type */ + unsigned int _res1 : 8; + unsigned int _res2 : 4; + unsigned int ml : 4; /* apxl ml */ + unsigned int _res3 : 4; + unsigned int qd : 4; /* queue depth */ + } tapq_gr2; + } tapq_info; + + tapq_info.value = 0; + + /* make sure we don't run into a specifiation exception */ + if (AP_QID_CARD(qid) > ap_max_adapter_id || + AP_QID_QUEUE(qid) > ap_max_domain_id) + return false; - status = ap_test_queue(qid, ap_apft_available(), &info); + /* call TAPQ on this APQN */ + status = ap_test_queue(qid, ap_apft_available(), &tapq_info.value); switch (status.response_code) { case AP_RESPONSE_NORMAL: - *queue_depth = (int)(info & 0xff); - *device_type = (int)((info >> 24) & 0xff); - *facilities = (unsigned int)(info >> 32); - /* Update maximum domain id */ - nd = (info >> 16) & 0xff; - /* if N bit is available, z13 and newer */ - if ((info & (1UL << 57)) && nd > 0) - ap_max_domain_id = nd; - else /* older machine types */ - ap_max_domain_id = 15; - switch (*device_type) { + case AP_RESPONSE_RESET_IN_PROGRESS: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + case AP_RESPONSE_BUSY: + /* + * According to the architecture in all these cases the + * info should be filled. All bits 0 is not possible as + * there is at least one of the mode bits set. + */ + if (WARN_ON_ONCE(!tapq_info.value)) + return false; + *q_type = tapq_info.tapq_gr2.at; + *q_fac = tapq_info.tapq_gr2.fac; + *q_depth = tapq_info.tapq_gr2.qd; + *q_ml = tapq_info.tapq_gr2.ml; + *q_decfg = status.response_code == AP_RESPONSE_DECONFIGURED; + switch (*q_type) { /* For CEX2 and CEX3 the available functions * are not reflected by the facilities bits. * Instead it is coded into the type. So here @@ -323,45 +361,39 @@ */ case AP_DEVICE_TYPE_CEX2A: case AP_DEVICE_TYPE_CEX3A: - *facilities |= 0x08000000; + *q_fac |= 0x08000000; break; case AP_DEVICE_TYPE_CEX2C: case AP_DEVICE_TYPE_CEX3C: - *facilities |= 0x10000000; + *q_fac |= 0x10000000; break; default: break; } - return 0; - case AP_RESPONSE_Q_NOT_AVAIL: - case AP_RESPONSE_DECONFIGURED: - case AP_RESPONSE_CHECKSTOPPED: - case AP_RESPONSE_INVALID_ADDRESS: - return -ENODEV; - case AP_RESPONSE_RESET_IN_PROGRESS: - case AP_RESPONSE_OTHERWISE_CHANGED: - case AP_RESPONSE_BUSY: - return -EBUSY; + return true; default: - BUG(); + /* + * A response code which indicates, there is no info available. + */ + return false; } } -void ap_wait(enum ap_wait wait) +void ap_wait(enum ap_sm_wait wait) { ktime_t hr_time; switch (wait) { - case AP_WAIT_AGAIN: - case AP_WAIT_INTERRUPT: + case AP_SM_WAIT_AGAIN: + case AP_SM_WAIT_INTERRUPT: if (ap_using_interrupts()) break; if (ap_poll_kthread) { wake_up(&ap_poll_wait); break; } - /* Fall through */ - case AP_WAIT_TIMEOUT: + fallthrough; + case AP_SM_WAIT_TIMEOUT: spin_lock_bh(&ap_poll_timer_lock); if (!hrtimer_is_queued(&ap_poll_timer)) { hr_time = poll_timeout; @@ -370,7 +402,7 @@ } spin_unlock_bh(&ap_poll_timer_lock); break; - case AP_WAIT_NONE: + case AP_SM_WAIT_NONE: default: break; } @@ -386,10 +418,8 @@ { struct ap_queue *aq = from_timer(aq, t, timeout); - if (ap_suspend_flag) - return; spin_lock_bh(&aq->lock); - ap_wait(ap_sm_event(aq, AP_EVENT_TIMEOUT)); + ap_wait(ap_sm_event(aq, AP_SM_EVENT_TIMEOUT)); spin_unlock_bh(&aq->lock); } @@ -401,8 +431,7 @@ */ static enum hrtimer_restart ap_poll_timeout(struct hrtimer *unused) { - if (!ap_suspend_flag) - tasklet_schedule(&ap_tasklet); + tasklet_schedule(&ap_tasklet); return HRTIMER_NORESTART; } @@ -413,8 +442,7 @@ static void ap_interrupt_handler(struct airq_struct *airq, bool floating) { inc_irq_stat(IRQIO_APB); - if (!ap_suspend_flag) - tasklet_schedule(&ap_tasklet); + tasklet_schedule(&ap_tasklet); } /** @@ -425,9 +453,9 @@ */ static void ap_tasklet_fn(unsigned long dummy) { - struct ap_card *ac; + int bkt; struct ap_queue *aq; - enum ap_wait wait = AP_WAIT_NONE; + enum ap_sm_wait wait = AP_SM_WAIT_NONE; /* Reset the indicator if interrupts are used. Thus new interrupts can * be received. Doing it in the beginning of the tasklet is therefor @@ -436,34 +464,30 @@ if (ap_using_interrupts()) xchg(ap_airq.lsi_ptr, 0); - spin_lock_bh(&ap_list_lock); - for_each_ap_card(ac) { - for_each_ap_queue(aq, ac) { - spin_lock_bh(&aq->lock); - wait = min(wait, ap_sm_event_loop(aq, AP_EVENT_POLL)); - spin_unlock_bh(&aq->lock); - } + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) { + spin_lock_bh(&aq->lock); + wait = min(wait, ap_sm_event_loop(aq, AP_SM_EVENT_POLL)); + spin_unlock_bh(&aq->lock); } - spin_unlock_bh(&ap_list_lock); + spin_unlock_bh(&ap_queues_lock); ap_wait(wait); } static int ap_pending_requests(void) { - struct ap_card *ac; + int bkt; struct ap_queue *aq; - spin_lock_bh(&ap_list_lock); - for_each_ap_card(ac) { - for_each_ap_queue(aq, ac) { - if (aq->queue_count == 0) - continue; - spin_unlock_bh(&ap_list_lock); - return 1; - } + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) { + if (aq->queue_count == 0) + continue; + spin_unlock_bh(&ap_queues_lock); + return 1; } - spin_unlock_bh(&ap_list_lock); + spin_unlock_bh(&ap_queues_lock); return 0; } @@ -486,7 +510,7 @@ while (!kthread_should_stop()) { add_wait_queue(&ap_poll_wait, &wait); set_current_state(TASK_INTERRUPTIBLE); - if (ap_suspend_flag || !ap_pending_requests()) { + if (!ap_pending_requests()) { schedule(); try_to_freeze(); } @@ -587,51 +611,6 @@ return retval; } -static int ap_dev_suspend(struct device *dev) -{ - struct ap_device *ap_dev = to_ap_dev(dev); - - if (ap_dev->drv && ap_dev->drv->suspend) - ap_dev->drv->suspend(ap_dev); - return 0; -} - -static int ap_dev_resume(struct device *dev) -{ - struct ap_device *ap_dev = to_ap_dev(dev); - - if (ap_dev->drv && ap_dev->drv->resume) - ap_dev->drv->resume(ap_dev); - return 0; -} - -static void ap_bus_suspend(void) -{ - AP_DBF(DBF_DEBUG, "%s running\n", __func__); - - ap_suspend_flag = 1; - /* - * Disable scanning for devices, thus we do not want to scan - * for them after removing. - */ - flush_work(&ap_scan_work); - tasklet_disable(&ap_tasklet); -} - -static int __ap_card_devices_unregister(struct device *dev, void *dummy) -{ - if (is_card_dev(dev)) - device_unregister(dev); - return 0; -} - -static int __ap_queue_devices_unregister(struct device *dev, void *dummy) -{ - if (is_queue_dev(dev)) - device_unregister(dev); - return 0; -} - static int __ap_queue_devices_with_id_unregister(struct device *dev, void *data) { if (is_queue_dev(dev) && @@ -640,67 +619,10 @@ return 0; } -static void ap_bus_resume(void) -{ - int rc; - - AP_DBF(DBF_DEBUG, "%s running\n", __func__); - - /* remove all queue devices */ - bus_for_each_dev(&ap_bus_type, NULL, NULL, - __ap_queue_devices_unregister); - /* remove all card devices */ - bus_for_each_dev(&ap_bus_type, NULL, NULL, - __ap_card_devices_unregister); - - /* Reset thin interrupt setting */ - if (ap_interrupts_available() && !ap_using_interrupts()) { - rc = register_adapter_interrupt(&ap_airq); - ap_airq_flag = (rc == 0); - } - if (!ap_interrupts_available() && ap_using_interrupts()) { - unregister_adapter_interrupt(&ap_airq); - ap_airq_flag = 0; - } - /* Reset domain */ - if (!user_set_domain) - ap_domain_index = -1; - /* Get things going again */ - ap_suspend_flag = 0; - if (ap_airq_flag) - xchg(ap_airq.lsi_ptr, 0); - tasklet_enable(&ap_tasklet); - queue_work(system_long_wq, &ap_scan_work); -} - -static int ap_power_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - switch (event) { - case PM_HIBERNATION_PREPARE: - case PM_SUSPEND_PREPARE: - ap_bus_suspend(); - break; - case PM_POST_HIBERNATION: - case PM_POST_SUSPEND: - ap_bus_resume(); - break; - default: - break; - } - return NOTIFY_DONE; -} -static struct notifier_block ap_power_notifier = { - .notifier_call = ap_power_event, -}; - -static SIMPLE_DEV_PM_OPS(ap_bus_pm_ops, ap_dev_suspend, ap_dev_resume); - static struct bus_type ap_bus_type = { .name = "ap", .match = &ap_bus_match, .uevent = &ap_uevent, - .pm = &ap_bus_pm_ops, }; static int __ap_revise_reserved(struct device *dev, void *dummy) @@ -717,8 +639,8 @@ drvres = to_ap_drv(dev->driver)->flags & AP_DRIVER_FLAG_DEFAULT; if (!!devres != !!drvres) { - AP_DBF(DBF_DEBUG, "reprobing queue=%02x.%04x\n", - card, queue); + AP_DBF_DBG("reprobing queue=%02x.%04x\n", + card, queue); rc = device_reprobe(dev); } } @@ -775,7 +697,10 @@ { struct ap_device *ap_dev = to_ap_dev(dev); struct ap_driver *ap_drv = to_ap_drv(dev->driver); - int card, queue, devres, drvres, rc; + int card, queue, devres, drvres, rc = -ENODEV; + + if (!get_device(dev)) + return rc; if (is_queue_dev(dev)) { /* @@ -792,33 +717,30 @@ mutex_unlock(&ap_perms_mutex); drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT; if (!!devres != !!drvres) - return -ENODEV; - /* (re-)init queue's state machine */ - ap_queue_reinit_state(to_ap_queue(dev)); + goto out; } /* Add queue/card to list of active queues/cards */ - spin_lock_bh(&ap_list_lock); - if (is_card_dev(dev)) - list_add(&to_ap_card(dev)->list, &ap_card_list); - else - list_add(&to_ap_queue(dev)->list, - &to_ap_queue(dev)->card->queues); - spin_unlock_bh(&ap_list_lock); + spin_lock_bh(&ap_queues_lock); + if (is_queue_dev(dev)) + hash_add(ap_queues, &to_ap_queue(dev)->hnode, + to_ap_queue(dev)->qid); + spin_unlock_bh(&ap_queues_lock); ap_dev->drv = ap_drv; rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; if (rc) { - spin_lock_bh(&ap_list_lock); - if (is_card_dev(dev)) - list_del_init(&to_ap_card(dev)->list); - else - list_del_init(&to_ap_queue(dev)->list); - spin_unlock_bh(&ap_list_lock); + spin_lock_bh(&ap_queues_lock); + if (is_queue_dev(dev)) + hash_del(&to_ap_queue(dev)->hnode); + spin_unlock_bh(&ap_queues_lock); ap_dev->drv = NULL; } +out: + if (rc) + put_device(dev); return rc; } @@ -840,24 +762,40 @@ ap_queue_remove(to_ap_queue(dev)); /* Remove queue/card from list of active queues/cards */ - spin_lock_bh(&ap_list_lock); - if (is_card_dev(dev)) - list_del_init(&to_ap_card(dev)->list); - else - list_del_init(&to_ap_queue(dev)->list); - spin_unlock_bh(&ap_list_lock); + spin_lock_bh(&ap_queues_lock); + if (is_queue_dev(dev)) + hash_del(&to_ap_queue(dev)->hnode); + spin_unlock_bh(&ap_queues_lock); + + put_device(dev); return 0; } +struct ap_queue *ap_get_qdev(ap_qid_t qid) +{ + int bkt; + struct ap_queue *aq; + + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) { + if (aq->qid == qid) { + get_device(&aq->ap_dev.device); + spin_unlock_bh(&ap_queues_lock); + return aq; + } + } + spin_unlock_bh(&ap_queues_lock); + + return NULL; +} +EXPORT_SYMBOL(ap_get_qdev); + int ap_driver_register(struct ap_driver *ap_drv, struct module *owner, char *name) { struct device_driver *drv = &ap_drv->driver; - if (!initialised) - return -ENODEV; - drv->bus = &ap_bus_type; drv->probe = ap_device_probe; drv->remove = ap_device_remove; @@ -875,8 +813,6 @@ void ap_bus_force_rescan(void) { - if (ap_suspend_flag) - return; /* processing a asynchronous bus rescan */ del_timer(&ap_config_timer); queue_work(system_long_wq, &ap_scan_work); @@ -889,7 +825,7 @@ */ void ap_bus_cfg_chg(void) { - AP_DBF(DBF_INFO, "%s config change, forcing bus rescan\n", __func__); + AP_DBF_DBG("%s config change, forcing bus rescan\n", __func__); ap_bus_force_rescan(); } @@ -949,7 +885,7 @@ */ static int modify_bitmap(const char *str, unsigned long *bitmap, int bits) { - int a, i, z; + unsigned long a, i, z; char *np, sign; /* bits needs to be a multiple of 8 */ @@ -1023,7 +959,7 @@ static ssize_t ap_domain_show(struct bus_type *bus, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index); + return scnprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index); } static ssize_t ap_domain_store(struct bus_type *bus, @@ -1035,11 +971,12 @@ domain < 0 || domain > ap_max_domain_id || !test_bit_inv(domain, ap_perms.aqm)) return -EINVAL; + spin_lock_bh(&ap_domain_lock); ap_domain_index = domain; spin_unlock_bh(&ap_domain_lock); - AP_DBF(DBF_DEBUG, "stored new default domain=%d\n", domain); + AP_DBF_INFO("stored new default domain=%d\n", domain); return count; } @@ -1048,60 +985,60 @@ static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf) { - if (!ap_configuration) /* QCI not supported */ - return snprintf(buf, PAGE_SIZE, "not supported\n"); + if (!ap_qci_info) /* QCI not supported */ + return scnprintf(buf, PAGE_SIZE, "not supported\n"); - return snprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_configuration->adm[0], ap_configuration->adm[1], - ap_configuration->adm[2], ap_configuration->adm[3], - ap_configuration->adm[4], ap_configuration->adm[5], - ap_configuration->adm[6], ap_configuration->adm[7]); + return scnprintf(buf, PAGE_SIZE, + "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->adm[0], ap_qci_info->adm[1], + ap_qci_info->adm[2], ap_qci_info->adm[3], + ap_qci_info->adm[4], ap_qci_info->adm[5], + ap_qci_info->adm[6], ap_qci_info->adm[7]); } static BUS_ATTR_RO(ap_control_domain_mask); static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf) { - if (!ap_configuration) /* QCI not supported */ - return snprintf(buf, PAGE_SIZE, "not supported\n"); + if (!ap_qci_info) /* QCI not supported */ + return scnprintf(buf, PAGE_SIZE, "not supported\n"); - return snprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_configuration->aqm[0], ap_configuration->aqm[1], - ap_configuration->aqm[2], ap_configuration->aqm[3], - ap_configuration->aqm[4], ap_configuration->aqm[5], - ap_configuration->aqm[6], ap_configuration->aqm[7]); + return scnprintf(buf, PAGE_SIZE, + "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->aqm[0], ap_qci_info->aqm[1], + ap_qci_info->aqm[2], ap_qci_info->aqm[3], + ap_qci_info->aqm[4], ap_qci_info->aqm[5], + ap_qci_info->aqm[6], ap_qci_info->aqm[7]); } static BUS_ATTR_RO(ap_usage_domain_mask); static ssize_t ap_adapter_mask_show(struct bus_type *bus, char *buf) { - if (!ap_configuration) /* QCI not supported */ - return snprintf(buf, PAGE_SIZE, "not supported\n"); + if (!ap_qci_info) /* QCI not supported */ + return scnprintf(buf, PAGE_SIZE, "not supported\n"); - return snprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_configuration->apm[0], ap_configuration->apm[1], - ap_configuration->apm[2], ap_configuration->apm[3], - ap_configuration->apm[4], ap_configuration->apm[5], - ap_configuration->apm[6], ap_configuration->apm[7]); + return scnprintf(buf, PAGE_SIZE, + "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->apm[0], ap_qci_info->apm[1], + ap_qci_info->apm[2], ap_qci_info->apm[3], + ap_qci_info->apm[4], ap_qci_info->apm[5], + ap_qci_info->apm[6], ap_qci_info->apm[7]); } static BUS_ATTR_RO(ap_adapter_mask); static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", - ap_using_interrupts() ? 1 : 0); + return scnprintf(buf, PAGE_SIZE, "%d\n", + ap_using_interrupts() ? 1 : 0); } static BUS_ATTR_RO(ap_interrupts); static ssize_t config_time_show(struct bus_type *bus, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ap_config_time); + return scnprintf(buf, PAGE_SIZE, "%d\n", ap_config_time); } static ssize_t config_time_store(struct bus_type *bus, @@ -1120,7 +1057,7 @@ static ssize_t poll_thread_show(struct bus_type *bus, char *buf) { - return snprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0); + return scnprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0); } static ssize_t poll_thread_store(struct bus_type *bus, @@ -1143,7 +1080,7 @@ static ssize_t poll_timeout_show(struct bus_type *bus, char *buf) { - return snprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout); + return scnprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout); } static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, @@ -1172,27 +1109,28 @@ static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf) { - int max_domain_id; - - if (ap_configuration) - max_domain_id = ap_max_domain_id ? : -1; - else - max_domain_id = 15; - return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id); + return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_domain_id); } static BUS_ATTR_RO(ap_max_domain_id); +static ssize_t ap_max_adapter_id_show(struct bus_type *bus, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_adapter_id); +} + +static BUS_ATTR_RO(ap_max_adapter_id); + static ssize_t apmask_show(struct bus_type *bus, char *buf) { int rc; if (mutex_lock_interruptible(&ap_perms_mutex)) return -ERESTARTSYS; - rc = snprintf(buf, PAGE_SIZE, - "0x%016lx%016lx%016lx%016lx\n", - ap_perms.apm[0], ap_perms.apm[1], - ap_perms.apm[2], ap_perms.apm[3]); + rc = scnprintf(buf, PAGE_SIZE, + "0x%016lx%016lx%016lx%016lx\n", + ap_perms.apm[0], ap_perms.apm[1], + ap_perms.apm[2], ap_perms.apm[3]); mutex_unlock(&ap_perms_mutex); return rc; @@ -1220,10 +1158,10 @@ if (mutex_lock_interruptible(&ap_perms_mutex)) return -ERESTARTSYS; - rc = snprintf(buf, PAGE_SIZE, - "0x%016lx%016lx%016lx%016lx\n", - ap_perms.aqm[0], ap_perms.aqm[1], - ap_perms.aqm[2], ap_perms.aqm[3]); + rc = scnprintf(buf, PAGE_SIZE, + "0x%016lx%016lx%016lx%016lx\n", + ap_perms.aqm[0], ap_perms.aqm[1], + ap_perms.aqm[2], ap_perms.aqm[3]); mutex_unlock(&ap_perms_mutex); return rc; @@ -1255,6 +1193,7 @@ &bus_attr_ap_interrupts, &bus_attr_poll_timeout, &bus_attr_ap_max_domain_id, + &bus_attr_ap_max_adapter_id, &bus_attr_apmask, &bus_attr_aqmask, NULL, @@ -1266,47 +1205,42 @@ */ static void ap_select_domain(void) { - int count, max_count, best_domain; struct ap_queue_status status; - int i, j; + int card, dom; /* - * We want to use a single domain. Either the one specified with - * the "domain=" parameter or the domain with the maximum number - * of devices. + * Choose the default domain. Either the one specified with + * the "domain=" parameter or the first domain with at least + * one valid APQN. */ spin_lock_bh(&ap_domain_lock); if (ap_domain_index >= 0) { /* Domain has already been selected. */ - spin_unlock_bh(&ap_domain_lock); - return; + goto out; } - best_domain = -1; - max_count = 0; - for (i = 0; i < AP_DOMAINS; i++) { - if (!ap_test_config_usage_domain(i) || - !test_bit_inv(i, ap_perms.aqm)) + for (dom = 0; dom <= ap_max_domain_id; dom++) { + if (!ap_test_config_usage_domain(dom) || + !test_bit_inv(dom, ap_perms.aqm)) continue; - count = 0; - for (j = 0; j < AP_DEVICES; j++) { - if (!ap_test_config_card_id(j)) + for (card = 0; card <= ap_max_adapter_id; card++) { + if (!ap_test_config_card_id(card) || + !test_bit_inv(card, ap_perms.apm)) continue; - status = ap_test_queue(AP_MKQID(j, i), + status = ap_test_queue(AP_MKQID(card, dom), ap_apft_available(), NULL); - if (status.response_code != AP_RESPONSE_NORMAL) - continue; - count++; - } - if (count > max_count) { - max_count = count; - best_domain = i; + if (status.response_code == AP_RESPONSE_NORMAL) + break; } + if (card <= ap_max_adapter_id) + break; } - if (best_domain >= 0) { - ap_domain_index = best_domain; - AP_DBF(DBF_DEBUG, "new ap_domain_index=%d\n", ap_domain_index); + if (dom <= ap_max_domain_id) { + ap_domain_index = dom; + AP_DBF_INFO("%s new default domain is %d\n", + __func__, ap_domain_index); } +out: spin_unlock_bh(&ap_domain_lock); } @@ -1320,8 +1254,11 @@ int comp_type = 0; /* < CEX2A is not supported */ - if (rawtype < AP_DEVICE_TYPE_CEX2A) + if (rawtype < AP_DEVICE_TYPE_CEX2A) { + AP_DBF_WARN("get_comp_type queue=%02x.%04x unsupported type %d\n", + AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype); return 0; + } /* up to CEX7 known and fully supported */ if (rawtype <= AP_DEVICE_TYPE_CEX7) return rawtype; @@ -1343,11 +1280,12 @@ comp_type = apinfo.cat; } if (!comp_type) - AP_DBF(DBF_WARN, "queue=%02x.%04x unable to map type %d\n", - AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype); + AP_DBF_WARN("get_comp_type queue=%02x.%04x unable to map type %d\n", + AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype); else if (comp_type != rawtype) - AP_DBF(DBF_INFO, "queue=%02x.%04x map type %d to %d\n", - AP_QID_CARD(qid), AP_QID_QUEUE(qid), rawtype, comp_type); + AP_DBF_INFO("get_comp_type queue=%02x.%04x map type %d to %d\n", + AP_QID_CARD(qid), AP_QID_QUEUE(qid), + rawtype, comp_type); return comp_type; } @@ -1381,156 +1319,287 @@ /* * Helper function for ap_scan_bus(). - * Does the scan bus job for the given adapter id. + * Remove card device and associated queue devices. + */ +static inline void ap_scan_rm_card_dev_and_queue_devs(struct ap_card *ac) +{ + bus_for_each_dev(&ap_bus_type, NULL, + (void *)(long) ac->id, + __ap_queue_devices_with_id_unregister); + device_unregister(&ac->ap_dev.device); +} + +/* + * Helper function for ap_scan_bus(). + * Does the scan bus job for all the domains within + * a valid adapter given by an ap_card ptr. */ -static void _ap_scan_bus_adapter(int id) +static inline void ap_scan_domains(struct ap_card *ac) { + bool decfg; ap_qid_t qid; unsigned int func; - struct ap_card *ac; struct device *dev; struct ap_queue *aq; - int rc, dom, depth, type, comp_type, borked; - - /* check if there is a card device registered with this id */ - dev = bus_find_device(&ap_bus_type, NULL, - (void *)(long) id, - __match_card_device_with_id); - ac = dev ? to_ap_card(dev) : NULL; - if (!ap_test_config_card_id(id)) { - if (dev) { - /* Card device has been removed from configuration */ - bus_for_each_dev(&ap_bus_type, NULL, - (void *)(long) id, - __ap_queue_devices_with_id_unregister); - device_unregister(dev); - put_device(dev); - } - return; - } + int rc, dom, depth, type, ml; /* - * This card id is enabled in the configuration. If we already have - * a card device with this id, check if type and functions are still - * the very same. Also verify that at least one queue is available. + * Go through the configuration for the domains and compare them + * to the existing queue devices. Also take care of the config + * and error state for the queue devices. */ - if (ac) { - /* find the first valid queue */ - for (dom = 0; dom < AP_DOMAINS; dom++) { - qid = AP_MKQID(id, dom); - if (ap_query_queue(qid, &depth, &type, &func) == 0) - break; - } - borked = 0; - if (dom >= AP_DOMAINS) { - /* no accessible queue on this card */ - borked = 1; - } else if (ac->raw_hwtype != type) { - /* card type has changed */ - AP_DBF(DBF_INFO, "card=%02x type changed.\n", id); - borked = 1; - } else if (ac->functions != func) { - /* card functions have changed */ - AP_DBF(DBF_INFO, "card=%02x functions changed.\n", id); - borked = 1; - } - if (borked) { - /* unregister card device and associated queues */ - bus_for_each_dev(&ap_bus_type, NULL, - (void *)(long) id, - __ap_queue_devices_with_id_unregister); - device_unregister(dev); - put_device(dev); - /* go back if there is no valid queue on this card */ - if (dom >= AP_DOMAINS) - return; - ac = NULL; - } - } - /* - * Go through all possible queue ids. Check and maybe create or release - * queue devices for this card. If there exists no card device yet, - * create a card device also. - */ - for (dom = 0; dom < AP_DOMAINS; dom++) { - qid = AP_MKQID(id, dom); + for (dom = 0; dom <= ap_max_domain_id; dom++) { + qid = AP_MKQID(ac->id, dom); dev = bus_find_device(&ap_bus_type, NULL, (void *)(long) qid, __match_queue_device_with_qid); aq = dev ? to_ap_queue(dev) : NULL; if (!ap_test_config_usage_domain(dom)) { if (dev) { - /* Queue device exists but has been - * removed from configuration. - */ + AP_DBF_INFO("%s(%d,%d) not in config any more, rm queue device\n", + __func__, ac->id, dom); device_unregister(dev); put_device(dev); } continue; } - /* try to fetch infos about this queue */ - rc = ap_query_queue(qid, &depth, &type, &func); - if (dev) { - if (rc == -ENODEV) - borked = 1; - else { - spin_lock_bh(&aq->lock); - borked = aq->state == AP_STATE_BORKED; - spin_unlock_bh(&aq->lock); - } - if (borked) { - /* Remove broken device */ - AP_DBF(DBF_DEBUG, - "removing broken queue=%02x.%04x\n", - id, dom); + /* domain is valid, get info from this APQN */ + if (!ap_queue_info(qid, &type, &func, &depth, &ml, &decfg)) { + if (aq) { + AP_DBF_INFO( + "%s(%d,%d) ap_queue_info() not successful, rm queue device\n", + __func__, ac->id, dom); device_unregister(dev); + put_device(dev); } - put_device(dev); continue; } - if (rc) - continue; - /* a new queue device is needed, check out comp type */ - comp_type = ap_get_compatible_type(qid, type, func); - if (!comp_type) - continue; - /* maybe a card device needs to be created first */ - if (!ac) { - ac = ap_card_create(id, depth, type, comp_type, func); - if (!ac) + /* if no queue device exists, create a new one */ + if (!aq) { + aq = ap_queue_create(qid, ac->ap_dev.device_type); + if (!aq) { + AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", + __func__, ac->id, dom); continue; - ac->ap_dev.device.bus = &ap_bus_type; - ac->ap_dev.device.parent = ap_root_device; - dev_set_name(&ac->ap_dev.device, "card%02x", id); - /* Register card device with AP bus */ - rc = device_register(&ac->ap_dev.device); + } + aq->card = ac; + aq->config = !decfg; + dev = &aq->ap_dev.device; + dev->bus = &ap_bus_type; + dev->parent = &ac->ap_dev.device; + dev_set_name(dev, "%02x.%04x", ac->id, dom); + /* register queue device */ + rc = device_register(dev); if (rc) { - put_device(&ac->ap_dev.device); - ac = NULL; - break; + AP_DBF_WARN("%s(%d,%d) device_register() failed\n", + __func__, ac->id, dom); + goto put_dev_and_continue; } /* get it and thus adjust reference counter */ - get_device(&ac->ap_dev.device); + get_device(dev); + if (decfg) + AP_DBF_INFO("%s(%d,%d) new (decfg) queue device created\n", + __func__, ac->id, dom); + else + AP_DBF_INFO("%s(%d,%d) new queue device created\n", + __func__, ac->id, dom); + goto put_dev_and_continue; } - /* now create the new queue device */ - aq = ap_queue_create(qid, comp_type); - if (!aq) - continue; - aq->card = ac; - aq->ap_dev.device.bus = &ap_bus_type; - aq->ap_dev.device.parent = &ac->ap_dev.device; - dev_set_name(&aq->ap_dev.device, "%02x.%04x", id, dom); - /* Register queue device */ - rc = device_register(&aq->ap_dev.device); + /* Check config state on the already existing queue device */ + spin_lock_bh(&aq->lock); + if (decfg && aq->config) { + /* config off this queue device */ + aq->config = false; + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = AP_RESPONSE_DECONFIGURED; + } + spin_unlock_bh(&aq->lock); + AP_DBF_INFO("%s(%d,%d) queue device config off\n", + __func__, ac->id, dom); + /* 'receive' pending messages with -EAGAIN */ + ap_flush_queue(aq); + goto put_dev_and_continue; + } + if (!decfg && !aq->config) { + /* config on this queue device */ + aq->config = true; + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { + aq->dev_state = AP_DEV_STATE_OPERATING; + aq->sm_state = AP_SM_STATE_RESET_START; + } + spin_unlock_bh(&aq->lock); + AP_DBF_INFO("%s(%d,%d) queue device config on\n", + __func__, ac->id, dom); + goto put_dev_and_continue; + } + /* handle other error states */ + if (!decfg && aq->dev_state == AP_DEV_STATE_ERROR) { + spin_unlock_bh(&aq->lock); + /* 'receive' pending messages with -EAGAIN */ + ap_flush_queue(aq); + /* re-init (with reset) the queue device */ + ap_queue_init_state(aq); + AP_DBF_INFO("%s(%d,%d) queue device reinit enforced\n", + __func__, ac->id, dom); + goto put_dev_and_continue; + } + spin_unlock_bh(&aq->lock); +put_dev_and_continue: + put_device(dev); + } +} + +/* + * Helper function for ap_scan_bus(). + * Does the scan bus job for the given adapter id. + */ +static inline void ap_scan_adapter(int ap) +{ + bool decfg; + ap_qid_t qid; + unsigned int func; + struct device *dev; + struct ap_card *ac; + int rc, dom, depth, type, comp_type, ml; + + /* Is there currently a card device for this adapter ? */ + dev = bus_find_device(&ap_bus_type, NULL, + (void *)(long) ap, + __match_card_device_with_id); + ac = dev ? to_ap_card(dev) : NULL; + + /* Adapter not in configuration ? */ + if (!ap_test_config_card_id(ap)) { + if (ac) { + AP_DBF_INFO("%s(%d) ap not in config any more, rm card and queue devices\n", + __func__, ap); + ap_scan_rm_card_dev_and_queue_devs(ac); + put_device(dev); + } + return; + } + + /* + * Adapter ap is valid in the current configuration. So do some checks: + * If no card device exists, build one. If a card device exists, check + * for type and functions changed. For all this we need to find a valid + * APQN first. + */ + + for (dom = 0; dom <= ap_max_domain_id; dom++) + if (ap_test_config_usage_domain(dom)) { + qid = AP_MKQID(ap, dom); + if (ap_queue_info(qid, &type, &func, + &depth, &ml, &decfg)) + break; + } + if (dom > ap_max_domain_id) { + /* Could not find a valid APQN for this adapter */ + if (ac) { + AP_DBF_INFO( + "%s(%d) no type info (no APQN found), rm card and queue devices\n", + __func__, ap); + ap_scan_rm_card_dev_and_queue_devs(ac); + put_device(dev); + } else { + AP_DBF_DBG("%s(%d) no type info (no APQN found), ignored\n", + __func__, ap); + } + return; + } + if (!type) { + /* No apdater type info available, an unusable adapter */ + if (ac) { + AP_DBF_INFO("%s(%d) no valid type (0) info, rm card and queue devices\n", + __func__, ap); + ap_scan_rm_card_dev_and_queue_devs(ac); + put_device(dev); + } else { + AP_DBF_DBG("%s(%d) no valid type (0) info, ignored\n", + __func__, ap); + } + return; + } + + if (ac) { + /* Check APQN against existing card device for changes */ + if (ac->raw_hwtype != type) { + AP_DBF_INFO("%s(%d) hwtype %d changed, rm card and queue devices\n", + __func__, ap, type); + ap_scan_rm_card_dev_and_queue_devs(ac); + put_device(dev); + ac = NULL; + } else if (ac->functions != func) { + AP_DBF_INFO("%s(%d) functions 0x%08x changed, rm card and queue devices\n", + __func__, ap, type); + ap_scan_rm_card_dev_and_queue_devs(ac); + put_device(dev); + ac = NULL; + } else { + if (decfg && ac->config) { + ac->config = false; + AP_DBF_INFO("%s(%d) card device config off\n", + __func__, ap); + + } + if (!decfg && !ac->config) { + ac->config = true; + AP_DBF_INFO("%s(%d) card device config on\n", + __func__, ap); + } + } + } + + if (!ac) { + /* Build a new card device */ + comp_type = ap_get_compatible_type(qid, type, func); + if (!comp_type) { + AP_DBF_WARN("%s(%d) type %d, can't get compatibility type\n", + __func__, ap, type); + return; + } + ac = ap_card_create(ap, depth, type, comp_type, func, ml); + if (!ac) { + AP_DBF_WARN("%s(%d) ap_card_create() failed\n", + __func__, ap); + return; + } + ac->config = !decfg; + dev = &ac->ap_dev.device; + dev->bus = &ap_bus_type; + dev->parent = ap_root_device; + dev_set_name(dev, "card%02x", ap); + /* maybe enlarge ap_max_msg_size to support this card */ + if (ac->maxmsgsize > atomic_read(&ap_max_msg_size)) { + atomic_set(&ap_max_msg_size, ac->maxmsgsize); + AP_DBF_INFO("%s(%d) ap_max_msg_size update to %d byte\n", + __func__, ap, atomic_read(&ap_max_msg_size)); + } + /* Register the new card device with AP bus */ + rc = device_register(dev); if (rc) { - put_device(&aq->ap_dev.device); - continue; + AP_DBF_WARN("%s(%d) device_register() failed\n", + __func__, ap); + put_device(dev); + return; } - } /* end domain loop */ + /* get it and thus adjust reference counter */ + get_device(dev); + if (decfg) + AP_DBF_INFO("%s(%d) new (decfg) card device type=%d func=0x%08x created\n", + __func__, ap, type, func); + else + AP_DBF_INFO("%s(%d) new card device type=%d func=0x%08x created\n", + __func__, ap, type, func); + } + + /* Verify the domains and the queue devices for this card */ + ap_scan_domains(ac); - if (ac) - put_device(&ac->ap_dev.device); + /* release the card device */ + put_device(&ac->ap_dev.device); } /** @@ -1539,16 +1608,16 @@ */ static void ap_scan_bus(struct work_struct *unused) { - int id; + int ap; - AP_DBF(DBF_DEBUG, "%s running\n", __func__); - - ap_query_configuration(ap_configuration); + ap_fetch_qci_info(ap_qci_info); ap_select_domain(); + AP_DBF_DBG("%s running\n", __func__); + /* loop over all possible adapters */ - for (id = 0; id < AP_DEVICES; id++) - _ap_scan_bus_adapter(id); + for (ap = 0; ap <= ap_max_adapter_id; ap++) + ap_scan_adapter(ap); /* check if there is at least one queue available with default domain */ if (ap_domain_index >= 0) { @@ -1559,9 +1628,8 @@ if (dev) put_device(dev); else - AP_DBF(DBF_INFO, - "no queue device with default domain %d available\n", - ap_domain_index); + AP_DBF_INFO("no queue device with default domain %d available\n", + ap_domain_index); } mod_timer(&ap_config_timer, jiffies + ap_config_time * HZ); @@ -1569,8 +1637,6 @@ static void ap_config_timeout(struct timer_list *unused) { - if (ap_suspend_flag) - return; queue_work(system_long_wq, &ap_scan_work); } @@ -1613,7 +1679,6 @@ */ static int __init ap_module_init(void) { - int max_domain_id; int rc, i; rc = ap_debug_init(); @@ -1625,30 +1690,25 @@ return -ENODEV; } + /* init ap_queue hashtable */ + hash_init(ap_queues); + /* set up the AP permissions (ioctls, ap and aq masks) */ ap_perms_init(); /* Get AP configuration data if available */ - ap_init_configuration(); + ap_init_qci_info(); - if (ap_configuration) - max_domain_id = - ap_max_domain_id ? ap_max_domain_id : AP_DOMAINS - 1; - else - max_domain_id = 15; - if (ap_domain_index < -1 || ap_domain_index > max_domain_id || + /* check default domain setting */ + if (ap_domain_index < -1 || ap_domain_index > ap_max_domain_id || (ap_domain_index >= 0 && !test_bit_inv(ap_domain_index, ap_perms.aqm))) { pr_warn("%d is not a valid cryptographic domain\n", ap_domain_index); ap_domain_index = -1; } - /* In resume callback we need to know if the user had set the domain. - * If so, we can not just reset it. - */ - if (ap_domain_index >= 0) - user_set_domain = 1; + /* enable interrupts if available */ if (ap_interrupts_available()) { rc = register_adapter_interrupt(&ap_airq); ap_airq_flag = (rc == 0); @@ -1679,7 +1739,6 @@ */ if (MACHINE_IS_VM) poll_timeout = 1500000; - spin_lock_init(&ap_poll_timer_lock); hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); ap_poll_timer.function = ap_poll_timeout; @@ -1690,17 +1749,10 @@ goto out_work; } - rc = register_pm_notifier(&ap_power_notifier); - if (rc) - goto out_pm; - queue_work(system_long_wq, &ap_scan_work); - initialised = true; return 0; -out_pm: - ap_poll_thread_stop(); out_work: hrtimer_cancel(&ap_poll_timer); root_device_unregister(ap_root_device); @@ -1711,7 +1763,7 @@ out: if (ap_using_interrupts()) unregister_adapter_interrupt(&ap_airq); - kfree(ap_configuration); + kfree(ap_qci_info); return rc; } device_initcall(ap_module_init); --- linux-oracle-5.4.0.orig/drivers/s390/crypto/ap_bus.h +++ linux-oracle-5.4.0/drivers/s390/crypto/ap_bus.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -24,11 +25,14 @@ #define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */ #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ +#define AP_DEFAULT_MAX_MSG_SIZE (12 * 1024) +#define AP_TAPQ_ML_FIELD_CHUNK_SIZE (4096) extern int ap_domain_index; +extern atomic_t ap_max_msg_size; -extern spinlock_t ap_list_lock; -extern struct list_head ap_card_list; +extern DECLARE_HASHTABLE(ap_queues, 8); +extern spinlock_t ap_queues_lock; static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) { @@ -49,6 +53,7 @@ #define AP_RESPONSE_NO_FIRST_PART 0x13 #define AP_RESPONSE_MESSAGE_TOO_BIG 0x15 #define AP_RESPONSE_REQ_FAC_NOT_INST 0x16 +#define AP_RESPONSE_INVALID_DOMAIN 0x42 /* * Known device types @@ -82,40 +87,47 @@ #define AP_INTR_ENABLED 1 /* AP interrupt enabled */ /* - * AP device states + * AP queue state machine states */ -enum ap_state { - AP_STATE_RESET_START, - AP_STATE_RESET_WAIT, - AP_STATE_SETIRQ_WAIT, - AP_STATE_IDLE, - AP_STATE_WORKING, - AP_STATE_QUEUE_FULL, - AP_STATE_SUSPEND_WAIT, - AP_STATE_REMOVE, /* about to be removed from driver */ - AP_STATE_UNBOUND, /* momentary not bound to a driver */ - AP_STATE_BORKED, /* broken */ - NR_AP_STATES +enum ap_sm_state { + AP_SM_STATE_RESET_START = 0, + AP_SM_STATE_RESET_WAIT, + AP_SM_STATE_SETIRQ_WAIT, + AP_SM_STATE_IDLE, + AP_SM_STATE_WORKING, + AP_SM_STATE_QUEUE_FULL, + NR_AP_SM_STATES }; /* - * AP device events + * AP queue state machine events */ -enum ap_event { - AP_EVENT_POLL, - AP_EVENT_TIMEOUT, - NR_AP_EVENTS +enum ap_sm_event { + AP_SM_EVENT_POLL, + AP_SM_EVENT_TIMEOUT, + NR_AP_SM_EVENTS }; /* - * AP wait behaviour + * AP queue state wait behaviour */ -enum ap_wait { - AP_WAIT_AGAIN, /* retry immediately */ - AP_WAIT_TIMEOUT, /* wait for timeout */ - AP_WAIT_INTERRUPT, /* wait for thin interrupt (if available) */ - AP_WAIT_NONE, /* no wait */ - NR_AP_WAIT +enum ap_sm_wait { + AP_SM_WAIT_AGAIN, /* retry immediately */ + AP_SM_WAIT_TIMEOUT, /* wait for timeout */ + AP_SM_WAIT_INTERRUPT, /* wait for thin interrupt (if available) */ + AP_SM_WAIT_NONE, /* no wait */ + NR_AP_SM_WAIT +}; + +/* + * AP queue device states + */ +enum ap_dev_state { + AP_DEV_STATE_UNINITIATED = 0, /* fresh and virgin, not touched */ + AP_DEV_STATE_OPERATING, /* queue dev is working normal */ + AP_DEV_STATE_SHUTDOWN, /* remove/unbind/shutdown in progress */ + AP_DEV_STATE_ERROR, /* device is in error state */ + NR_AP_DEV_STATES }; struct ap_device; @@ -136,8 +148,6 @@ int (*probe)(struct ap_device *); void (*remove)(struct ap_device *); - void (*suspend)(struct ap_device *); - void (*resume)(struct ap_device *); }; #define to_ap_drv(x) container_of((x), struct ap_driver, driver) @@ -155,56 +165,86 @@ struct ap_card { struct ap_device ap_dev; - struct list_head list; /* Private list of AP cards. */ - struct list_head queues; /* List of assoc. AP queues */ void *private; /* ap driver private pointer. */ int raw_hwtype; /* AP raw hardware type. */ unsigned int functions; /* AP device function bitfield. */ int queue_depth; /* AP queue depth.*/ int id; /* AP card number. */ - atomic_t total_request_count; /* # requests ever for this AP device.*/ + unsigned int maxmsgsize; /* AP msg limit for this card */ + bool config; /* configured state */ + atomic64_t total_request_count; /* # requests ever for this AP device.*/ }; #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device) struct ap_queue { struct ap_device ap_dev; - struct list_head list; /* Private list of AP queues. */ + struct hlist_node hnode; /* Node for the ap_queues hashtable */ struct ap_card *card; /* Ptr to assoc. AP card. */ spinlock_t lock; /* Per device lock. */ void *private; /* ap driver private pointer. */ + enum ap_dev_state dev_state; /* queue device state */ + bool config; /* configured state */ ap_qid_t qid; /* AP queue id. */ int interrupt; /* indicate if interrupts are enabled */ int queue_count; /* # messages currently on AP queue. */ - enum ap_state state; /* State of the AP device. */ int pendingq_count; /* # requests on pendingq list. */ int requestq_count; /* # requests on requestq list. */ - int total_request_count; /* # requests ever for this AP device.*/ + u64 total_request_count; /* # requests ever for this AP device.*/ int request_timeout; /* Request timeout in jiffies. */ struct timer_list timeout; /* Timer for request timeouts. */ struct list_head pendingq; /* List of message sent to AP queue. */ struct list_head requestq; /* List of message yet to be sent. */ struct ap_message *reply; /* Per device reply message. */ + enum ap_sm_state sm_state; /* ap queue state machine state */ + int last_err_rc; /* last error state response code */ }; #define to_ap_queue(x) container_of((x), struct ap_queue, ap_dev.device) -typedef enum ap_wait (ap_func_t)(struct ap_queue *queue); +typedef enum ap_sm_wait (ap_func_t)(struct ap_queue *queue); + +/* failure injection cmd struct */ +struct ap_fi { + union { + u16 cmd; /* fi flags + action */ + struct { + u8 flags; /* fi flags only */ + u8 action; /* fi action only */ + }; + }; +}; + +/* all currently known fi actions */ +enum ap_fi_actions { + AP_FI_ACTION_CCA_AGENT_FF = 0x01, + AP_FI_ACTION_CCA_DOM_INVAL = 0x02, + AP_FI_ACTION_NQAP_QID_INVAL = 0x03, +}; + +/* all currently known fi flags */ +enum ap_fi_flags { + AP_FI_FLAG_NO_RETRY = 0x01, + AP_FI_FLAG_TOGGLE_SPECIAL = 0x02, +}; struct ap_message { struct list_head list; /* Request queueing. */ unsigned long long psmid; /* Message id. */ - void *message; /* Pointer to message buffer. */ - size_t length; /* Message length. */ + void *msg; /* Pointer to message buffer. */ + unsigned int len; /* actual msg len in msg buffer */ + unsigned int bufsize; /* allocated msg buffer size */ + u16 flags; /* Flags, see AP_MSG_FLAG_xxx */ + struct ap_fi fi; /* Failure Injection cmd */ int rc; /* Return code for this message */ - void *private; /* ap driver private pointer. */ - unsigned int special:1; /* Used for special commands. */ /* receive is called from tasklet context */ void (*receive)(struct ap_queue *, struct ap_message *, struct ap_message *); }; +#define AP_MSG_FLAG_SPECIAL 1 /* flag msg as 'special' with NQAP */ + /** * ap_init_message() - Initialize ap_message. * Initialize a message before using. Otherwise this might result in @@ -222,16 +262,10 @@ */ static inline void ap_release_message(struct ap_message *ap_msg) { - kzfree(ap_msg->message); + kzfree(ap_msg->msg); kzfree(ap_msg->private); } -#define for_each_ap_card(_ac) \ - list_for_each_entry(_ac, &ap_card_list, list) - -#define for_each_ap_queue(_aq, _ac) \ - list_for_each_entry(_aq, &(_ac)->queues, list) - /* * Note: don't use ap_send/ap_recv after using ap_queue_message * for the first time. Otherwise the ap message queue will get @@ -240,15 +274,15 @@ int ap_send(ap_qid_t, unsigned long long, void *, size_t); int ap_recv(ap_qid_t, unsigned long long *, void *, size_t); -enum ap_wait ap_sm_event(struct ap_queue *aq, enum ap_event event); -enum ap_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_event event); +enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event); +enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event); -void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg); +int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg); void ap_cancel_message(struct ap_queue *aq, struct ap_message *ap_msg); void ap_flush_queue(struct ap_queue *aq); void *ap_airq_ptr(void); -void ap_wait(enum ap_wait wait); +void ap_wait(enum ap_sm_wait wait); void ap_request_timeout(struct timer_list *t); void ap_bus_force_rescan(void); @@ -259,12 +293,10 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); void ap_queue_prepare_remove(struct ap_queue *aq); void ap_queue_remove(struct ap_queue *aq); -void ap_queue_suspend(struct ap_device *ap_dev); -void ap_queue_resume(struct ap_device *ap_dev); -void ap_queue_reinit_state(struct ap_queue *aq); +void ap_queue_init_state(struct ap_queue *aq); -struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type, - int comp_device_type, unsigned int functions); +struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, + int comp_type, unsigned int functions, int ml); struct ap_perms { unsigned long ioctlm[BITS_TO_LONGS(AP_IOCTLS)]; @@ -275,6 +307,16 @@ extern struct mutex ap_perms_mutex; /* + * Get ap_queue device for this qid. + * Returns ptr to the struct ap_queue device or NULL if there + * was no ap_queue device with this qid found. When something is + * found, the reference count of the embedded device is increased. + * So the caller has to decrease the reference count after use + * with a call to put_device(&aq->ap_dev.device). + */ +struct ap_queue *ap_get_qdev(ap_qid_t qid); + +/* * check APQN for owned/reserved by ap bus and default driver(s). * Checks if this APQN is or will be in use by the ap bus * and the default set of drivers. --- linux-oracle-5.4.0.orig/drivers/s390/crypto/ap_card.c +++ linux-oracle-5.4.0/drivers/s390/crypto/ap_card.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "ap_bus.h" @@ -23,7 +24,7 @@ { struct ap_card *ac = to_ap_card(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type); + return scnprintf(buf, PAGE_SIZE, "%d\n", ac->ap_dev.device_type); } static DEVICE_ATTR_RO(hwtype); @@ -33,7 +34,7 @@ { struct ap_card *ac = to_ap_card(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype); + return scnprintf(buf, PAGE_SIZE, "%d\n", ac->raw_hwtype); } static DEVICE_ATTR_RO(raw_hwtype); @@ -43,7 +44,7 @@ { struct ap_card *ac = to_ap_card(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth); + return scnprintf(buf, PAGE_SIZE, "%d\n", ac->queue_depth); } static DEVICE_ATTR_RO(depth); @@ -53,7 +54,7 @@ { struct ap_card *ac = to_ap_card(dev); - return snprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions); + return scnprintf(buf, PAGE_SIZE, "0x%08X\n", ac->functions); } static DEVICE_ATTR_RO(ap_functions); @@ -63,27 +64,29 @@ char *buf) { struct ap_card *ac = to_ap_card(dev); - unsigned int req_cnt; + u64 req_cnt; req_cnt = 0; - spin_lock_bh(&ap_list_lock); - req_cnt = atomic_read(&ac->total_request_count); - spin_unlock_bh(&ap_list_lock); - return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); + spin_lock_bh(&ap_queues_lock); + req_cnt = atomic64_read(&ac->total_request_count); + spin_unlock_bh(&ap_queues_lock); + return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); } static ssize_t request_count_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct ap_card *ac = to_ap_card(dev); + int bkt; struct ap_queue *aq; + struct ap_card *ac = to_ap_card(dev); - spin_lock_bh(&ap_list_lock); - for_each_ap_queue(aq, ac) - aq->total_request_count = 0; - spin_unlock_bh(&ap_list_lock); - atomic_set(&ac->total_request_count, 0); + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) + if (ac == aq->card) + aq->total_request_count = 0; + spin_unlock_bh(&ap_queues_lock); + atomic64_set(&ac->total_request_count, 0); return count; } @@ -93,16 +96,18 @@ static ssize_t requestq_count_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ap_card *ac = to_ap_card(dev); + int bkt; struct ap_queue *aq; unsigned int reqq_cnt; + struct ap_card *ac = to_ap_card(dev); reqq_cnt = 0; - spin_lock_bh(&ap_list_lock); - for_each_ap_queue(aq, ac) - reqq_cnt += aq->requestq_count; - spin_unlock_bh(&ap_list_lock); - return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) + if (ac == aq->card) + reqq_cnt += aq->requestq_count; + spin_unlock_bh(&ap_queues_lock); + return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); } static DEVICE_ATTR_RO(requestq_count); @@ -110,16 +115,18 @@ static ssize_t pendingq_count_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ap_card *ac = to_ap_card(dev); + int bkt; struct ap_queue *aq; unsigned int penq_cnt; + struct ap_card *ac = to_ap_card(dev); penq_cnt = 0; - spin_lock_bh(&ap_list_lock); - for_each_ap_queue(aq, ac) - penq_cnt += aq->pendingq_count; - spin_unlock_bh(&ap_list_lock); - return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); + spin_lock_bh(&ap_queues_lock); + hash_for_each(ap_queues, bkt, aq, hnode) + if (ac == aq->card) + penq_cnt += aq->pendingq_count; + spin_unlock_bh(&ap_queues_lock); + return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); } static DEVICE_ATTR_RO(pendingq_count); @@ -127,11 +134,54 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sprintf(buf, "ap:t%02X\n", to_ap_dev(dev)->device_type); + return scnprintf(buf, PAGE_SIZE, "ap:t%02X\n", + to_ap_dev(dev)->device_type); } static DEVICE_ATTR_RO(modalias); +static ssize_t config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_card *ac = to_ap_card(dev); + + return scnprintf(buf, PAGE_SIZE, "%d\n", ac->config ? 1 : 0); +} + +static ssize_t config_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0, cfg; + struct ap_card *ac = to_ap_card(dev); + + if (sscanf(buf, "%d\n", &cfg) != 1 || cfg < 0 || cfg > 1) + return -EINVAL; + + if (cfg && !ac->config) + rc = sclp_ap_configure(ac->id); + else if (!cfg && ac->config) + rc = sclp_ap_deconfigure(ac->id); + if (rc) + return rc; + + ac->config = cfg ? true : false; + + return count; +} + +static DEVICE_ATTR_RW(config); + +static ssize_t max_msg_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_card *ac = to_ap_card(dev); + + return scnprintf(buf, PAGE_SIZE, "%u\n", ac->maxmsgsize); +} + +static DEVICE_ATTR_RO(max_msg_size); + static struct attribute *ap_card_dev_attrs[] = { &dev_attr_hwtype.attr, &dev_attr_raw_hwtype.attr, @@ -141,6 +191,8 @@ &dev_attr_requestq_count.attr, &dev_attr_pendingq_count.attr, &dev_attr_modalias.attr, + &dev_attr_config.attr, + &dev_attr_max_msg_size.attr, NULL }; @@ -162,24 +214,17 @@ { struct ap_card *ac = to_ap_card(dev); - if (!list_empty(&ac->list)) { - spin_lock_bh(&ap_list_lock); - list_del_init(&ac->list); - spin_unlock_bh(&ap_list_lock); - } kfree(ac); } struct ap_card *ap_card_create(int id, int queue_depth, int raw_type, - int comp_type, unsigned int functions) + int comp_type, unsigned int functions, int ml) { struct ap_card *ac; ac = kzalloc(sizeof(*ac), GFP_KERNEL); if (!ac) return NULL; - INIT_LIST_HEAD(&ac->list); - INIT_LIST_HEAD(&ac->queues); ac->ap_dev.device.release = ap_card_device_release; ac->ap_dev.device.type = &ap_card_type; ac->ap_dev.device_type = comp_type; @@ -187,5 +232,8 @@ ac->queue_depth = queue_depth; ac->functions = functions; ac->id = id; + ac->maxmsgsize = ml > 0 ? + ml * AP_TAPQ_ML_FIELD_CHUNK_SIZE : AP_DEFAULT_MAX_MSG_SIZE; + return ac; } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/ap_debug.h +++ linux-oracle-5.4.0/drivers/s390/crypto/ap_debug.h @@ -20,6 +20,14 @@ #define AP_DBF(...) \ debug_sprintf_event(ap_dbf_info, ##__VA_ARGS__) +#define AP_DBF_ERR(...) \ + debug_sprintf_event(ap_dbf_info, DBF_ERR, ##__VA_ARGS__) +#define AP_DBF_WARN(...) \ + debug_sprintf_event(ap_dbf_info, DBF_WARN, ##__VA_ARGS__) +#define AP_DBF_INFO(...) \ + debug_sprintf_event(ap_dbf_info, DBF_INFO, ##__VA_ARGS__) +#define AP_DBF_DBG(...) \ + debug_sprintf_event(ap_dbf_info, DBF_DEBUG, ##__VA_ARGS__) extern debug_info_t *ap_dbf_info; --- linux-oracle-5.4.0.orig/drivers/s390/crypto/ap_queue.c +++ linux-oracle-5.4.0/drivers/s390/crypto/ap_queue.c @@ -69,9 +69,9 @@ */ static inline struct ap_queue_status __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length, - unsigned int special) + int special) { - if (special == 1) + if (special) qid |= 0x400000UL; return ap_nqap(qid, psmid, msg, length); } @@ -119,9 +119,9 @@ /* State machine definitions and helpers */ -static enum ap_wait ap_sm_nop(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_nop(struct ap_queue *aq) { - return AP_WAIT_NONE; + return AP_SM_WAIT_NONE; } /** @@ -129,18 +129,19 @@ * not change the state of the device. * @aq: pointer to the AP queue * - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT */ static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) { struct ap_queue_status status; struct ap_message *ap_msg; + bool found = false; status = ap_dqap(aq->qid, &aq->reply->psmid, - aq->reply->message, aq->reply->length); + aq->reply->msg, aq->reply->bufsize); switch (status.response_code) { case AP_RESPONSE_NORMAL: - aq->queue_count--; + aq->queue_count = max_t(int, 0, aq->queue_count - 1); if (aq->queue_count > 0) mod_timer(&aq->timeout, jiffies + aq->request_timeout); @@ -150,9 +151,15 @@ list_del_init(&ap_msg->list); aq->pendingq_count--; ap_msg->receive(aq, ap_msg, aq->reply); + found = true; break; } - /* fall through */ + if (!found) { + AP_DBF_WARN("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n", + __func__, aq->reply->psmid, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + } + fallthrough; case AP_RESPONSE_NO_PENDING_REPLY: if (!status.queue_empty || aq->queue_count <= 0) break; @@ -172,56 +179,35 @@ * ap_sm_read(): Receive pending reply messages from an AP queue. * @aq: pointer to the AP queue * - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT */ -static enum ap_wait ap_sm_read(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_read(struct ap_queue *aq) { struct ap_queue_status status; if (!aq->reply) - return AP_WAIT_NONE; + return AP_SM_WAIT_NONE; status = ap_sm_recv(aq); switch (status.response_code) { case AP_RESPONSE_NORMAL: if (aq->queue_count > 0) { - aq->state = AP_STATE_WORKING; - return AP_WAIT_AGAIN; + aq->sm_state = AP_SM_STATE_WORKING; + return AP_SM_WAIT_AGAIN; } - aq->state = AP_STATE_IDLE; - return AP_WAIT_NONE; + aq->sm_state = AP_SM_STATE_IDLE; + return AP_SM_WAIT_NONE; case AP_RESPONSE_NO_PENDING_REPLY: if (aq->queue_count > 0) - return AP_WAIT_INTERRUPT; - aq->state = AP_STATE_IDLE; - return AP_WAIT_NONE; - default: - aq->state = AP_STATE_BORKED; - return AP_WAIT_NONE; - } -} - -/** - * ap_sm_suspend_read(): Receive pending reply messages from an AP queue - * without changing the device state in between. In suspend mode we don't - * allow sending new requests, therefore just fetch pending replies. - * @aq: pointer to the AP queue - * - * Returns AP_WAIT_NONE or AP_WAIT_AGAIN - */ -static enum ap_wait ap_sm_suspend_read(struct ap_queue *aq) -{ - struct ap_queue_status status; - - if (!aq->reply) - return AP_WAIT_NONE; - status = ap_sm_recv(aq); - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - if (aq->queue_count > 0) - return AP_WAIT_AGAIN; - /* fall through */ + return AP_SM_WAIT_INTERRUPT; + aq->sm_state = AP_SM_STATE_IDLE; + return AP_SM_WAIT_NONE; default: - return AP_WAIT_NONE; + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = status.response_code; + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return AP_SM_WAIT_NONE; } } @@ -229,48 +215,64 @@ * ap_sm_write(): Send messages from the request queue to an AP queue. * @aq: pointer to the AP queue * - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT */ -static enum ap_wait ap_sm_write(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_write(struct ap_queue *aq) { struct ap_queue_status status; struct ap_message *ap_msg; + ap_qid_t qid = aq->qid; if (aq->requestq_count <= 0) - return AP_WAIT_NONE; + return AP_SM_WAIT_NONE; /* Start the next request on the queue. */ ap_msg = list_entry(aq->requestq.next, struct ap_message, list); - status = __ap_send(aq->qid, ap_msg->psmid, - ap_msg->message, ap_msg->length, ap_msg->special); +#ifdef CONFIG_ZCRYPT_DEBUG + if (ap_msg->fi.action == AP_FI_ACTION_NQAP_QID_INVAL) { + AP_DBF_WARN("%s fi cmd 0x%04x: forcing invalid qid 0xFF00\n", + __func__, ap_msg->fi.cmd); + qid = 0xFF00; + } +#endif + status = __ap_send(qid, ap_msg->psmid, + ap_msg->msg, ap_msg->len, + ap_msg->flags & AP_MSG_FLAG_SPECIAL); switch (status.response_code) { case AP_RESPONSE_NORMAL: - aq->queue_count++; + aq->queue_count = max_t(int, 1, aq->queue_count + 1); if (aq->queue_count == 1) mod_timer(&aq->timeout, jiffies + aq->request_timeout); list_move_tail(&ap_msg->list, &aq->pendingq); aq->requestq_count--; aq->pendingq_count++; if (aq->queue_count < aq->card->queue_depth) { - aq->state = AP_STATE_WORKING; - return AP_WAIT_AGAIN; + aq->sm_state = AP_SM_STATE_WORKING; + return AP_SM_WAIT_AGAIN; } - /* fall through */ + fallthrough; case AP_RESPONSE_Q_FULL: - aq->state = AP_STATE_QUEUE_FULL; - return AP_WAIT_INTERRUPT; + aq->sm_state = AP_SM_STATE_QUEUE_FULL; + return AP_SM_WAIT_INTERRUPT; case AP_RESPONSE_RESET_IN_PROGRESS: - aq->state = AP_STATE_RESET_WAIT; - return AP_WAIT_TIMEOUT; + aq->sm_state = AP_SM_STATE_RESET_WAIT; + return AP_SM_WAIT_TIMEOUT; + case AP_RESPONSE_INVALID_DOMAIN: + AP_DBF(DBF_WARN, "AP_RESPONSE_INVALID_DOMAIN on NQAP\n"); + fallthrough; case AP_RESPONSE_MESSAGE_TOO_BIG: case AP_RESPONSE_REQ_FAC_NOT_INST: list_del_init(&ap_msg->list); aq->requestq_count--; ap_msg->rc = -EINVAL; ap_msg->receive(aq, ap_msg, NULL); - return AP_WAIT_AGAIN; + return AP_SM_WAIT_AGAIN; default: - aq->state = AP_STATE_BORKED; - return AP_WAIT_NONE; + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = status.response_code; + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return AP_SM_WAIT_NONE; } } @@ -278,9 +280,9 @@ * ap_sm_read_write(): Send and receive messages to/from an AP queue. * @aq: pointer to the AP queue * - * Returns AP_WAIT_NONE, AP_WAIT_AGAIN, or AP_WAIT_INTERRUPT + * Returns AP_SM_WAIT_NONE, AP_SM_WAIT_AGAIN, or AP_SM_WAIT_INTERRUPT */ -static enum ap_wait ap_sm_read_write(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_read_write(struct ap_queue *aq) { return min(ap_sm_read(aq), ap_sm_write(aq)); } @@ -291,7 +293,7 @@ * * Submit the Reset command to an AP queue. */ -static enum ap_wait ap_sm_reset(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_reset(struct ap_queue *aq) { struct ap_queue_status status; @@ -299,17 +301,16 @@ switch (status.response_code) { case AP_RESPONSE_NORMAL: case AP_RESPONSE_RESET_IN_PROGRESS: - aq->state = AP_STATE_RESET_WAIT; + aq->sm_state = AP_SM_STATE_RESET_WAIT; aq->interrupt = AP_INTR_DISABLED; - return AP_WAIT_TIMEOUT; - case AP_RESPONSE_BUSY: - return AP_WAIT_TIMEOUT; - case AP_RESPONSE_Q_NOT_AVAIL: - case AP_RESPONSE_DECONFIGURED: - case AP_RESPONSE_CHECKSTOPPED: + return AP_SM_WAIT_TIMEOUT; default: - aq->state = AP_STATE_BORKED; - return AP_WAIT_NONE; + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = status.response_code; + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return AP_SM_WAIT_NONE; } } @@ -319,7 +320,7 @@ * * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0. */ -static enum ap_wait ap_sm_reset_wait(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_reset_wait(struct ap_queue *aq) { struct ap_queue_status status; void *lsi_ptr; @@ -335,20 +336,24 @@ case AP_RESPONSE_NORMAL: lsi_ptr = ap_airq_ptr(); if (lsi_ptr && ap_queue_enable_interruption(aq, lsi_ptr) == 0) - aq->state = AP_STATE_SETIRQ_WAIT; + aq->sm_state = AP_SM_STATE_SETIRQ_WAIT; else - aq->state = (aq->queue_count > 0) ? - AP_STATE_WORKING : AP_STATE_IDLE; - return AP_WAIT_AGAIN; + aq->sm_state = (aq->queue_count > 0) ? + AP_SM_STATE_WORKING : AP_SM_STATE_IDLE; + return AP_SM_WAIT_AGAIN; case AP_RESPONSE_BUSY: case AP_RESPONSE_RESET_IN_PROGRESS: - return AP_WAIT_TIMEOUT; + return AP_SM_WAIT_TIMEOUT; case AP_RESPONSE_Q_NOT_AVAIL: case AP_RESPONSE_DECONFIGURED: case AP_RESPONSE_CHECKSTOPPED: default: - aq->state = AP_STATE_BORKED; - return AP_WAIT_NONE; + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = status.response_code; + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return AP_SM_WAIT_NONE; } } @@ -358,7 +363,7 @@ * * Returns AP_POLL_IMMEDIATELY, AP_POLL_AFTER_TIMEROUT or 0. */ -static enum ap_wait ap_sm_setirq_wait(struct ap_queue *aq) +static enum ap_sm_wait ap_sm_setirq_wait(struct ap_queue *aq) { struct ap_queue_status status; @@ -372,106 +377,75 @@ if (status.irq_enabled == 1) { /* Irqs are now enabled */ aq->interrupt = AP_INTR_ENABLED; - aq->state = (aq->queue_count > 0) ? - AP_STATE_WORKING : AP_STATE_IDLE; + aq->sm_state = (aq->queue_count > 0) ? + AP_SM_STATE_WORKING : AP_SM_STATE_IDLE; } switch (status.response_code) { case AP_RESPONSE_NORMAL: if (aq->queue_count > 0) - return AP_WAIT_AGAIN; - /* fallthrough */ + return AP_SM_WAIT_AGAIN; + fallthrough; case AP_RESPONSE_NO_PENDING_REPLY: - return AP_WAIT_TIMEOUT; + return AP_SM_WAIT_TIMEOUT; default: - aq->state = AP_STATE_BORKED; - return AP_WAIT_NONE; + aq->dev_state = AP_DEV_STATE_ERROR; + aq->last_err_rc = status.response_code; + AP_DBF_WARN("%s RC 0x%02x on 0x%02x.%04x -> AP_DEV_STATE_ERROR\n", + __func__, status.response_code, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + return AP_SM_WAIT_NONE; } } /* * AP state machine jump table */ -static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = { - [AP_STATE_RESET_START] = { - [AP_EVENT_POLL] = ap_sm_reset, - [AP_EVENT_TIMEOUT] = ap_sm_nop, - }, - [AP_STATE_RESET_WAIT] = { - [AP_EVENT_POLL] = ap_sm_reset_wait, - [AP_EVENT_TIMEOUT] = ap_sm_nop, - }, - [AP_STATE_SETIRQ_WAIT] = { - [AP_EVENT_POLL] = ap_sm_setirq_wait, - [AP_EVENT_TIMEOUT] = ap_sm_nop, +static ap_func_t *ap_jumptable[NR_AP_SM_STATES][NR_AP_SM_EVENTS] = { + [AP_SM_STATE_RESET_START] = { + [AP_SM_EVENT_POLL] = ap_sm_reset, + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, }, - [AP_STATE_IDLE] = { - [AP_EVENT_POLL] = ap_sm_write, - [AP_EVENT_TIMEOUT] = ap_sm_nop, + [AP_SM_STATE_RESET_WAIT] = { + [AP_SM_EVENT_POLL] = ap_sm_reset_wait, + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, }, - [AP_STATE_WORKING] = { - [AP_EVENT_POLL] = ap_sm_read_write, - [AP_EVENT_TIMEOUT] = ap_sm_reset, + [AP_SM_STATE_SETIRQ_WAIT] = { + [AP_SM_EVENT_POLL] = ap_sm_setirq_wait, + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, }, - [AP_STATE_QUEUE_FULL] = { - [AP_EVENT_POLL] = ap_sm_read, - [AP_EVENT_TIMEOUT] = ap_sm_reset, + [AP_SM_STATE_IDLE] = { + [AP_SM_EVENT_POLL] = ap_sm_write, + [AP_SM_EVENT_TIMEOUT] = ap_sm_nop, }, - [AP_STATE_SUSPEND_WAIT] = { - [AP_EVENT_POLL] = ap_sm_suspend_read, - [AP_EVENT_TIMEOUT] = ap_sm_nop, + [AP_SM_STATE_WORKING] = { + [AP_SM_EVENT_POLL] = ap_sm_read_write, + [AP_SM_EVENT_TIMEOUT] = ap_sm_reset, }, - [AP_STATE_REMOVE] = { - [AP_EVENT_POLL] = ap_sm_nop, - [AP_EVENT_TIMEOUT] = ap_sm_nop, - }, - [AP_STATE_UNBOUND] = { - [AP_EVENT_POLL] = ap_sm_nop, - [AP_EVENT_TIMEOUT] = ap_sm_nop, - }, - [AP_STATE_BORKED] = { - [AP_EVENT_POLL] = ap_sm_nop, - [AP_EVENT_TIMEOUT] = ap_sm_nop, + [AP_SM_STATE_QUEUE_FULL] = { + [AP_SM_EVENT_POLL] = ap_sm_read, + [AP_SM_EVENT_TIMEOUT] = ap_sm_reset, }, }; -enum ap_wait ap_sm_event(struct ap_queue *aq, enum ap_event event) +enum ap_sm_wait ap_sm_event(struct ap_queue *aq, enum ap_sm_event event) { - return ap_jumptable[aq->state][event](aq); + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) + return ap_jumptable[aq->sm_state][event](aq); + else + return AP_SM_WAIT_NONE; } -enum ap_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_event event) +enum ap_sm_wait ap_sm_event_loop(struct ap_queue *aq, enum ap_sm_event event) { - enum ap_wait wait; + enum ap_sm_wait wait; - while ((wait = ap_sm_event(aq, event)) == AP_WAIT_AGAIN) + while ((wait = ap_sm_event(aq, event)) == AP_SM_WAIT_AGAIN) ; return wait; } /* - * Power management for queue devices - */ -void ap_queue_suspend(struct ap_device *ap_dev) -{ - struct ap_queue *aq = to_ap_queue(&ap_dev->device); - - /* Poll on the device until all requests are finished. */ - spin_lock_bh(&aq->lock); - aq->state = AP_STATE_SUSPEND_WAIT; - while (ap_sm_event(aq, AP_EVENT_POLL) != AP_WAIT_NONE) - ; - aq->state = AP_STATE_BORKED; - spin_unlock_bh(&aq->lock); -} -EXPORT_SYMBOL(ap_queue_suspend); - -void ap_queue_resume(struct ap_device *ap_dev) -{ -} -EXPORT_SYMBOL(ap_queue_resume); - -/* * AP queue related attributes. */ static ssize_t request_count_show(struct device *dev, @@ -479,12 +453,20 @@ char *buf) { struct ap_queue *aq = to_ap_queue(dev); - unsigned int req_cnt; + bool valid = false; + u64 req_cnt; spin_lock_bh(&aq->lock); - req_cnt = aq->total_request_count; + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) { + req_cnt = aq->total_request_count; + valid = true; + } spin_unlock_bh(&aq->lock); - return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); + + if (valid) + return scnprintf(buf, PAGE_SIZE, "%llu\n", req_cnt); + else + return scnprintf(buf, PAGE_SIZE, "-\n"); } static ssize_t request_count_store(struct device *dev, @@ -509,9 +491,10 @@ unsigned int reqq_cnt = 0; spin_lock_bh(&aq->lock); - reqq_cnt = aq->requestq_count; + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) + reqq_cnt = aq->requestq_count; spin_unlock_bh(&aq->lock); - return snprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); + return scnprintf(buf, PAGE_SIZE, "%d\n", reqq_cnt); } static DEVICE_ATTR_RO(requestq_count); @@ -523,9 +506,10 @@ unsigned int penq_cnt = 0; spin_lock_bh(&aq->lock); - penq_cnt = aq->pendingq_count; + if (aq->dev_state > AP_DEV_STATE_UNINITIATED) + penq_cnt = aq->pendingq_count; spin_unlock_bh(&aq->lock); - return snprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); + return scnprintf(buf, PAGE_SIZE, "%d\n", penq_cnt); } static DEVICE_ATTR_RO(pendingq_count); @@ -537,17 +521,17 @@ int rc = 0; spin_lock_bh(&aq->lock); - switch (aq->state) { - case AP_STATE_RESET_START: - case AP_STATE_RESET_WAIT: - rc = snprintf(buf, PAGE_SIZE, "Reset in progress.\n"); + switch (aq->sm_state) { + case AP_SM_STATE_RESET_START: + case AP_SM_STATE_RESET_WAIT: + rc = scnprintf(buf, PAGE_SIZE, "Reset in progress.\n"); break; - case AP_STATE_WORKING: - case AP_STATE_QUEUE_FULL: - rc = snprintf(buf, PAGE_SIZE, "Reset Timer armed.\n"); + case AP_SM_STATE_WORKING: + case AP_SM_STATE_QUEUE_FULL: + rc = scnprintf(buf, PAGE_SIZE, "Reset Timer armed.\n"); break; default: - rc = snprintf(buf, PAGE_SIZE, "No Reset Timer set.\n"); + rc = scnprintf(buf, PAGE_SIZE, "No Reset Timer set.\n"); } spin_unlock_bh(&aq->lock); return rc; @@ -561,8 +545,8 @@ spin_lock_bh(&aq->lock); __ap_flush_queue(aq); - aq->state = AP_STATE_RESET_START; - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); + aq->sm_state = AP_SM_STATE_RESET_START; + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); spin_unlock_bh(&aq->lock); AP_DBF(DBF_INFO, "reset queue=%02x.%04x triggered by user\n", @@ -580,24 +564,150 @@ int rc = 0; spin_lock_bh(&aq->lock); - if (aq->state == AP_STATE_SETIRQ_WAIT) - rc = snprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n"); + if (aq->sm_state == AP_SM_STATE_SETIRQ_WAIT) + rc = scnprintf(buf, PAGE_SIZE, "Enable Interrupt pending.\n"); else if (aq->interrupt == AP_INTR_ENABLED) - rc = snprintf(buf, PAGE_SIZE, "Interrupts enabled.\n"); + rc = scnprintf(buf, PAGE_SIZE, "Interrupts enabled.\n"); else - rc = snprintf(buf, PAGE_SIZE, "Interrupts disabled.\n"); + rc = scnprintf(buf, PAGE_SIZE, "Interrupts disabled.\n"); spin_unlock_bh(&aq->lock); return rc; } static DEVICE_ATTR_RO(interrupt); +static ssize_t config_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_queue *aq = to_ap_queue(dev); + int rc; + + spin_lock_bh(&aq->lock); + rc = scnprintf(buf, PAGE_SIZE, "%d\n", aq->config ? 1 : 0); + spin_unlock_bh(&aq->lock); + return rc; +} + +static DEVICE_ATTR_RO(config); + +#ifdef CONFIG_ZCRYPT_DEBUG +static ssize_t states_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_queue *aq = to_ap_queue(dev); + int rc = 0; + + spin_lock_bh(&aq->lock); + /* queue device state */ + switch (aq->dev_state) { + case AP_DEV_STATE_UNINITIATED: + rc = scnprintf(buf, PAGE_SIZE, "UNINITIATED\n"); + break; + case AP_DEV_STATE_OPERATING: + rc = scnprintf(buf, PAGE_SIZE, "OPERATING"); + break; + case AP_DEV_STATE_SHUTDOWN: + rc = scnprintf(buf, PAGE_SIZE, "SHUTDOWN"); + break; + case AP_DEV_STATE_ERROR: + rc = scnprintf(buf, PAGE_SIZE, "ERROR"); + break; + default: + rc = scnprintf(buf, PAGE_SIZE, "UNKNOWN"); + } + /* state machine state */ + if (aq->dev_state) { + switch (aq->sm_state) { + case AP_SM_STATE_RESET_START: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [RESET_START]\n"); + break; + case AP_SM_STATE_RESET_WAIT: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [RESET_WAIT]\n"); + break; + case AP_SM_STATE_SETIRQ_WAIT: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [SETIRQ_WAIT]\n"); + break; + case AP_SM_STATE_IDLE: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [IDLE]\n"); + break; + case AP_SM_STATE_WORKING: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [WORKING]\n"); + break; + case AP_SM_STATE_QUEUE_FULL: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [FULL]\n"); + break; + default: + rc += scnprintf(buf + rc, PAGE_SIZE - rc, + " [UNKNOWN]\n"); + } + } + spin_unlock_bh(&aq->lock); + + return rc; +} +static DEVICE_ATTR_RO(states); + +static ssize_t last_err_rc_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ap_queue *aq = to_ap_queue(dev); + int rc; + + spin_lock_bh(&aq->lock); + rc = aq->last_err_rc; + spin_unlock_bh(&aq->lock); + + switch (rc) { + case AP_RESPONSE_NORMAL: + return scnprintf(buf, PAGE_SIZE, "NORMAL\n"); + case AP_RESPONSE_Q_NOT_AVAIL: + return scnprintf(buf, PAGE_SIZE, "Q_NOT_AVAIL\n"); + case AP_RESPONSE_RESET_IN_PROGRESS: + return scnprintf(buf, PAGE_SIZE, "RESET_IN_PROGRESS\n"); + case AP_RESPONSE_DECONFIGURED: + return scnprintf(buf, PAGE_SIZE, "DECONFIGURED\n"); + case AP_RESPONSE_CHECKSTOPPED: + return scnprintf(buf, PAGE_SIZE, "CHECKSTOPPED\n"); + case AP_RESPONSE_BUSY: + return scnprintf(buf, PAGE_SIZE, "BUSY\n"); + case AP_RESPONSE_INVALID_ADDRESS: + return scnprintf(buf, PAGE_SIZE, "INVALID_ADDRESS\n"); + case AP_RESPONSE_OTHERWISE_CHANGED: + return scnprintf(buf, PAGE_SIZE, "OTHERWISE_CHANGED\n"); + case AP_RESPONSE_Q_FULL: + return scnprintf(buf, PAGE_SIZE, "Q_FULL/NO_PENDING_REPLY\n"); + case AP_RESPONSE_INDEX_TOO_BIG: + return scnprintf(buf, PAGE_SIZE, "INDEX_TOO_BIG\n"); + case AP_RESPONSE_NO_FIRST_PART: + return scnprintf(buf, PAGE_SIZE, "NO_FIRST_PART\n"); + case AP_RESPONSE_MESSAGE_TOO_BIG: + return scnprintf(buf, PAGE_SIZE, "MESSAGE_TOO_BIG\n"); + case AP_RESPONSE_REQ_FAC_NOT_INST: + return scnprintf(buf, PAGE_SIZE, "REQ_FAC_NOT_INST\n"); + default: + return scnprintf(buf, PAGE_SIZE, "response code %d\n", rc); + } +} +static DEVICE_ATTR_RO(last_err_rc); +#endif + static struct attribute *ap_queue_dev_attrs[] = { &dev_attr_request_count.attr, &dev_attr_requestq_count.attr, &dev_attr_pendingq_count.attr, &dev_attr_reset.attr, &dev_attr_interrupt.attr, + &dev_attr_config.attr, +#ifdef CONFIG_ZCRYPT_DEBUG + &dev_attr_states.attr, + &dev_attr_last_err_rc.attr, +#endif NULL }; @@ -619,11 +729,10 @@ { struct ap_queue *aq = to_ap_queue(dev); - if (!list_empty(&aq->list)) { - spin_lock_bh(&ap_list_lock); - list_del_init(&aq->list); - spin_unlock_bh(&ap_list_lock); - } + spin_lock_bh(&ap_queues_lock); + hash_del(&aq->hnode); + spin_unlock_bh(&ap_queues_lock); + kfree(aq); } @@ -638,10 +747,8 @@ aq->ap_dev.device.type = &ap_queue_type; aq->ap_dev.device_type = device_type; aq->qid = qid; - aq->state = AP_STATE_RESET_START; aq->interrupt = AP_INTR_DISABLED; spin_lock_init(&aq->lock); - INIT_LIST_HEAD(&aq->list); INIT_LIST_HEAD(&aq->pendingq); INIT_LIST_HEAD(&aq->requestq); timer_setup(&aq->timeout, ap_request_timeout, 0); @@ -654,7 +761,7 @@ aq->reply = reply; spin_lock_bh(&aq->lock); - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); spin_unlock_bh(&aq->lock); } EXPORT_SYMBOL(ap_queue_init_reply); @@ -664,22 +771,30 @@ * @aq: The AP device to queue the message to * @ap_msg: The message that is to be added */ -void ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) +int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg) { - /* For asynchronous message handling a valid receive-callback - * is required. - */ + int rc = 0; + + /* msg needs to have a valid receive-callback */ BUG_ON(!ap_msg->receive); spin_lock_bh(&aq->lock); - /* Queue the message. */ - list_add_tail(&ap_msg->list, &aq->requestq); - aq->requestq_count++; - aq->total_request_count++; - atomic_inc(&aq->card->total_request_count); + + /* only allow to queue new messages if device state is ok */ + if (aq->dev_state == AP_DEV_STATE_OPERATING) { + list_add_tail(&ap_msg->list, &aq->requestq); + aq->requestq_count++; + aq->total_request_count++; + atomic64_inc(&aq->card->total_request_count); + } else + rc = -ENODEV; + /* Send/receive as many request from the queue as possible. */ - ap_wait(ap_sm_event_loop(aq, AP_EVENT_POLL)); + ap_wait(ap_sm_event_loop(aq, AP_SM_EVENT_POLL)); + spin_unlock_bh(&aq->lock); + + return rc; } EXPORT_SYMBOL(ap_queue_message); @@ -750,8 +865,8 @@ spin_lock_bh(&aq->lock); /* flush queue */ __ap_flush_queue(aq); - /* set REMOVE state to prevent new messages are queued in */ - aq->state = AP_STATE_REMOVE; + /* move queue device state to SHUTDOWN in progress */ + aq->dev_state = AP_DEV_STATE_SHUTDOWN; spin_unlock_bh(&aq->lock); del_timer_sync(&aq->timeout); } @@ -759,22 +874,23 @@ void ap_queue_remove(struct ap_queue *aq) { /* - * all messages have been flushed and the state is - * AP_STATE_REMOVE. Now reset with zero which also - * clears the irq registration and move the state - * to AP_STATE_UNBOUND to signal that this queue - * is not used by any driver currently. + * all messages have been flushed and the device state + * is SHUTDOWN. Now reset with zero which also clears + * the irq registration and move the device state + * to the initial value AP_DEV_STATE_UNINITIATED. */ spin_lock_bh(&aq->lock); ap_zapq(aq->qid); - aq->state = AP_STATE_UNBOUND; + aq->dev_state = AP_DEV_STATE_UNINITIATED; spin_unlock_bh(&aq->lock); } -void ap_queue_reinit_state(struct ap_queue *aq) +void ap_queue_init_state(struct ap_queue *aq) { spin_lock_bh(&aq->lock); - aq->state = AP_STATE_RESET_START; - ap_wait(ap_sm_event(aq, AP_EVENT_POLL)); + aq->dev_state = AP_DEV_STATE_OPERATING; + aq->sm_state = AP_SM_STATE_RESET_START; + ap_wait(ap_sm_event(aq, AP_SM_EVENT_POLL)); spin_unlock_bh(&aq->lock); } +EXPORT_SYMBOL(ap_queue_init_state); --- linux-oracle-5.4.0.orig/drivers/s390/crypto/pkey_api.c +++ linux-oracle-5.4.0/drivers/s390/crypto/pkey_api.c @@ -25,6 +25,7 @@ #include "zcrypt_api.h" #include "zcrypt_ccamisc.h" +#include "zcrypt_ep11misc.h" MODULE_LICENSE("GPL"); MODULE_AUTHOR("IBM Corporation"); @@ -33,9 +34,6 @@ #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ -/* mask of available pckmo subfunctions, fetched once at module init */ -static cpacf_mask_t pckmo_functions; - /* * debug feature data and functions */ @@ -71,6 +69,17 @@ u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ } __packed; +/* inside view of a clear key token (type 0x00 version 0x02) */ +struct clearaeskeytoken { + u8 type; /* 0x00 for PAES specific key tokens */ + u8 res0[3]; + u8 version; /* 0x02 for clear AES key token */ + u8 res1[3]; + u32 keytype; /* key type, one of the PKEY_KEYTYPE values */ + u32 len; /* bytes actually stored in clearkey[] */ + u8 clearkey[]; /* clear key value */ +} __packed; + /* * Create a protected key from a clear key value. */ @@ -78,6 +87,9 @@ const struct pkey_clrkey *clrkey, struct pkey_protkey *protkey) { + /* mask of available pckmo subfunctions */ + static cpacf_mask_t pckmo_functions; + long fc; int keysize; u8 paramblock[64]; @@ -101,11 +113,13 @@ return -EINVAL; } - /* - * Check if the needed pckmo subfunction is available. - * These subfunctions can be enabled/disabled by customers - * in the LPAR profile or may even change on the fly. - */ + /* Did we already check for PCKMO ? */ + if (!pckmo_functions.bytes[0]) { + /* no, so check now */ + if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) + return -ENODEV; + } + /* check for the pckmo subfunction we need now */ if (!cpacf_test_func(&pckmo_functions, fc)) { DEBUG_ERR("%s pckmo functions not available\n", __func__); return -ENODEV; @@ -173,6 +187,72 @@ } /* + * Construct EP11 key with given clear key value. + */ +static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen, + u8 *keybuf, size_t *keybuflen) +{ + int i, rc; + u16 card, dom; + u32 nr_apqns, *apqns = NULL; + + /* build a list of apqns suitable for ep11 keys with cpacf support */ + rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, + ZCRYPT_CEX7, EP11_API_V, NULL); + if (rc) + goto out; + + /* go through the list of apqns and try to bild an ep11 key */ + for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { + card = apqns[i] >> 16; + dom = apqns[i] & 0xFFFF; + rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, + 0, clrkey, keybuf, keybuflen); + if (rc == 0) + break; + } + +out: + kfree(apqns); + if (rc) + DEBUG_DBG("%s failed rc=%d\n", __func__, rc); + return rc; +} + +/* + * Find card and transform EP11 secure key into protected key. + */ +static int pkey_ep11key2pkey(const u8 *key, struct pkey_protkey *pkey) +{ + int i, rc; + u16 card, dom; + u32 nr_apqns, *apqns = NULL; + struct ep11keyblob *kb = (struct ep11keyblob *) key; + + /* build a list of apqns suitable for this key */ + rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, + ZCRYPT_CEX7, EP11_API_V, kb->wkvp); + if (rc) + goto out; + + /* go through the list of apqns and try to derive an pkey */ + for (rc = -ENODEV, i = 0; i < nr_apqns; i++) { + card = apqns[i] >> 16; + dom = apqns[i] & 0xFFFF; + rc = ep11_key2protkey(card, dom, key, kb->head.len, + pkey->protkey, &pkey->len, &pkey->type); + if (rc == 0) + break; + } + +out: + kfree(apqns); + if (rc) + DEBUG_DBG("%s failed rc=%d\n", __func__, rc); + return rc; +} + +/* * Verify key and give back some info about the key. */ static int pkey_verifykey(const struct pkey_seckey *seckey, @@ -305,26 +385,90 @@ static int pkey_nonccatok2pkey(const u8 *key, u32 keylen, struct pkey_protkey *protkey) { + int rc = -EINVAL; + u8 *tmpbuf = NULL; struct keytoken_header *hdr = (struct keytoken_header *)key; - struct protaeskeytoken *t; switch (hdr->version) { - case TOKVER_PROTECTED_KEY: - if (keylen != sizeof(struct protaeskeytoken)) - return -EINVAL; + case TOKVER_PROTECTED_KEY: { + struct protaeskeytoken *t; + if (keylen != sizeof(struct protaeskeytoken)) + goto out; t = (struct protaeskeytoken *)key; protkey->len = t->len; protkey->type = t->keytype; memcpy(protkey->protkey, t->protkey, sizeof(protkey->protkey)); + rc = pkey_verifyprotkey(protkey); + break; + } + case TOKVER_CLEAR_KEY: { + struct clearaeskeytoken *t; + struct pkey_clrkey ckey; + union u_tmpbuf { + u8 skey[SECKEYBLOBSIZE]; + u8 ep11key[MAXEP11AESKEYBLOBSIZE]; + }; + size_t tmpbuflen = sizeof(union u_tmpbuf); - return pkey_verifyprotkey(protkey); + if (keylen < sizeof(struct clearaeskeytoken)) + goto out; + t = (struct clearaeskeytoken *)key; + if (keylen != sizeof(*t) + t->len) + goto out; + if ((t->keytype == PKEY_KEYTYPE_AES_128 && t->len == 16) + || (t->keytype == PKEY_KEYTYPE_AES_192 && t->len == 24) + || (t->keytype == PKEY_KEYTYPE_AES_256 && t->len == 32)) + memcpy(ckey.clrkey, t->clearkey, t->len); + else + goto out; + /* alloc temp key buffer space */ + tmpbuf = kmalloc(tmpbuflen, GFP_ATOMIC); + if (!tmpbuf) { + rc = -ENOMEM; + goto out; + } + /* try direct way with the PCKMO instruction */ + rc = pkey_clr2protkey(t->keytype, &ckey, protkey); + if (rc == 0) + break; + /* PCKMO failed, so try the CCA secure key way */ + rc = cca_clr2seckey(0xFFFF, 0xFFFF, t->keytype, + ckey.clrkey, tmpbuf); + if (rc == 0) + rc = pkey_skey2pkey(tmpbuf, protkey); + if (rc == 0) + break; + /* if the CCA way also failed, let's try via EP11 */ + rc = pkey_clr2ep11key(ckey.clrkey, t->len, + tmpbuf, &tmpbuflen); + if (rc == 0) + rc = pkey_ep11key2pkey(tmpbuf, protkey); + /* now we should really have an protected key */ + DEBUG_ERR("%s unable to build protected key from clear", + __func__); + break; + } + case TOKVER_EP11_AES: { + if (keylen < MINEP11AESKEYBLOBSIZE) + goto out; + /* check ep11 key for exportable as protected key */ + rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1); + if (rc) + goto out; + rc = pkey_ep11key2pkey(key, protkey); + break; + } default: DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n", __func__, hdr->version); - return -EINVAL; + rc = -EINVAL; } + +out: + kfree(tmpbuf); + return rc; } /* @@ -403,6 +547,10 @@ if (*keybufsize < SECKEYBLOBSIZE) return -EINVAL; break; + case PKEY_TYPE_EP11: + if (*keybufsize < MINEP11AESKEYBLOBSIZE) + return -EINVAL; + break; default: return -EINVAL; } @@ -419,7 +567,10 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i].card; dom = apqns[i].domain; - if (ktype == PKEY_TYPE_CCA_DATA) { + if (ktype == PKEY_TYPE_EP11) { + rc = ep11_genaeskey(card, dom, ksize, kflags, + keybuf, keybufsize); + } else if (ktype == PKEY_TYPE_CCA_DATA) { rc = cca_genseckey(card, dom, ksize, keybuf); *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); } else /* TOKVER_CCA_VLSC */ @@ -450,6 +601,10 @@ if (*keybufsize < SECKEYBLOBSIZE) return -EINVAL; break; + case PKEY_TYPE_EP11: + if (*keybufsize < MINEP11AESKEYBLOBSIZE) + return -EINVAL; + break; default: return -EINVAL; } @@ -466,7 +621,10 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i].card; dom = apqns[i].domain; - if (ktype == PKEY_TYPE_CCA_DATA) { + if (ktype == PKEY_TYPE_EP11) { + rc = ep11_clr2keyblob(card, dom, ksize, kflags, + clrkey, keybuf, keybufsize); + } else if (ktype == PKEY_TYPE_CCA_DATA) { rc = cca_clr2seckey(card, dom, ksize, clrkey, keybuf); *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); @@ -489,11 +647,11 @@ u32 _nr_apqns, *_apqns = NULL; struct keytoken_header *hdr = (struct keytoken_header *)key; - if (keylen < sizeof(struct keytoken_header) || - hdr->type != TOKTYPE_CCA_INTERNAL) + if (keylen < sizeof(struct keytoken_header)) return -EINVAL; - if (hdr->version == TOKVER_CCA_AES) { + if (hdr->type == TOKTYPE_CCA_INTERNAL + && hdr->version == TOKVER_CCA_AES) { struct secaeskeytoken *t = (struct secaeskeytoken *)key; rc = cca_check_secaeskeytoken(debug_info, 3, key, 0); @@ -505,13 +663,14 @@ *ksize = (enum pkey_key_size) t->bitsize; rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, - ZCRYPT_CEX3C, t->mkvp, 0, 1); + ZCRYPT_CEX3C, AES_MK_SET, t->mkvp, 0, 1); if (rc == 0 && flags) *flags = PKEY_FLAGS_MATCH_CUR_MKVP; if (rc == -ENODEV) { rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, - ZCRYPT_CEX3C, 0, t->mkvp, 1); + ZCRYPT_CEX3C, AES_MK_SET, + 0, t->mkvp, 1); if (rc == 0 && flags) *flags = PKEY_FLAGS_MATCH_ALT_MKVP; } @@ -521,7 +680,8 @@ *cardnr = ((struct pkey_apqn *)_apqns)->card; *domain = ((struct pkey_apqn *)_apqns)->domain; - } else if (hdr->version == TOKVER_CCA_VLSC) { + } else if (hdr->type == TOKTYPE_CCA_INTERNAL + && hdr->version == TOKVER_CCA_VLSC) { struct cipherkeytoken *t = (struct cipherkeytoken *)key; rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1); @@ -540,13 +700,14 @@ } rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, - ZCRYPT_CEX6, t->mkvp0, 0, 1); + ZCRYPT_CEX6, AES_MK_SET, t->mkvp0, 0, 1); if (rc == 0 && flags) *flags = PKEY_FLAGS_MATCH_CUR_MKVP; if (rc == -ENODEV) { rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, - ZCRYPT_CEX6, 0, t->mkvp0, 1); + ZCRYPT_CEX6, AES_MK_SET, + 0, t->mkvp0, 1); if (rc == 0 && flags) *flags = PKEY_FLAGS_MATCH_ALT_MKVP; } @@ -556,6 +717,29 @@ *cardnr = ((struct pkey_apqn *)_apqns)->card; *domain = ((struct pkey_apqn *)_apqns)->domain; + } else if (hdr->type == TOKTYPE_NON_CCA + && hdr->version == TOKVER_EP11_AES) { + struct ep11keyblob *kb = (struct ep11keyblob *)key; + + rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1); + if (rc) + goto out; + if (ktype) + *ktype = PKEY_TYPE_EP11; + if (ksize) + *ksize = kb->head.keybitlen; + + rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, + ZCRYPT_CEX7, EP11_API_V, kb->wkvp); + if (rc) + goto out; + + if (flags) + *flags = PKEY_FLAGS_MATCH_CUR_MKVP; + + *cardnr = ((struct pkey_apqn *)_apqns)->card; + *domain = ((struct pkey_apqn *)_apqns)->domain; + } else rc = -EINVAL; @@ -578,30 +762,32 @@ if (keylen < sizeof(struct keytoken_header)) return -EINVAL; - switch (hdr->type) { - case TOKTYPE_NON_CCA: - return pkey_nonccatok2pkey(key, keylen, pkey); - case TOKTYPE_CCA_INTERNAL: - switch (hdr->version) { - case TOKVER_CCA_AES: + if (hdr->type == TOKTYPE_CCA_INTERNAL) { + if (hdr->version == TOKVER_CCA_AES) { if (keylen != sizeof(struct secaeskeytoken)) return -EINVAL; if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) return -EINVAL; - break; - case TOKVER_CCA_VLSC: + } else if (hdr->version == TOKVER_CCA_VLSC) { if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) return -EINVAL; if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) return -EINVAL; - break; - default: + } else { DEBUG_ERR("%s unknown CCA internal token version %d\n", __func__, hdr->version); return -EINVAL; } - break; - default: + } else if (hdr->type == TOKTYPE_NON_CCA) { + if (hdr->version == TOKVER_EP11_AES) { + if (keylen < sizeof(struct ep11keyblob)) + return -EINVAL; + if (ep11_check_aeskeyblob(debug_info, 3, key, 0, 1)) + return -EINVAL; + } else { + return pkey_nonccatok2pkey(key, keylen, pkey); + } + } else { DEBUG_ERR("%s unknown/unsupported blob type %d\n", __func__, hdr->type); return -EINVAL; @@ -611,12 +797,21 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i].card; dom = apqns[i].domain; - if (hdr->version == TOKVER_CCA_AES) + if (hdr->type == TOKTYPE_CCA_INTERNAL + && hdr->version == TOKVER_CCA_AES) rc = cca_sec2protkey(card, dom, key, pkey->protkey, &pkey->len, &pkey->type); - else /* TOKVER_CCA_VLSC */ + else if (hdr->type == TOKTYPE_CCA_INTERNAL + && hdr->version == TOKVER_CCA_VLSC) rc = cca_cipher2protkey(card, dom, key, pkey->protkey, &pkey->len, &pkey->type); + else { /* EP11 AES secure key blob */ + struct ep11keyblob *kb = (struct ep11keyblob *) key; + + rc = ep11_key2protkey(card, dom, key, kb->head.len, + pkey->protkey, &pkey->len, + &pkey->type); + } if (rc == 0) break; } @@ -631,12 +826,24 @@ u32 _nr_apqns, *_apqns = NULL; struct keytoken_header *hdr = (struct keytoken_header *)key; - if (keylen < sizeof(struct keytoken_header) || - hdr->type != TOKTYPE_CCA_INTERNAL || - flags == 0) + if (keylen < sizeof(struct keytoken_header) || flags == 0) return -EINVAL; - if (hdr->version == TOKVER_CCA_AES || hdr->version == TOKVER_CCA_VLSC) { + if (hdr->type == TOKTYPE_NON_CCA && hdr->version == TOKVER_EP11_AES) { + int minhwtype = 0, api = 0; + struct ep11keyblob *kb = (struct ep11keyblob *) key; + + if (flags != PKEY_FLAGS_MATCH_CUR_MKVP) + return -EINVAL; + if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) { + minhwtype = ZCRYPT_CEX7; + api = EP11_API_V; + } + rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + minhwtype, api, kb->wkvp); + if (rc) + goto out; + } else if (hdr->type == TOKTYPE_CCA_INTERNAL) { int minhwtype = ZCRYPT_CEX3C; u64 cur_mkvp = 0, old_mkvp = 0; @@ -647,7 +854,7 @@ cur_mkvp = t->mkvp; if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) old_mkvp = t->mkvp; - } else { + } else if (hdr->version == TOKVER_CCA_VLSC) { struct cipherkeytoken *t = (struct cipherkeytoken *)key; minhwtype = ZCRYPT_CEX6; @@ -655,19 +862,25 @@ cur_mkvp = t->mkvp0; if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) old_mkvp = t->mkvp0; + } else { + /* unknown cca internal token type */ + return -EINVAL; } rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, - minhwtype, cur_mkvp, old_mkvp, 1); + minhwtype, AES_MK_SET, + cur_mkvp, old_mkvp, 1); if (rc) goto out; - if (apqns) { - if (*nr_apqns < _nr_apqns) - rc = -ENOSPC; - else - memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); - } - *nr_apqns = _nr_apqns; + } else + return -EINVAL; + + if (apqns) { + if (*nr_apqns < _nr_apqns) + rc = -ENOSPC; + else + memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); } + *nr_apqns = _nr_apqns; out: kfree(_apqns); @@ -692,17 +905,30 @@ if (ktype == PKEY_TYPE_CCA_CIPHER) minhwtype = ZCRYPT_CEX6; rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, - minhwtype, cur_mkvp, old_mkvp, 1); + minhwtype, AES_MK_SET, + cur_mkvp, old_mkvp, 1); if (rc) goto out; - if (apqns) { - if (*nr_apqns < _nr_apqns) - rc = -ENOSPC; - else - memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); - } - *nr_apqns = _nr_apqns; + } else if (ktype == PKEY_TYPE_EP11) { + u8 *wkvp = NULL; + + if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) + wkvp = cur_mkvp; + rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, + ZCRYPT_CEX7, EP11_API_V, wkvp); + if (rc) + goto out; + + } else + return -EINVAL; + + if (apqns) { + if (*nr_apqns < _nr_apqns) + rc = -ENOSPC; + else + memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); } + *nr_apqns = _nr_apqns; out: kfree(_apqns); @@ -715,36 +941,18 @@ static void *_copy_key_from_user(void __user *ukey, size_t keylen) { - void *kkey; - if (!ukey || keylen < MINKEYBLOBSIZE || keylen > KEYBLOBBUFSIZE) return ERR_PTR(-EINVAL); - kkey = kmalloc(keylen, GFP_KERNEL); - if (!kkey) - return ERR_PTR(-ENOMEM); - if (copy_from_user(kkey, ukey, keylen)) { - kfree(kkey); - return ERR_PTR(-EFAULT); - } - return kkey; + return memdup_user(ukey, keylen); } static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) { - void *kapqns = NULL; - size_t nbytes; + if (!uapqns || nr_apqns == 0) + return NULL; - if (uapqns && nr_apqns > 0) { - nbytes = nr_apqns * sizeof(struct pkey_apqn); - kapqns = kmalloc(nbytes, GFP_KERNEL); - if (!kapqns) - return ERR_PTR(-ENOMEM); - if (copy_from_user(kapqns, uapqns, nbytes)) - return ERR_PTR(-EFAULT); - } - - return kapqns; + return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); } static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, @@ -777,10 +985,8 @@ rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, kcs.clrkey.clrkey, kcs.seckey.seckey); DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ucs, &kcs, sizeof(kcs))) - return -EFAULT; + if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs))) + rc = -EFAULT; memzero_explicit(&kcs, sizeof(kcs)); break; } @@ -792,7 +998,7 @@ return -EFAULT; rc = cca_sec2protkey(ksp.cardnr, ksp.domain, ksp.seckey.seckey, ksp.protkey.protkey, - NULL, &ksp.protkey.type); + &ksp.protkey.len, &ksp.protkey.type); DEBUG_DBG("%s cca_sec2protkey()=%d\n", __func__, rc); if (rc) break; @@ -809,10 +1015,8 @@ rc = pkey_clr2protkey(kcp.keytype, &kcp.clrkey, &kcp.protkey); DEBUG_DBG("%s pkey_clr2protkey()=%d\n", __func__, rc); - if (rc) - break; - if (copy_to_user(ucp, &kcp, sizeof(kcp))) - return -EFAULT; + if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp))) + rc = -EFAULT; memzero_explicit(&kcp, sizeof(kcp)); break; } @@ -955,11 +1159,14 @@ if (copy_from_user(&kcs, ucs, sizeof(kcs))) return -EFAULT; apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); - if (IS_ERR(apqns)) + if (IS_ERR(apqns)) { + memzero_explicit(&kcs, sizeof(kcs)); return PTR_ERR(apqns); + } kkey = kmalloc(klen, GFP_KERNEL); if (!kkey) { kfree(apqns); + memzero_explicit(&kcs, sizeof(kcs)); return -ENOMEM; } rc = pkey_clr2seckey2(apqns, kcs.apqn_entries, @@ -969,15 +1176,18 @@ kfree(apqns); if (rc) { kfree(kkey); + memzero_explicit(&kcs, sizeof(kcs)); break; } if (kcs.key) { if (kcs.keylen < klen) { kfree(kkey); + memzero_explicit(&kcs, sizeof(kcs)); return -EINVAL; } if (copy_to_user(kcs.key, kkey, klen)) { kfree(kkey); + memzero_explicit(&kcs, sizeof(kcs)); return -EFAULT; } } @@ -1375,8 +1585,9 @@ bool is_xts, char *buf, loff_t off, size_t count) { - size_t keysize; - int rc; + int i, rc, card, dom; + u32 nr_apqns, *apqns = NULL; + size_t keysize = CCACIPHERTOKENSIZE; if (off != 0 || count < CCACIPHERTOKENSIZE) return -EINVAL; @@ -1384,22 +1595,31 @@ if (count < 2 * CCACIPHERTOKENSIZE) return -EINVAL; - keysize = CCACIPHERTOKENSIZE; - rc = cca_gencipherkey(-1, -1, keybits, 0, buf, &keysize); + /* build a list of apqns able to generate an cipher key */ + rc = cca_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, + ZCRYPT_CEX6, 0, 0, 0, 0); if (rc) return rc; - memset(buf + keysize, 0, CCACIPHERTOKENSIZE - keysize); - if (is_xts) { - keysize = CCACIPHERTOKENSIZE; - rc = cca_gencipherkey(-1, -1, keybits, 0, - buf + CCACIPHERTOKENSIZE, &keysize); + memset(buf, 0, is_xts ? 2 * keysize : keysize); + + /* simple try all apqns from the list */ + for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { + card = apqns[i] >> 16; + dom = apqns[i] & 0xFFFF; + rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); + if (rc == 0) + break; + } if (rc) return rc; - memset(buf + CCACIPHERTOKENSIZE + keysize, 0, - CCACIPHERTOKENSIZE - keysize); - return 2 * CCACIPHERTOKENSIZE; + if (is_xts) { + keysize = CCACIPHERTOKENSIZE; + buf += CCACIPHERTOKENSIZE; + rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize); + if (rc == 0) + return 2 * CCACIPHERTOKENSIZE; } return CCACIPHERTOKENSIZE; @@ -1475,10 +1695,134 @@ .bin_attrs = ccacipher_attrs, }; +/* + * Sysfs attribute read function for all ep11 aes key binary attributes. + * The implementation can not deal with partial reads, because a new random + * secure key blob is generated with each read. In case of partial reads + * (i.e. off != 0 or count < key blob size) -EINVAL is returned. + * This function and the sysfs attributes using it provide EP11 key blobs + * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently + * 320 bytes. + */ +static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, + bool is_xts, char *buf, loff_t off, + size_t count) +{ + int i, rc, card, dom; + u32 nr_apqns, *apqns = NULL; + size_t keysize = MAXEP11AESKEYBLOBSIZE; + + if (off != 0 || count < MAXEP11AESKEYBLOBSIZE) + return -EINVAL; + if (is_xts) + if (count < 2 * MAXEP11AESKEYBLOBSIZE) + return -EINVAL; + + /* build a list of apqns able to generate an cipher key */ + rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF, + ZCRYPT_CEX7, EP11_API_V, NULL); + if (rc) + return rc; + + memset(buf, 0, is_xts ? 2 * keysize : keysize); + + /* simple try all apqns from the list */ + for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { + card = apqns[i] >> 16; + dom = apqns[i] & 0xFFFF; + rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); + if (rc == 0) + break; + } + if (rc) + return rc; + + if (is_xts) { + keysize = MAXEP11AESKEYBLOBSIZE; + buf += MAXEP11AESKEYBLOBSIZE; + rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); + if (rc == 0) + return 2 * MAXEP11AESKEYBLOBSIZE; + } + + return MAXEP11AESKEYBLOBSIZE; +} + +static ssize_t ep11_aes_128_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf, + off, count); +} + +static ssize_t ep11_aes_192_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf, + off, count); +} + +static ssize_t ep11_aes_256_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf, + off, count); +} + +static ssize_t ep11_aes_128_xts_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf, + off, count); +} + +static ssize_t ep11_aes_256_xts_read(struct file *filp, + struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, + size_t count) +{ + return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf, + off, count); +} + +static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE); +static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE); +static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE); +static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE); +static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE); + +static struct bin_attribute *ep11_attrs[] = { + &bin_attr_ep11_aes_128, + &bin_attr_ep11_aes_192, + &bin_attr_ep11_aes_256, + &bin_attr_ep11_aes_128_xts, + &bin_attr_ep11_aes_256_xts, + NULL +}; + +static struct attribute_group ep11_attr_group = { + .name = "ep11", + .bin_attrs = ep11_attrs, +}; + static const struct attribute_group *pkey_attr_groups[] = { &protkey_attr_group, &ccadata_attr_group, &ccacipher_attr_group, + &ep11_attr_group, NULL, }; @@ -1502,7 +1846,7 @@ */ static int __init pkey_init(void) { - cpacf_mask_t kmc_functions; + cpacf_mask_t func_mask; /* * The pckmo instruction should be available - even if we don't @@ -1510,15 +1854,15 @@ * is also the minimum level for the kmc instructions which * are able to work with protected keys. */ - if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) + if (!cpacf_query(CPACF_PCKMO, &func_mask)) return -ENODEV; /* check for kmc instructions available */ - if (!cpacf_query(CPACF_KMC, &kmc_functions)) + if (!cpacf_query(CPACF_KMC, &func_mask)) return -ENODEV; - if (!cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_128) || - !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_192) || - !cpacf_test_func(&kmc_functions, CPACF_KMC_PAES_256)) + if (!cpacf_test_func(&func_mask, CPACF_KMC_PAES_128) || + !cpacf_test_func(&func_mask, CPACF_KMC_PAES_192) || + !cpacf_test_func(&func_mask, CPACF_KMC_PAES_256)) return -ENODEV; pkey_debug_init(); --- linux-oracle-5.4.0.orig/drivers/s390/crypto/vfio_ap_drv.c +++ linux-oracle-5.4.0/drivers/s390/crypto/vfio_ap_drv.c @@ -71,23 +71,20 @@ static void vfio_ap_queue_dev_remove(struct ap_device *apdev) { struct vfio_ap_queue *q; - int apid, apqi; mutex_lock(&matrix_dev->lock); q = dev_get_drvdata(&apdev->device); + vfio_ap_mdev_reset_queue(q, 1); dev_set_drvdata(&apdev->device, NULL); - apid = AP_QID_CARD(q->apqn); - apqi = AP_QID_QUEUE(q->apqn); - vfio_ap_mdev_reset_queue(apid, apqi, 1); - vfio_ap_irq_disable(q); kfree(q); mutex_unlock(&matrix_dev->lock); } static void vfio_ap_matrix_dev_release(struct device *dev) { - struct ap_matrix_dev *matrix_dev = dev_get_drvdata(dev); + struct ap_matrix_dev *matrix_dev; + matrix_dev = container_of(dev, struct ap_matrix_dev, device); kfree(matrix_dev); } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/vfio_ap_ops.c +++ linux-oracle-5.4.0/drivers/s390/crypto/vfio_ap_ops.c @@ -25,6 +25,7 @@ #define VFIO_AP_MDEV_NAME_HWVIRT "VFIO AP Passthrough Device" static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev); +static struct vfio_ap_queue *vfio_ap_find_queue(int apqn); static int match_apqn(struct device *dev, const void *data) { @@ -49,20 +50,15 @@ int apqn) { struct vfio_ap_queue *q; - struct device *dev; if (!test_bit_inv(AP_QID_CARD(apqn), matrix_mdev->matrix.apm)) return NULL; if (!test_bit_inv(AP_QID_QUEUE(apqn), matrix_mdev->matrix.aqm)) return NULL; - dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, - &apqn, match_apqn); - if (!dev) - return NULL; - q = dev_get_drvdata(dev); - q->matrix_mdev = matrix_mdev; - put_device(dev); + q = vfio_ap_find_queue(apqn); + if (q) + q->matrix_mdev = matrix_mdev; return q; } @@ -119,13 +115,18 @@ */ static void vfio_ap_free_aqic_resources(struct vfio_ap_queue *q) { - if (q->saved_isc != VFIO_AP_ISC_INVALID && q->matrix_mdev) + if (!q) + return; + if (q->saved_isc != VFIO_AP_ISC_INVALID && + !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) { kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc); - if (q->saved_pfn && q->matrix_mdev) + q->saved_isc = VFIO_AP_ISC_INVALID; + } + if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) { vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), &q->saved_pfn, 1); - q->saved_pfn = 0; - q->saved_isc = VFIO_AP_ISC_INVALID; + q->saved_pfn = 0; + } } /** @@ -144,7 +145,7 @@ * Returns if ap_aqic function failed with invalid, deconfigured or * checkstopped AP. */ -struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) +static struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q) { struct ap_qirq_ctrl aqic_gisa = {}; struct ap_queue_status status; @@ -1114,48 +1115,70 @@ return NOTIFY_OK; } -static void vfio_ap_irq_disable_apqn(int apqn) +static struct vfio_ap_queue *vfio_ap_find_queue(int apqn) { struct device *dev; - struct vfio_ap_queue *q; + struct vfio_ap_queue *q = NULL; dev = driver_find_device(&matrix_dev->vfio_ap_drv->driver, NULL, &apqn, match_apqn); if (dev) { q = dev_get_drvdata(dev); - vfio_ap_irq_disable(q); put_device(dev); } + + return q; } -int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, +int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, unsigned int retry) { struct ap_queue_status status; + int ret; int retry2 = 2; - int apqn = AP_MKQID(apid, apqi); - do { - status = ap_zapq(apqn); - switch (status.response_code) { - case AP_RESPONSE_NORMAL: - while (!status.queue_empty && retry2--) { - msleep(20); - status = ap_tapq(apqn, NULL); - } - WARN_ON_ONCE(retry2 <= 0); - return 0; - case AP_RESPONSE_RESET_IN_PROGRESS: - case AP_RESPONSE_BUSY: + if (!q) + return 0; + +retry_zapq: + status = ap_zapq(q->apqn); + switch (status.response_code) { + case AP_RESPONSE_NORMAL: + ret = 0; + break; + case AP_RESPONSE_RESET_IN_PROGRESS: + if (retry--) { msleep(20); - break; - default: - /* things are really broken, give up */ - return -EIO; + goto retry_zapq; } - } while (retry--); + ret = -EBUSY; + break; + case AP_RESPONSE_Q_NOT_AVAIL: + case AP_RESPONSE_DECONFIGURED: + case AP_RESPONSE_CHECKSTOPPED: + WARN_ON_ONCE(status.irq_enabled); + ret = -EBUSY; + goto free_resources; + default: + /* things are really broken, give up */ + WARN(true, "PQAP/ZAPQ completed with invalid rc (%x)\n", + status.response_code); + return -EIO; + } + + /* wait for the reset to take effect */ + while (retry2--) { + if (status.queue_empty && !status.irq_enabled) + break; + msleep(20); + status = ap_tapq(q->apqn, NULL); + } + WARN_ON_ONCE(retry2 <= 0); - return -EBUSY; +free_resources: + vfio_ap_free_aqic_resources(q); + + return ret; } static int vfio_ap_mdev_reset_queues(struct mdev_device *mdev) @@ -1163,13 +1186,15 @@ int ret; int rc = 0; unsigned long apid, apqi; + struct vfio_ap_queue *q; struct ap_matrix_mdev *matrix_mdev = mdev_get_drvdata(mdev); for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, matrix_mdev->matrix.apm_max + 1) { for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, matrix_mdev->matrix.aqm_max + 1) { - ret = vfio_ap_mdev_reset_queue(apid, apqi, 1); + q = vfio_ap_find_queue(AP_MKQID(apid, apqi)); + ret = vfio_ap_mdev_reset_queue(q, 1); /* * Regardless whether a queue turns out to be busy, or * is not operational, we need to continue resetting @@ -1177,7 +1202,6 @@ */ if (ret) rc = ret; - vfio_ap_irq_disable_apqn(AP_MKQID(apid, apqi)); } } @@ -1255,7 +1279,7 @@ info.num_regions = 0; info.num_irqs = 0; - return copy_to_user((void __user *)arg, &info, minsz); + return copy_to_user((void __user *)arg, &info, minsz) ? -EFAULT : 0; } static ssize_t vfio_ap_mdev_ioctl(struct mdev_device *mdev, --- linux-oracle-5.4.0.orig/drivers/s390/crypto/vfio_ap_private.h +++ linux-oracle-5.4.0/drivers/s390/crypto/vfio_ap_private.h @@ -88,11 +88,6 @@ struct mdev_device *mdev; }; -extern int vfio_ap_mdev_register(void); -extern void vfio_ap_mdev_unregister(void); -int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, - unsigned int retry); - struct vfio_ap_queue { struct ap_matrix_mdev *matrix_mdev; unsigned long saved_pfn; @@ -100,5 +95,10 @@ #define VFIO_AP_ISC_INVALID 0xff unsigned char saved_isc; }; -struct ap_queue_status vfio_ap_irq_disable(struct vfio_ap_queue *q); + +int vfio_ap_mdev_register(void); +void vfio_ap_mdev_unregister(void); +int vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q, + unsigned int retry); + #endif /* _VFIO_AP_PRIVATE_H_ */ --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_api.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_api.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define CREATE_TRACE_POINTS @@ -36,6 +37,7 @@ #include "zcrypt_msgtype6.h" #include "zcrypt_msgtype50.h" #include "zcrypt_ccamisc.h" +#include "zcrypt_ep11misc.h" /* * Module description. @@ -397,6 +399,7 @@ ZCRYPT_NAME "_%d", (int) MINOR(devt)); nodename[sizeof(nodename)-1] = '\0'; if (dev_set_name(&zcdndev->device, nodename)) { + kfree(zcdndev); rc = -EINVAL; goto unlockout; } @@ -573,6 +576,7 @@ { if (!zq || !try_module_get(zq->queue->ap_dev.drv->driver.owner)) return NULL; + zcrypt_card_get(zc); zcrypt_queue_get(zq); get_device(&zq->queue->ap_dev.device); atomic_add(weight, &zc->load); @@ -592,6 +596,7 @@ atomic_sub(weight, &zq->load); put_device(&zq->queue->ap_dev.device); zcrypt_queue_put(zq); + zcrypt_card_put(zc); module_put(mod); } @@ -601,13 +606,13 @@ unsigned int pref_weight) { if (!pref_zc) - return false; + return true; weight += atomic_read(&zc->load); pref_weight += atomic_read(&pref_zc->load); if (weight == pref_weight) - return atomic_read(&zc->card->total_request_count) > - atomic_read(&pref_zc->card->total_request_count); - return weight > pref_weight; + return atomic64_read(&zc->card->total_request_count) < + atomic64_read(&pref_zc->card->total_request_count); + return weight < pref_weight; } static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq, @@ -616,30 +621,39 @@ unsigned int pref_weight) { if (!pref_zq) - return false; + return true; weight += atomic_read(&zq->load); pref_weight += atomic_read(&pref_zq->load); if (weight == pref_weight) - return zq->queue->total_request_count > + return zq->queue->total_request_count < pref_zq->queue->total_request_count; - return weight > pref_weight; + return weight < pref_weight; } /* * zcrypt ioctls. */ static long zcrypt_rsa_modexpo(struct ap_perms *perms, + struct zcrypt_track *tr, struct ica_rsa_modexpo *mex) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; - unsigned int weight, pref_weight; + struct ap_message ap_msg; + unsigned int wgt = 0, pref_wgt = 0; unsigned int func_code; - int qid = 0, rc = -ENODEV; + int cpen, qpen, qid = 0, rc = -ENODEV; struct module *mod; trace_s390_zcrypt_req(mex, TP_ICARSAMODEXPO); + ap_init_message(&ap_msg); + +#ifdef CONFIG_ZCRYPT_DEBUG + if (tr && tr->fi.cmd) + ap_msg.fi.cmd = tr->fi.cmd; +#endif + if (mex->outputdatalength < mex->inputdatalength) { func_code = 0; rc = -EINVAL; @@ -661,8 +675,9 @@ pref_zq = NULL; spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { - /* Check for online accelarator and CCA cards */ - if (!zc->online || !(zc->card->functions & 0x18000000)) + /* Check for useable accelarator or CCA card */ + if (!zc->online || !zc->card->config || + !(zc->card->functions & 0x18000000)) continue; /* Check for size limits */ if (zc->min_mod_size > mex->inputdatalength || @@ -672,26 +687,35 @@ if (!zcrypt_check_card(perms, zc->card->id)) continue; /* get weight index of the card device */ - weight = zc->speed_rating[func_code]; - if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) + wgt = zc->speed_rating[func_code]; + /* penalty if this msg was previously sent via this card */ + cpen = (tr && tr->again_counter && tr->last_qid && + AP_QID_CARD(tr->last_qid) == zc->card->id) ? + TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0; + if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt)) continue; for_each_zcrypt_queue(zq, zc) { - /* check if device is online and eligible */ - if (!zq->online || !zq->ops->rsa_modexpo) + /* check if device is useable and eligible */ + if (!zq->online || !zq->ops->rsa_modexpo || + !zq->queue->config) continue; /* check if device node has admission for this queue */ if (!zcrypt_check_queue(perms, AP_QID_QUEUE(zq->queue->qid))) continue; - if (zcrypt_queue_compare(zq, pref_zq, - weight, pref_weight)) + /* penalty if the msg was previously sent at this qid */ + qpen = (tr && tr->again_counter && tr->last_qid && + tr->last_qid == zq->queue->qid) ? + TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0; + if (!zcrypt_queue_compare(zq, pref_zq, + wgt + cpen + qpen, pref_wgt)) continue; pref_zc = zc; pref_zq = zq; - pref_weight = weight; + pref_wgt = wgt + cpen + qpen; } } - pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight); + pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt); spin_unlock(&zcrypt_list_lock); if (!pref_zq) { @@ -700,30 +724,44 @@ } qid = pref_zq->queue->qid; - rc = pref_zq->ops->rsa_modexpo(pref_zq, mex); + rc = pref_zq->ops->rsa_modexpo(pref_zq, mex, &ap_msg); spin_lock(&zcrypt_list_lock); - zcrypt_drop_queue(pref_zc, pref_zq, mod, weight); + zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt); spin_unlock(&zcrypt_list_lock); out: + ap_release_message(&ap_msg); + if (tr) { + tr->last_rc = rc; + tr->last_qid = qid; + } trace_s390_zcrypt_rep(mex, func_code, rc, AP_QID_CARD(qid), AP_QID_QUEUE(qid)); return rc; } static long zcrypt_rsa_crt(struct ap_perms *perms, + struct zcrypt_track *tr, struct ica_rsa_modexpo_crt *crt) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; - unsigned int weight, pref_weight; + struct ap_message ap_msg; + unsigned int wgt = 0, pref_wgt = 0; unsigned int func_code; - int qid = 0, rc = -ENODEV; + int cpen, qpen, qid = 0, rc = -ENODEV; struct module *mod; trace_s390_zcrypt_req(crt, TP_ICARSACRT); + ap_init_message(&ap_msg); + +#ifdef CONFIG_ZCRYPT_DEBUG + if (tr && tr->fi.cmd) + ap_msg.fi.cmd = tr->fi.cmd; +#endif + if (crt->outputdatalength < crt->inputdatalength) { func_code = 0; rc = -EINVAL; @@ -745,8 +783,9 @@ pref_zq = NULL; spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { - /* Check for online accelarator and CCA cards */ - if (!zc->online || !(zc->card->functions & 0x18000000)) + /* Check for useable accelarator or CCA card */ + if (!zc->online || !zc->card->config || + !(zc->card->functions & 0x18000000)) continue; /* Check for size limits */ if (zc->min_mod_size > crt->inputdatalength || @@ -756,26 +795,35 @@ if (!zcrypt_check_card(perms, zc->card->id)) continue; /* get weight index of the card device */ - weight = zc->speed_rating[func_code]; - if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) + wgt = zc->speed_rating[func_code]; + /* penalty if this msg was previously sent via this card */ + cpen = (tr && tr->again_counter && tr->last_qid && + AP_QID_CARD(tr->last_qid) == zc->card->id) ? + TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0; + if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt)) continue; for_each_zcrypt_queue(zq, zc) { - /* check if device is online and eligible */ - if (!zq->online || !zq->ops->rsa_modexpo_crt) + /* check if device is useable and eligible */ + if (!zq->online || !zq->ops->rsa_modexpo_crt || + !zq->queue->config) continue; /* check if device node has admission for this queue */ if (!zcrypt_check_queue(perms, AP_QID_QUEUE(zq->queue->qid))) continue; - if (zcrypt_queue_compare(zq, pref_zq, - weight, pref_weight)) + /* penalty if the msg was previously sent at this qid */ + qpen = (tr && tr->again_counter && tr->last_qid && + tr->last_qid == zq->queue->qid) ? + TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0; + if (!zcrypt_queue_compare(zq, pref_zq, + wgt + cpen + qpen, pref_wgt)) continue; pref_zc = zc; pref_zq = zq; - pref_weight = weight; + pref_wgt = wgt + cpen + qpen; } } - pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight); + pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt); spin_unlock(&zcrypt_list_lock); if (!pref_zq) { @@ -784,35 +832,52 @@ } qid = pref_zq->queue->qid; - rc = pref_zq->ops->rsa_modexpo_crt(pref_zq, crt); + rc = pref_zq->ops->rsa_modexpo_crt(pref_zq, crt, &ap_msg); spin_lock(&zcrypt_list_lock); - zcrypt_drop_queue(pref_zc, pref_zq, mod, weight); + zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt); spin_unlock(&zcrypt_list_lock); out: + ap_release_message(&ap_msg); + if (tr) { + tr->last_rc = rc; + tr->last_qid = qid; + } trace_s390_zcrypt_rep(crt, func_code, rc, AP_QID_CARD(qid), AP_QID_QUEUE(qid)); return rc; } -static long _zcrypt_send_cprb(struct ap_perms *perms, +static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms, + struct zcrypt_track *tr, struct ica_xcRB *xcRB) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; struct ap_message ap_msg; - unsigned int weight, pref_weight; + unsigned int wgt = 0, pref_wgt = 0; unsigned int func_code; unsigned short *domain, tdom; - int qid = 0, rc = -ENODEV; + int cpen, qpen, qid = 0, rc = -ENODEV; struct module *mod; trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB); xcRB->status = 0; ap_init_message(&ap_msg); - rc = get_cprb_fc(xcRB, &ap_msg, &func_code, &domain); + +#ifdef CONFIG_ZCRYPT_DEBUG + if (tr && tr->fi.cmd) + ap_msg.fi.cmd = tr->fi.cmd; + if (tr && tr->fi.action == AP_FI_ACTION_CCA_AGENT_FF) { + ZCRYPT_DBF_WARN("%s fi cmd 0x%04x: forcing invalid agent_ID 'FF'\n", + __func__, tr->fi.cmd); + xcRB->agent_ID = 0x4646; + } +#endif + + rc = get_cprb_fc(userspace, xcRB, &ap_msg, &func_code, &domain); if (rc) goto out; @@ -821,7 +886,7 @@ * domain but a control only domain, use the default domain as target. */ tdom = *domain; - if (tdom >= 0 && tdom < AP_DOMAINS && + if (tdom < AP_DOMAINS && !ap_test_config_usage_domain(tdom) && ap_test_config_ctrl_domain(tdom) && ap_domain_index >= 0) @@ -831,40 +896,53 @@ pref_zq = NULL; spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { - /* Check for online CCA cards */ - if (!zc->online || !(zc->card->functions & 0x10000000)) + /* Check for useable CCA card */ + if (!zc->online || !zc->card->config || + !(zc->card->functions & 0x10000000)) continue; /* Check for user selected CCA card */ if (xcRB->user_defined != AUTOSELECT && xcRB->user_defined != zc->card->id) continue; + /* check if request size exceeds card max msg size */ + if (ap_msg.len > zc->card->maxmsgsize) + continue; /* check if device node has admission for this card */ if (!zcrypt_check_card(perms, zc->card->id)) continue; /* get weight index of the card device */ - weight = speed_idx_cca(func_code) * zc->speed_rating[SECKEY]; - if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) + wgt = speed_idx_cca(func_code) * zc->speed_rating[SECKEY]; + /* penalty if this msg was previously sent via this card */ + cpen = (tr && tr->again_counter && tr->last_qid && + AP_QID_CARD(tr->last_qid) == zc->card->id) ? + TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0; + if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt)) continue; for_each_zcrypt_queue(zq, zc) { - /* check if device is online and eligible */ + /* check for device useable and eligible */ if (!zq->online || !zq->ops->send_cprb || - (tdom != (unsigned short) AUTOSELECT && + !zq->queue->config || + (tdom != AUTOSEL_DOM && tdom != AP_QID_QUEUE(zq->queue->qid))) continue; /* check if device node has admission for this queue */ if (!zcrypt_check_queue(perms, AP_QID_QUEUE(zq->queue->qid))) continue; - if (zcrypt_queue_compare(zq, pref_zq, - weight, pref_weight)) + /* penalty if the msg was previously sent at this qid */ + qpen = (tr && tr->again_counter && tr->last_qid && + tr->last_qid == zq->queue->qid) ? + TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0; + if (!zcrypt_queue_compare(zq, pref_zq, + wgt + cpen + qpen, pref_wgt)) continue; pref_zc = zc; pref_zq = zq; - pref_weight = weight; + pref_wgt = wgt + cpen + qpen; } } - pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight); + pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt); spin_unlock(&zcrypt_list_lock); if (!pref_zq) { @@ -874,17 +952,29 @@ /* in case of auto select, provide the correct domain */ qid = pref_zq->queue->qid; - if (*domain == (unsigned short) AUTOSELECT) + if (*domain == AUTOSEL_DOM) *domain = AP_QID_QUEUE(qid); - rc = pref_zq->ops->send_cprb(pref_zq, xcRB, &ap_msg); +#ifdef CONFIG_ZCRYPT_DEBUG + if (tr && tr->fi.action == AP_FI_ACTION_CCA_DOM_INVAL) { + ZCRYPT_DBF_WARN("%s fi cmd 0x%04x: forcing invalid domain\n", + __func__, tr->fi.cmd); + *domain = 99; + } +#endif + + rc = pref_zq->ops->send_cprb(userspace, pref_zq, xcRB, &ap_msg); spin_lock(&zcrypt_list_lock); - zcrypt_drop_queue(pref_zc, pref_zq, mod, weight); + zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt); spin_unlock(&zcrypt_list_lock); out: ap_release_message(&ap_msg); + if (tr) { + tr->last_rc = rc; + tr->last_qid = qid; + } trace_s390_zcrypt_rep(xcRB, func_code, rc, AP_QID_CARD(qid), AP_QID_QUEUE(qid)); return rc; @@ -892,7 +982,7 @@ long zcrypt_send_cprb(struct ica_xcRB *xcRB) { - return _zcrypt_send_cprb(&ap_perms, xcRB); + return _zcrypt_send_cprb(false, &ap_perms, NULL, xcRB); } EXPORT_SYMBOL(zcrypt_send_cprb); @@ -901,7 +991,7 @@ struct ep11_target_dev *targets) { while (target_num-- > 0) { - if (dev_id == targets->ap_id) + if (targets->ap_id == dev_id || targets->ap_id == AUTOSEL_AP) return true; targets++; } @@ -912,31 +1002,40 @@ unsigned short target_num, struct ep11_target_dev *targets) { + int card = AP_QID_CARD(dev_qid), dom = AP_QID_QUEUE(dev_qid); + while (target_num-- > 0) { - if (AP_MKQID(targets->ap_id, targets->dom_id) == dev_qid) + if ((targets->ap_id == card || targets->ap_id == AUTOSEL_AP) && + (targets->dom_id == dom || targets->dom_id == AUTOSEL_DOM)) return true; targets++; } return false; } -static long zcrypt_send_ep11_cprb(struct ap_perms *perms, - struct ep11_urb *xcrb) +static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms, + struct zcrypt_track *tr, + struct ep11_urb *xcrb) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; struct ep11_target_dev *targets; unsigned short target_num; - unsigned int weight, pref_weight; + unsigned int wgt = 0, pref_wgt = 0; unsigned int func_code; struct ap_message ap_msg; - int qid = 0, rc = -ENODEV; + int cpen, qpen, qid = 0, rc = -ENODEV; struct module *mod; trace_s390_zcrypt_req(xcrb, TP_ZSENDEP11CPRB); ap_init_message(&ap_msg); +#ifdef CONFIG_ZCRYPT_DEBUG + if (tr && tr->fi.cmd) + ap_msg.fi.cmd = tr->fi.cmd; +#endif + target_num = (unsigned short) xcrb->targets_num; /* empty list indicates autoselect (all available targets) */ @@ -952,7 +1051,7 @@ } uptr = (struct ep11_target_dev __force __user *) xcrb->targets; - if (copy_from_user(targets, uptr, + if (z_copy_from_user(userspace, targets, uptr, target_num * sizeof(*targets))) { func_code = 0; rc = -EFAULT; @@ -960,7 +1059,7 @@ } } - rc = get_ep11cprb_fc(xcrb, &ap_msg, &func_code); + rc = get_ep11cprb_fc(userspace, xcrb, &ap_msg, &func_code); if (rc) goto out_free; @@ -968,24 +1067,33 @@ pref_zq = NULL; spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { - /* Check for online EP11 cards */ - if (!zc->online || !(zc->card->functions & 0x04000000)) + /* Check for useable EP11 card */ + if (!zc->online || !zc->card->config || + !(zc->card->functions & 0x04000000)) continue; /* Check for user selected EP11 card */ if (targets && !is_desired_ep11_card(zc->card->id, target_num, targets)) continue; + /* check if request size exceeds card max msg size */ + if (ap_msg.len > zc->card->maxmsgsize) + continue; /* check if device node has admission for this card */ if (!zcrypt_check_card(perms, zc->card->id)) continue; /* get weight index of the card device */ - weight = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY]; - if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) + wgt = speed_idx_ep11(func_code) * zc->speed_rating[SECKEY]; + /* penalty if this msg was previously sent via this card */ + cpen = (tr && tr->again_counter && tr->last_qid && + AP_QID_CARD(tr->last_qid) == zc->card->id) ? + TRACK_AGAIN_CARD_WEIGHT_PENALTY : 0; + if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt)) continue; for_each_zcrypt_queue(zq, zc) { - /* check if device is online and eligible */ + /* check if device is useable and eligible */ if (!zq->online || !zq->ops->send_ep11_cprb || + !zq->queue->config || (targets && !is_desired_ep11_queue(zq->queue->qid, target_num, targets))) @@ -994,15 +1102,19 @@ if (!zcrypt_check_queue(perms, AP_QID_QUEUE(zq->queue->qid))) continue; - if (zcrypt_queue_compare(zq, pref_zq, - weight, pref_weight)) + /* penalty if the msg was previously sent at this qid */ + qpen = (tr && tr->again_counter && tr->last_qid && + tr->last_qid == zq->queue->qid) ? + TRACK_AGAIN_QUEUE_WEIGHT_PENALTY : 0; + if (!zcrypt_queue_compare(zq, pref_zq, + wgt + cpen + qpen, pref_wgt)) continue; pref_zc = zc; pref_zq = zq; - pref_weight = weight; + pref_wgt = wgt + cpen + qpen; } } - pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight); + pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt); spin_unlock(&zcrypt_list_lock); if (!pref_zq) { @@ -1011,26 +1123,36 @@ } qid = pref_zq->queue->qid; - rc = pref_zq->ops->send_ep11_cprb(pref_zq, xcrb, &ap_msg); + rc = pref_zq->ops->send_ep11_cprb(userspace, pref_zq, xcrb, &ap_msg); spin_lock(&zcrypt_list_lock); - zcrypt_drop_queue(pref_zc, pref_zq, mod, weight); + zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt); spin_unlock(&zcrypt_list_lock); out_free: kfree(targets); out: ap_release_message(&ap_msg); + if (tr) { + tr->last_rc = rc; + tr->last_qid = qid; + } trace_s390_zcrypt_rep(xcrb, func_code, rc, AP_QID_CARD(qid), AP_QID_QUEUE(qid)); return rc; } +long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb) +{ + return _zcrypt_send_ep11_cprb(false, &ap_perms, NULL, xcrb); +} +EXPORT_SYMBOL(zcrypt_send_ep11_cprb); + static long zcrypt_rng(char *buffer) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; - unsigned int weight, pref_weight; + unsigned int wgt = 0, pref_wgt = 0; unsigned int func_code; struct ap_message ap_msg; unsigned int domain; @@ -1048,26 +1170,27 @@ pref_zq = NULL; spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { - /* Check for online CCA cards */ - if (!zc->online || !(zc->card->functions & 0x10000000)) + /* Check for useable CCA card */ + if (!zc->online || !zc->card->config || + !(zc->card->functions & 0x10000000)) continue; /* get weight index of the card device */ - weight = zc->speed_rating[func_code]; - if (zcrypt_card_compare(zc, pref_zc, weight, pref_weight)) + wgt = zc->speed_rating[func_code]; + if (!zcrypt_card_compare(zc, pref_zc, wgt, pref_wgt)) continue; for_each_zcrypt_queue(zq, zc) { - /* check if device is online and eligible */ - if (!zq->online || !zq->ops->rng) + /* check if device is useable and eligible */ + if (!zq->online || !zq->ops->rng || + !zq->queue->config) continue; - if (zcrypt_queue_compare(zq, pref_zq, - weight, pref_weight)) + if (!zcrypt_queue_compare(zq, pref_zq, wgt, pref_wgt)) continue; pref_zc = zc; pref_zq = zq; - pref_weight = weight; + pref_wgt = wgt; } } - pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, weight); + pref_zq = zcrypt_pick_queue(pref_zc, pref_zq, &mod, wgt); spin_unlock(&zcrypt_list_lock); if (!pref_zq) { @@ -1079,7 +1202,7 @@ rc = pref_zq->ops->rng(pref_zq, buffer, &ap_msg); spin_lock(&zcrypt_list_lock); - zcrypt_drop_queue(pref_zc, pref_zq, mod, weight); + zcrypt_drop_queue(pref_zc, pref_zq, mod, wgt); spin_unlock(&zcrypt_list_lock); out: @@ -1216,11 +1339,12 @@ spin_unlock(&zcrypt_list_lock); } -static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) +static void zcrypt_perdev_reqcnt(u32 reqcnt[], size_t max_adapters) { struct zcrypt_card *zc; struct zcrypt_queue *zq; int card; + u64 cnt; memset(reqcnt, 0, sizeof(int) * max_adapters); spin_lock(&zcrypt_list_lock); @@ -1232,8 +1356,9 @@ || card >= max_adapters) continue; spin_lock(&zq->queue->lock); - reqcnt[card] = zq->queue->total_request_count; + cnt = zq->queue->total_request_count; spin_unlock(&zq->queue->lock); + reqcnt[card] = (cnt < UINT_MAX) ? (u32) cnt : UINT_MAX; } } local_bh_enable(); @@ -1286,99 +1411,207 @@ return requestq_count; } -static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) +static int icarsamodexpo_ioctl(struct ap_perms *perms, unsigned long arg) { int rc; - struct ap_perms *perms = - (struct ap_perms *) filp->private_data; + struct zcrypt_track tr; + struct ica_rsa_modexpo mex; + struct ica_rsa_modexpo __user *umex = (void __user *) arg; - rc = zcrypt_check_ioctl(perms, cmd); - if (rc) - return rc; + memset(&tr, 0, sizeof(tr)); + if (copy_from_user(&mex, umex, sizeof(mex))) + return -EFAULT; - switch (cmd) { - case ICARSAMODEXPO: { - struct ica_rsa_modexpo __user *umex = (void __user *) arg; - struct ica_rsa_modexpo mex; +#ifdef CONFIG_ZCRYPT_DEBUG + if (mex.inputdatalength & (1U << 31)) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + tr.fi.cmd = (u16)(mex.inputdatalength >> 16); + } + mex.inputdatalength &= 0x0000FFFF; +#endif - if (copy_from_user(&mex, umex, sizeof(mex))) - return -EFAULT; + do { + rc = zcrypt_rsa_modexpo(perms, &tr, &mex); + if (rc == -EAGAIN) + tr.again_counter++; +#ifdef CONFIG_ZCRYPT_DEBUG + if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY)) + break; +#endif + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + /* on failure: retry once again after a requested rescan */ + if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = zcrypt_rsa_modexpo(perms, &mex); - } while (rc == -EAGAIN); - /* on failure: retry once again after a requested rescan */ - if ((rc == -ENODEV) && (zcrypt_process_rescan())) - do { - rc = zcrypt_rsa_modexpo(perms, &mex); - } while (rc == -EAGAIN); - if (rc) { - ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSAMODEXPO rc=%d\n", rc); - return rc; - } - return put_user(mex.outputdatalength, &umex->outputdatalength); + rc = zcrypt_rsa_modexpo(perms, &tr, &mex); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; + if (rc) { + ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSAMODEXPO rc=%d\n", rc); + return rc; } - case ICARSACRT: { - struct ica_rsa_modexpo_crt __user *ucrt = (void __user *) arg; - struct ica_rsa_modexpo_crt crt; + return put_user(mex.outputdatalength, &umex->outputdatalength); +} - if (copy_from_user(&crt, ucrt, sizeof(crt))) - return -EFAULT; - do { - rc = zcrypt_rsa_crt(perms, &crt); - } while (rc == -EAGAIN); - /* on failure: retry once again after a requested rescan */ - if ((rc == -ENODEV) && (zcrypt_process_rescan())) - do { - rc = zcrypt_rsa_crt(perms, &crt); - } while (rc == -EAGAIN); - if (rc) { - ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSACRT rc=%d\n", rc); - return rc; - } - return put_user(crt.outputdatalength, &ucrt->outputdatalength); +static int icarsacrt_ioctl(struct ap_perms *perms, unsigned long arg) +{ + int rc; + struct zcrypt_track tr; + struct ica_rsa_modexpo_crt crt; + struct ica_rsa_modexpo_crt __user *ucrt = (void __user *) arg; + + memset(&tr, 0, sizeof(tr)); + if (copy_from_user(&crt, ucrt, sizeof(crt))) + return -EFAULT; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (crt.inputdatalength & (1U << 31)) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + tr.fi.cmd = (u16)(crt.inputdatalength >> 16); } - case ZSECSENDCPRB: { - struct ica_xcRB __user *uxcRB = (void __user *) arg; - struct ica_xcRB xcRB; + crt.inputdatalength &= 0x0000FFFF; +#endif - if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB))) - return -EFAULT; + do { + rc = zcrypt_rsa_crt(perms, &tr, &crt); + if (rc == -EAGAIN) + tr.again_counter++; +#ifdef CONFIG_ZCRYPT_DEBUG + if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY)) + break; +#endif + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + /* on failure: retry once again after a requested rescan */ + if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = _zcrypt_send_cprb(perms, &xcRB); - } while (rc == -EAGAIN); - /* on failure: retry once again after a requested rescan */ - if ((rc == -ENODEV) && (zcrypt_process_rescan())) - do { - rc = _zcrypt_send_cprb(perms, &xcRB); - } while (rc == -EAGAIN); - if (rc) - ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d status=0x%x\n", - rc, xcRB.status); - if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB))) - return -EFAULT; + rc = zcrypt_rsa_crt(perms, &tr, &crt); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; + if (rc) { + ZCRYPT_DBF(DBF_DEBUG, "ioctl ICARSACRT rc=%d\n", rc); return rc; } - case ZSENDEP11CPRB: { - struct ep11_urb __user *uxcrb = (void __user *)arg; - struct ep11_urb xcrb; + return put_user(crt.outputdatalength, &ucrt->outputdatalength); +} - if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb))) - return -EFAULT; +static int zsecsendcprb_ioctl(struct ap_perms *perms, unsigned long arg) +{ + int rc; + struct ica_xcRB xcRB; + struct zcrypt_track tr; + struct ica_xcRB __user *uxcRB = (void __user *) arg; + + memset(&tr, 0, sizeof(tr)); + if (copy_from_user(&xcRB, uxcRB, sizeof(xcRB))) + return -EFAULT; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (xcRB.status & (1U << 31)) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + tr.fi.cmd = (u16)(xcRB.status >> 16); + } + xcRB.status &= 0x0000FFFF; +#endif + + do { + rc = _zcrypt_send_cprb(true, perms, &tr, &xcRB); + if (rc == -EAGAIN) + tr.again_counter++; +#ifdef CONFIG_ZCRYPT_DEBUG + if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY)) + break; +#endif + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + /* on failure: retry once again after a requested rescan */ + if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = zcrypt_send_ep11_cprb(perms, &xcrb); - } while (rc == -EAGAIN); - /* on failure: retry once again after a requested rescan */ - if ((rc == -ENODEV) && (zcrypt_process_rescan())) - do { - rc = zcrypt_send_ep11_cprb(perms, &xcrb); - } while (rc == -EAGAIN); - if (rc) - ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDEP11CPRB rc=%d\n", rc); - if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb))) - return -EFAULT; - return rc; + rc = _zcrypt_send_cprb(true, perms, &tr, &xcRB); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; + if (rc) + ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d status=0x%x\n", + rc, xcRB.status); + if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB))) + return -EFAULT; + return rc; +} + +static int zsendep11cprb_ioctl(struct ap_perms *perms, unsigned long arg) +{ + int rc; + struct ep11_urb xcrb; + struct zcrypt_track tr; + struct ep11_urb __user *uxcrb = (void __user *)arg; + + memset(&tr, 0, sizeof(tr)); + if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb))) + return -EFAULT; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (xcrb.req_len & (1ULL << 63)) { + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + tr.fi.cmd = (u16)(xcrb.req_len >> 48); } + xcrb.req_len &= 0x0000FFFFFFFFFFFFULL; +#endif + + do { + rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb); + if (rc == -EAGAIN) + tr.again_counter++; +#ifdef CONFIG_ZCRYPT_DEBUG + if (rc == -EAGAIN && (tr.fi.flags & AP_FI_FLAG_NO_RETRY)) + break; +#endif + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + /* on failure: retry once again after a requested rescan */ + if ((rc == -ENODEV) && (zcrypt_process_rescan())) + do { + rc = _zcrypt_send_ep11_cprb(true, perms, &tr, &xcrb); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; + if (rc) + ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDEP11CPRB rc=%d\n", rc); + if (copy_to_user(uxcrb, &xcrb, sizeof(xcrb))) + return -EFAULT; + return rc; +} + +static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int rc; + struct ap_perms *perms = + (struct ap_perms *) filp->private_data; + + rc = zcrypt_check_ioctl(perms, cmd); + if (rc) + return rc; + + switch (cmd) { + case ICARSAMODEXPO: + return icarsamodexpo_ioctl(perms, arg); + case ICARSACRT: + return icarsacrt_ioctl(perms, arg); + case ZSECSENDCPRB: + return zsecsendcprb_ioctl(perms, arg); + case ZSENDEP11CPRB: + return zsendep11cprb_ioctl(perms, arg); case ZCRYPT_DEVICE_STATUS: { struct zcrypt_device_status_ext *device_status; size_t total_size = MAX_ZDEV_ENTRIES_EXT @@ -1411,13 +1644,14 @@ return 0; } case ZCRYPT_PERDEV_REQCNT: { - int *reqcnt; + u32 *reqcnt; - reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL); + reqcnt = kcalloc(AP_DEVICES, sizeof(u32), GFP_KERNEL); if (!reqcnt) return -ENOMEM; zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES); - if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) + if (copy_to_user((int __user *) arg, reqcnt, + sizeof(u32) * AP_DEVICES)) rc = -EFAULT; kfree(reqcnt); return rc; @@ -1470,7 +1704,7 @@ } case Z90STAT_PERDEV_REQCNT: { /* the old ioctl supports only 64 adapters */ - int reqcnt[MAX_ZDEV_CARDIDS]; + u32 reqcnt[MAX_ZDEV_CARDIDS]; zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS); if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) @@ -1503,8 +1737,10 @@ struct compat_ica_rsa_modexpo __user *umex32 = compat_ptr(arg); struct compat_ica_rsa_modexpo mex32; struct ica_rsa_modexpo mex64; + struct zcrypt_track tr; long rc; + memset(&tr, 0, sizeof(tr)); if (copy_from_user(&mex32, umex32, sizeof(mex32))) return -EFAULT; mex64.inputdata = compat_ptr(mex32.inputdata); @@ -1514,13 +1750,19 @@ mex64.b_key = compat_ptr(mex32.b_key); mex64.n_modulus = compat_ptr(mex32.n_modulus); do { - rc = zcrypt_rsa_modexpo(perms, &mex64); - } while (rc == -EAGAIN); + rc = zcrypt_rsa_modexpo(perms, &tr, &mex64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); /* on failure: retry once again after a requested rescan */ if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = zcrypt_rsa_modexpo(perms, &mex64); - } while (rc == -EAGAIN); + rc = zcrypt_rsa_modexpo(perms, &tr, &mex64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; if (rc) return rc; return put_user(mex64.outputdatalength, @@ -1545,8 +1787,10 @@ struct compat_ica_rsa_modexpo_crt __user *ucrt32 = compat_ptr(arg); struct compat_ica_rsa_modexpo_crt crt32; struct ica_rsa_modexpo_crt crt64; + struct zcrypt_track tr; long rc; + memset(&tr, 0, sizeof(tr)); if (copy_from_user(&crt32, ucrt32, sizeof(crt32))) return -EFAULT; crt64.inputdata = compat_ptr(crt32.inputdata); @@ -1559,13 +1803,19 @@ crt64.nq_prime = compat_ptr(crt32.nq_prime); crt64.u_mult_inv = compat_ptr(crt32.u_mult_inv); do { - rc = zcrypt_rsa_crt(perms, &crt64); - } while (rc == -EAGAIN); + rc = zcrypt_rsa_crt(perms, &tr, &crt64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); /* on failure: retry once again after a requested rescan */ if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = zcrypt_rsa_crt(perms, &crt64); - } while (rc == -EAGAIN); + rc = zcrypt_rsa_crt(perms, &tr, &crt64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; if (rc) return rc; return put_user(crt64.outputdatalength, @@ -1597,9 +1847,11 @@ { struct compat_ica_xcRB __user *uxcRB32 = compat_ptr(arg); struct compat_ica_xcRB xcRB32; + struct zcrypt_track tr; struct ica_xcRB xcRB64; long rc; + memset(&tr, 0, sizeof(tr)); if (copy_from_user(&xcRB32, uxcRB32, sizeof(xcRB32))) return -EFAULT; xcRB64.agent_ID = xcRB32.agent_ID; @@ -1623,13 +1875,19 @@ xcRB64.priority_window = xcRB32.priority_window; xcRB64.status = xcRB32.status; do { - rc = _zcrypt_send_cprb(perms, &xcRB64); - } while (rc == -EAGAIN); + rc = _zcrypt_send_cprb(true, perms, &tr, &xcRB64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); /* on failure: retry once again after a requested rescan */ if ((rc == -ENODEV) && (zcrypt_process_rescan())) do { - rc = _zcrypt_send_cprb(perms, &xcRB64); - } while (rc == -EAGAIN); + rc = _zcrypt_send_cprb(true, perms, &tr, &xcRB64); + if (rc == -EAGAIN) + tr.again_counter++; + } while (rc == -EAGAIN && tr.again_counter < TRACK_AGAIN_MAX); + if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX) + rc = -EIO; xcRB32.reply_control_blk_length = xcRB64.reply_control_blk_length; xcRB32.reply_data_length = xcRB64.reply_data_length; xcRB32.status = xcRB64.status; @@ -1885,6 +2143,7 @@ zcrypt_msgtype6_exit(); zcrypt_msgtype50_exit(); zcrypt_ccamisc_exit(); + zcrypt_ep11misc_exit(); zcrypt_debug_exit(); } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_api.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_api.h @@ -55,13 +55,30 @@ struct zcrypt_queue; +/* struct to hold tracking information for a userspace request/response */ +struct zcrypt_track { + int again_counter; /* retry attempts counter */ + int last_qid; /* last qid used */ + int last_rc; /* last return code */ +#ifdef CONFIG_ZCRYPT_DEBUG + struct ap_fi fi; /* failure injection cmd */ +#endif +}; + +/* defines related to message tracking */ +#define TRACK_AGAIN_MAX 10 +#define TRACK_AGAIN_CARD_WEIGHT_PENALTY 1000 +#define TRACK_AGAIN_QUEUE_WEIGHT_PENALTY 10000 + struct zcrypt_ops { - long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *); + long (*rsa_modexpo)(struct zcrypt_queue *, struct ica_rsa_modexpo *, + struct ap_message *); long (*rsa_modexpo_crt)(struct zcrypt_queue *, - struct ica_rsa_modexpo_crt *); - long (*send_cprb)(struct zcrypt_queue *, struct ica_xcRB *, + struct ica_rsa_modexpo_crt *, + struct ap_message *); + long (*send_cprb)(bool userspace, struct zcrypt_queue *, struct ica_xcRB *, struct ap_message *); - long (*send_ep11_cprb)(struct zcrypt_queue *, struct ep11_urb *, + long (*send_ep11_cprb)(bool userspace, struct zcrypt_queue *, struct ep11_urb *, struct ap_message *); long (*rng)(struct zcrypt_queue *, char *, struct ap_message *); struct list_head list; /* zcrypt ops list. */ @@ -82,7 +99,7 @@ int min_mod_size; /* Min number of bits. */ int max_mod_size; /* Max number of bits. */ int max_exp_bit_length; - int speed_rating[NUM_OPS]; /* Speed idx of crypto ops. */ + const int *speed_rating; /* Speed idx of crypto ops. */ atomic_t load; /* Utilization of the crypto device */ int request_count; /* # current requests. */ @@ -140,8 +157,31 @@ int zcrypt_api_init(void); void zcrypt_api_exit(void); long zcrypt_send_cprb(struct ica_xcRB *xcRB); +long zcrypt_send_ep11_cprb(struct ep11_urb *urb); void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); int zcrypt_device_status_ext(int card, int queue, struct zcrypt_device_status_ext *devstatus); +static inline unsigned long z_copy_from_user(bool userspace, + void *to, + const void __user *from, + unsigned long n) +{ + if (likely(userspace)) + return copy_from_user(to, from, n); + memcpy(to, (void __force *) from, n); + return 0; +} + +static inline unsigned long z_copy_to_user(bool userspace, + void __user *to, + const void *from, + unsigned long n) +{ + if (likely(userspace)) + return copy_to_user(to, from, n); + memcpy((void __force *) to, from, n); + return 0; +} + #endif /* _ZCRYPT_API_H_ */ --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_card.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_card.c @@ -41,7 +41,7 @@ { struct zcrypt_card *zc = to_ap_card(dev)->private; - return snprintf(buf, PAGE_SIZE, "%s\n", zc->type_string); + return scnprintf(buf, PAGE_SIZE, "%s\n", zc->type_string); } static DEVICE_ATTR_RO(type); @@ -50,22 +50,28 @@ struct device_attribute *attr, char *buf) { - struct zcrypt_card *zc = to_ap_card(dev)->private; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + int online = ac->config && zc->online ? 1 : 0; - return snprintf(buf, PAGE_SIZE, "%d\n", zc->online); + return scnprintf(buf, PAGE_SIZE, "%d\n", online); } static ssize_t online_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct zcrypt_card *zc = to_ap_card(dev)->private; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; struct zcrypt_queue *zq; int online, id; if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1) return -EINVAL; + if (online && !ac->config) + return -ENODEV; + zc->online = online; id = zc->card->id; @@ -86,7 +92,7 @@ { struct zcrypt_card *zc = to_ap_card(dev)->private; - return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zc->load)); + return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zc->load)); } static DEVICE_ATTR_RO(load); @@ -151,11 +157,6 @@ { int rc; - rc = sysfs_create_group(&zc->card->ap_dev.device.kobj, - &zcrypt_card_attr_group); - if (rc) - return rc; - spin_lock(&zcrypt_list_lock); list_add_tail(&zc->list, &zcrypt_card_list); spin_unlock(&zcrypt_list_lock); @@ -164,6 +165,14 @@ ZCRYPT_DBF(DBF_INFO, "card=%02x register online=1\n", zc->card->id); + rc = sysfs_create_group(&zc->card->ap_dev.device.kobj, + &zcrypt_card_attr_group); + if (rc) { + spin_lock(&zcrypt_list_lock); + list_del_init(&zc->list); + spin_unlock(&zcrypt_list_lock); + } + return rc; } EXPORT_SYMBOL(zcrypt_card_register); @@ -183,5 +192,6 @@ spin_unlock(&zcrypt_list_lock); sysfs_remove_group(&zc->card->ap_dev.device.kobj, &zcrypt_card_attr_group); + zcrypt_card_put(zc); } EXPORT_SYMBOL(zcrypt_card_unregister); --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_ccamisc.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_ccamisc.c @@ -205,9 +205,9 @@ preqcblk->rpl_msgbl = cprbplusparamblen; if (paramblen) { preqcblk->req_parmb = - ((u8 *) preqcblk) + sizeof(struct CPRBX); + ((u8 __user *) preqcblk) + sizeof(struct CPRBX); preqcblk->rpl_parmb = - ((u8 *) prepcblk) + sizeof(struct CPRBX); + ((u8 __user *) prepcblk) + sizeof(struct CPRBX); } *pcprbmem = cprbmem; @@ -249,24 +249,6 @@ } /* - * Helper function which calls zcrypt_send_cprb with - * memory management segment adjusted to kernel space - * so that the copy_from_user called within this - * function do in fact copy from kernel space. - */ -static inline int _zcrypt_send_cprb(struct ica_xcRB *xcrb) -{ - int rc; - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - rc = zcrypt_send_cprb(xcrb); - set_fs(old_fs); - - return rc; -} - -/* * Generate (random) CCA AES DATA secure key. */ int cca_genseckey(u16 cardnr, u16 domain, @@ -274,7 +256,7 @@ { int i, rc, keysize; int seckeysize; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct kgreqparm { @@ -320,7 +302,7 @@ preqcblk->domain = domain; /* fill request cprb param block with KG request */ - preqparm = (struct kgreqparm *) preqcblk->req_parmb; + preqparm = (struct kgreqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "KG", 2); preqparm->rule_array_len = sizeof(preqparm->rule_array_len); preqparm->lv1.len = sizeof(struct lv1); @@ -359,7 +341,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n", __func__, (int) cardnr, (int) domain, rc); @@ -377,8 +359,9 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct kgrepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct kgrepparm *) ptr; /* check length of the returned secure key token */ seckeysize = prepparm->lv3.keyblock.toklen @@ -415,7 +398,7 @@ const u8 *clrkey, u8 seckey[SECKEYBLOBSIZE]) { int rc, keysize, seckeysize; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct cmreqparm { @@ -460,7 +443,7 @@ preqcblk->domain = domain; /* fill request cprb param block with CM request */ - preqparm = (struct cmreqparm *) preqcblk->req_parmb; + preqparm = (struct cmreqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "CM", 2); memcpy(preqparm->rule_array, "AES ", 8); preqparm->rule_array_len = @@ -496,7 +479,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", __func__, (int) cardnr, (int) domain, rc); @@ -514,8 +497,9 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct cmrepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct cmrepparm *) ptr; /* check length of the returned secure key token */ seckeysize = prepparm->lv3.keyblock.toklen @@ -554,7 +538,7 @@ u8 *protkey, u32 *protkeylen, u32 *protkeytype) { int rc; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct uskreqparm { @@ -592,7 +576,7 @@ u8 pad2[1]; u8 vptype; u8 vp[32]; /* verification pattern */ - } keyblock; + } ckb; } lv3; } __packed * prepparm; @@ -605,7 +589,7 @@ preqcblk->domain = domain; /* fill request cprb param block with USK request */ - preqparm = (struct uskreqparm *) preqcblk->req_parmb; + preqparm = (struct uskreqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "US", 2); preqparm->rule_array_len = sizeof(preqparm->rule_array_len); preqparm->lv1.len = sizeof(struct lv1); @@ -622,7 +606,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", __func__, (int) cardnr, (int) domain, rc); @@ -646,19 +630,21 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct uskrepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct uskrepparm *) ptr; /* check the returned keyblock */ - if (prepparm->lv3.keyblock.version != 0x01) { - DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x != 0x01\n", - __func__, (int) prepparm->lv3.keyblock.version); + if (prepparm->lv3.ckb.version != 0x01 && + prepparm->lv3.ckb.version != 0x02) { + DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x\n", + __func__, (int) prepparm->lv3.ckb.version); rc = -EIO; goto out; } /* copy the tanslated protected key */ - switch (prepparm->lv3.keyblock.len) { + switch (prepparm->lv3.ckb.len) { case 16+32: /* AES 128 protected key */ if (protkeytype) @@ -676,13 +662,13 @@ break; default: DEBUG_ERR("%s unknown/unsupported keylen %d\n", - __func__, prepparm->lv3.keyblock.len); + __func__, prepparm->lv3.ckb.len); rc = -EIO; goto out; } - memcpy(protkey, prepparm->lv3.keyblock.key, prepparm->lv3.keyblock.len); + memcpy(protkey, prepparm->lv3.ckb.key, prepparm->lv3.ckb.len); if (protkeylen) - *protkeylen = prepparm->lv3.keyblock.len; + *protkeylen = prepparm->lv3.ckb.len; out: free_cprbmem(mem, PARMBSIZE, 0); @@ -713,7 +699,7 @@ u8 *keybuf, size_t *keybufsize) { int rc; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct gkreqparm { @@ -795,7 +781,7 @@ preqcblk->req_parml = sizeof(struct gkreqparm); /* prepare request param block with GK request */ - preqparm = (struct gkreqparm *) preqcblk->req_parmb; + preqparm = (struct gkreqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "GK", 2); preqparm->rule_array_len = sizeof(uint16_t) + 2 * 8; memcpy(preqparm->rule_array, "AES OP ", 2*8); @@ -846,7 +832,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR( "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", @@ -866,8 +852,9 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct gkrepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct gkrepparm *) ptr; /* do some plausibility checks on the key block */ if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) || @@ -916,7 +903,7 @@ int *key_token_size) { int rc, n; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct rule_array_block { @@ -973,7 +960,7 @@ preqcblk->req_parml = 0; /* prepare request param block with IP request */ - preq_ra_block = (struct rule_array_block *) preqcblk->req_parmb; + preq_ra_block = (struct rule_array_block __force *) preqcblk->req_parmb; memcpy(preq_ra_block->subfunc_code, "IP", 2); preq_ra_block->rule_array_len = sizeof(uint16_t) + 2 * 8; memcpy(preq_ra_block->rule_array, rule_array_1, 8); @@ -986,7 +973,7 @@ } /* prepare vud block */ - preq_vud_block = (struct vud_block *) + preq_vud_block = (struct vud_block __force *) (preqcblk->req_parmb + preqcblk->req_parml); n = complete ? 0 : (clr_key_bit_size + 7) / 8; preq_vud_block->len = sizeof(struct vud_block) + n; @@ -1000,7 +987,7 @@ preqcblk->req_parml += preq_vud_block->len; /* prepare key block */ - preq_key_block = (struct key_block *) + preq_key_block = (struct key_block __force *) (preqcblk->req_parmb + preqcblk->req_parml); n = *key_token_size; preq_key_block->len = sizeof(struct key_block) + n; @@ -1013,7 +1000,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR( "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", @@ -1033,12 +1020,13 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct iprepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct iprepparm *) ptr; /* do some plausibility checks on the key block */ - if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) || - prepparm->kb.len > 136 + 5 * sizeof(uint16_t)) { + if (prepparm->kb.len < 120 + 3 * sizeof(uint16_t) || + prepparm->kb.len > 136 + 3 * sizeof(uint16_t)) { DEBUG_ERR("%s reply with invalid or unknown key block\n", __func__); rc = -EIO; @@ -1150,7 +1138,7 @@ u8 *protkey, u32 *protkeylen, u32 *protkeytype) { int rc; - u8 *mem; + u8 *mem, *ptr; struct CPRBX *preqcblk, *prepcblk; struct ica_xcRB xcrb; struct aureqparm { @@ -1207,7 +1195,7 @@ preqcblk->domain = domain; /* fill request cprb param block with AU request */ - preqparm = (struct aureqparm *) preqcblk->req_parmb; + preqparm = (struct aureqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "AU", 2); preqparm->rule_array_len = sizeof(preqparm->rule_array_len) @@ -1229,7 +1217,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR( "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", @@ -1256,14 +1244,15 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct aurepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct aurepparm *) ptr; /* check the returned keyblock */ - if (prepparm->vud.ckb.version != 0x01) { - DEBUG_ERR( - "%s reply param keyblock version mismatch 0x%02x != 0x01\n", - __func__, (int) prepparm->vud.ckb.version); + if (prepparm->vud.ckb.version != 0x01 && + prepparm->vud.ckb.version != 0x02) { + DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x\n", + __func__, (int) prepparm->vud.ckb.version); rc = -EIO; goto out; } @@ -1346,7 +1335,7 @@ preqcblk->domain = domain; /* fill request cprb param block with FQ request */ - preqparm = (struct fqreqparm *) preqcblk->req_parmb; + preqparm = (struct fqreqparm __force *) preqcblk->req_parmb; memcpy(preqparm->subfunc_code, "FQ", 2); memcpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array)); preqparm->rule_array_len = @@ -1359,7 +1348,7 @@ prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ - rc = _zcrypt_send_cprb(&xcrb); + rc = zcrypt_send_cprb(&xcrb); if (rc) { DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", __func__, (int) cardnr, (int) domain, rc); @@ -1377,8 +1366,9 @@ } /* process response cprb param block */ - prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); - prepparm = (struct fqrepparm *) prepcblk->rpl_parmb; + ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepcblk->rpl_parmb = (u8 __user *) ptr; + prepparm = (struct fqrepparm *) ptr; ptr = prepparm->lvdata; /* check and possibly copy reply rule array */ @@ -1516,21 +1506,38 @@ rarray, &rlen, varray, &vlen); if (rc == 0 && rlen >= 10*8 && vlen >= 204) { memcpy(ci->serial, rarray, 8); - ci->new_mk_state = (char) rarray[7*8]; - ci->cur_mk_state = (char) rarray[8*8]; - ci->old_mk_state = (char) rarray[9*8]; - if (ci->old_mk_state == '2') - memcpy(&ci->old_mkvp, varray + 172, 8); - if (ci->cur_mk_state == '2') - memcpy(&ci->cur_mkvp, varray + 184, 8); - if (ci->new_mk_state == '3') - memcpy(&ci->new_mkvp, varray + 196, 8); - found = 1; + ci->new_aes_mk_state = (char) rarray[7*8]; + ci->cur_aes_mk_state = (char) rarray[8*8]; + ci->old_aes_mk_state = (char) rarray[9*8]; + if (ci->old_aes_mk_state == '2') + memcpy(&ci->old_aes_mkvp, varray + 172, 8); + if (ci->cur_aes_mk_state == '2') + memcpy(&ci->cur_aes_mkvp, varray + 184, 8); + if (ci->new_aes_mk_state == '3') + memcpy(&ci->new_aes_mkvp, varray + 196, 8); + found++; + } + if (!found) + goto out; + rlen = vlen = PAGE_SIZE/2; + rc = cca_query_crypto_facility(cardnr, domain, "STATICSB", + rarray, &rlen, varray, &vlen); + if (rc == 0 && rlen >= 10*8 && vlen >= 240) { + ci->new_apka_mk_state = (char) rarray[7*8]; + ci->cur_apka_mk_state = (char) rarray[8*8]; + ci->old_apka_mk_state = (char) rarray[9*8]; + if (ci->old_apka_mk_state == '2') + memcpy(&ci->old_apka_mkvp, varray + 208, 8); + if (ci->cur_apka_mk_state == '2') + memcpy(&ci->cur_apka_mkvp, varray + 220, 8); + if (ci->new_apka_mk_state == '3') + memcpy(&ci->new_apka_mkvp, varray + 232, 8); + found++; } +out: free_page((unsigned long) pg); - - return found ? 0 : -ENOENT; + return found == 2 ? 0 : -ENOENT; } /* @@ -1568,9 +1575,9 @@ return -EINVAL; /* fetch status of all crypto cards */ - device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, - sizeof(struct zcrypt_device_status_ext), - GFP_KERNEL); + device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT, + sizeof(struct zcrypt_device_status_ext), + GFP_KERNEL); if (!device_status) return -ENOMEM; zcrypt_device_status_mask_ext(device_status); @@ -1584,16 +1591,16 @@ /* enabled CCA card, check current mkvp from cache */ if (cca_info_cache_fetch(card, dom, &ci) == 0 && ci.hwtype >= minhwtype && - ci.cur_mk_state == '2' && - ci.cur_mkvp == mkvp) { + ci.cur_aes_mk_state == '2' && + ci.cur_aes_mkvp == mkvp) { if (!verify) break; /* verify: refresh card info */ if (fetch_cca_info(card, dom, &ci) == 0) { cca_info_cache_update(card, dom, &ci); if (ci.hwtype >= minhwtype && - ci.cur_mk_state == '2' && - ci.cur_mkvp == mkvp) + ci.cur_aes_mk_state == '2' && + ci.cur_aes_mkvp == mkvp) break; } } @@ -1615,12 +1622,12 @@ if (fetch_cca_info(card, dom, &ci) == 0) { cca_info_cache_update(card, dom, &ci); if (ci.hwtype >= minhwtype && - ci.cur_mk_state == '2' && - ci.cur_mkvp == mkvp) + ci.cur_aes_mk_state == '2' && + ci.cur_aes_mkvp == mkvp) break; if (ci.hwtype >= minhwtype && - ci.old_mk_state == '2' && - ci.old_mkvp == mkvp && + ci.old_aes_mk_state == '2' && + ci.old_aes_mkvp == mkvp && oi < 0) oi = i; } @@ -1640,7 +1647,7 @@ } else rc = -ENODEV; - kfree(device_status); + kvfree(device_status); return rc; } @@ -1674,87 +1681,92 @@ EXPORT_SYMBOL(cca_findcard); int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, - int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify) + int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp, + int verify) { struct zcrypt_device_status_ext *device_status; - int i, n, card, dom, curmatch, oldmatch, rc = 0; + u32 *_apqns = NULL, _nr_apqns = 0; + int i, card, dom, curmatch, oldmatch, rc = 0; struct cca_info ci; - *apqns = NULL; - *nr_apqns = 0; - /* fetch status of all crypto cards */ - device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, - sizeof(struct zcrypt_device_status_ext), - GFP_KERNEL); + device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT, + sizeof(struct zcrypt_device_status_ext), + GFP_KERNEL); if (!device_status) return -ENOMEM; zcrypt_device_status_mask_ext(device_status); - /* loop two times: first gather eligible apqns, then store them */ - while (1) { - n = 0; - /* walk through all the crypto cards */ - for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { - card = AP_QID_CARD(device_status[i].qid); - dom = AP_QID_QUEUE(device_status[i].qid); - /* check online state */ - if (!device_status[i].online) - continue; - /* check for cca functions */ - if (!(device_status[i].functions & 0x04)) - continue; - /* check cardnr */ - if (cardnr != 0xFFFF && card != cardnr) - continue; - /* check domain */ - if (domain != 0xFFFF && dom != domain) - continue; - /* get cca info on this apqn */ - if (cca_get_info(card, dom, &ci, verify)) - continue; - /* current master key needs to be valid */ - if (ci.cur_mk_state != '2') - continue; - /* check min hardware type */ - if (minhwtype > 0 && minhwtype > ci.hwtype) - continue; - if (cur_mkvp || old_mkvp) { - /* check mkvps */ - curmatch = oldmatch = 0; - if (cur_mkvp && cur_mkvp == ci.cur_mkvp) + /* allocate 1k space for up to 256 apqns */ + _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL); + if (!_apqns) { + kvfree(device_status); + return -ENOMEM; + } + + /* walk through all the crypto apqnss */ + for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { + card = AP_QID_CARD(device_status[i].qid); + dom = AP_QID_QUEUE(device_status[i].qid); + /* check online state */ + if (!device_status[i].online) + continue; + /* check for cca functions */ + if (!(device_status[i].functions & 0x04)) + continue; + /* check cardnr */ + if (cardnr != 0xFFFF && card != cardnr) + continue; + /* check domain */ + if (domain != 0xFFFF && dom != domain) + continue; + /* get cca info on this apqn */ + if (cca_get_info(card, dom, &ci, verify)) + continue; + /* current master key needs to be valid */ + if (mktype == AES_MK_SET && ci.cur_aes_mk_state != '2') + continue; + if (mktype == APKA_MK_SET && ci.cur_apka_mk_state != '2') + continue; + /* check min hardware type */ + if (minhwtype > 0 && minhwtype > ci.hwtype) + continue; + if (cur_mkvp || old_mkvp) { + /* check mkvps */ + curmatch = oldmatch = 0; + if (mktype == AES_MK_SET) { + if (cur_mkvp && cur_mkvp == ci.cur_aes_mkvp) + curmatch = 1; + if (old_mkvp && ci.old_aes_mk_state == '2' && + old_mkvp == ci.old_aes_mkvp) + oldmatch = 1; + } else { + if (cur_mkvp && cur_mkvp == ci.cur_apka_mkvp) curmatch = 1; - if (old_mkvp && ci.old_mk_state == '2' && - old_mkvp == ci.old_mkvp) + if (old_mkvp && ci.old_apka_mk_state == '2' && + old_mkvp == ci.old_apka_mkvp) oldmatch = 1; - if ((cur_mkvp || old_mkvp) && - (curmatch + oldmatch < 1)) - continue; } - /* apqn passed all filtering criterons */ - if (*apqns && n < *nr_apqns) - (*apqns)[n] = (((u16)card) << 16) | ((u16) dom); - n++; - } - /* loop 2nd time: array has been filled */ - if (*apqns) - break; - /* loop 1st time: have # of eligible apqns in n */ - if (!n) { - rc = -ENODEV; /* no eligible apqns found */ - break; - } - *nr_apqns = n; - /* allocate array to store n apqns into */ - *apqns = kmalloc_array(n, sizeof(u32), GFP_KERNEL); - if (!*apqns) { - rc = -ENOMEM; - break; + if (curmatch + oldmatch < 1) + continue; } - verify = 0; + /* apqn passed all filtering criterons, add to the array */ + if (_nr_apqns < 256) + _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16) dom); + } + + /* nothing found ? */ + if (!_nr_apqns) { + kfree(_apqns); + rc = -ENODEV; + } else { + /* no re-allocation, simple return the _apqns array */ + *apqns = _apqns; + *nr_apqns = _nr_apqns; + rc = 0; } - kfree(device_status); + kvfree(device_status); return rc; } EXPORT_SYMBOL(cca_findcard2); --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_ccamisc.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_ccamisc.h @@ -19,6 +19,7 @@ /* For TOKTYPE_NON_CCA: */ #define TOKVER_PROTECTED_KEY 0x01 /* Protected key token */ +#define TOKVER_CLEAR_KEY 0x02 /* Clear key token */ /* For TOKTYPE_CCA_INTERNAL: */ #define TOKVER_CCA_AES 0x04 /* CCA AES key token */ @@ -89,7 +90,7 @@ u16 kmf1; /* key management field 1 */ u16 kmf2; /* key management field 2 */ u16 kmf3; /* key management field 3 */ - u8 vdata[0]; /* variable part data follows */ + u8 vdata[]; /* variable part data follows */ } __packed; /* Some defines for the CCA AES cipherkeytoken kmf1 field */ @@ -185,6 +186,8 @@ * - if verify is enabled and a cur_mkvp and/or old_mkvp * value is given, then refetch the cca_info and make sure the current * cur_mkvp or old_mkvp values of the apqn are used. + * The mktype determines which set of master keys to use: + * 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set * The array of apqn entries is allocated with kmalloc and returned in *apqns; * the number of apqns stored into the list is returned in *nr_apqns. One apqn * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and @@ -193,18 +196,28 @@ * -ENODEV is returned. */ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, - int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify); + int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp, + int verify); + +#define AES_MK_SET 0 +#define APKA_MK_SET 1 /* struct to hold info for each CCA queue */ struct cca_info { - int hwtype; /* one of the defined AP_DEVICE_TYPE_* */ - char new_mk_state; /* '1' empty, '2' partially full, '3' full */ - char cur_mk_state; /* '1' invalid, '2' valid */ - char old_mk_state; /* '1' invalid, '2' valid */ - u64 new_mkvp; /* truncated sha256 hash of new master key */ - u64 cur_mkvp; /* truncated sha256 hash of current master key */ - u64 old_mkvp; /* truncated sha256 hash of old master key */ - char serial[9]; /* serial number string (8 ascii numbers + 0x00) */ + int hwtype; /* one of the defined AP_DEVICE_TYPE_* */ + char new_aes_mk_state; /* '1' empty, '2' partially full, '3' full */ + char cur_aes_mk_state; /* '1' invalid, '2' valid */ + char old_aes_mk_state; /* '1' invalid, '2' valid */ + char new_apka_mk_state; /* '1' empty, '2' partially full, '3' full */ + char cur_apka_mk_state; /* '1' invalid, '2' valid */ + char old_apka_mk_state; /* '1' invalid, '2' valid */ + u64 new_aes_mkvp; /* truncated sha256 of new aes master key */ + u64 cur_aes_mkvp; /* truncated sha256 of current aes master key */ + u64 old_aes_mkvp; /* truncated sha256 of old aes master key */ + u64 new_apka_mkvp; /* truncated sha256 of new apka master key */ + u64 cur_apka_mkvp; /* truncated sha256 of current apka mk */ + u64 old_apka_mkvp; /* truncated sha256 of old apka mk */ + char serial[9]; /* serial number (8 ascii numbers + 0x00) */ }; /* --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_cex2a.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_cex2a.c @@ -94,8 +94,7 @@ if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) { zc->min_mod_size = CEX2A_MIN_MOD_SIZE; zc->max_mod_size = CEX2A_MAX_MOD_SIZE; - memcpy(zc->speed_rating, CEX2A_SPEED_IDX, - sizeof(CEX2A_SPEED_IDX)); + zc->speed_rating = CEX2A_SPEED_IDX; zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE; zc->type_string = "CEX2A"; zc->user_space_type = ZCRYPT_CEX2A; @@ -108,8 +107,7 @@ zc->max_mod_size = CEX3A_MAX_MOD_SIZE; zc->max_exp_bit_length = CEX3A_MAX_MOD_SIZE; } - memcpy(zc->speed_rating, CEX3A_SPEED_IDX, - sizeof(CEX3A_SPEED_IDX)); + zc->speed_rating = CEX3A_SPEED_IDX; zc->type_string = "CEX3A"; zc->user_space_type = ZCRYPT_CEX3A; } else { @@ -175,6 +173,7 @@ zq->queue = aq; zq->online = 1; atomic_set(&zq->load, 0); + ap_queue_init_state(aq); ap_queue_init_reply(aq, &zq->reply); aq->request_timeout = CEX2A_CLEANUP_TIME, aq->private = zq; @@ -203,8 +202,6 @@ static struct ap_driver zcrypt_cex2a_queue_driver = { .probe = zcrypt_cex2a_queue_probe, .remove = zcrypt_cex2a_queue_remove, - .suspend = ap_queue_suspend, - .resume = ap_queue_resume, .ids = zcrypt_cex2a_queue_ids, .flags = AP_DRIVER_FLAG_DEFAULT, }; --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_cex2c.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_cex2c.c @@ -25,6 +25,7 @@ #include "zcrypt_msgtype6.h" #include "zcrypt_cex2c.h" #include "zcrypt_cca_key.h" +#include "zcrypt_ccamisc.h" #define CEX2C_MIN_MOD_SIZE 16 /* 128 bits */ #define CEX2C_MAX_MOD_SIZE 256 /* 2048 bits */ @@ -58,6 +59,118 @@ MODULE_DEVICE_TABLE(ap, zcrypt_cex2c_queue_ids); +/* + * CCA card additional device attributes + */ +static ssize_t cca_serialnr_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct cca_info ci; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + + memset(&ci, 0, sizeof(ci)); + + if (ap_domain_index >= 0) + cca_get_info(ac->id, ap_domain_index, &ci, zc->online); + + return scnprintf(buf, PAGE_SIZE, "%s\n", ci.serial); +} + +static struct device_attribute dev_attr_cca_serialnr = + __ATTR(serialnr, 0444, cca_serialnr_show, NULL); + +static struct attribute *cca_card_attrs[] = { + &dev_attr_cca_serialnr.attr, + NULL, +}; + +static const struct attribute_group cca_card_attr_grp = { + .attrs = cca_card_attrs, +}; + + /* + * CCA queue additional device attributes + */ +static ssize_t cca_mkvps_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int n = 0; + struct cca_info ci; + struct zcrypt_queue *zq = to_ap_queue(dev)->private; + static const char * const cao_state[] = { "invalid", "valid" }; + static const char * const new_state[] = { "empty", "partial", "full" }; + + memset(&ci, 0, sizeof(ci)); + + cca_get_info(AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + &ci, zq->online); + + if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3') + n = scnprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n", + new_state[ci.new_aes_mk_state - '1'], + ci.new_aes_mkvp); + else + n = scnprintf(buf, PAGE_SIZE, "AES NEW: - -\n"); + + if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "AES CUR: %s 0x%016llx\n", + cao_state[ci.cur_aes_mk_state - '1'], + ci.cur_aes_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n"); + + if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "AES OLD: %s 0x%016llx\n", + cao_state[ci.old_aes_mk_state - '1'], + ci.old_aes_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n"); + + if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA NEW: %s 0x%016llx\n", + new_state[ci.new_apka_mk_state - '1'], + ci.new_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n"); + + if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA CUR: %s 0x%016llx\n", + cao_state[ci.cur_apka_mk_state - '1'], + ci.cur_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n"); + + if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA OLD: %s 0x%016llx\n", + cao_state[ci.old_apka_mk_state - '1'], + ci.old_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n"); + + return n; +} + +static struct device_attribute dev_attr_cca_mkvps = + __ATTR(mkvps, 0444, cca_mkvps_show, NULL); + +static struct attribute *cca_queue_attrs[] = { + &dev_attr_cca_mkvps.attr, + NULL, +}; + +static const struct attribute_group cca_queue_attr_grp = { + .attrs = cca_queue_attrs, +}; + /** * Large random number detection function. Its sends a message to a CEX2C/CEX3C * card to find out if large random numbers are supported. @@ -87,24 +200,23 @@ int rc, i; ap_init_message(&ap_msg); - ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); - if (!ap_msg.message) + ap_msg.msg = (void *) get_zeroed_page(GFP_KERNEL); + if (!ap_msg.msg) return -ENOMEM; rng_type6CPRB_msgX(&ap_msg, 4, &domain); - msg = ap_msg.message; + msg = ap_msg.msg; msg->cprbx.domain = AP_QID_QUEUE(aq->qid); - rc = ap_send(aq->qid, 0x0102030405060708ULL, ap_msg.message, - ap_msg.length); + rc = ap_send(aq->qid, 0x0102030405060708ULL, ap_msg.msg, ap_msg.len); if (rc) goto out_free; /* Wait for the test message to complete. */ for (i = 0; i < 2 * HZ; i++) { msleep(1000 / HZ); - rc = ap_recv(aq->qid, &psmid, ap_msg.message, 4096); + rc = ap_recv(aq->qid, &psmid, ap_msg.msg, 4096); if (rc == 0 && psmid == 0x0102030405060708ULL) break; } @@ -115,13 +227,13 @@ goto out_free; } - reply = ap_msg.message; + reply = ap_msg.msg; if (reply->cprbx.ccp_rtcode == 0 && reply->cprbx.ccp_rscode == 0) rc = 1; else rc = 0; out_free: - free_page((unsigned long) ap_msg.message); + free_page((unsigned long) ap_msg.msg); return rc; } @@ -154,8 +266,7 @@ case AP_DEVICE_TYPE_CEX2C: zc->user_space_type = ZCRYPT_CEX2C; zc->type_string = "CEX2C"; - memcpy(zc->speed_rating, CEX2C_SPEED_IDX, - sizeof(CEX2C_SPEED_IDX)); + zc->speed_rating = CEX2C_SPEED_IDX; zc->min_mod_size = CEX2C_MIN_MOD_SIZE; zc->max_mod_size = CEX2C_MAX_MOD_SIZE; zc->max_exp_bit_length = CEX2C_MAX_MOD_SIZE; @@ -163,8 +274,7 @@ case AP_DEVICE_TYPE_CEX3C: zc->user_space_type = ZCRYPT_CEX3C; zc->type_string = "CEX3C"; - memcpy(zc->speed_rating, CEX3C_SPEED_IDX, - sizeof(CEX3C_SPEED_IDX)); + zc->speed_rating = CEX3C_SPEED_IDX; zc->min_mod_size = CEX3C_MIN_MOD_SIZE; zc->max_mod_size = CEX3C_MAX_MOD_SIZE; zc->max_exp_bit_length = CEX3C_MAX_MOD_SIZE; @@ -179,6 +289,17 @@ if (rc) { ac->private = NULL; zcrypt_card_free(zc); + return rc; + } + + if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) { + rc = sysfs_create_group(&ap_dev->device.kobj, + &cca_card_attr_grp); + if (rc) { + zcrypt_card_unregister(zc); + ac->private = NULL; + zcrypt_card_free(zc); + } } return rc; @@ -190,8 +311,11 @@ */ static void zcrypt_cex2c_card_remove(struct ap_device *ap_dev) { + struct ap_card *ac = to_ap_card(&ap_dev->device); struct zcrypt_card *zc = to_ap_card(&ap_dev->device)->private; + if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) + sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp); if (zc) zcrypt_card_unregister(zc); } @@ -220,6 +344,7 @@ zq->queue = aq; zq->online = 1; atomic_set(&zq->load, 0); + ap_rapq(aq->qid); rc = zcrypt_cex2c_rng_supported(aq); if (rc < 0) { zcrypt_queue_free(zq); @@ -231,6 +356,7 @@ else zq->ops = zcrypt_msgtype(MSGTYPE06_NAME, MSGTYPE06_VARIANT_NORNG); + ap_queue_init_state(aq); ap_queue_init_reply(aq, &zq->reply); aq->request_timeout = CEX2C_CLEANUP_TIME; aq->private = zq; @@ -238,7 +364,19 @@ if (rc) { aq->private = NULL; zcrypt_queue_free(zq); + return rc; } + + if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { + rc = sysfs_create_group(&ap_dev->device.kobj, + &cca_queue_attr_grp); + if (rc) { + zcrypt_queue_unregister(zq); + aq->private = NULL; + zcrypt_queue_free(zq); + } + } + return rc; } @@ -251,6 +389,8 @@ struct ap_queue *aq = to_ap_queue(&ap_dev->device); struct zcrypt_queue *zq = aq->private; + if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) + sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp); if (zq) zcrypt_queue_unregister(zq); } @@ -258,8 +398,6 @@ static struct ap_driver zcrypt_cex2c_queue_driver = { .probe = zcrypt_cex2c_queue_probe, .remove = zcrypt_cex2c_queue_remove, - .suspend = ap_queue_suspend, - .resume = ap_queue_resume, .ids = zcrypt_cex2c_queue_ids, .flags = AP_DRIVER_FLAG_DEFAULT, }; --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_cex4.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_cex4.c @@ -19,6 +19,7 @@ #include "zcrypt_error.h" #include "zcrypt_cex4.h" #include "zcrypt_ccamisc.h" +#include "zcrypt_ep11misc.h" #define CEX4A_MIN_MOD_SIZE 1 /* 8 bits */ #define CEX4A_MAX_MOD_SIZE_2K 256 /* 2048 bits */ @@ -27,9 +28,6 @@ #define CEX4C_MIN_MOD_SIZE 16 /* 256 bits */ #define CEX4C_MAX_MOD_SIZE 512 /* 4096 bits */ -#define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE -#define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE - /* Waiting time for requests to be processed. * Currently there are some types of request which are not deterministic. * But the maximum time limit managed by the stomper code is set to 60sec. @@ -71,11 +69,11 @@ MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids); /* - * CCA card addditional device attributes + * CCA card additional device attributes */ -static ssize_t serialnr_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t cca_serialnr_show(struct device *dev, + struct device_attribute *attr, + char *buf) { struct cca_info ci; struct ap_card *ac = to_ap_card(dev); @@ -86,25 +84,27 @@ if (ap_domain_index >= 0) cca_get_info(ac->id, ap_domain_index, &ci, zc->online); - return snprintf(buf, PAGE_SIZE, "%s\n", ci.serial); + return scnprintf(buf, PAGE_SIZE, "%s\n", ci.serial); } -static DEVICE_ATTR_RO(serialnr); + +static struct device_attribute dev_attr_cca_serialnr = + __ATTR(serialnr, 0444, cca_serialnr_show, NULL); static struct attribute *cca_card_attrs[] = { - &dev_attr_serialnr.attr, + &dev_attr_cca_serialnr.attr, NULL, }; -static const struct attribute_group cca_card_attr_group = { +static const struct attribute_group cca_card_attr_grp = { .attrs = cca_card_attrs, }; -/* - * CCA queue addditional device attributes - */ -static ssize_t mkvps_show(struct device *dev, - struct device_attribute *attr, - char *buf) + /* + * CCA queue additional device attributes + */ +static ssize_t cca_mkvps_show(struct device *dev, + struct device_attribute *attr, + char *buf) { int n = 0; struct cca_info ci; @@ -118,37 +118,282 @@ AP_QID_QUEUE(zq->queue->qid), &ci, zq->online); - if (ci.new_mk_state >= '1' && ci.new_mk_state <= '3') - n = snprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n", - new_state[ci.new_mk_state - '1'], ci.new_mkvp); + if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3') + n = scnprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n", + new_state[ci.new_aes_mk_state - '1'], + ci.new_aes_mkvp); else - n = snprintf(buf, PAGE_SIZE, "AES NEW: - -\n"); + n = scnprintf(buf, PAGE_SIZE, "AES NEW: - -\n"); - if (ci.cur_mk_state >= '1' && ci.cur_mk_state <= '2') - n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: %s 0x%016llx\n", - cao_state[ci.cur_mk_state - '1'], ci.cur_mkvp); + if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "AES CUR: %s 0x%016llx\n", + cao_state[ci.cur_aes_mk_state - '1'], + ci.cur_aes_mkvp); else - n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n"); + n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n"); - if (ci.old_mk_state >= '1' && ci.old_mk_state <= '2') - n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: %s 0x%016llx\n", - cao_state[ci.old_mk_state - '1'], ci.old_mkvp); + if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "AES OLD: %s 0x%016llx\n", + cao_state[ci.old_aes_mk_state - '1'], + ci.old_aes_mkvp); else - n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n"); + n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n"); + + if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA NEW: %s 0x%016llx\n", + new_state[ci.new_apka_mk_state - '1'], + ci.new_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n"); + + if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA CUR: %s 0x%016llx\n", + cao_state[ci.cur_apka_mk_state - '1'], + ci.cur_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n"); + + if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2') + n += scnprintf(buf + n, PAGE_SIZE - n, + "APKA OLD: %s 0x%016llx\n", + cao_state[ci.old_apka_mk_state - '1'], + ci.old_apka_mkvp); + else + n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n"); return n; } -static DEVICE_ATTR_RO(mkvps); + +static struct device_attribute dev_attr_cca_mkvps = + __ATTR(mkvps, 0444, cca_mkvps_show, NULL); static struct attribute *cca_queue_attrs[] = { - &dev_attr_mkvps.attr, + &dev_attr_cca_mkvps.attr, NULL, }; -static const struct attribute_group cca_queue_attr_group = { +static const struct attribute_group cca_queue_attr_grp = { .attrs = cca_queue_attrs, }; +/* + * EP11 card additional device attributes + */ +static ssize_t ep11_api_ordinalnr_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ep11_card_info ci; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + + memset(&ci, 0, sizeof(ci)); + + ep11_get_card_info(ac->id, &ci, zc->online); + + if (ci.API_ord_nr > 0) + return scnprintf(buf, PAGE_SIZE, "%u\n", ci.API_ord_nr); + else + return scnprintf(buf, PAGE_SIZE, "\n"); +} + +static struct device_attribute dev_attr_ep11_api_ordinalnr = + __ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL); + +static ssize_t ep11_fw_version_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ep11_card_info ci; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + + memset(&ci, 0, sizeof(ci)); + + ep11_get_card_info(ac->id, &ci, zc->online); + + if (ci.FW_version > 0) + return scnprintf(buf, PAGE_SIZE, "%d.%d\n", + (int)(ci.FW_version >> 8), + (int)(ci.FW_version & 0xFF)); + else + return scnprintf(buf, PAGE_SIZE, "\n"); +} + +static struct device_attribute dev_attr_ep11_fw_version = + __ATTR(FW_version, 0444, ep11_fw_version_show, NULL); + +static ssize_t ep11_serialnr_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ep11_card_info ci; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + + memset(&ci, 0, sizeof(ci)); + + ep11_get_card_info(ac->id, &ci, zc->online); + + if (ci.serial[0]) + return scnprintf(buf, PAGE_SIZE, "%16.16s\n", ci.serial); + else + return scnprintf(buf, PAGE_SIZE, "\n"); +} + +static struct device_attribute dev_attr_ep11_serialnr = + __ATTR(serialnr, 0444, ep11_serialnr_show, NULL); + +static const struct { + int mode_bit; + const char *mode_txt; +} ep11_op_modes[] = { + { 0, "FIPS2009" }, + { 1, "BSI2009" }, + { 2, "FIPS2011" }, + { 3, "BSI2011" }, + { 6, "BSICC2017" }, + { 0, NULL } +}; + +static ssize_t ep11_card_op_modes_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i, n = 0; + struct ep11_card_info ci; + struct ap_card *ac = to_ap_card(dev); + struct zcrypt_card *zc = ac->private; + + memset(&ci, 0, sizeof(ci)); + + ep11_get_card_info(ac->id, &ci, zc->online); + + for (i = 0; ep11_op_modes[i].mode_txt; i++) { + if (ci.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) { + if (n > 0) + buf[n++] = ' '; + n += scnprintf(buf + n, PAGE_SIZE - n, + "%s", ep11_op_modes[i].mode_txt); + } + } + n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); + + return n; +} + +static struct device_attribute dev_attr_ep11_card_op_modes = + __ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL); + +static struct attribute *ep11_card_attrs[] = { + &dev_attr_ep11_api_ordinalnr.attr, + &dev_attr_ep11_fw_version.attr, + &dev_attr_ep11_serialnr.attr, + &dev_attr_ep11_card_op_modes.attr, + NULL, +}; + +static const struct attribute_group ep11_card_attr_grp = { + .attrs = ep11_card_attrs, +}; + +/* + * EP11 queue additional device attributes + */ + +static ssize_t ep11_mkvps_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int n = 0; + struct ep11_domain_info di; + struct zcrypt_queue *zq = to_ap_queue(dev)->private; + static const char * const cwk_state[] = { "invalid", "valid" }; + static const char * const nwk_state[] = { "empty", "uncommitted", + "committed" }; + + memset(&di, 0, sizeof(di)); + + if (zq->online) + ep11_get_domain_info(AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + &di); + + if (di.cur_wk_state == '0') { + n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s -\n", + cwk_state[di.cur_wk_state - '0']); + } else if (di.cur_wk_state == '1') { + n = scnprintf(buf, PAGE_SIZE, "WK CUR: %s 0x", + cwk_state[di.cur_wk_state - '0']); + bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp)); + n += 2 * sizeof(di.cur_wkvp); + n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); + } else + n = scnprintf(buf, PAGE_SIZE, "WK CUR: - -\n"); + + if (di.new_wk_state == '0') { + n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n", + nwk_state[di.new_wk_state - '0']); + } else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') { + n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s 0x", + nwk_state[di.new_wk_state - '0']); + bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp)); + n += 2 * sizeof(di.new_wkvp); + n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); + } else + n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n"); + + return n; +} + +static struct device_attribute dev_attr_ep11_mkvps = + __ATTR(mkvps, 0444, ep11_mkvps_show, NULL); + +static ssize_t ep11_queue_op_modes_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i, n = 0; + struct ep11_domain_info di; + struct zcrypt_queue *zq = to_ap_queue(dev)->private; + + memset(&di, 0, sizeof(di)); + + if (zq->online) + ep11_get_domain_info(AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + &di); + + for (i = 0; ep11_op_modes[i].mode_txt; i++) { + if (di.op_mode & (1ULL << ep11_op_modes[i].mode_bit)) { + if (n > 0) + buf[n++] = ' '; + n += scnprintf(buf + n, PAGE_SIZE - n, + "%s", ep11_op_modes[i].mode_txt); + } + } + n += scnprintf(buf + n, PAGE_SIZE - n, "\n"); + + return n; +} + +static struct device_attribute dev_attr_ep11_queue_op_modes = + __ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL); + +static struct attribute *ep11_queue_attrs[] = { + &dev_attr_ep11_mkvps.attr, + &dev_attr_ep11_queue_op_modes.attr, + NULL, +}; + +static const struct attribute_group ep11_queue_attr_grp = { + .attrs = ep11_queue_attrs, +}; + /** * Probe function for CEX4/CEX5/CEX6/CEX7 card device. It always * accepts the AP device since the bus_match already checked @@ -161,31 +406,31 @@ * Normalized speed ratings per crypto adapter * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY */ - static const int CEX4A_SPEED_IDX[] = { + static const int CEX4A_SPEED_IDX[NUM_OPS] = { 14, 19, 249, 42, 228, 1458, 0, 0}; - static const int CEX5A_SPEED_IDX[] = { + static const int CEX5A_SPEED_IDX[NUM_OPS] = { 8, 9, 20, 18, 66, 458, 0, 0}; - static const int CEX6A_SPEED_IDX[] = { + static const int CEX6A_SPEED_IDX[NUM_OPS] = { 6, 9, 20, 17, 65, 438, 0, 0}; - static const int CEX7A_SPEED_IDX[] = { + static const int CEX7A_SPEED_IDX[NUM_OPS] = { 6, 8, 17, 15, 54, 362, 0, 0}; - static const int CEX4C_SPEED_IDX[] = { + static const int CEX4C_SPEED_IDX[NUM_OPS] = { 59, 69, 308, 83, 278, 2204, 209, 40}; static const int CEX5C_SPEED_IDX[] = { 24, 31, 50, 37, 90, 479, 27, 10}; - static const int CEX6C_SPEED_IDX[] = { + static const int CEX6C_SPEED_IDX[NUM_OPS] = { 16, 20, 32, 27, 77, 455, 24, 9}; - static const int CEX7C_SPEED_IDX[] = { + static const int CEX7C_SPEED_IDX[NUM_OPS] = { 14, 16, 26, 23, 64, 376, 23, 8}; - static const int CEX4P_SPEED_IDX[] = { + static const int CEX4P_SPEED_IDX[NUM_OPS] = { 0, 0, 0, 0, 0, 0, 0, 50}; - static const int CEX5P_SPEED_IDX[] = { + static const int CEX5P_SPEED_IDX[NUM_OPS] = { 0, 0, 0, 0, 0, 0, 0, 10}; - static const int CEX6P_SPEED_IDX[] = { + static const int CEX6P_SPEED_IDX[NUM_OPS] = { 0, 0, 0, 0, 0, 0, 0, 9}; - static const int CEX7P_SPEED_IDX[] = { + static const int CEX7P_SPEED_IDX[NUM_OPS] = { 0, 0, 0, 0, 0, 0, 0, 8}; struct ap_card *ac = to_ap_card(&ap_dev->device); @@ -201,26 +446,22 @@ if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) { zc->type_string = "CEX4A"; zc->user_space_type = ZCRYPT_CEX4; - memcpy(zc->speed_rating, CEX4A_SPEED_IDX, - sizeof(CEX4A_SPEED_IDX)); + zc->speed_rating = CEX4A_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) { zc->type_string = "CEX5A"; zc->user_space_type = ZCRYPT_CEX5; - memcpy(zc->speed_rating, CEX5A_SPEED_IDX, - sizeof(CEX5A_SPEED_IDX)); + zc->speed_rating = CEX5A_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) { zc->type_string = "CEX6A"; zc->user_space_type = ZCRYPT_CEX6; - memcpy(zc->speed_rating, CEX6A_SPEED_IDX, - sizeof(CEX6A_SPEED_IDX)); + zc->speed_rating = CEX6A_SPEED_IDX; } else { zc->type_string = "CEX7A"; /* wrong user space type, just for compatibility * with the ZCRYPT_STATUS_MASK ioctl. */ zc->user_space_type = ZCRYPT_CEX6; - memcpy(zc->speed_rating, CEX7A_SPEED_IDX, - sizeof(CEX7A_SPEED_IDX)); + zc->speed_rating = CEX7A_SPEED_IDX; } zc->min_mod_size = CEX4A_MIN_MOD_SIZE; if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) && @@ -240,32 +481,28 @@ * just keep it for cca compatibility */ zc->user_space_type = ZCRYPT_CEX3C; - memcpy(zc->speed_rating, CEX4C_SPEED_IDX, - sizeof(CEX4C_SPEED_IDX)); + zc->speed_rating = CEX4C_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) { zc->type_string = "CEX5C"; /* wrong user space type, must be CEX5 * just keep it for cca compatibility */ zc->user_space_type = ZCRYPT_CEX3C; - memcpy(zc->speed_rating, CEX5C_SPEED_IDX, - sizeof(CEX5C_SPEED_IDX)); + zc->speed_rating = CEX5C_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) { zc->type_string = "CEX6C"; /* wrong user space type, must be CEX6 * just keep it for cca compatibility */ zc->user_space_type = ZCRYPT_CEX3C; - memcpy(zc->speed_rating, CEX6C_SPEED_IDX, - sizeof(CEX6C_SPEED_IDX)); + zc->speed_rating = CEX6C_SPEED_IDX; } else { zc->type_string = "CEX7C"; /* wrong user space type, must be CEX7 * just keep it for cca compatibility */ zc->user_space_type = ZCRYPT_CEX3C; - memcpy(zc->speed_rating, CEX7C_SPEED_IDX, - sizeof(CEX7C_SPEED_IDX)); + zc->speed_rating = CEX7C_SPEED_IDX; } zc->min_mod_size = CEX4C_MIN_MOD_SIZE; zc->max_mod_size = CEX4C_MAX_MOD_SIZE; @@ -274,26 +511,22 @@ if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX4) { zc->type_string = "CEX4P"; zc->user_space_type = ZCRYPT_CEX4; - memcpy(zc->speed_rating, CEX4P_SPEED_IDX, - sizeof(CEX4P_SPEED_IDX)); + zc->speed_rating = CEX4P_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX5) { zc->type_string = "CEX5P"; zc->user_space_type = ZCRYPT_CEX5; - memcpy(zc->speed_rating, CEX5P_SPEED_IDX, - sizeof(CEX5P_SPEED_IDX)); + zc->speed_rating = CEX5P_SPEED_IDX; } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX6) { zc->type_string = "CEX6P"; zc->user_space_type = ZCRYPT_CEX6; - memcpy(zc->speed_rating, CEX6P_SPEED_IDX, - sizeof(CEX6P_SPEED_IDX)); + zc->speed_rating = CEX6P_SPEED_IDX; } else { zc->type_string = "CEX7P"; /* wrong user space type, just for compatibility * with the ZCRYPT_STATUS_MASK ioctl. */ zc->user_space_type = ZCRYPT_CEX6; - memcpy(zc->speed_rating, CEX7P_SPEED_IDX, - sizeof(CEX7P_SPEED_IDX)); + zc->speed_rating = CEX7P_SPEED_IDX; } zc->min_mod_size = CEX4C_MIN_MOD_SIZE; zc->max_mod_size = CEX4C_MAX_MOD_SIZE; @@ -308,17 +541,27 @@ if (rc) { ac->private = NULL; zcrypt_card_free(zc); - goto out; + return rc; } if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) { rc = sysfs_create_group(&ap_dev->device.kobj, - &cca_card_attr_group); - if (rc) + &cca_card_attr_grp); + if (rc) { + zcrypt_card_unregister(zc); + ac->private = NULL; + zcrypt_card_free(zc); + } + } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) { + rc = sysfs_create_group(&ap_dev->device.kobj, + &ep11_card_attr_grp); + if (rc) { zcrypt_card_unregister(zc); + ac->private = NULL; + zcrypt_card_free(zc); + } } -out: return rc; } @@ -332,7 +575,9 @@ struct zcrypt_card *zc = ac->private; if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) - sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_group); + sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp); + else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) + sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp); if (zc) zcrypt_card_unregister(zc); } @@ -357,19 +602,19 @@ int rc; if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) { - zq = zcrypt_queue_alloc(CEX4A_MAX_MESSAGE_SIZE); + zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT); } else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { - zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE); + zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; zq->ops = zcrypt_msgtype(MSGTYPE06_NAME, MSGTYPE06_VARIANT_DEFAULT); } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) { - zq = zcrypt_queue_alloc(CEX4C_MAX_MESSAGE_SIZE); + zq = zcrypt_queue_alloc(aq->card->maxmsgsize); if (!zq) return -ENOMEM; zq->ops = zcrypt_msgtype(MSGTYPE06_NAME, @@ -381,6 +626,7 @@ zq->queue = aq; zq->online = 1; atomic_set(&zq->load, 0); + ap_queue_init_state(aq); ap_queue_init_reply(aq, &zq->reply); aq->request_timeout = CEX4_CLEANUP_TIME, aq->private = zq; @@ -388,17 +634,27 @@ if (rc) { aq->private = NULL; zcrypt_queue_free(zq); - goto out; + return rc; } if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { rc = sysfs_create_group(&ap_dev->device.kobj, - &cca_queue_attr_group); - if (rc) + &cca_queue_attr_grp); + if (rc) { + zcrypt_queue_unregister(zq); + aq->private = NULL; + zcrypt_queue_free(zq); + } + } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) { + rc = sysfs_create_group(&ap_dev->device.kobj, + &ep11_queue_attr_grp); + if (rc) { zcrypt_queue_unregister(zq); + aq->private = NULL; + zcrypt_queue_free(zq); + } } -out: return rc; } @@ -412,7 +668,9 @@ struct zcrypt_queue *zq = aq->private; if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) - sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_group); + sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp); + else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) + sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp); if (zq) zcrypt_queue_unregister(zq); } @@ -420,8 +678,6 @@ static struct ap_driver zcrypt_cex4_queue_driver = { .probe = zcrypt_cex4_queue_probe, .remove = zcrypt_cex4_queue_remove, - .suspend = ap_queue_suspend, - .resume = ap_queue_resume, .ids = zcrypt_cex4_queue_ids, .flags = AP_DRIVER_FLAG_DEFAULT, }; --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_debug.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_debug.h @@ -21,6 +21,14 @@ #define ZCRYPT_DBF(...) \ debug_sprintf_event(zcrypt_dbf_info, ##__VA_ARGS__) +#define ZCRYPT_DBF_ERR(...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_ERR, ##__VA_ARGS__) +#define ZCRYPT_DBF_WARN(...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_WARN, ##__VA_ARGS__) +#define ZCRYPT_DBF_INFO(...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_INFO, ##__VA_ARGS__) +#define ZCRYPT_DBF_DBG(...) \ + debug_sprintf_event(zcrypt_dbf_info, DBF_DEBUG, ##__VA_ARGS__) extern debug_info_t *zcrypt_dbf_info; --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_ep11misc.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_ep11misc.c @@ -0,0 +1,1274 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright IBM Corp. 2019 + * Author(s): Harald Freudenberger + * + * Collection of EP11 misc functions used by zcrypt and pkey + */ + +#define KMSG_COMPONENT "zcrypt" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include + +#include "ap_bus.h" +#include "zcrypt_api.h" +#include "zcrypt_debug.h" +#include "zcrypt_msgtype6.h" +#include "zcrypt_ep11misc.h" +#include "zcrypt_ccamisc.h" + +#define DEBUG_DBG(...) ZCRYPT_DBF(DBF_DEBUG, ##__VA_ARGS__) +#define DEBUG_INFO(...) ZCRYPT_DBF(DBF_INFO, ##__VA_ARGS__) +#define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__) +#define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__) + +/* default iv used here */ +static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + +/* ep11 card info cache */ +struct card_list_entry { + struct list_head list; + u16 cardnr; + struct ep11_card_info info; +}; +static LIST_HEAD(card_list); +static DEFINE_SPINLOCK(card_list_lock); + +static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci) +{ + int rc = -ENOENT; + struct card_list_entry *ptr; + + spin_lock_bh(&card_list_lock); + list_for_each_entry(ptr, &card_list, list) { + if (ptr->cardnr == cardnr) { + memcpy(ci, &ptr->info, sizeof(*ci)); + rc = 0; + break; + } + } + spin_unlock_bh(&card_list_lock); + + return rc; +} + +static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci) +{ + int found = 0; + struct card_list_entry *ptr; + + spin_lock_bh(&card_list_lock); + list_for_each_entry(ptr, &card_list, list) { + if (ptr->cardnr == cardnr) { + memcpy(&ptr->info, ci, sizeof(*ci)); + found = 1; + break; + } + } + if (!found) { + ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC); + if (!ptr) { + spin_unlock_bh(&card_list_lock); + return; + } + ptr->cardnr = cardnr; + memcpy(&ptr->info, ci, sizeof(*ci)); + list_add(&ptr->list, &card_list); + } + spin_unlock_bh(&card_list_lock); +} + +static void card_cache_scrub(u16 cardnr) +{ + struct card_list_entry *ptr; + + spin_lock_bh(&card_list_lock); + list_for_each_entry(ptr, &card_list, list) { + if (ptr->cardnr == cardnr) { + list_del(&ptr->list); + kfree(ptr); + break; + } + } + spin_unlock_bh(&card_list_lock); +} + +static void __exit card_cache_free(void) +{ + struct card_list_entry *ptr, *pnext; + + spin_lock_bh(&card_list_lock); + list_for_each_entry_safe(ptr, pnext, &card_list, list) { + list_del(&ptr->list); + kfree(ptr); + } + spin_unlock_bh(&card_list_lock); +} + +/* + * Simple check if the key blob is a valid EP11 secure AES key. + */ +int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl, + const u8 *key, int keybitsize, + int checkcpacfexport) +{ + struct ep11keyblob *kb = (struct ep11keyblob *) key; + +#define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) + + if (kb->head.type != TOKTYPE_NON_CCA) { + if (dbg) + DBF("%s key check failed, type 0x%02x != 0x%02x\n", + __func__, (int) kb->head.type, TOKTYPE_NON_CCA); + return -EINVAL; + } + if (kb->head.version != TOKVER_EP11_AES) { + if (dbg) + DBF("%s key check failed, version 0x%02x != 0x%02x\n", + __func__, (int) kb->head.version, TOKVER_EP11_AES); + return -EINVAL; + } + if (kb->version != EP11_STRUCT_MAGIC) { + if (dbg) + DBF("%s key check failed, magic 0x%04x != 0x%04x\n", + __func__, (int) kb->version, EP11_STRUCT_MAGIC); + return -EINVAL; + } + switch (kb->head.keybitlen) { + case 128: + case 192: + case 256: + break; + default: + if (dbg) + DBF("%s key check failed, keybitlen %d invalid\n", + __func__, (int) kb->head.keybitlen); + return -EINVAL; + } + if (keybitsize > 0 && keybitsize != (int) kb->head.keybitlen) { + DBF("%s key check failed, keybitsize %d\n", + __func__, keybitsize); + return -EINVAL; + } + if (checkcpacfexport && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) { + if (dbg) + DBF("%s key check failed, PKEY_EXTRACTABLE is 0\n", + __func__); + return -EINVAL; + } +#undef DBF + + return 0; +} +EXPORT_SYMBOL(ep11_check_aeskeyblob); + +/* + * Allocate and prepare ep11 cprb plus additional payload. + */ +static inline struct ep11_cprb *alloc_cprb(size_t payload_len) +{ + size_t len = sizeof(struct ep11_cprb) + payload_len; + struct ep11_cprb *cprb; + + cprb = kzalloc(len, GFP_KERNEL); + if (!cprb) + return NULL; + + cprb->cprb_len = sizeof(struct ep11_cprb); + cprb->cprb_ver_id = 0x04; + memcpy(cprb->func_id, "T4", 2); + cprb->ret_code = 0xFFFFFFFF; + cprb->payload_len = payload_len; + + return cprb; +} + +/* + * Some helper functions related to ASN1 encoding. + * Limited to length info <= 2 byte. + */ + +#define ASN1TAGLEN(x) (2 + (x) + ((x) > 127 ? 1 : 0) + ((x) > 255 ? 1 : 0)) + +static int asn1tag_write(u8 *ptr, u8 tag, const u8 *pvalue, u16 valuelen) +{ + ptr[0] = tag; + if (valuelen > 255) { + ptr[1] = 0x82; + *((u16 *)(ptr + 2)) = valuelen; + memcpy(ptr + 4, pvalue, valuelen); + return 4 + valuelen; + } + if (valuelen > 127) { + ptr[1] = 0x81; + ptr[2] = (u8) valuelen; + memcpy(ptr + 3, pvalue, valuelen); + return 3 + valuelen; + } + ptr[1] = (u8) valuelen; + memcpy(ptr + 2, pvalue, valuelen); + return 2 + valuelen; +} + +/* EP11 payload > 127 bytes starts with this struct */ +struct pl_head { + u8 tag; + u8 lenfmt; + u16 len; + u8 func_tag; + u8 func_len; + u32 func; + u8 dom_tag; + u8 dom_len; + u32 dom; +} __packed; + +/* prep ep11 payload head helper function */ +static inline void prep_head(struct pl_head *h, + size_t pl_size, int api, int func) +{ + h->tag = 0x30; + h->lenfmt = 0x82; + h->len = pl_size - 4; + h->func_tag = 0x04; + h->func_len = sizeof(u32); + h->func = (api << 16) + func; + h->dom_tag = 0x04; + h->dom_len = sizeof(u32); +} + +/* prep urb helper function */ +static inline void prep_urb(struct ep11_urb *u, + struct ep11_target_dev *t, int nt, + struct ep11_cprb *req, size_t req_len, + struct ep11_cprb *rep, size_t rep_len) +{ + u->targets = (u8 __user *) t; + u->targets_num = nt; + u->req = (u8 __user *) req; + u->req_len = req_len; + u->resp = (u8 __user *) rep; + u->resp_len = rep_len; +} + +/* Check ep11 reply payload, return 0 or suggested errno value. */ +static int check_reply_pl(const u8 *pl, const char *func) +{ + int len; + u32 ret; + + /* start tag */ + if (*pl++ != 0x30) { + DEBUG_ERR("%s reply start tag mismatch\n", func); + return -EIO; + } + + /* payload length format */ + if (*pl < 127) { + len = *pl; + pl++; + } else if (*pl == 0x81) { + pl++; + len = *pl; + pl++; + } else if (*pl == 0x82) { + pl++; + len = *((u16 *)pl); + pl += 2; + } else { + DEBUG_ERR("%s reply start tag lenfmt mismatch 0x%02hhx\n", + func, *pl); + return -EIO; + } + + /* len should cover at least 3 fields with 32 bit value each */ + if (len < 3 * 6) { + DEBUG_ERR("%s reply length %d too small\n", func, len); + return -EIO; + } + + /* function tag, length and value */ + if (pl[0] != 0x04 || pl[1] != 0x04) { + DEBUG_ERR("%s function tag or length mismatch\n", func); + return -EIO; + } + pl += 6; + + /* dom tag, length and value */ + if (pl[0] != 0x04 || pl[1] != 0x04) { + DEBUG_ERR("%s dom tag or length mismatch\n", func); + return -EIO; + } + pl += 6; + + /* return value tag, length and value */ + if (pl[0] != 0x04 || pl[1] != 0x04) { + DEBUG_ERR("%s return value tag or length mismatch\n", func); + return -EIO; + } + pl += 2; + ret = *((u32 *)pl); + if (ret != 0) { + DEBUG_ERR("%s return value 0x%04x != 0\n", func, ret); + return -EIO; + } + + return 0; +} + + +/* + * Helper function which does an ep11 query with given query type. + */ +static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type, + size_t buflen, u8 *buf) +{ + struct ep11_info_req_pl { + struct pl_head head; + u8 query_type_tag; + u8 query_type_len; + u32 query_type; + u8 query_subtype_tag; + u8 query_subtype_len; + u32 query_subtype; + } __packed * req_pl; + struct ep11_info_rep_pl { + struct pl_head head; + u8 rc_tag; + u8 rc_len; + u32 rc; + u8 data_tag; + u8 data_lenfmt; + u16 data_len; + } __packed * rep_pl; + struct ep11_cprb *req = NULL, *rep = NULL; + struct ep11_target_dev target; + struct ep11_urb *urb = NULL; + int api = 1, rc = -ENOMEM; + + /* request cprb and payload */ + req = alloc_cprb(sizeof(struct ep11_info_req_pl)); + if (!req) + goto out; + req_pl = (struct ep11_info_req_pl *) (((u8 *) req) + sizeof(*req)); + prep_head(&req_pl->head, sizeof(*req_pl), api, 38); /* get xcp info */ + req_pl->query_type_tag = 0x04; + req_pl->query_type_len = sizeof(u32); + req_pl->query_type = query_type; + req_pl->query_subtype_tag = 0x04; + req_pl->query_subtype_len = sizeof(u32); + + /* reply cprb and payload */ + rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen); + if (!rep) + goto out; + rep_pl = (struct ep11_info_rep_pl *) (((u8 *) rep) + sizeof(*rep)); + + /* urb and target */ + urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL); + if (!urb) + goto out; + target.ap_id = cardnr; + target.dom_id = domain; + prep_urb(urb, &target, 1, + req, sizeof(*req) + sizeof(*req_pl), + rep, sizeof(*rep) + sizeof(*rep_pl) + buflen); + + rc = zcrypt_send_ep11_cprb(urb); + if (rc) { + DEBUG_ERR( + "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", + __func__, (int) cardnr, (int) domain, rc); + goto out; + } + + rc = check_reply_pl((u8 *)rep_pl, __func__); + if (rc) + goto out; + if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) { + DEBUG_ERR("%s unknown reply data format\n", __func__); + rc = -EIO; + goto out; + } + if (rep_pl->data_len > buflen) { + DEBUG_ERR("%s mismatch between reply data len and buffer len\n", + __func__); + rc = -ENOSPC; + goto out; + } + + memcpy(buf, ((u8 *) rep_pl) + sizeof(*rep_pl), rep_pl->data_len); + +out: + kfree(req); + kfree(rep); + kfree(urb); + return rc; +} + +/* + * Provide information about an EP11 card. + */ +int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify) +{ + int rc; + struct ep11_module_query_info { + u32 API_ord_nr; + u32 firmware_id; + u8 FW_major_vers; + u8 FW_minor_vers; + u8 CSP_major_vers; + u8 CSP_minor_vers; + u8 fwid[32]; + u8 xcp_config_hash[32]; + u8 CSP_config_hash[32]; + u8 serial[16]; + u8 module_date_time[16]; + u64 op_mode; + u32 PKCS11_flags; + u32 ext_flags; + u32 domains; + u32 sym_state_bytes; + u32 digest_state_bytes; + u32 pin_blob_bytes; + u32 SPKI_bytes; + u32 priv_key_blob_bytes; + u32 sym_blob_bytes; + u32 max_payload_bytes; + u32 CP_profile_bytes; + u32 max_CP_index; + } __packed * pmqi = NULL; + + rc = card_cache_fetch(card, info); + if (rc || verify) { + pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL); + if (!pmqi) + return -ENOMEM; + rc = ep11_query_info(card, AUTOSEL_DOM, + 0x01 /* module info query */, + sizeof(*pmqi), (u8 *) pmqi); + if (rc) { + if (rc == -ENODEV) + card_cache_scrub(card); + goto out; + } + memset(info, 0, sizeof(*info)); + info->API_ord_nr = pmqi->API_ord_nr; + info->FW_version = + (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers; + memcpy(info->serial, pmqi->serial, sizeof(info->serial)); + info->op_mode = pmqi->op_mode; + card_cache_update(card, info); + } + +out: + kfree(pmqi); + return rc; +} +EXPORT_SYMBOL(ep11_get_card_info); + +/* + * Provide information about a domain within an EP11 card. + */ +int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info) +{ + int rc; + struct ep11_domain_query_info { + u32 dom_index; + u8 cur_WK_VP[32]; + u8 new_WK_VP[32]; + u32 dom_flags; + u64 op_mode; + } __packed * p_dom_info; + + p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL); + if (!p_dom_info) + return -ENOMEM; + + rc = ep11_query_info(card, domain, 0x03 /* domain info query */, + sizeof(*p_dom_info), (u8 *) p_dom_info); + if (rc) + goto out; + + memset(info, 0, sizeof(*info)); + info->cur_wk_state = '0'; + info->new_wk_state = '0'; + if (p_dom_info->dom_flags & 0x10 /* left imprint mode */) { + if (p_dom_info->dom_flags & 0x02 /* cur wk valid */) { + info->cur_wk_state = '1'; + memcpy(info->cur_wkvp, p_dom_info->cur_WK_VP, 32); + } + if (p_dom_info->dom_flags & 0x04 /* new wk present */ + || p_dom_info->dom_flags & 0x08 /* new wk committed */) { + info->new_wk_state = + p_dom_info->dom_flags & 0x08 ? '2' : '1'; + memcpy(info->new_wkvp, p_dom_info->new_WK_VP, 32); + } + } + info->op_mode = p_dom_info->op_mode; + +out: + kfree(p_dom_info); + return rc; +} +EXPORT_SYMBOL(ep11_get_domain_info); + +/* + * Default EP11 AES key generate attributes, used when no keygenflags given: + * XCP_BLOB_ENCRYPT | XCP_BLOB_DECRYPT | XCP_BLOB_PROTKEY_EXTRACTABLE + */ +#define KEY_ATTR_DEFAULTS 0x00200c00 + +int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize) +{ + struct keygen_req_pl { + struct pl_head head; + u8 var_tag; + u8 var_len; + u32 var; + u8 keybytes_tag; + u8 keybytes_len; + u32 keybytes; + u8 mech_tag; + u8 mech_len; + u32 mech; + u8 attr_tag; + u8 attr_len; + u32 attr_header; + u32 attr_bool_mask; + u32 attr_bool_bits; + u32 attr_val_len_type; + u32 attr_val_len_value; + u8 pin_tag; + u8 pin_len; + } __packed * req_pl; + struct keygen_rep_pl { + struct pl_head head; + u8 rc_tag; + u8 rc_len; + u32 rc; + u8 data_tag; + u8 data_lenfmt; + u16 data_len; + u8 data[512]; + } __packed * rep_pl; + struct ep11_cprb *req = NULL, *rep = NULL; + struct ep11_target_dev target; + struct ep11_urb *urb = NULL; + struct ep11keyblob *kb; + int api, rc = -ENOMEM; + + switch (keybitsize) { + case 128: + case 192: + case 256: + break; + default: + DEBUG_ERR( + "%s unknown/unsupported keybitsize %d\n", + __func__, keybitsize); + rc = -EINVAL; + goto out; + } + + /* request cprb and payload */ + req = alloc_cprb(sizeof(struct keygen_req_pl)); + if (!req) + goto out; + req_pl = (struct keygen_req_pl *) (((u8 *) req) + sizeof(*req)); + api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1; + prep_head(&req_pl->head, sizeof(*req_pl), api, 21); /* GenerateKey */ + req_pl->var_tag = 0x04; + req_pl->var_len = sizeof(u32); + req_pl->keybytes_tag = 0x04; + req_pl->keybytes_len = sizeof(u32); + req_pl->keybytes = keybitsize / 8; + req_pl->mech_tag = 0x04; + req_pl->mech_len = sizeof(u32); + req_pl->mech = 0x00001080; /* CKM_AES_KEY_GEN */ + req_pl->attr_tag = 0x04; + req_pl->attr_len = 5 * sizeof(u32); + req_pl->attr_header = 0x10010000; + req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS; + req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS; + req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */ + req_pl->attr_val_len_value = keybitsize / 8; + req_pl->pin_tag = 0x04; + + /* reply cprb and payload */ + rep = alloc_cprb(sizeof(struct keygen_rep_pl)); + if (!rep) + goto out; + rep_pl = (struct keygen_rep_pl *) (((u8 *) rep) + sizeof(*rep)); + + /* urb and target */ + urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL); + if (!urb) + goto out; + target.ap_id = card; + target.dom_id = domain; + prep_urb(urb, &target, 1, + req, sizeof(*req) + sizeof(*req_pl), + rep, sizeof(*rep) + sizeof(*rep_pl)); + + rc = zcrypt_send_ep11_cprb(urb); + if (rc) { + DEBUG_ERR( + "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", + __func__, (int) card, (int) domain, rc); + goto out; + } + + rc = check_reply_pl((u8 *)rep_pl, __func__); + if (rc) + goto out; + if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) { + DEBUG_ERR("%s unknown reply data format\n", __func__); + rc = -EIO; + goto out; + } + if (rep_pl->data_len > *keybufsize) { + DEBUG_ERR("%s mismatch reply data len / key buffer len\n", + __func__); + rc = -ENOSPC; + goto out; + } + + /* copy key blob and set header values */ + memcpy(keybuf, rep_pl->data, rep_pl->data_len); + *keybufsize = rep_pl->data_len; + kb = (struct ep11keyblob *) keybuf; + kb->head.type = TOKTYPE_NON_CCA; + kb->head.len = rep_pl->data_len; + kb->head.version = TOKVER_EP11_AES; + kb->head.keybitlen = keybitsize; + +out: + kfree(req); + kfree(rep); + kfree(urb); + return rc; +} +EXPORT_SYMBOL(ep11_genaeskey); + +static int ep11_cryptsingle(u16 card, u16 domain, + u16 mode, u32 mech, const u8 *iv, + const u8 *key, size_t keysize, + const u8 *inbuf, size_t inbufsize, + u8 *outbuf, size_t *outbufsize) +{ + struct crypt_req_pl { + struct pl_head head; + u8 var_tag; + u8 var_len; + u32 var; + u8 mech_tag; + u8 mech_len; + u32 mech; + /* + * maybe followed by iv data + * followed by key tag + key blob + * followed by plaintext tag + plaintext + */ + } __packed * req_pl; + struct crypt_rep_pl { + struct pl_head head; + u8 rc_tag; + u8 rc_len; + u32 rc; + u8 data_tag; + u8 data_lenfmt; + /* data follows */ + } __packed * rep_pl; + struct ep11_cprb *req = NULL, *rep = NULL; + struct ep11_target_dev target; + struct ep11_urb *urb = NULL; + size_t req_pl_size, rep_pl_size; + int n, api = 1, rc = -ENOMEM; + u8 *p; + + /* the simple asn1 coding used has length limits */ + if (keysize > 0xFFFF || inbufsize > 0xFFFF) + return -EINVAL; + + /* request cprb and payload */ + req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0) + + ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize); + req = alloc_cprb(req_pl_size); + if (!req) + goto out; + req_pl = (struct crypt_req_pl *) (((u8 *) req) + sizeof(*req)); + prep_head(&req_pl->head, req_pl_size, api, (mode ? 20 : 19)); + req_pl->var_tag = 0x04; + req_pl->var_len = sizeof(u32); + /* mech is mech + mech params (iv here) */ + req_pl->mech_tag = 0x04; + req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0); + req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */ + p = ((u8 *) req_pl) + sizeof(*req_pl); + if (iv) { + memcpy(p, iv, 16); + p += 16; + } + /* key and input data */ + p += asn1tag_write(p, 0x04, key, keysize); + p += asn1tag_write(p, 0x04, inbuf, inbufsize); + + /* reply cprb and payload, assume out data size <= in data size + 32 */ + rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32); + rep = alloc_cprb(rep_pl_size); + if (!rep) + goto out; + rep_pl = (struct crypt_rep_pl *) (((u8 *) rep) + sizeof(*rep)); + + /* urb and target */ + urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL); + if (!urb) + goto out; + target.ap_id = card; + target.dom_id = domain; + prep_urb(urb, &target, 1, + req, sizeof(*req) + req_pl_size, + rep, sizeof(*rep) + rep_pl_size); + + rc = zcrypt_send_ep11_cprb(urb); + if (rc) { + DEBUG_ERR( + "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", + __func__, (int) card, (int) domain, rc); + goto out; + } + + rc = check_reply_pl((u8 *)rep_pl, __func__); + if (rc) + goto out; + if (rep_pl->data_tag != 0x04) { + DEBUG_ERR("%s unknown reply data format\n", __func__); + rc = -EIO; + goto out; + } + p = ((u8 *) rep_pl) + sizeof(*rep_pl); + if (rep_pl->data_lenfmt <= 127) + n = rep_pl->data_lenfmt; + else if (rep_pl->data_lenfmt == 0x81) + n = *p++; + else if (rep_pl->data_lenfmt == 0x82) { + n = *((u16 *) p); + p += 2; + } else { + DEBUG_ERR("%s unknown reply data length format 0x%02hhx\n", + __func__, rep_pl->data_lenfmt); + rc = -EIO; + goto out; + } + if (n > *outbufsize) { + DEBUG_ERR("%s mismatch reply data len %d / output buffer %zu\n", + __func__, n, *outbufsize); + rc = -ENOSPC; + goto out; + } + + memcpy(outbuf, p, n); + *outbufsize = n; + +out: + kfree(req); + kfree(rep); + kfree(urb); + return rc; +} + +static int ep11_unwrapkey(u16 card, u16 domain, + const u8 *kek, size_t keksize, + const u8 *enckey, size_t enckeysize, + u32 mech, const u8 *iv, + u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize) +{ + struct uw_req_pl { + struct pl_head head; + u8 attr_tag; + u8 attr_len; + u32 attr_header; + u32 attr_bool_mask; + u32 attr_bool_bits; + u32 attr_key_type; + u32 attr_key_type_value; + u32 attr_val_len; + u32 attr_val_len_value; + u8 mech_tag; + u8 mech_len; + u32 mech; + /* + * maybe followed by iv data + * followed by kek tag + kek blob + * followed by empty mac tag + * followed by empty pin tag + * followed by encryted key tag + bytes + */ + } __packed * req_pl; + struct uw_rep_pl { + struct pl_head head; + u8 rc_tag; + u8 rc_len; + u32 rc; + u8 data_tag; + u8 data_lenfmt; + u16 data_len; + u8 data[512]; + } __packed * rep_pl; + struct ep11_cprb *req = NULL, *rep = NULL; + struct ep11_target_dev target; + struct ep11_urb *urb = NULL; + struct ep11keyblob *kb; + size_t req_pl_size; + int api, rc = -ENOMEM; + u8 *p; + + /* request cprb and payload */ + req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0) + + ASN1TAGLEN(keksize) + 4 + ASN1TAGLEN(enckeysize); + req = alloc_cprb(req_pl_size); + if (!req) + goto out; + req_pl = (struct uw_req_pl *) (((u8 *) req) + sizeof(*req)); + api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1; + prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */ + req_pl->attr_tag = 0x04; + req_pl->attr_len = 7 * sizeof(u32); + req_pl->attr_header = 0x10020000; + req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS; + req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS; + req_pl->attr_key_type = 0x00000100; /* CKA_KEY_TYPE */ + req_pl->attr_key_type_value = 0x0000001f; /* CKK_AES */ + req_pl->attr_val_len = 0x00000161; /* CKA_VALUE_LEN */ + req_pl->attr_val_len_value = keybitsize / 8; + /* mech is mech + mech params (iv here) */ + req_pl->mech_tag = 0x04; + req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0); + req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */ + p = ((u8 *) req_pl) + sizeof(*req_pl); + if (iv) { + memcpy(p, iv, 16); + p += 16; + } + /* kek */ + p += asn1tag_write(p, 0x04, kek, keksize); + /* empty mac key tag */ + *p++ = 0x04; + *p++ = 0; + /* empty pin tag */ + *p++ = 0x04; + *p++ = 0; + /* encrytped key value tag and bytes */ + p += asn1tag_write(p, 0x04, enckey, enckeysize); + + /* reply cprb and payload */ + rep = alloc_cprb(sizeof(struct uw_rep_pl)); + if (!rep) + goto out; + rep_pl = (struct uw_rep_pl *) (((u8 *) rep) + sizeof(*rep)); + + /* urb and target */ + urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL); + if (!urb) + goto out; + target.ap_id = card; + target.dom_id = domain; + prep_urb(urb, &target, 1, + req, sizeof(*req) + req_pl_size, + rep, sizeof(*rep) + sizeof(*rep_pl)); + + rc = zcrypt_send_ep11_cprb(urb); + if (rc) { + DEBUG_ERR( + "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", + __func__, (int) card, (int) domain, rc); + goto out; + } + + rc = check_reply_pl((u8 *)rep_pl, __func__); + if (rc) + goto out; + if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) { + DEBUG_ERR("%s unknown reply data format\n", __func__); + rc = -EIO; + goto out; + } + if (rep_pl->data_len > *keybufsize) { + DEBUG_ERR("%s mismatch reply data len / key buffer len\n", + __func__); + rc = -ENOSPC; + goto out; + } + + /* copy key blob and set header values */ + memcpy(keybuf, rep_pl->data, rep_pl->data_len); + *keybufsize = rep_pl->data_len; + kb = (struct ep11keyblob *) keybuf; + kb->head.type = TOKTYPE_NON_CCA; + kb->head.len = rep_pl->data_len; + kb->head.version = TOKVER_EP11_AES; + kb->head.keybitlen = keybitsize; + +out: + kfree(req); + kfree(rep); + kfree(urb); + return rc; +} + +static int ep11_wrapkey(u16 card, u16 domain, + const u8 *key, size_t keysize, + u32 mech, const u8 *iv, + u8 *databuf, size_t *datasize) +{ + struct wk_req_pl { + struct pl_head head; + u8 var_tag; + u8 var_len; + u32 var; + u8 mech_tag; + u8 mech_len; + u32 mech; + /* + * followed by iv data + * followed by key tag + key blob + * followed by dummy kek param + * followed by dummy mac param + */ + } __packed * req_pl; + struct wk_rep_pl { + struct pl_head head; + u8 rc_tag; + u8 rc_len; + u32 rc; + u8 data_tag; + u8 data_lenfmt; + u16 data_len; + u8 data[512]; + } __packed * rep_pl; + struct ep11_cprb *req = NULL, *rep = NULL; + struct ep11_target_dev target; + struct ep11_urb *urb = NULL; + struct ep11keyblob *kb; + size_t req_pl_size; + int api, rc = -ENOMEM; + u8 *p; + + /* request cprb and payload */ + req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0) + + ASN1TAGLEN(keysize) + 4; + req = alloc_cprb(req_pl_size); + if (!req) + goto out; + if (!mech || mech == 0x80060001) + req->flags |= 0x20; /* CPACF_WRAP needs special bit */ + req_pl = (struct wk_req_pl *) (((u8 *) req) + sizeof(*req)); + api = (!mech || mech == 0x80060001) ? 4 : 1; /* CKM_IBM_CPACF_WRAP */ + prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */ + req_pl->var_tag = 0x04; + req_pl->var_len = sizeof(u32); + /* mech is mech + mech params (iv here) */ + req_pl->mech_tag = 0x04; + req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0); + req_pl->mech = (mech ? mech : 0x80060001); /* CKM_IBM_CPACF_WRAP */ + p = ((u8 *) req_pl) + sizeof(*req_pl); + if (iv) { + memcpy(p, iv, 16); + p += 16; + } + /* key blob */ + p += asn1tag_write(p, 0x04, key, keysize); + /* maybe the key argument needs the head data cleaned out */ + kb = (struct ep11keyblob *)(p - keysize); + if (kb->head.version == TOKVER_EP11_AES) + memset(&kb->head, 0, sizeof(kb->head)); + /* empty kek tag */ + *p++ = 0x04; + *p++ = 0; + /* empty mac tag */ + *p++ = 0x04; + *p++ = 0; + + /* reply cprb and payload */ + rep = alloc_cprb(sizeof(struct wk_rep_pl)); + if (!rep) + goto out; + rep_pl = (struct wk_rep_pl *) (((u8 *) rep) + sizeof(*rep)); + + /* urb and target */ + urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL); + if (!urb) + goto out; + target.ap_id = card; + target.dom_id = domain; + prep_urb(urb, &target, 1, + req, sizeof(*req) + req_pl_size, + rep, sizeof(*rep) + sizeof(*rep_pl)); + + rc = zcrypt_send_ep11_cprb(urb); + if (rc) { + DEBUG_ERR( + "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n", + __func__, (int) card, (int) domain, rc); + goto out; + } + + rc = check_reply_pl((u8 *)rep_pl, __func__); + if (rc) + goto out; + if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) { + DEBUG_ERR("%s unknown reply data format\n", __func__); + rc = -EIO; + goto out; + } + if (rep_pl->data_len > *datasize) { + DEBUG_ERR("%s mismatch reply data len / data buffer len\n", + __func__); + rc = -ENOSPC; + goto out; + } + + /* copy the data from the cprb to the data buffer */ + memcpy(databuf, rep_pl->data, rep_pl->data_len); + *datasize = rep_pl->data_len; + +out: + kfree(req); + kfree(rep); + kfree(urb); + return rc; +} + +int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, + const u8 *clrkey, u8 *keybuf, size_t *keybufsize) +{ + int rc; + struct ep11keyblob *kb; + u8 encbuf[64], *kek = NULL; + size_t clrkeylen, keklen, encbuflen = sizeof(encbuf); + + if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256) + clrkeylen = keybitsize / 8; + else { + DEBUG_ERR( + "%s unknown/unsupported keybitsize %d\n", + __func__, keybitsize); + return -EINVAL; + } + + /* allocate memory for the temp kek */ + keklen = MAXEP11AESKEYBLOBSIZE; + kek = kmalloc(keklen, GFP_ATOMIC); + if (!kek) { + rc = -ENOMEM; + goto out; + } + + /* Step 1: generate AES 256 bit random kek key */ + rc = ep11_genaeskey(card, domain, 256, + 0x00006c00, /* EN/DECRYTP, WRAP/UNWRAP */ + kek, &keklen); + if (rc) { + DEBUG_ERR( + "%s generate kek key failed, rc=%d\n", + __func__, rc); + goto out; + } + kb = (struct ep11keyblob *) kek; + memset(&kb->head, 0, sizeof(kb->head)); + + /* Step 2: encrypt clear key value with the kek key */ + rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen, + clrkey, clrkeylen, encbuf, &encbuflen); + if (rc) { + DEBUG_ERR( + "%s encrypting key value with kek key failed, rc=%d\n", + __func__, rc); + goto out; + } + + /* Step 3: import the encrypted key value as a new key */ + rc = ep11_unwrapkey(card, domain, kek, keklen, + encbuf, encbuflen, 0, def_iv, + keybitsize, 0, keybuf, keybufsize); + if (rc) { + DEBUG_ERR( + "%s importing key value as new key failed,, rc=%d\n", + __func__, rc); + goto out; + } + +out: + kfree(kek); + return rc; +} +EXPORT_SYMBOL(ep11_clr2keyblob); + +int ep11_key2protkey(u16 card, u16 dom, const u8 *key, size_t keylen, + u8 *protkey, u32 *protkeylen, u32 *protkeytype) +{ + int rc = -EIO; + u8 *wkbuf = NULL; + size_t wkbuflen = 256; + struct wk_info { + u16 version; + u8 res1[16]; + u32 pkeytype; + u32 pkeybitsize; + u64 pkeysize; + u8 res2[8]; + u8 pkey[0]; + } __packed * wki; + + /* alloc temp working buffer */ + wkbuf = kmalloc(wkbuflen, GFP_ATOMIC); + if (!wkbuf) + return -ENOMEM; + + /* ep11 secure key -> protected key + info */ + rc = ep11_wrapkey(card, dom, key, keylen, + 0, def_iv, wkbuf, &wkbuflen); + if (rc) { + DEBUG_ERR( + "%s rewrapping ep11 key to pkey failed, rc=%d\n", + __func__, rc); + goto out; + } + wki = (struct wk_info *) wkbuf; + + /* check struct version and pkey type */ + if (wki->version != 1 || wki->pkeytype != 1) { + DEBUG_ERR("%s wk info version %d or pkeytype %d mismatch.\n", + __func__, (int) wki->version, (int) wki->pkeytype); + rc = -EIO; + goto out; + } + + /* copy the tanslated protected key */ + switch (wki->pkeysize) { + case 16+32: + /* AES 128 protected key */ + if (protkeytype) + *protkeytype = PKEY_KEYTYPE_AES_128; + break; + case 24+32: + /* AES 192 protected key */ + if (protkeytype) + *protkeytype = PKEY_KEYTYPE_AES_192; + break; + case 32+32: + /* AES 256 protected key */ + if (protkeytype) + *protkeytype = PKEY_KEYTYPE_AES_256; + break; + default: + DEBUG_ERR("%s unknown/unsupported pkeysize %d\n", + __func__, (int) wki->pkeysize); + rc = -EIO; + goto out; + } + memcpy(protkey, wki->pkey, wki->pkeysize); + if (protkeylen) + *protkeylen = (u32) wki->pkeysize; + rc = 0; + +out: + kfree(wkbuf); + return rc; +} +EXPORT_SYMBOL(ep11_key2protkey); + +int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, + int minhwtype, int minapi, const u8 *wkvp) +{ + struct zcrypt_device_status_ext *device_status; + u32 *_apqns = NULL, _nr_apqns = 0; + int i, card, dom, rc = -ENOMEM; + struct ep11_domain_info edi; + struct ep11_card_info eci; + + /* fetch status of all crypto cards */ + device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT, + sizeof(struct zcrypt_device_status_ext), + GFP_KERNEL); + if (!device_status) + return -ENOMEM; + zcrypt_device_status_mask_ext(device_status); + + /* allocate 1k space for up to 256 apqns */ + _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL); + if (!_apqns) { + kvfree(device_status); + return -ENOMEM; + } + + /* walk through all the crypto apqnss */ + for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { + card = AP_QID_CARD(device_status[i].qid); + dom = AP_QID_QUEUE(device_status[i].qid); + /* check online state */ + if (!device_status[i].online) + continue; + /* check for ep11 functions */ + if (!(device_status[i].functions & 0x01)) + continue; + /* check cardnr */ + if (cardnr != 0xFFFF && card != cardnr) + continue; + /* check domain */ + if (domain != 0xFFFF && dom != domain) + continue; + /* check min hardware type */ + if (minhwtype && device_status[i].hwtype < minhwtype) + continue; + /* check min api version if given */ + if (minapi > 0) { + if (ep11_get_card_info(card, &eci, 0)) + continue; + if (minapi > eci.API_ord_nr) + continue; + } + /* check wkvp if given */ + if (wkvp) { + if (ep11_get_domain_info(card, dom, &edi)) + continue; + if (edi.cur_wk_state != '1') + continue; + if (memcmp(wkvp, edi.cur_wkvp, 16)) + continue; + } + /* apqn passed all filtering criterons, add to the array */ + if (_nr_apqns < 256) + _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16) dom); + } + + /* nothing found ? */ + if (!_nr_apqns) { + kfree(_apqns); + rc = -ENODEV; + } else { + /* no re-allocation, simple return the _apqns array */ + *apqns = _apqns; + *nr_apqns = _nr_apqns; + rc = 0; + } + + kvfree(device_status); + return rc; +} +EXPORT_SYMBOL(ep11_findcard2); + +void __exit zcrypt_ep11misc_exit(void) +{ + card_cache_free(); +} --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_ep11misc.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_ep11misc.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright IBM Corp. 2019 + * Author(s): Harald Freudenberger + * + * Collection of EP11 misc functions used by zcrypt and pkey + */ + +#ifndef _ZCRYPT_EP11MISC_H_ +#define _ZCRYPT_EP11MISC_H_ + +#include +#include + +#define TOKVER_EP11_AES 0x03 /* EP11 AES key blob */ + +#define EP11_API_V 4 /* highest known and supported EP11 API version */ + +#define EP11_STRUCT_MAGIC 0x1234 +#define EP11_BLOB_PKEY_EXTRACTABLE 0x200000 + +/* inside view of an EP11 secure key blob */ +struct ep11keyblob { + union { + u8 session[32]; + struct { + u8 type; /* 0x00 (TOKTYPE_NON_CCA) */ + u8 res0; /* unused */ + u16 len; /* total length in bytes of this blob */ + u8 version; /* 0x06 (TOKVER_EP11_AES) */ + u8 res1; /* unused */ + u16 keybitlen; /* clear key bit len, 0 for unknown */ + } head; + }; + u8 wkvp[16]; /* wrapping key verification pattern */ + u64 attr; /* boolean key attributes */ + u64 mode; /* mode bits */ + u16 version; /* 0x1234, EP11_STRUCT_MAGIC */ + u8 iv[14]; + u8 encrypted_key_data[144]; + u8 mac[32]; +} __packed; + +/* + * Simple check if the key blob is a valid EP11 secure AES key. + * If keybitsize is given, the bitsize of the key is also checked. + * If checkcpacfexport is enabled, the key is also checked for the + * attributes needed to export this key for CPACF use. + * Returns 0 on success or errno value on failure. + */ +int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl, + const u8 *key, int keybitsize, + int checkcpacfexport); + +/* EP11 card info struct */ +struct ep11_card_info { + u32 API_ord_nr; /* API ordinal number */ + u16 FW_version; /* Firmware major and minor version */ + char serial[16]; /* serial number string (16 ascii, no 0x00 !) */ + u64 op_mode; /* card operational mode(s) */ +}; + +/* EP11 domain info struct */ +struct ep11_domain_info { + char cur_wk_state; /* '0' invalid, '1' valid */ + char new_wk_state; /* '0' empty, '1' uncommitted, '2' committed */ + u8 cur_wkvp[32]; /* current wrapping key verification pattern */ + u8 new_wkvp[32]; /* new wrapping key verification pattern */ + u64 op_mode; /* domain operational mode(s) */ +}; + +/* + * Provide information about an EP11 card. + */ +int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify); + +/* + * Provide information about a domain within an EP11 card. + */ +int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info); + +/* + * Generate (random) EP11 AES secure key. + */ +int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize); + +/* + * Generate EP11 AES secure key with given clear key value. + */ +int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, + const u8 *clrkey, u8 *keybuf, size_t *keybufsize); + +/* + * Derive proteced key from EP11 AES secure key blob. + */ +int ep11_key2protkey(u16 cardnr, u16 domain, const u8 *key, size_t keylen, + u8 *protkey, u32 *protkeylen, u32 *protkeytype); + +/* + * Build a list of ep11 apqns meeting the following constrains: + * - apqn is online and is in fact an EP11 apqn + * - if cardnr is not FFFF only apqns with this cardnr + * - if domain is not FFFF only apqns with this domainnr + * - if minhwtype > 0 only apqns with hwtype >= minhwtype + * - if minapi > 0 only apqns with API_ord_nr >= minapi + * - if wkvp != NULL only apqns where the wkvp (EP11_WKVPLEN bytes) matches + * to the first EP11_WKVPLEN bytes of the wkvp of the current wrapping + * key for this domain. When a wkvp is given there will aways be a re-fetch + * of the domain info for the potential apqn - so this triggers an request + * reply to each apqn eligible. + * The array of apqn entries is allocated with kmalloc and returned in *apqns; + * the number of apqns stored into the list is returned in *nr_apqns. One apqn + * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and + * may be casted to struct pkey_apqn. The return value is either 0 for success + * or a negative errno value. If no apqn meeting the criterias is found, + * -ENODEV is returned. + */ +int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, + int minhwtype, int minapi, const u8 *wkvp); + +void zcrypt_ep11misc_exit(void); + +#endif /* _ZCRYPT_EP11MISC_H_ */ --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_error.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_error.h @@ -52,7 +52,6 @@ #define REP82_ERROR_INVALID_COMMAND 0x30 #define REP82_ERROR_MALFORMED_MSG 0x40 #define REP82_ERROR_INVALID_SPECIAL_CMD 0x41 -#define REP82_ERROR_INVALID_DOMAIN_PRECHECK 0x42 #define REP82_ERROR_RESERVED_FIELDO 0x50 /* old value */ #define REP82_ERROR_WORD_ALIGNMENT 0x60 #define REP82_ERROR_MESSAGE_LENGTH 0x80 @@ -61,12 +60,12 @@ #define REP82_ERROR_EVEN_MOD_IN_OPND 0x85 #define REP82_ERROR_RESERVED_FIELD 0x88 #define REP82_ERROR_INVALID_DOMAIN_PENDING 0x8A +#define REP82_ERROR_FILTERED_BY_HYPERVISOR 0x8B #define REP82_ERROR_TRANSPORT_FAIL 0x90 #define REP82_ERROR_PACKET_TRUNCATED 0xA0 #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 #define REP88_ERROR_MODULE_FAILURE 0x10 - #define REP88_ERROR_MESSAGE_TYPE 0x20 #define REP88_ERROR_MESSAGE_MALFORMD 0x22 #define REP88_ERROR_MESSAGE_LENGTH 0x23 @@ -79,82 +78,61 @@ static inline int convert_error(struct zcrypt_queue *zq, struct ap_message *reply) { - struct error_hdr *ehdr = reply->message; + struct error_hdr *ehdr = reply->msg; int card = AP_QID_CARD(zq->queue->qid); int queue = AP_QID_QUEUE(zq->queue->qid); switch (ehdr->reply_code) { - case REP82_ERROR_OPERAND_INVALID: - case REP82_ERROR_OPERAND_SIZE: - case REP82_ERROR_EVEN_MOD_IN_OPND: - case REP88_ERROR_MESSAGE_MALFORMD: - case REP82_ERROR_INVALID_DOMAIN_PRECHECK: - case REP82_ERROR_INVALID_DOMAIN_PENDING: - case REP82_ERROR_INVALID_SPECIAL_CMD: - // REP88_ERROR_INVALID_KEY // '82' CEX2A - // REP88_ERROR_OPERAND // '84' CEX2A - // REP88_ERROR_OPERAND_EVEN_MOD // '85' CEX2A - /* Invalid input data. */ + case REP82_ERROR_INVALID_MSG_LEN: /* 0x23 */ + case REP82_ERROR_RESERVD_FIELD: /* 0x24 */ + case REP82_ERROR_FORMAT_FIELD: /* 0x29 */ + case REP82_ERROR_MALFORMED_MSG: /* 0x40 */ + case REP82_ERROR_INVALID_SPECIAL_CMD: /* 0x41 */ + case REP82_ERROR_MESSAGE_LENGTH: /* 0x80 */ + case REP82_ERROR_OPERAND_INVALID: /* 0x82 */ + case REP82_ERROR_OPERAND_SIZE: /* 0x84 */ + case REP82_ERROR_EVEN_MOD_IN_OPND: /* 0x85 */ + case REP82_ERROR_INVALID_DOMAIN_PENDING: /* 0x8A */ + case REP82_ERROR_FILTERED_BY_HYPERVISOR: /* 0x8B */ + case REP82_ERROR_PACKET_TRUNCATED: /* 0xA0 */ + case REP88_ERROR_MESSAGE_MALFORMD: /* 0x22 */ + case REP88_ERROR_KEY_TYPE: /* 0x34 */ + /* RY indicates malformed request */ ZCRYPT_DBF(DBF_WARN, - "device=%02x.%04x reply=0x%02x => rc=EINVAL\n", + "dev=%02x.%04x RY=0x%02x => rc=EINVAL\n", card, queue, ehdr->reply_code); return -EINVAL; - case REP82_ERROR_MESSAGE_TYPE: - // REP88_ERROR_MESSAGE_TYPE // '20' CEX2A + case REP82_ERROR_MACHINE_FAILURE: /* 0x10 */ + case REP82_ERROR_MESSAGE_TYPE: /* 0x20 */ + case REP82_ERROR_TRANSPORT_FAIL: /* 0x90 */ /* - * To sent a message of the wrong type is a bug in the - * device driver. Send error msg, disable the device - * and then repeat the request. + * Msg to wrong type or card/infrastructure failure. + * Trigger rescan of the ap bus, trigger retry request. */ atomic_set(&zcrypt_rescan_req, 1); - zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", - card, queue); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", - card, queue, ehdr->reply_code); - return -EAGAIN; - case REP82_ERROR_TRANSPORT_FAIL: - /* Card or infrastructure failure, disable card */ - atomic_set(&zcrypt_rescan_req, 1); - zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", - card, queue); /* For type 86 response show the apfs value (failure reason) */ - if (ehdr->type == TYPE86_RSP_CODE) { + if (ehdr->reply_code == REP82_ERROR_TRANSPORT_FAIL && + ehdr->type == TYPE86_RSP_CODE) { struct { struct type86_hdr hdr; struct type86_fmt2_ext fmt2; - } __packed * head = reply->message; + } __packed * head = reply->msg; unsigned int apfs = *((u32 *)head->fmt2.apfs); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x reply=0x%02x apfs=0x%x => online=0 rc=EAGAIN\n", - card, queue, apfs, ehdr->reply_code); + ZCRYPT_DBF(DBF_WARN, + "dev=%02x.%04x RY=0x%02x apfs=0x%x => bus rescan, rc=EAGAIN\n", + card, queue, ehdr->reply_code, apfs); } else - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", + ZCRYPT_DBF(DBF_WARN, + "dev=%02x.%04x RY=0x%02x => bus rescan, rc=EAGAIN\n", card, queue, ehdr->reply_code); return -EAGAIN; - case REP82_ERROR_MACHINE_FAILURE: - // REP88_ERROR_MODULE_FAILURE // '10' CEX2A - /* If a card fails disable it and repeat the request. */ - atomic_set(&zcrypt_rescan_req, 1); - zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", - card, queue); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", - card, queue, ehdr->reply_code); - return -EAGAIN; default: - zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", - card, queue); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", + /* Assume request is valid and a retry will be worth it */ + ZCRYPT_DBF(DBF_WARN, + "dev=%02x.%04x RY=0x%02x => rc=EAGAIN\n", card, queue, ehdr->reply_code); - return -EAGAIN; /* repeat the request on a different device. */ + return -EAGAIN; } } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_msgtype50.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_msgtype50.c @@ -207,10 +207,10 @@ mod_len = mex->inputdatalength; if (mod_len <= 128) { - struct type50_meb1_msg *meb1 = ap_msg->message; + struct type50_meb1_msg *meb1 = ap_msg->msg; memset(meb1, 0, sizeof(*meb1)); - ap_msg->length = sizeof(*meb1); + ap_msg->len = sizeof(*meb1); meb1->header.msg_type_code = TYPE50_TYPE_CODE; meb1->header.msg_len = sizeof(*meb1); meb1->keyblock_type = TYPE50_MEB1_FMT; @@ -218,10 +218,10 @@ exp = meb1->exponent + sizeof(meb1->exponent) - mod_len; inp = meb1->message + sizeof(meb1->message) - mod_len; } else if (mod_len <= 256) { - struct type50_meb2_msg *meb2 = ap_msg->message; + struct type50_meb2_msg *meb2 = ap_msg->msg; memset(meb2, 0, sizeof(*meb2)); - ap_msg->length = sizeof(*meb2); + ap_msg->len = sizeof(*meb2); meb2->header.msg_type_code = TYPE50_TYPE_CODE; meb2->header.msg_len = sizeof(*meb2); meb2->keyblock_type = TYPE50_MEB2_FMT; @@ -229,10 +229,10 @@ exp = meb2->exponent + sizeof(meb2->exponent) - mod_len; inp = meb2->message + sizeof(meb2->message) - mod_len; } else if (mod_len <= 512) { - struct type50_meb3_msg *meb3 = ap_msg->message; + struct type50_meb3_msg *meb3 = ap_msg->msg; memset(meb3, 0, sizeof(*meb3)); - ap_msg->length = sizeof(*meb3); + ap_msg->len = sizeof(*meb3); meb3->header.msg_type_code = TYPE50_TYPE_CODE; meb3->header.msg_len = sizeof(*meb3); meb3->keyblock_type = TYPE50_MEB3_FMT; @@ -246,6 +246,12 @@ copy_from_user(exp, mex->b_key, mod_len) || copy_from_user(inp, mex->inputdata, mod_len)) return -EFAULT; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) + ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; +#endif + return 0; } @@ -275,10 +281,10 @@ * 512 byte modulus (4k keys). */ if (mod_len <= 128) { /* up to 1024 bit key size */ - struct type50_crb1_msg *crb1 = ap_msg->message; + struct type50_crb1_msg *crb1 = ap_msg->msg; memset(crb1, 0, sizeof(*crb1)); - ap_msg->length = sizeof(*crb1); + ap_msg->len = sizeof(*crb1); crb1->header.msg_type_code = TYPE50_TYPE_CODE; crb1->header.msg_len = sizeof(*crb1); crb1->keyblock_type = TYPE50_CRB1_FMT; @@ -289,10 +295,10 @@ u = crb1->u + sizeof(crb1->u) - short_len; inp = crb1->message + sizeof(crb1->message) - mod_len; } else if (mod_len <= 256) { /* up to 2048 bit key size */ - struct type50_crb2_msg *crb2 = ap_msg->message; + struct type50_crb2_msg *crb2 = ap_msg->msg; memset(crb2, 0, sizeof(*crb2)); - ap_msg->length = sizeof(*crb2); + ap_msg->len = sizeof(*crb2); crb2->header.msg_type_code = TYPE50_TYPE_CODE; crb2->header.msg_len = sizeof(*crb2); crb2->keyblock_type = TYPE50_CRB2_FMT; @@ -304,10 +310,10 @@ inp = crb2->message + sizeof(crb2->message) - mod_len; } else if ((mod_len <= 512) && /* up to 4096 bit key size */ (zq->zcard->max_mod_size == CEX3A_MAX_MOD_SIZE)) { - struct type50_crb3_msg *crb3 = ap_msg->message; + struct type50_crb3_msg *crb3 = ap_msg->msg; memset(crb3, 0, sizeof(*crb3)); - ap_msg->length = sizeof(*crb3); + ap_msg->len = sizeof(*crb3); crb3->header.msg_type_code = TYPE50_TYPE_CODE; crb3->header.msg_len = sizeof(*crb3); crb3->keyblock_type = TYPE50_CRB3_FMT; @@ -332,6 +338,11 @@ copy_from_user(inp, crt->inputdata, mod_len)) return -EFAULT; +#ifdef CONFIG_ZCRYPT_DEBUG + if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) + ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; +#endif + return 0; } @@ -350,39 +361,39 @@ char __user *outputdata, unsigned int outputdatalength) { - struct type80_hdr *t80h = reply->message; + struct type80_hdr *t80h = reply->msg; unsigned char *data; if (t80h->len < sizeof(*t80h) + outputdatalength) { /* The result is too short, the CEXxA card may not do that.. */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x code=0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x code=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - t80h->code); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + t80h->code); + ZCRYPT_DBF_ERR("dev=%02x.%04x code=0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + t80h->code); + return -EAGAIN; } if (zq->zcard->user_space_type == ZCRYPT_CEX2A) BUG_ON(t80h->len > CEX2A_MAX_RESPONSE_SIZE); else BUG_ON(t80h->len > CEX3A_MAX_RESPONSE_SIZE); - data = reply->message + t80h->len - outputdatalength; + data = reply->msg + t80h->len - outputdatalength; if (copy_to_user(outputdata, data, outputdatalength)) return -EFAULT; return 0; } -static int convert_response(struct zcrypt_queue *zq, - struct ap_message *reply, - char __user *outputdata, - unsigned int outputdatalength) +static int convert_response_cex2a(struct zcrypt_queue *zq, + struct ap_message *reply, + char __user *outputdata, + unsigned int outputdatalength) { /* Response type byte is the second byte in the response. */ - unsigned char rtype = ((unsigned char *) reply->message)[1]; + unsigned char rtype = ((unsigned char *) reply->msg)[1]; switch (rtype) { case TYPE82_RSP_CODE: @@ -393,15 +404,15 @@ outputdata, outputdatalength); default: /* Unknown response type, this should NEVER EVER happen */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (unsigned int) rtype); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) rtype); + ZCRYPT_DBF_ERR("dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) rtype); + return -EAGAIN; } } @@ -422,22 +433,22 @@ .reply_code = REP82_ERROR_MACHINE_FAILURE, }; struct type80_hdr *t80h; - int length; + int len; /* Copy the reply message to the request message buffer. */ if (!reply) goto out; /* ap_msg->rc indicates the error */ - t80h = reply->message; + t80h = reply->msg; if (t80h->type == TYPE80_RSP_CODE) { - if (aq->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) - length = min_t(int, - CEX2A_MAX_RESPONSE_SIZE, t80h->len); - else - length = min_t(int, - CEX3A_MAX_RESPONSE_SIZE, t80h->len); - memcpy(msg->message, reply->message, length); + len = t80h->len; + if (len > reply->bufsize || len > msg->bufsize) { + msg->rc = -EMSGSIZE; + } else { + memcpy(msg->msg, reply->msg, len); + msg->len = len; + } } else - memcpy(msg->message, reply->message, sizeof(error_reply)); + memcpy(msg->msg, reply->msg, sizeof(error_reply)); out: complete((struct completion *) msg->private); } @@ -452,41 +463,40 @@ * @mex: pointer to the modexpo request buffer */ static long zcrypt_cex2a_modexpo(struct zcrypt_queue *zq, - struct ica_rsa_modexpo *mex) + struct ica_rsa_modexpo *mex, + struct ap_message *ap_msg) { - struct ap_message ap_msg; struct completion work; int rc; - ap_init_message(&ap_msg); - if (zq->zcard->user_space_type == ZCRYPT_CEX2A) - ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, - GFP_KERNEL); - else - ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, - GFP_KERNEL); - if (!ap_msg.message) + ap_msg->bufsize = (zq->zcard->user_space_type == ZCRYPT_CEX2A) ? + MSGTYPE50_CRB2_MAX_MSG_SIZE : MSGTYPE50_CRB3_MAX_MSG_SIZE; + ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; - ap_msg.receive = zcrypt_cex2a_receive; - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + - atomic_inc_return(&zcrypt_step); - ap_msg.private = &work; - rc = ICAMEX_msg_to_type50MEX_msg(zq, &ap_msg, mex); + ap_msg->receive = zcrypt_cex2a_receive; + ap_msg->psmid = (((unsigned long long) current->pid) << 32) + + atomic_inc_return(&zcrypt_step); + ap_msg->private = &work; + rc = ICAMEX_msg_to_type50MEX_msg(zq, ap_msg, mex); if (rc) - goto out_free; + goto out; init_completion(&work); - ap_queue_message(zq->queue, &ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out; rc = wait_for_completion_interruptible(&work); if (rc == 0) { - rc = ap_msg.rc; + rc = ap_msg->rc; if (rc == 0) - rc = convert_response(zq, &ap_msg, mex->outputdata, - mex->outputdatalength); + rc = convert_response_cex2a(zq, ap_msg, + mex->outputdata, + mex->outputdatalength); } else /* Signal pending. */ - ap_cancel_message(zq->queue, &ap_msg); -out_free: - kfree(ap_msg.message); + ap_cancel_message(zq->queue, ap_msg); +out: + ap_msg->private = NULL; return rc; } @@ -498,41 +508,40 @@ * @crt: pointer to the modexpoc_crt request buffer */ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_queue *zq, - struct ica_rsa_modexpo_crt *crt) + struct ica_rsa_modexpo_crt *crt, + struct ap_message *ap_msg) { - struct ap_message ap_msg; struct completion work; int rc; - ap_init_message(&ap_msg); - if (zq->zcard->user_space_type == ZCRYPT_CEX2A) - ap_msg.message = kmalloc(MSGTYPE50_CRB2_MAX_MSG_SIZE, - GFP_KERNEL); - else - ap_msg.message = kmalloc(MSGTYPE50_CRB3_MAX_MSG_SIZE, - GFP_KERNEL); - if (!ap_msg.message) + ap_msg->bufsize = (zq->zcard->user_space_type == ZCRYPT_CEX2A) ? + MSGTYPE50_CRB2_MAX_MSG_SIZE : MSGTYPE50_CRB3_MAX_MSG_SIZE; + ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; - ap_msg.receive = zcrypt_cex2a_receive; - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + - atomic_inc_return(&zcrypt_step); - ap_msg.private = &work; - rc = ICACRT_msg_to_type50CRT_msg(zq, &ap_msg, crt); + ap_msg->receive = zcrypt_cex2a_receive; + ap_msg->psmid = (((unsigned long long) current->pid) << 32) + + atomic_inc_return(&zcrypt_step); + ap_msg->private = &work; + rc = ICACRT_msg_to_type50CRT_msg(zq, ap_msg, crt); if (rc) - goto out_free; + goto out; init_completion(&work); - ap_queue_message(zq->queue, &ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out; rc = wait_for_completion_interruptible(&work); if (rc == 0) { - rc = ap_msg.rc; + rc = ap_msg->rc; if (rc == 0) - rc = convert_response(zq, &ap_msg, crt->outputdata, - crt->outputdatalength); + rc = convert_response_cex2a(zq, ap_msg, + crt->outputdata, + crt->outputdatalength); } else /* Signal pending. */ - ap_cancel_message(zq->queue, &ap_msg); -out_free: - kfree(ap_msg.message); + ap_cancel_message(zq->queue, ap_msg); +out: + ap_msg->private = NULL; return rc; } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_msgtype6.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_msgtype6.c @@ -266,7 +266,7 @@ struct function_and_rules_block fr; unsigned short length; char text[0]; - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; int size; /* @@ -301,7 +301,7 @@ msg->cprbx.req_parml = size - sizeof(msg->hdr) - sizeof(msg->cprbx); - ap_msg->length = size; + ap_msg->len = size; return 0; } @@ -336,7 +336,7 @@ struct function_and_rules_block fr; unsigned short length; char text[0]; - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; int size; /* @@ -370,7 +370,7 @@ msg->fr = static_pkd_fnr; - ap_msg->length = size; + ap_msg->len = size; return 0; } @@ -388,7 +388,7 @@ struct type86_fmt2_ext fmt2; } __packed; -static int XCRB_msg_to_type6CPRB_msgX(struct ap_message *ap_msg, +static int XCRB_msg_to_type6CPRB_msgX(bool userspace, struct ap_message *ap_msg, struct ica_xcRB *xcRB, unsigned int *fcode, unsigned short **dom) @@ -400,11 +400,11 @@ struct { struct type6_hdr hdr; struct CPRBX cprbx; - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; int rcblen = CEIL4(xcRB->request_control_blk_length); - int replylen, req_sumlen, resp_sumlen; - char *req_data = ap_msg->message + sizeof(struct type6_hdr) + rcblen; + int req_sumlen, resp_sumlen; + char *req_data = ap_msg->msg + sizeof(struct type6_hdr) + rcblen; char *function_code; if (CEIL4(xcRB->request_control_blk_length) < @@ -412,10 +412,10 @@ return -EINVAL; /* overflow after alignment*/ /* length checks */ - ap_msg->length = sizeof(struct type6_hdr) + + ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcRB->request_control_blk_length) + xcRB->request_data_length; - if (ap_msg->length > MSGTYPE06_MAX_MSG_SIZE) + if (ap_msg->len > ap_msg->bufsize) return -EINVAL; /* @@ -435,12 +435,6 @@ xcRB->reply_control_blk_length) return -EINVAL; /* overflow after alignment*/ - replylen = sizeof(struct type86_fmt2_msg) + - CEIL4(xcRB->reply_control_blk_length) + - xcRB->reply_data_length; - if (replylen > MSGTYPE06_MAX_MSG_SIZE) - return -EINVAL; - /* * Overflow check * sum must be greater (or equal) than the largest operand @@ -465,8 +459,8 @@ msg->hdr.FromCardLen2 = xcRB->reply_data_length; /* prepare CPRB */ - if (copy_from_user(&(msg->cprbx), xcRB->request_control_blk_addr, - xcRB->request_control_blk_length)) + if (z_copy_from_user(userspace, &(msg->cprbx), xcRB->request_control_blk_addr, + xcRB->request_control_blk_length)) return -EFAULT; if (msg->cprbx.cprb_len + sizeof(msg->hdr.function_code) > xcRB->request_control_blk_length) @@ -480,22 +474,25 @@ if (memcmp(function_code, "US", 2) == 0 || memcmp(function_code, "AU", 2) == 0) - ap_msg->special = 1; - else - ap_msg->special = 0; + ap_msg->flags |= AP_MSG_FLAG_SPECIAL; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) + ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; +#endif /* copy data block */ if (xcRB->request_data_length && - copy_from_user(req_data, xcRB->request_data_address, - xcRB->request_data_length)) + z_copy_from_user(userspace, req_data, xcRB->request_data_address, + xcRB->request_data_length)) return -EFAULT; return 0; } -static int xcrb_msg_to_type6_ep11cprb_msgx(struct ap_message *ap_msg, - struct ep11_urb *xcRB, - unsigned int *fcode) +static int xcrb_msg_to_type6_ep11cprb_msgx(bool userspace, struct ap_message *ap_msg, + struct ep11_urb *xcRB, + unsigned int *fcode) { unsigned int lfmt; static struct type6_hdr static_type6_ep11_hdr = { @@ -512,7 +509,7 @@ struct ep11_cprb cprbx; unsigned char pld_tag; /* fixed value 0x30 */ unsigned char pld_lenfmt; /* payload length format */ - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; struct pld_hdr { unsigned char func_tag; /* fixed value 0x4 */ @@ -527,26 +524,21 @@ return -EINVAL; /* overflow after alignment*/ /* length checks */ - ap_msg->length = sizeof(struct type6_hdr) + xcRB->req_len; - if (CEIL4(xcRB->req_len) > MSGTYPE06_MAX_MSG_SIZE - - (sizeof(struct type6_hdr))) + ap_msg->len = sizeof(struct type6_hdr) + CEIL4(xcRB->req_len); + if (ap_msg->len > ap_msg->bufsize) return -EINVAL; if (CEIL4(xcRB->resp_len) < xcRB->resp_len) return -EINVAL; /* overflow after alignment*/ - if (CEIL4(xcRB->resp_len) > MSGTYPE06_MAX_MSG_SIZE - - (sizeof(struct type86_fmt2_msg))) - return -EINVAL; - /* prepare type6 header */ msg->hdr = static_type6_ep11_hdr; msg->hdr.ToCardLen1 = xcRB->req_len; msg->hdr.FromCardLen1 = xcRB->resp_len; /* Import CPRB data from the ioctl input parameter */ - if (copy_from_user(&(msg->cprbx.cprb_len), - (char __force __user *)xcRB->req, xcRB->req_len)) { + if (z_copy_from_user(userspace, &(msg->cprbx.cprb_len), + (char __force __user *)xcRB->req, xcRB->req_len)) { return -EFAULT; } @@ -569,7 +561,12 @@ /* enable special processing based on the cprbs flags special bit */ if (msg->cprbx.flags & 0x20) - ap_msg->special = 1; + ap_msg->flags |= AP_MSG_FLAG_SPECIAL; + +#ifdef CONFIG_ZCRYPT_DEBUG + if (ap_msg->fi.flags & AP_FI_FLAG_TOGGLE_SPECIAL) + ap_msg->flags ^= AP_MSG_FLAG_SPECIAL; +#endif return 0; } @@ -590,7 +587,7 @@ struct CPRBX cprbx; unsigned char pad[4]; /* 4 byte function code/rules block ? */ unsigned short length; - char text[0]; + char text[]; } __packed; struct type86_ep11_reply { @@ -639,7 +636,7 @@ 0x35, 0x9D, 0xD3, 0xD3, 0xA7, 0x9D, 0x5D, 0x41, 0x6F, 0x65, 0x1B, 0xCF, 0xA9, 0x87, 0x91, 0x09 }; - struct type86x_reply *msg = reply->message; + struct type86x_reply *msg = reply->msg; unsigned short service_rc, service_rs; unsigned int reply_len, pad_len; char *data; @@ -652,23 +649,22 @@ (service_rc == 8 && service_rs == 72) || (service_rc == 8 && service_rs == 770) || (service_rc == 12 && service_rs == 769)) { - ZCRYPT_DBF(DBF_DEBUG, - "device=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) service_rc, (int) service_rs); + ZCRYPT_DBF_WARN("dev=%02x.%04x rc/rs=%d/%d => rc=EINVAL\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) service_rc, (int) service_rs); return -EINVAL; } zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x rc/rs=%d/%d online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) service_rc, (int) service_rs); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) service_rc, (int) service_rs); + ZCRYPT_DBF_ERR("dev=%02x.%04x rc/rs=%d/%d => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) service_rc, (int) service_rs); + return -EAGAIN; } data = msg->text; reply_len = msg->length - 2; @@ -709,23 +705,23 @@ * * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. */ -static int convert_type86_xcrb(struct zcrypt_queue *zq, +static int convert_type86_xcrb(bool userspace, struct zcrypt_queue *zq, struct ap_message *reply, struct ica_xcRB *xcRB) { - struct type86_fmt2_msg *msg = reply->message; - char *data = reply->message; + struct type86_fmt2_msg *msg = reply->msg; + char *data = reply->msg; /* Copy CPRB to user */ - if (copy_to_user(xcRB->reply_control_blk_addr, - data + msg->fmt2.offset1, msg->fmt2.count1)) + if (z_copy_to_user(userspace, xcRB->reply_control_blk_addr, + data + msg->fmt2.offset1, msg->fmt2.count1)) return -EFAULT; xcRB->reply_control_blk_length = msg->fmt2.count1; /* Copy data buffer to user */ if (msg->fmt2.count2) - if (copy_to_user(xcRB->reply_data_addr, - data + msg->fmt2.offset2, msg->fmt2.count2)) + if (z_copy_to_user(userspace, xcRB->reply_data_addr, + data + msg->fmt2.offset2, msg->fmt2.count2)) return -EFAULT; xcRB->reply_data_length = msg->fmt2.count2; return 0; @@ -740,19 +736,19 @@ * * Returns 0 on success or -EINVAL, -EFAULT, -EAGAIN in case of an error. */ -static int convert_type86_ep11_xcrb(struct zcrypt_queue *zq, +static int convert_type86_ep11_xcrb(bool userspace, struct zcrypt_queue *zq, struct ap_message *reply, struct ep11_urb *xcRB) { - struct type86_fmt2_msg *msg = reply->message; - char *data = reply->message; + struct type86_fmt2_msg *msg = reply->msg; + char *data = reply->msg; if (xcRB->resp_len < msg->fmt2.count1) return -EINVAL; /* Copy response CPRB to user */ - if (copy_to_user((char __force __user *)xcRB->resp, - data + msg->fmt2.offset1, msg->fmt2.count1)) + if (z_copy_to_user(userspace, (char __force __user *)xcRB->resp, + data + msg->fmt2.offset1, msg->fmt2.count1)) return -EFAULT; xcRB->resp_len = msg->fmt2.count1; return 0; @@ -766,8 +762,8 @@ struct type86_hdr hdr; struct type86_fmt2_ext fmt2; struct CPRBX cprbx; - } __packed * msg = reply->message; - char *data = reply->message; + } __packed * msg = reply->msg; + char *data = reply->msg; if (msg->cprbx.ccp_rtcode != 0 || msg->cprbx.ccp_rscode != 0) return -EINVAL; @@ -780,7 +776,7 @@ char __user *outputdata, unsigned int outputdatalength) { - struct type86x_reply *msg = reply->message; + struct type86x_reply *msg = reply->msg; switch (msg->hdr.type) { case TYPE82_RSP_CODE: @@ -801,26 +797,27 @@ if (msg->cprbx.cprb_ver_id == 0x02) return convert_type86_ica(zq, reply, outputdata, outputdatalength); - /* fall through - wrong cprb version is an unknown response */ - default: /* Unknown response type, this should NEVER EVER happen */ + fallthrough; /* wrong cprb version is an unknown response */ + default: + /* Unknown response type, this should NEVER EVER happen */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) msg->hdr.type); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + ZCRYPT_DBF_ERR("dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + return -EAGAIN; } } -static int convert_response_xcrb(struct zcrypt_queue *zq, - struct ap_message *reply, - struct ica_xcRB *xcRB) +static int convert_response_xcrb(bool userspace, struct zcrypt_queue *zq, + struct ap_message *reply, + struct ica_xcRB *xcRB) { - struct type86x_reply *msg = reply->message; + struct type86x_reply *msg = reply->msg; switch (msg->hdr.type) { case TYPE82_RSP_CODE: @@ -833,27 +830,27 @@ return convert_error(zq, reply); } if (msg->cprbx.cprb_ver_id == 0x02) - return convert_type86_xcrb(zq, reply, xcRB); - /* fall through - wrong cprb version is an unknown response */ + return convert_type86_xcrb(userspace, zq, reply, xcRB); + fallthrough; /* wrong cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) msg->hdr.type); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + ZCRYPT_DBF_ERR("dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + return -EAGAIN; } } -static int convert_response_ep11_xcrb(struct zcrypt_queue *zq, - struct ap_message *reply, struct ep11_urb *xcRB) +static int convert_response_ep11_xcrb(bool userspace, struct zcrypt_queue *zq, + struct ap_message *reply, struct ep11_urb *xcRB) { - struct type86_ep11_reply *msg = reply->message; + struct type86_ep11_reply *msg = reply->msg; switch (msg->hdr.type) { case TYPE82_RSP_CODE: @@ -863,19 +860,19 @@ if (msg->hdr.reply_code) return convert_error(zq, reply); if (msg->cprbx.cprb_ver_id == 0x04) - return convert_type86_ep11_xcrb(zq, reply, xcRB); - /* fall through - wrong cprb version is an unknown resp */ + return convert_type86_ep11_xcrb(userspace, zq, reply, xcRB); + fallthrough; /* wrong cprb version is an unknown resp */ default: /* Unknown response type, this should NEVER EVER happen */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) msg->hdr.type); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + ZCRYPT_DBF_ERR("dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + return -EAGAIN; } } @@ -883,7 +880,7 @@ struct ap_message *reply, char *data) { - struct type86x_reply *msg = reply->message; + struct type86x_reply *msg = reply->msg; switch (msg->hdr.type) { case TYPE82_RSP_CODE: @@ -894,18 +891,18 @@ return -EINVAL; if (msg->cprbx.cprb_ver_id == 0x02) return convert_type86_rng(zq, reply, data); - /* fall through - wrong cprb version is an unknown response */ + fallthrough; /* wrong cprb version is an unknown response */ default: /* Unknown response type, this should NEVER EVER happen */ zq->online = 0; - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", + pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid)); - ZCRYPT_DBF(DBF_ERR, - "device=%02x.%04x rtype=0x%02x => online=0 rc=EAGAIN\n", - AP_QID_CARD(zq->queue->qid), - AP_QID_QUEUE(zq->queue->qid), - (int) msg->hdr.type); - return -EAGAIN; /* repeat the request on a different device. */ + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + ZCRYPT_DBF_ERR("dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n", + AP_QID_CARD(zq->queue->qid), + AP_QID_QUEUE(zq->queue->qid), + (int) msg->hdr.type); + return -EAGAIN; } } @@ -928,32 +925,38 @@ struct response_type *resp_type = (struct response_type *) msg->private; struct type86x_reply *t86r; - int length; + int len; /* Copy the reply message to the request message buffer. */ if (!reply) goto out; /* ap_msg->rc indicates the error */ - t86r = reply->message; + t86r = reply->msg; if (t86r->hdr.type == TYPE86_RSP_CODE && t86r->cprbx.cprb_ver_id == 0x02) { switch (resp_type->type) { case CEXXC_RESPONSE_TYPE_ICA: - length = sizeof(struct type86x_reply) - + t86r->length - 2; - length = min(CEXXC_MAX_ICA_RESPONSE_SIZE, length); - memcpy(msg->message, reply->message, length); + len = sizeof(struct type86x_reply) + t86r->length - 2; + if (len > reply->bufsize || len > msg->bufsize) { + msg->rc = -EMSGSIZE; + } else { + memcpy(msg->msg, reply->msg, len); + msg->len = len; + } break; case CEXXC_RESPONSE_TYPE_XCRB: - length = t86r->fmt2.offset2 + t86r->fmt2.count2; - length = min(MSGTYPE06_MAX_MSG_SIZE, length); - memcpy(msg->message, reply->message, length); + len = t86r->fmt2.offset2 + t86r->fmt2.count2; + if (len > reply->bufsize || len > msg->bufsize) { + msg->rc = -EMSGSIZE; + } else { + memcpy(msg->msg, reply->msg, len); + msg->len = len; + } break; default: - memcpy(msg->message, &error_reply, - sizeof(error_reply)); + memcpy(msg->msg, &error_reply, sizeof(error_reply)); } } else - memcpy(msg->message, reply->message, sizeof(error_reply)); + memcpy(msg->msg, reply->msg, sizeof(error_reply)); out: complete(&(resp_type->work)); } @@ -977,25 +980,29 @@ struct response_type *resp_type = (struct response_type *)msg->private; struct type86_ep11_reply *t86r; - int length; + int len; /* Copy the reply message to the request message buffer. */ if (!reply) goto out; /* ap_msg->rc indicates the error */ - t86r = reply->message; + t86r = reply->msg; if (t86r->hdr.type == TYPE86_RSP_CODE && t86r->cprbx.cprb_ver_id == 0x04) { switch (resp_type->type) { case CEXXC_RESPONSE_TYPE_EP11: - length = t86r->fmt2.offset1 + t86r->fmt2.count1; - length = min(MSGTYPE06_MAX_MSG_SIZE, length); - memcpy(msg->message, reply->message, length); + len = t86r->fmt2.offset1 + t86r->fmt2.count1; + if (len > reply->bufsize || len > msg->bufsize) { + msg->rc = -EMSGSIZE; + } else { + memcpy(msg->msg, reply->msg, len); + msg->len = len; + } break; default: - memcpy(msg->message, &error_reply, sizeof(error_reply)); + memcpy(msg->msg, &error_reply, sizeof(error_reply)); } } else { - memcpy(msg->message, reply->message, sizeof(error_reply)); + memcpy(msg->msg, reply->msg, sizeof(error_reply)); } out: complete(&(resp_type->work)); @@ -1011,39 +1018,43 @@ * @mex: pointer to the modexpo request buffer */ static long zcrypt_msgtype6_modexpo(struct zcrypt_queue *zq, - struct ica_rsa_modexpo *mex) + struct ica_rsa_modexpo *mex, + struct ap_message *ap_msg) { - struct ap_message ap_msg; struct response_type resp_type = { .type = CEXXC_RESPONSE_TYPE_ICA, }; int rc; - ap_init_message(&ap_msg); - ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); - if (!ap_msg.message) + ap_msg->msg = (void *) get_zeroed_page(GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; - ap_msg.receive = zcrypt_msgtype6_receive; - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + - atomic_inc_return(&zcrypt_step); - ap_msg.private = &resp_type; - rc = ICAMEX_msg_to_type6MEX_msgX(zq, &ap_msg, mex); + ap_msg->bufsize = PAGE_SIZE; + ap_msg->receive = zcrypt_msgtype6_receive; + ap_msg->psmid = (((unsigned long long) current->pid) << 32) + + atomic_inc_return(&zcrypt_step); + ap_msg->private = &resp_type; + rc = ICAMEX_msg_to_type6MEX_msgX(zq, ap_msg, mex); if (rc) goto out_free; init_completion(&resp_type.work); - ap_queue_message(zq->queue, &ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out_free; rc = wait_for_completion_interruptible(&resp_type.work); if (rc == 0) { - rc = ap_msg.rc; + rc = ap_msg->rc; if (rc == 0) - rc = convert_response_ica(zq, &ap_msg, + rc = convert_response_ica(zq, ap_msg, mex->outputdata, mex->outputdatalength); } else /* Signal pending. */ - ap_cancel_message(zq->queue, &ap_msg); + ap_cancel_message(zq->queue, ap_msg); out_free: - free_page((unsigned long) ap_msg.message); + free_page((unsigned long) ap_msg->msg); + ap_msg->private = NULL; + ap_msg->msg = NULL; return rc; } @@ -1055,40 +1066,44 @@ * @crt: pointer to the modexpoc_crt request buffer */ static long zcrypt_msgtype6_modexpo_crt(struct zcrypt_queue *zq, - struct ica_rsa_modexpo_crt *crt) + struct ica_rsa_modexpo_crt *crt, + struct ap_message *ap_msg) { - struct ap_message ap_msg; struct response_type resp_type = { .type = CEXXC_RESPONSE_TYPE_ICA, }; int rc; - ap_init_message(&ap_msg); - ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); - if (!ap_msg.message) + ap_msg->msg = (void *) get_zeroed_page(GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; - ap_msg.receive = zcrypt_msgtype6_receive; - ap_msg.psmid = (((unsigned long long) current->pid) << 32) + - atomic_inc_return(&zcrypt_step); - ap_msg.private = &resp_type; - rc = ICACRT_msg_to_type6CRT_msgX(zq, &ap_msg, crt); + ap_msg->bufsize = PAGE_SIZE; + ap_msg->receive = zcrypt_msgtype6_receive; + ap_msg->psmid = (((unsigned long long) current->pid) << 32) + + atomic_inc_return(&zcrypt_step); + ap_msg->private = &resp_type; + rc = ICACRT_msg_to_type6CRT_msgX(zq, ap_msg, crt); if (rc) goto out_free; init_completion(&resp_type.work); - ap_queue_message(zq->queue, &ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out_free; rc = wait_for_completion_interruptible(&resp_type.work); if (rc == 0) { - rc = ap_msg.rc; + rc = ap_msg->rc; if (rc == 0) - rc = convert_response_ica(zq, &ap_msg, + rc = convert_response_ica(zq, ap_msg, crt->outputdata, crt->outputdatalength); } else { /* Signal pending. */ - ap_cancel_message(zq->queue, &ap_msg); + ap_cancel_message(zq->queue, ap_msg); } out_free: - free_page((unsigned long) ap_msg.message); + free_page((unsigned long) ap_msg->msg); + ap_msg->private = NULL; + ap_msg->msg = NULL; return rc; } @@ -1099,16 +1114,17 @@ * by the caller with ap_init_message(). Also the caller has to * make sure ap_release_message() is always called even on failure. */ -unsigned int get_cprb_fc(struct ica_xcRB *xcRB, - struct ap_message *ap_msg, - unsigned int *func_code, unsigned short **dom) +unsigned int get_cprb_fc(bool userspace, struct ica_xcRB *xcRB, + struct ap_message *ap_msg, + unsigned int *func_code, unsigned short **dom) { struct response_type resp_type = { .type = CEXXC_RESPONSE_TYPE_XCRB, }; - ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); - if (!ap_msg->message) + ap_msg->bufsize = atomic_read(&ap_max_msg_size); + ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; ap_msg->receive = zcrypt_msgtype6_receive; ap_msg->psmid = (((unsigned long long) current->pid) << 32) + @@ -1116,7 +1132,7 @@ ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL); if (!ap_msg->private) return -ENOMEM; - return XCRB_msg_to_type6CPRB_msgX(ap_msg, xcRB, func_code, dom); + return XCRB_msg_to_type6CPRB_msgX(userspace, ap_msg, xcRB, func_code, dom); } /** @@ -1126,24 +1142,26 @@ * CEXxC device to the request distributor * @xcRB: pointer to the send_cprb request buffer */ -static long zcrypt_msgtype6_send_cprb(struct zcrypt_queue *zq, - struct ica_xcRB *xcRB, - struct ap_message *ap_msg) +static long zcrypt_msgtype6_send_cprb(bool userspace, struct zcrypt_queue *zq, + struct ica_xcRB *xcRB, + struct ap_message *ap_msg) { int rc; struct response_type *rtype = (struct response_type *)(ap_msg->private); init_completion(&rtype->work); - ap_queue_message(zq->queue, ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out; rc = wait_for_completion_interruptible(&rtype->work); if (rc == 0) { rc = ap_msg->rc; if (rc == 0) - rc = convert_response_xcrb(zq, ap_msg, xcRB); + rc = convert_response_xcrb(userspace, zq, ap_msg, xcRB); } else /* Signal pending. */ ap_cancel_message(zq->queue, ap_msg); - +out: return rc; } @@ -1154,16 +1172,17 @@ * by the caller with ap_init_message(). Also the caller has to * make sure ap_release_message() is always called even on failure. */ -unsigned int get_ep11cprb_fc(struct ep11_urb *xcrb, - struct ap_message *ap_msg, - unsigned int *func_code) +unsigned int get_ep11cprb_fc(bool userspace, struct ep11_urb *xcrb, + struct ap_message *ap_msg, + unsigned int *func_code) { struct response_type resp_type = { .type = CEXXC_RESPONSE_TYPE_EP11, }; - ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); - if (!ap_msg->message) + ap_msg->bufsize = atomic_read(&ap_max_msg_size); + ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; ap_msg->receive = zcrypt_msgtype6_receive_ep11; ap_msg->psmid = (((unsigned long long) current->pid) << 32) + @@ -1171,7 +1190,7 @@ ap_msg->private = kmemdup(&resp_type, sizeof(resp_type), GFP_KERNEL); if (!ap_msg->private) return -ENOMEM; - return xcrb_msg_to_type6_ep11cprb_msgx(ap_msg, xcrb, func_code); + return xcrb_msg_to_type6_ep11cprb_msgx(userspace, ap_msg, xcrb, func_code); } /** @@ -1181,7 +1200,7 @@ * CEX4P device to the request distributor * @xcRB: pointer to the ep11 user request block */ -static long zcrypt_msgtype6_send_ep11_cprb(struct zcrypt_queue *zq, +static long zcrypt_msgtype6_send_ep11_cprb(bool userspace, struct zcrypt_queue *zq, struct ep11_urb *xcrb, struct ap_message *ap_msg) { @@ -1193,7 +1212,7 @@ struct ep11_cprb cprbx; unsigned char pld_tag; /* fixed value 0x30 */ unsigned char pld_lenfmt; /* payload length format */ - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; struct pld_hdr { unsigned char func_tag; /* fixed value 0x4 */ unsigned char func_len; /* fixed value 0x4 */ @@ -1236,16 +1255,18 @@ } init_completion(&rtype->work); - ap_queue_message(zq->queue, ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out; rc = wait_for_completion_interruptible(&rtype->work); if (rc == 0) { rc = ap_msg->rc; if (rc == 0) - rc = convert_response_ep11_xcrb(zq, ap_msg, xcrb); + rc = convert_response_ep11_xcrb(userspace, zq, ap_msg, xcrb); } else /* Signal pending. */ ap_cancel_message(zq->queue, ap_msg); - +out: return rc; } @@ -1256,8 +1277,9 @@ .type = CEXXC_RESPONSE_TYPE_XCRB, }; - ap_msg->message = kmalloc(MSGTYPE06_MAX_MSG_SIZE, GFP_KERNEL); - if (!ap_msg->message) + ap_msg->bufsize = AP_DEFAULT_MAX_MSG_SIZE; + ap_msg->msg = kmalloc(ap_msg->bufsize, GFP_KERNEL); + if (!ap_msg->msg) return -ENOMEM; ap_msg->receive = zcrypt_msgtype6_receive; ap_msg->psmid = (((unsigned long long) current->pid) << 32) + @@ -1290,14 +1312,16 @@ char rule[8]; short int verb_length; short int key_length; - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; struct response_type *rtype = (struct response_type *)(ap_msg->private); int rc; msg->cprbx.domain = AP_QID_QUEUE(zq->queue->qid); init_completion(&rtype->work); - ap_queue_message(zq->queue, ap_msg); + rc = ap_queue_message(zq->queue, ap_msg); + if (rc) + goto out; rc = wait_for_completion_interruptible(&rtype->work); if (rc == 0) { rc = ap_msg->rc; @@ -1306,7 +1330,7 @@ } else /* Signal pending. */ ap_cancel_message(zq->queue, ap_msg); - +out: return rc; } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_msgtype6.h +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_msgtype6.h @@ -19,8 +19,6 @@ #define MSGTYPE06_VARIANT_NORNG 1 #define MSGTYPE06_VARIANT_EP11 2 -#define MSGTYPE06_MAX_MSG_SIZE (12*1024) - /** * The type 6 message family is associated with CEXxC/CEXxP cards. * @@ -96,9 +94,9 @@ unsigned int offset4; /* 0x00000000 */ } __packed; -unsigned int get_cprb_fc(struct ica_xcRB *, struct ap_message *, +unsigned int get_cprb_fc(bool userspace, struct ica_xcRB *, struct ap_message *, unsigned int *, unsigned short **); -unsigned int get_ep11cprb_fc(struct ep11_urb *, struct ap_message *, +unsigned int get_ep11cprb_fc(bool userspace, struct ep11_urb *, struct ap_message *, unsigned int *); unsigned int get_rng_fc(struct ap_message *, int *, unsigned int *); @@ -127,7 +125,7 @@ char rule[8]; short int verb_length; short int key_length; - } __packed * msg = ap_msg->message; + } __packed * msg = ap_msg->msg; static struct type6_hdr static_type6_hdrX = { .type = 0x06, .offset1 = 0x00000058, @@ -154,7 +152,7 @@ memcpy(msg->rule, "RANDOM ", 8); msg->verb_length = 0x02; msg->key_length = 0x02; - ap_msg->length = sizeof(*msg); + ap_msg->len = sizeof(*msg); *domain = (unsigned short)msg->cprbx.domain; } --- linux-oracle-5.4.0.orig/drivers/s390/crypto/zcrypt_queue.c +++ linux-oracle-5.4.0/drivers/s390/crypto/zcrypt_queue.c @@ -40,22 +40,27 @@ struct device_attribute *attr, char *buf) { - struct zcrypt_queue *zq = to_ap_queue(dev)->private; + struct ap_queue *aq = to_ap_queue(dev); + struct zcrypt_queue *zq = aq->private; + int online = aq->config && zq->online ? 1 : 0; - return snprintf(buf, PAGE_SIZE, "%d\n", zq->online); + return scnprintf(buf, PAGE_SIZE, "%d\n", online); } static ssize_t online_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct zcrypt_queue *zq = to_ap_queue(dev)->private; + struct ap_queue *aq = to_ap_queue(dev); + struct zcrypt_queue *zq = aq->private; struct zcrypt_card *zc = zq->zcard; int online; if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1) return -EINVAL; + if (online && (!aq->config || !aq->card->config)) + return -ENODEV; if (online && !zc->online) return -EINVAL; zq->online = online; @@ -78,7 +83,7 @@ { struct zcrypt_queue *zq = to_ap_queue(dev)->private; - return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load)); + return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load)); } static DEVICE_ATTR_RO(load); @@ -100,17 +105,17 @@ ap_flush_queue(zq->queue); } -struct zcrypt_queue *zcrypt_queue_alloc(size_t max_response_size) +struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size) { struct zcrypt_queue *zq; zq = kzalloc(sizeof(struct zcrypt_queue), GFP_KERNEL); if (!zq) return NULL; - zq->reply.message = kmalloc(max_response_size, GFP_KERNEL); - if (!zq->reply.message) + zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL); + if (!zq->reply.msg) goto out_free; - zq->reply.length = max_response_size; + zq->reply.bufsize = reply_buf_size; INIT_LIST_HEAD(&zq->list); kref_init(&zq->refcount); return zq; @@ -123,7 +128,7 @@ void zcrypt_queue_free(struct zcrypt_queue *zq) { - kfree(zq->reply.message); + kfree(zq->reply.msg); kfree(zq); } EXPORT_SYMBOL(zcrypt_queue_free); @@ -175,7 +180,6 @@ &zcrypt_queue_attr_group); if (rc) goto out; - get_device(&zq->queue->ap_dev.device); if (zq->ops->rng) { rc = zcrypt_rng_device_add(); @@ -187,7 +191,6 @@ out_unregister: sysfs_remove_group(&zq->queue->ap_dev.device.kobj, &zcrypt_queue_attr_group); - put_device(&zq->queue->ap_dev.device); out: spin_lock(&zcrypt_list_lock); list_del_init(&zq->list); @@ -215,12 +218,11 @@ list_del_init(&zq->list); zcrypt_device_count--; spin_unlock(&zcrypt_list_lock); - zcrypt_card_put(zc); if (zq->ops->rng) zcrypt_rng_device_remove(); sysfs_remove_group(&zq->queue->ap_dev.device.kobj, &zcrypt_queue_attr_group); - put_device(&zq->queue->ap_dev.device); + zcrypt_card_put(zc); zcrypt_queue_put(zq); } EXPORT_SYMBOL(zcrypt_queue_unregister); --- linux-oracle-5.4.0.orig/drivers/s390/net/ctcm_main.c +++ linux-oracle-5.4.0/drivers/s390/net/ctcm_main.c @@ -865,16 +865,9 @@ /** * Start transmission of a packet. * Called from generic network device layer. - * - * skb Pointer to buffer containing the packet. - * dev Pointer to interface struct. - * - * returns 0 if packet consumed, !0 if packet rejected. - * Note: If we return !0, then the packet is free'd by - * the generic network layer. */ /* first merge version - leaving both functions separated */ -static int ctcm_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ctcm_tx(struct sk_buff *skb, struct net_device *dev) { struct ctcm_priv *priv = dev->ml_priv; @@ -917,7 +910,7 @@ } /* unmerged MPC variant of ctcm_tx */ -static int ctcmpc_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t ctcmpc_tx(struct sk_buff *skb, struct net_device *dev) { int len = 0; struct ctcm_priv *priv = dev->ml_priv; --- linux-oracle-5.4.0.orig/drivers/s390/net/ctcm_mpc.c +++ linux-oracle-5.4.0/drivers/s390/net/ctcm_mpc.c @@ -626,8 +626,6 @@ ctcm_clear_busy_do(dev); } - kfree(mpcginfo); - return; } @@ -1206,10 +1204,10 @@ CTCM_FUNTAIL, dev->name); priv->stats.rx_dropped++; /* mpcginfo only used for non-data transfers */ - kfree(mpcginfo); if (do_debug_data) ctcmpc_dump_skb(pskb, -8); } + kfree(mpcginfo); } done: @@ -1991,7 +1989,6 @@ } break; } - kfree(mpcginfo); CTCM_PR_DEBUG("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n", __func__, ch->id, grp->outstanding_xid2, @@ -2052,7 +2049,6 @@ mpc_validate_xid(mpcginfo); break; } - kfree(mpcginfo); return; } --- linux-oracle-5.4.0.orig/drivers/s390/net/ctcm_sysfs.c +++ linux-oracle-5.4.0/drivers/s390/net/ctcm_sysfs.c @@ -39,11 +39,12 @@ struct ctcm_priv *priv = dev_get_drvdata(dev); int rc; - ndev = priv->channel[CTCM_READ]->netdev; - if (!(priv && priv->channel[CTCM_READ] && ndev)) { + if (!(priv && priv->channel[CTCM_READ] && + priv->channel[CTCM_READ]->netdev)) { CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev"); return -ENODEV; } + ndev = priv->channel[CTCM_READ]->netdev; rc = kstrtouint(buf, 0, &bs1); if (rc) --- linux-oracle-5.4.0.orig/drivers/s390/net/ism_drv.c +++ linux-oracle-5.4.0/drivers/s390/net/ism_drv.c @@ -521,8 +521,10 @@ ism->smcd = smcd_alloc_dev(&pdev->dev, dev_name(&pdev->dev), &ism_ops, ISM_NR_DMBS); - if (!ism->smcd) + if (!ism->smcd) { + ret = -ENOMEM; goto err_resource; + } ism->smcd->priv = ism; ret = ism_dev_init(ism); --- linux-oracle-5.4.0.orig/drivers/s390/net/lcs.c +++ linux-oracle-5.4.0/drivers/s390/net/lcs.c @@ -1518,9 +1518,8 @@ /** * Packet transmit function called by network stack */ -static int -__lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, - struct net_device *dev) +static netdev_tx_t __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb, + struct net_device *dev) { struct lcs_header *header; int rc = NETDEV_TX_OK; @@ -1581,8 +1580,7 @@ return rc; } -static int -lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t lcs_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct lcs_card *card; int rc; @@ -1735,10 +1733,11 @@ lcs_schedule_recovery(card); break; case LCS_CMD_STOPLAN: - pr_warn("Stoplan for %s initiated by LGW\n", - card->dev->name); - if (card->dev) + if (card->dev) { + pr_warn("Stoplan for %s initiated by LGW\n", + card->dev->name); netif_carrier_off(card->dev); + } break; default: LCS_DBF_TEXT(5, trace, "noLGWcmd"); --- linux-oracle-5.4.0.orig/drivers/s390/net/netiucv.c +++ linux-oracle-5.4.0/drivers/s390/net/netiucv.c @@ -1344,15 +1344,8 @@ /** * Start transmission of a packet. * Called from generic network device layer. - * - * @param skb Pointer to buffer containing the packet. - * @param dev Pointer to interface struct. - * - * @return 0 if packet consumed, !0 if packet rejected. - * Note: If we return !0, then the packet is free'd by - * the generic network layer. */ -static int netiucv_tx(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t netiucv_tx(struct sk_buff *skb, struct net_device *dev) { struct netiucv_priv *privptr = netdev_priv(dev); int rc; --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_core.h +++ linux-oracle-5.4.0/drivers/s390/net/qeth_core.h @@ -436,10 +436,13 @@ QETH_QDIO_BUF_EMPTY, /* Filled by driver; owned by hardware in order to be sent. */ QETH_QDIO_BUF_PRIMED, - /* Identified to be pending in TPQ. */ + /* Discovered by the TX completion code: */ QETH_QDIO_BUF_PENDING, - /* Found in completion queue. */ - QETH_QDIO_BUF_IN_CQ, + /* Finished by the TX completion code: */ + QETH_QDIO_BUF_NEED_QAOB, + /* Received QAOB notification on CQ: */ + QETH_QDIO_BUF_QAOB_OK, + QETH_QDIO_BUF_QAOB_ERROR, /* Handled via transfer pending / completion queue. */ QETH_QDIO_BUF_HANDLED_DELAYED, }; @@ -532,6 +535,8 @@ struct timer_list timer; struct qeth_hdr *prev_hdr; u8 bulk_start; + u8 bulk_count; + u8 bulk_max; }; #define qeth_for_each_output_queue(card, q, i) \ @@ -620,6 +625,7 @@ struct qeth_channel { struct ccw_device *ccwdev; + struct qeth_cmd_buffer *active_cmd; enum qeth_channel_states state; atomic_t irq_pending; }; @@ -879,6 +885,13 @@ return txq; } +static inline bool qeth_iqd_is_mcast_queue(struct qeth_card *card, + struct qeth_qdio_out_q *queue) +{ + return qeth_iqd_translate_txq(card->dev, queue->queue_no) == + QETH_IQD_MCAST_TXQ; +} + static inline void qeth_scrub_qdio_buffer(struct qdio_buffer *buf, unsigned int elements) { @@ -1024,6 +1037,8 @@ void qeth_clear_thread_start_bit(struct qeth_card *, unsigned long); void qeth_clear_thread_running_bit(struct qeth_card *, unsigned long); int qeth_core_hardsetup_card(struct qeth_card *card, bool *carrier_ok); +int qeth_stop_channel(struct qeth_channel *channel); + void qeth_print_status_message(struct qeth_card *); int qeth_init_qdio_queues(struct qeth_card *); int qeth_send_ipa_cmd(struct qeth_card *, struct qeth_cmd_buffer *, --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_core_main.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_core_main.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -226,7 +227,7 @@ return -ENOMEM; } for (j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j) { - ptr = (void *) __get_free_page(GFP_KERNEL); + ptr = (void *) __get_free_page(GFP_KERNEL|__GFP_MEMALLOC); if (!ptr) { while (j > 0) free_page((unsigned long) @@ -425,18 +426,13 @@ } } - if (forced_cleanup && (atomic_read(&(q->bufs[bidx]->state)) == - QETH_QDIO_BUF_HANDLED_DELAYED)) { - /* for recovery situations */ - qeth_init_qdio_out_buf(q, bidx); - QETH_CARD_TEXT(q->card, 2, "clprecov"); - } } static void qeth_qdio_handle_aob(struct qeth_card *card, unsigned long phys_aob_addr) { + enum qeth_qdio_out_buffer_state new_state = QETH_QDIO_BUF_QAOB_OK; struct qaob *aob; struct qeth_qdio_out_buffer *buffer; enum iucv_tx_notify notification; @@ -448,22 +444,6 @@ buffer = (struct qeth_qdio_out_buffer *) aob->user1; QETH_CARD_TEXT_(card, 5, "%lx", aob->user1); - if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, - QETH_QDIO_BUF_IN_CQ) == QETH_QDIO_BUF_PRIMED) { - notification = TX_NOTIFY_OK; - } else { - WARN_ON_ONCE(atomic_read(&buffer->state) != - QETH_QDIO_BUF_PENDING); - atomic_set(&buffer->state, QETH_QDIO_BUF_IN_CQ); - notification = TX_NOTIFY_DELAYED_OK; - } - - if (aob->aorc != 0) { - QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); - notification = qeth_compute_cq_notification(aob->aorc, 1); - } - qeth_notify_skbs(buffer->q, buffer, notification); - /* Free dangling allocations. The attached skbs are handled by * qeth_cleanup_handled_pending(). */ @@ -474,7 +454,33 @@ kmem_cache_free(qeth_core_header_cache, (void *) aob->sba[i]); } - atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + + if (aob->aorc) { + QETH_CARD_TEXT_(card, 2, "aorc%02X", aob->aorc); + new_state = QETH_QDIO_BUF_QAOB_ERROR; + } + + switch (atomic_xchg(&buffer->state, new_state)) { + case QETH_QDIO_BUF_PRIMED: + /* Faster than TX completion code. */ + notification = qeth_compute_cq_notification(aob->aorc, 0); + qeth_notify_skbs(buffer->q, buffer, notification); + atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + break; + case QETH_QDIO_BUF_PENDING: + /* TX completion code is active and will handle the async + * completion for us. + */ + break; + case QETH_QDIO_BUF_NEED_QAOB: + /* TX completion code is already finished. */ + notification = qeth_compute_cq_notification(aob->aorc, 1); + qeth_notify_skbs(buffer->q, buffer, notification); + atomic_set(&buffer->state, QETH_QDIO_BUF_HANDLED_DELAYED); + break; + default: + WARN_ON_ONCE(1); + } qdio_release_aob(aob); } @@ -515,7 +521,9 @@ QETH_CARD_TEXT(card, 6, "noirqpnd"); rc = ccw_device_start(channel->ccwdev, ccw, (addr_t) iob, 0, 0); - if (rc) { + if (!rc) { + channel->active_cmd = iob; + } else { QETH_DBF_MESSAGE(2, "error %i on device %x when starting next read ccw!\n", rc, CARD_DEVID(card)); atomic_set(&channel->irq_pending, 0); @@ -653,17 +661,17 @@ unsigned char *buffer) { QETH_DBF_HEX(CTRL, 2, buffer, QETH_DBF_CTRL_LEN); - if ((buffer[2] & 0xc0) == 0xc0) { + if ((buffer[2] & QETH_IDX_TERMINATE_MASK) == QETH_IDX_TERMINATE) { QETH_DBF_MESSAGE(2, "received an IDX TERMINATE with cause code %#04x\n", buffer[4]); QETH_CARD_TEXT(card, 2, "ckidxres"); QETH_CARD_TEXT(card, 2, " idxterm"); - QETH_CARD_TEXT_(card, 2, " rc%d", -EIO); - if (buffer[4] == 0xf6) { + QETH_CARD_TEXT_(card, 2, "rc%x", buffer[4]); + if (buffer[4] == QETH_IDX_TERM_BAD_TRANSPORT || + buffer[4] == QETH_IDX_TERM_BAD_TRANSPORT_VM) { dev_err(&card->gdev->dev, - "The qeth device is not configured " - "for the OSI layer required by z/VM\n"); - return -EPERM; + "The device does not support the configured transport mode\n"); + return -EPROTONOSUPPORT; } return -EIO; } @@ -740,10 +748,10 @@ case 0: break; case -EIO: - qeth_clear_ipacmd_list(card); qeth_schedule_recovery(card); /* fall through */ default: + qeth_clear_ipacmd_list(card); goto out; } @@ -986,8 +994,21 @@ QETH_CARD_TEXT(card, 5, "data"); } - if (qeth_intparm_is_iob(intparm)) - iob = (struct qeth_cmd_buffer *) __va((addr_t)intparm); + if (intparm == 0) { + QETH_CARD_TEXT(card, 5, "irqunsol"); + } else if ((addr_t)intparm != (addr_t)channel->active_cmd) { + QETH_CARD_TEXT(card, 5, "irqunexp"); + + dev_err(&cdev->dev, + "Received IRQ with intparm %lx, expected %px\n", + intparm, channel->active_cmd); + if (channel->active_cmd) + qeth_cancel_cmd(channel->active_cmd, -EIO); + } else { + iob = (struct qeth_cmd_buffer *) (addr_t)intparm; + } + + channel->active_cmd = NULL; rc = qeth_check_irb_error(card, cdev, irb); if (rc) { @@ -1007,15 +1028,10 @@ if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC)) channel->state = CH_STATE_HALTED; - if (intparm == QETH_CLEAR_CHANNEL_PARM) { - QETH_CARD_TEXT(card, 6, "clrchpar"); - /* we don't have to handle this further */ - intparm = 0; - } - if (intparm == QETH_HALT_CHANNEL_PARM) { - QETH_CARD_TEXT(card, 6, "hltchpar"); - /* we don't have to handle this further */ - intparm = 0; + if (iob && (irb->scsw.cmd.fctl & (SCSW_FCTL_CLEAR_FUNC | + SCSW_FCTL_HALT_FUNC))) { + qeth_cancel_cmd(iob, -ECANCELED); + iob = NULL; } cstat = irb->scsw.cmd.cstat; @@ -1073,7 +1089,7 @@ skb_queue_walk(&buf->skb_list, skb) { QETH_CARD_TEXT_(q->card, 5, "skbn%d", notification); QETH_CARD_TEXT_(q->card, 5, "%lx", (long) skb); - if (skb->protocol == htons(ETH_P_AF_IUCV) && skb->sk) + if (skb->sk && skb->sk->sk_family == PF_IUCV) iucv_sk(skb->sk)->sk_txnotify(skb, notification); } } @@ -1084,9 +1100,6 @@ struct qeth_qdio_out_q *queue = buf->q; struct sk_buff *skb; - /* release may never happen from within CQ tasklet scope */ - WARN_ON_ONCE(atomic_read(&buf->state) == QETH_QDIO_BUF_IN_CQ); - if (atomic_read(&buf->state) == QETH_QDIO_BUF_PENDING) qeth_notify_skbs(queue, buf, TX_NOTIFY_GENERALERROR); @@ -1234,7 +1247,6 @@ if (count == 1) dev_info(&card->gdev->dev, "Priority Queueing not supported\n"); - card->qdio.default_out_queue = single ? 0 : QETH_DEFAULT_QUEUE; card->qdio.no_out_queues = count; return 0; } @@ -1408,7 +1420,7 @@ QETH_CARD_TEXT(card, 3, "clearch"); spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); - rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM); + rc = ccw_device_clear(channel->ccwdev, (addr_t)channel->active_cmd); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); if (rc) @@ -1430,7 +1442,7 @@ QETH_CARD_TEXT(card, 3, "haltch"); spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); - rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM); + rc = ccw_device_halt(channel->ccwdev, (addr_t)channel->active_cmd); spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); if (rc) @@ -1444,6 +1456,25 @@ return 0; } +int qeth_stop_channel(struct qeth_channel *channel) +{ + struct ccw_device *cdev = channel->ccwdev; + int rc; + + rc = ccw_device_set_offline(cdev); + + spin_lock_irq(get_ccwdev_lock(cdev)); + if (channel->active_cmd) { + dev_err(&cdev->dev, "Stopped channel while cmd %px was still active\n", + channel->active_cmd); + channel->active_cmd = NULL; + } + spin_unlock_irq(get_ccwdev_lock(cdev)); + + return rc; +} +EXPORT_SYMBOL_GPL(qeth_stop_channel); + static int qeth_halt_channels(struct qeth_card *card) { int rc1 = 0, rc2 = 0, rc3 = 0; @@ -1747,6 +1778,8 @@ spin_lock_irq(get_ccwdev_lock(channel->ccwdev)); rc = ccw_device_start_timeout(channel->ccwdev, __ccw_from_cmd(iob), (addr_t) iob, 0, 0, timeout); + if (!rc) + channel->active_cmd = iob; spin_unlock_irq(get_ccwdev_lock(channel->ccwdev)); if (rc) { QETH_DBF_MESSAGE(2, "qeth_send_control_data on device %x: ccw_device_start rc = %i\n", @@ -2451,50 +2484,46 @@ rc = qeth_cm_enable(card); if (rc) { QETH_CARD_TEXT_(card, 2, "2err%d", rc); - goto out_qdio; + return rc; } rc = qeth_cm_setup(card); if (rc) { QETH_CARD_TEXT_(card, 2, "3err%d", rc); - goto out_qdio; + return rc; } rc = qeth_ulp_enable(card); if (rc) { QETH_CARD_TEXT_(card, 2, "4err%d", rc); - goto out_qdio; + return rc; } rc = qeth_ulp_setup(card); if (rc) { QETH_CARD_TEXT_(card, 2, "5err%d", rc); - goto out_qdio; + return rc; } rc = qeth_alloc_qdio_queues(card); if (rc) { QETH_CARD_TEXT_(card, 2, "5err%d", rc); - goto out_qdio; + return rc; } rc = qeth_qdio_establish(card); if (rc) { QETH_CARD_TEXT_(card, 2, "6err%d", rc); qeth_free_qdio_queues(card); - goto out_qdio; + return rc; } rc = qeth_qdio_activate(card); if (rc) { QETH_CARD_TEXT_(card, 2, "7err%d", rc); - goto out_qdio; + return rc; } rc = qeth_dm_act(card); if (rc) { QETH_CARD_TEXT_(card, 2, "8err%d", rc); - goto out_qdio; + return rc; } return 0; -out_qdio: - qeth_qdio_clear_card(card, !IS_IQD(card)); - qdio_free(CARD_DDEV(card)); - return rc; } void qeth_print_status_message(struct qeth_card *card) @@ -2583,7 +2612,7 @@ struct qeth_buffer_pool_entry, list); for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { if (page_count(virt_to_page(entry->elements[i])) > 1) { - page = alloc_page(GFP_ATOMIC); + page = dev_alloc_page(); if (!page) { return NULL; } else { @@ -2607,12 +2636,12 @@ buf->rx_skb = netdev_alloc_skb(card->dev, QETH_RX_PULL_LEN + ETH_HLEN); if (!buf->rx_skb) - return 1; + return -ENOMEM; } pool_entry = qeth_find_free_buffer_pool_entry(card); if (!pool_entry) - return 1; + return -ENOBUFS; /* * since the buffer is accessed only from the input_tasklet @@ -2634,6 +2663,18 @@ return 0; } +static unsigned int qeth_tx_select_bulk_max(struct qeth_card *card, + struct qeth_qdio_out_q *queue) +{ + if (!IS_IQD(card) || + qeth_iqd_is_mcast_queue(card, queue) || + card->options.cq == QETH_CQ_ENABLED || + qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd)) + return 1; + + return card->ssqd.mmwc ? card->ssqd.mmwc : 1; +} + int qeth_init_qdio_queues(struct qeth_card *card) { unsigned int i; @@ -2644,10 +2685,15 @@ /* inbound queue */ qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); memset(&card->rx, 0, sizeof(struct qeth_rx)); + qeth_initialize_working_pool_list(card); /*give only as many buffers to hardware as we have buffer pool entries*/ - for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) - qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]); + for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; i++) { + rc = qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]); + if (rc) + return rc; + } + card->qdio.in_q->next_buf_to_init = card->qdio.in_buf_pool.buf_count - 1; rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, @@ -2673,6 +2719,8 @@ queue->do_pack = 0; queue->prev_hdr = NULL; queue->bulk_start = 0; + queue->bulk_count = 0; + queue->bulk_max = qeth_tx_select_bulk_max(card, queue); atomic_set(&queue->used_buffers, 0); atomic_set(&queue->set_pci_flags_count, 0); atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); @@ -3318,10 +3366,11 @@ static void qeth_flush_queue(struct qeth_qdio_out_q *queue) { - qeth_flush_buffers(queue, queue->bulk_start, 1); + qeth_flush_buffers(queue, queue->bulk_start, queue->bulk_count); - queue->bulk_start = QDIO_BUFNR(queue->bulk_start + 1); + queue->bulk_start = QDIO_BUFNR(queue->bulk_start + queue->bulk_count); queue->prev_hdr = NULL; + queue->bulk_count = 0; } static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) @@ -3382,11 +3431,6 @@ goto out; } - if (card->state != CARD_STATE_DOWN) { - rc = -1; - goto out; - } - qeth_free_qdio_queues(card); card->options.cq = cq; rc = 0; @@ -3680,10 +3724,10 @@ } static bool qeth_iqd_may_bulk(struct qeth_qdio_out_q *queue, - struct qeth_qdio_out_buffer *buffer, struct sk_buff *curr_skb, struct qeth_hdr *curr_hdr) { + struct qeth_qdio_out_buffer *buffer = queue->bufs[queue->bulk_start]; struct qeth_hdr *prev_hdr = queue->prev_hdr; if (!prev_hdr) @@ -3803,13 +3847,14 @@ struct qeth_hdr *hdr, unsigned int offset, unsigned int hd_len) { - struct qeth_qdio_out_buffer *buffer = queue->bufs[queue->bulk_start]; unsigned int bytes = qdisc_pkt_len(skb); + struct qeth_qdio_out_buffer *buffer; unsigned int next_element; struct netdev_queue *txq; bool stopped = false; bool flush; + buffer = queue->bufs[QDIO_BUFNR(queue->bulk_start + queue->bulk_count)]; txq = netdev_get_tx_queue(card->dev, skb_get_queue_mapping(skb)); /* Just a sanity check, the wake/stop logic should ensure that we always @@ -3818,11 +3863,23 @@ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) return -EBUSY; - if ((buffer->next_element_to_fill + elements > queue->max_elements) || - !qeth_iqd_may_bulk(queue, buffer, skb, hdr)) { - atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); - qeth_flush_queue(queue); - buffer = queue->bufs[queue->bulk_start]; + flush = !qeth_iqd_may_bulk(queue, skb, hdr); + + if (flush || + (buffer->next_element_to_fill + elements > queue->max_elements)) { + if (buffer->next_element_to_fill > 0) { + atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); + queue->bulk_count++; + } + + if (queue->bulk_count >= queue->bulk_max) + flush = true; + + if (flush) + qeth_flush_queue(queue); + + buffer = queue->bufs[QDIO_BUFNR(queue->bulk_start + + queue->bulk_count)]; /* Sanity-check again: */ if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) @@ -3848,7 +3905,13 @@ if (flush || next_element >= queue->max_elements) { atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); - qeth_flush_queue(queue); + queue->bulk_count++; + + if (queue->bulk_count >= queue->bulk_max) + flush = true; + + if (flush) + qeth_flush_queue(queue); } if (stopped && !qeth_out_queue_is_full(queue)) @@ -4137,9 +4200,6 @@ int fallback = *(int *)reply->param; QETH_CARD_TEXT(card, 4, "setaccb"); - if (cmd->hdr.return_code) - return -EIO; - qeth_setadpparms_inspect_rc(cmd); access_ctrl_req = &cmd->data.setadapterparms.data.set_access_ctrl; QETH_CARD_TEXT_(card, 2, "rc=%d", @@ -4149,7 +4209,7 @@ QETH_DBF_MESSAGE(3, "ERR:SET_ACCESS_CTRL(%#x) on device %x: %#x\n", access_ctrl_req->subcmd_code, CARD_DEVID(card), cmd->data.setadapterparms.hdr.return_code); - switch (cmd->data.setadapterparms.hdr.return_code) { + switch (qeth_setadpparms_inspect_rc(cmd)) { case SET_ACCESS_CTRL_RC_SUCCESS: if (card->options.isolation == ISOLATION_MODE_NONE) { dev_info(&card->gdev->dev, @@ -4634,12 +4694,12 @@ static void qeth_determine_capabilities(struct qeth_card *card) { + struct qeth_channel *channel = &card->data; + struct ccw_device *ddev = channel->ccwdev; int rc; - struct ccw_device *ddev; int ddev_offline = 0; QETH_CARD_TEXT(card, 2, "detcapab"); - ddev = CARD_DDEV(card); if (!ddev->online) { ddev_offline = 1; rc = ccw_device_set_online(ddev); @@ -4678,7 +4738,7 @@ out_offline: if (ddev_offline == 1) - ccw_device_set_offline(ddev); + qeth_stop_channel(channel); out: return; } @@ -4694,10 +4754,10 @@ if (card->options.cq == QETH_CQ_ENABLED) { int offset = QDIO_MAX_BUFFERS_PER_Q * (card->qdio.no_in_queues - 1); - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { - in_sbal_ptrs[offset + i] = (struct qdio_buffer *) - virt_to_phys(card->qdio.c_q->bufs[i].buffer); - } + + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) + in_sbal_ptrs[offset + i] = + card->qdio.c_q->bufs[i].buffer; queue_start_poll[card->qdio.no_in_queues - 1] = NULL; } @@ -4731,10 +4791,9 @@ rc = -ENOMEM; goto out_free_qib_param; } - for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i) { - in_sbal_ptrs[i] = (struct qdio_buffer *) - virt_to_phys(card->qdio.in_q->bufs[i].buffer); - } + + for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) + in_sbal_ptrs[i] = card->qdio.in_q->bufs[i].buffer; queue_start_poll = kcalloc(card->qdio.no_in_queues, sizeof(void *), GFP_KERNEL); @@ -4755,11 +4814,11 @@ rc = -ENOMEM; goto out_free_queue_start_poll; } + for (i = 0, k = 0; i < card->qdio.no_out_queues; ++i) - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k) { - out_sbal_ptrs[k] = (struct qdio_buffer *)virt_to_phys( - card->qdio.out_qs[i]->bufs[j]->buffer); - } + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++, k++) + out_sbal_ptrs[k] = + card->qdio.out_qs[i]->bufs[j]->buffer; memset(&init_data, 0, sizeof(struct qdio_initialize)); init_data.cdev = CARD_DDEV(card); @@ -4879,9 +4938,9 @@ QETH_DBF_MESSAGE(2, "Retrying to do IDX activates on device %x.\n", CARD_DEVID(card)); rc = qeth_qdio_clear_card(card, !IS_IQD(card)); - ccw_device_set_offline(CARD_DDEV(card)); - ccw_device_set_offline(CARD_WDEV(card)); - ccw_device_set_offline(CARD_RDEV(card)); + qeth_stop_channel(&card->data); + qeth_stop_channel(&card->write); + qeth_stop_channel(&card->read); qdio_free(CARD_DDEV(card)); rc = ccw_device_set_online(CARD_RDEV(card)); if (rc) @@ -4972,10 +5031,8 @@ } if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST)) { rc = qeth_query_setdiagass(card); - if (rc < 0) { + if (rc) QETH_CARD_TEXT_(card, 2, "8err%d", rc); - goto out; - } } return 0; out: @@ -5203,9 +5260,32 @@ if (atomic_cmpxchg(&buffer->state, QETH_QDIO_BUF_PRIMED, QETH_QDIO_BUF_PENDING) == - QETH_QDIO_BUF_PRIMED) + QETH_QDIO_BUF_PRIMED) { qeth_notify_skbs(queue, buffer, TX_NOTIFY_PENDING); + /* Handle race with qeth_qdio_handle_aob(): */ + switch (atomic_xchg(&buffer->state, + QETH_QDIO_BUF_NEED_QAOB)) { + case QETH_QDIO_BUF_PENDING: + /* No concurrent QAOB notification. */ + break; + case QETH_QDIO_BUF_QAOB_OK: + qeth_notify_skbs(queue, buffer, + TX_NOTIFY_DELAYED_OK); + atomic_set(&buffer->state, + QETH_QDIO_BUF_HANDLED_DELAYED); + break; + case QETH_QDIO_BUF_QAOB_ERROR: + qeth_notify_skbs(queue, buffer, + TX_NOTIFY_DELAYED_GENERALERROR); + atomic_set(&buffer->state, + QETH_QDIO_BUF_HANDLED_DELAYED); + break; + default: + WARN_ON_ONCE(1); + } + } + QETH_CARD_TEXT_(card, 5, "pel%u", bidx); /* prepare the queue slot for re-use: */ --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_core_mpc.h +++ linux-oracle-5.4.0/drivers/s390/net/qeth_core_mpc.h @@ -28,20 +28,6 @@ #define QETH_TIMEOUT (10 * HZ) #define QETH_IPA_TIMEOUT (45 * HZ) -#define QETH_CLEAR_CHANNEL_PARM -10 -#define QETH_HALT_CHANNEL_PARM -11 - -static inline bool qeth_intparm_is_iob(unsigned long intparm) -{ - switch (intparm) { - case QETH_CLEAR_CHANNEL_PARM: - case QETH_HALT_CHANNEL_PARM: - case 0: - return false; - } - return true; -} - /*****************************************************************************/ /* IP Assist related definitions */ /*****************************************************************************/ @@ -912,6 +898,11 @@ #define QETH_IDX_ACT_ERR_AUTH 0x1E #define QETH_IDX_ACT_ERR_AUTH_USER 0x20 +#define QETH_IDX_TERMINATE 0xc0 +#define QETH_IDX_TERMINATE_MASK 0xc0 +#define QETH_IDX_TERM_BAD_TRANSPORT 0x41 +#define QETH_IDX_TERM_BAD_TRANSPORT_VM 0xf6 + #define PDU_ENCAPSULATION(buffer) \ (buffer + *(buffer + (*(buffer + 0x0b)) + \ *(buffer + *(buffer + 0x0b) + 0x11) + 0x07)) --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_core_sys.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_core_sys.c @@ -227,7 +227,7 @@ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; } else if (sysfs_streq(buf, "prio_queueing_vlan")) { if (IS_LAYER3(card)) { - rc = -ENOTSUPP; + rc = -EOPNOTSUPP; goto out; } card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN; --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_l2_main.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_l2_main.c @@ -287,14 +287,15 @@ card->state = CARD_STATE_HARDSETUP; } if (card->state == CARD_STATE_HARDSETUP) { - qeth_qdio_clear_card(card, 0); qeth_drain_output_queues(card); qeth_clear_working_pool_list(card); card->state = CARD_STATE_DOWN; } + qeth_qdio_clear_card(card, 0); flush_workqueue(card->event_wq); card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; + card->info.promisc_mode = 0; } static int qeth_l2_process_inbound_buffer(struct qeth_card *card, @@ -876,9 +877,9 @@ out_remove: qeth_l2_stop_card(card); - ccw_device_set_offline(CARD_DDEV(card)); - ccw_device_set_offline(CARD_WDEV(card)); - ccw_device_set_offline(CARD_RDEV(card)); + qeth_stop_channel(&card->data); + qeth_stop_channel(&card->write); + qeth_stop_channel(&card->read); qdio_free(CARD_DDEV(card)); mutex_unlock(&card->conf_mutex); @@ -909,9 +910,9 @@ rtnl_unlock(); qeth_l2_stop_card(card); - rc = ccw_device_set_offline(CARD_DDEV(card)); - rc2 = ccw_device_set_offline(CARD_WDEV(card)); - rc3 = ccw_device_set_offline(CARD_RDEV(card)); + rc = qeth_stop_channel(&card->data); + rc2 = qeth_stop_channel(&card->write); + rc3 = qeth_stop_channel(&card->read); if (!rc) rc = (rc2) ? rc2 : rc3; if (rc) @@ -1167,12 +1168,6 @@ NULL }; - /* Role should not change by itself, but if it did, */ - /* information from the hardware is authoritative. */ - mutex_lock(&data->card->sbp_lock); - data->card->options.sbp.role = entry->role; - mutex_unlock(&data->card->sbp_lock); - snprintf(env_locrem, sizeof(env_locrem), "BRIDGEPORT=statechange"); snprintf(env_role, sizeof(env_role), "ROLE=%s", (entry->role == QETH_SBP_ROLE_NONE) ? "none" : @@ -1198,6 +1193,10 @@ int extrasize; QETH_CARD_TEXT(card, 2, "brstchng"); + if (qports->num_entries == 0) { + QETH_CARD_TEXT(card, 2, "BPempty"); + return; + } if (qports->entry_length != sizeof(struct qeth_sbp_port_entry)) { QETH_CARD_TEXT_(card, 2, "BPsz%04x", qports->entry_length); return; @@ -1845,15 +1844,14 @@ QETH_CARD_TEXT(card, 2, "vniccsch"); - /* do not change anything if BridgePort is enabled */ - if (qeth_bridgeport_is_in_use(card)) - return -EBUSY; - /* check if characteristic and enable/disable are supported */ if (!(card->options.vnicc.sup_chars & vnicc) || !(card->options.vnicc.set_char_sup & vnicc)) return -EOPNOTSUPP; + if (qeth_bridgeport_is_in_use(card)) + return -EBUSY; + /* set enable/disable command and store wanted characteristic */ if (state) { cmd = IPA_VNICC_ENABLE; @@ -1899,14 +1897,13 @@ QETH_CARD_TEXT(card, 2, "vniccgch"); - /* do not get anything if BridgePort is enabled */ - if (qeth_bridgeport_is_in_use(card)) - return -EBUSY; - /* check if characteristic is supported */ if (!(card->options.vnicc.sup_chars & vnicc)) return -EOPNOTSUPP; + if (qeth_bridgeport_is_in_use(card)) + return -EBUSY; + /* if card is ready, query current VNICC state */ if (qeth_card_hw_is_reachable(card)) rc = qeth_l2_vnicc_query_chars(card); @@ -1924,15 +1921,14 @@ QETH_CARD_TEXT(card, 2, "vniccsto"); - /* do not change anything if BridgePort is enabled */ - if (qeth_bridgeport_is_in_use(card)) - return -EBUSY; - /* check if characteristic and set_timeout are supported */ if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) return -EOPNOTSUPP; + if (qeth_bridgeport_is_in_use(card)) + return -EBUSY; + /* do we need to do anything? */ if (card->options.vnicc.learning_timeout == timeout) return rc; @@ -1961,14 +1957,14 @@ QETH_CARD_TEXT(card, 2, "vniccgto"); - /* do not get anything if BridgePort is enabled */ - if (qeth_bridgeport_is_in_use(card)) - return -EBUSY; - /* check if characteristic and get_timeout are supported */ if (!(card->options.vnicc.sup_chars & QETH_VNICC_LEARNING) || !(card->options.vnicc.getset_timeout_sup & QETH_VNICC_LEARNING)) return -EOPNOTSUPP; + + if (qeth_bridgeport_is_in_use(card)) + return -EBUSY; + /* if card is ready, get timeout. Otherwise, just return stored value */ *timeout = card->options.vnicc.learning_timeout; if (qeth_card_hw_is_reachable(card)) @@ -1982,8 +1978,7 @@ /* check if VNICC is currently enabled */ bool qeth_l2_vnicc_is_in_use(struct qeth_card *card) { - /* if everything is turned off, VNICC is not active */ - if (!card->options.vnicc.cur_chars) + if (!card->options.vnicc.sup_chars) return false; /* default values are only OK if rx_bcast was not enabled by user * or the card is offline. @@ -2070,8 +2065,9 @@ /* enforce assumed default values and recover settings, if changed */ error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, timeout); - chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT; - chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE; + /* Change chars, if necessary */ + chars_tmp = card->options.vnicc.wanted_chars ^ + card->options.vnicc.cur_chars; chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; for_each_set_bit(i, &chars_tmp, chars_len) { vnicc = BIT(i); --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_l2_sys.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_l2_sys.c @@ -279,7 +279,8 @@ return; mutex_lock(&card->sbp_lock); - if (card->options.sbp.role != QETH_SBP_ROLE_NONE) { + if (!card->options.sbp.reflect_promisc && + card->options.sbp.role != QETH_SBP_ROLE_NONE) { /* Conditional to avoid spurious error messages */ qeth_bridgeport_setrole(card, card->options.sbp.role); /* Let the callback function refresh the stored role value. */ --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_l3_main.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_l3_main.c @@ -305,9 +305,10 @@ if (!recover) { hash_del(&addr->hnode); kfree(addr); - continue; + } else { + /* prepare for recovery */ + addr->disp_flag = QETH_DISP_ADDR_ADD; } - addr->disp_flag = QETH_DISP_ADDR_ADD; } mutex_unlock(&card->ip_lock); @@ -335,11 +336,13 @@ } else rc = qeth_l3_register_addr_entry(card, addr); - if (!rc) { + if (!rc || rc == -EADDRINUSE || rc == -ENETDOWN) { + /* keep it in the records */ addr->disp_flag = QETH_DISP_ADDR_DO_NOTHING; if (addr->ref_counter < 1) qeth_l3_delete_ip(card, addr); } else { + /* bad address */ hash_del(&addr->hnode); kfree(addr); } @@ -1426,13 +1429,14 @@ card->state = CARD_STATE_HARDSETUP; } if (card->state == CARD_STATE_HARDSETUP) { - qeth_qdio_clear_card(card, 0); qeth_drain_output_queues(card); qeth_clear_working_pool_list(card); card->state = CARD_STATE_DOWN; } + qeth_qdio_clear_card(card, 0); flush_workqueue(card->event_wq); + card->info.promisc_mode = 0; } static void qeth_l3_set_promisc_mode(struct qeth_card *card) @@ -2113,7 +2117,7 @@ struct net_device *dev, netdev_features_t features) { - if (qeth_get_ip_version(skb) != 4) + if (vlan_get_protocol(skb) != htons(ETH_P_IP)) features &= ~NETIF_F_HW_VLAN_CTAG_TX; return qeth_features_check(skb, dev, features); } @@ -2382,9 +2386,9 @@ return 0; out_remove: qeth_l3_stop_card(card); - ccw_device_set_offline(CARD_DDEV(card)); - ccw_device_set_offline(CARD_WDEV(card)); - ccw_device_set_offline(CARD_RDEV(card)); + qeth_stop_channel(&card->data); + qeth_stop_channel(&card->write); + qeth_stop_channel(&card->read); qdio_free(CARD_DDEV(card)); mutex_unlock(&card->conf_mutex); @@ -2420,9 +2424,10 @@ call_netdevice_notifiers(NETDEV_REBOOT, card->dev); rtnl_unlock(); } - rc = ccw_device_set_offline(CARD_DDEV(card)); - rc2 = ccw_device_set_offline(CARD_WDEV(card)); - rc3 = ccw_device_set_offline(CARD_RDEV(card)); + + rc = qeth_stop_channel(&card->data); + rc2 = qeth_stop_channel(&card->write); + rc3 = qeth_stop_channel(&card->read); if (!rc) rc = (rc2) ? rc2 : rc3; if (rc) --- linux-oracle-5.4.0.orig/drivers/s390/net/qeth_l3_sys.c +++ linux-oracle-5.4.0/drivers/s390/net/qeth_l3_sys.c @@ -270,24 +270,36 @@ struct device_attribute *attr, const char *buf, size_t count) { struct qeth_card *card = dev_get_drvdata(dev); + int rc = 0; char *tmp; - int rc; if (!card) return -EINVAL; if (!IS_IQD(card)) return -EPERM; - if (card->state != CARD_STATE_DOWN) - return -EPERM; - if (card->options.sniffer) - return -EPERM; - if (card->options.cq == QETH_CQ_NOTAVAILABLE) - return -EPERM; + + mutex_lock(&card->conf_mutex); + if (card->state != CARD_STATE_DOWN) { + rc = -EPERM; + goto out; + } + + if (card->options.sniffer) { + rc = -EPERM; + goto out; + } + + if (card->options.cq == QETH_CQ_NOTAVAILABLE) { + rc = -EPERM; + goto out; + } tmp = strsep((char **)&buf, "\n"); - if (strlen(tmp) > 8) - return -EINVAL; + if (strlen(tmp) > 8) { + rc = -EINVAL; + goto out; + } if (card->options.hsuid[0]) /* delete old ip address */ @@ -298,11 +310,13 @@ card->options.hsuid[0] = '\0'; memcpy(card->dev->perm_addr, card->options.hsuid, 9); qeth_configure_cq(card, QETH_CQ_DISABLED); - return count; + goto out; } - if (qeth_configure_cq(card, QETH_CQ_ENABLED)) - return -EPERM; + if (qeth_configure_cq(card, QETH_CQ_ENABLED)) { + rc = -EPERM; + goto out; + } snprintf(card->options.hsuid, sizeof(card->options.hsuid), "%-8s", tmp); @@ -311,6 +325,8 @@ rc = qeth_l3_modify_hsuid(card, true); +out: + mutex_unlock(&card->conf_mutex); return rc ? rc : count; } --- linux-oracle-5.4.0.orig/drivers/s390/scsi/Makefile +++ linux-oracle-5.4.0/drivers/s390/scsi/Makefile @@ -5,6 +5,6 @@ zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_dbf.o zfcp_erp.o \ zfcp_fc.o zfcp_fsf.o zfcp_qdio.o zfcp_scsi.o zfcp_sysfs.o \ - zfcp_unit.o + zfcp_unit.o zfcp_diag.o obj-$(CONFIG_ZFCP) += zfcp.o --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_aux.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_aux.c @@ -4,7 +4,7 @@ * * Module interface and handling of zfcp data structures. * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2020 */ /* @@ -25,6 +25,7 @@ * Martin Petermann * Sven Schuetz * Steffen Maier + * Benjamin Block */ #define KMSG_COMPONENT "zfcp" @@ -36,6 +37,7 @@ #include "zfcp_ext.h" #include "zfcp_fc.h" #include "zfcp_reqlist.h" +#include "zfcp_diag.h" #define ZFCP_BUS_ID_SIZE 20 @@ -356,6 +358,9 @@ adapter->erp_action.adapter = adapter; + if (zfcp_diag_adapter_setup(adapter)) + goto failed; + if (zfcp_qdio_setup(adapter)) goto failed; @@ -402,13 +407,15 @@ &zfcp_sysfs_adapter_attrs)) goto failed; + if (zfcp_diag_sysfs_setup(adapter)) + goto failed; + /* report size limit per scatter-gather segment */ adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; - if (!zfcp_scsi_adapter_register(adapter)) - return adapter; + return adapter; failed: zfcp_adapter_unregister(adapter); @@ -426,6 +433,7 @@ zfcp_fc_wka_ports_force_offline(adapter->gs); zfcp_scsi_adapter_unregister(adapter); + zfcp_diag_sysfs_destroy(adapter); sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); zfcp_erp_thread_kill(adapter); @@ -449,6 +457,7 @@ dev_set_drvdata(&adapter->ccw_device->dev, NULL); zfcp_fc_gs_destroy(adapter); zfcp_free_low_mem_buffers(adapter); + zfcp_diag_adapter_free(adapter); kfree(adapter->req_list); kfree(adapter->fc_stats); kfree(adapter->stats_reset_data); @@ -488,12 +497,12 @@ if (port) { put_device(&port->dev); retval = -EEXIST; - goto err_out; + goto err_put; } port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) - goto err_out; + goto err_put; rwlock_init(&port->unit_list_lock); INIT_LIST_HEAD(&port->unit_list); @@ -516,7 +525,7 @@ if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); - goto err_out; + goto err_put; } retval = -EINVAL; @@ -533,7 +542,8 @@ return port; -err_out: +err_put: zfcp_ccw_adapter_put(adapter); +err_out: return ERR_PTR(retval); } --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_dbf.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_dbf.c @@ -4,7 +4,7 @@ * * Debug traces for zfcp. * - * Copyright IBM Corp. 2002, 2018 + * Copyright IBM Corp. 2002, 2020 */ #define KMSG_COMPONENT "zfcp" @@ -95,11 +95,51 @@ memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); - if (q_head->fsf_command != FSF_QTCB_FCP_CMND) { - rec->pl_len = q_head->log_length; - zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, - rec->pl_len, "fsf_res", req->req_id); - } + rec->pl_len = q_head->log_length; + zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, + rec->pl_len, "fsf_res", req->req_id); + + debug_event(dbf->hba, level, rec, sizeof(*rec)); + spin_unlock_irqrestore(&dbf->hba_lock, flags); +} + +/** + * zfcp_dbf_hba_fsf_fces - trace event for fsf responses related to + * FC Endpoint Security (FCES) + * @tag: tag indicating which kind of FC Endpoint Security event has occurred + * @req: request for which a response was received + * @wwpn: remote port or ZFCP_DBF_INVALID_WWPN + * @fc_security_old: old FC Endpoint Security of FCP device or connection + * @fc_security_new: new FC Endpoint Security of FCP device or connection + */ +void zfcp_dbf_hba_fsf_fces(char *tag, const struct zfcp_fsf_req *req, u64 wwpn, + u32 fc_security_old, u32 fc_security_new) +{ + struct zfcp_dbf *dbf = req->adapter->dbf; + struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; + struct fsf_qtcb_header *q_head = &req->qtcb->header; + struct zfcp_dbf_hba *rec = &dbf->hba_buf; + static int const level = 3; + unsigned long flags; + + if (unlikely(!debug_level_enabled(dbf->hba, level))) + return; + + spin_lock_irqsave(&dbf->hba_lock, flags); + memset(rec, 0, sizeof(*rec)); + + memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); + rec->id = ZFCP_DBF_HBA_FCES; + rec->fsf_req_id = req->req_id; + rec->fsf_req_status = req->status; + rec->fsf_cmd = q_head->fsf_command; + rec->fsf_seq_no = q_pref->req_seq_no; + rec->u.fces.req_issued = req->issued; + rec->u.fces.fsf_status = q_head->fsf_status; + rec->u.fces.port_handle = q_head->port_handle; + rec->u.fces.wwpn = wwpn; + rec->u.fces.fc_security_old = fc_security_old; + rec->u.fces.fc_security_new = fc_security_new; debug_event(dbf->hba, level, rec, sizeof(*rec)); spin_unlock_irqrestore(&dbf->hba_lock, flags); --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_dbf.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_dbf.h @@ -3,7 +3,7 @@ * zfcp device driver * debug feature declarations * - * Copyright IBM Corp. 2008, 2017 + * Copyright IBM Corp. 2008, 2020 */ #ifndef ZFCP_DBF_H @@ -16,6 +16,7 @@ #define ZFCP_DBF_TAG_LEN 7 +#define ZFCP_DBF_INVALID_WWPN 0x0000000000000000ull #define ZFCP_DBF_INVALID_LUN 0xFFFFFFFFFFFFFFFFull enum zfcp_dbf_pseudo_erp_act_type { @@ -158,17 +159,38 @@ } __packed; /** + * struct zfcp_dbf_hba_fces - trace record for FC Endpoint Security + * @req_issued: timestamp when request was issued + * @fsf_status: fsf status + * @port_handle: handle for port + * @wwpn: remote FC port WWPN + * @fc_security_old: old FC Endpoint Security + * @fc_security_new: new FC Endpoint Security + * + */ +struct zfcp_dbf_hba_fces { + u64 req_issued; + u32 fsf_status; + u32 port_handle; + u64 wwpn; + u32 fc_security_old; + u32 fc_security_new; +} __packed; + +/** * enum zfcp_dbf_hba_id - HBA trace record identifier * @ZFCP_DBF_HBA_RES: response trace record * @ZFCP_DBF_HBA_USS: unsolicited status trace record * @ZFCP_DBF_HBA_BIT: bit error trace record * @ZFCP_DBF_HBA_BASIC: basic adapter event, only trace tag, no other data + * @ZFCP_DBF_HBA_FCES: FC Endpoint Security trace record */ enum zfcp_dbf_hba_id { ZFCP_DBF_HBA_RES = 1, ZFCP_DBF_HBA_USS = 2, ZFCP_DBF_HBA_BIT = 3, ZFCP_DBF_HBA_BASIC = 4, + ZFCP_DBF_HBA_FCES = 5, }; /** @@ -181,9 +203,10 @@ * @fsf_seq_no: fsf sequence number * @pl_len: length of payload stored as zfcp_dbf_pay * @u: record type specific data - * @u.res: data for fsf responses - * @u.uss: data for unsolicited status buffer - * @u.be: data for bit error unsolicited status buffer + * @u.res: data for fsf responses + * @u.uss: data for unsolicited status buffer + * @u.be: data for bit error unsolicited status buffer + * @u.fces: data for FC Endpoint Security */ struct zfcp_dbf_hba { u8 id; @@ -197,6 +220,7 @@ struct zfcp_dbf_hba_res res; struct zfcp_dbf_hba_uss uss; struct fsf_bit_error_payload be; + struct zfcp_dbf_hba_fces fces; } u; } __packed; --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_def.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_def.h @@ -4,7 +4,7 @@ * * Global definitions for the zfcp device driver. * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2020 */ #ifndef ZFCP_DEF_H @@ -86,6 +86,7 @@ #define ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED 0x00000080 #define ZFCP_STATUS_FSFREQ_TMFUNCFAILED 0x00000200 #define ZFCP_STATUS_FSFREQ_DISMISSED 0x00001000 +#define ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE 0x00020000 /************************* STRUCTURE DEFINITIONS *****************************/ @@ -157,6 +158,8 @@ u32 adapter_features; /* FCP channel features */ u32 connection_features; /* host connection features */ u32 hardware_version; /* of FCP channel */ + u32 fc_security_algorithms; /* of FCP channel */ + u32 fc_security_algorithms_old; /* of FCP channel */ u16 timer_ticks; /* time int for a tick */ struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ struct list_head port_list; /* remote port list */ @@ -197,6 +200,7 @@ struct device_dma_parameters dma_parms; struct zfcp_fc_events events; unsigned long next_port_scan; + struct zfcp_diag_adapter *diagnostics; }; struct zfcp_port { @@ -216,6 +220,8 @@ atomic_t erp_counter; u32 maxframe_size; u32 supported_classes; + u32 connection_info; + u32 connection_info_old; struct work_struct gid_pn_work; struct work_struct test_link_work; struct work_struct rport_work; --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_diag.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_diag.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * zfcp device driver + * + * Functions to handle diagnostics. + * + * Copyright IBM Corp. 2018 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "zfcp_diag.h" +#include "zfcp_ext.h" +#include "zfcp_def.h" + +static DECLARE_WAIT_QUEUE_HEAD(__zfcp_diag_publish_wait); + +/** + * zfcp_diag_adapter_setup() - Setup storage for adapter diagnostics. + * @adapter: the adapter to setup diagnostics for. + * + * Creates the data-structures to store the diagnostics for an adapter. This + * overwrites whatever was stored before at &zfcp_adapter->diagnostics! + * + * Return: + * * 0 - Everyting is OK + * * -ENOMEM - Could not allocate all/parts of the data-structures; + * &zfcp_adapter->diagnostics remains unchanged + */ +int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter) +{ + struct zfcp_diag_adapter *diag; + struct zfcp_diag_header *hdr; + + diag = kzalloc(sizeof(*diag), GFP_KERNEL); + if (diag == NULL) + return -ENOMEM; + + diag->max_age = (5 * 1000); /* default value: 5 s */ + + /* setup header for port_data */ + hdr = &diag->port_data.header; + + spin_lock_init(&hdr->access_lock); + hdr->buffer = &diag->port_data.data; + hdr->buffer_size = sizeof(diag->port_data.data); + /* set the timestamp so that the first test on age will always fail */ + hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age); + + /* setup header for config_data */ + hdr = &diag->config_data.header; + + spin_lock_init(&hdr->access_lock); + hdr->buffer = &diag->config_data.data; + hdr->buffer_size = sizeof(diag->config_data.data); + /* set the timestamp so that the first test on age will always fail */ + hdr->timestamp = jiffies - msecs_to_jiffies(diag->max_age); + + adapter->diagnostics = diag; + return 0; +} + +/** + * zfcp_diag_adapter_free() - Frees all adapter diagnostics allocations. + * @adapter: the adapter whose diagnostic structures should be freed. + * + * Frees all data-structures in the given adapter that store diagnostics + * information. Can savely be called with partially setup diagnostics. + */ +void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter) +{ + kfree(adapter->diagnostics); + adapter->diagnostics = NULL; +} + +/** + * zfcp_diag_sysfs_setup() - Setup the sysfs-group for adapter-diagnostics. + * @adapter: target adapter to which the group should be added. + * + * Return: 0 on success; Something else otherwise (see sysfs_create_group()). + */ +int zfcp_diag_sysfs_setup(struct zfcp_adapter *const adapter) +{ + int rc = sysfs_create_group(&adapter->ccw_device->dev.kobj, + &zfcp_sysfs_diag_attr_group); + if (rc == 0) + adapter->diagnostics->sysfs_established = 1; + + return rc; +} + +/** + * zfcp_diag_sysfs_destroy() - Remove the sysfs-group for adapter-diagnostics. + * @adapter: target adapter from which the group should be removed. + */ +void zfcp_diag_sysfs_destroy(struct zfcp_adapter *const adapter) +{ + if (adapter->diagnostics == NULL || + !adapter->diagnostics->sysfs_established) + return; + + /* + * We need this state-handling so we can prevent warnings being printed + * on the kernel-console in case we have to abort a halfway done + * zfcp_adapter_enqueue(), in which the sysfs-group was not yet + * established. sysfs_remove_group() does this checking as well, but + * still prints a warning in case we try to remove a group that has not + * been established before + */ + adapter->diagnostics->sysfs_established = 0; + sysfs_remove_group(&adapter->ccw_device->dev.kobj, + &zfcp_sysfs_diag_attr_group); +} + + +/** + * zfcp_diag_update_xdata() - Update a diagnostics buffer. + * @hdr: the meta data to update. + * @data: data to use for the update. + * @incomplete: flag stating whether the data in @data is incomplete. + */ +void zfcp_diag_update_xdata(struct zfcp_diag_header *const hdr, + const void *const data, const bool incomplete) +{ + const unsigned long capture_timestamp = jiffies; + unsigned long flags; + + spin_lock_irqsave(&hdr->access_lock, flags); + + /* make sure we never go into the past with an update */ + if (!time_after_eq(capture_timestamp, hdr->timestamp)) + goto out; + + hdr->timestamp = capture_timestamp; + hdr->incomplete = incomplete; + memcpy(hdr->buffer, data, hdr->buffer_size); +out: + spin_unlock_irqrestore(&hdr->access_lock, flags); +} + +/** + * zfcp_diag_update_port_data_buffer() - Implementation of + * &typedef zfcp_diag_update_buffer_func + * to collect and update Port Data. + * @adapter: Adapter to collect Port Data from. + * + * This call is SYNCHRONOUS ! It blocks till the respective command has + * finished completely, or has failed in some way. + * + * Return: + * * 0 - Successfully retrieved new Diagnostics and Updated the buffer; + * this also includes cases where data was retrieved, but + * incomplete; you'll have to check the flag ``incomplete`` + * of &struct zfcp_diag_header. + * * see zfcp_fsf_exchange_port_data_sync() for possible error-codes ( + * excluding -EAGAIN) + */ +int zfcp_diag_update_port_data_buffer(struct zfcp_adapter *const adapter) +{ + int rc; + + rc = zfcp_fsf_exchange_port_data_sync(adapter->qdio, NULL); + if (rc == -EAGAIN) + rc = 0; /* signaling incomplete via struct zfcp_diag_header */ + + /* buffer-data was updated in zfcp_fsf_exchange_port_data_handler() */ + + return rc; +} + +/** + * zfcp_diag_update_config_data_buffer() - Implementation of + * &typedef zfcp_diag_update_buffer_func + * to collect and update Config Data. + * @adapter: Adapter to collect Config Data from. + * + * This call is SYNCHRONOUS ! It blocks till the respective command has + * finished completely, or has failed in some way. + * + * Return: + * * 0 - Successfully retrieved new Diagnostics and Updated the buffer; + * this also includes cases where data was retrieved, but + * incomplete; you'll have to check the flag ``incomplete`` + * of &struct zfcp_diag_header. + * * see zfcp_fsf_exchange_config_data_sync() for possible error-codes ( + * excluding -EAGAIN) + */ +int zfcp_diag_update_config_data_buffer(struct zfcp_adapter *const adapter) +{ + int rc; + + rc = zfcp_fsf_exchange_config_data_sync(adapter->qdio, NULL); + if (rc == -EAGAIN) + rc = 0; /* signaling incomplete via struct zfcp_diag_header */ + + /* buffer-data was updated in zfcp_fsf_exchange_config_data_handler() */ + + return rc; +} + +static int __zfcp_diag_update_buffer(struct zfcp_adapter *const adapter, + struct zfcp_diag_header *const hdr, + zfcp_diag_update_buffer_func buffer_update, + unsigned long *const flags) + __must_hold(hdr->access_lock) +{ + int rc; + + if (hdr->updating == 1) { + rc = wait_event_interruptible_lock_irq(__zfcp_diag_publish_wait, + hdr->updating == 0, + hdr->access_lock); + rc = (rc == 0 ? -EAGAIN : -EINTR); + } else { + hdr->updating = 1; + spin_unlock_irqrestore(&hdr->access_lock, *flags); + + /* unlocked, because update function sleeps */ + rc = buffer_update(adapter); + + spin_lock_irqsave(&hdr->access_lock, *flags); + hdr->updating = 0; + + /* + * every thread waiting here went via an interruptible wait, + * so its fine to only wake those + */ + wake_up_interruptible_all(&__zfcp_diag_publish_wait); + } + + return rc; +} + +static bool +__zfcp_diag_test_buffer_age_isfresh(const struct zfcp_diag_adapter *const diag, + const struct zfcp_diag_header *const hdr) + __must_hold(hdr->access_lock) +{ + const unsigned long now = jiffies; + + /* + * Should not happen (data is from the future).. if it does, still + * signal that it needs refresh + */ + if (!time_after_eq(now, hdr->timestamp)) + return false; + + if (jiffies_to_msecs(now - hdr->timestamp) >= diag->max_age) + return false; + + return true; +} + +/** + * zfcp_diag_update_buffer_limited() - Collect diagnostics and update a + * diagnostics buffer rate limited. + * @adapter: Adapter to collect the diagnostics from. + * @hdr: buffer-header for which to update with the collected diagnostics. + * @buffer_update: Specific implementation for collecting and updating. + * + * This function will cause an update of the given @hdr by calling the also + * given @buffer_update function. If called by multiple sources at the same + * time, it will synchornize the update by only allowing one source to call + * @buffer_update and the others to wait for that source to complete instead + * (the wait is interruptible). + * + * Additionally this version is rate-limited and will only exit if either the + * buffer is fresh enough (within the limit) - it will do nothing if the buffer + * is fresh enough to begin with -, or if the source/thread that started this + * update is the one that made the update (to prevent endless loops). + * + * Return: + * * 0 - If the update was successfully published and/or the buffer is + * fresh enough + * * -EINTR - If the thread went into the wait-state and was interrupted + * * whatever @buffer_update returns + */ +int zfcp_diag_update_buffer_limited(struct zfcp_adapter *const adapter, + struct zfcp_diag_header *const hdr, + zfcp_diag_update_buffer_func buffer_update) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(&hdr->access_lock, flags); + + for (rc = 0; + !__zfcp_diag_test_buffer_age_isfresh(adapter->diagnostics, hdr); + rc = 0) { + rc = __zfcp_diag_update_buffer(adapter, hdr, buffer_update, + &flags); + if (rc != -EAGAIN) + break; + } + + spin_unlock_irqrestore(&hdr->access_lock, flags); + + return rc; +} --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_diag.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_diag.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * zfcp device driver + * + * Definitions for handling diagnostics in the the zfcp device driver. + * + * Copyright IBM Corp. 2018, 2020 + */ + +#ifndef ZFCP_DIAG_H +#define ZFCP_DIAG_H + +#include + +#include "zfcp_fsf.h" +#include "zfcp_def.h" + +/** + * struct zfcp_diag_header - general part of a diagnostic buffer. + * @access_lock: lock protecting all the data in this buffer. + * @updating: flag showing that an update for this buffer is currently running. + * @incomplete: flag showing that the data in @buffer is incomplete. + * @timestamp: time in jiffies when the data of this buffer was last captured. + * @buffer: implementation-depending data of this buffer + * @buffer_size: size of @buffer + */ +struct zfcp_diag_header { + spinlock_t access_lock; + + /* Flags */ + u64 updating :1; + u64 incomplete :1; + + unsigned long timestamp; + + void *buffer; + size_t buffer_size; +}; + +/** + * struct zfcp_diag_adapter - central storage for all diagnostics concerning an + * adapter. + * @sysfs_established: flag showing that the associated sysfs-group was created + * during run of zfcp_adapter_enqueue(). + * @max_age: maximum age of data in diagnostic buffers before they need to be + * refreshed (in ms). + * @port_data: data retrieved using exchange port data. + * @port_data.header: header with metadata for the cache in @port_data.data. + * @port_data.data: cached QTCB Bottom of command exchange port data. + * @config_data: data retrieved using exchange config data. + * @config_data.header: header with metadata for the cache in @config_data.data. + * @config_data.data: cached QTCB Bottom of command exchange config data. + */ +struct zfcp_diag_adapter { + u64 sysfs_established :1; + + unsigned long max_age; + + struct zfcp_diag_adapter_port_data { + struct zfcp_diag_header header; + struct fsf_qtcb_bottom_port data; + } port_data; + struct zfcp_diag_adapter_config_data { + struct zfcp_diag_header header; + struct fsf_qtcb_bottom_config data; + } config_data; +}; + +int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter); +void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter); + +int zfcp_diag_sysfs_setup(struct zfcp_adapter *const adapter); +void zfcp_diag_sysfs_destroy(struct zfcp_adapter *const adapter); + +void zfcp_diag_update_xdata(struct zfcp_diag_header *const hdr, + const void *const data, const bool incomplete); + +/* + * Function-Type used in zfcp_diag_update_buffer_limited() for the function + * that does the buffer-implementation dependent work. + */ +typedef int (*zfcp_diag_update_buffer_func)(struct zfcp_adapter *const adapter); + +int zfcp_diag_update_config_data_buffer(struct zfcp_adapter *const adapter); +int zfcp_diag_update_port_data_buffer(struct zfcp_adapter *const adapter); +int zfcp_diag_update_buffer_limited(struct zfcp_adapter *const adapter, + struct zfcp_diag_header *const hdr, + zfcp_diag_update_buffer_func buffer_update); + +/** + * zfcp_diag_support_sfp() - Return %true if the @adapter supports reporting + * SFP Data. + * @adapter: adapter to test the availability of SFP Data reporting for. + */ +static inline bool +zfcp_diag_support_sfp(const struct zfcp_adapter *const adapter) +{ + return !!(adapter->adapter_features & FSF_FEATURE_REPORT_SFP_DATA); +} + +#endif /* ZFCP_DIAG_H */ --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_erp.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_erp.c @@ -4,7 +4,7 @@ * * Error Recovery Procedures (ERP). * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2020 */ #define KMSG_COMPONENT "zfcp" @@ -14,6 +14,7 @@ #include #include "zfcp_ext.h" #include "zfcp_reqlist.h" +#include "zfcp_diag.h" #define ZFCP_MAX_ERPS 3 @@ -174,29 +175,29 @@ return 0; p_status = atomic_read(&port->status); if (!(p_status & ZFCP_STATUS_COMMON_RUNNING) || - p_status & ZFCP_STATUS_COMMON_ERP_FAILED) + p_status & ZFCP_STATUS_COMMON_ERP_FAILED) return 0; if (!(p_status & ZFCP_STATUS_COMMON_UNBLOCKED)) need = ZFCP_ERP_ACTION_REOPEN_PORT; - /* fall through */ + fallthrough; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: p_status = atomic_read(&port->status); if (!(p_status & ZFCP_STATUS_COMMON_OPEN)) need = ZFCP_ERP_ACTION_REOPEN_PORT; - /* fall through */ + fallthrough; case ZFCP_ERP_ACTION_REOPEN_PORT: p_status = atomic_read(&port->status); if (p_status & ZFCP_STATUS_COMMON_ERP_INUSE) return 0; a_status = atomic_read(&adapter->status); if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || - a_status & ZFCP_STATUS_COMMON_ERP_FAILED) + a_status & ZFCP_STATUS_COMMON_ERP_FAILED) return 0; if (p_status & ZFCP_STATUS_COMMON_NOESC) return need; if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; - /* fall through */ + fallthrough; case ZFCP_ERP_ACTION_REOPEN_ADAPTER: a_status = atomic_read(&adapter->status); if (a_status & ZFCP_STATUS_COMMON_ERP_INUSE) @@ -576,7 +577,10 @@ ZFCP_STATUS_ERP_TIMEDOUT)) { req->status |= ZFCP_STATUS_FSFREQ_DISMISSED; zfcp_dbf_rec_run("erscf_1", act); - req->erp_action = NULL; + /* lock-free concurrent access with + * zfcp_erp_timeout_handler() + */ + WRITE_ONCE(req->erp_action, NULL); } if (act->status & ZFCP_STATUS_ERP_TIMEDOUT) zfcp_dbf_rec_run("erscf_2", act); @@ -612,8 +616,14 @@ void zfcp_erp_timeout_handler(struct timer_list *t) { struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); - struct zfcp_erp_action *act = fsf_req->erp_action; + struct zfcp_erp_action *act; + if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) + return; + /* lock-free concurrent access with zfcp_erp_strategy_check_fsfreq() */ + act = READ_ONCE(fsf_req->erp_action); + if (!act) + return; zfcp_erp_notify(act, ZFCP_STATUS_ERP_TIMEDOUT); } @@ -725,7 +735,7 @@ adapter->peer_d_id); if (IS_ERR(port)) /* error or port already attached */ return; - _zfcp_erp_port_reopen(port, 0, "ereptp1"); + zfcp_erp_port_reopen(port, 0, "ereptp1"); } static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf( @@ -768,10 +778,14 @@ if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_XCONFIG_OK)) return ZFCP_ERP_FAILED; + return ZFCP_ERP_SUCCEEDED; +} + +static void +zfcp_erp_adapter_strategy_open_ptp_port(struct zfcp_adapter *const adapter) +{ if (fc_host_port_type(adapter->scsi_host) == FC_PORTTYPE_PTP) zfcp_erp_enqueue_ptp_port(adapter); - - return ZFCP_ERP_SUCCEEDED; } static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf_xport( @@ -800,6 +814,59 @@ return ZFCP_ERP_SUCCEEDED; } +static enum zfcp_erp_act_result +zfcp_erp_adapter_strategy_alloc_shost(struct zfcp_adapter *const adapter) +{ + struct zfcp_diag_adapter_config_data *const config_data = + &adapter->diagnostics->config_data; + struct zfcp_diag_adapter_port_data *const port_data = + &adapter->diagnostics->port_data; + unsigned long flags; + int rc; + + rc = zfcp_scsi_adapter_register(adapter); + if (rc == -EEXIST) + return ZFCP_ERP_SUCCEEDED; + else if (rc) + return ZFCP_ERP_FAILED; + + /* + * We allocated the shost for the first time. Before it was NULL, + * and so we deferred all updates in the xconf- and xport-data + * handlers. We need to make up for that now, and make all the updates + * that would have been done before. + * + * We can be sure that xconf- and xport-data succeeded, because + * otherwise this function is not called. But they might have been + * incomplete. + */ + + spin_lock_irqsave(&config_data->header.access_lock, flags); + zfcp_scsi_shost_update_config_data(adapter, &config_data->data, + !!config_data->header.incomplete); + spin_unlock_irqrestore(&config_data->header.access_lock, flags); + + if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { + spin_lock_irqsave(&port_data->header.access_lock, flags); + zfcp_scsi_shost_update_port_data(adapter, &port_data->data); + spin_unlock_irqrestore(&port_data->header.access_lock, flags); + } + + /* + * There is a remote possibility that the 'Exchange Port Data' request + * reports a different connectivity status than 'Exchange Config Data'. + * But any change to the connectivity status of the local optic that + * happens after the initial xconf request is expected to be reported + * to us, as soon as we post Status Read Buffers to the FCP channel + * firmware after this function. So any resulting inconsistency will + * only be momentary. + */ + if (config_data->header.incomplete) + zfcp_fsf_fc_host_link_down(adapter); + + return ZFCP_ERP_SUCCEEDED; +} + static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf( struct zfcp_erp_action *act) { @@ -809,6 +876,12 @@ if (zfcp_erp_adapter_strategy_open_fsf_xport(act) == ZFCP_ERP_FAILED) return ZFCP_ERP_FAILED; + if (zfcp_erp_adapter_strategy_alloc_shost(act->adapter) == + ZFCP_ERP_FAILED) + return ZFCP_ERP_FAILED; + + zfcp_erp_adapter_strategy_open_ptp_port(act->adapter); + if (mempool_resize(act->adapter->pool.sr_data, act->adapter->stat_read_buf_num)) return ZFCP_ERP_FAILED; @@ -1086,7 +1159,7 @@ if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) return zfcp_erp_lun_strategy_close(erp_action); /* already closed */ - /* fall through */ + fallthrough; case ZFCP_ERP_STEP_LUN_CLOSING: if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) return ZFCP_ERP_FAILED; @@ -1415,7 +1488,7 @@ if (act->step != ZFCP_ERP_STEP_UNINITIALIZED) if (result == ZFCP_ERP_SUCCEEDED) zfcp_erp_try_rport_unblock(port); - /* fall through */ + fallthrough; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: put_device(&port->dev); break; @@ -1636,6 +1709,13 @@ atomic_or(common_mask, &port->status); read_unlock_irqrestore(&adapter->port_list_lock, flags); + /* + * if `scsi_host` is missing, xconfig/xport data has never completed + * yet, so we can't access it, but there are also no SDEVs yet + */ + if (adapter->scsi_host == NULL) + return; + spin_lock_irqsave(adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, adapter->scsi_host) atomic_or(common_mask, &sdev_to_zfcp(sdev)->status); @@ -1673,6 +1753,13 @@ } read_unlock_irqrestore(&adapter->port_list_lock, flags); + /* + * if `scsi_host` is missing, xconfig/xport data has never completed + * yet, so we can't access it, but there are also no SDEVs yet + */ + if (adapter->scsi_host == NULL) + return; + spin_lock_irqsave(adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, adapter->scsi_host) { atomic_andnot(common_mask, &sdev_to_zfcp(sdev)->status); --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_ext.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_ext.h @@ -4,7 +4,7 @@ * * External function declarations. * - * Copyright IBM Corp. 2002, 2018 + * Copyright IBM Corp. 2002, 2020 */ #ifndef ZFCP_EXT_H @@ -44,6 +44,9 @@ extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64); extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *); +extern void zfcp_dbf_hba_fsf_fces(char *tag, const struct zfcp_fsf_req *req, + u64 wwpn, u32 fc_security_old, + u32 fc_security_new); extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **); extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *); @@ -122,6 +125,7 @@ extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *); extern int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *, struct fsf_qtcb_bottom_port *); +extern u32 zfcp_fsf_convert_portspeed(u32 fsf_speed); extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); extern int zfcp_fsf_status_read(struct zfcp_qdio *); extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); @@ -131,10 +135,18 @@ struct zfcp_fsf_ct_els *, unsigned int); extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *); extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); +extern void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter); extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev, u8 tm_flags); extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *); extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int); +enum zfcp_fsf_print_fmt { + ZFCP_FSF_PRINT_FMT_LIST, + ZFCP_FSF_PRINT_FMT_SINGLEITEM, +}; +extern ssize_t zfcp_fsf_scnprint_fc_security(char *buf, size_t size, + u32 fc_security, + enum zfcp_fsf_print_fmt fmt); /* zfcp_qdio.c */ extern int zfcp_qdio_setup(struct zfcp_adapter *); @@ -143,6 +155,8 @@ extern int zfcp_qdio_send(struct zfcp_qdio *, struct zfcp_qdio_req *); extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *, struct scatterlist *); +extern void zfcp_qdio_shost_update(struct zfcp_adapter *const adapter, + const struct zfcp_qdio *const qdio); extern int zfcp_qdio_open(struct zfcp_qdio *); extern void zfcp_qdio_close(struct zfcp_qdio *); extern void zfcp_qdio_siosl(struct zfcp_adapter *); @@ -159,6 +173,13 @@ extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *); extern void zfcp_scsi_set_prot(struct zfcp_adapter *); extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); +extern void zfcp_scsi_shost_update_config_data( + struct zfcp_adapter *const adapter, + const struct fsf_qtcb_bottom_config *const bottom, + const bool bottom_incomplete); +extern void zfcp_scsi_shost_update_port_data( + struct zfcp_adapter *const adapter, + const struct fsf_qtcb_bottom_port *const bottom); /* zfcp_sysfs.c */ extern const struct attribute_group *zfcp_unit_attr_groups[]; @@ -167,6 +188,7 @@ extern struct mutex zfcp_sysfs_port_units_mutex; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; +extern const struct attribute_group zfcp_sysfs_diag_attr_group; bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port); /* zfcp_unit.c */ --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_fc.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_fc.c @@ -145,27 +145,33 @@ static int zfcp_fc_wka_port_get(struct zfcp_fc_wka_port *wka_port) { + int ret = -EIO; + if (mutex_lock_interruptible(&wka_port->mutex)) return -ERESTARTSYS; if (wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE || wka_port->status == ZFCP_FC_WKA_PORT_CLOSING) { wka_port->status = ZFCP_FC_WKA_PORT_OPENING; - if (zfcp_fsf_open_wka_port(wka_port)) + if (zfcp_fsf_open_wka_port(wka_port)) { + /* could not even send request, nothing to wait for */ wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; + goto out; + } } - mutex_unlock(&wka_port->mutex); - - wait_event(wka_port->completion_wq, + wait_event(wka_port->opened, wka_port->status == ZFCP_FC_WKA_PORT_ONLINE || wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE); if (wka_port->status == ZFCP_FC_WKA_PORT_ONLINE) { atomic_inc(&wka_port->refcount); - return 0; + ret = 0; + goto out; } - return -EIO; +out: + mutex_unlock(&wka_port->mutex); + return ret; } static void zfcp_fc_wka_port_offline(struct work_struct *work) @@ -181,9 +187,12 @@ wka_port->status = ZFCP_FC_WKA_PORT_CLOSING; if (zfcp_fsf_close_wka_port(wka_port)) { + /* could not even send request, nothing to wait for */ wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; - wake_up(&wka_port->completion_wq); + goto out; } + wait_event(wka_port->closed, + wka_port->status == ZFCP_FC_WKA_PORT_OFFLINE); out: mutex_unlock(&wka_port->mutex); } @@ -193,13 +202,15 @@ if (atomic_dec_return(&wka_port->refcount) != 0) return; /* wait 10 milliseconds, other reqs might pop in */ - schedule_delayed_work(&wka_port->work, HZ / 100); + queue_delayed_work(wka_port->adapter->work_queue, &wka_port->work, + msecs_to_jiffies(10)); } static void zfcp_fc_wka_port_init(struct zfcp_fc_wka_port *wka_port, u32 d_id, struct zfcp_adapter *adapter) { - init_waitqueue_head(&wka_port->completion_wq); + init_waitqueue_head(&wka_port->opened); + init_waitqueue_head(&wka_port->closed); wka_port->adapter = adapter; wka_port->d_id = d_id; @@ -521,8 +532,9 @@ goto out; } - /* port is good, unblock rport without going through erp */ - zfcp_scsi_schedule_rport_register(port); + /* re-init to undo drop from zfcp_fc_adisc() */ + port->d_id = ntoh24(adisc_resp->adisc_port_id); + /* port is still good, nothing to do */ out: atomic_andnot(ZFCP_STATUS_PORT_LINK_TEST, &port->status); put_device(&port->dev); @@ -534,6 +546,7 @@ struct zfcp_fc_req *fc_req; struct zfcp_adapter *adapter = port->adapter; struct Scsi_Host *shost = adapter->scsi_host; + u32 d_id; int ret; fc_req = kmem_cache_zalloc(zfcp_fc_req_cache, GFP_ATOMIC); @@ -558,7 +571,15 @@ fc_req->u.adisc.req.adisc_cmd = ELS_ADISC; hton24(fc_req->u.adisc.req.adisc_port_id, fc_host_port_id(shost)); - ret = zfcp_fsf_send_els(adapter, port->d_id, &fc_req->ct_els, + d_id = port->d_id; /* remember as destination for send els below */ + /* + * Force fresh GID_PN lookup on next port recovery. + * Must happen after request setup and before sending request, + * to prevent race with port->d_id re-init in zfcp_fc_adisc_handler(). + */ + port->d_id = 0; + + ret = zfcp_fsf_send_els(adapter, d_id, &fc_req->ct_els, ZFCP_FC_CTELS_TMO); if (ret) kmem_cache_free(zfcp_fc_req_cache, fc_req); @@ -573,9 +594,6 @@ int retval; set_worker_desc("zadisc%16llx", port->wwpn); /* < WORKER_DESC_LEN=24 */ - get_device(&port->dev); - port->rport_task = RPORT_DEL; - zfcp_scsi_rport_work(&port->rport_work); /* only issue one test command at one time per port */ if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_fc.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_fc.h @@ -185,7 +185,8 @@ /** * struct zfcp_fc_wka_port - representation of well-known-address (WKA) FC port * @adapter: Pointer to adapter structure this WKA port belongs to - * @completion_wq: Wait for completion of open/close command + * @opened: Wait for completion of open command + * @closed: Wait for completion of close command * @status: Current status of WKA port * @refcount: Reference count to keep port open as long as it is in use * @d_id: FC destination id or well-known-address @@ -195,7 +196,8 @@ */ struct zfcp_fc_wka_port { struct zfcp_adapter *adapter; - wait_queue_head_t completion_wq; + wait_queue_head_t opened; + wait_queue_head_t closed; enum zfcp_fc_wka_status status; atomic_t refcount; u32 d_id; --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_fsf.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_fsf.c @@ -4,13 +4,14 @@ * * Implementation of FSF commands. * - * Copyright IBM Corp. 2002, 2018 + * Copyright IBM Corp. 2002, 2020 */ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include @@ -19,6 +20,7 @@ #include "zfcp_dbf.h" #include "zfcp_qdio.h" #include "zfcp_reqlist.h" +#include "zfcp_diag.h" /* timeout for FSF requests sent during scsi_eh: abort or FCP TMF */ #define ZFCP_FSF_SCSI_ER_TIMEOUT (10*HZ) @@ -118,6 +120,27 @@ read_unlock_irqrestore(&adapter->port_list_lock, flags); } +void zfcp_fsf_fc_host_link_down(struct zfcp_adapter *adapter) +{ + struct Scsi_Host *shost = adapter->scsi_host; + + adapter->hydra_version = 0; + adapter->peer_wwpn = 0; + adapter->peer_wwnn = 0; + adapter->peer_d_id = 0; + + /* if there is no shost yet, we have nothing to zero-out */ + if (shost == NULL) + return; + + fc_host_port_id(shost) = 0; + fc_host_fabric_name(shost) = 0; + fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; + fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; + snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x", 0); + memset(fc_host_active_fc4s(shost), 0, FC_FC4_LIST_SIZE); +} + static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *req, struct fsf_link_down_info *link_down) { @@ -130,6 +153,8 @@ zfcp_scsi_schedule_rports_block(adapter); + zfcp_fsf_fc_host_link_down(adapter); + if (!link_down) goto out; @@ -409,7 +434,7 @@ return; } - del_timer(&req->timer); + del_timer_sync(&req->timer); zfcp_fsf_protstatus_eval(req); zfcp_fsf_fsfstatus_eval(req); req->handler(req); @@ -458,7 +483,7 @@ #define ZFCP_FSF_PORTSPEED_128GBIT (1 << 8) #define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15) -static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed) +u32 zfcp_fsf_convert_portspeed(u32 fsf_speed) { u32 fdmi_speed = 0; if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT) @@ -488,40 +513,24 @@ { struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config; struct zfcp_adapter *adapter = req->adapter; - struct Scsi_Host *shost = adapter->scsi_host; - struct fc_els_flogi *nsp, *plogi; + struct fc_els_flogi *plogi; /* adjust pointers for missing command code */ - nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param - - sizeof(u32)); plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload - sizeof(u32)); if (req->data) memcpy(req->data, bottom, sizeof(*bottom)); - fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn); - fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn); - fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; - adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)FSF_STATUS_READS_RECOM); - if (fc_host_permanent_port_name(shost) == -1) - fc_host_permanent_port_name(shost) = fc_host_port_name(shost); - - zfcp_scsi_set_prot(adapter); - /* no error return above here, otherwise must fix call chains */ /* do not evaluate invalid fields */ if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE) return 0; - fc_host_port_id(shost) = ntoh24(bottom->s_id); - fc_host_speed(shost) = - zfcp_fsf_convert_portspeed(bottom->fc_link_speed); - adapter->hydra_version = bottom->adapter_type; switch (bottom->fc_topology) { @@ -529,17 +538,10 @@ adapter->peer_d_id = ntoh24(bottom->peer_d_id); adapter->peer_wwpn = be64_to_cpu(plogi->fl_wwpn); adapter->peer_wwnn = be64_to_cpu(plogi->fl_wwnn); - fc_host_port_type(shost) = FC_PORTTYPE_PTP; break; case FSF_TOPO_FABRIC: - if (bottom->connection_features & FSF_FEATURE_NPIV_MODE) - fc_host_port_type(shost) = FC_PORTTYPE_NPIV; - else - fc_host_port_type(shost) = FC_PORTTYPE_NPORT; break; case FSF_TOPO_AL: - fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; - /* fall through */ default: dev_err(&adapter->ccw_device->dev, "Unknown or unsupported arbitrated loop " @@ -554,9 +556,10 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) { struct zfcp_adapter *adapter = req->adapter; + struct zfcp_diag_header *const diag_hdr = + &adapter->diagnostics->config_data.header; struct fsf_qtcb *qtcb = req->qtcb; struct fsf_qtcb_bottom_config *bottom = &qtcb->bottom.config; - struct Scsi_Host *shost = adapter->scsi_host; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; @@ -570,6 +573,13 @@ switch (qtcb->header.fsf_status) { case FSF_GOOD: + /* + * usually we wait with an update till the cache is too old, + * but because we have the data available, update it anyway + */ + zfcp_diag_update_xdata(diag_hdr, bottom, false); + + zfcp_scsi_shost_update_config_data(adapter, bottom, false); if (zfcp_fsf_exchange_config_evaluate(req)) return; @@ -585,12 +595,8 @@ &adapter->status); break; case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: - fc_host_node_name(shost) = 0; - fc_host_port_name(shost) = 0; - fc_host_port_id(shost) = 0; - fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; - fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; - adapter->hydra_version = 0; + zfcp_diag_update_xdata(diag_hdr, bottom, true); + req->status |= ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE; /* avoids adapter shutdown to be able to recognize * events such as LINK UP */ @@ -598,6 +604,8 @@ &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); + + zfcp_scsi_shost_update_config_data(adapter, bottom, true); if (zfcp_fsf_exchange_config_evaluate(req)) return; break; @@ -606,13 +614,8 @@ return; } - if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { + if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) adapter->hardware_version = bottom->hardware_version; - memcpy(fc_host_serial_number(shost), bottom->serial_number, - min(FC_SERIAL_NUMBER_SIZE, 17)); - EBCASC(fc_host_serial_number(shost), - min(FC_SERIAL_NUMBER_SIZE, 17)); - } if (FSF_QTCB_CURRENT_VERSION < bottom->low_qtcb_version) { dev_err(&adapter->ccw_device->dev, @@ -629,43 +632,145 @@ } } +/* + * Mapping of FC Endpoint Security flag masks to mnemonics + * + * NOTE: Update macro ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH when making any + * changes. + */ +static const struct { + u32 mask; + char *name; +} zfcp_fsf_fc_security_mnemonics[] = { + { FSF_FC_SECURITY_AUTH, "Authentication" }, + { FSF_FC_SECURITY_ENC_FCSP2 | + FSF_FC_SECURITY_ENC_ERAS, "Encryption" }, +}; + +/* maximum strlen(zfcp_fsf_fc_security_mnemonics[...].name) + 1 */ +#define ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH 15 + +/** + * zfcp_fsf_scnprint_fc_security() - translate FC Endpoint Security flags into + * mnemonics and place in a buffer + * @buf : the buffer to place the translated FC Endpoint Security flag(s) + * into + * @size : the size of the buffer, including the trailing null space + * @fc_security: one or more FC Endpoint Security flags, or zero + * @fmt : specifies whether a list or a single item is to be put into the + * buffer + * + * The Fibre Channel (FC) Endpoint Security flags are translated into mnemonics. + * If the FC Endpoint Security flags are zero "none" is placed into the buffer. + * + * With ZFCP_FSF_PRINT_FMT_LIST the mnemonics are placed as a list separated by + * a comma followed by a space into the buffer. If one or more FC Endpoint + * Security flags cannot be translated into a mnemonic, as they are undefined + * in zfcp_fsf_fc_security_mnemonics, their bitwise ORed value in hexadecimal + * representation is placed into the buffer. + * + * With ZFCP_FSF_PRINT_FMT_SINGLEITEM only one single mnemonic is placed into + * the buffer. If the FC Endpoint Security flag cannot be translated, as it is + * undefined in zfcp_fsf_fc_security_mnemonics, its value in hexadecimal + * representation is placed into the buffer. If more than one FC Endpoint + * Security flag was specified, their value in hexadecimal representation is + * placed into the buffer. The macro ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH + * can be used to define a buffer that is large enough to hold one mnemonic. + * + * Return: The number of characters written into buf not including the trailing + * '\0'. If size is == 0 the function returns 0. + */ +ssize_t zfcp_fsf_scnprint_fc_security(char *buf, size_t size, u32 fc_security, + enum zfcp_fsf_print_fmt fmt) +{ + const char *prefix = ""; + ssize_t len = 0; + int i; + + if (fc_security == 0) + return scnprintf(buf, size, "none"); + if (fmt == ZFCP_FSF_PRINT_FMT_SINGLEITEM && hweight32(fc_security) != 1) + return scnprintf(buf, size, "0x%08x", fc_security); + + for (i = 0; i < ARRAY_SIZE(zfcp_fsf_fc_security_mnemonics); i++) { + if (!(fc_security & zfcp_fsf_fc_security_mnemonics[i].mask)) + continue; + + len += scnprintf(buf + len, size - len, "%s%s", prefix, + zfcp_fsf_fc_security_mnemonics[i].name); + prefix = ", "; + fc_security &= ~zfcp_fsf_fc_security_mnemonics[i].mask; + } + + if (fc_security != 0) + len += scnprintf(buf + len, size - len, "%s0x%08x", + prefix, fc_security); + + return len; +} + +static void zfcp_fsf_dbf_adapter_fc_security(struct zfcp_adapter *adapter, + struct zfcp_fsf_req *req) +{ + if (adapter->fc_security_algorithms == + adapter->fc_security_algorithms_old) { + /* no change, no trace */ + return; + } + + zfcp_dbf_hba_fsf_fces("fsfcesa", req, ZFCP_DBF_INVALID_WWPN, + adapter->fc_security_algorithms_old, + adapter->fc_security_algorithms); + + adapter->fc_security_algorithms_old = adapter->fc_security_algorithms; +} + static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req) { struct zfcp_adapter *adapter = req->adapter; struct fsf_qtcb_bottom_port *bottom = &req->qtcb->bottom.port; - struct Scsi_Host *shost = adapter->scsi_host; if (req->data) memcpy(req->data, bottom, sizeof(*bottom)); - if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { - fc_host_permanent_port_name(shost) = bottom->wwpn; - } else - fc_host_permanent_port_name(shost) = fc_host_port_name(shost); - fc_host_maxframe_size(shost) = bottom->maximum_frame_size; - fc_host_supported_speeds(shost) = - zfcp_fsf_convert_portspeed(bottom->supported_speed); - memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types, - FC_FC4_LIST_SIZE); - memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types, - FC_FC4_LIST_SIZE); + if (adapter->adapter_features & FSF_FEATURE_FC_SECURITY) + adapter->fc_security_algorithms = + bottom->fc_security_algorithms; + else + adapter->fc_security_algorithms = 0; + zfcp_fsf_dbf_adapter_fc_security(adapter, req); } static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) { + struct zfcp_diag_header *const diag_hdr = + &req->adapter->diagnostics->port_data.header; struct fsf_qtcb *qtcb = req->qtcb; + struct fsf_qtcb_bottom_port *bottom = &qtcb->bottom.port; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) return; switch (qtcb->header.fsf_status) { case FSF_GOOD: + /* + * usually we wait with an update till the cache is too old, + * but because we have the data available, update it anyway + */ + zfcp_diag_update_xdata(diag_hdr, bottom, false); + + zfcp_scsi_shost_update_port_data(req->adapter, bottom); zfcp_fsf_exchange_port_evaluate(req); break; case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: - zfcp_fsf_exchange_port_evaluate(req); + zfcp_diag_update_xdata(diag_hdr, bottom, true); + req->status |= ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE; + zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); + + zfcp_scsi_shost_update_port_data(req->adapter, bottom); + zfcp_fsf_exchange_port_evaluate(req); break; } } @@ -755,14 +860,14 @@ const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req); struct zfcp_adapter *adapter = req->adapter; struct zfcp_qdio *qdio = adapter->qdio; - int req_id = req->req_id; + unsigned long req_id = req->req_id; zfcp_reqlist_add(adapter->req_list, req); req->qdio_req.qdio_outb_usage = atomic_read(&qdio->req_q_free); req->issued = get_tod_clock(); if (zfcp_qdio_send(qdio, &req->qdio_req)) { - del_timer(&req->timer); + del_timer_sync(&req->timer); /* lookup request again, list might have changed */ zfcp_reqlist_find_rm(adapter->req_list, req_id); zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1"); @@ -889,7 +994,7 @@ switch (fsq->word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: zfcp_fc_test_link(zfcp_sdev->port); - /* fall through */ + fallthrough; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -984,7 +1089,7 @@ break; case FSF_PORT_HANDLE_NOT_VALID: zfcp_erp_adapter_reopen(adapter, 0, "fsscth1"); - /* fall through */ + fallthrough; case FSF_GENERIC_COMMAND_REJECTED: case FSF_PAYLOAD_SIZE_MISMATCH: case FSF_REQUEST_SIZE_TOO_LARGE: @@ -1170,7 +1275,7 @@ break; case FSF_SBAL_MISMATCH: /* should never occur, avoided in zfcp_fsf_send_els */ - /* fall through */ + fallthrough; default: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1261,7 +1366,9 @@ req->qtcb->bottom.config.feature_selection = FSF_FEATURE_NOTIFICATION_LOST | - FSF_FEATURE_UPDATE_ALERT; + FSF_FEATURE_UPDATE_ALERT | + FSF_FEATURE_REQUEST_SFP_DATA | + FSF_FEATURE_FC_SECURITY; req->erp_action = erp_action; req->handler = zfcp_fsf_exchange_config_data_handler; erp_action->fsf_req_id = req->req_id; @@ -1278,6 +1385,19 @@ return retval; } + +/** + * zfcp_fsf_exchange_config_data_sync() - Request information about FCP channel. + * @qdio: pointer to the QDIO-Queue to use for sending the command. + * @data: pointer to the QTCB-Bottom for storing the result of the command, + * might be %NULL. + * + * Returns: + * * 0 - Exchange Config Data was successful, @data is complete + * * -EIO - Exchange Config Data was not successful, @data is invalid + * * -EAGAIN - @data contains incomplete data + * * -ENOMEM - Some memory allocation failed along the way + */ int zfcp_fsf_exchange_config_data_sync(struct zfcp_qdio *qdio, struct fsf_qtcb_bottom_config *data) { @@ -1301,7 +1421,9 @@ req->qtcb->bottom.config.feature_selection = FSF_FEATURE_NOTIFICATION_LOST | - FSF_FEATURE_UPDATE_ALERT; + FSF_FEATURE_UPDATE_ALERT | + FSF_FEATURE_REQUEST_SFP_DATA | + FSF_FEATURE_FC_SECURITY; if (data) req->data = data; @@ -1309,9 +1431,16 @@ zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); spin_unlock_irq(&qdio->req_q_lock); + if (!retval) { /* NOTE: ONLY TOUCH SYNC req AGAIN ON req->completion. */ wait_for_completion(&req->completion); + + if (req->status & + (ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_DISMISSED)) + retval = -EIO; + else if (req->status & ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE) + retval = -EAGAIN; } zfcp_fsf_req_free(req); @@ -1369,10 +1498,17 @@ } /** - * zfcp_fsf_exchange_port_data_sync - request information about local port - * @qdio: pointer to struct zfcp_qdio - * @data: pointer to struct fsf_qtcb_bottom_port - * Returns: 0 on success, error otherwise + * zfcp_fsf_exchange_port_data_sync() - Request information about local port. + * @qdio: pointer to the QDIO-Queue to use for sending the command. + * @data: pointer to the QTCB-Bottom for storing the result of the command, + * might be %NULL. + * + * Returns: + * * 0 - Exchange Port Data was successful, @data is complete + * * -EIO - Exchange Port Data was not successful, @data is invalid + * * -EAGAIN - @data contains incomplete data + * * -ENOMEM - Some memory allocation failed along the way + * * -EOPNOTSUPP - This operation is not supported */ int zfcp_fsf_exchange_port_data_sync(struct zfcp_qdio *qdio, struct fsf_qtcb_bottom_port *data) @@ -1408,10 +1544,15 @@ if (!retval) { /* NOTE: ONLY TOUCH SYNC req AGAIN ON req->completion. */ wait_for_completion(&req->completion); + + if (req->status & + (ZFCP_STATUS_FSFREQ_ERROR | ZFCP_STATUS_FSFREQ_DISMISSED)) + retval = -EIO; + else if (req->status & ZFCP_STATUS_FSFREQ_XDATAINCOMPLETE) + retval = -EAGAIN; } zfcp_fsf_req_free(req); - return retval; out_unlock: @@ -1419,10 +1560,117 @@ return retval; } +static void zfcp_fsf_log_port_fc_security(struct zfcp_port *port, + struct zfcp_fsf_req *req) +{ + char mnemonic_old[ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH]; + char mnemonic_new[ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH]; + + if (port->connection_info == port->connection_info_old) { + /* no change, no log nor trace */ + return; + } + + zfcp_dbf_hba_fsf_fces("fsfcesp", req, port->wwpn, + port->connection_info_old, + port->connection_info); + + zfcp_fsf_scnprint_fc_security(mnemonic_old, sizeof(mnemonic_old), + port->connection_info_old, + ZFCP_FSF_PRINT_FMT_SINGLEITEM); + zfcp_fsf_scnprint_fc_security(mnemonic_new, sizeof(mnemonic_new), + port->connection_info, + ZFCP_FSF_PRINT_FMT_SINGLEITEM); + + if (strncmp(mnemonic_old, mnemonic_new, + ZFCP_FSF_MAX_FC_SECURITY_MNEMONIC_LENGTH) == 0) { + /* no change in string representation, no log */ + goto out; + } + + if (port->connection_info_old == 0) { + /* activation */ + dev_info(&port->adapter->ccw_device->dev, + "FC Endpoint Security of connection to remote port 0x%16llx enabled: %s\n", + port->wwpn, mnemonic_new); + } else if (port->connection_info == 0) { + /* deactivation */ + dev_warn(&port->adapter->ccw_device->dev, + "FC Endpoint Security of connection to remote port 0x%16llx disabled: was %s\n", + port->wwpn, mnemonic_old); + } else { + /* change */ + dev_warn(&port->adapter->ccw_device->dev, + "FC Endpoint Security of connection to remote port 0x%16llx changed: from %s to %s\n", + port->wwpn, mnemonic_old, mnemonic_new); + } + +out: + port->connection_info_old = port->connection_info; +} + +static void zfcp_fsf_log_security_error(const struct device *dev, u32 fsf_sqw0, + u64 wwpn) +{ + switch (fsf_sqw0) { + + /* + * Open Port command error codes + */ + + case FSF_SQ_SECURITY_REQUIRED: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: FC security is required but not supported or configured on remote port 0x%016llx\n", + wwpn); + break; + case FSF_SQ_SECURITY_TIMEOUT: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: a timeout prevented opening remote port 0x%016llx\n", + wwpn); + break; + case FSF_SQ_SECURITY_KM_UNAVAILABLE: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: opening remote port 0x%016llx failed because local and external key manager cannot communicate\n", + wwpn); + break; + case FSF_SQ_SECURITY_RKM_UNAVAILABLE: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: opening remote port 0x%016llx failed because it cannot communicate with the external key manager\n", + wwpn); + break; + case FSF_SQ_SECURITY_AUTH_FAILURE: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: the device could not verify the identity of remote port 0x%016llx\n", + wwpn); + break; + + /* + * Send FCP command error codes + */ + + case FSF_SQ_SECURITY_ENC_FAILURE: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: FC connection to remote port 0x%016llx closed because encryption broke down\n", + wwpn); + break; + + /* + * Unknown error codes + */ + + default: + dev_warn_ratelimited(dev, + "FC Endpoint Security error: the device issued an unknown error code 0x%08x related to the FC connection to remote port 0x%016llx\n", + fsf_sqw0, wwpn); + } +} + static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req) { + struct zfcp_adapter *adapter = req->adapter; struct zfcp_port *port = req->data; struct fsf_qtcb_header *header = &req->qtcb->header; + struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support; struct fc_els_flogi *plogi; if (req->status & ZFCP_STATUS_FSFREQ_ERROR) @@ -1432,7 +1680,7 @@ case FSF_PORT_ALREADY_OPEN: break; case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: - dev_warn(&req->adapter->ccw_device->dev, + dev_warn(&adapter->ccw_device->dev, "Not enough FCP adapter resources to open " "remote port 0x%016Lx\n", (unsigned long long)port->wwpn); @@ -1440,11 +1688,17 @@ ZFCP_STATUS_COMMON_ERP_FAILED); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; + case FSF_SECURITY_ERROR: + zfcp_fsf_log_security_error(&req->adapter->ccw_device->dev, + header->fsf_status_qual.word[0], + port->wwpn); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: /* no zfcp_fc_test_link() with failed open port */ - /* fall through */ + fallthrough; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: case FSF_SQ_NO_RETRY_POSSIBLE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1453,6 +1707,11 @@ break; case FSF_GOOD: port->handle = header->port_handle; + if (adapter->adapter_features & FSF_FEATURE_FC_SECURITY) + port->connection_info = bottom->connection_info; + else + port->connection_info = 0; + zfcp_fsf_log_port_fc_security(port, req); atomic_or(ZFCP_STATUS_COMMON_OPEN | ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); atomic_andnot(ZFCP_STATUS_COMMON_ACCESS_BOXED, @@ -1472,10 +1731,9 @@ * another GID_PN straight after a port has been opened. * Alternately, an ADISC/PDISC ELS should suffice, as well. */ - plogi = (struct fc_els_flogi *) req->qtcb->bottom.support.els; - if (req->qtcb->bottom.support.els1_length >= - FSF_PLOGI_MIN_LEN) - zfcp_fc_plogi_evaluate(port, plogi); + plogi = (struct fc_els_flogi *) bottom->els; + if (bottom->els1_length >= FSF_PLOGI_MIN_LEN) + zfcp_fc_plogi_evaluate(port, plogi); break; case FSF_UNKNOWN_OP_SUBTYPE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; @@ -1613,19 +1871,19 @@ case FSF_MAXIMUM_NUMBER_OF_PORTS_EXCEEDED: dev_warn(&req->adapter->ccw_device->dev, "Opening WKA port 0x%x failed\n", wka_port->d_id); - /* fall through */ + fallthrough; case FSF_ADAPTER_STATUS_AVAILABLE: req->status |= ZFCP_STATUS_FSFREQ_ERROR; wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; break; case FSF_GOOD: wka_port->handle = header->port_handle; - /* fall through */ + fallthrough; case FSF_PORT_ALREADY_OPEN: wka_port->status = ZFCP_FC_WKA_PORT_ONLINE; } out: - wake_up(&wka_port->completion_wq); + wake_up(&wka_port->opened); } /** @@ -1684,7 +1942,7 @@ } wka_port->status = ZFCP_FC_WKA_PORT_OFFLINE; - wake_up(&wka_port->completion_wq); + wake_up(&wka_port->closed); } /** @@ -1763,7 +2021,6 @@ case FSF_ADAPTER_STATUS_AVAILABLE: switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: - /* fall through */ case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1848,7 +2105,7 @@ case FSF_PORT_HANDLE_NOT_VALID: zfcp_erp_adapter_reopen(adapter, 0, "fsouh_1"); - /* fall through */ + fallthrough; case FSF_LUN_ALREADY_OPEN: break; case FSF_PORT_BOXED: @@ -1879,7 +2136,7 @@ (unsigned long long)zfcp_scsi_dev_lun(sdev), (unsigned long long)zfcp_sdev->port->wwpn); zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_ERP_FAILED); - /* fall through */ + fallthrough; case FSF_INVALID_COMMAND_OPTION: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1887,7 +2144,7 @@ switch (header->fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: zfcp_fc_test_link(zfcp_sdev->port); - /* fall through */ + fallthrough; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -1981,7 +2238,7 @@ switch (req->qtcb->header.fsf_status_qual.word[0]) { case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: zfcp_fc_test_link(zfcp_sdev->port); - /* fall through */ + fallthrough; case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; @@ -2166,6 +2423,13 @@ zfcp_fc_test_link(zfcp_sdev->port); req->status |= ZFCP_STATUS_FSFREQ_ERROR; break; + case FSF_SECURITY_ERROR: + zfcp_fsf_log_security_error(&req->adapter->ccw_device->dev, + header->fsf_status_qual.word[0], + zfcp_sdev->port->wwpn); + zfcp_erp_port_forced_reopen(zfcp_sdev->port, 0, "fssfch7"); + req->status |= ZFCP_STATUS_FSFREQ_ERROR; + break; } } --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_fsf.h +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_fsf.h @@ -4,7 +4,7 @@ * * Interface to the FSF support functions. * - * Copyright IBM Corp. 2002, 2018 + * Copyright IBM Corp. 2002, 2020 */ #ifndef FSF_H @@ -78,6 +78,7 @@ #define FSF_BLOCK_GUARD_CHECK_FAILURE 0x00000081 #define FSF_APP_TAG_CHECK_FAILURE 0x00000082 #define FSF_REF_TAG_CHECK_FAILURE 0x00000083 +#define FSF_SECURITY_ERROR 0x00000090 #define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD #define FSF_FCP_RSP_AVAILABLE 0x000000AF #define FSF_UNKNOWN_COMMAND 0x000000E2 @@ -110,6 +111,14 @@ #define FSF_PSQ_LINK_MODE_TABLE_CURRUPTED 0x00004000 #define FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT 0x00008000 +/* FSF status qualifier, security error */ +#define FSF_SQ_SECURITY_REQUIRED 0x00000001 +#define FSF_SQ_SECURITY_TIMEOUT 0x00000002 +#define FSF_SQ_SECURITY_KM_UNAVAILABLE 0x00000003 +#define FSF_SQ_SECURITY_RKM_UNAVAILABLE 0x00000004 +#define FSF_SQ_SECURITY_AUTH_FAILURE 0x00000005 +#define FSF_SQ_SECURITY_ENC_FAILURE 0x00000010 + /* payload size in status read buffer */ #define FSF_STATUS_READ_PAYLOAD_SIZE 4032 @@ -163,6 +172,9 @@ #define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020 #define FSF_FEATURE_UPDATE_ALERT 0x00000100 #define FSF_FEATURE_MEASUREMENT_DATA 0x00000200 +#define FSF_FEATURE_REQUEST_SFP_DATA 0x00000200 +#define FSF_FEATURE_REPORT_SFP_DATA 0x00000800 +#define FSF_FEATURE_FC_SECURITY 0x00001000 #define FSF_FEATURE_DIF_PROT_TYPE1 0x00010000 #define FSF_FEATURE_DIX_PROT_TCPIP 0x00020000 @@ -172,6 +184,11 @@ /* option */ #define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001 +/* FC security algorithms */ +#define FSF_FC_SECURITY_AUTH 0x00000001 +#define FSF_FC_SECURITY_ENC_FCSP2 0x00000002 +#define FSF_FC_SECURITY_ENC_ERAS 0x00000004 + struct fsf_queue_designator { u8 cssid; u8 chpid; @@ -336,7 +353,8 @@ u8 res3[3]; u8 timeout; u32 lun_access_info; - u8 res4[180]; + u32 connection_info; + u8 res4[176]; u32 els1_length; u32 els2_length; u32 req_buf_length; @@ -407,7 +425,25 @@ u8 cp_util; u8 cb_util; u8 a_util; - u8 res2[253]; + u8 res2; + s16 temperature; + u16 vcc; + u16 tx_bias; + u16 tx_power; + u16 rx_power; + union { + u16 raw; + struct { + u16 fec_active :1; + u16:7; + u16 connector_type :2; + u16 sfp_invalid :1; + u16 optical_port :1; + u16 port_tx_type :4; + }; + } sfp_flags; + u32 fc_security_algorithms; + u8 res3[236]; } __attribute__ ((packed)); union fsf_qtcb_bottom { --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_qdio.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_qdio.c @@ -4,7 +4,7 @@ * * Setup and helper functions to access QDIO. * - * Copyright IBM Corp. 2002, 2017 + * Copyright IBM Corp. 2002, 2020 */ #define KMSG_COMPONENT "zfcp" @@ -367,6 +367,18 @@ atomic_set(&qdio->req_q_free, 0); } +void zfcp_qdio_shost_update(struct zfcp_adapter *const adapter, + const struct zfcp_qdio *const qdio) +{ + struct Scsi_Host *const shost = adapter->scsi_host; + + if (shost == NULL) + return; + + shost->sg_tablesize = qdio->max_sbale_per_req; + shost->max_sectors = qdio->max_sbale_per_req * 8; +} + /** * zfcp_qdio_open - prepare and initialize response queue * @qdio: pointer to struct zfcp_qdio @@ -429,10 +441,7 @@ atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); atomic_or(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); - if (adapter->scsi_host) { - adapter->scsi_host->sg_tablesize = qdio->max_sbale_per_req; - adapter->scsi_host->max_sectors = qdio->max_sbale_per_req * 8; - } + zfcp_qdio_shost_update(adapter, qdio); return 0; --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_scsi.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_scsi.c @@ -4,7 +4,7 @@ * * Interface to Linux SCSI midlayer. * - * Copyright IBM Corp. 2002, 2018 + * Copyright IBM Corp. 2002, 2020 */ #define KMSG_COMPONENT "zfcp" @@ -451,26 +451,39 @@ }; /** - * zfcp_scsi_adapter_register - Register SCSI and FC host with SCSI midlayer + * zfcp_scsi_adapter_register() - Allocate and register SCSI and FC host with + * SCSI midlayer * @adapter: The zfcp adapter to register with the SCSI midlayer + * + * Allocates the SCSI host object for the given adapter, sets basic properties + * (such as the transport template, QDIO limits, ...), and registers it with + * the midlayer. + * + * During registration with the midlayer the corresponding FC host object for + * the referenced transport class is also implicitely allocated. + * + * Upon success adapter->scsi_host is set, and upon failure it remains NULL. If + * adapter->scsi_host is already set, nothing is done. + * + * Return: + * * 0 - Allocation and registration was successful + * * -EEXIST - SCSI and FC host did already exist, nothing was done, nothing + * was changed + * * -EIO - Allocation or registration failed */ int zfcp_scsi_adapter_register(struct zfcp_adapter *adapter) { struct ccw_dev_id dev_id; if (adapter->scsi_host) - return 0; + return -EEXIST; ccw_device_get_id(adapter->ccw_device, &dev_id); /* register adapter as SCSI host with mid layer of SCSI stack */ adapter->scsi_host = scsi_host_alloc(&zfcp_scsi_host_template, sizeof (struct zfcp_adapter *)); - if (!adapter->scsi_host) { - dev_err(&adapter->ccw_device->dev, - "Registering the FCP device with the " - "SCSI stack failed\n"); - return -EIO; - } + if (!adapter->scsi_host) + goto err_out; /* tell the SCSI stack some characteristics of this adapter */ adapter->scsi_host->max_id = 511; @@ -480,14 +493,23 @@ adapter->scsi_host->max_cmd_len = 16; /* in struct fcp_cmnd */ adapter->scsi_host->transportt = zfcp_scsi_transport_template; + /* make all basic properties known at registration time */ + zfcp_qdio_shost_update(adapter, adapter->qdio); + zfcp_scsi_set_prot(adapter); + adapter->scsi_host->hostdata[0] = (unsigned long) adapter; if (scsi_add_host(adapter->scsi_host, &adapter->ccw_device->dev)) { scsi_host_put(adapter->scsi_host); - return -EIO; + goto err_out; } return 0; +err_out: + adapter->scsi_host = NULL; + dev_err(&adapter->ccw_device->dev, + "Registering the FCP device with the SCSI stack failed\n"); + return -EIO; } /** @@ -605,7 +627,7 @@ return NULL; ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data); - if (ret) { + if (ret != 0 && ret != -EAGAIN) { kfree(data); return NULL; } @@ -634,7 +656,7 @@ return; ret = zfcp_fsf_exchange_port_data_sync(adapter->qdio, data); - if (ret) + if (ret != 0 && ret != -EAGAIN) kfree(data); else { adapter->stats_reset = jiffies/HZ; @@ -841,6 +863,95 @@ set_host_byte(scmd, DID_SOFT_ERROR); } +void zfcp_scsi_shost_update_config_data( + struct zfcp_adapter *const adapter, + const struct fsf_qtcb_bottom_config *const bottom, + const bool bottom_incomplete) +{ + struct Scsi_Host *const shost = adapter->scsi_host; + const struct fc_els_flogi *nsp, *plogi; + + if (shost == NULL) + return; + + snprintf(fc_host_firmware_version(shost), FC_VERSION_STRING_SIZE, + "0x%08x", bottom->lic_version); + + if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { + snprintf(fc_host_hardware_version(shost), + FC_VERSION_STRING_SIZE, + "0x%08x", bottom->hardware_version); + memcpy(fc_host_serial_number(shost), bottom->serial_number, + min(FC_SERIAL_NUMBER_SIZE, 17)); + EBCASC(fc_host_serial_number(shost), + min(FC_SERIAL_NUMBER_SIZE, 17)); + } + + /* adjust pointers for missing command code */ + nsp = (struct fc_els_flogi *) ((u8 *)&bottom->nport_serv_param + - sizeof(u32)); + plogi = (struct fc_els_flogi *) ((u8 *)&bottom->plogi_payload + - sizeof(u32)); + + snprintf(fc_host_manufacturer(shost), FC_SERIAL_NUMBER_SIZE, "%s", + "IBM"); + fc_host_port_name(shost) = be64_to_cpu(nsp->fl_wwpn); + fc_host_node_name(shost) = be64_to_cpu(nsp->fl_wwnn); + fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; + + zfcp_scsi_set_prot(adapter); + + /* do not evaluate invalid fields */ + if (bottom_incomplete) + return; + + fc_host_port_id(shost) = ntoh24(bottom->s_id); + fc_host_speed(shost) = + zfcp_fsf_convert_portspeed(bottom->fc_link_speed); + + snprintf(fc_host_model(shost), FC_SYMBOLIC_NAME_SIZE, "0x%04x", + bottom->adapter_type); + + switch (bottom->fc_topology) { + case FSF_TOPO_P2P: + fc_host_port_type(shost) = FC_PORTTYPE_PTP; + fc_host_fabric_name(shost) = 0; + break; + case FSF_TOPO_FABRIC: + fc_host_fabric_name(shost) = be64_to_cpu(plogi->fl_wwnn); + if (bottom->connection_features & FSF_FEATURE_NPIV_MODE) + fc_host_port_type(shost) = FC_PORTTYPE_NPIV; + else + fc_host_port_type(shost) = FC_PORTTYPE_NPORT; + break; + case FSF_TOPO_AL: + fc_host_port_type(shost) = FC_PORTTYPE_NLPORT; + fallthrough; + default: + fc_host_fabric_name(shost) = 0; + break; + } +} + +void zfcp_scsi_shost_update_port_data( + struct zfcp_adapter *const adapter, + const struct fsf_qtcb_bottom_port *const bottom) +{ + struct Scsi_Host *const shost = adapter->scsi_host; + + if (shost == NULL) + return; + + fc_host_permanent_port_name(shost) = bottom->wwpn; + fc_host_maxframe_size(shost) = bottom->maximum_frame_size; + fc_host_supported_speeds(shost) = + zfcp_fsf_convert_portspeed(bottom->supported_speed); + memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types, + FC_FC4_LIST_SIZE); + memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types, + FC_FC4_LIST_SIZE); +} + struct fc_function_template zfcp_transport_functions = { .show_starget_port_id = 1, .show_starget_port_name = 1, @@ -856,6 +967,10 @@ .show_host_supported_speeds = 1, .show_host_maxframe_size = 1, .show_host_serial_number = 1, + .show_host_manufacturer = 1, + .show_host_model = 1, + .show_host_hardware_version = 1, + .show_host_firmware_version = 1, .get_fc_host_stats = zfcp_scsi_get_fc_host_stats, .reset_fc_host_stats = zfcp_scsi_reset_fc_host_stats, .set_rport_dev_loss_tmo = zfcp_scsi_set_rport_dev_loss_tmo, @@ -871,5 +986,6 @@ .show_host_symbolic_name = 1, .show_host_speed = 1, .show_host_port_id = 1, + .show_host_fabric_name = 1, .dd_bsg_size = sizeof(struct zfcp_fsf_ct_els), }; --- linux-oracle-5.4.0.orig/drivers/s390/scsi/zfcp_sysfs.c +++ linux-oracle-5.4.0/drivers/s390/scsi/zfcp_sysfs.c @@ -4,13 +4,14 @@ * * sysfs attributes. * - * Copyright IBM Corp. 2008, 2010 + * Copyright IBM Corp. 2008, 2020 */ #define KMSG_COMPONENT "zfcp" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include "zfcp_diag.h" #include "zfcp_ext.h" #define ZFCP_DEV_ATTR(_feat, _name, _mode, _show, _store) \ @@ -215,20 +216,32 @@ { struct ccw_device *cdev = to_ccwdev(dev); struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); + int retval = 0; if (!adapter) return -ENODEV; /* + * If `scsi_host` is missing, we can't schedule `scan_work`, as it + * makes use of the corresponding fc_host object. But this state is + * only possible if xconfig/xport data has never completed yet, + * and we couldn't successfully scan for ports anyway. + */ + if (adapter->scsi_host == NULL) { + retval = -ENODEV; + goto out; + } + + /* * Users wish is our command: immediately schedule and flush a * worker to conduct a synchronous port scan, that is, neither * a random delay nor a rate limit is applied here. */ queue_delayed_work(adapter->work_queue, &adapter->scan_work, 0); flush_delayed_work(&adapter->scan_work); +out: zfcp_ccw_adapter_put(adapter); - - return (ssize_t) count; + return retval ? retval : (ssize_t) count; } static ZFCP_DEV_ATTR(adapter, port_rescan, S_IWUSR, NULL, zfcp_sysfs_port_rescan_store); @@ -325,6 +338,86 @@ static ZFCP_DEV_ATTR(adapter, port_remove, S_IWUSR, NULL, zfcp_sysfs_port_remove_store); +static ssize_t +zfcp_sysfs_adapter_diag_max_age_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev)); + ssize_t rc; + + if (!adapter) + return -ENODEV; + + /* ceil(log(2^64 - 1) / log(10)) = 20 */ + rc = scnprintf(buf, 20 + 2, "%lu\n", adapter->diagnostics->max_age); + + zfcp_ccw_adapter_put(adapter); + return rc; +} + +static ssize_t +zfcp_sysfs_adapter_diag_max_age_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev)); + unsigned long max_age; + ssize_t rc; + + if (!adapter) + return -ENODEV; + + rc = kstrtoul(buf, 10, &max_age); + if (rc != 0) + goto out; + + adapter->diagnostics->max_age = max_age; + + rc = count; +out: + zfcp_ccw_adapter_put(adapter); + return rc; +} +static ZFCP_DEV_ATTR(adapter, diag_max_age, 0644, + zfcp_sysfs_adapter_diag_max_age_show, + zfcp_sysfs_adapter_diag_max_age_store); + +static ssize_t zfcp_sysfs_adapter_fc_security_show( + struct device *dev, struct device_attribute *attr, char *buf) +{ + struct ccw_device *cdev = to_ccwdev(dev); + struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); + unsigned int status; + int i; + + if (!adapter) + return -ENODEV; + + /* + * Adapter status COMMON_OPEN implies xconf data and xport data + * was done. Adapter FC Endpoint Security capability remains + * unchanged in case of COMMON_ERP_FAILED (e.g. due to local link + * down). + */ + status = atomic_read(&adapter->status); + if (0 == (status & ZFCP_STATUS_COMMON_OPEN)) + i = sprintf(buf, "unknown\n"); + else if (!(adapter->adapter_features & FSF_FEATURE_FC_SECURITY)) + i = sprintf(buf, "unsupported\n"); + else { + i = zfcp_fsf_scnprint_fc_security( + buf, PAGE_SIZE - 1, adapter->fc_security_algorithms, + ZFCP_FSF_PRINT_FMT_LIST); + i += scnprintf(buf + i, PAGE_SIZE - i, "\n"); + } + + zfcp_ccw_adapter_put(adapter); + return i; +} +static ZFCP_DEV_ATTR(adapter, fc_security, S_IRUGO, + zfcp_sysfs_adapter_fc_security_show, + NULL); + static struct attribute *zfcp_adapter_attrs[] = { &dev_attr_adapter_failed.attr, &dev_attr_adapter_in_recovery.attr, @@ -337,6 +430,8 @@ &dev_attr_adapter_lic_version.attr, &dev_attr_adapter_status.attr, &dev_attr_adapter_hardware_version.attr, + &dev_attr_adapter_diag_max_age.attr, + &dev_attr_adapter_fc_security.attr, NULL }; @@ -380,6 +475,36 @@ } static DEVICE_ATTR(unit_remove, S_IWUSR, NULL, zfcp_sysfs_unit_remove_store); +static ssize_t zfcp_sysfs_port_fc_security_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct zfcp_port *port = container_of(dev, struct zfcp_port, dev); + struct zfcp_adapter *adapter = port->adapter; + unsigned int status = atomic_read(&port->status); + int i; + + if (0 == (status & ZFCP_STATUS_COMMON_OPEN) || + 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) || + 0 == (status & ZFCP_STATUS_PORT_PHYS_OPEN) || + 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED) || + 0 != (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) + i = sprintf(buf, "unknown\n"); + else if (!(adapter->adapter_features & FSF_FEATURE_FC_SECURITY)) + i = sprintf(buf, "unsupported\n"); + else { + i = zfcp_fsf_scnprint_fc_security( + buf, PAGE_SIZE - 1, port->connection_info, + ZFCP_FSF_PRINT_FMT_SINGLEITEM); + i += scnprintf(buf + i, PAGE_SIZE - i, "\n"); + } + + return i; +} +static ZFCP_DEV_ATTR(port, fc_security, S_IRUGO, + zfcp_sysfs_port_fc_security_show, + NULL); + static struct attribute *zfcp_port_attrs[] = { &dev_attr_unit_add.attr, &dev_attr_unit_remove.attr, @@ -387,6 +512,7 @@ &dev_attr_port_in_recovery.attr, &dev_attr_port_status.attr, &dev_attr_port_access_denied.attr, + &dev_attr_port_fc_security.attr, NULL }; static struct attribute_group zfcp_port_attr_group = { @@ -577,7 +703,7 @@ return -ENOMEM; retval = zfcp_fsf_exchange_port_data_sync(adapter->qdio, qtcb_port); - if (!retval) + if (retval == 0 || retval == -EAGAIN) retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util, qtcb_port->cb_util, qtcb_port->a_util); kfree(qtcb_port); @@ -603,7 +729,7 @@ return -ENOMEM; retval = zfcp_fsf_exchange_config_data_sync(adapter->qdio, qtcb_config); - if (!retval) + if (retval == 0 || retval == -EAGAIN) *stat_inf = qtcb_config->stat_info; kfree(qtcb_config); @@ -664,3 +790,123 @@ &dev_attr_queue_full, NULL }; + +static ssize_t zfcp_sysfs_adapter_diag_b2b_credit_show( + struct device *dev, struct device_attribute *attr, char *buf) +{ + struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(to_ccwdev(dev)); + struct zfcp_diag_header *diag_hdr; + struct fc_els_flogi *nsp; + ssize_t rc = -ENOLINK; + unsigned long flags; + unsigned int status; + + if (!adapter) + return -ENODEV; + + status = atomic_read(&adapter->status); + if (0 == (status & ZFCP_STATUS_COMMON_OPEN) || + 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) || + 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED)) + goto out; + + diag_hdr = &adapter->diagnostics->config_data.header; + + rc = zfcp_diag_update_buffer_limited( + adapter, diag_hdr, zfcp_diag_update_config_data_buffer); + if (rc != 0) + goto out; + + spin_lock_irqsave(&diag_hdr->access_lock, flags); + /* nport_serv_param doesn't contain the ELS_Command code */ + nsp = (struct fc_els_flogi *)((unsigned long) + adapter->diagnostics->config_data + .data.nport_serv_param - + sizeof(u32)); + + rc = scnprintf(buf, 5 + 2, "%hu\n", + be16_to_cpu(nsp->fl_csp.sp_bb_cred)); + spin_unlock_irqrestore(&diag_hdr->access_lock, flags); + +out: + zfcp_ccw_adapter_put(adapter); + return rc; +} +static ZFCP_DEV_ATTR(adapter_diag, b2b_credit, 0400, + zfcp_sysfs_adapter_diag_b2b_credit_show, NULL); + +#define ZFCP_DEFINE_DIAG_SFP_ATTR(_name, _qtcb_member, _prtsize, _prtfmt) \ + static ssize_t zfcp_sysfs_adapter_diag_sfp_##_name##_show( \ + struct device *dev, struct device_attribute *attr, char *buf) \ + { \ + struct zfcp_adapter *const adapter = \ + zfcp_ccw_adapter_by_cdev(to_ccwdev(dev)); \ + struct zfcp_diag_header *diag_hdr; \ + ssize_t rc = -ENOLINK; \ + unsigned long flags; \ + unsigned int status; \ + \ + if (!adapter) \ + return -ENODEV; \ + \ + status = atomic_read(&adapter->status); \ + if (0 == (status & ZFCP_STATUS_COMMON_OPEN) || \ + 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) || \ + 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED)) \ + goto out; \ + \ + if (!zfcp_diag_support_sfp(adapter)) { \ + rc = -EOPNOTSUPP; \ + goto out; \ + } \ + \ + diag_hdr = &adapter->diagnostics->port_data.header; \ + \ + rc = zfcp_diag_update_buffer_limited( \ + adapter, diag_hdr, zfcp_diag_update_port_data_buffer); \ + if (rc != 0) \ + goto out; \ + \ + spin_lock_irqsave(&diag_hdr->access_lock, flags); \ + rc = scnprintf( \ + buf, (_prtsize) + 2, _prtfmt "\n", \ + adapter->diagnostics->port_data.data._qtcb_member); \ + spin_unlock_irqrestore(&diag_hdr->access_lock, flags); \ + \ + out: \ + zfcp_ccw_adapter_put(adapter); \ + return rc; \ + } \ + static ZFCP_DEV_ATTR(adapter_diag_sfp, _name, 0400, \ + zfcp_sysfs_adapter_diag_sfp_##_name##_show, NULL) + +ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 6, "%hd"); +ZFCP_DEFINE_DIAG_SFP_ATTR(vcc, vcc, 5, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(tx_bias, tx_bias, 5, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(tx_power, tx_power, 5, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(rx_power, rx_power, 5, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(port_tx_type, sfp_flags.port_tx_type, 2, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(optical_port, sfp_flags.optical_port, 1, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(sfp_invalid, sfp_flags.sfp_invalid, 1, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(connector_type, sfp_flags.connector_type, 1, "%hu"); +ZFCP_DEFINE_DIAG_SFP_ATTR(fec_active, sfp_flags.fec_active, 1, "%hu"); + +static struct attribute *zfcp_sysfs_diag_attrs[] = { + &dev_attr_adapter_diag_sfp_temperature.attr, + &dev_attr_adapter_diag_sfp_vcc.attr, + &dev_attr_adapter_diag_sfp_tx_bias.attr, + &dev_attr_adapter_diag_sfp_tx_power.attr, + &dev_attr_adapter_diag_sfp_rx_power.attr, + &dev_attr_adapter_diag_sfp_port_tx_type.attr, + &dev_attr_adapter_diag_sfp_optical_port.attr, + &dev_attr_adapter_diag_sfp_sfp_invalid.attr, + &dev_attr_adapter_diag_sfp_connector_type.attr, + &dev_attr_adapter_diag_sfp_fec_active.attr, + &dev_attr_adapter_diag_b2b_credit.attr, + NULL, +}; + +const struct attribute_group zfcp_sysfs_diag_attr_group = { + .name = "diagnostics", + .attrs = zfcp_sysfs_diag_attrs, +}; --- linux-oracle-5.4.0.orig/drivers/s390/virtio/virtio_ccw.c +++ linux-oracle-5.4.0/drivers/s390/virtio/virtio_ccw.c @@ -117,7 +117,7 @@ }; /* the highest virtio-ccw revision we support */ -#define VIRTIO_CCW_REV_MAX 1 +#define VIRTIO_CCW_REV_MAX 2 struct virtio_ccw_vq_info { struct virtqueue *vq; @@ -952,7 +952,7 @@ u8 old_status = vcdev->dma_area->status; struct ccw1 *ccw; - if (vcdev->revision < 1) + if (vcdev->revision < 2) return vcdev->dma_area->status; ccw = ccw_device_dma_zalloc(vcdev->cdev, sizeof(*ccw)); --- linux-oracle-5.4.0.orig/drivers/scsi/3w-9xxx.c +++ linux-oracle-5.4.0/drivers/scsi/3w-9xxx.c @@ -2014,7 +2014,7 @@ retval = pci_enable_device(pdev); if (retval) { TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device"); - goto out_disable_device; + return -ENODEV; } pci_set_master(pdev); --- linux-oracle-5.4.0.orig/drivers/scsi/3w-xxxx.c +++ linux-oracle-5.4.0/drivers/scsi/3w-xxxx.c @@ -2310,8 +2310,10 @@ TW_DISABLE_INTERRUPTS(tw_dev); /* Initialize the card */ - if (tw_reset_sequence(tw_dev)) + if (tw_reset_sequence(tw_dev)) { + retval = -EINVAL; goto out_release_mem_region; + } /* Set host specific parameters */ host->max_id = TW_MAX_UNITS; --- linux-oracle-5.4.0.orig/drivers/scsi/53c700.c +++ linux-oracle-5.4.0/drivers/scsi/53c700.c @@ -1581,7 +1581,7 @@ printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); #endif resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; - } else if(dsp >= to32bit(&slot->pSG[0].ins) && + } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) && dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); --- linux-oracle-5.4.0.orig/drivers/scsi/BusLogic.c +++ linux-oracle-5.4.0/drivers/scsi/BusLogic.c @@ -3077,11 +3077,11 @@ ccb->opcode = BLOGIC_INITIATOR_CCB_SG; ccb->datalen = count * sizeof(struct blogic_sg_seg); if (blogic_multimaster_type(adapter)) - ccb->data = (void *)((unsigned int) ccb->dma_handle + + ccb->data = (unsigned int) ccb->dma_handle + ((unsigned long) &ccb->sglist - - (unsigned long) ccb)); + (unsigned long) ccb); else - ccb->data = ccb->sglist; + ccb->data = virt_to_32bit_virt(ccb->sglist); scsi_for_each_sg(command, sg, count, i) { ccb->sglist[i].segbytes = sg_dma_len(sg); @@ -3601,7 +3601,7 @@ if (buf[0] != '\n' || len > 1) printk("%sscsi%d: %s", blogic_msglevelmap[msglevel], adapter->host_no, buf); } else - printk("%s", buf); + pr_cont("%s", buf); } else { if (begin) { if (adapter != NULL && adapter->adapter_initd) @@ -3609,7 +3609,7 @@ else printk("%s%s", blogic_msglevelmap[msglevel], buf); } else - printk("%s", buf); + pr_cont("%s", buf); } begin = (buf[len - 1] == '\n'); } --- linux-oracle-5.4.0.orig/drivers/scsi/BusLogic.h +++ linux-oracle-5.4.0/drivers/scsi/BusLogic.h @@ -814,7 +814,7 @@ unsigned char cdblen; /* Byte 2 */ unsigned char sense_datalen; /* Byte 3 */ u32 datalen; /* Bytes 4-7 */ - void *data; /* Bytes 8-11 */ + u32 data; /* Bytes 8-11 */ unsigned char:8; /* Byte 12 */ unsigned char:8; /* Byte 13 */ enum blogic_adapter_status adapter_status; /* Byte 14 */ --- linux-oracle-5.4.0.orig/drivers/scsi/FlashPoint.c +++ linux-oracle-5.4.0/drivers/scsi/FlashPoint.c @@ -40,7 +40,7 @@ u16 si_per_targ_ultra_nego; u16 si_per_targ_no_disc; u16 si_per_targ_wide_nego; - u16 si_flags; + u16 si_mflags; unsigned char si_card_family; unsigned char si_bustype; unsigned char si_card_model[3]; @@ -1070,22 +1070,22 @@ ScamFlg = (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); - pCardInfo->si_flags = 0x0000; + pCardInfo->si_mflags = 0x0000; if (i & 0x01) - pCardInfo->si_flags |= SCSI_PARITY_ENA; + pCardInfo->si_mflags |= SCSI_PARITY_ENA; if (!(i & 0x02)) - pCardInfo->si_flags |= SOFT_RESET; + pCardInfo->si_mflags |= SOFT_RESET; if (i & 0x10) - pCardInfo->si_flags |= EXTENDED_TRANSLATION; + pCardInfo->si_mflags |= EXTENDED_TRANSLATION; if (ScamFlg & SCAM_ENABLED) - pCardInfo->si_flags |= FLAG_SCAM_ENABLED; + pCardInfo->si_mflags |= FLAG_SCAM_ENABLED; if (ScamFlg & SCAM_LEVEL2) - pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; + pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2; j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); if (i & 0x04) { @@ -1101,7 +1101,7 @@ if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) - pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; + pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN; pCardInfo->si_card_family = HARPOON_FAMILY; pCardInfo->si_bustype = BUSTYPE_PCI; @@ -1137,15 +1137,15 @@ if (pCardInfo->si_card_model[1] == '3') { if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; } else if (pCardInfo->si_card_model[2] == '0') { temp = RD_HARPOON(ioport + hp_xfer_pad); WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, temp); } else { temp = RD_HARPOON(ioport + hp_ee_ctrl); @@ -1163,9 +1163,9 @@ WR_HARPOON(ioport + hp_ee_ctrl, temp); WR_HARPOON(ioport + hp_xfer_pad, temp2); if (!(temp3 & BIT(7))) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; if (!(temp3 & BIT(6))) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; } ARAM_ACCESS(ioport); @@ -1272,7 +1272,7 @@ WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); CurrCard->ourId = pCardInfo->si_id; - i = (unsigned char)pCardInfo->si_flags; + i = (unsigned char)pCardInfo->si_mflags; if (i & SCSI_PARITY_ENA) WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); @@ -1286,14 +1286,14 @@ j |= SCSI_TERM_ENA_H; WR_HARPOON(ioport + hp_ee_ctrl, j); - if (!(pCardInfo->si_flags & SOFT_RESET)) { + if (!(pCardInfo->si_mflags & SOFT_RESET)) { FPT_sresb(ioport, thisCard); FPT_scini(thisCard, pCardInfo->si_id, 0); } - if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) + if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS) CurrCard->globalFlags |= F_NO_FILTER; if (pCurrNvRam) { --- linux-oracle-5.4.0.orig/drivers/scsi/Kconfig +++ linux-oracle-5.4.0/drivers/scsi/Kconfig @@ -114,15 +114,6 @@ . The module will be called sr_mod. -config BLK_DEV_SR_VENDOR - bool "Enable vendor-specific extensions (for SCSI CDROM)" - depends on BLK_DEV_SR - help - This enables the usage of vendor specific SCSI commands. This is - required to support multisession CDs with old NEC/TOSHIBA cdrom - drives (and HP Writers). If you have such a drive and get the first - session only, try saying Y here; everybody else says N. - config CHR_DEV_SG tristate "SCSI generic support" depends on SCSI @@ -452,7 +443,7 @@ config SCSI_DPT_I2O tristate "Adaptec I2O RAID support " - depends on SCSI && PCI && VIRT_TO_BUS + depends on SCSI && PCI help This driver supports all of Adaptec's I2O based RAID controllers as well as the DPT SmartRaid V cards. This is an Adaptec maintained @@ -1295,7 +1286,7 @@ config JAZZ_ESP bool "MIPS JAZZ FAS216 SCSI support" - depends on MACH_JAZZ && SCSI + depends on MACH_JAZZ && SCSI=y select SCSI_SPI_ATTRS help This is the driver for the onboard SCSI host adapter of MIPS Magnum --- linux-oracle-5.4.0.orig/drivers/scsi/NCR5380.c +++ linux-oracle-5.4.0/drivers/scsi/NCR5380.c @@ -129,6 +129,9 @@ #define NCR5380_release_dma_irq(x) #endif +static unsigned int disconnect_mask = ~0; +module_param(disconnect_mask, int, 0444); + static int do_abort(struct Scsi_Host *); static void do_reset(struct Scsi_Host *); static void bus_reset_cleanup(struct Scsi_Host *); @@ -954,7 +957,8 @@ int err; bool ret = true; bool can_disconnect = instance->irq != NO_IRQ && - cmd->cmnd[0] != REQUEST_SENSE; + cmd->cmnd[0] != REQUEST_SENSE && + (disconnect_mask & BIT(scmd_id(cmd))); NCR5380_dprint(NDEBUG_ARBITRATION, instance); dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n", --- linux-oracle-5.4.0.orig/drivers/scsi/aacraid/aachba.c +++ linux-oracle-5.4.0/drivers/scsi/aacraid/aachba.c @@ -2467,13 +2467,13 @@ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense(&dev->fsa_dev[cid].sense_data, - HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, + ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); scsicmd->scsi_done(scsicmd); - return 1; + return 0; } dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", @@ -2559,13 +2559,13 @@ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense(&dev->fsa_dev[cid].sense_data, - HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, + ILLEGAL_REQUEST, SENCODE_LBA_OUT_OF_RANGE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); scsicmd->scsi_done(scsicmd); - return 1; + return 0; } dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", --- linux-oracle-5.4.0.orig/drivers/scsi/aacraid/aacraid.h +++ linux-oracle-5.4.0/drivers/scsi/aacraid/aacraid.h @@ -2024,8 +2024,8 @@ }; struct aac_srb_unit { - struct aac_srb srb; struct aac_srb_reply srb_reply; + struct aac_srb srb; }; /* --- linux-oracle-5.4.0.orig/drivers/scsi/aacraid/comminit.c +++ linux-oracle-5.4.0/drivers/scsi/aacraid/comminit.c @@ -638,6 +638,7 @@ if (aac_comm_init(dev)<0){ kfree(dev->queues); + dev->queues = NULL; return NULL; } /* @@ -645,6 +646,7 @@ */ if (aac_fib_setup(dev) < 0) { kfree(dev->queues); + dev->queues = NULL; return NULL; } --- linux-oracle-5.4.0.orig/drivers/scsi/aacraid/commsup.c +++ linux-oracle-5.4.0/drivers/scsi/aacraid/commsup.c @@ -728,7 +728,7 @@ hbacmd->request_id = cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1); fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD; - } else if (command != HBA_IU_TYPE_SCSI_TM_REQ) + } else return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/scsi/aacraid/linit.c +++ linux-oracle-5.4.0/drivers/scsi/aacraid/linit.c @@ -723,7 +723,11 @@ status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib, (fib_callback) aac_hba_callback, (void *) cmd); - + if (status != -EINPROGRESS) { + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 secs for completion */ for (count = 0; count < 15; ++count) { if (cmd->SCp.sent_command) { @@ -902,11 +906,11 @@ info = &aac->hba_map[bus][cid]; - if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED; - pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host device reset request. SCSI hang ?\n", AAC_DRIVERNAME); fib = aac_fib_alloc(aac); @@ -921,7 +925,12 @@ status = aac_hba_send(command, fib, (fib_callback) aac_tmf_callback, (void *) info); - + if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state == 0) { @@ -960,11 +969,11 @@ info = &aac->hba_map[bus][cid]; - if (info->devtype != AAC_DEVTYPE_NATIVE_RAW && - info->reset_state > 0) + if (!(info->devtype == AAC_DEVTYPE_NATIVE_RAW && + !(info->reset_state > 0))) return FAILED; - pr_err("%s: Host adapter reset request. SCSI hang ?\n", + pr_err("%s: Host target reset request. SCSI hang ?\n", AAC_DRIVERNAME); fib = aac_fib_alloc(aac); @@ -981,6 +990,13 @@ (fib_callback) aac_tmf_callback, (void *) info); + if (status != -EINPROGRESS) { + info->reset_state = 0; + aac_fib_complete(fib); + aac_fib_free(fib); + return ret; + } + /* Wait up to 15 seconds for completion */ for (count = 0; count < 15; ++count) { if (info->reset_state <= 0) { @@ -1033,7 +1049,7 @@ } } - pr_err("%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME); /* * Check the health of the controller @@ -1591,7 +1607,7 @@ struct Scsi_Host *shost; struct aac_dev *aac; struct list_head *insert = &aac_devices; - int error = -ENODEV; + int error; int unique_id = 0; u64 dmamask; int mask_bits = 0; @@ -1616,7 +1632,6 @@ error = pci_enable_device(pdev); if (error) goto out; - error = -ENODEV; if (!(aac_drivers[index].quirks & AAC_QUIRK_SRC)) { error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); @@ -1648,8 +1663,10 @@ pci_set_master(pdev); shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev)); - if (!shost) + if (!shost) { + error = -ENOMEM; goto out_disable_pdev; + } shost->irq = pdev->irq; shost->unique_id = unique_id; @@ -1674,8 +1691,11 @@ aac->fibs = kcalloc(shost->can_queue + AAC_NUM_MGT_FIB, sizeof(struct fib), GFP_KERNEL); - if (!aac->fibs) + if (!aac->fibs) { + error = -ENOMEM; goto out_free_host; + } + spin_lock_init(&aac->fib_lock); mutex_init(&aac->ioctl_mutex); --- linux-oracle-5.4.0.orig/drivers/scsi/advansys.c +++ linux-oracle-5.4.0/drivers/scsi/advansys.c @@ -3366,8 +3366,8 @@ shost->host_no); seq_printf(m, - " iop_base 0x%lx, cable_detect: %X, err_code %u\n", - (unsigned long)v->iop_base, + " iop_base 0x%p, cable_detect: %X, err_code %u\n", + v->iop_base, AdvReadWordRegister(iop_base,IOPW_SCSI_CFG1) & CABLE_DETECT, v->err_code); --- linux-oracle-5.4.0.orig/drivers/scsi/aha152x.c +++ linux-oracle-5.4.0/drivers/scsi/aha152x.c @@ -3368,13 +3368,11 @@ setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1; setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT; setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0; - if (ints[0] > 8) { /*}*/ + if (ints[0] > 8) printk(KERN_NOTICE "aha152x: usage: aha152x=[,[," "[,[,[,[,[,]]]]]]]\n"); - } else { + else setup_count++; - return 0; - } return 1; } --- linux-oracle-5.4.0.orig/drivers/scsi/aic7xxx/aic7xxx_core.c +++ linux-oracle-5.4.0/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -493,7 +493,7 @@ return ((ahc_inb(ahc, port)) | (ahc_inb(ahc, port+1) << 8) | (ahc_inb(ahc, port+2) << 16) - | (ahc_inb(ahc, port+3) << 24) + | (((uint64_t)ahc_inb(ahc, port+3)) << 24) | (((uint64_t)ahc_inb(ahc, port+4)) << 32) | (((uint64_t)ahc_inb(ahc, port+5)) << 40) | (((uint64_t)ahc_inb(ahc, port+6)) << 48) @@ -2314,7 +2314,7 @@ * At some speeds, we only support * ST transfers. */ - if ((syncrate->sxfr_u2 & ST_SXFR) != 0) + if ((syncrate->sxfr_u2 & ST_SXFR) != 0) *ppr_options &= ~MSG_EXT_PPR_DT_REQ; break; } --- linux-oracle-5.4.0.orig/drivers/scsi/aic94xx/aic94xx_init.c +++ linux-oracle-5.4.0/drivers/scsi/aic94xx/aic94xx_init.c @@ -52,6 +52,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .track_queue_depth = 1, --- linux-oracle-5.4.0.orig/drivers/scsi/aic94xx/aic94xx_task.c +++ linux-oracle-5.4.0/drivers/scsi/aic94xx/aic94xx_task.c @@ -50,6 +50,9 @@ dma_addr_t dma = dma_map_single(&asd_ha->pcidev->dev, p, task->total_xfer_len, task->data_dir); + if (dma_mapping_error(&asd_ha->pcidev->dev, dma)) + return -ENOMEM; + sg_arr[0].bus_addr = cpu_to_le64((u64)dma); sg_arr[0].size = cpu_to_le32(task->total_xfer_len); sg_arr[0].flags |= ASD_SG_EL_LIST_EOL; --- linux-oracle-5.4.0.orig/drivers/scsi/arm/acornscsi.c +++ linux-oracle-5.4.0/drivers/scsi/arm/acornscsi.c @@ -2911,8 +2911,10 @@ ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); - if (!ashost->base || !ashost->fast) + if (!ashost->base || !ashost->fast) { + ret = -ENOMEM; goto out_put; + } host->irq = ec->irq; ashost->host = host; --- linux-oracle-5.4.0.orig/drivers/scsi/arm/cumana_2.c +++ linux-oracle-5.4.0/drivers/scsi/arm/cumana_2.c @@ -450,7 +450,7 @@ if (info->info.scsi.dma != NO_DMA) free_dma(info->info.scsi.dma); - free_irq(ec->irq, host); + free_irq(ec->irq, info); out_release: fas216_release(host); --- linux-oracle-5.4.0.orig/drivers/scsi/arm/eesox.c +++ linux-oracle-5.4.0/drivers/scsi/arm/eesox.c @@ -571,7 +571,7 @@ if (info->info.scsi.dma != NO_DMA) free_dma(info->info.scsi.dma); - free_irq(ec->irq, host); + free_irq(ec->irq, info); out_remove: fas216_remove(host); --- linux-oracle-5.4.0.orig/drivers/scsi/arm/powertec.c +++ linux-oracle-5.4.0/drivers/scsi/arm/powertec.c @@ -378,7 +378,7 @@ if (info->info.scsi.dma != NO_DMA) free_dma(info->info.scsi.dma); - free_irq(ec->irq, host); + free_irq(ec->irq, info); out_release: fas216_release(host); --- linux-oracle-5.4.0.orig/drivers/scsi/atari_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/atari_scsi.c @@ -742,7 +742,7 @@ atari_scsi_template.sg_tablesize = SG_ALL; } else { atari_scsi_template.can_queue = 1; - atari_scsi_template.sg_tablesize = SG_NONE; + atari_scsi_template.sg_tablesize = 1; } if (setup_can_queue > 0) @@ -751,8 +751,8 @@ if (setup_cmd_per_lun > 0) atari_scsi_template.cmd_per_lun = setup_cmd_per_lun; - /* Leave sg_tablesize at 0 on a Falcon! */ - if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0) + /* Don't increase sg_tablesize on Falcon! */ + if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize > 0) atari_scsi_template.sg_tablesize = setup_sg_tablesize; if (setup_hostid >= 0) { --- linux-oracle-5.4.0.orig/drivers/scsi/be2iscsi/be_iscsi.c +++ linux-oracle-5.4.0/drivers/scsi/be2iscsi/be_iscsi.c @@ -441,6 +441,10 @@ } nla_for_each_attr(attrib, data, dt_len, rm_len) { + /* ignore nla_type as it is never used */ + if (nla_len(attrib) < sizeof(*iface_param)) + return -EINVAL; + iface_param = nla_data(attrib); if (iface_param->param_type != ISCSI_NET_PARAM) --- linux-oracle-5.4.0.orig/drivers/scsi/be2iscsi/be_main.c +++ linux-oracle-5.4.0/drivers/scsi/be2iscsi/be_main.c @@ -416,7 +416,7 @@ "beiscsi_hba_alloc - iscsi_host_alloc failed\n"); return NULL; } - shost->max_id = BE2_MAX_SESSIONS; + shost->max_id = BE2_MAX_SESSIONS - 1; shost->max_channel = 0; shost->max_cmd_len = BEISCSI_MAX_CMD_LEN; shost->max_lun = BEISCSI_NUM_MAX_LUN; @@ -2694,6 +2694,7 @@ kfree(pwrb_context->pwrb_handle_base); kfree(pwrb_context->pwrb_handle_basestd); } + kfree(phwi_ctxt->be_wrbq); return -ENOMEM; } @@ -5318,7 +5319,7 @@ /* Re-enable UER. If different TPE occurs then it is recoverable. */ beiscsi_set_uer_feature(phba); - phba->shost->max_id = phba->params.cxns_per_ctrl; + phba->shost->max_id = phba->params.cxns_per_ctrl - 1; phba->shost->can_queue = phba->params.ios_per_ctrl; ret = beiscsi_init_port(phba); if (ret < 0) { @@ -5745,6 +5746,7 @@ pci_disable_msix(phba->pcidev); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); + pci_disable_pcie_error_reporting(pcidev); pci_set_drvdata(pcidev, NULL); disable_pci: pci_release_regions(pcidev); --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfa.h +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfa.h @@ -20,7 +20,6 @@ struct bfa_s; typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); -typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status); /* * Interrupt message handlers @@ -435,6 +434,14 @@ (__qe)->hcb_qe.cbarg = (__cbarg); \ (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \ (__qe)->data = (__data); \ +} while (0) + +#define bfa_pending_q_init_status(__qe, __cbfn, __cbarg, __data) do { \ + bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \ + (__qe)->hcb_qe.cbfn_status = (__cbfn); \ + (__qe)->hcb_qe.cbarg = (__cbarg); \ + (__qe)->hcb_qe.pre_rmv = BFA_TRUE; \ + (__qe)->data = (__data); \ } while (0) #endif /* __BFA_H__ */ --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfa_core.c +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfa_core.c @@ -1907,15 +1907,13 @@ struct list_head *qe; struct list_head *qen; struct bfa_cb_qe_s *hcb_qe; - bfa_cb_cbfn_status_t cbfn; list_for_each_safe(qe, qen, comp_q) { hcb_qe = (struct bfa_cb_qe_s *) qe; if (hcb_qe->pre_rmv) { /* qe is invalid after return, dequeue before cbfn() */ list_del(qe); - cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn); - cbfn(hcb_qe->cbarg, hcb_qe->fw_status); + hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status); } else hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); } --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfa_ioc.h +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfa_ioc.h @@ -361,14 +361,18 @@ void *cbarg; }; -typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); +typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); +typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status); /* * Generic BFA callback element. */ struct bfa_cb_qe_s { struct list_head qe; - bfa_cb_cbfn_t cbfn; + union { + bfa_cb_cbfn_status_t cbfn_status; + bfa_cb_cbfn_t cbfn; + }; bfa_boolean_t once; bfa_boolean_t pre_rmv; /* set for stack based qe(s) */ bfa_status_t fw_status; /* to access fw status in comp proc */ --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfad.c +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfad.c @@ -749,6 +749,7 @@ if (bfad->pci_bar0_kva == NULL) { printk(KERN_ERR "Fail to map bar0\n"); + rc = -ENODEV; goto out_release_region; } @@ -1705,9 +1706,8 @@ error = bfad_im_module_init(); if (error) { - error = -ENOMEM; printk(KERN_WARNING "bfad_im_module_init failure\n"); - goto ext; + return -ENOMEM; } if (strcmp(FCPI_NAME, " fcpim") == 0) --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfad_attr.c +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfad_attr.c @@ -275,8 +275,10 @@ rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa), fcstats, bfad_hcb_comp, &fcomp); spin_unlock_irqrestore(&bfad->bfad_lock, flags); - if (rc != BFA_STATUS_OK) + if (rc != BFA_STATUS_OK) { + kfree(fcstats); return NULL; + } wait_for_completion(&fcomp.comp); @@ -709,7 +711,7 @@ char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; bfa_get_adapter_serial_num(&bfad->bfa, serial_num); - return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); + return sysfs_emit(buf, "%s\n", serial_num); } static ssize_t @@ -723,7 +725,7 @@ char model[BFA_ADAPTER_MODEL_NAME_LEN]; bfa_get_adapter_model(&bfad->bfa, model); - return snprintf(buf, PAGE_SIZE, "%s\n", model); + return sysfs_emit(buf, "%s\n", model); } static ssize_t @@ -803,7 +805,7 @@ snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, "Invalid Model"); - return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); + return sysfs_emit(buf, "%s\n", model_descr); } static ssize_t @@ -817,7 +819,7 @@ u64 nwwn; nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port); - return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn)); + return sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn)); } static ssize_t @@ -834,7 +836,7 @@ bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); strlcpy(symname, port_attr.port_cfg.sym_name.symname, BFA_SYMNAME_MAXLEN); - return snprintf(buf, PAGE_SIZE, "%s\n", symname); + return sysfs_emit(buf, "%s\n", symname); } static ssize_t @@ -848,14 +850,14 @@ char hw_ver[BFA_VERSION_LEN]; bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); - return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); + return sysfs_emit(buf, "%s\n", hw_ver); } static ssize_t bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); + return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION); } static ssize_t @@ -869,7 +871,7 @@ char optrom_ver[BFA_VERSION_LEN]; bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); - return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); + return sysfs_emit(buf, "%s\n", optrom_ver); } static ssize_t @@ -883,7 +885,7 @@ char fw_ver[BFA_VERSION_LEN]; bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); - return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); + return sysfs_emit(buf, "%s\n", fw_ver); } static ssize_t @@ -895,7 +897,7 @@ (struct bfad_im_port_s *) shost->hostdata[0]; struct bfad_s *bfad = im_port->bfad; - return snprintf(buf, PAGE_SIZE, "%d\n", + return sysfs_emit(buf, "%d\n", bfa_get_nports(&bfad->bfa)); } @@ -903,7 +905,7 @@ bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, char *buf) { - return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); + return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME); } static ssize_t @@ -922,14 +924,14 @@ rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s), GFP_ATOMIC); if (rports == NULL) - return snprintf(buf, PAGE_SIZE, "Failed\n"); + return sysfs_emit(buf, "Failed\n"); spin_lock_irqsave(&bfad->bfad_lock, flags); bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports); spin_unlock_irqrestore(&bfad->bfad_lock, flags); kfree(rports); - return snprintf(buf, PAGE_SIZE, "%d\n", nrports); + return sysfs_emit(buf, "%d\n", nrports); } static DEVICE_ATTR(serial_number, S_IRUGO, --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfad_bsg.c +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfad_bsg.c @@ -2135,8 +2135,7 @@ struct bfa_cb_pending_q_s cb_qe; init_completion(&fcomp.comp); - bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, - &fcomp, &iocmd->stats); + bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); spin_lock_irqsave(&bfad->bfad_lock, flags); iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); spin_unlock_irqrestore(&bfad->bfad_lock, flags); @@ -2159,7 +2158,7 @@ struct bfa_cb_pending_q_s cb_qe; init_completion(&fcomp.comp); - bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); + bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); spin_lock_irqsave(&bfad->bfad_lock, flags); iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); @@ -2443,8 +2442,7 @@ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); init_completion(&fcomp.comp); - bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, - &fcomp, &iocmd->stats); + bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats); spin_lock_irqsave(&bfad->bfad_lock, flags); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); @@ -2474,8 +2472,7 @@ struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); init_completion(&fcomp.comp); - bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, - &fcomp, NULL); + bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL); spin_lock_irqsave(&bfad->bfad_lock, flags); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); --- linux-oracle-5.4.0.orig/drivers/scsi/bfa/bfad_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/bfa/bfad_debugfs.c @@ -250,7 +250,7 @@ unsigned long flags; void *kern_buf; - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); @@ -317,7 +317,7 @@ unsigned long flags; void *kern_buf; - kern_buf = memdup_user(buf, nbytes); + kern_buf = memdup_user_nul(buf, nbytes); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2fc/Kconfig +++ linux-oracle-5.4.0/drivers/scsi/bnx2fc/Kconfig @@ -5,6 +5,7 @@ depends on (IPV6 || IPV6=n) depends on LIBFC depends on LIBFCOE + depends on MMU select NETDEVICES select ETHERNET select NET_VENDOR_BROADCOM --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ linux-oracle-5.4.0/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -80,7 +80,7 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba); static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct device *parent, int npiv); -static void bnx2fc_destroy_work(struct work_struct *work); +static void bnx2fc_port_destroy(struct fcoe_port *port); static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev); static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device @@ -430,7 +430,6 @@ struct fcoe_ctlr *ctlr; struct fcoe_rcv_info *fr; struct fcoe_percpu_s *bg; - struct sk_buff *tmp_skb; interface = container_of(ptype, struct bnx2fc_interface, fcoe_packet_type); @@ -442,11 +441,9 @@ goto err; } - tmp_skb = skb_share_check(skb, GFP_ATOMIC); - if (!tmp_skb) - goto err; - - skb = tmp_skb; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + return -1; if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); @@ -506,7 +503,8 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) { - u32 fr_len; + u64 crc_err; + u32 fr_len, fr_crc; struct fc_lport *lport; struct fcoe_rcv_info *fr; struct fc_stats *stats; @@ -540,6 +538,11 @@ skb_pull(skb, sizeof(struct fcoe_hdr)); fr_len = skb->len - sizeof(struct fcoe_crc_eof); + stats = per_cpu_ptr(lport->stats, get_cpu()); + stats->RxFrames++; + stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; + put_cpu(); + fp = (struct fc_frame *)skb; fc_frame_init(fp); fr_dev(fp) = lport; @@ -622,16 +625,15 @@ return; } - stats = per_cpu_ptr(lport->stats, smp_processor_id()); - stats->RxFrames++; - stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; + fr_crc = le32_to_cpu(fr_crc(fp)); - if (le32_to_cpu(fr_crc(fp)) != - ~crc32(~0, skb->data, fr_len)) { - if (stats->InvalidCRCCount < 5) + if (unlikely(fr_crc != ~crc32(~0, skb->data, fr_len))) { + stats = per_cpu_ptr(lport->stats, get_cpu()); + crc_err = (stats->InvalidCRCCount++); + put_cpu(); + if (crc_err < 5) printk(KERN_WARNING PFX "dropping frame with " "CRC error\n"); - stats->InvalidCRCCount++; kfree_skb(skb); return; } @@ -902,9 +904,6 @@ __bnx2fc_destroy(interface); } mutex_unlock(&bnx2fc_dev_lock); - - /* Ensure ALL destroy work has been completed before return */ - flush_workqueue(bnx2fc_wq); return; default: @@ -1211,8 +1210,8 @@ mutex_unlock(&n_port->lp_mutex); bnx2fc_free_vport(interface->hba, port->lport); bnx2fc_port_shutdown(port->lport); + bnx2fc_port_destroy(port); bnx2fc_interface_put(interface); - queue_work(bnx2fc_wq, &port->destroy_work); return 0; } @@ -1521,7 +1520,6 @@ port->lport = lport; port->priv = interface; port->get_netdev = bnx2fc_netdev; - INIT_WORK(&port->destroy_work, bnx2fc_destroy_work); /* Configure fcoe_port */ rc = bnx2fc_lport_config(lport); @@ -1649,8 +1647,8 @@ bnx2fc_interface_cleanup(interface); bnx2fc_stop(interface); list_del(&interface->list); + bnx2fc_port_destroy(port); bnx2fc_interface_put(interface); - queue_work(bnx2fc_wq, &port->destroy_work); } /** @@ -1691,15 +1689,12 @@ return rc; } -static void bnx2fc_destroy_work(struct work_struct *work) +static void bnx2fc_port_destroy(struct fcoe_port *port) { - struct fcoe_port *port; struct fc_lport *lport; - port = container_of(work, struct fcoe_port, destroy_work); lport = port->lport; - - BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); + BNX2FC_HBA_DBG(lport, "Entered %s, destroying lport %p\n", __func__, lport); bnx2fc_if_destroy(lport); } @@ -2553,9 +2548,6 @@ __bnx2fc_destroy(interface); mutex_unlock(&bnx2fc_dev_lock); - /* Ensure ALL destroy work has been completed before return */ - flush_workqueue(bnx2fc_wq); - bnx2fc_ulp_stop(hba); /* unregister cnic device */ if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic)) --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2fc/bnx2fc_io.c +++ linux-oracle-5.4.0/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1219,6 +1219,7 @@ was a result from the ABTS request rather than the CLEANUP request */ set_bit(BNX2FC_FLAG_IO_CLEANUP, &io_req->req_flags); + rc = FAILED; goto done; } --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ linux-oracle-5.4.0/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -834,7 +834,6 @@ BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n"); - spin_lock_bh(&tgt->cq_lock); ctx_base_ptr = tgt->ctx_base; tgt->ctx_base = NULL; @@ -890,7 +889,6 @@ tgt->sq, tgt->sq_dma); tgt->sq = NULL; } - spin_unlock_bh(&tgt->cq_lock); if (ctx_base_ptr) iounmap(ctx_base_ptr); --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2i/Kconfig +++ linux-oracle-5.4.0/drivers/scsi/bnx2i/Kconfig @@ -4,6 +4,7 @@ depends on NET depends on PCI depends on (IPV6 || IPV6=n) + depends on MMU select SCSI_ISCSI_ATTRS select NETDEVICES select ETHERNET --- linux-oracle-5.4.0.orig/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ linux-oracle-5.4.0/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -793,7 +793,7 @@ return NULL; shost->dma_boundary = cnic->pcidev->dma_mask; shost->transportt = bnx2i_scsi_xport_template; - shost->max_id = ISCSI_MAX_CONNS_PER_HBA; + shost->max_id = ISCSI_MAX_CONNS_PER_HBA - 1; shost->max_channel = 0; shost->max_lun = 512; shost->max_cmd_len = 16; @@ -915,12 +915,12 @@ INIT_LIST_HEAD(&hba->ep_ofld_list); INIT_LIST_HEAD(&hba->ep_active_list); INIT_LIST_HEAD(&hba->ep_destroy_list); - pci_dev_put(hba->pcidev); if (hba->regview) { pci_iounmap(hba->pcidev, hba->regview); hba->regview = NULL; } + pci_dev_put(hba->pcidev); bnx2i_free_mp_bdt(hba); bnx2i_release_free_cid_que(hba); iscsi_host_free(shost); --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_defs.h +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_defs.h @@ -73,7 +73,21 @@ #define csio_list_prev(elem) (((struct list_head *)(elem))->prev) /* State machine */ -typedef void (*csio_sm_state_t)(void *, uint32_t); +struct csio_lnode; + +/* State machine evets */ +enum csio_ln_ev { + CSIO_LNE_NONE = (uint32_t)0, + CSIO_LNE_LINKUP, + CSIO_LNE_FAB_INIT_DONE, + CSIO_LNE_LINK_DOWN, + CSIO_LNE_DOWN_LINK, + CSIO_LNE_LOGO, + CSIO_LNE_CLOSE, + CSIO_LNE_MAX_EVENT, +}; + +typedef void (*csio_sm_state_t)(struct csio_lnode *ln, enum csio_ln_ev evt); struct csio_sm { struct list_head sm_list; @@ -83,7 +97,7 @@ static inline void csio_set_state(void *smp, void *state) { - ((struct csio_sm *)smp)->sm_state = (csio_sm_state_t)state; + ((struct csio_sm *)smp)->sm_state = state; } static inline void --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_hw.c +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_hw.c @@ -2384,7 +2384,7 @@ FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k), FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k)); - ret = EINVAL; + ret = -EINVAL; goto bye; } --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_init.c +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_init.c @@ -1257,3 +1257,4 @@ MODULE_VERSION(CSIO_DRV_VERSION); MODULE_FIRMWARE(FW_FNAME_T5); MODULE_FIRMWARE(FW_FNAME_T6); +MODULE_SOFTDEP("pre: cxgb4"); --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_lnode.c +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_lnode.c @@ -301,6 +301,7 @@ struct fc_fdmi_port_name *port_name; uint8_t buf[64]; uint8_t *fc4_type; + unsigned long flags; if (fdmi_req->wr_status != FW_SUCCESS) { csio_ln_dbg(ln, "WR error:%x in processing fdmi rhba cmd\n", @@ -385,13 +386,13 @@ len = (uint32_t)(pld - (uint8_t *)cmd); /* Submit FDMI RPA request */ - spin_lock_irq(&hw->lock); + spin_lock_irqsave(&hw->lock, flags); if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_done, FCOE_CT, &fdmi_req->dma_buf, len)) { CSIO_INC_STATS(ln, n_fdmi_err); csio_ln_dbg(ln, "Failed to issue fdmi rpa req\n"); } - spin_unlock_irq(&hw->lock); + spin_unlock_irqrestore(&hw->lock, flags); } /* @@ -412,6 +413,7 @@ struct fc_fdmi_rpl *reg_pl; struct fs_fdmi_attrs *attrib_blk; uint8_t buf[64]; + unsigned long flags; if (fdmi_req->wr_status != FW_SUCCESS) { csio_ln_dbg(ln, "WR error:%x in processing fdmi dprt cmd\n", @@ -491,13 +493,13 @@ attrib_blk->numattrs = htonl(numattrs); /* Submit FDMI RHBA request */ - spin_lock_irq(&hw->lock); + spin_lock_irqsave(&hw->lock, flags); if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_rhba_cbfn, FCOE_CT, &fdmi_req->dma_buf, len)) { CSIO_INC_STATS(ln, n_fdmi_err); csio_ln_dbg(ln, "Failed to issue fdmi rhba req\n"); } - spin_unlock_irq(&hw->lock); + spin_unlock_irqrestore(&hw->lock, flags); } /* @@ -512,6 +514,7 @@ void *cmd; struct fc_fdmi_port_name *port_name; uint32_t len; + unsigned long flags; if (fdmi_req->wr_status != FW_SUCCESS) { csio_ln_dbg(ln, "WR error:%x in processing fdmi dhba cmd\n", @@ -542,13 +545,13 @@ len += sizeof(*port_name); /* Submit FDMI request */ - spin_lock_irq(&hw->lock); + spin_lock_irqsave(&hw->lock, flags); if (csio_ln_mgmt_submit_req(fdmi_req, csio_ln_fdmi_dprt_cbfn, FCOE_CT, &fdmi_req->dma_buf, len)) { CSIO_INC_STATS(ln, n_fdmi_err); csio_ln_dbg(ln, "Failed to issue fdmi dprt req\n"); } - spin_unlock_irq(&hw->lock); + spin_unlock_irqrestore(&hw->lock, flags); } /** @@ -616,7 +619,7 @@ struct fc_els_csp *csp; struct fc_els_cssp *clsp; enum fw_retval retval; - __be32 nport_id; + __be32 nport_id = 0; retval = FW_CMD_RETVAL_G(ntohl(rsp->alloc_to_len16)); if (retval != FW_SUCCESS) { @@ -1092,7 +1095,7 @@ int csio_is_lnode_ready(struct csio_lnode *ln) { - return (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)); + return (csio_get_state(ln) == csio_lns_ready); } /*****************************************************************************/ @@ -1364,15 +1367,15 @@ void csio_lnode_state_to_str(struct csio_lnode *ln, int8_t *str) { - if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_uninit)) { + if (csio_get_state(ln) == csio_lns_uninit) { strcpy(str, "UNINIT"); return; } - if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_ready)) { + if (csio_get_state(ln) == csio_lns_ready) { strcpy(str, "READY"); return; } - if (csio_get_state(ln) == ((csio_sm_state_t)csio_lns_offline)) { + if (csio_get_state(ln) == csio_lns_offline) { strcpy(str, "OFFLINE"); return; } --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_lnode.h +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_lnode.h @@ -53,19 +53,6 @@ extern int csio_fcoe_rnodes; extern int csio_fdmi_enable; -/* State machine evets */ -enum csio_ln_ev { - CSIO_LNE_NONE = (uint32_t)0, - CSIO_LNE_LINKUP, - CSIO_LNE_FAB_INIT_DONE, - CSIO_LNE_LINK_DOWN, - CSIO_LNE_DOWN_LINK, - CSIO_LNE_LOGO, - CSIO_LNE_CLOSE, - CSIO_LNE_MAX_EVENT, -}; - - struct csio_fcf_info { struct list_head list; uint8_t priority; --- linux-oracle-5.4.0.orig/drivers/scsi/csiostor/csio_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/csiostor/csio_scsi.c @@ -1383,7 +1383,7 @@ return -EINVAL; /* Delete NPIV lnodes */ - csio_lnodes_exit(hw, 1); + csio_lnodes_exit(hw, 1); /* Block upper IOs */ csio_lnodes_block_request(hw); --- linux-oracle-5.4.0.orig/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ linux-oracle-5.4.0/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -959,6 +959,7 @@ struct net_device *ndev = cdev->ports[csk->port_id]; struct cxgbi_hba *chba = cdev->hbas[csk->port_id]; struct sk_buff *skb = NULL; + int ret; log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, "csk 0x%p,%u,0x%lx.\n", csk, csk->state, csk->flags); @@ -979,16 +980,16 @@ csk->atid = cxgb3_alloc_atid(t3dev, &t3_client, csk); if (csk->atid < 0) { pr_err("NO atid available.\n"); - return -EINVAL; + ret = -EINVAL; + goto put_sock; } cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); cxgbi_sock_get(csk); skb = alloc_wr(sizeof(struct cpl_act_open_req), 0, GFP_KERNEL); if (!skb) { - cxgb3_free_atid(t3dev, csk->atid); - cxgbi_sock_put(csk); - return -ENOMEM; + ret = -ENOMEM; + goto free_atid; } skb->sk = (struct sock *)csk; set_arp_failure_handler(skb, act_open_arp_failure); @@ -1010,6 +1011,15 @@ cxgbi_sock_set_state(csk, CTP_ACTIVE_OPEN); send_act_open_req(csk, skb, csk->l2t); return 0; + +free_atid: + cxgb3_free_atid(t3dev, csk->atid); +put_sock: + cxgbi_sock_put(csk); + l2t_release(t3dev, csk->l2t); + csk->l2t = NULL; + + return ret; } cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS] = { --- linux-oracle-5.4.0.orig/drivers/scsi/cxgbi/cxgb4i/Kconfig +++ linux-oracle-5.4.0/drivers/scsi/cxgbi/cxgb4i/Kconfig @@ -4,6 +4,7 @@ depends on PCI && INET && (IPV6 || IPV6=n) depends on THERMAL || !THERMAL depends on ETHERNET + depends on TLS || TLS=n select NET_VENDOR_CHELSIO select CHELSIO_T4 select CHELSIO_LIB --- linux-oracle-5.4.0.orig/drivers/scsi/cxgbi/libcxgbi.c +++ linux-oracle-5.4.0/drivers/scsi/cxgbi/libcxgbi.c @@ -121,7 +121,8 @@ "cdev 0x%p, p# %u.\n", cdev, cdev->nports); cxgbi_hbas_remove(cdev); cxgbi_device_portmap_cleanup(cdev); - cxgbi_ppm_release(cdev->cdev2ppm(cdev)); + if (cdev->cdev2ppm) + cxgbi_ppm_release(cdev->cdev2ppm(cdev)); if (cdev->pmap.max_connect) cxgbi_free_big_mem(cdev->pmap.port_csk); kfree(cdev); @@ -336,7 +337,7 @@ EXPORT_SYMBOL_GPL(cxgbi_hbas_remove); int cxgbi_hbas_add(struct cxgbi_device *cdev, u64 max_lun, - unsigned int max_id, struct scsi_host_template *sht, + unsigned int max_conns, struct scsi_host_template *sht, struct scsi_transport_template *stt) { struct cxgbi_hba *chba; @@ -356,7 +357,7 @@ shost->transportt = stt; shost->max_lun = max_lun; - shost->max_id = max_id; + shost->max_id = max_conns - 1; shost->max_channel = 0; shost->max_cmd_len = 16; --- linux-oracle-5.4.0.orig/drivers/scsi/cxlflash/main.c +++ linux-oracle-5.4.0/drivers/scsi/cxlflash/main.c @@ -3746,6 +3746,7 @@ cfg->afu_cookie = cfg->ops->create_afu(pdev); if (unlikely(!cfg->afu_cookie)) { dev_err(dev, "%s: create_afu failed\n", __func__); + rc = -ENOMEM; goto out_remove; } --- linux-oracle-5.4.0.orig/drivers/scsi/dc395x.c +++ linux-oracle-5.4.0/drivers/scsi/dc395x.c @@ -3664,10 +3664,19 @@ #endif if (dcb->target_lun != 0) { /* Copy settings */ - struct DeviceCtlBlk *p; - list_for_each_entry(p, &acb->dcb_list, list) - if (p->target_id == dcb->target_id) + struct DeviceCtlBlk *p = NULL, *iter; + + list_for_each_entry(iter, &acb->dcb_list, list) + if (iter->target_id == dcb->target_id) { + p = iter; break; + } + + if (!p) { + kfree(dcb); + return NULL; + } + dprintkdbg(DBG_1, "device_alloc: <%02i-%i> copy from <%02i-%i>\n", dcb->target_id, dcb->target_lun, @@ -4159,7 +4168,7 @@ const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; int srb_idx = 0; unsigned i = 0; - struct SGentry *uninitialized_var(ptr); + struct SGentry *ptr; for (i = 0; i < DC395x_MAX_SRB_CNT; i++) acb->srb_array[i].segment_x = NULL; @@ -4698,6 +4707,7 @@ /* initialise the adapter and everything we need */ if (adapter_init(acb, io_port_base, io_port_len, irq)) { dprintkl(KERN_INFO, "adapter init failed\n"); + acb = NULL; goto fail; } --- linux-oracle-5.4.0.orig/drivers/scsi/device_handler/scsi_dh_alua.c +++ linux-oracle-5.4.0/drivers/scsi/device_handler/scsi_dh_alua.c @@ -508,7 +508,8 @@ struct alua_port_group *tmp_pg; int len, k, off, bufflen = ALUA_RTPG_SIZE; unsigned char *desc, *buff; - unsigned err, retval; + unsigned err; + int retval; unsigned int tpg_desc_tbl_off; unsigned char orig_transition_tmo; unsigned long flags; @@ -548,12 +549,12 @@ kfree(buff); return SCSI_DH_OK; } - if (!scsi_sense_valid(&sense_hdr)) { + if (retval < 0 || !scsi_sense_valid(&sense_hdr)) { sdev_printk(KERN_INFO, sdev, "%s: rtpg failed, result %d\n", ALUA_DH_NAME, retval); kfree(buff); - if (driver_byte(retval) == DRIVER_ERROR) + if (retval < 0) return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_IO; } @@ -565,10 +566,11 @@ * even though it shouldn't according to T10. * The retry without rtpg_ext_hdr_req set * handles this. + * Note: some arrays return a sense key of ILLEGAL_REQUEST + * with ASC 00h if they don't support the extended header. */ if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) && - sense_hdr.sense_key == ILLEGAL_REQUEST && - sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) { + sense_hdr.sense_key == ILLEGAL_REQUEST) { pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } @@ -658,8 +660,8 @@ rcu_read_lock(); list_for_each_entry_rcu(h, &tmp_pg->dh_list, node) { - /* h->sdev should always be valid */ - BUG_ON(!h->sdev); + if (!h->sdev) + continue; h->sdev->access_state = desc[0]; } rcu_read_unlock(); @@ -705,7 +707,8 @@ pg->expiry = 0; rcu_read_lock(); list_for_each_entry_rcu(h, &pg->dh_list, node) { - BUG_ON(!h->sdev); + if (!h->sdev) + continue; h->sdev->access_state = (pg->state & SCSI_ACCESS_STATE_MASK); if (pg->pref) @@ -773,11 +776,11 @@ retval = submit_stpg(sdev, pg->group_id, &sense_hdr); if (retval) { - if (!scsi_sense_valid(&sense_hdr)) { + if (retval < 0 || !scsi_sense_valid(&sense_hdr)) { sdev_printk(KERN_INFO, sdev, "%s: stpg failed, result %d", ALUA_DH_NAME, retval); - if (driver_byte(retval) == DRIVER_ERROR) + if (retval < 0) return SCSI_DH_DEV_TEMP_BUSY; } else { sdev_printk(KERN_INFO, sdev, "%s: stpg failed\n", @@ -1033,10 +1036,12 @@ rcu_read_unlock(); mutex_unlock(&h->init_mutex); - if (alua_rtpg_queue(pg, sdev, qdata, true)) + if (alua_rtpg_queue(pg, sdev, qdata, true)) { fn = NULL; - else + } else { + kfree(qdata); err = SCSI_DH_DEV_OFFLINED; + } kref_put(&pg->kref, release_port_group); out: if (fn) @@ -1147,7 +1152,6 @@ spin_lock(&h->pg_lock); pg = rcu_dereference_protected(h->pg, lockdep_is_held(&h->pg_lock)); rcu_assign_pointer(h->pg, NULL); - h->sdev = NULL; spin_unlock(&h->pg_lock); if (pg) { spin_lock_irq(&pg->lock); @@ -1156,6 +1160,7 @@ kref_put(&pg->kref, release_port_group); } sdev->handler_data = NULL; + synchronize_rcu(); kfree(h); } --- linux-oracle-5.4.0.orig/drivers/scsi/device_handler/scsi_dh_rdac.c +++ linux-oracle-5.4.0/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -453,8 +453,8 @@ if (!h->ctlr) err = SCSI_DH_RES_TEMP_UNAVAIL; else { - list_add_rcu(&h->node, &h->ctlr->dh_list); h->sdev = sdev; + list_add_rcu(&h->node, &h->ctlr->dh_list); } spin_unlock(&list_lock); err = SCSI_DH_OK; @@ -778,11 +778,11 @@ spin_lock(&list_lock); if (h->ctlr) { list_del_rcu(&h->node); - h->sdev = NULL; kref_put(&h->ctlr->kref, release_controller); } spin_unlock(&list_lock); sdev->handler_data = NULL; + synchronize_rcu(); kfree(h); } --- linux-oracle-5.4.0.orig/drivers/scsi/dpt_i2o.c +++ linux-oracle-5.4.0/drivers/scsi/dpt_i2o.c @@ -56,7 +56,7 @@ #include /* for boot_cpu_data */ #include -#include /* for virt_to_bus, etc. */ +#include #include #include @@ -585,51 +585,6 @@ return 0; } -/* - * Turn a pointer to ioctl reply data into an u32 'context' - */ -static u32 adpt_ioctl_to_context(adpt_hba * pHba, void *reply) -{ -#if BITS_PER_LONG == 32 - return (u32)(unsigned long)reply; -#else - ulong flags = 0; - u32 nr, i; - - spin_lock_irqsave(pHba->host->host_lock, flags); - nr = ARRAY_SIZE(pHba->ioctl_reply_context); - for (i = 0; i < nr; i++) { - if (pHba->ioctl_reply_context[i] == NULL) { - pHba->ioctl_reply_context[i] = reply; - break; - } - } - spin_unlock_irqrestore(pHba->host->host_lock, flags); - if (i >= nr) { - printk(KERN_WARNING"%s: Too many outstanding " - "ioctl commands\n", pHba->name); - return (u32)-1; - } - - return i; -#endif -} - -/* - * Go from an u32 'context' to a pointer to ioctl reply data. - */ -static void *adpt_ioctl_from_context(adpt_hba *pHba, u32 context) -{ -#if BITS_PER_LONG == 32 - return (void *)(unsigned long)context; -#else - void *p = pHba->ioctl_reply_context[context]; - pHba->ioctl_reply_context[context] = NULL; - - return p; -#endif -} - /*=========================================================================== * Error Handling routines *=========================================================================== @@ -1652,208 +1607,6 @@ return 0; } - -static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) -{ - u32 msg[MAX_MESSAGE_SIZE]; - u32* reply = NULL; - u32 size = 0; - u32 reply_size = 0; - u32 __user *user_msg = arg; - u32 __user * user_reply = NULL; - void **sg_list = NULL; - u32 sg_offset = 0; - u32 sg_count = 0; - int sg_index = 0; - u32 i = 0; - u32 rcode = 0; - void *p = NULL; - dma_addr_t addr; - ulong flags = 0; - - memset(&msg, 0, MAX_MESSAGE_SIZE*4); - // get user msg size in u32s - if(get_user(size, &user_msg[0])){ - return -EFAULT; - } - size = size>>16; - - user_reply = &user_msg[size]; - if(size > MAX_MESSAGE_SIZE){ - return -EFAULT; - } - size *= 4; // Convert to bytes - - /* Copy in the user's I2O command */ - if(copy_from_user(msg, user_msg, size)) { - return -EFAULT; - } - get_user(reply_size, &user_reply[0]); - reply_size = reply_size>>16; - if(reply_size > REPLY_FRAME_SIZE){ - reply_size = REPLY_FRAME_SIZE; - } - reply_size *= 4; - reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL); - if(reply == NULL) { - printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name); - return -ENOMEM; - } - sg_offset = (msg[0]>>4)&0xf; - msg[2] = 0x40000000; // IOCTL context - msg[3] = adpt_ioctl_to_context(pHba, reply); - if (msg[3] == (u32)-1) { - rcode = -EBUSY; - goto free; - } - - sg_list = kcalloc(pHba->sg_tablesize, sizeof(*sg_list), GFP_KERNEL); - if (!sg_list) { - rcode = -ENOMEM; - goto free; - } - if(sg_offset) { - // TODO add 64 bit API - struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset); - sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); - if (sg_count > pHba->sg_tablesize){ - printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count); - rcode = -EINVAL; - goto free; - } - - for(i = 0; i < sg_count; i++) { - int sg_size; - - if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) { - printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count); - rcode = -EINVAL; - goto cleanup; - } - sg_size = sg[i].flag_count & 0xffffff; - /* Allocate memory for the transfer */ - p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL); - if(!p) { - printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - pHba->name,sg_size,i,sg_count); - rcode = -ENOMEM; - goto cleanup; - } - sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame. - /* Copy in the user's SG buffer if necessary */ - if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) { - // sg_simple_element API is 32 bit - if (copy_from_user(p,(void __user *)(ulong)sg[i].addr_bus, sg_size)) { - printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i); - rcode = -EFAULT; - goto cleanup; - } - } - /* sg_simple_element API is 32 bit, but addr < 4GB */ - sg[i].addr_bus = addr; - } - } - - do { - /* - * Stop any new commands from enterring the - * controller while processing the ioctl - */ - if (pHba->host) { - scsi_block_requests(pHba->host); - spin_lock_irqsave(pHba->host->host_lock, flags); - } - rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER); - if (rcode != 0) - printk("adpt_i2o_passthru: post wait failed %d %p\n", - rcode, reply); - if (pHba->host) { - spin_unlock_irqrestore(pHba->host->host_lock, flags); - scsi_unblock_requests(pHba->host); - } - } while (rcode == -ETIMEDOUT); - - if(rcode){ - goto cleanup; - } - - if(sg_offset) { - /* Copy back the Scatter Gather buffers back to user space */ - u32 j; - // TODO add 64 bit API - struct sg_simple_element* sg; - int sg_size; - - // re-acquire the original message to handle correctly the sg copy operation - memset(&msg, 0, MAX_MESSAGE_SIZE*4); - // get user msg size in u32s - if(get_user(size, &user_msg[0])){ - rcode = -EFAULT; - goto cleanup; - } - size = size>>16; - size *= 4; - if (size > MAX_MESSAGE_SIZE) { - rcode = -EINVAL; - goto cleanup; - } - /* Copy in the user's I2O command */ - if (copy_from_user (msg, user_msg, size)) { - rcode = -EFAULT; - goto cleanup; - } - sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element); - - // TODO add 64 bit API - sg = (struct sg_simple_element*)(msg + sg_offset); - for (j = 0; j < sg_count; j++) { - /* Copy out the SG list to user's buffer if necessary */ - if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) { - sg_size = sg[j].flag_count & 0xffffff; - // sg_simple_element API is 32 bit - if (copy_to_user((void __user *)(ulong)sg[j].addr_bus,sg_list[j], sg_size)) { - printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus); - rcode = -EFAULT; - goto cleanup; - } - } - } - } - - /* Copy back the reply to user space */ - if (reply_size) { - // we wrote our own values for context - now restore the user supplied ones - if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) { - printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name); - rcode = -EFAULT; - } - if(copy_to_user(user_reply, reply, reply_size)) { - printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name); - rcode = -EFAULT; - } - } - - -cleanup: - if (rcode != -ETIME && rcode != -EINTR) { - struct sg_simple_element *sg = - (struct sg_simple_element*) (msg +sg_offset); - while(sg_index) { - if(sg_list[--sg_index]) { - dma_free_coherent(&pHba->pDev->dev, - sg[sg_index].flag_count & 0xffffff, - sg_list[sg_index], - sg[sg_index].addr_bus); - } - } - } - -free: - kfree(sg_list); - kfree(reply); - return rcode; -} - #if defined __ia64__ static void adpt_ia64_info(sysInfo_S* si) { @@ -1980,8 +1733,6 @@ return -EFAULT; } break; - case I2OUSRCMD: - return adpt_i2o_passthru(pHba, argp); case DPT_CTRLINFO:{ drvrHBAinfo_S HbaInfo; @@ -2118,7 +1869,7 @@ } else { /* Ick, we should *never* be here */ printk(KERN_ERR "dpti: reply frame not from pool\n"); - reply = (u8 *)bus_to_virt(m); + continue; } if (readl(reply) & MSG_FAIL) { @@ -2138,13 +1889,6 @@ adpt_send_nop(pHba, old_m); } context = readl(reply+8); - if(context & 0x40000000){ // IOCTL - void *p = adpt_ioctl_from_context(pHba, readl(reply+12)); - if( p != NULL) { - memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4); - } - // All IOCTLs will also be post wait - } if(context & 0x80000000){ // Post wait message status = readl(reply+16); if(status >> 24){ @@ -2152,16 +1896,14 @@ } else { status = I2O_POST_WAIT_OK; } - if(!(context & 0x40000000)) { - /* - * The request tag is one less than the command tag - * as the firmware might treat a 0 tag as invalid - */ - cmd = scsi_host_find_tag(pHba->host, - readl(reply + 12) - 1); - if(cmd != NULL) { - printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); - } + /* + * The request tag is one less than the command tag + * as the firmware might treat a 0 tag as invalid + */ + cmd = scsi_host_find_tag(pHba->host, + readl(reply + 12) - 1); + if(cmd != NULL) { + printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context); } adpt_i2o_post_wait_complete(context, status); } else { // SCSI message --- linux-oracle-5.4.0.orig/drivers/scsi/dpti.h +++ linux-oracle-5.4.0/drivers/scsi/dpti.h @@ -248,7 +248,6 @@ void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED u32 FwDebugFlags; - u32 *ioctl_reply_context[4]; } adpt_hba; struct sg_simple_element { --- linux-oracle-5.4.0.orig/drivers/scsi/esas2r/esas2r_flash.c +++ linux-oracle-5.4.0/drivers/scsi/esas2r/esas2r_flash.c @@ -1197,6 +1197,7 @@ if (!esas2r_read_flash_block(a, a->nvram, FLS_OFFSET_NVR, sizeof(struct esas2r_sas_nvram))) { esas2r_hdebug("NVRAM read failed, using defaults"); + up(&a->nvram_semaphore); return false; } --- linux-oracle-5.4.0.orig/drivers/scsi/fcoe/fcoe.c +++ linux-oracle-5.4.0/drivers/scsi/fcoe/fcoe.c @@ -2506,6 +2506,7 @@ out_free: mutex_unlock(&fcoe_config_mutex); + fcoe_transport_detach(&fcoe_sw_transport); out_destroy: destroy_workqueue(fcoe_wq); return rc; --- linux-oracle-5.4.0.orig/drivers/scsi/fcoe/fcoe_ctlr.c +++ linux-oracle-5.4.0/drivers/scsi/fcoe/fcoe_ctlr.c @@ -255,9 +255,9 @@ WARN_ON(!fcf_dev); new->fcf_dev = NULL; fcoe_fcf_device_delete(fcf_dev); - kfree(new); mutex_unlock(&cdev->lock); } + kfree(new); } /** @@ -1966,7 +1966,7 @@ * * Returns: u64 fc world wide name */ -u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], +u64 fcoe_wwn_from_mac(unsigned char mac[ETH_ALEN], unsigned int scheme, unsigned int port) { u64 wwn; --- linux-oracle-5.4.0.orig/drivers/scsi/fcoe/fcoe_sysfs.c +++ linux-oracle-5.4.0/drivers/scsi/fcoe/fcoe_sysfs.c @@ -830,14 +830,15 @@ dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); error = device_register(&ctlr->dev); - if (error) - goto out_del_q2; + if (error) { + destroy_workqueue(ctlr->devloss_work_q); + destroy_workqueue(ctlr->work_q); + put_device(&ctlr->dev); + return NULL; + } return ctlr; -out_del_q2: - destroy_workqueue(ctlr->devloss_work_q); - ctlr->devloss_work_q = NULL; out_del_q: destroy_workqueue(ctlr->work_q); ctlr->work_q = NULL; @@ -1036,16 +1037,16 @@ fcf->selected = new_fcf->selected; error = device_register(&fcf->dev); - if (error) - goto out_del; + if (error) { + put_device(&fcf->dev); + goto out; + } fcf->state = FCOE_FCF_STATE_CONNECTED; list_add_tail(&fcf->peers, &ctlr->fcfs); return fcf; -out_del: - kfree(fcf); out: return NULL; } --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/fnic.h +++ linux-oracle-5.4.0/drivers/scsi/fnic/fnic.h @@ -39,7 +39,7 @@ #define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.6.0.47" +#define DRV_VERSION "1.6.0.53" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: " @@ -245,6 +245,7 @@ u32 vlan_hw_insert:1; /* let hw insert the tag */ u32 in_remove:1; /* fnic device in removal */ u32 stop_rx_link_events:1; /* stop proc. rx frames, link events */ + u32 link_events:1; /* set when we get any link event*/ struct completion *remove_wait; /* device remove thread blocks */ --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/fnic_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/fnic/fnic_debugfs.c @@ -67,9 +67,10 @@ fc_trc_flag->fnic_trace = 2; fc_trc_flag->fc_trace = 3; fc_trc_flag->fc_clear = 4; + return 0; } - return 0; + return -ENOMEM; } /* --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/fnic_fcs.c +++ linux-oracle-5.4.0/drivers/scsi/fnic/fnic_fcs.c @@ -56,6 +56,8 @@ spin_lock_irqsave(&fnic->fnic_lock, flags); + fnic->link_events = 1; /* less work to just set everytime*/ + if (fnic->stop_rx_link_events) { spin_unlock_irqrestore(&fnic->fnic_lock, flags); return; @@ -73,7 +75,7 @@ atomic64_set(&fnic->fnic_stats.misc_stats.current_port_speed, new_port_speed); if (old_port_speed != new_port_speed) - shost_printk(KERN_INFO, fnic->lport->host, + FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host, "Current vnic speed set to : %llu\n", new_port_speed); @@ -1358,7 +1360,7 @@ } vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list); - shost_printk(KERN_DEBUG, fnic->lport->host, + FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "fip_timer: vlan %d state %d sol_count %d\n", vlan->vid, vlan->state, vlan->sol_count); switch (vlan->state) { @@ -1381,7 +1383,7 @@ * no response on this vlan, remove from the list. * Try the next vlan */ - shost_printk(KERN_INFO, fnic->lport->host, + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, "Dequeue this VLAN ID %d from list\n", vlan->vid); list_del(&vlan->list); @@ -1391,7 +1393,7 @@ /* we exhausted all vlans, restart vlan disc */ spin_unlock_irqrestore(&fnic->vlans_lock, flags); - shost_printk(KERN_INFO, fnic->lport->host, + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, "fip_timer: vlan list empty, " "trigger vlan disc\n"); fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/fnic_main.c +++ linux-oracle-5.4.0/drivers/scsi/fnic/fnic_main.c @@ -581,6 +581,8 @@ fnic->lport = lp; fnic->ctlr.lp = lp; + fnic->link_events = 0; + snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME, host->host_no); @@ -741,6 +743,7 @@ for (i = 0; i < FNIC_IO_LOCKS; i++) spin_lock_init(&fnic->io_req_lock[i]); + err = -ENOMEM; fnic->io_req_pool = mempool_create_slab_pool(2, fnic_io_req_cache); if (!fnic->io_req_pool) goto err_out_free_resources; --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/fnic_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/fnic/fnic_scsi.c @@ -439,6 +439,9 @@ if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_IO_BLOCKED))) return SCSI_MLQUEUE_HOST_BUSY; + if (unlikely(fnic_chk_state_flags_locked(fnic, FNIC_FLAGS_FWRESET))) + return SCSI_MLQUEUE_HOST_BUSY; + rport = starget_to_rport(scsi_target(sc->device)); if (!rport) { FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, @@ -917,10 +920,11 @@ case FCPIO_SUCCESS: sc->result = (DID_OK << 16) | icmnd_cmpl->scsi_status; xfer_len = scsi_bufflen(sc); - scsi_set_resid(sc, icmnd_cmpl->residual); - if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER) + if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER) { xfer_len -= icmnd_cmpl->residual; + scsi_set_resid(sc, icmnd_cmpl->residual); + } if (icmnd_cmpl->scsi_status == SAM_STAT_CHECK_CONDITION) atomic64_inc(&fnic_stats->misc_stats.check_condition); @@ -1024,7 +1028,8 @@ atomic64_inc(&fnic_stats->io_stats.io_completions); - io_duration_time = jiffies_to_msecs(jiffies) - jiffies_to_msecs(io_req->start_time); + io_duration_time = jiffies_to_msecs(jiffies) - + jiffies_to_msecs(start_time); if(io_duration_time <= 10) atomic64_inc(&fnic_stats->io_stats.io_btw_0_to_10_msec); @@ -1397,7 +1402,7 @@ } if (!io_req) { spin_unlock_irqrestore(io_lock, flags); - goto cleanup_scsi_cmd; + continue; } CMD_SP(sc) = NULL; @@ -1412,7 +1417,6 @@ fnic_release_ioreq_buf(fnic, io_req, sc); mempool_free(io_req, fnic->io_req_pool); -cleanup_scsi_cmd: sc->result = DID_TRANSPORT_DISRUPTED << 16; FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "%s: tag:0x%x : sc:0x%p duration = %lu DID_TRANSPORT_DISRUPTED\n", @@ -1730,15 +1734,14 @@ continue; } - cmd_rport = starget_to_rport(scsi_target(sc->device)); - if (rport != cmd_rport) { + io_req = (struct fnic_io_req *)CMD_SP(sc); + if (!io_req) { spin_unlock_irqrestore(io_lock, flags); continue; } - io_req = (struct fnic_io_req *)CMD_SP(sc); - - if (!io_req || rport != cmd_rport) { + cmd_rport = starget_to_rport(scsi_target(sc->device)); + if (rport != cmd_rport) { spin_unlock_irqrestore(io_lock, flags); continue; } @@ -2669,7 +2672,8 @@ /* Issue firmware reset for fnic, wait for reset to complete */ retry_fw_reset: spin_lock_irqsave(&fnic->fnic_lock, flags); - if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)) { + if (unlikely(fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) && + fnic->link_events) { /* fw reset is in progress, poll for its completion */ spin_unlock_irqrestore(&fnic->fnic_lock, flags); schedule_timeout(msecs_to_jiffies(100)); --- linux-oracle-5.4.0.orig/drivers/scsi/fnic/vnic_dev.c +++ linux-oracle-5.4.0/drivers/scsi/fnic/vnic_dev.c @@ -444,7 +444,8 @@ fetch_index = ioread32(&vdev->devcmd2->wq.ctrl->fetch_index); if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone */ pr_err("error in devcmd2 init"); - return -ENODEV; + err = -ENODEV; + goto err_free_wq; } /* @@ -460,7 +461,7 @@ err = vnic_dev_alloc_desc_ring(vdev, &vdev->devcmd2->results_ring, DEVCMD2_RING_SIZE, DEVCMD2_DESC_SIZE); if (err) - goto err_free_wq; + goto err_disable_wq; vdev->devcmd2->result = (struct devcmd2_result *) vdev->devcmd2->results_ring.descs; @@ -481,8 +482,9 @@ err_free_desc_ring: vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring); -err_free_wq: +err_disable_wq: vnic_wq_disable(&vdev->devcmd2->wq); +err_free_wq: vnic_wq_free(&vdev->devcmd2->wq); err_free_devcmd2: kfree(vdev->devcmd2); @@ -688,26 +690,26 @@ int vnic_dev_hang_notify(struct vnic_dev *vdev) { - u64 a0, a1; + u64 a0 = 0, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait); } int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr) { - u64 a0, a1; + u64 a[2] = {}; int wait = 1000; int err, i; for (i = 0; i < ETH_ALEN; i++) mac_addr[i] = 0; - err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait); + err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a[0], &a[1], wait); if (err) return err; for (i = 0; i < ETH_ALEN; i++) - mac_addr[i] = ((u8 *)&a0)[i]; + mac_addr[i] = ((u8 *)&a)[i]; return 0; } @@ -732,30 +734,30 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) { - u64 a0 = 0, a1 = 0; + u64 a[2] = {}; int wait = 1000; int err; int i; for (i = 0; i < ETH_ALEN; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); + err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a[0], &a[1], wait); if (err) pr_err("Can't add addr [%pM], %d\n", addr, err); } void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) { - u64 a0 = 0, a1 = 0; + u64 a[2] = {}; int wait = 1000; int err; int i; for (i = 0; i < ETH_ALEN; i++) - ((u8 *)&a0)[i] = addr[i]; + ((u8 *)&a)[i] = addr[i]; - err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); + err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a[0], &a[1], wait); if (err) pr_err("Can't del addr [%pM], %d\n", addr, err); } --- linux-oracle-5.4.0.orig/drivers/scsi/hisi_sas/hisi_sas.h +++ linux-oracle-5.4.0/drivers/scsi/hisi_sas/hisi_sas.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,7 @@ #define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK | HISI_SAS_DIX_PROT_MASK) #define HISI_SAS_WAIT_PHYUP_TIMEOUT 20 +#define CLEAR_ITCT_TIMEOUT 20 struct hisi_hba; @@ -167,6 +169,7 @@ enum sas_linkrate minimum_linkrate; enum sas_linkrate maximum_linkrate; int enable; + atomic_t down_cnt; }; struct hisi_sas_port { @@ -177,10 +180,10 @@ struct hisi_sas_cq { struct hisi_hba *hisi_hba; - const struct cpumask *pci_irq_mask; - struct tasklet_struct tasklet; + const struct cpumask *irq_mask; int rd_point; int id; + int irq_no; }; struct hisi_sas_dq { @@ -296,8 +299,8 @@ void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no, struct sas_phy_linkrates *linkrates); enum sas_linkrate (*phy_get_max_linkrate)(void); - void (*clear_itct)(struct hisi_hba *hisi_hba, - struct hisi_sas_device *dev); + int (*clear_itct)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *dev); void (*free_device)(struct hisi_sas_device *sas_dev); int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id); void (*dereg_device)(struct hisi_hba *hisi_hba, @@ -321,6 +324,44 @@ const struct hisi_sas_debugfs_reg *debugfs_reg_port; }; +#define HISI_SAS_MAX_DEBUGFS_DUMP (50) + +struct hisi_sas_debugfs_cq { + struct hisi_sas_cq *cq; + void *complete_hdr; +}; + +struct hisi_sas_debugfs_dq { + struct hisi_sas_dq *dq; + struct hisi_sas_cmd_hdr *hdr; +}; + +struct hisi_sas_debugfs_regs { + struct hisi_hba *hisi_hba; + u32 *data; +}; + +struct hisi_sas_debugfs_port { + struct hisi_sas_phy *phy; + u32 *data; +}; + +struct hisi_sas_debugfs_iost { + struct hisi_sas_iost *iost; +}; + +struct hisi_sas_debugfs_itct { + struct hisi_sas_itct *itct; +}; + +struct hisi_sas_debugfs_iost_cache { + struct hisi_sas_iost_itct_cache *cache; +}; + +struct hisi_sas_debugfs_itct_cache { + struct hisi_sas_iost_itct_cache *cache; +}; + struct hisi_hba { /* This must be the first element, used by SHOST_TO_SAS_HA */ struct sas_ha_struct *p; @@ -402,19 +443,20 @@ /* debugfs memories */ /* Put Global AXI and RAS Register into register array */ - u32 *debugfs_regs[DEBUGFS_REGS_NUM]; - u32 *debugfs_port_reg[HISI_SAS_MAX_PHYS]; - void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES]; - struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES]; - struct hisi_sas_iost *debugfs_iost; - struct hisi_sas_itct *debugfs_itct; - u64 *debugfs_iost_cache; - u64 *debugfs_itct_cache; + struct hisi_sas_debugfs_regs debugfs_regs[HISI_SAS_MAX_DEBUGFS_DUMP][DEBUGFS_REGS_NUM]; + struct hisi_sas_debugfs_port debugfs_port_reg[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_PHYS]; + struct hisi_sas_debugfs_cq debugfs_cq[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_dq debugfs_dq[HISI_SAS_MAX_DEBUGFS_DUMP][HISI_SAS_MAX_QUEUES]; + struct hisi_sas_debugfs_iost debugfs_iost[HISI_SAS_MAX_DEBUGFS_DUMP]; + struct hisi_sas_debugfs_itct debugfs_itct[HISI_SAS_MAX_DEBUGFS_DUMP]; + struct hisi_sas_debugfs_iost_cache debugfs_iost_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; + struct hisi_sas_debugfs_itct_cache debugfs_itct_cache[HISI_SAS_MAX_DEBUGFS_DUMP]; + u64 debugfs_timestamp[HISI_SAS_MAX_DEBUGFS_DUMP]; + int debugfs_dump_index; struct dentry *debugfs_dir; struct dentry *debugfs_dump_dentry; struct dentry *debugfs_bist_dentry; - bool debugfs_snapshot; }; /* Generic HW DMA host memory structures */ @@ -556,6 +598,7 @@ extern struct scsi_transport_template *hisi_sas_stt; extern bool hisi_sas_debugfs_enable; +extern u32 hisi_sas_debugfs_dump_count; extern struct dentry *hisi_sas_debugfs_dir; extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba); @@ -584,7 +627,7 @@ extern void hisi_sas_init_mem(struct hisi_hba *hisi_hba); extern void hisi_sas_rst_work_handler(struct work_struct *work); extern void hisi_sas_sync_rst_work_handler(struct work_struct *work); -extern void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba); +extern void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba); extern void hisi_sas_phy_oob_ready(struct hisi_hba *hisi_hba, int phy_no); extern bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, enum hisi_sas_phy_event event); --- linux-oracle-5.4.0.orig/drivers/scsi/hisi_sas/hisi_sas_main.c +++ linux-oracle-5.4.0/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -163,13 +163,11 @@ static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) { - unsigned long flags; - if (hisi_hba->hw->slot_index_alloc || slot_idx >= HISI_SAS_UNRESERVED_IPTT) { - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); hisi_sas_slot_index_clear(hisi_hba, slot_idx); - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); } } @@ -185,12 +183,11 @@ { int index; void *bitmap = hisi_hba->slot_index_tags; - unsigned long flags; if (scsi_cmnd) return scsi_cmnd->request->tag; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, hisi_hba->last_slot_index + 1); if (index >= hisi_hba->slot_index_count) { @@ -198,13 +195,13 @@ hisi_hba->slot_index_count, HISI_SAS_UNRESERVED_IPTT); if (index >= hisi_hba->slot_index_count) { - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return -SAS_QUEUE_FULL; } } hisi_sas_slot_index_set(hisi_hba, index); hisi_hba->last_slot_index = index; - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return index; } @@ -220,7 +217,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, struct hisi_sas_slot *slot) { - unsigned long flags; int device_id = slot->device_id; struct hisi_sas_device *sas_dev = &hisi_hba->devices[device_id]; @@ -247,9 +243,9 @@ } } - spin_lock_irqsave(&sas_dev->lock, flags); + spin_lock(&sas_dev->lock); list_del_init(&slot->entry); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); memset(slot, 0, offsetof(struct hisi_sas_slot, buf)); @@ -489,14 +485,14 @@ slot_idx = rc; slot = &hisi_hba->slot_info[slot_idx]; - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); wr_q_index = dq->wr_point; dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS; list_add_tail(&slot->delivery, &dq->list); - spin_unlock_irqrestore(&dq->lock, flags); - spin_lock_irqsave(&sas_dev->lock, flags); + spin_unlock(&dq->lock); + spin_lock(&sas_dev->lock); list_add_tail(&slot->entry, &sas_dev->list); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); dlvry_queue = dq->id; dlvry_queue_slot = wr_q_index; @@ -562,7 +558,6 @@ { u32 rc; u32 pass = 0; - unsigned long flags; struct hisi_hba *hisi_hba; struct device *dev; struct domain_device *device = task->dev; @@ -587,7 +582,13 @@ dev = hisi_hba->dev; if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) { - if (in_softirq()) + /* + * For IOs from upper layer, it may already disable preempt + * in the IO path, if disable preempt again in down(), + * function schedule() will report schedule_bug(), so check + * preemptible() before goto down(). + */ + if (!preemptible()) return -EINVAL; down(&hisi_hba->sem); @@ -600,9 +601,9 @@ dev_err(dev, "task exec: failed[%d]!\n", rc); if (likely(pass)) { - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); hisi_hba->hw->start_delivery(dq); - spin_unlock_irqrestore(&dq->lock, flags); + spin_unlock(&dq->lock); } return rc; @@ -653,12 +654,11 @@ { struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct hisi_sas_device *sas_dev = NULL; - unsigned long flags; int last = hisi_hba->last_dev_id; int first = (hisi_hba->last_dev_id + 1) % HISI_SAS_MAX_DEVICES; int i; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); for (i = first; i != last; i %= HISI_SAS_MAX_DEVICES) { if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) { int queue = i % hisi_hba->queue_count; @@ -678,7 +678,7 @@ i++; } hisi_hba->last_dev_id = i; - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return sas_dev; } @@ -898,8 +898,11 @@ struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct device *dev = hisi_hba->dev; + dev_dbg(dev, "phy%d OOB ready\n", phy_no); + if (phy->phy_attached) + return; + if (!timer_pending(&phy->timer)) { - dev_dbg(dev, "phy%d OOB ready\n", phy_no); phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT * HZ; add_timer(&phy->timer); } @@ -968,12 +971,13 @@ struct hisi_hba *hisi_hba = sas_ha->lldd_ha; struct hisi_sas_phy *phy = sas_phy->lldd_phy; struct asd_sas_port *sas_port = sas_phy->port; - struct hisi_sas_port *port = to_hisi_sas_port(sas_port); + struct hisi_sas_port *port; unsigned long flags; if (!sas_port) return; + port = to_hisi_sas_port(sas_port); spin_lock_irqsave(&hisi_hba->lock, flags); port->port_attached = 1; port->id = phy->port_id; @@ -1045,6 +1049,7 @@ struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct device *dev = hisi_hba->dev; + int ret = 0; dev_info(dev, "dev[%d:%x] is gone\n", sas_dev->device_id, sas_dev->dev_type); @@ -1056,13 +1061,16 @@ hisi_sas_dereg_device(hisi_hba, device); - hisi_hba->hw->clear_itct(hisi_hba, sas_dev); + ret = hisi_hba->hw->clear_itct(hisi_hba, sas_dev); device->lldd_dev = NULL; } if (hisi_hba->hw->free_device) hisi_hba->hw->free_device(sas_dev); - sas_dev->dev_type = SAS_PHY_UNUSED; + + /* Don't mark it as SAS_PHY_UNUSED if failed to clear ITCT */ + if (!ret) + sas_dev->dev_type = SAS_PHY_UNUSED; sas_dev->sas_device = NULL; up(&hisi_hba->sem); } @@ -1222,10 +1230,10 @@ struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } @@ -1387,7 +1395,7 @@ device->linkrate = phy->sas_phy.linkrate; hisi_hba->hw->setup_itct(hisi_hba, sas_dev); - } else + } else if (!port->port_attached) port->id = 0xff; } } @@ -1563,14 +1571,14 @@ struct Scsi_Host *shost = hisi_hba->shost; int rc; - if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); if (!hisi_hba->hw->soft_reset) - return -1; + return -ENOENT; if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - return -1; + return -EPERM; dev_info(dev, "controller resetting...\n"); hisi_sas_controller_reset_prepare(hisi_hba); @@ -1615,11 +1623,11 @@ if (slot) { /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ cq = &hisi_hba->cq[slot->dlvry_queue]; - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); } spin_unlock_irqrestore(&task->task_state_lock, flags); rc = TMF_RESP_FUNC_COMPLETE; @@ -1683,10 +1691,10 @@ if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && task->lldd_task) { /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } } @@ -1954,14 +1962,14 @@ slot_idx = rc; slot = &hisi_hba->slot_info[slot_idx]; - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); wr_q_index = dq->wr_point; dq->wr_point = (dq->wr_point + 1) % HISI_SAS_QUEUE_SLOTS; list_add_tail(&slot->delivery, &dq->list); - spin_unlock_irqrestore(&dq->lock, flags); - spin_lock_irqsave(&sas_dev->lock, flags); + spin_unlock(&dq->lock); + spin_lock(&sas_dev->lock); list_add_tail(&slot->entry, &sas_dev->list); - spin_unlock_irqrestore(&sas_dev->lock, flags); + spin_unlock(&sas_dev->lock); dlvry_queue = dq->id; dlvry_queue_slot = wr_q_index; @@ -1990,9 +1998,9 @@ spin_unlock_irqrestore(&task->task_state_lock, flags); WRITE_ONCE(slot->ready, 1); /* send abort command to the chip */ - spin_lock_irqsave(&dq->lock, flags); + spin_lock(&dq->lock); hisi_hba->hw->start_delivery(dq); - spin_unlock_irqrestore(&dq->lock, flags); + spin_unlock(&dq->lock); return 0; @@ -2055,7 +2063,7 @@ /* Internal abort timed out */ if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct) + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { @@ -2065,10 +2073,10 @@ struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; /* - * flush tasklet to avoid free'ing task + * sync irq to avoid free'ing task * before using task in IO completion */ - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); slot->task = NULL; } dev_err(dev, "internal task abort: timeout and not done.\n"); @@ -2120,7 +2128,7 @@ case HISI_SAS_INT_ABT_DEV: for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - const struct cpumask *mask = cq->pci_irq_mask; + const struct cpumask *mask = cq->irq_mask; if (mask && !cpumask_intersects(cpu_online_mask, mask)) continue; @@ -2214,17 +2222,17 @@ } EXPORT_SYMBOL_GPL(hisi_sas_phy_down); -void hisi_sas_kill_tasklets(struct hisi_hba *hisi_hba) +void hisi_sas_sync_irqs(struct hisi_hba *hisi_hba) { int i; for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - tasklet_kill(&cq->tasklet); + synchronize_irq(cq->irq_no); } } -EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets); +EXPORT_SYMBOL_GPL(hisi_sas_sync_irqs); int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type) { @@ -2676,6 +2684,7 @@ err_out_register_ha: scsi_remove_host(shost); err_out_ha: + hisi_sas_debugfs_exit(hisi_hba); hisi_sas_free(hisi_hba); scsi_host_put(shost); return rc; @@ -2687,10 +2696,11 @@ static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba) { int queue_entry_size = hisi_hba->hw->complete_hdr_size; + int dump_index = hisi_hba->debugfs_dump_index; int i; for (i = 0; i < hisi_hba->queue_count; i++) - memcpy(hisi_hba->debugfs_complete_hdr[i], + memcpy(hisi_hba->debugfs_cq[dump_index][i].complete_hdr, hisi_hba->complete_hdr[i], HISI_SAS_QUEUE_SLOTS * queue_entry_size); } @@ -2698,13 +2708,14 @@ static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba) { int queue_entry_size = sizeof(struct hisi_sas_cmd_hdr); + int dump_index = hisi_hba->debugfs_dump_index; int i; for (i = 0; i < hisi_hba->queue_count; i++) { - struct hisi_sas_cmd_hdr *debugfs_cmd_hdr, *cmd_hdr; + struct hisi_sas_cmd_hdr *debugfs_cmd_hdr, *cmd_hdr; int j; - debugfs_cmd_hdr = hisi_hba->debugfs_cmd_hdr[i]; + debugfs_cmd_hdr = hisi_hba->debugfs_dq[dump_index][i].hdr; cmd_hdr = hisi_hba->cmd_hdr[i]; for (j = 0; j < HISI_SAS_QUEUE_SLOTS; j++) @@ -2715,6 +2726,7 @@ static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba) { + int dump_index = hisi_hba->debugfs_dump_index; const struct hisi_sas_debugfs_reg *port = hisi_hba->hw->debugfs_reg_port; int i, phy_cnt; @@ -2722,7 +2734,7 @@ u32 *databuf; for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) { - databuf = (u32 *)hisi_hba->debugfs_port_reg[phy_cnt]; + databuf = hisi_hba->debugfs_port_reg[dump_index][phy_cnt].data; for (i = 0; i < port->count; i++, databuf++) { offset = port->base_off + 4 * i; *databuf = port->read_port_reg(hisi_hba, phy_cnt, @@ -2733,7 +2745,8 @@ static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; @@ -2745,7 +2758,8 @@ static void hisi_sas_debugfs_snapshot_axi_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_AXI]; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *axi = hw->debugfs_reg_array[DEBUGFS_AXI]; @@ -2758,7 +2772,8 @@ static void hisi_sas_debugfs_snapshot_ras_reg(struct hisi_hba *hisi_hba) { - u32 *databuf = hisi_hba->debugfs_regs[DEBUGFS_RAS]; + int dump_index = hisi_hba->debugfs_dump_index; + u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS].data; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *ras = hw->debugfs_reg_array[DEBUGFS_RAS]; @@ -2771,8 +2786,9 @@ static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba) { - void *cachebuf = hisi_hba->debugfs_itct_cache; - void *databuf = hisi_hba->debugfs_itct; + int dump_index = hisi_hba->debugfs_dump_index; + void *cachebuf = hisi_hba->debugfs_itct_cache[dump_index].cache; + void *databuf = hisi_hba->debugfs_itct[dump_index].itct; struct hisi_sas_itct *itct; int i; @@ -2789,9 +2805,10 @@ static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba) { + int dump_index = hisi_hba->debugfs_dump_index; int max_command_entries = HISI_SAS_MAX_COMMANDS; - void *cachebuf = hisi_hba->debugfs_iost_cache; - void *databuf = hisi_hba->debugfs_iost; + void *cachebuf = hisi_hba->debugfs_iost_cache[dump_index].cache; + void *databuf = hisi_hba->debugfs_iost[dump_index].iost; struct hisi_sas_iost *iost; int i; @@ -2842,11 +2859,12 @@ static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_debugfs_regs *global = s->private; + struct hisi_hba *hisi_hba = global->hisi_hba; const struct hisi_sas_hw *hw = hisi_hba->hw; const void *reg_global = hw->debugfs_reg_array[DEBUGFS_GLOBAL]; - hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_GLOBAL], + hisi_sas_debugfs_print_reg(global->data, reg_global, s); return 0; @@ -2868,11 +2886,12 @@ static int hisi_sas_debugfs_axi_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_debugfs_regs *axi = s->private; + struct hisi_hba *hisi_hba = axi->hisi_hba; const struct hisi_sas_hw *hw = hisi_hba->hw; const void *reg_axi = hw->debugfs_reg_array[DEBUGFS_AXI]; - hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_AXI], + hisi_sas_debugfs_print_reg(axi->data, reg_axi, s); return 0; @@ -2894,11 +2913,12 @@ static int hisi_sas_debugfs_ras_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; + struct hisi_sas_debugfs_regs *ras = s->private; + struct hisi_hba *hisi_hba = ras->hisi_hba; const struct hisi_sas_hw *hw = hisi_hba->hw; const void *reg_ras = hw->debugfs_reg_array[DEBUGFS_RAS]; - hisi_sas_debugfs_print_reg(hisi_hba->debugfs_regs[DEBUGFS_RAS], + hisi_sas_debugfs_print_reg(ras->data, reg_ras, s); return 0; @@ -2920,13 +2940,13 @@ static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p) { - struct hisi_sas_phy *phy = s->private; + struct hisi_sas_debugfs_port *port = s->private; + struct hisi_sas_phy *phy = port->phy; struct hisi_hba *hisi_hba = phy->hisi_hba; const struct hisi_sas_hw *hw = hisi_hba->hw; const struct hisi_sas_debugfs_reg *reg_port = hw->debugfs_reg_port; - u32 *databuf = hisi_hba->debugfs_port_reg[phy->sas_phy.id]; - hisi_sas_debugfs_print_reg(databuf, reg_port, s); + hisi_sas_debugfs_print_reg(port->data, reg_port, s); return 0; } @@ -2975,13 +2995,13 @@ seq_puts(s, "\n"); } -static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr) +static void hisi_sas_cq_show_slot(struct seq_file *s, int slot, + struct hisi_sas_debugfs_cq *debugfs_cq) { - struct hisi_sas_cq *cq = cq_ptr; + struct hisi_sas_cq *cq = debugfs_cq->cq; struct hisi_hba *hisi_hba = cq->hisi_hba; - void *complete_queue = hisi_hba->debugfs_complete_hdr[cq->id]; - __le32 *complete_hdr = complete_queue + - (hisi_hba->hw->complete_hdr_size * slot); + __le32 *complete_hdr = debugfs_cq->complete_hdr + + (hisi_hba->hw->complete_hdr_size * slot); hisi_sas_show_row_32(s, slot, hisi_hba->hw->complete_hdr_size, @@ -2990,11 +3010,11 @@ static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p) { - struct hisi_sas_cq *cq = s->private; + struct hisi_sas_debugfs_cq *debugfs_cq = s->private; int slot; for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) { - hisi_sas_cq_show_slot(s, slot, cq); + hisi_sas_cq_show_slot(s, slot, debugfs_cq); } return 0; } @@ -3014,9 +3034,8 @@ static void hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr) { - struct hisi_sas_dq *dq = dq_ptr; - struct hisi_hba *hisi_hba = dq->hisi_hba; - void *cmd_queue = hisi_hba->debugfs_cmd_hdr[dq->id]; + struct hisi_sas_debugfs_dq *debugfs_dq = dq_ptr; + void *cmd_queue = debugfs_dq->hdr; __le32 *cmd_hdr = cmd_queue + sizeof(struct hisi_sas_cmd_hdr) * slot; @@ -3048,14 +3067,14 @@ static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; - struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost; + struct hisi_sas_debugfs_iost *debugfs_iost = s->private; + struct hisi_sas_iost *iost = debugfs_iost->iost; int i, max_command_entries = HISI_SAS_MAX_COMMANDS; - for (i = 0; i < max_command_entries; i++, debugfs_iost++) { - __le64 *iost = &debugfs_iost->qw0; + for (i = 0; i < max_command_entries; i++, iost++) { + __le64 *data = &iost->qw0; - hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost), iost); + hisi_sas_show_row_64(s, i, sizeof(*iost), data); } return 0; @@ -3076,9 +3095,8 @@ static int hisi_sas_debugfs_iost_cache_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; - struct hisi_sas_iost_itct_cache *iost_cache = - (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_iost_cache; + struct hisi_sas_debugfs_iost_cache *debugfs_iost_cache = s->private; + struct hisi_sas_iost_itct_cache *iost_cache = debugfs_iost_cache->cache; u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; int i, tab_idx; __le64 *iost; @@ -3117,13 +3135,13 @@ static int hisi_sas_debugfs_itct_show(struct seq_file *s, void *p) { int i; - struct hisi_hba *hisi_hba = s->private; - struct hisi_sas_itct *debugfs_itct = hisi_hba->debugfs_itct; + struct hisi_sas_debugfs_itct *debugfs_itct = s->private; + struct hisi_sas_itct *itct = debugfs_itct->itct; - for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, debugfs_itct++) { - __le64 *itct = &debugfs_itct->qw0; + for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) { + __le64 *data = &itct->qw0; - hisi_sas_show_row_64(s, i, sizeof(*debugfs_itct), itct); + hisi_sas_show_row_64(s, i, sizeof(*itct), data); } return 0; @@ -3144,9 +3162,8 @@ static int hisi_sas_debugfs_itct_cache_show(struct seq_file *s, void *p) { - struct hisi_hba *hisi_hba = s->private; - struct hisi_sas_iost_itct_cache *itct_cache = - (struct hisi_sas_iost_itct_cache *)hisi_hba->debugfs_itct_cache; + struct hisi_sas_debugfs_itct_cache *debugfs_itct_cache = s->private; + struct hisi_sas_iost_itct_cache *itct_cache = debugfs_itct_cache->cache; u32 cache_size = HISI_SAS_IOST_ITCT_CACHE_DW_SZ * 4; int i, tab_idx; __le64 *itct; @@ -3184,6 +3201,8 @@ static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba) { + u64 *debugfs_timestamp; + int dump_index = hisi_hba->debugfs_dump_index; struct dentry *dump_dentry; struct dentry *dentry; char name[256]; @@ -3191,19 +3210,26 @@ int c; int d; - /* Create dump dir inside device dir */ - dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir); - hisi_hba->debugfs_dump_dentry = dump_dentry; + snprintf(name, 256, "%d", dump_index); + + dump_dentry = debugfs_create_dir(name, hisi_hba->debugfs_dump_dentry); - debugfs_create_file("global", 0400, dump_dentry, hisi_hba, - &hisi_sas_debugfs_global_fops); + debugfs_timestamp = &hisi_hba->debugfs_timestamp[dump_index]; + + debugfs_create_u64("timestamp", 0400, dump_dentry, + debugfs_timestamp); + + debugfs_create_file("global", 0400, dump_dentry, + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL], + &hisi_sas_debugfs_global_fops); /* Create port dir and files */ dentry = debugfs_create_dir("port", dump_dentry); for (p = 0; p < hisi_hba->n_phy; p++) { snprintf(name, 256, "%d", p); - debugfs_create_file(name, 0400, dentry, &hisi_hba->phy[p], + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_port_reg[dump_index][p], &hisi_sas_debugfs_port_fops); } @@ -3212,7 +3238,8 @@ for (c = 0; c < hisi_hba->queue_count; c++) { snprintf(name, 256, "%d", c); - debugfs_create_file(name, 0400, dentry, &hisi_hba->cq[c], + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_cq[dump_index][c], &hisi_sas_debugfs_cq_fops); } @@ -3221,26 +3248,33 @@ for (d = 0; d < hisi_hba->queue_count; d++) { snprintf(name, 256, "%d", d); - debugfs_create_file(name, 0400, dentry, &hisi_hba->dq[d], + debugfs_create_file(name, 0400, dentry, + &hisi_hba->debugfs_dq[dump_index][d], &hisi_sas_debugfs_dq_fops); } - debugfs_create_file("iost", 0400, dump_dentry, hisi_hba, + debugfs_create_file("iost", 0400, dump_dentry, + &hisi_hba->debugfs_iost[dump_index], &hisi_sas_debugfs_iost_fops); - debugfs_create_file("iost_cache", 0400, dump_dentry, hisi_hba, + debugfs_create_file("iost_cache", 0400, dump_dentry, + &hisi_hba->debugfs_iost_cache[dump_index], &hisi_sas_debugfs_iost_cache_fops); - debugfs_create_file("itct", 0400, dump_dentry, hisi_hba, + debugfs_create_file("itct", 0400, dump_dentry, + &hisi_hba->debugfs_itct[dump_index], &hisi_sas_debugfs_itct_fops); - debugfs_create_file("itct_cache", 0400, dump_dentry, hisi_hba, + debugfs_create_file("itct_cache", 0400, dump_dentry, + &hisi_hba->debugfs_itct_cache[dump_index], &hisi_sas_debugfs_itct_cache_fops); - debugfs_create_file("axi", 0400, dump_dentry, hisi_hba, + debugfs_create_file("axi", 0400, dump_dentry, + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_AXI], &hisi_sas_debugfs_axi_fops); - debugfs_create_file("ras", 0400, dump_dentry, hisi_hba, + debugfs_create_file("ras", 0400, dump_dentry, + &hisi_hba->debugfs_regs[dump_index][DEBUGFS_RAS], &hisi_sas_debugfs_ras_fops); return; @@ -3271,8 +3305,7 @@ struct hisi_hba *hisi_hba = file->f_inode->i_private; char buf[8]; - /* A bit racy, but don't care too much since it's only debugfs */ - if (hisi_hba->debugfs_snapshot) + if (hisi_hba->debugfs_dump_index >= hisi_sas_debugfs_dump_count) return -EFAULT; if (count > 8) @@ -3670,132 +3703,201 @@ .owner = THIS_MODULE, }; +static ssize_t hisi_sas_debugfs_phy_down_cnt_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = filp->private_data; + struct hisi_sas_phy *phy = s->private; + unsigned int set_val; + int res; + + res = kstrtouint_from_user(buf, count, 0, &set_val); + if (res) + return res; + + if (set_val > 0) + return -EINVAL; + + atomic_set(&phy->down_cnt, 0); + + return count; +} + +static int hisi_sas_debugfs_phy_down_cnt_show(struct seq_file *s, void *p) +{ + struct hisi_sas_phy *phy = s->private; + + seq_printf(s, "%d\n", atomic_read(&phy->down_cnt)); + + return 0; +} + +static int hisi_sas_debugfs_phy_down_cnt_open(struct inode *inode, + struct file *filp) +{ + return single_open(filp, hisi_sas_debugfs_phy_down_cnt_show, + inode->i_private); +} + +static const struct file_operations hisi_sas_debugfs_phy_down_cnt_ops = { + .open = hisi_sas_debugfs_phy_down_cnt_open, + .read = seq_read, + .write = hisi_sas_debugfs_phy_down_cnt_write, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + void hisi_sas_debugfs_work_handler(struct work_struct *work) { struct hisi_hba *hisi_hba = container_of(work, struct hisi_hba, debugfs_work); + int debugfs_dump_index = hisi_hba->debugfs_dump_index; + struct device *dev = hisi_hba->dev; + u64 timestamp = local_clock(); - if (hisi_hba->debugfs_snapshot) + if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { + dev_warn(dev, "dump count exceeded!\n"); return; - hisi_hba->debugfs_snapshot = true; + } + + do_div(timestamp, NSEC_PER_MSEC); + hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; hisi_sas_debugfs_snapshot_regs(hisi_hba); + hisi_hba->debugfs_dump_index++; } EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler); -static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba) +static void hisi_sas_debugfs_release(struct hisi_hba *hisi_hba, int dump_index) { struct device *dev = hisi_hba->dev; int i; - devm_kfree(dev, hisi_hba->debugfs_iost_cache); - devm_kfree(dev, hisi_hba->debugfs_itct_cache); - devm_kfree(dev, hisi_hba->debugfs_iost); + devm_kfree(dev, hisi_hba->debugfs_iost_cache[dump_index].cache); + devm_kfree(dev, hisi_hba->debugfs_itct_cache[dump_index].cache); + devm_kfree(dev, hisi_hba->debugfs_iost[dump_index].iost); + devm_kfree(dev, hisi_hba->debugfs_itct[dump_index].itct); for (i = 0; i < hisi_hba->queue_count; i++) - devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]); + devm_kfree(dev, hisi_hba->debugfs_dq[dump_index][i].hdr); for (i = 0; i < hisi_hba->queue_count; i++) - devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]); + devm_kfree(dev, + hisi_hba->debugfs_cq[dump_index][i].complete_hdr); for (i = 0; i < DEBUGFS_REGS_NUM; i++) - devm_kfree(dev, hisi_hba->debugfs_regs[i]); + devm_kfree(dev, hisi_hba->debugfs_regs[dump_index][i].data); for (i = 0; i < hisi_hba->n_phy; i++) - devm_kfree(dev, hisi_hba->debugfs_port_reg[i]); + devm_kfree(dev, hisi_hba->debugfs_port_reg[dump_index][i].data); } -static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba) +static int hisi_sas_debugfs_alloc(struct hisi_hba *hisi_hba, int dump_index) { const struct hisi_sas_hw *hw = hisi_hba->hw; struct device *dev = hisi_hba->dev; - int p, c, d; + int p, c, d, r, i; size_t sz; - hisi_hba->debugfs_dump_dentry = - debugfs_create_dir("dump", hisi_hba->debugfs_dir); - - sz = hw->debugfs_reg_array[DEBUGFS_GLOBAL]->count * 4; - hisi_hba->debugfs_regs[DEBUGFS_GLOBAL] = - devm_kmalloc(dev, sz, GFP_KERNEL); - - if (!hisi_hba->debugfs_regs[DEBUGFS_GLOBAL]) - goto fail; + for (r = 0; r < DEBUGFS_REGS_NUM; r++) { + struct hisi_sas_debugfs_regs *regs = + &hisi_hba->debugfs_regs[dump_index][r]; + + sz = hw->debugfs_reg_array[r]->count * 4; + regs->data = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!regs->data) + goto fail; + regs->hisi_hba = hisi_hba; + } sz = hw->debugfs_reg_port->count * 4; for (p = 0; p < hisi_hba->n_phy; p++) { - hisi_hba->debugfs_port_reg[p] = - devm_kmalloc(dev, sz, GFP_KERNEL); + struct hisi_sas_debugfs_port *port = + &hisi_hba->debugfs_port_reg[dump_index][p]; - if (!hisi_hba->debugfs_port_reg[p]) + port->data = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!port->data) goto fail; + port->phy = &hisi_hba->phy[p]; } - sz = hw->debugfs_reg_array[DEBUGFS_AXI]->count * 4; - hisi_hba->debugfs_regs[DEBUGFS_AXI] = - devm_kmalloc(dev, sz, GFP_KERNEL); - - if (!hisi_hba->debugfs_regs[DEBUGFS_AXI]) - goto fail; - - sz = hw->debugfs_reg_array[DEBUGFS_RAS]->count * 4; - hisi_hba->debugfs_regs[DEBUGFS_RAS] = - devm_kmalloc(dev, sz, GFP_KERNEL); - - if (!hisi_hba->debugfs_regs[DEBUGFS_RAS]) - goto fail; - sz = hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS; for (c = 0; c < hisi_hba->queue_count; c++) { - hisi_hba->debugfs_complete_hdr[c] = - devm_kmalloc(dev, sz, GFP_KERNEL); + struct hisi_sas_debugfs_cq *cq = + &hisi_hba->debugfs_cq[dump_index][c]; - if (!hisi_hba->debugfs_complete_hdr[c]) + cq->complete_hdr = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!cq->complete_hdr) goto fail; + cq->cq = &hisi_hba->cq[c]; } sz = sizeof(struct hisi_sas_cmd_hdr) * HISI_SAS_QUEUE_SLOTS; for (d = 0; d < hisi_hba->queue_count; d++) { - hisi_hba->debugfs_cmd_hdr[d] = - devm_kmalloc(dev, sz, GFP_KERNEL); + struct hisi_sas_debugfs_dq *dq = + &hisi_hba->debugfs_dq[dump_index][d]; - if (!hisi_hba->debugfs_cmd_hdr[d]) + dq->hdr = devm_kmalloc(dev, sz, GFP_KERNEL); + if (!dq->hdr) goto fail; + dq->dq = &hisi_hba->dq[d]; } sz = HISI_SAS_MAX_COMMANDS * sizeof(struct hisi_sas_iost); - hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL); - if (!hisi_hba->debugfs_iost) + hisi_hba->debugfs_iost[dump_index].iost = + devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_iost[dump_index].iost) goto fail; sz = HISI_SAS_IOST_ITCT_CACHE_NUM * sizeof(struct hisi_sas_iost_itct_cache); - hisi_hba->debugfs_iost_cache = devm_kmalloc(dev, sz, GFP_KERNEL); - if (!hisi_hba->debugfs_iost_cache) + hisi_hba->debugfs_iost_cache[dump_index].cache = + devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_iost_cache[dump_index].cache) goto fail; sz = HISI_SAS_IOST_ITCT_CACHE_NUM * sizeof(struct hisi_sas_iost_itct_cache); - hisi_hba->debugfs_itct_cache = devm_kmalloc(dev, sz, GFP_KERNEL); - if (!hisi_hba->debugfs_itct_cache) + hisi_hba->debugfs_itct_cache[dump_index].cache = + devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_itct_cache[dump_index].cache) goto fail; /* New memory allocation must be locate before itct */ sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct); - hisi_hba->debugfs_itct = devm_kmalloc(dev, sz, GFP_KERNEL); - if (!hisi_hba->debugfs_itct) + hisi_hba->debugfs_itct[dump_index].itct = + devm_kmalloc(dev, sz, GFP_KERNEL); + if (!hisi_hba->debugfs_itct[dump_index].itct) goto fail; return 0; fail: - hisi_sas_debugfs_release(hisi_hba); + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) + hisi_sas_debugfs_release(hisi_hba, i); return -ENOMEM; } +static void hisi_sas_debugfs_phy_down_cnt_init(struct hisi_hba *hisi_hba) +{ + struct dentry *dir = debugfs_create_dir("phy_down_cnt", + hisi_hba->debugfs_dir); + char name[16]; + int phy_no; + + for (phy_no = 0; phy_no < hisi_hba->n_phy; phy_no++) { + snprintf(name, 16, "%d", phy_no); + debugfs_create_file(name, 0600, dir, + &hisi_hba->phy[phy_no], + &hisi_sas_debugfs_phy_down_cnt_ops); + } +} + static void hisi_sas_debugfs_bist_init(struct hisi_hba *hisi_hba) { hisi_hba->debugfs_bist_dentry = @@ -3827,10 +3929,11 @@ void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba) { struct device *dev = hisi_hba->dev; + int i; hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev), hisi_sas_debugfs_dir); - debugfs_create_file("trigger_dump", 0600, + debugfs_create_file("trigger_dump", 0200, hisi_hba->debugfs_dir, hisi_hba, &hisi_sas_debugfs_trigger_dump_fops); @@ -3838,9 +3941,17 @@ /* create bist structures */ hisi_sas_debugfs_bist_init(hisi_hba); - if (hisi_sas_debugfs_alloc(hisi_hba)) { - debugfs_remove_recursive(hisi_hba->debugfs_dir); - dev_dbg(dev, "failed to init debugfs!\n"); + hisi_hba->debugfs_dump_dentry = + debugfs_create_dir("dump", hisi_hba->debugfs_dir); + + hisi_sas_debugfs_phy_down_cnt_init(hisi_hba); + + for (i = 0; i < hisi_sas_debugfs_dump_count; i++) { + if (hisi_sas_debugfs_alloc(hisi_hba, i)) { + debugfs_remove_recursive(hisi_hba->debugfs_dir); + dev_dbg(dev, "failed to init debugfs!\n"); + break; + } } } EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init); @@ -3874,14 +3985,24 @@ module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444); MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)"); +u32 hisi_sas_debugfs_dump_count = 1; +EXPORT_SYMBOL_GPL(hisi_sas_debugfs_dump_count); +module_param_named(debugfs_dump_count, hisi_sas_debugfs_dump_count, uint, 0444); +MODULE_PARM_DESC(hisi_sas_debugfs_dump_count, "Number of debugfs dumps to allow"); + static __init int hisi_sas_init(void) { hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops); if (!hisi_sas_stt) return -ENOMEM; - if (hisi_sas_debugfs_enable) + if (hisi_sas_debugfs_enable) { hisi_sas_debugfs_dir = debugfs_create_dir("hisi_sas", NULL); + if (hisi_sas_debugfs_dump_count > HISI_SAS_MAX_DEBUGFS_DUMP) { + pr_info("hisi_sas: Limiting debugfs dump count\n"); + hisi_sas_debugfs_dump_count = HISI_SAS_MAX_DEBUGFS_DUMP; + } + } return 0; } --- linux-oracle-5.4.0.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ linux-oracle-5.4.0/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -531,8 +531,8 @@ (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF)); } -static void clear_itct_v1_hw(struct hisi_hba *hisi_hba, - struct hisi_sas_device *sas_dev) +static int clear_itct_v1_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) { u64 dev_id = sas_dev->device_id; struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; @@ -551,6 +551,8 @@ qw0 = le64_to_cpu(itct->qw0); qw0 &= ~ITCT_HDR_VALID_MSK; itct->qw0 = cpu_to_le64(qw0); + + return 0; } static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) @@ -1645,10 +1647,10 @@ idx = i * HISI_SAS_PHY_INT_NR; for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: fail map phy interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, @@ -1656,7 +1658,7 @@ if (rc) { dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } } @@ -1664,10 +1666,10 @@ idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; for (i = 0; i < hisi_hba->queue_count; i++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, @@ -1675,17 +1677,17 @@ if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, @@ -1693,7 +1695,7 @@ if (rc) { dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } @@ -1768,6 +1770,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = host_attrs_v1_hw, --- linux-oracle-5.4.0.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ linux-oracle-5.4.0/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -773,7 +773,6 @@ struct hisi_sas_device *sas_dev = device->lldd_dev; int sata_idx = sas_dev->sata_idx; int start, end; - unsigned long flags; if (!sata_dev) { /* @@ -797,12 +796,12 @@ end = 64 * (sata_idx + 2); } - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); while (1) { start = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, start); if (start >= end) { - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return -SAS_QUEUE_FULL; } /* @@ -814,7 +813,7 @@ } set_bit(start, bitmap); - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return start; } @@ -843,9 +842,8 @@ struct hisi_sas_device *sas_dev = NULL; int i, sata_dev = dev_is_sata(device); int sata_idx = -1; - unsigned long flags; - spin_lock_irqsave(&hisi_hba->lock, flags); + spin_lock(&hisi_hba->lock); if (sata_dev) if (!sata_index_alloc_v2_hw(hisi_hba, &sata_idx)) @@ -876,7 +874,7 @@ } out: - spin_unlock_irqrestore(&hisi_hba->lock, flags); + spin_unlock(&hisi_hba->lock); return sas_dev; } @@ -974,13 +972,14 @@ (0x1ULL << ITCT_HDR_RTOLT_OFF)); } -static void clear_itct_v2_hw(struct hisi_hba *hisi_hba, - struct hisi_sas_device *sas_dev) +static int clear_itct_v2_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) { DECLARE_COMPLETION_ONSTACK(completion); u64 dev_id = sas_dev->device_id; struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3); + struct device *dev = hisi_hba->dev; int i; sas_dev->completion = &completion; @@ -990,13 +989,19 @@ hisi_sas_write32(hisi_hba, ENT_INT_SRC3, ENT_INT_SRC3_ITC_INT_MSK); + /* need to set register twice to clear ITCT for v2 hw */ for (i = 0; i < 2; i++) { reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK); hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); - wait_for_completion(sas_dev->completion); + if (!wait_for_completion_timeout(sas_dev->completion, + CLEAR_ITCT_TIMEOUT * HZ)) { + dev_warn(dev, "failed to clear ITCT\n"); + return -ETIMEDOUT; + } memset(itct, 0, sizeof(struct hisi_sas_itct)); } + return 0; } static void free_device_v2_hw(struct hisi_sas_device *sas_dev) @@ -3104,9 +3109,9 @@ return IRQ_HANDLED; } -static void cq_tasklet_v2_hw(unsigned long val) +static irqreturn_t cq_thread_v2_hw(int irq_no, void *p) { - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; + struct hisi_sas_cq *cq = p; struct hisi_hba *hisi_hba = cq->hisi_hba; struct hisi_sas_slot *slot; struct hisi_sas_itct *itct; @@ -3174,6 +3179,8 @@ /* update rd_point */ cq->rd_point = rd_point; hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; } static irqreturn_t cq_interrupt_v2_hw(int irq_no, void *p) @@ -3184,9 +3191,7 @@ hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); - tasklet_schedule(&cq->tasklet); - - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static irqreturn_t sata_int_v2_hw(int irq_no, void *p) @@ -3353,18 +3358,18 @@ for (queue_no = 0; queue_no < hisi_hba->queue_count; queue_no++) { struct hisi_sas_cq *cq = &hisi_hba->cq[queue_no]; - struct tasklet_struct *t = &cq->tasklet; - irq = irq_map[queue_no + 96]; - rc = devm_request_irq(dev, irq, cq_interrupt_v2_hw, 0, - DRV_NAME " cq", cq); + cq->irq_no = irq_map[queue_no + 96]; + rc = devm_request_threaded_irq(dev, cq->irq_no, + cq_interrupt_v2_hw, + cq_thread_v2_hw, IRQF_ONESHOT, + DRV_NAME " cq", cq); if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); rc = -ENOENT; goto err_out; } - tasklet_init(t, cq_tasklet_v2_hw, (unsigned long)cq); } hisi_hba->cq_nvecs = hisi_hba->queue_count; @@ -3425,7 +3430,6 @@ interrupt_disable_v2_hw(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); - hisi_sas_kill_tasklets(hisi_hba); hisi_sas_stop_phys(hisi_hba); @@ -3542,6 +3546,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = host_attrs_v2_hw, @@ -3596,11 +3601,6 @@ static int hisi_sas_v2_remove(struct platform_device *pdev) { - struct sas_ha_struct *sha = platform_get_drvdata(pdev); - struct hisi_hba *hisi_hba = sha->lldd_ha; - - hisi_sas_kill_tasklets(hisi_hba); - return hisi_sas_remove(pdev); } --- linux-oracle-5.4.0.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ linux-oracle-5.4.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -495,6 +495,13 @@ #define BASE_VECTORS_V3_HW 16 #define MIN_AFFINE_VECTORS_V3_HW (BASE_VECTORS_V3_HW + 1) +#define CHNL_INT_STS_MSK 0xeeeeeeee +#define CHNL_INT_STS_PHY_MSK 0xe +#define CHNL_INT_STS_INT0_MSK BIT(1) +#define CHNL_INT_STS_INT1_MSK BIT(2) +#define CHNL_INT_STS_INT2_MSK BIT(3) +#define CHNL_WIDTH 4 + enum { DSM_FUNC_ERR_HANDLE_MSI = 0, }; @@ -504,7 +511,7 @@ /* permit overriding the host protection capabilities mask (EEDP/T10 PI) */ static int prot_mask; -module_param(prot_mask, int, 0); +module_param(prot_mask, int, 0444); MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 "); static bool auto_affine_msi_experimental; @@ -795,13 +802,14 @@ (0x1ULL << ITCT_HDR_RTOLT_OFF)); } -static void clear_itct_v3_hw(struct hisi_hba *hisi_hba, - struct hisi_sas_device *sas_dev) +static int clear_itct_v3_hw(struct hisi_hba *hisi_hba, + struct hisi_sas_device *sas_dev) { DECLARE_COMPLETION_ONSTACK(completion); u64 dev_id = sas_dev->device_id; struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id]; u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3); + struct device *dev = hisi_hba->dev; sas_dev->completion = &completion; @@ -814,8 +822,14 @@ reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK); hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val); - wait_for_completion(sas_dev->completion); + if (!wait_for_completion_timeout(sas_dev->completion, + CLEAR_ITCT_TIMEOUT * HZ)) { + dev_warn(dev, "failed to clear ITCT\n"); + return -ETIMEDOUT; + } + memset(itct, 0, sizeof(struct hisi_sas_itct)); + return 0; } static void dereg_device_v3_hw(struct hisi_hba *hisi_hba, @@ -1542,6 +1556,8 @@ u32 phy_state, sl_ctrl, txid_auto; struct device *dev = hisi_hba->dev; + atomic_inc(&phy->down_cnt); + del_timer(&phy->timer); hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 1); @@ -1810,19 +1826,19 @@ int phy_no = 0; irq_msk = hisi_sas_read32(hisi_hba, CHNL_INT_STATUS) - & 0xeeeeeeee; + & CHNL_INT_STS_MSK; while (irq_msk) { - if (irq_msk & (2 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT0_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int0_v3_hw(hisi_hba, phy_no); - if (irq_msk & (4 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT1_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int1_v3_hw(hisi_hba, phy_no); - if (irq_msk & (8 << (phy_no * 4))) + if (irq_msk & (CHNL_INT_STS_INT2_MSK << (phy_no * CHNL_WIDTH))) handle_chl_int2_v3_hw(hisi_hba, phy_no); - irq_msk &= ~(0xe << (phy_no * 4)); + irq_msk &= ~(CHNL_INT_STS_PHY_MSK << (phy_no * CHNL_WIDTH)); phy_no++; } @@ -2290,9 +2306,9 @@ return sts; } -static void cq_tasklet_v3_hw(unsigned long val) +static irqreturn_t cq_thread_v3_hw(int irq_no, void *p) { - struct hisi_sas_cq *cq = (struct hisi_sas_cq *)val; + struct hisi_sas_cq *cq = p; struct hisi_hba *hisi_hba = cq->hisi_hba; struct hisi_sas_slot *slot; struct hisi_sas_complete_v3_hdr *complete_queue; @@ -2329,6 +2345,8 @@ /* update rd_point */ cq->rd_point = rd_point; hisi_sas_write32(hisi_hba, COMPL_Q_0_RD_PTR + (0x14 * queue), rd_point); + + return IRQ_HANDLED; } static irqreturn_t cq_interrupt_v3_hw(int irq_no, void *p) @@ -2339,9 +2357,7 @@ hisi_sas_write32(hisi_hba, OQ_INT_SRC, 1 << queue); - tasklet_schedule(&cq->tasklet); - - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static void setup_reply_map_v3_hw(struct hisi_hba *hisi_hba, int nvecs) @@ -2356,7 +2372,7 @@ BASE_VECTORS_V3_HW); if (!mask) goto fallback; - cq->pci_irq_mask = mask; + cq->irq_mask = mask; for_each_cpu(cpu, mask) hisi_hba->reply_map[cpu] = queue; } @@ -2380,6 +2396,8 @@ .pre_vectors = BASE_VECTORS_V3_HW, }; + dev_info(dev, "Enable MSI auto-affinity\n"); + min_msi = MIN_AFFINE_VECTORS_V3_HW; hisi_hba->reply_map = devm_kcalloc(dev, nr_cpu_ids, @@ -2432,15 +2450,20 @@ goto free_irq_vectors; } - /* Init tasklets for cq only */ + if (hisi_sas_intr_conv) + dev_info(dev, "Enable interrupt converge\n"); + for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; - struct tasklet_struct *t = &cq->tasklet; int nr = hisi_sas_intr_conv ? 16 : 16 + i; - unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0; + unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : + IRQF_ONESHOT; - rc = devm_request_irq(dev, pci_irq_vector(pdev, nr), - cq_interrupt_v3_hw, irqflags, + cq->irq_no = pci_irq_vector(pdev, nr); + rc = devm_request_threaded_irq(dev, cq->irq_no, + cq_interrupt_v3_hw, + cq_thread_v3_hw, + irqflags, DRV_NAME " cq", cq); if (rc) { dev_err(dev, "could not request cq%d interrupt, rc=%d\n", @@ -2448,8 +2471,6 @@ rc = -ENOENT; goto free_irq_vectors; } - - tasklet_init(t, cq_tasklet_v3_hw, (unsigned long)cq); } return 0; @@ -2525,7 +2546,6 @@ interrupt_disable_v3_hw(hisi_hba); hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0); - hisi_sas_kill_tasklets(hisi_hba); hisi_sas_stop_phys(hisi_hba); @@ -2901,7 +2921,7 @@ wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000); - hisi_sas_kill_tasklets(hisi_hba); + hisi_sas_sync_irqs(hisi_hba); } static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba) @@ -3022,11 +3042,6 @@ hisi_sas_phy_write32(hisi_hba, phy_id, SAS_PHY_BIST_CTRL, reg_val); - mdelay(100); - reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); - hisi_sas_phy_write32(hisi_hba, phy_id, - SAS_PHY_BIST_CTRL, reg_val); - /* set the bist init value */ hisi_sas_phy_write32(hisi_hba, phy_id, SAS_PHY_BIST_CODE, @@ -3035,6 +3050,11 @@ SAS_PHY_BIST_CODE1, SAS_PHY_BIST_CODE1_INIT); + mdelay(100); + reg_val |= (CFG_RX_BIST_EN_MSK | CFG_TX_BIST_EN_MSK); + hisi_sas_phy_write32(hisi_hba, phy_id, + SAS_PHY_BIST_CTRL, reg_val); + /* clear error bit */ mdelay(100); hisi_sas_phy_read32(hisi_hba, phy_id, SAS_BIST_ERR_CNT); @@ -3064,6 +3084,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = host_attrs_v3_hw, @@ -3259,6 +3280,7 @@ err_out_register_ha: scsi_remove_host(shost); err_out_ha: + hisi_sas_debugfs_exit(hisi_hba); scsi_host_put(shost); err_out_regions: pci_release_regions(pdev); @@ -3273,14 +3295,14 @@ { int i; - free_irq(pci_irq_vector(pdev, 1), hisi_hba); - free_irq(pci_irq_vector(pdev, 2), hisi_hba); - free_irq(pci_irq_vector(pdev, 11), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; int nr = hisi_sas_intr_conv ? 16 : 16 + i; - free_irq(pci_irq_vector(pdev, nr), cq); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); } pci_free_irq_vectors(pdev); } @@ -3292,8 +3314,6 @@ struct hisi_hba *hisi_hba = sha->lldd_ha; struct Scsi_Host *shost = sha->core.shost; - hisi_sas_debugfs_exit(hisi_hba); - if (timer_pending(&hisi_hba->timer)) del_timer(&hisi_hba->timer); @@ -3301,10 +3321,10 @@ sas_remove_host(sha->core.shost); hisi_sas_v3_destroy_irqs(pdev, hisi_hba); - hisi_sas_kill_tasklets(hisi_hba); pci_release_regions(pdev); pci_disable_device(pdev); hisi_sas_free(hisi_hba); + hisi_sas_debugfs_exit(hisi_hba); scsi_host_put(shost); } @@ -3363,7 +3383,7 @@ } if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) - return -1; + return -EPERM; scsi_block_requests(shost); set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); @@ -3422,6 +3442,7 @@ if (rc) { scsi_remove_host(shost); pci_disable_device(pdev); + return rc; } hisi_hba->hw->phys_init(hisi_hba); sas_resume_ha(sha); --- linux-oracle-5.4.0.orig/drivers/scsi/hosts.c +++ linux-oracle-5.4.0/drivers/scsi/hosts.c @@ -179,6 +179,7 @@ scsi_forget_host(shost); mutex_unlock(&shost->scan_mutex); scsi_proc_host_rm(shost); + scsi_proc_hostdir_rm(shost->hostt); spin_lock_irqsave(shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_DEL)) @@ -219,6 +220,10 @@ goto fail; } + /* Use min_t(int, ...) in case shost->can_queue exceeds SHRT_MAX */ + shost->cmd_per_lun = min_t(int, shost->cmd_per_lun, + shost->can_queue); + error = scsi_init_sense_cache(shost); if (error) goto fail; @@ -253,12 +258,11 @@ device_enable_async_suspend(&shost->shost_dev); + get_device(&shost->shost_gendev); error = device_add(&shost->shost_dev); if (error) goto out_del_gendev; - get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL); @@ -275,33 +279,36 @@ shost->work_q_name); if (!shost->work_q) { error = -EINVAL; - goto out_free_shost_data; + goto out_del_dev; } } error = scsi_sysfs_add_host(shost); if (error) - goto out_destroy_host; + goto out_del_dev; scsi_proc_host_add(shost); scsi_autopm_put_host(shost); return error; - out_destroy_host: - if (shost->work_q) - destroy_workqueue(shost->work_q); - out_free_shost_data: - kfree(shost->shost_data); + /* + * Any host allocation in this function will be freed in + * scsi_host_dev_release(). + */ out_del_dev: device_del(&shost->shost_dev); out_del_gendev: + /* + * Host state is SHOST_RUNNING so we have to explicitly release + * ->shost_dev. + */ + put_device(&shost->shost_dev); device_del(&shost->shost_gendev); out_disable_runtime_pm: device_disable_async_suspend(&shost->shost_gendev); pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_mq_destroy_tags(shost); fail: return error; } @@ -312,9 +319,7 @@ struct Scsi_Host *shost = dev_to_shost(dev); struct device *parent = dev->parent; - scsi_proc_hostdir_rm(shost->hostt); - - /* Wait for functions invoked through call_rcu(&shost->rcu, ...) */ + /* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */ rcu_barrier(); if (shost->tmf_work_q) @@ -326,12 +331,13 @@ if (shost->shost_state == SHOST_CREATED) { /* - * Free the shost_dev device name here if scsi_host_alloc() - * and scsi_host_put() have been called but neither + * Free the shost_dev device name and remove the proc host dir + * here if scsi_host_{alloc,put}() have been called but neither * scsi_host_add() nor scsi_host_remove() has been called. * This avoids that the memory allocated for the shost_dev - * name is leaked. + * name as well as the proc dir structure are leaked. */ + scsi_proc_hostdir_rm(shost->hostt); kfree(dev_name(&shost->shost_dev)); } @@ -342,7 +348,7 @@ ida_simple_remove(&host_index_ida, shost->host_no); - if (parent) + if (shost->shost_state != SHOST_CREATED) put_device(parent); kfree(shost); } @@ -389,8 +395,10 @@ mutex_init(&shost->scan_mutex); index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); - if (index < 0) - goto fail_kfree; + if (index < 0) { + kfree(shost); + return NULL; + } shost->host_no = index; shost->dma_channel = 0xff; @@ -482,7 +490,8 @@ shost_printk(KERN_WARNING, shost, "error handler thread failed to spawn, error = %ld\n", PTR_ERR(shost->ehandler)); - goto fail_index_remove; + shost->ehandler = NULL; + goto fail; } shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d", @@ -491,17 +500,18 @@ if (!shost->tmf_work_q) { shost_printk(KERN_WARNING, shost, "failed to create tmf workq\n"); - goto fail_kthread; + goto fail; } scsi_proc_hostdir_add(shost->hostt); return shost; + fail: + /* + * Host state is still SHOST_CREATED and that is enough to release + * ->shost_gendev. scsi_host_dev_release() will free + * dev_name(&shost->shost_dev). + */ + put_device(&shost->shost_gendev); - fail_kthread: - kthread_stop(shost->ehandler); - fail_index_remove: - ida_simple_remove(&host_index_ida, shost->host_no); - fail_kfree: - kfree(shost); return NULL; } EXPORT_SYMBOL(scsi_host_alloc); @@ -509,7 +519,7 @@ static int __scsi_host_match(struct device *dev, const void *data) { struct Scsi_Host *p; - const unsigned short *hostnum = data; + const unsigned int *hostnum = data; p = class_to_shost(dev); return p->host_no == *hostnum; @@ -526,7 +536,7 @@ * that scsi_host_get() took. The put_device() below dropped * the reference from class_find_device(). **/ -struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) +struct Scsi_Host *scsi_host_lookup(unsigned int hostnum) { struct device *cdev; struct Scsi_Host *shost = NULL; --- linux-oracle-5.4.0.orig/drivers/scsi/hpsa.c +++ linux-oracle-5.4.0/drivers/scsi/hpsa.c @@ -504,6 +504,12 @@ return count; } +static void hpsa_turn_off_ioaccel_for_device(struct hpsa_scsi_dev_t *device) +{ + device->offload_enabled = 0; + device->offload_to_be_enabled = 0; +} + static ssize_t host_show_firmware_revision(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1738,8 +1744,7 @@ __func__, h->scsi_host->host_no, logical_drive->bus, logical_drive->target, logical_drive->lun); - logical_drive->offload_enabled = 0; - logical_drive->offload_to_be_enabled = 0; + hpsa_turn_off_ioaccel_for_device(logical_drive); logical_drive->queue_depth = 8; } } @@ -2499,8 +2504,7 @@ IOACCEL2_SERV_RESPONSE_FAILURE) { if (c2->error_data.status == IOACCEL2_STATUS_SR_IOACCEL_DISABLED) { - dev->offload_enabled = 0; - dev->offload_to_be_enabled = 0; + hpsa_turn_off_ioaccel_for_device(dev); } if (dev->in_reset) { @@ -3670,10 +3674,17 @@ this_device->offload_config = !!(ioaccel_status & OFFLOAD_CONFIGURED_BIT); if (this_device->offload_config) { - this_device->offload_to_be_enabled = + bool offload_enabled = !!(ioaccel_status & OFFLOAD_ENABLED_BIT); - if (hpsa_get_raid_map(h, scsi3addr, this_device)) - this_device->offload_to_be_enabled = 0; + /* + * Check to see if offload can be enabled. + */ + if (offload_enabled) { + rc = hpsa_get_raid_map(h, scsi3addr, this_device); + if (rc) /* could not load raid_map */ + goto out; + this_device->offload_to_be_enabled = 1; + } } out: @@ -3996,8 +4007,7 @@ } else { this_device->raid_level = RAID_UNKNOWN; this_device->offload_config = 0; - this_device->offload_enabled = 0; - this_device->offload_to_be_enabled = 0; + hpsa_turn_off_ioaccel_for_device(this_device); this_device->hba_ioaccel_enabled = 0; this_device->volume_offline = 0; this_device->queue_depth = h->nr_cmds; @@ -5230,8 +5240,12 @@ /* Handles load balance across RAID 1 members. * (2-drive R1 and R10 with even # of drives.) * Appropriate for SSDs, not optimal for HDDs + * Ensure we have the correct raid_map. */ - BUG_ON(le16_to_cpu(map->layout_map_count) != 2); + if (le16_to_cpu(map->layout_map_count) != 2) { + hpsa_turn_off_ioaccel_for_device(dev); + return IO_ACCEL_INELIGIBLE; + } if (dev->offload_to_mirror) map_index += le16_to_cpu(map->data_disks_per_row); dev->offload_to_mirror = !dev->offload_to_mirror; @@ -5239,8 +5253,12 @@ case HPSA_RAID_ADM: /* Handles N-way mirrors (R1-ADM) * and R10 with # of drives divisible by 3.) + * Ensure we have the correct raid_map. */ - BUG_ON(le16_to_cpu(map->layout_map_count) != 3); + if (le16_to_cpu(map->layout_map_count) != 3) { + hpsa_turn_off_ioaccel_for_device(dev); + return IO_ACCEL_INELIGIBLE; + } offload_to_mirror = dev->offload_to_mirror; raid_map_helper(map, offload_to_mirror, @@ -5265,7 +5283,10 @@ r5or6_blocks_per_row = le16_to_cpu(map->strip_size) * le16_to_cpu(map->data_disks_per_row); - BUG_ON(r5or6_blocks_per_row == 0); + if (r5or6_blocks_per_row == 0) { + hpsa_turn_off_ioaccel_for_device(dev); + return IO_ACCEL_INELIGIBLE; + } stripesize = r5or6_blocks_per_row * le16_to_cpu(map->layout_map_count); #if BITS_PER_LONG == 32 @@ -5789,7 +5810,7 @@ { struct Scsi_Host *sh; - sh = scsi_host_alloc(&hpsa_driver_template, sizeof(h)); + sh = scsi_host_alloc(&hpsa_driver_template, sizeof(struct ctlr_info *)); if (sh == NULL) { dev_err(&h->pdev->dev, "scsi_host_alloc failed\n"); return -ENOMEM; @@ -8285,7 +8306,7 @@ * * Called from monitor controller worker (hpsa_event_monitor_worker) * - * A Volume (or Volumes that comprise an Array set may be undergoing a + * A Volume (or Volumes that comprise an Array set) may be undergoing a * transformation, so we will be turning off ioaccel for all volumes that * make up the Array. */ @@ -8308,6 +8329,9 @@ * Run through current device list used during I/O requests. */ for (i = 0; i < h->ndevices; i++) { + int offload_to_be_enabled = 0; + int offload_config = 0; + device = h->dev[i]; if (!device) @@ -8325,25 +8349,35 @@ continue; ioaccel_status = buf[IOACCEL_STATUS_BYTE]; - device->offload_config = + + /* + * Check if offload is still configured on + */ + offload_config = !!(ioaccel_status & OFFLOAD_CONFIGURED_BIT); - if (device->offload_config) - device->offload_to_be_enabled = + /* + * If offload is configured on, check to see if ioaccel + * needs to be enabled. + */ + if (offload_config) + offload_to_be_enabled = !!(ioaccel_status & OFFLOAD_ENABLED_BIT); /* + * If ioaccel is to be re-enabled, re-enable later during the + * scan operation so the driver can get a fresh raidmap + * before turning ioaccel back on. + */ + if (offload_to_be_enabled) + continue; + + /* * Immediately turn off ioaccel for any volume the * controller tells us to. Some of the reasons could be: * transformation - change to the LVs of an Array. * degraded volume - component failure - * - * If ioaccel is to be re-enabled, re-enable later during the - * scan operation so the driver can get a fresh raidmap - * before turning ioaccel back on. - * */ - if (!device->offload_to_be_enabled) - device->offload_enabled = 0; + hpsa_turn_off_ioaccel_for_device(device); } kfree(buf); @@ -8820,7 +8854,7 @@ /* hook into SCSI subsystem */ rc = hpsa_scsi_add_host(h); if (rc) - goto clean7; /* perf, sg, cmd, irq, shost, pci, lu, aer/h */ + goto clean8; /* lastlogicals, perf, sg, cmd, irq, shost, pci, lu, aer/h */ /* Monitor the controller for firmware lockups */ h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL; @@ -8835,6 +8869,8 @@ HPSA_EVENT_MONITOR_INTERVAL); return 0; +clean8: /* lastlogicals, perf, sg, cmd, irq, shost, pci, lu, aer/h */ + kfree(h->lastlogicals); clean7: /* perf, sg, cmd, irq, shost, pci, lu, aer/h */ hpsa_free_performant_mode(h); h->access.set_intr_mask(h, HPSA_INTR_OFF); @@ -8867,7 +8903,7 @@ destroy_workqueue(h->monitor_ctlr_wq); h->monitor_ctlr_wq = NULL; } - kfree(h); + hpda_free_ctlr_info(h); return rc; } @@ -9727,7 +9763,8 @@ return 0; free_sas_phy: - hpsa_free_sas_phy(hpsa_sas_phy); + sas_phy_free(hpsa_sas_phy->phy); + kfree(hpsa_sas_phy); free_sas_port: hpsa_free_sas_port(hpsa_sas_port); free_sas_node: @@ -9763,10 +9800,12 @@ rc = hpsa_sas_port_add_rphy(hpsa_sas_port, rphy); if (rc) - goto free_sas_port; + goto free_sas_rphy; return 0; +free_sas_rphy: + sas_rphy_free(rphy); free_sas_port: hpsa_free_sas_port(hpsa_sas_port); device->sas_port = NULL; --- linux-oracle-5.4.0.orig/drivers/scsi/ibmvscsi/ibmvfc.c +++ linux-oracle-5.4.0/drivers/scsi/ibmvscsi/ibmvfc.c @@ -493,8 +493,17 @@ if (vhost->action == IBMVFC_HOST_ACTION_ALLOC_TGTS) vhost->action = action; break; + case IBMVFC_HOST_ACTION_REENABLE: + case IBMVFC_HOST_ACTION_RESET: + vhost->action = action; + break; case IBMVFC_HOST_ACTION_INIT: case IBMVFC_HOST_ACTION_TGT_DEL: + case IBMVFC_HOST_ACTION_LOGO: + case IBMVFC_HOST_ACTION_QUERY_TGTS: + case IBMVFC_HOST_ACTION_TGT_DEL_FAILED: + case IBMVFC_HOST_ACTION_NONE: + default: switch (vhost->action) { case IBMVFC_HOST_ACTION_RESET: case IBMVFC_HOST_ACTION_REENABLE: @@ -504,15 +513,6 @@ break; } break; - case IBMVFC_HOST_ACTION_LOGO: - case IBMVFC_HOST_ACTION_QUERY_TGTS: - case IBMVFC_HOST_ACTION_TGT_DEL_FAILED: - case IBMVFC_HOST_ACTION_NONE: - case IBMVFC_HOST_ACTION_RESET: - case IBMVFC_HOST_ACTION_REENABLE: - default: - vhost->action = action; - break; } } @@ -2881,8 +2881,10 @@ unsigned long flags = 0; spin_lock_irqsave(shost->host_lock, flags); - if (sdev->type == TYPE_DISK) + if (sdev->type == TYPE_DISK) { sdev->allow_restart = 1; + blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); + } spin_unlock_irqrestore(shost->host_lock, flags); return 0; } @@ -4337,26 +4339,45 @@ case IBMVFC_HOST_ACTION_INIT_WAIT: break; case IBMVFC_HOST_ACTION_RESET: - vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; spin_unlock_irqrestore(vhost->host->host_lock, flags); rc = ibmvfc_reset_crq(vhost); + spin_lock_irqsave(vhost->host->host_lock, flags); - if (rc == H_CLOSED) + if (!rc || rc == H_CLOSED) vio_enable_interrupts(to_vio_dev(vhost->dev)); - if (rc || (rc = ibmvfc_send_crq_init(vhost)) || - (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { - ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); - dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); + if (vhost->action == IBMVFC_HOST_ACTION_RESET) { + /* + * The only action we could have changed to would have + * been reenable, in which case, we skip the rest of + * this path and wait until we've done the re-enable + * before sending the crq init. + */ + vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; + + if (rc || (rc = ibmvfc_send_crq_init(vhost)) || + (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); + } } break; case IBMVFC_HOST_ACTION_REENABLE: - vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; spin_unlock_irqrestore(vhost->host->host_lock, flags); rc = ibmvfc_reenable_crq_queue(vhost); + spin_lock_irqsave(vhost->host->host_lock, flags); - if (rc || (rc = ibmvfc_send_crq_init(vhost))) { - ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); - dev_err(vhost->dev, "Error after enable (rc=%d)\n", rc); + if (vhost->action == IBMVFC_HOST_ACTION_REENABLE) { + /* + * The only action we could have changed to would have + * been reset, in which case, we skip the rest of this + * path and wait until we've done the reset before + * sending the crq init. + */ + vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; + if (rc || (rc = ibmvfc_send_crq_init(vhost))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after enable (rc=%d)\n", rc); + } } break; case IBMVFC_HOST_ACTION_LOGO: @@ -4788,6 +4809,7 @@ if (IS_ERR(vhost->work_thread)) { dev_err(dev, "Couldn't create kernel thread: %ld\n", PTR_ERR(vhost->work_thread)); + rc = PTR_ERR(vhost->work_thread); goto free_host_mem; } --- linux-oracle-5.4.0.orig/drivers/scsi/ibmvscsi/ibmvscsi.c +++ linux-oracle-5.4.0/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -415,6 +415,8 @@ int rc = 0; struct vio_dev *vdev = to_vio_dev(hostdata->dev); + set_adapter_info(hostdata); + /* Re-enable the CRQ */ do { if (rc) @@ -805,13 +807,29 @@ } /** + * ibmvscsi_set_request_limit - Set the adapter request_limit in response to + * an adapter failure, reset, or SRP Login. Done under host lock to prevent + * race with SCSI command submission. + * @hostdata: adapter to adjust + * @limit: new request limit + */ +static void ibmvscsi_set_request_limit(struct ibmvscsi_host_data *hostdata, int limit) +{ + unsigned long flags; + + spin_lock_irqsave(hostdata->host->host_lock, flags); + atomic_set(&hostdata->request_limit, limit); + spin_unlock_irqrestore(hostdata->host->host_lock, flags); +} + +/** * ibmvscsi_reset_host - Reset the connection to the server * @hostdata: struct ibmvscsi_host_data to reset */ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) { scsi_block_requests(hostdata->host); - atomic_set(&hostdata->request_limit, 0); + ibmvscsi_set_request_limit(hostdata, 0); purge_requests(hostdata, DID_ERROR); hostdata->action = IBMVSCSI_HOST_ACTION_RESET; @@ -1144,13 +1162,13 @@ dev_info(hostdata->dev, "SRP_LOGIN_REJ reason %u\n", evt_struct->xfer_iu->srp.login_rej.reason); /* Login failed. */ - atomic_set(&hostdata->request_limit, -1); + ibmvscsi_set_request_limit(hostdata, -1); return; default: dev_err(hostdata->dev, "Invalid login response typecode 0x%02x!\n", evt_struct->xfer_iu->srp.login_rsp.opcode); /* Login failed. */ - atomic_set(&hostdata->request_limit, -1); + ibmvscsi_set_request_limit(hostdata, -1); return; } @@ -1161,7 +1179,7 @@ * This value is set rather than added to request_limit because * request_limit could have been set to -1 by this client. */ - atomic_set(&hostdata->request_limit, + ibmvscsi_set_request_limit(hostdata, be32_to_cpu(evt_struct->xfer_iu->srp.login_rsp.req_lim_delta)); /* If we had any pending I/Os, kick them */ @@ -1193,13 +1211,13 @@ login->req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); - spin_lock_irqsave(hostdata->host->host_lock, flags); /* Start out with a request limit of 0, since this is negotiated in * the login request we are just sending and login requests always * get sent by the driver regardless of request_limit. */ - atomic_set(&hostdata->request_limit, 0); + ibmvscsi_set_request_limit(hostdata, 0); + spin_lock_irqsave(hostdata->host->host_lock, flags); rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2); spin_unlock_irqrestore(hostdata->host->host_lock, flags); dev_info(hostdata->dev, "sent SRP login\n"); @@ -1779,7 +1797,7 @@ return; case VIOSRP_CRQ_XPORT_EVENT: /* Hypervisor telling us the connection is closed */ scsi_block_requests(hostdata->host); - atomic_set(&hostdata->request_limit, 0); + ibmvscsi_set_request_limit(hostdata, 0); if (crq->format == 0x06) { /* We need to re-setup the interpartition connection */ dev_info(hostdata->dev, "Re-enabling adapter!\n"); @@ -2135,12 +2153,12 @@ } hostdata->action = IBMVSCSI_HOST_ACTION_NONE; + spin_unlock_irqrestore(hostdata->host->host_lock, flags); if (rc) { - atomic_set(&hostdata->request_limit, -1); + ibmvscsi_set_request_limit(hostdata, -1); dev_err(hostdata->dev, "error after %s\n", action); } - spin_unlock_irqrestore(hostdata->host->host_lock, flags); scsi_unblock_requests(hostdata->host); } @@ -2224,7 +2242,7 @@ init_waitqueue_head(&hostdata->work_wait_q); hostdata->host = host; hostdata->dev = dev; - atomic_set(&hostdata->request_limit, -1); + ibmvscsi_set_request_limit(hostdata, -1); hostdata->host->max_sectors = IBMVSCSI_MAX_SECTORS_DEFAULT; if (map_persist_bufs(hostdata)) { @@ -2320,16 +2338,12 @@ static int ibmvscsi_remove(struct vio_dev *vdev) { struct ibmvscsi_host_data *hostdata = dev_get_drvdata(&vdev->dev); - unsigned long flags; srp_remove_host(hostdata->host); scsi_remove_host(hostdata->host); purge_requests(hostdata, DID_ERROR); - - spin_lock_irqsave(hostdata->host->host_lock, flags); release_event_pool(&hostdata->pool, hostdata); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_events); --- linux-oracle-5.4.0.orig/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ linux-oracle-5.4.0/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -35,7 +35,7 @@ #define IBMVSCSIS_VERSION "v0.2" -#define INITIAL_SRP_LIMIT 800 +#define INITIAL_SRP_LIMIT 1024 #define DEFAULT_MAX_SECTORS 256 #define MAX_TXU 1024 * 1024 --- linux-oracle-5.4.0.orig/drivers/scsi/ipr.c +++ linux-oracle-5.4.0/drivers/scsi/ipr.c @@ -1517,23 +1517,22 @@ } /** - * strip_and_pad_whitespace - Strip and pad trailing whitespace. - * @i: index into buffer - * @buf: string to modify + * strip_whitespace - Strip and pad trailing whitespace. + * @i: size of buffer + * @buf: string to modify * - * This function will strip all trailing whitespace, pad the end - * of the string with a single space, and NULL terminate the string. + * This function will strip all trailing whitespace and + * NUL terminate the string. * - * Return value: - * new length of string **/ -static int strip_and_pad_whitespace(int i, char *buf) +static void strip_whitespace(int i, char *buf) { + if (i < 1) + return; + i--; while (i && buf[i] == ' ') i--; - buf[i+1] = ' '; - buf[i+2] = '\0'; - return i + 2; + buf[i+1] = '\0'; } /** @@ -1548,19 +1547,21 @@ static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, struct ipr_vpd *vpd) { - char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3]; - int i = 0; + char vendor_id[IPR_VENDOR_ID_LEN + 1]; + char product_id[IPR_PROD_ID_LEN + 1]; + char sn[IPR_SERIAL_NUM_LEN + 1]; - memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); - i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer); + memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); + strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id); - memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN); - i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer); + memcpy(product_id, vpd->vpids.product_id, IPR_PROD_ID_LEN); + strip_whitespace(IPR_PROD_ID_LEN, product_id); - memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN); - buffer[IPR_SERIAL_NUM_LEN + i] = '\0'; + memcpy(sn, vpd->sn, IPR_SERIAL_NUM_LEN); + strip_whitespace(IPR_SERIAL_NUM_LEN, sn); - ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer); + ipr_hcam_err(hostrcb, "%s VPID/SN: %s %s %s\n", prefix, + vendor_id, product_id, sn); } /** @@ -9772,7 +9773,7 @@ GFP_KERNEL); if (!ioa_cfg->hrrq[i].host_rrq) { - while (--i > 0) + while (--i >= 0) dma_free_coherent(&pdev->dev, sizeof(u32) * ioa_cfg->hrrq[i].size, ioa_cfg->hrrq[i].host_rrq, @@ -9947,6 +9948,7 @@ ioa_cfg->max_devs_supported = ipr_max_devs; if (ioa_cfg->sis64) { + host->max_channel = IPR_MAX_SIS64_BUSES; host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; if (ipr_max_devs > IPR_MAX_SIS64_DEVS) @@ -9955,6 +9957,7 @@ + ((sizeof(struct ipr_config_table_entry64) * ioa_cfg->max_devs_supported))); } else { + host->max_channel = IPR_VSET_BUS; host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) @@ -9964,7 +9967,6 @@ * ioa_cfg->max_devs_supported))); } - host->max_channel = IPR_VSET_BUS; host->unique_id = host->host_no; host->max_cmd_len = IPR_MAX_CDB_LEN; host->can_queue = ioa_cfg->max_cmds; @@ -10044,7 +10046,7 @@ ioa_cfg->vectors_info[i].desc, &ioa_cfg->hrrq[i]); if (rc) { - while (--i >= 0) + while (--i > 0) free_irq(pci_irq_vector(pdev, i), &ioa_cfg->hrrq[i]); return rc; @@ -10842,11 +10844,19 @@ **/ static int __init ipr_init(void) { + int rc; + ipr_info("IBM Power RAID SCSI Device Driver version: %s %s\n", IPR_DRIVER_VERSION, IPR_DRIVER_DATE); register_reboot_notifier(&ipr_notifier); - return pci_register_driver(&ipr_driver); + rc = pci_register_driver(&ipr_driver); + if (rc) { + unregister_reboot_notifier(&ipr_notifier); + return rc; + } + + return 0; } /** --- linux-oracle-5.4.0.orig/drivers/scsi/ipr.h +++ linux-oracle-5.4.0/drivers/scsi/ipr.h @@ -1300,6 +1300,7 @@ #define IPR_ARRAY_VIRTUAL_BUS 0x1 #define IPR_VSET_VIRTUAL_BUS 0x2 #define IPR_IOAFP_VIRTUAL_BUS 0x3 +#define IPR_MAX_SIS64_BUSES 0x4 #define IPR_GET_RES_PHYS_LOC(res) \ (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) --- linux-oracle-5.4.0.orig/drivers/scsi/isci/init.c +++ linux-oracle-5.4.0/drivers/scsi/isci/init.c @@ -166,6 +166,7 @@ .eh_abort_handler = sas_eh_abort_handler, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = isci_host_attrs, --- linux-oracle-5.4.0.orig/drivers/scsi/isci/request.c +++ linux-oracle-5.4.0/drivers/scsi/isci/request.c @@ -3398,7 +3398,7 @@ return SCI_FAILURE; } - return SCI_SUCCESS; + return status; } static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag) --- linux-oracle-5.4.0.orig/drivers/scsi/iscsi_boot_sysfs.c +++ linux-oracle-5.4.0/drivers/scsi/iscsi_boot_sysfs.c @@ -352,7 +352,7 @@ boot_kobj->kobj.kset = boot_kset->kset; if (kobject_init_and_add(&boot_kobj->kobj, &iscsi_boot_ktype, NULL, name, index)) { - kfree(boot_kobj); + kobject_put(&boot_kobj->kobj); return NULL; } boot_kobj->data = data; --- linux-oracle-5.4.0.orig/drivers/scsi/iscsi_tcp.c +++ linux-oracle-5.4.0/drivers/scsi/iscsi_tcp.c @@ -369,8 +369,16 @@ { struct iscsi_conn *conn = task->conn; unsigned int noreclaim_flag; + struct iscsi_tcp_conn *tcp_conn = conn->dd_data; + struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; int rc = 0; + if (!tcp_sw_conn->sock) { + iscsi_conn_printk(KERN_ERR, conn, + "Transport not bound to socket!\n"); + return -EINVAL; + } + noreclaim_flag = memalloc_noreclaim_save(); while (iscsi_sw_tcp_xmit_qlen(conn)) { @@ -762,7 +770,7 @@ enum iscsi_host_param param, char *buf) { struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(shost); - struct iscsi_session *session = tcp_sw_host->session; + struct iscsi_session *session; struct iscsi_conn *conn; struct iscsi_tcp_conn *tcp_conn; struct iscsi_sw_tcp_conn *tcp_sw_conn; @@ -771,6 +779,7 @@ switch (param) { case ISCSI_HOST_PARAM_IPADDRESS: + session = tcp_sw_host->session; if (!session) return -ENOTCONN; @@ -859,12 +868,14 @@ if (!cls_session) goto remove_host; session = cls_session->dd_data; - tcp_sw_host = iscsi_host_priv(shost); - tcp_sw_host->session = session; shost->can_queue = session->scsi_cmds_max; if (iscsi_tcp_r2tpool_alloc(session)) goto remove_session; + + /* We are now fully setup so expose the session to sysfs. */ + tcp_sw_host = iscsi_host_priv(shost); + tcp_sw_host->session = session; return cls_session; remove_session: @@ -879,6 +890,10 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session) { struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct iscsi_session *session = cls_session->dd_data; + + if (WARN_ON_ONCE(session->leadconn)) + return; iscsi_tcp_r2tpool_free(cls_session->dd_data); iscsi_session_teardown(cls_session); --- linux-oracle-5.4.0.orig/drivers/scsi/jazz_esp.c +++ linux-oracle-5.4.0/drivers/scsi/jazz_esp.c @@ -143,7 +143,9 @@ if (!esp->command_block) goto fail_unmap_regs; - host->irq = platform_get_irq(dev, 0); + host->irq = err = platform_get_irq(dev, 0); + if (err < 0) + goto fail_unmap_command_block; err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); if (err < 0) goto fail_unmap_command_block; --- linux-oracle-5.4.0.orig/drivers/scsi/libfc/fc_disc.c +++ linux-oracle-5.4.0/drivers/scsi/libfc/fc_disc.c @@ -581,8 +581,12 @@ if (PTR_ERR(fp) == -FC_EX_CLOSED) goto out; - if (IS_ERR(fp)) - goto redisc; + if (IS_ERR(fp)) { + mutex_lock(&disc->disc_mutex); + fc_disc_restart(disc); + mutex_unlock(&disc->disc_mutex); + goto out; + } cp = fc_frame_payload_get(fp, sizeof(*cp)); if (!cp) @@ -609,7 +613,7 @@ new_rdata->disc_id = disc->disc_id; fc_rport_login(new_rdata); } - goto out; + goto free_fp; } rdata->disc_id = disc->disc_id; mutex_unlock(&rdata->rp_mutex); @@ -626,6 +630,8 @@ fc_disc_restart(disc); mutex_unlock(&disc->disc_mutex); } +free_fp: + fc_frame_free(fp); out: kref_put(&rdata->kref, fc_rport_destroy); } --- linux-oracle-5.4.0.orig/drivers/scsi/libfc/fc_exch.c +++ linux-oracle-5.4.0/drivers/scsi/libfc/fc_exch.c @@ -1619,8 +1619,13 @@ rc = fc_exch_done_locked(ep); WARN_ON(fc_seq_exch(sp) != ep); spin_unlock_bh(&ep->ex_lock); - if (!rc) + if (!rc) { fc_exch_delete(ep); + } else { + FC_EXCH_DBG(ep, "ep is completed already," + "hence skip calling the resp\n"); + goto skip_resp; + } } /* @@ -1639,6 +1644,7 @@ if (!fc_invoke_resp(ep, sp, fp)) fc_frame_free(fp); +skip_resp: fc_exch_release(ep); return; rel: @@ -1691,6 +1697,7 @@ if (cancel_delayed_work_sync(&ep->timeout_work)) { FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); fc_exch_release(ep); /* release from pending timer hold */ + return; } spin_lock_bh(&ep->ex_lock); @@ -1895,10 +1902,16 @@ fc_exch_hold(ep); - if (!rc) + if (!rc) { fc_exch_delete(ep); + } else { + FC_EXCH_DBG(ep, "ep is completed already," + "hence skip calling the resp\n"); + goto skip_resp; + } fc_invoke_resp(ep, sp, ERR_PTR(-FC_EX_CLOSED)); +skip_resp: fc_seq_set_resp(sp, NULL, ep->arg); fc_exch_release(ep); } --- linux-oracle-5.4.0.orig/drivers/scsi/libfc/fc_fcp.c +++ linux-oracle-5.4.0/drivers/scsi/libfc/fc_fcp.c @@ -270,6 +270,11 @@ if (!fsp->seq_ptr) return -EINVAL; + if (fsp->state & FC_SRB_ABORT_PENDING) { + FC_FCP_DBG(fsp, "abort already pending\n"); + return -EBUSY; + } + per_cpu_ptr(fsp->lp->stats, get_cpu())->FcpPktAborts++; put_cpu(); @@ -1680,7 +1685,7 @@ if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) fc_fcp_rec(fsp); else - fc_fcp_recovery(fsp, FC_ERROR); + fc_fcp_recovery(fsp, FC_TIMED_OUT); break; } fc_fcp_unlock_pkt(fsp); @@ -1698,11 +1703,12 @@ fsp->status_code = code; fsp->cdb_status = 0; fsp->io_status = 0; - /* - * if this fails then we let the scsi command timer fire and - * scsi-ml escalate. - */ - fc_fcp_send_abort(fsp); + if (!fsp->cmd) + /* + * Only abort non-scsi commands; otherwise let the + * scsi command timer fire and scsi-ml escalate. + */ + fc_fcp_send_abort(fsp); } /** --- linux-oracle-5.4.0.orig/drivers/scsi/libfc/fc_lport.c +++ linux-oracle-5.4.0/drivers/scsi/libfc/fc_lport.c @@ -238,6 +238,12 @@ } mutex_lock(&lport->disc.disc_mutex); lport->ptp_rdata = fc_rport_create(lport, remote_fid); + if (!lport->ptp_rdata) { + printk(KERN_WARNING "libfc: Failed to setup lport 0x%x\n", + lport->port_id); + mutex_unlock(&lport->disc.disc_mutex); + return; + } kref_get(&lport->ptp_rdata->kref); lport->ptp_rdata->ids.port_name = remote_wwpn; lport->ptp_rdata->ids.node_name = remote_wwnn; @@ -1729,7 +1735,7 @@ if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " - "lport->mfs:%hu\n", mfs, lport->mfs); + "lport->mfs:%u\n", mfs, lport->mfs); fc_lport_error(lport, fp); goto out; } --- linux-oracle-5.4.0.orig/drivers/scsi/libfc/fc_rport.c +++ linux-oracle-5.4.0/drivers/scsi/libfc/fc_rport.c @@ -133,8 +133,10 @@ lockdep_assert_held(&lport->disc.disc_mutex); rdata = fc_rport_lookup(lport, port_id); - if (rdata) + if (rdata) { + kref_put(&rdata->kref, fc_rport_destroy); return rdata; + } if (lport->rport_priv_size > 0) rport_priv_size = lport->rport_priv_size; @@ -481,10 +483,11 @@ fc_rport_state_enter(rdata, RPORT_ST_DELETE); - kref_get(&rdata->kref); - if (rdata->event == RPORT_EV_NONE && - !queue_work(rport_event_queue, &rdata->event_work)) - kref_put(&rdata->kref, fc_rport_destroy); + if (rdata->event == RPORT_EV_NONE) { + kref_get(&rdata->kref); + if (!queue_work(rport_event_queue, &rdata->event_work)) + kref_put(&rdata->kref, fc_rport_destroy); + } rdata->event = event; } @@ -1157,6 +1160,7 @@ resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK); FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x spp_type 0x%x\n", pp->spp.spp_flags, pp->spp.spp_type); + rdata->spp_type = pp->spp.spp_type; if (resp_code != FC_SPP_RESP_ACK) { if (resp_code == FC_SPP_RESP_CONF) @@ -1179,11 +1183,13 @@ /* * Call prli provider if we should act as a target */ - prov = fc_passive_prov[rdata->spp_type]; - if (prov) { - memset(&temp_spp, 0, sizeof(temp_spp)); - prov->prli(rdata, pp->prli.prli_spp_len, - &pp->spp, &temp_spp); + if (rdata->spp_type < FC_FC4_PROV_SIZE) { + prov = fc_passive_prov[rdata->spp_type]; + if (prov) { + memset(&temp_spp, 0, sizeof(temp_spp)); + prov->prli(rdata, pp->prli.prli_spp_len, + &pp->spp, &temp_spp); + } } /* * Check if the image pair could be established @@ -1208,9 +1214,15 @@ rjt = fc_frame_payload_get(fp, sizeof(*rjt)); if (!rjt) FC_RPORT_DBG(rdata, "PRLI bad response\n"); - else + else { FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n", rjt->er_reason, rjt->er_explan); + if (rjt->er_reason == ELS_RJT_UNAB && + rjt->er_explan == ELS_EXPL_PLOGI_REQD) { + fc_rport_enter_plogi(rdata); + goto out; + } + } fc_rport_error_retry(rdata, FC_EX_ELS_RJT); } --- linux-oracle-5.4.0.orig/drivers/scsi/libiscsi.c +++ linux-oracle-5.4.0/drivers/scsi/libiscsi.c @@ -230,11 +230,11 @@ */ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) { - struct iscsi_conn *conn = task->conn; - struct iscsi_tm *tmf = &conn->tmhdr; + struct iscsi_session *session = task->conn->session; + struct iscsi_tm *tmf = &session->tmhdr; u64 hdr_lun; - if (conn->tmf_state == TMF_INITIAL) + if (session->tmf_state == TMF_INITIAL) return 0; if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC) @@ -254,24 +254,19 @@ * Fail all SCSI cmd PDUs */ if (opcode != ISCSI_OP_SCSI_DATA_OUT) { - iscsi_conn_printk(KERN_INFO, conn, - "task [op %x itt " - "0x%x/0x%x] " - "rejected.\n", - opcode, task->itt, - task->hdr_itt); + iscsi_session_printk(KERN_INFO, session, + "task [op %x itt 0x%x/0x%x] rejected.\n", + opcode, task->itt, task->hdr_itt); return -EACCES; } /* * And also all data-out PDUs in response to R2T * if fast_abort is set. */ - if (conn->session->fast_abort) { - iscsi_conn_printk(KERN_INFO, conn, - "task [op %x itt " - "0x%x/0x%x] fast abort.\n", - opcode, task->itt, - task->hdr_itt); + if (session->fast_abort) { + iscsi_session_printk(KERN_INFO, session, + "task [op %x itt 0x%x/0x%x] fast abort.\n", + opcode, task->itt, task->hdr_itt); return -EACCES; } break; @@ -284,7 +279,7 @@ */ if (opcode == ISCSI_OP_SCSI_DATA_OUT && task->hdr_itt == tmf->rtt) { - ISCSI_DBG_SESSION(conn->session, + ISCSI_DBG_SESSION(session, "Preventing task %x/%x from sending " "data-out due to abort task in " "progress\n", task->itt, @@ -533,8 +528,8 @@ if (conn->task == task) conn->task = NULL; - if (conn->ping_task == task) - conn->ping_task = NULL; + if (READ_ONCE(conn->ping_task) == task) + WRITE_ONCE(conn->ping_task, NULL); /* release get from queueing */ __iscsi_put_task(task); @@ -738,6 +733,9 @@ task->conn->session->age); } + if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK)) + WRITE_ONCE(conn->ping_task, task); + if (!ihost->workq) { if (iscsi_prep_mgmt_task(conn, task)) goto free_task; @@ -920,20 +918,21 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) { struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; + struct iscsi_session *session = conn->session; conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; conn->tmfrsp_pdus_cnt++; - if (conn->tmf_state != TMF_QUEUED) + if (session->tmf_state != TMF_QUEUED) return; if (tmf->response == ISCSI_TMF_RSP_COMPLETE) - conn->tmf_state = TMF_SUCCESS; + session->tmf_state = TMF_SUCCESS; else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) - conn->tmf_state = TMF_NOT_FOUND; + session->tmf_state = TMF_NOT_FOUND; else - conn->tmf_state = TMF_FAILED; - wake_up(&conn->ehwait); + session->tmf_state = TMF_FAILED; + wake_up(&session->ehwait); } static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) @@ -941,8 +940,11 @@ struct iscsi_nopout hdr; struct iscsi_task *task; - if (!rhdr && conn->ping_task) - return -EINVAL; + if (!rhdr) { + if (READ_ONCE(conn->ping_task)) + return -EINVAL; + WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK); + } memset(&hdr, 0, sizeof(struct iscsi_nopout)); hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE; @@ -957,11 +959,12 @@ task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); if (!task) { + if (!rhdr) + WRITE_ONCE(conn->ping_task, NULL); iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); return -EIO; } else if (!rhdr) { /* only track our nops */ - conn->ping_task = task; conn->last_ping = jiffies; } @@ -984,7 +987,7 @@ struct iscsi_conn *conn = task->conn; int rc = 0; - if (conn->ping_task != task) { + if (READ_ONCE(conn->ping_task) != task) { /* * If this is not in response to one of our * nops then it must be from userspace. @@ -1341,7 +1344,6 @@ enum iscsi_err err) { struct iscsi_conn *conn; - struct device *dev; spin_lock_bh(&session->frwd_lock); conn = session->leadconn; @@ -1350,10 +1352,8 @@ return; } - dev = get_device(&conn->cls_conn->dev); + iscsi_get_conn(conn->cls_conn); spin_unlock_bh(&session->frwd_lock); - if (!dev) - return; /* * if the host is being removed bypass the connection * recovery initialization because we are going to kill @@ -1363,7 +1363,7 @@ iscsi_conn_error_event(conn->cls_conn, err); else iscsi_conn_failure(conn, err); - put_device(dev); + iscsi_put_conn(conn->cls_conn); } EXPORT_SYMBOL_GPL(iscsi_session_failure); @@ -1525,14 +1525,9 @@ } rc = iscsi_prep_scsi_cmd_pdu(conn->task); if (rc) { - if (rc == -ENOMEM || rc == -EACCES) { - spin_lock_bh(&conn->taskqueuelock); - list_add_tail(&conn->task->running, - &conn->cmdqueue); - conn->task = NULL; - spin_unlock_bh(&conn->taskqueuelock); - goto done; - } else + if (rc == -ENOMEM || rc == -EACCES) + fail_scsi_task(conn->task, DID_IMM_RETRY); + else fail_scsi_task(conn->task, DID_ABORT); spin_lock_bh(&conn->taskqueuelock); continue; @@ -1785,15 +1780,14 @@ static void iscsi_tmf_timedout(struct timer_list *t) { - struct iscsi_conn *conn = from_timer(conn, t, tmf_timer); - struct iscsi_session *session = conn->session; + struct iscsi_session *session = from_timer(session, t, tmf_timer); spin_lock(&session->frwd_lock); - if (conn->tmf_state == TMF_QUEUED) { - conn->tmf_state = TMF_TIMEDOUT; + if (session->tmf_state == TMF_QUEUED) { + session->tmf_state = TMF_TIMEDOUT; ISCSI_DBG_EH(session, "tmf timedout\n"); /* unblock eh_abort() */ - wake_up(&conn->ehwait); + wake_up(&session->ehwait); } spin_unlock(&session->frwd_lock); } @@ -1816,8 +1810,8 @@ return -EPERM; } conn->tmfcmd_pdus_cnt++; - conn->tmf_timer.expires = timeout * HZ + jiffies; - add_timer(&conn->tmf_timer); + session->tmf_timer.expires = timeout * HZ + jiffies; + add_timer(&session->tmf_timer); ISCSI_DBG_EH(session, "tmf set timeout\n"); spin_unlock_bh(&session->frwd_lock); @@ -1831,12 +1825,12 @@ * 3) session is terminated or restarted or userspace has * given up on recovery */ - wait_event_interruptible(conn->ehwait, age != session->age || + wait_event_interruptible(session->ehwait, age != session->age || session->state != ISCSI_STATE_LOGGED_IN || - conn->tmf_state != TMF_QUEUED); + session->tmf_state != TMF_QUEUED); if (signal_pending(current)) flush_signals(current); - del_timer_sync(&conn->tmf_timer); + del_timer_sync(&session->tmf_timer); mutex_lock(&session->eh_mutex); spin_lock_bh(&session->frwd_lock); @@ -1923,7 +1917,7 @@ */ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) { - if (conn->ping_task && + if (READ_ONCE(conn->ping_task) && time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) + (conn->ping_timeout * HZ), jiffies)) return 1; @@ -1945,7 +1939,7 @@ ISCSI_DBG_EH(session, "scsi cmd %p timedout\n", sc); - spin_lock(&session->frwd_lock); + spin_lock_bh(&session->frwd_lock); task = (struct iscsi_task *)sc->SCp.ptr; if (!task) { /* @@ -2058,7 +2052,7 @@ * Checking the transport already or nop from a cmd timeout still * running */ - if (conn->ping_task) { + if (READ_ONCE(conn->ping_task)) { task->have_checked_conn = true; rc = BLK_EH_RESET_TIMER; goto done; @@ -2072,7 +2066,7 @@ done: if (task) task->last_timeout = jiffies; - spin_unlock(&session->frwd_lock); + spin_unlock_bh(&session->frwd_lock); ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? "timer reset" : "shutdown or nh"); return rc; @@ -2196,17 +2190,17 @@ } /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto failed; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_abort_task_pdu(task, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) goto failed; - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: spin_unlock_bh(&session->frwd_lock); /* @@ -2221,7 +2215,7 @@ */ spin_lock_bh(&session->frwd_lock); fail_scsi_task(task, DID_ABORT); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; memset(hdr, 0, sizeof(*hdr)); spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2232,7 +2226,7 @@ goto failed_unlocked; case TMF_NOT_FOUND: if (!sc->SCp.ptr) { - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; memset(hdr, 0, sizeof(*hdr)); /* task completed before tmf abort response */ ISCSI_DBG_EH(session, "sc completed while abort in " @@ -2241,7 +2235,7 @@ } /* fall through */ default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto failed; } @@ -2298,11 +2292,11 @@ conn = session->leadconn; /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto unlock; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_lun_reset_pdu(sc, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, @@ -2311,7 +2305,7 @@ goto unlock; } - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: break; case TMF_TIMEDOUT: @@ -2319,7 +2313,7 @@ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); goto done; default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto unlock; } @@ -2331,7 +2325,7 @@ spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); fail_scsi_tasks(conn, sc->device->lun, DID_ERROR); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2354,8 +2348,7 @@ spin_lock_bh(&session->frwd_lock); if (session->state != ISCSI_STATE_LOGGED_IN) { session->state = ISCSI_STATE_RECOVERY_FAILED; - if (session->leadconn) - wake_up(&session->leadconn->ehwait); + wake_up(&session->ehwait); } spin_unlock_bh(&session->frwd_lock); } @@ -2400,7 +2393,7 @@ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); ISCSI_DBG_EH(session, "wait for relogin\n"); - wait_event_interruptible(conn->ehwait, + wait_event_interruptible(session->ehwait, session->state == ISCSI_STATE_TERMINATE || session->state == ISCSI_STATE_LOGGED_IN || session->state == ISCSI_STATE_RECOVERY_FAILED); @@ -2461,11 +2454,11 @@ conn = session->leadconn; /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto unlock; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_tgt_reset_pdu(sc, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, @@ -2474,7 +2467,7 @@ goto unlock; } - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: break; case TMF_TIMEDOUT: @@ -2482,7 +2475,7 @@ iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); goto done; default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto unlock; } @@ -2494,7 +2487,7 @@ spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); fail_scsi_tasks(conn, -1, DID_ERROR); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2799,7 +2792,10 @@ session->tt = iscsit; session->dd_data = cls_session->dd_data + sizeof(*session); + session->tmf_state = TMF_INITIAL; + timer_setup(&session->tmf_timer, iscsi_tmf_timedout, 0); mutex_init(&session->eh_mutex); + spin_lock_init(&session->frwd_lock); spin_lock_init(&session->back_lock); @@ -2903,7 +2899,6 @@ conn->c_stage = ISCSI_CONN_INITIAL_STAGE; conn->id = conn_idx; conn->exp_statsn = 0; - conn->tmf_state = TMF_INITIAL; timer_setup(&conn->transport_timer, iscsi_check_transport_timeouts, 0); @@ -2929,8 +2924,7 @@ goto login_task_data_alloc_fail; conn->login_task->data = conn->data = data; - timer_setup(&conn->tmf_timer, iscsi_tmf_timedout, 0); - init_waitqueue_head(&conn->ehwait); + init_waitqueue_head(&session->ehwait); return cls_conn; @@ -2954,6 +2948,8 @@ { struct iscsi_conn *conn = cls_conn->dd_data; struct iscsi_session *session = conn->session; + char *tmp_persistent_address = conn->persistent_address; + char *tmp_local_ipaddr = conn->local_ipaddr; del_timer_sync(&conn->transport_timer); @@ -2965,7 +2961,7 @@ * leading connection? then give up on recovery. */ session->state = ISCSI_STATE_TERMINATE; - wake_up(&conn->ehwait); + wake_up(&session->ehwait); } spin_unlock_bh(&session->frwd_lock); @@ -2975,8 +2971,6 @@ spin_lock_bh(&session->frwd_lock); free_pages((unsigned long) conn->data, get_order(ISCSI_DEF_MAX_RECV_SEG_LEN)); - kfree(conn->persistent_address); - kfree(conn->local_ipaddr); /* regular RX path uses back_lock */ spin_lock_bh(&session->back_lock); kfifo_in(&session->cmdpool.queue, (void*)&conn->login_task, @@ -2988,6 +2982,8 @@ mutex_unlock(&session->eh_mutex); iscsi_destroy_conn(cls_conn); + kfree(tmp_persistent_address); + kfree(tmp_local_ipaddr); } EXPORT_SYMBOL_GPL(iscsi_conn_teardown); @@ -3040,7 +3036,7 @@ * commands after successful recovery */ conn->stop_stage = 0; - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; session->age++; if (session->age == 16) session->age = 0; @@ -3054,7 +3050,7 @@ spin_unlock_bh(&session->frwd_lock); iscsi_unblock_session(session->cls_session); - wake_up(&conn->ehwait); + wake_up(&session->ehwait); return 0; } EXPORT_SYMBOL_GPL(iscsi_conn_start); @@ -3141,7 +3137,7 @@ spin_lock_bh(&session->frwd_lock); fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); fail_mgmt_tasks(session, conn); - memset(&conn->tmhdr, 0, sizeof(conn->tmhdr)); + memset(&session->tmhdr, 0, sizeof(session->tmhdr)); spin_unlock_bh(&session->frwd_lock); mutex_unlock(&session->eh_mutex); } @@ -3324,125 +3320,125 @@ switch(param) { case ISCSI_PARAM_FAST_ABORT: - len = sprintf(buf, "%d\n", session->fast_abort); + len = sysfs_emit(buf, "%d\n", session->fast_abort); break; case ISCSI_PARAM_ABORT_TMO: - len = sprintf(buf, "%d\n", session->abort_timeout); + len = sysfs_emit(buf, "%d\n", session->abort_timeout); break; case ISCSI_PARAM_LU_RESET_TMO: - len = sprintf(buf, "%d\n", session->lu_reset_timeout); + len = sysfs_emit(buf, "%d\n", session->lu_reset_timeout); break; case ISCSI_PARAM_TGT_RESET_TMO: - len = sprintf(buf, "%d\n", session->tgt_reset_timeout); + len = sysfs_emit(buf, "%d\n", session->tgt_reset_timeout); break; case ISCSI_PARAM_INITIAL_R2T_EN: - len = sprintf(buf, "%d\n", session->initial_r2t_en); + len = sysfs_emit(buf, "%d\n", session->initial_r2t_en); break; case ISCSI_PARAM_MAX_R2T: - len = sprintf(buf, "%hu\n", session->max_r2t); + len = sysfs_emit(buf, "%hu\n", session->max_r2t); break; case ISCSI_PARAM_IMM_DATA_EN: - len = sprintf(buf, "%d\n", session->imm_data_en); + len = sysfs_emit(buf, "%d\n", session->imm_data_en); break; case ISCSI_PARAM_FIRST_BURST: - len = sprintf(buf, "%u\n", session->first_burst); + len = sysfs_emit(buf, "%u\n", session->first_burst); break; case ISCSI_PARAM_MAX_BURST: - len = sprintf(buf, "%u\n", session->max_burst); + len = sysfs_emit(buf, "%u\n", session->max_burst); break; case ISCSI_PARAM_PDU_INORDER_EN: - len = sprintf(buf, "%d\n", session->pdu_inorder_en); + len = sysfs_emit(buf, "%d\n", session->pdu_inorder_en); break; case ISCSI_PARAM_DATASEQ_INORDER_EN: - len = sprintf(buf, "%d\n", session->dataseq_inorder_en); + len = sysfs_emit(buf, "%d\n", session->dataseq_inorder_en); break; case ISCSI_PARAM_DEF_TASKMGMT_TMO: - len = sprintf(buf, "%d\n", session->def_taskmgmt_tmo); + len = sysfs_emit(buf, "%d\n", session->def_taskmgmt_tmo); break; case ISCSI_PARAM_ERL: - len = sprintf(buf, "%d\n", session->erl); + len = sysfs_emit(buf, "%d\n", session->erl); break; case ISCSI_PARAM_TARGET_NAME: - len = sprintf(buf, "%s\n", session->targetname); + len = sysfs_emit(buf, "%s\n", session->targetname); break; case ISCSI_PARAM_TARGET_ALIAS: - len = sprintf(buf, "%s\n", session->targetalias); + len = sysfs_emit(buf, "%s\n", session->targetalias); break; case ISCSI_PARAM_TPGT: - len = sprintf(buf, "%d\n", session->tpgt); + len = sysfs_emit(buf, "%d\n", session->tpgt); break; case ISCSI_PARAM_USERNAME: - len = sprintf(buf, "%s\n", session->username); + len = sysfs_emit(buf, "%s\n", session->username); break; case ISCSI_PARAM_USERNAME_IN: - len = sprintf(buf, "%s\n", session->username_in); + len = sysfs_emit(buf, "%s\n", session->username_in); break; case ISCSI_PARAM_PASSWORD: - len = sprintf(buf, "%s\n", session->password); + len = sysfs_emit(buf, "%s\n", session->password); break; case ISCSI_PARAM_PASSWORD_IN: - len = sprintf(buf, "%s\n", session->password_in); + len = sysfs_emit(buf, "%s\n", session->password_in); break; case ISCSI_PARAM_IFACE_NAME: - len = sprintf(buf, "%s\n", session->ifacename); + len = sysfs_emit(buf, "%s\n", session->ifacename); break; case ISCSI_PARAM_INITIATOR_NAME: - len = sprintf(buf, "%s\n", session->initiatorname); + len = sysfs_emit(buf, "%s\n", session->initiatorname); break; case ISCSI_PARAM_BOOT_ROOT: - len = sprintf(buf, "%s\n", session->boot_root); + len = sysfs_emit(buf, "%s\n", session->boot_root); break; case ISCSI_PARAM_BOOT_NIC: - len = sprintf(buf, "%s\n", session->boot_nic); + len = sysfs_emit(buf, "%s\n", session->boot_nic); break; case ISCSI_PARAM_BOOT_TARGET: - len = sprintf(buf, "%s\n", session->boot_target); + len = sysfs_emit(buf, "%s\n", session->boot_target); break; case ISCSI_PARAM_AUTO_SND_TGT_DISABLE: - len = sprintf(buf, "%u\n", session->auto_snd_tgt_disable); + len = sysfs_emit(buf, "%u\n", session->auto_snd_tgt_disable); break; case ISCSI_PARAM_DISCOVERY_SESS: - len = sprintf(buf, "%u\n", session->discovery_sess); + len = sysfs_emit(buf, "%u\n", session->discovery_sess); break; case ISCSI_PARAM_PORTAL_TYPE: - len = sprintf(buf, "%s\n", session->portal_type); + len = sysfs_emit(buf, "%s\n", session->portal_type); break; case ISCSI_PARAM_CHAP_AUTH_EN: - len = sprintf(buf, "%u\n", session->chap_auth_en); + len = sysfs_emit(buf, "%u\n", session->chap_auth_en); break; case ISCSI_PARAM_DISCOVERY_LOGOUT_EN: - len = sprintf(buf, "%u\n", session->discovery_logout_en); + len = sysfs_emit(buf, "%u\n", session->discovery_logout_en); break; case ISCSI_PARAM_BIDI_CHAP_EN: - len = sprintf(buf, "%u\n", session->bidi_chap_en); + len = sysfs_emit(buf, "%u\n", session->bidi_chap_en); break; case ISCSI_PARAM_DISCOVERY_AUTH_OPTIONAL: - len = sprintf(buf, "%u\n", session->discovery_auth_optional); + len = sysfs_emit(buf, "%u\n", session->discovery_auth_optional); break; case ISCSI_PARAM_DEF_TIME2WAIT: - len = sprintf(buf, "%d\n", session->time2wait); + len = sysfs_emit(buf, "%d\n", session->time2wait); break; case ISCSI_PARAM_DEF_TIME2RETAIN: - len = sprintf(buf, "%d\n", session->time2retain); + len = sysfs_emit(buf, "%d\n", session->time2retain); break; case ISCSI_PARAM_TSID: - len = sprintf(buf, "%u\n", session->tsid); + len = sysfs_emit(buf, "%u\n", session->tsid); break; case ISCSI_PARAM_ISID: - len = sprintf(buf, "%02x%02x%02x%02x%02x%02x\n", + len = sysfs_emit(buf, "%02x%02x%02x%02x%02x%02x\n", session->isid[0], session->isid[1], session->isid[2], session->isid[3], session->isid[4], session->isid[5]); break; case ISCSI_PARAM_DISCOVERY_PARENT_IDX: - len = sprintf(buf, "%u\n", session->discovery_parent_idx); + len = sysfs_emit(buf, "%u\n", session->discovery_parent_idx); break; case ISCSI_PARAM_DISCOVERY_PARENT_TYPE: if (session->discovery_parent_type) - len = sprintf(buf, "%s\n", + len = sysfs_emit(buf, "%s\n", session->discovery_parent_type); else - len = sprintf(buf, "\n"); + len = sysfs_emit(buf, "\n"); break; default: return -ENOSYS; @@ -3474,16 +3470,16 @@ case ISCSI_PARAM_CONN_ADDRESS: case ISCSI_HOST_PARAM_IPADDRESS: if (sin) - len = sprintf(buf, "%pI4\n", &sin->sin_addr.s_addr); + len = sysfs_emit(buf, "%pI4\n", &sin->sin_addr.s_addr); else - len = sprintf(buf, "%pI6\n", &sin6->sin6_addr); + len = sysfs_emit(buf, "%pI6\n", &sin6->sin6_addr); break; case ISCSI_PARAM_CONN_PORT: case ISCSI_PARAM_LOCAL_PORT: if (sin) - len = sprintf(buf, "%hu\n", be16_to_cpu(sin->sin_port)); + len = sysfs_emit(buf, "%hu\n", be16_to_cpu(sin->sin_port)); else - len = sprintf(buf, "%hu\n", + len = sysfs_emit(buf, "%hu\n", be16_to_cpu(sin6->sin6_port)); break; default: @@ -3502,88 +3498,88 @@ switch(param) { case ISCSI_PARAM_PING_TMO: - len = sprintf(buf, "%u\n", conn->ping_timeout); + len = sysfs_emit(buf, "%u\n", conn->ping_timeout); break; case ISCSI_PARAM_RECV_TMO: - len = sprintf(buf, "%u\n", conn->recv_timeout); + len = sysfs_emit(buf, "%u\n", conn->recv_timeout); break; case ISCSI_PARAM_MAX_RECV_DLENGTH: - len = sprintf(buf, "%u\n", conn->max_recv_dlength); + len = sysfs_emit(buf, "%u\n", conn->max_recv_dlength); break; case ISCSI_PARAM_MAX_XMIT_DLENGTH: - len = sprintf(buf, "%u\n", conn->max_xmit_dlength); + len = sysfs_emit(buf, "%u\n", conn->max_xmit_dlength); break; case ISCSI_PARAM_HDRDGST_EN: - len = sprintf(buf, "%d\n", conn->hdrdgst_en); + len = sysfs_emit(buf, "%d\n", conn->hdrdgst_en); break; case ISCSI_PARAM_DATADGST_EN: - len = sprintf(buf, "%d\n", conn->datadgst_en); + len = sysfs_emit(buf, "%d\n", conn->datadgst_en); break; case ISCSI_PARAM_IFMARKER_EN: - len = sprintf(buf, "%d\n", conn->ifmarker_en); + len = sysfs_emit(buf, "%d\n", conn->ifmarker_en); break; case ISCSI_PARAM_OFMARKER_EN: - len = sprintf(buf, "%d\n", conn->ofmarker_en); + len = sysfs_emit(buf, "%d\n", conn->ofmarker_en); break; case ISCSI_PARAM_EXP_STATSN: - len = sprintf(buf, "%u\n", conn->exp_statsn); + len = sysfs_emit(buf, "%u\n", conn->exp_statsn); break; case ISCSI_PARAM_PERSISTENT_PORT: - len = sprintf(buf, "%d\n", conn->persistent_port); + len = sysfs_emit(buf, "%d\n", conn->persistent_port); break; case ISCSI_PARAM_PERSISTENT_ADDRESS: - len = sprintf(buf, "%s\n", conn->persistent_address); + len = sysfs_emit(buf, "%s\n", conn->persistent_address); break; case ISCSI_PARAM_STATSN: - len = sprintf(buf, "%u\n", conn->statsn); + len = sysfs_emit(buf, "%u\n", conn->statsn); break; case ISCSI_PARAM_MAX_SEGMENT_SIZE: - len = sprintf(buf, "%u\n", conn->max_segment_size); + len = sysfs_emit(buf, "%u\n", conn->max_segment_size); break; case ISCSI_PARAM_KEEPALIVE_TMO: - len = sprintf(buf, "%u\n", conn->keepalive_tmo); + len = sysfs_emit(buf, "%u\n", conn->keepalive_tmo); break; case ISCSI_PARAM_LOCAL_PORT: - len = sprintf(buf, "%u\n", conn->local_port); + len = sysfs_emit(buf, "%u\n", conn->local_port); break; case ISCSI_PARAM_TCP_TIMESTAMP_STAT: - len = sprintf(buf, "%u\n", conn->tcp_timestamp_stat); + len = sysfs_emit(buf, "%u\n", conn->tcp_timestamp_stat); break; case ISCSI_PARAM_TCP_NAGLE_DISABLE: - len = sprintf(buf, "%u\n", conn->tcp_nagle_disable); + len = sysfs_emit(buf, "%u\n", conn->tcp_nagle_disable); break; case ISCSI_PARAM_TCP_WSF_DISABLE: - len = sprintf(buf, "%u\n", conn->tcp_wsf_disable); + len = sysfs_emit(buf, "%u\n", conn->tcp_wsf_disable); break; case ISCSI_PARAM_TCP_TIMER_SCALE: - len = sprintf(buf, "%u\n", conn->tcp_timer_scale); + len = sysfs_emit(buf, "%u\n", conn->tcp_timer_scale); break; case ISCSI_PARAM_TCP_TIMESTAMP_EN: - len = sprintf(buf, "%u\n", conn->tcp_timestamp_en); + len = sysfs_emit(buf, "%u\n", conn->tcp_timestamp_en); break; case ISCSI_PARAM_IP_FRAGMENT_DISABLE: - len = sprintf(buf, "%u\n", conn->fragment_disable); + len = sysfs_emit(buf, "%u\n", conn->fragment_disable); break; case ISCSI_PARAM_IPV4_TOS: - len = sprintf(buf, "%u\n", conn->ipv4_tos); + len = sysfs_emit(buf, "%u\n", conn->ipv4_tos); break; case ISCSI_PARAM_IPV6_TC: - len = sprintf(buf, "%u\n", conn->ipv6_traffic_class); + len = sysfs_emit(buf, "%u\n", conn->ipv6_traffic_class); break; case ISCSI_PARAM_IPV6_FLOW_LABEL: - len = sprintf(buf, "%u\n", conn->ipv6_flow_label); + len = sysfs_emit(buf, "%u\n", conn->ipv6_flow_label); break; case ISCSI_PARAM_IS_FW_ASSIGNED_IPV6: - len = sprintf(buf, "%u\n", conn->is_fw_assigned_ipv6); + len = sysfs_emit(buf, "%u\n", conn->is_fw_assigned_ipv6); break; case ISCSI_PARAM_TCP_XMIT_WSF: - len = sprintf(buf, "%u\n", conn->tcp_xmit_wsf); + len = sysfs_emit(buf, "%u\n", conn->tcp_xmit_wsf); break; case ISCSI_PARAM_TCP_RECV_WSF: - len = sprintf(buf, "%u\n", conn->tcp_recv_wsf); + len = sysfs_emit(buf, "%u\n", conn->tcp_recv_wsf); break; case ISCSI_PARAM_LOCAL_IPADDR: - len = sprintf(buf, "%s\n", conn->local_ipaddr); + len = sysfs_emit(buf, "%s\n", conn->local_ipaddr); break; default: return -ENOSYS; @@ -3601,13 +3597,13 @@ switch (param) { case ISCSI_HOST_PARAM_NETDEV_NAME: - len = sprintf(buf, "%s\n", ihost->netdev); + len = sysfs_emit(buf, "%s\n", ihost->netdev); break; case ISCSI_HOST_PARAM_HWADDRESS: - len = sprintf(buf, "%s\n", ihost->hwaddress); + len = sysfs_emit(buf, "%s\n", ihost->hwaddress); break; case ISCSI_HOST_PARAM_INITIATOR_NAME: - len = sprintf(buf, "%s\n", ihost->initiatorname); + len = sysfs_emit(buf, "%s\n", ihost->initiatorname); break; default: return -ENOSYS; --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_ata.c +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_ata.c @@ -200,15 +200,17 @@ memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); task->total_xfer_len = qc->nbytes; task->num_scatter = qc->n_elem; + task->data_dir = qc->dma_dir; + } else if (!ata_is_data(qc->tf.protocol)) { + task->data_dir = DMA_NONE; } else { for_each_sg(qc->sg, sg, qc->n_elem, si) xfer += sg_dma_len(sg); task->total_xfer_len = xfer; task->num_scatter = si; + task->data_dir = qc->dma_dir; } - - task->data_dir = qc->dma_dir; task->scatter = qc->sg; task->ata_task.retry_count = 1; task->task_state_flags = SAS_TASK_STATE_PENDING; --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_discover.c +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_discover.c @@ -81,12 +81,21 @@ else dev->dev_type = SAS_SATA_DEV; dev->tproto = SAS_PROTOCOL_SATA; - } else { + } else if (port->oob_mode == SAS_OOB_MODE) { struct sas_identify_frame *id = (struct sas_identify_frame *) dev->frame_rcvd; dev->dev_type = id->dev_type; dev->iproto = id->initiator_bits; dev->tproto = id->target_bits; + } else { + /* If the oob mode is OOB_NOT_CONNECTED, the port is + * disconnected due to race with PHY down. We cannot + * continue to discover this port + */ + sas_put_device(dev); + pr_warn("Port %016llx is disconnected when discovering\n", + SAS_ADDR(port->attached_sas_addr)); + return -ENODEV; } sas_init_dev(dev); @@ -173,10 +182,11 @@ pr_warn("driver on host %s cannot handle device %llx, error:%d\n", dev_name(sas_ha->dev), SAS_ADDR(dev->sas_addr), res); + return res; } set_bit(SAS_DEV_FOUND, &dev->state); kref_get(&dev->kref); - return res; + return 0; } --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_expander.c +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_expander.c @@ -85,7 +85,7 @@ res = i->dft->lldd_execute_task(task, GFP_KERNEL); if (res) { - del_timer(&task->slow_task->timer); + del_timer_sync(&task->slow_task->timer); pr_notice("executing SMP task failed:%d\n", res); break; } @@ -256,8 +256,7 @@ /* help some expanders that fail to zero sas_address in the 'no * device' case */ - if (phy->attached_dev_type == SAS_PHY_UNUSED || - phy->linkrate < SAS_LINK_RATE_1_5_GBPS) + if (phy->attached_dev_type == SAS_PHY_UNUSED) memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); else memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_internal.h +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_internal.h @@ -111,6 +111,20 @@ func, dev->parent ? "exp-attached" : "direct-attached", SAS_ADDR(dev->sas_addr), err); + + /* + * If the device probe failed, the expander phy attached address + * needs to be reset so that the phy will not be treated as flutter + * in the next revalidation + */ + if (dev->parent && !dev_is_expander(dev->dev_type)) { + struct sas_phy *phy = dev->phy; + struct domain_device *parent = dev->parent; + struct ex_phy *ex_phy = &parent->ex_dev.ex_phy[phy->number]; + + memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); + } + sas_unregister_dev(dev->port, dev); } --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_port.c +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_port.c @@ -25,7 +25,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) { - struct domain_device *dev; + struct domain_device *dev, *n; struct asd_sas_port *port = phy->port; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *si = to_sas_internal(sas_ha->core.shost->transportt); @@ -44,7 +44,7 @@ * 1/ presume every device came back * 2/ force the next revalidation to check all expander phys */ - list_for_each_entry(dev, &port->dev_list, dev_list_node) { + list_for_each_entry_safe(dev, n, &port->dev_list, dev_list_node) { int i, rc; rc = sas_notify_lldd_dev_found(dev); --- linux-oracle-5.4.0.orig/drivers/scsi/libsas/sas_scsi_host.c +++ linux-oracle-5.4.0/drivers/scsi/libsas/sas_scsi_host.c @@ -466,6 +466,9 @@ struct sas_internal *i = to_sas_internal(host->transportt); unsigned long flags; + if (current != host->ehandler) + return FAILED; + if (!i->dft->lldd_abort_task) return FAILED; @@ -911,6 +914,14 @@ blk_abort_request(sc->request); } +int sas_slave_alloc(struct scsi_device *sdev) +{ + if (dev_is_sata(sdev_to_domain_dev(sdev)) && sdev->lun) + return -ENXIO; + + return 0; +} + void sas_target_destroy(struct scsi_target *starget) { struct domain_device *found_dev = starget->hostdata; @@ -957,5 +968,6 @@ EXPORT_SYMBOL_GPL(sas_phy_reset); EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); EXPORT_SYMBOL_GPL(sas_eh_target_reset_handler); +EXPORT_SYMBOL_GPL(sas_slave_alloc); EXPORT_SYMBOL_GPL(sas_target_destroy); EXPORT_SYMBOL_GPL(sas_ioctl); --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -32,6 +32,7 @@ struct lpfc_sli2_slim; #define ELX_MODEL_NAME_SIZE 80 +#define ELX_FW_NAME_SIZE 84 #define LPFC_PCI_DEV_LP 0x1 #define LPFC_PCI_DEV_OC 0x2 @@ -262,7 +263,6 @@ uint32_t elsRcvPRLI; uint32_t elsRcvLIRR; uint32_t elsRcvRLS; - uint32_t elsRcvRPS; uint32_t elsRcvRPL; uint32_t elsRcvRRQ; uint32_t elsRcvRTV; @@ -377,6 +377,7 @@ #define FC_VPORT_LOGO_RCVD 0x200 /* LOGO received on vport */ #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ #define FC_LOGO_RCVD_DID_CHNG 0x800 /* FDISC on phys port detect DID chng*/ +#define FC_PT2PT_NO_NVME 0x1000 /* Don't send NVME PRLI */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ @@ -605,6 +606,12 @@ spinlock_t lock; /* lock for expedite pool */ }; +enum ras_state { + INACTIVE, + REG_INPROGRESS, + ACTIVE +}; + struct lpfc_ras_fwlog { uint8_t *fwlog_buff; uint32_t fw_buffcount; /* Buffer size posted to FW */ @@ -621,7 +628,7 @@ bool ras_enabled; /* Ras Enabled for the function */ #define LPFC_RAS_DISABLE_LOGGING 0x00 #define LPFC_RAS_ENABLE_LOGGING 0x01 - bool ras_active; /* RAS logging running state */ + enum ras_state state; /* RAS logging running state */ }; struct lpfc_hba { @@ -725,6 +732,7 @@ #define HBA_FCOE_MODE 0x4 /* HBA function in FCoE Mode */ #define HBA_SP_QUEUE_EVT 0x8 /* Slow-path qevt posted to worker thread*/ #define HBA_POST_RECEIVE_BUFFER 0x10 /* Rcv buffers need to be posted */ +#define HBA_PERSISTENT_TOPO 0x20 /* Persistent topology support in hba */ #define ELS_XRI_ABORT_EVENT 0x40 #define ASYNC_EVENT 0x80 #define LINK_DISABLED 0x100 /* Link disabled by user */ @@ -735,14 +743,15 @@ #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ #define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */ -#define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */ #define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */ #define HBA_FORCED_LINK_SPEED 0x40000 /* * Firmware supports Forced Link Speed * capability */ #define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */ +#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */ + struct completion *fw_dump_cmpl; /* cmpl event tracker for fw_dump */ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ struct lpfc_dmabuf slim2p; @@ -830,6 +839,7 @@ uint32_t cfg_fcp_mq_threshold; uint32_t cfg_hdw_queue; uint32_t cfg_irq_chann; + uint32_t cfg_irq_numa; uint32_t cfg_suppress_rsp; uint32_t cfg_nvme_oas; uint32_t cfg_nvme_embed_cmd; @@ -869,10 +879,19 @@ uint32_t cfg_hostmem_hgp; uint32_t cfg_log_verbose; uint32_t cfg_enable_fc4_type; +#define LPFC_ENABLE_FCP 1 +#define LPFC_ENABLE_NVME 2 +#define LPFC_ENABLE_BOTH 3 +#if (IS_ENABLED(CONFIG_NVME_FC)) +#define LPFC_MAX_ENBL_FC4_TYPE LPFC_ENABLE_BOTH +#define LPFC_DEF_ENBL_FC4_TYPE LPFC_ENABLE_BOTH +#else +#define LPFC_MAX_ENBL_FC4_TYPE LPFC_ENABLE_FCP +#define LPFC_DEF_ENBL_FC4_TYPE LPFC_ENABLE_FCP +#endif uint32_t cfg_aer_support; uint32_t cfg_sriov_nr_virtfn; uint32_t cfg_request_firmware_upgrade; - uint32_t cfg_iocb_cnt; uint32_t cfg_suppress_link_up; uint32_t cfg_rrq_xri_bitmap_sz; uint32_t cfg_delay_discovery; @@ -891,9 +910,6 @@ uint32_t cfg_ras_fwlog_func; uint32_t cfg_enable_bbcr; /* Enable BB Credit Recovery */ uint32_t cfg_enable_dpp; /* Enable Direct Packet Push */ -#define LPFC_ENABLE_FCP 1 -#define LPFC_ENABLE_NVME 2 -#define LPFC_ENABLE_BOTH 3 uint32_t cfg_enable_pbde; struct nvmet_fc_target_port *targetport; lpfc_vpd_t vpd; /* vital product data */ @@ -990,7 +1006,6 @@ struct dma_pool *lpfc_drb_pool; /* data receive buffer pool */ struct dma_pool *lpfc_nvmet_drb_pool; /* data receive buffer pool */ struct dma_pool *lpfc_hbq_pool; /* SLI3 hbq buffer pool */ - struct dma_pool *txrdy_payload_pool; struct dma_pool *lpfc_cmd_rsp_buf_pool; struct lpfc_dma_pool lpfc_mbuf_safety_pool; @@ -1029,7 +1044,6 @@ unsigned long bit_flags; #define FABRIC_COMANDS_BLOCKED 0 atomic_t num_rsrc_err; - atomic_t num_cmd_success; unsigned long last_rsrc_error_time; unsigned long last_ramp_down_time; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS @@ -1055,6 +1069,7 @@ #ifdef LPFC_HDWQ_LOCK_STAT struct dentry *debug_lockstat; #endif + struct dentry *debug_ras_log; atomic_t nvmeio_trc_cnt; uint32_t nvmeio_trc_size; uint32_t nvmeio_trc_output_idx; @@ -1209,6 +1224,15 @@ uint64_t ktime_seg10_min; uint64_t ktime_seg10_max; #endif + + struct hlist_node cpuhp; /* used for cpuhp per hba callback */ + struct timer_list cpuhp_poll_timer; + struct list_head poll_list; /* slowpath eq polling list */ +#define LPFC_POLL_HB 1 /* slowpath heartbeat */ +#define LPFC_POLL_FASTPATH 0 /* called from fastpath */ +#define LPFC_POLL_SLOWPATH 1 /* called from slowpath */ + + char os_host_name[MAXHOSTNAMELEN]; }; static inline struct Scsi_Host * @@ -1299,6 +1323,26 @@ } /** + * lpfc_next_online_numa_cpu - Finds next online CPU on NUMA node + * @numa_mask: Pointer to phba's numa_mask member. + * @start: starting cpu index + * + * Note: If no valid cpu found, then nr_cpu_ids is returned. + * + **/ +static inline unsigned int +lpfc_next_online_numa_cpu(const struct cpumask *numa_mask, unsigned int start) +{ + unsigned int cpu_it; + + for_each_cpu_wrap(cpu_it, numa_mask, start) { + if (cpu_online(cpu_it)) + break; + } + + return cpu_it; +} +/** * lpfc_sli4_mod_hba_eq_delay - update EQ delay * @phba: Pointer to HBA context object. * @q: The Event Queue to update. @@ -1317,3 +1361,32 @@ writel(reg_data.word0, phba->sli4_hba.u.if_type2.EQDregaddr); eq->q_mode = delay; } + + +/* + * Macro that declares tables and a routine to perform enum type to + * ascii string lookup. + * + * Defines a table for an enum. Uses xxx_INIT defines for + * the enum to populate the table. Macro defines a routine (named + * by caller) that will search all elements of the table for the key + * and return the name string if found or "Unrecognized" if not found. + */ +#define DECLARE_ENUM2STR_LOOKUP(routine, enum_name, enum_init) \ +static struct { \ + enum enum_name value; \ + char *name; \ +} fc_##enum_name##_e2str_names[] = enum_init; \ +static const char *routine(enum enum_name table_key) \ +{ \ + int i; \ + char *name = "Unrecognized"; \ + \ + for (i = 0; i < ARRAY_SIZE(fc_##enum_name##_e2str_names); i++) {\ + if (fc_##enum_name##_e2str_names[i].value == table_key) {\ + name = fc_##enum_name##_e2str_names[i].name; \ + break; \ + } \ + } \ + return name; \ +} --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_attr.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -176,7 +176,6 @@ int i; int len = 0; char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0}; - unsigned long iflags = 0; if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) { len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n"); @@ -347,7 +346,6 @@ if (strlcat(buf, "\nNVME Initiator Enabled\n", PAGE_SIZE) >= PAGE_SIZE) goto buffer_done; - rcu_read_lock(); scnprintf(tmp, sizeof(tmp), "XRI Dist lpfc%d Total %d IO %d ELS %d\n", phba->brd_no, @@ -355,7 +353,7 @@ phba->sli4_hba.io_xri_max, lpfc_sli4_get_els_iocb_cnt(phba)); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto buffer_done; /* Port state is only one of two values for now. */ if (localport->port_id) @@ -371,15 +369,17 @@ wwn_to_u64(vport->fc_nodename.u.wwn), localport->port_id, statep); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto buffer_done; + + spin_lock_irq(shost->host_lock); list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { nrport = NULL; - spin_lock_irqsave(&vport->phba->hbalock, iflags); + spin_lock(&vport->phba->hbalock); rport = lpfc_ndlp_get_nrport(ndlp); if (rport) nrport = rport->remoteport; - spin_unlock_irqrestore(&vport->phba->hbalock, iflags); + spin_unlock(&vport->phba->hbalock); if (!nrport) continue; @@ -398,39 +398,39 @@ /* Tab in to show lport ownership. */ if (strlcat(buf, "NVME RPORT ", PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; if (phba->brd_no >= 10) { if (strlcat(buf, " ", PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } scnprintf(tmp, sizeof(tmp), "WWPN x%llx ", nrport->port_name); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; scnprintf(tmp, sizeof(tmp), "WWNN x%llx ", nrport->node_name); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; scnprintf(tmp, sizeof(tmp), "DID x%06x ", nrport->port_id); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; /* An NVME rport can have multiple roles. */ if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) { if (strlcat(buf, "INITIATOR ", PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) { if (strlcat(buf, "TARGET ", PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) { if (strlcat(buf, "DISCSRVC ", PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR | FC_PORT_ROLE_NVME_TARGET | @@ -438,14 +438,14 @@ scnprintf(tmp, sizeof(tmp), "UNKNOWN ROLE x%x", nrport->port_role); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } scnprintf(tmp, sizeof(tmp), "%s\n", statep); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) - goto rcu_unlock_buf_done; + goto unlock_buf_done; } - rcu_read_unlock(); + spin_unlock_irq(shost->host_lock); if (!lport) goto buffer_done; @@ -505,11 +505,11 @@ atomic_read(&lport->cmpl_fcp_err)); strlcat(buf, tmp, PAGE_SIZE); - /* RCU is already unlocked. */ + /* host_lock is already unlocked. */ goto buffer_done; - rcu_unlock_buf_done: - rcu_read_unlock(); + unlock_buf_done: + spin_unlock_irq(shost->host_lock); buffer_done: len = strnlen(buf, PAGE_SIZE); @@ -1145,6 +1145,9 @@ pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK; pmboxq->u.mb.mbxOwner = OWN_HOST; + if ((vport->fc_flag & FC_PT2PT) && (vport->fc_flag & FC_PT2PT_NO_NVME)) + vport->fc_flag &= ~FC_PT2PT_NO_NVME; + mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO * 2); if ((mbxstatus == MBX_SUCCESS) && @@ -1475,8 +1478,9 @@ int i; msleep(100); - lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, - &portstat_reg.word0); + if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, + &portstat_reg.word0)) + return -EIO; /* verify if privileged for the request operation */ if (!bf_get(lpfc_sliport_status_rn, &portstat_reg) && @@ -1486,8 +1490,9 @@ /* wait for the SLI port firmware ready after firmware reset */ for (i = 0; i < LPFC_FW_RESET_MAXIMUM_WAIT_10MS_CNT; i++) { msleep(10); - lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, - &portstat_reg.word0); + if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, + &portstat_reg.word0)) + continue; if (!bf_get(lpfc_sliport_status_err, &portstat_reg)) continue; if (!bf_get(lpfc_sliport_status_rn, &portstat_reg)) @@ -1537,25 +1542,25 @@ before_fc_flag = phba->pport->fc_flag; sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn; - /* Disable SR-IOV virtual functions if enabled */ - if (phba->cfg_sriov_nr_virtfn) { - pci_disable_sriov(pdev); - phba->cfg_sriov_nr_virtfn = 0; - } + if (opcode == LPFC_FW_DUMP) { + init_completion(&online_compl); + phba->fw_dump_cmpl = &online_compl; + } else { + /* Disable SR-IOV virtual functions if enabled */ + if (phba->cfg_sriov_nr_virtfn) { + pci_disable_sriov(pdev); + phba->cfg_sriov_nr_virtfn = 0; + } - if (opcode == LPFC_FW_DUMP) - phba->hba_flag |= HBA_FW_DUMP_OP; + status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); - status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); + if (status != 0) + return status; - if (status != 0) { - phba->hba_flag &= ~HBA_FW_DUMP_OP; - return status; + /* wait for the device to be quiesced before firmware reset */ + msleep(100); } - /* wait for the device to be quiesced before firmware reset */ - msleep(100); - reg_val = readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET); @@ -1584,24 +1589,42 @@ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "3153 Fail to perform the requested " "access: x%x\n", reg_val); + if (phba->fw_dump_cmpl) + phba->fw_dump_cmpl = NULL; return rc; } /* keep the original port state */ - if (before_fc_flag & FC_OFFLINE_MODE) - goto out; - - init_completion(&online_compl); - job_posted = lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_ONLINE); - if (!job_posted) + if (before_fc_flag & FC_OFFLINE_MODE) { + if (phba->fw_dump_cmpl) + phba->fw_dump_cmpl = NULL; goto out; + } - wait_for_completion(&online_compl); + /* Firmware dump will trigger an HA_ERATT event, and + * lpfc_handle_eratt_s4 routine already handles bringing the port back + * online. + */ + if (opcode == LPFC_FW_DUMP) { + wait_for_completion(phba->fw_dump_cmpl); + } else { + init_completion(&online_compl); + job_posted = lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_ONLINE); + if (!job_posted) + goto out; + wait_for_completion(&online_compl); + } out: /* in any case, restore the virtual functions enabled as before */ if (sriov_nr_virtfn) { + /* If fw_dump was performed, first disable to clean up */ + if (opcode == LPFC_FW_DUMP) { + pci_disable_sriov(pdev); + phba->cfg_sriov_nr_virtfn = 0; + } + sriov_err = lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn); if (!sriov_err) @@ -1642,7 +1665,7 @@ { LPFC_MBOXQ_t *mbox = NULL; unsigned long val = 0; - char *pval = 0; + char *pval = NULL; int rc = 0; if (!strncmp("enable", buff_out, @@ -1691,8 +1714,7 @@ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, "0071 Set trunk mode failed with status: %d", rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free(mbox, phba->mbox_mem_pool); return 0; } @@ -3533,6 +3555,31 @@ LPFC_ATTR_R(suppress_link_up, LPFC_INITIALIZE_LINK, LPFC_INITIALIZE_LINK, LPFC_DELAY_INIT_LINK_INDEFINITELY, "Suppress Link Up at initialization"); + +static ssize_t +lpfc_pls_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; + + return scnprintf(buf, PAGE_SIZE, "%d\n", + phba->sli4_hba.pc_sli4_params.pls); +} +static DEVICE_ATTR(pls, 0444, + lpfc_pls_show, NULL); + +static ssize_t +lpfc_pt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; + + return scnprintf(buf, PAGE_SIZE, "%d\n", + (phba->hba_flag & HBA_PERSISTENT_TOPO) ? 1 : 0); +} +static DEVICE_ATTR(pt, 0444, + lpfc_pt_show, NULL); + /* # lpfc_cnt: Number of IOCBs allocated for ELS, CT, and ABTS # 1 - (1024) @@ -3580,9 +3627,6 @@ static DEVICE_ATTR(txcmplq_hw, S_IRUGO, lpfc_txcmplq_hw_show, NULL); -LPFC_ATTR_R(iocb_cnt, 2, 1, 5, - "Number of IOCBs alloc for ELS, CT, and ABTS: 1k to 5k IOCBs"); - /* # lpfc_nodev_tmo: If set, it will hold all I/O errors on devices that disappear # until the timer expires. Value range is [0,255]. Default value is 30. @@ -3822,8 +3866,8 @@ * 3 - register both FCP and NVME * Supported values are [1,3]. Default value is 3 */ -LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_BOTH, - LPFC_ENABLE_FCP, LPFC_ENABLE_BOTH, +LPFC_ATTR_R(enable_fc4_type, LPFC_DEF_ENBL_FC4_TYPE, + LPFC_ENABLE_FCP, LPFC_MAX_ENBL_FC4_TYPE, "Enable FC4 Protocol support - FCP / NVME"); /* @@ -3845,9 +3889,6 @@ /* # lun_queue_depth: This parameter is used to limit the number of outstanding # commands per FCP LUN. Value range is [1,512]. Default value is 30. -# If this parameter value is greater than 1/8th the maximum number of exchanges -# supported by the HBA port, then the lun queue depth will be reduced to -# 1/8th the maximum number of exchanges. */ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512, "Max number of FCP commands we can queue to a specific LUN"); @@ -4096,8 +4137,16 @@ val); return -EINVAL; } - if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || - phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && + /* + * The 'topology' is not a configurable parameter if : + * - persistent topology enabled + * - G7/G6 with no private loop support + */ + + if ((phba->hba_flag & HBA_PERSISTENT_TOPO || + (!phba->sli4_hba.pc_sli4_params.pls && + (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || + phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC))) && val == 4) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "3114 Loop mode not supported\n"); @@ -5298,7 +5347,7 @@ len += scnprintf(buf + len, PAGE_SIZE - len, "CPU %02d not present\n", phba->sli4_hba.curr_disp_cpu); - else if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) { + else if (cpup->eq == LPFC_VECTOR_MAP_EMPTY) { if (cpup->hdwq == LPFC_VECTOR_MAP_EMPTY) len += scnprintf( buf + len, PAGE_SIZE - len, @@ -5311,10 +5360,10 @@ else len += scnprintf( buf + len, PAGE_SIZE - len, - "CPU %02d EQ %04d hdwq %04d " + "CPU %02d EQ None hdwq %04d " "physid %d coreid %d ht %d ua %d\n", phba->sli4_hba.curr_disp_cpu, - cpup->eq, cpup->hdwq, cpup->phys_id, + cpup->hdwq, cpup->phys_id, cpup->core_id, (cpup->flag & LPFC_CPU_MAP_HYPER), (cpup->flag & LPFC_CPU_MAP_UNASSIGN)); @@ -5329,7 +5378,7 @@ cpup->core_id, (cpup->flag & LPFC_CPU_MAP_HYPER), (cpup->flag & LPFC_CPU_MAP_UNASSIGN), - cpup->irq); + lpfc_get_irq(cpup->eq)); else len += scnprintf( buf + len, PAGE_SIZE - len, @@ -5340,7 +5389,7 @@ cpup->core_id, (cpup->flag & LPFC_CPU_MAP_HYPER), (cpup->flag & LPFC_CPU_MAP_UNASSIGN), - cpup->irq); + lpfc_get_irq(cpup->eq)); } phba->sli4_hba.curr_disp_cpu++; @@ -5711,7 +5760,7 @@ * the driver will advertise it supports to the SCSI layer. * * 0 = Set nr_hw_queues by the number of CPUs or HW queues. - * 1,128 = Manually specify the maximum nr_hw_queue value to be set, + * 1,256 = Manually specify nr_hw_queue value to be advertised, * * Value range is [0,256]. Default value is 8. */ @@ -5729,30 +5778,130 @@ * A hardware IO queue maps (qidx) to a specific driver CQ/WQ. * * 0 = Configure the number of hdw queues to the number of active CPUs. - * 1,128 = Manually specify how many hdw queues to use. + * 1,256 = Manually specify how many hdw queues to use. * - * Value range is [0,128]. Default value is 0. + * Value range is [0,256]. Default value is 0. */ LPFC_ATTR_R(hdw_queue, LPFC_HBA_HDWQ_DEF, LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX, "Set the number of I/O Hardware Queues"); +static inline void +lpfc_assign_default_irq_numa(struct lpfc_hba *phba) +{ +#if IS_ENABLED(CONFIG_X86) + /* If AMD architecture, then default is LPFC_IRQ_CHANN_NUMA */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) + phba->cfg_irq_numa = 1; + else + phba->cfg_irq_numa = 0; +#else + phba->cfg_irq_numa = 0; +#endif +} + /* * lpfc_irq_chann: Set the number of IRQ vectors that are available * for Hardware Queues to utilize. This also will map to the number * of EQ / MSI-X vectors the driver will create. This should never be * more than the number of Hardware Queues * - * 0 = Configure number of IRQ Channels to the number of active CPUs. - * 1,128 = Manually specify how many IRQ Channels to use. + * 0 = Configure number of IRQ Channels to: + * if AMD architecture, number of CPUs on HBA's NUMA node + * otherwise, number of active CPUs. + * [1,256] = Manually specify how many IRQ Channels to use. * - * Value range is [0,128]. Default value is 0. + * Value range is [0,256]. Default value is [0]. */ -LPFC_ATTR_R(irq_chann, - LPFC_HBA_HDWQ_DEF, - LPFC_HBA_HDWQ_MIN, LPFC_HBA_HDWQ_MAX, - "Set the number of I/O IRQ Channels"); +static uint lpfc_irq_chann = LPFC_IRQ_CHANN_DEF; +module_param(lpfc_irq_chann, uint, 0444); +MODULE_PARM_DESC(lpfc_irq_chann, "Set number of interrupt vectors to allocate"); + +/* lpfc_irq_chann_init - Set the hba irq_chann initial value + * @phba: lpfc_hba pointer. + * @val: contains the initial value + * + * Description: + * Validates the initial value is within range and assigns it to the + * adapter. If not in range, an error message is posted and the + * default value is assigned. + * + * Returns: + * zero if value is in range and is set + * -EINVAL if value was out of range + **/ +static int +lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val) +{ + const struct cpumask *numa_mask; + + if (phba->cfg_use_msi != 2) { + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "8532 use_msi = %u ignoring cfg_irq_numa\n", + phba->cfg_use_msi); + phba->cfg_irq_numa = 0; + phba->cfg_irq_chann = LPFC_IRQ_CHANN_MIN; + return 0; + } + + /* Check if default setting was passed */ + if (val == LPFC_IRQ_CHANN_DEF) + lpfc_assign_default_irq_numa(phba); + + if (phba->cfg_irq_numa) { + numa_mask = &phba->sli4_hba.numa_mask; + + if (cpumask_empty(numa_mask)) { + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "8533 Could not identify NUMA node, " + "ignoring cfg_irq_numa\n"); + phba->cfg_irq_numa = 0; + phba->cfg_irq_chann = LPFC_IRQ_CHANN_MIN; + } else { + phba->cfg_irq_chann = cpumask_weight(numa_mask); + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "8543 lpfc_irq_chann set to %u " + "(numa)\n", phba->cfg_irq_chann); + } + } else { + if (val > LPFC_IRQ_CHANN_MAX) { + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "8545 lpfc_irq_chann attribute cannot " + "be set to %u, allowed range is " + "[%u,%u]\n", + val, + LPFC_IRQ_CHANN_MIN, + LPFC_IRQ_CHANN_MAX); + phba->cfg_irq_chann = LPFC_IRQ_CHANN_MIN; + return -EINVAL; + } + phba->cfg_irq_chann = val; + } + + return 0; +} + +/** + * lpfc_irq_chann_show - Display value of irq_chann + * @dev: class converted to a Scsi_host structure. + * @attr: device attribute, not used. + * @buf: on return contains a string with the list sizes + * + * Returns: size of formatted string. + **/ +static ssize_t +lpfc_irq_chann_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; + struct lpfc_hba *phba = vport->phba; + + return scnprintf(buf, PAGE_SIZE, "%u\n", phba->cfg_irq_chann); +} + +static DEVICE_ATTR_RO(lpfc_irq_chann); /* # lpfc_enable_hba_reset: Allow or prevent HBA resets to the hardware. @@ -5882,7 +6031,8 @@ len = scnprintf(buf, PAGE_SIZE, "SGL sz: %d total SGEs: %d\n", phba->cfg_sg_dma_buf_size, phba->cfg_total_seg_cnt); - len += scnprintf(buf + len, PAGE_SIZE, "Cfg: %d SCSI: %d NVME: %d\n", + len += scnprintf(buf + len, PAGE_SIZE - len, + "Cfg: %d SCSI: %d NVME: %d\n", phba->cfg_sg_seg_cnt, phba->cfg_scsi_seg_cnt, phba->cfg_nvme_seg_cnt); return len; @@ -5933,7 +6083,53 @@ * [1-4] = Multiple of 1/4th Mb of host memory for FW logging * Value range [0..4]. Default value is 0 */ -LPFC_ATTR_RW(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging"); +LPFC_ATTR(ras_fwlog_buffsize, 0, 0, 4, "Host memory for FW logging"); +lpfc_param_show(ras_fwlog_buffsize); + +static ssize_t +lpfc_ras_fwlog_buffsize_set(struct lpfc_hba *phba, uint val) +{ + int ret = 0; + enum ras_state state; + + if (!lpfc_rangecheck(val, 0, 4)) + return -EINVAL; + + if (phba->cfg_ras_fwlog_buffsize == val) + return 0; + + if (phba->cfg_ras_fwlog_func != PCI_FUNC(phba->pcidev->devfn)) + return -EINVAL; + + spin_lock_irq(&phba->hbalock); + state = phba->ras_fwlog.state; + spin_unlock_irq(&phba->hbalock); + + if (state == REG_INPROGRESS) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "6147 RAS Logging " + "registration is in progress\n"); + return -EBUSY; + } + + /* For disable logging: stop the logs and free the DMA. + * For ras_fwlog_buffsize size change we still need to free and + * reallocate the DMA in lpfc_sli4_ras_fwlog_init. + */ + phba->cfg_ras_fwlog_buffsize = val; + if (state == ACTIVE) { + lpfc_ras_stop_fwlog(phba); + lpfc_sli4_ras_dma_free(phba); + } + + lpfc_sli4_ras_init(phba); + if (phba->ras_fwlog.ras_enabled) + ret = lpfc_sli4_ras_fwlog_init(phba, phba->cfg_ras_fwlog_level, + LPFC_RAS_ENABLE_LOGGING); + return ret; +} + +lpfc_param_store(ras_fwlog_buffsize); +static DEVICE_ATTR_RW(lpfc_ras_fwlog_buffsize); /* * lpfc_ras_fwlog_level: Firmware logging verbosity level @@ -6071,8 +6267,9 @@ &dev_attr_lpfc_sriov_nr_virtfn, &dev_attr_lpfc_req_fw_upgrade, &dev_attr_lpfc_suppress_link_up, - &dev_attr_lpfc_iocb_cnt, &dev_attr_iocb_hw, + &dev_attr_pls, + &dev_attr_pt, &dev_attr_txq_hw, &dev_attr_txcmplq_hw, &dev_attr_lpfc_fips_level, @@ -6608,15 +6805,19 @@ pmboxq->ctx_buf = NULL; pmboxq->vport = vport; - if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } } memset(hs, 0, sizeof (struct fc_host_statistics)); @@ -6640,15 +6841,19 @@ pmboxq->ctx_buf = NULL; pmboxq->vport = vport; - if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } } hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; @@ -6721,15 +6926,19 @@ pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return; + return; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } } memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); @@ -6739,15 +6948,19 @@ pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else + if (rc != MBX_SUCCESS) { + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } + } else { rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) - mempool_free( pmboxq, phba->mbox_mem_pool); - return; + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } } lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; @@ -7085,11 +7298,22 @@ static void lpfc_get_hba_function_mode(struct lpfc_hba *phba) { - /* If it's a SkyHawk FCoE adapter */ - if (phba->pcidev->device == PCI_DEVICE_ID_SKYHAWK) + /* If the adapter supports FCoE mode */ + switch (phba->pcidev->device) { + case PCI_DEVICE_ID_SKYHAWK: + case PCI_DEVICE_ID_SKYHAWK_VF: + case PCI_DEVICE_ID_LANCER_FCOE: + case PCI_DEVICE_ID_LANCER_FCOE_VF: + case PCI_DEVICE_ID_ZEPHYR_DCSP: + case PCI_DEVICE_ID_HORNET: + case PCI_DEVICE_ID_TIGERSHARK: + case PCI_DEVICE_ID_TOMCAT: phba->hba_flag |= HBA_FCOE_MODE; - else + break; + default: + /* for others, clear the flag */ phba->hba_flag &= ~HBA_FCOE_MODE; + } } /** @@ -7099,6 +7323,7 @@ void lpfc_get_cfgparam(struct lpfc_hba *phba) { + lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); lpfc_fcp_io_sched_init(phba, lpfc_fcp_io_sched); lpfc_ns_query_init(phba, lpfc_ns_query); lpfc_fcp2_no_tgt_reset_init(phba, lpfc_fcp2_no_tgt_reset); @@ -7205,12 +7430,10 @@ phba->cfg_soft_wwpn = 0L; lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); - lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); lpfc_aer_support_init(phba, lpfc_aer_support); lpfc_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn); lpfc_request_firmware_upgrade_init(phba, lpfc_req_fw_upgrade); lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up); - lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt); lpfc_delay_discovery_init(phba, lpfc_delay_discovery); lpfc_sli_mode_init(phba, lpfc_sli_mode); phba->cfg_enable_dss = 1; @@ -7256,11 +7479,11 @@ } if (!phba->cfg_nvmet_mrq) - phba->cfg_nvmet_mrq = phba->cfg_irq_chann; + phba->cfg_nvmet_mrq = phba->cfg_hdw_queue; /* Adjust lpfc_nvmet_mrq to avoid running out of WQE slots */ - if (phba->cfg_nvmet_mrq > phba->cfg_irq_chann) { - phba->cfg_nvmet_mrq = phba->cfg_irq_chann; + if (phba->cfg_nvmet_mrq > phba->cfg_hdw_queue) { + phba->cfg_nvmet_mrq = phba->cfg_hdw_queue; lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC, "6018 Adjust lpfc_nvmet_mrq to %d\n", phba->cfg_nvmet_mrq); --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_bsg.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_bsg.c @@ -4489,12 +4489,6 @@ phba->mbox_ext_buf_ctx.seqNum++; nemb_tp = phba->mbox_ext_buf_ctx.nembType; - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); - if (!dd_data) { - rc = -ENOMEM; - goto job_error; - } - pbuf = (uint8_t *)dmabuf->virt; size = job->request_payload.payload_len; sg_copy_to_buffer(job->request_payload.sg_list, @@ -4531,6 +4525,13 @@ "2968 SLI_CONFIG ext-buffer wr all %d " "ebuffers received\n", phba->mbox_ext_buf_ctx.numBuf); + + dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + if (!dd_data) { + rc = -ENOMEM; + goto job_error; + } + /* mailbox command structure for base driver */ pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) { @@ -4579,6 +4580,8 @@ return SLI_CONFIG_HANDLED; job_error: + if (pmboxq) + mempool_free(pmboxq, phba->mbox_mem_pool); lpfc_bsg_dma_page_free(phba, dmabuf); kfree(dd_data); @@ -5435,10 +5438,12 @@ bsg_reply->reply_data.vendor_reply.vendor_rsp; /* Current logging state */ - if (ras_fwlog->ras_active == true) + spin_lock_irq(&phba->hbalock); + if (ras_fwlog->state == ACTIVE) ras_reply->state = LPFC_RASLOG_STATE_RUNNING; else ras_reply->state = LPFC_RASLOG_STATE_STOPPED; + spin_unlock_irq(&phba->hbalock); ras_reply->log_level = phba->ras_fwlog.fw_loglevel; ras_reply->log_buff_sz = phba->cfg_ras_fwlog_buffsize; @@ -5495,10 +5500,13 @@ if (action == LPFC_RASACTION_STOP_LOGGING) { /* Check if already disabled */ - if (ras_fwlog->ras_active == false) { + spin_lock_irq(&phba->hbalock); + if (ras_fwlog->state != ACTIVE) { + spin_unlock_irq(&phba->hbalock); rc = -ESRCH; goto ras_job_error; } + spin_unlock_irq(&phba->hbalock); /* Disable logging */ lpfc_ras_stop_fwlog(phba); @@ -5509,8 +5517,10 @@ * FW-logging with new log-level. Return status * "Logging already Running" to caller. **/ - if (ras_fwlog->ras_active) + spin_lock_irq(&phba->hbalock); + if (ras_fwlog->state != INACTIVE) action_status = -EINPROGRESS; + spin_unlock_irq(&phba->hbalock); /* Enable logging */ rc = lpfc_sli4_ras_fwlog_init(phba, log_level, @@ -5626,10 +5636,13 @@ goto ras_job_error; /* Logging to be stopped before reading */ - if (ras_fwlog->ras_active == true) { + spin_lock_irq(&phba->hbalock); + if (ras_fwlog->state == ACTIVE) { + spin_unlock_irq(&phba->hbalock); rc = -EINPROGRESS; goto ras_job_error; } + spin_unlock_irq(&phba->hbalock); if (job->request_len < sizeof(struct fc_bsg_request) + --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_crtn.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_crtn.h @@ -56,9 +56,6 @@ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *); -void lpfc_supported_pages(struct lpfcMboxq *); -void lpfc_pc_sli4_params(struct lpfcMboxq *); -int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *, uint16_t, uint16_t, bool); int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -140,9 +137,10 @@ int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *); -int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); +int lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry); int lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry); int lpfc_issue_fabric_reglogin(struct lpfc_vport *); +int lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry); int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, @@ -180,7 +178,7 @@ int lpfc_get_gidft_type(struct lpfc_vport *vport, struct lpfc_iocbq *iocbq); int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int, uint32_t); -void lpfc_fdmi_num_disc_check(struct lpfc_vport *); +void lpfc_fdmi_change_check(struct lpfc_vport *vport); void lpfc_delayed_disc_tmo(struct timer_list *); void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); @@ -215,6 +213,12 @@ irqreturn_t lpfc_sli4_intr_handler(int, void *); irqreturn_t lpfc_sli4_hba_intr_handler(int, void *); +void lpfc_sli4_cleanup_poll_list(struct lpfc_hba *phba); +int lpfc_sli4_poll_eq(struct lpfc_queue *q, uint8_t path); +void lpfc_sli4_poll_hbtimer(struct timer_list *t); +void lpfc_sli4_start_polling(struct lpfc_queue *q); +void lpfc_sli4_stop_polling(struct lpfc_queue *q); + void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_sli4_swap_str(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *); @@ -586,6 +590,7 @@ void lpfc_nvme_cmd_template(void); void lpfc_nvmet_cmd_template(void); void lpfc_nvme_cancel_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn); +void lpfc_nvme_prep_abort_wqe(struct lpfc_iocbq *pwqeq, u16 xritag, u8 opt); extern int lpfc_enable_nvmet_cnt; extern unsigned long long lpfc_enable_nvmet[]; extern int lpfc_no_hba_reset_cnt; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_ct.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -462,7 +462,6 @@ struct lpfc_nodelist *ndlp; if ((vport->port_type != LPFC_NPIV_PORT) || - (fc4_type == FC_TYPE_FCP) || !(vport->ct_flags & FC_CT_RFF_ID) || !vport->cfg_restrict_login) { ndlp = lpfc_setup_disc_node(vport, Did); @@ -763,9 +762,11 @@ cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0208 NameServer Rsp Data: x%x x%x " - "sz x%x\n", + "x%x x%x sz x%x\n", vport->fc_flag, CTreq->un.gid.Fc4Type, + vport->num_disc_nodes, + vport->gidft_inp, irsp->un.genreq64.bdl.bdeSize); lpfc_ns_rsp(vport, @@ -961,9 +962,13 @@ if (CTrsp->CommandResponse.bits.CmdRsp == cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "4105 NameServer Rsp Data: x%x x%x\n", + "4105 NameServer Rsp Data: x%x x%x " + "x%x x%x sz x%x\n", vport->fc_flag, - CTreq->un.gid.Fc4Type); + CTreq->un.gid.Fc4Type, + vport->num_disc_nodes, + vport->gidft_inp, + irsp->un.genreq64.bdl.bdeSize); lpfc_ns_rsp(vport, outp, @@ -1025,6 +1030,11 @@ } vport->gidft_inp--; } + + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6450 GID_PT cmpl inp %d disc %d\n", + vport->gidft_inp, vport->num_disc_nodes); + /* Link up / RSCN discovery */ if ((vport->num_disc_nodes == 0) && (vport->gidft_inp == 0)) { @@ -1159,6 +1169,11 @@ /* Link up / RSCN discovery */ if (vport->num_disc_nodes) vport->num_disc_nodes--; + + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6451 GFF_ID cmpl inp %d disc %d\n", + vport->gidft_inp, vport->num_disc_nodes); + if (vport->num_disc_nodes == 0) { /* * The driver has cycled through all Nports in the RSCN payload. @@ -1477,33 +1492,35 @@ lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol, size_t size) { - char fwrev[FW_REV_STR_SIZE]; - int n; + char fwrev[FW_REV_STR_SIZE] = {0}; + char tmp[MAXHOSTNAMELEN] = {0}; - lpfc_decode_firmware_rev(vport->phba, fwrev, 0); + memset(symbol, 0, size); + + scnprintf(tmp, sizeof(tmp), "Emulex %s", vport->phba->ModelName); + if (strlcat(symbol, tmp, size) >= size) + goto buffer_done; - n = scnprintf(symbol, size, "Emulex %s", vport->phba->ModelName); - if (size < n) - return n; - - n += scnprintf(symbol + n, size - n, " FV%s", fwrev); - if (size < n) - return n; - - n += scnprintf(symbol + n, size - n, " DV%s.", - lpfc_release_version); - if (size < n) - return n; - - n += scnprintf(symbol + n, size - n, " HN:%s.", - init_utsname()->nodename); - if (size < n) - return n; + lpfc_decode_firmware_rev(vport->phba, fwrev, 0); + scnprintf(tmp, sizeof(tmp), " FV%s", fwrev); + if (strlcat(symbol, tmp, size) >= size) + goto buffer_done; + + scnprintf(tmp, sizeof(tmp), " DV%s", lpfc_release_version); + if (strlcat(symbol, tmp, size) >= size) + goto buffer_done; + + scnprintf(tmp, sizeof(tmp), " HN:%s", vport->phba->os_host_name); + if (strlcat(symbol, tmp, size) >= size) + goto buffer_done; /* Note :- OS name is "Linux" */ - n += scnprintf(symbol + n, size - n, " OS:%s", - init_utsname()->sysname); - return n; + scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname); + strlcat(symbol, tmp, size); + +buffer_done: + return strnlen(symbol, size); + } static uint32_t @@ -1868,6 +1885,12 @@ if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) { case IOERR_SLI_ABORTED: + case IOERR_SLI_DOWN: + /* Driver aborted this IO. No retry as error + * is likely Offline->Online or some adapter + * error. Recovery will try again. + */ + break; case IOERR_ABORT_IN_PROGRESS: case IOERR_SEQUENCE_TIMEOUT: case IOERR_ILLEGAL_FRAME: @@ -1976,14 +1999,16 @@ /** - * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to + * lpfc_fdmi_change_check - Check for changed FDMI parameters * @vport: pointer to a host virtual N_Port data structure. * - * Called from hbeat timeout routine to check if the number of discovered - * ports has changed. If so, re-register thar port Attribute. + * Check how many mapped NPorts we are connected to + * Check if our hostname changed + * Called from hbeat timeout routine to check if any FDMI parameters + * changed. If so, re-register those Attributes. */ void -lpfc_fdmi_num_disc_check(struct lpfc_vport *vport) +lpfc_fdmi_change_check(struct lpfc_vport *vport) { struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; @@ -1996,17 +2021,41 @@ if (!(vport->fc_flag & FC_FABRIC)) return; + ndlp = lpfc_findnode_did(vport, FDMI_DID); + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) + return; + + /* Check if system hostname changed */ + if (strcmp(phba->os_host_name, init_utsname()->nodename)) { + memset(phba->os_host_name, 0, sizeof(phba->os_host_name)); + scnprintf(phba->os_host_name, sizeof(phba->os_host_name), "%s", + init_utsname()->nodename); + lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0); + + /* Since this effects multiple HBA and PORT attributes, we need + * de-register and go thru the whole FDMI registration cycle. + * DHBA -> DPRT -> RHBA -> RPA (physical port) + * DPRT -> RPRT (vports) + */ + if (vport->port_type == LPFC_PHYSICAL_PORT) + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); + else + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + + /* Since this code path registers all the port attributes + * we can just return without further checking. + */ + return; + } + if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc)) return; + /* Check if the number of mapped NPorts changed */ cnt = lpfc_find_map_node(vport); if (cnt == vport->fdmi_num_disc) return; - ndlp = lpfc_findnode_did(vport, FDMI_DID); - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) - return; - if (vport->port_type == LPFC_PHYSICAL_PORT) { lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, LPFC_FDMI_PORT_ATTR_num_disc); @@ -2023,8 +2072,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, sizeof(struct lpfc_name)); @@ -2040,8 +2089,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); /* This string MUST be consistent with other FC platforms * supported by Broadcom. @@ -2065,8 +2114,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, phba->SerialNumber, sizeof(ae->un.AttrString)); @@ -2087,8 +2136,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, phba->ModelName, sizeof(ae->un.AttrString)); @@ -2108,8 +2157,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, phba->ModelDesc, sizeof(ae->un.AttrString)); @@ -2131,8 +2180,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t i, j, incr, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); /* Convert JEDEC ID to ascii for hardware version */ incr = vp->rev.biuRev; @@ -2161,8 +2210,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, lpfc_release_version, sizeof(ae->un.AttrString)); @@ -2183,8 +2232,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); if (phba->sli_rev == LPFC_SLI_REV4) lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); @@ -2208,8 +2257,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); len = strnlen(ae->un.AttrString, @@ -2228,8 +2277,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", init_utsname()->sysname, @@ -2251,7 +2300,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); size = FOURBYTES + sizeof(uint32_t); @@ -2267,8 +2316,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); len = lpfc_vport_symbolic_node_name(vport, ae->un.AttrString, 256); @@ -2286,7 +2335,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; /* Nothing is defined for this currently */ ae->un.AttrInt = cpu_to_be32(0); @@ -2303,7 +2352,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; /* Each driver instance corresponds to a single port */ ae->un.AttrInt = cpu_to_be32(1); @@ -2320,8 +2369,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, sizeof(struct lpfc_name)); @@ -2339,8 +2388,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strlcat(ae->un.AttrString, phba->BIOSVersion, sizeof(ae->un.AttrString)); @@ -2360,7 +2409,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; /* Driver doesn't have access to this information */ ae->un.AttrInt = cpu_to_be32(0); @@ -2377,8 +2426,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, "EMULEX", sizeof(ae->un.AttrString)); @@ -2400,10 +2449,9 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 32); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); - ae->un.AttrTypes[3] = 0x02; /* Type 0x1 - ELS */ ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ @@ -2426,7 +2474,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = 0; if (!(phba->hba_flag & HBA_FCOE_MODE)) { @@ -2480,7 +2528,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; if (!(phba->hba_flag & HBA_FCOE_MODE)) { switch (phba->fc_linkspeed) { @@ -2550,7 +2598,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; hsp = (struct serv_parm *)&vport->fc_sparam; ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) | @@ -2570,8 +2618,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "/sys/class/scsi_host/host%d", shost->host_no); @@ -2591,11 +2639,11 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); - snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", - init_utsname()->nodename); + scnprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", + vport->phba->os_host_name); len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); len += (len & 3) ? (4 - (len & 3)) : 4; @@ -2612,8 +2660,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, sizeof(struct lpfc_name)); @@ -2630,8 +2678,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, sizeof(struct lpfc_name)); @@ -2648,8 +2696,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); len += (len & 3) ? (4 - (len & 3)) : 4; @@ -2667,7 +2715,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); else @@ -2685,7 +2733,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -2700,8 +2748,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, sizeof(struct lpfc_name)); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrWWN, &vport->fabric_portname, sizeof(struct lpfc_name)); @@ -2718,10 +2766,9 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 32); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); - ae->un.AttrTypes[3] = 0x02; /* Type 0x1 - ELS */ ae->un.AttrTypes[2] = 0x01; /* Type 0x8 - FCP */ ae->un.AttrTypes[7] = 0x01; /* Type 0x20 - CT */ @@ -2742,7 +2789,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; /* Link Up - operational */ ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); size = FOURBYTES + sizeof(uint32_t); @@ -2758,7 +2805,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; vport->fdmi_num_disc = lpfc_find_map_node(vport); ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); size = FOURBYTES + sizeof(uint32_t); @@ -2774,7 +2821,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -2789,8 +2836,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, "Smart SAN Initiator", sizeof(ae->un.AttrString)); @@ -2810,8 +2857,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, sizeof(struct lpfc_name)); @@ -2831,8 +2878,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, "Smart SAN Version 2.0", sizeof(ae->un.AttrString)); @@ -2853,8 +2900,8 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t len, size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; - memset(ae, 0, 256); + ae = &ad->AttrValue; + memset(ae, 0, sizeof(*ae)); strncpy(ae->un.AttrString, phba->ModelName, sizeof(ae->un.AttrString)); @@ -2873,7 +2920,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; /* SRIOV (type 3) is not supported */ if (vport->vpi) @@ -2893,7 +2940,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = cpu_to_be32(0); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -2908,7 +2955,7 @@ struct lpfc_fdmi_attr_entry *ae; uint32_t size; - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; + ae = &ad->AttrValue; ae->un.AttrInt = cpu_to_be32(1); size = FOURBYTES + sizeof(uint32_t); ad->AttrLen = cpu_to_be16(size); @@ -3056,7 +3103,8 @@ /* Registered Port List */ /* One entry (port) per adapter */ rh->rpl.EntryCnt = cpu_to_be32(1); - memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName, + memcpy(&rh->rpl.pe.PortName, + &phba->pport->fc_sparam.portName, sizeof(struct lpfc_name)); /* point to the HBA attribute block */ --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_debugfs.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -2046,6 +2047,7 @@ char mybuf[64]; char *pbuf; int i; + size_t bsize; /* Protect copy from user */ if (!access_ok(buf, nbytes)) @@ -2053,7 +2055,9 @@ memset(mybuf, 0, sizeof(mybuf)); - if (copy_from_user(mybuf, buf, nbytes)) + bsize = min(nbytes, (sizeof(mybuf) - 1)); + + if (copy_from_user(mybuf, buf, bsize)) return -EFAULT; pbuf = &mybuf[0]; @@ -2074,10 +2078,107 @@ qp->lock_conflict.wq_access = 0; } } - return nbytes; + return bsize; } #endif +static int lpfc_debugfs_ras_log_data(struct lpfc_hba *phba, + char *buffer, int size) +{ + int copied = 0; + struct lpfc_dmabuf *dmabuf, *next; + + memset(buffer, 0, size); + + spin_lock_irq(&phba->hbalock); + if (phba->ras_fwlog.state != ACTIVE) { + spin_unlock_irq(&phba->hbalock); + return -EINVAL; + } + spin_unlock_irq(&phba->hbalock); + + list_for_each_entry_safe(dmabuf, next, + &phba->ras_fwlog.fwlog_buff_list, list) { + /* Check if copying will go over size and a '\0' char */ + if ((copied + LPFC_RAS_MAX_ENTRY_SIZE) >= (size - 1)) { + memcpy(buffer + copied, dmabuf->virt, + size - copied - 1); + copied += size - copied - 1; + break; + } + memcpy(buffer + copied, dmabuf->virt, LPFC_RAS_MAX_ENTRY_SIZE); + copied += LPFC_RAS_MAX_ENTRY_SIZE; + } + return copied; +} + +static int +lpfc_debugfs_ras_log_release(struct inode *inode, struct file *file) +{ + struct lpfc_debug *debug = file->private_data; + + vfree(debug->buffer); + kfree(debug); + + return 0; +} + +/** + * lpfc_debugfs_ras_log_open - Open the RAS log debugfs buffer + * @inode: The inode pointer that contains a vport pointer. + * @file: The file pointer to attach the log output. + * + * Description: + * This routine is the entry point for the debugfs open file operation. It gets + * the vport from the i_private field in @inode, allocates the necessary buffer + * for the log, fills the buffer from the in-memory log for this vport, and then + * returns a pointer to that log in the private_data field in @file. + * + * Returns: + * This function returns zero if successful. On error it will return a negative + * error value. + **/ +static int +lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file) +{ + struct lpfc_hba *phba = inode->i_private; + struct lpfc_debug *debug; + int size; + int rc = -ENOMEM; + + spin_lock_irq(&phba->hbalock); + if (phba->ras_fwlog.state != ACTIVE) { + spin_unlock_irq(&phba->hbalock); + rc = -EINVAL; + goto out; + } + spin_unlock_irq(&phba->hbalock); + debug = kmalloc(sizeof(*debug), GFP_KERNEL); + if (!debug) + goto out; + + size = LPFC_RAS_MIN_BUFF_POST_SIZE * phba->cfg_ras_fwlog_buffsize; + debug->buffer = vmalloc(size); + if (!debug->buffer) + goto free_debug; + + debug->len = lpfc_debugfs_ras_log_data(phba, debug->buffer, size); + if (debug->len < 0) { + rc = -EINVAL; + goto free_buffer; + } + file->private_data = debug; + + return 0; + +free_buffer: + vfree(debug->buffer); +free_debug: + kfree(debug); +out: + return rc; +} + /** * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer * @inode: The inode pointer that contains a vport pointer. @@ -2217,7 +2318,7 @@ memset(dstbuf, 0, 33); size = (nbytes < 32) ? nbytes : 32; if (copy_from_user(dstbuf, buf, size)) - return 0; + return -EFAULT; if (dent == phba->debug_InjErrLBA) { if ((buf[0] == 'o') && (buf[1] == 'f') && (buf[2] == 'f')) @@ -2225,7 +2326,7 @@ } if ((tmp == 0) && (kstrtoull(dstbuf, 0, &tmp))) - return 0; + return -EINVAL; if (dent == phba->debug_writeGuard) phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; @@ -2402,8 +2503,8 @@ struct lpfc_sli4_hdw_queue *qp; struct lpfc_multixri_pool *multixri_pool; - if (nbytes > 64) - nbytes = 64; + if (nbytes > sizeof(mybuf) - 1) + nbytes = sizeof(mybuf) - 1; /* Protect copy from user */ if (!access_ok(buf, nbytes)) @@ -2487,8 +2588,8 @@ if (!phba->targetport) return -ENXIO; - if (nbytes > 64) - nbytes = 64; + if (nbytes > sizeof(mybuf) - 1) + nbytes = sizeof(mybuf) - 1; memset(mybuf, 0, sizeof(mybuf)); @@ -2629,8 +2730,8 @@ char mybuf[64]; char *pbuf; - if (nbytes > 64) - nbytes = 64; + if (nbytes > sizeof(mybuf) - 1) + nbytes = sizeof(mybuf) - 1; memset(mybuf, 0, sizeof(mybuf)); @@ -2757,8 +2858,8 @@ char mybuf[64]; char *pbuf; - if (nbytes > 64) - nbytes = 64; + if (nbytes > sizeof(mybuf) - 1) + nbytes = sizeof(mybuf) - 1; memset(mybuf, 0, sizeof(mybuf)); @@ -2863,8 +2964,8 @@ char *pbuf; int i, j; - if (nbytes > 64) - nbytes = 64; + if (nbytes > sizeof(mybuf) - 1) + nbytes = sizeof(mybuf) - 1; memset(mybuf, 0, sizeof(mybuf)); @@ -5286,6 +5387,16 @@ }; #endif +#undef lpfc_debugfs_ras_log +static const struct file_operations lpfc_debugfs_ras_log = { + .owner = THIS_MODULE, + .open = lpfc_debugfs_ras_log_open, + .llseek = lpfc_debugfs_lseek, + .read = lpfc_debugfs_read, + .release = lpfc_debugfs_ras_log_release, +}; +#endif + #undef lpfc_debugfs_op_dumpHBASlim static const struct file_operations lpfc_debugfs_op_dumpHBASlim = { .owner = THIS_MODULE, @@ -5457,7 +5568,6 @@ .release = lpfc_idiag_cmd_release, }; -#endif /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command * @phba: Pointer to HBA context object. @@ -5707,6 +5817,19 @@ goto debug_failed; } + /* RAS log */ + snprintf(name, sizeof(name), "ras_log"); + phba->debug_ras_log = + debugfs_create_file(name, 0644, + phba->hba_debugfs_root, + phba, &lpfc_debugfs_ras_log); + if (!phba->debug_ras_log) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, + "6148 Cannot create debugfs" + " ras_log\n"); + goto debug_failed; + } + /* Setup hbqinfo */ snprintf(name, sizeof(name), "hbqinfo"); phba->debug_hbqinfo = @@ -6117,6 +6240,9 @@ debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ phba->debug_hbqinfo = NULL; + debugfs_remove(phba->debug_ras_log); + phba->debug_ras_log = NULL; + #ifdef LPFC_HDWQ_LOCK_STAT debugfs_remove(phba->debug_lockstat); /* lockstat */ phba->debug_lockstat = NULL; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_els.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -1066,7 +1066,8 @@ /* FLOGI failed, so there is no fabric */ spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); + vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP | + FC_PT2PT_NO_NVME); spin_unlock_irq(shost->host_lock); /* If private loop, then allow max outstanding els to be @@ -1179,6 +1180,15 @@ phba->fcf.fcf_redisc_attempted = 0; /* reset */ goto out; } + } else if (vport->port_state > LPFC_FLOGI && + vport->fc_flag & FC_PT2PT) { + /* + * In a p2p topology, it is possible that discovery has + * already progressed, and this completion can be ignored. + * Recheck the indicated topology. + */ + if (!sp->cmn.fPort) + goto out; } flogifail: @@ -2236,6 +2246,7 @@ struct Scsi_Host *shost = lpfc_shost_from_vport(vport); IOCB_t *irsp; struct lpfc_nodelist *ndlp; + char *mode; /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; @@ -2273,8 +2284,17 @@ goto out; } + /* If we don't send GFT_ID to Fabric, a PRLI error + * could be expected. + */ + if ((vport->fc_flag & FC_FABRIC) || + (vport->cfg_enable_fc4_type != LPFC_ENABLE_BOTH)) + mode = KERN_ERR; + else + mode = KERN_INFO; + /* PRLI failed */ - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + lpfc_printf_vlog(vport, mode, LOG_ELS, "2754 PRLI failure DID:%06X Status:x%x/x%x, " "data: x%x\n", ndlp->nlp_DID, irsp->ulpStatus, @@ -2998,10 +3018,9 @@ * This routine is a generic completion callback function for ELS commands. * Specifically, it is the callback function which does not need to perform * any command specific operations. It is currently used by the ELS command - * issuing routines for the ELS State Change Request (SCR), - * lpfc_issue_els_scr(), and the ELS Fibre Channel Address Resolution - * Protocol Response (FARPR) routine, lpfc_issue_els_farpr(). Other than - * certain debug loggings, this callback function simply invokes the + * issuing routines for RSCN, lpfc_issue_els_rscn, and the ELS Fibre Channel + * Address Resolution Protocol Response (FARPR) routine, lpfc_issue_els_farpr(). + * Other than certain debug loggings, this callback function simply invokes the * lpfc_els_chk_latt() routine to check whether link went down during the * discovery process. **/ @@ -3015,14 +3034,117 @@ irsp = &rspiocb->iocb; lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, + "ELS cmd cmpl: status:x%x/x%x did:x%x", + irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->un.elsreq64.remoteID); + + /* ELS cmd tag completes */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n", + irsp->ulpIoTag, irsp->ulpStatus, + irsp->un.ulpWord[4], irsp->ulpTimeout); + + /* Check to see if link went down during discovery */ + lpfc_els_chk_latt(vport); + lpfc_els_free_iocb(phba, cmdiocb); +} + +/** + * lpfc_cmpl_els_disc_cmd - Completion callback function for Discovery ELS cmd + * @phba: pointer to lpfc hba data structure. + * @cmdiocb: pointer to lpfc command iocb data structure. + * @rspiocb: pointer to lpfc response iocb data structure. + * + * This routine is a generic completion callback function for Discovery ELS cmd. + * Currently used by the ELS command issuing routines for the ELS State Change + * Request (SCR), lpfc_issue_els_scr() and the ELS RDF, lpfc_issue_els_rdf(). + * These commands will be retried once only for ELS timeout errors. + **/ +static void +lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb) +{ + struct lpfc_vport *vport = cmdiocb->vport; + IOCB_t *irsp; + struct lpfc_els_rdf_rsp *prdf; + struct lpfc_dmabuf *pcmd, *prsp; + u32 *pdata; + u32 cmd; + + irsp = &rspiocb->iocb; + + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "ELS cmd cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.elsreq64.remoteID); /* ELS cmd tag completes */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n", + "0217 ELS cmd tag x%x completes Data: x%x x%x x%x " + "x%x\n", irsp->ulpIoTag, irsp->ulpStatus, - irsp->un.ulpWord[4], irsp->ulpTimeout); + irsp->un.ulpWord[4], irsp->ulpTimeout, + cmdiocb->retry); + + pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; + if (!pcmd) + goto out; + + pdata = (u32 *)pcmd->virt; + if (!pdata) + goto out; + cmd = *pdata; + + /* Only 1 retry for ELS Timeout only */ + if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT && + ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) == + IOERR_SEQUENCE_TIMEOUT)) { + cmdiocb->retry++; + if (cmdiocb->retry <= 1) { + switch (cmd) { + case ELS_CMD_SCR: + lpfc_issue_els_scr(vport, cmdiocb->retry); + break; + case ELS_CMD_RDF: + cmdiocb->context1 = NULL; /* save ndlp refcnt */ + lpfc_issue_els_rdf(vport, cmdiocb->retry); + break; + } + goto out; + } + phba->fc_stat.elsRetryExceeded++; + } + if (irsp->ulpStatus) { + /* ELS discovery cmd completes with error */ + lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS, + "4203 ELS cmd x%x error: x%x x%X\n", cmd, + irsp->ulpStatus, irsp->un.ulpWord[4]); + goto out; + } + + /* The RDF response doesn't have any impact on the running driver + * but the notification descriptors are dumped here for support. + */ + if (cmd == ELS_CMD_RDF) { + int i; + + prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); + if (!prsp) + goto out; + + prdf = (struct lpfc_els_rdf_rsp *)prsp->virt; + if (!prdf) + goto out; + + for (i = 0; i < ELS_RDF_REG_TAG_CNT && + i < be32_to_cpu(prdf->reg_d1.reg_desc.count); i++) + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "4677 Fabric RDF Notication Grant Data: " + "0x%08x\n", + be32_to_cpu( + prdf->reg_d1.desc_tags[i])); + } + +out: /* Check to see if link went down during discovery */ lpfc_els_chk_latt(vport); lpfc_els_free_iocb(phba, cmdiocb); @@ -3032,11 +3154,10 @@ /** * lpfc_issue_els_scr - Issue a scr to an node on a vport * @vport: pointer to a host virtual N_Port data structure. - * @nportid: N_Port identifier to the remote node. - * @retry: number of retries to the command IOCB. + * @retry: retry counter for the command IOCB. * * This routine issues a State Change Request (SCR) to a fabric node - * on a @vport. The remote node @nportid is passed into the function. It + * on a @vport. The remote node is Fabric Controller (0xfffffd). It * first search the @vport node list to find the matching ndlp. If no such * ndlp is found, a new ndlp shall be created for this (SCR) purpose. An * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb() @@ -3052,7 +3173,7 @@ * 1 - Failed to issue scr command **/ int -lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) +lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry) { struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *elsiocb; @@ -3062,9 +3183,9 @@ cmdsize = (sizeof(uint32_t) + sizeof(SCR)); - ndlp = lpfc_findnode_did(vport, nportid); + ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID); if (!ndlp) { - ndlp = lpfc_nlp_init(vport, nportid); + ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID); if (!ndlp) return 1; lpfc_enqueue_node(vport, ndlp); @@ -3099,7 +3220,7 @@ ndlp->nlp_DID, 0, 0); phba->fc_stat.elsXmitSCR++; - elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; + elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd; if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR) { /* The additional lpfc_nlp_put will cause the following @@ -3329,6 +3450,102 @@ /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of the node. */ + /* Don't release reference count as RDF is likely outstanding */ + return 0; +} + +/** + * lpfc_issue_els_rdf - Register for diagnostic functions from the fabric. + * @vport: pointer to a host virtual N_Port data structure. + * @retry: retry counter for the command IOCB. + * + * This routine issues an ELS RDF to the Fabric Controller to register + * for diagnostic functions. + * + * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp + * will be incremented by 1 for holding the ndlp and the reference to ndlp + * will be stored into the context1 field of the IOCB for the completion + * callback function to the RDF ELS command. + * + * Return code + * 0 - Successfully issued rdf command + * 1 - Failed to issue rdf command + **/ +int +lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_iocbq *elsiocb; + struct lpfc_els_rdf_req *prdf; + struct lpfc_nodelist *ndlp; + uint16_t cmdsize; + + cmdsize = sizeof(*prdf); + + ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID); + if (!ndlp) { + ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID); + if (!ndlp) + return -ENODEV; + lpfc_enqueue_node(vport, ndlp); + } else if (!NLP_CHK_NODE_ACT(ndlp)) { + ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); + if (!ndlp) + return -ENODEV; + } + + /* RDF ELS is not required on an NPIV VN_Port. */ + if (vport->port_type == LPFC_NPIV_PORT) { + lpfc_nlp_put(ndlp); + return -EACCES; + } + + elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, + ndlp->nlp_DID, ELS_CMD_RDF); + if (!elsiocb) { + /* This will trigger the release of the node just + * allocated + */ + lpfc_nlp_put(ndlp); + return -ENOMEM; + } + + /* Configure the payload for the supported FPIN events. */ + prdf = (struct lpfc_els_rdf_req *) + (((struct lpfc_dmabuf *)elsiocb->context2)->virt); + memset(prdf, 0, cmdsize); + prdf->rdf.fpin_cmd = ELS_RDF; + prdf->rdf.desc_len = cpu_to_be32(sizeof(struct lpfc_els_rdf_req) - + sizeof(struct fc_els_rdf)); + prdf->reg_d1.reg_desc.desc_tag = cpu_to_be32(ELS_DTAG_FPIN_REGISTER); + prdf->reg_d1.reg_desc.desc_len = cpu_to_be32( + FC_TLV_DESC_LENGTH_FROM_SZ(prdf->reg_d1)); + prdf->reg_d1.reg_desc.count = cpu_to_be32(ELS_RDF_REG_TAG_CNT); + prdf->reg_d1.desc_tags[0] = cpu_to_be32(ELS_DTAG_LNK_INTEGRITY); + + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, + "Issue RDF: did:x%x", + ndlp->nlp_DID, 0, 0); + + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "6444 Xmit RDF to remote NPORT x%x\n", + ndlp->nlp_DID); + + elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd; + if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == + IOCB_ERROR) { + /* The additional lpfc_nlp_put will cause the following + * lpfc_els_free_iocb routine to trigger the rlease of + * the node. + */ + lpfc_nlp_put(ndlp); + lpfc_els_free_iocb(phba, elsiocb); + return -EIO; + } + + /* An RDF was issued - this put ensures the ndlp is cleaned up + * when the RDF completes. + */ lpfc_nlp_put(ndlp); return 0; } @@ -3721,6 +3938,23 @@ /* Added for Vendor specifc support * Just keep retrying for these Rsn / Exp codes */ + if ((vport->fc_flag & FC_PT2PT) && + cmd == ELS_CMD_NVMEPRLI) { + switch (stat.un.b.lsRjtRsnCode) { + case LSRJT_UNABLE_TPC: + case LSRJT_INVALID_CMD: + case LSRJT_LOGICAL_ERR: + case LSRJT_CMD_UNSUPPORTED: + lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS, + "0168 NVME PRLI LS_RJT " + "reason %x port doesn't " + "support NVME, disabling NVME\n", + stat.un.b.lsRjtRsnCode); + retry = 0; + vport->fc_flag |= FC_PT2PT_NO_NVME; + goto out_retry; + } + } switch (stat.un.b.lsRjtRsnCode) { case LSRJT_UNABLE_TPC: /* The driver has a VALID PLOGI but the rport has @@ -4291,6 +4525,11 @@ irsp = &rspiocb->iocb; + if (!vport) { + lpfc_printf_log(phba, KERN_ERR, LOG_ELS, + "3177 ELS response failed\n"); + goto out; + } if (cmdiocb->context_un.mbox) mbox = cmdiocb->context_un.mbox; @@ -4430,9 +4669,11 @@ mempool_free(mbox, phba->mbox_mem_pool); } out: - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { + if (ndlp && NLP_CHK_NODE_ACT(ndlp) && shost) { spin_lock_irq(shost->host_lock); - ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); + if (mbox) + ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; + ndlp->nlp_flag &= ~NLP_RM_DFLT_RPI; spin_unlock_irq(shost->host_lock); /* If the node is not being used by another discovery thread, @@ -5260,6 +5501,11 @@ } } } + + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6452 Discover PLOGI %d flag x%x\n", + sentplogi, vport->fc_flag); + if (sentplogi) { lpfc_set_disctmo(vport); } @@ -6455,7 +6701,7 @@ uint32_t payload_len, length, nportid, *cmd; int rscn_cnt; int rscn_id = 0, hba_id = 0; - int i; + int i, tmo; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; lp = (uint32_t *) pcmd->virt; @@ -6561,6 +6807,13 @@ spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_DEFERRED; + + /* Restart disctmo if its already running */ + if (vport->fc_flag & FC_DISC_TMO) { + tmo = ((phba->fc_ratov * 3) + 3); + mod_timer(&vport->fc_disctmo, + jiffies + msecs_to_jiffies(1000 * tmo)); + } if ((rscn_cnt < FC_MAX_HOLD_RSCN) && !(vport->fc_flag & FC_RSCN_DISCOVERY)) { vport->fc_flag |= FC_RSCN_MODE; @@ -6663,9 +6916,10 @@ /* RSCN processed */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0215 RSCN processed Data: x%x x%x x%x x%x\n", + "0215 RSCN processed Data: x%x x%x x%x x%x x%x x%x\n", vport->fc_flag, 0, vport->fc_rscn_id_cnt, - vport->port_state); + vport->port_state, vport->num_disc_nodes, + vport->gidft_inp); /* To process RSCN, first compare RSCN data with NameServer */ vport->fc_ns_retry = 0; @@ -7107,108 +7361,12 @@ } /** - * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd - * @phba: pointer to lpfc hba data structure. - * @pmb: pointer to the driver internal queue element for mailbox command. - * - * This routine is the completion callback function for the MBX_READ_LNK_STAT - * mailbox command. This callback function is to actually send the Accept - * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It - * collects the link statistics from the completion of the MBX_READ_LNK_STAT - * mailbox command, constructs the RPS response with the link statistics - * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC - * response to the RPS. - * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPS Accept Response ELS IOCB command. - * - **/ -static void -lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) -{ - MAILBOX_t *mb; - IOCB_t *icmd; - RPS_RSP *rps_rsp; - uint8_t *pcmd; - struct lpfc_iocbq *elsiocb; - struct lpfc_nodelist *ndlp; - uint16_t status; - uint16_t oxid; - uint16_t rxid; - uint32_t cmdsize; - - mb = &pmb->u.mb; - - ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp; - rxid = (uint16_t)((unsigned long)(pmb->ctx_buf) & 0xffff); - oxid = (uint16_t)(((unsigned long)(pmb->ctx_buf) >> 16) & 0xffff); - pmb->ctx_ndlp = NULL; - pmb->ctx_buf = NULL; - - if (mb->mbxStatus) { - mempool_free(pmb, phba->mbox_mem_pool); - return; - } - - cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); - mempool_free(pmb, phba->mbox_mem_pool); - elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize, - lpfc_max_els_tries, ndlp, - ndlp->nlp_DID, ELS_CMD_ACC); - - /* Decrement the ndlp reference count from previous mbox command */ - lpfc_nlp_put(ndlp); - - if (!elsiocb) - return; - - icmd = &elsiocb->iocb; - icmd->ulpContext = rxid; - icmd->unsli3.rcvsli3.ox_id = oxid; - - pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); - *((uint32_t *) (pcmd)) = ELS_CMD_ACC; - pcmd += sizeof(uint32_t); /* Skip past command */ - rps_rsp = (RPS_RSP *)pcmd; - - if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) - status = 0x10; - else - status = 0x8; - if (phba->pport->fc_flag & FC_FABRIC) - status |= 0x4; - - rps_rsp->rsvd1 = 0; - rps_rsp->portStatus = cpu_to_be16(status); - rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt); - rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt); - rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt); - rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt); - rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord); - rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt); - /* Xmit ELS RPS ACC response tag */ - lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS, - "0118 Xmit ELS RPS ACC response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - elsiocb->iotag, elsiocb->iocb.ulpContext, - ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, - ndlp->nlp_rpi); - elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; - phba->fc_stat.elsXmitACC++; - if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR) - lpfc_els_free_iocb(phba, elsiocb); - return; -} - -/** * lpfc_els_rcv_rls - Process an unsolicited rls iocb * @vport: pointer to a host virtual N_Port data structure. * @cmdiocb: pointer to lpfc command iocb data structure. * @ndlp: pointer to a node-list data structure. * - * This routine processes Read Port Status (RPL) IOCB received as an + * This routine processes Read Link Status (RLS) IOCB received as an * ELS unsolicited event. It first checks the remote port state. If the * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE * state, it invokes the lpfc_els_rsl_reject() routine to send the reject @@ -7230,7 +7388,7 @@ if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) - /* reject the unsolicited RPS request and done with it */ + /* reject the unsolicited RLS request and done with it */ goto reject_out; mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); @@ -7278,7 +7436,7 @@ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp * will be incremented by 1 for holding the ndlp and the reference to ndlp * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPS Accept Response ELS IOCB command. + * callback function to the RTV Accept Response ELS IOCB command. * * Return codes * 0 - Successfully processed rtv iocb (currently always return 0) @@ -7297,7 +7455,7 @@ if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) - /* reject the unsolicited RPS request and done with it */ + /* reject the unsolicited RTV request and done with it */ goto reject_out; cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t); @@ -7350,84 +7508,7 @@ return 0; } -/* lpfc_els_rcv_rps - Process an unsolicited rps iocb - * @vport: pointer to a host virtual N_Port data structure. - * @cmdiocb: pointer to lpfc command iocb data structure. - * @ndlp: pointer to a node-list data structure. - * - * This routine processes Read Port Status (RPS) IOCB received as an - * ELS unsolicited event. It first checks the remote port state. If the - * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE - * state, it invokes the lpfc_els_rsp_reject() routine to send the reject - * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command - * for reading the HBA link statistics. It is for the callback function, - * lpfc_els_rsp_rps_acc(), set to the MBX_READ_LNK_STAT mailbox command - * to actually sending out RPS Accept (ACC) response. - * - * Return codes - * 0 - Successfully processed rps iocb (currently always return 0) - **/ -static int -lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, - struct lpfc_nodelist *ndlp) -{ - struct lpfc_hba *phba = vport->phba; - uint32_t *lp; - uint8_t flag; - LPFC_MBOXQ_t *mbox; - struct lpfc_dmabuf *pcmd; - RPS *rps; - struct ls_rjt stat; - - if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) && - (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) - /* reject the unsolicited RPS request and done with it */ - goto reject_out; - - pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; - lp = (uint32_t *) pcmd->virt; - flag = (be32_to_cpu(*lp++) & 0xf); - rps = (RPS *) lp; - - if ((flag == 0) || - ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) || - ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname, - sizeof(struct lpfc_name)) == 0))) { - - printk("Fix me....\n"); - dump_stack(); - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC); - if (mbox) { - lpfc_read_lnk_stat(phba, mbox); - mbox->ctx_buf = (void *)((unsigned long) - ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) | - cmdiocb->iocb.ulpContext)); /* rx_id */ - mbox->ctx_ndlp = lpfc_nlp_get(ndlp); - mbox->vport = vport; - mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; - if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) - != MBX_NOT_FINISHED) - /* Mbox completion will send ELS Response */ - return 0; - /* Decrement reference count used for the failed mbox - * command. - */ - lpfc_nlp_put(ndlp); - mempool_free(mbox, phba->mbox_mem_pool); - } - } - -reject_out: - /* issue rejection response */ - stat.un.b.lsRjtRsvd0 = 0; - stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; - stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; - stat.un.b.vendorUnique = 0; - lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); - return 0; -} - -/* lpfc_issue_els_rrq - Process an unsolicited rps iocb +/* lpfc_issue_els_rrq - Process an unsolicited rrq iocb * @vport: pointer to a host virtual N_Port data structure. * @ndlp: pointer to a node-list data structure. * @did: DID of the target. @@ -7986,20 +8067,22 @@ struct lpfc_sli_ring *pring; struct lpfc_iocbq *tmp_iocb, *piocb; IOCB_t *cmd = NULL; + unsigned long iflags = 0; lpfc_fabric_abort_vport(vport); + /* * For SLI3, only the hbalock is required. But SLI4 needs to coordinate * with the ring insert operation. Because lpfc_sli_issue_abort_iotag * ultimately grabs the ring_lock, the driver must splice the list into * a working list and release the locks before calling the abort. */ - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); pring = lpfc_phba_elsring(phba); /* Bail out if we've no ELS wq, like in PCI error recovery case. */ if (unlikely(!pring)) { - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); return; } @@ -8014,6 +8097,9 @@ if (piocb->vport != vport) continue; + if (piocb->iocb_flag & LPFC_DRIVER_ABORTED) + continue; + /* On the ELS ring we can have ELS_REQUESTs or * GEN_REQUESTs waiting for a response. */ @@ -8037,21 +8123,21 @@ if (phba->sli_rev == LPFC_SLI_REV4) spin_unlock(&pring->ring_lock); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); /* Abort each txcmpl iocb on aborted list and remove the dlist links. */ list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); list_del_init(&piocb->dlist); lpfc_sli_issue_abort_iotag(phba, pring, piocb); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); } if (!list_empty(&abort_list)) lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "3387 abort list for txq not empty\n"); INIT_LIST_HEAD(&abort_list); - spin_lock_irq(&phba->hbalock); + spin_lock_irqsave(&phba->hbalock, iflags); if (phba->sli_rev == LPFC_SLI_REV4) spin_lock(&pring->ring_lock); @@ -8091,7 +8177,7 @@ if (phba->sli_rev == LPFC_SLI_REV4) spin_unlock(&pring->ring_lock); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irqrestore(&phba->hbalock, iflags); /* Cancel all the IOCBs from the completions list */ lpfc_sli_cancel_iocbs(phba, &abort_list, @@ -8277,6 +8363,90 @@ } +DECLARE_ENUM2STR_LOOKUP(lpfc_get_tlv_dtag_nm, fc_ls_tlv_dtag, + FC_LS_TLV_DTAG_INIT); + +DECLARE_ENUM2STR_LOOKUP(lpfc_get_fpin_li_event_nm, fc_fpin_li_event_types, + FC_FPIN_LI_EVT_TYPES_INIT); + +/** + * lpfc_els_rcv_fpin_li - Process an FPIN Link Integrity Event. + * @vport: Pointer to vport object. + * @lnk_not: Pointer to the Link Integrity Notification Descriptor. + * + * This function processes a link integrity FPIN event by + * logging a message + **/ +static void +lpfc_els_rcv_fpin_li(struct lpfc_vport *vport, struct fc_tlv_desc *tlv) +{ + struct fc_fn_li_desc *li = (struct fc_fn_li_desc *)tlv; + const char *li_evt_str; + u32 li_evt; + + li_evt = be16_to_cpu(li->event_type); + li_evt_str = lpfc_get_fpin_li_event_nm(li_evt); + + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "4680 FPIN Link Integrity %s (x%x) " + "Detecting PN x%016llx Attached PN x%016llx " + "Duration %d mSecs Count %d Port Cnt %d\n", + li_evt_str, li_evt, + be64_to_cpu(li->detecting_wwpn), + be64_to_cpu(li->attached_wwpn), + be32_to_cpu(li->event_threshold), + be32_to_cpu(li->event_count), + be32_to_cpu(li->pname_count)); +} + +static void +lpfc_els_rcv_fpin(struct lpfc_vport *vport, struct fc_els_fpin *fpin, + u32 fpin_length) +{ + struct fc_tlv_desc *tlv; + const char *dtag_nm; + uint32_t desc_cnt = 0, bytes_remain; + u32 dtag; + + /* FPINs handled only if we are in the right discovery state */ + if (vport->port_state < LPFC_DISC_AUTH) + return; + + /* make sure there is the full fpin header */ + if (fpin_length < sizeof(struct fc_els_fpin)) + return; + + tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0]; + bytes_remain = fpin_length - offsetof(struct fc_els_fpin, fpin_desc); + bytes_remain = min_t(u32, bytes_remain, be32_to_cpu(fpin->desc_len)); + + /* process each descriptor */ + while (bytes_remain >= FC_TLV_DESC_HDR_SZ && + bytes_remain >= FC_TLV_DESC_SZ_FROM_LENGTH(tlv)) { + + dtag = be32_to_cpu(tlv->desc_tag); + switch (dtag) { + case ELS_DTAG_LNK_INTEGRITY: + lpfc_els_rcv_fpin_li(vport, tlv); + break; + default: + dtag_nm = lpfc_get_tlv_dtag_nm(dtag); + lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, + "4678 skipped FPIN descriptor[%d]: " + "tag x%x (%s)\n", + desc_cnt, dtag, dtag_nm); + break; + } + + desc_cnt++; + bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv); + tlv = fc_tlv_next_desc(tlv); + } + + fc_host_fpin_rcv(lpfc_shost_from_vport(vport), fpin_length, + (char *)fpin); +} + /** * lpfc_els_unsol_buffer - Process an unsolicited event data buffer * @phba: pointer to lpfc hba data structure. @@ -8298,7 +8468,7 @@ struct Scsi_Host *shost; struct lpfc_nodelist *ndlp; struct ls_rjt stat; - uint32_t *payload; + uint32_t *payload, payload_len; uint32_t cmd, did, newnode; uint8_t rjt_exp, rjt_err = 0, init_link = 0; IOCB_t *icmd = &elsiocb->iocb; @@ -8309,6 +8479,7 @@ newnode = 0; payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt; + payload_len = elsiocb->iocb.unsli3.rcvsli3.acc_len; cmd = *payload; if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) lpfc_post_buffer(phba, pring, 1); @@ -8372,6 +8543,8 @@ spin_lock_irq(shost->host_lock); if (ndlp->nlp_flag & NLP_IN_DEV_LOSS) { spin_unlock_irq(shost->host_lock); + if (newnode) + lpfc_nlp_put(ndlp); goto dropit; } spin_unlock_irq(shost->host_lock); @@ -8599,16 +8772,6 @@ if (newnode) lpfc_nlp_put(ndlp); break; - case ELS_CMD_RPS: - lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, - "RCV RPS: did:x%x/ste:x%x flg:x%x", - did, vport->port_state, ndlp->nlp_flag); - - phba->fc_stat.elsRcvRPS++; - lpfc_els_rcv_rps(vport, elsiocb, ndlp); - if (newnode) - lpfc_nlp_put(ndlp); - break; case ELS_CMD_RPL: lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, "RCV RPL: did:x%x/ste:x%x flg:x%x", @@ -8664,12 +8827,14 @@ rjt_exp = LSEXP_INVALID_OX_RX; break; case ELS_CMD_FPIN: - /* - * Received FPIN from fabric - pass it to the - * transport FPIN handler. - */ - fc_host_fpin_rcv(shost, elsiocb->iocb.unsli3.rcvsli3.acc_len, - (char *)payload); + lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, + "RCV FPIN: did:x%x/ste:x%x flg:x%x", + did, vport->port_state, ndlp->nlp_flag); + + lpfc_els_rcv_fpin(vport, (struct fc_els_fpin *)payload, + payload_len); + + /* There are no replies, so no rjt codes */ break; default: lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_hbadisc.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,7 @@ static void lpfc_disc_flush_list(struct lpfc_vport *vport); static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); static int lpfc_fcf_inuse(struct lpfc_hba *); +static void lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_terminate_rport_io(struct fc_rport *rport) @@ -626,10 +628,16 @@ if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) lpfc_sli4_post_async_mbox(phba); - if (ha_copy & HA_ERATT) + if (ha_copy & HA_ERATT) { /* Handle the error attention event */ lpfc_handle_eratt(phba); + if (phba->fw_dump_cmpl) { + complete(phba->fw_dump_cmpl); + phba->fw_dump_cmpl = NULL; + } + } + if (ha_copy & HA_MBATT) lpfc_sli_handle_mb_event(phba); @@ -700,7 +708,10 @@ if (!(phba->hba_flag & HBA_SP_QUEUE_EVT)) set_bit(LPFC_DATA_READY, &phba->data_flags); } else { - if (phba->link_state >= LPFC_LINK_UP || + /* Driver could have abort request completed in queue + * when link goes down. Allow for this transition. + */ + if (phba->link_state >= LPFC_LINK_DOWN || phba->link_flag & LS_MDS_LOOPBACK) { pring->flag &= ~LPFC_DEFERRED_RING_EVENT; lpfc_sli_handle_slow_ring_event(phba, pring, @@ -1130,12 +1141,13 @@ return; } - void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) { struct lpfc_vport *vport = pmb->vport; - uint8_t bbscn = 0; + LPFC_MBOXQ_t *sparam_mb; + struct lpfc_dmabuf *sparam_mp; + int rc; if (pmb->u.mb.mbxStatus) goto out; @@ -1160,18 +1172,45 @@ } /* Start discovery by sending a FLOGI. port_state is identically - * LPFC_FLOGI while waiting for FLOGI cmpl + * LPFC_FLOGI while waiting for FLOGI cmpl. */ if (vport->port_state != LPFC_FLOGI) { - if (phba->bbcredit_support && phba->cfg_enable_bbcr) { - bbscn = bf_get(lpfc_bbscn_def, - &phba->sli4_hba.bbscn_params); - vport->fc_sparam.cmn.bbRcvSizeMsb &= 0xf; - vport->fc_sparam.cmn.bbRcvSizeMsb |= (bbscn << 4); + /* Issue MBX_READ_SPARAM to update CSPs before FLOGI if + * bb-credit recovery is in place. + */ + if (phba->bbcredit_support && phba->cfg_enable_bbcr && + !(phba->link_flag & LS_LOOPBACK_MODE)) { + sparam_mb = mempool_alloc(phba->mbox_mem_pool, + GFP_KERNEL); + if (!sparam_mb) + goto sparam_out; + + rc = lpfc_read_sparam(phba, sparam_mb, 0); + if (rc) { + mempool_free(sparam_mb, phba->mbox_mem_pool); + goto sparam_out; + } + sparam_mb->vport = vport; + sparam_mb->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; + rc = lpfc_sli_issue_mbox(phba, sparam_mb, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + sparam_mp = (struct lpfc_dmabuf *) + sparam_mb->ctx_buf; + lpfc_mbuf_free(phba, sparam_mp->virt, + sparam_mp->phys); + kfree(sparam_mp); + sparam_mb->ctx_buf = NULL; + mempool_free(sparam_mb, phba->mbox_mem_pool); + goto sparam_out; + } + + phba->hba_flag |= HBA_DEFER_FLOGI; + } else { + lpfc_initial_flogi(vport); } - lpfc_initial_flogi(vport); - } else if (vport->fc_flag & FC_PT2PT) { - lpfc_disc_start(vport); + } else { + if (vport->fc_flag & FC_PT2PT) + lpfc_disc_start(vport); } return; @@ -1180,6 +1219,7 @@ "0306 CONFIG_LINK mbxStatus error x%x " "HBA state x%x\n", pmb->u.mb.mbxStatus, vport->port_state); +sparam_out: mempool_free(pmb, phba->mbox_mem_pool); lpfc_linkdown(phba); @@ -3097,6 +3137,14 @@ lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); + + /* Check if sending the FLOGI is being deferred to after we get + * up to date CSPs from MBX_READ_SPARAM. + */ + if (phba->hba_flag & HBA_DEFER_FLOGI) { + lpfc_initial_flogi(vport); + phba->hba_flag &= ~HBA_DEFER_FLOGI; + } return; out: @@ -3227,6 +3275,8 @@ } lpfc_linkup(phba); + sparam_mbox = NULL; + sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!sparam_mbox) goto out; @@ -3319,6 +3369,10 @@ lpfc_sli4_clear_fcf_rr_bmask(phba); } + /* Prepare for LINK up registrations */ + memset(phba->os_host_name, 0, sizeof(phba->os_host_name)); + scnprintf(phba->os_host_name, sizeof(phba->os_host_name), "%s", + init_utsname()->nodename); return; out: lpfc_vport_set_state(vport, FC_VPORT_FAILED); @@ -3456,8 +3510,8 @@ phba->pport->port_state, vport->fc_flag); else if (attn_type == LPFC_ATT_UNEXP_WWPN) lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, - "1313 Link Down UNEXP WWPN Event x%x received " - "Data: x%x x%x x%x x%x x%x\n", + "1313 Link Down Unexpected FA WWPN Event x%x " + "received Data: x%x x%x x%x x%x x%x\n", la->eventTag, phba->fc_eventTag, phba->pport->port_state, vport->fc_flag, bf_get(lpfc_mbx_read_top_mm, la), @@ -4046,7 +4100,7 @@ ndlp->nlp_flag |= NLP_RPI_REGISTERED; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); - lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_DISCOVERY, "0003 rpi:%x DID:%x flg:%x %d map%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), @@ -4069,7 +4123,9 @@ FC_TYPE_NVME); /* Issue SCR just before NameServer GID_FT Query */ - lpfc_issue_els_scr(vport, SCR_DID, 0); + lpfc_issue_els_scr(vport, 0); + + lpfc_issue_els_rdf(vport, 0); } vport->fc_ns_retry = 0; @@ -4575,8 +4631,10 @@ return ndlp; free_rpi: - if (phba->sli_rev == LPFC_SLI_REV4) + if (phba->sli_rev == LPFC_SLI_REV4) { lpfc_sli4_free_rpi(vport->phba, rpi); + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; + } return NULL; } @@ -4835,12 +4893,51 @@ if (ndlp->nlp_flag & NLP_RELEASE_RPI) { lpfc_sli4_free_rpi(vport->phba, ndlp->nlp_rpi); ndlp->nlp_flag &= ~NLP_RELEASE_RPI; + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; } ndlp->nlp_flag &= ~NLP_UNREG_INP; } } /* + * Sets the mailbox completion handler to be used for the + * unreg_rpi command. The handler varies based on the state of + * the port and what will be happening to the rpi next. + */ +static void +lpfc_set_unreg_login_mbx_cmpl(struct lpfc_hba *phba, struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp, LPFC_MBOXQ_t *mbox) +{ + unsigned long iflags; + + if (ndlp->nlp_flag & NLP_ISSUE_LOGO) { + mbox->ctx_ndlp = ndlp; + mbox->mbox_cmpl = lpfc_nlp_logo_unreg; + + } else if (phba->sli_rev == LPFC_SLI_REV4 && + (!(vport->load_flag & FC_UNLOADING)) && + (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= + LPFC_SLI_INTF_IF_TYPE_2) && + (kref_read(&ndlp->kref) > 0)) { + mbox->ctx_ndlp = lpfc_nlp_get(ndlp); + mbox->mbox_cmpl = lpfc_sli4_unreg_rpi_cmpl_clr; + } else { + if (vport->load_flag & FC_UNLOADING) { + if (phba->sli_rev == LPFC_SLI_REV4) { + spin_lock_irqsave(&vport->phba->ndlp_lock, + iflags); + ndlp->nlp_flag |= NLP_RELEASE_RPI; + spin_unlock_irqrestore(&vport->phba->ndlp_lock, + iflags); + } + lpfc_nlp_get(ndlp); + } + mbox->ctx_ndlp = ndlp; + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + } +} + +/* * Free rpi associated with LPFC_NODELIST entry. * This routine is called from lpfc_freenode(), when we are removing * a LPFC_NODELIST entry. It is also called if the driver initiates a @@ -4860,7 +4957,8 @@ if (ndlp->nlp_flag & NLP_RPI_REGISTERED || ndlp->nlp_flag & NLP_REG_LOGIN_SEND) { if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND) - lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, + lpfc_printf_vlog(vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, "3366 RPI x%x needs to be " "unregistered nlp_flag x%x " "did x%x\n", @@ -4871,7 +4969,8 @@ * no need to queue up another one. */ if (ndlp->nlp_flag & NLP_UNREG_INP) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + lpfc_printf_vlog(vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, "1436 unreg_rpi SKIP UNREG x%x on " "NPort x%x deferred x%x flg x%x " "Data: x%px\n", @@ -4890,39 +4989,19 @@ lpfc_unreg_login(phba, vport->vpi, rpi, mbox); mbox->vport = vport; - if (ndlp->nlp_flag & NLP_ISSUE_LOGO) { - mbox->ctx_ndlp = ndlp; - mbox->mbox_cmpl = lpfc_nlp_logo_unreg; - } else { - if (phba->sli_rev == LPFC_SLI_REV4 && - (!(vport->load_flag & FC_UNLOADING)) && - (bf_get(lpfc_sli_intf_if_type, - &phba->sli4_hba.sli_intf) >= - LPFC_SLI_INTF_IF_TYPE_2) && - (kref_read(&ndlp->kref) > 0)) { - mbox->ctx_ndlp = lpfc_nlp_get(ndlp); - mbox->mbox_cmpl = - lpfc_sli4_unreg_rpi_cmpl_clr; - /* - * accept PLOGIs after unreg_rpi_cmpl - */ - acc_plogi = 0; - } else if (vport->load_flag & FC_UNLOADING) { - mbox->ctx_ndlp = NULL; - mbox->mbox_cmpl = - lpfc_sli_def_mbox_cmpl; - } else { - mbox->ctx_ndlp = ndlp; - mbox->mbox_cmpl = - lpfc_sli_def_mbox_cmpl; - } - } + lpfc_set_unreg_login_mbx_cmpl(phba, vport, ndlp, mbox); + if (mbox->mbox_cmpl == lpfc_sli4_unreg_rpi_cmpl_clr) + /* + * accept PLOGIs after unreg_rpi_cmpl + */ + acc_plogi = 0; if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && (!(vport->fc_flag & FC_OFFLINE_MODE))) ndlp->nlp_flag |= NLP_UNREG_INP; - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + lpfc_printf_vlog(vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, "1433 unreg_rpi UNREG x%x on " "NPort x%x deferred flg x%x " "Data:x%px\n", @@ -5057,6 +5136,7 @@ struct lpfc_hba *phba = vport->phba; LPFC_MBOXQ_t *mb, *nextmb; struct lpfc_dmabuf *mp; + unsigned long iflags; /* Cleanup node for NPort */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, @@ -5138,8 +5218,20 @@ lpfc_cleanup_vports_rrqs(vport, ndlp); if (phba->sli_rev == LPFC_SLI_REV4) ndlp->nlp_flag |= NLP_RELEASE_RPI; - lpfc_unreg_rpi(vport, ndlp); - + if (!lpfc_unreg_rpi(vport, ndlp)) { + /* Clean up unregistered and non freed rpis */ + if ((ndlp->nlp_flag & NLP_RELEASE_RPI) && + !(ndlp->nlp_rpi == LPFC_RPI_ALLOC_ERROR)) { + lpfc_sli4_free_rpi(vport->phba, + ndlp->nlp_rpi); + spin_lock_irqsave(&vport->phba->ndlp_lock, + iflags); + ndlp->nlp_flag &= ~NLP_RELEASE_RPI; + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; + spin_unlock_irqrestore(&vport->phba->ndlp_lock, + iflags); + } + } return 0; } @@ -5165,8 +5257,10 @@ /* For this case we need to cleanup the default rpi * allocated by the firmware. */ - lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "0005 rpi:%x DID:%x flg:%x %d map:%x x%px\n", + lpfc_printf_vlog(vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, + "0005 Cleanup Default rpi:x%x DID:x%x flg:x%x " + "ref %d map:x%x ndlp x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), ndlp->nlp_usg_map, ndlp); @@ -5203,8 +5297,9 @@ */ lpfc_printf_vlog(vport, KERN_WARNING, LOG_NODE, "0940 removed node x%px DID x%x " - " rport not null x%px\n", - ndlp, ndlp->nlp_DID, ndlp->rport); + "rpi %d rport not null x%px\n", + ndlp, ndlp->nlp_DID, ndlp->nlp_rpi, + ndlp->rport); rport = ndlp->rport; rdata = rport->dd_data; rdata->pnode = NULL; @@ -5362,6 +5457,13 @@ if (!ndlp) return NULL; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); + + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6453 Setup New Node 2B_DISC x%x " + "Data:x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, vport->fc_flag); + spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_NPR_2B_DISC; spin_unlock_irq(shost->host_lock); @@ -5375,6 +5477,12 @@ "0014 Could not enable ndlp\n"); return NULL; } + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6454 Setup Enabled Node 2B_DISC x%x " + "Data:x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, vport->fc_flag); + spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_NPR_2B_DISC; spin_unlock_irq(shost->host_lock); @@ -5394,6 +5502,12 @@ */ lpfc_cancel_retry_delay_tmo(vport, ndlp); + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6455 Setup RSCN Node 2B_DISC x%x " + "Data:x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, vport->fc_flag); + /* NVME Target mode waits until rport is known to be * impacted by the RSCN before it transitions. No * active management - just go to NPR provided the @@ -5405,15 +5519,32 @@ /* If we've already received a PLOGI from this NPort * we don't need to try to discover it again. */ - if (ndlp->nlp_flag & NLP_RCV_PLOGI) + if (ndlp->nlp_flag & NLP_RCV_PLOGI && + !(ndlp->nlp_type & + (NLP_FCP_TARGET | NLP_NVME_TARGET))) return NULL; + ndlp->nlp_prev_state = ndlp->nlp_state; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); + spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_NPR_2B_DISC; spin_unlock_irq(shost->host_lock); - } else + } else { + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6456 Skip Setup RSCN Node x%x " + "Data:x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, vport->fc_flag); ndlp = NULL; + } } else { + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "6457 Setup Active Node 2B_DISC x%x " + "Data:x%x x%x x%x\n", + ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->nlp_state, vport->fc_flag); + /* If the initiator received a PLOGI from this NPort or if the * initiator is already in the process of discovery on it, * there's no need to try to discover it again. @@ -5565,10 +5696,10 @@ /* Start Discovery state */ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "0202 Start Discovery hba state x%x " - "Data: x%x x%x x%x\n", + "0202 Start Discovery port state x%x " + "flg x%x Data: x%x x%x x%x\n", vport->port_state, vport->fc_flag, vport->fc_plogi_cnt, - vport->fc_adisc_cnt); + vport->fc_adisc_cnt, vport->fc_npr_cnt); /* First do ADISCs - if any */ num_sent = lpfc_els_disc_adisc(vport); @@ -5996,7 +6127,7 @@ ndlp->nlp_flag |= NLP_RPI_REGISTERED; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); - lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_DISCOVERY, "0004 rpi:%x DID:%x flg:%x %d map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, kref_read(&ndlp->kref), @@ -6185,12 +6316,12 @@ INIT_LIST_HEAD(&ndlp->nlp_listp); if (vport->phba->sli_rev == LPFC_SLI_REV4) { ndlp->nlp_rpi = rpi; - lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "0007 rpi:%x DID:%x flg:%x refcnt:%d " - "map:%x x%px\n", ndlp->nlp_rpi, ndlp->nlp_DID, - ndlp->nlp_flag, - kref_read(&ndlp->kref), - ndlp->nlp_usg_map, ndlp); + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_DISCOVERY, + "0007 Init New ndlp x%px, rpi:x%x DID:%x " + "flg:x%x refcnt:%d map:x%x\n", + ndlp, ndlp->nlp_rpi, ndlp->nlp_DID, + ndlp->nlp_flag, kref_read(&ndlp->kref), + ndlp->nlp_usg_map); ndlp->active_rrqs_xri_bitmap = mempool_alloc(vport->phba->active_rrq_pool, @@ -6419,7 +6550,8 @@ goto out; } else if (ndlp->nlp_flag & NLP_RPI_REGISTERED) { ret = 1; - lpfc_printf_log(phba, KERN_INFO, LOG_ELS, + lpfc_printf_log(phba, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, "2624 RPI %x DID %x flag %x " "still logged in\n", ndlp->nlp_rpi, ndlp->nlp_DID, @@ -6610,7 +6742,9 @@ if (rc) return; /* Reset HBA FCF states after successful unregister FCF */ + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag = 0; + spin_unlock_irq(&phba->hbalock); phba->fcf.current_rec.flag = 0; /* --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_hw.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -22,7 +22,7 @@ #define FDMI_DID 0xfffffaU #define NameServer_DID 0xfffffcU -#define SCR_DID 0xfffffdU +#define Fabric_Cntl_DID 0xfffffdU #define Fabric_DID 0xfffffeU #define Bcast_DID 0xffffffU #define Mask_DID 0xffffffU @@ -588,6 +588,7 @@ #define ELS_CMD_RRQ 0x12000000 #define ELS_CMD_REC 0x13000000 #define ELS_CMD_RDP 0x18000000 +#define ELS_CMD_RDF 0x19000000 #define ELS_CMD_PRLI 0x20100014 #define ELS_CMD_NVMEPRLI 0x20140018 #define ELS_CMD_PRLO 0x21100014 @@ -597,7 +598,6 @@ #define ELS_CMD_ADISC 0x52000000 #define ELS_CMD_FARP 0x54000000 #define ELS_CMD_FARPR 0x55000000 -#define ELS_CMD_RPS 0x56000000 #define ELS_CMD_RPL 0x57000000 #define ELS_CMD_FAN 0x60000000 #define ELS_CMD_RSCN 0x61040000 @@ -630,6 +630,7 @@ #define ELS_CMD_RRQ 0x12 #define ELS_CMD_REC 0x13 #define ELS_CMD_RDP 0x18 +#define ELS_CMD_RDF 0x19 #define ELS_CMD_PRLI 0x14001020 #define ELS_CMD_NVMEPRLI 0x18001420 #define ELS_CMD_PRLO 0x14001021 @@ -639,7 +640,6 @@ #define ELS_CMD_ADISC 0x52 #define ELS_CMD_FARP 0x54 #define ELS_CMD_FARPR 0x55 -#define ELS_CMD_RPS 0x56 #define ELS_CMD_RPL 0x57 #define ELS_CMD_FAN 0x60 #define ELS_CMD_RSCN 0x0461 @@ -919,24 +919,6 @@ } un; } __packed RNID; -typedef struct _RPS { /* Structure is in Big Endian format */ - union { - uint32_t portNum; - struct lpfc_name portName; - } un; -} RPS; - -typedef struct _RPS_RSP { /* Structure is in Big Endian format */ - uint16_t rsvd1; - uint16_t portStatus; - uint32_t linkFailureCnt; - uint32_t lossSyncCnt; - uint32_t lossSignalCnt; - uint32_t primSeqErrCnt; - uint32_t invalidXmitWord; - uint32_t crcCnt; -} RPS_RSP; - struct RLS { /* Structure is in Big Endian format */ uint32_t rls; #define rls_rsvd_SHIFT 24 @@ -1340,25 +1322,8 @@ /* lpfc_sli_ct_request defines the CT_IU preamble for FDMI commands */ #define SLI_CT_FDMI_Subtypes 0x10 /* Management Service Subtype */ -/* - * Registered Port List Format - */ -struct lpfc_fdmi_reg_port_list { - uint32_t EntryCnt; - uint32_t pe; /* Variable-length array */ -}; - - /* Definitions for HBA / Port attribute entries */ -struct lpfc_fdmi_attr_def { /* Defined in TLV format */ - /* Structure is in Big Endian format */ - uint32_t AttrType:16; - uint32_t AttrLen:16; - uint32_t AttrValue; /* Marks start of Value (ATTRIBUTE_ENTRY) */ -}; - - /* Attribute Entry */ struct lpfc_fdmi_attr_entry { union { @@ -1369,7 +1334,13 @@ } un; }; -#define LPFC_FDMI_MAX_AE_SIZE sizeof(struct lpfc_fdmi_attr_entry) +struct lpfc_fdmi_attr_def { /* Defined in TLV format */ + /* Structure is in Big Endian format */ + uint32_t AttrType:16; + uint32_t AttrLen:16; + /* Marks start of Value (ATTRIBUTE_ENTRY) */ + struct lpfc_fdmi_attr_entry AttrValue; +} __packed; /* * HBA Attribute Block @@ -1394,12 +1365,19 @@ }; /* + * Registered Port List Format + */ +struct lpfc_fdmi_reg_port_list { + uint32_t EntryCnt; + struct lpfc_fdmi_port_entry pe; +} __packed; + +/* * Register HBA(RHBA) */ struct lpfc_fdmi_reg_hba { struct lpfc_fdmi_hba_ident hi; - struct lpfc_fdmi_reg_port_list rpl; /* variable-length array */ -/* struct lpfc_fdmi_attr_block ab; */ + struct lpfc_fdmi_reg_port_list rpl; }; /* --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_hw4.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_hw4.h @@ -20,6 +20,8 @@ * included with this package. * *******************************************************************/ +#include + /* Macros to deal with bit fields. Each bit field must have 3 #defines * associated with it (_SHIFT, _MASK, and _WORD). * EG. For a bit field that is in the 7th bit of the "field4" field of a @@ -122,6 +124,7 @@ /* Define SLI4 Alignment requirements. */ #define LPFC_ALIGN_16_BYTE 16 #define LPFC_ALIGN_64_BYTE 64 +#define SLI4_PAGE_SIZE 4096 /* Define SLI4 specific definitions. */ #define LPFC_MQ_CQE_BYTE_OFFSET 256 @@ -210,7 +213,6 @@ #define LPFC_MAX_IMAX 5000000 #define LPFC_DEF_IMAX 0 -#define LPFC_IMAX_THRESHOLD 1000 #define LPFC_MAX_AUTO_EQ_DELAY 120 #define LPFC_EQ_DELAY_STEP 15 #define LPFC_EQD_ISR_TRIGGER 20000 @@ -2320,6 +2322,7 @@ #define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67 #define ADD_STATUS_FW_NOT_SUPPORTED 0xEB #define ADD_STATUS_INVALID_REQUEST 0x4B +#define ADD_STATUS_FW_DOWNLOAD_HW_DISABLED 0x58 struct lpfc_mbx_sli4_config { struct mbox_header header; @@ -2809,6 +2812,15 @@ #define lpfc_mbx_rd_conf_trunk_SHIFT 12 #define lpfc_mbx_rd_conf_trunk_MASK 0x0000000F #define lpfc_mbx_rd_conf_trunk_WORD word2 +#define lpfc_mbx_rd_conf_pt_SHIFT 20 +#define lpfc_mbx_rd_conf_pt_MASK 0x00000003 +#define lpfc_mbx_rd_conf_pt_WORD word2 +#define lpfc_mbx_rd_conf_tf_SHIFT 22 +#define lpfc_mbx_rd_conf_tf_MASK 0x00000001 +#define lpfc_mbx_rd_conf_tf_WORD word2 +#define lpfc_mbx_rd_conf_ptv_SHIFT 23 +#define lpfc_mbx_rd_conf_ptv_MASK 0x00000001 +#define lpfc_mbx_rd_conf_ptv_WORD word2 #define lpfc_mbx_rd_conf_topology_SHIFT 24 #define lpfc_mbx_rd_conf_topology_MASK 0x000000FF #define lpfc_mbx_rd_conf_topology_WORD word2 @@ -2962,62 +2974,6 @@ #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3 }; -struct lpfc_mbx_supp_pages { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define list_offset_SHIFT 0 -#define list_offset_MASK 0x000000ff -#define list_offset_WORD word2 -#define next_offset_SHIFT 8 -#define next_offset_MASK 0x000000ff -#define next_offset_WORD word2 -#define elem_cnt_SHIFT 16 -#define elem_cnt_MASK 0x000000ff -#define elem_cnt_WORD word2 - uint32_t word3; -#define pn_0_SHIFT 24 -#define pn_0_MASK 0x000000ff -#define pn_0_WORD word3 -#define pn_1_SHIFT 16 -#define pn_1_MASK 0x000000ff -#define pn_1_WORD word3 -#define pn_2_SHIFT 8 -#define pn_2_MASK 0x000000ff -#define pn_2_WORD word3 -#define pn_3_SHIFT 0 -#define pn_3_MASK 0x000000ff -#define pn_3_WORD word3 - uint32_t word4; -#define pn_4_SHIFT 24 -#define pn_4_MASK 0x000000ff -#define pn_4_WORD word4 -#define pn_5_SHIFT 16 -#define pn_5_MASK 0x000000ff -#define pn_5_WORD word4 -#define pn_6_SHIFT 8 -#define pn_6_MASK 0x000000ff -#define pn_6_WORD word4 -#define pn_7_SHIFT 0 -#define pn_7_MASK 0x000000ff -#define pn_7_WORD word4 - uint32_t rsvd[27]; -#define LPFC_SUPP_PAGES 0 -#define LPFC_BLOCK_GUARD_PROFILES 1 -#define LPFC_SLI4_PARAMETERS 2 -}; - struct lpfc_mbx_memory_dump_type3 { uint32_t word1; #define lpfc_mbx_memory_dump_type3_type_SHIFT 0 @@ -3234,121 +3190,6 @@ uint8_t reserved191[57]; }; -struct lpfc_mbx_pc_sli4_params { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define if_type_SHIFT 0 -#define if_type_MASK 0x00000007 -#define if_type_WORD word2 -#define sli_rev_SHIFT 4 -#define sli_rev_MASK 0x0000000f -#define sli_rev_WORD word2 -#define sli_family_SHIFT 8 -#define sli_family_MASK 0x000000ff -#define sli_family_WORD word2 -#define featurelevel_1_SHIFT 16 -#define featurelevel_1_MASK 0x000000ff -#define featurelevel_1_WORD word2 -#define featurelevel_2_SHIFT 24 -#define featurelevel_2_MASK 0x0000001f -#define featurelevel_2_WORD word2 - uint32_t word3; -#define fcoe_SHIFT 0 -#define fcoe_MASK 0x00000001 -#define fcoe_WORD word3 -#define fc_SHIFT 1 -#define fc_MASK 0x00000001 -#define fc_WORD word3 -#define nic_SHIFT 2 -#define nic_MASK 0x00000001 -#define nic_WORD word3 -#define iscsi_SHIFT 3 -#define iscsi_MASK 0x00000001 -#define iscsi_WORD word3 -#define rdma_SHIFT 4 -#define rdma_MASK 0x00000001 -#define rdma_WORD word3 - uint32_t sge_supp_len; -#define SLI4_PAGE_SIZE 4096 - uint32_t word5; -#define if_page_sz_SHIFT 0 -#define if_page_sz_MASK 0x0000ffff -#define if_page_sz_WORD word5 -#define loopbk_scope_SHIFT 24 -#define loopbk_scope_MASK 0x0000000f -#define loopbk_scope_WORD word5 -#define rq_db_window_SHIFT 28 -#define rq_db_window_MASK 0x0000000f -#define rq_db_window_WORD word5 - uint32_t word6; -#define eq_pages_SHIFT 0 -#define eq_pages_MASK 0x0000000f -#define eq_pages_WORD word6 -#define eqe_size_SHIFT 8 -#define eqe_size_MASK 0x000000ff -#define eqe_size_WORD word6 - uint32_t word7; -#define cq_pages_SHIFT 0 -#define cq_pages_MASK 0x0000000f -#define cq_pages_WORD word7 -#define cqe_size_SHIFT 8 -#define cqe_size_MASK 0x000000ff -#define cqe_size_WORD word7 - uint32_t word8; -#define mq_pages_SHIFT 0 -#define mq_pages_MASK 0x0000000f -#define mq_pages_WORD word8 -#define mqe_size_SHIFT 8 -#define mqe_size_MASK 0x000000ff -#define mqe_size_WORD word8 -#define mq_elem_cnt_SHIFT 16 -#define mq_elem_cnt_MASK 0x000000ff -#define mq_elem_cnt_WORD word8 - uint32_t word9; -#define wq_pages_SHIFT 0 -#define wq_pages_MASK 0x0000ffff -#define wq_pages_WORD word9 -#define wqe_size_SHIFT 8 -#define wqe_size_MASK 0x000000ff -#define wqe_size_WORD word9 - uint32_t word10; -#define rq_pages_SHIFT 0 -#define rq_pages_MASK 0x0000ffff -#define rq_pages_WORD word10 -#define rqe_size_SHIFT 8 -#define rqe_size_MASK 0x000000ff -#define rqe_size_WORD word10 - uint32_t word11; -#define hdr_pages_SHIFT 0 -#define hdr_pages_MASK 0x0000000f -#define hdr_pages_WORD word11 -#define hdr_size_SHIFT 8 -#define hdr_size_MASK 0x0000000f -#define hdr_size_WORD word11 -#define hdr_pp_align_SHIFT 16 -#define hdr_pp_align_MASK 0x0000ffff -#define hdr_pp_align_WORD word11 - uint32_t word12; -#define sgl_pages_SHIFT 0 -#define sgl_pages_MASK 0x0000000f -#define sgl_pages_WORD word12 -#define sgl_pp_align_SHIFT 16 -#define sgl_pp_align_MASK 0x0000ffff -#define sgl_pp_align_WORD word12 - uint32_t rsvd_13_63[51]; -}; #define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \ &(~((SLI4_PAGE_SIZE)-1))) @@ -3479,6 +3320,9 @@ #define cfg_bv1s_SHIFT 10 #define cfg_bv1s_MASK 0x00000001 #define cfg_bv1s_WORD word19 +#define cfg_pvl_SHIFT 13 +#define cfg_pvl_MASK 0x00000001 +#define cfg_pvl_WORD word19 #define cfg_nsler_SHIFT 12 #define cfg_nsler_MASK 0x00000001 @@ -3518,6 +3362,7 @@ #define LPFC_SET_UE_RECOVERY 0x10 #define LPFC_SET_MDS_DIAGS 0x11 +#define LPFC_SET_DUAL_DUMP 0x1e struct lpfc_mbx_set_feature { struct mbox_header header; uint32_t feature; @@ -3532,6 +3377,15 @@ #define lpfc_mbx_set_feature_mds_deep_loopbk_SHIFT 1 #define lpfc_mbx_set_feature_mds_deep_loopbk_MASK 0x00000001 #define lpfc_mbx_set_feature_mds_deep_loopbk_WORD word6 +#define lpfc_mbx_set_feature_dd_SHIFT 0 +#define lpfc_mbx_set_feature_dd_MASK 0x00000001 +#define lpfc_mbx_set_feature_dd_WORD word6 +#define lpfc_mbx_set_feature_ddquery_SHIFT 1 +#define lpfc_mbx_set_feature_ddquery_MASK 0x00000001 +#define lpfc_mbx_set_feature_ddquery_WORD word6 +#define LPFC_DISABLE_DUAL_DUMP 0 +#define LPFC_ENABLE_DUAL_DUMP 1 +#define LPFC_QUERY_OP_DUAL_DUMP 2 uint32_t word7; #define lpfc_mbx_set_feature_UERP_SHIFT 0 #define lpfc_mbx_set_feature_UERP_MASK 0x0000ffff @@ -3903,6 +3757,9 @@ #define LPFC_CHANGE_STATUS_FW_RESET 0x02 #define LPFC_CHANGE_STATUS_PORT_MIGRATION 0x04 #define LPFC_CHANGE_STATUS_PCI_RESET 0x05 +#define lpfc_wr_object_csf_SHIFT 8 +#define lpfc_wr_object_csf_MASK 0x00000001 +#define lpfc_wr_object_csf_WORD word5 } response; } u; }; @@ -3958,8 +3815,6 @@ struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; struct lpfc_mbx_query_fw_config query_fw_cfg; struct lpfc_mbx_set_beacon_config beacon_config; - struct lpfc_mbx_supp_pages supp_pages; - struct lpfc_mbx_pc_sli4_params sli4_params; struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; struct lpfc_mbx_set_link_diag_state link_diag_state; struct lpfc_mbx_set_link_diag_loopback link_diag_loopback; @@ -4261,6 +4116,8 @@ #define LPFC_SLI_EVENT_TYPE_DIAG_DUMP 0x5 #define LPFC_SLI_EVENT_TYPE_MISCONFIGURED 0x9 #define LPFC_SLI_EVENT_TYPE_REMOTE_DPORT 0xA +#define LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN 0xF +#define LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE 0x10 }; /* @@ -4421,6 +4278,9 @@ #define wqe_sup_SHIFT 6 #define wqe_sup_MASK 0x00000001 #define wqe_sup_WORD word11 +#define wqe_ffrq_SHIFT 6 +#define wqe_ffrq_MASK 0x00000001 +#define wqe_ffrq_WORD word11 #define wqe_wqec_SHIFT 7 #define wqe_wqec_MASK 0x00000001 #define wqe_wqec_WORD word11 @@ -4659,6 +4519,7 @@ uint32_t rsvd_12_15[4]; /* word 12-15 */ }; +#define INHIBIT_ABORT 1 #define T_REQUEST_TAG 3 #define T_XRI_TAG 1 @@ -4767,6 +4628,23 @@ uint32_t fc_hdr_wd5; /* word 15 */ }; +#define ELS_RDF_REG_TAG_CNT 1 +struct lpfc_els_rdf_reg_desc { + struct fc_df_desc_fpin_reg reg_desc; /* descriptor header */ + __be32 desc_tags[ELS_RDF_REG_TAG_CNT]; + /* tags in reg_desc */ +}; + +struct lpfc_els_rdf_req { + struct fc_els_rdf rdf; /* hdr up to descriptors */ + struct lpfc_els_rdf_reg_desc reg_d1; /* 1st descriptor */ +}; + +struct lpfc_els_rdf_rsp { + struct fc_els_rdf_resp rdf_resp; /* hdr up to descriptors */ + struct lpfc_els_rdf_reg_desc reg_d1; /* 1st descriptor */ +}; + union lpfc_wqe { uint32_t words[16]; struct lpfc_wqe_generic generic; @@ -4807,8 +4685,8 @@ struct send_frame_wqe send_frame; }; -#define MAGIC_NUMER_G6 0xFEAA0003 -#define MAGIC_NUMER_G7 0xFEAA0005 +#define MAGIC_NUMBER_G6 0xFEAA0003 +#define MAGIC_NUMBER_G7 0xFEAA0005 struct lpfc_grp_hdr { uint32_t size; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_init.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include @@ -66,9 +68,13 @@ #include "lpfc_version.h" #include "lpfc_ids.h" +static enum cpuhp_state lpfc_cpuhp_state; /* Used when mapping IRQ vectors in a driver centric manner */ static uint32_t lpfc_present_cpu; +static void __lpfc_cpuhp_remove(struct lpfc_hba *phba); +static void lpfc_cpuhp_remove(struct lpfc_hba *phba); +static void lpfc_cpuhp_add(struct lpfc_hba *phba); static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static int lpfc_post_rcv_buf(struct lpfc_hba *); static int lpfc_sli4_queue_verify(struct lpfc_hba *); @@ -506,21 +512,12 @@ lpfc_sli_read_link_ste(phba); /* Reset the DFT_HBA_Q_DEPTH to the max xri */ - i = (mb->un.varRdConfig.max_xri + 1); - if (phba->cfg_hba_queue_depth > i) { + if (phba->cfg_hba_queue_depth > mb->un.varRdConfig.max_xri) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "3359 HBA queue depth changed from %d to %d\n", - phba->cfg_hba_queue_depth, i); - phba->cfg_hba_queue_depth = i; - } - - /* Reset the DFT_LUN_Q_DEPTH to (max xri >> 3) */ - i = (mb->un.varRdConfig.max_xri >> 3); - if (phba->pport->cfg_lun_queue_depth > i) { - lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "3360 LUN queue depth changed from %d to %d\n", - phba->pport->cfg_lun_queue_depth, i); - phba->pport->cfg_lun_queue_depth = i; + phba->cfg_hba_queue_depth, + mb->un.varRdConfig.max_xri); + phba->cfg_hba_queue_depth = mb->un.varRdConfig.max_xri; } phba->lmt = mb->un.varRdConfig.lmt; @@ -1235,10 +1232,9 @@ struct lpfc_hba, eq_delay_work); struct lpfc_eq_intr_info *eqi, *eqi_new; struct lpfc_queue *eq, *eq_next; - unsigned char *eqcnt = NULL; + unsigned char *ena_delay = NULL; uint32_t usdelay; int i; - bool update = false; if (!phba->cfg_auto_imax || phba->pport->load_flag & FC_UNLOADING) return; @@ -1247,44 +1243,36 @@ phba->pport->fc_flag & FC_OFFLINE_MODE) goto requeue; - eqcnt = kcalloc(num_possible_cpus(), sizeof(unsigned char), - GFP_KERNEL); - if (!eqcnt) + ena_delay = kcalloc(phba->sli4_hba.num_possible_cpu, sizeof(*ena_delay), + GFP_KERNEL); + if (!ena_delay) goto requeue; - if (phba->cfg_irq_chann > 1) { - /* Loop thru all IRQ vectors */ - for (i = 0; i < phba->cfg_irq_chann; i++) { - /* Get the EQ corresponding to the IRQ vector */ - eq = phba->sli4_hba.hba_eq_hdl[i].eq; - if (!eq) - continue; - if (eq->q_mode) { - update = true; - break; - } - if (eqcnt[eq->last_cpu] < 2) - eqcnt[eq->last_cpu]++; + for (i = 0; i < phba->cfg_irq_chann; i++) { + /* Get the EQ corresponding to the IRQ vector */ + eq = phba->sli4_hba.hba_eq_hdl[i].eq; + if (!eq) + continue; + if (eq->q_mode || eq->q_flag & HBA_EQ_DELAY_CHK) { + eq->q_flag &= ~HBA_EQ_DELAY_CHK; + ena_delay[eq->last_cpu] = 1; } - } else - update = true; + } for_each_present_cpu(i) { eqi = per_cpu_ptr(phba->sli4_hba.eq_info, i); - if (!update && eqcnt[i] < 2) { - eqi->icnt = 0; - continue; + if (ena_delay[i]) { + usdelay = (eqi->icnt >> 10) * LPFC_EQ_DELAY_STEP; + if (usdelay > LPFC_MAX_AUTO_EQ_DELAY) + usdelay = LPFC_MAX_AUTO_EQ_DELAY; + } else { + usdelay = 0; } - usdelay = (eqi->icnt / LPFC_IMAX_THRESHOLD) * - LPFC_EQ_DELAY_STEP; - if (usdelay > LPFC_MAX_AUTO_EQ_DELAY) - usdelay = LPFC_MAX_AUTO_EQ_DELAY; - eqi->icnt = 0; list_for_each_entry_safe(eq, eq_next, &eqi->list, cpu_list) { - if (eq->last_cpu != i) { + if (unlikely(eq->last_cpu != i)) { eqi_new = per_cpu_ptr(phba->sli4_hba.eq_info, eq->last_cpu); list_move_tail(&eq->cpu_list, &eqi_new->list); @@ -1296,7 +1284,7 @@ } } - kfree(eqcnt); + kfree(ena_delay); requeue: queue_delayed_work(phba->wq, &phba->eq_delay_work, @@ -1365,7 +1353,7 @@ if (vports != NULL) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { lpfc_rcv_seq_check_edtov(vports[i]); - lpfc_fdmi_num_disc_check(vports[i]); + lpfc_fdmi_change_check(vports[i]); } lpfc_destroy_vport_work_array(phba, vports); @@ -3053,11 +3041,12 @@ continue; } ndlp->nlp_rpi = rpi; - lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "0009 rpi:%x DID:%x " - "flg:%x map:%x x%px\n", ndlp->nlp_rpi, - ndlp->nlp_DID, ndlp->nlp_flag, - ndlp->nlp_usg_map, ndlp); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, + "0009 Assign RPI x%x to ndlp x%px " + "DID:x%06x flg:x%x map:x%x\n", + ndlp->nlp_rpi, ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, ndlp->nlp_usg_map); } } lpfc_destroy_vport_work_array(phba, vports); @@ -3387,6 +3376,8 @@ if (phba->cfg_xri_rebalancing) lpfc_create_multixri_pools(phba); + lpfc_cpuhp_add(phba); + lpfc_unblock_mgmt_io(phba); return 0; } @@ -3453,10 +3444,15 @@ list_for_each_entry_safe(ndlp, next_ndlp, &vports[i]->fc_nodes, nlp_listp) { - if (!NLP_CHK_NODE_ACT(ndlp)) - continue; - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) + if ((!NLP_CHK_NODE_ACT(ndlp)) || + ndlp->nlp_state == NLP_STE_UNUSED_NODE) { + /* Driver must assume RPI is invalid for + * any unused or inactive node. + */ + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; continue; + } + if (ndlp->nlp_type & NLP_FABRIC) { lpfc_disc_state_machine(vports[i], ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); @@ -3472,16 +3468,16 @@ * comes back online. */ if (phba->sli_rev == LPFC_SLI_REV4) { - lpfc_printf_vlog(ndlp->vport, - KERN_INFO, LOG_NODE, - "0011 lpfc_offline: " - "ndlp:x%px did %x " - "usgmap:x%x rpi:%x\n", - ndlp, ndlp->nlp_DID, - ndlp->nlp_usg_map, - ndlp->nlp_rpi); - + lpfc_printf_vlog(ndlp->vport, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, + "0011 Free RPI x%x on " + "ndlp:x%px did x%x " + "usgmap:x%x\n", + ndlp->nlp_rpi, ndlp, + ndlp->nlp_DID, + ndlp->nlp_usg_map); lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); + ndlp->nlp_rpi = LPFC_RPI_ALLOC_ERROR; } lpfc_unreg_rpi(vports[i], ndlp); } @@ -3545,6 +3541,7 @@ spin_unlock_irq(shost->host_lock); } lpfc_destroy_vport_work_array(phba, vports); + __lpfc_cpuhp_remove(phba); if (phba->cfg_xri_rebalancing) lpfc_destroy_multixri_pools(phba); @@ -5283,10 +5280,10 @@ evt_type = bf_get(lpfc_trailer_type, acqe_sli); lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "2901 Async SLI event - Event Data1:x%08x Event Data2:" - "x%08x SLI Event Type:%d\n", + "2901 Async SLI event - Type:%d, Event Data: x%08x " + "x%08x x%08x x%08x\n", evt_type, acqe_sli->event_data1, acqe_sli->event_data2, - evt_type); + acqe_sli->reserved, acqe_sli->trailer); port_name = phba->Port[0]; if (port_name == 0x00) @@ -5433,11 +5430,26 @@ "Event Data1:x%08x Event Data2: x%08x\n", acqe_sli->event_data1, acqe_sli->event_data2); break; + case LPFC_SLI_EVENT_TYPE_MISCONF_FAWWN: + /* Misconfigured WWN. Reports that the SLI Port is configured + * to use FA-WWN, but the attached device doesn’t support it. + * No driver action is required. + * Event Data1 - N.A, Event Data2 - N.A + */ + lpfc_log_msg(phba, KERN_WARNING, LOG_SLI, + "2699 Misconfigured FA-WWN - Attached device does " + "not support FA-WWN\n"); + break; + case LPFC_SLI_EVENT_TYPE_EEPROM_FAILURE: + /* EEPROM failure. No driver action is required */ + lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, + "2518 EEPROM failure - " + "Event Data1: x%08x Event Data2: x%08x\n", + acqe_sli->event_data1, acqe_sli->event_data2); + break; default: lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "3193 Async SLI event - Event Data1:x%08x Event Data2:" - "x%08x SLI Event Type:%d\n", - acqe_sli->event_data1, acqe_sli->event_data2, + "3193 Unrecognized SLI event, type: 0x%x", evt_type); break; } @@ -5976,6 +5988,29 @@ } /** + * lpfc_cpumask_of_node_init - initalizes cpumask of phba's NUMA node + * @phba: Pointer to HBA context object. + * + **/ +static void +lpfc_cpumask_of_node_init(struct lpfc_hba *phba) +{ + unsigned int cpu, numa_node; + struct cpumask *numa_mask = &phba->sli4_hba.numa_mask; + + cpumask_clear(numa_mask); + + /* Check if we're a NUMA architecture */ + numa_node = dev_to_node(&phba->pcidev->dev); + if (numa_node == NUMA_NO_NODE) + return; + + for_each_possible_cpu(cpu) + if (cpu_to_node(cpu) == numa_node) + cpumask_set_cpu(cpu, numa_mask); +} + +/** * lpfc_enable_pci_dev - Enable a generic PCI device. * @phba: pointer to lpfc hba data structure. * @@ -6407,8 +6442,6 @@ LPFC_MBOXQ_t *mboxq; MAILBOX_t *mb; int rc, i, max_buf_size; - uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; - struct lpfc_mqe *mqe; int longs; int extra; uint64_t wwn; @@ -6416,8 +6449,9 @@ u32 if_fam; phba->sli4_hba.num_present_cpu = lpfc_present_cpu; - phba->sli4_hba.num_possible_cpu = num_possible_cpus(); + phba->sli4_hba.num_possible_cpu = cpumask_last(cpu_possible_mask) + 1; phba->sli4_hba.curr_disp_cpu = 0; + lpfc_cpumask_of_node_init(phba); /* Get all the module params for configuring this host */ lpfc_get_cfgparam(phba); @@ -6531,7 +6565,7 @@ /* Allocate device driver memory */ rc = lpfc_mem_alloc(phba, SGL_ALIGN_SZ); if (rc) - return -ENOMEM; + goto out_destroy_workqueue; /* IF Type 2 ports get initialized now. */ if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= @@ -6632,32 +6666,6 @@ lpfc_nvme_mod_param_dep(phba); - /* Get the Supported Pages if PORT_CAPABILITIES is supported by port. */ - lpfc_supported_pages(mboxq); - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - if (!rc) { - mqe = &mboxq->u.mqe; - memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3), - LPFC_MAX_SUPPORTED_PAGES); - for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) { - switch (pn_page[i]) { - case LPFC_SLI4_PARAMETERS: - phba->sli4_hba.pc_sli4_params.supported = 1; - break; - default: - break; - } - } - /* Read the port's SLI4 Parameters capabilities if supported. */ - if (phba->sli4_hba.pc_sli4_params.supported) - rc = lpfc_pc_sli4_params_get(phba, mboxq); - if (rc) { - mempool_free(mboxq, phba->mbox_mem_pool); - rc = -EIO; - goto out_free_bsmbx; - } - } - /* * Get sli4 parameters that override parameters from Port capabilities. * If this call fails, it isn't critical unless the SLI4 parameters come @@ -6931,6 +6939,9 @@ lpfc_destroy_bootstrap_mbox(phba); out_free_mem: lpfc_mem_free(phba); +out_destroy_workqueue: + destroy_workqueue(phba->wq); + phba->wq = NULL; return rc; } @@ -6953,6 +6964,7 @@ phba->sli4_hba.num_possible_cpu = 0; phba->sli4_hba.num_present_cpu = 0; phba->sli4_hba.curr_disp_cpu = 0; + cpumask_clear(&phba->sli4_hba.numa_mask); /* Free memory allocated for fast-path work queue handles */ kfree(phba->sli4_hba.hba_eq_hdl); @@ -7126,7 +7138,7 @@ if (iocbq_entry == NULL) { printk(KERN_ERR "%s: only allocated %d iocbs of " "expected %d count. Unloading driver.\n", - __func__, i, LPFC_IOCB_LIST_CNT); + __func__, i, iocb_count); goto out_free_iocbq; } @@ -7545,18 +7557,10 @@ if (phba->nvmet_support) { /* Only 1 vport (pport) will support NVME target */ - if (phba->txrdy_payload_pool == NULL) { - phba->txrdy_payload_pool = dma_pool_create( - "txrdy_pool", &phba->pcidev->dev, - TXRDY_PAYLOAD_LEN, 16, 0); - if (phba->txrdy_payload_pool) { - phba->targetport = NULL; - phba->cfg_enable_fc4_type = LPFC_ENABLE_NVME; - lpfc_printf_log(phba, KERN_INFO, - LOG_INIT | LOG_NVME_DISC, - "6076 NVME Target Found\n"); - } - } + phba->targetport = NULL; + phba->cfg_enable_fc4_type = LPFC_ENABLE_NVME; + lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME_DISC, + "6076 NVME Target Found\n"); } lpfc_debugfs_initialize(vport); @@ -8235,6 +8239,86 @@ memset(&phba->sli4_hba.bmbx, 0, sizeof(struct lpfc_bmbx)); } +static const char * const lpfc_topo_to_str[] = { + "Loop then P2P", + "Loopback", + "P2P Only", + "Unsupported", + "Loop Only", + "Unsupported", + "P2P then Loop", +}; + +/** + * lpfc_map_topology - Map the topology read from READ_CONFIG + * @phba: pointer to lpfc hba data structure. + * @rdconf: pointer to read config data + * + * This routine is invoked to map the topology values as read + * from the read config mailbox command. If the persistent + * topology feature is supported, the firmware will provide the + * saved topology information to be used in INIT_LINK + * + **/ +#define LINK_FLAGS_DEF 0x0 +#define LINK_FLAGS_P2P 0x1 +#define LINK_FLAGS_LOOP 0x2 +static void +lpfc_map_topology(struct lpfc_hba *phba, struct lpfc_mbx_read_config *rd_config) +{ + u8 ptv, tf, pt; + + ptv = bf_get(lpfc_mbx_rd_conf_ptv, rd_config); + tf = bf_get(lpfc_mbx_rd_conf_tf, rd_config); + pt = bf_get(lpfc_mbx_rd_conf_pt, rd_config); + + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "2027 Read Config Data : ptv:0x%x, tf:0x%x pt:0x%x", + ptv, tf, pt); + if (!ptv) { + lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, + "2019 FW does not support persistent topology " + "Using driver parameter defined value [%s]", + lpfc_topo_to_str[phba->cfg_topology]); + return; + } + /* FW supports persistent topology - override module parameter value */ + phba->hba_flag |= HBA_PERSISTENT_TOPO; + switch (phba->pcidev->device) { + case PCI_DEVICE_ID_LANCER_G7_FC: + case PCI_DEVICE_ID_LANCER_G6_FC: + if (!tf) { + phba->cfg_topology = ((pt == LINK_FLAGS_LOOP) + ? FLAGS_TOPOLOGY_MODE_LOOP + : FLAGS_TOPOLOGY_MODE_PT_PT); + } else { + phba->hba_flag &= ~HBA_PERSISTENT_TOPO; + } + break; + default: /* G5 */ + if (tf) { + /* If topology failover set - pt is '0' or '1' */ + phba->cfg_topology = (pt ? FLAGS_TOPOLOGY_MODE_PT_LOOP : + FLAGS_TOPOLOGY_MODE_LOOP_PT); + } else { + phba->cfg_topology = ((pt == LINK_FLAGS_P2P) + ? FLAGS_TOPOLOGY_MODE_PT_PT + : FLAGS_TOPOLOGY_MODE_LOOP); + } + break; + } + if (phba->hba_flag & HBA_PERSISTENT_TOPO) { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "2020 Using persistent topology value [%s]", + lpfc_topo_to_str[phba->cfg_topology]); + } else { + lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, + "2021 Invalid topology values from FW " + "Using driver parameter defined value [%s]", + lpfc_topo_to_str[phba->cfg_topology]); + } +} + /** * lpfc_sli4_read_config - Get the config parameters. * @phba: pointer to lpfc hba data structure. @@ -8346,6 +8430,7 @@ phba->max_vpi = (phba->sli4_hba.max_cfg_param.max_vpi > 0) ? (phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0; phba->max_vports = phba->max_vpi; + lpfc_map_topology(phba, rd_config); lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "2003 cfg params Extents? %d " "XRI(B:%d M:%d), " @@ -8619,8 +8704,8 @@ */ if (phba->nvmet_support) { - if (phba->cfg_irq_chann < phba->cfg_nvmet_mrq) - phba->cfg_nvmet_mrq = phba->cfg_irq_chann; + if (phba->cfg_hdw_queue < phba->cfg_nvmet_mrq) + phba->cfg_nvmet_mrq = phba->cfg_hdw_queue; if (phba->cfg_nvmet_mrq > LPFC_NVMET_MRQ_MAX) phba->cfg_nvmet_mrq = LPFC_NVMET_MRQ_MAX; } @@ -9116,6 +9201,7 @@ /* Free the CQ/WQ corresponding to the Hardware Queue */ lpfc_sli4_queue_free(hdwq[idx].io_cq); lpfc_sli4_queue_free(hdwq[idx].io_wq); + hdwq[idx].hba_eq = NULL; hdwq[idx].io_cq = NULL; hdwq[idx].io_wq = NULL; if (phba->cfg_xpsgl && !phba->nvmet_support) @@ -9160,6 +9246,8 @@ } spin_unlock_irq(&phba->hbalock); + lpfc_sli4_cleanup_poll_list(phba); + /* Release HBA eqs */ if (phba->sli4_hba.hdwq) lpfc_sli4_release_hdwq(phba); @@ -9376,8 +9464,7 @@ "3250 QUERY_FW_CFG mailbox failed with status " "x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); rc = -ENXIO; goto out_error; } @@ -9393,8 +9480,7 @@ "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode, phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); /* * Set up HBA Event Queues (EQs) @@ -9990,8 +10076,7 @@ shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0495 SLI_FUNCTION_RESET mailbox " @@ -10243,7 +10328,7 @@ goto out_iounmap_all; } else { error = -ENOMEM; - goto out_iounmap_all; + goto out_iounmap_ctrl; } } @@ -10261,7 +10346,7 @@ dev_err(&pdev->dev, "ioremap failed for SLI4 HBA dpp registers.\n"); error = -ENOMEM; - goto out_iounmap_ctrl; + goto out_iounmap_all; } phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p; } @@ -10286,9 +10371,11 @@ return 0; out_iounmap_all: - iounmap(phba->sli4_hba.drbl_regs_memmap_p); + if (phba->sli4_hba.drbl_regs_memmap_p) + iounmap(phba->sli4_hba.drbl_regs_memmap_p); out_iounmap_ctrl: - iounmap(phba->sli4_hba.ctrl_regs_memmap_p); + if (phba->sli4_hba.ctrl_regs_memmap_p) + iounmap(phba->sli4_hba.ctrl_regs_memmap_p); out_iounmap_conf: iounmap(phba->sli4_hba.conf_regs_memmap_p); @@ -10320,6 +10407,8 @@ case LPFC_SLI_INTF_IF_TYPE_6: iounmap(phba->sli4_hba.drbl_regs_memmap_p); iounmap(phba->sli4_hba.conf_regs_memmap_p); + if (phba->sli4_hba.dpp_regs_memmap_p) + iounmap(phba->sli4_hba.dpp_regs_memmap_p); break; case LPFC_SLI_INTF_IF_TYPE_1: default: @@ -10581,7 +10670,6 @@ */ if ((match == LPFC_FIND_BY_EQ) && (cpup->flag & LPFC_CPU_FIRST_IRQ) && - (cpup->irq != LPFC_VECTOR_MAP_EMPTY) && (cpup->eq == id)) return cpu; @@ -10619,6 +10707,75 @@ } #endif +/* + * lpfc_assign_eq_map_info - Assigns eq for vector_map structure + * @phba: pointer to lpfc hba data structure. + * @eqidx: index for eq and irq vector + * @flag: flags to set for vector_map structure + * @cpu: cpu used to index vector_map structure + * + * The routine assigns eq info into vector_map structure + */ +static inline void +lpfc_assign_eq_map_info(struct lpfc_hba *phba, uint16_t eqidx, uint16_t flag, + unsigned int cpu) +{ + struct lpfc_vector_map_info *cpup = &phba->sli4_hba.cpu_map[cpu]; + struct lpfc_hba_eq_hdl *eqhdl = lpfc_get_eq_hdl(eqidx); + + cpup->eq = eqidx; + cpup->flag |= flag; + + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3336 Set Affinity: CPU %d irq %d eq %d flag x%x\n", + cpu, eqhdl->irq, cpup->eq, cpup->flag); +} + +/** + * lpfc_cpu_map_array_init - Initialize cpu_map structure + * @phba: pointer to lpfc hba data structure. + * + * The routine initializes the cpu_map array structure + */ +static void +lpfc_cpu_map_array_init(struct lpfc_hba *phba) +{ + struct lpfc_vector_map_info *cpup; + struct lpfc_eq_intr_info *eqi; + int cpu; + + for_each_possible_cpu(cpu) { + cpup = &phba->sli4_hba.cpu_map[cpu]; + cpup->phys_id = LPFC_VECTOR_MAP_EMPTY; + cpup->core_id = LPFC_VECTOR_MAP_EMPTY; + cpup->hdwq = LPFC_VECTOR_MAP_EMPTY; + cpup->eq = LPFC_VECTOR_MAP_EMPTY; + cpup->flag = 0; + eqi = per_cpu_ptr(phba->sli4_hba.eq_info, cpu); + INIT_LIST_HEAD(&eqi->list); + eqi->icnt = 0; + } +} + +/** + * lpfc_hba_eq_hdl_array_init - Initialize hba_eq_hdl structure + * @phba: pointer to lpfc hba data structure. + * + * The routine initializes the hba_eq_hdl array structure + */ +static void +lpfc_hba_eq_hdl_array_init(struct lpfc_hba *phba) +{ + struct lpfc_hba_eq_hdl *eqhdl; + int i; + + for (i = 0; i < phba->cfg_irq_chann; i++) { + eqhdl = lpfc_get_eq_hdl(i); + eqhdl->irq = LPFC_VECTOR_MAP_EMPTY; + eqhdl->phba = phba; + } +} + /** * lpfc_cpu_affinity_check - Check vector CPU affinity mappings * @phba: pointer to lpfc hba data structure. @@ -10637,22 +10794,10 @@ int max_core_id, min_core_id; struct lpfc_vector_map_info *cpup; struct lpfc_vector_map_info *new_cpup; - const struct cpumask *maskp; #ifdef CONFIG_X86 struct cpuinfo_x86 *cpuinfo; #endif - /* Init cpu_map array */ - for_each_possible_cpu(cpu) { - cpup = &phba->sli4_hba.cpu_map[cpu]; - cpup->phys_id = LPFC_VECTOR_MAP_EMPTY; - cpup->core_id = LPFC_VECTOR_MAP_EMPTY; - cpup->hdwq = LPFC_VECTOR_MAP_EMPTY; - cpup->eq = LPFC_VECTOR_MAP_EMPTY; - cpup->irq = LPFC_VECTOR_MAP_EMPTY; - cpup->flag = 0; - } - max_phys_id = 0; min_phys_id = LPFC_VECTOR_MAP_EMPTY; max_core_id = 0; @@ -10688,65 +10833,6 @@ min_core_id = cpup->core_id; } - for_each_possible_cpu(i) { - struct lpfc_eq_intr_info *eqi = - per_cpu_ptr(phba->sli4_hba.eq_info, i); - - INIT_LIST_HEAD(&eqi->list); - eqi->icnt = 0; - } - - /* This loop sets up all CPUs that are affinitized with a - * irq vector assigned to the driver. All affinitized CPUs - * will get a link to that vectors IRQ and EQ. - * - * NULL affinity mask handling: - * If irq count is greater than one, log an error message. - * If the null mask is received for the first irq, find the - * first present cpu, and assign the eq index to ensure at - * least one EQ is assigned. - */ - for (idx = 0; idx < phba->cfg_irq_chann; idx++) { - /* Get a CPU mask for all CPUs affinitized to this vector */ - maskp = pci_irq_get_affinity(phba->pcidev, idx); - if (!maskp) { - if (phba->cfg_irq_chann > 1) - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3329 No affinity mask found " - "for vector %d (%d)\n", - idx, phba->cfg_irq_chann); - if (!idx) { - cpu = cpumask_first(cpu_present_mask); - cpup = &phba->sli4_hba.cpu_map[cpu]; - cpup->eq = idx; - cpup->irq = pci_irq_vector(phba->pcidev, idx); - cpup->flag |= LPFC_CPU_FIRST_IRQ; - } - break; - } - - i = 0; - /* Loop through all CPUs associated with vector idx */ - for_each_cpu_and(cpu, maskp, cpu_present_mask) { - /* Set the EQ index and IRQ for that vector */ - cpup = &phba->sli4_hba.cpu_map[cpu]; - cpup->eq = idx; - cpup->irq = pci_irq_vector(phba->pcidev, idx); - - /* If this is the first CPU thats assigned to this - * vector, set LPFC_CPU_FIRST_IRQ. - */ - if (!i) - cpup->flag |= LPFC_CPU_FIRST_IRQ; - i++; - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3336 Set Affinity: CPU %d " - "irq %d eq %d flag x%x\n", - cpu, cpup->irq, cpup->eq, cpup->flag); - } - } - /* After looking at each irq vector assigned to this pcidev, its * possible to see that not ALL CPUs have been accounted for. * Next we will set any unassigned (unaffinitized) cpu map @@ -10772,7 +10858,7 @@ for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; if (!(new_cpup->flag & LPFC_CPU_MAP_UNASSIGN) && - (new_cpup->irq != LPFC_VECTOR_MAP_EMPTY) && + (new_cpup->eq != LPFC_VECTOR_MAP_EMPTY) && (new_cpup->phys_id == cpup->phys_id)) goto found_same; new_cpu = cpumask_next( @@ -10785,7 +10871,6 @@ found_same: /* We found a matching phys_id, so copy the IRQ info */ cpup->eq = new_cpup->eq; - cpup->irq = new_cpup->irq; /* Bump start_cpu to the next slot to minmize the * chance of having multiple unassigned CPU entries @@ -10797,9 +10882,10 @@ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "3337 Set Affinity: CPU %d " - "irq %d from id %d same " + "eq %d from peer cpu %d same " "phys_id (%d)\n", - cpu, cpup->irq, new_cpu, cpup->phys_id); + cpu, cpup->eq, new_cpu, + cpup->phys_id); } } @@ -10823,7 +10909,7 @@ for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { new_cpup = &phba->sli4_hba.cpu_map[new_cpu]; if (!(new_cpup->flag & LPFC_CPU_MAP_UNASSIGN) && - (new_cpup->irq != LPFC_VECTOR_MAP_EMPTY)) + (new_cpup->eq != LPFC_VECTOR_MAP_EMPTY)) goto found_any; new_cpu = cpumask_next( new_cpu, cpu_present_mask); @@ -10833,13 +10919,12 @@ /* We should never leave an entry unassigned */ lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3339 Set Affinity: CPU %d " - "irq %d UNASSIGNED\n", - cpup->hdwq, cpup->irq); + "eq %d UNASSIGNED\n", + cpup->hdwq, cpup->eq); continue; found_any: /* We found an available entry, copy the IRQ info */ cpup->eq = new_cpup->eq; - cpup->irq = new_cpup->irq; /* Bump start_cpu to the next slot to minmize the * chance of having multiple unassigned CPU entries @@ -10851,8 +10936,8 @@ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "3338 Set Affinity: CPU %d " - "irq %d from id %d (%d/%d)\n", - cpu, cpup->irq, new_cpu, + "eq %d from peer cpu %d (%d/%d)\n", + cpu, cpup->eq, new_cpu, new_cpup->phys_id, new_cpup->core_id); } } @@ -10873,11 +10958,11 @@ idx++; lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3333 Set Affinity: CPU %d (phys %d core %d): " - "hdwq %d eq %d irq %d flg x%x\n", + "hdwq %d eq %d flg x%x\n", cpu, cpup->phys_id, cpup->core_id, - cpup->hdwq, cpup->eq, cpup->irq, cpup->flag); + cpup->hdwq, cpup->eq, cpup->flag); } - /* Finally we need to associate a hdwq with each cpu_map entry + /* Associate a hdwq with each cpu_map entry * This will be 1 to 1 - hdwq to cpu, unless there are less * hardware queues then CPUs. For that case we will just round-robin * the available hardware queues as they get assigned to CPUs. @@ -10951,9 +11036,26 @@ logit: lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3335 Set Affinity: CPU %d (phys %d core %d): " - "hdwq %d eq %d irq %d flg x%x\n", + "hdwq %d eq %d flg x%x\n", cpu, cpup->phys_id, cpup->core_id, - cpup->hdwq, cpup->eq, cpup->irq, cpup->flag); + cpup->hdwq, cpup->eq, cpup->flag); + } + + /* + * Initialize the cpu_map slots for not-present cpus in case + * a cpu is hot-added. Perform a simple hdwq round robin assignment. + */ + idx = 0; + for_each_possible_cpu(cpu) { + cpup = &phba->sli4_hba.cpu_map[cpu]; + if (cpup->hdwq != LPFC_VECTOR_MAP_EMPTY) + continue; + + cpup->hdwq = idx++ % phba->cfg_hdw_queue; + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, + "3340 Set Affinity: not present " + "CPU %d hdwq %d\n", + cpu, cpup->hdwq); } /* The cpu_map array will be used later during initialization @@ -10963,11 +11065,288 @@ } /** + * lpfc_cpuhp_get_eq + * + * @phba: pointer to lpfc hba data structure. + * @cpu: cpu going offline + * @eqlist: + */ +static int +lpfc_cpuhp_get_eq(struct lpfc_hba *phba, unsigned int cpu, + struct list_head *eqlist) +{ + const struct cpumask *maskp; + struct lpfc_queue *eq; + struct cpumask *tmp; + u16 idx; + + tmp = kzalloc(cpumask_size(), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + for (idx = 0; idx < phba->cfg_irq_chann; idx++) { + maskp = pci_irq_get_affinity(phba->pcidev, idx); + if (!maskp) + continue; + /* + * if irq is not affinitized to the cpu going + * then we don't need to poll the eq attached + * to it. + */ + if (!cpumask_and(tmp, maskp, cpumask_of(cpu))) + continue; + /* get the cpus that are online and are affini- + * tized to this irq vector. If the count is + * more than 1 then cpuhp is not going to shut- + * down this vector. Since this cpu has not + * gone offline yet, we need >1. + */ + cpumask_and(tmp, maskp, cpu_online_mask); + if (cpumask_weight(tmp) > 1) + continue; + + /* Now that we have an irq to shutdown, get the eq + * mapped to this irq. Note: multiple hdwq's in + * the software can share an eq, but eventually + * only eq will be mapped to this vector + */ + eq = phba->sli4_hba.hba_eq_hdl[idx].eq; + list_add(&eq->_poll_list, eqlist); + } + kfree(tmp); + return 0; +} + +static void __lpfc_cpuhp_remove(struct lpfc_hba *phba) +{ + if (phba->sli_rev != LPFC_SLI_REV4) + return; + + cpuhp_state_remove_instance_nocalls(lpfc_cpuhp_state, + &phba->cpuhp); + /* + * unregistering the instance doesn't stop the polling + * timer. Wait for the poll timer to retire. + */ + synchronize_rcu(); + del_timer_sync(&phba->cpuhp_poll_timer); +} + +static void lpfc_cpuhp_remove(struct lpfc_hba *phba) +{ + if (phba->pport->fc_flag & FC_OFFLINE_MODE) + return; + + __lpfc_cpuhp_remove(phba); +} + +static void lpfc_cpuhp_add(struct lpfc_hba *phba) +{ + if (phba->sli_rev != LPFC_SLI_REV4) + return; + + rcu_read_lock(); + + if (!list_empty(&phba->poll_list)) { + timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0); + mod_timer(&phba->cpuhp_poll_timer, + jiffies + msecs_to_jiffies(LPFC_POLL_HB)); + } + + rcu_read_unlock(); + + cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state, + &phba->cpuhp); +} + +static int __lpfc_cpuhp_checks(struct lpfc_hba *phba, int *retval) +{ + if (phba->pport->load_flag & FC_UNLOADING) { + *retval = -EAGAIN; + return true; + } + + if (phba->sli_rev != LPFC_SLI_REV4) { + *retval = 0; + return true; + } + + /* proceed with the hotplug */ + return false; +} + +/** + * lpfc_irq_set_aff - set IRQ affinity + * @eqhdl: EQ handle + * @cpu: cpu to set affinity + * + **/ +static inline void +lpfc_irq_set_aff(struct lpfc_hba_eq_hdl *eqhdl, unsigned int cpu) +{ + cpumask_clear(&eqhdl->aff_mask); + cpumask_set_cpu(cpu, &eqhdl->aff_mask); + irq_set_status_flags(eqhdl->irq, IRQ_NO_BALANCING); + irq_set_affinity_hint(eqhdl->irq, &eqhdl->aff_mask); +} + +/** + * lpfc_irq_clear_aff - clear IRQ affinity + * @eqhdl: EQ handle + * + **/ +static inline void +lpfc_irq_clear_aff(struct lpfc_hba_eq_hdl *eqhdl) +{ + cpumask_clear(&eqhdl->aff_mask); + irq_clear_status_flags(eqhdl->irq, IRQ_NO_BALANCING); + irq_set_affinity_hint(eqhdl->irq, &eqhdl->aff_mask); +} + +/** + * lpfc_irq_rebalance - rebalances IRQ affinity according to cpuhp event + * @phba: pointer to HBA context object. + * @cpu: cpu going offline/online + * @offline: true, cpu is going offline. false, cpu is coming online. + * + * If cpu is going offline, we'll try our best effort to find the next + * online cpu on the phba's NUMA node and migrate all offlining IRQ affinities. + * + * If cpu is coming online, reaffinitize the IRQ back to the onlineng cpu. + * + * Note: Call only if cfg_irq_numa is enabled, otherwise rely on + * PCI_IRQ_AFFINITY to auto-manage IRQ affinity. + * + **/ +static void +lpfc_irq_rebalance(struct lpfc_hba *phba, unsigned int cpu, bool offline) +{ + struct lpfc_vector_map_info *cpup; + struct cpumask *aff_mask; + unsigned int cpu_select, cpu_next, idx; + const struct cpumask *numa_mask; + + if (!phba->cfg_irq_numa) + return; + + numa_mask = &phba->sli4_hba.numa_mask; + + if (!cpumask_test_cpu(cpu, numa_mask)) + return; + + cpup = &phba->sli4_hba.cpu_map[cpu]; + + if (!(cpup->flag & LPFC_CPU_FIRST_IRQ)) + return; + + if (offline) { + /* Find next online CPU on NUMA node */ + cpu_next = cpumask_next_wrap(cpu, numa_mask, cpu, true); + cpu_select = lpfc_next_online_numa_cpu(numa_mask, cpu_next); + + /* Found a valid CPU */ + if ((cpu_select < nr_cpu_ids) && (cpu_select != cpu)) { + /* Go through each eqhdl and ensure offlining + * cpu aff_mask is migrated + */ + for (idx = 0; idx < phba->cfg_irq_chann; idx++) { + aff_mask = lpfc_get_aff_mask(idx); + + /* Migrate affinity */ + if (cpumask_test_cpu(cpu, aff_mask)) + lpfc_irq_set_aff(lpfc_get_eq_hdl(idx), + cpu_select); + } + } else { + /* Rely on irqbalance if no online CPUs left on NUMA */ + for (idx = 0; idx < phba->cfg_irq_chann; idx++) + lpfc_irq_clear_aff(lpfc_get_eq_hdl(idx)); + } + } else { + /* Migrate affinity back to this CPU */ + lpfc_irq_set_aff(lpfc_get_eq_hdl(cpup->eq), cpu); + } +} + +static int lpfc_cpu_offline(unsigned int cpu, struct hlist_node *node) +{ + struct lpfc_hba *phba = hlist_entry_safe(node, struct lpfc_hba, cpuhp); + struct lpfc_queue *eq, *next; + LIST_HEAD(eqlist); + int retval; + + if (!phba) { + WARN_ONCE(!phba, "cpu: %u. phba:NULL", raw_smp_processor_id()); + return 0; + } + + if (__lpfc_cpuhp_checks(phba, &retval)) + return retval; + + lpfc_irq_rebalance(phba, cpu, true); + + retval = lpfc_cpuhp_get_eq(phba, cpu, &eqlist); + if (retval) + return retval; + + /* start polling on these eq's */ + list_for_each_entry_safe(eq, next, &eqlist, _poll_list) { + list_del_init(&eq->_poll_list); + lpfc_sli4_start_polling(eq); + } + + return 0; +} + +static int lpfc_cpu_online(unsigned int cpu, struct hlist_node *node) +{ + struct lpfc_hba *phba = hlist_entry_safe(node, struct lpfc_hba, cpuhp); + struct lpfc_queue *eq, *next; + unsigned int n; + int retval; + + if (!phba) { + WARN_ONCE(!phba, "cpu: %u. phba:NULL", raw_smp_processor_id()); + return 0; + } + + if (__lpfc_cpuhp_checks(phba, &retval)) + return retval; + + lpfc_irq_rebalance(phba, cpu, false); + + list_for_each_entry_safe(eq, next, &phba->poll_list, _poll_list) { + n = lpfc_find_cpu_handle(phba, eq->hdwq, LPFC_FIND_BY_HDWQ); + if (n == cpu) + lpfc_sli4_stop_polling(eq); + } + + return 0; +} + +/** * lpfc_sli4_enable_msix - Enable MSI-X interrupt mode to SLI-4 device * @phba: pointer to lpfc hba data structure. * * This routine is invoked to enable the MSI-X interrupt vectors to device - * with SLI-4 interface spec. + * with SLI-4 interface spec. It also allocates MSI-X vectors and maps them + * to cpus on the system. + * + * When cfg_irq_numa is enabled, the adapter will only allocate vectors for + * the number of cpus on the same numa node as this adapter. The vectors are + * allocated without requesting OS affinity mapping. A vector will be + * allocated and assigned to each online and offline cpu. If the cpu is + * online, then affinity will be set to that cpu. If the cpu is offline, then + * affinity will be set to the nearest peer cpu within the numa node that is + * online. If there are no online cpus within the numa node, affinity is not + * assigned and the OS may do as it pleases. Note: cpu vector affinity mapping + * is consistent with the way cpu online/offline is handled when cfg_irq_numa is + * configured. + * + * If numa mode is not enabled and there is more than 1 vector allocated, then + * the driver relies on the managed irq interface where the OS assigns vector to + * cpu affinity. The driver will then use that affinity mapping to setup its + * cpu mapping table. * * Return codes * 0 - successful @@ -10978,13 +11357,31 @@ { int vectors, rc, index; char *name; + const struct cpumask *numa_mask = NULL; + unsigned int cpu = 0, cpu_cnt = 0, cpu_select = nr_cpu_ids; + struct lpfc_hba_eq_hdl *eqhdl; + const struct cpumask *maskp; + bool first; + unsigned int flags = PCI_IRQ_MSIX; /* Set up MSI-X multi-message vectors */ vectors = phba->cfg_irq_chann; - rc = pci_alloc_irq_vectors(phba->pcidev, - 1, - vectors, PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); + if (phba->cfg_irq_numa) { + numa_mask = &phba->sli4_hba.numa_mask; + cpu_cnt = cpumask_weight(numa_mask); + vectors = min(phba->cfg_irq_chann, cpu_cnt); + + /* cpu: iterates over numa_mask including offline or online + * cpu_select: iterates over online numa_mask to set affinity + */ + cpu = cpumask_first(numa_mask); + cpu_select = lpfc_next_online_numa_cpu(numa_mask, cpu); + } else { + flags |= PCI_IRQ_AFFINITY; + } + + rc = pci_alloc_irq_vectors(phba->pcidev, 1, vectors, flags); if (rc < 0) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0484 PCI enable MSI-X failed (%d)\n", rc); @@ -10994,23 +11391,61 @@ /* Assign MSI-X vectors to interrupt handlers */ for (index = 0; index < vectors; index++) { - name = phba->sli4_hba.hba_eq_hdl[index].handler_name; + eqhdl = lpfc_get_eq_hdl(index); + name = eqhdl->handler_name; memset(name, 0, LPFC_SLI4_HANDLER_NAME_SZ); snprintf(name, LPFC_SLI4_HANDLER_NAME_SZ, LPFC_DRIVER_HANDLER_NAME"%d", index); - phba->sli4_hba.hba_eq_hdl[index].idx = index; - phba->sli4_hba.hba_eq_hdl[index].phba = phba; + eqhdl->idx = index; rc = request_irq(pci_irq_vector(phba->pcidev, index), &lpfc_sli4_hba_intr_handler, 0, - name, - &phba->sli4_hba.hba_eq_hdl[index]); + name, eqhdl); if (rc) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "0486 MSI-X fast-path (%d) " "request_irq failed (%d)\n", index, rc); goto cfg_fail_out; } + + eqhdl->irq = pci_irq_vector(phba->pcidev, index); + + if (phba->cfg_irq_numa) { + /* If found a neighboring online cpu, set affinity */ + if (cpu_select < nr_cpu_ids) + lpfc_irq_set_aff(eqhdl, cpu_select); + + /* Assign EQ to cpu_map */ + lpfc_assign_eq_map_info(phba, index, + LPFC_CPU_FIRST_IRQ, + cpu); + + /* Iterate to next offline or online cpu in numa_mask */ + cpu = cpumask_next(cpu, numa_mask); + + /* Find next online cpu in numa_mask to set affinity */ + cpu_select = lpfc_next_online_numa_cpu(numa_mask, cpu); + } else if (vectors == 1) { + cpu = cpumask_first(cpu_present_mask); + lpfc_assign_eq_map_info(phba, index, LPFC_CPU_FIRST_IRQ, + cpu); + } else { + maskp = pci_irq_get_affinity(phba->pcidev, index); + + first = true; + /* Loop through all CPUs associated with vector index */ + for_each_cpu_and(cpu, maskp, cpu_present_mask) { + /* If this is the first CPU thats assigned to + * this vector, set LPFC_CPU_FIRST_IRQ. + */ + lpfc_assign_eq_map_info(phba, index, + first ? + LPFC_CPU_FIRST_IRQ : 0, + cpu); + if (first) + first = false; + } + } } if (vectors != phba->cfg_irq_chann) { @@ -11020,17 +11455,18 @@ phba->cfg_irq_chann, vectors); if (phba->cfg_irq_chann > vectors) phba->cfg_irq_chann = vectors; - if (phba->nvmet_support && (phba->cfg_nvmet_mrq > vectors)) - phba->cfg_nvmet_mrq = vectors; } return rc; cfg_fail_out: /* free the irq already requested */ - for (--index; index >= 0; index--) - free_irq(pci_irq_vector(phba->pcidev, index), - &phba->sli4_hba.hba_eq_hdl[index]); + for (--index; index >= 0; index--) { + eqhdl = lpfc_get_eq_hdl(index); + lpfc_irq_clear_aff(eqhdl); + irq_set_affinity_hint(eqhdl->irq, NULL); + free_irq(eqhdl->irq, eqhdl); + } /* Unconfigure MSI-X capability structure */ pci_free_irq_vectors(phba->pcidev); @@ -11057,6 +11493,8 @@ lpfc_sli4_enable_msi(struct lpfc_hba *phba) { int rc, index; + unsigned int cpu; + struct lpfc_hba_eq_hdl *eqhdl; rc = pci_alloc_irq_vectors(phba->pcidev, 1, 1, PCI_IRQ_MSI | PCI_IRQ_AFFINITY); @@ -11078,9 +11516,15 @@ return rc; } + eqhdl = lpfc_get_eq_hdl(0); + eqhdl->irq = pci_irq_vector(phba->pcidev, 0); + + cpu = cpumask_first(cpu_present_mask); + lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, cpu); + for (index = 0; index < phba->cfg_irq_chann; index++) { - phba->sli4_hba.hba_eq_hdl[index].idx = index; - phba->sli4_hba.hba_eq_hdl[index].phba = phba; + eqhdl = lpfc_get_eq_hdl(index); + eqhdl->idx = index; } return 0; @@ -11138,15 +11582,21 @@ IRQF_SHARED, LPFC_DRIVER_NAME, phba); if (!retval) { struct lpfc_hba_eq_hdl *eqhdl; + unsigned int cpu; /* Indicate initialization to INTx mode */ phba->intr_type = INTx; intr_mode = 0; + eqhdl = lpfc_get_eq_hdl(0); + eqhdl->irq = pci_irq_vector(phba->pcidev, 0); + + cpu = cpumask_first(cpu_present_mask); + lpfc_assign_eq_map_info(phba, 0, LPFC_CPU_FIRST_IRQ, + cpu); for (idx = 0; idx < phba->cfg_irq_chann; idx++) { - eqhdl = &phba->sli4_hba.hba_eq_hdl[idx]; + eqhdl = lpfc_get_eq_hdl(idx); eqhdl->idx = idx; - eqhdl->phba = phba; } } } @@ -11168,14 +11618,14 @@ /* Disable the currently initialized interrupt mode */ if (phba->intr_type == MSIX) { int index; + struct lpfc_hba_eq_hdl *eqhdl; /* Free up MSI-X multi-message vectors */ for (index = 0; index < phba->cfg_irq_chann; index++) { - irq_set_affinity_hint( - pci_irq_vector(phba->pcidev, index), - NULL); - free_irq(pci_irq_vector(phba->pcidev, index), - &phba->sli4_hba.hba_eq_hdl[index]); + eqhdl = lpfc_get_eq_hdl(index); + lpfc_irq_clear_aff(eqhdl); + irq_set_affinity_hint(eqhdl->irq, NULL); + free_irq(eqhdl->irq, eqhdl); } } else { free_irq(phba->pcidev->irq, phba); @@ -11367,6 +11817,10 @@ /* Wait for completion of device XRI exchange busy */ lpfc_sli4_xri_exchange_busy_wait(phba); + /* per-phba callback de-registration for hotplug event */ + if (phba->pport) + lpfc_cpuhp_remove(phba); + /* Disable PCI subsystem interrupt */ lpfc_sli4_disable_intr(phba); @@ -11398,78 +11852,6 @@ phba->pport->work_port_events = 0; } - /** - * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities. - * @phba: Pointer to HBA context object. - * @mboxq: Pointer to the mailboxq memory for the mailbox command response. - * - * This function is called in the SLI4 code path to read the port's - * sli4 capabilities. - * - * This function may be be called from any context that can block-wait - * for the completion. The expectation is that this routine is called - * typically from probe_one or from the online routine. - **/ -int -lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) -{ - int rc; - struct lpfc_mqe *mqe; - struct lpfc_pc_sli4_params *sli4_params; - uint32_t mbox_tmo; - - rc = 0; - mqe = &mboxq->u.mqe; - - /* Read the port's SLI4 Parameters port capabilities */ - lpfc_pc_sli4_params(mboxq); - if (!phba->sli4_hba.intr_enable) - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - else { - mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq); - rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); - } - - if (unlikely(rc)) - return 1; - - sli4_params = &phba->sli4_hba.pc_sli4_params; - sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params); - sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params); - sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params); - sli4_params->featurelevel_1 = bf_get(featurelevel_1, - &mqe->un.sli4_params); - sli4_params->featurelevel_2 = bf_get(featurelevel_2, - &mqe->un.sli4_params); - sli4_params->proto_types = mqe->un.sli4_params.word3; - sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len; - sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params); - sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params); - sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params); - sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params); - sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params); - sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params); - sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params); - sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params); - sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params); - sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params); - sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params); - sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params); - sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params); - sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params); - sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params); - sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params); - sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); - sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); - sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); - - /* Make sure that sge_supp_len can be handled by the driver */ - if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) - sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; - - return rc; -} - /** * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS. * @phba: Pointer to HBA context object. @@ -11528,7 +11910,8 @@ else phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED; sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len; - sli4_params->loopbk_scope = bf_get(loopbk_scope, mbx_sli4_parameters); + sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope, + mbx_sli4_parameters); sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters); sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters); sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters); @@ -11538,6 +11921,7 @@ sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters); sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters); sli4_params->bv1s = bf_get(cfg_bv1s, mbx_sli4_parameters); + sli4_params->pls = bf_get(cfg_pvl, mbx_sli4_parameters); sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt, mbx_sli4_parameters); sli4_params->wqpcnt = bf_get(cfg_wqpcnt, mbx_sli4_parameters); @@ -11589,13 +11973,10 @@ } /* If the NVME FC4 type is enabled, scale the sg_seg_cnt to - * accommodate 512K and 1M IOs in a single nvme buf and supply - * enough NVME LS iocb buffers for larger connectivity counts. + * accommodate 512K and 1M IOs in a single nvme buf. */ - if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { + if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) phba->cfg_sg_seg_cnt = LPFC_MAX_NVME_SEG_CNT; - phba->cfg_iocb_cnt = 5; - } /* Only embed PBDE for if_type 6, PBDE support requires xib be set */ if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != @@ -12312,35 +12693,57 @@ } -static void +static int lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset, uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize, const struct firmware *fw) { - if ((offset == ADD_STATUS_FW_NOT_SUPPORTED) || + int rc; + + /* Three cases: (1) FW was not supported on the detected adapter. + * (2) FW update has been locked out administratively. + * (3) Some other error during FW update. + * In each case, an unmaskable message is written to the console + * for admin diagnosis. + */ + if (offset == ADD_STATUS_FW_NOT_SUPPORTED || (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC && - magic_number != MAGIC_NUMER_G6) || + magic_number != MAGIC_NUMBER_G6) || (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC && - magic_number != MAGIC_NUMER_G7)) + magic_number != MAGIC_NUMBER_G7)) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3030 This firmware version is not supported on " - "this HBA model. Device:%x Magic:%x Type:%x " - "ID:%x Size %d %zd\n", - phba->pcidev->device, magic_number, ftype, fid, - fsize, fw->size); - else + "3030 This firmware version is not supported on" + " this HBA model. Device:%x Magic:%x Type:%x " + "ID:%x Size %d %zd\n", + phba->pcidev->device, magic_number, ftype, fid, + fsize, fw->size); + rc = -EINVAL; + } else if (offset == ADD_STATUS_FW_DOWNLOAD_HW_DISABLED) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3021 Firmware downloads have been prohibited " + "by a system configuration setting on " + "Device:%x Magic:%x Type:%x ID:%x Size %d " + "%zd\n", + phba->pcidev->device, magic_number, ftype, fid, + fsize, fw->size); + rc = -EACCES; + } else { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3022 FW Download failed. Device:%x Magic:%x Type:%x " - "ID:%x Size %d %zd\n", - phba->pcidev->device, magic_number, ftype, fid, - fsize, fw->size); + "3022 FW Download failed. Add Status x%x " + "Device:%x Magic:%x Type:%x ID:%x Size %d " + "%zd\n", + offset, phba->pcidev->device, magic_number, + ftype, fid, fsize, fw->size); + rc = -EIO; + } + return rc; } - /** * lpfc_write_firmware - attempt to write a firmware image to the port * @fw: pointer to firmware image returned from request_firmware. - * @phba: pointer to lpfc hba data structure. + * @context: pointer to firmware image returned from request_firmware. + * @ret: return value this routine provides to the caller. * **/ static void @@ -12409,8 +12812,12 @@ rc = lpfc_wr_object(phba, &dma_buffer_list, (fw->size - offset), &offset); if (rc) { - lpfc_log_write_firmware_error(phba, offset, - magic_number, ftype, fid, fsize, fw); + rc = lpfc_log_write_firmware_error(phba, offset, + magic_number, + ftype, + fid, + fsize, + fw); goto release_out; } } @@ -12430,9 +12837,12 @@ } release_firmware(fw); out: - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3024 Firmware update done: %d.\n", rc); - return; + if (rc < 0) + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3062 Firmware update error, status %d.\n", rc); + else + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, + "3024 Firmware update success: size %d.\n", rc); } /** @@ -12445,7 +12855,7 @@ int lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) { - uint8_t file_name[ELX_MODEL_NAME_SIZE]; + char file_name[ELX_FW_NAME_SIZE] = {0}; int ret; const struct firmware *fw; @@ -12454,7 +12864,7 @@ LPFC_SLI_INTF_IF_TYPE_2) return -EPERM; - snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", phba->ModelName); + scnprintf(file_name, sizeof(file_name), "%s.grp", phba->ModelName); if (fw_upgrade == INT_FW_UPGRADE) { ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, @@ -12551,6 +12961,12 @@ phba->pport = NULL; lpfc_stop_port(phba); + /* Init cpu_map array */ + lpfc_cpu_map_array_init(phba); + + /* Init hba_eq_hdl array */ + lpfc_hba_eq_hdl_array_init(phba); + /* Configure and enable interrupt */ intr_mode = lpfc_sli4_enable_intr(phba, cfg_mode); if (intr_mode == LPFC_INTR_ERROR) { @@ -12632,6 +13048,9 @@ /* Enable RAS FW log support */ lpfc_sli4_ras_setup(phba); + INIT_LIST_HEAD(&phba->poll_list); + cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state, &phba->cpuhp); + return 0; out_free_sysfs_attr: @@ -13344,8 +13763,7 @@ phba->cfg_fof = 1; } else { phba->cfg_fof = 0; - if (phba->device_data_mem_pool) - mempool_destroy(phba->device_data_mem_pool); + mempool_destroy(phba->device_data_mem_pool); phba->device_data_mem_pool = NULL; } @@ -13450,11 +13868,24 @@ /* Initialize in case vector mapping is needed */ lpfc_present_cpu = num_present_cpus(); + error = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, + "lpfc/sli4:online", + lpfc_cpu_online, lpfc_cpu_offline); + if (error < 0) + goto cpuhp_failure; + lpfc_cpuhp_state = error; + error = pci_register_driver(&lpfc_driver); - if (error) { - fc_release_transport(lpfc_transport_template); - fc_release_transport(lpfc_vport_transport_template); - } + if (error) + goto unwind; + + return error; + +unwind: + cpuhp_remove_multi_state(lpfc_cpuhp_state); +cpuhp_failure: + fc_release_transport(lpfc_transport_template); + fc_release_transport(lpfc_vport_transport_template); return error; } @@ -13471,6 +13902,7 @@ { misc_deregister(&lpfc_mgmt_dev); pci_unregister_driver(&lpfc_driver); + cpuhp_remove_multi_state(lpfc_cpuhp_state); fc_release_transport(lpfc_transport_template); fc_release_transport(lpfc_vport_transport_template); idr_destroy(&lpfc_hba_index); --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_logmsg.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_logmsg.h @@ -46,6 +46,23 @@ #define LOG_NVME_IOERR 0x00800000 /* NVME IO Error events. */ #define LOG_ALL_MSG 0xffffffff /* LOG all messages */ +/* generate message by verbose log setting or severity */ +#define lpfc_vlog_msg(vport, level, mask, fmt, arg...) \ +{ if (((mask) & (vport)->cfg_log_verbose) || (level[1] <= '4')) \ + dev_printk(level, &((vport)->phba->pcidev)->dev, "%d:(%d):" \ + fmt, (vport)->phba->brd_no, vport->vpi, ##arg); } + +#define lpfc_log_msg(phba, level, mask, fmt, arg...) \ +do { \ + { uint32_t log_verbose = (phba)->pport ? \ + (phba)->pport->cfg_log_verbose : \ + (phba)->cfg_log_verbose; \ + if (((mask) & log_verbose) || (level[1] <= '4')) \ + dev_printk(level, &((phba)->pcidev)->dev, "%d:" \ + fmt, phba->brd_no, ##arg); \ + } \ +} while (0) + #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ do { \ { if (((mask) & (vport)->cfg_log_verbose) || (level[1] <= '3')) \ --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_mbox.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_mbox.c @@ -515,6 +515,7 @@ if ((phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC || phba->pcidev->device == PCI_DEVICE_ID_LANCER_G7_FC) && + !(phba->sli4_hba.pc_sli4_params.pls) && mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) { mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT; phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT; @@ -2622,39 +2623,3 @@ resume_rpi->event_tag = ndlp->phba->fc_eventTag; } -/** - * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages - * mailbox command. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES supported pages mailbox command is issued to - * retrieve the particular feature pages supported by the port. - **/ -void -lpfc_supported_pages(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_supp_pages *supp_pages; - - memset(mbox, 0, sizeof(*mbox)); - supp_pages = &mbox->u.mqe.un.supp_pages; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, supp_pages, LPFC_SUPP_PAGES); -} - -/** - * lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to - * retrieve the particular SLI4 features supported by the port. - **/ -void -lpfc_pc_sli4_params(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_pc_sli4_params *sli4_params; - - memset(mbox, 0, sizeof(*mbox)); - sli4_params = &mbox->u.mqe.un.sli4_params; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS); -} --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_mem.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_mem.c @@ -230,9 +230,6 @@ dma_pool_destroy(phba->lpfc_hrb_pool); phba->lpfc_hrb_pool = NULL; - dma_pool_destroy(phba->txrdy_payload_pool); - phba->txrdy_payload_pool = NULL; - dma_pool_destroy(phba->lpfc_hbq_pool); phba->lpfc_hbq_pool = NULL; @@ -593,8 +590,6 @@ * Description: Allocates a DMA-mapped receive buffer from the lpfc_hrb_pool PCI * pool along a non-DMA-mapped container for it. * - * Notes: Not interrupt-safe. Must be called with no locks held. - * * Returns: * pointer to HBQ on success * NULL on failure @@ -604,7 +599,7 @@ { struct rqb_dmabuf *dma_buf; - dma_buf = kzalloc(sizeof(struct rqb_dmabuf), GFP_KERNEL); + dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL); if (!dma_buf) return NULL; @@ -727,7 +722,6 @@ drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); if (rc < 0) { - (rqbp->rqb_free_buffer)(phba, rqb_entry); lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "6409 Cannot post to HRQ %d: %x %x %x " "DRQ %x %x\n", @@ -737,6 +731,7 @@ rqb_entry->hrq->entry_count, rqb_entry->drq->host_index, rqb_entry->drq->hba_index); + (rqbp->rqb_free_buffer)(phba, rqb_entry); } else { list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); rqbp->buffer_count++; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_nportdisc.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -279,6 +279,109 @@ lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); } +/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up + * @phba: pointer to lpfc hba data structure. + * @link_mbox: pointer to CONFIG_LINK mailbox object + * + * This routine is only called if we are SLI3, direct connect pt2pt + * mode and the remote NPort issues the PLOGI after link up. + */ +static void +lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox) +{ + LPFC_MBOXQ_t *login_mbox; + MAILBOX_t *mb = &link_mbox->u.mb; + struct lpfc_iocbq *save_iocb; + struct lpfc_nodelist *ndlp; + int rc; + + ndlp = link_mbox->ctx_ndlp; + login_mbox = link_mbox->context3; + save_iocb = login_mbox->context3; + link_mbox->context3 = NULL; + login_mbox->context3 = NULL; + + /* Check for CONFIG_LINK error */ + if (mb->mbxStatus) { + lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + "4575 CONFIG_LINK fails pt2pt discovery: %x\n", + mb->mbxStatus); + mempool_free(login_mbox, phba->mbox_mem_pool); + mempool_free(link_mbox, phba->mbox_mem_pool); + kfree(save_iocb); + return; + } + + /* Now that CONFIG_LINK completed, and our SID is configured, + * we can now proceed with sending the PLOGI ACC. + */ + rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI, + save_iocb, ndlp, login_mbox); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + "4576 PLOGI ACC fails pt2pt discovery: %x\n", + rc); + mempool_free(login_mbox, phba->mbox_mem_pool); + } + + mempool_free(link_mbox, phba->mbox_mem_pool); + kfree(save_iocb); +} + +/** + * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler + * @phba: Pointer to HBA context object. + * @pmb: Pointer to mailbox object. + * + * This function provides the unreg rpi mailbox completion handler for a tgt. + * The routine frees the memory resources associated with the completed + * mailbox command and transmits the ELS ACC. + * + * This routine is only called if we are SLI4, acting in target + * mode and the remote NPort issues the PLOGI after link up. + **/ +static void +lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +{ + struct lpfc_vport *vport = pmb->vport; + struct lpfc_nodelist *ndlp = pmb->ctx_ndlp; + LPFC_MBOXQ_t *mbox = pmb->context3; + struct lpfc_iocbq *piocb = NULL; + int rc; + + if (mbox) { + pmb->context3 = NULL; + piocb = mbox->context3; + mbox->context3 = NULL; + } + + /* + * Complete the unreg rpi mbx request, and update flags. + * This will also restart any deferred events. + */ + lpfc_nlp_get(ndlp); + lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb); + + if (!piocb) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY | LOG_ELS, + "4578 PLOGI ACC fail\n"); + if (mbox) + mempool_free(mbox, phba->mbox_mem_pool); + goto out; + } + + rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox); + if (rc) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY | LOG_ELS, + "4579 PLOGI ACC fail %x\n", rc); + if (mbox) + mempool_free(mbox, phba->mbox_mem_pool); + } + kfree(piocb); +out: + lpfc_nlp_put(ndlp); +} + static int lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb) @@ -291,10 +394,13 @@ IOCB_t *icmd; struct serv_parm *sp; uint32_t ed_tov; - LPFC_MBOXQ_t *mbox; + LPFC_MBOXQ_t *link_mbox; + LPFC_MBOXQ_t *login_mbox; + struct lpfc_iocbq *save_iocb; struct ls_rjt stat; uint32_t vid, flag; - int rc; + u16 rpi; + int rc, defer_acc; memset(&stat, 0, sizeof (struct ls_rjt)); pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -343,6 +449,7 @@ else ndlp->nlp_fcp_info |= CLASS3; + defer_acc = 0; ndlp->nlp_class_sup = 0; if (sp->cls1.classValid) ndlp->nlp_class_sup |= FC_COS_CLASS1; @@ -354,7 +461,6 @@ ndlp->nlp_class_sup |= FC_COS_CLASS4; ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; - /* if already logged in, do implicit logout */ switch (ndlp->nlp_state) { case NLP_STE_NPR_NODE: @@ -396,6 +502,10 @@ ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; ndlp->nlp_flag &= ~NLP_FIRSTBURST; + login_mbox = NULL; + link_mbox = NULL; + save_iocb = NULL; + /* Check for Nport to NPort pt2pt protocol */ if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { @@ -423,17 +533,22 @@ if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); else { - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (mbox == NULL) + defer_acc = 1; + link_mbox = mempool_alloc(phba->mbox_mem_pool, + GFP_KERNEL); + if (!link_mbox) goto out; - lpfc_config_link(phba, mbox); - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - mbox->vport = vport; - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); + lpfc_config_link(phba, link_mbox); + link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc; + link_mbox->vport = vport; + link_mbox->ctx_ndlp = ndlp; + + save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); + if (!save_iocb) goto out; - } + /* Save info from cmd IOCB used in rsp */ + memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb, + sizeof(struct lpfc_iocbq)); } lpfc_can_disctmo(vport); @@ -448,30 +563,57 @@ ndlp->nlp_flag |= NLP_SUPPRESS_RSP; } - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!mbox) + login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!login_mbox) goto out; /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */ - if (phba->sli_rev == LPFC_SLI_REV4) + if (phba->nvmet_support && !defer_acc) { + link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); + if (!link_mbox) + goto out; + + /* As unique identifiers such as iotag would be overwritten + * with those from the cmdiocb, allocate separate temporary + * storage for the copy. + */ + save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); + if (!save_iocb) + goto out; + + /* Unreg RPI is required for SLI4. */ + rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; + lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox); + link_mbox->vport = vport; + link_mbox->ctx_ndlp = ndlp; + link_mbox->mbox_cmpl = lpfc_defer_acc_rsp; + + if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && + (!(vport->fc_flag & FC_OFFLINE_MODE))) + ndlp->nlp_flag |= NLP_UNREG_INP; + + /* Save info from cmd IOCB used in rsp */ + memcpy(save_iocb, cmdiocb, sizeof(*save_iocb)); + + /* Delay sending ACC till unreg RPI completes. */ + defer_acc = 1; + } else if (phba->sli_rev == LPFC_SLI_REV4) lpfc_unreg_rpi(vport, ndlp); rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, - (uint8_t *) sp, mbox, ndlp->nlp_rpi); - if (rc) { - mempool_free(mbox, phba->mbox_mem_pool); + (uint8_t *)sp, login_mbox, ndlp->nlp_rpi); + if (rc) goto out; - } /* ACC PLOGI rsp command needs to execute first, - * queue this mbox command to be processed later. + * queue this login_mbox command to be processed later. */ - mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; + login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; /* - * mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox + * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox * command issued in lpfc_cmpl_els_acc(). */ - mbox->vport = vport; + login_mbox->vport = vport; spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); spin_unlock_irq(shost->host_lock); @@ -484,8 +626,10 @@ * single discovery thread, this will cause a huge delay in * discovery. Also this will cause multiple state machines * running in parallel for this node. + * This only applies to a fabric environment. */ - if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { + if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && + (vport->fc_flag & FC_FABRIC)) { /* software abort outstanding PLOGI */ lpfc_els_abort(phba, ndlp); } @@ -493,6 +637,9 @@ if ((vport->port_type == LPFC_NPIV_PORT && vport->cfg_restrict_login)) { + /* no deferred ACC */ + kfree(save_iocb); + /* In order to preserve RPIs, we want to cleanup * the default RPI the firmware created to rcv * this ELS request. The only way to do this is @@ -504,16 +651,50 @@ stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, - ndlp, mbox); + ndlp, login_mbox); if (rc) - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free(login_mbox, phba->mbox_mem_pool); return 1; } - rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); + if (defer_acc) { + /* So the order here should be: + * SLI3 pt2pt + * Issue CONFIG_LINK mbox + * CONFIG_LINK cmpl + * SLI4 tgt + * Issue UNREG RPI mbx + * UNREG RPI cmpl + * Issue PLOGI ACC + * PLOGI ACC cmpl + * Issue REG_LOGIN mbox + */ + + /* Save the REG_LOGIN mbox for and rcv IOCB copy later */ + link_mbox->context3 = login_mbox; + login_mbox->context3 = save_iocb; + + /* Start the ball rolling by issuing CONFIG_LINK here */ + rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) + goto out; + return 1; + } + + rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox); if (rc) - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free(login_mbox, phba->mbox_mem_pool); return 1; out: + if (defer_acc) + lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, + "4577 discovery failure: %p %p %p\n", + save_iocb, link_mbox, login_mbox); + kfree(save_iocb); + if (link_mbox) + mempool_free(link_mbox, phba->mbox_mem_pool); + if (login_mbox) + mempool_free(login_mbox, phba->mbox_mem_pool); + stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); @@ -600,8 +781,10 @@ /* Save the ELS cmd */ elsiocb->drvrTimeout = cmd; - lpfc_sli4_resume_rpi(ndlp, - lpfc_mbx_cmpl_resume_rpi, elsiocb); + if (lpfc_sli4_resume_rpi(ndlp, + lpfc_mbx_cmpl_resume_rpi, + elsiocb)) + kfree(elsiocb); goto out; } } @@ -661,7 +844,8 @@ else lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); if (ndlp->nlp_DID == Fabric_DID) { - if (vport->port_state <= LPFC_FDISC) + if (vport->port_state <= LPFC_FDISC || + vport->fc_flag & FC_PT2PT) goto out; lpfc_linkdown_port(vport); spin_lock_irq(shost->host_lock); @@ -707,9 +891,14 @@ } } else if ((!(ndlp->nlp_type & NLP_FABRIC) && ((ndlp->nlp_type & NLP_FCP_TARGET) || - !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || + (ndlp->nlp_type & NLP_NVME_TARGET) || + (vport->fc_flag & FC_PT2PT))) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { - /* Only try to re-login if this is NOT a Fabric Node */ + /* Only try to re-login if this is NOT a Fabric Node + * AND the remote NPORT is a FCP/NVME Target or we + * are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special + * case for LOGO as a response to ADISC behavior. + */ mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1)); spin_lock_irq(shost->host_lock); @@ -1775,8 +1964,6 @@ ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; lpfc_issue_els_logo(vport, ndlp, 0); - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); return ndlp->nlp_state; } @@ -1803,8 +1990,9 @@ * is configured try it. */ ndlp->nlp_fc4_type |= NLP_FC4_FCP; - if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || - (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { + if ((!(vport->fc_flag & FC_PT2PT_NO_NVME)) && + (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH || + vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { ndlp->nlp_fc4_type |= NLP_FC4_NVME; /* We need to update the localport also */ lpfc_nvme_update_localport(vport); @@ -2030,7 +2218,9 @@ if (bf_get_be32(prli_init, nvpr)) ndlp->nlp_type |= NLP_NVME_INITIATOR; - if (phba->nsler && bf_get_be32(prli_nsler, nvpr)) + if (phba->nsler && bf_get_be32(prli_nsler, nvpr) && + bf_get_be32(prli_conf, nvpr)) + ndlp->nlp_nvme_info |= NLP_NVME_NSLER; else ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_nvme.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_nvme.c @@ -196,6 +196,46 @@ } /** + * lpfc_nvme_prep_abort_wqe - set up 'abort' work queue entry. + * @pwqeq: Pointer to command iocb. + * @xritag: Tag that uniqely identifies the local exchange resource. + * @opt: Option bits - + * bit 0 = inhibit sending abts on the link + * + * This function is called with hbalock held. + **/ +void +lpfc_nvme_prep_abort_wqe(struct lpfc_iocbq *pwqeq, u16 xritag, u8 opt) +{ + union lpfc_wqe128 *wqe = &pwqeq->wqe; + + /* WQEs are reused. Clear stale data and set key fields to + * zero like ia, iaab, iaar, xri_tag, and ctxt_tag. + */ + memset(wqe, 0, sizeof(*wqe)); + + if (opt & INHIBIT_ABORT) + bf_set(abort_cmd_ia, &wqe->abort_cmd, 1); + /* Abort specified xri tag, with the mask deliberately zeroed */ + bf_set(abort_cmd_criteria, &wqe->abort_cmd, T_XRI_TAG); + + bf_set(wqe_cmnd, &wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); + + /* Abort the IO associated with this outstanding exchange ID. */ + wqe->abort_cmd.wqe_com.abort_tag = xritag; + + /* iotag for the wqe completion. */ + bf_set(wqe_reqtag, &wqe->abort_cmd.wqe_com, pwqeq->iotag); + + bf_set(wqe_qosd, &wqe->abort_cmd.wqe_com, 1); + bf_set(wqe_lenloc, &wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE); + + bf_set(wqe_cmd_type, &wqe->abort_cmd.wqe_com, OTHER_COMMAND); + bf_set(wqe_wqec, &wqe->abort_cmd.wqe_com, 1); + bf_set(wqe_cqid, &wqe->abort_cmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); +} + +/** * lpfc_nvme_create_queue - * @lpfc_pnvme: Pointer to the driver's nvme instance data * @qidx: An cpu index used to affinitize IO queues and MSIX vectors. @@ -342,13 +382,15 @@ if (ndlp->upcall_flags & NLP_WAIT_FOR_UNREG) { ndlp->nrport = NULL; ndlp->upcall_flags &= ~NLP_WAIT_FOR_UNREG; - } - spin_unlock_irq(&vport->phba->hbalock); + spin_unlock_irq(&vport->phba->hbalock); - /* Remove original register reference. The host transport - * won't reference this rport/remoteport any further. - */ - lpfc_nlp_put(ndlp); + /* Remove original register reference. The host transport + * won't reference this rport/remoteport any further. + */ + lpfc_nlp_put(ndlp); + } else { + spin_unlock_irq(&vport->phba->hbalock); + } rport_err: return; @@ -1200,7 +1242,8 @@ { struct lpfc_hba *phba = vport->phba; struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; - struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq); + struct nvme_common_command *sqe; + struct lpfc_iocbq *pwqeq = &lpfc_ncmd->cur_iocbq; union lpfc_wqe128 *wqe = &pwqeq->wqe; uint32_t req_len; @@ -1256,8 +1299,14 @@ cstat->control_requests++; } - if (pnode->nlp_nvme_info & NLP_NVME_NSLER) + if (pnode->nlp_nvme_info & NLP_NVME_NSLER) { bf_set(wqe_erp, &wqe->generic.wqe_com, 1); + sqe = &((struct nvme_fc_cmd_iu *) + nCmd->cmdaddr)->sqe.common; + if (sqe->opcode == nvme_admin_async_event) + bf_set(wqe_ffrq, &wqe->generic.wqe_com, 1); + } + /* * Finish initializing those WQE fields that are independent * of the nvme_cmnd request_buffer @@ -1791,7 +1840,6 @@ struct lpfc_iocbq *abts_buf; struct lpfc_iocbq *nvmereq_wqe; struct lpfc_nvme_fcpreq_priv *freqpriv; - union lpfc_wqe128 *abts_wqe; unsigned long flags; int ret_val; @@ -1912,37 +1960,7 @@ /* Ready - mark outstanding as aborted by driver. */ nvmereq_wqe->iocb_flag |= LPFC_DRIVER_ABORTED; - /* Complete prepping the abort wqe and issue to the FW. */ - abts_wqe = &abts_buf->wqe; - - /* WQEs are reused. Clear stale data and set key fields to - * zero like ia, iaab, iaar, xri_tag, and ctxt_tag. - */ - memset(abts_wqe, 0, sizeof(*abts_wqe)); - bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG); - - /* word 7 */ - bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); - bf_set(wqe_class, &abts_wqe->abort_cmd.wqe_com, - nvmereq_wqe->iocb.ulpClass); - - /* word 8 - tell the FW to abort the IO associated with this - * outstanding exchange ID. - */ - abts_wqe->abort_cmd.wqe_com.abort_tag = nvmereq_wqe->sli4_xritag; - - /* word 9 - this is the iotag for the abts_wqe completion. */ - bf_set(wqe_reqtag, &abts_wqe->abort_cmd.wqe_com, - abts_buf->iotag); - - /* word 10 */ - bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1); - bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE); - - /* word 11 */ - bf_set(wqe_cmd_type, &abts_wqe->abort_cmd.wqe_com, OTHER_COMMAND); - bf_set(wqe_wqec, &abts_wqe->abort_cmd.wqe_com, 1); - bf_set(wqe_cqid, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); + lpfc_nvme_prep_abort_wqe(abts_buf, nvmereq_wqe->sli4_xritag, 0); /* ABTS WQE must go to the same WQ as the WQE to be aborted */ abts_buf->iocb_flag |= LPFC_IO_NVME; @@ -2084,7 +2102,7 @@ lpfc_ncmd->flags &= ~LPFC_SBUF_BUMP_QDEPTH; qp = lpfc_ncmd->hdwq; - if (lpfc_ncmd->flags & LPFC_SBUF_XBUSY) { + if (unlikely(lpfc_ncmd->flags & LPFC_SBUF_XBUSY)) { lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, "6310 XB release deferred for " "ox_id x%x on reqtag x%x\n", @@ -2139,12 +2157,10 @@ */ lpfc_nvme_template.max_sgl_segments = phba->cfg_nvme_seg_cnt + 1; - /* Advertise how many hw queues we support based on fcp_io_sched */ - if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_HDWQ) - lpfc_nvme_template.max_hw_queues = phba->cfg_hdw_queue; - else - lpfc_nvme_template.max_hw_queues = - phba->sli4_hba.num_present_cpu; + /* Advertise how many hw queues we support based on cfg_hdw_queue, + * which will not exceed cpu count. + */ + lpfc_nvme_template.max_hw_queues = phba->cfg_hdw_queue; if (!IS_ENABLED(CONFIG_NVME_FC)) return ret; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_nvmet.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_nvmet.c @@ -378,13 +378,6 @@ int cpu; unsigned long iflag; - if (ctxp->txrdy) { - dma_pool_free(phba->txrdy_payload_pool, ctxp->txrdy, - ctxp->txrdy_phys); - ctxp->txrdy = NULL; - ctxp->txrdy_phys = 0; - } - if (ctxp->state == LPFC_NVMET_STE_FREE) { lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, "6411 NVMET free, already free IO x%x: %d %d\n", @@ -430,7 +423,6 @@ ctxp = (struct lpfc_nvmet_rcv_ctx *)ctx_buf->context; ctxp->wqeq = NULL; - ctxp->txrdy = NULL; ctxp->offset = 0; ctxp->phba = phba; ctxp->size = size; @@ -1392,7 +1384,7 @@ wqe = &nvmewqe->wqe; /* Initialize WQE */ - memset(wqe, 0, sizeof(union lpfc_wqe)); + memset(wqe, 0, sizeof(*wqe)); ctx_buf->iocbq->context1 = NULL; spin_lock(&phba->sli4_hba.sgl_list_lock); @@ -1923,7 +1915,7 @@ } tgtp->tport_unreg_cmp = &tport_unreg_cmp; nvmet_fc_unregister_targetport(phba->targetport); - if (!wait_for_completion_timeout(tgtp->tport_unreg_cmp, + if (!wait_for_completion_timeout(&tport_unreg_cmp, msecs_to_jiffies(LPFC_NVMET_WAIT_TMO))) lpfc_printf_log(phba, KERN_ERR, LOG_NVME, "6179 Unreg targetport x%px timeout " @@ -1958,12 +1950,10 @@ uint32_t *payload; uint32_t size, oxid, sid, rc; - fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt); - oxid = be16_to_cpu(fc_hdr->fh_ox_id); - if (!phba->targetport) { + if (!nvmebuf || !phba->targetport) { lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, - "6154 LS Drop IO x%x\n", oxid); + "6154 LS Drop IO\n"); oxid = 0; size = 0; sid = 0; @@ -1971,6 +1961,9 @@ goto dropit; } + fc_hdr = (struct fc_frame_header *)(nvmebuf->hbuf.virt); + oxid = be16_to_cpu(fc_hdr->fh_ox_id); + tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; payload = (uint32_t *)(nvmebuf->dbuf.virt); size = bf_get(lpfc_rcqe_length, &nvmebuf->cq_event.cqe.rcqe_cmpl); @@ -2326,7 +2319,6 @@ ctxp->state, ctxp->entry_cnt, ctxp->oxid); } ctxp->wqeq = NULL; - ctxp->txrdy = NULL; ctxp->offset = 0; ctxp->phba = phba; ctxp->size = size; @@ -2401,6 +2393,11 @@ d_buf = piocb->context2; nvmebuf = container_of(d_buf, struct hbq_dmabuf, dbuf); + if (!nvmebuf) { + lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, + "3015 LS Drop IO\n"); + return; + } if (phba->nvmet_support == 0) { lpfc_in_buf_free(phba, &nvmebuf->dbuf); return; @@ -2429,6 +2426,11 @@ uint64_t isr_timestamp, uint8_t cqflag) { + if (!nvmebuf) { + lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, + "3167 NVMET FCP Drop IO\n"); + return; + } if (phba->nvmet_support == 0) { lpfc_rq_buf_free(phba, &nvmebuf->hbuf); return; @@ -2595,7 +2597,6 @@ struct scatterlist *sgel; union lpfc_wqe128 *wqe; struct ulp_bde64 *bde; - uint32_t *txrdy; dma_addr_t physaddr; int i, cnt; int do_pbde; @@ -2757,23 +2758,11 @@ &lpfc_treceive_cmd_template.words[3], sizeof(uint32_t) * 9); - /* Words 0 - 2 : The first sg segment */ - txrdy = dma_pool_alloc(phba->txrdy_payload_pool, - GFP_KERNEL, &physaddr); - if (!txrdy) { - lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, - "6041 Bad txrdy buffer: oxid x%x\n", - ctxp->oxid); - return NULL; - } - ctxp->txrdy = txrdy; - ctxp->txrdy_phys = physaddr; - wqe->fcp_treceive.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; - wqe->fcp_treceive.bde.tus.f.bdeSize = TXRDY_PAYLOAD_LEN; - wqe->fcp_treceive.bde.addrLow = - cpu_to_le32(putPaddrLow(physaddr)); - wqe->fcp_treceive.bde.addrHigh = - cpu_to_le32(putPaddrHigh(physaddr)); + /* Words 0 - 2 : First SGE is skipped, set invalid BDE type */ + wqe->fcp_treceive.bde.tus.f.bdeFlags = LPFC_SGE_TYPE_SKIP; + wqe->fcp_treceive.bde.tus.f.bdeSize = 0; + wqe->fcp_treceive.bde.addrLow = 0; + wqe->fcp_treceive.bde.addrHigh = 0; /* Word 4 */ wqe->fcp_treceive.relative_offset = ctxp->offset; @@ -2808,17 +2797,13 @@ /* Word 12 */ wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; - /* Setup 1 TXRDY and 1 SKIP SGE */ - txrdy[0] = 0; - txrdy[1] = cpu_to_be32(rsp->transfer_length); - txrdy[2] = 0; - - sgl->addr_hi = putPaddrHigh(physaddr); - sgl->addr_lo = putPaddrLow(physaddr); + /* Setup 2 SKIP SGEs */ + sgl->addr_hi = 0; + sgl->addr_lo = 0; sgl->word2 = 0; - bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_DATA); + bf_set(lpfc_sli4_sge_type, sgl, LPFC_SGE_TYPE_SKIP); sgl->word2 = cpu_to_le32(sgl->word2); - sgl->sge_len = cpu_to_le32(TXRDY_PAYLOAD_LEN); + sgl->sge_len = 0; sgl++; sgl->addr_hi = 0; sgl->addr_lo = 0; @@ -3204,7 +3189,6 @@ bf_set(wqe_rcvoxid, &wqe_abts->xmit_sequence.wqe_com, xri); /* Word 10 */ - bf_set(wqe_dbde, &wqe_abts->xmit_sequence.wqe_com, 1); bf_set(wqe_iod, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_IOD_WRITE); bf_set(wqe_lenloc, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_LENLOC_WORD12); @@ -3239,9 +3223,9 @@ { struct lpfc_nvmet_tgtport *tgtp; struct lpfc_iocbq *abts_wqeq; - union lpfc_wqe128 *abts_wqe; struct lpfc_nodelist *ndlp; unsigned long flags; + u8 opt; int rc; tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; @@ -3280,8 +3264,8 @@ return 0; } abts_wqeq = ctxp->abort_wqeq; - abts_wqe = &abts_wqeq->wqe; ctxp->state = LPFC_NVMET_STE_ABORT; + opt = (ctxp->flag & LPFC_NVMET_ABTS_RCV) ? INHIBIT_ABORT : 0; spin_unlock_irqrestore(&ctxp->ctxlock, flags); /* Announce entry to new IO submit field. */ @@ -3327,40 +3311,12 @@ /* Ready - mark outstanding as aborted by driver. */ abts_wqeq->iocb_flag |= LPFC_DRIVER_ABORTED; - /* WQEs are reused. Clear stale data and set key fields to - * zero like ia, iaab, iaar, xri_tag, and ctxt_tag. - */ - memset(abts_wqe, 0, sizeof(*abts_wqe)); - - /* word 3 */ - bf_set(abort_cmd_criteria, &abts_wqe->abort_cmd, T_XRI_TAG); - - /* word 7 */ - bf_set(wqe_ct, &abts_wqe->abort_cmd.wqe_com, 0); - bf_set(wqe_cmnd, &abts_wqe->abort_cmd.wqe_com, CMD_ABORT_XRI_CX); - - /* word 8 - tell the FW to abort the IO associated with this - * outstanding exchange ID. - */ - abts_wqe->abort_cmd.wqe_com.abort_tag = ctxp->wqeq->sli4_xritag; - - /* word 9 - this is the iotag for the abts_wqe completion. */ - bf_set(wqe_reqtag, &abts_wqe->abort_cmd.wqe_com, - abts_wqeq->iotag); - - /* word 10 */ - bf_set(wqe_qosd, &abts_wqe->abort_cmd.wqe_com, 1); - bf_set(wqe_lenloc, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_LENLOC_NONE); - - /* word 11 */ - bf_set(wqe_cmd_type, &abts_wqe->abort_cmd.wqe_com, OTHER_COMMAND); - bf_set(wqe_wqec, &abts_wqe->abort_cmd.wqe_com, 1); - bf_set(wqe_cqid, &abts_wqe->abort_cmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); + lpfc_nvme_prep_abort_wqe(abts_wqeq, ctxp->wqeq->sli4_xritag, opt); /* ABTS WQE must go to the same WQ as the WQE to be aborted */ abts_wqeq->hba_wqidx = ctxp->wqeq->hba_wqidx; abts_wqeq->wqe_cmpl = lpfc_nvmet_sol_fcp_abort_cmp; - abts_wqeq->iocb_cmpl = 0; + abts_wqeq->iocb_cmpl = NULL; abts_wqeq->iocb_flag |= LPFC_IO_NVME; abts_wqeq->context2 = ctxp; abts_wqeq->vport = phba->pport; @@ -3495,7 +3451,7 @@ spin_lock_irqsave(&phba->hbalock, flags); abts_wqeq->wqe_cmpl = lpfc_nvmet_xmt_ls_abort_cmp; - abts_wqeq->iocb_cmpl = 0; + abts_wqeq->iocb_cmpl = NULL; abts_wqeq->iocb_flag |= LPFC_IO_NVME_LS; rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, abts_wqeq); spin_unlock_irqrestore(&phba->hbalock, flags); --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_nvmet.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_nvmet.h @@ -112,9 +112,7 @@ struct lpfc_hba *phba; struct lpfc_iocbq *wqeq; struct lpfc_iocbq *abort_wqeq; - dma_addr_t txrdy_phys; spinlock_t ctxlock; /* protect flag access */ - uint32_t *txrdy; uint32_t sid; uint32_t offset; uint16_t oxid; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -134,21 +134,21 @@ /** * lpfc_update_stats - Update statistical data for the command completion - * @phba: Pointer to HBA object. + * @vport: The virtual port on which this call is executing. * @lpfc_cmd: lpfc scsi command object pointer. * * This function is called when there is a command completion and this * function updates the statistical data for the command completion. **/ static void -lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) +lpfc_update_stats(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd) { + struct lpfc_hba *phba = vport->phba; struct lpfc_rport_data *rdata; struct lpfc_nodelist *pnode; struct scsi_cmnd *cmd = lpfc_cmd->pCmd; unsigned long flags; - struct Scsi_Host *shost = cmd->device->host; - struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); unsigned long latency; int i; @@ -246,11 +246,10 @@ struct Scsi_Host *shost; struct scsi_device *sdev; unsigned long new_queue_depth; - unsigned long num_rsrc_err, num_cmd_success; + unsigned long num_rsrc_err; int i; num_rsrc_err = atomic_read(&phba->num_rsrc_err); - num_cmd_success = atomic_read(&phba->num_cmd_success); /* * The error and success command counters are global per @@ -265,20 +264,16 @@ for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); shost_for_each_device(sdev, shost) { - new_queue_depth = - sdev->queue_depth * num_rsrc_err / - (num_rsrc_err + num_cmd_success); - if (!new_queue_depth) - new_queue_depth = sdev->queue_depth - 1; + if (num_rsrc_err >= sdev->queue_depth) + new_queue_depth = 1; else new_queue_depth = sdev->queue_depth - - new_queue_depth; + num_rsrc_err; scsi_change_queue_depth(sdev, new_queue_depth); } } lpfc_destroy_vport_work_array(phba, vports); atomic_set(&phba->num_rsrc_err, 0); - atomic_set(&phba->num_cmd_success, 0); } /** @@ -481,7 +476,7 @@ spin_lock(&qp->abts_io_buf_list_lock); list_for_each_entry_safe(psb, next_psb, &qp->lpfc_abts_io_buf_list, list) { - if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) + if (psb->cur_iocbq.iocb_flag & LPFC_IO_NVME) continue; if (psb->rdata && psb->rdata->pnode && @@ -526,9 +521,9 @@ &qp->lpfc_abts_io_buf_list, list) { if (psb->cur_iocbq.sli4_xritag == xri) { list_del_init(&psb->list); - psb->exch_busy = 0; + psb->flags &= ~LPFC_SBUF_XBUSY; psb->status = IOSTAT_SUCCESS; - if (psb->cur_iocbq.iocb_flag == LPFC_IO_NVME) { + if (psb->cur_iocbq.iocb_flag & LPFC_IO_NVME) { qp->abts_nvme_io_bufs--; spin_unlock(&qp->abts_io_buf_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); @@ -566,7 +561,7 @@ if (iocbq->sli4_xritag != xri) continue; psb = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); - psb->exch_busy = 0; + psb->flags &= ~LPFC_SBUF_XBUSY; spin_unlock_irqrestore(&phba->hbalock, iflag); if (!list_empty(&pring->txq)) lpfc_worker_wake_up(phba); @@ -609,7 +604,7 @@ } spin_unlock_irqrestore(&phba->scsi_buf_list_get_lock, iflag); - if (lpfc_ndlp_check_qdepth(phba, ndlp) && lpfc_cmd) { + if (lpfc_ndlp_check_qdepth(phba, ndlp)) { atomic_inc(&ndlp->cmd_pending); lpfc_cmd->flags |= LPFC_SBUF_BUMP_QDEPTH; } @@ -671,8 +666,10 @@ lpfc_cmd->prot_data_type = 0; #endif tmp = lpfc_get_cmd_rsp_buf_per_hdwq(phba, lpfc_cmd); - if (!tmp) + if (!tmp) { + lpfc_release_io_buf(phba, lpfc_cmd, lpfc_cmd->hdwq); return NULL; + } lpfc_cmd->fcp_cmnd = tmp->fcp_cmnd; lpfc_cmd->fcp_rsp = tmp->fcp_rsp; @@ -719,7 +716,7 @@ iocb->ulpLe = 1; iocb->ulpClass = CLASS3; - if (lpfc_ndlp_check_qdepth(phba, ndlp)) { + if (lpfc_ndlp_check_qdepth(phba, ndlp) && lpfc_cmd) { atomic_inc(&ndlp->cmd_pending); lpfc_cmd->flags |= LPFC_SBUF_BUMP_QDEPTH; } @@ -786,7 +783,7 @@ psb->prot_seg_cnt = 0; qp = psb->hdwq; - if (psb->exch_busy) { + if (psb->flags & LPFC_SBUF_XBUSY) { spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); psb->pCmd = NULL; list_add_tail(&psb->list, &qp->lpfc_abts_io_buf_list); @@ -1940,7 +1937,7 @@ * * Returns the number of SGEs added to the SGL. **/ -static int +static uint32_t lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, struct sli4_sge *sgl, int datasegcnt, struct lpfc_io_buf *lpfc_cmd) @@ -1948,8 +1945,8 @@ struct scatterlist *sgde = NULL; /* s/g data entry */ struct sli4_sge_diseed *diseed = NULL; dma_addr_t physaddr; - int i = 0, num_sge = 0, status; - uint32_t reftag; + int i = 0, status; + uint32_t reftag, num_sge = 0; uint8_t txop, rxop; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS uint32_t rc; @@ -2120,7 +2117,7 @@ * * Returns the number of SGEs added to the SGL. **/ -static int +static uint32_t lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, struct sli4_sge *sgl, int datacnt, int protcnt, struct lpfc_io_buf *lpfc_cmd) @@ -2144,8 +2141,8 @@ uint32_t rc; #endif uint32_t checking = 1; - uint32_t dma_offset = 0; - int num_sge = 0, j = 2; + uint32_t dma_offset = 0, num_sge = 0; + int j = 2; struct sli4_hybrid_sgl *sgl_xtra = NULL; sgpe = scsi_prot_sglist(sc); @@ -3812,7 +3809,7 @@ /* Sanity check on return of outstanding command */ cmd = lpfc_cmd->pCmd; - if (!cmd) { + if (!cmd || !phba) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "2621 IO completion: Not an active IO\n"); spin_unlock(&lpfc_cmd->buf_lock); @@ -3824,7 +3821,7 @@ phba->sli4_hba.hdwq[idx].scsi_cstat.io_cmpls++; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { + if (unlikely(phba->cpucheck_on & LPFC_CHECK_SCSI_IO)) { cpu = raw_smp_processor_id(); if (cpu < LPFC_CHECK_CPU_CNT && phba->sli4_hba.hdwq) phba->sli4_hba.hdwq[idx].cpucheck_cmpl_io[cpu]++; @@ -3835,7 +3832,10 @@ lpfc_cmd->result = (pIocbOut->iocb.un.ulpWord[4] & IOERR_PARAM_MASK); lpfc_cmd->status = pIocbOut->iocb.ulpStatus; /* pick up SLI4 exhange busy status from HBA */ - lpfc_cmd->exch_busy = pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY; + if (pIocbOut->iocb_flag & LPFC_EXCHANGE_BUSY) + lpfc_cmd->flags |= LPFC_SBUF_XBUSY; + else + lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS if (lpfc_cmd->prot_data_type) { @@ -3869,7 +3869,7 @@ } #endif - if (lpfc_cmd->status) { + if (unlikely(lpfc_cmd->status)) { if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT && (lpfc_cmd->result & IOERR_DRVR_MASK)) lpfc_cmd->status = IOSTAT_DRIVER_REJECT; @@ -4002,7 +4002,7 @@ scsi_get_resid(cmd)); } - lpfc_update_stats(phba, lpfc_cmd); + lpfc_update_stats(vport, lpfc_cmd); if (vport->cfg_max_scsicmpl_time && time_after(jiffies, lpfc_cmd->start_time + msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { @@ -4610,17 +4610,18 @@ err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd); } - if (err == 2) { - cmnd->result = DID_ERROR << 16; - goto out_fail_command_release_buf; - } else if (err) { + if (unlikely(err)) { + if (err == 2) { + cmnd->result = DID_ERROR << 16; + goto out_fail_command_release_buf; + } goto out_host_busy_free_buf; } lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp); #ifdef CONFIG_SCSI_LPFC_DEBUG_FS - if (phba->cpucheck_on & LPFC_CHECK_SCSI_IO) { + if (unlikely(phba->cpucheck_on & LPFC_CHECK_SCSI_IO)) { cpu = raw_smp_processor_id(); if (cpu < LPFC_CHECK_CPU_CNT) { struct lpfc_sli4_hdw_queue *hdwq = @@ -4843,20 +4844,21 @@ ret_val = __lpfc_sli_issue_iocb(phba, LPFC_FCP_RING, abtsiocb, 0); } - /* no longer need the lock after this point */ - spin_unlock_irqrestore(&phba->hbalock, flags); if (ret_val == IOCB_ERROR) { /* Indicate the IO is not being aborted by the driver. */ iocb->iocb_flag &= ~LPFC_DRIVER_ABORTED; lpfc_cmd->waitq = NULL; spin_unlock(&lpfc_cmd->buf_lock); + spin_unlock_irqrestore(&phba->hbalock, flags); lpfc_sli_release_iocbq(phba, abtsiocb); ret = FAILED; goto out; } + /* no longer need the lock after this point */ spin_unlock(&lpfc_cmd->buf_lock); + spin_unlock_irqrestore(&phba->hbalock, flags); if (phba->cfg_poll & DISABLE_FCP_RING_INT) lpfc_sli_handle_fast_ring_event(phba, --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_sli.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_sli.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -87,6 +87,10 @@ struct lpfc_eqe *eqe); static bool lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba); static bool lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba); +static struct lpfc_cqe *lpfc_sli4_cq_get(struct lpfc_queue *q); +static void __lpfc_sli4_consume_cqe(struct lpfc_hba *phba, + struct lpfc_queue *cq, + struct lpfc_cqe *cqe); static IOCB_t * lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) @@ -467,25 +471,52 @@ } static void -lpfc_sli4_eq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq) +lpfc_sli4_eqcq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq) { - struct lpfc_eqe *eqe; - uint32_t count = 0; + struct lpfc_eqe *eqe = NULL; + u32 eq_count = 0, cq_count = 0; + struct lpfc_cqe *cqe = NULL; + struct lpfc_queue *cq = NULL, *childq = NULL; + int cqid = 0; /* walk all the EQ entries and drop on the floor */ eqe = lpfc_sli4_eq_get(eq); while (eqe) { + /* Get the reference to the corresponding CQ */ + cqid = bf_get_le32(lpfc_eqe_resource_id, eqe); + cq = NULL; + + list_for_each_entry(childq, &eq->child_list, list) { + if (childq->queue_id == cqid) { + cq = childq; + break; + } + } + /* If CQ is valid, iterate through it and drop all the CQEs */ + if (cq) { + cqe = lpfc_sli4_cq_get(cq); + while (cqe) { + __lpfc_sli4_consume_cqe(phba, cq, cqe); + cq_count++; + cqe = lpfc_sli4_cq_get(cq); + } + /* Clear and re-arm the CQ */ + phba->sli4_hba.sli4_write_cq_db(phba, cq, cq_count, + LPFC_QUEUE_REARM); + cq_count = 0; + } __lpfc_sli4_consume_eqe(phba, eq, eqe); - count++; + eq_count++; eqe = lpfc_sli4_eq_get(eq); } /* Clear and re-arm the EQ */ - phba->sli4_hba.sli4_write_eq_db(phba, eq, count, LPFC_QUEUE_REARM); + phba->sli4_hba.sli4_write_eq_db(phba, eq, eq_count, LPFC_QUEUE_REARM); } static int -lpfc_sli4_process_eq(struct lpfc_hba *phba, struct lpfc_queue *eq) +lpfc_sli4_process_eq(struct lpfc_hba *phba, struct lpfc_queue *eq, + uint8_t rearm) { struct lpfc_eqe *eqe; int count = 0, consumed = 0; @@ -519,8 +550,8 @@ eq->queue_claimed = 0; rearm_and_exit: - /* Always clear and re-arm the EQ */ - phba->sli4_hba.sli4_write_eq_db(phba, eq, consumed, LPFC_QUEUE_REARM); + /* Always clear the EQ. */ + phba->sli4_hba.sli4_write_eq_db(phba, eq, consumed, rearm); return count; } @@ -2480,6 +2511,8 @@ !pmb->u.mb.mbxStatus) { rpi = pmb->u.mb.un.varWords[0]; vpi = pmb->u.mb.un.varRegLogin.vpi; + if (phba->sli_rev == LPFC_SLI_REV4) + vpi -= phba->sli4_hba.max_cfg_param.vpi_base; lpfc_unreg_login(phba, vpi, rpi, pmb); pmb->vport = vport; pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; @@ -2526,6 +2559,8 @@ } else { __lpfc_sli_rpi_release(vport, ndlp); } + if (vport->load_flag & FC_UNLOADING) + lpfc_nlp_put(ndlp); pmb->ctx_ndlp = NULL; } } @@ -2672,7 +2707,8 @@ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, "(%d):0323 Unknown Mailbox command " "x%x (x%x/x%x) Cmpl\n", - pmb->vport ? pmb->vport->vpi : 0, + pmb->vport ? pmb->vport->vpi : + LPFC_VPORT_UNKNOWN, pmbox->mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, pmb), @@ -2693,7 +2729,8 @@ "(%d):0305 Mbox cmd cmpl " "error - RETRYing Data: x%x " "(x%x/x%x) x%x x%x x%x\n", - pmb->vport ? pmb->vport->vpi : 0, + pmb->vport ? pmb->vport->vpi : + LPFC_VPORT_UNKNOWN, pmbox->mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, pmb), @@ -2701,7 +2738,8 @@ pmb), pmbox->mbxStatus, pmbox->un.varWords[0], - pmb->vport->port_state); + pmb->vport ? pmb->vport->port_state : + LPFC_VPORT_UNKNOWN); pmbox->mbxStatus = 0; pmbox->mbxOwner = OWN_HOST; rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); @@ -4008,6 +4046,11 @@ struct lpfc_iocbq *piocb, *next_iocb; spin_lock_irq(&phba->hbalock); + if (phba->hba_flag & HBA_IOQ_FLUSH || + !phba->sli4_hba.hdwq) { + spin_unlock_irq(&phba->hbalock); + return; + } /* Indicate the I/O queues are flushed */ phba->hba_flag |= HBA_IOQ_FLUSH; spin_unlock_irq(&phba->hbalock); @@ -4488,12 +4531,6 @@ phba->fcf.fcf_flag = 0; spin_unlock_irq(&phba->hbalock); - /* SLI4 INTF 2: if FW dump is being taken skip INIT_PORT */ - if (phba->hba_flag & HBA_FW_DUMP_OP) { - phba->hba_flag &= ~HBA_FW_DUMP_OP; - return rc; - } - /* Now physically reset the device */ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0389 Performing PCI function reset!\n"); @@ -4882,8 +4919,17 @@ lpfc_sli4_rb_setup(struct lpfc_hba *phba) { phba->hbq_in_use = 1; - phba->hbqs[LPFC_ELS_HBQ].entry_count = - lpfc_hbq_defs[LPFC_ELS_HBQ]->entry_count; + /** + * Specific case when the MDS diagnostics is enabled and supported. + * The receive buffer count is truncated to manage the incoming + * traffic. + **/ + if (phba->cfg_enable_mds_diags && phba->mds_diags_support) + phba->hbqs[LPFC_ELS_HBQ].entry_count = + lpfc_hbq_defs[LPFC_ELS_HBQ]->entry_count >> 1; + else + phba->hbqs[LPFC_ELS_HBQ].entry_count = + lpfc_hbq_defs[LPFC_ELS_HBQ]->entry_count; phba->hbq_count = 1; lpfc_sli_hbqbuf_init_hbqs(phba, LPFC_ELS_HBQ); /* Initially populate or replenish the HBQs */ @@ -5413,12 +5459,10 @@ phba->sli4_hba.lnk_info.lnk_no, phba->BIOSVersion); out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; } @@ -5519,12 +5563,10 @@ } out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; } @@ -6167,6 +6209,14 @@ mbox->u.mqe.un.set_feature.feature = LPFC_SET_MDS_DIAGS; mbox->u.mqe.un.set_feature.param_len = 8; break; + case LPFC_SET_DUAL_DUMP: + bf_set(lpfc_mbx_set_feature_dd, + &mbox->u.mqe.un.set_feature, LPFC_ENABLE_DUAL_DUMP); + bf_set(lpfc_mbx_set_feature_ddquery, + &mbox->u.mqe.un.set_feature, 0); + mbox->u.mqe.un.set_feature.feature = LPFC_SET_DUAL_DUMP; + mbox->u.mqe.un.set_feature.param_len = 4; + break; } return; @@ -6184,11 +6234,16 @@ { struct lpfc_ras_fwlog *ras_fwlog = &phba->ras_fwlog; - ras_fwlog->ras_active = false; + spin_lock_irq(&phba->hbalock); + ras_fwlog->state = INACTIVE; + spin_unlock_irq(&phba->hbalock); /* Disable FW logging to host memory */ writel(LPFC_CTL_PDEV_CTL_DDL_RAS, phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET); + + /* Wait 10ms for firmware to stop using DMA buffer */ + usleep_range(10 * 1000, 20 * 1000); } /** @@ -6224,7 +6279,9 @@ ras_fwlog->lwpd.virt = NULL; } - ras_fwlog->ras_active = false; + spin_lock_irq(&phba->hbalock); + ras_fwlog->state = INACTIVE; + spin_unlock_irq(&phba->hbalock); } /** @@ -6326,7 +6383,9 @@ goto disable_ras; } - ras_fwlog->ras_active = true; + spin_lock_irq(&phba->hbalock); + ras_fwlog->state = ACTIVE; + spin_unlock_irq(&phba->hbalock); mempool_free(pmb, phba->mbox_mem_pool); return; @@ -6358,6 +6417,10 @@ uint32_t len = 0, fwlog_buffsize, fwlog_entry_count; int rc = 0; + spin_lock_irq(&phba->hbalock); + ras_fwlog->state = INACTIVE; + spin_unlock_irq(&phba->hbalock); + fwlog_buffsize = (LPFC_RAS_MIN_BUFF_POST_SIZE * phba->cfg_ras_fwlog_buffsize); fwlog_entry_count = (fwlog_buffsize/LPFC_RAS_MAX_ENTRY_SIZE); @@ -6417,6 +6480,9 @@ mbx_fwlog->u.request.lwpd.addr_lo = putPaddrLow(ras_fwlog->lwpd.phys); mbx_fwlog->u.request.lwpd.addr_hi = putPaddrHigh(ras_fwlog->lwpd.phys); + spin_lock_irq(&phba->hbalock); + ras_fwlog->state = REG_INPROGRESS; + spin_unlock_irq(&phba->hbalock); mbox->vport = phba->pport; mbox->mbox_cmpl = lpfc_sli4_ras_mbox_cmpl; @@ -6902,7 +6968,7 @@ struct lpfc_sglq *sglq_entry = NULL; struct lpfc_sglq *sglq_entry_next = NULL; struct lpfc_sglq *sglq_entry_first = NULL; - int status, total_cnt; + int status = 0, total_cnt; int post_cnt = 0, num_posted = 0, block_cnt = 0; int last_xritag = NO_XRI; LIST_HEAD(prep_sgl_list); @@ -7092,12 +7158,16 @@ struct rqb_dmabuf *rqb_buffer; LIST_HEAD(rqb_buf_list); - spin_lock_irqsave(&phba->hbalock, flags); rqbp = hrq->rqbp; for (i = 0; i < count; i++) { + spin_lock_irqsave(&phba->hbalock, flags); /* IF RQ is already full, don't bother */ - if (rqbp->buffer_count + i >= rqbp->entry_count - 1) + if (rqbp->buffer_count + i >= rqbp->entry_count - 1) { + spin_unlock_irqrestore(&phba->hbalock, flags); break; + } + spin_unlock_irqrestore(&phba->hbalock, flags); + rqb_buffer = rqbp->rqb_alloc_buffer(phba); if (!rqb_buffer) break; @@ -7106,6 +7176,8 @@ rqb_buffer->idx = idx; list_add_tail(&rqb_buffer->hbuf.list, &rqb_buf_list); } + + spin_lock_irqsave(&phba->hbalock, flags); while (!list_empty(&rqb_buf_list)) { list_remove_head(&rqb_buf_list, rqb_buffer, struct rqb_dmabuf, hbuf.list); @@ -7148,7 +7220,7 @@ int lpfc_sli4_hba_setup(struct lpfc_hba *phba) { - int rc, i, cnt, len; + int rc, i, cnt, len, dd; LPFC_MBOXQ_t *mboxq; struct lpfc_mqe *mqe; uint8_t *vpd; @@ -7302,15 +7374,6 @@ phba->vpd.rev.fcphHigh, phba->vpd.rev.fcphLow, phba->vpd.rev.feaLevelHigh, phba->vpd.rev.feaLevelLow); - /* Reset the DFT_LUN_Q_DEPTH to (max xri >> 3) */ - rc = (phba->sli4_hba.max_cfg_param.max_xri >> 3); - if (phba->pport->cfg_lun_queue_depth > rc) { - lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "3362 LUN queue depth changed from %d to %d\n", - phba->pport->cfg_lun_queue_depth, rc); - phba->pport->cfg_lun_queue_depth = rc; - } - if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == LPFC_SLI_INTF_IF_TYPE_0) { lpfc_set_features(phba, mboxq, LPFC_SET_UE_RECOVERY); @@ -7399,6 +7462,23 @@ phba->sli3_options |= (LPFC_SLI3_NPIV_ENABLED | LPFC_SLI3_HBQ_ENABLED); spin_unlock_irq(&phba->hbalock); + /* Always try to enable dual dump feature if we can */ + lpfc_set_features(phba, mboxq, LPFC_SET_DUAL_DUMP); + rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); + dd = bf_get(lpfc_mbx_set_feature_dd, &mboxq->u.mqe.un.set_feature); + if ((rc == MBX_SUCCESS) && (dd == LPFC_ENABLE_DUAL_DUMP)) + lpfc_printf_log(phba, KERN_ERR, LOG_SLI | LOG_INIT, + "6448 Dual Dump is enabled\n"); + else + lpfc_printf_log(phba, KERN_INFO, LOG_SLI | LOG_INIT, + "6447 Dual Dump Mailbox x%x (x%x/x%x) failed, " + "rc:x%x dd:x%x\n", + bf_get(lpfc_mqe_command, &mboxq->u.mqe), + lpfc_sli_config_mbox_subsys_get( + phba, mboxq), + lpfc_sli_config_mbox_opcode_get( + phba, mboxq), + rc, dd); /* * Allocate all resources (xri,rpi,vpi,vfi) now. Subsequent * calls depends on these resources to complete port setup. @@ -7523,9 +7603,11 @@ } phba->sli4_hba.nvmet_xri_cnt = rc; - cnt = phba->cfg_iocb_cnt * 1024; - /* We need 1 iocbq for every SGL, for IO processing */ - cnt += phba->sli4_hba.nvmet_xri_cnt; + /* We allocate an iocbq for every receive context SGL. + * The additional allocation is for abort and ls handling. + */ + cnt = phba->sli4_hba.nvmet_xri_cnt + + phba->sli4_hba.max_cfg_param.max_xri; } else { /* update host common xri-sgl sizes and mappings */ rc = lpfc_sli4_io_sgl_update(phba); @@ -7547,14 +7629,17 @@ rc = -ENODEV; goto out_destroy_queue; } - cnt = phba->cfg_iocb_cnt * 1024; + /* Each lpfc_io_buf job structure has an iocbq element. + * This cnt provides for abort, els, ct and ls requests. + */ + cnt = phba->sli4_hba.max_cfg_param.max_xri; } if (!phba->sli.iocbq_lookup) { /* Initialize and populate the iocb list per host */ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2821 initialize iocb list %d total %d\n", - phba->cfg_iocb_cnt, cnt); + "2821 initialize iocb list with %d entries\n", + cnt); rc = lpfc_init_iocb_list(phba, cnt); if (rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -7590,7 +7675,7 @@ "0393 Error %d during rpi post operation\n", rc); rc = -ENODEV; - goto out_destroy_queue; + goto out_free_iocblist; } lpfc_sli4_node_prep(phba); @@ -7753,8 +7838,9 @@ out_unset_queue: /* Unset all the queues set up in this routine when error out */ lpfc_sli4_queue_unset(phba); -out_destroy_queue: +out_free_iocblist: lpfc_free_iocb_list(phba); +out_destroy_queue: lpfc_sli4_queue_destroy(phba); out_stop_timers: lpfc_stop_hba_timers(phba); @@ -7892,7 +7978,7 @@ if (mbox_pending) /* process and rearm the EQ */ - lpfc_sli4_process_eq(phba, fpeq); + lpfc_sli4_process_eq(phba, fpeq, LPFC_QUEUE_REARM); else /* Always clear and re-arm the EQ */ sli4_hba->sli4_write_eq_db(phba, fpeq, 0, LPFC_QUEUE_REARM); @@ -8964,7 +9050,8 @@ * @pring: Pointer to driver SLI ring object. * @piocb: Pointer to address of newly added command iocb. * - * This function is called with hbalock held to add a command + * This function is called with hbalock held for SLI3 ports or + * the ring lock held for SLI4 ports to add a command * iocb to the txq when SLI layer cannot submit the command iocb * to the ring. **/ @@ -8972,7 +9059,10 @@ __lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *piocb) { - lockdep_assert_held(&phba->hbalock); + if (phba->sli_rev == LPFC_SLI_REV4) + lockdep_assert_held(&pring->ring_lock); + else + lockdep_assert_held(&phba->hbalock); /* Insert the caller's iocb in the txq tail for later processing. */ list_add_tail(&piocb->list, &pring->txq); } @@ -9373,6 +9463,7 @@ if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) { if (pcmd && (*pcmd == ELS_CMD_FLOGI || *pcmd == ELS_CMD_SCR || + *pcmd == ELS_CMD_RDF || *pcmd == ELS_CMD_RSCN_XMT || *pcmd == ELS_CMD_FDISC || *pcmd == ELS_CMD_LOGO || @@ -9863,7 +9954,7 @@ * __lpfc_sli_issue_iocb_s4 is used by other functions in the driver to issue * an iocb command to an HBA with SLI-4 interface spec. * - * This function is called with hbalock held. The function will return success + * This function is called with ringlock held. The function will return success * after it successfully submit the iocb to firmware or after adding to the * txq. **/ @@ -10053,10 +10144,13 @@ struct lpfc_iocbq *piocb, uint32_t flag) { struct lpfc_sli_ring *pring; + struct lpfc_queue *eq; unsigned long iflags; int rc; if (phba->sli_rev == LPFC_SLI_REV4) { + eq = phba->sli4_hba.hdwq[piocb->hba_wqidx].hba_eq; + pring = lpfc_sli4_calc_ring(phba, piocb); if (unlikely(pring == NULL)) return IOCB_ERROR; @@ -10064,6 +10158,8 @@ spin_lock_irqsave(&pring->ring_lock, iflags); rc = __lpfc_sli_issue_iocb(phba, ring_number, piocb, flag); spin_unlock_irqrestore(&pring->ring_lock, iflags); + + lpfc_sli4_poll_eq(eq, LPFC_POLL_FASTPATH); } else { /* For now, SLI2/3 will still use hbalock */ spin_lock_irqsave(&phba->hbalock, iflags); @@ -10678,14 +10774,14 @@ set_bit(LPFC_DATA_READY, &phba->data_flags); } prev_pring_flag = pring->flag; - spin_lock_irq(&pring->ring_lock); + spin_lock(&pring->ring_lock); list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { if (iocb->vport != vport) continue; list_move_tail(&iocb->list, &completions); } - spin_unlock_irq(&pring->ring_lock); + spin_unlock(&pring->ring_lock); list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { if (iocb->vport != vport) @@ -11050,9 +11146,6 @@ irsp->ulpStatus, irsp->un.ulpWord[4]); spin_unlock_irq(&phba->hbalock); - if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT && - irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) - lpfc_sli_release_iocbq(phba, abort_iocb); } release_iocb: lpfc_sli_release_iocbq(phba, cmdiocb); @@ -11323,13 +11416,20 @@ lpfc_ctx_cmd ctx_cmd) { struct lpfc_io_buf *lpfc_cmd; + IOCB_t *icmd = NULL; int rc = 1; if (iocbq->vport != vport) return rc; - if (!(iocbq->iocb_flag & LPFC_IO_FCP) || - !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)) + if (!(iocbq->iocb_flag & LPFC_IO_FCP) || + !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || + iocbq->iocb_flag & LPFC_DRIVER_ABORTED) + return rc; + + icmd = &iocbq->iocb; + if (icmd->ulpCommand == CMD_ABORT_XRI_CN || + icmd->ulpCommand == CMD_CLOSE_XRI_CN) return rc; lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); @@ -11736,7 +11836,10 @@ !(cmdiocbq->iocb_flag & LPFC_IO_LIBDFC)) { lpfc_cmd = container_of(cmdiocbq, struct lpfc_io_buf, cur_iocbq); - lpfc_cmd->exch_busy = rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY; + if (rspiocbq && (rspiocbq->iocb_flag & LPFC_EXCHANGE_BUSY)) + lpfc_cmd->flags |= LPFC_SBUF_XBUSY; + else + lpfc_cmd->flags &= ~LPFC_SBUF_XBUSY; } pdone_q = cmdiocbq->context_un.wait_queue; @@ -13158,13 +13261,19 @@ phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; /* Setting active mailbox pointer need to be in sync to flag clear */ phba->sli.mbox_active = NULL; + if (bf_get(lpfc_trailer_consumed, mcqe)) + lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq); spin_unlock_irqrestore(&phba->hbalock, iflags); /* Wake up worker thread to post the next pending mailbox command */ lpfc_worker_wake_up(phba); + return workposted; + out_no_mqe_complete: + spin_lock_irqsave(&phba->hbalock, iflags); if (bf_get(lpfc_trailer_consumed, mcqe)) lpfc_sli4_mq_release(phba->sli4_hba.mbx_wq); - return workposted; + spin_unlock_irqrestore(&phba->hbalock, iflags); + return false; } /** @@ -13217,7 +13326,6 @@ struct lpfc_sli_ring *pring = cq->pring; int txq_cnt = 0; int txcmplq_cnt = 0; - int fcp_txcmplq_cnt = 0; /* Check for response status */ if (unlikely(bf_get(lpfc_wcqe_c_status, wcqe))) { @@ -13239,9 +13347,8 @@ txcmplq_cnt++; lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "0387 NO IOCBQ data: txq_cnt=%d iocb_cnt=%d " - "fcp_txcmplq_cnt=%d, els_txcmplq_cnt=%d\n", + "els_txcmplq_cnt=%d\n", txq_cnt, phba->iocb_cnt, - fcp_txcmplq_cnt, txcmplq_cnt); return false; } @@ -13592,6 +13699,7 @@ phba->sli4_hba.sli4_write_cq_db(phba, cq, consumed, LPFC_QUEUE_NOARM); consumed = 0; + cq->assoc_qp->q_flag |= HBA_EQ_DELAY_CHK; } if (count == LPFC_NVMET_CQ_NOTIFY) @@ -14220,7 +14328,7 @@ spin_lock_irqsave(&phba->hbalock, iflag); if (phba->link_state < LPFC_LINK_DOWN) /* Flush, clear interrupt, and rearm the EQ */ - lpfc_sli4_eq_flush(phba, fpeq); + lpfc_sli4_eqcq_flush(phba, fpeq); spin_unlock_irqrestore(&phba->hbalock, iflag); return IRQ_NONE; } @@ -14230,14 +14338,14 @@ fpeq->last_cpu = raw_smp_processor_id(); if (icnt > LPFC_EQD_ISR_TRIGGER && - phba->cfg_irq_chann == 1 && + fpeq->q_flag & HBA_EQ_DELAY_CHK && phba->cfg_auto_imax && fpeq->q_mode != LPFC_MAX_AUTO_EQ_DELAY && phba->sli.sli_flag & LPFC_SLI_USE_EQDR) lpfc_sli4_mod_hba_eq_delay(phba, fpeq, LPFC_MAX_AUTO_EQ_DELAY); /* process and rearm the EQ */ - ecount = lpfc_sli4_process_eq(phba, fpeq); + ecount = lpfc_sli4_process_eq(phba, fpeq, LPFC_QUEUE_REARM); if (unlikely(ecount == 0)) { fpeq->EQ_no_entry++; @@ -14297,6 +14405,147 @@ return (hba_handled == true) ? IRQ_HANDLED : IRQ_NONE; } /* lpfc_sli4_intr_handler */ +void lpfc_sli4_poll_hbtimer(struct timer_list *t) +{ + struct lpfc_hba *phba = from_timer(phba, t, cpuhp_poll_timer); + struct lpfc_queue *eq; + int i = 0; + + rcu_read_lock(); + + list_for_each_entry_rcu(eq, &phba->poll_list, _poll_list) + i += lpfc_sli4_poll_eq(eq, LPFC_POLL_SLOWPATH); + if (!list_empty(&phba->poll_list)) + mod_timer(&phba->cpuhp_poll_timer, + jiffies + msecs_to_jiffies(LPFC_POLL_HB)); + + rcu_read_unlock(); +} + +inline int lpfc_sli4_poll_eq(struct lpfc_queue *eq, uint8_t path) +{ + struct lpfc_hba *phba = eq->phba; + int i = 0; + + /* + * Unlocking an irq is one of the entry point to check + * for re-schedule, but we are good for io submission + * path as midlayer does a get_cpu to glue us in. Flush + * out the invalidate queue so we can see the updated + * value for flag. + */ + smp_rmb(); + + if (READ_ONCE(eq->mode) == LPFC_EQ_POLL) + /* We will not likely get the completion for the caller + * during this iteration but i guess that's fine. + * Future io's coming on this eq should be able to + * pick it up. As for the case of single io's, they + * will be handled through a sched from polling timer + * function which is currently triggered every 1msec. + */ + i = lpfc_sli4_process_eq(phba, eq, LPFC_QUEUE_NOARM); + + return i; +} + +static inline void lpfc_sli4_add_to_poll_list(struct lpfc_queue *eq) +{ + struct lpfc_hba *phba = eq->phba; + + if (list_empty(&phba->poll_list)) { + timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0); + /* kickstart slowpath processing for this eq */ + mod_timer(&phba->cpuhp_poll_timer, + jiffies + msecs_to_jiffies(LPFC_POLL_HB)); + } + + list_add_rcu(&eq->_poll_list, &phba->poll_list); + synchronize_rcu(); +} + +static inline void lpfc_sli4_remove_from_poll_list(struct lpfc_queue *eq) +{ + struct lpfc_hba *phba = eq->phba; + + /* Disable slowpath processing for this eq. Kick start the eq + * by RE-ARMING the eq's ASAP + */ + list_del_rcu(&eq->_poll_list); + synchronize_rcu(); + + if (list_empty(&phba->poll_list)) + del_timer_sync(&phba->cpuhp_poll_timer); +} + +void lpfc_sli4_cleanup_poll_list(struct lpfc_hba *phba) +{ + struct lpfc_queue *eq, *next; + + list_for_each_entry_safe(eq, next, &phba->poll_list, _poll_list) + list_del(&eq->_poll_list); + + INIT_LIST_HEAD(&phba->poll_list); + synchronize_rcu(); +} + +static inline void +__lpfc_sli4_switch_eqmode(struct lpfc_queue *eq, uint8_t mode) +{ + if (mode == eq->mode) + return; + /* + * currently this function is only called during a hotplug + * event and the cpu on which this function is executing + * is going offline. By now the hotplug has instructed + * the scheduler to remove this cpu from cpu active mask. + * So we don't need to work about being put aside by the + * scheduler for a high priority process. Yes, the inte- + * rrupts could come but they are known to retire ASAP. + */ + + /* Disable polling in the fastpath */ + WRITE_ONCE(eq->mode, mode); + /* flush out the store buffer */ + smp_wmb(); + + /* + * Add this eq to the polling list and start polling. For + * a grace period both interrupt handler and poller will + * try to process the eq _but_ that's fine. We have a + * synchronization mechanism in place (queue_claimed) to + * deal with it. This is just a draining phase for int- + * errupt handler (not eq's) as we have guranteed through + * barrier that all the CPUs have seen the new CQ_POLLED + * state. which will effectively disable the REARMING of + * the EQ. The whole idea is eq's die off eventually as + * we are not rearming EQ's anymore. + */ + mode ? lpfc_sli4_add_to_poll_list(eq) : + lpfc_sli4_remove_from_poll_list(eq); +} + +void lpfc_sli4_start_polling(struct lpfc_queue *eq) +{ + __lpfc_sli4_switch_eqmode(eq, LPFC_EQ_POLL); +} + +void lpfc_sli4_stop_polling(struct lpfc_queue *eq) +{ + struct lpfc_hba *phba = eq->phba; + + __lpfc_sli4_switch_eqmode(eq, LPFC_EQ_INTERRUPT); + + /* Kick start for the pending io's in h/w. + * Once we switch back to interrupt processing on a eq + * the io path completion will only arm eq's when it + * receives a completion. But since eq's are in disa- + * rmed state it doesn't receive a completion. This + * creates a deadlock scenaro. + */ + phba->sli4_hba.sli4_write_eq_db(phba, eq, 0, LPFC_QUEUE_REARM); +} + /** * lpfc_sli4_queue_free - free a queue structure and associated memory * @queue: The queue structure to free. @@ -14371,6 +14620,7 @@ return NULL; INIT_LIST_HEAD(&queue->list); + INIT_LIST_HEAD(&queue->_poll_list); INIT_LIST_HEAD(&queue->wq_list); INIT_LIST_HEAD(&queue->wqfull_list); INIT_LIST_HEAD(&queue->page_list); @@ -16316,8 +16566,7 @@ "2509 RQ_DESTROY mailbox failed with " "status x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, hrq->phba->mbox_mem_pool); + mempool_free(mbox, hrq->phba->mbox_mem_pool); return -ENXIO; } bf_set(lpfc_mbx_rq_destroy_q_id, &mbox->u.mqe.un.rq_destroy.u.request, @@ -16414,7 +16663,9 @@ shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -16609,7 +16860,9 @@ shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, @@ -16722,7 +16975,9 @@ shdr = (union lpfc_sli4_cfg_shdr *)&sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, @@ -17303,7 +17558,6 @@ if (cmd_iocbq) { ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1; lpfc_nlp_put(ndlp); - lpfc_nlp_not_used(ndlp); lpfc_sli_release_iocbq(phba, cmd_iocbq); } @@ -17703,6 +17957,10 @@ list_add_tail(&iocbq->list, &first_iocbq->list); } } + /* Free the sequence's header buffer */ + if (!first_iocbq) + lpfc_in_buf_free(vport->phba, &seq_dmabuf->dbuf); + return first_iocbq; } @@ -18066,8 +18324,7 @@ shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "2514 POST_RPI_HDR mailbox failed with " @@ -18124,8 +18381,9 @@ phba->sli4_hba.max_cfg_param.rpi_used++; phba->sli4_hba.rpi_count++; } - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "0001 rpi:%x max:%x lim:%x\n", + lpfc_printf_log(phba, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, + "0001 Allocated rpi:x%x max:x%x lim:x%x\n", (int) rpi, max_rpi, rpi_limit); /* @@ -18181,11 +18439,19 @@ static void __lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi) { + /* + * if the rpi value indicates a prior unreg has already + * been done, skip the unreg. + */ + if (rpi == LPFC_RPI_ALLOC_ERROR) + return; + if (test_and_clear_bit(rpi, phba->sli4_hba.rpi_bmask)) { phba->sli4_hba.rpi_count--; phba->sli4_hba.max_cfg_param.rpi_used--; } else { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + lpfc_printf_log(phba, KERN_INFO, + LOG_NODE | LOG_DISCOVERY, "2016 rpi %x not inuse\n", rpi); } @@ -19202,7 +19468,7 @@ struct lpfc_mbx_wr_object *wr_object; LPFC_MBOXQ_t *mbox; int rc = 0, i = 0; - uint32_t shdr_status, shdr_add_status, shdr_change_status; + uint32_t shdr_status, shdr_add_status, shdr_change_status, shdr_csf; uint32_t mbox_tmo; struct lpfc_dmabuf *dmabuf; uint32_t written = 0; @@ -19259,6 +19525,16 @@ if (check_change_status) { shdr_change_status = bf_get(lpfc_wr_object_change_status, &wr_object->u.response); + + if (shdr_change_status == LPFC_CHANGE_STATUS_FW_RESET || + shdr_change_status == LPFC_CHANGE_STATUS_PORT_MIGRATION) { + shdr_csf = bf_get(lpfc_wr_object_csf, + &wr_object->u.response); + if (shdr_csf) + shdr_change_status = + LPFC_CHANGE_STATUS_PCI_RESET; + } + switch (shdr_change_status) { case (LPFC_CHANGE_STATUS_PHYS_DEV_RESET): lpfc_printf_log(phba, KERN_INFO, LOG_INIT, @@ -19285,7 +19561,9 @@ break; } } - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -19503,6 +19781,7 @@ fail_msg, piocbq->iotag, piocbq->sli4_xritag); list_add_tail(&piocbq->list, &completions); + fail_msg = NULL; } spin_unlock_irqrestore(&pring->ring_lock, iflags); } @@ -19683,6 +19962,8 @@ lpfc_sli_ringtxcmpl_put(phba, pring, pwqe); spin_unlock_irqrestore(&pring->ring_lock, iflags); + + lpfc_sli4_poll_eq(qp->hba_eq, LPFC_POLL_FASTPATH); return 0; } @@ -19703,6 +19984,8 @@ } lpfc_sli_ringtxcmpl_put(phba, pring, pwqe); spin_unlock_irqrestore(&pring->ring_lock, iflags); + + lpfc_sli4_poll_eq(qp->hba_eq, LPFC_POLL_FASTPATH); return 0; } @@ -19731,6 +20014,8 @@ } lpfc_sli_ringtxcmpl_put(phba, pring, pwqe); spin_unlock_irqrestore(&pring->ring_lock, iflags); + + lpfc_sli4_poll_eq(qp->hba_eq, LPFC_POLL_FASTPATH); return 0; } return WQE_ERROR; @@ -20093,6 +20378,13 @@ lpfc_ncmd->cur_iocbq.wqe_cmpl = NULL; lpfc_ncmd->cur_iocbq.iocb_cmpl = NULL; + if (phba->cfg_xpsgl && !phba->nvmet_support && + !list_empty(&lpfc_ncmd->dma_sgl_xtra_list)) + lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd); + + if (!list_empty(&lpfc_ncmd->dma_cmd_rsp_list)) + lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd); + if (phba->cfg_xri_rebalancing) { if (lpfc_ncmd->expedite) { /* Return to expedite pool */ @@ -20157,13 +20449,6 @@ spin_unlock_irqrestore(&qp->io_buf_list_put_lock, iflag); } - - if (phba->cfg_xpsgl && !phba->nvmet_support && - !list_empty(&lpfc_ncmd->dma_sgl_xtra_list)) - lpfc_put_sgl_per_hdwq(phba, lpfc_ncmd); - - if (!list_empty(&lpfc_ncmd->dma_cmd_rsp_list)) - lpfc_put_cmd_rsp_buf_per_hdwq(phba, lpfc_ncmd); } /** @@ -20217,20 +20502,20 @@ static struct lpfc_io_buf * lpfc_get_io_buf_from_expedite_pool(struct lpfc_hba *phba) { - struct lpfc_io_buf *lpfc_ncmd; + struct lpfc_io_buf *lpfc_ncmd = NULL, *iter; struct lpfc_io_buf *lpfc_ncmd_next; unsigned long iflag; struct lpfc_epd_pool *epd_pool; epd_pool = &phba->epd_pool; - lpfc_ncmd = NULL; spin_lock_irqsave(&epd_pool->lock, iflag); if (epd_pool->count > 0) { - list_for_each_entry_safe(lpfc_ncmd, lpfc_ncmd_next, + list_for_each_entry_safe(iter, lpfc_ncmd_next, &epd_pool->list, list) { - list_del(&lpfc_ncmd->list); + list_del(&iter->list); epd_pool->count--; + lpfc_ncmd = iter; break; } } @@ -20399,8 +20684,9 @@ struct sli4_hybrid_sgl *allocated_sgl = NULL; struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; struct list_head *buf_list = &hdwq->sgl_list; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); if (likely(!list_empty(buf_list))) { /* break off 1 chunk from the sgl_list */ @@ -20412,9 +20698,9 @@ } } else { /* allocate more */ - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); tmp = kmalloc_node(sizeof(*tmp), GFP_ATOMIC, - cpu_to_node(smp_processor_id())); + cpu_to_node(hdwq->io_wq->chann)); if (!tmp) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "8353 error kmalloc memory for HDWQ " @@ -20434,7 +20720,7 @@ return NULL; } - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); list_add_tail(&tmp->list_node, &lpfc_buf->dma_sgl_xtra_list); } @@ -20442,7 +20728,7 @@ struct sli4_hybrid_sgl, list_node); - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); return allocated_sgl; } @@ -20466,8 +20752,9 @@ struct sli4_hybrid_sgl *tmp = NULL; struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; struct list_head *buf_list = &hdwq->sgl_list; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); if (likely(!list_empty(&lpfc_buf->dma_sgl_xtra_list))) { list_for_each_entry_safe(list_entry, tmp, @@ -20480,7 +20767,7 @@ rc = -EINVAL; } - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); return rc; } @@ -20501,8 +20788,9 @@ struct list_head *buf_list = &hdwq->sgl_list; struct sli4_hybrid_sgl *list_entry = NULL; struct sli4_hybrid_sgl *tmp = NULL; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); /* Free sgl pool */ list_for_each_entry_safe(list_entry, tmp, @@ -20514,7 +20802,7 @@ kfree(list_entry); } - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); } /** @@ -20538,8 +20826,9 @@ struct fcp_cmd_rsp_buf *allocated_buf = NULL; struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); if (likely(!list_empty(buf_list))) { /* break off 1 chunk from the list */ @@ -20552,9 +20841,9 @@ } } else { /* allocate more */ - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); tmp = kmalloc_node(sizeof(*tmp), GFP_ATOMIC, - cpu_to_node(smp_processor_id())); + cpu_to_node(hdwq->io_wq->chann)); if (!tmp) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "8355 error kmalloc memory for HDWQ " @@ -20579,7 +20868,7 @@ tmp->fcp_rsp = (struct fcp_rsp *)((uint8_t *)tmp->fcp_cmnd + sizeof(struct fcp_cmnd)); - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); list_add_tail(&tmp->list_node, &lpfc_buf->dma_cmd_rsp_list); } @@ -20587,7 +20876,7 @@ struct fcp_cmd_rsp_buf, list_node); - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); return allocated_buf; } @@ -20612,8 +20901,9 @@ struct fcp_cmd_rsp_buf *tmp = NULL; struct lpfc_sli4_hdw_queue *hdwq = lpfc_buf->hdwq; struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); if (likely(!list_empty(&lpfc_buf->dma_cmd_rsp_list))) { list_for_each_entry_safe(list_entry, tmp, @@ -20626,7 +20916,7 @@ rc = -EINVAL; } - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); return rc; } @@ -20647,8 +20937,9 @@ struct list_head *buf_list = &hdwq->cmd_rsp_buf_list; struct fcp_cmd_rsp_buf *list_entry = NULL; struct fcp_cmd_rsp_buf *tmp = NULL; + unsigned long iflags; - spin_lock_irq(&hdwq->hdwq_lock); + spin_lock_irqsave(&hdwq->hdwq_lock, iflags); /* Free cmd_rsp buf pool */ list_for_each_entry_safe(list_entry, tmp, @@ -20661,5 +20952,5 @@ kfree(list_entry); } - spin_unlock_irq(&hdwq->hdwq_lock); + spin_unlock_irqrestore(&hdwq->hdwq_lock, iflags); } --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_sli.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_sli.h @@ -384,14 +384,13 @@ struct lpfc_nodelist *ndlp; uint32_t timeout; - uint16_t flags; /* TBD convert exch_busy to flags */ + uint16_t flags; #define LPFC_SBUF_XBUSY 0x1 /* SLI4 hba reported XB on WCQE cmpl */ #define LPFC_SBUF_BUMP_QDEPTH 0x2 /* bumped queue depth counter */ /* External DIF device IO conversions */ #define LPFC_SBUF_NORMAL_DIF 0x4 /* normal mode to insert/strip */ #define LPFC_SBUF_PASS_DIF 0x8 /* insert/strip mode to passthru */ #define LPFC_SBUF_NOT_POSTED 0x10 /* SGL failed post to FW. */ - uint16_t exch_busy; /* SLI4 hba reported XB on complete WCQE */ uint16_t status; /* From IOCB Word 7- ulpStatus */ uint32_t result; /* From IOCB Word 4. */ --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_sli4.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_sli4.h @@ -41,8 +41,13 @@ /* Multi-queue arrangement for FCP EQ/CQ/WQ tuples */ #define LPFC_HBA_HDWQ_MIN 0 -#define LPFC_HBA_HDWQ_MAX 128 -#define LPFC_HBA_HDWQ_DEF 0 +#define LPFC_HBA_HDWQ_MAX 256 +#define LPFC_HBA_HDWQ_DEF LPFC_HBA_HDWQ_MIN + +/* irq_chann range, values */ +#define LPFC_IRQ_CHANN_MIN 0 +#define LPFC_IRQ_CHANN_MAX 256 +#define LPFC_IRQ_CHANN_DEF LPFC_IRQ_CHANN_MIN /* FCP MQ queue count limiting */ #define LPFC_FCP_MQ_THRESHOLD_MIN 0 @@ -133,6 +138,23 @@ struct lpfc_queue { struct list_head list; struct list_head wq_list; + + /* + * If interrupts are in effect on _all_ the eq's the footprint + * of polling code is zero (except mode). This memory is chec- + * ked for every io to see if the io needs to be polled and + * while completion to check if the eq's needs to be rearmed. + * Keep in same cacheline as the queue ptr to avoid cpu fetch + * stalls. Using 1B memory will leave us with 7B hole. Fill + * it with other frequently used members. + */ + uint16_t last_cpu; /* most recent cpu */ + uint16_t hdwq; + uint8_t qe_valid; + uint8_t mode; /* interrupt or polling */ +#define LPFC_EQ_INTERRUPT 0 +#define LPFC_EQ_POLL 1 + struct list_head wqfull_list; enum lpfc_sli4_queue_type type; enum lpfc_sli4_queue_subtype subtype; @@ -199,6 +221,7 @@ uint8_t q_flag; #define HBA_NVMET_WQFULL 0x1 /* We hit WQ Full condition for NVMET */ #define HBA_NVMET_CQ_NOTIFY 0x1 /* LPFC_NVMET_CQ_NOTIFY CQEs this EQE */ +#define HBA_EQ_DELAY_CHK 0x2 /* EQ is a candidate for coalescing */ #define LPFC_NVMET_CQ_NOTIFY 4 void __iomem *db_regaddr; uint16_t dpp_enable; @@ -239,10 +262,8 @@ struct delayed_work sched_spwork; uint64_t isr_timestamp; - uint16_t hdwq; - uint16_t last_cpu; /* most recent cpu */ - uint8_t qe_valid; struct lpfc_queue *assoc_qp; + struct list_head _poll_list; void **q_pgs; /* array to index entries per page */ }; @@ -451,11 +472,17 @@ #define LPFC_SLI4_HANDLER_NAME_SZ 16 struct lpfc_hba_eq_hdl { uint32_t idx; + uint16_t irq; char handler_name[LPFC_SLI4_HANDLER_NAME_SZ]; struct lpfc_hba *phba; struct lpfc_queue *eq; + struct cpumask aff_mask; }; +#define lpfc_get_eq_hdl(eqidx) (&phba->sli4_hba.hba_eq_hdl[eqidx]) +#define lpfc_get_aff_mask(eqidx) (&phba->sli4_hba.hba_eq_hdl[eqidx].aff_mask) +#define lpfc_get_irq(eqidx) (phba->sli4_hba.hba_eq_hdl[eqidx].irq) + /*BB Credit recovery value*/ struct lpfc_bbscn_params { uint32_t word0; @@ -513,6 +540,7 @@ uint8_t cqav; uint8_t wqsize; uint8_t bv1s; + uint8_t pls; #define LPFC_WQ_SZ64_SUPPORT 1 #define LPFC_WQ_SZ128_SUPPORT 2 uint8_t wqpcnt; @@ -544,11 +572,10 @@ #define LPFC_SLI4_HANDLER_CNT (LPFC_HBA_IO_CHAN_MAX+ \ LPFC_FOF_IO_CHAN_NUM) -/* Used for IRQ vector to CPU mapping */ +/* Used for tracking CPU mapping attributes */ struct lpfc_vector_map_info { uint16_t phys_id; uint16_t core_id; - uint16_t irq; uint16_t eq; uint16_t hdwq; uint16_t flag; @@ -891,6 +918,7 @@ struct lpfc_vector_map_info *cpu_map; uint16_t num_possible_cpu; uint16_t num_present_cpu; + struct cpumask numa_mask; uint16_t curr_disp_cpu; struct lpfc_eq_intr_info __percpu *eq_info; uint32_t conf_trunk; --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_version.h +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "12.4.0.0" +#define LPFC_DRIVER_VERSION "12.6.0.4" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ --- linux-oracle-5.4.0.orig/drivers/scsi/lpfc/lpfc_vport.c +++ linux-oracle-5.4.0/drivers/scsi/lpfc/lpfc_vport.c @@ -642,27 +642,16 @@ vport->port_state < LPFC_VPORT_READY) return -EAGAIN; } + /* - * This is a bit of a mess. We want to ensure the shost doesn't get - * torn down until we're done with the embedded lpfc_vport structure. - * - * Beyond holding a reference for this function, we also need a - * reference for outstanding I/O requests we schedule during delete - * processing. But once we scsi_remove_host() we can no longer obtain - * a reference through scsi_host_get(). - * - * So we take two references here. We release one reference at the - * bottom of the function -- after delinking the vport. And we - * release the other at the completion of the unreg_vpi that get's - * initiated after we've disposed of all other resources associated - * with the port. + * Take early refcount for outstanding I/O requests we schedule during + * delete processing for unreg_vpi. Always keep this before + * scsi_remove_host() as we can no longer obtain a reference through + * scsi_host_get() after scsi_host_remove as shost is set to SHOST_DEL. */ if (!scsi_host_get(shost)) return VPORT_INVAL; - if (!scsi_host_get(shost)) { - scsi_host_put(shost); - return VPORT_INVAL; - } + lpfc_free_sysfs_attr(vport); lpfc_debugfs_terminate(vport); @@ -679,10 +668,6 @@ ns_ndlp_referenced = true; } - /* Remove FC host and then SCSI host with the vport */ - fc_remove_host(shost); - scsi_remove_host(shost); - ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); /* In case of driver unload, we shall not perform fabric logo as the @@ -794,6 +779,10 @@ lpfc_nlp_put(ndlp); } + /* Remove FC host to break driver binding. */ + fc_remove_host(shost); + scsi_remove_host(shost); + lpfc_cleanup(vport); lpfc_sli_host_down(vport); @@ -809,8 +798,9 @@ if (!(vport->vpi_state & LPFC_VPI_REGISTERED) || lpfc_mbx_unreg_vpi(vport)) scsi_host_put(shost); - } else + } else { scsi_host_put(shost); + } lpfc_free_vpi(phba, vport->vpi); vport->work_port_events = 0; --- linux-oracle-5.4.0.orig/drivers/scsi/mac_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/mac_scsi.c @@ -464,7 +464,7 @@ mac_scsi_template.can_queue = setup_can_queue; if (setup_cmd_per_lun > 0) mac_scsi_template.cmd_per_lun = setup_cmd_per_lun; - if (setup_sg_tablesize >= 0) + if (setup_sg_tablesize > 0) mac_scsi_template.sg_tablesize = setup_sg_tablesize; if (setup_hostid >= 0) mac_scsi_template.this_id = setup_hostid & 7; --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid.c +++ linux-oracle-5.4.0/drivers/scsi/megaraid.c @@ -1439,6 +1439,7 @@ */ if (cmdid == CMDID_INT_CMDS) { scb = &adapter->int_scb; + cmd = scb->cmd; list_del_init(&scb->list); scb->state = SCB_FREE; @@ -4635,7 +4636,7 @@ * major number allocation. */ major = register_chrdev(0, "megadev_legacy", &megadev_fops); - if (!major) { + if (major < 0) { printk(KERN_WARNING "megaraid: failed to register char device\n"); } --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_mm.c +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_mm.c @@ -41,10 +41,6 @@ static void mraid_mm_free_adp_resources(mraid_mmadp_t *); static void mraid_mm_teardown_dma_pools(mraid_mmadp_t *); -#ifdef CONFIG_COMPAT -static long mraid_mm_compat_ioctl(struct file *, unsigned int, unsigned long); -#endif - MODULE_AUTHOR("LSI Logic Corporation"); MODULE_DESCRIPTION("LSI Logic Management Module"); MODULE_LICENSE("GPL"); @@ -68,9 +64,7 @@ static const struct file_operations lsi_fops = { .open = mraid_mm_open, .unlocked_ioctl = mraid_mm_unlocked_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = mraid_mm_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, .owner = THIS_MODULE, .llseek = noop_llseek, }; @@ -224,7 +218,6 @@ { int err; - /* inconsistent: mraid_mm_compat_ioctl doesn't take the BKL */ mutex_lock(&mraid_mm_mutex); err = mraid_mm_ioctl(filep, cmd, arg); mutex_unlock(&mraid_mm_mutex); @@ -246,7 +239,7 @@ mimd_t mimd; uint32_t adapno; int iterator; - + bool is_found; if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) { *rval = -EFAULT; @@ -262,12 +255,16 @@ adapter = NULL; iterator = 0; + is_found = false; list_for_each_entry(adapter, &adapters_list_g, list) { - if (iterator++ == adapno) break; + if (iterator++ == adapno) { + is_found = true; + break; + } } - if (!adapter) { + if (!is_found) { *rval = -ENODEV; return NULL; } @@ -733,6 +730,7 @@ uint32_t adapno; int iterator; mraid_mmadp_t* adapter; + bool is_found; /* * When the kioc returns from driver, make sure it still doesn't @@ -755,19 +753,23 @@ iterator = 0; adapter = NULL; adapno = kioc->adapno; + is_found = false; con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed " "ioctl that was timedout before\n")); list_for_each_entry(adapter, &adapters_list_g, list) { - if (iterator++ == adapno) break; + if (iterator++ == adapno) { + is_found = true; + break; + } } kioc->timedout = 0; - if (adapter) { + if (is_found) mraid_mm_dealloc_kioc( adapter, kioc ); - } + } else { wake_up(&wait_q); @@ -1228,25 +1230,6 @@ } -#ifdef CONFIG_COMPAT -/** - * mraid_mm_compat_ioctl - 32bit to 64bit ioctl conversion routine - * @filep : file operations pointer (ignored) - * @cmd : ioctl command - * @arg : user ioctl packet - */ -static long -mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - int err; - - err = mraid_mm_ioctl(filep, cmd, arg); - - return err; -} -#endif - /** * mraid_mm_exit - Module exit point */ --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_sas.h +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_sas.h @@ -21,8 +21,10 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION "07.710.50.00-rc1" -#define MEGASAS_RELDATE "June 28, 2019" +#define MEGASAS_VERSION "07.713.01.00-rc1" +#define MEGASAS_RELDATE "Dec 27, 2019" + +#define MEGASAS_MSIX_NAME_LEN 32 /* * Device IDs @@ -1515,6 +1517,8 @@ #define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \ MEGASAS_MAX_DEV_PER_CHANNEL) +#define MEGASAS_MAX_SUPPORTED_LD_IDS 240 + #define MEGASAS_MAX_SECTORS (2*1024) #define MEGASAS_MAX_SECTORS_IEEE (2*128) #define MEGASAS_DBG_LVL 1 @@ -2203,6 +2207,7 @@ }; struct megasas_irq_context { + char name[MEGASAS_MSIX_NAME_LEN]; struct megasas_instance *instance; u32 MSIxIndex; u32 os_irq; @@ -2230,9 +2235,9 @@ /* JBOD Queue depth definitions */ #define MEGASAS_SATA_QD 32 -#define MEGASAS_SAS_QD 64 +#define MEGASAS_SAS_QD 256 #define MEGASAS_DEFAULT_PD_QD 64 -#define MEGASAS_NVME_QD 32 +#define MEGASAS_NVME_QD 64 #define MR_DEFAULT_NVME_PAGE_SIZE 4096 #define MR_DEFAULT_NVME_PAGE_SHIFT 12 @@ -2256,6 +2261,15 @@ (mode) == MR_LATENCY_PERF_MODE ? "Latency" : \ "Unknown") +enum MEGASAS_LD_TARGET_ID_STATUS { + LD_TARGET_ID_INITIAL, + LD_TARGET_ID_ACTIVE, + LD_TARGET_ID_DELETED, +}; + +#define MEGASAS_TARGET_ID(sdev) \ + (((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id) + struct megasas_instance { unsigned int *reply_map; @@ -2313,13 +2327,16 @@ u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ bool use_seqnum_jbod_fp; /* Added for PD sequence */ bool smp_affinity_enable; - spinlock_t crashdump_lock; + struct mutex crashdump_lock; struct megasas_register_set __iomem *reg_set; u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD]; u8 ld_ids[MEGASAS_MAX_LD_IDS]; + u8 ld_tgtid_status[MEGASAS_MAX_LD_IDS]; + u8 ld_ids_prev[MEGASAS_MAX_LD_IDS]; + u8 ld_ids_from_raidmap[MEGASAS_MAX_LD_IDS]; s8 init_id; u16 max_num_sge; @@ -2539,6 +2556,9 @@ #define MEGASAS_IS_LOGICAL(sdev) \ ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1) +#define MEGASAS_IS_LUN_VALID(sdev) \ + (((sdev)->lun == 0) ? 1 : 0) + #define MEGASAS_DEV_INDEX(scp) \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ scp->device->id) @@ -2637,10 +2657,11 @@ }; enum DCMD_RETURN_STATUS { - DCMD_SUCCESS = 0, - DCMD_TIMEOUT = 1, - DCMD_FAILED = 2, - DCMD_NOT_FIRED = 3, + DCMD_SUCCESS = 0x00, + DCMD_TIMEOUT = 0x01, + DCMD_FAILED = 0x02, + DCMD_BUSY = 0x03, + DCMD_INIT = 0xff, }; u8 --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_sas_base.c +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_sas_base.c @@ -127,6 +127,8 @@ u32 seq_num, u32 class_locale_word); static void megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev); +static void +megasas_set_ld_removed_by_fw(struct megasas_instance *instance); /* * PCI ID table for all supported controllers @@ -199,7 +201,7 @@ static bool support_pci_lane_margining; /* define lock for aen poll */ -spinlock_t poll_aen_lock; +static spinlock_t poll_aen_lock; extern struct dentry *megasas_debugfs_root; extern void megasas_init_debugfs(void); @@ -250,13 +252,13 @@ * Fusion registers could intermittently return all zeroes. * This behavior is transient in nature and subsequent reads will * return valid value. As a workaround in driver, retry readl for - * upto three times until a non-zero value is read. + * up to thirty times until a non-zero value is read. */ if (instance->adapter_type == AERO_SERIES) { do { ret_val = readl(addr); i++; - } while (ret_val == 0 && i < 3); + } while (ret_val == 0 && i < 30); return ret_val; } else { return readl(addr); @@ -425,6 +427,12 @@ (class_locale.members.locale), format_class(class_locale.members.class), evt_detail->description); + + if (megasas_dbg_lvl & LD_PD_DEBUG) + dev_info(&instance->pdev->dev, + "evt_detail.args.ld.target_id/index %d/%d\n", + evt_detail->args.ld.target_id, evt_detail->args.ld.ld_index); + } /** @@ -1099,7 +1107,7 @@ if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); - return DCMD_NOT_FIRED; + return DCMD_INIT; } instance->instancet->issue_dcmd(instance, cmd); @@ -1123,19 +1131,19 @@ struct megasas_cmd *cmd, int timeout) { int ret = 0; - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; + cmd->cmd_status_drv = DCMD_INIT; if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); - return DCMD_NOT_FIRED; + return DCMD_INIT; } instance->instancet->issue_dcmd(instance, cmd); if (timeout) { ret = wait_event_timeout(instance->int_cmd_wait_q, - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); + cmd->cmd_status_drv != DCMD_INIT, timeout * HZ); if (!ret) { dev_err(&instance->pdev->dev, "DCMD(opcode: 0x%x) is timed out, func:%s\n", @@ -1144,10 +1152,9 @@ } } else wait_event(instance->int_cmd_wait_q, - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS); + cmd->cmd_status_drv != DCMD_INIT); - return (cmd->cmd_status_drv == MFI_STAT_OK) ? - DCMD_SUCCESS : DCMD_FAILED; + return cmd->cmd_status_drv; } /** @@ -1190,19 +1197,19 @@ cpu_to_le32(upper_32_bits(cmd_to_abort->frame_phys_addr)); cmd->sync_cmd = 1; - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; + cmd->cmd_status_drv = DCMD_INIT; if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); - return DCMD_NOT_FIRED; + return DCMD_INIT; } instance->instancet->issue_dcmd(instance, cmd); if (timeout) { ret = wait_event_timeout(instance->abort_cmd_wait_q, - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS, timeout * HZ); + cmd->cmd_status_drv != DCMD_INIT, timeout * HZ); if (!ret) { opcode = cmd_to_abort->frame->dcmd.opcode; dev_err(&instance->pdev->dev, @@ -1212,13 +1219,12 @@ } } else wait_event(instance->abort_cmd_wait_q, - cmd->cmd_status_drv != MFI_STAT_INVALID_STATUS); + cmd->cmd_status_drv != DCMD_INIT); cmd->sync_cmd = 0; megasas_return_cmd(instance, cmd); - return (cmd->cmd_status_drv == MFI_STAT_OK) ? - DCMD_SUCCESS : DCMD_FAILED; + return cmd->cmd_status_drv; } /** @@ -1759,6 +1765,7 @@ { struct megasas_instance *instance; struct MR_PRIV_DEVICE *mr_device_priv_data; + u32 ld_tgt_id; instance = (struct megasas_instance *) scmd->device->host->hostdata; @@ -1785,17 +1792,21 @@ } } - if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { + mr_device_priv_data = scmd->device->hostdata; + if (!mr_device_priv_data || + (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)) { scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); return 0; } - mr_device_priv_data = scmd->device->hostdata; - if (!mr_device_priv_data) { - scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); - return 0; + if (MEGASAS_IS_LOGICAL(scmd->device)) { + ld_tgt_id = MEGASAS_TARGET_ID(scmd->device); + if (instance->ld_tgtid_status[ld_tgt_id] == LD_TARGET_ID_DELETED) { + scmd->result = DID_NO_CONNECT << 16; + scmd->scsi_done(scmd); + return 0; + } } if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) @@ -1887,6 +1898,10 @@ mr_device_priv_data->is_tm_capable = raid->capability.tmCapable; + + if (!raid->flags.isEPD) + sdev->no_write_same = 1; + } else if (instance->use_seqnum_jbod_fp) { pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id; @@ -2071,7 +2086,7 @@ static int megasas_slave_alloc(struct scsi_device *sdev) { - u16 pd_index = 0; + u16 pd_index = 0, ld_tgt_id; struct megasas_instance *instance ; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -2089,6 +2104,9 @@ goto scan_target; } return -ENXIO; + } else if (!MEGASAS_IS_LUN_VALID(sdev)) { + sdev_printk(KERN_INFO, sdev, "%s: invalid LUN\n", __func__); + return -ENXIO; } scan_target: @@ -2096,6 +2114,14 @@ GFP_KERNEL); if (!mr_device_priv_data) return -ENOMEM; + + if (MEGASAS_IS_LOGICAL(sdev)) { + ld_tgt_id = MEGASAS_TARGET_ID(sdev); + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_ACTIVE; + if (megasas_dbg_lvl & LD_PD_DEBUG) + sdev_printk(KERN_INFO, sdev, "LD target ID %d created.\n", ld_tgt_id); + } + sdev->hostdata = mr_device_priv_data; atomic_set(&mr_device_priv_data->r1_ldio_hint, @@ -2105,6 +2131,23 @@ static void megasas_slave_destroy(struct scsi_device *sdev) { + u16 ld_tgt_id; + struct megasas_instance *instance; + + instance = megasas_lookup_instance(sdev->host->host_no); + + if (MEGASAS_IS_LOGICAL(sdev)) { + if (!MEGASAS_IS_LUN_VALID(sdev)) { + sdev_printk(KERN_INFO, sdev, "%s: invalid LUN\n", __func__); + return; + } + ld_tgt_id = MEGASAS_TARGET_ID(sdev); + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_DELETED; + if (megasas_dbg_lvl & LD_PD_DEBUG) + sdev_printk(KERN_INFO, sdev, + "LD target ID %d removed from OS stack\n", ld_tgt_id); + } + kfree(sdev->hostdata); sdev->hostdata = NULL; } @@ -2150,6 +2193,12 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) { + if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { + dev_warn(&instance->pdev->dev, + "Adapter already dead, skipping kill HBA\n"); + return; + } + /* Set critical error to block I/O & ioctls in case caller didn't */ atomic_set(&instance->adprecovery, MEGASAS_HW_CRITICAL_ERROR); /* Wait 1 second to ensure IO or ioctls in build have posted */ @@ -2726,7 +2775,7 @@ "reset queue\n", reset_cmd); - reset_cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; + reset_cmd->cmd_status_drv = DCMD_INIT; instance->instancet->fire_cmd(instance, reset_cmd->frame_phys_addr, 0, instance->reg_set); @@ -3167,14 +3216,13 @@ struct megasas_instance *instance = (struct megasas_instance *) shost->hostdata; int val = 0; - unsigned long flags; if (kstrtoint(buf, 0, &val) != 0) return -EINVAL; - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); instance->fw_crash_buffer_offset = val; - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return strlen(buf); } @@ -3189,24 +3237,23 @@ unsigned long dmachunk = CRASH_DMA_BUF_SIZE; unsigned long chunk_left_bytes; unsigned long src_addr; - unsigned long flags; u32 buff_offset; - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); buff_offset = instance->fw_crash_buffer_offset; - if (!instance->crash_dump_buf && + if (!instance->crash_dump_buf || !((instance->fw_crash_state == AVAILABLE) || (instance->fw_crash_state == COPYING))) { dev_err(&instance->pdev->dev, "Firmware crash dump is not available\n"); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return -EINVAL; } if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { dev_err(&instance->pdev->dev, "Firmware crash dump offset is out of range\n"); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return 0; } @@ -3218,7 +3265,7 @@ src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + (buff_offset % dmachunk); memcpy(buf, (void *)src_addr, size); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return size; } @@ -3243,7 +3290,6 @@ struct megasas_instance *instance = (struct megasas_instance *) shost->hostdata; int val = 0; - unsigned long flags; if (kstrtoint(buf, 0, &val) != 0) return -EINVAL; @@ -3257,9 +3303,9 @@ instance->fw_crash_state = val; if ((val == COPIED) || (val == COPY_ERROR)) { - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); megasas_free_host_crash_buffer(instance); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); if (val == COPY_ERROR) dev_info(&instance->pdev->dev, "application failed to " "copy Firmware crash dump\n"); @@ -3416,7 +3462,6 @@ .bios_param = megasas_bios_param, .change_queue_depth = scsi_change_queue_depth, .max_segment_size = 0xffffffff, - .no_write_same = 1, }; /** @@ -3432,7 +3477,11 @@ megasas_complete_int_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd) { - cmd->cmd_status_drv = cmd->frame->io.cmd_status; + if (cmd->cmd_status_drv == DCMD_INIT) + cmd->cmd_status_drv = + (cmd->frame->io.cmd_status == MFI_STAT_OK) ? + DCMD_SUCCESS : DCMD_FAILED; + wake_up(&instance->int_cmd_wait_q); } @@ -3451,11 +3500,27 @@ { if (cmd->sync_cmd) { cmd->sync_cmd = 0; - cmd->cmd_status_drv = 0; + cmd->cmd_status_drv = DCMD_SUCCESS; wake_up(&instance->abort_cmd_wait_q); } } +static void +megasas_set_ld_removed_by_fw(struct megasas_instance *instance) +{ + uint i; + + for (i = 0; (i < MEGASAS_MAX_LD_IDS); i++) { + if (instance->ld_ids_prev[i] != 0xff && + instance->ld_ids_from_raidmap[i] == 0xff) { + if (megasas_dbg_lvl & LD_PD_DEBUG) + dev_info(&instance->pdev->dev, + "LD target ID %d removed from RAID map\n", i); + instance->ld_tgtid_status[i] = LD_TARGET_ID_DELETED; + } + } +} + /** * megasas_complete_cmd - Completes a command * @instance: Adapter soft state @@ -3618,9 +3683,13 @@ fusion->fast_path_io = 0; } + if (instance->adapter_type >= INVADER_SERIES) + megasas_set_ld_removed_by_fw(instance); + megasas_sync_map_info(instance); spin_unlock_irqrestore(instance->host->host_lock, flags); + break; } if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO || @@ -3727,7 +3796,7 @@ dev_notice(&instance->pdev->dev, "%p synchronous cmd" "on the internal reset queue," "issue it again.\n", cmd); - cmd->cmd_status_drv = MFI_STAT_INVALID_STATUS; + cmd->cmd_status_drv = DCMD_INIT; instance->instancet->fire_cmd(instance, cmd->frame_phys_addr, 0, instance->reg_set); @@ -4392,7 +4461,8 @@ if (instance->adapter_type == MFI_SERIES) return KILL_ADAPTER; else if (instance->unload || - test_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags)) + test_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, + &instance->reset_flags)) return IGNORE_TIMEOUT; else return INITIATE_OCR; @@ -5546,9 +5616,11 @@ pdev = instance->pdev; instance->irq_context[0].instance = instance; instance->irq_context[0].MSIxIndex = 0; + snprintf(instance->irq_context->name, MEGASAS_MSIX_NAME_LEN, "%s%u", + "megasas", instance->host->host_no); if (request_irq(pci_irq_vector(pdev, 0), instance->instancet->service_isr, IRQF_SHARED, - "megasas", &instance->irq_context[0])) { + instance->irq_context->name, &instance->irq_context[0])) { dev_err(&instance->pdev->dev, "Failed to register IRQ from %s %d\n", __func__, __LINE__); @@ -5580,14 +5652,20 @@ for (i = 0; i < instance->msix_vectors; i++) { instance->irq_context[i].instance = instance; instance->irq_context[i].MSIxIndex = i; + snprintf(instance->irq_context[i].name, MEGASAS_MSIX_NAME_LEN, "%s%u-msix%u", + "megasas", instance->host->host_no, i); if (request_irq(pci_irq_vector(pdev, i), - instance->instancet->service_isr, 0, "megasas", + instance->instancet->service_isr, 0, instance->irq_context[i].name, &instance->irq_context[i])) { dev_err(&instance->pdev->dev, "Failed to register IRQ for vector %d.\n", i); - for (j = 0; j < i; j++) + for (j = 0; j < i; j++) { + if (j < instance->low_latency_index_start) + irq_set_affinity_hint( + pci_irq_vector(pdev, j), NULL); free_irq(pci_irq_vector(pdev, j), &instance->irq_context[j]); + } /* Retry irq register for IO_APIC*/ instance->msix_vectors = 0; instance->msix_load_balance = false; @@ -5625,6 +5703,9 @@ if (instance->msix_vectors) for (i = 0; i < instance->msix_vectors; i++) { + if (i < instance->low_latency_index_start) + irq_set_affinity_hint( + pci_irq_vector(instance->pdev, i), NULL); free_irq(pci_irq_vector(instance->pdev, i), &instance->irq_context[i]); } @@ -7232,7 +7313,7 @@ init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); - spin_lock_init(&instance->crashdump_lock); + mutex_init(&instance->crashdump_lock); spin_lock_init(&instance->mfi_pool_lock); spin_lock_init(&instance->hba_lock); spin_lock_init(&instance->stream_lock); @@ -7407,11 +7488,16 @@ return 0; fail_start_aen: + instance->unload = 1; + scsi_remove_host(instance->host); fail_io_attach: megasas_mgmt_info.count--; megasas_mgmt_info.max_index--; megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; + if (instance->requestorId && !instance->skip_heartbeat_timer_del) + del_timer_sync(&instance->sriov_heartbeat_timer); + instance->instancet->disable_intr(instance); megasas_destroy_irqs(instance); @@ -7419,8 +7505,16 @@ megasas_release_fusion(instance); else megasas_release_mfi(instance); + if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); + instance->msix_vectors = 0; + + if (instance->fw_crash_state != UNAVAILABLE) + megasas_free_host_crash_buffer(instance); + + if (instance->adapter_type != MFI_SERIES) + megasas_fusion_stop_watchdog(instance); fail_init_mfi: scsi_host_put(host); fail_alloc_instance: @@ -7588,7 +7682,7 @@ int rval; struct Scsi_Host *host; struct megasas_instance *instance; - int irq_flags = PCI_IRQ_LEGACY; + u32 status_reg; instance = pci_get_drvdata(pdev); @@ -7616,9 +7710,35 @@ /* * We expect the FW state to be READY */ - if (megasas_transition_to_ready(instance, 0)) - goto fail_ready_state; + if (megasas_transition_to_ready(instance, 0)) { + dev_info(&instance->pdev->dev, + "Failed to transition controller to ready from %s!\n", + __func__); + if (instance->adapter_type != MFI_SERIES) { + status_reg = + instance->instancet->read_fw_status_reg(instance); + if (!(status_reg & MFI_RESET_ADAPTER) || + ((megasas_adp_reset_wait_for_ready + (instance, true, 0)) == FAILED)) + goto fail_ready_state; + } else { + atomic_set(&instance->fw_reset_no_pci_access, 1); + instance->instancet->adp_reset + (instance, instance->reg_set); + atomic_set(&instance->fw_reset_no_pci_access, 0); + + /* waiting for about 30 seconds before retry */ + ssleep(30); + + if (megasas_transition_to_ready(instance, 0)) + goto fail_ready_state; + } + + dev_info(&instance->pdev->dev, + "FW restarted successfully from %s!\n", + __func__); + } if (megasas_set_dma_mask(instance)) goto fail_set_dma_mask; @@ -7630,16 +7750,15 @@ atomic_set(&instance->ldio_outstanding, 0); /* Now re-enable MSI-X */ - if (instance->msix_vectors) { - irq_flags = PCI_IRQ_MSIX; - if (instance->smp_affinity_enable) - irq_flags |= PCI_IRQ_AFFINITY; - } - rval = pci_alloc_irq_vectors(instance->pdev, 1, - instance->msix_vectors ? - instance->msix_vectors : 1, irq_flags); - if (rval < 0) - goto fail_reenable_msix; + if (instance->msix_vectors) + megasas_alloc_irq_vectors(instance); + + if (!instance->msix_vectors) { + rval = pci_alloc_irq_vectors(instance->pdev, 1, 1, + PCI_IRQ_LEGACY); + if (rval < 0) + goto fail_reenable_msix; + } megasas_setup_reply_map(instance); @@ -8030,8 +8149,9 @@ int error = 0, i; void *sense = NULL; dma_addr_t sense_handle; - unsigned long *sense_ptr; + void *sense_ptr; u32 opcode = 0; + int ret = DCMD_SUCCESS; memset(kbuff_arr, 0, sizeof(kbuff_arr)); @@ -8152,6 +8272,13 @@ } if (ioc->sense_len) { + /* make sure the pointer is part of the frame */ + if (ioc->sense_off > + (sizeof(union megasas_frame) - sizeof(__le64))) { + error = -EINVAL; + goto out; + } + sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len, &sense_handle, GFP_KERNEL); if (!sense) { @@ -8159,12 +8286,9 @@ goto out; } - sense_ptr = - (unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off); - if (instance->consistent_mask_64bit) - *sense_ptr = cpu_to_le64(sense_handle); - else - *sense_ptr = cpu_to_le32(sense_handle); + /* always store 64 bits regardless of addressing */ + sense_ptr = (void *)cmd->frame + ioc->sense_off; + put_unaligned_le64(sense_handle, sense_ptr); } /* @@ -8172,13 +8296,18 @@ * cmd to the SCSI mid-layer */ cmd->sync_cmd = 1; - if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) { + + ret = megasas_issue_blocked_cmd(instance, cmd, 0); + switch (ret) { + case DCMD_INIT: + case DCMD_BUSY: cmd->sync_cmd = 0; dev_err(&instance->pdev->dev, "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n", - __func__, __LINE__, cmd->frame->hdr.cmd, opcode, - cmd->cmd_status_drv); - return -EBUSY; + __func__, __LINE__, cmd->frame->hdr.cmd, opcode, + cmd->cmd_status_drv); + error = -EBUSY; + goto out; } cmd->sync_cmd = 0; @@ -8686,8 +8815,10 @@ union megasas_evt_class_locale class_locale; int event_type = 0; u32 seq_num; + u16 ld_target_id; int error; u8 dcmd_ret = DCMD_SUCCESS; + struct scsi_device *sdev1; if (!instance) { printk(KERN_ERR "invalid instance!\n"); @@ -8710,12 +8841,26 @@ break; case MR_EVT_LD_OFFLINE: - case MR_EVT_CFG_CLEARED: case MR_EVT_LD_DELETED: + ld_target_id = instance->evt_detail->args.ld.target_id; + sdev1 = scsi_device_lookup(instance->host, + MEGASAS_MAX_PD_CHANNELS + + (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL), + (ld_target_id - MEGASAS_MAX_DEV_PER_CHANNEL), + 0); + if (sdev1) { + mutex_unlock(&instance->reset_mutex); + megasas_remove_scsi_device(sdev1); + mutex_lock(&instance->reset_mutex); + } + + event_type = SCAN_VD_CHANNEL; + break; case MR_EVT_LD_CREATED: event_type = SCAN_VD_CHANNEL; break; + case MR_EVT_CFG_CLEARED: case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: case MR_EVT_FOREIGN_CFG_IMPORTED: case MR_EVT_LD_STATE_CHANGE: --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_sas_fp.c +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -350,17 +350,21 @@ num_lds = le16_to_cpu(drv_map->raidMap.ldCount); + memcpy(instance->ld_ids_prev, + instance->ld_ids_from_raidmap, + sizeof(instance->ld_ids_from_raidmap)); + memset(instance->ld_ids_from_raidmap, 0xff, MEGASAS_MAX_LD_IDS); /*Convert Raid capability values to CPU arch */ for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) { ld = MR_TargetIdToLdGet(i, drv_map); /* For non existing VDs, iterate to next VD*/ - if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1)) + if (ld >= MEGASAS_MAX_SUPPORTED_LD_IDS) continue; raid = MR_LdRaidGet(ld, drv_map); le32_to_cpus((u32 *)&raid->capability); - + instance->ld_ids_from_raidmap[i] = i; num_lds--; } @@ -386,9 +390,8 @@ le64_to_cpu(quad->logEnd) && (mega_mod64(row - le64_to_cpu(quad->logStart), le32_to_cpu(quad->diff))) == 0) { if (span_blk != NULL) { - u64 blk, debugBlk; + u64 blk; blk = mega_div64_32((row-le64_to_cpu(quad->logStart)), le32_to_cpu(quad->diff)); - debugBlk = blk; blk = (blk + le64_to_cpu(quad->offsetInSpan)) << raid->stripeShift; *span_blk = blk; @@ -699,9 +702,7 @@ __le16 *pDevHandle = &io_info->devHandle; u8 *pPdInterface = &io_info->pd_interface; u32 logArm, rowMod, armQ, arm; - struct fusion_context *fusion; - fusion = instance->ctrl_context; *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); /*Get row and span from io_info for Uneven Span IO.*/ @@ -801,9 +802,7 @@ u64 *pdBlock = &io_info->pdBlock; __le16 *pDevHandle = &io_info->devHandle; u8 *pPdInterface = &io_info->pd_interface; - struct fusion_context *fusion; - fusion = instance->ctrl_context; *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID); row = mega_div64_32(stripRow, raid->rowDataSize); --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -364,6 +364,35 @@ instance->max_fw_cmds = instance->max_fw_cmds-1; } } + +static inline void +megasas_get_msix_index(struct megasas_instance *instance, + struct scsi_cmnd *scmd, + struct megasas_cmd_fusion *cmd, + u8 data_arms) +{ + int sdev_busy; + + /* nr_hw_queue = 1 for MegaRAID */ + struct blk_mq_hw_ctx *hctx = + scmd->device->request_queue->queue_hw_ctx[0]; + + sdev_busy = atomic_read(&hctx->nr_active); + + if (instance->perf_mode == MR_BALANCED_PERF_MODE && + sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) + cmd->request_desc->SCSIIO.MSIxIndex = + mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / + MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); + else if (instance->msix_load_balance) + cmd->request_desc->SCSIIO.MSIxIndex = + (mega_mod64(atomic64_add_return(1, &instance->total_io_count), + instance->msix_vectors)); + else + cmd->request_desc->SCSIIO.MSIxIndex = + instance->reply_map[raw_smp_processor_id()]; +} + /** * megasas_free_cmds_fusion - Free all the cmds in the free cmd pool * @instance: Adapter soft state @@ -594,7 +623,8 @@ fusion->io_request_frames = dma_pool_alloc(fusion->io_request_frames_pool, - GFP_KERNEL, &fusion->io_request_frames_phys); + GFP_KERNEL | __GFP_NOWARN, + &fusion->io_request_frames_phys); if (!fusion->io_request_frames) { if (instance->max_fw_cmds >= (MEGASAS_REDUCE_QD_COUNT * 2)) { instance->max_fw_cmds -= MEGASAS_REDUCE_QD_COUNT; @@ -632,7 +662,7 @@ fusion->io_request_frames = dma_pool_alloc(fusion->io_request_frames_pool, - GFP_KERNEL, + GFP_KERNEL | __GFP_NOWARN, &fusion->io_request_frames_phys); if (!fusion->io_request_frames) { @@ -1312,7 +1342,9 @@ } if (ret == DCMD_TIMEOUT) - megaraid_sas_kill_hba(instance); + dev_warn(&instance->pdev->dev, + "%s DCMD timed out, continue without JBOD sequence map\n", + __func__); if (ret == DCMD_SUCCESS) instance->pd_seq_map_id++; @@ -1394,7 +1426,9 @@ ret = megasas_issue_polled(instance, cmd); if (ret == DCMD_TIMEOUT) - megaraid_sas_kill_hba(instance); + dev_warn(&instance->pdev->dev, + "%s DCMD timed out, RAID map is disabled\n", + __func__); megasas_return_cmd(instance, cmd); @@ -2825,19 +2859,7 @@ fp_possible = (io_info.fpOkForIo > 0) ? true : false; } - if ((instance->perf_mode == MR_BALANCED_PERF_MODE) && - atomic_read(&scp->device->device_busy) > - (io_info.data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) - cmd->request_desc->SCSIIO.MSIxIndex = - mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / - MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); - else if (instance->msix_load_balance) - cmd->request_desc->SCSIIO.MSIxIndex = - (mega_mod64(atomic64_add_return(1, &instance->total_io_count), - instance->msix_vectors)); - else - cmd->request_desc->SCSIIO.MSIxIndex = - instance->reply_map[raw_smp_processor_id()]; + megasas_get_msix_index(instance, scp, cmd, io_info.data_arms); if (instance->adapter_type >= VENTURA_SERIES) { /* FP for Optimal raid level 1. @@ -3158,18 +3180,7 @@ cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle; - if ((instance->perf_mode == MR_BALANCED_PERF_MODE) && - atomic_read(&scmd->device->device_busy) > MR_DEVICE_HIGH_IOPS_DEPTH) - cmd->request_desc->SCSIIO.MSIxIndex = - mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / - MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); - else if (instance->msix_load_balance) - cmd->request_desc->SCSIIO.MSIxIndex = - (mega_mod64(atomic64_add_return(1, &instance->total_io_count), - instance->msix_vectors)); - else - cmd->request_desc->SCSIIO.MSIxIndex = - instance->reply_map[raw_smp_processor_id()]; + megasas_get_msix_index(instance, scmd, cmd, 1); if (!fp_possible) { /* system pd firmware path */ @@ -3715,6 +3726,7 @@ if (irq_ctx->irq_poll_scheduled) { irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } } } @@ -3737,7 +3749,7 @@ instance = irq_ctx->instance; if (irq_ctx->irq_line_enable) { - disable_irq(irq_ctx->os_irq); + disable_irq_nosync(irq_ctx->os_irq); irq_ctx->irq_line_enable = false; } @@ -3746,6 +3758,7 @@ irq_poll_complete(irqpoll); irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } return num_entries; @@ -3762,6 +3775,7 @@ { struct megasas_instance *instance = (struct megasas_instance *)instance_addr; + struct megasas_irq_context *irq_ctx = NULL; u32 count, MSIxIndex; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; @@ -3770,8 +3784,10 @@ if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return; - for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) - complete_cmd_fusion(instance, MSIxIndex, NULL); + for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) { + irq_ctx = &instance->irq_context[MSIxIndex]; + complete_cmd_fusion(instance, MSIxIndex, irq_ctx); + } } /** @@ -3786,10 +3802,8 @@ if (instance->mask_interrupts) return IRQ_NONE; -#if defined(ENABLE_IRQ_POLL) if (irq_context->irq_poll_scheduled) return IRQ_HANDLED; -#endif if (!instance->msix_vectors) { mfiStatus = instance->instancet->clear_intr(instance); @@ -4219,13 +4233,15 @@ * megasas_refire_mgmt_cmd : Re-fire management commands * @instance: Controller's soft instance */ -static void megasas_refire_mgmt_cmd(struct megasas_instance *instance) +void megasas_refire_mgmt_cmd(struct megasas_instance *instance, + bool return_ioctl) { int j; struct megasas_cmd_fusion *cmd_fusion; struct fusion_context *fusion; struct megasas_cmd *cmd_mfi; union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req; u16 smid; bool refire_cmd = 0; u8 result; @@ -4283,6 +4299,21 @@ break; } + if (return_ioctl && cmd_mfi->sync_cmd && + cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) { + dev_err(&instance->pdev->dev, + "return -EBUSY from %s %d cmd 0x%x opcode 0x%x\n", + __func__, __LINE__, cmd_mfi->frame->hdr.cmd, + le32_to_cpu(cmd_mfi->frame->dcmd.opcode)); + cmd_mfi->cmd_status_drv = DCMD_BUSY; + result = COMPLETE_CMD; + } + + scsi_io_req = (struct MPI2_RAID_SCSI_IO_REQUEST *) + cmd_fusion->io_request; + if (scsi_io_req->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) + result = RETURN_CMD; + switch (result) { case REFIRE_CMD: megasas_fire_cmd_fusion(instance, req_desc); @@ -4298,6 +4329,37 @@ } /* + * megasas_return_polled_cmds: Return polled mode commands back to the pool + * before initiating an OCR. + * @instance: Controller's soft instance + */ +static void +megasas_return_polled_cmds(struct megasas_instance *instance) +{ + int i; + struct megasas_cmd_fusion *cmd_fusion; + struct fusion_context *fusion; + struct megasas_cmd *cmd_mfi; + + fusion = instance->ctrl_context; + + for (i = instance->max_scsi_cmds; i < instance->max_fw_cmds; i++) { + cmd_fusion = fusion->cmd_list[i]; + cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx]; + + if (cmd_mfi->flags & DRV_DCMD_POLLED_MODE) { + if (megasas_dbg_lvl & OCR_DEBUG) + dev_info(&instance->pdev->dev, + "%s %d return cmd 0x%x opcode 0x%x\n", + __func__, __LINE__, cmd_mfi->frame->hdr.cmd, + le32_to_cpu(cmd_mfi->frame->dcmd.opcode)); + cmd_mfi->flags &= ~DRV_DCMD_POLLED_MODE; + megasas_return_cmd(instance, cmd_mfi); + } + } +} + +/* * megasas_track_scsiio : Track SCSI IOs outstanding to a SCSI device * @instance: per adapter struct * @channel: the channel assigned by the OS @@ -4480,7 +4542,6 @@ if (!timeleft) { dev_err(&instance->pdev->dev, "task mgmt type 0x%x timed out\n", type); - cmd_mfi->flags |= DRV_DCMD_SKIP_REFIRE; mutex_unlock(&instance->reset_mutex); rc = megasas_reset_fusion(instance->host, MFI_IO_TIMEOUT_OCR); mutex_lock(&instance->reset_mutex); @@ -4650,7 +4711,7 @@ devhandle = megasas_get_tm_devhandle(scmd->device); if (devhandle == (u16)ULONG_MAX) { - ret = SUCCESS; + ret = FAILED; sdev_printk(KERN_INFO, scmd->device, "task abort issued for invalid devhandle\n"); mutex_unlock(&instance->reset_mutex); @@ -4720,7 +4781,7 @@ devhandle = megasas_get_tm_devhandle(scmd->device); if (devhandle == (u16)ULONG_MAX) { - ret = SUCCESS; + ret = FAILED; sdev_printk(KERN_INFO, scmd->device, "target reset issued for invalid devhandle\n"); mutex_unlock(&instance->reset_mutex); @@ -4847,6 +4908,7 @@ if (instance->requestorId && !instance->skip_heartbeat_timer_del) del_timer_sync(&instance->sriov_heartbeat_timer); set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); + set_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags); atomic_set(&instance->adprecovery, MEGASAS_ADPRESET_SM_POLLING); instance->instancet->disable_intr(instance); megasas_sync_irqs((unsigned long)instance); @@ -4951,7 +5013,9 @@ goto kill_hba; } - megasas_refire_mgmt_cmd(instance); + megasas_refire_mgmt_cmd(instance, + (i == (MEGASAS_FUSION_MAX_RESET_TRIES - 1) + ? 1 : 0)); /* Reset load balance info */ if (fusion->load_balance_info) @@ -4959,8 +5023,16 @@ (sizeof(struct LD_LOAD_BALANCE_INFO) * MAX_LOGICAL_DRIVES_EXT)); - if (!megasas_get_map_info(instance)) + if (!megasas_get_map_info(instance)) { megasas_sync_map_info(instance); + } else { + /* + * Return pending polled mode cmds before + * retrying OCR + */ + megasas_return_polled_cmds(instance); + continue; + } megasas_setup_jbod_map(instance); @@ -4987,6 +5059,15 @@ megasas_set_dynamic_target_properties(sdev, is_target_prop); } + status_reg = instance->instancet->read_fw_status_reg + (instance); + abs_state = status_reg & MFI_STATE_MASK; + if (abs_state != MFI_STATE_OPERATIONAL) { + dev_info(&instance->pdev->dev, + "Adapter is not OPERATIONAL, state 0x%x for scsi:%d\n", + abs_state, instance->host->host_no); + goto out; + } atomic_set(&instance->adprecovery, MEGASAS_HBA_OPERATIONAL); dev_info(&instance->pdev->dev, @@ -5046,7 +5127,7 @@ instance->skip_heartbeat_timer_del = 1; retval = FAILED; out: - clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); + clear_bit(MEGASAS_FUSION_OCR_NOT_POSSIBLE, &instance->reset_flags); mutex_unlock(&instance->reset_mutex); return retval; } --- linux-oracle-5.4.0.orig/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ linux-oracle-5.4.0/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -89,6 +89,7 @@ #define MEGASAS_FP_CMD_LEN 16 #define MEGASAS_FUSION_IN_RESET 0 +#define MEGASAS_FUSION_OCR_NOT_POSSIBLE 1 #define RAID_1_PEER_CMDS 2 #define JBOD_MAPS_COUNT 2 #define MEGASAS_REDUCE_QD_COUNT 64 @@ -864,9 +865,20 @@ u8 regTypeReqOnRead; __le16 seqNum; - struct { - u32 ldSyncRequired:1; - u32 reserved:31; +struct { +#ifndef MFI_BIG_ENDIAN + u32 ldSyncRequired:1; + u32 regTypeReqOnReadIsValid:1; + u32 isEPD:1; + u32 enableSLDOnAllRWIOs:1; + u32 reserved:28; +#else + u32 reserved:28; + u32 enableSLDOnAllRWIOs:1; + u32 isEPD:1; + u32 regTypeReqOnReadIsValid:1; + u32 ldSyncRequired:1; +#endif } flags; u8 LUN[8]; /* 0x24 8 byte LUN field used for SCSI IO's */ --- linux-oracle-5.4.0.orig/drivers/scsi/mesh.c +++ linux-oracle-5.4.0/drivers/scsi/mesh.c @@ -1045,6 +1045,8 @@ while ((in_8(&mr->bus_status1) & BS1_RST) != 0) udelay(1); printk("done\n"); + if (ms->dma_started) + halt_dma(ms); handle_reset(ms); /* request_q is empty, no point in mesh_start() */ return; @@ -1357,7 +1359,8 @@ ms->conn_tgt, ms->data_ptr, scsi_bufflen(cmd), ms->tgts[ms->conn_tgt].data_goes_out); } - scsi_dma_unmap(cmd); + if (cmd) + scsi_dma_unmap(cmd); ms->dma_started = 0; } @@ -1712,6 +1715,9 @@ spin_lock_irqsave(ms->host->host_lock, flags); + if (ms->dma_started) + halt_dma(ms); + /* Reset the controller & dbdma channel */ out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */ out_8(&mr->exception, 0xff); /* clear all exception bits */ --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpi/mpi2.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpi/mpi2.h @@ -122,6 +122,9 @@ * 08-28-18 02.00.53 Bumped MPI2_HEADER_VERSION_UNIT. * Added MPI2_IOCSTATUS_FAILURE * 12-17-18 02.00.54 Bumped MPI2_HEADER_VERSION_UNIT + * 06-24-19 02.00.55 Bumped MPI2_HEADER_VERSION_UNIT + * 08-01-19 02.00.56 Bumped MPI2_HEADER_VERSION_UNIT + * 10-02-19 02.00.57 Bumped MPI2_HEADER_VERSION_UNIT * -------------------------------------------------------------------------- */ @@ -162,7 +165,7 @@ /* Unit and Dev versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x36) +#define MPI2_HEADER_VERSION_UNIT (0x39) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -181,6 +184,7 @@ #define MPI2_IOC_STATE_READY (0x10000000) #define MPI2_IOC_STATE_OPERATIONAL (0x20000000) #define MPI2_IOC_STATE_FAULT (0x40000000) +#define MPI2_IOC_STATE_COREDUMP (0x50000000) #define MPI2_IOC_STATE_MASK (0xF0000000) #define MPI2_IOC_STATE_SHIFT (28) --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h @@ -249,6 +249,8 @@ * 08-28-18 02.00.46 Added NVMs Write Cache flag to IOUnitPage1 * Added DMDReport Delay Time defines to PCIeIOUnitPage1 * 12-17-18 02.00.47 Swap locations of Slotx2 and Slotx4 in ManPage 7. + * 08-01-19 02.00.49 Add MPI26_MANPAGE7_FLAG_X2_X4_SLOT_INFO_VALID + * Add MPI26_IOUNITPAGE1_NVME_WRCACHE_SHIFT */ #ifndef MPI2_CNFG_H @@ -891,6 +893,8 @@ #define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) #define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) +#define MPI26_MANPAGE7_FLAG_CONN_LANE_USE_PINOUT (0x00000020) +#define MPI26_MANPAGE7_FLAG_X2_X4_SLOT_INFO_VALID (0x00000010) /* *Generic structure to use for product-specific manufacturing pages @@ -962,9 +966,10 @@ /* IO Unit Page 1 Flags defines */ #define MPI26_IOUNITPAGE1_NVME_WRCACHE_MASK (0x00030000) -#define MPI26_IOUNITPAGE1_NVME_WRCACHE_ENABLE (0x00000000) -#define MPI26_IOUNITPAGE1_NVME_WRCACHE_DISABLE (0x00010000) -#define MPI26_IOUNITPAGE1_NVME_WRCACHE_NO_CHANGE (0x00020000) +#define MPI26_IOUNITPAGE1_NVME_WRCACHE_SHIFT (16) +#define MPI26_IOUNITPAGE1_NVME_WRCACHE_NO_CHANGE (0x00000000) +#define MPI26_IOUNITPAGE1_NVME_WRCACHE_ENABLE (0x00010000) +#define MPI26_IOUNITPAGE1_NVME_WRCACHE_DISABLE (0x00020000) #define MPI2_IOUNITPAGE1_ATA_SECURITY_FREEZE_LOCK (0x00004000) #define MPI25_IOUNITPAGE1_NEW_DEVICE_FAST_PATH_DISABLE (0x00002000) #define MPI25_IOUNITPAGE1_DISABLE_FAST_PATH (0x00001000) @@ -3931,7 +3936,13 @@ U32 MaximumDataTransferSize; /*0x0C */ U32 Capabilities; /*0x10 */ U16 NOIOB; /* 0x14 */ - U16 Reserved2; /* 0x16 */ + U16 ShutdownLatency; /* 0x16 */ + U16 VendorID; /* 0x18 */ + U16 DeviceID; /* 0x1A */ + U16 SubsystemVendorID; /* 0x1C */ + U16 SubsystemID; /* 0x1E */ + U8 RevisionID; /* 0x20 */ + U8 Reserved21[3]; /* 0x21 */ } MPI26_CONFIG_PAGE_PCIEDEV_2, *PTR_MPI26_CONFIG_PAGE_PCIEDEV_2, Mpi26PCIeDevicePage2_t, *pMpi26PCIeDevicePage2_t; --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpi/mpi2_image.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpi/mpi2_image.h @@ -19,6 +19,10 @@ * 09-07-18 02.06.03 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES * 12-17-18 02.06.04 Addd MPI2_EXT_IMAGE_TYPE_PBLP * Shorten some defines to be compatible with DOS + * 06-24-19 02.06.05 Whitespace adjustments to help with identifier + * checking tool. + * 10-02-19 02.06.06 Added MPI26_IMAGE_HEADER_SIG1_COREDUMP + * Added MPI2_FLASH_REGION_COREDUMP */ #ifndef MPI2_IMAGE_H #define MPI2_IMAGE_H @@ -213,6 +217,8 @@ #define MPI26_IMAGE_HEADER_SIG1_NVDATA (0x5444564E) #define MPI26_IMAGE_HEADER_SIG1_GAS_GAUGE (0x20534147) #define MPI26_IMAGE_HEADER_SIG1_PBLP (0x504C4250) +/* little-endian "DUMP" */ +#define MPI26_IMAGE_HEADER_SIG1_COREDUMP (0x504D5544) /**** Definitions for Signature2 field ****/ #define MPI26_IMAGE_HEADER_SIGNATURE2_VALUE (0x50584546) @@ -359,6 +365,7 @@ #define MPI2_FLASH_REGION_MR_NVDATA (0x14) #define MPI2_FLASH_REGION_CPLD (0x15) #define MPI2_FLASH_REGION_PSOC (0x16) +#define MPI2_FLASH_REGION_COREDUMP (0x17) /*ImageRevision */ #define MPI2_FLASH_LAYOUT_IMAGE_REVISION (0x00) --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h @@ -175,6 +175,10 @@ * Moved FW image definitions ionto new mpi2_image,h * 08-14-18 02.00.36 Fixed definition of MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16) * 09-07-18 02.00.37 Added MPI26_EVENT_PCIE_TOPO_PI_16_LANES + * 10-02-19 02.00.38 Added MPI26_IOCINIT_CFGFLAGS_COREDUMP_ENABLE + * Added MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED + * Added MPI2_FW_DOWNLOAD_ITYPE_COREDUMP + * Added MPI2_FW_UPLOAD_ITYPE_COREDUMP * -------------------------------------------------------------------------- */ @@ -248,6 +252,7 @@ /*ConfigurationFlags */ #define MPI26_IOCINIT_CFGFLAGS_NVME_SGL_FORMAT (0x0001) +#define MPI26_IOCINIT_CFGFLAGS_COREDUMP_ENABLE (0x0002) /*minimum depth for a Reply Descriptor Post Queue */ #define MPI2_RDPQ_DEPTH_MIN (16) @@ -377,6 +382,7 @@ /*ProductID field uses MPI2_FW_HEADER_PID_ */ /*IOCCapabilities */ +#define MPI26_IOCFACTS_CAPABILITY_COREDUMP_ENABLED (0x00200000) #define MPI26_IOCFACTS_CAPABILITY_PCIE_SRIOV (0x00100000) #define MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ (0x00080000) #define MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE (0x00040000) @@ -1458,8 +1464,8 @@ /*MPI v2.6 and newer */ #define MPI2_FW_DOWNLOAD_ITYPE_CPLD (0x15) #define MPI2_FW_DOWNLOAD_ITYPE_PSOC (0x16) +#define MPI2_FW_DOWNLOAD_ITYPE_COREDUMP (0x17) #define MPI2_FW_DOWNLOAD_ITYPE_MIN_PRODUCT_SPECIFIC (0xF0) -#define MPI2_FW_DOWNLOAD_ITYPE_TERMINATE (0xFF) /*MPI v2.0 FWDownload TransactionContext Element */ typedef struct _MPI2_FW_DOWNLOAD_TCSGE { --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_base.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -124,7 +124,14 @@ }; static int +_base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, + u32 ioc_state, int timeout); +static int _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc); +static void +_base_mask_interrupts(struct MPT3SAS_ADAPTER *ioc); +static void +_base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc); /** * mpt3sas_base_check_cmd_timeout - Function @@ -609,7 +616,8 @@ spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); - if (ioc->shost_recovery || ioc->pci_error_recovery) + if ((ioc->shost_recovery && (ioc->ioc_coredump_loop == 0)) || + ioc->pci_error_recovery) goto rearm_timer; spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); @@ -656,20 +664,64 @@ return; /* don't rearm timer */ } - ioc->non_operational_loop = 0; + if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) { + u8 timeout = (ioc->manu_pg11.CoreDumpTOSec) ? + ioc->manu_pg11.CoreDumpTOSec : + MPT3SAS_DEFAULT_COREDUMP_TIMEOUT_SECONDS; + + timeout /= (FAULT_POLLING_INTERVAL/1000); + + if (ioc->ioc_coredump_loop == 0) { + mpt3sas_print_coredump_info(ioc, + doorbell & MPI2_DOORBELL_DATA_MASK); + /* do not accept any IOs and disable the interrupts */ + spin_lock_irqsave( + &ioc->ioc_reset_in_progress_lock, flags); + ioc->shost_recovery = 1; + spin_unlock_irqrestore( + &ioc->ioc_reset_in_progress_lock, flags); + _base_mask_interrupts(ioc); + _base_clear_outstanding_commands(ioc); + } + + ioc_info(ioc, "%s: CoreDump loop %d.", + __func__, ioc->ioc_coredump_loop); + + /* Wait until CoreDump completes or times out */ + if (ioc->ioc_coredump_loop++ < timeout) { + spin_lock_irqsave( + &ioc->ioc_reset_in_progress_lock, flags); + goto rearm_timer; + } + } + if (ioc->ioc_coredump_loop) { + if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_COREDUMP) + ioc_err(ioc, "%s: CoreDump completed. LoopCount: %d", + __func__, ioc->ioc_coredump_loop); + else + ioc_err(ioc, "%s: CoreDump Timed out. LoopCount: %d", + __func__, ioc->ioc_coredump_loop); + ioc->ioc_coredump_loop = MPT3SAS_COREDUMP_LOOP_DONE; + } + ioc->non_operational_loop = 0; if ((doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) { rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); ioc_warn(ioc, "%s: hard reset: %s\n", __func__, rc == 0 ? "success" : "failed"); doorbell = mpt3sas_base_get_iocstate(ioc, 0); - if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) - mpt3sas_base_fault_info(ioc, doorbell & + if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { + mpt3sas_print_fault_code(ioc, doorbell & + MPI2_DOORBELL_DATA_MASK); + } else if ((doorbell & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) + mpt3sas_print_coredump_info(ioc, doorbell & MPI2_DOORBELL_DATA_MASK); if (rc && (doorbell & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL) return; /* don't rearm timer */ } + ioc->ioc_coredump_loop = 0; spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); rearm_timer: @@ -749,6 +801,49 @@ } /** + * mpt3sas_base_coredump_info - verbose translation of firmware CoreDump state + * @ioc: per adapter object + * @fault_code: fault code + * + * Return nothing. + */ +void +mpt3sas_base_coredump_info(struct MPT3SAS_ADAPTER *ioc, u16 fault_code) +{ + ioc_err(ioc, "coredump_state(0x%04x)!\n", fault_code); +} + +/** + * mpt3sas_base_wait_for_coredump_completion - Wait until coredump + * completes or times out + * @ioc: per adapter object + * + * Returns 0 for success, non-zero for failure. + */ +int +mpt3sas_base_wait_for_coredump_completion(struct MPT3SAS_ADAPTER *ioc, + const char *caller) +{ + u8 timeout = (ioc->manu_pg11.CoreDumpTOSec) ? + ioc->manu_pg11.CoreDumpTOSec : + MPT3SAS_DEFAULT_COREDUMP_TIMEOUT_SECONDS; + + int ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_FAULT, + timeout); + + if (ioc_state) + ioc_err(ioc, + "%s: CoreDump timed out. (ioc_state=0x%x)\n", + caller, ioc_state); + else + ioc_info(ioc, + "%s: CoreDump completed. (ioc_state=0x%x)\n", + caller, ioc_state); + + return ioc_state; +} + +/** * mpt3sas_halt_firmware - halt's mpt controller firmware * @ioc: per adapter object * @@ -768,9 +863,14 @@ dump_stack(); doorbell = ioc->base_readl(&ioc->chip->Doorbell); - if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) - mpt3sas_base_fault_info(ioc , doorbell); - else { + if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { + mpt3sas_print_fault_code(ioc, doorbell & + MPI2_DOORBELL_DATA_MASK); + } else if ((doorbell & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + mpt3sas_print_coredump_info(ioc, doorbell & + MPI2_DOORBELL_DATA_MASK); + } else { writel(0xC0FFEE00, &ioc->chip->Doorbell); ioc_err(ioc, "Firmware is halted due to command timeout\n"); } @@ -1632,7 +1732,7 @@ reply_q = container_of(irqpoll, struct adapter_reply_queue, irqpoll); if (reply_q->irq_line_enable) { - disable_irq(reply_q->os_irq); + disable_irq_nosync(reply_q->os_irq); reply_q->irq_line_enable = false; } num_entries = _base_process_reply_queue(reply_q); @@ -1641,6 +1741,13 @@ reply_q->irq_poll_scheduled = false; reply_q->irq_line_enable = true; enable_irq(reply_q->os_irq); + /* + * Go for one more round of processing the + * reply descriptor post queue incase if HBA + * Firmware has posted some reply descriptors + * while reenabling the IRQ. + */ + _base_process_reply_queue(reply_q); } return num_entries; @@ -1708,18 +1815,22 @@ /* TMs are on msix_index == 0 */ if (reply_q->msix_index == 0) continue; + synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); if (reply_q->irq_poll_scheduled) { /* Calling irq_poll_disable will wait for any pending * callbacks to have completed. */ irq_poll_disable(&reply_q->irqpoll); irq_poll_enable(&reply_q->irqpoll); - reply_q->irq_poll_scheduled = false; - reply_q->irq_line_enable = true; - enable_irq(reply_q->os_irq); - continue; + /* check how the scheduled poll has ended, + * clean up only if necessary + */ + if (reply_q->irq_poll_scheduled) { + reply_q->irq_poll_scheduled = false; + reply_q->irq_line_enable = true; + enable_irq(reply_q->os_irq); + } } - synchronize_irq(pci_irq_vector(ioc->pdev, reply_q->msix_index)); } } @@ -2299,12 +2410,8 @@ /* Get the SG list pointer and info. */ sges_left = scsi_dma_map(scmd); - if (sges_left < 0) { - sdev_printk(KERN_ERR, scmd->device, - "scsi_dma_map failed: request for %d bytes!\n", - scsi_bufflen(scmd)); + if (sges_left < 0) return 1; - } /* Check if we need to build a native SG list. */ if (base_is_prp_possible(ioc, pcie_device, @@ -2364,6 +2471,22 @@ _base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1); } +static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd) +{ + /* + * Some firmware versions byte-swap the REPORT ZONES command reply from + * ATA-ZAC devices by directly accessing in the host buffer. This does + * not respect the default command DMA direction and causes IOMMU page + * faults on some architectures with an IOMMU enforcing write mappings + * (e.g. AMD hosts). Avoid such issue by making the report zones buffer + * mapping bi-directional. + */ + if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES) + cmd->sc_data_direction = DMA_BIDIRECTIONAL; + + return scsi_dma_map(cmd); +} + /** * _base_build_sg_scmd - main sg creation routine * pcie_device is unused here! @@ -2410,13 +2533,9 @@ sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; sg_scmd = scsi_sglist(scmd); - sges_left = scsi_dma_map(scmd); - if (sges_left < 0) { - sdev_printk(KERN_ERR, scmd->device, - "scsi_dma_map failed: request for %d bytes!\n", - scsi_bufflen(scmd)); + sges_left = _base_scsi_dma_map(scmd); + if (sges_left < 0) return -ENOMEM; - } sg_local = &mpi_request->SGL; sges_in_segment = ioc->max_sges_in_main_message; @@ -2558,13 +2677,9 @@ } sg_scmd = scsi_sglist(scmd); - sges_left = scsi_dma_map(scmd); - if (sges_left < 0) { - sdev_printk(KERN_ERR, scmd->device, - "scsi_dma_map failed: request for %d bytes!\n", - scsi_bufflen(scmd)); + sges_left = _base_scsi_dma_map(scmd); + if (sges_left < 0) return -ENOMEM; - } sg_local = &mpi_request->SGL; sges_in_segment = (ioc->request_sz - @@ -3044,11 +3159,11 @@ descp = NULL; ioc_info(ioc, " %d %d\n", ioc->high_iops_queues, - ioc->msix_vector_count); + ioc->reply_queue_count); i = pci_alloc_irq_vectors_affinity(ioc->pdev, ioc->high_iops_queues, - ioc->msix_vector_count, irq_flags, descp); + ioc->reply_queue_count, irq_flags, descp); return i; } @@ -3103,6 +3218,8 @@ */ if (!ioc->combined_reply_queue && ioc->hba_mpi_version_belonged != MPI2_VERSION) { + ioc_info(ioc, + "combined ReplyQueue is off, Enabling msix load balance\n"); ioc->msix_load_balance = true; } @@ -3115,9 +3232,7 @@ r = _base_alloc_irq_vectors(ioc); if (r < 0) { - dfailprintk(ioc, - ioc_info(ioc, "pci_alloc_irq_vectors failed (r=%d) !!!\n", - r)); + ioc_info(ioc, "pci_alloc_irq_vectors failed (r=%d) !!!\n", r); goto try_ioapic; } @@ -3206,9 +3321,15 @@ dhsprintk(ioc, pr_info("%s: ioc_state(0x%08x)\n", __func__, ioc_state)); if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_base_fault_info(ioc, ioc_state & + mpt3sas_print_fault_code(ioc, ioc_state & MPI2_DOORBELL_DATA_MASK); rc = _base_diag_reset(ioc); + } else if ((ioc_state & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + mpt3sas_print_coredump_info(ioc, ioc_state & + MPI2_DOORBELL_DATA_MASK); + mpt3sas_base_wait_for_coredump_completion(ioc, __func__); + rc = _base_diag_reset(ioc); } return rc; @@ -3279,7 +3400,8 @@ } if (ioc->chip == NULL) { - ioc_err(ioc, "unable to map adapter memory! or resource not found\n"); + ioc_err(ioc, + "unable to map adapter memory! or resource not found\n"); r = -EINVAL; goto out_fail; } @@ -3318,8 +3440,8 @@ ioc->combined_reply_index_count, sizeof(resource_size_t *), GFP_KERNEL); if (!ioc->replyPostRegisterIndex) { - dfailprintk(ioc, - ioc_warn(ioc, "allocation for reply Post Register Index failed!!!\n")); + ioc_err(ioc, + "allocation for replyPostRegisterIndex failed!\n"); r = -ENOMEM; goto out_fail; } @@ -3467,6 +3589,22 @@ } /** + * _base_sdev_nr_inflight_request -get number of inflight requests + * of a request queue. + * @q: request_queue object + * + * returns number of inflight request of a request queue. + */ +inline unsigned long +_base_sdev_nr_inflight_request(struct request_queue *q) +{ + struct blk_mq_hw_ctx *hctx = q->queue_hw_ctx[0]; + + return atomic_read(&hctx->nr_active); +} + + +/** * _base_get_high_iops_msix_index - get the msix index of * high iops queues * @ioc: per adapter object @@ -3485,7 +3623,7 @@ * reply queues in terms of batch count 16 when outstanding * IOs on the target device is >=8. */ - if (atomic_read(&scmd->device->device_busy) > + if (_base_sdev_nr_inflight_request(scmd->device->request_queue) > MPT3SAS_DEVICE_HIGH_IOPS_DEPTH) return base_mod64(( atomic64_add_return(1, &ioc->high_iops_outstanding) / @@ -4242,10 +4380,12 @@ static int _base_display_fwpkg_version(struct MPT3SAS_ADAPTER *ioc) { - Mpi2FWImageHeader_t *FWImgHdr; + Mpi2FWImageHeader_t *fw_img_hdr; + Mpi26ComponentImageHeader_t *cmp_img_hdr; Mpi25FWUploadRequest_t *mpi_request; Mpi2FWUploadReply_t mpi_reply; int r = 0; + u32 package_version = 0; void *fwpkg_data = NULL; dma_addr_t fwpkg_data_dma; u16 smid, ioc_status; @@ -4262,7 +4402,8 @@ fwpkg_data = dma_alloc_coherent(&ioc->pdev->dev, data_length, &fwpkg_data_dma, GFP_KERNEL); if (!fwpkg_data) { - ioc_err(ioc, "failure at %s:%d/%s()!\n", + ioc_err(ioc, + "Memory allocation for fwpkg data failed at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); return -ENOMEM; } @@ -4302,14 +4443,26 @@ ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { - FWImgHdr = (Mpi2FWImageHeader_t *)fwpkg_data; - if (FWImgHdr->PackageVersion.Word) { - ioc_info(ioc, "FW Package Version (%02d.%02d.%02d.%02d)\n", - FWImgHdr->PackageVersion.Struct.Major, - FWImgHdr->PackageVersion.Struct.Minor, - FWImgHdr->PackageVersion.Struct.Unit, - FWImgHdr->PackageVersion.Struct.Dev); - } + fw_img_hdr = (Mpi2FWImageHeader_t *)fwpkg_data; + if (le32_to_cpu(fw_img_hdr->Signature) == + MPI26_IMAGE_HEADER_SIGNATURE0_MPI26) { + cmp_img_hdr = + (Mpi26ComponentImageHeader_t *) + (fwpkg_data); + package_version = + le32_to_cpu( + cmp_img_hdr->ApplicationSpecific); + } else + package_version = + le32_to_cpu( + fw_img_hdr->PackageVersion.Word); + if (package_version) + ioc_info(ioc, + "FW Package Ver(%02d.%02d.%02d.%02d)\n", + ((package_version) & 0xFF000000) >> 24, + ((package_version) & 0x00FF0000) >> 16, + ((package_version) & 0x0000FF00) >> 8, + (package_version) & 0x000000FF); } else { _debug_dump_mf(&mpi_reply, sizeof(Mpi2FWUploadReply_t)/4); @@ -4612,8 +4765,7 @@ if (!ioc->is_gen35_ioc && ioc->manu_pg11.EEDPTagMode == 0) { pr_err("%s: overriding NVDATA EEDPTagMode setting\n", ioc->name); - ioc->manu_pg11.EEDPTagMode &= ~0x3; - ioc->manu_pg11.EEDPTagMode |= 0x1; + ioc->manu_pg11.EEDPTagMode = 0x1; mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply, &ioc->manu_pg11); } @@ -4777,7 +4929,9 @@ } kfree(ioc->hpr_lookup); + ioc->hpr_lookup = NULL; kfree(ioc->internal_lookup); + ioc->internal_lookup = NULL; if (ioc->chain_lookup) { for (i = 0; i < ioc->scsiio_depth; i++) { for (j = ioc->chains_per_prp_buffer; @@ -4980,12 +5134,13 @@ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; } - dinitprintk(ioc, - ioc_info(ioc, "scatter gather: sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), chains_per_io(%d)\n", - ioc->max_sges_in_main_message, - ioc->max_sges_in_chain_message, - ioc->shost->sg_tablesize, - ioc->chains_needed_per_io)); + ioc_info(ioc, + "scatter gather: sge_in_main_msg(%d), sge_per_chain(%d), " + "sge_per_io(%d), chains_per_io(%d)\n", + ioc->max_sges_in_main_message, + ioc->max_sges_in_chain_message, + ioc->shost->sg_tablesize, + ioc->chains_needed_per_io); /* reply post queue, 16 byte align */ reply_post_free_sz = ioc->reply_post_queue_depth * @@ -5095,15 +5250,13 @@ ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * ioc->request_sz); - dinitprintk(ioc, - ioc_info(ioc, "request pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", - ioc->request, ioc->hba_queue_depth, - ioc->request_sz, - (ioc->hba_queue_depth * ioc->request_sz) / 1024)); + ioc_info(ioc, + "request pool(0x%p) - dma(0x%llx): " + "depth(%d), frame_size(%d), pool_size(%d kB)\n", + ioc->request, (unsigned long long) ioc->request_dma, + ioc->hba_queue_depth, ioc->request_sz, + (ioc->hba_queue_depth * ioc->request_sz) / 1024); - dinitprintk(ioc, - ioc_info(ioc, "request pool: dma(0x%llx)\n", - (unsigned long long)ioc->request_dma)); total_sz += sz; dinitprintk(ioc, @@ -5234,7 +5387,6 @@ &ct->chain_buffer_dma); if (!ct->chain_buffer) { ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n"); - _base_release_memory_pools(ioc); goto out; } } @@ -5289,13 +5441,12 @@ goto out; } } - dinitprintk(ioc, - ioc_info(ioc, "sense pool(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n", - ioc->sense, ioc->scsiio_depth, - SCSI_SENSE_BUFFERSIZE, sz / 1024)); - dinitprintk(ioc, - ioc_info(ioc, "sense_dma(0x%llx)\n", - (unsigned long long)ioc->sense_dma)); + ioc_info(ioc, + "sense pool(0x%p)- dma(0x%llx): depth(%d)," + "element_size(%d), pool_size(%d kB)\n", + ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth, + SCSI_SENSE_BUFFERSIZE, sz / 1024); + total_sz += sz; /* reply pool, 4 byte align */ @@ -5373,12 +5524,10 @@ ioc_err(ioc, "config page: dma_pool_alloc failed\n"); goto out; } - dinitprintk(ioc, - ioc_info(ioc, "config page(0x%p): size(%d)\n", - ioc->config_page, ioc->config_page_sz)); - dinitprintk(ioc, - ioc_info(ioc, "config_page_dma(0x%llx)\n", - (unsigned long long)ioc->config_page_dma)); + + ioc_info(ioc, "config page(0x%p) - dma(0x%llx): size(%d)\n", + ioc->config_page, (unsigned long long)ioc->config_page_dma, + ioc->config_page_sz); total_sz += ioc->config_page_sz; ioc_info(ioc, "Allocated physical memory: size(%d kB)\n", @@ -5433,6 +5582,8 @@ return 0; if (count && current_state == MPI2_IOC_STATE_FAULT) break; + if (count && current_state == MPI2_IOC_STATE_COREDUMP) + break; usleep_range(1000, 1500); count++; @@ -5534,7 +5685,12 @@ doorbell = ioc->base_readl(&ioc->chip->Doorbell); if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_base_fault_info(ioc , doorbell); + mpt3sas_print_fault_code(ioc, doorbell); + return -EFAULT; + } + if ((doorbell & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + mpt3sas_print_coredump_info(ioc, doorbell); return -EFAULT; } } else if (int_status == 0xFFFFFFFF) @@ -5596,6 +5752,7 @@ { u32 ioc_state; int r = 0; + unsigned long flags; if (reset_type != MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET) { ioc_err(ioc, "%s: unknown reset_type\n", __func__); @@ -5614,6 +5771,7 @@ r = -EFAULT; goto out; } + ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, timeout); if (ioc_state) { ioc_err(ioc, "%s: failed going to ready state (ioc_state=0x%x)\n", @@ -5622,6 +5780,26 @@ goto out; } out: + if (r != 0) { + ioc_state = mpt3sas_base_get_iocstate(ioc, 0); + spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); + /* + * Wait for IOC state CoreDump to clear only during + * HBA initialization & release time. + */ + if ((ioc_state & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP && (ioc->is_driver_loading == 1 || + ioc->fault_reset_work_q == NULL)) { + spin_unlock_irqrestore( + &ioc->ioc_reset_in_progress_lock, flags); + mpt3sas_print_coredump_info(ioc, ioc_state); + mpt3sas_base_wait_for_coredump_completion(ioc, + __func__); + spin_lock_irqsave( + &ioc->ioc_reset_in_progress_lock, flags); + } + spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); + } ioc_info(ioc, "message unit reset: %s\n", r == 0 ? "SUCCESS" : "FAILED"); return r; @@ -5679,11 +5857,12 @@ int i; u8 failed; __le32 *mfp; + int ret_val; /* make sure doorbell is not in use */ if ((ioc->base_readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__); - return -EFAULT; + goto doorbell_diag_reset; } /* clear pending doorbell interrupts from previous state changes */ @@ -5769,10 +5948,14 @@ mfp = (__le32 *)reply; pr_info("\toffset:data\n"); for (i = 0; i < reply_bytes/4; i++) - pr_info("\t[0x%02x]:%08x\n", i*4, + ioc_info(ioc, "\t[0x%02x]:%08x\n", i*4, le32_to_cpu(mfp[i])); } return 0; + +doorbell_diag_reset: + ret_val = _base_diag_reset(ioc); + return ret_val; } /** @@ -5837,10 +6020,9 @@ ioc->ioc_link_reset_in_progress) ioc->ioc_link_reset_in_progress = 0; if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->base_cmds.status, mpi_request, - sizeof(Mpi2SasIoUnitControlRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, ioc->base_cmds.status, + mpi_request, sizeof(Mpi2SasIoUnitControlRequest_t)/4, + issue_reset); goto issue_host_reset; } if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) @@ -5913,10 +6095,9 @@ wait_for_completion_timeout(&ioc->base_cmds.done, msecs_to_jiffies(10000)); if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->base_cmds.status, mpi_request, - sizeof(Mpi2SepRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, + ioc->base_cmds.status, mpi_request, + sizeof(Mpi2SepRequest_t)/4, issue_reset); goto issue_host_reset; } if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) @@ -6015,9 +6196,15 @@ } if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_base_fault_info(ioc, ioc_state & + mpt3sas_print_fault_code(ioc, ioc_state & MPI2_DOORBELL_DATA_MASK); goto issue_diag_reset; + } else if ((ioc_state & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + ioc_info(ioc, + "%s: Skipping the diag reset here. (ioc_state=0x%x)\n", + __func__, ioc_state); + return -EFAULT; } ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, timeout); @@ -6028,7 +6215,9 @@ return -EFAULT; } - issue_diag_reset: + return 0; + +issue_diag_reset: rc = _base_diag_reset(ioc); return rc; } @@ -6196,6 +6385,12 @@ cpu_to_le64((u64)ioc->reply_post[0].reply_post_free_dma); } + /* + * Set the flag to enable CoreDump state feature in IOC firmware. + */ + mpi_request.ConfigurationFlags |= + cpu_to_le16(MPI26_IOCINIT_CFGFLAGS_COREDUMP_ENABLE); + /* This time stamp specifies number of milliseconds * since epoch ~ midnight January 1, 1970. */ @@ -6207,15 +6402,15 @@ int i; mfp = (__le32 *)&mpi_request; - pr_info("\toffset:data\n"); + ioc_info(ioc, "\toffset:data\n"); for (i = 0; i < sizeof(Mpi2IOCInitRequest_t)/4; i++) - pr_info("\t[0x%02x]:%08x\n", i*4, + ioc_info(ioc, "\t[0x%02x]:%08x\n", i*4, le32_to_cpu(mfp[i])); } r = _base_handshake_req_reply_wait(ioc, sizeof(Mpi2IOCInitRequest_t), (u32 *)&mpi_request, - sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 10); + sizeof(Mpi2IOCInitReply_t), (u16 *)&mpi_reply, 30); if (r != 0) { ioc_err(ioc, "%s: handshake failed (r=%d)\n", __func__, r); @@ -6560,6 +6755,8 @@ ioc_info(ioc, "sending diag reset !!\n"); + pci_cfg_access_lock(ioc->pdev); + drsprintk(ioc, ioc_info(ioc, "clear interrupts\n")); count = 0; @@ -6579,8 +6776,11 @@ /* wait 100 msec */ msleep(100); - if (count++ > 20) + if (count++ > 20) { + ioc_info(ioc, + "Stop writing magic sequence after 20 retries\n"); goto out; + } host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); drsprintk(ioc, @@ -6604,8 +6804,11 @@ host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); - if (host_diagnostic == 0xFFFFFFFF) + if (host_diagnostic == 0xFFFFFFFF) { + ioc_info(ioc, + "Invalid host diagnostic register value\n"); goto out; + } if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) break; @@ -6641,10 +6844,12 @@ goto out; } + pci_cfg_access_unlock(ioc->pdev); ioc_info(ioc, "diag reset: SUCCESS\n"); return 0; out: + pci_cfg_access_unlock(ioc->pdev); ioc_err(ioc, "diag reset: FAILED\n"); return -EFAULT; } @@ -6692,16 +6897,33 @@ return 0; if (ioc_state & MPI2_DOORBELL_USED) { - dhsprintk(ioc, ioc_info(ioc, "unexpected doorbell active!\n")); + ioc_info(ioc, "unexpected doorbell active!\n"); goto issue_diag_reset; } if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_base_fault_info(ioc, ioc_state & + mpt3sas_print_fault_code(ioc, ioc_state & MPI2_DOORBELL_DATA_MASK); goto issue_diag_reset; } + if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_COREDUMP) { + /* + * if host reset is invoked while watch dog thread is waiting + * for IOC state to be changed to Fault state then driver has + * to wait here for CoreDump state to clear otherwise reset + * will be issued to the FW and FW move the IOC state to + * reset state without copying the FW logs to coredump region. + */ + if (ioc->ioc_coredump_loop != MPT3SAS_COREDUMP_LOOP_DONE) { + mpt3sas_print_coredump_info(ioc, ioc_state & + MPI2_DOORBELL_DATA_MASK); + mpt3sas_base_wait_for_coredump_completion(ioc, + __func__); + } + goto issue_diag_reset; + } + if (type == FORCE_BIG_HAMMER) goto issue_diag_reset; @@ -6945,8 +7167,7 @@ ioc->cpu_msix_table = kzalloc(ioc->cpu_msix_table_sz, GFP_KERNEL); ioc->reply_queue_count = 1; if (!ioc->cpu_msix_table) { - dfailprintk(ioc, - ioc_info(ioc, "allocation for cpu_msix_table failed!!!\n")); + ioc_info(ioc, "Allocation for cpu_msix_table failed!!!\n"); r = -ENOMEM; goto out_free_resources; } @@ -6955,8 +7176,7 @@ ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz, sizeof(resource_size_t *), GFP_KERNEL); if (!ioc->reply_post_host_index) { - dfailprintk(ioc, - ioc_info(ioc, "allocation for reply_post_host_index failed!!!\n")); + ioc_info(ioc, "Allocation for reply_post_host_index failed!!!\n"); r = -ENOMEM; goto out_free_resources; } @@ -7071,6 +7291,12 @@ ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); if (ioc->facts.MaxDevHandle % 8) ioc->pd_handles_sz++; + /* + * pd_handles_sz should have, at least, the minimal room for + * set_bit()/test_bit(), otherwise out-of-memory touch may occur. + */ + ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long)); + ioc->pd_handles = kzalloc(ioc->pd_handles_sz, GFP_KERNEL); if (!ioc->pd_handles) { @@ -7088,16 +7314,27 @@ ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8); if (ioc->facts.MaxDevHandle % 8) ioc->pend_os_device_add_sz++; + + /* + * pend_os_device_add_sz should have, at least, the minimal room for + * set_bit()/test_bit(), otherwise out-of-memory may occur. + */ + ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz, + sizeof(unsigned long)); ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, GFP_KERNEL); - if (!ioc->pend_os_device_add) + if (!ioc->pend_os_device_add) { + r = -ENOMEM; goto out_free_resources; + } ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz; ioc->device_remove_in_progress = kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL); - if (!ioc->device_remove_in_progress) + if (!ioc->device_remove_in_progress) { + r = -ENOMEM; goto out_free_resources; + } ioc->fwfault_debug = mpt3sas_fwfault_debug; @@ -7182,6 +7419,7 @@ sizeof(struct mpt3sas_facts)); ioc->non_operational_loop = 0; + ioc->ioc_coredump_loop = 0; ioc->got_task_abort_from_ioctl = 0; return 0; @@ -7263,14 +7501,14 @@ } /** - * _base_after_reset_handler - after reset handler + * _base_clear_outstanding_mpt_commands - clears outstanding mpt commands * @ioc: per adapter object */ -static void _base_after_reset_handler(struct MPT3SAS_ADAPTER *ioc) +static void +_base_clear_outstanding_mpt_commands(struct MPT3SAS_ADAPTER *ioc) { - mpt3sas_scsih_after_reset_handler(ioc); - mpt3sas_ctl_after_reset_handler(ioc); - dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_AFTER_RESET\n", __func__)); + dtmprintk(ioc, + ioc_info(ioc, "%s: clear outstanding mpt cmds\n", __func__)); if (ioc->transport_cmds.status & MPT3_CMD_PENDING) { ioc->transport_cmds.status |= MPT3_CMD_RESET; mpt3sas_base_free_smid(ioc, ioc->transport_cmds.smid); @@ -7304,6 +7542,17 @@ } /** + * _base_clear_outstanding_commands - clear all outstanding commands + * @ioc: per adapter object + */ +static void _base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc) +{ + mpt3sas_scsih_clear_outstanding_scsi_tm_commands(ioc); + mpt3sas_ctl_clear_outstanding_ioctls(ioc); + _base_clear_outstanding_mpt_commands(ioc); +} + +/** * _base_reset_done_handler - reset done handler * @ioc: per adapter object */ @@ -7362,6 +7611,12 @@ if (ioc->facts.MaxDevHandle % 8) pd_handles_sz++; + /* + * pd_handles should have, at least, the minimal room for + * set_bit()/test_bit(), otherwise out-of-memory touch may + * occur. + */ + pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long)); pd_handles = krealloc(ioc->pd_handles, pd_handles_sz, GFP_KERNEL); if (!pd_handles) { @@ -7461,7 +7716,9 @@ MPT3_DIAG_BUFFER_IS_RELEASED))) { is_trigger = 1; ioc_state = mpt3sas_base_get_iocstate(ioc, 0); - if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) + if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT || + (ioc_state & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) is_fault = 1; } _base_pre_reset_handler(ioc); @@ -7470,7 +7727,7 @@ r = _base_make_ioc_ready(ioc, type); if (r) goto out; - _base_after_reset_handler(ioc); + _base_clear_outstanding_commands(ioc); /* If this hard reset is called while port enable is active, then * there is no reason to call make_ioc_operational @@ -7501,9 +7758,7 @@ _base_reset_done_handler(ioc); out: - dtmprintk(ioc, - ioc_info(ioc, "%s: %s\n", - __func__, r == 0 ? "SUCCESS" : "FAILED")); + ioc_info(ioc, "%s: %s\n", __func__, r == 0 ? "SUCCESS" : "FAILED"); spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); ioc->shost_recovery = 0; --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_base.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -76,9 +76,9 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "31.100.00.00" -#define MPT3SAS_MAJOR_VERSION 31 -#define MPT3SAS_MINOR_VERSION 100 +#define MPT3SAS_DRIVER_VERSION "35.101.00.00" +#define MPT3SAS_MAJOR_VERSION 35 +#define MPT3SAS_MINOR_VERSION 101 #define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION 00 @@ -90,6 +90,10 @@ #define MPT2SAS_BUILD_VERSION 0 #define MPT2SAS_RELEASE_VERSION 00 +/* CoreDump: Default timeout */ +#define MPT3SAS_DEFAULT_COREDUMP_TIMEOUT_SECONDS (15) /*15 seconds*/ +#define MPT3SAS_COREDUMP_LOOP_DONE (0xFF) + /* * Set MPT3SAS_SG_DEPTH value based on user input. */ @@ -140,6 +144,7 @@ #define MAX_CHAIN_ELEMT_SZ 16 #define DEFAULT_NUM_FWCHAIN_ELEMTS 8 +#define IO_UNIT_CONTROL_SHUTDOWN_TIMEOUT 6 #define FW_IMG_HDR_READ_TIMEOUT 15 #define IOC_OPERATIONAL_WAIT_COUNT 10 @@ -303,6 +308,8 @@ #define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) #define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) +#define MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED (0x08) +#define MPT3_DIAG_BUFFER_IS_APP_OWNED (0x10) /* * HP HBA branding @@ -391,9 +398,15 @@ u8 Reserved6; /* 2Fh */ __le32 Reserved7[7]; /* 30h - 4Bh */ u8 NVMeAbortTO; /* 4Ch */ - u8 Reserved8; /* 4Dh */ - u16 Reserved9; /* 4Eh */ - __le32 Reserved10[4]; /* 50h - 60h */ + u8 NumPerDevEvents; /* 4Dh */ + u8 HostTraceBufferDecrementSizeKB; /* 4Eh */ + u8 HostTraceBufferFlags; /* 4Fh */ + u16 HostTraceBufferMaxSizeKB; /* 50h */ + u16 HostTraceBufferMinSizeKB; /* 52h */ + u8 CoreDumpTOSec; /* 54h */ + u8 Reserved8; /* 55h */ + u16 Reserved9; /* 56h */ + __le32 Reserved10; /* 58h */ }; /** @@ -406,6 +419,7 @@ * @flags: MPT_TARGET_FLAGS_XXX flags * @deleted: target flaged for deletion * @tm_busy: target is busy with TM request. + * @port: hba port entry containing target's port number info * @sas_dev: The sas_device associated with this target * @pcie_dev: The pcie device associated with this target */ @@ -418,6 +432,7 @@ u32 flags; u8 deleted; u8 tm_busy; + struct hba_port *port; struct _sas_device *sas_dev; struct _pcie_device *pcie_dev; }; @@ -520,6 +535,9 @@ * addition routine. * @chassis_slot: chassis slot * @is_chassis_slot_valid: chassis slot valid or not + * @port: hba port entry containing device's port number info + * @rphy: device's sas_rphy address used to identify this device structure in + * target_alloc callback function */ struct _sas_device { struct list_head list; @@ -546,6 +564,8 @@ u8 is_chassis_slot_valid; u8 connector_name[5]; struct kref refcount; + struct hba_port *port; + struct sas_rphy *rphy; }; static inline void sas_device_get(struct _sas_device *s) @@ -584,6 +604,7 @@ * @connector_name: ASCII value of the Connector's name * @serial_number: pointer of serial number string allocated runtime * @access_status: Device's Access Status + * @shutdown_latency: NVMe device's RTD3 Entry Latency * @refcount: reference count for deletion */ struct _pcie_device { @@ -606,6 +627,7 @@ u8 *serial_number; u8 reset_timeout; u8 access_status; + u16 shutdown_latency; struct kref refcount; }; /** @@ -714,6 +736,7 @@ * @remote_identify: attached device identification * @rphy: sas transport rphy object * @port: sas transport wide/narrow port object + * @hba_port: hba port entry containing port's port number info * @phy_list: _sas_phy list objects belonging to this port */ struct _sas_port { @@ -722,6 +745,7 @@ struct sas_identify remote_identify; struct sas_rphy *rphy; struct sas_port *port; + struct hba_port *hba_port; struct list_head phy_list; }; @@ -735,6 +759,7 @@ * @handle: device handle for this phy * @attached_handle: device handle for attached device * @phy_belongs_to_port: port has been created for this phy + * @port: hba port entry containing port number info */ struct _sas_phy { struct list_head port_siblings; @@ -745,6 +770,8 @@ u16 handle; u16 attached_handle; u8 phy_belongs_to_port; + u8 hba_vphy; + struct hba_port *port; }; /** @@ -760,6 +787,8 @@ * @responding: used in _scsih_expander_device_mark_responding * @phy: a list of phys that make up this sas_host/expander * @sas_port_list: list of ports attached to this sas_host/expander + * @port: hba port entry containing node's port number info + * @rphy: sas_rphy object of this expander */ struct _sas_node { struct list_head list; @@ -771,11 +800,12 @@ u16 enclosure_handle; u64 enclosure_logical_id; u8 responding; + struct hba_port *port; struct _sas_phy *phy; struct list_head sas_port_list; + struct sas_rphy *rphy; }; - /** * struct _enclosure_node - enclosure information * @list: list of enclosures @@ -993,6 +1023,46 @@ dma_addr_t reply_post_free_dma; }; +/** + * struct virtual_phy - vSES phy structure + * sas_address: SAS Address of vSES device + * phy_mask: vSES device's phy number + * flags: flags used to manage this structure + */ +struct virtual_phy { + struct list_head list; + u64 sas_address; + u32 phy_mask; + u8 flags; +}; + +#define MPT_VPHY_FLAG_DIRTY_PHY 0x01 + +/** + * struct hba_port - Saves each HBA's Wide/Narrow port info + * @sas_address: sas address of this wide/narrow port's attached device + * @phy_mask: HBA PHY's belonging to this port + * @port_id: port number + * @flags: hba port flags + * @vphys_mask : mask of vSES devices Phy number + * @vphys_list : list containing vSES device structures + */ +struct hba_port { + struct list_head list; + u64 sas_address; + u32 phy_mask; + u8 port_id; + u8 flags; + u32 vphys_mask; + struct list_head vphys_list; +}; + +/* hba port flags */ +#define HBA_PORT_FLAG_DIRTY_PORT 0x01 +#define HBA_PORT_FLAG_NEW_PORT 0x02 + +#define MULTIPATH_DISABLED_PORT_ID 0xFF + typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); /** * struct MPT3SAS_ADAPTER - per adapter struct @@ -1040,6 +1110,7 @@ * @cpu_msix_table: table for mapping cpus to msix index * @cpu_msix_table_sz: table size * @total_io_cnt: Gives total IO count, used to load balance the interrupts + * @ioc_coredump_loop: will have non-zero value when FW is in CoreDump state * @high_iops_outstanding: used to load balance the interrupts * within high iops reply queues * @msix_load_balance: Enables load balancing of interrupts across @@ -1068,6 +1139,10 @@ * @event_context: unique id for each logged event * @event_log: event log pointer * @event_masks: events that are masked + * @max_shutdown_latency: timeout value for NVMe shutdown operation, + * which is equal that NVMe drive's RTD3 Entry Latency + * which has reported maximum RTD3 Entry Latency value + * among attached NVMe drives. * @facts: static facts data * @prev_fw_facts: previous fw facts data * @pfacts: static port facts data @@ -1168,6 +1243,8 @@ * which ensures the syncrhonization between cli/sysfs_show path. * @atomic_desc_capable: Atomic Request Descriptor support. * @GET_MSIX_INDEX: Get the msix index of high iops queues. + * @multipath_on_hba: flag to determine multipath on hba is enabled or not + * @port_table_list: list containing HBA's wide/narrow port's info */ struct MPT3SAS_ADAPTER { struct list_head list; @@ -1226,6 +1303,7 @@ u32 ioc_reset_count; MPT3SAS_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; u32 non_operational_loop; + u8 ioc_coredump_loop; atomic64_t total_io_cnt; atomic64_t high_iops_outstanding; bool msix_load_balance; @@ -1278,7 +1356,7 @@ u8 tm_custom_handling; u8 nvme_abort_timeout; - + u16 max_shutdown_latency; /* static config pages */ struct mpt3sas_facts facts; @@ -1455,6 +1533,9 @@ PUT_SMID_IO_FP_HIP put_smid_hi_priority; PUT_SMID_DEFAULT put_smid_default; GET_MSIX_INDEX get_msix_index_for_smlio; + + u8 multipath_on_hba; + struct list_head port_table_list; }; #define MPT_DRV_SUPPORT_BITMAP_MEMMOVE 0x00000001 @@ -1526,6 +1607,17 @@ u32 mpt3sas_base_get_iocstate(struct MPT3SAS_ADAPTER *ioc, int cooked); void mpt3sas_base_fault_info(struct MPT3SAS_ADAPTER *ioc , u16 fault_code); +#define mpt3sas_print_fault_code(ioc, fault_code) \ +do { pr_err("%s fault info from func: %s\n", ioc->name, __func__); \ + mpt3sas_base_fault_info(ioc, fault_code); } while (0) + +void mpt3sas_base_coredump_info(struct MPT3SAS_ADAPTER *ioc, u16 fault_code); +#define mpt3sas_print_coredump_info(ioc, fault_code) \ +do { pr_err("%s fault info from func: %s\n", ioc->name, __func__); \ + mpt3sas_base_coredump_info(ioc, fault_code); } while (0) + +int mpt3sas_base_wait_for_coredump_completion(struct MPT3SAS_ADAPTER *ioc, + const char *caller); int mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, Mpi2SasIoUnitControlReply_t *mpi_reply, Mpi2SasIoUnitControlRequest_t *mpi_request); @@ -1547,6 +1639,11 @@ u8 mpt3sas_base_check_cmd_timeout(struct MPT3SAS_ADAPTER *ioc, u8 status, void *mpi_request, int sz); +#define mpt3sas_check_cmd_timeout(ioc, status, mpi_request, sz, issue_reset) \ +do { ioc_err(ioc, "In func: %s\n", __func__); \ + issue_reset = mpt3sas_base_check_cmd_timeout(ioc, \ + status, mpi_request, sz); } while (0) + int mpt3sas_wait_for_ioc(struct MPT3SAS_ADAPTER *ioc, int wait_count); /* scsih shared API */ @@ -1555,7 +1652,8 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply); void mpt3sas_scsih_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc); -void mpt3sas_scsih_after_reset_handler(struct MPT3SAS_ADAPTER *ioc); +void mpt3sas_scsih_clear_outstanding_scsi_tm_commands( + struct MPT3SAS_ADAPTER *ioc); void mpt3sas_scsih_reset_done_handler(struct MPT3SAS_ADAPTER *ioc); int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun, @@ -1566,20 +1664,27 @@ void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle); -void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address); +void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct hba_port *port); void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address); + u64 sas_address, struct hba_port *port); u8 mpt3sas_check_for_pending_internal_cmds(struct MPT3SAS_ADAPTER *ioc, u16 smid); +struct hba_port * +mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, u8 port, + u8 bypass_dirty_port_flag); struct _sas_node *mpt3sas_scsih_expander_find_by_handle( struct MPT3SAS_ADAPTER *ioc, u16 handle); struct _sas_node *mpt3sas_scsih_expander_find_by_sas_address( - struct MPT3SAS_ADAPTER *ioc, u64 sas_address); + struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct hba_port *port); struct _sas_device *mpt3sas_get_sdev_by_addr( - struct MPT3SAS_ADAPTER *ioc, u64 sas_address); + struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct hba_port *port); struct _sas_device *__mpt3sas_get_sdev_by_addr( - struct MPT3SAS_ADAPTER *ioc, u64 sas_address); + struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct hba_port *port); struct _sas_device *mpt3sas_get_sdev_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); struct _pcie_device *mpt3sas_get_pdev_by_handle(struct MPT3SAS_ADAPTER *ioc, @@ -1589,6 +1694,11 @@ struct _raid_device * mpt3sas_raid_device_find_by_handle(struct MPT3SAS_ADAPTER *ioc, u16 handle); void mpt3sas_scsih_change_queue_depth(struct scsi_device *sdev, int qdepth); +struct _sas_device * +__mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, struct sas_rphy *rphy); +struct virtual_phy * +mpt3sas_get_vphy_by_phy(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port, u32 phy); /* config shared API */ u8 mpt3sas_config_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, @@ -1689,7 +1799,7 @@ u8 mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply); void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc); -void mpt3sas_ctl_after_reset_handler(struct MPT3SAS_ADAPTER *ioc); +void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc); void mpt3sas_ctl_reset_done_handler(struct MPT3SAS_ADAPTER *ioc); u8 mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply); @@ -1706,18 +1816,26 @@ u8 mpt3sas_transport_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply); struct _sas_port *mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, - u16 handle, u64 sas_address); + u16 handle, u64 sas_address, struct hba_port *port); void mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, - u64 sas_address_parent); + u64 sas_address_parent, struct hba_port *port); int mpt3sas_transport_add_host_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy *mpt3sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev); int mpt3sas_transport_add_expander_phy(struct MPT3SAS_ADAPTER *ioc, struct _sas_phy *mpt3sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev); void mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address, u16 handle, u8 phy_number, u8 link_rate); + u64 sas_address, u16 handle, u8 phy_number, u8 link_rate, + struct hba_port *port); extern struct sas_function_template mpt3sas_transport_functions; extern struct scsi_transport_template *mpt3sas_transport_template; +void +mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy); +void +mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, + struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy, + u64 sas_address, struct hba_port *port); /* trigger data externs */ void mpt3sas_send_trigger_data_event(struct MPT3SAS_ADAPTER *ioc, struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data); --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_config.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -101,9 +101,6 @@ Mpi2ConfigRequest_t *mpi_request; char *desc = NULL; - if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) - return; - mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); switch (mpi_request->Header.PageType & MPI2_CONFIG_PAGETYPE_MASK) { case MPI2_CONFIG_PAGETYPE_IO_UNIT: @@ -269,7 +266,8 @@ mpi_reply->MsgLength*4); } ioc->config_cmds.status &= ~MPT3_CMD_PENDING; - _config_display_some_debug(ioc, smid, "config_done", mpi_reply); + if (ioc->logging_level & MPT_DEBUG_CONFIG) + _config_display_some_debug(ioc, smid, "config_done", mpi_reply); ioc->config_cmds.smid = USHRT_MAX; complete(&ioc->config_cmds.done); return 1; @@ -305,6 +303,7 @@ u8 retry_count, issue_host_reset = 0; struct config_request mem; u32 ioc_status = UINT_MAX; + u8 issue_reset = 0; mutex_lock(&ioc->config_cmds.mutex); if (ioc->config_cmds.status != MPT3_CMD_NOT_USED) { @@ -378,14 +377,18 @@ config_request = mpt3sas_base_get_msg_frame(ioc, smid); ioc->config_cmds.smid = smid; memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); - _config_display_some_debug(ioc, smid, "config_request", NULL); + if (ioc->logging_level & MPT_DEBUG_CONFIG) + _config_display_some_debug(ioc, smid, "config_request", NULL); init_completion(&ioc->config_cmds.done); ioc->put_smid_default(ioc, smid); wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ); if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { - mpt3sas_base_check_cmd_timeout(ioc, - ioc->config_cmds.status, mpi_request, - sizeof(Mpi2ConfigRequest_t)/4); + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); + mpt3sas_check_cmd_timeout(ioc, + ioc->config_cmds.status, mpi_request, + sizeof(Mpi2ConfigRequest_t)/4, issue_reset); retry_count++; if (ioc->config_cmds.smid == smid) mpt3sas_base_free_smid(ioc, smid); @@ -404,8 +407,11 @@ /* Reply Frame Sanity Checks to workaround FW issues */ if ((mpi_request->Header.PageType & 0xF) != (mpi_reply->Header.PageType & 0xF)) { + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); _debug_dump_mf(mpi_request, ioc->request_sz/4); - _debug_dump_reply(mpi_reply, ioc->request_sz/4); + _debug_dump_reply(mpi_reply, ioc->reply_sz/4); panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", ioc->name, __func__, mpi_request->Header.PageType & 0xF, @@ -415,8 +421,11 @@ if (((mpi_request->Header.PageType & 0xF) == MPI2_CONFIG_PAGETYPE_EXTENDED) && mpi_request->ExtPageType != mpi_reply->ExtPageType) { + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); _debug_dump_mf(mpi_request, ioc->request_sz/4); - _debug_dump_reply(mpi_reply, ioc->request_sz/4); + _debug_dump_reply(mpi_reply, ioc->reply_sz/4); panic("%s: %s: Firmware BUG: mpi_reply mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", ioc->name, __func__, mpi_request->ExtPageType, @@ -439,8 +448,11 @@ if (p) { if ((mpi_request->Header.PageType & 0xF) != (p[3] & 0xF)) { + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); _debug_dump_mf(mpi_request, ioc->request_sz/4); - _debug_dump_reply(mpi_reply, ioc->request_sz/4); + _debug_dump_reply(mpi_reply, ioc->reply_sz/4); _debug_dump_config(p, min_t(u16, mem.sz, config_page_sz)/4); panic("%s: %s: Firmware BUG: config page mismatch: Requested PageType(0x%02x) Reply PageType(0x%02x)\n", @@ -452,8 +464,11 @@ if (((mpi_request->Header.PageType & 0xF) == MPI2_CONFIG_PAGETYPE_EXTENDED) && (mpi_request->ExtPageType != p[6])) { + if (!(ioc->logging_level & MPT_DEBUG_CONFIG)) + _config_display_some_debug(ioc, + smid, "config_request", NULL); _debug_dump_mf(mpi_request, ioc->request_sz/4); - _debug_dump_reply(mpi_reply, ioc->request_sz/4); + _debug_dump_reply(mpi_reply, ioc->reply_sz/4); _debug_dump_config(p, min_t(u16, mem.sz, config_page_sz)/4); panic("%s: %s: Firmware BUG: config page mismatch: Requested ExtPageType(0x%02x) Reply ExtPageType(0x%02x)\n", --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -180,6 +180,12 @@ case MPI2_FUNCTION_SMP_PASSTHROUGH: desc = "smp_passthrough"; break; + case MPI2_FUNCTION_TOOLBOX: + desc = "toolbox"; + break; + case MPI2_FUNCTION_NVME_ENCAPSULATED: + desc = "nvme_encapsulated"; + break; } if (!desc) @@ -466,19 +472,27 @@ if ((ioc->diag_buffer_status[i] & MPT3_DIAG_BUFFER_IS_RELEASED)) continue; + + /* + * add a log message to indicate the release + */ + ioc_info(ioc, + "%s: Releasing the trace buffer due to adapter reset.", + __func__); mpt3sas_send_diag_release(ioc, i, &issue_reset); } } /** - * mpt3sas_ctl_reset_handler - reset callback handler (for ctl) + * mpt3sas_ctl_reset_handler - clears outstanding ioctl cmd. * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. */ -void mpt3sas_ctl_after_reset_handler(struct MPT3SAS_ADAPTER *ioc) +void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc) { - dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_AFTER_RESET\n", __func__)); + dtmprintk(ioc, + ioc_info(ioc, "%s: clear outstanding ioctl cmd\n", __func__)); if (ioc->ctl_cmds.status & MPT3_CMD_PENDING) { ioc->ctl_cmds.status |= MPT3_CMD_RESET; mpt3sas_base_free_smid(ioc, ioc->ctl_cmds.smid); @@ -650,7 +664,7 @@ Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL; struct _pcie_device *pcie_device = NULL; u16 smid; - u8 timeout; + unsigned long timeout; u8 issue_reset; u32 sz, sz_arg; void *psge; @@ -778,6 +792,18 @@ case MPI2_FUNCTION_NVME_ENCAPSULATED: { nvme_encap_request = (Mpi26NVMeEncapsulatedRequest_t *)request; + if (!ioc->pcie_sg_lookup) { + dtmprintk(ioc, ioc_info(ioc, + "HBA doesn't support NVMe. Rejecting NVMe Encapsulated request.\n" + )); + + if (ioc->logging_level & MPT_DEBUG_TM) + _debug_dump_mf(nvme_encap_request, + ioc->request_sz/4); + mpt3sas_base_free_smid(ioc, smid); + ret = -EINVAL; + goto out; + } /* * Get the Physical Address of the sense buffer. * Use Error Response buffer address field to hold the sense @@ -876,8 +902,10 @@ (Mpi2SmpPassthroughRequest_t *)mpi_request; u8 *data; - /* ioc determines which port to use */ - smp_request->PhysicalPort = 0xFF; + if (!ioc->multipath_on_hba) { + /* ioc determines which port to use */ + smp_request->PhysicalPort = 0xFF; + } if (smp_request->PassthroughFlags & MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE) data = (u8 *)&smp_request->SGL; @@ -1002,10 +1030,9 @@ ioc->ignore_loginfos = 0; } if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->ctl_cmds.status, mpi_request, - karg.data_sge_offset); + mpt3sas_check_cmd_timeout(ioc, + ioc->ctl_cmds.status, mpi_request, + karg.data_sge_offset, issue_reset); goto issue_host_reset; } @@ -1306,7 +1333,8 @@ __func__)); retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); - ioc_info(ioc, "host reset: %s\n", ((!retval) ? "SUCCESS" : "FAILED")); + ioc_info(ioc, + "Ioctl: host reset: %s\n", ((!retval) ? "SUCCESS" : "FAILED")); return 0; } @@ -1484,6 +1512,26 @@ return rc; } +/** + * _ctl_diag_get_bufftype - return diag buffer type + * either TRACE, SNAPSHOT, or EXTENDED + * @ioc: per adapter object + * @unique_id: specifies the unique_id for the buffer + * + * returns MPT3_DIAG_UID_NOT_FOUND if the id not found + */ +static u8 +_ctl_diag_get_bufftype(struct MPT3SAS_ADAPTER *ioc, u32 unique_id) +{ + u8 index; + + for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { + if (ioc->unique_id[index] == unique_id) + return index; + } + + return MPT3_DIAG_UID_NOT_FOUND; +} /** * _ctl_diag_register_2 - wrapper for registering diag buffer support @@ -1531,11 +1579,88 @@ return -EPERM; } + if (diag_register->unique_id == 0) { + ioc_err(ioc, + "%s: Invalid UID(0x%08x), buffer_type(0x%02x)\n", __func__, + diag_register->unique_id, buffer_type); + return -EINVAL; + } + + if ((ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_APP_OWNED) && + !(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_RELEASED)) { + ioc_err(ioc, + "%s: buffer_type(0x%02x) is already registered by application with UID(0x%08x)\n", + __func__, buffer_type, ioc->unique_id[buffer_type]); + return -EINVAL; + } + if (ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_REGISTERED) { - ioc_err(ioc, "%s: already has a registered buffer for buffer_type(0x%02x)\n", - __func__, buffer_type); - return -EINVAL; + /* + * If driver posts buffer initially, then an application wants + * to Register that buffer (own it) without Releasing first, + * the application Register command MUST have the same buffer + * type and size in the Register command (obtained from the + * Query command). Otherwise that Register command will be + * failed. If the application has released the buffer but wants + * to re-register it, it should be allowed as long as the + * Unique-Id/Size match. + */ + + if (ioc->unique_id[buffer_type] == MPT3DIAGBUFFUNIQUEID && + ioc->diag_buffer_sz[buffer_type] == + diag_register->requested_buffer_size) { + + if (!(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_RELEASED)) { + dctlprintk(ioc, ioc_info(ioc, + "%s: diag_buffer (%d) ownership changed. old-ID(0x%08x), new-ID(0x%08x)\n", + __func__, buffer_type, + ioc->unique_id[buffer_type], + diag_register->unique_id)); + + /* + * Application wants to own the buffer with + * the same size. + */ + ioc->unique_id[buffer_type] = + diag_register->unique_id; + rc = 0; /* success */ + goto out; + } + } else if (ioc->unique_id[buffer_type] != + MPT3DIAGBUFFUNIQUEID) { + if (ioc->unique_id[buffer_type] != + diag_register->unique_id || + ioc->diag_buffer_sz[buffer_type] != + diag_register->requested_buffer_size || + !(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_RELEASED)) { + ioc_err(ioc, + "%s: already has a registered buffer for buffer_type(0x%02x)\n", + __func__, buffer_type); + return -EINVAL; + } + } else { + ioc_err(ioc, "%s: already has a registered buffer for buffer_type(0x%02x)\n", + __func__, buffer_type); + return -EINVAL; + } + } else if (ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) { + + if (ioc->unique_id[buffer_type] != MPT3DIAGBUFFUNIQUEID || + ioc->diag_buffer_sz[buffer_type] != + diag_register->requested_buffer_size) { + + ioc_err(ioc, + "%s: already a buffer is allocated for buffer_type(0x%02x) of size %d bytes, so please try registering again with same size\n", + __func__, buffer_type, + ioc->diag_buffer_sz[buffer_type]); + return -EINVAL; + } } if (diag_register->requested_buffer_size % 4) { @@ -1560,7 +1685,8 @@ request_data = ioc->diag_buffer[buffer_type]; request_data_sz = diag_register->requested_buffer_size; ioc->unique_id[buffer_type] = diag_register->unique_id; - ioc->diag_buffer_status[buffer_type] = 0; + ioc->diag_buffer_status[buffer_type] &= + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED; memcpy(ioc->product_specific[buffer_type], diag_register->product_specific, MPT3_PRODUCT_SPECIFIC_DWORDS); ioc->diagnostic_flags[buffer_type] = diag_register->diagnostic_flags; @@ -1584,7 +1710,8 @@ ioc_err(ioc, "%s: failed allocating memory for diag buffers, requested size(%d)\n", __func__, request_data_sz); mpt3sas_base_free_smid(ioc, smid); - return -ENOMEM; + rc = -ENOMEM; + goto out; } ioc->diag_buffer[buffer_type] = request_data; ioc->diag_buffer_sz[buffer_type] = request_data_sz; @@ -1615,10 +1742,9 @@ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->ctl_cmds.status, mpi_request, - sizeof(Mpi2DiagBufferPostRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, + ioc->ctl_cmds.status, mpi_request, + sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset); goto issue_host_reset; } @@ -1649,9 +1775,12 @@ out: - if (rc && request_data) + if (rc && request_data) { dma_free_coherent(&ioc->pdev->dev, request_data_sz, request_data, request_data_dma); + ioc->diag_buffer_status[buffer_type] &= + ~MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED; + } ioc->ctl_cmds.status = MPT3_CMD_NOT_USED; return rc; @@ -1669,6 +1798,10 @@ mpt3sas_enable_diag_buffer(struct MPT3SAS_ADAPTER *ioc, u8 bits_to_register) { struct mpt3_diag_register diag_register; + u32 ret_val; + u32 trace_buff_size = ioc->manu_pg11.HostTraceBufferMaxSizeKB<<10; + u32 min_trace_buff_size = 0; + u32 decr_trace_buff_size = 0; memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); @@ -1677,10 +1810,68 @@ ioc->diag_trigger_master.MasterData = (MASTER_TRIGGER_FW_FAULT + MASTER_TRIGGER_ADAPTER_RESET); diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; - /* register for 2MB buffers */ - diag_register.requested_buffer_size = 2 * (1024 * 1024); - diag_register.unique_id = 0x7075900; - _ctl_diag_register_2(ioc, &diag_register); + diag_register.unique_id = + (ioc->hba_mpi_version_belonged == MPI2_VERSION) ? + (MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID); + + if (trace_buff_size != 0) { + diag_register.requested_buffer_size = trace_buff_size; + min_trace_buff_size = + ioc->manu_pg11.HostTraceBufferMinSizeKB<<10; + decr_trace_buff_size = + ioc->manu_pg11.HostTraceBufferDecrementSizeKB<<10; + + if (min_trace_buff_size > trace_buff_size) { + /* The buff size is not set correctly */ + ioc_err(ioc, + "Min Trace Buff size (%d KB) greater than Max Trace Buff size (%d KB)\n", + min_trace_buff_size>>10, + trace_buff_size>>10); + ioc_err(ioc, + "Using zero Min Trace Buff Size\n"); + min_trace_buff_size = 0; + } + + if (decr_trace_buff_size == 0) { + /* + * retry the min size if decrement + * is not available. + */ + decr_trace_buff_size = + trace_buff_size - min_trace_buff_size; + } + } else { + /* register for 2MB buffers */ + diag_register.requested_buffer_size = 2 * (1024 * 1024); + } + + do { + ret_val = _ctl_diag_register_2(ioc, &diag_register); + + if (ret_val == -ENOMEM && min_trace_buff_size && + (trace_buff_size - decr_trace_buff_size) >= + min_trace_buff_size) { + /* adjust the buffer size */ + trace_buff_size -= decr_trace_buff_size; + diag_register.requested_buffer_size = + trace_buff_size; + } else + break; + } while (true); + + if (ret_val == -ENOMEM) + ioc_err(ioc, + "Cannot allocate trace buffer memory. Last memory tried = %d KB\n", + diag_register.requested_buffer_size>>10); + else if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] + & MPT3_DIAG_BUFFER_IS_REGISTERED) { + ioc_err(ioc, "Trace buffer memory %d KB allocated\n", + diag_register.requested_buffer_size>>10); + if (ioc->hba_mpi_version_belonged != MPI2_VERSION) + ioc->diag_buffer_status[ + MPI2_DIAG_BUF_TYPE_TRACE] |= + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED; + } } if (bits_to_register & 2) { @@ -1723,6 +1914,12 @@ } rc = _ctl_diag_register_2(ioc, &karg); + + if (!rc && (ioc->diag_buffer_status[karg.buffer_type] & + MPT3_DIAG_BUFFER_IS_REGISTERED)) + ioc->diag_buffer_status[karg.buffer_type] |= + MPT3_DIAG_BUFFER_IS_APP_OWNED; + return rc; } @@ -1752,7 +1949,13 @@ dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__)); - buffer_type = karg.unique_id & 0x000000ff; + buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id); + if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) { + ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n", + __func__, karg.unique_id); + return -EINVAL; + } + if (!_ctl_diag_capability(ioc, buffer_type)) { ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n", __func__, buffer_type); @@ -1785,12 +1988,21 @@ return -ENOMEM; } - request_data_sz = ioc->diag_buffer_sz[buffer_type]; - request_data_dma = ioc->diag_buffer_dma[buffer_type]; - dma_free_coherent(&ioc->pdev->dev, request_data_sz, - request_data, request_data_dma); - ioc->diag_buffer[buffer_type] = NULL; - ioc->diag_buffer_status[buffer_type] = 0; + if (ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED) { + ioc->unique_id[buffer_type] = MPT3DIAGBUFFUNIQUEID; + ioc->diag_buffer_status[buffer_type] &= + ~MPT3_DIAG_BUFFER_IS_APP_OWNED; + ioc->diag_buffer_status[buffer_type] &= + ~MPT3_DIAG_BUFFER_IS_REGISTERED; + } else { + request_data_sz = ioc->diag_buffer_sz[buffer_type]; + request_data_dma = ioc->diag_buffer_dma[buffer_type]; + dma_free_coherent(&ioc->pdev->dev, request_data_sz, + request_data, request_data_dma); + ioc->diag_buffer[buffer_type] = NULL; + ioc->diag_buffer_status[buffer_type] = 0; + } return 0; } @@ -1829,14 +2041,17 @@ return -EPERM; } - if ((ioc->diag_buffer_status[buffer_type] & - MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { - ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n", - __func__, buffer_type); - return -EINVAL; + if (!(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED)) { + if ((ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { + ioc_err(ioc, "%s: buffer_type(0x%02x) is not registered\n", + __func__, buffer_type); + return -EINVAL; + } } - if (karg.unique_id & 0xffffff00) { + if (karg.unique_id) { if (karg.unique_id != ioc->unique_id[buffer_type]) { ioc_err(ioc, "%s: unique_id(0x%08x) is not registered\n", __func__, karg.unique_id); @@ -1851,13 +2066,21 @@ return -ENOMEM; } - if (ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_RELEASED) - karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | - MPT3_APP_FLAGS_BUFFER_VALID); - else - karg.application_flags = (MPT3_APP_FLAGS_APP_OWNED | - MPT3_APP_FLAGS_BUFFER_VALID | - MPT3_APP_FLAGS_FW_BUFFER_ACCESS); + if ((ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_REGISTERED)) + karg.application_flags |= MPT3_APP_FLAGS_BUFFER_VALID; + + if (!(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_RELEASED)) + karg.application_flags |= MPT3_APP_FLAGS_FW_BUFFER_ACCESS; + + if (!(ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED)) + karg.application_flags |= MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC; + + if ((ioc->diag_buffer_status[buffer_type] & + MPT3_DIAG_BUFFER_IS_APP_OWNED)) + karg.application_flags |= MPT3_APP_FLAGS_APP_OWNED; for (i = 0; i < MPT3_PRODUCT_SPECIFIC_DWORDS; i++) karg.product_specific[i] = @@ -1893,6 +2116,7 @@ u16 ioc_status; u32 ioc_state; int rc; + u8 reset_needed = 0; dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__)); @@ -1900,6 +2124,7 @@ rc = 0; *issue_reset = 0; + ioc_state = mpt3sas_base_get_iocstate(ioc, 1); if (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { if (ioc->diag_buffer_status[buffer_type] & @@ -1942,9 +2167,10 @@ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { - *issue_reset = mpt3sas_base_check_cmd_timeout(ioc, - ioc->ctl_cmds.status, mpi_request, - sizeof(Mpi2DiagReleaseRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, + ioc->ctl_cmds.status, mpi_request, + sizeof(Mpi2DiagReleaseRequest_t)/4, reset_needed); + *issue_reset = reset_needed; rc = -EFAULT; goto out; } @@ -2002,7 +2228,13 @@ dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__)); - buffer_type = karg.unique_id & 0x000000ff; + buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id); + if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) { + ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n", + __func__, karg.unique_id); + return -EINVAL; + } + if (!_ctl_diag_capability(ioc, buffer_type)) { ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n", __func__, buffer_type); @@ -2026,7 +2258,7 @@ MPT3_DIAG_BUFFER_IS_RELEASED) { ioc_err(ioc, "%s: buffer_type(0x%02x) is already released\n", __func__, buffer_type); - return 0; + return -EINVAL; } request_data = ioc->diag_buffer[buffer_type]; @@ -2086,7 +2318,13 @@ dctlprintk(ioc, ioc_info(ioc, "%s\n", __func__)); - buffer_type = karg.unique_id & 0x000000ff; + buffer_type = _ctl_diag_get_bufftype(ioc, karg.unique_id); + if (buffer_type == MPT3_DIAG_UID_NOT_FOUND) { + ioc_err(ioc, "%s: buffer with unique_id(0x%08x) not found\n", + __func__, karg.unique_id); + return -EINVAL; + } + if (!_ctl_diag_capability(ioc, buffer_type)) { ioc_err(ioc, "%s: doesn't have capability for buffer_type(0x%02x)\n", __func__, buffer_type); @@ -2190,10 +2428,9 @@ MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); if (!(ioc->ctl_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->ctl_cmds.status, mpi_request, - sizeof(Mpi2DiagBufferPostRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, + ioc->ctl_cmds.status, mpi_request, + sizeof(Mpi2DiagBufferPostRequest_t)/4, issue_reset); goto issue_host_reset; } @@ -2210,6 +2447,8 @@ if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { ioc->diag_buffer_status[buffer_type] |= MPT3_DIAG_BUFFER_IS_REGISTERED; + ioc->diag_buffer_status[buffer_type] &= + ~MPT3_DIAG_BUFFER_IS_RELEASED; dctlprintk(ioc, ioc_info(ioc, "%s: success\n", __func__)); } else { ioc_info(ioc, "%s: ioc_status(0x%04x) log_info(0x%08x)\n", @@ -2908,19 +3147,18 @@ if (!ioc->is_warpdrive) { ioc_err(ioc, "%s: BRM attribute is only for warpdrive\n", __func__); - goto out; + return 0; } /* pci_access_mutex lock acquired by sysfs show path */ mutex_lock(&ioc->pci_access_mutex); - if (ioc->pci_error_recovery || ioc->remove_host) { - mutex_unlock(&ioc->pci_access_mutex); - return 0; - } + if (ioc->pci_error_recovery || ioc->remove_host) + goto out; /* allocate upto GPIOVal 36 entries */ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); io_unit_pg3 = kzalloc(sz, GFP_KERNEL); if (!io_unit_pg3) { + rc = -ENOMEM; ioc_err(ioc, "%s: failed allocating memory for iounit_pg3: (%d) bytes\n", __func__, sz); goto out; @@ -2930,6 +3168,7 @@ 0) { ioc_err(ioc, "%s: failed reading iounit_pg3\n", __func__); + rc = -EINVAL; goto out; } @@ -2937,12 +3176,14 @@ if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { ioc_err(ioc, "%s: iounit_pg3 failed with ioc_status(0x%04x)\n", __func__, ioc_status); + rc = -EINVAL; goto out; } if (io_unit_pg3->GPIOCount < 25) { ioc_err(ioc, "%s: iounit_pg3->GPIOCount less than 25 entries, detected (%d) entries\n", __func__, io_unit_pg3->GPIOCount); + rc = -EINVAL; goto out; } @@ -3130,10 +3371,49 @@ memset(&diag_register, 0, sizeof(struct mpt3_diag_register)); ioc_info(ioc, "posting host trace buffers\n"); diag_register.buffer_type = MPI2_DIAG_BUF_TYPE_TRACE; - diag_register.requested_buffer_size = (1024 * 1024); - diag_register.unique_id = 0x7075900; + + if (ioc->manu_pg11.HostTraceBufferMaxSizeKB != 0 && + ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0) { + /* post the same buffer allocated previously */ + diag_register.requested_buffer_size = + ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE]; + } else { + /* + * Free the diag buffer memory which was previously + * allocated by an application. + */ + if ((ioc->diag_buffer_sz[MPI2_DIAG_BUF_TYPE_TRACE] != 0) + && + (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & + MPT3_DIAG_BUFFER_IS_APP_OWNED)) { + pci_free_consistent(ioc->pdev, + ioc->diag_buffer_sz[ + MPI2_DIAG_BUF_TYPE_TRACE], + ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE], + ioc->diag_buffer_dma[ + MPI2_DIAG_BUF_TYPE_TRACE]); + ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE] = + NULL; + } + + diag_register.requested_buffer_size = (1024 * 1024); + } + + diag_register.unique_id = + (ioc->hba_mpi_version_belonged == MPI2_VERSION) ? + (MPT2DIAGBUFFUNIQUEID):(MPT3DIAGBUFFUNIQUEID); ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] = 0; _ctl_diag_register_2(ioc, &diag_register); + if (ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & + MPT3_DIAG_BUFFER_IS_REGISTERED) { + ioc_info(ioc, + "Trace buffer %d KB allocated through sysfs\n", + diag_register.requested_buffer_size>>10); + if (ioc->hba_mpi_version_belonged != MPI2_VERSION) + ioc->diag_buffer_status[ + MPI2_DIAG_BUF_TYPE_TRACE] |= + MPT3_DIAG_BUFFER_IS_DRIVER_ALLOCATED; + } } else if (!strcmp(str, "release")) { /* exit out if host buffers are already released */ if (!ioc->diag_buffer[MPI2_DIAG_BUF_TYPE_TRACE]) @@ -3702,12 +3982,6 @@ for (i = 0; i < MPI2_DIAG_BUF_TYPE_COUNT; i++) { if (!ioc->diag_buffer[i]) continue; - if (!(ioc->diag_buffer_status[i] & - MPT3_DIAG_BUFFER_IS_REGISTERED)) - continue; - if ((ioc->diag_buffer_status[i] & - MPT3_DIAG_BUFFER_IS_RELEASED)) - continue; dma_free_coherent(&ioc->pdev->dev, ioc->diag_buffer_sz[i], ioc->diag_buffer[i], --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -95,6 +95,14 @@ #define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \ struct mpt3_diag_read_buffer) +/* Trace Buffer default UniqueId */ +#define MPT2DIAGBUFFUNIQUEID (0x07075900) +#define MPT3DIAGBUFFUNIQUEID (0x4252434D) + +/* UID not found */ +#define MPT3_DIAG_UID_NOT_FOUND (0xFF) + + /** * struct mpt3_ioctl_header - main header structure * @ioc_number - IOC unit number @@ -310,6 +318,7 @@ #define MPT3_APP_FLAGS_APP_OWNED (0x0001) #define MPT3_APP_FLAGS_BUFFER_VALID (0x0002) #define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) +#define MPT3_APP_FLAGS_DYNAMIC_BUFFER_ALLOC (0x0008) /* flags for mpt3_diag_read_buffer */ #define MPT3_FLAGS_REREGISTER (0x0001) --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -159,6 +159,15 @@ MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue, def=disabled(0)"); +static int multipath_on_hba = -1; +module_param(multipath_on_hba, int, 0); +MODULE_PARM_DESC(multipath_on_hba, + "Multipath support to add same target device\n\t\t" + "as many times as it is visible to HBA from various paths\n\t\t" + "(by default:\n\t\t" + "\t SAS 2.0 & SAS 3.0 HBA - This will be disabled,\n\t\t" + "\t SAS 3.5 HBA - This will be enabled)"); + /* raid transport support */ static struct raid_template *mpt3sas_raid_template; static struct raid_template *mpt2sas_raid_template; @@ -357,6 +366,87 @@ } /** + * mpt3sas_get_port_by_id - get hba port entry corresponding to provided + * port number from port list + * @ioc: per adapter object + * @port_id: port number + * @bypass_dirty_port_flag: when set look the matching hba port entry even + * if hba port entry is marked as dirty. + * + * Search for hba port entry corresponding to provided port number, + * if available return port object otherwise return NULL. + */ +struct hba_port * +mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, + u8 port_id, u8 bypass_dirty_port_flag) +{ + struct hba_port *port, *port_next; + + /* + * When multipath_on_hba is disabled then + * search the hba_port entry using default + * port id i.e. 255 + */ + if (!ioc->multipath_on_hba) + port_id = MULTIPATH_DISABLED_PORT_ID; + + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + if (port->port_id != port_id) + continue; + if (bypass_dirty_port_flag) + return port; + if (port->flags & HBA_PORT_FLAG_DIRTY_PORT) + continue; + return port; + } + + /* + * Allocate hba_port object for default port id (i.e. 255) + * when multipath_on_hba is disabled for the HBA. + * And add this object to port_table_list. + */ + if (!ioc->multipath_on_hba) { + port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + if (!port) + return NULL; + + port->port_id = port_id; + ioc_info(ioc, + "hba_port entry: %p, port: %d is added to hba_port list\n", + port, port->port_id); + list_add_tail(&port->list, + &ioc->port_table_list); + return port; + } + return NULL; +} + +/** + * mpt3sas_get_vphy_by_phy - get virtual_phy object corresponding to phy number + * @ioc: per adapter object + * @port: hba_port object + * @phy: phy number + * + * Return virtual_phy object corresponding to phy number. + */ +struct virtual_phy * +mpt3sas_get_vphy_by_phy(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port, u32 phy) +{ + struct virtual_phy *vphy, *vphy_next; + + if (!port->vphys_mask) + return NULL; + + list_for_each_entry_safe(vphy, vphy_next, &port->vphys_list, list) { + if (vphy->phy_mask & (1 << phy)) + return vphy; + } + return NULL; +} + +/** * _scsih_is_boot_device - search for matching boot device. * @sas_address: sas address * @device_name: device name specified in INDENTIFY fram @@ -614,48 +704,105 @@ return ret; } + +/** + * __mpt3sas_get_sdev_by_rphy - sas device search + * @ioc: per adapter object + * @rphy: sas_rphy pointer + * + * Context: This function will acquire ioc->sas_device_lock and will release + * before returning the sas_device object. + * + * This searches for sas_device from rphy object + * then return sas_device object. + */ struct _sas_device * -__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address) +__mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, + struct sas_rphy *rphy) { struct _sas_device *sas_device; assert_spin_locked(&ioc->sas_device_lock); - list_for_each_entry(sas_device, &ioc->sas_device_list, list) - if (sas_device->sas_address == sas_address) - goto found_device; + list_for_each_entry(sas_device, &ioc->sas_device_list, list) { + if (sas_device->rphy != rphy) + continue; + sas_device_get(sas_device); + return sas_device; + } - list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) - if (sas_device->sas_address == sas_address) - goto found_device; + sas_device = NULL; + list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) { + if (sas_device->rphy != rphy) + continue; + sas_device_get(sas_device); + return sas_device; + } return NULL; +} -found_device: - sas_device_get(sas_device); - return sas_device; +/** + * mpt3sas_get_sdev_by_addr - get _sas_device object corresponding to provided + * sas address from sas_device_list list + * @ioc: per adapter object + * @port: port number + * + * Search for _sas_device object corresponding to provided sas address, + * if available return _sas_device object address otherwise return NULL. + */ +struct _sas_device * +__mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, + u64 sas_address, struct hba_port *port) +{ + struct _sas_device *sas_device; + + if (!port) + return NULL; + + assert_spin_locked(&ioc->sas_device_lock); + + list_for_each_entry(sas_device, &ioc->sas_device_list, list) { + if (sas_device->sas_address != sas_address) + continue; + if (sas_device->port != port) + continue; + sas_device_get(sas_device); + return sas_device; + } + + list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) { + if (sas_device->sas_address != sas_address) + continue; + if (sas_device->port != port) + continue; + sas_device_get(sas_device); + return sas_device; + } + + return NULL; } /** * mpt3sas_get_sdev_by_addr - sas device search * @ioc: per adapter object * @sas_address: sas address + * @port: hba port entry * Context: Calling function should acquire ioc->sas_device_lock * - * This searches for sas_device based on sas_address, then return sas_device - * object. + * This searches for sas_device based on sas_address & port number, + * then return sas_device object. */ struct _sas_device * mpt3sas_get_sdev_by_addr(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address) + u64 sas_address, struct hba_port *port) { struct _sas_device *sas_device; unsigned long flags; spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = __mpt3sas_get_sdev_by_addr(ioc, - sas_address); + sas_address, port); spin_unlock_irqrestore(&ioc->sas_device_lock, flags); return sas_device; @@ -824,13 +971,17 @@ } /** - * mpt3sas_device_remove_by_sas_address - removing device object by sas address + * mpt3sas_device_remove_by_sas_address - removing device object by + * sas address & port number * @ioc: per adapter object * @sas_address: device sas_address + * @port: hba port entry + * + * Return nothing. */ void mpt3sas_device_remove_by_sas_address(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address) + u64 sas_address, struct hba_port *port) { struct _sas_device *sas_device; unsigned long flags; @@ -839,7 +990,7 @@ return; spin_lock_irqsave(&ioc->sas_device_lock, flags); - sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address); + sas_device = __mpt3sas_get_sdev_by_addr(ioc, sas_address, port); if (sas_device) { list_del_init(&sas_device->list); sas_device_put(sas_device); @@ -884,7 +1035,7 @@ } if (!mpt3sas_transport_port_add(ioc, sas_device->handle, - sas_device->sas_address_parent)) { + sas_device->sas_address_parent, sas_device->port)) { _scsih_sas_device_remove(ioc, sas_device); } else if (!sas_device->starget) { /* @@ -895,7 +1046,8 @@ if (!ioc->is_driver_loading) { mpt3sas_transport_port_remove(ioc, sas_device->sas_address, - sas_device->sas_address_parent); + sas_device->sas_address_parent, + sas_device->port); _scsih_sas_device_remove(ioc, sas_device); } } else @@ -1050,6 +1202,34 @@ } /** + * _scsih_set_nvme_max_shutdown_latency - Update max_shutdown_latency. + * @ioc: per adapter object + * Context: This function will acquire ioc->pcie_device_lock + * + * Update ioc->max_shutdown_latency to that NVMe drives RTD3 Entry Latency + * which has reported maximum among all available NVMe drives. + * Minimum max_shutdown_latency will be six seconds. + */ +static void +_scsih_set_nvme_max_shutdown_latency(struct MPT3SAS_ADAPTER *ioc) +{ + struct _pcie_device *pcie_device; + unsigned long flags; + u16 shutdown_latency = IO_UNIT_CONTROL_SHUTDOWN_TIMEOUT; + + spin_lock_irqsave(&ioc->pcie_device_lock, flags); + list_for_each_entry(pcie_device, &ioc->pcie_device_list, list) { + if (pcie_device->shutdown_latency) { + if (shutdown_latency < pcie_device->shutdown_latency) + shutdown_latency = + pcie_device->shutdown_latency; + } + } + ioc->max_shutdown_latency = shutdown_latency; + spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); +} + +/** * _scsih_pcie_device_remove - remove pcie_device from list. * @ioc: per adapter object * @pcie_device: the pcie_device object @@ -1063,6 +1243,7 @@ { unsigned long flags; int was_on_pcie_device_list = 0; + u8 update_latency = 0; if (!pcie_device) return; @@ -1082,11 +1263,21 @@ list_del_init(&pcie_device->list); was_on_pcie_device_list = 1; } + if (pcie_device->shutdown_latency == ioc->max_shutdown_latency) + update_latency = 1; spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); if (was_on_pcie_device_list) { kfree(pcie_device->serial_number); pcie_device_put(pcie_device); } + + /* + * This device's RTD3 Entry Latency matches IOC's + * max_shutdown_latency. Recalculate IOC's max_shutdown_latency + * from the available drives as current drive is getting removed. + */ + if (update_latency) + _scsih_set_nvme_max_shutdown_latency(ioc); } @@ -1101,6 +1292,7 @@ struct _pcie_device *pcie_device; unsigned long flags; int was_on_pcie_device_list = 0; + u8 update_latency = 0; if (ioc->shost_recovery) return; @@ -1113,12 +1305,22 @@ was_on_pcie_device_list = 1; pcie_device_put(pcie_device); } + if (pcie_device->shutdown_latency == ioc->max_shutdown_latency) + update_latency = 1; } spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); if (was_on_pcie_device_list) { _scsih_pcie_device_remove_from_sml(ioc, pcie_device); pcie_device_put(pcie_device); } + + /* + * This device's RTD3 Entry Latency matches IOC's + * max_shutdown_latency. Recalculate IOC's max_shutdown_latency + * from the available drives as current drive is getting removed. + */ + if (update_latency) + _scsih_set_nvme_max_shutdown_latency(ioc); } /** @@ -1382,21 +1584,26 @@ * mpt3sas_scsih_expander_find_by_sas_address - expander device search * @ioc: per adapter object * @sas_address: sas address + * @port: hba port entry * Context: Calling function should acquire ioc->sas_node_lock. * - * This searches for expander device based on sas_address, then returns the - * sas_node object. + * This searches for expander device based on sas_address & port number, + * then returns the sas_node object. */ struct _sas_node * mpt3sas_scsih_expander_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address) + u64 sas_address, struct hba_port *port) { - struct _sas_node *sas_expander, *r; + struct _sas_node *sas_expander, *r = NULL; + + if (!port) + return r; - r = NULL; list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { if (sas_expander->sas_address != sas_address) continue; + if (sas_expander->port != port) + continue; r = sas_expander; goto out; } @@ -1554,7 +1761,12 @@ max_depth = 1; if (qdepth > max_depth) qdepth = max_depth; - return scsi_change_queue_depth(sdev, qdepth); + scsi_change_queue_depth(sdev, qdepth); + sdev_printk(KERN_INFO, sdev, + "qdepth(%d), tagged(%d), scsi_level(%d), cmd_que(%d)\n", + sdev->queue_depth, sdev->tagged_supported, + sdev->scsi_level, ((sdev->inquiry[7] & 2) >> 1)); + return sdev->queue_depth; } /** @@ -1629,6 +1841,7 @@ if (pcie_device) { sas_target_priv_data->handle = pcie_device->handle; sas_target_priv_data->sas_address = pcie_device->wwid; + sas_target_priv_data->port = NULL; sas_target_priv_data->pcie_dev = pcie_device; pcie_device->starget = starget; pcie_device->id = starget->id; @@ -1646,12 +1859,12 @@ /* sas/sata devices */ spin_lock_irqsave(&ioc->sas_device_lock, flags); rphy = dev_to_rphy(starget->dev.parent); - sas_device = __mpt3sas_get_sdev_by_addr(ioc, - rphy->identify.sas_address); + sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); if (sas_device) { sas_target_priv_data->handle = sas_device->handle; sas_target_priv_data->sas_address = sas_device->sas_address; + sas_target_priv_data->port = sas_device->port; sas_target_priv_data->sas_dev = sas_device; sas_device->starget = starget; sas_device->id = starget->id; @@ -1807,7 +2020,8 @@ } else if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = __mpt3sas_get_sdev_by_addr(ioc, - sas_target_priv_data->sas_address); + sas_target_priv_data->sas_address, + sas_target_priv_data->port); if (sas_device && (sas_device->starget == NULL)) { sdev_printk(KERN_INFO, sdev, "%s : sas_device->starget set to starget @ %d\n", @@ -2412,7 +2626,8 @@ spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = __mpt3sas_get_sdev_by_addr(ioc, - sas_device_priv_data->sas_target->sas_address); + sas_device_priv_data->sas_target->sas_address, + sas_device_priv_data->sas_target->port); if (!sas_device) { spin_unlock_irqrestore(&ioc->sas_device_lock, flags); dfailprintk(ioc, @@ -2673,6 +2888,7 @@ u16 smid = 0; u32 ioc_state; int rc; + u8 issue_reset = 0; lockdep_assert_held(&ioc->tm_cmds.mutex); @@ -2695,7 +2911,13 @@ } if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { - mpt3sas_base_fault_info(ioc, ioc_state & + mpt3sas_print_fault_code(ioc, ioc_state & + MPI2_DOORBELL_DATA_MASK); + rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); + return (!rc) ? SUCCESS : FAILED; + } else if ((ioc_state & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + mpt3sas_print_coredump_info(ioc, ioc_state & MPI2_DOORBELL_DATA_MASK); rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); return (!rc) ? SUCCESS : FAILED; @@ -2726,9 +2948,10 @@ ioc->put_smid_hi_priority(ioc, smid, msix_task); wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { - if (mpt3sas_base_check_cmd_timeout(ioc, - ioc->tm_cmds.status, mpi_request, - sizeof(Mpi2SCSITaskManagementRequest_t)/4)) { + mpt3sas_check_cmd_timeout(ioc, + ioc->tm_cmds.status, mpi_request, + sizeof(Mpi2SCSITaskManagementRequest_t)/4, issue_reset); + if (issue_reset) { rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); rc = (!rc) ? SUCCESS : FAILED; @@ -2875,15 +3098,17 @@ u8 timeout = 30; struct _pcie_device *pcie_device = NULL; - sdev_printk(KERN_INFO, scmd->device, - "attempting task abort! scmd(%p)\n", scmd); + sdev_printk(KERN_INFO, scmd->device, "attempting task abort!" + "scmd(0x%p), outstanding for %u ms & timeout %u ms\n", + scmd, jiffies_to_msecs(jiffies - scmd->jiffies_at_alloc), + (scmd->request->timeout / HZ) * 1000); _scsih_tm_display_info(ioc, scmd); sas_device_priv_data = scmd->device->hostdata; if (!sas_device_priv_data || !sas_device_priv_data->sas_target || ioc->remove_host) { sdev_printk(KERN_INFO, scmd->device, - "device been deleted! scmd(%p)\n", scmd); + "device been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); r = SUCCESS; @@ -2892,6 +3117,8 @@ /* check for completed command */ if (st == NULL || st->cb_idx == 0xFF) { + sdev_printk(KERN_INFO, scmd->device, "No reference found at " + "driver, assuming scmd(0x%p) might have completed\n", scmd); scmd->result = DID_RESET << 16; r = SUCCESS; goto out; @@ -2920,7 +3147,7 @@ if (r == SUCCESS && st->cb_idx != 0xFF) r = FAILED; out: - sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n", + sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(0x%p)\n", ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); if (pcie_device) pcie_device_put(pcie_device); @@ -2949,14 +3176,14 @@ struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; sdev_printk(KERN_INFO, scmd->device, - "attempting device reset! scmd(%p)\n", scmd); + "attempting device reset! scmd(0x%p)\n", scmd); _scsih_tm_display_info(ioc, scmd); sas_device_priv_data = scmd->device->hostdata; if (!sas_device_priv_data || !sas_device_priv_data->sas_target || ioc->remove_host) { sdev_printk(KERN_INFO, scmd->device, - "device been deleted! scmd(%p)\n", scmd); + "device been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); r = SUCCESS; @@ -2996,7 +3223,7 @@ if (r == SUCCESS && atomic_read(&scmd->device->device_busy)) r = FAILED; out: - sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", + sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(0x%p)\n", ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); if (sas_device) @@ -3027,15 +3254,15 @@ struct scsi_target *starget = scmd->device->sdev_target; struct MPT3SAS_TARGET *target_priv_data = starget->hostdata; - starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n", - scmd); + starget_printk(KERN_INFO, starget, + "attempting target reset! scmd(0x%p)\n", scmd); _scsih_tm_display_info(ioc, scmd); sas_device_priv_data = scmd->device->hostdata; if (!sas_device_priv_data || !sas_device_priv_data->sas_target || ioc->remove_host) { - starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", - scmd); + starget_printk(KERN_INFO, starget, + "target been deleted! scmd(0x%p)\n", scmd); scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); r = SUCCESS; @@ -3074,7 +3301,7 @@ if (r == SUCCESS && atomic_read(&starget->target_busy)) r = FAILED; out: - starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", + starget_printk(KERN_INFO, starget, "target reset: %s scmd(0x%p)\n", ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); if (sas_device) @@ -3097,7 +3324,7 @@ struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host); int r, retval; - ioc_info(ioc, "attempting host reset! scmd(%p)\n", scmd); + ioc_info(ioc, "attempting host reset! scmd(0x%p)\n", scmd); scsi_print_command(scmd); if (ioc->is_driver_loading || ioc->remove_host) { @@ -3109,7 +3336,7 @@ retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); r = (retval < 0) ? FAILED : SUCCESS; out: - ioc_info(ioc, "host reset: %s scmd(%p)\n", + ioc_info(ioc, "host reset: %s scmd(0x%p)\n", r == SUCCESS ? "SUCCESS" : "FAILED", scmd); return r; @@ -3238,6 +3465,7 @@ fw_event = list_first_entry(&ioc->fw_event_list, struct fw_event_work, list); list_del_init(&fw_event->list); + fw_event_work_put(fw_event); } spin_unlock_irqrestore(&ioc->fw_event_lock, flags); @@ -3272,7 +3500,6 @@ if (cancel_work_sync(&fw_event->work)) fw_event_work_put(fw_event); - fw_event_work_put(fw_event); } } @@ -3376,22 +3603,26 @@ * _scsih_ublock_io_device - prepare device to be deleted * @ioc: per adapter object * @sas_address: sas address + * @port: hba port entry * * unblock then put device in offline state */ static void -_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) +_scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, + u64 sas_address, struct hba_port *port) { struct MPT3SAS_DEVICE *sas_device_priv_data; struct scsi_device *sdev; shost_for_each_device(sdev, ioc->shost) { sas_device_priv_data = sdev->hostdata; - if (!sas_device_priv_data) + if (!sas_device_priv_data || !sas_device_priv_data->sas_target) continue; if (sas_device_priv_data->sas_target->sas_address != sas_address) continue; + if (sas_device_priv_data->sas_target->port != port) + continue; if (sas_device_priv_data->block) _scsih_internal_device_unblock(sdev, sas_device_priv_data); @@ -3492,7 +3723,8 @@ SAS_END_DEVICE) { spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_device = __mpt3sas_get_sdev_by_addr(ioc, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); if (sas_device) { set_bit(sas_device->handle, ioc->blocking_handles); @@ -3511,7 +3743,8 @@ SAS_FANOUT_EXPANDER_DEVICE) { expander_sibling = mpt3sas_scsih_expander_find_by_sas_address( - ioc, mpt3sas_port->remote_identify.sas_address); + ioc, mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); _scsih_block_io_to_children_attached_to_ex(ioc, expander_sibling); } @@ -3600,6 +3833,7 @@ struct _tr_list *delayed_tr; u32 ioc_state; u8 tr_method = 0; + struct hba_port *port = NULL; if (ioc->pci_error_recovery) { dewtprintk(ioc, @@ -3628,6 +3862,7 @@ sas_target_priv_data = sas_device->starget->hostdata; sas_target_priv_data->deleted = 1; sas_address = sas_device->sas_address; + port = sas_device->port; } spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (!sas_device) { @@ -3675,7 +3910,7 @@ pcie_device->enclosure_level, pcie_device->connector_name)); } - _scsih_ublock_io_device(ioc, sas_address); + _scsih_ublock_io_device(ioc, sas_address, port); sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; } @@ -4475,6 +4710,7 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc, Mpi2EventDataTemperature_t *event_data) { + u32 doorbell; if (ioc->temp_sensors_count >= event_data->SensorNum) { ioc_err(ioc, "Temperature Threshold flags %s%s%s%s exceeded for Sensor: %d !!!\n", le16_to_cpu(event_data->Status) & 0x1 ? "0 " : " ", @@ -4484,6 +4720,18 @@ event_data->SensorNum); ioc_err(ioc, "Current Temp In Celsius: %d\n", event_data->CurrentTemperature); + if (ioc->hba_mpi_version_belonged != MPI2_VERSION) { + doorbell = mpt3sas_base_get_iocstate(ioc, 0); + if ((doorbell & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_FAULT) { + mpt3sas_print_fault_code(ioc, + doorbell & MPI2_DOORBELL_DATA_MASK); + } else if ((doorbell & MPI2_IOC_STATE_MASK) == + MPI2_IOC_STATE_COREDUMP) { + mpt3sas_print_coredump_info(ioc, + doorbell & MPI2_DOORBELL_DATA_MASK); + } + } } } @@ -5161,7 +5409,7 @@ /* insert into event log */ sz = offsetof(Mpi2EventNotificationReply_t, EventData) + sizeof(Mpi2EventDataSasDeviceStatusChange_t); - event_reply = kzalloc(sz, GFP_KERNEL); + event_reply = kzalloc(sz, GFP_ATOMIC); if (!event_reply) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -5436,6 +5684,616 @@ } /** + * _scsih_update_vphys_after_reset - update the Port's + * vphys_list after reset + * @ioc: per adapter object + * + * Returns nothing. + */ +static void +_scsih_update_vphys_after_reset(struct MPT3SAS_ADAPTER *ioc) +{ + u16 sz, ioc_status; + int i; + Mpi2ConfigReply_t mpi_reply; + Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; + u16 attached_handle; + u64 attached_sas_addr; + u8 found = 0, port_id; + Mpi2SasPhyPage0_t phy_pg0; + struct hba_port *port, *port_next, *mport; + struct virtual_phy *vphy, *vphy_next; + struct _sas_device *sas_device; + + /* + * Mark all the vphys objects as dirty. + */ + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + if (!port->vphys_mask) + continue; + list_for_each_entry_safe(vphy, vphy_next, + &port->vphys_list, list) { + vphy->flags |= MPT_VPHY_FLAG_DIRTY_PHY; + } + } + + /* + * Read SASIOUnitPage0 to get each HBA Phy's data. + */ + sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + + (ioc->sas_hba.num_phys * sizeof(Mpi2SasIOUnit0PhyData_t)); + sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); + if (!sas_iounit_pg0) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + return; + } + if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, + sas_iounit_pg0, sz)) != 0) + goto out; + ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) + goto out; + /* + * Loop over each HBA Phy. + */ + for (i = 0; i < ioc->sas_hba.num_phys; i++) { + /* + * Check whether Phy's Negotiation Link Rate is > 1.5G or not. + */ + if ((sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4) < + MPI2_SAS_NEG_LINK_RATE_1_5) + continue; + /* + * Check whether Phy is connected to SEP device or not, + * if it is SEP device then read the Phy's SASPHYPage0 data to + * determine whether Phy is a virtual Phy or not. if it is + * virtual phy then it is conformed that the attached remote + * device is a HBA's vSES device. + */ + if (!(le32_to_cpu( + sas_iounit_pg0->PhyData[i].ControllerPhyDeviceInfo) & + MPI2_SAS_DEVICE_INFO_SEP)) + continue; + + if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, + i))) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + continue; + } + + if (!(le32_to_cpu(phy_pg0.PhyInfo) & + MPI2_SAS_PHYINFO_VIRTUAL_PHY)) + continue; + /* + * Get the vSES device's SAS Address. + */ + attached_handle = le16_to_cpu( + sas_iounit_pg0->PhyData[i].AttachedDevHandle); + if (_scsih_get_sas_address(ioc, attached_handle, + &attached_sas_addr) != 0) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + continue; + } + + found = 0; + port = port_next = NULL; + /* + * Loop over each virtual_phy object from + * each port's vphys_list. + */ + list_for_each_entry_safe(port, + port_next, &ioc->port_table_list, list) { + if (!port->vphys_mask) + continue; + list_for_each_entry_safe(vphy, vphy_next, + &port->vphys_list, list) { + /* + * Continue with next virtual_phy object + * if the object is not marked as dirty. + */ + if (!(vphy->flags & MPT_VPHY_FLAG_DIRTY_PHY)) + continue; + + /* + * Continue with next virtual_phy object + * if the object's SAS Address is not equals + * to current Phy's vSES device SAS Address. + */ + if (vphy->sas_address != attached_sas_addr) + continue; + /* + * Enable current Phy number bit in object's + * phy_mask field. + */ + if (!(vphy->phy_mask & (1 << i))) + vphy->phy_mask = (1 << i); + /* + * Get hba_port object from hba_port table + * corresponding to current phy's Port ID. + * if there is no hba_port object corresponding + * to Phy's Port ID then create a new hba_port + * object & add to hba_port table. + */ + port_id = sas_iounit_pg0->PhyData[i].Port; + mport = mpt3sas_get_port_by_id(ioc, port_id, 1); + if (!mport) { + mport = kzalloc( + sizeof(struct hba_port), GFP_KERNEL); + if (!mport) + break; + mport->port_id = port_id; + ioc_info(ioc, + "%s: hba_port entry: %p, port: %d is added to hba_port list\n", + __func__, mport, mport->port_id); + list_add_tail(&mport->list, + &ioc->port_table_list); + } + /* + * If mport & port pointers are not pointing to + * same hba_port object then it means that vSES + * device's Port ID got changed after reset and + * hence move current virtual_phy object from + * port's vphys_list to mport's vphys_list. + */ + if (port != mport) { + if (!mport->vphys_mask) + INIT_LIST_HEAD( + &mport->vphys_list); + mport->vphys_mask |= (1 << i); + port->vphys_mask &= ~(1 << i); + list_move(&vphy->list, + &mport->vphys_list); + sas_device = mpt3sas_get_sdev_by_addr( + ioc, attached_sas_addr, port); + if (sas_device) + sas_device->port = mport; + } + /* + * Earlier while updating the hba_port table, + * it is determined that there is no other + * direct attached device with mport's Port ID, + * Hence mport was marked as dirty. Only vSES + * device has this Port ID, so unmark the mport + * as dirt. + */ + if (mport->flags & HBA_PORT_FLAG_DIRTY_PORT) { + mport->sas_address = 0; + mport->phy_mask = 0; + mport->flags &= + ~HBA_PORT_FLAG_DIRTY_PORT; + } + /* + * Unmark current virtual_phy object as dirty. + */ + vphy->flags &= ~MPT_VPHY_FLAG_DIRTY_PHY; + found = 1; + break; + } + if (found) + break; + } + } +out: + kfree(sas_iounit_pg0); +} + +/** + * _scsih_get_port_table_after_reset - Construct temporary port table + * @ioc: per adapter object + * @port_table: address where port table needs to be constructed + * + * return number of HBA port entries available after reset. + */ +static int +_scsih_get_port_table_after_reset(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port_table) +{ + u16 sz, ioc_status; + int i, j; + Mpi2ConfigReply_t mpi_reply; + Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; + u16 attached_handle; + u64 attached_sas_addr; + u8 found = 0, port_count = 0, port_id; + + sz = offsetof(Mpi2SasIOUnitPage0_t, PhyData) + (ioc->sas_hba.num_phys + * sizeof(Mpi2SasIOUnit0PhyData_t)); + sas_iounit_pg0 = kzalloc(sz, GFP_KERNEL); + if (!sas_iounit_pg0) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + return port_count; + } + + if ((mpt3sas_config_get_sas_iounit_pg0(ioc, &mpi_reply, + sas_iounit_pg0, sz)) != 0) + goto out; + ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) + goto out; + for (i = 0; i < ioc->sas_hba.num_phys; i++) { + found = 0; + if ((sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4) < + MPI2_SAS_NEG_LINK_RATE_1_5) + continue; + attached_handle = + le16_to_cpu(sas_iounit_pg0->PhyData[i].AttachedDevHandle); + if (_scsih_get_sas_address( + ioc, attached_handle, &attached_sas_addr) != 0) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + continue; + } + + for (j = 0; j < port_count; j++) { + port_id = sas_iounit_pg0->PhyData[i].Port; + if (port_table[j].port_id == port_id && + port_table[j].sas_address == attached_sas_addr) { + port_table[j].phy_mask |= (1 << i); + found = 1; + break; + } + } + + if (found) + continue; + + port_id = sas_iounit_pg0->PhyData[i].Port; + port_table[port_count].port_id = port_id; + port_table[port_count].phy_mask = (1 << i); + port_table[port_count].sas_address = attached_sas_addr; + port_count++; + } +out: + kfree(sas_iounit_pg0); + return port_count; +} + +enum hba_port_matched_codes { + NOT_MATCHED = 0, + MATCHED_WITH_ADDR_AND_PHYMASK, + MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT, + MATCHED_WITH_ADDR_AND_SUBPHYMASK, + MATCHED_WITH_ADDR, +}; + +/** + * _scsih_look_and_get_matched_port_entry - Get matched hba port entry + * from HBA port table + * @ioc: per adapter object + * @port_entry - hba port entry from temporary port table which needs to be + * searched for matched entry in the HBA port table + * @matched_port_entry - save matched hba port entry here + * @count - count of matched entries + * + * return type of matched entry found. + */ +static enum hba_port_matched_codes +_scsih_look_and_get_matched_port_entry(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port_entry, + struct hba_port **matched_port_entry, int *count) +{ + struct hba_port *port_table_entry, *matched_port = NULL; + enum hba_port_matched_codes matched_code = NOT_MATCHED; + int lcount = 0; + *matched_port_entry = NULL; + + list_for_each_entry(port_table_entry, &ioc->port_table_list, list) { + if (!(port_table_entry->flags & HBA_PORT_FLAG_DIRTY_PORT)) + continue; + + if ((port_table_entry->sas_address == port_entry->sas_address) + && (port_table_entry->phy_mask == port_entry->phy_mask)) { + matched_code = MATCHED_WITH_ADDR_AND_PHYMASK; + matched_port = port_table_entry; + break; + } + + if ((port_table_entry->sas_address == port_entry->sas_address) + && (port_table_entry->phy_mask & port_entry->phy_mask) + && (port_table_entry->port_id == port_entry->port_id)) { + matched_code = MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT; + matched_port = port_table_entry; + continue; + } + + if ((port_table_entry->sas_address == port_entry->sas_address) + && (port_table_entry->phy_mask & port_entry->phy_mask)) { + if (matched_code == + MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT) + continue; + matched_code = MATCHED_WITH_ADDR_AND_SUBPHYMASK; + matched_port = port_table_entry; + continue; + } + + if (port_table_entry->sas_address == port_entry->sas_address) { + if (matched_code == + MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT) + continue; + if (matched_code == MATCHED_WITH_ADDR_AND_SUBPHYMASK) + continue; + matched_code = MATCHED_WITH_ADDR; + matched_port = port_table_entry; + lcount++; + } + } + + *matched_port_entry = matched_port; + if (matched_code == MATCHED_WITH_ADDR) + *count = lcount; + return matched_code; +} + +/** + * _scsih_del_phy_part_of_anther_port - remove phy if it + * is a part of anther port + *@ioc: per adapter object + *@port_table: port table after reset + *@index: hba port entry index + *@port_count: number of ports available after host reset + *@offset: HBA phy bit offset + * + */ +static void +_scsih_del_phy_part_of_anther_port(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *port_table, + int index, u8 port_count, int offset) +{ + struct _sas_node *sas_node = &ioc->sas_hba; + u32 i, found = 0; + + for (i = 0; i < port_count; i++) { + if (i == index) + continue; + + if (port_table[i].phy_mask & (1 << offset)) { + mpt3sas_transport_del_phy_from_an_existing_port( + ioc, sas_node, &sas_node->phy[offset]); + found = 1; + break; + } + } + if (!found) + port_table[index].phy_mask |= (1 << offset); +} + +/** + * _scsih_add_or_del_phys_from_existing_port - add/remove phy to/from + * right port + *@ioc: per adapter object + *@hba_port_entry: hba port table entry + *@port_table: temporary port table + *@index: hba port entry index + *@port_count: number of ports available after host reset + * + */ +static void +_scsih_add_or_del_phys_from_existing_port(struct MPT3SAS_ADAPTER *ioc, + struct hba_port *hba_port_entry, struct hba_port *port_table, + int index, int port_count) +{ + u32 phy_mask, offset = 0; + struct _sas_node *sas_node = &ioc->sas_hba; + + phy_mask = hba_port_entry->phy_mask ^ port_table[index].phy_mask; + + for (offset = 0; offset < ioc->sas_hba.num_phys; offset++) { + if (phy_mask & (1 << offset)) { + if (!(port_table[index].phy_mask & (1 << offset))) { + _scsih_del_phy_part_of_anther_port( + ioc, port_table, index, port_count, + offset); + continue; + } + if (sas_node->phy[offset].phy_belongs_to_port) + mpt3sas_transport_del_phy_from_an_existing_port( + ioc, sas_node, &sas_node->phy[offset]); + mpt3sas_transport_add_phy_to_an_existing_port( + ioc, sas_node, &sas_node->phy[offset], + hba_port_entry->sas_address, + hba_port_entry); + } + } +} + +/** + * _scsih_del_dirty_vphy - delete virtual_phy objects marked as dirty. + * @ioc: per adapter object + * + * Returns nothing. + */ +static void +_scsih_del_dirty_vphy(struct MPT3SAS_ADAPTER *ioc) +{ + struct hba_port *port, *port_next; + struct virtual_phy *vphy, *vphy_next; + + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + if (!port->vphys_mask) + continue; + list_for_each_entry_safe(vphy, vphy_next, + &port->vphys_list, list) { + if (vphy->flags & MPT_VPHY_FLAG_DIRTY_PHY) { + drsprintk(ioc, ioc_info(ioc, + "Deleting vphy %p entry from port id: %d\t, Phy_mask 0x%08x\n", + vphy, port->port_id, + vphy->phy_mask)); + port->vphys_mask &= ~vphy->phy_mask; + list_del(&vphy->list); + kfree(vphy); + } + } + if (!port->vphys_mask && !port->sas_address) + port->flags |= HBA_PORT_FLAG_DIRTY_PORT; + } +} + +/** + * _scsih_del_dirty_port_entries - delete dirty port entries from port list + * after host reset + *@ioc: per adapter object + * + */ +static void +_scsih_del_dirty_port_entries(struct MPT3SAS_ADAPTER *ioc) +{ + struct hba_port *port, *port_next; + + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + if (!(port->flags & HBA_PORT_FLAG_DIRTY_PORT) || + port->flags & HBA_PORT_FLAG_NEW_PORT) + continue; + + drsprintk(ioc, ioc_info(ioc, + "Deleting port table entry %p having Port: %d\t Phy_mask 0x%08x\n", + port, port->port_id, port->phy_mask)); + list_del(&port->list); + kfree(port); + } +} + +/** + * _scsih_sas_port_refresh - Update HBA port table after host reset + * @ioc: per adapter object + */ +static void +_scsih_sas_port_refresh(struct MPT3SAS_ADAPTER *ioc) +{ + u32 port_count = 0; + struct hba_port *port_table; + struct hba_port *port_table_entry; + struct hba_port *port_entry = NULL; + int i, j, count = 0, lcount = 0; + int ret; + u64 sas_addr; + + drsprintk(ioc, ioc_info(ioc, + "updating ports for sas_host(0x%016llx)\n", + (unsigned long long)ioc->sas_hba.sas_address)); + + port_table = kcalloc(ioc->sas_hba.num_phys, + sizeof(struct hba_port), GFP_KERNEL); + if (!port_table) + return; + + port_count = _scsih_get_port_table_after_reset(ioc, port_table); + if (!port_count) + return; + + drsprintk(ioc, ioc_info(ioc, "New Port table\n")); + for (j = 0; j < port_count; j++) + drsprintk(ioc, ioc_info(ioc, + "Port: %d\t Phy_mask 0x%08x\t sas_addr(0x%016llx)\n", + port_table[j].port_id, + port_table[j].phy_mask, port_table[j].sas_address)); + + list_for_each_entry(port_table_entry, &ioc->port_table_list, list) + port_table_entry->flags |= HBA_PORT_FLAG_DIRTY_PORT; + + drsprintk(ioc, ioc_info(ioc, "Old Port table\n")); + port_table_entry = NULL; + list_for_each_entry(port_table_entry, &ioc->port_table_list, list) { + drsprintk(ioc, ioc_info(ioc, + "Port: %d\t Phy_mask 0x%08x\t sas_addr(0x%016llx)\n", + port_table_entry->port_id, + port_table_entry->phy_mask, + port_table_entry->sas_address)); + } + + for (j = 0; j < port_count; j++) { + ret = _scsih_look_and_get_matched_port_entry(ioc, + &port_table[j], &port_entry, &count); + if (!port_entry) { + drsprintk(ioc, ioc_info(ioc, + "No Matched entry for sas_addr(0x%16llx), Port:%d\n", + port_table[j].sas_address, + port_table[j].port_id)); + continue; + } + + switch (ret) { + case MATCHED_WITH_ADDR_SUBPHYMASK_AND_PORT: + case MATCHED_WITH_ADDR_AND_SUBPHYMASK: + _scsih_add_or_del_phys_from_existing_port(ioc, + port_entry, port_table, j, port_count); + break; + case MATCHED_WITH_ADDR: + sas_addr = port_table[j].sas_address; + for (i = 0; i < port_count; i++) { + if (port_table[i].sas_address == sas_addr) + lcount++; + } + + if (count > 1 || lcount > 1) + port_entry = NULL; + else + _scsih_add_or_del_phys_from_existing_port(ioc, + port_entry, port_table, j, port_count); + } + + if (!port_entry) + continue; + + if (port_entry->port_id != port_table[j].port_id) + port_entry->port_id = port_table[j].port_id; + port_entry->flags &= ~HBA_PORT_FLAG_DIRTY_PORT; + port_entry->phy_mask = port_table[j].phy_mask; + } + + port_table_entry = NULL; +} + +/** + * _scsih_alloc_vphy - allocate virtual_phy object + * @ioc: per adapter object + * @port_id: Port ID number + * @phy_num: HBA Phy number + * + * Returns allocated virtual_phy object. + */ +static struct virtual_phy * +_scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) +{ + struct virtual_phy *vphy; + struct hba_port *port; + + port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!port) + return NULL; + + vphy = mpt3sas_get_vphy_by_phy(ioc, port, phy_num); + if (!vphy) { + vphy = kzalloc(sizeof(struct virtual_phy), GFP_KERNEL); + if (!vphy) + return NULL; + + if (!port->vphys_mask) + INIT_LIST_HEAD(&port->vphys_list); + + /* + * Enable bit corresponding to HBA phy number on its + * parent hba_port object's vphys_mask field. + */ + port->vphys_mask |= (1 << phy_num); + vphy->phy_mask |= (1 << phy_num); + + list_add_tail(&vphy->list, &port->vphys_list); + + ioc_info(ioc, + "vphy entry: %p, port id: %d, phy:%d is added to port's vphys_list\n", + vphy, port->port_id, phy_num); + } + return vphy; +} + +/** * _scsih_sas_host_refresh - refreshing sas host object contents * @ioc: per adapter object * Context: user @@ -5453,7 +6311,9 @@ Mpi2ConfigReply_t mpi_reply; Mpi2SasIOUnitPage0_t *sas_iounit_pg0 = NULL; u16 attached_handle; - u8 link_rate; + u8 link_rate, port_id; + struct hba_port *port; + Mpi2SasPhyPage0_t phy_pg0; dtmprintk(ioc, ioc_info(ioc, "updating handles for sas_host(0x%016llx)\n", @@ -5477,15 +6337,57 @@ for (i = 0; i < ioc->sas_hba.num_phys ; i++) { link_rate = sas_iounit_pg0->PhyData[i].NegotiatedLinkRate >> 4; if (i == 0) - ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> - PhyData[0].ControllerDevHandle); + ioc->sas_hba.handle = le16_to_cpu( + sas_iounit_pg0->PhyData[0].ControllerDevHandle); + port_id = sas_iounit_pg0->PhyData[i].Port; + if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { + port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + if (!port) + goto out; + + port->port_id = port_id; + ioc_info(ioc, + "hba_port entry: %p, port: %d is added to hba_port list\n", + port, port->port_id); + if (ioc->shost_recovery) + port->flags = HBA_PORT_FLAG_NEW_PORT; + list_add_tail(&port->list, &ioc->port_table_list); + } + /* + * Check whether current Phy belongs to HBA vSES device or not. + */ + if (le32_to_cpu(sas_iounit_pg0->PhyData[i].ControllerPhyDeviceInfo) & + MPI2_SAS_DEVICE_INFO_SEP && + (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { + if ((mpt3sas_config_get_phy_pg0(ioc, &mpi_reply, + &phy_pg0, i))) { + ioc_err(ioc, + "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out; + } + if (!(le32_to_cpu(phy_pg0.PhyInfo) & + MPI2_SAS_PHYINFO_VIRTUAL_PHY)) + continue; + /* + * Allocate a virtual_phy object for vSES device, if + * this vSES device is hot added. + */ + if (!_scsih_alloc_vphy(ioc, port_id, i)) + goto out; + ioc->sas_hba.phy[i].hba_vphy = 1; + } + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; attached_handle = le16_to_cpu(sas_iounit_pg0->PhyData[i]. AttachedDevHandle); if (attached_handle && link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) link_rate = MPI2_SAS_NEG_LINK_RATE_1_5; + ioc->sas_hba.phy[i].port = + mpt3sas_get_port_by_id(ioc, port_id, 0); mpt3sas_transport_update_links(ioc, ioc->sas_hba.sas_address, - attached_handle, i, link_rate); + attached_handle, i, link_rate, + ioc->sas_hba.phy[i].port); } out: kfree(sas_iounit_pg0); @@ -5510,7 +6412,8 @@ u16 ioc_status; u16 sz; u8 device_missing_delay; - u8 num_phys; + u8 num_phys, port_id; + struct hba_port *port; mpt3sas_config_get_number_hba_phys(ioc, &num_phys); if (!num_phys) { @@ -5603,8 +6506,40 @@ if (i == 0) ioc->sas_hba.handle = le16_to_cpu(sas_iounit_pg0-> PhyData[0].ControllerDevHandle); + + port_id = sas_iounit_pg0->PhyData[i].Port; + if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { + port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + if (!port) + goto out; + + port->port_id = port_id; + ioc_info(ioc, + "hba_port entry: %p, port: %d is added to hba_port list\n", + port, port->port_id); + list_add_tail(&port->list, + &ioc->port_table_list); + } + + /* + * Check whether current Phy belongs to HBA vSES device or not. + */ + if ((le32_to_cpu(phy_pg0.PhyInfo) & + MPI2_SAS_PHYINFO_VIRTUAL_PHY) && + (phy_pg0.NegotiatedLinkRate >> 4) >= + MPI2_SAS_NEG_LINK_RATE_1_5) { + /* + * Allocate a virtual_phy object for vSES device. + */ + if (!_scsih_alloc_vphy(ioc, port_id, i)) + goto out; + ioc->sas_hba.phy[i].hba_vphy = 1; + } + ioc->sas_hba.phy[i].handle = ioc->sas_hba.handle; ioc->sas_hba.phy[i].phy_id = i; + ioc->sas_hba.phy[i].port = + mpt3sas_get_port_by_id(ioc, port_id, 0); mpt3sas_transport_add_host_phy(ioc, &ioc->sas_hba.phy[i], phy_pg0, ioc->sas_hba.parent_dev); } @@ -5658,6 +6593,7 @@ int i; unsigned long flags; struct _sas_port *mpt3sas_port = NULL; + u8 port_id; int rc = 0; @@ -5690,10 +6626,13 @@ __FILE__, __LINE__, __func__); return -1; } + + port_id = expander_pg0.PhysicalPort; if (sas_address_parent != ioc->sas_hba.sas_address) { spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc, - sas_address_parent); + sas_address_parent, + mpt3sas_get_port_by_id(ioc, port_id, 0)); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (!sas_expander) { rc = _scsih_expander_add(ioc, parent_handle); @@ -5705,7 +6644,7 @@ spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_address = le64_to_cpu(expander_pg0.SASAddress); sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc, - sas_address); + sas_address, mpt3sas_get_port_by_id(ioc, port_id, 0)); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (sas_expander) @@ -5723,13 +6662,22 @@ sas_expander->num_phys = expander_pg0.NumPhys; sas_expander->sas_address_parent = sas_address_parent; sas_expander->sas_address = sas_address; + sas_expander->port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!sas_expander->port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + rc = -1; + goto out_fail; + } ioc_info(ioc, "expander_add: handle(0x%04x), parent(0x%04x), sas_addr(0x%016llx), phys(%d)\n", handle, parent_handle, (u64)sas_expander->sas_address, sas_expander->num_phys); - if (!sas_expander->num_phys) + if (!sas_expander->num_phys) { + rc = -1; goto out_fail; + } sas_expander->phy = kcalloc(sas_expander->num_phys, sizeof(struct _sas_phy), GFP_KERNEL); if (!sas_expander->phy) { @@ -5741,7 +6689,7 @@ INIT_LIST_HEAD(&sas_expander->sas_port_list); mpt3sas_port = mpt3sas_transport_port_add(ioc, handle, - sas_address_parent); + sas_address_parent, sas_expander->port); if (!mpt3sas_port) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -5749,6 +6697,7 @@ goto out_fail; } sas_expander->parent_dev = &mpt3sas_port->rphy->dev; + sas_expander->rphy = mpt3sas_port->rphy; for (i = 0 ; i < sas_expander->num_phys ; i++) { if ((mpt3sas_config_get_expander_pg1(ioc, &mpi_reply, @@ -5760,6 +6709,8 @@ } sas_expander->phy[i].handle = handle; sas_expander->phy[i].phy_id = i; + sas_expander->phy[i].port = + mpt3sas_get_port_by_id(ioc, port_id, 0); if ((mpt3sas_transport_add_expander_phy(ioc, &sas_expander->phy[i], expander_pg1, @@ -5787,7 +6738,7 @@ if (mpt3sas_port) mpt3sas_transport_port_remove(ioc, sas_expander->sas_address, - sas_address_parent); + sas_address_parent, sas_expander->port); kfree(sas_expander); return rc; } @@ -5798,7 +6749,8 @@ * @sas_address: expander sas_address */ void -mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) +mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, + struct hba_port *port) { struct _sas_node *sas_expander; unsigned long flags; @@ -5806,9 +6758,12 @@ if (ioc->shost_recovery) return; + if (!port) + return; + spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_expander = mpt3sas_scsih_expander_find_by_sas_address(ioc, - sas_address); + sas_address, port); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (sas_expander) _scsih_expander_node_remove(ioc, sas_expander); @@ -5931,7 +6886,7 @@ { Mpi2ConfigReply_t mpi_reply; Mpi2SasDevicePage0_t sas_device_pg0; - struct _sas_device *sas_device; + struct _sas_device *sas_device = NULL; struct _enclosure_node *enclosure_dev = NULL; u32 ioc_status; unsigned long flags; @@ -5939,6 +6894,7 @@ struct scsi_target *starget; struct MPT3SAS_TARGET *sas_target_priv_data; u32 device_info; + struct hba_port *port; if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) @@ -5961,8 +6917,11 @@ spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_address = le64_to_cpu(sas_device_pg0.SASAddress); + port = mpt3sas_get_port_by_id(ioc, sas_device_pg0.PhysicalPort, 0); + if (!port) + goto out_unlock; sas_device = __mpt3sas_get_sdev_by_addr(ioc, - sas_address); + sas_address, port); if (!sas_device) goto out_unlock; @@ -6018,7 +6977,7 @@ goto out_unlock; spin_unlock_irqrestore(&ioc->sas_device_lock, flags); - _scsih_ublock_io_device(ioc, sas_address); + _scsih_ublock_io_device(ioc, sas_address, port); if (sas_device) sas_device_put(sas_device); @@ -6052,6 +7011,7 @@ u32 ioc_status; u64 sas_address; u32 device_info; + u8 port_id; if ((mpt3sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { @@ -6088,8 +7048,9 @@ sas_device_pg0.AccessStatus)) return -1; + port_id = sas_device_pg0.PhysicalPort; sas_device = mpt3sas_get_sdev_by_addr(ioc, - sas_address); + sas_address, mpt3sas_get_port_by_id(ioc, port_id, 0)); if (sas_device) { clear_bit(handle, ioc->pend_os_device_add); sas_device_put(sas_device); @@ -6130,6 +7091,12 @@ sas_device->phy = sas_device_pg0.PhyNum; sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; + sas_device->port = mpt3sas_get_port_by_id(ioc, port_id, 0); + if (!sas_device->port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out; + } if (le16_to_cpu(sas_device_pg0.Flags) & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { @@ -6163,6 +7130,7 @@ else _scsih_sas_device_add(ioc, sas_device); +out: sas_device_put(sas_device); return 0; } @@ -6195,7 +7163,8 @@ if (sas_device->starget && sas_device->starget->hostdata) { sas_target_priv_data = sas_device->starget->hostdata; sas_target_priv_data->deleted = 1; - _scsih_ublock_io_device(ioc, sas_device->sas_address); + _scsih_ublock_io_device(ioc, sas_device->sas_address, + sas_device->port); sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; } @@ -6203,7 +7172,8 @@ if (!ioc->hide_drives) mpt3sas_transport_port_remove(ioc, sas_device->sas_address, - sas_device->sas_address_parent); + sas_device->sas_address_parent, + sas_device->port); ioc_info(ioc, "removing handle(0x%04x), sas_addr(0x%016llx)\n", sas_device->handle, (u64)sas_device->sas_address); @@ -6314,6 +7284,7 @@ u64 sas_address; unsigned long flags; u8 link_rate, prev_link_rate; + struct hba_port *port; Mpi2EventDataSasTopologyChangeList_t *event_data = (Mpi2EventDataSasTopologyChangeList_t *) fw_event->event_data; @@ -6335,6 +7306,7 @@ } parent_handle = le16_to_cpu(event_data->ExpanderDevHandle); + port = mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort, 0); /* handle expander add */ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) @@ -6347,6 +7319,7 @@ if (sas_expander) { sas_address = sas_expander->sas_address; max_phys = sas_expander->num_phys; + port = sas_expander->port; } else if (parent_handle < ioc->sas_hba.num_phys) { sas_address = ioc->sas_hba.sas_address; max_phys = ioc->sas_hba.num_phys; @@ -6389,7 +7362,7 @@ break; mpt3sas_transport_update_links(ioc, sas_address, - handle, phy_number, link_rate); + handle, phy_number, link_rate, port); if (link_rate < MPI2_SAS_NEG_LINK_RATE_1_5) break; @@ -6408,7 +7381,7 @@ break; mpt3sas_transport_update_links(ioc, sas_address, - handle, phy_number, link_rate); + handle, phy_number, link_rate, port); _scsih_add_device(ioc, handle, phy_number, 0); @@ -6423,7 +7396,7 @@ /* handle expander removal */ if (event_data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING && sas_expander) - mpt3sas_expander_remove(ioc, sas_address); + mpt3sas_expander_remove(ioc, sas_address, port); return 0; } @@ -6524,7 +7497,8 @@ spin_lock_irqsave(&ioc->sas_device_lock, flags); sas_address = le64_to_cpu(event_data->SASAddress); sas_device = __mpt3sas_get_sdev_by_addr(ioc, - sas_address); + sas_address, + mpt3sas_get_port_by_id(ioc, event_data->PhysicalPort, 0)); if (!sas_device || !sas_device->starget) goto out; @@ -6673,7 +7647,7 @@ if (pcie_device->starget && pcie_device->starget->hostdata) { sas_target_priv_data = pcie_device->starget->hostdata; sas_target_priv_data->deleted = 1; - _scsih_ublock_io_device(ioc, pcie_device->wwid); + _scsih_ublock_io_device(ioc, pcie_device->wwid, NULL); sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; } @@ -6795,7 +7769,7 @@ spin_unlock_irqrestore(&ioc->pcie_device_lock, flags); pcie_device_put(pcie_device); - _scsih_ublock_io_device(ioc, wwid); + _scsih_ublock_io_device(ioc, wwid, NULL); return; } @@ -6933,6 +7907,16 @@ le32_to_cpu(pcie_device_pg0.DeviceInfo)))) { pcie_device->nvme_mdts = le32_to_cpu(pcie_device_pg2.MaximumDataTransferSize); + pcie_device->shutdown_latency = + le16_to_cpu(pcie_device_pg2.ShutdownLatency); + /* + * Set IOC's max_shutdown_latency to drive's RTD3 Entry Latency + * if drive's RTD3 Entry Latency is greater then IOC's + * max_shutdown_latency. + */ + if (pcie_device->shutdown_latency > ioc->max_shutdown_latency) + ioc->max_shutdown_latency = + pcie_device->shutdown_latency; if (pcie_device_pg2.ControllerResetTO) pcie_device->reset_timeout = pcie_device_pg2.ControllerResetTO; @@ -7669,10 +8653,9 @@ wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { - issue_reset = - mpt3sas_base_check_cmd_timeout(ioc, - ioc->scsih_cmds.status, mpi_request, - sizeof(Mpi2RaidActionRequest_t)/4); + mpt3sas_check_cmd_timeout(ioc, + ioc->scsih_cmds.status, mpi_request, + sizeof(Mpi2RaidActionRequest_t)/4, issue_reset); rc = -EFAULT; goto out; } @@ -7955,7 +8938,9 @@ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) mpt3sas_transport_update_links(ioc, sas_address, handle, - sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, + mpt3sas_get_port_by_id(ioc, + sas_device_pg0.PhysicalPort, 0)); _scsih_ir_fastpath(ioc, handle, element->PhysDiskNum); _scsih_add_device(ioc, handle, 0, 1); @@ -8261,7 +9246,9 @@ parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) mpt3sas_transport_update_links(ioc, sas_address, handle, - sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, + mpt3sas_get_port_by_id(ioc, + sas_device_pg0.PhysicalPort, 0)); _scsih_add_device(ioc, handle, 0, 1); @@ -8386,6 +9373,8 @@ struct _sas_device *sas_device = NULL; struct _enclosure_node *enclosure_dev = NULL; unsigned long flags; + struct hba_port *port = mpt3sas_get_port_by_id( + ioc, sas_device_pg0->PhysicalPort, 0); if (sas_device_pg0->EnclosureHandle) { enclosure_dev = @@ -8397,69 +9386,71 @@ } spin_lock_irqsave(&ioc->sas_device_lock, flags); list_for_each_entry(sas_device, &ioc->sas_device_list, list) { - if ((sas_device->sas_address == le64_to_cpu( - sas_device_pg0->SASAddress)) && (sas_device->slot == - le16_to_cpu(sas_device_pg0->Slot))) { - sas_device->responding = 1; - starget = sas_device->starget; - if (starget && starget->hostdata) { - sas_target_priv_data = starget->hostdata; - sas_target_priv_data->tm_busy = 0; - sas_target_priv_data->deleted = 0; - } else - sas_target_priv_data = NULL; - if (starget) { - starget_printk(KERN_INFO, starget, - "handle(0x%04x), sas_addr(0x%016llx)\n", - le16_to_cpu(sas_device_pg0->DevHandle), - (unsigned long long) - sas_device->sas_address); + if (sas_device->sas_address != le64_to_cpu( + sas_device_pg0->SASAddress)) + continue; + if (sas_device->slot != le16_to_cpu(sas_device_pg0->Slot)) + continue; + if (sas_device->port != port) + continue; + sas_device->responding = 1; + starget = sas_device->starget; + if (starget && starget->hostdata) { + sas_target_priv_data = starget->hostdata; + sas_target_priv_data->tm_busy = 0; + sas_target_priv_data->deleted = 0; + } else + sas_target_priv_data = NULL; + if (starget) { + starget_printk(KERN_INFO, starget, + "handle(0x%04x), sas_addr(0x%016llx)\n", + le16_to_cpu(sas_device_pg0->DevHandle), + (unsigned long long) + sas_device->sas_address); - if (sas_device->enclosure_handle != 0) - starget_printk(KERN_INFO, starget, - "enclosure logical id(0x%016llx)," - " slot(%d)\n", - (unsigned long long) - sas_device->enclosure_logical_id, - sas_device->slot); - } - if (le16_to_cpu(sas_device_pg0->Flags) & - MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { - sas_device->enclosure_level = - sas_device_pg0->EnclosureLevel; - memcpy(&sas_device->connector_name[0], - &sas_device_pg0->ConnectorName[0], 4); - } else { - sas_device->enclosure_level = 0; - sas_device->connector_name[0] = '\0'; - } + if (sas_device->enclosure_handle != 0) + starget_printk(KERN_INFO, starget, + "enclosure logical id(0x%016llx), slot(%d)\n", + (unsigned long long) + sas_device->enclosure_logical_id, + sas_device->slot); + } + if (le16_to_cpu(sas_device_pg0->Flags) & + MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { + sas_device->enclosure_level = + sas_device_pg0->EnclosureLevel; + memcpy(&sas_device->connector_name[0], + &sas_device_pg0->ConnectorName[0], 4); + } else { + sas_device->enclosure_level = 0; + sas_device->connector_name[0] = '\0'; + } - sas_device->enclosure_handle = - le16_to_cpu(sas_device_pg0->EnclosureHandle); - sas_device->is_chassis_slot_valid = 0; - if (enclosure_dev) { - sas_device->enclosure_logical_id = le64_to_cpu( - enclosure_dev->pg0.EnclosureLogicalID); - if (le16_to_cpu(enclosure_dev->pg0.Flags) & - MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID) { - sas_device->is_chassis_slot_valid = 1; - sas_device->chassis_slot = - enclosure_dev->pg0.ChassisSlot; - } + sas_device->enclosure_handle = + le16_to_cpu(sas_device_pg0->EnclosureHandle); + sas_device->is_chassis_slot_valid = 0; + if (enclosure_dev) { + sas_device->enclosure_logical_id = le64_to_cpu( + enclosure_dev->pg0.EnclosureLogicalID); + if (le16_to_cpu(enclosure_dev->pg0.Flags) & + MPI2_SAS_ENCLS0_FLAGS_CHASSIS_SLOT_VALID) { + sas_device->is_chassis_slot_valid = 1; + sas_device->chassis_slot = + enclosure_dev->pg0.ChassisSlot; } + } - if (sas_device->handle == le16_to_cpu( - sas_device_pg0->DevHandle)) - goto out; - pr_info("\thandle changed from(0x%04x)!!!\n", - sas_device->handle); - sas_device->handle = le16_to_cpu( - sas_device_pg0->DevHandle); - if (sas_target_priv_data) - sas_target_priv_data->handle = - le16_to_cpu(sas_device_pg0->DevHandle); + if (sas_device->handle == le16_to_cpu( + sas_device_pg0->DevHandle)) goto out; - } + pr_info("\thandle changed from(0x%04x)!!!\n", + sas_device->handle); + sas_device->handle = le16_to_cpu( + sas_device_pg0->DevHandle); + if (sas_target_priv_data) + sas_target_priv_data->handle = + le16_to_cpu(sas_device_pg0->DevHandle); + goto out; } out: spin_unlock_irqrestore(&ioc->sas_device_lock, flags); @@ -8810,6 +9801,8 @@ u16 handle = le16_to_cpu(expander_pg0->DevHandle); u16 enclosure_handle = le16_to_cpu(expander_pg0->EnclosureHandle); u64 sas_address = le64_to_cpu(expander_pg0->SASAddress); + struct hba_port *port = mpt3sas_get_port_by_id( + ioc, expander_pg0->PhysicalPort, 0); if (enclosure_handle) enclosure_dev = @@ -8820,6 +9813,8 @@ list_for_each_entry(sas_expander, &ioc->sas_expander_list, list) { if (sas_expander->sas_address != sas_address) continue; + if (sas_expander->port != port) + continue; sas_expander->responding = 1; if (enclosure_dev) { @@ -8859,6 +9854,7 @@ u16 ioc_status; u64 sas_address; u16 handle; + u8 port; ioc_info(ioc, "search for expanders: start\n"); @@ -8876,9 +9872,12 @@ handle = le16_to_cpu(expander_pg0.DevHandle); sas_address = le64_to_cpu(expander_pg0.SASAddress); - pr_info("\texpander present: handle(0x%04x), sas_addr(0x%016llx)\n", - handle, - (unsigned long long)sas_address); + port = expander_pg0.PhysicalPort; + pr_info( + "\texpander present: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", + handle, (unsigned long long)sas_address, + (ioc->multipath_on_hba ? + port : MULTIPATH_DISABLED_PORT_ID)); _scsih_mark_responding_expander(ioc, &expander_pg0); } @@ -9000,7 +9999,8 @@ mpt3sas_transport_update_links(ioc, sas_expander->sas_address, le16_to_cpu(expander_pg1.AttachedDevHandle), i, - expander_pg1.NegotiatedLinkRate >> 4); + expander_pg1.NegotiatedLinkRate >> 4, + sas_expander->port); } } @@ -9019,7 +10019,7 @@ Mpi2RaidPhysDiskPage0_t pd_pg0; Mpi2EventIrConfigElement_t element; Mpi2ConfigReply_t mpi_reply; - u8 phys_disk_num; + u8 phys_disk_num, port_id; u16 ioc_status; u16 handle, parent_handle; u64 sas_address; @@ -9049,8 +10049,10 @@ } handle = le16_to_cpu(expander_pg0.DevHandle); spin_lock_irqsave(&ioc->sas_node_lock, flags); + port_id = expander_pg0.PhysicalPort; expander_device = mpt3sas_scsih_expander_find_by_sas_address( - ioc, le64_to_cpu(expander_pg0.SASAddress)); + ioc, le64_to_cpu(expander_pg0.SASAddress), + mpt3sas_get_port_by_id(ioc, port_id, 0)); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (expander_device) _scsih_refresh_expander_links(ioc, expander_device, @@ -9109,9 +10111,11 @@ ioc_info(ioc, "\tBEFORE adding phys disk: handle (0x%04x), sas_addr(0x%016llx)\n", handle, (u64)le64_to_cpu(sas_device_pg0.SASAddress)); + port_id = sas_device_pg0.PhysicalPort; mpt3sas_transport_update_links(ioc, sas_address, handle, sas_device_pg0.PhyNum, - MPI2_SAS_NEG_LINK_RATE_1_5); + MPI2_SAS_NEG_LINK_RATE_1_5, + mpt3sas_get_port_by_id(ioc, port_id, 0)); set_bit(handle, ioc->pd_handles); retry_count = 0; /* This will retry adding the end device. @@ -9197,8 +10201,10 @@ if (!(_scsih_is_end_device( le32_to_cpu(sas_device_pg0.DeviceInfo)))) continue; + port_id = sas_device_pg0.PhysicalPort; sas_device = mpt3sas_get_sdev_by_addr(ioc, - le64_to_cpu(sas_device_pg0.SASAddress)); + le64_to_cpu(sas_device_pg0.SASAddress), + mpt3sas_get_port_by_id(ioc, port_id, 0)); if (sas_device) { sas_device_put(sas_device); continue; @@ -9209,7 +10215,8 @@ handle, (u64)le64_to_cpu(sas_device_pg0.SASAddress)); mpt3sas_transport_update_links(ioc, sas_address, handle, - sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5); + sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5, + mpt3sas_get_port_by_id(ioc, port_id, 0)); retry_count = 0; /* This will retry adding the end device. * _scsih_add_device() will decide on retries and @@ -9272,15 +10279,17 @@ } /** - * mpt3sas_scsih_after_reset_handler - reset callback handler (for scsih) + * mpt3sas_scsih_clear_outstanding_scsi_tm_commands - clears outstanding + * scsi & tm cmds. * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. */ void -mpt3sas_scsih_after_reset_handler(struct MPT3SAS_ADAPTER *ioc) +mpt3sas_scsih_clear_outstanding_scsi_tm_commands(struct MPT3SAS_ADAPTER *ioc) { - dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_AFTER_RESET\n", __func__)); + dtmprintk(ioc, + ioc_info(ioc, "%s: clear outstanding scsi & tm cmds\n", __func__)); if (ioc->scsih_cmds.status & MPT3_CMD_PENDING) { ioc->scsih_cmds.status |= MPT3_CMD_RESET; mpt3sas_base_free_smid(ioc, ioc->scsih_cmds.smid); @@ -9311,6 +10320,10 @@ dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_DONE_RESET\n", __func__)); if ((!ioc->is_driver_loading) && !(disable_discovery > 0 && !ioc->sas_hba.num_phys)) { + if (ioc->multipath_on_hba) { + _scsih_sas_port_refresh(ioc); + _scsih_update_vphys_after_reset(ioc); + } _scsih_prep_device_scan(ioc); _scsih_create_enclosure_list_after_reset(ioc); _scsih_search_responding_sas_devices(ioc); @@ -9356,7 +10369,10 @@ ssleep(1); } _scsih_remove_unresponding_devices(ioc); + _scsih_del_dirty_vphy(ioc); + _scsih_del_dirty_port_entries(ioc); _scsih_scan_for_devices_after_reset(ioc); + _scsih_set_nvme_max_shutdown_latency(ioc); break; case MPT3SAS_PORT_ENABLE_COMPLETE: ioc->start_scan = 0; @@ -9635,21 +10651,25 @@ if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) mpt3sas_device_remove_by_sas_address(ioc, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); else if (mpt3sas_port->remote_identify.device_type == SAS_EDGE_EXPANDER_DEVICE || mpt3sas_port->remote_identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) mpt3sas_expander_remove(ioc, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); } mpt3sas_transport_port_remove(ioc, sas_expander->sas_address, - sas_expander->sas_address_parent); + sas_expander->sas_address_parent, sas_expander->port); - ioc_info(ioc, "expander_remove: handle(0x%04x), sas_addr(0x%016llx)\n", - sas_expander->handle, (unsigned long long) - sas_expander->sas_address); + ioc_info(ioc, + "expander_remove: handle(0x%04x), sas_addr(0x%016llx), port:%d\n", + sas_expander->handle, (unsigned long long) + sas_expander->sas_address, + sas_expander->port->port_id); spin_lock_irqsave(&ioc->sas_node_lock, flags); list_del(&sas_expander->list); @@ -9660,6 +10680,75 @@ } /** + * _scsih_nvme_shutdown - NVMe shutdown notification + * @ioc: per adapter object + * + * Sending IoUnitControl request with shutdown operation code to alert IOC that + * the host system is shutting down so that IOC can issue NVMe shutdown to + * NVMe drives attached to it. + */ +static void +_scsih_nvme_shutdown(struct MPT3SAS_ADAPTER *ioc) +{ + Mpi26IoUnitControlRequest_t *mpi_request; + Mpi26IoUnitControlReply_t *mpi_reply; + u16 smid; + + /* are there any NVMe devices ? */ + if (list_empty(&ioc->pcie_device_list)) + return; + + mutex_lock(&ioc->scsih_cmds.mutex); + + if (ioc->scsih_cmds.status != MPT3_CMD_NOT_USED) { + ioc_err(ioc, "%s: scsih_cmd in use\n", __func__); + goto out; + } + + ioc->scsih_cmds.status = MPT3_CMD_PENDING; + + smid = mpt3sas_base_get_smid(ioc, ioc->scsih_cb_idx); + if (!smid) { + ioc_err(ioc, + "%s: failed obtaining a smid\n", __func__); + ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; + goto out; + } + + mpi_request = mpt3sas_base_get_msg_frame(ioc, smid); + ioc->scsih_cmds.smid = smid; + memset(mpi_request, 0, sizeof(Mpi26IoUnitControlRequest_t)); + mpi_request->Function = MPI2_FUNCTION_IO_UNIT_CONTROL; + mpi_request->Operation = MPI26_CTRL_OP_SHUTDOWN; + + init_completion(&ioc->scsih_cmds.done); + ioc->put_smid_default(ioc, smid); + /* Wait for max_shutdown_latency seconds */ + ioc_info(ioc, + "Io Unit Control shutdown (sending), Shutdown latency %d sec\n", + ioc->max_shutdown_latency); + wait_for_completion_timeout(&ioc->scsih_cmds.done, + ioc->max_shutdown_latency*HZ); + + if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { + ioc_err(ioc, "%s: timeout\n", __func__); + goto out; + } + + if (ioc->scsih_cmds.status & MPT3_CMD_REPLY_VALID) { + mpi_reply = ioc->scsih_cmds.reply; + ioc_info(ioc, "Io Unit Control shutdown (complete):" + "ioc_status(0x%04x), loginfo(0x%08x)\n", + le16_to_cpu(mpi_reply->IOCStatus), + le32_to_cpu(mpi_reply->IOCLogInfo)); + } + out: + ioc->scsih_cmds.status = MPT3_CMD_NOT_USED; + mutex_unlock(&ioc->scsih_cmds.mutex); +} + + +/** * _scsih_ir_shutdown - IR shutdown notification * @ioc: per adapter object * @@ -9744,11 +10833,12 @@ struct workqueue_struct *wq; unsigned long flags; Mpi2ConfigReply_t mpi_reply; + struct hba_port *port, *port_next; ioc->remove_host = 1; - mpt3sas_wait_for_commands_to_complete(ioc); - _scsih_flush_running_cmds(ioc); + if (!pci_device_is_present(pdev)) + _scsih_flush_running_cmds(ioc); _scsih_fw_event_cleanup_queue(ioc); @@ -9793,13 +10883,21 @@ if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) mpt3sas_device_remove_by_sas_address(ioc, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); else if (mpt3sas_port->remote_identify.device_type == SAS_EDGE_EXPANDER_DEVICE || mpt3sas_port->remote_identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) mpt3sas_expander_remove(ioc, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); + } + + list_for_each_entry_safe(port, port_next, + &ioc->port_table_list, list) { + list_del(&port->list); + kfree(port); } /* free phys attached to the sas_host */ @@ -9831,8 +10929,8 @@ ioc->remove_host = 1; - mpt3sas_wait_for_commands_to_complete(ioc); - _scsih_flush_running_cmds(ioc); + if (!pci_device_is_present(pdev)) + _scsih_flush_running_cmds(ioc); _scsih_fw_event_cleanup_queue(ioc); @@ -9851,6 +10949,7 @@ &ioc->ioc_pg1_copy); _scsih_ir_shutdown(ioc); + _scsih_nvme_shutdown(ioc); mpt3sas_base_detach(ioc); } @@ -9877,6 +10976,7 @@ unsigned long flags; int rc; int tid; + struct hba_port *port; /* no Bios, return immediately */ if (!ioc->bios_pg3.BiosVersion) @@ -9918,19 +11018,24 @@ handle = sas_device->handle; sas_address_parent = sas_device->sas_address_parent; sas_address = sas_device->sas_address; + port = sas_device->port; list_move_tail(&sas_device->list, &ioc->sas_device_list); spin_unlock_irqrestore(&ioc->sas_device_lock, flags); if (ioc->hide_drives) return; + + if (!port) + return; + if (!mpt3sas_transport_port_add(ioc, handle, - sas_address_parent)) { + sas_address_parent, port)) { _scsih_sas_device_remove(ioc, sas_device); } else if (!sas_device->starget) { if (!ioc->is_driver_loading) { mpt3sas_transport_port_remove(ioc, sas_address, - sas_address_parent); + sas_address_parent, port); _scsih_sas_device_remove(ioc, sas_device); } } @@ -10018,7 +11123,7 @@ while ((sas_device = get_next_sas_device(ioc))) { if (!mpt3sas_transport_port_add(ioc, sas_device->handle, - sas_device->sas_address_parent)) { + sas_device->sas_address_parent, sas_device->port)) { _scsih_sas_device_remove(ioc, sas_device); sas_device_put(sas_device); continue; @@ -10032,7 +11137,8 @@ if (!ioc->is_driver_loading) { mpt3sas_transport_port_remove(ioc, sas_device->sas_address, - sas_device->sas_address_parent); + sas_device->sas_address_parent, + sas_device->port); _scsih_sas_device_remove(ioc, sas_device); sas_device_put(sas_device); continue; @@ -10193,6 +11299,8 @@ int rc; if (diag_buffer_enable != -1 && diag_buffer_enable != 0) mpt3sas_enable_diag_buffer(ioc, diag_buffer_enable); + else if (ioc->manu_pg11.HostTraceBufferMaxSizeKB != 0) + mpt3sas_enable_diag_buffer(ioc, 1); if (disable_discovery > 0) return; @@ -10460,6 +11568,12 @@ ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; break; } + + if (multipath_on_hba == -1 || multipath_on_hba == 0) + ioc->multipath_on_hba = 0; + else + ioc->multipath_on_hba = 1; + break; case MPI25_VERSION: case MPI26_VERSION: @@ -10507,6 +11621,23 @@ ioc->combined_reply_index_count = MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3; } + + switch (ioc->is_gen35_ioc) { + case 0: + if (multipath_on_hba == -1 || multipath_on_hba == 0) + ioc->multipath_on_hba = 0; + else + ioc->multipath_on_hba = 1; + break; + case 1: + if (multipath_on_hba == -1 || multipath_on_hba > 0) + ioc->multipath_on_hba = 1; + else + ioc->multipath_on_hba = 0; + default: + break; + } + break; default: return -ENODEV; @@ -10531,6 +11662,8 @@ ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; ioc->logging_level = logging_level; ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; + /* Host waits for minimum of six seconds */ + ioc->max_shutdown_latency = IO_UNIT_CONTROL_SHUTDOWN_TIMEOUT; /* * Enable MEMORY MOVE support flag. */ @@ -10565,6 +11698,7 @@ INIT_LIST_HEAD(&ioc->delayed_event_ack_list); INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); INIT_LIST_HEAD(&ioc->reply_queue_list); + INIT_LIST_HEAD(&ioc->port_table_list); sprintf(ioc->name, "%s_cm%d", ioc->driver_name, ioc->id); @@ -10679,6 +11813,7 @@ mpt3sas_base_stop_watchdog(ioc); flush_scheduled_work(); scsi_block_requests(shost); + _scsih_nvme_shutdown(ioc); device_state = pci_choose_state(pdev, state); ioc_info(ioc, "pdev=0x%p, slot=%s, entering operating state [D%d]\n", pdev, pci_name(pdev), device_state); @@ -10713,7 +11848,7 @@ r = mpt3sas_base_map_resources(ioc); if (r) return r; - + ioc_info(ioc, "Issuing Hard Reset as part of OS Resume\n"); mpt3sas_base_hard_reset_handler(ioc, SOFT_RESET); scsi_unblock_requests(shost); mpt3sas_base_start_watchdog(ioc); @@ -10782,6 +11917,7 @@ if (rc) return PCI_ERS_RESULT_DISCONNECT; + ioc_info(ioc, "Issuing Hard Reset as part of PCI Slot Reset\n"); rc = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER); ioc_warn(ioc, "hard reset: %s\n", @@ -11136,8 +12272,10 @@ mpt3sas_ctl_init(hbas_to_enumerate); error = pci_register_driver(&mpt3sas_driver); - if (error) + if (error) { + mpt3sas_ctl_exit(hbas_to_enumerate); scsih_exit(); + } return error; } --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -61,9 +61,28 @@ #include "mpt3sas_base.h" /** + * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to + * @phy - sas_phy object + * + * Return Port number + */ +static inline u8 +_transport_get_port_id_by_sas_phy(struct sas_phy *phy) +{ + u8 port_id = 0xFF; + struct hba_port *port = phy->hostdata; + + if (port) + port_id = port->port_id; + + return port_id; +} + +/** * _transport_sas_node_find_by_sas_address - sas node search * @ioc: per adapter object * @sas_address: sas address of expander or sas host + * @port: hba port entry * Context: Calling function should acquire ioc->sas_node_lock. * * Search for either hba phys or expander device based on handle, then returns @@ -71,13 +90,56 @@ */ static struct _sas_node * _transport_sas_node_find_by_sas_address(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address) + u64 sas_address, struct hba_port *port) { if (ioc->sas_hba.sas_address == sas_address) return &ioc->sas_hba; else return mpt3sas_scsih_expander_find_by_sas_address(ioc, - sas_address); + sas_address, port); +} + +/** + * _transport_get_port_id_by_rphy - Get Port number from rphy object + * @ioc: per adapter object + * @rphy: sas_rphy object + * + * Returns Port number. + */ +static u8 +_transport_get_port_id_by_rphy(struct MPT3SAS_ADAPTER *ioc, + struct sas_rphy *rphy) +{ + struct _sas_node *sas_expander; + struct _sas_device *sas_device; + unsigned long flags; + u8 port_id = 0xFF; + + if (!rphy) + return port_id; + + if (rphy->identify.device_type == SAS_EDGE_EXPANDER_DEVICE || + rphy->identify.device_type == SAS_FANOUT_EXPANDER_DEVICE) { + spin_lock_irqsave(&ioc->sas_node_lock, flags); + list_for_each_entry(sas_expander, + &ioc->sas_expander_list, list) { + if (sas_expander->rphy == rphy) { + port_id = sas_expander->port->port_id; + break; + } + } + spin_unlock_irqrestore(&ioc->sas_node_lock, flags); + } else if (rphy->identify.device_type == SAS_END_DEVICE) { + spin_lock_irqsave(&ioc->sas_device_lock, flags); + sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); + if (sas_device) { + port_id = sas_device->port->port_id; + sas_device_put(sas_device); + } + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + } + + return port_id; } /** @@ -288,7 +350,7 @@ */ static int _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address, struct sas_expander_device *edev) + u64 sas_address, struct sas_expander_device *edev, u8 port_id) { Mpi2SmpPassthroughRequest_t *mpi_request; Mpi2SmpPassthroughReply_t *mpi_reply; @@ -355,7 +417,7 @@ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; - mpi_request->PhysicalPort = 0xFF; + mpi_request->PhysicalPort = port_id; mpi_request->SASAddress = cpu_to_le64(sas_address); mpi_request->RequestDataLength = cpu_to_le16(data_out_sz); psge = &mpi_request->SGL; @@ -439,6 +501,7 @@ struct _sas_port *mpt3sas_port) { u64 sas_address = mpt3sas_port->remote_identify.sas_address; + struct hba_port *port = mpt3sas_port->hba_port; enum sas_device_type device_type = mpt3sas_port->remote_identify.device_type; @@ -448,10 +511,11 @@ ioc->logging_level |= MPT_DEBUG_TRANSPORT; if (device_type == SAS_END_DEVICE) - mpt3sas_device_remove_by_sas_address(ioc, sas_address); + mpt3sas_device_remove_by_sas_address(ioc, + sas_address, port); else if (device_type == SAS_EDGE_EXPANDER_DEVICE || device_type == SAS_FANOUT_EXPANDER_DEVICE) - mpt3sas_expander_remove(ioc, sas_address); + mpt3sas_expander_remove(ioc, sas_address, port); ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; } @@ -500,16 +564,17 @@ } /** - * _transport_add_phy_to_an_existing_port - adding new phy to existing port + * mpt3sas_transport_add_phy_to_an_existing_port - adding new phy to existing port * @ioc: per adapter object * @sas_node: sas node object (either expander or sas host) * @mpt3sas_phy: mpt3sas per phy object * @sas_address: sas address of device/expander were phy needs to be added to + * @port: hba port entry */ -static void -_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, +void +mpt3sas_transport_add_phy_to_an_existing_port(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy, - u64 sas_address) + u64 sas_address, struct hba_port *port) { struct _sas_port *mpt3sas_port; struct _sas_phy *phy_srch; @@ -517,11 +582,16 @@ if (mpt3sas_phy->phy_belongs_to_port == 1) return; + if (!port) + return; + list_for_each_entry(mpt3sas_port, &sas_node->sas_port_list, port_list) { if (mpt3sas_port->remote_identify.sas_address != sas_address) continue; + if (mpt3sas_port->hba_port != port) + continue; list_for_each_entry(phy_srch, &mpt3sas_port->phy_list, port_siblings) { if (phy_srch == mpt3sas_phy) @@ -534,13 +604,13 @@ } /** - * _transport_del_phy_from_an_existing_port - delete phy from existing port + * mpt3sas_transport_del_phy_from_an_existing_port - delete phy from existing port * @ioc: per adapter object * @sas_node: sas node object (either expander or sas host) * @mpt3sas_phy: mpt3sas per phy object */ -static void -_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, +void +mpt3sas_transport_del_phy_from_an_existing_port(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, struct _sas_phy *mpt3sas_phy) { struct _sas_port *mpt3sas_port, *next; @@ -556,7 +626,11 @@ if (phy_srch != mpt3sas_phy) continue; - if (mpt3sas_port->num_phys == 1) + /* + * Don't delete port during host reset, + * just delete phy. + */ + if (mpt3sas_port->num_phys == 1 && !ioc->shost_recovery) _transport_delete_port(ioc, mpt3sas_port); else _transport_delete_phy(ioc, mpt3sas_port, @@ -571,21 +645,24 @@ * @ioc: per adapter object * @sas_node: sas node object (either expander or sas host) * @sas_address: sas address of device being added + * @port: hba port entry * * See the explanation above from _transport_delete_duplicate_port */ static void _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, - u64 sas_address) + u64 sas_address, struct hba_port *port) { int i; for (i = 0; i < sas_node->num_phys; i++) { if (sas_node->phy[i].remote_identify.sas_address != sas_address) continue; + if (sas_node->phy[i].port != port) + continue; if (sas_node->phy[i].phy_belongs_to_port == 1) - _transport_del_phy_from_an_existing_port(ioc, sas_node, - &sas_node->phy[i]); + mpt3sas_transport_del_phy_from_an_existing_port(ioc, + sas_node, &sas_node->phy[i]); } } @@ -594,6 +671,7 @@ * @ioc: per adapter object * @handle: handle of attached device * @sas_address: sas address of parent expander or sas host + * @port: hba port entry * Context: This function will acquire ioc->sas_node_lock. * * Adding new port object to the sas_node->sas_port_list. @@ -602,7 +680,7 @@ */ struct _sas_port * mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, - u64 sas_address) + u64 sas_address, struct hba_port *hba_port) { struct _sas_phy *mpt3sas_phy, *next; struct _sas_port *mpt3sas_port; @@ -612,6 +690,13 @@ struct _sas_device *sas_device = NULL; int i; struct sas_port *port; + struct virtual_phy *vphy = NULL; + + if (!hba_port) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + return NULL; + } mpt3sas_port = kzalloc(sizeof(struct _sas_port), GFP_KERNEL); @@ -624,7 +709,8 @@ INIT_LIST_HEAD(&mpt3sas_port->port_list); INIT_LIST_HEAD(&mpt3sas_port->phy_list); spin_lock_irqsave(&ioc->sas_node_lock, flags); - sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); + sas_node = _transport_sas_node_find_by_sas_address(ioc, + sas_address, hba_port); spin_unlock_irqrestore(&ioc->sas_node_lock, flags); if (!sas_node) { @@ -646,16 +732,32 @@ goto out_fail; } + mpt3sas_port->hba_port = hba_port; _transport_sanity_check(ioc, sas_node, - mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->remote_identify.sas_address, hba_port); for (i = 0; i < sas_node->num_phys; i++) { if (sas_node->phy[i].remote_identify.sas_address != mpt3sas_port->remote_identify.sas_address) continue; + if (sas_node->phy[i].port != hba_port) + continue; list_add_tail(&sas_node->phy[i].port_siblings, &mpt3sas_port->phy_list); mpt3sas_port->num_phys++; + if (sas_node->handle <= ioc->sas_hba.num_phys) { + if (!sas_node->phy[i].hba_vphy) { + hba_port->phy_mask |= (1 << i); + continue; + } + + vphy = mpt3sas_get_vphy_by_phy(ioc, hba_port, i); + if (!vphy) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out_fail; + } + } } if (!mpt3sas_port->num_phys) { @@ -664,13 +766,25 @@ goto out_fail; } + if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { + sas_device = mpt3sas_get_sdev_by_addr(ioc, + mpt3sas_port->remote_identify.sas_address, + mpt3sas_port->hba_port); + if (!sas_device) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out_fail; + } + sas_device->pend_sas_rphy_add = 1; + } + if (!sas_node->parent_dev) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); goto out_fail; } port = sas_port_alloc_num(sas_node->parent_dev); - if ((sas_port_add(port))) { + if (!port || (sas_port_add(port))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); goto out_fail; @@ -686,32 +800,43 @@ mpt3sas_phy->phy_id); sas_port_add_phy(port, mpt3sas_phy->phy); mpt3sas_phy->phy_belongs_to_port = 1; + mpt3sas_phy->port = hba_port; } mpt3sas_port->port = port; - if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) + if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { rphy = sas_end_device_alloc(port); - else + sas_device->rphy = rphy; + if (sas_node->handle <= ioc->sas_hba.num_phys) { + if (!vphy) + hba_port->sas_address = + sas_device->sas_address; + else + vphy->sas_address = + sas_device->sas_address; + } + } else { rphy = sas_expander_alloc(port, mpt3sas_port->remote_identify.device_type); + if (sas_node->handle <= ioc->sas_hba.num_phys) + hba_port->sas_address = + mpt3sas_port->remote_identify.sas_address; + } - rphy->identify = mpt3sas_port->remote_identify; - - if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { - sas_device = mpt3sas_get_sdev_by_addr(ioc, - mpt3sas_port->remote_identify.sas_address); - if (!sas_device) { - dfailprintk(ioc, - ioc_info(ioc, "failure at %s:%d/%s()!\n", - __FILE__, __LINE__, __func__)); - goto out_fail; - } - sas_device->pend_sas_rphy_add = 1; + if (!rphy) { + ioc_err(ioc, "failure at %s:%d/%s()!\n", + __FILE__, __LINE__, __func__); + goto out_delete_port; } + rphy->identify = mpt3sas_port->remote_identify; + if ((sas_rphy_add(rphy))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); + sas_rphy_free(rphy); + rphy = NULL; + goto out_delete_port; } if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { @@ -719,11 +844,10 @@ sas_device_put(sas_device); } - if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) - dev_printk(KERN_INFO, &rphy->dev, - "add: handle(0x%04x), sas_addr(0x%016llx)\n", - handle, (unsigned long long) - mpt3sas_port->remote_identify.sas_address); + dev_info(&rphy->dev, + "add: handle(0x%04x), sas_addr(0x%016llx)\n", handle, + (unsigned long long)mpt3sas_port->remote_identify.sas_address); + mpt3sas_port->rphy = rphy; spin_lock_irqsave(&ioc->sas_node_lock, flags); list_add_tail(&mpt3sas_port->port_list, &sas_node->sas_port_list); @@ -736,10 +860,13 @@ MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) _transport_expander_report_manufacture(ioc, mpt3sas_port->remote_identify.sas_address, - rphy_to_expander_device(rphy)); + rphy_to_expander_device(rphy), hba_port->port_id); return mpt3sas_port; - out_fail: +out_delete_port: + sas_port_delete(port); + +out_fail: list_for_each_entry_safe(mpt3sas_phy, next, &mpt3sas_port->phy_list, port_siblings) list_del(&mpt3sas_phy->port_siblings); @@ -752,6 +879,7 @@ * @ioc: per adapter object * @sas_address: sas address of attached device * @sas_address_parent: sas address of parent expander or sas host + * @port: hba port entry * Context: This function will acquire ioc->sas_node_lock. * * Removing object and freeing associated memory from the @@ -759,7 +887,7 @@ */ void mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, - u64 sas_address_parent) + u64 sas_address_parent, struct hba_port *port) { int i; unsigned long flags; @@ -767,10 +895,15 @@ struct _sas_node *sas_node; u8 found = 0; struct _sas_phy *mpt3sas_phy, *next_phy; + struct hba_port *hba_port_next, *hba_port = NULL; + struct virtual_phy *vphy, *vphy_next = NULL; + + if (!port) + return; spin_lock_irqsave(&ioc->sas_node_lock, flags); sas_node = _transport_sas_node_find_by_sas_address(ioc, - sas_address_parent); + sas_address_parent, port); if (!sas_node) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return; @@ -779,6 +912,8 @@ port_list) { if (mpt3sas_port->remote_identify.sas_address != sas_address) continue; + if (mpt3sas_port->hba_port != port) + continue; found = 1; list_del(&mpt3sas_port->port_list); goto out; @@ -789,6 +924,61 @@ return; } + if (sas_node->handle <= ioc->sas_hba.num_phys && + (ioc->multipath_on_hba)) { + if (port->vphys_mask) { + list_for_each_entry_safe(vphy, vphy_next, + &port->vphys_list, list) { + if (vphy->sas_address != sas_address) + continue; + ioc_info(ioc, + "remove vphy entry: %p of port:%p,from %d port's vphys list\n", + vphy, port, port->port_id); + port->vphys_mask &= ~vphy->phy_mask; + list_del(&vphy->list); + kfree(vphy); + } + } + + list_for_each_entry_safe(hba_port, hba_port_next, + &ioc->port_table_list, list) { + if (hba_port != port) + continue; + /* + * Delete hba_port object if + * - hba_port object's sas address matches with current + * removed device's sas address and no vphy's + * associated with it. + * - Current removed device is a vSES device and + * none of the other direct attached device have + * this vSES device's port number (hence hba_port + * object sas_address field will be zero). + */ + if ((hba_port->sas_address == sas_address || + !hba_port->sas_address) && !hba_port->vphys_mask) { + ioc_info(ioc, + "remove hba_port entry: %p port: %d from hba_port list\n", + hba_port, hba_port->port_id); + list_del(&hba_port->list); + kfree(hba_port); + } else if (hba_port->sas_address == sas_address && + hba_port->vphys_mask) { + /* + * Current removed device is a non vSES device + * and a vSES device has the same port number + * as of current device's port number. Hence + * only clear the sas_address filed, don't + * delete the hba_port object. + */ + ioc_info(ioc, + "clearing sas_address from hba_port entry: %p port: %d from hba_port list\n", + hba_port, hba_port->port_id); + port->sas_address = 0; + } + break; + } + } + for (i = 0; i < sas_node->num_phys; i++) { if (sas_node->phy[i].remote_identify.sas_address == sas_address) memset(&sas_node->phy[i].remote_identify, 0 , @@ -813,6 +1003,8 @@ } if (!ioc->remove_host) sas_port_delete(mpt3sas_port->port); + ioc_info(ioc, "%s: removed: sas_addr(0x%016llx)\n", + __func__, (unsigned long long)sas_address); kfree(mpt3sas_port); } @@ -863,6 +1055,7 @@ phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); phy->maximum_linkrate = _transport_convert_phy_link_rate( phy_pg0.ProgrammedLinkRate >> 4); + phy->hostdata = mpt3sas_phy->port; if ((sas_phy_add(phy))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", @@ -933,6 +1126,7 @@ expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); phy->maximum_linkrate = _transport_convert_phy_link_rate( expander_pg1.ProgrammedLinkRate >> 4); + phy->hostdata = mpt3sas_phy->port; if ((sas_phy_add(phy))) { ioc_err(ioc, "failure at %s:%d/%s()!\n", @@ -960,20 +1154,26 @@ * @handle: attached device handle * @phy_number: phy number * @link_rate: new link rate + * @port: hba port entry + * + * Return nothing. */ void mpt3sas_transport_update_links(struct MPT3SAS_ADAPTER *ioc, - u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) + u64 sas_address, u16 handle, u8 phy_number, u8 link_rate, + struct hba_port *port) { unsigned long flags; struct _sas_node *sas_node; struct _sas_phy *mpt3sas_phy; + struct hba_port *hba_port = NULL; if (ioc->shost_recovery || ioc->pci_error_recovery) return; spin_lock_irqsave(&ioc->sas_node_lock, flags); - sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); + sas_node = _transport_sas_node_find_by_sas_address(ioc, + sas_address, port); if (!sas_node) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return; @@ -985,8 +1185,19 @@ if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { _transport_set_identify(ioc, handle, &mpt3sas_phy->remote_identify); - _transport_add_phy_to_an_existing_port(ioc, sas_node, - mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address); + if ((sas_node->handle <= ioc->sas_hba.num_phys) && + (ioc->multipath_on_hba)) { + list_for_each_entry(hba_port, + &ioc->port_table_list, list) { + if (hba_port->sas_address == sas_address && + hba_port == port) + hba_port->phy_mask |= + (1 << mpt3sas_phy->phy_id); + } + } + mpt3sas_transport_add_phy_to_an_existing_port(ioc, sas_node, + mpt3sas_phy, mpt3sas_phy->remote_identify.sas_address, + port); } else memset(&mpt3sas_phy->remote_identify, 0 , sizeof(struct sas_identify)); @@ -1121,7 +1332,7 @@ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; - mpi_request->PhysicalPort = 0xFF; + mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy); mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); @@ -1211,10 +1422,13 @@ unsigned long flags; Mpi2ConfigReply_t mpi_reply; Mpi2SasPhyPage1_t phy_pg1; + struct hba_port *port = phy->hostdata; + int port_id = port->port_id; spin_lock_irqsave(&ioc->sas_node_lock, flags); if (_transport_sas_node_find_by_sas_address(ioc, - phy->identify.sas_address) == NULL) { + phy->identify.sas_address, + mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return -EINVAL; } @@ -1264,8 +1478,7 @@ int rc; spin_lock_irqsave(&ioc->sas_device_lock, flags); - sas_device = __mpt3sas_get_sdev_by_addr(ioc, - rphy->identify.sas_address); + sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); if (sas_device) { *identifier = sas_device->enclosure_logical_id; rc = 0; @@ -1294,8 +1507,7 @@ int rc; spin_lock_irqsave(&ioc->sas_device_lock, flags); - sas_device = __mpt3sas_get_sdev_by_addr(ioc, - rphy->identify.sas_address); + sas_device = __mpt3sas_get_sdev_by_rphy(ioc, rphy); if (sas_device) { rc = sas_device->slot; sas_device_put(sas_device); @@ -1416,7 +1628,7 @@ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; - mpi_request->PhysicalPort = 0xFF; + mpi_request->PhysicalPort = _transport_get_port_id_by_sas_phy(phy); mpi_request->VF_ID = 0; /* TODO */ mpi_request->VP_ID = 0; mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); @@ -1498,11 +1710,14 @@ struct MPT3SAS_ADAPTER *ioc = phy_to_ioc(phy); Mpi2SasIoUnitControlReply_t mpi_reply; Mpi2SasIoUnitControlRequest_t mpi_request; + struct hba_port *port = phy->hostdata; + int port_id = port->port_id; unsigned long flags; spin_lock_irqsave(&ioc->sas_node_lock, flags); if (_transport_sas_node_find_by_sas_address(ioc, - phy->identify.sas_address) == NULL) { + phy->identify.sas_address, + mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return -EINVAL; } @@ -1555,10 +1770,13 @@ int rc = 0; unsigned long flags; int i, discovery_active; + struct hba_port *port = phy->hostdata; + int port_id = port->port_id; spin_lock_irqsave(&ioc->sas_node_lock, flags); if (_transport_sas_node_find_by_sas_address(ioc, - phy->identify.sas_address) == NULL) { + phy->identify.sas_address, + mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return -EINVAL; } @@ -1692,10 +1910,13 @@ int i; int rc = 0; unsigned long flags; + struct hba_port *port = phy->hostdata; + int port_id = port->port_id; spin_lock_irqsave(&ioc->sas_node_lock, flags); if (_transport_sas_node_find_by_sas_address(ioc, - phy->identify.sas_address) == NULL) { + phy->identify.sas_address, + mpt3sas_get_port_by_id(ioc, port_id, 0)) == NULL) { spin_unlock_irqrestore(&ioc->sas_node_lock, flags); return -EINVAL; } @@ -1897,7 +2118,7 @@ memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; - mpi_request->PhysicalPort = 0xFF; + mpi_request->PhysicalPort = _transport_get_port_id_by_rphy(ioc, rphy); mpi_request->SASAddress = (rphy) ? cpu_to_le64(rphy->identify.sas_address) : cpu_to_le64(ioc->sas_hba.sas_address); --- linux-oracle-5.4.0.orig/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c +++ linux-oracle-5.4.0/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c @@ -113,15 +113,21 @@ struct SL_WH_TRIGGERS_EVENT_DATA_T *event_data) { u8 issue_reset = 0; + u32 *trig_data = (u32 *)&event_data->u.master; dTriggerDiagPrintk(ioc, ioc_info(ioc, "%s: enter\n", __func__)); /* release the diag buffer trace */ if ((ioc->diag_buffer_status[MPI2_DIAG_BUF_TYPE_TRACE] & MPT3_DIAG_BUFFER_IS_RELEASED) == 0) { - dTriggerDiagPrintk(ioc, - ioc_info(ioc, "%s: release trace diag buffer\n", - __func__)); + /* + * add a log message so that user knows which event caused + * the release + */ + ioc_info(ioc, + "%s: Releasing the trace buffer. Trigger_Type 0x%08x, Data[0] 0x%08x, Data[1] 0x%08x\n", + __func__, event_data->trigger_type, + trig_data[0], trig_data[1]); mpt3sas_send_diag_release(ioc, MPI2_DIAG_BUF_TYPE_TRACE, &issue_reset); } --- linux-oracle-5.4.0.orig/drivers/scsi/mvsas/mv_init.c +++ linux-oracle-5.4.0/drivers/scsi/mvsas/mv_init.c @@ -45,6 +45,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = mvst_host_attrs, @@ -645,6 +646,7 @@ { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 }, { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 }, { PCI_VDEVICE(ADAPTEC2, 0x0450), chip_6440 }, + { PCI_VDEVICE(TTI, 0x2640), chip_6440 }, { PCI_VDEVICE(TTI, 0x2710), chip_9480 }, { PCI_VDEVICE(TTI, 0x2720), chip_9480 }, { PCI_VDEVICE(TTI, 0x2721), chip_9480 }, @@ -696,7 +698,7 @@ mvs_show_driver_version(struct device *cdev, struct device_attribute *attr, char *buffer) { - return snprintf(buffer, PAGE_SIZE, "%s\n", DRV_VERSION); + return sysfs_emit(buffer, "%s\n", DRV_VERSION); } static DEVICE_ATTR(driver_version, @@ -748,7 +750,7 @@ static ssize_t mvs_show_interrupt_coalescing(struct device *cdev, struct device_attribute *attr, char *buffer) { - return snprintf(buffer, PAGE_SIZE, "%d\n", interrupt_coalescing); + return sysfs_emit(buffer, "%d\n", interrupt_coalescing); } static DEVICE_ATTR(interrupt_coalescing, --- linux-oracle-5.4.0.orig/drivers/scsi/mvumi.c +++ linux-oracle-5.4.0/drivers/scsi/mvumi.c @@ -2425,6 +2425,7 @@ if (IS_ERR(mhba->dm_thread)) { dev_err(&mhba->pdev->dev, "failed to create device scan thread\n"); + ret = PTR_ERR(mhba->dm_thread); mutex_unlock(&mhba->sas_discovery_mutex); goto fail_create_thread; } --- linux-oracle-5.4.0.orig/drivers/scsi/myrb.c +++ linux-oracle-5.4.0/drivers/scsi/myrb.c @@ -1241,7 +1241,8 @@ myrb_unmap(cb); if (cb->mmio_base) { - cb->disable_intr(cb->io_base); + if (cb->disable_intr) + cb->disable_intr(cb->io_base); iounmap(cb->mmio_base); } if (cb->irq) @@ -1802,9 +1803,9 @@ name = myrb_devstate_name(ldev_info->state); if (name) - ret = snprintf(buf, 32, "%s\n", name); + ret = snprintf(buf, 64, "%s\n", name); else - ret = snprintf(buf, 32, "Invalid (%02X)\n", + ret = snprintf(buf, 64, "Invalid (%02X)\n", ldev_info->state); } else { struct myrb_pdev_state *pdev_info = sdev->hostdata; @@ -1823,9 +1824,9 @@ else name = myrb_devstate_name(pdev_info->state); if (name) - ret = snprintf(buf, 32, "%s\n", name); + ret = snprintf(buf, 64, "%s\n", name); else - ret = snprintf(buf, 32, "Invalid (%02X)\n", + ret = snprintf(buf, 64, "Invalid (%02X)\n", pdev_info->state); } return ret; @@ -1913,11 +1914,11 @@ name = myrb_raidlevel_name(ldev_info->raid_level); if (!name) - return snprintf(buf, 32, "Invalid (%02X)\n", + return snprintf(buf, 64, "Invalid (%02X)\n", ldev_info->state); - return snprintf(buf, 32, "%s\n", name); + return snprintf(buf, 64, "%s\n", name); } - return snprintf(buf, 32, "Physical Drive\n"); + return snprintf(buf, 64, "Physical Drive\n"); } static DEVICE_ATTR_RO(raid_level); @@ -1930,15 +1931,15 @@ unsigned char status; if (sdev->channel < myrb_logical_channel(sdev->host)) - return snprintf(buf, 32, "physical device - not rebuilding\n"); + return snprintf(buf, 64, "physical device - not rebuilding\n"); status = myrb_get_rbld_progress(cb, &rbld_buf); if (rbld_buf.ldev_num != sdev->id || status != MYRB_STATUS_SUCCESS) - return snprintf(buf, 32, "not rebuilding\n"); + return snprintf(buf, 64, "not rebuilding\n"); - return snprintf(buf, 32, "rebuilding block %u of %u\n", + return snprintf(buf, 64, "rebuilding block %u of %u\n", rbld_buf.ldev_size - rbld_buf.blocks_left, rbld_buf.ldev_size); } @@ -3516,9 +3517,13 @@ mutex_init(&cb->dcmd_mutex); mutex_init(&cb->dma_mutex); cb->pdev = pdev; + cb->host = shost; - if (pci_enable_device(pdev)) - goto failure; + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, "Failed to enable PCI device\n"); + scsi_host_put(shost); + return NULL; + } if (privdata->hw_init == DAC960_PD_hw_init || privdata->hw_init == DAC960_P_hw_init) { --- linux-oracle-5.4.0.orig/drivers/scsi/myrs.c +++ linux-oracle-5.4.0/drivers/scsi/myrs.c @@ -950,9 +950,9 @@ name = myrs_devstate_name(ldev_info->dev_state); if (name) - ret = snprintf(buf, 32, "%s\n", name); + ret = snprintf(buf, 64, "%s\n", name); else - ret = snprintf(buf, 32, "Invalid (%02X)\n", + ret = snprintf(buf, 64, "Invalid (%02X)\n", ldev_info->dev_state); } else { struct myrs_pdev_info *pdev_info; @@ -961,9 +961,9 @@ pdev_info = sdev->hostdata; name = myrs_devstate_name(pdev_info->dev_state); if (name) - ret = snprintf(buf, 32, "%s\n", name); + ret = snprintf(buf, 64, "%s\n", name); else - ret = snprintf(buf, 32, "Invalid (%02X)\n", + ret = snprintf(buf, 64, "Invalid (%02X)\n", pdev_info->dev_state); } return ret; @@ -1069,13 +1069,13 @@ ldev_info = sdev->hostdata; name = myrs_raid_level_name(ldev_info->raid_level); if (!name) - return snprintf(buf, 32, "Invalid (%02X)\n", + return snprintf(buf, 64, "Invalid (%02X)\n", ldev_info->dev_state); } else name = myrs_raid_level_name(MYRS_RAID_PHYSICAL); - return snprintf(buf, 32, "%s\n", name); + return snprintf(buf, 64, "%s\n", name); } static DEVICE_ATTR_RO(raid_level); @@ -1089,7 +1089,7 @@ unsigned char status; if (sdev->channel < cs->ctlr_info->physchan_present) - return snprintf(buf, 32, "physical device - not rebuilding\n"); + return snprintf(buf, 64, "physical device - not rebuilding\n"); ldev_info = sdev->hostdata; ldev_num = ldev_info->ldev_num; @@ -1101,11 +1101,11 @@ return -EIO; } if (ldev_info->rbld_active) { - return snprintf(buf, 32, "rebuilding block %zu of %zu\n", + return snprintf(buf, 64, "rebuilding block %zu of %zu\n", (size_t)ldev_info->rbld_lba, (size_t)ldev_info->cfg_devsize); } else - return snprintf(buf, 32, "not rebuilding\n"); + return snprintf(buf, 64, "not rebuilding\n"); } static ssize_t rebuild_store(struct device *dev, @@ -1194,7 +1194,7 @@ unsigned char status; if (sdev->channel < cs->ctlr_info->physchan_present) - return snprintf(buf, 32, "physical device - not checking\n"); + return snprintf(buf, 64, "physical device - not checking\n"); ldev_info = sdev->hostdata; if (!ldev_info) @@ -1202,11 +1202,11 @@ ldev_num = ldev_info->ldev_num; status = myrs_get_ldev_info(cs, ldev_num, ldev_info); if (ldev_info->cc_active) - return snprintf(buf, 32, "checking block %zu of %zu\n", + return snprintf(buf, 64, "checking block %zu of %zu\n", (size_t)ldev_info->cc_lba, (size_t)ldev_info->cfg_devsize); else - return snprintf(buf, 32, "not checking\n"); + return snprintf(buf, 64, "not checking\n"); } static ssize_t consistency_check_store(struct device *dev, @@ -2272,14 +2272,15 @@ myrs_unmap(cs); if (cs->mmio_base) { - cs->disable_intr(cs); + if (cs->disable_intr) + cs->disable_intr(cs); iounmap(cs->mmio_base); + cs->mmio_base = NULL; } if (cs->irq) free_irq(cs->irq, cs); if (cs->io_addr) release_region(cs->io_addr, 0x80); - iounmap(cs->mmio_base); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); scsi_host_put(cs->host); --- linux-oracle-5.4.0.orig/drivers/scsi/pcmcia/fdomain_cs.c +++ linux-oracle-5.4.0/drivers/scsi/pcmcia/fdomain_cs.c @@ -45,8 +45,10 @@ goto fail_disable; if (!request_region(link->resource[0]->start, FDOMAIN_REGION_SIZE, - "fdomain_cs")) + "fdomain_cs")) { + ret = -EBUSY; goto fail_disable; + } sh = fdomain_create(link->resource[0]->start, link->irq, 7, &link->dev); if (!sh) { --- linux-oracle-5.4.0.orig/drivers/scsi/pm8001/pm8001_hwi.c +++ linux-oracle-5.4.0/drivers/scsi/pm8001/pm8001_hwi.c @@ -1750,6 +1750,7 @@ ccb->device = pm8001_ha_dev; ccb->ccb_tag = ccb_tag; ccb->task = task; + ccb->n_elem = 0; circularQ = &pm8001_ha->inbnd_q_tbl[0]; @@ -1812,6 +1813,7 @@ ccb->device = pm8001_ha_dev; ccb->ccb_tag = ccb_tag; ccb->task = task; + ccb->n_elem = 0; pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG; pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG; @@ -1828,7 +1830,7 @@ sata_cmd.tag = cpu_to_le32(ccb_tag); sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9)); + sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9)); memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); @@ -3773,12 +3775,11 @@ mb(); if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) { - pm8001_tag_free(pm8001_ha, tag); sas_free_task(t); - /* clear the flag */ - pm8001_dev->id &= 0xBFFFFFFF; - } else + pm8001_dev->id &= ~NCQ_ABORT_ALL_FLAG; + } else { t->task_done(t); + } return 0; } @@ -4172,7 +4173,7 @@ { struct outbound_queue_table *circularQ; void *pMsg1 = NULL; - u8 uninitialized_var(bc); + u8 bc; u32 ret = MPI_IO_STATUS_FAIL; unsigned long flags; @@ -4727,7 +4728,7 @@ memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8); sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag); if (pm8001_ha->chip_id != chip_8001) - sspTMCmd.ds_ads_m = 0x08; + sspTMCmd.ds_ads_m = cpu_to_le32(0x08); circularQ = &pm8001_ha->inbnd_q_tbl[0]; ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd, 0); return ret; --- linux-oracle-5.4.0.orig/drivers/scsi/pm8001/pm8001_init.c +++ linux-oracle-5.4.0/drivers/scsi/pm8001/pm8001_init.c @@ -86,6 +86,7 @@ .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, .shost_attrs = pm8001_host_attrs, @@ -1040,7 +1041,8 @@ pm8001_init_sas_add(pm8001_ha); /* phy setting support for motherboard controller */ - if (pm8001_configure_phy_settings(pm8001_ha)) + rc = pm8001_configure_phy_settings(pm8001_ha); + if (rc) goto err_out_shost; pm8001_post_sas_ha_init(shost, chip); --- linux-oracle-5.4.0.orig/drivers/scsi/pm8001/pm8001_sas.c +++ linux-oracle-5.4.0/drivers/scsi/pm8001/pm8001_sas.c @@ -680,8 +680,7 @@ void pm8001_task_done(struct sas_task *task) { - if (!del_timer(&task->slow_task->timer)) - return; + del_timer(&task->slow_task->timer); complete(&task->slow_task->completion); } @@ -689,9 +688,14 @@ { struct sas_task_slow *slow = from_timer(slow, t, timer); struct sas_task *task = slow->task; + unsigned long flags; - task->task_state_flags |= SAS_TASK_STATE_ABORTED; - complete(&task->slow_task->completion); + spin_lock_irqsave(&task->task_state_lock, flags); + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + complete(&task->slow_task->completion); + } + spin_unlock_irqrestore(&task->task_state_lock, flags); } #define PM8001_TASK_TIMEOUT 20 @@ -746,13 +750,16 @@ } res = -TMF_RESP_FUNC_FAILED; /* Even TMF timed out, return direct. */ - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("TMF task[%x]timeout.\n", - tmf->tmf)); - goto ex_err; - } + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + struct pm8001_ccb_info *ccb = task->lldd_task; + + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("TMF task[%x]timeout.\n", + tmf->tmf)); + + if (ccb) + ccb->task = NULL; + goto ex_err; } if (task->task_status.resp == SAS_TASK_COMPLETE && @@ -816,7 +823,7 @@ res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); if (res) - return res; + goto ex_err; ccb = &pm8001_ha->ccb_info[ccb_tag]; ccb->device = pm8001_dev; ccb->ccb_tag = ccb_tag; @@ -836,12 +843,10 @@ wait_for_completion(&task->slow_task->completion); res = TMF_RESP_FUNC_FAILED; /* Even TMF timed out, return direct. */ - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("TMF task timeout.\n")); - goto ex_err; - } + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("TMF task timeout.\n")); + goto ex_err; } if (task->task_status.resp == SAS_TASK_COMPLETE && @@ -1202,8 +1207,8 @@ pm8001_dev = dev->lldd_dev; pm8001_ha = pm8001_find_ha_by_dev(dev); phy_id = pm8001_dev->attached_phy; - rc = pm8001_find_tag(task, &tag); - if (rc == 0) { + ret = pm8001_find_tag(task, &tag); + if (ret == 0) { pm8001_printk("no tag for task:%p\n", task); return TMF_RESP_FUNC_FAILED; } @@ -1241,26 +1246,50 @@ /* 2. Send Phy Control Hard Reset */ reinit_completion(&completion); + phy->port_reset_status = PORT_RESET_TMO; phy->reset_success = false; phy->enable_completion = &completion; phy->reset_completion = &completion_reset; ret = PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id, PHY_HARD_RESET); - if (ret) - goto out; - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("Waiting for local phy ctl\n")); - wait_for_completion(&completion); - if (!phy->reset_success) + if (ret) { + phy->enable_completion = NULL; + phy->reset_completion = NULL; goto out; + } - /* 3. Wait for Port Reset complete / Port reset TMO */ + /* In the case of the reset timeout/fail we still + * abort the command at the firmware. The assumption + * here is that the drive is off doing something so + * that it's not processing requests, and we want to + * avoid getting a completion for this and either + * leaking the task in libsas or losing the race and + * getting a double free. + */ PM8001_MSG_DBG(pm8001_ha, + pm8001_printk("Waiting for local phy ctl\n")); + ret = wait_for_completion_timeout(&completion, + PM8001_TASK_TIMEOUT * HZ); + if (!ret || !phy->reset_success) { + phy->enable_completion = NULL; + phy->reset_completion = NULL; + } else { + /* 3. Wait for Port Reset complete or + * Port reset TMO + */ + PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Waiting for Port reset\n")); - wait_for_completion(&completion_reset); - if (phy->port_reset_status) { - pm8001_dev_gone_notify(dev); - goto out; + ret = wait_for_completion_timeout( + &completion_reset, + PM8001_TASK_TIMEOUT * HZ); + if (!ret) + phy->reset_completion = NULL; + WARN_ON(phy->port_reset_status == + PORT_RESET_TMO); + if (phy->port_reset_status == PORT_RESET_TMO) { + pm8001_dev_gone_notify(dev); + goto out; + } } /* --- linux-oracle-5.4.0.orig/drivers/scsi/pm8001/pm80xx_hwi.c +++ linux-oracle-5.4.0/drivers/scsi/pm8001/pm80xx_hwi.c @@ -881,9 +881,11 @@ else page_code = THERMAL_PAGE_CODE_8H; - payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) | - (THERMAL_ENABLE << 8) | page_code; - payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8); + payload.cfg_pg[0] = + cpu_to_le32((THERMAL_LOG_ENABLE << 9) | + (THERMAL_ENABLE << 8) | page_code); + payload.cfg_pg[1] = + cpu_to_le32((LTEMPHIL << 24) | (RTEMPHIL << 8)); rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); if (rc) @@ -1435,6 +1437,7 @@ ccb->device = pm8001_ha_dev; ccb->ccb_tag = ccb_tag; ccb->task = task; + ccb->n_elem = 0; circularQ = &pm8001_ha->inbnd_q_tbl[0]; @@ -1516,7 +1519,7 @@ sata_cmd.tag = cpu_to_le32(ccb_tag); sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 << 7) | (0x5 << 9)); + sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9))); memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); @@ -2382,6 +2385,8 @@ pm8001_printk("task 0x%p done with io_status 0x%x" " resp 0x%x stat 0x%x but aborted by upper layer!\n", t, status, ts->resp, ts->stat)); + if (t->slow_task) + complete(&t->slow_task->completion); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); } else { spin_unlock_irqrestore(&t->task_state_lock, flags); @@ -3808,7 +3813,7 @@ { struct outbound_queue_table *circularQ; void *pMsg1 = NULL; - u8 uninitialized_var(bc); + u8 bc; u32 ret = MPI_IO_STATUS_FAIL; unsigned long flags; u32 regval; --- linux-oracle-5.4.0.orig/drivers/scsi/pmcraid.c +++ linux-oracle-5.4.0/drivers/scsi/pmcraid.c @@ -4532,7 +4532,7 @@ return 0; out_unwind: - while (--i > 0) + while (--i >= 0) free_irq(pci_irq_vector(pdev, i), &pinstance->hrrq_vector[i]); pci_free_irq_vectors(pdev); return rc; --- linux-oracle-5.4.0.orig/drivers/scsi/qedf/qedf.h +++ linux-oracle-5.4.0/drivers/scsi/qedf/qedf.h @@ -355,6 +355,7 @@ #define QEDF_GRCDUMP_CAPTURE 4 #define QEDF_IN_RECOVERY 5 #define QEDF_DBG_STOP_IO 6 +#define QEDF_PROBING 8 unsigned long flags; /* Miscellaneous state flags */ int fipvlan_retries; u8 num_queues; --- linux-oracle-5.4.0.orig/drivers/scsi/qedf/qedf_dbg.h +++ linux-oracle-5.4.0/drivers/scsi/qedf/qedf_dbg.h @@ -60,6 +60,8 @@ #define QEDF_LOG_NOTICE 0x40000000 /* Notice logs */ #define QEDF_LOG_WARN 0x80000000 /* Warning logs */ +#define QEDF_DEBUGFS_LOG_LEN (2 * PAGE_SIZE) + /* Debug context structure */ struct qedf_dbg_ctx { unsigned int host_no; --- linux-oracle-5.4.0.orig/drivers/scsi/qedf/qedf_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/qedf/qedf_debugfs.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "qedf.h" #include "qedf_dbg.h" @@ -100,7 +101,9 @@ qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { + ssize_t ret; size_t cnt = 0; + char *cbuf; int id; struct qedf_fastpath *fp = NULL; struct qedf_dbg_ctx *qedf_dbg = @@ -110,19 +113,25 @@ QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); - cnt = sprintf(buffer, "\nFastpath I/O completions\n\n"); + cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN); + if (!cbuf) + return 0; + + cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n"); for (id = 0; id < qedf->num_queues; id++) { fp = &(qedf->fp_array[id]); if (fp->sb_id == QEDF_SB_ID_NULL) continue; - cnt += sprintf((buffer + cnt), "#%d: %lu\n", id, - fp->completions); + cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, + "#%d: %lu\n", id, fp->completions); } - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); + + vfree(cbuf); + + return ret; } static ssize_t @@ -140,15 +149,14 @@ loff_t *ppos) { int cnt; + char cbuf[32]; struct qedf_dbg_ctx *qedf_dbg = (struct qedf_dbg_ctx *)filp->private_data; QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "debug mask=0x%x\n", qedf_debug); - cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug); + cnt = scnprintf(cbuf, sizeof(cbuf), "debug mask = 0x%x\n", qedf_debug); - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); } static ssize_t @@ -164,7 +172,7 @@ if (!count || *ppos) return 0; - kern_buf = memdup_user(buffer, count); + kern_buf = memdup_user_nul(buffer, count); if (IS_ERR(kern_buf)) return PTR_ERR(kern_buf); @@ -187,18 +195,17 @@ size_t count, loff_t *ppos) { int cnt; + char cbuf[7]; struct qedf_dbg_ctx *qedf_dbg = (struct qedf_dbg_ctx *)filp->private_data; struct qedf_ctx *qedf = container_of(qedf_dbg, struct qedf_ctx, dbg_ctx); QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); - cnt = sprintf(buffer, "%s\n", + cnt = scnprintf(cbuf, sizeof(cbuf), "%s\n", qedf->stop_io_on_error ? "true" : "false"); - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); } static ssize_t --- linux-oracle-5.4.0.orig/drivers/scsi/qedf/qedf_io.c +++ linux-oracle-5.4.0/drivers/scsi/qedf/qedf_io.c @@ -1504,9 +1504,19 @@ { int rval; + if (io_req == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "io_req is NULL.\n"); + return; + } + + if (io_req->fcport == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "fcport is NULL.\n"); + return; + } + if (!cqe) { QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, - "cqe is NULL for io_req %p\n", io_req); + "cqe is NULL for io_req %p\n", io_req); return; } @@ -1522,6 +1532,16 @@ le32_to_cpu(cqe->cqe_info.err_info.rx_buf_off), le32_to_cpu(cqe->cqe_info.err_info.rx_id)); + /* When flush is active, let the cmds be flushed out from the cleanup context */ + if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &io_req->fcport->flags) || + (test_bit(QEDF_RPORT_IN_LUN_RESET, &io_req->fcport->flags) && + io_req->sc_cmd->device->lun == (u64)io_req->fcport->lun_reset_lun)) { + QEDF_ERR(&qedf->dbg_ctx, + "Dropping EQE for xid=0x%x as fcport is flushing", + io_req->xid); + return; + } + if (qedf->stop_io_on_error) { qedf_stop_all_io(qedf); return; @@ -2233,6 +2253,7 @@ io_req->tm_flags == FCP_TMF_TGT_RESET) { clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags); io_req->sc_cmd = NULL; + kref_put(&io_req->refcount, qedf_release_cmd); complete(&io_req->tm_done); } @@ -2309,9 +2330,6 @@ io_req->fcport = fcport; io_req->cmd_type = QEDF_TASK_MGMT_CMD; - /* Record which cpu this request is associated with */ - io_req->cpu = smp_processor_id(); - /* Set TM flags */ io_req->io_req_flags = QEDF_READ; io_req->data_xfer_len = 0; @@ -2333,6 +2351,9 @@ spin_lock_irqsave(&fcport->rport_lock, flags); + /* Record which cpu this request is associated with */ + io_req->cpu = smp_processor_id(); + sqe_idx = qedf_get_sqe_idx(fcport); sqe = &fcport->sq[sqe_idx]; memset(sqe, 0, sizeof(struct fcoe_wqe)); --- linux-oracle-5.4.0.orig/drivers/scsi/qedf/qedf_main.c +++ linux-oracle-5.4.0/drivers/scsi/qedf/qedf_main.c @@ -668,7 +668,7 @@ rdata = fcport->rdata; if (!rdata || !kref_get_unless_zero(&rdata->kref)) { QEDF_ERR(&qedf->dbg_ctx, "stale rport, sc_cmd=%p\n", sc_cmd); - rc = 1; + rc = SUCCESS; goto out; } @@ -1729,22 +1729,20 @@ fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); QEDF_WARN(&(base_qedf->dbg_ctx), "Failed to create vport, " "WWPN (0x%s) already exists.\n", buf); - goto err1; + return rc; } if (atomic_read(&base_qedf->link_state) != QEDF_LINK_UP) { QEDF_WARN(&(base_qedf->dbg_ctx), "Cannot create vport " "because link is not up.\n"); - rc = -EIO; - goto err1; + return -EIO; } vn_port = libfc_vport_create(vport, sizeof(struct qedf_ctx)); if (!vn_port) { QEDF_WARN(&(base_qedf->dbg_ctx), "Could not create lport " "for vport.\n"); - rc = -ENOMEM; - goto err1; + return -ENOMEM; } fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); @@ -1768,7 +1766,7 @@ if (rc) { QEDF_ERR(&(base_qedf->dbg_ctx), "Could not allocate memory " "for lport stats.\n"); - goto err2; + goto err; } fc_set_wwnn(vn_port, vport->node_name); @@ -1786,7 +1784,7 @@ if (rc) { QEDF_WARN(&base_qedf->dbg_ctx, "Error adding Scsi_Host rc=0x%x.\n", rc); - goto err2; + goto err; } /* Set default dev_loss_tmo based on module parameter */ @@ -1827,9 +1825,10 @@ vport_qedf->dbg_ctx.host_no = vn_port->host->host_no; vport_qedf->dbg_ctx.pdev = base_qedf->pdev; -err2: + return 0; + +err: scsi_host_put(vn_port->host); -err1: return rc; } @@ -1870,8 +1869,7 @@ fc_lport_free_stats(vn_port); /* Release Scsi_Host */ - if (vn_port->host) - scsi_host_put(vn_port->host); + scsi_host_put(vn_port->host); out: return 0; @@ -2598,6 +2596,7 @@ sb_id, QED_SB_TYPE_STORAGE); if (ret) { + dma_free_coherent(&qedf->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys); QEDF_ERR(&qedf->dbg_ctx, "Status block initialization failed (0x%x) for id = %d.\n", ret, sb_id); @@ -2896,7 +2895,7 @@ { u32 *list; int i; - int status = 0, rc; + int status; u32 *pbl; dma_addr_t page; int num_pages; @@ -2908,7 +2907,7 @@ */ if (!qedf->num_queues) { QEDF_ERR(&(qedf->dbg_ctx), "No MSI-X vectors available!\n"); - return 1; + return -ENOMEM; } /* @@ -2916,9 +2915,8 @@ * addresses of our queues */ if (!qedf->p_cpuq) { - status = 1; QEDF_ERR(&qedf->dbg_ctx, "p_cpuq is NULL.\n"); - goto mem_alloc_failure; + return -EINVAL; } qedf->global_queues = kzalloc((sizeof(struct global_queue *) @@ -2932,8 +2930,8 @@ "qedf->global_queues=%p.\n", qedf->global_queues); /* Allocate DMA coherent buffers for BDQ */ - rc = qedf_alloc_bdq(qedf); - if (rc) { + status = qedf_alloc_bdq(qedf); + if (status) { QEDF_ERR(&qedf->dbg_ctx, "Unable to allocate bdq.\n"); goto mem_alloc_failure; } @@ -3153,7 +3151,7 @@ { int rc = -EINVAL; struct fc_lport *lport; - struct qedf_ctx *qedf; + struct qedf_ctx *qedf = NULL; struct Scsi_Host *host; bool is_vf = false; struct qed_ll2_params params; @@ -3183,6 +3181,7 @@ /* Initialize qedf_ctx */ qedf = lport_priv(lport); + set_bit(QEDF_PROBING, &qedf->flags); qedf->lport = lport; qedf->ctlr.lp = lport; qedf->pdev = pdev; @@ -3206,9 +3205,12 @@ } else { /* Init pointers during recovery */ qedf = pci_get_drvdata(pdev); + set_bit(QEDF_PROBING, &qedf->flags); lport = qedf->lport; } + QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, "Probe started.\n"); + host = lport->host; /* Allocate mempool for qedf_io_work structs */ @@ -3298,6 +3300,7 @@ } /* Start the Slowpath-process */ + memset(&slowpath_params, 0, sizeof(struct qed_slowpath_params)); slowpath_params.int_mode = QED_INT_MODE_MSIX; slowpath_params.drv_major = QEDF_DRIVER_MAJOR_VER; slowpath_params.drv_minor = QEDF_DRIVER_MINOR_VER; @@ -3513,6 +3516,10 @@ else fc_fabric_login(lport); + QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, "Probe done.\n"); + + clear_bit(QEDF_PROBING, &qedf->flags); + /* All good */ return 0; @@ -3687,11 +3694,25 @@ { struct qedf_ctx *qedf = dev; struct qed_mfw_tlv_fcoe *fcoe = data; - struct fc_lport *lport = qedf->lport; - struct Scsi_Host *host = lport->host; - struct fc_host_attrs *fc_host = shost_to_fc_host(host); + struct fc_lport *lport; + struct Scsi_Host *host; + struct fc_host_attrs *fc_host; struct fc_host_statistics *hst; + if (!qedf) { + QEDF_ERR(NULL, "qedf is null.\n"); + return; + } + + if (test_bit(QEDF_PROBING, &qedf->flags)) { + QEDF_ERR(&qedf->dbg_ctx, "Function is still probing.\n"); + return; + } + + lport = qedf->lport; + host = lport->host; + fc_host = shost_to_fc_host(host); + /* Force a refresh of the fc_host stats including offload stats */ hst = qedf_fc_get_host_stats(host); --- linux-oracle-5.4.0.orig/drivers/scsi/qedi/qedi_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/qedi/qedi_debugfs.c @@ -120,15 +120,11 @@ qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { - size_t cnt = 0; + char buf[64]; + int len; - if (*ppos) - return 0; - - cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover); - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + len = sprintf(buf, "do_not_recover=%d\n", qedi_do_not_recover); + return simple_read_from_buffer(buffer, count, ppos, buf, len); } static int --- linux-oracle-5.4.0.orig/drivers/scsi/qedi/qedi_fw.c +++ linux-oracle-5.4.0/drivers/scsi/qedi/qedi_fw.c @@ -59,6 +59,7 @@ "Freeing tid=0x%x for cid=0x%x\n", cmd->task_id, qedi_conn->iscsi_conn_id); + spin_lock(&qedi_conn->list_lock); if (likely(cmd->io_cmd_in_list)) { cmd->io_cmd_in_list = false; list_del_init(&cmd->io_cmd); @@ -69,6 +70,7 @@ cmd->task_id, qedi_conn->iscsi_conn_id, &cmd->io_cmd); } + spin_unlock(&qedi_conn->list_lock); cmd->state = RESPONSE_RECEIVED; qedi_clear_task_idx(qedi, cmd->task_id); @@ -122,6 +124,7 @@ "Freeing tid=0x%x for cid=0x%x\n", cmd->task_id, qedi_conn->iscsi_conn_id); + spin_lock(&qedi_conn->list_lock); if (likely(cmd->io_cmd_in_list)) { cmd->io_cmd_in_list = false; list_del_init(&cmd->io_cmd); @@ -132,6 +135,7 @@ cmd->task_id, qedi_conn->iscsi_conn_id, &cmd->io_cmd); } + spin_unlock(&qedi_conn->list_lock); cmd->state = RESPONSE_RECEIVED; qedi_clear_task_idx(qedi, cmd->task_id); @@ -222,11 +226,13 @@ tmf_hdr = (struct iscsi_tm *)qedi_cmd->task->hdr; + spin_lock(&qedi_conn->list_lock); if (likely(qedi_cmd->io_cmd_in_list)) { qedi_cmd->io_cmd_in_list = false; list_del_init(&qedi_cmd->io_cmd); qedi_conn->active_cmd_count--; } + spin_unlock(&qedi_conn->list_lock); if (((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) == ISCSI_TM_FUNC_LOGICAL_UNIT_RESET) || @@ -288,11 +294,13 @@ ISCSI_LOGIN_RESPONSE_HDR_DATA_SEG_LEN_MASK; qedi_conn->gen_pdu.resp_wr_ptr = qedi_conn->gen_pdu.resp_buf + pld_len; + spin_lock(&qedi_conn->list_lock); if (likely(cmd->io_cmd_in_list)) { cmd->io_cmd_in_list = false; list_del_init(&cmd->io_cmd); qedi_conn->active_cmd_count--; } + spin_unlock(&qedi_conn->list_lock); memset(task_ctx, '\0', sizeof(*task_ctx)); @@ -817,8 +825,11 @@ qedi_clear_task_idx(qedi_conn->qedi, rtid); spin_lock(&qedi_conn->list_lock); - list_del_init(&dbg_cmd->io_cmd); - qedi_conn->active_cmd_count--; + if (likely(dbg_cmd->io_cmd_in_list)) { + dbg_cmd->io_cmd_in_list = false; + list_del_init(&dbg_cmd->io_cmd); + qedi_conn->active_cmd_count--; + } spin_unlock(&qedi_conn->list_lock); qedi_cmd->state = CLEANUP_RECV; wake_up_interruptible(&qedi_conn->wait_queue); @@ -1236,6 +1247,7 @@ qedi_conn->cmd_cleanup_req++; qedi_iscsi_cleanup_task(ctask, true); + cmd->io_cmd_in_list = false; list_del_init(&cmd->io_cmd); qedi_conn->active_cmd_count--; QEDI_WARN(&qedi->dbg_ctx, @@ -1439,7 +1451,7 @@ ldel_exit: spin_lock_bh(&qedi_conn->tmf_work_lock); - if (!qedi_cmd->list_tmf_work) { + if (qedi_cmd->list_tmf_work) { list_del_init(&list_work->list); qedi_cmd->list_tmf_work = NULL; kfree(list_work); @@ -1447,8 +1459,11 @@ spin_unlock_bh(&qedi_conn->tmf_work_lock); spin_lock(&qedi_conn->list_lock); - list_del_init(&cmd->io_cmd); - qedi_conn->active_cmd_count--; + if (likely(cmd->io_cmd_in_list)) { + cmd->io_cmd_in_list = false; + list_del_init(&cmd->io_cmd); + qedi_conn->active_cmd_count--; + } spin_unlock(&qedi_conn->list_lock); clear_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); --- linux-oracle-5.4.0.orig/drivers/scsi/qedi/qedi_iscsi.c +++ linux-oracle-5.4.0/drivers/scsi/qedi/qedi_iscsi.c @@ -797,6 +797,37 @@ return qedi_iscsi_send_ioreq(task); } +static void qedi_offload_work(struct work_struct *work) +{ + struct qedi_endpoint *qedi_ep = + container_of(work, struct qedi_endpoint, offload_work); + struct qedi_ctx *qedi; + int wait_delay = 5 * HZ; + int ret; + + qedi = qedi_ep->qedi; + + ret = qedi_iscsi_offload_conn(qedi_ep); + if (ret) { + QEDI_ERR(&qedi->dbg_ctx, + "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n", + qedi_ep->iscsi_cid, qedi_ep, ret); + qedi_ep->state = EP_STATE_OFLDCONN_FAILED; + return; + } + + ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait, + (qedi_ep->state == + EP_STATE_OFLDCONN_COMPL), + wait_delay); + if (ret <= 0 || qedi_ep->state != EP_STATE_OFLDCONN_COMPL) { + qedi_ep->state = EP_STATE_OFLDCONN_FAILED; + QEDI_ERR(&qedi->dbg_ctx, + "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n", + qedi_ep->iscsi_cid, qedi_ep); + } +} + static struct iscsi_endpoint * qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, int non_blocking) @@ -840,6 +871,7 @@ } qedi_ep = ep->dd_data; memset(qedi_ep, 0, sizeof(struct qedi_endpoint)); + INIT_WORK(&qedi_ep->offload_work, qedi_offload_work); qedi_ep->state = EP_STATE_IDLE; qedi_ep->iscsi_cid = (u32)-1; qedi_ep->qedi = qedi; @@ -972,11 +1004,13 @@ { struct qedi_cmd *cmd, *cmd_tmp; + spin_lock(&qedi_conn->list_lock); list_for_each_entry_safe(cmd, cmd_tmp, &qedi_conn->active_cmd_list, io_cmd) { list_del_init(&cmd->io_cmd); qedi_conn->active_cmd_count--; } + spin_unlock(&qedi_conn->list_lock); } static void qedi_ep_disconnect(struct iscsi_endpoint *ep) @@ -994,11 +1028,11 @@ qedi_ep = ep->dd_data; qedi = qedi_ep->qedi; + flush_work(&qedi_ep->offload_work); + if (qedi_ep->state == EP_STATE_OFLDCONN_START) goto ep_exit_recover; - flush_work(&qedi_ep->offload_work); - if (qedi_ep->conn) { qedi_conn = qedi_ep->conn; conn = qedi_conn->cls_conn->dd_data; @@ -1061,6 +1095,9 @@ break; } + if (!abrt_conn) + wait_delay += qedi->pf_params.iscsi_pf_params.two_msl_timer; + qedi_ep->state = EP_STATE_DISCONN_START; ret = qedi_ops->destroy_conn(qedi->cdev, qedi_ep->handle, abrt_conn); if (ret) { @@ -1155,37 +1192,6 @@ return rc; } -static void qedi_offload_work(struct work_struct *work) -{ - struct qedi_endpoint *qedi_ep = - container_of(work, struct qedi_endpoint, offload_work); - struct qedi_ctx *qedi; - int wait_delay = 5 * HZ; - int ret; - - qedi = qedi_ep->qedi; - - ret = qedi_iscsi_offload_conn(qedi_ep); - if (ret) { - QEDI_ERR(&qedi->dbg_ctx, - "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n", - qedi_ep->iscsi_cid, qedi_ep, ret); - qedi_ep->state = EP_STATE_OFLDCONN_FAILED; - return; - } - - ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait, - (qedi_ep->state == - EP_STATE_OFLDCONN_COMPL), - wait_delay); - if ((ret <= 0) || (qedi_ep->state != EP_STATE_OFLDCONN_COMPL)) { - qedi_ep->state = EP_STATE_OFLDCONN_FAILED; - QEDI_ERR(&qedi->dbg_ctx, - "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n", - qedi_ep->iscsi_cid, qedi_ep); - } -} - static int qedi_set_path(struct Scsi_Host *shost, struct iscsi_path *path_data) { struct qedi_ctx *qedi; @@ -1214,6 +1220,10 @@ } iscsi_cid = (u32)path_data->handle; + if (iscsi_cid >= qedi->max_active_conns) { + ret = -EINVAL; + goto set_path_exit; + } qedi_ep = qedi->ep_tbl[iscsi_cid]; QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, "iscsi_cid=0x%x, qedi_ep=%p\n", iscsi_cid, qedi_ep); @@ -1297,7 +1307,6 @@ qedi_ep->dst_addr, qedi_ep->dst_port); } - INIT_WORK(&qedi_ep->offload_work, qedi_offload_work); queue_work(qedi->offload_thread, &qedi_ep->offload_work); ret = 0; --- linux-oracle-5.4.0.orig/drivers/scsi/qedi/qedi_main.c +++ linux-oracle-5.4.0/drivers/scsi/qedi/qedi_main.c @@ -359,6 +359,7 @@ ret = qedi_ops->common->sb_init(qedi->cdev, sb_info, sb_virt, sb_phys, sb_id, QED_SB_TYPE_STORAGE); if (ret) { + dma_free_coherent(&qedi->pdev->dev, sizeof(*sb_virt), sb_virt, sb_phys); QEDI_ERR(&qedi->dbg_ctx, "Status block initialization failed for id = %d.\n", sb_id); @@ -631,7 +632,7 @@ goto exit_setup_shost; } - shost->max_id = QEDI_MAX_ISCSI_CONNS_PER_HBA; + shost->max_id = QEDI_MAX_ISCSI_CONNS_PER_HBA - 1; shost->max_channel = 0; shost->max_lun = ~0; shost->max_cmd_len = 16; @@ -1553,7 +1554,7 @@ { u32 *list; int i; - int status = 0, rc; + int status; u32 *pbl; dma_addr_t page; int num_pages; @@ -1564,14 +1565,14 @@ */ if (!qedi->num_queues) { QEDI_ERR(&qedi->dbg_ctx, "No MSI-X vectors available!\n"); - return 1; + return -ENOMEM; } /* Make sure we allocated the PBL that will contain the physical * addresses of our queues */ if (!qedi->p_cpuq) { - status = 1; + status = -EINVAL; goto mem_alloc_failure; } @@ -1586,13 +1587,13 @@ "qedi->global_queues=%p.\n", qedi->global_queues); /* Allocate DMA coherent buffers for BDQ */ - rc = qedi_alloc_bdq(qedi); - if (rc) + status = qedi_alloc_bdq(qedi); + if (status) goto mem_alloc_failure; /* Allocate DMA coherent buffers for NVM_ISCSI_CFG */ - rc = qedi_alloc_nvm_iscsi_cfg(qedi); - if (rc) + status = qedi_alloc_nvm_iscsi_cfg(qedi); + if (status) goto mem_alloc_failure; /* Allocate a CQ and an associated PBL for each MSI-X @@ -1605,6 +1606,7 @@ if (!qedi->global_queues[i]) { QEDI_ERR(&qedi->dbg_ctx, "Unable to allocation global queue %d.\n", i); + status = -ENOMEM; goto mem_alloc_failure; } @@ -1909,8 +1911,9 @@ struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu); struct qedi_work *work, *tmp; struct task_struct *thread; + unsigned long flags; - spin_lock_bh(&p->p_work_lock); + spin_lock_irqsave(&p->p_work_lock, flags); thread = p->iothread; p->iothread = NULL; @@ -1921,7 +1924,7 @@ kfree(work); } - spin_unlock_bh(&p->p_work_lock); + spin_unlock_irqrestore(&p->p_work_lock, flags); if (thread) kthread_stop(thread); return 0; @@ -2175,7 +2178,7 @@ chap_name); break; case ISCSI_BOOT_TGT_CHAP_SECRET: - rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, + rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, chap_secret); break; case ISCSI_BOOT_TGT_REV_CHAP_NAME: @@ -2183,7 +2186,7 @@ mchap_name); break; case ISCSI_BOOT_TGT_REV_CHAP_SECRET: - rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_NAME_MAX_LEN, + rc = sprintf(buf, "%.*s\n", NVM_ISCSI_CFG_CHAP_PWD_MAX_LEN, mchap_secret); break; case ISCSI_BOOT_TGT_FLAGS: @@ -2630,7 +2633,7 @@ QEDI_ERR(&qedi->dbg_ctx, "Unable to start offload thread!\n"); rc = -ENODEV; - goto free_cid_que; + goto free_tmf_thread; } /* F/w needs 1st task context memory entry for performance */ @@ -2650,6 +2653,8 @@ return 0; +free_tmf_thread: + destroy_workqueue(qedi->tmf_thread); free_cid_que: qedi_release_cid_que(qedi); free_uio: --- linux-oracle-5.4.0.orig/drivers/scsi/qla1280.h +++ linux-oracle-5.4.0/drivers/scsi/qla1280.h @@ -117,12 +117,12 @@ uint16_t id_h; /* ID high */ uint16_t cfg_0; /* Configuration 0 */ #define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */ -#define ISP_CFG0_1020 BIT_0 /* ISP1020 */ -#define ISP_CFG0_1020A BIT_1 /* ISP1020A */ -#define ISP_CFG0_1040 BIT_2 /* ISP1040 */ -#define ISP_CFG0_1040A BIT_3 /* ISP1040A */ -#define ISP_CFG0_1040B BIT_4 /* ISP1040B */ -#define ISP_CFG0_1040C BIT_5 /* ISP1040C */ +#define ISP_CFG0_1020 1 /* ISP1020 */ +#define ISP_CFG0_1020A 2 /* ISP1020A */ +#define ISP_CFG0_1040 3 /* ISP1040 */ +#define ISP_CFG0_1040A 4 /* ISP1040A */ +#define ISP_CFG0_1040B 5 /* ISP1040B */ +#define ISP_CFG0_1040C 6 /* ISP1040C */ uint16_t cfg_1; /* Configuration 1 */ #define ISP_CFG1_F128 BIT_6 /* 128-byte FIFO threshold */ #define ISP_CFG1_F64 BIT_4|BIT_5 /* 128-byte FIFO threshold */ --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_attr.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_attr.c @@ -176,6 +176,7 @@ faddr = ha->flt_region_nvram; if (IS_QLA28XX(ha)) { + qla28xx_get_aux_images(vha, &active_regions); if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) faddr = ha->flt_region_nvram_sec; } @@ -526,7 +527,7 @@ if (!capable(CAP_SYS_ADMIN)) return -EINVAL; - if (IS_NOCACHE_VPD_TYPE(ha)) + if (!IS_NOCACHE_VPD_TYPE(ha)) goto skip; faddr = ha->flt_region_vpd << 2; @@ -709,7 +710,7 @@ ql_log(ql_log_info, vha, 0x706f, "Issuing MPI reset.\n"); - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + if (IS_QLA83XX(ha)) { uint32_t idc_control; qla83xx_idc_lock(vha, 0); @@ -1019,9 +1020,6 @@ continue; if (iter->type == 3 && !(IS_CNA_CAPABLE(ha))) continue; - if (iter->type == 0x27 && - (!IS_QLA27XX(ha) || !IS_QLA28XX(ha))) - continue; sysfs_remove_bin_file(&host->shost_gendev.kobj, iter->attr); @@ -1758,6 +1756,18 @@ return strlen(buf); } +static const struct { + u16 rate; + char *str; +} port_speed_str[] = { + { PORT_SPEED_4GB, "4" }, + { PORT_SPEED_8GB, "8" }, + { PORT_SPEED_16GB, "16" }, + { PORT_SPEED_32GB, "32" }, + { PORT_SPEED_64GB, "64" }, + { PORT_SPEED_10GB, "10" }, +}; + static ssize_t qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1765,7 +1775,8 @@ struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); struct qla_hw_data *ha = vha->hw; ssize_t rval; - char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"}; + u16 i; + char *speed = "Unknown"; rval = qla2x00_get_data_rate(vha); if (rval != QLA_SUCCESS) { @@ -1774,10 +1785,14 @@ return -EINVAL; } - ql_log(ql_log_info, vha, 0x70d6, - "port speed:%d\n", ha->link_data_rate); + for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) { + if (port_speed_str[i].rate != ha->link_data_rate) + continue; + speed = port_speed_str[i].str; + break; + } - return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); + return scnprintf(buf, PAGE_SIZE, "%s\n", speed); } /* ----- */ @@ -2559,6 +2574,7 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) { fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + scsi_qla_host_t *vha; if (!fcport) return; @@ -2568,9 +2584,12 @@ if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) return; + vha = fcport->vha; if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) { qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16); + qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, + 0, WAIT_TARGET); return; } /* @@ -2585,6 +2604,15 @@ else qla2x00_port_logout(fcport->vha, fcport); } + + /* check for any straggling io left behind */ + if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) { + ql_log(ql_log_warn, vha, 0x300b, + "IO not return. Resetting. \n"); + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + qla2x00_wait_for_chip_reset(vha); + } } static int @@ -2693,6 +2721,8 @@ vha->qla_stats.jiffies_at_last_reset = get_jiffies_64(); if (IS_FWI2_CAPABLE(ha)) { + int rval; + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, GFP_KERNEL); if (!stats) { @@ -2702,7 +2732,11 @@ } /* reset firmware statistics */ - qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + if (rval != QLA_SUCCESS) + ql_log(ql_log_warn, vha, 0x70de, + "Resetting ISP statistics failed: rval = %d\n", + rval); dma_free_coherent(&ha->pdev->dev, sizeof(*stats), stats, stats_dma); @@ -2830,8 +2864,6 @@ vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_user, vha, 0x7082, "Registered for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; scsi_host_set_prot(vha->host, prot | SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION @@ -2925,11 +2957,11 @@ test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) msleep(1000); - qla_nvme_delete(vha); qla24xx_disable_vp(vha); qla2x00_wait_for_sess_deletion(vha); + qla_nvme_delete(vha); vha->flags.delete_progress = 1; qlt_remove_target(ha, vha); @@ -3038,6 +3070,7 @@ .show_host_node_name = 1, .show_host_port_name = 1, .show_host_supported_classes = 1, + .show_host_supported_speeds = 1, .get_host_port_id = qla2x00_get_host_port_id, .show_host_port_id = 1, --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_bsg.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_bsg.c @@ -17,10 +17,11 @@ struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply; + sp->free(sp); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free(sp); } void qla2x00_bsg_sp_free(srb_t *sp) @@ -258,6 +259,10 @@ if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) { + rval = -ENOMEM; + goto done; + } fcport = *(fc_port_t **) rport->dd_data; host = rport_to_shost(rport); vha = shost_priv(host); @@ -292,7 +297,7 @@ "request_sg_cnt=%x reply_sg_cnt=%x.\n", bsg_job->request_payload.sg_cnt, bsg_job->reply_payload.sg_cnt); - rval = -EPERM; + rval = -ENOBUFS; goto done; } @@ -457,16 +462,6 @@ goto done; } - if ((req_sg_cnt != bsg_job->request_payload.sg_cnt) || - (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) { - ql_log(ql_log_warn, vha, 0x7011, - "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x " - "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt, - req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt); - rval = -EAGAIN; - goto done_unmap_sg; - } - if (!vha->flags.online) { ql_log(ql_log_warn, vha, 0x7012, "Host is not online.\n"); @@ -2399,7 +2394,7 @@ struct qla_active_regions regions = { }; struct active_regions active_regions = { }; - qla28xx_get_aux_images(vha, &active_regions); + qla27xx_get_active_image(vha, &active_regions); regions.global_image = active_regions.global; if (IS_QLA28XX(ha)) { @@ -2525,6 +2520,8 @@ if (bsg_request->msgcode == FC_BSG_RPT_ELS) { rport = fc_bsg_to_rport(bsg_job); + if (!rport) + return ret; host = rport_to_shost(rport); vha = shost_priv(host); } else { --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_dbg.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_dbg.c @@ -18,11 +18,11 @@ * | Device Discovery | 0x2134 | 0x210e-0x2116 | * | | | 0x211a | * | | | 0x211c-0x2128 | - * | | | 0x212a-0x2130 | + * | | | 0x212a-0x2134 | * | Queue Command and IO tracing | 0x3074 | 0x300b | * | | | 0x3027-0x3028 | * | | | 0x303d-0x3041 | - * | | | 0x302d,0x3033 | + * | | | 0x302e,0x3033 | * | | | 0x3036,0x3038 | * | | | 0x303a | * | DPC Thread | 0x4023 | 0x4002,0x4013 | @@ -2519,12 +2519,6 @@ /* Driver Debug Functions. */ /****************************************************************************/ -static inline int -ql_mask_match(uint level) -{ - return (level & ql2xextended_error_logging) == level; -} - /* * This function is for formatting and logging debug information. * It is to be used when vha is available. It formats the message --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_dbg.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_dbg.h @@ -374,3 +374,9 @@ extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *, struct qla_hw_data *); extern int qla24xx_soft_reset(struct qla_hw_data *); + +static inline int +ql_mask_match(uint level) +{ + return (level & ql2xextended_error_logging) == level; +} --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_def.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_def.h @@ -591,19 +591,19 @@ */ uint8_t cmd_type; uint8_t pad[3]; - atomic_t ref_count; struct kref cmd_kref; /* need to migrate ref_count over to this */ void *priv; - wait_queue_head_t nvme_ls_waitq; struct fc_port *fcport; struct scsi_qla_host *vha; unsigned int start_timer:1; + uint32_t handle; uint16_t flags; uint16_t type; const char *name; int iocbs; struct qla_qpair *qpair; + struct srb *cmd_sp; struct list_head elem; u32 gen1; /* scratch */ u32 gen2; /* scratch */ @@ -2277,7 +2277,7 @@ uint8_t fabric_port_name[WWN_SIZE]; uint16_t fp_speed; uint8_t fc4_type; - uint8_t fc4f_nvme; /* nvme fc4 feature bits */ + uint8_t fc4_features; } sw_info_t; /* FCP-4 types */ @@ -2397,6 +2397,8 @@ unsigned int id_changed:1; unsigned int scan_needed:1; unsigned int n2n_flag:1; + unsigned int explicit_logout:1; + unsigned int prli_pend_timer:1; struct completion nvme_del_done; uint32_t nvme_prli_service_param; @@ -2423,6 +2425,7 @@ struct work_struct free_work; struct work_struct reg_work; uint64_t jiffies_at_registration; + unsigned long prli_expired; struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX]; uint16_t tgt_id; @@ -2445,7 +2448,7 @@ u32 supported_classes; uint8_t fc4_type; - uint8_t fc4f_nvme; + uint8_t fc4_features; uint8_t scan_state; unsigned long last_queue_full; @@ -2459,6 +2462,7 @@ struct qla_tgt_sess *tgt_session; struct ct_sns_desc ct_desc; enum discovery_state disc_state; + atomic_t shadow_disc_state; enum discovery_state next_disc_state; enum login_state fw_login_state; unsigned long dm_login_expire; @@ -2476,6 +2480,9 @@ u16 n2n_chip_reset; } fc_port_t; +#define FC4_PRIORITY_NVME 0 +#define FC4_PRIORITY_FCP 1 + #define QLA_FCPORT_SCAN 1 #define QLA_FCPORT_FOUND 2 @@ -2500,6 +2507,19 @@ extern const char *const port_state_str[5]; +static const char * const port_dstate_str[] = { + "DELETED", + "GNN_ID", + "GNL", + "LOGIN_PEND", + "LOGIN_FAILED", + "GPDB", + "UPD_FCPORT", + "LOGIN_COMPLETE", + "ADISC", + "DELETE_PEND" +}; + /* * FC port flags. */ @@ -2701,7 +2721,11 @@ #define FDMI_PORT_SPEED_8GB 0x10 #define FDMI_PORT_SPEED_16GB 0x20 #define FDMI_PORT_SPEED_32GB 0x40 -#define FDMI_PORT_SPEED_64GB 0x80 +#define FDMI_PORT_SPEED_20GB 0x80 +#define FDMI_PORT_SPEED_40GB 0x100 +#define FDMI_PORT_SPEED_128GB 0x200 +#define FDMI_PORT_SPEED_64GB 0x400 +#define FDMI_PORT_SPEED_256GB 0x800 #define FDMI_PORT_SPEED_UNKNOWN 0x8000 #define FC_CLASS_2 0x04 @@ -3871,8 +3895,8 @@ #define IS_OEM_001(ha) ((ha)->device_type & DT_OEM_001) #define HAS_EXTENDED_IDS(ha) ((ha)->device_type & DT_EXTENDED_IDS) #define IS_CT6_SUPPORTED(ha) ((ha)->device_type & DT_CT6_SUPPORTED) -#define IS_MQUE_CAPABLE(ha) ((ha)->mqenable || IS_QLA83XX(ha) || \ - IS_QLA27XX(ha) || IS_QLA28XX(ha)) +#define IS_MQUE_CAPABLE(ha) (IS_QLA83XX(ha) || IS_QLA27XX(ha) || \ + IS_QLA28XX(ha)) #define IS_BIDI_CAPABLE(ha) \ (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) /* Bit 21 of fw_attributes decides the MCTP capabilities */ @@ -4291,6 +4315,8 @@ atomic_t nvme_active_aen_cnt; uint16_t nvme_last_rptd_aen; /* Last recorded aen count */ + uint8_t fc4_type_priority; + atomic_t zio_threshold; uint16_t last_zio_threshold; @@ -4816,8 +4842,34 @@ ha->current_topology == ISP_CFG_N || \ !ha->current_topology) +#define QLA_N2N_WAIT_TIME 5 /* 2 * ra_tov(n2n) + 1 */ + +#define NVME_TYPE(fcport) \ + (fcport->fc4_type & FS_FC4TYPE_NVME) \ + +#define FCP_TYPE(fcport) \ + (fcport->fc4_type & FS_FC4TYPE_FCP) \ + +#define NVME_ONLY_TARGET(fcport) \ + (NVME_TYPE(fcport) && !FCP_TYPE(fcport)) \ + +#define NVME_FCP_TARGET(fcport) \ + (FCP_TYPE(fcport) && NVME_TYPE(fcport)) \ + +#define NVME_TARGET(ha, fcport) \ + ((NVME_FCP_TARGET(fcport) && \ + (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \ + NVME_ONLY_TARGET(fcport)) \ + +#define PRLI_PHASE(_cls) \ + ((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP)) + #include "qla_target.h" #include "qla_gbl.h" #include "qla_dbg.h" #include "qla_inline.h" + +#define IS_SESSION_DELETED(_fcport) (_fcport->disc_state == DSC_DELETE_PEND || \ + _fcport->disc_state == DSC_DELETED) + #endif --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_fw.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_fw.h @@ -1523,6 +1523,10 @@ #define FLT_REG_NVRAM_SEC_28XX_1 0x10F #define FLT_REG_NVRAM_SEC_28XX_2 0x111 #define FLT_REG_NVRAM_SEC_28XX_3 0x113 +#define FLT_REG_MPI_PRI_28XX 0xD3 +#define FLT_REG_MPI_SEC_28XX 0xF0 +#define FLT_REG_PEP_PRI_28XX 0xD1 +#define FLT_REG_PEP_SEC_28XX 0xF1 struct qla_flt_region { uint16_t code; @@ -2101,4 +2105,6 @@ #define FA_FLASH_LAYOUT_ADDR_83 (0x3F1000/4) #define FA_FLASH_LAYOUT_ADDR_28 (0x11000/4) +#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET 0x196 + #endif --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_gbl.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_gbl.h @@ -80,6 +80,7 @@ int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e); extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *); extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state); extern fc_port_t * @@ -155,7 +156,6 @@ extern int ql2xgffidenable; extern int ql2xenabledif; extern int ql2xenablehba_err_chk; -extern int ql2xtargetreset; extern int ql2xdontresethba; extern uint64_t ql2xmaxlun; extern int ql2xmdcapmask; @@ -255,6 +255,7 @@ extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); @@ -396,7 +397,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *); extern int -qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); +qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map, + u8 *num_entries); extern int qla2x00_get_link_status(scsi_qla_host_t *, uint16_t, struct link_statistics *, @@ -768,7 +770,6 @@ extern void qlafx00_fxdisc_iocb(srb_t *, struct fxdisc_entry_fx00 *); extern void qlafx00_timer_routine(scsi_qla_host_t *); extern int qlafx00_rescan_isp(scsi_qla_host_t *); -extern int qlafx00_loop_reset(scsi_qla_host_t *vha); /* qla82xx related functions */ @@ -917,4 +918,5 @@ /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); +void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea); #endif /* _QLA_GBL_H */ --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_gs.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_gs.c @@ -248,7 +248,7 @@ WWN_SIZE); fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ? - FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER; + FS_FC4TYPE_FCP : FC4_TYPE_OTHER; if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) @@ -675,8 +675,7 @@ return (QLA_SUCCESS); } - return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha), - FC4_TYPE_FCP_SCSI); + return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha), type); } static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id, @@ -726,7 +725,7 @@ /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ ct_req->req.rff_id.port_id = port_id_to_be_id(*d_id); ct_req->req.rff_id.fc4_feature = fc4feature; - ct_req->req.rff_id.fc4_type = fc4type; /* SCSI - FCP */ + ct_req->req.rff_id.fc4_type = fc4type; /* SCSI-FCP or FC-NVMe */ sp->u.iocb_cmd.u.ctarg.req_size = RFF_ID_REQ_SIZE; sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE; @@ -2887,7 +2886,7 @@ struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; struct qla_hw_data *ha = vha->hw; - uint8_t fcp_scsi_features = 0; + uint8_t fcp_scsi_features = 0, nvme_features = 0; struct ct_arg arg; for (i = 0; i < ha->max_fibre_devices; i++) { @@ -2933,14 +2932,19 @@ ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; fcp_scsi_features &= 0x0f; - if (fcp_scsi_features) - list[i].fc4_type = FC4_TYPE_FCP_SCSI; - else - list[i].fc4_type = FC4_TYPE_OTHER; + if (fcp_scsi_features) { + list[i].fc4_type = FS_FC4TYPE_FCP; + list[i].fc4_features = fcp_scsi_features; + } - list[i].fc4f_nvme = + nvme_features = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; - list[i].fc4f_nvme &= 0xf; + nvme_features &= 0xf; + + if (nvme_features) { + list[i].fc4_type |= FS_FC4TYPE_NVME; + list[i].fc4_features = nvme_features; + } } /* Last device exit. */ @@ -3005,7 +3009,7 @@ fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); if (res == QLA_FUNCTION_TIMEOUT) - return; + goto done; if (res == (DID_ERROR << 16)) { /* entry status error */ @@ -3435,6 +3439,8 @@ fc_port_t *fcport = sp->fcport; struct ct_sns_rsp *ct_rsp; struct event_arg ea; + uint8_t fc4_scsi_feat; + uint8_t fc4_nvme_feat; ql_dbg(ql_dbg_disc, vha, 0x2133, "Async done-%s res %x ID %x. %8phC\n", @@ -3442,24 +3448,25 @@ fcport->flags &= ~FCF_ASYNC_SENT; ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; + fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; + fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; + /* * FC-GS-7, 5.2.3.12 FC-4 Features - format * The format of the FC-4 Features object, as defined by the FC-4, * Shall be an array of 4-bit values, one for each type code value */ if (!res) { - if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { + if (fc4_scsi_feat & 0xf) { /* w1 b00:03 */ - fcport->fc4_type = - ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; - fcport->fc4_type &= 0xf; - } + fcport->fc4_type = FS_FC4TYPE_FCP; + fcport->fc4_features = fc4_scsi_feat & 0xf; + } - if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { + if (fc4_nvme_feat & 0xf) { /* w5 [00:03]/28h */ - fcport->fc4f_nvme = - ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; - fcport->fc4f_nvme &= 0xf; + fcport->fc4_type |= FS_FC4TYPE_NVME; + fcport->fc4_features = fc4_nvme_feat & 0xf; } } @@ -3638,7 +3645,9 @@ qla2x00_clear_loop_id(fcport); fcport->flags |= FCF_FABRIC_DEVICE; } else if (fcport->d_id.b24 != rp->id.b24 || - fcport->scan_needed) { + (fcport->scan_needed && + fcport->port_type != FCT_INITIATOR && + fcport->port_type != FCT_NVME_INITIATOR)) { qlt_schedule_sess_for_deletion(fcport); } fcport->d_id.b24 = rp->id.b24; @@ -3671,10 +3680,22 @@ } if (fcport->scan_state != QLA_FCPORT_FOUND) { + bool do_delete = false; + + if (fcport->scan_needed && + fcport->disc_state == DSC_LOGIN_PEND) { + /* Cable got disconnected after we sent + * a login. Do delete to prevent timeout. + */ + fcport->logout_on_delete = 1; + do_delete = true; + } + fcport->scan_needed = 0; - if ((qla_dual_mode_enabled(vha) || - qla_ini_mode_enabled(vha)) && - atomic_read(&fcport->state) == FCS_ONLINE) { + if (((qla_dual_mode_enabled(vha) || + qla_ini_mode_enabled(vha)) && + atomic_read(&fcport->state) == FCS_ONLINE) || + do_delete) { if (fcport->loop_id != FC_NO_LOOP_ID) { if (fcport->flags & FCF_FCP2_DEVICE) fcport->logout_on_delete = 0; @@ -4268,7 +4289,7 @@ if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) return rval; - fcport->disc_state = DSC_GNN_ID; + qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID); sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); if (!sp) goto done; --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_init.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_init.c @@ -50,16 +50,9 @@ { srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer); struct srb_iocb *iocb; - struct req_que *req; - unsigned long flags; - struct qla_hw_data *ha = sp->vha->hw; - WARN_ON_ONCE(irqs_disabled()); - spin_lock_irqsave(&ha->hardware_lock, flags); - req = sp->qpair->req; - req->outstanding_cmds[sp->handle] = NULL; + WARN_ON(irqs_disabled()); iocb = &sp->u.iocb_cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); iocb->timeout(sp); } @@ -71,6 +64,16 @@ qla2x00_rel_sp(sp); } +void qla2xxx_rel_done_warning(srb_t *sp, int res) +{ + WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp); +} + +void qla2xxx_rel_free_warning(srb_t *sp) +{ + WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp); +} + /* Asynchronous Login/Logout Routines -------------------------------------- */ unsigned long @@ -101,8 +104,22 @@ u32 handle; unsigned long flags; + if (sp->cmd_sp) + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n", + sp->cmd_sp->handle, sp->cmd_sp->type, + sp->handle, sp->type); + else + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout 2 - hdl=%x, type=%x\n", + sp->handle, sp->type); + spin_lock_irqsave(qpair->qp_lock_ptr, flags); for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { + if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] == + sp->cmd_sp)) + qpair->req->outstanding_cmds[handle] = NULL; + /* removing the abort */ if (qpair->req->outstanding_cmds[handle] == sp) { qpair->req->outstanding_cmds[handle] = NULL; @@ -111,6 +128,9 @@ } spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + if (sp->cmd_sp) + sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); + abt->u.abt.comp_status = CS_TIMEOUT; sp->done(sp, QLA_OS_TIMER_EXPIRED); } @@ -126,7 +146,7 @@ sp->free(sp); } -static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) +int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) { scsi_qla_host_t *vha = cmd_sp->vha; struct srb_iocb *abt_iocb; @@ -142,6 +162,7 @@ sp->type = SRB_ABT_CMD; sp->name = "abort"; sp->qpair = cmd_sp->qpair; + sp->cmd_sp = cmd_sp; if (wait) sp->flags = SRB_WAKEUP_ON_COMP; @@ -225,6 +246,7 @@ case SRB_NACK_PRLI: case SRB_NACK_LOGO: case SRB_CTRL_VP: + default: rc = qla24xx_async_abort_cmd(sp, false); if (rc) { spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); @@ -241,10 +263,6 @@ sp->done(sp, QLA_FUNCTION_TIMEOUT); } break; - default: - WARN_ON_ONCE(true); - sp->done(sp, QLA_FUNCTION_TIMEOUT); - break; } } @@ -309,10 +327,10 @@ if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); fcport->flags |= FCF_ASYNC_SENT; fcport->logout_completed = 0; - fcport->disc_state = DSC_LOGIN_PEND; sp->type = SRB_LOGIN_CMD; sp->name = "login"; sp->gen1 = fcport->rscn_gen; @@ -328,7 +346,7 @@ else lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; ql_dbg(ql_dbg_disc, vha, 0x2072, @@ -467,6 +485,7 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea) { struct fc_port *fcport = ea->fcport; + unsigned long flags; ql_dbg(ql_dbg_disc, vha, 0x20d2, "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", @@ -481,9 +500,15 @@ ql_dbg(ql_dbg_disc, vha, 0x2066, "%s %8phC: adisc fail: post delete\n", __func__, ea->fcport->port_name); + + spin_lock_irqsave(&vha->work_lock, flags); /* deleted = 0 & logout_on_delete = force fw cleanup */ - fcport->deleted = 0; + if (fcport->deleted == QLA_SESS_DELETED) + fcport->deleted = 0; + fcport->logout_on_delete = 1; + spin_unlock_irqrestore(&vha->work_lock, flags); + qlt_schedule_sess_for_deletion(ea->fcport); return; } @@ -516,6 +541,7 @@ e->u.fcport.fcport = fcport; fcport->flags |= FCF_ASYNC_ACTIVE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); return qla2x00_post_work(vha, e); } @@ -553,6 +579,14 @@ struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; + if (IS_SESSION_DELETED(fcport)) { + ql_log(ql_log_warn, vha, 0xffff, + "%s: %8phC is being delete - not sending command.\n", + __func__, fcport->port_name); + fcport->flags &= ~FCF_ASYNC_ACTIVE; + return rval; + } + if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) return rval; @@ -667,7 +701,7 @@ port_id_t id; u64 wwn; u16 data[2]; - u8 current_login_state; + u8 current_login_state, nvme_cls; fcport = ea->fcport; ql_dbg(ql_dbg_disc, vha, 0xffff, @@ -726,19 +760,24 @@ loop_id = le16_to_cpu(e->nport_handle); loop_id = (loop_id & 0x7fff); - if (fcport->fc4f_nvme) - current_login_state = e->current_login_state >> 4; - else - current_login_state = e->current_login_state & 0xf; + nvme_cls = e->current_login_state >> 4; + current_login_state = e->current_login_state & 0xf; + if (PRLI_PHASE(nvme_cls)) { + current_login_state = nvme_cls; + fcport->fc4_type &= ~FS_FC4TYPE_FCP; + fcport->fc4_type |= FS_FC4TYPE_NVME; + } else if (PRLI_PHASE(current_login_state)) { + fcport->fc4_type |= FS_FC4TYPE_FCP; + fcport->fc4_type &= ~FS_FC4TYPE_NVME; + } ql_dbg(ql_dbg_disc, vha, 0x20e2, - "%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n", + "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n", __func__, fcport->port_name, e->current_login_state, fcport->fw_login_state, - fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, loop_id, fcport->loop_id); + fcport->fc4_type, id.b24, fcport->d_id.b24, + loop_id, fcport->loop_id); switch (fcport->disc_state) { case DSC_DELETE_PEND: @@ -820,7 +859,8 @@ * with GNL. Push disc_state back to DELETED * so GNL can go out again */ - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, + DSC_DELETED); break; case DSC_LS_PRLI_COMP: if ((e->prli_svc_param_word_3[0] & BIT_4) == 0) @@ -896,7 +936,7 @@ qla24xx_fcport_handle_login(vha, fcport); break; case ISP_CFG_N: - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, DSC_DELETED); if (time_after_eq(jiffies, fcport->dm_login_expire)) { if (fcport->n2n_link_reset_cnt < 2) { fcport->n2n_link_reset_cnt++; @@ -930,6 +970,9 @@ set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } break; + case ISP_CFG_NL: + qla24xx_fcport_handle_login(vha, fcport); + break; default: break; } @@ -953,8 +996,6 @@ sp->name, res, sp->u.iocb_cmd.u.mbx.in_mb[1], sp->u.iocb_cmd.u.mbx.in_mb[2]); - if (res == QLA_FUNCTION_TIMEOUT) - return; sp->fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE); memset(&ea, 0, sizeof(ea)); @@ -976,7 +1017,7 @@ set_bit(loop_id, vha->hw->loop_id_map); wwn = wwn_to_u64(e->port_name); - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8, + ql_dbg(ql_dbg_disc, vha, 0x20e8, "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n", __func__, (void *)&wwn, e->port_id[2], e->port_id[1], e->port_id[0], e->current_login_state, e->last_login_state, @@ -992,8 +1033,8 @@ spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { - list_del_init(&fcport->gnl_entry); spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); + list_del_init(&fcport->gnl_entry); fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); ea.fcport = fcport; @@ -1035,6 +1076,16 @@ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); vha->gnl.sent = 0; + if (!list_empty(&vha->gnl.fcports)) { + /* retrigger gnl */ + list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports, + gnl_entry) { + list_del_init(&fcport->gnl_entry); + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS) + break; + } + } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); sp->free(sp); @@ -1056,7 +1107,7 @@ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); fcport->flags |= FCF_ASYNC_SENT; - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; @@ -1135,19 +1186,18 @@ "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", sp->name, res, fcport->port_name, mb[1], mb[2]); - if (res == QLA_FUNCTION_TIMEOUT) { - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - return; - } - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + + if (res == QLA_FUNCTION_TIMEOUT) + goto done; + memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; ea.sp = sp; qla24xx_handle_gpdb_event(vha, &ea); +done: dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, sp->u.iocb_cmd.u.mbx.in_dma); @@ -1201,12 +1251,19 @@ struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; - if (!vha->flags.online) + if (!vha->flags.online) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } - if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || - fcport->fw_login_state == DSC_LS_PRLI_PEND) + if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND || + fcport->fw_login_state == DSC_LS_PRLI_PEND) && + qla_dual_mode_enabled(vha)) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) @@ -1225,13 +1282,14 @@ sp->done = qla2x00_async_prli_sp_done; lio->u.logio.flags = 0; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI; ql_dbg(ql_dbg_disc, vha, 0x211b, - "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n", + "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n", fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24, - fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc"); + fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority, + NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp"); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -1272,20 +1330,27 @@ struct port_database_24xx *pd; struct qla_hw_data *ha = vha->hw; - if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) || - fcport->loop_id == FC_NO_LOOP_ID) { + if (IS_SESSION_DELETED(fcport)) { ql_log(ql_log_warn, vha, 0xffff, - "%s: %8phC - not sending command.\n", - __func__, fcport->port_name); + "%s: %8phC is being delete - not sending command.\n", + __func__, fcport->port_name); + fcport->flags &= ~FCF_ASYNC_ACTIVE; return rval; } - fcport->disc_state = DSC_GPDB; + if (!vha->flags.online || fcport->flags & FCF_ASYNC_SENT) { + ql_log(ql_log_warn, vha, 0xffff, + "%s: %8phC online %d flags %x - not sending command.\n", + __func__, fcport->port_name, vha->flags.online, fcport->flags); + goto done; + } sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_GPDB); + fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_MB_IOCB; sp->name = "gpdb"; @@ -1345,7 +1410,6 @@ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); ea->fcport->login_gen++; - ea->fcport->deleted = 0; ea->fcport->logout_on_delete = 1; if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) { @@ -1364,7 +1428,7 @@ ql_dbg(ql_dbg_disc, vha, 0x20d6, "%s %d %8phC session revalidate success\n", __func__, __LINE__, ea->fcport->port_name); - ea->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE); } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); } @@ -1382,14 +1446,14 @@ fcport->flags &= ~FCF_ASYNC_SENT; ql_dbg(ql_dbg_disc, vha, 0x20d2, - "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name, - fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme, - ea->rc); + "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__, + fcport->port_name, fcport->disc_state, pd->current_login_state, + fcport->fc4_type, ea->rc); if (fcport->disc_state == DSC_DELETE_PEND) return; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) ls = pd->current_login_state >> 4; else ls = pd->current_login_state & 0xf; @@ -1418,7 +1482,7 @@ /* Set discovery state back to GNL to Relogin attempt */ if (qla_dual_mode_enabled(vha) || qla_ini_mode_enabled(vha)) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } return; @@ -1438,6 +1502,11 @@ u8 login = 0; int rc; + ql_dbg(ql_dbg_disc, vha, 0x307b, + "%s %8phC DS %d LS %d lid %d retries=%d\n", + __func__, fcport->port_name, fcport->disc_state, + fcport->fw_login_state, fcport->loop_id, fcport->login_retry); + if (qla_tgt_mode_enabled(vha)) return; @@ -1495,7 +1564,8 @@ fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen, fcport->login_gen, fcport->loop_id, fcport->scan_state); - if (fcport->scan_state != QLA_FCPORT_FOUND) + if (fcport->scan_state != QLA_FCPORT_FOUND || + fcport->disc_state == DSC_DELETE_PEND) return 0; if ((fcport->loop_id != FC_NO_LOOP_ID) && @@ -1516,7 +1586,7 @@ if (vha->host->active_mode == MODE_TARGET) return 0; - if (fcport->flags & FCF_ASYNC_SENT) { + if (fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE)) { set_bit(RELOGIN_NEEDED, &vha->dpc_flags); return 0; } @@ -1578,12 +1648,17 @@ ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %8phC post %s PRLI\n", __func__, __LINE__, fcport->port_name, - fcport->fc4f_nvme ? "NVME" : "FC"); + NVME_TARGET(vha->hw, fcport) ? "NVME" : + "FC"); qla24xx_post_prli_work(vha, fcport); } break; default: if (fcport->login_pause) { + ql_dbg(ql_dbg_disc, vha, 0x20d8, + "%s %d %8phC exit\n", + __func__, __LINE__, + fcport->port_name); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); @@ -1701,6 +1776,15 @@ qla24xx_fcport_handle_login(vha, fcport); } +void qla_handle_els_plogi_done(scsi_qla_host_t *vha, + struct event_arg *ea) +{ + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post PRLI\n", + __func__, __LINE__, ea->fcport->port_name); + qla24xx_post_prli_work(vha, ea->fcport); +} + /* * RSCN(s) came in for this fcport, but the RSCN(s) was not able * to be consumed by the fcport @@ -1729,9 +1813,23 @@ { srb_t *sp = data; struct srb_iocb *tmf = &sp->u.iocb_cmd; + int rc, h; + unsigned long flags; - tmf->u.tmf.comp_status = CS_TIMEOUT; - complete(&tmf->u.tmf.comp); + rc = qla24xx_async_abort_cmd(sp, false); + if (rc) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + tmf->u.tmf.comp_status = CS_TIMEOUT; + tmf->u.tmf.data = QLA_FUNCTION_FAILED; + complete(&tmf->u.tmf.comp); + } } static void qla2x00_tmf_sp_done(srb_t *sp, int res) @@ -1860,36 +1958,56 @@ break; } - if (ea->fcport->fc4f_nvme) { - ql_dbg(ql_dbg_disc, vha, 0x2118, - "%s %d %8phC post fc4 prli\n", - __func__, __LINE__, ea->fcport->port_name); - ea->fcport->fc4f_nvme = 0; - qla24xx_post_prli_work(vha, ea->fcport); - return; - } + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC priority %s, fc4type %x\n", + __func__, __LINE__, ea->fcport->port_name, + vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ? + "FCP" : "NVMe", ea->fcport->fc4_type); - /* at this point both PRLI NVME & PRLI FCP failed */ if (N2N_TOPO(vha->hw)) { + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) { + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + ea->fcport->fc4_type |= FS_FC4TYPE_FCP; + } else { + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; + ea->fcport->fc4_type |= FS_FC4TYPE_NVME; + } + if (ea->fcport->n2n_link_reset_cnt < 3) { ea->fcport->n2n_link_reset_cnt++; + vha->relogin_jif = jiffies + 2 * HZ; /* - * remote port is not sending Plogi. Reset - * link to kick start his state machine + * PRLI failed. Reset link to kick start + * state machine */ set_bit(N2N_LINK_RESET, &vha->dpc_flags); } else { ql_log(ql_log_warn, vha, 0x2119, - "%s %d %8phC Unable to reconnect\n", - __func__, __LINE__, ea->fcport->port_name); + "%s %d %8phC Unable to reconnect\n", + __func__, __LINE__, + ea->fcport->port_name); } } else { /* - * switch connect. login failed. Take connection - * down and allow relogin to retrigger + * switch connect. login failed. Take connection down + * and allow relogin to retrigger */ + if (NVME_FCP_TARGET(ea->fcport)) { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post %s prli\n", + __func__, __LINE__, + ea->fcport->port_name, + (ea->fcport->fc4_type & FS_FC4TYPE_NVME) + ? "NVMe" : "FCP"); + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + else + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; + } + ea->fcport->flags &= ~FCF_ASYNC_SENT; ea->fcport->keep_nport_handle = 0; + ea->fcport->logout_on_delete = 1; qlt_schedule_sess_for_deletion(ea->fcport); } break; @@ -1952,14 +2070,14 @@ * force a relogin attempt via implicit LOGO, PLOGI, and PRLI * requests. */ - if (ea->fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, ea->fcport)) { ql_dbg(ql_dbg_disc, vha, 0x2117, "%s %d %8phC post prli\n", __func__, __LINE__, ea->fcport->port_name); qla24xx_post_prli_work(vha, ea->fcport); } else { ql_dbg(ql_dbg_disc, vha, 0x20ea, - "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n", + "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n", __func__, __LINE__, ea->fcport->port_name, ea->fcport->loop_id, ea->fcport->d_id.b24); @@ -1979,7 +2097,7 @@ __func__, __LINE__, ea->fcport->port_name, ea->data[1]); ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_FAILED); if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED) set_bit(RELOGIN_NEEDED, &vha->dpc_flags); else @@ -2030,6 +2148,7 @@ set_bit(lid, vha->hw->loop_id_map); ea->fcport->loop_id = lid; ea->fcport->keep_nport_handle = 0; + ea->fcport->logout_on_delete = 1; qlt_schedule_sess_for_deletion(ea->fcport); } break; @@ -3167,6 +3286,14 @@ struct rsp_que *rsp = ha->rsp_q_map[0]; struct qla2xxx_fw_dump *fw_dump; + if (ha->fw_dump) { + ql_dbg(ql_dbg_init, vha, 0x00bd, + "Firmware dump already allocated.\n"); + return; + } + + ha->fw_dumped = 0; + ha->fw_dump_cap_flags = 0; dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; req_q_size = rsp_q_size = 0; @@ -3177,7 +3304,7 @@ mem_size = (ha->fw_memory_size - 0x11000 + 1) * sizeof(uint16_t); } else if (IS_FWI2_CAPABLE(ha)) { - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) + if (IS_QLA83XX(ha)) fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem); else if (IS_QLA81XX(ha)) fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem); @@ -3189,8 +3316,7 @@ mem_size = (ha->fw_memory_size - 0x100000 + 1) * sizeof(uint32_t); if (ha->mqenable) { - if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha) && - !IS_QLA28XX(ha)) + if (!IS_QLA83XX(ha)) mq_size = sizeof(struct qla2xxx_mq_chain); /* * Allocate maximum buffer size for all queues - Q0. @@ -3687,8 +3813,7 @@ ha->fw_major_version, ha->fw_minor_version, ha->fw_subminor_version); - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || - IS_QLA28XX(ha)) { + if (IS_QLA83XX(ha)) { ha->flags.fac_supported = 0; rval = QLA_SUCCESS; } @@ -4090,15 +4215,16 @@ (ha->flags.fawwpn_enabled) ? "enabled" : "disabled"); } + QLA_FW_STARTED(ha); rval = qla2x00_init_firmware(vha, ha->init_cb_size); next_check: if (rval) { + QLA_FW_STOPPED(ha); ql_log(ql_log_fatal, vha, 0x00d2, "Init Firmware **** FAILED ****.\n"); } else { ql_dbg(ql_dbg_init, vha, 0x00d3, "Init Firmware -- success.\n"); - QLA_FW_STARTED(ha); vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0; } @@ -4386,7 +4512,7 @@ if (use_tbl && ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) - strlcpy(ha->model_desc, + strscpy(ha->model_desc, qla2x00_model_name[index * 2 + 1], sizeof(ha->model_desc)); } else { @@ -4394,14 +4520,14 @@ if (use_tbl && ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && index < QLA_MODEL_NAMES) { - strlcpy(ha->model_number, + strscpy(ha->model_number, qla2x00_model_name[index * 2], sizeof(ha->model_number)); - strlcpy(ha->model_desc, + strscpy(ha->model_desc, qla2x00_model_name[index * 2 + 1], sizeof(ha->model_desc)); } else { - strlcpy(ha->model_number, def, + strscpy(ha->model_number, def, sizeof(ha->model_number)); } } @@ -4830,6 +4956,7 @@ } INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); + INIT_WORK(&fcport->free_work, qlt_free_session_done); INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); @@ -4908,14 +5035,8 @@ set_bit(RSCN_UPDATE, &flags); clear_bit(LOCAL_LOOP_UPDATE, &flags); - } else if (ha->current_topology == ISP_CFG_N) { - clear_bit(RSCN_UPDATE, &flags); - if (qla_tgt_mode_enabled(vha)) { - /* allow the other side to start the login */ - clear_bit(LOCAL_LOOP_UPDATE, &flags); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } - } else if (ha->current_topology == ISP_CFG_NL) { + } else if (ha->current_topology == ISP_CFG_NL || + ha->current_topology == ISP_CFG_N) { clear_bit(RSCN_UPDATE, &flags); set_bit(LOCAL_LOOP_UPDATE, &flags); } else if (!vha->flags.online || @@ -4987,6 +5108,22 @@ return (rval); } +static void +qla_reinitialize_link(scsi_qla_host_t *vha) +{ + int rval; + + atomic_set(&vha->loop_state, LOOP_DOWN); + atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); + rval = qla2x00_full_login_lip(vha); + if (rval == QLA_SUCCESS) { + ql_dbg(ql_dbg_disc, vha, 0xd050, "Link reinitialized\n"); + } else { + ql_dbg(ql_dbg_disc, vha, 0xd051, + "Link reinitialization failed (%d)\n", rval); + } +} + /* * qla2x00_configure_local_loop * Updates Fibre Channel Device Database with local loop devices. @@ -5032,7 +5169,6 @@ memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb, sizeof(ha->plogi_els_payld.data)); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } else { ql_dbg(ql_dbg_init, vha, 0x00d1, "PLOGI ELS param read fail.\n"); @@ -5052,9 +5188,23 @@ spin_unlock_irqrestore(&vha->work_lock, flags); if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { + u8 loop_map_entries = 0; + int rc; + + rc = qla2x00_get_fcal_position_map(vha, NULL, + &loop_map_entries); + if (rc == QLA_SUCCESS && loop_map_entries > 1) { + /* + * There are devices that are still not logged + * in. Reinitialize to give them a chance. + */ + qla_reinitialize_link(vha); + return QLA_FUNCTION_FAILED; + } set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } + return QLA_FUNCTION_FAILED; } found_devs = 0; @@ -5167,6 +5317,13 @@ memcpy(fcport->node_name, new_fcport->node_name, WWN_SIZE); fcport->scan_state = QLA_FCPORT_FOUND; + if (fcport->login_retry == 0) { + fcport->login_retry = vha->hw->login_retry_count; + ql_dbg(ql_dbg_disc, vha, 0x2135, + "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n", + fcport->port_name, fcport->loop_id, + fcport->login_retry); + } found++; break; } @@ -5358,17 +5515,26 @@ void qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) { + unsigned long flags; + if (IS_SW_RESV_ADDR(fcport->d_id)) return; ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n", __func__, fcport->port_name); - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); fcport->login_retry = vha->hw->login_retry_count; fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); + + spin_lock_irqsave(&vha->work_lock, flags); fcport->deleted = 0; - fcport->logout_on_delete = 1; + spin_unlock_irqrestore(&vha->work_lock, flags); + + if (vha->hw->current_topology == ISP_CFG_NL) + fcport->logout_on_delete = 0; + else + fcport->logout_on_delete = 1; fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0; switch (vha->hw->current_topology) { @@ -5382,9 +5548,9 @@ qla2x00_iidma_fcport(vha, fcport); - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); qla2x00_set_fcport_state(fcport, FCS_ONLINE); return; } @@ -5429,7 +5595,7 @@ } } - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); } void qla_register_fcport_fn(struct work_struct *work) @@ -5710,11 +5876,8 @@ new_fcport->fc4_type = swl[swl_idx].fc4_type; new_fcport->nvme_flag = 0; - new_fcport->fc4f_nvme = 0; if (vha->flags.nvme_enabled && - swl[swl_idx].fc4f_nvme) { - new_fcport->fc4f_nvme = - swl[swl_idx].fc4f_nvme; + swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) { ql_log(ql_log_info, vha, 0x2131, "FOUND: NVME port %8phC as FC Type 28h\n", new_fcport->port_name); @@ -5770,7 +5933,7 @@ /* Bypass ports whose FCP-4 type is not FCP_SCSI */ if (ql2xgffidenable && - (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI && + (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) && new_fcport->fc4_type != FC4_TYPE_UNKNOWN)) continue; @@ -5839,9 +6002,9 @@ break; } - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); vha->fcport_count--; fcport->login_succ = 0; } @@ -5879,8 +6042,7 @@ if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) break; - if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || - (fcport->flags & FCF_LOGIN_NEEDED) == 0) + if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) continue; if (fcport->scan_state == QLA_FCPORT_SCAN) { @@ -5903,7 +6065,8 @@ } } - if (fcport->scan_state == QLA_FCPORT_FOUND) + if (fcport->scan_state == QLA_FCPORT_FOUND && + (fcport->flags & FCF_LOGIN_NEEDED) != 0) qla24xx_fcport_handle_login(vha, fcport); } return (rval); @@ -6754,7 +6917,8 @@ return 0; break; case QLA2XXX_INI_MODE_DUAL: - if (!qla_dual_mode_enabled(vha)) + if (!qla_dual_mode_enabled(vha) && + !qla_ini_mode_enabled(vha)) return 0; break; case QLA2XXX_INI_MODE_ENABLED: @@ -8514,6 +8678,11 @@ /* N2N: driver will initiate Login instead of FW */ icb->firmware_options_3 |= BIT_8; + /* Determine NVMe/FCP priority for target ports */ + ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha); + ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n", + ha->fc4_type_priority & BIT_0 ? "FCP" : "NVMe"); + if (rval) { ql_log(ql_log_warn, vha, 0x0076, "NVRAM configuration failed.\n"); @@ -8948,7 +9117,7 @@ qpair->rsp->req = qpair->req; qpair->rsp->qpair = qpair; /* init qpair to this cpu. Will adjust at run time. */ - qla_cpu_update(qpair, smp_processor_id()); + qla_cpu_update(qpair, raw_smp_processor_id()); if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) @@ -9003,8 +9172,6 @@ struct qla_hw_data *ha = qpair->hw; qpair->delete_in_progress = 1; - while (atomic_read(&qpair->ref_count)) - msleep(500); ret = qla25xx_delete_req_que(vha, qpair->req); if (ret != QLA_SUCCESS) --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_inline.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_inline.h @@ -105,6 +105,33 @@ INIT_LIST_HEAD(&ctx->dsd_list); } +static inline void +qla2x00_set_fcport_disc_state(fc_port_t *fcport, int state) +{ + int old_val; + uint8_t shiftbits, mask; + uint8_t port_dstate_str_sz; + + /* This will have to change when the max no. of states > 16 */ + shiftbits = 4; + mask = (1 << shiftbits) - 1; + + port_dstate_str_sz = sizeof(port_dstate_str) / sizeof(char *); + fcport->disc_state = state; + while (1) { + old_val = atomic_read(&fcport->shadow_disc_state); + if (old_val == atomic_cmpxchg(&fcport->shadow_disc_state, + old_val, (old_val << shiftbits) | state)) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x2134, + "FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n", + fcport->port_name, (old_val & mask) < port_dstate_str_sz ? + port_dstate_str[old_val & mask] : "Unknown", + port_dstate_str[state], fcport->d_id.b24); + return; + } + } +} + static inline int qla2x00_hba_err_chk_enabled(srb_t *sp) { @@ -183,10 +210,15 @@ return sp; } +void qla2xxx_rel_done_warning(srb_t *sp, int res); +void qla2xxx_rel_free_warning(srb_t *sp); + static inline void qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp) { sp->qpair = NULL; + sp->done = qla2xxx_rel_done_warning; + sp->free = qla2xxx_rel_free_warning; mempool_free(sp, qpair->srb_mempool); QLA_QPAIR_MARK_NOT_BUSY(qpair); } @@ -307,3 +339,15 @@ WRT_REG_DWORD(req->req_q_in, req->ring_index); } + +static inline int +qla2xxx_get_fc4_priority(struct scsi_qla_host *vha) +{ + uint32_t data; + + data = + ((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET]; + + + return ((data >> 6) & BIT_0); +} --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_iocb.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_iocb.c @@ -601,7 +601,8 @@ put_unaligned_le32(COMMAND_TYPE_6, &cmd_pkt->entry_type); /* No data transfer */ - if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { + if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE || + tot_dsds == 0) { cmd_pkt->byte_count = cpu_to_le32(0); return 0; } @@ -2405,11 +2406,19 @@ static void qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio) { + u16 control_flags = LCF_COMMAND_LOGO; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; - logio->control_flags = - cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); - if (!sp->fcport->keep_nport_handle) - logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT); + + if (sp->fcport->explicit_logout) { + control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT; + } else { + control_flags |= LCF_IMPL_LOGO; + + if (!sp->fcport->keep_nport_handle) + control_flags |= LCF_FREE_NPORT; + } + + logio->control_flags = cpu_to_le16(control_flags); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->port_id[0] = sp->fcport->d_id.b.al_pa; logio->port_id[1] = sp->fcport->d_id.b.area; @@ -2511,7 +2520,8 @@ { struct srb_iocb *elsio = &sp->u.iocb_cmd; - kfree(sp->fcport); + if (sp->fcport) + kfree(sp->fcport); if (elsio->u.els_logo.els_logo_pyld) dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE, @@ -2529,13 +2539,32 @@ fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; struct srb_iocb *lio = &sp->u.iocb_cmd; + unsigned long flags = 0; + int res, h; ql_dbg(ql_dbg_io, vha, 0x3069, "%s Timeout, hdl=%x, portid=%02x%02x%02x\n", sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - complete(&lio->u.els_logo.comp); + /* Abort the exchange */ + res = qla24xx_async_abort_cmd(sp, false); + if (res) { + ql_dbg(ql_dbg_io, vha, 0x3070, + "mbx abort_command failed.\n"); + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + complete(&lio->u.els_logo.comp); + } else { + ql_dbg(ql_dbg_io, vha, 0x3071, + "mbx abort_command success.\n"); + } } static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res) @@ -2602,6 +2631,7 @@ if (!elsio->u.els_logo.els_logo_pyld) { sp->free(sp); + kfree(sp->fcport); return QLA_FUNCTION_FAILED; } @@ -2676,7 +2706,8 @@ ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI ELS IOCB:\n"); ql_dump_buffer(ql_log_info, vha, 0x0109, - (uint8_t *)els_iocb, 0x70); + (uint8_t *)els_iocb, + sizeof(*els_iocb)); } else { els_iocb->control_flags = 1 << 13; els_iocb->tx_byte_count = @@ -2699,23 +2730,29 @@ srb_t *sp = data; fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; - struct qla_hw_data *ha = vha->hw; unsigned long flags = 0; - int res; + int res, h; ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069, "%s hdl=%x ELS Timeout, %8phC portid=%06x\n", sp->name, sp->handle, fcport->port_name, fcport->d_id.b24); /* Abort the exchange */ - spin_lock_irqsave(&ha->hardware_lock, flags); - res = ha->isp_ops->abort_command(sp); + res = qla24xx_async_abort_cmd(sp, false); ql_dbg(ql_dbg_io, vha, 0x3070, "mbx abort_command %s\n", (res == QLA_SUCCESS) ? "successful" : "failed"); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - sp->done(sp, QLA_FUNCTION_TIMEOUT); + if (res) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + sp->done(sp, QLA_FUNCTION_TIMEOUT); + } } void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi) @@ -2740,6 +2777,10 @@ struct scsi_qla_host *vha = sp->vha; struct event_arg ea; struct qla_work_evt *e; + struct fc_port *conflict_fcport; + port_id_t cid; /* conflict Nport id */ + u32 *fw_status = sp->u.iocb_cmd.u.els_plogi.fw_status; + u16 lid; ql_dbg(ql_dbg_disc, vha, 0x3072, "%s ELS done rc %d hdl=%x, portid=%06x %8phC\n", @@ -2751,14 +2792,100 @@ if (sp->flags & SRB_WAKEUP_ON_COMP) complete(&lio->u.els_plogi.comp); else { - if (res) { - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } else { + switch (fw_status[0]) { + case CS_DATA_UNDERRUN: + case CS_COMPLETE: memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; - ea.data[0] = MBS_COMMAND_COMPLETE; - ea.sp = sp; - qla24xx_handle_plogi_done_event(vha, &ea); + ea.rc = res; + qla_handle_els_plogi_done(vha, &ea); + break; + + case CS_IOCB_ERROR: + switch (fw_status[1]) { + case LSC_SCODE_PORTID_USED: + lid = fw_status[2] & 0xffff; + qlt_find_sess_invalidate_other(vha, + wwn_to_u64(fcport->port_name), + fcport->d_id, lid, &conflict_fcport); + if (conflict_fcport) { + /* + * Another fcport shares the same + * loop_id & nport id; conflict + * fcport needs to finish cleanup + * before this fcport can proceed + * to login. + */ + conflict_fcport->conflict = fcport; + fcport->login_pause = 1; + ql_dbg(ql_dbg_disc, vha, 0x20ed, + "%s %d %8phC pid %06x inuse with lid %#x post gidpn\n", + __func__, __LINE__, + fcport->port_name, + fcport->d_id.b24, lid); + } else { + ql_dbg(ql_dbg_disc, vha, 0x20ed, + "%s %d %8phC pid %06x inuse with lid %#x sched del\n", + __func__, __LINE__, + fcport->port_name, + fcport->d_id.b24, lid); + qla2x00_clear_loop_id(fcport); + set_bit(lid, vha->hw->loop_id_map); + fcport->loop_id = lid; + fcport->keep_nport_handle = 0; + qlt_schedule_sess_for_deletion(fcport); + } + break; + + case LSC_SCODE_NPORT_USED: + cid.b.domain = (fw_status[2] >> 16) & 0xff; + cid.b.area = (fw_status[2] >> 8) & 0xff; + cid.b.al_pa = fw_status[2] & 0xff; + cid.b.rsvd_1 = 0; + + ql_dbg(ql_dbg_disc, vha, 0x20ec, + "%s %d %8phC lid %#x in use with pid %06x post gnl\n", + __func__, __LINE__, fcport->port_name, + fcport->loop_id, cid.b24); + set_bit(fcport->loop_id, + vha->hw->loop_id_map); + fcport->loop_id = FC_NO_LOOP_ID; + qla24xx_post_gnl_work(vha, fcport); + break; + + case LSC_SCODE_NOXCB: + vha->hw->exch_starvation++; + if (vha->hw->exch_starvation > 5) { + ql_log(ql_log_warn, vha, 0xd046, + "Exchange starvation. Resetting RISC\n"); + vha->hw->exch_starvation = 0; + set_bit(ISP_ABORT_NEEDED, + &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + break; + } + /* fall through */ + default: + ql_dbg(ql_dbg_disc, vha, 0x20eb, + "%s %8phC cmd error fw_status 0x%x 0x%x 0x%x\n", + __func__, sp->fcport->port_name, + fw_status[0], fw_status[1], fw_status[2]); + + fcport->flags &= ~FCF_ASYNC_SENT; + qlt_schedule_sess_for_deletion(fcport); + break; + } + break; + + default: + ql_dbg(ql_dbg_disc, vha, 0x20eb, + "%s %8phC cmd error 2 fw_status 0x%x 0x%x 0x%x\n", + __func__, sp->fcport->port_name, + fw_status[0], fw_status[1], fw_status[2]); + + sp->fcport->flags &= ~FCF_ASYNC_SENT; + qlt_schedule_sess_for_deletion(fcport); + break; } e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); @@ -2792,11 +2919,12 @@ return -ENOMEM; } + fcport->flags |= FCF_ASYNC_SENT; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); elsio = &sp->u.iocb_cmd; ql_dbg(ql_dbg_io, vha, 0x3073, "Enter: PLOGI portid=%06x\n", fcport->d_id.b24); - fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_ELS_DCMD; sp->name = "ELS_DCMD"; sp->fcport = fcport; @@ -2842,7 +2970,8 @@ ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109, - (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70); + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, + sizeof(*elsio->u.els_plogi.els_plogi_pyld)); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -3539,7 +3668,7 @@ spin_lock_irqsave(qp->qp_lock_ptr, flags); pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); if (!pkt) { - rval = EAGAIN; + rval = -EAGAIN; ql_log(ql_log_warn, vha, 0x700c, "qla2x00_alloc_iocbs failed.\n"); goto done; --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_isr.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_isr.c @@ -639,8 +639,12 @@ unsigned long flags; fc_port_t *fcport = NULL; - if (!vha->hw->flags.fw_started) + if (!vha->hw->flags.fw_started) { + ql_log(ql_log_warn, vha, 0x50ff, + "Dropping AEN - %04x %04x %04x %04x.\n", + mb[0], mb[1], mb[2], mb[3]); return; + } /* Setup to process RIO completion. */ handle_cnt = 0; @@ -1061,8 +1065,6 @@ ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", mb[1], mb[2], mb[3]); - - qlt_async_event(mb[0], vha, mb); break; } @@ -1079,8 +1081,6 @@ set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(VP_CONFIG_OK, &vha->vp_flags); - - qlt_async_event(mb[0], vha, mb); break; case MBA_RSCN_UPDATE: /* State Change Registration */ @@ -1843,6 +1843,7 @@ iocb->u.tmf.data = QLA_FUNCTION_FAILED; } else if ((le16_to_cpu(sts->scsi_status) & SS_RESPONSE_INFO_LEN_VALID)) { + host_to_fcp_swap(sts->data, sizeof(sts->data)); if (le32_to_cpu(sts->rsp_data_len) < 4) { ql_log(ql_log_warn, fcport->vha, 0x503b, "Async-%s error - hdl=%x not enough response(%d).\n", @@ -1901,6 +1902,18 @@ inbuf = (uint32_t *)&sts->nvme_ersp_data; outbuf = (uint32_t *)fd->rspaddr; iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len); + if (unlikely(iocb->u.nvme.rsp_pyld_len > + sizeof(struct nvme_fc_ersp_iu))) { + if (ql_mask_match(ql_dbg_io)) { + WARN_ONCE(1, "Unexpected response payload length %u.\n", + iocb->u.nvme.rsp_pyld_len); + ql_log(ql_log_warn, fcport->vha, 0x5100, + "Unexpected response payload length %u.\n", + iocb->u.nvme.rsp_pyld_len); + } + iocb->u.nvme.rsp_pyld_len = + sizeof(struct nvme_fc_ersp_iu); + } iter = iocb->u.nvme.rsp_pyld_len >> 2; for (; iter; iter--) *outbuf++ = swab32(*inbuf++); @@ -2697,7 +2710,6 @@ case CS_PORT_BUSY: case CS_INCOMPLETE: case CS_PORT_UNAVAILABLE: - case CS_TIMEOUT: case CS_RESET: /* @@ -3554,16 +3566,12 @@ } /* Enable MSI-X vector for response queue update for queue 0 */ - if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - if (ha->msixbase && ha->mqiobase && - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || - ql2xmqsupport)) - ha->mqenable = 1; - } else - if (ha->mqiobase && - (ha->max_rsp_queues > 1 || ha->max_req_queues > 1 || - ql2xmqsupport)) - ha->mqenable = 1; + if (IS_MQUE_CAPABLE(ha) && + (ha->msixbase && ha->mqiobase && ha->max_qpairs)) + ha->mqenable = 1; + else + ha->mqenable = 0; + ql_dbg(ql_dbg_multiq, vha, 0xc005, "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.\n", ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues); @@ -3624,7 +3632,7 @@ skip_msix: ql_log(ql_log_info, vha, 0x0037, - "Falling back-to MSI mode -%d.\n", ret); + "Falling back-to MSI mode -- ret=%d.\n", ret); if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && @@ -3632,13 +3640,13 @@ goto skip_msi; ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); - if (!ret) { + if (ret > 0) { ql_dbg(ql_dbg_init, vha, 0x0038, "MSI: Enabled.\n"); ha->flags.msi_enabled = 1; } else ql_log(ql_log_warn, vha, 0x0039, - "Falling back-to INTa mode -- %d.\n", ret); + "Falling back-to INTa mode -- ret=%d.\n", ret); skip_msi: /* Skip INTx on ISP82xx. */ --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_mbx.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_mbx.c @@ -10,6 +10,12 @@ #include #include +#ifdef CONFIG_PPC +#define IS_PPCARCH true +#else +#define IS_PPCARCH false +#endif + static struct mb_cmd_name { uint16_t cmd; const char *str; @@ -265,6 +271,12 @@ atomic_inc(&ha->num_pend_mbx_stage3); if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { + ql_dbg(ql_dbg_mbx, vha, 0x117a, + "cmd=%x Timeout.\n", command); + spin_lock_irqsave(&ha->hardware_lock, flags); + clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + if (chip_reset != ha->chip_reset) { spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; @@ -275,12 +287,6 @@ rval = QLA_ABORTED; goto premature_exit; } - ql_dbg(ql_dbg_mbx, vha, 0x117a, - "cmd=%x Timeout.\n", command); - spin_lock_irqsave(&ha->hardware_lock, flags); - clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - } else if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { spin_lock_irqsave(&ha->hardware_lock, flags); @@ -335,14 +341,6 @@ if (time_after(jiffies, wait_time)) break; - /* - * Check if it's UNLOADING, cause we cannot poll in - * this case, or else a NULL pointer dereference - * is triggered. - */ - if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) - return QLA_FUNCTION_TIMEOUT; - /* Check for pending interrupts. */ qla2x00_poll(ha->rsp_q_map[0]); @@ -739,6 +737,9 @@ vha->min_supported_speed = nv->min_supported_speed; } + + if (IS_PPCARCH) + mcp->mb[11] |= BIT_4; } if (ha->flags.exlogins_enabled) @@ -1932,7 +1933,7 @@ pd24 = (struct port_database_24xx *) pd; /* Check for logged in state. */ - if (fcport->fc4f_nvme) { + if (NVME_TARGET(ha, fcport)) { current_login_state = pd24->current_login_state >> 4; last_login_state = pd24->last_login_state >> 4; } else { @@ -2905,8 +2906,7 @@ ha->orig_fw_iocb_count = mcp->mb[10]; if (ha->flags.npiv_supported) ha->max_npiv_vports = mcp->mb[11]; - if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || - IS_QLA28XX(ha)) + if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) ha->fw_max_fcf_count = mcp->mb[12]; } @@ -2928,7 +2928,8 @@ * Kernel context. */ int -qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map) +qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map, + u8 *num_entries) { int rval; mbx_cmd_t mc; @@ -2968,6 +2969,8 @@ if (pos_map) memcpy(pos_map, pmap, FCAL_MAP_SIZE); + if (num_entries) + *num_entries = pmap[0]; } dma_pool_free(ha->s_dma_pool, pmap, pmap_dma); @@ -3117,7 +3120,7 @@ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, "Entered %s.\n", __func__); - if (vha->flags.qpairs_available && sp->qpair) + if (sp->qpair) req = sp->qpair->req; else return QLA_FUNCTION_FAILED; @@ -3888,19 +3891,41 @@ fcport->scan_state = QLA_FCPORT_SCAN; fcport->n2n_flag = 0; } + id.b24 = 0; + if (wwn_to_u64(vha->port_name) > + wwn_to_u64(rptid_entry->u.f1.port_name)) { + vha->d_id.b24 = 0; + vha->d_id.b.al_pa = 1; + ha->flags.n2n_bigger = 1; + + id.b.al_pa = 2; + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: assign local id %x remote id %x\n", + vha->d_id.b24, id.b24); + } else { + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: Remote login - Waiting for WWPN %8phC.\n", + rptid_entry->u.f1.port_name); + ha->flags.n2n_bigger = 0; + } fcport = qla2x00_find_fcport_by_wwpn(vha, rptid_entry->u.f1.port_name, 1); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + if (fcport) { fcport->plogi_nack_done_deadline = jiffies + HZ; - fcport->dm_login_expire = jiffies + 2*HZ; + fcport->dm_login_expire = jiffies + + QLA_N2N_WAIT_TIME * HZ; fcport->scan_state = QLA_FCPORT_FOUND; fcport->n2n_flag = 1; fcport->keep_nport_handle = 1; - if (vha->flags.nvme_enabled) - fcport->fc4f_nvme = 1; + + if (wwn_to_u64(vha->port_name) > + wwn_to_u64(fcport->port_name)) { + fcport->d_id = id; + } switch (fcport->disc_state) { case DSC_DELETED: @@ -3914,23 +3939,6 @@ break; } } else { - id.b24 = 0; - if (wwn_to_u64(vha->port_name) > - wwn_to_u64(rptid_entry->u.f1.port_name)) { - vha->d_id.b24 = 0; - vha->d_id.b.al_pa = 1; - ha->flags.n2n_bigger = 1; - - id.b.al_pa = 2; - ql_dbg(ql_dbg_async, vha, 0x5075, - "Format 1: assign local id %x remote id %x\n", - vha->d_id.b24, id.b24); - } else { - ql_dbg(ql_dbg_async, vha, 0x5075, - "Format 1: Remote login - Waiting for WWPN %8phC.\n", - rptid_entry->u.f1.port_name); - ha->flags.n2n_bigger = 0; - } qla24xx_post_newsess_work(vha, &id, rptid_entry->u.f1.port_name, rptid_entry->u.f1.node_name, @@ -3941,7 +3949,6 @@ /* if our portname is higher then initiate N2N login */ set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); - ha->flags.n2n_ae = 1; return; break; case TOPO_FL: @@ -5397,7 +5404,7 @@ mcp->out_mb = MBX_1|MBX_0; mcp->in_mb = MBX_2|MBX_1|MBX_0; if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) - mcp->in_mb |= MBX_3; + mcp->in_mb |= MBX_4|MBX_3; mcp->tov = MBX_TOV_SECONDS; mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); @@ -6150,9 +6157,8 @@ mcp->mb[7] = LSW(MSD(req_dma)); mcp->mb[8] = MSW(addr); /* Setting RAM ID to valid */ - mcp->mb[10] |= BIT_7; /* For MCTP RAM ID is 0x40 */ - mcp->mb[10] |= 0x40; + mcp->mb[10] = BIT_7 | 0x40; mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| MBX_0; @@ -6287,17 +6293,13 @@ case QLA_SUCCESS: ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", __func__, sp->name); - sp->free(sp); break; default: ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - sp->free(sp); break; } - return rval; - done_free_sp: sp->free(sp); done: @@ -6362,7 +6364,7 @@ uint64_t zero = 0; u8 current_login_state, last_login_state; - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { current_login_state = pd->current_login_state >> 4; last_login_state = pd->last_login_state >> 4; } else { @@ -6397,8 +6399,8 @@ fcport->d_id.b.al_pa = pd->port_id[2]; fcport->d_id.b.rsvd_1 = 0; - if (fcport->fc4f_nvme) { - fcport->port_type = 0; + if (NVME_TARGET(vha->hw, fcport)) { + fcport->port_type = FCT_NVME; if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) fcport->port_type |= FCT_NVME_INITIATOR; if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_mid.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_mid.c @@ -165,7 +165,7 @@ atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); list_for_each_entry(fcport, &vha->vp_fcports, list) - fcport->logout_on_delete = 0; + fcport->logout_on_delete = 1; qla2x00_mark_all_devices_lost(vha, 0); @@ -492,6 +492,7 @@ return(NULL); } + vha->irq_offset = QLA_BASE_VECTORS; host = vha->host; fc_vport->dd_data = vha; /* New host info */ @@ -946,7 +947,7 @@ sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); if (!sp) - goto done; + return rval; sp->type = SRB_CTRL_VP; sp->name = "ctrl_vp"; @@ -962,7 +963,7 @@ ql_dbg(ql_dbg_async, vha, 0xffff, "%s: %s Failed submission. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + goto done; } ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", @@ -980,16 +981,13 @@ case QLA_SUCCESS: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n", __func__, sp->name); - goto done_free_sp; + break; default: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + break; } done: - return rval; - -done_free_sp: sp->free(sp); return rval; } --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_mr.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_mr.c @@ -693,7 +693,7 @@ struct qla_hw_data *ha = vha->hw; if (pci_is_pcie(ha->pdev)) - strlcpy(str, "PCIe iSA", str_len); + strscpy(str, "PCIe iSA", str_len); return str; } @@ -741,29 +741,6 @@ } int -qlafx00_loop_reset(scsi_qla_host_t *vha) -{ - int ret; - struct fc_port *fcport; - struct qla_hw_data *ha = vha->hw; - - if (ql2xtargetreset) { - list_for_each_entry(fcport, &vha->vp_fcports, list) { - if (fcport->port_type != FCT_TARGET) - continue; - - ret = ha->isp_ops->target_reset(fcport, 0, 0); - if (ret != QLA_SUCCESS) { - ql_dbg(ql_dbg_taskm, vha, 0x803d, - "Bus Reset failed: Reset=%d " - "d_id=%x.\n", ret, fcport->d_id.b24); - } - } - } - return QLA_SUCCESS; -} - -int qlafx00_iospace_config(struct qla_hw_data *ha) { if (pci_request_selected_regions(ha->pdev, ha->bars, @@ -1877,21 +1854,21 @@ phost_info = &preg_hsi->hsi; memset(preg_hsi, 0, sizeof(struct register_host_info)); phost_info->os_type = OS_TYPE_LINUX; - strlcpy(phost_info->sysname, p_sysid->sysname, + strscpy(phost_info->sysname, p_sysid->sysname, sizeof(phost_info->sysname)); - strlcpy(phost_info->nodename, p_sysid->nodename, + strscpy(phost_info->nodename, p_sysid->nodename, sizeof(phost_info->nodename)); if (!strcmp(phost_info->nodename, "(none)")) ha->mr.host_info_resend = true; - strlcpy(phost_info->release, p_sysid->release, + strscpy(phost_info->release, p_sysid->release, sizeof(phost_info->release)); - strlcpy(phost_info->version, p_sysid->version, + strscpy(phost_info->version, p_sysid->version, sizeof(phost_info->version)); - strlcpy(phost_info->machine, p_sysid->machine, + strscpy(phost_info->machine, p_sysid->machine, sizeof(phost_info->machine)); - strlcpy(phost_info->domainname, p_sysid->domainname, + strscpy(phost_info->domainname, p_sysid->domainname, sizeof(phost_info->domainname)); - strlcpy(phost_info->hostdriver, QLA2XXX_VERSION, + strscpy(phost_info->hostdriver, QLA2XXX_VERSION, sizeof(phost_info->hostdriver)); preg_hsi->utc = (uint64_t)ktime_get_real_seconds(); ql_dbg(ql_dbg_init, vha, 0x0149, @@ -1937,9 +1914,9 @@ if (fx_type == FXDISC_GET_CONFIG_INFO) { struct config_info_data *pinfo = (struct config_info_data *) fdisc->u.fxiocb.rsp_addr; - strlcpy(vha->hw->model_number, pinfo->model_num, + strscpy(vha->hw->model_number, pinfo->model_num, ARRAY_SIZE(vha->hw->model_number)); - strlcpy(vha->hw->model_desc, pinfo->model_description, + strscpy(vha->hw->model_desc, pinfo->model_description, ARRAY_SIZE(vha->hw->model_desc)); memcpy(&vha->hw->mr.symbolic_name, pinfo->symbolic_name, sizeof(vha->hw->mr.symbolic_name)); --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_nvme.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_nvme.c @@ -28,7 +28,10 @@ return 0; } - if (!vha->nvme_local_port && qla_nvme_register_hba(vha)) + if (qla_nvme_register_hba(vha)) + return 0; + + if (!vha->nvme_local_port) return 0; if (!(fcport->nvme_prli_service_param & @@ -84,8 +87,9 @@ struct qla_hw_data *ha; struct qla_qpair *qpair; - if (!qidx) - qidx++; + /* Map admin queue and 1st IO queue to index 0 */ + if (qidx) + qidx--; vha = (struct scsi_qla_host *)lport->private; ha = vha->hw; @@ -167,6 +171,7 @@ spin_unlock_irqrestore(&priv->cmd_lock, flags); fd = priv->fd; + fd->done(fd, priv->comp_status); out: qla2x00_rel_sp(sp); @@ -224,8 +229,8 @@ if (ha->flags.host_shutting_down) { ql_log(ql_log_info, sp->fcport->vha, 0xffff, - "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n", - __func__, sp, sp->type, atomic_read(&sp->ref_count)); + "%s Calling done on sp: %p, type: 0x%x\n", + __func__, sp, sp->type); sp->done(sp, 0); goto out; } @@ -308,8 +313,7 @@ nvme->u.nvme.rsp_len = fd->rsplen; nvme->u.nvme.rsp_dma = fd->rspdma; nvme->u.nvme.timeout_sec = fd->timeout; - nvme->u.nvme.cmd_dma = dma_map_single(&ha->pdev->dev, fd->rqstaddr, - fd->rqstlen, DMA_TO_DEVICE); + nvme->u.nvme.cmd_dma = fd->rqstdma; dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma, fd->rqstlen, DMA_TO_DEVICE); @@ -317,7 +321,6 @@ if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x700e, "qla2x00_start_sp failed = %d\n", rval); - wake_up(&sp->nvme_ls_waitq); sp->priv = NULL; priv->sp = NULL; qla2x00_rel_sp(sp); @@ -535,6 +538,11 @@ struct nvme_private *priv = fd->private; struct qla_nvme_rport *qla_rport = rport->private; + if (!priv) { + /* nvme association has been torn down */ + return rval; + } + fcport = qla_rport->fcport; if (!qpair || !fcport || (qpair && !qpair->fw_started) || @@ -557,7 +565,6 @@ if (!sp) return -EBUSY; - init_waitqueue_head(&sp->nvme_ls_waitq); kref_init(&sp->cmd_kref); spin_lock_init(&priv->cmd_lock); sp->priv = (void *)priv; @@ -573,9 +580,8 @@ rval = qla2x00_start_nvme_mq(sp); if (rval != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x212d, + ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x212d, "qla2x00_start_nvme_mq failed = %d\n", rval); - wake_up(&sp->nvme_ls_waitq); sp->priv = NULL; priv->sp = NULL; qla2xxx_rel_qpair_sp(sp->qpair, sp); @@ -677,7 +683,7 @@ struct nvme_fc_port_template *tmpl; struct qla_hw_data *ha; struct nvme_fc_port_info pinfo; - int ret = EINVAL; + int ret = -EINVAL; if (!IS_ENABLED(CONFIG_NVME_FC)) return ret; --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_nx.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_nx.c @@ -1113,7 +1113,8 @@ return ret; } - if (qla82xx_flash_set_write_enable(ha)) + ret = qla82xx_flash_set_write_enable(ha); + if (ret < 0) goto done_write; qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, data); @@ -1612,8 +1613,7 @@ return (u8 *)&ha->hablob->fw->data[offset]; } -static __le32 -qla82xx_get_fw_size(struct qla_hw_data *ha) +static u32 qla82xx_get_fw_size(struct qla_hw_data *ha) { struct qla82xx_uri_data_desc *uri_desc = NULL; @@ -1624,7 +1624,7 @@ return cpu_to_le32(uri_desc->size); } - return cpu_to_le32(*(u32 *)&ha->hablob->fw->data[FW_SIZE_OFFSET]); + return get_unaligned_le32(&ha->hablob->fw->data[FW_SIZE_OFFSET]); } static u8 * @@ -1816,7 +1816,7 @@ } flashaddr = FLASH_ADDR_START; - size = (__force u32)qla82xx_get_fw_size(ha) / 8; + size = qla82xx_get_fw_size(ha) / 8; ptr64 = (u64 *)qla82xx_get_fw_offs(ha); for (i = 0; i < size; i++) { --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_os.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_os.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -190,12 +191,6 @@ " 0 -- Regular doorbell.\n" " 1 -- CAMRAM doorbell (faster).\n"); -int ql2xtargetreset = 1; -module_param(ql2xtargetreset, int, S_IRUGO); -MODULE_PARM_DESC(ql2xtargetreset, - "Enable target reset." - "Default is 1 - use hw defaults."); - int ql2xgffidenable; module_param(ql2xgffidenable, int, S_IRUGO); MODULE_PARM_DESC(ql2xgffidenable, @@ -698,11 +693,6 @@ struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) - return; - - atomic_dec(&sp->ref_count); - sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; @@ -794,11 +784,6 @@ struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) - return; - - atomic_dec(&sp->ref_count); - sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; @@ -829,7 +814,7 @@ uint16_t hwq; struct qla_qpair *qpair = NULL; - tag = blk_mq_unique_tag(cmd->request); + tag = blk_mq_unique_tag(scsi_cmd_to_rq(cmd)); hwq = blk_mq_unique_tag_to_hwq(tag); qpair = ha->queue_pair_map[hwq]; @@ -903,7 +888,7 @@ sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; - atomic_set(&sp->ref_count, 1); + CMD_SP(cmd) = (void *)sp; sp->free = qla2x00_sp_free_dma; sp->done = qla2x00_sp_compl; @@ -985,18 +970,14 @@ sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; - atomic_set(&sp->ref_count, 1); CMD_SP(cmd) = (void *)sp; sp->free = qla2xxx_qpair_sp_free_dma; sp->done = qla2xxx_qpair_sp_compl; - sp->qpair = qpair; rval = ha->isp_ops->start_scsi_mq(sp); if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); - if (rval == QLA_INTERFACE_ERROR) - goto qc24_fail_command; goto qc24_host_busy_free_sp; } @@ -1184,16 +1165,6 @@ return return_status; } -static int -sp_get(struct srb *sp) -{ - if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count)) - /* kref get fail */ - return ENXIO; - else - return 0; -} - #define ISP_REG_DISCONNECT 0xffffffffU /************************************************************************** * qla2x00_isp_reg_stat @@ -1249,6 +1220,10 @@ uint64_t lun; int rval; struct qla_hw_data *ha = vha->hw; + uint32_t ratov_j; + struct qla_qpair *qpair; + unsigned long flags; + int fast_fail_status = SUCCESS; if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, @@ -1256,18 +1231,21 @@ return FAILED; } + /* Save any FAST_IO_FAIL value to return later if abort succeeds */ ret = fc_block_scsi_eh(cmd); if (ret != 0) - return ret; + fast_fail_status = ret; sp = scsi_cmd_priv(cmd); + qpair = sp->qpair; - if (sp->fcport && sp->fcport->deleted) - return SUCCESS; + if ((sp->fcport && sp->fcport->deleted) || !qpair) + return fast_fail_status != SUCCESS ? fast_fail_status : FAILED; + + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + sp->comp = ∁ + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); - /* Return if the command has already finished. */ - if (sp_get(sp)) - return SUCCESS; id = cmd->device->id; lun = cmd->device->lun; @@ -1276,47 +1254,37 @@ "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", vha->host_no, id, lun, sp, cmd, sp->handle); + /* + * Abort will release the original Command/sp from FW. Let the + * original command call scsi_done. In return, he will wakeup + * this sleeping thread. + */ rval = ha->isp_ops->abort_command(sp); + ql_dbg(ql_dbg_taskm, vha, 0x8003, "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); + /* Wait for the command completion. */ + ratov_j = ha->r_a_tov/10 * 4 * 1000; + ratov_j = msecs_to_jiffies(ratov_j); switch (rval) { case QLA_SUCCESS: - /* - * The command has been aborted. That means that the firmware - * won't report a completion. - */ - sp->done(sp, DID_ABORT << 16); - ret = SUCCESS; - break; - case QLA_FUNCTION_PARAMETER_ERROR: { - /* Wait for the command completion. */ - uint32_t ratov = ha->r_a_tov/10; - uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000); - - WARN_ON_ONCE(sp->comp); - sp->comp = ∁ if (!wait_for_completion_timeout(&comp, ratov_j)) { ql_dbg(ql_dbg_taskm, vha, 0xffff, "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", - __func__, ha->r_a_tov); + __func__, ha->r_a_tov/10); ret = FAILED; } else { - ret = SUCCESS; + ret = fast_fail_status; } break; - } default: - /* - * Either abort failed or abort and completion raced. Let - * the SCSI core retry the abort in the former case. - */ ret = FAILED; break; } sp->comp = NULL; - atomic_dec(&sp->ref_count); + ql_log(ql_log_info, vha, 0x801c, "Abort command issued nexus=%ld:%d:%llu -- %x.\n", vha->host_no, id, lun, ret); @@ -1653,27 +1621,10 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) { int ret; - struct fc_port *fcport; struct qla_hw_data *ha = vha->hw; - if (IS_QLAFX00(ha)) { - return qlafx00_loop_reset(vha); - } - - if (ql2xtargetreset == 1 && ha->flags.enable_target_reset) { - list_for_each_entry(fcport, &vha->vp_fcports, list) { - if (fcport->port_type != FCT_TARGET) - continue; - - ret = ha->isp_ops->target_reset(fcport, 0, 0); - if (ret != QLA_SUCCESS) { - ql_dbg(ql_dbg_taskm, vha, 0x802c, - "Bus Reset failed: Reset=%d " - "d_id=%x.\n", ret, fcport->d_id.b24); - } - } - } - + if (IS_QLAFX00(ha)) + return QLA_SUCCESS; if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { atomic_set(&vha->loop_state, LOOP_DOWN); @@ -1699,6 +1650,10 @@ return QLA_SUCCESS; } +/* + * The caller must ensure that no completion interrupts will happen + * while this function is in progress. + */ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, unsigned long *flags) __releases(qp->qp_lock_ptr) @@ -1707,35 +1662,68 @@ DECLARE_COMPLETION_ONSTACK(comp); scsi_qla_host_t *vha = qp->vha; struct qla_hw_data *ha = vha->hw; + struct scsi_cmnd *cmd = GET_CMD_SP(sp); int rval; + bool ret_cmd; + uint32_t ratov_j; - if (sp_get(sp)) + if (qla2x00_chip_is_down(vha)) { + sp->done(sp, res); return; + } if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && !qla2x00_isp_reg_stat(ha))) { + if (sp->comp) { + sp->done(sp, res); + return; + } + sp->comp = ∁ spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); - rval = ha->isp_ops->abort_command(sp); + rval = ha->isp_ops->abort_command(sp); + /* Wait for command completion. */ + ret_cmd = false; + ratov_j = ha->r_a_tov/10 * 4 * 1000; + ratov_j = msecs_to_jiffies(ratov_j); switch (rval) { case QLA_SUCCESS: - sp->done(sp, res); + if (wait_for_completion_timeout(&comp, ratov_j)) { + ql_dbg(ql_dbg_taskm, vha, 0xffff, + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", + __func__, ha->r_a_tov/10); + ret_cmd = true; + } + /* else FW return SP to driver */ break; - case QLA_FUNCTION_PARAMETER_ERROR: - wait_for_completion(&comp); + default: + ret_cmd = true; break; } spin_lock_irqsave(qp->qp_lock_ptr, *flags); - sp->comp = NULL; + switch (sp->type) { + case SRB_SCSI_CMD: + if (ret_cmd && blk_mq_request_started(scsi_cmd_to_rq(cmd))) + sp->done(sp, res); + break; + default: + if (ret_cmd) + sp->done(sp, res); + break; + } + } else { + sp->done(sp, res); } - - atomic_dec(&sp->ref_count); } +/* + * The caller must ensure that no completion interrupts will happen + * while this function is in progress. + */ static void __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) { @@ -1755,7 +1743,12 @@ for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { - req->outstanding_cmds[cnt] = NULL; + if (qla2x00_chip_is_down(vha)) { + req->outstanding_cmds[cnt] = NULL; + sp->done(sp, res); + continue; + } + switch (sp->cmd_type) { case TYPE_SRB: qla2x00_abort_srb(qp, sp, res, &flags); @@ -1777,11 +1770,16 @@ default: break; } + req->outstanding_cmds[cnt] = NULL; } } spin_unlock_irqrestore(qp->qp_lock_ptr, flags); } +/* + * The caller must ensure that no completion interrupts will happen + * while this function is in progress. + */ void qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) { @@ -1983,6 +1981,11 @@ /* Determine queue resources */ ha->max_req_queues = ha->max_rsp_queues = 1; ha->msix_count = QLA_BASE_VECTORS; + + /* Check if FW supports MQ or not */ + if (!(ha->fw_attributes & BIT_6)) + goto mqiobase_exit; + if (!ql2xmqsupport || !ql2xnvmeenable || (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))) goto mqiobase_exit; @@ -2791,13 +2794,14 @@ return ret; } + if (is_kdump_kernel()) { + ql2xmqsupport = 0; + ql2xallocfwdump = 0; + } + /* This may fail but that's ok */ pci_enable_pcie_error_reporting(pdev); - /* Turn off T10-DIF when FC-NVMe is enabled */ - if (ql2xnvmeenable) - ql2xenabledif = 0; - ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); if (!ha) { ql_log_pci(ql_log_fatal, pdev, 0x0009, @@ -3112,6 +3116,13 @@ host->max_id = ha->max_fibre_devices; host->cmd_per_lun = 3; host->unique_id = host->host_no; + + if (ql2xenabledif && ql2xenabledif != 2) { + ql_log(ql_log_warn, base_vha, 0x302d, + "Invalid value for ql2xenabledif, resetting it to default (2)\n"); + ql2xenabledif = 2; + } + if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) host->max_cmd_len = 32; else @@ -3343,8 +3354,6 @@ base_vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_init, base_vha, 0x00f1, "Registering for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; if (ql2xprotmask) scsi_host_set_prot(host, ql2xprotmask); else @@ -3638,8 +3647,7 @@ if (ha->mqiobase) iounmap(ha->mqiobase); - if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) && - ha->msixbase) + if (ha->msixbase) iounmap(ha->msixbase); } } @@ -3690,6 +3698,13 @@ } qla2x00_wait_for_hba_ready(base_vha); + /* + * if UNLOADING flag is already set, then continue unload, + * where it was set first. + */ + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) + return; + if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { if (ha->flags.fw_started) @@ -3708,15 +3723,6 @@ qla2x00_wait_for_sess_deletion(base_vha); - /* - * if UNLOAD flag is already set, then continue unload, - * where it was set first. - */ - if (test_bit(UNLOADING, &base_vha->dpc_flags)) - return; - - set_bit(UNLOADING, &base_vha->dpc_flags); - qla_nvme_delete(base_vha); dma_free_coherent(&ha->pdev->dev, @@ -4056,7 +4062,7 @@ ql_dbg_pci(ql_dbg_init, ha->pdev, 0xe0ee, "%s: failed alloc dsd\n", __func__); - return 1; + return -ENOMEM; } ha->dif_bundle_kallocs++; @@ -4425,7 +4431,7 @@ qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt) { u32 temp; - struct init_cb_81xx *icb = (struct init_cb_81xx *)&vha->hw->init_cb; + struct init_cb_81xx *icb = (struct init_cb_81xx *)vha->hw->init_cb; *ret_cnt = FW_DEF_EXCHANGES_CNT; if (max_cnt > vha->hw->max_exchg) @@ -4666,7 +4672,8 @@ ha->sfp_data = NULL; if (ha->flt) - dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, + dma_free_coherent(&ha->pdev->dev, + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, ha->flt, ha->flt_dma); ha->flt = NULL; ha->flt_dma = 0; @@ -4833,7 +4840,8 @@ } INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); - sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); + snprintf(vha->host_str, sizeof(vha->host_str), "%s_%lu", + QLA2XXX_DRIVER_NAME, vha->host_no); ql_dbg(ql_dbg_init, vha, 0x0041, "Allocated the host=%p hw=%p vha=%p dev_name=%s", vha->host, vha->hw, vha, @@ -4848,6 +4856,9 @@ struct qla_work_evt *e; uint8_t bail; + if (test_bit(UNLOADING, &vha->dpc_flags)) + return NULL; + QLA_VHA_MARK_BUSY(vha, bail); if (bail) return NULL; @@ -4960,7 +4971,7 @@ switch (code) { case QLA_UEVENT_CODE_FW_DUMP: - snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", + snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", vha->host_no); break; default: @@ -5001,7 +5012,7 @@ fcport->jiffies_at_registration = jiffies; fcport->sec_since_registration = 0; fcport->next_disc_state = DSC_DELETED; - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); spin_unlock_irqrestore(&fcport->vha->work_lock, flags); queue_work(system_unbound_wq, &fcport->reg_work); @@ -5042,19 +5053,19 @@ fcport->d_id = e->u.new_sess.id; fcport->flags |= FCF_FABRIC_DEVICE; fcport->fw_login_state = DSC_LS_PLOGI_PEND; - if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP) - fcport->fc4_type = FC4_TYPE_FCP_SCSI; - - if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) { - fcport->fc4_type = FC4_TYPE_OTHER; - fcport->fc4f_nvme = FC4_TYPE_NVME; - } memcpy(fcport->port_name, e->u.new_sess.port_name, WWN_SIZE); - if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) + fcport->fc4_type = e->u.new_sess.fc4_type; + if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) { + fcport->dm_login_expire = jiffies + + QLA_N2N_WAIT_TIME * HZ; + fcport->fc4_type = FS_FC4TYPE_FCP; fcport->n2n_flag = 1; + if (vha->flags.nvme_enabled) + fcport->fc4_type |= FS_FC4TYPE_NVME; + } } else { ql_dbg(ql_dbg_disc, vha, 0xffff, @@ -5158,13 +5169,13 @@ fcport->flags &= ~FCF_FABRIC_DEVICE; fcport->keep_nport_handle = 1; if (vha->flags.nvme_enabled) { - fcport->fc4f_nvme = 1; + fcport->fc4_type = + (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP); fcport->n2n_flag = 1; } fcport->fw_login_state = 0; - /* - * wait link init done before sending login - */ + + schedule_delayed_work(&vha->scan.scan_work, 5); } else { qla24xx_fcport_handle_login(vha, fcport); } @@ -5359,6 +5370,11 @@ ea.fcport = fcport; qla24xx_handle_relogin_event(vha, &ea); } else if (vha->hw->current_topology == + ISP_CFG_NL && + IS_QLA2XXX_MIDTYPE(vha->hw)) { + (void)qla24xx_fcport_handle_login(vha, + fcport); + } else if (vha->hw->current_topology == ISP_CFG_NL) { fcport->login_retry--; status = @@ -6042,13 +6058,6 @@ struct pci_dev *pdev = ha->pdev; scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); - /* - * if UNLOAD flag is already set, then continue unload, - * where it was set first. - */ - if (test_bit(UNLOADING, &base_vha->dpc_flags)) - return; - ql_log(ql_log_warn, base_vha, 0x015b, "Disabling adapter.\n"); @@ -6059,9 +6068,14 @@ return; } - qla2x00_wait_for_sess_deletion(base_vha); + /* + * if UNLOADING flag is already set, then continue unload, + * where it was set first. + */ + if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) + return; - set_bit(UNLOADING, &base_vha->dpc_flags); + qla2x00_wait_for_sess_deletion(base_vha); qla2x00_delete_all_vps(ha, base_vha); @@ -6285,6 +6299,7 @@ if (do_reset && !(test_and_set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags))) { + base_vha->flags.online = 1; ql_dbg(ql_dbg_dpc, base_vha, 0x4007, "ISP abort scheduled.\n"); if (ha->isp_ops->abort_isp(base_vha)) { @@ -6368,9 +6383,12 @@ } } loop_resync_check: - if (test_and_clear_bit(LOOP_RESYNC_NEEDED, + if (!qla2x00_reset_active(base_vha) && + test_and_clear_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags)) { - + /* + * Allow abort_isp to complete before moving on to scanning. + */ ql_dbg(ql_dbg_dpc, base_vha, 0x400f, "Loop resync scheduled.\n"); @@ -6614,7 +6632,7 @@ /* if the loop has been down for 4 minutes, reinit adapter */ if (atomic_dec_and_test(&vha->loop_down_timer) != 0) { - if (!(vha->device_flags & DFLG_NO_CABLE)) { + if (!(vha->device_flags & DFLG_NO_CABLE) && !vha->vp_idx) { ql_log(ql_log_warn, vha, 0x6009, "Loop down - aborting ISP.\n"); --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_sup.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_sup.c @@ -843,19 +843,19 @@ ha->flt_region_nvram = start; break; case FLT_REG_IMG_PRI_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_img_status_pri = start; break; case FLT_REG_IMG_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_img_status_sec = start; break; case FLT_REG_FW_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_fw_sec = start; break; case FLT_REG_BOOTLOAD_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_boot_sec = start; break; case FLT_REG_AUX_IMG_PRI_28XX: @@ -1355,7 +1355,7 @@ flash_data_addr(ha, faddr), cpu_to_le32(*dwptr)); if (ret) { ql_dbg(ql_dbg_user, vha, 0x7006, - "Failed slopw write %x (%x)\n", faddr, *dwptr); + "Failed slow write %x (%x)\n", faddr, *dwptr); break; } } @@ -2725,8 +2725,11 @@ ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, "Region %x is secure\n", region.code); - if (region.code == FLT_REG_FW || - region.code == FLT_REG_FW_SEC_27XX) { + switch (region.code) { + case FLT_REG_FW: + case FLT_REG_FW_SEC_27XX: + case FLT_REG_MPI_PRI_28XX: + case FLT_REG_MPI_SEC_28XX: fw_array = dwptr; /* 1st fw array */ @@ -2757,9 +2760,23 @@ buf_size_without_sfub += risc_size; fw_array += risc_size; } - } else { - ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, - "Secure region %x not supported\n", + break; + + case FLT_REG_PEP_PRI_28XX: + case FLT_REG_PEP_SEC_28XX: + fw_array = dwptr; + + /* 1st fw array */ + risc_size = be32_to_cpu(fw_array[3]); + risc_attr = be32_to_cpu(fw_array[9]); + + buf_size_without_sfub = risc_size; + fw_array += risc_size; + break; + + default: + ql_log(ql_log_warn + ql_dbg_verbose, vha, + 0xffff, "Secure region %x not supported\n", region.code); rval = QLA_COMMAND_ERROR; goto done; @@ -2880,7 +2897,7 @@ "Sending Secure Flash MB Cmd\n"); rval = qla28xx_secure_flash_update(vha, 0, region.code, buf_size_without_sfub, sfub_dma, - sizeof(struct secure_flash_update_block)); + sizeof(struct secure_flash_update_block) >> 2); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0xffff, "Secure Flash MB Cmd failed %x.", rval); --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_target.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_target.c @@ -596,7 +596,8 @@ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); } else { sp->fcport->login_retry = 0; - sp->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(sp->fcport, + DSC_LOGIN_COMPLETE); sp->fcport->deleted = 0; sp->fcport->logout_on_delete = 1; } @@ -957,7 +958,7 @@ struct qlt_plogi_ack_t *own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084, + ql_dbg(ql_dbg_disc, vha, 0xf084, "%s: se_sess %p / sess %p from port %8phC loop_id %#04x" " s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n", __func__, sess->se_sess, sess, sess->port_name, sess->loop_id, @@ -1024,7 +1025,7 @@ while (!READ_ONCE(sess->logout_completed)) { if (!traced) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086, + ql_dbg(ql_dbg_disc, vha, 0xf086, "%s: waiting for sess %p logout\n", __func__, sess); traced = true; @@ -1039,6 +1040,16 @@ "%s: sess %p logout completed\n", __func__, sess); } + /* check for any straggling io left behind */ + if (!(sess->flags & FCF_FCP2_DEVICE) && + qla2x00_eh_wait_for_pending_commands(sess->vha, sess->d_id.b24, 0, WAIT_TARGET)) { + ql_log(ql_log_warn, vha, 0x3027, + "IO not return. Resetting.\n"); + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + qla2x00_wait_for_chip_reset(vha); + } + if (sess->logo_ack_needed) { sess->logo_ack_needed = 0; qla24xx_async_notify_ack(vha, sess, @@ -1052,9 +1063,8 @@ tgt->sess_count--; } - sess->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(sess, DSC_DELETED); sess->fw_login_state = DSC_LS_PORT_UNAVAIL; - sess->deleted = QLA_SESS_DELETED; if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) { vha->fcport_count--; @@ -1104,10 +1114,16 @@ } } + sess->explicit_logout = 0; spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); + + spin_lock_irqsave(&vha->work_lock, flags); + sess->flags &= ~FCF_ASYNC_SENT; + sess->deleted = QLA_SESS_DELETED; sess->free_pending = 0; + spin_unlock_irqrestore(&vha->work_lock, flags); - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, + ql_dbg(ql_dbg_disc, vha, 0xf001, "Unregistration of sess %p %8phC finished fcp_cnt %d\n", sess, sess->port_name, vha->fcport_count); @@ -1150,17 +1166,21 @@ return; } sess->free_pending = 1; + /* + * Use FCF_ASYNC_SENT flag to block other cmds used in sess + * management from being sent. + */ + sess->flags |= FCF_ASYNC_SENT; + sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); if (sess->se_sess) vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); - sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; - sess->disc_state = DSC_DELETE_PEND; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; - INIT_WORK(&sess->free_work, qlt_free_session_done); queue_work(sess->vha->hw->wq, &sess->free_work); } EXPORT_SYMBOL(qlt_unreg_sess); @@ -1221,14 +1241,15 @@ case DSC_DELETE_PEND: return; case DSC_DELETED: - if (tgt && tgt->tgt_stop && (tgt->sess_count == 0)) - wake_up_all(&tgt->waitQ); - if (sess->vha->fcport_count == 0) - wake_up_all(&sess->vha->fcport_waitQ); - if (!sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN] && - !sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]) + !sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]) { + if (tgt && tgt->tgt_stop && tgt->sess_count == 0) + wake_up_all(&tgt->waitQ); + + if (sess->vha->fcport_count == 0) + wake_up_all(&sess->vha->fcport_waitQ); return; + } break; case DSC_UPD_FCPORT: /* @@ -1257,15 +1278,15 @@ sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); - sess->disc_state = DSC_DELETE_PEND; + sess->prli_pend_timer = 0; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); qla24xx_chk_fcp_state(sess); - ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, + ql_dbg(ql_dbg_disc, sess->vha, 0xe001, "Scheduling sess %p for deletion %8phC\n", sess, sess->port_name); - INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work)); } @@ -1548,10 +1569,12 @@ return; } + mutex_lock(&tgt->ha->optrom_mutex); mutex_lock(&vha->vha_tgt.tgt_mutex); tgt->tgt_stop = 0; tgt->tgt_stopped = 1; mutex_unlock(&vha->vha_tgt.tgt_mutex); + mutex_unlock(&tgt->ha->optrom_mutex); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n", tgt); @@ -3206,8 +3229,7 @@ if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || (cmd->sess && cmd->sess->deleted)) { cmd->state = QLA_TGT_STATE_PROCESSED; - res = 0; - goto free; + return 0; } ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018, @@ -3218,8 +3240,9 @@ res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, &full_req_cnt); - if (unlikely(res != 0)) - goto free; + if (unlikely(res != 0)) { + return res; + } spin_lock_irqsave(qpair->qp_lock_ptr, flags); @@ -3238,9 +3261,8 @@ "RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n", vha->flags.online, qla2x00_reset_active(vha), cmd->reset_count, qpair->chip_reset); - spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); res = 0; - goto free; + goto out_unmap_unlock; } /* Does F/W have an IOCBs for this request */ @@ -3343,8 +3365,6 @@ qlt_unmap_sg(vha, cmd); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); -free: - vha->hw->tgt.tgt_ops->free_cmd(cmd); return res; } EXPORT_SYMBOL(qlt_xmit_response); @@ -3365,10 +3385,6 @@ prm.sg = NULL; prm.req_cnt = 1; - /* Calculate number of entries and segments required */ - if (qlt_pci_map_calc_cnt(&prm) != 0) - return -EAGAIN; - if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) || (cmd->sess && cmd->sess->deleted)) { /* @@ -3386,6 +3402,10 @@ return 0; } + /* Calculate number of entries and segments required */ + if (qlt_pci_map_calc_cnt(&prm) != 0) + return -EAGAIN; + spin_lock_irqsave(qpair->qp_lock_ptr, flags); /* Does F/W have an IOCBs for this request */ res = qlt_check_reserve_free_req(qpair, prm.req_cnt); @@ -3758,6 +3778,9 @@ spin_lock_irqsave(&cmd->cmd_lock, flags); if (cmd->aborted) { + if (cmd->sg_mapped) + qlt_unmap_sg(vha, cmd); + spin_unlock_irqrestore(&cmd->cmd_lock, flags); /* * It's normal to see 2 calls in this path: @@ -3790,9 +3813,6 @@ BUG_ON(cmd->cmd_in_wq); - if (cmd->sg_mapped) - qlt_unmap_sg(cmd->vha, cmd); - if (!cmd->q_full) qlt_decr_num_pend_cmds(cmd->vha); @@ -4580,7 +4600,7 @@ /* find other sess with nport_id collision */ if (port_id.b24 == other_sess->d_id.b24) { if (loop_id != other_sess->loop_id) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000c, + ql_dbg(ql_dbg_disc, vha, 0x1000c, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4596,7 +4616,7 @@ * Another wwn used to have our s_id/loop_id * kill the session, but don't free the loop_id */ - ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b, + ql_dbg(ql_dbg_disc, vha, 0xf01b, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4611,7 +4631,7 @@ /* find other sess with nport handle collision */ if ((loop_id == other_sess->loop_id) && (loop_id != FC_NO_LOOP_ID)) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000d, + ql_dbg(ql_dbg_disc, vha, 0x1000d, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4804,6 +4824,7 @@ switch (sess->disc_state) { case DSC_DELETED: + case DSC_LOGIN_PEND: qlt_plogi_ack_unref(vha, pla); break; @@ -5667,7 +5688,7 @@ /* found existing exchange */ qpair->retry_term_cnt++; if (qpair->retry_term_cnt >= 5) { - rc = EIO; + rc = -EIO; qpair->retry_term_cnt = 0; ql_log(ql_log_warn, vha, 0xffff, "Unable to send ABTS Respond. Dumping firmware.\n"); @@ -6053,7 +6074,7 @@ if (!IS_SW_RESV_ADDR(fcport->d_id)) vha->fcport_count++; fcport->login_gen++; - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); fcport->login_succ = 1; newfcport = 1; } @@ -7076,8 +7097,7 @@ if (!QLA_TGT_MODE_ENABLED()) return; - if ((ql2xenablemsix == 0) || IS_QLA83XX(ha) || IS_QLA27XX(ha) || - IS_QLA28XX(ha)) { + if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { ISP_ATIO_Q_IN(base_vha) = &ha->mqiobase->isp25mq.atio_q_in; ISP_ATIO_Q_OUT(base_vha) = &ha->mqiobase->isp25mq.atio_q_out; } else { --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_target.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_target.h @@ -116,7 +116,6 @@ (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) #endif -#endif #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ @@ -244,6 +243,7 @@ #ifndef CTIO_RET_TYPE #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ +#endif struct fcp_hdr { uint8_t r_ctl; --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_tmpl.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_tmpl.c @@ -910,7 +910,8 @@ static inline int qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp) { - return qla27xx_template_checksum(tmp, tmp->template_size) == 0; + return qla27xx_template_checksum(tmp, + le32_to_cpu(tmp->template_size)) == 0; } static inline int @@ -926,7 +927,7 @@ ulong len = 0; if (qla27xx_fwdt_template_valid(tmp)) { - len = tmp->template_size; + len = le32_to_cpu(tmp->template_size); tmp = memcpy(buf, tmp, len); ql27xx_edit_template(vha, tmp); qla27xx_walk_template(vha, tmp, buf, &len); @@ -942,7 +943,7 @@ ulong len = 0; if (qla27xx_fwdt_template_valid(tmp)) { - len = tmp->template_size; + len = le32_to_cpu(tmp->template_size); qla27xx_walk_template(vha, tmp, NULL, &len); } @@ -954,7 +955,7 @@ { struct qla27xx_fwdt_template *tmp = p; - return tmp->template_size; + return le32_to_cpu(tmp->template_size); } int --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/qla_tmpl.h +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/qla_tmpl.h @@ -13,7 +13,7 @@ struct __packed qla27xx_fwdt_template { __le32 template_type; __le32 entry_offset; - uint32_t template_size; + __le32 template_size; uint32_t count; /* borrow field for running/residual count */ __le32 entry_count; --- linux-oracle-5.4.0.orig/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ linux-oracle-5.4.0/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -246,6 +246,8 @@ */ static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) { + if (!mcmd) + return; INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); } @@ -348,6 +350,7 @@ target_sess_cmd_list_set_waiting(se_sess); spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + sess->explicit_logout = 1; tcm_qla2xxx_put_sess(sess); } @@ -620,7 +623,6 @@ { struct qla_tgt_cmd *cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); - struct scsi_qla_host *vha = cmd->vha; if (cmd->aborted) { /* Cmd can loop during Q-full. tcm_qla2xxx_aborted_task @@ -633,7 +635,6 @@ cmd->se_cmd.transport_state, cmd->se_cmd.t_state, cmd->se_cmd.se_cmd_flags); - vha->hw->tgt.tgt_ops->free_cmd(cmd); return 0; } @@ -661,7 +662,6 @@ { struct qla_tgt_cmd *cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); - struct scsi_qla_host *vha = cmd->vha; int xmit_type = QLA_TGT_XMIT_STATUS; if (cmd->aborted) { @@ -675,7 +675,6 @@ cmd, kref_read(&cmd->se_cmd.cmd_kref), cmd->se_cmd.transport_state, cmd->se_cmd.t_state, cmd->se_cmd.se_cmd_flags); - vha->hw->tgt.tgt_ops->free_cmd(cmd); return 0; } cmd->bufflen = se_cmd->data_length; @@ -923,6 +922,7 @@ atomic_set(&tpg->lport_tpg_enabled, 0); qlt_stop_phase1(vha->vha_tgt.qla_tgt); + qlt_stop_phase2(vha->vha_tgt.qla_tgt); } return count; @@ -1085,6 +1085,7 @@ atomic_set(&tpg->lport_tpg_enabled, 0); qlt_stop_phase1(vha->vha_tgt.qla_tgt); + qlt_stop_phase2(vha->vha_tgt.qla_tgt); } return count; --- linux-oracle-5.4.0.orig/drivers/scsi/qla4xxx/ql4_mbx.c +++ linux-oracle-5.4.0/drivers/scsi/qla4xxx/ql4_mbx.c @@ -640,9 +640,6 @@ if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) != QLA_SUCCESS) { - dma_free_coherent(&ha->pdev->dev, - sizeof(struct addr_ctrl_blk), - init_fw_cb, init_fw_cb_dma); goto exit_init_fw_cb; } --- linux-oracle-5.4.0.orig/drivers/scsi/qla4xxx/ql4_os.c +++ linux-oracle-5.4.0/drivers/scsi/qla4xxx/ql4_os.c @@ -939,6 +939,11 @@ memset(&chap_rec, 0, sizeof(chap_rec)); nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*param_info)) { + rc = -EINVAL; + goto exit_set_chap; + } + param_info = nla_data(attr); switch (param_info->param) { @@ -1220,7 +1225,7 @@ le64_to_cpu(ql_iscsi_stats->iscsi_sequence_error); exit_host_stats: if (ql_iscsi_stats) - dma_free_coherent(&ha->pdev->dev, host_stats_size, + dma_free_coherent(&ha->pdev->dev, stats_size, ql_iscsi_stats, iscsi_stats_dma); ql4_printk(KERN_INFO, ha, "%s: Get host stats done\n", @@ -2723,6 +2728,11 @@ } nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*iface_param)) { + rval = -EINVAL; + goto exit_init_fw_cb; + } + iface_param = nla_data(attr); if (iface_param->param_type == ISCSI_NET_PARAM) { @@ -4145,7 +4155,7 @@ dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, ha->queues_dma); - if (ha->fw_dump) + if (ha->fw_dump) vfree(ha->fw_dump); ha->queues_len = 0; @@ -4275,7 +4285,6 @@ return QLA_SUCCESS; mem_alloc_error_exit: - qla4xxx_mem_free(ha); return QLA_ERROR; } @@ -8094,6 +8103,11 @@ memset((void *)&chap_tbl, 0, sizeof(chap_tbl)); nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*fnode_param)) { + rc = -EINVAL; + goto exit_set_param; + } + fnode_param = nla_data(attr); switch (fnode_param->param) { --- linux-oracle-5.4.0.orig/drivers/scsi/raid_class.c +++ linux-oracle-5.4.0/drivers/scsi/raid_class.c @@ -209,53 +209,6 @@ raid_attr_ro_fn(resync); raid_attr_ro_state_fn(state); -static void raid_component_release(struct device *dev) -{ - struct raid_component *rc = - container_of(dev, struct raid_component, dev); - dev_printk(KERN_ERR, rc->dev.parent, "COMPONENT RELEASE\n"); - put_device(rc->dev.parent); - kfree(rc); -} - -int raid_component_add(struct raid_template *r,struct device *raid_dev, - struct device *component_dev) -{ - struct device *cdev = - attribute_container_find_class_device(&r->raid_attrs.ac, - raid_dev); - struct raid_component *rc; - struct raid_data *rd = dev_get_drvdata(cdev); - int err; - - rc = kzalloc(sizeof(*rc), GFP_KERNEL); - if (!rc) - return -ENOMEM; - - INIT_LIST_HEAD(&rc->node); - device_initialize(&rc->dev); - rc->dev.release = raid_component_release; - rc->dev.parent = get_device(component_dev); - rc->num = rd->component_count++; - - dev_set_name(&rc->dev, "component-%d", rc->num); - list_add_tail(&rc->node, &rd->component_list); - rc->dev.class = &raid_class.class; - err = device_add(&rc->dev); - if (err) - goto err_out; - - return 0; - -err_out: - list_del(&rc->node); - rd->component_count--; - put_device(component_dev); - kfree(rc); - return err; -} -EXPORT_SYMBOL(raid_component_add); - struct raid_template * raid_class_attach(struct raid_function_template *ft) { --- linux-oracle-5.4.0.orig/drivers/scsi/scsi.c +++ linux-oracle-5.4.0/drivers/scsi/scsi.c @@ -331,11 +331,18 @@ if (result) return -EIO; - /* Sanity check that we got the page back that we asked for */ + /* + * Sanity check that we got the page back that we asked for and that + * the page size is not 0. + */ if (buffer[1] != page) return -EIO; - return get_unaligned_be16(&buffer[2]) + 4; + result = get_unaligned_be16(&buffer[2]); + if (!result) + return -EIO; + + return result + 4; } /** @@ -555,8 +562,10 @@ */ void scsi_device_put(struct scsi_device *sdev) { - module_put(sdev->host->hostt->module); + struct module *mod = sdev->host->hostt->module; + put_device(&sdev->sdev_gendev); + module_put(mod); } EXPORT_SYMBOL(scsi_device_put); --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_debug.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_debug.c @@ -1658,7 +1658,7 @@ { unsigned char *cmd = scp->cmnd; unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; - int alloc_len; + u32 alloc_len; alloc_len = get_unaligned_be32(cmd + 10); /* following just in case virtual_gb changed */ @@ -1687,7 +1687,7 @@ } return fill_from_dev_buffer(scp, arr, - min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); + min_t(u32, alloc_len, SDEBUG_READCAP16_ARR_SZ)); } #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 @@ -1698,8 +1698,9 @@ unsigned char *cmd = scp->cmnd; unsigned char *arr; int host_no = devip->sdbg_host->shost->host_no; - int n, ret, alen, rlen; int port_group_a, port_group_b, port_a, port_b; + u32 alen, n, rlen; + int ret; alen = get_unaligned_be32(cmd + 6); arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC); @@ -1761,9 +1762,9 @@ * - The constructed command length * - The maximum array size */ - rlen = min(alen,n); + rlen = min(alen, n); ret = fill_from_dev_buffer(scp, arr, - min(rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); + min_t(u32, rlen, SDEBUG_MAX_TGTPGS_ARR_SZ)); kfree(arr); return ret; } @@ -2296,11 +2297,11 @@ __func__, param_len, res); md_len = mselect6 ? (arr[0] + 1) : (get_unaligned_be16(arr + 0) + 2); bd_len = mselect6 ? arr[3] : get_unaligned_be16(arr + 6); - if (md_len > 2) { + off = bd_len + (mselect6 ? 4 : 8); + if (md_len > 2 || off >= res) { mk_sense_invalid_fld(scp, SDEB_IN_DATA, 0, -1); return check_condition_result; } - off = bd_len + (mselect6 ? 4 : 8); mpage = arr[off] & 0x3f; ps = !!(arr[off] & 0x80); if (ps) { @@ -3139,7 +3140,7 @@ mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); return illegal_condition_result; } - lrdp = kzalloc(lbdof_blen, GFP_ATOMIC); + lrdp = kzalloc(lbdof_blen, GFP_ATOMIC | __GFP_NOWARN); if (lrdp == NULL) return SCSI_MLQUEUE_HOST_BUSY; if (sdebug_verbose) @@ -5263,6 +5264,11 @@ return -EINVAL; } + if (sdebug_num_tgts < 0) { + pr_err("num_tgts must be >= 0\n"); + return -EINVAL; + } + if (sdebug_guard > 1) { pr_err("guard must be 0 or 1\n"); return -EINVAL; @@ -5291,6 +5297,12 @@ pr_err("submit_queues must be 1 or more\n"); return -EINVAL; } + + if ((sdebug_max_queue > SDEBUG_CANQUEUE) || (sdebug_max_queue < 1)) { + pr_err("max_queue must be in range [1, %d]\n", SDEBUG_CANQUEUE); + return -EINVAL; + } + sdebug_q_arr = kcalloc(submit_queues, sizeof(struct sdebug_queue), GFP_KERNEL); if (sdebug_q_arr == NULL) --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_debugfs.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_debugfs.c @@ -10,6 +10,7 @@ SCSI_CMD_FLAG_NAME(TAGGED), SCSI_CMD_FLAG_NAME(UNCHECKED_ISA_DMA), SCSI_CMD_FLAG_NAME(INITIALIZED), + SCSI_CMD_FLAG_NAME(LAST), }; #undef SCSI_CMD_FLAG_NAME --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_devinfo.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_devinfo.c @@ -184,6 +184,7 @@ {"HP", "C3323-300", "4269", BLIST_NOTQ}, {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, {"HP", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, + {"HPE", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, @@ -231,6 +232,7 @@ {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"SKhynix", "H28U74301AMR", NULL, BLIST_SKIP_VPD_PAGES}, {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, @@ -239,6 +241,7 @@ {"LSI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"ENGENIO", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"LENOVO", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, + {"FUJITSU", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SanDisk", "Cruzer Blade", NULL, BLIST_TRY_VPD_PAGES | BLIST_INQUIRY_36}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_dh.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_dh.c @@ -63,6 +63,7 @@ {"LSI", "INF-01-00", "rdac", }, {"ENGENIO", "INF-01-00", "rdac", }, {"LENOVO", "DE_Series", "rdac", }, + {"FUJITSU", "ETERNUS_AHB", "rdac", }, {NULL, NULL, NULL }, }; --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_error.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_error.c @@ -116,6 +116,14 @@ return 1; } +static bool scsi_cmd_retry_allowed(struct scsi_cmnd *cmd) +{ + if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) + return true; + + return ++cmd->retries <= cmd->allowed; +} + /** * scmd_eh_abort_handler - Handle command aborts * @work: command to be aborted. @@ -151,7 +159,7 @@ "eh timeout, not retrying " "aborted command\n")); } else if (!scsi_noretry_cmd(scmd) && - (++scmd->retries <= scmd->allowed)) { + scsi_cmd_retry_allowed(scmd)) { SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_WARNING, scmd, "retry aborted command\n")); @@ -1264,11 +1272,18 @@ * upper level. */ if (rtn == SUCCESS) - /* we don't want this command reissued, just - * finished with the sense data, so set - * retries to the max allowed to ensure it - * won't get reissued */ - scmd->retries = scmd->allowed; + /* + * We don't want this command reissued, just finished + * with the sense data, so set retries to the max + * allowed to ensure it won't get reissued. If the user + * has requested infinite retries, we also want to + * finish this command, so force completion by setting + * retries and allowed to the same value. + */ + if (scmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) + scmd->retries = scmd->allowed = 1; + else + scmd->retries = scmd->allowed; else if (rtn != NEEDS_RETRY) continue; @@ -1942,8 +1957,7 @@ * the request was not marked fast fail. Note that above, * even if the request is marked fast fail, we still requeue * for queue congestion conditions (QUEUE_FULL or BUSY) */ - if ((++scmd->retries) <= scmd->allowed - && !scsi_noretry_cmd(scmd)) { + if (scsi_cmd_retry_allowed(scmd) && !scsi_noretry_cmd(scmd)) { return NEEDS_RETRY; } else { /* @@ -2089,8 +2103,7 @@ list_for_each_entry_safe(scmd, next, done_q, eh_entry) { list_del_init(&scmd->eh_entry); if (scsi_device_online(scmd->device) && - !scsi_noretry_cmd(scmd) && - (++scmd->retries <= scmd->allowed)) { + !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd)) { SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd, "%s: flush retry cmd\n", --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_lib.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_lib.c @@ -551,7 +551,7 @@ } } -static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd) +static void scsi_free_sgtables(struct scsi_cmnd *cmd) { if (cmd->sdb.table.nents) sg_free_table_chained(&cmd->sdb.table, @@ -563,11 +563,20 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd) { - scsi_mq_free_sgtables(cmd); + scsi_free_sgtables(cmd); scsi_uninit_cmd(cmd); scsi_del_cmd_from_list(cmd); } +static void scsi_run_queue_async(struct scsi_device *sdev) +{ + if (scsi_target(sdev)->single_lun || + !list_empty(&sdev->host->starved_list)) + kblockd_schedule_work(&sdev->requeue_work); + else + blk_mq_run_hw_queues(sdev->request_queue, true); +} + /* Returns false when no more bytes to process, true if there are more */ static bool scsi_end_request(struct request *req, blk_status_t error, unsigned int bytes) @@ -612,11 +621,7 @@ __blk_mq_end_request(req, error); - if (scsi_target(sdev)->single_lun || - !list_empty(&sdev->host->starved_list)) - kblockd_schedule_work(&sdev->requeue_work); - else - blk_mq_run_hw_queues(q, true); + scsi_run_queue_async(sdev); percpu_ref_put(&q->q_usage_counter); return false; @@ -669,6 +674,23 @@ scsi_mq_requeue_cmd(cmd); } +static bool scsi_cmd_runtime_exceeced(struct scsi_cmnd *cmd) +{ + struct request *req = cmd->request; + unsigned long wait_for; + + if (cmd->allowed == SCSI_CMD_RETRIES_NO_LIMIT) + return false; + + wait_for = (cmd->allowed + 1) * req->timeout; + if (time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { + scmd_printk(KERN_ERR, cmd, "timing out command, waited %lus\n", + wait_for/HZ); + return true; + } + return false; +} + /* Helper for scsi_io_completion() when special action required. */ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) { @@ -677,7 +699,6 @@ int level = 0; enum {ACTION_FAIL, ACTION_REPREP, ACTION_RETRY, ACTION_DELAYED_RETRY} action; - unsigned long wait_for = (cmd->allowed + 1) * req->timeout; struct scsi_sense_hdr sshdr; bool sense_valid; bool sense_current = true; /* false implies "deferred sense" */ @@ -757,6 +778,7 @@ case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x11: /* notify (enable spinup) required */ case 0x14: /* space allocation in progress */ case 0x1a: /* start stop unit in progress */ case 0x1b: /* sanitize in progress */ @@ -782,8 +804,7 @@ } else action = ACTION_FAIL; - if (action != ACTION_FAIL && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) + if (action != ACTION_FAIL && scsi_cmd_runtime_exceeced(cmd)) action = ACTION_FAIL; switch (action) { @@ -1063,7 +1084,7 @@ return BLK_STS_OK; out_free_sgtables: - scsi_mq_free_sgtables(cmd); + scsi_free_sgtables(cmd); return ret; } EXPORT_SYMBOL(scsi_init_io); @@ -1214,6 +1235,7 @@ struct request *req) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + blk_status_t ret; if (!blk_rq_bytes(req)) cmd->sc_data_direction = DMA_NONE; @@ -1223,9 +1245,14 @@ cmd->sc_data_direction = DMA_FROM_DEVICE; if (blk_rq_is_scsi(req)) - return scsi_setup_scsi_cmnd(sdev, req); + ret = scsi_setup_scsi_cmnd(sdev, req); else - return scsi_setup_fs_cmnd(sdev, req); + ret = scsi_setup_fs_cmnd(sdev, req); + + if (ret != BLK_STS_OK) + scsi_free_sgtables(cmd); + + return ret; } static blk_status_t @@ -1452,7 +1479,6 @@ static void scsi_softirq_done(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); - unsigned long wait_for = (cmd->allowed + 1) * rq->timeout; int disposition; INIT_LIST_HEAD(&cmd->eh_entry); @@ -1462,13 +1488,8 @@ atomic_inc(&cmd->device->ioerr_cnt); disposition = scsi_decide_disposition(cmd); - if (disposition != SUCCESS && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { - scmd_printk(KERN_ERR, cmd, - "timing out command, waited %lus\n", - wait_for/HZ); + if (disposition != SUCCESS && scsi_cmd_runtime_exceeced(cmd)) disposition = SUCCESS; - } scsi_log_completion(cmd, disposition); @@ -1522,6 +1543,7 @@ */ SCSI_LOG_MLQUEUE(3, scmd_printk(KERN_INFO, cmd, "queuecommand : device blocked\n")); + atomic_dec(&cmd->device->iorequest_cnt); return SCSI_MLQUEUE_DEVICE_BUSY; } @@ -1554,6 +1576,7 @@ trace_scsi_dispatch_cmd_start(cmd); rtn = host->hostt->queuecommand(host, cmd); if (rtn) { + atomic_dec(&cmd->device->iorequest_cnt); trace_scsi_dispatch_cmd_error(cmd, rtn); if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && rtn != SCSI_MLQUEUE_TARGET_BUSY) @@ -1606,18 +1629,12 @@ static void scsi_mq_done(struct scsi_cmnd *cmd) { + if (unlikely(blk_should_fake_timeout(cmd->request->q))) + return; if (unlikely(test_and_set_bit(SCMD_STATE_COMPLETE, &cmd->state))) return; trace_scsi_dispatch_cmd_done(cmd); - - /* - * If the block layer didn't complete the request due to a timeout - * injection, scsi must clear its internal completed state so that the - * timeout handler will see it needs to escalate its own error - * recovery. - */ - if (unlikely(!blk_mq_complete_request(cmd->request))) - clear_bit(SCMD_STATE_COMPLETE, &cmd->state); + blk_mq_complete_request(cmd->request); } static void scsi_mq_put_budget(struct blk_mq_hw_ctx *hctx) @@ -1633,12 +1650,7 @@ struct request_queue *q = hctx->queue; struct scsi_device *sdev = q->queuedata; - if (scsi_dev_queue_ready(q, sdev)) - return true; - - if (atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev)) - blk_mq_delay_run_hw_queue(hctx, SCSI_QUEUE_DELAY); - return false; + return scsi_dev_queue_ready(q, sdev); } static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, @@ -1707,8 +1719,7 @@ case BLK_STS_OK: break; case BLK_STS_RESOURCE: - if (atomic_read(&sdev->device_busy) || - scsi_device_blocked(sdev)) + if (scsi_device_blocked(sdev)) ret = BLK_STS_DEV_RESOURCE; break; default: @@ -1723,6 +1734,7 @@ */ if (req->rq_flags & RQF_DONTPREP) scsi_mq_uninit_cmd(cmd); + scsi_run_queue_async(sdev); break; } return ret; @@ -2918,6 +2930,78 @@ } EXPORT_SYMBOL(sdev_enable_disk_events); +static unsigned char designator_prio(const unsigned char *d) +{ + if (d[1] & 0x30) + /* not associated with LUN */ + return 0; + + if (d[3] == 0) + /* invalid length */ + return 0; + + /* + * Order of preference for lun descriptor: + * - SCSI name string + * - NAA IEEE Registered Extended + * - EUI-64 based 16-byte + * - EUI-64 based 12-byte + * - NAA IEEE Registered + * - NAA IEEE Extended + * - EUI-64 based 8-byte + * - SCSI name string (truncated) + * - T10 Vendor ID + * as longer descriptors reduce the likelyhood + * of identification clashes. + */ + + switch (d[1] & 0xf) { + case 8: + /* SCSI name string, variable-length UTF-8 */ + return 9; + case 3: + switch (d[4] >> 4) { + case 6: + /* NAA registered extended */ + return 8; + case 5: + /* NAA registered */ + return 5; + case 4: + /* NAA extended */ + return 4; + case 3: + /* NAA locally assigned */ + return 1; + default: + break; + } + break; + case 2: + switch (d[3]) { + case 16: + /* EUI64-based, 16 byte */ + return 7; + case 12: + /* EUI64-based, 12 byte */ + return 6; + case 8: + /* EUI64-based, 8 byte */ + return 3; + default: + break; + } + break; + case 1: + /* T10 vendor ID */ + return 1; + default: + break; + } + + return 0; +} + /** * scsi_vpd_lun_id - return a unique device identification * @sdev: SCSI device @@ -2934,7 +3018,7 @@ */ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len) { - u8 cur_id_type = 0xff; + u8 cur_id_prio = 0; u8 cur_id_size = 0; const unsigned char *d, *cur_id_str; const struct scsi_vpd *vpd_pg83; @@ -2947,20 +3031,6 @@ return -ENXIO; } - /* - * Look for the correct descriptor. - * Order of preference for lun descriptor: - * - SCSI name string - * - NAA IEEE Registered Extended - * - EUI-64 based 16-byte - * - EUI-64 based 12-byte - * - NAA IEEE Registered - * - NAA IEEE Extended - * - T10 Vendor ID - * as longer descriptors reduce the likelyhood - * of identification clashes. - */ - /* The id string must be at least 20 bytes + terminating NULL byte */ if (id_len < 21) { rcu_read_unlock(); @@ -2970,8 +3040,9 @@ memset(id, 0, id_len); d = vpd_pg83->data + 4; while (d < vpd_pg83->data + vpd_pg83->len) { - /* Skip designators not referring to the LUN */ - if ((d[1] & 0x30) != 0x00) + u8 prio = designator_prio(d); + + if (prio == 0 || cur_id_prio > prio) goto next_desig; switch (d[1] & 0xf) { @@ -2979,28 +3050,19 @@ /* T10 Vendor ID */ if (cur_id_size > d[3]) break; - /* Prefer anything */ - if (cur_id_type > 0x01 && cur_id_type != 0xff) - break; + cur_id_prio = prio; cur_id_size = d[3]; if (cur_id_size + 4 > id_len) cur_id_size = id_len - 4; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; id_size = snprintf(id, id_len, "t10.%*pE", cur_id_size, cur_id_str); break; case 0x2: /* EUI-64 */ - if (cur_id_size > d[3]) - break; - /* Prefer NAA IEEE Registered Extended */ - if (cur_id_type == 0x3 && - cur_id_size == d[3]) - break; + cur_id_prio = prio; cur_id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; switch (cur_id_size) { case 8: id_size = snprintf(id, id_len, @@ -3018,17 +3080,14 @@ cur_id_str); break; default: - cur_id_size = 0; break; } break; case 0x3: /* NAA */ - if (cur_id_size > d[3]) - break; + cur_id_prio = prio; cur_id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; switch (cur_id_size) { case 8: id_size = snprintf(id, id_len, @@ -3041,26 +3100,25 @@ cur_id_str); break; default: - cur_id_size = 0; break; } break; case 0x8: /* SCSI name string */ - if (cur_id_size + 4 > d[3]) + if (cur_id_size > d[3]) break; /* Prefer others for truncated descriptor */ - if (cur_id_size && d[3] > id_len) - break; + if (d[3] > id_len) { + prio = 2; + if (cur_id_prio > prio) + break; + } + cur_id_prio = prio; cur_id_size = id_size = d[3]; cur_id_str = d + 4; - cur_id_type = d[1] & 0xf; if (cur_id_size >= id_len) cur_id_size = id_len - 1; memcpy(id, cur_id_str, cur_id_size); - /* Decrease priority for truncated descriptor */ - if (cur_id_size != id_size) - cur_id_size = 6; break; default: break; --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_pm.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_pm.c @@ -80,6 +80,10 @@ dev_dbg(dev, "scsi resume: %d\n", err); if (err == 0) { + bool was_runtime_suspended; + + was_runtime_suspended = pm_runtime_suspended(dev); + pm_runtime_disable(dev); err = pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -93,8 +97,10 @@ */ if (!err && scsi_is_sdev_device(dev)) { struct scsi_device *sdev = to_scsi_device(dev); - - blk_set_runtime_active(sdev->request_queue); + if (was_runtime_suspended) + blk_post_runtime_resume(sdev->request_queue, 0); + else + blk_set_runtime_active(sdev->request_queue); } } --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_priv.h +++ linux-oracle-5.4.0/drivers/scsi/scsi_priv.h @@ -15,6 +15,7 @@ struct Scsi_Host; struct scsi_nl_hdr; +#define SCSI_CMD_RETRIES_NO_LIMIT -1 /* * Scsi Error Handler Flags --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_proc.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_proc.c @@ -311,7 +311,7 @@ size_t length, loff_t *ppos) { int host, channel, id, lun; - char *buffer, *p; + char *buffer, *end, *p; int err; if (!buf || length > PAGE_SIZE) @@ -326,10 +326,14 @@ goto out; err = -EINVAL; - if (length < PAGE_SIZE) - buffer[length] = '\0'; - else if (buffer[PAGE_SIZE-1]) - goto out; + if (length < PAGE_SIZE) { + end = buffer + length; + *end = '\0'; + } else { + end = buffer + PAGE_SIZE - 1; + if (*end) + goto out; + } /* * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi @@ -338,10 +342,10 @@ if (!strncmp("scsi add-single-device", buffer, 22)) { p = buffer + 23; - host = simple_strtoul(p, &p, 0); - channel = simple_strtoul(p + 1, &p, 0); - id = simple_strtoul(p + 1, &p, 0); - lun = simple_strtoul(p + 1, &p, 0); + host = (p < end) ? simple_strtoul(p, &p, 0) : 0; + channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; err = scsi_add_single_device(host, channel, id, lun); @@ -352,10 +356,10 @@ } else if (!strncmp("scsi remove-single-device", buffer, 25)) { p = buffer + 26; - host = simple_strtoul(p, &p, 0); - channel = simple_strtoul(p + 1, &p, 0); - id = simple_strtoul(p + 1, &p, 0); - lun = simple_strtoul(p + 1, &p, 0); + host = (p < end) ? simple_strtoul(p, &p, 0) : 0; + channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; err = scsi_remove_single_device(host, channel, id, lun); } --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_scan.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_scan.c @@ -454,7 +454,8 @@ error = shost->hostt->target_alloc(starget); if(error) { - dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error); + if (error != -ENXIO) + dev_err(dev, "target allocation failed, error %d\n", error); /* don't want scsi_target_reap to do the final * put because it will be under the host lock */ scsi_target_destroy(starget); @@ -1129,8 +1130,7 @@ * that no LUN is present, so don't add sdev in these cases. * Two specific examples are: * 1) NetApp targets: return PQ=1, PDT=0x1f - * 2) IBM/2145 targets: return PQ=1, PDT=0 - * 3) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" + * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved" * in the UFI 1.0 spec (we cannot rely on reserved bits). * * References: @@ -1144,8 +1144,8 @@ * PDT=00h Direct-access device (floppy) * PDT=1Fh none (no FDD connected to the requested logical unit) */ - if (((result[0] >> 5) == 1 || - (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f)) && + if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && + (result[0] & 0x1f) == 0x1f && !scsi_is_wlun(lun)) { SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, "scsi scan: peripheral device type" @@ -1715,15 +1715,16 @@ */ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) { - struct async_scan_data *data; + struct async_scan_data *data = NULL; unsigned long flags; if (strncmp(scsi_scan_type, "sync", 4) == 0) return NULL; + mutex_lock(&shost->scan_mutex); if (shost->async_scan) { shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__); - return NULL; + goto err; } data = kmalloc(sizeof(*data), GFP_KERNEL); @@ -1734,7 +1735,6 @@ goto err; init_completion(&data->prev_finished); - mutex_lock(&shost->scan_mutex); spin_lock_irqsave(shost->host_lock, flags); shost->async_scan = 1; spin_unlock_irqrestore(shost->host_lock, flags); @@ -1749,6 +1749,7 @@ return data; err: + mutex_unlock(&shost->scan_mutex); kfree(data); return NULL; } --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_sysfs.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_sysfs.c @@ -438,9 +438,12 @@ struct list_head *this, *tmp; struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; unsigned long flags; + struct module *mod; sdev = container_of(work, struct scsi_device, ew.work); + mod = sdev->host->hostt->module; + scsi_dh_release_device(sdev); parent = sdev->sdev_gendev.parent; @@ -481,11 +484,17 @@ if (parent) put_device(parent); + module_put(mod); } static void scsi_device_dev_release(struct device *dev) { struct scsi_device *sdp = to_scsi_device(dev); + + /* Set module pointer as NULL in case of module unloading */ + if (!try_module_get(sdp->host->hostt->module)) + sdp->host->hostt->module = NULL; + execute_in_process_context(scsi_device_dev_release_usercontext, &sdp->ew); } @@ -767,6 +776,7 @@ int i, ret; struct scsi_device *sdev = to_scsi_device(dev); enum scsi_device_state state = 0; + bool rescan_dev = false; for (i = 0; i < ARRAY_SIZE(sdev_states); i++) { const int len = strlen(sdev_states[i].name); @@ -785,15 +795,36 @@ } mutex_lock(&sdev->state_mutex); - ret = scsi_device_set_state(sdev, state); - /* - * If the device state changes to SDEV_RUNNING, we need to run - * the queue to avoid I/O hang. - */ - if (ret == 0 && state == SDEV_RUNNING) - blk_mq_run_hw_queues(sdev->request_queue, true); + switch (sdev->sdev_state) { + case SDEV_RUNNING: + case SDEV_OFFLINE: + break; + default: + mutex_unlock(&sdev->state_mutex); + return -EINVAL; + } + if (sdev->sdev_state == SDEV_RUNNING && state == SDEV_RUNNING) { + ret = 0; + } else { + ret = scsi_device_set_state(sdev, state); + if (ret == 0 && state == SDEV_RUNNING) + rescan_dev = true; + } mutex_unlock(&sdev->state_mutex); + if (rescan_dev) { + /* + * If the device state changes to SDEV_RUNNING, we need to + * run the queue to avoid I/O hang, and rescan the device + * to revalidate it. Running the queue first is necessary + * because another thread may be waiting inside + * blk_mq_freeze_queue_wait() and because that call may be + * waiting for pending I/O to finish. + */ + blk_mq_run_hw_queues(sdev->request_queue, true); + scsi_rescan_device(dev); + } + return ret == 0 ? count : -EINVAL; } --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_trace.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_trace.c @@ -9,7 +9,7 @@ #include #define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f) -#define SERVICE_ACTION32(cdb) ((cdb[8] << 8) | cdb[9]) +#define SERVICE_ACTION32(cdb) (get_unaligned_be16(&cdb[8])) static const char * scsi_trace_misc(struct trace_seq *, unsigned char *, int); @@ -18,15 +18,18 @@ scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); - sector_t lba = 0, txlen = 0; + u32 lba = 0, txlen; lba |= ((cdb[1] & 0x1F) << 16); lba |= (cdb[2] << 8); lba |= cdb[3]; - txlen = cdb[4]; + /* + * From SBC-2: a TRANSFER LENGTH field set to zero specifies that 256 + * logical blocks shall be read (READ(6)) or written (WRITE(6)). + */ + txlen = cdb[4] ? cdb[4] : 256; - trace_seq_printf(p, "lba=%llu txlen=%llu", - (unsigned long long)lba, (unsigned long long)txlen); + trace_seq_printf(p, "lba=%u txlen=%u", lba, txlen); trace_seq_putc(p, 0); return ret; @@ -36,17 +39,12 @@ scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); - sector_t lba = 0, txlen = 0; + u32 lba, txlen; - lba |= (cdb[2] << 24); - lba |= (cdb[3] << 16); - lba |= (cdb[4] << 8); - lba |= cdb[5]; - txlen |= (cdb[7] << 8); - txlen |= cdb[8]; + lba = get_unaligned_be32(&cdb[2]); + txlen = get_unaligned_be16(&cdb[7]); - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, + trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen, cdb[1] >> 5); if (cdb[0] == WRITE_SAME) @@ -61,19 +59,12 @@ scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); - sector_t lba = 0, txlen = 0; + u32 lba, txlen; - lba |= (cdb[2] << 24); - lba |= (cdb[3] << 16); - lba |= (cdb[4] << 8); - lba |= cdb[5]; - txlen |= (cdb[6] << 24); - txlen |= (cdb[7] << 16); - txlen |= (cdb[8] << 8); - txlen |= cdb[9]; + lba = get_unaligned_be32(&cdb[2]); + txlen = get_unaligned_be32(&cdb[6]); - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, + trace_seq_printf(p, "lba=%u txlen=%u protect=%u", lba, txlen, cdb[1] >> 5); trace_seq_putc(p, 0); @@ -84,23 +75,13 @@ scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); - sector_t lba = 0, txlen = 0; + u64 lba; + u32 txlen; - lba |= ((u64)cdb[2] << 56); - lba |= ((u64)cdb[3] << 48); - lba |= ((u64)cdb[4] << 40); - lba |= ((u64)cdb[5] << 32); - lba |= (cdb[6] << 24); - lba |= (cdb[7] << 16); - lba |= (cdb[8] << 8); - lba |= cdb[9]; - txlen |= (cdb[10] << 24); - txlen |= (cdb[11] << 16); - txlen |= (cdb[12] << 8); - txlen |= cdb[13]; + lba = get_unaligned_be64(&cdb[2]); + txlen = get_unaligned_be32(&cdb[10]); - trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u", - (unsigned long long)lba, (unsigned long long)txlen, + trace_seq_printf(p, "lba=%llu txlen=%u protect=%u", lba, txlen, cdb[1] >> 5); if (cdb[0] == WRITE_SAME_16) @@ -115,8 +96,8 @@ scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p), *cmd; - sector_t lba = 0, txlen = 0; - u32 ei_lbrt = 0; + u64 lba; + u32 ei_lbrt, txlen; switch (SERVICE_ACTION32(cdb)) { case READ_32: @@ -136,26 +117,12 @@ goto out; } - lba |= ((u64)cdb[12] << 56); - lba |= ((u64)cdb[13] << 48); - lba |= ((u64)cdb[14] << 40); - lba |= ((u64)cdb[15] << 32); - lba |= (cdb[16] << 24); - lba |= (cdb[17] << 16); - lba |= (cdb[18] << 8); - lba |= cdb[19]; - ei_lbrt |= (cdb[20] << 24); - ei_lbrt |= (cdb[21] << 16); - ei_lbrt |= (cdb[22] << 8); - ei_lbrt |= cdb[23]; - txlen |= (cdb[28] << 24); - txlen |= (cdb[29] << 16); - txlen |= (cdb[30] << 8); - txlen |= cdb[31]; - - trace_seq_printf(p, "%s_32 lba=%llu txlen=%llu protect=%u ei_lbrt=%u", - cmd, (unsigned long long)lba, - (unsigned long long)txlen, cdb[10] >> 5, ei_lbrt); + lba = get_unaligned_be64(&cdb[12]); + ei_lbrt = get_unaligned_be32(&cdb[20]); + txlen = get_unaligned_be32(&cdb[28]); + + trace_seq_printf(p, "%s_32 lba=%llu txlen=%u protect=%u ei_lbrt=%u", + cmd, lba, txlen, cdb[10] >> 5, ei_lbrt); if (SERVICE_ACTION32(cdb) == WRITE_SAME_32) trace_seq_printf(p, " unmap=%u", cdb[10] >> 3 & 1); @@ -170,7 +137,7 @@ scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p); - unsigned int regions = cdb[7] << 8 | cdb[8]; + unsigned int regions = get_unaligned_be16(&cdb[7]); trace_seq_printf(p, "regions=%u", (regions - 8) / 16); trace_seq_putc(p, 0); @@ -182,8 +149,8 @@ scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) { const char *ret = trace_seq_buffer_ptr(p), *cmd; - sector_t lba = 0; - u32 alloc_len = 0; + u64 lba; + u32 alloc_len; switch (SERVICE_ACTION16(cdb)) { case SAI_READ_CAPACITY_16: @@ -197,21 +164,10 @@ goto out; } - lba |= ((u64)cdb[2] << 56); - lba |= ((u64)cdb[3] << 48); - lba |= ((u64)cdb[4] << 40); - lba |= ((u64)cdb[5] << 32); - lba |= (cdb[6] << 24); - lba |= (cdb[7] << 16); - lba |= (cdb[8] << 8); - lba |= cdb[9]; - alloc_len |= (cdb[10] << 24); - alloc_len |= (cdb[11] << 16); - alloc_len |= (cdb[12] << 8); - alloc_len |= cdb[13]; + lba = get_unaligned_be64(&cdb[2]); + alloc_len = get_unaligned_be32(&cdb[10]); - trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, - (unsigned long long)lba, alloc_len); + trace_seq_printf(p, "%s lba=%llu alloc_len=%u", cmd, lba, alloc_len); out: trace_seq_putc(p, 0); --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_transport_iscsi.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_transport_iscsi.c @@ -24,6 +24,8 @@ #define ISCSI_TRANSPORT_VERSION "2.0-870" +#define ISCSI_SEND_MAX_ALLOWED 10 + #define CREATE_TRACE_POINTS #include @@ -122,7 +124,11 @@ char *buf) { struct iscsi_internal *priv = dev_to_iscsi_internal(dev); - return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport)); + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + return sysfs_emit(buf, "%llu\n", + (unsigned long long)iscsi_handle(priv->iscsi_transport)); } static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); @@ -132,7 +138,7 @@ struct device_attribute *attr,char *buf) \ { \ struct iscsi_internal *priv = dev_to_iscsi_internal(dev); \ - return sprintf(buf, format"\n", priv->iscsi_transport->name); \ + return sysfs_emit(buf, format"\n", priv->iscsi_transport->name);\ } \ static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); @@ -173,7 +179,7 @@ show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) { struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); - return sprintf(buf, "%llu\n", (unsigned long long) ep->id); + return sysfs_emit(buf, "%llu\n", (unsigned long long) ep->id); } static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); @@ -426,40 +432,9 @@ struct device *dev = container_of(kobj, struct device, kobj); struct iscsi_iface *iface = iscsi_dev_to_iface(dev); struct iscsi_transport *t = iface->transport; - int param; - int param_type; + int param = -1; - if (attr == &dev_attr_iface_enabled.attr) - param = ISCSI_NET_PARAM_IFACE_ENABLE; - else if (attr == &dev_attr_iface_vlan_id.attr) - param = ISCSI_NET_PARAM_VLAN_ID; - else if (attr == &dev_attr_iface_vlan_priority.attr) - param = ISCSI_NET_PARAM_VLAN_PRIORITY; - else if (attr == &dev_attr_iface_vlan_enabled.attr) - param = ISCSI_NET_PARAM_VLAN_ENABLED; - else if (attr == &dev_attr_iface_mtu.attr) - param = ISCSI_NET_PARAM_MTU; - else if (attr == &dev_attr_iface_port.attr) - param = ISCSI_NET_PARAM_PORT; - else if (attr == &dev_attr_iface_ipaddress_state.attr) - param = ISCSI_NET_PARAM_IPADDR_STATE; - else if (attr == &dev_attr_iface_delayed_ack_en.attr) - param = ISCSI_NET_PARAM_DELAYED_ACK_EN; - else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) - param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; - else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) - param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; - else if (attr == &dev_attr_iface_tcp_wsf.attr) - param = ISCSI_NET_PARAM_TCP_WSF; - else if (attr == &dev_attr_iface_tcp_timer_scale.attr) - param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; - else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) - param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; - else if (attr == &dev_attr_iface_cache_id.attr) - param = ISCSI_NET_PARAM_CACHE_ID; - else if (attr == &dev_attr_iface_redirect_en.attr) - param = ISCSI_NET_PARAM_REDIRECT_EN; - else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) + if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; else if (attr == &dev_attr_iface_header_digest.attr) param = ISCSI_IFACE_PARAM_HDRDGST_EN; @@ -495,6 +470,40 @@ param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN; else if (attr == &dev_attr_iface_initiator_name.attr) param = ISCSI_IFACE_PARAM_INITIATOR_NAME; + + if (param != -1) + return t->attr_is_visible(ISCSI_IFACE_PARAM, param); + + if (attr == &dev_attr_iface_enabled.attr) + param = ISCSI_NET_PARAM_IFACE_ENABLE; + else if (attr == &dev_attr_iface_vlan_id.attr) + param = ISCSI_NET_PARAM_VLAN_ID; + else if (attr == &dev_attr_iface_vlan_priority.attr) + param = ISCSI_NET_PARAM_VLAN_PRIORITY; + else if (attr == &dev_attr_iface_vlan_enabled.attr) + param = ISCSI_NET_PARAM_VLAN_ENABLED; + else if (attr == &dev_attr_iface_mtu.attr) + param = ISCSI_NET_PARAM_MTU; + else if (attr == &dev_attr_iface_port.attr) + param = ISCSI_NET_PARAM_PORT; + else if (attr == &dev_attr_iface_ipaddress_state.attr) + param = ISCSI_NET_PARAM_IPADDR_STATE; + else if (attr == &dev_attr_iface_delayed_ack_en.attr) + param = ISCSI_NET_PARAM_DELAYED_ACK_EN; + else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) + param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; + else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) + param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; + else if (attr == &dev_attr_iface_tcp_wsf.attr) + param = ISCSI_NET_PARAM_TCP_WSF; + else if (attr == &dev_attr_iface_tcp_timer_scale.attr) + param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; + else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) + param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; + else if (attr == &dev_attr_iface_cache_id.attr) + param = ISCSI_NET_PARAM_CACHE_ID; + else if (attr == &dev_attr_iface_redirect_en.attr) + param = ISCSI_NET_PARAM_REDIRECT_EN; else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) { if (attr == &dev_attr_ipv4_iface_ipaddress.attr) param = ISCSI_NET_PARAM_IPV4_ADDR; @@ -585,32 +594,7 @@ return 0; } - switch (param) { - case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO: - case ISCSI_IFACE_PARAM_HDRDGST_EN: - case ISCSI_IFACE_PARAM_DATADGST_EN: - case ISCSI_IFACE_PARAM_IMM_DATA_EN: - case ISCSI_IFACE_PARAM_INITIAL_R2T_EN: - case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN: - case ISCSI_IFACE_PARAM_PDU_INORDER_EN: - case ISCSI_IFACE_PARAM_ERL: - case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH: - case ISCSI_IFACE_PARAM_FIRST_BURST: - case ISCSI_IFACE_PARAM_MAX_R2T: - case ISCSI_IFACE_PARAM_MAX_BURST: - case ISCSI_IFACE_PARAM_CHAP_AUTH_EN: - case ISCSI_IFACE_PARAM_BIDI_CHAP_EN: - case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL: - case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN: - case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN: - case ISCSI_IFACE_PARAM_INITIATOR_NAME: - param_type = ISCSI_IFACE_PARAM; - break; - default: - param_type = ISCSI_NET_PARAM; - } - - return t->attr_is_visible(param_type, param); + return t->attr_is_visible(ISCSI_NET_PARAM, param); } static struct attribute *iscsi_iface_attrs[] = { @@ -1910,12 +1894,12 @@ } spin_unlock_irqrestore(&session->lock, flags); - if (session->transport->session_recovery_timedout) - session->transport->session_recovery_timedout(session); - ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n"); scsi_target_unblock(&session->dev, SDEV_TRANSPORT_OFFLINE); ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n"); + + if (session->transport->session_recovery_timedout) + session->transport->session_recovery_timedout(session); } static void __iscsi_unblock_session(struct work_struct *work) @@ -2010,7 +1994,7 @@ if (session->target_id == ISCSI_MAX_TARGET) { spin_unlock_irqrestore(&session->lock, flags); mutex_unlock(&ihost->mutex); - return; + goto unbind_session_exit; } target_id = session->target_id; @@ -2022,6 +2006,8 @@ ida_simple_remove(&iscsi_sess_ida, target_id); scsi_remove_target(&session->dev); + +unbind_session_exit: iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); } @@ -2300,6 +2286,18 @@ } EXPORT_SYMBOL_GPL(iscsi_destroy_conn); +void iscsi_put_conn(struct iscsi_cls_conn *conn) +{ + put_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_put_conn); + +void iscsi_get_conn(struct iscsi_cls_conn *conn) +{ + get_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_get_conn); + /* * iscsi interface functions */ @@ -2761,11 +2759,18 @@ struct iscsi_cls_session *session; int err = 0, value = 0; + if (ev->u.set_param.len > PAGE_SIZE) + return -EINVAL; + session = iscsi_session_lookup(ev->u.set_param.sid); conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); if (!conn || !session) return -EINVAL; + /* data will be regarded as NULL-ended string, do length check */ + if (strlen(data) > ev->u.set_param.len) + return -EINVAL; + switch (ev->u.set_param.param) { case ISCSI_PARAM_SESS_RECOVERY_TMO: sscanf(data, "%d", &value); @@ -2908,6 +2913,9 @@ if (!transport->set_host_param) return -ENOSYS; + if (ev->u.set_host_param.len > PAGE_SIZE) + return -EINVAL; + shost = scsi_host_lookup(ev->u.set_host_param.host_no); if (!shost) { printk(KERN_ERR "set_host_param could not find host no %u\n", @@ -2915,6 +2923,10 @@ return -ENODEV; } + /* see similar check in iscsi_if_set_param() */ + if (strlen(data) > ev->u.set_host_param.len) + return -EINVAL; + err = transport->set_host_param(shost, ev->u.set_host_param.param, data, ev->u.set_host_param.len); scsi_host_put(shost); @@ -2945,6 +2957,24 @@ return err; } +static int iscsi_session_has_conns(int sid) +{ + struct iscsi_cls_conn *conn; + unsigned long flags; + int found = 0; + + spin_lock_irqsave(&connlock, flags); + list_for_each_entry(conn, &connlist, conn_list) { + if (iscsi_conn_get_sid(conn) == sid) { + found = 1; + break; + } + } + spin_unlock_irqrestore(&connlock, flags); + + return found; +} + static int iscsi_set_iface_params(struct iscsi_transport *transport, struct iscsi_uevent *ev, uint32_t len) @@ -3152,7 +3182,7 @@ pr_err("%s could not find host no %u\n", __func__, ev->u.set_flashnode.host_no); err = -ENODEV; - goto put_host; + goto exit_set_fnode; } idx = ev->u.set_flashnode.flashnode_idx; @@ -3477,6 +3507,7 @@ { int err = 0; u32 portid; + u32 pdu_len; struct iscsi_uevent *ev = nlmsg_data(nlh); struct iscsi_transport *transport = NULL; struct iscsi_internal *priv; @@ -3484,6 +3515,9 @@ struct iscsi_cls_conn *conn; struct iscsi_endpoint *ep = NULL; + if (!netlink_capable(skb, CAP_SYS_ADMIN)) + return -EPERM; + if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE) *group = ISCSI_NL_GRP_UIP; else @@ -3522,10 +3556,12 @@ break; case ISCSI_UEVENT_DESTROY_SESSION: session = iscsi_session_lookup(ev->u.d_session.sid); - if (session) - transport->destroy_session(session); - else + if (!session) err = -EINVAL; + else if (iscsi_session_has_conns(ev->u.d_session.sid)) + err = -EBUSY; + else + transport->destroy_session(session); break; case ISCSI_UEVENT_UNBIND_SESSION: session = iscsi_session_lookup(ev->u.d_session.sid); @@ -3589,6 +3625,14 @@ err = -EINVAL; break; case ISCSI_UEVENT_SEND_PDU: + pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); + + if ((ev->u.send_pdu.hdr_size > pdu_len) || + (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { + err = -EINVAL; + break; + } + conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); if (conn) ev->r.retcode = transport->send_pdu(conn, @@ -3682,6 +3726,7 @@ struct nlmsghdr *nlh; struct iscsi_uevent *ev; uint32_t group; + int retries = ISCSI_SEND_MAX_ALLOWED; nlh = nlmsg_hdr(skb); if (nlh->nlmsg_len < sizeof(*nlh) + sizeof(*ev) || @@ -3701,7 +3746,7 @@ } do { /* - * special case for GET_STATS: + * special case for GET_STATS, GET_CHAP and GET_HOST_STATS: * on success - sending reply and stats from * inside of if_recv_msg(), * on error - fall through. @@ -3710,8 +3755,14 @@ break; if (ev->type == ISCSI_UEVENT_GET_CHAP && !err) break; + if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err) + break; err = iscsi_if_send_reply(portid, nlh->nlmsg_type, ev, sizeof(*ev)); + if (err == -EAGAIN && --retries < 0) { + printk(KERN_WARNING "Send reply failed, error %d\n", err); + break; + } } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH); skb_pull(skb, rlen); } @@ -3769,7 +3820,6 @@ iscsi_conn_attr(tcp_recv_wsf, ISCSI_PARAM_TCP_RECV_WSF); iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR); - #define iscsi_conn_ep_attr_show(param) \ static ssize_t show_conn_ep_param_##param(struct device *dev, \ struct device_attribute *attr,\ @@ -3990,7 +4040,7 @@ char *buf) { struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); - return sprintf(buf, "%s\n", iscsi_session_state_name(session->state)); + return sysfs_emit(buf, "%s\n", iscsi_session_state_name(session->state)); } static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state, NULL); @@ -3999,7 +4049,7 @@ char *buf) { struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); - return sprintf(buf, "%d\n", session->creator); + return sysfs_emit(buf, "%d\n", session->creator); } static ISCSI_CLASS_ATTR(priv_sess, creator, S_IRUGO, show_priv_session_creator, NULL); @@ -4008,7 +4058,7 @@ char *buf) { struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); - return sprintf(buf, "%d\n", session->target_id); + return sysfs_emit(buf, "%d\n", session->target_id); } static ISCSI_CLASS_ATTR(priv_sess, target_id, S_IRUGO, show_priv_session_target_id, NULL); @@ -4021,8 +4071,8 @@ struct iscsi_cls_session *session = \ iscsi_dev_to_session(dev->parent); \ if (session->field == -1) \ - return sprintf(buf, "off\n"); \ - return sprintf(buf, format"\n", session->field); \ + return sysfs_emit(buf, "off\n"); \ + return sysfs_emit(buf, format"\n", session->field); \ } #define iscsi_priv_session_attr_store(field) \ --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_transport_sas.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_transport_sas.c @@ -1391,9 +1391,6 @@ struct sas_rphy *rphy = dev_to_rphy(dev); struct sas_expander_device *edev = rphy_to_expander_device(rphy); - if (rphy->q) - blk_cleanup_queue(rphy->q); - put_device(dev->parent); kfree(edev); } @@ -1403,9 +1400,6 @@ struct sas_rphy *rphy = dev_to_rphy(dev); struct sas_end_device *edev = rphy_to_end_device(rphy); - if (rphy->q) - blk_cleanup_queue(rphy->q); - put_device(dev->parent); kfree(edev); } @@ -1634,8 +1628,7 @@ } sas_rphy_unlink(rphy); - if (rphy->q) - bsg_unregister_queue(rphy->q); + bsg_remove_queue(rphy->q); transport_remove_device(dev); device_del(dev); } --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_transport_spi.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_transport_spi.c @@ -117,12 +117,16 @@ sshdr = &sshdr_tmp; for(i = 0; i < DV_RETRIES; i++) { + /* + * The purpose of the RQF_PM flag below is to bypass the + * SDEV_QUIESCE state. + */ result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense, sshdr, DV_TIMEOUT, /* retries */ 1, REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER, - 0, NULL); + RQF_PM, NULL); if (driver_byte(result) != DRIVER_SENSE || sshdr->sense_key != UNIT_ATTENTION) break; @@ -339,7 +343,7 @@ struct spi_transport_attrs *tp \ = (struct spi_transport_attrs *)&starget->starget_data; \ \ - if (i->f->set_##field) \ + if (!i->f->set_##field) \ return -EINVAL; \ val = simple_strtoul(buf, NULL, 0); \ if (val > tp->max_##field) \ @@ -673,10 +677,10 @@ for (r = 0; r < retries; r++) { result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE, buffer, len, &sshdr); - if(result || !scsi_device_online(sdev)) { + if (result || !scsi_device_online(sdev)) { scsi_device_set_state(sdev, SDEV_QUIESCE); - if (scsi_sense_valid(&sshdr) + if (result > 0 && scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST /* INVALID FIELD IN CDB */ && sshdr.asc == 0x24 && sshdr.ascq == 0x00) @@ -1005,23 +1009,26 @@ */ lock_system_sleep(); + if (scsi_autopm_get_device(sdev)) + goto unlock_system_sleep; + if (unlikely(spi_dv_in_progress(starget))) - goto unlock; + goto put_autopm; if (unlikely(scsi_device_get(sdev))) - goto unlock; + goto put_autopm; spi_dv_in_progress(starget) = 1; buffer = kzalloc(len, GFP_KERNEL); if (unlikely(!buffer)) - goto out_put; + goto put_sdev; /* We need to verify that the actual device will quiesce; the * later target quiesce is just a nice to have */ if (unlikely(scsi_device_quiesce(sdev))) - goto out_free; + goto free_buffer; scsi_target_quiesce(starget); @@ -1041,12 +1048,16 @@ spi_initial_dv(starget) = 1; - out_free: +free_buffer: kfree(buffer); - out_put: + +put_sdev: spi_dv_in_progress(starget) = 0; scsi_device_put(sdev); -unlock: +put_autopm: + scsi_autopm_put_device(sdev); + +unlock_system_sleep: unlock_system_sleep(); } EXPORT_SYMBOL(spi_dv_device); --- linux-oracle-5.4.0.orig/drivers/scsi/scsi_transport_srp.c +++ linux-oracle-5.4.0/drivers/scsi/scsi_transport_srp.c @@ -541,7 +541,14 @@ res = mutex_lock_interruptible(&rport->mutex); if (res) goto out; - scsi_target_block(&shost->shost_gendev); + if (rport->state != SRP_RPORT_FAIL_FAST && rport->state != SRP_RPORT_LOST) + /* + * sdev state must be SDEV_TRANSPORT_OFFLINE, transition + * to SDEV_BLOCK is illegal. Calling scsi_target_unblock() + * later is ok though, scsi_internal_device_unblock_nowait() + * treats SDEV_TRANSPORT_OFFLINE like SDEV_BLOCK. + */ + scsi_target_block(&shost->shost_gendev); res = rport->state != SRP_RPORT_LOST ? i->f->reconnect(rport) : -ENODEV; pr_debug("%s (state %d): transport.reconnect() returned %d\n", dev_name(&shost->shost_gendev), rport->state, res); --- linux-oracle-5.4.0.orig/drivers/scsi/sd.c +++ linux-oracle-5.4.0/drivers/scsi/sd.c @@ -196,7 +196,7 @@ } if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, - SD_MAX_RETRIES, &data, NULL)) + sdkp->max_retries, &data, NULL)) return -EINVAL; len = min_t(size_t, sizeof(buffer), data.length - data.header_length - data.block_descriptor_length); @@ -214,7 +214,7 @@ data.device_specific = 0; if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, - SD_MAX_RETRIES, &data, &sshdr)) { + sdkp->max_retries, &data, &sshdr)) { if (scsi_sense_valid(&sshdr)) sd_print_sense_hdr(sdkp, &sshdr); return -EINVAL; @@ -530,6 +530,39 @@ } static DEVICE_ATTR_RW(max_write_same_blocks); +static ssize_t +max_retries_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdev = sdkp->device; + int retries, err; + + err = kstrtoint(buf, 10, &retries); + if (err) + return err; + + if (retries == SCSI_CMD_RETRIES_NO_LIMIT || retries <= SD_MAX_RETRIES) { + sdkp->max_retries = retries; + return count; + } + + sdev_printk(KERN_ERR, sdev, "max_retries must be between -1 and %d\n", + SD_MAX_RETRIES); + return -EINVAL; +} + +static ssize_t +max_retries_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return sprintf(buf, "%d\n", sdkp->max_retries); +} + +static DEVICE_ATTR_RW(max_retries); + static struct attribute *sd_disk_attrs[] = { &dev_attr_cache_type.attr, &dev_attr_FUA.attr, @@ -543,6 +576,7 @@ &dev_attr_zeroing_mode.attr, &dev_attr_max_write_same_blocks.attr, &dev_attr_max_medium_access_timeouts.attr, + &dev_attr_max_retries.attr, NULL, }; ATTRIBUTE_GROUPS(sd_disk); @@ -651,7 +685,8 @@ static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len, bool send) { - struct scsi_device *sdev = data; + struct scsi_disk *sdkp = data; + struct scsi_device *sdev = sdkp->device; u8 cdb[12] = { 0, }; int ret; @@ -662,7 +697,7 @@ ret = scsi_execute_req(sdev, cdb, send ? DMA_TO_DEVICE : DMA_FROM_DEVICE, - buffer, len, NULL, SD_TIMEOUT, SD_MAX_RETRIES, NULL); + buffer, len, NULL, SD_TIMEOUT, sdkp->max_retries, NULL); return ret <= 0 ? ret : -EIO; } #endif /* CONFIG_BLK_SED_OPAL */ @@ -825,6 +860,7 @@ { struct scsi_device *sdp = cmd->device; struct request *rq = cmd->request; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); unsigned int data_len = 24; @@ -848,7 +884,7 @@ put_unaligned_be64(lba, &buf[8]); put_unaligned_be32(nr_blocks, &buf[16]); - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; cmd->transfersize = data_len; rq->timeout = SD_TIMEOUT; @@ -860,6 +896,7 @@ { struct scsi_device *sdp = cmd->device; struct request *rq = cmd->request; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); u32 data_len = sdp->sector_size; @@ -879,7 +916,7 @@ put_unaligned_be64(lba, &cmd->cmnd[2]); put_unaligned_be32(nr_blocks, &cmd->cmnd[10]); - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; cmd->transfersize = data_len; rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT; @@ -891,6 +928,7 @@ { struct scsi_device *sdp = cmd->device; struct request *rq = cmd->request; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq)); u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); u32 data_len = sdp->sector_size; @@ -910,7 +948,7 @@ put_unaligned_be32(lba, &cmd->cmnd[2]); put_unaligned_be16(nr_blocks, &cmd->cmnd[7]); - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; cmd->transfersize = data_len; rq->timeout = unmap ? SD_TIMEOUT : SD_WRITE_SAME_TIMEOUT; @@ -934,8 +972,10 @@ } } - if (sdp->no_write_same) + if (sdp->no_write_same) { + rq->rq_flags |= RQF_QUIET; return BLK_STS_TARGET; + } if (sdkp->ws16 || lba > 0xffffffff || nr_blocks > 0xffff) return sd_setup_write_same16_cmnd(cmd, false); @@ -1042,7 +1082,7 @@ } cmd->transfersize = sdp->sector_size; - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; /* * For WRITE SAME the data transferred via the DATA OUT buffer is @@ -1064,6 +1104,7 @@ static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd) { struct request *rq = cmd->request; + struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); /* flush requests don't perform I/O, zero the S/G table */ memset(&cmd->sdb, 0, sizeof(cmd->sdb)); @@ -1071,7 +1112,7 @@ cmd->cmnd[0] = SYNCHRONIZE_CACHE; cmd->cmd_len = 10; cmd->transfersize = 0; - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; rq->timeout = rq->q->rq_timeout * SD_FLUSH_TIMEOUT_MULTIPLIER; return BLK_STS_OK; @@ -1242,7 +1283,7 @@ */ cmd->transfersize = sdp->sector_size; cmd->underflow = nr_blocks << 9; - cmd->allowed = SD_MAX_RETRIES; + cmd->allowed = sdkp->max_retries; cmd->sdb.length = nr_blocks * sdp->sector_size; SCSI_LOG_HLQUEUE(1, @@ -1584,7 +1625,7 @@ if (scsi_block_when_processing_errors(sdp)) { struct scsi_sense_hdr sshdr = { 0, }; - retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, + retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, sdkp->max_retries, &sshdr); /* failed to execute TUR, assume media not present */ @@ -1641,7 +1682,7 @@ * flush everything. */ res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, sshdr, - timeout, SD_MAX_RETRIES, 0, RQF_PM, NULL); + timeout, sdkp->max_retries, 0, RQF_PM, NULL); if (res == 0) break; } @@ -1694,20 +1735,30 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { - struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; + struct gendisk *disk = bdev->bd_disk; + struct scsi_disk *sdkp = scsi_disk(disk); + struct scsi_device *sdev = sdkp->device; + void __user *p = compat_ptr(arg); int error; + error = scsi_verify_blk_ioctl(bdev, cmd); + if (error < 0) + return error; + error = scsi_ioctl_block_when_processing_errors(sdev, cmd, (mode & FMODE_NDELAY) != 0); if (error) return error; + + if (is_sed_ioctl(cmd)) + return sed_ioctl(sdkp->opal_dev, cmd, p); /* * Let the static ioctl translation table take care of it. */ if (!sdev->host->hostt->compat_ioctl) return -ENOIOCTLCMD; - return sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg); + return sdev->host->hostt->compat_ioctl(sdev, cmd, p); } #endif @@ -1734,7 +1785,8 @@ static int sd_pr_command(struct block_device *bdev, u8 sa, u64 key, u64 sa_key, u8 type, u8 flags) { - struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device; + struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); + struct scsi_device *sdev = sdkp->device; struct scsi_sense_hdr sshdr; int result; u8 cmd[16] = { 0, }; @@ -1750,7 +1802,7 @@ data[20] = flags; result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, &data, sizeof(data), - &sshdr, SD_TIMEOUT, SD_MAX_RETRIES, NULL); + &sshdr, SD_TIMEOUT, sdkp->max_retries, NULL); if (driver_byte(result) == DRIVER_SENSE && scsi_sense_valid(&sshdr)) { @@ -2084,7 +2136,7 @@ the_result = scsi_execute_req(sdkp->device, cmd, DMA_NONE, NULL, 0, &sshdr, SD_TIMEOUT, - SD_MAX_RETRIES, NULL); + sdkp->max_retries, NULL); /* * If the drive has indicated to us that it @@ -2140,7 +2192,7 @@ cmd[4] |= 1 << 4; scsi_execute_req(sdkp->device, cmd, DMA_NONE, NULL, 0, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES, + SD_TIMEOUT, sdkp->max_retries, NULL); spintime_expire = jiffies + 100 * HZ; spintime = 1; @@ -2192,8 +2244,10 @@ u8 type; int ret = 0; - if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) + if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) { + sdkp->protection_type = 0; return ret; + } type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ @@ -2280,7 +2334,7 @@ the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buffer, RC16_LEN, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES, NULL); + SD_TIMEOUT, sdkp->max_retries, NULL); if (media_not_present(sdkp, &sshdr)) return -ENODEV; @@ -2365,7 +2419,7 @@ the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buffer, 8, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES, NULL); + SD_TIMEOUT, sdkp->max_retries, NULL); if (media_not_present(sdkp, &sshdr)) return -ENODEV; @@ -2552,12 +2606,12 @@ /* called with buffer of length 512 */ static inline int -sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, +sd_do_mode_sense(struct scsi_disk *sdkp, int dbd, int modepage, unsigned char *buffer, int len, struct scsi_mode_data *data, struct scsi_sense_hdr *sshdr) { - return scsi_mode_sense(sdp, dbd, modepage, buffer, len, - SD_TIMEOUT, SD_MAX_RETRIES, data, + return scsi_mode_sense(sdkp->device, dbd, modepage, buffer, len, + SD_TIMEOUT, sdkp->max_retries, data, sshdr); } @@ -2580,14 +2634,14 @@ } if (sdp->use_192_bytes_for_3f) { - res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 192, &data, NULL); + res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 192, &data, NULL); } else { /* * First attempt: ask for all pages (0x3F), but only 4 bytes. * We have to start carefully: some devices hang if we ask * for more than is available. */ - res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 4, &data, NULL); + res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 4, &data, NULL); /* * Second attempt: ask for page 0 When only page 0 is @@ -2596,13 +2650,13 @@ * CDB. */ if (!scsi_status_is_good(res)) - res = sd_do_mode_sense(sdp, 0, 0, buffer, 4, &data, NULL); + res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL); /* * Third attempt: ask 255 bytes, as we did earlier. */ if (!scsi_status_is_good(res)) - res = sd_do_mode_sense(sdp, 0, 0x3F, buffer, 255, + res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255, &data, NULL); } @@ -2664,7 +2718,7 @@ } /* cautiously ask */ - res = sd_do_mode_sense(sdp, dbd, modepage, buffer, first_len, + res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len, &data, &sshdr); if (!scsi_status_is_good(res)) @@ -2696,7 +2750,7 @@ /* Get the data */ if (len > first_len) - res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, + res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len, &data, &sshdr); if (scsi_status_is_good(res)) { @@ -2815,7 +2869,7 @@ return; res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, - SD_MAX_RETRIES, &data, &sshdr); + sdkp->max_retries, &data, &sshdr); if (!scsi_status_is_good(res) || !data.header_length || data.length < 6) { @@ -3159,9 +3213,11 @@ if (sd_validate_opt_xfer_size(sdkp, dev_max)) { q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks); rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks); - } else + } else { + q->limits.io_opt = 0; rw_max = min_not_zero(logical_to_sectors(sdp, dev_max), (sector_t)BLK_DEF_MAX_SECTORS); + } /* Do not exceed controller limit */ rw_max = min(rw_max, queue_max_hw_sectors(q)); @@ -3317,6 +3373,7 @@ sdkp->driver = &sd_template; sdkp->disk = gd; sdkp->index = index; + sdkp->max_retries = SD_MAX_RETRIES; atomic_set(&sdkp->openers, 0); atomic_set(&sdkp->device->ioerr_cnt, 0); @@ -3329,15 +3386,16 @@ } device_initialize(&sdkp->dev); - sdkp->dev.parent = dev; + sdkp->dev.parent = get_device(dev); sdkp->dev.class = &sd_disk_class; dev_set_name(&sdkp->dev, "%s", dev_name(dev)); error = device_add(&sdkp->dev); - if (error) - goto out_free_index; + if (error) { + put_device(&sdkp->dev); + goto out; + } - get_device(dev); dev_set_drvdata(dev, sdkp); gd->major = sd_major((index & 0xf0) >> 4); @@ -3376,7 +3434,7 @@ sd_revalidate_disk(gd); if (sdkp->security) { - sdkp->opal_dev = init_opal_dev(sdp, &sd_sec_submit); + sdkp->opal_dev = init_opal_dev(sdkp, &sd_sec_submit); if (sdkp->opal_dev) sd_printk(KERN_NOTICE, sdkp, "supports TCG Opal\n"); } @@ -3488,7 +3546,7 @@ return -ENODEV; res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES, 0, RQF_PM, NULL); + SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL); if (res) { sd_print_result(sdkp, "Start/Stop Unit failed", res); if (driver_byte(res) == DRIVER_SENSE) --- linux-oracle-5.4.0.orig/drivers/scsi/sd.h +++ linux-oracle-5.4.0/drivers/scsi/sd.h @@ -82,6 +82,7 @@ #endif atomic_t openers; sector_t capacity; /* size in logical blocks */ + int max_retries; u32 max_xfer_blocks; u32 opt_xfer_blocks; u32 max_ws_blocks; --- linux-oracle-5.4.0.orig/drivers/scsi/ses.c +++ linux-oracle-5.4.0/drivers/scsi/ses.c @@ -87,9 +87,16 @@ 0 }; unsigned char recv_page_code; + unsigned int retries = SES_RETRIES; + struct scsi_sense_hdr sshdr; + + do { + ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, + &sshdr, SES_TIMEOUT, 1, NULL); + } while (ret > 0 && --retries && scsi_sense_valid(&sshdr) && + (sshdr.sense_key == NOT_READY || + (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29))); - ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, - NULL, SES_TIMEOUT, SES_RETRIES, NULL); if (unlikely(ret)) return ret; @@ -111,7 +118,7 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code, void *buf, int bufflen) { - u32 result; + int result; unsigned char cmd[] = { SEND_DIAGNOSTIC, @@ -121,9 +128,16 @@ bufflen & 0xff, 0 }; + struct scsi_sense_hdr sshdr; + unsigned int retries = SES_RETRIES; + + do { + result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen, + &sshdr, SES_TIMEOUT, 1, NULL); + } while (result > 0 && --retries && scsi_sense_valid(&sshdr) && + (sshdr.sense_key == NOT_READY || + (sshdr.sense_key == UNIT_ATTENTION && sshdr.asc == 0x29))); - result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen, - NULL, SES_TIMEOUT, SES_RETRIES, NULL); if (result) sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n", result); @@ -419,8 +433,8 @@ } #endif /* 0 */ -static void ses_process_descriptor(struct enclosure_component *ecomp, - unsigned char *desc) +static int ses_process_descriptor(struct enclosure_component *ecomp, + unsigned char *desc, int max_desc_len) { int eip = desc[0] & 0x10; int invalid = desc[0] & 0x80; @@ -431,22 +445,32 @@ unsigned char *d; if (invalid) - return; + return 0; switch (proto) { case SCSI_PROTOCOL_FCP: if (eip) { + if (max_desc_len <= 7) + return 1; d = desc + 4; slot = d[3]; } break; case SCSI_PROTOCOL_SAS: + if (eip) { + if (max_desc_len <= 27) + return 1; d = desc + 4; slot = d[3]; d = desc + 8; - } else + } else { + if (max_desc_len <= 23) + return 1; d = desc + 4; + } + + /* only take the phy0 addr */ addr = (u64)d[12] << 56 | (u64)d[13] << 48 | @@ -463,6 +487,8 @@ } ecomp->slot = slot; scomp->addr = addr; + + return 0; } struct efd { @@ -477,9 +503,6 @@ int i; struct ses_component *scomp; - if (!edev->component[0].scratch) - return 0; - for (i = 0; i < edev->components; i++) { scomp = edev->component[i].scratch; if (scomp->addr != efd->addr) @@ -535,7 +558,7 @@ /* skip past overall descriptor */ desc_ptr += len + 4; } - if (ses_dev->page10) + if (ses_dev->page10 && ses_dev->page10_len > 9) addl_desc_ptr = ses_dev->page10 + 8; type_ptr = ses_dev->page1_types; components = 0; @@ -543,17 +566,22 @@ for (j = 0; j < type_ptr[1]; j++) { char *name = NULL; struct enclosure_component *ecomp; + int max_desc_len; if (desc_ptr) { - if (desc_ptr >= buf + page7_len) { + if (desc_ptr + 3 >= buf + page7_len) { desc_ptr = NULL; } else { len = (desc_ptr[2] << 8) + desc_ptr[3]; desc_ptr += 4; - /* Add trailing zero - pushes into - * reserved space */ - desc_ptr[len] = '\0'; - name = desc_ptr; + if (desc_ptr + len > buf + page7_len) + desc_ptr = NULL; + else { + /* Add trailing zero - pushes into + * reserved space */ + desc_ptr[len] = '\0'; + name = desc_ptr; + } } } if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE || @@ -565,14 +593,20 @@ components++, type_ptr[0], name); - else + else if (components < edev->components) ecomp = &edev->component[components++]; + else + ecomp = ERR_PTR(-EINVAL); if (!IS_ERR(ecomp)) { - if (addl_desc_ptr) - ses_process_descriptor( - ecomp, - addl_desc_ptr); + if (addl_desc_ptr) { + max_desc_len = ses_dev->page10_len - + (addl_desc_ptr - ses_dev->page10); + if (ses_process_descriptor(ecomp, + addl_desc_ptr, + max_desc_len)) + addl_desc_ptr = NULL; + } if (create) enclosure_component_register( ecomp); @@ -589,9 +623,11 @@ /* these elements are optional */ type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT || type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT || - type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) + type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) { addl_desc_ptr += addl_desc_ptr[1] + 2; - + if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len) + addl_desc_ptr = NULL; + } } } kfree(buf); @@ -690,6 +726,7 @@ type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) components += type_ptr[1]; } + ses_dev->page1 = buf; ses_dev->page1_len = len; buf = NULL; @@ -731,9 +768,11 @@ buf = NULL; } page2_not_supported: - scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); - if (!scomp) - goto err_free; + if (components > 0) { + scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); + if (!scomp) + goto err_free; + } edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev), components, &ses_enclosure_callbacks); @@ -813,7 +852,8 @@ kfree(ses_dev->page2); kfree(ses_dev); - kfree(edev->component[0].scratch); + if (edev->components) + kfree(edev->component[0].scratch); put_device(&edev->edev); enclosure_unregister(edev); --- linux-oracle-5.4.0.orig/drivers/scsi/sg.c +++ linux-oracle-5.4.0/drivers/scsi/sg.c @@ -190,7 +190,7 @@ static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp); static Sg_fd *sg_add_sfp(Sg_device * sdp); static void sg_remove_sfp(struct kref *); -static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id); +static Sg_request *sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy); static Sg_request *sg_add_request(Sg_fd * sfp); static int sg_remove_request(Sg_fd * sfp, Sg_request * srp); static Sg_device *sg_get_dev(int dev); @@ -390,7 +390,6 @@ mutex_lock(&sdp->open_rel_lock); scsi_autopm_put_device(sdp->device); - kref_put(&sfp->f_ref, sg_remove_sfp); sdp->open_cnt--; /* possibly many open()s waiting on exlude clearing, start many; @@ -402,6 +401,7 @@ wake_up_interruptible(&sdp->open_wait); } mutex_unlock(&sdp->open_rel_lock); + kref_put(&sfp->f_ref, sg_remove_sfp); return 0; } @@ -412,6 +412,7 @@ Sg_fd *sfp; Sg_request *srp; int req_pack_id = -1; + bool busy; sg_io_hdr_t *hp; struct sg_header *old_hdr = NULL; int retval = 0; @@ -459,25 +460,19 @@ } else req_pack_id = old_hdr->pack_id; } - srp = sg_get_rq_mark(sfp, req_pack_id); + srp = sg_get_rq_mark(sfp, req_pack_id, &busy); if (!srp) { /* now wait on packet to arrive */ - if (atomic_read(&sdp->detaching)) { - retval = -ENODEV; - goto free_old_hdr; - } if (filp->f_flags & O_NONBLOCK) { retval = -EAGAIN; goto free_old_hdr; } retval = wait_event_interruptible(sfp->read_wait, - (atomic_read(&sdp->detaching) || - (srp = sg_get_rq_mark(sfp, req_pack_id)))); - if (atomic_read(&sdp->detaching)) { - retval = -ENODEV; - goto free_old_hdr; - } - if (retval) { - /* -ERESTARTSYS as signal hit process */ + ((srp = sg_get_rq_mark(sfp, req_pack_id, &busy)) || + (!busy && atomic_read(&sdp->detaching)))); + if (!srp) { + /* signal or detaching */ + if (!retval) + retval = -ENODEV; goto free_old_hdr; } } @@ -689,8 +684,10 @@ hp->flags = input_size; /* structure abuse ... */ hp->pack_id = old_hdr.pack_id; hp->usr_ptr = NULL; - if (__copy_from_user(cmnd, buf, cmd_size)) + if (__copy_from_user(cmnd, buf, cmd_size)) { + sg_remove_request(sfp, srp); return -EFAULT; + } /* * SG_DXFER_TO_FROM_DEV is functionally equivalent to SG_DXFER_FROM_DEV, * but is is possible that the app intended SG_DXFER_TO_DEV, because there @@ -803,8 +800,10 @@ "sg_common_write: scsi opcode=0x%02x, cmd_size=%d\n", (int) cmnd[0], (int) hp->cmd_len)); - if (hp->dxfer_len >= SZ_256M) + if (hp->dxfer_len >= SZ_256M) { + sg_remove_request(sfp, srp); return -EINVAL; + } k = sg_start_req(srp, cmnd); if (k) { @@ -924,9 +923,7 @@ if (result < 0) return result; result = wait_event_interruptible(sfp->read_wait, - (srp_done(sfp, srp) || atomic_read(&sdp->detaching))); - if (atomic_read(&sdp->detaching)) - return -ENODEV; + srp_done(sfp, srp)); write_lock_irq(&sfp->rq_list_lock); if (srp->done) { srp->done = 2; @@ -2070,19 +2067,28 @@ } static Sg_request * -sg_get_rq_mark(Sg_fd * sfp, int pack_id) +sg_get_rq_mark(Sg_fd * sfp, int pack_id, bool *busy) { Sg_request *resp; unsigned long iflags; + *busy = false; write_lock_irqsave(&sfp->rq_list_lock, iflags); list_for_each_entry(resp, &sfp->rq_list, entry) { - /* look for requests that are ready + not SG_IO owned */ - if ((1 == resp->done) && (!resp->sg_io_owned) && + /* look for requests that are not SG_IO owned */ + if ((!resp->sg_io_owned) && ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { - resp->done = 2; /* guard against other readers */ - write_unlock_irqrestore(&sfp->rq_list_lock, iflags); - return resp; + switch (resp->done) { + case 0: /* request active */ + *busy = true; + break; + case 1: /* request done; response ready to return */ + resp->done = 2; /* guard against other readers */ + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return resp; + case 2: /* response already being returned */ + break; + } } } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); @@ -2136,6 +2142,15 @@ res = 1; } write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + /* + * If the device is detaching, wakeup any readers in case we just + * removed the last response, which would leave nothing for them to + * return other than -ENODEV. + */ + if (unlikely(atomic_read(&sfp->parentdp->detaching))) + wake_up_interruptible_all(&sfp->read_wait); + return res; } --- linux-oracle-5.4.0.orig/drivers/scsi/smartpqi/smartpqi.h +++ linux-oracle-5.4.0/drivers/scsi/smartpqi/smartpqi.h @@ -276,7 +276,9 @@ u8 reserved4 : 2; u8 additional_cdb_bytes_usage : 3; u8 reserved5 : 3; - u8 cdb[32]; + u8 cdb[16]; + u8 reserved6[12]; + __le32 timeout; struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; @@ -357,7 +359,7 @@ struct pqi_iu_header header; u8 event_type; u8 reserved2 : 7; - u8 request_acknowlege : 1; + u8 request_acknowledge : 1; __le16 event_id; __le32 additional_event_id; union { @@ -385,7 +387,8 @@ struct pqi_iu_header header; __le16 request_id; __le16 nexus_id; - u8 reserved[4]; + u8 reserved[2]; + __le16 timeout; u8 lun_number[8]; __le16 protocol_specific; __le16 outbound_queue_id_to_manage; @@ -445,7 +448,7 @@ struct pqi_ofa_memory { __le64 signature; /* "OFA_QRM" */ - __le16 version; /* version of this struct(1 = 1st version) */ + __le16 version; /* version of this struct (1 = 1st version) */ u8 reserved[62]; __le32 bytes_allocated; /* total allocated memory in bytes */ __le16 num_memory_descriptors; @@ -761,6 +764,8 @@ #define PQI_FIRMWARE_FEATURE_OFA 0 #define PQI_FIRMWARE_FEATURE_SMP 1 #define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 +#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 +#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -826,10 +831,17 @@ struct report_lun_header { __be32 list_length; - u8 extended_response; + u8 flags; u8 reserved[3]; }; +/* for flags field of struct report_lun_header */ +#define CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID (1 << 0) +#define CISS_REPORT_LOG_FLAG_QUEUE_DEPTH (1 << 5) +#define CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX (1 << 6) + +#define CISS_REPORT_PHYS_FLAG_OTHER (1 << 1) + struct report_log_lun_extended_entry { u8 lunid[8]; u8 volume_id[16]; @@ -851,7 +863,7 @@ }; /* for device_flags field of struct report_phys_lun_extended_entry */ -#define REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED 0x8 +#define CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED 0x8 struct report_phys_lun_extended { struct report_lun_header header; @@ -864,7 +876,7 @@ u8 reserved[2]; }; -/* constants for flags field of RAID map */ +/* for flags field of RAID map */ #define RAID_MAP_ENCRYPTION_ENABLED 0x1 struct raid_map { @@ -907,7 +919,6 @@ u8 scsi3addr[8]; __be64 wwid; u8 volume_id[16]; - u8 unique_id[16]; u8 is_physical_device : 1; u8 is_external_raid_device : 1; u8 is_expander_smp_device : 1; @@ -954,13 +965,9 @@ }; /* VPD inquiry pages */ -#define SCSI_VPD_SUPPORTED_PAGES 0x0 /* standard page */ -#define SCSI_VPD_DEVICE_ID 0x83 /* standard page */ #define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */ #define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */ #define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */ -#define SCSI_VPD_HEADER_SZ 4 -#define SCSI_VPD_DEVICE_ID_IDX 8 /* Index of page id in page */ #define VPD_PAGE (1 << 8) @@ -1130,13 +1137,16 @@ struct mutex ofa_mutex; /* serialize ofa */ bool controller_online; bool block_requests; - bool in_shutdown; + bool block_device_reset; bool in_ofa; + bool in_shutdown; u8 inbound_spanning_supported : 1; u8 outbound_spanning_supported : 1; u8 pqi_mode_enabled : 1; u8 pqi_reset_quiesce_supported : 1; u8 soft_reset_handshake_supported : 1; + u8 raid_iu_timeout_supported: 1; + u8 tmf_iu_timeout_supported: 1; struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; @@ -1170,9 +1180,10 @@ spinlock_t raid_bypass_retry_list_lock; struct work_struct raid_bypass_retry_work; - struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; - dma_addr_t pqi_ofa_mem_dma_handle; - void **pqi_ofa_chunk_virt_addr; + struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; + dma_addr_t pqi_ofa_mem_dma_handle; + void **pqi_ofa_chunk_virt_addr; + atomic_t sync_cmds_outstanding; }; enum pqi_ctrl_mode { @@ -1191,10 +1202,6 @@ #define CISS_REPORT_PHYS 0xc3 /* Report Physical LUNs */ #define CISS_GET_RAID_MAP 0xc8 -/* constants for CISS_REPORT_LOG/CISS_REPORT_PHYS commands */ -#define CISS_REPORT_LOG_EXTENDED 0x1 -#define CISS_REPORT_PHYS_EXTENDED 0x2 - /* BMIC commands */ #define BMIC_IDENTIFY_CONTROLLER 0x11 #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 @@ -1208,7 +1215,7 @@ #define BMIC_SET_DIAG_OPTIONS 0xf4 #define BMIC_SENSE_DIAG_OPTIONS 0xf5 -#define CSMI_CC_SAS_SMP_PASSTHRU 0X17 +#define CSMI_CC_SAS_SMP_PASSTHRU 0x17 #define SA_FLUSH_CACHE 0x1 @@ -1244,10 +1251,12 @@ u8 ctrl_serial_number[16]; }; -#define SA_EXPANDER_SMP_DEVICE 0x05 -#define SA_CONTROLLER_DEVICE 0x07 -/*SCSI Invalid Device Type for SAS devices*/ -#define PQI_SAS_SCSI_INVALID_DEVTYPE 0xff +/* constants for device_type field */ +#define SA_DEVICE_TYPE_SATA 0x1 +#define SA_DEVICE_TYPE_SAS 0x2 +#define SA_DEVICE_TYPE_EXPANDER_SMP 0x5 +#define SA_DEVICE_TYPE_CONTROLLER 0x7 +#define SA_DEVICE_TYPE_NVME 0x9 struct bmic_identify_physical_device { u8 scsi_bus; /* SCSI Bus number on controller */ @@ -1273,7 +1282,7 @@ __le32 rpm; /* drive rotational speed in RPM */ u8 device_type; /* type of drive */ u8 sata_version; /* only valid when device_type = */ - /* BMIC_DEVICE_TYPE_SATA */ + /* SA_DEVICE_TYPE_SATA */ __le64 big_total_block_count; __le64 ris_starting_lba; __le32 ris_size; @@ -1396,18 +1405,6 @@ #pragma pack() -static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost) -{ - void *hostdata = shost_priv(shost); - - return *((struct pqi_ctrl_info **)hostdata); -} - -static inline bool pqi_ctrl_offline(struct pqi_ctrl_info *ctrl_info) -{ - return !ctrl_info->controller_online; -} - static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info) { atomic_inc(&ctrl_info->num_busy_threads); @@ -1418,9 +1415,11 @@ atomic_dec(&ctrl_info->num_busy_threads); } -static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) +static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost) { - return ctrl_info->block_requests; + void *hostdata = shost_priv(shost); + + return *((struct pqi_ctrl_info **)hostdata); } void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, --- linux-oracle-5.4.0.orig/drivers/scsi/smartpqi/smartpqi_init.c +++ linux-oracle-5.4.0/drivers/scsi/smartpqi/smartpqi_init.c @@ -33,11 +33,11 @@ #define BUILD_TIMESTAMP #endif -#define DRIVER_VERSION "1.2.8-026" +#define DRIVER_VERSION "1.2.10-025" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 2 -#define DRIVER_RELEASE 8 -#define DRIVER_REVISION 26 +#define DRIVER_RELEASE 10 +#define DRIVER_REVISION 25 #define DRIVER_NAME "Microsemi PQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")" @@ -211,6 +211,11 @@ return scsi3addr[2] != 0; } +static inline bool pqi_ctrl_offline(struct pqi_ctrl_info *ctrl_info) +{ + return !ctrl_info->controller_online; +} + static inline void pqi_check_ctrl_health(struct pqi_ctrl_info *ctrl_info) { if (ctrl_info->controller_online) @@ -235,6 +240,21 @@ sis_write_driver_scratch(ctrl_info, mode); } +static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->block_device_reset = true; +} + +static inline bool pqi_device_reset_blocked(struct pqi_ctrl_info *ctrl_info) +{ + return ctrl_info->block_device_reset; +} + +static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) +{ + return ctrl_info->block_requests; +} + static inline void pqi_ctrl_block_requests(struct pqi_ctrl_info *ctrl_info) { ctrl_info->block_requests = true; @@ -331,6 +351,16 @@ return device->in_remove && !ctrl_info->in_shutdown; } +static inline void pqi_ctrl_shutdown_start(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->in_shutdown = true; +} + +static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) +{ + return ctrl_info->in_shutdown; +} + static inline void pqi_schedule_rescan_worker_with_delay( struct pqi_ctrl_info *ctrl_info, unsigned long delay) { @@ -360,6 +390,11 @@ cancel_delayed_work_sync(&ctrl_info->rescan_work); } +static inline void pqi_cancel_event_worker(struct pqi_ctrl_info *ctrl_info) +{ + cancel_work_sync(&ctrl_info->event_work); +} + static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info) { if (!ctrl_info->heartbeat_counter) @@ -377,7 +412,7 @@ } static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info, - u8 clear) + u8 clear) { u8 status; @@ -462,9 +497,9 @@ request->data_direction = SOP_READ_FLAG; cdb[0] = cmd; if (cmd == CISS_REPORT_PHYS) - cdb[1] = CISS_REPORT_PHYS_EXTENDED; + cdb[1] = CISS_REPORT_PHYS_FLAG_OTHER; else - cdb[1] = CISS_REPORT_LOG_EXTENDED; + cdb[1] = CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID; put_unaligned_be32(cdb_length, &cdb[6]); break; case CISS_GET_RAID_MAP: @@ -507,8 +542,7 @@ put_unaligned_be16(cdb_length, &cdb[7]); break; default: - dev_err(&ctrl_info->pci_dev->dev, "unknown command 0x%c\n", - cmd); + dev_err(&ctrl_info->pci_dev->dev, "unknown command 0x%c\n", cmd); break; } @@ -567,13 +601,12 @@ } static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, - u8 *scsi3addr, void *buffer, size_t buffer_length, u16 vpd_page, - struct pqi_raid_error_info *error_info, - unsigned long timeout_msecs) + u8 *scsi3addr, void *buffer, size_t buffer_length, u16 vpd_page, + struct pqi_raid_error_info *error_info, unsigned long timeout_msecs) { int rc; - enum dma_data_direction dir; struct pqi_raid_path_request request; + enum dma_data_direction dir; rc = pqi_build_raid_path_request(ctrl_info, &request, cmd, scsi3addr, buffer, @@ -581,44 +614,44 @@ if (rc) return rc; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, error_info, timeout_msecs); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, + error_info, timeout_msecs); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); + return rc; } -/* Helper functions for pqi_send_scsi_raid_request */ +/* helper functions for pqi_send_scsi_raid_request */ static inline int pqi_send_ctrl_raid_request(struct pqi_ctrl_info *ctrl_info, - u8 cmd, void *buffer, size_t buffer_length) + u8 cmd, void *buffer, size_t buffer_length) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, NULL, NO_TIMEOUT); + buffer, buffer_length, 0, NULL, NO_TIMEOUT); } static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info, - u8 cmd, void *buffer, size_t buffer_length, - struct pqi_raid_error_info *error_info) + u8 cmd, void *buffer, size_t buffer_length, + struct pqi_raid_error_info *error_info) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, error_info, NO_TIMEOUT); + buffer, buffer_length, 0, error_info, NO_TIMEOUT); } - static inline int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info, - struct bmic_identify_controller *buffer) + struct bmic_identify_controller *buffer) { return pqi_send_ctrl_raid_request(ctrl_info, BMIC_IDENTIFY_CONTROLLER, - buffer, sizeof(*buffer)); + buffer, sizeof(*buffer)); } static inline int pqi_sense_subsystem_info(struct pqi_ctrl_info *ctrl_info, - struct bmic_sense_subsystem_info *sense_info) + struct bmic_sense_subsystem_info *sense_info) { return pqi_send_ctrl_raid_request(ctrl_info, - BMIC_SENSE_SUBSYSTEM_INFORMATION, - sense_info, sizeof(*sense_info)); + BMIC_SENSE_SUBSYSTEM_INFORMATION, sense_info, + sizeof(*sense_info)); } static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info, @@ -628,83 +661,9 @@ buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT); } -static bool pqi_vpd_page_supported(struct pqi_ctrl_info *ctrl_info, - u8 *scsi3addr, u16 vpd_page) -{ - int rc; - int i; - int pages; - unsigned char *buf, bufsize; - - buf = kzalloc(256, GFP_KERNEL); - if (!buf) - return false; - - /* Get the size of the page list first */ - rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, - VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES, - buf, SCSI_VPD_HEADER_SZ); - if (rc != 0) - goto exit_unsupported; - - pages = buf[3]; - if ((pages + SCSI_VPD_HEADER_SZ) <= 255) - bufsize = pages + SCSI_VPD_HEADER_SZ; - else - bufsize = 255; - - /* Get the whole VPD page list */ - rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, - VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES, - buf, bufsize); - if (rc != 0) - goto exit_unsupported; - - pages = buf[3]; - for (i = 1; i <= pages; i++) - if (buf[3 + i] == vpd_page) - goto exit_supported; - -exit_unsupported: - kfree(buf); - return false; - -exit_supported: - kfree(buf); - return true; -} - -static int pqi_get_device_id(struct pqi_ctrl_info *ctrl_info, - u8 *scsi3addr, u8 *device_id, int buflen) -{ - int rc; - unsigned char *buf; - - if (!pqi_vpd_page_supported(ctrl_info, scsi3addr, SCSI_VPD_DEVICE_ID)) - return 1; /* function not supported */ - - buf = kzalloc(64, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - rc = pqi_scsi_inquiry(ctrl_info, scsi3addr, - VPD_PAGE | SCSI_VPD_DEVICE_ID, - buf, 64); - if (rc == 0) { - if (buflen > 16) - buflen = 16; - memcpy(device_id, &buf[SCSI_VPD_DEVICE_ID_IDX], buflen); - } - - kfree(buf); - - return rc; -} - static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, - struct bmic_identify_physical_device *buffer, - size_t buffer_length) + struct bmic_identify_physical_device *buffer, size_t buffer_length) { int rc; enum dma_data_direction dir; @@ -725,6 +684,7 @@ 0, NULL, NO_TIMEOUT); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); + return rc; } @@ -763,7 +723,7 @@ buffer, buffer_length, error_info); } -#define PQI_FETCH_PTRAID_DATA (1UL<<31) +#define PQI_FETCH_PTRAID_DATA (1 << 31) static int pqi_set_diag_rescan(struct pqi_ctrl_info *ctrl_info) { @@ -775,14 +735,15 @@ return -ENOMEM; rc = pqi_send_ctrl_raid_request(ctrl_info, BMIC_SENSE_DIAG_OPTIONS, - diag, sizeof(*diag)); + diag, sizeof(*diag)); if (rc) goto out; diag->options |= cpu_to_le32(PQI_FETCH_PTRAID_DATA); - rc = pqi_send_ctrl_raid_request(ctrl_info, BMIC_SET_DIAG_OPTIONS, - diag, sizeof(*diag)); + rc = pqi_send_ctrl_raid_request(ctrl_info, BMIC_SET_DIAG_OPTIONS, diag, + sizeof(*diag)); + out: kfree(diag); @@ -793,7 +754,7 @@ void *buffer, size_t buffer_length) { return pqi_send_ctrl_raid_request(ctrl_info, BMIC_WRITE_HOST_WELLNESS, - buffer, buffer_length); + buffer, buffer_length); } #pragma pack(1) @@ -946,7 +907,7 @@ void *buffer, size_t buffer_length) { return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer, - buffer_length); + buffer_length); } static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, @@ -1246,6 +1207,7 @@ "Requested %d bytes, received %d bytes", raid_map_size, get_unaligned_le32(&raid_map->structure_size)); + rc = -EINVAL; goto error; } } @@ -1280,9 +1242,9 @@ if (rc) goto out; -#define RAID_BYPASS_STATUS 4 -#define RAID_BYPASS_CONFIGURED 0x1 -#define RAID_BYPASS_ENABLED 0x2 +#define RAID_BYPASS_STATUS 4 +#define RAID_BYPASS_CONFIGURED 0x1 +#define RAID_BYPASS_ENABLED 0x2 bypass_status = buffer[RAID_BYPASS_STATUS]; device->raid_bypass_configured = @@ -1385,14 +1347,6 @@ } } - if (pqi_get_device_id(ctrl_info, device->scsi3addr, - device->unique_id, sizeof(device->unique_id)) < 0) - dev_warn(&ctrl_info->pci_dev->dev, - "Can't get device id for scsi %d:%d:%d:%d\n", - ctrl_info->scsi_host->host_no, - device->bus, device->target, - device->lun); - out: kfree(buffer); @@ -1413,6 +1367,7 @@ device->queue_depth = PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH; return; } + device->box_index = id_phys->box_index; device->phys_box_on_bus = id_phys->phys_box_on_bus; device->phy_connected_dev_type = id_phys->phy_connected_dev_type[0]; @@ -1828,7 +1783,7 @@ device = new_device_list[i]; find_result = pqi_scsi_find_entry(ctrl_info, device, - &matching_device); + &matching_device); switch (find_result) { case DEVICE_SAME: @@ -2057,9 +2012,8 @@ rc = -ENOMEM; goto out; } - if (pqi_hide_vsep) { - int i; + if (pqi_hide_vsep) { for (i = num_physicals - 1; i >= 0; i--) { phys_lun_ext_entry = &physdev_list->lun_entries[i]; @@ -2132,7 +2086,7 @@ device->is_physical_device = is_physical_device; if (is_physical_device) { if (phys_lun_ext_entry->device_type == - SA_EXPANDER_SMP_DEVICE) + SA_DEVICE_TYPE_EXPANDER_SMP) device->is_expander_smp_device = true; } else { device->is_external_raid_device = @@ -2169,16 +2123,13 @@ if (device->is_physical_device) { device->wwid = phys_lun_ext_entry->wwid; if ((phys_lun_ext_entry->device_flags & - REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED) && + CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && phys_lun_ext_entry->aio_handle) { device->aio_enabled = true; - device->aio_handle = - phys_lun_ext_entry->aio_handle; + device->aio_handle = + phys_lun_ext_entry->aio_handle; } - - pqi_get_physical_disk_info(ctrl_info, - device, id_phys); - + pqi_get_physical_disk_info(ctrl_info, device, id_phys); } else { memcpy(device->volume_id, log_lun_ext_entry->volume_id, sizeof(device->volume_id)); @@ -2511,7 +2462,6 @@ offload_to_mirror = (offload_to_mirror >= layout_map_count - 1) ? 0 : offload_to_mirror + 1; - WARN_ON(offload_to_mirror >= layout_map_count); device->offload_to_mirror = offload_to_mirror; /* * Avoid direct use of device->offload_to_mirror within this @@ -2964,10 +2914,14 @@ return rc; } -static unsigned int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, - struct pqi_queue_group *queue_group) +static inline void pqi_invalid_response(struct pqi_ctrl_info *ctrl_info) { - unsigned int num_responses; + pqi_take_ctrl_offline(ctrl_info); +} + +static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue_group *queue_group) +{ + int num_responses; pqi_index_t oq_pi; pqi_index_t oq_ci; struct pqi_io_request *io_request; @@ -2979,6 +2933,13 @@ while (1) { oq_pi = readl(queue_group->oq_pi); + if (oq_pi >= ctrl_info->num_elements_per_oq) { + pqi_invalid_response(ctrl_info); + dev_err(&ctrl_info->pci_dev->dev, + "I/O interrupt: producer index (%u) out of range (0-%u): consumer index: %u\n", + oq_pi, ctrl_info->num_elements_per_oq - 1, oq_ci); + return -1; + } if (oq_pi == oq_ci) break; @@ -2987,10 +2948,22 @@ (oq_ci * PQI_OPERATIONAL_OQ_ELEMENT_LENGTH); request_id = get_unaligned_le16(&response->request_id); - WARN_ON(request_id >= ctrl_info->max_io_slots); + if (request_id >= ctrl_info->max_io_slots) { + pqi_invalid_response(ctrl_info); + dev_err(&ctrl_info->pci_dev->dev, + "request ID in response (%u) out of range (0-%u): producer index: %u consumer index: %u\n", + request_id, ctrl_info->max_io_slots - 1, oq_pi, oq_ci); + return -1; + } io_request = &ctrl_info->io_request_pool[request_id]; - WARN_ON(atomic_read(&io_request->refcount) == 0); + if (atomic_read(&io_request->refcount) == 0) { + pqi_invalid_response(ctrl_info); + dev_err(&ctrl_info->pci_dev->dev, + "request ID in response (%u) does not match an outstanding I/O request: producer index: %u consumer index: %u\n", + request_id, oq_pi, oq_ci); + return -1; + } switch (response->header.iu_type) { case PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS: @@ -3020,24 +2993,22 @@ io_request->error_info = ctrl_info->error_buffer + (get_unaligned_le16(&response->error_index) * PQI_ERROR_BUFFER_ELEMENT_LENGTH); - pqi_process_io_error(response->header.iu_type, - io_request); + pqi_process_io_error(response->header.iu_type, io_request); break; default: + pqi_invalid_response(ctrl_info); dev_err(&ctrl_info->pci_dev->dev, - "unexpected IU type: 0x%x\n", - response->header.iu_type); - break; + "unexpected IU type: 0x%x: producer index: %u consumer index: %u\n", + response->header.iu_type, oq_pi, oq_ci); + return -1; } - io_request->io_complete_callback(io_request, - io_request->context); + io_request->io_complete_callback(io_request, io_request->context); /* * Note that the I/O request structure CANNOT BE TOUCHED after * returning from the I/O completion callback! */ - oq_ci = (oq_ci + 1) % ctrl_info->num_elements_per_oq; } @@ -3158,7 +3129,7 @@ } static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info, - enum pqi_soft_reset_status reset_status) + enum pqi_soft_reset_status reset_status) { int rc; @@ -3202,8 +3173,8 @@ if (event_id == PQI_EVENT_OFA_QUIESCE) { dev_info(&ctrl_info->pci_dev->dev, - "Received Online Firmware Activation quiesce event for controller %u\n", - ctrl_info->ctrl_id); + "Received Online Firmware Activation quiesce event for controller %u\n", + ctrl_info->ctrl_id); pqi_ofa_ctrl_quiesce(ctrl_info); pqi_acknowledge_event(ctrl_info, event); if (ctrl_info->soft_reset_handshake_supported) { @@ -3223,8 +3194,8 @@ pqi_ofa_free_host_buffer(ctrl_info); pqi_acknowledge_event(ctrl_info, event); dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation(%u) cancel reason : %u\n", - ctrl_info->ctrl_id, event->ofa_cancel_reason); + "Online Firmware Activation(%u) cancel reason : %u\n", + ctrl_info->ctrl_id, event->ofa_cancel_reason); } mutex_unlock(&ctrl_info->ofa_mutex); @@ -3350,9 +3321,9 @@ } } -static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) +static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) { - unsigned int num_events; + int num_events; pqi_index_t oq_pi; pqi_index_t oq_ci; struct pqi_event_queue *event_queue; @@ -3366,26 +3337,31 @@ while (1) { oq_pi = readl(event_queue->oq_pi); + if (oq_pi >= PQI_NUM_EVENT_QUEUE_ELEMENTS) { + pqi_invalid_response(ctrl_info); + dev_err(&ctrl_info->pci_dev->dev, + "event interrupt: producer index (%u) out of range (0-%u): consumer index: %u\n", + oq_pi, PQI_NUM_EVENT_QUEUE_ELEMENTS - 1, oq_ci); + return -1; + } + if (oq_pi == oq_ci) break; num_events++; - response = event_queue->oq_element_array + - (oq_ci * PQI_EVENT_OQ_ELEMENT_LENGTH); + response = event_queue->oq_element_array + (oq_ci * PQI_EVENT_OQ_ELEMENT_LENGTH); event_index = pqi_event_type_to_event_index(response->event_type); - if (event_index >= 0) { - if (response->request_acknowlege) { - event = &ctrl_info->events[event_index]; - event->pending = true; - event->event_type = response->event_type; - event->event_id = response->event_id; - event->additional_event_id = - response->additional_event_id; + if (event_index >= 0 && response->request_acknowledge) { + event = &ctrl_info->events[event_index]; + event->pending = true; + event->event_type = response->event_type; + event->event_id = response->event_id; + event->additional_event_id = response->additional_event_id; + if (event->event_type == PQI_EVENT_TYPE_OFA) pqi_ofa_capture_event_payload(event, response); - } } oq_ci = (oq_ci + 1) % PQI_NUM_EVENT_QUEUE_ELEMENTS; @@ -3403,7 +3379,7 @@ #define PQI_LEGACY_INTX_MASK 0x1 static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info, - bool enable_intx) + bool enable_intx) { u32 intx_mask; struct pqi_device_registers __iomem *pqi_registers; @@ -3500,7 +3476,8 @@ { struct pqi_ctrl_info *ctrl_info; struct pqi_queue_group *queue_group; - unsigned int num_responses_handled; + int num_io_responses_handled; + int num_events_handled; queue_group = data; ctrl_info = queue_group->ctrl_info; @@ -3508,17 +3485,25 @@ if (!pqi_is_valid_irq(ctrl_info)) return IRQ_NONE; - num_responses_handled = pqi_process_io_intr(ctrl_info, queue_group); + num_io_responses_handled = pqi_process_io_intr(ctrl_info, queue_group); + if (num_io_responses_handled < 0) + goto out; - if (irq == ctrl_info->event_irq) - num_responses_handled += pqi_process_event_intr(ctrl_info); + if (irq == ctrl_info->event_irq) { + num_events_handled = pqi_process_event_intr(ctrl_info); + if (num_events_handled < 0) + goto out; + } else { + num_events_handled = 0; + } - if (num_responses_handled) + if (num_io_responses_handled + num_events_handled > 0) atomic_inc(&ctrl_info->num_interrupts); pqi_start_io(ctrl_info, queue_group, RAID_PATH, NULL); pqi_start_io(ctrl_info, queue_group, AIO_PATH, NULL); +out: return IRQ_HANDLED; } @@ -3841,7 +3826,7 @@ &pqi_registers->admin_oq_pi_addr); reg = PQI_ADMIN_IQ_NUM_ELEMENTS | - (PQI_ADMIN_OQ_NUM_ELEMENTS) << 8 | + (PQI_ADMIN_OQ_NUM_ELEMENTS << 8) | (admin_queues->int_msg_num << 16); writel(reg, &pqi_registers->admin_iq_num_elements); writel(PQI_CREATE_ADMIN_QUEUE_PAIR, @@ -4048,8 +4033,8 @@ complete(waiting); } -static int pqi_process_raid_io_error_synchronous(struct pqi_raid_error_info - *error_info) +static int pqi_process_raid_io_error_synchronous( + struct pqi_raid_error_info *error_info) { int rc = -EIO; @@ -4122,6 +4107,8 @@ goto out; } + atomic_inc(&ctrl_info->sync_cmds_outstanding); + io_request = pqi_alloc_io_request(ctrl_info); put_unaligned_le16(io_request->index, @@ -4168,6 +4155,7 @@ pqi_free_io_request(io_request); + atomic_dec(&ctrl_info->sync_cmds_outstanding); out: up(&ctrl_info->sync_request_sem); @@ -4665,11 +4653,11 @@ static inline int pqi_alloc_error_buffer(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->error_buffer = dma_alloc_coherent(&ctrl_info->pci_dev->dev, - ctrl_info->error_buffer_length, - &ctrl_info->error_buffer_dma_handle, - GFP_KERNEL); + ctrl_info->error_buffer = dma_alloc_coherent(&ctrl_info->pci_dev->dev, + ctrl_info->error_buffer_length, + &ctrl_info->error_buffer_dma_handle, + GFP_KERNEL); if (!ctrl_info->error_buffer) return -ENOMEM; @@ -5042,10 +5030,10 @@ } switch (scmd->sc_data_direction) { - case DMA_TO_DEVICE: + case DMA_FROM_DEVICE: request->data_direction = SOP_READ_FLAG; break; - case DMA_FROM_DEVICE: + case DMA_TO_DEVICE: request->data_direction = SOP_WRITE_FLAG; break; case DMA_NONE: @@ -5402,7 +5390,7 @@ pqi_ctrl_busy(ctrl_info); if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) || - pqi_ctrl_in_ofa(ctrl_info)) { + pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) { rc = SCSI_MLQUEUE_HOST_BUSY; goto out; } @@ -5419,7 +5407,7 @@ if (pqi_is_logical_device(device)) { raid_bypassed = false; if (device->raid_bypass_enabled && - !blk_rq_is_passthrough(scmd->request)) { + !blk_rq_is_passthrough(scmd->request)) { rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) @@ -5538,6 +5526,8 @@ list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); } @@ -5574,6 +5564,8 @@ list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); } @@ -5650,6 +5642,18 @@ return 0; } +static int pqi_ctrl_wait_for_pending_sync_cmds(struct pqi_ctrl_info *ctrl_info) +{ + while (atomic_read(&ctrl_info->sync_cmds_outstanding)) { + pqi_check_ctrl_health(ctrl_info); + if (pqi_ctrl_offline(ctrl_info)) + return -ENXIO; + usleep_range(1000, 2000); + } + + return 0; +} + static void pqi_lun_reset_complete(struct pqi_io_request *io_request, void *context) { @@ -5658,7 +5662,8 @@ complete(waiting); } -#define PQI_LUN_RESET_TIMEOUT_SECS 10 +#define PQI_LUN_RESET_TIMEOUT_SECS 30 +#define PQI_LUN_RESET_POLL_COMPLETION_SECS 10 static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct completion *wait) @@ -5667,7 +5672,7 @@ while (1) { if (wait_for_completion_io_timeout(wait, - PQI_LUN_RESET_TIMEOUT_SECS * PQI_HZ)) { + PQI_LUN_RESET_POLL_COMPLETION_SECS * PQI_HZ)) { rc = 0; break; } @@ -5704,6 +5709,9 @@ memcpy(request->lun_number, device->scsi3addr, sizeof(request->lun_number)); request->task_management_function = SOP_TASK_MANAGEMENT_LUN_RESET; + if (ctrl_info->tmf_iu_timeout_supported) + put_unaligned_le16(PQI_LUN_RESET_TIMEOUT_SECS, + &request->timeout); pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, @@ -5733,7 +5741,7 @@ for (retries = 0;;) { rc = pqi_lun_reset(ctrl_info, device); - if (rc != -EAGAIN || ++retries > PQI_LUN_RESET_RETRIES) + if (rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) break; msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); } @@ -5787,17 +5795,17 @@ shost->host_no, device->bus, device->target, device->lun); pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) { - dev_err(&ctrl_info->pci_dev->dev, - "controller %u offlined - cannot send device reset\n", - ctrl_info->ctrl_id); + if (pqi_ctrl_offline(ctrl_info) || + pqi_device_reset_blocked(ctrl_info)) { rc = FAILED; goto out; } pqi_wait_until_ofa_finished(ctrl_info); + atomic_inc(&ctrl_info->sync_cmds_outstanding); rc = pqi_device_reset(ctrl_info, device); + atomic_dec(&ctrl_info->sync_cmds_outstanding); out: dev_err(&ctrl_info->pci_dev->dev, @@ -6066,6 +6074,9 @@ put_unaligned_le16(iu_length, &request.header.iu_length); + if (ctrl_info->raid_iu_timeout_supported) + put_unaligned_le32(iocommand.Request.Timeout, &request.timeout); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info, NO_TIMEOUT); @@ -6119,7 +6130,7 @@ ctrl_info = shost_to_hba(sdev->host); - if (pqi_ctrl_in_ofa(ctrl_info)) + if (pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) return -EBUSY; switch (cmd) { @@ -6160,14 +6171,8 @@ static ssize_t pqi_driver_version_show(struct device *dev, struct device_attribute *attr, char *buffer) { - struct Scsi_Host *shost; - struct pqi_ctrl_info *ctrl_info; - - shost = class_to_shost(dev); - ctrl_info = shost_to_hba(shost); - - return snprintf(buffer, PAGE_SIZE, - "%s\n", DRIVER_VERSION BUILD_TIMESTAMP); + return snprintf(buffer, PAGE_SIZE, "%s\n", + DRIVER_VERSION BUILD_TIMESTAMP); } static ssize_t pqi_serial_number_show(struct device *dev, @@ -6283,7 +6288,7 @@ struct scsi_device *sdev; struct pqi_scsi_dev *device; unsigned long flags; - unsigned char uid[16]; + u8 unique_id[16]; sdev = to_scsi_device(dev); ctrl_info = shost_to_hba(sdev->host); @@ -6296,16 +6301,22 @@ flags); return -ENODEV; } - memcpy(uid, device->unique_id, sizeof(uid)); + + if (device->is_physical_device) { + memset(unique_id, 0, 8); + memcpy(unique_id + 8, &device->wwid, sizeof(device->wwid)); + } else { + memcpy(unique_id, device->volume_id, sizeof(device->volume_id)); + } spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); return snprintf(buffer, PAGE_SIZE, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", - uid[0], uid[1], uid[2], uid[3], - uid[4], uid[5], uid[6], uid[7], - uid[8], uid[9], uid[10], uid[11], - uid[12], uid[13], uid[14], uid[15]); + unique_id[0], unique_id[1], unique_id[2], unique_id[3], + unique_id[4], unique_id[5], unique_id[6], unique_id[7], + unique_id[8], unique_id[9], unique_id[10], unique_id[11], + unique_id[12], unique_id[13], unique_id[14], unique_id[15]); } static ssize_t pqi_lunid_show(struct device *dev, @@ -6328,6 +6339,7 @@ flags); return -ENODEV; } + memcpy(lunid, device->scsi3addr, sizeof(lunid)); spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); @@ -6335,7 +6347,8 @@ return snprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid); } -#define MAX_PATHS 8 +#define MAX_PATHS 8 + static ssize_t pqi_path_info_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -6347,9 +6360,9 @@ int output_len = 0; u8 box; u8 bay; - u8 path_map_index = 0; + u8 path_map_index; char *active; - unsigned char phys_connector[2]; + u8 phys_connector[2]; sdev = to_scsi_device(dev); ctrl_info = shost_to_hba(sdev->host); @@ -6365,7 +6378,7 @@ bay = device->bay; for (i = 0; i < MAX_PATHS; i++) { - path_map_index = 1<active_path_index) active = "Active"; else if (device->path_map & path_map_index) @@ -6416,10 +6429,10 @@ } spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); + return output_len; } - static ssize_t pqi_sas_address_show(struct device *dev, struct device_attribute *attr, char *buffer) { @@ -6440,6 +6453,7 @@ flags); return -ENODEV; } + sas_address = device->sas_address; spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); @@ -6844,6 +6858,27 @@ firmware_feature->feature_name); } +static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, + struct pqi_firmware_feature *firmware_feature) +{ + switch (firmware_feature->feature_bit) { + case PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE: + ctrl_info->soft_reset_handshake_supported = + firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT: + ctrl_info->raid_iu_timeout_supported = + firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT: + ctrl_info->tmf_iu_timeout_supported = + firmware_feature->enabled; + break; + } + + pqi_firmware_feature_status(ctrl_info, firmware_feature); +} + static inline void pqi_firmware_feature_update(struct pqi_ctrl_info *ctrl_info, struct pqi_firmware_feature *firmware_feature) { @@ -6867,7 +6902,17 @@ { .feature_name = "New Soft Reset Handshake", .feature_bit = PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE, - .feature_status = pqi_firmware_feature_status, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "RAID IU Timeout", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "TMF IU Timeout", + .feature_bit = PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT, + .feature_status = pqi_ctrl_update_feature_flags, }, }; @@ -6921,7 +6966,6 @@ return; } - ctrl_info->soft_reset_handshake_supported = false; for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) { if (!pqi_firmware_features[i].supported) continue; @@ -6929,10 +6973,6 @@ firmware_features_iomem_addr, pqi_firmware_features[i].feature_bit)) { pqi_firmware_features[i].enabled = true; - if (pqi_firmware_features[i].feature_bit == - PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE) - ctrl_info->soft_reset_handshake_supported = - true; } pqi_firmware_feature_update(ctrl_info, &pqi_firmware_features[i]); @@ -7074,13 +7114,20 @@ return pqi_revert_to_sis_mode(ctrl_info); } +#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 + static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) { int rc; - rc = pqi_force_sis_mode(ctrl_info); - if (rc) - return rc; + if (reset_devices) { + sis_soft_reset(ctrl_info); + msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); + } else { + rc = pqi_force_sis_mode(ctrl_info); + if (rc) + return rc; + } /* * Wait until the controller is ready to start accepting SIS @@ -7386,7 +7433,7 @@ rc = pqi_get_ctrl_product_details(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, - "error obtaining product detail\n"); + "error obtaining product details\n"); return rc; } @@ -7514,6 +7561,7 @@ INIT_WORK(&ctrl_info->event_work, pqi_event_worker); atomic_set(&ctrl_info->num_interrupts, 0); + atomic_set(&ctrl_info->sync_cmds_outstanding, 0); INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker); INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker); @@ -7721,6 +7769,8 @@ dev_err(dev, "Failed to allocate host buffer of size = %u", bytes_requested); } + + return; } static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info) @@ -7787,8 +7837,6 @@ 0, NULL, NO_TIMEOUT); } -#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 - static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info) { msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); @@ -7956,28 +8004,73 @@ pqi_remove_ctrl(ctrl_info); } +static void pqi_crash_if_pending_command(struct pqi_ctrl_info *ctrl_info) +{ + unsigned int i; + struct pqi_io_request *io_request; + struct scsi_cmnd *scmd; + + for (i = 0; i < ctrl_info->max_io_slots; i++) { + io_request = &ctrl_info->io_request_pool[i]; + if (atomic_read(&io_request->refcount) == 0) + continue; + scmd = io_request->scmd; + WARN_ON(scmd != NULL); /* IO command from SML */ + WARN_ON(scmd == NULL); /* Non-IO cmd or driver initiated*/ + } +} + static void pqi_shutdown(struct pci_dev *pci_dev) { int rc; struct pqi_ctrl_info *ctrl_info; ctrl_info = pci_get_drvdata(pci_dev); - if (!ctrl_info) - goto error; + if (!ctrl_info) { + dev_err(&pci_dev->dev, + "cache could not be flushed\n"); + return; + } + + pqi_disable_events(ctrl_info); + pqi_wait_until_ofa_finished(ctrl_info); + pqi_cancel_update_time_worker(ctrl_info); + pqi_cancel_rescan_worker(ctrl_info); + pqi_cancel_event_worker(ctrl_info); + + pqi_ctrl_shutdown_start(ctrl_info); + pqi_ctrl_wait_until_quiesced(ctrl_info); + + rc = pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); + if (rc) { + dev_err(&pci_dev->dev, + "wait for pending I/O failed\n"); + return; + } + + pqi_ctrl_block_device_reset(ctrl_info); + pqi_wait_until_lun_reset_finished(ctrl_info); /* * Write all data in the controller's battery-backed cache to * storage. */ rc = pqi_flush_cache(ctrl_info, SHUTDOWN); - pqi_free_interrupts(ctrl_info); - pqi_reset(ctrl_info); - if (rc == 0) + if (rc) + dev_err(&pci_dev->dev, + "unable to flush controller cache\n"); + + pqi_ctrl_block_requests(ctrl_info); + + rc = pqi_ctrl_wait_for_pending_sync_cmds(ctrl_info); + if (rc) { + dev_err(&pci_dev->dev, + "wait for pending sync cmds failed\n"); return; + } -error: - dev_warn(&pci_dev->dev, - "unable to flush controller cache\n"); + pqi_crash_if_pending_command(ctrl_info); + pqi_reset(ctrl_info); } static void pqi_process_lockup_action_param(void) @@ -8098,6 +8191,10 @@ }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x8460) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x1104) }, { @@ -8170,6 +8267,22 @@ }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0051) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0052) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0053) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0054) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x19e5, 0xd227) }, { @@ -8326,6 +8439,122 @@ }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1400) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1402) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1410) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1411) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1412) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1420) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1430) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1440) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1441) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1450) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1452) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1460) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1461) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1462) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1470) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1471) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1472) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1480) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1490) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1491) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14d0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14e0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14f0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADVANTECH, 0x8312) }, { @@ -8390,6 +8619,10 @@ }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_HP, 0x1002) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1100) }, { @@ -8398,6 +8631,22 @@ }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x0294) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02db) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02dc) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x032e) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1d8d, 0x0800) }, { @@ -8686,6 +8935,8 @@ BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, cdb) != 32); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, + timeout) != 60); + BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, sg_descriptors) != 64); BUILD_BUG_ON(sizeof(struct pqi_raid_path_request) != PQI_OPERATIONAL_IQ_ELEMENT_LENGTH); @@ -8840,6 +9091,8 @@ BUILD_BUG_ON(offsetof(struct pqi_task_management_request, nexus_id) != 10); BUILD_BUG_ON(offsetof(struct pqi_task_management_request, + timeout) != 14); + BUILD_BUG_ON(offsetof(struct pqi_task_management_request, lun_number) != 16); BUILD_BUG_ON(offsetof(struct pqi_task_management_request, protocol_specific) != 24); --- linux-oracle-5.4.0.orig/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ linux-oracle-5.4.0/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -45,9 +45,9 @@ struct sas_phy *phy = pqi_sas_phy->phy; sas_port_delete_phy(pqi_sas_phy->parent_port->port, phy); - sas_phy_free(phy); if (pqi_sas_phy->added_to_port) list_del(&pqi_sas_phy->phy_list_entry); + sas_phy_delete(phy); kfree(pqi_sas_phy); } @@ -312,7 +312,6 @@ static int pqi_sas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) { - int rc; unsigned long flags; struct Scsi_Host *shost; @@ -361,7 +360,7 @@ } } - if (found_device->phy_connected_dev_type != SA_CONTROLLER_DEVICE) { + if (found_device->phy_connected_dev_type != SA_DEVICE_TYPE_CONTROLLER) { rc = -EINVAL; goto out; } @@ -382,12 +381,10 @@ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); return rc; - } static int pqi_sas_get_bay_identifier(struct sas_rphy *rphy) { - int rc; unsigned long flags; struct pqi_ctrl_info *ctrl_info; @@ -482,7 +479,6 @@ req_size -= SMP_CRC_FIELD_LENGTH; put_unaligned_le32(req_size, ¶meters->request_length); - put_unaligned_le32(resp_size, ¶meters->response_length); sg_copy_to_buffer(job->request_payload.sg_list, @@ -512,12 +508,12 @@ struct sas_rphy *rphy) { int rc; - struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + struct pqi_ctrl_info *ctrl_info; struct bmic_csmi_smp_passthru_buffer *smp_buf; struct pqi_raid_error_info error_info; unsigned int reslen = 0; - pqi_ctrl_busy(ctrl_info); + ctrl_info = shost_to_hba(shost); if (job->reply_payload.payload_len == 0) { rc = -ENOMEM; @@ -539,16 +535,6 @@ goto out; } - if (pqi_ctrl_offline(ctrl_info)) { - rc = -ENXIO; - goto out; - } - - if (pqi_ctrl_blocked(ctrl_info)) { - rc = -EBUSY; - goto out; - } - smp_buf = pqi_build_csmi_smp_passthru_buffer(rphy, job); if (!smp_buf) { rc = -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/scsi/sni_53c710.c +++ linux-oracle-5.4.0/drivers/scsi/sni_53c710.c @@ -59,6 +59,7 @@ struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; struct resource *res; + int rc; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) @@ -84,7 +85,9 @@ goto out_kfree; host->this_id = 7; host->base = base; - host->irq = platform_get_irq(dev, 0); + host->irq = rc = platform_get_irq(dev, 0); + if (rc < 0) + goto out_put_host; if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) { printk(KERN_ERR "snirm710: request_irq failed!\n"); goto out_put_host; --- linux-oracle-5.4.0.orig/drivers/scsi/snic/snic_disc.c +++ linux-oracle-5.4.0/drivers/scsi/snic/snic_disc.c @@ -318,7 +318,10 @@ ret); put_device(&snic->shost->shost_gendev); - kfree(tgt); + spin_lock_irqsave(snic->shost->host_lock, flags); + list_del(&tgt->list); + spin_unlock_irqrestore(snic->shost->host_lock, flags); + put_device(&tgt->dev); tgt = NULL; return tgt; --- linux-oracle-5.4.0.orig/drivers/scsi/sr.c +++ linux-oracle-5.4.0/drivers/scsi/sr.c @@ -218,6 +218,8 @@ return DISK_EVENT_EJECT_REQUEST; else if (med->media_event_code == 2) return DISK_EVENT_MEDIA_CHANGE; + else if (med->media_event_code == 3) + return DISK_EVENT_MEDIA_CHANGE; return 0; } @@ -750,7 +752,7 @@ cd->cdi.disk = disk; if (register_cdrom(&cd->cdi)) - goto fail_put; + goto fail_minor; /* * Initialize block layer runtime PM stuffs before the @@ -768,6 +770,10 @@ return 0; +fail_minor: + spin_lock(&sr_index_lock); + clear_bit(minor, sr_index_bits); + spin_unlock(&sr_index_lock); fail_put: put_disk(disk); fail_free: @@ -881,7 +887,7 @@ /* allocate transfer buffer */ - buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) { sr_printk(KERN_ERR, cd, "out of memory.\n"); return; --- linux-oracle-5.4.0.orig/drivers/scsi/sr_vendor.c +++ linux-oracle-5.4.0/drivers/scsi/sr_vendor.c @@ -66,9 +66,6 @@ void sr_vendor_init(Scsi_CD *cd) { -#ifndef CONFIG_BLK_DEV_SR_VENDOR - cd->vendor = VENDOR_SCSI3; -#else const char *vendor = cd->device->vendor; const char *model = cd->device->model; @@ -100,7 +97,6 @@ cd->vendor = VENDOR_TOSHIBA; } -#endif } @@ -114,12 +110,10 @@ struct ccs_modesel_head *modesel; int rc, density = 0; -#ifdef CONFIG_BLK_DEV_SR_VENDOR if (cd->vendor == VENDOR_TOSHIBA) density = (blocklength > 2048) ? 0x81 : 0x83; -#endif - buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) return -ENOMEM; @@ -167,7 +161,7 @@ if (cd->cdi.mask & CDC_MULTI_SESSION) return 0; - buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) return -ENOMEM; @@ -205,7 +199,6 @@ } break; -#ifdef CONFIG_BLK_DEV_SR_VENDOR case VENDOR_NEC:{ unsigned long min, sec, frame; cgc.cmd[0] = 0xde; @@ -298,7 +291,6 @@ sector = buffer[11] + (buffer[10] << 8) + (buffer[9] << 16) + (buffer[8] << 24); break; -#endif /* CONFIG_BLK_DEV_SR_VENDOR */ default: /* should not happen */ --- linux-oracle-5.4.0.orig/drivers/scsi/st.c +++ linux-oracle-5.4.0/drivers/scsi/st.c @@ -1267,8 +1267,8 @@ spin_lock(&st_use_lock); if (STp->in_use) { spin_unlock(&st_use_lock); - scsi_tape_put(STp); DEBC_printk(STp, "Device already in use.\n"); + scsi_tape_put(STp); return (-EBUSY); } @@ -3505,6 +3505,7 @@ int i, cmd_nr, cmd_type, bt; int retval = 0; unsigned int blk; + bool cmd_mtiocget; struct scsi_tape *STp = file->private_data; struct st_modedef *STm; struct st_partstat *STps; @@ -3619,6 +3620,7 @@ */ if (mtc.mt_op != MTREW && mtc.mt_op != MTOFFL && + mtc.mt_op != MTLOAD && mtc.mt_op != MTRETEN && mtc.mt_op != MTERASE && mtc.mt_op != MTSEEK && @@ -3732,17 +3734,28 @@ goto out; } + cmd_mtiocget = cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET); + if ((i = flush_buffer(STp, 0)) < 0) { - retval = i; - goto out; - } - if (STp->can_partitions && - (i = switch_partition(STp)) < 0) { - retval = i; - goto out; + if (cmd_mtiocget && STp->pos_unknown) { + /* flush fails -> modify status accordingly */ + reset_state(STp); + STp->pos_unknown = 1; + } else { /* return error */ + retval = i; + goto out; + } + } else { /* flush_buffer succeeds */ + if (STp->can_partitions) { + i = switch_partition(STp); + if (i < 0) { + retval = i; + goto out; + } + } } - if (cmd_type == _IOC_TYPE(MTIOCGET) && cmd_nr == _IOC_NR(MTIOCGET)) { + if (cmd_mtiocget) { struct mtget mt_status; if (_IOC_SIZE(cmd_in) != sizeof(struct mtget)) { @@ -3756,7 +3769,7 @@ ((STp->density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK); mt_status.mt_blkno = STps->drv_block; mt_status.mt_fileno = STps->drv_file; - if (STp->block_size != 0) { + if (STp->block_size != 0 && mt_status.mt_blkno >= 0) { if (STps->rw == ST_WRITING) mt_status.mt_blkno += (STp->buffer)->buffer_bytes / STp->block_size; --- linux-oracle-5.4.0.orig/drivers/scsi/stex.c +++ linux-oracle-5.4.0/drivers/scsi/stex.c @@ -109,7 +109,9 @@ TASK_ATTRIBUTE_HEADOFQUEUE = 0x1, TASK_ATTRIBUTE_ORDERED = 0x2, TASK_ATTRIBUTE_ACA = 0x4, +}; +enum { SS_STS_NORMAL = 0x80000000, SS_STS_DONE = 0x40000000, SS_STS_HANDSHAKE = 0x20000000, @@ -121,7 +123,9 @@ SS_I2H_REQUEST_RESET = 0x2000, SS_MU_OPERATIONAL = 0x80000000, +}; +enum { STEX_CDB_LENGTH = 16, STATUS_VAR_LEN = 128, @@ -668,16 +672,17 @@ return 0; case PASSTHRU_CMD: if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) { - struct st_drvver ver; + const struct st_drvver ver = { + .major = ST_VER_MAJOR, + .minor = ST_VER_MINOR, + .oem = ST_OEM, + .build = ST_BUILD_VER, + .signature[0] = PASSTHRU_SIGNATURE, + .console_id = host->max_id - 1, + .host_no = hba->host->host_no, + }; size_t cp_len = sizeof(ver); - ver.major = ST_VER_MAJOR; - ver.minor = ST_VER_MINOR; - ver.oem = ST_OEM; - ver.build = ST_BUILD_VER; - ver.signature[0] = PASSTHRU_SIGNATURE; - ver.console_id = host->max_id - 1; - ver.host_no = hba->host->host_no; cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); cmd->result = sizeof(ver) == cp_len ? DID_OK << 16 | COMMAND_COMPLETE << 8 : --- linux-oracle-5.4.0.orig/drivers/scsi/storvsc_drv.c +++ linux-oracle-5.4.0/drivers/scsi/storvsc_drv.c @@ -378,10 +378,14 @@ static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth); static int storvsc_vcpus_per_sub_channel = 4; +static unsigned int storvsc_max_hw_queues; module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); +module_param(storvsc_max_hw_queues, uint, 0644); +MODULE_PARM_DESC(storvsc_max_hw_queues, "Maximum number of hardware queues"); + module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO); MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels"); @@ -1423,6 +1427,8 @@ { blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ)); + /* storvsc devices don't support MAINTENANCE_IN SCSI cmd */ + sdevice->no_report_opcodes = 1; sdevice->no_write_same = 1; /* @@ -1526,10 +1532,6 @@ */ static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd) { -#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) - if (scmnd->device->host->transportt == fc_transport_template) - return fc_eh_timed_out(scmnd); -#endif return BLK_EH_RESET_TIMER; } @@ -1641,6 +1643,7 @@ length = scsi_bufflen(scmnd); payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb; payload_sz = sizeof(cmd_request->mpb); + payload->range.len = 0; if (sg_count) { if (sg_count > MAX_PAGE_BUFFER_COUNT) { @@ -1732,6 +1735,7 @@ { int ret; int num_cpus = num_online_cpus(); + int num_present_cpus = num_present_cpus(); struct Scsi_Host *host; struct hv_host_device *host_dev; bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); @@ -1834,17 +1838,34 @@ * from the host. */ host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT); +#if defined(CONFIG_X86_32) + dev_warn(&device->device, "adjusting sg_tablesize 0x%x -> 0x%x", + host->sg_tablesize, MAX_MULTIPAGE_BUFFER_COUNT); + host->sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT; +#endif + /* + * For non-IDE disks, the host supports multiple channels. * Set the number of HW queues we are supporting. */ - host->nr_hw_queues = num_present_cpus(); + if (!dev_is_ide) { + if (storvsc_max_hw_queues > num_present_cpus) { + storvsc_max_hw_queues = 0; + storvsc_log(device, STORVSC_LOGGING_WARN, + "Resetting invalid storvsc_max_hw_queues value to default.\n"); + } + if (storvsc_max_hw_queues) + host->nr_hw_queues = storvsc_max_hw_queues; + else + host->nr_hw_queues = num_present_cpus; + } /* * Set the error handler work queue. */ host_dev->handle_error_wq = alloc_ordered_workqueue("storvsc_error_wq_%d", - WQ_MEM_RECLAIM, + 0, host->host_no); if (!host_dev->handle_error_wq) goto err_out2; --- linux-oracle-5.4.0.orig/drivers/scsi/sun3_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/sun3_scsi.c @@ -501,7 +501,7 @@ .eh_host_reset_handler = sun3scsi_host_reset, .can_queue = 16, .this_id = 7, - .sg_tablesize = SG_NONE, + .sg_tablesize = 1, .cmd_per_lun = 2, .dma_boundary = PAGE_SIZE - 1, .cmd_size = NCR5380_CMD_SIZE, @@ -523,7 +523,7 @@ sun3_scsi_template.can_queue = setup_can_queue; if (setup_cmd_per_lun > 0) sun3_scsi_template.cmd_per_lun = setup_cmd_per_lun; - if (setup_sg_tablesize >= 0) + if (setup_sg_tablesize > 0) sun3_scsi_template.sg_tablesize = setup_sg_tablesize; if (setup_hostid >= 0) sun3_scsi_template.this_id = setup_hostid & 7; --- linux-oracle-5.4.0.orig/drivers/scsi/sun3x_esp.c +++ linux-oracle-5.4.0/drivers/scsi/sun3x_esp.c @@ -206,7 +206,9 @@ if (!esp->command_block) goto fail_unmap_regs_dma; - host->irq = platform_get_irq(dev, 0); + host->irq = err = platform_get_irq(dev, 0); + if (err < 0) + goto fail_unmap_command_block; err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "SUN3X ESP", esp); if (err < 0) --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/cdns-pltfrm.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/cdns-pltfrm.c @@ -56,7 +56,7 @@ * Make sure the register was updated, * UniPro layer will not work with an incorrect value. */ - mb(); + ufshcd_readl(hba, CDNS_UFS_REG_HCLKDIV); return 0; } @@ -99,6 +99,12 @@ */ ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0); + /* + * Disabling Autohibern8 feature in cadence UFS + * to mask unexpected interrupt trigger. + */ + hba->ahit = 0; + return 0; } --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/tc-dwc-g210-pci.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/tc-dwc-g210-pci.c @@ -135,7 +135,6 @@ return err; } - pci_set_drvdata(pdev, hba); pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs-hisi.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs-hisi.c @@ -481,21 +481,24 @@ host->hba = hba; ufshcd_set_variant(hba, host); - host->rst = devm_reset_control_get(dev, "rst"); + host->rst = devm_reset_control_get(dev, "rst"); if (IS_ERR(host->rst)) { dev_err(dev, "%s: failed to get reset control\n", __func__); - return PTR_ERR(host->rst); + err = PTR_ERR(host->rst); + goto error; } ufs_hisi_set_pm_lvl(hba); err = ufs_hisi_get_resource(host); - if (err) { - ufshcd_set_variant(hba, NULL); - return err; - } + if (err) + goto error; return 0; + +error: + ufshcd_set_variant(hba, NULL); + return err; } static int ufs_hi3660_init(struct ufs_hba *hba) --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs-mediatek.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs-mediatek.c @@ -13,6 +13,7 @@ #include "ufshcd.h" #include "ufshcd-pltfrm.h" +#include "ufs_quirks.h" #include "unipro.h" #include "ufs-mediatek.h" @@ -286,6 +287,15 @@ return 0; } +static int ufs_mtk_apply_dev_quirks(struct ufs_hba *hba, + struct ufs_dev_desc *card) +{ + if (card->wmanufacturerid == UFS_VENDOR_SAMSUNG) + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE), 6); + + return 0; +} + /** * struct ufs_hba_mtk_vops - UFS MTK specific variant operations * @@ -298,6 +308,7 @@ .setup_clocks = ufs_mtk_setup_clocks, .link_startup_notify = ufs_mtk_link_startup_notify, .pwr_change_notify = ufs_mtk_pwr_change_notify, + .apply_dev_quirks = ufs_mtk_apply_dev_quirks, .suspend = ufs_mtk_suspend, .resume = ufs_mtk_resume, }; --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs-qcom.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs-qcom.c @@ -781,8 +781,11 @@ writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio); - /* ensure that ref_clk is enabled/disabled before we return */ - wmb(); + /* + * Make sure the write to ref_clk reaches the destination and + * not stored in a Write Buffer (WB). + */ + readl(host->dev_ref_clk_ctrl_mmio); /* * If we call hibern8 exit after this, we need to make sure that @@ -905,7 +908,8 @@ return err; } -static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba) +static int ufs_qcom_apply_dev_quirks(struct ufs_hba *hba, + struct ufs_dev_desc *card) { int err = 0; @@ -1491,9 +1495,6 @@ */ } mask <<= offset; - - pm_runtime_get_sync(host->hba->dev); - ufshcd_hold(host->hba, false); ufshcd_rmwl(host->hba, TEST_BUS_SEL, (u32)host->testbus.select_major << 19, REG_UFS_CFG1); @@ -1506,8 +1507,6 @@ * committed before returning. */ mb(); - ufshcd_release(host->hba); - pm_runtime_put_sync(host->hba->dev); return 0; } @@ -1545,11 +1544,11 @@ /* sleep a bit intermittently as we are dumping too much data */ ufs_qcom_print_hw_debug_reg_all(hba, NULL, ufs_qcom_dump_regs_wrapper); - usleep_range(1000, 1100); + udelay(1000); ufs_qcom_testbus_read(hba); - usleep_range(1000, 1100); + udelay(1000); ufs_qcom_print_unipro_testbus(hba); - usleep_range(1000, 1100); + udelay(1000); } /** --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs-qcom.h +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs-qcom.h @@ -155,10 +155,10 @@ 1 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); /* - * Make sure assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); } static inline void ufs_qcom_deassert_reset(struct ufs_hba *hba) @@ -167,10 +167,10 @@ 0 << OFFSET_UFS_PHY_SOFT_RESET, REG_UFS_CFG1); /* - * Make sure de-assertion of ufs phy reset is written to - * register before returning + * Dummy read to ensure the write takes effect before doing any sort + * of delay */ - mb(); + ufshcd_readl(hba, REG_UFS_CFG1); } struct ufs_qcom_bus_vote { --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs-sysfs.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs-sysfs.c @@ -126,13 +126,16 @@ return; spin_lock_irqsave(hba->host->host_lock, flags); - if (hba->ahit == ahit) - goto out_unlock; - hba->ahit = ahit; - if (!pm_runtime_suspended(hba->dev)) - ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); -out_unlock: + if (hba->ahit != ahit) + hba->ahit = ahit; spin_unlock_irqrestore(hba->host->host_lock, flags); + if (!pm_runtime_suspended(hba->dev)) { + pm_runtime_get_sync(hba->dev); + ufshcd_hold(hba, false); + ufshcd_auto_hibern8_enable(hba); + ufshcd_release(hba); + pm_runtime_put(hba->dev); + } } /* Convert Auto-Hibernate Idle Timer register value to microseconds */ --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs_bsg.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs_bsg.c @@ -106,8 +106,10 @@ desc_op = bsg_request->upiu_req.qr.opcode; ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff, &desc_len, desc_op); - if (ret) + if (ret) { + pm_runtime_put_sync(hba->dev); goto out; + } /* fall through */ case UPIU_TRANSACTION_NOP_OUT: @@ -202,7 +204,7 @@ bsg_dev->parent = get_device(parent); bsg_dev->release = ufs_bsg_node_release; - dev_set_name(bsg_dev, "ufs-bsg"); + dev_set_name(bsg_dev, "ufs-bsg%u", shost->host_no); ret = device_add(bsg_dev); if (ret) @@ -211,6 +213,7 @@ q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), ufs_bsg_request, NULL, 0); if (IS_ERR(q)) { ret = PTR_ERR(q); + device_del(bsg_dev); goto out; } --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufs_quirks.h +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufs_quirks.h @@ -12,6 +12,7 @@ #define UFS_ANY_VENDOR 0xFFFF #define UFS_ANY_MODEL "ANY_MODEL" +#define UFS_VENDOR_MICRON 0x12C #define UFS_VENDOR_TOSHIBA 0x198 #define UFS_VENDOR_SAMSUNG 0x1CE #define UFS_VENDOR_SKHYNIX 0x1AD --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufshcd-pci.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufshcd-pci.c @@ -96,6 +96,30 @@ { return ufshcd_system_resume(dev_get_drvdata(dev)); } + +/** + * ufshcd_pci_poweroff - suspend-to-disk poweroff function + * @dev: pointer to PCI device handle + * + * Returns 0 if successful + * Returns non-zero otherwise + */ +static int ufshcd_pci_poweroff(struct device *dev) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + int spm_lvl = hba->spm_lvl; + int ret; + + /* + * For poweroff we need to set the UFS device to PowerDown mode. + * Force spm_lvl to ensure that. + */ + hba->spm_lvl = 5; + ret = ufshcd_system_suspend(hba); + hba->spm_lvl = spm_lvl; + return ret; +} + #endif /* !CONFIG_PM_SLEEP */ #ifdef CONFIG_PM @@ -190,8 +214,14 @@ } static const struct dev_pm_ops ufshcd_pci_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ufshcd_pci_suspend, - ufshcd_pci_resume) +#ifdef CONFIG_PM_SLEEP + .suspend = ufshcd_pci_suspend, + .resume = ufshcd_pci_resume, + .freeze = ufshcd_pci_suspend, + .thaw = ufshcd_pci_resume, + .poweroff = ufshcd_pci_poweroff, + .restore = ufshcd_pci_resume, +#endif SET_RUNTIME_PM_OPS(ufshcd_pci_runtime_suspend, ufshcd_pci_runtime_resume, ufshcd_pci_runtime_idle) --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufshcd-pltfrm.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -125,9 +125,20 @@ return ret; } +static bool phandle_exists(const struct device_node *np, + const char *phandle_name, int index) +{ + struct device_node *parse_np = of_parse_phandle(np, phandle_name, index); + + if (parse_np) + of_node_put(parse_np); + + return parse_np != NULL; +} + #define MAX_PROP_SIZE 32 static int ufshcd_populate_vreg(struct device *dev, const char *name, - struct ufs_vreg **out_vreg) + struct ufs_vreg **out_vreg) { int ret = 0; char prop_name[MAX_PROP_SIZE]; @@ -140,7 +151,7 @@ } snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", name); - if (!of_parse_phandle(np, prop_name, 0)) { + if (!phandle_exists(np, prop_name, 0)) { dev_info(dev, "%s: Unable to find %s regulator, assuming enabled\n", __func__, prop_name); goto out; @@ -436,8 +447,6 @@ goto dealloc_host; } - platform_set_drvdata(pdev, hba); - pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufshcd.c +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufshcd.c @@ -118,8 +118,13 @@ if (!regs) return -ENOMEM; - for (pos = 0; pos < len; pos += 4) + for (pos = 0; pos < len; pos += 4) { + if (offset == 0 && + pos >= REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER && + pos <= REG_UIC_ERROR_CODE_DME) + continue; regs[pos / 4] = ufshcd_readl(hba, offset + pos); + } ufshcd_hex_dump(prefix, regs, len); kfree(regs); @@ -217,6 +222,8 @@ static struct ufs_dev_fix ufs_fixups[] = { /* UFS cards deviations table */ + UFS_FIX(UFS_VENDOR_MICRON, UFS_ANY_MODEL, + UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, @@ -237,7 +244,7 @@ END_FIX }; -static void ufshcd_tmc_handler(struct ufs_hba *hba); +static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba); static void ufshcd_async_scan(void *data, async_cookie_t cookie); static int ufshcd_reset_and_restore(struct ufs_hba *hba); static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd); @@ -318,8 +325,7 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag, const char *str) { - int off = (int)tag - hba->nutrs; - struct utp_task_req_desc *descp = &hba->utmrdl_base_addr[off]; + struct utp_task_req_desc *descp = &hba->utmrdl_base_addr[tag]; trace_ufshcd_upiu(dev_name(hba->dev), str, &descp->req_header, &descp->input_param1); @@ -332,27 +338,27 @@ u8 opcode = 0; u32 intr, doorbell; struct ufshcd_lrb *lrbp = &hba->lrb[tag]; + struct scsi_cmnd *cmd = lrbp->cmd; int transfer_len = -1; if (!trace_ufshcd_command_enabled()) { /* trace UPIU W/O tracing command */ - if (lrbp->cmd) + if (cmd) ufshcd_add_cmd_upiu_trace(hba, tag, str); return; } - if (lrbp->cmd) { /* data phase exists */ + if (cmd) { /* data phase exists */ /* trace UPIU also */ ufshcd_add_cmd_upiu_trace(hba, tag, str); - opcode = (u8)(*lrbp->cmd->cmnd); + opcode = cmd->cmnd[0]; if ((opcode == READ_10) || (opcode == WRITE_10)) { /* * Currently we only fully trace read(10) and write(10) * commands */ - if (lrbp->cmd->request && lrbp->cmd->request->bio) - lba = - lrbp->cmd->request->bio->bi_iter.bi_sector; + if (cmd->request && cmd->request->bio) + lba = cmd->request->bio->bi_iter.bi_sector; transfer_len = be32_to_cpu( lrbp->ucd_req_ptr->sc.exp_data_transfer_len); } @@ -494,8 +500,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba) { dev_err(hba->dev, "UFS Host state=%d\n", hba->ufshcd_state); - dev_err(hba->dev, "lrb in use=0x%lx, outstanding reqs=0x%lx tasks=0x%lx\n", - hba->lrb_in_use, hba->outstanding_reqs, hba->outstanding_tasks); + dev_err(hba->dev, "outstanding reqs=0x%lx tasks=0x%lx\n", + hba->outstanding_reqs, hba->outstanding_tasks); dev_err(hba->dev, "saved_err=0x%x, saved_uic_err=0x%x\n", hba->saved_err, hba->saved_uic_err); dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", @@ -643,40 +649,6 @@ } /** - * ufshcd_get_tm_free_slot - get a free slot for task management request - * @hba: per adapter instance - * @free_slot: pointer to variable with available slot value - * - * Get a free tag and lock it until ufshcd_put_tm_slot() is called. - * Returns 0 if free slot is not available, else return 1 with tag value - * in @free_slot. - */ -static bool ufshcd_get_tm_free_slot(struct ufs_hba *hba, int *free_slot) -{ - int tag; - bool ret = false; - - if (!free_slot) - goto out; - - do { - tag = find_first_zero_bit(&hba->tm_slots_in_use, hba->nutmrs); - if (tag >= hba->nutmrs) - goto out; - } while (test_and_set_bit_lock(tag, &hba->tm_slots_in_use)); - - *free_slot = tag; - ret = true; -out: - return ret; -} - -static inline void ufshcd_put_tm_slot(struct ufs_hba *hba, int slot) -{ - clear_bit_unlock(slot, &hba->tm_slots_in_use); -} - -/** * ufshcd_utrl_clear - Clear a bit in UTRLCLR register * @hba: per adapter instance * @pos: position of the bit to be cleared @@ -1255,8 +1227,15 @@ } spin_unlock_irqrestore(hba->host->host_lock, irq_flags); + pm_runtime_get_noresume(hba->dev); + if (!pm_runtime_active(hba->dev)) { + pm_runtime_put_noidle(hba->dev); + ret = -EAGAIN; + goto out; + } start = ktime_get(); ret = ufshcd_devfreq_scale(hba, scale_up); + pm_runtime_put(hba->dev); trace_ufshcd_profile_clk_scaling(dev_name(hba->dev), (scale_up ? "up" : "down"), @@ -1270,6 +1249,24 @@ return ret; } +static bool ufshcd_is_busy(struct request *req, void *priv, bool reserved) +{ + int *busy = priv; + + WARN_ON_ONCE(reserved); + (*busy)++; + return false; +} + +/* Whether or not any tag is in use by a request that is in progress. */ +static bool ufshcd_any_tag_in_use(struct ufs_hba *hba) +{ + struct request_queue *q = hba->cmd_queue; + int busy = 0; + + blk_mq_tagset_busy_iter(q->tag_set, ufshcd_is_busy, &busy); + return busy; +} static int ufshcd_devfreq_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) @@ -1514,6 +1511,7 @@ int ufshcd_hold(struct ufs_hba *hba, bool async) { int rc = 0; + bool flush_result; unsigned long flags; if (!ufshcd_is_clkgating_allowed(hba)) @@ -1539,8 +1537,15 @@ */ if (ufshcd_can_hibern8_during_gating(hba) && ufshcd_is_link_hibern8(hba)) { + if (async) { + rc = -EAGAIN; + hba->clk_gating.active_reqs--; + break; + } spin_unlock_irqrestore(hba->host->host_lock, flags); - flush_work(&hba->clk_gating.ungate_work); + flush_result = flush_work(&hba->clk_gating.ungate_work); + if (hba->clk_gating.is_suspended && !flush_result) + goto out; spin_lock_irqsave(hba->host->host_lock, flags); goto start; } @@ -1559,12 +1564,12 @@ */ /* fallthrough */ case CLKS_OFF: - ufshcd_scsi_block_requests(hba); hba->clk_gating.state = REQ_CLKS_ON; trace_ufshcd_clk_gating(dev_name(hba->dev), hba->clk_gating.state); - queue_work(hba->clk_gating.clk_gating_workq, - &hba->clk_gating.ungate_work); + if (queue_work(hba->clk_gating.clk_gating_workq, + &hba->clk_gating.ungate_work)) + ufshcd_scsi_block_requests(hba); /* * fall through to check if we should wait for this * work to be done or not. @@ -1616,7 +1621,7 @@ if (hba->clk_gating.active_reqs || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL - || hba->lrb_in_use || hba->outstanding_tasks + || ufshcd_any_tag_in_use(hba) || hba->outstanding_tasks || hba->active_uic_cmd || hba->uic_async_done) goto rel_lock; @@ -1670,7 +1675,7 @@ if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL - || hba->lrb_in_use || hba->outstanding_tasks + || ufshcd_any_tag_in_use(hba) || hba->outstanding_tasks || hba->active_uic_cmd || hba->uic_async_done || ufshcd_eh_in_progress(hba)) return; @@ -1878,12 +1883,12 @@ { hba->lrb[task_tag].issue_time_stamp = ktime_get(); hba->lrb[task_tag].compl_time_stamp = ktime_set(0, 0); + ufshcd_add_command_trace(hba, task_tag, "send"); ufshcd_clk_scaling_start_busy(hba); __set_bit(task_tag, &hba->outstanding_reqs); ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); /* Make sure that doorbell is committed immediately */ wmb(); - ufshcd_add_command_trace(hba, task_tag, "send"); } /** @@ -2440,22 +2445,9 @@ hba->req_abort_count = 0; - /* acquire the tag to make sure device cmds don't use it */ - if (test_and_set_bit_lock(tag, &hba->lrb_in_use)) { - /* - * Dev manage command in progress, requeue the command. - * Requeuing the command helps in cases where the request *may* - * find different tag instead of waiting for dev manage command - * completion. - */ - err = SCSI_MLQUEUE_HOST_BUSY; - goto out; - } - err = ufshcd_hold(hba, true); if (err) { err = SCSI_MLQUEUE_HOST_BUSY; - clear_bit_unlock(tag, &hba->lrb_in_use); goto out; } WARN_ON(hba->clk_gating.state != CLKS_ON); @@ -2475,8 +2467,8 @@ err = ufshcd_map_sg(hba, lrbp); if (err) { + ufshcd_release(hba); lrbp->cmd = NULL; - clear_bit_unlock(tag, &hba->lrb_in_use); goto out; } /* Make sure descriptors are ready before ringing the doorbell */ @@ -2624,48 +2616,10 @@ } /** - * ufshcd_get_dev_cmd_tag - Get device management command tag - * @hba: per-adapter instance - * @tag_out: pointer to variable with available slot value - * - * Get a free slot and lock it until device management command - * completes. - * - * Returns false if free slot is unavailable for locking, else - * return true with tag value in @tag. - */ -static bool ufshcd_get_dev_cmd_tag(struct ufs_hba *hba, int *tag_out) -{ - int tag; - bool ret = false; - unsigned long tmp; - - if (!tag_out) - goto out; - - do { - tmp = ~hba->lrb_in_use; - tag = find_last_bit(&tmp, hba->nutrs); - if (tag >= hba->nutrs) - goto out; - } while (test_and_set_bit_lock(tag, &hba->lrb_in_use)); - - *tag_out = tag; - ret = true; -out: - return ret; -} - -static inline void ufshcd_put_dev_cmd_tag(struct ufs_hba *hba, int tag) -{ - clear_bit_unlock(tag, &hba->lrb_in_use); -} - -/** * ufshcd_exec_dev_cmd - API for sending device management requests * @hba: UFS hba * @cmd_type: specifies the type (NOP, Query...) - * @timeout: time in seconds + * @timeout: timeout in milliseconds * * NOTE: Since there is only one available tag for device management commands, * it is expected you hold the hba->dev_cmd.lock mutex. @@ -2673,6 +2627,8 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, enum dev_cmd_type cmd_type, int timeout) { + struct request_queue *q = hba->cmd_queue; + struct request *req; struct ufshcd_lrb *lrbp; int err; int tag; @@ -2686,7 +2642,16 @@ * Even though we use wait_event() which sleeps indefinitely, * the maximum wait time is bounded by SCSI request timeout. */ - wait_event(hba->dev_cmd.tag_wq, ufshcd_get_dev_cmd_tag(hba, &tag)); + req = blk_get_request(q, REQ_OP_DRV_OUT, 0); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out_unlock; + } + tag = req->tag; + WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); + /* Set the timeout such that the SCSI error handler is not activated. */ + req->timeout = msecs_to_jiffies(2 * timeout); + blk_mq_start_request(req); init_completion(&wait); lrbp = &hba->lrb[tag]; @@ -2711,8 +2676,8 @@ err ? "query_complete_err" : "query_complete"); out_put_tag: - ufshcd_put_dev_cmd_tag(hba, tag); - wake_up(&hba->dev_cmd.tag_wq); + blk_put_request(req); +out_unlock: up_read(&hba->clk_scaling_lock); return err; } @@ -2986,10 +2951,10 @@ goto out_unlock; } - hba->dev_cmd.query.descriptor = NULL; *buf_len = be16_to_cpu(response->upiu_res.length); out_unlock: + hba->dev_cmd.query.descriptor = NULL; mutex_unlock(&hba->dev_cmd.lock); out: ufshcd_release(hba); @@ -3300,7 +3265,7 @@ */ ret = utf16s_to_utf8s(uc_str->uc, uc_str->len - QUERY_DESC_HDR_SIZE, - UTF16_BIG_ENDIAN, str, ascii_len); + UTF16_BIG_ENDIAN, str, ascii_len - 1); /* replace non-printable or non-ASCII characters with spaces */ for (i = 0; i < ret; i++) @@ -3575,7 +3540,7 @@ ret = ufshcd_send_uic_cmd(hba, &uic_cmd); if (ret) dev_err(hba->dev, - "dme-reset: error code %d\n", ret); + "dme-enable: error code %d\n", ret); return ret; } @@ -3604,11 +3569,16 @@ min_sleep_time_us = MIN_DELAY_BEFORE_DME_CMDS_US - delta; else - return; /* no more delay required */ + min_sleep_time_us = 0; /* no more delay required */ + } + + if (min_sleep_time_us > 0) { + /* allow sleep for extra 50us if needed */ + usleep_range(min_sleep_time_us, min_sleep_time_us + 50); } - /* allow sleep for extra 50us if needed */ - usleep_range(min_sleep_time_us, min_sleep_time_us + 50); + /* update the last_dme_cmd_tstamp */ + hba->last_dme_cmd_tstamp = ktime_get(); } /** @@ -3766,7 +3736,7 @@ * Make sure UIC command completion interrupt is disabled before * issuing UIC command. */ - wmb(); + ufshcd_readl(hba, REG_INTERRUPT_ENABLE); reenable_intr = true; } ret = __ufshcd_send_uic_cmd(hba, cmd, false); @@ -3885,15 +3855,24 @@ ktime_to_us(ktime_sub(ktime_get(), start)), ret); if (ret) { + int err; + dev_err(hba->dev, "%s: hibern8 enter failed. ret = %d\n", __func__, ret); /* - * If link recovery fails then return error so that caller - * don't retry the hibern8 enter again. + * If link recovery fails then return error code returned from + * ufshcd_link_recovery(). + * If link recovery succeeds then return -EAGAIN to attempt + * hibern8 enter retry again. */ - if (ufshcd_link_recovery(hba)) - ret = -ENOLINK; + err = ufshcd_link_recovery(hba); + if (err) { + dev_err(hba->dev, "%s: link recovery failed", __func__); + ret = err; + } else { + ret = -EAGAIN; + } } else ufshcd_vops_hibern8_notify(hba, UIC_CMD_DME_HIBER_ENTER, POST_CHANGE); @@ -3907,7 +3886,7 @@ for (retries = UIC_HIBERN8_ENTER_RETRIES; retries > 0; retries--) { ret = __ufshcd_uic_hibern8_enter(hba); - if (!ret || ret == -ENOLINK) + if (!ret) goto out; } out: @@ -3941,7 +3920,7 @@ return ret; } -static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) +void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) { unsigned long flags; @@ -4779,7 +4758,8 @@ break; } /* end of switch */ - if (host_byte(result) != DID_OK) + if ((host_byte(result) != DID_OK) && + (host_byte(result) != DID_REQUEUE) && !hba->silence_err_logs) ufshcd_print_trs(hba, 1 << lrbp->task_tag, true); return result; } @@ -4788,19 +4768,29 @@ * ufshcd_uic_cmd_compl - handle completion of uic command * @hba: per adapter instance * @intr_status: interrupt status generated by the controller + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ -static void ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) +static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) { + irqreturn_t retval = IRQ_NONE; + if ((intr_status & UIC_COMMAND_COMPL) && hba->active_uic_cmd) { hba->active_uic_cmd->argument2 |= ufshcd_get_uic_cmd_result(hba); hba->active_uic_cmd->argument3 = ufshcd_get_dme_attr_val(hba); complete(&hba->active_uic_cmd->done); + retval = IRQ_HANDLED; } - if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) + if ((intr_status & UFSHCD_UIC_PWR_MASK) && hba->uic_async_done) { complete(hba->uic_async_done); + retval = IRQ_HANDLED; + } + return retval; } /** @@ -4826,7 +4816,6 @@ cmd->result = result; /* Mark completed command as NULL in LRB */ lrbp->cmd = NULL; - clear_bit_unlock(index, &hba->lrb_in_use); /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); __ufshcd_release(hba); @@ -4848,16 +4837,17 @@ hba->outstanding_reqs ^= completed_reqs; ufshcd_clk_scaling_update_busy(hba); - - /* we might have free'd some tags above */ - wake_up(&hba->dev_cmd.tag_wq); } /** * ufshcd_transfer_req_compl - handle SCSI and query command completion * @hba: per adapter instance + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ -static void ufshcd_transfer_req_compl(struct ufs_hba *hba) +static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) { unsigned long completed_reqs; u32 tr_doorbell; @@ -4876,7 +4866,12 @@ tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); completed_reqs = tr_doorbell ^ hba->outstanding_reqs; - __ufshcd_transfer_req_compl(hba, completed_reqs); + if (completed_reqs) { + __ufshcd_transfer_req_compl(hba, completed_reqs); + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } } /** @@ -5014,6 +5009,7 @@ hba->auto_bkops_enabled = false; trace_ufshcd_auto_bkops_state(dev_name(hba->dev), "Disabled"); + hba->is_urgent_bkops_lvl_checked = false; out: return err; } @@ -5038,6 +5034,7 @@ hba->ee_ctrl_mask &= ~MASK_EE_URGENT_BKOPS; ufshcd_disable_auto_bkops(hba); } + hba->is_urgent_bkops_lvl_checked = false; } static inline int ufshcd_get_bkops_status(struct ufs_hba *hba, u32 *status) @@ -5309,8 +5306,8 @@ /* * if host reset is required then skip clearing the pending - * transfers forcefully because they will automatically get - * cleared after link startup. + * transfers forcefully because they will get cleared during + * host reset and restore */ if (needs_reset) goto skip_pending_xfer_clear; @@ -5395,67 +5392,84 @@ /** * ufshcd_update_uic_error - check and set fatal UIC error flags. * @hba: per-adapter instance + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ -static void ufshcd_update_uic_error(struct ufs_hba *hba) +static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) { u32 reg; + irqreturn_t retval = IRQ_NONE; /* PHY layer lane error */ reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER); /* Ignore LINERESET indication, as this is not an error */ if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) && - (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) { + (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) { /* * To know whether this error is fatal or not, DB timeout * must be checked but this error is handled separately. */ dev_dbg(hba->dev, "%s: UIC Lane error reported\n", __func__); ufshcd_update_reg_hist(&hba->ufs_stats.pa_err, reg); + retval |= IRQ_HANDLED; } /* PA_INIT_ERROR is fatal and needs UIC reset */ reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DATA_LINK_LAYER); - if (reg) + if ((reg & UIC_DATA_LINK_LAYER_ERROR) && + (reg & UIC_DATA_LINK_LAYER_ERROR_CODE_MASK)) { ufshcd_update_reg_hist(&hba->ufs_stats.dl_err, reg); - if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) - hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR; - else if (hba->dev_quirks & - UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { - if (reg & UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED) - hba->uic_error |= - UFSHCD_UIC_DL_NAC_RECEIVED_ERROR; - else if (reg & UIC_DATA_LINK_LAYER_ERROR_TCx_REPLAY_TIMEOUT) - hba->uic_error |= UFSHCD_UIC_DL_TCx_REPLAY_ERROR; + if (reg & UIC_DATA_LINK_LAYER_ERROR_PA_INIT) + hba->uic_error |= UFSHCD_UIC_DL_PA_INIT_ERROR; + else if (hba->dev_quirks & + UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS) { + if (reg & UIC_DATA_LINK_LAYER_ERROR_NAC_RECEIVED) + hba->uic_error |= + UFSHCD_UIC_DL_NAC_RECEIVED_ERROR; + else if (reg & UIC_DATA_LINK_LAYER_ERROR_TCx_REPLAY_TIMEOUT) + hba->uic_error |= UFSHCD_UIC_DL_TCx_REPLAY_ERROR; + } + retval |= IRQ_HANDLED; } /* UIC NL/TL/DME errors needs software retry */ reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_NETWORK_LAYER); - if (reg) { + if ((reg & UIC_NETWORK_LAYER_ERROR) && + (reg & UIC_NETWORK_LAYER_ERROR_CODE_MASK)) { ufshcd_update_reg_hist(&hba->ufs_stats.nl_err, reg); hba->uic_error |= UFSHCD_UIC_NL_ERROR; + retval |= IRQ_HANDLED; } reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_TRANSPORT_LAYER); - if (reg) { + if ((reg & UIC_TRANSPORT_LAYER_ERROR) && + (reg & UIC_TRANSPORT_LAYER_ERROR_CODE_MASK)) { ufshcd_update_reg_hist(&hba->ufs_stats.tl_err, reg); hba->uic_error |= UFSHCD_UIC_TL_ERROR; + retval |= IRQ_HANDLED; } reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_DME); - if (reg) { + if ((reg & UIC_DME_ERROR) && + (reg & UIC_DME_ERROR_CODE_MASK)) { ufshcd_update_reg_hist(&hba->ufs_stats.dme_err, reg); hba->uic_error |= UFSHCD_UIC_DME_ERROR; + retval |= IRQ_HANDLED; } dev_dbg(hba->dev, "%s: UIC error flags = 0x%08x\n", __func__, hba->uic_error); + return retval; } static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, u32 intr_mask) { - if (!ufshcd_is_auto_hibern8_supported(hba)) + if (!ufshcd_is_auto_hibern8_supported(hba) || + !ufshcd_is_auto_hibern8_enabled(hba)) return false; if (!(intr_mask & UFSHCD_UIC_HIBERN8_MASK)) @@ -5472,10 +5486,15 @@ /** * ufshcd_check_errors - Check for errors that need s/w attention * @hba: per-adapter instance + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ -static void ufshcd_check_errors(struct ufs_hba *hba) +static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) { bool queue_eh_work = false; + irqreturn_t retval = IRQ_NONE; if (hba->errors & INT_FATAL_ERRORS) { ufshcd_update_reg_hist(&hba->ufs_stats.fatal_err, hba->errors); @@ -5484,7 +5503,7 @@ if (hba->errors & UIC_ERROR) { hba->uic_error = 0; - ufshcd_update_uic_error(hba); + retval = ufshcd_update_uic_error(hba); if (hba->uic_error) queue_eh_work = true; } @@ -5532,6 +5551,7 @@ } schedule_work(&hba->eh_work); } + retval |= IRQ_HANDLED; } /* * if (!queue_eh_work) - @@ -5539,44 +5559,81 @@ * itself without s/w intervention or errors that will be * handled by the SCSI core layer. */ + return retval; +} + +struct ctm_info { + struct ufs_hba *hba; + unsigned long pending; + unsigned int ncpl; +}; + +static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) +{ + struct ctm_info *const ci = priv; + struct completion *c; + + WARN_ON_ONCE(reserved); + if (test_bit(req->tag, &ci->pending)) + return true; + ci->ncpl++; + c = req->end_io_data; + if (c) + complete(c); + return true; } /** * ufshcd_tmc_handler - handle task management function completion * @hba: per adapter instance - */ -static void ufshcd_tmc_handler(struct ufs_hba *hba) -{ - u32 tm_doorbell; + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt + */ +static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) +{ + struct request_queue *q = hba->tmf_queue; + struct ctm_info ci = { + .hba = hba, + .pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL), + }; - tm_doorbell = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); - hba->tm_condition = tm_doorbell ^ hba->outstanding_tasks; - wake_up(&hba->tm_wq); + blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); + return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; } /** * ufshcd_sl_intr - Interrupt service routine * @hba: per adapter instance * @intr_status: contains interrupts generated by the controller + * + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ -static void ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) +static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { + irqreturn_t retval = IRQ_NONE; + hba->errors = UFSHCD_ERROR_MASK & intr_status; if (ufshcd_is_auto_hibern8_error(hba, intr_status)) hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); if (hba->errors) - ufshcd_check_errors(hba); + retval |= ufshcd_check_errors(hba); if (intr_status & UFSHCD_UIC_MASK) - ufshcd_uic_cmd_compl(hba, intr_status); + retval |= ufshcd_uic_cmd_compl(hba, intr_status); if (intr_status & UTP_TASK_REQ_COMPL) - ufshcd_tmc_handler(hba); + retval |= ufshcd_tmc_handler(hba); if (intr_status & UTP_TRANSFER_REQ_COMPL) - ufshcd_transfer_req_compl(hba); + retval |= ufshcd_transfer_req_compl(hba); + + return retval; } /** @@ -5584,12 +5641,13 @@ * @irq: irq number * @__hba: pointer to adapter instance * - * Returns IRQ_HANDLED - If interrupt is valid - * IRQ_NONE - If invalid interrupt + * Returns + * IRQ_HANDLED - If interrupt is valid + * IRQ_NONE - If invalid interrupt */ static irqreturn_t ufshcd_intr(int irq, void *__hba) { - u32 intr_status, enabled_intr_status; + u32 intr_status, enabled_intr_status = 0; irqreturn_t retval = IRQ_NONE; struct ufs_hba *hba = __hba; int retries = hba->nutrs; @@ -5603,18 +5661,25 @@ * read, make sure we handle them by checking the interrupt status * again in a loop until we process all of the reqs before returning. */ - do { + while (intr_status && retries--) { enabled_intr_status = intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE); if (intr_status) ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS); - if (enabled_intr_status) { - ufshcd_sl_intr(hba, enabled_intr_status); - retval = IRQ_HANDLED; - } + if (enabled_intr_status) + retval |= ufshcd_sl_intr(hba, enabled_intr_status); intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); - } while (intr_status && --retries); + } + + if (enabled_intr_status && retval == IRQ_NONE && + !ufshcd_eh_in_progress(hba)) { + dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x (-, 0x%08x)\n", + __func__, + intr_status, + enabled_intr_status); + ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: "); + } spin_unlock(hba->host->host_lock); return retval; @@ -5644,33 +5709,39 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, struct utp_task_req_desc *treq, u8 tm_function) { + struct request_queue *q = hba->tmf_queue; struct Scsi_Host *host = hba->host; + DECLARE_COMPLETION_ONSTACK(wait); + struct request *req; unsigned long flags; - int free_slot, task_tag, err; + int task_tag, err; /* - * Get free slot, sleep if slots are unavailable. - * Even though we use wait_event() which sleeps indefinitely, - * the maximum wait time is bounded by %TM_CMD_TIMEOUT. + * blk_get_request() is used here only to get a free tag. */ - wait_event(hba->tm_tag_wq, ufshcd_get_tm_free_slot(hba, &free_slot)); + req = blk_get_request(q, REQ_OP_DRV_OUT, 0); + if (IS_ERR(req)) + return PTR_ERR(req); + + req->end_io_data = &wait; ufshcd_hold(hba, false); spin_lock_irqsave(host->host_lock, flags); - task_tag = hba->nutrs + free_slot; + blk_mq_start_request(req); + task_tag = req->tag; treq->req_header.dword_0 |= cpu_to_be32(task_tag); - memcpy(hba->utmrdl_base_addr + free_slot, treq, sizeof(*treq)); - ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function); + memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq)); + ufshcd_vops_setup_task_mgmt(hba, task_tag, tm_function); /* send command to the controller */ - __set_bit(free_slot, &hba->outstanding_tasks); + __set_bit(task_tag, &hba->outstanding_tasks); /* Make sure descriptors are ready before ringing the task doorbell */ wmb(); - ufshcd_writel(hba, 1 << free_slot, REG_UTP_TASK_REQ_DOOR_BELL); + ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL); /* Make sure that doorbell is committed immediately */ wmb(); @@ -5679,33 +5750,35 @@ ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_send"); /* wait until the task management command is completed */ - err = wait_event_timeout(hba->tm_wq, - test_bit(free_slot, &hba->tm_condition), + err = wait_for_completion_io_timeout(&wait, msecs_to_jiffies(TM_CMD_TIMEOUT)); if (!err) { + /* + * Make sure that ufshcd_compl_tm() does not trigger a + * use-after-free. + */ + req->end_io_data = NULL; ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete_err"); dev_err(hba->dev, "%s: task management cmd 0x%.2x timed-out\n", __func__, tm_function); - if (ufshcd_clear_tm_cmd(hba, free_slot)) - dev_WARN(hba->dev, "%s: unable clear tm cmd (slot %d) after timeout\n", - __func__, free_slot); + if (ufshcd_clear_tm_cmd(hba, task_tag)) + dev_WARN(hba->dev, "%s: unable to clear tm cmd (slot %d) after timeout\n", + __func__, task_tag); err = -ETIMEDOUT; } else { err = 0; - memcpy(treq, hba->utmrdl_base_addr + free_slot, sizeof(*treq)); + memcpy(treq, hba->utmrdl_base_addr + task_tag, sizeof(*treq)); ufshcd_add_tm_upiu_trace(hba, task_tag, "tm_complete"); } spin_lock_irqsave(hba->host->host_lock, flags); - __clear_bit(free_slot, &hba->outstanding_tasks); + __clear_bit(task_tag, &hba->outstanding_tasks); spin_unlock_irqrestore(hba->host->host_lock, flags); - clear_bit(free_slot, &hba->tm_condition); - ufshcd_put_tm_slot(hba, free_slot); - wake_up(&hba->tm_tag_wq); - ufshcd_release(hba); + blk_put_request(req); + return err; } @@ -5779,6 +5852,8 @@ int cmd_type, enum query_opcode desc_op) { + struct request_queue *q = hba->cmd_queue; + struct request *req; struct ufshcd_lrb *lrbp; int err = 0; int tag; @@ -5788,7 +5863,13 @@ down_read(&hba->clk_scaling_lock); - wait_event(hba->dev_cmd.tag_wq, ufshcd_get_dev_cmd_tag(hba, &tag)); + req = blk_get_request(q, REQ_OP_DRV_OUT, 0); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto out_unlock; + } + tag = req->tag; + WARN_ON_ONCE(!ufshcd_valid_tag(hba, tag)); init_completion(&wait); lrbp = &hba->lrb[tag]; @@ -5862,8 +5943,8 @@ } } - ufshcd_put_dev_cmd_tag(hba, tag); - wake_up(&hba->dev_cmd.tag_wq); + blk_put_request(req); +out_unlock: up_read(&hba->clk_scaling_lock); return err; } @@ -5950,19 +6031,16 @@ { struct Scsi_Host *host; struct ufs_hba *hba; - unsigned int tag; u32 pos; int err; - u8 resp = 0xF; - struct ufshcd_lrb *lrbp; + u8 resp = 0xF, lun; unsigned long flags; host = cmd->device->host; hba = shost_priv(host); - tag = cmd->request->tag; - lrbp = &hba->lrb[tag]; - err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp); + lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun); + err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp); if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) { if (!err) err = resp; @@ -5971,7 +6049,7 @@ /* clear the commands that were pending for corresponding LUN */ for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) { - if (hba->lrb[pos].lun == lrbp->lun) { + if (hba->lrb[pos].lun == lun) { err = ufshcd_clear_cmd(hba, pos); if (err) break; @@ -6117,7 +6195,7 @@ /* command completed already */ dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n", __func__, tag); - goto out; + goto cleanup; } else { dev_err(hba->dev, "%s: no response from device. tag = %d, err %d\n", @@ -6151,6 +6229,9 @@ goto out; } + lrbp->cmd = NULL; + +cleanup: scsi_dma_unmap(cmd); spin_lock_irqsave(host->host_lock, flags); @@ -6158,9 +6239,6 @@ hba->lrb[tag].cmd = NULL; spin_unlock_irqrestore(host->host_lock, flags); - clear_bit_unlock(tag, &hba->lrb_in_use); - wake_up(&hba->dev_cmd.tag_wq); - out: if (!err) { err = SUCCESS; @@ -6193,9 +6271,15 @@ int err; unsigned long flags; - /* Reset the host controller */ + /* + * Stop the host controller and complete the requests + * cleared by h/w + */ spin_lock_irqsave(hba->host->host_lock, flags); ufshcd_hba_stop(hba, false); + hba->silence_err_logs = true; + ufshcd_complete_requests(hba); + hba->silence_err_logs = false; spin_unlock_irqrestore(hba->host->host_lock, flags); /* scale up clocks to max frequency before full reinitialization */ @@ -6229,7 +6313,6 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) { int err = 0; - unsigned long flags; int retries = MAX_HOST_RESET_RETRIES; do { @@ -6239,15 +6322,6 @@ err = ufshcd_host_reset_and_restore(hba); } while (err && --retries); - /* - * After reset the door-bell might be cleared, complete - * outstanding requests in s/w here. - */ - spin_lock_irqsave(hba->host->host_lock, flags); - ufshcd_transfer_req_compl(hba); - ufshcd_tmc_handler(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); - return err; } @@ -6713,7 +6787,8 @@ return ret; } -static void ufshcd_tune_unipro_params(struct ufs_hba *hba) +static void ufshcd_tune_unipro_params(struct ufs_hba *hba, + struct ufs_dev_desc *card) { if (ufshcd_is_unipro_pa_params_tuning_req(hba)) { ufshcd_tune_pa_tactivate(hba); @@ -6727,7 +6802,7 @@ if (hba->dev_quirks & UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE) ufshcd_quirk_tune_host_pa_tactivate(hba); - ufshcd_vops_apply_dev_quirks(hba); + ufshcd_vops_apply_dev_quirks(hba, card); } static void ufshcd_clear_dbg_ufs_stats(struct ufs_hba *hba) @@ -6770,23 +6845,13 @@ &hba->desc_size.geom_desc); if (err) hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; + err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0, &hba->desc_size.hlth_desc); if (err) hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; } -static void ufshcd_def_desc_sizes(struct ufs_hba *hba) -{ - hba->desc_size.dev_desc = QUERY_DESC_DEVICE_DEF_SIZE; - hba->desc_size.pwr_desc = QUERY_DESC_POWER_DEF_SIZE; - hba->desc_size.interc_desc = QUERY_DESC_INTERCONNECT_DEF_SIZE; - hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; - hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; - hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; - hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; -} - static struct ufs_ref_clk ufs_ref_clk_freqs[] = { {19200000, REF_CLK_FREQ_19_2_MHZ}, {26000000, REF_CLK_FREQ_26_MHZ}, @@ -6881,9 +6946,6 @@ /* UniPro link is active now */ ufshcd_set_link_active(hba); - /* Enable Auto-Hibernate if configured */ - ufshcd_auto_hibern8_enable(hba); - ret = ufshcd_verify_dev_init(hba); if (ret) goto out; @@ -6903,10 +6965,9 @@ } ufs_fixup_device_setup(hba, &card); + ufshcd_tune_unipro_params(hba, &card); ufs_put_device_desc(&card); - ufshcd_tune_unipro_params(hba); - /* UFS device is also active now */ ufshcd_set_ufs_dev_active(hba); ufshcd_force_reset_auto_bkops(hba); @@ -6934,6 +6995,9 @@ /* set the state as operational after switching to desired gear */ hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; + /* Enable Auto-Hibernate if configured */ + ufshcd_auto_hibern8_enable(hba); + /* * If we are in error handling context or in power management callbacks * context, no need to scan the host @@ -6951,7 +7015,8 @@ ufshcd_init_icc_levels(hba); /* Add required well known logical units to scsi mid layer */ - if (ufshcd_scsi_add_wlus(hba)) + ret = ufshcd_scsi_add_wlus(hba); + if (ret) goto out; /* Initialize devfreq after UFS device is detected */ @@ -7950,12 +8015,12 @@ if (hba->clk_scaling.is_allowed) ufshcd_resume_clkscaling(hba); - /* Schedule clock gating in case of no access to UFS device yet */ - ufshcd_release(hba); - /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + /* Schedule clock gating in case of no access to UFS device yet */ + ufshcd_release(hba); + goto out; set_old_link_state: @@ -8149,11 +8214,7 @@ if (ufshcd_is_ufs_dev_poweroff(hba) && ufshcd_is_link_off(hba)) goto out; - if (pm_runtime_suspended(hba->dev)) { - ret = ufshcd_runtime_resume(hba); - if (ret) - goto out; - } + pm_runtime_get_sync(hba->dev); ret = ufshcd_suspend(hba, UFS_SHUTDOWN_PM); out: @@ -8173,6 +8234,9 @@ { ufs_bsg_remove(hba); ufs_sysfs_remove_nodes(hba->dev); + blk_cleanup_queue(hba->tmf_queue); + blk_mq_free_tag_set(&hba->tmf_tag_set); + blk_cleanup_queue(hba->cmd_queue); scsi_remove_host(hba->host); /* disable interrupts */ ufshcd_disable_intr(hba, hba->intr_mask); @@ -8251,6 +8315,18 @@ } EXPORT_SYMBOL(ufshcd_alloc_host); +/* This function exists because blk_mq_alloc_tag_set() requires this. */ +static blk_status_t ufshcd_queue_tmf(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *qd) +{ + WARN_ON_ONCE(true); + return BLK_STS_NOTSUPP; +} + +static const struct blk_mq_ops ufshcd_tmf_ops = { + .queue_rq = ufshcd_queue_tmf, +}; + /** * ufshcd_init - Driver initialization routine * @hba: per-adapter instance @@ -8264,6 +8340,13 @@ struct Scsi_Host *host = hba->host; struct device *dev = hba->dev; + /* + * dev_set_drvdata() must be called before any callbacks are registered + * that use dev_get_drvdata() (frequency scaling, clock scaling, hwmon, + * sysfs). + */ + dev_set_drvdata(dev, hba); + if (!mmio_base) { dev_err(hba->dev, "Invalid memory reference for mmio_base is NULL\n"); @@ -8274,9 +8357,6 @@ hba->mmio_base = mmio_base; hba->irq = irq; - /* Set descriptor lengths to specification defaults */ - ufshcd_def_desc_sizes(hba); - err = ufshcd_hba_init(hba); if (err) goto out_error; @@ -8323,10 +8403,6 @@ hba->max_pwr_info.is_valid = false; - /* Initailize wait queue for task management */ - init_waitqueue_head(&hba->tm_wq); - init_waitqueue_head(&hba->tm_tag_wq); - /* Initialize work queues */ INIT_WORK(&hba->eh_work, ufshcd_err_handler); INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler); @@ -8339,9 +8415,6 @@ init_rwsem(&hba->clk_scaling_lock); - /* Initialize device management tag acquire wait queue */ - init_waitqueue_head(&hba->dev_cmd.tag_wq); - ufshcd_init_clk_gating(hba); ufshcd_init_clk_scaling(hba); @@ -8358,7 +8431,7 @@ * Make sure that UFS interrupts are disabled and any pending interrupt * status is cleared before registering UFS interrupt handler. */ - mb(); + ufshcd_readl(hba, REG_INTERRUPT_ENABLE); /* IRQ registration */ err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); @@ -8375,6 +8448,27 @@ goto exit_gating; } + hba->cmd_queue = blk_mq_init_queue(&hba->host->tag_set); + if (IS_ERR(hba->cmd_queue)) { + err = PTR_ERR(hba->cmd_queue); + goto out_remove_scsi_host; + } + + hba->tmf_tag_set = (struct blk_mq_tag_set) { + .nr_hw_queues = 1, + .queue_depth = hba->nutmrs, + .ops = &ufshcd_tmf_ops, + .flags = BLK_MQ_F_NO_SCHED, + }; + err = blk_mq_alloc_tag_set(&hba->tmf_tag_set); + if (err < 0) + goto free_cmd_queue; + hba->tmf_queue = blk_mq_init_queue(&hba->tmf_tag_set); + if (IS_ERR(hba->tmf_queue)) { + err = PTR_ERR(hba->tmf_queue); + goto free_tmf_tag_set; + } + /* Reset the attached device */ ufshcd_vops_device_reset(hba); @@ -8384,7 +8478,7 @@ dev_err(hba->dev, "Host controller enable failed\n"); ufshcd_print_host_regs(hba); ufshcd_print_host_state(hba); - goto out_remove_scsi_host; + goto free_tmf_queue; } /* @@ -8421,6 +8515,12 @@ return 0; +free_tmf_queue: + blk_cleanup_queue(hba->tmf_queue); +free_tmf_tag_set: + blk_mq_free_tag_set(&hba->tmf_tag_set); +free_cmd_queue: + blk_cleanup_queue(hba->cmd_queue); out_remove_scsi_host: scsi_remove_host(hba->host); exit_gating: @@ -8437,5 +8537,6 @@ MODULE_AUTHOR("Santosh Yaragnavi "); MODULE_AUTHOR("Vinayak Holikatti "); MODULE_DESCRIPTION("Generic UFS host controller driver Core"); +MODULE_SOFTDEP("pre: governor_simpleondemand"); MODULE_LICENSE("GPL"); MODULE_VERSION(UFSHCD_DRIVER_VERSION); --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufshcd.h +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufshcd.h @@ -55,6 +55,7 @@ #include #include #include +#include #include "unipro.h" #include @@ -212,13 +213,11 @@ * @type: device management command type - Query, NOP OUT * @lock: lock to allow one command at a time * @complete: internal commands completion - * @tag_wq: wait queue until free command slot is available */ struct ufs_dev_cmd { enum dev_cmd_type type; struct mutex lock; struct completion *complete; - wait_queue_head_t tag_wq; struct ufs_query query; }; @@ -322,7 +321,7 @@ void (*setup_task_mgmt)(struct ufs_hba *, int, u8); void (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme, enum ufs_notify_change_status); - int (*apply_dev_quirks)(struct ufs_hba *); + int (*apply_dev_quirks)(struct ufs_hba *, struct ufs_dev_desc *); int (*suspend)(struct ufs_hba *, enum ufs_pm_op); int (*resume)(struct ufs_hba *, enum ufs_pm_op); void (*dbg_register_dump)(struct ufs_hba *hba); @@ -483,7 +482,7 @@ * @host: Scsi_Host instance of the driver * @dev: device handle * @lrb: local reference block - * @lrb_in_use: lrb in use + * @cmd_queue: Used to allocate command tags from hba->host->tag_set. * @outstanding_tasks: Bits representing outstanding task requests * @outstanding_reqs: Bits representing outstanding transfer requests * @capabilities: UFS Controller Capabilities @@ -495,11 +494,9 @@ * @irq: Irq number of the controller * @active_uic_cmd: handle of active UIC command * @uic_cmd_mutex: mutex for uic command - * @tm_wq: wait queue for task management - * @tm_tag_wq: wait queue for free task management slots - * @tm_slots_in_use: bit map of task management request slots in use + * @tmf_tag_set: TMF tag set. + * @tmf_queue: Used to allocate TMF tags. * @pwr_done: completion for power mode change - * @tm_condition: condition variable for task management * @ufshcd_state: UFSHCD states * @eh_flags: Error handling flags * @intr_mask: Interrupt Mask Bits @@ -513,6 +510,7 @@ * @uic_error: UFS interconnect layer error status * @saved_err: sticky error mask * @saved_uic_err: sticky UIC error mask + * @silence_err_logs: flag to silence error logs * @dev_cmd: ufs device management command information * @last_dme_cmd_tstamp: time stamp of the last completed DME command * @auto_bkops_enabled: to track whether bkops is enabled in device @@ -541,6 +539,7 @@ struct Scsi_Host *host; struct device *dev; + struct request_queue *cmd_queue; /* * This field is to keep a reference to "scsi_device" corresponding to * "UFS device" W-LU. @@ -561,7 +560,6 @@ u32 ahit; struct ufshcd_lrb *lrb; - unsigned long lrb_in_use; unsigned long outstanding_tasks; unsigned long outstanding_reqs; @@ -643,10 +641,8 @@ /* Device deviations from standard UFS device spec. */ unsigned int dev_quirks; - wait_queue_head_t tm_wq; - wait_queue_head_t tm_tag_wq; - unsigned long tm_condition; - unsigned long tm_slots_in_use; + struct blk_mq_tag_set tmf_tag_set; + struct request_queue *tmf_queue; struct uic_command *active_uic_cmd; struct mutex uic_cmd_mutex; @@ -670,6 +666,7 @@ u32 saved_err; u32 saved_uic_err; struct ufs_stats ufs_stats; + bool silence_err_logs; /* Device management request data */ struct ufs_dev_cmd dev_cmd; @@ -769,6 +766,11 @@ return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT); } +static inline bool ufshcd_is_auto_hibern8_enabled(struct ufs_hba *hba) +{ + return FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, hba->ahit) ? true : false; +} + #define ufshcd_writel(hba, val, reg) \ writel((val), (hba)->mmio_base + (reg)) #define ufshcd_readl(hba, reg) \ @@ -916,6 +918,8 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, enum flag_idn idn, bool *flag_res); +void ufshcd_auto_hibern8_enable(struct ufs_hba *hba); + #define SD_ASCII_STD true #define SD_RAW false int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, @@ -1043,10 +1047,11 @@ return hba->vops->hibern8_notify(hba, cmd, status); } -static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba) +static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba, + struct ufs_dev_desc *card) { if (hba->vops && hba->vops->apply_dev_quirks) - return hba->vops->apply_dev_quirks(hba); + return hba->vops->apply_dev_quirks(hba, card); return 0; } --- linux-oracle-5.4.0.orig/drivers/scsi/ufs/ufshci.h +++ linux-oracle-5.4.0/drivers/scsi/ufs/ufshci.h @@ -195,7 +195,7 @@ /* UECDL - Host UIC Error Code Data Link Layer 3Ch */ #define UIC_DATA_LINK_LAYER_ERROR 0x80000000 -#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0x7FFF +#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0xFFFF #define UIC_DATA_LINK_LAYER_ERROR_TCX_REP_TIMER_EXP 0x2 #define UIC_DATA_LINK_LAYER_ERROR_AFCX_REQ_TIMER_EXP 0x4 #define UIC_DATA_LINK_LAYER_ERROR_FCX_PRO_TIMER_EXP 0x8 --- linux-oracle-5.4.0.orig/drivers/scsi/virtio_scsi.c +++ linux-oracle-5.4.0/drivers/scsi/virtio_scsi.c @@ -297,7 +297,7 @@ } break; default: - pr_info("Unsupport virtio scsi event reason %x\n", event->reason); + pr_info("Unsupported virtio scsi event reason %x\n", event->reason); } } @@ -381,7 +381,7 @@ virtscsi_handle_param_change(vscsi, event); break; default: - pr_err("Unsupport virtio scsi event %x\n", event->event); + pr_err("Unsupported virtio scsi event %x\n", event->event); } virtscsi_kick_event(vscsi, event_node); } --- linux-oracle-5.4.0.orig/drivers/scsi/vmw_pvscsi.c +++ linux-oracle-5.4.0/drivers/scsi/vmw_pvscsi.c @@ -574,7 +574,16 @@ case BTSTAT_SUCCESS: case BTSTAT_LINKED_COMMAND_COMPLETED: case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG: - /* If everything went fine, let's move on.. */ + /* + * Commands like INQUIRY may transfer less data than + * requested by the initiator via bufflen. Set residual + * count to make upper layer aware of the actual amount + * of data returned. There are cases when controller + * returns zero dataLen with non zero data - do not set + * residual count in that case. + */ + if (e->dataLen && (e->dataLen < scsi_bufflen(cmd))) + scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen); cmd->result = (DID_OK << 16); break; --- linux-oracle-5.4.0.orig/drivers/scsi/vmw_pvscsi.h +++ linux-oracle-5.4.0/drivers/scsi/vmw_pvscsi.h @@ -333,8 +333,8 @@ u8 tag; u8 bus; u8 target; - u8 vcpuHint; - u8 unused[59]; + u16 vcpuHint; + u8 unused[58]; } __packed; /* --- linux-oracle-5.4.0.orig/drivers/scsi/xen-scsifront.c +++ linux-oracle-5.4.0/drivers/scsi/xen-scsifront.c @@ -233,12 +233,11 @@ return; for (i = 0; i < shadow->nr_grants; i++) { - if (unlikely(gnttab_query_foreign_access(shadow->gref[i]))) { + if (unlikely(!gnttab_try_end_foreign_access(shadow->gref[i]))) { shost_printk(KERN_ALERT, info->host, KBUILD_MODNAME "grant still in use by backend\n"); BUG(); } - gnttab_end_foreign_access(shadow->gref[i], 0, 0UL); } kfree(shadow->sg); --- linux-oracle-5.4.0.orig/drivers/scsi/zorro7xx.c +++ linux-oracle-5.4.0/drivers/scsi/zorro7xx.c @@ -159,6 +159,8 @@ scsi_remove_host(host); NCR_700_release(host); + if (host->base > 0x01000000) + iounmap(hostdata->base); kfree(hostdata); free_irq(host->irq, host); zorro_release_device(z); --- linux-oracle-5.4.0.orig/drivers/scsi/zorro_esp.c +++ linux-oracle-5.4.0/drivers/scsi/zorro_esp.c @@ -218,7 +218,14 @@ static u32 zorro_esp_dma_length_limit(struct esp *esp, u32 dma_addr, u32 dma_len) { - return dma_len > 0xFFFF ? 0xFFFF : dma_len; + return dma_len > (1U << 16) ? (1U << 16) : dma_len; +} + +static u32 fastlane_esp_dma_length_limit(struct esp *esp, u32 dma_addr, + u32 dma_len) +{ + /* The old driver used 0xfffc as limit, so do that here too */ + return dma_len > 0xfffc ? 0xfffc : dma_len; } static void zorro_esp_reset_dma(struct esp *esp) @@ -604,7 +611,7 @@ .esp_write8 = zorro_esp_write8, .esp_read8 = zorro_esp_read8, .irq_pending = fastlane_esp_irq_pending, - .dma_length_limit = zorro_esp_dma_length_limit, + .dma_length_limit = fastlane_esp_dma_length_limit, .reset_dma = zorro_esp_reset_dma, .dma_drain = zorro_esp_dma_drain, .dma_invalidate = fastlane_esp_dma_invalidate, --- linux-oracle-5.4.0.orig/drivers/sh/clk/core.c +++ linux-oracle-5.4.0/drivers/sh/clk/core.c @@ -295,7 +295,7 @@ int ret; if (!clk) - return -EINVAL; + return 0; spin_lock_irqsave(&clock_lock, flags); ret = __clk_enable(clk); --- linux-oracle-5.4.0.orig/drivers/sh/intc/core.c +++ linux-oracle-5.4.0/drivers/sh/intc/core.c @@ -194,7 +194,6 @@ goto err0; INIT_LIST_HEAD(&d->list); - list_add_tail(&d->list, &intc_list); raw_spin_lock_init(&d->lock); INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); @@ -380,6 +379,7 @@ d->skip_suspend = desc->skip_syscore_suspend; + list_add_tail(&d->list, &intc_list); nr_intc_controllers++; return 0; --- linux-oracle-5.4.0.orig/drivers/sh/maple/maple.c +++ linux-oracle-5.4.0/drivers/sh/maple/maple.c @@ -835,8 +835,10 @@ maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN); - if (!maple_queue_cache) + if (!maple_queue_cache) { + retval = -ENOMEM; goto cleanup_bothirqs; + } INIT_LIST_HEAD(&maple_waitq); INIT_LIST_HEAD(&maple_sentq); @@ -849,6 +851,7 @@ if (!mdev[i]) { while (i-- > 0) maple_free_dev(mdev[i]); + retval = -ENOMEM; goto cleanup_cache; } baseunits[i] = mdev[i]; --- linux-oracle-5.4.0.orig/drivers/siox/siox-core.c +++ linux-oracle-5.4.0/drivers/siox/siox-core.c @@ -835,6 +835,8 @@ err_device_register: /* don't care to make the buffer smaller again */ + put_device(&sdevice->dev); + sdevice = NULL; err_buf_alloc: siox_master_unlock(smaster); --- linux-oracle-5.4.0.orig/drivers/slimbus/core.c +++ linux-oracle-5.4.0/drivers/slimbus/core.c @@ -283,6 +283,7 @@ /* slim_remove_device: Remove the effect of slim_add_device() */ static void slim_remove_device(struct slim_device *sbdev) { + of_node_put(sbdev->dev.of_node); device_unregister(&sbdev->dev); } @@ -301,8 +302,6 @@ { /* Remove all clients */ device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device); - /* Enter Clock Pause */ - slim_ctrl_clk_pause(ctrl, false, 0); ida_simple_remove(&ctrl_ida, ctrl->id); return 0; @@ -326,8 +325,8 @@ mutex_lock(&ctrl->lock); sbdev->is_laddr_valid = false; mutex_unlock(&ctrl->lock); - - ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr); + if (!ctrl->get_laddr) + ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr); slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN); } EXPORT_SYMBOL_GPL(slim_report_absent); @@ -440,8 +439,8 @@ if (ret < 0) goto err; } else if (report_present) { - ret = ida_simple_get(&ctrl->laddr_ida, - 0, SLIM_LA_MANAGER - 1, GFP_KERNEL); + ret = ida_alloc_max(&ctrl->laddr_ida, + SLIM_LA_MANAGER - 1, GFP_KERNEL); if (ret < 0) goto err; --- linux-oracle-5.4.0.orig/drivers/slimbus/messaging.c +++ linux-oracle-5.4.0/drivers/slimbus/messaging.c @@ -66,7 +66,7 @@ int ret = 0; spin_lock_irqsave(&ctrl->txn_lock, flags); - ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 0, + ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 1, SLIM_MAX_TIDS, GFP_ATOMIC); if (ret < 0) { spin_unlock_irqrestore(&ctrl->txn_lock, flags); @@ -131,7 +131,8 @@ goto slim_xfer_err; } } - + /* Initialize tid to invalid value */ + txn->tid = 0; need_tid = slim_tid_txn(txn->mt, txn->mc); if (need_tid) { @@ -146,8 +147,9 @@ } ret = ctrl->xfer_msg(ctrl, txn); - - if (!ret && need_tid && !txn->msg->comp) { + if (ret == -ETIMEDOUT) { + slim_free_txn_tid(ctrl, txn); + } else if (!ret && need_tid && !txn->msg->comp) { unsigned long ms = txn->rl + HZ; timeout = wait_for_completion_timeout(txn->comp, @@ -163,7 +165,7 @@ txn->mt, txn->mc, txn->la, ret); slim_xfer_err: - if (!clk_pause_msg && (!need_tid || ret == -ETIMEDOUT)) { + if (!clk_pause_msg && (txn->tid == 0 || ret == -ETIMEDOUT)) { /* * remove runtime-pm vote if this was TX only, or * if there was error during this transaction --- linux-oracle-5.4.0.orig/drivers/slimbus/qcom-ctrl.c +++ linux-oracle-5.4.0/drivers/slimbus/qcom-ctrl.c @@ -515,9 +515,9 @@ } ctrl->irq = platform_get_irq(pdev, 0); - if (!ctrl->irq) { + if (ctrl->irq < 0) { dev_err(&pdev->dev, "no slimbus IRQ\n"); - return -ENODEV; + return ctrl->irq; } sctrl = &ctrl->ctrl; --- linux-oracle-5.4.0.orig/drivers/slimbus/qcom-ngd-ctrl.c +++ linux-oracle-5.4.0/drivers/slimbus/qcom-ngd-ctrl.c @@ -1061,7 +1061,8 @@ { u32 cfg = readl_relaxed(ctrl->ngd->base); - if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) + if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN || + ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP) qcom_slim_ngd_init_dma(ctrl); /* By default enable message queues */ @@ -1112,6 +1113,7 @@ dev_info(ctrl->dev, "Subsys restart: ADSP active framer\n"); return 0; } + qcom_slim_ngd_setup(ctrl); return 0; } @@ -1201,6 +1203,9 @@ struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev); int ret = 0; + if (!ctrl->qmi.handle) + return 0; + if (ctrl->state >= QCOM_SLIM_NGD_CTRL_ASLEEP) ret = qcom_slim_ngd_power_up(ctrl); if (ret) { @@ -1273,9 +1278,13 @@ { struct qcom_slim_ngd_qmi *qmi = container_of(hdl, struct qcom_slim_ngd_qmi, svc_event_hdl); + struct qcom_slim_ngd_ctrl *ctrl = + container_of(qmi, struct qcom_slim_ngd_ctrl, qmi); qmi->svc_info.sq_node = 0; qmi->svc_info.sq_port = 0; + + qcom_slim_ngd_enable(ctrl, false); } static struct qmi_ops qcom_slim_ngd_qmi_svc_event_ops = { @@ -1354,7 +1363,6 @@ ngd->pdev->driver_override = QCOM_SLIM_NGD_DRV_NAME; ngd->pdev->dev.of_node = node; ctrl->ngd = ngd; - platform_set_drvdata(ngd->pdev, ctrl); platform_device_add(ngd->pdev); ngd->base = ctrl->base + ngd->id * data->offset + @@ -1369,12 +1377,13 @@ static int qcom_slim_ngd_probe(struct platform_device *pdev) { - struct qcom_slim_ngd_ctrl *ctrl = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; + struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev->parent); int ret; ctrl->ctrl.dev = dev; + platform_set_drvdata(pdev, ctrl); pm_runtime_use_autosuspend(dev); pm_runtime_set_autosuspend_delay(dev, QCOM_SLIM_NGD_AUTOSUSPEND); pm_runtime_set_suspended(dev); @@ -1493,6 +1502,10 @@ struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev); int ret = 0; + qcom_slim_ngd_exit_dma(ctrl); + if (!ctrl->qmi.handle) + return 0; + ret = qcom_slim_qmi_power_request(ctrl, false); if (ret && ret != -EBUSY) dev_info(ctrl->dev, "slim resource not idle:%d\n", ret); --- linux-oracle-5.4.0.orig/drivers/slimbus/stream.c +++ linux-oracle-5.4.0/drivers/slimbus/stream.c @@ -67,10 +67,10 @@ 384000, 768000, 0, /* Reserved */ - 110250, - 220500, - 441000, - 882000, + 11025, + 22050, + 44100, + 88200, 176400, 352800, 705600, --- linux-oracle-5.4.0.orig/drivers/soc/amlogic/meson-canvas.c +++ linux-oracle-5.4.0/drivers/soc/amlogic/meson-canvas.c @@ -72,8 +72,10 @@ * current state, this driver probe cannot return -EPROBE_DEFER */ canvas = dev_get_drvdata(&canvas_pdev->dev); - if (!canvas) + if (!canvas) { + put_device(&canvas_pdev->dev); return ERR_PTR(-EINVAL); + } return canvas; } --- linux-oracle-5.4.0.orig/drivers/soc/amlogic/meson-ee-pwrc.c +++ linux-oracle-5.4.0/drivers/soc/amlogic/meson-ee-pwrc.c @@ -323,6 +323,8 @@ struct meson_ee_pwrc *pwrc, struct meson_ee_pwrc_domain *dom) { + int ret; + dom->pwrc = pwrc; dom->num_rstc = dom->desc.reset_names_count; dom->num_clks = dom->desc.clk_names_count; @@ -368,15 +370,21 @@ * prepare/enable counters won't be in sync. */ if (dom->num_clks && dom->desc.get_power && !dom->desc.get_power(dom)) { - int ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks); + ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks); if (ret) return ret; - pm_genpd_init(&dom->base, &pm_domain_always_on_gov, false); - } else - pm_genpd_init(&dom->base, NULL, - (dom->desc.get_power ? - dom->desc.get_power(dom) : true)); + ret = pm_genpd_init(&dom->base, &pm_domain_always_on_gov, + false); + if (ret) + return ret; + } else { + ret = pm_genpd_init(&dom->base, NULL, + (dom->desc.get_power ? + dom->desc.get_power(dom) : true)); + if (ret) + return ret; + } return 0; } @@ -441,9 +449,7 @@ pwrc->xlate.domains[i] = &dom->base; } - of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate); - - return 0; + return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate); } static void meson_ee_pwrc_shutdown(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/soc/amlogic/meson-mx-socinfo.c +++ linux-oracle-5.4.0/drivers/soc/amlogic/meson-mx-socinfo.c @@ -126,6 +126,7 @@ np = of_find_matching_node(NULL, meson_mx_socinfo_analog_top_ids); if (np) { analog_top_regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(analog_top_regmap)) return PTR_ERR(analog_top_regmap); --- linux-oracle-5.4.0.orig/drivers/soc/aspeed/aspeed-lpc-ctrl.c +++ linux-oracle-5.4.0/drivers/soc/aspeed/aspeed-lpc-ctrl.c @@ -46,7 +46,7 @@ unsigned long vsize = vma->vm_end - vma->vm_start; pgprot_t prot = vma->vm_page_prot; - if (vma->vm_pgoff + vsize > lpc_ctrl->mem_base + lpc_ctrl->mem_size) + if (vma->vm_pgoff + vma_pages(vma) > lpc_ctrl->mem_size >> PAGE_SHIFT) return -EINVAL; /* ast2400/2500 AHB accesses are not cache coherent */ --- linux-oracle-5.4.0.orig/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ linux-oracle-5.4.0/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -67,6 +68,7 @@ struct aspeed_lpc_snoop { struct regmap *regmap; int irq; + struct clk *clk; struct aspeed_lpc_snoop_channel chan[NUM_SNOOP_CHANNELS]; }; @@ -93,17 +95,19 @@ return -EINTR; } ret = kfifo_to_user(&chan->fifo, buffer, count, &copied); + if (ret) + return ret; - return ret ? ret : copied; + return copied; } -static unsigned int snoop_file_poll(struct file *file, +static __poll_t snoop_file_poll(struct file *file, struct poll_table_struct *pt) { struct aspeed_lpc_snoop_channel *chan = snoop_file_to_chan(file); poll_wait(file, &chan->wq, pt); - return !kfifo_is_empty(&chan->fifo) ? POLLIN : 0; + return !kfifo_is_empty(&chan->fifo) ? EPOLLIN : 0; } static const struct file_operations snoop_fops = { @@ -282,22 +286,42 @@ return -ENODEV; } + lpc_snoop->clk = devm_clk_get(dev, NULL); + if (IS_ERR(lpc_snoop->clk)) { + rc = PTR_ERR(lpc_snoop->clk); + if (rc != -EPROBE_DEFER) + dev_err(dev, "couldn't get clock\n"); + return rc; + } + rc = clk_prepare_enable(lpc_snoop->clk); + if (rc) { + dev_err(dev, "couldn't enable clock\n"); + return rc; + } + rc = aspeed_lpc_snoop_config_irq(lpc_snoop, pdev); if (rc) - return rc; + goto err; rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 0, port); if (rc) - return rc; + goto err; /* Configuration of 2nd snoop channel port is optional */ if (of_property_read_u32_index(dev->of_node, "snoop-ports", 1, &port) == 0) { rc = aspeed_lpc_enable_snoop(lpc_snoop, dev, 1, port); - if (rc) + if (rc) { aspeed_lpc_disable_snoop(lpc_snoop, 0); + goto err; + } } + return 0; + +err: + clk_disable_unprepare(lpc_snoop->clk); + return rc; } @@ -309,6 +333,8 @@ aspeed_lpc_disable_snoop(lpc_snoop, 0); aspeed_lpc_disable_snoop(lpc_snoop, 1); + clk_disable_unprepare(lpc_snoop->clk); + return 0; } --- linux-oracle-5.4.0.orig/drivers/soc/aspeed/aspeed-p2a-ctrl.c +++ linux-oracle-5.4.0/drivers/soc/aspeed/aspeed-p2a-ctrl.c @@ -110,7 +110,7 @@ vsize = vma->vm_end - vma->vm_start; prot = vma->vm_page_prot; - if (vma->vm_pgoff + vsize > ctrl->mem_base + ctrl->mem_size) + if (vma->vm_pgoff + vma_pages(vma) > ctrl->mem_size >> PAGE_SHIFT) return -EINVAL; /* ast2400/2500 AHB accesses are not cache coherent */ --- linux-oracle-5.4.0.orig/drivers/soc/atmel/soc.c +++ linux-oracle-5.4.0/drivers/soc/atmel/soc.c @@ -264,8 +264,21 @@ return soc_dev; } +static const struct of_device_id at91_soc_allowed_list[] __initconst = { + { .compatible = "atmel,at91rm9200", }, + { .compatible = "atmel,at91sam9", }, + { .compatible = "atmel,sama5", }, + { .compatible = "atmel,samv7", }, + { } +}; + static int __init atmel_soc_device_init(void) { + struct device_node *np = of_find_node_by_path("/"); + + if (!of_match_node(at91_soc_allowed_list, np)) + return 0; + at91_soc_init(socs); return 0; --- linux-oracle-5.4.0.orig/drivers/soc/bcm/brcmstb/pm/pm-arm.c +++ linux-oracle-5.4.0/drivers/soc/bcm/brcmstb/pm/pm-arm.c @@ -681,13 +681,14 @@ const struct of_device_id *of_id = NULL; struct device_node *dn; void __iomem *base; - int ret, i; + int ret, i, s; /* AON ctrl registers */ base = brcmstb_ioremap_match(aon_ctrl_dt_ids, 0, NULL); if (IS_ERR(base)) { pr_err("error mapping AON_CTRL\n"); - return PTR_ERR(base); + ret = PTR_ERR(base); + goto aon_err; } ctrl.aon_ctrl_base = base; @@ -697,8 +698,10 @@ /* Assume standard offset */ ctrl.aon_sram = ctrl.aon_ctrl_base + AON_CTRL_SYSTEM_DATA_RAM_OFS; + s = 0; } else { ctrl.aon_sram = base; + s = 1; } writel_relaxed(0, ctrl.aon_sram + AON_REG_PANIC); @@ -708,7 +711,8 @@ (const void **)&ddr_phy_data); if (IS_ERR(base)) { pr_err("error mapping DDR PHY\n"); - return PTR_ERR(base); + ret = PTR_ERR(base); + goto ddr_phy_err; } ctrl.support_warm_boot = ddr_phy_data->supports_warm_boot; ctrl.pll_status_offset = ddr_phy_data->pll_status_offset; @@ -728,17 +732,20 @@ for_each_matching_node(dn, ddr_shimphy_dt_ids) { i = ctrl.num_memc; if (i >= MAX_NUM_MEMC) { + of_node_put(dn); pr_warn("too many MEMCs (max %d)\n", MAX_NUM_MEMC); break; } base = of_io_request_and_map(dn, 0, dn->full_name); if (IS_ERR(base)) { + of_node_put(dn); if (!ctrl.support_warm_boot) break; pr_err("error mapping DDR SHIMPHY %d\n", i); - return PTR_ERR(base); + ret = PTR_ERR(base); + goto ddr_shimphy_err; } ctrl.memcs[i].ddr_shimphy_base = base; ctrl.num_memc++; @@ -749,14 +756,18 @@ for_each_matching_node(dn, brcmstb_memc_of_match) { base = of_iomap(dn, 0); if (!base) { + of_node_put(dn); pr_err("error mapping DDR Sequencer %d\n", i); - return -ENOMEM; + ret = -ENOMEM; + goto brcmstb_memc_err; } of_id = of_match_node(brcmstb_memc_of_match, dn); if (!of_id) { iounmap(base); - return -EINVAL; + of_node_put(dn); + ret = -EINVAL; + goto brcmstb_memc_err; } ddr_seq_data = of_id->data; @@ -776,20 +787,24 @@ dn = of_find_matching_node(NULL, sram_dt_ids); if (!dn) { pr_err("SRAM not found\n"); - return -EINVAL; + ret = -EINVAL; + goto brcmstb_memc_err; } ret = brcmstb_init_sram(dn); + of_node_put(dn); if (ret) { pr_err("error setting up SRAM for PM\n"); - return ret; + goto brcmstb_memc_err; } ctrl.pdev = pdev; ctrl.s3_params = kmalloc(sizeof(*ctrl.s3_params), GFP_KERNEL); - if (!ctrl.s3_params) - return -ENOMEM; + if (!ctrl.s3_params) { + ret = -ENOMEM; + goto s3_params_err; + } ctrl.s3_params_pa = dma_map_single(&pdev->dev, ctrl.s3_params, sizeof(*ctrl.s3_params), DMA_TO_DEVICE); @@ -809,7 +824,21 @@ out: kfree(ctrl.s3_params); - +s3_params_err: + iounmap(ctrl.boot_sram); +brcmstb_memc_err: + for (i--; i >= 0; i--) + iounmap(ctrl.memcs[i].ddr_ctrl); +ddr_shimphy_err: + for (i = 0; i < ctrl.num_memc; i++) + iounmap(ctrl.memcs[i].ddr_shimphy_base); + + iounmap(ctrl.memcs[0].ddr_phy_base); +ddr_phy_err: + iounmap(ctrl.aon_ctrl_base); + if (s) + iounmap(ctrl.aon_sram); +aon_err: pr_warn("PM: initialization failed with code %d\n", ret); return ret; --- linux-oracle-5.4.0.orig/drivers/soc/fsl/Kconfig +++ linux-oracle-5.4.0/drivers/soc/fsl/Kconfig @@ -24,6 +24,7 @@ tristate "QorIQ DPAA2 DPIO driver" depends on FSL_MC_BUS select SOC_BUS + select FSL_GUTS help Driver for the DPAA2 DPIO object. A DPIO provides queue and buffer management facilities for software to interact with --- linux-oracle-5.4.0.orig/drivers/soc/fsl/dpaa2-console.c +++ linux-oracle-5.4.0/drivers/soc/fsl/dpaa2-console.c @@ -231,6 +231,7 @@ cd->cur_ptr += bytes; written += bytes; + kfree(kbuf); return written; err_free_buf: --- linux-oracle-5.4.0.orig/drivers/soc/fsl/dpio/dpio-driver.c +++ linux-oracle-5.4.0/drivers/soc/fsl/dpio/dpio-driver.c @@ -95,7 +95,6 @@ { int error; struct fsl_mc_device_irq *irq; - cpumask_t mask; irq = dpio_dev->irqs[0]; error = devm_request_irq(&dpio_dev->dev, @@ -112,9 +111,7 @@ } /* set the affinity hint */ - cpumask_clear(&mask); - cpumask_set_cpu(cpu, &mask); - if (irq_set_affinity_hint(irq->msi_desc->irq, &mask)) + if (irq_set_affinity_hint(irq->msi_desc->irq, cpumask_of(cpu))) dev_err(&dpio_dev->dev, "irq_set_affinity failed irq %d cpu %d\n", irq->msi_desc->irq, cpu); @@ -233,10 +230,6 @@ goto err_allocate_irqs; } - err = register_dpio_irq_handlers(dpio_dev, desc.cpu); - if (err) - goto err_register_dpio_irq; - priv->io = dpaa2_io_create(&desc, dev); if (!priv->io) { dev_err(dev, "dpaa2_io_create failed\n"); @@ -244,6 +237,10 @@ goto err_dpaa2_io_create; } + err = register_dpio_irq_handlers(dpio_dev, desc.cpu); + if (err) + goto err_register_dpio_irq; + dev_info(dev, "probed\n"); dev_dbg(dev, " receives_notifications = %d\n", desc.receives_notifications); --- linux-oracle-5.4.0.orig/drivers/soc/fsl/guts.c +++ linux-oracle-5.4.0/drivers/soc/fsl/guts.c @@ -142,7 +142,7 @@ struct device *dev = &pdev->dev; struct resource *res; const struct fsl_soc_die_attr *soc_die; - const char *machine; + const char *machine = NULL; u32 svr; /* Initialize guts */ --- linux-oracle-5.4.0.orig/drivers/soc/fsl/qbman/bman.c +++ linux-oracle-5.4.0/drivers/soc/fsl/qbman/bman.c @@ -660,7 +660,7 @@ } done: put_affine_portal(); - return 0; + return err; } struct gen_pool *bm_bpalloc; --- linux-oracle-5.4.0.orig/drivers/soc/fsl/qbman/qman.c +++ linux-oracle-5.4.0/drivers/soc/fsl/qbman/qman.c @@ -186,7 +186,7 @@ __be32 tag; struct qm_fd fd; u8 __reserved3[32]; -} __packed; +} __packed __aligned(8); #define QM_EQCR_VERB_VBIT 0x80 #define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */ #define QM_EQCR_VERB_CMD_ENQUEUE 0x01 @@ -996,7 +996,7 @@ /* linked-list of CSCN handlers. */ struct list_head cgr_cbs; /* list lock */ - spinlock_t cgr_lock; + raw_spinlock_t cgr_lock; struct work_struct congestion_work; struct work_struct mr_work; char irqname[MAX_IRQNAME]; @@ -1286,7 +1286,7 @@ /* if the given mask is NULL, assume all CGRs can be seen */ qman_cgrs_fill(&portal->cgrs[0]); INIT_LIST_HEAD(&portal->cgr_cbs); - spin_lock_init(&portal->cgr_lock); + raw_spin_lock_init(&portal->cgr_lock); INIT_WORK(&portal->congestion_work, qm_congestion_task); INIT_WORK(&portal->mr_work, qm_mr_process_task); portal->bits = 0; @@ -1461,11 +1461,14 @@ union qm_mc_result *mcr; struct qman_cgr *cgr; - spin_lock(&p->cgr_lock); + /* + * FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock! + */ + raw_spin_lock_irq(&p->cgr_lock); qm_mc_start(&p->p); qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION); if (!qm_mc_result_timeout(&p->p, &mcr)) { - spin_unlock(&p->cgr_lock); + raw_spin_unlock_irq(&p->cgr_lock); dev_crit(p->config->dev, "QUERYCONGESTION timeout\n"); qman_p_irqsource_add(p, QM_PIRQ_CSCI); return; @@ -1481,7 +1484,7 @@ list_for_each_entry(cgr, &p->cgr_cbs, node) if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid)) cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid)); - spin_unlock(&p->cgr_lock); + raw_spin_unlock_irq(&p->cgr_lock); qman_p_irqsource_add(p, QM_PIRQ_CSCI); } @@ -2438,7 +2441,7 @@ preempt_enable(); cgr->chan = p->config->channel; - spin_lock(&p->cgr_lock); + raw_spin_lock_irq(&p->cgr_lock); if (opts) { struct qm_mcc_initcgr local_opts = *opts; @@ -2475,19 +2478,14 @@ qman_cgrs_get(&p->cgrs[1], cgr->cgrid)) cgr->cb(p, cgr, 1); out: - spin_unlock(&p->cgr_lock); + raw_spin_unlock_irq(&p->cgr_lock); put_affine_portal(); return ret; } EXPORT_SYMBOL(qman_create_cgr); -int qman_delete_cgr(struct qman_cgr *cgr) +static struct qman_portal *qman_cgr_get_affine_portal(struct qman_cgr *cgr) { - unsigned long irqflags; - struct qm_mcr_querycgr cgr_state; - struct qm_mcc_initcgr local_opts; - int ret = 0; - struct qman_cgr *i; struct qman_portal *p = get_affine_portal(); if (cgr->chan != p->config->channel) { @@ -2495,12 +2493,27 @@ dev_err(p->config->dev, "CGR not owned by current portal"); dev_dbg(p->config->dev, " create 0x%x, delete 0x%x\n", cgr->chan, p->config->channel); - - ret = -EINVAL; - goto put_portal; + put_affine_portal(); + return NULL; } + + return p; +} + +int qman_delete_cgr(struct qman_cgr *cgr) +{ + unsigned long irqflags; + struct qm_mcr_querycgr cgr_state; + struct qm_mcc_initcgr local_opts; + int ret = 0; + struct qman_cgr *i; + struct qman_portal *p = qman_cgr_get_affine_portal(cgr); + + if (!p) + return -EINVAL; + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr)); - spin_lock_irqsave(&p->cgr_lock, irqflags); + raw_spin_lock_irqsave(&p->cgr_lock, irqflags); list_del(&cgr->node); /* * If there are no other CGR objects for this CGRID in the list, @@ -2525,8 +2538,7 @@ /* add back to the list */ list_add(&cgr->node, &p->cgr_cbs); release_lock: - spin_unlock_irqrestore(&p->cgr_lock, irqflags); -put_portal: + raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags); put_affine_portal(); return ret; } @@ -2557,6 +2569,54 @@ } EXPORT_SYMBOL(qman_delete_cgr_safe); +static int qman_update_cgr(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts) +{ + int ret; + unsigned long irqflags; + struct qman_portal *p = qman_cgr_get_affine_portal(cgr); + + if (!p) + return -EINVAL; + + raw_spin_lock_irqsave(&p->cgr_lock, irqflags); + ret = qm_modify_cgr(cgr, 0, opts); + raw_spin_unlock_irqrestore(&p->cgr_lock, irqflags); + put_affine_portal(); + return ret; +} + +struct update_cgr_params { + struct qman_cgr *cgr; + struct qm_mcc_initcgr *opts; + int ret; +}; + +static void qman_update_cgr_smp_call(void *p) +{ + struct update_cgr_params *params = p; + + params->ret = qman_update_cgr(params->cgr, params->opts); +} + +int qman_update_cgr_safe(struct qman_cgr *cgr, struct qm_mcc_initcgr *opts) +{ + struct update_cgr_params params = { + .cgr = cgr, + .opts = opts, + }; + + preempt_disable(); + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) + smp_call_function_single(qman_cgr_cpus[cgr->cgrid], + qman_update_cgr_smp_call, ¶ms, + true); + else + params.ret = qman_update_cgr(cgr, opts); + preempt_enable(); + return params.ret; +} +EXPORT_SYMBOL(qman_update_cgr_safe); + /* Cleanup FQs */ static int _qm_mr_consume_and_match_verb(struct qm_portal *p, int v) --- linux-oracle-5.4.0.orig/drivers/soc/fsl/qe/Kconfig +++ linux-oracle-5.4.0/drivers/soc/fsl/qe/Kconfig @@ -38,6 +38,7 @@ config QE_USB bool + depends on QUICC_ENGINE default y if USB_FSL_QE help QE USB Controller support --- linux-oracle-5.4.0.orig/drivers/soc/fsl/qe/qe_io.c +++ linux-oracle-5.4.0/drivers/soc/fsl/qe/qe_io.c @@ -37,6 +37,8 @@ if (ret) return ret; par_io = ioremap(res.start, resource_size(&res)); + if (!par_io) + return -ENOMEM; num_ports = of_get_property(np, "num-ports", NULL); if (num_ports) --- linux-oracle-5.4.0.orig/drivers/soc/imx/gpc.c +++ linux-oracle-5.4.0/drivers/soc/imx/gpc.c @@ -87,8 +87,8 @@ static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd) { struct imx_pm_domain *pd = to_imx_pm_domain(genpd); - int i, ret, sw, sw2iso; - u32 val; + int i, ret; + u32 val, req; if (pd->supply) { ret = regulator_enable(pd->supply); @@ -107,17 +107,18 @@ regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS, 0x1, 0x1); - /* Read ISO and ISO2SW power up delays */ - regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val); - sw = val & 0x3f; - sw2iso = (val >> 8) & 0x3f; - /* Request GPC to power up domain */ - val = BIT(pd->cntr_pdn_bit + 1); - regmap_update_bits(pd->regmap, GPC_CNTR, val, val); + req = BIT(pd->cntr_pdn_bit + 1); + regmap_update_bits(pd->regmap, GPC_CNTR, req, req); + + /* Wait for the PGC to handle the request */ + ret = regmap_read_poll_timeout(pd->regmap, GPC_CNTR, val, !(val & req), + 1, 50); + if (ret) + pr_err("powerup request on domain %s timed out\n", genpd->name); - /* Wait ISO + ISO2SW IPG clock cycles */ - udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz)); + /* Wait for reset to propagate through peripherals */ + usleep_range(5, 10); /* Disable reset clocks for all devices in the domain */ for (i = 0; i < pd->num_clks; i++) @@ -343,6 +344,7 @@ .rd_table = &access_table, .wr_table = &access_table, .max_register = 0x2ac, + .fast_io = true, }; static struct generic_pm_domain *imx_gpc_onecell_domains[] = { --- linux-oracle-5.4.0.orig/drivers/soc/imx/soc-imx-scu.c +++ linux-oracle-5.4.0/drivers/soc/imx/soc-imx-scu.c @@ -25,7 +25,7 @@ u32 id; } resp; } data; -} __packed; +} __packed __aligned(4); struct imx_sc_msg_misc_get_soc_uid { struct imx_sc_rpc_msg hdr; --- linux-oracle-5.4.0.orig/drivers/soc/ixp4xx/ixp4xx-npe.c +++ linux-oracle-5.4.0/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -690,8 +690,8 @@ if (!(ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_RESET_NPEA << i))) { - dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR not available\n", + i, res); continue; /* NPE already disabled or not present */ } npe->regs = devm_ioremap_resource(dev, res); @@ -699,13 +699,12 @@ return PTR_ERR(npe->regs); if (npe_reset(npe)) { - dev_info(dev, "NPE%d at 0x%08x-0x%08x does not reset\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR does not reset\n", + i, res); continue; } npe->valid = 1; - dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR registered\n", i, res); found++; } @@ -736,7 +735,7 @@ static struct platform_driver ixp4xx_npe_driver = { .driver = { .name = "ixp4xx-npe", - .of_match_table = of_match_ptr(ixp4xx_npe_of_match), + .of_match_table = ixp4xx_npe_of_match, }, .probe = ixp4xx_npe_probe, .remove = ixp4xx_npe_remove, --- linux-oracle-5.4.0.orig/drivers/soc/ixp4xx/ixp4xx-qmgr.c +++ linux-oracle-5.4.0/drivers/soc/ixp4xx/ixp4xx-qmgr.c @@ -145,12 +145,12 @@ /* ACK - it may clear any bits so don't rely on it */ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]); - en_bitmap = qmgr_regs->irqen[0]; + en_bitmap = __raw_readl(&qmgr_regs->irqen[0]); while (en_bitmap) { i = __fls(en_bitmap); /* number of the last "low" queue */ en_bitmap &= ~BIT(i); - src = qmgr_regs->irqsrc[i >> 3]; - stat = qmgr_regs->stat1[i >> 3]; + src = __raw_readl(&qmgr_regs->irqsrc[i >> 3]); + stat = __raw_readl(&qmgr_regs->stat1[i >> 3]); if (src & 4) /* the IRQ condition is inverted */ stat = ~stat; if (stat & BIT(src & 3)) { @@ -170,7 +170,8 @@ /* ACK - it may clear any bits so don't rely on it */ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]); - req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h; + req_bitmap = __raw_readl(&qmgr_regs->irqen[1]) & + __raw_readl(&qmgr_regs->statne_h); while (req_bitmap) { i = __fls(req_bitmap); /* number of the last "high" queue */ req_bitmap &= ~BIT(i); --- linux-oracle-5.4.0.orig/drivers/soc/mediatek/mtk-cmdq-helper.c +++ linux-oracle-5.4.0/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -38,6 +38,7 @@ client->pkt_cnt = 0; client->client.dev = dev; client->client.tx_block = false; + client->client.knows_txdone = true; client->chan = mbox_request_channel(&client->client, index); if (IS_ERR(client->chan)) { @@ -155,7 +156,7 @@ err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask); offset_mask |= CMDQ_WRITE_ENABLE_MASK; } - err |= cmdq_pkt_write(pkt, value, subsys, offset_mask); + err |= cmdq_pkt_write(pkt, subsys, offset_mask, value); return err; } @@ -257,7 +258,9 @@ spin_unlock_irqrestore(&client->lock, flags); } - mbox_send_message(client->chan, pkt); + err = mbox_send_message(client->chan, pkt); + if (err < 0) + return err; /* We can send next packet immediately, so just call txdone. */ mbox_client_txdone(client->chan, 0); --- linux-oracle-5.4.0.orig/drivers/soc/mediatek/mtk-scpsys.c +++ linux-oracle-5.4.0/drivers/soc/mediatek/mtk-scpsys.c @@ -446,6 +446,7 @@ for (i = 0; i < num; i++) { struct scp_domain *scpd = &scp->domains[i]; struct generic_pm_domain *genpd = &scpd->genpd; + bool on; /* * Initially turn on all domains to make the domains usable @@ -453,9 +454,9 @@ * software. The unused domains will be switched off during * late_init time. */ - genpd->power_on(genpd); + on = !WARN_ON(genpd->power_on(genpd) < 0); - pm_genpd_init(genpd, NULL, false); + pm_genpd_init(genpd, NULL, !on); } /* --- linux-oracle-5.4.0.orig/drivers/soc/qcom/Kconfig +++ linux-oracle-5.4.0/drivers/soc/qcom/Kconfig @@ -56,19 +56,12 @@ config QCOM_LLCC tristate "Qualcomm Technologies, Inc. LLCC driver" depends on ARCH_QCOM || COMPILE_TEST + select REGMAP_MMIO help Qualcomm Technologies, Inc. platform specific - Last Level Cache Controller(LLCC) driver. This provides interfaces - to clients that use the LLCC. Say yes here to enable LLCC slice - driver. - -config QCOM_SDM845_LLCC - tristate "Qualcomm Technologies, Inc. SDM845 LLCC driver" - depends on QCOM_LLCC - help - Say yes here to enable the LLCC driver for SDM845. This provides - data required to configure LLCC so that clients can start using the - LLCC slices. + Last Level Cache Controller(LLCC) driver for platforms such as, + SDM845. This provides interfaces to clients that use the LLCC. + Say yes here to enable LLCC slice driver. config QCOM_MDT_LOADER tristate --- linux-oracle-5.4.0.orig/drivers/soc/qcom/Makefile +++ linux-oracle-5.4.0/drivers/soc/qcom/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_QCOM_SOCINFO) += socinfo.o obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o obj-$(CONFIG_QCOM_APR) += apr.o -obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o -obj-$(CONFIG_QCOM_SDM845_LLCC) += llcc-sdm845.o +obj-$(CONFIG_QCOM_LLCC) += llcc-qcom.o obj-$(CONFIG_QCOM_RPMHPD) += rpmhpd.o obj-$(CONFIG_QCOM_RPMPD) += rpmpd.o --- linux-oracle-5.4.0.orig/drivers/soc/qcom/cmd-db.c +++ linux-oracle-5.4.0/drivers/soc/qcom/cmd-db.c @@ -247,7 +247,7 @@ return -EINVAL; } - cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WB); + cmd_db_header = memremap(rmem->base, rmem->size, MEMREMAP_WC); if (!cmd_db_header) { ret = -ENOMEM; cmd_db_header = NULL; --- linux-oracle-5.4.0.orig/drivers/soc/qcom/llcc-qcom.c +++ linux-oracle-5.4.0/drivers/soc/qcom/llcc-qcom.c @@ -0,0 +1,462 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACTIVATE BIT(0) +#define DEACTIVATE BIT(1) +#define ACT_CTRL_OPCODE_ACTIVATE BIT(0) +#define ACT_CTRL_OPCODE_DEACTIVATE BIT(1) +#define ACT_CTRL_ACT_TRIG BIT(0) +#define ACT_CTRL_OPCODE_SHIFT 0x01 +#define ATTR1_PROBE_TARGET_WAYS_SHIFT 0x02 +#define ATTR1_FIXED_SIZE_SHIFT 0x03 +#define ATTR1_PRIORITY_SHIFT 0x04 +#define ATTR1_MAX_CAP_SHIFT 0x10 +#define ATTR0_RES_WAYS_MASK GENMASK(11, 0) +#define ATTR0_BONUS_WAYS_MASK GENMASK(27, 16) +#define ATTR0_BONUS_WAYS_SHIFT 0x10 +#define LLCC_STATUS_READ_DELAY 100 + +#define CACHE_LINE_SIZE_SHIFT 6 + +#define LLCC_COMMON_STATUS0 0x0003000c +#define LLCC_LB_CNT_MASK GENMASK(31, 28) +#define LLCC_LB_CNT_SHIFT 28 + +#define MAX_CAP_TO_BYTES(n) (n * SZ_1K) +#define LLCC_TRP_ACT_CTRLn(n) (n * SZ_4K) +#define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K) +#define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) +#define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) + +#define BANK_OFFSET_STRIDE 0x80000 + +static struct llcc_slice_config sdm845_data[] = { + { LLCC_CPUSS, 1, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 1 }, + { LLCC_VIDSC0, 2, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, + { LLCC_VIDSC1, 3, 512, 2, 1, 0x0, 0x0f0, 0, 0, 1, 1, 0 }, + { LLCC_ROTATOR, 4, 563, 2, 1, 0x0, 0x00e, 2, 0, 1, 1, 0 }, + { LLCC_VOICE, 5, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_AUDIO, 6, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_MDMHPGRW, 7, 1024, 2, 0, 0xfc, 0xf00, 0, 0, 1, 1, 0 }, + { LLCC_MDM, 8, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_CMPT, 10, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_GPUHTW, 11, 512, 1, 1, 0xc, 0x0, 0, 0, 1, 1, 0 }, + { LLCC_GPU, 12, 2304, 1, 0, 0xff0, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_MMUHWT, 13, 256, 2, 0, 0x0, 0x1, 0, 0, 1, 0, 1 }, + { LLCC_CMPTDMA, 15, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_DISP, 16, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_VIDFW, 17, 2816, 1, 0, 0xffc, 0x2, 0, 0, 1, 1, 0 }, + { LLCC_MDMHPFX, 20, 1024, 2, 1, 0x0, 0xf00, 0, 0, 1, 1, 0 }, + { LLCC_MDMPNG, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0 }, + { LLCC_AUDHW, 22, 1024, 1, 1, 0xffc, 0x2, 0, 0, 1, 1, 0 }, +}; + +static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER; + +static struct regmap_config llcc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; + +/** + * llcc_slice_getd - get llcc slice descriptor + * @uid: usecase_id for the client + * + * A pointer to llcc slice descriptor will be returned on success and + * and error pointer is returned on failure + */ +struct llcc_slice_desc *llcc_slice_getd(u32 uid) +{ + const struct llcc_slice_config *cfg; + struct llcc_slice_desc *desc; + u32 sz, count; + + if (IS_ERR(drv_data)) + return ERR_CAST(drv_data); + + cfg = drv_data->cfg; + sz = drv_data->cfg_size; + + for (count = 0; cfg && count < sz; count++, cfg++) + if (cfg->usecase_id == uid) + break; + + if (count == sz || !cfg) + return ERR_PTR(-ENODEV); + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return ERR_PTR(-ENOMEM); + + desc->slice_id = cfg->slice_id; + desc->slice_size = cfg->max_cap; + + return desc; +} +EXPORT_SYMBOL_GPL(llcc_slice_getd); + +/** + * llcc_slice_putd - llcc slice descritpor + * @desc: Pointer to llcc slice descriptor + */ +void llcc_slice_putd(struct llcc_slice_desc *desc) +{ + if (!IS_ERR_OR_NULL(desc)) + kfree(desc); +} +EXPORT_SYMBOL_GPL(llcc_slice_putd); + +static int llcc_update_act_ctrl(u32 sid, + u32 act_ctrl_reg_val, u32 status) +{ + u32 act_ctrl_reg; + u32 status_reg; + u32 slice_status; + int ret; + + if (IS_ERR(drv_data)) + return PTR_ERR(drv_data); + + act_ctrl_reg = LLCC_TRP_ACT_CTRLn(sid); + status_reg = LLCC_TRP_STATUSn(sid); + + /* Set the ACTIVE trigger */ + act_ctrl_reg_val |= ACT_CTRL_ACT_TRIG; + ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg, + act_ctrl_reg_val); + if (ret) + return ret; + + /* Clear the ACTIVE trigger */ + act_ctrl_reg_val &= ~ACT_CTRL_ACT_TRIG; + ret = regmap_write(drv_data->bcast_regmap, act_ctrl_reg, + act_ctrl_reg_val); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(drv_data->bcast_regmap, status_reg, + slice_status, !(slice_status & status), + 0, LLCC_STATUS_READ_DELAY); + return ret; +} + +/** + * llcc_slice_activate - Activate the llcc slice + * @desc: Pointer to llcc slice descriptor + * + * A value of zero will be returned on success and a negative errno will + * be returned in error cases + */ +int llcc_slice_activate(struct llcc_slice_desc *desc) +{ + int ret; + u32 act_ctrl_val; + + if (IS_ERR(drv_data)) + return PTR_ERR(drv_data); + + if (IS_ERR_OR_NULL(desc)) + return -EINVAL; + + mutex_lock(&drv_data->lock); + if (test_bit(desc->slice_id, drv_data->bitmap)) { + mutex_unlock(&drv_data->lock); + return 0; + } + + act_ctrl_val = ACT_CTRL_OPCODE_ACTIVATE << ACT_CTRL_OPCODE_SHIFT; + + ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, + DEACTIVATE); + if (ret) { + mutex_unlock(&drv_data->lock); + return ret; + } + + __set_bit(desc->slice_id, drv_data->bitmap); + mutex_unlock(&drv_data->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(llcc_slice_activate); + +/** + * llcc_slice_deactivate - Deactivate the llcc slice + * @desc: Pointer to llcc slice descriptor + * + * A value of zero will be returned on success and a negative errno will + * be returned in error cases + */ +int llcc_slice_deactivate(struct llcc_slice_desc *desc) +{ + u32 act_ctrl_val; + int ret; + + if (IS_ERR(drv_data)) + return PTR_ERR(drv_data); + + if (IS_ERR_OR_NULL(desc)) + return -EINVAL; + + mutex_lock(&drv_data->lock); + if (!test_bit(desc->slice_id, drv_data->bitmap)) { + mutex_unlock(&drv_data->lock); + return 0; + } + act_ctrl_val = ACT_CTRL_OPCODE_DEACTIVATE << ACT_CTRL_OPCODE_SHIFT; + + ret = llcc_update_act_ctrl(desc->slice_id, act_ctrl_val, + ACTIVATE); + if (ret) { + mutex_unlock(&drv_data->lock); + return ret; + } + + __clear_bit(desc->slice_id, drv_data->bitmap); + mutex_unlock(&drv_data->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(llcc_slice_deactivate); + +/** + * llcc_get_slice_id - return the slice id + * @desc: Pointer to llcc slice descriptor + */ +int llcc_get_slice_id(struct llcc_slice_desc *desc) +{ + if (IS_ERR_OR_NULL(desc)) + return -EINVAL; + + return desc->slice_id; +} +EXPORT_SYMBOL_GPL(llcc_get_slice_id); + +/** + * llcc_get_slice_size - return the slice id + * @desc: Pointer to llcc slice descriptor + */ +size_t llcc_get_slice_size(struct llcc_slice_desc *desc) +{ + if (IS_ERR_OR_NULL(desc)) + return 0; + + return desc->slice_size; +} +EXPORT_SYMBOL_GPL(llcc_get_slice_size); + +static int qcom_llcc_cfg_program(struct platform_device *pdev) +{ + int i; + u32 attr1_cfg; + u32 attr0_cfg; + u32 attr1_val; + u32 attr0_val; + u32 max_cap_cacheline; + u32 sz; + int ret = 0; + const struct llcc_slice_config *llcc_table; + struct llcc_slice_desc desc; + + sz = drv_data->cfg_size; + llcc_table = drv_data->cfg; + + for (i = 0; i < sz; i++) { + attr1_cfg = LLCC_TRP_ATTR1_CFGn(llcc_table[i].slice_id); + attr0_cfg = LLCC_TRP_ATTR0_CFGn(llcc_table[i].slice_id); + + attr1_val = llcc_table[i].cache_mode; + attr1_val |= llcc_table[i].probe_target_ways << + ATTR1_PROBE_TARGET_WAYS_SHIFT; + attr1_val |= llcc_table[i].fixed_size << + ATTR1_FIXED_SIZE_SHIFT; + attr1_val |= llcc_table[i].priority << + ATTR1_PRIORITY_SHIFT; + + max_cap_cacheline = MAX_CAP_TO_BYTES(llcc_table[i].max_cap); + + /* LLCC instances can vary for each target. + * The SW writes to broadcast register which gets propagated + * to each llcc instace (llcc0,.. llccN). + * Since the size of the memory is divided equally amongst the + * llcc instances, we need to configure the max cap accordingly. + */ + max_cap_cacheline = max_cap_cacheline / drv_data->num_banks; + max_cap_cacheline >>= CACHE_LINE_SIZE_SHIFT; + attr1_val |= max_cap_cacheline << ATTR1_MAX_CAP_SHIFT; + + attr0_val = llcc_table[i].res_ways & ATTR0_RES_WAYS_MASK; + attr0_val |= llcc_table[i].bonus_ways << ATTR0_BONUS_WAYS_SHIFT; + + ret = regmap_write(drv_data->bcast_regmap, attr1_cfg, + attr1_val); + if (ret) + return ret; + ret = regmap_write(drv_data->bcast_regmap, attr0_cfg, + attr0_val); + if (ret) + return ret; + if (llcc_table[i].activate_on_init) { + desc.slice_id = llcc_table[i].slice_id; + ret = llcc_slice_activate(&desc); + } + } + return ret; +} + +static int qcom_llcc_remove(struct platform_device *pdev) +{ + /* Set the global pointer to a error code to avoid referencing it */ + drv_data = ERR_PTR(-ENODEV); + return 0; +} + +static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, + const char *name) +{ + struct resource *res; + void __iomem *base; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (!res) + return ERR_PTR(-ENODEV); + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return ERR_CAST(base); + + llcc_regmap_config.name = name; + return devm_regmap_init_mmio(&pdev->dev, base, &llcc_regmap_config); +} + +static int qcom_llcc_probe(struct platform_device *pdev, + const struct llcc_slice_config *llcc_cfg, u32 sz) +{ + u32 num_banks; + struct device *dev = &pdev->dev; + int ret, i; + struct platform_device *llcc_edac; + + if (!IS_ERR(drv_data)) + return -EBUSY; + + drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); + if (!drv_data) { + ret = -ENOMEM; + goto err; + } + + drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base"); + if (IS_ERR(drv_data->regmap)) { + ret = PTR_ERR(drv_data->regmap); + goto err; + } + + drv_data->bcast_regmap = + qcom_llcc_init_mmio(pdev, "llcc_broadcast_base"); + if (IS_ERR(drv_data->bcast_regmap)) { + ret = PTR_ERR(drv_data->bcast_regmap); + goto err; + } + + ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0, + &num_banks); + if (ret) + goto err; + + num_banks &= LLCC_LB_CNT_MASK; + num_banks >>= LLCC_LB_CNT_SHIFT; + drv_data->num_banks = num_banks; + + for (i = 0; i < sz; i++) + if (llcc_cfg[i].slice_id > drv_data->max_slices) + drv_data->max_slices = llcc_cfg[i].slice_id; + + drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32), + GFP_KERNEL); + if (!drv_data->offsets) { + ret = -ENOMEM; + goto err; + } + + for (i = 0; i < num_banks; i++) + drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; + + drv_data->bitmap = devm_kcalloc(dev, + BITS_TO_LONGS(drv_data->max_slices), sizeof(unsigned long), + GFP_KERNEL); + if (!drv_data->bitmap) { + ret = -ENOMEM; + goto err; + } + + drv_data->cfg = llcc_cfg; + drv_data->cfg_size = sz; + mutex_init(&drv_data->lock); + platform_set_drvdata(pdev, drv_data); + + ret = qcom_llcc_cfg_program(pdev); + if (ret) + goto err; + + drv_data->ecc_irq = platform_get_irq(pdev, 0); + if (drv_data->ecc_irq >= 0) { + llcc_edac = platform_device_register_data(&pdev->dev, + "qcom_llcc_edac", -1, drv_data, + sizeof(*drv_data)); + if (IS_ERR(llcc_edac)) + dev_err(dev, "Failed to register llcc edac driver\n"); + } + + return 0; +err: + drv_data = ERR_PTR(-ENODEV); + return ret; +} + +static int sdm845_qcom_llcc_remove(struct platform_device *pdev) +{ + return qcom_llcc_remove(pdev); +} + +static int sdm845_qcom_llcc_probe(struct platform_device *pdev) +{ + return qcom_llcc_probe(pdev, sdm845_data, ARRAY_SIZE(sdm845_data)); +} + +static const struct of_device_id sdm845_qcom_llcc_of_match[] = { + { .compatible = "qcom,sdm845-llcc", }, + { } +}; + +static struct platform_driver sdm845_qcom_llcc_driver = { + .driver = { + .name = "sdm845-llcc", + .of_match_table = sdm845_qcom_llcc_of_match, + }, + .probe = sdm845_qcom_llcc_probe, + .remove = sdm845_qcom_llcc_remove, +}; +module_platform_driver(sdm845_qcom_llcc_driver); + +MODULE_DESCRIPTION("QCOM sdm845 LLCC driver"); +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/soc/qcom/mdt_loader.c +++ linux-oracle-5.4.0/drivers/soc/qcom/mdt_loader.c @@ -98,7 +98,7 @@ if (ehdr->e_phnum < 2) return ERR_PTR(-EINVAL); - if (phdrs[0].p_type == PT_LOAD || phdrs[1].p_type == PT_LOAD) + if (phdrs[0].p_type == PT_LOAD) return ERR_PTR(-EINVAL); if ((phdrs[1].p_flags & QCOM_MDT_TYPE_MASK) != QCOM_MDT_TYPE_HASH) @@ -230,6 +230,14 @@ break; } + if (phdr->p_filesz > phdr->p_memsz) { + dev_err(dev, + "refusing to load segment %d with p_filesz > p_memsz\n", + i); + ret = -EINVAL; + break; + } + ptr = mem_region + offset; if (phdr->p_filesz && phdr->p_offset < fw->size) { @@ -253,6 +261,15 @@ break; } + if (seg_fw->size != phdr->p_filesz) { + dev_err(dev, + "failed to load segment %d from truncated file %s\n", + i, fw_name); + release_firmware(seg_fw); + ret = -EINVAL; + break; + } + release_firmware(seg_fw); } --- linux-oracle-5.4.0.orig/drivers/soc/qcom/qcom-geni-se.c +++ linux-oracle-5.4.0/drivers/soc/qcom/qcom-geni-se.c @@ -282,10 +282,23 @@ static void geni_se_select_dma_mode(struct geni_se *se) { + u32 proto = geni_se_read_proto(se); u32 val; geni_se_irq_clear(se); + val = readl_relaxed(se->base + SE_GENI_M_IRQ_EN); + if (proto != GENI_SE_UART) { + val &= ~(M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN); + val &= ~(M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN); + } + writel_relaxed(val, se->base + SE_GENI_M_IRQ_EN); + + val = readl_relaxed(se->base + SE_GENI_S_IRQ_EN); + if (proto != GENI_SE_UART) + val &= ~S_CMD_DONE_EN; + writel_relaxed(val, se->base + SE_GENI_S_IRQ_EN); + val = readl_relaxed(se->base + SE_GENI_DMA_MODE_EN); val |= GENI_DMA_MODE_EN; writel_relaxed(val, se->base + SE_GENI_DMA_MODE_EN); @@ -537,7 +550,8 @@ for (i = 0; i < MAX_CLK_PERF_LEVEL; i++) { freq = clk_round_rate(se->clk, freq + 1); - if (freq <= 0 || freq == se->clk_perf_tbl[i - 1]) + if (freq <= 0 || + (i > 0 && freq == se->clk_perf_tbl[i - 1])) break; se->clk_perf_tbl[i] = freq; } @@ -644,7 +658,7 @@ writel_relaxed(lower_32_bits(*iova), se->base + SE_DMA_TX_PTR_L); writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_TX_PTR_H); writel_relaxed(GENI_SE_DMA_EOT_BUF, se->base + SE_DMA_TX_ATTR); - writel_relaxed(len, se->base + SE_DMA_TX_LEN); + writel(len, se->base + SE_DMA_TX_LEN); return 0; } EXPORT_SYMBOL(geni_se_tx_dma_prep); @@ -681,7 +695,7 @@ writel_relaxed(upper_32_bits(*iova), se->base + SE_DMA_RX_PTR_H); /* RX does not have EOT buffer type bit. So just reset RX_ATTR */ writel_relaxed(0, se->base + SE_DMA_RX_ATTR); - writel_relaxed(len, se->base + SE_DMA_RX_LEN); + writel(len, se->base + SE_DMA_RX_LEN); return 0; } EXPORT_SYMBOL(geni_se_rx_dma_prep); --- linux-oracle-5.4.0.orig/drivers/soc/qcom/qcom_aoss.c +++ linux-oracle-5.4.0/drivers/soc/qcom/qcom_aoss.c @@ -472,12 +472,12 @@ static int qmp_cooling_devices_register(struct qmp *qmp) { struct device_node *np, *child; - int count = QMP_NUM_COOLING_RESOURCES; + int count = 0; int ret; np = qmp->dev->of_node; - qmp->cooling_devs = devm_kcalloc(qmp->dev, count, + qmp->cooling_devs = devm_kcalloc(qmp->dev, QMP_NUM_COOLING_RESOURCES, sizeof(*qmp->cooling_devs), GFP_KERNEL); @@ -489,16 +489,22 @@ continue; ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++], child); - if (ret) + if (ret) { + of_node_put(child); goto unroll; + } } + if (!count) + devm_kfree(qmp->dev, qmp->cooling_devs); + return 0; unroll: while (--count >= 0) thermal_cooling_device_unregister (qmp->cooling_devs[count].cdev); + devm_kfree(qmp->dev, qmp->cooling_devs); return ret; } @@ -540,7 +546,7 @@ } irq = platform_get_irq(pdev, 0); - ret = devm_request_irq(&pdev->dev, irq, qmp_intr, IRQF_ONESHOT, + ret = devm_request_irq(&pdev->dev, irq, qmp_intr, 0, "aoss-qmp", qmp); if (ret < 0) { dev_err(&pdev->dev, "failed to request interrupt\n"); --- linux-oracle-5.4.0.orig/drivers/soc/qcom/qmi_encdec.c +++ linux-oracle-5.4.0/drivers/soc/qcom/qmi_encdec.c @@ -534,8 +534,8 @@ decoded_bytes += rc; } - if (string_len > temp_ei->elem_len) { - pr_err("%s: String len %d > Max Len %d\n", + if (string_len >= temp_ei->elem_len) { + pr_err("%s: String len %d >= Max Len %d\n", __func__, string_len, temp_ei->elem_len); return -ETOOSMALL; } else if (string_len > tlv_len) { --- linux-oracle-5.4.0.orig/drivers/soc/qcom/rpmh-rsc.c +++ linux-oracle-5.4.0/drivers/soc/qcom/rpmh-rsc.c @@ -148,7 +148,7 @@ static struct tcs_group *get_tcs_for_msg(struct rsc_drv *drv, const struct tcs_request *msg) { - int type, ret; + int type; struct tcs_group *tcs; switch (msg->state) { @@ -169,19 +169,10 @@ * If we are making an active request on a RSC that does not have a * dedicated TCS for active state use, then re-purpose a wake TCS to * send active votes. - * NOTE: The driver must be aware that this RSC does not have a - * dedicated AMC, and therefore would invalidate the sleep and wake - * TCSes before making an active state request. */ tcs = get_tcs_of_type(drv, type); - if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) { + if (msg->state == RPMH_ACTIVE_ONLY_STATE && !tcs->num_tcs) tcs = get_tcs_of_type(drv, WAKE_TCS); - if (tcs->num_tcs) { - ret = rpmh_rsc_invalidate(drv); - if (ret) - return ERR_PTR(ret); - } - } return tcs; } @@ -201,6 +192,42 @@ return NULL; } +static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) +{ + u32 enable; + + /* + * HW req: Clear the DRV_CONTROL and enable TCS again + * While clearing ensure that the AMC mode trigger is cleared + * and then the mode enable is cleared. + */ + enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0); + enable &= ~TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); + enable &= ~TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); + + if (trigger) { + /* Enable the AMC mode on the TCS and then trigger the TCS */ + enable = TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); + enable |= TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); + } +} + +static void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) +{ + u32 data; + + data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, 0); + if (enable) + data |= BIT(tcs_id); + else + data &= ~BIT(tcs_id); + write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, data); +} + /** * tcs_tx_done: TX Done interrupt handler */ @@ -237,6 +264,14 @@ } trace_rpmh_tx_done(drv, i, req, err); + + /* + * If wake tcs was re-purposed for sending active + * votes, clear AMC trigger & enable modes and + * disable interrupt for this TCS + */ + if (!drv->tcs[ACTIVE_TCS].num_tcs) + __tcs_set_trigger(drv, i, false); skip: /* Reclaim the TCS */ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, i, 0); @@ -244,6 +279,13 @@ write_tcs_reg(drv, RSC_DRV_IRQ_CLEAR, 0, BIT(i)); spin_lock(&drv->lock); clear_bit(i, drv->tcs_in_use); + /* + * Disable interrupt for WAKE TCS to avoid being + * spammed with interrupts coming when the solver + * sends its wake votes. + */ + if (!drv->tcs[ACTIVE_TCS].num_tcs) + enable_tcs_irq(drv, i, false); spin_unlock(&drv->lock); if (req) rpmh_tx_done(req, err); @@ -285,28 +327,6 @@ write_tcs_reg(drv, RSC_DRV_CMD_ENABLE, tcs_id, cmd_enable); } -static void __tcs_trigger(struct rsc_drv *drv, int tcs_id) -{ - u32 enable; - - /* - * HW req: Clear the DRV_CONTROL and enable TCS again - * While clearing ensure that the AMC mode trigger is cleared - * and then the mode enable is cleared. - */ - enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0); - enable &= ~TCS_AMC_MODE_TRIGGER; - write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); - enable &= ~TCS_AMC_MODE_ENABLE; - write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); - - /* Enable the AMC mode on the TCS and then trigger the TCS */ - enable = TCS_AMC_MODE_ENABLE; - write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); - enable |= TCS_AMC_MODE_TRIGGER; - write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); -} - static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, const struct tcs_request *msg) { @@ -377,10 +397,20 @@ tcs->req[tcs_id - tcs->offset] = msg; set_bit(tcs_id, drv->tcs_in_use); + if (msg->state == RPMH_ACTIVE_ONLY_STATE && tcs->type != ACTIVE_TCS) { + /* + * Clear previously programmed WAKE commands in selected + * repurposed TCS to avoid triggering them. tcs->slots will be + * cleaned from rpmh_flush() by invoking rpmh_rsc_invalidate() + */ + write_tcs_reg_sync(drv, RSC_DRV_CMD_ENABLE, tcs_id, 0); + write_tcs_reg_sync(drv, RSC_DRV_CMD_WAIT_FOR_CMPL, tcs_id, 0); + enable_tcs_irq(drv, tcs_id, true); + } spin_unlock(&drv->lock); __tcs_buffer_write(drv, tcs_id, 0, msg); - __tcs_trigger(drv, tcs_id); + __tcs_set_trigger(drv, tcs_id, true); done_write: spin_unlock_irqrestore(&tcs->lock, flags); @@ -685,6 +715,7 @@ .driver = { .name = "rpmh", .of_match_table = rpmh_drv_match, + .suppress_bind_attrs = true, }, }; --- linux-oracle-5.4.0.orig/drivers/soc/qcom/rpmh.c +++ linux-oracle-5.4.0/drivers/soc/qcom/rpmh.c @@ -119,6 +119,7 @@ { struct cache_req *req; unsigned long flags; + u32 old_sleep_val, old_wake_val; spin_lock_irqsave(&ctrlr->cache_lock, flags); req = __find_req(ctrlr, cmd->addr); @@ -133,26 +134,27 @@ req->addr = cmd->addr; req->sleep_val = req->wake_val = UINT_MAX; - INIT_LIST_HEAD(&req->list); list_add_tail(&req->list, &ctrlr->cache); existing: + old_sleep_val = req->sleep_val; + old_wake_val = req->wake_val; + switch (state) { case RPMH_ACTIVE_ONLY_STATE: - if (req->sleep_val != UINT_MAX) - req->wake_val = cmd->data; - break; case RPMH_WAKE_ONLY_STATE: req->wake_val = cmd->data; break; case RPMH_SLEEP_STATE: req->sleep_val = cmd->data; break; - default: - break; } - ctrlr->dirty = true; + ctrlr->dirty |= (req->sleep_val != old_sleep_val || + req->wake_val != old_wake_val) && + req->sleep_val != UINT_MAX && + req->wake_val != UINT_MAX; + unlock: spin_unlock_irqrestore(&ctrlr->cache_lock, flags); @@ -287,6 +289,7 @@ spin_lock_irqsave(&ctrlr->cache_lock, flags); list_add_tail(&req->list, &ctrlr->batch_cache); + ctrlr->dirty = true; spin_unlock_irqrestore(&ctrlr->cache_lock, flags); } @@ -314,18 +317,6 @@ return ret; } -static void invalidate_batch(struct rpmh_ctrlr *ctrlr) -{ - struct batch_cache_req *req, *tmp; - unsigned long flags; - - spin_lock_irqsave(&ctrlr->cache_lock, flags); - list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) - kfree(req); - INIT_LIST_HEAD(&ctrlr->batch_cache); - spin_unlock_irqrestore(&ctrlr->cache_lock, flags); -} - /** * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the * batch to finish. @@ -465,6 +456,13 @@ return 0; } + /* Invalidate the TCSes first to avoid stale data */ + do { + ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); + } while (ret == -EAGAIN); + if (ret) + return ret; + /* First flush the cached batch requests */ ret = flush_batch(ctrlr); if (ret) @@ -496,25 +494,25 @@ EXPORT_SYMBOL(rpmh_flush); /** - * rpmh_invalidate: Invalidate all sleep and active sets - * sets. + * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache * * @dev: The device making the request * - * Invalidate the sleep and active values in the TCS blocks. + * Invalidate the sleep and wake values in batch_cache. */ int rpmh_invalidate(const struct device *dev) { struct rpmh_ctrlr *ctrlr = get_rpmh_ctrlr(dev); - int ret; + struct batch_cache_req *req, *tmp; + unsigned long flags; - invalidate_batch(ctrlr); + spin_lock_irqsave(&ctrlr->cache_lock, flags); + list_for_each_entry_safe(req, tmp, &ctrlr->batch_cache, list) + kfree(req); + INIT_LIST_HEAD(&ctrlr->batch_cache); ctrlr->dirty = true; + spin_unlock_irqrestore(&ctrlr->cache_lock, flags); - do { - ret = rpmh_rsc_invalidate(ctrlr_to_drv(ctrlr)); - } while (ret == -EAGAIN); - - return ret; + return 0; } EXPORT_SYMBOL(rpmh_invalidate); --- linux-oracle-5.4.0.orig/drivers/soc/qcom/rpmhpd.c +++ linux-oracle-5.4.0/drivers/soc/qcom/rpmhpd.c @@ -93,6 +93,7 @@ static struct rpmhpd sdm845_mx_ao = { .pd = { .name = "mx_ao", }, + .active_only = true, .peer = &sdm845_mx, .res_name = "mx.lvl", }; @@ -107,6 +108,7 @@ static struct rpmhpd sdm845_cx_ao = { .pd = { .name = "cx_ao", }, + .active_only = true, .peer = &sdm845_cx, .parent = &sdm845_mx_ao.pd, .res_name = "cx.lvl", @@ -233,12 +235,11 @@ static int rpmhpd_power_off(struct generic_pm_domain *domain) { struct rpmhpd *pd = domain_to_rpmhpd(domain); - int ret = 0; + int ret; mutex_lock(&rpmhpd_lock); - ret = rpmhpd_aggregate_corner(pd, pd->level[0]); - + ret = rpmhpd_aggregate_corner(pd, 0); if (!ret) pd->enabled = false; --- linux-oracle-5.4.0.orig/drivers/soc/qcom/rpmpd.c +++ linux-oracle-5.4.0/drivers/soc/qcom/rpmpd.c @@ -362,6 +362,9 @@ data->domains = devm_kcalloc(&pdev->dev, num, sizeof(*data->domains), GFP_KERNEL); + if (!data->domains) + return -ENOMEM; + data->num_domains = num; for (i = 0; i < num; i++) { --- linux-oracle-5.4.0.orig/drivers/soc/qcom/smem_state.c +++ linux-oracle-5.4.0/drivers/soc/qcom/smem_state.c @@ -116,7 +116,8 @@ if (args.args_count != 1) { dev_err(dev, "invalid #qcom,smem-state-cells\n"); - return ERR_PTR(-EINVAL); + state = ERR_PTR(-EINVAL); + goto put; } state = of_node_to_state(args.np); @@ -136,6 +137,7 @@ struct qcom_smem_state *state = container_of(ref, struct qcom_smem_state, refcount); list_del(&state->list); + of_node_put(state->of_node); kfree(state); } @@ -169,7 +171,7 @@ kref_init(&state->refcount); - state->of_node = of_node; + state->of_node = of_node_get(of_node); state->ops = *ops; state->priv = priv; --- linux-oracle-5.4.0.orig/drivers/soc/qcom/smp2p.c +++ linux-oracle-5.4.0/drivers/soc/qcom/smp2p.c @@ -318,15 +318,16 @@ static int smp2p_update_bits(void *data, u32 mask, u32 value) { struct smp2p_entry *entry = data; + unsigned long flags; u32 orig; u32 val; - spin_lock(&entry->lock); + spin_lock_irqsave(&entry->lock, flags); val = orig = readl(entry->value); val &= ~mask; val |= value; writel(val, entry->value); - spin_unlock(&entry->lock); + spin_unlock_irqrestore(&entry->lock, flags); if (val != orig) qcom_smp2p_kick(entry->smp2p); @@ -419,6 +420,7 @@ } smp2p->ipc_regmap = syscon_node_to_regmap(syscon); + of_node_put(syscon); if (IS_ERR(smp2p->ipc_regmap)) return PTR_ERR(smp2p->ipc_regmap); --- linux-oracle-5.4.0.orig/drivers/soc/qcom/smsm.c +++ linux-oracle-5.4.0/drivers/soc/qcom/smsm.c @@ -109,7 +109,7 @@ DECLARE_BITMAP(irq_enabled, 32); DECLARE_BITMAP(irq_rising, 32); DECLARE_BITMAP(irq_falling, 32); - u32 last_value; + unsigned long last_value; u32 *remote_state; u32 *subscription; @@ -204,8 +204,7 @@ u32 val; val = readl(entry->remote_state); - changed = val ^ entry->last_value; - entry->last_value = val; + changed = val ^ xchg(&entry->last_value, val); for_each_set_bit(i, entry->irq_enabled, 32) { if (!(changed & BIT(i))) @@ -266,6 +265,12 @@ struct qcom_smsm *smsm = entry->smsm; u32 val; + /* Make sure our last cached state is up-to-date */ + if (readl(entry->remote_state) & BIT(irq)) + set_bit(irq, &entry->last_value); + else + clear_bit(irq, &entry->last_value); + set_bit(irq, entry->irq_enabled); if (entry->subscription) { @@ -354,6 +359,7 @@ return 0; host->ipc_regmap = syscon_node_to_regmap(syscon); + of_node_put(syscon); if (IS_ERR(host->ipc_regmap)) return PTR_ERR(host->ipc_regmap); @@ -505,7 +511,7 @@ for (id = 0; id < smsm->num_hosts; id++) { ret = smsm_parse_ipc(smsm, id); if (ret < 0) - return ret; + goto out_put; } /* Acquire the main SMSM state vector */ @@ -513,13 +519,14 @@ smsm->num_entries * sizeof(u32)); if (ret < 0 && ret != -EEXIST) { dev_err(&pdev->dev, "unable to allocate shared state entry\n"); - return ret; + goto out_put; } states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); if (IS_ERR(states)) { dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); - return PTR_ERR(states); + ret = PTR_ERR(states); + goto out_put; } /* Acquire the list of interrupt mask vectors */ @@ -527,13 +534,14 @@ ret = qcom_smem_alloc(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, size); if (ret < 0 && ret != -EEXIST) { dev_err(&pdev->dev, "unable to allocate smsm interrupt mask\n"); - return ret; + goto out_put; } intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); if (IS_ERR(intr_mask)) { dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); - return PTR_ERR(intr_mask); + ret = PTR_ERR(intr_mask); + goto out_put; } /* Setup the reference to the local state bits */ @@ -544,7 +552,8 @@ smsm->state = qcom_smem_state_register(local_node, &smsm_state_ops, smsm); if (IS_ERR(smsm->state)) { dev_err(smsm->dev, "failed to register qcom_smem_state\n"); - return PTR_ERR(smsm->state); + ret = PTR_ERR(smsm->state); + goto out_put; } /* Register handlers for remote processor entries of interest. */ @@ -574,16 +583,19 @@ } platform_set_drvdata(pdev, smsm); + of_node_put(local_node); return 0; unwind_interfaces: + of_node_put(node); for (id = 0; id < smsm->num_entries; id++) if (smsm->entries[id].domain) irq_domain_remove(smsm->entries[id].domain); qcom_smem_state_unregister(smsm->state); - +out_put: + of_node_put(local_node); return ret; } --- linux-oracle-5.4.0.orig/drivers/soc/qcom/socinfo.c +++ linux-oracle-5.4.0/drivers/soc/qcom/socinfo.c @@ -428,13 +428,21 @@ qs->attr.family = "Snapdragon"; qs->attr.machine = socinfo_machine(&pdev->dev, le32_to_cpu(info->id)); + qs->attr.soc_id = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u", + le32_to_cpu(info->id)); qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u", SOCINFO_MAJOR(le32_to_cpu(info->ver)), SOCINFO_MINOR(le32_to_cpu(info->ver))); - if (offsetof(struct socinfo, serial_num) <= item_size) + if (!qs->attr.soc_id || !qs->attr.revision) + return -ENOMEM; + + if (offsetofend(struct socinfo, serial_num) <= item_size) { qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u", le32_to_cpu(info->serial_num)); + if (!qs->attr.serial_number) + return -ENOMEM; + } qs->soc_dev = soc_device_register(&qs->attr); if (IS_ERR(qs->soc_dev)) @@ -445,7 +453,7 @@ /* Feed the soc specific unique data into entropy pool */ add_device_randomness(info, item_size); - platform_set_drvdata(pdev, qs->soc_dev); + platform_set_drvdata(pdev, qs); return 0; } --- linux-oracle-5.4.0.orig/drivers/soc/renesas/r8a77980-sysc.c +++ linux-oracle-5.4.0/drivers/soc/renesas/r8a77980-sysc.c @@ -25,7 +25,8 @@ PD_CPU_NOCR }, { "ca53-cpu3", 0x200, 3, R8A77980_PD_CA53_CPU3, R8A77980_PD_CA53_SCU, PD_CPU_NOCR }, - { "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON }, + { "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON, + PD_CPU_NOCR }, { "a3ir", 0x180, 0, R8A77980_PD_A3IR, R8A77980_PD_ALWAYS_ON }, { "a2ir0", 0x400, 0, R8A77980_PD_A2IR0, R8A77980_PD_A3IR }, { "a2ir1", 0x400, 1, R8A77980_PD_A2IR1, R8A77980_PD_A3IR }, --- linux-oracle-5.4.0.orig/drivers/soc/renesas/renesas-soc.c +++ linux-oracle-5.4.0/drivers/soc/renesas/renesas-soc.c @@ -326,7 +326,7 @@ if (np) { chipid = of_iomap(np, 0); of_node_put(np); - } else if (soc->id) { + } else if (soc->id && family->reg) { chipid = ioremap(family->reg, 4); } if (chipid) { --- linux-oracle-5.4.0.orig/drivers/soc/renesas/rmobile-sysc.c +++ linux-oracle-5.4.0/drivers/soc/renesas/rmobile-sysc.c @@ -327,6 +327,7 @@ pmd = of_get_child_by_name(np, "pm-domains"); if (!pmd) { + iounmap(base); pr_warn("%pOF lacks pm-domains node\n", np); continue; } --- linux-oracle-5.4.0.orig/drivers/soc/rockchip/Kconfig +++ linux-oracle-5.4.0/drivers/soc/rockchip/Kconfig @@ -6,8 +6,8 @@ # config ROCKCHIP_GRF - bool - default y + bool "Rockchip General Register Files support" if COMPILE_TEST + default y if ARCH_ROCKCHIP help The General Register Files are a central component providing special additional settings registers for a lot of soc-components. --- linux-oracle-5.4.0.orig/drivers/soc/rockchip/grf.c +++ linux-oracle-5.4.0/drivers/soc/rockchip/grf.c @@ -148,12 +148,14 @@ return -ENODEV; if (!match || !match->data) { pr_err("%s: missing grf data\n", __func__); + of_node_put(np); return -EINVAL; } grf_info = match->data; grf = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(grf)) { pr_err("%s: could not get grf syscon\n", __func__); return PTR_ERR(grf); --- linux-oracle-5.4.0.orig/drivers/soc/sunxi/sunxi_sram.c +++ linux-oracle-5.4.0/drivers/soc/sunxi/sunxi_sram.c @@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun50i_a64_sram_c = { .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1, - SUNXI_SRAM_MAP(0, 1, "cpu"), - SUNXI_SRAM_MAP(1, 0, "de2")), + SUNXI_SRAM_MAP(1, 0, "cpu"), + SUNXI_SRAM_MAP(0, 1, "de2")), }; static const struct of_device_id sunxi_sram_dt_ids[] = { @@ -254,6 +254,7 @@ writel(val | ((device << sram_data->offset) & mask), base + sram_data->reg); + sram_desc->claimed = true; spin_unlock(&sram_lock); return 0; @@ -318,12 +319,11 @@ .writeable_reg = sunxi_sram_regmap_accessible_reg, }; -static int sunxi_sram_probe(struct platform_device *pdev) +static int __init sunxi_sram_probe(struct platform_device *pdev) { - struct resource *res; - struct dentry *d; struct regmap *emac_clock; const struct sunxi_sramc_variant *variant; + struct device *dev = &pdev->dev; sram_dev = &pdev->dev; @@ -331,18 +331,10 @@ if (!variant) return -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); - of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); - - d = debugfs_create_file("sram", S_IRUGO, NULL, NULL, - &sunxi_sram_fops); - if (!d) - return -ENOMEM; - if (variant->has_emac_clock) { emac_clock = devm_regmap_init_mmio(&pdev->dev, base, &sunxi_sram_emac_clock_regmap); @@ -351,6 +343,10 @@ return PTR_ERR(emac_clock); } + of_platform_populate(dev->of_node, NULL, NULL, dev); + + debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops); + return 0; } @@ -396,9 +392,8 @@ .name = "sunxi-sram", .of_match_table = sunxi_sram_dt_match, }, - .probe = sunxi_sram_probe, }; -module_platform_driver(sunxi_sram_driver); +builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe); MODULE_AUTHOR("Maxime Ripard "); MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver"); --- linux-oracle-5.4.0.orig/drivers/soc/tegra/Kconfig +++ linux-oracle-5.4.0/drivers/soc/tegra/Kconfig @@ -130,6 +130,7 @@ config SOC_TEGRA_PMC bool + select GENERIC_PINCONF config SOC_TEGRA_POWERGATE_BPMP def_bool y --- linux-oracle-5.4.0.orig/drivers/soc/tegra/fuse/fuse-tegra.c +++ linux-oracle-5.4.0/drivers/soc/tegra/fuse/fuse-tegra.c @@ -172,7 +172,7 @@ }; builtin_platform_driver(tegra_fuse_driver); -bool __init tegra_fuse_read_spare(unsigned int spare) +u32 __init tegra_fuse_read_spare(unsigned int spare) { unsigned int offset = fuse->soc->info->spare + spare * 4; --- linux-oracle-5.4.0.orig/drivers/soc/tegra/fuse/fuse-tegra30.c +++ linux-oracle-5.4.0/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -35,7 +35,9 @@ defined(CONFIG_ARCH_TEGRA_124_SOC) || \ defined(CONFIG_ARCH_TEGRA_132_SOC) || \ defined(CONFIG_ARCH_TEGRA_210_SOC) || \ - defined(CONFIG_ARCH_TEGRA_186_SOC) + defined(CONFIG_ARCH_TEGRA_186_SOC) || \ + defined(CONFIG_ARCH_TEGRA_194_SOC) || \ + defined(CONFIG_ARCH_TEGRA_234_SOC) static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) { if (WARN_ON(!fuse->base)) --- linux-oracle-5.4.0.orig/drivers/soc/tegra/fuse/fuse.h +++ linux-oracle-5.4.0/drivers/soc/tegra/fuse/fuse.h @@ -53,7 +53,7 @@ void tegra_init_revision(void); void tegra_init_apbmisc(void); -bool __init tegra_fuse_read_spare(unsigned int spare); +u32 __init tegra_fuse_read_spare(unsigned int spare); u32 __init tegra_fuse_read_early(unsigned int offset); #ifdef CONFIG_ARCH_TEGRA_2x_SOC --- linux-oracle-5.4.0.orig/drivers/soc/tegra/fuse/speedo-tegra210.c +++ linux-oracle-5.4.0/drivers/soc/tegra/fuse/speedo-tegra210.c @@ -94,7 +94,7 @@ unsigned int i; for (i = 0; i < num; i++) - if (value < speedos[num]) + if (value < speedos[i]) return i; return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ linux-oracle-5.4.0/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -123,7 +123,7 @@ apbmisc.flags = IORESOURCE_MEM; /* strapping options */ - if (tegra_get_chip_id() == TEGRA124) { + if (of_machine_is_compatible("nvidia,tegra124")) { straps.start = 0x7000e864; straps.end = 0x7000e867; } else { --- linux-oracle-5.4.0.orig/drivers/soc/tegra/pmc.c +++ linux-oracle-5.4.0/drivers/soc/tegra/pmc.c @@ -579,7 +579,7 @@ err = tegra_powergate_enable_clocks(pg); if (err) - goto disable_clks; + goto powergate_off; usleep_range(10, 20); @@ -591,7 +591,7 @@ err = reset_control_deassert(pg->reset); if (err) - goto powergate_off; + goto disable_clks; usleep_range(10, 20); @@ -1899,6 +1899,20 @@ event->id, &pmc->irq, pmc); + /* + * GPIOs don't have an equivalent interrupt in the + * parent controller (GIC). However some code, such + * as the one in irq_get_irqchip_state(), require a + * valid IRQ chip to be set. Make sure that's the + * case by passing NULL here, which will install a + * dummy IRQ chip for the interrupt in the parent + * domain. + */ + if (domain->parent) + irq_domain_set_hwirq_and_chip(domain->parent, + virq, 0, NULL, + NULL); + break; } } @@ -1908,10 +1922,22 @@ * dummy hardware IRQ number. This is used in the ->irq_set_type() * and ->irq_set_wake() callbacks to return early for these IRQs. */ - if (i == soc->num_wake_events) + if (i == soc->num_wake_events) { err = irq_domain_set_hwirq_and_chip(domain, virq, ULONG_MAX, &pmc->irq, pmc); + /* + * Interrupts without a wake event don't have a corresponding + * interrupt in the parent controller (GIC). Pass NULL for the + * chip here, which causes a dummy IRQ chip to be installed + * for the interrupt in the parent domain, to make this + * explicit. + */ + if (domain->parent) + irq_domain_set_hwirq_and_chip(domain->parent, virq, 0, + NULL, NULL); + } + return err; } --- linux-oracle-5.4.0.orig/drivers/soc/ti/knav_dma.c +++ linux-oracle-5.4.0/drivers/soc/ti/knav_dma.c @@ -759,8 +759,9 @@ pm_runtime_enable(kdev->dev); ret = pm_runtime_get_sync(kdev->dev); if (ret < 0) { + pm_runtime_put_noidle(kdev->dev); dev_err(kdev->dev, "unable to enable pktdma, err %d\n", ret); - return ret; + goto err_pm_disable; } /* Initialise all packet dmas */ @@ -774,7 +775,8 @@ if (list_empty(&kdev->list)) { dev_err(dev, "no valid dma instance\n"); - return -ENODEV; + ret = -ENODEV; + goto err_put_sync; } debugfs_create_file("knav_dma", S_IFREG | S_IRUGO, NULL, NULL, @@ -782,6 +784,13 @@ device_ready = true; return ret; + +err_put_sync: + pm_runtime_put_sync(kdev->dev); +err_pm_disable: + pm_runtime_disable(kdev->dev); + + return ret; } static int knav_dma_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/soc/ti/knav_qmss_queue.c +++ linux-oracle-5.4.0/drivers/soc/ti/knav_qmss_queue.c @@ -64,7 +64,7 @@ * Newest followed by older ones. Search is done from start of the array * until a firmware file is found. */ -const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"}; +static const char * const knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"}; static bool device_ready; bool knav_qmss_device_ready(void) @@ -1789,8 +1789,9 @@ INIT_LIST_HEAD(&kdev->pdsps); pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { + pm_runtime_disable(&pdev->dev); dev_err(dev, "Failed to enable QMSS\n"); return ret; } @@ -1858,9 +1859,10 @@ if (ret) goto err; - regions = of_get_child_by_name(node, "descriptor-regions"); + regions = of_get_child_by_name(node, "descriptor-regions"); if (!regions) { dev_err(dev, "descriptor-regions not specified\n"); + ret = -ENODEV; goto err; } ret = knav_queue_setup_regions(kdev, regions); --- linux-oracle-5.4.0.orig/drivers/soc/ti/wkup_m3_ipc.c +++ linux-oracle-5.4.0/drivers/soc/ti/wkup_m3_ipc.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -151,7 +150,6 @@ static int wkup_m3_ping(struct wkup_m3_ipc *m3_ipc) { struct device *dev = m3_ipc->dev; - mbox_msg_t dummy_msg = 0; int ret; if (!m3_ipc->mbox) { @@ -167,7 +165,7 @@ * the RX callback to avoid multiple interrupts being received * by the CM3. */ - ret = mbox_send_message(m3_ipc->mbox, &dummy_msg); + ret = mbox_send_message(m3_ipc->mbox, NULL); if (ret < 0) { dev_err(dev, "%s: mbox_send_message() failed: %d\n", __func__, ret); @@ -189,7 +187,6 @@ static int wkup_m3_ping_noirq(struct wkup_m3_ipc *m3_ipc) { struct device *dev = m3_ipc->dev; - mbox_msg_t dummy_msg = 0; int ret; if (!m3_ipc->mbox) { @@ -198,7 +195,7 @@ return -EIO; } - ret = mbox_send_message(m3_ipc->mbox, &dummy_msg); + ret = mbox_send_message(m3_ipc->mbox, NULL); if (ret < 0) { dev_err(dev, "%s: mbox_send_message() failed: %d\n", __func__, ret); @@ -419,6 +416,8 @@ ret = rproc_boot(m3_ipc->rproc); if (ret) dev_err(dev, "rproc_boot failed\n"); + else + m3_ipc_state = m3_ipc; do_exit(0); } @@ -445,9 +444,9 @@ } irq = platform_get_irq(pdev, 0); - if (!irq) { + if (irq < 0) { dev_err(&pdev->dev, "no irq resource\n"); - return -ENXIO; + return irq; } ret = devm_request_irq(dev, irq, wkup_m3_txev_handler, @@ -505,8 +504,6 @@ goto err_put_rproc; } - m3_ipc_state = m3_ipc; - return 0; err_put_rproc: --- linux-oracle-5.4.0.orig/drivers/soc/ux500/ux500-soc-id.c +++ linux-oracle-5.4.0/drivers/soc/ux500/ux500-soc-id.c @@ -159,20 +159,18 @@ static const char *db8500_read_soc_id(struct device_node *backupram) { void __iomem *base; - void __iomem *uid; const char *retstr; + u32 uid[5]; base = of_iomap(backupram, 0); if (!base) return NULL; - uid = base + 0x1fc0; + memcpy_fromio(uid, base + 0x1fc0, sizeof(uid)); /* Throw these device-specific numbers into the entropy pool */ - add_device_randomness(uid, 0x14); + add_device_randomness(uid, sizeof(uid)); retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", - readl((u32 *)uid+0), - readl((u32 *)uid+1), readl((u32 *)uid+2), - readl((u32 *)uid+3), readl((u32 *)uid+4)); + uid[0], uid[1], uid[2], uid[3], uid[4]); iounmap(base); return retstr; } --- linux-oracle-5.4.0.orig/drivers/soc/versatile/soc-integrator.c +++ linux-oracle-5.4.0/drivers/soc/versatile/soc-integrator.c @@ -111,6 +111,7 @@ return -ENODEV; syscon_regmap = syscon_node_to_regmap(np); + of_node_put(np); if (IS_ERR(syscon_regmap)) return PTR_ERR(syscon_regmap); --- linux-oracle-5.4.0.orig/drivers/soc/versatile/soc-realview.c +++ linux-oracle-5.4.0/drivers/soc/versatile/soc-realview.c @@ -4,6 +4,7 @@ * * Author: Linus Walleij */ +#include #include #include #include @@ -79,6 +80,13 @@ static struct device_attribute realview_build_attr = __ATTR(build, S_IRUGO, realview_get_build, NULL); +static void realview_soc_socdev_release(void *data) +{ + struct soc_device *soc_dev = data; + + soc_device_unregister(soc_dev); +} + static int realview_soc_probe(struct platform_device *pdev) { struct regmap *syscon_regmap; @@ -91,7 +99,7 @@ if (IS_ERR(syscon_regmap)) return PTR_ERR(syscon_regmap); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; @@ -103,10 +111,14 @@ soc_dev_attr->machine = "RealView"; soc_dev_attr->family = "Versatile"; soc_dev = soc_device_register(soc_dev_attr); - if (IS_ERR(soc_dev)) { - kfree(soc_dev_attr); + if (IS_ERR(soc_dev)) return -ENODEV; - } + + ret = devm_add_action_or_reset(&pdev->dev, realview_soc_socdev_release, + soc_dev); + if (ret) + return ret; + ret = regmap_read(syscon_regmap, REALVIEW_SYS_ID_OFFSET, &realview_coreid); if (ret) --- linux-oracle-5.4.0.orig/drivers/soc/xilinx/Kconfig +++ linux-oracle-5.4.0/drivers/soc/xilinx/Kconfig @@ -19,7 +19,7 @@ config ZYNQMP_POWER bool "Enable Xilinx Zynq MPSoC Power Management driver" - depends on PM && ARCH_ZYNQMP + depends on PM && ZYNQMP_FIRMWARE default y help Say yes to enable power management support for ZyqnMP SoC. @@ -31,7 +31,7 @@ config ZYNQMP_PM_DOMAINS bool "Enable Zynq MPSoC generic PM domains" default y - depends on PM && ARCH_ZYNQMP && ZYNQMP_FIRMWARE + depends on PM && ZYNQMP_FIRMWARE select PM_GENERIC_DOMAINS help Say yes to enable device power management through PM domains --- linux-oracle-5.4.0.orig/drivers/soundwire/bus.c +++ linux-oracle-5.4.0/drivers/soundwire/bus.c @@ -113,6 +113,8 @@ struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_bus *bus = slave->bus; + pm_runtime_disable(dev); + sdw_slave_debugfs_exit(slave); mutex_lock(&bus->bus_lock); @@ -523,7 +525,7 @@ struct sdw_slave *slave, *_s; struct sdw_slave_id id; struct sdw_msg msg; - bool found = false; + bool found; int count = 0, ret; u64 addr; @@ -555,6 +557,7 @@ sdw_extract_slave_id(bus, addr, &id); + found = false; /* Now compare with entries */ list_for_each_entry_safe(slave, _s, &bus->slaves, node) { if (sdw_compare_devid(slave, id) == 0) { --- linux-oracle-5.4.0.orig/drivers/soundwire/bus_type.c +++ linux-oracle-5.4.0/drivers/soundwire/bus_type.c @@ -155,12 +155,8 @@ drv->driver.owner = owner; drv->driver.probe = sdw_drv_probe; - - if (drv->remove) - drv->driver.remove = sdw_drv_remove; - - if (drv->shutdown) - drv->driver.shutdown = sdw_drv_shutdown; + drv->driver.remove = sdw_drv_remove; + drv->driver.shutdown = sdw_drv_shutdown; return driver_register(&drv->driver); } --- linux-oracle-5.4.0.orig/drivers/soundwire/cadence_master.c +++ linux-oracle-5.4.0/drivers/soundwire/cadence_master.c @@ -183,9 +183,6 @@ #define CDNS_DEFAULT_SSP_INTERVAL 0x18 #define CDNS_TX_TIMEOUT 2000 -#define CDNS_PCM_PDI_OFFSET 0x2 -#define CDNS_PDM_PDI_OFFSET 0x6 - #define CDNS_SCP_RX_FIFOLEVEL 0x2 /* @@ -232,6 +229,22 @@ } /* + * all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL + * need to be confirmed with a write to MCP_CONFIG_UPDATE + */ +static int cdns_update_config(struct sdw_cdns *cdns) +{ + int ret; + + ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE, + CDNS_MCP_CONFIG_UPDATE_BIT); + if (ret < 0) + dev_err(cdns->dev, "Config update timedout\n"); + + return ret; +} + +/* * debugfs */ #ifdef CONFIG_DEBUG_FS @@ -279,11 +292,7 @@ ret += scnprintf(buf + ret, RD_BUF - ret, "\nDPn B0 Registers\n"); - /* - * in sdw_cdns_pdi_init() we filter out the Bulk PDIs, - * so the indices need to be corrected again - */ - num_ports = cdns->num_ports + CDNS_PCM_PDI_OFFSET; + num_ports = cdns->num_ports; for (i = 0; i < num_ports; i++) { ret += scnprintf(buf + ret, RD_BUF - ret, @@ -352,10 +361,10 @@ if (!(cdns->response_buf[i] & CDNS_MCP_RESP_ACK)) { no_ack = 1; dev_dbg_ratelimited(cdns->dev, "Msg Ack not received\n"); - if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) { - nack = 1; - dev_err_ratelimited(cdns->dev, "Msg NACK received\n"); - } + } + if (cdns->response_buf[i] & CDNS_MCP_RESP_NACK) { + nack = 1; + dev_err_ratelimited(cdns->dev, "Msg NACK received\n"); } } @@ -752,7 +761,38 @@ /* * init routines */ -static int _cdns_enable_interrupt(struct sdw_cdns *cdns) + +/** + * sdw_cdns_exit_reset() - Program reset parameters and start bus operations + * @cdns: Cadence instance + */ +int sdw_cdns_exit_reset(struct sdw_cdns *cdns) +{ + /* program maximum length reset to be safe */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, + CDNS_MCP_CONTROL_RST_DELAY, + CDNS_MCP_CONTROL_RST_DELAY); + + /* use hardware generated reset */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, + CDNS_MCP_CONTROL_HW_RST, + CDNS_MCP_CONTROL_HW_RST); + + /* enable bus operations with clock and data */ + cdns_updatel(cdns, CDNS_MCP_CONFIG, + CDNS_MCP_CONFIG_OP, + CDNS_MCP_CONFIG_OP_NORMAL); + + /* commit changes */ + return cdns_update_config(cdns); +} +EXPORT_SYMBOL(sdw_cdns_exit_reset); + +/** + * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config + * @cdns: Cadence instance + */ +int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns) { u32 mask; @@ -784,24 +824,8 @@ cdns_writel(cdns, CDNS_MCP_INTMASK, mask); - return 0; -} - -/** - * sdw_cdns_enable_interrupt() - Enable SDW interrupts and update config - * @cdns: Cadence instance - */ -int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns) -{ - int ret; - - _cdns_enable_interrupt(cdns); - ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE, - CDNS_MCP_CONFIG_UPDATE_BIT); - if (ret < 0) - dev_err(cdns->dev, "Config update timedout\n"); - - return ret; + /* commit changes */ + return cdns_update_config(cdns); } EXPORT_SYMBOL(sdw_cdns_enable_interrupt); @@ -821,7 +845,6 @@ for (i = 0; i < num; i++) { pdi[i].num = i + pdi_offset; - pdi[i].assigned = false; } *stream = pdi; @@ -838,7 +861,8 @@ struct sdw_cdns_stream_config config) { struct sdw_cdns_streams *stream; - int offset, i, ret; + int offset; + int ret; cdns->pcm.num_bd = config.pcm_bd; cdns->pcm.num_in = config.pcm_in; @@ -850,11 +874,8 @@ /* Allocate PDIs for PCMs */ stream = &cdns->pcm; - /* First two PDIs are reserved for bulk transfers */ - if (stream->num_bd < CDNS_PCM_PDI_OFFSET) - return -EINVAL; - stream->num_bd -= CDNS_PCM_PDI_OFFSET; - offset = CDNS_PCM_PDI_OFFSET; + /* we allocate PDI0 and PDI1 which are used for Bulk */ + offset = 0; ret = cdns_allocate_pdi(cdns, &stream->bd, stream->num_bd, offset); @@ -881,7 +902,6 @@ /* Allocate PDIs for PDMs */ stream = &cdns->pdm; - offset = CDNS_PDM_PDI_OFFSET; ret = cdns_allocate_pdi(cdns, &stream->bd, stream->num_bd, offset); if (ret) @@ -898,6 +918,9 @@ ret = cdns_allocate_pdi(cdns, &stream->out, stream->num_out, offset); + + offset += stream->num_out; + if (ret) return ret; @@ -905,18 +928,6 @@ stream->num_pdi = stream->num_bd + stream->num_in + stream->num_out; cdns->num_ports += stream->num_pdi; - cdns->ports = devm_kcalloc(cdns->dev, cdns->num_ports, - sizeof(*cdns->ports), GFP_KERNEL); - if (!cdns->ports) { - ret = -ENOMEM; - return ret; - } - - for (i = 0; i < cdns->num_ports; i++) { - cdns->ports[i].assigned = false; - cdns->ports[i].num = i + 1; /* Port 0 reserved for bulk */ - } - return 0; } EXPORT_SYMBOL(sdw_cdns_pdi_init); @@ -975,6 +986,10 @@ cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL); cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL); + /* flush command FIFOs */ + cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_RST, + CDNS_MCP_CONTROL_CMD_RST); + /* Set cmd accept mode */ cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, CDNS_MCP_CONTROL_CMD_ACCEPT); @@ -997,13 +1012,10 @@ /* Set cmd mode for Tx and Rx cmds */ val &= ~CDNS_MCP_CONFIG_CMD; - /* Set operation to normal */ - val &= ~CDNS_MCP_CONFIG_OP; - val |= CDNS_MCP_CONFIG_OP_NORMAL; - cdns_writel(cdns, CDNS_MCP_CONFIG, val); - return 0; + /* commit changes */ + return cdns_update_config(cdns); } EXPORT_SYMBOL(sdw_cdns_init); @@ -1185,20 +1197,20 @@ * @num: Number of PDIs * @pdi: PDI instances * - * Find and return a free PDI for a given PDI array + * Find a PDI for a given PDI array. The PDI num and dai_id are + * expected to match, return NULL otherwise. */ static struct sdw_cdns_pdi *cdns_find_pdi(struct sdw_cdns *cdns, + unsigned int offset, unsigned int num, - struct sdw_cdns_pdi *pdi) + struct sdw_cdns_pdi *pdi, + int dai_id) { int i; - for (i = 0; i < num; i++) { - if (pdi[i].assigned) - continue; - pdi[i].assigned = true; - return &pdi[i]; - } + for (i = offset; i < offset + num; i++) + if (pdi[i].num == dai_id) + return &pdi[i]; return NULL; } @@ -1207,13 +1219,11 @@ * sdw_cdns_config_stream: Configure a stream * * @cdns: Cadence instance - * @port: Cadence data port * @ch: Channel count * @dir: Data direction * @pdi: PDI to be used */ void sdw_cdns_config_stream(struct sdw_cdns *cdns, - struct sdw_cdns_port *port, u32 ch, u32 dir, struct sdw_cdns_pdi *pdi) { u32 offset, val = 0; @@ -1221,113 +1231,51 @@ if (dir == SDW_DATA_DIR_RX) val = CDNS_PORTCTRL_DIRN; - offset = CDNS_PORTCTRL + port->num * CDNS_PORT_OFFSET; + offset = CDNS_PORTCTRL + pdi->num * CDNS_PORT_OFFSET; cdns_updatel(cdns, offset, CDNS_PORTCTRL_DIRN, val); - val = port->num; + val = pdi->num; val |= ((1 << ch) - 1) << SDW_REG_SHIFT(CDNS_PDI_CONFIG_CHANNEL); cdns_writel(cdns, CDNS_PDI_CONFIG(pdi->num), val); } EXPORT_SYMBOL(sdw_cdns_config_stream); /** - * cdns_get_num_pdi() - Get number of PDIs required - * - * @cdns: Cadence instance - * @pdi: PDI to be used - * @num: Number of PDIs - * @ch_count: Channel count - */ -static int cdns_get_num_pdi(struct sdw_cdns *cdns, - struct sdw_cdns_pdi *pdi, - unsigned int num, u32 ch_count) -{ - int i, pdis = 0; - - for (i = 0; i < num; i++) { - if (pdi[i].assigned) - continue; - - if (pdi[i].ch_count < ch_count) - ch_count -= pdi[i].ch_count; - else - ch_count = 0; - - pdis++; - - if (!ch_count) - break; - } - - if (ch_count) - return 0; - - return pdis; -} - -/** - * sdw_cdns_get_stream() - Get stream information + * sdw_cdns_alloc_pdi() - Allocate a PDI * * @cdns: Cadence instance * @stream: Stream to be allocated * @ch: Channel count * @dir: Data direction */ -int sdw_cdns_get_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - u32 ch, u32 dir) -{ - int pdis = 0; - - if (dir == SDW_DATA_DIR_RX) - pdis = cdns_get_num_pdi(cdns, stream->in, stream->num_in, ch); - else - pdis = cdns_get_num_pdi(cdns, stream->out, stream->num_out, ch); - - /* check if we found PDI, else find in bi-directional */ - if (!pdis) - pdis = cdns_get_num_pdi(cdns, stream->bd, stream->num_bd, ch); - - return pdis; -} -EXPORT_SYMBOL(sdw_cdns_get_stream); - -/** - * sdw_cdns_alloc_stream() - Allocate a stream - * - * @cdns: Cadence instance - * @stream: Stream to be allocated - * @port: Cadence data port - * @ch: Channel count - * @dir: Data direction - */ -int sdw_cdns_alloc_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - struct sdw_cdns_port *port, u32 ch, u32 dir) +struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, + struct sdw_cdns_streams *stream, + u32 ch, u32 dir, int dai_id) { struct sdw_cdns_pdi *pdi = NULL; if (dir == SDW_DATA_DIR_RX) - pdi = cdns_find_pdi(cdns, stream->num_in, stream->in); + pdi = cdns_find_pdi(cdns, 0, stream->num_in, stream->in, + dai_id); else - pdi = cdns_find_pdi(cdns, stream->num_out, stream->out); + pdi = cdns_find_pdi(cdns, 0, stream->num_out, stream->out, + dai_id); /* check if we found a PDI, else find in bi-directional */ if (!pdi) - pdi = cdns_find_pdi(cdns, stream->num_bd, stream->bd); - - if (!pdi) - return -EIO; + pdi = cdns_find_pdi(cdns, 0, stream->num_bd, stream->bd, + dai_id); - port->pdi = pdi; - pdi->l_ch_num = 0; - pdi->h_ch_num = ch - 1; - pdi->dir = dir; - pdi->ch_count = ch; + if (pdi) { + pdi->l_ch_num = 0; + pdi->h_ch_num = ch - 1; + pdi->dir = dir; + pdi->ch_count = ch; + } - return 0; + return pdi; } -EXPORT_SYMBOL(sdw_cdns_alloc_stream); +EXPORT_SYMBOL(sdw_cdns_alloc_pdi); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Cadence Soundwire Library"); --- linux-oracle-5.4.0.orig/drivers/soundwire/cadence_master.h +++ linux-oracle-5.4.0/drivers/soundwire/cadence_master.h @@ -8,7 +8,6 @@ /** * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance * - * @assigned: pdi assigned * @num: pdi number * @intel_alh_id: link identifier * @l_ch_num: low channel for PDI @@ -18,7 +17,6 @@ * @type: stream type, PDM or PCM */ struct sdw_cdns_pdi { - bool assigned; int num; int intel_alh_id; int l_ch_num; @@ -29,23 +27,6 @@ }; /** - * struct sdw_cdns_port: Cadence port structure - * - * @num: port number - * @assigned: port assigned - * @ch: channel count - * @direction: data port direction - * @pdi: pdi for this port - */ -struct sdw_cdns_port { - unsigned int num; - bool assigned; - unsigned int ch; - enum sdw_data_direction direction; - struct sdw_cdns_pdi *pdi; -}; - -/** * struct sdw_cdns_streams: Cadence stream data structure * * @num_bd: number of bidirectional streams @@ -95,8 +76,8 @@ * struct sdw_cdns_dma_data: Cadence DMA data * * @name: SoundWire stream name - * @nr_ports: Number of ports - * @port: Ports + * @stream: stream runtime + * @pdi: PDI used for this dai * @bus: Bus handle * @stream_type: Stream type * @link_id: Master link id @@ -104,8 +85,7 @@ struct sdw_cdns_dma_data { char *name; struct sdw_stream_runtime *stream; - int nr_ports; - struct sdw_cdns_port **port; + struct sdw_cdns_pdi *pdi; struct sdw_bus *bus; enum sdw_stream_type stream_type; int link_id; @@ -161,6 +141,7 @@ int sdw_cdns_init(struct sdw_cdns *cdns); int sdw_cdns_pdi_init(struct sdw_cdns *cdns, struct sdw_cdns_stream_config config); +int sdw_cdns_exit_reset(struct sdw_cdns *cdns); int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns); #ifdef CONFIG_DEBUG_FS @@ -170,10 +151,10 @@ int sdw_cdns_get_stream(struct sdw_cdns *cdns, struct sdw_cdns_streams *stream, u32 ch, u32 dir); -int sdw_cdns_alloc_stream(struct sdw_cdns *cdns, - struct sdw_cdns_streams *stream, - struct sdw_cdns_port *port, u32 ch, u32 dir); -void sdw_cdns_config_stream(struct sdw_cdns *cdns, struct sdw_cdns_port *port, +struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, + struct sdw_cdns_streams *stream, + u32 ch, u32 dir, int dai_id); +void sdw_cdns_config_stream(struct sdw_cdns *cdns, u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); int sdw_cdns_pcm_set_stream(struct snd_soc_dai *dai, --- linux-oracle-5.4.0.orig/drivers/soundwire/intel.c +++ linux-oracle-5.4.0/drivers/soundwire/intel.c @@ -479,7 +479,10 @@ unsigned int link_id = sdw->instance; int pdi_conf = 0; - pdi->intel_alh_id = (link_id * 16) + pdi->num + 5; + /* the Bulk and PCM streams are not contiguous */ + pdi->intel_alh_id = (link_id * 16) + pdi->num + 3; + if (pdi->num >= 2) + pdi->intel_alh_id += 2; /* * Program stream parameters to stream SHIM register @@ -508,7 +511,10 @@ unsigned int link_id = sdw->instance; unsigned int conf; - pdi->intel_alh_id = (link_id * 16) + pdi->num + 5; + /* the Bulk and PCM streams are not contiguous */ + pdi->intel_alh_id = (link_id * 16) + pdi->num + 3; + if (pdi->num >= 2) + pdi->intel_alh_id += 2; /* Program Stream config ALH register */ conf = intel_readl(alh, SDW_ALH_STRMZCFG(pdi->intel_alh_id)); @@ -603,66 +609,6 @@ * DAI routines */ -static struct sdw_cdns_port *intel_alloc_port(struct sdw_intel *sdw, - u32 ch, u32 dir, bool pcm) -{ - struct sdw_cdns *cdns = &sdw->cdns; - struct sdw_cdns_port *port = NULL; - int i, ret = 0; - - for (i = 0; i < cdns->num_ports; i++) { - if (cdns->ports[i].assigned) - continue; - - port = &cdns->ports[i]; - port->assigned = true; - port->direction = dir; - port->ch = ch; - break; - } - - if (!port) { - dev_err(cdns->dev, "Unable to find a free port\n"); - return NULL; - } - - if (pcm) { - ret = sdw_cdns_alloc_stream(cdns, &cdns->pcm, port, ch, dir); - if (ret) - goto out; - - intel_pdi_shim_configure(sdw, port->pdi); - sdw_cdns_config_stream(cdns, port, ch, dir, port->pdi); - - intel_pdi_alh_configure(sdw, port->pdi); - - } else { - ret = sdw_cdns_alloc_stream(cdns, &cdns->pdm, port, ch, dir); - } - -out: - if (ret) { - port->assigned = false; - port = NULL; - } - - return port; -} - -static void intel_port_cleanup(struct sdw_cdns_dma_data *dma) -{ - int i; - - for (i = 0; i < dma->nr_ports; i++) { - if (dma->port[i]) { - dma->port[i]->pdi->assigned = false; - dma->port[i]->pdi = NULL; - dma->port[i]->assigned = false; - dma->port[i] = NULL; - } - } -} - static int intel_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -670,9 +616,11 @@ struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); struct sdw_intel *sdw = cdns_to_intel(cdns); struct sdw_cdns_dma_data *dma; + struct sdw_cdns_pdi *pdi; struct sdw_stream_config sconfig; struct sdw_port_config *pconfig; - int ret, i, ch, dir; + int ch, dir; + int ret; bool pcm = true; dma = snd_soc_dai_get_dma_data(dai, substream); @@ -685,38 +633,30 @@ else dir = SDW_DATA_DIR_TX; - if (dma->stream_type == SDW_STREAM_PDM) { - /* TODO: Check whether PDM decimator is already in use */ - dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pdm, ch, dir); + if (dma->stream_type == SDW_STREAM_PDM) pcm = false; - } else { - dma->nr_ports = sdw_cdns_get_stream(cdns, &cdns->pcm, ch, dir); - } - if (!dma->nr_ports) { - dev_err(dai->dev, "ports/resources not available\n"); - return -EINVAL; + if (pcm) + pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, ch, dir, dai->id); + else + pdi = sdw_cdns_alloc_pdi(cdns, &cdns->pdm, ch, dir, dai->id); + + if (!pdi) { + ret = -EINVAL; + goto error; } - dma->port = kcalloc(dma->nr_ports, sizeof(*dma->port), GFP_KERNEL); - if (!dma->port) - return -ENOMEM; + /* do run-time configurations for SHIM, ALH and PDI/PORT */ + intel_pdi_shim_configure(sdw, pdi); + intel_pdi_alh_configure(sdw, pdi); + sdw_cdns_config_stream(cdns, ch, dir, pdi); - for (i = 0; i < dma->nr_ports; i++) { - dma->port[i] = intel_alloc_port(sdw, ch, dir, pcm); - if (!dma->port[i]) { - ret = -EINVAL; - goto port_error; - } - } /* Inform DSP about PDI stream number */ - for (i = 0; i < dma->nr_ports; i++) { - ret = intel_config_stream(sdw, substream, dai, params, - dma->port[i]->pdi->intel_alh_id); - if (ret) - goto port_error; - } + ret = intel_config_stream(sdw, substream, dai, params, + pdi->intel_alh_id); + if (ret) + goto error; sconfig.direction = dir; sconfig.ch_count = ch; @@ -731,32 +671,22 @@ } /* Port configuration */ - pconfig = kcalloc(dma->nr_ports, sizeof(*pconfig), GFP_KERNEL); + pconfig = kcalloc(1, sizeof(*pconfig), GFP_KERNEL); if (!pconfig) { ret = -ENOMEM; - goto port_error; + goto error; } - for (i = 0; i < dma->nr_ports; i++) { - pconfig[i].num = dma->port[i]->num; - pconfig[i].ch_mask = (1 << ch) - 1; - } + pconfig->num = pdi->num; + pconfig->ch_mask = (1 << ch) - 1; ret = sdw_stream_add_master(&cdns->bus, &sconfig, - pconfig, dma->nr_ports, dma->stream); - if (ret) { + pconfig, 1, dma->stream); + if (ret) dev_err(cdns->dev, "add master to stream failed:%d\n", ret); - goto stream_error; - } kfree(pconfig); - return ret; - -stream_error: - kfree(pconfig); -port_error: - intel_port_cleanup(dma); - kfree(dma->port); +error: return ret; } @@ -776,8 +706,6 @@ dev_err(dai->dev, "remove master from stream %s failed: %d\n", dma->stream->name, ret); - intel_port_cleanup(dma); - kfree(dma->port); return ret; } @@ -836,8 +764,9 @@ /* TODO: Read supported rates/formats from hardware */ for (i = off; i < (off + num); i++) { - dais[i].name = kasprintf(GFP_KERNEL, "SDW%d Pin%d", - cdns->instance, i); + dais[i].name = devm_kasprintf(cdns->dev, GFP_KERNEL, + "SDW%d Pin%d", + cdns->instance, i); if (!dais[i].name) return -ENOMEM; @@ -1043,8 +972,6 @@ if (ret) goto err_init; - ret = sdw_cdns_enable_interrupt(&sdw->cdns); - /* Read the PDI config and initialize cadence PDI */ intel_pdi_init(sdw, &config); ret = sdw_cdns_pdi_init(&sdw->cdns, config); @@ -1062,6 +989,18 @@ goto err_init; } + ret = sdw_cdns_enable_interrupt(&sdw->cdns); + if (ret < 0) { + dev_err(sdw->cdns.dev, "cannot enable interrupts\n"); + goto err_init; + } + + ret = sdw_cdns_exit_reset(&sdw->cdns); + if (ret < 0) { + dev_err(sdw->cdns.dev, "unable to exit bus reset sequence\n"); + goto err_init; + } + /* Register DAIs */ ret = intel_register_dai(sdw); if (ret) { --- linux-oracle-5.4.0.orig/drivers/soundwire/intel_init.c +++ linux-oracle-5.4.0/drivers/soundwire/intel_init.c @@ -178,8 +178,6 @@ return AE_NOT_FOUND; } - res->handle = handle; - /* * On some Intel platforms, multiple children of the HDAS * device can be found, but only one of them is the SoundWire @@ -190,6 +188,9 @@ if ((adr & GENMASK(31, 28)) >> 28 != SDW_LINK_TYPE) return AE_OK; /* keep going */ + /* found the correct SoundWire controller */ + res->handle = handle; + /* device found, stop namespace walk */ return AE_CTRL_TERMINATE; } --- linux-oracle-5.4.0.orig/drivers/soundwire/slave.c +++ linux-oracle-5.4.0/drivers/soundwire/slave.c @@ -57,6 +57,8 @@ list_del(&slave->node); mutex_unlock(&bus->bus_lock); put_device(&slave->dev); + + return ret; } sdw_slave_debugfs_init(slave); --- linux-oracle-5.4.0.orig/drivers/soundwire/stream.c +++ linux-oracle-5.4.0/drivers/soundwire/stream.c @@ -420,7 +420,6 @@ struct completion *port_ready; struct sdw_dpn_prop *dpn_prop; struct sdw_prepare_ch prep_ch; - unsigned int time_left; bool intr = false; int ret = 0, val; u32 addr; @@ -477,15 +476,15 @@ /* Wait for completion on port ready */ port_ready = &s_rt->slave->port_ready[prep_ch.num]; - time_left = wait_for_completion_timeout(port_ready, - msecs_to_jiffies(dpn_prop->ch_prep_timeout)); + wait_for_completion_timeout(port_ready, + msecs_to_jiffies(dpn_prop->ch_prep_timeout)); val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); - val &= p_rt->ch_mask; - if (!time_left || val) { + if ((val < 0) || (val & p_rt->ch_mask)) { + ret = (val < 0) ? val : -ETIMEDOUT; dev_err(&s_rt->slave->dev, - "Chn prep failed for port:%d\n", prep_ch.num); - return -ETIMEDOUT; + "Chn prep failed for port %d: %d\n", prep_ch.num, ret); + return ret; } } @@ -702,6 +701,7 @@ kfree(wbuf); error_1: kfree(wr_msg); + bus->defer_msg.msg = NULL; return ret; } @@ -709,14 +709,15 @@ * sdw_ml_sync_bank_switch: Multilink register bank switch * * @bus: SDW bus instance + * @multi_link: whether this is a multi-link stream with hardware-based sync * * Caller function should free the buffers on error */ -static int sdw_ml_sync_bank_switch(struct sdw_bus *bus) +static int sdw_ml_sync_bank_switch(struct sdw_bus *bus, bool multi_link) { unsigned long time_left; - if (!bus->multi_link) + if (!multi_link) return 0; /* Wait for completion of transfer */ @@ -809,7 +810,7 @@ bus->bank_switch_timeout = DEFAULT_BANK_SWITCH_TIMEOUT; /* Check if bank switch was successful */ - ret = sdw_ml_sync_bank_switch(bus); + ret = sdw_ml_sync_bank_switch(bus, multi_link); if (ret < 0) { dev_err(bus->dev, "multi link bank switch failed: %d\n", ret); @@ -825,9 +826,10 @@ error: list_for_each_entry(m_rt, &stream->master_list, stream_node) { bus = m_rt->bus; - - kfree(bus->defer_msg.msg->buf); - kfree(bus->defer_msg.msg); + if (bus->defer_msg.msg) { + kfree(bus->defer_msg.msg->buf); + kfree(bus->defer_msg.msg); + } } msg_unlock: @@ -1355,8 +1357,16 @@ } ret = sdw_config_stream(&slave->dev, stream, stream_config, true); - if (ret) + if (ret) { + /* + * sdw_release_master_stream will release s_rt in slave_rt_list in + * stream_error case, but s_rt is only added to slave_rt_list + * when sdw_config_stream is successful, so free s_rt explicitly + * when sdw_config_stream is failed. + */ + kfree(s_rt); goto stream_error; + } list_add_tail(&s_rt->m_rt_node, &m_rt->slave_rt_list); --- linux-oracle-5.4.0.orig/drivers/spi/Kconfig +++ linux-oracle-5.4.0/drivers/spi/Kconfig @@ -280,6 +280,15 @@ This controller does not support generic SPI messages. It only supports the high-level SPI memory interface. +config SPI_HISI_SFC_V3XX + tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets" + depends on (ARM64 && ACPI) || COMPILE_TEST + depends on HAS_IOMEM + select CONFIG_MTD_SPI_NOR + help + This enables support for HiSilicon v3xx SPI-NOR flash controller + found in hi16xx chipsets. + config SPI_NXP_FLEXSPI tristate "NXP Flex SPI controller" depends on ARCH_LAYERSCAPE || HAS_IOMEM @@ -865,6 +874,7 @@ config SPI_ZYNQ_QSPI tristate "Xilinx Zynq QSPI controller" depends on ARCH_ZYNQ || COMPILE_TEST + depends on SPI_MEM help This enables support for the Zynq Quad SPI controller in master mode. @@ -944,4 +954,7 @@ endif # SPI_SLAVE +config SPI_DYNAMIC + def_bool ACPI || OF_DYNAMIC || SPI_SLAVE + endif # SPI --- linux-oracle-5.4.0.orig/drivers/spi/Makefile +++ linux-oracle-5.4.0/drivers/spi/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_FSL_QUADSPI) += spi-fsl-qspi.o obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o obj-$(CONFIG_SPI_GPIO) += spi-gpio.o +obj-$(CONFIG_SPI_HISI_SFC_V3XX) += spi-hisi-sfc-v3xx.o obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o obj-$(CONFIG_SPI_IMX) += spi-imx.o obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o --- linux-oracle-5.4.0.orig/drivers/spi/atmel-quadspi.c +++ linux-oracle-5.4.0/drivers/spi/atmel-quadspi.c @@ -149,6 +149,7 @@ struct clk *qspick; struct platform_device *pdev; const struct atmel_qspi_caps *caps; + resource_size_t mmap_size; u32 pending; u32 mr; u32 scr; @@ -201,6 +202,9 @@ static bool atmel_qspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op) { + if (!spi_mem_default_supports_op(mem, op)) + return false; + if (atmel_qspi_find_mode(op) < 0) return false; @@ -283,10 +287,14 @@ if (dummy_cycles) ifr |= QSPI_IFR_NBDUM(dummy_cycles); - /* Set data enable */ - if (op->data.nbytes) + /* Set data enable and data transfer type. */ + if (op->data.nbytes) { ifr |= QSPI_IFR_DATAEN; + if (op->addr.nbytes) + ifr |= QSPI_IFR_TFRTYP_MEM; + } + /* * If the QSPI controller is set in regular SPI mode, set it in * Serial Memory Mode (SMM). @@ -311,7 +319,7 @@ writel_relaxed(icr, aq->regs + QSPI_WICR); writel_relaxed(ifr, aq->regs + QSPI_IFR); } else { - if (op->data.dir == SPI_MEM_DATA_OUT) + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) ifr |= QSPI_IFR_SAMA5D2_WRITE_TRSFR; /* Set QSPI Instruction Frame registers */ @@ -329,6 +337,14 @@ u32 sr, offset; int err; + /* + * Check if the address exceeds the MMIO window size. An improvement + * would be to add support for regular SPI mode and fall back to it + * when the flash memories overrun the controller's memory space. + */ + if (op->addr.val + op->data.nbytes > aq->mmap_size) + return -ENOTSUPP; + err = atmel_qspi_set_cfg(aq, op, &offset); if (err) return err; @@ -445,7 +461,7 @@ struct resource *res; int irq, err = 0; - ctrl = spi_alloc_master(&pdev->dev, sizeof(*aq)); + ctrl = devm_spi_alloc_master(&pdev->dev, sizeof(*aq)); if (!ctrl) return -ENOMEM; @@ -467,8 +483,7 @@ aq->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(aq->regs)) { dev_err(&pdev->dev, "missing registers\n"); - err = PTR_ERR(aq->regs); - goto exit; + return PTR_ERR(aq->regs); } /* Map the AHB memory */ @@ -476,10 +491,11 @@ aq->mem = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(aq->mem)) { dev_err(&pdev->dev, "missing AHB memory\n"); - err = PTR_ERR(aq->mem); - goto exit; + return PTR_ERR(aq->mem); } + aq->mmap_size = resource_size(res); + /* Get the peripheral clock */ aq->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(aq->pclk)) @@ -487,22 +503,21 @@ if (IS_ERR(aq->pclk)) { dev_err(&pdev->dev, "missing peripheral clock\n"); - err = PTR_ERR(aq->pclk); - goto exit; + return PTR_ERR(aq->pclk); } /* Enable the peripheral clock */ err = clk_prepare_enable(aq->pclk); if (err) { dev_err(&pdev->dev, "failed to enable the peripheral clock\n"); - goto exit; + return err; } aq->caps = of_device_get_match_data(&pdev->dev); if (!aq->caps) { dev_err(&pdev->dev, "Could not retrieve QSPI caps\n"); err = -EINVAL; - goto exit; + goto disable_pclk; } if (aq->caps->has_qspick) { @@ -546,8 +561,6 @@ clk_disable_unprepare(aq->qspick); disable_pclk: clk_disable_unprepare(aq->pclk); -exit: - spi_controller_put(ctrl); return err; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-armada-3700.c +++ linux-oracle-5.4.0/drivers/spi/spi-armada-3700.c @@ -906,7 +906,7 @@ return 0; error_clk: - clk_disable_unprepare(spi->clk); + clk_unprepare(spi->clk); error: spi_master_put(master); out: --- linux-oracle-5.4.0.orig/drivers/spi/spi-ath79.c +++ linux-oracle-5.4.0/drivers/spi/spi-ath79.c @@ -156,8 +156,7 @@ master->use_gpio_descriptors = true; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); - master->setup = spi_bitbang_setup; - master->cleanup = spi_bitbang_cleanup; + master->flags = SPI_MASTER_GPIO_SS; if (pdata) { master->bus_num = pdata->bus_num; master->num_chipselect = pdata->num_chipselect; --- linux-oracle-5.4.0.orig/drivers/spi/spi-atmel.c +++ linux-oracle-5.4.0/drivers/spi/spi-atmel.c @@ -302,7 +302,6 @@ bool use_cs_gpios; bool keep_cs; - bool cs_active; u32 fifo_size; }; @@ -1183,10 +1182,8 @@ as = spi_master_get_devdata(spi->master); /* see notes above re chipselect */ - if (!atmel_spi_is_v2(as) - && spi->chip_select == 0 - && (spi->mode & SPI_CS_HIGH)) { - dev_dbg(&spi->dev, "setup: can't be active-high\n"); + if (!as->use_cs_gpios && (spi->mode & SPI_CS_HIGH)) { + dev_warn(&spi->dev, "setup: non GPIO CS can't be active-high\n"); return -EINVAL; } @@ -1376,11 +1373,9 @@ &msg->transfers)) { as->keep_cs = true; } else { - as->cs_active = !as->cs_active; - if (as->cs_active) - cs_activate(as, msg->spi); - else - cs_deactivate(as, msg->spi); + cs_deactivate(as, msg->spi); + udelay(10); + cs_activate(as, msg->spi); } } @@ -1403,7 +1398,6 @@ atmel_spi_lock(as); cs_activate(as, spi); - as->cs_active = true; as->keep_cs = false; msg->status = 0; @@ -1575,7 +1569,7 @@ if (ret == 0) { as->use_dma = true; } else if (ret == -EPROBE_DEFER) { - return ret; + goto out_unmap_regs; } } else if (as->caps.has_pdc_support) { as->use_pdc = true; --- linux-oracle-5.4.0.orig/drivers/spi/spi-bcm-qspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-bcm-qspi.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include "spi-bcm-qspi.h" @@ -509,7 +509,7 @@ u32 rd = 0; u32 wr = 0; - if (qspi->base[CHIP_SELECT]) { + if (cs >= 0 && qspi->base[CHIP_SELECT]) { rd = bcm_qspi_read(qspi, CHIP_SELECT, 0); wr = (rd & ~0xff) | (1 << cs); if (rd == wr) @@ -670,7 +670,7 @@ if (buf) buf[tp.byte] = read_rxram_slot_u8(qspi, slot); dev_dbg(&qspi->pdev->dev, "RD %02x\n", - buf ? buf[tp.byte] : 0xff); + buf ? buf[tp.byte] : 0x0); } else { u16 *buf = tp.trans->rx_buf; @@ -678,7 +678,7 @@ buf[tp.byte / 2] = read_rxram_slot_u16(qspi, slot); dev_dbg(&qspi->pdev->dev, "RD %04x\n", - buf ? buf[tp.byte] : 0xffff); + buf ? buf[tp.byte / 2] : 0x0); } update_qspi_trans_byte_count(qspi, &tp, @@ -733,13 +733,13 @@ while (!tstatus && slot < MSPI_NUM_CDRAM) { if (tp.trans->bits_per_word <= 8) { const u8 *buf = tp.trans->tx_buf; - u8 val = buf ? buf[tp.byte] : 0xff; + u8 val = buf ? buf[tp.byte] : 0x00; write_txram_slot_u8(qspi, slot, val); dev_dbg(&qspi->pdev->dev, "WR %02x\n", val); } else { const u16 *buf = tp.trans->tx_buf; - u16 val = buf ? buf[tp.byte / 2] : 0xffff; + u16 val = buf ? buf[tp.byte / 2] : 0x0000; write_txram_slot_u16(qspi, slot, val); dev_dbg(&qspi->pdev->dev, "WR %04x\n", val); @@ -960,7 +960,7 @@ addr = op->addr.val; len = op->data.nbytes; - if (bcm_qspi_bspi_ver_three(qspi) == true) { + if (has_bspi(qspi) && bcm_qspi_bspi_ver_three(qspi) == true) { /* * The address coming into this function is a raw flash offset. * But for BSPI <= V3, we need to convert it to a remapped BSPI @@ -976,10 +976,10 @@ /* non-aligned and very short transfers are handled by MSPI */ if (!IS_ALIGNED((uintptr_t)addr, 4) || !IS_ALIGNED((uintptr_t)buf, 4) || - len < 4) + len < 4 || op->cmd.opcode == SPINOR_OP_RDSFDP) mspi_read = true; - if (mspi_read) + if (!has_bspi(qspi) || mspi_read) return bcm_qspi_mspi_exec_mem_op(spi, op); ret = bcm_qspi_bspi_set_mode(qspi, op, 0); @@ -1213,13 +1213,18 @@ if (!of_match_node(bcm_qspi_of_match, dev->of_node)) return -ENODEV; - master = spi_alloc_master(dev, sizeof(struct bcm_qspi)); + master = devm_spi_alloc_master(dev, sizeof(struct bcm_qspi)); if (!master) { dev_err(dev, "error allocating spi_master\n"); return -ENOMEM; } qspi = spi_master_get_devdata(master); + + qspi->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(qspi->clk)) + return PTR_ERR(qspi->clk); + qspi->pdev = pdev; qspi->trans_pos.trans = NULL; qspi->trans_pos.byte = 0; @@ -1245,23 +1250,15 @@ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mspi"); - if (res) { - qspi->base[MSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[MSPI])) { - ret = PTR_ERR(qspi->base[MSPI]); - goto qspi_resource_err; - } - } else { - goto qspi_resource_err; - } + qspi->base[MSPI] = devm_ioremap_resource(dev, res); + if (IS_ERR(qspi->base[MSPI])) + return PTR_ERR(qspi->base[MSPI]); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bspi"); if (res) { qspi->base[BSPI] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[BSPI])) { - ret = PTR_ERR(qspi->base[BSPI]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[BSPI])) + return PTR_ERR(qspi->base[BSPI]); qspi->bspi_mode = true; } else { qspi->bspi_mode = false; @@ -1272,18 +1269,14 @@ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cs_reg"); if (res) { qspi->base[CHIP_SELECT] = devm_ioremap_resource(dev, res); - if (IS_ERR(qspi->base[CHIP_SELECT])) { - ret = PTR_ERR(qspi->base[CHIP_SELECT]); - goto qspi_resource_err; - } + if (IS_ERR(qspi->base[CHIP_SELECT])) + return PTR_ERR(qspi->base[CHIP_SELECT]); } qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), GFP_KERNEL); - if (!qspi->dev_ids) { - ret = -ENOMEM; - goto qspi_resource_err; - } + if (!qspi->dev_ids) + return -ENOMEM; for (val = 0; val < num_irqs; val++) { irq = -1; @@ -1303,7 +1296,7 @@ &qspi->dev_ids[val]); if (ret < 0) { dev_err(&pdev->dev, "IRQ %s not found\n", name); - goto qspi_probe_err; + goto qspi_unprepare_err; } qspi->dev_ids[val].dev = qspi; @@ -1318,7 +1311,7 @@ if (!num_ints) { dev_err(&pdev->dev, "no IRQs registered, cannot init driver\n"); ret = -EINVAL; - goto qspi_probe_err; + goto qspi_unprepare_err; } /* @@ -1332,13 +1325,6 @@ qspi->soc_intc = NULL; } - qspi->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(qspi->clk)) { - dev_warn(dev, "unable to get clock\n"); - ret = PTR_ERR(qspi->clk); - goto qspi_probe_err; - } - ret = clk_prepare_enable(qspi->clk); if (ret) { dev_err(dev, "failed to prepare clock\n"); @@ -1359,7 +1345,7 @@ qspi->xfer_mode.addrlen = -1; qspi->xfer_mode.hp = -1; - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret < 0) { dev_err(dev, "can't register master\n"); goto qspi_reg_err; @@ -1369,11 +1355,10 @@ qspi_reg_err: bcm_qspi_hw_uninit(qspi); +qspi_unprepare_err: clk_disable_unprepare(qspi->clk); qspi_probe_err: kfree(qspi->dev_ids); -qspi_resource_err: - spi_master_put(master); return ret; } /* probe function to be called by SoC specific platform driver probe */ @@ -1383,10 +1368,10 @@ { struct bcm_qspi *qspi = platform_get_drvdata(pdev); + spi_unregister_master(qspi->master); bcm_qspi_hw_uninit(qspi); clk_disable_unprepare(qspi->clk); kfree(qspi->dev_ids); - spi_unregister_master(qspi->master); return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-bcm2835.c +++ linux-oracle-5.4.0/drivers/spi/spi-bcm2835.c @@ -68,7 +68,7 @@ #define BCM2835_SPI_FIFO_SIZE 64 #define BCM2835_SPI_FIFO_SIZE_3_4 48 #define BCM2835_SPI_DMA_MIN_LENGTH 96 -#define BCM2835_SPI_NUM_CS 3 /* raise as necessary */ +#define BCM2835_SPI_NUM_CS 24 /* raise as necessary */ #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS | SPI_3WIRE) @@ -1159,10 +1159,14 @@ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); /* if an error occurred and we have an active dma, then terminate */ - dmaengine_terminate_sync(ctlr->dma_tx); - bs->tx_dma_active = false; - dmaengine_terminate_sync(ctlr->dma_rx); - bs->rx_dma_active = false; + if (ctlr->dma_tx) { + dmaengine_terminate_sync(ctlr->dma_tx); + bs->tx_dma_active = false; + } + if (ctlr->dma_rx) { + dmaengine_terminate_sync(ctlr->dma_rx); + bs->rx_dma_active = false; + } bcm2835_spi_undo_prologue(bs); /* and reset */ @@ -1179,9 +1183,14 @@ struct spi_controller *ctlr = spi->controller; struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct gpio_chip *chip; - enum gpio_lookup_flags lflags; u32 cs; + if (spi->chip_select >= BCM2835_SPI_NUM_CS) { + dev_err(&spi->dev, "only %d chip-selects supported\n", + BCM2835_SPI_NUM_CS - 1); + return -EINVAL; + } + /* * Precalculate SPI slave's CS register value for ->prepare_message(): * The driver always uses software-controlled GPIO chip select, hence @@ -1245,21 +1254,9 @@ if (!chip) return 0; - /* - * Retrieve the corresponding GPIO line used for CS. - * The inversion semantics will be handled by the GPIO core - * code, so we pass GPIOS_OUT_LOW for "unasserted" and - * the correct flag for inversion semantics. The SPI_CS_HIGH - * on spi->mode cannot be checked for polarity in this case - * as the flag use_gpio_descriptors enforces SPI_CS_HIGH. - */ - if (of_property_read_bool(spi->dev.of_node, "spi-cs-high")) - lflags = GPIO_ACTIVE_HIGH; - else - lflags = GPIO_ACTIVE_LOW; spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select, DRV_NAME, - lflags, + GPIO_LOOKUP_FLAGS_DEFAULT, GPIOD_OUT_LOW); if (IS_ERR(spi->cs_gpiod)) return PTR_ERR(spi->cs_gpiod); @@ -1277,7 +1274,7 @@ struct bcm2835_spi *bs; int err; - ctlr = spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs), + ctlr = devm_spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs), dma_get_cache_alignment())); if (!ctlr) return -ENOMEM; @@ -1287,7 +1284,7 @@ ctlr->use_gpio_descriptors = true; ctlr->mode_bits = BCM2835_SPI_MODE_BITS; ctlr->bits_per_word_mask = SPI_BPW_MASK(8); - ctlr->num_chipselect = BCM2835_SPI_NUM_CS; + ctlr->num_chipselect = 3; ctlr->setup = bcm2835_spi_setup; ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->handle_err = bcm2835_spi_handle_err; @@ -1297,23 +1294,19 @@ bs = spi_controller_get_devdata(ctlr); bs->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(bs->regs)) { - err = PTR_ERR(bs->regs); - goto out_controller_put; - } + if (IS_ERR(bs->regs)) + return PTR_ERR(bs->regs); bs->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(bs->clk)) { err = PTR_ERR(bs->clk); dev_err(&pdev->dev, "could not get clk: %d\n", err); - goto out_controller_put; + return err; } bs->irq = platform_get_irq(pdev, 0); - if (bs->irq <= 0) { - err = bs->irq ? bs->irq : -ENODEV; - goto out_controller_put; - } + if (bs->irq <= 0) + return bs->irq ? bs->irq : -ENODEV; clk_prepare_enable(bs->clk); @@ -1327,24 +1320,23 @@ dev_name(&pdev->dev), ctlr); if (err) { dev_err(&pdev->dev, "could not request IRQ: %d\n", err); - goto out_clk_disable; + goto out_dma_release; } - err = devm_spi_register_controller(&pdev->dev, ctlr); + err = spi_register_controller(ctlr); if (err) { dev_err(&pdev->dev, "could not register SPI controller: %d\n", err); - goto out_clk_disable; + goto out_dma_release; } bcm2835_debugfs_create(bs, dev_name(&pdev->dev)); return 0; -out_clk_disable: +out_dma_release: + bcm2835_dma_release(ctlr, bs); clk_disable_unprepare(bs->clk); -out_controller_put: - spi_controller_put(ctlr); return err; } @@ -1355,6 +1347,8 @@ bcm2835_debugfs_remove(bs); + spi_unregister_controller(ctlr); + /* Clear FIFOs, and disable the HW block */ bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); --- linux-oracle-5.4.0.orig/drivers/spi/spi-bcm2835aux.c +++ linux-oracle-5.4.0/drivers/spi/spi-bcm2835aux.c @@ -494,7 +494,7 @@ unsigned long clk_hz; int err; - master = spi_alloc_master(&pdev->dev, sizeof(*bs)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs)); if (!master) return -ENOMEM; @@ -524,29 +524,25 @@ /* the main area */ bs->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(bs->regs)) { - err = PTR_ERR(bs->regs); - goto out_master_put; - } + if (IS_ERR(bs->regs)) + return PTR_ERR(bs->regs); bs->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(bs->clk)) { err = PTR_ERR(bs->clk); dev_err(&pdev->dev, "could not get clk: %d\n", err); - goto out_master_put; + return err; } bs->irq = platform_get_irq(pdev, 0); - if (bs->irq <= 0) { - err = bs->irq ? bs->irq : -ENODEV; - goto out_master_put; - } + if (bs->irq <= 0) + return bs->irq ? bs->irq : -ENODEV; /* this also enables the HW block */ err = clk_prepare_enable(bs->clk); if (err) { dev_err(&pdev->dev, "could not prepare clock: %d\n", err); - goto out_master_put; + return err; } /* just checking if the clock returns a sane value */ @@ -569,7 +565,7 @@ goto out_clk_disable; } - err = devm_spi_register_master(&pdev->dev, master); + err = spi_register_master(master); if (err) { dev_err(&pdev->dev, "could not register SPI master: %d\n", err); goto out_clk_disable; @@ -581,8 +577,6 @@ out_clk_disable: clk_disable_unprepare(bs->clk); -out_master_put: - spi_master_put(master); return err; } @@ -593,6 +587,8 @@ bcm2835aux_debugfs_remove(bs); + spi_unregister_master(master); + bcm2835aux_spi_reset_hw(bs); /* disable the HW block by releasing the clock */ --- linux-oracle-5.4.0.orig/drivers/spi/spi-bcm63xx-hsspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-bcm63xx-hsspi.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #define HSSPI_GLOBAL_CTRL_REG 0x0 #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 @@ -161,6 +163,7 @@ int step_size = HSSPI_BUFFER_LEN; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; + u32 val = 0; bcm63xx_hsspi_set_clk(bs, spi, t->speed_hz); bcm63xx_hsspi_set_cs(bs, spi->chip_select, true); @@ -176,11 +179,16 @@ step_size -= HSSPI_OPCODE_LEN; if ((opcode == HSSPI_OP_READ && t->rx_nbits == SPI_NBITS_DUAL) || - (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) + (opcode == HSSPI_OP_WRITE && t->tx_nbits == SPI_NBITS_DUAL)) { opcode |= HSSPI_OP_MULTIBIT; - __raw_writel(1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT | - 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT | 0xff, + if (t->rx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT; + if (t->tx_nbits == SPI_NBITS_DUAL) + val |= 1 << MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT; + } + + __raw_writel(val | 0xff, bs->regs + HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); while (pending > 0) { @@ -367,7 +375,6 @@ goto out_disable_clk; rate = clk_get_rate(pll_clk); - clk_disable_unprepare(pll_clk); if (!rate) { ret = -EINVAL; goto out_disable_pll_clk; @@ -429,13 +436,17 @@ if (ret) goto out_put_master; + pm_runtime_enable(&pdev->dev); + /* register and we are done */ ret = devm_spi_register_master(dev, master); if (ret) - goto out_put_master; + goto out_pm_disable; return 0; +out_pm_disable: + pm_runtime_disable(&pdev->dev); out_put_master: spi_master_put(master); out_disable_pll_clk: @@ -484,8 +495,10 @@ if (bs->pll_clk) { ret = clk_prepare_enable(bs->pll_clk); - if (ret) + if (ret) { + clk_disable_unprepare(bs->clk); return ret; + } } spi_master_resume(master); --- linux-oracle-5.4.0.orig/drivers/spi/spi-bcm63xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-bcm63xx.c @@ -125,7 +125,7 @@ SPI_MSG_DATA_SIZE, }; -#define BCM63XX_SPI_MAX_PREPEND 15 +#define BCM63XX_SPI_MAX_PREPEND 7 #define BCM63XX_SPI_MAX_CS 8 #define BCM63XX_SPI_BUS_NUM 0 @@ -475,12 +475,14 @@ { }, }; +MODULE_DEVICE_TABLE(platform, bcm63xx_spi_dev_match); static const struct of_device_id bcm63xx_spi_of_match[] = { { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets }, { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets }, { }, }; +MODULE_DEVICE_TABLE(of, bcm63xx_spi_of_match); static int bcm63xx_spi_probe(struct platform_device *pdev) { --- linux-oracle-5.4.0.orig/drivers/spi/spi-bitbang.c +++ linux-oracle-5.4.0/drivers/spi/spi-bitbang.c @@ -181,6 +181,8 @@ { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; + bool initial_setup = false; + int retval; bitbang = spi_master_get_devdata(spi->master); @@ -189,22 +191,30 @@ if (!cs) return -ENOMEM; spi->controller_state = cs; + initial_setup = true; } /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; - if (!cs->txrx_word) - return -EINVAL; + if (!cs->txrx_word) { + retval = -EINVAL; + goto err_free; + } if (bitbang->setup_transfer) { - int retval = bitbang->setup_transfer(spi, NULL); + retval = bitbang->setup_transfer(spi, NULL); if (retval < 0) - return retval; + goto err_free; } dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); return 0; + +err_free: + if (initial_setup) + kfree(cs); + return retval; } EXPORT_SYMBOL_GPL(spi_bitbang_setup); --- linux-oracle-5.4.0.orig/drivers/spi/spi-cadence.c +++ linux-oracle-5.4.0/drivers/spi/spi-cadence.c @@ -115,6 +115,7 @@ void __iomem *regs; struct clk *ref_clk; struct clk *pclk; + unsigned int clk_rate; u32 speed_hz; const u8 *txbuf; u8 *rxbuf; @@ -168,16 +169,16 @@ /** * cdns_spi_chipselect - Select or deselect the chip select line * @spi: Pointer to the spi_device structure - * @enable: Select (1) or deselect (0) the chip select line + * @is_high: Select(0) or deselect (1) the chip select line */ -static void cdns_spi_chipselect(struct spi_device *spi, bool enable) +static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) { struct cdns_spi *xspi = spi_master_get_devdata(spi->master); u32 ctrl_reg; ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); - if (!enable) { + if (is_high) { /* Deselect the slave */ ctrl_reg |= CDNS_SPI_CR_SSCTRL; } else { @@ -250,7 +251,7 @@ u32 ctrl_reg, baud_rate_val; unsigned long frequency; - frequency = clk_get_rate(xspi->ref_clk); + frequency = xspi->clk_rate; ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR); @@ -516,6 +517,12 @@ goto clk_dis_apb; } + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); if (ret < 0) master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; @@ -530,11 +537,6 @@ /* SPI controller initializations */ cdns_spi_init_hw(xspi); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); - irq = platform_get_irq(pdev, 0); if (irq <= 0) { ret = -ENXIO; @@ -558,12 +560,16 @@ master->auto_runtime_pm = true; master->mode_bits = SPI_CPOL | SPI_CPHA; + xspi->clk_rate = clk_get_rate(xspi->ref_clk); /* Set to default valid value */ - master->max_speed_hz = clk_get_rate(xspi->ref_clk) / 4; + master->max_speed_hz = xspi->clk_rate / 4; xspi->speed_hz = master->max_speed_hz; master->bits_per_word_mask = SPI_BPW_MASK(8); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); --- linux-oracle-5.4.0.orig/drivers/spi/spi-cavium-thunderx.c +++ linux-oracle-5.4.0/drivers/spi/spi-cavium-thunderx.c @@ -82,6 +82,7 @@ error: clk_disable_unprepare(p->clk); + pci_release_regions(pdev); spi_master_put(master); return ret; } @@ -96,6 +97,7 @@ return; clk_disable_unprepare(p->clk); + pci_release_regions(pdev); /* Put everything in a known state. */ writeq(0, p->register_base + OCTEON_SPI_CFG(p)); } --- linux-oracle-5.4.0.orig/drivers/spi/spi-davinci.c +++ linux-oracle-5.4.0/drivers/spi/spi-davinci.c @@ -1040,13 +1040,13 @@ spi_bitbang_stop(&dspi->bitbang); clk_disable_unprepare(dspi->clk); - spi_master_put(master); if (dspi->dma_rx) { dma_release_channel(dspi->dma_rx); dma_release_channel(dspi->dma_tx); } + spi_master_put(master); return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-dln2.c +++ linux-oracle-5.4.0/drivers/spi/spi-dln2.c @@ -780,7 +780,7 @@ static int dln2_spi_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct dln2_spi *dln2 = spi_master_get_devdata(master); pm_runtime_disable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/spi/spi-dw-mid.c +++ linux-oracle-5.4.0/drivers/spi/spi-dw-mid.c @@ -147,6 +147,7 @@ if (!xfer->tx_buf) return NULL; + memset(&txconf, 0, sizeof(txconf)); txconf.direction = DMA_MEM_TO_DEV; txconf.dst_addr = dws->dma_addr; txconf.dst_maxburst = 16; @@ -193,6 +194,7 @@ if (!xfer->rx_buf) return NULL; + memset(&rxconf, 0, sizeof(rxconf)); rxconf.direction = DMA_DEV_TO_MEM; rxconf.src_addr = dws->dma_addr; rxconf.src_maxburst = 16; @@ -218,19 +220,23 @@ static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer) { - u16 dma_ctrl = 0; + u16 imr = 0, dma_ctrl = 0; dw_writel(dws, DW_SPI_DMARDLR, 0xf); dw_writel(dws, DW_SPI_DMATDLR, 0x10); - if (xfer->tx_buf) + if (xfer->tx_buf) { dma_ctrl |= SPI_DMA_TDMAE; - if (xfer->rx_buf) + imr |= SPI_INT_TXOI; + } + if (xfer->rx_buf) { dma_ctrl |= SPI_DMA_RDMAE; + imr |= SPI_INT_RXUI | SPI_INT_RXOI; + } dw_writel(dws, DW_SPI_DMACR, dma_ctrl); /* Set the interrupt mask */ - spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI); + spi_umask_intr(dws, imr); dws->transfer_handler = dma_transfer; @@ -260,7 +266,7 @@ dma_async_issue_pending(dws->txchan); } - return 0; + return 1; } static void mid_spi_dma_stop(struct dw_spi *dws) --- linux-oracle-5.4.0.orig/drivers/spi/spi-dw.c +++ linux-oracle-5.4.0/drivers/spi/spi-dw.c @@ -128,11 +128,20 @@ { struct dw_spi *dws = spi_controller_get_devdata(spi->controller); struct chip_data *chip = spi_get_ctldata(spi); + bool cs_high = !!(spi->mode & SPI_CS_HIGH); + /* Chip select logic is inverted from spi_set_cs() */ if (chip && chip->cs_control) - chip->cs_control(enable); + chip->cs_control(!enable); - if (enable) + /* + * DW SPI controller demands any native CS being set in order to + * proceed with data transfer. So in order to activate the SPI + * communications we must set a corresponding bit in the Slave + * Enable register no matter whether the SPI core is configured to + * support active-high or active-low CS level. + */ + if (cs_high == enable) dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select)); else if (dws->cs_override) dw_writel(dws, DW_SPI_SER, 0); @@ -171,9 +180,11 @@ static void dw_writer(struct dw_spi *dws) { - u32 max = tx_max(dws); + u32 max; u16 txw = 0; + spin_lock(&dws->buf_lock); + max = tx_max(dws); while (max--) { /* Set the tx word if the transfer's original "tx" is not null */ if (dws->tx_end - dws->len) { @@ -185,13 +196,16 @@ dw_write_io_reg(dws, DW_SPI_DR, txw); dws->tx += dws->n_bytes; } + spin_unlock(&dws->buf_lock); } static void dw_reader(struct dw_spi *dws) { - u32 max = rx_max(dws); + u32 max; u16 rxw; + spin_lock(&dws->buf_lock); + max = rx_max(dws); while (max--) { rxw = dw_read_io_reg(dws, DW_SPI_DR); /* Care rx only if the transfer's original "rx" is not null */ @@ -203,6 +217,7 @@ } dws->rx += dws->n_bytes; } + spin_unlock(&dws->buf_lock); } static void int_error_stop(struct dw_spi *dws, const char *msg) @@ -275,18 +290,23 @@ { struct dw_spi *dws = spi_controller_get_devdata(master); struct chip_data *chip = spi_get_ctldata(spi); + unsigned long flags; u8 imask = 0; u16 txlevel = 0; u32 cr0; int ret; dws->dma_mapped = 0; - + spin_lock_irqsave(&dws->buf_lock, flags); dws->tx = (void *)transfer->tx_buf; dws->tx_end = dws->tx + transfer->len; dws->rx = transfer->rx_buf; dws->rx_end = dws->rx + transfer->len; dws->len = transfer->len; + spin_unlock_irqrestore(&dws->buf_lock, flags); + + /* Ensure dw->rx and dw->rx_end are visible */ + smp_mb(); spi_enable_chip(dws, 0); @@ -308,7 +328,8 @@ cr0 = (transfer->bits_per_word - 1) | (chip->type << SPI_FRF_OFFSET) | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) | - (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET)) + (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) | + (((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET)) | (chip->tmode << SPI_TMOD_OFFSET); /* @@ -360,11 +381,8 @@ spi_enable_chip(dws, 1); - if (dws->dma_mapped) { - ret = dws->dma_ops->dma_transfer(dws, transfer); - if (ret < 0) - return ret; - } + if (dws->dma_mapped) + return dws->dma_ops->dma_transfer(dws, transfer); if (chip->poll_mode) return poll_transfer(dws); @@ -469,6 +487,7 @@ dws->type = SSI_MOTO_SPI; dws->dma_inited = 0; dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); + spin_lock_init(&dws->buf_lock); spi_controller_set_devdata(master, dws); @@ -507,10 +526,11 @@ dws->dma_inited = 0; } else { master->can_dma = dws->dma_ops->can_dma; + master->flags |= SPI_CONTROLLER_MUST_TX; } } - ret = devm_spi_register_controller(dev, master); + ret = spi_register_controller(master); if (ret) { dev_err(&master->dev, "problem registering spi master\n"); goto err_dma_exit; @@ -534,6 +554,8 @@ { dw_spi_debugfs_remove(dws); + spi_unregister_controller(dws->master); + if (dws->dma_ops && dws->dma_ops->dma_exit) dws->dma_ops->dma_exit(dws); --- linux-oracle-5.4.0.orig/drivers/spi/spi-dw.h +++ linux-oracle-5.4.0/drivers/spi/spi-dw.h @@ -120,6 +120,7 @@ size_t len; void *tx; void *tx_end; + spinlock_t buf_lock; void *rx; void *rx_end; int dma_mapped; --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-cpm.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-cpm.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "spi-fsl-cpm.h" #include "spi-fsl-lib.h" @@ -120,6 +121,21 @@ mspi->rx_dma = mspi->dma_dummy_rx; mspi->map_rx_dma = 0; } + if (t->bits_per_word == 16 && t->tx_buf) { + const u16 *src = t->tx_buf; + u16 *dst; + int i; + + dst = kmalloc(t->len, GFP_KERNEL); + if (!dst) + return -ENOMEM; + + for (i = 0; i < t->len >> 1; i++) + dst[i] = cpu_to_le16p(src + i); + + mspi->tx = dst; + mspi->map_tx_dma = 1; + } if (mspi->map_tx_dma) { void *nonconst_tx = (void *)mspi->tx; /* shut up gcc */ @@ -173,6 +189,13 @@ if (mspi->map_rx_dma) dma_unmap_single(dev, mspi->rx_dma, t->len, DMA_FROM_DEVICE); mspi->xfer_in_progress = NULL; + + if (t->bits_per_word == 16 && t->rx_buf) { + int i; + + for (i = 0; i < t->len; i += 2) + le16_to_cpus(t->rx_buf + i); + } } EXPORT_SYMBOL_GPL(fsl_spi_cpm_bufs_complete); --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-dspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-dspi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ // // Copyright 2013 Freescale Semiconductor, Inc. +// Copyright 2020 NXP // // Freescale DSPI driver // This file contains a driver for the Freescale DSPI @@ -33,6 +34,9 @@ #define SPI_MCR_CLR_TXF BIT(11) #define SPI_MCR_CLR_RXF BIT(10) #define SPI_MCR_XSPI BIT(3) +#define SPI_MCR_DIS_TXF BIT(13) +#define SPI_MCR_DIS_RXF BIT(12) +#define SPI_MCR_HALT BIT(0) #define SPI_TCR 0x08 #define SPI_TCR_GET_TCNT(x) (((x) & GENMASK(31, 16)) >> 16) @@ -117,7 +121,6 @@ struct chip_data { u32 ctar_val; - u16 void_write_data; }; enum dspi_trans_mode { @@ -186,14 +189,12 @@ const void *tx; void *rx; void *rx_end; - u16 void_write_data; u16 tx_cmd; u8 bits_per_word; u8 bytes_per_word; const struct fsl_dspi_devtype_data *devtype_data; - wait_queue_head_t waitq; - u32 waitflags; + struct completion xfer_done; struct fsl_dspi_dma *dma; }; @@ -420,6 +421,7 @@ goto err_rx_dma_buf; } + memset(&cfg, 0, sizeof(cfg)); cfg.src_addr = phy_addr + SPI_POPR; cfg.dst_addr = phy_addr + SPI_PUSHR; cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -583,21 +585,14 @@ dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT; if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) { - /* Write two TX FIFO entries first, and then the corresponding - * CMD FIFO entry. + /* Write the CMD FIFO entry first, and then the two + * corresponding TX FIFO entries. */ u32 data = dspi_pop_tx(dspi); - if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE) { - /* LSB */ - tx_fifo_write(dspi, data & 0xFFFF); - tx_fifo_write(dspi, data >> 16); - } else { - /* MSB */ - tx_fifo_write(dspi, data >> 16); - tx_fifo_write(dspi, data & 0xFFFF); - } cmd_fifo_write(dspi); + tx_fifo_write(dspi, data & 0xFFFF); + tx_fifo_write(dspi, data >> 16); } else { /* Write one entry to both TX FIFO and CMD FIFO * simultaneously. @@ -710,10 +705,8 @@ if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))) return IRQ_NONE; - if (dspi_rxtx(dspi) == 0) { - dspi->waitflags = 1; - wake_up_interruptible(&dspi->waitq); - } + if (dspi_rxtx(dspi) == 0) + complete(&dspi->xfer_done); return IRQ_HANDLED; } @@ -753,8 +746,6 @@ dspi->tx_cmd |= SPI_PUSHR_CMD_CONT; } - dspi->void_write_data = dspi->cur_chip->void_write_data; - dspi->tx = transfer->tx_buf; dspi->rx = transfer->rx_buf; dspi->rx_end = dspi->rx + transfer->len; @@ -807,13 +798,9 @@ status = dspi_poll(dspi); } while (status == -EINPROGRESS); } else if (trans_mode != DSPI_DMA_MODE) { - status = wait_event_interruptible(dspi->waitq, - dspi->waitflags); - dspi->waitflags = 0; + wait_for_completion(&dspi->xfer_done); + reinit_completion(&dspi->xfer_done); } - if (status) - dev_err(&dspi->pdev->dev, - "Waiting for transfer to complete failed!\n"); if (transfer->delay_usecs) udelay(transfer->delay_usecs); @@ -829,7 +816,9 @@ static int dspi_setup(struct spi_device *spi) { struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller); + u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz); unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; + u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4); u32 cs_sck_delay = 0, sck_cs_delay = 0; struct fsl_dspi_platform_data *pdata; unsigned char pasc = 0, asc = 0; @@ -857,7 +846,18 @@ sck_cs_delay = pdata->sck_cs_delay; } - chip->void_write_data = 0; + /* Since tCSC and tASC apply to continuous transfers too, avoid SCK + * glitches of half a cycle by never allowing tCSC + tASC to go below + * half a SCK period. + */ + if (cs_sck_delay < quarter_period_ns) + cs_sck_delay = quarter_period_ns; + if (sck_cs_delay < quarter_period_ns) + sck_cs_delay = quarter_period_ns; + + dev_dbg(&spi->dev, + "DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n", + cs_sck_delay, sck_cs_delay); clkrate = clk_get_rate(dspi->clk); hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate); @@ -915,6 +915,8 @@ struct spi_controller *ctlr = dev_get_drvdata(dev); struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); + if (dspi->irq) + disable_irq(dspi->irq); spi_controller_suspend(ctlr); clk_disable_unprepare(dspi->clk); @@ -935,6 +937,8 @@ if (ret) return ret; spi_controller_resume(ctlr); + if (dspi->irq) + enable_irq(dspi->irq); return 0; } @@ -1122,21 +1126,21 @@ goto poll_mode; } - ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt, - IRQF_SHARED, pdev->name, dspi); + ret = request_threaded_irq(dspi->irq, dspi_interrupt, NULL, + IRQF_SHARED, pdev->name, dspi); if (ret < 0) { dev_err(&pdev->dev, "Unable to attach DSPI interrupt\n"); goto out_clk_put; } - init_waitqueue_head(&dspi->waitq); + init_completion(&dspi->xfer_done); poll_mode: if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) { ret = dspi_request_dma(dspi, res->start); if (ret < 0) { dev_err(&pdev->dev, "can't get dma channels\n"); - goto out_clk_put; + goto out_free_irq; } } @@ -1148,11 +1152,16 @@ ret = spi_register_controller(ctlr); if (ret != 0) { dev_err(&pdev->dev, "Problem registering DSPI ctlr\n"); - goto out_clk_put; + goto out_release_dma; } return ret; +out_release_dma: + dspi_release_dma(dspi); +out_free_irq: + if (dspi->irq) + free_irq(dspi->irq, dspi); out_clk_put: clk_disable_unprepare(dspi->clk); out_ctlr_put: @@ -1167,13 +1176,29 @@ struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr); /* Disconnect from the SPI framework */ + spi_unregister_controller(dspi->ctlr); + + /* Disable RX and TX */ + regmap_update_bits(dspi->regmap, SPI_MCR, + SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF, + SPI_MCR_DIS_TXF | SPI_MCR_DIS_RXF); + + /* Stop Running */ + regmap_update_bits(dspi->regmap, SPI_MCR, SPI_MCR_HALT, SPI_MCR_HALT); + dspi_release_dma(dspi); + if (dspi->irq) + free_irq(dspi->irq, dspi); clk_disable_unprepare(dspi->clk); - spi_unregister_controller(dspi->ctlr); return 0; } +static void dspi_shutdown(struct platform_device *pdev) +{ + dspi_remove(pdev); +} + static struct platform_driver fsl_dspi_driver = { .driver.name = DRIVER_NAME, .driver.of_match_table = fsl_dspi_dt_ids, @@ -1181,6 +1206,7 @@ .driver.pm = &dspi_pm, .probe = dspi_probe, .remove = dspi_remove, + .shutdown = dspi_shutdown, }; module_platform_driver(fsl_dspi_driver); --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-espi.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-espi.c @@ -555,13 +555,14 @@ static irqreturn_t fsl_espi_irq(s32 irq, void *context_data) { struct fsl_espi *espi = context_data; - u32 events; + u32 events, mask; spin_lock(&espi->lock); /* Get interrupt events(tx/rx) */ events = fsl_espi_read_reg(espi, ESPI_SPIE); - if (!events) { + mask = fsl_espi_read_reg(espi, ESPI_SPIM); + if (!(events & mask)) { spin_unlock(&espi->lock); return IRQ_NONE; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-lpspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-lpspi.c @@ -86,8 +86,6 @@ #define TCR_RXMSK BIT(19) #define TCR_TXMSK BIT(18) -static int clkdivs[] = {1, 2, 4, 8, 16, 32, 64, 128}; - struct lpspi_config { u8 bpw; u8 chip_select; @@ -207,7 +205,7 @@ spi_controller_get_devdata(controller); int ret; - ret = pm_runtime_get_sync(fsl_lpspi->dev); + ret = pm_runtime_resume_and_get(fsl_lpspi->dev); if (ret < 0) { dev_err(fsl_lpspi->dev, "failed to enable clock\n"); return ret; @@ -319,7 +317,7 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) { struct lpspi_config config = fsl_lpspi->config; - unsigned int perclk_rate, scldiv; + unsigned int perclk_rate, scldiv, div; u8 prescale; perclk_rate = clk_get_rate(fsl_lpspi->clk_per); @@ -330,16 +328,17 @@ return -EINVAL; } + div = DIV_ROUND_UP(perclk_rate, config.speed_hz); + for (prescale = 0; prescale < 8; prescale++) { - scldiv = perclk_rate / - (clkdivs[prescale] * config.speed_hz) - 2; + scldiv = div / (1 << prescale) - 2; if (scldiv < 256) { fsl_lpspi->config.prescale = prescale; break; } } - if (prescale == 8 && scldiv >= 256) + if (scldiv >= 256) return -EINVAL; writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16), @@ -862,6 +861,22 @@ fsl_lpspi->dev = &pdev->dev; fsl_lpspi->is_slave = is_slave; + controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); + controller->transfer_one = fsl_lpspi_transfer_one; + controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware; + controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware; + controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; + controller->dev.of_node = pdev->dev.of_node; + controller->bus_num = pdev->id; + controller->slave_abort = fsl_lpspi_slave_abort; + + ret = devm_spi_register_controller(&pdev->dev, controller); + if (ret < 0) { + dev_err(&pdev->dev, "spi_register_controller error.\n"); + goto out_controller_put; + } + if (!fsl_lpspi->is_slave) { for (i = 0; i < controller->num_chipselect; i++) { int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); @@ -885,16 +900,6 @@ controller->prepare_message = fsl_lpspi_prepare_message; } - controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); - controller->transfer_one = fsl_lpspi_transfer_one; - controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware; - controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware; - controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; - controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; - controller->dev.of_node = pdev->dev.of_node; - controller->bus_num = pdev->id; - controller->slave_abort = fsl_lpspi_slave_abort; - init_completion(&fsl_lpspi->xfer_done); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -938,7 +943,7 @@ ret = pm_runtime_get_sync(fsl_lpspi->dev); if (ret < 0) { dev_err(fsl_lpspi->dev, "failed to enable clock\n"); - return ret; + goto out_controller_put; } temp = readl(fsl_lpspi->base + IMX7ULP_PARAM); @@ -952,12 +957,6 @@ if (ret < 0) dev_err(&pdev->dev, "dma setup error %d, use pio\n", ret); - ret = devm_spi_register_controller(&pdev->dev, controller); - if (ret < 0) { - dev_err(&pdev->dev, "spi_register_controller error.\n"); - goto out_controller_put; - } - return 0; out_controller_put: @@ -973,9 +972,6 @@ spi_controller_get_devdata(controller); pm_runtime_disable(fsl_lpspi->dev); - - spi_master_put(controller); - return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-qspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-qspi.c @@ -63,6 +63,11 @@ #define QUADSPI_IPCR 0x08 #define QUADSPI_IPCR_SEQID(x) ((x) << 24) +#define QUADSPI_FLSHCR 0x0c +#define QUADSPI_FLSHCR_TCSS_MASK GENMASK(3, 0) +#define QUADSPI_FLSHCR_TCSH_MASK GENMASK(11, 8) +#define QUADSPI_FLSHCR_TDH_MASK GENMASK(17, 16) + #define QUADSPI_BUF3CR 0x1c #define QUADSPI_BUF3CR_ALLMST_MASK BIT(31) #define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8) @@ -95,6 +100,9 @@ #define QUADSPI_FR 0x160 #define QUADSPI_FR_TFF_MASK BIT(0) +#define QUADSPI_RSER 0x164 +#define QUADSPI_RSER_TFIE BIT(0) + #define QUADSPI_SPTRCLR 0x16c #define QUADSPI_SPTRCLR_IPPTRC BIT(8) #define QUADSPI_SPTRCLR_BFPTRC BIT(0) @@ -112,9 +120,6 @@ #define QUADSPI_LCKER_LOCK BIT(0) #define QUADSPI_LCKER_UNLOCK BIT(1) -#define QUADSPI_RSER 0x164 -#define QUADSPI_RSER_TFIE BIT(0) - #define QUADSPI_LUT_BASE 0x310 #define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) #define QUADSPI_LUT_REG(idx) \ @@ -181,6 +186,12 @@ */ #define QUADSPI_QUIRK_BASE_INTERNAL BIT(4) +/* + * Controller uses TDH bits in register QUADSPI_FLSHCR. + * They need to be set in accordance with the DDR/SDR mode. + */ +#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5) + struct fsl_qspi_devtype_data { unsigned int rxfifo; unsigned int txfifo; @@ -209,7 +220,8 @@ .rxfifo = SZ_128, .txfifo = SZ_512, .ahb_buf_size = SZ_1K, - .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING, .little_endian = true, }; @@ -217,7 +229,8 @@ .rxfifo = SZ_128, .txfifo = SZ_512, .ahb_buf_size = SZ_1K, - .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, + .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK | + QUADSPI_QUIRK_USE_TDH_SETTING, .little_endian = true, }; @@ -275,6 +288,11 @@ return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL); } +static inline int needs_tdh_setting(struct fsl_qspi *q) +{ + return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING; +} + /* * An IC bug makes it necessary to rearrange the 32-bit data. * Later chips, such as IMX6SLX, have fixed this bug. @@ -380,7 +398,7 @@ op->data.nbytes > q->devtype_data->txfifo) return false; - return true; + return spi_mem_default_supports_op(mem, op); } static void fsl_qspi_prepare_lut(struct fsl_qspi *q, @@ -710,6 +728,16 @@ qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, base + QUADSPI_MCR); + /* + * Previous boot stages (BootROM, bootloader) might have used DDR + * mode and did not clear the TDH bits. As we currently use SDR mode + * only, clear the TDH bits if necessary. + */ + if (needs_tdh_setting(q)) + qspi_writel(q, qspi_readl(q, base + QUADSPI_FLSHCR) & + ~QUADSPI_FLSHCR_TDH_MASK, + base + QUADSPI_FLSHCR); + reg = qspi_readl(q, base + QUADSPI_SMPR); qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK | QUADSPI_SMPR_FSPHS_MASK --- linux-oracle-5.4.0.orig/drivers/spi/spi-fsl-spi.c +++ linux-oracle-5.4.0/drivers/spi/spi-fsl-spi.c @@ -204,24 +204,6 @@ return bits_per_word; } -static int mspi_apply_qe_mode_quirks(struct spi_mpc8xxx_cs *cs, - struct spi_device *spi, - int bits_per_word) -{ - /* QE uses Little Endian for words > 8 - * so transform all words > 8 into 8 bits - * Unfortnatly that doesn't work for LSB so - * reject these for now */ - /* Note: 32 bits word, LSB works iff - * tfcr/rfcr is set to CPMFCR_GBL */ - if (spi->mode & SPI_LSB_FIRST && - bits_per_word > 8) - return -EINVAL; - if (bits_per_word > 8) - return 8; /* pretend its 8 bits */ - return bits_per_word; -} - static int fsl_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) { @@ -249,9 +231,6 @@ bits_per_word = mspi_apply_cpu_mode_quirks(cs, spi, mpc8xxx_spi, bits_per_word); - else if (mpc8xxx_spi->flags & SPI_QE) - bits_per_word = mspi_apply_qe_mode_quirks(cs, spi, - bits_per_word); if (bits_per_word < 0) return bits_per_word; @@ -369,14 +348,30 @@ * In CPU mode, optimize large byte transfers to use larger * bits_per_word values to reduce number of interrupts taken. */ - if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) { - list_for_each_entry(t, &m->transfers, transfer_list) { + list_for_each_entry(t, &m->transfers, transfer_list) { + if (!(mpc8xxx_spi->flags & SPI_CPM_MODE)) { if (t->len < 256 || t->bits_per_word != 8) continue; if ((t->len & 3) == 0) t->bits_per_word = 32; else if ((t->len & 1) == 0) t->bits_per_word = 16; + } else { + /* + * CPM/QE uses Little Endian for words > 8 + * so transform 16 and 32 bits words into 8 bits + * Unfortnatly that doesn't work for LSB so + * reject these for now + * Note: 32 bits word, LSB works iff + * tfcr/rfcr is set to CPMFCR_GBL + */ + if (m->spi->mode & SPI_LSB_FIRST && t->bits_per_word > 8) + return -EINVAL; + if (t->bits_per_word == 16 || t->bits_per_word == 32) + t->bits_per_word = 8; /* pretend its 8 bits */ + if (t->bits_per_word == 8 && t->len >= 256 && + (mpc8xxx_spi->flags & SPI_CPM1)) + t->bits_per_word = 16; } } @@ -442,6 +437,7 @@ { struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_spi_reg *reg_base; + bool initial_setup = false; int retval; u32 hw_mode; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); @@ -454,6 +450,7 @@ if (!cs) return -ENOMEM; spi_set_ctldata(spi, cs); + initial_setup = true; } mpc8xxx_spi = spi_master_get_devdata(spi->master); @@ -477,6 +474,8 @@ retval = fsl_spi_setup_transfer(spi, NULL); if (retval < 0) { cs->hw_mode = hw_mode; /* Restore settings */ + if (initial_setup) + kfree(cs); return retval; } @@ -612,6 +611,7 @@ master->setup = fsl_spi_setup; master->cleanup = fsl_spi_cleanup; master->transfer_one_message = fsl_spi_do_one_msg; + master->use_gpio_descriptors = true; mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi->max_bits_per_word = 32; @@ -630,8 +630,14 @@ if (mpc8xxx_spi->type == TYPE_GRLIB) fsl_spi_grlib_probe(dev); - master->bits_per_word_mask = - (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)) & + if (mpc8xxx_spi->flags & SPI_CPM_MODE) + master->bits_per_word_mask = + (SPI_BPW_RANGE_MASK(4, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32)); + else + master->bits_per_word_mask = + (SPI_BPW_RANGE_MASK(4, 16) | SPI_BPW_MASK(32)); + + master->bits_per_word_mask &= SPI_BPW_RANGE_MASK(1, mpc8xxx_spi->max_bits_per_word); if (mpc8xxx_spi->flags & SPI_QE_CPU_MODE) @@ -716,10 +722,11 @@ type = fsl_spi_get_type(&ofdev->dev); if (type == TYPE_FSL) { struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); + bool spisel_boot = false; #if IS_ENABLED(CONFIG_FSL_SOC) struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); - bool spisel_boot = of_property_read_bool(np, "fsl,spisel_boot"); + spisel_boot = of_property_read_bool(np, "fsl,spisel_boot"); if (spisel_boot) { pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4); if (!pinfo->immr_spi_cs) { @@ -728,17 +735,31 @@ } } #endif - - pdata->cs_control = fsl_spi_cs_control; + /* + * Handle the case where we have one hardwired (always selected) + * device on the first "chipselect". Else we let the core code + * handle any GPIOs or native chip selects and assign the + * appropriate callback for dealing with the CS lines. This isn't + * supported on the GRLIB variant. + */ + ret = gpiod_count(dev, "cs"); + if (ret < 0) + ret = 0; + if (ret == 0 && !spisel_boot) { + pdata->max_chipselect = 1; + } else { + pdata->max_chipselect = ret + spisel_boot; + pdata->cs_control = fsl_spi_cs_control; + } } ret = of_address_to_resource(np, 0, &mem); if (ret) goto err; - irq = irq_of_parse_and_map(np, 0); - if (!irq) { - ret = -EINVAL; + irq = platform_get_irq(ofdev, 0); + if (irq < 0) { + ret = irq; goto err; } @@ -751,7 +772,6 @@ return 0; err: - irq_dispose_mapping(irq); return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-geni-qcom.c +++ linux-oracle-5.4.0/drivers/spi/spi-geni-qcom.c @@ -32,7 +32,7 @@ #define CS_DEMUX_OUTPUT_SEL GENMASK(3, 0) #define SE_SPI_TRANS_CFG 0x25c -#define CS_TOGGLE BIT(0) +#define CS_TOGGLE BIT(1) #define SE_SPI_WORD_LEN 0x268 #define WORD_LEN_MSK GENMASK(9, 0) @@ -552,7 +552,7 @@ return PTR_ERR(clk); } - spi = spi_alloc_master(&pdev->dev, sizeof(*mas)); + spi = devm_spi_alloc_master(&pdev->dev, sizeof(*mas)); if (!spi) return -ENOMEM; @@ -599,7 +599,6 @@ free_irq(mas->irq, spi); spi_geni_probe_runtime_disable: pm_runtime_disable(&pdev->dev); - spi_master_put(spi); return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-gpio.c +++ linux-oracle-5.4.0/drivers/spi/spi-gpio.c @@ -244,9 +244,19 @@ if (output) return gpiod_direction_output(spi_gpio->mosi, 1); - ret = gpiod_direction_input(spi_gpio->mosi); - if (ret) - return ret; + /* + * Only change MOSI to an input if using 3WIRE mode. + * Otherwise, MOSI could be left floating if there is + * no pull resistor connected to the I/O pin, or could + * be left logic high if there is a pull-up. Transmitting + * logic high when only clocking MISO data in can put some + * SPI devices in to a bad state. + */ + if (spi->mode & SPI_3WIRE) { + ret = gpiod_direction_input(spi_gpio->mosi); + if (ret) + return ret; + } /* * Send a turnaround high impedance cycle when switching * from output to input. Theoretically there should be @@ -350,11 +360,6 @@ return 0; } -static void spi_gpio_put(void *data) -{ - spi_master_put(data); -} - static int spi_gpio_probe(struct platform_device *pdev) { int status; @@ -366,14 +371,10 @@ of_id = of_match_device(spi_gpio_dt_ids, &pdev->dev); - master = spi_alloc_master(dev, sizeof(*spi_gpio)); + master = devm_spi_alloc_master(dev, sizeof(*spi_gpio)); if (!master) return -ENOMEM; - status = devm_add_action_or_reset(&pdev->dev, spi_gpio_put, master); - if (status) - return status; - if (of_id) status = spi_gpio_probe_dt(pdev, master); else @@ -433,7 +434,7 @@ if (status) return status; - return devm_spi_register_master(&pdev->dev, spi_master_get(master)); + return devm_spi_register_master(&pdev->dev, master); } MODULE_ALIAS("platform:" DRIVER_NAME); --- linux-oracle-5.4.0.orig/drivers/spi/spi-hisi-sfc-v3xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-hisi-sfc-v3xx.c @@ -0,0 +1,381 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets +// +// Copyright (c) 2019 HiSilicon Technologies Co., Ltd. +// Author: John Garry + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HISI_SFC_V3XX_VERSION (0x1f8) + +#define HISI_SFC_V3XX_CMD_CFG (0x300) +#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17) +#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17) +#define HISI_SFC_V3XX_CMD_CFG_FULL_DIO (3 << 17) +#define HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT (5 << 17) +#define HISI_SFC_V3XX_CMD_CFG_QUAD_IO (6 << 17) +#define HISI_SFC_V3XX_CMD_CFG_FULL_QIO (7 << 17) +#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9 +#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8) +#define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7) +#define HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF 4 +#define HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK BIT(3) +#define HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF 1 +#define HISI_SFC_V3XX_CMD_CFG_START_MSK BIT(0) +#define HISI_SFC_V3XX_CMD_INS (0x308) +#define HISI_SFC_V3XX_CMD_ADDR (0x30c) +#define HISI_SFC_V3XX_CMD_DATABUF0 (0x400) + +struct hisi_sfc_v3xx_host { + struct device *dev; + void __iomem *regbase; + int max_cmd_dword; +}; + +#define HISI_SFC_V3XX_WAIT_TIMEOUT_US 1000000 +#define HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US 10 + +static int hisi_sfc_v3xx_wait_cmd_idle(struct hisi_sfc_v3xx_host *host) +{ + u32 reg; + + return readl_poll_timeout(host->regbase + HISI_SFC_V3XX_CMD_CFG, reg, + !(reg & HISI_SFC_V3XX_CMD_CFG_START_MSK), + HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US, + HISI_SFC_V3XX_WAIT_TIMEOUT_US); +} + +static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem, + struct spi_mem_op *op) +{ + struct spi_device *spi = mem->spi; + struct hisi_sfc_v3xx_host *host; + uintptr_t addr = (uintptr_t)op->data.buf.in; + int max_byte_count; + + host = spi_controller_get_devdata(spi->master); + + max_byte_count = host->max_cmd_dword * 4; + + if (!IS_ALIGNED(addr, 4) && op->data.nbytes >= 4) + op->data.nbytes = 4 - (addr % 4); + else if (op->data.nbytes > max_byte_count) + op->data.nbytes = max_byte_count; + + return 0; +} + +/* + * memcpy_{to,from}io doesn't gurantee 32b accesses - which we require for the + * DATABUF registers -so use __io{read,write}32_copy when possible. For + * trailing bytes, copy them byte-by-byte from the DATABUF register, as we + * can't clobber outside the source/dest buffer. + * + * For efficient data read/write, we try to put any start 32b unaligned data + * into a separate transaction in hisi_sfc_v3xx_adjust_op_size(). + */ +static void hisi_sfc_v3xx_read_databuf(struct hisi_sfc_v3xx_host *host, + u8 *to, unsigned int len) +{ + void __iomem *from; + int i; + + from = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0; + + if (IS_ALIGNED((uintptr_t)to, 4)) { + int words = len / 4; + + __ioread32_copy(to, from, words); + + len -= words * 4; + if (len) { + u32 val; + + to += words * 4; + from += words * 4; + + val = __raw_readl(from); + + for (i = 0; i < len; i++, val >>= 8, to++) + *to = (u8)val; + } + } else { + for (i = 0; i < DIV_ROUND_UP(len, 4); i++, from += 4) { + u32 val = __raw_readl(from); + int j; + + for (j = 0; j < 4 && (j + (i * 4) < len); + to++, val >>= 8, j++) + *to = (u8)val; + } + } +} + +static void hisi_sfc_v3xx_write_databuf(struct hisi_sfc_v3xx_host *host, + const u8 *from, unsigned int len) +{ + void __iomem *to; + int i; + + to = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0; + + if (IS_ALIGNED((uintptr_t)from, 4)) { + int words = len / 4; + + __iowrite32_copy(to, from, words); + + len -= words * 4; + if (len) { + u32 val = 0; + + to += words * 4; + from += words * 4; + + for (i = 0; i < len; i++, from++) + val |= *from << i * 8; + __raw_writel(val, to); + } + + } else { + for (i = 0; i < DIV_ROUND_UP(len, 4); i++, to += 4) { + u32 val = 0; + int j; + + for (j = 0; j < 4 && (j + (i * 4) < len); + from++, j++) + val |= *from << j * 8; + __raw_writel(val, to); + } + } +} + +static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host, + const struct spi_mem_op *op, + u8 chip_select) +{ + int ret, len = op->data.nbytes; + u32 config = 0; + + if (op->addr.nbytes) + config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK; + + switch (op->data.buswidth) { + case 0 ... 1: + break; + case 2: + if (op->addr.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT; + } else if (op->addr.buswidth == 2) { + if (op->cmd.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IO; + } else if (op->cmd.buswidth == 2) { + config |= HISI_SFC_V3XX_CMD_CFG_FULL_DIO; + } else { + return -EIO; + } + } else { + return -EIO; + } + break; + case 4: + if (op->addr.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT; + } else if (op->addr.buswidth == 4) { + if (op->cmd.buswidth <= 1) { + config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IO; + } else if (op->cmd.buswidth == 4) { + config |= HISI_SFC_V3XX_CMD_CFG_FULL_QIO; + } else { + return -EIO; + } + } else { + return -EIO; + } + break; + default: + return -EOPNOTSUPP; + } + + if (op->data.dir != SPI_MEM_NO_DATA) { + config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF; + config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK; + } + + if (op->data.dir == SPI_MEM_DATA_OUT) + hisi_sfc_v3xx_write_databuf(host, op->data.buf.out, len); + else if (op->data.dir == SPI_MEM_DATA_IN) + config |= HISI_SFC_V3XX_CMD_CFG_RW_MSK; + + config |= op->dummy.nbytes << HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF | + chip_select << HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF | + HISI_SFC_V3XX_CMD_CFG_START_MSK; + + writel(op->addr.val, host->regbase + HISI_SFC_V3XX_CMD_ADDR); + writel(op->cmd.opcode, host->regbase + HISI_SFC_V3XX_CMD_INS); + + writel(config, host->regbase + HISI_SFC_V3XX_CMD_CFG); + + ret = hisi_sfc_v3xx_wait_cmd_idle(host); + if (ret) + return ret; + + if (op->data.dir == SPI_MEM_DATA_IN) + hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, len); + + return 0; +} + +static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + struct hisi_sfc_v3xx_host *host; + struct spi_device *spi = mem->spi; + u8 chip_select = spi->chip_select; + + host = spi_controller_get_devdata(spi->master); + + return hisi_sfc_v3xx_generic_exec_op(host, op, chip_select); +} + +static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = { + .adjust_op_size = hisi_sfc_v3xx_adjust_op_size, + .exec_op = hisi_sfc_v3xx_exec_op, +}; + +static int hisi_sfc_v3xx_buswidth_override_bits; + +/* + * ACPI FW does not allow us to currently set the device buswidth, so quirk it + * depending on the board. + */ +static int __init hisi_sfc_v3xx_dmi_quirk(const struct dmi_system_id *d) +{ + hisi_sfc_v3xx_buswidth_override_bits = SPI_RX_QUAD | SPI_TX_QUAD; + + return 0; +} + +static const struct dmi_system_id hisi_sfc_v3xx_dmi_quirk_table[] = { + { + .callback = hisi_sfc_v3xx_dmi_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), + DMI_MATCH(DMI_PRODUCT_NAME, "D06"), + }, + }, + { + .callback = hisi_sfc_v3xx_dmi_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), + DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 2280 V2"), + }, + }, + { + .callback = hisi_sfc_v3xx_dmi_quirk, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Huawei"), + DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 200 (Model 2280)"), + }, + }, + {} +}; + +static int hisi_sfc_v3xx_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hisi_sfc_v3xx_host *host; + struct spi_controller *ctlr; + u32 version; + int ret; + + ctlr = spi_alloc_master(&pdev->dev, sizeof(*host)); + if (!ctlr) + return -ENOMEM; + + ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | + SPI_TX_DUAL | SPI_TX_QUAD; + + ctlr->buswidth_override_bits = hisi_sfc_v3xx_buswidth_override_bits; + + host = spi_controller_get_devdata(ctlr); + host->dev = dev; + + platform_set_drvdata(pdev, host); + + host->regbase = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(host->regbase)) { + ret = PTR_ERR(host->regbase); + goto err_put_master; + } + + ctlr->bus_num = -1; + ctlr->num_chipselect = 1; + ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops; + + version = readl(host->regbase + HISI_SFC_V3XX_VERSION); + + switch (version) { + case 0x351: + host->max_cmd_dword = 64; + break; + default: + host->max_cmd_dword = 16; + break; + } + + ret = devm_spi_register_controller(dev, ctlr); + if (ret) + goto err_put_master; + + dev_info(&pdev->dev, "hw version 0x%x\n", version); + + return 0; + +err_put_master: + spi_master_put(ctlr); + return ret; +} + +#if IS_ENABLED(CONFIG_ACPI) +static const struct acpi_device_id hisi_sfc_v3xx_acpi_ids[] = { + {"HISI0341", 0}, + {} +}; +MODULE_DEVICE_TABLE(acpi, hisi_sfc_v3xx_acpi_ids); +#endif + +static struct platform_driver hisi_sfc_v3xx_spi_driver = { + .driver = { + .name = "hisi-sfc-v3xx", + .acpi_match_table = ACPI_PTR(hisi_sfc_v3xx_acpi_ids), + }, + .probe = hisi_sfc_v3xx_probe, +}; + +static int __init hisi_sfc_v3xx_spi_init(void) +{ + dmi_check_system(hisi_sfc_v3xx_dmi_quirk_table); + + return platform_driver_register(&hisi_sfc_v3xx_spi_driver); +} + +static void __exit hisi_sfc_v3xx_spi_exit(void) +{ + platform_driver_unregister(&hisi_sfc_v3xx_spi_driver); +} + +module_init(hisi_sfc_v3xx_spi_init); +module_exit(hisi_sfc_v3xx_spi_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("John Garry "); +MODULE_DESCRIPTION("HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets"); --- linux-oracle-5.4.0.orig/drivers/spi/spi-img-spfi.c +++ linux-oracle-5.4.0/drivers/spi/spi-img-spfi.c @@ -673,6 +673,8 @@ dma_release_channel(spfi->tx_ch); if (spfi->rx_ch) dma_release_channel(spfi->rx_ch); + spfi->tx_ch = NULL; + spfi->rx_ch = NULL; dev_warn(spfi->dev, "Failed to get DMA channels, falling back to PIO mode\n"); } else { master->dma_tx = spfi->tx_ch; @@ -769,8 +771,10 @@ int ret; ret = pm_runtime_get_sync(dev); - if (ret) + if (ret < 0) { + pm_runtime_put_noidle(dev); return ret; + } spfi_reset(spfi); pm_runtime_put(dev); --- linux-oracle-5.4.0.orig/drivers/spi/spi-imx.c +++ linux-oracle-5.4.0/drivers/spi/spi-imx.c @@ -64,8 +64,7 @@ struct spi_imx_devtype_data { void (*intctrl)(struct spi_imx_data *, int); int (*prepare_message)(struct spi_imx_data *, struct spi_message *); - int (*prepare_transfer)(struct spi_imx_data *, struct spi_device *, - struct spi_transfer *); + int (*prepare_transfer)(struct spi_imx_data *, struct spi_device *); void (*trigger)(struct spi_imx_data *); int (*rx_available)(struct spi_imx_data *); void (*reset)(struct spi_imx_data *); @@ -240,6 +239,18 @@ return true; } +/* + * Note the number of natively supported chip selects for MX51 is 4. Some + * devices may have less actual SS pins but the register map supports 4. When + * using gpio chip selects the cs values passed into the macros below can go + * outside the range 0 - 3. We therefore need to limit the cs value to avoid + * corrupting bits outside the allocated locations. + * + * The simplest way to do this is to just mask the cs bits to 2 bits. This + * still allows all 4 native chip selects to work as well as gpio chip selects + * (which can use any of the 4 chip select configurations). + */ + #define MX51_ECSPI_CTRL 0x08 #define MX51_ECSPI_CTRL_ENABLE (1 << 0) #define MX51_ECSPI_CTRL_XCH (1 << 2) @@ -248,16 +259,16 @@ #define MX51_ECSPI_CTRL_DRCTL(drctl) ((drctl) << 16) #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 -#define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) +#define MX51_ECSPI_CTRL_CS(cs) ((cs & 3) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c -#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) -#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs) + 4)) -#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs) + 8)) -#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs) + 12)) -#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs) + 20)) +#define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs & 3) + 0)) +#define MX51_ECSPI_CONFIG_SCLKPOL(cs) (1 << ((cs & 3) + 4)) +#define MX51_ECSPI_CONFIG_SBBCTRL(cs) (1 << ((cs & 3) + 8)) +#define MX51_ECSPI_CONFIG_SSBPOL(cs) (1 << ((cs & 3) + 12)) +#define MX51_ECSPI_CONFIG_SCLKCTL(cs) (1 << ((cs & 3) + 20)) #define MX51_ECSPI_INT 0x10 #define MX51_ECSPI_INT_TEEN (1 << 0) @@ -432,8 +443,7 @@ unsigned int pre, post; unsigned int fin = spi_imx->spi_clk; - if (unlikely(fspi > fin)) - return 0; + fspi = min(fspi, fin); post = fls(fin) - fls(fspi); if (fin > fspi << post) @@ -498,8 +508,10 @@ struct spi_message *msg) { struct spi_device *spi = msg->spi; + struct spi_transfer *xfer; u32 ctrl = MX51_ECSPI_CTRL_ENABLE; - u32 testreg; + u32 min_speed_hz = ~0U; + u32 testreg, delay; u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); /* set Master or Slave mode */ @@ -560,15 +572,43 @@ writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); + /* + * Wait until the changes in the configuration register CONFIGREG + * propagate into the hardware. It takes exactly one tick of the + * SCLK clock, but we will wait two SCLK clock just to be sure. The + * effect of the delay it takes for the hardware to apply changes + * is noticable if the SCLK clock run very slow. In such a case, if + * the polarity of SCLK should be inverted, the GPIO ChipSelect might + * be asserted before the SCLK polarity changes, which would disrupt + * the SPI communication as the device on the other end would consider + * the change of SCLK polarity as a clock tick already. + * + * Because spi_imx->spi_bus_clk is only set in bitbang prepare_message + * callback, iterate over all the transfers in spi_message, find the + * one with lowest bus frequency, and use that bus frequency for the + * delay calculation. In case all transfers have speed_hz == 0, then + * min_speed_hz is ~0 and the resulting delay is zero. + */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (!xfer->speed_hz) + continue; + min_speed_hz = min(xfer->speed_hz, min_speed_hz); + } + + delay = (2 * 1000000) / min_speed_hz; + if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ + udelay(delay); + else /* SCLK is _very_ slow */ + usleep_range(delay, delay + 10); + return 0; } static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); - u32 clk = t->speed_hz, delay; + u32 clk; /* Clear BL field and set the right value */ ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; @@ -582,7 +622,7 @@ /* set clock speed */ ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET | 0xf << MX51_ECSPI_CTRL_PREDIV_OFFSET); - ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk); + ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->spi_bus_clk, &clk); spi_imx->spi_bus_clk = clk; if (spi_imx->usedma) @@ -590,23 +630,6 @@ writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); - /* - * Wait until the changes in the configuration register CONFIGREG - * propagate into the hardware. It takes exactly one tick of the - * SCLK clock, but we will wait two SCLK clock just to be sure. The - * effect of the delay it takes for the hardware to apply changes - * is noticable if the SCLK clock run very slow. In such a case, if - * the polarity of SCLK should be inverted, the GPIO ChipSelect might - * be asserted before the SCLK polarity changes, which would disrupt - * the SPI communication as the device on the other end would consider - * the change of SCLK polarity as a clock tick already. - */ - delay = (2 * 1000000) / clk; - if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ - udelay(delay); - else /* SCLK is _very_ slow */ - usleep_range(delay, delay + 10); - return 0; } @@ -694,13 +717,12 @@ } static int mx31_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, t->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) << MX31_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -799,14 +821,13 @@ } static int mx21_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; unsigned int clk; - reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, t->speed_hz, max, &clk) + reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, spi_imx->spi_bus_clk, max, &clk) << MX21_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -875,13 +896,12 @@ } static int mx1_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, t->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) << MX1_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -973,7 +993,7 @@ .rx_available = mx31_rx_available, .reset = mx31_reset, .fifo_size = 8, - .has_dmamode = true, + .has_dmamode = false, .dynamic_burst = false, .has_slavemode = false, .devtype = IMX35_CSPI, @@ -1199,6 +1219,16 @@ if (!t) return 0; + if (!t->speed_hz) { + if (!spi->max_speed_hz) { + dev_err(&spi->dev, "no speed_hz provided!\n"); + return -EINVAL; + } + dev_dbg(&spi->dev, "using spi->max_speed_hz!\n"); + spi_imx->spi_bus_clk = spi->max_speed_hz; + } else + spi_imx->spi_bus_clk = t->speed_hz; + spi_imx->bits_per_word = t->bits_per_word; /* @@ -1240,7 +1270,7 @@ spi_imx->slave_burst = t->len; } - spi_imx->devtype_data->prepare_transfer(spi_imx, spi, t); + spi_imx->devtype_data->prepare_transfer(spi_imx, spi); return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-lantiq-ssc.c +++ linux-oracle-5.4.0/drivers/spi/spi-lantiq-ssc.c @@ -184,6 +184,7 @@ unsigned int tx_fifo_size; unsigned int rx_fifo_size; unsigned int base_cs; + unsigned int fdx_tx_level; }; static u32 lantiq_ssc_readl(const struct lantiq_ssc_spi *spi, u32 reg) @@ -481,6 +482,7 @@ u32 data; unsigned int tx_free = tx_fifo_free(spi); + spi->fdx_tx_level = 0; while (spi->tx_todo && tx_free) { switch (spi->bits_per_word) { case 2 ... 8: @@ -509,6 +511,7 @@ lantiq_ssc_writel(spi, data, LTQ_SPI_TB); tx_free--; + spi->fdx_tx_level++; } } @@ -520,6 +523,13 @@ u32 data; unsigned int rx_fill = rx_fifo_level(spi); + /* + * Wait until all expected data to be shifted in. + * Otherwise, rx overrun may occur. + */ + while (rx_fill != spi->fdx_tx_level) + rx_fill = rx_fifo_level(spi); + while (rx_fill) { data = lantiq_ssc_readl(spi, LTQ_SPI_RB); @@ -907,7 +917,7 @@ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 8) | SPI_BPW_MASK(16) | SPI_BPW_MASK(32); - spi->wq = alloc_ordered_workqueue(dev_name(dev), 0); + spi->wq = alloc_ordered_workqueue(dev_name(dev), WQ_MEM_RECLAIM); if (!spi->wq) { err = -ENOMEM; goto err_clk_put; --- linux-oracle-5.4.0.orig/drivers/spi/spi-loopback-test.c +++ linux-oracle-5.4.0/drivers/spi/spi-loopback-test.c @@ -90,7 +90,7 @@ { .description = "tx/rx-transfer - crossing PAGE_SIZE", .fill_option = FILL_COUNT_8, - .iterate_len = { ITERATE_MAX_LEN }, + .iterate_len = { ITERATE_LEN }, .iterate_tx_align = ITERATE_ALIGN, .iterate_rx_align = ITERATE_ALIGN, .transfer_count = 1, @@ -868,7 +868,7 @@ test.transfers[i].len = len; if (test.transfers[i].tx_buf) test.transfers[i].tx_buf += tx_off; - if (test.transfers[i].tx_buf) + if (test.transfers[i].rx_buf) test.transfers[i].rx_buf += rx_off; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-mem.c +++ linux-oracle-5.4.0/drivers/spi/spi-mem.c @@ -108,15 +108,17 @@ return 0; case 2: - if ((tx && (mode & (SPI_TX_DUAL | SPI_TX_QUAD))) || - (!tx && (mode & (SPI_RX_DUAL | SPI_RX_QUAD)))) + if ((tx && + (mode & (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL))) || + (!tx && + (mode & (SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL)))) return 0; break; case 4: - if ((tx && (mode & SPI_TX_QUAD)) || - (!tx && (mode & SPI_RX_QUAD))) + if ((tx && (mode & (SPI_TX_QUAD | SPI_TX_OCTAL))) || + (!tx && (mode & (SPI_RX_QUAD | SPI_RX_OCTAL)))) return 0; break; @@ -235,6 +237,7 @@ ret = pm_runtime_get_sync(ctlr->dev.parent); if (ret < 0) { + pm_runtime_put_noidle(ctlr->dev.parent); dev_err(&ctlr->dev, "Failed to power device: %d\n", ret); return ret; --- linux-oracle-5.4.0.orig/drivers/spi/spi-meson-spicc.c +++ linux-oracle-5.4.0/drivers/spi/spi-meson-spicc.c @@ -527,6 +527,11 @@ writel_relaxed(0, spicc->base + SPICC_INTREG); irq = platform_get_irq(pdev, 0); + if (irq < 0) { + ret = irq; + goto out_master; + } + ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq, 0, NULL, spicc); if (ret) { @@ -597,6 +602,8 @@ clk_disable_unprepare(spicc->core); + spi_master_put(spicc->master); + return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-meson-spifc.c +++ linux-oracle-5.4.0/drivers/spi/spi-meson-spifc.c @@ -349,6 +349,7 @@ return 0; out_clk: clk_disable_unprepare(spifc->clk); + pm_runtime_disable(spifc->dev); out_err: spi_master_put(master); return ret; --- linux-oracle-5.4.0.orig/drivers/spi/spi-mpc52xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-mpc52xx.c @@ -519,6 +519,7 @@ struct mpc52xx_spi *ms = spi_master_get_devdata(master); int i; + cancel_work_sync(&ms->work); free_irq(ms->irq0, ms); free_irq(ms->irq1, ms); --- linux-oracle-5.4.0.orig/drivers/spi/spi-mt65xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-mt65xx.c @@ -36,7 +36,6 @@ #define SPI_CFG0_SCK_LOW_OFFSET 8 #define SPI_CFG0_CS_HOLD_OFFSET 16 #define SPI_CFG0_CS_SETUP_OFFSET 24 -#define SPI_ADJUST_CFG0_SCK_LOW_OFFSET 16 #define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0 #define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16 @@ -48,6 +47,8 @@ #define SPI_CFG1_CS_IDLE_MASK 0xff #define SPI_CFG1_PACKET_LOOP_MASK 0xff00 #define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000 +#define SPI_CFG2_SCK_HIGH_OFFSET 0 +#define SPI_CFG2_SCK_LOW_OFFSET 16 #define SPI_CMD_ACT BIT(0) #define SPI_CMD_RESUME BIT(1) @@ -279,7 +280,7 @@ static void mtk_spi_prepare_transfer(struct spi_master *master, struct spi_transfer *xfer) { - u32 spi_clk_hz, div, sck_time, cs_time, reg_val = 0; + u32 spi_clk_hz, div, sck_time, cs_time, reg_val; struct mtk_spi *mdata = spi_master_get_devdata(master); spi_clk_hz = clk_get_rate(mdata->spi_clk); @@ -292,18 +293,18 @@ cs_time = sck_time * 2; if (mdata->dev_comp->enhance_timing) { + reg_val = (((sck_time - 1) & 0xffff) + << SPI_CFG2_SCK_HIGH_OFFSET); reg_val |= (((sck_time - 1) & 0xffff) - << SPI_CFG0_SCK_HIGH_OFFSET); - reg_val |= (((sck_time - 1) & 0xffff) - << SPI_ADJUST_CFG0_SCK_LOW_OFFSET); + << SPI_CFG2_SCK_LOW_OFFSET); writel(reg_val, mdata->base + SPI_CFG2_REG); - reg_val |= (((cs_time - 1) & 0xffff) + reg_val = (((cs_time - 1) & 0xffff) << SPI_ADJUST_CFG0_CS_HOLD_OFFSET); reg_val |= (((cs_time - 1) & 0xffff) << SPI_ADJUST_CFG0_CS_SETUP_OFFSET); writel(reg_val, mdata->base + SPI_CFG0_REG); } else { - reg_val |= (((sck_time - 1) & 0xff) + reg_val = (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET); reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET); reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); @@ -425,14 +426,15 @@ mtk_spi_prepare_transfer(master, xfer); mtk_spi_setup_packet(master); - cnt = xfer->len / 4; - iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); - - remainder = xfer->len % 4; - if (remainder > 0) { - reg_val = 0; - memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); - writel(reg_val, mdata->base + SPI_TX_DATA_REG); + if (xfer->tx_buf) { + cnt = xfer->len / 4; + iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); + remainder = xfer->len % 4; + if (remainder > 0) { + reg_val = 0; + memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); + writel(reg_val, mdata->base + SPI_TX_DATA_REG); + } } mtk_spi_enable_transfer(master); @@ -531,7 +533,7 @@ else mdata->state = MTK_SPI_IDLE; - if (!master->can_dma(master, master->cur_msg->spi, trans)) { + if (!master->can_dma(master, NULL, trans)) { if (trans->rx_buf) { cnt = mdata->xfer_len / 4; ioread32_rep(mdata->base + SPI_RX_DATA_REG, @@ -557,17 +559,19 @@ mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, len); mtk_spi_setup_packet(master); - cnt = mdata->xfer_len / 4; - iowrite32_rep(mdata->base + SPI_TX_DATA_REG, - trans->tx_buf + mdata->num_xfered, cnt); + if (trans->tx_buf) { + cnt = mdata->xfer_len / 4; + iowrite32_rep(mdata->base + SPI_TX_DATA_REG, + trans->tx_buf + mdata->num_xfered, cnt); - remainder = mdata->xfer_len % 4; - if (remainder > 0) { - reg_val = 0; - memcpy(®_val, - trans->tx_buf + (cnt * 4) + mdata->num_xfered, - remainder); - writel(reg_val, mdata->base + SPI_TX_DATA_REG); + remainder = mdata->xfer_len % 4; + if (remainder > 0) { + reg_val = 0; + memcpy(®_val, + trans->tx_buf + (cnt * 4) + mdata->num_xfered, + remainder); + writel(reg_val, mdata->base + SPI_TX_DATA_REG); + } } mtk_spi_enable_transfer(master); --- linux-oracle-5.4.0.orig/drivers/spi/spi-mt7621.c +++ linux-oracle-5.4.0/drivers/spi/spi-mt7621.c @@ -340,19 +340,18 @@ return PTR_ERR(base); clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", - status); - return PTR_ERR(clk); - } + if (IS_ERR(clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk), + "unable to get SYS clock\n"); status = clk_prepare_enable(clk); if (status) return status; - master = spi_alloc_master(&pdev->dev, sizeof(*rs)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*rs)); if (!master) { dev_info(&pdev->dev, "master allocation failed\n"); + clk_disable_unprepare(clk); return -ENOMEM; } @@ -377,10 +376,15 @@ ret = device_reset(&pdev->dev); if (ret) { dev_err(&pdev->dev, "SPI reset failed!\n"); + clk_disable_unprepare(clk); return ret; } - return devm_spi_register_controller(&pdev->dev, master); + ret = spi_register_controller(master); + if (ret) + clk_disable_unprepare(clk); + + return ret; } static int mt7621_spi_remove(struct platform_device *pdev) @@ -391,6 +395,7 @@ master = dev_get_drvdata(&pdev->dev); rs = spi_controller_get_devdata(master); + spi_unregister_controller(master); clk_disable_unprepare(rs->clk); return 0; --- linux-oracle-5.4.0.orig/drivers/spi/spi-mxic.c +++ linux-oracle-5.4.0/drivers/spi/spi-mxic.c @@ -304,25 +304,21 @@ writel(data, mxic->regs + TXD(nbytes % 4)); - if (rxbuf) { - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_TX_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; - - ret = readl_poll_timeout(mxic->regs + INT_STS, sts, - sts & INT_RX_NOT_EMPTY, 0, - USEC_PER_SEC); - if (ret) - return ret; + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_TX_EMPTY, 0, USEC_PER_SEC); + if (ret) + return ret; + + ret = readl_poll_timeout(mxic->regs + INT_STS, sts, + sts & INT_RX_NOT_EMPTY, 0, + USEC_PER_SEC); + if (ret) + return ret; - data = readl(mxic->regs + RXD); + data = readl(mxic->regs + RXD); + if (rxbuf) { data >>= (8 * (4 - nbytes)); memcpy(rxbuf + pos, &data, nbytes); - WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); - } else { - readl(mxic->regs + RXD); } WARN_ON(readl(mxic->regs + INT_STS) & INT_RX_NOT_EMPTY); @@ -528,7 +524,7 @@ struct mxic_spi *mxic; int ret; - master = spi_alloc_master(&pdev->dev, sizeof(struct mxic_spi)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(struct mxic_spi)); if (!master) return -ENOMEM; @@ -573,15 +569,9 @@ ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); - goto err_put_master; + pm_runtime_disable(&pdev->dev); } - return 0; - -err_put_master: - spi_master_put(master); - pm_runtime_disable(&pdev->dev); - return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-mxs.c +++ linux-oracle-5.4.0/drivers/spi/spi-mxs.c @@ -40,6 +40,7 @@ #include #include #include +#include #define DRIVER_NAME "mxs-spi" @@ -253,7 +254,7 @@ desc = dmaengine_prep_slave_sg(ssp->dmach, &dma_xfer[sg_count].sg, 1, (flags & TXRX_WRITE) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_PREP_INTERRUPT | MXS_DMA_CTRL_WAIT4END); if (!desc) { dev_err(ssp->dev, @@ -608,6 +609,7 @@ ret = pm_runtime_get_sync(ssp->dev); if (ret < 0) { + pm_runtime_put_noidle(ssp->dev); dev_err(ssp->dev, "runtime_get_sync failed\n"); goto out_pm_runtime_disable; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-npcm-fiu.c +++ linux-oracle-5.4.0/drivers/spi/spi-npcm-fiu.c @@ -334,8 +334,9 @@ uma_cfg |= ilog2(op->cmd.buswidth); uma_cfg |= ilog2(op->addr.buswidth) << NPCM_FIU_UMA_CFG_ADBPCK_SHIFT; - uma_cfg |= ilog2(op->dummy.buswidth) - << NPCM_FIU_UMA_CFG_DBPCK_SHIFT; + if (op->dummy.nbytes) + uma_cfg |= ilog2(op->dummy.buswidth) + << NPCM_FIU_UMA_CFG_DBPCK_SHIFT; uma_cfg |= ilog2(op->data.buswidth) << NPCM_FIU_UMA_CFG_RDBPCK_SHIFT; uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT; @@ -677,10 +678,9 @@ struct npcm_fiu_spi *fiu; void __iomem *regbase; struct resource *res; - int ret; - int id; + int id, ret; - ctrl = spi_alloc_master(dev, sizeof(*fiu)); + ctrl = devm_spi_alloc_master(dev, sizeof(*fiu)); if (!ctrl) return -ENOMEM; @@ -738,9 +738,9 @@ ret = devm_spi_register_master(dev, ctrl); if (ret) - return ret; + clk_disable_unprepare(fiu->clk); - return 0; + return ret; } static int npcm_fiu_remove(struct platform_device *pdev) --- linux-oracle-5.4.0.orig/drivers/spi/spi-nxp-fspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-nxp-fspi.c @@ -439,7 +439,7 @@ op->data.nbytes > f->devtype_data->txfifo) return false; - return true; + return spi_mem_default_supports_op(mem, op); } /* Instead of busy looping invoke readl_poll_timeout functionality. */ @@ -679,14 +679,15 @@ if (i < op->data.nbytes) { u32 data = 0; int j; + int remaining = op->data.nbytes - i; /* Wait for TXFIFO empty */ ret = fspi_readl_poll_tout(f, f->iobase + FSPI_INTR, FSPI_INTR_IPTXWE, 0, POLL_TOUT, true); WARN_ON(ret); - for (j = 0; j < ALIGN(op->data.nbytes - i, 4); j += 4) { - memcpy(&data, buf + i + j, 4); + for (j = 0; j < ALIGN(remaining, 4); j += 4) { + memcpy(&data, buf + i + j, min_t(int, 4, remaining - j)); fspi_writel(f, data, base + FSPI_TFDR + j); } fspi_writel(f, FSPI_INTR_IPTXWE, base + FSPI_INTR); @@ -897,6 +898,13 @@ fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, base + FSPI_AHBCR); + /* Reset the FLSHxCR1 registers. */ + reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); + fspi_writel(f, reg, base + FSPI_FLSHA1CR1); + fspi_writel(f, reg, base + FSPI_FLSHA2CR1); + fspi_writel(f, reg, base + FSPI_FLSHB1CR1); + fspi_writel(f, reg, base + FSPI_FLSHB2CR1); + /* AHB Read - Set lut sequence ID for all CS. */ fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); @@ -948,6 +956,7 @@ struct resource *res; struct nxp_fspi *f; int ret; + u32 reg; ctlr = spi_alloc_master(&pdev->dev, sizeof(*f)); if (!ctlr) @@ -1005,6 +1014,11 @@ goto err_put_ctrl; } + /* Clear potential interrupts */ + reg = fspi_readl(f, f->iobase + FSPI_INTR); + if (reg) + fspi_writel(f, reg, f->iobase + FSPI_INTR); + /* find the irq */ ret = platform_get_irq(pdev, 0); if (ret < 0) --- linux-oracle-5.4.0.orig/drivers/spi/spi-omap-100k.c +++ linux-oracle-5.4.0/drivers/spi/spi-omap-100k.c @@ -242,7 +242,7 @@ else word_len = spi->bits_per_word; - if (spi->bits_per_word > 32) + if (word_len > 32) return -EINVAL; cs->word_len = word_len; @@ -416,6 +416,7 @@ return status; err_fck: + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(spi100k->fck); err_ick: clk_disable_unprepare(spi100k->ick); @@ -426,7 +427,7 @@ static int omap1_spi100k_remove(struct platform_device *pdev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = platform_get_drvdata(pdev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master); pm_runtime_disable(&pdev->dev); @@ -440,7 +441,7 @@ #ifdef CONFIG_PM static int omap1_spi100k_runtime_suspend(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master); clk_disable_unprepare(spi100k->ick); @@ -451,7 +452,7 @@ static int omap1_spi100k_runtime_resume(struct device *dev) { - struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct spi_master *master = dev_get_drvdata(dev); struct omap1_spi100k *spi100k = spi_master_get_devdata(master); int ret; --- linux-oracle-5.4.0.orig/drivers/spi/spi-omap-uwire.c +++ linux-oracle-5.4.0/drivers/spi/spi-omap-uwire.c @@ -424,15 +424,22 @@ static int uwire_setup(struct spi_device *spi) { struct uwire_state *ust = spi->controller_state; + bool initial_setup = false; + int status; if (ust == NULL) { ust = kzalloc(sizeof(*ust), GFP_KERNEL); if (ust == NULL) return -ENOMEM; spi->controller_state = ust; + initial_setup = true; } - return uwire_setup_transfer(spi, NULL); + status = uwire_setup_transfer(spi, NULL); + if (status && initial_setup) + kfree(ust); + + return status; } static void uwire_cleanup(struct spi_device *spi) --- linux-oracle-5.4.0.orig/drivers/spi/spi-omap2-mcspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-omap2-mcspi.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -348,9 +347,19 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) { - u32 val; + unsigned long timeout; - return readl_poll_timeout(reg, val, val & bit, 1, MSEC_PER_SEC); + timeout = jiffies + msecs_to_jiffies(1000); + while (!(readl_relaxed(reg) & bit)) { + if (time_after(jiffies, timeout)) { + if (!(readl_relaxed(reg) & bit)) + return -ETIMEDOUT; + else + return 0; + } + cpu_relax(); + } + return 0; } static int mcspi_wait_for_completion(struct omap2_mcspi *mcspi, @@ -985,20 +994,12 @@ * Note that we currently allow DMA only if we get a channel * for both rx and tx. Otherwise we'll do PIO for both rx and tx. */ -static int omap2_mcspi_request_dma(struct spi_device *spi) +static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi, + struct omap2_mcspi_dma *mcspi_dma) { - struct spi_master *master = spi->master; - struct omap2_mcspi *mcspi; - struct omap2_mcspi_dma *mcspi_dma; int ret = 0; - mcspi = spi_master_get_devdata(master); - mcspi_dma = mcspi->dma_channels + spi->chip_select; - - init_completion(&mcspi_dma->dma_rx_completion); - init_completion(&mcspi_dma->dma_tx_completion); - - mcspi_dma->dma_rx = dma_request_chan(&master->dev, + mcspi_dma->dma_rx = dma_request_chan(mcspi->dev, mcspi_dma->dma_rx_ch_name); if (IS_ERR(mcspi_dma->dma_rx)) { ret = PTR_ERR(mcspi_dma->dma_rx); @@ -1006,7 +1007,7 @@ goto no_dma; } - mcspi_dma->dma_tx = dma_request_chan(&master->dev, + mcspi_dma->dma_tx = dma_request_chan(mcspi->dev, mcspi_dma->dma_tx_ch_name); if (IS_ERR(mcspi_dma->dma_tx)) { ret = PTR_ERR(mcspi_dma->dma_tx); @@ -1015,20 +1016,57 @@ mcspi_dma->dma_rx = NULL; } + init_completion(&mcspi_dma->dma_rx_completion); + init_completion(&mcspi_dma->dma_tx_completion); + no_dma: return ret; } +static void omap2_mcspi_release_dma(struct spi_master *master) +{ + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + struct omap2_mcspi_dma *mcspi_dma; + int i; + + for (i = 0; i < master->num_chipselect; i++) { + mcspi_dma = &mcspi->dma_channels[i]; + + if (mcspi_dma->dma_rx) { + dma_release_channel(mcspi_dma->dma_rx); + mcspi_dma->dma_rx = NULL; + } + if (mcspi_dma->dma_tx) { + dma_release_channel(mcspi_dma->dma_tx); + mcspi_dma->dma_tx = NULL; + } + } +} + +static void omap2_mcspi_cleanup(struct spi_device *spi) +{ + struct omap2_mcspi_cs *cs; + + if (spi->controller_state) { + /* Unlink controller state from context save list */ + cs = spi->controller_state; + list_del(&cs->node); + + kfree(cs); + } + + if (gpio_is_valid(spi->cs_gpio)) + gpio_free(spi->cs_gpio); +} + static int omap2_mcspi_setup(struct spi_device *spi) { + bool initial_setup = false; int ret; struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); struct omap2_mcspi_regs *ctx = &mcspi->ctx; - struct omap2_mcspi_dma *mcspi_dma; struct omap2_mcspi_cs *cs = spi->controller_state; - mcspi_dma = &mcspi->dma_channels[spi->chip_select]; - if (!cs) { cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) @@ -1041,6 +1079,7 @@ spi->controller_state = cs; /* Link this to context save list */ list_add_tail(&cs->node, &ctx->cs); + initial_setup = true; if (gpio_is_valid(spi->cs_gpio)) { ret = gpio_request(spi->cs_gpio, dev_name(&spi->dev)); @@ -1053,60 +1092,25 @@ } } - if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { - ret = omap2_mcspi_request_dma(spi); - if (ret) - dev_warn(&spi->dev, "not using DMA for McSPI (%d)\n", - ret); - } - ret = pm_runtime_get_sync(mcspi->dev); if (ret < 0) { pm_runtime_put_noidle(mcspi->dev); + if (initial_setup) + omap2_mcspi_cleanup(spi); return ret; } ret = omap2_mcspi_setup_transfer(spi, NULL); + if (ret && initial_setup) + omap2_mcspi_cleanup(spi); + pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); return ret; } -static void omap2_mcspi_cleanup(struct spi_device *spi) -{ - struct omap2_mcspi *mcspi; - struct omap2_mcspi_dma *mcspi_dma; - struct omap2_mcspi_cs *cs; - - mcspi = spi_master_get_devdata(spi->master); - - if (spi->controller_state) { - /* Unlink controller state from context save list */ - cs = spi->controller_state; - list_del(&cs->node); - - kfree(cs); - } - - if (spi->chip_select < spi->master->num_chipselect) { - mcspi_dma = &mcspi->dma_channels[spi->chip_select]; - - if (mcspi_dma->dma_rx) { - dma_release_channel(mcspi_dma->dma_rx); - mcspi_dma->dma_rx = NULL; - } - if (mcspi_dma->dma_tx) { - dma_release_channel(mcspi_dma->dma_tx); - mcspi_dma->dma_tx = NULL; - } - } - - if (gpio_is_valid(spi->cs_gpio)) - gpio_free(spi->cs_gpio); -} - static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data) { struct omap2_mcspi *mcspi = data; @@ -1313,6 +1317,9 @@ if (spi_controller_is_slave(master)) return true; + master->dma_rx = mcspi_dma->dma_rx; + master->dma_tx = mcspi_dma->dma_tx; + return (xfer->len >= DMA_MIN_BYTES); } @@ -1475,6 +1482,11 @@ for (i = 0; i < master->num_chipselect; i++) { sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i); sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i); + + status = omap2_mcspi_request_dma(mcspi, + &mcspi->dma_channels[i]); + if (status == -EPROBE_DEFER) + goto free_master; } status = platform_get_irq(pdev, 0); @@ -1512,6 +1524,7 @@ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); free_master: + omap2_mcspi_release_dma(master); spi_master_put(master); return status; } @@ -1521,6 +1534,8 @@ struct spi_master *master = platform_get_drvdata(pdev); struct omap2_mcspi *mcspi = spi_master_get_devdata(master); + omap2_mcspi_release_dma(master); + pm_runtime_dont_use_autosuspend(mcspi->dev); pm_runtime_put_sync(mcspi->dev); pm_runtime_disable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/spi/spi-pic32.c +++ linux-oracle-5.4.0/drivers/spi/spi-pic32.c @@ -361,6 +361,7 @@ struct dma_slave_config cfg; int ret; + memset(&cfg, 0, sizeof(cfg)); cfg.device_fc = true; cfg.src_addr = pic32s->dma_base + buf_offset; cfg.dst_addr = pic32s->dma_base + buf_offset; @@ -825,6 +826,7 @@ return 0; err_bailout: + pic32_spi_dma_unprep(pic32s); clk_disable_unprepare(pic32s->clk); err_master: spi_master_put(master); --- linux-oracle-5.4.0.orig/drivers/spi/spi-pl022.c +++ linux-oracle-5.4.0/drivers/spi/spi-pl022.c @@ -1720,12 +1720,13 @@ return -EINVAL; } } else { - if (chip_info->duplex != SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) + if (chip_info->duplex != SSP_MICROWIRE_CHANNEL_FULL_DUPLEX) { dev_err(&pl022->adev->dev, "Microwire half duplex mode requested," " but this is only available in the" " ST version of PL022\n"); - return -EINVAL; + return -EINVAL; + } } } return 0; --- linux-oracle-5.4.0.orig/drivers/spi/spi-ppc4xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-ppc4xx.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -170,10 +169,8 @@ int scr; u8 cdm = 0; u32 speed; - u8 bits_per_word; /* Start with the generic configuration for this device. */ - bits_per_word = spi->bits_per_word; speed = spi->max_speed_hz; /* @@ -181,9 +178,6 @@ * the transfer to overwrite the generic configuration with zeros. */ if (t) { - if (t->bits_per_word) - bits_per_word = t->bits_per_word; - if (t->speed_hz) speed = min(t->speed_hz, spi->max_speed_hz); } @@ -496,7 +490,11 @@ } /* Request IRQ */ - hw->irqnum = irq_of_parse_and_map(np, 0); + ret = platform_get_irq(op, 0); + if (ret < 0) + goto free_host; + hw->irqnum = ret; + ret = request_irq(hw->irqnum, spi_ppc4xx_int, 0, "spi_ppc4xx_of", (void *)hw); if (ret) { --- linux-oracle-5.4.0.orig/drivers/spi/spi-pxa2xx-pci.c +++ linux-oracle-5.4.0/drivers/spi/spi-pxa2xx-pci.c @@ -21,7 +21,8 @@ PORT_BSW1, PORT_BSW2, PORT_CE4100, - PORT_LPT, + PORT_LPT0, + PORT_LPT1, }; struct pxa_spi_info { @@ -57,8 +58,10 @@ static struct dw_dma_slave bsw2_tx_param = { .dst_id = 8 }; static struct dw_dma_slave bsw2_rx_param = { .src_id = 9 }; -static struct dw_dma_slave lpt_tx_param = { .dst_id = 0 }; -static struct dw_dma_slave lpt_rx_param = { .src_id = 1 }; +static struct dw_dma_slave lpt1_tx_param = { .dst_id = 0 }; +static struct dw_dma_slave lpt1_rx_param = { .src_id = 1 }; +static struct dw_dma_slave lpt0_tx_param = { .dst_id = 2 }; +static struct dw_dma_slave lpt0_rx_param = { .src_id = 3 }; static bool lpss_dma_filter(struct dma_chan *chan, void *param) { @@ -71,14 +74,23 @@ return true; } +static void lpss_dma_put_device(void *dma_dev) +{ + pci_dev_put(dma_dev); +} + static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { struct pci_dev *dma_dev; + int ret; c->num_chipselect = 1; c->max_clk_rate = 50000000; dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev); + if (ret) + return ret; if (c->tx_param) { struct dw_dma_slave *slave = c->tx_param; @@ -102,8 +114,9 @@ static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c) { - struct pci_dev *dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0)); struct dw_dma_slave *tx, *rx; + struct pci_dev *dma_dev; + int ret; switch (PCI_FUNC(dev->devfn)) { case 0: @@ -128,6 +141,11 @@ return -ENODEV; } + dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(21, 0)); + ret = devm_add_action_or_reset(&dev->dev, lpss_dma_put_device, dma_dev); + if (ret) + return ret; + tx = c->tx_param; tx->dma_dev = &dma_dev->dev; @@ -185,12 +203,19 @@ .num_chipselect = 1, .max_clk_rate = 50000000, }, - [PORT_LPT] = { + [PORT_LPT0] = { .type = LPSS_LPT_SSP, .port_id = 0, .setup = lpss_spi_setup, - .tx_param = &lpt_tx_param, - .rx_param = &lpt_rx_param, + .tx_param = &lpt0_tx_param, + .rx_param = &lpt0_rx_param, + }, + [PORT_LPT1] = { + .type = LPSS_LPT_SSP, + .port_id = 1, + .setup = lpss_spi_setup, + .tx_param = &lpt1_tx_param, + .rx_param = &lpt1_rx_param, }, }; @@ -285,8 +310,9 @@ { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 }, { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 }, { PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 }, - { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT }, - { }, + { PCI_VDEVICE(INTEL, 0x9ce5), PORT_LPT0 }, + { PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT1 }, + { } }; MODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices); --- linux-oracle-5.4.0.orig/drivers/spi/spi-pxa2xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-pxa2xx.c @@ -68,6 +68,10 @@ #define LPSS_CAPS_CS_EN_SHIFT 9 #define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT) +#define LPSS_PRIV_CLOCK_GATE 0x38 +#define LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK 0x3 +#define LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON 0x3 + struct lpss_config { /* LPSS offset from drv_data->ioaddr */ unsigned offset; @@ -84,6 +88,8 @@ unsigned cs_sel_shift; unsigned cs_sel_mask; unsigned cs_num; + /* Quirks */ + unsigned cs_clk_stays_gated : 1; }; /* Keep these sorted with enum pxa_ssp_type */ @@ -142,6 +148,7 @@ .tx_threshold_hi = 48, .cs_sel_shift = 8, .cs_sel_mask = 3 << 8, + .cs_clk_stays_gated = true, }, { /* LPSS_CNL_SSP */ .offset = 0x200, @@ -154,6 +161,7 @@ .tx_threshold_hi = 56, .cs_sel_shift = 8, .cs_sel_mask = 3 << 8, + .cs_clk_stays_gated = true, }, }; @@ -381,6 +389,22 @@ else value |= LPSS_CS_CONTROL_CS_HIGH; __lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value); + if (config->cs_clk_stays_gated) { + u32 clkgate; + + /* + * Changing CS alone when dynamic clock gating is on won't + * actually flip CS at that time. This ruins SPI transfers + * that specify delays, or have no data. Toggle the clock mode + * to force on briefly to poke the CS pin to move. + */ + clkgate = __lpss_ssp_read_priv(drv_data, LPSS_PRIV_CLOCK_GATE); + value = (clkgate & ~LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK) | + LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON; + + __lpss_ssp_write_priv(drv_data, LPSS_PRIV_CLOCK_GATE, value); + __lpss_ssp_write_priv(drv_data, LPSS_PRIV_CLOCK_GATE, clkgate); + } } static void cs_assert(struct spi_device *spi) @@ -1217,6 +1241,8 @@ chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; err = gpiod_direction_output(gpiod, !chip->gpio_cs_inverted); + if (err) + gpiod_put(chip->gpiod_cs); } return err; @@ -1230,6 +1256,7 @@ struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); uint tx_thres, tx_hi_thres, rx_thres; + int err; switch (drv_data->ssp_type) { case QUARK_X1000_SSP: @@ -1376,7 +1403,11 @@ if (drv_data->ssp_type == CE4100_SSP) return 0; - return setup_cs(spi, chip, chip_info); + err = setup_cs(spi, chip, chip_info); + if (err) + kfree(chip); + + return err; } static void cleanup(struct spi_device *spi) @@ -1441,6 +1472,10 @@ { PCI_VDEVICE(INTEL, 0x4b2a), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x4b2b), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x4b37), LPSS_BXT_SSP }, + /* JSL */ + { PCI_VDEVICE(INTEL, 0x4daa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x4dab), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x4dfb), LPSS_CNL_SSP }, /* APL */ { PCI_VDEVICE(INTEL, 0x5ac2), LPSS_BXT_SSP }, { PCI_VDEVICE(INTEL, 0x5ac4), LPSS_BXT_SSP }, @@ -1457,6 +1492,10 @@ { PCI_VDEVICE(INTEL, 0x02aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02ab), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0x02fb), LPSS_CNL_SSP }, + /* CML-H */ + { PCI_VDEVICE(INTEL, 0x06aa), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x06ab), LPSS_CNL_SSP }, + { PCI_VDEVICE(INTEL, 0x06fb), LPSS_CNL_SSP }, /* TGL-LP */ { PCI_VDEVICE(INTEL, 0xa0aa), LPSS_CNL_SSP }, { PCI_VDEVICE(INTEL, 0xa0ab), LPSS_CNL_SSP }, @@ -1565,7 +1604,13 @@ #endif ssp->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(ssp->clk)) + return NULL; + ssp->irq = platform_get_irq(pdev, 0); + if (ssp->irq < 0) + return NULL; + ssp->type = type; ssp->pdev = pdev; ssp->port_id = pxa2xx_spi_get_port_id(adev); @@ -1602,6 +1647,11 @@ return cs; } +static size_t pxa2xx_spi_max_dma_transfer_size(struct spi_device *spi) +{ + return MAX_DMA_LEN; +} + static int pxa2xx_spi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1632,9 +1682,9 @@ } if (platform_info->is_slave) - controller = spi_alloc_slave(dev, sizeof(struct driver_data)); + controller = devm_spi_alloc_slave(dev, sizeof(*drv_data)); else - controller = spi_alloc_master(dev, sizeof(struct driver_data)); + controller = devm_spi_alloc_master(dev, sizeof(*drv_data)); if (!controller) { dev_err(&pdev->dev, "cannot alloc spi_controller\n"); @@ -1707,6 +1757,8 @@ } else { controller->can_dma = pxa2xx_spi_can_dma; controller->max_dma_len = MAX_DMA_LEN; + controller->max_transfer_size = + pxa2xx_spi_max_dma_transfer_size; } } @@ -1836,7 +1888,7 @@ /* Register with the SPI framework */ platform_set_drvdata(pdev, drv_data); - status = devm_spi_register_controller(&pdev->dev, controller); + status = spi_register_controller(controller); if (status != 0) { dev_err(&pdev->dev, "problem registering spi controller\n"); goto out_error_pm_runtime_enabled; @@ -1845,7 +1897,6 @@ return status; out_error_pm_runtime_enabled: - pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); out_error_clock_enabled: @@ -1856,7 +1907,6 @@ free_irq(ssp->irq, drv_data); out_error_controller_alloc: - spi_controller_put(controller); pxa_ssp_free(ssp); return status; } @@ -1872,6 +1922,8 @@ pm_runtime_get_sync(&pdev->dev); + spi_unregister_controller(drv_data->controller); + /* Disable the SSP at the peripheral and SOC level */ pxa2xx_spi_write(drv_data, SSCR0, 0); clk_disable_unprepare(ssp->clk); --- linux-oracle-5.4.0.orig/drivers/spi/spi-qup.c +++ linux-oracle-5.4.0/drivers/spi/spi-qup.c @@ -1030,23 +1030,8 @@ return -ENXIO; } - ret = clk_prepare_enable(cclk); - if (ret) { - dev_err(dev, "cannot enable core clock\n"); - return ret; - } - - ret = clk_prepare_enable(iclk); - if (ret) { - clk_disable_unprepare(cclk); - dev_err(dev, "cannot enable iface clock\n"); - return ret; - } - master = spi_alloc_master(dev, sizeof(struct spi_qup)); if (!master) { - clk_disable_unprepare(cclk); - clk_disable_unprepare(iclk); dev_err(dev, "cannot allocate master\n"); return -ENOMEM; } @@ -1092,6 +1077,19 @@ spin_lock_init(&controller->lock); init_completion(&controller->done); + ret = clk_prepare_enable(cclk); + if (ret) { + dev_err(dev, "cannot enable core clock\n"); + goto error_dma; + } + + ret = clk_prepare_enable(iclk); + if (ret) { + clk_disable_unprepare(cclk); + dev_err(dev, "cannot enable iface clock\n"); + goto error_dma; + } + iomode = readl_relaxed(base + QUP_IO_M_MODES); size = QUP_IO_M_OUTPUT_BLOCK_SIZE(iomode); @@ -1121,7 +1119,7 @@ ret = spi_qup_set_state(controller, QUP_STATE_RESET); if (ret) { dev_err(dev, "cannot set RESET state\n"); - goto error_dma; + goto error_clk; } writel_relaxed(0, base + QUP_OPERATIONAL); @@ -1145,7 +1143,7 @@ ret = devm_request_irq(dev, irq, spi_qup_qup_irq, IRQF_TRIGGER_HIGH, pdev->name, controller); if (ret) - goto error_dma; + goto error_clk; pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC); pm_runtime_use_autosuspend(dev); @@ -1160,11 +1158,12 @@ disable_pm: pm_runtime_disable(&pdev->dev); +error_clk: + clk_disable_unprepare(cclk); + clk_disable_unprepare(iclk); error_dma: spi_qup_release_dma(master); error: - clk_disable_unprepare(cclk); - clk_disable_unprepare(iclk); spi_master_put(master); return ret; } @@ -1199,8 +1198,10 @@ return ret; ret = clk_prepare_enable(controller->cclk); - if (ret) + if (ret) { + clk_disable_unprepare(controller->iclk); return ret; + } /* Disable clocks auto gaiting */ config = readl_relaxed(controller->base + QUP_CONFIG); @@ -1217,6 +1218,11 @@ struct spi_qup *controller = spi_master_get_devdata(master); int ret; + if (pm_runtime_suspended(device)) { + ret = spi_qup_pm_resume_runtime(device); + if (ret) + return ret; + } ret = spi_master_suspend(master); if (ret) return ret; @@ -1225,10 +1231,8 @@ if (ret) return ret; - if (!pm_runtime_suspended(device)) { - clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); - } + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); return 0; } @@ -1243,14 +1247,25 @@ return ret; ret = clk_prepare_enable(controller->cclk); - if (ret) + if (ret) { + clk_disable_unprepare(controller->iclk); return ret; + } ret = spi_qup_set_state(controller, QUP_STATE_RESET); if (ret) - return ret; + goto disable_clk; + + ret = spi_master_resume(master); + if (ret) + goto disable_clk; - return spi_master_resume(master); + return 0; + +disable_clk: + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + return ret; } #endif /* CONFIG_PM_SLEEP */ @@ -1261,17 +1276,21 @@ int ret; ret = pm_runtime_get_sync(&pdev->dev); - if (ret < 0) - return ret; - ret = spi_qup_set_state(controller, QUP_STATE_RESET); - if (ret) - return ret; + if (ret >= 0) { + ret = spi_qup_set_state(controller, QUP_STATE_RESET); + if (ret) + dev_warn(&pdev->dev, "failed to reset controller (%pe)\n", + ERR_PTR(ret)); - spi_qup_release_dma(master); + clk_disable_unprepare(controller->cclk); + clk_disable_unprepare(controller->iclk); + } else { + dev_warn(&pdev->dev, "failed to resume, skip hw disable (%pe)\n", + ERR_PTR(ret)); + } - clk_disable_unprepare(controller->cclk); - clk_disable_unprepare(controller->iclk); + spi_qup_release_dma(master); pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/spi/spi-rb4xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-rb4xx.c @@ -142,7 +142,7 @@ if (IS_ERR(spi_base)) return PTR_ERR(spi_base); - master = spi_alloc_master(&pdev->dev, sizeof(*rbspi)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(*rbspi)); if (!master) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/spi/spi-rockchip.c +++ linux-oracle-5.4.0/drivers/spi/spi-rockchip.c @@ -286,7 +286,7 @@ static void rockchip_spi_pio_reader(struct rockchip_spi *rs) { u32 words = readl_relaxed(rs->regs + ROCKCHIP_SPI_RXFLR); - u32 rx_left = rs->rx_left - words; + u32 rx_left = (rs->rx_left > words) ? rs->rx_left - words : 0; /* the hardware doesn't allow us to change fifo threshold * level while spi is enabled, so instead make sure to leave --- linux-oracle-5.4.0.orig/drivers/spi/spi-rspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-rspi.c @@ -595,6 +595,10 @@ rspi->dma_callbacked, HZ); if (ret > 0 && rspi->dma_callbacked) { ret = 0; + if (tx) + dmaengine_synchronize(rspi->ctlr->dma_tx); + if (rx) + dmaengine_synchronize(rspi->ctlr->dma_rx); } else { if (!ret) { dev_err(&rspi->ctlr->dev, "DMA timeout\n"); @@ -1044,14 +1048,11 @@ } memset(&cfg, 0, sizeof(cfg)); + cfg.dst_addr = port_addr + RSPI_SPDR; + cfg.src_addr = port_addr + RSPI_SPDR; + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; cfg.direction = dir; - if (dir == DMA_MEM_TO_DEV) { - cfg.dst_addr = port_addr; - cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - } else { - cfg.src_addr = port_addr; - cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; - } ret = dmaengine_slave_config(chan, &cfg); if (ret) { @@ -1082,12 +1083,12 @@ } ctlr->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id, - res->start + RSPI_SPDR); + res->start); if (!ctlr->dma_tx) return -ENODEV; ctlr->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id, - res->start + RSPI_SPDR); + res->start); if (!ctlr->dma_rx) { dma_release_channel(ctlr->dma_tx); ctlr->dma_tx = NULL; @@ -1257,9 +1258,9 @@ ctlr->flags = ops->flags; ctlr->dev.of_node = pdev->dev.of_node; - ret = platform_get_irq_byname(pdev, "rx"); + ret = platform_get_irq_byname_optional(pdev, "rx"); if (ret < 0) { - ret = platform_get_irq_byname(pdev, "mux"); + ret = platform_get_irq_byname_optional(pdev, "mux"); if (ret < 0) ret = platform_get_irq(pdev, 0); if (ret >= 0) @@ -1270,10 +1271,6 @@ if (ret >= 0) rspi->tx_irq = ret; } - if (ret < 0) { - dev_err(&pdev->dev, "platform_get_irq error\n"); - goto error2; - } if (rspi->rx_irq == rspi->tx_irq) { /* Single multiplexed interrupt */ --- linux-oracle-5.4.0.orig/drivers/spi/spi-s3c24xx-fiq.S +++ linux-oracle-5.4.0/drivers/spi/spi-s3c24xx-fiq.S @@ -33,7 +33,6 @@ @ and an offset to the irq acknowledgment word ENTRY(s3c24xx_spi_fiq_rx) -s3c24xx_spi_fix_rx: .word fiq_rx_end - fiq_rx_start .word fiq_rx_irq_ack - fiq_rx_start fiq_rx_start: @@ -47,7 +46,7 @@ strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do @@ set IRQ controller so that next op will trigger IRQ mov fiq_rtmp, #0 @@ -59,7 +58,6 @@ fiq_rx_end: ENTRY(s3c24xx_spi_fiq_txrx) -s3c24xx_spi_fiq_txrx: .word fiq_txrx_end - fiq_txrx_start .word fiq_txrx_irq_ack - fiq_txrx_start fiq_txrx_start: @@ -74,7 +72,7 @@ strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do mov fiq_rtmp, #0 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] @@ -86,7 +84,6 @@ fiq_txrx_end: ENTRY(s3c24xx_spi_fiq_tx) -s3c24xx_spi_fix_tx: .word fiq_tx_end - fiq_tx_start .word fiq_tx_irq_ack - fiq_tx_start fiq_tx_start: @@ -99,7 +96,7 @@ strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] subs fiq_rcount, fiq_rcount, #1 - subnes pc, lr, #4 @@ return, still have work to do + subsne pc, lr, #4 @@ return, still have work to do mov fiq_rtmp, #0 str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] --- linux-oracle-5.4.0.orig/drivers/spi/spi-s3c64xx.c +++ linux-oracle-5.4.0/drivers/spi/spi-s3c64xx.c @@ -84,6 +84,7 @@ #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) #define S3C64XX_SPI_PACKET_CNT_EN (1<<16) +#define S3C64XX_SPI_PACKET_CNT_MASK GENMASK(15, 0) #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) @@ -122,6 +123,7 @@ struct s3c64xx_spi_dma_data { struct dma_chan *ch; + dma_cookie_t cookie; enum dma_transfer_direction direction; }; @@ -209,7 +211,7 @@ loops = msecs_to_loops(1); do { val = readl(regs + S3C64XX_SPI_STATUS); - } while (TX_FIFO_LVL(val, sdd) && loops--); + } while (TX_FIFO_LVL(val, sdd) && --loops); if (loops == 0) dev_warn(&sdd->pdev->dev, "Timed out flushing TX FIFO\n"); @@ -222,7 +224,7 @@ readl(regs + S3C64XX_SPI_RX_DATA); else break; - } while (loops--); + } while (--loops); if (loops == 0) dev_warn(&sdd->pdev->dev, "Timed out flushing RX FIFO\n"); @@ -264,12 +266,13 @@ spin_unlock_irqrestore(&sdd->lock, flags); } -static void prepare_dma(struct s3c64xx_spi_dma_data *dma, +static int prepare_dma(struct s3c64xx_spi_dma_data *dma, struct sg_table *sgt) { struct s3c64xx_spi_driver_data *sdd; struct dma_slave_config config; struct dma_async_tx_descriptor *desc; + int ret; memset(&config, 0, sizeof(config)); @@ -293,12 +296,24 @@ desc = dmaengine_prep_slave_sg(dma->ch, sgt->sgl, sgt->nents, dma->direction, DMA_PREP_INTERRUPT); + if (!desc) { + dev_err(&sdd->pdev->dev, "unable to prepare %s scatterlist", + dma->direction == DMA_DEV_TO_MEM ? "rx" : "tx"); + return -ENOMEM; + } desc->callback = s3c64xx_spi_dmacb; desc->callback_param = dma; - dmaengine_submit(desc); + dma->cookie = dmaengine_submit(desc); + ret = dma_submit_error(dma->cookie); + if (ret) { + dev_err(&sdd->pdev->dev, "DMA submission failed"); + return -EIO; + } + dma_async_issue_pending(dma->ch); + return 0; } static void s3c64xx_spi_set_cs(struct spi_device *spi, bool enable) @@ -348,11 +363,12 @@ return xfer->len > (FIFO_LVL_MASK(sdd) >> 1) + 1; } -static void s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, +static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, struct spi_transfer *xfer, int dma_mode) { void __iomem *regs = sdd->regs; u32 modecfg, chcfg; + int ret = 0; modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); @@ -378,7 +394,7 @@ chcfg |= S3C64XX_SPI_CH_TXCH_ON; if (dma_mode) { modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; - prepare_dma(&sdd->tx_dma, &xfer->tx_sg); + ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg); } else { switch (sdd->cur_bpw) { case 32: @@ -410,12 +426,17 @@ writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) | S3C64XX_SPI_PACKET_CNT_EN, regs + S3C64XX_SPI_PACKET_CNT); - prepare_dma(&sdd->rx_dma, &xfer->rx_sg); + ret = prepare_dma(&sdd->rx_dma, &xfer->rx_sg); } } + if (ret) + return ret; + writel(modecfg, regs + S3C64XX_SPI_MODE_CFG); writel(chcfg, regs + S3C64XX_SPI_CH_CFG); + + return 0; } static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, @@ -548,9 +569,10 @@ return 0; } -static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) +static int s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) { void __iomem *regs = sdd->regs; + int ret; u32 val; /* Disable Clock */ @@ -598,7 +620,9 @@ if (sdd->port_conf->clk_from_cmu) { /* The src_clk clock is divided internally by 2 */ - clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); + ret = clk_set_rate(sdd->src_clk, sdd->cur_speed * 2); + if (ret) + return ret; } else { /* Configure Clock */ val = readl(regs + S3C64XX_SPI_CLK_CFG); @@ -612,6 +636,8 @@ val |= S3C64XX_SPI_ENCLK_ENABLE; writel(val, regs + S3C64XX_SPI_CLK_CFG); } + + return 0; } #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) @@ -629,6 +655,13 @@ return 0; } +static size_t s3c64xx_spi_max_transfer_size(struct spi_device *spi) +{ + struct spi_controller *ctlr = spi->controller; + + return ctlr->can_dma ? S3C64XX_SPI_PACKET_CNT_MASK : SIZE_MAX; +} + static int s3c64xx_spi_transfer_one(struct spi_master *master, struct spi_device *spi, struct spi_transfer *xfer) @@ -654,7 +687,9 @@ sdd->cur_bpw = bpw; sdd->cur_speed = speed; sdd->cur_mode = spi->mode; - s3c64xx_spi_config(sdd); + status = s3c64xx_spi_config(sdd); + if (status) + return status; } if (!is_polling(sdd) && (xfer->len > fifo_len) && @@ -678,13 +713,18 @@ sdd->state &= ~RXBUSY; sdd->state &= ~TXBUSY; - s3c64xx_enable_datapath(sdd, xfer, use_dma); - /* Start the signals */ s3c64xx_spi_set_cs(spi, true); + status = s3c64xx_enable_datapath(sdd, xfer, use_dma); + spin_unlock_irqrestore(&sdd->lock, flags); + if (status) { + dev_err(&spi->dev, "failed to enable data path for transfer: %d\n", status); + break; + } + if (use_dma) status = s3c64xx_wait_for_dma(sdd, xfer); else @@ -1086,6 +1126,7 @@ master->prepare_transfer_hardware = s3c64xx_spi_prepare_transfer; master->prepare_message = s3c64xx_spi_prepare_message; master->transfer_one = s3c64xx_spi_transfer_one; + master->max_transfer_size = s3c64xx_spi_max_transfer_size; master->num_chipselect = sci->num_cs; master->dma_alignment = 8; master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) | --- linux-oracle-5.4.0.orig/drivers/spi/spi-sc18is602.c +++ linux-oracle-5.4.0/drivers/spi/spi-sc18is602.c @@ -239,13 +239,12 @@ struct sc18is602_platform_data *pdata = dev_get_platdata(dev); struct sc18is602 *hw; struct spi_master *master; - int error; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -EINVAL; - master = spi_alloc_master(dev, sizeof(struct sc18is602)); + master = devm_spi_alloc_master(dev, sizeof(struct sc18is602)); if (!master) return -ENOMEM; @@ -299,15 +298,7 @@ master->min_speed_hz = hw->freq / 128; master->max_speed_hz = hw->freq / 4; - error = devm_spi_register_master(dev, master); - if (error) - goto error_reg; - - return 0; - -error_reg: - spi_master_put(master); - return error; + return devm_spi_register_master(dev, master); } static const struct i2c_device_id sc18is602_id[] = { --- linux-oracle-5.4.0.orig/drivers/spi/spi-sh-msiof.c +++ linux-oracle-5.4.0/drivers/spi/spi-sh-msiof.c @@ -32,12 +32,15 @@ #include +#define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) + struct sh_msiof_chipdata { u32 bits_per_word_mask; u16 tx_fifo_size; u16 rx_fifo_size; u16 ctlr_flags; u16 min_div_pow; + u32 flags; }; struct sh_msiof_spi_priv { @@ -1072,6 +1075,16 @@ .min_div_pow = 1, }; +static const struct sh_msiof_chipdata rcar_r8a7795_data = { + .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) | + SPI_BPW_MASK(24) | SPI_BPW_MASK(32), + .tx_fifo_size = 64, + .rx_fifo_size = 64, + .ctlr_flags = SPI_CONTROLLER_MUST_TX, + .min_div_pow = 1, + .flags = SH_MSIOF_FLAG_FIXED_DTDL_200, +}; + static const struct of_device_id sh_msiof_match[] = { { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, @@ -1082,6 +1095,7 @@ { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7795", .data = &rcar_r8a7795_data }, { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, { .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */ @@ -1317,6 +1331,9 @@ return -ENXIO; } + if (chipdata->flags & SH_MSIOF_FLAG_FIXED_DTDL_200) + info->dtdl = 200; + if (info->mode == MSIOF_SPI_SLAVE) ctlr = spi_alloc_slave(&pdev->dev, sizeof(struct sh_msiof_spi_priv)); --- linux-oracle-5.4.0.orig/drivers/spi/spi-sh.c +++ linux-oracle-5.4.0/drivers/spi/spi-sh.c @@ -440,7 +440,7 @@ if (irq < 0) return irq; - master = spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data)); + master = devm_spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data)); if (master == NULL) { dev_err(&pdev->dev, "spi_alloc_master error.\n"); return -ENOMEM; @@ -458,16 +458,14 @@ break; default: dev_err(&pdev->dev, "No support width\n"); - ret = -ENODEV; - goto error1; + return -ENODEV; } ss->irq = irq; ss->master = master; ss->addr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (ss->addr == NULL) { dev_err(&pdev->dev, "ioremap error.\n"); - ret = -ENOMEM; - goto error1; + return -ENOMEM; } INIT_LIST_HEAD(&ss->queue); spin_lock_init(&ss->lock); @@ -477,7 +475,7 @@ ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss); if (ret < 0) { dev_err(&pdev->dev, "request_irq error\n"); - goto error1; + return ret; } master->num_chipselect = 2; @@ -496,9 +494,6 @@ error3: free_irq(irq, ss); - error1: - spi_master_put(master); - return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-sifive.c +++ linux-oracle-5.4.0/drivers/spi/spi-sifive.c @@ -357,14 +357,14 @@ if (!cs_bits) { dev_err(&pdev->dev, "Could not auto probe CS lines\n"); ret = -EINVAL; - goto put_master; + goto disable_clk; } num_cs = ilog2(cs_bits) + 1; if (num_cs > SIFIVE_SPI_MAX_CS) { dev_err(&pdev->dev, "Invalid number of spi slaves\n"); ret = -EINVAL; - goto put_master; + goto disable_clk; } /* Define our master */ @@ -393,7 +393,7 @@ dev_name(&pdev->dev), spi); if (ret) { dev_err(&pdev->dev, "Unable to bind to interrupt\n"); - goto put_master; + goto disable_clk; } dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n", @@ -402,11 +402,13 @@ ret = devm_spi_register_master(&pdev->dev, master); if (ret < 0) { dev_err(&pdev->dev, "spi_register_master failed\n"); - goto put_master; + goto disable_clk; } return 0; +disable_clk: + clk_disable_unprepare(spi->clk); put_master: spi_master_put(master); @@ -420,6 +422,7 @@ /* Disable all the interrupts just in case */ sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0); + clk_disable_unprepare(spi->clk); return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-sprd-adi.c +++ linux-oracle-5.4.0/drivers/spi/spi-sprd-adi.c @@ -102,7 +102,7 @@ #define HWRST_STATUS_WATCHDOG 0xf0 /* Use default timeout 50 ms that converts to watchdog values */ -#define WDG_LOAD_VAL ((50 * 1000) / 32768) +#define WDG_LOAD_VAL ((50 * 32768) / 1000) #define WDG_LOAD_MASK GENMASK(15, 0) #define WDG_UNLOCK_KEY 0xe551 @@ -384,15 +384,18 @@ sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, WDG_UNLOCK_KEY); /* Load the watchdog timeout value, 50ms is always enough. */ + sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_HIGH, 0); sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_LOW, WDG_LOAD_VAL & WDG_LOAD_MASK); - sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOAD_HIGH, 0); /* Start the watchdog to reset system */ sprd_adi_read(sadi, sadi->slave_pbase + REG_WDG_CTRL, &val); val |= BIT_WDG_RUN | BIT_WDG_RST; sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_CTRL, val); + /* Lock the watchdog */ + sprd_adi_write(sadi, sadi->slave_pbase + REG_WDG_LOCK, ~WDG_UNLOCK_KEY); + mdelay(1000); dev_emerg(sadi->dev, "Unable to restart system\n"); --- linux-oracle-5.4.0.orig/drivers/spi/spi-sprd.c +++ linux-oracle-5.4.0/drivers/spi/spi-sprd.c @@ -563,11 +563,11 @@ ss->dma.dma_chan[SPRD_SPI_TX] = dma_request_chan(ss->dev, "tx_chn"); if (IS_ERR_OR_NULL(ss->dma.dma_chan[SPRD_SPI_TX])) { + dma_release_channel(ss->dma.dma_chan[SPRD_SPI_RX]); if (PTR_ERR(ss->dma.dma_chan[SPRD_SPI_TX]) == -EPROBE_DEFER) return PTR_ERR(ss->dma.dma_chan[SPRD_SPI_TX]); dev_err(ss->dev, "request TX DMA channel failed!\n"); - dma_release_channel(ss->dma.dma_chan[SPRD_SPI_RX]); return PTR_ERR(ss->dma.dma_chan[SPRD_SPI_TX]); } @@ -674,7 +674,7 @@ u16 word_delay, interval; u32 val; - val = readl_relaxed(ss->base + SPRD_SPI_CTL7); + val = readl_relaxed(ss->base + SPRD_SPI_CTL0); val &= ~(SPRD_SPI_SCK_REV | SPRD_SPI_NG_TX | SPRD_SPI_NG_RX); /* Set default chip selection, clock phase and clock polarity */ val |= ss->hw_mode & SPI_CPHA ? SPRD_SPI_NG_RX : SPRD_SPI_NG_TX; @@ -1008,6 +1008,7 @@ ret = pm_runtime_get_sync(ss->dev); if (ret < 0) { + pm_runtime_put_noidle(ss->dev); dev_err(ss->dev, "failed to resume SPI controller\n"); return ret; } @@ -1065,6 +1066,7 @@ { .compatible = "sprd,sc9860-spi", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, sprd_spi_of_match); static struct platform_driver sprd_spi_driver = { .driver = { --- linux-oracle-5.4.0.orig/drivers/spi/spi-st-ssc4.c +++ linux-oracle-5.4.0/drivers/spi/spi-st-ssc4.c @@ -375,11 +375,13 @@ ret = devm_spi_register_master(&pdev->dev, master); if (ret) { dev_err(&pdev->dev, "Failed to register master\n"); - goto clk_disable; + goto rpm_disable; } return 0; +rpm_disable: + pm_runtime_disable(&pdev->dev); clk_disable: clk_disable_unprepare(spi_st->clk); put_master: @@ -392,6 +394,8 @@ struct spi_master *master = platform_get_drvdata(pdev); struct spi_st *spi_st = spi_master_get_devdata(master); + pm_runtime_disable(&pdev->dev); + clk_disable_unprepare(spi_st->clk); pinctrl_pm_select_sleep_state(&pdev->dev); --- linux-oracle-5.4.0.orig/drivers/spi/spi-stm32-qspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-stm32-qspi.c @@ -291,9 +291,10 @@ int err = 0; if (!op->data.nbytes) - return stm32_qspi_wait_nobusy(qspi); + goto wait_nobusy; - if (readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) + if ((readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) || + qspi->fmode == CCR_FMODE_APM) goto out; reinit_completion(&qspi->data_completion); @@ -312,6 +313,9 @@ out: /* clear flags */ writel_relaxed(FCR_CTCF | FCR_CTEF, qspi->io_base + QSPI_FCR); +wait_nobusy: + if (!err) + err = stm32_qspi_wait_nobusy(qspi); return err; } @@ -528,7 +532,6 @@ stm32_qspi_dma_free(qspi); mutex_destroy(&qspi->lock); clk_disable_unprepare(qspi->clk); - spi_master_put(qspi->ctrl); } static int stm32_qspi_probe(struct platform_device *pdev) @@ -626,6 +629,8 @@ err: stm32_qspi_release(qspi); + spi_master_put(qspi->ctrl); + return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-stm32.c +++ linux-oracle-5.4.0/drivers/spi/spi-stm32.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -442,7 +443,8 @@ { u32 div, mbrdiv; - div = DIV_ROUND_UP(spi->clk_rate, speed_hz); + /* Ensure spi->clk_rate is even */ + div = DIV_ROUND_CLOSEST(spi->clk_rate & ~0x1, speed_hz); /* * SPI framework set xfer->speed_hz to master->max_speed_hz if @@ -468,26 +470,36 @@ /** * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level * @spi: pointer to the spi controller data structure + * @xfer_len: length of the message to be transferred */ -static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi) +static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len) { - u32 fthlv, half_fifo; + u32 fthlv, half_fifo, packet; /* data packet should not exceed 1/2 of fifo space */ half_fifo = (spi->fifo_size / 2); + /* data_packet should not exceed transfer length */ + if (half_fifo > xfer_len) + packet = xfer_len; + else + packet = half_fifo; + if (spi->cur_bpw <= 8) - fthlv = half_fifo; + fthlv = packet; else if (spi->cur_bpw <= 16) - fthlv = half_fifo / 2; + fthlv = packet / 2; else - fthlv = half_fifo / 4; + fthlv = packet / 4; /* align packet size with data registers access */ if (spi->cur_bpw > 8) - fthlv -= (fthlv % 2); /* multiple of 2 */ + fthlv += (fthlv % 2) ? 1 : 0; else - fthlv -= (fthlv % 4); /* multiple of 4 */ + fthlv += (fthlv % 4) ? (4 - (fthlv % 4)) : 0; + + if (!fthlv) + fthlv = 1; return fthlv; } @@ -901,25 +913,33 @@ ier = readl_relaxed(spi->base + STM32H7_SPI_IER); mask = ier; - /* EOTIE is triggered on EOT, SUSP and TXC events. */ + /* + * EOTIE enables irq from EOT, SUSP and TXC events. We need to set + * SUSP to acknowledge it later. TXC is automatically cleared + */ + mask |= STM32H7_SPI_SR_SUSP; /* - * When TXTF is set, DXPIE and TXPIE are cleared. So in case of - * Full-Duplex, need to poll RXP event to know if there are remaining - * data, before disabling SPI. + * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP + * are set. So in case of Full-Duplex, need to poll TXP and RXP event. */ - if (spi->rx_buf && !spi->cur_usedma) - mask |= STM32H7_SPI_SR_RXP; + if ((spi->cur_comm == SPI_FULL_DUPLEX) && !spi->cur_usedma) + mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; if (!(sr & mask)) { - dev_dbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", - sr, ier); + dev_vdbg(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", + sr, ier); spin_unlock_irqrestore(&spi->lock, flags); return IRQ_NONE; } if (sr & STM32H7_SPI_SR_SUSP) { - dev_warn(spi->dev, "Communication suspended\n"); + static DEFINE_RATELIMIT_STATE(rs, + DEFAULT_RATELIMIT_INTERVAL * 10, + 1); + ratelimit_set_flags(&rs, RATELIMIT_MSG_ON_RELEASE); + if (__ratelimit(&rs)) + dev_dbg_ratelimited(spi->dev, "Communication suspended\n"); if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) stm32h7_spi_read_rxfifo(spi, false); /* @@ -936,15 +956,8 @@ } if (sr & STM32H7_SPI_SR_OVR) { - dev_warn(spi->dev, "Overrun: received value discarded\n"); - if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) - stm32h7_spi_read_rxfifo(spi, false); - /* - * If overrun is detected while using DMA, it means that - * something went wrong, so stop the current transfer - */ - if (spi->cur_usedma) - end = true; + dev_err(spi->dev, "Overrun: RX data lost\n"); + end = true; } if (sr & STM32H7_SPI_SR_EOT) { @@ -961,13 +974,13 @@ if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0))) stm32h7_spi_read_rxfifo(spi, false); - writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR); + writel_relaxed(sr & mask, spi->base + STM32H7_SPI_IFCR); spin_unlock_irqrestore(&spi->lock, flags); if (end) { - spi_finalize_current_transfer(master); stm32h7_spi_disable(spi); + spi_finalize_current_transfer(master); } return IRQ_HANDLED; @@ -1395,7 +1408,7 @@ cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) & STM32H7_SPI_CFG1_DSIZE; - spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi); + spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen); fthlv = spi->cur_fthlv - 1; cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV; @@ -1578,39 +1591,33 @@ unsigned long flags; unsigned int comm_type; int nb_words, ret = 0; + int mbr; spin_lock_irqsave(&spi->lock, flags); - if (spi->cur_bpw != transfer->bits_per_word) { - spi->cur_bpw = transfer->bits_per_word; - spi->cfg->set_bpw(spi); - } + spi->cur_xferlen = transfer->len; - if (spi->cur_speed != transfer->speed_hz) { - int mbr; - - /* Update spi->cur_speed with real clock speed */ - mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz, - spi->cfg->baud_rate_div_min, - spi->cfg->baud_rate_div_max); - if (mbr < 0) { - ret = mbr; - goto out; - } + spi->cur_bpw = transfer->bits_per_word; + spi->cfg->set_bpw(spi); - transfer->speed_hz = spi->cur_speed; - stm32_spi_set_mbr(spi, mbr); + /* Update spi->cur_speed with real clock speed */ + mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz, + spi->cfg->baud_rate_div_min, + spi->cfg->baud_rate_div_max); + if (mbr < 0) { + ret = mbr; + goto out; } - comm_type = stm32_spi_communication_type(spi_dev, transfer); - if (spi->cur_comm != comm_type) { - ret = spi->cfg->set_mode(spi, comm_type); + transfer->speed_hz = spi->cur_speed; + stm32_spi_set_mbr(spi, mbr); - if (ret < 0) - goto out; + comm_type = stm32_spi_communication_type(spi_dev, transfer); + ret = spi->cfg->set_mode(spi, comm_type); + if (ret < 0) + goto out; - spi->cur_comm = comm_type; - } + spi->cur_comm = comm_type; if (spi->cfg->set_data_idleness) spi->cfg->set_data_idleness(spi, transfer->len); @@ -1628,8 +1635,6 @@ goto out; } - spi->cur_xferlen = transfer->len; - dev_dbg(spi->dev, "transfer communication mode set to %d\n", spi->cur_comm); dev_dbg(spi->dev, @@ -1660,6 +1665,10 @@ struct stm32_spi *spi = spi_master_get_devdata(master); int ret; + /* Don't do anything on 0 bytes transfers */ + if (transfer->len == 0) + return 0; + spi->tx_buf = transfer->tx_buf; spi->rx_buf = transfer->rx_buf; spi->tx_len = spi->tx_buf ? transfer->len : 0; @@ -1903,35 +1912,48 @@ master->transfer_one = stm32_spi_transfer_one; master->unprepare_message = stm32_spi_unprepare_msg; - spi->dma_tx = dma_request_slave_channel(spi->dev, "tx"); - if (!spi->dma_tx) + spi->dma_tx = dma_request_chan(spi->dev, "tx"); + if (IS_ERR(spi->dma_tx)) { + ret = PTR_ERR(spi->dma_tx); + spi->dma_tx = NULL; + if (ret == -EPROBE_DEFER) + goto err_clk_disable; + dev_warn(&pdev->dev, "failed to request tx dma channel\n"); - else + } else { master->dma_tx = spi->dma_tx; + } + + spi->dma_rx = dma_request_chan(spi->dev, "rx"); + if (IS_ERR(spi->dma_rx)) { + ret = PTR_ERR(spi->dma_rx); + spi->dma_rx = NULL; + if (ret == -EPROBE_DEFER) + goto err_dma_release; - spi->dma_rx = dma_request_slave_channel(spi->dev, "rx"); - if (!spi->dma_rx) dev_warn(&pdev->dev, "failed to request rx dma channel\n"); - else + } else { master->dma_rx = spi->dma_rx; + } if (spi->dma_tx || spi->dma_rx) master->can_dma = stm32_spi_can_dma; pm_runtime_set_active(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); pm_runtime_enable(&pdev->dev); - ret = devm_spi_register_master(&pdev->dev, master); + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi master registration failed: %d\n", ret); - goto err_dma_release; + goto err_pm_disable; } if (!master->cs_gpios) { dev_err(&pdev->dev, "no CS gpios available\n"); ret = -EINVAL; - goto err_dma_release; + goto err_pm_disable; } for (i = 0; i < master->num_chipselect; i++) { @@ -1955,13 +1977,15 @@ return 0; +err_pm_disable: + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); err_dma_release: if (spi->dma_tx) dma_release_channel(spi->dma_tx); if (spi->dma_rx) dma_release_channel(spi->dma_rx); - - pm_runtime_disable(&pdev->dev); err_clk_disable: clk_disable_unprepare(spi->clk); err_master_put: @@ -1975,8 +1999,14 @@ struct spi_master *master = platform_get_drvdata(pdev); struct stm32_spi *spi = spi_master_get_devdata(master); + pm_runtime_get_sync(&pdev->dev); + + spi_unregister_master(master); spi->cfg->disable(spi); + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); if (master->dma_tx) dma_release_channel(master->dma_tx); if (master->dma_rx) @@ -1984,7 +2014,8 @@ clk_disable_unprepare(spi->clk); - pm_runtime_disable(&pdev->dev); + + pinctrl_pm_select_sleep_state(&pdev->dev); return 0; } @@ -1997,13 +2028,18 @@ clk_disable_unprepare(spi->clk); - return 0; + return pinctrl_pm_select_sleep_state(dev); } static int stm32_spi_runtime_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct stm32_spi *spi = spi_master_get_devdata(master); + int ret; + + ret = pinctrl_pm_select_default_state(dev); + if (ret) + return ret; return clk_prepare_enable(spi->clk); } @@ -2033,10 +2069,24 @@ return ret; ret = spi_master_resume(master); - if (ret) + if (ret) { clk_disable_unprepare(spi->clk); + return ret; + } - return ret; + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + pm_runtime_put_noidle(dev); + dev_err(dev, "Unable to power device:%d\n", ret); + return ret; + } + + spi->cfg->config(spi); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; } #endif --- linux-oracle-5.4.0.orig/drivers/spi/spi-sun6i.c +++ linux-oracle-5.4.0/drivers/spi/spi-sun6i.c @@ -198,7 +198,7 @@ struct spi_transfer *tfr) { struct sun6i_spi *sspi = spi_master_get_devdata(master); - unsigned int mclk_rate, div, timeout; + unsigned int mclk_rate, div, div_cdr1, div_cdr2, timeout; unsigned int start, end, tx_time; unsigned int trig_level; unsigned int tx_len = 0; @@ -287,18 +287,20 @@ * First try CDR2, and if we can't reach the expected * frequency, fall back to CDR1. */ - div = mclk_rate / (2 * tfr->speed_hz); - if (div <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { - if (div > 0) - div--; - - reg = SUN6I_CLK_CTL_CDR2(div) | SUN6I_CLK_CTL_DRS; + div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); + div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); + if (div_cdr2 <= (SUN6I_CLK_CTL_CDR2_MASK + 1)) { + reg = SUN6I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN6I_CLK_CTL_DRS; } else { - div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); + div = min(SUN6I_CLK_CTL_CDR1_MASK, order_base_2(div_cdr1)); reg = SUN6I_CLK_CTL_CDR1(div); } sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); + /* Finally enable the bus - doing so before might raise SCK to HIGH */ + reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); + reg |= SUN6I_GBL_CTL_BUS_ENABLE; + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); /* Setup the transfer now... */ if (sspi->tx_buf) @@ -407,7 +409,7 @@ } sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, - SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); return 0; --- linux-oracle-5.4.0.orig/drivers/spi/spi-synquacer.c +++ linux-oracle-5.4.0/drivers/spi/spi-synquacer.c @@ -472,10 +472,9 @@ read_fifo(sspi); } - if (status < 0) { - dev_err(sspi->dev, "failed to transfer. status: 0x%x\n", - status); - return status; + if (status == 0) { + dev_err(sspi->dev, "failed to transfer. Timeout.\n"); + return -ETIMEDOUT; } return 0; @@ -490,6 +489,10 @@ val &= ~(SYNQUACER_HSSPI_DMPSEL_CS_MASK << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT); val |= spi->chip_select << SYNQUACER_HSSPI_DMPSEL_CS_SHIFT; + + if (!enable) + val |= SYNQUACER_HSSPI_DMSTOP_STOP; + writel(val, sspi->regs + SYNQUACER_HSSPI_REG_DMSTART); } @@ -658,7 +661,8 @@ if (!master->max_speed_hz) { dev_err(&pdev->dev, "missing clock source\n"); - return -EINVAL; + ret = -EINVAL; + goto disable_clk; } master->min_speed_hz = master->max_speed_hz / 254; @@ -671,7 +675,7 @@ rx_irq = platform_get_irq(pdev, 0); if (rx_irq <= 0) { ret = rx_irq; - goto put_spi; + goto disable_clk; } snprintf(sspi->rx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-rx", dev_name(&pdev->dev)); @@ -679,13 +683,13 @@ 0, sspi->rx_irq_name, sspi); if (ret) { dev_err(&pdev->dev, "request rx_irq failed (%d)\n", ret); - goto put_spi; + goto disable_clk; } tx_irq = platform_get_irq(pdev, 1); if (tx_irq <= 0) { ret = tx_irq; - goto put_spi; + goto disable_clk; } snprintf(sspi->tx_irq_name, SYNQUACER_HSSPI_IRQ_NAME_MAX, "%s-tx", dev_name(&pdev->dev)); @@ -693,7 +697,7 @@ 0, sspi->tx_irq_name, sspi); if (ret) { dev_err(&pdev->dev, "request tx_irq failed (%d)\n", ret); - goto put_spi; + goto disable_clk; } master->dev.of_node = np; @@ -711,7 +715,7 @@ ret = synquacer_spi_enable(master); if (ret) - goto fail_enable; + goto disable_clk; pm_runtime_set_active(sspi->dev); pm_runtime_enable(sspi->dev); @@ -724,7 +728,7 @@ disable_pm: pm_runtime_disable(sspi->dev); -fail_enable: +disable_clk: clk_disable_unprepare(sspi->clk); put_spi: spi_master_put(master); @@ -779,6 +783,7 @@ ret = synquacer_spi_enable(master); if (ret) { + clk_disable_unprepare(sspi->clk); dev_err(dev, "failed to enable spi (%d)\n", ret); return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-tegra114.c +++ linux-oracle-5.4.0/drivers/spi/spi-tegra114.c @@ -954,6 +954,7 @@ ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { + pm_runtime_put_noidle(tspi->dev); dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); if (cdata) tegra_spi_cleanup(spi); @@ -1351,6 +1352,10 @@ tspi->phys = r->start; spi_irq = platform_get_irq(pdev, 0); + if (spi_irq < 0) { + ret = spi_irq; + goto exit_free_master; + } tspi->irq = spi_irq; tspi->clk = devm_clk_get(&pdev->dev, "spi"); @@ -1472,6 +1477,7 @@ ret = pm_runtime_get_sync(dev); if (ret < 0) { + pm_runtime_put_noidle(dev); dev_err(dev, "pm runtime failed, e = %d\n", ret); return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-tegra20-sflash.c +++ linux-oracle-5.4.0/drivers/spi/spi-tegra20-sflash.c @@ -456,7 +456,11 @@ goto exit_free_master; } - tsd->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto exit_free_master; + tsd->irq = ret; + ret = request_irq(tsd->irq, tegra_sflash_isr, 0, dev_name(&pdev->dev), tsd); if (ret < 0) { @@ -551,6 +555,7 @@ ret = pm_runtime_get_sync(dev); if (ret < 0) { + pm_runtime_put_noidle(dev); dev_err(dev, "pm runtime failed, e = %d\n", ret); return ret; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-tegra20-slink.c +++ linux-oracle-5.4.0/drivers/spi/spi-tegra20-slink.c @@ -756,6 +756,7 @@ ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { + pm_runtime_put_noidle(tspi->dev); dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); return ret; } @@ -1010,14 +1011,8 @@ struct resource *r; int ret, spi_irq; const struct tegra_slink_chip_data *cdata = NULL; - const struct of_device_id *match; - match = of_match_device(tegra_slink_of_match, &pdev->dev); - if (!match) { - dev_err(&pdev->dev, "Error: No device match found\n"); - return -ENODEV; - } - cdata = match->data; + cdata = of_device_get_match_data(&pdev->dev); master = spi_alloc_master(&pdev->dev, sizeof(*tspi)); if (!master) { @@ -1073,7 +1068,7 @@ ret = clk_enable(tspi->clk); if (ret < 0) { dev_err(&pdev->dev, "Clock enable failed %d\n", ret); - goto exit_free_master; + goto exit_clk_unprepare; } spi_irq = platform_get_irq(pdev, 0); @@ -1146,6 +1141,8 @@ free_irq(spi_irq, tspi); exit_clk_disable: clk_disable(tspi->clk); +exit_clk_unprepare: + clk_unprepare(tspi->clk); exit_free_master: spi_master_put(master); return ret; @@ -1159,6 +1156,7 @@ free_irq(tspi->irq, tspi); clk_disable(tspi->clk); + clk_unprepare(tspi->clk); if (tspi->tx_dma_chan) tegra_slink_deinit_dma_param(tspi, false); @@ -1189,6 +1187,7 @@ ret = pm_runtime_get_sync(dev); if (ret < 0) { + pm_runtime_put_noidle(dev); dev_err(dev, "pm runtime failed, e = %d\n", ret); return ret; } @@ -1200,7 +1199,7 @@ } #endif -static int tegra_slink_runtime_suspend(struct device *dev) +static int __maybe_unused tegra_slink_runtime_suspend(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct tegra_slink_data *tspi = spi_master_get_devdata(master); @@ -1212,7 +1211,7 @@ return 0; } -static int tegra_slink_runtime_resume(struct device *dev) +static int __maybe_unused tegra_slink_runtime_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct tegra_slink_data *tspi = spi_master_get_devdata(master); --- linux-oracle-5.4.0.orig/drivers/spi/spi-ti-qspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-ti-qspi.c @@ -62,6 +62,7 @@ u32 dc; bool mmap_enabled; + int current_cs; }; #define QSPI_PID (0x0) @@ -175,6 +176,7 @@ ret = pm_runtime_get_sync(qspi->dev); if (ret < 0) { + pm_runtime_put_noidle(qspi->dev); dev_err(qspi->dev, "pm_runtime_get_sync() failed\n"); return ret; } @@ -399,6 +401,7 @@ enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; struct dma_async_tx_descriptor *tx; int ret; + unsigned long time_left; tx = dmaengine_prep_dma_memcpy(chan, dma_dst, dma_src, len, flags); if (!tx) { @@ -418,9 +421,9 @@ } dma_async_issue_pending(chan); - ret = wait_for_completion_timeout(&qspi->transfer_complete, + time_left = wait_for_completion_timeout(&qspi->transfer_complete, msecs_to_jiffies(len)); - if (ret <= 0) { + if (time_left == 0) { dmaengine_terminate_sync(chan); dev_err(qspi->dev, "DMA wait_for_completion_timeout\n"); return -ETIMEDOUT; @@ -487,6 +490,7 @@ MEM_CS_EN(spi->chip_select)); } qspi->mmap_enabled = true; + qspi->current_cs = spi->chip_select; } static void ti_qspi_disable_memory_map(struct spi_device *spi) @@ -498,6 +502,7 @@ regmap_update_bits(qspi->ctrl_base, qspi->ctrl_reg, MEM_CS_MASK, 0); qspi->mmap_enabled = false; + qspi->current_cs = -1; } static void ti_qspi_setup_mmap_read(struct spi_device *spi, u8 opcode, @@ -543,7 +548,7 @@ mutex_lock(&qspi->list_lock); - if (!qspi->mmap_enabled) + if (!qspi->mmap_enabled || qspi->current_cs != mem->spi->chip_select) ti_qspi_enable_memory_map(mem->spi); ti_qspi_setup_mmap_read(mem->spi, op->cmd.opcode, op->data.buswidth, op->addr.nbytes, op->dummy.nbytes); @@ -652,6 +657,17 @@ return 0; } +static void ti_qspi_dma_cleanup(struct ti_qspi *qspi) +{ + if (qspi->rx_bb_addr) + dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE, + qspi->rx_bb_addr, + qspi->rx_bb_dma_addr); + + if (qspi->rx_chan) + dma_release_channel(qspi->rx_chan); +} + static const struct of_device_id ti_qspi_match[] = { {.compatible = "ti,dra7xxx-qspi" }, {.compatible = "ti,am4372-qspi" }, @@ -799,11 +815,14 @@ } } qspi->mmap_enabled = false; + qspi->current_cs = -1; ret = devm_spi_register_master(&pdev->dev, master); if (!ret) return 0; + ti_qspi_dma_cleanup(qspi); + pm_runtime_disable(&pdev->dev); free_master: spi_master_put(master); @@ -822,12 +841,7 @@ pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); - if (qspi->rx_bb_addr) - dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE, - qspi->rx_bb_addr, - qspi->rx_bb_dma_addr); - if (qspi->rx_chan) - dma_release_channel(qspi->rx_chan); + ti_qspi_dma_cleanup(qspi); return 0; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-topcliff-pch.c +++ linux-oracle-5.4.0/drivers/spi/spi-topcliff-pch.c @@ -576,8 +576,10 @@ data->pkt_tx_buff = kzalloc(size, GFP_KERNEL); if (data->pkt_tx_buff != NULL) { data->pkt_rx_buff = kzalloc(size, GFP_KERNEL); - if (!data->pkt_rx_buff) + if (!data->pkt_rx_buff) { kfree(data->pkt_tx_buff); + data->pkt_tx_buff = NULL; + } } if (!data->pkt_rx_buff) { --- linux-oracle-5.4.0.orig/drivers/spi/spi-uniphier.c +++ linux-oracle-5.4.0/drivers/spi/spi-uniphier.c @@ -290,25 +290,32 @@ } } -static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) +static void uniphier_spi_set_fifo_threshold(struct uniphier_spi_priv *priv, + unsigned int threshold) { - unsigned int fifo_threshold, fill_bytes; u32 val; - fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, - bytes_per_word(priv->bits_per_word)); - fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); - - fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes); - - /* set fifo threshold */ val = readl(priv->base + SSI_FC); val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK); - val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold); - val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold); + val |= FIELD_PREP(SSI_FC_TXFTH_MASK, SSI_FIFO_DEPTH - threshold); + val |= FIELD_PREP(SSI_FC_RXFTH_MASK, threshold); writel(val, priv->base + SSI_FC); +} + +static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv) +{ + unsigned int fifo_threshold, fill_words; + unsigned int bpw = bytes_per_word(priv->bits_per_word); + + fifo_threshold = DIV_ROUND_UP(priv->rx_bytes, bpw); + fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH); + + uniphier_spi_set_fifo_threshold(priv, fifo_threshold); + + fill_words = fifo_threshold - + DIV_ROUND_UP(priv->rx_bytes - priv->tx_bytes, bpw); - while (fill_bytes--) + while (fill_words--) uniphier_spi_send(priv); } --- linux-oracle-5.4.0.orig/drivers/spi/spi-zynq-qspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-zynq-qspi.c @@ -533,7 +533,7 @@ zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } @@ -551,13 +551,16 @@ zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } if (op->dummy.nbytes) { tmpbuf = kzalloc(op->dummy.nbytes, GFP_KERNEL); + if (!tmpbuf) + return -ENOMEM; + memset(tmpbuf, 0xff, op->dummy.nbytes); reinit_completion(&xqspi->data_completion); xqspi->txbuf = tmpbuf; @@ -567,7 +570,7 @@ zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; @@ -591,7 +594,7 @@ zynq_qspi_write_op(xqspi, ZYNQ_QSPI_FIFO_DEPTH, true); zynq_qspi_write(xqspi, ZYNQ_QSPI_IEN_OFFSET, ZYNQ_QSPI_IXR_RXTX_MASK); - if (!wait_for_completion_interruptible_timeout(&xqspi->data_completion, + if (!wait_for_completion_timeout(&xqspi->data_completion, msecs_to_jiffies(1000))) err = -ETIMEDOUT; } --- linux-oracle-5.4.0.orig/drivers/spi/spi-zynqmp-gqspi.c +++ linux-oracle-5.4.0/drivers/spi/spi-zynqmp-gqspi.c @@ -401,9 +401,6 @@ zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry); - /* Dummy generic FIFO entry */ - zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0); - /* Manually start the generic FIFO command */ zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) | --- linux-oracle-5.4.0.orig/drivers/spi/spi.c +++ linux-oracle-5.4.0/drivers/spi/spi.c @@ -47,10 +47,6 @@ { struct spi_device *spi = to_spi_device(dev); - /* spi controllers may cleanup for released devices */ - if (spi->controller->cleanup) - spi->controller->cleanup(spi); - spi_controller_put(spi->controller); kfree(spi->driver_override); kfree(spi); @@ -401,13 +397,25 @@ spi->irq = 0; } + if (has_acpi_companion(dev) && spi->irq < 0) { + struct acpi_device *adev = to_acpi_device_node(dev->fwnode); + + spi->irq = acpi_dev_gpio_irq_get(adev, 0); + if (spi->irq == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (spi->irq < 0) + spi->irq = 0; + } + ret = dev_pm_domain_attach(dev, true); if (ret) return ret; - ret = sdrv->probe(spi); - if (ret) - dev_pm_domain_detach(dev, true); + if (sdrv->probe) { + ret = sdrv->probe(spi); + if (ret) + dev_pm_domain_detach(dev, true); + } return ret; } @@ -415,9 +423,10 @@ static int spi_drv_remove(struct device *dev) { const struct spi_driver *sdrv = to_spi_driver(dev->driver); - int ret; + int ret = 0; - ret = sdrv->remove(to_spi_device(dev)); + if (sdrv->remove) + ret = sdrv->remove(to_spi_device(dev)); dev_pm_domain_detach(dev, true); return ret; @@ -442,10 +451,8 @@ { sdrv->driver.owner = owner; sdrv->driver.bus = &spi_bus_type; - if (sdrv->probe) - sdrv->driver.probe = spi_drv_probe; - if (sdrv->remove) - sdrv->driver.remove = spi_drv_remove; + sdrv->driver.probe = spi_drv_probe; + sdrv->driver.remove = spi_drv_remove; if (sdrv->shutdown) sdrv->driver.shutdown = spi_drv_shutdown; return driver_register(&sdrv->driver); @@ -510,6 +517,7 @@ spi->dev.bus = &spi_bus_type; spi->dev.release = spidev_release; spi->cs_gpio = -ENOENT; + spi->mode = ctlr->buswidth_override_bits; spin_lock_init(&spi->statistics.lock); @@ -542,6 +550,12 @@ return 0; } +static void spi_cleanup(struct spi_device *spi) +{ + if (spi->controller->cleanup) + spi->controller->cleanup(spi); +} + /** * spi_add_device - Add spi_device allocated with spi_alloc_device * @spi: spi_device to register @@ -553,7 +567,6 @@ */ int spi_add_device(struct spi_device *spi) { - static DEFINE_MUTEX(spi_add_lock); struct spi_controller *ctlr = spi->controller; struct device *dev = ctlr->dev.parent; int status; @@ -572,7 +585,7 @@ * chipselect **BEFORE** we call setup(), else we'll trash * its configuration. Lock against concurrent add() calls. */ - mutex_lock(&spi_add_lock); + mutex_lock(&ctlr->add_lock); status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check); if (status) { @@ -581,6 +594,13 @@ goto done; } + /* Controller may unregister concurrently */ + if (IS_ENABLED(CONFIG_SPI_DYNAMIC) && + !device_is_registered(&ctlr->dev)) { + status = -ENODEV; + goto done; + } + /* Descriptors take precedence */ if (ctlr->cs_gpiods) spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select]; @@ -600,14 +620,16 @@ /* Device may be bound to an active driver when this returns */ status = device_add(&spi->dev); - if (status < 0) + if (status < 0) { dev_err(dev, "can't add %s, status %d\n", dev_name(&spi->dev), status); - else + spi_cleanup(spi); + } else { dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); + } done: - mutex_unlock(&spi_add_lock); + mutex_unlock(&ctlr->add_lock); return status; } EXPORT_SYMBOL_GPL(spi_add_device); @@ -697,7 +719,9 @@ } if (ACPI_COMPANION(&spi->dev)) acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); - device_unregister(&spi->dev); + device_del(&spi->dev); + spi_cleanup(spi); + put_device(&spi->dev); } EXPORT_SYMBOL_GPL(spi_unregister_device); @@ -825,10 +849,10 @@ int i, ret; if (vmalloced_buf || kmap_buf) { - desc_len = min_t(int, max_seg_size, PAGE_SIZE); + desc_len = min_t(unsigned long, max_seg_size, PAGE_SIZE); sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len); } else if (virt_addr_valid(buf)) { - desc_len = min_t(int, max_seg_size, ctlr->max_dma_len); + desc_len = min_t(size_t, max_seg_size, ctlr->max_dma_len); sgs = DIV_ROUND_UP(len, desc_len); } else { return -EINVAL; @@ -912,6 +936,7 @@ else rx_dev = ctlr->dev.parent; + ret = -ENOMSG; list_for_each_entry(xfer, &msg->transfers, transfer_list) { if (!ctlr->can_dma(ctlr, msg->spi, xfer)) continue; @@ -935,6 +960,9 @@ } } } + /* No transfer has been mapped, bail out with success */ + if (ret) + return 0; ctlr->cur_msg_mapped = true; @@ -1229,8 +1257,6 @@ if (msg->status && ctlr->handle_err) ctlr->handle_err(ctlr, msg); - spi_res_release(ctlr, msg); - spi_finalize_current_message(ctlr); return ret; @@ -1513,6 +1539,13 @@ spi_unmap_msg(ctlr, mesg); + /* In the prepare_messages callback the spi bus has the opportunity to + * split a transfer to smaller chunks. + * Release splited transfers here since spi_map_msg is done on the + * splited transfers. + */ + spi_res_release(ctlr, mesg); + if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { ret = ctlr->unprepare_message(ctlr, mesg); if (ret) { @@ -1711,15 +1744,7 @@ spi->mode |= SPI_3WIRE; if (of_property_read_bool(nc, "spi-lsb-first")) spi->mode |= SPI_LSB_FIRST; - - /* - * For descriptors associated with the device, polarity inversion is - * handled in the gpiolib, so all chip selects are "active high" in - * the logical sense, the gpiolib will invert the line if need be. - */ - if (ctlr->use_gpio_descriptors) - spi->mode |= SPI_CS_HIGH; - else if (of_property_read_bool(nc, "spi-cs-high")) + if (of_property_read_bool(nc, "spi-cs-high")) spi->mode |= SPI_CS_HIGH; /* Device DUAL/QUAD mode */ @@ -1783,6 +1808,15 @@ } spi->chip_select = value; + /* + * For descriptors associated with the device, polarity inversion is + * handled in the gpiolib, so all gpio chip selects are "active high" + * in the logical sense, the gpiolib will invert the line if need be. + */ + if ((ctlr->use_gpio_descriptors) && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + spi->mode |= SPI_CS_HIGH; + /* Device speed */ rc = of_property_read_u32(nc, "spi-max-frequency", &value); if (rc) { @@ -1824,6 +1858,7 @@ /* Store a pointer to the node in the device structure */ of_node_get(nc); spi->dev.of_node = nc; + spi->dev.fwnode = of_fwnode_handle(nc); /* Register the new device */ rc = spi_add_device(spi); @@ -1949,6 +1984,7 @@ } lookup->max_speed_hz = sb->connection_speed; + lookup->bits_per_word = sb->data_bit_length; if (sb->clock_phase == ACPI_SPI_SECOND_PHASE) lookup->mode |= SPI_CPHA; @@ -2010,9 +2046,10 @@ return AE_NO_MEMORY; } + ACPI_COMPANION_SET(&spi->dev, adev); spi->max_speed_hz = lookup.max_speed_hz; - spi->mode = lookup.mode; + spi->mode |= lookup.mode; spi->irq = lookup.irq; spi->bits_per_word = lookup.bits_per_word; spi->chip_select = lookup.chip_select; @@ -2020,9 +2057,6 @@ acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias, sizeof(spi->modalias)); - if (spi->irq < 0) - spi->irq = acpi_dev_gpio_irq_get(adev, 0); - acpi_device_set_enumerated(adev); adev->power.flags.ignore_parent = true; @@ -2238,6 +2272,50 @@ } EXPORT_SYMBOL_GPL(__spi_alloc_controller); +static void devm_spi_release_controller(struct device *dev, void *ctlr) +{ + spi_controller_put(*(struct spi_controller **)ctlr); +} + +/** + * __devm_spi_alloc_controller - resource-managed __spi_alloc_controller() + * @dev: physical device of SPI controller + * @size: how much zeroed driver-private data to allocate + * @slave: whether to allocate an SPI master (false) or SPI slave (true) + * Context: can sleep + * + * Allocate an SPI controller and automatically release a reference on it + * when @dev is unbound from its driver. Drivers are thus relieved from + * having to call spi_controller_put(). + * + * The arguments to this function are identical to __spi_alloc_controller(). + * + * Return: the SPI controller structure on success, else NULL. + */ +struct spi_controller *__devm_spi_alloc_controller(struct device *dev, + unsigned int size, + bool slave) +{ + struct spi_controller **ptr, *ctlr; + + ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return NULL; + + ctlr = __spi_alloc_controller(dev, size, slave); + if (ctlr) { + ctlr->devm_allocated = true; + *ptr = ctlr; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ctlr; +} +EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller); + #ifdef CONFIG_OF static int of_spi_get_gpio_numbers(struct spi_controller *ctlr) { @@ -2437,6 +2515,7 @@ spin_lock_init(&ctlr->bus_lock_spinlock); mutex_init(&ctlr->bus_lock_mutex); mutex_init(&ctlr->io_mutex); + mutex_init(&ctlr->add_lock); ctlr->bus_lock_flag = 0; init_completion(&ctlr->xfer_completion); if (!ctlr->max_dma_len) @@ -2451,7 +2530,7 @@ if (ctlr->use_gpio_descriptors) { status = spi_get_gpio_descs(ctlr); if (status) - return status; + goto free_bus_id; /* * A controller using GPIO descriptors always * supports SPI_CS_HIGH if need be. @@ -2461,7 +2540,7 @@ /* Legacy code path for GPIOs from DT */ status = of_spi_get_gpio_numbers(ctlr); if (status) - return status; + goto free_bus_id; } } @@ -2469,17 +2548,14 @@ * Even if it's just one always-selected device, there must * be at least one chipselect. */ - if (!ctlr->num_chipselect) - return -EINVAL; + if (!ctlr->num_chipselect) { + status = -EINVAL; + goto free_bus_id; + } status = device_add(&ctlr->dev); - if (status < 0) { - /* free bus id */ - mutex_lock(&board_lock); - idr_remove(&spi_master_idr, ctlr->bus_num); - mutex_unlock(&board_lock); - goto done; - } + if (status < 0) + goto free_bus_id; dev_dbg(dev, "registered %s %s\n", spi_controller_is_slave(ctlr) ? "slave" : "master", dev_name(&ctlr->dev)); @@ -2495,11 +2571,7 @@ status = spi_controller_initialize_queue(ctlr); if (status) { device_del(&ctlr->dev); - /* free bus id */ - mutex_lock(&board_lock); - idr_remove(&spi_master_idr, ctlr->bus_num); - mutex_unlock(&board_lock); - goto done; + goto free_bus_id; } } /* add statistics */ @@ -2514,7 +2586,12 @@ /* Register devices from the device tree and ACPI */ of_register_spi_devices(ctlr); acpi_register_spi_devices(ctlr); -done: + return status; + +free_bus_id: + mutex_lock(&board_lock); + idr_remove(&spi_master_idr, ctlr->bus_num); + mutex_unlock(&board_lock); return status; } EXPORT_SYMBOL_GPL(spi_register_controller); @@ -2582,6 +2659,12 @@ struct spi_controller *found; int id = ctlr->bus_num; + /* Prevent addition of new devices, unregister existing ones */ + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) + mutex_lock(&ctlr->add_lock); + + device_for_each_child(&ctlr->dev, NULL, __unregister); + /* First make sure that this controller was ever added */ mutex_lock(&board_lock); found = idr_find(&spi_master_idr, id); @@ -2594,13 +2677,22 @@ list_del(&ctlr->list); mutex_unlock(&board_lock); - device_for_each_child(&ctlr->dev, NULL, __unregister); - device_unregister(&ctlr->dev); + device_del(&ctlr->dev); + /* free bus id */ mutex_lock(&board_lock); if (found == ctlr) idr_remove(&spi_master_idr, id); mutex_unlock(&board_lock); + + if (IS_ENABLED(CONFIG_SPI_DYNAMIC)) + mutex_unlock(&ctlr->add_lock); + + /* Release the last reference on the controller if its driver + * has not yet been converted to devm_spi_alloc_master/slave(). + */ + if (!ctlr->devm_allocated) + put_device(&ctlr->dev); } EXPORT_SYMBOL_GPL(spi_unregister_controller); --- linux-oracle-5.4.0.orig/drivers/spi/spidev.c +++ linux-oracle-5.4.0/drivers/spi/spidev.c @@ -223,6 +223,11 @@ for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; n; n--, k_tmp++, u_tmp++) { + /* Ensure that also following allocations from rx_buf/tx_buf will meet + * DMA alignment requirements. + */ + unsigned int len_aligned = ALIGN(u_tmp->len, ARCH_KMALLOC_MINALIGN); + k_tmp->len = u_tmp->len; total += k_tmp->len; @@ -238,17 +243,17 @@ if (u_tmp->rx_buf) { /* this transfer needs space in RX bounce buffer */ - rx_total += k_tmp->len; + rx_total += len_aligned; if (rx_total > bufsiz) { status = -EMSGSIZE; goto done; } k_tmp->rx_buf = rx_buf; - rx_buf += k_tmp->len; + rx_buf += len_aligned; } if (u_tmp->tx_buf) { /* this transfer needs space in TX bounce buffer */ - tx_total += k_tmp->len; + tx_total += len_aligned; if (tx_total > bufsiz) { status = -EMSGSIZE; goto done; @@ -258,7 +263,7 @@ (uintptr_t) u_tmp->tx_buf, u_tmp->len)) goto done; - tx_buf += k_tmp->len; + tx_buf += len_aligned; } k_tmp->cs_change = !!u_tmp->cs_change; @@ -290,16 +295,16 @@ goto done; /* copy any rx data out of bounce buffer */ - rx_buf = spidev->rx_buffer; - for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { + for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; + n; + n--, k_tmp++, u_tmp++) { if (u_tmp->rx_buf) { if (copy_to_user((u8 __user *) - (uintptr_t) u_tmp->rx_buf, rx_buf, + (uintptr_t) u_tmp->rx_buf, k_tmp->rx_buf, u_tmp->len)) { status = -EFAULT; goto done; } - rx_buf += u_tmp->len; } } status = total; @@ -368,12 +373,23 @@ switch (cmd) { /* read requests */ case SPI_IOC_RD_MODE: - retval = put_user(spi->mode & SPI_MODE_MASK, - (__u8 __user *)arg); - break; case SPI_IOC_RD_MODE32: - retval = put_user(spi->mode & SPI_MODE_MASK, - (__u32 __user *)arg); + tmp = spi->mode; + + { + struct spi_controller *ctlr = spi->controller; + + if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + tmp &= ~SPI_CS_HIGH; + } + + if (cmd == SPI_IOC_RD_MODE) + retval = put_user(tmp & SPI_MODE_MASK, + (__u8 __user *)arg); + else + retval = put_user(tmp & SPI_MODE_MASK, + (__u32 __user *)arg); break; case SPI_IOC_RD_LSB_FIRST: retval = put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, @@ -394,6 +410,7 @@ else retval = get_user(tmp, (u32 __user *)arg); if (retval == 0) { + struct spi_controller *ctlr = spi->controller; u32 save = spi->mode; if (tmp & ~SPI_MODE_MASK) { @@ -401,6 +418,10 @@ break; } + if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && + ctlr->cs_gpiods[spi->chip_select]) + tmp |= SPI_CS_HIGH; + tmp |= spi->mode & ~SPI_MODE_MASK; spi->mode = (u16)tmp; retval = spi_setup(spi); @@ -567,7 +588,6 @@ if (!spidev->tx_buffer) { spidev->tx_buffer = kmalloc(bufsiz, GFP_KERNEL); if (!spidev->tx_buffer) { - dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); status = -ENOMEM; goto err_find_dev; } @@ -576,7 +596,6 @@ if (!spidev->rx_buffer) { spidev->rx_buffer = kmalloc(bufsiz, GFP_KERNEL); if (!spidev->rx_buffer) { - dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); status = -ENOMEM; goto err_alloc_rx_buf; } @@ -600,15 +619,20 @@ static int spidev_release(struct inode *inode, struct file *filp) { struct spidev_data *spidev; + int dofree; mutex_lock(&device_list_lock); spidev = filp->private_data; filp->private_data = NULL; + spin_lock_irq(&spidev->spi_lock); + /* ... after we unbound from the underlying device? */ + dofree = (spidev->spi == NULL); + spin_unlock_irq(&spidev->spi_lock); + /* last close? */ spidev->users--; if (!spidev->users) { - int dofree; kfree(spidev->tx_buffer); spidev->tx_buffer = NULL; @@ -616,17 +640,15 @@ kfree(spidev->rx_buffer); spidev->rx_buffer = NULL; - spin_lock_irq(&spidev->spi_lock); - if (spidev->spi) - spidev->speed_hz = spidev->spi->max_speed_hz; - - /* ... after we unbound from the underlying device? */ - dofree = (spidev->spi == NULL); - spin_unlock_irq(&spidev->spi_lock); - if (dofree) kfree(spidev); + else + spidev->speed_hz = spidev->spi->max_speed_hz; } +#ifdef CONFIG_SPI_SLAVE + if (!dofree) + spi_slave_abort(spidev->spi); +#endif mutex_unlock(&device_list_lock); return 0; @@ -775,13 +797,13 @@ { struct spidev_data *spidev = spi_get_drvdata(spi); + /* prevent new opens */ + mutex_lock(&device_list_lock); /* make sure ops on existing fds can abort cleanly */ spin_lock_irq(&spidev->spi_lock); spidev->spi = NULL; spin_unlock_irq(&spidev->spi_lock); - /* prevent new opens */ - mutex_lock(&device_list_lock); list_del(&spidev->device_entry); device_destroy(spidev_class, spidev->devt); clear_bit(MINOR(spidev->devt), minors); --- linux-oracle-5.4.0.orig/drivers/spmi/spmi-pmic-arb.c +++ linux-oracle-5.4.0/drivers/spmi/spmi-pmic-arb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved. */ #include #include @@ -505,8 +505,7 @@ static void periph_interrupt(struct spmi_pmic_arb *pmic_arb, u16 apid) { unsigned int irq; - u32 status; - int id; + u32 status, id; u8 sid = (pmic_arb->apid_data[apid].ppid >> 8) & 0xF; u8 per = pmic_arb->apid_data[apid].ppid & 0xFF; @@ -731,6 +730,7 @@ return 0; } +static struct lock_class_key qpnpint_irq_lock_class, qpnpint_irq_request_class; static void qpnpint_irq_domain_map(struct spmi_pmic_arb *pmic_arb, struct irq_domain *domain, unsigned int virq, @@ -746,6 +746,9 @@ else handler = handle_level_irq; + + irq_set_lockdep_class(virq, &qpnpint_irq_lock_class, + &qpnpint_irq_request_class); irq_domain_set_info(domain, virq, hwirq, &pmic_arb_irqchip, pmic_arb, handler, NULL, NULL); } @@ -884,7 +887,8 @@ * version 5, there is more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID - * for a given PPID will receive interrupts from the PPID. + * which has the IRQ owner bit set for a given PPID will receive + * interrupts from the PPID. */ for (i = 0; ; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(i); @@ -907,16 +911,16 @@ apid = pmic_arb->ppid_to_apid[ppid] & ~PMIC_ARB_APID_VALID; prev_apidd = &pmic_arb->apid_data[apid]; - if (valid && is_irq_ee && - prev_apidd->write_ee == pmic_arb->ee) { + if (!valid || apidd->write_ee == pmic_arb->ee) { + /* First PPID mapping or one for this EE */ + pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; + } else if (valid && is_irq_ee && + prev_apidd->write_ee == pmic_arb->ee) { /* * Duplicate PPID mapping after the one for this EE; * override the irq owner */ prev_apidd->irq_ee = apidd->irq_ee; - } else if (!valid || is_irq_ee) { - /* First PPID mapping or duplicate for another EE */ - pmic_arb->ppid_to_apid[ppid] = i | PMIC_ARB_APID_VALID; } apidd->ppid = ppid; --- linux-oracle-5.4.0.orig/drivers/spmi/spmi.c +++ linux-oracle-5.4.0/drivers/spmi/spmi.c @@ -348,7 +348,8 @@ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver); pm_runtime_get_sync(dev); - sdrv->remove(to_spmi_device(dev)); + if (sdrv->remove) + sdrv->remove(to_spmi_device(dev)); pm_runtime_put_noidle(dev); pm_runtime_disable(dev); --- linux-oracle-5.4.0.orig/drivers/ssb/driver_chipcommon.c +++ linux-oracle-5.4.0/drivers/ssb/driver_chipcommon.c @@ -119,7 +119,7 @@ static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc) { struct ssb_bus *bus = cc->dev->bus; - u32 uninitialized_var(tmp); + u32 tmp; if (cc->dev->id.revision < 6) { if (bus->bustype == SSB_BUSTYPE_SSB || @@ -149,7 +149,7 @@ /* Get maximum or minimum (depending on get_max flag) slowclock frequency. */ static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max) { - int uninitialized_var(limit); + int limit; enum ssb_clksrc clocksrc; int divisor = 1; u32 tmp; --- linux-oracle-5.4.0.orig/drivers/ssb/main.c +++ linux-oracle-5.4.0/drivers/ssb/main.c @@ -340,11 +340,13 @@ static int ssb_device_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); + struct ssb_device *ssb_dev; if (!dev) return -ENODEV; + ssb_dev = dev_to_ssb_dev(dev); + return add_uevent_var(env, "MODALIAS=ssb:v%04Xid%04Xrev%02X", ssb_dev->id.vendor, ssb_dev->id.coreid, @@ -835,7 +837,7 @@ case SSB_CHIPCO_CLK_F6_7: return 7; } - return 0; + return 1; } /* Calculate the speed the backplane would run at a given set of clockcontrol values */ --- linux-oracle-5.4.0.orig/drivers/ssb/scan.c +++ linux-oracle-5.4.0/drivers/ssb/scan.c @@ -325,6 +325,7 @@ if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { pr_err("More than %d ssb cores found (%d)\n", SSB_MAX_NR_CORES, bus->nr_devices); + err = -EINVAL; goto err_unmap; } if (bus->bustype == SSB_BUSTYPE_SSB) { --- linux-oracle-5.4.0.orig/drivers/ssb/sdio.c +++ linux-oracle-5.4.0/drivers/ssb/sdio.c @@ -411,7 +411,6 @@ sdio_claim_host(bus->host_sdio); if (unlikely(ssb_sdio_switch_core(bus, dev))) { error = -EIO; - memset((void *)buffer, 0xff, count); goto err_out; } offset |= bus->sdio_sbaddr & 0xffff; --- linux-oracle-5.4.0.orig/drivers/staging/android/Kconfig +++ linux-oracle-5.4.0/drivers/staging/android/Kconfig @@ -4,7 +4,7 @@ if ANDROID config ASHMEM - bool "Enable the Anonymous Shared Memory Subsystem" + tristate "Enable the Anonymous Shared Memory Subsystem" depends on SHMEM help The ashmem subsystem is a new shared memory allocator, similar to --- linux-oracle-5.4.0.orig/drivers/staging/android/Makefile +++ linux-oracle-5.4.0/drivers/staging/android/Makefile @@ -3,5 +3,6 @@ obj-y += ion/ -obj-$(CONFIG_ASHMEM) += ashmem.o +ashmem_linux-y += ashmem.o +obj-$(CONFIG_ASHMEM) += ashmem_linux.o obj-$(CONFIG_ANDROID_VSOC) += vsoc.o --- linux-oracle-5.4.0.orig/drivers/staging/android/ashmem.c +++ linux-oracle-5.4.0/drivers/staging/android/ashmem.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,15 @@ static struct kmem_cache *ashmem_area_cachep __read_mostly; static struct kmem_cache *ashmem_range_cachep __read_mostly; +/* + * A separate lockdep class for the backing shmem inodes to resolve the lockdep + * warning about the race between kswapd taking fs_reclaim before inode_lock + * and write syscall taking inode_lock and then fs_reclaim. + * Note that such race is impossible because ashmem does not support write + * syscalls operating on the backing shmem. + */ +static struct lock_class_key backing_shmem_inode_class; + static inline unsigned long range_size(struct ashmem_range *range) { return range->pgend - range->pgstart + 1; @@ -351,8 +361,23 @@ _calc_vm_trans(prot, PROT_EXEC, VM_MAYEXEC); } +static int ashmem_vmfile_mmap(struct file *file, struct vm_area_struct *vma) +{ + /* do not allow to mmap ashmem backing shmem file directly */ + return -EPERM; +} + +static unsigned long +ashmem_vmfile_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + return current->mm->get_unmapped_area(file, addr, len, pgoff, flags); +} + static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) { + static struct file_operations vmfile_fops; struct ashmem_area *asma = file->private_data; int ret = 0; @@ -381,6 +406,7 @@ if (!asma->file) { char *name = ASHMEM_NAME_DEF; struct file *vmfile; + struct inode *inode; if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0') name = asma->name; @@ -392,7 +418,22 @@ goto out; } vmfile->f_mode |= FMODE_LSEEK; + inode = file_inode(vmfile); + lockdep_set_class(&inode->i_rwsem, &backing_shmem_inode_class); asma->file = vmfile; + /* + * override mmap operation of the vmfile so that it can't be + * remapped which would lead to creation of a new vma with no + * asma permission checks. Have to override get_unmapped_area + * as well to prevent VM_BUG_ON check for f_ops modification. + */ + if (!vmfile_fops.mmap) { + vmfile_fops = *vmfile->f_op; + vmfile_fops.mmap = ashmem_vmfile_mmap; + vmfile_fops.get_unmapped_area = + ashmem_vmfile_get_unmapped_area; + } + vmfile->f_op = &vmfile_fops; } get_file(asma->file); @@ -924,4 +965,18 @@ out: return ret; } -device_initcall(ashmem_init); + +static void __exit ashmem_exit(void) +{ + misc_deregister(&ashmem_misc); + unregister_shrinker(&ashmem_shrinker); + kmem_cache_destroy(ashmem_range_cachep); + kmem_cache_destroy(ashmem_area_cachep); +} + +module_init(ashmem_init); +module_exit(ashmem_exit); + +MODULE_AUTHOR("Google, Inc."); +MODULE_DESCRIPTION("Driver for Android shared memory device"); +MODULE_LICENSE("GPL v2"); --- linux-oracle-5.4.0.orig/drivers/staging/android/ion/ion.c +++ linux-oracle-5.4.0/drivers/staging/android/ion/ion.c @@ -114,6 +114,9 @@ void *vaddr; if (buffer->kmap_cnt) { + if (buffer->kmap_cnt == INT_MAX) + return ERR_PTR(-EOVERFLOW); + buffer->kmap_cnt++; return buffer->vaddr; } --- linux-oracle-5.4.0.orig/drivers/staging/android/ion/ion_heap.c +++ linux-oracle-5.4.0/drivers/staging/android/ion/ion_heap.c @@ -99,12 +99,12 @@ static int ion_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot) { - void *addr = vm_map_ram(pages, num, -1, pgprot); + void *addr = vmap(pages, num, VM_MAP, pgprot); if (!addr) return -ENOMEM; memset(addr, 0, PAGE_SIZE * num); - vm_unmap_ram(addr, num); + vunmap(addr); return 0; } --- linux-oracle-5.4.0.orig/drivers/staging/axis-fifo/Kconfig +++ linux-oracle-5.4.0/drivers/staging/axis-fifo/Kconfig @@ -4,7 +4,7 @@ # config XIL_AXIS_FIFO tristate "Xilinx AXI-Stream FIFO IP core driver" - depends on OF + depends on OF && HAS_IOMEM help This adds support for the Xilinx AXI-Stream FIFO IP core driver. The AXI Streaming FIFO allows memory mapped access to a AXI Streaming --- linux-oracle-5.4.0.orig/drivers/staging/board/board.c +++ linux-oracle-5.4.0/drivers/staging/board/board.c @@ -136,6 +136,7 @@ static int board_staging_add_dev_domain(struct platform_device *pdev, const char *domain) { + struct device *dev = &pdev->dev; struct of_phandle_args pd_args; struct device_node *np; @@ -148,7 +149,11 @@ pd_args.np = np; pd_args.args_count = 0; - return of_genpd_add_device(&pd_args, &pdev->dev); + /* Initialization similar to device_pm_init_common() */ + spin_lock_init(&dev->power.lock); + dev->power.early_init = true; + + return of_genpd_add_device(&pd_args, dev); } #else static inline int board_staging_add_dev_domain(struct platform_device *pdev, --- linux-oracle-5.4.0.orig/drivers/staging/comedi/comedi_fops.c +++ linux-oracle-5.4.0/drivers/staging/comedi/comedi_fops.c @@ -2383,6 +2383,18 @@ start += PAGE_SIZE; } + +#ifdef CONFIG_MMU + /* + * Leaving behind a partial mapping of a buffer we're about to + * drop is unsafe, see remap_pfn_range_notrack(). + * We need to zap the range here ourselves instead of relying + * on the automatic zapping in remap_pfn_range() because we call + * remap_pfn_range() in a loop. + */ + if (retval) + zap_vma_ptes(vma, vma->vm_start, size); +#endif } if (retval == 0) { @@ -2725,8 +2737,10 @@ } cfp = kzalloc(sizeof(*cfp), GFP_KERNEL); - if (!cfp) + if (!cfp) { + comedi_dev_put(dev); return -ENOMEM; + } cfp->dev = dev; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/addi_apci_1032.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/addi_apci_1032.c @@ -106,14 +106,22 @@ unsigned int *data) { struct apci1032_private *devpriv = dev->private; - unsigned int shift, oldmask; + unsigned int shift, oldmask, himask, lomask; switch (data[0]) { case INSN_CONFIG_DIGITAL_TRIG: if (data[1] != 0) return -EINVAL; shift = data[3]; - oldmask = (1U << shift) - 1; + if (shift < 32) { + oldmask = (1U << shift) - 1; + himask = data[4] << shift; + lomask = data[5] << shift; + } else { + oldmask = 0xffffffffu; + himask = 0; + lomask = 0; + } switch (data[2]) { case COMEDI_DIGITAL_TRIG_DISABLE: devpriv->ctrl = 0; @@ -136,8 +144,8 @@ devpriv->mode2 &= oldmask; } /* configure specified channels */ - devpriv->mode1 |= data[4] << shift; - devpriv->mode2 |= data[5] << shift; + devpriv->mode1 |= himask; + devpriv->mode2 |= lomask; break; case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: if (devpriv->ctrl != (APCI1032_CTRL_INT_ENA | @@ -154,8 +162,8 @@ devpriv->mode2 &= oldmask; } /* configure specified channels */ - devpriv->mode1 |= data[4] << shift; - devpriv->mode2 |= data[5] << shift; + devpriv->mode1 |= himask; + devpriv->mode2 |= lomask; break; default: return -EINVAL; @@ -252,6 +260,7 @@ struct apci1032_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; unsigned int ctrl; + unsigned short val; /* check interrupt is from this device */ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) & @@ -267,7 +276,8 @@ outl(ctrl & ~APCI1032_CTRL_INT_ENA, dev->iobase + APCI1032_CTRL_REG); s->state = inl(dev->iobase + APCI1032_STATUS_REG) & 0xffff; - comedi_buf_write_samples(s, &s->state, 1); + val = s->state; + comedi_buf_write_samples(s, &val, 1); comedi_handle_events(dev, s); /* enable the interrupt */ --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/addi_apci_1500.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/addi_apci_1500.c @@ -208,7 +208,7 @@ struct comedi_device *dev = d; struct apci1500_private *devpriv = dev->private; struct comedi_subdevice *s = dev->read_subdev; - unsigned int status = 0; + unsigned short status = 0; unsigned int val; val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); @@ -238,14 +238,14 @@ * * Mask Meaning * ---------- ------------------------------------------ - * 0x00000001 Event 1 has occurred - * 0x00000010 Event 2 has occurred - * 0x00000100 Counter/timer 1 has run down (not implemented) - * 0x00001000 Counter/timer 2 has run down (not implemented) - * 0x00010000 Counter 3 has run down (not implemented) - * 0x00100000 Watchdog has run down (not implemented) - * 0x01000000 Voltage error - * 0x10000000 Short-circuit error + * 0b00000001 Event 1 has occurred + * 0b00000010 Event 2 has occurred + * 0b00000100 Counter/timer 1 has run down (not implemented) + * 0b00001000 Counter/timer 2 has run down (not implemented) + * 0b00010000 Counter 3 has run down (not implemented) + * 0b00100000 Watchdog has run down (not implemented) + * 0b01000000 Voltage error + * 0b10000000 Short-circuit error */ comedi_buf_write_samples(s, &status, 1); comedi_handle_events(dev, s); @@ -452,13 +452,14 @@ struct apci1500_private *devpriv = dev->private; unsigned int trig = data[1]; unsigned int shift = data[3]; - unsigned int hi_mask = data[4] << shift; - unsigned int lo_mask = data[5] << shift; - unsigned int chan_mask = hi_mask | lo_mask; - unsigned int old_mask = (1 << shift) - 1; - unsigned int pm = devpriv->pm[trig] & old_mask; - unsigned int pt = devpriv->pt[trig] & old_mask; - unsigned int pp = devpriv->pp[trig] & old_mask; + unsigned int hi_mask; + unsigned int lo_mask; + unsigned int chan_mask; + unsigned int old_mask; + unsigned int pm; + unsigned int pt; + unsigned int pp; + unsigned int invalid_chan; if (trig > 1) { dev_dbg(dev->class_dev, @@ -466,11 +467,28 @@ return -EINVAL; } - if (chan_mask > 0xffff) { + if (shift <= 16) { + hi_mask = data[4] << shift; + lo_mask = data[5] << shift; + old_mask = (1U << shift) - 1; + invalid_chan = (data[4] | data[5]) >> (16 - shift); + } else { + hi_mask = 0; + lo_mask = 0; + old_mask = 0xffff; + invalid_chan = data[4] | data[5]; + } + chan_mask = hi_mask | lo_mask; + + if (invalid_chan) { dev_dbg(dev->class_dev, "invalid digital trigger channel\n"); return -EINVAL; } + pm = devpriv->pm[trig] & old_mask; + pt = devpriv->pt[trig] & old_mask; + pp = devpriv->pp[trig] & old_mask; + switch (data[2]) { case COMEDI_DIGITAL_TRIG_DISABLE: /* clear trigger configuration */ --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/addi_apci_1564.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -331,14 +331,22 @@ unsigned int *data) { struct apci1564_private *devpriv = dev->private; - unsigned int shift, oldmask; + unsigned int shift, oldmask, himask, lomask; switch (data[0]) { case INSN_CONFIG_DIGITAL_TRIG: if (data[1] != 0) return -EINVAL; shift = data[3]; - oldmask = (1U << shift) - 1; + if (shift < 32) { + oldmask = (1U << shift) - 1; + himask = data[4] << shift; + lomask = data[5] << shift; + } else { + oldmask = 0xffffffffu; + himask = 0; + lomask = 0; + } switch (data[2]) { case COMEDI_DIGITAL_TRIG_DISABLE: devpriv->ctrl = 0; @@ -362,8 +370,8 @@ devpriv->mode2 &= oldmask; } /* configure specified channels */ - devpriv->mode1 |= data[4] << shift; - devpriv->mode2 |= data[5] << shift; + devpriv->mode1 |= himask; + devpriv->mode2 |= lomask; break; case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: if (devpriv->ctrl != (APCI1564_DI_IRQ_ENA | @@ -380,8 +388,8 @@ devpriv->mode2 &= oldmask; } /* configure specified channels */ - devpriv->mode1 |= data[4] << shift; - devpriv->mode2 |= data[5] << shift; + devpriv->mode1 |= himask; + devpriv->mode2 |= lomask; break; default: return -EINVAL; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/adv_pci1710.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/adv_pci1710.c @@ -46,8 +46,8 @@ #define PCI171X_RANGE_UNI BIT(4) #define PCI171X_RANGE_GAIN(x) (((x) & 0x7) << 0) #define PCI171X_MUX_REG 0x04 /* W: A/D multiplexor control */ -#define PCI171X_MUX_CHANH(x) (((x) & 0xf) << 8) -#define PCI171X_MUX_CHANL(x) (((x) & 0xf) << 0) +#define PCI171X_MUX_CHANH(x) (((x) & 0xff) << 8) +#define PCI171X_MUX_CHANL(x) (((x) & 0xff) << 0) #define PCI171X_MUX_CHAN(x) (PCI171X_MUX_CHANH(x) | PCI171X_MUX_CHANL(x)) #define PCI171X_STATUS_REG 0x06 /* R: status register */ #define PCI171X_STATUS_IRQ BIT(11) /* 1=IRQ occurred */ @@ -300,11 +300,11 @@ static int pci1710_ai_read_sample(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int cur_chan, - unsigned int *val) + unsigned short *val) { const struct boardtype *board = dev->board_ptr; struct pci1710_private *devpriv = dev->private; - unsigned int sample; + unsigned short sample; unsigned int chan; sample = inw(dev->iobase + PCI171X_AD_DATA_REG); @@ -345,7 +345,7 @@ pci1710_ai_setup_chanlist(dev, s, &insn->chanspec, 1, 1); for (i = 0; i < insn->n; i++) { - unsigned int val; + unsigned short val; /* start conversion */ outw(0, dev->iobase + PCI171X_SOFTTRG_REG); @@ -395,7 +395,7 @@ { struct comedi_cmd *cmd = &s->async->cmd; unsigned int status; - unsigned int val; + unsigned short val; int ret; status = inw(dev->iobase + PCI171X_STATUS_REG); @@ -455,7 +455,7 @@ } for (i = 0; i < devpriv->max_samples; i++) { - unsigned int val; + unsigned short val; int ret; ret = pci1710_ai_read_sample(dev, s, s->async->cur_chan, &val); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/adv_pci1760.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/adv_pci1760.c @@ -59,7 +59,7 @@ #define PCI1760_CMD_CLR_IMB2 0x00 /* Clears IMB2 */ #define PCI1760_CMD_SET_DO 0x01 /* Set output state */ #define PCI1760_CMD_GET_DO 0x02 /* Read output status */ -#define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */ +#define PCI1760_CMD_GET_STATUS 0x07 /* Read current status */ #define PCI1760_CMD_GET_FW_VER 0x0e /* Read firmware version */ #define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */ #define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */ --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/cb_pcidas.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1281,7 +1281,7 @@ devpriv->amcc + AMCC_OP_REG_INTCSR); ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED, - dev->board_name, dev); + "cb_pcidas", dev); if (ret) { dev_dbg(dev->class_dev, "unable to allocate irq %d\n", pcidev->irq); @@ -1342,6 +1342,7 @@ if (dev->irq && board->has_ao_fifo) { dev->write_subdev = s; s->subdev_flags |= SDF_CMD_WRITE; + s->len_chanlist = s->n_chan; s->do_cmdtest = cb_pcidas_ao_cmdtest; s->do_cmd = cb_pcidas_ao_cmd; s->cancel = cb_pcidas_ao_cancel; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/cb_pcidas64.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -4035,7 +4035,7 @@ init_stc_registers(dev); retval = request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, - dev->board_name, dev); + "cb_pcidas64", dev); if (retval) { dev_dbg(dev->class_dev, "unable to allocate irq %u\n", pcidev->irq); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/comedi_test.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/comedi_test.c @@ -87,6 +87,8 @@ struct comedi_device *dev; /* parent comedi device */ u64 ao_last_scan_time; /* time of previous AO scan in usec */ unsigned int ao_scan_period; /* AO scan period in usec */ + bool ai_timer_enable:1; /* should AI timer be running? */ + bool ao_timer_enable:1; /* should AO timer be running? */ unsigned short ao_loopbacks[N_CHANS]; }; @@ -236,8 +238,12 @@ time_increment = devpriv->ai_convert_time - now; else time_increment = 1; - mod_timer(&devpriv->ai_timer, - jiffies + usecs_to_jiffies(time_increment)); + spin_lock(&dev->spinlock); + if (devpriv->ai_timer_enable) { + mod_timer(&devpriv->ai_timer, + jiffies + usecs_to_jiffies(time_increment)); + } + spin_unlock(&dev->spinlock); } overrun: @@ -393,9 +399,12 @@ * Seem to need an extra jiffy here, otherwise timer expires slightly * early! */ + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = true; devpriv->ai_timer.expires = jiffies + usecs_to_jiffies(devpriv->ai_convert_period) + 1; add_timer(&devpriv->ai_timer); + spin_unlock_bh(&dev->spinlock); return 0; } @@ -404,6 +413,9 @@ { struct waveform_private *devpriv = dev->private; + spin_lock_bh(&dev->spinlock); + devpriv->ai_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ai_timer); @@ -495,8 +507,12 @@ unsigned int time_inc = devpriv->ao_last_scan_time + devpriv->ao_scan_period - now; - mod_timer(&devpriv->ao_timer, - jiffies + usecs_to_jiffies(time_inc)); + spin_lock(&dev->spinlock); + if (devpriv->ao_timer_enable) { + mod_timer(&devpriv->ao_timer, + jiffies + usecs_to_jiffies(time_inc)); + } + spin_unlock(&dev->spinlock); } underrun: @@ -517,9 +533,12 @@ async->inttrig = NULL; devpriv->ao_last_scan_time = ktime_to_us(ktime_get()); + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = true; devpriv->ao_timer.expires = jiffies + usecs_to_jiffies(devpriv->ao_scan_period); add_timer(&devpriv->ao_timer); + spin_unlock_bh(&dev->spinlock); return 1; } @@ -604,6 +623,9 @@ struct waveform_private *devpriv = dev->private; s->async->inttrig = NULL; + spin_lock_bh(&dev->spinlock); + devpriv->ao_timer_enable = false; + spin_unlock_bh(&dev->spinlock); if (in_softirq()) { /* Assume we were called from the timer routine itself. */ del_timer(&devpriv->ao_timer); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/das6402.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/das6402.c @@ -186,7 +186,7 @@ if (status & DAS6402_STATUS_FFULL) { async->events |= COMEDI_CB_OVERFLOW; } else if (status & DAS6402_STATUS_FFNE) { - unsigned int val; + unsigned short val; val = das6402_ai_read_sample(dev, s); comedi_buf_write_samples(s, &val, 1); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/das800.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/das800.c @@ -427,7 +427,7 @@ struct comedi_cmd *cmd; unsigned long irq_flags; unsigned int status; - unsigned int val; + unsigned short val; bool fifo_empty; bool fifo_overflow; int i; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/dmm32at.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/dmm32at.c @@ -404,7 +404,7 @@ { struct comedi_device *dev = d; unsigned char intstat; - unsigned int val; + unsigned short val; int i; if (!dev->attached) { --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/dt2815.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/dt2815.c @@ -92,6 +92,7 @@ int ret; for (i = 0; i < insn->n; i++) { + /* FIXME: lo bit 0 chooses voltage output or current output */ lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01; hi = (data[i] & 0xff0) >> 4; @@ -105,6 +106,8 @@ if (ret) return ret; + outb(hi, dev->iobase + DT2815_DATA); + devpriv->ao_readback[chan] = data[i]; } return i; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/dt9812.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/dt9812.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "../comedi_usb.h" @@ -237,22 +238,42 @@ { struct usb_device *usb = comedi_to_usb_dev(dev); struct dt9812_private *devpriv = dev->private; - struct dt9812_usb_cmd cmd; + struct dt9812_usb_cmd *cmd; + size_t tbuf_size; int count, ret; + void *tbuf; - cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA); - cmd.u.flash_data_info.address = + tbuf_size = max(sizeof(*cmd), buf_size); + + tbuf = kzalloc(tbuf_size, GFP_KERNEL); + if (!tbuf) + return -ENOMEM; + + cmd = tbuf; + + cmd->cmd = cpu_to_le32(DT9812_R_FLASH_DATA); + cmd->u.flash_data_info.address = cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset); - cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size); + cmd->u.flash_data_info.numbytes = cpu_to_le16(buf_size); /* DT9812 only responds to 32 byte writes!! */ ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), - &cmd, 32, &count, DT9812_USB_TIMEOUT); + cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); if (ret) - return ret; + goto out; + + ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), + tbuf, buf_size, &count, DT9812_USB_TIMEOUT); + if (!ret) { + if (count == buf_size) + memcpy(buf, tbuf, buf_size); + else + ret = -EREMOTEIO; + } +out: + kfree(tbuf); - return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), - buf, buf_size, &count, DT9812_USB_TIMEOUT); + return ret; } static int dt9812_read_multiple_registers(struct comedi_device *dev, @@ -261,22 +282,42 @@ { struct usb_device *usb = comedi_to_usb_dev(dev); struct dt9812_private *devpriv = dev->private; - struct dt9812_usb_cmd cmd; + struct dt9812_usb_cmd *cmd; int i, count, ret; + size_t buf_size; + void *buf; + + buf_size = max_t(size_t, sizeof(*cmd), reg_count); + + buf = kzalloc(buf_size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + cmd = buf; - cmd.cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); - cmd.u.read_multi_info.count = reg_count; + cmd->cmd = cpu_to_le32(DT9812_R_MULTI_BYTE_REG); + cmd->u.read_multi_info.count = reg_count; for (i = 0; i < reg_count; i++) - cmd.u.read_multi_info.address[i] = address[i]; + cmd->u.read_multi_info.address[i] = address[i]; /* DT9812 only responds to 32 byte writes!! */ ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), - &cmd, 32, &count, DT9812_USB_TIMEOUT); + cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); if (ret) - return ret; + goto out; - return usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), - value, reg_count, &count, DT9812_USB_TIMEOUT); + ret = usb_bulk_msg(usb, usb_rcvbulkpipe(usb, devpriv->cmd_rd.addr), + buf, reg_count, &count, DT9812_USB_TIMEOUT); + if (!ret) { + if (count == reg_count) + memcpy(value, buf, reg_count); + else + ret = -EREMOTEIO; + } +out: + kfree(buf); + + return ret; } static int dt9812_write_multiple_registers(struct comedi_device *dev, @@ -285,19 +326,27 @@ { struct usb_device *usb = comedi_to_usb_dev(dev); struct dt9812_private *devpriv = dev->private; - struct dt9812_usb_cmd cmd; + struct dt9812_usb_cmd *cmd; int i, count; + int ret; - cmd.cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); - cmd.u.read_multi_info.count = reg_count; + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; + + cmd->cmd = cpu_to_le32(DT9812_W_MULTI_BYTE_REG); + cmd->u.read_multi_info.count = reg_count; for (i = 0; i < reg_count; i++) { - cmd.u.write_multi_info.write[i].address = address[i]; - cmd.u.write_multi_info.write[i].value = value[i]; + cmd->u.write_multi_info.write[i].address = address[i]; + cmd->u.write_multi_info.write[i].value = value[i]; } /* DT9812 only responds to 32 byte writes!! */ - return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), - &cmd, 32, &count, DT9812_USB_TIMEOUT); + ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), + cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); + kfree(cmd); + + return ret; } static int dt9812_rmw_multiple_registers(struct comedi_device *dev, @@ -306,17 +355,25 @@ { struct usb_device *usb = comedi_to_usb_dev(dev); struct dt9812_private *devpriv = dev->private; - struct dt9812_usb_cmd cmd; + struct dt9812_usb_cmd *cmd; int i, count; + int ret; + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) + return -ENOMEM; - cmd.cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); - cmd.u.rmw_multi_info.count = reg_count; + cmd->cmd = cpu_to_le32(DT9812_RMW_MULTI_BYTE_REG); + cmd->u.rmw_multi_info.count = reg_count; for (i = 0; i < reg_count; i++) - cmd.u.rmw_multi_info.rmw[i] = rmw[i]; + cmd->u.rmw_multi_info.rmw[i] = rmw[i]; /* DT9812 only responds to 32 byte writes!! */ - return usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), - &cmd, 32, &count, DT9812_USB_TIMEOUT); + ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr), + cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT); + kfree(cmd); + + return ret; } static int dt9812_digital_in(struct comedi_device *dev, u8 *bits) --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/gsc_hpdi.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/gsc_hpdi.c @@ -623,6 +623,11 @@ dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE, &devpriv->dio_buffer_phys_addr[i], GFP_KERNEL); + if (!devpriv->dio_buffer[i]) { + dev_warn(dev->class_dev, + "failed to allocate DMA buffer\n"); + return -ENOMEM; + } } /* allocate dma descriptors */ devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev, @@ -630,6 +635,11 @@ NUM_DMA_DESCRIPTORS, &devpriv->dma_desc_phys_addr, GFP_KERNEL); + if (!devpriv->dma_desc) { + dev_warn(dev->class_dev, + "failed to allocate DMA descriptors\n"); + return -ENOMEM; + } if (devpriv->dma_desc_phys_addr & 0xf) { dev_warn(dev->class_dev, " dma descriptors not quad-word aligned (bug)\n"); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/me4000.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/me4000.c @@ -924,7 +924,7 @@ struct comedi_subdevice *s = dev->read_subdev; int i; int c = 0; - unsigned int lval; + unsigned short lval; if (!dev->attached) return IRQ_NONE; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/mf6x4.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/mf6x4.c @@ -112,8 +112,9 @@ struct mf6x4_private *devpriv = dev->private; unsigned int status; + /* EOLC goes low at end of conversion. */ status = ioread32(devpriv->gpioc_reg); - if (status & MF6X4_GPIOC_EOLC) + if ((status & MF6X4_GPIOC_EOLC) == 0) return 0; return -EBUSY; } --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/ni_6527.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/ni_6527.c @@ -332,7 +332,7 @@ case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: /* check shift amount */ shift = data[3]; - if (shift >= s->n_chan) { + if (shift >= 32) { mask = 0; rising = 0; falling = 0; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/ni_routes.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/ni_routes.c @@ -74,9 +74,6 @@ } } - if (!rv) - return -ENODATA; - /* Second, find the set of routes valid for this device. */ for (i = 0; ni_device_routes_list[i]; ++i) { if (memcmp(ni_device_routes_list[i]->device, board_name, @@ -86,12 +83,12 @@ } } - if (!dr) - return -ENODATA; - tables->route_values = rv; tables->valid_routes = dr; + if (!rv || !dr) + return -ENODATA; + return 0; } @@ -489,6 +486,9 @@ { int src; + if (!tables->route_values) + return -EINVAL; + dest = B(dest); /* subtract NI names offset */ /* ensure we are not going to under/over run the route value table */ if (dest < 0 || dest >= NI_NUM_NAMES) --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/ni_usb6501.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/ni_usb6501.c @@ -144,6 +144,10 @@ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00}; +/* Largest supported packets */ +static const size_t TX_MAX_SIZE = sizeof(SET_PORT_DIR_REQUEST); +static const size_t RX_MAX_SIZE = sizeof(READ_PORT_RESPONSE); + enum commands { READ_PORT, WRITE_PORT, @@ -501,6 +505,12 @@ if (!devpriv->ep_rx || !devpriv->ep_tx) return -ENODEV; + if (usb_endpoint_maxp(devpriv->ep_rx) < RX_MAX_SIZE) + return -ENODEV; + + if (usb_endpoint_maxp(devpriv->ep_tx) < TX_MAX_SIZE) + return -ENODEV; + return 0; } --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/pcl711.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/pcl711.c @@ -184,7 +184,7 @@ struct comedi_device *dev = d; struct comedi_subdevice *s = dev->read_subdev; struct comedi_cmd *cmd = &s->async->cmd; - unsigned int data; + unsigned short data; if (!dev->attached) { dev_err(dev->class_dev, "spurious interrupt\n"); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/pcl818.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/pcl818.c @@ -423,7 +423,7 @@ static bool pcl818_ai_write_sample(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int chan, unsigned int val) + unsigned int chan, unsigned short val) { struct pcl818_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/usbduxfast.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/usbduxfast.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk + * Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk */ /* @@ -8,7 +8,7 @@ * Description: University of Stirling USB DAQ & INCITE Technology Limited * Devices: [ITL] USB-DUX-FAST (usbduxfast) * Author: Bernd Porr - * Updated: 10 Oct 2014 + * Updated: 16 Nov 2019 * Status: stable */ @@ -22,6 +22,7 @@ * * * Revision history: + * 1.0: Fixed a rounding error in usbduxfast_ai_cmdtest * 0.9: Dropping the first data packet which seems to be from the last transfer. * Buffer overflows in the FX2 are handed over to comedi. * 0.92: Dropping now 4 packets. The quad buffer has to be emptied. @@ -350,6 +351,7 @@ struct comedi_cmd *cmd) { int err = 0; + int err2 = 0; unsigned int steps; unsigned int arg; @@ -399,11 +401,16 @@ */ steps = (cmd->convert_arg * 30) / 1000; if (cmd->chanlist_len != 1) - err |= comedi_check_trigger_arg_min(&steps, - MIN_SAMPLING_PERIOD); - err |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD); - arg = (steps * 1000) / 30; - err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); + err2 |= comedi_check_trigger_arg_min(&steps, + MIN_SAMPLING_PERIOD); + else + err2 |= comedi_check_trigger_arg_min(&steps, 1); + err2 |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD); + if (err2) { + err |= err2; + arg = (steps * 1000) / 30; + err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); + } if (cmd->stop_src == TRIG_COUNT) err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); --- linux-oracle-5.4.0.orig/drivers/staging/comedi/drivers/vmk80xx.c +++ linux-oracle-5.4.0/drivers/staging/comedi/drivers/vmk80xx.c @@ -90,6 +90,9 @@ #define IC3_VERSION BIT(0) #define IC6_VERSION BIT(1) +#define MIN_BUF_SIZE 64 +#define PACKET_TIMEOUT 10000 /* ms */ + enum vmk80xx_model { VMK8055_MODEL, VMK8061_MODEL @@ -157,22 +160,21 @@ __u8 rx_addr; unsigned int tx_pipe; unsigned int rx_pipe; - size_t size; + size_t tx_size; + size_t rx_size; tx_addr = devpriv->ep_tx->bEndpointAddress; rx_addr = devpriv->ep_rx->bEndpointAddress; tx_pipe = usb_sndbulkpipe(usb, tx_addr); rx_pipe = usb_rcvbulkpipe(usb, rx_addr); + tx_size = usb_endpoint_maxp(devpriv->ep_tx); + rx_size = usb_endpoint_maxp(devpriv->ep_rx); - /* - * The max packet size attributes of the K8061 - * input/output endpoints are identical - */ - size = usb_endpoint_maxp(devpriv->ep_tx); + usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, tx_size, NULL, + PACKET_TIMEOUT); - usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, - size, NULL, devpriv->ep_tx->bInterval); - usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, size, NULL, HZ * 10); + usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, rx_size, NULL, + PACKET_TIMEOUT); } static int vmk80xx_read_packet(struct comedi_device *dev) @@ -191,7 +193,7 @@ pipe = usb_rcvintpipe(usb, ep->bEndpointAddress); return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf, usb_endpoint_maxp(ep), NULL, - HZ * 10); + PACKET_TIMEOUT); } static int vmk80xx_write_packet(struct comedi_device *dev, int cmd) @@ -212,7 +214,7 @@ pipe = usb_sndintpipe(usb, ep->bEndpointAddress); return usb_interrupt_msg(usb, pipe, devpriv->usb_tx_buf, usb_endpoint_maxp(ep), NULL, - HZ * 10); + PACKET_TIMEOUT); } static int vmk80xx_reset_device(struct comedi_device *dev) @@ -640,32 +642,24 @@ struct vmk80xx_private *devpriv = dev->private; struct usb_interface *intf = comedi_to_usb_interface(dev); struct usb_host_interface *iface_desc = intf->cur_altsetting; - struct usb_endpoint_descriptor *ep_desc; - int i; - - if (iface_desc->desc.bNumEndpoints != 2) - return -ENODEV; + struct usb_endpoint_descriptor *ep_rx_desc, *ep_tx_desc; + int ret; - for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { - ep_desc = &iface_desc->endpoint[i].desc; + if (devpriv->model == VMK8061_MODEL) + ret = usb_find_common_endpoints(iface_desc, &ep_rx_desc, + &ep_tx_desc, NULL, NULL); + else + ret = usb_find_common_endpoints(iface_desc, NULL, NULL, + &ep_rx_desc, &ep_tx_desc); - if (usb_endpoint_is_int_in(ep_desc) || - usb_endpoint_is_bulk_in(ep_desc)) { - if (!devpriv->ep_rx) - devpriv->ep_rx = ep_desc; - continue; - } + if (ret) + return -ENODEV; - if (usb_endpoint_is_int_out(ep_desc) || - usb_endpoint_is_bulk_out(ep_desc)) { - if (!devpriv->ep_tx) - devpriv->ep_tx = ep_desc; - continue; - } - } + devpriv->ep_rx = ep_rx_desc; + devpriv->ep_tx = ep_tx_desc; - if (!devpriv->ep_rx || !devpriv->ep_tx) - return -ENODEV; + if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx)) + return -EINVAL; return 0; } @@ -675,12 +669,12 @@ struct vmk80xx_private *devpriv = dev->private; size_t size; - size = usb_endpoint_maxp(devpriv->ep_rx); + size = max(usb_endpoint_maxp(devpriv->ep_rx), MIN_BUF_SIZE); devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL); if (!devpriv->usb_rx_buf) return -ENOMEM; - size = usb_endpoint_maxp(devpriv->ep_tx); + size = max(usb_endpoint_maxp(devpriv->ep_tx), MIN_BUF_SIZE); devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); if (!devpriv->usb_tx_buf) return -ENOMEM; --- linux-oracle-5.4.0.orig/drivers/staging/emxx_udc/emxx_udc.c +++ linux-oracle-5.4.0/drivers/staging/emxx_udc/emxx_udc.c @@ -2064,7 +2064,7 @@ struct nbu2ss_ep *ep, int status) { - struct nbu2ss_req *req; + struct nbu2ss_req *req, *n; /* Endpoint Disable */ _nbu2ss_epn_exit(udc, ep); @@ -2076,7 +2076,7 @@ return 0; /* called with irqs blocked */ - list_for_each_entry(req, &ep->queue, queue) { + list_for_each_entry_safe(req, n, &ep->queue, queue) { _nbu2ss_ep_done(ep, req, status); } @@ -2593,10 +2593,15 @@ req->unaligned = false; if (req->unaligned) { - if (!ep->virt_buf) - ep->virt_buf = dma_alloc_coherent(NULL, PAGE_SIZE, + if (!ep->virt_buf) { + ep->virt_buf = dma_alloc_coherent(udc->dev, PAGE_SIZE, &ep->phys_buf, GFP_ATOMIC | GFP_DMA); + if (!ep->virt_buf) { + spin_unlock_irqrestore(&udc->lock, flags); + return -ENOMEM; + } + } if (ep->epnum > 0) { if (ep->direct == USB_DIR_IN) memcpy(ep->virt_buf, req->req.buf, @@ -3153,7 +3158,7 @@ for (i = 0; i < NUM_ENDPOINTS; i++) { ep = &udc->ep[i]; if (ep->virt_buf) - dma_free_coherent(NULL, PAGE_SIZE, (void *)ep->virt_buf, + dma_free_coherent(udc->dev, PAGE_SIZE, (void *)ep->virt_buf, ep->phys_buf); } --- linux-oracle-5.4.0.orig/drivers/staging/exfat/exfat.h +++ linux-oracle-5.4.0/drivers/staging/exfat/exfat.h @@ -943,8 +943,8 @@ s32 create_file(struct inode *inode, struct chain_t *p_dir, struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid); void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry); -s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, - struct uni_name_t *p_uniname, struct file_id_t *fid); +s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry, + struct uni_name_t *p_uniname, struct file_id_t *fid); s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry, struct chain_t *p_newdir, struct uni_name_t *p_uniname, struct file_id_t *fid); --- linux-oracle-5.4.0.orig/drivers/staging/exfat/exfat_core.c +++ linux-oracle-5.4.0/drivers/staging/exfat/exfat_core.c @@ -3381,8 +3381,8 @@ fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries); } -s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, - struct uni_name_t *p_uniname, struct file_id_t *fid) +s32 exfat_rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry, + struct uni_name_t *p_uniname, struct file_id_t *fid) { s32 ret, newentry = -1, num_old_entries, num_new_entries; sector_t sector_old, sector_new; --- linux-oracle-5.4.0.orig/drivers/staging/exfat/exfat_super.c +++ linux-oracle-5.4.0/drivers/staging/exfat/exfat_super.c @@ -59,7 +59,7 @@ /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ static void exfat_time_fat2unix(struct timespec64 *ts, struct date_time_t *tp) { - ts->tv_sec = mktime64(tp->Year + 1980, tp->Month + 1, tp->Day, + ts->tv_sec = mktime64(tp->Year + 1980, tp->Month, tp->Day, tp->Hour, tp->Minute, tp->Second); ts->tv_nsec = tp->MilliSecond * NSEC_PER_MSEC; @@ -1308,8 +1308,8 @@ fs_set_vol_flags(sb, VOL_DIRTY); if (olddir.dir == newdir.dir) - ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name, - fid); + ret = exfat_rename_file(new_parent_inode, &olddir, dentry, + &uni_name, fid); else ret = move_file(new_parent_inode, &olddir, dentry, &newdir, &uni_name, fid); --- linux-oracle-5.4.0.orig/drivers/staging/fbtft/fb_agm1264k-fl.c +++ linux-oracle-5.4.0/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -84,9 +84,9 @@ dev_dbg(par->info->device, "%s()\n", __func__); - gpiod_set_value(par->gpio.reset, 0); - udelay(20); gpiod_set_value(par->gpio.reset, 1); + udelay(20); + gpiod_set_value(par->gpio.reset, 0); mdelay(120); } @@ -194,12 +194,12 @@ /* select chip */ if (*buf) { /* cs1 */ - gpiod_set_value(par->CS0, 1); - gpiod_set_value(par->CS1, 0); - } else { - /* cs0 */ gpiod_set_value(par->CS0, 0); gpiod_set_value(par->CS1, 1); + } else { + /* cs0 */ + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 0); } gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ @@ -397,8 +397,8 @@ } kfree(convert_buf); - gpiod_set_value(par->CS0, 1); - gpiod_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 0); return ret; } @@ -419,10 +419,10 @@ for (i = 0; i < 8; ++i) gpiod_set_value(par->gpio.db[i], data & (1 << i)); /* set E */ - gpiod_set_value(par->EPIN, 1); + gpiod_set_value(par->EPIN, 0); udelay(5); /* unset E - write */ - gpiod_set_value(par->EPIN, 0); + gpiod_set_value(par->EPIN, 1); udelay(1); } --- linux-oracle-5.4.0.orig/drivers/staging/fbtft/fb_bd663474.c +++ linux-oracle-5.4.0/drivers/staging/fbtft/fb_bd663474.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "fbtft.h" @@ -24,9 +23,6 @@ static int init_display(struct fbtft_par *par) { - if (par->gpio.cs) - gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ - par->fbtftops.reset(par); /* Initialization sequence from Lib_UTFT */ --- linux-oracle-5.4.0.orig/drivers/staging/fbtft/fb_ili9163.c +++ linux-oracle-5.4.0/drivers/staging/fbtft/fb_ili9163.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include